From 2c180b689ab1099e463bac256bb81bee6a7e66a5 Mon Sep 17 00:00:00 2001 From: Nadir Date: Sun, 1 Mar 2026 07:23:32 +0100 Subject: [PATCH 1/3] added mseide-msegui dependancy --- mseide-msegui/.gitignore | 9 + mseide-msegui/COPYING.GPL | 340 + mseide-msegui/COPYING.LGPL | 504 + mseide-msegui/COPYING.MSE | 23 + mseide-msegui/DEBUG.TXT | 42 + mseide-msegui/README.TXT | 390 + mseide-msegui/VERSION.TXT | 675 + mseide-msegui/apps/demo/demo.pas | 8 + mseide-msegui/apps/demo/demo.prj | 1016 + mseide-msegui/apps/demo/main.mfm | 25 + mseide-msegui/apps/demo/main.pas | 28 + mseide-msegui/apps/demo/main_mfm.pas | 37 + mseide-msegui/apps/facedemo/facedemo.pas | 11 + mseide-msegui/apps/facedemo/facedemo.prj | 1015 + mseide-msegui/apps/facedemo/main.mfm | 3558 +++ mseide-msegui/apps/facedemo/main.pas | 34 + mseide-msegui/apps/facedemo/main_mfm.pas | 5367 ++++ mseide-msegui/apps/i18ndemo/de/dummy.txt | 1 + mseide-msegui/apps/i18ndemo/fr/dummy.txt | 1 + mseide-msegui/apps/i18ndemo/i18ndemo.pas | 27 + mseide-msegui/apps/i18ndemo/i18ndemo.prj | 1200 + mseide-msegui/apps/i18ndemo/i18ndemo.trd | 86 + mseide-msegui/apps/i18ndemo/i18ndemo.trp | 133 + mseide-msegui/apps/i18ndemo/main.mfm | 90 + mseide-msegui/apps/i18ndemo/main.pas | 57 + mseide-msegui/apps/i18ndemo/main_mfm.pas | 84 + mseide-msegui/apps/ide/COPYING.GPL | 340 + mseide-msegui/apps/ide/COPYING.IDE | 17 + mseide-msegui/apps/ide/actionsmodule.mfm | 2605 ++ mseide-msegui/apps/ide/actionsmodule.pas | 918 + mseide-msegui/apps/ide/actionsmodule_mfm.pas | 2295 ++ mseide-msegui/apps/ide/breakpointsform.mfm | 471 + mseide-msegui/apps/ide/breakpointsform.pas | 822 + .../apps/ide/breakpointsform_mfm.pas | 569 + mseide-msegui/apps/ide/cdesignparser.pas | 637 + mseide-msegui/apps/ide/commandlineform.mfm | 41 + mseide-msegui/apps/ide/commandlineform.pas | 59 + .../apps/ide/commandlineform_mfm.pas | 72 + .../apps/ide/componentpaletteform.mfm | 134 + .../apps/ide/componentpaletteform.pas | 155 + .../apps/ide/componentpaletteform_mfm.pas | 214 + mseide-msegui/apps/ide/componentstore.mfm | 469 + mseide-msegui/apps/ide/componentstore.pas | 1071 + mseide-msegui/apps/ide/componentstore_mfm.pas | 524 + mseide-msegui/apps/ide/compstore/dummy | 1 + mseide-msegui/apps/ide/cpuarmform.mfm | 997 + mseide-msegui/apps/ide/cpuarmform.pas | 133 + mseide-msegui/apps/ide/cpuarmform_mfm.pas | 843 + mseide-msegui/apps/ide/cpuarmm3form.mfm | 285 + mseide-msegui/apps/ide/cpuarmm3form.pas | 22 + mseide-msegui/apps/ide/cpuarmm3form_mfm.pas | 175 + mseide-msegui/apps/ide/cpuavr32form.mfm | 1058 + mseide-msegui/apps/ide/cpuavr32form.pas | 305 + mseide-msegui/apps/ide/cpuavr32form_mfm.pas | 876 + mseide-msegui/apps/ide/cpucpu32form.mfm | 897 + mseide-msegui/apps/ide/cpucpu32form.pas | 109 + mseide-msegui/apps/ide/cpucpu32form_mfm.pas | 793 + mseide-msegui/apps/ide/cpuform.mfm | 99 + mseide-msegui/apps/ide/cpuform.pas | 372 + mseide-msegui/apps/ide/cpuform_mfm.pas | 133 + mseide-msegui/apps/ide/cpui386form.mfm | 757 + mseide-msegui/apps/ide/cpui386form.pas | 131 + mseide-msegui/apps/ide/cpui386form_mfm.pas | 621 + mseide-msegui/apps/ide/cpurl78form.mfm | 1743 ++ mseide-msegui/apps/ide/cpurl78form.pas | 149 + mseide-msegui/apps/ide/cpurl78form_mfm.pas | 1721 ++ mseide-msegui/apps/ide/cpux86_64form.mfm | 807 + mseide-msegui/apps/ide/cpux86_64form.pas | 133 + mseide-msegui/apps/ide/cpux86_64form_mfm.pas | 671 + mseide-msegui/apps/ide/debuggerform.mfm | 164 + mseide-msegui/apps/ide/debuggerform.pas | 33 + mseide-msegui/apps/ide/debuggerform_mfm.pas | 211 + mseide-msegui/apps/ide/disassform.mfm | 166 + mseide-msegui/apps/ide/disassform.pas | 339 + mseide-msegui/apps/ide/disassform_mfm.pas | 227 + mseide-msegui/apps/ide/dumpunitgroups.pas | 236 + mseide-msegui/apps/ide/finddialogform.mfm | 213 + mseide-msegui/apps/ide/finddialogform.pas | 113 + mseide-msegui/apps/ide/finddialogform_mfm.pas | 238 + .../apps/ide/findinfiledialogform.mfm | 308 + .../apps/ide/findinfiledialogform.pas | 244 + .../apps/ide/findinfiledialogform_mfm.pas | 286 + mseide-msegui/apps/ide/findinfileform.mfm | 111 + mseide-msegui/apps/ide/findinfileform.pas | 77 + mseide-msegui/apps/ide/findinfileform_mfm.pas | 174 + mseide-msegui/apps/ide/findinfilepage.mfm | 158 + mseide-msegui/apps/ide/findinfilepage.pas | 368 + mseide-msegui/apps/ide/findinfilepage_mfm.pas | 184 + mseide-msegui/apps/ide/formdesigner.mfm | 338 + mseide-msegui/apps/ide/formdesigner.pas | 4178 +++ mseide-msegui/apps/ide/formdesigner_mfm.pas | 375 + mseide-msegui/apps/ide/guitemplates.mfm | 426 + mseide-msegui/apps/ide/guitemplates.pas | 113 + mseide-msegui/apps/ide/guitemplates_mfm.pas | 226 + mseide-msegui/apps/ide/main.mfm | 1572 ++ mseide-msegui/apps/ide/main.pas | 3125 +++ mseide-msegui/apps/ide/main_mfm.pas | 1950 ++ mseide-msegui/apps/ide/make.pas | 566 + mseide-msegui/apps/ide/memoryform.mfm | 501 + mseide-msegui/apps/ide/memoryform.pas | 254 + mseide-msegui/apps/ide/memoryform_mfm.pas | 453 + mseide-msegui/apps/ide/menusdesign.pas | 51 + mseide-msegui/apps/ide/messageform.mfm | 102 + mseide-msegui/apps/ide/messageform.pas | 143 + mseide-msegui/apps/ide/messageform_mfm.pas | 146 + mseide-msegui/apps/ide/msecodetemplates.pas | 374 + mseide-msegui/apps/ide/msecomptree.mfm | 73 + mseide-msegui/apps/ide/msecomptree.pas | 173 + mseide-msegui/apps/ide/msecomptree_mfm.pas | 94 + mseide-msegui/apps/ide/msedesigner.pas | 6037 +++++ mseide-msegui/apps/ide/msedesignparser.pas | 2210 ++ mseide-msegui/apps/ide/mseide.ico | Bin 0 -> 12862 bytes mseide-msegui/apps/ide/mseide.pas | 76 + mseide-msegui/apps/ide/mseide.prj | 1047 + mseide-msegui/apps/ide/mseide.rc | 24 + mseide-msegui/apps/ide/mseide.res | Bin 0 -> 13624 bytes mseide-msegui/apps/ide/mseide_zeos.prj | 1163 + mseide-msegui/apps/ide/mseparamentryform.mfm | 140 + mseide-msegui/apps/ide/mseparamentryform.pas | 46 + .../apps/ide/mseparamentryform_mfm.pas | 153 + .../apps/ide/msetemplateselectform.mfm | 261 + .../apps/ide/msetemplateselectform.pas | 85 + .../apps/ide/msetemplateselectform_mfm.pas | 348 + mseide-msegui/apps/ide/objectinspector.mfm | 366 + mseide-msegui/apps/ide/objectinspector.pas | 2039 ++ .../apps/ide/objectinspector_mfm.pas | 457 + mseide-msegui/apps/ide/panelform.mfm | 38 + mseide-msegui/apps/ide/panelform.pas | 314 + mseide-msegui/apps/ide/panelform_mfm.pas | 88 + mseide-msegui/apps/ide/pascaldesignparser.pas | 1504 ++ mseide-msegui/apps/ide/printform.mfm | 252 + mseide-msegui/apps/ide/printform.pas | 178 + mseide-msegui/apps/ide/printform_mfm.pas | 246 + .../apps/ide/programparametersform.mfm | 230 + .../apps/ide/programparametersform.pas | 123 + .../apps/ide/programparametersform_mfm.pas | 241 + mseide-msegui/apps/ide/projectoptionsform.mfm | 6790 +++++ mseide-msegui/apps/ide/projectoptionsform.pas | 3602 +++ .../apps/ide/projectoptionsform_mfm.pas | 9382 +++++++ mseide-msegui/apps/ide/projecttreeform.mfm | 407 + mseide-msegui/apps/ide/projecttreeform.pas | 1565 ++ .../apps/ide/projecttreeform_mfm.pas | 475 + mseide-msegui/apps/ide/replacedialogform.mfm | 167 + mseide-msegui/apps/ide/replacedialogform.pas | 93 + .../apps/ide/replacedialogform_mfm.pas | 133 + mseide-msegui/apps/ide/reportdesigner.mfm | 459 + mseide-msegui/apps/ide/reportdesigner.pas | 630 + mseide-msegui/apps/ide/reportdesigner_mfm.pas | 330 + mseide-msegui/apps/ide/selecteditpageform.mfm | 66 + mseide-msegui/apps/ide/selecteditpageform.pas | 163 + .../apps/ide/selecteditpageform_mfm.pas | 98 + .../apps/ide/selectsubformdialogform.pas | 36 + .../apps/ide/selectsubformdialogform_mfm.pas | 47 + .../apps/ide/selectsubmoduledialogform.mfm | 51 + .../apps/ide/selectsubmoduledialogform.pas | 36 + .../ide/selectsubmoduledialogform_mfm.pas | 64 + mseide-msegui/apps/ide/setcreateorderform.mfm | 109 + mseide-msegui/apps/ide/setcreateorderform.pas | 89 + .../apps/ide/setcreateorderform_mfm.pas | 121 + mseide-msegui/apps/ide/settaborderform.mfm | 162 + mseide-msegui/apps/ide/settaborderform.pas | 259 + .../apps/ide/settaborderform_mfm.pas | 193 + mseide-msegui/apps/ide/skeletons.pas | 84 + mseide-msegui/apps/ide/sourceform.mfm | 568 + mseide-msegui/apps/ide/sourceform.pas | 1636 ++ mseide-msegui/apps/ide/sourceform_mfm.pas | 618 + mseide-msegui/apps/ide/sourcehintform.mfm | 24 + mseide-msegui/apps/ide/sourcehintform.pas | 56 + mseide-msegui/apps/ide/sourcehintform_mfm.pas | 49 + mseide-msegui/apps/ide/sourcepage.mfm | 169 + mseide-msegui/apps/ide/sourcepage.pas | 1836 ++ mseide-msegui/apps/ide/sourcepage_mfm.pas | 213 + mseide-msegui/apps/ide/sourceupdate.pas | 2350 ++ mseide-msegui/apps/ide/stackform.mfm | 199 + mseide-msegui/apps/ide/stackform.pas | 198 + mseide-msegui/apps/ide/stackform_mfm.pas | 290 + .../apps/ide/storedcomponentinfodialog.mfm | 107 + .../apps/ide/storedcomponentinfodialog.pas | 88 + .../ide/storedcomponentinfodialog_mfm.pas | 113 + mseide-msegui/apps/ide/stringconsts.mfm | 11 + mseide-msegui/apps/ide/stringconsts.pas | 17 + mseide-msegui/apps/ide/stringconsts_mfm.pas | 24 + mseide-msegui/apps/ide/symbolform.mfm | 235 + mseide-msegui/apps/ide/symbolform.pas | 149 + mseide-msegui/apps/ide/symbolform_mfm.pas | 316 + mseide-msegui/apps/ide/syntaxdefs/cpp.sdef | 80 + mseide-msegui/apps/ide/syntaxdefs/glsl.sdef | 88 + .../apps/ide/syntaxdefs/grammar.sdef | 54 + mseide-msegui/apps/ide/syntaxdefs/ipf.sdef | 96 + mseide-msegui/apps/ide/syntaxdefs/ipf2.sdef | 131 + mseide-msegui/apps/ide/syntaxdefs/java.sdef | 85 + mseide-msegui/apps/ide/syntaxdefs/llvm.sdef | 45 + .../apps/ide/syntaxdefs/mselang.sdef | 107 + .../apps/ide/syntaxdefs/objecttext.sdef | 35 + mseide-msegui/apps/ide/syntaxdefs/pascal.sdef | 107 + .../apps/ide/syntaxdefs/pascal2.sdef | 109 + .../apps/ide/syntaxdefs/pascal_solarized.sdef | 170 + .../ide/syntaxdefs/pascal_solarized_dark.sdef | 168 + mseide-msegui/apps/ide/syntaxdefs/python.sdef | 45 + mseide-msegui/apps/ide/syntaxdefs/sql.sdef | 82 + mseide-msegui/apps/ide/targetconsole.mfm | 113 + mseide-msegui/apps/ide/targetconsole.pas | 153 + mseide-msegui/apps/ide/targetconsole_mfm.pas | 139 + mseide-msegui/apps/ide/templateeditor.mfm | 372 + mseide-msegui/apps/ide/templateeditor.pas | 222 + mseide-msegui/apps/ide/templateeditor_mfm.pas | 324 + mseide-msegui/apps/ide/templates/console.prj | 970 + .../apps/ide/templates/console/program.pas | 8 + .../apps/ide/templates/console/project.pas | 8 + .../apps/ide/templates/console/projectarm.pas | 8 + .../apps/ide/templates/console/unit.pas | 5 + .../apps/ide/templates/copytarget.sh | 17 + .../apps/ide/templates/crossarmconsole.prj | 1143 + .../apps/ide/templates/crossarmdefault.prj | 1175 + mseide-msegui/apps/ide/templates/default.prj | 971 + .../apps/ide/templates/default/datamodule.mfm | 9 + .../apps/ide/templates/default/datamodule.pas | 15 + .../ide/templates/default/dockingform.mfm | 7 + .../ide/templates/default/dockingform.pas | 16 + .../ide/templates/default/dockpanelform.mfm | 20 + .../ide/templates/default/dockpanelform.pas | 15 + .../ide/templates/default/inheritedform.mfm | 3 + .../ide/templates/default/inheritedform.pas | 17 + .../apps/ide/templates/default/main.mfm | 7 + .../apps/ide/templates/default/main.pas | 16 + .../apps/ide/templates/default/main_mfm.pas | 22 + .../apps/ide/templates/default/mainform.mfm | 8 + .../apps/ide/templates/default/mainform.pas | 16 + .../apps/ide/templates/default/pascform.mfm | 11 + .../apps/ide/templates/default/pascform.pas | 16 + .../apps/ide/templates/default/program.pas | 11 + .../apps/ide/templates/default/project.pas | 12 + .../apps/ide/templates/default/report.mfm | 18 + .../apps/ide/templates/default/report.pas | 18 + .../ide/templates/default/reppageform.mfm | 14 + .../ide/templates/default/reppageform.pas | 17 + .../ide/templates/default/scrollboxform.mfm | 7 + .../ide/templates/default/scrollboxform.pas | 15 + .../apps/ide/templates/default/simpleform.mfm | 7 + .../apps/ide/templates/default/simpleform.pas | 15 + .../apps/ide/templates/default/sizingform.mfm | 7 + .../apps/ide/templates/default/sizingform.pas | 16 + .../apps/ide/templates/default/subform.mfm | 7 + .../apps/ide/templates/default/subform.pas | 15 + .../apps/ide/templates/default/tabform.mfm | 7 + .../apps/ide/templates/default/tabform.pas | 15 + .../apps/ide/templates/default/unit.pas | 5 + .../apps/ide/templates/layoutconsole.prj | 891 + .../apps/ide/templates/layoutdockedforms.prj | 956 + .../apps/ide/templates/layoutgui.prj | 906 + mseide-msegui/apps/ide/templates/library.prj | 263 + .../apps/ide/templates/library/program.pas | 8 + .../apps/ide/templates/library/project.pas | 5 + .../apps/ide/templates/library/unit.pas | 5 + .../apps/ide/templates/runsshgdbserver.sh | 8 + mseide-msegui/apps/ide/templates/zeos.prj | 984 + mseide-msegui/apps/ide/threadsform.mfm | 189 + mseide-msegui/apps/ide/threadsform.pas | 148 + mseide-msegui/apps/ide/threadsform_mfm.pas | 278 + mseide-msegui/apps/ide/toolhandlermodule.mfm | 14 + mseide-msegui/apps/ide/toolhandlermodule.pas | 66 + .../apps/ide/toolhandlermodule_mfm.pas | 30 + mseide-msegui/apps/ide/watchform.mfm | 434 + mseide-msegui/apps/ide/watchform.pas | 336 + mseide-msegui/apps/ide/watchform_mfm.pas | 509 + mseide-msegui/apps/ide/watchpointsform.mfm | 353 + mseide-msegui/apps/ide/watchpointsform.pas | 210 + .../apps/ide/watchpointsform_mfm.pas | 440 + mseide-msegui/apps/myide/mybutton.pas | 80 + mseide-msegui/apps/myide/mymseide.prj | 1010 + mseide-msegui/apps/myide/regcomponents.inc | 1 + mseide-msegui/apps/myide/regmycomps.pas | 17 + mseide-msegui/contributed/README.TXT | 4 + mseide-msegui/help/README.TXT | 4 + mseide-msegui/icons/buttons/breakpoint.png | Bin 0 -> 481 bytes mseide-msegui/icons/buttons/breakpoint.svg | 272 + mseide-msegui/icons/buttons/continue.png | Bin 0 -> 582 bytes mseide-msegui/icons/buttons/continue.svg | 283 + mseide-msegui/icons/buttons/continuedisab.png | Bin 0 -> 489 bytes mseide-msegui/icons/buttons/continuedisab.svg | 255 + mseide-msegui/icons/buttons/execline.png | Bin 0 -> 527 bytes mseide-msegui/icons/buttons/execline.svg | 285 + mseide-msegui/icons/buttons/finish.png | Bin 0 -> 1199 bytes mseide-msegui/icons/buttons/finish.svg | 449 + mseide-msegui/icons/buttons/finishdisab.png | Bin 0 -> 870 bytes mseide-msegui/icons/buttons/finishdisab.svg | 398 + mseide-msegui/icons/buttons/finishi.png | Bin 0 -> 1183 bytes mseide-msegui/icons/buttons/finishi.svg | 423 + mseide-msegui/icons/buttons/interrupt.png | Bin 0 -> 489 bytes mseide-msegui/icons/buttons/interrupt.svg | 329 + .../icons/buttons/interruptdisab.png | Bin 0 -> 213 bytes .../icons/buttons/interruptdisab.svg | 265 + mseide-msegui/icons/buttons/next.png | Bin 0 -> 947 bytes mseide-msegui/icons/buttons/next.svg | 399 + mseide-msegui/icons/buttons/nextdisab.png | Bin 0 -> 655 bytes mseide-msegui/icons/buttons/nextdisab.svg | 359 + mseide-msegui/icons/buttons/nexti.png | Bin 0 -> 929 bytes mseide-msegui/icons/buttons/nexti.svg | 399 + mseide-msegui/icons/buttons/nextidisab.png | Bin 0 -> 601 bytes mseide-msegui/icons/buttons/nextidisab.svg | 339 + mseide-msegui/icons/buttons/path3846.png | Bin 0 -> 735 bytes mseide-msegui/icons/buttons/reset.png | Bin 0 -> 1318 bytes mseide-msegui/icons/buttons/reset.svg | 327 + mseide-msegui/icons/buttons/resetdisab.png | Bin 0 -> 978 bytes mseide-msegui/icons/buttons/resetdisab.svg | 332 + mseide-msegui/icons/buttons/step.png | Bin 0 -> 1171 bytes mseide-msegui/icons/buttons/step.svg | 475 + mseide-msegui/icons/buttons/stepdisab.png | Bin 0 -> 856 bytes mseide-msegui/icons/buttons/stepdisab.svg | 399 + mseide-msegui/icons/buttons/stepi.png | Bin 0 -> 1140 bytes mseide-msegui/icons/buttons/stepi.svg | 475 + mseide-msegui/icons/buttons/stepidisab.png | Bin 0 -> 840 bytes mseide-msegui/icons/buttons/stepidisab.svg | 372 + mseide-msegui/icons/buttons/watches.png | Bin 0 -> 565 bytes mseide-msegui/icons/buttons/watches.svg | 299 + mseide-msegui/icons/components/123.png | Bin 0 -> 349 bytes mseide-msegui/icons/components/123s.png | Bin 0 -> 308 bytes mseide-msegui/icons/components/123ss.png | Bin 0 -> 308 bytes mseide-msegui/icons/components/1_2.png | Bin 0 -> 303 bytes mseide-msegui/icons/components/64.png | Bin 0 -> 404 bytes mseide-msegui/icons/components/TComponent.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/TComponent.png | Bin 0 -> 897 bytes .../icons/components/TIBConnection.bmp | Bin 0 -> 1782 bytes .../icons/components/TSQLTransaction.bmp | Bin 0 -> 1782 bytes .../icons/components/TZConnection.bmp | Bin 0 -> 1654 bytes mseide-msegui/icons/components/TZSequence.bmp | Bin 0 -> 1234 bytes .../icons/components/TZSqlMetadata.bmp | Bin 0 -> 1654 bytes .../icons/components/TZSqlMonitor.bmp | Bin 0 -> 1654 bytes .../icons/components/TZSqlProcessor.bmp | Bin 0 -> 1654 bytes .../icons/components/TZStoredProc.bmp | Bin 0 -> 1654 bytes .../icons/components/TZUpdateSql.bmp | Bin 0 -> 1654 bytes mseide-msegui/icons/components/_sta.png | Bin 0 -> 333 bytes mseide-msegui/icons/components/a01.png | Bin 0 -> 348 bytes mseide-msegui/icons/components/a4ss.png | Bin 0 -> 276 bytes mseide-msegui/icons/components/ab.png | Bin 0 -> 330 bytes mseide-msegui/icons/components/abc.png | Bin 0 -> 365 bytes mseide-msegui/icons/components/abc_de.png | Bin 0 -> 398 bytes mseide-msegui/icons/components/abcss.png | Bin 0 -> 351 bytes mseide-msegui/icons/components/abs.png | Bin 0 -> 325 bytes mseide-msegui/icons/components/abss.png | Bin 0 -> 290 bytes mseide-msegui/icons/components/breakpoint.png | Bin 0 -> 382 bytes mseide-msegui/icons/components/capt.png | Bin 0 -> 366 bytes mseide-msegui/icons/components/ctrl.png | Bin 0 -> 332 bytes mseide-msegui/icons/components/d_t.png | Bin 0 -> 242 bytes mseide-msegui/icons/components/d_tss.png.png | Bin 0 -> 233 bytes mseide-msegui/icons/components/dbf.png | Bin 0 -> 288 bytes mseide-msegui/icons/components/dirss.png | Bin 0 -> 244 bytes mseide-msegui/icons/components/e_if.png | Bin 0 -> 269 bytes mseide-msegui/icons/components/enum.png | Bin 0 -> 286 bytes mseide-msegui/icons/components/file.png | Bin 0 -> 264 bytes mseide-msegui/icons/components/files.png | Bin 0 -> 264 bytes mseide-msegui/icons/components/finishi.svg | 450 + mseide-msegui/icons/components/fix.png | Bin 0 -> 293 bytes mseide-msegui/icons/components/gdi.png | Bin 0 -> 287 bytes mseide-msegui/icons/components/hist.png | Bin 0 -> 301 bytes mseide-msegui/icons/components/key.png | Bin 0 -> 348 bytes mseide-msegui/icons/components/lips.svg | 102 + mseide-msegui/icons/components/loc.png | Bin 0 -> 353 bytes .../icons/components/logo_mysql_sun_a.gif | Bin 0 -> 913 bytes mseide-msegui/icons/components/me.png | Bin 0 -> 319 bytes mseide-msegui/icons/components/mem.png | Bin 0 -> 318 bytes mseide-msegui/icons/components/memo.png | Bin 0 -> 405 bytes mseide-msegui/icons/components/mes.png | Bin 0 -> 326 bytes mseide-msegui/icons/components/nil.png | Bin 0 -> 254 bytes mseide-msegui/icons/components/par_env.png | Bin 0 -> 470 bytes .../components/pastedpic_11232008_073918.png | Bin 0 -> 7848 bytes mseide-msegui/icons/components/path3889-4.png | Bin 0 -> 257 bytes mseide-msegui/icons/components/path3889.png | Bin 0 -> 259 bytes mseide-msegui/icons/components/path4098.png | Bin 0 -> 1060 bytes mseide-msegui/icons/components/path4104.png | Bin 0 -> 623 bytes mseide-msegui/icons/components/path4444.png | Bin 0 -> 309 bytes mseide-msegui/icons/components/port_land.png | Bin 0 -> 402 bytes mseide-msegui/icons/components/portss.png | Bin 0 -> 306 bytes mseide-msegui/icons/components/proc_mon.png | Bin 0 -> 408 bytes mseide-msegui/icons/components/ps.png | Bin 0 -> 317 bytes mseide-msegui/icons/components/rec.png | Bin 0 -> 337 bytes mseide-msegui/icons/components/rect2648.png | Bin 0 -> 144 bytes mseide-msegui/icons/components/rect9378.png | Bin 0 -> 144 bytes mseide-msegui/icons/components/sdf.png | Bin 0 -> 308 bytes mseide-msegui/icons/components/sel.png | Bin 0 -> 311 bytes mseide-msegui/icons/components/sigbase.svg | 221 + mseide-msegui/icons/components/sigedit.svg | 236 + mseide-msegui/icons/components/sql.png | Bin 0 -> 363 bytes mseide-msegui/icons/components/sql_e.png | Bin 0 -> 376 bytes mseide-msegui/icons/components/sql_eee.png | Bin 0 -> 379 bytes mseide-msegui/icons/components/sql_qqq.png | Bin 0 -> 425 bytes mseide-msegui/icons/components/symbols.svg | 427 + mseide-msegui/icons/components/tacecomp.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/taction.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/taction.png | Bin 0 -> 829 bytes mseide-msegui/icons/components/taction.svg | 306 + mseide-msegui/icons/components/tactivator.bmp | Bin 0 -> 1782 bytes mseide-msegui/icons/components/tactivator.png | Bin 0 -> 597 bytes mseide-msegui/icons/components/tactivator.svg | 491 + .../icons/components/tanimitemcomp.png | Bin 0 -> 401 bytes .../icons/components/tanimitemcomp.svg | 188 + mseide-msegui/icons/components/tanimtimer.png | Bin 0 -> 1694 bytes mseide-msegui/icons/components/tanimtimer.svg | 623 + .../icons/components/tasciicommport.bmp | Bin 0 -> 406 bytes .../icons/components/tasciicommport.png | Bin 0 -> 726 bytes .../icons/components/tasciicommport.svg | 205 + .../icons/components/tasciiproptport.png | Bin 0 -> 729 bytes .../icons/components/tasciiprotport.png | Bin 0 -> 729 bytes .../icons/components/tasciiprotport.svg | 205 + .../icons/components/tassistivehandler.png | Bin 0 -> 890 bytes .../icons/components/tassistivehandler.svg | 130 + .../icons/components/tassistivewidgetitem.png | Bin 0 -> 592 bytes .../icons/components/tassistivewidgetitem.svg | 130 + .../components/tasymciphercryptohandler.png | Bin 0 -> 858 bytes .../components/tasymciphercryptohandler.svg | 221 + .../icons/components/tasynsercommchannel.png | Bin 0 -> 1124 bytes .../icons/components/tasynsercommchannel.svg | 213 + mseide-msegui/icons/components/taudioout.png | Bin 0 -> 731 bytes mseide-msegui/icons/components/taudioout.svg | 243 + mseide-msegui/icons/components/tbandarea.bmp | Bin 0 -> 1782 bytes mseide-msegui/icons/components/tbandbroup.bmp | Bin 0 -> 1782 bytes mseide-msegui/icons/components/tbandgroup.bmp | Bin 0 -> 1782 bytes mseide-msegui/icons/components/tbarcode.png | Bin 0 -> 348 bytes mseide-msegui/icons/components/tbarcode.svg | 398 + .../icons/components/tbase64cryptohandler.png | Bin 0 -> 852 bytes .../icons/components/tbase64cryptohandler.svg | 221 + .../icons/components/tbase64handler.png | Bin 0 -> 852 bytes .../icons/components/tbase64handler.svg | 221 + .../icons/components/tbitmapcomp.bmp | Bin 0 -> 406 bytes .../icons/components/tbitmapcomp.png | Bin 0 -> 892 bytes .../icons/components/tbitmapcomp.svg | 266 + .../icons/components/tbitmapcontainer.bmp | Bin 0 -> 406 bytes .../icons/components/tbooleandisp.bmp | Bin 0 -> 406 bytes .../icons/components/tbooleandisp.png | Bin 0 -> 525 bytes .../icons/components/tbooleandisp.svg | 371 + .../icons/components/tbooleanedit.bmp | Bin 0 -> 406 bytes .../icons/components/tbooleaneditradio.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/tbutton.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/tbutton.png | Bin 0 -> 592 bytes mseide-msegui/icons/components/tbutton.svg | 202 + .../icons/components/tbytestringdisp.bmp | Bin 0 -> 406 bytes .../icons/components/tbytestringdisp.png | Bin 0 -> 684 bytes .../icons/components/tbytestringdisp.svg | 428 + .../icons/components/tbytestringlist.png | Bin 0 -> 684 bytes .../components/tcalendardatetimeedit.bmp | Bin 0 -> 1782 bytes .../components/tcalendardatetimeedit.png | Bin 0 -> 539 bytes .../components/tcalendardatetimeedit.svg | 567 + mseide-msegui/icons/components/tcaption.png | Bin 0 -> 416 bytes mseide-msegui/icons/components/tchart.bmp | Bin 0 -> 1782 bytes mseide-msegui/icons/components/tchart.png | Bin 0 -> 898 bytes mseide-msegui/icons/components/tchart.svg | 303 + .../icons/components/tchartrecorder.bmp | Bin 0 -> 1782 bytes .../icons/components/tchartrecorder.png | Bin 0 -> 1225 bytes .../icons/components/tchartrecorder.svg | 330 + mseide-msegui/icons/components/tcoloredit.bmp | Bin 0 -> 1782 bytes mseide-msegui/icons/components/tcoloredit.png | Bin 0 -> 313 bytes mseide-msegui/icons/components/tcoloredit.svg | 261 + mseide-msegui/icons/components/tcommport.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/tcommport.png | Bin 0 -> 776 bytes mseide-msegui/icons/components/tcommport.svg | 205 + .../icons/components/tcommselector.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/tcomponent.svg | 256 + .../components/tconnectedifidatasource.png | Bin 0 -> 968 bytes .../components/tconnectedifidatasource.svg | 386 + .../icons/components/tdatabutton.bmp | Bin 0 -> 1782 bytes .../icons/components/tdatabutton.png | Bin 0 -> 472 bytes .../icons/components/tdatabutton.svg | 245 + mseide-msegui/icons/components/tdataedit.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/tdataicon.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/tdataicon.png | Bin 0 -> 546 bytes mseide-msegui/icons/components/tdataicon.svg | 253 + mseide-msegui/icons/components/tdataimage.bmp | Bin 0 -> 1782 bytes mseide-msegui/icons/components/tdataimage.png | Bin 0 -> 842 bytes mseide-msegui/icons/components/tdataimage.svg | 317 + .../icons/components/tdatasource.bmp | Bin 0 -> 1782 bytes .../icons/components/tdatetimedisp.bmp | Bin 0 -> 1782 bytes .../icons/components/tdatetimedisp.png | Bin 0 -> 558 bytes .../icons/components/tdatetimedisp.svg | 371 + .../icons/components/tdatetimedisplb.svg | 375 + .../icons/components/tdatetimeedit.bmp | Bin 0 -> 406 bytes .../icons/components/tdatetimeedit.png | Bin 0 -> 328 bytes .../icons/components/tdatetimeedit.svg | 243 + mseide-msegui/icons/components/tdbbarcode.png | Bin 0 -> 422 bytes mseide-msegui/icons/components/tdbbarcode.svg | 406 + .../icons/components/tdbbooleandisp.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbbooleandisp.png | Bin 0 -> 501 bytes .../icons/components/tdbbooleanedit.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbbooleaneditradio.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbbooleantextedit.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbbooleantextedit.png | Bin 0 -> 684 bytes .../icons/components/tdbbooleantextedit.svg | 423 + .../components/tdbcalendardatetimeedit.bmp | Bin 0 -> 1782 bytes .../components/tdbcalendardatetimeedit.png | Bin 0 -> 559 bytes .../components/tdbcalendardatetimeedit.svg | 567 + .../icons/components/tdbcoloredit.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbcoloredit.png | Bin 0 -> 328 bytes .../icons/components/tdbcoloredit.svg | 268 + .../icons/components/tdbdatabutton.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbdatabutton.png | Bin 0 -> 550 bytes .../icons/components/tdbdatabutton.svg | 236 + .../icons/components/tdbdataicon.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbdataicon.png | Bin 0 -> 554 bytes .../icons/components/tdbdataicon.svg | 248 + .../icons/components/tdbdataimage.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbdataimage.png | Bin 0 -> 824 bytes .../icons/components/tdbdataimage.svg | 317 + .../icons/components/tdbdatetimedisp.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbdatetimedisp.png | Bin 0 -> 530 bytes .../icons/components/tdbdatetimedisp.svg | 371 + .../icons/components/tdbdatetimedisplb.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbdatetimedisplb.png | Bin 0 -> 584 bytes .../icons/components/tdbdatetimedisplb.svg | 375 + .../icons/components/tdbdatetimeedit.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbdatetimeedit.png | Bin 0 -> 347 bytes .../icons/components/tdbdatetimeedit.svg | 243 + .../components/tdbdatetimelookup64db.png | Bin 0 -> 843 bytes .../components/tdbdatetimelookup64db.svg | 396 + .../components/tdbdatetimelookup64lb.png | Bin 0 -> 788 bytes .../components/tdbdatetimelookup64lb.svg | 395 + .../icons/components/tdbdatetimelookupdb.png | Bin 0 -> 632 bytes .../icons/components/tdbdatetimelookupdb.svg | 385 + .../icons/components/tdbdatetimelookuplb.png | Bin 0 -> 571 bytes .../icons/components/tdbdatetimelookuplb.svg | 384 + .../components/tdbdatetimelookupstrdb.png | Bin 0 -> 798 bytes .../components/tdbdatetimelookupstrdb.svg | 396 + .../components/tdbdatetimelookupstrlb.png | Bin 0 -> 746 bytes .../components/tdbdatetimelookupstrlb.svg | 395 + .../icons/components/tdbdbenumedit.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbdialogstringedit.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbdialogstringedit.png | Bin 0 -> 569 bytes .../icons/components/tdbdialogstringedit.svg | 312 + .../icons/components/tdbdropdownlistedit.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbdropdownlistedit.png | Bin 0 -> 898 bytes .../icons/components/tdbdropdownlistedit.svg | 458 + .../components/tdbdropdownlisteditdb.png | Bin 0 -> 952 bytes .../components/tdbdropdownlisteditdb.svg | 465 + .../components/tdbdropdownlisteditlb.png | Bin 0 -> 986 bytes .../components/tdbdropdownlisteditlb.svg | 465 + .../icons/components/tdbenum64editdb.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbenum64editdb.png | Bin 0 -> 1033 bytes .../icons/components/tdbenum64editdb.svg | 452 + .../icons/components/tdbenum64editlb.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbenum64editlb.png | Bin 0 -> 1034 bytes .../icons/components/tdbenum64editlb.svg | 452 + .../icons/components/tdbenumedit.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbenumedit.png | Bin 0 -> 960 bytes .../icons/components/tdbenumedit.svg | 438 + .../icons/components/tdbenumeditdb.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbenumeditdb.png | Bin 0 -> 1024 bytes .../icons/components/tdbenumeditdb.svg | 438 + .../icons/components/tdbenumeditlb.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbenumeditlb.png | Bin 0 -> 1043 bytes .../icons/components/tdbenumeditlb.svg | 445 + mseide-msegui/icons/components/tdbevent.bmp | Bin 0 -> 1782 bytes mseide-msegui/icons/components/tdbevent.png | Bin 0 -> 677 bytes mseide-msegui/icons/components/tdbevent.svg | 334 + mseide-msegui/icons/components/tdbf.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbfilenameedit.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbfilenameedit.png | Bin 0 -> 411 bytes .../icons/components/tdbfilenameedit.svg | 246 + mseide-msegui/icons/components/tdbimage.bmp | Bin 0 -> 1782 bytes .../components/tdbintegerblookup64db.png | Bin 0 -> 985 bytes .../icons/components/tdbintegerdisp.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbintegerdisp.png | Bin 0 -> 634 bytes .../icons/components/tdbintegerdisp.svg | 371 + .../icons/components/tdbintegerdisplb.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbintegerdisplb.png | Bin 0 -> 704 bytes .../icons/components/tdbintegerdisplb.svg | 375 + .../icons/components/tdbintegeredit.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbintegeredit.png | Bin 0 -> 586 bytes .../icons/components/tdbintegeredit.svg | 244 + .../icons/components/tdbintegerlookup64db.png | Bin 0 -> 985 bytes .../icons/components/tdbintegerlookup64db.svg | 396 + .../icons/components/tdbintegerlookup64lb.png | Bin 0 -> 952 bytes .../icons/components/tdbintegerlookup64lb.svg | 395 + .../icons/components/tdbintegerlookupdb.png | Bin 0 -> 755 bytes .../icons/components/tdbintegerlookupdb.svg | 385 + .../icons/components/tdbintegerlookuplb.png | Bin 0 -> 726 bytes .../icons/components/tdbintegerlookuplb.svg | 384 + .../components/tdbintegerlookupstrdb.png | Bin 0 -> 933 bytes .../components/tdbintegerlookupstrdb.svg | 396 + .../components/tdbintegerlookupstrlb.png | Bin 0 -> 903 bytes .../components/tdbintegerlookupstrlb.svg | 395 + .../icons/components/tdbkeystringedit.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbkeystringedit.png | Bin 0 -> 803 bytes .../icons/components/tdbkeystringedit.svg | 449 + .../icons/components/tdbkeystringeditdb.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbkeystringeditdb.png | Bin 0 -> 849 bytes .../icons/components/tdbkeystringeditdb.svg | 449 + .../icons/components/tdbkeystringeditlb.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbkeystringeditlb.png | Bin 0 -> 857 bytes .../icons/components/tdbkeystringeditlb.svg | 449 + mseide-msegui/icons/components/tdblabel.bmp | Bin 0 -> 1782 bytes mseide-msegui/icons/components/tdblabel.png | Bin 0 -> 402 bytes mseide-msegui/icons/components/tdblabel.svg | 360 + .../icons/components/tdblookupbuffer.bmp | Bin 0 -> 1782 bytes .../icons/components/tdblookupbuffer.png | Bin 0 -> 321 bytes .../icons/components/tdblookupinteger64db.png | Bin 0 -> 985 bytes .../icons/components/tdblookupinteger64lb.png | Bin 0 -> 952 bytes .../icons/components/tdblookupintegerlb.png | Bin 0 -> 726 bytes .../components/tdblookupintegerstrlb.png | Bin 0 -> 903 bytes .../icons/components/tdblookupstring64lb.png | Bin 0 -> 921 bytes .../icons/components/tdbmemoblookupbuffer.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbmemoedit.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbmemoedit.png | Bin 0 -> 641 bytes .../icons/components/tdbmemoedit.svg | 261 + .../icons/components/tdbmemolookupbuffer.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbmemolookupbuffer.png | Bin 0 -> 463 bytes .../icons/components/tdbnavigator.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbprogressbar.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbprogressbar.png | Bin 0 -> 270 bytes .../icons/components/tdbprogressbar.svg | 228 + .../icons/components/tdbrealdisp.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbrealdisp.png | Bin 0 -> 526 bytes .../icons/components/tdbrealdisp.svg | 371 + .../icons/components/tdbrealdisplb.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbrealdisplb.png | Bin 0 -> 627 bytes .../icons/components/tdbrealdisplb.svg | 375 + .../icons/components/tdbrealedit.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbrealedit.png | Bin 0 -> 471 bytes .../icons/components/tdbrealedit.svg | 244 + .../icons/components/tdbreallookup64db.png | Bin 0 -> 865 bytes .../icons/components/tdbreallookup64db.svg | 396 + .../icons/components/tdbreallookup64lb.png | Bin 0 -> 824 bytes .../icons/components/tdbreallookup64lb.svg | 395 + .../icons/components/tdbreallookupdb.png | Bin 0 -> 651 bytes .../icons/components/tdbreallookupdb.svg | 385 + .../icons/components/tdbreallookuplb.png | Bin 0 -> 613 bytes .../icons/components/tdbreallookuplb.svg | 384 + .../icons/components/tdbreallookupstrdb.png | Bin 0 -> 823 bytes .../icons/components/tdbreallookupstrdb.svg | 396 + .../icons/components/tdbreallookupstrlb.png | Bin 0 -> 787 bytes .../icons/components/tdbreallookupstrlb.svg | 395 + .../icons/components/tdbrealspinedit.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbrealspinedit.png | Bin 0 -> 486 bytes .../icons/components/tdbrealspinedit.svg | 246 + mseide-msegui/icons/components/tdbslider.bmp | Bin 0 -> 1782 bytes mseide-msegui/icons/components/tdbslider.png | Bin 0 -> 540 bytes mseide-msegui/icons/components/tdbslider.svg | 813 + .../icons/components/tdbstingdisp.png | Bin 0 -> 630 bytes .../icons/components/tdbstingdisplb.png | Bin 0 -> 687 bytes .../icons/components/tdbstringdisp.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbstringdisp.png | Bin 0 -> 658 bytes .../icons/components/tdbstringdisp.svg | 371 + .../icons/components/tdbstringdisplb.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbstringdisplb.png | Bin 0 -> 718 bytes .../icons/components/tdbstringdisplb.svg | 375 + .../icons/components/tdbstringedit.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbstringedit.png | Bin 0 -> 589 bytes .../icons/components/tdbstringedit.svg | 244 + .../icons/components/tdbstringgrid.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbstringgrid.png | Bin 0 -> 1333 bytes .../icons/components/tdbstringgrid.svg | 564 + .../icons/components/tdbstringlookup64db.png | Bin 0 -> 970 bytes .../icons/components/tdbstringlookup64db.svg | 396 + .../icons/components/tdbstringlookup64lb.png | Bin 0 -> 921 bytes .../icons/components/tdbstringlookup64lb.svg | 395 + .../icons/components/tdbstringlookupdb.png | Bin 0 -> 746 bytes .../icons/components/tdbstringlookupdb.svg | 385 + .../icons/components/tdbstringlookuplb.png | Bin 0 -> 707 bytes .../icons/components/tdbstringlookuplb.svg | 384 + .../icons/components/tdbstringlookupstrdb.png | Bin 0 -> 935 bytes .../icons/components/tdbstringlookupstrdb.svg | 396 + .../icons/components/tdbstringlookupstrlb.png | Bin 0 -> 882 bytes .../icons/components/tdbstringlookupstrlb.svg | 395 + .../icons/components/tdbwidgetgrid.bmp | Bin 0 -> 1782 bytes .../icons/components/tdbwidgetgrid.png | Bin 0 -> 898 bytes .../icons/components/tdbwidgetgrid.svg | 534 + mseide-msegui/icons/components/tdial.bmp | Bin 0 -> 1782 bytes .../icons/components/tdialogstringedit.bmp | Bin 0 -> 1782 bytes .../icons/components/tdialogstringedit.png | Bin 0 -> 537 bytes .../icons/components/tdialogstringedit.svg | 302 + .../icons/components/tdigesthandler.png | Bin 0 -> 868 bytes .../icons/components/tdigesthandler.svg | 221 + .../icons/components/tdintegerblookup64db.png | Bin 0 -> 985 bytes .../icons/components/tdirdropdownedit.bmp | Bin 0 -> 406 bytes .../icons/components/tdirdropdownedit.png | Bin 0 -> 714 bytes .../icons/components/tdirdropdownedit.svg | 385 + .../icons/components/tdirtreeview.png | Bin 0 -> 516 bytes .../icons/components/tdirtreeview.svg | 217 + .../icons/components/tdirtreeview2.svg | 243 + .../icons/components/tdispwidget.bmp | Bin 0 -> 406 bytes .../icons/components/tdmdatetimedisp.png | Bin 0 -> 530 bytes .../icons/components/tdmemoblookupbuffer.bmp | Bin 0 -> 1782 bytes .../icons/components/tdockformwidget.bmp | Bin 0 -> 406 bytes .../icons/components/tdockformwidget.png | Bin 0 -> 434 bytes .../icons/components/tdockformwidget.svg | 371 + .../icons/components/tdockhandle.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/tdockpanel.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/tdockpanel.png | Bin 0 -> 231 bytes mseide-msegui/icons/components/tdockpanel.svg | 315 + .../components/tdockpanelformcontroller.png | Bin 0 -> 814 bytes .../components/tdockpanelformcontroller.svg | 481 + mseide-msegui/icons/components/tdrawgrid.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/tdrawgrid.png | Bin 0 -> 1075 bytes mseide-msegui/icons/components/tdrawgrid.svg | 613 + .../icons/components/tdropdownitemedit.bmp | Bin 0 -> 406 bytes .../icons/components/tdropdownitemedit.png | Bin 0 -> 315 bytes .../icons/components/tdropdownitemedit.svg | 279 + .../icons/components/tdropdownlistedit.bmp | Bin 0 -> 406 bytes .../icons/components/tdropdownlistedit.png | Bin 0 -> 843 bytes .../icons/components/tdropdownlistedit.svg | 458 + .../icons/components/tdropdownlisteditdb.png | Bin 0 -> 964 bytes .../icons/components/tdropdownlisteditdb.svg | 465 + .../icons/components/tdropdownlisteditlb.png | Bin 0 -> 967 bytes .../icons/components/tdropdownlisteditlb.svg | 465 + .../icons/components/tdummycryptohandler.png | Bin 0 -> 812 bytes .../icons/components/tdummycryptohandler.svg | 221 + mseide-msegui/icons/components/tedit.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/tedit.png | Bin 0 -> 243 bytes mseide-msegui/icons/components/tedit.svg | 221 + .../icons/components/tenum64editdb.bmp | Bin 0 -> 1782 bytes .../icons/components/tenum64editdb.png | Bin 0 -> 1000 bytes .../icons/components/tenum64editdb.svg | 452 + .../icons/components/tenum64editlb.bmp | Bin 0 -> 1782 bytes .../icons/components/tenum64editlb.png | Bin 0 -> 999 bytes .../icons/components/tenum64editlb.svg | 452 + mseide-msegui/icons/components/tenumedit.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/tenumedit.png | Bin 0 -> 910 bytes mseide-msegui/icons/components/tenumedit.svg | 438 + .../icons/components/tenumeditdb.bmp | Bin 0 -> 1782 bytes .../icons/components/tenumeditdb.png | Bin 0 -> 1004 bytes .../icons/components/tenumeditdb.svg | 445 + .../icons/components/tenumeditedit.png | Bin 0 -> 910 bytes .../icons/components/tenumeditlb.bmp | Bin 0 -> 1782 bytes .../icons/components/tenumeditlb.png | Bin 0 -> 1016 bytes .../icons/components/tenumeditlb.svg | 445 + .../icons/components/tenumtypeedit.bmp | Bin 0 -> 406 bytes .../icons/components/tenumtypeedit.png | Bin 0 -> 673 bytes .../icons/components/tenumtypeedit.svg | 462 + .../icons/components/tenvelopeedit.png | Bin 0 -> 613 bytes .../icons/components/tenvelopeedit.svg | 281 + mseide-msegui/icons/components/test.bmp | Bin 0 -> 1782 bytes mseide-msegui/icons/components/test.pnm | Bin 0 -> 1786 bytes mseide-msegui/icons/components/test.svg | 236 + .../icons/components/teventwidget.bmp | Bin 0 -> 406 bytes .../icons/components/teventwidget.png | Bin 0 -> 710 bytes .../icons/components/teventwidget.svg | 268 + .../icons/components/texpandingwidget.png | Bin 0 -> 821 bytes .../icons/components/texpandingwidget.svg | 191 + mseide-msegui/icons/components/text3429.png | Bin 0 -> 569 bytes mseide-msegui/icons/components/tfacecomp.bmp | Bin 0 -> 1782 bytes mseide-msegui/icons/components/tfacecomp.png | Bin 0 -> 380 bytes mseide-msegui/icons/components/tfacecomp.svg | 269 + mseide-msegui/icons/components/tfacelist.bmp | Bin 0 -> 1782 bytes mseide-msegui/icons/components/tfacelist.png | Bin 0 -> 287 bytes mseide-msegui/icons/components/tfacelist.svg | 346 + .../icons/components/tfb3connection.png | Bin 0 -> 1350 bytes .../icons/components/tfb3connection.svg | 448 + .../icons/components/tfb3service.png | Bin 0 -> 1628 bytes .../icons/components/tfb3service.svg | 461 + .../icons/components/tfbconnection.png | Bin 0 -> 1469 bytes .../icons/components/tfbconnection.svg | 446 + mseide-msegui/icons/components/tfbservice.png | Bin 0 -> 1568 bytes mseide-msegui/icons/components/tfbservice.svg | 449 + mseide-msegui/icons/components/tfft.png | Bin 0 -> 499 bytes mseide-msegui/icons/components/tfft.svg | 233 + .../icons/components/tffttableedit.png | Bin 0 -> 331 bytes .../icons/components/tffttableedit.svg | 274 + .../icons/components/tfieldfieldlink.bmp | Bin 0 -> 1782 bytes .../icons/components/tfieldfieldlink.png | Bin 0 -> 551 bytes .../icons/components/tfieldfieldlink.svg | 213 + mseide-msegui/icons/components/tfieldlink.bmp | Bin 0 -> 1782 bytes mseide-msegui/icons/components/tfieldlink.png | Bin 0 -> 645 bytes mseide-msegui/icons/components/tfieldlink.svg | 201 + .../icons/components/tfieldparamlink.bmp | Bin 0 -> 1782 bytes .../icons/components/tfieldparamlink.png | Bin 0 -> 619 bytes .../icons/components/tfieldparamlink.svg | 213 + .../icons/components/tfilechangenotifier.png | Bin 0 -> 934 bytes .../icons/components/tfilechangenotifier.svg | 275 + .../icons/components/tfilechangenotifyer.bmp | Bin 0 -> 406 bytes .../icons/components/tfilechangenotifyer.png | Bin 0 -> 1018 bytes .../icons/components/tfilechangenotifyer.svg | 306 + .../icons/components/tfiledialog.bmp | Bin 0 -> 406 bytes .../icons/components/tfiledialog.png | Bin 0 -> 531 bytes .../icons/components/tfiledialog.svg | 385 + .../icons/components/tfilelistview.bmp | Bin 0 -> 406 bytes .../icons/components/tfilelistview.png | Bin 0 -> 345 bytes .../icons/components/tfilelistview.svg | 211 + .../icons/components/tfilenameedit.bmp | Bin 0 -> 406 bytes .../icons/components/tfilenameedit.png | Bin 0 -> 379 bytes .../icons/components/tfilenameedit.svg | 245 + mseide-msegui/icons/components/tfoldedit.png | Bin 0 -> 761 bytes mseide-msegui/icons/components/tfoldedit.svg | 246 + mseide-msegui/icons/components/tfontcomp.png | Bin 0 -> 787 bytes mseide-msegui/icons/components/tfontcomp.svg | 216 + mseide-msegui/icons/components/tformlink.bmp | Bin 0 -> 1782 bytes .../icons/components/tformwidget.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/tframecomp.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/tframecomp.png | Bin 0 -> 394 bytes mseide-msegui/icons/components/tframecomp.svg | 258 + .../icons/components/tfunctableedit.png | Bin 0 -> 548 bytes .../icons/components/tfunctableedit.svg | 266 + .../icons/components/tfuncttableedit.png | Bin 0 -> 556 bytes .../icons/components/tfuncttableedit.svg | 280 + mseide-msegui/icons/components/tgdbmi.bmp | Bin 0 -> 406 bytes .../icons/components/tgdiprinter.bmp | Bin 0 -> 1782 bytes .../icons/components/tgdiprinter.png | Bin 0 -> 1181 bytes .../icons/components/tgdiprinter.svg | 331 + mseide-msegui/icons/components/tgroupbox.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/tgroupbox.png | Bin 0 -> 354 bytes mseide-msegui/icons/components/tgroupbox.svg | 315 + .../icons/components/tguiprocess.png | Bin 0 -> 1013 bytes .../icons/components/tguiprocess.svg | 228 + .../icons/components/tguirttistat.png | Bin 0 -> 1259 bytes .../icons/components/tguirttistat.svg | 329 + .../icons/components/tguithreadcomp.bmp | Bin 0 -> 406 bytes .../icons/components/tguithreadcomp.png | Bin 0 -> 616 bytes .../icons/components/tguithreadcomp.svg | 491 + .../icons/components/thelpcontroller.png | Bin 0 -> 994 bytes .../icons/components/thelpcontroller.svg | 220 + .../icons/components/thexstringedit.bmp | Bin 0 -> 1782 bytes .../icons/components/thexstringedit.png | Bin 0 -> 513 bytes .../icons/components/thexstringedit.svg | 250 + .../icons/components/thistoryedit.bmp | Bin 0 -> 406 bytes .../icons/components/thistoryedit.png | Bin 0 -> 679 bytes .../icons/components/thistoryedit.svg | 447 + mseide-msegui/icons/components/thread.bmp | Bin 0 -> 1782 bytes mseide-msegui/icons/components/ticon.png | Bin 0 -> 489 bytes mseide-msegui/icons/components/ticon.svg | 225 + .../icons/components/tifiactionendpoint.png | Bin 0 -> 857 bytes .../icons/components/tifiactionendpoint.svg | 333 + .../icons/components/tifiactionlinkcomp.png | Bin 0 -> 894 bytes .../icons/components/tifiactionlinkcomp.svg | 332 + .../icons/components/tifibooleanendpoint.png | Bin 0 -> 473 bytes .../icons/components/tifibooleanendpoint.svg | 220 + .../icons/components/tifibooleanlinkcomp.png | Bin 0 -> 518 bytes .../icons/components/tifibooleanlinkcomp.svg | 232 + .../icons/components/tifidatetimeendpoint.png | Bin 0 -> 419 bytes .../icons/components/tifidatetimeendpoint.svg | 219 + .../icons/components/tifidatetimelinkcomp.png | Bin 0 -> 454 bytes .../icons/components/tifidatetimelinkcomp.svg | 231 + mseide-msegui/icons/components/tifidialog.png | Bin 0 -> 761 bytes mseide-msegui/icons/components/tifidialog.svg | 402 + .../icons/components/tifidialogendpoint.png | Bin 0 -> 698 bytes .../icons/components/tifidialogendpoint.svg | 220 + .../icons/components/tifidialoglinkcomp.png | Bin 0 -> 701 bytes .../icons/components/tifidialoglinkcomp.svg | 225 + .../icons/components/tifidropdownendpoint.png | Bin 0 -> 1202 bytes .../icons/components/tifidropdownendpoint.svg | 483 + .../components/tifidropdownlistlinkcomp.png | Bin 0 -> 570 bytes .../components/tifidropdownlistlinkcomp.svg | 224 + .../icons/components/tifienumendpoint.png | Bin 0 -> 528 bytes .../icons/components/tifienumendpoint.svg | 219 + .../icons/components/tifienumlinkcomp.png | Bin 0 -> 544 bytes .../icons/components/tifienumlinkcomp.svg | 224 + .../icons/components/tififormlinkcomp.png | Bin 0 -> 609 bytes .../icons/components/tififormlinkcomp.svg | 225 + .../icons/components/tifigridlinkcomp.png | Bin 0 -> 1575 bytes .../icons/components/tifigridlinkcomp.svg | 459 + .../icons/components/tifigtidlinkcomp.png | Bin 0 -> 1592 bytes .../icons/components/tifiint64endpoint.png | Bin 0 -> 505 bytes .../icons/components/tifiint64endpoint.svg | 219 + .../icons/components/tifiint64linkcomp.png | Bin 0 -> 552 bytes .../icons/components/tifiint64linkcomp.svg | 224 + .../icons/components/tifiintegerendpoint.png | Bin 0 -> 545 bytes .../icons/components/tifiintegerendpoint.svg | 225 + .../icons/components/tifiintegerlinkcomp.png | Bin 0 -> 593 bytes .../icons/components/tifiintegerlinkcomp.svg | 224 + .../icons/components/tifiitemlinkcomp.png | Bin 0 -> 483 bytes .../icons/components/tifiitemlinkcomp.svg | 225 + .../icons/components/tifilinkcomp.png | Bin 0 -> 928 bytes .../icons/components/tifilinkcomp.svg | 216 + .../icons/components/tifipointerendpoint.png | Bin 0 -> 421 bytes .../icons/components/tifipointerendpoint.svg | 219 + .../icons/components/tifipointerlinkcomp.png | Bin 0 -> 460 bytes .../icons/components/tifipointerlinkcomp.svg | 231 + .../icons/components/tifirealendpoint.png | Bin 0 -> 547 bytes .../icons/components/tifirealendpoint.svg | 219 + .../icons/components/tifireallinkcomp.png | Bin 0 -> 598 bytes .../icons/components/tifireallinkcomp.svg | 224 + .../icons/components/tifisqlresult.png | Bin 0 -> 832 bytes .../icons/components/tifisqlresult.svg | 398 + .../icons/components/tifistringendpoint.png | Bin 0 -> 620 bytes .../icons/components/tifistringendpoint.svg | 219 + .../icons/components/tifistringlinkcomp.png | Bin 0 -> 662 bytes .../icons/components/tifistringlinkcomp.svg | 208 + .../icons/components/tifitreeitemlinkcomp.png | Bin 0 -> 504 bytes .../icons/components/tifitreeitemlinkcomp.svg | 225 + mseide-msegui/icons/components/timage.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/timage.png | Bin 0 -> 809 bytes mseide-msegui/icons/components/timage.svg | 264 + mseide-msegui/icons/components/timagelist.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/timagelist.png | Bin 0 -> 886 bytes mseide-msegui/icons/components/timagelist.svg | 498 + mseide-msegui/icons/components/tint64disp.png | Bin 0 -> 602 bytes mseide-msegui/icons/components/tint64disp.svg | 381 + mseide-msegui/icons/components/tint64edit.png | Bin 0 -> 578 bytes mseide-msegui/icons/components/tint64edit.svg | 254 + .../icons/components/tintegerdisp.bmp | Bin 0 -> 406 bytes .../icons/components/tintegerdisp.png | Bin 0 -> 670 bytes .../icons/components/tintegerdisp.svg | 380 + .../icons/components/tintegeredit.bmp | Bin 0 -> 406 bytes .../icons/components/tintegeredit.png | Bin 0 -> 516 bytes .../icons/components/tintegeredit.svg | 243 + mseide-msegui/icons/components/titemedit.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/titemedit.png | Bin 0 -> 239 bytes mseide-msegui/icons/components/titemedit.svg | 221 + .../icons/components/tkeystringcontainer.png | Bin 0 -> 1524 bytes .../icons/components/tkeystringcontainer.svg | 226 + .../icons/components/tkeystringedit.bmp | Bin 0 -> 1782 bytes .../icons/components/tkeystringedit.png | Bin 0 -> 778 bytes .../icons/components/tkeystringedit.svg | 442 + .../icons/components/tkeystringeditdb.bmp | Bin 0 -> 1782 bytes .../icons/components/tkeystringeditdb.png | Bin 0 -> 839 bytes .../icons/components/tkeystringeditdb.svg | 449 + .../icons/components/tkeystringeditlb.bmp | Bin 0 -> 1782 bytes .../icons/components/tkeystringeditlb.png | Bin 0 -> 839 bytes .../icons/components/tkeystringeditlb.svg | 449 + mseide-msegui/icons/components/tlabel.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/tlabel.png | Bin 0 -> 471 bytes mseide-msegui/icons/components/tlabel.svg | 291 + mseide-msegui/icons/components/tlayouter.bmp | Bin 0 -> 1782 bytes mseide-msegui/icons/components/tlayouter.png | Bin 0 -> 816 bytes mseide-msegui/icons/components/tlayouter.svg | 206 + mseide-msegui/icons/components/tlistview.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/tlistview.png | Bin 0 -> 1376 bytes mseide-msegui/icons/components/tlistview.svg | 555 + .../icons/components/tlocaldataset.png | Bin 0 -> 561 bytes .../icons/components/tlocaldataset.svg | 447 + .../icons/components/tlookupbuffer.bmp | Bin 0 -> 1782 bytes .../icons/components/tlookupbuffer.png | Bin 0 -> 319 bytes mseide-msegui/icons/components/tmainmenu.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/tmainmenu.png | Bin 0 -> 1051 bytes mseide-msegui/icons/components/tmainmenu.svg | 354 + .../icons/components/tmainmenuwidget.bmp | Bin 0 -> 406 bytes .../icons/components/tmainmenuwidget.png | Bin 0 -> 868 bytes .../icons/components/tmainmenuwidget.svg | 347 + .../icons/components/tmbdropdownitemedit.bmp | Bin 0 -> 406 bytes .../icons/components/tmbdropdownitemedit.png | Bin 0 -> 347 bytes .../icons/components/tmbdropdownitemedit.svg | 327 + .../icons/components/tmemodialogedit.png | Bin 0 -> 510 bytes .../icons/components/tmemodialogedit.svg | 319 + .../components/tmemodialogstringedit.svg | 290 + mseide-msegui/icons/components/tmemoedit.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/tmemoedit.png | Bin 0 -> 591 bytes mseide-msegui/icons/components/tmemoedit.svg | 261 + .../icons/components/tmidisource.png | Bin 0 -> 555 bytes .../icons/components/tmidisource.svg | 224 + .../icons/components/tmodulelink.bmp | Bin 0 -> 1782 bytes .../icons/components/tmseautoincfield.bmp | Bin 0 -> 1782 bytes .../icons/components/tmseautoincfield.png | Bin 0 -> 476 bytes .../icons/components/tmseautoincfield.svg | 193 + .../icons/components/tmsebcdfield.bmp | Bin 0 -> 1782 bytes .../icons/components/tmsebcdfield.png | Bin 0 -> 564 bytes .../icons/components/tmsebcdfield.svg | 194 + .../icons/components/tmsebinaryfield.bmp | Bin 0 -> 1782 bytes .../icons/components/tmsebinaryfield.png | Bin 0 -> 451 bytes .../icons/components/tmsebinaryfield.svg | 193 + .../icons/components/tmseblobfield.bmp | Bin 0 -> 1782 bytes .../icons/components/tmseblobfield.png | Bin 0 -> 542 bytes .../icons/components/tmseblobfield.svg | 194 + .../icons/components/tmsebooleanfield.bmp | Bin 0 -> 1782 bytes .../icons/components/tmsebooleanfield.png | Bin 0 -> 413 bytes .../icons/components/tmsebooleanfield.svg | 193 + .../icons/components/tmsebytesfield.bmp | Bin 0 -> 1782 bytes .../icons/components/tmsebytesfield.png | Bin 0 -> 591 bytes .../icons/components/tmsebytesfield.svg | 193 + .../icons/components/tmsecurrencyfield.bmp | Bin 0 -> 1782 bytes .../icons/components/tmsecurrencyfield.png | Bin 0 -> 525 bytes .../icons/components/tmsecurrencyfield.svg | 193 + .../icons/components/tmsedatasource.png | Bin 0 -> 392 bytes .../icons/components/tmsedatasource.svg | 436 + .../icons/components/tmsedatefield.bmp | Bin 0 -> 1782 bytes .../icons/components/tmsedatefield.png | Bin 0 -> 334 bytes .../icons/components/tmsedatefield.svg | 193 + .../icons/components/tmsedatetimefield.bmp | Bin 0 -> 1782 bytes .../icons/components/tmsedatetimefield.png | Bin 0 -> 425 bytes .../icons/components/tmsedatetimefield.svg | 193 + mseide-msegui/icons/components/tmsedbf.bmp | Bin 0 -> 1782 bytes mseide-msegui/icons/components/tmsedbf.png | Bin 0 -> 469 bytes mseide-msegui/icons/components/tmsedbf.svg | 440 + .../icons/components/tmsefixdataset.png | Bin 0 -> 435 bytes .../icons/components/tmsefixedataset.png | Bin 0 -> 435 bytes .../components/tmsefixedformatdataset.bmp | Bin 0 -> 1782 bytes .../components/tmsefixedformatdataset.png | Bin 0 -> 435 bytes .../components/tmsefixedformatdataset.svg | 440 + .../components/tmsefixedfornatdataset.png | Bin 0 -> 435 bytes .../icons/components/tmsefloatfield.bmp | Bin 0 -> 1782 bytes .../icons/components/tmsefloatfield.png | Bin 0 -> 395 bytes .../icons/components/tmsefloatfield.svg | 193 + .../icons/components/tmseflotfield.png | Bin 0 -> 395 bytes .../icons/components/tmseformwidget.bmp | Bin 0 -> 406 bytes .../icons/components/tmseformwidget.png | Bin 0 -> 386 bytes .../icons/components/tmseformwidget.svg | 351 + .../icons/components/tmsegraphicfield.bmp | Bin 0 -> 1782 bytes .../icons/components/tmsegraphicfield.png | Bin 0 -> 803 bytes .../icons/components/tmsegraphicfield.svg | 264 + .../icons/components/tmseguidfield.png | Bin 0 -> 551 bytes .../icons/components/tmseguidfield.svg | 195 + .../icons/components/tmseibconnection.bmp | Bin 0 -> 1782 bytes .../icons/components/tmseibconnection.png | Bin 0 -> 1295 bytes .../icons/components/tmseibconnection.svg | 432 + .../icons/components/tmselargeintfield.bmp | Bin 0 -> 1782 bytes .../icons/components/tmselargeintfield.png | Bin 0 -> 479 bytes .../icons/components/tmselargeintfield.svg | 193 + .../icons/components/tmselongintfield.bmp | Bin 0 -> 1782 bytes .../icons/components/tmselongintfield.png | Bin 0 -> 501 bytes .../icons/components/tmselongintfield.svg | 193 + .../icons/components/tmsememdataset.bmp | Bin 0 -> 1782 bytes .../icons/components/tmsememdataset.png | Bin 0 -> 539 bytes .../icons/components/tmsememdataset.svg | 434 + .../icons/components/tmsememofield.bmp | Bin 0 -> 1782 bytes .../icons/components/tmsememofield.png | Bin 0 -> 627 bytes .../icons/components/tmsememofield.svg | 198 + .../components/tmsemysql40connection.bmp | Bin 0 -> 1782 bytes .../components/tmsemysql41connection.bmp | Bin 0 -> 1782 bytes .../components/tmsemysql50connection.bmp | Bin 0 -> 1782 bytes .../icons/components/tmsemysqlconnection.png | Bin 0 -> 1074 bytes .../icons/components/tmsemysqlconnection.svg | 159 + .../icons/components/tmseodbcconnection.bmp | Bin 0 -> 1782 bytes .../icons/components/tmseodbcconnection.png | Bin 0 -> 879 bytes .../icons/components/tmseodbcconnection.svg | 471 + .../icons/components/tmsepqconnection.bmp | Bin 0 -> 1782 bytes .../icons/components/tmseprocess.png | Bin 0 -> 1032 bytes .../icons/components/tmseprocess.svg | 216 + .../icons/components/tmsesdfdataset.bmp | Bin 0 -> 1782 bytes .../icons/components/tmsesdfdataset.png | Bin 0 -> 530 bytes .../icons/components/tmsesdfdataset.svg | 410 + .../icons/components/tmsesmallintfield.bmp | Bin 0 -> 1782 bytes .../icons/components/tmsesmallintfield.png | Bin 0 -> 418 bytes .../icons/components/tmsesmallintfield.svg | 193 + .../icons/components/tmsesqlite3dataset.bmp | Bin 0 -> 1782 bytes .../icons/components/tmsesqlquery.bmp | Bin 0 -> 1782 bytes .../icons/components/tmsesqlquery.png | Bin 0 -> 609 bytes .../icons/components/tmsesqlquery.svg | 433 + .../icons/components/tmsesqlscript.bmp | Bin 0 -> 1782 bytes .../icons/components/tmsesqlscript.png | Bin 0 -> 584 bytes .../icons/components/tmsesqlscript.svg | 397 + .../icons/components/tmsesqltransaction.bmp | Bin 0 -> 1782 bytes .../icons/components/tmsesqltransaction.png | Bin 0 -> 1002 bytes .../icons/components/tmsesqltransaction.svg | 432 + .../icons/components/tmsestringfield.bmp | Bin 0 -> 1782 bytes .../icons/components/tmsestringfield.png | Bin 0 -> 500 bytes .../icons/components/tmsestringfield.svg | 193 + .../icons/components/tmsetimefield.bmp | Bin 0 -> 1782 bytes .../icons/components/tmsetimefield.png | Bin 0 -> 274 bytes .../icons/components/tmsetimefield.svg | 193 + .../icons/components/tmsevarbytesfield.bmp | Bin 0 -> 1782 bytes .../icons/components/tmsevarbytesfield.png | Bin 0 -> 568 bytes .../icons/components/tmsevarbytesfield.svg | 193 + .../icons/components/tmsevarfield.svg | 193 + .../icons/components/tmsevariantfield.png | Bin 0 -> 553 bytes .../icons/components/tmsevariantfield.svg | 193 + .../icons/components/tmsewordfield.bmp | Bin 0 -> 1782 bytes .../icons/components/tmsewordfield.png | Bin 0 -> 490 bytes .../icons/components/tmsewordfield.svg | 193 + mseide-msegui/icons/components/tmsezquery.bmp | Bin 0 -> 1654 bytes .../icons/components/tmsezreadonlyquery.bmp | Bin 0 -> 1654 bytes mseide-msegui/icons/components/tmseztable.bmp | Bin 0 -> 1654 bytes .../icons/components/tnoguiaction.bmp | Bin 0 -> 406 bytes .../icons/components/tnoguiaction.png | Bin 0 -> 914 bytes .../icons/components/tnoguiaction.svg | 290 + .../icons/components/topenglcanvaswidget.png | Bin 0 -> 949 bytes .../icons/components/topenglcanvaswidget.svg | 293 + .../icons/components/topenglwidget.bmp | Bin 0 -> 1782 bytes .../icons/components/topenglwidget.png | Bin 0 -> 559 bytes .../icons/components/topenglwidget.svg | 288 + .../components/topensslcryptohandler.png | Bin 0 -> 841 bytes .../components/topensslcryptohandler.svg | 219 + .../components/tpageorientationselector.png | Bin 0 -> 778 bytes .../components/tpageorientationselector.svg | 430 + .../icons/components/tpagesizeselector.png | Bin 0 -> 707 bytes .../icons/components/tpagesizeselector.svg | 430 + mseide-msegui/icons/components/tpaintbox.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/tpaintbox.png | Bin 0 -> 718 bytes mseide-msegui/icons/components/tpaintbox.svg | 279 + .../icons/components/tparamconnector.png | Bin 0 -> 525 bytes .../icons/components/tparamconnector.svg | 195 + mseide-msegui/icons/components/tparamlink.svg | 195 + .../icons/components/tpickwidget.png | Bin 0 -> 1135 bytes .../icons/components/tpickwidget.svg | 288 + .../icons/components/tpipeiochannel.bmp | Bin 0 -> 1782 bytes .../icons/components/tpipereader.png | Bin 0 -> 1254 bytes .../icons/components/tpipereader.svg | 473 + .../icons/components/tpipereadercomp.bmp | Bin 0 -> 406 bytes .../icons/components/tpipereadercomp.png | Bin 0 -> 1245 bytes .../icons/components/tpipereadercomp.svg | 473 + .../icons/components/tpointeredit.bmp | Bin 0 -> 406 bytes .../icons/components/tpointeredit.png | Bin 0 -> 362 bytes .../icons/components/tpointeredit.svg | 232 + mseide-msegui/icons/components/tpolygon.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/tpolygon.png | Bin 0 -> 728 bytes mseide-msegui/icons/components/tpolygon.svg | 289 + mseide-msegui/icons/components/tpopupmenu.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/tpopupmenu.png | Bin 0 -> 1046 bytes mseide-msegui/icons/components/tpopupmenu.svg | 290 + .../icons/components/tpostscriptprinter.bmp | Bin 0 -> 1782 bytes .../icons/components/tpostscriptprinter.png | Bin 0 -> 1210 bytes .../icons/components/tpostscriptprinter.svg | 354 + mseide-msegui/icons/components/tprinter.bmp | Bin 0 -> 1782 bytes .../icons/components/tprocessmonitor.bmp | Bin 0 -> 1782 bytes .../icons/components/tprocessmonitor.png | Bin 0 -> 1132 bytes .../icons/components/tprocessmonitor.svg | 279 + .../icons/components/tprogressbar.bmp | Bin 0 -> 1782 bytes .../icons/components/tprogressbar.png | Bin 0 -> 279 bytes .../icons/components/tprogressbar.svg | 228 + mseide-msegui/icons/components/tpsprinter.png | Bin 0 -> 1210 bytes mseide-msegui/icons/components/tpsprinter.svg | 354 + .../icons/components/tpythonscript.png | Bin 0 -> 863 bytes .../icons/components/tpythonscript.svg | 217 + mseide-msegui/icons/components/tra.png | Bin 0 -> 322 bytes mseide-msegui/icons/components/trealdisp.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/trealdisp.png | Bin 0 -> 585 bytes mseide-msegui/icons/components/trealdisp.svg | 380 + mseide-msegui/icons/components/trealedit.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/trealedit.png | Bin 0 -> 446 bytes mseide-msegui/icons/components/trealedit.svg | 243 + .../icons/components/trealspinedit.bmp | Bin 0 -> 406 bytes .../icons/components/trealspinedit.png | Bin 0 -> 471 bytes .../icons/components/trealspinedit.svg | 246 + .../icons/components/trecordband.bmp | Bin 0 -> 1782 bytes .../icons/components/trecordfieldedit.png | Bin 0 -> 522 bytes .../icons/components/trecordfieldedit.svg | 258 + .../icons/components/treportpage.png | Bin 0 -> 1194 bytes .../icons/components/treportpage.svg | 247 + .../icons/components/treppagenumdisp.bmp | Bin 0 -> 1782 bytes .../icons/components/trepprintdatedisp.bmp | Bin 0 -> 1782 bytes mseide-msegui/icons/components/treppsdisp.png | Bin 0 -> 584 bytes mseide-msegui/icons/components/treppsdisp.svg | 243 + mseide-msegui/icons/components/trepspacer.bmp | Bin 0 -> 1782 bytes .../icons/components/trepvaluedisp.bmp | Bin 0 -> 1782 bytes .../icons/components/trichbutton.bmp | Bin 0 -> 1782 bytes .../icons/components/trichbutton.png | Bin 0 -> 662 bytes .../icons/components/trichbutton.svg | 220 + .../components/trichstockglyphbutton.bmp | 66 + .../components/trichstockglyphbutton.png | Bin 0 -> 470 bytes .../components/trichstockglyphbutton.svg | 218 + .../icons/components/trichstringdisp.png | Bin 0 -> 666 bytes .../icons/components/trichstringdisp.svg | 388 + mseide-msegui/icons/components/trttistat.png | Bin 0 -> 1226 bytes mseide-msegui/icons/components/trttistat.svg | 299 + mseide-msegui/icons/components/true_false.png | Bin 0 -> 382 bytes mseide-msegui/icons/components/trxdataset.bmp | Bin 0 -> 1782 bytes .../icons/components/trxwidgetgrid.bmp | Bin 0 -> 1782 bytes mseide-msegui/icons/components/tscrollbox.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/tscrollbox.png | Bin 0 -> 327 bytes mseide-msegui/icons/components/tscrollbox.svg | 413 + mseide-msegui/icons/components/tselector.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/tselector.png | Bin 0 -> 704 bytes mseide-msegui/icons/components/tselector.svg | 449 + .../icons/components/tsequencelink.bmp | Bin 0 -> 1782 bytes .../icons/components/tsequencelink.png | Bin 0 -> 466 bytes .../icons/components/tsequencelink.svg | 222 + .../icons/components/tsercommchannel.png | Bin 0 -> 1062 bytes .../icons/components/tsercommchannel.svg | 215 + .../icons/components/tsercommcomp.png | Bin 0 -> 1300 bytes .../icons/components/tsercommcomp.svg | 213 + mseide-msegui/icons/components/tshortcut.bmp | Bin 0 -> 1782 bytes .../icons/components/tshortcutcontroller.bmp | Bin 0 -> 1782 bytes .../icons/components/tshortcutcontroller.png | Bin 0 -> 867 bytes .../icons/components/tshortcutcontroller.svg | 224 + mseide-msegui/icons/components/tsigadd.png | Bin 0 -> 735 bytes mseide-msegui/icons/components/tsigadd.svg | 222 + .../icons/components/tsigconnector.png | Bin 0 -> 774 bytes .../icons/components/tsigconnector.svg | 268 + .../icons/components/tsigcontroller.png | Bin 0 -> 955 bytes .../icons/components/tsigcontroller.svg | 226 + mseide-msegui/icons/components/tsigdelay.png | Bin 0 -> 822 bytes mseide-msegui/icons/components/tsigdelay.svg | 233 + mseide-msegui/icons/components/tsigdelayn.png | Bin 0 -> 861 bytes mseide-msegui/icons/components/tsigdelayn.svg | 233 + .../icons/components/tsigdelayvar.png | Bin 0 -> 884 bytes .../icons/components/tsigdelayvar.svg | 233 + .../icons/components/tsigenvelope.png | Bin 0 -> 955 bytes .../icons/components/tsigenvelope.svg | 256 + mseide-msegui/icons/components/tsigfft.png | Bin 0 -> 850 bytes mseide-msegui/icons/components/tsigfft.svg | 233 + mseide-msegui/icons/components/tsigfilter.png | Bin 0 -> 922 bytes mseide-msegui/icons/components/tsigfilter.svg | 252 + .../icons/components/tsigfilterbank.png | Bin 0 -> 1621 bytes .../icons/components/tsigfilterbank.svg | 320 + mseide-msegui/icons/components/tsigfir.png | Bin 0 -> 895 bytes mseide-msegui/icons/components/tsigfir.svg | 233 + .../icons/components/tsigfunctable.png | Bin 0 -> 902 bytes .../icons/components/tsigfunctable.svg | 252 + .../icons/components/tsigfuncttable.png | Bin 0 -> 902 bytes .../icons/components/tsigfuncttable.svg | 252 + mseide-msegui/icons/components/tsigiir.png | Bin 0 -> 813 bytes mseide-msegui/icons/components/tsigiir.svg | 233 + mseide-msegui/icons/components/tsigin.png | Bin 0 -> 846 bytes mseide-msegui/icons/components/tsigin.svg | 254 + .../icons/components/tsigkeyboard.png | Bin 0 -> 955 bytes .../icons/components/tsigkeyboard.svg | 348 + .../icons/components/tsigmidiconnector.png | Bin 0 -> 1173 bytes .../icons/components/tsigmidiconnector.svg | 272 + .../components/tsigmidimulticonnector.png | Bin 0 -> 1231 bytes .../components/tsigmidimulticonnector.svg | 311 + .../icons/components/tsigmidisource.png | Bin 0 -> 947 bytes .../icons/components/tsigmidisource.svg | 233 + mseide-msegui/icons/components/tsigmult.png | Bin 0 -> 786 bytes mseide-msegui/icons/components/tsigmult.svg | 223 + mseide-msegui/icons/components/tsignoise.png | Bin 0 -> 1321 bytes mseide-msegui/icons/components/tsignoise.svg | 250 + mseide-msegui/icons/components/tsigout.png | Bin 0 -> 1056 bytes mseide-msegui/icons/components/tsigout.svg | 248 + .../icons/components/tsigoutaudio.png | Bin 0 -> 1284 bytes .../icons/components/tsigoutaudio.svg | 252 + .../icons/components/tsigsampler.png | Bin 0 -> 1439 bytes .../icons/components/tsigsampler.svg | 237 + .../icons/components/tsigsamplerfft.png | Bin 0 -> 1385 bytes .../icons/components/tsigsamplerfft.svg | 237 + mseide-msegui/icons/components/tsigscope.png | Bin 0 -> 1153 bytes mseide-msegui/icons/components/tsigscope.svg | 342 + .../icons/components/tsigscopefft.png | Bin 0 -> 739 bytes .../icons/components/tsigscopefft.svg | 380 + .../icons/components/tsigwavetable.png | Bin 0 -> 1180 bytes .../icons/components/tsigwavetable.svg | 251 + .../icons/components/tsimplewidget.bmp | Bin 0 -> 1782 bytes .../icons/components/tsimplewidget.png | Bin 0 -> 632 bytes .../icons/components/tsimplewidget.svg | 165 + .../icons/components/tsimplewidgt.bmp | Bin 0 -> 1782 bytes .../icons/components/tskincontroller.bmp | Bin 0 -> 1782 bytes .../icons/components/tskincontroller.png | Bin 0 -> 415 bytes .../icons/components/tskincontroller.svg | 289 + .../icons/components/tskinextender.png | Bin 0 -> 422 bytes .../icons/components/tskinextender.svg | 290 + mseide-msegui/icons/components/tslider.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/tslider.png | Bin 0 -> 626 bytes mseide-msegui/icons/components/tslider.svg | 813 + .../icons/components/tsocketclient.bmp | Bin 0 -> 1782 bytes .../components/tsocketclientiochannel.bmp | Bin 0 -> 1782 bytes .../icons/components/tsocketclientstdio.bmp | Bin 0 -> 1782 bytes .../icons/components/tsocketserver.bmp | Bin 0 -> 1782 bytes .../components/tsocketserveriochannel.bmp | Bin 0 -> 1782 bytes .../icons/components/tsocketserverstdio.bmp | Bin 0 -> 1782 bytes .../icons/components/tsocketstdio.bmp | Bin 0 -> 1782 bytes .../icons/components/tsocketstdiochannel.bmp | Bin 0 -> 1782 bytes .../icons/components/tsourceedit.png | Bin 0 -> 1100 bytes .../icons/components/tsourceedit.svg | 270 + mseide-msegui/icons/components/tspacer.bmp | Bin 0 -> 1782 bytes mseide-msegui/icons/components/tspacer.png | Bin 0 -> 738 bytes mseide-msegui/icons/components/tspacer.svg | 190 + mseide-msegui/icons/components/tsplitter.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/tsplitter.png | Bin 0 -> 704 bytes mseide-msegui/icons/components/tsplitter.svg | 192 + .../icons/components/tsqlite3connection.bmp | Bin 0 -> 1782 bytes .../icons/components/tsqllookupbuffer.bmp | Bin 0 -> 1782 bytes .../icons/components/tsqllookupbuffer.png | Bin 0 -> 438 bytes mseide-msegui/icons/components/tsqlresult.bmp | Bin 0 -> 1782 bytes mseide-msegui/icons/components/tsqlresult.png | Bin 0 -> 827 bytes mseide-msegui/icons/components/tsqlresult.svg | 407 + .../icons/components/tsqlresultconnector.png | Bin 0 -> 534 bytes .../icons/components/tsqlresultconnector.svg | 198 + .../icons/components/tsqlstatement.bmp | Bin 0 -> 1782 bytes .../icons/components/tsqlstatement.png | Bin 0 -> 577 bytes .../icons/components/tsqlstatement.svg | 397 + mseide-msegui/icons/components/tssl.bmp | Bin 0 -> 1782 bytes mseide-msegui/icons/components/tstatfile.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/tstatfile.png | Bin 0 -> 868 bytes mseide-msegui/icons/components/tstatfile.svg | 220 + mseide-msegui/icons/components/tstepbox.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/tstepbox.png | Bin 0 -> 286 bytes mseide-msegui/icons/components/tstepbox.svg | 307 + mseide-msegui/icons/components/tstingdisp.png | Bin 0 -> 681 bytes .../icons/components/tstockglyphbutton.bmp | Bin 0 -> 406 bytes .../icons/components/tstockglyphbutton.png | Bin 0 -> 431 bytes .../icons/components/tstockglyphbutton.svg | 203 + .../components/tstockglyphdatabutton.bmp | Bin 0 -> 1782 bytes .../components/tstockglyphdatabutton.png | Bin 0 -> 492 bytes .../components/tstockglyphdatabutton.svg | 259 + .../icons/components/tstringcontainer.png | Bin 0 -> 1481 bytes .../icons/components/tstringcontainer.svg | 225 + .../icons/components/tstringdisp.bmp | Bin 0 -> 406 bytes .../icons/components/tstringdisp.png | Bin 0 -> 681 bytes .../icons/components/tstringdisp.svg | 380 + .../icons/components/tstringedit.bmp | Bin 0 -> 406 bytes .../icons/components/tstringedit.png | Bin 0 -> 534 bytes .../icons/components/tstringedit.svg | 292 + .../icons/components/tstringgrid.bmp | Bin 0 -> 406 bytes .../icons/components/tstringgrid.png | Bin 0 -> 1319 bytes .../icons/components/tstringgrid.svg | 564 + .../components/tsymciphercryptohandler.png | Bin 0 -> 849 bytes .../components/tsymciphercryptohandler.svg | 218 + .../icons/components/tsyntaxedit.bmp | Bin 0 -> 406 bytes .../icons/components/tsyntaxedit.png | Bin 0 -> 1100 bytes .../icons/components/tsyntaxedit.svg | 270 + .../icons/components/tsyntaxpainter.bmp | Bin 0 -> 406 bytes .../icons/components/tsysenvmanager.bmp | Bin 0 -> 406 bytes .../icons/components/tsysenvmanager.png | Bin 0 -> 1154 bytes .../icons/components/tsysenvmanager.svg | 220 + mseide-msegui/icons/components/ttabbar.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/ttabbar.png | Bin 0 -> 463 bytes mseide-msegui/icons/components/ttabbar.svg | 440 + mseide-msegui/icons/components/ttabpage.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/ttabpage.png | Bin 0 -> 775 bytes mseide-msegui/icons/components/ttabpage.svg | 467 + mseide-msegui/icons/components/ttabwidget.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/ttabwidget.png | Bin 0 -> 582 bytes mseide-msegui/icons/components/ttabwidget.svg | 483 + mseide-msegui/icons/components/tterminal.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/tterminal.png | Bin 0 -> 464 bytes mseide-msegui/icons/components/tterminal.svg | 236 + mseide-msegui/icons/components/ttextedit.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/ttextedit.png | Bin 0 -> 1039 bytes mseide-msegui/icons/components/ttextedit.svg | 252 + .../icons/components/tthreadcomp.bmp | Bin 0 -> 406 bytes .../icons/components/tthreadcomp.png | Bin 0 -> 645 bytes .../icons/components/tthreadcomp.svg | 491 + mseide-msegui/icons/components/ttilearea.bmp | Bin 0 -> 1782 bytes mseide-msegui/icons/components/ttimer.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/ttimer.png | Bin 0 -> 1697 bytes mseide-msegui/icons/components/ttimer.svg | 616 + .../icons/components/ttimestampfieldlink.bmp | Bin 0 -> 1782 bytes .../icons/components/ttimestampfieldlink.png | Bin 0 -> 623 bytes .../icons/components/ttimestampfieldlink.svg | 201 + mseide-msegui/icons/components/ttoolbar.bmp | Bin 0 -> 406 bytes mseide-msegui/icons/components/ttoolbar.png | Bin 0 -> 513 bytes mseide-msegui/icons/components/ttoolbar.svg | 419 + .../icons/components/ttraywidget.png | Bin 0 -> 901 bytes .../icons/components/ttraywidget.svg | 285 + .../icons/components/ttreeitemedit.bmp | Bin 0 -> 406 bytes .../icons/components/ttreeitemedit.png | Bin 0 -> 279 bytes .../icons/components/ttreeitemedit.svg | 231 + .../icons/components/ttreeitemitemedit.png | Bin 0 -> 279 bytes .../icons/components/ttrigconnector.png | Bin 0 -> 1429 bytes .../icons/components/ttrigconnector.svg | 382 + .../icons/components/ttxdatagrid.bmp | Bin 0 -> 1782 bytes mseide-msegui/icons/components/ttxdataset.bmp | Bin 0 -> 1782 bytes .../icons/components/ttxsqlquery.bmp | Bin 0 -> 1782 bytes .../icons/components/tundotextedit.png | Bin 0 -> 1011 bytes .../icons/components/twavetableedit.png | Bin 0 -> 815 bytes .../icons/components/twavetableedit.svg | 258 + .../icons/components/twidgetgrid.bmp | Bin 0 -> 406 bytes .../icons/components/twidgetgrid.png | Bin 0 -> 868 bytes .../icons/components/twidgetgrid.svg | 546 + .../icons/components/twindowwidget.bmp | Bin 0 -> 1782 bytes .../icons/components/twindowwidget.png | Bin 0 -> 597 bytes .../icons/components/twindowwidget.svg | 289 + .../icons/components/twmfprinter.png | Bin 0 -> 1346 bytes .../icons/components/twmfprinter.svg | 331 + .../icons/components/txserieschartedit.png | Bin 0 -> 300 bytes .../icons/components/txserieschartedit.svg | 274 + .../icons/components/txychartedit.png | Bin 0 -> 557 bytes .../icons/components/txychartedit.svg | 316 + mseide-msegui/icons/components/typ.png | Bin 0 -> 328 bytes mseide-msegui/icons/components/type.png | Bin 0 -> 339 bytes .../icons/components/tzstreamhandler.png | Bin 0 -> 765 bytes .../icons/components/tzstreamhandler.svg | 221 + mseide-msegui/icons/components/watches.bmp | Bin 0 -> 1782 bytes mseide-msegui/icons/components/watchon.bmp | Bin 0 -> 406 bytes .../icons/components/watchpoints.bmp | Bin 0 -> 1782 bytes mseide-msegui/icons/components/wmf.png | Bin 0 -> 392 bytes mseide-msegui/icons/forms/assembler.png | Bin 0 -> 799 bytes mseide-msegui/icons/forms/assembler.svg | 454 + mseide-msegui/icons/forms/breakpoints.png | Bin 0 -> 675 bytes mseide-msegui/icons/forms/breakpoints.svg | 433 + mseide-msegui/icons/forms/componentstore.png | Bin 0 -> 614 bytes mseide-msegui/icons/forms/componentstore.svg | 569 + mseide-msegui/icons/forms/console.png | Bin 0 -> 541 bytes mseide-msegui/icons/forms/console.svg | 408 + mseide-msegui/icons/forms/cpu.png | Bin 0 -> 802 bytes mseide-msegui/icons/forms/cpu.svg | 426 + mseide-msegui/icons/forms/debugger.png | Bin 0 -> 668 bytes mseide-msegui/icons/forms/debugger.svg | 367 + mseide-msegui/icons/forms/findresults.png | Bin 0 -> 1300 bytes mseide-msegui/icons/forms/findresults.svg | 462 + mseide-msegui/icons/forms/memory.png | Bin 0 -> 1084 bytes mseide-msegui/icons/forms/memory.svg | 630 + mseide-msegui/icons/forms/messages.png | Bin 0 -> 535 bytes mseide-msegui/icons/forms/messages.svg | 407 + mseide-msegui/icons/forms/msei18n_24x24.png | Bin 0 -> 1968 bytes mseide-msegui/icons/forms/objectinspector.png | Bin 0 -> 925 bytes mseide-msegui/icons/forms/objectinspector.svg | 418 + mseide-msegui/icons/forms/palette.png | Bin 0 -> 1065 bytes mseide-msegui/icons/forms/palette.svg | 542 + mseide-msegui/icons/forms/rect6550.png | Bin 0 -> 222 bytes mseide-msegui/icons/forms/source.png | Bin 0 -> 907 bytes mseide-msegui/icons/forms/source.svg | 466 + mseide-msegui/icons/forms/stack.png | Bin 0 -> 884 bytes mseide-msegui/icons/forms/stack.svg | 461 + mseide-msegui/icons/forms/thread.png | Bin 0 -> 700 bytes mseide-msegui/icons/forms/thread.svg | 519 + mseide-msegui/icons/forms/watches.png | Bin 0 -> 826 bytes mseide-msegui/icons/forms/watches.svg | 426 + mseide-msegui/icons/forms/watchpoints.png | Bin 0 -> 873 bytes mseide-msegui/icons/forms/watchppoints.svg | 447 + mseide-msegui/icons/frames/demo/0.png | Bin 0 -> 147 bytes mseide-msegui/icons/frames/demo/0.xcf | Bin 0 -> 804 bytes mseide-msegui/icons/frames/demo/1.png | Bin 0 -> 121 bytes mseide-msegui/icons/frames/demo/1.xcf | Bin 0 -> 643 bytes mseide-msegui/icons/frames/demo/10.png | Bin 0 -> 147 bytes mseide-msegui/icons/frames/demo/10.xcf | Bin 0 -> 806 bytes mseide-msegui/icons/frames/demo/11.png | Bin 0 -> 127 bytes mseide-msegui/icons/frames/demo/11.xcf | Bin 0 -> 628 bytes mseide-msegui/icons/frames/demo/12.png | Bin 0 -> 147 bytes mseide-msegui/icons/frames/demo/12.xcf | Bin 0 -> 803 bytes mseide-msegui/icons/frames/demo/13.png | Bin 0 -> 120 bytes mseide-msegui/icons/frames/demo/13.xcf | Bin 0 -> 640 bytes mseide-msegui/icons/frames/demo/14.png | Bin 0 -> 145 bytes mseide-msegui/icons/frames/demo/14.xcf | Bin 0 -> 806 bytes mseide-msegui/icons/frames/demo/15.png | Bin 0 -> 127 bytes mseide-msegui/icons/frames/demo/15.xcf | Bin 0 -> 628 bytes mseide-msegui/icons/frames/demo/16.png | Bin 0 -> 145 bytes mseide-msegui/icons/frames/demo/16.xcf | Bin 0 -> 804 bytes mseide-msegui/icons/frames/demo/17.png | Bin 0 -> 121 bytes mseide-msegui/icons/frames/demo/17.xcf | Bin 0 -> 640 bytes mseide-msegui/icons/frames/demo/18.png | Bin 0 -> 147 bytes mseide-msegui/icons/frames/demo/18.xcf | Bin 0 -> 806 bytes mseide-msegui/icons/frames/demo/19.png | Bin 0 -> 127 bytes mseide-msegui/icons/frames/demo/19.xcf | Bin 0 -> 628 bytes mseide-msegui/icons/frames/demo/2.png | Bin 0 -> 147 bytes mseide-msegui/icons/frames/demo/2.xcf | Bin 0 -> 806 bytes mseide-msegui/icons/frames/demo/20.png | Bin 0 -> 147 bytes mseide-msegui/icons/frames/demo/20.xcf | Bin 0 -> 803 bytes mseide-msegui/icons/frames/demo/21.png | Bin 0 -> 120 bytes mseide-msegui/icons/frames/demo/21.xcf | Bin 0 -> 640 bytes mseide-msegui/icons/frames/demo/22.png | Bin 0 -> 147 bytes mseide-msegui/icons/frames/demo/22.xcf | Bin 0 -> 806 bytes mseide-msegui/icons/frames/demo/23.png | Bin 0 -> 127 bytes mseide-msegui/icons/frames/demo/23.xcf | Bin 0 -> 628 bytes mseide-msegui/icons/frames/demo/24.png | Bin 0 -> 145 bytes mseide-msegui/icons/frames/demo/24.xcf | Bin 0 -> 804 bytes mseide-msegui/icons/frames/demo/25.png | Bin 0 -> 121 bytes mseide-msegui/icons/frames/demo/25.xcf | Bin 0 -> 640 bytes mseide-msegui/icons/frames/demo/26.png | Bin 0 -> 147 bytes mseide-msegui/icons/frames/demo/26.xcf | Bin 0 -> 806 bytes mseide-msegui/icons/frames/demo/27.png | Bin 0 -> 127 bytes mseide-msegui/icons/frames/demo/27.xcf | Bin 0 -> 628 bytes mseide-msegui/icons/frames/demo/28.png | Bin 0 -> 147 bytes mseide-msegui/icons/frames/demo/28.xcf | Bin 0 -> 803 bytes mseide-msegui/icons/frames/demo/29.png | Bin 0 -> 120 bytes mseide-msegui/icons/frames/demo/29.xcf | Bin 0 -> 640 bytes mseide-msegui/icons/frames/demo/3.png | Bin 0 -> 127 bytes mseide-msegui/icons/frames/demo/3.xcf | Bin 0 -> 628 bytes mseide-msegui/icons/frames/demo/30.png | Bin 0 -> 147 bytes mseide-msegui/icons/frames/demo/30.xcf | Bin 0 -> 806 bytes mseide-msegui/icons/frames/demo/31.png | Bin 0 -> 127 bytes mseide-msegui/icons/frames/demo/31.xcf | Bin 0 -> 628 bytes mseide-msegui/icons/frames/demo/4.png | Bin 0 -> 147 bytes mseide-msegui/icons/frames/demo/4.xcf | Bin 0 -> 803 bytes mseide-msegui/icons/frames/demo/5.png | Bin 0 -> 121 bytes mseide-msegui/icons/frames/demo/5.xcf | Bin 0 -> 640 bytes mseide-msegui/icons/frames/demo/6.png | Bin 0 -> 147 bytes mseide-msegui/icons/frames/demo/6.xcf | Bin 0 -> 806 bytes mseide-msegui/icons/frames/demo/7.png | Bin 0 -> 126 bytes mseide-msegui/icons/frames/demo/7.xcf | Bin 0 -> 628 bytes mseide-msegui/icons/frames/demo/8.png | Bin 0 -> 147 bytes mseide-msegui/icons/frames/demo/8.xcf | Bin 0 -> 807 bytes mseide-msegui/icons/frames/demo/9.png | Bin 0 -> 121 bytes mseide-msegui/icons/frames/demo/9.xcf | Bin 0 -> 642 bytes mseide-msegui/icons/frames/frames.png | Bin 0 -> 1160 bytes mseide-msegui/icons/frames/frames.svg | 102 + mseide-msegui/icons/frames/frames.xcf | Bin 0 -> 5422 bytes mseide-msegui/icons/frames/frames0.png | Bin 0 -> 240 bytes mseide-msegui/icons/frames/frames1.png | Bin 0 -> 177 bytes mseide-msegui/icons/frames/frames2.png | Bin 0 -> 239 bytes mseide-msegui/icons/frames/frames3.png | Bin 0 -> 176 bytes mseide-msegui/icons/frames/frames4.png | Bin 0 -> 242 bytes mseide-msegui/icons/frames/frames5.png | Bin 0 -> 163 bytes mseide-msegui/icons/frames/frames6.png | Bin 0 -> 251 bytes mseide-msegui/icons/frames/frames7.png | Bin 0 -> 177 bytes mseide-msegui/icons/makicon | 21 + mseide-msegui/icons/menus/assembler.png | Bin 0 -> 616 bytes mseide-msegui/icons/menus/assembler.svg | 429 + mseide-msegui/icons/menus/breakpoints.png | Bin 0 -> 467 bytes mseide-msegui/icons/menus/breakpoints.svg | 426 + mseide-msegui/icons/menus/componentstore.png | Bin 0 -> 429 bytes mseide-msegui/icons/menus/componentstore.svg | 536 + mseide-msegui/icons/menus/console.png | Bin 0 -> 381 bytes mseide-msegui/icons/menus/console.svg | 407 + mseide-msegui/icons/menus/cpu.png | Bin 0 -> 434 bytes mseide-msegui/icons/menus/cpu.svg | 407 + mseide-msegui/icons/menus/debugger.png | Bin 0 -> 486 bytes mseide-msegui/icons/menus/debugger.svg | 338 + mseide-msegui/icons/menus/findresults.png | Bin 0 -> 809 bytes mseide-msegui/icons/menus/findresults.svg | 456 + mseide-msegui/icons/menus/memory.png | Bin 0 -> 717 bytes mseide-msegui/icons/menus/memory.svg | 610 + mseide-msegui/icons/menus/messages.png | Bin 0 -> 405 bytes mseide-msegui/icons/menus/messages.svg | 407 + mseide-msegui/icons/menus/objectinspector.png | Bin 0 -> 542 bytes mseide-msegui/icons/menus/objectinspector.svg | 396 + mseide-msegui/icons/menus/palette.png | Bin 0 -> 733 bytes mseide-msegui/icons/menus/palette.svg | 561 + .../icons/menus/pastedpic_11162008_154602.png | Bin 0 -> 798 bytes mseide-msegui/icons/menus/source.png | Bin 0 -> 623 bytes mseide-msegui/icons/menus/source.svg | 462 + mseide-msegui/icons/menus/stack.png | Bin 0 -> 449 bytes mseide-msegui/icons/menus/stack.svg | 431 + mseide-msegui/icons/menus/symbols.png | Bin 0 -> 889 bytes mseide-msegui/icons/menus/thread.png | Bin 0 -> 569 bytes mseide-msegui/icons/menus/thread.svg | 486 + mseide-msegui/icons/menus/threads.svg | 439 + mseide-msegui/icons/menus/watches.png | Bin 0 -> 438 bytes mseide-msegui/icons/menus/watches.svg | 425 + mseide-msegui/icons/menus/watchpoints.png | Bin 0 -> 572 bytes mseide-msegui/icons/menus/watchppoints.svg | 440 + mseide-msegui/icons/msegui/edelweiss.svg | 245 + mseide-msegui/icons/msegui/edelweiss2_16.png | Bin 0 -> 1029 bytes .../icons/msegui/edelweiss2_16bi.png | Bin 0 -> 976 bytes mseide-msegui/icons/msegui/edelweiss2_17.png | Bin 0 -> 1103 bytes .../icons/msegui/edelweiss2_17bi.png | Bin 0 -> 1051 bytes mseide-msegui/icons/msegui/edelweiss2_18.png | Bin 0 -> 1204 bytes .../icons/msegui/edelweiss2_18bi.png | Bin 0 -> 1136 bytes mseide-msegui/icons/msegui/edelweiss2_24.png | Bin 0 -> 1836 bytes .../icons/msegui/edelweiss2_24bi.png | Bin 0 -> 1734 bytes mseide-msegui/icons/msegui/edelweiss2_32.png | Bin 0 -> 2821 bytes .../icons/msegui/edelweiss2_32bi.png | Bin 0 -> 2722 bytes mseide-msegui/icons/msegui/edelweiss2_48.png | Bin 0 -> 5112 bytes .../icons/msegui/edelweiss2_48bi.png | Bin 0 -> 5097 bytes mseide-msegui/icons/msegui/edelweiss2_64.png | Bin 0 -> 7603 bytes .../icons/msegui/edelweiss2_64bi.ico | Bin 0 -> 12862 bytes .../icons/msegui/edelweiss2_64bi.png | Bin 0 -> 7779 bytes mseide-msegui/icons/msegui/edelweiss_bi.svg | 342 + .../icons/msegui/edelweiss_biround.svg | 344 + .../icons/msegui/edelweissgreen_24bi.png | Bin 0 -> 1754 bytes .../icons/msegui/edelweissgreen_32bi.png | Bin 0 -> 2760 bytes .../icons/msegui/edelweissgreen_bi.svg | 342 + mseide-msegui/icons/resources/dir.png | Bin 0 -> 205 bytes mseide-msegui/icons/resources/dirgreen.png | Bin 0 -> 201 bytes .../icons/resources/dirgreenwarn.png | Bin 0 -> 216 bytes mseide-msegui/icons/resources/diropen.png | Bin 0 -> 226 bytes .../icons/resources/diropengreen.png | Bin 0 -> 230 bytes .../icons/resources/diropengreenwarn.png | Bin 0 -> 247 bytes mseide-msegui/icons/resources/diropenred.png | Bin 0 -> 213 bytes .../icons/resources/diropenredgreen.png | Bin 0 -> 245 bytes .../icons/resources/diropenredgreenwarn.png | Bin 0 -> 257 bytes .../icons/resources/diropenredwarn.png | Bin 0 -> 228 bytes .../icons/resources/diropenwhite.png | Bin 0 -> 220 bytes mseide-msegui/icons/resources/dirplus.png | Bin 0 -> 224 bytes .../icons/resources/dirplusgreen.png | Bin 0 -> 223 bytes mseide-msegui/icons/resources/dirplusred.png | Bin 0 -> 209 bytes .../icons/resources/dirpluswhite.png | Bin 0 -> 208 bytes mseide-msegui/icons/resources/dirred.png | Bin 0 -> 202 bytes mseide-msegui/icons/resources/dirredgreen.png | Bin 0 -> 206 bytes .../icons/resources/dirredgreenwarn.png | Bin 0 -> 229 bytes mseide-msegui/icons/resources/dirredwarn.png | Bin 0 -> 221 bytes mseide-msegui/icons/resources/dirwhite.png | Bin 0 -> 191 bytes mseide-msegui/icons/resources/file.png | Bin 0 -> 199 bytes .../icons/resources/filedialogres.png | Bin 0 -> 488 bytes mseide-msegui/icons/resources/filegreen.png | Bin 0 -> 196 bytes .../icons/resources/filegreenminusred.png | Bin 0 -> 237 bytes .../icons/resources/filegreenred.png | Bin 0 -> 202 bytes .../icons/resources/filegreenredwarn.png | Bin 0 -> 225 bytes .../icons/resources/filegreenwarn.png | Bin 0 -> 221 bytes .../icons/resources/fileminusred.png | Bin 0 -> 207 bytes .../icons/resources/fileplusgreen.png | Bin 0 -> 215 bytes mseide-msegui/icons/resources/filered.png | Bin 0 -> 205 bytes .../icons/resources/fileredplusgreen.png | Bin 0 -> 223 bytes mseide-msegui/icons/resources/fileredwarn.png | Bin 0 -> 230 bytes mseide-msegui/icons/resources/filterreset.png | Bin 0 -> 132 bytes mseide-msegui/icons/resources/form.png | Bin 0 -> 216 bytes .../icons/resources/imagebackground.png | Bin 0 -> 177 bytes .../icons/resources/mergepending.png | Bin 0 -> 190 bytes .../icons/resources/mergependingred.png | Bin 0 -> 192 bytes mseide-msegui/icons/resources/opengl.png | Bin 0 -> 14482 bytes .../icons/resources/pushconflict.png | Bin 0 -> 214 bytes .../resources/pushmergeconflictpending.png | Bin 0 -> 214 bytes .../icons/resources/pushmergepending.png | Bin 0 -> 215 bytes mseide-msegui/icons/resources/pushpending.png | Bin 0 -> 185 bytes .../stg_checkboxparentnotchecked.png | Bin 0 -> 166 bytes .../stg_checkboxparentnotchecked.xcf | Bin 0 -> 772 bytes mseide-msegui/icons/resources/unitform.png | Bin 0 -> 265 bytes mseide-msegui/lib/common/COPYING.LGPL | 504 + mseide-msegui/lib/common/COPYING.MSE | 23 + .../common/assistive/mseassistivehandler.pas | 2596 ++ mseide-msegui/lib/common/audio/mseaudio.pas | 357 + .../lib/common/audio/mseespeakng.pas | 465 + mseide-msegui/lib/common/audio/msemidi.pas | 833 + mseide-msegui/lib/common/audio/msepulse.pas | 58 + .../lib/common/audio/msepulseglob.pas | 333 + .../lib/common/audio/msepulsesimple.pas | 201 + mseide-msegui/lib/common/audio/msespeak.pas | 1244 + .../lib/common/container/msedatalist.pas | 7128 +++++ .../lib/common/container/msehash.pas | 3280 +++ .../lib/common/container/msehashstore.pas | 423 + .../lib/common/container/mselinklist.pas | 437 + .../lib/common/container/mselist.pas | 1861 ++ .../lib/common/container/msestringident.pas | 573 + .../lib/common/container/msesumlist.pas | 606 + mseide-msegui/lib/common/crypto/msecrc.pas | 111 + .../lib/common/crypto/msecryptio.pas | 147 + .../lib/common/crypto/msecryptohandler.pas | 930 + .../lib/common/crypto/msecryptstream.pas | 21 + .../lib/common/crypto/mseopenssl.pas | 529 + .../lib/common/crypto/mseopensslaes.pas | 38 + .../lib/common/crypto/mseopensslasn.pas | 75 + .../lib/common/crypto/mseopensslbignum.pas | 379 + .../lib/common/crypto/mseopensslbio.pas | 248 + .../lib/common/crypto/mseopenssldes.pas | 49 + .../lib/common/crypto/mseopenssldsa.pas | 71 + .../lib/common/crypto/mseopensslevp.pas | 564 + .../lib/common/crypto/mseopensslpem.pas | 85 + .../lib/common/crypto/mseopensslpkcs.pas | 173 + .../lib/common/crypto/mseopensslrand.pas | 67 + .../lib/common/crypto/mseopensslrsa.pas | 120 + .../lib/common/crypto/mseopensslsmime.pas | 38 + .../lib/common/crypto/mseopensslx509.pas | 386 + mseide-msegui/lib/common/crypto/msessl.pas | 1076 + mseide-msegui/lib/common/crypto/msezlib.pas | 743 + .../lib/common/crypto/msezstream.pas | 309 + mseide-msegui/lib/common/db/firebird.pas | 12993 +++++++++ mseide-msegui/lib/common/db/ibase60.inc | 3241 +++ mseide-msegui/lib/common/db/ibase60.pas | 9 + mseide-msegui/lib/common/db/ibase60dyn.pas | 18 + mseide-msegui/lib/common/db/memds.pp | 987 + mseide-msegui/lib/common/db/mibconnection.pas | 1827 ++ mseide-msegui/lib/common/db/mmysql40conn.pas | 26 + mseide-msegui/lib/common/db/mmysql41conn.pas | 26 + mseide-msegui/lib/common/db/mmysql4conn.pas | 28 + mseide-msegui/lib/common/db/mmysql50conn.pas | 27 + mseide-msegui/lib/common/db/mmysqlconn.inc | 1136 + mseide-msegui/lib/common/db/mmysqlconn.pas | 1965 ++ mseide-msegui/lib/common/db/modbcconn.pas | 1818 ++ mseide-msegui/lib/common/db/mpqconnection.pas | 1708 ++ mseide-msegui/lib/common/db/msebufdataset.pas | 10892 ++++++++ mseide-msegui/lib/common/db/msedatabase.pas | 1170 + mseide-msegui/lib/common/db/msedb.pas | 9363 +++++++ .../common/db/msedbcalendardatetimeedit.pas | 202 + mseide-msegui/lib/common/db/msedbdialog.pas | 812 + .../lib/common/db/msedbdispwidgets.pas | 997 + mseide-msegui/lib/common/db/msedbedit.pas | 12722 +++++++++ mseide-msegui/lib/common/db/msedbevents.pas | 276 + mseide-msegui/lib/common/db/msedbf.pas | 375 + mseide-msegui/lib/common/db/msedbgraphics.pas | 579 + mseide-msegui/lib/common/db/msedblookup.pas | 2759 ++ .../lib/common/db/msefb3connection.pas | 1981 ++ mseide-msegui/lib/common/db/msefb3service.pas | 1759 ++ .../lib/common/db/msefbinterface.pas | 397 + mseide-msegui/lib/common/db/msefbservice.pas | 1695 ++ mseide-msegui/lib/common/db/msefbutils.pas | 165 + mseide-msegui/lib/common/db/msefirebird.pas | 469 + .../lib/common/db/mseibconnection.pas | 110 + .../lib/common/db/mselocaldataset.pas | 426 + .../lib/common/db/mselookupbuffer.pas | 1963 ++ mseide-msegui/lib/common/db/msememds.pas | 354 + .../lib/common/db/msemysql40conn.pas | 65 + .../lib/common/db/msemysql41conn.pas | 86 + .../lib/common/db/msemysql50conn.pas | 85 + mseide-msegui/lib/common/db/msemysqlconn.pas | 84 + mseide-msegui/lib/common/db/mseodbcconn.pas | 78 + .../lib/common/db/msepqconnection.pas | 189 + mseide-msegui/lib/common/db/msesdfdata.pas | 725 + mseide-msegui/lib/common/db/msesqldb.pas | 1992 ++ .../lib/common/db/msesqlite3conn.pas | 1160 + mseide-msegui/lib/common/db/msesqlquery.pas | 2409 ++ mseide-msegui/lib/common/db/msesqlresult.pas | 2458 ++ mseide-msegui/lib/common/db/msezeos.pas | 1385 + mseide-msegui/lib/common/db/msqldb.pas | 2880 ++ mseide-msegui/lib/common/db/mysqldyn.pas | 2297 ++ mseide-msegui/lib/common/db/odbcsqldyn.pas | 1771 ++ mseide-msegui/lib/common/db/postgres3dyn.pas | 594 + mseide-msegui/lib/common/db/sqlite3dyn.pas | 948 + .../designutils/msecomponenteditors.pas | 172 + .../designutils/msecornermaskeditor.mfm | 130 + .../designutils/msecornermaskeditor.pas | 80 + .../designutils/msecornermaskeditor_mfm.pas | 153 + .../common/designutils/msedbfieldeditor.mfm | 333 + .../common/designutils/msedbfieldeditor.pas | 457 + .../designutils/msedbfieldeditor_mfm.pas | 435 + .../lib/common/designutils/msedesignintf.pas | 1674 ++ .../designutils/msedoublereallisteditor.mfm | 151 + .../designutils/msedoublereallisteditor.pas | 58 + .../msedoublereallisteditor_mfm.pas | 158 + .../designutils/msedoublestringlisteditor.mfm | 173 + .../designutils/msedoublestringlisteditor.pas | 59 + .../msedoublestringlisteditor_mfm.pas | 219 + .../designutils/msefaceselectorform.mfm | 44 + .../designutils/msefaceselectorform.pas | 109 + .../designutils/msefaceselectorform_mfm.pas | 70 + .../lib/common/designutils/msefadeedit.mfm | 653 + .../lib/common/designutils/msefadeedit.pas | 1031 + .../common/designutils/msefadeedit_mfm.pas | 657 + .../common/designutils/msefadepropedit.pas | 256 + .../common/designutils/msefircoeffeditor.mfm | 100 + .../common/designutils/msefircoeffeditor.pas | 22 + .../designutils/msefircoeffeditor_mfm.pas | 102 + .../common/designutils/mseformdatatools.pas | 333 + .../lib/common/designutils/msegdbutils.pas | 5038 ++++ .../common/designutils/mseificlienteditor.mfm | 120 + .../common/designutils/mseificlienteditor.pas | 198 + .../designutils/mseificlienteditor_mfm.pas | 128 + .../designutils/mseificomponenteditors.pas | 47 + .../common/designutils/mseififieldeditor.mfm | 336 + .../common/designutils/mseififieldeditor.pas | 572 + .../designutils/mseififieldeditor_mfm.pas | 447 + .../common/designutils/mseiircoeffeditor.mfm | 189 + .../common/designutils/mseiircoeffeditor.pas | 44 + .../designutils/mseiircoeffeditor_mfm.pas | 202 + .../common/designutils/mseimagelisteditor.mfm | 286 + .../common/designutils/mseimagelisteditor.pas | 388 + .../designutils/mseimagelisteditor_mfm.pas | 296 + .../designutils/mseimageselectorform.mfm | 35 + .../designutils/mseimageselectorform.pas | 90 + .../designutils/mseimageselectorform_mfm.pas | 52 + .../designutils/mseindexlookupeditor.mfm | 161 + .../designutils/mseindexlookupeditor.pas | 131 + .../designutils/mseindexlookupeditor_mfm.pas | 193 + .../designutils/mseintegerlisteditor.mfm | 106 + .../designutils/mseintegerlisteditor.pas | 61 + .../designutils/mseintegerlisteditor_mfm.pas | 105 + .../lib/common/designutils/mseparser.pas | 2734 ++ .../common/designutils/msepropertyeditors.pas | 6158 +++++ .../designutils/msepropertyeditorsmodule.mfm | 28 + .../designutils/msepropertyeditorsmodule.pas | 32 + .../msepropertyeditorsmodule_mfm.pas | 38 + .../common/designutils/msereallisteditor.mfm | 111 + .../common/designutils/msereallisteditor.pas | 61 + .../designutils/msereallisteditor_mfm.pas | 109 + .../common/designutils/mseresourcetools.pas | 163 + .../designutils/mserichstringeditor.mfm | 113 + .../designutils/mserichstringeditor.pas | 81 + .../designutils/mserichstringeditor_mfm.pas | 136 + .../lib/common/designutils/msesettings.mfm | 571 + .../lib/common/designutils/msesettings.pas | 312 + .../common/designutils/msesettings_mfm.pas | 528 + .../lib/common/designutils/mseskindesign.pas | 87 + .../designutils/msestringintlisteditor.mfm | 133 + .../designutils/msestringintlisteditor.pas | 59 + .../msestringintlisteditor_mfm.pas | 121 + .../designutils/msestringlisteditor.mfm | 112 + .../designutils/msestringlisteditor.pas | 61 + .../designutils/msestringlisteditor_mfm.pas | 144 + .../lib/common/designutils/msesyntaxedit.pas | 1440 + .../common/designutils/msesyntaxpainter.pas | 1942 ++ .../designutils/msesysenvmanagereditor.mfm | 538 + .../designutils/msesysenvmanagereditor.pas | 146 + .../msesysenvmanagereditor_mfm.pas | 659 + .../designutils/msetaborderoverrideeditor.mfm | 194 + .../designutils/msetaborderoverrideeditor.pas | 171 + .../msetaborderoverrideeditor_mfm.pas | 229 + .../lib/common/designutils/msetexteditor.mfm | 213 + .../lib/common/designutils/msetexteditor.pas | 153 + .../common/designutils/msetexteditor_mfm.pas | 195 + .../lib/common/designutils/panelform.mfm | 37 + .../lib/common/designutils/panelform.pas | 292 + .../lib/common/designutils/panelform_mfm.pas | 87 + .../lib/common/dialogs/msecolordialog.mfm | 561 + .../lib/common/dialogs/msecolordialog.pas | 952 + .../lib/common/dialogs/msecolordialog_mfm.pas | 542 + .../lib/common/dialogs/msedialog.pas | 673 + .../lib/common/dialogs/msedirtree.mfm | 70 + .../lib/common/dialogs/msedirtree.pas | 514 + .../lib/common/dialogs/msedirtree_mfm.pas | 98 + .../lib/common/dialogs/msedirtreesub.mfm | 21 + .../lib/common/dialogs/msedirtreesub.pas | 35 + .../lib/common/dialogs/msedirtreesub_mfm.pas | 29 + .../lib/common/dialogs/msefiledialog.mfm | 346 + .../lib/common/dialogs/msefiledialog.pas | 2811 ++ .../lib/common/dialogs/msefiledialog_mfm.pas | 440 + .../lib/common/dialogs/msefiledialogres.mfm | 178 + .../lib/common/dialogs/msefiledialogres.pas | 61 + .../common/dialogs/msefiledialogres_mfm.pas | 287 + .../common/dialogs/msefontformatdialog.mfm | 232 + .../common/dialogs/msefontformatdialog.pas | 90 + .../dialogs/msefontformatdialog_mfm.pas | 212 + .../lib/common/dialogs/mseintegerenter.mfm | 58 + .../lib/common/dialogs/mseintegerenter.pas | 62 + .../common/dialogs/mseintegerenter_mfm.pas | 74 + .../lib/common/dialogs/msememodialog.mfm | 84 + .../lib/common/dialogs/msememodialog.pas | 232 + .../lib/common/dialogs/msememodialog_mfm.pas | 113 + .../lib/common/dialogs/msepopupcalendar.mfm | 213 + .../lib/common/dialogs/msepopupcalendar.pas | 417 + .../common/dialogs/msepopupcalendar_mfm.pas | 274 + .../lib/common/dialogs/mserealenter.mfm | 64 + .../lib/common/dialogs/mserealenter.pas | 62 + .../lib/common/dialogs/mserealenter_mfm.pas | 79 + .../lib/common/dialogs/mseshortcutdialog.mfm | 314 + .../lib/common/dialogs/mseshortcutdialog.pas | 697 + .../common/dialogs/mseshortcutdialog_mfm.pas | 356 + .../lib/common/dialogs/msestringenter.mfm | 94 + .../lib/common/dialogs/msestringenter.pas | 110 + .../lib/common/dialogs/msestringenter_mfm.pas | 143 + .../editwidgets/msecalendardatetimeedit.pas | 182 + .../lib/common/editwidgets/msedataedits.pas | 6755 +++++ .../lib/common/editwidgets/msedataimage.pas | 860 + .../lib/common/editwidgets/msedatanodes.pas | 4019 +++ .../common/editwidgets/msedropdownlist.pas | 2998 +++ .../lib/common/editwidgets/mseedit.pas | 2437 ++ .../lib/common/editwidgets/msefoldedit.pas | 878 + .../lib/common/editwidgets/msegraphedits.pas | 5180 ++++ .../lib/common/editwidgets/mselistbrowser.pas | 7180 +++++ .../lib/common/editwidgets/mserealsumedit.pas | 219 + .../common/editwidgets/msestringlistedit.pas | 433 + .../lib/common/editwidgets/mseterminal.pas | 848 + .../lib/common/editwidgets/msetextedit.pas | 2834 ++ .../lib/common/editwidgets/msevaluenodes.pas | 777 + .../common/editwidgets/msevaluenodesglob.pas | 26 + .../lib/common/editwidgets/msewidgetgrid.pas | 4084 +++ .../lib/common/fpccompatibility/dbf_avl.pas | 435 + .../common/fpccompatibility/dbf_collate.pas | 2347 ++ .../common/fpccompatibility/dbf_common.inc | 262 + .../common/fpccompatibility/dbf_common.pas | 455 + .../common/fpccompatibility/dbf_cursor.pas | 64 + .../common/fpccompatibility/dbf_dbffile.pas | 2848 ++ .../common/fpccompatibility/dbf_fields.pas | 597 + .../common/fpccompatibility/dbf_idxcur.pas | 217 + .../common/fpccompatibility/dbf_idxfile.pas | 4186 +++ .../lib/common/fpccompatibility/dbf_lang.pas | 655 + .../lib/common/fpccompatibility/dbf_memo.pas | 556 + .../common/fpccompatibility/dbf_parser.pas | 604 + .../common/fpccompatibility/dbf_pgcfile.pas | 232 + .../common/fpccompatibility/dbf_pgfile.pas | 927 + .../lib/common/fpccompatibility/dbf_reg.pas | 366 + .../lib/common/fpccompatibility/dbf_str.inc | 24 + .../lib/common/fpccompatibility/dbf_str.pas | 36 + .../common/fpccompatibility/dbf_str_es.pas | 36 + .../common/fpccompatibility/dbf_str_fr.pas | 54 + .../common/fpccompatibility/dbf_str_ita.pas | 29 + .../common/fpccompatibility/dbf_str_nl.pas | 35 + .../common/fpccompatibility/dbf_str_pl.pas | 36 + .../common/fpccompatibility/dbf_str_pt.pas | 37 + .../common/fpccompatibility/dbf_str_ru.pas | 40 + .../common/fpccompatibility/dbf_struct.inc | 145 + .../lib/common/fpccompatibility/dbf_wtil.pas | 670 + .../common/fpccompatibility/formatfunc.pas | 470 + .../lib/common/fpccompatibility/fpcolcnv.inc | 326 + .../lib/common/fpccompatibility/fpcolors.inc | 49 + .../common/fpccompatibility/fpcompactimg.inc | 602 + .../lib/common/fpccompatibility/fphandler.inc | 275 + .../lib/common/fpccompatibility/fpimage.inc | 558 + .../lib/common/fpccompatibility/fpimage.pas | 701 + .../lib/common/fpccompatibility/fppalette.inc | 265 + .../lib/common/fpccompatibility/fpreadbmp.pas | 520 + .../lib/common/fpccompatibility/fpreadgif.pas | 544 + .../common/fpccompatibility/fpreadjpeg.pas | 482 + .../lib/common/fpccompatibility/fpreadpcx.pas | 310 + .../lib/common/fpccompatibility/fpreadpng.pas | 870 + .../lib/common/fpccompatibility/fpreadpnm.pp | 350 + .../lib/common/fpccompatibility/fpreadpsd.pas | 612 + .../lib/common/fpccompatibility/fpreadtga.pp | 345 + .../common/fpccompatibility/fpreadtiff.pas | 2400 ++ .../lib/common/fpccompatibility/fpreadxpm.pp | 328 + .../lib/common/fpccompatibility/fpreadxwd.pas | 297 + .../lib/common/fpccompatibility/fptiffcmn.pas | 420 + .../common/fpccompatibility/fpwritebmp.pas | 732 + .../lib/common/fpccompatibility/fpwritebmp.pp | 734 + .../common/fpccompatibility/fpwritejpeg.pas | 226 + .../common/fpccompatibility/fpwritepcx.pas | 156 + .../lib/common/fpccompatibility/fpwritepng.pp | 757 + .../lib/common/fpccompatibility/fpwritepnm.pp | 283 + .../lib/common/fpccompatibility/fpwritetga.pp | 101 + .../common/fpccompatibility/fpwritetiff.pas | 903 + .../lib/common/fpccompatibility/fpwritexpm.pp | 173 + .../common/fpccompatibility/getstrfromint.inc | 38 + .../common/fpccompatibility/jcapimin_del.pas | 402 + .../common/fpccompatibility/jcapistd_del.pas | 224 + .../common/fpccompatibility/jccoefct_del.pas | 524 + .../common/fpccompatibility/jccolor_del.pas | 531 + .../common/fpccompatibility/jcdctmgr_del.pas | 516 + .../common/fpccompatibility/jchuff_del.pas | 1118 + .../common/fpccompatibility/jcinit_del.pas | 97 + .../common/fpccompatibility/jcmainct_del.pas | 345 + .../common/fpccompatibility/jcmarker_del.pas | 726 + .../common/fpccompatibility/jcmaster_del.pas | 704 + .../common/fpccompatibility/jcomapi_del.pas | 131 + .../common/fpccompatibility/jconfig_del.inc | 118 + .../common/fpccompatibility/jconsts_del.pas | 11 + .../common/fpccompatibility/jcparam_del.pas | 700 + .../common/fpccompatibility/jcphuff_del.pas | 962 + .../common/fpccompatibility/jcprepct_del.pas | 408 + .../common/fpccompatibility/jcsample_del.pas | 632 + .../common/fpccompatibility/jctrans_del.pas | 459 + .../common/fpccompatibility/jdapimin_del.pas | 506 + .../common/fpccompatibility/jdapistd_del.pas | 377 + .../common/fpccompatibility/jdatadst_del.pas | 172 + .../common/fpccompatibility/jdatasrc_del.pas | 225 + .../common/fpccompatibility/jdcoefct_del.pas | 898 + .../common/fpccompatibility/jdcolor_del.pas | 502 + .../lib/common/fpccompatibility/jdct_del.pas | 110 + .../common/fpccompatibility/jddctmgr_del.pas | 330 + .../common/fpccompatibility/jdeferr_del.pas | 498 + .../common/fpccompatibility/jdhuff_del.pas | 1205 + .../common/fpccompatibility/jdinput_del.pas | 417 + .../common/fpccompatibility/jdmainct_del.pas | 611 + .../common/fpccompatibility/jdmarker_del.pas | 2658 ++ .../common/fpccompatibility/jdmaster_del.pas | 680 + .../common/fpccompatibility/jdmerge_del.pas | 515 + .../common/fpccompatibility/jdphuff_del.pas | 1060 + .../common/fpccompatibility/jdpostct_del.pas | 343 + .../common/fpccompatibility/jdsample_del.pas | 593 + .../common/fpccompatibility/jdtrans_del.pas | 192 + .../common/fpccompatibility/jerror_del.pas | 463 + .../common/fpccompatibility/jfdctflt_del.pas | 178 + .../common/fpccompatibility/jfdctfst_del.pas | 239 + .../common/fpccompatibility/jfdctint_del.pas | 299 + .../common/fpccompatibility/jidct2d_del.pas | 1048 + .../common/fpccompatibility/jidctasm_del.pas | 793 + .../common/fpccompatibility/jidctflt_del.pas | 287 + .../common/fpccompatibility/jidctfst_del.pas | 411 + .../common/fpccompatibility/jidctint_del.pas | 441 + .../common/fpccompatibility/jidctred_del.pas | 526 + .../common/fpccompatibility/jinclude_del.pas | 127 + .../common/fpccompatibility/jmemdos_del.pas | 780 + .../common/fpccompatibility/jmemdosa_del.pas | 365 + .../common/fpccompatibility/jmemmgr_del.pas | 1285 + .../common/fpccompatibility/jmemnobs_del.pas | 265 + .../common/fpccompatibility/jmemsys_del.pas | 177 + .../common/fpccompatibility/jmorecfg_del.pas | 250 + .../common/fpccompatibility/jpeglib_del.pas | 1301 + .../common/fpccompatibility/jquant1_del.pas | 1011 + .../common/fpccompatibility/jquant2_del.pas | 1553 ++ .../common/fpccompatibility/jutils_del.pas | 233 + .../lib/common/fpccompatibility/mclasses.pas | 9349 +++++++ .../lib/common/fpccompatibility/mdb.pas | 11557 ++++++++ .../lib/common/fpccompatibility/mdbf.pas | 3065 +++ .../common/fpccompatibility/mdbf_prscore.pas | 2347 ++ .../common/fpccompatibility/mdbf_prsdef.pas | 1053 + .../common/fpccompatibility/mdbf_prssupp.pas | 269 + .../lib/common/fpccompatibility/msdfdata.pas | 1149 + .../lib/common/fpccompatibility/pngcomn.pp | 88 + .../lib/common/fpccompatibility/zstream.pas | 428 + .../lib/common/graphics/msebitmap.pas | 3863 +++ .../lib/common/graphics/msedrawtext.pas | 1859 ++ .../lib/common/graphics/mseellipsetria.pas | 522 + .../lib/common/graphics/msefcfontselect.pas | 309 + mseide-msegui/lib/common/graphics/msefont.pas | 814 + .../lib/common/graphics/msefontcache.pas | 210 + .../lib/common/graphics/msefontconfig.pas | 329 + .../lib/common/graphics/msefreetype.pas | 475 + .../lib/common/graphics/mseftfontcache.pas | 438 + .../lib/common/graphics/mseftglyphs.pas | 287 + .../lib/common/graphics/msegdi32gdi.pas | 3375 +++ .../lib/common/graphics/msegdiplus.pas | 495 + .../lib/common/graphics/msegenericgdi.pas | 1285 + .../lib/common/graphics/msegraphics.pas | 7255 +++++ .../lib/common/graphics/msegraphutils.pas | 2113 ++ .../lib/common/graphics/mselinetria.pas | 943 + .../lib/common/graphics/msepolytria.pas | 1793 ++ .../lib/common/graphics/msetriaglob.pas | 51 + .../lib/common/graphics/msex11gdi.pas | 3335 +++ mseide-msegui/lib/common/i18n/msei18nglob.pas | 26 + .../lib/common/i18n/msei18nutils.pas | 359 + mseide-msegui/lib/common/i18n/mselanglink.pas | 59 + .../lib/common/i18n/msestringcontainer.pas | 184 + mseide-msegui/lib/common/i18n/mseucs2toru.pas | 168 + mseide-msegui/lib/common/ifi/mseifi.pas | 2089 ++ mseide-msegui/lib/common/ifi/mseificomp.pas | 5392 ++++ .../lib/common/ifi/mseificompglob.pas | 81 + mseide-msegui/lib/common/ifi/mseifidbcomp.pas | 265 + mseide-msegui/lib/common/ifi/mseifidbgui.pas | 228 + .../lib/common/ifi/mseifidialogcomp.pas | 153 + mseide-msegui/lib/common/ifi/mseifids.pas | 3100 +++ .../lib/common/ifi/mseifiendpoint.pas | 418 + mseide-msegui/lib/common/ifi/mseifiglob.pas | 62 + mseide-msegui/lib/common/ifi/mseifigui.pas | 856 + mseide-msegui/lib/common/ifi/mseifilink.pas | 3936 +++ mseide-msegui/lib/common/ifi/msejson.pas | 1177 + mseide-msegui/lib/common/ifi/msesockets.pas | 815 + .../lib/common/image/mseformatbmpicoread.pas | 505 + .../lib/common/image/mseformatjpgread.pas | 70 + .../lib/common/image/mseformatjpgwrite.pas | 51 + .../lib/common/image/mseformatpngread.pas | 70 + .../lib/common/image/mseformatpngwrite.pas | 87 + .../lib/common/image/mseformatpnmread.pas | 70 + .../lib/common/image/mseformattgaread.pas | 71 + .../lib/common/image/mseformattiffread.pas | 70 + .../lib/common/image/mseformattiffwrite.pas | 52 + .../lib/common/image/mseformatxpmread.pas | 59 + .../lib/common/image/msegraphicsmagick.pas | 1124 + .../lib/common/image/msegraphicstream.pas | 933 + .../lib/common/image/msemagickstream.pas | 1148 + .../lib/common/kernel/kernel_bmp.pas | 33 + .../lib/common/kernel/linux/cwstring.pas | 641 + mseide-msegui/lib/common/kernel/linux/ice.pas | 148 + .../lib/common/kernel/linux/mseguiintf.pas | 7148 +++++ .../lib/common/kernel/linux/msenoguiintf.pas | 126 + .../common/kernel/linux/mseprocmonitor.pas | 239 + .../lib/common/kernel/linux/msesetlocale.pas | 258 + .../lib/common/kernel/linux/msesocketintf.pas | 501 + .../lib/common/kernel/linux/msesysintf.pas | 1450 + .../lib/common/kernel/linux/msesysintf1.pas | 432 + .../lib/common/kernel/linux/mseuniintf.pas | 131 + .../lib/common/kernel/linux/mxft.pas | 454 + .../lib/common/kernel/linux/mxrandr.pas | 216 + .../lib/common/kernel/linux/mxrender.pas | 490 + mseide-msegui/lib/common/kernel/linux/sm.pas | 197 + mseide-msegui/lib/common/kernel/mseact.pas | 1472 + .../lib/common/kernel/mseactions.pas | 2250 ++ .../lib/common/kernel/mseapplication.pas | 2147 ++ .../lib/common/kernel/msearrayprops.pas | 2266 ++ .../lib/common/kernel/msearrayutils.pas | 3426 +++ .../lib/common/kernel/mseassistiveclient.pas | 80 + .../lib/common/kernel/mseassistiveserver.pas | 104 + .../lib/common/kernel/msebintree.pas | 870 + mseide-msegui/lib/common/kernel/msebits.pas | 815 + .../lib/common/kernel/msebucketlist.pas | 884 + .../lib/common/kernel/mseclasses.pas | 6100 +++++ mseide-msegui/lib/common/kernel/mseconsts.pas | 492 + .../lib/common/kernel/mseconsts_de.pas | 236 + .../lib/common/kernel/mseconsts_es.pas | 238 + .../lib/common/kernel/mseconsts_fr.pas | 277 + .../lib/common/kernel/mseconsts_id.pas | 235 + .../lib/common/kernel/mseconsts_ru.pas | 280 + .../lib/common/kernel/mseconsts_uzcyr.pas | 243 + .../lib/common/kernel/mseconsts_zh.pas | 242 + mseide-msegui/lib/common/kernel/msectypes.pas | 117 + .../lib/common/kernel/msedatamodules.pas | 511 + mseide-msegui/lib/common/kernel/msedate.pas | 84 + mseide-msegui/lib/common/kernel/msedrag.pas | 578 + .../lib/common/kernel/msedynload.pas | 492 + mseide-msegui/lib/common/kernel/mseerr.pas | 61 + mseide-msegui/lib/common/kernel/mseevent.pas | 440 + .../lib/common/kernel/msefileutils.pas | 2254 ++ .../lib/common/kernel/msefloattostr.pas | 621 + .../lib/common/kernel/mseformatstr.pas | 5891 ++++ mseide-msegui/lib/common/kernel/mseglob.pas | 185 + mseide-msegui/lib/common/kernel/msegui.pas | 22378 ++++++++++++++++ .../lib/common/kernel/mseguiglob.pas | 431 + .../lib/common/kernel/mseguiinifini.pas | 19 + .../lib/common/kernel/mseguiintf.inc | 228 + .../lib/common/kernel/mseguithreadcomp.pas | 37 + .../lib/common/kernel/mseinterfaces.pas | 133 + .../lib/common/kernel/msekeyboard.pas | 327 + mseide-msegui/lib/common/kernel/mselibc.pas | 3282 +++ mseide-msegui/lib/common/kernel/msemacros.pas | 1096 + mseide-msegui/lib/common/kernel/msemenus.pas | 2436 ++ mseide-msegui/lib/common/kernel/msenogui.pas | 219 + .../lib/common/kernel/msenoguiintf.inc | 4 + .../lib/common/kernel/mseobjecttext.pas | 1646 ++ .../lib/common/kernel/msepipestream.pas | 953 + .../lib/common/kernel/msepointer.pas | 585 + .../lib/common/kernel/mseprocmonitor.inc | 22 + mseide-msegui/lib/common/kernel/msereal.pas | 178 + .../lib/common/kernel/mserichstring.pas | 1577 ++ .../lib/common/kernel/mserttistat.pas | 1446 + .../lib/common/kernel/msescrollbar.pas | 1921 ++ mseide-msegui/lib/common/kernel/mseshapes.pas | 1700 ++ mseide-msegui/lib/common/kernel/mseskin.pas | 4385 +++ .../lib/common/kernel/msesocketintf.inc | 49 + .../lib/common/kernel/msesonames.pas | 50 + mseide-msegui/lib/common/kernel/msestat.pas | 2054 ++ .../lib/common/kernel/msestatfile.pas | 843 + .../lib/common/kernel/msestockobjects.mfm | 285 + .../lib/common/kernel/msestockobjects.pas | 544 + .../lib/common/kernel/msestockobjects_mfm.pas | 448 + mseide-msegui/lib/common/kernel/msestream.pas | 3172 +++ .../lib/common/kernel/msestreaming.pas | 370 + .../lib/common/kernel/msestrings.pas | 6254 +++++ mseide-msegui/lib/common/kernel/msesys.pas | 569 + .../lib/common/kernel/msesysintf.inc | 92 + .../lib/common/kernel/msesysintf1.inc | 49 + .../lib/common/kernel/msesystypes.pas | 47 + .../lib/common/kernel/msesysutils.pas | 404 + mseide-msegui/lib/common/kernel/msethread.pas | 478 + .../lib/common/kernel/msethreadcomp.pas | 227 + mseide-msegui/lib/common/kernel/msetimer.pas | 1426 + .../lib/common/kernel/msetmpmodules.pas | 100 + mseide-msegui/lib/common/kernel/msetypes.pas | 532 + .../lib/common/kernel/mseunicodeps.pas | 581 + .../lib/common/kernel/mseuniintf.inc | 12 + .../lib/common/kernel/msevariants.pas | 86 + .../lib/common/kernel/windows/mseguiintf.pas | 3531 +++ .../common/kernel/windows/msenoguiintf.pas | 167 + .../common/kernel/windows/mseprocmonitor.pas | 182 + .../common/kernel/windows/msesocketintf.pas | 426 + .../lib/common/kernel/windows/msesysintf.pas | 1999 ++ .../lib/common/kernel/windows/msesysintf1.pas | 577 + .../lib/common/kernel/windows/msesystimer.pas | 198 + .../lib/common/kernel/windows/mseuniintf.pas | 27 + .../lib/common/kernel/windows/msewindnd.pas | 1048 + .../lib/common/kernel/windows/msewinglob.pas | 24 + mseide-msegui/lib/common/math/msefft.pas | 287 + mseide-msegui/lib/common/math/msefftw.pas | 233 + mseide-msegui/lib/common/math/msefilter.pas | 1253 + mseide-msegui/lib/common/math/mselfsr.pas | 45 + mseide-msegui/lib/common/math/msenoise.pas | 115 + mseide-msegui/lib/common/math/msesigaudio.pas | 499 + mseide-msegui/lib/common/math/msesigfft.pas | 483 + .../lib/common/math/msesigfftgui.pas | 156 + mseide-msegui/lib/common/math/msesiggui.pas | 2028 ++ mseide-msegui/lib/common/math/msesigmidi.pas | 1213 + mseide-msegui/lib/common/math/msesignal.pas | 4991 ++++ mseide-msegui/lib/common/math/msesignoise.pas | 316 + mseide-msegui/lib/common/opengl/mseftgl.pas | 420 + mseide-msegui/lib/common/opengl/msegl.pas | 1987 ++ mseide-msegui/lib/common/opengl/mseglext.pas | 8268 ++++++ .../lib/common/opengl/mseglextglob.pas | 653 + mseide-msegui/lib/common/opengl/mseglu.pas | 487 + mseide-msegui/lib/common/opengl/mseglx.pas | 225 + mseide-msegui/lib/common/opengl/mseopengl.pas | 255 + .../common/opengl/mseopenglcanvaswidget.pas | 254 + .../lib/common/opengl/mseopenglgdi.pas | 1977 ++ .../lib/common/opengl/mseopenglgdiinit.pas | 18 + .../lib/common/opengl/mseopenglwidget.pas | 407 + .../common/pascalscript/msepascalscript.pas | 435 + .../lib/common/pascalscript/msepascimport.pas | 11 + .../pascalscript/msepascimportmsegui.pas | 51 + .../lib/common/printer/msegdiprint.pas | 625 + .../common/printer/msepostscriptprinter.pas | 2693 ++ .../lib/common/printer/mseprinter.pas | 2049 ++ .../lib/common/regcomponents/designer_bmp.pas | 119 + .../lib/common/regcomponents/regcrypto.pas | 38 + .../common/regcomponents/regcrypto_bmp.pas | 693 + .../lib/common/regcomponents/regdb.pas | 1757 ++ .../lib/common/regcomponents/regdb_bmp.pas | 9441 +++++++ .../common/regcomponents/regdeprecated.pas | 43 + .../regcomponents/regdeprecated_bmp.pas | 233 + .../common/regcomponents/regdesignutils.pas | 35 + .../regcomponents/regdesignutils_bmp.pas | 150 + .../lib/common/regcomponents/regdialogs.pas | 43 + .../common/regcomponents/regdialogs_bmp.pas | 649 + .../common/regcomponents/regeditwidgets.pas | 403 + .../regcomponents/regeditwidgets_bmp.pas | 1974 ++ .../common/regcomponents/regexperimental.pas | 31 + .../lib/common/regcomponents/regglob.pas | 144 + .../lib/common/regcomponents/regifi.pas | 259 + .../lib/common/regcomponents/regifi_bmp.pas | 2317 ++ .../lib/common/regcomponents/regifirem.pas | 287 + .../common/regcomponents/regifirem_bmp.pas | 691 + .../lib/common/regcomponents/regkernel.pas | 908 + .../common/regcomponents/regkernel_bmp.pas | 3769 +++ .../lib/common/regcomponents/regmath.pas | 199 + .../lib/common/regcomponents/regmath_bmp.pas | 4887 ++++ .../lib/common/regcomponents/regmm.pas | 33 + .../common/regcomponents/regpascalscript.pas | 277 + .../lib/common/regcomponents/regprinter.pas | 32 + .../lib/common/regcomponents/regreport.pas | 182 + .../common/regcomponents/regreport_bmp.pas | 387 + .../common/regcomponents/regserialcomm.pas | 37 + .../regcomponents/regserialcomm_bmp.pas | 721 + .../lib/common/regcomponents/regsysutils.pas | 185 + .../common/regcomponents/regsysutils_bmp.pas | 558 + .../common/regcomponents/regunitgroups.pas | 126 + .../lib/common/regcomponents/regwidgets.pas | 570 + .../common/regcomponents/regwidgets_bmp.pas | 4366 +++ .../lib/common/regcomponents/regzeoslib.pas | 207 + .../common/regcomponents/regzeoslib_bmp.pas | 696 + mseide-msegui/lib/common/report/mselatex.pas | 174 + mseide-msegui/lib/common/report/msereport.pas | 8733 ++++++ mseide-msegui/lib/common/report/mserepps.pas | 322 + .../lib/common/serialcomm/msecommport.pas | 2263 ++ .../lib/common/serialcomm/msecommtimer.pas | 196 + .../lib/common/serialcomm/msecommutils.pas | 211 + .../lib/common/serialcomm/msesercomm.pas | 1328 + mseide-msegui/lib/common/sysutils/msedbus.pas | 750 + .../lib/common/sysutils/msedbusinterface.pas | 3916 +++ .../lib/common/sysutils/mseenvmacros.pas | 67 + .../lib/common/sysutils/mseexecmacros.pas | 73 + .../lib/common/sysutils/msefilechange.pas | 708 + .../lib/common/sysutils/msefilemacros.pas | 158 + .../lib/common/sysutils/mseguiprocess.pas | 114 + .../common/sysutils/mseinputcontroller.pas | 242 + .../lib/common/sysutils/msemacmacros.pas | 73 + mseide-msegui/lib/common/sysutils/msemime.pas | 246 + .../lib/common/sysutils/mseprocess.pas | 1044 + .../common/sysutils/mseprocmonitorcomp.pas | 145 + .../lib/common/sysutils/mseprocutils.pas | 1510 ++ .../lib/common/sysutils/msepython.pas | 302 + .../common/sysutils/msestatusnotifieritem.pas | 608 + .../sysutils/msestatussnotifieritem.pas | 99 + .../lib/common/sysutils/msestrmacros.pas | 98 + .../lib/common/sysutils/msesysdnd.pas | 194 + .../lib/common/sysutils/msesysenv.pas | 1349 + .../lib/common/unicode/mseunicode.pas | 287 + .../lib/common/widgets/msebarcode.pas | 739 + mseide-msegui/lib/common/widgets/msechart.pas | 4637 ++++ .../lib/common/widgets/msechartedit.pas | 2019 ++ mseide-msegui/lib/common/widgets/msedial.pas | 3037 +++ .../lib/common/widgets/msedispwidgets.pas | 1388 + mseide-msegui/lib/common/widgets/msedock.pas | 6027 +++++ .../lib/common/widgets/msedockpanelform.pas | 835 + .../lib/common/widgets/msedragglob.pas | 131 + .../lib/common/widgets/mseeditglob.pas | 273 + mseide-msegui/lib/common/widgets/mseforms.pas | 3308 +++ mseide-msegui/lib/common/widgets/msegrids.pas | 19460 ++++++++++++++ .../lib/common/widgets/msegridsglob.pas | 35 + .../lib/common/widgets/mseguirttistat.pas | 92 + mseide-msegui/lib/common/widgets/mseimage.pas | 188 + .../lib/common/widgets/mseinplaceedit.pas | 3026 +++ .../lib/common/widgets/msemenuwidgets.pas | 2483 ++ .../lib/common/widgets/mseobjectpicker.pas | 733 + .../lib/common/widgets/msepickwidget.pas | 191 + .../lib/common/widgets/msepolygon.pas | 648 + .../lib/common/widgets/msesimplewidgets.pas | 2828 ++ .../lib/common/widgets/msesizingform.pas | 219 + .../lib/common/widgets/msesplitter.pas | 2602 ++ mseide-msegui/lib/common/widgets/msetabs.pas | 5524 ++++ .../lib/common/widgets/msetabsglob.pas | 30 + .../lib/common/widgets/msetoolbar.pas | 2013 ++ .../lib/common/widgets/msetraywidget.pas | 499 + .../lib/common/widgets/msewidgets.pas | 6475 +++++ .../lib/common/widgets/msewindowwidget.pas | 568 + mseide-msegui/msegui.svg | 245 + mseide-msegui/msegui_24.png | Bin 0 -> 1836 bytes mseide-msegui/msegui_32.png | Bin 0 -> 2821 bytes mseide-msegui/msegui_48.png | Bin 0 -> 5112 bytes mseide-msegui/msegui_64.png | Bin 0 -> 7603 bytes mseide-msegui/tools/bmp2pas.pas | 112 + mseide-msegui/tools/bmp2pas.prj | 967 + mseide-msegui/tools/data2pas.pas | 75 + mseide-msegui/tools/data2pas.prj | 43 + mseide-msegui/tools/dist/copybin.sh | 31 + mseide-msegui/tools/dist/makdist.mrp | 315 + mseide-msegui/tools/dist/makeallfp.sh | 8 + mseide-msegui/tools/dist/runmake.sh | 15 + mseide-msegui/tools/doc/README.TXT | 4 + mseide-msegui/tools/form2pas.pas | 91 + mseide-msegui/tools/form2pas.prj | 953 + mseide-msegui/tools/i18n/main.mfm | 614 + mseide-msegui/tools/i18n/main.pas | 1199 + mseide-msegui/tools/i18n/main_mfm.pas | 654 + mseide-msegui/tools/i18n/messagesform.mfm | 51 + mseide-msegui/tools/i18n/messagesform.pas | 31 + mseide-msegui/tools/i18n/messagesform_mfm.pas | 74 + mseide-msegui/tools/i18n/msei18n.ico | Bin 0 -> 16958 bytes mseide-msegui/tools/i18n/msei18n.pas | 35 + mseide-msegui/tools/i18n/msei18n.prj | 1076 + mseide-msegui/tools/i18n/msei18n.rc | 24 + mseide-msegui/tools/i18n/msei18n.res | Bin 0 -> 17680 bytes mseide-msegui/tools/i18n/msei18n.svg | 342 + mseide-msegui/tools/i18n/msei18n_24.png | Bin 0 -> 1878 bytes mseide-msegui/tools/i18n/msei18n_32.png | Bin 0 -> 2946 bytes mseide-msegui/tools/i18n/msei18n_48.png | Bin 0 -> 5486 bytes mseide-msegui/tools/i18n/msei18n_64.png | Bin 0 -> 8537 bytes .../tools/i18n/mseresourceparser.pas | 885 + mseide-msegui/tools/i18n/project.mfm | 452 + mseide-msegui/tools/i18n/project.pas | 158 + mseide-msegui/tools/i18n/project_mfm.pas | 396 + mseide-msegui/tools/msedirclear.cmd | 5 + mseide-msegui/tools/msedirclear.sh | 35 + mseide-msegui/tools/unitdep/main.mfm | 219 + mseide-msegui/tools/unitdep/main.pas | 582 + mseide-msegui/tools/unitdep/main_mfm.pas | 247 + mseide-msegui/tools/unitdep/mseunitdep.pas | 28 + mseide-msegui/tools/unitdep/mseunitdep.prj | 1120 + mseide-msegui/tools/valgrind/fixes_3_0.supp | 21 + .../tools/valgrind/fixes_3_0_64.supp | 20 + mseide-msegui/tools/xft2gs/README.TXT | 4 + 2216 files changed, 907832 insertions(+) create mode 100644 mseide-msegui/.gitignore create mode 100644 mseide-msegui/COPYING.GPL create mode 100644 mseide-msegui/COPYING.LGPL create mode 100644 mseide-msegui/COPYING.MSE create mode 100644 mseide-msegui/DEBUG.TXT create mode 100644 mseide-msegui/README.TXT create mode 100644 mseide-msegui/VERSION.TXT create mode 100644 mseide-msegui/apps/demo/demo.pas create mode 100644 mseide-msegui/apps/demo/demo.prj create mode 100644 mseide-msegui/apps/demo/main.mfm create mode 100644 mseide-msegui/apps/demo/main.pas create mode 100644 mseide-msegui/apps/demo/main_mfm.pas create mode 100644 mseide-msegui/apps/facedemo/facedemo.pas create mode 100644 mseide-msegui/apps/facedemo/facedemo.prj create mode 100644 mseide-msegui/apps/facedemo/main.mfm create mode 100644 mseide-msegui/apps/facedemo/main.pas create mode 100644 mseide-msegui/apps/facedemo/main_mfm.pas create mode 100644 mseide-msegui/apps/i18ndemo/de/dummy.txt create mode 100644 mseide-msegui/apps/i18ndemo/fr/dummy.txt create mode 100644 mseide-msegui/apps/i18ndemo/i18ndemo.pas create mode 100644 mseide-msegui/apps/i18ndemo/i18ndemo.prj create mode 100644 mseide-msegui/apps/i18ndemo/i18ndemo.trd create mode 100644 mseide-msegui/apps/i18ndemo/i18ndemo.trp create mode 100644 mseide-msegui/apps/i18ndemo/main.mfm create mode 100644 mseide-msegui/apps/i18ndemo/main.pas create mode 100644 mseide-msegui/apps/i18ndemo/main_mfm.pas create mode 100644 mseide-msegui/apps/ide/COPYING.GPL create mode 100644 mseide-msegui/apps/ide/COPYING.IDE create mode 100644 mseide-msegui/apps/ide/actionsmodule.mfm create mode 100644 mseide-msegui/apps/ide/actionsmodule.pas create mode 100644 mseide-msegui/apps/ide/actionsmodule_mfm.pas create mode 100644 mseide-msegui/apps/ide/breakpointsform.mfm create mode 100644 mseide-msegui/apps/ide/breakpointsform.pas create mode 100644 mseide-msegui/apps/ide/breakpointsform_mfm.pas create mode 100644 mseide-msegui/apps/ide/cdesignparser.pas create mode 100644 mseide-msegui/apps/ide/commandlineform.mfm create mode 100644 mseide-msegui/apps/ide/commandlineform.pas create mode 100644 mseide-msegui/apps/ide/commandlineform_mfm.pas create mode 100644 mseide-msegui/apps/ide/componentpaletteform.mfm create mode 100644 mseide-msegui/apps/ide/componentpaletteform.pas create mode 100644 mseide-msegui/apps/ide/componentpaletteform_mfm.pas create mode 100644 mseide-msegui/apps/ide/componentstore.mfm create mode 100644 mseide-msegui/apps/ide/componentstore.pas create mode 100644 mseide-msegui/apps/ide/componentstore_mfm.pas create mode 100644 mseide-msegui/apps/ide/compstore/dummy create mode 100644 mseide-msegui/apps/ide/cpuarmform.mfm create mode 100644 mseide-msegui/apps/ide/cpuarmform.pas create mode 100644 mseide-msegui/apps/ide/cpuarmform_mfm.pas create mode 100644 mseide-msegui/apps/ide/cpuarmm3form.mfm create mode 100644 mseide-msegui/apps/ide/cpuarmm3form.pas create mode 100644 mseide-msegui/apps/ide/cpuarmm3form_mfm.pas create mode 100644 mseide-msegui/apps/ide/cpuavr32form.mfm create mode 100644 mseide-msegui/apps/ide/cpuavr32form.pas create mode 100644 mseide-msegui/apps/ide/cpuavr32form_mfm.pas create mode 100644 mseide-msegui/apps/ide/cpucpu32form.mfm create mode 100644 mseide-msegui/apps/ide/cpucpu32form.pas create mode 100644 mseide-msegui/apps/ide/cpucpu32form_mfm.pas create mode 100644 mseide-msegui/apps/ide/cpuform.mfm create mode 100644 mseide-msegui/apps/ide/cpuform.pas create mode 100644 mseide-msegui/apps/ide/cpuform_mfm.pas create mode 100644 mseide-msegui/apps/ide/cpui386form.mfm create mode 100644 mseide-msegui/apps/ide/cpui386form.pas create mode 100644 mseide-msegui/apps/ide/cpui386form_mfm.pas create mode 100644 mseide-msegui/apps/ide/cpurl78form.mfm create mode 100644 mseide-msegui/apps/ide/cpurl78form.pas create mode 100644 mseide-msegui/apps/ide/cpurl78form_mfm.pas create mode 100644 mseide-msegui/apps/ide/cpux86_64form.mfm create mode 100644 mseide-msegui/apps/ide/cpux86_64form.pas create mode 100644 mseide-msegui/apps/ide/cpux86_64form_mfm.pas create mode 100644 mseide-msegui/apps/ide/debuggerform.mfm create mode 100644 mseide-msegui/apps/ide/debuggerform.pas create mode 100644 mseide-msegui/apps/ide/debuggerform_mfm.pas create mode 100644 mseide-msegui/apps/ide/disassform.mfm create mode 100644 mseide-msegui/apps/ide/disassform.pas create mode 100644 mseide-msegui/apps/ide/disassform_mfm.pas create mode 100644 mseide-msegui/apps/ide/dumpunitgroups.pas create mode 100644 mseide-msegui/apps/ide/finddialogform.mfm create mode 100644 mseide-msegui/apps/ide/finddialogform.pas create mode 100644 mseide-msegui/apps/ide/finddialogform_mfm.pas create mode 100644 mseide-msegui/apps/ide/findinfiledialogform.mfm create mode 100644 mseide-msegui/apps/ide/findinfiledialogform.pas create mode 100644 mseide-msegui/apps/ide/findinfiledialogform_mfm.pas create mode 100644 mseide-msegui/apps/ide/findinfileform.mfm create mode 100644 mseide-msegui/apps/ide/findinfileform.pas create mode 100644 mseide-msegui/apps/ide/findinfileform_mfm.pas create mode 100644 mseide-msegui/apps/ide/findinfilepage.mfm create mode 100644 mseide-msegui/apps/ide/findinfilepage.pas create mode 100644 mseide-msegui/apps/ide/findinfilepage_mfm.pas create mode 100644 mseide-msegui/apps/ide/formdesigner.mfm create mode 100644 mseide-msegui/apps/ide/formdesigner.pas create mode 100644 mseide-msegui/apps/ide/formdesigner_mfm.pas create mode 100644 mseide-msegui/apps/ide/guitemplates.mfm create mode 100644 mseide-msegui/apps/ide/guitemplates.pas create mode 100644 mseide-msegui/apps/ide/guitemplates_mfm.pas create mode 100644 mseide-msegui/apps/ide/main.mfm create mode 100644 mseide-msegui/apps/ide/main.pas create mode 100644 mseide-msegui/apps/ide/main_mfm.pas create mode 100644 mseide-msegui/apps/ide/make.pas create mode 100644 mseide-msegui/apps/ide/memoryform.mfm create mode 100644 mseide-msegui/apps/ide/memoryform.pas create mode 100644 mseide-msegui/apps/ide/memoryform_mfm.pas create mode 100644 mseide-msegui/apps/ide/menusdesign.pas create mode 100644 mseide-msegui/apps/ide/messageform.mfm create mode 100644 mseide-msegui/apps/ide/messageform.pas create mode 100644 mseide-msegui/apps/ide/messageform_mfm.pas create mode 100644 mseide-msegui/apps/ide/msecodetemplates.pas create mode 100644 mseide-msegui/apps/ide/msecomptree.mfm create mode 100644 mseide-msegui/apps/ide/msecomptree.pas create mode 100644 mseide-msegui/apps/ide/msecomptree_mfm.pas create mode 100644 mseide-msegui/apps/ide/msedesigner.pas create mode 100644 mseide-msegui/apps/ide/msedesignparser.pas create mode 100644 mseide-msegui/apps/ide/mseide.ico create mode 100644 mseide-msegui/apps/ide/mseide.pas create mode 100644 mseide-msegui/apps/ide/mseide.prj create mode 100644 mseide-msegui/apps/ide/mseide.rc create mode 100644 mseide-msegui/apps/ide/mseide.res create mode 100644 mseide-msegui/apps/ide/mseide_zeos.prj create mode 100644 mseide-msegui/apps/ide/mseparamentryform.mfm create mode 100644 mseide-msegui/apps/ide/mseparamentryform.pas create mode 100644 mseide-msegui/apps/ide/mseparamentryform_mfm.pas create mode 100644 mseide-msegui/apps/ide/msetemplateselectform.mfm create mode 100644 mseide-msegui/apps/ide/msetemplateselectform.pas create mode 100644 mseide-msegui/apps/ide/msetemplateselectform_mfm.pas create mode 100644 mseide-msegui/apps/ide/objectinspector.mfm create mode 100644 mseide-msegui/apps/ide/objectinspector.pas create mode 100644 mseide-msegui/apps/ide/objectinspector_mfm.pas create mode 100644 mseide-msegui/apps/ide/panelform.mfm create mode 100644 mseide-msegui/apps/ide/panelform.pas create mode 100644 mseide-msegui/apps/ide/panelform_mfm.pas create mode 100644 mseide-msegui/apps/ide/pascaldesignparser.pas create mode 100644 mseide-msegui/apps/ide/printform.mfm create mode 100644 mseide-msegui/apps/ide/printform.pas create mode 100644 mseide-msegui/apps/ide/printform_mfm.pas create mode 100644 mseide-msegui/apps/ide/programparametersform.mfm create mode 100644 mseide-msegui/apps/ide/programparametersform.pas create mode 100644 mseide-msegui/apps/ide/programparametersform_mfm.pas create mode 100644 mseide-msegui/apps/ide/projectoptionsform.mfm create mode 100644 mseide-msegui/apps/ide/projectoptionsform.pas create mode 100644 mseide-msegui/apps/ide/projectoptionsform_mfm.pas create mode 100644 mseide-msegui/apps/ide/projecttreeform.mfm create mode 100644 mseide-msegui/apps/ide/projecttreeform.pas create mode 100644 mseide-msegui/apps/ide/projecttreeform_mfm.pas create mode 100644 mseide-msegui/apps/ide/replacedialogform.mfm create mode 100644 mseide-msegui/apps/ide/replacedialogform.pas create mode 100644 mseide-msegui/apps/ide/replacedialogform_mfm.pas create mode 100644 mseide-msegui/apps/ide/reportdesigner.mfm create mode 100644 mseide-msegui/apps/ide/reportdesigner.pas create mode 100644 mseide-msegui/apps/ide/reportdesigner_mfm.pas create mode 100644 mseide-msegui/apps/ide/selecteditpageform.mfm create mode 100644 mseide-msegui/apps/ide/selecteditpageform.pas create mode 100644 mseide-msegui/apps/ide/selecteditpageform_mfm.pas create mode 100644 mseide-msegui/apps/ide/selectsubformdialogform.pas create mode 100644 mseide-msegui/apps/ide/selectsubformdialogform_mfm.pas create mode 100644 mseide-msegui/apps/ide/selectsubmoduledialogform.mfm create mode 100644 mseide-msegui/apps/ide/selectsubmoduledialogform.pas create mode 100644 mseide-msegui/apps/ide/selectsubmoduledialogform_mfm.pas create mode 100644 mseide-msegui/apps/ide/setcreateorderform.mfm create mode 100644 mseide-msegui/apps/ide/setcreateorderform.pas create mode 100644 mseide-msegui/apps/ide/setcreateorderform_mfm.pas create mode 100644 mseide-msegui/apps/ide/settaborderform.mfm create mode 100644 mseide-msegui/apps/ide/settaborderform.pas create mode 100644 mseide-msegui/apps/ide/settaborderform_mfm.pas create mode 100644 mseide-msegui/apps/ide/skeletons.pas create mode 100644 mseide-msegui/apps/ide/sourceform.mfm create mode 100644 mseide-msegui/apps/ide/sourceform.pas create mode 100644 mseide-msegui/apps/ide/sourceform_mfm.pas create mode 100644 mseide-msegui/apps/ide/sourcehintform.mfm create mode 100644 mseide-msegui/apps/ide/sourcehintform.pas create mode 100644 mseide-msegui/apps/ide/sourcehintform_mfm.pas create mode 100644 mseide-msegui/apps/ide/sourcepage.mfm create mode 100644 mseide-msegui/apps/ide/sourcepage.pas create mode 100644 mseide-msegui/apps/ide/sourcepage_mfm.pas create mode 100644 mseide-msegui/apps/ide/sourceupdate.pas create mode 100644 mseide-msegui/apps/ide/stackform.mfm create mode 100644 mseide-msegui/apps/ide/stackform.pas create mode 100644 mseide-msegui/apps/ide/stackform_mfm.pas create mode 100644 mseide-msegui/apps/ide/storedcomponentinfodialog.mfm create mode 100644 mseide-msegui/apps/ide/storedcomponentinfodialog.pas create mode 100644 mseide-msegui/apps/ide/storedcomponentinfodialog_mfm.pas create mode 100644 mseide-msegui/apps/ide/stringconsts.mfm create mode 100644 mseide-msegui/apps/ide/stringconsts.pas create mode 100644 mseide-msegui/apps/ide/stringconsts_mfm.pas create mode 100644 mseide-msegui/apps/ide/symbolform.mfm create mode 100644 mseide-msegui/apps/ide/symbolform.pas create mode 100644 mseide-msegui/apps/ide/symbolform_mfm.pas create mode 100644 mseide-msegui/apps/ide/syntaxdefs/cpp.sdef create mode 100644 mseide-msegui/apps/ide/syntaxdefs/glsl.sdef create mode 100644 mseide-msegui/apps/ide/syntaxdefs/grammar.sdef create mode 100644 mseide-msegui/apps/ide/syntaxdefs/ipf.sdef create mode 100644 mseide-msegui/apps/ide/syntaxdefs/ipf2.sdef create mode 100644 mseide-msegui/apps/ide/syntaxdefs/java.sdef create mode 100644 mseide-msegui/apps/ide/syntaxdefs/llvm.sdef create mode 100644 mseide-msegui/apps/ide/syntaxdefs/mselang.sdef create mode 100644 mseide-msegui/apps/ide/syntaxdefs/objecttext.sdef create mode 100644 mseide-msegui/apps/ide/syntaxdefs/pascal.sdef create mode 100644 mseide-msegui/apps/ide/syntaxdefs/pascal2.sdef create mode 100644 mseide-msegui/apps/ide/syntaxdefs/pascal_solarized.sdef create mode 100644 mseide-msegui/apps/ide/syntaxdefs/pascal_solarized_dark.sdef create mode 100644 mseide-msegui/apps/ide/syntaxdefs/python.sdef create mode 100644 mseide-msegui/apps/ide/syntaxdefs/sql.sdef create mode 100644 mseide-msegui/apps/ide/targetconsole.mfm create mode 100644 mseide-msegui/apps/ide/targetconsole.pas create mode 100644 mseide-msegui/apps/ide/targetconsole_mfm.pas create mode 100644 mseide-msegui/apps/ide/templateeditor.mfm create mode 100644 mseide-msegui/apps/ide/templateeditor.pas create mode 100644 mseide-msegui/apps/ide/templateeditor_mfm.pas create mode 100644 mseide-msegui/apps/ide/templates/console.prj create mode 100644 mseide-msegui/apps/ide/templates/console/program.pas create mode 100644 mseide-msegui/apps/ide/templates/console/project.pas create mode 100644 mseide-msegui/apps/ide/templates/console/projectarm.pas create mode 100644 mseide-msegui/apps/ide/templates/console/unit.pas create mode 100755 mseide-msegui/apps/ide/templates/copytarget.sh create mode 100644 mseide-msegui/apps/ide/templates/crossarmconsole.prj create mode 100644 mseide-msegui/apps/ide/templates/crossarmdefault.prj create mode 100644 mseide-msegui/apps/ide/templates/default.prj create mode 100644 mseide-msegui/apps/ide/templates/default/datamodule.mfm create mode 100644 mseide-msegui/apps/ide/templates/default/datamodule.pas create mode 100644 mseide-msegui/apps/ide/templates/default/dockingform.mfm create mode 100644 mseide-msegui/apps/ide/templates/default/dockingform.pas create mode 100644 mseide-msegui/apps/ide/templates/default/dockpanelform.mfm create mode 100644 mseide-msegui/apps/ide/templates/default/dockpanelform.pas create mode 100644 mseide-msegui/apps/ide/templates/default/inheritedform.mfm create mode 100644 mseide-msegui/apps/ide/templates/default/inheritedform.pas create mode 100644 mseide-msegui/apps/ide/templates/default/main.mfm create mode 100644 mseide-msegui/apps/ide/templates/default/main.pas create mode 100644 mseide-msegui/apps/ide/templates/default/main_mfm.pas create mode 100644 mseide-msegui/apps/ide/templates/default/mainform.mfm create mode 100644 mseide-msegui/apps/ide/templates/default/mainform.pas create mode 100644 mseide-msegui/apps/ide/templates/default/pascform.mfm create mode 100644 mseide-msegui/apps/ide/templates/default/pascform.pas create mode 100644 mseide-msegui/apps/ide/templates/default/program.pas create mode 100644 mseide-msegui/apps/ide/templates/default/project.pas create mode 100644 mseide-msegui/apps/ide/templates/default/report.mfm create mode 100644 mseide-msegui/apps/ide/templates/default/report.pas create mode 100644 mseide-msegui/apps/ide/templates/default/reppageform.mfm create mode 100644 mseide-msegui/apps/ide/templates/default/reppageform.pas create mode 100644 mseide-msegui/apps/ide/templates/default/scrollboxform.mfm create mode 100644 mseide-msegui/apps/ide/templates/default/scrollboxform.pas create mode 100644 mseide-msegui/apps/ide/templates/default/simpleform.mfm create mode 100644 mseide-msegui/apps/ide/templates/default/simpleform.pas create mode 100644 mseide-msegui/apps/ide/templates/default/sizingform.mfm create mode 100644 mseide-msegui/apps/ide/templates/default/sizingform.pas create mode 100644 mseide-msegui/apps/ide/templates/default/subform.mfm create mode 100644 mseide-msegui/apps/ide/templates/default/subform.pas create mode 100644 mseide-msegui/apps/ide/templates/default/tabform.mfm create mode 100644 mseide-msegui/apps/ide/templates/default/tabform.pas create mode 100644 mseide-msegui/apps/ide/templates/default/unit.pas create mode 100644 mseide-msegui/apps/ide/templates/layoutconsole.prj create mode 100644 mseide-msegui/apps/ide/templates/layoutdockedforms.prj create mode 100644 mseide-msegui/apps/ide/templates/layoutgui.prj create mode 100644 mseide-msegui/apps/ide/templates/library.prj create mode 100644 mseide-msegui/apps/ide/templates/library/program.pas create mode 100644 mseide-msegui/apps/ide/templates/library/project.pas create mode 100644 mseide-msegui/apps/ide/templates/library/unit.pas create mode 100755 mseide-msegui/apps/ide/templates/runsshgdbserver.sh create mode 100644 mseide-msegui/apps/ide/templates/zeos.prj create mode 100644 mseide-msegui/apps/ide/threadsform.mfm create mode 100644 mseide-msegui/apps/ide/threadsform.pas create mode 100644 mseide-msegui/apps/ide/threadsform_mfm.pas create mode 100644 mseide-msegui/apps/ide/toolhandlermodule.mfm create mode 100644 mseide-msegui/apps/ide/toolhandlermodule.pas create mode 100644 mseide-msegui/apps/ide/toolhandlermodule_mfm.pas create mode 100644 mseide-msegui/apps/ide/watchform.mfm create mode 100644 mseide-msegui/apps/ide/watchform.pas create mode 100644 mseide-msegui/apps/ide/watchform_mfm.pas create mode 100644 mseide-msegui/apps/ide/watchpointsform.mfm create mode 100644 mseide-msegui/apps/ide/watchpointsform.pas create mode 100644 mseide-msegui/apps/ide/watchpointsform_mfm.pas create mode 100644 mseide-msegui/apps/myide/mybutton.pas create mode 100644 mseide-msegui/apps/myide/mymseide.prj create mode 100644 mseide-msegui/apps/myide/regcomponents.inc create mode 100644 mseide-msegui/apps/myide/regmycomps.pas create mode 100644 mseide-msegui/contributed/README.TXT create mode 100644 mseide-msegui/help/README.TXT create mode 100644 mseide-msegui/icons/buttons/breakpoint.png create mode 100644 mseide-msegui/icons/buttons/breakpoint.svg create mode 100644 mseide-msegui/icons/buttons/continue.png create mode 100644 mseide-msegui/icons/buttons/continue.svg create mode 100644 mseide-msegui/icons/buttons/continuedisab.png create mode 100644 mseide-msegui/icons/buttons/continuedisab.svg create mode 100644 mseide-msegui/icons/buttons/execline.png create mode 100644 mseide-msegui/icons/buttons/execline.svg create mode 100644 mseide-msegui/icons/buttons/finish.png create mode 100644 mseide-msegui/icons/buttons/finish.svg create mode 100644 mseide-msegui/icons/buttons/finishdisab.png create mode 100644 mseide-msegui/icons/buttons/finishdisab.svg create mode 100644 mseide-msegui/icons/buttons/finishi.png create mode 100644 mseide-msegui/icons/buttons/finishi.svg create mode 100644 mseide-msegui/icons/buttons/interrupt.png create mode 100644 mseide-msegui/icons/buttons/interrupt.svg create mode 100644 mseide-msegui/icons/buttons/interruptdisab.png create mode 100644 mseide-msegui/icons/buttons/interruptdisab.svg create mode 100644 mseide-msegui/icons/buttons/next.png create mode 100644 mseide-msegui/icons/buttons/next.svg create mode 100644 mseide-msegui/icons/buttons/nextdisab.png create mode 100644 mseide-msegui/icons/buttons/nextdisab.svg create mode 100644 mseide-msegui/icons/buttons/nexti.png create mode 100644 mseide-msegui/icons/buttons/nexti.svg create mode 100644 mseide-msegui/icons/buttons/nextidisab.png create mode 100644 mseide-msegui/icons/buttons/nextidisab.svg create mode 100644 mseide-msegui/icons/buttons/path3846.png create mode 100644 mseide-msegui/icons/buttons/reset.png create mode 100644 mseide-msegui/icons/buttons/reset.svg create mode 100644 mseide-msegui/icons/buttons/resetdisab.png create mode 100644 mseide-msegui/icons/buttons/resetdisab.svg create mode 100644 mseide-msegui/icons/buttons/step.png create mode 100644 mseide-msegui/icons/buttons/step.svg create mode 100644 mseide-msegui/icons/buttons/stepdisab.png create mode 100644 mseide-msegui/icons/buttons/stepdisab.svg create mode 100644 mseide-msegui/icons/buttons/stepi.png create mode 100644 mseide-msegui/icons/buttons/stepi.svg create mode 100644 mseide-msegui/icons/buttons/stepidisab.png create mode 100644 mseide-msegui/icons/buttons/stepidisab.svg create mode 100644 mseide-msegui/icons/buttons/watches.png create mode 100644 mseide-msegui/icons/buttons/watches.svg create mode 100644 mseide-msegui/icons/components/123.png create mode 100644 mseide-msegui/icons/components/123s.png create mode 100644 mseide-msegui/icons/components/123ss.png create mode 100644 mseide-msegui/icons/components/1_2.png create mode 100644 mseide-msegui/icons/components/64.png create mode 100755 mseide-msegui/icons/components/TComponent.bmp create mode 100644 mseide-msegui/icons/components/TComponent.png create mode 100644 mseide-msegui/icons/components/TIBConnection.bmp create mode 100644 mseide-msegui/icons/components/TSQLTransaction.bmp create mode 100644 mseide-msegui/icons/components/TZConnection.bmp create mode 100644 mseide-msegui/icons/components/TZSequence.bmp create mode 100644 mseide-msegui/icons/components/TZSqlMetadata.bmp create mode 100644 mseide-msegui/icons/components/TZSqlMonitor.bmp create mode 100644 mseide-msegui/icons/components/TZSqlProcessor.bmp create mode 100644 mseide-msegui/icons/components/TZStoredProc.bmp create mode 100644 mseide-msegui/icons/components/TZUpdateSql.bmp create mode 100644 mseide-msegui/icons/components/_sta.png create mode 100644 mseide-msegui/icons/components/a01.png create mode 100644 mseide-msegui/icons/components/a4ss.png create mode 100644 mseide-msegui/icons/components/ab.png create mode 100644 mseide-msegui/icons/components/abc.png create mode 100644 mseide-msegui/icons/components/abc_de.png create mode 100644 mseide-msegui/icons/components/abcss.png create mode 100644 mseide-msegui/icons/components/abs.png create mode 100644 mseide-msegui/icons/components/abss.png create mode 100644 mseide-msegui/icons/components/breakpoint.png create mode 100644 mseide-msegui/icons/components/capt.png create mode 100644 mseide-msegui/icons/components/ctrl.png create mode 100644 mseide-msegui/icons/components/d_t.png create mode 100644 mseide-msegui/icons/components/d_tss.png.png create mode 100644 mseide-msegui/icons/components/dbf.png create mode 100644 mseide-msegui/icons/components/dirss.png create mode 100644 mseide-msegui/icons/components/e_if.png create mode 100644 mseide-msegui/icons/components/enum.png create mode 100644 mseide-msegui/icons/components/file.png create mode 100644 mseide-msegui/icons/components/files.png create mode 100644 mseide-msegui/icons/components/finishi.svg create mode 100644 mseide-msegui/icons/components/fix.png create mode 100644 mseide-msegui/icons/components/gdi.png create mode 100644 mseide-msegui/icons/components/hist.png create mode 100644 mseide-msegui/icons/components/key.png create mode 100644 mseide-msegui/icons/components/lips.svg create mode 100644 mseide-msegui/icons/components/loc.png create mode 100644 mseide-msegui/icons/components/logo_mysql_sun_a.gif create mode 100644 mseide-msegui/icons/components/me.png create mode 100644 mseide-msegui/icons/components/mem.png create mode 100644 mseide-msegui/icons/components/memo.png create mode 100644 mseide-msegui/icons/components/mes.png create mode 100644 mseide-msegui/icons/components/nil.png create mode 100644 mseide-msegui/icons/components/par_env.png create mode 100644 mseide-msegui/icons/components/pastedpic_11232008_073918.png create mode 100644 mseide-msegui/icons/components/path3889-4.png create mode 100644 mseide-msegui/icons/components/path3889.png create mode 100644 mseide-msegui/icons/components/path4098.png create mode 100644 mseide-msegui/icons/components/path4104.png create mode 100644 mseide-msegui/icons/components/path4444.png create mode 100644 mseide-msegui/icons/components/port_land.png create mode 100644 mseide-msegui/icons/components/portss.png create mode 100644 mseide-msegui/icons/components/proc_mon.png create mode 100644 mseide-msegui/icons/components/ps.png create mode 100644 mseide-msegui/icons/components/rec.png create mode 100644 mseide-msegui/icons/components/rect2648.png create mode 100644 mseide-msegui/icons/components/rect9378.png create mode 100644 mseide-msegui/icons/components/sdf.png create mode 100644 mseide-msegui/icons/components/sel.png create mode 100644 mseide-msegui/icons/components/sigbase.svg create mode 100644 mseide-msegui/icons/components/sigedit.svg create mode 100644 mseide-msegui/icons/components/sql.png create mode 100644 mseide-msegui/icons/components/sql_e.png create mode 100644 mseide-msegui/icons/components/sql_eee.png create mode 100644 mseide-msegui/icons/components/sql_qqq.png create mode 100644 mseide-msegui/icons/components/symbols.svg create mode 100755 mseide-msegui/icons/components/tacecomp.bmp create mode 100755 mseide-msegui/icons/components/taction.bmp create mode 100644 mseide-msegui/icons/components/taction.png create mode 100644 mseide-msegui/icons/components/taction.svg create mode 100644 mseide-msegui/icons/components/tactivator.bmp create mode 100644 mseide-msegui/icons/components/tactivator.png create mode 100644 mseide-msegui/icons/components/tactivator.svg create mode 100644 mseide-msegui/icons/components/tanimitemcomp.png create mode 100644 mseide-msegui/icons/components/tanimitemcomp.svg create mode 100644 mseide-msegui/icons/components/tanimtimer.png create mode 100644 mseide-msegui/icons/components/tanimtimer.svg create mode 100755 mseide-msegui/icons/components/tasciicommport.bmp create mode 100644 mseide-msegui/icons/components/tasciicommport.png create mode 100644 mseide-msegui/icons/components/tasciicommport.svg create mode 100644 mseide-msegui/icons/components/tasciiproptport.png create mode 100644 mseide-msegui/icons/components/tasciiprotport.png create mode 100644 mseide-msegui/icons/components/tasciiprotport.svg create mode 100644 mseide-msegui/icons/components/tassistivehandler.png create mode 100644 mseide-msegui/icons/components/tassistivehandler.svg create mode 100644 mseide-msegui/icons/components/tassistivewidgetitem.png create mode 100644 mseide-msegui/icons/components/tassistivewidgetitem.svg create mode 100644 mseide-msegui/icons/components/tasymciphercryptohandler.png create mode 100644 mseide-msegui/icons/components/tasymciphercryptohandler.svg create mode 100644 mseide-msegui/icons/components/tasynsercommchannel.png create mode 100644 mseide-msegui/icons/components/tasynsercommchannel.svg create mode 100644 mseide-msegui/icons/components/taudioout.png create mode 100644 mseide-msegui/icons/components/taudioout.svg create mode 100644 mseide-msegui/icons/components/tbandarea.bmp create mode 100644 mseide-msegui/icons/components/tbandbroup.bmp create mode 100644 mseide-msegui/icons/components/tbandgroup.bmp create mode 100644 mseide-msegui/icons/components/tbarcode.png create mode 100644 mseide-msegui/icons/components/tbarcode.svg create mode 100644 mseide-msegui/icons/components/tbase64cryptohandler.png create mode 100644 mseide-msegui/icons/components/tbase64cryptohandler.svg create mode 100644 mseide-msegui/icons/components/tbase64handler.png create mode 100644 mseide-msegui/icons/components/tbase64handler.svg create mode 100755 mseide-msegui/icons/components/tbitmapcomp.bmp create mode 100644 mseide-msegui/icons/components/tbitmapcomp.png create mode 100644 mseide-msegui/icons/components/tbitmapcomp.svg create mode 100755 mseide-msegui/icons/components/tbitmapcontainer.bmp create mode 100644 mseide-msegui/icons/components/tbooleandisp.bmp create mode 100644 mseide-msegui/icons/components/tbooleandisp.png create mode 100644 mseide-msegui/icons/components/tbooleandisp.svg create mode 100755 mseide-msegui/icons/components/tbooleanedit.bmp create mode 100755 mseide-msegui/icons/components/tbooleaneditradio.bmp create mode 100755 mseide-msegui/icons/components/tbutton.bmp create mode 100644 mseide-msegui/icons/components/tbutton.png create mode 100644 mseide-msegui/icons/components/tbutton.svg create mode 100644 mseide-msegui/icons/components/tbytestringdisp.bmp create mode 100644 mseide-msegui/icons/components/tbytestringdisp.png create mode 100644 mseide-msegui/icons/components/tbytestringdisp.svg create mode 100644 mseide-msegui/icons/components/tbytestringlist.png create mode 100644 mseide-msegui/icons/components/tcalendardatetimeedit.bmp create mode 100644 mseide-msegui/icons/components/tcalendardatetimeedit.png create mode 100644 mseide-msegui/icons/components/tcalendardatetimeedit.svg create mode 100644 mseide-msegui/icons/components/tcaption.png create mode 100644 mseide-msegui/icons/components/tchart.bmp create mode 100644 mseide-msegui/icons/components/tchart.png create mode 100644 mseide-msegui/icons/components/tchart.svg create mode 100644 mseide-msegui/icons/components/tchartrecorder.bmp create mode 100644 mseide-msegui/icons/components/tchartrecorder.png create mode 100644 mseide-msegui/icons/components/tchartrecorder.svg create mode 100644 mseide-msegui/icons/components/tcoloredit.bmp create mode 100644 mseide-msegui/icons/components/tcoloredit.png create mode 100644 mseide-msegui/icons/components/tcoloredit.svg create mode 100755 mseide-msegui/icons/components/tcommport.bmp create mode 100644 mseide-msegui/icons/components/tcommport.png create mode 100644 mseide-msegui/icons/components/tcommport.svg create mode 100755 mseide-msegui/icons/components/tcommselector.bmp create mode 100644 mseide-msegui/icons/components/tcomponent.svg create mode 100644 mseide-msegui/icons/components/tconnectedifidatasource.png create mode 100644 mseide-msegui/icons/components/tconnectedifidatasource.svg create mode 100644 mseide-msegui/icons/components/tdatabutton.bmp create mode 100644 mseide-msegui/icons/components/tdatabutton.png create mode 100644 mseide-msegui/icons/components/tdatabutton.svg create mode 100755 mseide-msegui/icons/components/tdataedit.bmp create mode 100755 mseide-msegui/icons/components/tdataicon.bmp create mode 100644 mseide-msegui/icons/components/tdataicon.png create mode 100644 mseide-msegui/icons/components/tdataicon.svg create mode 100644 mseide-msegui/icons/components/tdataimage.bmp create mode 100644 mseide-msegui/icons/components/tdataimage.png create mode 100644 mseide-msegui/icons/components/tdataimage.svg create mode 100644 mseide-msegui/icons/components/tdatasource.bmp create mode 100644 mseide-msegui/icons/components/tdatetimedisp.bmp create mode 100644 mseide-msegui/icons/components/tdatetimedisp.png create mode 100644 mseide-msegui/icons/components/tdatetimedisp.svg create mode 100644 mseide-msegui/icons/components/tdatetimedisplb.svg create mode 100755 mseide-msegui/icons/components/tdatetimeedit.bmp create mode 100644 mseide-msegui/icons/components/tdatetimeedit.png create mode 100644 mseide-msegui/icons/components/tdatetimeedit.svg create mode 100644 mseide-msegui/icons/components/tdbbarcode.png create mode 100644 mseide-msegui/icons/components/tdbbarcode.svg create mode 100644 mseide-msegui/icons/components/tdbbooleandisp.bmp create mode 100644 mseide-msegui/icons/components/tdbbooleandisp.png create mode 100644 mseide-msegui/icons/components/tdbbooleanedit.bmp create mode 100644 mseide-msegui/icons/components/tdbbooleaneditradio.bmp create mode 100644 mseide-msegui/icons/components/tdbbooleantextedit.bmp create mode 100644 mseide-msegui/icons/components/tdbbooleantextedit.png create mode 100644 mseide-msegui/icons/components/tdbbooleantextedit.svg create mode 100644 mseide-msegui/icons/components/tdbcalendardatetimeedit.bmp create mode 100644 mseide-msegui/icons/components/tdbcalendardatetimeedit.png create mode 100644 mseide-msegui/icons/components/tdbcalendardatetimeedit.svg create mode 100644 mseide-msegui/icons/components/tdbcoloredit.bmp create mode 100644 mseide-msegui/icons/components/tdbcoloredit.png create mode 100644 mseide-msegui/icons/components/tdbcoloredit.svg create mode 100644 mseide-msegui/icons/components/tdbdatabutton.bmp create mode 100644 mseide-msegui/icons/components/tdbdatabutton.png create mode 100644 mseide-msegui/icons/components/tdbdatabutton.svg create mode 100644 mseide-msegui/icons/components/tdbdataicon.bmp create mode 100644 mseide-msegui/icons/components/tdbdataicon.png create mode 100644 mseide-msegui/icons/components/tdbdataicon.svg create mode 100644 mseide-msegui/icons/components/tdbdataimage.bmp create mode 100644 mseide-msegui/icons/components/tdbdataimage.png create mode 100644 mseide-msegui/icons/components/tdbdataimage.svg create mode 100644 mseide-msegui/icons/components/tdbdatetimedisp.bmp create mode 100644 mseide-msegui/icons/components/tdbdatetimedisp.png create mode 100644 mseide-msegui/icons/components/tdbdatetimedisp.svg create mode 100644 mseide-msegui/icons/components/tdbdatetimedisplb.bmp create mode 100644 mseide-msegui/icons/components/tdbdatetimedisplb.png create mode 100644 mseide-msegui/icons/components/tdbdatetimedisplb.svg create mode 100644 mseide-msegui/icons/components/tdbdatetimeedit.bmp create mode 100644 mseide-msegui/icons/components/tdbdatetimeedit.png create mode 100644 mseide-msegui/icons/components/tdbdatetimeedit.svg create mode 100644 mseide-msegui/icons/components/tdbdatetimelookup64db.png create mode 100644 mseide-msegui/icons/components/tdbdatetimelookup64db.svg create mode 100644 mseide-msegui/icons/components/tdbdatetimelookup64lb.png create mode 100644 mseide-msegui/icons/components/tdbdatetimelookup64lb.svg create mode 100644 mseide-msegui/icons/components/tdbdatetimelookupdb.png create mode 100644 mseide-msegui/icons/components/tdbdatetimelookupdb.svg create mode 100644 mseide-msegui/icons/components/tdbdatetimelookuplb.png create mode 100644 mseide-msegui/icons/components/tdbdatetimelookuplb.svg create mode 100644 mseide-msegui/icons/components/tdbdatetimelookupstrdb.png create mode 100644 mseide-msegui/icons/components/tdbdatetimelookupstrdb.svg create mode 100644 mseide-msegui/icons/components/tdbdatetimelookupstrlb.png create mode 100644 mseide-msegui/icons/components/tdbdatetimelookupstrlb.svg create mode 100644 mseide-msegui/icons/components/tdbdbenumedit.bmp create mode 100644 mseide-msegui/icons/components/tdbdialogstringedit.bmp create mode 100644 mseide-msegui/icons/components/tdbdialogstringedit.png create mode 100644 mseide-msegui/icons/components/tdbdialogstringedit.svg create mode 100644 mseide-msegui/icons/components/tdbdropdownlistedit.bmp create mode 100644 mseide-msegui/icons/components/tdbdropdownlistedit.png create mode 100644 mseide-msegui/icons/components/tdbdropdownlistedit.svg create mode 100644 mseide-msegui/icons/components/tdbdropdownlisteditdb.png create mode 100644 mseide-msegui/icons/components/tdbdropdownlisteditdb.svg create mode 100644 mseide-msegui/icons/components/tdbdropdownlisteditlb.png create mode 100644 mseide-msegui/icons/components/tdbdropdownlisteditlb.svg create mode 100644 mseide-msegui/icons/components/tdbenum64editdb.bmp create mode 100644 mseide-msegui/icons/components/tdbenum64editdb.png create mode 100644 mseide-msegui/icons/components/tdbenum64editdb.svg create mode 100644 mseide-msegui/icons/components/tdbenum64editlb.bmp create mode 100644 mseide-msegui/icons/components/tdbenum64editlb.png create mode 100644 mseide-msegui/icons/components/tdbenum64editlb.svg create mode 100644 mseide-msegui/icons/components/tdbenumedit.bmp create mode 100644 mseide-msegui/icons/components/tdbenumedit.png create mode 100644 mseide-msegui/icons/components/tdbenumedit.svg create mode 100644 mseide-msegui/icons/components/tdbenumeditdb.bmp create mode 100644 mseide-msegui/icons/components/tdbenumeditdb.png create mode 100644 mseide-msegui/icons/components/tdbenumeditdb.svg create mode 100644 mseide-msegui/icons/components/tdbenumeditlb.bmp create mode 100644 mseide-msegui/icons/components/tdbenumeditlb.png create mode 100644 mseide-msegui/icons/components/tdbenumeditlb.svg create mode 100644 mseide-msegui/icons/components/tdbevent.bmp create mode 100644 mseide-msegui/icons/components/tdbevent.png create mode 100644 mseide-msegui/icons/components/tdbevent.svg create mode 100644 mseide-msegui/icons/components/tdbf.bmp create mode 100644 mseide-msegui/icons/components/tdbfilenameedit.bmp create mode 100644 mseide-msegui/icons/components/tdbfilenameedit.png create mode 100644 mseide-msegui/icons/components/tdbfilenameedit.svg create mode 100644 mseide-msegui/icons/components/tdbimage.bmp create mode 100644 mseide-msegui/icons/components/tdbintegerblookup64db.png create mode 100644 mseide-msegui/icons/components/tdbintegerdisp.bmp create mode 100644 mseide-msegui/icons/components/tdbintegerdisp.png create mode 100644 mseide-msegui/icons/components/tdbintegerdisp.svg create mode 100644 mseide-msegui/icons/components/tdbintegerdisplb.bmp create mode 100644 mseide-msegui/icons/components/tdbintegerdisplb.png create mode 100644 mseide-msegui/icons/components/tdbintegerdisplb.svg create mode 100644 mseide-msegui/icons/components/tdbintegeredit.bmp create mode 100644 mseide-msegui/icons/components/tdbintegeredit.png create mode 100644 mseide-msegui/icons/components/tdbintegeredit.svg create mode 100644 mseide-msegui/icons/components/tdbintegerlookup64db.png create mode 100644 mseide-msegui/icons/components/tdbintegerlookup64db.svg create mode 100644 mseide-msegui/icons/components/tdbintegerlookup64lb.png create mode 100644 mseide-msegui/icons/components/tdbintegerlookup64lb.svg create mode 100644 mseide-msegui/icons/components/tdbintegerlookupdb.png create mode 100644 mseide-msegui/icons/components/tdbintegerlookupdb.svg create mode 100644 mseide-msegui/icons/components/tdbintegerlookuplb.png create mode 100644 mseide-msegui/icons/components/tdbintegerlookuplb.svg create mode 100644 mseide-msegui/icons/components/tdbintegerlookupstrdb.png create mode 100644 mseide-msegui/icons/components/tdbintegerlookupstrdb.svg create mode 100644 mseide-msegui/icons/components/tdbintegerlookupstrlb.png create mode 100644 mseide-msegui/icons/components/tdbintegerlookupstrlb.svg create mode 100644 mseide-msegui/icons/components/tdbkeystringedit.bmp create mode 100644 mseide-msegui/icons/components/tdbkeystringedit.png create mode 100644 mseide-msegui/icons/components/tdbkeystringedit.svg create mode 100644 mseide-msegui/icons/components/tdbkeystringeditdb.bmp create mode 100644 mseide-msegui/icons/components/tdbkeystringeditdb.png create mode 100644 mseide-msegui/icons/components/tdbkeystringeditdb.svg create mode 100644 mseide-msegui/icons/components/tdbkeystringeditlb.bmp create mode 100644 mseide-msegui/icons/components/tdbkeystringeditlb.png create mode 100644 mseide-msegui/icons/components/tdbkeystringeditlb.svg create mode 100644 mseide-msegui/icons/components/tdblabel.bmp create mode 100644 mseide-msegui/icons/components/tdblabel.png create mode 100644 mseide-msegui/icons/components/tdblabel.svg create mode 100644 mseide-msegui/icons/components/tdblookupbuffer.bmp create mode 100644 mseide-msegui/icons/components/tdblookupbuffer.png create mode 100644 mseide-msegui/icons/components/tdblookupinteger64db.png create mode 100644 mseide-msegui/icons/components/tdblookupinteger64lb.png create mode 100644 mseide-msegui/icons/components/tdblookupintegerlb.png create mode 100644 mseide-msegui/icons/components/tdblookupintegerstrlb.png create mode 100644 mseide-msegui/icons/components/tdblookupstring64lb.png create mode 100644 mseide-msegui/icons/components/tdbmemoblookupbuffer.bmp create mode 100644 mseide-msegui/icons/components/tdbmemoedit.bmp create mode 100644 mseide-msegui/icons/components/tdbmemoedit.png create mode 100644 mseide-msegui/icons/components/tdbmemoedit.svg create mode 100644 mseide-msegui/icons/components/tdbmemolookupbuffer.bmp create mode 100644 mseide-msegui/icons/components/tdbmemolookupbuffer.png create mode 100644 mseide-msegui/icons/components/tdbnavigator.bmp create mode 100644 mseide-msegui/icons/components/tdbprogressbar.bmp create mode 100644 mseide-msegui/icons/components/tdbprogressbar.png create mode 100644 mseide-msegui/icons/components/tdbprogressbar.svg create mode 100644 mseide-msegui/icons/components/tdbrealdisp.bmp create mode 100644 mseide-msegui/icons/components/tdbrealdisp.png create mode 100644 mseide-msegui/icons/components/tdbrealdisp.svg create mode 100644 mseide-msegui/icons/components/tdbrealdisplb.bmp create mode 100644 mseide-msegui/icons/components/tdbrealdisplb.png create mode 100644 mseide-msegui/icons/components/tdbrealdisplb.svg create mode 100644 mseide-msegui/icons/components/tdbrealedit.bmp create mode 100644 mseide-msegui/icons/components/tdbrealedit.png create mode 100644 mseide-msegui/icons/components/tdbrealedit.svg create mode 100644 mseide-msegui/icons/components/tdbreallookup64db.png create mode 100644 mseide-msegui/icons/components/tdbreallookup64db.svg create mode 100644 mseide-msegui/icons/components/tdbreallookup64lb.png create mode 100644 mseide-msegui/icons/components/tdbreallookup64lb.svg create mode 100644 mseide-msegui/icons/components/tdbreallookupdb.png create mode 100644 mseide-msegui/icons/components/tdbreallookupdb.svg create mode 100644 mseide-msegui/icons/components/tdbreallookuplb.png create mode 100644 mseide-msegui/icons/components/tdbreallookuplb.svg create mode 100644 mseide-msegui/icons/components/tdbreallookupstrdb.png create mode 100644 mseide-msegui/icons/components/tdbreallookupstrdb.svg create mode 100644 mseide-msegui/icons/components/tdbreallookupstrlb.png create mode 100644 mseide-msegui/icons/components/tdbreallookupstrlb.svg create mode 100644 mseide-msegui/icons/components/tdbrealspinedit.bmp create mode 100644 mseide-msegui/icons/components/tdbrealspinedit.png create mode 100644 mseide-msegui/icons/components/tdbrealspinedit.svg create mode 100644 mseide-msegui/icons/components/tdbslider.bmp create mode 100644 mseide-msegui/icons/components/tdbslider.png create mode 100644 mseide-msegui/icons/components/tdbslider.svg create mode 100644 mseide-msegui/icons/components/tdbstingdisp.png create mode 100644 mseide-msegui/icons/components/tdbstingdisplb.png create mode 100644 mseide-msegui/icons/components/tdbstringdisp.bmp create mode 100644 mseide-msegui/icons/components/tdbstringdisp.png create mode 100644 mseide-msegui/icons/components/tdbstringdisp.svg create mode 100644 mseide-msegui/icons/components/tdbstringdisplb.bmp create mode 100644 mseide-msegui/icons/components/tdbstringdisplb.png create mode 100644 mseide-msegui/icons/components/tdbstringdisplb.svg create mode 100644 mseide-msegui/icons/components/tdbstringedit.bmp create mode 100644 mseide-msegui/icons/components/tdbstringedit.png create mode 100644 mseide-msegui/icons/components/tdbstringedit.svg create mode 100644 mseide-msegui/icons/components/tdbstringgrid.bmp create mode 100644 mseide-msegui/icons/components/tdbstringgrid.png create mode 100644 mseide-msegui/icons/components/tdbstringgrid.svg create mode 100644 mseide-msegui/icons/components/tdbstringlookup64db.png create mode 100644 mseide-msegui/icons/components/tdbstringlookup64db.svg create mode 100644 mseide-msegui/icons/components/tdbstringlookup64lb.png create mode 100644 mseide-msegui/icons/components/tdbstringlookup64lb.svg create mode 100644 mseide-msegui/icons/components/tdbstringlookupdb.png create mode 100644 mseide-msegui/icons/components/tdbstringlookupdb.svg create mode 100644 mseide-msegui/icons/components/tdbstringlookuplb.png create mode 100644 mseide-msegui/icons/components/tdbstringlookuplb.svg create mode 100644 mseide-msegui/icons/components/tdbstringlookupstrdb.png create mode 100644 mseide-msegui/icons/components/tdbstringlookupstrdb.svg create mode 100644 mseide-msegui/icons/components/tdbstringlookupstrlb.png create mode 100644 mseide-msegui/icons/components/tdbstringlookupstrlb.svg create mode 100644 mseide-msegui/icons/components/tdbwidgetgrid.bmp create mode 100644 mseide-msegui/icons/components/tdbwidgetgrid.png create mode 100644 mseide-msegui/icons/components/tdbwidgetgrid.svg create mode 100644 mseide-msegui/icons/components/tdial.bmp create mode 100644 mseide-msegui/icons/components/tdialogstringedit.bmp create mode 100644 mseide-msegui/icons/components/tdialogstringedit.png create mode 100644 mseide-msegui/icons/components/tdialogstringedit.svg create mode 100644 mseide-msegui/icons/components/tdigesthandler.png create mode 100644 mseide-msegui/icons/components/tdigesthandler.svg create mode 100644 mseide-msegui/icons/components/tdintegerblookup64db.png create mode 100755 mseide-msegui/icons/components/tdirdropdownedit.bmp create mode 100644 mseide-msegui/icons/components/tdirdropdownedit.png create mode 100644 mseide-msegui/icons/components/tdirdropdownedit.svg create mode 100644 mseide-msegui/icons/components/tdirtreeview.png create mode 100644 mseide-msegui/icons/components/tdirtreeview.svg create mode 100644 mseide-msegui/icons/components/tdirtreeview2.svg create mode 100755 mseide-msegui/icons/components/tdispwidget.bmp create mode 100644 mseide-msegui/icons/components/tdmdatetimedisp.png create mode 100644 mseide-msegui/icons/components/tdmemoblookupbuffer.bmp create mode 100755 mseide-msegui/icons/components/tdockformwidget.bmp create mode 100644 mseide-msegui/icons/components/tdockformwidget.png create mode 100644 mseide-msegui/icons/components/tdockformwidget.svg create mode 100755 mseide-msegui/icons/components/tdockhandle.bmp create mode 100755 mseide-msegui/icons/components/tdockpanel.bmp create mode 100644 mseide-msegui/icons/components/tdockpanel.png create mode 100644 mseide-msegui/icons/components/tdockpanel.svg create mode 100644 mseide-msegui/icons/components/tdockpanelformcontroller.png create mode 100644 mseide-msegui/icons/components/tdockpanelformcontroller.svg create mode 100755 mseide-msegui/icons/components/tdrawgrid.bmp create mode 100644 mseide-msegui/icons/components/tdrawgrid.png create mode 100644 mseide-msegui/icons/components/tdrawgrid.svg create mode 100644 mseide-msegui/icons/components/tdropdownitemedit.bmp create mode 100644 mseide-msegui/icons/components/tdropdownitemedit.png create mode 100644 mseide-msegui/icons/components/tdropdownitemedit.svg create mode 100755 mseide-msegui/icons/components/tdropdownlistedit.bmp create mode 100644 mseide-msegui/icons/components/tdropdownlistedit.png create mode 100644 mseide-msegui/icons/components/tdropdownlistedit.svg create mode 100644 mseide-msegui/icons/components/tdropdownlisteditdb.png create mode 100644 mseide-msegui/icons/components/tdropdownlisteditdb.svg create mode 100644 mseide-msegui/icons/components/tdropdownlisteditlb.png create mode 100644 mseide-msegui/icons/components/tdropdownlisteditlb.svg create mode 100644 mseide-msegui/icons/components/tdummycryptohandler.png create mode 100644 mseide-msegui/icons/components/tdummycryptohandler.svg create mode 100755 mseide-msegui/icons/components/tedit.bmp create mode 100644 mseide-msegui/icons/components/tedit.png create mode 100644 mseide-msegui/icons/components/tedit.svg create mode 100644 mseide-msegui/icons/components/tenum64editdb.bmp create mode 100644 mseide-msegui/icons/components/tenum64editdb.png create mode 100644 mseide-msegui/icons/components/tenum64editdb.svg create mode 100644 mseide-msegui/icons/components/tenum64editlb.bmp create mode 100644 mseide-msegui/icons/components/tenum64editlb.png create mode 100644 mseide-msegui/icons/components/tenum64editlb.svg create mode 100755 mseide-msegui/icons/components/tenumedit.bmp create mode 100644 mseide-msegui/icons/components/tenumedit.png create mode 100644 mseide-msegui/icons/components/tenumedit.svg create mode 100644 mseide-msegui/icons/components/tenumeditdb.bmp create mode 100644 mseide-msegui/icons/components/tenumeditdb.png create mode 100644 mseide-msegui/icons/components/tenumeditdb.svg create mode 100644 mseide-msegui/icons/components/tenumeditedit.png create mode 100644 mseide-msegui/icons/components/tenumeditlb.bmp create mode 100644 mseide-msegui/icons/components/tenumeditlb.png create mode 100644 mseide-msegui/icons/components/tenumeditlb.svg create mode 100644 mseide-msegui/icons/components/tenumtypeedit.bmp create mode 100644 mseide-msegui/icons/components/tenumtypeedit.png create mode 100644 mseide-msegui/icons/components/tenumtypeedit.svg create mode 100644 mseide-msegui/icons/components/tenvelopeedit.png create mode 100644 mseide-msegui/icons/components/tenvelopeedit.svg create mode 100644 mseide-msegui/icons/components/test.bmp create mode 100644 mseide-msegui/icons/components/test.pnm create mode 100644 mseide-msegui/icons/components/test.svg create mode 100755 mseide-msegui/icons/components/teventwidget.bmp create mode 100644 mseide-msegui/icons/components/teventwidget.png create mode 100644 mseide-msegui/icons/components/teventwidget.svg create mode 100644 mseide-msegui/icons/components/texpandingwidget.png create mode 100644 mseide-msegui/icons/components/texpandingwidget.svg create mode 100644 mseide-msegui/icons/components/text3429.png create mode 100755 mseide-msegui/icons/components/tfacecomp.bmp create mode 100644 mseide-msegui/icons/components/tfacecomp.png create mode 100644 mseide-msegui/icons/components/tfacecomp.svg create mode 100644 mseide-msegui/icons/components/tfacelist.bmp create mode 100644 mseide-msegui/icons/components/tfacelist.png create mode 100644 mseide-msegui/icons/components/tfacelist.svg create mode 100644 mseide-msegui/icons/components/tfb3connection.png create mode 100644 mseide-msegui/icons/components/tfb3connection.svg create mode 100644 mseide-msegui/icons/components/tfb3service.png create mode 100644 mseide-msegui/icons/components/tfb3service.svg create mode 100644 mseide-msegui/icons/components/tfbconnection.png create mode 100644 mseide-msegui/icons/components/tfbconnection.svg create mode 100644 mseide-msegui/icons/components/tfbservice.png create mode 100644 mseide-msegui/icons/components/tfbservice.svg create mode 100644 mseide-msegui/icons/components/tfft.png create mode 100644 mseide-msegui/icons/components/tfft.svg create mode 100644 mseide-msegui/icons/components/tffttableedit.png create mode 100644 mseide-msegui/icons/components/tffttableedit.svg create mode 100644 mseide-msegui/icons/components/tfieldfieldlink.bmp create mode 100644 mseide-msegui/icons/components/tfieldfieldlink.png create mode 100644 mseide-msegui/icons/components/tfieldfieldlink.svg create mode 100644 mseide-msegui/icons/components/tfieldlink.bmp create mode 100644 mseide-msegui/icons/components/tfieldlink.png create mode 100644 mseide-msegui/icons/components/tfieldlink.svg create mode 100644 mseide-msegui/icons/components/tfieldparamlink.bmp create mode 100644 mseide-msegui/icons/components/tfieldparamlink.png create mode 100644 mseide-msegui/icons/components/tfieldparamlink.svg create mode 100644 mseide-msegui/icons/components/tfilechangenotifier.png create mode 100644 mseide-msegui/icons/components/tfilechangenotifier.svg create mode 100755 mseide-msegui/icons/components/tfilechangenotifyer.bmp create mode 100644 mseide-msegui/icons/components/tfilechangenotifyer.png create mode 100644 mseide-msegui/icons/components/tfilechangenotifyer.svg create mode 100755 mseide-msegui/icons/components/tfiledialog.bmp create mode 100644 mseide-msegui/icons/components/tfiledialog.png create mode 100644 mseide-msegui/icons/components/tfiledialog.svg create mode 100755 mseide-msegui/icons/components/tfilelistview.bmp create mode 100644 mseide-msegui/icons/components/tfilelistview.png create mode 100644 mseide-msegui/icons/components/tfilelistview.svg create mode 100755 mseide-msegui/icons/components/tfilenameedit.bmp create mode 100644 mseide-msegui/icons/components/tfilenameedit.png create mode 100644 mseide-msegui/icons/components/tfilenameedit.svg create mode 100644 mseide-msegui/icons/components/tfoldedit.png create mode 100644 mseide-msegui/icons/components/tfoldedit.svg create mode 100644 mseide-msegui/icons/components/tfontcomp.png create mode 100644 mseide-msegui/icons/components/tfontcomp.svg create mode 100644 mseide-msegui/icons/components/tformlink.bmp create mode 100755 mseide-msegui/icons/components/tformwidget.bmp create mode 100755 mseide-msegui/icons/components/tframecomp.bmp create mode 100644 mseide-msegui/icons/components/tframecomp.png create mode 100644 mseide-msegui/icons/components/tframecomp.svg create mode 100644 mseide-msegui/icons/components/tfunctableedit.png create mode 100644 mseide-msegui/icons/components/tfunctableedit.svg create mode 100644 mseide-msegui/icons/components/tfuncttableedit.png create mode 100644 mseide-msegui/icons/components/tfuncttableedit.svg create mode 100755 mseide-msegui/icons/components/tgdbmi.bmp create mode 100644 mseide-msegui/icons/components/tgdiprinter.bmp create mode 100644 mseide-msegui/icons/components/tgdiprinter.png create mode 100644 mseide-msegui/icons/components/tgdiprinter.svg create mode 100755 mseide-msegui/icons/components/tgroupbox.bmp create mode 100644 mseide-msegui/icons/components/tgroupbox.png create mode 100644 mseide-msegui/icons/components/tgroupbox.svg create mode 100644 mseide-msegui/icons/components/tguiprocess.png create mode 100644 mseide-msegui/icons/components/tguiprocess.svg create mode 100644 mseide-msegui/icons/components/tguirttistat.png create mode 100644 mseide-msegui/icons/components/tguirttistat.svg create mode 100644 mseide-msegui/icons/components/tguithreadcomp.bmp create mode 100644 mseide-msegui/icons/components/tguithreadcomp.png create mode 100644 mseide-msegui/icons/components/tguithreadcomp.svg create mode 100644 mseide-msegui/icons/components/thelpcontroller.png create mode 100644 mseide-msegui/icons/components/thelpcontroller.svg create mode 100644 mseide-msegui/icons/components/thexstringedit.bmp create mode 100644 mseide-msegui/icons/components/thexstringedit.png create mode 100644 mseide-msegui/icons/components/thexstringedit.svg create mode 100644 mseide-msegui/icons/components/thistoryedit.bmp create mode 100644 mseide-msegui/icons/components/thistoryedit.png create mode 100644 mseide-msegui/icons/components/thistoryedit.svg create mode 100644 mseide-msegui/icons/components/thread.bmp create mode 100644 mseide-msegui/icons/components/ticon.png create mode 100644 mseide-msegui/icons/components/ticon.svg create mode 100644 mseide-msegui/icons/components/tifiactionendpoint.png create mode 100644 mseide-msegui/icons/components/tifiactionendpoint.svg create mode 100644 mseide-msegui/icons/components/tifiactionlinkcomp.png create mode 100644 mseide-msegui/icons/components/tifiactionlinkcomp.svg create mode 100644 mseide-msegui/icons/components/tifibooleanendpoint.png create mode 100644 mseide-msegui/icons/components/tifibooleanendpoint.svg create mode 100644 mseide-msegui/icons/components/tifibooleanlinkcomp.png create mode 100644 mseide-msegui/icons/components/tifibooleanlinkcomp.svg create mode 100644 mseide-msegui/icons/components/tifidatetimeendpoint.png create mode 100644 mseide-msegui/icons/components/tifidatetimeendpoint.svg create mode 100644 mseide-msegui/icons/components/tifidatetimelinkcomp.png create mode 100644 mseide-msegui/icons/components/tifidatetimelinkcomp.svg create mode 100644 mseide-msegui/icons/components/tifidialog.png create mode 100644 mseide-msegui/icons/components/tifidialog.svg create mode 100644 mseide-msegui/icons/components/tifidialogendpoint.png create mode 100644 mseide-msegui/icons/components/tifidialogendpoint.svg create mode 100644 mseide-msegui/icons/components/tifidialoglinkcomp.png create mode 100644 mseide-msegui/icons/components/tifidialoglinkcomp.svg create mode 100644 mseide-msegui/icons/components/tifidropdownendpoint.png create mode 100644 mseide-msegui/icons/components/tifidropdownendpoint.svg create mode 100644 mseide-msegui/icons/components/tifidropdownlistlinkcomp.png create mode 100644 mseide-msegui/icons/components/tifidropdownlistlinkcomp.svg create mode 100644 mseide-msegui/icons/components/tifienumendpoint.png create mode 100644 mseide-msegui/icons/components/tifienumendpoint.svg create mode 100644 mseide-msegui/icons/components/tifienumlinkcomp.png create mode 100644 mseide-msegui/icons/components/tifienumlinkcomp.svg create mode 100644 mseide-msegui/icons/components/tififormlinkcomp.png create mode 100644 mseide-msegui/icons/components/tififormlinkcomp.svg create mode 100644 mseide-msegui/icons/components/tifigridlinkcomp.png create mode 100644 mseide-msegui/icons/components/tifigridlinkcomp.svg create mode 100644 mseide-msegui/icons/components/tifigtidlinkcomp.png create mode 100644 mseide-msegui/icons/components/tifiint64endpoint.png create mode 100644 mseide-msegui/icons/components/tifiint64endpoint.svg create mode 100644 mseide-msegui/icons/components/tifiint64linkcomp.png create mode 100644 mseide-msegui/icons/components/tifiint64linkcomp.svg create mode 100644 mseide-msegui/icons/components/tifiintegerendpoint.png create mode 100644 mseide-msegui/icons/components/tifiintegerendpoint.svg create mode 100644 mseide-msegui/icons/components/tifiintegerlinkcomp.png create mode 100644 mseide-msegui/icons/components/tifiintegerlinkcomp.svg create mode 100644 mseide-msegui/icons/components/tifiitemlinkcomp.png create mode 100644 mseide-msegui/icons/components/tifiitemlinkcomp.svg create mode 100644 mseide-msegui/icons/components/tifilinkcomp.png create mode 100644 mseide-msegui/icons/components/tifilinkcomp.svg create mode 100644 mseide-msegui/icons/components/tifipointerendpoint.png create mode 100644 mseide-msegui/icons/components/tifipointerendpoint.svg create mode 100644 mseide-msegui/icons/components/tifipointerlinkcomp.png create mode 100644 mseide-msegui/icons/components/tifipointerlinkcomp.svg create mode 100644 mseide-msegui/icons/components/tifirealendpoint.png create mode 100644 mseide-msegui/icons/components/tifirealendpoint.svg create mode 100644 mseide-msegui/icons/components/tifireallinkcomp.png create mode 100644 mseide-msegui/icons/components/tifireallinkcomp.svg create mode 100644 mseide-msegui/icons/components/tifisqlresult.png create mode 100644 mseide-msegui/icons/components/tifisqlresult.svg create mode 100644 mseide-msegui/icons/components/tifistringendpoint.png create mode 100644 mseide-msegui/icons/components/tifistringendpoint.svg create mode 100644 mseide-msegui/icons/components/tifistringlinkcomp.png create mode 100644 mseide-msegui/icons/components/tifistringlinkcomp.svg create mode 100644 mseide-msegui/icons/components/tifitreeitemlinkcomp.png create mode 100644 mseide-msegui/icons/components/tifitreeitemlinkcomp.svg create mode 100755 mseide-msegui/icons/components/timage.bmp create mode 100644 mseide-msegui/icons/components/timage.png create mode 100644 mseide-msegui/icons/components/timage.svg create mode 100755 mseide-msegui/icons/components/timagelist.bmp create mode 100644 mseide-msegui/icons/components/timagelist.png create mode 100644 mseide-msegui/icons/components/timagelist.svg create mode 100644 mseide-msegui/icons/components/tint64disp.png create mode 100644 mseide-msegui/icons/components/tint64disp.svg create mode 100644 mseide-msegui/icons/components/tint64edit.png create mode 100644 mseide-msegui/icons/components/tint64edit.svg create mode 100755 mseide-msegui/icons/components/tintegerdisp.bmp create mode 100644 mseide-msegui/icons/components/tintegerdisp.png create mode 100644 mseide-msegui/icons/components/tintegerdisp.svg create mode 100755 mseide-msegui/icons/components/tintegeredit.bmp create mode 100644 mseide-msegui/icons/components/tintegeredit.png create mode 100644 mseide-msegui/icons/components/tintegeredit.svg create mode 100644 mseide-msegui/icons/components/titemedit.bmp create mode 100644 mseide-msegui/icons/components/titemedit.png create mode 100644 mseide-msegui/icons/components/titemedit.svg create mode 100644 mseide-msegui/icons/components/tkeystringcontainer.png create mode 100644 mseide-msegui/icons/components/tkeystringcontainer.svg create mode 100644 mseide-msegui/icons/components/tkeystringedit.bmp create mode 100644 mseide-msegui/icons/components/tkeystringedit.png create mode 100644 mseide-msegui/icons/components/tkeystringedit.svg create mode 100644 mseide-msegui/icons/components/tkeystringeditdb.bmp create mode 100644 mseide-msegui/icons/components/tkeystringeditdb.png create mode 100644 mseide-msegui/icons/components/tkeystringeditdb.svg create mode 100644 mseide-msegui/icons/components/tkeystringeditlb.bmp create mode 100644 mseide-msegui/icons/components/tkeystringeditlb.png create mode 100644 mseide-msegui/icons/components/tkeystringeditlb.svg create mode 100755 mseide-msegui/icons/components/tlabel.bmp create mode 100644 mseide-msegui/icons/components/tlabel.png create mode 100644 mseide-msegui/icons/components/tlabel.svg create mode 100644 mseide-msegui/icons/components/tlayouter.bmp create mode 100644 mseide-msegui/icons/components/tlayouter.png create mode 100644 mseide-msegui/icons/components/tlayouter.svg create mode 100755 mseide-msegui/icons/components/tlistview.bmp create mode 100644 mseide-msegui/icons/components/tlistview.png create mode 100644 mseide-msegui/icons/components/tlistview.svg create mode 100644 mseide-msegui/icons/components/tlocaldataset.png create mode 100644 mseide-msegui/icons/components/tlocaldataset.svg create mode 100644 mseide-msegui/icons/components/tlookupbuffer.bmp create mode 100644 mseide-msegui/icons/components/tlookupbuffer.png create mode 100755 mseide-msegui/icons/components/tmainmenu.bmp create mode 100644 mseide-msegui/icons/components/tmainmenu.png create mode 100644 mseide-msegui/icons/components/tmainmenu.svg create mode 100644 mseide-msegui/icons/components/tmainmenuwidget.bmp create mode 100644 mseide-msegui/icons/components/tmainmenuwidget.png create mode 100644 mseide-msegui/icons/components/tmainmenuwidget.svg create mode 100644 mseide-msegui/icons/components/tmbdropdownitemedit.bmp create mode 100644 mseide-msegui/icons/components/tmbdropdownitemedit.png create mode 100644 mseide-msegui/icons/components/tmbdropdownitemedit.svg create mode 100644 mseide-msegui/icons/components/tmemodialogedit.png create mode 100644 mseide-msegui/icons/components/tmemodialogedit.svg create mode 100644 mseide-msegui/icons/components/tmemodialogstringedit.svg create mode 100644 mseide-msegui/icons/components/tmemoedit.bmp create mode 100644 mseide-msegui/icons/components/tmemoedit.png create mode 100644 mseide-msegui/icons/components/tmemoedit.svg create mode 100644 mseide-msegui/icons/components/tmidisource.png create mode 100644 mseide-msegui/icons/components/tmidisource.svg create mode 100644 mseide-msegui/icons/components/tmodulelink.bmp create mode 100644 mseide-msegui/icons/components/tmseautoincfield.bmp create mode 100644 mseide-msegui/icons/components/tmseautoincfield.png create mode 100644 mseide-msegui/icons/components/tmseautoincfield.svg create mode 100644 mseide-msegui/icons/components/tmsebcdfield.bmp create mode 100644 mseide-msegui/icons/components/tmsebcdfield.png create mode 100644 mseide-msegui/icons/components/tmsebcdfield.svg create mode 100644 mseide-msegui/icons/components/tmsebinaryfield.bmp create mode 100644 mseide-msegui/icons/components/tmsebinaryfield.png create mode 100644 mseide-msegui/icons/components/tmsebinaryfield.svg create mode 100644 mseide-msegui/icons/components/tmseblobfield.bmp create mode 100644 mseide-msegui/icons/components/tmseblobfield.png create mode 100644 mseide-msegui/icons/components/tmseblobfield.svg create mode 100644 mseide-msegui/icons/components/tmsebooleanfield.bmp create mode 100644 mseide-msegui/icons/components/tmsebooleanfield.png create mode 100644 mseide-msegui/icons/components/tmsebooleanfield.svg create mode 100644 mseide-msegui/icons/components/tmsebytesfield.bmp create mode 100644 mseide-msegui/icons/components/tmsebytesfield.png create mode 100644 mseide-msegui/icons/components/tmsebytesfield.svg create mode 100644 mseide-msegui/icons/components/tmsecurrencyfield.bmp create mode 100644 mseide-msegui/icons/components/tmsecurrencyfield.png create mode 100644 mseide-msegui/icons/components/tmsecurrencyfield.svg create mode 100644 mseide-msegui/icons/components/tmsedatasource.png create mode 100644 mseide-msegui/icons/components/tmsedatasource.svg create mode 100644 mseide-msegui/icons/components/tmsedatefield.bmp create mode 100644 mseide-msegui/icons/components/tmsedatefield.png create mode 100644 mseide-msegui/icons/components/tmsedatefield.svg create mode 100644 mseide-msegui/icons/components/tmsedatetimefield.bmp create mode 100644 mseide-msegui/icons/components/tmsedatetimefield.png create mode 100644 mseide-msegui/icons/components/tmsedatetimefield.svg create mode 100644 mseide-msegui/icons/components/tmsedbf.bmp create mode 100644 mseide-msegui/icons/components/tmsedbf.png create mode 100644 mseide-msegui/icons/components/tmsedbf.svg create mode 100644 mseide-msegui/icons/components/tmsefixdataset.png create mode 100644 mseide-msegui/icons/components/tmsefixedataset.png create mode 100644 mseide-msegui/icons/components/tmsefixedformatdataset.bmp create mode 100644 mseide-msegui/icons/components/tmsefixedformatdataset.png create mode 100644 mseide-msegui/icons/components/tmsefixedformatdataset.svg create mode 100644 mseide-msegui/icons/components/tmsefixedfornatdataset.png create mode 100644 mseide-msegui/icons/components/tmsefloatfield.bmp create mode 100644 mseide-msegui/icons/components/tmsefloatfield.png create mode 100644 mseide-msegui/icons/components/tmsefloatfield.svg create mode 100644 mseide-msegui/icons/components/tmseflotfield.png create mode 100755 mseide-msegui/icons/components/tmseformwidget.bmp create mode 100644 mseide-msegui/icons/components/tmseformwidget.png create mode 100644 mseide-msegui/icons/components/tmseformwidget.svg create mode 100644 mseide-msegui/icons/components/tmsegraphicfield.bmp create mode 100644 mseide-msegui/icons/components/tmsegraphicfield.png create mode 100644 mseide-msegui/icons/components/tmsegraphicfield.svg create mode 100644 mseide-msegui/icons/components/tmseguidfield.png create mode 100644 mseide-msegui/icons/components/tmseguidfield.svg create mode 100644 mseide-msegui/icons/components/tmseibconnection.bmp create mode 100644 mseide-msegui/icons/components/tmseibconnection.png create mode 100644 mseide-msegui/icons/components/tmseibconnection.svg create mode 100644 mseide-msegui/icons/components/tmselargeintfield.bmp create mode 100644 mseide-msegui/icons/components/tmselargeintfield.png create mode 100644 mseide-msegui/icons/components/tmselargeintfield.svg create mode 100644 mseide-msegui/icons/components/tmselongintfield.bmp create mode 100644 mseide-msegui/icons/components/tmselongintfield.png create mode 100644 mseide-msegui/icons/components/tmselongintfield.svg create mode 100644 mseide-msegui/icons/components/tmsememdataset.bmp create mode 100644 mseide-msegui/icons/components/tmsememdataset.png create mode 100644 mseide-msegui/icons/components/tmsememdataset.svg create mode 100644 mseide-msegui/icons/components/tmsememofield.bmp create mode 100644 mseide-msegui/icons/components/tmsememofield.png create mode 100644 mseide-msegui/icons/components/tmsememofield.svg create mode 100644 mseide-msegui/icons/components/tmsemysql40connection.bmp create mode 100644 mseide-msegui/icons/components/tmsemysql41connection.bmp create mode 100644 mseide-msegui/icons/components/tmsemysql50connection.bmp create mode 100644 mseide-msegui/icons/components/tmsemysqlconnection.png create mode 100644 mseide-msegui/icons/components/tmsemysqlconnection.svg create mode 100644 mseide-msegui/icons/components/tmseodbcconnection.bmp create mode 100644 mseide-msegui/icons/components/tmseodbcconnection.png create mode 100644 mseide-msegui/icons/components/tmseodbcconnection.svg create mode 100644 mseide-msegui/icons/components/tmsepqconnection.bmp create mode 100644 mseide-msegui/icons/components/tmseprocess.png create mode 100644 mseide-msegui/icons/components/tmseprocess.svg create mode 100644 mseide-msegui/icons/components/tmsesdfdataset.bmp create mode 100644 mseide-msegui/icons/components/tmsesdfdataset.png create mode 100644 mseide-msegui/icons/components/tmsesdfdataset.svg create mode 100644 mseide-msegui/icons/components/tmsesmallintfield.bmp create mode 100644 mseide-msegui/icons/components/tmsesmallintfield.png create mode 100644 mseide-msegui/icons/components/tmsesmallintfield.svg create mode 100644 mseide-msegui/icons/components/tmsesqlite3dataset.bmp create mode 100644 mseide-msegui/icons/components/tmsesqlquery.bmp create mode 100644 mseide-msegui/icons/components/tmsesqlquery.png create mode 100644 mseide-msegui/icons/components/tmsesqlquery.svg create mode 100644 mseide-msegui/icons/components/tmsesqlscript.bmp create mode 100644 mseide-msegui/icons/components/tmsesqlscript.png create mode 100644 mseide-msegui/icons/components/tmsesqlscript.svg create mode 100644 mseide-msegui/icons/components/tmsesqltransaction.bmp create mode 100644 mseide-msegui/icons/components/tmsesqltransaction.png create mode 100644 mseide-msegui/icons/components/tmsesqltransaction.svg create mode 100644 mseide-msegui/icons/components/tmsestringfield.bmp create mode 100644 mseide-msegui/icons/components/tmsestringfield.png create mode 100644 mseide-msegui/icons/components/tmsestringfield.svg create mode 100644 mseide-msegui/icons/components/tmsetimefield.bmp create mode 100644 mseide-msegui/icons/components/tmsetimefield.png create mode 100644 mseide-msegui/icons/components/tmsetimefield.svg create mode 100644 mseide-msegui/icons/components/tmsevarbytesfield.bmp create mode 100644 mseide-msegui/icons/components/tmsevarbytesfield.png create mode 100644 mseide-msegui/icons/components/tmsevarbytesfield.svg create mode 100644 mseide-msegui/icons/components/tmsevarfield.svg create mode 100644 mseide-msegui/icons/components/tmsevariantfield.png create mode 100644 mseide-msegui/icons/components/tmsevariantfield.svg create mode 100644 mseide-msegui/icons/components/tmsewordfield.bmp create mode 100644 mseide-msegui/icons/components/tmsewordfield.png create mode 100644 mseide-msegui/icons/components/tmsewordfield.svg create mode 100644 mseide-msegui/icons/components/tmsezquery.bmp create mode 100644 mseide-msegui/icons/components/tmsezreadonlyquery.bmp create mode 100644 mseide-msegui/icons/components/tmseztable.bmp create mode 100644 mseide-msegui/icons/components/tnoguiaction.bmp create mode 100644 mseide-msegui/icons/components/tnoguiaction.png create mode 100644 mseide-msegui/icons/components/tnoguiaction.svg create mode 100644 mseide-msegui/icons/components/topenglcanvaswidget.png create mode 100644 mseide-msegui/icons/components/topenglcanvaswidget.svg create mode 100644 mseide-msegui/icons/components/topenglwidget.bmp create mode 100644 mseide-msegui/icons/components/topenglwidget.png create mode 100644 mseide-msegui/icons/components/topenglwidget.svg create mode 100644 mseide-msegui/icons/components/topensslcryptohandler.png create mode 100644 mseide-msegui/icons/components/topensslcryptohandler.svg create mode 100644 mseide-msegui/icons/components/tpageorientationselector.png create mode 100644 mseide-msegui/icons/components/tpageorientationselector.svg create mode 100644 mseide-msegui/icons/components/tpagesizeselector.png create mode 100644 mseide-msegui/icons/components/tpagesizeselector.svg create mode 100755 mseide-msegui/icons/components/tpaintbox.bmp create mode 100644 mseide-msegui/icons/components/tpaintbox.png create mode 100644 mseide-msegui/icons/components/tpaintbox.svg create mode 100644 mseide-msegui/icons/components/tparamconnector.png create mode 100644 mseide-msegui/icons/components/tparamconnector.svg create mode 100644 mseide-msegui/icons/components/tparamlink.svg create mode 100644 mseide-msegui/icons/components/tpickwidget.png create mode 100644 mseide-msegui/icons/components/tpickwidget.svg create mode 100644 mseide-msegui/icons/components/tpipeiochannel.bmp create mode 100644 mseide-msegui/icons/components/tpipereader.png create mode 100644 mseide-msegui/icons/components/tpipereader.svg create mode 100755 mseide-msegui/icons/components/tpipereadercomp.bmp create mode 100644 mseide-msegui/icons/components/tpipereadercomp.png create mode 100644 mseide-msegui/icons/components/tpipereadercomp.svg create mode 100644 mseide-msegui/icons/components/tpointeredit.bmp create mode 100644 mseide-msegui/icons/components/tpointeredit.png create mode 100644 mseide-msegui/icons/components/tpointeredit.svg create mode 100644 mseide-msegui/icons/components/tpolygon.bmp create mode 100644 mseide-msegui/icons/components/tpolygon.png create mode 100644 mseide-msegui/icons/components/tpolygon.svg create mode 100755 mseide-msegui/icons/components/tpopupmenu.bmp create mode 100644 mseide-msegui/icons/components/tpopupmenu.png create mode 100644 mseide-msegui/icons/components/tpopupmenu.svg create mode 100644 mseide-msegui/icons/components/tpostscriptprinter.bmp create mode 100644 mseide-msegui/icons/components/tpostscriptprinter.png create mode 100644 mseide-msegui/icons/components/tpostscriptprinter.svg create mode 100644 mseide-msegui/icons/components/tprinter.bmp create mode 100644 mseide-msegui/icons/components/tprocessmonitor.bmp create mode 100644 mseide-msegui/icons/components/tprocessmonitor.png create mode 100644 mseide-msegui/icons/components/tprocessmonitor.svg create mode 100644 mseide-msegui/icons/components/tprogressbar.bmp create mode 100644 mseide-msegui/icons/components/tprogressbar.png create mode 100644 mseide-msegui/icons/components/tprogressbar.svg create mode 100644 mseide-msegui/icons/components/tpsprinter.png create mode 100644 mseide-msegui/icons/components/tpsprinter.svg create mode 100644 mseide-msegui/icons/components/tpythonscript.png create mode 100644 mseide-msegui/icons/components/tpythonscript.svg create mode 100644 mseide-msegui/icons/components/tra.png create mode 100755 mseide-msegui/icons/components/trealdisp.bmp create mode 100644 mseide-msegui/icons/components/trealdisp.png create mode 100644 mseide-msegui/icons/components/trealdisp.svg create mode 100755 mseide-msegui/icons/components/trealedit.bmp create mode 100644 mseide-msegui/icons/components/trealedit.png create mode 100644 mseide-msegui/icons/components/trealedit.svg create mode 100644 mseide-msegui/icons/components/trealspinedit.bmp create mode 100644 mseide-msegui/icons/components/trealspinedit.png create mode 100644 mseide-msegui/icons/components/trealspinedit.svg create mode 100644 mseide-msegui/icons/components/trecordband.bmp create mode 100644 mseide-msegui/icons/components/trecordfieldedit.png create mode 100644 mseide-msegui/icons/components/trecordfieldedit.svg create mode 100644 mseide-msegui/icons/components/treportpage.png create mode 100644 mseide-msegui/icons/components/treportpage.svg create mode 100644 mseide-msegui/icons/components/treppagenumdisp.bmp create mode 100644 mseide-msegui/icons/components/trepprintdatedisp.bmp create mode 100644 mseide-msegui/icons/components/treppsdisp.png create mode 100644 mseide-msegui/icons/components/treppsdisp.svg create mode 100644 mseide-msegui/icons/components/trepspacer.bmp create mode 100644 mseide-msegui/icons/components/trepvaluedisp.bmp create mode 100644 mseide-msegui/icons/components/trichbutton.bmp create mode 100644 mseide-msegui/icons/components/trichbutton.png create mode 100644 mseide-msegui/icons/components/trichbutton.svg create mode 100644 mseide-msegui/icons/components/trichstockglyphbutton.bmp create mode 100644 mseide-msegui/icons/components/trichstockglyphbutton.png create mode 100644 mseide-msegui/icons/components/trichstockglyphbutton.svg create mode 100644 mseide-msegui/icons/components/trichstringdisp.png create mode 100644 mseide-msegui/icons/components/trichstringdisp.svg create mode 100644 mseide-msegui/icons/components/trttistat.png create mode 100644 mseide-msegui/icons/components/trttistat.svg create mode 100644 mseide-msegui/icons/components/true_false.png create mode 100644 mseide-msegui/icons/components/trxdataset.bmp create mode 100644 mseide-msegui/icons/components/trxwidgetgrid.bmp create mode 100755 mseide-msegui/icons/components/tscrollbox.bmp create mode 100644 mseide-msegui/icons/components/tscrollbox.png create mode 100644 mseide-msegui/icons/components/tscrollbox.svg create mode 100644 mseide-msegui/icons/components/tselector.bmp create mode 100644 mseide-msegui/icons/components/tselector.png create mode 100644 mseide-msegui/icons/components/tselector.svg create mode 100644 mseide-msegui/icons/components/tsequencelink.bmp create mode 100644 mseide-msegui/icons/components/tsequencelink.png create mode 100644 mseide-msegui/icons/components/tsequencelink.svg create mode 100644 mseide-msegui/icons/components/tsercommchannel.png create mode 100644 mseide-msegui/icons/components/tsercommchannel.svg create mode 100644 mseide-msegui/icons/components/tsercommcomp.png create mode 100644 mseide-msegui/icons/components/tsercommcomp.svg create mode 100644 mseide-msegui/icons/components/tshortcut.bmp create mode 100644 mseide-msegui/icons/components/tshortcutcontroller.bmp create mode 100644 mseide-msegui/icons/components/tshortcutcontroller.png create mode 100644 mseide-msegui/icons/components/tshortcutcontroller.svg create mode 100644 mseide-msegui/icons/components/tsigadd.png create mode 100644 mseide-msegui/icons/components/tsigadd.svg create mode 100644 mseide-msegui/icons/components/tsigconnector.png create mode 100644 mseide-msegui/icons/components/tsigconnector.svg create mode 100644 mseide-msegui/icons/components/tsigcontroller.png create mode 100644 mseide-msegui/icons/components/tsigcontroller.svg create mode 100644 mseide-msegui/icons/components/tsigdelay.png create mode 100644 mseide-msegui/icons/components/tsigdelay.svg create mode 100644 mseide-msegui/icons/components/tsigdelayn.png create mode 100644 mseide-msegui/icons/components/tsigdelayn.svg create mode 100644 mseide-msegui/icons/components/tsigdelayvar.png create mode 100644 mseide-msegui/icons/components/tsigdelayvar.svg create mode 100644 mseide-msegui/icons/components/tsigenvelope.png create mode 100644 mseide-msegui/icons/components/tsigenvelope.svg create mode 100644 mseide-msegui/icons/components/tsigfft.png create mode 100644 mseide-msegui/icons/components/tsigfft.svg create mode 100644 mseide-msegui/icons/components/tsigfilter.png create mode 100644 mseide-msegui/icons/components/tsigfilter.svg create mode 100644 mseide-msegui/icons/components/tsigfilterbank.png create mode 100644 mseide-msegui/icons/components/tsigfilterbank.svg create mode 100644 mseide-msegui/icons/components/tsigfir.png create mode 100644 mseide-msegui/icons/components/tsigfir.svg create mode 100644 mseide-msegui/icons/components/tsigfunctable.png create mode 100644 mseide-msegui/icons/components/tsigfunctable.svg create mode 100644 mseide-msegui/icons/components/tsigfuncttable.png create mode 100644 mseide-msegui/icons/components/tsigfuncttable.svg create mode 100644 mseide-msegui/icons/components/tsigiir.png create mode 100644 mseide-msegui/icons/components/tsigiir.svg create mode 100644 mseide-msegui/icons/components/tsigin.png create mode 100644 mseide-msegui/icons/components/tsigin.svg create mode 100644 mseide-msegui/icons/components/tsigkeyboard.png create mode 100644 mseide-msegui/icons/components/tsigkeyboard.svg create mode 100644 mseide-msegui/icons/components/tsigmidiconnector.png create mode 100644 mseide-msegui/icons/components/tsigmidiconnector.svg create mode 100644 mseide-msegui/icons/components/tsigmidimulticonnector.png create mode 100644 mseide-msegui/icons/components/tsigmidimulticonnector.svg create mode 100644 mseide-msegui/icons/components/tsigmidisource.png create mode 100644 mseide-msegui/icons/components/tsigmidisource.svg create mode 100644 mseide-msegui/icons/components/tsigmult.png create mode 100644 mseide-msegui/icons/components/tsigmult.svg create mode 100644 mseide-msegui/icons/components/tsignoise.png create mode 100644 mseide-msegui/icons/components/tsignoise.svg create mode 100644 mseide-msegui/icons/components/tsigout.png create mode 100644 mseide-msegui/icons/components/tsigout.svg create mode 100644 mseide-msegui/icons/components/tsigoutaudio.png create mode 100644 mseide-msegui/icons/components/tsigoutaudio.svg create mode 100644 mseide-msegui/icons/components/tsigsampler.png create mode 100644 mseide-msegui/icons/components/tsigsampler.svg create mode 100644 mseide-msegui/icons/components/tsigsamplerfft.png create mode 100644 mseide-msegui/icons/components/tsigsamplerfft.svg create mode 100644 mseide-msegui/icons/components/tsigscope.png create mode 100644 mseide-msegui/icons/components/tsigscope.svg create mode 100644 mseide-msegui/icons/components/tsigscopefft.png create mode 100644 mseide-msegui/icons/components/tsigscopefft.svg create mode 100644 mseide-msegui/icons/components/tsigwavetable.png create mode 100644 mseide-msegui/icons/components/tsigwavetable.svg create mode 100644 mseide-msegui/icons/components/tsimplewidget.bmp create mode 100644 mseide-msegui/icons/components/tsimplewidget.png create mode 100644 mseide-msegui/icons/components/tsimplewidget.svg create mode 100644 mseide-msegui/icons/components/tsimplewidgt.bmp create mode 100644 mseide-msegui/icons/components/tskincontroller.bmp create mode 100644 mseide-msegui/icons/components/tskincontroller.png create mode 100644 mseide-msegui/icons/components/tskincontroller.svg create mode 100644 mseide-msegui/icons/components/tskinextender.png create mode 100644 mseide-msegui/icons/components/tskinextender.svg create mode 100755 mseide-msegui/icons/components/tslider.bmp create mode 100644 mseide-msegui/icons/components/tslider.png create mode 100644 mseide-msegui/icons/components/tslider.svg create mode 100644 mseide-msegui/icons/components/tsocketclient.bmp create mode 100644 mseide-msegui/icons/components/tsocketclientiochannel.bmp create mode 100644 mseide-msegui/icons/components/tsocketclientstdio.bmp create mode 100644 mseide-msegui/icons/components/tsocketserver.bmp create mode 100644 mseide-msegui/icons/components/tsocketserveriochannel.bmp create mode 100644 mseide-msegui/icons/components/tsocketserverstdio.bmp create mode 100644 mseide-msegui/icons/components/tsocketstdio.bmp create mode 100644 mseide-msegui/icons/components/tsocketstdiochannel.bmp create mode 100644 mseide-msegui/icons/components/tsourceedit.png create mode 100644 mseide-msegui/icons/components/tsourceedit.svg create mode 100644 mseide-msegui/icons/components/tspacer.bmp create mode 100644 mseide-msegui/icons/components/tspacer.png create mode 100644 mseide-msegui/icons/components/tspacer.svg create mode 100755 mseide-msegui/icons/components/tsplitter.bmp create mode 100644 mseide-msegui/icons/components/tsplitter.png create mode 100644 mseide-msegui/icons/components/tsplitter.svg create mode 100644 mseide-msegui/icons/components/tsqlite3connection.bmp create mode 100644 mseide-msegui/icons/components/tsqllookupbuffer.bmp create mode 100644 mseide-msegui/icons/components/tsqllookupbuffer.png create mode 100644 mseide-msegui/icons/components/tsqlresult.bmp create mode 100644 mseide-msegui/icons/components/tsqlresult.png create mode 100644 mseide-msegui/icons/components/tsqlresult.svg create mode 100644 mseide-msegui/icons/components/tsqlresultconnector.png create mode 100644 mseide-msegui/icons/components/tsqlresultconnector.svg create mode 100644 mseide-msegui/icons/components/tsqlstatement.bmp create mode 100644 mseide-msegui/icons/components/tsqlstatement.png create mode 100644 mseide-msegui/icons/components/tsqlstatement.svg create mode 100644 mseide-msegui/icons/components/tssl.bmp create mode 100755 mseide-msegui/icons/components/tstatfile.bmp create mode 100644 mseide-msegui/icons/components/tstatfile.png create mode 100644 mseide-msegui/icons/components/tstatfile.svg create mode 100755 mseide-msegui/icons/components/tstepbox.bmp create mode 100644 mseide-msegui/icons/components/tstepbox.png create mode 100644 mseide-msegui/icons/components/tstepbox.svg create mode 100644 mseide-msegui/icons/components/tstingdisp.png create mode 100755 mseide-msegui/icons/components/tstockglyphbutton.bmp create mode 100644 mseide-msegui/icons/components/tstockglyphbutton.png create mode 100644 mseide-msegui/icons/components/tstockglyphbutton.svg create mode 100644 mseide-msegui/icons/components/tstockglyphdatabutton.bmp create mode 100644 mseide-msegui/icons/components/tstockglyphdatabutton.png create mode 100644 mseide-msegui/icons/components/tstockglyphdatabutton.svg create mode 100644 mseide-msegui/icons/components/tstringcontainer.png create mode 100644 mseide-msegui/icons/components/tstringcontainer.svg create mode 100755 mseide-msegui/icons/components/tstringdisp.bmp create mode 100644 mseide-msegui/icons/components/tstringdisp.png create mode 100644 mseide-msegui/icons/components/tstringdisp.svg create mode 100755 mseide-msegui/icons/components/tstringedit.bmp create mode 100644 mseide-msegui/icons/components/tstringedit.png create mode 100644 mseide-msegui/icons/components/tstringedit.svg create mode 100755 mseide-msegui/icons/components/tstringgrid.bmp create mode 100644 mseide-msegui/icons/components/tstringgrid.png create mode 100644 mseide-msegui/icons/components/tstringgrid.svg create mode 100644 mseide-msegui/icons/components/tsymciphercryptohandler.png create mode 100644 mseide-msegui/icons/components/tsymciphercryptohandler.svg create mode 100755 mseide-msegui/icons/components/tsyntaxedit.bmp create mode 100644 mseide-msegui/icons/components/tsyntaxedit.png create mode 100644 mseide-msegui/icons/components/tsyntaxedit.svg create mode 100755 mseide-msegui/icons/components/tsyntaxpainter.bmp create mode 100755 mseide-msegui/icons/components/tsysenvmanager.bmp create mode 100644 mseide-msegui/icons/components/tsysenvmanager.png create mode 100644 mseide-msegui/icons/components/tsysenvmanager.svg create mode 100755 mseide-msegui/icons/components/ttabbar.bmp create mode 100644 mseide-msegui/icons/components/ttabbar.png create mode 100644 mseide-msegui/icons/components/ttabbar.svg create mode 100755 mseide-msegui/icons/components/ttabpage.bmp create mode 100644 mseide-msegui/icons/components/ttabpage.png create mode 100644 mseide-msegui/icons/components/ttabpage.svg create mode 100755 mseide-msegui/icons/components/ttabwidget.bmp create mode 100644 mseide-msegui/icons/components/ttabwidget.png create mode 100644 mseide-msegui/icons/components/ttabwidget.svg create mode 100755 mseide-msegui/icons/components/tterminal.bmp create mode 100644 mseide-msegui/icons/components/tterminal.png create mode 100644 mseide-msegui/icons/components/tterminal.svg create mode 100755 mseide-msegui/icons/components/ttextedit.bmp create mode 100644 mseide-msegui/icons/components/ttextedit.png create mode 100644 mseide-msegui/icons/components/ttextedit.svg create mode 100755 mseide-msegui/icons/components/tthreadcomp.bmp create mode 100644 mseide-msegui/icons/components/tthreadcomp.png create mode 100644 mseide-msegui/icons/components/tthreadcomp.svg create mode 100644 mseide-msegui/icons/components/ttilearea.bmp create mode 100755 mseide-msegui/icons/components/ttimer.bmp create mode 100644 mseide-msegui/icons/components/ttimer.png create mode 100644 mseide-msegui/icons/components/ttimer.svg create mode 100644 mseide-msegui/icons/components/ttimestampfieldlink.bmp create mode 100644 mseide-msegui/icons/components/ttimestampfieldlink.png create mode 100644 mseide-msegui/icons/components/ttimestampfieldlink.svg create mode 100755 mseide-msegui/icons/components/ttoolbar.bmp create mode 100644 mseide-msegui/icons/components/ttoolbar.png create mode 100644 mseide-msegui/icons/components/ttoolbar.svg create mode 100644 mseide-msegui/icons/components/ttraywidget.png create mode 100644 mseide-msegui/icons/components/ttraywidget.svg create mode 100644 mseide-msegui/icons/components/ttreeitemedit.bmp create mode 100644 mseide-msegui/icons/components/ttreeitemedit.png create mode 100644 mseide-msegui/icons/components/ttreeitemedit.svg create mode 100644 mseide-msegui/icons/components/ttreeitemitemedit.png create mode 100644 mseide-msegui/icons/components/ttrigconnector.png create mode 100644 mseide-msegui/icons/components/ttrigconnector.svg create mode 100644 mseide-msegui/icons/components/ttxdatagrid.bmp create mode 100644 mseide-msegui/icons/components/ttxdataset.bmp create mode 100644 mseide-msegui/icons/components/ttxsqlquery.bmp create mode 100644 mseide-msegui/icons/components/tundotextedit.png create mode 100644 mseide-msegui/icons/components/twavetableedit.png create mode 100644 mseide-msegui/icons/components/twavetableedit.svg create mode 100755 mseide-msegui/icons/components/twidgetgrid.bmp create mode 100644 mseide-msegui/icons/components/twidgetgrid.png create mode 100644 mseide-msegui/icons/components/twidgetgrid.svg create mode 100644 mseide-msegui/icons/components/twindowwidget.bmp create mode 100644 mseide-msegui/icons/components/twindowwidget.png create mode 100644 mseide-msegui/icons/components/twindowwidget.svg create mode 100644 mseide-msegui/icons/components/twmfprinter.png create mode 100644 mseide-msegui/icons/components/twmfprinter.svg create mode 100644 mseide-msegui/icons/components/txserieschartedit.png create mode 100644 mseide-msegui/icons/components/txserieschartedit.svg create mode 100644 mseide-msegui/icons/components/txychartedit.png create mode 100644 mseide-msegui/icons/components/txychartedit.svg create mode 100644 mseide-msegui/icons/components/typ.png create mode 100644 mseide-msegui/icons/components/type.png create mode 100644 mseide-msegui/icons/components/tzstreamhandler.png create mode 100644 mseide-msegui/icons/components/tzstreamhandler.svg create mode 100644 mseide-msegui/icons/components/watches.bmp create mode 100755 mseide-msegui/icons/components/watchon.bmp create mode 100644 mseide-msegui/icons/components/watchpoints.bmp create mode 100644 mseide-msegui/icons/components/wmf.png create mode 100644 mseide-msegui/icons/forms/assembler.png create mode 100644 mseide-msegui/icons/forms/assembler.svg create mode 100644 mseide-msegui/icons/forms/breakpoints.png create mode 100644 mseide-msegui/icons/forms/breakpoints.svg create mode 100644 mseide-msegui/icons/forms/componentstore.png create mode 100644 mseide-msegui/icons/forms/componentstore.svg create mode 100644 mseide-msegui/icons/forms/console.png create mode 100644 mseide-msegui/icons/forms/console.svg create mode 100644 mseide-msegui/icons/forms/cpu.png create mode 100644 mseide-msegui/icons/forms/cpu.svg create mode 100644 mseide-msegui/icons/forms/debugger.png create mode 100644 mseide-msegui/icons/forms/debugger.svg create mode 100644 mseide-msegui/icons/forms/findresults.png create mode 100644 mseide-msegui/icons/forms/findresults.svg create mode 100644 mseide-msegui/icons/forms/memory.png create mode 100644 mseide-msegui/icons/forms/memory.svg create mode 100644 mseide-msegui/icons/forms/messages.png create mode 100644 mseide-msegui/icons/forms/messages.svg create mode 100644 mseide-msegui/icons/forms/msei18n_24x24.png create mode 100644 mseide-msegui/icons/forms/objectinspector.png create mode 100644 mseide-msegui/icons/forms/objectinspector.svg create mode 100644 mseide-msegui/icons/forms/palette.png create mode 100644 mseide-msegui/icons/forms/palette.svg create mode 100644 mseide-msegui/icons/forms/rect6550.png create mode 100644 mseide-msegui/icons/forms/source.png create mode 100644 mseide-msegui/icons/forms/source.svg create mode 100644 mseide-msegui/icons/forms/stack.png create mode 100644 mseide-msegui/icons/forms/stack.svg create mode 100644 mseide-msegui/icons/forms/thread.png create mode 100644 mseide-msegui/icons/forms/thread.svg create mode 100644 mseide-msegui/icons/forms/watches.png create mode 100644 mseide-msegui/icons/forms/watches.svg create mode 100644 mseide-msegui/icons/forms/watchpoints.png create mode 100644 mseide-msegui/icons/forms/watchppoints.svg create mode 100644 mseide-msegui/icons/frames/demo/0.png create mode 100644 mseide-msegui/icons/frames/demo/0.xcf create mode 100644 mseide-msegui/icons/frames/demo/1.png create mode 100644 mseide-msegui/icons/frames/demo/1.xcf create mode 100644 mseide-msegui/icons/frames/demo/10.png create mode 100644 mseide-msegui/icons/frames/demo/10.xcf create mode 100644 mseide-msegui/icons/frames/demo/11.png create mode 100644 mseide-msegui/icons/frames/demo/11.xcf create mode 100644 mseide-msegui/icons/frames/demo/12.png create mode 100644 mseide-msegui/icons/frames/demo/12.xcf create mode 100644 mseide-msegui/icons/frames/demo/13.png create mode 100644 mseide-msegui/icons/frames/demo/13.xcf create mode 100644 mseide-msegui/icons/frames/demo/14.png create mode 100644 mseide-msegui/icons/frames/demo/14.xcf create mode 100644 mseide-msegui/icons/frames/demo/15.png create mode 100644 mseide-msegui/icons/frames/demo/15.xcf create mode 100644 mseide-msegui/icons/frames/demo/16.png create mode 100644 mseide-msegui/icons/frames/demo/16.xcf create mode 100644 mseide-msegui/icons/frames/demo/17.png create mode 100644 mseide-msegui/icons/frames/demo/17.xcf create mode 100644 mseide-msegui/icons/frames/demo/18.png create mode 100644 mseide-msegui/icons/frames/demo/18.xcf create mode 100644 mseide-msegui/icons/frames/demo/19.png create mode 100644 mseide-msegui/icons/frames/demo/19.xcf create mode 100644 mseide-msegui/icons/frames/demo/2.png create mode 100644 mseide-msegui/icons/frames/demo/2.xcf create mode 100644 mseide-msegui/icons/frames/demo/20.png create mode 100644 mseide-msegui/icons/frames/demo/20.xcf create mode 100644 mseide-msegui/icons/frames/demo/21.png create mode 100644 mseide-msegui/icons/frames/demo/21.xcf create mode 100644 mseide-msegui/icons/frames/demo/22.png create mode 100644 mseide-msegui/icons/frames/demo/22.xcf create mode 100644 mseide-msegui/icons/frames/demo/23.png create mode 100644 mseide-msegui/icons/frames/demo/23.xcf create mode 100644 mseide-msegui/icons/frames/demo/24.png create mode 100644 mseide-msegui/icons/frames/demo/24.xcf create mode 100644 mseide-msegui/icons/frames/demo/25.png create mode 100644 mseide-msegui/icons/frames/demo/25.xcf create mode 100644 mseide-msegui/icons/frames/demo/26.png create mode 100644 mseide-msegui/icons/frames/demo/26.xcf create mode 100644 mseide-msegui/icons/frames/demo/27.png create mode 100644 mseide-msegui/icons/frames/demo/27.xcf create mode 100644 mseide-msegui/icons/frames/demo/28.png create mode 100644 mseide-msegui/icons/frames/demo/28.xcf create mode 100644 mseide-msegui/icons/frames/demo/29.png create mode 100644 mseide-msegui/icons/frames/demo/29.xcf create mode 100644 mseide-msegui/icons/frames/demo/3.png create mode 100644 mseide-msegui/icons/frames/demo/3.xcf create mode 100644 mseide-msegui/icons/frames/demo/30.png create mode 100644 mseide-msegui/icons/frames/demo/30.xcf create mode 100644 mseide-msegui/icons/frames/demo/31.png create mode 100644 mseide-msegui/icons/frames/demo/31.xcf create mode 100644 mseide-msegui/icons/frames/demo/4.png create mode 100644 mseide-msegui/icons/frames/demo/4.xcf create mode 100644 mseide-msegui/icons/frames/demo/5.png create mode 100644 mseide-msegui/icons/frames/demo/5.xcf create mode 100644 mseide-msegui/icons/frames/demo/6.png create mode 100644 mseide-msegui/icons/frames/demo/6.xcf create mode 100644 mseide-msegui/icons/frames/demo/7.png create mode 100644 mseide-msegui/icons/frames/demo/7.xcf create mode 100644 mseide-msegui/icons/frames/demo/8.png create mode 100644 mseide-msegui/icons/frames/demo/8.xcf create mode 100644 mseide-msegui/icons/frames/demo/9.png create mode 100644 mseide-msegui/icons/frames/demo/9.xcf create mode 100644 mseide-msegui/icons/frames/frames.png create mode 100644 mseide-msegui/icons/frames/frames.svg create mode 100644 mseide-msegui/icons/frames/frames.xcf create mode 100644 mseide-msegui/icons/frames/frames0.png create mode 100644 mseide-msegui/icons/frames/frames1.png create mode 100644 mseide-msegui/icons/frames/frames2.png create mode 100644 mseide-msegui/icons/frames/frames3.png create mode 100644 mseide-msegui/icons/frames/frames4.png create mode 100644 mseide-msegui/icons/frames/frames5.png create mode 100644 mseide-msegui/icons/frames/frames6.png create mode 100644 mseide-msegui/icons/frames/frames7.png create mode 100755 mseide-msegui/icons/makicon create mode 100644 mseide-msegui/icons/menus/assembler.png create mode 100644 mseide-msegui/icons/menus/assembler.svg create mode 100644 mseide-msegui/icons/menus/breakpoints.png create mode 100644 mseide-msegui/icons/menus/breakpoints.svg create mode 100644 mseide-msegui/icons/menus/componentstore.png create mode 100644 mseide-msegui/icons/menus/componentstore.svg create mode 100644 mseide-msegui/icons/menus/console.png create mode 100644 mseide-msegui/icons/menus/console.svg create mode 100644 mseide-msegui/icons/menus/cpu.png create mode 100644 mseide-msegui/icons/menus/cpu.svg create mode 100644 mseide-msegui/icons/menus/debugger.png create mode 100644 mseide-msegui/icons/menus/debugger.svg create mode 100644 mseide-msegui/icons/menus/findresults.png create mode 100644 mseide-msegui/icons/menus/findresults.svg create mode 100644 mseide-msegui/icons/menus/memory.png create mode 100644 mseide-msegui/icons/menus/memory.svg create mode 100644 mseide-msegui/icons/menus/messages.png create mode 100644 mseide-msegui/icons/menus/messages.svg create mode 100644 mseide-msegui/icons/menus/objectinspector.png create mode 100644 mseide-msegui/icons/menus/objectinspector.svg create mode 100644 mseide-msegui/icons/menus/palette.png create mode 100644 mseide-msegui/icons/menus/palette.svg create mode 100644 mseide-msegui/icons/menus/pastedpic_11162008_154602.png create mode 100644 mseide-msegui/icons/menus/source.png create mode 100644 mseide-msegui/icons/menus/source.svg create mode 100644 mseide-msegui/icons/menus/stack.png create mode 100644 mseide-msegui/icons/menus/stack.svg create mode 100644 mseide-msegui/icons/menus/symbols.png create mode 100644 mseide-msegui/icons/menus/thread.png create mode 100644 mseide-msegui/icons/menus/thread.svg create mode 100644 mseide-msegui/icons/menus/threads.svg create mode 100644 mseide-msegui/icons/menus/watches.png create mode 100644 mseide-msegui/icons/menus/watches.svg create mode 100644 mseide-msegui/icons/menus/watchpoints.png create mode 100644 mseide-msegui/icons/menus/watchppoints.svg create mode 100644 mseide-msegui/icons/msegui/edelweiss.svg create mode 100644 mseide-msegui/icons/msegui/edelweiss2_16.png create mode 100644 mseide-msegui/icons/msegui/edelweiss2_16bi.png create mode 100644 mseide-msegui/icons/msegui/edelweiss2_17.png create mode 100644 mseide-msegui/icons/msegui/edelweiss2_17bi.png create mode 100644 mseide-msegui/icons/msegui/edelweiss2_18.png create mode 100644 mseide-msegui/icons/msegui/edelweiss2_18bi.png create mode 100644 mseide-msegui/icons/msegui/edelweiss2_24.png create mode 100644 mseide-msegui/icons/msegui/edelweiss2_24bi.png create mode 100644 mseide-msegui/icons/msegui/edelweiss2_32.png create mode 100644 mseide-msegui/icons/msegui/edelweiss2_32bi.png create mode 100644 mseide-msegui/icons/msegui/edelweiss2_48.png create mode 100644 mseide-msegui/icons/msegui/edelweiss2_48bi.png create mode 100644 mseide-msegui/icons/msegui/edelweiss2_64.png create mode 100644 mseide-msegui/icons/msegui/edelweiss2_64bi.ico create mode 100644 mseide-msegui/icons/msegui/edelweiss2_64bi.png create mode 100644 mseide-msegui/icons/msegui/edelweiss_bi.svg create mode 100644 mseide-msegui/icons/msegui/edelweiss_biround.svg create mode 100644 mseide-msegui/icons/msegui/edelweissgreen_24bi.png create mode 100644 mseide-msegui/icons/msegui/edelweissgreen_32bi.png create mode 100644 mseide-msegui/icons/msegui/edelweissgreen_bi.svg create mode 100644 mseide-msegui/icons/resources/dir.png create mode 100644 mseide-msegui/icons/resources/dirgreen.png create mode 100644 mseide-msegui/icons/resources/dirgreenwarn.png create mode 100644 mseide-msegui/icons/resources/diropen.png create mode 100644 mseide-msegui/icons/resources/diropengreen.png create mode 100644 mseide-msegui/icons/resources/diropengreenwarn.png create mode 100644 mseide-msegui/icons/resources/diropenred.png create mode 100644 mseide-msegui/icons/resources/diropenredgreen.png create mode 100644 mseide-msegui/icons/resources/diropenredgreenwarn.png create mode 100644 mseide-msegui/icons/resources/diropenredwarn.png create mode 100644 mseide-msegui/icons/resources/diropenwhite.png create mode 100644 mseide-msegui/icons/resources/dirplus.png create mode 100644 mseide-msegui/icons/resources/dirplusgreen.png create mode 100644 mseide-msegui/icons/resources/dirplusred.png create mode 100644 mseide-msegui/icons/resources/dirpluswhite.png create mode 100644 mseide-msegui/icons/resources/dirred.png create mode 100644 mseide-msegui/icons/resources/dirredgreen.png create mode 100644 mseide-msegui/icons/resources/dirredgreenwarn.png create mode 100644 mseide-msegui/icons/resources/dirredwarn.png create mode 100644 mseide-msegui/icons/resources/dirwhite.png create mode 100644 mseide-msegui/icons/resources/file.png create mode 100644 mseide-msegui/icons/resources/filedialogres.png create mode 100644 mseide-msegui/icons/resources/filegreen.png create mode 100644 mseide-msegui/icons/resources/filegreenminusred.png create mode 100644 mseide-msegui/icons/resources/filegreenred.png create mode 100644 mseide-msegui/icons/resources/filegreenredwarn.png create mode 100644 mseide-msegui/icons/resources/filegreenwarn.png create mode 100644 mseide-msegui/icons/resources/fileminusred.png create mode 100644 mseide-msegui/icons/resources/fileplusgreen.png create mode 100644 mseide-msegui/icons/resources/filered.png create mode 100644 mseide-msegui/icons/resources/fileredplusgreen.png create mode 100644 mseide-msegui/icons/resources/fileredwarn.png create mode 100644 mseide-msegui/icons/resources/filterreset.png create mode 100644 mseide-msegui/icons/resources/form.png create mode 100644 mseide-msegui/icons/resources/imagebackground.png create mode 100644 mseide-msegui/icons/resources/mergepending.png create mode 100644 mseide-msegui/icons/resources/mergependingred.png create mode 100644 mseide-msegui/icons/resources/opengl.png create mode 100644 mseide-msegui/icons/resources/pushconflict.png create mode 100644 mseide-msegui/icons/resources/pushmergeconflictpending.png create mode 100644 mseide-msegui/icons/resources/pushmergepending.png create mode 100644 mseide-msegui/icons/resources/pushpending.png create mode 100644 mseide-msegui/icons/resources/stg_checkboxparentnotchecked.png create mode 100644 mseide-msegui/icons/resources/stg_checkboxparentnotchecked.xcf create mode 100644 mseide-msegui/icons/resources/unitform.png create mode 100644 mseide-msegui/lib/common/COPYING.LGPL create mode 100644 mseide-msegui/lib/common/COPYING.MSE create mode 100644 mseide-msegui/lib/common/assistive/mseassistivehandler.pas create mode 100644 mseide-msegui/lib/common/audio/mseaudio.pas create mode 100644 mseide-msegui/lib/common/audio/mseespeakng.pas create mode 100644 mseide-msegui/lib/common/audio/msemidi.pas create mode 100644 mseide-msegui/lib/common/audio/msepulse.pas create mode 100644 mseide-msegui/lib/common/audio/msepulseglob.pas create mode 100644 mseide-msegui/lib/common/audio/msepulsesimple.pas create mode 100644 mseide-msegui/lib/common/audio/msespeak.pas create mode 100644 mseide-msegui/lib/common/container/msedatalist.pas create mode 100644 mseide-msegui/lib/common/container/msehash.pas create mode 100644 mseide-msegui/lib/common/container/msehashstore.pas create mode 100644 mseide-msegui/lib/common/container/mselinklist.pas create mode 100644 mseide-msegui/lib/common/container/mselist.pas create mode 100644 mseide-msegui/lib/common/container/msestringident.pas create mode 100644 mseide-msegui/lib/common/container/msesumlist.pas create mode 100644 mseide-msegui/lib/common/crypto/msecrc.pas create mode 100644 mseide-msegui/lib/common/crypto/msecryptio.pas create mode 100644 mseide-msegui/lib/common/crypto/msecryptohandler.pas create mode 100644 mseide-msegui/lib/common/crypto/msecryptstream.pas create mode 100644 mseide-msegui/lib/common/crypto/mseopenssl.pas create mode 100644 mseide-msegui/lib/common/crypto/mseopensslaes.pas create mode 100644 mseide-msegui/lib/common/crypto/mseopensslasn.pas create mode 100644 mseide-msegui/lib/common/crypto/mseopensslbignum.pas create mode 100644 mseide-msegui/lib/common/crypto/mseopensslbio.pas create mode 100644 mseide-msegui/lib/common/crypto/mseopenssldes.pas create mode 100644 mseide-msegui/lib/common/crypto/mseopenssldsa.pas create mode 100644 mseide-msegui/lib/common/crypto/mseopensslevp.pas create mode 100644 mseide-msegui/lib/common/crypto/mseopensslpem.pas create mode 100644 mseide-msegui/lib/common/crypto/mseopensslpkcs.pas create mode 100644 mseide-msegui/lib/common/crypto/mseopensslrand.pas create mode 100644 mseide-msegui/lib/common/crypto/mseopensslrsa.pas create mode 100644 mseide-msegui/lib/common/crypto/mseopensslsmime.pas create mode 100644 mseide-msegui/lib/common/crypto/mseopensslx509.pas create mode 100644 mseide-msegui/lib/common/crypto/msessl.pas create mode 100644 mseide-msegui/lib/common/crypto/msezlib.pas create mode 100644 mseide-msegui/lib/common/crypto/msezstream.pas create mode 100644 mseide-msegui/lib/common/db/firebird.pas create mode 100644 mseide-msegui/lib/common/db/ibase60.inc create mode 100644 mseide-msegui/lib/common/db/ibase60.pas create mode 100644 mseide-msegui/lib/common/db/ibase60dyn.pas create mode 100644 mseide-msegui/lib/common/db/memds.pp create mode 100644 mseide-msegui/lib/common/db/mibconnection.pas create mode 100644 mseide-msegui/lib/common/db/mmysql40conn.pas create mode 100644 mseide-msegui/lib/common/db/mmysql41conn.pas create mode 100644 mseide-msegui/lib/common/db/mmysql4conn.pas create mode 100644 mseide-msegui/lib/common/db/mmysql50conn.pas create mode 100644 mseide-msegui/lib/common/db/mmysqlconn.inc create mode 100644 mseide-msegui/lib/common/db/mmysqlconn.pas create mode 100644 mseide-msegui/lib/common/db/modbcconn.pas create mode 100644 mseide-msegui/lib/common/db/mpqconnection.pas create mode 100644 mseide-msegui/lib/common/db/msebufdataset.pas create mode 100644 mseide-msegui/lib/common/db/msedatabase.pas create mode 100644 mseide-msegui/lib/common/db/msedb.pas create mode 100644 mseide-msegui/lib/common/db/msedbcalendardatetimeedit.pas create mode 100644 mseide-msegui/lib/common/db/msedbdialog.pas create mode 100644 mseide-msegui/lib/common/db/msedbdispwidgets.pas create mode 100644 mseide-msegui/lib/common/db/msedbedit.pas create mode 100644 mseide-msegui/lib/common/db/msedbevents.pas create mode 100644 mseide-msegui/lib/common/db/msedbf.pas create mode 100644 mseide-msegui/lib/common/db/msedbgraphics.pas create mode 100644 mseide-msegui/lib/common/db/msedblookup.pas create mode 100644 mseide-msegui/lib/common/db/msefb3connection.pas create mode 100644 mseide-msegui/lib/common/db/msefb3service.pas create mode 100644 mseide-msegui/lib/common/db/msefbinterface.pas create mode 100644 mseide-msegui/lib/common/db/msefbservice.pas create mode 100644 mseide-msegui/lib/common/db/msefbutils.pas create mode 100644 mseide-msegui/lib/common/db/msefirebird.pas create mode 100644 mseide-msegui/lib/common/db/mseibconnection.pas create mode 100644 mseide-msegui/lib/common/db/mselocaldataset.pas create mode 100644 mseide-msegui/lib/common/db/mselookupbuffer.pas create mode 100644 mseide-msegui/lib/common/db/msememds.pas create mode 100644 mseide-msegui/lib/common/db/msemysql40conn.pas create mode 100644 mseide-msegui/lib/common/db/msemysql41conn.pas create mode 100644 mseide-msegui/lib/common/db/msemysql50conn.pas create mode 100644 mseide-msegui/lib/common/db/msemysqlconn.pas create mode 100644 mseide-msegui/lib/common/db/mseodbcconn.pas create mode 100644 mseide-msegui/lib/common/db/msepqconnection.pas create mode 100644 mseide-msegui/lib/common/db/msesdfdata.pas create mode 100644 mseide-msegui/lib/common/db/msesqldb.pas create mode 100644 mseide-msegui/lib/common/db/msesqlite3conn.pas create mode 100644 mseide-msegui/lib/common/db/msesqlquery.pas create mode 100644 mseide-msegui/lib/common/db/msesqlresult.pas create mode 100644 mseide-msegui/lib/common/db/msezeos.pas create mode 100644 mseide-msegui/lib/common/db/msqldb.pas create mode 100644 mseide-msegui/lib/common/db/mysqldyn.pas create mode 100644 mseide-msegui/lib/common/db/odbcsqldyn.pas create mode 100644 mseide-msegui/lib/common/db/postgres3dyn.pas create mode 100644 mseide-msegui/lib/common/db/sqlite3dyn.pas create mode 100644 mseide-msegui/lib/common/designutils/msecomponenteditors.pas create mode 100644 mseide-msegui/lib/common/designutils/msecornermaskeditor.mfm create mode 100644 mseide-msegui/lib/common/designutils/msecornermaskeditor.pas create mode 100644 mseide-msegui/lib/common/designutils/msecornermaskeditor_mfm.pas create mode 100644 mseide-msegui/lib/common/designutils/msedbfieldeditor.mfm create mode 100644 mseide-msegui/lib/common/designutils/msedbfieldeditor.pas create mode 100644 mseide-msegui/lib/common/designutils/msedbfieldeditor_mfm.pas create mode 100644 mseide-msegui/lib/common/designutils/msedesignintf.pas create mode 100644 mseide-msegui/lib/common/designutils/msedoublereallisteditor.mfm create mode 100644 mseide-msegui/lib/common/designutils/msedoublereallisteditor.pas create mode 100644 mseide-msegui/lib/common/designutils/msedoublereallisteditor_mfm.pas create mode 100644 mseide-msegui/lib/common/designutils/msedoublestringlisteditor.mfm create mode 100644 mseide-msegui/lib/common/designutils/msedoublestringlisteditor.pas create mode 100644 mseide-msegui/lib/common/designutils/msedoublestringlisteditor_mfm.pas create mode 100644 mseide-msegui/lib/common/designutils/msefaceselectorform.mfm create mode 100644 mseide-msegui/lib/common/designutils/msefaceselectorform.pas create mode 100644 mseide-msegui/lib/common/designutils/msefaceselectorform_mfm.pas create mode 100644 mseide-msegui/lib/common/designutils/msefadeedit.mfm create mode 100644 mseide-msegui/lib/common/designutils/msefadeedit.pas create mode 100644 mseide-msegui/lib/common/designutils/msefadeedit_mfm.pas create mode 100644 mseide-msegui/lib/common/designutils/msefadepropedit.pas create mode 100644 mseide-msegui/lib/common/designutils/msefircoeffeditor.mfm create mode 100644 mseide-msegui/lib/common/designutils/msefircoeffeditor.pas create mode 100644 mseide-msegui/lib/common/designutils/msefircoeffeditor_mfm.pas create mode 100644 mseide-msegui/lib/common/designutils/mseformdatatools.pas create mode 100644 mseide-msegui/lib/common/designutils/msegdbutils.pas create mode 100644 mseide-msegui/lib/common/designutils/mseificlienteditor.mfm create mode 100644 mseide-msegui/lib/common/designutils/mseificlienteditor.pas create mode 100644 mseide-msegui/lib/common/designutils/mseificlienteditor_mfm.pas create mode 100644 mseide-msegui/lib/common/designutils/mseificomponenteditors.pas create mode 100644 mseide-msegui/lib/common/designutils/mseififieldeditor.mfm create mode 100644 mseide-msegui/lib/common/designutils/mseififieldeditor.pas create mode 100644 mseide-msegui/lib/common/designutils/mseififieldeditor_mfm.pas create mode 100644 mseide-msegui/lib/common/designutils/mseiircoeffeditor.mfm create mode 100644 mseide-msegui/lib/common/designutils/mseiircoeffeditor.pas create mode 100644 mseide-msegui/lib/common/designutils/mseiircoeffeditor_mfm.pas create mode 100644 mseide-msegui/lib/common/designutils/mseimagelisteditor.mfm create mode 100644 mseide-msegui/lib/common/designutils/mseimagelisteditor.pas create mode 100644 mseide-msegui/lib/common/designutils/mseimagelisteditor_mfm.pas create mode 100644 mseide-msegui/lib/common/designutils/mseimageselectorform.mfm create mode 100644 mseide-msegui/lib/common/designutils/mseimageselectorform.pas create mode 100644 mseide-msegui/lib/common/designutils/mseimageselectorform_mfm.pas create mode 100644 mseide-msegui/lib/common/designutils/mseindexlookupeditor.mfm create mode 100644 mseide-msegui/lib/common/designutils/mseindexlookupeditor.pas create mode 100644 mseide-msegui/lib/common/designutils/mseindexlookupeditor_mfm.pas create mode 100644 mseide-msegui/lib/common/designutils/mseintegerlisteditor.mfm create mode 100644 mseide-msegui/lib/common/designutils/mseintegerlisteditor.pas create mode 100644 mseide-msegui/lib/common/designutils/mseintegerlisteditor_mfm.pas create mode 100644 mseide-msegui/lib/common/designutils/mseparser.pas create mode 100644 mseide-msegui/lib/common/designutils/msepropertyeditors.pas create mode 100644 mseide-msegui/lib/common/designutils/msepropertyeditorsmodule.mfm create mode 100644 mseide-msegui/lib/common/designutils/msepropertyeditorsmodule.pas create mode 100644 mseide-msegui/lib/common/designutils/msepropertyeditorsmodule_mfm.pas create mode 100644 mseide-msegui/lib/common/designutils/msereallisteditor.mfm create mode 100644 mseide-msegui/lib/common/designutils/msereallisteditor.pas create mode 100644 mseide-msegui/lib/common/designutils/msereallisteditor_mfm.pas create mode 100644 mseide-msegui/lib/common/designutils/mseresourcetools.pas create mode 100644 mseide-msegui/lib/common/designutils/mserichstringeditor.mfm create mode 100644 mseide-msegui/lib/common/designutils/mserichstringeditor.pas create mode 100644 mseide-msegui/lib/common/designutils/mserichstringeditor_mfm.pas create mode 100644 mseide-msegui/lib/common/designutils/msesettings.mfm create mode 100644 mseide-msegui/lib/common/designutils/msesettings.pas create mode 100644 mseide-msegui/lib/common/designutils/msesettings_mfm.pas create mode 100644 mseide-msegui/lib/common/designutils/mseskindesign.pas create mode 100644 mseide-msegui/lib/common/designutils/msestringintlisteditor.mfm create mode 100644 mseide-msegui/lib/common/designutils/msestringintlisteditor.pas create mode 100644 mseide-msegui/lib/common/designutils/msestringintlisteditor_mfm.pas create mode 100644 mseide-msegui/lib/common/designutils/msestringlisteditor.mfm create mode 100644 mseide-msegui/lib/common/designutils/msestringlisteditor.pas create mode 100644 mseide-msegui/lib/common/designutils/msestringlisteditor_mfm.pas create mode 100644 mseide-msegui/lib/common/designutils/msesyntaxedit.pas create mode 100644 mseide-msegui/lib/common/designutils/msesyntaxpainter.pas create mode 100644 mseide-msegui/lib/common/designutils/msesysenvmanagereditor.mfm create mode 100644 mseide-msegui/lib/common/designutils/msesysenvmanagereditor.pas create mode 100644 mseide-msegui/lib/common/designutils/msesysenvmanagereditor_mfm.pas create mode 100644 mseide-msegui/lib/common/designutils/msetaborderoverrideeditor.mfm create mode 100644 mseide-msegui/lib/common/designutils/msetaborderoverrideeditor.pas create mode 100644 mseide-msegui/lib/common/designutils/msetaborderoverrideeditor_mfm.pas create mode 100644 mseide-msegui/lib/common/designutils/msetexteditor.mfm create mode 100644 mseide-msegui/lib/common/designutils/msetexteditor.pas create mode 100644 mseide-msegui/lib/common/designutils/msetexteditor_mfm.pas create mode 100644 mseide-msegui/lib/common/designutils/panelform.mfm create mode 100644 mseide-msegui/lib/common/designutils/panelform.pas create mode 100644 mseide-msegui/lib/common/designutils/panelform_mfm.pas create mode 100644 mseide-msegui/lib/common/dialogs/msecolordialog.mfm create mode 100644 mseide-msegui/lib/common/dialogs/msecolordialog.pas create mode 100644 mseide-msegui/lib/common/dialogs/msecolordialog_mfm.pas create mode 100644 mseide-msegui/lib/common/dialogs/msedialog.pas create mode 100644 mseide-msegui/lib/common/dialogs/msedirtree.mfm create mode 100644 mseide-msegui/lib/common/dialogs/msedirtree.pas create mode 100644 mseide-msegui/lib/common/dialogs/msedirtree_mfm.pas create mode 100644 mseide-msegui/lib/common/dialogs/msedirtreesub.mfm create mode 100644 mseide-msegui/lib/common/dialogs/msedirtreesub.pas create mode 100644 mseide-msegui/lib/common/dialogs/msedirtreesub_mfm.pas create mode 100644 mseide-msegui/lib/common/dialogs/msefiledialog.mfm create mode 100644 mseide-msegui/lib/common/dialogs/msefiledialog.pas create mode 100644 mseide-msegui/lib/common/dialogs/msefiledialog_mfm.pas create mode 100644 mseide-msegui/lib/common/dialogs/msefiledialogres.mfm create mode 100644 mseide-msegui/lib/common/dialogs/msefiledialogres.pas create mode 100644 mseide-msegui/lib/common/dialogs/msefiledialogres_mfm.pas create mode 100644 mseide-msegui/lib/common/dialogs/msefontformatdialog.mfm create mode 100644 mseide-msegui/lib/common/dialogs/msefontformatdialog.pas create mode 100644 mseide-msegui/lib/common/dialogs/msefontformatdialog_mfm.pas create mode 100644 mseide-msegui/lib/common/dialogs/mseintegerenter.mfm create mode 100644 mseide-msegui/lib/common/dialogs/mseintegerenter.pas create mode 100644 mseide-msegui/lib/common/dialogs/mseintegerenter_mfm.pas create mode 100644 mseide-msegui/lib/common/dialogs/msememodialog.mfm create mode 100644 mseide-msegui/lib/common/dialogs/msememodialog.pas create mode 100644 mseide-msegui/lib/common/dialogs/msememodialog_mfm.pas create mode 100644 mseide-msegui/lib/common/dialogs/msepopupcalendar.mfm create mode 100644 mseide-msegui/lib/common/dialogs/msepopupcalendar.pas create mode 100644 mseide-msegui/lib/common/dialogs/msepopupcalendar_mfm.pas create mode 100644 mseide-msegui/lib/common/dialogs/mserealenter.mfm create mode 100644 mseide-msegui/lib/common/dialogs/mserealenter.pas create mode 100644 mseide-msegui/lib/common/dialogs/mserealenter_mfm.pas create mode 100644 mseide-msegui/lib/common/dialogs/mseshortcutdialog.mfm create mode 100644 mseide-msegui/lib/common/dialogs/mseshortcutdialog.pas create mode 100644 mseide-msegui/lib/common/dialogs/mseshortcutdialog_mfm.pas create mode 100644 mseide-msegui/lib/common/dialogs/msestringenter.mfm create mode 100644 mseide-msegui/lib/common/dialogs/msestringenter.pas create mode 100644 mseide-msegui/lib/common/dialogs/msestringenter_mfm.pas create mode 100644 mseide-msegui/lib/common/editwidgets/msecalendardatetimeedit.pas create mode 100644 mseide-msegui/lib/common/editwidgets/msedataedits.pas create mode 100644 mseide-msegui/lib/common/editwidgets/msedataimage.pas create mode 100644 mseide-msegui/lib/common/editwidgets/msedatanodes.pas create mode 100644 mseide-msegui/lib/common/editwidgets/msedropdownlist.pas create mode 100644 mseide-msegui/lib/common/editwidgets/mseedit.pas create mode 100644 mseide-msegui/lib/common/editwidgets/msefoldedit.pas create mode 100644 mseide-msegui/lib/common/editwidgets/msegraphedits.pas create mode 100644 mseide-msegui/lib/common/editwidgets/mselistbrowser.pas create mode 100644 mseide-msegui/lib/common/editwidgets/mserealsumedit.pas create mode 100644 mseide-msegui/lib/common/editwidgets/msestringlistedit.pas create mode 100644 mseide-msegui/lib/common/editwidgets/mseterminal.pas create mode 100644 mseide-msegui/lib/common/editwidgets/msetextedit.pas create mode 100644 mseide-msegui/lib/common/editwidgets/msevaluenodes.pas create mode 100644 mseide-msegui/lib/common/editwidgets/msevaluenodesglob.pas create mode 100644 mseide-msegui/lib/common/editwidgets/msewidgetgrid.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/dbf_avl.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/dbf_collate.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/dbf_common.inc create mode 100644 mseide-msegui/lib/common/fpccompatibility/dbf_common.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/dbf_cursor.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/dbf_dbffile.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/dbf_fields.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/dbf_idxcur.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/dbf_idxfile.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/dbf_lang.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/dbf_memo.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/dbf_parser.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/dbf_pgcfile.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/dbf_pgfile.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/dbf_reg.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/dbf_str.inc create mode 100644 mseide-msegui/lib/common/fpccompatibility/dbf_str.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/dbf_str_es.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/dbf_str_fr.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/dbf_str_ita.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/dbf_str_nl.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/dbf_str_pl.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/dbf_str_pt.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/dbf_str_ru.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/dbf_struct.inc create mode 100644 mseide-msegui/lib/common/fpccompatibility/dbf_wtil.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/formatfunc.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/fpcolcnv.inc create mode 100644 mseide-msegui/lib/common/fpccompatibility/fpcolors.inc create mode 100644 mseide-msegui/lib/common/fpccompatibility/fpcompactimg.inc create mode 100644 mseide-msegui/lib/common/fpccompatibility/fphandler.inc create mode 100644 mseide-msegui/lib/common/fpccompatibility/fpimage.inc create mode 100644 mseide-msegui/lib/common/fpccompatibility/fpimage.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/fppalette.inc create mode 100644 mseide-msegui/lib/common/fpccompatibility/fpreadbmp.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/fpreadgif.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/fpreadjpeg.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/fpreadpcx.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/fpreadpng.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/fpreadpnm.pp create mode 100644 mseide-msegui/lib/common/fpccompatibility/fpreadpsd.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/fpreadtga.pp create mode 100644 mseide-msegui/lib/common/fpccompatibility/fpreadtiff.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/fpreadxpm.pp create mode 100644 mseide-msegui/lib/common/fpccompatibility/fpreadxwd.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/fptiffcmn.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/fpwritebmp.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/fpwritebmp.pp create mode 100644 mseide-msegui/lib/common/fpccompatibility/fpwritejpeg.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/fpwritepcx.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/fpwritepng.pp create mode 100644 mseide-msegui/lib/common/fpccompatibility/fpwritepnm.pp create mode 100644 mseide-msegui/lib/common/fpccompatibility/fpwritetga.pp create mode 100644 mseide-msegui/lib/common/fpccompatibility/fpwritetiff.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/fpwritexpm.pp create mode 100644 mseide-msegui/lib/common/fpccompatibility/getstrfromint.inc create mode 100644 mseide-msegui/lib/common/fpccompatibility/jcapimin_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jcapistd_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jccoefct_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jccolor_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jcdctmgr_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jchuff_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jcinit_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jcmainct_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jcmarker_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jcmaster_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jcomapi_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jconfig_del.inc create mode 100644 mseide-msegui/lib/common/fpccompatibility/jconsts_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jcparam_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jcphuff_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jcprepct_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jcsample_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jctrans_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jdapimin_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jdapistd_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jdatadst_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jdatasrc_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jdcoefct_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jdcolor_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jdct_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jddctmgr_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jdeferr_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jdhuff_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jdinput_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jdmainct_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jdmarker_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jdmaster_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jdmerge_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jdphuff_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jdpostct_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jdsample_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jdtrans_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jerror_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jfdctflt_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jfdctfst_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jfdctint_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jidct2d_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jidctasm_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jidctflt_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jidctfst_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jidctint_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jidctred_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jinclude_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jmemdos_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jmemdosa_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jmemmgr_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jmemnobs_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jmemsys_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jmorecfg_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jpeglib_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jquant1_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jquant2_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/jutils_del.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/mclasses.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/mdb.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/mdbf.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/mdbf_prscore.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/mdbf_prsdef.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/mdbf_prssupp.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/msdfdata.pas create mode 100644 mseide-msegui/lib/common/fpccompatibility/pngcomn.pp create mode 100644 mseide-msegui/lib/common/fpccompatibility/zstream.pas create mode 100644 mseide-msegui/lib/common/graphics/msebitmap.pas create mode 100644 mseide-msegui/lib/common/graphics/msedrawtext.pas create mode 100644 mseide-msegui/lib/common/graphics/mseellipsetria.pas create mode 100644 mseide-msegui/lib/common/graphics/msefcfontselect.pas create mode 100644 mseide-msegui/lib/common/graphics/msefont.pas create mode 100644 mseide-msegui/lib/common/graphics/msefontcache.pas create mode 100644 mseide-msegui/lib/common/graphics/msefontconfig.pas create mode 100644 mseide-msegui/lib/common/graphics/msefreetype.pas create mode 100644 mseide-msegui/lib/common/graphics/mseftfontcache.pas create mode 100644 mseide-msegui/lib/common/graphics/mseftglyphs.pas create mode 100644 mseide-msegui/lib/common/graphics/msegdi32gdi.pas create mode 100644 mseide-msegui/lib/common/graphics/msegdiplus.pas create mode 100644 mseide-msegui/lib/common/graphics/msegenericgdi.pas create mode 100644 mseide-msegui/lib/common/graphics/msegraphics.pas create mode 100644 mseide-msegui/lib/common/graphics/msegraphutils.pas create mode 100644 mseide-msegui/lib/common/graphics/mselinetria.pas create mode 100644 mseide-msegui/lib/common/graphics/msepolytria.pas create mode 100644 mseide-msegui/lib/common/graphics/msetriaglob.pas create mode 100644 mseide-msegui/lib/common/graphics/msex11gdi.pas create mode 100644 mseide-msegui/lib/common/i18n/msei18nglob.pas create mode 100644 mseide-msegui/lib/common/i18n/msei18nutils.pas create mode 100644 mseide-msegui/lib/common/i18n/mselanglink.pas create mode 100644 mseide-msegui/lib/common/i18n/msestringcontainer.pas create mode 100644 mseide-msegui/lib/common/i18n/mseucs2toru.pas create mode 100644 mseide-msegui/lib/common/ifi/mseifi.pas create mode 100644 mseide-msegui/lib/common/ifi/mseificomp.pas create mode 100644 mseide-msegui/lib/common/ifi/mseificompglob.pas create mode 100644 mseide-msegui/lib/common/ifi/mseifidbcomp.pas create mode 100644 mseide-msegui/lib/common/ifi/mseifidbgui.pas create mode 100644 mseide-msegui/lib/common/ifi/mseifidialogcomp.pas create mode 100644 mseide-msegui/lib/common/ifi/mseifids.pas create mode 100644 mseide-msegui/lib/common/ifi/mseifiendpoint.pas create mode 100644 mseide-msegui/lib/common/ifi/mseifiglob.pas create mode 100644 mseide-msegui/lib/common/ifi/mseifigui.pas create mode 100644 mseide-msegui/lib/common/ifi/mseifilink.pas create mode 100644 mseide-msegui/lib/common/ifi/msejson.pas create mode 100644 mseide-msegui/lib/common/ifi/msesockets.pas create mode 100644 mseide-msegui/lib/common/image/mseformatbmpicoread.pas create mode 100644 mseide-msegui/lib/common/image/mseformatjpgread.pas create mode 100644 mseide-msegui/lib/common/image/mseformatjpgwrite.pas create mode 100644 mseide-msegui/lib/common/image/mseformatpngread.pas create mode 100644 mseide-msegui/lib/common/image/mseformatpngwrite.pas create mode 100644 mseide-msegui/lib/common/image/mseformatpnmread.pas create mode 100644 mseide-msegui/lib/common/image/mseformattgaread.pas create mode 100644 mseide-msegui/lib/common/image/mseformattiffread.pas create mode 100644 mseide-msegui/lib/common/image/mseformattiffwrite.pas create mode 100644 mseide-msegui/lib/common/image/mseformatxpmread.pas create mode 100644 mseide-msegui/lib/common/image/msegraphicsmagick.pas create mode 100644 mseide-msegui/lib/common/image/msegraphicstream.pas create mode 100644 mseide-msegui/lib/common/image/msemagickstream.pas create mode 100644 mseide-msegui/lib/common/kernel/kernel_bmp.pas create mode 100644 mseide-msegui/lib/common/kernel/linux/cwstring.pas create mode 100644 mseide-msegui/lib/common/kernel/linux/ice.pas create mode 100644 mseide-msegui/lib/common/kernel/linux/mseguiintf.pas create mode 100644 mseide-msegui/lib/common/kernel/linux/msenoguiintf.pas create mode 100644 mseide-msegui/lib/common/kernel/linux/mseprocmonitor.pas create mode 100644 mseide-msegui/lib/common/kernel/linux/msesetlocale.pas create mode 100644 mseide-msegui/lib/common/kernel/linux/msesocketintf.pas create mode 100644 mseide-msegui/lib/common/kernel/linux/msesysintf.pas create mode 100644 mseide-msegui/lib/common/kernel/linux/msesysintf1.pas create mode 100644 mseide-msegui/lib/common/kernel/linux/mseuniintf.pas create mode 100644 mseide-msegui/lib/common/kernel/linux/mxft.pas create mode 100644 mseide-msegui/lib/common/kernel/linux/mxrandr.pas create mode 100644 mseide-msegui/lib/common/kernel/linux/mxrender.pas create mode 100644 mseide-msegui/lib/common/kernel/linux/sm.pas create mode 100644 mseide-msegui/lib/common/kernel/mseact.pas create mode 100644 mseide-msegui/lib/common/kernel/mseactions.pas create mode 100644 mseide-msegui/lib/common/kernel/mseapplication.pas create mode 100644 mseide-msegui/lib/common/kernel/msearrayprops.pas create mode 100644 mseide-msegui/lib/common/kernel/msearrayutils.pas create mode 100644 mseide-msegui/lib/common/kernel/mseassistiveclient.pas create mode 100644 mseide-msegui/lib/common/kernel/mseassistiveserver.pas create mode 100644 mseide-msegui/lib/common/kernel/msebintree.pas create mode 100644 mseide-msegui/lib/common/kernel/msebits.pas create mode 100644 mseide-msegui/lib/common/kernel/msebucketlist.pas create mode 100644 mseide-msegui/lib/common/kernel/mseclasses.pas create mode 100644 mseide-msegui/lib/common/kernel/mseconsts.pas create mode 100644 mseide-msegui/lib/common/kernel/mseconsts_de.pas create mode 100644 mseide-msegui/lib/common/kernel/mseconsts_es.pas create mode 100644 mseide-msegui/lib/common/kernel/mseconsts_fr.pas create mode 100644 mseide-msegui/lib/common/kernel/mseconsts_id.pas create mode 100644 mseide-msegui/lib/common/kernel/mseconsts_ru.pas create mode 100644 mseide-msegui/lib/common/kernel/mseconsts_uzcyr.pas create mode 100644 mseide-msegui/lib/common/kernel/mseconsts_zh.pas create mode 100644 mseide-msegui/lib/common/kernel/msectypes.pas create mode 100644 mseide-msegui/lib/common/kernel/msedatamodules.pas create mode 100644 mseide-msegui/lib/common/kernel/msedate.pas create mode 100644 mseide-msegui/lib/common/kernel/msedrag.pas create mode 100644 mseide-msegui/lib/common/kernel/msedynload.pas create mode 100644 mseide-msegui/lib/common/kernel/mseerr.pas create mode 100644 mseide-msegui/lib/common/kernel/mseevent.pas create mode 100644 mseide-msegui/lib/common/kernel/msefileutils.pas create mode 100644 mseide-msegui/lib/common/kernel/msefloattostr.pas create mode 100644 mseide-msegui/lib/common/kernel/mseformatstr.pas create mode 100644 mseide-msegui/lib/common/kernel/mseglob.pas create mode 100644 mseide-msegui/lib/common/kernel/msegui.pas create mode 100644 mseide-msegui/lib/common/kernel/mseguiglob.pas create mode 100644 mseide-msegui/lib/common/kernel/mseguiinifini.pas create mode 100644 mseide-msegui/lib/common/kernel/mseguiintf.inc create mode 100644 mseide-msegui/lib/common/kernel/mseguithreadcomp.pas create mode 100644 mseide-msegui/lib/common/kernel/mseinterfaces.pas create mode 100644 mseide-msegui/lib/common/kernel/msekeyboard.pas create mode 100644 mseide-msegui/lib/common/kernel/mselibc.pas create mode 100644 mseide-msegui/lib/common/kernel/msemacros.pas create mode 100644 mseide-msegui/lib/common/kernel/msemenus.pas create mode 100644 mseide-msegui/lib/common/kernel/msenogui.pas create mode 100644 mseide-msegui/lib/common/kernel/msenoguiintf.inc create mode 100644 mseide-msegui/lib/common/kernel/mseobjecttext.pas create mode 100644 mseide-msegui/lib/common/kernel/msepipestream.pas create mode 100644 mseide-msegui/lib/common/kernel/msepointer.pas create mode 100644 mseide-msegui/lib/common/kernel/mseprocmonitor.inc create mode 100644 mseide-msegui/lib/common/kernel/msereal.pas create mode 100644 mseide-msegui/lib/common/kernel/mserichstring.pas create mode 100644 mseide-msegui/lib/common/kernel/mserttistat.pas create mode 100644 mseide-msegui/lib/common/kernel/msescrollbar.pas create mode 100644 mseide-msegui/lib/common/kernel/mseshapes.pas create mode 100644 mseide-msegui/lib/common/kernel/mseskin.pas create mode 100644 mseide-msegui/lib/common/kernel/msesocketintf.inc create mode 100644 mseide-msegui/lib/common/kernel/msesonames.pas create mode 100644 mseide-msegui/lib/common/kernel/msestat.pas create mode 100644 mseide-msegui/lib/common/kernel/msestatfile.pas create mode 100644 mseide-msegui/lib/common/kernel/msestockobjects.mfm create mode 100644 mseide-msegui/lib/common/kernel/msestockobjects.pas create mode 100644 mseide-msegui/lib/common/kernel/msestockobjects_mfm.pas create mode 100644 mseide-msegui/lib/common/kernel/msestream.pas create mode 100644 mseide-msegui/lib/common/kernel/msestreaming.pas create mode 100644 mseide-msegui/lib/common/kernel/msestrings.pas create mode 100644 mseide-msegui/lib/common/kernel/msesys.pas create mode 100644 mseide-msegui/lib/common/kernel/msesysintf.inc create mode 100644 mseide-msegui/lib/common/kernel/msesysintf1.inc create mode 100644 mseide-msegui/lib/common/kernel/msesystypes.pas create mode 100644 mseide-msegui/lib/common/kernel/msesysutils.pas create mode 100644 mseide-msegui/lib/common/kernel/msethread.pas create mode 100644 mseide-msegui/lib/common/kernel/msethreadcomp.pas create mode 100644 mseide-msegui/lib/common/kernel/msetimer.pas create mode 100644 mseide-msegui/lib/common/kernel/msetmpmodules.pas create mode 100644 mseide-msegui/lib/common/kernel/msetypes.pas create mode 100644 mseide-msegui/lib/common/kernel/mseunicodeps.pas create mode 100644 mseide-msegui/lib/common/kernel/mseuniintf.inc create mode 100644 mseide-msegui/lib/common/kernel/msevariants.pas create mode 100644 mseide-msegui/lib/common/kernel/windows/mseguiintf.pas create mode 100644 mseide-msegui/lib/common/kernel/windows/msenoguiintf.pas create mode 100644 mseide-msegui/lib/common/kernel/windows/mseprocmonitor.pas create mode 100644 mseide-msegui/lib/common/kernel/windows/msesocketintf.pas create mode 100644 mseide-msegui/lib/common/kernel/windows/msesysintf.pas create mode 100644 mseide-msegui/lib/common/kernel/windows/msesysintf1.pas create mode 100644 mseide-msegui/lib/common/kernel/windows/msesystimer.pas create mode 100644 mseide-msegui/lib/common/kernel/windows/mseuniintf.pas create mode 100644 mseide-msegui/lib/common/kernel/windows/msewindnd.pas create mode 100644 mseide-msegui/lib/common/kernel/windows/msewinglob.pas create mode 100644 mseide-msegui/lib/common/math/msefft.pas create mode 100644 mseide-msegui/lib/common/math/msefftw.pas create mode 100644 mseide-msegui/lib/common/math/msefilter.pas create mode 100644 mseide-msegui/lib/common/math/mselfsr.pas create mode 100644 mseide-msegui/lib/common/math/msenoise.pas create mode 100644 mseide-msegui/lib/common/math/msesigaudio.pas create mode 100644 mseide-msegui/lib/common/math/msesigfft.pas create mode 100644 mseide-msegui/lib/common/math/msesigfftgui.pas create mode 100644 mseide-msegui/lib/common/math/msesiggui.pas create mode 100644 mseide-msegui/lib/common/math/msesigmidi.pas create mode 100644 mseide-msegui/lib/common/math/msesignal.pas create mode 100644 mseide-msegui/lib/common/math/msesignoise.pas create mode 100644 mseide-msegui/lib/common/opengl/mseftgl.pas create mode 100644 mseide-msegui/lib/common/opengl/msegl.pas create mode 100644 mseide-msegui/lib/common/opengl/mseglext.pas create mode 100644 mseide-msegui/lib/common/opengl/mseglextglob.pas create mode 100644 mseide-msegui/lib/common/opengl/mseglu.pas create mode 100644 mseide-msegui/lib/common/opengl/mseglx.pas create mode 100644 mseide-msegui/lib/common/opengl/mseopengl.pas create mode 100644 mseide-msegui/lib/common/opengl/mseopenglcanvaswidget.pas create mode 100644 mseide-msegui/lib/common/opengl/mseopenglgdi.pas create mode 100644 mseide-msegui/lib/common/opengl/mseopenglgdiinit.pas create mode 100644 mseide-msegui/lib/common/opengl/mseopenglwidget.pas create mode 100644 mseide-msegui/lib/common/pascalscript/msepascalscript.pas create mode 100644 mseide-msegui/lib/common/pascalscript/msepascimport.pas create mode 100644 mseide-msegui/lib/common/pascalscript/msepascimportmsegui.pas create mode 100644 mseide-msegui/lib/common/printer/msegdiprint.pas create mode 100644 mseide-msegui/lib/common/printer/msepostscriptprinter.pas create mode 100644 mseide-msegui/lib/common/printer/mseprinter.pas create mode 100644 mseide-msegui/lib/common/regcomponents/designer_bmp.pas create mode 100644 mseide-msegui/lib/common/regcomponents/regcrypto.pas create mode 100644 mseide-msegui/lib/common/regcomponents/regcrypto_bmp.pas create mode 100644 mseide-msegui/lib/common/regcomponents/regdb.pas create mode 100644 mseide-msegui/lib/common/regcomponents/regdb_bmp.pas create mode 100644 mseide-msegui/lib/common/regcomponents/regdeprecated.pas create mode 100644 mseide-msegui/lib/common/regcomponents/regdeprecated_bmp.pas create mode 100644 mseide-msegui/lib/common/regcomponents/regdesignutils.pas create mode 100644 mseide-msegui/lib/common/regcomponents/regdesignutils_bmp.pas create mode 100644 mseide-msegui/lib/common/regcomponents/regdialogs.pas create mode 100644 mseide-msegui/lib/common/regcomponents/regdialogs_bmp.pas create mode 100644 mseide-msegui/lib/common/regcomponents/regeditwidgets.pas create mode 100644 mseide-msegui/lib/common/regcomponents/regeditwidgets_bmp.pas create mode 100644 mseide-msegui/lib/common/regcomponents/regexperimental.pas create mode 100644 mseide-msegui/lib/common/regcomponents/regglob.pas create mode 100644 mseide-msegui/lib/common/regcomponents/regifi.pas create mode 100644 mseide-msegui/lib/common/regcomponents/regifi_bmp.pas create mode 100644 mseide-msegui/lib/common/regcomponents/regifirem.pas create mode 100644 mseide-msegui/lib/common/regcomponents/regifirem_bmp.pas create mode 100644 mseide-msegui/lib/common/regcomponents/regkernel.pas create mode 100644 mseide-msegui/lib/common/regcomponents/regkernel_bmp.pas create mode 100644 mseide-msegui/lib/common/regcomponents/regmath.pas create mode 100644 mseide-msegui/lib/common/regcomponents/regmath_bmp.pas create mode 100644 mseide-msegui/lib/common/regcomponents/regmm.pas create mode 100644 mseide-msegui/lib/common/regcomponents/regpascalscript.pas create mode 100644 mseide-msegui/lib/common/regcomponents/regprinter.pas create mode 100644 mseide-msegui/lib/common/regcomponents/regreport.pas create mode 100644 mseide-msegui/lib/common/regcomponents/regreport_bmp.pas create mode 100644 mseide-msegui/lib/common/regcomponents/regserialcomm.pas create mode 100644 mseide-msegui/lib/common/regcomponents/regserialcomm_bmp.pas create mode 100644 mseide-msegui/lib/common/regcomponents/regsysutils.pas create mode 100644 mseide-msegui/lib/common/regcomponents/regsysutils_bmp.pas create mode 100644 mseide-msegui/lib/common/regcomponents/regunitgroups.pas create mode 100644 mseide-msegui/lib/common/regcomponents/regwidgets.pas create mode 100644 mseide-msegui/lib/common/regcomponents/regwidgets_bmp.pas create mode 100644 mseide-msegui/lib/common/regcomponents/regzeoslib.pas create mode 100644 mseide-msegui/lib/common/regcomponents/regzeoslib_bmp.pas create mode 100644 mseide-msegui/lib/common/report/mselatex.pas create mode 100644 mseide-msegui/lib/common/report/msereport.pas create mode 100644 mseide-msegui/lib/common/report/mserepps.pas create mode 100644 mseide-msegui/lib/common/serialcomm/msecommport.pas create mode 100644 mseide-msegui/lib/common/serialcomm/msecommtimer.pas create mode 100644 mseide-msegui/lib/common/serialcomm/msecommutils.pas create mode 100644 mseide-msegui/lib/common/serialcomm/msesercomm.pas create mode 100644 mseide-msegui/lib/common/sysutils/msedbus.pas create mode 100644 mseide-msegui/lib/common/sysutils/msedbusinterface.pas create mode 100644 mseide-msegui/lib/common/sysutils/mseenvmacros.pas create mode 100644 mseide-msegui/lib/common/sysutils/mseexecmacros.pas create mode 100644 mseide-msegui/lib/common/sysutils/msefilechange.pas create mode 100644 mseide-msegui/lib/common/sysutils/msefilemacros.pas create mode 100644 mseide-msegui/lib/common/sysutils/mseguiprocess.pas create mode 100644 mseide-msegui/lib/common/sysutils/mseinputcontroller.pas create mode 100644 mseide-msegui/lib/common/sysutils/msemacmacros.pas create mode 100644 mseide-msegui/lib/common/sysutils/msemime.pas create mode 100644 mseide-msegui/lib/common/sysutils/mseprocess.pas create mode 100644 mseide-msegui/lib/common/sysutils/mseprocmonitorcomp.pas create mode 100644 mseide-msegui/lib/common/sysutils/mseprocutils.pas create mode 100644 mseide-msegui/lib/common/sysutils/msepython.pas create mode 100644 mseide-msegui/lib/common/sysutils/msestatusnotifieritem.pas create mode 100644 mseide-msegui/lib/common/sysutils/msestatussnotifieritem.pas create mode 100644 mseide-msegui/lib/common/sysutils/msestrmacros.pas create mode 100644 mseide-msegui/lib/common/sysutils/msesysdnd.pas create mode 100644 mseide-msegui/lib/common/sysutils/msesysenv.pas create mode 100644 mseide-msegui/lib/common/unicode/mseunicode.pas create mode 100644 mseide-msegui/lib/common/widgets/msebarcode.pas create mode 100644 mseide-msegui/lib/common/widgets/msechart.pas create mode 100644 mseide-msegui/lib/common/widgets/msechartedit.pas create mode 100644 mseide-msegui/lib/common/widgets/msedial.pas create mode 100644 mseide-msegui/lib/common/widgets/msedispwidgets.pas create mode 100644 mseide-msegui/lib/common/widgets/msedock.pas create mode 100644 mseide-msegui/lib/common/widgets/msedockpanelform.pas create mode 100644 mseide-msegui/lib/common/widgets/msedragglob.pas create mode 100644 mseide-msegui/lib/common/widgets/mseeditglob.pas create mode 100644 mseide-msegui/lib/common/widgets/mseforms.pas create mode 100644 mseide-msegui/lib/common/widgets/msegrids.pas create mode 100644 mseide-msegui/lib/common/widgets/msegridsglob.pas create mode 100644 mseide-msegui/lib/common/widgets/mseguirttistat.pas create mode 100644 mseide-msegui/lib/common/widgets/mseimage.pas create mode 100644 mseide-msegui/lib/common/widgets/mseinplaceedit.pas create mode 100644 mseide-msegui/lib/common/widgets/msemenuwidgets.pas create mode 100644 mseide-msegui/lib/common/widgets/mseobjectpicker.pas create mode 100644 mseide-msegui/lib/common/widgets/msepickwidget.pas create mode 100644 mseide-msegui/lib/common/widgets/msepolygon.pas create mode 100644 mseide-msegui/lib/common/widgets/msesimplewidgets.pas create mode 100644 mseide-msegui/lib/common/widgets/msesizingform.pas create mode 100644 mseide-msegui/lib/common/widgets/msesplitter.pas create mode 100644 mseide-msegui/lib/common/widgets/msetabs.pas create mode 100644 mseide-msegui/lib/common/widgets/msetabsglob.pas create mode 100644 mseide-msegui/lib/common/widgets/msetoolbar.pas create mode 100644 mseide-msegui/lib/common/widgets/msetraywidget.pas create mode 100644 mseide-msegui/lib/common/widgets/msewidgets.pas create mode 100644 mseide-msegui/lib/common/widgets/msewindowwidget.pas create mode 100644 mseide-msegui/msegui.svg create mode 100644 mseide-msegui/msegui_24.png create mode 100644 mseide-msegui/msegui_32.png create mode 100644 mseide-msegui/msegui_48.png create mode 100644 mseide-msegui/msegui_64.png create mode 100644 mseide-msegui/tools/bmp2pas.pas create mode 100644 mseide-msegui/tools/bmp2pas.prj create mode 100644 mseide-msegui/tools/data2pas.pas create mode 100644 mseide-msegui/tools/data2pas.prj create mode 100755 mseide-msegui/tools/dist/copybin.sh create mode 100644 mseide-msegui/tools/dist/makdist.mrp create mode 100644 mseide-msegui/tools/dist/makeallfp.sh create mode 100755 mseide-msegui/tools/dist/runmake.sh create mode 100644 mseide-msegui/tools/doc/README.TXT create mode 100644 mseide-msegui/tools/form2pas.pas create mode 100644 mseide-msegui/tools/form2pas.prj create mode 100644 mseide-msegui/tools/i18n/main.mfm create mode 100644 mseide-msegui/tools/i18n/main.pas create mode 100644 mseide-msegui/tools/i18n/main_mfm.pas create mode 100644 mseide-msegui/tools/i18n/messagesform.mfm create mode 100644 mseide-msegui/tools/i18n/messagesform.pas create mode 100644 mseide-msegui/tools/i18n/messagesform_mfm.pas create mode 100644 mseide-msegui/tools/i18n/msei18n.ico create mode 100644 mseide-msegui/tools/i18n/msei18n.pas create mode 100644 mseide-msegui/tools/i18n/msei18n.prj create mode 100644 mseide-msegui/tools/i18n/msei18n.rc create mode 100644 mseide-msegui/tools/i18n/msei18n.res create mode 100644 mseide-msegui/tools/i18n/msei18n.svg create mode 100644 mseide-msegui/tools/i18n/msei18n_24.png create mode 100644 mseide-msegui/tools/i18n/msei18n_32.png create mode 100644 mseide-msegui/tools/i18n/msei18n_48.png create mode 100644 mseide-msegui/tools/i18n/msei18n_64.png create mode 100644 mseide-msegui/tools/i18n/mseresourceparser.pas create mode 100644 mseide-msegui/tools/i18n/project.mfm create mode 100644 mseide-msegui/tools/i18n/project.pas create mode 100644 mseide-msegui/tools/i18n/project_mfm.pas create mode 100644 mseide-msegui/tools/msedirclear.cmd create mode 100755 mseide-msegui/tools/msedirclear.sh create mode 100644 mseide-msegui/tools/unitdep/main.mfm create mode 100644 mseide-msegui/tools/unitdep/main.pas create mode 100644 mseide-msegui/tools/unitdep/main_mfm.pas create mode 100644 mseide-msegui/tools/unitdep/mseunitdep.pas create mode 100644 mseide-msegui/tools/unitdep/mseunitdep.prj create mode 100644 mseide-msegui/tools/valgrind/fixes_3_0.supp create mode 100644 mseide-msegui/tools/valgrind/fixes_3_0_64.supp create mode 100644 mseide-msegui/tools/xft2gs/README.TXT diff --git a/mseide-msegui/.gitignore b/mseide-msegui/.gitignore new file mode 100644 index 0000000..7c3dae9 --- /dev/null +++ b/mseide-msegui/.gitignore @@ -0,0 +1,9 @@ +*.o +*.ppu +*.dcu +*.~* +*.a +*.bak +*.bak? +*.rst +*.rsj \ No newline at end of file diff --git a/mseide-msegui/COPYING.GPL b/mseide-msegui/COPYING.GPL new file mode 100644 index 0000000..5b6e7c6 --- /dev/null +++ b/mseide-msegui/COPYING.GPL @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/mseide-msegui/COPYING.LGPL b/mseide-msegui/COPYING.LGPL new file mode 100644 index 0000000..b1e3f5a --- /dev/null +++ b/mseide-msegui/COPYING.LGPL @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/mseide-msegui/COPYING.MSE b/mseide-msegui/COPYING.MSE new file mode 100644 index 0000000..e2eff9b --- /dev/null +++ b/mseide-msegui/COPYING.MSE @@ -0,0 +1,23 @@ +This is the file COPYING.MSE, it applies to the MSEgui Library. + +The source code of the MSEgui Library is +distributed under the Library GNU General Public License +(see the file COPYING) with the following modification: + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent modules, +and to copy and distribute the resulting executable under terms of your choice, +provided that you also meet, for each linked independent module, the terms +and conditions of the license of that module. An independent module is a module +which is not derived from or based on this library. If you modify this +library, you may extend this exception to your version of the library, but you are +not obligated to do so. If you do not wish to do so, delete this exception +statement from your version. + +If you didn't receive a copy of the file COPYING, contact: + Free Software Foundation + 675 Mass Ave + Cambridge, MA 02139 + USA + diff --git a/mseide-msegui/DEBUG.TXT b/mseide-msegui/DEBUG.TXT new file mode 100644 index 0000000..bc5bb86 --- /dev/null +++ b/mseide-msegui/DEBUG.TXT @@ -0,0 +1,42 @@ +MSEide debugging +**************** +Breakpoints don't work on win32 in units compiled with -CX +(create smartlinked units). It is recommended to use mingw gdb 6.8+ on win32. +String and dynamic array variables of units compiled with +-gv (Valgrind debug info) are displayed incorrect. +gdb 6.5 has bugs with threads and forking on linux. Please update to gdb 6.6+. +FPC 2.2+ projects must be compiled with -O- (no optimization) for debugging. + +Tips from IvankoB: +------------------ + +In win-32, when debugging MSEide as a slave project run within master +MSEide, there're possible +uncontrollable breakpoints on pressing the F12 key (in MSEide, this key +toggles design/code view +for form, datamodules and reports). These breakpoints are caused by the +win-32 internal debug +facilities activated by the F12 key too. To release this key for MSEide, +there's a solution: + +- run the REGEDIT.exe + +- set   +"HKLM\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\AeDebug\UserDebuggerHotKey" +to 0x2F +(it's the scancode of VK_HELP which is not present on most PC keyboards ) + +- reboot + +In win-32, WRITELN called from within a program won't be printed in the IDE +internal console (because of some STDIO flushing issues on pipes) +unless the below code is inserted at beginning of the startup file +of the program: + +{$ifdef mswindows} +     TextRec(Output).FlushFunc:= TextRec(Output).InOutFunc; +{$endif} + +Also, You should place {$apptype console} compiler directive at beginning +of each unit calling WRITELN otherwise You may either encounter "File not +found" exception or to see silent nothing. \ No newline at end of file diff --git a/mseide-msegui/README.TXT b/mseide-msegui/README.TXT new file mode 100644 index 0000000..1ed363a --- /dev/null +++ b/mseide-msegui/README.TXT @@ -0,0 +1,390 @@ +MSEide+MSEgui Pascal Cross Platform GUI Development System. + +2018-11-03 Version 4.6.2 +Copyright (c) 1999-2018 by Martin Schreiber + +- Compiles with FPC 3.0.2 or 3.0.4 +- For FreeBSD-x86_64, Linux-i386, Linux-x86_64, Linux-arm(Raspberry Pi), + Windows-i386, Windows-x86_64. +- Links to xlib and gdi32, no external widget library needed. +- Internal character encoding is utf-16. +- Uses anti aliased fonts on Linux (Xft). +- All screen drawing is double buffered. +- Has docking forms and MDI. +- Has embedded forms (similar to TFrame). +- Has sophisticated database access components and data edit widgets. +- Internationalization functionality with resource modules. +- Report generator. + +IDE: +- Integrated debugging. +- Source code highlighting. +- Source code navigation with support for include files. +- Code completion for classes. +- Integrated visual form designer with source code update for components and + events. +- Flexible and handy build system with switchable macros. +- Visual form inheritance. +- Integrated report designer. + +License: +IDE and tools are under GPL, library under modified LGPL like FPC-RTL. +Package maintainers may delete the files "apps/ide/COPYING.GPL", +"lib/common/COPYING.LGPL" and "lib/common/COPYING.MSE". + +Installation: +************* +1. Download and install FPC 3.0.2 or 3.0.4, you can get it from + https://www.freepascal.org/download.var +2. Download mseide_msegui_src_4_6_2.zip and the mseide_* archive + for your system. + https://sourceforge.net/projects/mseide-msegui/files/mseide-msegui/4.6.2/ +3. Extract them to a directory of your choice ('yourdirectory') . +4. Run 'yourdirectory/bin/mseide' on Linux and FreeBSD or + 'yourdirectory\bin\mseide.exe' on windows. +5. In 'Settings'-'Configure MSEide'-'${MSEDIR}' select 'yourdirectory/msegui'. +6. In 'Project'-'Open' select 'yourdirectory/msegui/apps/demo/demo.prj'. +7. 'Target'-'Continue'. + +If you get the error "/usr/bin/ld: cannot find -lX11" install the +libX11-devel or libX11-dev package or make a symbolic link +/usr/lib/libX11.so -> /usr/lib/libX11.so.6 +see +https://bugs.freepascal.org/view.php?id=32367 + +If you wish to to compile the IDE: + +1. In 'Project'-'Open' select 'yourdirectory/msegui/apps/ide/mseide.prj'. +2. 'Target'-'Continue'. + +Compiling MSEide from commandline on Linux and FreeBSD: +fpc -Fulib/common/* -Fulib/common/kernel/linux apps/ide/mseide.pas +On Windows: +fpc -Fulib\common\* -Fulib\common\kernel\windows apps\ide\mseide.pas + +If FPC crashes while compiling try on Linux and FreeBSD: +fpc -B -Fulib/common/* -Fulib/common/kernel/linux apps/ide/mseide.pas +On Windows: +fpc -B -Fulib\common\* -Fulib\common\kernel\windows apps\ide\mseide.pas + +Creating a new GUI project +************************** +'Project'-'New'-'From Template', select "default.prj" + +Creating a new console project +****************************** +'Project'-'New'-'From Template', select "console.prj" + +MSEgui command line parameters +****************************** +--FONTALIAS=,[,[,[,[,] + [,]]]] + Change the used fonts. Example for a 16 pixel height default font: + --FONTALIAS=stf_default,,16 + +--NOZEROLINES + Use 1-width lines instead of 0-width lines. X11 only. Workaround for buggy HW-accelerated + X-servers which don't draw lineends exactly. Can degrade performance, see + https://bugzilla.opensuse.org/show_bug.cgi?id=1021803 + +--NOZORDERHANDLING + Do not touch Z-order of the windows. + +--NORESTACKWINDOW + Do not use the NET_RESTACK_WINDOW protocol. + +--RESTACKWINDOW + Use the NET_RESTACK_WINDOW protocol. + +--NORECONFIGUREWMWINDOW + Do not use xreconfigurewmwindow() for window stacking operation. + +--RECONFIGUREWMWINDOW + Use xreconfigurewmwindow() for window stacking operation. + +--STACKMODEBELOWWORKAROUND + Necessary for windowmanagers with buggy xreconfigurewmwindow() handling. + +--NOSTACKMODEBELOWWORKAROUND + No workaround. + +--TOPLEVELRAISE + Use the top level frame window id instead of the application client window id + for window raise operation. Implies --NORESTACKWINDOW and + --NORECONFIGUREWMWINDOW. + +--NOSTATICGRAVITY + Simulates staticgravity for buggy window managers. + +MSEide command line parameters +****************************** +-np + Do not load a project. + +-ns + Do not use a skin, no fades. + +--globstatfile= + Use instead the default global MSEide status file. + +--macrogroup= + Use 'Project'-'Options'-'Macros'-'Active group' number , = 1..6. + +--macrodef=,{,,} + Macro definition, will be overridden by 'Project'-'Options'-'Macros'. Example: + --macrodef=MAC1,abc,MAC2,def + defines ${MAC1} with value 'abc' and ${MAC2} with value 'def'. +--storeglobalmacros + Store --macrodef defines as global 'Settings'-'Configure MSEide' macros and + terminate MSEide. + +MSEide environment variables +**************************** +Macros in 'Settings'-'Configure MSEide' can be overridden by environment +variables. They will be overriden by --macrodef and 'Project'-'Options'-'Macros'. +Possible names: +FPCDIR, FPCLIBDIR, MSEDIR, MSELIBDIR, SYNTAXDEFDIR, TEMPLATEDIR, +COMPSTOREDIR, COMPILER, DEBUGGER, EXEEXT, TARGET, TARGETOSDIR. + +MSEide project macros +********************* +Predefined project macros: +PROJECTNAME, PROJECTDIR, MAINFILE, TARGETFILE, +TARGETENV (in format for "env" unix command), TARGETPARAMS, +they can be overridden by 'Project'-'Options'-'Macros'. + +MSEide macro functions +********************** +${MAC_IFDEF(macroname)} returns the macro value if defined. +${MAC_IFDEF(macroname,notdefinedvalue)} returns the macro value if defined, + notdefinedvalue otherwise. +${MAC_IFDEF(macroname,notdefinedvalue,definedvalue)} + returns definedvalue if macroname is defined, notdefinedvalue otherwise. + +MSEide environment macros +************************* +${ENV_VAR(variablename)} returns the variable value if defined. +${ENV_VAR(variablename,notdefinedvalue)} returns the variable value if defined, + notdefinedvalue otherwise. +${ENV_VAR(variablename,notdefinedvalue,definedvalue)} + returns definedvalue if variablename is defined, notdefinedvalue otherwise. + +MSEide string macros +******************** +Macro format is ${STR_*(text)}. +STR_TRIM + Trim whitespace from the ends of text. +STR_TRIMLEFT + Trim whitespace from the beginning of text. +STR_TRIMRIGHT + Trim whitespace from the end of text. + +STR_COALESCE + Return first not empty value. Format is + ${STR_COALESCE(text[,text...])} or + ${STR_COALESCE("text"[,"text"...])} + +MSEide file macros +****************** +Macro format is ${FILE_*(fileparameter)} or ${FILE_*("fileparameter")}. +FILE_MSE convert to MSE format. +FILE_SYS convert to sys format. +FILE_PATH absolute path. +FILE_FILE no trailing path delimiter. +FILE_DIR trailing path delimiter. +FILE_NAME no directory part. +FILE_NAMEBASE no directory and no name extension part. +FILE_EXT file name extension. +FILE_NONAME directory part only. +FILE_NOEXT no file name extension. + +MSEide exec macros +****************** +${EXEC_OUT(commandline[,timeoutms])} + Executes commandline, returns the process output. Timeout in + milli seconds, default = 1000, -1 = infinite. + +MSEide macros in 'Project'-'Options'-'Debugger'-'xterm Command' +*************************************************************** +${PTS} expands to tty pts path. +${PTSN} expands to tty pts number. +${PTSH} expands to tty pts handle. +Entering an empty string restores the default. + +MSEide external tools parameters macros +*************************************** +Predefined macros in 'Project'-'Options'-'Tools'-'Parameters': +CURSOURCEFILE current source file. +CURMODULEFILE current *.mfm file. +CURSSELECTION selected text in source editor. +CURSWORD word at cursor in source editor +CURSDEFINITION} definition of the current token at cursor + (Ctrl+LClick destination), needs activated P-column + (Parse source before call) to be current. +CURCOMPONENTCLASS current selected component class in form editor. +CURPROPERTY current selected property in object inspector. + +Antialiased text with MSEgui 32 bit on 64 bit Linux +**************************************************** +MSEgui uses Xft for antialiased fonts on Linux. Please install lib32-libxft +package if necessary. + +Popup widgets behind the forms +****************************** +If the popup widgets are showed behind the forms, try to start the +MSEgui program with the option '--TOPLEVELRAISE'. Do *not* use this option +if is not necessary (KDE, Gnome... work well without). + +Display problems with Linux radeon and other EXA drivers +******************************************************** +If the display is distorted or slow add +Option "EXAPixmaps" "off" +to +Section "Device" +of xorg.conf, see +https://bugs.freedesktop.org/show_bug.cgi?id=69543 +https://bugs.freedesktop.org/show_bug.cgi?id=84253 +or use the proprietary video driver for your video chip. + +Flashing taskbar widgets in IceWM +********************************* +Newer revisions of IceWM let the taskbar icons of MSEgui applications flash. +Start the MSEgui application with the option '--TOPLEVELRAISE'. + +Invalid inputmanager for Ubuntu +******************************* +The utf-8 setup in Ubuntu seems to be incomplete. If you get the exception +"egui : Invalid inputmanager tinternalapplication ." at program start, try to +replace your language locale in /usr/share/X11/locale/locale.dir +by en_US as a workaround. Example for ru_RU.UTF-8: +replace +ru_RU.UTF-8/XLC_LOCALE ru_RU.UTF-8 +by +en_US.UTF-8/XLC_LOCALE ru_RU.UTF-8 + +Wrong window positions for Ubuntu 14.04 +*************************************** +Window positions in Unity are wrong because the Ubuntu windowmanager +does not support static_gravity: +http://askubuntu.com/questions/451903/wingravity-static-gravity-not-suppo +https://bugs.launchpad.net/ubuntu/+bug/1312044 +http://askubuntu.com/questions/457456/wingravity-static-gravity-not-supported-in-14-04 + +How to add custom components to MSEide +************************************** +There is a project 'apps/myide/mymseide.prj' as a demo. +Start MSEide, open project 'apps/myide/mymseide.prj', 'Project'-'Build', +'Target'-'Continue', +the IDE with the new component 'tmybutton' will be compiled and +started in the the debugger. +Binary name is 'mymseide' (linux) or 'mymseide.exe' (win32). + +If you wish to do it from scratch: + +- Create a register unit for your components + (see 'apps/myide/regmycomps.pas' for an example). +- Enter the unitname followed by a comma + ('myregunit,' if your regunitfile is 'myregunit.pas') in + a file named 'regcomponents.inc'. +- Build the IDE with -dmorecomponents as option. + +Component units integrated by this mechanism don't need to be GPL, see +apps/ide/COPYING.IDE + +If you want to add custom icons to your components: + +- Convert 24*24 pixel BMP or PNG files with tools/bmp2pas to + an icon unit ('*_bmp.pas'). +- Add the name of the icon unit to 'uses' in your register unit. + +How to run i18ndemo +******************* +- Start MSEide. +- 'Project'-'Open'-'yourdirectory/msegui/apps/i18ndemo/i18ndemo.prj'. +- 'Project'-'Make' to create the rsj files. +- 'Project'-'Open'-'yourdirectory/msegui/tools/i18n/msei18n.prj'. +- 'Target'-'Continue'. +In MSEi18n: + - Adjust 'Settings'-'Configure MSEi18n'-'${MSEDIR}' and ${COMPILER}. + - 'Open'-'yourdirectory/msegui/apps/i18ndemo/i18ndemo.trp' + - 'Make'. + - Close message window. + - Close MSEi18n. +- 'Project'-'Open'-'yourdirectory/msegui/apps/i18ndemo/i18ndemo.prj'. +- 'Target'-'Continue'. + +SQLite +****** +tsqlite3connection field type mapping: + + Type name SQLite storage class Field type Data type ++--------------------+---------------------+-------------+-------------+ +| INTEGER or INT | INTEGER 4 | ftinteger | integer | +| LARGEINT | INTEGER 8 | ftlargeint | largeint | +| BIGINT | INTEGER 8 | ftlargeint | largeint | +| WORD | INTEGER 2 | ftword | word | +| SMALLINT | INTEGER 2 | ftsmallint | smallint | +| BOOLEAN | INTEGER 2 | ftboolean | wordbool | +| FLOAT[...] or REAL | REAL | ftfloat | double | +| or DOUBLE[...] | | | | +| CURRENCY | REAL | ftcurrency | double! | +| DATETIME or | REAL | ftdatetime | tdatetime | +| TIMESTAMP | | | | +| DATE | REAL | ftdate | tdatetime | +| TIME | REAL | fttime | tdatetime | +| NUMERIC[...] | INTEGER 8 (*10'000) | ftbcd | currency | +| VARCHAR[(n)] | TEXT | ftstring | msestring | +| TEXT | TEXT | ftmemo | utf8 string | +| TEXT | TEXT dso_stringmemo | ftstring | msestring | +| BLOB | BLOB | ftblob | string | ++--------------------+---------------------+-------------+-------------+ + +ZeosLib +******* +In order to install the Zeos components add the path to the Zeos source to +'Project'-'Options'-'Make'-'Directories' and compile the IDE with +-dmse_with_zeoslib -dMSEgui. +There is a predefined IDE project apps/ide/mseide_zeos.prj, update 'Project'- +'Options'-'Macros' according to your installation. + +Crosscompiling and remote debugging i386/x84_64-linux -> arm-linux +*********************************************************** +For Raspberry Pi: +- Establish a ssh login without password (public key authentication). + +On the i386/x84_64-linux host: +- install the scp program +- download and extract + https://sourceforge.net/projects/mseide-msegui/files/fpcrossarm/crossfpc-i386_linux_eabihf_3_0_5.tar.gz + (or crossfpc-x86_64_linux_eabihf_3_0_5.tar.gz) + to . + +- Start MSEide, in 'Settings'-'Configure MSEide'-'Global Macros' add: + +Name Value + +CROSSMSEDIR +CROSSFPCDIR +CROSSFPCVERSION 3.0.5 +HOSTIP +REMOTEIP +REMOTEPORT +REMOTEUSER pi + +- 'Project'-'New'-'From Template', select "crossarmdefault.prj" or + "crossarmconsole.prj". +- Create the new project. +- 'Project'-'Options'-'Macros', set the TARGETPROJECTDIR value to the project + path in remote target, ex: "/home/pi/proj/testcase". +- Check the TARGETENV macro. +- If your application needs additional libraries copy them from Raspberry Pi + /lib/arm-linux-gnueabihf or /usr/lib/arm-linux-gnueabihf to + /eabihf/lib + +Press F9 and hope the best. ;-) +If there is a debugger timeout at startup enlarge the +'Project'-'Options'-'Target'-'Wait before connect' value. + +Have a lot of fun! + +Martin diff --git a/mseide-msegui/VERSION.TXT b/mseide-msegui/VERSION.TXT new file mode 100644 index 0000000..929c3d3 --- /dev/null +++ b/mseide-msegui/VERSION.TXT @@ -0,0 +1,675 @@ +MSEide+MSEgui breaking changes version history +********************************************** +Version 4.6.2 +2018-11-03 +2018-10-15 + tcustomframe.colorclient default value cl_transparent -> cl_default. + tdispframe default actualcolorclient() value cl_transparent -> cl_noedit. +2018-10-14 + getsubformeventty and initsubformeventty sender parameter TObject->ttabpage. +2018-09-25 + winidty = ptruint -> winidty = type ptruint. Existing IDE generated + eventhandlers with winidty parameter (createwinideventty, destroywinideventty) + must be updated (longword/qword -> winidty). +2018-09-23 + singlekeyshiftstatesmask -> shiftstatesrepeatmask. +2018-09-14 + optiondockty od_childicons -> optionformty odf_childicons. +2018-09-12 + tifi*clientcontroller.onvaluchanged properties are value type specific. +2017-12-22 + iassistiveserver.doactionexecute() has iassistiveclient parameter. + iassistiveserver.dofocuschanged() has iassistiveclient parameter. +2017-12-17 + iassitiveserver.clientmouseevent() -> doclientmouseevent() +2017-12-15 + initializedynlib(),releasdynlib() callback has data pointer parameter. + +Version 4.6 +2017-11-23 +2017-10-28 imagebufferinfoty -> maskedimagety. +2017-09-22 + tdatabutton.min -> valuemin, max -> valuemax. + tintegeredit.min -> valuemin, max -> valuemax. + tint64edit.min -> valuemin, max -> valuemax. + tenumedit.min -> valuemin, max -> valuemax. + trealedit.min -> valuemin, max -> valuemax. + tdatetimeedit.min -> valuemin, max -> valuemax. +2017-09-14 + Definition of the inner active area of buttons is made with + the new tframe property frameo_* instead of framei_*, + framei_* is used in order to adjust the caption rect. + ttabs.captionframe_* replaced by tframe.framei_*. +2017-07-13 + Definition of "msestring" moved from "msestrings" to "msetypes". +2017-04-14 + cellinfoty boolean flags replaced by celldrawstatesty set. + +Version 4.4.2 +2017-04-08 +2017-04-03 + cl_defaultrect -> cl_buttondefaultrect. +2017-03-30 + Changed parameter clipandmove -> clip, move in + beforeframepaintbackgroundeventty and beforeframepaintbackgroundeventty. +2017-02-20 + dno_append removed from tdbnavigator default options. + +Version 4.4 +2017-02-13 +2017-01-29 + tsqlresult.cols -> datacols. +2017-01-27 tlayouter.place_options plo_syncmaxautosize, + plo_synccaptiondistx,plo_synccaptiondisty, + plo_syncpaintwidth,plo_syncpaintheight -> + optionslayout lao_syncmaxautosize, + lao_synccaptiondistx,lao_synccaptiondisty, + lao_syncpaintwidth,lao_syncpaintheight. +2017-01-19 + msefbconnection.pas -> msefb3connection.pas. + tfbconnection -> tfb3connection. +2016-12-26 + timagelist.getimage returns bitmap- and maskbitmap-kind of imagelist. +2016-10-21 + tlistitem.drawimage() parameter order changed. +2016-10-02 + teditwidgetdatalink.options oed_syncedittonavigator default off. +2016-09-30 + Options belonging to bufdataset descendants only moved from + tdscontroller.options to tmsebufdataset.options. + "delayedapplycount" tdscontroller -> tmsebufdataset. +2016-09-28 + Frame buttons options fbo_disabled overrides readonly-state of widget. + For existing widgets which have been saved in readonly-state fbo_disabled must + be cleared one time in design mode. +2016-09-26 + TCustomSQLConnection DatabaseName, Password, UserName, HostName, Charset and + Role properties ansistring -> msestring. +2016-27-04 + ondrawcelleventty cellinfo parameter var instead of const. + +Version 4.2 +2016-02-24 +2015-12-23 + Endpoints of visible tframe.frameimage edges are always painted independently + of the hiddenedges state of neighbors. Copy the middle image to the end images + in order to restore the old appearance. +2015-11-23 + twidget.findwidget() -> findchild(). + twidget.findtagwidget() -> findtagchild(). + +Version 4.0 +2015-11-13 +2015-11-03 + tcustomface opacity values of alpha blending inverted, white is + full opaqueness of the elements. +2015-10-27 + tcustomframe.frameimage_offsetactivemouse, + frameimage_offsetactiveclicked, frameface_offsetactivemouse and + frameface_offsetactiveclicked removed. The resulting offset is now the sum + of all active offsets. +2015-10-24 + tslider.scrollbar.face moved to tcustomscrollbar, + disable tslider.scrollbar.face in order to show the pattern. + +Version 4.0beta1 +2015-09-30 + tfiledialog statvalues lastdir, filehistory, filefilter and fielefilterindext + moved to oe1_saveoptions section. +2015-09-27 + charencodingty ce_utf8n -> ce_utf8, please load broken forms into MSEide + in order to fix the *.mfm files. +2015-09-15 + Internal character encoding is utf-16 instead of UCS2. +2015-08-09 + applyrecupdateeventty asql parameter is msestring. +2015-08-08 + trystrto*mse() -> trystrto*(). +2015-07-02 + Commandline functions and params use msestring instead of string. + +Version 3.8 +2015-05-13 + tcustomapplication.locked() -> islockedthread(). +2015-02-04 + tselector.dropdownitems ->tdropdowndatacols, published properties removed. +2015-01-17 + tdscontroller.recnonullbased -> recnozerobased. +2014-12-26 + tskinfont has template property instead of individual properties. + +Version 3.6 +2014-11-25 +2014-11-19 + tdataedit.optionsedit oe_savevalue,oe_savestate,oe_saveoptions, + oe_checkvaluepaststatread -> optionsedit1 oe1_savevalue,oe1_savestate, + oe1_saveoptions,oe1_checkvalueafterstatread. + tfiledialog.optionseedit -> optionsedit1. +2014-11-16 + Type of "onshortcut" is "shortcuteventty" with an additional "origin" + parameter. +2014-10-14 + Dropdowncols fontcoloractive -> fontacitve. +2014-10-01 + tprocess.input tpipewriter -> tpipewriterpers, use tprocess.input.pipewriter. +2014-09-30 + Inplace tmacrolist.expandmacros() -> expandmacros1(). + +Version 3.4a +2014-08-20 +Version 3.4 +2014-08-15 +2014-07-15 + tpoorstringdatalist.addchars() processeditchars: boolean -> + aoptions: addcharoptionsty. + tcustomstringcol.addchars() processeditchars: boolean -> + aoptions: addcharoptionsty. +2014-06-26 + TField.ProviderFlags pfInInsert and pfInitInsert removed. + TField.Visible, ReadOnly, Required, ProviderFlags and + providerflags1 combined into TField.optionsfield property. +2014-06-08 + Separate TField.ProviderFlags pfInInsert, pfInUpdate. +2014-03-09 + Parameter monochrome -> kind for t*bitmap.create(). + t*bitmap.monochrome removed, use t*bitmap.kind instead. +2014-02-26 + params parameter for tmaskedbitmap.loadfrom*(). + +Version 3.2 +2014-01-30 +2014-01-27 + tcustomframe.*framewidth() -> *framedim(). + twidget.framewidth() -> framedim(). + +Version 3.0 +2013-09-27 +2013-07-14 + No #0 for last byte in tcanvas.dashes, + use cl_transparent colorbackground instead. +2013-07-02 + tcanvas.lineoptions -> tcanvas.options + +Version 3.0beta1 +2013-06-29 +2013-05-02 + sender parameter of ifi clientevents is tcustomificlientcontroller. +2013-04-30 + onsetvalue of ifi t*clientcontroller have a iificlient parameter. +2013-04-14 + transparency properties -> opacity. +2013-03-28 + treader.readset() settype parameter is type of set instead of type of enum. + twriter.writeset() settype parameter is type of set instead of type of enum. +2013-03-10 + tcustomgrid.optionsgrid og_noresetselect -> optionsgrid1 og1_noresetselect. +2013-03-03 + sender parameter of tcustomstringcol.oncopytoclipboard, onpastefromclipboard + is tcustomstringcol. + +2013-02-14 + tapplication.postevent() boolean parameters -> posteventoptionsty. + application.modallevel returns 0 instead of -1 for single loop stack. +2013-02-12 + t*dispwidget.onchange -> ondatachange. +2013-01-20 + Forking of classes.pp. Add "mclasses" after "classes" in uses. +2013-01-19 + Forking of db.pas. Change "db" -> "mdb" in uses. + +Version 2.8.6 +2012-12-31 + lib/common/kernel/i386-linux -> lib/common/kernel/linux. + lib/common/kernel/i386-win32 -> lib/common/kernel/windows. + There is a new settings macro ${TARGETOSDIR} which points to the new directory. + Please replace ${TARGET} by ${TARGETOSDIR} in your existing project options. +2012-12-18 + tstringcontainer -> tkeystringcontainer + +Version 2.8.4 +2012-12-14 +2012-12-13 + tpoorstringdatalist.addchars() returns added rowcount instead of rowindex. +2012-11-25 + tpopupmenu.additems() aseparator parameter removed, use tcustommenu.options + oe_noseparator. +2012-10-26 + optionsscrollty oscr_zoom -> oscr_zoomwidth,oscr_zoomheight. +2012-10-11 + onloaded called after loaded() of the children and self.loaded(). + oncreate called after children have been created but before loaded(). + oncreated called in afterconstruction(). +2012-10-08 + oncreate always called before onloaded independent of globalloading and inline + state. + treport oncreate <-> onloaded. +2012-09-14 + tcustommseform oncreate <-> onloaded. + tmsedatamodule oncreate <-> onloaded. +2012-09-13 + fieldarrayty -> fieldarty. +2012-09-07 + formatfloatmse() format 0.###f defines decimal places, use 0..###f for mantissa + digits. +2012-06-30 + Global syntax definition format for tsyntaxpainter changed: + keyworddefs = + KEYWORDDEFS keyworddefsname [stylename] newline + {{keyword} newline} + + Local syntax definition format for tsyntaxpainter changed: + keywords = + KEYWORDS [style] newline //style used as default + {keyworddefsname [style] newline} + +2012-04-14 + *cryptio* -> *cryptoio*. +2012-04-13 + mopenssl -> mseopenssl, uses dynlibinfoty, stadardised with other lib bindings. + BIO functions -> mseopensslbio. + +Version 2.8.2 +2012-04-01 +2012-02-01 + optionedit oe_autopoupmenu,oe_keyexecute-> + optionedit1 oe1_autopoupmenu,oe1_keyexecute-> +2012-01-27 + optionwidget ow_fontglyphheight,ow_fontlineheight,ow_autoscale -> + optionwidget1 ow1_fontglyphheight,ow1_fontlineheight,ow1_autoscale. + +Version 2.8 +2012-01-11 +2011-12-31 + tsqlresult inherits from tsqlstatement, options -> sqlresultoptionsty. + tsqlquery moved to msesqlquery.pas. +2011-12-25 + shiftstatemustinclude and shiftstatemustnotinclude parameters for iscellclick(), + same as iscellkeypress(). +2011-12-20 + Statfile multi line string values format unified. + rttistat ansi string value stored in binary. + +Version 2.8rc1 +2011-12-12 +2011-11-28 + tcustomgrid.gridframewidth removed, use frame.framei* instead. +2011-11-23 + execmse*() inactive,nostdhandle,tty,usepipewritehandle,sessionleader parameter + replaced by execoptionsty options parameter. + richstring formatset() functions -> *1() named. +2011-11-21 + tmsesqlquery.controller.options default = [dso_autoapply,dso_autocommitret]. +2011-11-19 + coloptionty co_sortdescent -> co_sortdescend +2011-11-17 + nowutc(), nowlocal() msesysutils.pas -> msedate.pas. +2011-11-05 + splitteroptionsty spo_nohshrinkzero -> spo_hshrinkzero. + splitteroptionsty spo_novshrinkzero -> spo_vshrinkzero. +2011-10-02 + Sender parameter in ttimer.ontimer is ttimer instead of tsimpletimer. +2011-09-30 + formatsettingsmse moved from msesys.pas to mseformatsettings.pas. +2011-09-29 + Deprecated bucket lists moved from msehash.pas to to msebucketlist.pas +2011-09-26 + Array utility functions msedatalist.pas -> msearrayutils.pas. + Library load functions msesys.pas -> msedynload.pas. +2011-09-17 + Unified parameter order for sort functions. +2011-06-27 + tdatasetcontroller.options dso_refreshwaitcursor -> dso_waitcursor. +2011-06-23 + handled parameter for stepeventty. +2011-06-01 + tdb*lookuplb.lookupbuffer, lookupkeyfieldno, lookupvaluefieldno moved to + datalink. +2011-05-20 + strscan() and msestrscan with integer result removed, use findchar() instead. +2011-05-19 + tfieldparamlink.slaveparams -> destparams. + tfieldparamlink.slavefields -> destfields. +2011-04-06 + dso_sync* options -> optionsmasterlink. +2011-03-30 + optionseditty moved to mseeditglob. +2011-03-29 + tvalueclientcontroller.datafield -> fieldname. +2011-03-26 + tfieldparamlink.datafield -> fieldname. +2011-03-13 + tskincontroller.toolbar_* -> toolar_horz_*, toolbar_vert_*. +2011-03-12 + tmse*field.providerflags1 pf1_refresh -> pf1_refreshinsert, pf1_refreshupdate. +2011-02-28 + Font handling functions moved to graphics/msefont.pas. + +Version 2.6 +2011-02-26 +2011-02-13 + tterminal.onprocfinished sender parameter is tterminal instead of tmseprocess. +2010-12-13 + tscrollingwidget.scrollpos -> tscrollboxframe.scrollpos. +2010-11-19 + Changed iobjectpicker and tpickwidget event properties. +2010-11-2 + No negative ttimer values for single shot, use options to_single instead. + +Version 2.4 +2010-11-01 +2010-10-22 + sys_homedir -> sys_apphomedir. + "~/" returns sys_userhomedir, use "^/" for application home directory. +2010-10-14 + tscrollingwidget.onchildscaled -> onlayout. +2010-09-10 + tmsecomponentarrayprop -> tmsecomponentlinkarrayprop, + tmsecomponentitem -> tmsecomponentlinkitem +2010-09-08 + trecordertrace.offset -> start. +2010-09-01 + tapplication.create() calls lock(). +2010-08-27 + Read versions of image format units have suffix "read", + example mseformatpng -> mseformatpngread. +2010-08-18 + DB single key locate() replaced by multi key version. +2010-06-5 + application.screensize -> application.screenrect. + +Version 2.4rc1 +2010-06-03 +2010-05-21 + No indirection for richstringty format colors. +2010-04-08 + optionswidgetty ow_noautosizing -> optionswidget1ty ow1_noautosizing. + coloptions1ty co1_active removed. + coloptionsty co_rowfont, co_rowcolor, co_zebracolor, co_rowcoloractive -> + coloptions1ty co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcoloractive. + Grid coloractive -> colorfocus. +2010-03-16 + key_* $10xx -> $01xx. + key_enter -> key_return. +2010-02-17 + twidget.optionswidget ow_canclosenil -> optionswidget1 ow1_canclosenil. +2010-02-11 + synchronizeprocty -> synchronizeeventty. + objectprocty -> proceventty. + tagprocty -> tageventty. + tevent -> tmseevent. +2010-02-09 + ttabs framei direction reversed. + ttabbar uses ow1_autoheight instead of ow_autoscale. + ttabwidget.options -> tab_options. +2010-02-06 + tdataedit.empty_textstyle -> empty_fontstyle. +2010-01-04 + Some definitions moved from msegrids.pas to msegridsglob.pas. +2009-12-15 + Default tcustomframe.colorframe = cl_black. +2009-12-13 + t*widget.valuescale -> valuerange, inverted. +2009-12-10 + ttrace.xseriesdata -> ydata. + ttrace.xoffset, yoffset -> xstart,ystart, sign reversed. + ttrace.xscale, yscale -> xrange, yrange. + tchart.dialshorz -> xdials. + tchart.dialsvert -> ydials. +2009-12-09 + ttrace.xseriescount-> maxcount. +2009-12-03 + tcustombutton.captionpos -> imagepos. + tcolheader.captionpos -> imagepos. + tcustomdatabutton.captionpos -> imagepos. + ttabs.captionpos -> imagepos. + ttabwidget.tab_captionpos -> tab_imagepos. +2009-11-25 + tcustomdialcontroller opposite reversed for gd_up, gd_down. +2009-11-24 + tcustomchart.dialhorz, dialvert -> array dialshorz, dialsvert. + dialoptionty do_rotatetext -> dialmarkeroptionty dmo_rotatetext and + dialtickoptionty dto_rotatetext. + tcustomdialcontroller.offset -> start. + +Version 2.2beta2 +2009-11-18 +2009-11-09 + comparprocty out result -> var result. +2009-11-01 + tfont.colorshadow -> shadow_color. +2009-10-19 + twidget.optionswidget ow_autosize, ow_autosizeanright, ow_autosizeanleft moved + to optionswidget1 ow1_autowidth, ow1_autoheight, ow1_autosizeanright, + ow1_autosizeanbottom. + Changed signature of endpickmoveeventty. +2009-09-16 + trichbutton has no stockglyph, use trichstockglyphbutton. +2009-08-05 + datatypty -> listdatatypety. +2009-07-31 + optiongridty og_merged -> og_colmerged. +2009-06-27 + tmsesqlquery.refresh does not restore recno, use controller.refresh(true). + +Version 2.2beta1 +2009-06-23 +2009-06-17 + msestringicomp1 -> msestringicompupper. + lstringicomp1 -> lstringicompupper. + tcustomgrid.getselectedrows -> tdatacols.selectedrows. +2009-06-02 + tgriddatalink.datafield -> fieldname_state. +2009-04-10 + Modified parameters for updateerroreventty (tmsebufdataset.onupdateerror). +2009-03-15 + tcalendardatetimeedit moved to msecalendardatetimeedit.pas. + tdbcalendardatetimeedit moved to msedbcalendardatetimeedit.pas. +2009-03-13 + Event handlers must be in "managed" area of the class + definition, between "class" and the first "private", "protected", + "public" or "published". +2009-03-02 + const modifiers for indexeventty parameters (datalist.pas). +2009-02-13 + titemedit.onmouseevent -> onclientmouseevent. +2009-02-12 + optiongridty og_rotaterow -> og_wraprow, additional og_wrapcol, + must be activated in existing projects. +2009-02-06 + checkvalueeventty, settexteventty, gettexteventty tdataedit -> tcustomdataedit. +2009-02-04 + tdatacol.onchange -> datacolchangeeventty. + +Version 2.0rc1 +2009-02-02 +2009-01-28 + tdb*grid.datasourec moved to tdb*grid.datalink. +2009-01-17 + mouseeventinfoty, mousewheeleventinfoty, keyeventinfoty moved to + mseguiglob.pas. +2009-01-12 + tdb*editwidget.datasource, optionsdb and datafield moved to + tdb*editwidget.datalink. +2008-12-16 + tmseform descendants without resources (no *.mfm file) must override + class function hasresource() and return false. + +Version 2.0beta2 +2008-12-15 +2008-10-25 + int64 parameter for tlookupbuffer.addrow and tlookupbuffer.addrows. +2008-10-16 + tcustomrealedit.asinteger returns minint for empty value. + +Version 2.0beta1 +2008-10-15 +2008-10-09 + New parameters leadingtext and handled in exceptioneventty. +2008-10-04 + shapestatety ss_* -> shs_* in in order to distinguish from shiftstate. +2008-09-02 + '[' is special char instead of '#' in string propertyediter. +2008-08-04 + tguiapplication.waitdialog aidleaction parameter is type waitidleeventty. + tthreadcomp.runwithwaitdialog moved to tguithreadcomp. +2008-05-31 + optioneditty oe_returntaborder -> optionwidgetty ow_keyreturntaborder + +Version 1.8rc1 +2008-05-24 +2008-05-14 + tsqlquery.executedirect uses write transaction. +2008-04-09 + treport.onbeforerender -> reporteventty. + treport.onafterrender -> onreportfinished. +2008-03-26 + tbuttonframe.options fbo_flat, fbo_noanim -> + tcustomframe.optionsskin fso_flat, fso_noanim. + +Version 1.8beta1 +2008-03-20 + gridcoordty parameter for griddataeventty. + gridcoordty parameter for griddatablockeventty. + griddatamovedeventty -> gridblockmovedeventty. + gridbeforedatablockeventty -> gridbeforeblockeventty. +2008-03-14 + syncminframewidth -> syncpaintwidth. + syncminframeheight -> syncpaintheight. +2008-03-11 + twidget.taborderedwidgets -> gettaborderedwidgets. +2008-03-09 + tcustomcaptionframe.captiondistouter -> options cfo_captiondistouter. + tcustomcaptionframe.captionnoclip -> options cfo_captionnoclip. +2008-03-04 + mseguithread.pas -> msethreadcomp.pas +2008-02-02 + tscrollbar.options sbo_flat and sbo_noanim moved to tframe.optionsskin. + tbutton.options bo_flat,bo_noanim,bo_nofocusrect,bo_nodefaultrect + moved to tframe.optionsskin. + tmenu.options mo_noanim moved to itemframetemplate.optionsskin. +2008-01-04 + tcustomdatabutton visible and enabled no more published. +2007-12-28 + tdbcontroller.onbeforeconnect,onconnecterror and onafterconnect moved to + tmdatabase. +2007-12-13 + tapplication.wakeupguithread -> wakeupmainthread. +2007-12-08 + optionsedit oe_autoapply moved to optiondb oed_autoapply. +2007-12-07 + cl_none changed from $80000000 to $80000006, $80000000 can not be used + as default property value. +2007-12-01 + tcoloredit.buttonellipse moved to frame. + tframebutton.visible,enabled and left no more published, use options. + +Version 1.6 +2007-11-19 +2007-10-29 + Refactoring for GUI independent MSEifi: + modalresultty moved to mseglob. + Action basics moved to mseact. + tactivator moved to mseapplication. + +2007-09-29 + sqlscripteventty -> sqlstatementeventty + sqlscripterroreventty -> sqlstatementerroreventty +2007-09-27 menuoptinonsty mo_flat -> mo_noanim. + +Version 1.4 +2007-09-06 + Default value of tdbnaviagator.options = [dno_confirmdelete,dno_append]. + tcustomrecordband.options bo_show*/bo_hide* -> optionsshow bos_show*/bos_hide* +2007-08-29 Defaultvalue of tmsebufdataset.packetrecords = -1. +2007-08-25 + tfieldlink.dataset -> destdataset. + tfieldlink.datafield -> destdatafield. + tfieldfiledlink.sourcedatafield -> datafield. + +Version 1.4beta1 +2007-08-07 Modified type of tmsebufdataset.onupdateerror. +2007-08-01 TDatabase -> tmdatabase, moved to msedatabase.pas. +2007-07-24 tspacer.offset_* -> dist_*. + +Version 1.2 +2007-06-15 + +Version 1.2rc2 +2007-05-17 tcustomrealedit.scale -> valuescale. +2007-05-07 tcustomprogressbar.scale -> valuescale. + +Version 1.2rc1 +2007-03-29 tdbimage renamed to tdbdataimage. + +Version 1.2beta2 +2007-03-22 tcustommseform.onloaded renamed to oneventloopstart. +2007-03-18 tgripframe.grip_colorbutton -> grip_colorglyph. +2007-02-23 Published properties tcolordropdownlistcontroller.cols, valuecol + and itemindex removed. +2007-02-21 tprintercanvas.firstpage, lastpage replaced by + tprintercanvas.pages. + +Version 1.2beta1 +2007-02-15 TSQLQuery.UpdateSQL,InsertSQL and DeleteSQL renamed to + SQLUpdate,SQLInsert and SQLDelete. +2007-02-06 tstockobjects.paintglyph order of parameters changed. +2007-02-06 timagelist.paint order of parameters changed. +2007-01-25 tprinter.ppmm -> tcanvas.ppmm. +2006-12-23 tfixrow.hints moved to tcolheader. +2006-12-22 Item order of tfixcols, tfixrows and tfixcolheaders reversed. +2006-11-22 tcustomlookupbuffer.options olbdb_invalidateonupdatedata -> + olbdb_invalidateifmodified. +2006-10-23 Function vartorealty. +2006-10-20 ttimestampfieldlink, tfieldlink, tdscontroller.post. + +Version 1.0rc1 +2006-10-19 oldb_invalidateonupdatedata -> olbdb_invalidateonupdatedata. +2006-10-18 Blob suport for tmibconnection and tmpqconnection. +2006-10-17 Calculated fields for tmbufdataset. +2006-10-16 tdbimage. +2006-10-15 tfieldfieldlink. +2006-09-27 tmsecomponent.linkedobjects, tobjeclinker.linkedobjects. +2006-09-25 tstatfile moved to msestatfile.pas. + tmsedatamodule moved to msedatamodules.pas. + Properties tstatfile.activator, tactivator.onactvateerror, + tdbcontroller.onbeforeconnect, onconnecterror. + tpostprintprinter clipping. +2006-09-23 tpostscriptprinter pattern support. + +Version 0.9b +2006-08-27 tsplitter.options spo_dockleft,spo_docktop,spo_dockright, + spo_dockbottom, default on. +2006-08-25 Property tscalingwidget.optionsscale, osc_expandx,osc_expandy, + osc_shrinkx,osc_shrinky, used in tgroupbox and tscrollbox. + tspacer. +2006-08-24 tintegerbutton renamed to tdatabutton, tdbdatabutton, + tdialogstringedit, tdbdialogstringedit. +2006-08-20 tprogressbar. +2006-08-18 tsequencelink. +2006-08-10 tpostscriptprinter imageprinting. +2006-07-29 foregroundcolor renamed to colorforeground. +2006-07-29 backgroundcolor renamed to colorbackground. +2006-07-22 Property tfilenamedit.dialogkind removed, + use controller.options fdo_save. +2006-07-19 tmsecomponent.helpcontext. +2006-07-19 tapplication.helpcontext. +2006-07-18 tcanvas.drawvect. +2006-07-13 msedrawtext.breaklines. +2006-07-12 tdbstringdisplb, tdbintegerdisplb, tdbrealdisplb, tdbdatetimedisplb. +2006-07-11 tcustomlookupbuffer.lookupinteger, lookuptext and lookupfloat. +2006-07-10 Switch to FPC 2.0.4, support for 2.0.2 and 2.0.3 removed. + +Version 0.9a +2006-07-08 tcustomedit.onkeydown. +2006-07-07 Field keyeventty.keynomod, holds unmodified key. +2006-07-06 property tgriddatalink.datafield, sets tcustomgrid.rowcolorstate and + rowfontstate according to tgriddadalink.field.asinteger. +2006-07-05 tinplaceedit.lasttextclipped. +2006-07-05 Default of tgroupbox.optionswidget + + [ow_arrrowfocusin,ow_arrowfocusout,ow_parenttabfocus,ow_subfocus]. +2006-07-05 Flag twidget.optionswidget ow_parenttabfocus. +2006-07-04 tdbcalendardatetimeedit. +2006-07-04 tcalendardatetimeedit. + +Version 0.9 +2006-07-01 First Sourceforge SVN release diff --git a/mseide-msegui/apps/demo/demo.pas b/mseide-msegui/apps/demo/demo.pas new file mode 100644 index 0000000..e300c20 --- /dev/null +++ b/mseide-msegui/apps/demo/demo.pas @@ -0,0 +1,8 @@ +program demo; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +uses + {$ifdef FPC}{$ifdef unix}cthreads,{$endif}{$endif}msegui,mseforms,main; +begin + application.createform(tmainfo,mainfo); + application.run; +end. diff --git a/mseide-msegui/apps/demo/demo.prj b/mseide-msegui/apps/demo/demo.prj new file mode 100644 index 0000000..37c6e8f --- /dev/null +++ b/mseide-msegui/apps/demo/demo.prj @@ -0,0 +1,1016 @@ +[componentpalette] +order0=0 +order1=0 +order2=0 +order3=0 +order4=0 +order5=0 +order6=0 +order7=0 +order8=0 +order9=0 +order10=0 +order11=0 +order12=0 +order13=0 +order14=0 +order15=0 +order16=0 +order17=0 +order18=0 +[projectoptions] +projectdir=/home/mse/packs/standard/git/mseide-msegui/apps/demo +projectfilename=/home/mse/packs/standard/git/mseide-msegui/apps/demo/demo.prj +mainfile=demo.pas +targetfile=demo${EXEEXT} +messageoutputfile= +makecommand=${COMPILER} +makedir= +unitdirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}kernel/ + ${MSELIBDIR}*/ +unitpref=-Fu +incpref=-Fi +libpref=-Fl +objpref=-Fo +targpref=-o +befcommand=0 +aftcommand=0 +makeoptions=4 + -Xg -l -Mobjfpc -Sh -Fcutf8 + -gl -O- + -B + -O2 -XX -Xs -CX +codetemplatedirs=1 + ${TEMPLATEDIR} +toolmenus=0 +toolfiles=0 +toolparams=0 +fontnames=0 +scriptbeforecopy= +scriptaftercopy= +newprojectfiles=4 + ${TEMPLATEDIR}default/project.pas + ${TEMPLATEDIR}default/main.pas + ${TEMPLATEDIR}default/main.mfm + ${TEMPLATEDIR}default/main_mfm.pas +newprojectfilesdest=4 + ${%PROJECTNAME%}.pas + + + +newfinames=3 + Program + Unit + Textfile +newfifilters=3 + "*.pas" "*.pp" + "*.pas" "*.pp" + +newfiexts=3 + pas + pas + +newfisources=3 + ${TEMPLATEDIR}default/program.pas + ${TEMPLATEDIR}default/unit.pas + +newfonames=11 + Mainform + Simple Form + Docking Form + Datamodule + Subform + Scrollboxform + Tabform + Dockpanel + Report + Scriptform + Inherited Form +newfonamebases=11 + form + form + form + module + form + form + form + form + report + script + form +newfosources=11 + ${TEMPLATEDIR}default/mainform.pas + ${TEMPLATEDIR}default/simpleform.pas + ${TEMPLATEDIR}default/dockingform.pas + ${TEMPLATEDIR}default/datamodule.pas + ${TEMPLATEDIR}default/subform.pas + ${TEMPLATEDIR}default/scrollboxform.pas + ${TEMPLATEDIR}default/tabform.pas + ${TEMPLATEDIR}default/dockpanelform.pas + ${TEMPLATEDIR}default/report.pas + ${TEMPLATEDIR}default/pascform.pas + ${TEMPLATEDIR}default/inheritedform.pas +newfoforms=11 + ${TEMPLATEDIR}default/mainform.mfm + ${TEMPLATEDIR}default/simpleform.mfm + ${TEMPLATEDIR}default/dockingform.mfm + ${TEMPLATEDIR}default/datamodule.mfm + ${TEMPLATEDIR}default/subform.mfm + ${TEMPLATEDIR}default/scrollboxform.mfm + ${TEMPLATEDIR}default/tabform.mfm + ${TEMPLATEDIR}default/dockpanelform.mfm + ${TEMPLATEDIR}default/report.mfm + ${TEMPLATEDIR}default/pascform.mfm + ${TEMPLATEDIR}default/inheritedform.mfm +forcezorder=0 +stripmessageesc=0 +copymessages=0 +closemessages=1 +checkmethods=1 +colorerror=-1610612712 +colorwarning=-1610612717 +colornote=-1610612716 +usercolors=30 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +usercolorcomment=30 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +formatmacronames=0 +formatmacrovalues=0 +settingsfile= +settingseditor=0 +settingsdebugger=0 +settingsstorage=0 +settingsprojecttree=0 +settingsautoload=0 +settingsautosave=0 +modulenames=1 + MAINFO +moduletypes=1 + TMAINFO +modulefiles=1 + /home/mse/packs/standard/git/mseide-msegui/apps/demo/main.mfm +befcommandon=0 +makeoptionson=4 + 63 + 31 + 34 + 32 +aftcommandon=0 +unitdirson=3 + 983103 + 983103 + 983103 +macroon=0 +macronames=0 +macrovalues=0 +macrogroup=0 +groupcomments=6 + + + + + + +toolsave=0 +toolhide=0 +toolparse=0 +toolmessages=0 +toolshortcuts=0 +fontalias=0 +fontancestors=0 +fontheights=0 +fontwidths=0 +fontoptions=0 +fontxscales=0 +expandprojectfilemacros=4 + 1 + 1 + 1 + 0 +loadprojectfile=4 + 1 + 1 + 1 + 0 +newinheritedforms=11 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 +uid=0 +sourcefilemasks=3 + "*.pas" "*.dpr" "*.lpr" "*.pp" "*.inc" + "*.c" "*.cc" "*.h" + "*.mfm" +syntaxdeffiles=3 + ${SYNTAXDEFDIR}pascal.sdef + ${SYNTAXDEFDIR}cpp.sdef + ${SYNTAXDEFDIR}objecttext.sdef +filemasknames=3 + Source + Forms + All Files +filemasks=3 + "*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + *.mfm + * +showgrid=1 +snaptogrid=1 +moveonfirstclick=1 +noformdesignerdocking=0 +gridsizex=8 +gridsizey=8 +autoindent=1 +blockindent=1 +linenumberson=0 +rightmarginon=1 +rightmarginchars=80 +scrollheight=0 +tabstops=4 +spacetabs=0 +showtabs=0 +tabindent=0 +editfontname=mseide_source +editfontheight=0 +editfontwidth=0 +editfontextraspace=0 +editfontcolor=-1879048183 +editbkcolor=-1879048186 +statementcolor=14745599 +editfontantialiased=1 +editmarkbrackets=1 +backupfilecount=2 +encoding=1 +codetemplatedirs=1 + ${TEMPLATEDIR} +debugcommand=${DEBUGGER} +debugoptions= +debugtarget= +runcommand= +xtermcommand=xterm -S${PTSN}/${PTSH} +remoteconnection= +uploadcommand= +gdbprocessor=auto +gdbservercommand= +gdbservercommandattach= +beforeconnect= +afterconnect= +beforeload= +afterload= +beforerun= +sourcebase= +sourcedirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ + ./ +defines=0 +progparameters= +progworkingdirectory= +envvarnames=0 +envvarvalues=0 +defineson=0 +stoponexception=0 +valuehints=1 +activateonbreak=1 +raiseonbreak=1 +showconsole=0 +externalconsole=0 +settty=1 +gdbdownload=0 +downloadalways=0 +startupbkpt=0 +startupbkpton=0 +gdbsimulator=0 +gdbserverstartonce=0 +gdbloadtimeout= +gdbserverwait=0 +nogdbserverexit=0 +gdbservertty=0 +exceptclassnames=1 + EconvertError +exceptignore=1 + 0 +nodebugbeginend=0 +sigsettings=27 + 1,1,T,F + 3,3,T,F + 4,4,T,F + 6,6,T,F + 7,7,T,F + 8,8,T,F + 9,9,T,F + 10,10,T,F + 11,11,T,F + 12,12,T,F + 13,13,T,F + 15,15,T,F + 16,16,T,F + 17,17,F,F + 18,18,T,F + 19,19,T,F + 20,20,T,F + 21,21,T,F + 22,22,T,F + 23,23,T,F + 24,24,T,F + 25,25,T,F + 26,26,T,F + 27,27,T,F + 28,28,T,F + 29,29,T,F + 30,30,T,F +defaultmake=1 +[breakpoints] +on=0 +path=0 +line=0 +address=0 +addbkpt=0 +ignore=0 +condition=0 +panels=2 + panel1 + panel2 +units= + ( + a=0,4132,6,Pascal Units + ) +cmodules= + ( + a=0,4132,6,C Modules + ) +files= + ( + a=0,4132,6,Text Files + ) +[componentstore] +storedir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ +filename= +[components] +[selecteditpage] +colwidth=100 +x=0 +y=0 +cx=0 +cy=0 +[progparams] +progparamhistory=0 +workdirparamhistory=0 +envvarons=0 +[edit] +hintwidth=0 +hintheight=0 +finddtext= +findhistory=0 +findoptions=1 +editpos=2 + 0,0 + 0,0 +bookmarks0=0 +bookmarks1=0 +sourcefiles=2 + /home/mse/packs/standard/git/mseide-msegui/apps/demo/main.pas + /home/mse/packs/standard/git/mseide-msegui/apps/demo/demo.pas +relpaths=2 + main.pas + demo.pas +ismoduletexts=2 + 0 + 0 +modules=1 + /home/mse/packs/standard/git/mseide-msegui/apps/demo/main.mfm +moduleoptions=1 + 0 +visiblemodules=1 + -1 +nomenumodules=1 + 0 +[sourcefo.tabwidget] +tabsize=125 +firsttab=0 +index=1 +[layout] +windowlayout=552 + [mainfo.openform] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.projectfiledia] + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + [mainfo.openfile] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/demo/demo.pas + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + filehistory=2 + /home/mse/packs/standard/git/mseide-msegui/apps/demo/demo.pas + /home/mse/packs/standard/git/mseide-msegui/apps/demo/main.pas + filefilterindex=0 + filefilter="*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + [mainfo.basedock] + splitdir=2 + useroptions=146560 + [mainfo] + splitdir=0 + useroptions=33554555 + stackedunder=mainfo.panel1 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=25 + cx=323 + cy=64 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [targetconsolefo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=209 + y=385 + cx=368 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [threadsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=37 + y=270 + cx=349 + cy=276 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo] + splitdir=0 + useroptions=16507 + stackedunder=cpui386fo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=100 + y=100 + cx=453 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo.add] + value=0 + [memoryfo.memon] + value=0 + [memoryfo.bitwidth] + value=0 + [memoryfo.cnt] + value=0 + [disassfo] + splitdir=0 + useroptions=16491 + stackedunder=componentpalettefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=162 + y=502 + cx=564 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [findinfilefo] + splitdir=0 + useroptions=16491 + stackedunder=disassfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=548 + y=115 + cx=369 + cy=198 + rcx=0 + rcy=0 + [projecttreefo] + splitdir=0 + useroptions=16491 + stackedunder=memoryfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=263 + y=431 + cx=286 + cy=201 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [projecttreefo.grid] + propcolwidthref=135 + width0=141 + sortdescend0=0 + width1=129 + sortdescend1=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=16 + [stackfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=295 + rcx=0 + rcy=0 + [watchpointsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=120 + y=368 + cx=483 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [watchpointsfo.grid] + propcolwidthref=352 + sortdescend0=0 + values1=0 + values1_ci=-1 + width1=33 + sortdescend1=0 + values2=0 + width2=158 + sortdescend2=0 + width4=34 + sortdescend4=0 + values5=0 + values5_ci=-1 + width5=38 + sortdescend5=0 + values6=0 + width6=184 + sortdescend6=0 + [breakpointsfo] + splitdir=0 + useroptions=16491 + stackedunder=projecttreefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=107 + y=404 + cx=636 + cy=128 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [breakpointsfo.bkptson] + value=1 + [objectinspectorfo] + splitdir=0 + useroptions=16491 + stackedunder=mainfo.panel2 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=724 + y=157 + cx=296 + cy=566 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [objectinspectorfo.grid] + propcolwidthref=286 + width0=105 + sortdescend0=0 + width1=175 + sortdescend1=0 + [symbolfo] + splitdir=0 + useroptions=16507 + stackedunder=findinfilefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=142 + y=257 + cx=361 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [symbolfo.grid] + propcolwidthref=222 + values0=0 + width0=111 + sortdescend0=0 + width1=135 + sortdescend1=0 + [symbolfo.symbol] + [watchfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=298 + cx=313 + cy=236 + rcx=0 + rcy=0 + [watchfo.grid] + propcolwidthref=118 + values0=0 + values0_ci=-1 + sortdescend0=0 + values1=0 + width1=152 + sortdescend1=0 + values3=0 + values3_ci=-1 + sortdescend3=0 + values4=0 + values4_ci=-1 + width4=13 + sortdescend4=0 + [watchfo.watchon] + [watchfo.expression] + [watchfo.watcheson] + value=1 + [messagefo] + splitdir=0 + useroptions=49259 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=510 + cx=675 + cy=95 + rcx=0 + rcy=0 + [componentstorefo] + splitdir=0 + useroptions=24699 + stackedunder=symbolfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=305 + y=101 + cx=445 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentstorefo.grid] + propcolwidthref=435 + width0=111 + sortdescend0=0 + sortdescend1=0 + width2=112 + sortdescend2=0 + width3=185 + sortdescend3=0 + [componentstorefo.storefiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.groupfiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.compfiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentpalettefo] + splitdir=0 + useroptions=24683 + stackedunder=objectinspectorfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=25 + cx=685 + cy=103 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [componentpalettefo.componentpages] + activetab=0 + [debuggerfo] + splitdir=0 + useroptions=24683 + parent=mainfo.basedock + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=28 + rcx=0 + rcy=0 + [sourcefo] + splitdir=0 + useroptions=16489 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=675 + cy=507 + rcx=0 + rcy=0 + [actionsmo.watchesonact] + checked=1 + [actionsmo.bluedotsonact] + checked=1 + [cpui386fo] + irqoff=0 + splitdir=0 + useroptions=16491 + stackedunder=componentstorefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=337 + y=295 + cx=273 + cy=207 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [mainfo.panel1] + splitdir=2 + useroptions=33586667 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=118 + cx=685 + cy=605 + rcx=0 + rcy=0 + wsize=0 + active=1 + visible=1 + [mainfo.panel2] + splitdir=2 + useroptions=33586667 + stackedunder=_mse_mainfo_mse_ + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=189 + cx=323 + cy=534 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [_mse_mainfo_mse_] + splitdir=0 + useroptions=16507 + stackedunder=mainfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=153 + y=240 + cx=351 + cy=166 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 +[targetconsole] +finddtext= +findhistory=0 +findoptions=1 diff --git a/mseide-msegui/apps/demo/main.mfm b/mseide-msegui/apps/demo/main.mfm new file mode 100644 index 0000000..763722e --- /dev/null +++ b/mseide-msegui/apps/demo/main.mfm @@ -0,0 +1,25 @@ +object mainfo: tmainfo + bounds_x = 153 + bounds_y = 240 + bounds_cx = 341 + bounds_cy = 166 + container.bounds = ( + 0 + 0 + 341 + 166 + ) + options = [fo_main, fo_terminateonclose, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savestate] + moduleclassname = 'tmseform' + object tbutton1: tbutton + bounds_x = 144 + bounds_y = 72 + bounds_cx = 50 + bounds_cy = 22 + state = [as_localcaption, as_localonexecute] + caption = 'Exit' + font.xscale = 1 + font.dummy = 0 + onexecute = exitonexecute + end +end diff --git a/mseide-msegui/apps/demo/main.pas b/mseide-msegui/apps/demo/main.pas new file mode 100644 index 0000000..517d9b8 --- /dev/null +++ b/mseide-msegui/apps/demo/main.pas @@ -0,0 +1,28 @@ +unit main; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +uses + msegui,mseclasses,mseforms,msesimplewidgets; + +type + tmainfo = class(tmseform) + tbutton1: tbutton; + procedure exitonexecute(const sender: TObject); + end; + +var + mainfo: tmainfo; + +implementation +uses + main_mfm; + +procedure tmainfo.exitonexecute(const sender: TObject); +begin + application.terminated:= true; +end; + +end. diff --git a/mseide-msegui/apps/demo/main_mfm.pas b/mseide-msegui/apps/demo/main_mfm.pas new file mode 100644 index 0000000..caca492 --- /dev/null +++ b/mseide-msegui/apps/demo/main_mfm.pas @@ -0,0 +1,37 @@ +unit main_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,main; + +const + objdata: record size: integer; data: array[0..394] of byte end = + (size: 395; data: ( + 84,80,70,48,7,116,109,97,105,110,102,111,6,109,97,105,110,102,111,8, + 98,111,117,110,100,115,95,120,3,153,0,8,98,111,117,110,100,115,95,121, + 3,240,0,9,98,111,117,110,100,115,95,99,120,3,85,1,9,98,111,117, + 110,100,115,95,99,121,3,166,0,16,99,111,110,116,97,105,110,101,114,46, + 98,111,117,110,100,115,1,2,0,2,0,3,85,1,3,166,0,0,7,111, + 112,116,105,111,110,115,11,7,102,111,95,109,97,105,110,19,102,111,95,116, + 101,114,109,105,110,97,116,101,111,110,99,108,111,115,101,15,102,111,95,97, + 117,116,111,114,101,97,100,115,116,97,116,16,102,111,95,97,117,116,111,119, + 114,105,116,101,115,116,97,116,10,102,111,95,115,97,118,101,112,111,115,12, + 102,111,95,115,97,118,101,115,116,97,116,101,0,15,109,111,100,117,108,101, + 99,108,97,115,115,110,97,109,101,6,8,116,109,115,101,102,111,114,109,0, + 7,116,98,117,116,116,111,110,8,116,98,117,116,116,111,110,49,8,98,111, + 117,110,100,115,95,120,3,144,0,8,98,111,117,110,100,115,95,121,2,72, + 9,98,111,117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95, + 99,121,2,22,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120, + 101,99,117,116,101,0,7,99,97,112,116,105,111,110,6,4,69,120,105,116, + 11,102,111,110,116,46,120,115,99,97,108,101,2,1,10,102,111,110,116,46, + 100,117,109,109,121,2,0,9,111,110,101,120,101,99,117,116,101,7,13,101, + 120,105,116,111,110,101,120,101,99,117,116,101,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tmainfo,''); +end. diff --git a/mseide-msegui/apps/facedemo/facedemo.pas b/mseide-msegui/apps/facedemo/facedemo.pas new file mode 100644 index 0000000..098fa73 --- /dev/null +++ b/mseide-msegui/apps/facedemo/facedemo.pas @@ -0,0 +1,11 @@ +program facedemo; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifdef FPC} + {$ifdef mswindows}{$apptype gui}{$endif} +{$endif} +uses + {$ifdef FPC}{$ifdef unix}cthreads,{$endif}{$endif}msegui,mseforms,main; +begin + application.createform(tmainfo,mainfo); + application.run; +end. diff --git a/mseide-msegui/apps/facedemo/facedemo.prj b/mseide-msegui/apps/facedemo/facedemo.prj new file mode 100644 index 0000000..92abfd2 --- /dev/null +++ b/mseide-msegui/apps/facedemo/facedemo.prj @@ -0,0 +1,1015 @@ +[componentpalette] +order0=0 +order1=0 +order2=0 +order3=0 +order4=0 +order5=0 +order6=0 +order7=0 +order8=0 +order9=0 +order10=0 +order11=0 +order12=0 +order13=0 +order14=0 +order15=0 +order16=0 +order17=0 +order18=0 +[projectoptions] +projectdir=/home/mse/packs/standard/git/mseide-msegui/apps/facedemo +projectfilename=/home/mse/packs/standard/git/mseide-msegui/apps/facedemo/facedemo.prj +mainfile=facedemo.pas +targetfile=facedemo${EXEEXT} +messageoutputfile= +makecommand=${COMPILER} +makedir= +unitdirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}kernel/ + ${MSELIBDIR}*/ +unitpref=-Fu +incpref=-Fi +libpref=-Fl +objpref=-Fo +targpref=-o +befcommand=0 +aftcommand=0 +makeoptions=4 + -Xg -l -Mobjfpc -Sh -Fcutf8 + -gl -O- + -B + -O2 -XX -Xs -CX +codetemplatedirs=1 + ${TEMPLATEDIR} +toolmenus=0 +toolfiles=0 +toolparams=0 +fontnames=0 +scriptbeforecopy= +scriptaftercopy= +newprojectfiles=4 + ${TEMPLATEDIR}default/project.pas + ${TEMPLATEDIR}default/main.pas + ${TEMPLATEDIR}default/main.mfm + ${TEMPLATEDIR}default/main_mfm.pas +newprojectfilesdest=4 + ${%PROJECTNAME%}.pas + + + +newfinames=3 + Program + Unit + Textfile +newfifilters=3 + "*.pas" "*.pp" + "*.pas" "*.pp" + +newfiexts=3 + pas + pas + +newfisources=3 + ${TEMPLATEDIR}default/program.pas + ${TEMPLATEDIR}default/unit.pas + +newfonames=11 + Mainform + Simple Form + Docking Form + Datamodule + Subform + Scrollboxform + Tabform + Dockpanel + Report + Scriptform + Inherited Form +newfonamebases=11 + form + form + form + module + form + form + form + form + report + script + form +newfosources=11 + ${TEMPLATEDIR}default/mainform.pas + ${TEMPLATEDIR}default/simpleform.pas + ${TEMPLATEDIR}default/dockingform.pas + ${TEMPLATEDIR}default/datamodule.pas + ${TEMPLATEDIR}default/subform.pas + ${TEMPLATEDIR}default/scrollboxform.pas + ${TEMPLATEDIR}default/tabform.pas + ${TEMPLATEDIR}default/dockpanelform.pas + ${TEMPLATEDIR}default/report.pas + ${TEMPLATEDIR}default/pascform.pas + ${TEMPLATEDIR}default/inheritedform.pas +newfoforms=11 + ${TEMPLATEDIR}default/mainform.mfm + ${TEMPLATEDIR}default/simpleform.mfm + ${TEMPLATEDIR}default/dockingform.mfm + ${TEMPLATEDIR}default/datamodule.mfm + ${TEMPLATEDIR}default/subform.mfm + ${TEMPLATEDIR}default/scrollboxform.mfm + ${TEMPLATEDIR}default/tabform.mfm + ${TEMPLATEDIR}default/dockpanelform.mfm + ${TEMPLATEDIR}default/report.mfm + ${TEMPLATEDIR}default/pascform.mfm + ${TEMPLATEDIR}default/inheritedform.mfm +forcezorder=0 +stripmessageesc=0 +copymessages=0 +closemessages=1 +checkmethods=1 +colorerror=-1610612712 +colorwarning=-1610612717 +colornote=-1610612716 +usercolors=30 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +usercolorcomment=30 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +formatmacronames=0 +formatmacrovalues=0 +settingsfile= +settingseditor=0 +settingsdebugger=0 +settingsstorage=0 +settingsprojecttree=0 +settingsautoload=0 +settingsautosave=0 +modulenames=1 + MAINFO +moduletypes=1 + TMAINFO +modulefiles=1 + /home/mse/packs/standard/git/mseide-msegui/apps/facedemo/main.mfm +befcommandon=0 +makeoptionson=4 + 63 + 31 + 34 + 32 +aftcommandon=0 +unitdirson=3 + 65599 + 196671 + 65599 +macroon=0 +macronames=0 +macrovalues=0 +macrogroup=0 +groupcomments=6 + + + + + + +toolsave=0 +toolhide=0 +toolparse=0 +toolmessages=0 +toolshortcuts=0 +fontalias=0 +fontancestors=0 +fontheights=0 +fontwidths=0 +fontoptions=0 +fontxscales=0 +expandprojectfilemacros=4 + 1 + 1 + 1 + 0 +loadprojectfile=4 + 1 + 1 + 1 + 0 +newinheritedforms=11 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 +uid=0 +sourcefilemasks=3 + "*.pas" "*.dpr" "*.lpr" "*.pp" "*.inc" + "*.c" "*.cc" "*.h" + "*.mfm" +syntaxdeffiles=3 + ${SYNTAXDEFDIR}pascal.sdef + ${SYNTAXDEFDIR}cpp.sdef + ${SYNTAXDEFDIR}objecttext.sdef +filemasknames=3 + Source + Forms + All Files +filemasks=3 + "*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + *.mfm + * +showgrid=1 +snaptogrid=1 +moveonfirstclick=1 +noformdesignerdocking=0 +gridsizex=8 +gridsizey=8 +autoindent=1 +blockindent=1 +linenumberson=0 +rightmarginon=1 +rightmarginchars=80 +scrollheight=0 +tabstops=4 +spacetabs=0 +showtabs=0 +tabindent=0 +editfontname=mseide_source +editfontheight=0 +editfontwidth=0 +editfontextraspace=0 +editfontcolor=-1879048183 +editbkcolor=-1879048186 +statementcolor=14745599 +editfontantialiased=1 +editmarkbrackets=1 +backupfilecount=2 +encoding=1 +codetemplatedirs=1 + ${TEMPLATEDIR} +debugcommand=${DEBUGGER} +debugoptions= +debugtarget= +runcommand= +xtermcommand=xterm -S${PTSN}/${PTSH} +remoteconnection= +uploadcommand= +gdbprocessor=auto +gdbservercommand= +gdbservercommandattach= +beforeconnect= +afterconnect= +beforeload= +afterload= +beforerun= +sourcebase= +sourcedirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ + ./ +defines=0 +progparameters= +progworkingdirectory= +envvarnames=0 +envvarvalues=0 +defineson=0 +stoponexception=0 +valuehints=1 +activateonbreak=1 +raiseonbreak=1 +showconsole=0 +externalconsole=0 +settty=1 +gdbdownload=0 +downloadalways=0 +startupbkpt=0 +startupbkpton=0 +gdbsimulator=0 +gdbserverstartonce=0 +gdbloadtimeout= +gdbserverwait=0 +nogdbserverexit=0 +gdbservertty=0 +exceptclassnames=1 + EconvertError +exceptignore=1 + 0 +nodebugbeginend=0 +sigsettings=27 + 1,1,T,F + 3,3,T,F + 4,4,T,F + 6,6,T,F + 7,7,T,F + 8,8,T,F + 9,9,T,F + 10,10,T,F + 11,11,T,F + 12,12,T,F + 13,13,T,F + 15,15,T,F + 16,16,T,F + 17,17,F,F + 18,18,T,F + 19,19,T,F + 20,20,T,F + 21,21,T,F + 22,22,T,F + 23,23,T,F + 24,24,T,F + 25,25,T,F + 26,26,T,F + 27,27,T,F + 28,28,T,F + 29,29,T,F + 30,30,T,F +defaultmake=1 +[breakpoints] +on=0 +path=0 +line=0 +address=0 +addbkpt=0 +ignore=0 +condition=0 +panels=2 + panel1 + panel2 +units= + ( + a=0,4132,6,Pascal Units + ) +cmodules= + ( + a=0,4132,6,C Modules + ) +files= + ( + a=0,4132,6,Text Files + ) +[componentstore] +storedir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ +filename= +[components] +[selecteditpage] +colwidth=100 +x=0 +y=0 +cx=0 +cy=0 +[progparams] +progparamhistory=0 +workdirparamhistory=0 +envvarons=0 +[edit] +hintwidth=0 +hintheight=0 +finddtext= +findhistory=0 +findoptions=1 +editpos=2 + 0,0 + 0,-1073741823 +bookmarks0=0 +bookmarks1=0 +sourcefiles=2 + /home/mse/packs/standard/git/mseide-msegui/apps/facedemo/main.pas + /home/mse/packs/standard/git/mseide-msegui/apps/facedemo/facedemo.pas +relpaths=2 + main.pas + facedemo.pas +ismoduletexts=2 + 0 + 0 +modules=1 + /home/mse/packs/standard/git/mseide-msegui/apps/facedemo/main.mfm +moduleoptions=1 + 0 +visiblemodules=1 + -1 +nomenumodules=1 + 0 +[sourcefo.tabwidget] +tabsize=60 +firsttab=0 +index=0 +[layout] +windowlayout=551 + [mainfo.openform] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.projectfiledia] + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + [mainfo.openfile] + filenames=0 + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + filehistory=2 + /home/mse/packs/standard/git/mseide-msegui/apps/facedemo/facedemo.pas + /home/mse/packs/standard/git/mseide-msegui/apps/facedemo/main.pas + filefilterindex=0 + filefilter="*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + [mainfo.basedock] + splitdir=2 + useroptions=146560 + [mainfo] + splitdir=0 + useroptions=33554555 + stackedunder=componentpalettefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=25 + cx=323 + cy=64 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [targetconsolefo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=209 + y=385 + cx=368 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [threadsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=37 + y=270 + cx=349 + cy=276 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo] + splitdir=0 + useroptions=16507 + stackedunder=cpui386fo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=100 + y=100 + cx=453 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo.add] + value=0 + [memoryfo.memon] + value=0 + [memoryfo.bitwidth] + value=0 + [memoryfo.cnt] + value=0 + [disassfo] + splitdir=0 + useroptions=16491 + stackedunder=mainfo.panel1 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=162 + y=502 + cx=564 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [findinfilefo] + splitdir=0 + useroptions=16491 + stackedunder=disassfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=548 + y=115 + cx=369 + cy=198 + rcx=0 + rcy=0 + [projecttreefo] + splitdir=0 + useroptions=16491 + stackedunder=memoryfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=263 + y=431 + cx=286 + cy=201 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [projecttreefo.grid] + propcolwidthref=135 + width0=141 + sortdescend0=0 + width1=129 + sortdescend1=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=16 + [stackfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=295 + rcx=0 + rcy=0 + [watchpointsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=120 + y=368 + cx=483 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [watchpointsfo.grid] + propcolwidthref=352 + sortdescend0=0 + values1=0 + values1_ci=-1 + width1=33 + sortdescend1=0 + values2=0 + width2=158 + sortdescend2=0 + width4=34 + sortdescend4=0 + values5=0 + values5_ci=-1 + width5=38 + sortdescend5=0 + values6=0 + width6=184 + sortdescend6=0 + [breakpointsfo] + splitdir=0 + useroptions=16491 + stackedunder=projecttreefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=107 + y=404 + cx=636 + cy=128 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [breakpointsfo.bkptson] + value=1 + [objectinspectorfo] + splitdir=0 + useroptions=16491 + stackedunder=_mse_mainfo_mse_ + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=724 + y=157 + cx=296 + cy=566 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [objectinspectorfo.grid] + propcolwidthref=286 + width0=105 + sortdescend0=0 + width1=175 + sortdescend1=0 + [symbolfo] + splitdir=0 + useroptions=16507 + stackedunder=findinfilefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=142 + y=257 + cx=361 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [symbolfo.grid] + propcolwidthref=222 + values0=0 + width0=111 + sortdescend0=0 + width1=135 + sortdescend1=0 + [symbolfo.symbol] + [watchfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=298 + cx=313 + cy=236 + rcx=0 + rcy=0 + [watchfo.grid] + propcolwidthref=118 + values0=0 + values0_ci=-1 + sortdescend0=0 + values1=0 + width1=152 + sortdescend1=0 + values3=0 + values3_ci=-1 + sortdescend3=0 + values4=0 + values4_ci=-1 + width4=13 + sortdescend4=0 + [watchfo.watchon] + [watchfo.expression] + [watchfo.watcheson] + value=1 + [messagefo] + splitdir=0 + useroptions=49259 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=510 + cx=675 + cy=95 + rcx=0 + rcy=0 + [componentstorefo] + splitdir=0 + useroptions=24699 + stackedunder=symbolfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=305 + y=101 + cx=445 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentstorefo.grid] + propcolwidthref=435 + width0=111 + sortdescend0=0 + sortdescend1=0 + width2=112 + sortdescend2=0 + width3=185 + sortdescend3=0 + [componentstorefo.storefiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.groupfiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.compfiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentpalettefo] + splitdir=0 + useroptions=24683 + stackedunder=mainfo.panel2 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=25 + cx=685 + cy=103 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [componentpalettefo.componentpages] + activetab=0 + [debuggerfo] + splitdir=0 + useroptions=24683 + parent=mainfo.basedock + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=28 + rcx=0 + rcy=0 + [sourcefo] + splitdir=0 + useroptions=16489 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=675 + cy=507 + rcx=0 + rcy=0 + [actionsmo.watchesonact] + checked=1 + [actionsmo.bluedotsonact] + checked=1 + [cpui386fo] + irqoff=0 + splitdir=0 + useroptions=16491 + stackedunder=componentstorefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=337 + y=295 + cx=273 + cy=207 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [mainfo.panel1] + splitdir=2 + useroptions=33586667 + stackedunder=mainfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=118 + cx=685 + cy=605 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel2] + splitdir=2 + useroptions=33586667 + stackedunder=objectinspectorfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=189 + cx=323 + cy=534 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [_mse_mainfo_mse_] + splitdir=0 + useroptions=16507 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=58 + y=273 + cx=648 + cy=286 + rcx=0 + rcy=0 + wsize=0 + active=1 + visible=1 +[targetconsole] +finddtext= +findhistory=0 +findoptions=1 diff --git a/mseide-msegui/apps/facedemo/main.mfm b/mseide-msegui/apps/facedemo/main.mfm new file mode 100644 index 0000000..1e5b0c1 --- /dev/null +++ b/mseide-msegui/apps/facedemo/main.mfm @@ -0,0 +1,3558 @@ +object mainfo: tmainfo + visible = False + bounds_x = 58 + bounds_y = 273 + bounds_cx = 638 + bounds_cy = 286 + container.frame.levelo = -1 + container.frame.leveli = 1 + container.frame.framewidth = 1 + container.frame.colorframe = 13092491 + container.frame.localprops = [frl_levelo, frl_leveli, frl_framewidth, frl_colorframe] + container.frame.localprops1 = [] + container.face.image.alignment = [al_tiled] + container.face.image.opacity = 8355711 + container.face.image.image = { + 00000000000000009600000096000000380A0100000000000000000000000000 + 0000000000000000000000000000000000000000D8D8D801DBDBDB01DADADA02 + DBDBDB03D9D9D901DADADA01FFFFFF01DADADA02A9A9A901D9D9D901D8D8D801 + A9A9A901DADADA01DBDBDB01D9D9D901D7D7D701D9D9D901DCDCDC01D8D8D801 + DBDBDB01D8D8D801DBDBDB01DDDDDD01D8D8D801DBDBDB01D9D9D901FEFEFE01 + DCDCDC01D9D9D901DBDBDB01DADADA02D9D9D902DCDCDC01DBDBDB01DADADA03 + DCDCDC01DADADA02DCDCDC01DADADA09DBDBDB01DADADA01D9D9D902DADADA02 + DBDBDB01D9D9D902DBDBDB02D7D7D701DDDDDD01D9D9D902DBDBDB01DADADA01 + D9D9D901DADADA01D8D8D801DDDDDD01DBDBDB01DADADA01D9D9D901DBDBDB01 + FEFEFE02FFFFFF01A7A7A701DBDBDB01FFFFFF01DADADA01FFFFFF01FDFDFD01 + DADADA01A7A7A702FFFFFF01FEFEFE01FFFFFF01D8D8D801ABABAB01D9D9D902 + DADADA01FFFFFF01D9D9D901A9A9A901D8D8D801DCDCDC01D8D8D801FDFDFD01 + FFFFFF01DADADA01D9D9D902FFFFFF01D8D8D801DADADA01DBDBDB01DADADA01 + D9D9D901DBDBDB01DADADA09DCDCDC01A7A7A701A5A5A501A9A9A901D9D9D901 + DBDBDB01D9D9D901DADADA0FDDDDDD01D8D8D801DADADA01DDDDDD01D5D5D502 + DBDBDB02DADADA01FFFFFF01D8D8D801DBDBDB03D9D9D901DADADA02D7D7D701 + DADADA01DFDFDF01DBDBDB01DADADA03DBDBDB01DCDCDC01D4D4D401DFDFDF01 + DADADA01A8A8A801FFFFFF01D7D7D701DADADA01DBDBDB01DADADA01D9D9D901 + DCDCDC02D7D7D702D9D9D901D8D8D801DBDBDB01D9D9D902D8D8D801D9D9D901 + DADADA09D8D8D801DBDBDB01DDDDDD01DCDCDC01D8D8D801DDDDDD01D6D6D601 + DCDCDC01DADADA01DCDCDC01D8D8D801DBDBDB01DADADA01D9D9D901DADADA01 + DCDCDC02DADADA01DCDCDC01DADADA01D7D7D701D9D9D901D7D7D701DEDEDE01 + D8D8D801FFFFFF02FCFCFC01DADADA01FFFFFF01FDFDFD02FCFCFC01FFFFFF02 + AAAAAA01A8A8A801FEFEFE01FFFFFF01FBFBFB01DADADA01DCDCDC01D8D8D801 + DFDFDF01D9D9D901FDFDFD01DADADA01A7A7A701D9D9D901DADADA01DBDBDB01 + FFFFFF01FAFAFA01DADADA01DBDBDB02FCFCFC01FFFFFF01DADADA01D7D7D701 + DBDBDB01DADADA01D9D9D901DADADA09DBDBDB01A8A8A802ABABAB01A7A7A702 + DBDBDB01D9D9D901DADADA0ED9D9D901DADADA01D9D9D902DCDCDC01DEDEDE01 + DCDCDC01D9D9D901DADADA01DCDCDC01FFFFFF01D8D8D802FEFEFE01E0E0E001 + D7D7D701DBDBDB01D9D9D901AEAEAE01D4D4D401DADADA01A9A9A901D8D8D801 + DCDCDC01DADADA01D9D9D901DDDDDD01D8D8D801D5D5D501DDDDDD01DADADA02 + D9D9D901DCDCDC01A8A8A801DBDBDB01DADADA01D7D7D701DDDDDD02DBDBDB01 + D9D9D901DCDCDC01D9D9D901DDDDDD01DCDCDC01D9D9D901DADADA09DBDBDB01 + D9D9D901D7D7D701D8D8D801DADADA01D9D9D901DCDCDC01D7D7D701D8D8D801 + DCDCDC01D7D7D701DADADA02DCDCDC01D6D6D601D9D9D901D7D7D701DADADA03 + DCDCDC01D8D8D801DEDEDE01D5D5D501DBDBDB01D8D8D801FCFCFC01FFFFFF01 + DADADA01FDFDFD01DFDFDF01DADADA01FDFDFD01FFFFFF01D8D8D802DCDCDC01 + D8D8D802FFFFFF01DBDBDB01D9D9D901DBDBDB01D6D6D601D9D9D901FFFFFF01 + DDDDDD01A8A8A802DBDBDB01DADADA01D8D8D801DDDDDD01D9D9D902FFFFFF01 + FDFDFD02DCDCDC01DBDBDB01D9D9D901DBDBDB01DADADA01D9D9D901DADADA08 + D8D8D801DCDCDC01A9A9A901A5A5A501A6A6A601AAAAAA01A7A7A701AAAAAA01 + DADADA0FDCDCDC01DADADA01D8D8D801DBDBDB01D8D8D801D4D4D401DADADA01 + D9D9D901DADADA01A9A9A901D9D9D901DDDDDD01D8D8D801D6D6D601DDDDDD01 + D6D6D601DDDDDD01D7D7D701DCDCDC01DDDDDD01DBDBDB01DADADA02DCDCDC01 + D8D8D801A8A8A801FFFFFF01DBDBDB01D9D9D901DCDCDC01DADADA02AAAAAA01 + A6A6A601D7D7D701DBDBDB02D9D9D901D7D7D701DCDCDC01DBDBDB01D9D9D901 + D7D7D701D9D9D902D8D8D801DADADA09D8D8D801DBDBDB01DCDCDC02DADADA02 + D9D9D901DDDDDD01DADADA01D9D9D901DBDBDB02DADADA02DCDCDC01DBDBDB01 + D9D9D901DADADA02DCDCDC01D6D6D601DDDDDD01DBDBDB01DCDCDC01D8D8D801 + DBDBDB01D8D8D801DDDDDD01D7D7D701DEDEDE01D8D8D801D9D9D901DADADA01 + FFFFFF01FEFEFE01D6D6D601DEDEDE01D8D8D801DBDBDB01D9D9D903DDDDDD02 + DBDBDB01FEFEFE01DADADA01D8D8D801AAAAAA01A7A7A701A8A8A801DBDBDB01 + D9D9D901DCDCDC01D9D9D901DBDBDB01FFFFFF01FDFDFD01FCFCFC01DADADA01 + DDDDDD01D8D8D801DCDCDC01DADADA09DCDCDC01D9D9D902DDDDDD01A8A8A801 + ABABAB01A6A6A601D8D8D801DADADA0ED9D9D901D8D8D801DCDCDC01DADADA01 + D9D9D901DEDEDE01DCDCDC01D8D8D801DCDCDC01A7A7A702DBDBDB01D9D9D901 + DEDEDE01D9D9D901D8D8D801FFFFFF01DCDCDC01DBDBDB01FFFFFF01A4A4A401 + D9D9D901DBDBDB01D8D8D801D9D9D901DBDBDB01D7D7D701DBDBDB01D9D9D901 + D7D7D701DADADA01D9D9D901FFFFFF01D7D7D701DCDCDC01D9D9D901DDDDDD01 + D9D9D901D8D8D801DDDDDD01D6D6D601DCDCDC01D9D9D901DDDDDD01DBDBDB01 + DADADA01DCDCDC02DADADA08DEDEDE01D6D6D601D9D9D901DADADA01D9D9D901 + DADADA01D9D9D901A8A8A801D9D9D901DADADA01DBDBDB01D8D8D802DADADA01 + A9A9A901D9D9D901DCDCDC01DADADA01D6D6D601DCDCDC02D7D7D701DADADA01 + D8D8D801DBDBDB01DADADA01DBDBDB01D8D8D801DADADA01D9D9D901D8D8D801 + AAAAAA01FDFDFD01DADADA01DCDCDC01DADADA03DBDBDB01D9D9D901DDDDDD01 + DADADA01A3A3A301DDDDDD01DADADA01FEFEFE01FFFFFF01DCDCDC01D8D8D801 + A8A8A801D8D8D802D9D9D901DCDCDC01D8D8D801DBDBDB01FDFDFD01FFFFFF02 + FEFEFE01D8D8D801DBDBDB01D7D7D701DCDCDC01DADADA09D9D9D901DBDBDB01 + D6D6D601DBDBDB01D8D8D801DCDCDC02DADADA10DCDCDC01D7D7D701D8D8D801 + DADADA01D7D7D701DCDCDC01FFFFFF01D6D6D601ABABAB01DBDBDB01A5A5A501 + A7A7A701AAAAAA01A9A9A901DADADA01D8D8D802DBDBDB03DADADA01DBDBDB01 + FFFFFF01DCDCDC01DADADA01DBDBDB01DDDDDD01D9D9D901DBDBDB01FDFDFD01 + FFFFFF01A6A6A601DDDDDD01D6D6D601D8D8D801DBDBDB02D8D8D801DCDCDC01 + DBDBDB01D9D9D901DBDBDB01D9D9D902DBDBDB01D7D7D701DADADA08D8D8D801 + DCDCDC01D9D9D902DDDDDD01DADADA01D7D7D701D9D9D901DBDBDB01DADADA01 + D9D9D901DBDBDB01D7D7D701DDDDDD01D8D8D802D7D7D701DBDBDB02DADADA01 + D9D9D901DADADA01D9D9D901DCDCDC01DBDBDB01DADADA02D8D8D801DBDBDB01 + DDDDDD01D9D9D901DADADA02A6A6A601D9D9D901A6A6A601D8D8D801DEDEDE01 + DADADA01DBDBDB01A7A7A701A9A9A902A7A7A702D9D9D901FFFFFF01FEFEFE01 + FFFFFF01DBDBDB03DFDFDF01D6D6D601A9A9A901A7A7A702DBDBDB01FEFEFE01 + FFFFFF01DBDBDB01DCDCDC01D8D8D801DBDBDB01DADADA08DCDCDC01D9D9D901 + DCDCDC01DADADA01D8D8D801A9A9A901D9D9D901D8D8D801DADADA0EDBDBDB01 + D8D8D801DADADA01DBDBDB01DEDEDE01D7D7D701DCDCDC01FEFEFE01FFFFFF01 + DBDBDB01D8D8D801DADADA01DBDBDB01DADADA01DCDCDC01A6A6A601A8A8A802 + FFFFFF01DCDCDC01D7D7D701DADADA01D9D9D901DADADA01DBDBDB01D8D8D802 + DBDBDB01D6D6D601DADADA04D8D8D801D9D9D901DBDBDB01DCDCDC01D9D9D902 + DBDBDB01DCDCDC01D3D3D301DFDFDF01D8D8D801D9D9D901DADADA01DDDDDD01 + DCDCDC01DADADA0BD9D9D902FFFFFF01D7D7D701DBDBDB01D8D8D801DADADA01 + DCDCDC01D8D8D801FFFFFF01D9D9D902DDDDDD01DCDCDC01D7D7D701DADADA01 + DEDEDE01D7D7D701DBDBDB01A8A8A801A6A6A601A8A8A802DADADA02DCDCDC01 + FCFCFC01D7D7D701DDDDDD01DADADA01A8A8A801DCDCDC01DDDDDD01D7D7D701 + D9D9D901DADADA01D9D9D901DADADA01A7A7A702AAAAAA01A7A7A701DADADA01 + DDDDDD01FEFEFE01D8D8D801DDDDDD01A7A7A701D7D7D701D6D6D601A7A7A701 + ADADAD01D9D9D902DBDBDB01FDFDFD01FEFEFE01DCDCDC01D7D7D701DDDDDD01 + D8D8D801DADADA08D7D7D701DCDCDC01D7D7D701DADADA01DEDEDE01D8D8D801 + DBDBDB01DCDCDC01DADADA0FD9D9D901DCDCDC01D8D8D801DADADA01DDDDDD01 + D8D8D801DCDCDC01FCFCFC01DADADA01FFFFFF01FEFEFE01FFFFFF02D8D8D801 + DCDCDC01DADADA02A7A7A701A8A8A801D9D9D901DCDCDC01DADADA02A7A7A701 + A9A9A901DBDBDB01DADADA01D9D9D901DCDCDC01D9D9D901FFFFFF01DADADA03 + DBDBDB01D9D9D901DADADA01DBDBDB01D9D9D901A7A7A701ABABAB01DADADA01 + D9D9D901DDDDDD01D9D9D903DADADA08DCDCDC01D9D9D901DADADA01DCDCDC01 + D8D8D801D9D9D901DCDCDC01DADADA01DBDBDB02D9D9D901DBDBDB01D9D9D902 + DCDCDC01D9D9D902DCDCDC01D9D9D902DADADA01A6A6A601A9A9A901A8A8A803 + DADADA01D9D9D901DADADA01DCDCDC02FDFDFD01DBDBDB01FCFCFC01DADADA01 + D9D9D901DBDBDB01DCDCDC01FDFDFD01FFFFFF01DBDBDB01D8D8D801DDDDDD01 + A6A6A601DADADA01DBDBDB01D8D8D801DBDBDB01DCDCDC01D8D8D801D9D9D901 + DEDEDE01D7D7D701FFFFFF01D8D8D801FFFFFF01DCDCDC01D7D7D701FFFFFF02 + FAFAFA01DFDFDF01FCFCFC01FFFFFF01DADADA09DBDBDB01D8D8D801FFFFFF01 + D9D9D901DBDBDB01D9D9D901DADADA10D9D9D903DBDBDB02DADADA01D9D9D901 + DBDBDB01D8D8D801DBDBDB01DCDCDC01D9D9D901FFFFFF01FEFEFE01FFFFFF01 + DBDBDB02A6A6A601DBDBDB01A8A8A801DADADA01DCDCDC01DADADA01A9A9A901 + A6A6A601DADADA01D9D9D901DADADA01D9D9D901DBDBDB01D9D9D901DADADA01 + DBDBDB01D8D8D801DBDBDB03D7D7D701A9A9A901A7A7A701ABABAB01A5A5A501 + DADADA05DCDCDC01D9D9D901DDDDDD01D8D8D801DADADA02DBDBDB03DADADA01 + D9D9D901DDDDDD01D6D6D601DCDCDC01D8D8D801DCDCDC02D9D9D901DADADA01 + D8D8D801DADADA01DBDBDB02DADADA01D8D8D801DEDEDE01D9D9D901DBDBDB01 + FFFFFF01DBDBDB01D8D8D801DCDCDC01A7A7A701DDDDDD01D9D9D902DBDBDB01 + A7A7A701AAAAAA01FDFDFD01A8A8A801A9A9A901DADADA01D9D9D901DCDCDC01 + A7A7A701D9D9D901FFFFFF01D8D8D801DBDBDB01DADADA01A9A9A901DADADA01 + D9D9D901DEDEDE01A7A7A701D8D8D801AAAAAA01D8D8D801FEFEFE01FFFFFF01 + DADADA01D9D9D901DCDCDC01DBDBDB01DADADA01FEFEFE01FFFFFF03FDFDFD01 + FFFFFF02D9D9D901DADADA02D9D9D901DDDDDD01D7D7D701DCDCDC01FFFFFF01 + FEFEFE01D8D8D801DDDDDD01D9D9D901DADADA01DBDBDB01DADADA01DBDBDB01 + D9D9D901DBDBDB01D9D9D902DDDDDD01D8D8D801D9D9D902DBDBDB01DADADA01 + DCDCDC01D8D8D801DBDBDB01DADADA01DCDCDC01DDDDDD01DCDCDC01D8D8D802 + DADADA02A8A8A801DBDBDB01D8D8D801DADADA01D9D9D901DADADA01DEDEDE01 + D7D7D701FEFEFE01FFFFFF01DDDDDD01DADADA03FBFBFB01FFFFFF01DCDCDC01 + A7A7A701DCDCDC01DDDDDD01D5D5D501DFDFDF01D7D7D701DADADA01DBDBDB01 + D8D8D801D9D9D901DADADA01DBDBDB01D8D8D801FFFFFF02D8D8D801D7D7D701 + DDDDDD01D9D9D901DADADA02DBDBDB01D9D9D902D7D7D701DBDBDB01DADADA03 + DBDBDB01A6A6A602DBDBDB01DADADA01D8D8D801DCDCDC02D8D8D801D9D9D903 + DADADA01DEDEDE01D9D9D901D8D8D801DADADA01D9D9D901ACACAC01A3A3A301 + A7A7A701D9D9D901DADADA02FEFEFE01FFFFFF01A6A6A601DDDDDD01A5A5A501 + DBDBDB01A5A5A501A8A8A801A7A7A702DADADA01D9D9D901DCDCDC01DADADA01 + DBDBDB01A8A8A801D8D8D801D9D9D901FFFFFF01DBDBDB01A8A8A801A4A4A401 + D9D9D901DADADA01D6D6D601A9A9A901ACACAC01A7A7A701FDFDFD01DCDCDC01 + FFFFFF01DADADA01D9D9D902DADADA01D8D8D801DEDEDE01FDFDFD01DCDCDC01 + D9D9D901FFFFFF01FCFCFC02DBDBDB01DADADA01D8D8D801FFFFFF03FCFCFC01 + FDFDFD01DCDCDC02DADADA01D8D8D801D9D9D902DADADA01D7D7D701DBDBDB01 + D7D7D701DDDDDD01D8D8D801DCDCDC01D7D7D701DDDDDD01DADADA01DCDCDC01 + D9D9D901D7D7D701DBDBDB01D8D8D801D9D9D901D8D8D802D6D6D601DCDCDC01 + DEDEDE01D6D6D601DADADA02A7A7A701DFDFDF01DCDCDC01D9D9D901D8D8D801 + D9D9D901DADADA01FFFFFF01D8D8D801FFFFFF01D9D9D901DADADA01DDDDDD01 + FFFFFF02D7D7D701DBDBDB01DADADA01D7D7D701DDDDDD01D6D6D601DBDBDB02 + D8D8D801DCDCDC01DADADA01DBDBDB01D6D6D601FFFFFF04D7D7D701A7A7A701 + DBDBDB01D8D8D801D9D9D901DADADA01D9D9D901DBDBDB01DADADA01D9D9D901 + DCDCDC01D8D8D801D9D9D901DBDBDB01AAAAAA01ABABAB01DBDBDB01D9D9D901 + DADADA01DBDBDB01DADADA01DBDBDB01DADADA01DCDCDC01D9D9D902DBDBDB01 + D8D8D801DCDCDC01D8D8D801ABABAB01A9A9A901A7A7A701ABABAB01DADADA01 + FFFFFF03DADADA01A9A9A901D6D6D601DBDBDB01FFFFFF02AAAAAA01D9D9D901 + FFFFFF01DBDBDB01D8D8D801DBDBDB01FFFFFF01FDFDFD01AAAAAA01DBDBDB01 + FEFEFE02FDFDFD01DBDBDB01D8D8D801E0E0E001FDFDFD01FFFFFF02D8D8D801 + DADADA01DCDCDC01DADADA01D4D4D401DCDCDC01DEDEDE01DADADA01D8D8D801 + DEDEDE01D8D8D801DADADA01D9D9D901DCDCDC01DBDBDB01FFFFFF01DEDEDE01 + D8D8D801DADADA01DDDDDD01FEFEFE01D6D6D601D9D9D901DCDCDC02DADADA01 + D9D9D901D8D8D801DADADA01DBDBDB01DADADA02DCDCDC01D9D9D901A8A8A801 + DADADA01DDDDDD01DADADA01D9D9D901DADADA01D9D9D901DADADA01DCDCDC01 + DBDBDB01DCDCDC01E0E0E001DDDDDD01DBDBDB02DADADA01DCDCDC01D6D6D601 + FFFFFF01DBDBDB01A7A7A701ABABAB01D7D7D701D9D9D901DADADA01DCDCDC01 + D7D7D701DCDCDC01D9D9D901DADADA01D8D8D801DEDEDE01D8D8D802D9D9D901 + FEFEFE01DADADA01D8D8D801DEDEDE01DBDBDB01D8D8D801DCDCDC01DBDBDB01 + D8D8D801DBDBDB01D8D8D801DBDBDB01DADADA01DCDCDC01D9D9D902D8D8D801 + D5D5D501DBDBDB02DCDCDC01DBDBDB01D8D8D801DEDEDE01D9D9D901DADADA01 + DCDCDC01D9D9D901D8D8D801DBDBDB01FFFFFF01FEFEFE01D8D8D801D7D7D701 + DADADA01D9D9D901DDDDDD01D8D8D801D9D9D901DBDBDB02D7D7D701DADADA01 + DBDBDB01D9D9D901DCDCDC01DDDDDD01FCFCFC01DADADA01D7D7D701DEDEDE01 + D9D9D901D7D7D701DBDBDB01D8D8D801FFFFFF01D9D9D901FFFFFF01D9D9D901 + FEFEFE02FCFCFC02DBDBDB01D8D8D802DFDFDF01D9D9D902DCDCDC01FAFAFA01 + DEDEDE01FFFFFF03D8D8D801DCDCDC01D9D9D901FEFEFE02D8D8D801A9A9A901 + AAAAAA01DADADA01A9A9A901ACACAC01D9D9D901DADADA01D8D8D801DCDCDC01 + D4D4D401DDDDDD02D7D7D701DCDCDC01A5A5A501D9D9D901D7D7D701DADADA01 + A8A8A801D9D9D901D8D8D801DEDEDE01DADADA01D9D9D901D8D8D801D7D7D701 + DDDDDD01DEDEDE01D8D8D801DBDBDB01D7D7D701DADADA01D7D7D701DCDCDC01 + D8D8D801DBDBDB01D6D6D601D9D9D901DCDCDC01DADADA02D8D8D801DBDBDB01 + D8D8D802D9D9D901D7D7D701D8D8D801DCDCDC01DADADA01D9D9D901DCDCDC01 + DADADA01FDFDFD01A9A9A901A7A7A701DADADA01DEDEDE01DADADA01D9D9D901 + DCDCDC01D9D9D901DADADA01DCDCDC01D8D8D802DCDCDC01DADADA02DCDCDC02 + DBDBDB01D7D7D701DBDBDB03D8D8D801DADADA01D9D9D901DCDCDC01D5D5D501 + DADADA01D9D9D901DCDCDC01DADADA02FFFFFF01D9D9D901DCDCDC01D8D8D801 + DADADA01DCDCDC01D7D7D701DADADA01D8D8D802DCDCDC01DADADA01D9D9D901 + FFFFFF01FDFDFD01DEDEDE02D9D9D901DBDBDB01DADADA01D9D9D901DCDCDC01 + D7D7D701DADADA01DCDCDC01DBDBDB01DADADA01D8D8D801DBDBDB01FDFDFD01 + DEDEDE01D9D9D902DADADA01A7A7A701DBDBDB01AAAAAA02FEFEFE01DADADA01 + D7D7D701DADADA01DCDCDC01FDFDFD01FFFFFF01DADADA01DDDDDD01DBDBDB01 + DADADA01D9D9D901A8A8A801DADADA01DEDEDE01DADADA01A7A7A701D7D7D702 + D9D9D901DCDCDC01A8A8A801D9D9D901DBDBDB01DADADA01AAAAAA01D7D7D701 + DBDBDB01D7D7D701A7A7A701D9D9D901DADADA02DCDCDC01DADADA01DEDEDE01 + D9D9D903DBDBDB01DCDCDC02DEDEDE01D9D9D901AAAAAA01FDFDFD01DADADA02 + DCDCDC01DADADA01DCDCDC01D9D9D901DBDBDB01D7D7D701DCDCDC01DADADA01 + D8D8D801DCDCDC01FFFFFF01D7D7D701DCDCDC01DADADA01DBDBDB01DCDCDC01 + D8D8D801DADADA01DCDCDC01D9D9D901DBDBDB01DADADA01D9D9D901DBDBDB02 + DADADA03D8D8D801D9D9D901FFFFFF02D8D8D801E0E0E001D7D7D702D8D8D801 + DADADA01DCDCDC01D9D9D901DADADA02DBDBDB01DCDCDC01D9D9D901AAAAAA01 + D9D9D901D8D8D801D7D7D701DFDFDF01DADADA02D9D9D903DCDCDC01DADADA02 + DEDEDE01DADADA01DBDBDB01D9D9D901D7D7D701DDDDDD01DADADA01D7D7D701 + DDDDDD01D7D7D701DDDDDD01D7D7D701D9D9D901DDDDDD01DBDBDB01D9D9D901 + DBDBDB01DADADA01D8D8D801DADADA02D6D6D601D8D8D801D9D9D901DADADA02 + D9D9D901DBDBDB01DADADA01D9D9D901D8D8D801DBDBDB01D9D9D901DDDDDD01 + D5D5D501FFFFFF02FDFDFD01FFFFFF02DBDBDB01D7D7D701DBDBDB01D4D4D401 + ABABAB01A8A8A801A9A9A901AAAAAA01A3A3A301DDDDDD01DADADA01DDDDDD01 + D6D6D601D9D9D901DCDCDC01FFFFFF02A8A8A801AAAAAA01A6A6A601A9A9A901 + ABABAB01DEDEDE01D8D8D801D9D9D903DCDCDC01FFFFFF01D8D8D801A8A8A801 + DBDBDB01FFFFFF01DCDCDC01DBDBDB01A7A7A701A8A8A801D9D9D901A7A7A701 + D9D9D902DADADA01FFFFFF01D8D8D801FDFDFD01FEFEFE01D7D7D701A9A9A901 + A8A8A801DADADA01A8A8A801D9D9D901D8D8D801DADADA01D9D9D902D8D8D801 + DADADA01D7D7D701D9D9D901DEDEDE01D7D7D701A7A7A701DADADA02D8D8D801 + DCDCDC01DBDBDB01D9D9D901DBDBDB01D9D9D901A9A9A901DADADA01D9D9D901 + DBDBDB02DADADA01D9D9D901DBDBDB01DADADA01DDDDDD01D9D9D901DADADA01 + D9D9D902D8D8D801A8A8A801DEDEDE01DCDCDC01DBDBDB01D7D7D701DCDCDC01 + D8D8D801DDDDDD01D9D9D901D7D7D701DBDBDB01A6A6A601DCDCDC02DADADA01 + DBDBDB01D6D6D601DBDBDB01DEDEDE01DBDBDB01D8D8D801DBDBDB01D8D8D801 + DDDDDD01D8D8D802DDDDDD01D6D6D601DEDEDE01D7D7D701DADADA01D9D9D901 + DCDCDC01DADADA01D8D8D801DDDDDD01DADADA01D8D8D801DADADA01DDDDDD01 + D8D8D801D6D6D601DDDDDD01D9D9D902DDDDDD02DADADA01D9D9D901DBDBDB01 + D9D9D902DEDEDE01DADADA01DBDBDB01D9D9D901DBDBDB01D8D8D801FFFFFF02 + FEFEFE01FFFFFF01FBFBFB01DADADA01FCFCFC01FFFFFF01DBDBDB01DDDDDD01 + A6A6A601A9A9A901A5A5A501AAAAAA02A5A5A501A9A9A901DADADA01D9D9D901 + DEDEDE01FEFEFE02D9D9D901A7A7A701FFFFFF01DADADA01DCDCDC01D6D6D601 + D9D9D901D8D8D801DDDDDD02D8D8D801FEFEFE01D9D9D901DBDBDB01A9A9A901 + DADADA01DBDBDB01D8D8D801D9D9D901AAAAAA01A6A6A601AAAAAA01A8A8A801 + DBDBDB01DCDCDC01D6D6D601FFFFFF03DADADA01FFFFFF01DADADA03DBDBDB02 + DADADA01DDDDDD01DADADA01DBDBDB01DADADA01DCDCDC01DADADA01DCDCDC01 + D7D7D701DCDCDC01D9D9D901DDDDDD01D9D9D902DADADA01D6D6D601DBDBDB03 + A7A7A701A6A6A601DFDFDF01D6D6D601DBDBDB01DADADA03D9D9D902DCDCDC01 + D7D7D701DCDCDC02DADADA01D9D9D901A7A7A701DCDCDC01D8D8D801DADADA02 + DDDDDD01D6D6D601DBDBDB01FFFFFF01DADADA01D6D6D601DEDEDE01D7D7D701 + DCDCDC01D8D8D801DDDDDD01DADADA01D7D7D701DCDCDC01D9D9D901DBDBDB01 + DADADA01D7D7D701DBDBDB02DADADA01DCDCDC01D7D7D701DBDBDB01D9D9D901 + DCDCDC01D8D8D801D9D9D901DCDCDC01D8D8D802DCDCDC01D9D9D902DBDBDB01 + DCDCDC01D7D7D701DCDCDC01DADADA01D9D9D901DADADA01D9D9D901DBDBDB01 + DADADA03D9D9D902DADADA01DCDCDC01DADADA01D9D9D901DBDBDB01D8D8D801 + DBDBDB02DADADA01DCDCDC01DBDBDB01D9D9D901FEFEFE02FFFFFF01FEFEFE01 + DADADA01A9A9A901A6A6A601AAAAAA01A6A6A601AAAAAA01A8A8A801A6A6A601 + A9A9A901DBDBDB01DADADA01FFFFFF02FEFEFE01D9D9D901DCDCDC01D9D9D901 + DDDDDD01D9D9D901FCFCFC01DCDCDC01FFFFFF03DADADA01A8A8A801A7A7A701 + FFFFFF01D9D9D901A8A8A801D9D9D901DBDBDB01A8A8A801A9A9A901D9D9D901 + FFFFFF01DCDCDC01A7A7A701D9D9D901FFFFFF02D8D8D801FFFFFF01DDDDDD01 + D8D8D801DADADA02D8D8D801D9D9D901DCDCDC01D9D9D901DADADA01D9D9D901 + DCDCDC01FDFDFD01DADADA01DBDBDB01D8D8D801D9D9D901DCDCDC01DADADA01 + DEDEDE01DADADA01FDFDFD01DADADA06D9D9D901D8D8D801D9D9D901DCDCDC01 + FFFFFF02DCDCDC01D9D9D901FEFEFE01DDDDDD01D8D8D801A7A7A701DADADA01 + DDDDDD01DADADA01D9D9D901DADADA01A9A9A901A8A8A801D7D7D701DDDDDD01 + D9D9D901DADADA01DBDBDB01DADADA10D8D8D801D9D9D901DBDBDB02DADADA02 + D9D9D901DCDCDC01DBDBDB01D8D8D801DADADA01DBDBDB01D9D9D901DADADA02 + D9D9D901DADADA08D9D9D901DBDBDB01DADADA03DBDBDB01DADADA02DBDBDB01 + D8D8D801DBDBDB02FEFEFE01FFFFFF02FEFEFE01FFFFFF02D8D8D801AAAAAA01 + A7A7A701A8A8A801AAAAAA01A6A6A601DBDBDB01D8D8D801A9A9A901A7A7A701 + D8D8D801DCDCDC01D7D7D701FFFFFF01DADADA01DCDCDC01D9D9D901D8D8D801 + DEDEDE01A9A9A901D8D8D801FFFFFF01D9D9D902A9A9A901FEFEFE01DADADA01 + FFFFFF02A5A5A501A9A9A901A8A8A802A6A6A601A9A9A901DBDBDB01A9A9A902 + DADADA01D7D7D701DCDCDC01DBDBDB01D8D8D801DCDCDC01D8D8D801DBDBDB01 + DADADA08D9D9D901DCDCDC01D9D9D901DADADA01DBDBDB01D8D8D801D9D9D901 + FFFFFF01FEFEFE01DEDEDE01D7D7D701DADADA02DBDBDB01DCDCDC01DEDEDE01 + D9D9D901D7D7D701DADADA01A5A5A501DCDCDC01D8D8D801DADADA01FFFFFF01 + DBDBDB01A9A9A901D9D9D901D4D4D401DCDCDC02D9D9D902D8D8D801DFDFDF01 + D7D7D701DADADA01DDDDDD01D8D8D801DADADA10DCDCDC01DDDDDD01DBDBDB01 + D7D7D701D9D9D901DADADA01DDDDDD01D8D8D801DADADA01DDDDDD01DBDBDB01 + D9D9D903DCDCDC02DADADA08DDDDDD01D7D7D701DBDBDB01DCDCDC01D8D8D801 + D9D9D903DBDBDB01DCDCDC01D6D6D601DDDDDD01D7D7D701DBDBDB01FDFDFD01 + FFFFFF02FDFDFD02FFFFFF02FCFCFC01FFFFFF01DADADA01D9D9D901A9A9A901 + A8A8A802DADADA02DEDEDE01D7D7D701DADADA01D7D7D701DBDBDB02A6A6A601 + A3A3A301A9A9A901DBDBDB01FFFFFF01D9D9D901D8D8D801DDDDDD01FDFDFD01 + DCDCDC01F9F9F901FFFFFF01A4A4A401ABABAB01A8A8A801DDDDDD01D9D9D901 + A7A7A703DCDCDC01DADADA01D9D9D904DBDBDB01D9D9D901DADADA0ADBDBDB01 + D9D9D901DCDCDC01DADADA01DEDEDE01D7D7D701DDDDDD01D4D4D401DADADA01 + DBDBDB01D8D8D801DBDBDB01D6D6D601DBDBDB01DADADA01DCDCDC01DBDBDB01 + D9D9D902DDDDDD01A7A7A701FEFEFE01A5A5A501AAAAAA01DADADA01E0E0E001 + D5D5D501FFFFFF02FDFDFD01DCDCDC01D9D9D901DBDBDB01DADADA01D9D9D901 + DDDDDD01DADADA10D9D9D901D5D5D501D9D9D901DEDEDE01DADADA01D6D6D601 + DDDDDD01D8D8D801D7D7D701DADADA01D7D7D701DBDBDB01DEDEDE01D9D9D901 + D8D8D801DADADA09D5D5D501DDDDDD01DADADA01D9D9D901DBDBDB02D8D8D801 + DDDDDD01D6D6D601DADADA01DDDDDD01DADADA02DBDBDB01D9D9D901DBDBDB01 + FDFDFD01FFFFFF02FDFDFD01FFFFFF01FDFDFD01FFFFFF02D8D8D801DBDBDB01 + A8A8A801D8D8D801DFDFDF01D7D7D701A5A5A501DCDCDC01DBDBDB01D9D9D901 + DCDCDC01FEFEFE01DBDBDB01ABABAB01A9A9A901A8A8A801D9D9D901A9A9A901 + DBDBDB01A7A7A701AAAAAA01D8D8D801FFFFFF01FEFEFE01DCDCDC01D9D9D901 + FDFDFD01DADADA01DBDBDB01D8D8D801A9A9A901AAAAAA01A5A5A501AAAAAA01 + D9D9D901DADADA01DCDCDC01DEDEDE01D6D6D601DCDCDC01DADADA08D9D9D901 + D8D8D801DCDCDC01A7A7A701DADADA01DBDBDB01D5D5D501DEDEDE01D8D8D802 + DFDFDF01DBDBDB01D9D9D901DCDCDC01A9A9A901A7A7A701DCDCDC01FCFCFC01 + DBDBDB01DCDCDC01DADADA01D7D7D701A8A8A801E0E0E001A7A7A702D9D9D901 + D8D8D801ABABAB01A7A7A701A6A6A601DADADA02D9D9D901DBDBDB01DADADA01 + D9D9D902DADADA10DBDBDB01DEDEDE01DADADA01D7D7D701DCDCDC01DBDBDB01 + D8D8D801DADADA01DDDDDD01DBDBDB01DADADA02DBDBDB01D9D9D902DBDBDB01 + DADADA08DBDBDB01D9D9D902DCDCDC01D6D6D601DADADA01D9D9D902DEDEDE01 + D9D9D901A8A8A801A6A6A601A8A8A801AAAAAA01D9D9D901D8D8D801D7D7D701 + DEDEDE01DBDBDB01D9D9D901A8A8A801FFFFFF01FEFEFE01FFFFFF01DEDEDE01 + D9D9D901A8A8A802ABABAB01D7D7D701DCDCDC01D9D9D901DCDCDC01DBDBDB01 + FDFDFD01D9D9D901DCDCDC01D6D6D601A8A8A802DCDCDC01D9D9D901A8A8A801 + A9A9A901D9D9D901A8A8A801DADADA02FFFFFF01D8D8D801FFFFFF03DADADA01 + AAAAAA01A4A4A401A8A8A801D9D9D901AAAAAA01DBDBDB01DADADA01D6D6D601 + DADADA01D9D9D901DADADA08DDDDDD01DADADA02D8D8D801DBDBDB01D9D9D901 + DEDEDE01D8D8D801DCDCDC01DADADA02D7D7D701D9D9D901DCDCDC01DADADA01 + D8D8D801DBDBDB01DADADA01D9D9D901D8D8D801FFFFFF01DBDBDB01DADADA01 + D6D6D601A8A8A801AAAAAA01DADADA02A9A9A903DCDCDC01DADADA02DBDBDB01 + D8D8D801DADADA01DDDDDD01DADADA10D8D8D802DBDBDB01DADADA01D7D7D701 + DCDCDC01D9D9D901DBDBDB01D9D9D901D8D8D801DDDDDD01DADADA01D7D7D701 + DCDCDC02D9D9D901DADADA08DCDCDC01D7D7D701DBDBDB01D8D8D801DADADA01 + DDDDDD01DADADA02A6A6A601A4A4A401DEDEDE01A6A6A601D6D6D601A9A9A901 + D8D8D801DCDCDC01DADADA01DCDCDC01D5D5D501A8A8A801DCDCDC01A7A7A701 + FCFCFC01FEFEFE01D6D6D601A9A9A901A7A7A701AAAAAA01FBFBFB01DCDCDC01 + DBDBDB02D8D8D801DADADA01FFFFFF01DDDDDD01D5D5D501E0E0E001DFDFDF01 + D8D8D801D9D9D904AAAAAA01DBDBDB01D8D8D801DADADA01D9D9D901DADADA01 + FFFFFF02FDFDFD01DBDBDB01D8D8D801DEDEDE01D8D8D801DBDBDB01DADADA01 + A6A6A601D8D8D801DADADA01DEDEDE01DADADA09D8D8D801FDFDFD01DADADA01 + E0E0E001D8D8D801DDDDDD01DBDBDB01DADADA01D9D9D902DADADA01D9D9D901 + DADADA02D9D9D901DCDCDC01D9D9D901DCDCDC01D9D9D901DADADA01FFFFFF01 + D6D6D601DADADA01DCDCDC01ABABAB01D7D7D701FFFFFF02D5D5D501ABABAB01 + A6A6A601D9D9D901DADADA01D9D9D901DBDBDB01DCDCDC02D8D8D801DADADA10 + DBDBDB01D9D9D901DCDCDC01DBDBDB01D9D9D901DBDBDB01DADADA01D9D9D901 + DCDCDC01D7D7D701DADADA01DBDBDB01DADADA01DBDBDB01DADADA01D9D9D901 + DADADA08D8D8D801DDDDDD01D5D5D501DDDDDD01D9D9D901D8D8D801A8A8A801 + DADADA01FFFFFF01E0E0E001D6D6D601FFFFFF01AAAAAA01D8D8D801D9D9D901 + DCDCDC01DBDBDB01D4D4D401FFFFFF01A8A8A801D7D7D701AAAAAA01DBDBDB01 + FFFFFF01DBDBDB01FFFFFF01FEFEFE01D8D8D801DCDCDC01D7D7D701DADADA01 + D8D8D801DBDBDB01FFFFFF03DBDBDB01D5D5D501D9D9D901DADADA01FEFEFE01 + FFFFFF01ABABAB01DBDBDB01FEFEFE01FFFFFF01D7D7D701FFFFFF01DEDEDE01 + D7D7D701D8D8D801FFFFFF02FDFDFD01FFFFFF01D6D6D601FFFFFF01D7D7D701 + DADADA01DCDCDC01DEDEDE01D9D9D903DADADA08DDDDDD01DCDCDC02D8D8D804 + DBDBDB01DADADA01DDDDDD02DBDBDB02DADADA01DBDBDB01D9D9D901D8D8D801 + DEDEDE01DADADA02FCFCFC01DEDEDE01FEFEFE01FFFFFF01D9D9D901DBDBDB01 + FDFDFD01DADADA02A8A8A801A9A9A901D9D9D901DCDCDC01DADADA01D8D8D802 + D9D9D901DBDBDB01DADADA11DCDCDC01D6D6D601DCDCDC01DADADA01A6A6A601 + AAAAAA01DADADA01D7D7D701DFDFDF01D9D9D902DBDBDB01D6D6D601DADADA01 + DCDCDC01DADADA09DCDCDC01D9D9D901DADADA01DEDEDE01D8D8D801FDFDFD01 + FFFFFF01D8D8D801FDFDFD01DADADA02D9D9D901DADADA01DBDBDB01D9D9D901 + DADADA01FFFFFF01DADADA01FFFFFF01DDDDDD01A7A7A701FBFBFB01D9D9D901 + FCFCFC01FEFEFE01DCDCDC01DADADA01D9D9D901DADADA01DCDCDC02DADADA01 + FEFEFE02FFFFFF02D8D8D801FFFFFF04FAFAFA01A7A7A701FDFDFD01FFFFFF01 + DCDCDC01FCFCFC01A5A5A501AAAAAA01DADADA01FFFFFF01FDFDFD01FFFFFF01 + D8D8D801ABABAB01D8D8D801FFFFFF01DCDCDC01DADADA01D7D7D701DCDCDC01 + D9D9D901DBDBDB01DADADA09D7D7D701DBDBDB01D8D8D801DDDDDD01DCDCDC02 + D9D9D902DADADA01D8D8D802D9D9D901DBDBDB01DADADA01D9D9D901DBDBDB01 + D8D8D802DCDCDC01FFFFFF01FEFEFE01FFFFFF01D8D8D801DADADA01DBDBDB02 + DADADA01DCDCDC01A7A7A701AAAAAA01D9D9D901DBDBDB01D9D9D901DBDBDB01 + DCDCDC01D9D9D901DADADA11D9D9D901DCDCDC01D9D9D901DBDBDB01D9D9D901 + A7A7A701A8A8A802AAAAAA01D8D8D801DBDBDB01D9D9D901DCDCDC01D7D7D701 + DEDEDE01D8D8D801DADADA08D9D9D901DADADA01DBDBDB01D9D9D901FDFDFD01 + DCDCDC01DADADA01FFFFFF02DBDBDB01FFFFFF01D9D9D901DBDBDB01DADADA03 + D9D9D901FFFFFF01D8D8D801FDFDFD01DADADA02FFFFFF01DBDBDB01DADADA01 + DCDCDC01D9D9D902DADADA02D9D9D902DADADA01D9D9D901FFFFFF01D8D8D801 + FEFEFE01DCDCDC01D9D9D901DADADA01FEFEFE01FFFFFF01A9A9A901DCDCDC01 + DADADA02D9D9D901DBDBDB01A8A8A801A9A9A901DADADA01DBDBDB01D9D9D901 + DBDBDB02A7A7A701DBDBDB01D7D7D701D9D9D901DCDCDC01DADADA02DBDBDB01 + DADADA09DBDBDB01D9D9D901DADADA01DBDBDB01D9D9D902DBDBDB01DADADA01 + DBDBDB01D9D9D902DCDCDC01DBDBDB01D8D8D801D9D9D901DADADA01DBDBDB01 + DADADA01D9D9D901FEFEFE01DDDDDD01DADADA01DBDBDB01D9D9D902FEFEFE01 + DADADA01DDDDDD01D7D7D701A9A9A901A8A8A801D9D9D902DADADA01DCDCDC01 + DADADA01D9D9D901DADADA01D9D9D901DFDFDF01D7D7D701DADADA01DBDBDB01 + DADADA01D9D9D901DADADA03D9D9D902DBDBDB01DCDCDC01D8D8D801DCDCDC01 + DADADA01DBDBDB01D9D9D901FFFFFF02ABABAB01A6A6A601A8A8A801A9A9A901 + A8A8A801A9A9A901D9D9D901DCDCDC01DBDBDB01D9D9D901DBDBDB02DADADA01 + D9D9D902DDDDDD01D9D9D901DBDBDB02DCDCDC01D9D9D901DADADA02D9D9D901 + DBDBDB01DADADA01D8D8D801DBDBDB01FFFFFF01DBDBDB01D9D9D902DADADA01 + D8D8D801DBDBDB02DADADA01D8D8D801FFFFFF01A7A7A701DADADA01AAAAAA01 + D9D9D901DBDBDB01DADADA02D8D8D801DCDCDC01D8D8D801DBDBDB01D9D9D902 + DADADA01DBDBDB01FFFFFF01D8D8D801D9D9D901DEDEDE01D9D9D901DADADA01 + FFFFFF01D8D8D801DDDDDD01D9D9D901D8D8D801FFFFFF02DADADA03DBDBDB01 + D7D7D701FFFFFF01DBDBDB01D9D9D901DADADA11DBDBDB01D9D9D901DADADA02 + D9D9D901DADADA01D9D9D901DADADA06DCDCDC01D9D9D901D8D8D801FFFFFF01 + DCDCDC01DADADA01D8D8D801D7D7D701D9D9D901DADADA01FFFFFF02FDFDFD01 + FCFCFC01FFFFFF01A7A7A701D8D8D801DEDEDE01DDDDDD01D6D6D601DADADA01 + D9D9D901D8D8D801DCDCDC01D8D8D801DADADA01DCDCDC01DADADA01D9D9D901 + DCDCDC01D8D8D801DBDBDB01DADADA01D7D7D701DEDEDE01DBDBDB01D6D6D601 + DCDCDC01DBDBDB01D8D8D801DADADA02DCDCDC01FBFBFB01FCFCFC01DCDCDC01 + D8D8D801AAAAAA01A6A6A601DBDBDB01DCDCDC01D6D6D601DADADA01DDDDDD01 + D7D7D701DBDBDB01D9D9D901DBDBDB01DCDCDC01DADADA01D7D7D701DADADA01 + D7D7D701D9D9D902DADADA01DBDBDB01D9D9D901DCDCDC01A6A6A601A7A7A701 + DDDDDD01D9D9D901DBDBDB01D8D8D801DCDCDC01D4D4D401DBDBDB01DCDCDC01 + DADADA01D8D8D801DADADA01FFFFFF01D8D8D801DBDBDB01D7D7D701DADADA01 + D9D9D902DADADA01DCDCDC01DDDDDD01D9D9D901DCDCDC01DBDBDB01DADADA01 + DDDDDD01FBFBFB01DDDDDD01FEFEFE01DCDCDC01DADADA01D4D4D401DBDBDB01 + FEFEFE01DADADA01DCDCDC01D6D6D601DADADA01DCDCDC01FEFEFE01FDFDFD01 + DBDBDB01D7D7D701DADADA02DDDDDD01FDFDFD01D9D9D902DADADA10D8D8D801 + DCDCDC01D9D9D901DEDEDE01DBDBDB01D8D8D801DBDBDB01DCDCDC01DADADA06 + DBDBDB02DADADA01DCDCDC01D7D7D701D8D8D801DEDEDE01DCDCDC01D9D9D901 + DCDCDC01FDFDFD02DCDCDC01FFFFFF01FDFDFD01DBDBDB01DDDDDD01D6D6D601 + D8D8D801DDDDDD01DCDCDC01D8D8D801DCDCDC01D9D9D901DCDCDC01D8D8D801 + D7D7D701DEDEDE01DBDBDB01DADADA01D8D8D801DCDCDC01DBDBDB01DADADA01 + D9D9D901DDDDDD01D9D9D903DBDBDB01D9D9D901DADADA01D8D8D801FFFFFF02 + D6D6D601DEDEDE01D9D9D902DBDBDB01D9D9D901DBDBDB02D9D9D901DBDBDB01 + DADADA05DCDCDC01D8D8D801E0E0E001DBDBDB01DADADA03D9D9D901DADADA01 + A9A9A901A8A8A801DCDCDC01DDDDDD01D4D4D401DCDCDC01DDDDDD01DADADA01 + DBDBDB01D8D8D801DADADA01D7D7D701DBDBDB01FFFFFF01FAFAFA01FFFFFF01 + DBDBDB01D8D8D801DCDCDC02D9D9D902D6D6D601DBDBDB01DADADA01D7D7D701 + DDDDDD01D9D9D901DBDBDB01D8D8D801DADADA02DCDCDC01D9D9D901DCDCDC01 + DDDDDD01DADADA01D9D9D901DBDBDB01D9D9D901DBDBDB01D9D9D901DCDCDC01 + D7D7D701DCDCDC01D8D8D801DDDDDD01D5D5D501DBDBDB01DCDCDC01DADADA11 + DBDBDB01D8D8D801DCDCDC01D5D5D501DBDBDB01DCDCDC01DADADA01D7D7D701 + DADADA06D6D6D601DCDCDC01D9D9D901DADADA01DDDDDD01DADADA01D9D9D901 + D8D8D801DADADA01DBDBDB02DCDCDC01A6A6A601D9D9D901DEDEDE01D7D7D701 + D9D9D901DBDBDB01DADADA01DEDEDE01D4D4D401DDDDDD01DADADA02DBDBDB01 + D9D9D901DCDCDC01D8D8D803D9D9D901DADADA01A8A8A802DADADA01D6D6D601 + DBDBDB01D9D9D901DEDEDE01D9D9D901DCDCDC01D9D9D901DBDBDB01FDFDFD01 + FFFFFF01D9D9D902A7A7A701DDDDDD01D8D8D801DCDCDC01D9D9D901D7D7D701 + D8D8D801DCDCDC01DADADA01DDDDDD01D8D8D801D9D9D901DBDBDB01D8D8D801 + DCDCDC01D7D7D701D9D9D901DBDBDB03FFFFFF02D7D7D701DBDBDB01D9D9D902 + DDDDDD01D9D9D901D7D7D701DEDEDE01DADADA01D7D7D701DBDBDB02D8D8D801 + D9D9D901DCDCDC01D8D8D801DDDDDD01D9D9D902DBDBDB01DADADA01DBDBDB01 + DADADA01DDDDDD01D9D9D902DADADA01D9D9D902DDDDDD01DADADA01D8D8D801 + D7D7D701DDDDDD01D9D9D901D8D8D801DADADA01D8D8D801DDDDDD01D8D8D801 + DBDBDB02D7D7D701DCDCDC01DBDBDB01DADADA01DBDBDB01DADADA01DBDBDB01 + D9D9D902DADADA11D9D9D901DFDFDF01D8D8D801D9D9D902DBDBDB01DCDCDC01 + DADADA06DCDCDC01DADADA01D9D9D901DADADA01D8D8D801DBDBDB01D9D9D901 + DBDBDB01DCDCDC01D7D7D701FCFCFC01D7D7D701DBDBDB01A7A7A702A9A9A901 + A6A6A601ABABAB01A7A7A701D8D8D801D9D9D901DADADA01D9D9D901DDDDDD01 + DADADA01D8D8D801DBDBDB01DADADA02DFDFDF01D9D9D901DBDBDB01A8A8A801 + AAAAAA01DBDBDB02DDDDDD01DADADA01D9D9D904DCDCDC01FBFBFB01FFFFFF03 + DCDCDC01DADADA01D9D9D901D8D8D801DADADA01DEDEDE01DDDDDD01D7D7D701 + DADADA01D9D9D902DADADA02DDDDDD01D9D9D901DEDEDE01DADADA01DBDBDB01 + A5A5A501AAAAAA01FDFDFD01FFFFFF01DBDBDB01DADADA02D8D8D801DCDCDC01 + D7D7D701D9D9D901DADADA01D8D8D801DBDBDB01DADADA01DDDDDD01D7D7D701 + DCDCDC01DADADA02D9D9D901DCDCDC02D8D8D801DBDBDB02DCDCDC01D6D6D601 + D9D9D901DEDEDE01D8D8D801DCDCDC01D8D8D801D7D7D701DBDBDB02DADADA01 + D9D9D901DADADA01A9A9A901DBDBDB01DDDDDD01D6D6D601DBDBDB01D8D8D802 + DDDDDD01D6D6D601DCDCDC01D9D9D901D8D8D801DADADA02D7D7D701DEDEDE01 + DADADA10D9D9D901DBDBDB01D6D6D601DEDEDE01DBDBDB01D8D8D801DADADA01 + DCDCDC01DADADA08D9D9D901DADADA01DBDBDB01DADADA01DBDBDB02D7D7D701 + DEDEDE01FFFFFF02DBDBDB01DCDCDC01D9D9D901A7A7A702A9A9A901A8A8A801 + A9A9A901DBDBDB01D7D7D701DFDFDF01D7D7D701D9D9D901DDDDDD01DCDCDC01 + D8D8D801DADADA01D7D7D701FFFFFF02A7A7A702DADADA02D5D5D501DBDBDB01 + D8D8D801DCDCDC01DBDBDB01DADADA01DCDCDC01FFFFFF01FEFEFE01FFFFFF01 + DADADA01D8D8D801DADADA01DCDCDC02DADADA01D6D6D601DBDBDB02DCDCDC01 + DBDBDB02DADADA01D8D8D801DBDBDB01D7D7D701DADADA01DBDBDB02ABABAB01 + A6A6A601DCDCDC01D8D8D801DBDBDB01DADADA02DCDCDC01DBDBDB02DDDDDD01 + DADADA02D8D8D801DBDBDB01DADADA04DCDCDC02D7D7D701D8D8D801DADADA02 + D9D9D901D6D6D601DFDFDF01D8D8D801DBDBDB01DADADA01D9D9D901DADADA01 + DDDDDD01DCDCDC01D8D8D801DDDDDD01A9A9A901D9D9D901A7A7A701DCDCDC01 + D5D5D501A9A9A901A8A8A801A9A9A901DDDDDD01D9D9D902DEDEDE01D7D7D701 + DDDDDD01DADADA01D7D7D701DEDEDE01D6D6D601DADADA10DBDBDB01D9D9D901 + DCDCDC01D9D9D901DBDBDB02D9D9D901D7D7D701DADADA07D9D9D901D8D8D801 + DDDDDD01A8A8A801A7A7A701D8D8D801A6A6A601DBDBDB01D9D9D901D8D8D801 + FBFBFB01FFFFFF01FBFBFB01FFFFFF01DDDDDD01DBDBDB01A7A7A701A6A6A601 + AAAAAA01A7A7A701AAAAAA01A7A7A701DBDBDB01AAAAAA01A4A4A402DDDDDD01 + DBDBDB01DDDDDD01FFFFFF01FEFEFE01DBDBDB01A9A9A901D9D9D901DBDBDB01 + DEDEDE01DADADA01D7D7D701DBDBDB01D8D8D801DADADA01D7D7D701A6A6A601 + DEDEDE01D8D8D801D9D9D901DCDCDC01D9D9D901DADADA01D7D7D701DBDBDB01 + DDDDDD01DADADA01D7D7D701DBDBDB02D6D6D601DBDBDB01DFDFDF01D7D7D701 + DCDCDC01DADADA01FEFEFE01FDFDFD01DADADA01DBDBDB02A9A9A901A6A6A601 + D9D9D901DBDBDB01D8D8D801D9D9D903DBDBDB02D7D7D701DCDCDC01DADADA02 + D9D9D901DBDBDB01D8D8D802DEDEDE01DCDCDC01DBDBDB01D8D8D801DCDCDC01 + DADADA01D9D9D901DDDDDD01D7D7D701D9D9D902DCDCDC01D6D6D601D9D9D901 + DBDBDB01D9D9D901FCFCFC01A9A9A901A6A6A601ABABAB01DBDBDB01DADADA01 + A9A9A901A8A8A801A5A5A501DCDCDC01DADADA02D9D9D901D7D7D701DBDBDB01 + DADADA01DBDBDB02DADADA12D7D7D701DADADA01D9D9D901DADADA01DBDBDB01 + DCDCDC01DADADA06D9D9D901DBDBDB02D8D8D801D9D9D901AAAAAA01D9D9D901 + DBDBDB01DCDCDC01D7D7D701DADADA01DFDFDF01A4A4A401DDDDDD01D9D9D901 + D8D8D801DBDBDB01D8D8D801AAAAAA01A9A9A901D7D7D701DCDCDC01A7A7A701 + A8A8A801A7A7A701AAAAAA01DDDDDD01D7D7D701D9D9D902FFFFFF01DBDBDB01 + A9A9A901D9D9D901D8D8D801DBDBDB01D8D8D801D9D9D901DEDEDE01D8D8D801 + DCDCDC01D9D9D901DCDCDC01D9D9D901DADADA01D8D8D801DBDBDB01DADADA01 + DBDBDB01D9D9D901DADADA01DCDCDC01D8D8D801D9D9D901DEDEDE01D8D8D801 + D9D9D901DDDDDD01D8D8D801D9D9D901DBDBDB01A6A6A601DCDCDC01FFFFFF02 + DADADA01DDDDDD01A5A5A501DBDBDB01DCDCDC01DADADA03DCDCDC01DADADA01 + D9D9D901DADADA01D9D9D901DCDCDC01D8D8D801DADADA01D9D9D901DBDBDB01 + DADADA02DCDCDC01D8D8D801A7A7A701DCDCDC01D7D7D701DBDBDB02A7A7A701 + DADADA01DBDBDB01DADADA01D9D9D901DBDBDB01A8A8A801A9A9A901FDFDFD01 + DADADA01FFFFFF01D9D9D901AAAAAA01D8D8D801D7D7D701DEDEDE01A5A5A501 + A8A8A801ABABAB01A6A6A601DADADA02AAAAAA01A8A8A801DADADA01D9D9D901 + D8D8D801DBDBDB01DADADA12A8A8A801DEDEDE01D8D8D802DDDDDD01D7D7D701 + DADADA07D8D8D801FFFFFF01FDFDFD01D9D9D901DBDBDB01A7A7A701DCDCDC01 + D9D9D901DCDCDC01DADADA01A9A9A902DADADA01DBDBDB01FEFEFE01FFFFFF01 + DCDCDC01D8D8D801DCDCDC01FFFFFF01D8D8D801FFFFFF01DADADA01FFFFFF01 + D8D8D801A7A7A701A8A8A801DBDBDB01D8D8D801DBDBDB01DADADA01A8A8A801 + D8D8D801DADADA01DDDDDD01DADADA01D8D8D801DCDCDC01DADADA01DBDBDB01 + FFFFFF01DBDBDB01D9D9D902DADADA01D8D8D801DBDBDB01DADADA09DBDBDB02 + D9D9D901A8A8A801A7A7A701DCDCDC01D7D7D701DBDBDB02FFFFFF01D8D8D801 + DCDCDC01DBDBDB01DCDCDC01D9D9D901DADADA01D9D9D901DADADA01DBDBDB01 + D9D9D901DBDBDB01DCDCDC01DADADA02DEDEDE01D6D6D601DADADA01D9D9D901 + DDDDDD01D9D9D901DADADA01DCDCDC01A7A7A701DADADA01D9D9D901DADADA01 + DBDBDB01D7D7D701DCDCDC01DBDBDB01D8D8D801DBDBDB01DADADA01D9D9D901 + FFFFFF01FBFBFB01FFFFFF01A8A8A802DADADA01D9D9D902AAAAAA01A9A9A901 + A7A7A701D9D9D901DADADA01D8D8D801A8A8A801DDDDDD01DADADA01D7D7D701 + DCDCDC01D9D9D901DBDBDB01DADADA01DBDBDB01D8D8D801DCDCDC01D7D7D701 + DDDDDD01DADADA01DCDCDC01D9D9D902DDDDDD01D7D7D701D8D8D801DCDCDC01 + A7A7A701ACACAC01A4A4A401DBDBDB01DCDCDC01D9D9D901A8A8A801A6A6A601 + A7A7A701AAAAAA01A5A5A501DADADA01DDDDDD01D5D5D501DCDCDC01DADADA02 + FEFEFE01DDDDDD01D9D9D901A5A5A501DADADA02DCDCDC01FEFEFE01FDFDFD01 + D9D9D901D8D8D801DDDDDD01FFFFFF01FCFCFC01FFFFFF01A8A8A801A7A7A701 + FFFFFF02FEFEFE01FFFFFF01DADADA01A8A8A801ABABAB01D8D8D801DBDBDB01 + FFFFFF02D8D8D801DCDCDC01D8D8D801DCDCDC01D8D8D801D9D9D901DBDBDB01 + DADADA01D9D9D902DBDBDB01D8D8D801DCDCDC01D4D4D401DBDBDB01DCDCDC01 + DADADA09D9D9D901DBDBDB01D7D7D701FFFFFF01A7A7A701A9A9A901A4A4A401 + DFDFDF01DADADA01FDFDFD01D9D9D901ADADAD01D8D8D801D7D7D701A7A7A701 + DADADA01D9D9D901DCDCDC01D9D9D901DDDDDD01D8D8D801DCDCDC01D6D6D601 + D9D9D901DADADA01D7D7D701DEDEDE01DADADA01DDDDDD01FDFDFD01D8D8D801 + DDDDDD01D6D6D601ABABAB01FFFFFF01DEDEDE01D9D9D901DADADA01DDDDDD01 + D8D8D801FEFEFE01FFFFFF01D9D9D901D6D6D601DDDDDD01D8D8D801FFFFFF01 + D9D9D901DBDBDB01D6D6D601DEDEDE01D9D9D901DBDBDB01D8D8D801A7A7A701 + ABABAB01D6D6D601FFFFFF01DADADA01AAAAAA01A3A3A301DBDBDB02D9D9D901 + DDDDDD01D7D7D701A7A7A702DCDCDC01DADADA01D9D9D902DADADA01D8D8D801 + DBDBDB02D8D8D801E0E0E001DADADA01D7D7D701FFFFFF01D6D6D601DEDEDE01 + DADADA01D8D8D801A9A9A901A5A5A501ACACAC01AAAAAA01A3A3A301AAAAAA01 + D9D9D901D8D8D801DDDDDD01D7D7D701D9D9D901DCDCDC01FDFDFD01FFFFFF01 + D7D7D701DDDDDD01DADADA01DBDBDB01FDFDFD02DADADA01DDDDDD01A7A7A701 + AAAAAA01D7D7D701FFFFFF01DCDCDC01A7A7A701DADADA01D9D9D901DADADA01 + A7A7A701A8A8A801D5D5D501DEDEDE01A3A3A301DCDCDC02FBFBFB01FFFFFF01 + DDDDDD01D7D7D701DCDCDC01A8A8A801D8D8D801DADADA01E0E0E001D6D6D601 + DDDDDD02D4D4D401DCDCDC01DDDDDD01DADADA01DBDBDB01D8D8D801DADADA09 + DDDDDD01D8D8D801FFFFFF01FCFCFC01A8A8A801A9A9A901A8A8A801A5A5A501 + AAAAAA01DBDBDB01A9A9A901A6A6A601DBDBDB01DADADA01DFDFDF01DBDBDB02 + D8D8D801A8A8A801D8D8D801DCDCDC01D9D9D901D7D7D701DDDDDD01D9D9D901 + DFDFDF01D7D7D701D9D9D901DBDBDB01DADADA01DBDBDB01FBFBFB01DADADA01 + DBDBDB01A7A7A701D7D7D701D9D9D901D8D8D801DADADA01D9D9D901DBDBDB01 + D8D8D801D9D9D901DCDCDC01D9D9D901D6D6D601DBDBDB02D7D7D701DDDDDD01 + DADADA01D8D8D801DBDBDB01DCDCDC01A7A7A701A5A5A501ABABAB01D6D6D601 + A7A7A701A8A8A801A7A7A701A8A8A801A9A9A901A7A7A701A6A6A601AAAAAA01 + A8A8A801A7A7A701A6A6A601D9D9D901DCDCDC01DBDBDB01D9D9D901DADADA01 + DBDBDB01D9D9D901D8D8D801A9A9A901FFFFFF02FDFDFD01DEDEDE01D7D7D701 + D8D8D801FFFFFF01D9D9D904A9A9A902D8D8D801DEDEDE01D7D7D701DCDCDC02 + D7D7D701DADADA01FFFFFF01DBDBDB01DADADA01D9D9D902DEDEDE01DADADA02 + D9D9D901DCDCDC01A3A3A301ACACAC01D8D8D801DADADA01DEDEDE01D7D7D701 + DCDCDC01DBDBDB01A7A7A701DADADA01DEDEDE01A8A8A801DBDBDB01D8D8D801 + DADADA02A8A8A801D7D7D701DEDEDE01D7D7D701DBDBDB01DCDCDC01DADADA01 + D8D8D801DADADA01D9D9D902DDDDDD01D9D9D901D7D7D701DEDEDE01DADADA01 + D7D7D701DBDBDB01DADADA09D9D9D901FFFFFF02DCDCDC01A5A5A501A7A7A701 + ABABAB01A5A5A501DCDCDC01A9A9A901A6A6A601FFFFFF01D8D8D802A6A6A601 + DCDCDC01DADADA01DCDCDC01D8D8D801D9D9D901D8D8D801DFDFDF01D9D9D901 + DCDCDC01D6D6D601DCDCDC01DDDDDD01D9D9D902DEDEDE01FFFFFF01DADADA01 + D8D8D801DCDCDC01DBDBDB01DCDCDC01A5A5A501DCDCDC01DBDBDB02DCDCDC01 + DADADA02DBDBDB01FFFFFF01DBDBDB01D6D6D601FFFFFF01FAFAFA01DDDDDD01 + D8D8D801DADADA01D8D8D801D9D9D901AAAAAA01A9A9A901D9D9D901DEDEDE01 + A9A9A901A8A8A804DDDDDD01D5D5D501ABABAB02A9A9A901DCDCDC01DBDBDB01 + D9D9D901DFDFDF01D5D5D501DBDBDB01DADADA02D8D8D801DCDCDC01DADADA01 + DCDCDC01D9D9D901DADADA01FFFFFF02FEFEFE01DEDEDE01DADADA01D9D9D901 + A8A8A801DADADA01DCDCDC01D7D7D701D9D9D901DBDBDB01D8D8D801D9D9D901 + DBDBDB01D7D7D701D8D8D801DCDCDC01DADADA01D8D8D802D9D9D901DCDCDC01 + D9D9D901FFFFFF01AAAAAA01DADADA02D9D9D901DBDBDB02D9D9D901DADADA01 + DBDBDB01D9D9D901FFFFFF01D7D7D701DCDCDC01DBDBDB01DADADA01DBDBDB01 + DCDCDC01A7A7A701FDFDFD01DBDBDB02D7D7D702DADADA01DCDCDC01DADADA01 + D8D8D801DCDCDC01D7D7D701D9D9D901DADADA01D8D8D801DBDBDB01DADADA09 + D9D9D901DADADA01FFFFFF02FDFDFD01FFFFFF01DADADA01D8D8D801DADADA01 + DBDBDB01D7D7D701DCDCDC01DADADA01D8D8D801DFDFDF01D9D9D901FDFDFD01 + DCDCDC01D7D7D701DADADA01DFDFDF01D9D9D902A4A4A401A9A9A901DBDBDB01 + D8D8D801DBDBDB01D9D9D901DBDBDB01D9D9D902FFFFFF01DCDCDC01D8D8D801 + DDDDDD01D9D9D902DADADA01D8D8D801D9D9D901D6D6D601D9D9D901DADADA01 + FFFFFF01FCFCFC01FFFFFF04FCFCFC01DADADA01DCDCDC01DADADA01D8D8D801 + DBDBDB01D7D7D701DEDEDE01FBFBFB01FDFDFD01FFFFFF01D7D7D701DCDCDC01 + DADADA01D8D8D801DDDDDD01DADADA01A4A4A401A8A8A801A7A7A702DBDBDB01 + D6D6D601DDDDDD01DBDBDB01FDFDFD01DBDBDB01DCDCDC01D9D9D902D8D8D801 + DADADA02FFFFFF01FDFDFD01FFFFFF01FEFEFE01D8D8D801DADADA03D8D8D801 + DCDCDC01ABABAB01D7D7D701DEDEDE01DBDBDB01DADADA01DCDCDC01DEDEDE01 + D9D9D902FFFFFF01DADADA01FFFFFF01D7D7D701FFFFFF01D9D9D901FFFFFF01 + FEFEFE01DDDDDD01D7D7D701DADADA01A7A7A701DCDCDC01D7D7D701DDDDDD02 + D8D8D801DDDDDD01DBDBDB01D9D9D901FFFFFF01A7A7A702A9A9A901A8A8A801 + DADADA01DCDCDC01DDDDDD02DBDBDB01D7D7D701DBDBDB01DCDCDC01DBDBDB02 + DDDDDD01DADADA02D8D8D801DBDBDB01DADADA08DCDCDC01D9D9D901FEFEFE01 + FFFFFF06FDFDFD01DCDCDC01DBDBDB01D8D8D801FFFFFF01D8D8D801DADADA02 + DCDCDC01DADADA01DCDCDC01D9D9D901D5D5D501DFDFDF01AAAAAA01A8A8A801 + DADADA01DBDBDB01D7D7D701DCDCDC02D9D9D901DEDEDE01D7D7D701D8D8D801 + DBDBDB01FBFBFB01DEDEDE01D8D8D801DADADA01DCDCDC01DBDBDB01DDDDDD01 + D9D9D901DBDBDB01FFFFFF02D5D5D501DCDCDC01FBFBFB01FFFFFF01FDFDFD01 + DADADA01DBDBDB01DADADA02D9D9D901DCDCDC01D8D8D801DCDCDC01FFFFFF01 + D6D6D601FFFFFF01FDFDFD01D9D9D901FFFFFF01DBDBDB01D9D9D901AAAAAA01 + ABABAB01A6A6A601A7A7A701AAAAAA01ABABAB01D9D9D901DADADA01D8D8D801 + DDDDDD01D8D8D801DADADA02DBDBDB01DADADA01D8D8D801DADADA01FFFFFF02 + FCFCFC01DDDDDD01A9A9A901DBDBDB01A7A7A701A6A6A601DBDBDB01D6D6D601 + DADADA02DBDBDB01D6D6D601D9D9D901D4D4D401AAAAAA01DBDBDB01D7D7D701 + FEFEFE01FFFFFF01DADADA01FBFBFB01DEDEDE01FDFDFD01DCDCDC01D9D9D901 + FFFFFF02FCFCFC01FFFFFF02D8D8D801D7D7D701DBDBDB01D9D9D901DCDCDC01 + A7A7A701A8A8A801DCDCDC01A9A9A901A5A5A501DCDCDC01D8D8D801DBDBDB01 + A6A6A601DBDBDB01D9D9D901DCDCDC01D8D8D802D9D9D903DBDBDB02D7D7D701 + DCDCDC01DADADA0BD9D9D901FEFEFE01FFFFFF01FAFAFA01FEFEFE01DCDCDC01 + D9D9D901D8D8D801DCDCDC01D8D8D801D9D9D901DCDCDC01DBDBDB01DADADA01 + D7D7D701DBDBDB01D9D9D902FFFFFF01D7D7D701A6A6A601D8D8D801DBDBDB01 + DCDCDC01DADADA02D7D7D701DBDBDB01D6D6D601DCDCDC01D7D7D701DEDEDE01 + DCDCDC01D8D8D801DADADA01D9D9D903D8D8D801D9D9D901A8A8A801DBDBDB01 + D8D8D801DADADA01D8D8D801DADADA01FFFFFF02DBDBDB01D7D7D701DBDBDB02 + DADADA01A8A8A801A7A7A701A5A5A501FDFDFD01FFFFFF05D8D8D801DADADA01 + FFFFFF01FEFEFE01DCDCDC01D7D7D701D9D9D901A5A5A501D9D9D901DCDCDC02 + D8D8D801D7D7D701DEDEDE01D7D7D701DADADA01DBDBDB01DADADA01DBDBDB01 + D5D5D501FFFFFF02A8A8A802A7A7A701A8A8A801DCDCDC01D8D8D801DEDEDE01 + DCDCDC01D7D7D701D8D8D801DDDDDD01DBDBDB02A9A9A901D8D8D801DBDBDB01 + DADADA01D8D8D801DDDDDD01A9A9A901D7D7D701DCDCDC01D8D8D801DBDBDB01 + FDFDFD01DADADA01DDDDDD01FFFFFF01FDFDFD01DDDDDD01A8A8A801A7A7A701 + A9A9A901D7D7D701DCDCDC01D9D9D902D8D8D801ABABAB01A7A7A701DBDBDB01 + DADADA01D8D8D801DDDDDD01D7D7D701DADADA01DCDCDC01DADADA01DCDCDC01 + DADADA01D9D9D901DADADA01D9D9D901DCDCDC01D8D8D801DADADA08D9D9D901 + DBDBDB01D8D8D801DFDFDF01D7D7D701D8D8D801DEDEDE01D9D9D902DBDBDB02 + D8D8D801DBDBDB01DDDDDD01D8D8D801D9D9D902DDDDDD01D9D9D901D8D8D801 + DFDFDF01FDFDFD01FEFEFE01A9A9A901AAAAAA01DADADA01D9D9D902DBDBDB01 + DADADA01DBDBDB02DADADA01DBDBDB01D9D9D901D7D7D701DADADA01DBDBDB01 + D9D9D901DADADA01D9D9D901DEDEDE01A7A7A702A6A6A601DCDCDC01D9D9D901 + A8A8A801DADADA01FEFEFE01DBDBDB01DADADA01D9D9D901DBDBDB01D9D9D901 + DADADA02A8A8A801FFFFFF01DCDCDC01DADADA01FDFDFD01DADADA01FFFFFF01 + FEFEFE01FFFFFF01DADADA01D9D9D901FFFFFF01FDFDFD01DEDEDE01A8A8A801 + A9A9A901A8A8A801D9D9D902DCDCDC01D9D9D902DBDBDB01DADADA01D9D9D901 + DCDCDC01D8D8D801DCDCDC01FFFFFF02D8D8D801DBDBDB01DADADA01A7A7A701 + A9A9A901A7A7A701D9D9D901DBDBDB01DADADA02DBDBDB01FFFFFF01FBFBFB01 + FFFFFF01D9D9D901A9A9A902D9D9D901FDFDFD01DCDCDC01DBDBDB01D9D9D901 + DADADA03A8A8A802D7D7D701DCDCDC01A9A9A901A8A8A801A6A6A601FFFFFF01 + D8D8D801DADADA02D9D9D901A8A8A801AAAAAA01A9A9A901DADADA03D9D9D901 + DADADA01D9D9D901DADADA01D9D9D901DADADA03D9D9D901DCDCDC01D8D8D801 + DADADA11DBDBDB01D9D9D901DCDCDC01DADADA02DBDBDB01D8D8D801DADADA03 + DCDCDC01D6D6D601FFFFFF02D7D7D701AAAAAA01A8A8A801A5A5A501DCDCDC01 + DBDBDB01DADADA01D9D9D901DADADA03D8D8D801DDDDDD01DADADA01A8A8A801 + A7A7A701D9D9D901DADADA02DBDBDB01A8A8A801AAAAAA01A6A6A601A9A9A901 + AAAAAA01A5A5A501A9A9A901DBDBDB01D9D9D901DBDBDB01DADADA01D9D9D901 + DCDCDC01DADADA01DCDCDC01A4A4A401DCDCDC01DADADA02DBDBDB01DADADA01 + FFFFFF01FEFEFE01A8A8A802AAAAAA01A8A8A801D8D8D801DADADA01A9A9A901 + A8A8A801DADADA01D9D9D901DBDBDB01DADADA01D8D8D801DDDDDD01D9D9D901 + DBDBDB01DADADA01D9D9D901DCDCDC01D8D8D801FFFFFF02DADADA01D8D8D801 + DBDBDB01AAAAAA01A8A8A802DCDCDC01D9D9D902DCDCDC01D8D8D801FFFFFF02 + D6D6D601DDDDDD01A7A7A701FCFCFC01FFFFFF01DDDDDD02D5D5D501DADADA02 + FEFEFE01FFFFFF01D9D9D902E0E0E001FCFCFC01FFFFFF01FEFEFE01DBDBDB01 + DADADA01D9D9D901DBDBDB02DADADA01D7D7D701A9A9A901A8A8A801A7A7A701 + A8A8A801D9D9D901DADADA01DBDBDB01D8D8D801DCDCDC02DADADA01D7D7D701 + DBDBDB01DDDDDD01D5D5D501DCDCDC01DADADA12DCDCDC01D8D8D802D9D9D901 + DCDCDC02A9A9A901DADADA01DBDBDB01DADADA03FFFFFF01D9D9D901A7A7A701 + A9A9A901DCDCDC01D8D8D802DBDBDB02D9D9D901DBDBDB02D7D7D701DADADA02 + D8D8D801DCDCDC01DADADA01DBDBDB01FFFFFF01D9D9D902A7A7A701ABABAB01 + FDFDFD01A5A5A501ACACAC01D7D7D701DDDDDD01D7D7D701D9D9D901DDDDDD01 + FEFEFE01FDFDFD01DBDBDB01A8A8A802DCDCDC01DBDBDB01D8D8D803DADADA01 + FFFFFF02A8A8A801A2A2A201DBDBDB01DCDCDC01D7D7D701DCDCDC01A8A8A801 + D8D8D801DDDDDD01DBDBDB01D7D7D701DDDDDD01D9D9D901DBDBDB01D8D8D801 + DCDCDC02D8D8D801D9D9D901ACACAC01DADADA02FFFFFF02D4D4D401A9A9A901 + A7A7A701A6A6A601DADADA01DCDCDC01D9D9D901DCDCDC01DADADA02FFFFFF02 + DCDCDC01A9A9A901A8A8A801D9D9D901D7D7D701DDDDDD01DBDBDB01D8D8D801 + FFFFFF02D9D9D901D7D7D701FEFEFE01FFFFFF01DADADA01A9A9A901D9D9D901 + DCDCDC01DADADA02DBDBDB01DADADA02D8D8D801A8A8A801AAAAAA01A5A5A501 + DCDCDC01D8D8D801DFDFDF01D9D9D901D8D8D801D7D7D701DBDBDB01D9D9D901 + D7D7D701D9D9D901DCDCDC01DBDBDB01D9D9D901DADADA10D9D9D902DDDDDD01 + DADADA01DCDCDC01DEDEDE01D4D4D401A7A7A701DADADA01D6D6D601DADADA01 + DCDCDC01D8D8D801FDFDFD01DDDDDD01DBDBDB01D9D9D901D8D8D801DCDCDC02 + D9D9D901DADADA01A8A8A802A9A9A901DDDDDD01FDFDFD01FFFFFF01A6A6A601 + DADADA01DBDBDB01FEFEFE01FFFFFF02D9D9D901DCDCDC01FDFDFD01FFFFFF02 + D9D9D901DADADA01D8D8D801DDDDDD01DBDBDB01DADADA01DEDEDE01FBFBFB01 + DCDCDC01A5A5A501AAAAAA01A5A5A501D9D9D901DBDBDB01DDDDDD01DCDCDC01 + FEFEFE02DCDCDC01D6D6D601B0B0B001DBDBDB01D8D8D801DCDCDC01A5A5A501 + A8A8A801AAAAAA01A7A7A702DEDEDE01D8D8D801A7A7A701DBDBDB01DADADA02 + D8D8D801A8A8A801DADADA01D6D6D601DADADA01FFFFFF01FEFEFE01DBDBDB01 + D8D8D801DEDEDE01DADADA01DCDCDC01D8D8D801DCDCDC01DADADA01D8D8D801 + DCDCDC01DBDBDB01FDFDFD01D8D8D801D9D9D901A8A8A801A7A7A701DBDBDB01 + A8A8A801D9D9D901DBDBDB02A5A5A501A7A7A701DCDCDC01DBDBDB01DEDEDE01 + A4A4A401ABABAB01DADADA04D8D8D801DBDBDB03DCDCDC01DBDBDB01A5A5A501 + ACACAC01D9D9D901DCDCDC01D7D7D701DADADA01DCDCDC01DADADA01DBDBDB04 + DADADA01D7D7D701DBDBDB01DADADA10D8D8D801DBDBDB01DADADA02D8D8D801 + FFFFFF01DFDFDF01A8A8A801A9A9A901AAAAAA01ABABAB01A5A5A501FFFFFF01 + FEFEFE01FDFDFD01D8D8D801A8A8A801ACACAC01A8A8A801D7D7D701DCDCDC01 + DADADA01D9D9D901A8A8A801D7D7D701DBDBDB01DADADA01D7D7D701DDDDDD01 + DADADA02FFFFFF01FEFEFE01FBFBFB01FFFFFF01D9D9D901FFFFFF01FEFEFE01 + FCFCFC01DADADA01DDDDDD01DBDBDB01D9D9D901A6A6A601D9D9D901FCFCFC01 + FFFFFF02A9A9A901A7A7A702AAAAAA01DBDBDB01D8D8D801D6D6D601DCDCDC01 + FEFEFE01DBDBDB01DADADA01D6D6D601D9D9D901DBDBDB02A8A8A801A7A7A702 + AAAAAA01A8A8A801A7A7A701AAAAAA01D6D6D601DCDCDC02D8D8D801DDDDDD01 + DCDCDC01D9D9D901DDDDDD01A6A6A601A8A8A801FFFFFF01DBDBDB01D9D9D901 + FCFCFC01DBDBDB01D9D9D901DDDDDD01D8D8D801DCDCDC01DADADA02D6D6D601 + DBDBDB01FFFFFF02A9A9A902D8D8D801A9A9A901DBDBDB01D8D8D801A8A8A801 + DCDCDC01D8D8D801DDDDDD01DBDBDB01D6D6D601D9D9D901DBDBDB01D7D7D701 + D8D8D801DCDCDC01DEDEDE01D9D9D901DBDBDB01D6D6D601DADADA01D8D8D802 + A9A9A901A6A6A601DADADA01DCDCDC01D6D6D601DEDEDE01D6D6D601D9D9D901 + DBDBDB01D7D7D701DCDCDC01D9D9D901DADADA13DCDCDC01DADADA01D8D8D801 + DFDFDF01D6D6D601FFFFFF01D7D7D701DBDBDB01A8A8A801DBDBDB01A5A5A501 + A6A6A601D9D9D901FDFDFD01DEDEDE01DBDBDB01A6A6A601A5A5A501AAAAAA01 + DADADA01FFFFFF01FDFDFD01DCDCDC01A8A8A801DCDCDC01D9D9D901FFFFFF01 + DDDDDD01D6D6D601DCDCDC01D9D9D901DBDBDB01FFFFFF02D9D9D901DADADA01 + D8D8D801FFFFFF03D7D7D701DBDBDB01D8D8D801FEFEFE01DDDDDD01FFFFFF02 + FEFEFE01DADADA01A8A8A803A5A5A501D9D9D901E0E0E001FDFDFD01FFFFFF01 + DADADA01DBDBDB01D9D9D901DBDBDB01DADADA01D8D8D801D9D9D901DADADA01 + DBDBDB01A9A9A901A5A5A501DCDCDC01A8A8A801A9A9A901DBDBDB01D9D9D901 + FFFFFF01DADADA01FEFEFE01FFFFFF01D8D8D801A7A7A701FEFEFE02A9A9A902 + DBDBDB01D9D9D901DDDDDD01DADADA01D9D9D901D6D6D601DBDBDB01D9D9D901 + DDDDDD01DBDBDB01FCFCFC02ACACAC01FEFEFE01DADADA01DDDDDD01D7D7D701 + D9D9D901FFFFFF01AAAAAA01A6A6A602DADADA01DEDEDE01DBDBDB01D9D9D901 + DDDDDD01DADADA01D9D9D901D6D6D601DDDDDD01D9D9D901DCDCDC01DDDDDD01 + D8D8D801DADADA01AEAEAE01A6A6A601D6D6D601DDDDDD01DBDBDB03DCDCDC01 + D7D7D701DDDDDD01D6D6D601DADADA01AAAAAA01A6A6A601DDDDDD01DADADA10 + D9D9D901DBDBDB02D6D6D601DFDFDF01FEFEFE01FFFFFF03FDFDFD01A8A8A802 + DDDDDD01DCDCDC01FCFCFC01FEFEFE02DCDCDC01DADADA01DBDBDB01D9D9D901 + FFFFFF01D9D9D901D8D8D801DADADA01D9D9D902D8D8D801DCDCDC01DBDBDB01 + D9D9D901DADADA01D9D9D901DDDDDD01D8D8D801DCDCDC01DBDBDB01FDFDFD01 + FEFEFE02DCDCDC01DADADA01A8A8A801DCDCDC01D8D8D801D9D9D901D8D8D801 + DCDCDC01D9D9D901DADADA01A9A9A901A8A8A801A6A6A601ABABAB01A5A5A501 + FEFEFE02DBDBDB02D9D9D901DADADA01DBDBDB01DADADA01DBDBDB01DCDCDC01 + D8D8D801DADADA02A5A5A501A7A7A701DCDCDC01D7D7D701DADADA01FFFFFF01 + F9F9F901FEFEFE01FFFFFF02A7A7A701FFFFFF01DEDEDE01D5D5D501DBDBDB01 + DCDCDC01D8D8D801D7D7D701DADADA01DCDCDC01DBDBDB02D8D8D802DBDBDB01 + FFFFFF02D5D5D501FFFFFF01D9D9D901A8A8A801FFFFFF01DCDCDC01DADADA01 + A6A6A601ACACAC01DADADA01D9D9D902D6D6D601DADADA01D9D9D901DBDBDB03 + D9D9D901DBDBDB01D8D8D801DADADA01DBDBDB01DCDCDC01A2A2A201DCDCDC01 + DBDBDB02D9D9D902DBDBDB01D7D7D701DCDCDC01DBDBDB01D8D8D801A9A9A901 + A8A8A801A7A7A701A6A6A601DADADA10D9D9D901DADADA02DBDBDB01D9D9D902 + FFFFFF01D9D9D901FEFEFE01FFFFFF02A9A9A901A8A8A801D7D7D701FFFFFF01 + DBDBDB01FFFFFF01DCDCDC01DADADA01D8D8D801FFFFFF01FBFBFB01DBDBDB01 + DEDEDE01DADADA01DDDDDD01D9D9D901DBDBDB01D9D9D901D7D7D701DBDBDB01 + DADADA01D9D9D901DADADA01DEDEDE01D9D9D901D8D8D801DCDCDC01FEFEFE01 + FFFFFF01FEFEFE01DBDBDB02D9D9D901DADADA01DCDCDC01DADADA01FEFEFE01 + D8D8D801DBDBDB01DADADA01A7A7A701A8A8A801A9A9A901A7A7A701DBDBDB01 + FFFFFF01DCDCDC01DADADA01D8D8D801DBDBDB01D9D9D901DCDCDC01D8D8D801 + D7D7D701DDDDDD01DADADA01DBDBDB02ABABAB01A7A7A701AAAAAA01A8A8A801 + D6D6D601DDDDDD01DBDBDB01FFFFFF01D9D9D901DADADA01FFFFFF02DBDBDB01 + D7D7D701DBDBDB01DADADA01DBDBDB01DADADA02D8D8D801DDDDDD01D9D9D901 + DADADA02FFFFFF01D9D9D901DCDCDC01DADADA02FFFFFF01DDDDDD01FDFDFD01 + FEFEFE01D9D9D901DADADA02DBDBDB01DADADA01DDDDDD01DADADA03D9D9D901 + DCDCDC01D8D8D801D9D9D901DBDBDB01DADADA02D9D9D901ACACAC01DBDBDB01 + D9D9D903DBDBDB01DADADA01DCDCDC01D6D6D601DADADA01FFFFFF01DBDBDB01 + A7A7A701DBDBDB01D8D8D801DADADA10DCDCDC01D8D8D801DCDCDC01DADADA01 + D9D9D901DADADA01D9D9D901DADADA01FFFFFF02DBDBDB01DADADA01D7D7D701 + DEDEDE01D9D9D901A8A8A801D9D9D901DADADA02DBDBDB01D9D9D901DCDCDC01 + DBDBDB01D8D8D802DCDCDC01D9D9D901DADADA01D9D9D901DCDCDC01D9D9D901 + DBDBDB01DCDCDC01D8D8D801DADADA03DBDBDB01FFFFFF01FEFEFE01FFFFFF01 + D7D7D701DADADA01D9D9D901FFFFFF01FCFCFC01FFFFFF03D9D9D901D8D8D801 + DDDDDD01D7D7D701A7A7A701A9A9A901DADADA01DBDBDB01D7D7D701D9D9D901 + DEDEDE01D8D8D801DADADA01DCDCDC01DADADA01DBDBDB02D8D8D801DCDCDC01 + A6A6A601A9A9A901A7A7A702A9A9A901DADADA02D9D9D901FCFCFC01DEDEDE01 + FDFDFD01DBDBDB01D9D9D901DBDBDB01DCDCDC01DADADA02D9D9D901DADADA09 + DBDBDB01FEFEFE01DBDBDB01D8D8D801DCDCDC01FEFEFE01FFFFFF01DBDBDB01 + FCFCFC01FFFFFF01FDFDFD01D8D8D801DADADA01D9D9D901DADADA02DBDBDB01 + DDDDDD01D7D7D701DCDCDC01DADADA01D7D7D701DDDDDD01A9A9A901A7A7A701 + D9D9D901DBDBDB01DADADA03DBDBDB01D9D9D901DADADA01D9D9D901DCDCDC01 + D8D8D801FFFFFF01DDDDDD01D8D8D801D7D7D701DFDFDF01D8D8D801DBDBDB02 + D9D9D904DADADA02D8D8D801DCDCDC01D9D9D901DBDBDB01DADADA01D8D8D801 + DCDCDC01DADADA02D9D9D901DADADA01DCDCDC01DADADA01D9D9D901FFFFFF01 + FEFEFE01D7D7D701DBDBDB01FFFFFF01DDDDDD01D8D8D801DBDBDB01D8D8D801 + DBDBDB01D9D9D901D8D8D801DADADA03D9D9D901DBDBDB01D9D9D901DADADA01 + DCDCDC02DBDBDB01D9D9D901DBDBDB01D9D9D901DADADA02D9D9D901DADADA01 + D8D8D801DBDBDB01DADADA01A6A6A601DBDBDB01DADADA01D9D9D901AAAAAA01 + FBFBFB01FFFFFF02D6D6D601DBDBDB01DCDCDC01DADADA01DDDDDD01A8A8A801 + DADADA01D8D8D801DEDEDE01D9D9D902DCDCDC01D8D8D802DCDCDC01DADADA01 + D9D9D901DCDCDC01DADADA01D8D8D801DEDEDE01D7D7D701A9A9A901A8A8A801 + A9A9A901DDDDDD01D7D7D701DBDBDB01D9D9D901DADADA01D9D9D901DADADA0E + DEDEDE01D5D5D501DADADA01D9D9D901DBDBDB01D9D9D901FFFFFF01FDFDFD02 + FFFFFF01FAFAFA01FDFDFD01E2E2E201DADADA01D9D9D901DBDBDB01D9D9D901 + DCDCDC01D7D7D701DADADA01D9D9D901DCDCDC01DBDBDB01D8D8D801A7A7A701 + A8A8A801DBDBDB01A8A8A803DADADA01D8D8D801D9D9D901AAAAAA01DBDBDB01 + D8D8D801ACACAC01A7A7A701DADADA01DDDDDD01DBDBDB02DADADA01D8D8D801 + D7D7D701DDDDDD01DCDCDC01DBDBDB01DCDCDC01DADADA01DBDBDB01DADADA02 + DBDBDB01DADADA01D8D8D801DDDDDD01D7D7D701DCDCDC01DBDBDB01D9D9D903 + D8D8D801DBDBDB01DADADA01D9D9D901DADADA01DCDCDC01FBFBFB01D8D8D801 + A7A7A701DCDCDC01D6D6D601DCDCDC02DDDDDD01D8D8D801DBDBDB03D9D9D901 + DBDBDB01D6D6D601D9D9D901D8D8D802DCDCDC01DADADA01DBDBDB02DCDCDC01 + D9D9D901DBDBDB01DDDDDD01D8D8D801A8A8A801AAAAAA01A7A7A701A8A8A801 + D7D7D701D9D9D901DBDBDB01FFFFFF01FDFDFD01FFFFFF01DCDCDC01D5D5D501 + FFFFFF01FDFDFD01D8D8D801DCDCDC01DDDDDD01D6D6D601DCDCDC01DADADA01 + D8D8D801DEDEDE01DBDBDB01D7D7D701DADADA01DDDDDD01D6D6D601DADADA01 + FEFEFE01FFFFFF01D8D8D801AAAAAA01A7A7A701A8A8A801A5A5A501DCDCDC01 + DBDBDB02DADADA10D6D6D601DCDCDC01DBDBDB01DDDDDD01D8D8D801DCDCDC01 + FFFFFF01D9D9D902DFDFDF01FDFDFD01FFFFFF01D5D5D501DADADA01D9D9D901 + DBDBDB02D9D9D901DADADA01DFDFDF01D8D8D801D9D9D902DDDDDD01A6A6A601 + A8A8A801A7A7A701AAAAAA02A6A6A601AAAAAA01DADADA01FFFFFF01DCDCDC01 + D9D9D901A6A6A601A9A9A901A8A8A801D7D7D701DADADA01DBDBDB01D6D6D601 + D8D8D801E0E0E001A7A7A701A5A5A501DADADA03A5A5A501DBDBDB01D9D9D901 + DDDDDD01D6D6D601DADADA01DDDDDD01DBDBDB01D9D9D901DADADA02DDDDDD01 + DBDBDB03D9D9D901D8D8D801DBDBDB01D9D9D901DADADA01DCDCDC01DDDDDD01 + DBDBDB01A6A6A601DEDEDE01D8D8D801DADADA01D7D7D701DBDBDB01DDDDDD01 + D7D7D701D9D9D901DADADA01DCDCDC02DBDBDB01DCDCDC01DADADA02D7D7D701 + DEDEDE01D8D8D801D6D6D601A9A9A901A6A6A601D9D9D901FFFFFF01D9D9D901 + D7D7D701FFFFFF01FEFEFE01DDDDDD01DEDEDE01D8D8D801FEFEFE01FFFFFF01 + FEFEFE01D9D9D901DADADA01DDDDDD01FFFFFF04FEFEFE01FFFFFF01DBDBDB01 + DADADA01D9D9D901DBDBDB01DDDDDD01DADADA01D8D8D801DDDDDD01FFFFFF02 + FDFDFD01FFFFFF01FCFCFC01A9A9A901A8A8A801AAAAAA01A5A5A501DBDBDB01 + DADADA01DDDDDD01D7D7D701DADADA0EDBDBDB01DADADA02D8D8D801DADADA01 + D9D9D901DBDBDB02D8D8D802FFFFFF03DADADA01D9D9D902DADADA02D9D9D903 + DADADA01DCDCDC01D8D8D801A8A8A801DADADA01DCDCDC01D7D7D701A5A5A501 + AAAAAA01A5A5A501DDDDDD01D7D7D701DADADA02DCDCDC01A7A7A701A9A9A901 + DDDDDD01DADADA02DCDCDC01A7A7A703DDDDDD01D9D9D902D8D8D801DEDEDE01 + D7D7D701DBDBDB01D8D8D801DEDEDE01D9D9D902DADADA01DBDBDB01D8D8D801 + DADADA01D9D9D901D7D7D701DCDCDC01D8D8D801DCDCDC01DADADA02DDDDDD01 + D7D7D701DADADA01A3A3A301DBDBDB01A8A8A801DCDCDC01D8D8D801DBDBDB02 + D8D8D801DADADA01DCDCDC01A9A9A901D9D9D901D7D7D701DBDBDB01D8D8D802 + DEDEDE01D7D7D701D9D9D902DCDCDC01DBDBDB02DDDDDD01FEFEFE01FFFFFF03 + A5A5A501D9D9D901DBDBDB01D7D7D701D9D9D901DCDCDC01FFFFFF01FEFEFE01 + DCDCDC01D9D9D901FEFEFE02FFFFFF01DBDBDB01FFFFFF02DADADA01D9D9D901 + DBDBDB01DADADA01D8D8D801D7D7D701D9D9D904FFFFFF02FEFEFE01FFFFFF01 + FDFDFD01ABABAB01A5A5A501A9A9A901DEDEDE01D7D7D701D8D8D801DADADA0F + DBDBDB01D8D8D801D9D9D901ACACAC01D8D8D801DCDCDC01DBDBDB01D8D8D801 + DADADA01DBDBDB01FFFFFF01FCFCFC01FDFDFD01DBDBDB02D9D9D901D8D8D801 + DDDDDD01D7D7D701DCDCDC01DBDBDB01D8D8D801DCDCDC01DADADA01DBDBDB01 + D8D8D801DADADA03D9D9D901DEDEDE01FAFAFA01DCDCDC01D8D8D801DEDEDE01 + D7D7D701A7A7A701A6A6A601D7D7D701DCDCDC01DADADA01D9D9D901FFFFFF01 + DADADA01ACACAC01D9D9D901DCDCDC01FEFEFE01DDDDDD01D9D9D901DBDBDB01 + DADADA01D8D8D801DADADA01D9D9D901DCDCDC01DBDBDB01D7D7D701DADADA01 + DEDEDE01D7D7D701D9D9D901DCDCDC01D9D9D901DADADA01DDDDDD01D6D6D601 + D7D7D701DCDCDC01A8A8A801FFFFFF01D9D9D901DCDCDC01D7D7D701DADADA01 + D8D8D802DADADA01DBDBDB02D9D9D901D8D8D801DCDCDC01DDDDDD01D9D9D901 + DADADA01D8D8D801DDDDDD02D9D9D901FDFDFD01FFFFFF01D8D8D801DADADA01 + D8D8D801DADADA01D9D9D901DADADA01A7A7A701ABABAB01D7D7D701A9A9A901 + AAAAAA01D9D9D901FFFFFF03D8D8D801DBDBDB04D7D7D701FFFFFF03FCFCFC01 + DEDEDE01D9D9D901FFFFFF02DCDCDC01D9D9D901DBDBDB02D9D9D901FFFFFF02 + FEFEFE01FFFFFF01D9D9D901DADADA01D9D9D901DDDDDD01D8D8D801DDDDDD01 + DADADA0ED8D8D801E0E0E001A5A5A501A7A7A701DCDCDC01D8D8D802DBDBDB01 + DADADA01D9D9D901D8D8D801FFFFFF01FCFCFC01FFFFFF02D9D9D901DDDDDD01 + DADADA01DCDCDC01D8D8D801D5D5D501DEDEDE01D7D7D701DADADA01DBDBDB04 + FFFFFF01FDFDFD02FFFFFF02FEFEFE01D9D9D901DBDBDB01A7A7A701DCDCDC01 + DDDDDD01DADADA01FFFFFF03AAAAAA01A2A2A201A7A7A701D9D9D901A9A9A901 + D8D8D801D6D6D601DEDEDE01DCDCDC01D9D9D901DCDCDC01DADADA01D8D8D801 + DADADA01D8D8D801DBDBDB01DADADA01DDDDDD01DCDCDC01D4D4D401DDDDDD01 + A7A7A701D7D7D701DEDEDE01FFFFFF01FEFEFE01DBDBDB01FEFEFE01D8D8D802 + DBDBDB01DADADA01DEDEDE01DCDCDC01D7D7D701FFFFFF01D6D6D601DDDDDD01 + DADADA01A9A9A901A4A4A401D9D9D901DBDBDB01DADADA01D8D8D801D6D6D601 + DFDFDF01D8D8D801DADADA01DBDBDB01DADADA01DDDDDD01D8D8D801DBDBDB01 + A8A8A801AAAAAA01A6A6A601ACACAC01A6A6A602DADADA01D6D6D601DCDCDC01 + D8D8D801DBDBDB01D9D9D901FFFFFF01D7D7D701DADADA01FFFFFF01FBFBFB01 + FFFFFF01FBFBFB01DADADA01FFFFFF01FDFDFD01FFFFFF01D7D7D701D9D9D901 + DDDDDD01D8D8D801DADADA01D9D9D901D8D8D801FFFFFF02FEFEFE01DADADA01 + DBDBDB01D9D9D901DADADA01DBDBDB01D8D8D801DADADA0ED7D7D701FFFFFF01 + A8A8A802DADADA02DDDDDD01D9D9D901DCDCDC01D7D7D701DBDBDB01FFFFFF03 + FDFDFD01FFFFFF01FDFDFD01D7D7D701DCDCDC01DADADA01DEDEDE01DADADA01 + D8D8D801DCDCDC01D9D9D901FFFFFF01FDFDFD01DCDCDC01D7D7D701DDDDDD01 + FDFDFD01FFFFFF03DADADA01D8D8D801E0E0E001D8D8D801DADADA01D9D9D902 + FFFFFF01FCFCFC01DBDBDB01ACACAC01D9D9D902A9A9A901DBDBDB01DCDCDC01 + DADADA01D8D8D801D9D9D901DADADA01DBDBDB01DCDCDC01DADADA01DCDCDC01 + DBDBDB01D4D4D401DCDCDC01D8D8D801DBDBDB01D8D8D801DDDDDD01D7D7D701 + DADADA01FDFDFD01D8D8D801D9D9D901DADADA01DBDBDB02DDDDDD01D7D7D701 + D5D5D501DADADA01DCDCDC01A8A8A802DADADA01D7D7D701A8A8A801ABABAB01 + DADADA01D9D9D901DADADA01DBDBDB01DEDEDE01D8D8D802DCDCDC01D8D8D801 + DADADA01D8D8D801DCDCDC01D9D9D901D7D7D701DDDDDD01D8D8D801FDFDFD01 + DDDDDD01DBDBDB01DADADA01DBDBDB01DADADA02D8D8D801DDDDDD01A6A6A601 + DDDDDD01D9D9D901A8A8A801DBDBDB01DCDCDC01FEFEFE01FFFFFF01DADADA01 + DBDBDB01D9D9D901ACACAC01A9A9A901D5D5D501DDDDDD02D7D7D701DCDCDC01 + D7D7D701DBDBDB01D9D9D901DBDBDB01DADADA02DCDCDC02D9D9D901DADADA0E + FFFFFF02D9D9D901DADADA01DBDBDB01D8D8D801D9D9D901DADADA01D9D9D901 + DADADA01DBDBDB01DADADA01D9D9D901FFFFFF01FDFDFD01FFFFFF03FEFEFE01 + DADADA02D9D9D901FFFFFF01DADADA01FFFFFF02D5D5D501DDDDDD01DCDCDC01 + D7D7D701DCDCDC01DADADA01FFFFFF01D9D9D901DBDBDB01DADADA01D9D9D901 + DBDBDB01D8D8D801DBDBDB02FEFEFE01FFFFFF01FDFDFD01DADADA01FFFFFF01 + DBDBDB01D9D9D902DCDCDC01D9D9D902DBDBDB01DADADA01D9D9D902DBDBDB01 + D8D8D801DBDBDB01D9D9D902DBDBDB01FFFFFF01DBDBDB01D8D8D801DDDDDD01 + D8D8D801DBDBDB02DADADA01D9D9D901DADADA01DBDBDB01A5A5A501DCDCDC01 + A8A8A801AAAAAA01A5A5A501A7A7A701DBDBDB01FFFFFF02DBDBDB01D9D9D901 + DADADA04D8D8D801DCDCDC01DADADA02DCDCDC01D9D9D901FFFFFF01D9D9D901 + DDDDDD01FDFDFD01FEFEFE01FFFFFF02D9D9D901DBDBDB01DADADA01DBDBDB01 + D7D7D701D9D9D901DDDDDD01D9D9D901D8D8D801DCDCDC01A8A8A802D9D9D901 + FDFDFD01DCDCDC01DBDBDB01D7D7D701A8A8A802A7A7A702DBDBDB01DADADA01 + D6D6D601DBDBDB01DCDCDC01D9D9D901A9A9A901DADADA01D9D9D901DADADA02 + D8D8D801DADADA08DBDBDB01D8D8D801DDDDDD01DBDBDB02DADADA01D7D7D701 + DCDCDC01FFFFFF02D9D9D902DBDBDB01DADADA01DCDCDC01DADADA02DBDBDB01 + D9D9D901DCDCDC01DBDBDB01D9D9D901DADADA01FDFDFD01FFFFFF01FEFEFE02 + DADADA01FFFFFF02FEFEFE01DADADA02DBDBDB01D8D8D801DADADA01DBDBDB01 + D8D8D801DCDCDC01D9D9D901FEFEFE01DCDCDC01A9A9A901D9D9D901A8A8A801 + DBDBDB01D8D8D801DCDCDC01DADADA02FCFCFC01DCDCDC01D8D8D801FFFFFF01 + DADADA02D8D8D801DDDDDD01DADADA01D9D9D901A7A7A701DADADA02DBDBDB02 + DCDCDC01D7D7D701DBDBDB01DADADA01DBDBDB01D8D8D801DADADA03DEDEDE01 + D6D6D601A9A9A901DBDBDB01DADADA01DBDBDB01DCDCDC01A6A6A601A9A9A901 + A8A8A801DADADA01DBDBDB01A4A4A401DCDCDC01FFFFFF02D8D8D801DADADA01 + DCDCDC01DADADA01D9D9D901DCDCDC01D9D9D901DBDBDB01D9D9D902DDDDDD01 + D8D8D801D9D9D901DADADA01A7A7A701FDFDFD01DBDBDB01DADADA01DBDBDB01 + DADADA01D9D9D901DADADA03D9D9D901FFFFFF01DCDCDC01DADADA01FFFFFF01 + D9D9D901A9A9A901A5A5A501D9D9D901A7A7A701D9D9D901DBDBDB02FFFFFF01 + DCDCDC01D8D8D801DCDCDC01D7D7D701DCDCDC02D8D8D801DBDBDB01D9D9D901 + DCDCDC01D8D8D801DCDCDC01D8D8D801DADADA01DCDCDC01D9D9D902DADADA01 + D9D9D901DBDBDB01DDDDDD01D9D9D901D7D7D701DFDFDF01D6D6D601D8D8D801 + DADADA01D9D9D901DDDDDD01D8D8D802E1E1E101D7D7D701DBDBDB02D9D9D901 + D8D8D801DADADA01D8D8D801DADADA02D8D8D801D9D9D902DEDEDE01DBDBDB01 + D9D9D901FFFFFF03D9D9D901FEFEFE01DDDDDD01DADADA01D8D8D801DCDCDC01 + DBDBDB01D8D8D801D9D9D901DCDCDC01D7D7D701FFFFFF01FDFDFD01DCDCDC01 + D8D8D801DBDBDB01ACACAC01D9D9D901D7D7D701D9D9D902DCDCDC01DBDBDB01 + D7D7D701DBDBDB01D9D9D903DADADA01D6D6D601DDDDDD01DBDBDB01ADADAD01 + D8D8D802DBDBDB01D7D7D702E0E0E001D9D9D901DBDBDB02DCDCDC01A9A9A901 + D9D9D901DADADA01D8D8D801DBDBDB01D9D9D901DCDCDC01DBDBDB01FDFDFD01 + D8D8D801D9D9D901DADADA02D8D8D801A9A9A901DBDBDB01DADADA02AAAAAA01 + A8A8A801D8D8D801D9D9D901DBDBDB01D9D9D901D7D7D701DBDBDB01DCDCDC01 + DADADA01DBDBDB01DADADA01D8D8D801DDDDDD01A8A8A801A9A9A901DDDDDD01 + DADADA01D9D9D902DDDDDD01DADADA01DBDBDB02DADADA01DBDBDB02D8D8D801 + FFFFFF01FCFCFC01DEDEDE01D5D5D501E2E2E201D7D7D701DDDDDD01FFFFFF02 + FDFDFD02DADADA02DCDCDC01DDDDDD01D6D6D601D9D9D901FFFFFF01D8D8D801 + D9D9D902DCDCDC01DADADA01DCDCDC02D5D5D501DEDEDE01DDDDDD01D9D9D901 + DBDBDB01DADADA01D6D6D601DCDCDC01A8A8A801A7A7A701A9A9A901DBDBDB01 + DADADA01DBDBDB02DADADA01D8D8D801D9D9D901DBDBDB01D9D9D902DADADA01 + D8D8D801DDDDDD01DADADA01DDDDDD01DBDBDB01DADADA01DDDDDD01DADADA01 + D7D7D701D9D9D901DADADA01FFFFFF01DADADA01D6D6D601DADADA01DCDCDC01 + D7D7D701D8D8D801D9D9D901D8D8D801DADADA01DBDBDB01DADADA01DBDBDB01 + D9D9D901FFFFFF01FDFDFD01DBDBDB01DADADA02D6D6D601DADADA01E1E1E101 + D9D9D901D7D7D701D9D9D901DBDBDB01DCDCDC01DADADA01DDDDDD01D9D9D901 + DADADA01DCDCDC01DBDBDB01FEFEFE01D6D6D601D8D8D801DCDCDC01A8A8A802 + DCDCDC01DADADA02D7D7D701DCDCDC01D7D7D701D8D8D801A6A6A601DCDCDC02 + FFFFFF01DBDBDB01D9D9D901DADADA01D8D8D801FFFFFF02DEDEDE01D7D7D701 + DBDBDB01DADADA01D9D9D901DADADA01D9D9D901A3A3A301A8A8A801DADADA01 + DCDCDC01DBDBDB01D7D7D701DBDBDB03D9D9D901DADADA04DCDCDC01A5A5A501 + A8A8A801D6D6D601DADADA01DDDDDD01D9D9D902A7A7A701D9D9D901DCDCDC01 + D5D5D501DBDBDB02D9D9D901DCDCDC01FFFFFF01FBFBFB01DADADA01FEFEFE01 + DADADA01D9D9D901FEFEFE01DADADA01DDDDDD01DBDBDB01D9D9D901DADADA01 + D8D8D801D5D5D501DCDCDC01D9D9D901DADADA01DCDCDC01DBDBDB02D9D9D901 + D8D8D802DBDBDB01DCDCDC01D8D8D802A8A8A801A7A7A702DDDDDD01DADADA01 + DBDBDB01D9D9D901DBDBDB01D9D9D901DBDBDB01D8D8D802DADADA01DDDDDD01 + D8D8D801DCDCDC01D9D9D901DCDCDC02DADADA01D9D9D901DBDBDB01DADADA01 + D6D6D601DADADA01D8D8D801DEDEDE01D7D7D701DDDDDD01DCDCDC01D6D6D601 + DBDBDB01DEDEDE01D7D7D701DCDCDC01DADADA01DCDCDC02D9D9D901DBDBDB01 + DADADA01D8D8D801D9D9D901DCDCDC01D9D9D901DBDBDB01D7D7D701FFFFFF01 + DCDCDC01D9D9D901DDDDDD01D7D7D701DBDBDB01DADADA01DDDDDD01D9D9D902 + D6D6D601D8D8D801DCDCDC01D9D9D901A6A6A602FFFFFF01DEDEDE01D7D7D701 + A8A8A801AAAAAA01A7A7A701DADADA01DBDBDB01DADADA01DDDDDD01D7D7D701 + FFFFFF01DADADA01DDDDDD01DADADA01D7D7D701D9D9D902DCDCDC01DDDDDD01 + A9A9A901D8D8D801FEFEFE01FCFCFC01FFFFFF02D8D8D801DDDDDD01DADADA01 + FDFDFD01FFFFFF01A8A8A801D9D9D902DBDBDB01DCDCDC01D9D9D901DBDBDB01 + DADADA01D8D8D801DADADA01FFFFFF01DADADA01DBDBDB01D7D7D701A9A9A901 + AAAAAA01A8A8A801DCDCDC01DBDBDB01DADADA02A5A5A501DCDCDC01D9D9D901 + DFDFDF01DADADA01D9D9D901DCDCDC01D3D3D301DFDFDF01DBDBDB01DADADA01 + D8D8D801DEDEDE01D9D9D901DEDEDE01D8D8D801DADADA01D9D9D901DCDCDC01 + D8D8D801DBDBDB01DDDDDD01DCDCDC02D6D6D601D9D9D901D8D8D801DADADA01 + DBDBDB01DDDDDD01DADADA02D8D8D802DBDBDB01ABABAB01A9A9A902D6D6D601 + DADADA01FEFEFE01DCDCDC02D6D6D601D9D9D902DEDEDE01DBDBDB01D9D9D901 + D7D7D701DCDCDC01DADADA01DBDBDB01D8D8D801DCDCDC01D9D9D901D8D8D801 + DEDEDE01A9A9A901DEDEDE01D8D8D802DEDEDE01D6D6D601DBDBDB01DDDDDD01 + D8D8D802DBDBDB01D8D8D801D9D9D902DBDBDB02D7D7D701DFDFDF01DADADA02 + D9D9D901DCDCDC01FFFFFF01DADADA02D8D8D801DDDDDD01D6D6D601D8D8D801 + DCDCDC01DBDBDB01A7A7A701D6D6D601DFDFDF01DCDCDC02DADADA01DBDBDB01 + DADADA01DBDBDB02DADADA01FFFFFF01FDFDFD01DBDBDB01DADADA01DBDBDB01 + D7D7D701DBDBDB01D8D8D801DCDCDC01FFFFFF01D9D9D901D8D8D801DADADA01 + DFDFDF01A7A7A701AAAAAA01A7A7A701A5A5A501ACACAC01D9D9D901DFDFDF01 + FFFFFF01DBDBDB01DADADA01D8D8D801D9D9D901DADADA01DCDCDC01D6D6D601 + DCDCDC01D8D8D801DADADA01DCDCDC01D9D9D901DADADA03DBDBDB01FDFDFD01 + FEFEFE01FFFFFF01FDFDFD01DDDDDD01A9A9A901A6A6A601A8A8A801A7A7A701 + DBDBDB01FBFBFB01DDDDDD01DCDCDC01DADADA01D7D7D701D8D8D801DADADA01 + D7D7D701DBDBDB01DDDDDD01DADADA01D8D8D801DBDBDB01DDDDDD01D4D4D401 + DBDBDB02D9D9D901DDDDDD01DADADA01D7D7D701DBDBDB01D9D9D901D5D5D501 + DDDDDD01D6D6D601DDDDDD01D9D9D901DCDCDC01D8D8D801DBDBDB01D7D7D701 + D9D9D901DDDDDD01D8D8D801FFFFFF01D8D8D801DADADA01A6A6A601DADADA01 + DBDBDB01DADADA03D9D9D901DCDCDC01DBDBDB01DCDCDC01D6D6D601DADADA01 + DCDCDC01DBDBDB02D9D9D901DADADA01D6D6D601DDDDDD01DADADA01DDDDDD01 + D6D6D601AAAAAA01A5A5A501AAAAAA01DBDBDB02D9D9D901D4D4D401DEDEDE01 + D8D8D801DDDDDD01DADADA01DEDEDE01D6D6D601DCDCDC01A5A5A502DDDDDD01 + D8D8D801DCDCDC01D9D9D903DADADA03DBDBDB01DADADA01DDDDDD01DADADA01 + DBDBDB01D8D8D801DCDCDC01DDDDDD01D6D6D601D9D9D901DADADA01FEFEFE02 + DADADA01D9D9D902FFFFFF01FCFCFC01FFFFFF01D8D8D801DADADA03D9D9D901 + DDDDDD01D8D8D801D9D9D901A9A9A901DADADA02A6A6A602A9A9A901D8D8D801 + DADADA01A8A8A802A4A4A401ABABAB01A7A7A701A6A6A601DEDEDE01D7D7D701 + D9D9D901FFFFFF01DCDCDC01D8D8D801DEDEDE01DBDBDB01D9D9D901D8D8D801 + ABABAB01D8D8D801D9D9D901DCDCDC01FFFFFF01FDFDFD01FFFFFF01DADADA01 + D8D8D802A9A9A901A7A7A701A8A8A802DADADA01DBDBDB01D9D9D902DDDDDD01 + DADADA01D8D8D801DEDEDE01DBDBDB01DADADA01D8D8D801DBDBDB01D9D9D902 + DDDDDD01D9D9D901DBDBDB01D8D8D802DCDCDC01DEDEDE01D8D8D801DBDBDB02 + D9D9D901D8D8D801DBDBDB01DADADA02D8D8D801DBDBDB01DCDCDC01D8D8D802 + DCDCDC01FDFDFD01DCDCDC01DADADA03DCDCDC01D8D8D801DADADA01D7D7D701 + DCDCDC01D8D8D801DBDBDB01D9D9D901DEDEDE01D8D8D801D9D9D903DADADA01 + DCDCDC01DADADA01DBDBDB01D8D8D801FEFEFE01DBDBDB02DADADA01A4A4A401 + D9D9D901DADADA01DCDCDC02D9D9D901DADADA01D9D9D901DADADA01D8D8D801 + DCDCDC01DADADA01ABABAB01DCDCDC01D8D8D801D9D9D901DADADA02DDDDDD01 + D9D9D902DBDBDB01D7D7D701DCDCDC01DADADA01D9D9D901DDDDDD01FCFCFC01 + DCDCDC01DBDBDB01D8D8D801D9D9D901DBDBDB03DADADA01DBDBDB02D9D9D901 + DDDDDD01DBDBDB01D5D5D501E0E0E001DADADA01D9D9D901DCDCDC01DBDBDB01 + D7D7D701DEDEDE01DBDBDB01D6D6D601DBDBDB01FFFFFF01FEFEFE01DCDCDC02 + D9D9D901DBDBDB01DCDCDC01A7A7A701D8D8D801ABABAB01D8D8D801A8A8A801 + FEFEFE01FFFFFF01D5D5D501DADADA02D8D8D801D9D9D901DADADA01D6D6D601 + DCDCDC01DADADA03DBDBDB01D5D5D501ABABAB01D8D8D801DBDBDB01DDDDDD01 + DBDBDB01D8D8D801ADADAD01A7A7A701A5A5A501ABABAB01D6D6D601DBDBDB02 + DADADA01D8D8D801DDDDDD01D9D9D901A6A6A601DADADA01DCDCDC01DADADA01 + D9D9D901DADADA01D9D9D901DBDBDB03DADADA01D9D9D901D7D7D701DBDBDB01 + D7D7D701DDDDDD01D6D6D601DBDBDB01DCDCDC01D7D7D701DADADA02D8D8D801 + DDDDDD01D9D9D901DCDCDC01FEFEFE01FFFFFF01FCFCFC01DBDBDB02DADADA01 + D9D9D901DBDBDB02D9D9D901DBDBDB01D8D8D801DBDBDB02D7D7D701DCDCDC01 + DBDBDB03D9D9D901DADADA02D9D9D901DBDBDB01FFFFFF01FDFDFD01FFFFFF01 + DBDBDB01DDDDDD01A8A8A801A7A7A701D9D9D901DADADA01DBDBDB02DADADA01 + D8D8D801DBDBDB01FFFFFF01FEFEFE01DADADA01D8D8D801DADADA01DBDBDB01 + DDDDDD01D7D7D701DBDBDB01DADADA01D9D9D901DDDDDD01D8D8D801DCDCDC01 + D8D8D801DADADA02DCDCDC01DADADA01D8D8D801DBDBDB02DADADA01D7D7D701 + DDDDDD01D9D9D901DBDBDB01D7D7D701DCDCDC01D9D9D901DCDCDC01DBDBDB01 + D6D6D601D9D9D901DADADA03D9D9D901FFFFFF01DADADA01DBDBDB01FEFEFE02 + FFFFFF01D8D8D801FEFEFE01FFFFFF01D9D9D901DADADA01FFFFFF03DADADA01 + A8A8A801DCDCDC01D7D7D701DCDCDC01DADADA03A8A8A801D9D9D901FFFFFF01 + DADADA01D7D7D701AAAAAA01A8A8A802ABABAB01D6D6D601DBDBDB01DCDCDC01 + D8D8D801DBDBDB01DCDCDC01D6D6D601DCDCDC01A9A9A901A7A7A701DBDBDB01 + D9D9D902DADADA02DBDBDB01D9D9D901A8A8A801DBDBDB01D9D9D901DADADA01 + DBDBDB01D9D9D901DCDCDC01D7D7D701DADADA04DCDCDC01D7D7D701DCDCDC01 + D9D9D901DADADA02D8D8D801DCDCDC01DBDBDB01D9D9D901DBDBDB01DADADA02 + D9D9D901FFFFFF02DCDCDC01DADADA01A5A5A501ABABAB01D8D8D801DADADA01 + D9D9D901DEDEDE01DADADA01D7D7D701DDDDDD01DADADA01D6D6D601DCDCDC01 + D9D9D901DADADA04DFDFDF01D8D8D801DADADA01D8D8D801DBDBDB01FEFEFE01 + D9D9D901DADADA01DCDCDC01DADADA03D9D9D901A8A8A801DBDBDB01DADADA01 + DCDCDC01FFFFFF01D9D9D901DBDBDB02D8D8D801D9D9D901DBDBDB01DADADA01 + D8D8D801DBDBDB01DADADA01DDDDDD01D8D8D801DBDBDB01D9D9D902DCDCDC01 + D9D9D901DCDCDC01D7D7D701DDDDDD01DADADA02D9D9D901DCDCDC01DADADA02 + DBDBDB01DADADA01D9D9D901DBDBDB01D9D9D901DCDCDC01D9D9D901DADADA01 + D8D8D801DCDCDC01D6D6D601DCDCDC01DDDDDD01D7D7D701DBDBDB01FFFFFF01 + FCFCFC01FFFFFF03FEFEFE01FFFFFF02DADADA01FFFFFF01DADADA01ABABAB01 + A7A7A702A9A9A901D8D8D801ABABAB01A5A5A501A9A9A901DADADA02DBDBDB01 + D8D8D801A8A8A801A7A7A701DADADA01DCDCDC01D9D9D901DEDEDE01D7D7D701 + DCDCDC01DADADA01DBDBDB01D8D8D801DBDBDB01A9A9A901D8D8D801D9D9D901 + DCDCDC01D9D9D901DADADA01DCDCDC01D8D8D801DCDCDC01DADADA02D9D9D901 + DADADA01D8D8D801D9D9D901DBDBDB01DCDCDC01D8D8D801A8A8A801A7A7A703 + AAAAAA01A8A8A801DADADA01DBDBDB01DADADA01DBDBDB01D9D9D901DBDBDB01 + DADADA02D9D9D901DDDDDD01D9D9D901D7D7D701DBDBDB01DADADA01AAAAAA01 + A7A7A701ABABAB01D7D7D701DCDCDC01D9D9D901D8D8D801DCDCDC02D8D8D801 + DADADA01DFDFDF01D8D8D801DCDCDC01DDDDDD01D7D7D701DBDBDB01D8D8D801 + D6D6D601DDDDDD01DADADA01DCDCDC02D9D9D901FDFDFD01FFFFFF01DADADA01 + D6D6D601DADADA01D9D9D901DBDBDB01DADADA01A8A8A801A7A7A701D7D7D701 + D9D9D901DBDBDB01D8D8D802DCDCDC01DEDEDE01D8D8D801DBDBDB02DADADA01 + D8D8D801D7D7D701DADADA01DCDCDC01DADADA01DCDCDC01D6D6D601DCDCDC01 + D7D7D701DCDCDC01D9D9D902DADADA01DBDBDB01DADADA01D9D9D901DCDCDC01 + D8D8D801DCDCDC01DBDBDB01D9D9D901DCDCDC01D6D6D601DCDCDC01DDDDDD01 + DADADA01D8D8D801DEDEDE01D9D9D901A3A3A301AAAAAA01A7A7A701FCFCFC01 + DDDDDD01DBDBDB01FEFEFE01FFFFFF01D8D8D801DCDCDC01DADADA01DBDBDB01 + FDFDFD01A6A6A601D9D9D901AAAAAA01A9A9A901A8A8A801ABABAB01D7D7D701 + A8A8A801A7A7A701DEDEDE01DADADA01FEFEFE01FFFFFF01FEFEFE01DCDCDC01 + D7D7D701D9D9D901DADADA01D4D4D401DCDCDC01D9D9D902D8D8D801DFDFDF01 + D7D7D701DBDBDB01DDDDDD01DBDBDB02D9D9D901DADADA02FDFDFD01DBDBDB01 + A6A6A601A8A8A801AAAAAA01DBDBDB01DCDCDC01DADADA02A6A6A601A8A8A801 + A6A6A601AAAAAA01ABABAB01AAAAAA01A5A5A501DADADA01DCDCDC01DBDBDB01 + D8D8D801DDDDDD01D9D9D901DADADA01D9D9D902DBDBDB01D7D7D701D9D9D901 + DEDEDE01DADADA01FFFFFF01FDFDFD01A6A6A601D8D8D801DDDDDD01DADADA02 + DBDBDB01D8D8D801DEDEDE01D9D9D901DCDCDC01D7D7D701DADADA01D9D9D901 + D6D6D601DCDCDC01D8D8D801DDDDDD01DADADA01D8D8D801DADADA01D8D8D801 + D7D7D701DBDBDB01DCDCDC01DADADA01D8D8D801DDDDDD01DBDBDB01FFFFFF01 + D9D9D902AAAAAA01D7D7D701DBDBDB03DEDEDE01DBDBDB01D8D8D803DBDBDB01 + D9D9D901DADADA01DCDCDC01DEDEDE01D8D8D801DCDCDC01D7D7D701D9D9D901 + DFDFDF01D7D7D701DEDEDE01DADADA01DBDBDB01DADADA01DBDBDB01DADADA01 + D9D9D901DBDBDB01D8D8D801D9D9D901DBDBDB01DADADA01D9D9D901DCDCDC01 + DADADA02D9D9D901DADADA01DBDBDB01D7D7D701DADADA01AAAAAA01A9A9A901 + A7A7A701ABABAB01D9D9D901DADADA01D9D9D901D7D7D701A9A9A902DADADA01 + DBDBDB02DFDFDF01FDFDFD01D6D6D601AAAAAA01D6D6D601DADADA01DFDFDF01 + D7D7D701A9A9A901D8D8D802FDFDFD01FFFFFF01DADADA01FCFCFC01FFFFFF01 + DCDCDC01DADADA01DEDEDE01DCDCDC01DADADA01FFFFFF02FEFEFE01A9A9A901 + A7A7A701D8D8D801D5D5D501DDDDDD01DCDCDC01DBDBDB01DADADA01DEDEDE01 + DBDBDB01A6A6A601A8A8A801ACACAC01A4A4A401A9A9A901A5A5A501A7A7A701 + DCDCDC01D7D7D701DEDEDE01D6D6D601D8D8D801D9D9D901A8A8A801D9D9D901 + DDDDDD01D6D6D601DCDCDC01D9D9D901DADADA01DBDBDB01DADADA01DBDBDB01 + AAAAAA01D6D6D601DDDDDD01DBDBDB01FDFDFD01FFFFFF02DBDBDB01DDDDDD01 + D7D7D701DADADA01DCDCDC01D9D9D901DBDBDB01D6D6D601DBDBDB02DCDCDC01 + DADADA01D8D8D801DFDFDF01D6D6D601DCDCDC01D9D9D901ABABAB01A7A7A701 + D9D9D901DADADA01DDDDDD01D9D9D903DADADA01DCDCDC01D7D7D701A8A8A801 + FEFEFE01FFFFFF01D6D6D601E1E1E101D8D8D801DBDBDB02D8D8D802DBDBDB03 + D7D7D701A8A8A801A9A9A901DADADA01DBDBDB01D7D7D701DBDBDB01DADADA01 + DBDBDB01DADADA01D8D8D801D9D9D903DADADA01D8D8D801DEDEDE01DADADA01 + D9D9D901DCDCDC01DDDDDD01DADADA01D6D6D601DADADA01D7D7D701DDDDDD01 + D9D9D901D8D8D801DADADA02FFFFFF02D8D8D801A7A7A701A9A9A901A5A5A501 + DADADA01DCDCDC01A8A8A801ABABAB01A8A8A801D9D9D901DADADA01FFFFFF01 + A6A6A601DBDBDB01FEFEFE01FFFFFF02DADADA01FFFFFF01FCFCFC01AAAAAA01 + D9D9D901DBDBDB01DEDEDE01D9D9D901DADADA01FFFFFF02FEFEFE01D9D9D901 + D8D8D801D9D9D902D7D7D701FFFFFF02DADADA01A8A8A801ACACAC01A9A9A901 + DBDBDB01A7A7A701A5A5A501A7A7A701A6A6A601FEFEFE01FFFFFF01FDFDFD01 + A7A7A701A6A6A601ABABAB01A5A5A501DCDCDC01DADADA02DDDDDD01D6D6D601 + DDDDDD01DCDCDC01A8A8A801AAAAAA01DBDBDB01DADADA01DBDBDB01DADADA01 + D8D8D801DADADA02D8D8D801DBDBDB01D7D7D701DDDDDD01D6D6D601D9D9D901 + DCDCDC01FFFFFF01D9D9D901D8D8D802DCDCDC01D9D9D902D8D8D801AAAAAA01 + DBDBDB01DADADA01D6D6D601DCDCDC01DBDBDB02D9D9D902DCDCDC01A6A6A602 + AAAAAA01DADADA01D9D9D901DADADA01DCDCDC01D8D8D801DFDFDF01D8D8D802 + DDDDDD01A6A6A601FFFFFF01DDDDDD01DBDBDB01D5D5D501D8D8D801DDDDDD01 + D8D8D801DBDBDB01DADADA01DEDEDE01D6D6D601D8D8D801DEDEDE01A7A7A703 + DBDBDB01DDDDDD01D9D9D901DCDCDC01D8D8D801DBDBDB01DEDEDE01DBDBDB01 + A7A7A701DEDEDE01D8D8D801DBDBDB01D7D7D701DADADA01DDDDDD01DADADA01 + D7D7D701D9D9D901DBDBDB01DDDDDD01DBDBDB01DADADA02DBDBDB02D8D8D801 + FFFFFF01D8D8D801DCDCDC01D9D9D901A7A7A701AAAAAA01DBDBDB01A8A8A801 + D8D8D801D7D7D701DBDBDB01D8D8D801FFFFFF02D7D7D701D9D9D901DCDCDC01 + D7D7D701D9D9D901DEDEDE01A5A5A501D8D8D801A7A7A701DDDDDD01DADADA01 + D4D4D401FFFFFF01A7A7A702FBFBFB01FFFFFF01DBDBDB01DADADA02A7A7A701 + AAAAAA01DBDBDB01FEFEFE02D7D7D701D8D8D801DDDDDD01D6D6D601DADADA01 + ABABAB01AAAAAA01A8A8A801FFFFFF01FEFEFE01FFFFFF02D7D7D701D9D9D902 + DADADA01DBDBDB01D9D9D902DCDCDC01D8D8D801D7D7D701AAAAAA01A8A8A801 + D5D5D501DBDBDB01DCDCDC01D8D8D801DCDCDC01DADADA01DCDCDC01FFFFFF01 + DADADA02D9D9D901DBDBDB01DDDDDD01D8D8D801DADADA01DCDCDC01D8D8D801 + DFDFDF01DCDCDC01D9D9D901A9A9A902D8D8D801DADADA01DCDCDC01DADADA02 + D8D8D801DADADA01D9D9D901DBDBDB01D9D9D901FEFEFE01AAAAAA01A8A8A801 + A7A7A701DADADA01D8D8D801DCDCDC01D9D9D901D5D5D501DFDFDF01FEFEFE01 + D8D8D801DBDBDB01DADADA01D6D6D601DBDBDB01DCDCDC01DDDDDD01D9D9D901 + DCDCDC01DBDBDB01D8D8D801D7D7D701DBDBDB01FFFFFF01FDFDFD01DBDBDB01 + A8A8A801DBDBDB01D8D8D801DADADA01D9D9D902DFDFDF01D7D7D701D9D9D901 + DBDBDB01D7D7D701DCDCDC01DBDBDB01DADADA01DCDCDC01D9D9D901D8D8D801 + DBDBDB01DFDFDF01D7D7D701A9A9A901A6A6A601D8D8D801DBDBDB01D9D9D902 + DBDBDB01A7A7A701D8D8D801DBDBDB01DADADA02A9A9A901A8A8A801FFFFFF01 + D9D9D902DCDCDC01D8D8D801DEDEDE01FFFFFF02DADADA01A8A8A802DADADA01 + A8A8A801A9A9A901DBDBDB01AAAAAA01A6A6A601DADADA01D9D9D901FFFFFF01 + DBDBDB01D9D9D901ABABAB01DCDCDC01FFFFFF01FEFEFE01FFFFFF02D8D8D801 + DBDBDB01A6A6A601D8D8D801FFFFFF02D9D9D901FDFDFD01FFFFFF01FBFBFB01 + DBDBDB01A7A7A701DBDBDB01D9D9D901FFFFFF02FBFBFB01FFFFFF01DADADA03 + D9D9D901DBDBDB01DADADA01D8D8D801D9D9D901DDDDDD01A5A5A501ABABAB01 + DDDDDD01D6D6D601D9D9D901DDDDDD01D8D8D801DADADA01D9D9D901DADADA02 + DBDBDB01DADADA01D7D7D701DCDCDC01D9D9D901D8D8D801DBDBDB01DADADA01 + D4D4D401D9D9D901D8D8D801DBDBDB01A5A5A501ADADAD01A8A8A801A5A5A501 + DBDBDB01DADADA01DCDCDC01DBDBDB01A8A8A801DBDBDB01DADADA02A9A9A901 + A5A5A501AAAAAA01DDDDDD01D9D9D901D8D8D801D9D9D901DEDEDE01A4A4A401 + FFFFFF01DCDCDC01D9D9D901DBDBDB01DADADA02DBDBDB01D8D8D801D7D7D701 + DCDCDC01D9D9D901DDDDDD01DADADA02FCFCFC01FFFFFF02DADADA01A8A8A801 + D9D9D901DCDCDC01DADADA01DCDCDC01D7D7D701DBDBDB02D9D9D901E0E0E001 + D6D6D601D8D8D801D9D9D901DADADA02DCDCDC01D8D8D801D7D7D701A8A8A801 + A9A9A901AAAAAA01A5A5A501DADADA01DCDCDC01D7D7D701DBDBDB01FFFFFF01 + DADADA01D9D9D901D8D8D801DDDDDD01A7A7A701DBDBDB01D7D7D701DEDEDE01 + ACACAC01D4D4D401D9D9D901DADADA01D8D8D801FEFEFE01FFFFFF01DDDDDD01 + FEFEFE01DBDBDB01FFFFFF01FEFEFE01FFFFFF01DBDBDB01A9A9A901DADADA01 + A8A8A801FFFFFF01FEFEFE01DADADA01A6A6A601DADADA01FEFEFE01FFFFFF01 + FEFEFE01FBFBFB01DCDCDC01DBDBDB01DADADA01A7A7A701DCDCDC01D7D7D701 + D9D9D901FFFFFF02FEFEFE01FFFFFF01DBDBDB01DADADA02D8D8D801FEFEFE01 + FFFFFF01D9D9D901DADADA02DEDEDE01D9D9D901D8D8D801DCDCDC02DDDDDD01 + D5D5D501A8A8A801A7A7A701DBDBDB01DDDDDD01DCDCDC01D7D7D701DCDCDC01 + D8D8D801DBDBDB01DADADA01DBDBDB01DADADA01DBDBDB01DADADA02DBDBDB01 + DADADA01DBDBDB01DDDDDD01DCDCDC01DADADA02A9A9A901A5A5A501A8A8A801 + A7A7A701DCDCDC01DBDBDB01D9D9D902A7A7A701D9D9D901AAAAAA01D7D7D701 + DDDDDD01DBDBDB01A7A7A701DADADA01D9D9D901DADADA01D9D9D901DDDDDD01 + D8D8D801A8A8A801A7A7A701D9D9D901DADADA03DCDCDC01D9D9D901DBDBDB01 + DADADA02D9D9D901DBDBDB01DADADA01D9D9D901DCDCDC01FFFFFF01D6D6D601 + DBDBDB01A8A8A801DADADA01D9D9D901DCDCDC01D8D8D801DCDCDC01DDDDDD01 + A5A5A501DADADA03DBDBDB01DCDCDC01D9D9D903DBDBDB01FFFFFF01D9D9D901 + A7A7A701A6A6A601AAAAAA01DADADA01A7A7A701DCDCDC01FDFDFD01FEFEFE01 + DBDBDB01DADADA01DBDBDB01D9D9D901A8A8A801DBDBDB01D8D8D801A9A9A901 + D8D8D801DCDCDC02D9D9D901DBDBDB01FFFFFF01FEFEFE02FFFFFF02FDFDFD01 + FFFFFF02A6A6A601A7A7A701A9A9A901A8A8A802DADADA01FFFFFF01DBDBDB01 + A9A9A901D8D8D801D7D7D701DCDCDC01DDDDDD01FEFEFE02DBDBDB02D9D9D901 + DBDBDB01A9A9A901D8D8D801FFFFFF02D9D9D901DADADA02DBDBDB03FFFFFF01 + D7D7D701DADADA01DBDBDB01D5D5D501FFFFFF01D9D9D901DADADA01FEFEFE01 + FDFDFD01DDDDDD01A9A9A901A7A7A701AAAAAA01D7D7D701D9D9D901DDDDDD01 + D8D8D801DCDCDC01DADADA01D9D9D901DBDBDB01D9D9D901DBDBDB02D8D8D801 + DBDBDB01DADADA01D8D8D801D9D9D901DADADA01D9D9D901DCDCDC01DADADA01 + D9D9D901DBDBDB01DADADA02D9D9D901DCDCDC01D9D9D901DBDBDB01D9D9D901 + DADADA01DDDDDD01D3D3D301DEDEDE01DCDCDC01D9D9D901DBDBDB01DADADA01 + D7D7D701FFFFFF01DADADA01DCDCDC01ABABAB01D7D7D701D9D9D901DCDCDC01 + D9D9D901DBDBDB01DADADA01DDDDDD01D9D9D901DADADA01DBDBDB01D7D7D701 + DCDCDC01D9D9D901DBDBDB01D9D9D901FFFFFF01D9D9D901A8A8A801A6A6A601 + DADADA01DCDCDC01DBDBDB01FFFFFF01DADADA03D9D9D901DADADA01D9D9D901 + DADADA01DDDDDD01D9D9D901DADADA01FEFEFE01FDFDFD01DBDBDB01DCDCDC01 + A5A5A501DBDBDB02D8D8D801D9D9D901DBDBDB01DADADA02D9D9D901D8D8D801 + FFFFFF01FEFEFE01DADADA01DBDBDB01A6A6A601A7A7A701DBDBDB03D9D9D901 + FFFFFF01D7D7D701DCDCDC01AAAAAA01A6A6A601A9A9A902DBDBDB01A7A7A701 + DADADA01A9A9A901DADADA01A9A9A901D8D8D801FEFEFE01DCDCDC01DADADA01 + D8D8D801DEDEDE01D9D9D903FFFFFF01DBDBDB01DADADA02A8A8A801AAAAAA01 + A8A8A801A7A7A701DADADA01D9D9D901DADADA02D8D8D801D9D9D901FFFFFF02 + D7D7D701DADADA01D9D9D901FFFFFF01FCFCFC01FFFFFF01FEFEFE01FDFDFD01 + FFFFFF01FEFEFE01AAAAAA01A5A5A501DBDBDB04DADADA02DCDCDC01D5D5D501 + DDDDDD01DADADA01D9D9D901DADADA01DEDEDE01D9D9D902DCDCDC01DADADA02 + D9D9D901D7D7D701D8D8D801DBDBDB01A7A7A701D9D9D901DBDBDB01DCDCDC01 + FDFDFD01FFFFFF01DADADA01D9D9D902DDDDDD01DCDCDC01D9D9D902DBDBDB01 + DADADA01DDDDDD01DCDCDC01FEFEFE01D7D7D701A6A6A601D9D9D901DCDCDC01 + DBDBDB01DADADA01D8D8D801DDDDDD01D9D9D901D6D6D601DDDDDD01D8D8D801 + D7D7D701DFDFDF01DADADA01D6D6D601DCDCDC01D8D8D801FFFFFF01DADADA02 + ACACAC01D9D9D901D6D6D601D8D8D801FFFFFF01DBDBDB01DADADA01D9D9D901 + DDDDDD01D9D9D901DDDDDD01DADADA01D8D8D801DADADA01D9D9D901FFFFFF03 + D7D7D701DBDBDB01FCFCFC01FFFFFF01D8D8D801A7A7A701DCDCDC01D8D8D801 + DBDBDB01DDDDDD01DADADA01D8D8D802D7D7D701AAAAAA01A7A7A701A8A8A801 + DFDFDF01D2D2D201D9D9D901DBDBDB02DADADA01A7A7A702A8A8A801ABABAB01 + D5D5D501DADADA04FAFAFA01ABABAB01A7A7A701FFFFFF01D8D8D801DADADA01 + DCDCDC01D5D5D501DCDCDC01AAAAAA01A9A9A901D7D7D701DADADA01DBDBDB01 + D9D9D901A7A7A702A8A8A801A6A6A601DCDCDC01DBDBDB01D8D8D801DBDBDB02 + DCDCDC01FDFDFD01FCFCFC01FFFFFF01FEFEFE01D9D9D901FFFFFF02D6D6D601 + DADADA01FFFFFF01FEFEFE01FFFFFF01FDFDFD01DEDEDE01DCDCDC01D8D8D801 + D9D9D901D8D8D801DEDEDE01D7D7D701D8D8D801ABABAB01DBDBDB01D9D9D901 + D8D8D801DCDCDC01A2A2A201DADADA03D9D9D902DEDEDE01DADADA01DDDDDD01 + A8A8A801D9D9D902A6A6A601D9D9D901DFDFDF01D7D7D701D9D9D901DDDDDD01 + DADADA02A8A8A801D9D9D902A8A8A801A6A6A601D8D8D801DBDBDB01D8D8D801 + DCDCDC01A9A9A901DADADA02D8D8D801DBDBDB01DDDDDD01DADADA01D8D8D801 + DFDFDF01DADADA01D8D8D801A8A8A801D7D7D701D9D9D901DEDEDE01D7D7D701 + D8D8D801FEFEFE02D7D7D701DBDBDB01D8D8D801DEDEDE01DCDCDC01D8D8D801 + DDDDDD01DBDBDB01DCDCDC01D7D7D701DADADA01D8D8D801D9D9D901DCDCDC01 + D9D9D901DCDCDC01FEFEFE02D8D8D801A8A8A801AAAAAA01A9A9A901D7D7D701 + DEDEDE01FFFFFF01FDFDFD01FEFEFE01FFFFFF01A5A5A501A8A8A801DADADA01 + DDDDDD01D8D8D801DCDCDC01A7A7A701D7D7D701DCDCDC01DDDDDD02DADADA01 + FDFDFD01FFFFFF01DADADA01D7D7D701DDDDDD01DBDBDB02DADADA02A7A7A701 + DBDBDB01DEDEDE01D9D9D901A7A7A701DCDCDC01DBDBDB01DADADA01DBDBDB01 + DEDEDE01D9D9D901A7A7A701DBDBDB01DADADA01DDDDDD01DADADA02D8D8D801 + DADADA01A9A9A901AFAFAF01D6D6D601DBDBDB01DCDCDC01DADADA01D7D7D702 + FFFFFF02D9D9D901DADADA02D9D9D901D6D6D601DFDFDF01D9D9D901D8D8D801 + FFFFFF01FDFDFD01DCDCDC01D8D8D802DCDCDC01DBDBDB01D9D9D901DDDDDD01 + DCDCDC01A9A9A901DBDBDB01D7D7D701D8D8D801DDDDDD01D8D8D801DBDBDB01 + DEDEDE01DCDCDC01D9D9D901DBDBDB02D9D9D902FEFEFE01D7D7D701DBDBDB01 + DADADA01DFDFDF01A8A8A801D6D6D601DBDBDB01DCDCDC01D6D6D601DADADA01 + A7A7A701DADADA01A9A9A901AAAAAA01A8A8A801ABABAB01D9D9D901FFFFFF01 + FEFEFE01A7A7A701DBDBDB01DADADA02DDDDDD01D7D7D701A7A7A701A8A8A801 + DADADA02D8D8D801DDDDDD01A7A7A701DCDCDC01D9D9D902DDDDDD01DBDBDB02 + FFFFFF01DCDCDC01DADADA01DCDCDC01D8D8D802DBDBDB01A7A7A701D8D8D801 + DBDBDB02A9A9A901AAAAAA01D8D8D801D9D9D901DDDDDD01D9D9D902FFFFFF01 + DBDBDB01D9D9D901A6A6A601AAAAAA01D8D8D802FDFDFD01FFFFFF01DBDBDB01 + D9D9D901FFFFFF01DBDBDB01D9D9D901DADADA01DCDCDC01D7D7D701A9A9A901 + DDDDDD01D4D4D401DADADA01D9D9D902FFFFFF02DADADA01D9D9D901DCDCDC01 + D4D4D401DADADA01DBDBDB01DCDCDC01A9A9A901D9D9D901D7D7D701A9A9A901 + DADADA01A6A6A601D9D9D901DADADA01D8D8D801D9D9D901FFFFFF01A5A5A501 + ABABAB01DADADA01FCFCFC01DCDCDC01D8D8D801DBDBDB01DCDCDC01A4A4A401 + D6D6D601DADADA01DBDBDB01D7D7D701DBDBDB03DADADA01DBDBDB01A8A8A801 + A7A7A701D8D8D801DCDCDC01DDDDDD01D5D5D501DBDBDB01D9D9D901DBDBDB01 + DCDCDC01DBDBDB01DADADA01DCDCDC01DADADA01D9D9D901DCDCDC01D9D9D901 + FDFDFD01A5A5A501DBDBDB01DCDCDC01DADADA01FFFFFF01D9D9D901DDDDDD01 + D5D5D501D9D9D901DADADA01DBDBDB01D5D5D501DBDBDB01DDDDDD01D8D8D801 + DEDEDE01FFFFFF01FEFEFE02DBDBDB01DADADA01FFFFFF01FDFDFD01DDDDDD01 + DADADA01DBDBDB01DADADA01DCDCDC01D9D9D901A7A7A701A9A9A901A5A5A501 + FFFFFF02DBDBDB01D8D8D801DADADA01D9D9D902DBDBDB01DCDCDC01D8D8D801 + DBDBDB02FEFEFE01DBDBDB01D9D9D901D7D7D701DCDCDC01D9D9D901DADADA02 + D7D7D701DBDBDB01D8D8D801DADADA02DBDBDB01DCDCDC01DADADA01A8A8A801 + DCDCDC01DADADA02A8A8A801A9A9A901ABABAB01A7A7A701D7D7D701DBDBDB01 + FFFFFF01FEFEFE01FDFDFD01FFFFFF01DBDBDB01FCFCFC01DDDDDD01DBDBDB01 + DADADA01D7D7D701FFFFFF02D9D9D901FFFFFF01FCFCFC01FFFFFF01FEFEFE01 + DADADA02D8D8D801DCDCDC02D9D9D901DBDBDB01FFFFFF01FBFBFB01FEFEFE01 + DCDCDC01D9D9D901FFFFFF01DCDCDC01D8D8D801FDFDFD01FCFCFC01DCDCDC01 + FFFFFF01A6A6A601DBDBDB01ABABAB01A8A8A801D8D8D801DFDFDF01D5D5D501 + DADADA01DEDEDE01D7D7D701FFFFFF02D7D7D701DCDCDC01DBDBDB01D8D8D801 + DADADA01DFDFDF01D8D8D801DBDBDB01DDDDDD01DADADA03FFFFFF01D8D8D801 + A7A7A701DADADA01DBDBDB01D8D8D801DADADA01D9D9D902DADADA01DBDBDB01 + D7D7D701DADADA01D9D9D901DBDBDB01D7D7D701DEDEDE01D7D7D701FFFFFF01 + DBDBDB01DCDCDC01DADADA01D7D7D701DADADA03DBDBDB01DCDCDC01D7D7D701 + DCDCDC01DADADA01DFDFDF01D8D8D801A6A6A601DBDBDB01D9D9D902FEFEFE01 + DBDBDB01FFFFFF02FCFCFC01FFFFFF01D9D9D901A5A5A501FFFFFF01DBDBDB01 + D8D8D801DEDEDE01A7A7A701A6A6A601ABABAB01FFFFFF01D6D6D601DBDBDB01 + DADADA01DCDCDC01A7A7A701FFFFFF02D6D6D601DBDBDB01DDDDDD01D9D9D901 + FFFFFF01D8D8D801DDDDDD01D9D9D901DBDBDB01DADADA01D8D8D801DADADA01 + DBDBDB01D9D9D901D8D8D801DEDEDE01D9D9D902FDFDFD01DEDEDE01D7D7D701 + D9D9D901FEFEFE01FFFFFF01D9D9D901A7A7A701A6A6A601A4A4A401DFDFDF01 + D8D8D801DADADA01D8D8D801FFFFFF02FEFEFE01DDDDDD01D7D7D701D9D9D901 + DBDBDB01FEFEFE01DCDCDC01DBDBDB01FFFFFF03FDFDFD01FFFFFF01DADADA01 + D9D9D901DADADA01DEDEDE01D6D6D601D9D9D901DADADA01FFFFFF05FCFCFC01 + FFFFFF04FEFEFE01D8D8D801DBDBDB01A5A5A501A8A8A801A9A9A901FFFFFF01 + DCDCDC01FFFFFF02D9D9D901DBDBDB01FFFFFF01FEFEFE01FFFFFF01DADADA01 + D8D8D802DDDDDD01D7D7D701D8D8D801DADADA01D8D8D801D6D6D601DCDCDC01 + D8D8D801FFFFFF02D9D9D901DBDBDB01DADADA02D8D8D801DBDBDB01DADADA01 + D9D9D902DEDEDE01DCDCDC01D9D9D901DDDDDD01DCDCDC01D8D8D801DADADA01 + FEFEFE01DBDBDB01D8D8D801DBDBDB01DEDEDE01D8D8D801DBDBDB01D6D6D601 + D9D9D901DADADA01DCDCDC01DDDDDD01D8D8D801D9D9D901DBDBDB01DCDCDC02 + D9D9D901DBDBDB01FFFFFF01FEFEFE01DBDBDB01D9D9D901FFFFFF01FDFDFD01 + D9D9D901A9A9A901DBDBDB01D6D6D601DDDDDD01D7D7D701FFFFFF01AAAAAA01 + D7D7D701DADADA01DDDDDD01D9D9D901DCDCDC01D6D6D601ABABAB01A8A8A801 + D9D9D901DCDCDC01DADADA01D9D9D901D8D8D801DADADA01DDDDDD01D8D8D801 + D9D9D901D8D8D801DEDEDE01D6D6D601DBDBDB01DCDCDC01D9D9D901DCDCDC01 + D8D8D801DDDDDD01D9D9D901FFFFFF01D8D8D801DCDCDC01DADADA01FEFEFE01 + FFFFFF01FBFBFB01FFFFFF01A7A7A701A8A8A801D9D9D901DBDBDB01DADADA01 + DBDBDB01D8D8D802A6A6A601A9A9A901DDDDDD01D9D9D901A6A6A601AAAAAA01 + F9F9F901A7A7A701D9D9D901D8D8D801DADADA01A8A8A801D9D9D901DBDBDB01 + DADADA02A7A7A701D9D9D901DADADA01DCDCDC01DADADA01FCFCFC01FFFFFF01 + D8D8D801FEFEFE01FFFFFF01D9D9D901D7D7D701D8D8D801DBDBDB01FDFDFD01 + D9D9D901DEDEDE01DADADA01A6A6A601DADADA01FEFEFE01DADADA02D6D6D601 + DDDDDD01DADADA01FFFFFF02D9D9D901DBDBDB01A9A9A901DCDCDC01D8D8D801 + DBDBDB01DCDCDC01D9D9D901DBDBDB03D6D6D601FFFFFF01DADADA03D7D7D701 + DDDDDD01D9D9D901DBDBDB02D9D9D901D7D7D701DADADA01D7D7D701DDDDDD01 + A5A5A501A6A6A601ADADAD01D8D8D801D9D9D901DADADA01D8D8D801DBDBDB01 + DADADA03DBDBDB01DCDCDC01D9D9D901A8A8A801D7D7D701DCDCDC01FDFDFD02 + FFFFFF01DADADA01D8D8D801FFFFFF01D7D7D701DDDDDD01D8D8D801DCDCDC01 + FEFEFE01FFFFFF01DBDBDB01D9D9D901D8D8D801DCDCDC01DADADA01D9D9D901 + FFFFFF01DADADA01D9D9D901DCDCDC01D9D9D901DADADA01FFFFFF01DEDEDE01 + A5A5A501A8A8A801A9A9A901D9D9D901DBDBDB01D9D9D901DBDBDB02D8D8D801 + DBDBDB01DADADA02D7D7D701DCDCDC01DADADA01D8D8D801DBDBDB01D9D9D901 + DBDBDB01D8D8D801DADADA01DCDCDC01D7D7D701D9D9D901DCDCDC01D9D9D901 + FFFFFF02FDFDFD01A7A7A701AAAAAA01A7A7A701DADADA01D8D8D801DCDCDC01 + D8D8D801FFFFFF01D9D9D901D8D8D801FFFFFF01D9D9D901DADADA02AAAAAA01 + A8A8A802DADADA01D9D9D901DBDBDB01DCDCDC01D8D8D801D9D9D901A9A9A901 + A7A7A701DBDBDB02D9D9D901DADADA01DCDCDC01D9D9D901DCDCDC01DADADA01 + D7D7D701DDDDDD01DBDBDB02D8D8D801FFFFFF02D9D9D901FFFFFF01A6A6A601 + DBDBDB01DCDCDC01D8D8D801DADADA01ABABAB01D8D8D801DADADA01DCDCDC01 + FDFDFD01FFFFFF01D8D8D801A8A8A801DBDBDB01D9D9D901DBDBDB01D9D9D901 + DADADA02D8D8D801DADADA01DDDDDD01D8D8D801DADADA01DBDBDB01D9D9D901 + DDDDDD01D7D7D701DBDBDB02D8D8D801DCDCDC01DADADA01D9D9D901DBDBDB01 + D9D9D901DADADA01DBDBDB01D7D7D701DCDCDC02D9D9D901DBDBDB02D9D9D901 + DBDBDB02D8D8D801DADADA01DBDBDB01A9A9A901DADADA01FEFEFE01FFFFFF03 + DCDCDC01D9D9D901DADADA02DCDCDC01D7D7D701DADADA01D9D9D901FFFFFF02 + D8D8D801DADADA01DBDBDB01A7A7A701FCFCFC01DCDCDC01D9D9D901D8D8D801 + DCDCDC01DBDBDB01D9D9D901FFFFFF02A7A7A701A9A9A902A7A7A701DCDCDC01 + D9D9D901D8D8D801DBDBDB02DADADA09D9D9D901DADADA01DBDBDB01D6D6D601 + DCDCDC01DDDDDD01D9D9D901D8D8D801DEDEDE01FDFDFD01DCDCDC01A9A9A901 + A7A7A701A8A8A802DADADA01D9D9D901FFFFFF02DADADA02FFFFFF02A5A5A501 + DCDCDC01A9A9A901DADADA01DBDBDB01FDFDFD01DBDBDB02D9D9D901DADADA01 + FEFEFE01ABABAB01D7D7D701DBDBDB01D8D8D801DCDCDC01DADADA08DCDCDC01 + D8D8D801FFFFFF01FEFEFE01D9D9D901A9A9A901A6A6A601A9A9A901A7A7A701 + D9D9D901DCDCDC01D9D9D901DADADA02FDFDFD01FFFFFF01FEFEFE01A6A6A601 + AAAAAA01D9D9D901DBDBDB01D8D8D801DDDDDD01D9D9D902DBDBDB02D9D9D901 + DCDCDC01D8D8D802DCDCDC01DADADA01D8D8D801D7D7D701DDDDDD01DADADA02 + DEDEDE01D8D8D801FFFFFF01FEFEFE01FFFFFF01DCDCDC01D9D9D902DBDBDB01 + DADADA01DCDCDC01D8D8D801DBDBDB01DADADA01DBDBDB01DADADA01D7D7D701 + A9A9A901A7A7A701ABABAB01DADADA01D9D9D901DDDDDD01D9D9D901D8D8D801 + DADADA01D9D9D901DBDBDB01D9D9D901DDDDDD01DADADA01D9D9D901FDFDFD01 + FFFFFF01DDDDDD01D7D7D701DCDCDC01A7A7A701DCDCDC01D9D9D901DCDCDC01 + DADADA01D9D9D901DADADA02FDFDFD01FFFFFF01D9D9D901A7A7A701DCDCDC01 + DADADA01DDDDDD01DCDCDC01DBDBDB01D8D8D801DADADA0ADDDDDD01D9D9D902 + E1E1E101D6D6D602DADADA01DCDCDC01DADADA01D9D9D902DADADA01A6A6A601 + A9A9A901A8A8A801DADADA01DCDCDC01DBDBDB01D7D7D701DADADA01DCDCDC01 + D8D8D801DBDBDB01DCDCDC01D8D8D801FFFFFF01D9D9D901AAAAAA01DADADA01 + DCDCDC01D8D8D801DBDBDB01DCDCDC01D8D8D801D7D7D701DCDCDC01DBDBDB02 + D8D8D801DADADA09DBDBDB01DADADA01A9A9A901D7D7D701AAAAAA01A8A8A801 + A6A6A601AAAAAA01FFFFFF01D8D8D801D9D9D902DBDBDB01DCDCDC01DBDBDB01 + FFFFFF01DDDDDD01D7D7D702DCDCDC01D8D8D802A9A9A901DCDCDC01DADADA02 + DBDBDB01D6D6D601DBDBDB01DEDEDE01D8D8D801D9D9D901DEDEDE01DCDCDC01 + DBDBDB01D8D8D801A6A6A601D9D9D901DBDBDB02DADADA01DEDEDE01D7D7D701 + DCDCDC01DADADA01D8D8D801DADADA01D9D9D902DDDDDD01D7D7D701DBDBDB01 + D6D6D601FFFFFF01A9A9A901DCDCDC01D3D3D301DFDFDF01D8D8D801D9D9D901 + DADADA02DBDBDB01DDDDDD01D8D8D801DBDBDB01D9D9D901D8D8D801DBDBDB01 + DADADA01D8D8D803A7A7A703A8A8A801D8D8D801DBDBDB02D9D9D901D8D8D801 + FFFFFF01FBFBFB01DADADA01FFFFFF01D6D6D601DADADA01A8A8A801D4D4D401 + DEDEDE01DCDCDC01DADADA09D6D6D601DDDDDD01D9D9D902D7D7D701A6A6A601 + ACACAC01A8A8A801A7A7A701D8D8D801DFDFDF01D6D6D601DDDDDD01DBDBDB01 + A9A9A901D9D9D901DADADA01DBDBDB01A5A5A501AAAAAA01A5A5A501A8A8A801 + DCDCDC01D9D9D901DDDDDD01A5A5A501DDDDDD01A8A8A801A9A9A901A6A6A601 + DCDCDC01DADADA01D9D9D901FCFCFC01DCDCDC02D9D9D901DCDCDC01D5D5D501 + DDDDDD01DADADA08D9D9D901DDDDDD01D6D6D601DADADA01D9D9D902DCDCDC01 + A9A9A901DADADA01D5D5D501DADADA01DBDBDB01AAAAAA01D5D5D501DBDBDB01 + FDFDFD02D9D9D901DBDBDB02D7D7D701DEDEDE01DCDCDC01A7A7A701D7D7D701 + DDDDDD01D7D7D701DFDFDF01DCDCDC01D7D7D701DADADA02AAAAAA01A4A4A401 + DADADA01D8D8D801DBDBDB01DCDCDC01DADADA01DCDCDC01D9D9D901DBDBDB01 + D6D6D601DADADA03DCDCDC01DBDBDB02DCDCDC01D9D9D901DADADA01FFFFFF03 + D8D8D801DCDCDC01DBDBDB01D9D9D901DBDBDB01D9D9D902DCDCDC01DADADA01 + D8D8D801DADADA01D9D9D901DBDBDB01DCDCDC01A6A6A601D9D9D901E1E1E101 + DADADA01DCDCDC01A7A7A701D9D9D901DCDCDC01D8D8D801DCDCDC01D7D7D701 + DDDDDD01DBDBDB02F8F8F801FFFFFF01AAAAAA01A8A8A801A9A9A901DBDBDB01 + D9D9D901DEDEDE01D9D9D901D8D8D801DCDCDC01DADADA08DDDDDD01D7D7D701 + DBDBDB01DADADA01A9A9A901AAAAAA01A5A5A501A9A9A901DCDCDC01DADADA01 + FEFEFE01DDDDDD01D9D9D901D8D8D801A5A5A501DBDBDB01DCDCDC01A6A6A601 + ABABAB01A8A8A801AAAAAA01D7D7D701DADADA01DDDDDD01A7A7A701A8A8A801 + FEFEFE01A8A8A801A9A9A902A4A4A401DBDBDB01FFFFFF01DCDCDC01D9D9D901 + D8D8D801DBDBDB01D9D9D901DCDCDC01DADADA09FEFEFE01FFFFFF01DEDEDE01 + D9D9D901DDDDDD01DADADA01D7D7D701A6A6A602DEDEDE01A8A8A801D8D8D802 + DCDCDC02DBDBDB01DCDCDC01D9D9D901DEDEDE01A7A7A701DADADA01FFFFFF01 + D6D6D601DADADA01DBDBDB02DCDCDC01D4D4D401D9D9D901DEDEDE01D5D5D501 + DDDDDD01A6A6A601AAAAAA01DDDDDD01FDFDFD01DEDEDE01D9D9D901DBDBDB01 + D7D7D701A6A6A601ABABAB01A8A8A801DBDBDB01D9D9D902DBDBDB01D8D8D801 + DBDBDB01D9D9D901D8D8D801DCDCDC01D9D9D901FCFCFC01A9A9A901A7A7A701 + D6D6D601DCDCDC01D9D9D901DDDDDD01DBDBDB01DADADA01DCDCDC01D4D4D401 + DFDFDF01DBDBDB01DADADA02D9D9D901DDDDDD01D9D9D901D8D8D802DADADA01 + FFFFFF01FEFEFE01DCDCDC01D9D9D901D8D8D801DBDBDB01D9D9D902DCDCDC01 + FFFFFF01DADADA01D7D7D701A8A8A801FFFFFF01DBDBDB01D9D9D901DADADA01 + DDDDDD01D8D8D801DADADA09D9D9D901DADADA01A8A8A801D9D9D901DCDCDC01 + D8D8D801DCDCDC01D8D8D801D9D9D901D7D7D701DADADA01DBDBDB01DCDCDC01 + A7A7A701DEDEDE01D8D8D801FDFDFD01DDDDDD01D8D8D801DBDBDB01DADADA01 + DBDBDB01DDDDDD01D6D6D601A8A8A801D8D8D801DEDEDE01DCDCDC01A4A4A401 + ABABAB01AAAAAA01A7A7A701A4A4A401D9D9D901DADADA01DDDDDD01D5D5D501 + DADADA01DCDCDC01D9D9D901DADADA08FFFFFF01FEFEFE01FCFCFC01D9D9D902 + D8D8D801DDDDDD01A9A9A902A6A6A601FFFFFF01DBDBDB01DCDCDC01D8D8D803 + D9D9D901D7D7D701DCDCDC01D7D7D701DADADA01FFFFFF01D9D9D901DCDCDC02 + D7D7D701D8D8D801DFDFDF01DBDBDB01DCDCDC01FFFFFF02ACACAC01D7D7D701 + D8D8D801D9D9D902DBDBDB01D8D8D801ABABAB01A9A9A901A4A4A401DBDBDB03 + D8D8D801D9D9D901DCDCDC01DADADA01D9D9D901DEDEDE01D6D6D601D8D8D801 + DCDCDC01ABABAB01DADADA01DCDCDC01DBDBDB01D9D9D901D7D7D701D9D9D902 + DADADA01DBDBDB01DDDDDD01D5D5D501D8D8D801FFFFFF01DADADA01D7D7D701 + DBDBDB01DADADA01DCDCDC01A8A8A801D8D8D801DADADA03DBDBDB02DCDCDC01 + DADADA01DBDBDB01FFFFFF03D9D9D901D8D8D801DADADA01DDDDDD01DBDBDB01 + D6D6D601DCDCDC01DADADA09D8D8D801DDDDDD01D8D8D801DADADA01DBDBDB01 + DADADA02DBDBDB01A6A6A601DFDFDF01DBDBDB01D8D8D801D9D9D901DADADA01 + D8D8D801FFFFFF01FEFEFE01DBDBDB01D8D8D801D9D9D901DBDBDB01D7D7D701 + DCDCDC01DBDBDB01A9A9A901DADADA01FBFBFB01D9D9D901DDDDDD01D5D5D501 + A8A8A801AAAAAA01A9A9A902DCDCDC02DBDBDB01DADADA01DBDBDB01D9D9D901 + DADADA08FFFFFF01FEFEFE01DCDCDC01DBDBDB02DADADA01D7D7D701A9A9A901 + DADADA01D8D8D801D9D9D901DBDBDB01DADADA02DBDBDB01DCDCDC01DADADA01 + FFFFFF01D7D7D701DCDCDC01DEDEDE01A7A7A701D9D9D901DBDBDB01D9D9D901 + DCDCDC01DADADA03D7D7D701FEFEFE01FFFFFF01DADADA03DBDBDB02DADADA01 + DBDBDB01FDFDFD01FFFFFF01DCDCDC01DBDBDB01D9D9D902DBDBDB02D7D7D701 + DADADA02D7D7D701DCDCDC01FFFFFF02D5D5D501DADADA01DBDBDB01D9D9D901 + DCDCDC01D9D9D901DDDDDD01DCDCDC01DADADA02D8D8D801D9D9D901FFFFFF01 + DADADA01D7D7D701DCDCDC01DBDBDB01D8D8D801AAAAAA01D4D4D401DEDEDE01 + DBDBDB01D9D9D902DBDBDB01D7D7D701D9D9D901DADADA02A6A6A601FFFFFF01 + DADADA01DDDDDD01A7A7A701DBDBDB01D8D8D801D5D5D501E1E1E101DBDBDB01 + D7D7D701DADADA08FEFEFE02DBDBDB02D9D9D901DBDBDB01D9D9D902DCDCDC01 + D8D8D801D7D7D701DBDBDB01A8A8A801DEDEDE01DADADA01FEFEFE01FFFFFF01 + D8D8D801DDDDDD01D9D9D901DCDCDC01D9D9D901D8D8D801DADADA02FEFEFE01 + FFFFFF03DFDFDF01D8D8D801A6A6A601A5A5A501A9A9A901D9D9D901D6D6D601 + D8D8D801DCDCDC01DADADA01DCDCDC01DADADA08DBDBDB01FCFCFC01FFFFFF02 + A7A7A701DADADA01DCDCDC01D7D7D701A9A9A901DCDCDC01D5D5D501DCDCDC01 + D8D8D801D9D9D901DFDFDF01D6D6D601DADADA01D8D8D801DFDFDF01D6D6D601 + A6A6A601DADADA01D8D8D801DBDBDB01DADADA02D8D8D801DCDCDC01D4D4D401 + DDDDDD01FFFFFF01DBDBDB01DADADA03DCDCDC01D8D8D801D9D9D901FFFFFF02 + DADADA01D7D7D701DDDDDD01DBDBDB01DADADA01D9D9D901DDDDDD01D9D9D901 + DBDBDB01A7A7A701DEDEDE01FDFDFD01FFFFFF01DADADA01D9D9D901DBDBDB01 + D9D9D901D8D8D801DBDBDB01D9D9D902D8D8D801D9D9D901DBDBDB01DADADA01 + D9D9D901FEFEFE01DADADA01DCDCDC01DADADA02FFFFFF01DBDBDB01A9A9A901 + DADADA01A6A6A601DCDCDC01DADADA02DBDBDB01DDDDDD01DADADA01D8D8D801 + DDDDDD01D7D7D701DCDCDC01DADADA01D8D8D801DCDCDC01D9D9D901DDDDDD01 + D8D8D801D9D9D901DCDCDC01DADADA08FFFFFF01FDFDFD01DADADA01DCDCDC01 + D8D8D801DCDCDC01DADADA01DBDBDB01D8D8D801DBDBDB01DDDDDD01A9A9A901 + A6A6A601D9D9D901A8A8A801FFFFFF01FDFDFD01FFFFFF01FCFCFC01FFFFFF02 + DBDBDB01D8D8D801DBDBDB01DCDCDC01FEFEFE01FFFFFF01FDFDFD01FFFFFF01 + FEFEFE01FFFFFF01DBDBDB01A9A9A901D9D9D901DBDBDB03DADADA01D8D8D801 + DADADA09FFFFFF02FEFEFE02DBDBDB01D9D9D901D8D8D801AAAAAA01A7A7A701 + D9D9D901DCDCDC01DADADA03D9D9D901DBDBDB01DADADA02D9D9D901FFFFFF01 + DADADA02DBDBDB01D9D9D901DADADA01DBDBDB01DADADA02DDDDDD01D7D7D701 + DBDBDB01D8D8D801DADADA01D9D9D901DBDBDB01D8D8D801FFFFFF01A9A9A901 + D9D9D902DADADA01DCDCDC01D8D8D801D9D9D901DEDEDE01D8D8D801D9D9D901 + DBDBDB01D9D9D901A9A9A901D9D9D901D8D8D801DBDBDB02DADADA01D9D9D901 + DADADA03DCDCDC01DADADA02DCDCDC01D8D8D801DBDBDB01FEFEFE01FFFFFF01 + FEFEFE01FFFFFF02FEFEFE01DBDBDB01DADADA02DDDDDD01D9D9D902DCDCDC01 + D9D9D901DBDBDB01A7A7A701DBDBDB01DADADA01DBDBDB01D9D9D901FFFFFF01 + DBDBDB01D7D7D701DADADA01DDDDDD01D7D7D701D9D9D901DADADA02DCDCDC01 + DADADA01D9D9D901DADADA02DBDBDB01DADADA01D9D9D901FFFFFF01FEFEFE01 + DBDBDB01D9D9D901DCDCDC01D9D9D901DDDDDD01D7D7D701DADADA01D9D9D902 + A7A7A701DADADA01DBDBDB01A6A6A601FFFFFF04FDFDFD01FFFFFF01D9D9D901 + DCDCDC01A8A8A801DADADA02DBDBDB01FEFEFE01FFFFFF01FDFDFD01FFFFFF02 + DADADA09D8D8D801DADADA03A7A7A701ABABAB01D8D8D801DBDBDB01D9D9D901 + FDFDFD01FFFFFF01D7D7D701DADADA02AAAAAA01A8A8A801DBDBDB01A6A6A601 + ABABAB01D8D8D801DCDCDC01D8D8D801DBDBDB02D8D8D801FFFFFF01D9D9D902 + A5A5A501ABABAB01A6A6A601AAAAAA01D8D8D801DBDBDB01D9D9D901DCDCDC01 + D7D7D701DEDEDE01D8D8D801DADADA01DBDBDB01D8D8D801FFFFFF01A7A7A701 + A5A5A501DBDBDB02D9D9D901DBDBDB01D9D9D901DBDBDB01A8A8A801DADADA02 + FFFFFF01DBDBDB01A6A6A601DEDEDE01D7D7D701D8D8D801DBDBDB01D9D9D901 + DBDBDB02DADADA01D9D9D901DADADA01DBDBDB01DADADA01D8D8D801DDDDDD01 + DADADA01FEFEFE01FFFFFF03D8D8D801A9A9A901FFFFFF01D8D8D801FDFDFD01 + DBDBDB01DCDCDC01D9D9D901D8D8D801DCDCDC01D8D8D801A8A8A802A6A6A601 + A5A5A501A8A8A801D9D9D902DDDDDD01DBDBDB01D7D7D701DDDDDD02DBDBDB02 + D7D7D701DCDCDC01DBDBDB01D9D9D902DBDBDB01DADADA01DBDBDB01FEFEFE01 + DBDBDB01D6D6D601DEDEDE01D9D9D903DDDDDD01DADADA01DBDBDB02A7A7A701 + FFFFFF01D8D8D801DDDDDD01DBDBDB01DADADA01D6D6D601DDDDDD01FFFFFF01 + D8D8D801DDDDDD01A8A8A802DCDCDC01D8D8D801D9D9D901DCDCDC01D9D9D901 + FFFFFF01F9F9F901DCDCDC01DADADA08DBDBDB01DCDCDC01D9D9D901DBDBDB01 + D9D9D901DADADA01D9D9D901DEDEDE01DADADA01D7D7D701DCDCDC01DADADA01 + DCDCDC01DADADA01DCDCDC01A4A4A401A6A6A601A8A8A801ABABAB02D9D9D901 + D7D7D701DDDDDD01D8D8D802DCDCDC01D8D8D801DCDCDC01DDDDDD01A8A8A802 + A7A7A701D7D7D701DFDFDF01D9D9D902DBDBDB01D6D6D601DADADA01DCDCDC01 + D7D7D701DADADA01DDDDDD01FBFBFB01DCDCDC01DDDDDD01D9D9D901DADADA01 + DBDBDB01DCDCDC01DADADA01D9D9D901DBDBDB01D7D7D701DDDDDD01FDFDFD01 + D9D9D901A7A7A701D9D9D901DDDDDD01DADADA01DCDCDC01D9D9D902DADADA01 + D9D9D901DEDEDE01DADADA02D9D9D901DADADA01DBDBDB01D7D7D701DDDDDD01 + D9D9D901DADADA02DBDBDB01A6A6A601DADADA01DEDEDE01D8D8D801DADADA01 + DBDBDB02DCDCDC01FCFCFC01FFFFFF01D8D8D801A7A7A701ADADAD01AAAAAA01 + DADADA01D9D9D902D7D7D701DADADA01DCDCDC01D9D9D901DBDBDB01D6D6D601 + DADADA01DCDCDC01D8D8D802DDDDDD01D9D9D901D7D7D701DCDCDC01DADADA01 + D9D9D901DBDBDB01DADADA01D9D9D903DDDDDD01D8D8D801DADADA01D8D8D801 + A8A8A801DEDEDE01FEFEFE01D8D8D801D9D9D901D8D8D801DBDBDB01DDDDDD01 + D5D5D501FEFEFE01DADADA02A7A7A701D8D8D801D6D6D601DEDEDE01DADADA01 + D9D9D901DBDBDB02DDDDDD01D7D7D701DADADA08D8D8D801D9D9D901DCDCDC01 + FDFDFD01FFFFFF01D8D8D801DBDBDB01D6D6D601DADADA01DCDCDC01D9D9D901 + D8D8D801DBDBDB01D9D9D902AAAAAA01DADADA01DBDBDB01A4A4A401DADADA02 + DBDBDB01D8D8D801DCDCDC01D9D9D901DEDEDE01DBDBDB01FDFDFD02FEFEFE01 + DADADA02DCDCDC01D7D7D701DADADA01DBDBDB01DADADA01DBDBDB01DADADA01 + D9D9D901DEDEDE01DADADA01FBFBFB01FFFFFF01D8D8D801DADADA01D9D9D902 + D8D8D802FFFFFF01DEDEDE01D7D7D701DBDBDB01D7D7D701FFFFFF01DADADA01 + AAAAAA01A7A7A701D8D8D801DCDCDC01D8D8D801DADADA01DBDBDB01D7D7D701 + DDDDDD01D7D7D701DADADA01DBDBDB01D8D8D801DADADA01DDDDDD01A4A4A401 + DADADA01D9D9D901DADADA01FFFFFF01D8D8D801DCDCDC01DADADA01D4D4D401 + DFDFDF01D9D9D902DADADA01D9D9D901FEFEFE01DCDCDC01FFFFFF02D9D9D901 + A5A5A501DBDBDB01D9D9D902DCDCDC02DADADA01DBDBDB01D7D7D701DEDEDE01 + DADADA01D9D9D901DADADA01D9D9D901D8D8D801DEDEDE01DADADA02FDFDFD01 + FFFFFF01D9D9D901DADADA01DCDCDC01DBDBDB01DADADA01D9D9D901DBDBDB01 + DADADA01DBDBDB01A6A6A601A4A4A401DDDDDD01DCDCDC01DBDBDB01DDDDDD01 + DADADA01D8D8D801FFFFFF01DBDBDB01D8D8D801DBDBDB01A5A5A501DEDEDE01 + DDDDDD01A5A5A501A9A9A901AAAAAA01D9D9D901DADADA01D9D9D901DCDCDC01 + DADADA08DBDBDB01DDDDDD01D9D9D902DBDBDB01D8D8D801DCDCDC01DBDBDB01 + FEFEFE01FFFFFF01D7D7D701DBDBDB01D9D9D901DBDBDB01DADADA01D9D9D901 + DDDDDD01D8D8D801ACACAC01D9D9D901DBDBDB01DADADA01DBDBDB01D9D9D901 + DCDCDC01D8D8D801D6D6D601FFFFFF01DEDEDE01FEFEFE01A5A5A501DCDCDC01 + D9D9D901D8D8D801DDDDDD01DADADA01D7D7D701DCDCDC02D9D9D901D8D8D802 + DCDCDC01DADADA01D9D9D901DCDCDC01D8D8D801DCDCDC01DADADA01DBDBDB01 + D9D9D901D8D8D801DEDEDE01D9D9D902FEFEFE01DADADA01A4A4A401A9A9A901 + DDDDDD01D6D6D601DADADA01DBDBDB01D9D9D901DDDDDD01DBDBDB01DCDCDC01 + DADADA01D9D9D902DCDCDC01D9D9D901DDDDDD01DBDBDB01DDDDDD01D9D9D901 + FDFDFD01DDDDDD01D9D9D901DADADA01DCDCDC01D7D7D701DADADA01DEDEDE01 + D6D6D601DCDCDC01AAAAAA01FEFEFE01FFFFFF01FCFCFC01A7A7A701ADADAD01 + A6A6A601DADADA01DBDBDB01DADADA01D5D5D501DCDCDC01DBDBDB01D8D8D801 + A9A9A901A8A8A802ABABAB01AAAAAA01A8A8A801DADADA01D8D8D801FDFDFD01 + FFFFFF01FEFEFE01DADADA04DBDBDB01D9D9D901DBDBDB01D7D7D701ACACAC01 + A7A7A701ACACAC01A7A7A702D7D7D701D8D8D801DBDBDB01D8D8D801FFFFFF01 + DADADA01D9D9D901A8A8A801DBDBDB01D8D8D801DBDBDB01A6A6A601AAAAAA01 + A6A6A601DBDBDB02D9D9D901DADADA09D9D9D901D6D6D601DDDDDD01DCDCDC01 + D7D7D701DCDCDC01DADADA01D9D9D901FFFFFF02DBDBDB03D6D6D601DCDCDC01 + DBDBDB01DADADA01A6A6A601DBDBDB01DADADA01D7D7D701DDDDDD01D6D6D601 + DCDCDC01D9D9D901DCDCDC01DADADA01ABABAB01D9D9D901AAAAAA01A8A8A801 + D8D8D801DDDDDD01DBDBDB01DADADA02DBDBDB01D9D9D902DBDBDB01DCDCDC02 + D8D8D801DADADA03DBDBDB01D9D9D901DBDBDB02D8D8D801DCDCDC01DADADA01 + D6D6D601DDDDDD01FFFFFF02D9D9D901DCDCDC01DADADA01DDDDDD01DADADA01 + DCDCDC01D8D8D801DBDBDB01A4A4A401DADADA03DCDCDC01FFFFFF01DADADA01 + A6A6A602A5A5A501DADADA01DBDBDB01DADADA01DCDCDC01DADADA01DDDDDD01 + DADADA01D8D8D801DCDCDC01D7D7D701FFFFFF01A6A6A601A5A5A501FFFFFF01 + FEFEFE01ACACAC01D5D5D501AAAAAA01DADADA01DCDCDC01DBDBDB01D9D9D901 + DCDCDC01D7D7D701DADADA01A8A8A801A9A9A901A7A7A701A5A5A501A8A8A801 + A5A5A501D9D9D901DBDBDB01DCDCDC01FEFEFE01FFFFFF01D9D9D901DBDBDB01 + D9D9D901D6D6D601DEDEDE01D9D9D901DADADA01DEDEDE01D6D6D601A7A7A701 + A9A9A901A7A7A701AAAAAA01DADADA02A7A7A701FFFFFF01FCFCFC01FFFFFF01 + D8D8D801A8A8A801D9D9D901FFFFFF02DBDBDB01A5A5A501DCDCDC01DADADA01 + DBDBDB03DADADA09DCDCDC01DADADA02DCDCDC01D6D6D601DBDBDB01D9D9D901 + FAFAFA01FEFEFE01DBDBDB01D8D8D801D9D9D901DEDEDE01D9D9D901FEFEFE01 + FFFFFF01E0E0E001D7D7D701DADADA01DEDEDE01D8D8D801D9D9D901DADADA01 + D9D9D901DBDBDB01FFFFFF01A7A7A701FFFFFF01D4D4D401ACACAC01D8D8D801 + D7D7D701DADADA01D7D7D701DBDBDB01DEDEDE01D9D9D901D8D8D801DADADA02 + D8D8D801D9D9D901DDDDDD01D8D8D801D9D9D903DADADA02D9D9D901DBDBDB03 + D9D9D901FEFEFE01FBFBFB01DADADA01DBDBDB01D9D9D901DBDBDB01D5D5D501 + DDDDDD01DADADA02A5A5A501ACACAC01D9D9D901DADADA01D9D9D901A8A8A802 + DADADA01DCDCDC02DDDDDD01D6D6D601DADADA02D8D8D801D9D9D901DCDCDC01 + DBDBDB02DADADA01D9D9D902AAAAAA01FEFEFE01FFFFFF01FCFCFC01AAAAAA01 + DCDCDC01D8D8D801D6D6D601DDDDDD01DADADA02FFFFFF03D8D8D801DADADA02 + ABABAB01A9A9A902D7D7D701DCDCDC01FDFDFD01D6D6D601E0E0E001D7D7D701 + DBDBDB01DEDEDE01D7D7D701D9D9D901DADADA01D8D8D801DBDBDB01E0E0E001 + FCFCFC01A6A6A601DADADA01DBDBDB01DADADA01A8A8A801DADADA01D8D8D801 + DADADA01ABABAB01A5A5A501A7A7A701FFFFFF03DCDCDC01DBDBDB01DADADA03 + D8D8D801DADADA08D8D8D801DADADA01D8D8D801DADADA01DEDEDE01D9D9D901 + DADADA01DDDDDD01FFFFFF03D8D8D801DCDCDC01D9D9D901FCFCFC01FFFFFF01 + D7D7D701D6D6D601DCDCDC01DADADA03D9D9D901DBDBDB01DADADA01FFFFFF01 + FEFEFE01DADADA02DDDDDD01D8D8D801DDDDDD01DADADA01DDDDDD01DBDBDB01 + D9D9D903DCDCDC02DDDDDD01D7D7D701D9D9D901DBDBDB01D8D8D801DDDDDD01 + DCDCDC01DBDBDB01D9D9D901D7D7D701DEDEDE01DADADA01D7D7D701DDDDDD01 + DBDBDB01DADADA01DBDBDB01DADADA01DBDBDB01D9D9D901DADADA01DCDCDC01 + D6D6D601FFFFFF01DBDBDB01DADADA01D8D8D801ABABAB01A6A6A601A8A8A801 + FEFEFE01FFFFFF02D7D7D701DBDBDB01D9D9D902DCDCDC01DADADA01DBDBDB01 + D9D9D901DBDBDB01D9D9D901A8A8A801FFFFFF02DCDCDC01DADADA01FFFFFF01 + DADADA01FFFFFF01DBDBDB01A5A5A501DBDBDB03DADADA01D9D9D901FFFFFF02 + FEFEFE01FFFFFF01DADADA02A8A8A801A7A7A701A6A6A601ABABAB01D7D7D701 + FFFFFF01DCDCDC01D9D9D901DADADA02D6D6D601DDDDDD01DBDBDB01DADADA01 + DDDDDD01FDFDFD01D6D6D601FFFFFF01D8D8D801DCDCDC01FFFFFF01D9D9D901 + A7A7A702DCDCDC01DBDBDB01A5A5A501AAAAAA01A7A7A701D9D9D901FEFEFE01 + DADADA01DBDBDB01D8D8D801DADADA01DEDEDE01D7D7D701DCDCDC01DADADA08 + DCDCDC01D8D8D801DBDBDB01DADADA01D7D7D701A9A9A901DADADA01D8D8D801 + FEFEFE01FFFFFF03DADADA01A6A6A601DCDCDC01DADADA02DDDDDD01DADADA02 + D9D9D901DBDBDB01A8A8A801D9D9D901DBDBDB01FCFCFC01DDDDDD01D9D9D901 + FEFEFE01DADADA02D9D9D901DBDBDB01D8D8D801DADADA01DBDBDB01D9D9D901 + DADADA02D9D9D902DBDBDB02DADADA03D8D8D801D9D9D901DBDBDB01DCDCDC01 + D9D9D901D7D7D701DDDDDD01A6A6A601A5A5A501A9A9A901A8A8A801D7D7D701 + DBDBDB01D9D9D901DADADA01D9D9D901DCDCDC01FEFEFE01FFFFFF01D9D9D901 + DADADA01D7D7D701ABABAB01A7A7A701DCDCDC01D9D9D902DBDBDB01A6A6A601 + A8A8A801AAAAAA01A7A7A701A8A8A801A7A7A701DEDEDE01D4D4D401FFFFFF01 + DCDCDC01D9D9D901FEFEFE01DBDBDB01D8D8D801DCDCDC01FFFFFF01D9D9D901 + D7D7D701DDDDDD01D9D9D901DBDBDB01D9D9D901DADADA01D9D9D901DBDBDB01 + FFFFFF03DBDBDB01D8D8D801DCDCDC01A8A8A801A6A6A601ADADAD01FAFAFA01 + FFFFFF02DADADA01DBDBDB01D8D8D801DADADA01DBDBDB02DADADA01D9D9D901 + A8A8A801DBDBDB01D9D9D901D8D8D801DEDEDE01FFFFFF01D8D8D801DADADA01 + DBDBDB01D9D9D901DADADA01DBDBDB01A9A9A901A6A6A601A8A8A801A6A6A601 + DCDCDC01D8D8D801DBDBDB01DDDDDD01D9D9D902DADADA04DBDBDB01A7A7A701 + D9D9D901DBDBDB01A7A7A701DBDBDB01DADADA01DBDBDB01D9D9D901D8D8D801 + DEDEDE01D7D7D701D8D8D801DADADA01FFFFFF02FDFDFD01DCDCDC01D8D8D801 + DBDBDB03DADADA03DCDCDC02D9D9D902DCDCDC01FFFFFF01FDFDFD01DEDEDE01 + D7D7D701DDDDDD01DADADA01D9D9D901DADADA11DCDCDC01D8D8D801DBDBDB01 + D9D9D902AAAAAA01A8A8A802DCDCDC01D7D7D701DDDDDD01DBDBDB01D9D9D901 + A9A9A901A8A8A802DCDCDC01D9D9D901FDFDFD01FFFFFF02A4A4A401AAAAAA01 + DADADA01DBDBDB01D9D9D901DADADA01A3A3A301AAAAAA01A7A7A701AAAAAA01 + D7D7D701FFFFFF01DADADA01D9D9D901D7D7D701DEDEDE01DDDDDD01D7D7D701 + A7A7A701AAAAAA01D9D9D901DDDDDD01DBDBDB01D8D8D801D9D9D901DCDCDC01 + D9D9D901DADADA02D9D9D901FFFFFF01D8D8D802DCDCDC02DADADA01A7A7A701 + D8D8D801FFFFFF01FCFCFC01FEFEFE01D7D7D701DCDCDC01DEDEDE01D9D9D901 + DCDCDC01D8D8D801A9A9A901DADADA01DCDCDC01D9D9D901DBDBDB01DCDCDC01 + D7D7D701DBDBDB01DEDEDE01FFFFFF02D9D9D901D8D8D801D9D9D901DCDCDC01 + A8A8A801A9A9A901AAAAAA01DDDDDD01DBDBDB01D8D8D802D9D9D901DCDCDC03 + D6D6D601DCDCDC01D8D8D801AAAAAA01DADADA02A9A9A901A6A6A601DADADA01 + D9D9D901FFFFFF01DBDBDB01D7D7D701DBDBDB01DFDFDF01DBDBDB01D8D8D801 + FFFFFF02D6D6D601DEDEDE01DBDBDB01D9D9D901D8D8D801DADADA01DDDDDD01 + D7D7D701FEFEFE01D9D9D902DDDDDD01D8D8D801DCDCDC01DBDBDB01DADADA01 + DBDBDB01D9D9D901D8D8D801DDDDDD01DADADA10D8D8D801D7D7D701DEDEDE01 + FFFFFF02DCDCDC01FFFFFF01A6A6A601D8D8D801DDDDDD01DADADA01D8D8D801 + A9A9A901A6A6A601A9A9A902A8A8A801A7A7A701FFFFFF04DCDCDC01DADADA01 + FFFFFF01FEFEFE01FFFFFF04DCDCDC01D9D9D901DCDCDC01D9D9D901DADADA01 + D9D9D901DEDEDE01D6D6D601D7D7D701DDDDDD01A9A9A901A6A6A601D9D9D901 + DBDBDB01D9D9D901A7A7A701DADADA01D9D9D901D8D8D801DDDDDD01DADADA01 + D9D9D901DBDBDB01DADADA01DBDBDB01DADADA01D7D7D701DADADA01ABABAB01 + A8A8A801D8D8D801FFFFFF03D9D9D901DADADA01D7D7D701D6D6D601FFFFFF03 + D7D7D701DADADA02D9D9D901D8D8D801FEFEFE02FFFFFF02DDDDDD01DADADA01 + FFFFFF01FCFCFC01DCDCDC01A7A7A701AAAAAA01D3D3D301D9D9D901DBDBDB02 + DDDDDD01DADADA01D7D7D701D8D8D801DCDCDC01FFFFFF01DADADA01D8D8D801 + FEFEFE01D9D9D901DBDBDB01DADADA02DBDBDB01D8D8D801DCDCDC01D9D9D902 + D5D5D501DADADA01DCDCDC01D7D7D701DADADA01DCDCDC01D6D6D601D8D8D801 + DCDCDC01DBDBDB01DCDCDC01D6D6D601DEDEDE01DDDDDD01DADADA01D9D9D901 + DCDCDC01DADADA01D9D9D901DADADA01D9D9D901D8D8D801DCDCDC02D7D7D701 + DADADA10DBDBDB01DDDDDD01D3D3D301DBDBDB01FFFFFF01FCFCFC01FEFEFE01 + DCDCDC01D9D9D901DADADA01DDDDDD01D5D5D501FFFFFF02D7D7D701FFFFFF01 + FDFDFD01ACACAC01D6D6D601D9D9D901FEFEFE01FFFFFF01DADADA01D9D9D901 + DADADA01D9D9D901FCFCFC01FFFFFF03DADADA01D8D8D801DADADA01DEDEDE01 + DADADA01D9D9D901DADADA02FFFFFF01FCFCFC01FFFFFF01D9D9D901DBDBDB01 + DADADA01A7A7A701A9A9A902DBDBDB01AAAAAA01A7A7A701AAAAAA01DADADA01 + D9D9D901DADADA01DBDBDB01DADADA01D9D9D901A9A9A901A5A5A501A9A9A901 + D9D9D901FEFEFE01FDFDFD01FEFEFE01FFFFFF01FEFEFE01FFFFFF03D8D8D801 + DADADA02DBDBDB01D8D8D801FEFEFE01DDDDDD01A8A8A801A9A9A901FEFEFE01 + FDFDFD01FFFFFF04FEFEFE01DADADA01D7D7D701E1E1E101DCDCDC01DADADA01 + D8D8D801DADADA01D9D9D901DCDCDC01DADADA02FDFDFD01D7D7D701DEDEDE01 + FFFFFF01FEFEFE01DADADA01DBDBDB01D9D9D901DBDBDB01D9D9D901D8D8D801 + DDDDDD01D9D9D901DCDCDC01D9D9D901DCDCDC01D7D7D701DCDCDC01DFDFDF01 + D9D9D901DEDEDE01D8D8D801DADADA01D9D9D901DCDCDC01D9D9D902D7D7D701 + DCDCDC01D8D8D801DCDCDC01DADADA01DCDCDC01DDDDDD01D9D9D902DCDCDC01 + D9D9D901DADADA10DCDCDC01D8D8D801DBDBDB01FFFFFF01D6D6D601FFFFFF01 + DADADA01D7D7D701DBDBDB02FCFCFC01DFDFDF01DADADA01FFFFFF01DBDBDB01 + FEFEFE01A9A9A901A6A6A601ABABAB01DDDDDD01DBDBDB02DADADA01D9D9D902 + DEDEDE01DADADA01DDDDDD01DBDBDB01D8D8D801D9D9D901DCDCDC01D9D9D901 + D7D7D701DADADA01D8D8D801DCDCDC02FBFBFB01FFFFFF01DCDCDC01D9D9D901 + DADADA01FFFFFF01A7A7A701A8A8A801A7A7A703A8A8A801D7D7D701D8D8D801 + DFDFDF01DBDBDB01D8D8D801DBDBDB01DCDCDC01D9D9D901A9A9A901A7A7A701 + DBDBDB01DADADA01FFFFFF02FBFBFB01D7D7D701DDDDDD01D7D7D701D8D8D801 + DADADA01D9D9D901DCDCDC01D8D8D801FFFFFF01DFDFDF01D7D7D701A7A7A702 + DCDCDC01FFFFFF01A9A9A901A5A5A501D9D9D903DCDCDC01DADADA01D8D8D801 + D7D7D701DBDBDB01DCDCDC02D8D8D801DBDBDB02D9D9D902DEDEDE01D7D7D701 + D8D8D801DADADA01D9D9D901DADADA01DCDCDC01DADADA01D9D9D901DCDCDC01 + D5D5D501DDDDDD01D9D9D902DBDBDB01DCDCDC01D7D7D702D9D9D901D7D7D701 + DDDDDD01DCDCDC01D6D6D601DADADA01DCDCDC01D8D8D801DDDDDD01DCDCDC01 + DADADA02D8D8D802DADADA01DBDBDB01D9D9D902DCDCDC01DADADA10D9D9D901 + D7D7D701DDDDDD01D8D8D801DCDCDC01D7D7D701D9D9D901DEDEDE01DADADA01 + D9D9D902A7A7A701D6D6D601A6A6A601DBDBDB01DCDCDC01A9A9A901A7A7A702 + D8D8D802D9D9D901A7A7A701ADADAD01D7D7D701A6A6A601A9A9A901A4A4A401 + AAAAAA01DBDBDB01DADADA01DBDBDB04DDDDDD01D7D7D701A7A7A701A9A9A901 + DCDCDC01DBDBDB01DADADA01FBFBFB01FFFFFF02A9A9A901DDDDDD01D7D7D701 + DFDFDF01D9D9D901DCDCDC01DBDBDB02D6D6D601DADADA01DBDBDB01D8D8D801 + DADADA01A9A9A901AAAAAA01D8D8D801D9D9D901DADADA01D6D6D601E0E0E001 + DEDEDE01D8D8D802DDDDDD01DBDBDB01A9A9A901D8D8D802FFFFFF01FAFAFA01 + FFFFFF01DEDEDE01A8A8A801A9A9A901A5A5A501A6A6A601AFAFAF01A6A6A601 + AAAAAA01ACACAC01A5A5A501DBDBDB01DADADA02DBDBDB01DADADA02D9D9D901 + DADADA01D7D7D701D9D9D901DFDFDF01D8D8D801DBDBDB01DDDDDD01DBDBDB02 + D9D9D902DADADA01DBDBDB01DADADA01DBDBDB01D9D9D901DADADA01DBDBDB01 + D9D9D902DFDFDF01DBDBDB01DCDCDC02D9D9D902E1E1E101A5A5A501A8A8A801 + A7A7A701DBDBDB01D8D8D801DADADA01D8D8D801DEDEDE01DCDCDC01D8D8D801 + DADADA01DCDCDC01DADADA01D9D9D901DADADA10DBDBDB01DCDCDC01D8D8D801 + DBDBDB03DADADA01D7D7D701DADADA01FFFFFF02D6D6D601FFFFFF01A8A8A801 + DADADA01D7D7D701DADADA01AAAAAA01A7A7A701DCDCDC01DBDBDB01DADADA01 + DBDBDB01D6D6D601AAAAAA02A7A7A701ABABAB01DADADA01D9D9D901DADADA01 + D6D6D601DBDBDB01D8D8D801D6D6D601DDDDDD01D8D8D801A8A8A801A9A9A901 + D8D8D801D6D6D601DEDEDE01FFFFFF01FEFEFE01DCDCDC01D7D7D701DADADA01 + DCDCDC01D5D5D501DADADA01DBDBDB01DADADA01D7D7D701DCDCDC02DADADA01 + DFDFDF01DADADA01A6A6A601A7A7A701DCDCDC01DBDBDB01DADADA01FDFDFD01 + D8D8D801D6D6D601DDDDDD01DADADA01D8D8D801A7A7A702DCDCDC01DADADA01 + DCDCDC01FFFFFF01FAFAFA01DBDBDB01A6A6A601D9D9D902DFDFDF01D7D7D701 + DADADA01A5A5A501A8A8A801ABABAB01D9D9D901DADADA01DCDCDC01DBDBDB01 + DADADA03D9D9D901DDDDDD01DCDCDC01D9D9D901D8D8D802D9D9D901A8A8A801 + DADADA02DBDBDB01DADADA01DBDBDB02D7D7D701DBDBDB01D9D9D901DADADA01 + D6D6D601DCDCDC02D7D7D701DADADA01D9D9D901DCDCDC01D9D9D901D6D6D601 + DADADA01ACACAC01A7A7A701DBDBDB01D8D8D801DBDBDB01D8D8D801DADADA04 + D9D9D902DCDCDC01DADADA10D8D8D801DCDCDC01DADADA01DBDBDB01D9D9D901 + D6D6D601DEDEDE01DADADA01D9D9D901FCFCFC01FFFFFF02D6D6D601FEFEFE01 + DADADA01DDDDDD01DBDBDB01A5A5A501A8A8A801DCDCDC01FEFEFE01FDFDFD01 + D9D9D901FFFFFF01FEFEFE02FFFFFF01DADADA01D9D9D901DADADA02DBDBDB01 + D9D9D901DADADA01DBDBDB01FDFDFD01DADADA01A9A9A901A7A7A701DCDCDC01 + DADADA01A7A7A701A8A8A801DBDBDB01D8D8D801DCDCDC01D9D9D901FFFFFF02 + FEFEFE01FFFFFF01DADADA01DBDBDB01DADADA01D8D8D801DBDBDB01D7D7D701 + DDDDDD01A7A7A701ABABAB01A6A6A601DADADA01D7D7D701DFDFDF01D9D9D902 + DADADA01D8D8D801FFFFFF01DADADA01DBDBDB01DADADA01DBDBDB01D9D9D902 + FFFFFF01FEFEFE01DBDBDB01DADADA01FFFFFF01FEFEFE01FFFFFF03DBDBDB01 + D8D8D801DADADA04DBDBDB01D9D9D901DBDBDB01DADADA02D7D7D701DADADA01 + DCDCDC01DBDBDB02DADADA01A8A8A801DBDBDB01D7D7D701DDDDDD01D8D8D801 + DADADA02D8D8D801DBDBDB01DADADA01DCDCDC01D9D9D902DADADA02DCDCDC01 + D7D7D701FFFFFF02FEFEFE01DADADA01D9D9D901DADADA01DDDDDD01D8D8D801 + DBDBDB01DADADA01DBDBDB02D9D9D901DBDBDB01DCDCDC01D8D8D801DADADA13 + D8D8D801DCDCDC01DBDBDB01D6D6D601DCDCDC02DADADA02FEFEFE01FFFFFF02 + DBDBDB01D8D8D801D9D9D901ABABAB01A7A7A701D9D9D901FFFFFF03FDFDFD01 + FFFFFF01FEFEFE01D9D9D901DDDDDD01D6D6D601DCDCDC01DBDBDB01D8D8D801 + DCDCDC01D9D9D902DCDCDC01D8D8D801AAAAAA01ACACAC01A6A6A601A7A7A701 + A9A9A901D7D7D701DADADA01DBDBDB01DADADA02DBDBDB01FFFFFF01FDFDFD01 + FEFEFE01DADADA01DBDBDB01DADADA01DBDBDB01D9D9D901DADADA01DBDBDB01 + AAAAAA01A7A7A701A8A8A802D9D9D901DADADA01DDDDDD01D7D7D701DEDEDE01 + FDFDFD01FFFFFF01DCDCDC01DBDBDB01DADADA01D9D9D902FFFFFF01D8D8D801 + DCDCDC01D9D9D901D8D8D801DDDDDD01D9D9D902FFFFFF02D7D7D701DADADA02 + D9D9D901DBDBDB01DADADA01DBDBDB01DADADA01D8D8D801DADADA02DCDCDC01 + D9D9D901D8D8D801FEFEFE01DDDDDD01D9D9D901A9A9A901DADADA09DCDCDC01 + D6D6D601DBDBDB01DCDCDC01D9D9D901A8A8A801D9D9D901D8D8D801FFFFFF02 + D7D7D701DCDCDC01DADADA03DBDBDB01D9D9D901DBDBDB02DADADA03A9A9A901 + DADADA08D9D9D901DCDCDC01D8D8D801DCDCDC01D9D9D901DADADA01D8D8D801 + DBDBDB02D9D9D901DADADA03DCDCDC01DBDBDB02DADADA02DBDBDB01DADADA01 + FFFFFF01FEFEFE01FFFFFF03D9D9D901A8A8A801A9A9A901A7A7A702DCDCDC01 + D8D8D801D7D7D701DBDBDB02A8A8A801DCDCDC01DBDBDB02D9D9D901D7D7D701 + DDDDDD01FEFEFE01D7D7D701DEDEDE01A5A5A501A4A4A401DCDCDC01DDDDDD01 + DADADA01DEDEDE01D8D8D801DDDDDD01A6A6A602A9A9A901D8D8D801FFFFFF02 + D9D9D901DADADA01DBDBDB01DCDCDC01D8D8D801FFFFFF02D4D4D401A8A8A801 + AAAAAA01A9A9A901DDDDDD01D8D8D801D9D9D901DBDBDB01DADADA01DBDBDB01 + DCDCDC01D8D8D802DCDCDC02DBDBDB01D9D9D901FFFFFF01DADADA01D9D9D901 + DCDCDC01A7A7A701A9A9A902D7D7D701DBDBDB01A9A9A901ABABAB01DBDBDB01 + D7D7D701DBDBDB01D9D9D901D7D7D701DDDDDD01DADADA01DDDDDD01D9D9D901 + D8D8D801DEDEDE01D9D9D901DEDEDE01FBFBFB01DADADA01D9D9D901DADADA08 + DBDBDB01D9D9D901DDDDDD01D9D9D901DBDBDB01DADADA02A9A9A901AAAAAA01 + D9D9D901A7A7A701DDDDDD01D7D7D701DADADA02D9D9D901DBDBDB01D9D9D901 + D7D7D701D9D9D901DCDCDC01D7D7D701DBDBDB01D8D8D801DADADA08D6D6D601 + DBDBDB01DADADA01D9D9D901DADADA02ABABAB01DADADA01D9D9D901DCDCDC01 + D9D9D902DADADA01D8D8D802D9D9D901DBDBDB01DADADA01D7D7D701DCDCDC01 + FDFDFD01FFFFFF02FEFEFE01FDFDFD01DDDDDD01A7A7A702FFFFFF02A8A8A802 + ADADAD01D9D9D901D8D8D801D9D9D901DDDDDD01D6D6D601D7D7D701DCDCDC01 + DBDBDB01FFFFFF01DADADA01DCDCDC01DADADA01DCDCDC02D8D8D801DADADA02 + D6D6D601DEDEDE01D9D9D901DCDCDC01A9A9A901A7A7A701DCDCDC01FFFFFF01 + FEFEFE01D7D7D701DBDBDB01DADADA01D6D6D601FFFFFF01FDFDFD01FFFFFF02 + DBDBDB01A7A7A701A6A6A601D7D7D701DCDCDC02D8D8D801D9D9D901DADADA01 + D9D9D901DADADA01D6D6D601DDDDDD01D8D8D801FDFDFD01FFFFFF02FBFBFB01 + FFFFFF01FDFDFD01FEFEFE01DDDDDD01D8D8D801DADADA01DBDBDB01A8A8A801 + D7D7D701DCDCDC01DDDDDD01D7D7D701DBDBDB01AAAAAA01A5A5A501DBDBDB01 + D6D6D601DDDDDD01D9D9D902DADADA02FFFFFF01D9D9D901DADADA09D8D8D801 + DEDEDE01D7D7D701D8D8D801FFFFFF01DBDBDB01DADADA01D8D8D801DBDBDB01 + D7D7D701DADADA02D9D9D901DEDEDE01DCDCDC01DBDBDB01D8D8D801DBDBDB01 + DEDEDE01DBDBDB01D8D8D801FFFFFF01D5D5D501DBDBDB01DADADA08DBDBDB01 + DEDEDE01D9D9D901DADADA01DBDBDB01DADADA01D8D8D801D9D9D901DCDCDC01 + D9D9D901D8D8D801DBDBDB01DADADA01DBDBDB01DFDFDF01DADADA01D9D9D901 + DDDDDD01DADADA01D9D9D901DCDCDC01DADADA01D7D7D701DCDCDC01FFFFFF01 + FCFCFC01FFFFFF02D9D9D901D7D7D701D8D8D801D9D9D901D8D8D801FFFFFF01 + DCDCDC01D9D9D902DBDBDB01DDDDDD01DADADA01D8D8D801FEFEFE01D9D9D901 + DEDEDE01D5D5D501DADADA01D8D8D801DEDEDE01D8D8D801DBDBDB01DADADA01 + DCDCDC01D8D8D801DADADA01A9A9A901ABABAB01A5A5A501FDFDFD01FEFEFE01 + DEDEDE01D9D9D901DBDBDB01A9A9A901D8D8D801FFFFFF01FCFCFC01FFFFFF01 + DBDBDB01A5A5A501ACACAC01D9D9D901DCDCDC01D9D9D902DDDDDD01DCDCDC01 + DADADA01DCDCDC01DDDDDD01DADADA02D9D9D901FCFCFC01D8D8D801DCDCDC01 + FEFEFE01FFFFFF02DADADA01D8D8D801FFFFFF01FDFDFD01DBDBDB02D8D8D801 + D9D9D901DDDDDD01DCDCDC01A8A8A801A9A9A902DBDBDB01D7D7D701DDDDDD01 + DBDBDB02DADADA03DBDBDB01DADADA08DBDBDB01D9D9D902DEDEDE01DADADA01 + FFFFFF01FEFEFE01DDDDDD01FFFFFF01DADADA01D9D9D901DCDCDC02D7D7D701 + DADADA01D8D8D801DADADA01D9D9D901D8D8D802D9D9D901D7D7D701DCDCDC02 + DADADA09D6D6D601DBDBDB01D9D9D901FFFFFF01D7D7D701DCDCDC01DBDBDB01 + D7D7D701D9D9D901DCDCDC01DDDDDD01D9D9D901D8D8D801D9D9D901D8D8D801 + D9D9D901DBDBDB01DADADA02D9D9D901DADADA01D8D8D801DADADA01FDFDFD01 + FEFEFE01DDDDDD01D7D7D701DDDDDD01D9D9D901FFFFFF01DADADA01DCDCDC01 + D9D9D901DBDBDB01D9D9D901D8D8D801DCDCDC01D9D9D901D8D8D801FFFFFF02 + D9D9D902DCDCDC01D8D8D801D9D9D901DCDCDC01DADADA01DCDCDC02D8D8D801 + D9D9D901DCDCDC01A5A5A501A7A7A701A9A9A901FFFFFF01FDFDFD01FEFEFE01 + DBDBDB01A7A7A701A8A8A802D9D9D901FDFDFD01DBDBDB01DCDCDC01A7A7A702 + DCDCDC01D9D9D902DBDBDB01DADADA01D8D8D802DADADA01D8D8D801D9D9D901 + DDDDDD01D9D9D901E0E0E001D7D7D701DCDCDC03DADADA01D9D9D901DBDBDB01 + FFFFFF01DBDBDB01D8D8D801DADADA01DCDCDC01D9D9D901FDFDFD01FEFEFE01 + A6A6A601DBDBDB01D7D7D701DBDBDB01DCDCDC01DADADA01D6D6D601D9D9D901 + DDDDDD01D8D8D801DBDBDB01DADADA09DBDBDB01DADADA01DBDBDB01D8D8D802 + D9D9D901DCDCDC01D8D8D801DBDBDB03D7D7D701DADADA01D7D7D701DEDEDE01 + DBDBDB01DCDCDC01DADADA01DBDBDB01DEDEDE01D9D9D901DBDBDB01DCDCDC01 + D7D7D701DADADA09DDDDDD01D8D8D801DBDBDB01DADADA01DEDEDE01D6D6D601 + D9D9D901DCDCDC02DADADA01D7D7D701DBDBDB01DDDDDD01D8D8D801DCDCDC02 + D9D9D902DADADA01DCDCDC01DDDDDD01DCDCDC01D9D9D901DBDBDB02DADADA01 + DEDEDE01D7D7D701DCDCDC01D8D8D801DBDBDB01D9D9D901D7D7D701DBDBDB01 + DCDCDC01D9D9D901D8D8D801DADADA01D7D7D701FFFFFF02FEFEFE01D9D9D902 + DCDCDC02D9D9D901D7D7D701DCDCDC01D7D7D701D9D9D901DEDEDE01D6D6D601 + FFFFFF01D8D8D801DCDCDC01FFFFFF01FEFEFE02DEDEDE01A7A7A701A9A9A901 + A8A8A801AAAAAA01DBDBDB01DADADA01D7D7D701AAAAAA01A7A7A701D9D9D901 + DADADA01DCDCDC01DADADA01D8D8D801DCDCDC01DEDEDE01D8D8D801DBDBDB02 + DADADA01D9D9D902DCDCDC01D5D5D501DADADA02D7D7D701DADADA01D9D9D901 + DBDBDB02DADADA01DBDBDB01D8D8D801DBDBDB01FFFFFF03DDDDDD01DBDBDB01 + D8D8D801DADADA01D9D9D901DCDCDC02DBDBDB02D8D8D801D9D9D901DADADA08 + D8D8D801DCDCDC01DADADA01DBDBDB02DDDDDD01D9D9D901DBDBDB01D8D8D801 + DDDDDD01D8D8D801DEDEDE01DCDCDC01DADADA01D8D8D802DADADA02D9D9D901 + DADADA01D9D9D903DCDCDC01DADADA08D9D9D901DADADA03D8D8D802DDDDDD01 + DADADA01DBDBDB01D7D7D701DBDBDB02D8D8D801DBDBDB02D9D9D902D8D8D801 + DCDCDC01DADADA02D8D8D801DCDCDC01DBDBDB01D9D9D902D5D5D501D9D9D901 + DBDBDB01D6D6D601DBDBDB01DDDDDD01DADADA01DBDBDB01D9D9D901D8D8D801 + DBDBDB01DCDCDC01D9D9D901DDDDDD01FFFFFF02FCFCFC01FFFFFF02FDFDFD01 + DADADA01DBDBDB04FEFEFE01FFFFFF03D8D8D802DCDCDC01FEFEFE01FFFFFF01 + D7D7D701DBDBDB01A6A6A601A8A8A801D6D6D601DADADA02DCDCDC01A8A8A801 + DADADA01DCDCDC01D9D9D902DADADA04D8D8D801DBDBDB01D7D7D701DCDCDC01 + DADADA01DCDCDC01D8D8D801DBDBDB03DADADA01AAAAAA01DDDDDD01D7D7D701 + DADADA01D7D7D701DDDDDD02D7D7D701FEFEFE01DDDDDD01D7D7D701D9D9D901 + DADADA02D9D9D901DADADA02D8D8D801D9D9D901D7D7D701DDDDDD01DBDBDB01 + DADADA08DEDEDE01D8D8D801DBDBDB01DADADA01DBDBDB01DADADA01D8D8D801 + D9D9D901DDDDDD01D5D5D501DADADA01D9D9D901DADADA01DCDCDC01DADADA01 + DBDBDB01D8D8D801DCDCDC01D9D9D902DBDBDB01DCDCDC01D9D9D902DADADA08 + DDDDDD01D6D6D601DDDDDD01D8D8D801DADADA01DBDBDB03D8D8D801DCDCDC01 + D8D8D801DBDBDB01DCDCDC01D8D8D801DCDCDC01D9D9D901DCDCDC01DADADA01 + DBDBDB01DADADA01DBDBDB01DADADA01DBDBDB01D9D9D901DBDBDB02DDDDDD01 + D9D9D901DCDCDC01DADADA01A8A8A801A5A5A501DCDCDC01DADADA01DBDBDB01 + D9D9D901DADADA02D9D9D901DADADA01D9D9D901FDFDFD01FFFFFF01FEFEFE02 + DCDCDC01D9D9D901DBDBDB01DADADA01D9D9D901DADADA01FFFFFF01DADADA04 + DBDBDB01D8D8D801FFFFFF01DADADA01D9D9D901DCDCDC01DBDBDB02DCDCDC01 + D9D9D902DADADA01D8D8D801DCDCDC01D8D8D801DCDCDC01DBDBDB01D9D9D901 + DBDBDB02DADADA01DBDBDB01D9D9D901DADADA01D9D9D901DADADA03DCDCDC01 + D9D9D902AAAAAA01D7D7D701D9D9D901DCDCDC01DADADA01DCDCDC01D8D8D801 + D9D9D902DDDDDD01D8D8D801DCDCDC01D8D8D801DADADA02DBDBDB01DADADA02 + DBDBDB02D9D9D901DBDBDB01D9D9D901DADADA08D8D8D801DBDBDB01D7D7D701 + DDDDDD01D9D9D901D8D8D801DEDEDE01D9D9D901D8D8D801DFDFDF01D8D8D801 + D9D9D901DADADA01DBDBDB01D8D8D801DADADA01DBDBDB01D8D8D801DADADA01 + DCDCDC01D8D8D801DBDBDB01D8D8D801DCDCDC01DADADA08D8D8D801DEDEDE01 + D9D9D901D8D8D801DBDBDB02D7D7D701D9D9D901DBDBDB01DADADA01A8A8A801 + A9A9A901D7D7D701DCDCDC01D9D9D901DCDCDC01D9D9D901DADADA02DBDBDB01 + D9D9D901DADADA02DBDBDB01D8D8D801DCDCDC01DADADA01D8D8D801DCDCDC01 + D9D9D901DADADA03DBDBDB01DADADA02D8D8D801DADADA01D9D9D901DDDDDD01 + D8D8D801DCDCDC01D9D9D902FFFFFF02DADADA01DCDCDC01D9D9D901DBDBDB01 + D9D9D902DCDCDC01D9D9D901D8D8D801DDDDDD01DADADA01D9D9D901DBDBDB01 + DEDEDE01D5D5D501DBDBDB03D9D9D901DBDBDB01DADADA01D9D9D901DCDCDC01 + DADADA01D9D9D901DADADA02DBDBDB01D7D7D701DBDBDB01DADADA01DBDBDB02 + DADADA01D8D8D801DDDDDD01DBDBDB01D9D9D901DBDBDB01D9D9D901FFFFFF01 + A7A7A701ABABAB01DADADA03DBDBDB01DADADA01D9D9D901D8D8D801DCDCDC01 + D9D9D901DBDBDB01D9D9D901DBDBDB01DADADA09D9D9D901DBDBDB01DADADA02 + D9D9D901DCDCDC01D7D7D701DBDBDB01D8D8D801DDDDDD01DBDBDB01D9D9D901 + DADADA01D9D9D901DBDBDB01DADADA01DBDBDB01D9D9D901D8D8D801DCDCDC02 + D9D9D901DADADA01DBDBDB01DADADA02D8D8D801DBDBDB01D9D9D901DCDCDC01 + DADADA01DBDBDB01DADADA10D7D7D701DEDEDE01D8D8D801D9D9D901DCDCDC01 + D8D8D801DBDBDB01DCDCDC01DADADA0FD9D9D901AAAAAA01D6D6D601DBDBDB01 + DCDCDC01DBDBDB01DADADA01DBDBDB01D7D7D701DBDBDB01D8D8D801DADADA01 + FFFFFF01FCFCFC01FFFFFF01FEFEFE01FFFFFF02D6D6D601DCDCDC02D9D9D901 + DADADA01DEDEDE01D6D6D601DADADA01DEDEDE01D6D6D601DADADA02DDDDDD01 + DBDBDB01DADADA01D6D6D601DCDCDC01D9D9D901DCDCDC01D7D7D701DADADA01 + DDDDDD01D9D9D901D8D8D801D9D9D901DDDDDD01DADADA01D7D7D701A8A8A801 + D9D9D902DADADA01D7D7D701D8D8D801DADADA01DCDCDC01FDFDFD01DADADA01 + A5A5A501A4A4A401D9D9D901DDDDDD01DADADA01D7D7D701DBDBDB01DDDDDD02 + DADADA01D7D7D701DCDCDC01DADADA01D9D9D901DADADA09DBDBDB01D7D7D701 + D9D9D901DADADA01D8D8D801D9D9D901DFDFDF01D8D8D801DADADA01D7D7D701 + DDDDDD01D9D9D901DCDCDC01DADADA01DCDCDC01D9D9D902DCDCDC02D7D7D701 + DADADA01DCDCDC01D8D8D801D9D9D902DBDBDB01DCDCDC01DADADA02D8D8D801 + DBDBDB01D8D8D801DADADA10FFFFFF01F8F8F801E0E0E001D7D7D701DBDBDB01 + DADADA02D8D8D801DADADA0EDBDBDB01D8D8D801DBDBDB02D9D9D901DBDBDB02 + D9D9D901D7D7D701DFDFDF01D8D8D802DEDEDE01DDDDDD01FDFDFD01FFFFFF02 + D7D7D701DADADA01DEDEDE01D9D9D901A6A6A601AAAAAA01D9D9D901D8D8D801 + DBDBDB01DADADA04D9D9D901FFFFFF01FEFEFE01FFFFFF02D9D9D901DADADA01 + DBDBDB01DEDEDE01DBDBDB01D7D7D701DBDBDB01DCDCDC01DADADA01D6D6D601 + AAAAAA01A7A7A701A9A9A901A6A6A601DCDCDC01DADADA01DCDCDC01DBDBDB01 + D8D8D801D9D9D901FFFFFF02ADADAD01A9A9A901D9D9D901DBDBDB01DADADA01 + DCDCDC01A6A6A601A5A5A501D9D9D901D8D8D801DDDDDD01D8D8D801D9D9D902 + DBDBDB01DADADA09DBDBDB01DADADA01DCDCDC01DDDDDD01D8D8D802DBDBDB01 + DDDDDD01DADADA01D9D9D903DADADA01D8D8D801DBDBDB01D9D9D901DBDBDB02 + DADADA03DBDBDB01DCDCDC01DDDDDD01D8D8D803D9D9D901E0E0E001D6D6D601 + DEDEDE01DADADA10D9D9D901DEDEDE01D9D9D901DADADA01DDDDDD01D9D9D901 + DBDBDB02DADADA0EFEFEFE01DCDCDC01DBDBDB01DADADA01DCDCDC01D7D7D701 + D6D6D601DADADA01DBDBDB01D9D9D901DEDEDE01D9D9D901D8D8D801D6D6D601 + DBDBDB01D9D9D901DCDCDC01DBDBDB01D9D9D901D7D7D701AAAAAA01A8A8A801 + A5A5A501DBDBDB03DADADA01D9D9D901DADADA01DBDBDB01FDFDFD01FEFEFE01 + FFFFFF01FBFBFB01D7D7D701DEDEDE01D9D9D901DADADA01D7D7D701D9D9D901 + DDDDDD01DBDBDB01D9D9D901DADADA01DDDDDD01D7D7D701ABABAB01A7A7A701 + DBDBDB01D7D7D701DADADA01D7D7D701DDDDDD01DADADA01D8D8D801FFFFFF01 + FEFEFE01A6A6A601D7D7D701DADADA01A8A8A801D7D7D701DCDCDC01DBDBDB01 + AAAAAA01DADADA01DBDBDB01DDDDDD01D8D8D801DCDCDC01DBDBDB01D9D9D901 + DADADA08DCDCDC01D7D7D701D9D9D901DBDBDB01D7D7D701DDDDDD01D9D9D901 + DADADA01D8D8D801D9D9D901AAAAAA01DADADA02D9D9D901DADADA01DCDCDC01 + DBDBDB01D9D9D901D7D7D701DDDDDD01DADADA01D8D8D801DDDDDD01D6D6D601 + D7D7D701ABABAB01DBDBDB01A8A8A802DADADA01D6D6D601DADADA11D9D9D901 + DDDDDD01DADADA03D8D8D801DADADA01DBDBDB01DADADA0ED9D9D901DBDBDB01 + D7D7D701D9D9D901DADADA01DCDCDC01DBDBDB01DCDCDC02D8D8D801D7D7D701 + DBDBDB01DCDCDC01DBDBDB01A5A5A501DCDCDC01D8D8D801DCDCDC01AAAAAA01 + DADADA01DDDDDD01A5A5A501ABABAB01A7A7A701D7D7D701D9D9D901DCDCDC01 + D9D9D901DCDCDC02DADADA01DBDBDB01D9D9D901DDDDDD01DBDBDB01D7D7D701 + DADADA01DCDCDC01DADADA01DEDEDE01D7D7D701D9D9D903DCDCDC01D7D7D701 + DCDCDC01A7A7A701DADADA01DCDCDC01DADADA01A7A7A701A9A9A901D7D7D701 + DCDCDC01FFFFFF01FEFEFE01DBDBDB01ADADAD01A5A5A501ABABAB01DCDCDC01 + FDFDFD01D8D8D801DADADA01D7D7D701DCDCDC01D9D9D901DADADA03DBDBDB01 + DADADA08D9D9D901DBDBDB01D9D9D901DADADA01DBDBDB01DCDCDC01D9D9D901 + DADADA02DBDBDB01D9D9D901DBDBDB01DDDDDD01D7D7D701DDDDDD01D7D7D701 + DADADA03D9D9D901DBDBDB01DADADA01D9D9D901DDDDDD01DBDBDB01A6A6A601 + DBDBDB01D8D8D801D9D9D901DCDCDC01D9D9D901DBDBDB01DADADA12D8D8D801 + DADADA01DCDCDC01DBDBDB01DADADA01D8D8D801DADADA0FD9D9D901DEDEDE01 + DADADA01D9D9D902D8D8D801D9D9D901DBDBDB02D9D9D901D8D8D801DBDBDB03 + A7A7A701A9A9A901A5A5A501D7D7D701D9D9D901DBDBDB01A7A7A701ABABAB01 + D7D7D701DCDCDC01DEDEDE01D8D8D801D7D7D701D8D8D802DCDCDC01D7D7D701 + D6D6D601DADADA01DDDDDD01D9D9D901DEDEDE01D9D9D902D8D8D801DBDBDB01 + DEDEDE01A9A9A901D9D9D901DADADA01DEDEDE01A2A2A201A9A9A901D8D8D801 + DBDBDB01D9D9D901A7A7A701D9D9D901AEAEAE01A4A4A401DADADA01A8A8A802 + D4D4D401ADADAD01A4A4A401A6A6A601FFFFFF01DBDBDB01DADADA01DEDEDE01 + D9D9D901DBDBDB01D9D9D901DADADA01D9D9D901DBDBDB01DADADA09D9D9D901 + DDDDDD01DCDCDC01D8D8D801DCDCDC01D8D8D801A8A8A801FDFDFD01DADADA01 + D9D9D901DADADA01D8D8D801DCDCDC02DBDBDB02D9D9D901DDDDDD01D7D7D701 + DCDCDC01DBDBDB01D7D7D701FEFEFE01DBDBDB01FEFEFE02DCDCDC01D9D9D901 + A8A8A801DDDDDD01D9D9D901DADADA13D9D9D903DCDCDC01DDDDDD01DADADA10 + D5D5D501DEDEDE01DADADA01DCDCDC01DEDEDE01D7D7D701D9D9D901DBDBDB01 + D8D8D801DDDDDD01FFFFFF01DBDBDB01D8D8D801A8A8A801DBDBDB01D9D9D901 + DDDDDD01FEFEFE01FFFFFF01D9D9D901DBDBDB01D9D9D901D8D8D801DBDBDB01 + D9D9D901AEAEAE01A8A8A801A9A9A901D9D9D901DBDBDB01DEDEDE01D7D7D701 + DCDCDC01D6D6D601D9D9D901DDDDDD01D7D7D701DBDBDB01D7D7D701FEFEFE02 + FFFFFF02FEFEFE01DCDCDC01DADADA01DCDCDC01FDFDFD01FFFFFF01DCDCDC01 + D6D6D601A8A8A802A9A9A901DCDCDC01D8D8D801DBDBDB01DADADA01DCDCDC01 + DBDBDB01D8D8D801D9D9D902DADADA01D8D8D801DCDCDC01D9D9D901DDDDDD01 + DCDCDC01D7D7D701DADADA08DDDDDD01D8D8D801D7D7D701DADADA01D7D7D701 + DBDBDB02DCDCDC01ABABAB01A7A7A701DADADA01DBDBDB01DADADA01DCDCDC01 + D4D4D401DBDBDB02D8D8D801DCDCDC01D9D9D901DCDCDC01D9D9D901DBDBDB01 + FFFFFF01DADADA01DBDBDB01DADADA01DCDCDC01A8A8A801A5A5A501DADADA01 + DBDBDB01DADADA10DBDBDB01D9D9D901DADADA01DBDBDB02DCDCDC01D9D9D901 + D6D6D601DADADA0ED8D8D801DDDDDD01DCDCDC01D7D7D701DADADA02D7D7D701 + DCDCDC01DBDBDB01D9D9D901DBDBDB01DADADA01D7D7D701FFFFFF01DCDCDC01 + D8D8D802DDDDDD01DADADA01FEFEFE01FFFFFF01DBDBDB01D8D8D801DCDCDC02 + D7D7D701AAAAAA01A5A5A501A8A8A802DADADA01D9D9D902DBDBDB01D7D7D701 + DDDDDD01DADADA01D8D8D801DCDCDC01DBDBDB01FFFFFF03FEFEFE01FFFFFF01 + FDFDFD01DBDBDB01DADADA01D9D9D901FFFFFF01A5A5A501DADADA01FFFFFF01 + D7D7D701D9D9D901DADADA01D8D8D801DCDCDC01FFFFFF02D7D7D701D9D9D901 + DCDCDC01DADADA01D9D9D901AAAAAA01D8D8D801DCDCDC01DBDBDB01D7D7D701 + DBDBDB02DADADA08D7D7D701DDDDDD01DBDBDB01D8D8D801DDDDDD01FDFDFD01 + D9D9D902D8D8D801DADADA01DDDDDD01D6D6D601DDDDDD01D9D9D901DBDBDB01 + DCDCDC01DADADA02D9D9D901DADADA01D9D9D901DADADA01DCDCDC01D8D8D801 + DBDBDB01D8D8D801DADADA01FEFEFE01DBDBDB01DCDCDC01A7A7A702DADADA11 + D9D9D901DBDBDB02D8D8D801DADADA01DBDBDB02DADADA16DBDBDB01DADADA01 + D7D7D701DDDDDD01DCDCDC01FFFFFF01FEFEFE01DBDBDB01DADADA01A7A7A701 + A9A9A901FBFBFB01FFFFFF01DADADA02D9D9D901DCDCDC01FFFFFF01FDFDFD01 + DCDCDC01A6A6A601A9A9A901DDDDDD01D7D7D701DCDCDC01D9D9D901DCDCDC01 + D7D7D701DADADA01D9D9D901DBDBDB04DADADA01D8D8D801DBDBDB01D9D9D902 + DADADA01DCDCDC01D8D8D801DBDBDB01FEFEFE01DADADA01DCDCDC01DADADA01 + D9D9D902DBDBDB01DADADA01A6A6A601AAAAAA01DADADA01D9D9D901D8D8D801 + DBDBDB01DADADA02DBDBDB01D8D8D801DBDBDB02D8D8D801DADADA01DBDBDB02 + D7D7D701DDDDDD01DADADA01D8D8D801DBDBDB02DADADA01D9D9D903DADADA01 + FFFFFF02DADADA10DBDBDB01D9D9D901FFFFFF02D9D9D901DADADA01A7A7A701 + A8A8A801DBDBDB02DADADA01D9D9D901DADADA01D9D9D901DCDCDC01D9D9D902 + DBDBDB02DADADA01D9D9D901DADADA01D7D7D701DDDDDD01D9D9D901DADADA01 + D8D8D801DDDDDD01D7D7D701DADADA01DCDCDC01D7D7D701D9D9D901DBDBDB01 + DADADA01D8D8D801DDDDDD01D8D8D801DADADA01D8D8D801DADADA0EDBDBDB01 + D9D9D901DDDDDD01D8D8D801FBFBFB01FFFFFF01FEFEFE01DADADA01DDDDDD01 + A4A4A401DBDBDB01FFFFFF02FEFEFE01FDFDFD01FFFFFF01FCFCFC01FFFFFF01 + DADADA01FDFDFD01AAAAAA01D7D7D701D9D9D901DEDEDE01D7D7D701DBDBDB01 + D7D7D701DADADA01DDDDDD01DCDCDC01D8D8D801D7D7D701DADADA01D9D9D902 + DBDBDB03DCDCDC01DADADA01FDFDFD01FFFFFF01DBDBDB01DADADA01FFFFFF04 + DBDBDB01DADADA01DBDBDB01A7A7A701D8D8D802DCDCDC01FFFFFF01D9D9D902 + DADADA01D9D9D901DDDDDD01D8D8D801D9D9D901DBDBDB01D9D9D901D7D7D701 + D9D9D901DEDEDE01D8D8D802DEDEDE01DADADA01D7D7D701DBDBDB02DCDCDC01 + DBDBDB01DCDCDC01D6D6D601DBDBDB01DADADA10D8D8D801DBDBDB01DADADA02 + FFFFFF02ABABAB01A9A9A901D7D7D701DADADA01DBDBDB01DCDCDC01D8D8D801 + DFDFDF01D6D6D601DBDBDB01DCDCDC01D8D8D801DBDBDB01DCDCDC01D9D9D901 + AAAAAA02D7D7D701D9D9D901DCDCDC01DADADA02D9D9D901DADADA01DBDBDB01 + DEDEDE01DCDCDC01D8D8D801DCDCDC01DBDBDB01D7D7D701D9D9D901E0E0E001 + DBDBDB01DADADA0ED8D8D801DBDBDB01DADADA02ACACAC01D8D8D801DBDBDB01 + D9D9D901FFFFFF01DADADA01DBDBDB01FAFAFA01FFFFFF02FEFEFE01DCDCDC01 + DADADA01FFFFFF03D9D9D901DCDCDC01DBDBDB01D7D7D701DBDBDB01DADADA01 + DCDCDC01D9D9D901D7D7D701DADADA01D9D9D901DEDEDE01D7D7D701DDDDDD01 + DADADA01DBDBDB01D9D9D901DADADA01D6D6D601DBDBDB01AAAAAA01A6A6A601 + FFFFFF01FDFDFD01FFFFFF01FEFEFE01FDFDFD01FFFFFF01DBDBDB01FDFDFD01 + FFFFFF01DADADA01DCDCDC01DBDBDB01D7D7D701D9D9D901A9A9A901A8A8A801 + DADADA01DBDBDB01D8D8D801DCDCDC01DADADA01D8D8D801A8A8A801DCDCDC01 + DBDBDB01D6D6D601DADADA03D7D7D701DDDDDD01D7D7D701DADADA01D8D8D801 + D9D9D901D8D8D801DEDEDE01D9D9D901DADADA10DBDBDB03DADADA01FFFFFF02 + D3D3D301DCDCDC01DFDFDF01D8D8D801A7A7A701D7D7D701DBDBDB01DADADA01 + DBDBDB01D9D9D901D8D8D801DBDBDB01D7D7D701DEDEDE01A6A6A601A5A5A501 + ABABAB01DADADA01D9D9D903DADADA01DCDCDC01D9D9D902D8D8D801D7D7D701 + DBDBDB01D9D9D901DADADA03D8D8D801DADADA0FDBDBDB01DADADA02D9D9D901 + D6D6D601FFFFFF01DADADA01DCDCDC01D9D9D901DADADA02DEDEDE01D9D9D901 + DADADA01D7D7D701DADADA01FFFFFF01D7D7D701FFFFFF01DADADA01DBDBDB01 + D8D8D802DCDCDC01DBDBDB01D6D6D601DDDDDD01D9D9D901DADADA01DCDCDC01 + D7D7D701D9D9D901DDDDDD01D9D9D901A5A5A501D9D9D901DADADA01DCDCDC01 + DEDEDE01A8A8A802DCDCDC01A6A6A601DDDDDD01D7D7D701DBDBDB01DEDEDE01 + D7D7D701DADADA01FBFBFB01D8D8D801DBDBDB01D8D8D801DBDBDB01D9D9D901 + DBDBDB01A7A7A701A6A6A601DCDCDC01DBDBDB01D7D7D701DCDCDC01DBDBDB01 + DCDCDC02D7D7D701DCDCDC01DDDDDD01D8D8D801DBDBDB01D9D9D901DDDDDD01 + D8D8D801DADADA01DDDDDD01DBDBDB01DADADA01DCDCDC01D7D7D701DCDCDC01 + DADADA10D9D9D901DBDBDB01D7D7D701DADADA01FFFFFF01FDFDFD01DCDCDC01 + DDDDDD01D6D6D601D9D9D901DBDBDB01DEDEDE01DADADA01D7D7D701DEDEDE01 + D9D9D902DDDDDD01A7A7A701FFFFFF01FEFEFE01DDDDDD01D9D9D901DADADA01 + DEDEDE01D7D7D701DCDCDC01DDDDDD01D6D6D601DDDDDD01DBDBDB01A6A6A601 + ABABAB01D9D9D901DCDCDC01D9D9D901DADADA01DCDCDC01D9D9D901DADADA11 + FDFDFD01FFFFFF01FEFEFE01FFFFFF01D8D8D801D9D9D901DCDCDC02D7D7D702 + DEDEDE01D8D8D801DCDCDC01D9D9D901DCDCDC01D6D6D601DFDFDF01D6D6D601 + DDDDDD01DBDBDB04DCDCDC01D7D7D701DBDBDB01DADADA01DBDBDB01DCDCDC01 + D9D9D901DADADA01D8D8D801DDDDDD01DBDBDB01D9D9D901DCDCDC01FBFBFB01 + FFFFFF01DCDCDC01D5D5D501DCDCDC01D8D8D801D9D9D901D7D7D701DADADA01 + DCDCDC01D7D7D701E1E1E101D9D9D901DDDDDD01D9D9D901D7D7D701FFFFFF01 + FEFEFE01DCDCDC01DBDBDB01D9D9D901D7D7D701DADADA01AAAAAA01FDFDFD01 + DBDBDB01D9D9D901DDDDDD01D8D8D802DDDDDD01DADADA02D7D7D701DBDBDB01 + DADADA01D8D8D801DADADA02D6D6D601DDDDDD01D7D7D701DADADA10D9D9D901 + D8D8D801DEDEDE01DADADA01D9D9D901DADADA01DCDCDC01D6D6D601FFFFFF01 + D8D8D801DADADA01D9D9D901DADADA01D8D8D801A7A7A701D8D8D801DDDDDD01 + D8D8D801FFFFFF01FDFDFD01FFFFFF01DADADA01D8D8D801DCDCDC01D7D7D701 + DBDBDB01D8D8D801DBDBDB01DADADA01D9D9D902A9A9A901A5A5A501DADADA02 + DCDCDC01D9D9D902DDDDDD01DBDBDB01DADADA10DCDCDC01DBDBDB01FFFFFF01 + FBFBFB01DADADA01DCDCDC01D8D8D801DBDBDB02D9D9D901DADADA01D9D9D902 + DADADA02DCDCDC01D9D9D901DADADA01D9D9D901D8D8D801DADADA01D9D9D901 + D7D7D701DCDCDC01DBDBDB01D6D6D601DDDDDD01DADADA01A4A4A401AAAAAA01 + FFFFFF01DADADA01DBDBDB01DADADA01D8D8D801FCFCFC01FFFFFF02FDFDFD01 + DEDEDE01DADADA02DDDDDD01DBDBDB01D9D9D902DCDCDC01D5D5D501DBDBDB01 + D7D7D701DDDDDD01D9D9D901FDFDFD01FEFEFE01D9D9D901DBDBDB01D8D8D801 + E1E1E101DADADA01D9D9D902DADADA01DBDBDB01DADADA01A9A9A901A6A6A601 + D9D9D901DBDBDB01D8D8D801DEDEDE01A7A7A701A8A8A801DADADA01DCDCDC01 + DBDBDB01D9D9D901DEDEDE01DADADA11DCDCDC01DBDBDB01D7D7D701D8D8D801 + DBDBDB01D8D8D801DCDCDC01DBDBDB01D7D7D701DEDEDE01D8D8D801DADADA01 + DCDCDC01DADADA01ACACAC01A8A8A801FEFEFE01DADADA01D9D9D901DFDFDF01 + D6D6D601DBDBDB01DADADA01D8D8D801DBDBDB01DCDCDC01DADADA01D9D9D901 + DBDBDB01FEFEFE01FFFFFF01A6A6A601AAAAAA01DDDDDD01D8D8D801DADADA01 + DCDCDC01D8D8D801D9D9D901DADADA0FDBDBDB01D8D8D801DBDBDB01DCDCDC01 + D6D6D601DDDDDD01DBDBDB01D7D7D702DDDDDD01D8D8D801DBDBDB01DADADA01 + DEDEDE01D8D8D801DBDBDB02D7D7D701DEDEDE01DBDBDB01D9D9D901DFDFDF01 + DBDBDB01D7D7D701DADADA02D8D8D801DCDCDC01D8D8D801D9D9D901DCDCDC01 + D9D9D901DBDBDB01D8D8D801DADADA01DCDCDC01D9D9D901DDDDDD01DADADA01 + D9D9D901DADADA01D8D8D801DCDCDC01DBDBDB01D8D8D801D9D9D901DBDBDB01 + DADADA01D9D9D901DBDBDB01DDDDDD01D8D8D801D9D9D901DCDCDC01DBDBDB01 + DADADA01DBDBDB02D8D8D801FAFAFA01D9D9D901DDDDDD01D8D8D801DCDCDC01 + DADADA01D9D9D901DADADA02DBDBDB01DADADA01D9D9D901DADADA01DCDCDC01 + DBDBDB01D8D8D802D9D9D901DBDBDB01D6D6D601D8D8D801DADADA10D7D7D701 + DCDCDC02DBDBDB01DDDDDD01D6D6D601DBDBDB01D8D8D801DDDDDD01A6A6A601 + DADADA01D9D9D901FEFEFE01D9D9D901A6A6A601A8A8A801DADADA02DCDCDC01 + D5D5D501DBDBDB01DCDCDC01DBDBDB01DADADA01D8D8D801D9D9D901DADADA01 + DBDBDB01DCDCDC01FFFFFF01FAFAFA01ACACAC01A6A6A601D9D9D901DDDDDD01 + D8D8D801DBDBDB01DCDCDC01DADADA10DBDBDB03D7D7D701DCDCDC02D5D5D501 + DDDDDD01DBDBDB01D7D7D701DCDCDC01D9D9D902D8D8D801DADADA02DBDBDB01 + DADADA02D8D8D801DADADA01D7D7D701DBDBDB03D9D9D901DCDCDC01D7D7D701 + FFFFFF01FCFCFC01DCDCDC01D9D9D902DDDDDD01D9D9D901DADADA01DBDBDB01 + D8D8D801DBDBDB01D9D9D901DCDCDC01D8D8D801D9D9D901DADADA01DBDBDB02 + D9D9D901DBDBDB02D7D7D701DBDBDB01DCDCDC01D9D9D902DBDBDB01D9D9D902 + A8A8A801AAAAAA01DADADA01DBDBDB01DADADA01DBDBDB01DADADA01FDFDFD01 + FFFFFF01D8D8D801DBDBDB02D9D9D901FEFEFE01FFFFFF01D9D9D901DADADA02 + DBDBDB02D8D8D801DDDDDD01DADADA11DDDDDD01D6D6D601DCDCDC01D9D9D902 + DCDCDC01D9D9D901A9A9A901A8A8A801A9A9A901A8A8A802DADADA01DCDCDC01 + A7A7A701DBDBDB01DCDCDC01A5A5A501DBDBDB01DCDCDC01DBDBDB01D8D8D802 + A9A9A901DBDBDB01DADADA02D8D8D801DADADA01FDFDFD01FFFFFF01D8D8D801 + DADADA01DCDCDC01D8D8D801DBDBDB01D9D9D901DADADA02DBDBDB01DADADA10 + D8D8D801DBDBDB01DCDCDC01D9D9D902DBDBDB01DCDCDC01D8D8D801D9D9D901 + DCDCDC01DADADA01D9D9D901DCDCDC01D8D8D801DADADA21D9D9D901DCDCDC01 + D8D8D801DADADA01DDDDDD01D8D8D801DCDCDC01DDDDDD01D8D8D801D9D9D901 + DBDBDB01D9D9D901DCDCDC01D8D8D801DADADA01DBDBDB01DADADA01D8D8D801 + DBDBDB02D8D8D801DCDCDC01DADADA01DBDBDB01D8D8D801DBDBDB02D9D9D901 + DBDBDB01DADADA01D8D8D801DBDBDB01A9A9A901D9D9D902DBDBDB01DADADA01 + DCDCDC01DADADA01D9D9D901DCDCDC01D9D9D901DADADA02D7D7D701DEDEDE01 + D8D8D801D9D9D901DDDDDD01D8D8D801DCDCDC01D9D9D902DADADA01FFFFFF01 + A8A8A802A6A6A601ABABAB01DADADA02A7A7A701DADADA01DDDDDD01D6D6D601 + DCDCDC02D7D7D701DBDBDB01D9D9D901DBDBDB02D9D9D901DBDBDB01A8A8A801 + DBDBDB01FCFCFC01FFFFFF01DADADA02A9A9A901DADADA01DBDBDB01DADADA01 + DBDBDB02DADADA10DCDCDC01DBDBDB01D9D9D901D8D8D802DADADA01D9D9D901 + D8D8D801DDDDDD01DBDBDB01D7D7D701DBDBDB01D8D8D801D9D9D901DCDCDC01 + DADADA20DBDBDB01D8D8D801DADADA01DBDBDB01DEDEDE01D7D7D701DCDCDC01 + FEFEFE01FCFCFC01DEDEDE01DADADA02D9D9D901DADADA01DDDDDD01D8D8D801 + DCDCDC01D9D9D901DBDBDB01D9D9D901A7A7A701AAAAAA01D9D9D901DBDBDB01 + D9D9D901DBDBDB02D7D7D701D9D9D901DCDCDC01D9D9D901DADADA01D7D7D701 + DADADA01DBDBDB01DDDDDD01DADADA01D8D8D801D9D9D903DCDCDC01DADADA02 + D8D8D801DCDCDC01D7D7D701A9A9A901DADADA02D9D9D901D6D6D601DFDFDF01 + FEFEFE01FFFFFF01D9D9D901DBDBDB01DCDCDC02D7D7D701D9D9D901AAAAAA01 + A8A8A801FFFFFF01A8A8A801D9D9D901D8D8D801D9D9D901DBDBDB01FEFEFE01 + DDDDDD01D8D8D801DBDBDB02D7D7D701DADADA01DBDBDB01DADADA03D9D9D901 + A7A7A701D9D9D901D8D8D801DBDBDB01D8D8D801DBDBDB01DADADA0FD9D9D902 + DADADA01DBDBDB02DDDDDD02DADADA02D8D8D802D9D9D901DEDEDE01DADADA01 + D8D8D801DBDBDB01DADADA22DCDCDC01D7D7D701D8D8D801DADADA01D7D7D701 + DCDCDC02D7D7D701DCDCDC01DADADA01DBDBDB01D6D6D601DDDDDD01A9A9A901 + A5A5A501DADADA01AAAAAA01A8A8A801DCDCDC01A7A7A701D8D8D801D9D9D901 + DCDCDC01D9D9D901DADADA01DDDDDD01DADADA01D2D2D201DEDEDE01FFFFFF01 + DEDEDE01DADADA01D8D8D801D9D9D901DDDDDD01D7D7D701DEDEDE01DADADA01 + ABABAB01A5A5A501DCDCDC01D7D7D701DCDCDC01DADADA01A8A8A801A9A9A901 + AAAAAA01D9D9D901D8D8D801DCDCDC01D8D8D801DADADA01FFFFFF02D9D9D901 + DADADA01D8D8D801DBDBDB02AAAAAA01D6D6D601AAAAAA01A6A6A601DDDDDD01 + DCDCDC01DBDBDB01DADADA01DCDCDC01D8D8D801DADADA02FFFFFF01DBDBDB01 + D9D9D901D8D8D801DBDBDB01DCDCDC01FEFEFE01DCDCDC01AAAAAA01D9D9D901 + DEDEDE01DBDBDB02D9D9D901DADADA0FDCDCDC01D8D8D801DADADA02D9D9D901 + DADADA01D9D9D902DADADA02DDDDDD01DCDCDC01D6D6D601DADADA01DBDBDB01 + D9D9D901DADADA20D9D9D901D8D8D801DCDCDC01DADADA01D9D9D901DEDEDE01 + DCDCDC01D8D8D801D9D9D901DCDCDC01D8D8D802DDDDDD01D9D9D901DADADA01 + D8D8D801ABABAB01DBDBDB01FCFCFC01DEDEDE01D7D7D701DADADA01DBDBDB01 + DCDCDC01D8D8D801DDDDDD01DCDCDC01D7D7D701DBDBDB01DEDEDE01D8D8D801 + D7D7D701D8D8D802DEDEDE01D9D9D901D8D8D801A9A9A901A7A7A701A8A8A801 + A5A5A501A9A9A901A7A7A701DBDBDB01DADADA01FFFFFF01A5A5A501A8A8A801 + A4A4A401A8A8A801ABABAB01DDDDDD01D7D7D701FFFFFF02FEFEFE01FDFDFD01 + FFFFFF01DCDCDC01D6D6D601DDDDDD01A7A7A701DCDCDC01A5A5A501AAAAAA01 + DADADA01D7D7D701D9D9D901DADADA01A5A5A501DBDBDB01DCDCDC01A7A7A701 + A8A8A801DADADA01DBDBDB02DDDDDD01D7D7D701FEFEFE01D6D6D601DBDBDB01 + DADADA01D7D7D701D9D9D901DBDBDB01DDDDDD01D9D9D901DADADA0EDBDBDB01 + D9D9D901DCDCDC01D9D9D901D7D7D701DADADA02DCDCDC01DBDBDB01D8D8D801 + D7D7D701DBDBDB01D8D8D801DDDDDD01D9D9D901DEDEDE01DADADA21DCDCDC01 + DADADA01D8D8D801DBDBDB01D8D8D801D4D4D401DADADA01D8D8D801DBDBDB02 + D9D9D901DADADA01FEFEFE01FFFFFF01DDDDDD01FDFDFD01FFFFFF01D9D9D901 + FCFCFC01DBDBDB01DDDDDD01D9D9D901D8D8D801DBDBDB01D8D8D801DADADA01 + DBDBDB01D9D9D902DADADA01DEDEDE01DBDBDB01DADADA01DCDCDC01D7D7D701 + DCDCDC01A8A8A801D9D9D902A7A7A701A9A9A901AAAAAA01D8D8D801FEFEFE01 + FFFFFF01DBDBDB01A7A7A701ABABAB01AAAAAA01D8D8D801A5A5A501DFDFDF01 + D9D9D901FEFEFE01FFFFFF02FDFDFD01DADADA01DDDDDD01A6A6A601D7D7D701 + E1E1E101A8A8A802A6A6A601A9A9A901ABABAB01A9A9A903D9D9D901AAAAAA01 + A6A6A601A8A8A801DCDCDC01DADADA01D8D8D801DADADA01FFFFFF01DCDCDC01 + D9D9D901DADADA01DDDDDD01D7D7D701D9D9D901D8D8D801DDDDDD01DADADA0E + D8D8D801DADADA01DCDCDC01D9D9D901DBDBDB01DFDFDF01D8D8D802D9D9D901 + A5A5A501ADADAD01D9D9D901DADADA01DBDBDB01D9D9D901D6D6D601DADADA20 + D9D9D901DADADA01D9D9D902DCDCDC01DEDEDE01DCDCDC01D9D9D901DCDCDC01 + DADADA02D9D9D901D8D8D801DADADA01FFFFFF01D7D7D701DCDCDC01FFFFFF01 + DADADA01DCDCDC01DADADA02D8D8D801DDDDDD01DCDCDC01D7D7D701DADADA01 + DBDBDB01D8D8D801D9D9D903DBDBDB01D8D8D801DBDBDB01FFFFFF01FEFEFE01 + FDFDFD01DADADA01DBDBDB01DDDDDD01A6A6A601A7A7A701DCDCDC01FEFEFE01 + FCFCFC01DBDBDB01DADADA01D9D9D901A4A4A401AAAAAA01A9A9A901D8D8D801 + DBDBDB01D9D9D901DBDBDB01FFFFFF02D8D8D801D9D9D901DADADA01DDDDDD01 + D5D5D501A7A7A701A8A8A801A9A9A901A4A4A401DBDBDB01A7A7A701A5A5A501 + FDFDFD01FFFFFF01A7A7A701ABABAB01D9D9D901D7D7D701DBDBDB01A9A9A901 + A7A7A701D7D7D701DADADA01DEDEDE01D7D7D702DEDEDE01DBDBDB01DADADA01 + D8D8D801DADADA10DBDBDB01D8D8D801DBDBDB01DADADA01D4D4D401DDDDDD01 + DCDCDC01D7D7D701DCDCDC01D9D9D902DDDDDD01DADADA22DDDDDD01D8D8D801 + DADADA01DDDDDD01D5D5D502DBDBDB02D7D7D701A7A7A701DEDEDE01D9D9D901 + DCDCDC01D9D9D902DBDBDB01D7D7D701DADADA02D8D8D802DCDCDC01D8D8D801 + DADADA01DBDBDB01DADADA01DBDBDB01D9D9D901DADADA01DBDBDB01D9D9D901 + DBDBDB01DADADA01DBDBDB01D8D8D801FFFFFF01FAFAFA01FFFFFF01FDFDFD01 + FFFFFF02D7D7D701DADADA01D9D9D901FFFFFF02DCDCDC01D8D8D801AAAAAA01 + DBDBDB01A8A8A801A5A5A501A9A9A901DADADA01D8D8D801DADADA01FCFCFC01 + FFFFFF02DCDCDC01DADADA01D6D6D601DDDDDD02D8D8D801DCDCDC02D8D8D801 + DBDBDB01DCDCDC01FFFFFF01FDFDFD01D9D9D901D7D7D701DCDCDC01DADADA01 + DBDBDB01D8D8D801DEDEDE01DBDBDB01DADADA01D9D9D901DCDCDC01DADADA02 + DBDBDB01D9D9D901DBDBDB01DADADA0EDBDBDB01D9D9D901DBDBDB01DADADA02 + D7D7D701DEDEDE01FEFEFE01FFFFFF01DBDBDB01D9D9D901DADADA01DCDCDC01 + D8D8D801DBDBDB02DADADA20D8D8D801DBDBDB01DADADA02DBDBDB03D9D9D901 + DADADA01DBDBDB01D9D9D901D8D8D801DADADA01DCDCDC01D9D9D901DBDBDB01 + DCDCDC01DADADA01D9D9D901DCDCDC01DADADA02D9D9D901DBDBDB01D7D7D701 + DCDCDC01DBDBDB01D7D7D701DBDBDB02D6D6D601DADADA01D8D8D801DCDCDC01 + DADADA01D8D8D801FFFFFF02FEFEFE01FFFFFF01FEFEFE01DCDCDC01DBDBDB01 + A8A8A801DBDBDB01D7D7D701DBDBDB02D7D7D701DDDDDD01A8A8A801A9A9A901 + A8A8A801D9D9D901DCDCDC01DBDBDB01FFFFFF01FEFEFE01FFFFFF02DADADA03 + D8D8D801DADADA03D9D9D901A9A9A901D9D9D901FFFFFF02DADADA01ABABAB01 + D9D9D901FDFDFD01FFFFFF01DBDBDB01D8D8D801A8A8A802DADADA01DCDCDC01 + DBDBDB01D9D9D901DADADA01DBDBDB01DADADA3FDBDBDB01D9D9D901DBDBDB01 + DADADA02D7D7D701DEDEDE01FEFEFE01DADADA08DBDBDB01D6D6D601DCDCDC01 + D9D9D901DADADA01D7D7D701DDDDDD01DADADA01A8A8A802D8D8D801DADADA01 + D9D9D901DDDDDD01D9D9D901A6A6A601DCDCDC01D9D9D901DBDBDB01D7D7D701 + DDDDDD01D9D9D901D7D7D701DCDCDC02DADADA02A6A6A601DBDBDB01DADADA02 + DBDBDB01DADADA02DBDBDB01AAAAAA01A5A5A501DADADA04FDFDFD01FFFFFF03 + DADADA01DBDBDB01D9D9D901DBDBDB01DADADA02A7A7A701DADADA01D8D8D801 + FFFFFF01DADADA01A7A7A701A9A9A901AAAAAA01A6A6A601A8A8A801AAAAAA01 + A5A5A501A9A9A901A7A7A701A9A9A901D9D9D901D8D8D801D9D9D901DBDBDB02 + D9D9D901DADADA40DBDBDB01D8D8D801DBDBDB01DADADA01D4D4D401DDDDDD01 + DADADA08D8D8D801DDDDDD01D9D9D901DCDCDC01D9D9D901DDDDDD01D8D8D801 + D9D9D901A9A9A902DBDBDB01D8D8D801A7A7A701A6A6A602ACACAC01D6D6D601 + DBDBDB01DDDDDD01D8D8D801D7D7D701DEDEDE01DBDBDB01D9D9D902FEFEFE01 + FFFFFF01FEFEFE01D9D9D901DADADA01D9D9D901D8D8D801FFFFFF01FDFDFD01 + D9D9D901A7A7A701A9A9A901ADADAD01A4A4A401D9D9D901DBDBDB01D9D9D901 + FFFFFF03DADADA01D6D6D601DBDBDB01DADADA03A5A5A501E0E0E001D8D8D801 + D7D7D701DBDBDB01A9A9A901A6A6A601AAAAAA01A8A8A801A6A6A601DBDBDB02 + AAAAAA01ABABAB01A1A1A101A9A9A901DFDFDF01D9D9D902DBDBDB01DADADA3F + D8D8D801DADADA01DCDCDC01D9D9D901DBDBDB01DFDFDF01D8D8D802DADADA08 + DBDBDB01D8D8D801DADADA01D8D8D801D7D7D701DBDBDB01FFFFFF02D9D9D901 + DBDBDB01D8D8D801DBDBDB01A8A8A801DBDBDB01A6A6A602DDDDDD01DBDBDB01 + DADADA01DDDDDD01DCDCDC01D6D6D601DCDCDC01D9D9D901A6A6A601FFFFFF01 + FEFEFE01FFFFFF01DCDCDC01DADADA01FEFEFE01FFFFFF01FEFEFE01FFFFFF02 + A5A5A501A8A8A801A9A9A902DDDDDD01DADADA02DBDBDB01FEFEFE01FDFDFD01 + FFFFFF01DDDDDD01D9D9D901D7D7D701DCDCDC01A8A8A801AAAAAA01A5A5A501 + DBDBDB01DADADA01D8D8D801DADADA01D9D9D903DCDCDC01D9D9D901DDDDDD01 + D6D6D601A5A5A501DEDEDE01A7A7A701DADADA01D9D9D901D7D7D701DDDDDD01 + D8D8D801DADADA3EDBDBDB01D9D9D901DCDCDC01D9D9D901D7D7D701DADADA02 + DCDCDC01DADADA08D8D8D801DBDBDB01DADADA01DEDEDE01DBDBDB01DADADA01 + FFFFFF02D9D9D902FFFFFF02DADADA01DCDCDC01A8A8A802D6D6D601DCDCDC01 + D8D8D801D7D7D701D9D9D901DDDDDD01D9D9D901DCDCDC01A8A8A801DCDCDC01 + FEFEFE02D9D9D902DBDBDB01DADADA01FFFFFF01FCFCFC02DEDEDE01DCDCDC01 + A7A7A701A8A8A801D7D7D701D8D8D801DCDCDC01D8D8D801FFFFFF03D3D3D301 + DEDEDE01DDDDDD01D7D7D701A9A9A901A5A5A501A8A8A801DCDCDC01D9D9D901 + DCDCDC01DADADA02DFDFDF01D9D9D901D7D7D701DADADA01D9D9D901DDDDDD01 + D9D9D901DCDCDC01D6D6D601AAAAAA01DCDCDC01DBDBDB02D9D9D901DADADA3E + DCDCDC01D8D8D801DADADA02D9D9D901DADADA01D9D9D902DADADA08DEDEDE01 + D7D7D701D8D8D801DBDBDB01D7D7D701DCDCDC01D7D7D701AAAAAA01A9A9A901 + A8A8A801FEFEFE01FFFFFF02D8D8D801A8A8A801A9A9A901DBDBDB01D9D9D901 + DEDEDE01DCDCDC02D9D9D901FFFFFF01D9D9D901DCDCDC01D8D8D801FFFFFF02 + A9A9A901ACACAC01A6A6A601D9D9D902FFFFFF01DBDBDB01DADADA01D5D5D501 + ABABAB01A9A9A901DCDCDC01DDDDDD01DBDBDB01D9D9D901A8A8A801DBDBDB01 + FFFFFF01DCDCDC01D8D8D802D9D9D901E0E0E001A7A7A701DBDBDB01D9D9D901 + DCDCDC01D6D6D601D9D9D901DADADA01D7D7D701DADADA01DDDDDD02D6D6D601 + ABABAB01FFFFFF01DADADA01DCDCDC01A4A4A401D9D9D901DBDBDB01D8D8D801 + DADADA3FD9D9D902DADADA01DBDBDB02DDDDDD02DADADA09D9D9D902DEDEDE01 + D8D8D801D9D9D901DCDCDC01D9D9D901DBDBDB01A9A9A901A6A6A601FFFFFF02 + FBFBFB01DBDBDB01AAAAAA01A4A4A401DBDBDB01D9D9D901D8D8D801DBDBDB01 + D7D7D701A9A9A901DCDCDC01DADADA01D8D8D801DEDEDE01FEFEFE01FFFFFF01 + A3A3A301A8A8A801A9A9A901DADADA02FFFFFF01D9D9D902DCDCDC01A8A8A801 + A6A6A601A8A8A801A5A5A501D7D7D701DCDCDC01DADADA01FCFCFC01FDFDFD01 + DCDCDC01D9D9D901DBDBDB02D5D5D501DBDBDB02D9D9D901DADADA01DCDCDC01 + DBDBDB01DADADA01DBDBDB01DADADA01D9D9D901DADADA01DCDCDC01A5A5A501 + D8D8D801FFFFFF01DADADA01DCDCDC01DBDBDB01DADADA01D9D9D901DADADA40 + DCDCDC01DBDBDB01D9D9D901D8D8D802DADADA01D9D9D901DADADA08D9D9D901 + DBDBDB01D7D7D701DBDBDB01DEDEDE01FEFEFE01FDFDFD01D9D9D901A6A6A601 + ACACAC01A4A4A401DADADA01FFFFFF01FDFDFD01ABABAB01D9D9D901D7D7D701 + DADADA01D9D9D901DFDFDF01D9D9D901D8D8D801DBDBDB01DADADA03FFFFFF01 + D6D6D601DCDCDC01AAAAAA01A4A4A401AAAAAA01DBDBDB01D5D5D501DDDDDD01 + DADADA01DBDBDB01AAAAAA01A7A7A701A8A8A801A9A9A901FFFFFF02A9A9A901 + D6D6D601DFDFDF01D7D7D701DCDCDC02D9D9D901DADADA01DDDDDD01DADADA01 + D9D9D901DBDBDB01D8D8D801DADADA02DBDBDB01D9D9D901D8D8D801DCDCDC01 + A6A6A601ABABAB01A9A9A901FDFDFD01DBDBDB01D8D8D801A7A7A701DCDCDC01 + DADADA01D8D8D801DADADA40D8D8D801DBDBDB01DCDCDC01D9D9D902DBDBDB01 + DADADA08DBDBDB02DADADA01DBDBDB01D8D8D801DADADA01FFFFFF01D9D9D901 + DCDCDC01A6A6A601A9A9A901FFFFFF03D6D6D601AAAAAA01DCDCDC01DADADA01 + D9D9D901FBFBFB01FFFFFF01D9D9D901DBDBDB01DADADA03FDFDFD01FFFFFF01 + FEFEFE01A6A6A601ACACAC01A7A7A701D9D9D901DEDEDE01D8D8D801D9D9D901 + DBDBDB01D9D9D901DADADA01DBDBDB01D8D8D801DBDBDB01D9D9D901DADADA01 + DBDBDB01D8D8D801DBDBDB01D9D9D901D8D8D801DBDBDB01D9D9D901D7D7D701 + DBDBDB01D8D8D801DCDCDC01DADADA01D9D9D901DCDCDC01D7D7D701DDDDDD01 + DADADA01D9D9D901AAAAAA01A8A8A802DBDBDB01D8D8D801DDDDDD01D7D7D701 + ABABAB01D7D7D701DCDCDC01DADADA46DCDCDC01D7D7D701DADADA01DDDDDD01 + DADADA02DBDBDB01D9D9D902DCDCDC01D9D9D901DDDDDD01DADADA01FEFEFE01 + D9D9D901FFFFFF02DCDCDC01A8A8A801A6A6A601FFFFFF01DBDBDB01A7A7A701 + A9A9A901AAAAAA01A8A8A801DBDBDB01D8D8D801DADADA01D9D9D901DCDCDC01 + D9D9D901D8D8D801FFFFFF04DADADA01D9D9D901DCDCDC01DBDBDB01DCDCDC01 + DADADA01D7D7D701DADADA01D9D9D901FFFFFF01DADADA01D9D9D901FFFFFF01 + FEFEFE01D9D9D901D8D8D801DADADA01DBDBDB01DADADA0EDCDCDC01FFFFFF01 + D8D8D801DDDDDD01D9D9D901FFFFFF01DADADA01DBDBDB01DADADA01A7A7A701 + DBDBDB01DADADA46D9D9D901DFDFDF01D8D8D801DADADA01D8D8D801A6A6A601 + AAAAAA01DBDBDB01DCDCDC01D8D8D801D9D9D903FFFFFF01A9A9A901FDFDFD01 + FEFEFE01AAAAAA01A7A7A701ADADAD01DADADA01FDFDFD01DDDDDD01A6A6A601 + A5A5A501A8A8A801D7D7D701D9D9D901DDDDDD01D9D9D901D6D6D601DBDBDB01 + D9D9D901E0E0E001D9D9D901FEFEFE01FFFFFF01DADADA02D8D8D801DBDBDB01 + D6D6D601FFFFFF03DBDBDB01D7D7D701D8D8D801DBDBDB01D7D7D701DADADA01 + DEDEDE01DADADA01DBDBDB02D7D7D701DADADA08DBDBDB01DCDCDC01D9D9D901 + DBDBDB01DADADA01FFFFFF02DEDEDE01D9D9D901DADADA01DBDBDB01FFFFFF01 + DBDBDB01D9D9D901DBDBDB01D8D8D801DADADA46D8D8D801DADADA03DBDBDB01 + DADADA01A9A9A901A7A7A701A6A6A601DDDDDD01DBDBDB01DADADA01FFFFFF01 + DADADA01A5A5A501FFFFFF02D8D8D801A7A7A701A8A8A801D8D8D801FFFFFF01 + FDFDFD01FFFFFF01A9A9A901A8A8A801DDDDDD01DFDFDF01DADADA01D7D7D701 + DBDBDB01DADADA01DBDBDB01D7D7D701DADADA02FEFEFE02DADADA01DCDCDC01 + DBDBDB01D9D9D901FFFFFF01FEFEFE01D8D8D801DDDDDD01DCDCDC01DBDBDB01 + D9D9D901FFFFFF01DCDCDC01D7D7D701DADADA01D6D6D601DBDBDB02DADADA08 + D9D9D901DBDBDB01DADADA01D9D9D901D8D8D801D9D9D901DCDCDC01D7D7D701 + D9D9D901DCDCDC01D9D9D901D8D8D801FEFEFE01DADADA01DDDDDD01DADADA47 + DCDCDC01D8D8D801D9D9D901FEFEFE01FFFFFF01DCDCDC01D8D8D801D9D9D901 + DCDCDC01D8D8D801D9D9D901DADADA01FEFEFE01DCDCDC01DADADA01FEFEFE01 + FCFCFC01DADADA01AAAAAA01A5A5A501AAAAAA01FFFFFF01FEFEFE02A7A7A701 + DCDCDC01D6D6D601D7D7D701D9D9D901DBDBDB01A9A9A901DADADA01D9D9D901 + DBDBDB02FFFFFF01FDFDFD01DDDDDD01DADADA01D8D8D801A6A6A601AAAAAA01 + D8D8D801DADADA01DBDBDB01D7D7D701D9D9D902FFFFFF02D9D9D901DCDCDC01 + DADADA01DBDBDB01DCDCDC01D8D8D801DADADA09DCDCDC01DADADA01DDDDDD01 + DADADA01DDDDDD01D7D7D701DDDDDD01DBDBDB02D8D8D801DDDDDD02DADADA02 + D7D7D701DADADA46D9D9D901DADADA01DCDCDC01A9A9A901FFFFFF01FCFCFC01 + FFFFFF01DCDCDC01D9D9D902DADADA01DEDEDE01FEFEFE01A6A6A601ACACAC01 + FFFFFF02DBDBDB01DADADA01A9A9A901A7A7A702FFFFFF01D9D9D901A6A6A601 + ABABAB01DADADA01DCDCDC01DDDDDD01D9D9D901DADADA01D9D9D901DADADA01 + FFFFFF01DADADA01D8D8D801FFFFFF01D7D7D701D6D6D601DFDFDF01A8A8A801 + A9A9A901D8D8D801A9A9A901DADADA01D9D9D901DADADA01DBDBDB01FEFEFE01 + FFFFFF01DDDDDD01D8D8D802DBDBDB02D9D9D901DADADA08DDDDDD01D7D7D701 + A8A8A801D7D7D701A9A9A901DCDCDC01D7D7D701DADADA01D8D8D801DCDCDC01 + DBDBDB01D9D9D901D5D5D501D9D9D901DBDBDB02DADADA46D9D9D901DDDDDD01 + D8D8D801A7A7A701DADADA01DCDCDC01D6D6D601D9D9D901DDDDDD01DBDBDB01 + D9D9D901D8D8D801D9D9D901A9A9A901A3A3A301FFFFFF01FCFCFC01DBDBDB01 + D6D6D601AAAAAA01A8A8A801A5A5A501FEFEFE01ADADAD01A9A9A902DCDCDC01 + D7D7D701FCFCFC01DBDBDB01DADADA02DBDBDB01DADADA01D8D8D801FFFFFF02 + DADADA01DFDFDF01D7D7D701A8A8A801A6A6A601DBDBDB01AAAAAA01DADADA01 + DBDBDB02D8D8D801FEFEFE01FFFFFF01D9D9D901DBDBDB01DEDEDE01D7D7D701 + DBDBDB01D9D9D901DADADA08D9D9D901A9A9A902D8D8D801A8A8A801D8D8D801 + DBDBDB01DCDCDC01DBDBDB01D7D7D701DCDCDC01D6D6D601DCDCDC01DEDEDE01 + D8D8D801DBDBDB01DADADA06 + } + container.face.fade_pos.count = 2 + container.face.fade_pos.items = ( + 0 + 1 + ) + container.face.fade_color.count = 2 + container.face.fade_color.items = ( + 15590106 + 11906751 + ) + container.face.localprops = [fal_faopacity] + container.taborder = 1 + container.bounds = ( + 0 + 30 + 638 + 256 + ) + optionswindow = [wo_groupleader] + mainmenu = mainmenu1 + options = [fo_main, fo_terminateonclose, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savestate] + statfile = tstatfile1 + caption = 'MSEide + MSEgui' + moduleclassname = 'tmseform' + object tstringedit1: tstringedit + color = -2147483645 + frame.leveli = 1 + frame.framewidth = 2 + frame.colorframe = -2147483645 + frame.colorclient = -2147483645 + frame.caption = 'Caption &topleft' + frame.font.color = 29539 + frame.font.name = 'stf_default' + frame.font.xscale = 1 + frame.font.localprops = [flp_color, flp_xscale] + frame.localprops = [frl_leveli, frl_framewidth, frl_colorframe, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + bounds_x = 107 + bounds_y = 39 + bounds_cy = 43 + statfile = tstatfile1 + reffontheight = 14 + end + object tstringedit2: tstringedit + color = -2147483645 + frame.leveli = 1 + frame.framewidth = 2 + frame.colorframe = -2147483645 + frame.colorclient = -2147483645 + frame.caption = 'Caption &top' + frame.captionpos = cp_top + frame.font.color = 37241 + frame.font.style = [fs_bold] + frame.font.name = 'stf_default' + frame.font.xscale = 1 + frame.font.localprops = [flp_color, flp_style, flp_xscale] + frame.localprops = [frl_leveli, frl_framewidth, frl_colorframe, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + face.fade_pos.count = 2 + face.fade_pos.items = ( + 0 + 1 + ) + face.fade_color.count = 2 + face.fade_color.items = ( + 12378329 + 10592767 + ) + face.fade_opacity = 6250335 + face.localprops = [fal_faopacity] + taborder = 1 + bounds_x = 262 + bounds_y = 39 + bounds_cy = 43 + statfile = tstatfile1 + reffontheight = 14 + end + object tstringedit3: tstringedit + color = -2147483645 + frame.levelo = 3 + frame.leveli = -1 + frame.framewidth = 2 + frame.colorframe = -2147483645 + frame.colorclient = -2147483645 + frame.caption = 'Caption &left' + frame.captionpos = cp_left + frame.font.color = -1610612730 + frame.font.style = [fs_bold, fs_italic] + frame.font.name = 'stf_default' + frame.font.xscale = 1 + frame.font.localprops = [flp_color, flp_style, flp_xscale] + frame.localprops = [frl_levelo, frl_leveli, frl_framewidth, frl_colorframe, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 81 + 0 + 0 + 0 + ) + face.fade_pos.count = 2 + face.fade_pos.items = ( + 0 + 1 + ) + face.fade_color.count = 2 + face.fade_color.items = ( + -1610612730 + -1610612731 + ) + face.fade_direction = gd_up + face.fade_opacity = 8355711 + face.localprops = [fal_fadirection, fal_faopacity] + taborder = 3 + bounds_x = 23 + bounds_y = 112 + bounds_cx = 181 + bounds_cy = 32 + statfile = tstatfile1 + reffontheight = 14 + end + object tstringedit4: tstringedit + color = -2147483645 + frame.levelo = 0 + frame.frameimage_list = imli + frame.frameimage_offset = 24 + frame.colorclient = -2147483645 + frame.caption = 'Caption &bottom' + frame.captionpos = cp_bottom + frame.font.color = 12419927 + frame.font.name = 'stf_default' + frame.font.xscale = 1 + frame.font.localprops = [flp_color, flp_xscale] + frame.localprops = [frl_levelo, frl_leveli, frl_framewidth, frl_frameimagelist, frl_frameimageoffset, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 0 + 17 + ) + taborder = 6 + bounds_x = 261 + bounds_y = 177 + bounds_cy = 49 + statfile = tstatfile1 + reffontheight = 14 + end + object tstringedit5: tstringedit + color = -2147483645 + frame.levelo = 3 + frame.leveli = -1 + frame.framewidth = 2 + frame.colorframe = -2147483645 + frame.colorclient = -2147483645 + frame.caption = 'Caption botto&mright' + frame.captionpos = cp_bottomright + frame.font.color = 8876645 + frame.font.colorbackground = 13418736 + frame.font.name = 'stf_default' + frame.font.xscale = 1 + frame.font.localprops = [flp_color, flp_colorbackground, flp_xscale] + frame.localprops = [frl_levelo, frl_leveli, frl_framewidth, frl_colorframe, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 28 + 0 + 0 + 17 + ) + taborder = 5 + bounds_x = 76 + bounds_y = 176 + bounds_cx = 128 + bounds_cy = 49 + statfile = tstatfile1 + reffontheight = 14 + end + object tstringedit6: tstringedit + color = -2147483645 + frame.levelo = 0 + frame.frameimage_list = imli + frame.frameimage_offset = 8 + frame.colorclient = -2147483645 + frame.caption = 'Caption &right' + frame.captionpos = cp_right + frame.font.color = 11372216 + frame.font.style = [fs_italic] + frame.font.name = 'stf_default' + frame.font.xscale = 1 + frame.font.localprops = [flp_color, flp_style, flp_xscale] + frame.localprops = [frl_levelo, frl_leveli, frl_framewidth, frl_frameimagelist, frl_frameimageoffset, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 84 + 0 + ) + face.fade_pos.count = 2 + face.fade_pos.items = ( + 0 + 1 + ) + face.fade_color.count = 2 + face.fade_color.items = ( + -1610612730 + -1610612731 + ) + face.fade_direction = gd_up + face.fade_opacity = 8355711 + face.localprops = [fal_fadirection, fal_faopacity] + taborder = 4 + bounds_x = 261 + bounds_y = 113 + bounds_cx = 184 + bounds_cy = 32 + statfile = tstatfile1 + reffontheight = 14 + end + object tstringedit7: tstringedit + color = -2147483645 + frame.levelo = -1 + frame.leveli = 1 + frame.framewidth = 2 + frame.colorframe = -2147483645 + frame.framei_left = 4 + frame.framei_right = 4 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_framewidth, frl_colorframe, frl_fileft, frl_firight, frl_colorclient] + frame.localprops1 = [] + face.options = [fao_alphafadeimage] + face.image.transparentcolor = -2147483642 + face.image.options = [bmo_masked] + face.image.alignment = [al_xcentered, al_ycentered, al_tiled] + face.image.image = { + 000000000200000064000000640000009C580000000000000000000000000000 + 0000000000000000000000000000000000000000AAD5BA01CFEDC901D4EDD901 + DBFBE801F3FEF41F63AD8C01637F6001CFEDC9013F6A49013693630108744201 + 57A07401BEE1C301E6EDDB01BCB7A4019C927401837654017A6D440272663C03 + 7A6D440272663C017A6D440172663C037A6D440172663C017C724C02887D5801 + 948B6D01A1987D01A49E84018376540140604201F3FEF407BEE1C301A9C3A101 + 7C724C01293916013E4C360151583F0158583401444D28012D3E1B018E937301 + B4DAC401F3FEF40BD2FADA01CFEDC90138543302153A1B0144886C017AC6A401 + BEF6DC01F3FEF402B6F5E401F3FEF41ABEF6DC014060420178A8840195D1AB01 + 33805501257C4C015BA47F01C1DCCC01E1E4D601B7B09C01908664017A6D4401 + 72663C0D7A6D44017C724C01887D5801948B6D01A49E8401B7B09C01A9A78401 + 50664C017EAA8E01F3FEF405B6F5E40163AD8C01153A1B015F754C0183B19401 + B3ECD501DBFBE801BCEACC01BEF6DC01DCFEF401BFD8B90178957401304B3401 + 64967001B6F5E401F3FEF404B6F5E401F3FEF401B3ECD50192C2A501637F6001 + 1F402401153A1B01BEF6DC01BAFEEF01B0E2C20178B08B01566C540129391601 + 78A88401BCEACC01F3FEF41CB0E2C201153A1B01A9C3A101AAD5BA0178A88401 + 96B99E01C7E4D101DCE2C301ACAE8A01888264017A6D44016B60340672663C06 + 7A6D44017C724C01887D5801948B6D01A9A78401BCB7A4028E9373012D3E1B01 + B3ECD501F3FEF404B0E2C20140604201566C54019AD5BA0194E6C4011E8F7601 + 0F8264011EAC8E0127BAA7011EAC8E01088C5D011881560195D1AB01BCEACC01 + 637F6001566C5401BEF6DC01F3FEF404A6CBAC012E492A015061410178957401 + A9C3A101B0E2C20126A28E01249772011C7A640144886C019DCCB401BCEACC01 + 44886C011F4024017BB79301B6F5E401F3FEF419B6F5E401F3FEF4019AD5BA01 + 2E492A0196B99E01F0FBEB01C7E4D101F0FBEB01CCCBBC01A1987D0183765401 + 6B603401655729056B60340472663C027A6D44017C724C01887D580190866401 + A9A78401B7B09C01C9C5B401B7B09C0172663C017CA08001F3FEF403B6F5E401 + AAD5BA01153A1B0179977E01D2FADA012281740158BC9C0152E1E0012CCAB401 + 0ACACA010DD7D00128E2CF0140EEC8012BCA9901257C4C017EAA8E01F0FBEB01 + 637F6002BEF6DC02F3FEF40196B99E012D3E1B018E937301CFEDC901AAD5BA01 + 7CA08001338055012BEEDF0112E2D0012CD4D1014CD6DC022281740158BC9C01 + B3ECD5014473580150664C01B0E2C201F3FEF41B9AD5BA01293916018E937301 + C6CCAA01D5D3C301AFA68F019086640172663C01574E2402584B1A0265572904 + 6B60340272663C017A6D44017C724C0183765401948B6D01A49E8401BCB7A401 + C9C5B401C4BFAB0190866401153A1B01BCFAD301F3FEF4039AD5BA0129391601 + 83B194017CD6B401148874014CD6DC010CB1CF01049FC40104A8C30107BFCB01 + 0ACACA011DEDD00128ECC10112C39501088C5D01488A5C01B4DAC401A8C5AC01 + 444D280185B79D01D2FADA01A6CBAC0129391601788B6D01E8F8DB0192C09B01 + 338055010B9664012BCA990129F7DE010DD7D00107BFCB0109B0C20104A8C301 + 0CB1CF0152E1E001228174018CCAB80185B79D012E492A0185B79D01F3FEF41B + B0E2C20150664C013E563C01887D580272663C01584B1A0145411501413C0C01 + 45411503584B1A02655729026B60340172663C02887D580190866401A49E8401 + B7B09C01C6CCAA01C4BFAB018E9373012E492A019AD5BA01F3FEF402B6F5E401 + BCEACC012E492A0178A8840198C9AB0126A28E012CD4D10104A8C301049FC401 + 0CB1CF021CD8DC012BEEDF0124E1B70110B58C01088C5D011881560163AD8C01 + C7E4D101C6CCAA017A6D4401385433017CA080015F754C0158583401ABB09401 + F0FBEB017BB793011881560106976D012BCA99011AD8B60129F7DE010DD7D001 + 0CB1CF01049FC401048DBF022CAACC014CD6DC0122817401BAFEEF0150664C01 + 68967C01BEF6DC01F3FEF41B98C9AB01447358011F40240129391601444D2801 + 545429015061410165572901413C0C0245411501584B1A02655729016B603401 + 72663C017C724C0190866401A1987D01B7B09C01C4BFAB01BCB7A401A1987D01 + 444D280196B99E01F3FEF4047CA0800157745601BCFAD301148874014CD6DC01 + 04A8C3020CB1CF0111CBD70124E4DE0112E2D00116C7A40109A06D0108744201 + 3693630178B08B01C1DCCC01E8F8DB01ABB094017A6D440145411501584B1A01 + 454115016B603401AFA68F01F0FBEB0195D1AB0146986E010874420122A47101 + 09A06D0114CB9A012BEEDF011CD8DC0113BDD7010797C701048DBF010482BC01 + 049AB40138CEDC0122817401B3ECD50144886C01637F6001B6F5E401F3FEF41B + BCFAD301BCEACC0195D1AB01A6CBAC0192C09B0178A88401789574016A8A6401 + 6B60340145411501413C0C0145411501655729027A6D4401887D58019C927401 + ACAE8A01BCB7A401ABB09401948B6D012E492A017BB79301F3FEF404B3ECD501 + 153A1B01BFD8B9010F82640148EDD40107BFCB0109B0C20113BDD7011CD8DC01 + 2BEEDF0115D5AC010BB18201088C5D010B7D4A01499F730192C2A501BCEACC01 + F0FBEB01C9C5B401948B6D0172663C01584B1A01413C0C01584B1A0172663C01 + A1987D01D5D3C301DBFBE80192C2A501499F7301087442010B7D4A01088C5D01 + 12BD92012BE3C40124E4DE0111CBD7010CB1CF010797C701048DBF0234C2D401 + 26A28E0194D6C401488A5C01668B6E01F3FEF401B6F5E401F3FEF41EBCFAD301 + 94E6C40198C9AB017EAA8E01637F60016B603401413C0C014541150165572901 + 7A6D4401888264019C927401A9A784019C9274017C724C012939160198C9AB01 + F3FEF4057BB7930157745601B0E2C2011EAC8E0128E2CF010ACACA010DD7D001 + 2BEEDF0112E2D00112BD920106976D01087442013693630163AD8C0195D1AB01 + D4EDD901E1EFE401CCCBBC01AFA68F01887D580172663C01574E2401584B1A01 + 655729017A6D4401948B6D01BCB7A401E6EDDB01D4EDD90192C2A50164967001 + 5FAB82010C8853010B7D4A010BB1820115D5AC012BEEDF011CD8DC0113BDD701 + 04A8C301049AB40104A8C30124CBC90126A28E019CEDC9015F754C017BB79301 + F3FEF4229CEDC90198C9AB0178A884015F754C0129391601444D28016B603401 + 7C724C0157745601566C48012E492A01637F6001BCEACC01F3FEF404BEF6DC01 + F3FEF401447358017EAA8E0163AD8C012BCCA8011DEDD00112E2D0012BEEDF01 + 15D5AC010AA67D010C885302499F730180BF9B01AAD5BA01E1EFE401EDF0E501 + CCCBBC01ABB09401948B6D01837654016B603402574E24016B60340172663C01 + 90866401A9A78401D5D3C301F0FBEB01C7E4D10192C2A50198C9AB015FAB8201 + 22895F010874420109A06D0112BD920110D6C40129F7DE011CD8DC0111CBD701 + 07BFCB0248EDD40112734C01BAFEEF011F402401B3ECD501F3FEF424B0E2C201 + 7EAA8E015F754C012E492A011F4024013854330168967C019AD5BA01F3FEF407 + BEF6DC011F402401A6CBAC013C8D64012BCCA8012BF9D20124E1B70112C39501 + 06976D010B7D4A01369363015FAB82019DCCB401C7E4D101DBFBE801EDF0E501 + CCCBBC01B7B09C018C987E01888264017A6D440172663C016B6034037A6D4401 + 887D5801A49E8401BCB7A401DBDACE01F3FEF401E1E4D601C7E4D1019DCCB401 + 63AD8C0146986E010B7D4A011179560109A06D0112BD92011AD8B6012BEEDF01 + 24E4DE0112E2D0012EEDD10128C4A40163AD8C017EAA8E0168967C01F3FEF401 + B6F5E401F3FEF425BCFAD302D2FADA01F3FEF409BEF6DC01153A1B01BFD8B901 + 3C8D640124B5920112BD920110A974010B7D4A01188156015BA47F0185B79D01 + B4DAC401D4EDD901F3FEF401DBDACE01C9C5B401B7B09C01A1987D0190866401 + 837654017A6D440172663C047C724C01887D5801948B6D01AFA68F01C9C5B401 + E1E4D601F3FEF402D4EDD901B1CCB90192C2A5015BA47F01369363010B7D4A01 + 0874420109A06D010BB1820114CB9A0124E1B7012BE3C4012ED3A40112734C01 + D2FADA011F402401BCFAD301F3FEF432BCFAD3012E492A01A8C5AC015BA47F01 + 257C4C010C8853010B7D4A0146986E017BB79301AAD5BA01D4EDD901F3FEF401 + E6EDDB01D5D3C301C2BAAC01AFA68F01A1987D0190866401887D580183765401 + 7A6D440272663C017A6D440283765401887D580190866401A49E8401ABB09401 + CCCBBC01E1E4D601DBDACE01F0FBEB02C1DCCC01AAD5BA0180BF9B015FAB8201 + 46986E01188156010B7D4A01117956010B96640109A06D012497720112734C01 + CFEDC90140604201B0E2C201F3FEF433637F600178957401BFD8B90146986E02 + 78B08B01AAD5BA01C7E4D101F3FEF401E1EFE401D5D3C301C9C5B401B7B09C01 + A49E84019C92740190866401887D58027C724C017A6D4406887D580190866401 + 9C927401A49E8401B7B09C01C9C5B401CCCBBC01DBDACE01EDF0E501F3FEF401 + E6EDDB01C1DCCC01AAD5BA0198C9AB0185B79D0163AD8C0146986E0142916E01 + 22895F013380550168967C01D2FADA0157745601A6CBAC01F3FEF4338CCAB801 + 50614101C7E4D101BEE1C301C0D8C401D2FADA01F0FBEB01D4EDD901D5D3C301 + C4BFAB01B7B09C01AFA68F01A1987D0190866402887D5801837654027C724C01 + 7A6D44017C724C017A6D44017C724C0283765402887D5801948B6D019C927401 + A9A78401B7B09C02C2BAAC01CCCBBC01E1E4D601EDF0E501F3FEF402D4EDD902 + BEE1C301AAD5BA01A6CBAC0198C9AB02BFD8B901D4EDD9013F6A4901AAD5BA01 + F3FEF433BEF6DC013F6A490188826401C6CCAA01BFD8B901CCCBBC01BCB7A401 + B7B09C01A49E8401A1987D019C927401948B6D019086640188826401887D5802 + 7C724C09887D580288826401948B6D019C927401A49E8402AFA68F01B7B09C01 + C4BFAB01CCCBBC01D5D3C301E1E4D601E6EDDB02F0FBEB01F3FEF401F0FBEB01 + F3FEF401F0FBEB01DCE2C301A49E84012E492A01BCEACC01F3FEF434B0E2C201 + 2D3E1B0150664C01887D5801888264019086640288826402887D580283765401 + 7C724C01837654017C724C057A6D44017C724C0183765401887D58017A6D4401 + 887D58017C724C01887D580190866401948B6D019C927403A49E8401AFA68F02 + BCB7A402C2BAAC01C9C5B404BCB7A401B7B09C01948B6D0150664C01566C4801 + F3FEF436B0E2C20157745601413C0C01545429016B60340172663C027A6D4401 + 7C724C057A6D44017C724C027A6D4401887D5801837654017C724C0183765401 + 7C724C0183765401887D580490866401948B6D0190866401948B6D029C927401 + A1987D01A49E8402AFA68F02A49E8402A1987D01948B6D01887D58016B603401 + 4541150178B08B01BEF6DC01F3FEF436B0E2C201668B6E0145411501413C0C01 + 655729016B60340172663C027A6D44037C724C02837654017C724C01887D5801 + 7A6D4401837654017C724C02887D580183765403887D580388826401887D5801 + 88826402948B6D0490866401948B6D0290866401887D58017C724C016B603401 + 584B1A015454290192C09B01F3FEF436B6F5E401F3FEF40198C9AB015F754C01 + 413C0C01584B1A01655729016B60340172663C017A6D44027C724C017A6D4401 + 7C724C02887D5801837654027A6D4401887D58027C724C01887D580183765402 + 7C724C01887D580183765401887D580183765401887D580688826401887D5801 + 7C724C0272663C016B60340165572901454115016B6034017BB79301F3FEF438 + 9CEDC9018E937301584B1A0145411501655729026B60340172663C017A6D4402 + 7C724C03837654017C724C0183765401887D580183765403887D58017A6D4401 + 887D580183765402887D580283765402887D58017C724C01887D58017C724C01 + 887D5801837654017C724C017A6D440365572902413C0C01545429017CA08001 + BCEACC01F3FEF41BB6F5E401F3FEF41BBEF6DC0178B08B015454290145411501 + 574E2401655729016B60340172663C017A6D44027C724C02837654017C724C01 + 83765401887D58017C724C01887D580183765401887D58017C724C01887D5802 + 837654067C724C01837654017C724C047A6D44017C724C017A6D44016B603401 + 65572901574E2401413C0C01454115016A8A640198C9AB01F3FEF43883B19401 + 566C4801413C0C01584B1A016557290172663C027A6D44027C724C0283765402 + 887D58017C724C0183765404887D5801837654017C724C0183765402887D5801 + 7C724C01837654017C724C01837654017C724C01887D58017C724C037A6D4402 + 72663C016B603402574E2401584B1A01413C0C015F754C0178B08B01B6F5E401 + F3FEF43792C09B01566C4801413C0C01584B1A01655729016B60340172663C01 + 7A6D44017C724C01887D580183765401887D580183765402887D580388826401 + 83765401887D580183765401887D5802837654047C724C01837654017C724C05 + 7A6D440272663C016B60340165572901574E2401584B1A01413C0C0154542901 + 7CA08001ADE2CE01A4EAD401F3FEF43698C9AB015F754C01413C0C01584B1A01 + 6557290172663C017A6D44017C724C01887D580183765401887D580288826402 + 887D580683765401887D58017C724C01887D58017C724C01887D58017C724C01 + 887D58017C724C047A6D44017C724C017A6D440272663C0265572902584B1A01 + 413C0C01545429016A8A64019AD5BA01F3FEF40DBEF6DC01B6F5E401BEF6DC01 + F3FEF42795D1AB015F754C01413C0C016557290172663C017C724C0183765401 + 887D580188826401948B6D019086640188826401948B6D0188826401948B6D02 + 887D58019086640188826401887D580283765402887D5801837654017C724C01 + 837654017C724C02837654017C724C017A6D44017C724C017A6D440172663C03 + 6B60340165572902584B1A01413C0C0147491B016496700198C9AB01F3FEF409 + B6F5E401BEF6DC01AAD5BA0178A884015F754C015858340138543301566C4801 + 7CA08001AAD5BA01BEF6DC01F3FEF423A9C3A10147491B01574E240172663C01 + 7C724C0188826401948B6D019C927402A1987D01A49E8401A1987D01A49E8401 + A1987D029C927401948B6D0288826402887D580383765401887D58017C724C04 + 7A6D44017C724C017A6D440472663C026B60340165572901584B1A02413C0C01 + 54542901789574019AD5BA01F3FEF408B6F5E40198C9AB01385433026A8A6401 + 78B08B01A9C3A10192C09B01A9A784016A8A64013854330144735801B0E2C201 + B6F5E401F3FEF41FB6F5E401F3FEF40183B194012D3E1B0150664C0190866401 + A1987D01AFA68F02BCB7A402B7B09C01BCB7A401B7B09C02AFA68F02A49E8401 + A1987D02948B6D03887D5801837654027C724C037A6D44017C724C037A6D4403 + 72663C026B60340265572901584B1A0145411501413C0C017A6D440178A88401 + A4EAD401F3FEF406B6F5E401BCEACC01637F60014060420183B19401DBFBE801 + 8FE0B70178B08B0157A074015FAB820192C09B01B0E2C201E8F8DB01788B6D01 + 1F402401A6CBAC01F3FEF42183B1940154542901948B6D01C4BFAB01D5D3C301 + DCE2C301E1E4D601DBDACE01DCE2C301E1E4D601DBDACE02CCCBBC02C9C5B401 + BCB7A401B7B09C019DA58D01A49E84019C9274018882640190866401887D5802 + 7C724C01837654017C724C017A6D44017C724C017A6D440572663C016B603402 + 65572901584B1A02413C0C0154542901668B6E0198C9AB01F3FEF406B6F5E401 + A4EAD40140604201637F6001CFEDC90192C09B01257C4C011E88540122A47102 + 16945B010F6D420144886C01A9C3A101F0FBEB01A49E8401153A1B01B0E2C201 + F3FEF42092C09B0138543301BCB7A401F0FBEB01E6EDDB01C7E4D102D4EDD902 + DBFBE801F3FEF402F0FBEB01E1EFE401DBDACE02CCCBBC01C2BAAC01AFA68F01 + A49E8401A1987D019086640188826401887D58017C724C037A6D44017C724C01 + 7A6D440372663C036B60340265572901584B1A01413C0C025F754C0178B08B01 + A4EAD401B6F5E401F3FEF405BEF6DC01637F6002DBFBE80157A074010C885301 + 23B07E0120BC920120B7800123B07E0116945B010F6D4201488A5C017BB79301 + D4EDD901C9C5B40150664C0178957401B6F5E401F3FEF41FB0E2C2012E492A01 + BCB7A401D4EDD9017BB7930178A884015FAB820161B88F017BB793017AC6A401 + 95D1AB01AAD5BA01C7E4D101D4EDD901F3FEF401F0FBEB01E1E4D601D5D3C301 + C9C5B401B7B09C01AFA68F019C92740190866401887D5801837654017C724C01 + 7A6D44057C724C0172663C017A6D440172663C016B603402574E2401584B1A01 + 413C0C0154542901789574019AD5BA01F3FEF40792C2A5013E563C01CFEDC901 + 78B08B010B7D4A0123B07E0120B7800110A974010B9664010B7D4A0246986E01 + 7BB79301AAD5BA01F3FEF401C4BFAB017C724C0140604201BEF6DC01F3FEF420 + 44735801788B6D01E8F8DB0157A074010F6D4201087442021881560122895F01 + 499F73015BA47F017BB7930198C9AB01B4DAC401C7E4D101F0FBEB01F3FEF401 + E1E4D601CCCBBC01BCB7A401AFA68F019C92740190866401887D580183765401 + 7C724C037A6D44017C724C027A6D44017C724C0172663C026B60340165572901 + 47491B01413C0C015F754C0192C2A501BEF6DC01F3FEF406BEF6DC01566C5401 + 8E937301B0E2C201338055011E8854010C885302087442011E885401499F7301 + 78B08B0198C9AB01C7E4D101F3FEF401D5D3C301A49E84016B60340154542901 + 9AD5BA01F3FEF4209AD5BA012E492A01C6CCAA0180BF9B0112734C0122A47101 + 23B07E0110A974010B9664010B7D4A021E885401499F73015FAB820180BF9B01 + AAD5BA01BCEACC01F3FEF401E6EDDB01D5D3C301BCB7A401AFA68F019C927401 + 887D580183765401887D5801837654017C724C01837654067C724C017A6D4401 + 6B603401584B1A01413C0C01649670019CEDC901F3FEF407B3ECD5012D3E1B01 + C6CCAA01A9C3A10133885A01257C4C011E885401369363015BA47F0180BF9B01 + A6CBAC01C7E4D101DBFBE801EDF0E501CCCBBC01AFA68F019086640165572901 + 444D280192C2A501F3FEF4217EAA8E013F6A4901D2FADA0146986E0120A98001 + 2ED3A40124E1B70115D5AC0112C395010BB182010B9664010B7D4A02499F7301 + 5FAB820192C09B01BFD8B901DBFBE801F0FBEB01DBDACE01BCB7A401A49E8401 + 948B6D018882640190866405948B6D029C927401948B6D019086640183765401 + 72663C01574E240147491B0192C2A501F3FEF4089AD5BA013E4C3601DCE2C301 + B1CCB9017CA0800183B194017BB7930198C9AB01C1DCCC01E1EFE401F0FBEB01 + DBFBE801DBDACE01C2BAAC019DA58D01948B6D017A6D4401574E2401413C0C01 + 6A8A6401B0E2C201F3FEF42178957401566C5401DBFBE8013693630123B07E01 + 40EEC8012BF9D20228ECC10115D5AC010BB1820109A06D010B7D4A0246986E01 + 61B88F01A6CBAC01C7E4D101F3FEF401DBDACE01C2BAAC01A49E84019C927401 + A49E8404B7B09C01AFA68F01B7B09C02ACAE8A01A9A78401A1987D01887D5801 + 444D2801637F6001BCFAD301F3FEF408AAD5BA01444D2801C6CCAA01E8F8DB01 + BEE1C301D4EDD901E8F8DB01F3FEF401EDF0E501DCE2C301D5D3C301C4BFAB01 + B7B09C01A49E84019C927401887D580172663C01655729014541150154542901 + 7CA08001AAD5BA01F3FEF401B6F5E401F3FEF41F7EAA8E0140604201B0E2C201 + 63AD8C0106976D012BE3C40140EEC8011DEDD0012BF9D20128ECC1011CD5A201 + 20B780010B9664010874420133885A0157A0740192C2A501C1DCCC01F3FEF401 + DBDACE01C4BFAB01AFA68F01C2BAAC01C4BFAB01C2BAAC01C9C5B401CCCBBC01 + D5D3C301DBDACE01D5D3C302C9C5B401A9A784017C724C01293916019AD5BA01 + F3FEF409A4EAD4012E492A01A1987D01BFD8B901E1E4D601DBDACE01D5D3C301 + C9C5B401C4BFAB01BCB7A401AFA68F01A49E84019C927401948B6D01887D5801 + 7C724C0172663C0165572901574E24014541150147491B01637F600192C09B01 + F3FEF420BEF6DC0183B1940147491B0178B08B01BCEACC0122895F011EAC8E01 + 40EEC8013FF9D2012BF9D20128ECC10124E1B70112C3950110A974010C885301 + 257C4C0157A0740196B99E01C1DCCC01F3FEF401DBDACE01C4BFAB01DCE2C301 + D5D3C301E1E4D602EDF0E502F0FBEB01EDF0E501DBDACE01BCB7A401637F6001 + 2939160198C9AB01F3FEF40ABEF6DC01444D28017A6D44018E937301A49E8403 + A1987D02948B6D029086640188826401837654017C724C017A6D440172663C01 + 6B60340165572901574E240245411501444D28017BB79301F3FEF401B6F5E401 + F3FEF419B6F5E401F3FEF401B6F5E401B0E2C20192C2A5017CA0800150614101 + 574E2401788B6D01ADE2CE017CD6B4011488740106976D0110B58C0116C7A401 + 2BCCA80112C3950123B07E0133885A0112734C01488A5C0183B19401DCE2C301 + F3FEF401DBDACE01CCCBBC01B7B09C01BCB7A401CCCBBC01DCE2C301E1E4D602 + DBDACE01C4BFAB01A1987D01506141013E563C01B0E2C201F3FEF40C78957401 + 47491B016B6034017A6D4401887D580488826401887D580183765401887D5801 + 7C724C027A6D440372663C027A6D440172663C0151583F0129391601C7E4D101 + F3FEF419BCFAD301A6CBAC016A8A6401293916013E4C3601566C4801637F6001 + 8E93730179977E017CA08001ABB09401A8C5AC01C7E4D101DCFEF401B0E2C201 + 85B79D015BA47F0146986E01649670015BA47F0192C09B01BEE1C301F0FBEB01 + DBDACE01ABB09401A1987D019C9274012D3E1B013E4C360151583F01566C5402 + 50664C0151583F012D3E1B01566C480195D1AB01D2FADA01F3FEF40D92C09B01 + 47491B0145411501655729016B60340172663C017A6D44017C724C067A6D4401 + 7C724C017A6D440183765402887D5801948B6D019C9274018E93730150614101 + 7BB79301F3FEF414B6F5E401F3FEF402B3ECD50178B08B011F40240140604201 + 78957401AAD5BA01DBFBE801B0E2C2017AC6A4017BB7930292C2A501B0E2C201 + DBFBE801C7E4D101B7B09C018E9373016A8A64018E9373017CA080027EAA8E01 + 668B6E015774560151583F012D3D2501444D2801566C480150664C01BEF6DC01 + A4EAD4019AD5BA018CCAB8019DCCB40198C9AB01ADE2CE01B6F5E401F3FEF410 + 95D1AB015F754C01413C0C01584B1A016557290272663C017A6D44017C724C01 + 7A6D44017C724C017A6D44017C724C017A6D44017C724C0183765401887D5801 + 88826401A1987D01B7B09C01C9C5B401C4BFAB0190866401637F6001F3FEF415 + BEF6DC0183B19401293916015774560192C2A501BAFEEF0158BC9C0111795601 + 06976D011EAC8E0116C7A4012BCCA80112BD920122A471010B7D4A0133885A01 + 92C09B01F0FBEB01ABB0940158583401566C480178A8840178B08B0183B19401 + 8CCAB8019AD5BA01A4EAD401B6F5E401F3FEF41B98C9AB01637F6001413C0C01 + 584B1A026B60340272663C017A6D44037C724C017A6D44017C724C0183765401 + 887D580188826401A49E8401B7B09C01D5D3C301EDF0E501E6EDDB018C987E01 + 50664C01F3FEF413BEF6DC019DCCB401385433014473580192C09B01A4EAD401 + 44886C011E8F760130D6BA0148EDD4012BE3C4011DEDD0022BF9D20128ECC101 + 14CB9A0122A471010874420142916E01A8C5AC01E8F8DB01948B6D0129391601 + BEE1C301F3FEF42198C9AB015F754C01413C0C02655729026B60340172663C03 + 7A6D44027C724C0283765401948B6D019C927401B7B09C01D5D3C301F0FBEB01 + EDF0E501F3FEF401A9A7840157745601BEF6DC01F3FEF411BCEACC017CA08001 + 2E492A0183B19401BCFAD301249E840247EFDC012CD4D1010ACACA020DD7D001 + 12E2D0012BF9D2012BE3C40114CB9A0110A974010B7D4A011881560178A88401 + AAD5BA01F0FBEB01A9A784015454290164967001DBFBE801F3FEF409B6F5E401 + F3FEF41680BF9B015F754C01413C0C01584B1A02655729016B60340272663C01 + 7A6D440172663C017A6D440283765401887D58019C927401AFA68F01CCCBBC01 + E1EFE402D5D3C301DBFBE801788B6D017CA08001F3FEF40EBEF6DC01F3FEF401 + B6F5E40198C9AB011F40240157745601BCEACC0180BF9B010F82640150DCD001 + 2CD4D1010ACACA0107BFCB0111CBD7011CD8DC012BEEDF011DEDD00115D5AC01 + 0BB18201088C5D010874420146986E017BB79301AAD5BA01F0FBEB01CCCBBC01 + 8E9373016B60340150614101A6CBAC01F3FEF401B6F5E401F3FEF404BEF6DC01 + F3FEF4017BB79301BCEACC01F3FEF41692C09B015F754C01413C0C01584B1A01 + 655729026B60340272663C027A6D44038376540190866401A1987D01BCB7A401 + DBDACE01F0FBEB01C0D8C401AFC6B701F0FBEB0150664C01AAD5BA01F3FEF40F + BCEACC0179977E012E492A0183B19401BEF6DC011488740124B5920152E1E001 + 0ACACA0107BFCB010ACACA010DD7D00124E4DE012BF9D20115D5AC010BB18201 + 0B9664010874420122895F015FAB820198C9AB01BCEACC01F0FBEB01D5D3C301 + AFA68F018882640154542901413C0C016A8A640192C09B0195D1AB01BEE1C301 + A6CBAC017CA08001637F6001577456018C987E015F754C01153A1B0196B99E01 + F3FEF414BEF6DC019AD5BA01637F6001413C0C02574E2401655729026B603402 + 72663C027A6D44017C724C01887D580190866401AFA68F01C9C5B401F0FBEB01 + C7E4D101AFC6B701D5D3C301AFC6B70129391601F3FEF40EB3ECD50183B19401 + 153A1B0157745601B0E2C2017AC6A4011179560144DABF0112E2D0010ACACA01 + 11CBD70224E4DE012BEEDF011AD8B60110B58C0106976D010874420122895F01 + 57A0740180BF9B01BFD8B901DBFBE801EDF0E501CCCBBC01ABB09401948B6D01 + 7A6D440165572901413C0C01584B1A015F754C016A8A6401566C480129391601 + 385433018376540190866401637F6001F0FBEB01A6CBAC01406042017CA08001 + F3FEF4149AD5BA01649670015454290145411501584B1A02655729016B603403 + 72663C027C724C01837654019C927401B7B09C01DBDACE01F0FBEB01CCCBBC01 + B1CCB901F3FEF401637F600185B79D01B6F5E401F3FEF40BBEE1C30196B99E01 + 2D3E1B0150664C017BB79301BCFAD301249772011EAC8E012BEEDF010DD7D001 + 0ACACA010DD7D00112E2D00129F7DE011AD8B60112C3950109A06D010B7D4A01 + 0C885301499F730178B08B019DCCB401D4EDD901F3FEF401E1E4D601C9C5B401 + AFA68F019C9274017C724C0172663C0165572901584B1A01413C0C0345411501 + 6B603401948B6D01A8C5AC01F0FBEB01F3FEF40146986E017BB79301E8F8DB01 + 3F6A49017CA08001F3FEF413A4EAD4017BB793015F754C0145411501413C0C01 + 584B1A02655729026B60340272663C017A6D4401887D5801A49E8401BCB7A401 + E6EDDB01EDF0E501C1DCCC01D4EDD901ABB094012E492A01F3FEF40ABEF6DC01 + AAD5BA0178957401153A1B01566C480178B08B01DBFBE80161B88F0111795601 + 2BCCA8011DEDD00112E2D0010DD7D00112E2D00129F7DE012BE3C40114CB9A01 + 10A974010C8853010B7D4A0146986E015FAB820192C2A501C1DCCC01F0FBEB02 + D5D3C301C2BAAC01A9A78401948B6D01887D58017A6D440172663C0165572901 + 574E2401584B1A02574E2401655729017C724C01A49E8401DBDACE01C7E4D101 + 96B99E0108744201257C4C0136936301DBFBE80150664C0196B99E01F3FEF413 + 9AD5BA017CA08001566C4801413C0C014541150147491B01584B1A0165572901 + 584B1A01655729016B60340172663C01887D5801A1987D01C9C5B401EDF0E501 + F0FBEB02C4BFAB012E492A01B0E2C201F3FEF406BEF6DC02AAD5BA017CA08001 + 2E492A01385433016A8A6401A6CBAC01BAFEEF0180BF9B010B7D4A0110B58C01 + 1DEDD00429F7DE011DEDD00112C395010BB18201088C5D010B7D4A0122895F01 + 5FAB820185B79D01B4DAC401E1EFE401F3FEF401E1E4D601CCCBBC01BCB7A401 + A49E84019C92740188826401837654017A6D440172663C016B60340165572904 + 72663C01887D5801B7B09C01E6EDDB01BFD8B9015BA47F010874420123B07E01 + 20A9800122895F01BCFAD3012E492A0194E6C401B6F5E401F3FEF4129AD5BA01 + 7CA080015F754C0147491B01413C0C0145411501413C0C01584B1A01574E2401 + 655729016B603401887D5801A1987D01C4BFAB01DBDACE01E1E4D601ABB09401 + 304B340198C9AB01F3FEF401B6F5E401F3FEF401BEF6DC01F3FEF401BEF6DC01 + 9AD5BA017CA080012E492A0138543301637F600192C09B01D2FADA019AD5BA01 + 499F73010F6D420120A9800124E1B7012BF9D20329F7DE0128ECC10114CB9A01 + 0BB18201088C5D010874420122895F01499F730185B79D019DCCB401D4EDD901 + F0FBEB01EDF0E501DBDACE01C4BFAB01ABB09401A1987D01948B6D0188826401 + 837654017C724C017A6D440172663C026B60340372663C017A6D440190866401 + AFA68F01E1E4D601C7E4D1017CA080010B7D4A0120B7800129DCAC0120BC9201 + 499F730198C9AB012E492A01BEF6DC01F3FEF4139AD5BA017EAA8E01788B6D01 + 72663C015454290145411501413C0C0247491B01655729017A6D4401948B6D01 + A9A78401ACAE8A01888264012D3E1B0198C9AB01F3FEF404BCEACC0196B99E01 + 506141012E492A01637F600196B99E01DBFBE80194E6C4015FAB820111795601 + 0B96640112BD920124E1B70128ECC1012BF9D20128ECC1021AD8B60112C39501 + 0AA67D01088C5D010874420122895F01499F730183B194019DCCB401C7E4D101 + F0FBEB01F3FEF401E1E4D601CCCBBC01BCB7A401AFA68F01A49E8401948B6D01 + 887D5801888264017C724C027A6D440272663C0583765401948B6D01AFA68F01 + E1E4D601D4EDD9017EAA8E010C88530109A06D0124E1B7013FF9D20124B59201 + 7AC6A401668B6E0178B08B01F3FEF4149CEDC90198C9AB017BB793017CA08001 + 6A8A64015F754C01506141014541150254542901506141022E492A01637F6001 + BCEACC01DBFBE801F3FEF401B6F5E401A4EAD4017BB793011F402401566C4801 + A9A78401BCFAD301B0E2C2015FAB8201257C4C01088C5D0123B07E012ED3A401 + 29DCAC0124E1B70315D5AC0112C395010BB1820106976D010C88530108744201 + 22895F01499F73017BB7930198C9AB01ADE2CE01EDF0E501F3FEF401E1E4D601 + D5D3C301C2BAAC01ABB09401A49E84019C9274019086640188826401887D5801 + 7C724C037A6D44067C724C0183765401948B6D01AFA68F01D5D3C301DBFBE801 + A8C5AC0122A471010B7D4A0116C7A4012BF9D2013FF9D201088C5D01DBFBE801 + 304B3401ADE2CE01F3FEF415B6F5E40194E6C4019AD5BA0198C9AB017BB79301 + 7CA080016A8A64015F754C01637F60017EAA8E01B0E2C201F3FEF403BEF6DC01 + A9C3A101444D280150664C0196B99E01DBFBE8017AC6A40133885A01088C5D01 + 23B07E0114CB9A012ED3A4011CD5A20129DCAC011CD5A20114CB9A0120B78001 + 10A9740109A06D010C885301087442010C885301369363015BA47F017BB79301 + 9DCCB401C1DCCC01E1EFE401F3FEF401EDF0E501D5D3C301C9C5B401BCB7A401 + AFA68F01A1987D01948B6D0190866402837654037C724C037A6D44017C724C01 + 7A6D44017C724C017A6D44017C724C01887D5801948B6D01A49E8401CCCBBC01 + F3FEF401B1CCB90161B88F01087442010BB1820128ECC1011DEDD0012BE3C401 + 42916E0180BF9B0144735801F3FEF422B3ECD5016A8A64013854330178A88401 + F0FBEB0180BF9B01257C4C010B96640120B780012BCA99011CD5A20114CB9A01 + 12C3950110B58C010BB182010B966401088C5D010B7D4A01087442010C885301 + 36936301499F730178B08B0192C2A5019DCCB401C7E4D101E1EFE401F3FEF401 + EDF0E501DBDACE01C9C5B401C2BAAC01AFA68F01A49E84019C927401948B6D01 + 90866401887D58027C724C03837654017C724C057A6D44017C724C0183765401 + 887D5801948B6D01A49E8401C4BFAB01E1EFE401E1E4D60195D1AB0124977201 + 088C5D011CD5A2012BF9D2011DEDD00124B5920194E6C4013F6A49019AD5BA01 + B6F5E401F3FEF41F92C2A5012D3E1B01637F6001BEE1C30195D1AB0133885A01 + 0C88530123B07E012BCA990112C3950120B780020B96640116945B010B7D4A01 + 087442010C8853013C8D6401499F73015BA47F017BB7930192C2A5019DCCB401 + C1DCCC01C7E4D101F3FEF401F0FBEB01E1EFE401D5D3C301C4BFAB01BCB7A401 + AFA68F01A49E84019C927401948B6D0190866401887D580188826401887D5801 + 7C724C01887D58027A6D4401837654017C724C0183765401887D58017A6D4401 + 83765401887D58017C724C01887D5802948B6D01A49E8401BCB7A401DBDACE01 + EDF0E501B0E2C20163AD8C01087442010BB182011DEDD0022BF9D20111795601 + 9AD5BA0138543301F3FEF41EBEF6DC017EAA8E0147491B017CA08001DBFBE801 + 78A884010F6D420122A4710120B7800209A06D010B9664010B7D4A0108744201 + 1881560146986E01499F73015FAB82017BB7930192C2A5019DCCB401B4DAC401 + C7E4D101D4EDD901F3FEF402E1EFE401DBDACE01D5D3C301C4BFAB01BCB7A401 + B7B09C01A49E8401A1987D019C927401948B6D019086640188826401887D5801 + 83765403887D58017C724C01887D5802837654027A6D4401887D58017C724C03 + 83765401887D5801888264019C927401B7B09C01D5D3C301F3FEF401D4EDD901 + 92C2A501369363010C88530112C3950129F7DE011DEDD00120BC92018FE0B701 + 5F754C0198C9AB01F3FEF41CBCEACC01637F60014060420192C09B01CFEDC901 + 46986E010B7D4A0122A471020B9664010C8853010874420122895F0146986E01 + 5FAB820185B79D0198C9AB019DCCB401C1DCCC01C7E4D101DBFBE801F3FEF402 + E1EFE401EDF0E501DBDACE01D5D3C301CCCBBC01C2BAAC01BCB7A401AFA68F01 + A49E84019C927402948B6D02887D5805837654027C724C01887D580183765402 + 887D58017C724C01887D580183765401887D580183765401887D580390866401 + 9C927401AFA68F01C4BFAB01EDF0E501F3FEF401B4DAC40161B88F010B7D4A01 + 10A9740124E1B7012BF9D20128ECC10112734C01B0E2C2011F402401BEF6DC01 + F3FEF419BEF6DC01A6CBAC011F4024015F754C01CFEDC90195D1AB0133805501 + 1E88540116945B020B7D4A02369363015FAB820180BF9B019AD5BA01B4DAC401 + D4EDD901F0FBEB01F3FEF401F0FBEB01E1EFE401DBDACE02D5D3C301C9C5B401 + C2BAAC02B7B09C01AFA68F02A49E84019C92740390866402887D580283765401 + 887D580183765402887D580183765402887D58017C724C0183765402887D5801 + 7C724C0183765404887D5802948B6D02A9A78401BCB7A401DBDACE01E1EFE402 + 98C9AB0146986E01087442010BB1820128ECC10140EEC80123B07E017CD6B401 + 5774560192C2A501B6F5E401F3FEF417BEF6DC017CA080012E492A017CA08001 + F0FBEB0178B08B01087442011E88540116945B01087442010B7D4A0136936301 + 83B1940195D1AB01C1DCCC01D4EDD901F3FEF401F0FBEB01E1E4D601DBDACE01 + CCCBBC02C4BFAB02B7B09C039DA58D01AFA68F01A49E8401A1987D029C927401 + 948B6D02888264019086640188826401887D580188826401887D580483765403 + 887D580383765402887D580283765401887D580183765401887D5803948B6D01 + A1987D01AFA68F01CCCBBC01E1E4D601F3FEF401C1DCCC0183B1940136936301 + 0C88530112C3950128ECC1012ED3A40122895F01B0E2C201153A1B01BEF6DC01 + F3FEF414BEF6DC01F3FEF401ADE2CE01406042013F6A4901A6CBAC01BEE1C301 + 46986E01257C4C0116945B02087442013693630178A8840195D1AB01BCEACC01 + F0FBEB01EDF0E501E1E4D601D5D3C301C4BFAB01BCB7A402AFA68F02A49E8402 + A1987D01A49E8401A1987D029C927403948B6D0488826401887D580188826401 + 887D580283765402887D580283765402887D580283765402887D580383765401 + 887D580383765401887D580188826401908664019C927401AFA68F01BCB7A401 + C9C5B401E1E4D601DBFBE801AAD5BA0163AD8C0118815601088C5D0112C39501 + 2ED3A40116945B0195D1AB016A8A640164967001F3FEF41592C2A50129391601 + 6A8A6401D2FADA0180BF9B01087442010B96640110A974010C88530108744201 + 369363017BB79301BEE1C301DBFBE801EDF0E501DBDACE01C9C5B401BCB7A401 + AFA68F01A9A78401A1987D019C927403948B6D019C927401948B6D049C927402 + 948B6D0488826401948B6D019086640188826401887D58018882640183765401 + 887D58028376540188826401887D580583765401887D580183765401887D5802 + 8376540288826401887D5802948B6D02A1987D01B7B09C01BCB7A401CCCBBC01 + F0FBEB01D4EDD9019AD5BA015BA47F011881560116945B0120B7800122A47101 + 36936301D2FADA014060420196B99E01F3FEF412B6F5E40183B194012E492A01 + 7EAA8E01BEF6DC0142916E010B96640120B7800216945B010B7D4A01499F7301 + 92C09B01B3ECD501F0FBEB01DBDACE01C2BAAC01AFA68F01A9A784019C927402 + 90866401948B6D0190866406948B6D01908664019C927401948B6D029C927401 + 948B6D019C92740290866401948B6D019086640188826401887D580188826401 + 887D580183765401887D580283765401887D580183765401887D580183765401 + 887D5805837654018882640183765401887D58028882640190866401948B6D01 + 9C927401A49E8401AFA68F01C2BAAC01DBDACE01EDF0E501E1EFE40195D1AB01 + 5BA47F01257C4C010C88530116945B010F6D420192C09B01C6CCAA012E492A01 + 7CA08001BCEACC01B6F5E401F3FEF40EBEF6DC017CA080013E563C01A6CBAC01 + 95D1AB010B7D4A010BB182012BCA990112C3950109A06D010874420136936301 + 7AC6A401D4EDD901E1EFE401D5D3C301B7B09C01AFA68F019C927401948B6D01 + 9086640188826401887D580488826401887D58018882640190866402948B6D01 + 9C927403A1987D039C927401A1987D019C92740190866401948B6D0190866401 + 887D58028882640183765401887D580283765401887D580483765401887D5802 + 83765401887D580488826401887D580290866401948B6D01A1987D01A49E8401 + AFA68F01C4BFAB01DBDACE01E1EFE4029DCCB4015FAB82013693630108744201 + 12734C013C8D6401BEE1C301C6CCAA01566C540129391601789574019DCCB401 + ADE2CE01BEF6DC01F3FEF401BEF6DC01F3FEF401B6F5E401F3FEF401B6F5E401 + F3FEF401B6F5E401F3FEF401B6F5E401A4EAD401637F600140604201B0E2C201 + 61B88F010F8264011CD5A20124E1B70129DCAC010BB182010B7D4A0136936301 + 80BF9B01D4EDD901EDF0E501CCCBBC01B7B09C019C927401948B6D0190866401 + 887D580183765402887D58017C724C0183765401887D58028882640190866402 + 948B6D029C927401A49E8402AFA68F04A49E84029C927401948B6D0290866401 + 88826401887D580183765401887D580583765401887D580383765401887D5801 + 88826401887D580188826401887D580390866402948B6D029C927401A1987D01 + AFA68F01C2BAAC01DBDACE01E6EDDB01DBFBE801B4DAC40185B79D01499F7301 + 3C8D64013693630178A88401B4DAC401D4EDD90196B99E01788B6D0150664C01 + 2E492A012939160150664C017CA0800192C09B01B0E2C201BCFAD301F3FEF403 + BCFAD301AAD5BA014060420157745601D2FADA015FAB82010AA67D012BE3C401 + 2BF9D20128ECC10112C39501088C5D010C88530178B08B01ADE2CE01F0FBEB01 + CCCBBC01B7B09C01A1987D01948B6D01887D5801837654037C724C0183765401 + 887D580283765401887D580290866401948B6D019C927401A1987D01A49E8401 + AFA68F01B7B09C01BCB7A401C2BAAC02BCB7A402B7B09C01AFA68F01A49E8401 + 9C927401948B6D02887D5803837654027C724C01837654028882640183765401 + 887D580583765401888264018376540188826402887D580190866401948B6D02 + 9C927401A49E8401AFA68F01BCB7A401CCCBBC01E1E4D601F3FEF401E1EFE401 + AAD5BA0185B79D0183B1940178A884017EAA8E01A8C5AC01C0D8C401E6EDDB01 + F0FBEB01DCE2C301C6CCAA01ACAE8A016A8A640144735801444D2801153A1B01 + 3F6A490168967C017CA08001577456012E492A0164967001DBFBE8011E8F7601 + 24B5920129F7DE012BF9D20215D5AC0109A06D010B7D4A015FAB82019AD5BA01 + F3FEF401DBDACE01B7B09C01A1987D01948B6D01887D58027C724C0183765401 + 7C724C01837654027C724C01887D58028882640190866401888264019C927401 + A1987D01AFA68F01BCB7A401C2BAAC01CCCBBC01D5D3C301DBDACE03D5D3C301 + CCCBBC01C2BAAC01B7B09C01AFA68F01A1987D01948B6D0288826401887D5802 + 83765402887D580183765403887D5803888264018376540188826401887D5801 + 88826401887D580290866404948B6D02A1987D01A49E8401B7B09C01C2BAAC01 + D5D3C301D4EDD901F3FEF401E1EFE401B4DAC401AFC6B70192C2A50183B19401 + 85B79D0183B1940178B08B017BB7930295D1AB01BFD8B901D2FADA02BFD8B901 + 78A8840178957401668B6E0178A88401B0E2C2018FE0B701117956012CCAB401 + 1DEDD00112E2D0011DEDD00124E1B7010BB182010874420146986E0192C2A501 + E1EFE401E1E4D601C9C5B401AFA68F019C92740188826401887D58017C724C02 + 837654017C724C0183765402887D580183765401887D58018882640190866401 + 9C927401A1987D01AFA68F01BCB7A401C9C5B401D5D3C301E1E4D601EDF0E501 + F3FEF403F0FBEB01E1EFE401DBDACE01CCCBBC01C2BAAC01AFA68F01A1987D01 + 9C9274019086640188826401887D580283765404887D58018882640183765402 + 887D580288826401887D580388826401887D58029086640188826402948B6D02 + 9C927401A49E8402B7B09C01C2BAAC01CCCBBC01E1E4D601F0FBEB02D4EDD901 + B4DAC40192C2A50183B1940178A8840164967001488A5C0233805502488A5C01 + 57A0740178B08B0180BF9B017AC6A4017BB793010F826401249E840140EEC801 + 12E2D0010DD7D0011DEDD00212C395010C88530122895F017BB79301C1DCCC01 + F3FEF401D5D3C301B7B09C01A1987D0190866401887D5801837654017C724C01 + 837654017C724C01887D580283765402887D58018882640190866401948B6D01 + A1987D01A49E8401B7B09C01CCCBBC01E1E4D601F0FBEB02D4EDD901C1DCCC01 + B4DAC402BCEACC01E1EFE401F3FEF401E1EFE401DBDACE01C9C5B401B7B09C01 + A49E84019C927401948B6D01887D580383765405887D580183765401887D5802 + 83765401887D580188826401887D580188826403887D580190866401948B6D01 + 88826401948B6D03A1987D02AFA68F01B7B09C01BCB7A401AFC6B701D5D3C301 + EDF0E501F3FEF401E1EFE401B4DAC4019DCCB40178B08B0157A074013C8D6401 + 257C4C01087442010B7D4A011E88540109A06D0122A471010BB1820116C7A401 + 28E2CF020DD7D00212E2D0012BF9D20116C7A4010B9664010B7D4A015FAB8201 + 9DCCB401DBFBE801DBDACE01C4BFAB01AFA68F01948B6D0190866401887D5801 + 83765401887D580183765401887D580183765401887D58018376540188826401 + 887D580190866401948B6D019C927401A49E8401B7B09C01CCCBBC01DBDACE01 + F3FEF401D4EDD901AAD5BA0192C2A50161B88F015FAB820178B08B0180BF9B01 + 92C09B01AAD5BA01E1EFE401F3FEF401E1E4D601CCCBBC01BCB7A401A49E8401 + 8E937301948B6D01887D58018882640183765405887D580288826401887D5805 + 88826401887D580188826401908664028882640190866401948B6D0188826401 + 948B6D029C927402A1987D01A49E8401AFA68F01BCB7A401C2BAAC01D5D3C301 + E1E4D601F3FEF401EDF0E501ADE2CE0198C9AB017BB7930157A0740133885A01 + 087442010C88530109A06D0120B7800129DCAC012BF9D2011DEDD00112E2D002 + 1DEDD0012BEEDF0112C3950109A06D010B7D4A0146986E0192C2A501D4EDD901 + F0FBEB01D5D3C301B7B09C01A1987D01948B6D01887D580283765403887D5805 + 88826402948B6D01A1987D01AFA68F01C2BAAC01DBDACE01F0FBEB01D4EDD901 + 9DCCB4015FAB82011E8F760111795601087442010F6D42010B7D4A0124977201 + 5BA47F017AC6A401B4DAC401DBFBE801E1EFE401D5D3C301BCB7A4019DA58D01 + 9C927401948B6D018882640283765401887D580383765401887D580388826402 + 948B6D0188826401948B6D018882640190866401948B6D069C927401948B6D02 + 9C927401908664019C927402A1987D01A49E8401B7B09C01C2BAAC01CCCBBC01 + E1E4D601EDF0E501F0FBEB01C7E4D1019DCCB40185B79D0157A0740136936301 + 08744201088C5D0120B780011CD5A20128ECC1011DEDD00224E1B70112C39501 + 0B966401087442013693630180BF9B01B4DAC401F3FEF401DBDACE01C2BAAC01 + AFA68F019C9274019086640283765401887D580283765401887D580183765401 + 887D580390866401948B6D019C927401A49E8401B7B09C01C9C5B401EDF0E501 + E1EFE4019DCCB4015FAB82010B7D4A01088C5D0110B58C0128C4A40127BAA701 + 1EAC8E010B96640112734C013693630163AD8C019DCCB401D4EDD901F0FBEB01 + DBDACE01C4BFAB01B7B09C01A1987D01948B6D0288826403887D580188826403 + 90866401948B6D0188826401948B6D0188826401948B6D04A49E8403A1987D04 + 8E937301948B6D0388826401948B6D019C927401A1987D01A49E8401AFA68F01 + BCB7A401C9C5B401E1E4D601E1EFE401F3FEF401D4EDD901AAD5BA0180BF9B01 + 5FAB820122895F010F6D4201088C5D010AA67D010BB1820209A06D01088C5D01 + 0B7D4A0146986E0183B19401AAD5BA01EDF0E501E6EDDB01CCCBBC01B7B09C01 + A1987D019C92740190866401887D580788826401887D58018882640190866402 + A1987D01A49E8401C2BAAC01D5D3C301F0FBEB01C7E4D10185B79D0122895F01 + 06976D0130D6BA0138E2DC0111CBD70138CEDC012BEEDF0124E1B7010BB18201 + 0C885301257C4C0157A0740192C09B01C7E4D101F0FBEB01E1E4D601CCCBBC01 + BCB7A4019DA58D01A1987D019C927401948B6D079C927403A1987D018C987E01 + A1987D018C987E01A1987D01B7B09C05AFA68F019DA58D01AFA68F01A1987D02 + 948B6D0388826402948B6D019C927401A49E8401AFA68F01BCB7A401C4BFAB01 + D5D3C301E6EDDB01F3FEF401E1EFE401B4DAC40192C2A50163AD8C0142916E01 + 188156010B7D4A0322895F015BA47F017BB7930194D6C401E1EFE401EDF0E501 + DBDACE01C2BAAC01AFA68F01A1987D018882640190866401887D580588826401 + 887D58039086640188826401948B6D01A1987D01ABB09401C4BFAB01E1E4D601 + F3FEF401AAD5BA015BA47F010874420124B592013CDAE4010797C7010574BB02 + 049FC4011CD8DC012EEDD10112C395010B96640108744201369363017BB79301 + AAD5BA01DBFBE801EDF0E501DBDACE01C9C5B401B7B09C01AFA68F02A49E8404 + 9DA58D01A49E84019DA58D01AFA68F02B7B09C01AFA68F01B7B09C03DBDACE01 + D5D3C301DBDACE01D5D3C302CCCBBC01C9C5B401C4BFAB01B7B09C01AFA68F01 + A49E84019C927401948B6D0188826401948B6D01888264019086640188826401 + 9C927401A1987D01AFA68F01B7B09C01C2BAAC01D5D3C301E1E4D601F0FBEB01 + DBFBE801BCEACC01A6CBAC0180BF9B0161B88F0163AD8C017BB7930185B79D01 + 98C9AB01C1DCCC01EDF0E501F0FBEB01E1E4D601C4BFAB01B7B09C01A49E8401 + 9C927401948B6D0190866401887D580190866401887D580590866401887D5801 + 90866401948B6D019C927401A49E8401AFA68F01C9C5B401EDF0E501E1EFE401 + 95D1AB0146986E010C88530130D6BA0113BDD7010574BB010442A702049AB401 + 3CDAE40150DCD0012ED3A40123B07E0116945B010874420133885A0178A88401 + A8C5AC01C7E4D101F0FBEB01EDF0E501E1E4D601CCCBBC01C9C5B402C2BAAC02 + C4BFAB04C9C5B401CCCBBC03D5D3C303F0FBEB01F3FEF401DBFBE801F3FEF403 + E1EFE401E1E4D601D5D3C301C4BFAB01B7B09C01A49E8401A1987D0190866401 + 948B6D01887D580188826402908664029C927402A49E8401ABB09401BCB7A401 + CCCBBC01DCE2C301EDF0E501F3FEF401E1EFE401C7E4D101C1DCCC02C7E4D101 + E1EFE401F3FEF401EDF0E501DBDACE01C9C5B401B7B09C01AFA68F01A1987D01 + 948B6D0188826401948B6D01908664018882640190866401887D580188826402 + 887D580188826401887D580190866401948B6D02A49E8401B7B09C01CCCBBC01 + E1E4D601EDF0E5018CCAB80146986E01088C5D0130D6BA0113BDD7010574BB01 + 0442A7010574BB0144BCC4011179560122895F01117956010F6D42023F6A4901 + 3380550142916E0178B08B0192C2A501B4DAC401D4EDD901DCFEF401F3FEF401 + EDF0E502E1EFE402E1E4D601E1EFE401EDF0E501F0FBEB03F3FEF40598C9AB01 + A8C5AC0192C2A50198C9AB01B1CCB901BFD8B901C7E4D101D4EDD901F3FEF401 + E6EDDB01D5D3C301C4BFAB01AFA68F01A49E8401948B6D0190866401887D5801 + 8882640183765401887D58018882640190866401948B6D019C927401A49E8401 + ABB09401B7B09C01C9C5B401DBDACE01E1E4D601EDF0E501F0FBEB03EDF0E501 + E1E4D601DBDACE01C9C5B401BCB7A401AFA68F01A1987D019C927401948B6D02 + 90866403887D580188826401887D580190866401887D580190866401887D5801 + 908664029C927401A49E8401AFA68F01CCCBBC01E1EFE4029DCCB40146986E01 + 0C8853012CCAB40138CEDC01049AB4010574BB015CD2FC017CCAC40180BF9B01 + 78B08B0195D1AB01D2FADA01BCFAD3018FE0B7017AC6A40180BF9B0192C09B02 + AFC6B701B1CCB901D5D3C301C7E4D101C1DCCC01E1EFE401E1E4D601C7E4D101 + E1EFE401DBDACE01C7E4D102C1DCCC01C0D8C403AAD5BA01B1CCB90257A07402 + 46986E016496700146986E0157A0740178B08B0192C09B01AAD5BA01E6EDDB01 + F0FBEB01DBDACE01C4BFAB01AFA68F019C927401948B6D01887D580183765401 + 887D580183765402887D5802908664029C927401A1987D01A9A78401ABB09401 + BCB7A401C9C5B401D5D3C303CCCBBC02C2BAAC01B7B09C01AFA68F01A49E8401 + A1987D019C927401948B6D0290866401887D580190866403887D580188826401 + 887D58018882640190866402948B6D019C927401A1987D01B7B09C01C9C5B401 + E1E4D601F0FBEB01AAD5BA01499F73010874420110B58C012BEEDF0107BFCB01 + 09B0C20144BCC401BAFEEF01153A1B017CA0800133805501153A1B0138543301 + 577456017CA08001A9C3A101DCE2C301F0FBEB02E6EDDB01DBDACE01C1DCCC01 + CCCBBC01B1CCB902A8C5AC0292C2A50196B99E0183B194017BB7930178B08B02 + 78A884015FAB820178A884015BA47F01488A5C0133805501488A5C0133805501 + 257C4C0233885A01488A5C015BA47F0192C09B01C1DCCC01F3FEF401E1E4D601 + C2BAAC01AFA68F019C92740190866401887D5801837654017C724C03887D5801 + 83765401887D5802948B6D019C927401A1987D01A49E8401AFA68F01B7B09C01 + BCB7A403B7B09C03AFA68F01A1987D029C927401948B6D0288826401948B6D02 + 887D580188826401948B6D01887D580190866401887D58019086640188826401 + 948B6D02A49E8401AFA68F01C4BFAB01E1E4D601F3FEF401B4DAC40178B08B01 + 0C88530106976D012BE3C40112E2D0010DD7D00127BAA701DCFEF40129391601 + DBFBE801F3FEF401D2FADA01BCEACC01AAD5BA017CA0800150664C012D3D2501 + 3E4C3601637F60018C987E01A9C3A101BEE1C301DBFBE802C7E4D101C0D8C401 + A6CBAC0192C09B0296B99E0183B1940178A884037CA0800178A8840157A07401 + CFEDC901B0E2C201AAD5BA0192C09B0178B08B01668B6E01257C4C0233805501 + 57A074017BB79301BEE1C301F3FEF401E1E4D601C2BAAC01A49E8401948B6D01 + 887D5801837654017C724C017A6D44017C724C017A6D44017C724C02887D5801 + 83765401887D58019C927401948B6D01A1987D01A49E8402B7B09C01AFA68F01 + B7B09C02A49E8403A1987D019C927401948B6D038882640190866404887D5801 + 88826401887D580190866403948B6D01A1987D01A9A78401BCB7A401DBDACE01 + F0FBEB01D4EDD90192C2A50146986E010B7D4A0112C395012BF9D2011DEDD001 + 28C4A401BCEACC011F402401BEF6DC01F3FEF406BCFAD301ADE2CE0192C2A501 + 44886C011F4024012E492A01566C4801888264018C987E01A9C3A101C6CCAA01 + E1E4D601E8F8DB02F0FBEB0750664C01566C5401637F60017CA0800198C9AB01 + DBFBE80195D1AB0157A07401338055026496700185B79D01C0D8C401F3FEF401 + D5D3C301BCB7A401A1987D0188826401837654017A6D440372663C017A6D4402 + 7C724C0283765402908664029C927401A49E8402B7B09C01AFA68F02B7B09C01 + AFA68F01A49E8402A1987D019C927402948B6D029086640288826401948B6D01 + 90866401887D580190866401887D580190866402948B6D019C927401A49E8401 + BCB7A401CCCBBC01E1E4D601F0FBEB01AAD5BA0163AD8C011881560109A06D01 + 29DCAC012BF9D2012BCA9901B0E2C2012E492A01BEF6DC01F3FEF409D2FADA01 + F3FEF401BCEACC01A6CBAC0196B99E01668B6E0150614101293916011F402401 + 2D3D25013E4C36033E563C013E4C36032E492A01ADE2CE027AC6A4017EAA8E01 + 38543301406042017EAA8E01F0FBEB0192C09B0142916E013C8D64015BA47F01 + 92C2A501C7E4D101F0FBEB01C9C5B401A49E8401948B6D01837654017A6D4401 + 72663C077C724C0288826401948B6D01A1987D01A49E8401B7B09C01BCB7A402 + C2BAAC01BCB7A401B7B09C02AFA68F01A49E8401A1987D019C927401948B6D02 + 8882640190866402887D580190866401887D580190866401887D580190866402 + 948B6D019C927401A1987D01AFA68F01C4BFAB01DBDACE01F0FBEB01D4EDD901 + 92C2A50146986E01087442010BB1820129DCAC0124B592018FE0B70138543301 + BEF6DC01F3FEF411BEF6DC03A4EAD404BEF6DC01B6F5E402F3FEF404DBFBE801 + AAD5BA0140604201566C4801A6CBAC01BCEACC0178B08B017CA0800183B19401 + B1CCB901EDF0E501E1E4D601B7B09C01948B6D01887D58017A6D44016B603401 + 655729046B60340172663C027C724C01837654019C927401A49E8401B7B09C01 + C4BFAB01C9C5B401D5D3C301CCCBBC02C9C5B401C2BAAC01BCB7A401AFA68F01 + A49E8401A1987D019C927401948B6D0290866403887D580190866401887D5801 + 88826401887D5801908664039C927401A49E8401ABB09401C9C5B401DBDACE01 + F3FEF401B4DAC4017BB793013C8D64010C88530120B7800116945B01BCEACC01 + 2E492A01BEF6DC01F3FEF421B3ECD50185B79D012E492A018C987E01D2FADA01 + C0D8C401A8C5AC01AFC6B701E6EDDB01EDF0E501C4BFAB01A1987D0183765401 + 72663C0165572902584B1A016557290472663C017C724C01908664018C987E01 + B7B09C01C9C5B401DBDACE01EDF0E502F0FBEB01E1EFE401DBDACE01D5D3C301 + C9C5B401B7B09C01AFA68F01A49E84019C927402948B6D018882640190866402 + 887D580190866401887D580190866402887D5801948B6D0190866401948B6D01 + A1987D01A49E8401BCB7A401C9C5B401E6EDDB01F0FBEB01B4DAC4015FAB8201 + 18815601257C4C02E8F8DB01153A1B01F3FEF424BCEACC014473580151583F01 + 7EAA8E01D4EDD901F3FEF401F0FBEB01E6EDDB01C4BFAB019C9274017A6D4401 + 6B603401584B1A0147491B0245411502584B1A01655729016B6034017C724C01 + 948B6D01B7B09C01D5D3C301F0FBEB01DBFBE801E1EFE401C7E4D101E1EFE401 + EDF0E501F3FEF401E1EFE401DBDACE01C9C5B401BCB7A401AFA68F01A49E8401 + 9C927401948B6D0190866402887D58019086640188826401887D580188826401 + 887D580390866402948B6D019C927401A49E8401BCB7A401CCCBBC01E1EFE401 + DBFBE801AAD5BA0178A88401369363017BB79301A9C3A10157745601F3FEF426 + 9DCCB401406042013E563C01788B6D01A49E8401A9A784019C927401887D5801 + 72663C01584B1A01413C0C0245411502413C0C0247491B01655729017C724C01 + A49E8401D5D3C301F0FBEB01B0E2C20198C9AB017BB7930180BF9B0192C2A501 + AAD5BA01C7E4D101F0FBEB01EDF0E501DBDACE01C2BAAC01B7B09C01A49E8401 + 9C927401948B6D018882640190866402887D580188826401887D580790866401 + 948B6D019C927401A49E8401AFA68F01C9C5B401DCE2C301F3FEF401C0D8C401 + AFC6B701E8F8DB01637F6001A8C5AC01F3FEF427DBFBE801B4DAC4017CA08001 + 38543301293916012D3E1B01293916012D3E1B0172663C01637F60018E937301 + 7CA08001649670016A8A64016B60340129391601584B1A0183765401ABB09401 + F0FBEB019DCCB40168967C0133885A010B7D4A011E88540146986E0163AD8C01 + 98C9AB01C1DCCC01F3FEF401E6EDDB01D5D3C301C2BAAC01AFA68F01A1987D01 + 9C927401948B6D0190866401887D580190866401887D580483765401887D5805 + 908664029C927401A49E8401BCB7A401D5D3C301E6EDDB01E8F8DB0196B99E01 + 153A1B01BCFAD301F3FEF426A4EAD401F3FEF404BCFAD301BEF6DC04F3FEF403 + BEF6DC01ADE2CE0192C2A50178957401293916016B603401ABB09401F0FBEB01 + 78A884010874420109A06D0122A471010B966401087442011E8854015FAB8201 + 95D1AB01E1E4D601F3FEF401E1E4D601C2BAAC01AFA68F01A49E84019C927401 + 9086640288826401887D58067C724C0183765403887D580183765401887D5801 + 8882640190866401948B6D01A1987D019DA58D01A49E84014060420183B19401 + F3FEF436BCFAD301F3FEF401AAD5BA015061410150664C01C0D8C4017BB79301 + 22895F012ED3A40128ECC1011CD5A2010BB182010B7D4A0122895F0178B08B01 + 94D6C401EDF0E501E1EFE401CCCBBC01B7B09C01A49E84019C927401948B6D01 + 90866401887D580188826401887D580183765401887D580283765401887D5802 + 7C724C047A6D440572663C01545429015F754C01F3FEF43ABCFAD301668B6E01 + 57745601DBFBE80122895F0129DCAC012EEDD10129F7DE0115D5AC0110A97401 + 08744201499F730192C2A501D4EDD901F3FEF401D5D3C301BCB7A401A49E8401 + 9C92740190866402887D580283765401887D58027C724C01887D58017C724C01 + 83765401887D58017C724C017A6D440372663C016B60340165572902413C0C01 + 566C4801B4DAC401F3FEF43BBEF6DC01637F60016A8A64017CD6B4011EAC8E01 + 1DEDD00112E2D0012BF9D20112C395010C88530122895F017BB79301C1DCCC01 + F3FEF401DBDACE01C4BFAB01AFA68F019C92740190866402887D580483765401 + 887D580183765401887D58017C724C037A6D440272663C016B60340165572901 + 584B1A01413C0C016557290178A88401F3FEF401B6F5E401F3FEF43BB0E2C201 + 153A1B01AAD5BA011881560147EFDC0112E2D0011DEDD0011AD8B60110A97401 + 0B7D4A015FAB8201AAD5BA01F3FEF401DBDACE01C4BFAB01A49E84019C927401 + 948B6D01887D580483765403887D58017A6D4401837654017C724C017A6D4402 + 72663C016B60340165572902413C0C025F754C0195D1AB01F3FEF43CB6F5E401 + F3FEF40185B79D01577456018FE0B70127BAA70110D6C40112E2D00129F7DE01 + 0BB1820108744201499F73019DCCB401DBFBE801E1E4D601C2BAAC01AFA68F01 + 9C9274018882640283765404887D580183765402887D58017C724C037A6D4401 + 72663C016B60340165572901584B1A0145411501413C0C01637F60019AD5BA01 + F3FEF43EADE2CE01153A1B01BCEACC01106E4C012EEDD1010DD7D0012BEEDF01 + 14CB9A010C8853013693630192C2A501E1EFE401E1E4D601C4BFAB01AFA68F01 + 948B6D0190866401887D5801888264017C724C01887D5801837654037A6D4401 + 7C724C027A6D440272663C026B60340165572901574E2401584B1A01413C0C01 + 5F754C0198C9AB01F3FEF43F7CA080016496700161B88F0144DABF010DD7D001 + 1DEDD00124E1B7010B96640122895F0180BF9B01D4EDD901E1EFE401C4BFAB01 + AFA68F01948B6D0188826401887D58017C724C01887D58017C724C0183765401 + 7C724C0183765401887D58017C724C037A6D440272663C016B603402584B1A02 + 413C0C016B6034017BB79301F3FEF43FBEE1C30138543301BAFEEF0124977201 + 28E2CF011DEDD0012BE3C40110A974010B7D4A017BB79301D4EDD901E6EDDB01 + C4BFAB019DA58D01948B6D0190866401837654027C724C01837654017C724C01 + 837654017C724C047A6D440272663C0265572902574E2401584B1A0145411502 + 7CA08001BEF6DC01F3FEF43F50664C017BB7930168967C012BE3C4011DEDD001 + 28ECC1010BB182010B7D4A0161B88F01C7E4D101E1EFE401C4BFAB01A49E8401 + 948B6D01887D5801837654017C724C01837654017C724C01837654017C724C04 + 7A6D440372663C026B60340265572902584B1A01413C0C0157745601BCFAD301 + F3FEF43F8CCAB80150664C01BCEACC010AA67D013FF9D2012BF9D2010BB18201 + 0B7D4A015FAB8201C7E4D101E6EDDB01C4BFAB01A49E84019086640183765402 + 7C724C077A6D44017C724C017A6D440272663C036B6034016557290354542901 + 2E492A01BCEACC01F3FEF43FB6F5E4013854330192C09B01249772012ED3A401 + 24E1B70112C39501087442015FAB8201C7E4D101E6EDDB01BCB7A401A1987D01 + 90866401837654017C724C05887D58017A6D44017C724C0372663C017A6D4401 + 72663C026B60340272663C026B60340229391601BCEACC01F3FEF44092C2A501 + 3F6A4901BCFAD301188156012BCA990120B780010B7D4A0157A07401ADE2CE01 + E6EDDB01C2BAAC019C92740188826401837654017A6D44017C724C017A6D4401 + 7C724C017A6D44027C724C017A6D440472663C067C724C01887D580172663C01 + 29391601BCEACC01B6F5E401F3FEF43FD2FADA014060420178B08B0161B88F01 + 0B9664010BB18201087442015BA47F01C7E4D101E6EDDB01B7B09C019C927401 + 837654017C724C017A6D440A72663C047A6D440283765401887D580190866401 + 7C724C012E492A01D2FADA01F3FEF41E0F000000F8FFFFFF1FF07F000C000000 + 3F010000F8FFFFFF1FFCFFA10F000000FF000000F0FFFFFF1FFEFFC30F000000 + FF030000E8FFFFFF8FFFFFEF0F000000FF070000C0FFFFFF8FFFFFFF0F000000 + FF0F000080FFFFFFE7FFFFFF0F000000FF3F000000FEFFFFC3FFFFFF0F000000 + FF7F000000FCFFFFE1FFFFFF0F000000FF7F01000080FFFFE0FFFFFF0F000000 + FFFF00000000FC7FE8FFFFFF0F000000FFFF01000000E01FF0FFFFFF0B000000 + FFFF050000000007F0FFFDFF07000000FEFF030000000000F07FFFFF0F000000 + FFFF030000000000E0DFFFFF0F000000F7FF030000000000E0FFFFFF0F000000 + 9FFF030000000000E0FFFFFF0F000000FFEB030000000000C0FFFFFF0F000000 + FFFF01000000000080FFFFFF0F000000FFFF03000000000000FFFFFF0F000000 + FFFF01000000000080FEFFFF0F000000FFFF01000000000000FEFFFF0F000000 + FFFF03000020000000FEFFFF0F000000FFFF03000000000000FCFFFF0F000000 + FFFF07000000000000FCFFFF0F000000FFFF0F000000000000FCFFFF0F000000 + FFFF07000700000000FCFFFF0F000000FFFF07F07F00000000FCFFFF0F000000 + FFFF07F8FF01000000FDFFFF0F000000FFFF07FEFF01000000FCFFFF0F000000 + FFFF03FFFF03000000FCCFFF0F000000FFFF07FFFF07000000FCFFFE0F000000 + FFFF01FFBF07000000F8FFF70F000000FFFF81FFDF07000000F8FFEF0F000000 + FFFF80FFFF07000000F0FFFF0F000000FF7F80FFFF0F000000E0FF7F0F000000 + FF7F80BFFF5F000000C0FFFF0E000000FF3F80FFFF3F000000C0FFFF0D000000 + FF1F80FFFF7F010000F4FFFF0D000000FF0F00FFFFFF000000FEFFFF0F000000 + FF0700FFFFFF000090FFFFFF0F000000FF0000FFFFFF0000E0FFFFFF01000000 + 000000FFFFFF0000F8FFFF0700000000000000FFFFDF0100FCFFFF0F00000000 + 020000FFFFFF0040FFFFFF2F04000000030000FFFFFF0080FFFFFFFF0F000000 + 070080FFFF7F00E0FFFFFFFF0F0000000F0000FFFFEF00F8FFFFFBFF07000000 + 1F0000FFFF3F00FFFFFFFFFF0F0000003F0000FEFF3FF0FFFF7FFFFF0F000000 + FF0000FCFF5FFDFFFFFFFFFF0F000000FF0000F8FF0FFFFFFFEFFFFF0F000000 + FF0000F0FFEFFFFFFFFBFFFF0F000000FF0100C0FFF1FFFFFFFEFFFF0B000000 + FF01000000F8FFFFBFFFFFFF0F000000FF07000000FCFFFFF7FFFFFF0F000000 + FF03000000FFFFFFFCFFFFFF07000000FF07000080FFFFCFFFFFFFFF0F000000 + FE0F0000E0FFFFFEFFFFFFFF0F000000FF1F0000F0FFEFFFFFFFFFFF0F000000 + FD1F0000FAFFFFFFFFFFFFFF0F000000FF1F0000FCFFFFFFFFFFFFFF0F000000 + FF3F0000FFFFFFFFFFFFFFFF0F000000FFFF0180FFFFFFFFFFFFFFFF0F000000 + FFFFAFEAFFFFFFFFFFFFFFFF0F000000FFFFFFF1FFFFFFFFFFFFFFFF0F000000 + 7FFFFFFFFFFBFFFFFFFFFFFF0F000000FFFDFFFFFFFFFFFFC7FFFFFF0F000000 + FFFFFFFFFFFDFFFFFFFEFFFF0F000000FFBFFFFFFFFFFF7FFFFBFFFF0F000000 + FFFFFEFFFFFFFFFFFFFFFFFF0F000000FFFFFFFF7FFFFFFFFFFFFFFF0F000000 + FFFFDFFFFFFFFFFFFFFFFFFF0F000000FFFF7FFFFFFFFFDFFFFFFFFF0F000000 + FFFFFFFFFFFFFFFFFFFFFFFF0F000000C5FFFFEFF7FFFFFFFFFFEF7F00000000 + FFFEFFFFFFFFFFFFFFFFFFFF0F000000FFFFFFFFFFFFFFFFFFFFFFFF0F000000 + FFF7FFFFFFFFFFDFFFFDFFFF0F000000FFEFFFFFFFFFFFFFFF81FFFF0F000000 + FFDFFFFFFFFFFFFFFF01F4FF0F000000FFFFFFFFFFFFFFFFFF0100FC0F000000 + F0FFFFFFFFFFFF7FFF01000000000000C0FFFFFFFFFFFFFFFF00000000000000 + 00DFFFFFBFFFFFFFFF0000000000000000FCFFFFFFFFFFFFFB00000000000000 + 00F8FFFFFFFEFFFFFF0000000000000000848FFFFFFDFFFF7F00000000000000 + 000000FAFFFFFFFF3F00000000000000000000F0FFFBFFFF3F00000000000000 + 000000E0FFFBFFFF5F00000000000000000000C0FFFBFFFF1F00000000000000 + 000000A0FFFFFFFF1F0000000000000000000080FFFFFFFF1F00000000000000 + 00000000FFFFFFFF1F0000000000000000000000FFFFFFFF3F00000000000000 + 00000000FEFFFFFF3F0000000000000000000000FEFFFFFF3F00000000000000 + 00000000FEFFFFFF3F0000000000000000000000FCFFFFFF7F00000000000000 + 00000000FCFFFFFF3F00000000000000 + } + face.fade_pos.count = 5 + face.fade_pos.items = ( + 0 + 0.2 + 0.5 + 0.8 + 1 + ) + face.fade_color.count = 5 + face.fade_color.items = ( + 16777215 + 8421504 + 4210752 + 8421504 + 16777215 + ) + face.fade_direction = gd_up + face.localprops = [fal_options, fal_fadirection, fal_faopacity] + taborder = 2 + bounds_x = 400 + bounds_y = 40 + bounds_cx = 132 + bounds_cy = 52 + statfile = tstatfile1 + reffontheight = 14 + end + object tstringedit8: tstringedit + color = -2147483645 + frame.levelo = 0 + frame.framei_left = 4 + frame.framei_right = 4 + frame.frameimage_list = imli + frame.frameimage_offsetmouse = 8 + frame.frameimage_offsetclicked = 8 + frame.frameimage_offsetactive = 24 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_framewidth, frl_fileft, frl_firight, frl_frameimagelist, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_colorclient] + frame.localprops1 = [] + face.options = [fao_alphafadeimage] + face.image.alignment = [al_xcentered, al_ycentered, al_tiled] + face.image.image = { + 000000000000000020000000200000006C0B0000000000000000000000000000 + 0000000000000000000000000000000000000000BDBDBD01B5B5B501BDBDBD04 + C6C6C601CECECE01DEDEDE03D6D6D6019C9C9C0194949401CECECE01DEDEDE02 + B5B5B502BDBDBD01DEDEDE03D6D6D601C6C6C602BDBDBD01B5B5B502BDBDBD01 + 949494019C9C9C01BDBDBD01ADADAD029C9C9C01949494019C9C9C01A5A5A501 + BDBDBD01A5A5A5019C9C9C0194949402D6D6D60194949402DEDEDE01BDBDBD02 + B5B5B501BDBDBD019C9C9C02A5A5A501ADADAD01A5A5A5029C9C9C0194949401 + 9C9C9C01B5B5B5019C9C9C01CECECE02C6C6C601ADADAD01B5B5B501D6D6D601 + DEDEDE02CECECE01C6C6C601BDBDBD03DEDEDE01CECECE01ADADAD01BDBDBD01 + 9C9C9C01ADADAD01DEDEDE01CECECE01B5B5B501C6C6C603D6D6D601DEDEDE02 + CECECE0194949401B5B5B501D6D6D601BDBDBD01C6C6C601DEDEDE0194949401 + B5B5B502DEDEDE04BDBDBD01CECECE01DEDEDE03B5B5B5029C9C9C01D6D6D601 + DEDEDE03BDBDBD01CECECE01DEDEDE03CECECE019C9C9C01BDBDBD01B5B5B501 + DEDEDE01A5A5A501DEDEDE029C9C9C01BDBDBD02B5B5B503BDBDBD01B5B5B502 + BDBDBD01B5B5B501CECECE01D6D6D6019C9C9C01B5B5B501DEDEDE01BDBDBD01 + B5B5B501BDBDBD01B5B5B502BDBDBD01B5B5B5029C9C9C01949494019C9C9C01 + B5B5B501DEDEDE03C6C6C601A5A5A501DEDEDE01B5B5B501BDBDBD01A5A5A501 + 9C9C9C06BDBDBD02ADADAD0194949401DEDEDE019C9C9C01949494019C9C9C05 + ADADAD019C9C9C01CECECE01B5B5B50194949401DEDEDE03B5B5B50194949401 + DEDEDE01CECECE0194949402D6D6D601DEDEDE06A5A5A502BDBDBD01C6C6C601 + DEDEDE06BDBDBD03DEDEDE01BDBDBD0194949401DEDEDE03ADADAD0194949401 + DEDEDE02BDBDBD01B5B5B502D6D6D601DEDEDE03A5A5A501D6D6D6019C9C9C01 + BDBDBD019C9C9C01B5B5B502BDBDBD01DEDEDE03C6C6C6019C9C9C01A5A5A501 + DEDEDE02C6C6C601ADADAD01CECECE01DEDEDE0294949401B5B5B501DEDEDE02 + BDBDBD01A5A5A5019C9C9C01B5B5B501DEDEDE03C6C6C602A5A5A501D6D6D601 + B5B5B50194949401CECECE02DEDEDE02CECECE01A5A5A501B5B5B50194949401 + DEDEDE039C9C9C01BDBDBD01DEDEDE01C6C6C601B5B5B501C6C6C601DEDEDE02 + B5B5B50194949401C6C6C601A5A5A501ADADAD01BDBDBD03B5B5B5019C9C9C01 + DEDEDE01B5B5B501A5A5A501B5B5B503BDBDBD01A5A5A502BDBDBD019C9C9C01 + DEDEDE03A5A5A50194949401DEDEDE01B5B5B5019C9C9C01DEDEDE03ADADAD02 + DEDEDE01C6C6C6019C9C9C01ADADAD01949494029C9C9C02DEDEDE01B5B5B501 + ADADAD019C9C9C03B5B5B501A5A5A501DEDEDE01CECECE01BDBDBD01CECECE01 + DEDEDE02BDBDBD01A5A5A501D6D6D601ADADAD01BDBDBD01DEDEDE039C9C9C01 + B5B5B501DEDEDE02C6C6C601ADADAD019C9C9C01CECECE01BDBDBD019C9C9C01 + DEDEDE01B5B5B5019C9C9C01DEDEDE01BDBDBD01A5A5A501ADADAD01D6D6D601 + DEDEDE029C9C9C01BDBDBD01DEDEDE02D6D6D601A5A5A501D6D6D601DEDEDE05 + 9C9C9C01B5B5B501BDBDBD0194949402CECECE01A5A5A502D6D6D601A5A5A501 + C6C6C60194949401B5B5B501BDBDBD01A5A5A501C6C6C601ADADAD019C9C9C01 + A5A5A501B5B5B5019C9C9C01B5B5B501DEDEDE06CECECE01D6D6D601BDBDBD01 + 9C9C9C01B5B5B5019C9C9C02D6D6D601C6C6C60194949401B5B5B501BDBDBD01 + 9C9C9C01A5A5A501B5B5B5019C9C9C01BDBDBD01ADADAD01BDBDBD019C9C9C01 + A5A5A501CECECE01ADADAD019C9C9C01ADADAD019C9C9C01ADADAD01CECECE02 + DEDEDE02CECECE019C9C9C02A5A5A501B5B5B5019C9C9C01D6D6D601DEDEDE01 + B5B5B501CECECE02B5B5B50294949401BDBDBD01B5B5B502ADADAD01B5B5B501 + A5A5A501B5B5B501DEDEDE01ADADAD01C6C6C601DEDEDE01BDBDBD01B5B5B501 + 94949401ADADAD01A5A5A501B5B5B501DEDEDE019C9C9C01ADADAD01BDBDBD01 + D6D6D601DEDEDE06BDBDBD019C9C9C01DEDEDE01CECECE019C9C9C01BDBDBD02 + B5B5B501DEDEDE01B5B5B5019C9C9C01DEDEDE07C6C6C601ADADAD0294949401 + B5B5B5029C9C9C01B5B5B501CECECE02DEDEDE02CECECE01D6D6D601C6C6C601 + A5A5A501D6D6D601B5B5B501ADADAD01BDBDBD0294949401CECECE01B5B5B501 + 94949401DEDEDE01D6D6D601DEDEDE02CECECE02BDBDBD019C9C9C01A5A5A501 + 94949401BDBDBD01DEDEDE01ADADAD01BDBDBD0194949401ADADAD01A5A5A501 + B5B5B501BDBDBD01ADADAD01CECECE01BDBDBD01A5A5A50194949401B5B5B501 + ADADAD02A5A5A503ADADAD01B5B5B501CECECE01A5A5A501C6C6C601B5B5B501 + A5A5A5019C9C9C01ADADAD02A5A5A501CECECE01DEDEDE05C6C6C6019C9C9C02 + A5A5A504ADADAD01A5A5A501BDBDBD0194949401BDBDBD0194949401BDBDBD01 + 94949401B5B5B5019C9C9C01B5B5B5019C9C9C01BDBDBD019C9C9C01B5B5B502 + CECECE01DEDEDE04C6C6C601CECECE01DEDEDE039C9C9C01BDBDBD01D6D6D601 + BDBDBD01C6C6C601ADADAD01B5B5B501BDBDBD01C6C6C601ADADAD01CECECE01 + B5B5B501A5A5A501D6D6D601949494019C9C9C01D6D6D601BDBDBD01CECECE01 + DEDEDE0194949401B5B5B501DEDEDE03C6C6C601D6D6D601A5A5A501ADADAD01 + DEDEDE039C9C9C01B5B5B501DEDEDE01D6D6D601ADADAD02CECECE01B5B5B502 + 9C9C9C01DEDEDE01B5B5B5019C9C9C01BDBDBD02C6C6C6019C9C9C01C6C6C601 + DEDEDE02A5A5A501BDBDBD01DEDEDE02CECECE01B5B5B501CECECE01B5B5B501 + 9C9C9C01D6D6D601DEDEDE02B5B5B5019C9C9C01D6D6D601B5B5B501ADADAD01 + 9C9C9C02949494019C9C9C0194949401DEDEDE01B5B5B501ADADAD0194949403 + 9C9C9C01A5A5A501C6C6C602A5A5A501DEDEDE03BDBDBD0194949401DEDEDE01 + CECECE01A5A5A501BDBDBD01DEDEDE02B5B5B5019C9C9C01B5B5B5019C9C9C01 + CECECE01DEDEDE03BDBDBD019C9C9C01DEDEDE01B5B5B50194949401DEDEDE04 + B5B5B501A5A5A501BDBDBD0194949401DEDEDE0394949401B5B5B501DEDEDE02 + 9C9C9C01B5B5B501DEDEDE02BDBDBD02A5A5A501C6C6C601DEDEDE03A5A5A501 + D6D6D601ADADAD01C6C6C6019C9C9C01B5B5B501ADADAD01BDBDBD01DEDEDE03 + 9C9C9C01B5B5B5019C9C9C01DEDEDE02CECECE01ADADAD01C6C6C601DEDEDE02 + B5B5B50194949401DEDEDE02B5B5B501ADADAD01C6C6C601DEDEDE04C6C6C601 + D6D6D60194949401BDBDBD019C9C9C01BDBDBD01CECECE02DEDEDE049C9C9C02 + CECECE01DEDEDE01B5B5B5019C9C9C01DEDEDE03BDBDBD019C9C9C01DEDEDE01 + C6C6C601ADADAD01C6C6C601B5B5B502BDBDBD01B5B5B503CECECE01B5B5B502 + A5A5A501D6D6D601BDBDBD01B5B5B502BDBDBD01B5B5B502BDBDBD01ADADAD01 + 9C9C9C01DEDEDE01B5B5B50194949401DEDEDE03D6D6D601B5B5B501C6C6C601 + 949494019C9C9C01949494029C9C9C0194949404C6C6C601CECECE01A5A5A501 + B5B5B501DEDEDE01949494019C9C9C0494949403BDBDBD01B5B5B501A5A5A501 + B5B5B501DEDEDE02D6D6D601DEDEDE019C9C9C01ADADAD0194949401CECECE01 + DEDEDE08C6C6C601ADADAD019C9C9C01DEDEDE09B5B5B501BDBDBD01ADADAD01 + BDBDBD01DEDEDE01C6C6C602DEDEDE01949494019C9C9C01CECECE01DEDEDE04 + A5A5A501C6C6C601DEDEDE03A5A5A502BDBDBD01C6C6C601DEDEDE03A5A5A501 + C6C6C601DEDEDE04A5A5A501ADADAD01B5B5B501DEDEDE019C9C9C01D6D6D601 + 94949401ADADAD01BDBDBD02B5B5B502ADADAD01A5A5A5029C9C9C02DEDEDE01 + B5B5B501A5A5A501CECECE01B5B5B5019C9C9C01CECECE01C6C6C6019C9C9C01 + A5A5A503BDBDBD01B5B5B503C6C6C6019C9C9C01BDBDBD01DEDEDE0194949401 + A5A5A5019C9C9C01949494019C9C9C02A5A5A502BDBDBD01B5B5B502C6C6C601 + BDBDBD02B5B5B501DEDEDE01CECECE019C9C9C0194949401D6D6D601B5B5B504 + A5A5A502949494019C9C9C0294949401B5B5B5029C9C9C01CECECE01DEDEDE09 + CECECE01A5A5A501B5B5B501DEDEDE03CECECE01A5A5A502DEDEDE0AB5B5B502 + } + face.fade_pos.count = 3 + face.fade_pos.items = ( + 0 + 0.5 + 1 + ) + face.fade_color.count = 3 + face.fade_color.items = ( + 16777215 + 0 + 16777215 + ) + face.localprops = [fal_options, fal_faopacity] + taborder = 7 + bounds_x = 400 + bounds_y = 168 + bounds_cx = 132 + bounds_cy = 52 + statfile = tstatfile1 + reffontheight = 14 + end + object buttonface1: tfacecomp + template.fade_pos.count = 2 + template.fade_pos.items = ( + 0 + 1 + ) + template.fade_color.count = 2 + template.fade_color.items = ( + -1610612731 + -1610612732 + ) + template.fade_direction = gd_down + left = 16 + top = 72 + end + object mainmenu1: tmainmenu + popupframetemplate = popupframe + popupitemframetemplate = popupitemframe + popupitemfacetemplate = buttonface2 + popupitemframetemplateactive = popupitemframe + popupitemfacetemplateactive = buttonface2 + frametemplate = mainmenuframe + facetemplate = buttonface1 + itemframetemplate = mainmenuitemframe + itemfacetemplate = buttonface2 + itemframetemplateactive = mainmenuitemframe + itemfacetemplateactive = buttonface2 + menu.submenu.count = 4 + menu.submenu.items = < + item + submenu.count = 4 + submenu.items = < + item + submenu.count = 6 + submenu.items = < + item + caption = 'ewrgqeg qewr ' + state = [as_localcaption] + end + item + caption = 'qer qwetr' + state = [as_localcaption] + end + item + caption = 'uzkme56are' + state = [as_localcaption] + end + item + caption = 'w435 ertrh46' + state = [as_localcaption] + end + item + caption = '4w5gbsgfdbsw' + state = [as_localcaption] + end + item + caption = 'aerga aerg345 ' + state = [as_localcaption] + end> + caption = '&1111111111' + state = [as_localcaption] + end + item + caption = '&22222222' + state = [as_localcaption] + end + item + caption = '&333333333' + state = [as_localcaption] + end + item + caption = '&4444444444' + state = [as_localcaption] + end> + caption = '&Aaaaaaa' + state = [as_localcaption] + end + item + caption = '&Bbbbbb' + state = [as_localcaption] + end + item + caption = '&Cccccccc' + state = [as_localcaption] + end + item + caption = '&Ddddd' + state = [as_localcaption] + end> + left = 24 + top = 40 + end + object mainmenuframe: tframecomp + template.leveli = 1 + left = 144 + top = 36 + end + object mainmenuitemframe: tframecomp + template.levelo = -1 + template.leveli = 1 + template.framewidth = 2 + template.colorframe = -2147483645 + template.framei_left = 2 + template.framei_top = 2 + template.framei_right = 2 + template.framei_bottom = 2 + left = 288 + top = 36 + end + object buttonface2: tfacecomp + template.fade_pos.count = 2 + template.fade_pos.items = ( + 0 + 1 + ) + template.fade_color.count = 2 + template.fade_color.items = ( + -1610612731 + -1610612732 + ) + template.fade_direction = gd_up + left = 16 + top = 104 + end + object popupitemframe: tframecomp + template.levelo = -1 + template.leveli = 1 + template.framei_top = 1 + template.framei_bottom = 1 + left = 442 + top = 63 + end + object popupframe: tframecomp + template.levelo = 2 + template.framewidth = 1 + left = 443 + top = 35 + end + object tstatfile1: tstatfile + filename = 'status.sta' + left = 19 + top = 195 + end + object imli: timagelist + width = 4 + height = 4 + options = [] + count = 51 + left = 448 + top = 112 + image = { + 00000000000000002000000020000000200B0000000000000000000000000000 + 0000000000000000000000000000000000000000D5E7E901CEDFE401CADDE101 + C9DCE001CADDE101743C0001FCFDFD02CCDEE3017E4D1601CAC7BF01D6DFE201 + D5DEE104CDD7DB01BDBDB6017E4D1601E6F1F301DAE2E401D4DDE001743C0001 + E2EEF101CADDE101CBDEE201CEDFE401D5E7E901C9DCE004CEDFE401D0E1E601 + A8957A0183572501CADDE101743C0001FCFDFD02CFE1E501A087660193714A01 + B4AEA301C5D0D604B6B7B101906E4801A28B6A01EBF4F501DAE2E401D4DDE001 + 743C0001E2EEF1017E4D1601A0886701D2E4E802743C0004CBDEE201A8957A01 + A27D5501DDCFC001CADDE101743C0001FCFDFD02D4E6E901D8E9EC01AA997D01 + 83572501743C00047E4D1601A48C6C01EAF4F401EEF6F701DAE2E401D4DDE001 + 743C0001E2EEF101E8DFD501A27D5501A9957B01D5E7E901FFFFFF04CBDEE201 + 83572501DCCEBF01FEFEFE01CADDE101743C0001FCFDFD02DAEAED01DFEDEF01 + E7F1F301EDF5F601F0F6F804F2F7F801F2F8F901F1F7F801DEEDEF01DAE2E401 + D4DDE001743C0001E2EEF101FDFEFE01DBCEBF0183572501DAEAED01FEFEFE04 + D5E7E901CEDFE401CADDE101C9DCE001CADDE101743C0001F5D3BA01F6D3BA01 + CCDEE3017E4D1601E4AD89087E4D1601E6F1F301E4AD8902743C0001E2EEF101 + CADDE101CBDEE201CEDFE401D5E7E901C9DCE004CEDFE401D0E1E601A8957A01 + 83572501CADDE101743C0001F5D3BA01F6D3BA01CFE1E501A0876601854D2701 + C17D4D01EE826905854D2701A28B6A01EBF4F501E4AD8902743C0001E2EEF101 + 7E4D1601A0886701D2E4E802743C0004CBDEE201A8957A01854D2701FFE7CE01 + CADDE101743C0001F5D3BA01F6D3BA01D4E6E901D8E9EC01AA997D0183572501 + 743C00047E4D1601A48C6C01EAF4F401EEF6F701E4AD8902743C0001E2EEF101 + FFE7CE01854D2701A9957B01D5E7E901FFE7CE04CBDEE20183572501F6D4BC02 + CADDE101743C0001F5D3BA01F6D3BA01DAEAED01DFEDEF01E7F1F301EDF5F601 + EFF6F704F2F7F801F2F8F901F1F7F801DEEDEF01E4AD8902743C0001E2EEF101 + F6D4BC0283572501DAEAED01F6D4BC04D5E7E901CEDFE401CADDE101C9DCE001 + CBDEE201743C0001CFD8DA01D7DEE001CCDEE3017E4D1601C7C5BC01DEE6E601 + E3E9EA04DAD3CA01D2CEC4017E4D1601E6F1F301DFE5E602743C0001E2EEF101 + CADDE101CBDEE201CEDFE401D5E7E901C9DCE004CEDFE401D0E1E601A8957A01 + 83572501CBDEE201743C0001CFD8DA01D7DEE001CFE1E501A087660198754D01 + CBC1B201EEF1F204DAD3CA019B774F01A28B6A01EBF4F501DFE5E602743C0001 + E2EEF1017E4D1601A0886701D2E4E802743C0004CBDEE201A8957A018E6D4601 + ACA89D01CBDEE201743C0001CFD8DA01D7DEE001D4E6E901D8E9EC01AA997D01 + 83572501743C00047E4D1601A48C6C01EAF4F401EEF6F701DFE5E602743C0001 + E2EEF101B7B7B10192704901A9957B01D5E7E901C1CCD104CBDEE20183572501 + B1ABA001C6D0D601CBDEE201743C0001CFD8DA01D7DEE001DAEAED01DFEDEF01 + E7F1F301EDF5F601F0F7F804F2F7F801F2F8F901F1F7F801DEEDEF01DFE5E602 + 743C0001E2EEF101CED7DB01BDB5A90183572501DAEAED01CFD8DC04CFE3E501 + BBCED501B2C8D001B1C7CD01B2C8D001743C00019ADFFE0179D2FC01B8CCD401 + 7D4C140149B5EF0130B2F80130B3F80430B2F80147B5ED017D4C1401F5F9FA01 + 33B4F80135B4F801743C0001EEF5F701B2C8D001B6CBD101BBCED501CFE3E501 + A2BBC404BBCED501C8D9E1019F86650182542201B2C8D001743C00019ADFFE01 + 79D2FC01BFD2DA01997B5601718684010097E5066F8483019D825E01FAFCFC01 + 33B4F80135B4F801743C0001EEF5F7017D4C1401997C5701CCDFE301C6DBE001 + 743C0004B6CBD1019F866501A19E8D01D2E8EF01B2C8D001743C00019ADFFE01 + 79D2FC01CCE0E301D8E9EC01A28B6A0182542201743C00047D4C14019F846101 + F0F8F801FCFDFE0133B4F80135B4F801743C0001EEF5F701D3EDF801A19E8D01 + A0856501CFE3E501CFF0FF04B6CBD10182542201ADDCEE0179D2FC01B2C8D001 + 743C00019ADFFE0179D2FC01DCECEF01EAF3F401F6F9FB01FBFDFD01FFFFFF04 + FEFEFE02FDFEFE01E8F2F40133B4F80135B4F801743C0001EEF5F70179D2FC01 + ADDCEE0182542201DEECEF0189D8FD04CFE3E501BBCED501B2C8D001B1C7CD01 + B2C8D001743C00019ADFFE0179D2FC01B8CCD4017D4C140149B5EF0130B2F801 + 30B3F80430B2F80147B5ED017D4C1401F5F9FA0133B4F80135B4F801743C0001 + EEF5F701B2C8D001B6CBD101BBCED501CFE3E501A2BBC404BBCED501C8D9E101 + 9F86650182542201B2C8D001743C00019ADFFE0179D2FC01BFD2DA01997B5601 + 718684010097E5066F8483019D825E01FAFCFC0133B4F80135B4F801743C0001 + EEF5F7017D4C1401997C5701CCDFE301C6DBE001743C0004B6CBD1019F866501 + A19E8D01D2E8EF01B2C8D001743C00019ADFFE0179D2FC01CCE0E301D8E9EC01 + A28B6A0182542201743C00047D4C14019F846101F0F8F801FCFDFE0133B4F801 + 35B4F801743C0001EEF5F701D3EDF801A19E8D01A0856501CFE3E501CFF0FF04 + B6CBD10182542201ADDCEE0179D2FC01B2C8D001743C00019ADFFE0179D2FC01 + DCECEF01EAF3F401F6F9FB01FBFDFD01FFFFFF04FEFEFE02FDFEFE01E8F2F401 + 33B4F80135B4F801743C0001EEF5F70179D2FC01ADDCEE0182542201DEECEF01 + 89D8FD04D5E7E901CEDFE401CADDE101C9DCE001CBDEE201743C0001CFD8DA01 + D7DEE001CCDEE3017E4D1601C7C5BC01DEE6E601E3E9EA04DAD3CA01D2CEC401 + 7E4D1601E6F1F301DFE5E602743C0001E2EEF101CADDE101CBDEE201CEDFE401 + D5E7E901C9DCE004CEDFE401D0E1E601A8957A0183572501CBDEE201743C0001 + CFD8DA01D7DEE001CFE1E501A087660198754D01CBC1B201EEF1F204DAD3CA01 + 9B774F01A28B6A01EBF4F501DFE5E602743C0001E2EEF1017E4D1601A0886701 + D2E4E802743C0004CBDEE201A8957A018E6D4601ACA89D01CBDEE201743C0001 + CFD8DA01D7DEE001D4E6E901D8E9EC01AA997D0183572501743C00047E4D1601 + A48C6C01EAF4F401EEF6F701DFE5E602743C0001E2EEF101B7B7B10192704901 + A9957B01D5E7E901C1CCD104CBDEE20183572501B1ABA001C6D0D601CBDEE201 + 743C0001CFD8DA01D7DEE001DAEAED01DFEDEF01E7F1F301EDF5F601F0F7F804 + F2F7F801F2F8F901F1F7F801DEEDEF01DFE5E602743C0001E2EEF101CED7DB01 + BDB5A90183572501DAEAED01CFD8DC04C9DCE004FFFFFF08C9DCE004CADDE101 + CBDEE201CEDFE401D5E7E901E4AD8902743C0001E2EEF101E4AD89027E4D1601 + E6F1F301E4AD8904743C0004FFFFFF08743C00047E4D1601A0886701D2E4E802 + E4AD8902743C0001E2EEF101EE826901854D2701A28B6A01EBF4F501EE826904 + FFE7CE04FFFFFF08FFE7CE05854D2701A9957B01D5E7E901E4AD8902743C0001 + E2EEF1017E4D1601A48C6C01EAF4F401EEF6F701743C0004F6D4BC04FFFFFF08 + F6D4BC0683572501DAEAED01E4AD8902743C0001E2EEF101F2F7F801F2F8F901 + F1F7F801DEEDEF01EFF6F704CCDEE3017E4D1601E4AD8902CADDE101743C0001 + F5D3BA01F6D3BA01D5E7E901CEDFE401CADDE101C9DCE001D0D0D002CECECE01 + 7777770121212101060606012525250190909001D0D0D00200000001D0D0D003 + 00000001D0D0D00300000001D0D0D001CFE1E501A0876601854D2701C17D4D01 + CADDE101743C0001F5D3BA01F6D3BA01CEDFE401D0E1E601A8957A0183572501 + D0D0D014D4E6E901D8E9EC01AA997D0183572501CADDE101743C0001F5D3BA01 + F6D3BA01CBDEE201A8957A01854D2701FFE7CE01D0D0D014DAEAED01DFEDEF01 + E7F1F301EDF5F601CADDE101743C0001F5D3BA01F6D3BA01CBDEE20183572501 + F6D4BC02D0D0D009FFFFFF0180808001D0D0D009 + } + end +end diff --git a/mseide-msegui/apps/facedemo/main.pas b/mseide-msegui/apps/facedemo/main.pas new file mode 100644 index 0000000..2ad2e41 --- /dev/null +++ b/mseide-msegui/apps/facedemo/main.pas @@ -0,0 +1,34 @@ +unit main; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msegui,mseclasses,mseforms,msemenus,msedataedits,msestat,msestatfile,msebitmap, + mseapplication,mseedit,mseglob,mseguiglob,mseificomp,mseificompglob,mseifiglob, + msestream,msestrings,msetypes,sysutils; + +type + tmainfo = class(tmseform) + buttonface1: tfacecomp; + mainmenu1: tmainmenu; + mainmenuframe: tframecomp; + mainmenuitemframe: tframecomp; + buttonface2: tfacecomp; + popupitemframe: tframecomp; + popupframe: tframecomp; + tstatfile1: tstatfile; + tstringedit1: tstringedit; + tstringedit2: tstringedit; + tstringedit3: tstringedit; + tstringedit4: tstringedit; + tstringedit5: tstringedit; + tstringedit6: tstringedit; + tstringedit7: tstringedit; + tstringedit8: tstringedit; + imli: timagelist; + end; +var + mainfo: tmainfo; +implementation +uses + main_mfm; +end. diff --git a/mseide-msegui/apps/facedemo/main_mfm.pas b/mseide-msegui/apps/facedemo/main_mfm.pas new file mode 100644 index 0000000..c27d404 --- /dev/null +++ b/mseide-msegui/apps/facedemo/main_mfm.pas @@ -0,0 +1,5367 @@ +unit main_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,main; + +const + objdata: record size: integer; data: array[0..106987] of byte end = + (size: 106988; data: ( + 84,80,70,48,7,116,109,97,105,110,102,111,6,109,97,105,110,102,111,7, + 118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,58,8, + 98,111,117,110,100,115,95,121,3,17,1,9,98,111,117,110,100,115,95,99, + 120,3,126,2,9,98,111,117,110,100,115,95,99,121,3,30,1,22,99,111, + 110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,101,118,101,108,111, + 2,255,22,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108, + 101,118,101,108,105,2,1,26,99,111,110,116,97,105,110,101,114,46,102,114, + 97,109,101,46,102,114,97,109,101,119,105,100,116,104,2,1,26,99,111,110, + 116,97,105,110,101,114,46,102,114,97,109,101,46,99,111,108,111,114,102,114, + 97,109,101,4,139,198,199,0,26,99,111,110,116,97,105,110,101,114,46,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108, + 95,108,101,118,101,108,111,10,102,114,108,95,108,101,118,101,108,105,14,102, + 114,108,95,102,114,97,109,101,119,105,100,116,104,14,102,114,108,95,99,111, + 108,111,114,102,114,97,109,101,0,27,99,111,110,116,97,105,110,101,114,46, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,30, + 99,111,110,116,97,105,110,101,114,46,102,97,99,101,46,105,109,97,103,101, + 46,97,108,105,103,110,109,101,110,116,11,8,97,108,95,116,105,108,101,100, + 0,28,99,111,110,116,97,105,110,101,114,46,102,97,99,101,46,105,109,97, + 103,101,46,111,112,97,99,105,116,121,4,127,127,127,0,26,99,111,110,116, + 97,105,110,101,114,46,102,97,99,101,46,105,109,97,103,101,46,105,109,97, + 103,101,10,108,10,1,0,0,0,0,0,0,0,0,0,150,0,0,0,150, + 0,0,0,56,10,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,216, + 216,216,1,219,219,219,1,218,218,218,2,219,219,219,3,217,217,217,1,218, + 218,218,1,255,255,255,1,218,218,218,2,169,169,169,1,217,217,217,1,216, + 216,216,1,169,169,169,1,218,218,218,1,219,219,219,1,217,217,217,1,215, + 215,215,1,217,217,217,1,220,220,220,1,216,216,216,1,219,219,219,1,216, + 216,216,1,219,219,219,1,221,221,221,1,216,216,216,1,219,219,219,1,217, + 217,217,1,254,254,254,1,220,220,220,1,217,217,217,1,219,219,219,1,218, + 218,218,2,217,217,217,2,220,220,220,1,219,219,219,1,218,218,218,3,220, + 220,220,1,218,218,218,2,220,220,220,1,218,218,218,9,219,219,219,1,218, + 218,218,1,217,217,217,2,218,218,218,2,219,219,219,1,217,217,217,2,219, + 219,219,2,215,215,215,1,221,221,221,1,217,217,217,2,219,219,219,1,218, + 218,218,1,217,217,217,1,218,218,218,1,216,216,216,1,221,221,221,1,219, + 219,219,1,218,218,218,1,217,217,217,1,219,219,219,1,254,254,254,2,255, + 255,255,1,167,167,167,1,219,219,219,1,255,255,255,1,218,218,218,1,255, + 255,255,1,253,253,253,1,218,218,218,1,167,167,167,2,255,255,255,1,254, + 254,254,1,255,255,255,1,216,216,216,1,171,171,171,1,217,217,217,2,218, + 218,218,1,255,255,255,1,217,217,217,1,169,169,169,1,216,216,216,1,220, + 220,220,1,216,216,216,1,253,253,253,1,255,255,255,1,218,218,218,1,217, + 217,217,2,255,255,255,1,216,216,216,1,218,218,218,1,219,219,219,1,218, + 218,218,1,217,217,217,1,219,219,219,1,218,218,218,9,220,220,220,1,167, + 167,167,1,165,165,165,1,169,169,169,1,217,217,217,1,219,219,219,1,217, + 217,217,1,218,218,218,15,221,221,221,1,216,216,216,1,218,218,218,1,221, + 221,221,1,213,213,213,2,219,219,219,2,218,218,218,1,255,255,255,1,216, + 216,216,1,219,219,219,3,217,217,217,1,218,218,218,2,215,215,215,1,218, + 218,218,1,223,223,223,1,219,219,219,1,218,218,218,3,219,219,219,1,220, + 220,220,1,212,212,212,1,223,223,223,1,218,218,218,1,168,168,168,1,255, + 255,255,1,215,215,215,1,218,218,218,1,219,219,219,1,218,218,218,1,217, + 217,217,1,220,220,220,2,215,215,215,2,217,217,217,1,216,216,216,1,219, + 219,219,1,217,217,217,2,216,216,216,1,217,217,217,1,218,218,218,9,216, + 216,216,1,219,219,219,1,221,221,221,1,220,220,220,1,216,216,216,1,221, + 221,221,1,214,214,214,1,220,220,220,1,218,218,218,1,220,220,220,1,216, + 216,216,1,219,219,219,1,218,218,218,1,217,217,217,1,218,218,218,1,220, + 220,220,2,218,218,218,1,220,220,220,1,218,218,218,1,215,215,215,1,217, + 217,217,1,215,215,215,1,222,222,222,1,216,216,216,1,255,255,255,2,252, + 252,252,1,218,218,218,1,255,255,255,1,253,253,253,2,252,252,252,1,255, + 255,255,2,170,170,170,1,168,168,168,1,254,254,254,1,255,255,255,1,251, + 251,251,1,218,218,218,1,220,220,220,1,216,216,216,1,223,223,223,1,217, + 217,217,1,253,253,253,1,218,218,218,1,167,167,167,1,217,217,217,1,218, + 218,218,1,219,219,219,1,255,255,255,1,250,250,250,1,218,218,218,1,219, + 219,219,2,252,252,252,1,255,255,255,1,218,218,218,1,215,215,215,1,219, + 219,219,1,218,218,218,1,217,217,217,1,218,218,218,9,219,219,219,1,168, + 168,168,2,171,171,171,1,167,167,167,2,219,219,219,1,217,217,217,1,218, + 218,218,14,217,217,217,1,218,218,218,1,217,217,217,2,220,220,220,1,222, + 222,222,1,220,220,220,1,217,217,217,1,218,218,218,1,220,220,220,1,255, + 255,255,1,216,216,216,2,254,254,254,1,224,224,224,1,215,215,215,1,219, + 219,219,1,217,217,217,1,174,174,174,1,212,212,212,1,218,218,218,1,169, + 169,169,1,216,216,216,1,220,220,220,1,218,218,218,1,217,217,217,1,221, + 221,221,1,216,216,216,1,213,213,213,1,221,221,221,1,218,218,218,2,217, + 217,217,1,220,220,220,1,168,168,168,1,219,219,219,1,218,218,218,1,215, + 215,215,1,221,221,221,2,219,219,219,1,217,217,217,1,220,220,220,1,217, + 217,217,1,221,221,221,1,220,220,220,1,217,217,217,1,218,218,218,9,219, + 219,219,1,217,217,217,1,215,215,215,1,216,216,216,1,218,218,218,1,217, + 217,217,1,220,220,220,1,215,215,215,1,216,216,216,1,220,220,220,1,215, + 215,215,1,218,218,218,2,220,220,220,1,214,214,214,1,217,217,217,1,215, + 215,215,1,218,218,218,3,220,220,220,1,216,216,216,1,222,222,222,1,213, + 213,213,1,219,219,219,1,216,216,216,1,252,252,252,1,255,255,255,1,218, + 218,218,1,253,253,253,1,223,223,223,1,218,218,218,1,253,253,253,1,255, + 255,255,1,216,216,216,2,220,220,220,1,216,216,216,2,255,255,255,1,219, + 219,219,1,217,217,217,1,219,219,219,1,214,214,214,1,217,217,217,1,255, + 255,255,1,221,221,221,1,168,168,168,2,219,219,219,1,218,218,218,1,216, + 216,216,1,221,221,221,1,217,217,217,2,255,255,255,1,253,253,253,2,220, + 220,220,1,219,219,219,1,217,217,217,1,219,219,219,1,218,218,218,1,217, + 217,217,1,218,218,218,8,216,216,216,1,220,220,220,1,169,169,169,1,165, + 165,165,1,166,166,166,1,170,170,170,1,167,167,167,1,170,170,170,1,218, + 218,218,15,220,220,220,1,218,218,218,1,216,216,216,1,219,219,219,1,216, + 216,216,1,212,212,212,1,218,218,218,1,217,217,217,1,218,218,218,1,169, + 169,169,1,217,217,217,1,221,221,221,1,216,216,216,1,214,214,214,1,221, + 221,221,1,214,214,214,1,221,221,221,1,215,215,215,1,220,220,220,1,221, + 221,221,1,219,219,219,1,218,218,218,2,220,220,220,1,216,216,216,1,168, + 168,168,1,255,255,255,1,219,219,219,1,217,217,217,1,220,220,220,1,218, + 218,218,2,170,170,170,1,166,166,166,1,215,215,215,1,219,219,219,2,217, + 217,217,1,215,215,215,1,220,220,220,1,219,219,219,1,217,217,217,1,215, + 215,215,1,217,217,217,2,216,216,216,1,218,218,218,9,216,216,216,1,219, + 219,219,1,220,220,220,2,218,218,218,2,217,217,217,1,221,221,221,1,218, + 218,218,1,217,217,217,1,219,219,219,2,218,218,218,2,220,220,220,1,219, + 219,219,1,217,217,217,1,218,218,218,2,220,220,220,1,214,214,214,1,221, + 221,221,1,219,219,219,1,220,220,220,1,216,216,216,1,219,219,219,1,216, + 216,216,1,221,221,221,1,215,215,215,1,222,222,222,1,216,216,216,1,217, + 217,217,1,218,218,218,1,255,255,255,1,254,254,254,1,214,214,214,1,222, + 222,222,1,216,216,216,1,219,219,219,1,217,217,217,3,221,221,221,2,219, + 219,219,1,254,254,254,1,218,218,218,1,216,216,216,1,170,170,170,1,167, + 167,167,1,168,168,168,1,219,219,219,1,217,217,217,1,220,220,220,1,217, + 217,217,1,219,219,219,1,255,255,255,1,253,253,253,1,252,252,252,1,218, + 218,218,1,221,221,221,1,216,216,216,1,220,220,220,1,218,218,218,9,220, + 220,220,1,217,217,217,2,221,221,221,1,168,168,168,1,171,171,171,1,166, + 166,166,1,216,216,216,1,218,218,218,14,217,217,217,1,216,216,216,1,220, + 220,220,1,218,218,218,1,217,217,217,1,222,222,222,1,220,220,220,1,216, + 216,216,1,220,220,220,1,167,167,167,2,219,219,219,1,217,217,217,1,222, + 222,222,1,217,217,217,1,216,216,216,1,255,255,255,1,220,220,220,1,219, + 219,219,1,255,255,255,1,164,164,164,1,217,217,217,1,219,219,219,1,216, + 216,216,1,217,217,217,1,219,219,219,1,215,215,215,1,219,219,219,1,217, + 217,217,1,215,215,215,1,218,218,218,1,217,217,217,1,255,255,255,1,215, + 215,215,1,220,220,220,1,217,217,217,1,221,221,221,1,217,217,217,1,216, + 216,216,1,221,221,221,1,214,214,214,1,220,220,220,1,217,217,217,1,221, + 221,221,1,219,219,219,1,218,218,218,1,220,220,220,2,218,218,218,8,222, + 222,222,1,214,214,214,1,217,217,217,1,218,218,218,1,217,217,217,1,218, + 218,218,1,217,217,217,1,168,168,168,1,217,217,217,1,218,218,218,1,219, + 219,219,1,216,216,216,2,218,218,218,1,169,169,169,1,217,217,217,1,220, + 220,220,1,218,218,218,1,214,214,214,1,220,220,220,2,215,215,215,1,218, + 218,218,1,216,216,216,1,219,219,219,1,218,218,218,1,219,219,219,1,216, + 216,216,1,218,218,218,1,217,217,217,1,216,216,216,1,170,170,170,1,253, + 253,253,1,218,218,218,1,220,220,220,1,218,218,218,3,219,219,219,1,217, + 217,217,1,221,221,221,1,218,218,218,1,163,163,163,1,221,221,221,1,218, + 218,218,1,254,254,254,1,255,255,255,1,220,220,220,1,216,216,216,1,168, + 168,168,1,216,216,216,2,217,217,217,1,220,220,220,1,216,216,216,1,219, + 219,219,1,253,253,253,1,255,255,255,2,254,254,254,1,216,216,216,1,219, + 219,219,1,215,215,215,1,220,220,220,1,218,218,218,9,217,217,217,1,219, + 219,219,1,214,214,214,1,219,219,219,1,216,216,216,1,220,220,220,2,218, + 218,218,16,220,220,220,1,215,215,215,1,216,216,216,1,218,218,218,1,215, + 215,215,1,220,220,220,1,255,255,255,1,214,214,214,1,171,171,171,1,219, + 219,219,1,165,165,165,1,167,167,167,1,170,170,170,1,169,169,169,1,218, + 218,218,1,216,216,216,2,219,219,219,3,218,218,218,1,219,219,219,1,255, + 255,255,1,220,220,220,1,218,218,218,1,219,219,219,1,221,221,221,1,217, + 217,217,1,219,219,219,1,253,253,253,1,255,255,255,1,166,166,166,1,221, + 221,221,1,214,214,214,1,216,216,216,1,219,219,219,2,216,216,216,1,220, + 220,220,1,219,219,219,1,217,217,217,1,219,219,219,1,217,217,217,2,219, + 219,219,1,215,215,215,1,218,218,218,8,216,216,216,1,220,220,220,1,217, + 217,217,2,221,221,221,1,218,218,218,1,215,215,215,1,217,217,217,1,219, + 219,219,1,218,218,218,1,217,217,217,1,219,219,219,1,215,215,215,1,221, + 221,221,1,216,216,216,2,215,215,215,1,219,219,219,2,218,218,218,1,217, + 217,217,1,218,218,218,1,217,217,217,1,220,220,220,1,219,219,219,1,218, + 218,218,2,216,216,216,1,219,219,219,1,221,221,221,1,217,217,217,1,218, + 218,218,2,166,166,166,1,217,217,217,1,166,166,166,1,216,216,216,1,222, + 222,222,1,218,218,218,1,219,219,219,1,167,167,167,1,169,169,169,2,167, + 167,167,2,217,217,217,1,255,255,255,1,254,254,254,1,255,255,255,1,219, + 219,219,3,223,223,223,1,214,214,214,1,169,169,169,1,167,167,167,2,219, + 219,219,1,254,254,254,1,255,255,255,1,219,219,219,1,220,220,220,1,216, + 216,216,1,219,219,219,1,218,218,218,8,220,220,220,1,217,217,217,1,220, + 220,220,1,218,218,218,1,216,216,216,1,169,169,169,1,217,217,217,1,216, + 216,216,1,218,218,218,14,219,219,219,1,216,216,216,1,218,218,218,1,219, + 219,219,1,222,222,222,1,215,215,215,1,220,220,220,1,254,254,254,1,255, + 255,255,1,219,219,219,1,216,216,216,1,218,218,218,1,219,219,219,1,218, + 218,218,1,220,220,220,1,166,166,166,1,168,168,168,2,255,255,255,1,220, + 220,220,1,215,215,215,1,218,218,218,1,217,217,217,1,218,218,218,1,219, + 219,219,1,216,216,216,2,219,219,219,1,214,214,214,1,218,218,218,4,216, + 216,216,1,217,217,217,1,219,219,219,1,220,220,220,1,217,217,217,2,219, + 219,219,1,220,220,220,1,211,211,211,1,223,223,223,1,216,216,216,1,217, + 217,217,1,218,218,218,1,221,221,221,1,220,220,220,1,218,218,218,11,217, + 217,217,2,255,255,255,1,215,215,215,1,219,219,219,1,216,216,216,1,218, + 218,218,1,220,220,220,1,216,216,216,1,255,255,255,1,217,217,217,2,221, + 221,221,1,220,220,220,1,215,215,215,1,218,218,218,1,222,222,222,1,215, + 215,215,1,219,219,219,1,168,168,168,1,166,166,166,1,168,168,168,2,218, + 218,218,2,220,220,220,1,252,252,252,1,215,215,215,1,221,221,221,1,218, + 218,218,1,168,168,168,1,220,220,220,1,221,221,221,1,215,215,215,1,217, + 217,217,1,218,218,218,1,217,217,217,1,218,218,218,1,167,167,167,2,170, + 170,170,1,167,167,167,1,218,218,218,1,221,221,221,1,254,254,254,1,216, + 216,216,1,221,221,221,1,167,167,167,1,215,215,215,1,214,214,214,1,167, + 167,167,1,173,173,173,1,217,217,217,2,219,219,219,1,253,253,253,1,254, + 254,254,1,220,220,220,1,215,215,215,1,221,221,221,1,216,216,216,1,218, + 218,218,8,215,215,215,1,220,220,220,1,215,215,215,1,218,218,218,1,222, + 222,222,1,216,216,216,1,219,219,219,1,220,220,220,1,218,218,218,15,217, + 217,217,1,220,220,220,1,216,216,216,1,218,218,218,1,221,221,221,1,216, + 216,216,1,220,220,220,1,252,252,252,1,218,218,218,1,255,255,255,1,254, + 254,254,1,255,255,255,2,216,216,216,1,220,220,220,1,218,218,218,2,167, + 167,167,1,168,168,168,1,217,217,217,1,220,220,220,1,218,218,218,2,167, + 167,167,1,169,169,169,1,219,219,219,1,218,218,218,1,217,217,217,1,220, + 220,220,1,217,217,217,1,255,255,255,1,218,218,218,3,219,219,219,1,217, + 217,217,1,218,218,218,1,219,219,219,1,217,217,217,1,167,167,167,1,171, + 171,171,1,218,218,218,1,217,217,217,1,221,221,221,1,217,217,217,3,218, + 218,218,8,220,220,220,1,217,217,217,1,218,218,218,1,220,220,220,1,216, + 216,216,1,217,217,217,1,220,220,220,1,218,218,218,1,219,219,219,2,217, + 217,217,1,219,219,219,1,217,217,217,2,220,220,220,1,217,217,217,2,220, + 220,220,1,217,217,217,2,218,218,218,1,166,166,166,1,169,169,169,1,168, + 168,168,3,218,218,218,1,217,217,217,1,218,218,218,1,220,220,220,2,253, + 253,253,1,219,219,219,1,252,252,252,1,218,218,218,1,217,217,217,1,219, + 219,219,1,220,220,220,1,253,253,253,1,255,255,255,1,219,219,219,1,216, + 216,216,1,221,221,221,1,166,166,166,1,218,218,218,1,219,219,219,1,216, + 216,216,1,219,219,219,1,220,220,220,1,216,216,216,1,217,217,217,1,222, + 222,222,1,215,215,215,1,255,255,255,1,216,216,216,1,255,255,255,1,220, + 220,220,1,215,215,215,1,255,255,255,2,250,250,250,1,223,223,223,1,252, + 252,252,1,255,255,255,1,218,218,218,9,219,219,219,1,216,216,216,1,255, + 255,255,1,217,217,217,1,219,219,219,1,217,217,217,1,218,218,218,16,217, + 217,217,3,219,219,219,2,218,218,218,1,217,217,217,1,219,219,219,1,216, + 216,216,1,219,219,219,1,220,220,220,1,217,217,217,1,255,255,255,1,254, + 254,254,1,255,255,255,1,219,219,219,2,166,166,166,1,219,219,219,1,168, + 168,168,1,218,218,218,1,220,220,220,1,218,218,218,1,169,169,169,1,166, + 166,166,1,218,218,218,1,217,217,217,1,218,218,218,1,217,217,217,1,219, + 219,219,1,217,217,217,1,218,218,218,1,219,219,219,1,216,216,216,1,219, + 219,219,3,215,215,215,1,169,169,169,1,167,167,167,1,171,171,171,1,165, + 165,165,1,218,218,218,5,220,220,220,1,217,217,217,1,221,221,221,1,216, + 216,216,1,218,218,218,2,219,219,219,3,218,218,218,1,217,217,217,1,221, + 221,221,1,214,214,214,1,220,220,220,1,216,216,216,1,220,220,220,2,217, + 217,217,1,218,218,218,1,216,216,216,1,218,218,218,1,219,219,219,2,218, + 218,218,1,216,216,216,1,222,222,222,1,217,217,217,1,219,219,219,1,255, + 255,255,1,219,219,219,1,216,216,216,1,220,220,220,1,167,167,167,1,221, + 221,221,1,217,217,217,2,219,219,219,1,167,167,167,1,170,170,170,1,253, + 253,253,1,168,168,168,1,169,169,169,1,218,218,218,1,217,217,217,1,220, + 220,220,1,167,167,167,1,217,217,217,1,255,255,255,1,216,216,216,1,219, + 219,219,1,218,218,218,1,169,169,169,1,218,218,218,1,217,217,217,1,222, + 222,222,1,167,167,167,1,216,216,216,1,170,170,170,1,216,216,216,1,254, + 254,254,1,255,255,255,1,218,218,218,1,217,217,217,1,220,220,220,1,219, + 219,219,1,218,218,218,1,254,254,254,1,255,255,255,3,253,253,253,1,255, + 255,255,2,217,217,217,1,218,218,218,2,217,217,217,1,221,221,221,1,215, + 215,215,1,220,220,220,1,255,255,255,1,254,254,254,1,216,216,216,1,221, + 221,221,1,217,217,217,1,218,218,218,1,219,219,219,1,218,218,218,1,219, + 219,219,1,217,217,217,1,219,219,219,1,217,217,217,2,221,221,221,1,216, + 216,216,1,217,217,217,2,219,219,219,1,218,218,218,1,220,220,220,1,216, + 216,216,1,219,219,219,1,218,218,218,1,220,220,220,1,221,221,221,1,220, + 220,220,1,216,216,216,2,218,218,218,2,168,168,168,1,219,219,219,1,216, + 216,216,1,218,218,218,1,217,217,217,1,218,218,218,1,222,222,222,1,215, + 215,215,1,254,254,254,1,255,255,255,1,221,221,221,1,218,218,218,3,251, + 251,251,1,255,255,255,1,220,220,220,1,167,167,167,1,220,220,220,1,221, + 221,221,1,213,213,213,1,223,223,223,1,215,215,215,1,218,218,218,1,219, + 219,219,1,216,216,216,1,217,217,217,1,218,218,218,1,219,219,219,1,216, + 216,216,1,255,255,255,2,216,216,216,1,215,215,215,1,221,221,221,1,217, + 217,217,1,218,218,218,2,219,219,219,1,217,217,217,2,215,215,215,1,219, + 219,219,1,218,218,218,3,219,219,219,1,166,166,166,2,219,219,219,1,218, + 218,218,1,216,216,216,1,220,220,220,2,216,216,216,1,217,217,217,3,218, + 218,218,1,222,222,222,1,217,217,217,1,216,216,216,1,218,218,218,1,217, + 217,217,1,172,172,172,1,163,163,163,1,167,167,167,1,217,217,217,1,218, + 218,218,2,254,254,254,1,255,255,255,1,166,166,166,1,221,221,221,1,165, + 165,165,1,219,219,219,1,165,165,165,1,168,168,168,1,167,167,167,2,218, + 218,218,1,217,217,217,1,220,220,220,1,218,218,218,1,219,219,219,1,168, + 168,168,1,216,216,216,1,217,217,217,1,255,255,255,1,219,219,219,1,168, + 168,168,1,164,164,164,1,217,217,217,1,218,218,218,1,214,214,214,1,169, + 169,169,1,172,172,172,1,167,167,167,1,253,253,253,1,220,220,220,1,255, + 255,255,1,218,218,218,1,217,217,217,2,218,218,218,1,216,216,216,1,222, + 222,222,1,253,253,253,1,220,220,220,1,217,217,217,1,255,255,255,1,252, + 252,252,2,219,219,219,1,218,218,218,1,216,216,216,1,255,255,255,3,252, + 252,252,1,253,253,253,1,220,220,220,2,218,218,218,1,216,216,216,1,217, + 217,217,2,218,218,218,1,215,215,215,1,219,219,219,1,215,215,215,1,221, + 221,221,1,216,216,216,1,220,220,220,1,215,215,215,1,221,221,221,1,218, + 218,218,1,220,220,220,1,217,217,217,1,215,215,215,1,219,219,219,1,216, + 216,216,1,217,217,217,1,216,216,216,2,214,214,214,1,220,220,220,1,222, + 222,222,1,214,214,214,1,218,218,218,2,167,167,167,1,223,223,223,1,220, + 220,220,1,217,217,217,1,216,216,216,1,217,217,217,1,218,218,218,1,255, + 255,255,1,216,216,216,1,255,255,255,1,217,217,217,1,218,218,218,1,221, + 221,221,1,255,255,255,2,215,215,215,1,219,219,219,1,218,218,218,1,215, + 215,215,1,221,221,221,1,214,214,214,1,219,219,219,2,216,216,216,1,220, + 220,220,1,218,218,218,1,219,219,219,1,214,214,214,1,255,255,255,4,215, + 215,215,1,167,167,167,1,219,219,219,1,216,216,216,1,217,217,217,1,218, + 218,218,1,217,217,217,1,219,219,219,1,218,218,218,1,217,217,217,1,220, + 220,220,1,216,216,216,1,217,217,217,1,219,219,219,1,170,170,170,1,171, + 171,171,1,219,219,219,1,217,217,217,1,218,218,218,1,219,219,219,1,218, + 218,218,1,219,219,219,1,218,218,218,1,220,220,220,1,217,217,217,2,219, + 219,219,1,216,216,216,1,220,220,220,1,216,216,216,1,171,171,171,1,169, + 169,169,1,167,167,167,1,171,171,171,1,218,218,218,1,255,255,255,3,218, + 218,218,1,169,169,169,1,214,214,214,1,219,219,219,1,255,255,255,2,170, + 170,170,1,217,217,217,1,255,255,255,1,219,219,219,1,216,216,216,1,219, + 219,219,1,255,255,255,1,253,253,253,1,170,170,170,1,219,219,219,1,254, + 254,254,2,253,253,253,1,219,219,219,1,216,216,216,1,224,224,224,1,253, + 253,253,1,255,255,255,2,216,216,216,1,218,218,218,1,220,220,220,1,218, + 218,218,1,212,212,212,1,220,220,220,1,222,222,222,1,218,218,218,1,216, + 216,216,1,222,222,222,1,216,216,216,1,218,218,218,1,217,217,217,1,220, + 220,220,1,219,219,219,1,255,255,255,1,222,222,222,1,216,216,216,1,218, + 218,218,1,221,221,221,1,254,254,254,1,214,214,214,1,217,217,217,1,220, + 220,220,2,218,218,218,1,217,217,217,1,216,216,216,1,218,218,218,1,219, + 219,219,1,218,218,218,2,220,220,220,1,217,217,217,1,168,168,168,1,218, + 218,218,1,221,221,221,1,218,218,218,1,217,217,217,1,218,218,218,1,217, + 217,217,1,218,218,218,1,220,220,220,1,219,219,219,1,220,220,220,1,224, + 224,224,1,221,221,221,1,219,219,219,2,218,218,218,1,220,220,220,1,214, + 214,214,1,255,255,255,1,219,219,219,1,167,167,167,1,171,171,171,1,215, + 215,215,1,217,217,217,1,218,218,218,1,220,220,220,1,215,215,215,1,220, + 220,220,1,217,217,217,1,218,218,218,1,216,216,216,1,222,222,222,1,216, + 216,216,2,217,217,217,1,254,254,254,1,218,218,218,1,216,216,216,1,222, + 222,222,1,219,219,219,1,216,216,216,1,220,220,220,1,219,219,219,1,216, + 216,216,1,219,219,219,1,216,216,216,1,219,219,219,1,218,218,218,1,220, + 220,220,1,217,217,217,2,216,216,216,1,213,213,213,1,219,219,219,2,220, + 220,220,1,219,219,219,1,216,216,216,1,222,222,222,1,217,217,217,1,218, + 218,218,1,220,220,220,1,217,217,217,1,216,216,216,1,219,219,219,1,255, + 255,255,1,254,254,254,1,216,216,216,1,215,215,215,1,218,218,218,1,217, + 217,217,1,221,221,221,1,216,216,216,1,217,217,217,1,219,219,219,2,215, + 215,215,1,218,218,218,1,219,219,219,1,217,217,217,1,220,220,220,1,221, + 221,221,1,252,252,252,1,218,218,218,1,215,215,215,1,222,222,222,1,217, + 217,217,1,215,215,215,1,219,219,219,1,216,216,216,1,255,255,255,1,217, + 217,217,1,255,255,255,1,217,217,217,1,254,254,254,2,252,252,252,2,219, + 219,219,1,216,216,216,2,223,223,223,1,217,217,217,2,220,220,220,1,250, + 250,250,1,222,222,222,1,255,255,255,3,216,216,216,1,220,220,220,1,217, + 217,217,1,254,254,254,2,216,216,216,1,169,169,169,1,170,170,170,1,218, + 218,218,1,169,169,169,1,172,172,172,1,217,217,217,1,218,218,218,1,216, + 216,216,1,220,220,220,1,212,212,212,1,221,221,221,2,215,215,215,1,220, + 220,220,1,165,165,165,1,217,217,217,1,215,215,215,1,218,218,218,1,168, + 168,168,1,217,217,217,1,216,216,216,1,222,222,222,1,218,218,218,1,217, + 217,217,1,216,216,216,1,215,215,215,1,221,221,221,1,222,222,222,1,216, + 216,216,1,219,219,219,1,215,215,215,1,218,218,218,1,215,215,215,1,220, + 220,220,1,216,216,216,1,219,219,219,1,214,214,214,1,217,217,217,1,220, + 220,220,1,218,218,218,2,216,216,216,1,219,219,219,1,216,216,216,2,217, + 217,217,1,215,215,215,1,216,216,216,1,220,220,220,1,218,218,218,1,217, + 217,217,1,220,220,220,1,218,218,218,1,253,253,253,1,169,169,169,1,167, + 167,167,1,218,218,218,1,222,222,222,1,218,218,218,1,217,217,217,1,220, + 220,220,1,217,217,217,1,218,218,218,1,220,220,220,1,216,216,216,2,220, + 220,220,1,218,218,218,2,220,220,220,2,219,219,219,1,215,215,215,1,219, + 219,219,3,216,216,216,1,218,218,218,1,217,217,217,1,220,220,220,1,213, + 213,213,1,218,218,218,1,217,217,217,1,220,220,220,1,218,218,218,2,255, + 255,255,1,217,217,217,1,220,220,220,1,216,216,216,1,218,218,218,1,220, + 220,220,1,215,215,215,1,218,218,218,1,216,216,216,2,220,220,220,1,218, + 218,218,1,217,217,217,1,255,255,255,1,253,253,253,1,222,222,222,2,217, + 217,217,1,219,219,219,1,218,218,218,1,217,217,217,1,220,220,220,1,215, + 215,215,1,218,218,218,1,220,220,220,1,219,219,219,1,218,218,218,1,216, + 216,216,1,219,219,219,1,253,253,253,1,222,222,222,1,217,217,217,2,218, + 218,218,1,167,167,167,1,219,219,219,1,170,170,170,2,254,254,254,1,218, + 218,218,1,215,215,215,1,218,218,218,1,220,220,220,1,253,253,253,1,255, + 255,255,1,218,218,218,1,221,221,221,1,219,219,219,1,218,218,218,1,217, + 217,217,1,168,168,168,1,218,218,218,1,222,222,222,1,218,218,218,1,167, + 167,167,1,215,215,215,2,217,217,217,1,220,220,220,1,168,168,168,1,217, + 217,217,1,219,219,219,1,218,218,218,1,170,170,170,1,215,215,215,1,219, + 219,219,1,215,215,215,1,167,167,167,1,217,217,217,1,218,218,218,2,220, + 220,220,1,218,218,218,1,222,222,222,1,217,217,217,3,219,219,219,1,220, + 220,220,2,222,222,222,1,217,217,217,1,170,170,170,1,253,253,253,1,218, + 218,218,2,220,220,220,1,218,218,218,1,220,220,220,1,217,217,217,1,219, + 219,219,1,215,215,215,1,220,220,220,1,218,218,218,1,216,216,216,1,220, + 220,220,1,255,255,255,1,215,215,215,1,220,220,220,1,218,218,218,1,219, + 219,219,1,220,220,220,1,216,216,216,1,218,218,218,1,220,220,220,1,217, + 217,217,1,219,219,219,1,218,218,218,1,217,217,217,1,219,219,219,2,218, + 218,218,3,216,216,216,1,217,217,217,1,255,255,255,2,216,216,216,1,224, + 224,224,1,215,215,215,2,216,216,216,1,218,218,218,1,220,220,220,1,217, + 217,217,1,218,218,218,2,219,219,219,1,220,220,220,1,217,217,217,1,170, + 170,170,1,217,217,217,1,216,216,216,1,215,215,215,1,223,223,223,1,218, + 218,218,2,217,217,217,3,220,220,220,1,218,218,218,2,222,222,222,1,218, + 218,218,1,219,219,219,1,217,217,217,1,215,215,215,1,221,221,221,1,218, + 218,218,1,215,215,215,1,221,221,221,1,215,215,215,1,221,221,221,1,215, + 215,215,1,217,217,217,1,221,221,221,1,219,219,219,1,217,217,217,1,219, + 219,219,1,218,218,218,1,216,216,216,1,218,218,218,2,214,214,214,1,216, + 216,216,1,217,217,217,1,218,218,218,2,217,217,217,1,219,219,219,1,218, + 218,218,1,217,217,217,1,216,216,216,1,219,219,219,1,217,217,217,1,221, + 221,221,1,213,213,213,1,255,255,255,2,253,253,253,1,255,255,255,2,219, + 219,219,1,215,215,215,1,219,219,219,1,212,212,212,1,171,171,171,1,168, + 168,168,1,169,169,169,1,170,170,170,1,163,163,163,1,221,221,221,1,218, + 218,218,1,221,221,221,1,214,214,214,1,217,217,217,1,220,220,220,1,255, + 255,255,2,168,168,168,1,170,170,170,1,166,166,166,1,169,169,169,1,171, + 171,171,1,222,222,222,1,216,216,216,1,217,217,217,3,220,220,220,1,255, + 255,255,1,216,216,216,1,168,168,168,1,219,219,219,1,255,255,255,1,220, + 220,220,1,219,219,219,1,167,167,167,1,168,168,168,1,217,217,217,1,167, + 167,167,1,217,217,217,2,218,218,218,1,255,255,255,1,216,216,216,1,253, + 253,253,1,254,254,254,1,215,215,215,1,169,169,169,1,168,168,168,1,218, + 218,218,1,168,168,168,1,217,217,217,1,216,216,216,1,218,218,218,1,217, + 217,217,2,216,216,216,1,218,218,218,1,215,215,215,1,217,217,217,1,222, + 222,222,1,215,215,215,1,167,167,167,1,218,218,218,2,216,216,216,1,220, + 220,220,1,219,219,219,1,217,217,217,1,219,219,219,1,217,217,217,1,169, + 169,169,1,218,218,218,1,217,217,217,1,219,219,219,2,218,218,218,1,217, + 217,217,1,219,219,219,1,218,218,218,1,221,221,221,1,217,217,217,1,218, + 218,218,1,217,217,217,2,216,216,216,1,168,168,168,1,222,222,222,1,220, + 220,220,1,219,219,219,1,215,215,215,1,220,220,220,1,216,216,216,1,221, + 221,221,1,217,217,217,1,215,215,215,1,219,219,219,1,166,166,166,1,220, + 220,220,2,218,218,218,1,219,219,219,1,214,214,214,1,219,219,219,1,222, + 222,222,1,219,219,219,1,216,216,216,1,219,219,219,1,216,216,216,1,221, + 221,221,1,216,216,216,2,221,221,221,1,214,214,214,1,222,222,222,1,215, + 215,215,1,218,218,218,1,217,217,217,1,220,220,220,1,218,218,218,1,216, + 216,216,1,221,221,221,1,218,218,218,1,216,216,216,1,218,218,218,1,221, + 221,221,1,216,216,216,1,214,214,214,1,221,221,221,1,217,217,217,2,221, + 221,221,2,218,218,218,1,217,217,217,1,219,219,219,1,217,217,217,2,222, + 222,222,1,218,218,218,1,219,219,219,1,217,217,217,1,219,219,219,1,216, + 216,216,1,255,255,255,2,254,254,254,1,255,255,255,1,251,251,251,1,218, + 218,218,1,252,252,252,1,255,255,255,1,219,219,219,1,221,221,221,1,166, + 166,166,1,169,169,169,1,165,165,165,1,170,170,170,2,165,165,165,1,169, + 169,169,1,218,218,218,1,217,217,217,1,222,222,222,1,254,254,254,2,217, + 217,217,1,167,167,167,1,255,255,255,1,218,218,218,1,220,220,220,1,214, + 214,214,1,217,217,217,1,216,216,216,1,221,221,221,2,216,216,216,1,254, + 254,254,1,217,217,217,1,219,219,219,1,169,169,169,1,218,218,218,1,219, + 219,219,1,216,216,216,1,217,217,217,1,170,170,170,1,166,166,166,1,170, + 170,170,1,168,168,168,1,219,219,219,1,220,220,220,1,214,214,214,1,255, + 255,255,3,218,218,218,1,255,255,255,1,218,218,218,3,219,219,219,2,218, + 218,218,1,221,221,221,1,218,218,218,1,219,219,219,1,218,218,218,1,220, + 220,220,1,218,218,218,1,220,220,220,1,215,215,215,1,220,220,220,1,217, + 217,217,1,221,221,221,1,217,217,217,2,218,218,218,1,214,214,214,1,219, + 219,219,3,167,167,167,1,166,166,166,1,223,223,223,1,214,214,214,1,219, + 219,219,1,218,218,218,3,217,217,217,2,220,220,220,1,215,215,215,1,220, + 220,220,2,218,218,218,1,217,217,217,1,167,167,167,1,220,220,220,1,216, + 216,216,1,218,218,218,2,221,221,221,1,214,214,214,1,219,219,219,1,255, + 255,255,1,218,218,218,1,214,214,214,1,222,222,222,1,215,215,215,1,220, + 220,220,1,216,216,216,1,221,221,221,1,218,218,218,1,215,215,215,1,220, + 220,220,1,217,217,217,1,219,219,219,1,218,218,218,1,215,215,215,1,219, + 219,219,2,218,218,218,1,220,220,220,1,215,215,215,1,219,219,219,1,217, + 217,217,1,220,220,220,1,216,216,216,1,217,217,217,1,220,220,220,1,216, + 216,216,2,220,220,220,1,217,217,217,2,219,219,219,1,220,220,220,1,215, + 215,215,1,220,220,220,1,218,218,218,1,217,217,217,1,218,218,218,1,217, + 217,217,1,219,219,219,1,218,218,218,3,217,217,217,2,218,218,218,1,220, + 220,220,1,218,218,218,1,217,217,217,1,219,219,219,1,216,216,216,1,219, + 219,219,2,218,218,218,1,220,220,220,1,219,219,219,1,217,217,217,1,254, + 254,254,2,255,255,255,1,254,254,254,1,218,218,218,1,169,169,169,1,166, + 166,166,1,170,170,170,1,166,166,166,1,170,170,170,1,168,168,168,1,166, + 166,166,1,169,169,169,1,219,219,219,1,218,218,218,1,255,255,255,2,254, + 254,254,1,217,217,217,1,220,220,220,1,217,217,217,1,221,221,221,1,217, + 217,217,1,252,252,252,1,220,220,220,1,255,255,255,3,218,218,218,1,168, + 168,168,1,167,167,167,1,255,255,255,1,217,217,217,1,168,168,168,1,217, + 217,217,1,219,219,219,1,168,168,168,1,169,169,169,1,217,217,217,1,255, + 255,255,1,220,220,220,1,167,167,167,1,217,217,217,1,255,255,255,2,216, + 216,216,1,255,255,255,1,221,221,221,1,216,216,216,1,218,218,218,2,216, + 216,216,1,217,217,217,1,220,220,220,1,217,217,217,1,218,218,218,1,217, + 217,217,1,220,220,220,1,253,253,253,1,218,218,218,1,219,219,219,1,216, + 216,216,1,217,217,217,1,220,220,220,1,218,218,218,1,222,222,222,1,218, + 218,218,1,253,253,253,1,218,218,218,6,217,217,217,1,216,216,216,1,217, + 217,217,1,220,220,220,1,255,255,255,2,220,220,220,1,217,217,217,1,254, + 254,254,1,221,221,221,1,216,216,216,1,167,167,167,1,218,218,218,1,221, + 221,221,1,218,218,218,1,217,217,217,1,218,218,218,1,169,169,169,1,168, + 168,168,1,215,215,215,1,221,221,221,1,217,217,217,1,218,218,218,1,219, + 219,219,1,218,218,218,16,216,216,216,1,217,217,217,1,219,219,219,2,218, + 218,218,2,217,217,217,1,220,220,220,1,219,219,219,1,216,216,216,1,218, + 218,218,1,219,219,219,1,217,217,217,1,218,218,218,2,217,217,217,1,218, + 218,218,8,217,217,217,1,219,219,219,1,218,218,218,3,219,219,219,1,218, + 218,218,2,219,219,219,1,216,216,216,1,219,219,219,2,254,254,254,1,255, + 255,255,2,254,254,254,1,255,255,255,2,216,216,216,1,170,170,170,1,167, + 167,167,1,168,168,168,1,170,170,170,1,166,166,166,1,219,219,219,1,216, + 216,216,1,169,169,169,1,167,167,167,1,216,216,216,1,220,220,220,1,215, + 215,215,1,255,255,255,1,218,218,218,1,220,220,220,1,217,217,217,1,216, + 216,216,1,222,222,222,1,169,169,169,1,216,216,216,1,255,255,255,1,217, + 217,217,2,169,169,169,1,254,254,254,1,218,218,218,1,255,255,255,2,165, + 165,165,1,169,169,169,1,168,168,168,2,166,166,166,1,169,169,169,1,219, + 219,219,1,169,169,169,2,218,218,218,1,215,215,215,1,220,220,220,1,219, + 219,219,1,216,216,216,1,220,220,220,1,216,216,216,1,219,219,219,1,218, + 218,218,8,217,217,217,1,220,220,220,1,217,217,217,1,218,218,218,1,219, + 219,219,1,216,216,216,1,217,217,217,1,255,255,255,1,254,254,254,1,222, + 222,222,1,215,215,215,1,218,218,218,2,219,219,219,1,220,220,220,1,222, + 222,222,1,217,217,217,1,215,215,215,1,218,218,218,1,165,165,165,1,220, + 220,220,1,216,216,216,1,218,218,218,1,255,255,255,1,219,219,219,1,169, + 169,169,1,217,217,217,1,212,212,212,1,220,220,220,2,217,217,217,2,216, + 216,216,1,223,223,223,1,215,215,215,1,218,218,218,1,221,221,221,1,216, + 216,216,1,218,218,218,16,220,220,220,1,221,221,221,1,219,219,219,1,215, + 215,215,1,217,217,217,1,218,218,218,1,221,221,221,1,216,216,216,1,218, + 218,218,1,221,221,221,1,219,219,219,1,217,217,217,3,220,220,220,2,218, + 218,218,8,221,221,221,1,215,215,215,1,219,219,219,1,220,220,220,1,216, + 216,216,1,217,217,217,3,219,219,219,1,220,220,220,1,214,214,214,1,221, + 221,221,1,215,215,215,1,219,219,219,1,253,253,253,1,255,255,255,2,253, + 253,253,2,255,255,255,2,252,252,252,1,255,255,255,1,218,218,218,1,217, + 217,217,1,169,169,169,1,168,168,168,2,218,218,218,2,222,222,222,1,215, + 215,215,1,218,218,218,1,215,215,215,1,219,219,219,2,166,166,166,1,163, + 163,163,1,169,169,169,1,219,219,219,1,255,255,255,1,217,217,217,1,216, + 216,216,1,221,221,221,1,253,253,253,1,220,220,220,1,249,249,249,1,255, + 255,255,1,164,164,164,1,171,171,171,1,168,168,168,1,221,221,221,1,217, + 217,217,1,167,167,167,3,220,220,220,1,218,218,218,1,217,217,217,4,219, + 219,219,1,217,217,217,1,218,218,218,10,219,219,219,1,217,217,217,1,220, + 220,220,1,218,218,218,1,222,222,222,1,215,215,215,1,221,221,221,1,212, + 212,212,1,218,218,218,1,219,219,219,1,216,216,216,1,219,219,219,1,214, + 214,214,1,219,219,219,1,218,218,218,1,220,220,220,1,219,219,219,1,217, + 217,217,2,221,221,221,1,167,167,167,1,254,254,254,1,165,165,165,1,170, + 170,170,1,218,218,218,1,224,224,224,1,213,213,213,1,255,255,255,2,253, + 253,253,1,220,220,220,1,217,217,217,1,219,219,219,1,218,218,218,1,217, + 217,217,1,221,221,221,1,218,218,218,16,217,217,217,1,213,213,213,1,217, + 217,217,1,222,222,222,1,218,218,218,1,214,214,214,1,221,221,221,1,216, + 216,216,1,215,215,215,1,218,218,218,1,215,215,215,1,219,219,219,1,222, + 222,222,1,217,217,217,1,216,216,216,1,218,218,218,9,213,213,213,1,221, + 221,221,1,218,218,218,1,217,217,217,1,219,219,219,2,216,216,216,1,221, + 221,221,1,214,214,214,1,218,218,218,1,221,221,221,1,218,218,218,2,219, + 219,219,1,217,217,217,1,219,219,219,1,253,253,253,1,255,255,255,2,253, + 253,253,1,255,255,255,1,253,253,253,1,255,255,255,2,216,216,216,1,219, + 219,219,1,168,168,168,1,216,216,216,1,223,223,223,1,215,215,215,1,165, + 165,165,1,220,220,220,1,219,219,219,1,217,217,217,1,220,220,220,1,254, + 254,254,1,219,219,219,1,171,171,171,1,169,169,169,1,168,168,168,1,217, + 217,217,1,169,169,169,1,219,219,219,1,167,167,167,1,170,170,170,1,216, + 216,216,1,255,255,255,1,254,254,254,1,220,220,220,1,217,217,217,1,253, + 253,253,1,218,218,218,1,219,219,219,1,216,216,216,1,169,169,169,1,170, + 170,170,1,165,165,165,1,170,170,170,1,217,217,217,1,218,218,218,1,220, + 220,220,1,222,222,222,1,214,214,214,1,220,220,220,1,218,218,218,8,217, + 217,217,1,216,216,216,1,220,220,220,1,167,167,167,1,218,218,218,1,219, + 219,219,1,213,213,213,1,222,222,222,1,216,216,216,2,223,223,223,1,219, + 219,219,1,217,217,217,1,220,220,220,1,169,169,169,1,167,167,167,1,220, + 220,220,1,252,252,252,1,219,219,219,1,220,220,220,1,218,218,218,1,215, + 215,215,1,168,168,168,1,224,224,224,1,167,167,167,2,217,217,217,1,216, + 216,216,1,171,171,171,1,167,167,167,1,166,166,166,1,218,218,218,2,217, + 217,217,1,219,219,219,1,218,218,218,1,217,217,217,2,218,218,218,16,219, + 219,219,1,222,222,222,1,218,218,218,1,215,215,215,1,220,220,220,1,219, + 219,219,1,216,216,216,1,218,218,218,1,221,221,221,1,219,219,219,1,218, + 218,218,2,219,219,219,1,217,217,217,2,219,219,219,1,218,218,218,8,219, + 219,219,1,217,217,217,2,220,220,220,1,214,214,214,1,218,218,218,1,217, + 217,217,2,222,222,222,1,217,217,217,1,168,168,168,1,166,166,166,1,168, + 168,168,1,170,170,170,1,217,217,217,1,216,216,216,1,215,215,215,1,222, + 222,222,1,219,219,219,1,217,217,217,1,168,168,168,1,255,255,255,1,254, + 254,254,1,255,255,255,1,222,222,222,1,217,217,217,1,168,168,168,2,171, + 171,171,1,215,215,215,1,220,220,220,1,217,217,217,1,220,220,220,1,219, + 219,219,1,253,253,253,1,217,217,217,1,220,220,220,1,214,214,214,1,168, + 168,168,2,220,220,220,1,217,217,217,1,168,168,168,1,169,169,169,1,217, + 217,217,1,168,168,168,1,218,218,218,2,255,255,255,1,216,216,216,1,255, + 255,255,3,218,218,218,1,170,170,170,1,164,164,164,1,168,168,168,1,217, + 217,217,1,170,170,170,1,219,219,219,1,218,218,218,1,214,214,214,1,218, + 218,218,1,217,217,217,1,218,218,218,8,221,221,221,1,218,218,218,2,216, + 216,216,1,219,219,219,1,217,217,217,1,222,222,222,1,216,216,216,1,220, + 220,220,1,218,218,218,2,215,215,215,1,217,217,217,1,220,220,220,1,218, + 218,218,1,216,216,216,1,219,219,219,1,218,218,218,1,217,217,217,1,216, + 216,216,1,255,255,255,1,219,219,219,1,218,218,218,1,214,214,214,1,168, + 168,168,1,170,170,170,1,218,218,218,2,169,169,169,3,220,220,220,1,218, + 218,218,2,219,219,219,1,216,216,216,1,218,218,218,1,221,221,221,1,218, + 218,218,16,216,216,216,2,219,219,219,1,218,218,218,1,215,215,215,1,220, + 220,220,1,217,217,217,1,219,219,219,1,217,217,217,1,216,216,216,1,221, + 221,221,1,218,218,218,1,215,215,215,1,220,220,220,2,217,217,217,1,218, + 218,218,8,220,220,220,1,215,215,215,1,219,219,219,1,216,216,216,1,218, + 218,218,1,221,221,221,1,218,218,218,2,166,166,166,1,164,164,164,1,222, + 222,222,1,166,166,166,1,214,214,214,1,169,169,169,1,216,216,216,1,220, + 220,220,1,218,218,218,1,220,220,220,1,213,213,213,1,168,168,168,1,220, + 220,220,1,167,167,167,1,252,252,252,1,254,254,254,1,214,214,214,1,169, + 169,169,1,167,167,167,1,170,170,170,1,251,251,251,1,220,220,220,1,219, + 219,219,2,216,216,216,1,218,218,218,1,255,255,255,1,221,221,221,1,213, + 213,213,1,224,224,224,1,223,223,223,1,216,216,216,1,217,217,217,4,170, + 170,170,1,219,219,219,1,216,216,216,1,218,218,218,1,217,217,217,1,218, + 218,218,1,255,255,255,2,253,253,253,1,219,219,219,1,216,216,216,1,222, + 222,222,1,216,216,216,1,219,219,219,1,218,218,218,1,166,166,166,1,216, + 216,216,1,218,218,218,1,222,222,222,1,218,218,218,9,216,216,216,1,253, + 253,253,1,218,218,218,1,224,224,224,1,216,216,216,1,221,221,221,1,219, + 219,219,1,218,218,218,1,217,217,217,2,218,218,218,1,217,217,217,1,218, + 218,218,2,217,217,217,1,220,220,220,1,217,217,217,1,220,220,220,1,217, + 217,217,1,218,218,218,1,255,255,255,1,214,214,214,1,218,218,218,1,220, + 220,220,1,171,171,171,1,215,215,215,1,255,255,255,2,213,213,213,1,171, + 171,171,1,166,166,166,1,217,217,217,1,218,218,218,1,217,217,217,1,219, + 219,219,1,220,220,220,2,216,216,216,1,218,218,218,16,219,219,219,1,217, + 217,217,1,220,220,220,1,219,219,219,1,217,217,217,1,219,219,219,1,218, + 218,218,1,217,217,217,1,220,220,220,1,215,215,215,1,218,218,218,1,219, + 219,219,1,218,218,218,1,219,219,219,1,218,218,218,1,217,217,217,1,218, + 218,218,8,216,216,216,1,221,221,221,1,213,213,213,1,221,221,221,1,217, + 217,217,1,216,216,216,1,168,168,168,1,218,218,218,1,255,255,255,1,224, + 224,224,1,214,214,214,1,255,255,255,1,170,170,170,1,216,216,216,1,217, + 217,217,1,220,220,220,1,219,219,219,1,212,212,212,1,255,255,255,1,168, + 168,168,1,215,215,215,1,170,170,170,1,219,219,219,1,255,255,255,1,219, + 219,219,1,255,255,255,1,254,254,254,1,216,216,216,1,220,220,220,1,215, + 215,215,1,218,218,218,1,216,216,216,1,219,219,219,1,255,255,255,3,219, + 219,219,1,213,213,213,1,217,217,217,1,218,218,218,1,254,254,254,1,255, + 255,255,1,171,171,171,1,219,219,219,1,254,254,254,1,255,255,255,1,215, + 215,215,1,255,255,255,1,222,222,222,1,215,215,215,1,216,216,216,1,255, + 255,255,2,253,253,253,1,255,255,255,1,214,214,214,1,255,255,255,1,215, + 215,215,1,218,218,218,1,220,220,220,1,222,222,222,1,217,217,217,3,218, + 218,218,8,221,221,221,1,220,220,220,2,216,216,216,4,219,219,219,1,218, + 218,218,1,221,221,221,2,219,219,219,2,218,218,218,1,219,219,219,1,217, + 217,217,1,216,216,216,1,222,222,222,1,218,218,218,2,252,252,252,1,222, + 222,222,1,254,254,254,1,255,255,255,1,217,217,217,1,219,219,219,1,253, + 253,253,1,218,218,218,2,168,168,168,1,169,169,169,1,217,217,217,1,220, + 220,220,1,218,218,218,1,216,216,216,2,217,217,217,1,219,219,219,1,218, + 218,218,17,220,220,220,1,214,214,214,1,220,220,220,1,218,218,218,1,166, + 166,166,1,170,170,170,1,218,218,218,1,215,215,215,1,223,223,223,1,217, + 217,217,2,219,219,219,1,214,214,214,1,218,218,218,1,220,220,220,1,218, + 218,218,9,220,220,220,1,217,217,217,1,218,218,218,1,222,222,222,1,216, + 216,216,1,253,253,253,1,255,255,255,1,216,216,216,1,253,253,253,1,218, + 218,218,2,217,217,217,1,218,218,218,1,219,219,219,1,217,217,217,1,218, + 218,218,1,255,255,255,1,218,218,218,1,255,255,255,1,221,221,221,1,167, + 167,167,1,251,251,251,1,217,217,217,1,252,252,252,1,254,254,254,1,220, + 220,220,1,218,218,218,1,217,217,217,1,218,218,218,1,220,220,220,2,218, + 218,218,1,254,254,254,2,255,255,255,2,216,216,216,1,255,255,255,4,250, + 250,250,1,167,167,167,1,253,253,253,1,255,255,255,1,220,220,220,1,252, + 252,252,1,165,165,165,1,170,170,170,1,218,218,218,1,255,255,255,1,253, + 253,253,1,255,255,255,1,216,216,216,1,171,171,171,1,216,216,216,1,255, + 255,255,1,220,220,220,1,218,218,218,1,215,215,215,1,220,220,220,1,217, + 217,217,1,219,219,219,1,218,218,218,9,215,215,215,1,219,219,219,1,216, + 216,216,1,221,221,221,1,220,220,220,2,217,217,217,2,218,218,218,1,216, + 216,216,2,217,217,217,1,219,219,219,1,218,218,218,1,217,217,217,1,219, + 219,219,1,216,216,216,2,220,220,220,1,255,255,255,1,254,254,254,1,255, + 255,255,1,216,216,216,1,218,218,218,1,219,219,219,2,218,218,218,1,220, + 220,220,1,167,167,167,1,170,170,170,1,217,217,217,1,219,219,219,1,217, + 217,217,1,219,219,219,1,220,220,220,1,217,217,217,1,218,218,218,17,217, + 217,217,1,220,220,220,1,217,217,217,1,219,219,219,1,217,217,217,1,167, + 167,167,1,168,168,168,2,170,170,170,1,216,216,216,1,219,219,219,1,217, + 217,217,1,220,220,220,1,215,215,215,1,222,222,222,1,216,216,216,1,218, + 218,218,8,217,217,217,1,218,218,218,1,219,219,219,1,217,217,217,1,253, + 253,253,1,220,220,220,1,218,218,218,1,255,255,255,2,219,219,219,1,255, + 255,255,1,217,217,217,1,219,219,219,1,218,218,218,3,217,217,217,1,255, + 255,255,1,216,216,216,1,253,253,253,1,218,218,218,2,255,255,255,1,219, + 219,219,1,218,218,218,1,220,220,220,1,217,217,217,2,218,218,218,2,217, + 217,217,2,218,218,218,1,217,217,217,1,255,255,255,1,216,216,216,1,254, + 254,254,1,220,220,220,1,217,217,217,1,218,218,218,1,254,254,254,1,255, + 255,255,1,169,169,169,1,220,220,220,1,218,218,218,2,217,217,217,1,219, + 219,219,1,168,168,168,1,169,169,169,1,218,218,218,1,219,219,219,1,217, + 217,217,1,219,219,219,2,167,167,167,1,219,219,219,1,215,215,215,1,217, + 217,217,1,220,220,220,1,218,218,218,2,219,219,219,1,218,218,218,9,219, + 219,219,1,217,217,217,1,218,218,218,1,219,219,219,1,217,217,217,2,219, + 219,219,1,218,218,218,1,219,219,219,1,217,217,217,2,220,220,220,1,219, + 219,219,1,216,216,216,1,217,217,217,1,218,218,218,1,219,219,219,1,218, + 218,218,1,217,217,217,1,254,254,254,1,221,221,221,1,218,218,218,1,219, + 219,219,1,217,217,217,2,254,254,254,1,218,218,218,1,221,221,221,1,215, + 215,215,1,169,169,169,1,168,168,168,1,217,217,217,2,218,218,218,1,220, + 220,220,1,218,218,218,1,217,217,217,1,218,218,218,1,217,217,217,1,223, + 223,223,1,215,215,215,1,218,218,218,1,219,219,219,1,218,218,218,1,217, + 217,217,1,218,218,218,3,217,217,217,2,219,219,219,1,220,220,220,1,216, + 216,216,1,220,220,220,1,218,218,218,1,219,219,219,1,217,217,217,1,255, + 255,255,2,171,171,171,1,166,166,166,1,168,168,168,1,169,169,169,1,168, + 168,168,1,169,169,169,1,217,217,217,1,220,220,220,1,219,219,219,1,217, + 217,217,1,219,219,219,2,218,218,218,1,217,217,217,2,221,221,221,1,217, + 217,217,1,219,219,219,2,220,220,220,1,217,217,217,1,218,218,218,2,217, + 217,217,1,219,219,219,1,218,218,218,1,216,216,216,1,219,219,219,1,255, + 255,255,1,219,219,219,1,217,217,217,2,218,218,218,1,216,216,216,1,219, + 219,219,2,218,218,218,1,216,216,216,1,255,255,255,1,167,167,167,1,218, + 218,218,1,170,170,170,1,217,217,217,1,219,219,219,1,218,218,218,2,216, + 216,216,1,220,220,220,1,216,216,216,1,219,219,219,1,217,217,217,2,218, + 218,218,1,219,219,219,1,255,255,255,1,216,216,216,1,217,217,217,1,222, + 222,222,1,217,217,217,1,218,218,218,1,255,255,255,1,216,216,216,1,221, + 221,221,1,217,217,217,1,216,216,216,1,255,255,255,2,218,218,218,3,219, + 219,219,1,215,215,215,1,255,255,255,1,219,219,219,1,217,217,217,1,218, + 218,218,17,219,219,219,1,217,217,217,1,218,218,218,2,217,217,217,1,218, + 218,218,1,217,217,217,1,218,218,218,6,220,220,220,1,217,217,217,1,216, + 216,216,1,255,255,255,1,220,220,220,1,218,218,218,1,216,216,216,1,215, + 215,215,1,217,217,217,1,218,218,218,1,255,255,255,2,253,253,253,1,252, + 252,252,1,255,255,255,1,167,167,167,1,216,216,216,1,222,222,222,1,221, + 221,221,1,214,214,214,1,218,218,218,1,217,217,217,1,216,216,216,1,220, + 220,220,1,216,216,216,1,218,218,218,1,220,220,220,1,218,218,218,1,217, + 217,217,1,220,220,220,1,216,216,216,1,219,219,219,1,218,218,218,1,215, + 215,215,1,222,222,222,1,219,219,219,1,214,214,214,1,220,220,220,1,219, + 219,219,1,216,216,216,1,218,218,218,2,220,220,220,1,251,251,251,1,252, + 252,252,1,220,220,220,1,216,216,216,1,170,170,170,1,166,166,166,1,219, + 219,219,1,220,220,220,1,214,214,214,1,218,218,218,1,221,221,221,1,215, + 215,215,1,219,219,219,1,217,217,217,1,219,219,219,1,220,220,220,1,218, + 218,218,1,215,215,215,1,218,218,218,1,215,215,215,1,217,217,217,2,218, + 218,218,1,219,219,219,1,217,217,217,1,220,220,220,1,166,166,166,1,167, + 167,167,1,221,221,221,1,217,217,217,1,219,219,219,1,216,216,216,1,220, + 220,220,1,212,212,212,1,219,219,219,1,220,220,220,1,218,218,218,1,216, + 216,216,1,218,218,218,1,255,255,255,1,216,216,216,1,219,219,219,1,215, + 215,215,1,218,218,218,1,217,217,217,2,218,218,218,1,220,220,220,1,221, + 221,221,1,217,217,217,1,220,220,220,1,219,219,219,1,218,218,218,1,221, + 221,221,1,251,251,251,1,221,221,221,1,254,254,254,1,220,220,220,1,218, + 218,218,1,212,212,212,1,219,219,219,1,254,254,254,1,218,218,218,1,220, + 220,220,1,214,214,214,1,218,218,218,1,220,220,220,1,254,254,254,1,253, + 253,253,1,219,219,219,1,215,215,215,1,218,218,218,2,221,221,221,1,253, + 253,253,1,217,217,217,2,218,218,218,16,216,216,216,1,220,220,220,1,217, + 217,217,1,222,222,222,1,219,219,219,1,216,216,216,1,219,219,219,1,220, + 220,220,1,218,218,218,6,219,219,219,2,218,218,218,1,220,220,220,1,215, + 215,215,1,216,216,216,1,222,222,222,1,220,220,220,1,217,217,217,1,220, + 220,220,1,253,253,253,2,220,220,220,1,255,255,255,1,253,253,253,1,219, + 219,219,1,221,221,221,1,214,214,214,1,216,216,216,1,221,221,221,1,220, + 220,220,1,216,216,216,1,220,220,220,1,217,217,217,1,220,220,220,1,216, + 216,216,1,215,215,215,1,222,222,222,1,219,219,219,1,218,218,218,1,216, + 216,216,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,221, + 221,221,1,217,217,217,3,219,219,219,1,217,217,217,1,218,218,218,1,216, + 216,216,1,255,255,255,2,214,214,214,1,222,222,222,1,217,217,217,2,219, + 219,219,1,217,217,217,1,219,219,219,2,217,217,217,1,219,219,219,1,218, + 218,218,5,220,220,220,1,216,216,216,1,224,224,224,1,219,219,219,1,218, + 218,218,3,217,217,217,1,218,218,218,1,169,169,169,1,168,168,168,1,220, + 220,220,1,221,221,221,1,212,212,212,1,220,220,220,1,221,221,221,1,218, + 218,218,1,219,219,219,1,216,216,216,1,218,218,218,1,215,215,215,1,219, + 219,219,1,255,255,255,1,250,250,250,1,255,255,255,1,219,219,219,1,216, + 216,216,1,220,220,220,2,217,217,217,2,214,214,214,1,219,219,219,1,218, + 218,218,1,215,215,215,1,221,221,221,1,217,217,217,1,219,219,219,1,216, + 216,216,1,218,218,218,2,220,220,220,1,217,217,217,1,220,220,220,1,221, + 221,221,1,218,218,218,1,217,217,217,1,219,219,219,1,217,217,217,1,219, + 219,219,1,217,217,217,1,220,220,220,1,215,215,215,1,220,220,220,1,216, + 216,216,1,221,221,221,1,213,213,213,1,219,219,219,1,220,220,220,1,218, + 218,218,17,219,219,219,1,216,216,216,1,220,220,220,1,213,213,213,1,219, + 219,219,1,220,220,220,1,218,218,218,1,215,215,215,1,218,218,218,6,214, + 214,214,1,220,220,220,1,217,217,217,1,218,218,218,1,221,221,221,1,218, + 218,218,1,217,217,217,1,216,216,216,1,218,218,218,1,219,219,219,2,220, + 220,220,1,166,166,166,1,217,217,217,1,222,222,222,1,215,215,215,1,217, + 217,217,1,219,219,219,1,218,218,218,1,222,222,222,1,212,212,212,1,221, + 221,221,1,218,218,218,2,219,219,219,1,217,217,217,1,220,220,220,1,216, + 216,216,3,217,217,217,1,218,218,218,1,168,168,168,2,218,218,218,1,214, + 214,214,1,219,219,219,1,217,217,217,1,222,222,222,1,217,217,217,1,220, + 220,220,1,217,217,217,1,219,219,219,1,253,253,253,1,255,255,255,1,217, + 217,217,2,167,167,167,1,221,221,221,1,216,216,216,1,220,220,220,1,217, + 217,217,1,215,215,215,1,216,216,216,1,220,220,220,1,218,218,218,1,221, + 221,221,1,216,216,216,1,217,217,217,1,219,219,219,1,216,216,216,1,220, + 220,220,1,215,215,215,1,217,217,217,1,219,219,219,3,255,255,255,2,215, + 215,215,1,219,219,219,1,217,217,217,2,221,221,221,1,217,217,217,1,215, + 215,215,1,222,222,222,1,218,218,218,1,215,215,215,1,219,219,219,2,216, + 216,216,1,217,217,217,1,220,220,220,1,216,216,216,1,221,221,221,1,217, + 217,217,2,219,219,219,1,218,218,218,1,219,219,219,1,218,218,218,1,221, + 221,221,1,217,217,217,2,218,218,218,1,217,217,217,2,221,221,221,1,218, + 218,218,1,216,216,216,1,215,215,215,1,221,221,221,1,217,217,217,1,216, + 216,216,1,218,218,218,1,216,216,216,1,221,221,221,1,216,216,216,1,219, + 219,219,2,215,215,215,1,220,220,220,1,219,219,219,1,218,218,218,1,219, + 219,219,1,218,218,218,1,219,219,219,1,217,217,217,2,218,218,218,17,217, + 217,217,1,223,223,223,1,216,216,216,1,217,217,217,2,219,219,219,1,220, + 220,220,1,218,218,218,6,220,220,220,1,218,218,218,1,217,217,217,1,218, + 218,218,1,216,216,216,1,219,219,219,1,217,217,217,1,219,219,219,1,220, + 220,220,1,215,215,215,1,252,252,252,1,215,215,215,1,219,219,219,1,167, + 167,167,2,169,169,169,1,166,166,166,1,171,171,171,1,167,167,167,1,216, + 216,216,1,217,217,217,1,218,218,218,1,217,217,217,1,221,221,221,1,218, + 218,218,1,216,216,216,1,219,219,219,1,218,218,218,2,223,223,223,1,217, + 217,217,1,219,219,219,1,168,168,168,1,170,170,170,1,219,219,219,2,221, + 221,221,1,218,218,218,1,217,217,217,4,220,220,220,1,251,251,251,1,255, + 255,255,3,220,220,220,1,218,218,218,1,217,217,217,1,216,216,216,1,218, + 218,218,1,222,222,222,1,221,221,221,1,215,215,215,1,218,218,218,1,217, + 217,217,2,218,218,218,2,221,221,221,1,217,217,217,1,222,222,222,1,218, + 218,218,1,219,219,219,1,165,165,165,1,170,170,170,1,253,253,253,1,255, + 255,255,1,219,219,219,1,218,218,218,2,216,216,216,1,220,220,220,1,215, + 215,215,1,217,217,217,1,218,218,218,1,216,216,216,1,219,219,219,1,218, + 218,218,1,221,221,221,1,215,215,215,1,220,220,220,1,218,218,218,2,217, + 217,217,1,220,220,220,2,216,216,216,1,219,219,219,2,220,220,220,1,214, + 214,214,1,217,217,217,1,222,222,222,1,216,216,216,1,220,220,220,1,216, + 216,216,1,215,215,215,1,219,219,219,2,218,218,218,1,217,217,217,1,218, + 218,218,1,169,169,169,1,219,219,219,1,221,221,221,1,214,214,214,1,219, + 219,219,1,216,216,216,2,221,221,221,1,214,214,214,1,220,220,220,1,217, + 217,217,1,216,216,216,1,218,218,218,2,215,215,215,1,222,222,222,1,218, + 218,218,16,217,217,217,1,219,219,219,1,214,214,214,1,222,222,222,1,219, + 219,219,1,216,216,216,1,218,218,218,1,220,220,220,1,218,218,218,8,217, + 217,217,1,218,218,218,1,219,219,219,1,218,218,218,1,219,219,219,2,215, + 215,215,1,222,222,222,1,255,255,255,2,219,219,219,1,220,220,220,1,217, + 217,217,1,167,167,167,2,169,169,169,1,168,168,168,1,169,169,169,1,219, + 219,219,1,215,215,215,1,223,223,223,1,215,215,215,1,217,217,217,1,221, + 221,221,1,220,220,220,1,216,216,216,1,218,218,218,1,215,215,215,1,255, + 255,255,2,167,167,167,2,218,218,218,2,213,213,213,1,219,219,219,1,216, + 216,216,1,220,220,220,1,219,219,219,1,218,218,218,1,220,220,220,1,255, + 255,255,1,254,254,254,1,255,255,255,1,218,218,218,1,216,216,216,1,218, + 218,218,1,220,220,220,2,218,218,218,1,214,214,214,1,219,219,219,2,220, + 220,220,1,219,219,219,2,218,218,218,1,216,216,216,1,219,219,219,1,215, + 215,215,1,218,218,218,1,219,219,219,2,171,171,171,1,166,166,166,1,220, + 220,220,1,216,216,216,1,219,219,219,1,218,218,218,2,220,220,220,1,219, + 219,219,2,221,221,221,1,218,218,218,2,216,216,216,1,219,219,219,1,218, + 218,218,4,220,220,220,2,215,215,215,1,216,216,216,1,218,218,218,2,217, + 217,217,1,214,214,214,1,223,223,223,1,216,216,216,1,219,219,219,1,218, + 218,218,1,217,217,217,1,218,218,218,1,221,221,221,1,220,220,220,1,216, + 216,216,1,221,221,221,1,169,169,169,1,217,217,217,1,167,167,167,1,220, + 220,220,1,213,213,213,1,169,169,169,1,168,168,168,1,169,169,169,1,221, + 221,221,1,217,217,217,2,222,222,222,1,215,215,215,1,221,221,221,1,218, + 218,218,1,215,215,215,1,222,222,222,1,214,214,214,1,218,218,218,16,219, + 219,219,1,217,217,217,1,220,220,220,1,217,217,217,1,219,219,219,2,217, + 217,217,1,215,215,215,1,218,218,218,7,217,217,217,1,216,216,216,1,221, + 221,221,1,168,168,168,1,167,167,167,1,216,216,216,1,166,166,166,1,219, + 219,219,1,217,217,217,1,216,216,216,1,251,251,251,1,255,255,255,1,251, + 251,251,1,255,255,255,1,221,221,221,1,219,219,219,1,167,167,167,1,166, + 166,166,1,170,170,170,1,167,167,167,1,170,170,170,1,167,167,167,1,219, + 219,219,1,170,170,170,1,164,164,164,2,221,221,221,1,219,219,219,1,221, + 221,221,1,255,255,255,1,254,254,254,1,219,219,219,1,169,169,169,1,217, + 217,217,1,219,219,219,1,222,222,222,1,218,218,218,1,215,215,215,1,219, + 219,219,1,216,216,216,1,218,218,218,1,215,215,215,1,166,166,166,1,222, + 222,222,1,216,216,216,1,217,217,217,1,220,220,220,1,217,217,217,1,218, + 218,218,1,215,215,215,1,219,219,219,1,221,221,221,1,218,218,218,1,215, + 215,215,1,219,219,219,2,214,214,214,1,219,219,219,1,223,223,223,1,215, + 215,215,1,220,220,220,1,218,218,218,1,254,254,254,1,253,253,253,1,218, + 218,218,1,219,219,219,2,169,169,169,1,166,166,166,1,217,217,217,1,219, + 219,219,1,216,216,216,1,217,217,217,3,219,219,219,2,215,215,215,1,220, + 220,220,1,218,218,218,2,217,217,217,1,219,219,219,1,216,216,216,2,222, + 222,222,1,220,220,220,1,219,219,219,1,216,216,216,1,220,220,220,1,218, + 218,218,1,217,217,217,1,221,221,221,1,215,215,215,1,217,217,217,2,220, + 220,220,1,214,214,214,1,217,217,217,1,219,219,219,1,217,217,217,1,252, + 252,252,1,169,169,169,1,166,166,166,1,171,171,171,1,219,219,219,1,218, + 218,218,1,169,169,169,1,168,168,168,1,165,165,165,1,220,220,220,1,218, + 218,218,2,217,217,217,1,215,215,215,1,219,219,219,1,218,218,218,1,219, + 219,219,2,218,218,218,18,215,215,215,1,218,218,218,1,217,217,217,1,218, + 218,218,1,219,219,219,1,220,220,220,1,218,218,218,6,217,217,217,1,219, + 219,219,2,216,216,216,1,217,217,217,1,170,170,170,1,217,217,217,1,219, + 219,219,1,220,220,220,1,215,215,215,1,218,218,218,1,223,223,223,1,164, + 164,164,1,221,221,221,1,217,217,217,1,216,216,216,1,219,219,219,1,216, + 216,216,1,170,170,170,1,169,169,169,1,215,215,215,1,220,220,220,1,167, + 167,167,1,168,168,168,1,167,167,167,1,170,170,170,1,221,221,221,1,215, + 215,215,1,217,217,217,2,255,255,255,1,219,219,219,1,169,169,169,1,217, + 217,217,1,216,216,216,1,219,219,219,1,216,216,216,1,217,217,217,1,222, + 222,222,1,216,216,216,1,220,220,220,1,217,217,217,1,220,220,220,1,217, + 217,217,1,218,218,218,1,216,216,216,1,219,219,219,1,218,218,218,1,219, + 219,219,1,217,217,217,1,218,218,218,1,220,220,220,1,216,216,216,1,217, + 217,217,1,222,222,222,1,216,216,216,1,217,217,217,1,221,221,221,1,216, + 216,216,1,217,217,217,1,219,219,219,1,166,166,166,1,220,220,220,1,255, + 255,255,2,218,218,218,1,221,221,221,1,165,165,165,1,219,219,219,1,220, + 220,220,1,218,218,218,3,220,220,220,1,218,218,218,1,217,217,217,1,218, + 218,218,1,217,217,217,1,220,220,220,1,216,216,216,1,218,218,218,1,217, + 217,217,1,219,219,219,1,218,218,218,2,220,220,220,1,216,216,216,1,167, + 167,167,1,220,220,220,1,215,215,215,1,219,219,219,2,167,167,167,1,218, + 218,218,1,219,219,219,1,218,218,218,1,217,217,217,1,219,219,219,1,168, + 168,168,1,169,169,169,1,253,253,253,1,218,218,218,1,255,255,255,1,217, + 217,217,1,170,170,170,1,216,216,216,1,215,215,215,1,222,222,222,1,165, + 165,165,1,168,168,168,1,171,171,171,1,166,166,166,1,218,218,218,2,170, + 170,170,1,168,168,168,1,218,218,218,1,217,217,217,1,216,216,216,1,219, + 219,219,1,218,218,218,18,168,168,168,1,222,222,222,1,216,216,216,2,221, + 221,221,1,215,215,215,1,218,218,218,7,216,216,216,1,255,255,255,1,253, + 253,253,1,217,217,217,1,219,219,219,1,167,167,167,1,220,220,220,1,217, + 217,217,1,220,220,220,1,218,218,218,1,169,169,169,2,218,218,218,1,219, + 219,219,1,254,254,254,1,255,255,255,1,220,220,220,1,216,216,216,1,220, + 220,220,1,255,255,255,1,216,216,216,1,255,255,255,1,218,218,218,1,255, + 255,255,1,216,216,216,1,167,167,167,1,168,168,168,1,219,219,219,1,216, + 216,216,1,219,219,219,1,218,218,218,1,168,168,168,1,216,216,216,1,218, + 218,218,1,221,221,221,1,218,218,218,1,216,216,216,1,220,220,220,1,218, + 218,218,1,219,219,219,1,255,255,255,1,219,219,219,1,217,217,217,2,218, + 218,218,1,216,216,216,1,219,219,219,1,218,218,218,9,219,219,219,2,217, + 217,217,1,168,168,168,1,167,167,167,1,220,220,220,1,215,215,215,1,219, + 219,219,2,255,255,255,1,216,216,216,1,220,220,220,1,219,219,219,1,220, + 220,220,1,217,217,217,1,218,218,218,1,217,217,217,1,218,218,218,1,219, + 219,219,1,217,217,217,1,219,219,219,1,220,220,220,1,218,218,218,2,222, + 222,222,1,214,214,214,1,218,218,218,1,217,217,217,1,221,221,221,1,217, + 217,217,1,218,218,218,1,220,220,220,1,167,167,167,1,218,218,218,1,217, + 217,217,1,218,218,218,1,219,219,219,1,215,215,215,1,220,220,220,1,219, + 219,219,1,216,216,216,1,219,219,219,1,218,218,218,1,217,217,217,1,255, + 255,255,1,251,251,251,1,255,255,255,1,168,168,168,2,218,218,218,1,217, + 217,217,2,170,170,170,1,169,169,169,1,167,167,167,1,217,217,217,1,218, + 218,218,1,216,216,216,1,168,168,168,1,221,221,221,1,218,218,218,1,215, + 215,215,1,220,220,220,1,217,217,217,1,219,219,219,1,218,218,218,1,219, + 219,219,1,216,216,216,1,220,220,220,1,215,215,215,1,221,221,221,1,218, + 218,218,1,220,220,220,1,217,217,217,2,221,221,221,1,215,215,215,1,216, + 216,216,1,220,220,220,1,167,167,167,1,172,172,172,1,164,164,164,1,219, + 219,219,1,220,220,220,1,217,217,217,1,168,168,168,1,166,166,166,1,167, + 167,167,1,170,170,170,1,165,165,165,1,218,218,218,1,221,221,221,1,213, + 213,213,1,220,220,220,1,218,218,218,2,254,254,254,1,221,221,221,1,217, + 217,217,1,165,165,165,1,218,218,218,2,220,220,220,1,254,254,254,1,253, + 253,253,1,217,217,217,1,216,216,216,1,221,221,221,1,255,255,255,1,252, + 252,252,1,255,255,255,1,168,168,168,1,167,167,167,1,255,255,255,2,254, + 254,254,1,255,255,255,1,218,218,218,1,168,168,168,1,171,171,171,1,216, + 216,216,1,219,219,219,1,255,255,255,2,216,216,216,1,220,220,220,1,216, + 216,216,1,220,220,220,1,216,216,216,1,217,217,217,1,219,219,219,1,218, + 218,218,1,217,217,217,2,219,219,219,1,216,216,216,1,220,220,220,1,212, + 212,212,1,219,219,219,1,220,220,220,1,218,218,218,9,217,217,217,1,219, + 219,219,1,215,215,215,1,255,255,255,1,167,167,167,1,169,169,169,1,164, + 164,164,1,223,223,223,1,218,218,218,1,253,253,253,1,217,217,217,1,173, + 173,173,1,216,216,216,1,215,215,215,1,167,167,167,1,218,218,218,1,217, + 217,217,1,220,220,220,1,217,217,217,1,221,221,221,1,216,216,216,1,220, + 220,220,1,214,214,214,1,217,217,217,1,218,218,218,1,215,215,215,1,222, + 222,222,1,218,218,218,1,221,221,221,1,253,253,253,1,216,216,216,1,221, + 221,221,1,214,214,214,1,171,171,171,1,255,255,255,1,222,222,222,1,217, + 217,217,1,218,218,218,1,221,221,221,1,216,216,216,1,254,254,254,1,255, + 255,255,1,217,217,217,1,214,214,214,1,221,221,221,1,216,216,216,1,255, + 255,255,1,217,217,217,1,219,219,219,1,214,214,214,1,222,222,222,1,217, + 217,217,1,219,219,219,1,216,216,216,1,167,167,167,1,171,171,171,1,214, + 214,214,1,255,255,255,1,218,218,218,1,170,170,170,1,163,163,163,1,219, + 219,219,2,217,217,217,1,221,221,221,1,215,215,215,1,167,167,167,2,220, + 220,220,1,218,218,218,1,217,217,217,2,218,218,218,1,216,216,216,1,219, + 219,219,2,216,216,216,1,224,224,224,1,218,218,218,1,215,215,215,1,255, + 255,255,1,214,214,214,1,222,222,222,1,218,218,218,1,216,216,216,1,169, + 169,169,1,165,165,165,1,172,172,172,1,170,170,170,1,163,163,163,1,170, + 170,170,1,217,217,217,1,216,216,216,1,221,221,221,1,215,215,215,1,217, + 217,217,1,220,220,220,1,253,253,253,1,255,255,255,1,215,215,215,1,221, + 221,221,1,218,218,218,1,219,219,219,1,253,253,253,2,218,218,218,1,221, + 221,221,1,167,167,167,1,170,170,170,1,215,215,215,1,255,255,255,1,220, + 220,220,1,167,167,167,1,218,218,218,1,217,217,217,1,218,218,218,1,167, + 167,167,1,168,168,168,1,213,213,213,1,222,222,222,1,163,163,163,1,220, + 220,220,2,251,251,251,1,255,255,255,1,221,221,221,1,215,215,215,1,220, + 220,220,1,168,168,168,1,216,216,216,1,218,218,218,1,224,224,224,1,214, + 214,214,1,221,221,221,2,212,212,212,1,220,220,220,1,221,221,221,1,218, + 218,218,1,219,219,219,1,216,216,216,1,218,218,218,9,221,221,221,1,216, + 216,216,1,255,255,255,1,252,252,252,1,168,168,168,1,169,169,169,1,168, + 168,168,1,165,165,165,1,170,170,170,1,219,219,219,1,169,169,169,1,166, + 166,166,1,219,219,219,1,218,218,218,1,223,223,223,1,219,219,219,2,216, + 216,216,1,168,168,168,1,216,216,216,1,220,220,220,1,217,217,217,1,215, + 215,215,1,221,221,221,1,217,217,217,1,223,223,223,1,215,215,215,1,217, + 217,217,1,219,219,219,1,218,218,218,1,219,219,219,1,251,251,251,1,218, + 218,218,1,219,219,219,1,167,167,167,1,215,215,215,1,217,217,217,1,216, + 216,216,1,218,218,218,1,217,217,217,1,219,219,219,1,216,216,216,1,217, + 217,217,1,220,220,220,1,217,217,217,1,214,214,214,1,219,219,219,2,215, + 215,215,1,221,221,221,1,218,218,218,1,216,216,216,1,219,219,219,1,220, + 220,220,1,167,167,167,1,165,165,165,1,171,171,171,1,214,214,214,1,167, + 167,167,1,168,168,168,1,167,167,167,1,168,168,168,1,169,169,169,1,167, + 167,167,1,166,166,166,1,170,170,170,1,168,168,168,1,167,167,167,1,166, + 166,166,1,217,217,217,1,220,220,220,1,219,219,219,1,217,217,217,1,218, + 218,218,1,219,219,219,1,217,217,217,1,216,216,216,1,169,169,169,1,255, + 255,255,2,253,253,253,1,222,222,222,1,215,215,215,1,216,216,216,1,255, + 255,255,1,217,217,217,4,169,169,169,2,216,216,216,1,222,222,222,1,215, + 215,215,1,220,220,220,2,215,215,215,1,218,218,218,1,255,255,255,1,219, + 219,219,1,218,218,218,1,217,217,217,2,222,222,222,1,218,218,218,2,217, + 217,217,1,220,220,220,1,163,163,163,1,172,172,172,1,216,216,216,1,218, + 218,218,1,222,222,222,1,215,215,215,1,220,220,220,1,219,219,219,1,167, + 167,167,1,218,218,218,1,222,222,222,1,168,168,168,1,219,219,219,1,216, + 216,216,1,218,218,218,2,168,168,168,1,215,215,215,1,222,222,222,1,215, + 215,215,1,219,219,219,1,220,220,220,1,218,218,218,1,216,216,216,1,218, + 218,218,1,217,217,217,2,221,221,221,1,217,217,217,1,215,215,215,1,222, + 222,222,1,218,218,218,1,215,215,215,1,219,219,219,1,218,218,218,9,217, + 217,217,1,255,255,255,2,220,220,220,1,165,165,165,1,167,167,167,1,171, + 171,171,1,165,165,165,1,220,220,220,1,169,169,169,1,166,166,166,1,255, + 255,255,1,216,216,216,2,166,166,166,1,220,220,220,1,218,218,218,1,220, + 220,220,1,216,216,216,1,217,217,217,1,216,216,216,1,223,223,223,1,217, + 217,217,1,220,220,220,1,214,214,214,1,220,220,220,1,221,221,221,1,217, + 217,217,2,222,222,222,1,255,255,255,1,218,218,218,1,216,216,216,1,220, + 220,220,1,219,219,219,1,220,220,220,1,165,165,165,1,220,220,220,1,219, + 219,219,2,220,220,220,1,218,218,218,2,219,219,219,1,255,255,255,1,219, + 219,219,1,214,214,214,1,255,255,255,1,250,250,250,1,221,221,221,1,216, + 216,216,1,218,218,218,1,216,216,216,1,217,217,217,1,170,170,170,1,169, + 169,169,1,217,217,217,1,222,222,222,1,169,169,169,1,168,168,168,4,221, + 221,221,1,213,213,213,1,171,171,171,2,169,169,169,1,220,220,220,1,219, + 219,219,1,217,217,217,1,223,223,223,1,213,213,213,1,219,219,219,1,218, + 218,218,2,216,216,216,1,220,220,220,1,218,218,218,1,220,220,220,1,217, + 217,217,1,218,218,218,1,255,255,255,2,254,254,254,1,222,222,222,1,218, + 218,218,1,217,217,217,1,168,168,168,1,218,218,218,1,220,220,220,1,215, + 215,215,1,217,217,217,1,219,219,219,1,216,216,216,1,217,217,217,1,219, + 219,219,1,215,215,215,1,216,216,216,1,220,220,220,1,218,218,218,1,216, + 216,216,2,217,217,217,1,220,220,220,1,217,217,217,1,255,255,255,1,170, + 170,170,1,218,218,218,2,217,217,217,1,219,219,219,2,217,217,217,1,218, + 218,218,1,219,219,219,1,217,217,217,1,255,255,255,1,215,215,215,1,220, + 220,220,1,219,219,219,1,218,218,218,1,219,219,219,1,220,220,220,1,167, + 167,167,1,253,253,253,1,219,219,219,2,215,215,215,2,218,218,218,1,220, + 220,220,1,218,218,218,1,216,216,216,1,220,220,220,1,215,215,215,1,217, + 217,217,1,218,218,218,1,216,216,216,1,219,219,219,1,218,218,218,9,217, + 217,217,1,218,218,218,1,255,255,255,2,253,253,253,1,255,255,255,1,218, + 218,218,1,216,216,216,1,218,218,218,1,219,219,219,1,215,215,215,1,220, + 220,220,1,218,218,218,1,216,216,216,1,223,223,223,1,217,217,217,1,253, + 253,253,1,220,220,220,1,215,215,215,1,218,218,218,1,223,223,223,1,217, + 217,217,2,164,164,164,1,169,169,169,1,219,219,219,1,216,216,216,1,219, + 219,219,1,217,217,217,1,219,219,219,1,217,217,217,2,255,255,255,1,220, + 220,220,1,216,216,216,1,221,221,221,1,217,217,217,2,218,218,218,1,216, + 216,216,1,217,217,217,1,214,214,214,1,217,217,217,1,218,218,218,1,255, + 255,255,1,252,252,252,1,255,255,255,4,252,252,252,1,218,218,218,1,220, + 220,220,1,218,218,218,1,216,216,216,1,219,219,219,1,215,215,215,1,222, + 222,222,1,251,251,251,1,253,253,253,1,255,255,255,1,215,215,215,1,220, + 220,220,1,218,218,218,1,216,216,216,1,221,221,221,1,218,218,218,1,164, + 164,164,1,168,168,168,1,167,167,167,2,219,219,219,1,214,214,214,1,221, + 221,221,1,219,219,219,1,253,253,253,1,219,219,219,1,220,220,220,1,217, + 217,217,2,216,216,216,1,218,218,218,2,255,255,255,1,253,253,253,1,255, + 255,255,1,254,254,254,1,216,216,216,1,218,218,218,3,216,216,216,1,220, + 220,220,1,171,171,171,1,215,215,215,1,222,222,222,1,219,219,219,1,218, + 218,218,1,220,220,220,1,222,222,222,1,217,217,217,2,255,255,255,1,218, + 218,218,1,255,255,255,1,215,215,215,1,255,255,255,1,217,217,217,1,255, + 255,255,1,254,254,254,1,221,221,221,1,215,215,215,1,218,218,218,1,167, + 167,167,1,220,220,220,1,215,215,215,1,221,221,221,2,216,216,216,1,221, + 221,221,1,219,219,219,1,217,217,217,1,255,255,255,1,167,167,167,2,169, + 169,169,1,168,168,168,1,218,218,218,1,220,220,220,1,221,221,221,2,219, + 219,219,1,215,215,215,1,219,219,219,1,220,220,220,1,219,219,219,2,221, + 221,221,1,218,218,218,2,216,216,216,1,219,219,219,1,218,218,218,8,220, + 220,220,1,217,217,217,1,254,254,254,1,255,255,255,6,253,253,253,1,220, + 220,220,1,219,219,219,1,216,216,216,1,255,255,255,1,216,216,216,1,218, + 218,218,2,220,220,220,1,218,218,218,1,220,220,220,1,217,217,217,1,213, + 213,213,1,223,223,223,1,170,170,170,1,168,168,168,1,218,218,218,1,219, + 219,219,1,215,215,215,1,220,220,220,2,217,217,217,1,222,222,222,1,215, + 215,215,1,216,216,216,1,219,219,219,1,251,251,251,1,222,222,222,1,216, + 216,216,1,218,218,218,1,220,220,220,1,219,219,219,1,221,221,221,1,217, + 217,217,1,219,219,219,1,255,255,255,2,213,213,213,1,220,220,220,1,251, + 251,251,1,255,255,255,1,253,253,253,1,218,218,218,1,219,219,219,1,218, + 218,218,2,217,217,217,1,220,220,220,1,216,216,216,1,220,220,220,1,255, + 255,255,1,214,214,214,1,255,255,255,1,253,253,253,1,217,217,217,1,255, + 255,255,1,219,219,219,1,217,217,217,1,170,170,170,1,171,171,171,1,166, + 166,166,1,167,167,167,1,170,170,170,1,171,171,171,1,217,217,217,1,218, + 218,218,1,216,216,216,1,221,221,221,1,216,216,216,1,218,218,218,2,219, + 219,219,1,218,218,218,1,216,216,216,1,218,218,218,1,255,255,255,2,252, + 252,252,1,221,221,221,1,169,169,169,1,219,219,219,1,167,167,167,1,166, + 166,166,1,219,219,219,1,214,214,214,1,218,218,218,2,219,219,219,1,214, + 214,214,1,217,217,217,1,212,212,212,1,170,170,170,1,219,219,219,1,215, + 215,215,1,254,254,254,1,255,255,255,1,218,218,218,1,251,251,251,1,222, + 222,222,1,253,253,253,1,220,220,220,1,217,217,217,1,255,255,255,2,252, + 252,252,1,255,255,255,2,216,216,216,1,215,215,215,1,219,219,219,1,217, + 217,217,1,220,220,220,1,167,167,167,1,168,168,168,1,220,220,220,1,169, + 169,169,1,165,165,165,1,220,220,220,1,216,216,216,1,219,219,219,1,166, + 166,166,1,219,219,219,1,217,217,217,1,220,220,220,1,216,216,216,2,217, + 217,217,3,219,219,219,2,215,215,215,1,220,220,220,1,218,218,218,11,217, + 217,217,1,254,254,254,1,255,255,255,1,250,250,250,1,254,254,254,1,220, + 220,220,1,217,217,217,1,216,216,216,1,220,220,220,1,216,216,216,1,217, + 217,217,1,220,220,220,1,219,219,219,1,218,218,218,1,215,215,215,1,219, + 219,219,1,217,217,217,2,255,255,255,1,215,215,215,1,166,166,166,1,216, + 216,216,1,219,219,219,1,220,220,220,1,218,218,218,2,215,215,215,1,219, + 219,219,1,214,214,214,1,220,220,220,1,215,215,215,1,222,222,222,1,220, + 220,220,1,216,216,216,1,218,218,218,1,217,217,217,3,216,216,216,1,217, + 217,217,1,168,168,168,1,219,219,219,1,216,216,216,1,218,218,218,1,216, + 216,216,1,218,218,218,1,255,255,255,2,219,219,219,1,215,215,215,1,219, + 219,219,2,218,218,218,1,168,168,168,1,167,167,167,1,165,165,165,1,253, + 253,253,1,255,255,255,5,216,216,216,1,218,218,218,1,255,255,255,1,254, + 254,254,1,220,220,220,1,215,215,215,1,217,217,217,1,165,165,165,1,217, + 217,217,1,220,220,220,2,216,216,216,1,215,215,215,1,222,222,222,1,215, + 215,215,1,218,218,218,1,219,219,219,1,218,218,218,1,219,219,219,1,213, + 213,213,1,255,255,255,2,168,168,168,2,167,167,167,1,168,168,168,1,220, + 220,220,1,216,216,216,1,222,222,222,1,220,220,220,1,215,215,215,1,216, + 216,216,1,221,221,221,1,219,219,219,2,169,169,169,1,216,216,216,1,219, + 219,219,1,218,218,218,1,216,216,216,1,221,221,221,1,169,169,169,1,215, + 215,215,1,220,220,220,1,216,216,216,1,219,219,219,1,253,253,253,1,218, + 218,218,1,221,221,221,1,255,255,255,1,253,253,253,1,221,221,221,1,168, + 168,168,1,167,167,167,1,169,169,169,1,215,215,215,1,220,220,220,1,217, + 217,217,2,216,216,216,1,171,171,171,1,167,167,167,1,219,219,219,1,218, + 218,218,1,216,216,216,1,221,221,221,1,215,215,215,1,218,218,218,1,220, + 220,220,1,218,218,218,1,220,220,220,1,218,218,218,1,217,217,217,1,218, + 218,218,1,217,217,217,1,220,220,220,1,216,216,216,1,218,218,218,8,217, + 217,217,1,219,219,219,1,216,216,216,1,223,223,223,1,215,215,215,1,216, + 216,216,1,222,222,222,1,217,217,217,2,219,219,219,2,216,216,216,1,219, + 219,219,1,221,221,221,1,216,216,216,1,217,217,217,2,221,221,221,1,217, + 217,217,1,216,216,216,1,223,223,223,1,253,253,253,1,254,254,254,1,169, + 169,169,1,170,170,170,1,218,218,218,1,217,217,217,2,219,219,219,1,218, + 218,218,1,219,219,219,2,218,218,218,1,219,219,219,1,217,217,217,1,215, + 215,215,1,218,218,218,1,219,219,219,1,217,217,217,1,218,218,218,1,217, + 217,217,1,222,222,222,1,167,167,167,2,166,166,166,1,220,220,220,1,217, + 217,217,1,168,168,168,1,218,218,218,1,254,254,254,1,219,219,219,1,218, + 218,218,1,217,217,217,1,219,219,219,1,217,217,217,1,218,218,218,2,168, + 168,168,1,255,255,255,1,220,220,220,1,218,218,218,1,253,253,253,1,218, + 218,218,1,255,255,255,1,254,254,254,1,255,255,255,1,218,218,218,1,217, + 217,217,1,255,255,255,1,253,253,253,1,222,222,222,1,168,168,168,1,169, + 169,169,1,168,168,168,1,217,217,217,2,220,220,220,1,217,217,217,2,219, + 219,219,1,218,218,218,1,217,217,217,1,220,220,220,1,216,216,216,1,220, + 220,220,1,255,255,255,2,216,216,216,1,219,219,219,1,218,218,218,1,167, + 167,167,1,169,169,169,1,167,167,167,1,217,217,217,1,219,219,219,1,218, + 218,218,2,219,219,219,1,255,255,255,1,251,251,251,1,255,255,255,1,217, + 217,217,1,169,169,169,2,217,217,217,1,253,253,253,1,220,220,220,1,219, + 219,219,1,217,217,217,1,218,218,218,3,168,168,168,2,215,215,215,1,220, + 220,220,1,169,169,169,1,168,168,168,1,166,166,166,1,255,255,255,1,216, + 216,216,1,218,218,218,2,217,217,217,1,168,168,168,1,170,170,170,1,169, + 169,169,1,218,218,218,3,217,217,217,1,218,218,218,1,217,217,217,1,218, + 218,218,1,217,217,217,1,218,218,218,3,217,217,217,1,220,220,220,1,216, + 216,216,1,218,218,218,17,219,219,219,1,217,217,217,1,220,220,220,1,218, + 218,218,2,219,219,219,1,216,216,216,1,218,218,218,3,220,220,220,1,214, + 214,214,1,255,255,255,2,215,215,215,1,170,170,170,1,168,168,168,1,165, + 165,165,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,218, + 218,218,3,216,216,216,1,221,221,221,1,218,218,218,1,168,168,168,1,167, + 167,167,1,217,217,217,1,218,218,218,2,219,219,219,1,168,168,168,1,170, + 170,170,1,166,166,166,1,169,169,169,1,170,170,170,1,165,165,165,1,169, + 169,169,1,219,219,219,1,217,217,217,1,219,219,219,1,218,218,218,1,217, + 217,217,1,220,220,220,1,218,218,218,1,220,220,220,1,164,164,164,1,220, + 220,220,1,218,218,218,2,219,219,219,1,218,218,218,1,255,255,255,1,254, + 254,254,1,168,168,168,2,170,170,170,1,168,168,168,1,216,216,216,1,218, + 218,218,1,169,169,169,1,168,168,168,1,218,218,218,1,217,217,217,1,219, + 219,219,1,218,218,218,1,216,216,216,1,221,221,221,1,217,217,217,1,219, + 219,219,1,218,218,218,1,217,217,217,1,220,220,220,1,216,216,216,1,255, + 255,255,2,218,218,218,1,216,216,216,1,219,219,219,1,170,170,170,1,168, + 168,168,2,220,220,220,1,217,217,217,2,220,220,220,1,216,216,216,1,255, + 255,255,2,214,214,214,1,221,221,221,1,167,167,167,1,252,252,252,1,255, + 255,255,1,221,221,221,2,213,213,213,1,218,218,218,2,254,254,254,1,255, + 255,255,1,217,217,217,2,224,224,224,1,252,252,252,1,255,255,255,1,254, + 254,254,1,219,219,219,1,218,218,218,1,217,217,217,1,219,219,219,2,218, + 218,218,1,215,215,215,1,169,169,169,1,168,168,168,1,167,167,167,1,168, + 168,168,1,217,217,217,1,218,218,218,1,219,219,219,1,216,216,216,1,220, + 220,220,2,218,218,218,1,215,215,215,1,219,219,219,1,221,221,221,1,213, + 213,213,1,220,220,220,1,218,218,218,18,220,220,220,1,216,216,216,2,217, + 217,217,1,220,220,220,2,169,169,169,1,218,218,218,1,219,219,219,1,218, + 218,218,3,255,255,255,1,217,217,217,1,167,167,167,1,169,169,169,1,220, + 220,220,1,216,216,216,2,219,219,219,2,217,217,217,1,219,219,219,2,215, + 215,215,1,218,218,218,2,216,216,216,1,220,220,220,1,218,218,218,1,219, + 219,219,1,255,255,255,1,217,217,217,2,167,167,167,1,171,171,171,1,253, + 253,253,1,165,165,165,1,172,172,172,1,215,215,215,1,221,221,221,1,215, + 215,215,1,217,217,217,1,221,221,221,1,254,254,254,1,253,253,253,1,219, + 219,219,1,168,168,168,2,220,220,220,1,219,219,219,1,216,216,216,3,218, + 218,218,1,255,255,255,2,168,168,168,1,162,162,162,1,219,219,219,1,220, + 220,220,1,215,215,215,1,220,220,220,1,168,168,168,1,216,216,216,1,221, + 221,221,1,219,219,219,1,215,215,215,1,221,221,221,1,217,217,217,1,219, + 219,219,1,216,216,216,1,220,220,220,2,216,216,216,1,217,217,217,1,172, + 172,172,1,218,218,218,2,255,255,255,2,212,212,212,1,169,169,169,1,167, + 167,167,1,166,166,166,1,218,218,218,1,220,220,220,1,217,217,217,1,220, + 220,220,1,218,218,218,2,255,255,255,2,220,220,220,1,169,169,169,1,168, + 168,168,1,217,217,217,1,215,215,215,1,221,221,221,1,219,219,219,1,216, + 216,216,1,255,255,255,2,217,217,217,1,215,215,215,1,254,254,254,1,255, + 255,255,1,218,218,218,1,169,169,169,1,217,217,217,1,220,220,220,1,218, + 218,218,2,219,219,219,1,218,218,218,2,216,216,216,1,168,168,168,1,170, + 170,170,1,165,165,165,1,220,220,220,1,216,216,216,1,223,223,223,1,217, + 217,217,1,216,216,216,1,215,215,215,1,219,219,219,1,217,217,217,1,215, + 215,215,1,217,217,217,1,220,220,220,1,219,219,219,1,217,217,217,1,218, + 218,218,16,217,217,217,2,221,221,221,1,218,218,218,1,220,220,220,1,222, + 222,222,1,212,212,212,1,167,167,167,1,218,218,218,1,214,214,214,1,218, + 218,218,1,220,220,220,1,216,216,216,1,253,253,253,1,221,221,221,1,219, + 219,219,1,217,217,217,1,216,216,216,1,220,220,220,2,217,217,217,1,218, + 218,218,1,168,168,168,2,169,169,169,1,221,221,221,1,253,253,253,1,255, + 255,255,1,166,166,166,1,218,218,218,1,219,219,219,1,254,254,254,1,255, + 255,255,2,217,217,217,1,220,220,220,1,253,253,253,1,255,255,255,2,217, + 217,217,1,218,218,218,1,216,216,216,1,221,221,221,1,219,219,219,1,218, + 218,218,1,222,222,222,1,251,251,251,1,220,220,220,1,165,165,165,1,170, + 170,170,1,165,165,165,1,217,217,217,1,219,219,219,1,221,221,221,1,220, + 220,220,1,254,254,254,2,220,220,220,1,214,214,214,1,176,176,176,1,219, + 219,219,1,216,216,216,1,220,220,220,1,165,165,165,1,168,168,168,1,170, + 170,170,1,167,167,167,2,222,222,222,1,216,216,216,1,167,167,167,1,219, + 219,219,1,218,218,218,2,216,216,216,1,168,168,168,1,218,218,218,1,214, + 214,214,1,218,218,218,1,255,255,255,1,254,254,254,1,219,219,219,1,216, + 216,216,1,222,222,222,1,218,218,218,1,220,220,220,1,216,216,216,1,220, + 220,220,1,218,218,218,1,216,216,216,1,220,220,220,1,219,219,219,1,253, + 253,253,1,216,216,216,1,217,217,217,1,168,168,168,1,167,167,167,1,219, + 219,219,1,168,168,168,1,217,217,217,1,219,219,219,2,165,165,165,1,167, + 167,167,1,220,220,220,1,219,219,219,1,222,222,222,1,164,164,164,1,171, + 171,171,1,218,218,218,4,216,216,216,1,219,219,219,3,220,220,220,1,219, + 219,219,1,165,165,165,1,172,172,172,1,217,217,217,1,220,220,220,1,215, + 215,215,1,218,218,218,1,220,220,220,1,218,218,218,1,219,219,219,4,218, + 218,218,1,215,215,215,1,219,219,219,1,218,218,218,16,216,216,216,1,219, + 219,219,1,218,218,218,2,216,216,216,1,255,255,255,1,223,223,223,1,168, + 168,168,1,169,169,169,1,170,170,170,1,171,171,171,1,165,165,165,1,255, + 255,255,1,254,254,254,1,253,253,253,1,216,216,216,1,168,168,168,1,172, + 172,172,1,168,168,168,1,215,215,215,1,220,220,220,1,218,218,218,1,217, + 217,217,1,168,168,168,1,215,215,215,1,219,219,219,1,218,218,218,1,215, + 215,215,1,221,221,221,1,218,218,218,2,255,255,255,1,254,254,254,1,251, + 251,251,1,255,255,255,1,217,217,217,1,255,255,255,1,254,254,254,1,252, + 252,252,1,218,218,218,1,221,221,221,1,219,219,219,1,217,217,217,1,166, + 166,166,1,217,217,217,1,252,252,252,1,255,255,255,2,169,169,169,1,167, + 167,167,2,170,170,170,1,219,219,219,1,216,216,216,1,214,214,214,1,220, + 220,220,1,254,254,254,1,219,219,219,1,218,218,218,1,214,214,214,1,217, + 217,217,1,219,219,219,2,168,168,168,1,167,167,167,2,170,170,170,1,168, + 168,168,1,167,167,167,1,170,170,170,1,214,214,214,1,220,220,220,2,216, + 216,216,1,221,221,221,1,220,220,220,1,217,217,217,1,221,221,221,1,166, + 166,166,1,168,168,168,1,255,255,255,1,219,219,219,1,217,217,217,1,252, + 252,252,1,219,219,219,1,217,217,217,1,221,221,221,1,216,216,216,1,220, + 220,220,1,218,218,218,2,214,214,214,1,219,219,219,1,255,255,255,2,169, + 169,169,2,216,216,216,1,169,169,169,1,219,219,219,1,216,216,216,1,168, + 168,168,1,220,220,220,1,216,216,216,1,221,221,221,1,219,219,219,1,214, + 214,214,1,217,217,217,1,219,219,219,1,215,215,215,1,216,216,216,1,220, + 220,220,1,222,222,222,1,217,217,217,1,219,219,219,1,214,214,214,1,218, + 218,218,1,216,216,216,2,169,169,169,1,166,166,166,1,218,218,218,1,220, + 220,220,1,214,214,214,1,222,222,222,1,214,214,214,1,217,217,217,1,219, + 219,219,1,215,215,215,1,220,220,220,1,217,217,217,1,218,218,218,19,220, + 220,220,1,218,218,218,1,216,216,216,1,223,223,223,1,214,214,214,1,255, + 255,255,1,215,215,215,1,219,219,219,1,168,168,168,1,219,219,219,1,165, + 165,165,1,166,166,166,1,217,217,217,1,253,253,253,1,222,222,222,1,219, + 219,219,1,166,166,166,1,165,165,165,1,170,170,170,1,218,218,218,1,255, + 255,255,1,253,253,253,1,220,220,220,1,168,168,168,1,220,220,220,1,217, + 217,217,1,255,255,255,1,221,221,221,1,214,214,214,1,220,220,220,1,217, + 217,217,1,219,219,219,1,255,255,255,2,217,217,217,1,218,218,218,1,216, + 216,216,1,255,255,255,3,215,215,215,1,219,219,219,1,216,216,216,1,254, + 254,254,1,221,221,221,1,255,255,255,2,254,254,254,1,218,218,218,1,168, + 168,168,3,165,165,165,1,217,217,217,1,224,224,224,1,253,253,253,1,255, + 255,255,1,218,218,218,1,219,219,219,1,217,217,217,1,219,219,219,1,218, + 218,218,1,216,216,216,1,217,217,217,1,218,218,218,1,219,219,219,1,169, + 169,169,1,165,165,165,1,220,220,220,1,168,168,168,1,169,169,169,1,219, + 219,219,1,217,217,217,1,255,255,255,1,218,218,218,1,254,254,254,1,255, + 255,255,1,216,216,216,1,167,167,167,1,254,254,254,2,169,169,169,2,219, + 219,219,1,217,217,217,1,221,221,221,1,218,218,218,1,217,217,217,1,214, + 214,214,1,219,219,219,1,217,217,217,1,221,221,221,1,219,219,219,1,252, + 252,252,2,172,172,172,1,254,254,254,1,218,218,218,1,221,221,221,1,215, + 215,215,1,217,217,217,1,255,255,255,1,170,170,170,1,166,166,166,2,218, + 218,218,1,222,222,222,1,219,219,219,1,217,217,217,1,221,221,221,1,218, + 218,218,1,217,217,217,1,214,214,214,1,221,221,221,1,217,217,217,1,220, + 220,220,1,221,221,221,1,216,216,216,1,218,218,218,1,174,174,174,1,166, + 166,166,1,214,214,214,1,221,221,221,1,219,219,219,3,220,220,220,1,215, + 215,215,1,221,221,221,1,214,214,214,1,218,218,218,1,170,170,170,1,166, + 166,166,1,221,221,221,1,218,218,218,16,217,217,217,1,219,219,219,2,214, + 214,214,1,223,223,223,1,254,254,254,1,255,255,255,3,253,253,253,1,168, + 168,168,2,221,221,221,1,220,220,220,1,252,252,252,1,254,254,254,2,220, + 220,220,1,218,218,218,1,219,219,219,1,217,217,217,1,255,255,255,1,217, + 217,217,1,216,216,216,1,218,218,218,1,217,217,217,2,216,216,216,1,220, + 220,220,1,219,219,219,1,217,217,217,1,218,218,218,1,217,217,217,1,221, + 221,221,1,216,216,216,1,220,220,220,1,219,219,219,1,253,253,253,1,254, + 254,254,2,220,220,220,1,218,218,218,1,168,168,168,1,220,220,220,1,216, + 216,216,1,217,217,217,1,216,216,216,1,220,220,220,1,217,217,217,1,218, + 218,218,1,169,169,169,1,168,168,168,1,166,166,166,1,171,171,171,1,165, + 165,165,1,254,254,254,2,219,219,219,2,217,217,217,1,218,218,218,1,219, + 219,219,1,218,218,218,1,219,219,219,1,220,220,220,1,216,216,216,1,218, + 218,218,2,165,165,165,1,167,167,167,1,220,220,220,1,215,215,215,1,218, + 218,218,1,255,255,255,1,249,249,249,1,254,254,254,1,255,255,255,2,167, + 167,167,1,255,255,255,1,222,222,222,1,213,213,213,1,219,219,219,1,220, + 220,220,1,216,216,216,1,215,215,215,1,218,218,218,1,220,220,220,1,219, + 219,219,2,216,216,216,2,219,219,219,1,255,255,255,2,213,213,213,1,255, + 255,255,1,217,217,217,1,168,168,168,1,255,255,255,1,220,220,220,1,218, + 218,218,1,166,166,166,1,172,172,172,1,218,218,218,1,217,217,217,2,214, + 214,214,1,218,218,218,1,217,217,217,1,219,219,219,3,217,217,217,1,219, + 219,219,1,216,216,216,1,218,218,218,1,219,219,219,1,220,220,220,1,162, + 162,162,1,220,220,220,1,219,219,219,2,217,217,217,2,219,219,219,1,215, + 215,215,1,220,220,220,1,219,219,219,1,216,216,216,1,169,169,169,1,168, + 168,168,1,167,167,167,1,166,166,166,1,218,218,218,16,217,217,217,1,218, + 218,218,2,219,219,219,1,217,217,217,2,255,255,255,1,217,217,217,1,254, + 254,254,1,255,255,255,2,169,169,169,1,168,168,168,1,215,215,215,1,255, + 255,255,1,219,219,219,1,255,255,255,1,220,220,220,1,218,218,218,1,216, + 216,216,1,255,255,255,1,251,251,251,1,219,219,219,1,222,222,222,1,218, + 218,218,1,221,221,221,1,217,217,217,1,219,219,219,1,217,217,217,1,215, + 215,215,1,219,219,219,1,218,218,218,1,217,217,217,1,218,218,218,1,222, + 222,222,1,217,217,217,1,216,216,216,1,220,220,220,1,254,254,254,1,255, + 255,255,1,254,254,254,1,219,219,219,2,217,217,217,1,218,218,218,1,220, + 220,220,1,218,218,218,1,254,254,254,1,216,216,216,1,219,219,219,1,218, + 218,218,1,167,167,167,1,168,168,168,1,169,169,169,1,167,167,167,1,219, + 219,219,1,255,255,255,1,220,220,220,1,218,218,218,1,216,216,216,1,219, + 219,219,1,217,217,217,1,220,220,220,1,216,216,216,1,215,215,215,1,221, + 221,221,1,218,218,218,1,219,219,219,2,171,171,171,1,167,167,167,1,170, + 170,170,1,168,168,168,1,214,214,214,1,221,221,221,1,219,219,219,1,255, + 255,255,1,217,217,217,1,218,218,218,1,255,255,255,2,219,219,219,1,215, + 215,215,1,219,219,219,1,218,218,218,1,219,219,219,1,218,218,218,2,216, + 216,216,1,221,221,221,1,217,217,217,1,218,218,218,2,255,255,255,1,217, + 217,217,1,220,220,220,1,218,218,218,2,255,255,255,1,221,221,221,1,253, + 253,253,1,254,254,254,1,217,217,217,1,218,218,218,2,219,219,219,1,218, + 218,218,1,221,221,221,1,218,218,218,3,217,217,217,1,220,220,220,1,216, + 216,216,1,217,217,217,1,219,219,219,1,218,218,218,2,217,217,217,1,172, + 172,172,1,219,219,219,1,217,217,217,3,219,219,219,1,218,218,218,1,220, + 220,220,1,214,214,214,1,218,218,218,1,255,255,255,1,219,219,219,1,167, + 167,167,1,219,219,219,1,216,216,216,1,218,218,218,16,220,220,220,1,216, + 216,216,1,220,220,220,1,218,218,218,1,217,217,217,1,218,218,218,1,217, + 217,217,1,218,218,218,1,255,255,255,2,219,219,219,1,218,218,218,1,215, + 215,215,1,222,222,222,1,217,217,217,1,168,168,168,1,217,217,217,1,218, + 218,218,2,219,219,219,1,217,217,217,1,220,220,220,1,219,219,219,1,216, + 216,216,2,220,220,220,1,217,217,217,1,218,218,218,1,217,217,217,1,220, + 220,220,1,217,217,217,1,219,219,219,1,220,220,220,1,216,216,216,1,218, + 218,218,3,219,219,219,1,255,255,255,1,254,254,254,1,255,255,255,1,215, + 215,215,1,218,218,218,1,217,217,217,1,255,255,255,1,252,252,252,1,255, + 255,255,3,217,217,217,1,216,216,216,1,221,221,221,1,215,215,215,1,167, + 167,167,1,169,169,169,1,218,218,218,1,219,219,219,1,215,215,215,1,217, + 217,217,1,222,222,222,1,216,216,216,1,218,218,218,1,220,220,220,1,218, + 218,218,1,219,219,219,2,216,216,216,1,220,220,220,1,166,166,166,1,169, + 169,169,1,167,167,167,2,169,169,169,1,218,218,218,2,217,217,217,1,252, + 252,252,1,222,222,222,1,253,253,253,1,219,219,219,1,217,217,217,1,219, + 219,219,1,220,220,220,1,218,218,218,2,217,217,217,1,218,218,218,9,219, + 219,219,1,254,254,254,1,219,219,219,1,216,216,216,1,220,220,220,1,254, + 254,254,1,255,255,255,1,219,219,219,1,252,252,252,1,255,255,255,1,253, + 253,253,1,216,216,216,1,218,218,218,1,217,217,217,1,218,218,218,2,219, + 219,219,1,221,221,221,1,215,215,215,1,220,220,220,1,218,218,218,1,215, + 215,215,1,221,221,221,1,169,169,169,1,167,167,167,1,217,217,217,1,219, + 219,219,1,218,218,218,3,219,219,219,1,217,217,217,1,218,218,218,1,217, + 217,217,1,220,220,220,1,216,216,216,1,255,255,255,1,221,221,221,1,216, + 216,216,1,215,215,215,1,223,223,223,1,216,216,216,1,219,219,219,2,217, + 217,217,4,218,218,218,2,216,216,216,1,220,220,220,1,217,217,217,1,219, + 219,219,1,218,218,218,1,216,216,216,1,220,220,220,1,218,218,218,2,217, + 217,217,1,218,218,218,1,220,220,220,1,218,218,218,1,217,217,217,1,255, + 255,255,1,254,254,254,1,215,215,215,1,219,219,219,1,255,255,255,1,221, + 221,221,1,216,216,216,1,219,219,219,1,216,216,216,1,219,219,219,1,217, + 217,217,1,216,216,216,1,218,218,218,3,217,217,217,1,219,219,219,1,217, + 217,217,1,218,218,218,1,220,220,220,2,219,219,219,1,217,217,217,1,219, + 219,219,1,217,217,217,1,218,218,218,2,217,217,217,1,218,218,218,1,216, + 216,216,1,219,219,219,1,218,218,218,1,166,166,166,1,219,219,219,1,218, + 218,218,1,217,217,217,1,170,170,170,1,251,251,251,1,255,255,255,2,214, + 214,214,1,219,219,219,1,220,220,220,1,218,218,218,1,221,221,221,1,168, + 168,168,1,218,218,218,1,216,216,216,1,222,222,222,1,217,217,217,2,220, + 220,220,1,216,216,216,2,220,220,220,1,218,218,218,1,217,217,217,1,220, + 220,220,1,218,218,218,1,216,216,216,1,222,222,222,1,215,215,215,1,169, + 169,169,1,168,168,168,1,169,169,169,1,221,221,221,1,215,215,215,1,219, + 219,219,1,217,217,217,1,218,218,218,1,217,217,217,1,218,218,218,14,222, + 222,222,1,213,213,213,1,218,218,218,1,217,217,217,1,219,219,219,1,217, + 217,217,1,255,255,255,1,253,253,253,2,255,255,255,1,250,250,250,1,253, + 253,253,1,226,226,226,1,218,218,218,1,217,217,217,1,219,219,219,1,217, + 217,217,1,220,220,220,1,215,215,215,1,218,218,218,1,217,217,217,1,220, + 220,220,1,219,219,219,1,216,216,216,1,167,167,167,1,168,168,168,1,219, + 219,219,1,168,168,168,3,218,218,218,1,216,216,216,1,217,217,217,1,170, + 170,170,1,219,219,219,1,216,216,216,1,172,172,172,1,167,167,167,1,218, + 218,218,1,221,221,221,1,219,219,219,2,218,218,218,1,216,216,216,1,215, + 215,215,1,221,221,221,1,220,220,220,1,219,219,219,1,220,220,220,1,218, + 218,218,1,219,219,219,1,218,218,218,2,219,219,219,1,218,218,218,1,216, + 216,216,1,221,221,221,1,215,215,215,1,220,220,220,1,219,219,219,1,217, + 217,217,3,216,216,216,1,219,219,219,1,218,218,218,1,217,217,217,1,218, + 218,218,1,220,220,220,1,251,251,251,1,216,216,216,1,167,167,167,1,220, + 220,220,1,214,214,214,1,220,220,220,2,221,221,221,1,216,216,216,1,219, + 219,219,3,217,217,217,1,219,219,219,1,214,214,214,1,217,217,217,1,216, + 216,216,2,220,220,220,1,218,218,218,1,219,219,219,2,220,220,220,1,217, + 217,217,1,219,219,219,1,221,221,221,1,216,216,216,1,168,168,168,1,170, + 170,170,1,167,167,167,1,168,168,168,1,215,215,215,1,217,217,217,1,219, + 219,219,1,255,255,255,1,253,253,253,1,255,255,255,1,220,220,220,1,213, + 213,213,1,255,255,255,1,253,253,253,1,216,216,216,1,220,220,220,1,221, + 221,221,1,214,214,214,1,220,220,220,1,218,218,218,1,216,216,216,1,222, + 222,222,1,219,219,219,1,215,215,215,1,218,218,218,1,221,221,221,1,214, + 214,214,1,218,218,218,1,254,254,254,1,255,255,255,1,216,216,216,1,170, + 170,170,1,167,167,167,1,168,168,168,1,165,165,165,1,220,220,220,1,219, + 219,219,2,218,218,218,16,214,214,214,1,220,220,220,1,219,219,219,1,221, + 221,221,1,216,216,216,1,220,220,220,1,255,255,255,1,217,217,217,2,223, + 223,223,1,253,253,253,1,255,255,255,1,213,213,213,1,218,218,218,1,217, + 217,217,1,219,219,219,2,217,217,217,1,218,218,218,1,223,223,223,1,216, + 216,216,1,217,217,217,2,221,221,221,1,166,166,166,1,168,168,168,1,167, + 167,167,1,170,170,170,2,166,166,166,1,170,170,170,1,218,218,218,1,255, + 255,255,1,220,220,220,1,217,217,217,1,166,166,166,1,169,169,169,1,168, + 168,168,1,215,215,215,1,218,218,218,1,219,219,219,1,214,214,214,1,216, + 216,216,1,224,224,224,1,167,167,167,1,165,165,165,1,218,218,218,3,165, + 165,165,1,219,219,219,1,217,217,217,1,221,221,221,1,214,214,214,1,218, + 218,218,1,221,221,221,1,219,219,219,1,217,217,217,1,218,218,218,2,221, + 221,221,1,219,219,219,3,217,217,217,1,216,216,216,1,219,219,219,1,217, + 217,217,1,218,218,218,1,220,220,220,1,221,221,221,1,219,219,219,1,166, + 166,166,1,222,222,222,1,216,216,216,1,218,218,218,1,215,215,215,1,219, + 219,219,1,221,221,221,1,215,215,215,1,217,217,217,1,218,218,218,1,220, + 220,220,2,219,219,219,1,220,220,220,1,218,218,218,2,215,215,215,1,222, + 222,222,1,216,216,216,1,214,214,214,1,169,169,169,1,166,166,166,1,217, + 217,217,1,255,255,255,1,217,217,217,1,215,215,215,1,255,255,255,1,254, + 254,254,1,221,221,221,1,222,222,222,1,216,216,216,1,254,254,254,1,255, + 255,255,1,254,254,254,1,217,217,217,1,218,218,218,1,221,221,221,1,255, + 255,255,4,254,254,254,1,255,255,255,1,219,219,219,1,218,218,218,1,217, + 217,217,1,219,219,219,1,221,221,221,1,218,218,218,1,216,216,216,1,221, + 221,221,1,255,255,255,2,253,253,253,1,255,255,255,1,252,252,252,1,169, + 169,169,1,168,168,168,1,170,170,170,1,165,165,165,1,219,219,219,1,218, + 218,218,1,221,221,221,1,215,215,215,1,218,218,218,14,219,219,219,1,218, + 218,218,2,216,216,216,1,218,218,218,1,217,217,217,1,219,219,219,2,216, + 216,216,2,255,255,255,3,218,218,218,1,217,217,217,2,218,218,218,2,217, + 217,217,3,218,218,218,1,220,220,220,1,216,216,216,1,168,168,168,1,218, + 218,218,1,220,220,220,1,215,215,215,1,165,165,165,1,170,170,170,1,165, + 165,165,1,221,221,221,1,215,215,215,1,218,218,218,2,220,220,220,1,167, + 167,167,1,169,169,169,1,221,221,221,1,218,218,218,2,220,220,220,1,167, + 167,167,3,221,221,221,1,217,217,217,2,216,216,216,1,222,222,222,1,215, + 215,215,1,219,219,219,1,216,216,216,1,222,222,222,1,217,217,217,2,218, + 218,218,1,219,219,219,1,216,216,216,1,218,218,218,1,217,217,217,1,215, + 215,215,1,220,220,220,1,216,216,216,1,220,220,220,1,218,218,218,2,221, + 221,221,1,215,215,215,1,218,218,218,1,163,163,163,1,219,219,219,1,168, + 168,168,1,220,220,220,1,216,216,216,1,219,219,219,2,216,216,216,1,218, + 218,218,1,220,220,220,1,169,169,169,1,217,217,217,1,215,215,215,1,219, + 219,219,1,216,216,216,2,222,222,222,1,215,215,215,1,217,217,217,2,220, + 220,220,1,219,219,219,2,221,221,221,1,254,254,254,1,255,255,255,3,165, + 165,165,1,217,217,217,1,219,219,219,1,215,215,215,1,217,217,217,1,220, + 220,220,1,255,255,255,1,254,254,254,1,220,220,220,1,217,217,217,1,254, + 254,254,2,255,255,255,1,219,219,219,1,255,255,255,2,218,218,218,1,217, + 217,217,1,219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1,217, + 217,217,4,255,255,255,2,254,254,254,1,255,255,255,1,253,253,253,1,171, + 171,171,1,165,165,165,1,169,169,169,1,222,222,222,1,215,215,215,1,216, + 216,216,1,218,218,218,15,219,219,219,1,216,216,216,1,217,217,217,1,172, + 172,172,1,216,216,216,1,220,220,220,1,219,219,219,1,216,216,216,1,218, + 218,218,1,219,219,219,1,255,255,255,1,252,252,252,1,253,253,253,1,219, + 219,219,2,217,217,217,1,216,216,216,1,221,221,221,1,215,215,215,1,220, + 220,220,1,219,219,219,1,216,216,216,1,220,220,220,1,218,218,218,1,219, + 219,219,1,216,216,216,1,218,218,218,3,217,217,217,1,222,222,222,1,250, + 250,250,1,220,220,220,1,216,216,216,1,222,222,222,1,215,215,215,1,167, + 167,167,1,166,166,166,1,215,215,215,1,220,220,220,1,218,218,218,1,217, + 217,217,1,255,255,255,1,218,218,218,1,172,172,172,1,217,217,217,1,220, + 220,220,1,254,254,254,1,221,221,221,1,217,217,217,1,219,219,219,1,218, + 218,218,1,216,216,216,1,218,218,218,1,217,217,217,1,220,220,220,1,219, + 219,219,1,215,215,215,1,218,218,218,1,222,222,222,1,215,215,215,1,217, + 217,217,1,220,220,220,1,217,217,217,1,218,218,218,1,221,221,221,1,214, + 214,214,1,215,215,215,1,220,220,220,1,168,168,168,1,255,255,255,1,217, + 217,217,1,220,220,220,1,215,215,215,1,218,218,218,1,216,216,216,2,218, + 218,218,1,219,219,219,2,217,217,217,1,216,216,216,1,220,220,220,1,221, + 221,221,1,217,217,217,1,218,218,218,1,216,216,216,1,221,221,221,2,217, + 217,217,1,253,253,253,1,255,255,255,1,216,216,216,1,218,218,218,1,216, + 216,216,1,218,218,218,1,217,217,217,1,218,218,218,1,167,167,167,1,171, + 171,171,1,215,215,215,1,169,169,169,1,170,170,170,1,217,217,217,1,255, + 255,255,3,216,216,216,1,219,219,219,4,215,215,215,1,255,255,255,3,252, + 252,252,1,222,222,222,1,217,217,217,1,255,255,255,2,220,220,220,1,217, + 217,217,1,219,219,219,2,217,217,217,1,255,255,255,2,254,254,254,1,255, + 255,255,1,217,217,217,1,218,218,218,1,217,217,217,1,221,221,221,1,216, + 216,216,1,221,221,221,1,218,218,218,14,216,216,216,1,224,224,224,1,165, + 165,165,1,167,167,167,1,220,220,220,1,216,216,216,2,219,219,219,1,218, + 218,218,1,217,217,217,1,216,216,216,1,255,255,255,1,252,252,252,1,255, + 255,255,2,217,217,217,1,221,221,221,1,218,218,218,1,220,220,220,1,216, + 216,216,1,213,213,213,1,222,222,222,1,215,215,215,1,218,218,218,1,219, + 219,219,4,255,255,255,1,253,253,253,2,255,255,255,2,254,254,254,1,217, + 217,217,1,219,219,219,1,167,167,167,1,220,220,220,1,221,221,221,1,218, + 218,218,1,255,255,255,3,170,170,170,1,162,162,162,1,167,167,167,1,217, + 217,217,1,169,169,169,1,216,216,216,1,214,214,214,1,222,222,222,1,220, + 220,220,1,217,217,217,1,220,220,220,1,218,218,218,1,216,216,216,1,218, + 218,218,1,216,216,216,1,219,219,219,1,218,218,218,1,221,221,221,1,220, + 220,220,1,212,212,212,1,221,221,221,1,167,167,167,1,215,215,215,1,222, + 222,222,1,255,255,255,1,254,254,254,1,219,219,219,1,254,254,254,1,216, + 216,216,2,219,219,219,1,218,218,218,1,222,222,222,1,220,220,220,1,215, + 215,215,1,255,255,255,1,214,214,214,1,221,221,221,1,218,218,218,1,169, + 169,169,1,164,164,164,1,217,217,217,1,219,219,219,1,218,218,218,1,216, + 216,216,1,214,214,214,1,223,223,223,1,216,216,216,1,218,218,218,1,219, + 219,219,1,218,218,218,1,221,221,221,1,216,216,216,1,219,219,219,1,168, + 168,168,1,170,170,170,1,166,166,166,1,172,172,172,1,166,166,166,2,218, + 218,218,1,214,214,214,1,220,220,220,1,216,216,216,1,219,219,219,1,217, + 217,217,1,255,255,255,1,215,215,215,1,218,218,218,1,255,255,255,1,251, + 251,251,1,255,255,255,1,251,251,251,1,218,218,218,1,255,255,255,1,253, + 253,253,1,255,255,255,1,215,215,215,1,217,217,217,1,221,221,221,1,216, + 216,216,1,218,218,218,1,217,217,217,1,216,216,216,1,255,255,255,2,254, + 254,254,1,218,218,218,1,219,219,219,1,217,217,217,1,218,218,218,1,219, + 219,219,1,216,216,216,1,218,218,218,14,215,215,215,1,255,255,255,1,168, + 168,168,2,218,218,218,2,221,221,221,1,217,217,217,1,220,220,220,1,215, + 215,215,1,219,219,219,1,255,255,255,3,253,253,253,1,255,255,255,1,253, + 253,253,1,215,215,215,1,220,220,220,1,218,218,218,1,222,222,222,1,218, + 218,218,1,216,216,216,1,220,220,220,1,217,217,217,1,255,255,255,1,253, + 253,253,1,220,220,220,1,215,215,215,1,221,221,221,1,253,253,253,1,255, + 255,255,3,218,218,218,1,216,216,216,1,224,224,224,1,216,216,216,1,218, + 218,218,1,217,217,217,2,255,255,255,1,252,252,252,1,219,219,219,1,172, + 172,172,1,217,217,217,2,169,169,169,1,219,219,219,1,220,220,220,1,218, + 218,218,1,216,216,216,1,217,217,217,1,218,218,218,1,219,219,219,1,220, + 220,220,1,218,218,218,1,220,220,220,1,219,219,219,1,212,212,212,1,220, + 220,220,1,216,216,216,1,219,219,219,1,216,216,216,1,221,221,221,1,215, + 215,215,1,218,218,218,1,253,253,253,1,216,216,216,1,217,217,217,1,218, + 218,218,1,219,219,219,2,221,221,221,1,215,215,215,1,213,213,213,1,218, + 218,218,1,220,220,220,1,168,168,168,2,218,218,218,1,215,215,215,1,168, + 168,168,1,171,171,171,1,218,218,218,1,217,217,217,1,218,218,218,1,219, + 219,219,1,222,222,222,1,216,216,216,2,220,220,220,1,216,216,216,1,218, + 218,218,1,216,216,216,1,220,220,220,1,217,217,217,1,215,215,215,1,221, + 221,221,1,216,216,216,1,253,253,253,1,221,221,221,1,219,219,219,1,218, + 218,218,1,219,219,219,1,218,218,218,2,216,216,216,1,221,221,221,1,166, + 166,166,1,221,221,221,1,217,217,217,1,168,168,168,1,219,219,219,1,220, + 220,220,1,254,254,254,1,255,255,255,1,218,218,218,1,219,219,219,1,217, + 217,217,1,172,172,172,1,169,169,169,1,213,213,213,1,221,221,221,2,215, + 215,215,1,220,220,220,1,215,215,215,1,219,219,219,1,217,217,217,1,219, + 219,219,1,218,218,218,2,220,220,220,2,217,217,217,1,218,218,218,14,255, + 255,255,2,217,217,217,1,218,218,218,1,219,219,219,1,216,216,216,1,217, + 217,217,1,218,218,218,1,217,217,217,1,218,218,218,1,219,219,219,1,218, + 218,218,1,217,217,217,1,255,255,255,1,253,253,253,1,255,255,255,3,254, + 254,254,1,218,218,218,2,217,217,217,1,255,255,255,1,218,218,218,1,255, + 255,255,2,213,213,213,1,221,221,221,1,220,220,220,1,215,215,215,1,220, + 220,220,1,218,218,218,1,255,255,255,1,217,217,217,1,219,219,219,1,218, + 218,218,1,217,217,217,1,219,219,219,1,216,216,216,1,219,219,219,2,254, + 254,254,1,255,255,255,1,253,253,253,1,218,218,218,1,255,255,255,1,219, + 219,219,1,217,217,217,2,220,220,220,1,217,217,217,2,219,219,219,1,218, + 218,218,1,217,217,217,2,219,219,219,1,216,216,216,1,219,219,219,1,217, + 217,217,2,219,219,219,1,255,255,255,1,219,219,219,1,216,216,216,1,221, + 221,221,1,216,216,216,1,219,219,219,2,218,218,218,1,217,217,217,1,218, + 218,218,1,219,219,219,1,165,165,165,1,220,220,220,1,168,168,168,1,170, + 170,170,1,165,165,165,1,167,167,167,1,219,219,219,1,255,255,255,2,219, + 219,219,1,217,217,217,1,218,218,218,4,216,216,216,1,220,220,220,1,218, + 218,218,2,220,220,220,1,217,217,217,1,255,255,255,1,217,217,217,1,221, + 221,221,1,253,253,253,1,254,254,254,1,255,255,255,2,217,217,217,1,219, + 219,219,1,218,218,218,1,219,219,219,1,215,215,215,1,217,217,217,1,221, + 221,221,1,217,217,217,1,216,216,216,1,220,220,220,1,168,168,168,2,217, + 217,217,1,253,253,253,1,220,220,220,1,219,219,219,1,215,215,215,1,168, + 168,168,2,167,167,167,2,219,219,219,1,218,218,218,1,214,214,214,1,219, + 219,219,1,220,220,220,1,217,217,217,1,169,169,169,1,218,218,218,1,217, + 217,217,1,218,218,218,2,216,216,216,1,218,218,218,8,219,219,219,1,216, + 216,216,1,221,221,221,1,219,219,219,2,218,218,218,1,215,215,215,1,220, + 220,220,1,255,255,255,2,217,217,217,2,219,219,219,1,218,218,218,1,220, + 220,220,1,218,218,218,2,219,219,219,1,217,217,217,1,220,220,220,1,219, + 219,219,1,217,217,217,1,218,218,218,1,253,253,253,1,255,255,255,1,254, + 254,254,2,218,218,218,1,255,255,255,2,254,254,254,1,218,218,218,2,219, + 219,219,1,216,216,216,1,218,218,218,1,219,219,219,1,216,216,216,1,220, + 220,220,1,217,217,217,1,254,254,254,1,220,220,220,1,169,169,169,1,217, + 217,217,1,168,168,168,1,219,219,219,1,216,216,216,1,220,220,220,1,218, + 218,218,2,252,252,252,1,220,220,220,1,216,216,216,1,255,255,255,1,218, + 218,218,2,216,216,216,1,221,221,221,1,218,218,218,1,217,217,217,1,167, + 167,167,1,218,218,218,2,219,219,219,2,220,220,220,1,215,215,215,1,219, + 219,219,1,218,218,218,1,219,219,219,1,216,216,216,1,218,218,218,3,222, + 222,222,1,214,214,214,1,169,169,169,1,219,219,219,1,218,218,218,1,219, + 219,219,1,220,220,220,1,166,166,166,1,169,169,169,1,168,168,168,1,218, + 218,218,1,219,219,219,1,164,164,164,1,220,220,220,1,255,255,255,2,216, + 216,216,1,218,218,218,1,220,220,220,1,218,218,218,1,217,217,217,1,220, + 220,220,1,217,217,217,1,219,219,219,1,217,217,217,2,221,221,221,1,216, + 216,216,1,217,217,217,1,218,218,218,1,167,167,167,1,253,253,253,1,219, + 219,219,1,218,218,218,1,219,219,219,1,218,218,218,1,217,217,217,1,218, + 218,218,3,217,217,217,1,255,255,255,1,220,220,220,1,218,218,218,1,255, + 255,255,1,217,217,217,1,169,169,169,1,165,165,165,1,217,217,217,1,167, + 167,167,1,217,217,217,1,219,219,219,2,255,255,255,1,220,220,220,1,216, + 216,216,1,220,220,220,1,215,215,215,1,220,220,220,2,216,216,216,1,219, + 219,219,1,217,217,217,1,220,220,220,1,216,216,216,1,220,220,220,1,216, + 216,216,1,218,218,218,1,220,220,220,1,217,217,217,2,218,218,218,1,217, + 217,217,1,219,219,219,1,221,221,221,1,217,217,217,1,215,215,215,1,223, + 223,223,1,214,214,214,1,216,216,216,1,218,218,218,1,217,217,217,1,221, + 221,221,1,216,216,216,2,225,225,225,1,215,215,215,1,219,219,219,2,217, + 217,217,1,216,216,216,1,218,218,218,1,216,216,216,1,218,218,218,2,216, + 216,216,1,217,217,217,2,222,222,222,1,219,219,219,1,217,217,217,1,255, + 255,255,3,217,217,217,1,254,254,254,1,221,221,221,1,218,218,218,1,216, + 216,216,1,220,220,220,1,219,219,219,1,216,216,216,1,217,217,217,1,220, + 220,220,1,215,215,215,1,255,255,255,1,253,253,253,1,220,220,220,1,216, + 216,216,1,219,219,219,1,172,172,172,1,217,217,217,1,215,215,215,1,217, + 217,217,2,220,220,220,1,219,219,219,1,215,215,215,1,219,219,219,1,217, + 217,217,3,218,218,218,1,214,214,214,1,221,221,221,1,219,219,219,1,173, + 173,173,1,216,216,216,2,219,219,219,1,215,215,215,2,224,224,224,1,217, + 217,217,1,219,219,219,2,220,220,220,1,169,169,169,1,217,217,217,1,218, + 218,218,1,216,216,216,1,219,219,219,1,217,217,217,1,220,220,220,1,219, + 219,219,1,253,253,253,1,216,216,216,1,217,217,217,1,218,218,218,2,216, + 216,216,1,169,169,169,1,219,219,219,1,218,218,218,2,170,170,170,1,168, + 168,168,1,216,216,216,1,217,217,217,1,219,219,219,1,217,217,217,1,215, + 215,215,1,219,219,219,1,220,220,220,1,218,218,218,1,219,219,219,1,218, + 218,218,1,216,216,216,1,221,221,221,1,168,168,168,1,169,169,169,1,221, + 221,221,1,218,218,218,1,217,217,217,2,221,221,221,1,218,218,218,1,219, + 219,219,2,218,218,218,1,219,219,219,2,216,216,216,1,255,255,255,1,252, + 252,252,1,222,222,222,1,213,213,213,1,226,226,226,1,215,215,215,1,221, + 221,221,1,255,255,255,2,253,253,253,2,218,218,218,2,220,220,220,1,221, + 221,221,1,214,214,214,1,217,217,217,1,255,255,255,1,216,216,216,1,217, + 217,217,2,220,220,220,1,218,218,218,1,220,220,220,2,213,213,213,1,222, + 222,222,1,221,221,221,1,217,217,217,1,219,219,219,1,218,218,218,1,214, + 214,214,1,220,220,220,1,168,168,168,1,167,167,167,1,169,169,169,1,219, + 219,219,1,218,218,218,1,219,219,219,2,218,218,218,1,216,216,216,1,217, + 217,217,1,219,219,219,1,217,217,217,2,218,218,218,1,216,216,216,1,221, + 221,221,1,218,218,218,1,221,221,221,1,219,219,219,1,218,218,218,1,221, + 221,221,1,218,218,218,1,215,215,215,1,217,217,217,1,218,218,218,1,255, + 255,255,1,218,218,218,1,214,214,214,1,218,218,218,1,220,220,220,1,215, + 215,215,1,216,216,216,1,217,217,217,1,216,216,216,1,218,218,218,1,219, + 219,219,1,218,218,218,1,219,219,219,1,217,217,217,1,255,255,255,1,253, + 253,253,1,219,219,219,1,218,218,218,2,214,214,214,1,218,218,218,1,225, + 225,225,1,217,217,217,1,215,215,215,1,217,217,217,1,219,219,219,1,220, + 220,220,1,218,218,218,1,221,221,221,1,217,217,217,1,218,218,218,1,220, + 220,220,1,219,219,219,1,254,254,254,1,214,214,214,1,216,216,216,1,220, + 220,220,1,168,168,168,2,220,220,220,1,218,218,218,2,215,215,215,1,220, + 220,220,1,215,215,215,1,216,216,216,1,166,166,166,1,220,220,220,2,255, + 255,255,1,219,219,219,1,217,217,217,1,218,218,218,1,216,216,216,1,255, + 255,255,2,222,222,222,1,215,215,215,1,219,219,219,1,218,218,218,1,217, + 217,217,1,218,218,218,1,217,217,217,1,163,163,163,1,168,168,168,1,218, + 218,218,1,220,220,220,1,219,219,219,1,215,215,215,1,219,219,219,3,217, + 217,217,1,218,218,218,4,220,220,220,1,165,165,165,1,168,168,168,1,214, + 214,214,1,218,218,218,1,221,221,221,1,217,217,217,2,167,167,167,1,217, + 217,217,1,220,220,220,1,213,213,213,1,219,219,219,2,217,217,217,1,220, + 220,220,1,255,255,255,1,251,251,251,1,218,218,218,1,254,254,254,1,218, + 218,218,1,217,217,217,1,254,254,254,1,218,218,218,1,221,221,221,1,219, + 219,219,1,217,217,217,1,218,218,218,1,216,216,216,1,213,213,213,1,220, + 220,220,1,217,217,217,1,218,218,218,1,220,220,220,1,219,219,219,2,217, + 217,217,1,216,216,216,2,219,219,219,1,220,220,220,1,216,216,216,2,168, + 168,168,1,167,167,167,2,221,221,221,1,218,218,218,1,219,219,219,1,217, + 217,217,1,219,219,219,1,217,217,217,1,219,219,219,1,216,216,216,2,218, + 218,218,1,221,221,221,1,216,216,216,1,220,220,220,1,217,217,217,1,220, + 220,220,2,218,218,218,1,217,217,217,1,219,219,219,1,218,218,218,1,214, + 214,214,1,218,218,218,1,216,216,216,1,222,222,222,1,215,215,215,1,221, + 221,221,1,220,220,220,1,214,214,214,1,219,219,219,1,222,222,222,1,215, + 215,215,1,220,220,220,1,218,218,218,1,220,220,220,2,217,217,217,1,219, + 219,219,1,218,218,218,1,216,216,216,1,217,217,217,1,220,220,220,1,217, + 217,217,1,219,219,219,1,215,215,215,1,255,255,255,1,220,220,220,1,217, + 217,217,1,221,221,221,1,215,215,215,1,219,219,219,1,218,218,218,1,221, + 221,221,1,217,217,217,2,214,214,214,1,216,216,216,1,220,220,220,1,217, + 217,217,1,166,166,166,2,255,255,255,1,222,222,222,1,215,215,215,1,168, + 168,168,1,170,170,170,1,167,167,167,1,218,218,218,1,219,219,219,1,218, + 218,218,1,221,221,221,1,215,215,215,1,255,255,255,1,218,218,218,1,221, + 221,221,1,218,218,218,1,215,215,215,1,217,217,217,2,220,220,220,1,221, + 221,221,1,169,169,169,1,216,216,216,1,254,254,254,1,252,252,252,1,255, + 255,255,2,216,216,216,1,221,221,221,1,218,218,218,1,253,253,253,1,255, + 255,255,1,168,168,168,1,217,217,217,2,219,219,219,1,220,220,220,1,217, + 217,217,1,219,219,219,1,218,218,218,1,216,216,216,1,218,218,218,1,255, + 255,255,1,218,218,218,1,219,219,219,1,215,215,215,1,169,169,169,1,170, + 170,170,1,168,168,168,1,220,220,220,1,219,219,219,1,218,218,218,2,165, + 165,165,1,220,220,220,1,217,217,217,1,223,223,223,1,218,218,218,1,217, + 217,217,1,220,220,220,1,211,211,211,1,223,223,223,1,219,219,219,1,218, + 218,218,1,216,216,216,1,222,222,222,1,217,217,217,1,222,222,222,1,216, + 216,216,1,218,218,218,1,217,217,217,1,220,220,220,1,216,216,216,1,219, + 219,219,1,221,221,221,1,220,220,220,2,214,214,214,1,217,217,217,1,216, + 216,216,1,218,218,218,1,219,219,219,1,221,221,221,1,218,218,218,2,216, + 216,216,2,219,219,219,1,171,171,171,1,169,169,169,2,214,214,214,1,218, + 218,218,1,254,254,254,1,220,220,220,2,214,214,214,1,217,217,217,2,222, + 222,222,1,219,219,219,1,217,217,217,1,215,215,215,1,220,220,220,1,218, + 218,218,1,219,219,219,1,216,216,216,1,220,220,220,1,217,217,217,1,216, + 216,216,1,222,222,222,1,169,169,169,1,222,222,222,1,216,216,216,2,222, + 222,222,1,214,214,214,1,219,219,219,1,221,221,221,1,216,216,216,2,219, + 219,219,1,216,216,216,1,217,217,217,2,219,219,219,2,215,215,215,1,223, + 223,223,1,218,218,218,2,217,217,217,1,220,220,220,1,255,255,255,1,218, + 218,218,2,216,216,216,1,221,221,221,1,214,214,214,1,216,216,216,1,220, + 220,220,1,219,219,219,1,167,167,167,1,214,214,214,1,223,223,223,1,220, + 220,220,2,218,218,218,1,219,219,219,1,218,218,218,1,219,219,219,2,218, + 218,218,1,255,255,255,1,253,253,253,1,219,219,219,1,218,218,218,1,219, + 219,219,1,215,215,215,1,219,219,219,1,216,216,216,1,220,220,220,1,255, + 255,255,1,217,217,217,1,216,216,216,1,218,218,218,1,223,223,223,1,167, + 167,167,1,170,170,170,1,167,167,167,1,165,165,165,1,172,172,172,1,217, + 217,217,1,223,223,223,1,255,255,255,1,219,219,219,1,218,218,218,1,216, + 216,216,1,217,217,217,1,218,218,218,1,220,220,220,1,214,214,214,1,220, + 220,220,1,216,216,216,1,218,218,218,1,220,220,220,1,217,217,217,1,218, + 218,218,3,219,219,219,1,253,253,253,1,254,254,254,1,255,255,255,1,253, + 253,253,1,221,221,221,1,169,169,169,1,166,166,166,1,168,168,168,1,167, + 167,167,1,219,219,219,1,251,251,251,1,221,221,221,1,220,220,220,1,218, + 218,218,1,215,215,215,1,216,216,216,1,218,218,218,1,215,215,215,1,219, + 219,219,1,221,221,221,1,218,218,218,1,216,216,216,1,219,219,219,1,221, + 221,221,1,212,212,212,1,219,219,219,2,217,217,217,1,221,221,221,1,218, + 218,218,1,215,215,215,1,219,219,219,1,217,217,217,1,213,213,213,1,221, + 221,221,1,214,214,214,1,221,221,221,1,217,217,217,1,220,220,220,1,216, + 216,216,1,219,219,219,1,215,215,215,1,217,217,217,1,221,221,221,1,216, + 216,216,1,255,255,255,1,216,216,216,1,218,218,218,1,166,166,166,1,218, + 218,218,1,219,219,219,1,218,218,218,3,217,217,217,1,220,220,220,1,219, + 219,219,1,220,220,220,1,214,214,214,1,218,218,218,1,220,220,220,1,219, + 219,219,2,217,217,217,1,218,218,218,1,214,214,214,1,221,221,221,1,218, + 218,218,1,221,221,221,1,214,214,214,1,170,170,170,1,165,165,165,1,170, + 170,170,1,219,219,219,2,217,217,217,1,212,212,212,1,222,222,222,1,216, + 216,216,1,221,221,221,1,218,218,218,1,222,222,222,1,214,214,214,1,220, + 220,220,1,165,165,165,2,221,221,221,1,216,216,216,1,220,220,220,1,217, + 217,217,3,218,218,218,3,219,219,219,1,218,218,218,1,221,221,221,1,218, + 218,218,1,219,219,219,1,216,216,216,1,220,220,220,1,221,221,221,1,214, + 214,214,1,217,217,217,1,218,218,218,1,254,254,254,2,218,218,218,1,217, + 217,217,2,255,255,255,1,252,252,252,1,255,255,255,1,216,216,216,1,218, + 218,218,3,217,217,217,1,221,221,221,1,216,216,216,1,217,217,217,1,169, + 169,169,1,218,218,218,2,166,166,166,2,169,169,169,1,216,216,216,1,218, + 218,218,1,168,168,168,2,164,164,164,1,171,171,171,1,167,167,167,1,166, + 166,166,1,222,222,222,1,215,215,215,1,217,217,217,1,255,255,255,1,220, + 220,220,1,216,216,216,1,222,222,222,1,219,219,219,1,217,217,217,1,216, + 216,216,1,171,171,171,1,216,216,216,1,217,217,217,1,220,220,220,1,255, + 255,255,1,253,253,253,1,255,255,255,1,218,218,218,1,216,216,216,2,169, + 169,169,1,167,167,167,1,168,168,168,2,218,218,218,1,219,219,219,1,217, + 217,217,2,221,221,221,1,218,218,218,1,216,216,216,1,222,222,222,1,219, + 219,219,1,218,218,218,1,216,216,216,1,219,219,219,1,217,217,217,2,221, + 221,221,1,217,217,217,1,219,219,219,1,216,216,216,2,220,220,220,1,222, + 222,222,1,216,216,216,1,219,219,219,2,217,217,217,1,216,216,216,1,219, + 219,219,1,218,218,218,2,216,216,216,1,219,219,219,1,220,220,220,1,216, + 216,216,2,220,220,220,1,253,253,253,1,220,220,220,1,218,218,218,3,220, + 220,220,1,216,216,216,1,218,218,218,1,215,215,215,1,220,220,220,1,216, + 216,216,1,219,219,219,1,217,217,217,1,222,222,222,1,216,216,216,1,217, + 217,217,3,218,218,218,1,220,220,220,1,218,218,218,1,219,219,219,1,216, + 216,216,1,254,254,254,1,219,219,219,2,218,218,218,1,164,164,164,1,217, + 217,217,1,218,218,218,1,220,220,220,2,217,217,217,1,218,218,218,1,217, + 217,217,1,218,218,218,1,216,216,216,1,220,220,220,1,218,218,218,1,171, + 171,171,1,220,220,220,1,216,216,216,1,217,217,217,1,218,218,218,2,221, + 221,221,1,217,217,217,2,219,219,219,1,215,215,215,1,220,220,220,1,218, + 218,218,1,217,217,217,1,221,221,221,1,252,252,252,1,220,220,220,1,219, + 219,219,1,216,216,216,1,217,217,217,1,219,219,219,3,218,218,218,1,219, + 219,219,2,217,217,217,1,221,221,221,1,219,219,219,1,213,213,213,1,224, + 224,224,1,218,218,218,1,217,217,217,1,220,220,220,1,219,219,219,1,215, + 215,215,1,222,222,222,1,219,219,219,1,214,214,214,1,219,219,219,1,255, + 255,255,1,254,254,254,1,220,220,220,2,217,217,217,1,219,219,219,1,220, + 220,220,1,167,167,167,1,216,216,216,1,171,171,171,1,216,216,216,1,168, + 168,168,1,254,254,254,1,255,255,255,1,213,213,213,1,218,218,218,2,216, + 216,216,1,217,217,217,1,218,218,218,1,214,214,214,1,220,220,220,1,218, + 218,218,3,219,219,219,1,213,213,213,1,171,171,171,1,216,216,216,1,219, + 219,219,1,221,221,221,1,219,219,219,1,216,216,216,1,173,173,173,1,167, + 167,167,1,165,165,165,1,171,171,171,1,214,214,214,1,219,219,219,2,218, + 218,218,1,216,216,216,1,221,221,221,1,217,217,217,1,166,166,166,1,218, + 218,218,1,220,220,220,1,218,218,218,1,217,217,217,1,218,218,218,1,217, + 217,217,1,219,219,219,3,218,218,218,1,217,217,217,1,215,215,215,1,219, + 219,219,1,215,215,215,1,221,221,221,1,214,214,214,1,219,219,219,1,220, + 220,220,1,215,215,215,1,218,218,218,2,216,216,216,1,221,221,221,1,217, + 217,217,1,220,220,220,1,254,254,254,1,255,255,255,1,252,252,252,1,219, + 219,219,2,218,218,218,1,217,217,217,1,219,219,219,2,217,217,217,1,219, + 219,219,1,216,216,216,1,219,219,219,2,215,215,215,1,220,220,220,1,219, + 219,219,3,217,217,217,1,218,218,218,2,217,217,217,1,219,219,219,1,255, + 255,255,1,253,253,253,1,255,255,255,1,219,219,219,1,221,221,221,1,168, + 168,168,1,167,167,167,1,217,217,217,1,218,218,218,1,219,219,219,2,218, + 218,218,1,216,216,216,1,219,219,219,1,255,255,255,1,254,254,254,1,218, + 218,218,1,216,216,216,1,218,218,218,1,219,219,219,1,221,221,221,1,215, + 215,215,1,219,219,219,1,218,218,218,1,217,217,217,1,221,221,221,1,216, + 216,216,1,220,220,220,1,216,216,216,1,218,218,218,2,220,220,220,1,218, + 218,218,1,216,216,216,1,219,219,219,2,218,218,218,1,215,215,215,1,221, + 221,221,1,217,217,217,1,219,219,219,1,215,215,215,1,220,220,220,1,217, + 217,217,1,220,220,220,1,219,219,219,1,214,214,214,1,217,217,217,1,218, + 218,218,3,217,217,217,1,255,255,255,1,218,218,218,1,219,219,219,1,254, + 254,254,2,255,255,255,1,216,216,216,1,254,254,254,1,255,255,255,1,217, + 217,217,1,218,218,218,1,255,255,255,3,218,218,218,1,168,168,168,1,220, + 220,220,1,215,215,215,1,220,220,220,1,218,218,218,3,168,168,168,1,217, + 217,217,1,255,255,255,1,218,218,218,1,215,215,215,1,170,170,170,1,168, + 168,168,2,171,171,171,1,214,214,214,1,219,219,219,1,220,220,220,1,216, + 216,216,1,219,219,219,1,220,220,220,1,214,214,214,1,220,220,220,1,169, + 169,169,1,167,167,167,1,219,219,219,1,217,217,217,2,218,218,218,2,219, + 219,219,1,217,217,217,1,168,168,168,1,219,219,219,1,217,217,217,1,218, + 218,218,1,219,219,219,1,217,217,217,1,220,220,220,1,215,215,215,1,218, + 218,218,4,220,220,220,1,215,215,215,1,220,220,220,1,217,217,217,1,218, + 218,218,2,216,216,216,1,220,220,220,1,219,219,219,1,217,217,217,1,219, + 219,219,1,218,218,218,2,217,217,217,1,255,255,255,2,220,220,220,1,218, + 218,218,1,165,165,165,1,171,171,171,1,216,216,216,1,218,218,218,1,217, + 217,217,1,222,222,222,1,218,218,218,1,215,215,215,1,221,221,221,1,218, + 218,218,1,214,214,214,1,220,220,220,1,217,217,217,1,218,218,218,4,223, + 223,223,1,216,216,216,1,218,218,218,1,216,216,216,1,219,219,219,1,254, + 254,254,1,217,217,217,1,218,218,218,1,220,220,220,1,218,218,218,3,217, + 217,217,1,168,168,168,1,219,219,219,1,218,218,218,1,220,220,220,1,255, + 255,255,1,217,217,217,1,219,219,219,2,216,216,216,1,217,217,217,1,219, + 219,219,1,218,218,218,1,216,216,216,1,219,219,219,1,218,218,218,1,221, + 221,221,1,216,216,216,1,219,219,219,1,217,217,217,2,220,220,220,1,217, + 217,217,1,220,220,220,1,215,215,215,1,221,221,221,1,218,218,218,2,217, + 217,217,1,220,220,220,1,218,218,218,2,219,219,219,1,218,218,218,1,217, + 217,217,1,219,219,219,1,217,217,217,1,220,220,220,1,217,217,217,1,218, + 218,218,1,216,216,216,1,220,220,220,1,214,214,214,1,220,220,220,1,221, + 221,221,1,215,215,215,1,219,219,219,1,255,255,255,1,252,252,252,1,255, + 255,255,3,254,254,254,1,255,255,255,2,218,218,218,1,255,255,255,1,218, + 218,218,1,171,171,171,1,167,167,167,2,169,169,169,1,216,216,216,1,171, + 171,171,1,165,165,165,1,169,169,169,1,218,218,218,2,219,219,219,1,216, + 216,216,1,168,168,168,1,167,167,167,1,218,218,218,1,220,220,220,1,217, + 217,217,1,222,222,222,1,215,215,215,1,220,220,220,1,218,218,218,1,219, + 219,219,1,216,216,216,1,219,219,219,1,169,169,169,1,216,216,216,1,217, + 217,217,1,220,220,220,1,217,217,217,1,218,218,218,1,220,220,220,1,216, + 216,216,1,220,220,220,1,218,218,218,2,217,217,217,1,218,218,218,1,216, + 216,216,1,217,217,217,1,219,219,219,1,220,220,220,1,216,216,216,1,168, + 168,168,1,167,167,167,3,170,170,170,1,168,168,168,1,218,218,218,1,219, + 219,219,1,218,218,218,1,219,219,219,1,217,217,217,1,219,219,219,1,218, + 218,218,2,217,217,217,1,221,221,221,1,217,217,217,1,215,215,215,1,219, + 219,219,1,218,218,218,1,170,170,170,1,167,167,167,1,171,171,171,1,215, + 215,215,1,220,220,220,1,217,217,217,1,216,216,216,1,220,220,220,2,216, + 216,216,1,218,218,218,1,223,223,223,1,216,216,216,1,220,220,220,1,221, + 221,221,1,215,215,215,1,219,219,219,1,216,216,216,1,214,214,214,1,221, + 221,221,1,218,218,218,1,220,220,220,2,217,217,217,1,253,253,253,1,255, + 255,255,1,218,218,218,1,214,214,214,1,218,218,218,1,217,217,217,1,219, + 219,219,1,218,218,218,1,168,168,168,1,167,167,167,1,215,215,215,1,217, + 217,217,1,219,219,219,1,216,216,216,2,220,220,220,1,222,222,222,1,216, + 216,216,1,219,219,219,2,218,218,218,1,216,216,216,1,215,215,215,1,218, + 218,218,1,220,220,220,1,218,218,218,1,220,220,220,1,214,214,214,1,220, + 220,220,1,215,215,215,1,220,220,220,1,217,217,217,2,218,218,218,1,219, + 219,219,1,218,218,218,1,217,217,217,1,220,220,220,1,216,216,216,1,220, + 220,220,1,219,219,219,1,217,217,217,1,220,220,220,1,214,214,214,1,220, + 220,220,1,221,221,221,1,218,218,218,1,216,216,216,1,222,222,222,1,217, + 217,217,1,163,163,163,1,170,170,170,1,167,167,167,1,252,252,252,1,221, + 221,221,1,219,219,219,1,254,254,254,1,255,255,255,1,216,216,216,1,220, + 220,220,1,218,218,218,1,219,219,219,1,253,253,253,1,166,166,166,1,217, + 217,217,1,170,170,170,1,169,169,169,1,168,168,168,1,171,171,171,1,215, + 215,215,1,168,168,168,1,167,167,167,1,222,222,222,1,218,218,218,1,254, + 254,254,1,255,255,255,1,254,254,254,1,220,220,220,1,215,215,215,1,217, + 217,217,1,218,218,218,1,212,212,212,1,220,220,220,1,217,217,217,2,216, + 216,216,1,223,223,223,1,215,215,215,1,219,219,219,1,221,221,221,1,219, + 219,219,2,217,217,217,1,218,218,218,2,253,253,253,1,219,219,219,1,166, + 166,166,1,168,168,168,1,170,170,170,1,219,219,219,1,220,220,220,1,218, + 218,218,2,166,166,166,1,168,168,168,1,166,166,166,1,170,170,170,1,171, + 171,171,1,170,170,170,1,165,165,165,1,218,218,218,1,220,220,220,1,219, + 219,219,1,216,216,216,1,221,221,221,1,217,217,217,1,218,218,218,1,217, + 217,217,2,219,219,219,1,215,215,215,1,217,217,217,1,222,222,222,1,218, + 218,218,1,255,255,255,1,253,253,253,1,166,166,166,1,216,216,216,1,221, + 221,221,1,218,218,218,2,219,219,219,1,216,216,216,1,222,222,222,1,217, + 217,217,1,220,220,220,1,215,215,215,1,218,218,218,1,217,217,217,1,214, + 214,214,1,220,220,220,1,216,216,216,1,221,221,221,1,218,218,218,1,216, + 216,216,1,218,218,218,1,216,216,216,1,215,215,215,1,219,219,219,1,220, + 220,220,1,218,218,218,1,216,216,216,1,221,221,221,1,219,219,219,1,255, + 255,255,1,217,217,217,2,170,170,170,1,215,215,215,1,219,219,219,3,222, + 222,222,1,219,219,219,1,216,216,216,3,219,219,219,1,217,217,217,1,218, + 218,218,1,220,220,220,1,222,222,222,1,216,216,216,1,220,220,220,1,215, + 215,215,1,217,217,217,1,223,223,223,1,215,215,215,1,222,222,222,1,218, + 218,218,1,219,219,219,1,218,218,218,1,219,219,219,1,218,218,218,1,217, + 217,217,1,219,219,219,1,216,216,216,1,217,217,217,1,219,219,219,1,218, + 218,218,1,217,217,217,1,220,220,220,1,218,218,218,2,217,217,217,1,218, + 218,218,1,219,219,219,1,215,215,215,1,218,218,218,1,170,170,170,1,169, + 169,169,1,167,167,167,1,171,171,171,1,217,217,217,1,218,218,218,1,217, + 217,217,1,215,215,215,1,169,169,169,2,218,218,218,1,219,219,219,2,223, + 223,223,1,253,253,253,1,214,214,214,1,170,170,170,1,214,214,214,1,218, + 218,218,1,223,223,223,1,215,215,215,1,169,169,169,1,216,216,216,2,253, + 253,253,1,255,255,255,1,218,218,218,1,252,252,252,1,255,255,255,1,220, + 220,220,1,218,218,218,1,222,222,222,1,220,220,220,1,218,218,218,1,255, + 255,255,2,254,254,254,1,169,169,169,1,167,167,167,1,216,216,216,1,213, + 213,213,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,222, + 222,222,1,219,219,219,1,166,166,166,1,168,168,168,1,172,172,172,1,164, + 164,164,1,169,169,169,1,165,165,165,1,167,167,167,1,220,220,220,1,215, + 215,215,1,222,222,222,1,214,214,214,1,216,216,216,1,217,217,217,1,168, + 168,168,1,217,217,217,1,221,221,221,1,214,214,214,1,220,220,220,1,217, + 217,217,1,218,218,218,1,219,219,219,1,218,218,218,1,219,219,219,1,170, + 170,170,1,214,214,214,1,221,221,221,1,219,219,219,1,253,253,253,1,255, + 255,255,2,219,219,219,1,221,221,221,1,215,215,215,1,218,218,218,1,220, + 220,220,1,217,217,217,1,219,219,219,1,214,214,214,1,219,219,219,2,220, + 220,220,1,218,218,218,1,216,216,216,1,223,223,223,1,214,214,214,1,220, + 220,220,1,217,217,217,1,171,171,171,1,167,167,167,1,217,217,217,1,218, + 218,218,1,221,221,221,1,217,217,217,3,218,218,218,1,220,220,220,1,215, + 215,215,1,168,168,168,1,254,254,254,1,255,255,255,1,214,214,214,1,225, + 225,225,1,216,216,216,1,219,219,219,2,216,216,216,2,219,219,219,3,215, + 215,215,1,168,168,168,1,169,169,169,1,218,218,218,1,219,219,219,1,215, + 215,215,1,219,219,219,1,218,218,218,1,219,219,219,1,218,218,218,1,216, + 216,216,1,217,217,217,3,218,218,218,1,216,216,216,1,222,222,222,1,218, + 218,218,1,217,217,217,1,220,220,220,1,221,221,221,1,218,218,218,1,214, + 214,214,1,218,218,218,1,215,215,215,1,221,221,221,1,217,217,217,1,216, + 216,216,1,218,218,218,2,255,255,255,2,216,216,216,1,167,167,167,1,169, + 169,169,1,165,165,165,1,218,218,218,1,220,220,220,1,168,168,168,1,171, + 171,171,1,168,168,168,1,217,217,217,1,218,218,218,1,255,255,255,1,166, + 166,166,1,219,219,219,1,254,254,254,1,255,255,255,2,218,218,218,1,255, + 255,255,1,252,252,252,1,170,170,170,1,217,217,217,1,219,219,219,1,222, + 222,222,1,217,217,217,1,218,218,218,1,255,255,255,2,254,254,254,1,217, + 217,217,1,216,216,216,1,217,217,217,2,215,215,215,1,255,255,255,2,218, + 218,218,1,168,168,168,1,172,172,172,1,169,169,169,1,219,219,219,1,167, + 167,167,1,165,165,165,1,167,167,167,1,166,166,166,1,254,254,254,1,255, + 255,255,1,253,253,253,1,167,167,167,1,166,166,166,1,171,171,171,1,165, + 165,165,1,220,220,220,1,218,218,218,2,221,221,221,1,214,214,214,1,221, + 221,221,1,220,220,220,1,168,168,168,1,170,170,170,1,219,219,219,1,218, + 218,218,1,219,219,219,1,218,218,218,1,216,216,216,1,218,218,218,2,216, + 216,216,1,219,219,219,1,215,215,215,1,221,221,221,1,214,214,214,1,217, + 217,217,1,220,220,220,1,255,255,255,1,217,217,217,1,216,216,216,2,220, + 220,220,1,217,217,217,2,216,216,216,1,170,170,170,1,219,219,219,1,218, + 218,218,1,214,214,214,1,220,220,220,1,219,219,219,2,217,217,217,2,220, + 220,220,1,166,166,166,2,170,170,170,1,218,218,218,1,217,217,217,1,218, + 218,218,1,220,220,220,1,216,216,216,1,223,223,223,1,216,216,216,2,221, + 221,221,1,166,166,166,1,255,255,255,1,221,221,221,1,219,219,219,1,213, + 213,213,1,216,216,216,1,221,221,221,1,216,216,216,1,219,219,219,1,218, + 218,218,1,222,222,222,1,214,214,214,1,216,216,216,1,222,222,222,1,167, + 167,167,3,219,219,219,1,221,221,221,1,217,217,217,1,220,220,220,1,216, + 216,216,1,219,219,219,1,222,222,222,1,219,219,219,1,167,167,167,1,222, + 222,222,1,216,216,216,1,219,219,219,1,215,215,215,1,218,218,218,1,221, + 221,221,1,218,218,218,1,215,215,215,1,217,217,217,1,219,219,219,1,221, + 221,221,1,219,219,219,1,218,218,218,2,219,219,219,2,216,216,216,1,255, + 255,255,1,216,216,216,1,220,220,220,1,217,217,217,1,167,167,167,1,170, + 170,170,1,219,219,219,1,168,168,168,1,216,216,216,1,215,215,215,1,219, + 219,219,1,216,216,216,1,255,255,255,2,215,215,215,1,217,217,217,1,220, + 220,220,1,215,215,215,1,217,217,217,1,222,222,222,1,165,165,165,1,216, + 216,216,1,167,167,167,1,221,221,221,1,218,218,218,1,212,212,212,1,255, + 255,255,1,167,167,167,2,251,251,251,1,255,255,255,1,219,219,219,1,218, + 218,218,2,167,167,167,1,170,170,170,1,219,219,219,1,254,254,254,2,215, + 215,215,1,216,216,216,1,221,221,221,1,214,214,214,1,218,218,218,1,171, + 171,171,1,170,170,170,1,168,168,168,1,255,255,255,1,254,254,254,1,255, + 255,255,2,215,215,215,1,217,217,217,2,218,218,218,1,219,219,219,1,217, + 217,217,2,220,220,220,1,216,216,216,1,215,215,215,1,170,170,170,1,168, + 168,168,1,213,213,213,1,219,219,219,1,220,220,220,1,216,216,216,1,220, + 220,220,1,218,218,218,1,220,220,220,1,255,255,255,1,218,218,218,2,217, + 217,217,1,219,219,219,1,221,221,221,1,216,216,216,1,218,218,218,1,220, + 220,220,1,216,216,216,1,223,223,223,1,220,220,220,1,217,217,217,1,169, + 169,169,2,216,216,216,1,218,218,218,1,220,220,220,1,218,218,218,2,216, + 216,216,1,218,218,218,1,217,217,217,1,219,219,219,1,217,217,217,1,254, + 254,254,1,170,170,170,1,168,168,168,1,167,167,167,1,218,218,218,1,216, + 216,216,1,220,220,220,1,217,217,217,1,213,213,213,1,223,223,223,1,254, + 254,254,1,216,216,216,1,219,219,219,1,218,218,218,1,214,214,214,1,219, + 219,219,1,220,220,220,1,221,221,221,1,217,217,217,1,220,220,220,1,219, + 219,219,1,216,216,216,1,215,215,215,1,219,219,219,1,255,255,255,1,253, + 253,253,1,219,219,219,1,168,168,168,1,219,219,219,1,216,216,216,1,218, + 218,218,1,217,217,217,2,223,223,223,1,215,215,215,1,217,217,217,1,219, + 219,219,1,215,215,215,1,220,220,220,1,219,219,219,1,218,218,218,1,220, + 220,220,1,217,217,217,1,216,216,216,1,219,219,219,1,223,223,223,1,215, + 215,215,1,169,169,169,1,166,166,166,1,216,216,216,1,219,219,219,1,217, + 217,217,2,219,219,219,1,167,167,167,1,216,216,216,1,219,219,219,1,218, + 218,218,2,169,169,169,1,168,168,168,1,255,255,255,1,217,217,217,2,220, + 220,220,1,216,216,216,1,222,222,222,1,255,255,255,2,218,218,218,1,168, + 168,168,2,218,218,218,1,168,168,168,1,169,169,169,1,219,219,219,1,170, + 170,170,1,166,166,166,1,218,218,218,1,217,217,217,1,255,255,255,1,219, + 219,219,1,217,217,217,1,171,171,171,1,220,220,220,1,255,255,255,1,254, + 254,254,1,255,255,255,2,216,216,216,1,219,219,219,1,166,166,166,1,216, + 216,216,1,255,255,255,2,217,217,217,1,253,253,253,1,255,255,255,1,251, + 251,251,1,219,219,219,1,167,167,167,1,219,219,219,1,217,217,217,1,255, + 255,255,2,251,251,251,1,255,255,255,1,218,218,218,3,217,217,217,1,219, + 219,219,1,218,218,218,1,216,216,216,1,217,217,217,1,221,221,221,1,165, + 165,165,1,171,171,171,1,221,221,221,1,214,214,214,1,217,217,217,1,221, + 221,221,1,216,216,216,1,218,218,218,1,217,217,217,1,218,218,218,2,219, + 219,219,1,218,218,218,1,215,215,215,1,220,220,220,1,217,217,217,1,216, + 216,216,1,219,219,219,1,218,218,218,1,212,212,212,1,217,217,217,1,216, + 216,216,1,219,219,219,1,165,165,165,1,173,173,173,1,168,168,168,1,165, + 165,165,1,219,219,219,1,218,218,218,1,220,220,220,1,219,219,219,1,168, + 168,168,1,219,219,219,1,218,218,218,2,169,169,169,1,165,165,165,1,170, + 170,170,1,221,221,221,1,217,217,217,1,216,216,216,1,217,217,217,1,222, + 222,222,1,164,164,164,1,255,255,255,1,220,220,220,1,217,217,217,1,219, + 219,219,1,218,218,218,2,219,219,219,1,216,216,216,1,215,215,215,1,220, + 220,220,1,217,217,217,1,221,221,221,1,218,218,218,2,252,252,252,1,255, + 255,255,2,218,218,218,1,168,168,168,1,217,217,217,1,220,220,220,1,218, + 218,218,1,220,220,220,1,215,215,215,1,219,219,219,2,217,217,217,1,224, + 224,224,1,214,214,214,1,216,216,216,1,217,217,217,1,218,218,218,2,220, + 220,220,1,216,216,216,1,215,215,215,1,168,168,168,1,169,169,169,1,170, + 170,170,1,165,165,165,1,218,218,218,1,220,220,220,1,215,215,215,1,219, + 219,219,1,255,255,255,1,218,218,218,1,217,217,217,1,216,216,216,1,221, + 221,221,1,167,167,167,1,219,219,219,1,215,215,215,1,222,222,222,1,172, + 172,172,1,212,212,212,1,217,217,217,1,218,218,218,1,216,216,216,1,254, + 254,254,1,255,255,255,1,221,221,221,1,254,254,254,1,219,219,219,1,255, + 255,255,1,254,254,254,1,255,255,255,1,219,219,219,1,169,169,169,1,218, + 218,218,1,168,168,168,1,255,255,255,1,254,254,254,1,218,218,218,1,166, + 166,166,1,218,218,218,1,254,254,254,1,255,255,255,1,254,254,254,1,251, + 251,251,1,220,220,220,1,219,219,219,1,218,218,218,1,167,167,167,1,220, + 220,220,1,215,215,215,1,217,217,217,1,255,255,255,2,254,254,254,1,255, + 255,255,1,219,219,219,1,218,218,218,2,216,216,216,1,254,254,254,1,255, + 255,255,1,217,217,217,1,218,218,218,2,222,222,222,1,217,217,217,1,216, + 216,216,1,220,220,220,2,221,221,221,1,213,213,213,1,168,168,168,1,167, + 167,167,1,219,219,219,1,221,221,221,1,220,220,220,1,215,215,215,1,220, + 220,220,1,216,216,216,1,219,219,219,1,218,218,218,1,219,219,219,1,218, + 218,218,1,219,219,219,1,218,218,218,2,219,219,219,1,218,218,218,1,219, + 219,219,1,221,221,221,1,220,220,220,1,218,218,218,2,169,169,169,1,165, + 165,165,1,168,168,168,1,167,167,167,1,220,220,220,1,219,219,219,1,217, + 217,217,2,167,167,167,1,217,217,217,1,170,170,170,1,215,215,215,1,221, + 221,221,1,219,219,219,1,167,167,167,1,218,218,218,1,217,217,217,1,218, + 218,218,1,217,217,217,1,221,221,221,1,216,216,216,1,168,168,168,1,167, + 167,167,1,217,217,217,1,218,218,218,3,220,220,220,1,217,217,217,1,219, + 219,219,1,218,218,218,2,217,217,217,1,219,219,219,1,218,218,218,1,217, + 217,217,1,220,220,220,1,255,255,255,1,214,214,214,1,219,219,219,1,168, + 168,168,1,218,218,218,1,217,217,217,1,220,220,220,1,216,216,216,1,220, + 220,220,1,221,221,221,1,165,165,165,1,218,218,218,3,219,219,219,1,220, + 220,220,1,217,217,217,3,219,219,219,1,255,255,255,1,217,217,217,1,167, + 167,167,1,166,166,166,1,170,170,170,1,218,218,218,1,167,167,167,1,220, + 220,220,1,253,253,253,1,254,254,254,1,219,219,219,1,218,218,218,1,219, + 219,219,1,217,217,217,1,168,168,168,1,219,219,219,1,216,216,216,1,169, + 169,169,1,216,216,216,1,220,220,220,2,217,217,217,1,219,219,219,1,255, + 255,255,1,254,254,254,2,255,255,255,2,253,253,253,1,255,255,255,2,166, + 166,166,1,167,167,167,1,169,169,169,1,168,168,168,2,218,218,218,1,255, + 255,255,1,219,219,219,1,169,169,169,1,216,216,216,1,215,215,215,1,220, + 220,220,1,221,221,221,1,254,254,254,2,219,219,219,2,217,217,217,1,219, + 219,219,1,169,169,169,1,216,216,216,1,255,255,255,2,217,217,217,1,218, + 218,218,2,219,219,219,3,255,255,255,1,215,215,215,1,218,218,218,1,219, + 219,219,1,213,213,213,1,255,255,255,1,217,217,217,1,218,218,218,1,254, + 254,254,1,253,253,253,1,221,221,221,1,169,169,169,1,167,167,167,1,170, + 170,170,1,215,215,215,1,217,217,217,1,221,221,221,1,216,216,216,1,220, + 220,220,1,218,218,218,1,217,217,217,1,219,219,219,1,217,217,217,1,219, + 219,219,2,216,216,216,1,219,219,219,1,218,218,218,1,216,216,216,1,217, + 217,217,1,218,218,218,1,217,217,217,1,220,220,220,1,218,218,218,1,217, + 217,217,1,219,219,219,1,218,218,218,2,217,217,217,1,220,220,220,1,217, + 217,217,1,219,219,219,1,217,217,217,1,218,218,218,1,221,221,221,1,211, + 211,211,1,222,222,222,1,220,220,220,1,217,217,217,1,219,219,219,1,218, + 218,218,1,215,215,215,1,255,255,255,1,218,218,218,1,220,220,220,1,171, + 171,171,1,215,215,215,1,217,217,217,1,220,220,220,1,217,217,217,1,219, + 219,219,1,218,218,218,1,221,221,221,1,217,217,217,1,218,218,218,1,219, + 219,219,1,215,215,215,1,220,220,220,1,217,217,217,1,219,219,219,1,217, + 217,217,1,255,255,255,1,217,217,217,1,168,168,168,1,166,166,166,1,218, + 218,218,1,220,220,220,1,219,219,219,1,255,255,255,1,218,218,218,3,217, + 217,217,1,218,218,218,1,217,217,217,1,218,218,218,1,221,221,221,1,217, + 217,217,1,218,218,218,1,254,254,254,1,253,253,253,1,219,219,219,1,220, + 220,220,1,165,165,165,1,219,219,219,2,216,216,216,1,217,217,217,1,219, + 219,219,1,218,218,218,2,217,217,217,1,216,216,216,1,255,255,255,1,254, + 254,254,1,218,218,218,1,219,219,219,1,166,166,166,1,167,167,167,1,219, + 219,219,3,217,217,217,1,255,255,255,1,215,215,215,1,220,220,220,1,170, + 170,170,1,166,166,166,1,169,169,169,2,219,219,219,1,167,167,167,1,218, + 218,218,1,169,169,169,1,218,218,218,1,169,169,169,1,216,216,216,1,254, + 254,254,1,220,220,220,1,218,218,218,1,216,216,216,1,222,222,222,1,217, + 217,217,3,255,255,255,1,219,219,219,1,218,218,218,2,168,168,168,1,170, + 170,170,1,168,168,168,1,167,167,167,1,218,218,218,1,217,217,217,1,218, + 218,218,2,216,216,216,1,217,217,217,1,255,255,255,2,215,215,215,1,218, + 218,218,1,217,217,217,1,255,255,255,1,252,252,252,1,255,255,255,1,254, + 254,254,1,253,253,253,1,255,255,255,1,254,254,254,1,170,170,170,1,165, + 165,165,1,219,219,219,4,218,218,218,2,220,220,220,1,213,213,213,1,221, + 221,221,1,218,218,218,1,217,217,217,1,218,218,218,1,222,222,222,1,217, + 217,217,2,220,220,220,1,218,218,218,2,217,217,217,1,215,215,215,1,216, + 216,216,1,219,219,219,1,167,167,167,1,217,217,217,1,219,219,219,1,220, + 220,220,1,253,253,253,1,255,255,255,1,218,218,218,1,217,217,217,2,221, + 221,221,1,220,220,220,1,217,217,217,2,219,219,219,1,218,218,218,1,221, + 221,221,1,220,220,220,1,254,254,254,1,215,215,215,1,166,166,166,1,217, + 217,217,1,220,220,220,1,219,219,219,1,218,218,218,1,216,216,216,1,221, + 221,221,1,217,217,217,1,214,214,214,1,221,221,221,1,216,216,216,1,215, + 215,215,1,223,223,223,1,218,218,218,1,214,214,214,1,220,220,220,1,216, + 216,216,1,255,255,255,1,218,218,218,2,172,172,172,1,217,217,217,1,214, + 214,214,1,216,216,216,1,255,255,255,1,219,219,219,1,218,218,218,1,217, + 217,217,1,221,221,221,1,217,217,217,1,221,221,221,1,218,218,218,1,216, + 216,216,1,218,218,218,1,217,217,217,1,255,255,255,3,215,215,215,1,219, + 219,219,1,252,252,252,1,255,255,255,1,216,216,216,1,167,167,167,1,220, + 220,220,1,216,216,216,1,219,219,219,1,221,221,221,1,218,218,218,1,216, + 216,216,2,215,215,215,1,170,170,170,1,167,167,167,1,168,168,168,1,223, + 223,223,1,210,210,210,1,217,217,217,1,219,219,219,2,218,218,218,1,167, + 167,167,2,168,168,168,1,171,171,171,1,213,213,213,1,218,218,218,4,250, + 250,250,1,171,171,171,1,167,167,167,1,255,255,255,1,216,216,216,1,218, + 218,218,1,220,220,220,1,213,213,213,1,220,220,220,1,170,170,170,1,169, + 169,169,1,215,215,215,1,218,218,218,1,219,219,219,1,217,217,217,1,167, + 167,167,2,168,168,168,1,166,166,166,1,220,220,220,1,219,219,219,1,216, + 216,216,1,219,219,219,2,220,220,220,1,253,253,253,1,252,252,252,1,255, + 255,255,1,254,254,254,1,217,217,217,1,255,255,255,2,214,214,214,1,218, + 218,218,1,255,255,255,1,254,254,254,1,255,255,255,1,253,253,253,1,222, + 222,222,1,220,220,220,1,216,216,216,1,217,217,217,1,216,216,216,1,222, + 222,222,1,215,215,215,1,216,216,216,1,171,171,171,1,219,219,219,1,217, + 217,217,1,216,216,216,1,220,220,220,1,162,162,162,1,218,218,218,3,217, + 217,217,2,222,222,222,1,218,218,218,1,221,221,221,1,168,168,168,1,217, + 217,217,2,166,166,166,1,217,217,217,1,223,223,223,1,215,215,215,1,217, + 217,217,1,221,221,221,1,218,218,218,2,168,168,168,1,217,217,217,2,168, + 168,168,1,166,166,166,1,216,216,216,1,219,219,219,1,216,216,216,1,220, + 220,220,1,169,169,169,1,218,218,218,2,216,216,216,1,219,219,219,1,221, + 221,221,1,218,218,218,1,216,216,216,1,223,223,223,1,218,218,218,1,216, + 216,216,1,168,168,168,1,215,215,215,1,217,217,217,1,222,222,222,1,215, + 215,215,1,216,216,216,1,254,254,254,2,215,215,215,1,219,219,219,1,216, + 216,216,1,222,222,222,1,220,220,220,1,216,216,216,1,221,221,221,1,219, + 219,219,1,220,220,220,1,215,215,215,1,218,218,218,1,216,216,216,1,217, + 217,217,1,220,220,220,1,217,217,217,1,220,220,220,1,254,254,254,2,216, + 216,216,1,168,168,168,1,170,170,170,1,169,169,169,1,215,215,215,1,222, + 222,222,1,255,255,255,1,253,253,253,1,254,254,254,1,255,255,255,1,165, + 165,165,1,168,168,168,1,218,218,218,1,221,221,221,1,216,216,216,1,220, + 220,220,1,167,167,167,1,215,215,215,1,220,220,220,1,221,221,221,2,218, + 218,218,1,253,253,253,1,255,255,255,1,218,218,218,1,215,215,215,1,221, + 221,221,1,219,219,219,2,218,218,218,2,167,167,167,1,219,219,219,1,222, + 222,222,1,217,217,217,1,167,167,167,1,220,220,220,1,219,219,219,1,218, + 218,218,1,219,219,219,1,222,222,222,1,217,217,217,1,167,167,167,1,219, + 219,219,1,218,218,218,1,221,221,221,1,218,218,218,2,216,216,216,1,218, + 218,218,1,169,169,169,1,175,175,175,1,214,214,214,1,219,219,219,1,220, + 220,220,1,218,218,218,1,215,215,215,2,255,255,255,2,217,217,217,1,218, + 218,218,2,217,217,217,1,214,214,214,1,223,223,223,1,217,217,217,1,216, + 216,216,1,255,255,255,1,253,253,253,1,220,220,220,1,216,216,216,2,220, + 220,220,1,219,219,219,1,217,217,217,1,221,221,221,1,220,220,220,1,169, + 169,169,1,219,219,219,1,215,215,215,1,216,216,216,1,221,221,221,1,216, + 216,216,1,219,219,219,1,222,222,222,1,220,220,220,1,217,217,217,1,219, + 219,219,2,217,217,217,2,254,254,254,1,215,215,215,1,219,219,219,1,218, + 218,218,1,223,223,223,1,168,168,168,1,214,214,214,1,219,219,219,1,220, + 220,220,1,214,214,214,1,218,218,218,1,167,167,167,1,218,218,218,1,169, + 169,169,1,170,170,170,1,168,168,168,1,171,171,171,1,217,217,217,1,255, + 255,255,1,254,254,254,1,167,167,167,1,219,219,219,1,218,218,218,2,221, + 221,221,1,215,215,215,1,167,167,167,1,168,168,168,1,218,218,218,2,216, + 216,216,1,221,221,221,1,167,167,167,1,220,220,220,1,217,217,217,2,221, + 221,221,1,219,219,219,2,255,255,255,1,220,220,220,1,218,218,218,1,220, + 220,220,1,216,216,216,2,219,219,219,1,167,167,167,1,216,216,216,1,219, + 219,219,2,169,169,169,1,170,170,170,1,216,216,216,1,217,217,217,1,221, + 221,221,1,217,217,217,2,255,255,255,1,219,219,219,1,217,217,217,1,166, + 166,166,1,170,170,170,1,216,216,216,2,253,253,253,1,255,255,255,1,219, + 219,219,1,217,217,217,1,255,255,255,1,219,219,219,1,217,217,217,1,218, + 218,218,1,220,220,220,1,215,215,215,1,169,169,169,1,221,221,221,1,212, + 212,212,1,218,218,218,1,217,217,217,2,255,255,255,2,218,218,218,1,217, + 217,217,1,220,220,220,1,212,212,212,1,218,218,218,1,219,219,219,1,220, + 220,220,1,169,169,169,1,217,217,217,1,215,215,215,1,169,169,169,1,218, + 218,218,1,166,166,166,1,217,217,217,1,218,218,218,1,216,216,216,1,217, + 217,217,1,255,255,255,1,165,165,165,1,171,171,171,1,218,218,218,1,252, + 252,252,1,220,220,220,1,216,216,216,1,219,219,219,1,220,220,220,1,164, + 164,164,1,214,214,214,1,218,218,218,1,219,219,219,1,215,215,215,1,219, + 219,219,3,218,218,218,1,219,219,219,1,168,168,168,1,167,167,167,1,216, + 216,216,1,220,220,220,1,221,221,221,1,213,213,213,1,219,219,219,1,217, + 217,217,1,219,219,219,1,220,220,220,1,219,219,219,1,218,218,218,1,220, + 220,220,1,218,218,218,1,217,217,217,1,220,220,220,1,217,217,217,1,253, + 253,253,1,165,165,165,1,219,219,219,1,220,220,220,1,218,218,218,1,255, + 255,255,1,217,217,217,1,221,221,221,1,213,213,213,1,217,217,217,1,218, + 218,218,1,219,219,219,1,213,213,213,1,219,219,219,1,221,221,221,1,216, + 216,216,1,222,222,222,1,255,255,255,1,254,254,254,2,219,219,219,1,218, + 218,218,1,255,255,255,1,253,253,253,1,221,221,221,1,218,218,218,1,219, + 219,219,1,218,218,218,1,220,220,220,1,217,217,217,1,167,167,167,1,169, + 169,169,1,165,165,165,1,255,255,255,2,219,219,219,1,216,216,216,1,218, + 218,218,1,217,217,217,2,219,219,219,1,220,220,220,1,216,216,216,1,219, + 219,219,2,254,254,254,1,219,219,219,1,217,217,217,1,215,215,215,1,220, + 220,220,1,217,217,217,1,218,218,218,2,215,215,215,1,219,219,219,1,216, + 216,216,1,218,218,218,2,219,219,219,1,220,220,220,1,218,218,218,1,168, + 168,168,1,220,220,220,1,218,218,218,2,168,168,168,1,169,169,169,1,171, + 171,171,1,167,167,167,1,215,215,215,1,219,219,219,1,255,255,255,1,254, + 254,254,1,253,253,253,1,255,255,255,1,219,219,219,1,252,252,252,1,221, + 221,221,1,219,219,219,1,218,218,218,1,215,215,215,1,255,255,255,2,217, + 217,217,1,255,255,255,1,252,252,252,1,255,255,255,1,254,254,254,1,218, + 218,218,2,216,216,216,1,220,220,220,2,217,217,217,1,219,219,219,1,255, + 255,255,1,251,251,251,1,254,254,254,1,220,220,220,1,217,217,217,1,255, + 255,255,1,220,220,220,1,216,216,216,1,253,253,253,1,252,252,252,1,220, + 220,220,1,255,255,255,1,166,166,166,1,219,219,219,1,171,171,171,1,168, + 168,168,1,216,216,216,1,223,223,223,1,213,213,213,1,218,218,218,1,222, + 222,222,1,215,215,215,1,255,255,255,2,215,215,215,1,220,220,220,1,219, + 219,219,1,216,216,216,1,218,218,218,1,223,223,223,1,216,216,216,1,219, + 219,219,1,221,221,221,1,218,218,218,3,255,255,255,1,216,216,216,1,167, + 167,167,1,218,218,218,1,219,219,219,1,216,216,216,1,218,218,218,1,217, + 217,217,2,218,218,218,1,219,219,219,1,215,215,215,1,218,218,218,1,217, + 217,217,1,219,219,219,1,215,215,215,1,222,222,222,1,215,215,215,1,255, + 255,255,1,219,219,219,1,220,220,220,1,218,218,218,1,215,215,215,1,218, + 218,218,3,219,219,219,1,220,220,220,1,215,215,215,1,220,220,220,1,218, + 218,218,1,223,223,223,1,216,216,216,1,166,166,166,1,219,219,219,1,217, + 217,217,2,254,254,254,1,219,219,219,1,255,255,255,2,252,252,252,1,255, + 255,255,1,217,217,217,1,165,165,165,1,255,255,255,1,219,219,219,1,216, + 216,216,1,222,222,222,1,167,167,167,1,166,166,166,1,171,171,171,1,255, + 255,255,1,214,214,214,1,219,219,219,1,218,218,218,1,220,220,220,1,167, + 167,167,1,255,255,255,2,214,214,214,1,219,219,219,1,221,221,221,1,217, + 217,217,1,255,255,255,1,216,216,216,1,221,221,221,1,217,217,217,1,219, + 219,219,1,218,218,218,1,216,216,216,1,218,218,218,1,219,219,219,1,217, + 217,217,1,216,216,216,1,222,222,222,1,217,217,217,2,253,253,253,1,222, + 222,222,1,215,215,215,1,217,217,217,1,254,254,254,1,255,255,255,1,217, + 217,217,1,167,167,167,1,166,166,166,1,164,164,164,1,223,223,223,1,216, + 216,216,1,218,218,218,1,216,216,216,1,255,255,255,2,254,254,254,1,221, + 221,221,1,215,215,215,1,217,217,217,1,219,219,219,1,254,254,254,1,220, + 220,220,1,219,219,219,1,255,255,255,3,253,253,253,1,255,255,255,1,218, + 218,218,1,217,217,217,1,218,218,218,1,222,222,222,1,214,214,214,1,217, + 217,217,1,218,218,218,1,255,255,255,5,252,252,252,1,255,255,255,4,254, + 254,254,1,216,216,216,1,219,219,219,1,165,165,165,1,168,168,168,1,169, + 169,169,1,255,255,255,1,220,220,220,1,255,255,255,2,217,217,217,1,219, + 219,219,1,255,255,255,1,254,254,254,1,255,255,255,1,218,218,218,1,216, + 216,216,2,221,221,221,1,215,215,215,1,216,216,216,1,218,218,218,1,216, + 216,216,1,214,214,214,1,220,220,220,1,216,216,216,1,255,255,255,2,217, + 217,217,1,219,219,219,1,218,218,218,2,216,216,216,1,219,219,219,1,218, + 218,218,1,217,217,217,2,222,222,222,1,220,220,220,1,217,217,217,1,221, + 221,221,1,220,220,220,1,216,216,216,1,218,218,218,1,254,254,254,1,219, + 219,219,1,216,216,216,1,219,219,219,1,222,222,222,1,216,216,216,1,219, + 219,219,1,214,214,214,1,217,217,217,1,218,218,218,1,220,220,220,1,221, + 221,221,1,216,216,216,1,217,217,217,1,219,219,219,1,220,220,220,2,217, + 217,217,1,219,219,219,1,255,255,255,1,254,254,254,1,219,219,219,1,217, + 217,217,1,255,255,255,1,253,253,253,1,217,217,217,1,169,169,169,1,219, + 219,219,1,214,214,214,1,221,221,221,1,215,215,215,1,255,255,255,1,170, + 170,170,1,215,215,215,1,218,218,218,1,221,221,221,1,217,217,217,1,220, + 220,220,1,214,214,214,1,171,171,171,1,168,168,168,1,217,217,217,1,220, + 220,220,1,218,218,218,1,217,217,217,1,216,216,216,1,218,218,218,1,221, + 221,221,1,216,216,216,1,217,217,217,1,216,216,216,1,222,222,222,1,214, + 214,214,1,219,219,219,1,220,220,220,1,217,217,217,1,220,220,220,1,216, + 216,216,1,221,221,221,1,217,217,217,1,255,255,255,1,216,216,216,1,220, + 220,220,1,218,218,218,1,254,254,254,1,255,255,255,1,251,251,251,1,255, + 255,255,1,167,167,167,1,168,168,168,1,217,217,217,1,219,219,219,1,218, + 218,218,1,219,219,219,1,216,216,216,2,166,166,166,1,169,169,169,1,221, + 221,221,1,217,217,217,1,166,166,166,1,170,170,170,1,249,249,249,1,167, + 167,167,1,217,217,217,1,216,216,216,1,218,218,218,1,168,168,168,1,217, + 217,217,1,219,219,219,1,218,218,218,2,167,167,167,1,217,217,217,1,218, + 218,218,1,220,220,220,1,218,218,218,1,252,252,252,1,255,255,255,1,216, + 216,216,1,254,254,254,1,255,255,255,1,217,217,217,1,215,215,215,1,216, + 216,216,1,219,219,219,1,253,253,253,1,217,217,217,1,222,222,222,1,218, + 218,218,1,166,166,166,1,218,218,218,1,254,254,254,1,218,218,218,2,214, + 214,214,1,221,221,221,1,218,218,218,1,255,255,255,2,217,217,217,1,219, + 219,219,1,169,169,169,1,220,220,220,1,216,216,216,1,219,219,219,1,220, + 220,220,1,217,217,217,1,219,219,219,3,214,214,214,1,255,255,255,1,218, + 218,218,3,215,215,215,1,221,221,221,1,217,217,217,1,219,219,219,2,217, + 217,217,1,215,215,215,1,218,218,218,1,215,215,215,1,221,221,221,1,165, + 165,165,1,166,166,166,1,173,173,173,1,216,216,216,1,217,217,217,1,218, + 218,218,1,216,216,216,1,219,219,219,1,218,218,218,3,219,219,219,1,220, + 220,220,1,217,217,217,1,168,168,168,1,215,215,215,1,220,220,220,1,253, + 253,253,2,255,255,255,1,218,218,218,1,216,216,216,1,255,255,255,1,215, + 215,215,1,221,221,221,1,216,216,216,1,220,220,220,1,254,254,254,1,255, + 255,255,1,219,219,219,1,217,217,217,1,216,216,216,1,220,220,220,1,218, + 218,218,1,217,217,217,1,255,255,255,1,218,218,218,1,217,217,217,1,220, + 220,220,1,217,217,217,1,218,218,218,1,255,255,255,1,222,222,222,1,165, + 165,165,1,168,168,168,1,169,169,169,1,217,217,217,1,219,219,219,1,217, + 217,217,1,219,219,219,2,216,216,216,1,219,219,219,1,218,218,218,2,215, + 215,215,1,220,220,220,1,218,218,218,1,216,216,216,1,219,219,219,1,217, + 217,217,1,219,219,219,1,216,216,216,1,218,218,218,1,220,220,220,1,215, + 215,215,1,217,217,217,1,220,220,220,1,217,217,217,1,255,255,255,2,253, + 253,253,1,167,167,167,1,170,170,170,1,167,167,167,1,218,218,218,1,216, + 216,216,1,220,220,220,1,216,216,216,1,255,255,255,1,217,217,217,1,216, + 216,216,1,255,255,255,1,217,217,217,1,218,218,218,2,170,170,170,1,168, + 168,168,2,218,218,218,1,217,217,217,1,219,219,219,1,220,220,220,1,216, + 216,216,1,217,217,217,1,169,169,169,1,167,167,167,1,219,219,219,2,217, + 217,217,1,218,218,218,1,220,220,220,1,217,217,217,1,220,220,220,1,218, + 218,218,1,215,215,215,1,221,221,221,1,219,219,219,2,216,216,216,1,255, + 255,255,2,217,217,217,1,255,255,255,1,166,166,166,1,219,219,219,1,220, + 220,220,1,216,216,216,1,218,218,218,1,171,171,171,1,216,216,216,1,218, + 218,218,1,220,220,220,1,253,253,253,1,255,255,255,1,216,216,216,1,168, + 168,168,1,219,219,219,1,217,217,217,1,219,219,219,1,217,217,217,1,218, + 218,218,2,216,216,216,1,218,218,218,1,221,221,221,1,216,216,216,1,218, + 218,218,1,219,219,219,1,217,217,217,1,221,221,221,1,215,215,215,1,219, + 219,219,2,216,216,216,1,220,220,220,1,218,218,218,1,217,217,217,1,219, + 219,219,1,217,217,217,1,218,218,218,1,219,219,219,1,215,215,215,1,220, + 220,220,2,217,217,217,1,219,219,219,2,217,217,217,1,219,219,219,2,216, + 216,216,1,218,218,218,1,219,219,219,1,169,169,169,1,218,218,218,1,254, + 254,254,1,255,255,255,3,220,220,220,1,217,217,217,1,218,218,218,2,220, + 220,220,1,215,215,215,1,218,218,218,1,217,217,217,1,255,255,255,2,216, + 216,216,1,218,218,218,1,219,219,219,1,167,167,167,1,252,252,252,1,220, + 220,220,1,217,217,217,1,216,216,216,1,220,220,220,1,219,219,219,1,217, + 217,217,1,255,255,255,2,167,167,167,1,169,169,169,2,167,167,167,1,220, + 220,220,1,217,217,217,1,216,216,216,1,219,219,219,2,218,218,218,9,217, + 217,217,1,218,218,218,1,219,219,219,1,214,214,214,1,220,220,220,1,221, + 221,221,1,217,217,217,1,216,216,216,1,222,222,222,1,253,253,253,1,220, + 220,220,1,169,169,169,1,167,167,167,1,168,168,168,2,218,218,218,1,217, + 217,217,1,255,255,255,2,218,218,218,2,255,255,255,2,165,165,165,1,220, + 220,220,1,169,169,169,1,218,218,218,1,219,219,219,1,253,253,253,1,219, + 219,219,2,217,217,217,1,218,218,218,1,254,254,254,1,171,171,171,1,215, + 215,215,1,219,219,219,1,216,216,216,1,220,220,220,1,218,218,218,8,220, + 220,220,1,216,216,216,1,255,255,255,1,254,254,254,1,217,217,217,1,169, + 169,169,1,166,166,166,1,169,169,169,1,167,167,167,1,217,217,217,1,220, + 220,220,1,217,217,217,1,218,218,218,2,253,253,253,1,255,255,255,1,254, + 254,254,1,166,166,166,1,170,170,170,1,217,217,217,1,219,219,219,1,216, + 216,216,1,221,221,221,1,217,217,217,2,219,219,219,2,217,217,217,1,220, + 220,220,1,216,216,216,2,220,220,220,1,218,218,218,1,216,216,216,1,215, + 215,215,1,221,221,221,1,218,218,218,2,222,222,222,1,216,216,216,1,255, + 255,255,1,254,254,254,1,255,255,255,1,220,220,220,1,217,217,217,2,219, + 219,219,1,218,218,218,1,220,220,220,1,216,216,216,1,219,219,219,1,218, + 218,218,1,219,219,219,1,218,218,218,1,215,215,215,1,169,169,169,1,167, + 167,167,1,171,171,171,1,218,218,218,1,217,217,217,1,221,221,221,1,217, + 217,217,1,216,216,216,1,218,218,218,1,217,217,217,1,219,219,219,1,217, + 217,217,1,221,221,221,1,218,218,218,1,217,217,217,1,253,253,253,1,255, + 255,255,1,221,221,221,1,215,215,215,1,220,220,220,1,167,167,167,1,220, + 220,220,1,217,217,217,1,220,220,220,1,218,218,218,1,217,217,217,1,218, + 218,218,2,253,253,253,1,255,255,255,1,217,217,217,1,167,167,167,1,220, + 220,220,1,218,218,218,1,221,221,221,1,220,220,220,1,219,219,219,1,216, + 216,216,1,218,218,218,10,221,221,221,1,217,217,217,2,225,225,225,1,214, + 214,214,2,218,218,218,1,220,220,220,1,218,218,218,1,217,217,217,2,218, + 218,218,1,166,166,166,1,169,169,169,1,168,168,168,1,218,218,218,1,220, + 220,220,1,219,219,219,1,215,215,215,1,218,218,218,1,220,220,220,1,216, + 216,216,1,219,219,219,1,220,220,220,1,216,216,216,1,255,255,255,1,217, + 217,217,1,170,170,170,1,218,218,218,1,220,220,220,1,216,216,216,1,219, + 219,219,1,220,220,220,1,216,216,216,1,215,215,215,1,220,220,220,1,219, + 219,219,2,216,216,216,1,218,218,218,9,219,219,219,1,218,218,218,1,169, + 169,169,1,215,215,215,1,170,170,170,1,168,168,168,1,166,166,166,1,170, + 170,170,1,255,255,255,1,216,216,216,1,217,217,217,2,219,219,219,1,220, + 220,220,1,219,219,219,1,255,255,255,1,221,221,221,1,215,215,215,2,220, + 220,220,1,216,216,216,2,169,169,169,1,220,220,220,1,218,218,218,2,219, + 219,219,1,214,214,214,1,219,219,219,1,222,222,222,1,216,216,216,1,217, + 217,217,1,222,222,222,1,220,220,220,1,219,219,219,1,216,216,216,1,166, + 166,166,1,217,217,217,1,219,219,219,2,218,218,218,1,222,222,222,1,215, + 215,215,1,220,220,220,1,218,218,218,1,216,216,216,1,218,218,218,1,217, + 217,217,2,221,221,221,1,215,215,215,1,219,219,219,1,214,214,214,1,255, + 255,255,1,169,169,169,1,220,220,220,1,211,211,211,1,223,223,223,1,216, + 216,216,1,217,217,217,1,218,218,218,2,219,219,219,1,221,221,221,1,216, + 216,216,1,219,219,219,1,217,217,217,1,216,216,216,1,219,219,219,1,218, + 218,218,1,216,216,216,3,167,167,167,3,168,168,168,1,216,216,216,1,219, + 219,219,2,217,217,217,1,216,216,216,1,255,255,255,1,251,251,251,1,218, + 218,218,1,255,255,255,1,214,214,214,1,218,218,218,1,168,168,168,1,212, + 212,212,1,222,222,222,1,220,220,220,1,218,218,218,9,214,214,214,1,221, + 221,221,1,217,217,217,2,215,215,215,1,166,166,166,1,172,172,172,1,168, + 168,168,1,167,167,167,1,216,216,216,1,223,223,223,1,214,214,214,1,221, + 221,221,1,219,219,219,1,169,169,169,1,217,217,217,1,218,218,218,1,219, + 219,219,1,165,165,165,1,170,170,170,1,165,165,165,1,168,168,168,1,220, + 220,220,1,217,217,217,1,221,221,221,1,165,165,165,1,221,221,221,1,168, + 168,168,1,169,169,169,1,166,166,166,1,220,220,220,1,218,218,218,1,217, + 217,217,1,252,252,252,1,220,220,220,2,217,217,217,1,220,220,220,1,213, + 213,213,1,221,221,221,1,218,218,218,8,217,217,217,1,221,221,221,1,214, + 214,214,1,218,218,218,1,217,217,217,2,220,220,220,1,169,169,169,1,218, + 218,218,1,213,213,213,1,218,218,218,1,219,219,219,1,170,170,170,1,213, + 213,213,1,219,219,219,1,253,253,253,2,217,217,217,1,219,219,219,2,215, + 215,215,1,222,222,222,1,220,220,220,1,167,167,167,1,215,215,215,1,221, + 221,221,1,215,215,215,1,223,223,223,1,220,220,220,1,215,215,215,1,218, + 218,218,2,170,170,170,1,164,164,164,1,218,218,218,1,216,216,216,1,219, + 219,219,1,220,220,220,1,218,218,218,1,220,220,220,1,217,217,217,1,219, + 219,219,1,214,214,214,1,218,218,218,3,220,220,220,1,219,219,219,2,220, + 220,220,1,217,217,217,1,218,218,218,1,255,255,255,3,216,216,216,1,220, + 220,220,1,219,219,219,1,217,217,217,1,219,219,219,1,217,217,217,2,220, + 220,220,1,218,218,218,1,216,216,216,1,218,218,218,1,217,217,217,1,219, + 219,219,1,220,220,220,1,166,166,166,1,217,217,217,1,225,225,225,1,218, + 218,218,1,220,220,220,1,167,167,167,1,217,217,217,1,220,220,220,1,216, + 216,216,1,220,220,220,1,215,215,215,1,221,221,221,1,219,219,219,2,248, + 248,248,1,255,255,255,1,170,170,170,1,168,168,168,1,169,169,169,1,219, + 219,219,1,217,217,217,1,222,222,222,1,217,217,217,1,216,216,216,1,220, + 220,220,1,218,218,218,8,221,221,221,1,215,215,215,1,219,219,219,1,218, + 218,218,1,169,169,169,1,170,170,170,1,165,165,165,1,169,169,169,1,220, + 220,220,1,218,218,218,1,254,254,254,1,221,221,221,1,217,217,217,1,216, + 216,216,1,165,165,165,1,219,219,219,1,220,220,220,1,166,166,166,1,171, + 171,171,1,168,168,168,1,170,170,170,1,215,215,215,1,218,218,218,1,221, + 221,221,1,167,167,167,1,168,168,168,1,254,254,254,1,168,168,168,1,169, + 169,169,2,164,164,164,1,219,219,219,1,255,255,255,1,220,220,220,1,217, + 217,217,1,216,216,216,1,219,219,219,1,217,217,217,1,220,220,220,1,218, + 218,218,9,254,254,254,1,255,255,255,1,222,222,222,1,217,217,217,1,221, + 221,221,1,218,218,218,1,215,215,215,1,166,166,166,2,222,222,222,1,168, + 168,168,1,216,216,216,2,220,220,220,2,219,219,219,1,220,220,220,1,217, + 217,217,1,222,222,222,1,167,167,167,1,218,218,218,1,255,255,255,1,214, + 214,214,1,218,218,218,1,219,219,219,2,220,220,220,1,212,212,212,1,217, + 217,217,1,222,222,222,1,213,213,213,1,221,221,221,1,166,166,166,1,170, + 170,170,1,221,221,221,1,253,253,253,1,222,222,222,1,217,217,217,1,219, + 219,219,1,215,215,215,1,166,166,166,1,171,171,171,1,168,168,168,1,219, + 219,219,1,217,217,217,2,219,219,219,1,216,216,216,1,219,219,219,1,217, + 217,217,1,216,216,216,1,220,220,220,1,217,217,217,1,252,252,252,1,169, + 169,169,1,167,167,167,1,214,214,214,1,220,220,220,1,217,217,217,1,221, + 221,221,1,219,219,219,1,218,218,218,1,220,220,220,1,212,212,212,1,223, + 223,223,1,219,219,219,1,218,218,218,2,217,217,217,1,221,221,221,1,217, + 217,217,1,216,216,216,2,218,218,218,1,255,255,255,1,254,254,254,1,220, + 220,220,1,217,217,217,1,216,216,216,1,219,219,219,1,217,217,217,2,220, + 220,220,1,255,255,255,1,218,218,218,1,215,215,215,1,168,168,168,1,255, + 255,255,1,219,219,219,1,217,217,217,1,218,218,218,1,221,221,221,1,216, + 216,216,1,218,218,218,9,217,217,217,1,218,218,218,1,168,168,168,1,217, + 217,217,1,220,220,220,1,216,216,216,1,220,220,220,1,216,216,216,1,217, + 217,217,1,215,215,215,1,218,218,218,1,219,219,219,1,220,220,220,1,167, + 167,167,1,222,222,222,1,216,216,216,1,253,253,253,1,221,221,221,1,216, + 216,216,1,219,219,219,1,218,218,218,1,219,219,219,1,221,221,221,1,214, + 214,214,1,168,168,168,1,216,216,216,1,222,222,222,1,220,220,220,1,164, + 164,164,1,171,171,171,1,170,170,170,1,167,167,167,1,164,164,164,1,217, + 217,217,1,218,218,218,1,221,221,221,1,213,213,213,1,218,218,218,1,220, + 220,220,1,217,217,217,1,218,218,218,8,255,255,255,1,254,254,254,1,252, + 252,252,1,217,217,217,2,216,216,216,1,221,221,221,1,169,169,169,2,166, + 166,166,1,255,255,255,1,219,219,219,1,220,220,220,1,216,216,216,3,217, + 217,217,1,215,215,215,1,220,220,220,1,215,215,215,1,218,218,218,1,255, + 255,255,1,217,217,217,1,220,220,220,2,215,215,215,1,216,216,216,1,223, + 223,223,1,219,219,219,1,220,220,220,1,255,255,255,2,172,172,172,1,215, + 215,215,1,216,216,216,1,217,217,217,2,219,219,219,1,216,216,216,1,171, + 171,171,1,169,169,169,1,164,164,164,1,219,219,219,3,216,216,216,1,217, + 217,217,1,220,220,220,1,218,218,218,1,217,217,217,1,222,222,222,1,214, + 214,214,1,216,216,216,1,220,220,220,1,171,171,171,1,218,218,218,1,220, + 220,220,1,219,219,219,1,217,217,217,1,215,215,215,1,217,217,217,2,218, + 218,218,1,219,219,219,1,221,221,221,1,213,213,213,1,216,216,216,1,255, + 255,255,1,218,218,218,1,215,215,215,1,219,219,219,1,218,218,218,1,220, + 220,220,1,168,168,168,1,216,216,216,1,218,218,218,3,219,219,219,2,220, + 220,220,1,218,218,218,1,219,219,219,1,255,255,255,3,217,217,217,1,216, + 216,216,1,218,218,218,1,221,221,221,1,219,219,219,1,214,214,214,1,220, + 220,220,1,218,218,218,9,216,216,216,1,221,221,221,1,216,216,216,1,218, + 218,218,1,219,219,219,1,218,218,218,2,219,219,219,1,166,166,166,1,223, + 223,223,1,219,219,219,1,216,216,216,1,217,217,217,1,218,218,218,1,216, + 216,216,1,255,255,255,1,254,254,254,1,219,219,219,1,216,216,216,1,217, + 217,217,1,219,219,219,1,215,215,215,1,220,220,220,1,219,219,219,1,169, + 169,169,1,218,218,218,1,251,251,251,1,217,217,217,1,221,221,221,1,213, + 213,213,1,168,168,168,1,170,170,170,1,169,169,169,2,220,220,220,2,219, + 219,219,1,218,218,218,1,219,219,219,1,217,217,217,1,218,218,218,8,255, + 255,255,1,254,254,254,1,220,220,220,1,219,219,219,2,218,218,218,1,215, + 215,215,1,169,169,169,1,218,218,218,1,216,216,216,1,217,217,217,1,219, + 219,219,1,218,218,218,2,219,219,219,1,220,220,220,1,218,218,218,1,255, + 255,255,1,215,215,215,1,220,220,220,1,222,222,222,1,167,167,167,1,217, + 217,217,1,219,219,219,1,217,217,217,1,220,220,220,1,218,218,218,3,215, + 215,215,1,254,254,254,1,255,255,255,1,218,218,218,3,219,219,219,2,218, + 218,218,1,219,219,219,1,253,253,253,1,255,255,255,1,220,220,220,1,219, + 219,219,1,217,217,217,2,219,219,219,2,215,215,215,1,218,218,218,2,215, + 215,215,1,220,220,220,1,255,255,255,2,213,213,213,1,218,218,218,1,219, + 219,219,1,217,217,217,1,220,220,220,1,217,217,217,1,221,221,221,1,220, + 220,220,1,218,218,218,2,216,216,216,1,217,217,217,1,255,255,255,1,218, + 218,218,1,215,215,215,1,220,220,220,1,219,219,219,1,216,216,216,1,170, + 170,170,1,212,212,212,1,222,222,222,1,219,219,219,1,217,217,217,2,219, + 219,219,1,215,215,215,1,217,217,217,1,218,218,218,2,166,166,166,1,255, + 255,255,1,218,218,218,1,221,221,221,1,167,167,167,1,219,219,219,1,216, + 216,216,1,213,213,213,1,225,225,225,1,219,219,219,1,215,215,215,1,218, + 218,218,8,254,254,254,2,219,219,219,2,217,217,217,1,219,219,219,1,217, + 217,217,2,220,220,220,1,216,216,216,1,215,215,215,1,219,219,219,1,168, + 168,168,1,222,222,222,1,218,218,218,1,254,254,254,1,255,255,255,1,216, + 216,216,1,221,221,221,1,217,217,217,1,220,220,220,1,217,217,217,1,216, + 216,216,1,218,218,218,2,254,254,254,1,255,255,255,3,223,223,223,1,216, + 216,216,1,166,166,166,1,165,165,165,1,169,169,169,1,217,217,217,1,214, + 214,214,1,216,216,216,1,220,220,220,1,218,218,218,1,220,220,220,1,218, + 218,218,8,219,219,219,1,252,252,252,1,255,255,255,2,167,167,167,1,218, + 218,218,1,220,220,220,1,215,215,215,1,169,169,169,1,220,220,220,1,213, + 213,213,1,220,220,220,1,216,216,216,1,217,217,217,1,223,223,223,1,214, + 214,214,1,218,218,218,1,216,216,216,1,223,223,223,1,214,214,214,1,166, + 166,166,1,218,218,218,1,216,216,216,1,219,219,219,1,218,218,218,2,216, + 216,216,1,220,220,220,1,212,212,212,1,221,221,221,1,255,255,255,1,219, + 219,219,1,218,218,218,3,220,220,220,1,216,216,216,1,217,217,217,1,255, + 255,255,2,218,218,218,1,215,215,215,1,221,221,221,1,219,219,219,1,218, + 218,218,1,217,217,217,1,221,221,221,1,217,217,217,1,219,219,219,1,167, + 167,167,1,222,222,222,1,253,253,253,1,255,255,255,1,218,218,218,1,217, + 217,217,1,219,219,219,1,217,217,217,1,216,216,216,1,219,219,219,1,217, + 217,217,2,216,216,216,1,217,217,217,1,219,219,219,1,218,218,218,1,217, + 217,217,1,254,254,254,1,218,218,218,1,220,220,220,1,218,218,218,2,255, + 255,255,1,219,219,219,1,169,169,169,1,218,218,218,1,166,166,166,1,220, + 220,220,1,218,218,218,2,219,219,219,1,221,221,221,1,218,218,218,1,216, + 216,216,1,221,221,221,1,215,215,215,1,220,220,220,1,218,218,218,1,216, + 216,216,1,220,220,220,1,217,217,217,1,221,221,221,1,216,216,216,1,217, + 217,217,1,220,220,220,1,218,218,218,8,255,255,255,1,253,253,253,1,218, + 218,218,1,220,220,220,1,216,216,216,1,220,220,220,1,218,218,218,1,219, + 219,219,1,216,216,216,1,219,219,219,1,221,221,221,1,169,169,169,1,166, + 166,166,1,217,217,217,1,168,168,168,1,255,255,255,1,253,253,253,1,255, + 255,255,1,252,252,252,1,255,255,255,2,219,219,219,1,216,216,216,1,219, + 219,219,1,220,220,220,1,254,254,254,1,255,255,255,1,253,253,253,1,255, + 255,255,1,254,254,254,1,255,255,255,1,219,219,219,1,169,169,169,1,217, + 217,217,1,219,219,219,3,218,218,218,1,216,216,216,1,218,218,218,9,255, + 255,255,2,254,254,254,2,219,219,219,1,217,217,217,1,216,216,216,1,170, + 170,170,1,167,167,167,1,217,217,217,1,220,220,220,1,218,218,218,3,217, + 217,217,1,219,219,219,1,218,218,218,2,217,217,217,1,255,255,255,1,218, + 218,218,2,219,219,219,1,217,217,217,1,218,218,218,1,219,219,219,1,218, + 218,218,2,221,221,221,1,215,215,215,1,219,219,219,1,216,216,216,1,218, + 218,218,1,217,217,217,1,219,219,219,1,216,216,216,1,255,255,255,1,169, + 169,169,1,217,217,217,2,218,218,218,1,220,220,220,1,216,216,216,1,217, + 217,217,1,222,222,222,1,216,216,216,1,217,217,217,1,219,219,219,1,217, + 217,217,1,169,169,169,1,217,217,217,1,216,216,216,1,219,219,219,2,218, + 218,218,1,217,217,217,1,218,218,218,3,220,220,220,1,218,218,218,2,220, + 220,220,1,216,216,216,1,219,219,219,1,254,254,254,1,255,255,255,1,254, + 254,254,1,255,255,255,2,254,254,254,1,219,219,219,1,218,218,218,2,221, + 221,221,1,217,217,217,2,220,220,220,1,217,217,217,1,219,219,219,1,167, + 167,167,1,219,219,219,1,218,218,218,1,219,219,219,1,217,217,217,1,255, + 255,255,1,219,219,219,1,215,215,215,1,218,218,218,1,221,221,221,1,215, + 215,215,1,217,217,217,1,218,218,218,2,220,220,220,1,218,218,218,1,217, + 217,217,1,218,218,218,2,219,219,219,1,218,218,218,1,217,217,217,1,255, + 255,255,1,254,254,254,1,219,219,219,1,217,217,217,1,220,220,220,1,217, + 217,217,1,221,221,221,1,215,215,215,1,218,218,218,1,217,217,217,2,167, + 167,167,1,218,218,218,1,219,219,219,1,166,166,166,1,255,255,255,4,253, + 253,253,1,255,255,255,1,217,217,217,1,220,220,220,1,168,168,168,1,218, + 218,218,2,219,219,219,1,254,254,254,1,255,255,255,1,253,253,253,1,255, + 255,255,2,218,218,218,9,216,216,216,1,218,218,218,3,167,167,167,1,171, + 171,171,1,216,216,216,1,219,219,219,1,217,217,217,1,253,253,253,1,255, + 255,255,1,215,215,215,1,218,218,218,2,170,170,170,1,168,168,168,1,219, + 219,219,1,166,166,166,1,171,171,171,1,216,216,216,1,220,220,220,1,216, + 216,216,1,219,219,219,2,216,216,216,1,255,255,255,1,217,217,217,2,165, + 165,165,1,171,171,171,1,166,166,166,1,170,170,170,1,216,216,216,1,219, + 219,219,1,217,217,217,1,220,220,220,1,215,215,215,1,222,222,222,1,216, + 216,216,1,218,218,218,1,219,219,219,1,216,216,216,1,255,255,255,1,167, + 167,167,1,165,165,165,1,219,219,219,2,217,217,217,1,219,219,219,1,217, + 217,217,1,219,219,219,1,168,168,168,1,218,218,218,2,255,255,255,1,219, + 219,219,1,166,166,166,1,222,222,222,1,215,215,215,1,216,216,216,1,219, + 219,219,1,217,217,217,1,219,219,219,2,218,218,218,1,217,217,217,1,218, + 218,218,1,219,219,219,1,218,218,218,1,216,216,216,1,221,221,221,1,218, + 218,218,1,254,254,254,1,255,255,255,3,216,216,216,1,169,169,169,1,255, + 255,255,1,216,216,216,1,253,253,253,1,219,219,219,1,220,220,220,1,217, + 217,217,1,216,216,216,1,220,220,220,1,216,216,216,1,168,168,168,2,166, + 166,166,1,165,165,165,1,168,168,168,1,217,217,217,2,221,221,221,1,219, + 219,219,1,215,215,215,1,221,221,221,2,219,219,219,2,215,215,215,1,220, + 220,220,1,219,219,219,1,217,217,217,2,219,219,219,1,218,218,218,1,219, + 219,219,1,254,254,254,1,219,219,219,1,214,214,214,1,222,222,222,1,217, + 217,217,3,221,221,221,1,218,218,218,1,219,219,219,2,167,167,167,1,255, + 255,255,1,216,216,216,1,221,221,221,1,219,219,219,1,218,218,218,1,214, + 214,214,1,221,221,221,1,255,255,255,1,216,216,216,1,221,221,221,1,168, + 168,168,2,220,220,220,1,216,216,216,1,217,217,217,1,220,220,220,1,217, + 217,217,1,255,255,255,1,249,249,249,1,220,220,220,1,218,218,218,8,219, + 219,219,1,220,220,220,1,217,217,217,1,219,219,219,1,217,217,217,1,218, + 218,218,1,217,217,217,1,222,222,222,1,218,218,218,1,215,215,215,1,220, + 220,220,1,218,218,218,1,220,220,220,1,218,218,218,1,220,220,220,1,164, + 164,164,1,166,166,166,1,168,168,168,1,171,171,171,2,217,217,217,1,215, + 215,215,1,221,221,221,1,216,216,216,2,220,220,220,1,216,216,216,1,220, + 220,220,1,221,221,221,1,168,168,168,2,167,167,167,1,215,215,215,1,223, + 223,223,1,217,217,217,2,219,219,219,1,214,214,214,1,218,218,218,1,220, + 220,220,1,215,215,215,1,218,218,218,1,221,221,221,1,251,251,251,1,220, + 220,220,1,221,221,221,1,217,217,217,1,218,218,218,1,219,219,219,1,220, + 220,220,1,218,218,218,1,217,217,217,1,219,219,219,1,215,215,215,1,221, + 221,221,1,253,253,253,1,217,217,217,1,167,167,167,1,217,217,217,1,221, + 221,221,1,218,218,218,1,220,220,220,1,217,217,217,2,218,218,218,1,217, + 217,217,1,222,222,222,1,218,218,218,2,217,217,217,1,218,218,218,1,219, + 219,219,1,215,215,215,1,221,221,221,1,217,217,217,1,218,218,218,2,219, + 219,219,1,166,166,166,1,218,218,218,1,222,222,222,1,216,216,216,1,218, + 218,218,1,219,219,219,2,220,220,220,1,252,252,252,1,255,255,255,1,216, + 216,216,1,167,167,167,1,173,173,173,1,170,170,170,1,218,218,218,1,217, + 217,217,2,215,215,215,1,218,218,218,1,220,220,220,1,217,217,217,1,219, + 219,219,1,214,214,214,1,218,218,218,1,220,220,220,1,216,216,216,2,221, + 221,221,1,217,217,217,1,215,215,215,1,220,220,220,1,218,218,218,1,217, + 217,217,1,219,219,219,1,218,218,218,1,217,217,217,3,221,221,221,1,216, + 216,216,1,218,218,218,1,216,216,216,1,168,168,168,1,222,222,222,1,254, + 254,254,1,216,216,216,1,217,217,217,1,216,216,216,1,219,219,219,1,221, + 221,221,1,213,213,213,1,254,254,254,1,218,218,218,2,167,167,167,1,216, + 216,216,1,214,214,214,1,222,222,222,1,218,218,218,1,217,217,217,1,219, + 219,219,2,221,221,221,1,215,215,215,1,218,218,218,8,216,216,216,1,217, + 217,217,1,220,220,220,1,253,253,253,1,255,255,255,1,216,216,216,1,219, + 219,219,1,214,214,214,1,218,218,218,1,220,220,220,1,217,217,217,1,216, + 216,216,1,219,219,219,1,217,217,217,2,170,170,170,1,218,218,218,1,219, + 219,219,1,164,164,164,1,218,218,218,2,219,219,219,1,216,216,216,1,220, + 220,220,1,217,217,217,1,222,222,222,1,219,219,219,1,253,253,253,2,254, + 254,254,1,218,218,218,2,220,220,220,1,215,215,215,1,218,218,218,1,219, + 219,219,1,218,218,218,1,219,219,219,1,218,218,218,1,217,217,217,1,222, + 222,222,1,218,218,218,1,251,251,251,1,255,255,255,1,216,216,216,1,218, + 218,218,1,217,217,217,2,216,216,216,2,255,255,255,1,222,222,222,1,215, + 215,215,1,219,219,219,1,215,215,215,1,255,255,255,1,218,218,218,1,170, + 170,170,1,167,167,167,1,216,216,216,1,220,220,220,1,216,216,216,1,218, + 218,218,1,219,219,219,1,215,215,215,1,221,221,221,1,215,215,215,1,218, + 218,218,1,219,219,219,1,216,216,216,1,218,218,218,1,221,221,221,1,164, + 164,164,1,218,218,218,1,217,217,217,1,218,218,218,1,255,255,255,1,216, + 216,216,1,220,220,220,1,218,218,218,1,212,212,212,1,223,223,223,1,217, + 217,217,2,218,218,218,1,217,217,217,1,254,254,254,1,220,220,220,1,255, + 255,255,2,217,217,217,1,165,165,165,1,219,219,219,1,217,217,217,2,220, + 220,220,2,218,218,218,1,219,219,219,1,215,215,215,1,222,222,222,1,218, + 218,218,1,217,217,217,1,218,218,218,1,217,217,217,1,216,216,216,1,222, + 222,222,1,218,218,218,2,253,253,253,1,255,255,255,1,217,217,217,1,218, + 218,218,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,219, + 219,219,1,218,218,218,1,219,219,219,1,166,166,166,1,164,164,164,1,221, + 221,221,1,220,220,220,1,219,219,219,1,221,221,221,1,218,218,218,1,216, + 216,216,1,255,255,255,1,219,219,219,1,216,216,216,1,219,219,219,1,165, + 165,165,1,222,222,222,1,221,221,221,1,165,165,165,1,169,169,169,1,170, + 170,170,1,217,217,217,1,218,218,218,1,217,217,217,1,220,220,220,1,218, + 218,218,8,219,219,219,1,221,221,221,1,217,217,217,2,219,219,219,1,216, + 216,216,1,220,220,220,1,219,219,219,1,254,254,254,1,255,255,255,1,215, + 215,215,1,219,219,219,1,217,217,217,1,219,219,219,1,218,218,218,1,217, + 217,217,1,221,221,221,1,216,216,216,1,172,172,172,1,217,217,217,1,219, + 219,219,1,218,218,218,1,219,219,219,1,217,217,217,1,220,220,220,1,216, + 216,216,1,214,214,214,1,255,255,255,1,222,222,222,1,254,254,254,1,165, + 165,165,1,220,220,220,1,217,217,217,1,216,216,216,1,221,221,221,1,218, + 218,218,1,215,215,215,1,220,220,220,2,217,217,217,1,216,216,216,2,220, + 220,220,1,218,218,218,1,217,217,217,1,220,220,220,1,216,216,216,1,220, + 220,220,1,218,218,218,1,219,219,219,1,217,217,217,1,216,216,216,1,222, + 222,222,1,217,217,217,2,254,254,254,1,218,218,218,1,164,164,164,1,169, + 169,169,1,221,221,221,1,214,214,214,1,218,218,218,1,219,219,219,1,217, + 217,217,1,221,221,221,1,219,219,219,1,220,220,220,1,218,218,218,1,217, + 217,217,2,220,220,220,1,217,217,217,1,221,221,221,1,219,219,219,1,221, + 221,221,1,217,217,217,1,253,253,253,1,221,221,221,1,217,217,217,1,218, + 218,218,1,220,220,220,1,215,215,215,1,218,218,218,1,222,222,222,1,214, + 214,214,1,220,220,220,1,170,170,170,1,254,254,254,1,255,255,255,1,252, + 252,252,1,167,167,167,1,173,173,173,1,166,166,166,1,218,218,218,1,219, + 219,219,1,218,218,218,1,213,213,213,1,220,220,220,1,219,219,219,1,216, + 216,216,1,169,169,169,1,168,168,168,2,171,171,171,1,170,170,170,1,168, + 168,168,1,218,218,218,1,216,216,216,1,253,253,253,1,255,255,255,1,254, + 254,254,1,218,218,218,4,219,219,219,1,217,217,217,1,219,219,219,1,215, + 215,215,1,172,172,172,1,167,167,167,1,172,172,172,1,167,167,167,2,215, + 215,215,1,216,216,216,1,219,219,219,1,216,216,216,1,255,255,255,1,218, + 218,218,1,217,217,217,1,168,168,168,1,219,219,219,1,216,216,216,1,219, + 219,219,1,166,166,166,1,170,170,170,1,166,166,166,1,219,219,219,2,217, + 217,217,1,218,218,218,9,217,217,217,1,214,214,214,1,221,221,221,1,220, + 220,220,1,215,215,215,1,220,220,220,1,218,218,218,1,217,217,217,1,255, + 255,255,2,219,219,219,3,214,214,214,1,220,220,220,1,219,219,219,1,218, + 218,218,1,166,166,166,1,219,219,219,1,218,218,218,1,215,215,215,1,221, + 221,221,1,214,214,214,1,220,220,220,1,217,217,217,1,220,220,220,1,218, + 218,218,1,171,171,171,1,217,217,217,1,170,170,170,1,168,168,168,1,216, + 216,216,1,221,221,221,1,219,219,219,1,218,218,218,2,219,219,219,1,217, + 217,217,2,219,219,219,1,220,220,220,2,216,216,216,1,218,218,218,3,219, + 219,219,1,217,217,217,1,219,219,219,2,216,216,216,1,220,220,220,1,218, + 218,218,1,214,214,214,1,221,221,221,1,255,255,255,2,217,217,217,1,220, + 220,220,1,218,218,218,1,221,221,221,1,218,218,218,1,220,220,220,1,216, + 216,216,1,219,219,219,1,164,164,164,1,218,218,218,3,220,220,220,1,255, + 255,255,1,218,218,218,1,166,166,166,2,165,165,165,1,218,218,218,1,219, + 219,219,1,218,218,218,1,220,220,220,1,218,218,218,1,221,221,221,1,218, + 218,218,1,216,216,216,1,220,220,220,1,215,215,215,1,255,255,255,1,166, + 166,166,1,165,165,165,1,255,255,255,1,254,254,254,1,172,172,172,1,213, + 213,213,1,170,170,170,1,218,218,218,1,220,220,220,1,219,219,219,1,217, + 217,217,1,220,220,220,1,215,215,215,1,218,218,218,1,168,168,168,1,169, + 169,169,1,167,167,167,1,165,165,165,1,168,168,168,1,165,165,165,1,217, + 217,217,1,219,219,219,1,220,220,220,1,254,254,254,1,255,255,255,1,217, + 217,217,1,219,219,219,1,217,217,217,1,214,214,214,1,222,222,222,1,217, + 217,217,1,218,218,218,1,222,222,222,1,214,214,214,1,167,167,167,1,169, + 169,169,1,167,167,167,1,170,170,170,1,218,218,218,2,167,167,167,1,255, + 255,255,1,252,252,252,1,255,255,255,1,216,216,216,1,168,168,168,1,217, + 217,217,1,255,255,255,2,219,219,219,1,165,165,165,1,220,220,220,1,218, + 218,218,1,219,219,219,3,218,218,218,9,220,220,220,1,218,218,218,2,220, + 220,220,1,214,214,214,1,219,219,219,1,217,217,217,1,250,250,250,1,254, + 254,254,1,219,219,219,1,216,216,216,1,217,217,217,1,222,222,222,1,217, + 217,217,1,254,254,254,1,255,255,255,1,224,224,224,1,215,215,215,1,218, + 218,218,1,222,222,222,1,216,216,216,1,217,217,217,1,218,218,218,1,217, + 217,217,1,219,219,219,1,255,255,255,1,167,167,167,1,255,255,255,1,212, + 212,212,1,172,172,172,1,216,216,216,1,215,215,215,1,218,218,218,1,215, + 215,215,1,219,219,219,1,222,222,222,1,217,217,217,1,216,216,216,1,218, + 218,218,2,216,216,216,1,217,217,217,1,221,221,221,1,216,216,216,1,217, + 217,217,3,218,218,218,2,217,217,217,1,219,219,219,3,217,217,217,1,254, + 254,254,1,251,251,251,1,218,218,218,1,219,219,219,1,217,217,217,1,219, + 219,219,1,213,213,213,1,221,221,221,1,218,218,218,2,165,165,165,1,172, + 172,172,1,217,217,217,1,218,218,218,1,217,217,217,1,168,168,168,2,218, + 218,218,1,220,220,220,2,221,221,221,1,214,214,214,1,218,218,218,2,216, + 216,216,1,217,217,217,1,220,220,220,1,219,219,219,2,218,218,218,1,217, + 217,217,2,170,170,170,1,254,254,254,1,255,255,255,1,252,252,252,1,170, + 170,170,1,220,220,220,1,216,216,216,1,214,214,214,1,221,221,221,1,218, + 218,218,2,255,255,255,3,216,216,216,1,218,218,218,2,171,171,171,1,169, + 169,169,2,215,215,215,1,220,220,220,1,253,253,253,1,214,214,214,1,224, + 224,224,1,215,215,215,1,219,219,219,1,222,222,222,1,215,215,215,1,217, + 217,217,1,218,218,218,1,216,216,216,1,219,219,219,1,224,224,224,1,252, + 252,252,1,166,166,166,1,218,218,218,1,219,219,219,1,218,218,218,1,168, + 168,168,1,218,218,218,1,216,216,216,1,218,218,218,1,171,171,171,1,165, + 165,165,1,167,167,167,1,255,255,255,3,220,220,220,1,219,219,219,1,218, + 218,218,3,216,216,216,1,218,218,218,8,216,216,216,1,218,218,218,1,216, + 216,216,1,218,218,218,1,222,222,222,1,217,217,217,1,218,218,218,1,221, + 221,221,1,255,255,255,3,216,216,216,1,220,220,220,1,217,217,217,1,252, + 252,252,1,255,255,255,1,215,215,215,1,214,214,214,1,220,220,220,1,218, + 218,218,3,217,217,217,1,219,219,219,1,218,218,218,1,255,255,255,1,254, + 254,254,1,218,218,218,2,221,221,221,1,216,216,216,1,221,221,221,1,218, + 218,218,1,221,221,221,1,219,219,219,1,217,217,217,3,220,220,220,2,221, + 221,221,1,215,215,215,1,217,217,217,1,219,219,219,1,216,216,216,1,221, + 221,221,1,220,220,220,1,219,219,219,1,217,217,217,1,215,215,215,1,222, + 222,222,1,218,218,218,1,215,215,215,1,221,221,221,1,219,219,219,1,218, + 218,218,1,219,219,219,1,218,218,218,1,219,219,219,1,217,217,217,1,218, + 218,218,1,220,220,220,1,214,214,214,1,255,255,255,1,219,219,219,1,218, + 218,218,1,216,216,216,1,171,171,171,1,166,166,166,1,168,168,168,1,254, + 254,254,1,255,255,255,2,215,215,215,1,219,219,219,1,217,217,217,2,220, + 220,220,1,218,218,218,1,219,219,219,1,217,217,217,1,219,219,219,1,217, + 217,217,1,168,168,168,1,255,255,255,2,220,220,220,1,218,218,218,1,255, + 255,255,1,218,218,218,1,255,255,255,1,219,219,219,1,165,165,165,1,219, + 219,219,3,218,218,218,1,217,217,217,1,255,255,255,2,254,254,254,1,255, + 255,255,1,218,218,218,2,168,168,168,1,167,167,167,1,166,166,166,1,171, + 171,171,1,215,215,215,1,255,255,255,1,220,220,220,1,217,217,217,1,218, + 218,218,2,214,214,214,1,221,221,221,1,219,219,219,1,218,218,218,1,221, + 221,221,1,253,253,253,1,214,214,214,1,255,255,255,1,216,216,216,1,220, + 220,220,1,255,255,255,1,217,217,217,1,167,167,167,2,220,220,220,1,219, + 219,219,1,165,165,165,1,170,170,170,1,167,167,167,1,217,217,217,1,254, + 254,254,1,218,218,218,1,219,219,219,1,216,216,216,1,218,218,218,1,222, + 222,222,1,215,215,215,1,220,220,220,1,218,218,218,8,220,220,220,1,216, + 216,216,1,219,219,219,1,218,218,218,1,215,215,215,1,169,169,169,1,218, + 218,218,1,216,216,216,1,254,254,254,1,255,255,255,3,218,218,218,1,166, + 166,166,1,220,220,220,1,218,218,218,2,221,221,221,1,218,218,218,2,217, + 217,217,1,219,219,219,1,168,168,168,1,217,217,217,1,219,219,219,1,252, + 252,252,1,221,221,221,1,217,217,217,1,254,254,254,1,218,218,218,2,217, + 217,217,1,219,219,219,1,216,216,216,1,218,218,218,1,219,219,219,1,217, + 217,217,1,218,218,218,2,217,217,217,2,219,219,219,2,218,218,218,3,216, + 216,216,1,217,217,217,1,219,219,219,1,220,220,220,1,217,217,217,1,215, + 215,215,1,221,221,221,1,166,166,166,1,165,165,165,1,169,169,169,1,168, + 168,168,1,215,215,215,1,219,219,219,1,217,217,217,1,218,218,218,1,217, + 217,217,1,220,220,220,1,254,254,254,1,255,255,255,1,217,217,217,1,218, + 218,218,1,215,215,215,1,171,171,171,1,167,167,167,1,220,220,220,1,217, + 217,217,2,219,219,219,1,166,166,166,1,168,168,168,1,170,170,170,1,167, + 167,167,1,168,168,168,1,167,167,167,1,222,222,222,1,212,212,212,1,255, + 255,255,1,220,220,220,1,217,217,217,1,254,254,254,1,219,219,219,1,216, + 216,216,1,220,220,220,1,255,255,255,1,217,217,217,1,215,215,215,1,221, + 221,221,1,217,217,217,1,219,219,219,1,217,217,217,1,218,218,218,1,217, + 217,217,1,219,219,219,1,255,255,255,3,219,219,219,1,216,216,216,1,220, + 220,220,1,168,168,168,1,166,166,166,1,173,173,173,1,250,250,250,1,255, + 255,255,2,218,218,218,1,219,219,219,1,216,216,216,1,218,218,218,1,219, + 219,219,2,218,218,218,1,217,217,217,1,168,168,168,1,219,219,219,1,217, + 217,217,1,216,216,216,1,222,222,222,1,255,255,255,1,216,216,216,1,218, + 218,218,1,219,219,219,1,217,217,217,1,218,218,218,1,219,219,219,1,169, + 169,169,1,166,166,166,1,168,168,168,1,166,166,166,1,220,220,220,1,216, + 216,216,1,219,219,219,1,221,221,221,1,217,217,217,2,218,218,218,4,219, + 219,219,1,167,167,167,1,217,217,217,1,219,219,219,1,167,167,167,1,219, + 219,219,1,218,218,218,1,219,219,219,1,217,217,217,1,216,216,216,1,222, + 222,222,1,215,215,215,1,216,216,216,1,218,218,218,1,255,255,255,2,253, + 253,253,1,220,220,220,1,216,216,216,1,219,219,219,3,218,218,218,3,220, + 220,220,2,217,217,217,2,220,220,220,1,255,255,255,1,253,253,253,1,222, + 222,222,1,215,215,215,1,221,221,221,1,218,218,218,1,217,217,217,1,218, + 218,218,17,220,220,220,1,216,216,216,1,219,219,219,1,217,217,217,2,170, + 170,170,1,168,168,168,2,220,220,220,1,215,215,215,1,221,221,221,1,219, + 219,219,1,217,217,217,1,169,169,169,1,168,168,168,2,220,220,220,1,217, + 217,217,1,253,253,253,1,255,255,255,2,164,164,164,1,170,170,170,1,218, + 218,218,1,219,219,219,1,217,217,217,1,218,218,218,1,163,163,163,1,170, + 170,170,1,167,167,167,1,170,170,170,1,215,215,215,1,255,255,255,1,218, + 218,218,1,217,217,217,1,215,215,215,1,222,222,222,1,221,221,221,1,215, + 215,215,1,167,167,167,1,170,170,170,1,217,217,217,1,221,221,221,1,219, + 219,219,1,216,216,216,1,217,217,217,1,220,220,220,1,217,217,217,1,218, + 218,218,2,217,217,217,1,255,255,255,1,216,216,216,2,220,220,220,2,218, + 218,218,1,167,167,167,1,216,216,216,1,255,255,255,1,252,252,252,1,254, + 254,254,1,215,215,215,1,220,220,220,1,222,222,222,1,217,217,217,1,220, + 220,220,1,216,216,216,1,169,169,169,1,218,218,218,1,220,220,220,1,217, + 217,217,1,219,219,219,1,220,220,220,1,215,215,215,1,219,219,219,1,222, + 222,222,1,255,255,255,2,217,217,217,1,216,216,216,1,217,217,217,1,220, + 220,220,1,168,168,168,1,169,169,169,1,170,170,170,1,221,221,221,1,219, + 219,219,1,216,216,216,2,217,217,217,1,220,220,220,3,214,214,214,1,220, + 220,220,1,216,216,216,1,170,170,170,1,218,218,218,2,169,169,169,1,166, + 166,166,1,218,218,218,1,217,217,217,1,255,255,255,1,219,219,219,1,215, + 215,215,1,219,219,219,1,223,223,223,1,219,219,219,1,216,216,216,1,255, + 255,255,2,214,214,214,1,222,222,222,1,219,219,219,1,217,217,217,1,216, + 216,216,1,218,218,218,1,221,221,221,1,215,215,215,1,254,254,254,1,217, + 217,217,2,221,221,221,1,216,216,216,1,220,220,220,1,219,219,219,1,218, + 218,218,1,219,219,219,1,217,217,217,1,216,216,216,1,221,221,221,1,218, + 218,218,16,216,216,216,1,215,215,215,1,222,222,222,1,255,255,255,2,220, + 220,220,1,255,255,255,1,166,166,166,1,216,216,216,1,221,221,221,1,218, + 218,218,1,216,216,216,1,169,169,169,1,166,166,166,1,169,169,169,2,168, + 168,168,1,167,167,167,1,255,255,255,4,220,220,220,1,218,218,218,1,255, + 255,255,1,254,254,254,1,255,255,255,4,220,220,220,1,217,217,217,1,220, + 220,220,1,217,217,217,1,218,218,218,1,217,217,217,1,222,222,222,1,214, + 214,214,1,215,215,215,1,221,221,221,1,169,169,169,1,166,166,166,1,217, + 217,217,1,219,219,219,1,217,217,217,1,167,167,167,1,218,218,218,1,217, + 217,217,1,216,216,216,1,221,221,221,1,218,218,218,1,217,217,217,1,219, + 219,219,1,218,218,218,1,219,219,219,1,218,218,218,1,215,215,215,1,218, + 218,218,1,171,171,171,1,168,168,168,1,216,216,216,1,255,255,255,3,217, + 217,217,1,218,218,218,1,215,215,215,1,214,214,214,1,255,255,255,3,215, + 215,215,1,218,218,218,2,217,217,217,1,216,216,216,1,254,254,254,2,255, + 255,255,2,221,221,221,1,218,218,218,1,255,255,255,1,252,252,252,1,220, + 220,220,1,167,167,167,1,170,170,170,1,211,211,211,1,217,217,217,1,219, + 219,219,2,221,221,221,1,218,218,218,1,215,215,215,1,216,216,216,1,220, + 220,220,1,255,255,255,1,218,218,218,1,216,216,216,1,254,254,254,1,217, + 217,217,1,219,219,219,1,218,218,218,2,219,219,219,1,216,216,216,1,220, + 220,220,1,217,217,217,2,213,213,213,1,218,218,218,1,220,220,220,1,215, + 215,215,1,218,218,218,1,220,220,220,1,214,214,214,1,216,216,216,1,220, + 220,220,1,219,219,219,1,220,220,220,1,214,214,214,1,222,222,222,1,221, + 221,221,1,218,218,218,1,217,217,217,1,220,220,220,1,218,218,218,1,217, + 217,217,1,218,218,218,1,217,217,217,1,216,216,216,1,220,220,220,2,215, + 215,215,1,218,218,218,16,219,219,219,1,221,221,221,1,211,211,211,1,219, + 219,219,1,255,255,255,1,252,252,252,1,254,254,254,1,220,220,220,1,217, + 217,217,1,218,218,218,1,221,221,221,1,213,213,213,1,255,255,255,2,215, + 215,215,1,255,255,255,1,253,253,253,1,172,172,172,1,214,214,214,1,217, + 217,217,1,254,254,254,1,255,255,255,1,218,218,218,1,217,217,217,1,218, + 218,218,1,217,217,217,1,252,252,252,1,255,255,255,3,218,218,218,1,216, + 216,216,1,218,218,218,1,222,222,222,1,218,218,218,1,217,217,217,1,218, + 218,218,2,255,255,255,1,252,252,252,1,255,255,255,1,217,217,217,1,219, + 219,219,1,218,218,218,1,167,167,167,1,169,169,169,2,219,219,219,1,170, + 170,170,1,167,167,167,1,170,170,170,1,218,218,218,1,217,217,217,1,218, + 218,218,1,219,219,219,1,218,218,218,1,217,217,217,1,169,169,169,1,165, + 165,165,1,169,169,169,1,217,217,217,1,254,254,254,1,253,253,253,1,254, + 254,254,1,255,255,255,1,254,254,254,1,255,255,255,3,216,216,216,1,218, + 218,218,2,219,219,219,1,216,216,216,1,254,254,254,1,221,221,221,1,168, + 168,168,1,169,169,169,1,254,254,254,1,253,253,253,1,255,255,255,4,254, + 254,254,1,218,218,218,1,215,215,215,1,225,225,225,1,220,220,220,1,218, + 218,218,1,216,216,216,1,218,218,218,1,217,217,217,1,220,220,220,1,218, + 218,218,2,253,253,253,1,215,215,215,1,222,222,222,1,255,255,255,1,254, + 254,254,1,218,218,218,1,219,219,219,1,217,217,217,1,219,219,219,1,217, + 217,217,1,216,216,216,1,221,221,221,1,217,217,217,1,220,220,220,1,217, + 217,217,1,220,220,220,1,215,215,215,1,220,220,220,1,223,223,223,1,217, + 217,217,1,222,222,222,1,216,216,216,1,218,218,218,1,217,217,217,1,220, + 220,220,1,217,217,217,2,215,215,215,1,220,220,220,1,216,216,216,1,220, + 220,220,1,218,218,218,1,220,220,220,1,221,221,221,1,217,217,217,2,220, + 220,220,1,217,217,217,1,218,218,218,16,220,220,220,1,216,216,216,1,219, + 219,219,1,255,255,255,1,214,214,214,1,255,255,255,1,218,218,218,1,215, + 215,215,1,219,219,219,2,252,252,252,1,223,223,223,1,218,218,218,1,255, + 255,255,1,219,219,219,1,254,254,254,1,169,169,169,1,166,166,166,1,171, + 171,171,1,221,221,221,1,219,219,219,2,218,218,218,1,217,217,217,2,222, + 222,222,1,218,218,218,1,221,221,221,1,219,219,219,1,216,216,216,1,217, + 217,217,1,220,220,220,1,217,217,217,1,215,215,215,1,218,218,218,1,216, + 216,216,1,220,220,220,2,251,251,251,1,255,255,255,1,220,220,220,1,217, + 217,217,1,218,218,218,1,255,255,255,1,167,167,167,1,168,168,168,1,167, + 167,167,3,168,168,168,1,215,215,215,1,216,216,216,1,223,223,223,1,219, + 219,219,1,216,216,216,1,219,219,219,1,220,220,220,1,217,217,217,1,169, + 169,169,1,167,167,167,1,219,219,219,1,218,218,218,1,255,255,255,2,251, + 251,251,1,215,215,215,1,221,221,221,1,215,215,215,1,216,216,216,1,218, + 218,218,1,217,217,217,1,220,220,220,1,216,216,216,1,255,255,255,1,223, + 223,223,1,215,215,215,1,167,167,167,2,220,220,220,1,255,255,255,1,169, + 169,169,1,165,165,165,1,217,217,217,3,220,220,220,1,218,218,218,1,216, + 216,216,1,215,215,215,1,219,219,219,1,220,220,220,2,216,216,216,1,219, + 219,219,2,217,217,217,2,222,222,222,1,215,215,215,1,216,216,216,1,218, + 218,218,1,217,217,217,1,218,218,218,1,220,220,220,1,218,218,218,1,217, + 217,217,1,220,220,220,1,213,213,213,1,221,221,221,1,217,217,217,2,219, + 219,219,1,220,220,220,1,215,215,215,2,217,217,217,1,215,215,215,1,221, + 221,221,1,220,220,220,1,214,214,214,1,218,218,218,1,220,220,220,1,216, + 216,216,1,221,221,221,1,220,220,220,1,218,218,218,2,216,216,216,2,218, + 218,218,1,219,219,219,1,217,217,217,2,220,220,220,1,218,218,218,16,217, + 217,217,1,215,215,215,1,221,221,221,1,216,216,216,1,220,220,220,1,215, + 215,215,1,217,217,217,1,222,222,222,1,218,218,218,1,217,217,217,2,167, + 167,167,1,214,214,214,1,166,166,166,1,219,219,219,1,220,220,220,1,169, + 169,169,1,167,167,167,2,216,216,216,2,217,217,217,1,167,167,167,1,173, + 173,173,1,215,215,215,1,166,166,166,1,169,169,169,1,164,164,164,1,170, + 170,170,1,219,219,219,1,218,218,218,1,219,219,219,4,221,221,221,1,215, + 215,215,1,167,167,167,1,169,169,169,1,220,220,220,1,219,219,219,1,218, + 218,218,1,251,251,251,1,255,255,255,2,169,169,169,1,221,221,221,1,215, + 215,215,1,223,223,223,1,217,217,217,1,220,220,220,1,219,219,219,2,214, + 214,214,1,218,218,218,1,219,219,219,1,216,216,216,1,218,218,218,1,169, + 169,169,1,170,170,170,1,216,216,216,1,217,217,217,1,218,218,218,1,214, + 214,214,1,224,224,224,1,222,222,222,1,216,216,216,2,221,221,221,1,219, + 219,219,1,169,169,169,1,216,216,216,2,255,255,255,1,250,250,250,1,255, + 255,255,1,222,222,222,1,168,168,168,1,169,169,169,1,165,165,165,1,166, + 166,166,1,175,175,175,1,166,166,166,1,170,170,170,1,172,172,172,1,165, + 165,165,1,219,219,219,1,218,218,218,2,219,219,219,1,218,218,218,2,217, + 217,217,1,218,218,218,1,215,215,215,1,217,217,217,1,223,223,223,1,216, + 216,216,1,219,219,219,1,221,221,221,1,219,219,219,2,217,217,217,2,218, + 218,218,1,219,219,219,1,218,218,218,1,219,219,219,1,217,217,217,1,218, + 218,218,1,219,219,219,1,217,217,217,2,223,223,223,1,219,219,219,1,220, + 220,220,2,217,217,217,2,225,225,225,1,165,165,165,1,168,168,168,1,167, + 167,167,1,219,219,219,1,216,216,216,1,218,218,218,1,216,216,216,1,222, + 222,222,1,220,220,220,1,216,216,216,1,218,218,218,1,220,220,220,1,218, + 218,218,1,217,217,217,1,218,218,218,16,219,219,219,1,220,220,220,1,216, + 216,216,1,219,219,219,3,218,218,218,1,215,215,215,1,218,218,218,1,255, + 255,255,2,214,214,214,1,255,255,255,1,168,168,168,1,218,218,218,1,215, + 215,215,1,218,218,218,1,170,170,170,1,167,167,167,1,220,220,220,1,219, + 219,219,1,218,218,218,1,219,219,219,1,214,214,214,1,170,170,170,2,167, + 167,167,1,171,171,171,1,218,218,218,1,217,217,217,1,218,218,218,1,214, + 214,214,1,219,219,219,1,216,216,216,1,214,214,214,1,221,221,221,1,216, + 216,216,1,168,168,168,1,169,169,169,1,216,216,216,1,214,214,214,1,222, + 222,222,1,255,255,255,1,254,254,254,1,220,220,220,1,215,215,215,1,218, + 218,218,1,220,220,220,1,213,213,213,1,218,218,218,1,219,219,219,1,218, + 218,218,1,215,215,215,1,220,220,220,2,218,218,218,1,223,223,223,1,218, + 218,218,1,166,166,166,1,167,167,167,1,220,220,220,1,219,219,219,1,218, + 218,218,1,253,253,253,1,216,216,216,1,214,214,214,1,221,221,221,1,218, + 218,218,1,216,216,216,1,167,167,167,2,220,220,220,1,218,218,218,1,220, + 220,220,1,255,255,255,1,250,250,250,1,219,219,219,1,166,166,166,1,217, + 217,217,2,223,223,223,1,215,215,215,1,218,218,218,1,165,165,165,1,168, + 168,168,1,171,171,171,1,217,217,217,1,218,218,218,1,220,220,220,1,219, + 219,219,1,218,218,218,3,217,217,217,1,221,221,221,1,220,220,220,1,217, + 217,217,1,216,216,216,2,217,217,217,1,168,168,168,1,218,218,218,2,219, + 219,219,1,218,218,218,1,219,219,219,2,215,215,215,1,219,219,219,1,217, + 217,217,1,218,218,218,1,214,214,214,1,220,220,220,2,215,215,215,1,218, + 218,218,1,217,217,217,1,220,220,220,1,217,217,217,1,214,214,214,1,218, + 218,218,1,172,172,172,1,167,167,167,1,219,219,219,1,216,216,216,1,219, + 219,219,1,216,216,216,1,218,218,218,4,217,217,217,2,220,220,220,1,218, + 218,218,16,216,216,216,1,220,220,220,1,218,218,218,1,219,219,219,1,217, + 217,217,1,214,214,214,1,222,222,222,1,218,218,218,1,217,217,217,1,252, + 252,252,1,255,255,255,2,214,214,214,1,254,254,254,1,218,218,218,1,221, + 221,221,1,219,219,219,1,165,165,165,1,168,168,168,1,220,220,220,1,254, + 254,254,1,253,253,253,1,217,217,217,1,255,255,255,1,254,254,254,2,255, + 255,255,1,218,218,218,1,217,217,217,1,218,218,218,2,219,219,219,1,217, + 217,217,1,218,218,218,1,219,219,219,1,253,253,253,1,218,218,218,1,169, + 169,169,1,167,167,167,1,220,220,220,1,218,218,218,1,167,167,167,1,168, + 168,168,1,219,219,219,1,216,216,216,1,220,220,220,1,217,217,217,1,255, + 255,255,2,254,254,254,1,255,255,255,1,218,218,218,1,219,219,219,1,218, + 218,218,1,216,216,216,1,219,219,219,1,215,215,215,1,221,221,221,1,167, + 167,167,1,171,171,171,1,166,166,166,1,218,218,218,1,215,215,215,1,223, + 223,223,1,217,217,217,2,218,218,218,1,216,216,216,1,255,255,255,1,218, + 218,218,1,219,219,219,1,218,218,218,1,219,219,219,1,217,217,217,2,255, + 255,255,1,254,254,254,1,219,219,219,1,218,218,218,1,255,255,255,1,254, + 254,254,1,255,255,255,3,219,219,219,1,216,216,216,1,218,218,218,4,219, + 219,219,1,217,217,217,1,219,219,219,1,218,218,218,2,215,215,215,1,218, + 218,218,1,220,220,220,1,219,219,219,2,218,218,218,1,168,168,168,1,219, + 219,219,1,215,215,215,1,221,221,221,1,216,216,216,1,218,218,218,2,216, + 216,216,1,219,219,219,1,218,218,218,1,220,220,220,1,217,217,217,2,218, + 218,218,2,220,220,220,1,215,215,215,1,255,255,255,2,254,254,254,1,218, + 218,218,1,217,217,217,1,218,218,218,1,221,221,221,1,216,216,216,1,219, + 219,219,1,218,218,218,1,219,219,219,2,217,217,217,1,219,219,219,1,220, + 220,220,1,216,216,216,1,218,218,218,19,216,216,216,1,220,220,220,1,219, + 219,219,1,214,214,214,1,220,220,220,2,218,218,218,2,254,254,254,1,255, + 255,255,2,219,219,219,1,216,216,216,1,217,217,217,1,171,171,171,1,167, + 167,167,1,217,217,217,1,255,255,255,3,253,253,253,1,255,255,255,1,254, + 254,254,1,217,217,217,1,221,221,221,1,214,214,214,1,220,220,220,1,219, + 219,219,1,216,216,216,1,220,220,220,1,217,217,217,2,220,220,220,1,216, + 216,216,1,170,170,170,1,172,172,172,1,166,166,166,1,167,167,167,1,169, + 169,169,1,215,215,215,1,218,218,218,1,219,219,219,1,218,218,218,2,219, + 219,219,1,255,255,255,1,253,253,253,1,254,254,254,1,218,218,218,1,219, + 219,219,1,218,218,218,1,219,219,219,1,217,217,217,1,218,218,218,1,219, + 219,219,1,170,170,170,1,167,167,167,1,168,168,168,2,217,217,217,1,218, + 218,218,1,221,221,221,1,215,215,215,1,222,222,222,1,253,253,253,1,255, + 255,255,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,2,255, + 255,255,1,216,216,216,1,220,220,220,1,217,217,217,1,216,216,216,1,221, + 221,221,1,217,217,217,2,255,255,255,2,215,215,215,1,218,218,218,2,217, + 217,217,1,219,219,219,1,218,218,218,1,219,219,219,1,218,218,218,1,216, + 216,216,1,218,218,218,2,220,220,220,1,217,217,217,1,216,216,216,1,254, + 254,254,1,221,221,221,1,217,217,217,1,169,169,169,1,218,218,218,9,220, + 220,220,1,214,214,214,1,219,219,219,1,220,220,220,1,217,217,217,1,168, + 168,168,1,217,217,217,1,216,216,216,1,255,255,255,2,215,215,215,1,220, + 220,220,1,218,218,218,3,219,219,219,1,217,217,217,1,219,219,219,2,218, + 218,218,3,169,169,169,1,218,218,218,8,217,217,217,1,220,220,220,1,216, + 216,216,1,220,220,220,1,217,217,217,1,218,218,218,1,216,216,216,1,219, + 219,219,2,217,217,217,1,218,218,218,3,220,220,220,1,219,219,219,2,218, + 218,218,2,219,219,219,1,218,218,218,1,255,255,255,1,254,254,254,1,255, + 255,255,3,217,217,217,1,168,168,168,1,169,169,169,1,167,167,167,2,220, + 220,220,1,216,216,216,1,215,215,215,1,219,219,219,2,168,168,168,1,220, + 220,220,1,219,219,219,2,217,217,217,1,215,215,215,1,221,221,221,1,254, + 254,254,1,215,215,215,1,222,222,222,1,165,165,165,1,164,164,164,1,220, + 220,220,1,221,221,221,1,218,218,218,1,222,222,222,1,216,216,216,1,221, + 221,221,1,166,166,166,2,169,169,169,1,216,216,216,1,255,255,255,2,217, + 217,217,1,218,218,218,1,219,219,219,1,220,220,220,1,216,216,216,1,255, + 255,255,2,212,212,212,1,168,168,168,1,170,170,170,1,169,169,169,1,221, + 221,221,1,216,216,216,1,217,217,217,1,219,219,219,1,218,218,218,1,219, + 219,219,1,220,220,220,1,216,216,216,2,220,220,220,2,219,219,219,1,217, + 217,217,1,255,255,255,1,218,218,218,1,217,217,217,1,220,220,220,1,167, + 167,167,1,169,169,169,2,215,215,215,1,219,219,219,1,169,169,169,1,171, + 171,171,1,219,219,219,1,215,215,215,1,219,219,219,1,217,217,217,1,215, + 215,215,1,221,221,221,1,218,218,218,1,221,221,221,1,217,217,217,1,216, + 216,216,1,222,222,222,1,217,217,217,1,222,222,222,1,251,251,251,1,218, + 218,218,1,217,217,217,1,218,218,218,8,219,219,219,1,217,217,217,1,221, + 221,221,1,217,217,217,1,219,219,219,1,218,218,218,2,169,169,169,1,170, + 170,170,1,217,217,217,1,167,167,167,1,221,221,221,1,215,215,215,1,218, + 218,218,2,217,217,217,1,219,219,219,1,217,217,217,1,215,215,215,1,217, + 217,217,1,220,220,220,1,215,215,215,1,219,219,219,1,216,216,216,1,218, + 218,218,8,214,214,214,1,219,219,219,1,218,218,218,1,217,217,217,1,218, + 218,218,2,171,171,171,1,218,218,218,1,217,217,217,1,220,220,220,1,217, + 217,217,2,218,218,218,1,216,216,216,2,217,217,217,1,219,219,219,1,218, + 218,218,1,215,215,215,1,220,220,220,1,253,253,253,1,255,255,255,2,254, + 254,254,1,253,253,253,1,221,221,221,1,167,167,167,2,255,255,255,2,168, + 168,168,2,173,173,173,1,217,217,217,1,216,216,216,1,217,217,217,1,221, + 221,221,1,214,214,214,1,215,215,215,1,220,220,220,1,219,219,219,1,255, + 255,255,1,218,218,218,1,220,220,220,1,218,218,218,1,220,220,220,2,216, + 216,216,1,218,218,218,2,214,214,214,1,222,222,222,1,217,217,217,1,220, + 220,220,1,169,169,169,1,167,167,167,1,220,220,220,1,255,255,255,1,254, + 254,254,1,215,215,215,1,219,219,219,1,218,218,218,1,214,214,214,1,255, + 255,255,1,253,253,253,1,255,255,255,2,219,219,219,1,167,167,167,1,166, + 166,166,1,215,215,215,1,220,220,220,2,216,216,216,1,217,217,217,1,218, + 218,218,1,217,217,217,1,218,218,218,1,214,214,214,1,221,221,221,1,216, + 216,216,1,253,253,253,1,255,255,255,2,251,251,251,1,255,255,255,1,253, + 253,253,1,254,254,254,1,221,221,221,1,216,216,216,1,218,218,218,1,219, + 219,219,1,168,168,168,1,215,215,215,1,220,220,220,1,221,221,221,1,215, + 215,215,1,219,219,219,1,170,170,170,1,165,165,165,1,219,219,219,1,214, + 214,214,1,221,221,221,1,217,217,217,2,218,218,218,2,255,255,255,1,217, + 217,217,1,218,218,218,9,216,216,216,1,222,222,222,1,215,215,215,1,216, + 216,216,1,255,255,255,1,219,219,219,1,218,218,218,1,216,216,216,1,219, + 219,219,1,215,215,215,1,218,218,218,2,217,217,217,1,222,222,222,1,220, + 220,220,1,219,219,219,1,216,216,216,1,219,219,219,1,222,222,222,1,219, + 219,219,1,216,216,216,1,255,255,255,1,213,213,213,1,219,219,219,1,218, + 218,218,8,219,219,219,1,222,222,222,1,217,217,217,1,218,218,218,1,219, + 219,219,1,218,218,218,1,216,216,216,1,217,217,217,1,220,220,220,1,217, + 217,217,1,216,216,216,1,219,219,219,1,218,218,218,1,219,219,219,1,223, + 223,223,1,218,218,218,1,217,217,217,1,221,221,221,1,218,218,218,1,217, + 217,217,1,220,220,220,1,218,218,218,1,215,215,215,1,220,220,220,1,255, + 255,255,1,252,252,252,1,255,255,255,2,217,217,217,1,215,215,215,1,216, + 216,216,1,217,217,217,1,216,216,216,1,255,255,255,1,220,220,220,1,217, + 217,217,2,219,219,219,1,221,221,221,1,218,218,218,1,216,216,216,1,254, + 254,254,1,217,217,217,1,222,222,222,1,213,213,213,1,218,218,218,1,216, + 216,216,1,222,222,222,1,216,216,216,1,219,219,219,1,218,218,218,1,220, + 220,220,1,216,216,216,1,218,218,218,1,169,169,169,1,171,171,171,1,165, + 165,165,1,253,253,253,1,254,254,254,1,222,222,222,1,217,217,217,1,219, + 219,219,1,169,169,169,1,216,216,216,1,255,255,255,1,252,252,252,1,255, + 255,255,1,219,219,219,1,165,165,165,1,172,172,172,1,217,217,217,1,220, + 220,220,1,217,217,217,2,221,221,221,1,220,220,220,1,218,218,218,1,220, + 220,220,1,221,221,221,1,218,218,218,2,217,217,217,1,252,252,252,1,216, + 216,216,1,220,220,220,1,254,254,254,1,255,255,255,2,218,218,218,1,216, + 216,216,1,255,255,255,1,253,253,253,1,219,219,219,2,216,216,216,1,217, + 217,217,1,221,221,221,1,220,220,220,1,168,168,168,1,169,169,169,2,219, + 219,219,1,215,215,215,1,221,221,221,1,219,219,219,2,218,218,218,3,219, + 219,219,1,218,218,218,8,219,219,219,1,217,217,217,2,222,222,222,1,218, + 218,218,1,255,255,255,1,254,254,254,1,221,221,221,1,255,255,255,1,218, + 218,218,1,217,217,217,1,220,220,220,2,215,215,215,1,218,218,218,1,216, + 216,216,1,218,218,218,1,217,217,217,1,216,216,216,2,217,217,217,1,215, + 215,215,1,220,220,220,2,218,218,218,9,214,214,214,1,219,219,219,1,217, + 217,217,1,255,255,255,1,215,215,215,1,220,220,220,1,219,219,219,1,215, + 215,215,1,217,217,217,1,220,220,220,1,221,221,221,1,217,217,217,1,216, + 216,216,1,217,217,217,1,216,216,216,1,217,217,217,1,219,219,219,1,218, + 218,218,2,217,217,217,1,218,218,218,1,216,216,216,1,218,218,218,1,253, + 253,253,1,254,254,254,1,221,221,221,1,215,215,215,1,221,221,221,1,217, + 217,217,1,255,255,255,1,218,218,218,1,220,220,220,1,217,217,217,1,219, + 219,219,1,217,217,217,1,216,216,216,1,220,220,220,1,217,217,217,1,216, + 216,216,1,255,255,255,2,217,217,217,2,220,220,220,1,216,216,216,1,217, + 217,217,1,220,220,220,1,218,218,218,1,220,220,220,2,216,216,216,1,217, + 217,217,1,220,220,220,1,165,165,165,1,167,167,167,1,169,169,169,1,255, + 255,255,1,253,253,253,1,254,254,254,1,219,219,219,1,167,167,167,1,168, + 168,168,2,217,217,217,1,253,253,253,1,219,219,219,1,220,220,220,1,167, + 167,167,2,220,220,220,1,217,217,217,2,219,219,219,1,218,218,218,1,216, + 216,216,2,218,218,218,1,216,216,216,1,217,217,217,1,221,221,221,1,217, + 217,217,1,224,224,224,1,215,215,215,1,220,220,220,3,218,218,218,1,217, + 217,217,1,219,219,219,1,255,255,255,1,219,219,219,1,216,216,216,1,218, + 218,218,1,220,220,220,1,217,217,217,1,253,253,253,1,254,254,254,1,166, + 166,166,1,219,219,219,1,215,215,215,1,219,219,219,1,220,220,220,1,218, + 218,218,1,214,214,214,1,217,217,217,1,221,221,221,1,216,216,216,1,219, + 219,219,1,218,218,218,9,219,219,219,1,218,218,218,1,219,219,219,1,216, + 216,216,2,217,217,217,1,220,220,220,1,216,216,216,1,219,219,219,3,215, + 215,215,1,218,218,218,1,215,215,215,1,222,222,222,1,219,219,219,1,220, + 220,220,1,218,218,218,1,219,219,219,1,222,222,222,1,217,217,217,1,219, + 219,219,1,220,220,220,1,215,215,215,1,218,218,218,9,221,221,221,1,216, + 216,216,1,219,219,219,1,218,218,218,1,222,222,222,1,214,214,214,1,217, + 217,217,1,220,220,220,2,218,218,218,1,215,215,215,1,219,219,219,1,221, + 221,221,1,216,216,216,1,220,220,220,2,217,217,217,2,218,218,218,1,220, + 220,220,1,221,221,221,1,220,220,220,1,217,217,217,1,219,219,219,2,218, + 218,218,1,222,222,222,1,215,215,215,1,220,220,220,1,216,216,216,1,219, + 219,219,1,217,217,217,1,215,215,215,1,219,219,219,1,220,220,220,1,217, + 217,217,1,216,216,216,1,218,218,218,1,215,215,215,1,255,255,255,2,254, + 254,254,1,217,217,217,2,220,220,220,2,217,217,217,1,215,215,215,1,220, + 220,220,1,215,215,215,1,217,217,217,1,222,222,222,1,214,214,214,1,255, + 255,255,1,216,216,216,1,220,220,220,1,255,255,255,1,254,254,254,2,222, + 222,222,1,167,167,167,1,169,169,169,1,168,168,168,1,170,170,170,1,219, + 219,219,1,218,218,218,1,215,215,215,1,170,170,170,1,167,167,167,1,217, + 217,217,1,218,218,218,1,220,220,220,1,218,218,218,1,216,216,216,1,220, + 220,220,1,222,222,222,1,216,216,216,1,219,219,219,2,218,218,218,1,217, + 217,217,2,220,220,220,1,213,213,213,1,218,218,218,2,215,215,215,1,218, + 218,218,1,217,217,217,1,219,219,219,2,218,218,218,1,219,219,219,1,216, + 216,216,1,219,219,219,1,255,255,255,3,221,221,221,1,219,219,219,1,216, + 216,216,1,218,218,218,1,217,217,217,1,220,220,220,2,219,219,219,2,216, + 216,216,1,217,217,217,1,218,218,218,8,216,216,216,1,220,220,220,1,218, + 218,218,1,219,219,219,2,221,221,221,1,217,217,217,1,219,219,219,1,216, + 216,216,1,221,221,221,1,216,216,216,1,222,222,222,1,220,220,220,1,218, + 218,218,1,216,216,216,2,218,218,218,2,217,217,217,1,218,218,218,1,217, + 217,217,3,220,220,220,1,218,218,218,8,217,217,217,1,218,218,218,3,216, + 216,216,2,221,221,221,1,218,218,218,1,219,219,219,1,215,215,215,1,219, + 219,219,2,216,216,216,1,219,219,219,2,217,217,217,2,216,216,216,1,220, + 220,220,1,218,218,218,2,216,216,216,1,220,220,220,1,219,219,219,1,217, + 217,217,2,213,213,213,1,217,217,217,1,219,219,219,1,214,214,214,1,219, + 219,219,1,221,221,221,1,218,218,218,1,219,219,219,1,217,217,217,1,216, + 216,216,1,219,219,219,1,220,220,220,1,217,217,217,1,221,221,221,1,255, + 255,255,2,252,252,252,1,255,255,255,2,253,253,253,1,218,218,218,1,219, + 219,219,4,254,254,254,1,255,255,255,3,216,216,216,2,220,220,220,1,254, + 254,254,1,255,255,255,1,215,215,215,1,219,219,219,1,166,166,166,1,168, + 168,168,1,214,214,214,1,218,218,218,2,220,220,220,1,168,168,168,1,218, + 218,218,1,220,220,220,1,217,217,217,2,218,218,218,4,216,216,216,1,219, + 219,219,1,215,215,215,1,220,220,220,1,218,218,218,1,220,220,220,1,216, + 216,216,1,219,219,219,3,218,218,218,1,170,170,170,1,221,221,221,1,215, + 215,215,1,218,218,218,1,215,215,215,1,221,221,221,2,215,215,215,1,254, + 254,254,1,221,221,221,1,215,215,215,1,217,217,217,1,218,218,218,2,217, + 217,217,1,218,218,218,2,216,216,216,1,217,217,217,1,215,215,215,1,221, + 221,221,1,219,219,219,1,218,218,218,8,222,222,222,1,216,216,216,1,219, + 219,219,1,218,218,218,1,219,219,219,1,218,218,218,1,216,216,216,1,217, + 217,217,1,221,221,221,1,213,213,213,1,218,218,218,1,217,217,217,1,218, + 218,218,1,220,220,220,1,218,218,218,1,219,219,219,1,216,216,216,1,220, + 220,220,1,217,217,217,2,219,219,219,1,220,220,220,1,217,217,217,2,218, + 218,218,8,221,221,221,1,214,214,214,1,221,221,221,1,216,216,216,1,218, + 218,218,1,219,219,219,3,216,216,216,1,220,220,220,1,216,216,216,1,219, + 219,219,1,220,220,220,1,216,216,216,1,220,220,220,1,217,217,217,1,220, + 220,220,1,218,218,218,1,219,219,219,1,218,218,218,1,219,219,219,1,218, + 218,218,1,219,219,219,1,217,217,217,1,219,219,219,2,221,221,221,1,217, + 217,217,1,220,220,220,1,218,218,218,1,168,168,168,1,165,165,165,1,220, + 220,220,1,218,218,218,1,219,219,219,1,217,217,217,1,218,218,218,2,217, + 217,217,1,218,218,218,1,217,217,217,1,253,253,253,1,255,255,255,1,254, + 254,254,2,220,220,220,1,217,217,217,1,219,219,219,1,218,218,218,1,217, + 217,217,1,218,218,218,1,255,255,255,1,218,218,218,4,219,219,219,1,216, + 216,216,1,255,255,255,1,218,218,218,1,217,217,217,1,220,220,220,1,219, + 219,219,2,220,220,220,1,217,217,217,2,218,218,218,1,216,216,216,1,220, + 220,220,1,216,216,216,1,220,220,220,1,219,219,219,1,217,217,217,1,219, + 219,219,2,218,218,218,1,219,219,219,1,217,217,217,1,218,218,218,1,217, + 217,217,1,218,218,218,3,220,220,220,1,217,217,217,2,170,170,170,1,215, + 215,215,1,217,217,217,1,220,220,220,1,218,218,218,1,220,220,220,1,216, + 216,216,1,217,217,217,2,221,221,221,1,216,216,216,1,220,220,220,1,216, + 216,216,1,218,218,218,2,219,219,219,1,218,218,218,2,219,219,219,2,217, + 217,217,1,219,219,219,1,217,217,217,1,218,218,218,8,216,216,216,1,219, + 219,219,1,215,215,215,1,221,221,221,1,217,217,217,1,216,216,216,1,222, + 222,222,1,217,217,217,1,216,216,216,1,223,223,223,1,216,216,216,1,217, + 217,217,1,218,218,218,1,219,219,219,1,216,216,216,1,218,218,218,1,219, + 219,219,1,216,216,216,1,218,218,218,1,220,220,220,1,216,216,216,1,219, + 219,219,1,216,216,216,1,220,220,220,1,218,218,218,8,216,216,216,1,222, + 222,222,1,217,217,217,1,216,216,216,1,219,219,219,2,215,215,215,1,217, + 217,217,1,219,219,219,1,218,218,218,1,168,168,168,1,169,169,169,1,215, + 215,215,1,220,220,220,1,217,217,217,1,220,220,220,1,217,217,217,1,218, + 218,218,2,219,219,219,1,217,217,217,1,218,218,218,2,219,219,219,1,216, + 216,216,1,220,220,220,1,218,218,218,1,216,216,216,1,220,220,220,1,217, + 217,217,1,218,218,218,3,219,219,219,1,218,218,218,2,216,216,216,1,218, + 218,218,1,217,217,217,1,221,221,221,1,216,216,216,1,220,220,220,1,217, + 217,217,2,255,255,255,2,218,218,218,1,220,220,220,1,217,217,217,1,219, + 219,219,1,217,217,217,2,220,220,220,1,217,217,217,1,216,216,216,1,221, + 221,221,1,218,218,218,1,217,217,217,1,219,219,219,1,222,222,222,1,213, + 213,213,1,219,219,219,3,217,217,217,1,219,219,219,1,218,218,218,1,217, + 217,217,1,220,220,220,1,218,218,218,1,217,217,217,1,218,218,218,2,219, + 219,219,1,215,215,215,1,219,219,219,1,218,218,218,1,219,219,219,2,218, + 218,218,1,216,216,216,1,221,221,221,1,219,219,219,1,217,217,217,1,219, + 219,219,1,217,217,217,1,255,255,255,1,167,167,167,1,171,171,171,1,218, + 218,218,3,219,219,219,1,218,218,218,1,217,217,217,1,216,216,216,1,220, + 220,220,1,217,217,217,1,219,219,219,1,217,217,217,1,219,219,219,1,218, + 218,218,9,217,217,217,1,219,219,219,1,218,218,218,2,217,217,217,1,220, + 220,220,1,215,215,215,1,219,219,219,1,216,216,216,1,221,221,221,1,219, + 219,219,1,217,217,217,1,218,218,218,1,217,217,217,1,219,219,219,1,218, + 218,218,1,219,219,219,1,217,217,217,1,216,216,216,1,220,220,220,2,217, + 217,217,1,218,218,218,1,219,219,219,1,218,218,218,2,216,216,216,1,219, + 219,219,1,217,217,217,1,220,220,220,1,218,218,218,1,219,219,219,1,218, + 218,218,16,215,215,215,1,222,222,222,1,216,216,216,1,217,217,217,1,220, + 220,220,1,216,216,216,1,219,219,219,1,220,220,220,1,218,218,218,15,217, + 217,217,1,170,170,170,1,214,214,214,1,219,219,219,1,220,220,220,1,219, + 219,219,1,218,218,218,1,219,219,219,1,215,215,215,1,219,219,219,1,216, + 216,216,1,218,218,218,1,255,255,255,1,252,252,252,1,255,255,255,1,254, + 254,254,1,255,255,255,2,214,214,214,1,220,220,220,2,217,217,217,1,218, + 218,218,1,222,222,222,1,214,214,214,1,218,218,218,1,222,222,222,1,214, + 214,214,1,218,218,218,2,221,221,221,1,219,219,219,1,218,218,218,1,214, + 214,214,1,220,220,220,1,217,217,217,1,220,220,220,1,215,215,215,1,218, + 218,218,1,221,221,221,1,217,217,217,1,216,216,216,1,217,217,217,1,221, + 221,221,1,218,218,218,1,215,215,215,1,168,168,168,1,217,217,217,2,218, + 218,218,1,215,215,215,1,216,216,216,1,218,218,218,1,220,220,220,1,253, + 253,253,1,218,218,218,1,165,165,165,1,164,164,164,1,217,217,217,1,221, + 221,221,1,218,218,218,1,215,215,215,1,219,219,219,1,221,221,221,2,218, + 218,218,1,215,215,215,1,220,220,220,1,218,218,218,1,217,217,217,1,218, + 218,218,9,219,219,219,1,215,215,215,1,217,217,217,1,218,218,218,1,216, + 216,216,1,217,217,217,1,223,223,223,1,216,216,216,1,218,218,218,1,215, + 215,215,1,221,221,221,1,217,217,217,1,220,220,220,1,218,218,218,1,220, + 220,220,1,217,217,217,2,220,220,220,2,215,215,215,1,218,218,218,1,220, + 220,220,1,216,216,216,1,217,217,217,2,219,219,219,1,220,220,220,1,218, + 218,218,2,216,216,216,1,219,219,219,1,216,216,216,1,218,218,218,16,255, + 255,255,1,248,248,248,1,224,224,224,1,215,215,215,1,219,219,219,1,218, + 218,218,2,216,216,216,1,218,218,218,14,219,219,219,1,216,216,216,1,219, + 219,219,2,217,217,217,1,219,219,219,2,217,217,217,1,215,215,215,1,223, + 223,223,1,216,216,216,2,222,222,222,1,221,221,221,1,253,253,253,1,255, + 255,255,2,215,215,215,1,218,218,218,1,222,222,222,1,217,217,217,1,166, + 166,166,1,170,170,170,1,217,217,217,1,216,216,216,1,219,219,219,1,218, + 218,218,4,217,217,217,1,255,255,255,1,254,254,254,1,255,255,255,2,217, + 217,217,1,218,218,218,1,219,219,219,1,222,222,222,1,219,219,219,1,215, + 215,215,1,219,219,219,1,220,220,220,1,218,218,218,1,214,214,214,1,170, + 170,170,1,167,167,167,1,169,169,169,1,166,166,166,1,220,220,220,1,218, + 218,218,1,220,220,220,1,219,219,219,1,216,216,216,1,217,217,217,1,255, + 255,255,2,173,173,173,1,169,169,169,1,217,217,217,1,219,219,219,1,218, + 218,218,1,220,220,220,1,166,166,166,1,165,165,165,1,217,217,217,1,216, + 216,216,1,221,221,221,1,216,216,216,1,217,217,217,2,219,219,219,1,218, + 218,218,9,219,219,219,1,218,218,218,1,220,220,220,1,221,221,221,1,216, + 216,216,2,219,219,219,1,221,221,221,1,218,218,218,1,217,217,217,3,218, + 218,218,1,216,216,216,1,219,219,219,1,217,217,217,1,219,219,219,2,218, + 218,218,3,219,219,219,1,220,220,220,1,221,221,221,1,216,216,216,3,217, + 217,217,1,224,224,224,1,214,214,214,1,222,222,222,1,218,218,218,16,217, + 217,217,1,222,222,222,1,217,217,217,1,218,218,218,1,221,221,221,1,217, + 217,217,1,219,219,219,2,218,218,218,14,254,254,254,1,220,220,220,1,219, + 219,219,1,218,218,218,1,220,220,220,1,215,215,215,1,214,214,214,1,218, + 218,218,1,219,219,219,1,217,217,217,1,222,222,222,1,217,217,217,1,216, + 216,216,1,214,214,214,1,219,219,219,1,217,217,217,1,220,220,220,1,219, + 219,219,1,217,217,217,1,215,215,215,1,170,170,170,1,168,168,168,1,165, + 165,165,1,219,219,219,3,218,218,218,1,217,217,217,1,218,218,218,1,219, + 219,219,1,253,253,253,1,254,254,254,1,255,255,255,1,251,251,251,1,215, + 215,215,1,222,222,222,1,217,217,217,1,218,218,218,1,215,215,215,1,217, + 217,217,1,221,221,221,1,219,219,219,1,217,217,217,1,218,218,218,1,221, + 221,221,1,215,215,215,1,171,171,171,1,167,167,167,1,219,219,219,1,215, + 215,215,1,218,218,218,1,215,215,215,1,221,221,221,1,218,218,218,1,216, + 216,216,1,255,255,255,1,254,254,254,1,166,166,166,1,215,215,215,1,218, + 218,218,1,168,168,168,1,215,215,215,1,220,220,220,1,219,219,219,1,170, + 170,170,1,218,218,218,1,219,219,219,1,221,221,221,1,216,216,216,1,220, + 220,220,1,219,219,219,1,217,217,217,1,218,218,218,8,220,220,220,1,215, + 215,215,1,217,217,217,1,219,219,219,1,215,215,215,1,221,221,221,1,217, + 217,217,1,218,218,218,1,216,216,216,1,217,217,217,1,170,170,170,1,218, + 218,218,2,217,217,217,1,218,218,218,1,220,220,220,1,219,219,219,1,217, + 217,217,1,215,215,215,1,221,221,221,1,218,218,218,1,216,216,216,1,221, + 221,221,1,214,214,214,1,215,215,215,1,171,171,171,1,219,219,219,1,168, + 168,168,2,218,218,218,1,214,214,214,1,218,218,218,17,217,217,217,1,221, + 221,221,1,218,218,218,3,216,216,216,1,218,218,218,1,219,219,219,1,218, + 218,218,14,217,217,217,1,219,219,219,1,215,215,215,1,217,217,217,1,218, + 218,218,1,220,220,220,1,219,219,219,1,220,220,220,2,216,216,216,1,215, + 215,215,1,219,219,219,1,220,220,220,1,219,219,219,1,165,165,165,1,220, + 220,220,1,216,216,216,1,220,220,220,1,170,170,170,1,218,218,218,1,221, + 221,221,1,165,165,165,1,171,171,171,1,167,167,167,1,215,215,215,1,217, + 217,217,1,220,220,220,1,217,217,217,1,220,220,220,2,218,218,218,1,219, + 219,219,1,217,217,217,1,221,221,221,1,219,219,219,1,215,215,215,1,218, + 218,218,1,220,220,220,1,218,218,218,1,222,222,222,1,215,215,215,1,217, + 217,217,3,220,220,220,1,215,215,215,1,220,220,220,1,167,167,167,1,218, + 218,218,1,220,220,220,1,218,218,218,1,167,167,167,1,169,169,169,1,215, + 215,215,1,220,220,220,1,255,255,255,1,254,254,254,1,219,219,219,1,173, + 173,173,1,165,165,165,1,171,171,171,1,220,220,220,1,253,253,253,1,216, + 216,216,1,218,218,218,1,215,215,215,1,220,220,220,1,217,217,217,1,218, + 218,218,3,219,219,219,1,218,218,218,8,217,217,217,1,219,219,219,1,217, + 217,217,1,218,218,218,1,219,219,219,1,220,220,220,1,217,217,217,1,218, + 218,218,2,219,219,219,1,217,217,217,1,219,219,219,1,221,221,221,1,215, + 215,215,1,221,221,221,1,215,215,215,1,218,218,218,3,217,217,217,1,219, + 219,219,1,218,218,218,1,217,217,217,1,221,221,221,1,219,219,219,1,166, + 166,166,1,219,219,219,1,216,216,216,1,217,217,217,1,220,220,220,1,217, + 217,217,1,219,219,219,1,218,218,218,18,216,216,216,1,218,218,218,1,220, + 220,220,1,219,219,219,1,218,218,218,1,216,216,216,1,218,218,218,15,217, + 217,217,1,222,222,222,1,218,218,218,1,217,217,217,2,216,216,216,1,217, + 217,217,1,219,219,219,2,217,217,217,1,216,216,216,1,219,219,219,3,167, + 167,167,1,169,169,169,1,165,165,165,1,215,215,215,1,217,217,217,1,219, + 219,219,1,167,167,167,1,171,171,171,1,215,215,215,1,220,220,220,1,222, + 222,222,1,216,216,216,1,215,215,215,1,216,216,216,2,220,220,220,1,215, + 215,215,1,214,214,214,1,218,218,218,1,221,221,221,1,217,217,217,1,222, + 222,222,1,217,217,217,2,216,216,216,1,219,219,219,1,222,222,222,1,169, + 169,169,1,217,217,217,1,218,218,218,1,222,222,222,1,162,162,162,1,169, + 169,169,1,216,216,216,1,219,219,219,1,217,217,217,1,167,167,167,1,217, + 217,217,1,174,174,174,1,164,164,164,1,218,218,218,1,168,168,168,2,212, + 212,212,1,173,173,173,1,164,164,164,1,166,166,166,1,255,255,255,1,219, + 219,219,1,218,218,218,1,222,222,222,1,217,217,217,1,219,219,219,1,217, + 217,217,1,218,218,218,1,217,217,217,1,219,219,219,1,218,218,218,9,217, + 217,217,1,221,221,221,1,220,220,220,1,216,216,216,1,220,220,220,1,216, + 216,216,1,168,168,168,1,253,253,253,1,218,218,218,1,217,217,217,1,218, + 218,218,1,216,216,216,1,220,220,220,2,219,219,219,2,217,217,217,1,221, + 221,221,1,215,215,215,1,220,220,220,1,219,219,219,1,215,215,215,1,254, + 254,254,1,219,219,219,1,254,254,254,2,220,220,220,1,217,217,217,1,168, + 168,168,1,221,221,221,1,217,217,217,1,218,218,218,19,217,217,217,3,220, + 220,220,1,221,221,221,1,218,218,218,16,213,213,213,1,222,222,222,1,218, + 218,218,1,220,220,220,1,222,222,222,1,215,215,215,1,217,217,217,1,219, + 219,219,1,216,216,216,1,221,221,221,1,255,255,255,1,219,219,219,1,216, + 216,216,1,168,168,168,1,219,219,219,1,217,217,217,1,221,221,221,1,254, + 254,254,1,255,255,255,1,217,217,217,1,219,219,219,1,217,217,217,1,216, + 216,216,1,219,219,219,1,217,217,217,1,174,174,174,1,168,168,168,1,169, + 169,169,1,217,217,217,1,219,219,219,1,222,222,222,1,215,215,215,1,220, + 220,220,1,214,214,214,1,217,217,217,1,221,221,221,1,215,215,215,1,219, + 219,219,1,215,215,215,1,254,254,254,2,255,255,255,2,254,254,254,1,220, + 220,220,1,218,218,218,1,220,220,220,1,253,253,253,1,255,255,255,1,220, + 220,220,1,214,214,214,1,168,168,168,2,169,169,169,1,220,220,220,1,216, + 216,216,1,219,219,219,1,218,218,218,1,220,220,220,1,219,219,219,1,216, + 216,216,1,217,217,217,2,218,218,218,1,216,216,216,1,220,220,220,1,217, + 217,217,1,221,221,221,1,220,220,220,1,215,215,215,1,218,218,218,8,221, + 221,221,1,216,216,216,1,215,215,215,1,218,218,218,1,215,215,215,1,219, + 219,219,2,220,220,220,1,171,171,171,1,167,167,167,1,218,218,218,1,219, + 219,219,1,218,218,218,1,220,220,220,1,212,212,212,1,219,219,219,2,216, + 216,216,1,220,220,220,1,217,217,217,1,220,220,220,1,217,217,217,1,219, + 219,219,1,255,255,255,1,218,218,218,1,219,219,219,1,218,218,218,1,220, + 220,220,1,168,168,168,1,165,165,165,1,218,218,218,1,219,219,219,1,218, + 218,218,16,219,219,219,1,217,217,217,1,218,218,218,1,219,219,219,2,220, + 220,220,1,217,217,217,1,214,214,214,1,218,218,218,14,216,216,216,1,221, + 221,221,1,220,220,220,1,215,215,215,1,218,218,218,2,215,215,215,1,220, + 220,220,1,219,219,219,1,217,217,217,1,219,219,219,1,218,218,218,1,215, + 215,215,1,255,255,255,1,220,220,220,1,216,216,216,2,221,221,221,1,218, + 218,218,1,254,254,254,1,255,255,255,1,219,219,219,1,216,216,216,1,220, + 220,220,2,215,215,215,1,170,170,170,1,165,165,165,1,168,168,168,2,218, + 218,218,1,217,217,217,2,219,219,219,1,215,215,215,1,221,221,221,1,218, + 218,218,1,216,216,216,1,220,220,220,1,219,219,219,1,255,255,255,3,254, + 254,254,1,255,255,255,1,253,253,253,1,219,219,219,1,218,218,218,1,217, + 217,217,1,255,255,255,1,165,165,165,1,218,218,218,1,255,255,255,1,215, + 215,215,1,217,217,217,1,218,218,218,1,216,216,216,1,220,220,220,1,255, + 255,255,2,215,215,215,1,217,217,217,1,220,220,220,1,218,218,218,1,217, + 217,217,1,170,170,170,1,216,216,216,1,220,220,220,1,219,219,219,1,215, + 215,215,1,219,219,219,2,218,218,218,8,215,215,215,1,221,221,221,1,219, + 219,219,1,216,216,216,1,221,221,221,1,253,253,253,1,217,217,217,2,216, + 216,216,1,218,218,218,1,221,221,221,1,214,214,214,1,221,221,221,1,217, + 217,217,1,219,219,219,1,220,220,220,1,218,218,218,2,217,217,217,1,218, + 218,218,1,217,217,217,1,218,218,218,1,220,220,220,1,216,216,216,1,219, + 219,219,1,216,216,216,1,218,218,218,1,254,254,254,1,219,219,219,1,220, + 220,220,1,167,167,167,2,218,218,218,17,217,217,217,1,219,219,219,2,216, + 216,216,1,218,218,218,1,219,219,219,2,218,218,218,22,219,219,219,1,218, + 218,218,1,215,215,215,1,221,221,221,1,220,220,220,1,255,255,255,1,254, + 254,254,1,219,219,219,1,218,218,218,1,167,167,167,1,169,169,169,1,251, + 251,251,1,255,255,255,1,218,218,218,2,217,217,217,1,220,220,220,1,255, + 255,255,1,253,253,253,1,220,220,220,1,166,166,166,1,169,169,169,1,221, + 221,221,1,215,215,215,1,220,220,220,1,217,217,217,1,220,220,220,1,215, + 215,215,1,218,218,218,1,217,217,217,1,219,219,219,4,218,218,218,1,216, + 216,216,1,219,219,219,1,217,217,217,2,218,218,218,1,220,220,220,1,216, + 216,216,1,219,219,219,1,254,254,254,1,218,218,218,1,220,220,220,1,218, + 218,218,1,217,217,217,2,219,219,219,1,218,218,218,1,166,166,166,1,170, + 170,170,1,218,218,218,1,217,217,217,1,216,216,216,1,219,219,219,1,218, + 218,218,2,219,219,219,1,216,216,216,1,219,219,219,2,216,216,216,1,218, + 218,218,1,219,219,219,2,215,215,215,1,221,221,221,1,218,218,218,1,216, + 216,216,1,219,219,219,2,218,218,218,1,217,217,217,3,218,218,218,1,255, + 255,255,2,218,218,218,16,219,219,219,1,217,217,217,1,255,255,255,2,217, + 217,217,1,218,218,218,1,167,167,167,1,168,168,168,1,219,219,219,2,218, + 218,218,1,217,217,217,1,218,218,218,1,217,217,217,1,220,220,220,1,217, + 217,217,2,219,219,219,2,218,218,218,1,217,217,217,1,218,218,218,1,215, + 215,215,1,221,221,221,1,217,217,217,1,218,218,218,1,216,216,216,1,221, + 221,221,1,215,215,215,1,218,218,218,1,220,220,220,1,215,215,215,1,217, + 217,217,1,219,219,219,1,218,218,218,1,216,216,216,1,221,221,221,1,216, + 216,216,1,218,218,218,1,216,216,216,1,218,218,218,14,219,219,219,1,217, + 217,217,1,221,221,221,1,216,216,216,1,251,251,251,1,255,255,255,1,254, + 254,254,1,218,218,218,1,221,221,221,1,164,164,164,1,219,219,219,1,255, + 255,255,2,254,254,254,1,253,253,253,1,255,255,255,1,252,252,252,1,255, + 255,255,1,218,218,218,1,253,253,253,1,170,170,170,1,215,215,215,1,217, + 217,217,1,222,222,222,1,215,215,215,1,219,219,219,1,215,215,215,1,218, + 218,218,1,221,221,221,1,220,220,220,1,216,216,216,1,215,215,215,1,218, + 218,218,1,217,217,217,2,219,219,219,3,220,220,220,1,218,218,218,1,253, + 253,253,1,255,255,255,1,219,219,219,1,218,218,218,1,255,255,255,4,219, + 219,219,1,218,218,218,1,219,219,219,1,167,167,167,1,216,216,216,2,220, + 220,220,1,255,255,255,1,217,217,217,2,218,218,218,1,217,217,217,1,221, + 221,221,1,216,216,216,1,217,217,217,1,219,219,219,1,217,217,217,1,215, + 215,215,1,217,217,217,1,222,222,222,1,216,216,216,2,222,222,222,1,218, + 218,218,1,215,215,215,1,219,219,219,2,220,220,220,1,219,219,219,1,220, + 220,220,1,214,214,214,1,219,219,219,1,218,218,218,16,216,216,216,1,219, + 219,219,1,218,218,218,2,255,255,255,2,171,171,171,1,169,169,169,1,215, + 215,215,1,218,218,218,1,219,219,219,1,220,220,220,1,216,216,216,1,223, + 223,223,1,214,214,214,1,219,219,219,1,220,220,220,1,216,216,216,1,219, + 219,219,1,220,220,220,1,217,217,217,1,170,170,170,2,215,215,215,1,217, + 217,217,1,220,220,220,1,218,218,218,2,217,217,217,1,218,218,218,1,219, + 219,219,1,222,222,222,1,220,220,220,1,216,216,216,1,220,220,220,1,219, + 219,219,1,215,215,215,1,217,217,217,1,224,224,224,1,219,219,219,1,218, + 218,218,14,216,216,216,1,219,219,219,1,218,218,218,2,172,172,172,1,216, + 216,216,1,219,219,219,1,217,217,217,1,255,255,255,1,218,218,218,1,219, + 219,219,1,250,250,250,1,255,255,255,2,254,254,254,1,220,220,220,1,218, + 218,218,1,255,255,255,3,217,217,217,1,220,220,220,1,219,219,219,1,215, + 215,215,1,219,219,219,1,218,218,218,1,220,220,220,1,217,217,217,1,215, + 215,215,1,218,218,218,1,217,217,217,1,222,222,222,1,215,215,215,1,221, + 221,221,1,218,218,218,1,219,219,219,1,217,217,217,1,218,218,218,1,214, + 214,214,1,219,219,219,1,170,170,170,1,166,166,166,1,255,255,255,1,253, + 253,253,1,255,255,255,1,254,254,254,1,253,253,253,1,255,255,255,1,219, + 219,219,1,253,253,253,1,255,255,255,1,218,218,218,1,220,220,220,1,219, + 219,219,1,215,215,215,1,217,217,217,1,169,169,169,1,168,168,168,1,218, + 218,218,1,219,219,219,1,216,216,216,1,220,220,220,1,218,218,218,1,216, + 216,216,1,168,168,168,1,220,220,220,1,219,219,219,1,214,214,214,1,218, + 218,218,3,215,215,215,1,221,221,221,1,215,215,215,1,218,218,218,1,216, + 216,216,1,217,217,217,1,216,216,216,1,222,222,222,1,217,217,217,1,218, + 218,218,16,219,219,219,3,218,218,218,1,255,255,255,2,211,211,211,1,220, + 220,220,1,223,223,223,1,216,216,216,1,167,167,167,1,215,215,215,1,219, + 219,219,1,218,218,218,1,219,219,219,1,217,217,217,1,216,216,216,1,219, + 219,219,1,215,215,215,1,222,222,222,1,166,166,166,1,165,165,165,1,171, + 171,171,1,218,218,218,1,217,217,217,3,218,218,218,1,220,220,220,1,217, + 217,217,2,216,216,216,1,215,215,215,1,219,219,219,1,217,217,217,1,218, + 218,218,3,216,216,216,1,218,218,218,15,219,219,219,1,218,218,218,2,217, + 217,217,1,214,214,214,1,255,255,255,1,218,218,218,1,220,220,220,1,217, + 217,217,1,218,218,218,2,222,222,222,1,217,217,217,1,218,218,218,1,215, + 215,215,1,218,218,218,1,255,255,255,1,215,215,215,1,255,255,255,1,218, + 218,218,1,219,219,219,1,216,216,216,2,220,220,220,1,219,219,219,1,214, + 214,214,1,221,221,221,1,217,217,217,1,218,218,218,1,220,220,220,1,215, + 215,215,1,217,217,217,1,221,221,221,1,217,217,217,1,165,165,165,1,217, + 217,217,1,218,218,218,1,220,220,220,1,222,222,222,1,168,168,168,2,220, + 220,220,1,166,166,166,1,221,221,221,1,215,215,215,1,219,219,219,1,222, + 222,222,1,215,215,215,1,218,218,218,1,251,251,251,1,216,216,216,1,219, + 219,219,1,216,216,216,1,219,219,219,1,217,217,217,1,219,219,219,1,167, + 167,167,1,166,166,166,1,220,220,220,1,219,219,219,1,215,215,215,1,220, + 220,220,1,219,219,219,1,220,220,220,2,215,215,215,1,220,220,220,1,221, + 221,221,1,216,216,216,1,219,219,219,1,217,217,217,1,221,221,221,1,216, + 216,216,1,218,218,218,1,221,221,221,1,219,219,219,1,218,218,218,1,220, + 220,220,1,215,215,215,1,220,220,220,1,218,218,218,16,217,217,217,1,219, + 219,219,1,215,215,215,1,218,218,218,1,255,255,255,1,253,253,253,1,220, + 220,220,1,221,221,221,1,214,214,214,1,217,217,217,1,219,219,219,1,222, + 222,222,1,218,218,218,1,215,215,215,1,222,222,222,1,217,217,217,2,221, + 221,221,1,167,167,167,1,255,255,255,1,254,254,254,1,221,221,221,1,217, + 217,217,1,218,218,218,1,222,222,222,1,215,215,215,1,220,220,220,1,221, + 221,221,1,214,214,214,1,221,221,221,1,219,219,219,1,166,166,166,1,171, + 171,171,1,217,217,217,1,220,220,220,1,217,217,217,1,218,218,218,1,220, + 220,220,1,217,217,217,1,218,218,218,17,253,253,253,1,255,255,255,1,254, + 254,254,1,255,255,255,1,216,216,216,1,217,217,217,1,220,220,220,2,215, + 215,215,2,222,222,222,1,216,216,216,1,220,220,220,1,217,217,217,1,220, + 220,220,1,214,214,214,1,223,223,223,1,214,214,214,1,221,221,221,1,219, + 219,219,4,220,220,220,1,215,215,215,1,219,219,219,1,218,218,218,1,219, + 219,219,1,220,220,220,1,217,217,217,1,218,218,218,1,216,216,216,1,221, + 221,221,1,219,219,219,1,217,217,217,1,220,220,220,1,251,251,251,1,255, + 255,255,1,220,220,220,1,213,213,213,1,220,220,220,1,216,216,216,1,217, + 217,217,1,215,215,215,1,218,218,218,1,220,220,220,1,215,215,215,1,225, + 225,225,1,217,217,217,1,221,221,221,1,217,217,217,1,215,215,215,1,255, + 255,255,1,254,254,254,1,220,220,220,1,219,219,219,1,217,217,217,1,215, + 215,215,1,218,218,218,1,170,170,170,1,253,253,253,1,219,219,219,1,217, + 217,217,1,221,221,221,1,216,216,216,2,221,221,221,1,218,218,218,2,215, + 215,215,1,219,219,219,1,218,218,218,1,216,216,216,1,218,218,218,2,214, + 214,214,1,221,221,221,1,215,215,215,1,218,218,218,16,217,217,217,1,216, + 216,216,1,222,222,222,1,218,218,218,1,217,217,217,1,218,218,218,1,220, + 220,220,1,214,214,214,1,255,255,255,1,216,216,216,1,218,218,218,1,217, + 217,217,1,218,218,218,1,216,216,216,1,167,167,167,1,216,216,216,1,221, + 221,221,1,216,216,216,1,255,255,255,1,253,253,253,1,255,255,255,1,218, + 218,218,1,216,216,216,1,220,220,220,1,215,215,215,1,219,219,219,1,216, + 216,216,1,219,219,219,1,218,218,218,1,217,217,217,2,169,169,169,1,165, + 165,165,1,218,218,218,2,220,220,220,1,217,217,217,2,221,221,221,1,219, + 219,219,1,218,218,218,16,220,220,220,1,219,219,219,1,255,255,255,1,251, + 251,251,1,218,218,218,1,220,220,220,1,216,216,216,1,219,219,219,2,217, + 217,217,1,218,218,218,1,217,217,217,2,218,218,218,2,220,220,220,1,217, + 217,217,1,218,218,218,1,217,217,217,1,216,216,216,1,218,218,218,1,217, + 217,217,1,215,215,215,1,220,220,220,1,219,219,219,1,214,214,214,1,221, + 221,221,1,218,218,218,1,164,164,164,1,170,170,170,1,255,255,255,1,218, + 218,218,1,219,219,219,1,218,218,218,1,216,216,216,1,252,252,252,1,255, + 255,255,2,253,253,253,1,222,222,222,1,218,218,218,2,221,221,221,1,219, + 219,219,1,217,217,217,2,220,220,220,1,213,213,213,1,219,219,219,1,215, + 215,215,1,221,221,221,1,217,217,217,1,253,253,253,1,254,254,254,1,217, + 217,217,1,219,219,219,1,216,216,216,1,225,225,225,1,218,218,218,1,217, + 217,217,2,218,218,218,1,219,219,219,1,218,218,218,1,169,169,169,1,166, + 166,166,1,217,217,217,1,219,219,219,1,216,216,216,1,222,222,222,1,167, + 167,167,1,168,168,168,1,218,218,218,1,220,220,220,1,219,219,219,1,217, + 217,217,1,222,222,222,1,218,218,218,17,220,220,220,1,219,219,219,1,215, + 215,215,1,216,216,216,1,219,219,219,1,216,216,216,1,220,220,220,1,219, + 219,219,1,215,215,215,1,222,222,222,1,216,216,216,1,218,218,218,1,220, + 220,220,1,218,218,218,1,172,172,172,1,168,168,168,1,254,254,254,1,218, + 218,218,1,217,217,217,1,223,223,223,1,214,214,214,1,219,219,219,1,218, + 218,218,1,216,216,216,1,219,219,219,1,220,220,220,1,218,218,218,1,217, + 217,217,1,219,219,219,1,254,254,254,1,255,255,255,1,166,166,166,1,170, + 170,170,1,221,221,221,1,216,216,216,1,218,218,218,1,220,220,220,1,216, + 216,216,1,217,217,217,1,218,218,218,15,219,219,219,1,216,216,216,1,219, + 219,219,1,220,220,220,1,214,214,214,1,221,221,221,1,219,219,219,1,215, + 215,215,2,221,221,221,1,216,216,216,1,219,219,219,1,218,218,218,1,222, + 222,222,1,216,216,216,1,219,219,219,2,215,215,215,1,222,222,222,1,219, + 219,219,1,217,217,217,1,223,223,223,1,219,219,219,1,215,215,215,1,218, + 218,218,2,216,216,216,1,220,220,220,1,216,216,216,1,217,217,217,1,220, + 220,220,1,217,217,217,1,219,219,219,1,216,216,216,1,218,218,218,1,220, + 220,220,1,217,217,217,1,221,221,221,1,218,218,218,1,217,217,217,1,218, + 218,218,1,216,216,216,1,220,220,220,1,219,219,219,1,216,216,216,1,217, + 217,217,1,219,219,219,1,218,218,218,1,217,217,217,1,219,219,219,1,221, + 221,221,1,216,216,216,1,217,217,217,1,220,220,220,1,219,219,219,1,218, + 218,218,1,219,219,219,2,216,216,216,1,250,250,250,1,217,217,217,1,221, + 221,221,1,216,216,216,1,220,220,220,1,218,218,218,1,217,217,217,1,218, + 218,218,2,219,219,219,1,218,218,218,1,217,217,217,1,218,218,218,1,220, + 220,220,1,219,219,219,1,216,216,216,2,217,217,217,1,219,219,219,1,214, + 214,214,1,216,216,216,1,218,218,218,16,215,215,215,1,220,220,220,2,219, + 219,219,1,221,221,221,1,214,214,214,1,219,219,219,1,216,216,216,1,221, + 221,221,1,166,166,166,1,218,218,218,1,217,217,217,1,254,254,254,1,217, + 217,217,1,166,166,166,1,168,168,168,1,218,218,218,2,220,220,220,1,213, + 213,213,1,219,219,219,1,220,220,220,1,219,219,219,1,218,218,218,1,216, + 216,216,1,217,217,217,1,218,218,218,1,219,219,219,1,220,220,220,1,255, + 255,255,1,250,250,250,1,172,172,172,1,166,166,166,1,217,217,217,1,221, + 221,221,1,216,216,216,1,219,219,219,1,220,220,220,1,218,218,218,16,219, + 219,219,3,215,215,215,1,220,220,220,2,213,213,213,1,221,221,221,1,219, + 219,219,1,215,215,215,1,220,220,220,1,217,217,217,2,216,216,216,1,218, + 218,218,2,219,219,219,1,218,218,218,2,216,216,216,1,218,218,218,1,215, + 215,215,1,219,219,219,3,217,217,217,1,220,220,220,1,215,215,215,1,255, + 255,255,1,252,252,252,1,220,220,220,1,217,217,217,2,221,221,221,1,217, + 217,217,1,218,218,218,1,219,219,219,1,216,216,216,1,219,219,219,1,217, + 217,217,1,220,220,220,1,216,216,216,1,217,217,217,1,218,218,218,1,219, + 219,219,2,217,217,217,1,219,219,219,2,215,215,215,1,219,219,219,1,220, + 220,220,1,217,217,217,2,219,219,219,1,217,217,217,2,168,168,168,1,170, + 170,170,1,218,218,218,1,219,219,219,1,218,218,218,1,219,219,219,1,218, + 218,218,1,253,253,253,1,255,255,255,1,216,216,216,1,219,219,219,2,217, + 217,217,1,254,254,254,1,255,255,255,1,217,217,217,1,218,218,218,2,219, + 219,219,2,216,216,216,1,221,221,221,1,218,218,218,17,221,221,221,1,214, + 214,214,1,220,220,220,1,217,217,217,2,220,220,220,1,217,217,217,1,169, + 169,169,1,168,168,168,1,169,169,169,1,168,168,168,2,218,218,218,1,220, + 220,220,1,167,167,167,1,219,219,219,1,220,220,220,1,165,165,165,1,219, + 219,219,1,220,220,220,1,219,219,219,1,216,216,216,2,169,169,169,1,219, + 219,219,1,218,218,218,2,216,216,216,1,218,218,218,1,253,253,253,1,255, + 255,255,1,216,216,216,1,218,218,218,1,220,220,220,1,216,216,216,1,219, + 219,219,1,217,217,217,1,218,218,218,2,219,219,219,1,218,218,218,16,216, + 216,216,1,219,219,219,1,220,220,220,1,217,217,217,2,219,219,219,1,220, + 220,220,1,216,216,216,1,217,217,217,1,220,220,220,1,218,218,218,1,217, + 217,217,1,220,220,220,1,216,216,216,1,218,218,218,33,217,217,217,1,220, + 220,220,1,216,216,216,1,218,218,218,1,221,221,221,1,216,216,216,1,220, + 220,220,1,221,221,221,1,216,216,216,1,217,217,217,1,219,219,219,1,217, + 217,217,1,220,220,220,1,216,216,216,1,218,218,218,1,219,219,219,1,218, + 218,218,1,216,216,216,1,219,219,219,2,216,216,216,1,220,220,220,1,218, + 218,218,1,219,219,219,1,216,216,216,1,219,219,219,2,217,217,217,1,219, + 219,219,1,218,218,218,1,216,216,216,1,219,219,219,1,169,169,169,1,217, + 217,217,2,219,219,219,1,218,218,218,1,220,220,220,1,218,218,218,1,217, + 217,217,1,220,220,220,1,217,217,217,1,218,218,218,2,215,215,215,1,222, + 222,222,1,216,216,216,1,217,217,217,1,221,221,221,1,216,216,216,1,220, + 220,220,1,217,217,217,2,218,218,218,1,255,255,255,1,168,168,168,2,166, + 166,166,1,171,171,171,1,218,218,218,2,167,167,167,1,218,218,218,1,221, + 221,221,1,214,214,214,1,220,220,220,2,215,215,215,1,219,219,219,1,217, + 217,217,1,219,219,219,2,217,217,217,1,219,219,219,1,168,168,168,1,219, + 219,219,1,252,252,252,1,255,255,255,1,218,218,218,2,169,169,169,1,218, + 218,218,1,219,219,219,1,218,218,218,1,219,219,219,2,218,218,218,16,220, + 220,220,1,219,219,219,1,217,217,217,1,216,216,216,2,218,218,218,1,217, + 217,217,1,216,216,216,1,221,221,221,1,219,219,219,1,215,215,215,1,219, + 219,219,1,216,216,216,1,217,217,217,1,220,220,220,1,218,218,218,32,219, + 219,219,1,216,216,216,1,218,218,218,1,219,219,219,1,222,222,222,1,215, + 215,215,1,220,220,220,1,254,254,254,1,252,252,252,1,222,222,222,1,218, + 218,218,2,217,217,217,1,218,218,218,1,221,221,221,1,216,216,216,1,220, + 220,220,1,217,217,217,1,219,219,219,1,217,217,217,1,167,167,167,1,170, + 170,170,1,217,217,217,1,219,219,219,1,217,217,217,1,219,219,219,2,215, + 215,215,1,217,217,217,1,220,220,220,1,217,217,217,1,218,218,218,1,215, + 215,215,1,218,218,218,1,219,219,219,1,221,221,221,1,218,218,218,1,216, + 216,216,1,217,217,217,3,220,220,220,1,218,218,218,2,216,216,216,1,220, + 220,220,1,215,215,215,1,169,169,169,1,218,218,218,2,217,217,217,1,214, + 214,214,1,223,223,223,1,254,254,254,1,255,255,255,1,217,217,217,1,219, + 219,219,1,220,220,220,2,215,215,215,1,217,217,217,1,170,170,170,1,168, + 168,168,1,255,255,255,1,168,168,168,1,217,217,217,1,216,216,216,1,217, + 217,217,1,219,219,219,1,254,254,254,1,221,221,221,1,216,216,216,1,219, + 219,219,2,215,215,215,1,218,218,218,1,219,219,219,1,218,218,218,3,217, + 217,217,1,167,167,167,1,217,217,217,1,216,216,216,1,219,219,219,1,216, + 216,216,1,219,219,219,1,218,218,218,15,217,217,217,2,218,218,218,1,219, + 219,219,2,221,221,221,2,218,218,218,2,216,216,216,2,217,217,217,1,222, + 222,222,1,218,218,218,1,216,216,216,1,219,219,219,1,218,218,218,34,220, + 220,220,1,215,215,215,1,216,216,216,1,218,218,218,1,215,215,215,1,220, + 220,220,2,215,215,215,1,220,220,220,1,218,218,218,1,219,219,219,1,214, + 214,214,1,221,221,221,1,169,169,169,1,165,165,165,1,218,218,218,1,170, + 170,170,1,168,168,168,1,220,220,220,1,167,167,167,1,216,216,216,1,217, + 217,217,1,220,220,220,1,217,217,217,1,218,218,218,1,221,221,221,1,218, + 218,218,1,210,210,210,1,222,222,222,1,255,255,255,1,222,222,222,1,218, + 218,218,1,216,216,216,1,217,217,217,1,221,221,221,1,215,215,215,1,222, + 222,222,1,218,218,218,1,171,171,171,1,165,165,165,1,220,220,220,1,215, + 215,215,1,220,220,220,1,218,218,218,1,168,168,168,1,169,169,169,1,170, + 170,170,1,217,217,217,1,216,216,216,1,220,220,220,1,216,216,216,1,218, + 218,218,1,255,255,255,2,217,217,217,1,218,218,218,1,216,216,216,1,219, + 219,219,2,170,170,170,1,214,214,214,1,170,170,170,1,166,166,166,1,221, + 221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,220,220,220,1,216, + 216,216,1,218,218,218,2,255,255,255,1,219,219,219,1,217,217,217,1,216, + 216,216,1,219,219,219,1,220,220,220,1,254,254,254,1,220,220,220,1,170, + 170,170,1,217,217,217,1,222,222,222,1,219,219,219,2,217,217,217,1,218, + 218,218,15,220,220,220,1,216,216,216,1,218,218,218,2,217,217,217,1,218, + 218,218,1,217,217,217,2,218,218,218,2,221,221,221,1,220,220,220,1,214, + 214,214,1,218,218,218,1,219,219,219,1,217,217,217,1,218,218,218,32,217, + 217,217,1,216,216,216,1,220,220,220,1,218,218,218,1,217,217,217,1,222, + 222,222,1,220,220,220,1,216,216,216,1,217,217,217,1,220,220,220,1,216, + 216,216,2,221,221,221,1,217,217,217,1,218,218,218,1,216,216,216,1,171, + 171,171,1,219,219,219,1,252,252,252,1,222,222,222,1,215,215,215,1,218, + 218,218,1,219,219,219,1,220,220,220,1,216,216,216,1,221,221,221,1,220, + 220,220,1,215,215,215,1,219,219,219,1,222,222,222,1,216,216,216,1,215, + 215,215,1,216,216,216,2,222,222,222,1,217,217,217,1,216,216,216,1,169, + 169,169,1,167,167,167,1,168,168,168,1,165,165,165,1,169,169,169,1,167, + 167,167,1,219,219,219,1,218,218,218,1,255,255,255,1,165,165,165,1,168, + 168,168,1,164,164,164,1,168,168,168,1,171,171,171,1,221,221,221,1,215, + 215,215,1,255,255,255,2,254,254,254,1,253,253,253,1,255,255,255,1,220, + 220,220,1,214,214,214,1,221,221,221,1,167,167,167,1,220,220,220,1,165, + 165,165,1,170,170,170,1,218,218,218,1,215,215,215,1,217,217,217,1,218, + 218,218,1,165,165,165,1,219,219,219,1,220,220,220,1,167,167,167,1,168, + 168,168,1,218,218,218,1,219,219,219,2,221,221,221,1,215,215,215,1,254, + 254,254,1,214,214,214,1,219,219,219,1,218,218,218,1,215,215,215,1,217, + 217,217,1,219,219,219,1,221,221,221,1,217,217,217,1,218,218,218,14,219, + 219,219,1,217,217,217,1,220,220,220,1,217,217,217,1,215,215,215,1,218, + 218,218,2,220,220,220,1,219,219,219,1,216,216,216,1,215,215,215,1,219, + 219,219,1,216,216,216,1,221,221,221,1,217,217,217,1,222,222,222,1,218, + 218,218,33,220,220,220,1,218,218,218,1,216,216,216,1,219,219,219,1,216, + 216,216,1,212,212,212,1,218,218,218,1,216,216,216,1,219,219,219,2,217, + 217,217,1,218,218,218,1,254,254,254,1,255,255,255,1,221,221,221,1,253, + 253,253,1,255,255,255,1,217,217,217,1,252,252,252,1,219,219,219,1,221, + 221,221,1,217,217,217,1,216,216,216,1,219,219,219,1,216,216,216,1,218, + 218,218,1,219,219,219,1,217,217,217,2,218,218,218,1,222,222,222,1,219, + 219,219,1,218,218,218,1,220,220,220,1,215,215,215,1,220,220,220,1,168, + 168,168,1,217,217,217,2,167,167,167,1,169,169,169,1,170,170,170,1,216, + 216,216,1,254,254,254,1,255,255,255,1,219,219,219,1,167,167,167,1,171, + 171,171,1,170,170,170,1,216,216,216,1,165,165,165,1,223,223,223,1,217, + 217,217,1,254,254,254,1,255,255,255,2,253,253,253,1,218,218,218,1,221, + 221,221,1,166,166,166,1,215,215,215,1,225,225,225,1,168,168,168,2,166, + 166,166,1,169,169,169,1,171,171,171,1,169,169,169,3,217,217,217,1,170, + 170,170,1,166,166,166,1,168,168,168,1,220,220,220,1,218,218,218,1,216, + 216,216,1,218,218,218,1,255,255,255,1,220,220,220,1,217,217,217,1,218, + 218,218,1,221,221,221,1,215,215,215,1,217,217,217,1,216,216,216,1,221, + 221,221,1,218,218,218,14,216,216,216,1,218,218,218,1,220,220,220,1,217, + 217,217,1,219,219,219,1,223,223,223,1,216,216,216,2,217,217,217,1,165, + 165,165,1,173,173,173,1,217,217,217,1,218,218,218,1,219,219,219,1,217, + 217,217,1,214,214,214,1,218,218,218,32,217,217,217,1,218,218,218,1,217, + 217,217,2,220,220,220,1,222,222,222,1,220,220,220,1,217,217,217,1,220, + 220,220,1,218,218,218,2,217,217,217,1,216,216,216,1,218,218,218,1,255, + 255,255,1,215,215,215,1,220,220,220,1,255,255,255,1,218,218,218,1,220, + 220,220,1,218,218,218,2,216,216,216,1,221,221,221,1,220,220,220,1,215, + 215,215,1,218,218,218,1,219,219,219,1,216,216,216,1,217,217,217,3,219, + 219,219,1,216,216,216,1,219,219,219,1,255,255,255,1,254,254,254,1,253, + 253,253,1,218,218,218,1,219,219,219,1,221,221,221,1,166,166,166,1,167, + 167,167,1,220,220,220,1,254,254,254,1,252,252,252,1,219,219,219,1,218, + 218,218,1,217,217,217,1,164,164,164,1,170,170,170,1,169,169,169,1,216, + 216,216,1,219,219,219,1,217,217,217,1,219,219,219,1,255,255,255,2,216, + 216,216,1,217,217,217,1,218,218,218,1,221,221,221,1,213,213,213,1,167, + 167,167,1,168,168,168,1,169,169,169,1,164,164,164,1,219,219,219,1,167, + 167,167,1,165,165,165,1,253,253,253,1,255,255,255,1,167,167,167,1,171, + 171,171,1,217,217,217,1,215,215,215,1,219,219,219,1,169,169,169,1,167, + 167,167,1,215,215,215,1,218,218,218,1,222,222,222,1,215,215,215,2,222, + 222,222,1,219,219,219,1,218,218,218,1,216,216,216,1,218,218,218,16,219, + 219,219,1,216,216,216,1,219,219,219,1,218,218,218,1,212,212,212,1,221, + 221,221,1,220,220,220,1,215,215,215,1,220,220,220,1,217,217,217,2,221, + 221,221,1,218,218,218,34,221,221,221,1,216,216,216,1,218,218,218,1,221, + 221,221,1,213,213,213,2,219,219,219,2,215,215,215,1,167,167,167,1,222, + 222,222,1,217,217,217,1,220,220,220,1,217,217,217,2,219,219,219,1,215, + 215,215,1,218,218,218,2,216,216,216,2,220,220,220,1,216,216,216,1,218, + 218,218,1,219,219,219,1,218,218,218,1,219,219,219,1,217,217,217,1,218, + 218,218,1,219,219,219,1,217,217,217,1,219,219,219,1,218,218,218,1,219, + 219,219,1,216,216,216,1,255,255,255,1,250,250,250,1,255,255,255,1,253, + 253,253,1,255,255,255,2,215,215,215,1,218,218,218,1,217,217,217,1,255, + 255,255,2,220,220,220,1,216,216,216,1,170,170,170,1,219,219,219,1,168, + 168,168,1,165,165,165,1,169,169,169,1,218,218,218,1,216,216,216,1,218, + 218,218,1,252,252,252,1,255,255,255,2,220,220,220,1,218,218,218,1,214, + 214,214,1,221,221,221,2,216,216,216,1,220,220,220,2,216,216,216,1,219, + 219,219,1,220,220,220,1,255,255,255,1,253,253,253,1,217,217,217,1,215, + 215,215,1,220,220,220,1,218,218,218,1,219,219,219,1,216,216,216,1,222, + 222,222,1,219,219,219,1,218,218,218,1,217,217,217,1,220,220,220,1,218, + 218,218,2,219,219,219,1,217,217,217,1,219,219,219,1,218,218,218,14,219, + 219,219,1,217,217,217,1,219,219,219,1,218,218,218,2,215,215,215,1,222, + 222,222,1,254,254,254,1,255,255,255,1,219,219,219,1,217,217,217,1,218, + 218,218,1,220,220,220,1,216,216,216,1,219,219,219,2,218,218,218,32,216, + 216,216,1,219,219,219,1,218,218,218,2,219,219,219,3,217,217,217,1,218, + 218,218,1,219,219,219,1,217,217,217,1,216,216,216,1,218,218,218,1,220, + 220,220,1,217,217,217,1,219,219,219,1,220,220,220,1,218,218,218,1,217, + 217,217,1,220,220,220,1,218,218,218,2,217,217,217,1,219,219,219,1,215, + 215,215,1,220,220,220,1,219,219,219,1,215,215,215,1,219,219,219,2,214, + 214,214,1,218,218,218,1,216,216,216,1,220,220,220,1,218,218,218,1,216, + 216,216,1,255,255,255,2,254,254,254,1,255,255,255,1,254,254,254,1,220, + 220,220,1,219,219,219,1,168,168,168,1,219,219,219,1,215,215,215,1,219, + 219,219,2,215,215,215,1,221,221,221,1,168,168,168,1,169,169,169,1,168, + 168,168,1,217,217,217,1,220,220,220,1,219,219,219,1,255,255,255,1,254, + 254,254,1,255,255,255,2,218,218,218,3,216,216,216,1,218,218,218,3,217, + 217,217,1,169,169,169,1,217,217,217,1,255,255,255,2,218,218,218,1,171, + 171,171,1,217,217,217,1,253,253,253,1,255,255,255,1,219,219,219,1,216, + 216,216,1,168,168,168,2,218,218,218,1,220,220,220,1,219,219,219,1,217, + 217,217,1,218,218,218,1,219,219,219,1,218,218,218,63,219,219,219,1,217, + 217,217,1,219,219,219,1,218,218,218,2,215,215,215,1,222,222,222,1,254, + 254,254,1,218,218,218,8,219,219,219,1,214,214,214,1,220,220,220,1,217, + 217,217,1,218,218,218,1,215,215,215,1,221,221,221,1,218,218,218,1,168, + 168,168,2,216,216,216,1,218,218,218,1,217,217,217,1,221,221,221,1,217, + 217,217,1,166,166,166,1,220,220,220,1,217,217,217,1,219,219,219,1,215, + 215,215,1,221,221,221,1,217,217,217,1,215,215,215,1,220,220,220,2,218, + 218,218,2,166,166,166,1,219,219,219,1,218,218,218,2,219,219,219,1,218, + 218,218,2,219,219,219,1,170,170,170,1,165,165,165,1,218,218,218,4,253, + 253,253,1,255,255,255,3,218,218,218,1,219,219,219,1,217,217,217,1,219, + 219,219,1,218,218,218,2,167,167,167,1,218,218,218,1,216,216,216,1,255, + 255,255,1,218,218,218,1,167,167,167,1,169,169,169,1,170,170,170,1,166, + 166,166,1,168,168,168,1,170,170,170,1,165,165,165,1,169,169,169,1,167, + 167,167,1,169,169,169,1,217,217,217,1,216,216,216,1,217,217,217,1,219, + 219,219,2,217,217,217,1,218,218,218,64,219,219,219,1,216,216,216,1,219, + 219,219,1,218,218,218,1,212,212,212,1,221,221,221,1,218,218,218,8,216, + 216,216,1,221,221,221,1,217,217,217,1,220,220,220,1,217,217,217,1,221, + 221,221,1,216,216,216,1,217,217,217,1,169,169,169,2,219,219,219,1,216, + 216,216,1,167,167,167,1,166,166,166,2,172,172,172,1,214,214,214,1,219, + 219,219,1,221,221,221,1,216,216,216,1,215,215,215,1,222,222,222,1,219, + 219,219,1,217,217,217,2,254,254,254,1,255,255,255,1,254,254,254,1,217, + 217,217,1,218,218,218,1,217,217,217,1,216,216,216,1,255,255,255,1,253, + 253,253,1,217,217,217,1,167,167,167,1,169,169,169,1,173,173,173,1,164, + 164,164,1,217,217,217,1,219,219,219,1,217,217,217,1,255,255,255,3,218, + 218,218,1,214,214,214,1,219,219,219,1,218,218,218,3,165,165,165,1,224, + 224,224,1,216,216,216,1,215,215,215,1,219,219,219,1,169,169,169,1,166, + 166,166,1,170,170,170,1,168,168,168,1,166,166,166,1,219,219,219,2,170, + 170,170,1,171,171,171,1,161,161,161,1,169,169,169,1,223,223,223,1,217, + 217,217,2,219,219,219,1,218,218,218,63,216,216,216,1,218,218,218,1,220, + 220,220,1,217,217,217,1,219,219,219,1,223,223,223,1,216,216,216,2,218, + 218,218,8,219,219,219,1,216,216,216,1,218,218,218,1,216,216,216,1,215, + 215,215,1,219,219,219,1,255,255,255,2,217,217,217,1,219,219,219,1,216, + 216,216,1,219,219,219,1,168,168,168,1,219,219,219,1,166,166,166,2,221, + 221,221,1,219,219,219,1,218,218,218,1,221,221,221,1,220,220,220,1,214, + 214,214,1,220,220,220,1,217,217,217,1,166,166,166,1,255,255,255,1,254, + 254,254,1,255,255,255,1,220,220,220,1,218,218,218,1,254,254,254,1,255, + 255,255,1,254,254,254,1,255,255,255,2,165,165,165,1,168,168,168,1,169, + 169,169,2,221,221,221,1,218,218,218,2,219,219,219,1,254,254,254,1,253, + 253,253,1,255,255,255,1,221,221,221,1,217,217,217,1,215,215,215,1,220, + 220,220,1,168,168,168,1,170,170,170,1,165,165,165,1,219,219,219,1,218, + 218,218,1,216,216,216,1,218,218,218,1,217,217,217,3,220,220,220,1,217, + 217,217,1,221,221,221,1,214,214,214,1,165,165,165,1,222,222,222,1,167, + 167,167,1,218,218,218,1,217,217,217,1,215,215,215,1,221,221,221,1,216, + 216,216,1,218,218,218,62,219,219,219,1,217,217,217,1,220,220,220,1,217, + 217,217,1,215,215,215,1,218,218,218,2,220,220,220,1,218,218,218,8,216, + 216,216,1,219,219,219,1,218,218,218,1,222,222,222,1,219,219,219,1,218, + 218,218,1,255,255,255,2,217,217,217,2,255,255,255,2,218,218,218,1,220, + 220,220,1,168,168,168,2,214,214,214,1,220,220,220,1,216,216,216,1,215, + 215,215,1,217,217,217,1,221,221,221,1,217,217,217,1,220,220,220,1,168, + 168,168,1,220,220,220,1,254,254,254,2,217,217,217,2,219,219,219,1,218, + 218,218,1,255,255,255,1,252,252,252,2,222,222,222,1,220,220,220,1,167, + 167,167,1,168,168,168,1,215,215,215,1,216,216,216,1,220,220,220,1,216, + 216,216,1,255,255,255,3,211,211,211,1,222,222,222,1,221,221,221,1,215, + 215,215,1,169,169,169,1,165,165,165,1,168,168,168,1,220,220,220,1,217, + 217,217,1,220,220,220,1,218,218,218,2,223,223,223,1,217,217,217,1,215, + 215,215,1,218,218,218,1,217,217,217,1,221,221,221,1,217,217,217,1,220, + 220,220,1,214,214,214,1,170,170,170,1,220,220,220,1,219,219,219,2,217, + 217,217,1,218,218,218,62,220,220,220,1,216,216,216,1,218,218,218,2,217, + 217,217,1,218,218,218,1,217,217,217,2,218,218,218,8,222,222,222,1,215, + 215,215,1,216,216,216,1,219,219,219,1,215,215,215,1,220,220,220,1,215, + 215,215,1,170,170,170,1,169,169,169,1,168,168,168,1,254,254,254,1,255, + 255,255,2,216,216,216,1,168,168,168,1,169,169,169,1,219,219,219,1,217, + 217,217,1,222,222,222,1,220,220,220,2,217,217,217,1,255,255,255,1,217, + 217,217,1,220,220,220,1,216,216,216,1,255,255,255,2,169,169,169,1,172, + 172,172,1,166,166,166,1,217,217,217,2,255,255,255,1,219,219,219,1,218, + 218,218,1,213,213,213,1,171,171,171,1,169,169,169,1,220,220,220,1,221, + 221,221,1,219,219,219,1,217,217,217,1,168,168,168,1,219,219,219,1,255, + 255,255,1,220,220,220,1,216,216,216,2,217,217,217,1,224,224,224,1,167, + 167,167,1,219,219,219,1,217,217,217,1,220,220,220,1,214,214,214,1,217, + 217,217,1,218,218,218,1,215,215,215,1,218,218,218,1,221,221,221,2,214, + 214,214,1,171,171,171,1,255,255,255,1,218,218,218,1,220,220,220,1,164, + 164,164,1,217,217,217,1,219,219,219,1,216,216,216,1,218,218,218,63,217, + 217,217,2,218,218,218,1,219,219,219,2,221,221,221,2,218,218,218,9,217, + 217,217,2,222,222,222,1,216,216,216,1,217,217,217,1,220,220,220,1,217, + 217,217,1,219,219,219,1,169,169,169,1,166,166,166,1,255,255,255,2,251, + 251,251,1,219,219,219,1,170,170,170,1,164,164,164,1,219,219,219,1,217, + 217,217,1,216,216,216,1,219,219,219,1,215,215,215,1,169,169,169,1,220, + 220,220,1,218,218,218,1,216,216,216,1,222,222,222,1,254,254,254,1,255, + 255,255,1,163,163,163,1,168,168,168,1,169,169,169,1,218,218,218,2,255, + 255,255,1,217,217,217,2,220,220,220,1,168,168,168,1,166,166,166,1,168, + 168,168,1,165,165,165,1,215,215,215,1,220,220,220,1,218,218,218,1,252, + 252,252,1,253,253,253,1,220,220,220,1,217,217,217,1,219,219,219,2,213, + 213,213,1,219,219,219,2,217,217,217,1,218,218,218,1,220,220,220,1,219, + 219,219,1,218,218,218,1,219,219,219,1,218,218,218,1,217,217,217,1,218, + 218,218,1,220,220,220,1,165,165,165,1,216,216,216,1,255,255,255,1,218, + 218,218,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,218, + 218,218,64,220,220,220,1,219,219,219,1,217,217,217,1,216,216,216,2,218, + 218,218,1,217,217,217,1,218,218,218,8,217,217,217,1,219,219,219,1,215, + 215,215,1,219,219,219,1,222,222,222,1,254,254,254,1,253,253,253,1,217, + 217,217,1,166,166,166,1,172,172,172,1,164,164,164,1,218,218,218,1,255, + 255,255,1,253,253,253,1,171,171,171,1,217,217,217,1,215,215,215,1,218, + 218,218,1,217,217,217,1,223,223,223,1,217,217,217,1,216,216,216,1,219, + 219,219,1,218,218,218,3,255,255,255,1,214,214,214,1,220,220,220,1,170, + 170,170,1,164,164,164,1,170,170,170,1,219,219,219,1,213,213,213,1,221, + 221,221,1,218,218,218,1,219,219,219,1,170,170,170,1,167,167,167,1,168, + 168,168,1,169,169,169,1,255,255,255,2,169,169,169,1,214,214,214,1,223, + 223,223,1,215,215,215,1,220,220,220,2,217,217,217,1,218,218,218,1,221, + 221,221,1,218,218,218,1,217,217,217,1,219,219,219,1,216,216,216,1,218, + 218,218,2,219,219,219,1,217,217,217,1,216,216,216,1,220,220,220,1,166, + 166,166,1,171,171,171,1,169,169,169,1,253,253,253,1,219,219,219,1,216, + 216,216,1,167,167,167,1,220,220,220,1,218,218,218,1,216,216,216,1,218, + 218,218,64,216,216,216,1,219,219,219,1,220,220,220,1,217,217,217,2,219, + 219,219,1,218,218,218,8,219,219,219,2,218,218,218,1,219,219,219,1,216, + 216,216,1,218,218,218,1,255,255,255,1,217,217,217,1,220,220,220,1,166, + 166,166,1,169,169,169,1,255,255,255,3,214,214,214,1,170,170,170,1,220, + 220,220,1,218,218,218,1,217,217,217,1,251,251,251,1,255,255,255,1,217, + 217,217,1,219,219,219,1,218,218,218,3,253,253,253,1,255,255,255,1,254, + 254,254,1,166,166,166,1,172,172,172,1,167,167,167,1,217,217,217,1,222, + 222,222,1,216,216,216,1,217,217,217,1,219,219,219,1,217,217,217,1,218, + 218,218,1,219,219,219,1,216,216,216,1,219,219,219,1,217,217,217,1,218, + 218,218,1,219,219,219,1,216,216,216,1,219,219,219,1,217,217,217,1,216, + 216,216,1,219,219,219,1,217,217,217,1,215,215,215,1,219,219,219,1,216, + 216,216,1,220,220,220,1,218,218,218,1,217,217,217,1,220,220,220,1,215, + 215,215,1,221,221,221,1,218,218,218,1,217,217,217,1,170,170,170,1,168, + 168,168,2,219,219,219,1,216,216,216,1,221,221,221,1,215,215,215,1,171, + 171,171,1,215,215,215,1,220,220,220,1,218,218,218,70,220,220,220,1,215, + 215,215,1,218,218,218,1,221,221,221,1,218,218,218,2,219,219,219,1,217, + 217,217,2,220,220,220,1,217,217,217,1,221,221,221,1,218,218,218,1,254, + 254,254,1,217,217,217,1,255,255,255,2,220,220,220,1,168,168,168,1,166, + 166,166,1,255,255,255,1,219,219,219,1,167,167,167,1,169,169,169,1,170, + 170,170,1,168,168,168,1,219,219,219,1,216,216,216,1,218,218,218,1,217, + 217,217,1,220,220,220,1,217,217,217,1,216,216,216,1,255,255,255,4,218, + 218,218,1,217,217,217,1,220,220,220,1,219,219,219,1,220,220,220,1,218, + 218,218,1,215,215,215,1,218,218,218,1,217,217,217,1,255,255,255,1,218, + 218,218,1,217,217,217,1,255,255,255,1,254,254,254,1,217,217,217,1,216, + 216,216,1,218,218,218,1,219,219,219,1,218,218,218,14,220,220,220,1,255, + 255,255,1,216,216,216,1,221,221,221,1,217,217,217,1,255,255,255,1,218, + 218,218,1,219,219,219,1,218,218,218,1,167,167,167,1,219,219,219,1,218, + 218,218,70,217,217,217,1,223,223,223,1,216,216,216,1,218,218,218,1,216, + 216,216,1,166,166,166,1,170,170,170,1,219,219,219,1,220,220,220,1,216, + 216,216,1,217,217,217,3,255,255,255,1,169,169,169,1,253,253,253,1,254, + 254,254,1,170,170,170,1,167,167,167,1,173,173,173,1,218,218,218,1,253, + 253,253,1,221,221,221,1,166,166,166,1,165,165,165,1,168,168,168,1,215, + 215,215,1,217,217,217,1,221,221,221,1,217,217,217,1,214,214,214,1,219, + 219,219,1,217,217,217,1,224,224,224,1,217,217,217,1,254,254,254,1,255, + 255,255,1,218,218,218,2,216,216,216,1,219,219,219,1,214,214,214,1,255, + 255,255,3,219,219,219,1,215,215,215,1,216,216,216,1,219,219,219,1,215, + 215,215,1,218,218,218,1,222,222,222,1,218,218,218,1,219,219,219,2,215, + 215,215,1,218,218,218,8,219,219,219,1,220,220,220,1,217,217,217,1,219, + 219,219,1,218,218,218,1,255,255,255,2,222,222,222,1,217,217,217,1,218, + 218,218,1,219,219,219,1,255,255,255,1,219,219,219,1,217,217,217,1,219, + 219,219,1,216,216,216,1,218,218,218,70,216,216,216,1,218,218,218,3,219, + 219,219,1,218,218,218,1,169,169,169,1,167,167,167,1,166,166,166,1,221, + 221,221,1,219,219,219,1,218,218,218,1,255,255,255,1,218,218,218,1,165, + 165,165,1,255,255,255,2,216,216,216,1,167,167,167,1,168,168,168,1,216, + 216,216,1,255,255,255,1,253,253,253,1,255,255,255,1,169,169,169,1,168, + 168,168,1,221,221,221,1,223,223,223,1,218,218,218,1,215,215,215,1,219, + 219,219,1,218,218,218,1,219,219,219,1,215,215,215,1,218,218,218,2,254, + 254,254,2,218,218,218,1,220,220,220,1,219,219,219,1,217,217,217,1,255, + 255,255,1,254,254,254,1,216,216,216,1,221,221,221,1,220,220,220,1,219, + 219,219,1,217,217,217,1,255,255,255,1,220,220,220,1,215,215,215,1,218, + 218,218,1,214,214,214,1,219,219,219,2,218,218,218,8,217,217,217,1,219, + 219,219,1,218,218,218,1,217,217,217,1,216,216,216,1,217,217,217,1,220, + 220,220,1,215,215,215,1,217,217,217,1,220,220,220,1,217,217,217,1,216, + 216,216,1,254,254,254,1,218,218,218,1,221,221,221,1,218,218,218,71,220, + 220,220,1,216,216,216,1,217,217,217,1,254,254,254,1,255,255,255,1,220, + 220,220,1,216,216,216,1,217,217,217,1,220,220,220,1,216,216,216,1,217, + 217,217,1,218,218,218,1,254,254,254,1,220,220,220,1,218,218,218,1,254, + 254,254,1,252,252,252,1,218,218,218,1,170,170,170,1,165,165,165,1,170, + 170,170,1,255,255,255,1,254,254,254,2,167,167,167,1,220,220,220,1,214, + 214,214,1,215,215,215,1,217,217,217,1,219,219,219,1,169,169,169,1,218, + 218,218,1,217,217,217,1,219,219,219,2,255,255,255,1,253,253,253,1,221, + 221,221,1,218,218,218,1,216,216,216,1,166,166,166,1,170,170,170,1,216, + 216,216,1,218,218,218,1,219,219,219,1,215,215,215,1,217,217,217,2,255, + 255,255,2,217,217,217,1,220,220,220,1,218,218,218,1,219,219,219,1,220, + 220,220,1,216,216,216,1,218,218,218,9,220,220,220,1,218,218,218,1,221, + 221,221,1,218,218,218,1,221,221,221,1,215,215,215,1,221,221,221,1,219, + 219,219,2,216,216,216,1,221,221,221,2,218,218,218,2,215,215,215,1,218, + 218,218,70,217,217,217,1,218,218,218,1,220,220,220,1,169,169,169,1,255, + 255,255,1,252,252,252,1,255,255,255,1,220,220,220,1,217,217,217,2,218, + 218,218,1,222,222,222,1,254,254,254,1,166,166,166,1,172,172,172,1,255, + 255,255,2,219,219,219,1,218,218,218,1,169,169,169,1,167,167,167,2,255, + 255,255,1,217,217,217,1,166,166,166,1,171,171,171,1,218,218,218,1,220, + 220,220,1,221,221,221,1,217,217,217,1,218,218,218,1,217,217,217,1,218, + 218,218,1,255,255,255,1,218,218,218,1,216,216,216,1,255,255,255,1,215, + 215,215,1,214,214,214,1,223,223,223,1,168,168,168,1,169,169,169,1,216, + 216,216,1,169,169,169,1,218,218,218,1,217,217,217,1,218,218,218,1,219, + 219,219,1,254,254,254,1,255,255,255,1,221,221,221,1,216,216,216,2,219, + 219,219,2,217,217,217,1,218,218,218,8,221,221,221,1,215,215,215,1,168, + 168,168,1,215,215,215,1,169,169,169,1,220,220,220,1,215,215,215,1,218, + 218,218,1,216,216,216,1,220,220,220,1,219,219,219,1,217,217,217,1,213, + 213,213,1,217,217,217,1,219,219,219,2,218,218,218,70,217,217,217,1,221, + 221,221,1,216,216,216,1,167,167,167,1,218,218,218,1,220,220,220,1,214, + 214,214,1,217,217,217,1,221,221,221,1,219,219,219,1,217,217,217,1,216, + 216,216,1,217,217,217,1,169,169,169,1,163,163,163,1,255,255,255,1,252, + 252,252,1,219,219,219,1,214,214,214,1,170,170,170,1,168,168,168,1,165, + 165,165,1,254,254,254,1,173,173,173,1,169,169,169,2,220,220,220,1,215, + 215,215,1,252,252,252,1,219,219,219,1,218,218,218,2,219,219,219,1,218, + 218,218,1,216,216,216,1,255,255,255,2,218,218,218,1,223,223,223,1,215, + 215,215,1,168,168,168,1,166,166,166,1,219,219,219,1,170,170,170,1,218, + 218,218,1,219,219,219,2,216,216,216,1,254,254,254,1,255,255,255,1,217, + 217,217,1,219,219,219,1,222,222,222,1,215,215,215,1,219,219,219,1,217, + 217,217,1,218,218,218,8,217,217,217,1,169,169,169,2,216,216,216,1,168, + 168,168,1,216,216,216,1,219,219,219,1,220,220,220,1,219,219,219,1,215, + 215,215,1,220,220,220,1,214,214,214,1,220,220,220,1,222,222,222,1,216, + 216,216,1,219,219,219,1,218,218,218,6,29,99,111,110,116,97,105,110,101, + 114,46,102,97,99,101,46,102,97,100,101,95,112,111,115,46,99,111,117,110, + 116,2,2,29,99,111,110,116,97,105,110,101,114,46,102,97,99,101,46,102, + 97,100,101,95,112,111,115,46,105,116,101,109,115,1,2,0,2,1,0,31, + 99,111,110,116,97,105,110,101,114,46,102,97,99,101,46,102,97,100,101,95, + 99,111,108,111,114,46,99,111,117,110,116,2,2,31,99,111,110,116,97,105, + 110,101,114,46,102,97,99,101,46,102,97,100,101,95,99,111,108,111,114,46, + 105,116,101,109,115,1,4,218,226,237,0,4,191,174,181,0,0,25,99,111, + 110,116,97,105,110,101,114,46,102,97,99,101,46,108,111,99,97,108,112,114, + 111,112,115,11,13,102,97,108,95,102,97,111,112,97,99,105,116,121,0,18, + 99,111,110,116,97,105,110,101,114,46,116,97,98,111,114,100,101,114,2,1, + 16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2,0, + 2,30,3,126,2,3,0,1,0,13,111,112,116,105,111,110,115,119,105,110, + 100,111,119,11,14,119,111,95,103,114,111,117,112,108,101,97,100,101,114,0, + 8,109,97,105,110,109,101,110,117,7,9,109,97,105,110,109,101,110,117,49, + 7,111,112,116,105,111,110,115,11,7,102,111,95,109,97,105,110,19,102,111, + 95,116,101,114,109,105,110,97,116,101,111,110,99,108,111,115,101,15,102,111, + 95,97,117,116,111,114,101,97,100,115,116,97,116,16,102,111,95,97,117,116, + 111,119,114,105,116,101,115,116,97,116,10,102,111,95,115,97,118,101,112,111, + 115,12,102,111,95,115,97,118,101,115,116,97,116,101,0,8,115,116,97,116, + 102,105,108,101,7,10,116,115,116,97,116,102,105,108,101,49,7,99,97,112, + 116,105,111,110,6,15,77,83,69,105,100,101,32,43,32,77,83,69,103,117, + 105,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,8,116, + 109,115,101,102,111,114,109,0,11,116,115,116,114,105,110,103,101,100,105,116, + 12,116,115,116,114,105,110,103,101,100,105,116,49,5,99,111,108,111,114,4, + 3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,105,2,1,16, + 102,114,97,109,101,46,102,114,97,109,101,119,105,100,116,104,2,2,16,102, + 114,97,109,101,46,99,111,108,111,114,102,114,97,109,101,4,3,0,0,128, + 17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,3, + 0,0,128,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,16,67, + 97,112,116,105,111,110,32,38,116,111,112,108,101,102,116,16,102,114,97,109, + 101,46,102,111,110,116,46,99,111,108,111,114,3,99,115,15,102,114,97,109, + 101,46,102,111,110,116,46,110,97,109,101,6,11,115,116,102,95,100,101,102, + 97,117,108,116,17,102,114,97,109,101,46,102,111,110,116,46,120,115,99,97, + 108,101,2,1,21,102,114,97,109,101,46,102,111,110,116,46,108,111,99,97, + 108,112,114,111,112,115,11,9,102,108,112,95,99,111,108,111,114,10,102,108, + 112,95,120,115,99,97,108,101,0,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,105,14,102, + 114,108,95,102,114,97,109,101,119,105,100,116,104,14,102,114,108,95,99,111, + 108,111,114,102,114,97,109,101,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,17,2,0,2,0,0,8,98,111,117,110,100,115,95, + 120,2,107,8,98,111,117,110,100,115,95,121,2,39,9,98,111,117,110,100, + 115,95,99,121,2,43,8,115,116,97,116,102,105,108,101,7,10,116,115,116, + 97,116,102,105,108,101,49,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,0,11,116,115,116,114,105,110,103,101,100,105,116,12,116,115, + 116,114,105,110,103,101,100,105,116,50,5,99,111,108,111,114,4,3,0,0, + 128,12,102,114,97,109,101,46,108,101,118,101,108,105,2,1,16,102,114,97, + 109,101,46,102,114,97,109,101,119,105,100,116,104,2,2,16,102,114,97,109, + 101,46,99,111,108,111,114,102,114,97,109,101,4,3,0,0,128,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,12,67,97,112,116, + 105,111,110,32,38,116,111,112,16,102,114,97,109,101,46,99,97,112,116,105, + 111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46, + 102,111,110,116,46,99,111,108,111,114,4,121,145,0,0,16,102,114,97,109, + 101,46,102,111,110,116,46,115,116,121,108,101,11,7,102,115,95,98,111,108, + 100,0,15,102,114,97,109,101,46,102,111,110,116,46,110,97,109,101,6,11, + 115,116,102,95,100,101,102,97,117,108,116,17,102,114,97,109,101,46,102,111, + 110,116,46,120,115,99,97,108,101,2,1,21,102,114,97,109,101,46,102,111, + 110,116,46,108,111,99,97,108,112,114,111,112,115,11,9,102,108,112,95,99, + 111,108,111,114,9,102,108,112,95,115,116,121,108,101,10,102,108,112,95,120, + 115,99,97,108,101,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,114,108,95,108,101,118,101,108,105,14,102,114,108,95, + 102,114,97,109,101,119,105,100,116,104,14,102,114,108,95,99,111,108,111,114, + 102,114,97,109,101,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,17,2,0,2,0,0,19,102,97,99,101,46,102,97,100,101,95, + 112,111,115,46,99,111,117,110,116,2,2,19,102,97,99,101,46,102,97,100, + 101,95,112,111,115,46,105,116,101,109,115,1,2,0,2,1,0,21,102,97, + 99,101,46,102,97,100,101,95,99,111,108,111,114,46,99,111,117,110,116,2, + 2,21,102,97,99,101,46,102,97,100,101,95,99,111,108,111,114,46,105,116, + 101,109,115,1,4,217,224,188,0,4,255,161,161,0,0,17,102,97,99,101, + 46,102,97,100,101,95,111,112,97,99,105,116,121,4,95,95,95,0,15,102, + 97,99,101,46,108,111,99,97,108,112,114,111,112,115,11,13,102,97,108,95, + 102,97,111,112,97,99,105,116,121,0,8,116,97,98,111,114,100,101,114,2, + 1,8,98,111,117,110,100,115,95,120,3,6,1,8,98,111,117,110,100,115, + 95,121,2,39,9,98,111,117,110,100,115,95,99,121,2,43,8,115,116,97, + 116,102,105,108,101,7,10,116,115,116,97,116,102,105,108,101,49,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,11,116,115,116,114, + 105,110,103,101,100,105,116,12,116,115,116,114,105,110,103,101,100,105,116,51, + 5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101, + 118,101,108,111,2,3,12,102,114,97,109,101,46,108,101,118,101,108,105,2, + 255,16,102,114,97,109,101,46,102,114,97,109,101,119,105,100,116,104,2,2, + 16,102,114,97,109,101,46,99,111,108,111,114,102,114,97,109,101,4,3,0, + 0,128,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116, + 4,3,0,0,128,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 13,67,97,112,116,105,111,110,32,38,108,101,102,116,16,102,114,97,109,101, + 46,99,97,112,116,105,111,110,112,111,115,7,7,99,112,95,108,101,102,116, + 16,102,114,97,109,101,46,102,111,110,116,46,99,111,108,111,114,4,6,0, + 0,160,16,102,114,97,109,101,46,102,111,110,116,46,115,116,121,108,101,11, + 7,102,115,95,98,111,108,100,9,102,115,95,105,116,97,108,105,99,0,15, + 102,114,97,109,101,46,102,111,110,116,46,110,97,109,101,6,11,115,116,102, + 95,100,101,102,97,117,108,116,17,102,114,97,109,101,46,102,111,110,116,46, + 120,115,99,97,108,101,2,1,21,102,114,97,109,101,46,102,111,110,116,46, + 108,111,99,97,108,112,114,111,112,115,11,9,102,108,112,95,99,111,108,111, + 114,9,102,108,112,95,115,116,121,108,101,10,102,108,112,95,120,115,99,97, + 108,101,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,114,108,95,108,101,118,101,108,111,10,102,114,108,95,108,101,118, + 101,108,105,14,102,114,108,95,102,114,97,109,101,119,105,100,116,104,14,102, + 114,108,95,99,111,108,111,114,102,114,97,109,101,15,102,114,108,95,99,111, + 108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,81,2,0,2,0,2,0,0,19,102,97, + 99,101,46,102,97,100,101,95,112,111,115,46,99,111,117,110,116,2,2,19, + 102,97,99,101,46,102,97,100,101,95,112,111,115,46,105,116,101,109,115,1, + 2,0,2,1,0,21,102,97,99,101,46,102,97,100,101,95,99,111,108,111, + 114,46,99,111,117,110,116,2,2,21,102,97,99,101,46,102,97,100,101,95, + 99,111,108,111,114,46,105,116,101,109,115,1,4,6,0,0,160,4,5,0, + 0,160,0,19,102,97,99,101,46,102,97,100,101,95,100,105,114,101,99,116, + 105,111,110,7,5,103,100,95,117,112,17,102,97,99,101,46,102,97,100,101, + 95,111,112,97,99,105,116,121,4,127,127,127,0,15,102,97,99,101,46,108, + 111,99,97,108,112,114,111,112,115,11,15,102,97,108,95,102,97,100,105,114, + 101,99,116,105,111,110,13,102,97,108,95,102,97,111,112,97,99,105,116,121, + 0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117,110,100,115,95, + 120,2,23,8,98,111,117,110,100,115,95,121,2,112,9,98,111,117,110,100, + 115,95,99,120,3,181,0,9,98,111,117,110,100,115,95,99,121,2,32,8, + 115,116,97,116,102,105,108,101,7,10,116,115,116,97,116,102,105,108,101,49, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,11,116, + 115,116,114,105,110,103,101,100,105,116,12,116,115,116,114,105,110,103,101,100, + 105,116,52,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101, + 46,108,101,118,101,108,111,2,0,21,102,114,97,109,101,46,102,114,97,109, + 101,105,109,97,103,101,95,108,105,115,116,7,4,105,109,108,105,23,102,114, + 97,109,101,46,102,114,97,109,101,105,109,97,103,101,95,111,102,102,115,101, + 116,2,24,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110, + 116,4,3,0,0,128,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,15,67,97,112,116,105,111,110,32,38,98,111,116,116,111,109,16,102,114, + 97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,9,99,112,95,98, + 111,116,116,111,109,16,102,114,97,109,101,46,102,111,110,116,46,99,111,108, + 111,114,4,87,131,189,0,15,102,114,97,109,101,46,102,111,110,116,46,110, + 97,109,101,6,11,115,116,102,95,100,101,102,97,117,108,116,17,102,114,97, + 109,101,46,102,111,110,116,46,120,115,99,97,108,101,2,1,21,102,114,97, + 109,101,46,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,9, + 102,108,112,95,99,111,108,111,114,10,102,108,112,95,120,115,99,97,108,101, + 0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,10,102,114,108,95,108,101,118,101,108, + 105,14,102,114,108,95,102,114,97,109,101,119,105,100,116,104,18,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,108,105,115,116,20,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,15,102,114,108, + 95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,0,2,17,0, + 8,116,97,98,111,114,100,101,114,2,6,8,98,111,117,110,100,115,95,120, + 3,5,1,8,98,111,117,110,100,115,95,121,3,177,0,9,98,111,117,110, + 100,115,95,99,121,2,49,8,115,116,97,116,102,105,108,101,7,10,116,115, + 116,97,116,102,105,108,101,49,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,14,0,0,11,116,115,116,114,105,110,103,101,100,105,116,12,116, + 115,116,114,105,110,103,101,100,105,116,53,5,99,111,108,111,114,4,3,0, + 0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,3,12,102,114, + 97,109,101,46,108,101,118,101,108,105,2,255,16,102,114,97,109,101,46,102, + 114,97,109,101,119,105,100,116,104,2,2,16,102,114,97,109,101,46,99,111, + 108,111,114,102,114,97,109,101,4,3,0,0,128,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,20,67,97,112,116,105,111,110,32, + 98,111,116,116,111,38,109,114,105,103,104,116,16,102,114,97,109,101,46,99, + 97,112,116,105,111,110,112,111,115,7,14,99,112,95,98,111,116,116,111,109, + 114,105,103,104,116,16,102,114,97,109,101,46,102,111,110,116,46,99,111,108, + 111,114,4,101,114,135,0,26,102,114,97,109,101,46,102,111,110,116,46,99, + 111,108,111,114,98,97,99,107,103,114,111,117,110,100,4,240,192,204,0,15, + 102,114,97,109,101,46,102,111,110,116,46,110,97,109,101,6,11,115,116,102, + 95,100,101,102,97,117,108,116,17,102,114,97,109,101,46,102,111,110,116,46, + 120,115,99,97,108,101,2,1,21,102,114,97,109,101,46,102,111,110,116,46, + 108,111,99,97,108,112,114,111,112,115,11,9,102,108,112,95,99,111,108,111, + 114,19,102,108,112,95,99,111,108,111,114,98,97,99,107,103,114,111,117,110, + 100,10,102,108,112,95,120,115,99,97,108,101,0,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101, + 108,111,10,102,114,108,95,108,101,118,101,108,105,14,102,114,108,95,102,114, + 97,109,101,119,105,100,116,104,14,102,114,108,95,99,111,108,111,114,102,114, + 97,109,101,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,28, + 2,0,2,0,2,17,0,8,116,97,98,111,114,100,101,114,2,5,8,98, + 111,117,110,100,115,95,120,2,76,8,98,111,117,110,100,115,95,121,3,176, + 0,9,98,111,117,110,100,115,95,99,120,3,128,0,9,98,111,117,110,100, + 115,95,99,121,2,49,8,115,116,97,116,102,105,108,101,7,10,116,115,116, + 97,116,102,105,108,101,49,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,0,11,116,115,116,114,105,110,103,101,100,105,116,12,116,115, + 116,114,105,110,103,101,100,105,116,54,5,99,111,108,111,114,4,3,0,0, + 128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,21,102,114,97, + 109,101,46,102,114,97,109,101,105,109,97,103,101,95,108,105,115,116,7,4, + 105,109,108,105,23,102,114,97,109,101,46,102,114,97,109,101,105,109,97,103, + 101,95,111,102,102,115,101,116,2,8,17,102,114,97,109,101,46,99,111,108, + 111,114,99,108,105,101,110,116,4,3,0,0,128,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,14,67,97,112,116,105,111,110,32,38,114,105, + 103,104,116,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115, + 7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,102,111,110, + 116,46,99,111,108,111,114,4,184,134,173,0,16,102,114,97,109,101,46,102, + 111,110,116,46,115,116,121,108,101,11,9,102,115,95,105,116,97,108,105,99, + 0,15,102,114,97,109,101,46,102,111,110,116,46,110,97,109,101,6,11,115, + 116,102,95,100,101,102,97,117,108,116,17,102,114,97,109,101,46,102,111,110, + 116,46,120,115,99,97,108,101,2,1,21,102,114,97,109,101,46,102,111,110, + 116,46,108,111,99,97,108,112,114,111,112,115,11,9,102,108,112,95,99,111, + 108,111,114,9,102,108,112,95,115,116,121,108,101,10,102,108,112,95,120,115, + 99,97,108,101,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,10,102,114,108,95,108, + 101,118,101,108,105,14,102,114,108,95,102,114,97,109,101,119,105,100,116,104, + 18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,105,115,116,20, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2, + 84,2,0,0,19,102,97,99,101,46,102,97,100,101,95,112,111,115,46,99, + 111,117,110,116,2,2,19,102,97,99,101,46,102,97,100,101,95,112,111,115, + 46,105,116,101,109,115,1,2,0,2,1,0,21,102,97,99,101,46,102,97, + 100,101,95,99,111,108,111,114,46,99,111,117,110,116,2,2,21,102,97,99, + 101,46,102,97,100,101,95,99,111,108,111,114,46,105,116,101,109,115,1,4, + 6,0,0,160,4,5,0,0,160,0,19,102,97,99,101,46,102,97,100,101, + 95,100,105,114,101,99,116,105,111,110,7,5,103,100,95,117,112,17,102,97, + 99,101,46,102,97,100,101,95,111,112,97,99,105,116,121,4,127,127,127,0, + 15,102,97,99,101,46,108,111,99,97,108,112,114,111,112,115,11,15,102,97, + 108,95,102,97,100,105,114,101,99,116,105,111,110,13,102,97,108,95,102,97, + 111,112,97,99,105,116,121,0,8,116,97,98,111,114,100,101,114,2,4,8, + 98,111,117,110,100,115,95,120,3,5,1,8,98,111,117,110,100,115,95,121, + 2,113,9,98,111,117,110,100,115,95,99,120,3,184,0,9,98,111,117,110, + 100,115,95,99,121,2,32,8,115,116,97,116,102,105,108,101,7,10,116,115, + 116,97,116,102,105,108,101,49,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,14,0,0,11,116,115,116,114,105,110,103,101,100,105,116,12,116, + 115,116,114,105,110,103,101,100,105,116,55,5,99,111,108,111,114,4,3,0, + 0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,12,102,114, + 97,109,101,46,108,101,118,101,108,105,2,1,16,102,114,97,109,101,46,102, + 114,97,109,101,119,105,100,116,104,2,2,16,102,114,97,109,101,46,99,111, + 108,111,114,102,114,97,109,101,4,3,0,0,128,17,102,114,97,109,101,46, + 102,114,97,109,101,105,95,108,101,102,116,2,4,18,102,114,97,109,101,46, + 102,114,97,109,101,105,95,114,105,103,104,116,2,4,17,102,114,97,109,101, + 46,99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95, + 108,101,118,101,108,111,10,102,114,108,95,108,101,118,101,108,105,14,102,114, + 108,95,102,114,97,109,101,119,105,100,116,104,14,102,114,108,95,99,111,108, + 111,114,102,114,97,109,101,10,102,114,108,95,102,105,108,101,102,116,11,102, + 114,108,95,102,105,114,105,103,104,116,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,12,102,97,99,101,46,111,112,116,105,111,110,115, + 11,18,102,97,111,95,97,108,112,104,97,102,97,100,101,105,109,97,103,101, + 0,27,102,97,99,101,46,105,109,97,103,101,46,116,114,97,110,115,112,97, + 114,101,110,116,99,111,108,111,114,4,6,0,0,128,18,102,97,99,101,46, + 105,109,97,103,101,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,0,20,102,97,99,101,46,105,109,97,103,101,46,97,108, + 105,103,110,109,101,110,116,11,12,97,108,95,120,99,101,110,116,101,114,101, + 100,12,97,108,95,121,99,101,110,116,101,114,101,100,8,97,108,95,116,105, + 108,101,100,0,16,102,97,99,101,46,105,109,97,103,101,46,105,109,97,103, + 101,10,16,95,0,0,0,0,0,0,2,0,0,0,100,0,0,0,100,0, + 0,0,156,88,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,170,213, + 186,1,207,237,201,1,212,237,217,1,219,251,232,1,243,254,244,31,99,173, + 140,1,99,127,96,1,207,237,201,1,63,106,73,1,54,147,99,1,8,116, + 66,1,87,160,116,1,190,225,195,1,230,237,219,1,188,183,164,1,156,146, + 116,1,131,118,84,1,122,109,68,2,114,102,60,3,122,109,68,2,114,102, + 60,1,122,109,68,1,114,102,60,3,122,109,68,1,114,102,60,1,124,114, + 76,2,136,125,88,1,148,139,109,1,161,152,125,1,164,158,132,1,131,118, + 84,1,64,96,66,1,243,254,244,7,190,225,195,1,169,195,161,1,124,114, + 76,1,41,57,22,1,62,76,54,1,81,88,63,1,88,88,52,1,68,77, + 40,1,45,62,27,1,142,147,115,1,180,218,196,1,243,254,244,11,210,250, + 218,1,207,237,201,1,56,84,51,2,21,58,27,1,68,136,108,1,122,198, + 164,1,190,246,220,1,243,254,244,2,182,245,228,1,243,254,244,26,190,246, + 220,1,64,96,66,1,120,168,132,1,149,209,171,1,51,128,85,1,37,124, + 76,1,91,164,127,1,193,220,204,1,225,228,214,1,183,176,156,1,144,134, + 100,1,122,109,68,1,114,102,60,13,122,109,68,1,124,114,76,1,136,125, + 88,1,148,139,109,1,164,158,132,1,183,176,156,1,169,167,132,1,80,102, + 76,1,126,170,142,1,243,254,244,5,182,245,228,1,99,173,140,1,21,58, + 27,1,95,117,76,1,131,177,148,1,179,236,213,1,219,251,232,1,188,234, + 204,1,190,246,220,1,220,254,244,1,191,216,185,1,120,149,116,1,48,75, + 52,1,100,150,112,1,182,245,228,1,243,254,244,4,182,245,228,1,243,254, + 244,1,179,236,213,1,146,194,165,1,99,127,96,1,31,64,36,1,21,58, + 27,1,190,246,220,1,186,254,239,1,176,226,194,1,120,176,139,1,86,108, + 84,1,41,57,22,1,120,168,132,1,188,234,204,1,243,254,244,28,176,226, + 194,1,21,58,27,1,169,195,161,1,170,213,186,1,120,168,132,1,150,185, + 158,1,199,228,209,1,220,226,195,1,172,174,138,1,136,130,100,1,122,109, + 68,1,107,96,52,6,114,102,60,6,122,109,68,1,124,114,76,1,136,125, + 88,1,148,139,109,1,169,167,132,1,188,183,164,2,142,147,115,1,45,62, + 27,1,179,236,213,1,243,254,244,4,176,226,194,1,64,96,66,1,86,108, + 84,1,154,213,186,1,148,230,196,1,30,143,118,1,15,130,100,1,30,172, + 142,1,39,186,167,1,30,172,142,1,8,140,93,1,24,129,86,1,149,209, + 171,1,188,234,204,1,99,127,96,1,86,108,84,1,190,246,220,1,243,254, + 244,4,166,203,172,1,46,73,42,1,80,97,65,1,120,149,116,1,169,195, + 161,1,176,226,194,1,38,162,142,1,36,151,114,1,28,122,100,1,68,136, + 108,1,157,204,180,1,188,234,204,1,68,136,108,1,31,64,36,1,123,183, + 147,1,182,245,228,1,243,254,244,25,182,245,228,1,243,254,244,1,154,213, + 186,1,46,73,42,1,150,185,158,1,240,251,235,1,199,228,209,1,240,251, + 235,1,204,203,188,1,161,152,125,1,131,118,84,1,107,96,52,1,101,87, + 41,5,107,96,52,4,114,102,60,2,122,109,68,1,124,114,76,1,136,125, + 88,1,144,134,100,1,169,167,132,1,183,176,156,1,201,197,180,1,183,176, + 156,1,114,102,60,1,124,160,128,1,243,254,244,3,182,245,228,1,170,213, + 186,1,21,58,27,1,121,151,126,1,210,250,218,1,34,129,116,1,88,188, + 156,1,82,225,224,1,44,202,180,1,10,202,202,1,13,215,208,1,40,226, + 207,1,64,238,200,1,43,202,153,1,37,124,76,1,126,170,142,1,240,251, + 235,1,99,127,96,2,190,246,220,2,243,254,244,1,150,185,158,1,45,62, + 27,1,142,147,115,1,207,237,201,1,170,213,186,1,124,160,128,1,51,128, + 85,1,43,238,223,1,18,226,208,1,44,212,209,1,76,214,220,2,34,129, + 116,1,88,188,156,1,179,236,213,1,68,115,88,1,80,102,76,1,176,226, + 194,1,243,254,244,27,154,213,186,1,41,57,22,1,142,147,115,1,198,204, + 170,1,213,211,195,1,175,166,143,1,144,134,100,1,114,102,60,1,87,78, + 36,2,88,75,26,2,101,87,41,4,107,96,52,2,114,102,60,1,122,109, + 68,1,124,114,76,1,131,118,84,1,148,139,109,1,164,158,132,1,188,183, + 164,1,201,197,180,1,196,191,171,1,144,134,100,1,21,58,27,1,188,250, + 211,1,243,254,244,3,154,213,186,1,41,57,22,1,131,177,148,1,124,214, + 180,1,20,136,116,1,76,214,220,1,12,177,207,1,4,159,196,1,4,168, + 195,1,7,191,203,1,10,202,202,1,29,237,208,1,40,236,193,1,18,195, + 149,1,8,140,93,1,72,138,92,1,180,218,196,1,168,197,172,1,68,77, + 40,1,133,183,157,1,210,250,218,1,166,203,172,1,41,57,22,1,120,139, + 109,1,232,248,219,1,146,192,155,1,51,128,85,1,11,150,100,1,43,202, + 153,1,41,247,222,1,13,215,208,1,7,191,203,1,9,176,194,1,4,168, + 195,1,12,177,207,1,82,225,224,1,34,129,116,1,140,202,184,1,133,183, + 157,1,46,73,42,1,133,183,157,1,243,254,244,27,176,226,194,1,80,102, + 76,1,62,86,60,1,136,125,88,2,114,102,60,1,88,75,26,1,69,65, + 21,1,65,60,12,1,69,65,21,3,88,75,26,2,101,87,41,2,107,96, + 52,1,114,102,60,2,136,125,88,1,144,134,100,1,164,158,132,1,183,176, + 156,1,198,204,170,1,196,191,171,1,142,147,115,1,46,73,42,1,154,213, + 186,1,243,254,244,2,182,245,228,1,188,234,204,1,46,73,42,1,120,168, + 132,1,152,201,171,1,38,162,142,1,44,212,209,1,4,168,195,1,4,159, + 196,1,12,177,207,2,28,216,220,1,43,238,223,1,36,225,183,1,16,181, + 140,1,8,140,93,1,24,129,86,1,99,173,140,1,199,228,209,1,198,204, + 170,1,122,109,68,1,56,84,51,1,124,160,128,1,95,117,76,1,88,88, + 52,1,171,176,148,1,240,251,235,1,123,183,147,1,24,129,86,1,6,151, + 109,1,43,202,153,1,26,216,182,1,41,247,222,1,13,215,208,1,12,177, + 207,1,4,159,196,1,4,141,191,2,44,170,204,1,76,214,220,1,34,129, + 116,1,186,254,239,1,80,102,76,1,104,150,124,1,190,246,220,1,243,254, + 244,27,152,201,171,1,68,115,88,1,31,64,36,1,41,57,22,1,68,77, + 40,1,84,84,41,1,80,97,65,1,101,87,41,1,65,60,12,2,69,65, + 21,1,88,75,26,2,101,87,41,1,107,96,52,1,114,102,60,1,124,114, + 76,1,144,134,100,1,161,152,125,1,183,176,156,1,196,191,171,1,188,183, + 164,1,161,152,125,1,68,77,40,1,150,185,158,1,243,254,244,4,124,160, + 128,1,87,116,86,1,188,250,211,1,20,136,116,1,76,214,220,1,4,168, + 195,2,12,177,207,1,17,203,215,1,36,228,222,1,18,226,208,1,22,199, + 164,1,9,160,109,1,8,116,66,1,54,147,99,1,120,176,139,1,193,220, + 204,1,232,248,219,1,171,176,148,1,122,109,68,1,69,65,21,1,88,75, + 26,1,69,65,21,1,107,96,52,1,175,166,143,1,240,251,235,1,149,209, + 171,1,70,152,110,1,8,116,66,1,34,164,113,1,9,160,109,1,20,203, + 154,1,43,238,223,1,28,216,220,1,19,189,215,1,7,151,199,1,4,141, + 191,1,4,130,188,1,4,154,180,1,56,206,220,1,34,129,116,1,179,236, + 213,1,68,136,108,1,99,127,96,1,182,245,228,1,243,254,244,27,188,250, + 211,1,188,234,204,1,149,209,171,1,166,203,172,1,146,192,155,1,120,168, + 132,1,120,149,116,1,106,138,100,1,107,96,52,1,69,65,21,1,65,60, + 12,1,69,65,21,1,101,87,41,2,122,109,68,1,136,125,88,1,156,146, + 116,1,172,174,138,1,188,183,164,1,171,176,148,1,148,139,109,1,46,73, + 42,1,123,183,147,1,243,254,244,4,179,236,213,1,21,58,27,1,191,216, + 185,1,15,130,100,1,72,237,212,1,7,191,203,1,9,176,194,1,19,189, + 215,1,28,216,220,1,43,238,223,1,21,213,172,1,11,177,130,1,8,140, + 93,1,11,125,74,1,73,159,115,1,146,194,165,1,188,234,204,1,240,251, + 235,1,201,197,180,1,148,139,109,1,114,102,60,1,88,75,26,1,65,60, + 12,1,88,75,26,1,114,102,60,1,161,152,125,1,213,211,195,1,219,251, + 232,1,146,194,165,1,73,159,115,1,8,116,66,1,11,125,74,1,8,140, + 93,1,18,189,146,1,43,227,196,1,36,228,222,1,17,203,215,1,12,177, + 207,1,7,151,199,1,4,141,191,2,52,194,212,1,38,162,142,1,148,214, + 196,1,72,138,92,1,102,139,110,1,243,254,244,1,182,245,228,1,243,254, + 244,30,188,250,211,1,148,230,196,1,152,201,171,1,126,170,142,1,99,127, + 96,1,107,96,52,1,65,60,12,1,69,65,21,1,101,87,41,1,122,109, + 68,1,136,130,100,1,156,146,116,1,169,167,132,1,156,146,116,1,124,114, + 76,1,41,57,22,1,152,201,171,1,243,254,244,5,123,183,147,1,87,116, + 86,1,176,226,194,1,30,172,142,1,40,226,207,1,10,202,202,1,13,215, + 208,1,43,238,223,1,18,226,208,1,18,189,146,1,6,151,109,1,8,116, + 66,1,54,147,99,1,99,173,140,1,149,209,171,1,212,237,217,1,225,239, + 228,1,204,203,188,1,175,166,143,1,136,125,88,1,114,102,60,1,87,78, + 36,1,88,75,26,1,101,87,41,1,122,109,68,1,148,139,109,1,188,183, + 164,1,230,237,219,1,212,237,217,1,146,194,165,1,100,150,112,1,95,171, + 130,1,12,136,83,1,11,125,74,1,11,177,130,1,21,213,172,1,43,238, + 223,1,28,216,220,1,19,189,215,1,4,168,195,1,4,154,180,1,4,168, + 195,1,36,203,201,1,38,162,142,1,156,237,201,1,95,117,76,1,123,183, + 147,1,243,254,244,34,156,237,201,1,152,201,171,1,120,168,132,1,95,117, + 76,1,41,57,22,1,68,77,40,1,107,96,52,1,124,114,76,1,87,116, + 86,1,86,108,72,1,46,73,42,1,99,127,96,1,188,234,204,1,243,254, + 244,4,190,246,220,1,243,254,244,1,68,115,88,1,126,170,142,1,99,173, + 140,1,43,204,168,1,29,237,208,1,18,226,208,1,43,238,223,1,21,213, + 172,1,10,166,125,1,12,136,83,2,73,159,115,1,128,191,155,1,170,213, + 186,1,225,239,228,1,237,240,229,1,204,203,188,1,171,176,148,1,148,139, + 109,1,131,118,84,1,107,96,52,2,87,78,36,1,107,96,52,1,114,102, + 60,1,144,134,100,1,169,167,132,1,213,211,195,1,240,251,235,1,199,228, + 209,1,146,194,165,1,152,201,171,1,95,171,130,1,34,137,95,1,8,116, + 66,1,9,160,109,1,18,189,146,1,16,214,196,1,41,247,222,1,28,216, + 220,1,17,203,215,1,7,191,203,2,72,237,212,1,18,115,76,1,186,254, + 239,1,31,64,36,1,179,236,213,1,243,254,244,36,176,226,194,1,126,170, + 142,1,95,117,76,1,46,73,42,1,31,64,36,1,56,84,51,1,104,150, + 124,1,154,213,186,1,243,254,244,7,190,246,220,1,31,64,36,1,166,203, + 172,1,60,141,100,1,43,204,168,1,43,249,210,1,36,225,183,1,18,195, + 149,1,6,151,109,1,11,125,74,1,54,147,99,1,95,171,130,1,157,204, + 180,1,199,228,209,1,219,251,232,1,237,240,229,1,204,203,188,1,183,176, + 156,1,140,152,126,1,136,130,100,1,122,109,68,1,114,102,60,1,107,96, + 52,3,122,109,68,1,136,125,88,1,164,158,132,1,188,183,164,1,219,218, + 206,1,243,254,244,1,225,228,214,1,199,228,209,1,157,204,180,1,99,173, + 140,1,70,152,110,1,11,125,74,1,17,121,86,1,9,160,109,1,18,189, + 146,1,26,216,182,1,43,238,223,1,36,228,222,1,18,226,208,1,46,237, + 209,1,40,196,164,1,99,173,140,1,126,170,142,1,104,150,124,1,243,254, + 244,1,182,245,228,1,243,254,244,37,188,250,211,2,210,250,218,1,243,254, + 244,9,190,246,220,1,21,58,27,1,191,216,185,1,60,141,100,1,36,181, + 146,1,18,189,146,1,16,169,116,1,11,125,74,1,24,129,86,1,91,164, + 127,1,133,183,157,1,180,218,196,1,212,237,217,1,243,254,244,1,219,218, + 206,1,201,197,180,1,183,176,156,1,161,152,125,1,144,134,100,1,131,118, + 84,1,122,109,68,1,114,102,60,4,124,114,76,1,136,125,88,1,148,139, + 109,1,175,166,143,1,201,197,180,1,225,228,214,1,243,254,244,2,212,237, + 217,1,177,204,185,1,146,194,165,1,91,164,127,1,54,147,99,1,11,125, + 74,1,8,116,66,1,9,160,109,1,11,177,130,1,20,203,154,1,36,225, + 183,1,43,227,196,1,46,211,164,1,18,115,76,1,210,250,218,1,31,64, + 36,1,188,250,211,1,243,254,244,50,188,250,211,1,46,73,42,1,168,197, + 172,1,91,164,127,1,37,124,76,1,12,136,83,1,11,125,74,1,70,152, + 110,1,123,183,147,1,170,213,186,1,212,237,217,1,243,254,244,1,230,237, + 219,1,213,211,195,1,194,186,172,1,175,166,143,1,161,152,125,1,144,134, + 100,1,136,125,88,1,131,118,84,1,122,109,68,2,114,102,60,1,122,109, + 68,2,131,118,84,1,136,125,88,1,144,134,100,1,164,158,132,1,171,176, + 148,1,204,203,188,1,225,228,214,1,219,218,206,1,240,251,235,2,193,220, + 204,1,170,213,186,1,128,191,155,1,95,171,130,1,70,152,110,1,24,129, + 86,1,11,125,74,1,17,121,86,1,11,150,100,1,9,160,109,1,36,151, + 114,1,18,115,76,1,207,237,201,1,64,96,66,1,176,226,194,1,243,254, + 244,51,99,127,96,1,120,149,116,1,191,216,185,1,70,152,110,2,120,176, + 139,1,170,213,186,1,199,228,209,1,243,254,244,1,225,239,228,1,213,211, + 195,1,201,197,180,1,183,176,156,1,164,158,132,1,156,146,116,1,144,134, + 100,1,136,125,88,2,124,114,76,1,122,109,68,6,136,125,88,1,144,134, + 100,1,156,146,116,1,164,158,132,1,183,176,156,1,201,197,180,1,204,203, + 188,1,219,218,206,1,237,240,229,1,243,254,244,1,230,237,219,1,193,220, + 204,1,170,213,186,1,152,201,171,1,133,183,157,1,99,173,140,1,70,152, + 110,1,66,145,110,1,34,137,95,1,51,128,85,1,104,150,124,1,210,250, + 218,1,87,116,86,1,166,203,172,1,243,254,244,51,140,202,184,1,80,97, + 65,1,199,228,209,1,190,225,195,1,192,216,196,1,210,250,218,1,240,251, + 235,1,212,237,217,1,213,211,195,1,196,191,171,1,183,176,156,1,175,166, + 143,1,161,152,125,1,144,134,100,2,136,125,88,1,131,118,84,2,124,114, + 76,1,122,109,68,1,124,114,76,1,122,109,68,1,124,114,76,2,131,118, + 84,2,136,125,88,1,148,139,109,1,156,146,116,1,169,167,132,1,183,176, + 156,2,194,186,172,1,204,203,188,1,225,228,214,1,237,240,229,1,243,254, + 244,2,212,237,217,2,190,225,195,1,170,213,186,1,166,203,172,1,152,201, + 171,2,191,216,185,1,212,237,217,1,63,106,73,1,170,213,186,1,243,254, + 244,51,190,246,220,1,63,106,73,1,136,130,100,1,198,204,170,1,191,216, + 185,1,204,203,188,1,188,183,164,1,183,176,156,1,164,158,132,1,161,152, + 125,1,156,146,116,1,148,139,109,1,144,134,100,1,136,130,100,1,136,125, + 88,2,124,114,76,9,136,125,88,2,136,130,100,1,148,139,109,1,156,146, + 116,1,164,158,132,2,175,166,143,1,183,176,156,1,196,191,171,1,204,203, + 188,1,213,211,195,1,225,228,214,1,230,237,219,2,240,251,235,1,243,254, + 244,1,240,251,235,1,243,254,244,1,240,251,235,1,220,226,195,1,164,158, + 132,1,46,73,42,1,188,234,204,1,243,254,244,52,176,226,194,1,45,62, + 27,1,80,102,76,1,136,125,88,1,136,130,100,1,144,134,100,2,136,130, + 100,2,136,125,88,2,131,118,84,1,124,114,76,1,131,118,84,1,124,114, + 76,5,122,109,68,1,124,114,76,1,131,118,84,1,136,125,88,1,122,109, + 68,1,136,125,88,1,124,114,76,1,136,125,88,1,144,134,100,1,148,139, + 109,1,156,146,116,3,164,158,132,1,175,166,143,2,188,183,164,2,194,186, + 172,1,201,197,180,4,188,183,164,1,183,176,156,1,148,139,109,1,80,102, + 76,1,86,108,72,1,243,254,244,54,176,226,194,1,87,116,86,1,65,60, + 12,1,84,84,41,1,107,96,52,1,114,102,60,2,122,109,68,1,124,114, + 76,5,122,109,68,1,124,114,76,2,122,109,68,1,136,125,88,1,131,118, + 84,1,124,114,76,1,131,118,84,1,124,114,76,1,131,118,84,1,136,125, + 88,4,144,134,100,1,148,139,109,1,144,134,100,1,148,139,109,2,156,146, + 116,1,161,152,125,1,164,158,132,2,175,166,143,2,164,158,132,2,161,152, + 125,1,148,139,109,1,136,125,88,1,107,96,52,1,69,65,21,1,120,176, + 139,1,190,246,220,1,243,254,244,54,176,226,194,1,102,139,110,1,69,65, + 21,1,65,60,12,1,101,87,41,1,107,96,52,1,114,102,60,2,122,109, + 68,3,124,114,76,2,131,118,84,1,124,114,76,1,136,125,88,1,122,109, + 68,1,131,118,84,1,124,114,76,2,136,125,88,1,131,118,84,3,136,125, + 88,3,136,130,100,1,136,125,88,1,136,130,100,2,148,139,109,4,144,134, + 100,1,148,139,109,2,144,134,100,1,136,125,88,1,124,114,76,1,107,96, + 52,1,88,75,26,1,84,84,41,1,146,192,155,1,243,254,244,54,182,245, + 228,1,243,254,244,1,152,201,171,1,95,117,76,1,65,60,12,1,88,75, + 26,1,101,87,41,1,107,96,52,1,114,102,60,1,122,109,68,2,124,114, + 76,1,122,109,68,1,124,114,76,2,136,125,88,1,131,118,84,2,122,109, + 68,1,136,125,88,2,124,114,76,1,136,125,88,1,131,118,84,2,124,114, + 76,1,136,125,88,1,131,118,84,1,136,125,88,1,131,118,84,1,136,125, + 88,6,136,130,100,1,136,125,88,1,124,114,76,2,114,102,60,1,107,96, + 52,1,101,87,41,1,69,65,21,1,107,96,52,1,123,183,147,1,243,254, + 244,56,156,237,201,1,142,147,115,1,88,75,26,1,69,65,21,1,101,87, + 41,2,107,96,52,1,114,102,60,1,122,109,68,2,124,114,76,3,131,118, + 84,1,124,114,76,1,131,118,84,1,136,125,88,1,131,118,84,3,136,125, + 88,1,122,109,68,1,136,125,88,1,131,118,84,2,136,125,88,2,131,118, + 84,2,136,125,88,1,124,114,76,1,136,125,88,1,124,114,76,1,136,125, + 88,1,131,118,84,1,124,114,76,1,122,109,68,3,101,87,41,2,65,60, + 12,1,84,84,41,1,124,160,128,1,188,234,204,1,243,254,244,27,182,245, + 228,1,243,254,244,27,190,246,220,1,120,176,139,1,84,84,41,1,69,65, + 21,1,87,78,36,1,101,87,41,1,107,96,52,1,114,102,60,1,122,109, + 68,2,124,114,76,2,131,118,84,1,124,114,76,1,131,118,84,1,136,125, + 88,1,124,114,76,1,136,125,88,1,131,118,84,1,136,125,88,1,124,114, + 76,1,136,125,88,2,131,118,84,6,124,114,76,1,131,118,84,1,124,114, + 76,4,122,109,68,1,124,114,76,1,122,109,68,1,107,96,52,1,101,87, + 41,1,87,78,36,1,65,60,12,1,69,65,21,1,106,138,100,1,152,201, + 171,1,243,254,244,56,131,177,148,1,86,108,72,1,65,60,12,1,88,75, + 26,1,101,87,41,1,114,102,60,2,122,109,68,2,124,114,76,2,131,118, + 84,2,136,125,88,1,124,114,76,1,131,118,84,4,136,125,88,1,131,118, + 84,1,124,114,76,1,131,118,84,2,136,125,88,1,124,114,76,1,131,118, + 84,1,124,114,76,1,131,118,84,1,124,114,76,1,136,125,88,1,124,114, + 76,3,122,109,68,2,114,102,60,1,107,96,52,2,87,78,36,1,88,75, + 26,1,65,60,12,1,95,117,76,1,120,176,139,1,182,245,228,1,243,254, + 244,55,146,192,155,1,86,108,72,1,65,60,12,1,88,75,26,1,101,87, + 41,1,107,96,52,1,114,102,60,1,122,109,68,1,124,114,76,1,136,125, + 88,1,131,118,84,1,136,125,88,1,131,118,84,2,136,125,88,3,136,130, + 100,1,131,118,84,1,136,125,88,1,131,118,84,1,136,125,88,2,131,118, + 84,4,124,114,76,1,131,118,84,1,124,114,76,5,122,109,68,2,114,102, + 60,1,107,96,52,1,101,87,41,1,87,78,36,1,88,75,26,1,65,60, + 12,1,84,84,41,1,124,160,128,1,173,226,206,1,164,234,212,1,243,254, + 244,54,152,201,171,1,95,117,76,1,65,60,12,1,88,75,26,1,101,87, + 41,1,114,102,60,1,122,109,68,1,124,114,76,1,136,125,88,1,131,118, + 84,1,136,125,88,2,136,130,100,2,136,125,88,6,131,118,84,1,136,125, + 88,1,124,114,76,1,136,125,88,1,124,114,76,1,136,125,88,1,124,114, + 76,1,136,125,88,1,124,114,76,4,122,109,68,1,124,114,76,1,122,109, + 68,2,114,102,60,2,101,87,41,2,88,75,26,1,65,60,12,1,84,84, + 41,1,106,138,100,1,154,213,186,1,243,254,244,13,190,246,220,1,182,245, + 228,1,190,246,220,1,243,254,244,39,149,209,171,1,95,117,76,1,65,60, + 12,1,101,87,41,1,114,102,60,1,124,114,76,1,131,118,84,1,136,125, + 88,1,136,130,100,1,148,139,109,1,144,134,100,1,136,130,100,1,148,139, + 109,1,136,130,100,1,148,139,109,2,136,125,88,1,144,134,100,1,136,130, + 100,1,136,125,88,2,131,118,84,2,136,125,88,1,131,118,84,1,124,114, + 76,1,131,118,84,1,124,114,76,2,131,118,84,1,124,114,76,1,122,109, + 68,1,124,114,76,1,122,109,68,1,114,102,60,3,107,96,52,1,101,87, + 41,2,88,75,26,1,65,60,12,1,71,73,27,1,100,150,112,1,152,201, + 171,1,243,254,244,9,182,245,228,1,190,246,220,1,170,213,186,1,120,168, + 132,1,95,117,76,1,88,88,52,1,56,84,51,1,86,108,72,1,124,160, + 128,1,170,213,186,1,190,246,220,1,243,254,244,35,169,195,161,1,71,73, + 27,1,87,78,36,1,114,102,60,1,124,114,76,1,136,130,100,1,148,139, + 109,1,156,146,116,2,161,152,125,1,164,158,132,1,161,152,125,1,164,158, + 132,1,161,152,125,2,156,146,116,1,148,139,109,2,136,130,100,2,136,125, + 88,3,131,118,84,1,136,125,88,1,124,114,76,4,122,109,68,1,124,114, + 76,1,122,109,68,4,114,102,60,2,107,96,52,1,101,87,41,1,88,75, + 26,2,65,60,12,1,84,84,41,1,120,149,116,1,154,213,186,1,243,254, + 244,8,182,245,228,1,152,201,171,1,56,84,51,2,106,138,100,1,120,176, + 139,1,169,195,161,1,146,192,155,1,169,167,132,1,106,138,100,1,56,84, + 51,1,68,115,88,1,176,226,194,1,182,245,228,1,243,254,244,31,182,245, + 228,1,243,254,244,1,131,177,148,1,45,62,27,1,80,102,76,1,144,134, + 100,1,161,152,125,1,175,166,143,2,188,183,164,2,183,176,156,1,188,183, + 164,1,183,176,156,2,175,166,143,2,164,158,132,1,161,152,125,2,148,139, + 109,3,136,125,88,1,131,118,84,2,124,114,76,3,122,109,68,1,124,114, + 76,3,122,109,68,3,114,102,60,2,107,96,52,2,101,87,41,1,88,75, + 26,1,69,65,21,1,65,60,12,1,122,109,68,1,120,168,132,1,164,234, + 212,1,243,254,244,6,182,245,228,1,188,234,204,1,99,127,96,1,64,96, + 66,1,131,177,148,1,219,251,232,1,143,224,183,1,120,176,139,1,87,160, + 116,1,95,171,130,1,146,192,155,1,176,226,194,1,232,248,219,1,120,139, + 109,1,31,64,36,1,166,203,172,1,243,254,244,33,131,177,148,1,84,84, + 41,1,148,139,109,1,196,191,171,1,213,211,195,1,220,226,195,1,225,228, + 214,1,219,218,206,1,220,226,195,1,225,228,214,1,219,218,206,2,204,203, + 188,2,201,197,180,1,188,183,164,1,183,176,156,1,157,165,141,1,164,158, + 132,1,156,146,116,1,136,130,100,1,144,134,100,1,136,125,88,2,124,114, + 76,1,131,118,84,1,124,114,76,1,122,109,68,1,124,114,76,1,122,109, + 68,5,114,102,60,1,107,96,52,2,101,87,41,1,88,75,26,2,65,60, + 12,1,84,84,41,1,102,139,110,1,152,201,171,1,243,254,244,6,182,245, + 228,1,164,234,212,1,64,96,66,1,99,127,96,1,207,237,201,1,146,192, + 155,1,37,124,76,1,30,136,84,1,34,164,113,2,22,148,91,1,15,109, + 66,1,68,136,108,1,169,195,161,1,240,251,235,1,164,158,132,1,21,58, + 27,1,176,226,194,1,243,254,244,32,146,192,155,1,56,84,51,1,188,183, + 164,1,240,251,235,1,230,237,219,1,199,228,209,2,212,237,217,2,219,251, + 232,1,243,254,244,2,240,251,235,1,225,239,228,1,219,218,206,2,204,203, + 188,1,194,186,172,1,175,166,143,1,164,158,132,1,161,152,125,1,144,134, + 100,1,136,130,100,1,136,125,88,1,124,114,76,3,122,109,68,1,124,114, + 76,1,122,109,68,3,114,102,60,3,107,96,52,2,101,87,41,1,88,75, + 26,1,65,60,12,2,95,117,76,1,120,176,139,1,164,234,212,1,182,245, + 228,1,243,254,244,5,190,246,220,1,99,127,96,2,219,251,232,1,87,160, + 116,1,12,136,83,1,35,176,126,1,32,188,146,1,32,183,128,1,35,176, + 126,1,22,148,91,1,15,109,66,1,72,138,92,1,123,183,147,1,212,237, + 217,1,201,197,180,1,80,102,76,1,120,149,116,1,182,245,228,1,243,254, + 244,31,176,226,194,1,46,73,42,1,188,183,164,1,212,237,217,1,123,183, + 147,1,120,168,132,1,95,171,130,1,97,184,143,1,123,183,147,1,122,198, + 164,1,149,209,171,1,170,213,186,1,199,228,209,1,212,237,217,1,243,254, + 244,1,240,251,235,1,225,228,214,1,213,211,195,1,201,197,180,1,183,176, + 156,1,175,166,143,1,156,146,116,1,144,134,100,1,136,125,88,1,131,118, + 84,1,124,114,76,1,122,109,68,5,124,114,76,1,114,102,60,1,122,109, + 68,1,114,102,60,1,107,96,52,2,87,78,36,1,88,75,26,1,65,60, + 12,1,84,84,41,1,120,149,116,1,154,213,186,1,243,254,244,7,146,194, + 165,1,62,86,60,1,207,237,201,1,120,176,139,1,11,125,74,1,35,176, + 126,1,32,183,128,1,16,169,116,1,11,150,100,1,11,125,74,2,70,152, + 110,1,123,183,147,1,170,213,186,1,243,254,244,1,196,191,171,1,124,114, + 76,1,64,96,66,1,190,246,220,1,243,254,244,32,68,115,88,1,120,139, + 109,1,232,248,219,1,87,160,116,1,15,109,66,1,8,116,66,2,24,129, + 86,1,34,137,95,1,73,159,115,1,91,164,127,1,123,183,147,1,152,201, + 171,1,180,218,196,1,199,228,209,1,240,251,235,1,243,254,244,1,225,228, + 214,1,204,203,188,1,188,183,164,1,175,166,143,1,156,146,116,1,144,134, + 100,1,136,125,88,1,131,118,84,1,124,114,76,3,122,109,68,1,124,114, + 76,2,122,109,68,1,124,114,76,1,114,102,60,2,107,96,52,1,101,87, + 41,1,71,73,27,1,65,60,12,1,95,117,76,1,146,194,165,1,190,246, + 220,1,243,254,244,6,190,246,220,1,86,108,84,1,142,147,115,1,176,226, + 194,1,51,128,85,1,30,136,84,1,12,136,83,2,8,116,66,1,30,136, + 84,1,73,159,115,1,120,176,139,1,152,201,171,1,199,228,209,1,243,254, + 244,1,213,211,195,1,164,158,132,1,107,96,52,1,84,84,41,1,154,213, + 186,1,243,254,244,32,154,213,186,1,46,73,42,1,198,204,170,1,128,191, + 155,1,18,115,76,1,34,164,113,1,35,176,126,1,16,169,116,1,11,150, + 100,1,11,125,74,2,30,136,84,1,73,159,115,1,95,171,130,1,128,191, + 155,1,170,213,186,1,188,234,204,1,243,254,244,1,230,237,219,1,213,211, + 195,1,188,183,164,1,175,166,143,1,156,146,116,1,136,125,88,1,131,118, + 84,1,136,125,88,1,131,118,84,1,124,114,76,1,131,118,84,6,124,114, + 76,1,122,109,68,1,107,96,52,1,88,75,26,1,65,60,12,1,100,150, + 112,1,156,237,201,1,243,254,244,7,179,236,213,1,45,62,27,1,198,204, + 170,1,169,195,161,1,51,136,90,1,37,124,76,1,30,136,84,1,54,147, + 99,1,91,164,127,1,128,191,155,1,166,203,172,1,199,228,209,1,219,251, + 232,1,237,240,229,1,204,203,188,1,175,166,143,1,144,134,100,1,101,87, + 41,1,68,77,40,1,146,194,165,1,243,254,244,33,126,170,142,1,63,106, + 73,1,210,250,218,1,70,152,110,1,32,169,128,1,46,211,164,1,36,225, + 183,1,21,213,172,1,18,195,149,1,11,177,130,1,11,150,100,1,11,125, + 74,2,73,159,115,1,95,171,130,1,146,192,155,1,191,216,185,1,219,251, + 232,1,240,251,235,1,219,218,206,1,188,183,164,1,164,158,132,1,148,139, + 109,1,136,130,100,1,144,134,100,5,148,139,109,2,156,146,116,1,148,139, + 109,1,144,134,100,1,131,118,84,1,114,102,60,1,87,78,36,1,71,73, + 27,1,146,194,165,1,243,254,244,8,154,213,186,1,62,76,54,1,220,226, + 195,1,177,204,185,1,124,160,128,1,131,177,148,1,123,183,147,1,152,201, + 171,1,193,220,204,1,225,239,228,1,240,251,235,1,219,251,232,1,219,218, + 206,1,194,186,172,1,157,165,141,1,148,139,109,1,122,109,68,1,87,78, + 36,1,65,60,12,1,106,138,100,1,176,226,194,1,243,254,244,33,120,149, + 116,1,86,108,84,1,219,251,232,1,54,147,99,1,35,176,126,1,64,238, + 200,1,43,249,210,2,40,236,193,1,21,213,172,1,11,177,130,1,9,160, + 109,1,11,125,74,2,70,152,110,1,97,184,143,1,166,203,172,1,199,228, + 209,1,243,254,244,1,219,218,206,1,194,186,172,1,164,158,132,1,156,146, + 116,1,164,158,132,4,183,176,156,1,175,166,143,1,183,176,156,2,172,174, + 138,1,169,167,132,1,161,152,125,1,136,125,88,1,68,77,40,1,99,127, + 96,1,188,250,211,1,243,254,244,8,170,213,186,1,68,77,40,1,198,204, + 170,1,232,248,219,1,190,225,195,1,212,237,217,1,232,248,219,1,243,254, + 244,1,237,240,229,1,220,226,195,1,213,211,195,1,196,191,171,1,183,176, + 156,1,164,158,132,1,156,146,116,1,136,125,88,1,114,102,60,1,101,87, + 41,1,69,65,21,1,84,84,41,1,124,160,128,1,170,213,186,1,243,254, + 244,1,182,245,228,1,243,254,244,31,126,170,142,1,64,96,66,1,176,226, + 194,1,99,173,140,1,6,151,109,1,43,227,196,1,64,238,200,1,29,237, + 208,1,43,249,210,1,40,236,193,1,28,213,162,1,32,183,128,1,11,150, + 100,1,8,116,66,1,51,136,90,1,87,160,116,1,146,194,165,1,193,220, + 204,1,243,254,244,1,219,218,206,1,196,191,171,1,175,166,143,1,194,186, + 172,1,196,191,171,1,194,186,172,1,201,197,180,1,204,203,188,1,213,211, + 195,1,219,218,206,1,213,211,195,2,201,197,180,1,169,167,132,1,124,114, + 76,1,41,57,22,1,154,213,186,1,243,254,244,9,164,234,212,1,46,73, + 42,1,161,152,125,1,191,216,185,1,225,228,214,1,219,218,206,1,213,211, + 195,1,201,197,180,1,196,191,171,1,188,183,164,1,175,166,143,1,164,158, + 132,1,156,146,116,1,148,139,109,1,136,125,88,1,124,114,76,1,114,102, + 60,1,101,87,41,1,87,78,36,1,69,65,21,1,71,73,27,1,99,127, + 96,1,146,192,155,1,243,254,244,32,190,246,220,1,131,177,148,1,71,73, + 27,1,120,176,139,1,188,234,204,1,34,137,95,1,30,172,142,1,64,238, + 200,1,63,249,210,1,43,249,210,1,40,236,193,1,36,225,183,1,18,195, + 149,1,16,169,116,1,12,136,83,1,37,124,76,1,87,160,116,1,150,185, + 158,1,193,220,204,1,243,254,244,1,219,218,206,1,196,191,171,1,220,226, + 195,1,213,211,195,1,225,228,214,2,237,240,229,2,240,251,235,1,237,240, + 229,1,219,218,206,1,188,183,164,1,99,127,96,1,41,57,22,1,152,201, + 171,1,243,254,244,10,190,246,220,1,68,77,40,1,122,109,68,1,142,147, + 115,1,164,158,132,3,161,152,125,2,148,139,109,2,144,134,100,1,136,130, + 100,1,131,118,84,1,124,114,76,1,122,109,68,1,114,102,60,1,107,96, + 52,1,101,87,41,1,87,78,36,2,69,65,21,1,68,77,40,1,123,183, + 147,1,243,254,244,1,182,245,228,1,243,254,244,25,182,245,228,1,243,254, + 244,1,182,245,228,1,176,226,194,1,146,194,165,1,124,160,128,1,80,97, + 65,1,87,78,36,1,120,139,109,1,173,226,206,1,124,214,180,1,20,136, + 116,1,6,151,109,1,16,181,140,1,22,199,164,1,43,204,168,1,18,195, + 149,1,35,176,126,1,51,136,90,1,18,115,76,1,72,138,92,1,131,177, + 148,1,220,226,195,1,243,254,244,1,219,218,206,1,204,203,188,1,183,176, + 156,1,188,183,164,1,204,203,188,1,220,226,195,1,225,228,214,2,219,218, + 206,1,196,191,171,1,161,152,125,1,80,97,65,1,62,86,60,1,176,226, + 194,1,243,254,244,12,120,149,116,1,71,73,27,1,107,96,52,1,122,109, + 68,1,136,125,88,4,136,130,100,1,136,125,88,1,131,118,84,1,136,125, + 88,1,124,114,76,2,122,109,68,3,114,102,60,2,122,109,68,1,114,102, + 60,1,81,88,63,1,41,57,22,1,199,228,209,1,243,254,244,25,188,250, + 211,1,166,203,172,1,106,138,100,1,41,57,22,1,62,76,54,1,86,108, + 72,1,99,127,96,1,142,147,115,1,121,151,126,1,124,160,128,1,171,176, + 148,1,168,197,172,1,199,228,209,1,220,254,244,1,176,226,194,1,133,183, + 157,1,91,164,127,1,70,152,110,1,100,150,112,1,91,164,127,1,146,192, + 155,1,190,225,195,1,240,251,235,1,219,218,206,1,171,176,148,1,161,152, + 125,1,156,146,116,1,45,62,27,1,62,76,54,1,81,88,63,1,86,108, + 84,2,80,102,76,1,81,88,63,1,45,62,27,1,86,108,72,1,149,209, + 171,1,210,250,218,1,243,254,244,13,146,192,155,1,71,73,27,1,69,65, + 21,1,101,87,41,1,107,96,52,1,114,102,60,1,122,109,68,1,124,114, + 76,6,122,109,68,1,124,114,76,1,122,109,68,1,131,118,84,2,136,125, + 88,1,148,139,109,1,156,146,116,1,142,147,115,1,80,97,65,1,123,183, + 147,1,243,254,244,20,182,245,228,1,243,254,244,2,179,236,213,1,120,176, + 139,1,31,64,36,1,64,96,66,1,120,149,116,1,170,213,186,1,219,251, + 232,1,176,226,194,1,122,198,164,1,123,183,147,2,146,194,165,1,176,226, + 194,1,219,251,232,1,199,228,209,1,183,176,156,1,142,147,115,1,106,138, + 100,1,142,147,115,1,124,160,128,2,126,170,142,1,102,139,110,1,87,116, + 86,1,81,88,63,1,45,61,37,1,68,77,40,1,86,108,72,1,80,102, + 76,1,190,246,220,1,164,234,212,1,154,213,186,1,140,202,184,1,157,204, + 180,1,152,201,171,1,173,226,206,1,182,245,228,1,243,254,244,16,149,209, + 171,1,95,117,76,1,65,60,12,1,88,75,26,1,101,87,41,2,114,102, + 60,1,122,109,68,1,124,114,76,1,122,109,68,1,124,114,76,1,122,109, + 68,1,124,114,76,1,122,109,68,1,124,114,76,1,131,118,84,1,136,125, + 88,1,136,130,100,1,161,152,125,1,183,176,156,1,201,197,180,1,196,191, + 171,1,144,134,100,1,99,127,96,1,243,254,244,21,190,246,220,1,131,177, + 148,1,41,57,22,1,87,116,86,1,146,194,165,1,186,254,239,1,88,188, + 156,1,17,121,86,1,6,151,109,1,30,172,142,1,22,199,164,1,43,204, + 168,1,18,189,146,1,34,164,113,1,11,125,74,1,51,136,90,1,146,192, + 155,1,240,251,235,1,171,176,148,1,88,88,52,1,86,108,72,1,120,168, + 132,1,120,176,139,1,131,177,148,1,140,202,184,1,154,213,186,1,164,234, + 212,1,182,245,228,1,243,254,244,27,152,201,171,1,99,127,96,1,65,60, + 12,1,88,75,26,2,107,96,52,2,114,102,60,1,122,109,68,3,124,114, + 76,1,122,109,68,1,124,114,76,1,131,118,84,1,136,125,88,1,136,130, + 100,1,164,158,132,1,183,176,156,1,213,211,195,1,237,240,229,1,230,237, + 219,1,140,152,126,1,80,102,76,1,243,254,244,19,190,246,220,1,157,204, + 180,1,56,84,51,1,68,115,88,1,146,192,155,1,164,234,212,1,68,136, + 108,1,30,143,118,1,48,214,186,1,72,237,212,1,43,227,196,1,29,237, + 208,2,43,249,210,1,40,236,193,1,20,203,154,1,34,164,113,1,8,116, + 66,1,66,145,110,1,168,197,172,1,232,248,219,1,148,139,109,1,41,57, + 22,1,190,225,195,1,243,254,244,33,152,201,171,1,95,117,76,1,65,60, + 12,2,101,87,41,2,107,96,52,1,114,102,60,3,122,109,68,2,124,114, + 76,2,131,118,84,1,148,139,109,1,156,146,116,1,183,176,156,1,213,211, + 195,1,240,251,235,1,237,240,229,1,243,254,244,1,169,167,132,1,87,116, + 86,1,190,246,220,1,243,254,244,17,188,234,204,1,124,160,128,1,46,73, + 42,1,131,177,148,1,188,250,211,1,36,158,132,2,71,239,220,1,44,212, + 209,1,10,202,202,2,13,215,208,1,18,226,208,1,43,249,210,1,43,227, + 196,1,20,203,154,1,16,169,116,1,11,125,74,1,24,129,86,1,120,168, + 132,1,170,213,186,1,240,251,235,1,169,167,132,1,84,84,41,1,100,150, + 112,1,219,251,232,1,243,254,244,9,182,245,228,1,243,254,244,22,128,191, + 155,1,95,117,76,1,65,60,12,1,88,75,26,2,101,87,41,1,107,96, + 52,2,114,102,60,1,122,109,68,1,114,102,60,1,122,109,68,2,131,118, + 84,1,136,125,88,1,156,146,116,1,175,166,143,1,204,203,188,1,225,239, + 228,2,213,211,195,1,219,251,232,1,120,139,109,1,124,160,128,1,243,254, + 244,14,190,246,220,1,243,254,244,1,182,245,228,1,152,201,171,1,31,64, + 36,1,87,116,86,1,188,234,204,1,128,191,155,1,15,130,100,1,80,220, + 208,1,44,212,209,1,10,202,202,1,7,191,203,1,17,203,215,1,28,216, + 220,1,43,238,223,1,29,237,208,1,21,213,172,1,11,177,130,1,8,140, + 93,1,8,116,66,1,70,152,110,1,123,183,147,1,170,213,186,1,240,251, + 235,1,204,203,188,1,142,147,115,1,107,96,52,1,80,97,65,1,166,203, + 172,1,243,254,244,1,182,245,228,1,243,254,244,4,190,246,220,1,243,254, + 244,1,123,183,147,1,188,234,204,1,243,254,244,22,146,192,155,1,95,117, + 76,1,65,60,12,1,88,75,26,1,101,87,41,2,107,96,52,2,114,102, + 60,2,122,109,68,3,131,118,84,1,144,134,100,1,161,152,125,1,188,183, + 164,1,219,218,206,1,240,251,235,1,192,216,196,1,175,198,183,1,240,251, + 235,1,80,102,76,1,170,213,186,1,243,254,244,15,188,234,204,1,121,151, + 126,1,46,73,42,1,131,177,148,1,190,246,220,1,20,136,116,1,36,181, + 146,1,82,225,224,1,10,202,202,1,7,191,203,1,10,202,202,1,13,215, + 208,1,36,228,222,1,43,249,210,1,21,213,172,1,11,177,130,1,11,150, + 100,1,8,116,66,1,34,137,95,1,95,171,130,1,152,201,171,1,188,234, + 204,1,240,251,235,1,213,211,195,1,175,166,143,1,136,130,100,1,84,84, + 41,1,65,60,12,1,106,138,100,1,146,192,155,1,149,209,171,1,190,225, + 195,1,166,203,172,1,124,160,128,1,99,127,96,1,87,116,86,1,140,152, + 126,1,95,117,76,1,21,58,27,1,150,185,158,1,243,254,244,20,190,246, + 220,1,154,213,186,1,99,127,96,1,65,60,12,2,87,78,36,1,101,87, + 41,2,107,96,52,2,114,102,60,2,122,109,68,1,124,114,76,1,136,125, + 88,1,144,134,100,1,175,166,143,1,201,197,180,1,240,251,235,1,199,228, + 209,1,175,198,183,1,213,211,195,1,175,198,183,1,41,57,22,1,243,254, + 244,14,179,236,213,1,131,177,148,1,21,58,27,1,87,116,86,1,176,226, + 194,1,122,198,164,1,17,121,86,1,68,218,191,1,18,226,208,1,10,202, + 202,1,17,203,215,2,36,228,222,1,43,238,223,1,26,216,182,1,16,181, + 140,1,6,151,109,1,8,116,66,1,34,137,95,1,87,160,116,1,128,191, + 155,1,191,216,185,1,219,251,232,1,237,240,229,1,204,203,188,1,171,176, + 148,1,148,139,109,1,122,109,68,1,101,87,41,1,65,60,12,1,88,75, + 26,1,95,117,76,1,106,138,100,1,86,108,72,1,41,57,22,1,56,84, + 51,1,131,118,84,1,144,134,100,1,99,127,96,1,240,251,235,1,166,203, + 172,1,64,96,66,1,124,160,128,1,243,254,244,20,154,213,186,1,100,150, + 112,1,84,84,41,1,69,65,21,1,88,75,26,2,101,87,41,1,107,96, + 52,3,114,102,60,2,124,114,76,1,131,118,84,1,156,146,116,1,183,176, + 156,1,219,218,206,1,240,251,235,1,204,203,188,1,177,204,185,1,243,254, + 244,1,99,127,96,1,133,183,157,1,182,245,228,1,243,254,244,11,190,225, + 195,1,150,185,158,1,45,62,27,1,80,102,76,1,123,183,147,1,188,250, + 211,1,36,151,114,1,30,172,142,1,43,238,223,1,13,215,208,1,10,202, + 202,1,13,215,208,1,18,226,208,1,41,247,222,1,26,216,182,1,18,195, + 149,1,9,160,109,1,11,125,74,1,12,136,83,1,73,159,115,1,120,176, + 139,1,157,204,180,1,212,237,217,1,243,254,244,1,225,228,214,1,201,197, + 180,1,175,166,143,1,156,146,116,1,124,114,76,1,114,102,60,1,101,87, + 41,1,88,75,26,1,65,60,12,3,69,65,21,1,107,96,52,1,148,139, + 109,1,168,197,172,1,240,251,235,1,243,254,244,1,70,152,110,1,123,183, + 147,1,232,248,219,1,63,106,73,1,124,160,128,1,243,254,244,19,164,234, + 212,1,123,183,147,1,95,117,76,1,69,65,21,1,65,60,12,1,88,75, + 26,2,101,87,41,2,107,96,52,2,114,102,60,1,122,109,68,1,136,125, + 88,1,164,158,132,1,188,183,164,1,230,237,219,1,237,240,229,1,193,220, + 204,1,212,237,217,1,171,176,148,1,46,73,42,1,243,254,244,10,190,246, + 220,1,170,213,186,1,120,149,116,1,21,58,27,1,86,108,72,1,120,176, + 139,1,219,251,232,1,97,184,143,1,17,121,86,1,43,204,168,1,29,237, + 208,1,18,226,208,1,13,215,208,1,18,226,208,1,41,247,222,1,43,227, + 196,1,20,203,154,1,16,169,116,1,12,136,83,1,11,125,74,1,70,152, + 110,1,95,171,130,1,146,194,165,1,193,220,204,1,240,251,235,2,213,211, + 195,1,194,186,172,1,169,167,132,1,148,139,109,1,136,125,88,1,122,109, + 68,1,114,102,60,1,101,87,41,1,87,78,36,1,88,75,26,2,87,78, + 36,1,101,87,41,1,124,114,76,1,164,158,132,1,219,218,206,1,199,228, + 209,1,150,185,158,1,8,116,66,1,37,124,76,1,54,147,99,1,219,251, + 232,1,80,102,76,1,150,185,158,1,243,254,244,19,154,213,186,1,124,160, + 128,1,86,108,72,1,65,60,12,1,69,65,21,1,71,73,27,1,88,75, + 26,1,101,87,41,1,88,75,26,1,101,87,41,1,107,96,52,1,114,102, + 60,1,136,125,88,1,161,152,125,1,201,197,180,1,237,240,229,1,240,251, + 235,2,196,191,171,1,46,73,42,1,176,226,194,1,243,254,244,6,190,246, + 220,2,170,213,186,1,124,160,128,1,46,73,42,1,56,84,51,1,106,138, + 100,1,166,203,172,1,186,254,239,1,128,191,155,1,11,125,74,1,16,181, + 140,1,29,237,208,4,41,247,222,1,29,237,208,1,18,195,149,1,11,177, + 130,1,8,140,93,1,11,125,74,1,34,137,95,1,95,171,130,1,133,183, + 157,1,180,218,196,1,225,239,228,1,243,254,244,1,225,228,214,1,204,203, + 188,1,188,183,164,1,164,158,132,1,156,146,116,1,136,130,100,1,131,118, + 84,1,122,109,68,1,114,102,60,1,107,96,52,1,101,87,41,4,114,102, + 60,1,136,125,88,1,183,176,156,1,230,237,219,1,191,216,185,1,91,164, + 127,1,8,116,66,1,35,176,126,1,32,169,128,1,34,137,95,1,188,250, + 211,1,46,73,42,1,148,230,196,1,182,245,228,1,243,254,244,18,154,213, + 186,1,124,160,128,1,95,117,76,1,71,73,27,1,65,60,12,1,69,65, + 21,1,65,60,12,1,88,75,26,1,87,78,36,1,101,87,41,1,107,96, + 52,1,136,125,88,1,161,152,125,1,196,191,171,1,219,218,206,1,225,228, + 214,1,171,176,148,1,48,75,52,1,152,201,171,1,243,254,244,1,182,245, + 228,1,243,254,244,1,190,246,220,1,243,254,244,1,190,246,220,1,154,213, + 186,1,124,160,128,1,46,73,42,1,56,84,51,1,99,127,96,1,146,192, + 155,1,210,250,218,1,154,213,186,1,73,159,115,1,15,109,66,1,32,169, + 128,1,36,225,183,1,43,249,210,3,41,247,222,1,40,236,193,1,20,203, + 154,1,11,177,130,1,8,140,93,1,8,116,66,1,34,137,95,1,73,159, + 115,1,133,183,157,1,157,204,180,1,212,237,217,1,240,251,235,1,237,240, + 229,1,219,218,206,1,196,191,171,1,171,176,148,1,161,152,125,1,148,139, + 109,1,136,130,100,1,131,118,84,1,124,114,76,1,122,109,68,1,114,102, + 60,2,107,96,52,3,114,102,60,1,122,109,68,1,144,134,100,1,175,166, + 143,1,225,228,214,1,199,228,209,1,124,160,128,1,11,125,74,1,32,183, + 128,1,41,220,172,1,32,188,146,1,73,159,115,1,152,201,171,1,46,73, + 42,1,190,246,220,1,243,254,244,19,154,213,186,1,126,170,142,1,120,139, + 109,1,114,102,60,1,84,84,41,1,69,65,21,1,65,60,12,2,71,73, + 27,1,101,87,41,1,122,109,68,1,148,139,109,1,169,167,132,1,172,174, + 138,1,136,130,100,1,45,62,27,1,152,201,171,1,243,254,244,4,188,234, + 204,1,150,185,158,1,80,97,65,1,46,73,42,1,99,127,96,1,150,185, + 158,1,219,251,232,1,148,230,196,1,95,171,130,1,17,121,86,1,11,150, + 100,1,18,189,146,1,36,225,183,1,40,236,193,1,43,249,210,1,40,236, + 193,2,26,216,182,1,18,195,149,1,10,166,125,1,8,140,93,1,8,116, + 66,1,34,137,95,1,73,159,115,1,131,177,148,1,157,204,180,1,199,228, + 209,1,240,251,235,1,243,254,244,1,225,228,214,1,204,203,188,1,188,183, + 164,1,175,166,143,1,164,158,132,1,148,139,109,1,136,125,88,1,136,130, + 100,1,124,114,76,2,122,109,68,2,114,102,60,5,131,118,84,1,148,139, + 109,1,175,166,143,1,225,228,214,1,212,237,217,1,126,170,142,1,12,136, + 83,1,9,160,109,1,36,225,183,1,63,249,210,1,36,181,146,1,122,198, + 164,1,102,139,110,1,120,176,139,1,243,254,244,20,156,237,201,1,152,201, + 171,1,123,183,147,1,124,160,128,1,106,138,100,1,95,117,76,1,80,97, + 65,1,69,65,21,2,84,84,41,1,80,97,65,2,46,73,42,1,99,127, + 96,1,188,234,204,1,219,251,232,1,243,254,244,1,182,245,228,1,164,234, + 212,1,123,183,147,1,31,64,36,1,86,108,72,1,169,167,132,1,188,250, + 211,1,176,226,194,1,95,171,130,1,37,124,76,1,8,140,93,1,35,176, + 126,1,46,211,164,1,41,220,172,1,36,225,183,3,21,213,172,1,18,195, + 149,1,11,177,130,1,6,151,109,1,12,136,83,1,8,116,66,1,34,137, + 95,1,73,159,115,1,123,183,147,1,152,201,171,1,173,226,206,1,237,240, + 229,1,243,254,244,1,225,228,214,1,213,211,195,1,194,186,172,1,171,176, + 148,1,164,158,132,1,156,146,116,1,144,134,100,1,136,130,100,1,136,125, + 88,1,124,114,76,3,122,109,68,6,124,114,76,1,131,118,84,1,148,139, + 109,1,175,166,143,1,213,211,195,1,219,251,232,1,168,197,172,1,34,164, + 113,1,11,125,74,1,22,199,164,1,43,249,210,1,63,249,210,1,8,140, + 93,1,219,251,232,1,48,75,52,1,173,226,206,1,243,254,244,21,182,245, + 228,1,148,230,196,1,154,213,186,1,152,201,171,1,123,183,147,1,124,160, + 128,1,106,138,100,1,95,117,76,1,99,127,96,1,126,170,142,1,176,226, + 194,1,243,254,244,3,190,246,220,1,169,195,161,1,68,77,40,1,80,102, + 76,1,150,185,158,1,219,251,232,1,122,198,164,1,51,136,90,1,8,140, + 93,1,35,176,126,1,20,203,154,1,46,211,164,1,28,213,162,1,41,220, + 172,1,28,213,162,1,20,203,154,1,32,183,128,1,16,169,116,1,9,160, + 109,1,12,136,83,1,8,116,66,1,12,136,83,1,54,147,99,1,91,164, + 127,1,123,183,147,1,157,204,180,1,193,220,204,1,225,239,228,1,243,254, + 244,1,237,240,229,1,213,211,195,1,201,197,180,1,188,183,164,1,175,166, + 143,1,161,152,125,1,148,139,109,1,144,134,100,2,131,118,84,3,124,114, + 76,3,122,109,68,1,124,114,76,1,122,109,68,1,124,114,76,1,122,109, + 68,1,124,114,76,1,136,125,88,1,148,139,109,1,164,158,132,1,204,203, + 188,1,243,254,244,1,177,204,185,1,97,184,143,1,8,116,66,1,11,177, + 130,1,40,236,193,1,29,237,208,1,43,227,196,1,66,145,110,1,128,191, + 155,1,68,115,88,1,243,254,244,34,179,236,213,1,106,138,100,1,56,84, + 51,1,120,168,132,1,240,251,235,1,128,191,155,1,37,124,76,1,11,150, + 100,1,32,183,128,1,43,202,153,1,28,213,162,1,20,203,154,1,18,195, + 149,1,16,181,140,1,11,177,130,1,11,150,100,1,8,140,93,1,11,125, + 74,1,8,116,66,1,12,136,83,1,54,147,99,1,73,159,115,1,120,176, + 139,1,146,194,165,1,157,204,180,1,199,228,209,1,225,239,228,1,243,254, + 244,1,237,240,229,1,219,218,206,1,201,197,180,1,194,186,172,1,175,166, + 143,1,164,158,132,1,156,146,116,1,148,139,109,1,144,134,100,1,136,125, + 88,2,124,114,76,3,131,118,84,1,124,114,76,5,122,109,68,1,124,114, + 76,1,131,118,84,1,136,125,88,1,148,139,109,1,164,158,132,1,196,191, + 171,1,225,239,228,1,225,228,214,1,149,209,171,1,36,151,114,1,8,140, + 93,1,28,213,162,1,43,249,210,1,29,237,208,1,36,181,146,1,148,230, + 196,1,63,106,73,1,154,213,186,1,182,245,228,1,243,254,244,31,146,194, + 165,1,45,62,27,1,99,127,96,1,190,225,195,1,149,209,171,1,51,136, + 90,1,12,136,83,1,35,176,126,1,43,202,153,1,18,195,149,1,32,183, + 128,2,11,150,100,1,22,148,91,1,11,125,74,1,8,116,66,1,12,136, + 83,1,60,141,100,1,73,159,115,1,91,164,127,1,123,183,147,1,146,194, + 165,1,157,204,180,1,193,220,204,1,199,228,209,1,243,254,244,1,240,251, + 235,1,225,239,228,1,213,211,195,1,196,191,171,1,188,183,164,1,175,166, + 143,1,164,158,132,1,156,146,116,1,148,139,109,1,144,134,100,1,136,125, + 88,1,136,130,100,1,136,125,88,1,124,114,76,1,136,125,88,2,122,109, + 68,1,131,118,84,1,124,114,76,1,131,118,84,1,136,125,88,1,122,109, + 68,1,131,118,84,1,136,125,88,1,124,114,76,1,136,125,88,2,148,139, + 109,1,164,158,132,1,188,183,164,1,219,218,206,1,237,240,229,1,176,226, + 194,1,99,173,140,1,8,116,66,1,11,177,130,1,29,237,208,2,43,249, + 210,1,17,121,86,1,154,213,186,1,56,84,51,1,243,254,244,30,190,246, + 220,1,126,170,142,1,71,73,27,1,124,160,128,1,219,251,232,1,120,168, + 132,1,15,109,66,1,34,164,113,1,32,183,128,2,9,160,109,1,11,150, + 100,1,11,125,74,1,8,116,66,1,24,129,86,1,70,152,110,1,73,159, + 115,1,95,171,130,1,123,183,147,1,146,194,165,1,157,204,180,1,180,218, + 196,1,199,228,209,1,212,237,217,1,243,254,244,2,225,239,228,1,219,218, + 206,1,213,211,195,1,196,191,171,1,188,183,164,1,183,176,156,1,164,158, + 132,1,161,152,125,1,156,146,116,1,148,139,109,1,144,134,100,1,136,130, + 100,1,136,125,88,1,131,118,84,3,136,125,88,1,124,114,76,1,136,125, + 88,2,131,118,84,2,122,109,68,1,136,125,88,1,124,114,76,3,131,118, + 84,1,136,125,88,1,136,130,100,1,156,146,116,1,183,176,156,1,213,211, + 195,1,243,254,244,1,212,237,217,1,146,194,165,1,54,147,99,1,12,136, + 83,1,18,195,149,1,41,247,222,1,29,237,208,1,32,188,146,1,143,224, + 183,1,95,117,76,1,152,201,171,1,243,254,244,28,188,234,204,1,99,127, + 96,1,64,96,66,1,146,192,155,1,207,237,201,1,70,152,110,1,11,125, + 74,1,34,164,113,2,11,150,100,1,12,136,83,1,8,116,66,1,34,137, + 95,1,70,152,110,1,95,171,130,1,133,183,157,1,152,201,171,1,157,204, + 180,1,193,220,204,1,199,228,209,1,219,251,232,1,243,254,244,2,225,239, + 228,1,237,240,229,1,219,218,206,1,213,211,195,1,204,203,188,1,194,186, + 172,1,188,183,164,1,175,166,143,1,164,158,132,1,156,146,116,2,148,139, + 109,2,136,125,88,5,131,118,84,2,124,114,76,1,136,125,88,1,131,118, + 84,2,136,125,88,1,124,114,76,1,136,125,88,1,131,118,84,1,136,125, + 88,1,131,118,84,1,136,125,88,3,144,134,100,1,156,146,116,1,175,166, + 143,1,196,191,171,1,237,240,229,1,243,254,244,1,180,218,196,1,97,184, + 143,1,11,125,74,1,16,169,116,1,36,225,183,1,43,249,210,1,40,236, + 193,1,18,115,76,1,176,226,194,1,31,64,36,1,190,246,220,1,243,254, + 244,25,190,246,220,1,166,203,172,1,31,64,36,1,95,117,76,1,207,237, + 201,1,149,209,171,1,51,128,85,1,30,136,84,1,22,148,91,2,11,125, + 74,2,54,147,99,1,95,171,130,1,128,191,155,1,154,213,186,1,180,218, + 196,1,212,237,217,1,240,251,235,1,243,254,244,1,240,251,235,1,225,239, + 228,1,219,218,206,2,213,211,195,1,201,197,180,1,194,186,172,2,183,176, + 156,1,175,166,143,2,164,158,132,1,156,146,116,3,144,134,100,2,136,125, + 88,2,131,118,84,1,136,125,88,1,131,118,84,2,136,125,88,1,131,118, + 84,2,136,125,88,1,124,114,76,1,131,118,84,2,136,125,88,1,124,114, + 76,1,131,118,84,4,136,125,88,2,148,139,109,2,169,167,132,1,188,183, + 164,1,219,218,206,1,225,239,228,2,152,201,171,1,70,152,110,1,8,116, + 66,1,11,177,130,1,40,236,193,1,64,238,200,1,35,176,126,1,124,214, + 180,1,87,116,86,1,146,194,165,1,182,245,228,1,243,254,244,23,190,246, + 220,1,124,160,128,1,46,73,42,1,124,160,128,1,240,251,235,1,120,176, + 139,1,8,116,66,1,30,136,84,1,22,148,91,1,8,116,66,1,11,125, + 74,1,54,147,99,1,131,177,148,1,149,209,171,1,193,220,204,1,212,237, + 217,1,243,254,244,1,240,251,235,1,225,228,214,1,219,218,206,1,204,203, + 188,2,196,191,171,2,183,176,156,3,157,165,141,1,175,166,143,1,164,158, + 132,1,161,152,125,2,156,146,116,1,148,139,109,2,136,130,100,1,144,134, + 100,1,136,130,100,1,136,125,88,1,136,130,100,1,136,125,88,4,131,118, + 84,3,136,125,88,3,131,118,84,2,136,125,88,2,131,118,84,1,136,125, + 88,1,131,118,84,1,136,125,88,3,148,139,109,1,161,152,125,1,175,166, + 143,1,204,203,188,1,225,228,214,1,243,254,244,1,193,220,204,1,131,177, + 148,1,54,147,99,1,12,136,83,1,18,195,149,1,40,236,193,1,46,211, + 164,1,34,137,95,1,176,226,194,1,21,58,27,1,190,246,220,1,243,254, + 244,20,190,246,220,1,243,254,244,1,173,226,206,1,64,96,66,1,63,106, + 73,1,166,203,172,1,190,225,195,1,70,152,110,1,37,124,76,1,22,148, + 91,2,8,116,66,1,54,147,99,1,120,168,132,1,149,209,171,1,188,234, + 204,1,240,251,235,1,237,240,229,1,225,228,214,1,213,211,195,1,196,191, + 171,1,188,183,164,2,175,166,143,2,164,158,132,2,161,152,125,1,164,158, + 132,1,161,152,125,2,156,146,116,3,148,139,109,4,136,130,100,1,136,125, + 88,1,136,130,100,1,136,125,88,2,131,118,84,2,136,125,88,2,131,118, + 84,2,136,125,88,2,131,118,84,2,136,125,88,3,131,118,84,1,136,125, + 88,3,131,118,84,1,136,125,88,1,136,130,100,1,144,134,100,1,156,146, + 116,1,175,166,143,1,188,183,164,1,201,197,180,1,225,228,214,1,219,251, + 232,1,170,213,186,1,99,173,140,1,24,129,86,1,8,140,93,1,18,195, + 149,1,46,211,164,1,22,148,91,1,149,209,171,1,106,138,100,1,100,150, + 112,1,243,254,244,21,146,194,165,1,41,57,22,1,106,138,100,1,210,250, + 218,1,128,191,155,1,8,116,66,1,11,150,100,1,16,169,116,1,12,136, + 83,1,8,116,66,1,54,147,99,1,123,183,147,1,190,225,195,1,219,251, + 232,1,237,240,229,1,219,218,206,1,201,197,180,1,188,183,164,1,175,166, + 143,1,169,167,132,1,161,152,125,1,156,146,116,3,148,139,109,1,156,146, + 116,1,148,139,109,4,156,146,116,2,148,139,109,4,136,130,100,1,148,139, + 109,1,144,134,100,1,136,130,100,1,136,125,88,1,136,130,100,1,131,118, + 84,1,136,125,88,2,131,118,84,1,136,130,100,1,136,125,88,5,131,118, + 84,1,136,125,88,1,131,118,84,1,136,125,88,2,131,118,84,2,136,130, + 100,1,136,125,88,2,148,139,109,2,161,152,125,1,183,176,156,1,188,183, + 164,1,204,203,188,1,240,251,235,1,212,237,217,1,154,213,186,1,91,164, + 127,1,24,129,86,1,22,148,91,1,32,183,128,1,34,164,113,1,54,147, + 99,1,210,250,218,1,64,96,66,1,150,185,158,1,243,254,244,18,182,245, + 228,1,131,177,148,1,46,73,42,1,126,170,142,1,190,246,220,1,66,145, + 110,1,11,150,100,1,32,183,128,2,22,148,91,1,11,125,74,1,73,159, + 115,1,146,192,155,1,179,236,213,1,240,251,235,1,219,218,206,1,194,186, + 172,1,175,166,143,1,169,167,132,1,156,146,116,2,144,134,100,1,148,139, + 109,1,144,134,100,6,148,139,109,1,144,134,100,1,156,146,116,1,148,139, + 109,2,156,146,116,1,148,139,109,1,156,146,116,2,144,134,100,1,148,139, + 109,1,144,134,100,1,136,130,100,1,136,125,88,1,136,130,100,1,136,125, + 88,1,131,118,84,1,136,125,88,2,131,118,84,1,136,125,88,1,131,118, + 84,1,136,125,88,1,131,118,84,1,136,125,88,5,131,118,84,1,136,130, + 100,1,131,118,84,1,136,125,88,2,136,130,100,1,144,134,100,1,148,139, + 109,1,156,146,116,1,164,158,132,1,175,166,143,1,194,186,172,1,219,218, + 206,1,237,240,229,1,225,239,228,1,149,209,171,1,91,164,127,1,37,124, + 76,1,12,136,83,1,22,148,91,1,15,109,66,1,146,192,155,1,198,204, + 170,1,46,73,42,1,124,160,128,1,188,234,204,1,182,245,228,1,243,254, + 244,14,190,246,220,1,124,160,128,1,62,86,60,1,166,203,172,1,149,209, + 171,1,11,125,74,1,11,177,130,1,43,202,153,1,18,195,149,1,9,160, + 109,1,8,116,66,1,54,147,99,1,122,198,164,1,212,237,217,1,225,239, + 228,1,213,211,195,1,183,176,156,1,175,166,143,1,156,146,116,1,148,139, + 109,1,144,134,100,1,136,130,100,1,136,125,88,4,136,130,100,1,136,125, + 88,1,136,130,100,1,144,134,100,2,148,139,109,1,156,146,116,3,161,152, + 125,3,156,146,116,1,161,152,125,1,156,146,116,1,144,134,100,1,148,139, + 109,1,144,134,100,1,136,125,88,2,136,130,100,1,131,118,84,1,136,125, + 88,2,131,118,84,1,136,125,88,4,131,118,84,1,136,125,88,2,131,118, + 84,1,136,125,88,4,136,130,100,1,136,125,88,2,144,134,100,1,148,139, + 109,1,161,152,125,1,164,158,132,1,175,166,143,1,196,191,171,1,219,218, + 206,1,225,239,228,2,157,204,180,1,95,171,130,1,54,147,99,1,8,116, + 66,1,18,115,76,1,60,141,100,1,190,225,195,1,198,204,170,1,86,108, + 84,1,41,57,22,1,120,149,116,1,157,204,180,1,173,226,206,1,190,246, + 220,1,243,254,244,1,190,246,220,1,243,254,244,1,182,245,228,1,243,254, + 244,1,182,245,228,1,243,254,244,1,182,245,228,1,243,254,244,1,182,245, + 228,1,164,234,212,1,99,127,96,1,64,96,66,1,176,226,194,1,97,184, + 143,1,15,130,100,1,28,213,162,1,36,225,183,1,41,220,172,1,11,177, + 130,1,11,125,74,1,54,147,99,1,128,191,155,1,212,237,217,1,237,240, + 229,1,204,203,188,1,183,176,156,1,156,146,116,1,148,139,109,1,144,134, + 100,1,136,125,88,1,131,118,84,2,136,125,88,1,124,114,76,1,131,118, + 84,1,136,125,88,2,136,130,100,1,144,134,100,2,148,139,109,2,156,146, + 116,1,164,158,132,2,175,166,143,4,164,158,132,2,156,146,116,1,148,139, + 109,2,144,134,100,1,136,130,100,1,136,125,88,1,131,118,84,1,136,125, + 88,5,131,118,84,1,136,125,88,3,131,118,84,1,136,125,88,1,136,130, + 100,1,136,125,88,1,136,130,100,1,136,125,88,3,144,134,100,2,148,139, + 109,2,156,146,116,1,161,152,125,1,175,166,143,1,194,186,172,1,219,218, + 206,1,230,237,219,1,219,251,232,1,180,218,196,1,133,183,157,1,73,159, + 115,1,60,141,100,1,54,147,99,1,120,168,132,1,180,218,196,1,212,237, + 217,1,150,185,158,1,120,139,109,1,80,102,76,1,46,73,42,1,41,57, + 22,1,80,102,76,1,124,160,128,1,146,192,155,1,176,226,194,1,188,250, + 211,1,243,254,244,3,188,250,211,1,170,213,186,1,64,96,66,1,87,116, + 86,1,210,250,218,1,95,171,130,1,10,166,125,1,43,227,196,1,43,249, + 210,1,40,236,193,1,18,195,149,1,8,140,93,1,12,136,83,1,120,176, + 139,1,173,226,206,1,240,251,235,1,204,203,188,1,183,176,156,1,161,152, + 125,1,148,139,109,1,136,125,88,1,131,118,84,3,124,114,76,1,131,118, + 84,1,136,125,88,2,131,118,84,1,136,125,88,2,144,134,100,1,148,139, + 109,1,156,146,116,1,161,152,125,1,164,158,132,1,175,166,143,1,183,176, + 156,1,188,183,164,1,194,186,172,2,188,183,164,2,183,176,156,1,175,166, + 143,1,164,158,132,1,156,146,116,1,148,139,109,2,136,125,88,3,131,118, + 84,2,124,114,76,1,131,118,84,2,136,130,100,1,131,118,84,1,136,125, + 88,5,131,118,84,1,136,130,100,1,131,118,84,1,136,130,100,2,136,125, + 88,1,144,134,100,1,148,139,109,2,156,146,116,1,164,158,132,1,175,166, + 143,1,188,183,164,1,204,203,188,1,225,228,214,1,243,254,244,1,225,239, + 228,1,170,213,186,1,133,183,157,1,131,177,148,1,120,168,132,1,126,170, + 142,1,168,197,172,1,192,216,196,1,230,237,219,1,240,251,235,1,220,226, + 195,1,198,204,170,1,172,174,138,1,106,138,100,1,68,115,88,1,68,77, + 40,1,21,58,27,1,63,106,73,1,104,150,124,1,124,160,128,1,87,116, + 86,1,46,73,42,1,100,150,112,1,219,251,232,1,30,143,118,1,36,181, + 146,1,41,247,222,1,43,249,210,2,21,213,172,1,9,160,109,1,11,125, + 74,1,95,171,130,1,154,213,186,1,243,254,244,1,219,218,206,1,183,176, + 156,1,161,152,125,1,148,139,109,1,136,125,88,2,124,114,76,1,131,118, + 84,1,124,114,76,1,131,118,84,2,124,114,76,1,136,125,88,2,136,130, + 100,1,144,134,100,1,136,130,100,1,156,146,116,1,161,152,125,1,175,166, + 143,1,188,183,164,1,194,186,172,1,204,203,188,1,213,211,195,1,219,218, + 206,3,213,211,195,1,204,203,188,1,194,186,172,1,183,176,156,1,175,166, + 143,1,161,152,125,1,148,139,109,2,136,130,100,1,136,125,88,2,131,118, + 84,2,136,125,88,1,131,118,84,3,136,125,88,3,136,130,100,1,131,118, + 84,1,136,130,100,1,136,125,88,1,136,130,100,1,136,125,88,2,144,134, + 100,4,148,139,109,2,161,152,125,1,164,158,132,1,183,176,156,1,194,186, + 172,1,213,211,195,1,212,237,217,1,243,254,244,1,225,239,228,1,180,218, + 196,1,175,198,183,1,146,194,165,1,131,177,148,1,133,183,157,1,131,177, + 148,1,120,176,139,1,123,183,147,2,149,209,171,1,191,216,185,1,210,250, + 218,2,191,216,185,1,120,168,132,1,120,149,116,1,102,139,110,1,120,168, + 132,1,176,226,194,1,143,224,183,1,17,121,86,1,44,202,180,1,29,237, + 208,1,18,226,208,1,29,237,208,1,36,225,183,1,11,177,130,1,8,116, + 66,1,70,152,110,1,146,194,165,1,225,239,228,1,225,228,214,1,201,197, + 180,1,175,166,143,1,156,146,116,1,136,130,100,1,136,125,88,1,124,114, + 76,2,131,118,84,1,124,114,76,1,131,118,84,2,136,125,88,1,131,118, + 84,1,136,125,88,1,136,130,100,1,144,134,100,1,156,146,116,1,161,152, + 125,1,175,166,143,1,188,183,164,1,201,197,180,1,213,211,195,1,225,228, + 214,1,237,240,229,1,243,254,244,3,240,251,235,1,225,239,228,1,219,218, + 206,1,204,203,188,1,194,186,172,1,175,166,143,1,161,152,125,1,156,146, + 116,1,144,134,100,1,136,130,100,1,136,125,88,2,131,118,84,4,136,125, + 88,1,136,130,100,1,131,118,84,2,136,125,88,2,136,130,100,1,136,125, + 88,3,136,130,100,1,136,125,88,2,144,134,100,1,136,130,100,2,148,139, + 109,2,156,146,116,1,164,158,132,2,183,176,156,1,194,186,172,1,204,203, + 188,1,225,228,214,1,240,251,235,2,212,237,217,1,180,218,196,1,146,194, + 165,1,131,177,148,1,120,168,132,1,100,150,112,1,72,138,92,2,51,128, + 85,2,72,138,92,1,87,160,116,1,120,176,139,1,128,191,155,1,122,198, + 164,1,123,183,147,1,15,130,100,1,36,158,132,1,64,238,200,1,18,226, + 208,1,13,215,208,1,29,237,208,2,18,195,149,1,12,136,83,1,34,137, + 95,1,123,183,147,1,193,220,204,1,243,254,244,1,213,211,195,1,183,176, + 156,1,161,152,125,1,144,134,100,1,136,125,88,1,131,118,84,1,124,114, + 76,1,131,118,84,1,124,114,76,1,136,125,88,2,131,118,84,2,136,125, + 88,1,136,130,100,1,144,134,100,1,148,139,109,1,161,152,125,1,164,158, + 132,1,183,176,156,1,204,203,188,1,225,228,214,1,240,251,235,2,212,237, + 217,1,193,220,204,1,180,218,196,2,188,234,204,1,225,239,228,1,243,254, + 244,1,225,239,228,1,219,218,206,1,201,197,180,1,183,176,156,1,164,158, + 132,1,156,146,116,1,148,139,109,1,136,125,88,3,131,118,84,5,136,125, + 88,1,131,118,84,1,136,125,88,2,131,118,84,1,136,125,88,1,136,130, + 100,1,136,125,88,1,136,130,100,3,136,125,88,1,144,134,100,1,148,139, + 109,1,136,130,100,1,148,139,109,3,161,152,125,2,175,166,143,1,183,176, + 156,1,188,183,164,1,175,198,183,1,213,211,195,1,237,240,229,1,243,254, + 244,1,225,239,228,1,180,218,196,1,157,204,180,1,120,176,139,1,87,160, + 116,1,60,141,100,1,37,124,76,1,8,116,66,1,11,125,74,1,30,136, + 84,1,9,160,109,1,34,164,113,1,11,177,130,1,22,199,164,1,40,226, + 207,2,13,215,208,2,18,226,208,1,43,249,210,1,22,199,164,1,11,150, + 100,1,11,125,74,1,95,171,130,1,157,204,180,1,219,251,232,1,219,218, + 206,1,196,191,171,1,175,166,143,1,148,139,109,1,144,134,100,1,136,125, + 88,1,131,118,84,1,136,125,88,1,131,118,84,1,136,125,88,1,131,118, + 84,1,136,125,88,1,131,118,84,1,136,130,100,1,136,125,88,1,144,134, + 100,1,148,139,109,1,156,146,116,1,164,158,132,1,183,176,156,1,204,203, + 188,1,219,218,206,1,243,254,244,1,212,237,217,1,170,213,186,1,146,194, + 165,1,97,184,143,1,95,171,130,1,120,176,139,1,128,191,155,1,146,192, + 155,1,170,213,186,1,225,239,228,1,243,254,244,1,225,228,214,1,204,203, + 188,1,188,183,164,1,164,158,132,1,142,147,115,1,148,139,109,1,136,125, + 88,1,136,130,100,1,131,118,84,5,136,125,88,2,136,130,100,1,136,125, + 88,5,136,130,100,1,136,125,88,1,136,130,100,1,144,134,100,2,136,130, + 100,1,144,134,100,1,148,139,109,1,136,130,100,1,148,139,109,2,156,146, + 116,2,161,152,125,1,164,158,132,1,175,166,143,1,188,183,164,1,194,186, + 172,1,213,211,195,1,225,228,214,1,243,254,244,1,237,240,229,1,173,226, + 206,1,152,201,171,1,123,183,147,1,87,160,116,1,51,136,90,1,8,116, + 66,1,12,136,83,1,9,160,109,1,32,183,128,1,41,220,172,1,43,249, + 210,1,29,237,208,1,18,226,208,2,29,237,208,1,43,238,223,1,18,195, + 149,1,9,160,109,1,11,125,74,1,70,152,110,1,146,194,165,1,212,237, + 217,1,240,251,235,1,213,211,195,1,183,176,156,1,161,152,125,1,148,139, + 109,1,136,125,88,2,131,118,84,3,136,125,88,5,136,130,100,2,148,139, + 109,1,161,152,125,1,175,166,143,1,194,186,172,1,219,218,206,1,240,251, + 235,1,212,237,217,1,157,204,180,1,95,171,130,1,30,143,118,1,17,121, + 86,1,8,116,66,1,15,109,66,1,11,125,74,1,36,151,114,1,91,164, + 127,1,122,198,164,1,180,218,196,1,219,251,232,1,225,239,228,1,213,211, + 195,1,188,183,164,1,157,165,141,1,156,146,116,1,148,139,109,1,136,130, + 100,2,131,118,84,1,136,125,88,3,131,118,84,1,136,125,88,3,136,130, + 100,2,148,139,109,1,136,130,100,1,148,139,109,1,136,130,100,1,144,134, + 100,1,148,139,109,6,156,146,116,1,148,139,109,2,156,146,116,1,144,134, + 100,1,156,146,116,2,161,152,125,1,164,158,132,1,183,176,156,1,194,186, + 172,1,204,203,188,1,225,228,214,1,237,240,229,1,240,251,235,1,199,228, + 209,1,157,204,180,1,133,183,157,1,87,160,116,1,54,147,99,1,8,116, + 66,1,8,140,93,1,32,183,128,1,28,213,162,1,40,236,193,1,29,237, + 208,2,36,225,183,1,18,195,149,1,11,150,100,1,8,116,66,1,54,147, + 99,1,128,191,155,1,180,218,196,1,243,254,244,1,219,218,206,1,194,186, + 172,1,175,166,143,1,156,146,116,1,144,134,100,2,131,118,84,1,136,125, + 88,2,131,118,84,1,136,125,88,1,131,118,84,1,136,125,88,3,144,134, + 100,1,148,139,109,1,156,146,116,1,164,158,132,1,183,176,156,1,201,197, + 180,1,237,240,229,1,225,239,228,1,157,204,180,1,95,171,130,1,11,125, + 74,1,8,140,93,1,16,181,140,1,40,196,164,1,39,186,167,1,30,172, + 142,1,11,150,100,1,18,115,76,1,54,147,99,1,99,173,140,1,157,204, + 180,1,212,237,217,1,240,251,235,1,219,218,206,1,196,191,171,1,183,176, + 156,1,161,152,125,1,148,139,109,2,136,130,100,3,136,125,88,1,136,130, + 100,3,144,134,100,1,148,139,109,1,136,130,100,1,148,139,109,1,136,130, + 100,1,148,139,109,4,164,158,132,3,161,152,125,4,142,147,115,1,148,139, + 109,3,136,130,100,1,148,139,109,1,156,146,116,1,161,152,125,1,164,158, + 132,1,175,166,143,1,188,183,164,1,201,197,180,1,225,228,214,1,225,239, + 228,1,243,254,244,1,212,237,217,1,170,213,186,1,128,191,155,1,95,171, + 130,1,34,137,95,1,15,109,66,1,8,140,93,1,10,166,125,1,11,177, + 130,2,9,160,109,1,8,140,93,1,11,125,74,1,70,152,110,1,131,177, + 148,1,170,213,186,1,237,240,229,1,230,237,219,1,204,203,188,1,183,176, + 156,1,161,152,125,1,156,146,116,1,144,134,100,1,136,125,88,7,136,130, + 100,1,136,125,88,1,136,130,100,1,144,134,100,2,161,152,125,1,164,158, + 132,1,194,186,172,1,213,211,195,1,240,251,235,1,199,228,209,1,133,183, + 157,1,34,137,95,1,6,151,109,1,48,214,186,1,56,226,220,1,17,203, + 215,1,56,206,220,1,43,238,223,1,36,225,183,1,11,177,130,1,12,136, + 83,1,37,124,76,1,87,160,116,1,146,192,155,1,199,228,209,1,240,251, + 235,1,225,228,214,1,204,203,188,1,188,183,164,1,157,165,141,1,161,152, + 125,1,156,146,116,1,148,139,109,7,156,146,116,3,161,152,125,1,140,152, + 126,1,161,152,125,1,140,152,126,1,161,152,125,1,183,176,156,5,175,166, + 143,1,157,165,141,1,175,166,143,1,161,152,125,2,148,139,109,3,136,130, + 100,2,148,139,109,1,156,146,116,1,164,158,132,1,175,166,143,1,188,183, + 164,1,196,191,171,1,213,211,195,1,230,237,219,1,243,254,244,1,225,239, + 228,1,180,218,196,1,146,194,165,1,99,173,140,1,66,145,110,1,24,129, + 86,1,11,125,74,3,34,137,95,1,91,164,127,1,123,183,147,1,148,214, + 196,1,225,239,228,1,237,240,229,1,219,218,206,1,194,186,172,1,175,166, + 143,1,161,152,125,1,136,130,100,1,144,134,100,1,136,125,88,5,136,130, + 100,1,136,125,88,3,144,134,100,1,136,130,100,1,148,139,109,1,161,152, + 125,1,171,176,148,1,196,191,171,1,225,228,214,1,243,254,244,1,170,213, + 186,1,91,164,127,1,8,116,66,1,36,181,146,1,60,218,228,1,7,151, + 199,1,5,116,187,2,4,159,196,1,28,216,220,1,46,237,209,1,18,195, + 149,1,11,150,100,1,8,116,66,1,54,147,99,1,123,183,147,1,170,213, + 186,1,219,251,232,1,237,240,229,1,219,218,206,1,201,197,180,1,183,176, + 156,1,175,166,143,2,164,158,132,4,157,165,141,1,164,158,132,1,157,165, + 141,1,175,166,143,2,183,176,156,1,175,166,143,1,183,176,156,3,219,218, + 206,1,213,211,195,1,219,218,206,1,213,211,195,2,204,203,188,1,201,197, + 180,1,196,191,171,1,183,176,156,1,175,166,143,1,164,158,132,1,156,146, + 116,1,148,139,109,1,136,130,100,1,148,139,109,1,136,130,100,1,144,134, + 100,1,136,130,100,1,156,146,116,1,161,152,125,1,175,166,143,1,183,176, + 156,1,194,186,172,1,213,211,195,1,225,228,214,1,240,251,235,1,219,251, + 232,1,188,234,204,1,166,203,172,1,128,191,155,1,97,184,143,1,99,173, + 140,1,123,183,147,1,133,183,157,1,152,201,171,1,193,220,204,1,237,240, + 229,1,240,251,235,1,225,228,214,1,196,191,171,1,183,176,156,1,164,158, + 132,1,156,146,116,1,148,139,109,1,144,134,100,1,136,125,88,1,144,134, + 100,1,136,125,88,5,144,134,100,1,136,125,88,1,144,134,100,1,148,139, + 109,1,156,146,116,1,164,158,132,1,175,166,143,1,201,197,180,1,237,240, + 229,1,225,239,228,1,149,209,171,1,70,152,110,1,12,136,83,1,48,214, + 186,1,19,189,215,1,5,116,187,1,4,66,167,2,4,154,180,1,60,218, + 228,1,80,220,208,1,46,211,164,1,35,176,126,1,22,148,91,1,8,116, + 66,1,51,136,90,1,120,168,132,1,168,197,172,1,199,228,209,1,240,251, + 235,1,237,240,229,1,225,228,214,1,204,203,188,1,201,197,180,2,194,186, + 172,2,196,191,171,4,201,197,180,1,204,203,188,3,213,211,195,3,240,251, + 235,1,243,254,244,1,219,251,232,1,243,254,244,3,225,239,228,1,225,228, + 214,1,213,211,195,1,196,191,171,1,183,176,156,1,164,158,132,1,161,152, + 125,1,144,134,100,1,148,139,109,1,136,125,88,1,136,130,100,2,144,134, + 100,2,156,146,116,2,164,158,132,1,171,176,148,1,188,183,164,1,204,203, + 188,1,220,226,195,1,237,240,229,1,243,254,244,1,225,239,228,1,199,228, + 209,1,193,220,204,2,199,228,209,1,225,239,228,1,243,254,244,1,237,240, + 229,1,219,218,206,1,201,197,180,1,183,176,156,1,175,166,143,1,161,152, + 125,1,148,139,109,1,136,130,100,1,148,139,109,1,144,134,100,1,136,130, + 100,1,144,134,100,1,136,125,88,1,136,130,100,2,136,125,88,1,136,130, + 100,1,136,125,88,1,144,134,100,1,148,139,109,2,164,158,132,1,183,176, + 156,1,204,203,188,1,225,228,214,1,237,240,229,1,140,202,184,1,70,152, + 110,1,8,140,93,1,48,214,186,1,19,189,215,1,5,116,187,1,4,66, + 167,1,5,116,187,1,68,188,196,1,17,121,86,1,34,137,95,1,17,121, + 86,1,15,109,66,2,63,106,73,1,51,128,85,1,66,145,110,1,120,176, + 139,1,146,194,165,1,180,218,196,1,212,237,217,1,220,254,244,1,243,254, + 244,1,237,240,229,2,225,239,228,2,225,228,214,1,225,239,228,1,237,240, + 229,1,240,251,235,3,243,254,244,5,152,201,171,1,168,197,172,1,146,194, + 165,1,152,201,171,1,177,204,185,1,191,216,185,1,199,228,209,1,212,237, + 217,1,243,254,244,1,230,237,219,1,213,211,195,1,196,191,171,1,175,166, + 143,1,164,158,132,1,148,139,109,1,144,134,100,1,136,125,88,1,136,130, + 100,1,131,118,84,1,136,125,88,1,136,130,100,1,144,134,100,1,148,139, + 109,1,156,146,116,1,164,158,132,1,171,176,148,1,183,176,156,1,201,197, + 180,1,219,218,206,1,225,228,214,1,237,240,229,1,240,251,235,3,237,240, + 229,1,225,228,214,1,219,218,206,1,201,197,180,1,188,183,164,1,175,166, + 143,1,161,152,125,1,156,146,116,1,148,139,109,2,144,134,100,3,136,125, + 88,1,136,130,100,1,136,125,88,1,144,134,100,1,136,125,88,1,144,134, + 100,1,136,125,88,1,144,134,100,2,156,146,116,1,164,158,132,1,175,166, + 143,1,204,203,188,1,225,239,228,2,157,204,180,1,70,152,110,1,12,136, + 83,1,44,202,180,1,56,206,220,1,4,154,180,1,5,116,187,1,92,210, + 252,1,124,202,196,1,128,191,155,1,120,176,139,1,149,209,171,1,210,250, + 218,1,188,250,211,1,143,224,183,1,122,198,164,1,128,191,155,1,146,192, + 155,2,175,198,183,1,177,204,185,1,213,211,195,1,199,228,209,1,193,220, + 204,1,225,239,228,1,225,228,214,1,199,228,209,1,225,239,228,1,219,218, + 206,1,199,228,209,2,193,220,204,1,192,216,196,3,170,213,186,1,177,204, + 185,2,87,160,116,2,70,152,110,1,100,150,112,1,70,152,110,1,87,160, + 116,1,120,176,139,1,146,192,155,1,170,213,186,1,230,237,219,1,240,251, + 235,1,219,218,206,1,196,191,171,1,175,166,143,1,156,146,116,1,148,139, + 109,1,136,125,88,1,131,118,84,1,136,125,88,1,131,118,84,2,136,125, + 88,2,144,134,100,2,156,146,116,1,161,152,125,1,169,167,132,1,171,176, + 148,1,188,183,164,1,201,197,180,1,213,211,195,3,204,203,188,2,194,186, + 172,1,183,176,156,1,175,166,143,1,164,158,132,1,161,152,125,1,156,146, + 116,1,148,139,109,2,144,134,100,1,136,125,88,1,144,134,100,3,136,125, + 88,1,136,130,100,1,136,125,88,1,136,130,100,1,144,134,100,2,148,139, + 109,1,156,146,116,1,161,152,125,1,183,176,156,1,201,197,180,1,225,228, + 214,1,240,251,235,1,170,213,186,1,73,159,115,1,8,116,66,1,16,181, + 140,1,43,238,223,1,7,191,203,1,9,176,194,1,68,188,196,1,186,254, + 239,1,21,58,27,1,124,160,128,1,51,128,85,1,21,58,27,1,56,84, + 51,1,87,116,86,1,124,160,128,1,169,195,161,1,220,226,195,1,240,251, + 235,2,230,237,219,1,219,218,206,1,193,220,204,1,204,203,188,1,177,204, + 185,2,168,197,172,2,146,194,165,1,150,185,158,1,131,177,148,1,123,183, + 147,1,120,176,139,2,120,168,132,1,95,171,130,1,120,168,132,1,91,164, + 127,1,72,138,92,1,51,128,85,1,72,138,92,1,51,128,85,1,37,124, + 76,2,51,136,90,1,72,138,92,1,91,164,127,1,146,192,155,1,193,220, + 204,1,243,254,244,1,225,228,214,1,194,186,172,1,175,166,143,1,156,146, + 116,1,144,134,100,1,136,125,88,1,131,118,84,1,124,114,76,3,136,125, + 88,1,131,118,84,1,136,125,88,2,148,139,109,1,156,146,116,1,161,152, + 125,1,164,158,132,1,175,166,143,1,183,176,156,1,188,183,164,3,183,176, + 156,3,175,166,143,1,161,152,125,2,156,146,116,1,148,139,109,2,136,130, + 100,1,148,139,109,2,136,125,88,1,136,130,100,1,148,139,109,1,136,125, + 88,1,144,134,100,1,136,125,88,1,144,134,100,1,136,130,100,1,148,139, + 109,2,164,158,132,1,175,166,143,1,196,191,171,1,225,228,214,1,243,254, + 244,1,180,218,196,1,120,176,139,1,12,136,83,1,6,151,109,1,43,227, + 196,1,18,226,208,1,13,215,208,1,39,186,167,1,220,254,244,1,41,57, + 22,1,219,251,232,1,243,254,244,1,210,250,218,1,188,234,204,1,170,213, + 186,1,124,160,128,1,80,102,76,1,45,61,37,1,62,76,54,1,99,127, + 96,1,140,152,126,1,169,195,161,1,190,225,195,1,219,251,232,2,199,228, + 209,1,192,216,196,1,166,203,172,1,146,192,155,2,150,185,158,1,131,177, + 148,1,120,168,132,3,124,160,128,1,120,168,132,1,87,160,116,1,207,237, + 201,1,176,226,194,1,170,213,186,1,146,192,155,1,120,176,139,1,102,139, + 110,1,37,124,76,2,51,128,85,1,87,160,116,1,123,183,147,1,190,225, + 195,1,243,254,244,1,225,228,214,1,194,186,172,1,164,158,132,1,148,139, + 109,1,136,125,88,1,131,118,84,1,124,114,76,1,122,109,68,1,124,114, + 76,1,122,109,68,1,124,114,76,2,136,125,88,1,131,118,84,1,136,125, + 88,1,156,146,116,1,148,139,109,1,161,152,125,1,164,158,132,2,183,176, + 156,1,175,166,143,1,183,176,156,2,164,158,132,3,161,152,125,1,156,146, + 116,1,148,139,109,3,136,130,100,1,144,134,100,4,136,125,88,1,136,130, + 100,1,136,125,88,1,144,134,100,3,148,139,109,1,161,152,125,1,169,167, + 132,1,188,183,164,1,219,218,206,1,240,251,235,1,212,237,217,1,146,194, + 165,1,70,152,110,1,11,125,74,1,18,195,149,1,43,249,210,1,29,237, + 208,1,40,196,164,1,188,234,204,1,31,64,36,1,190,246,220,1,243,254, + 244,6,188,250,211,1,173,226,206,1,146,194,165,1,68,136,108,1,31,64, + 36,1,46,73,42,1,86,108,72,1,136,130,100,1,140,152,126,1,169,195, + 161,1,198,204,170,1,225,228,214,1,232,248,219,2,240,251,235,7,80,102, + 76,1,86,108,84,1,99,127,96,1,124,160,128,1,152,201,171,1,219,251, + 232,1,149,209,171,1,87,160,116,1,51,128,85,2,100,150,112,1,133,183, + 157,1,192,216,196,1,243,254,244,1,213,211,195,1,188,183,164,1,161,152, + 125,1,136,130,100,1,131,118,84,1,122,109,68,3,114,102,60,1,122,109, + 68,2,124,114,76,2,131,118,84,2,144,134,100,2,156,146,116,1,164,158, + 132,2,183,176,156,1,175,166,143,2,183,176,156,1,175,166,143,1,164,158, + 132,2,161,152,125,1,156,146,116,2,148,139,109,2,144,134,100,2,136,130, + 100,1,148,139,109,1,144,134,100,1,136,125,88,1,144,134,100,1,136,125, + 88,1,144,134,100,2,148,139,109,1,156,146,116,1,164,158,132,1,188,183, + 164,1,204,203,188,1,225,228,214,1,240,251,235,1,170,213,186,1,99,173, + 140,1,24,129,86,1,9,160,109,1,41,220,172,1,43,249,210,1,43,202, + 153,1,176,226,194,1,46,73,42,1,190,246,220,1,243,254,244,9,210,250, + 218,1,243,254,244,1,188,234,204,1,166,203,172,1,150,185,158,1,102,139, + 110,1,80,97,65,1,41,57,22,1,31,64,36,1,45,61,37,1,62,76, + 54,3,62,86,60,1,62,76,54,3,46,73,42,1,173,226,206,2,122,198, + 164,1,126,170,142,1,56,84,51,1,64,96,66,1,126,170,142,1,240,251, + 235,1,146,192,155,1,66,145,110,1,60,141,100,1,91,164,127,1,146,194, + 165,1,199,228,209,1,240,251,235,1,201,197,180,1,164,158,132,1,148,139, + 109,1,131,118,84,1,122,109,68,1,114,102,60,7,124,114,76,2,136,130, + 100,1,148,139,109,1,161,152,125,1,164,158,132,1,183,176,156,1,188,183, + 164,2,194,186,172,1,188,183,164,1,183,176,156,2,175,166,143,1,164,158, + 132,1,161,152,125,1,156,146,116,1,148,139,109,2,136,130,100,1,144,134, + 100,2,136,125,88,1,144,134,100,1,136,125,88,1,144,134,100,1,136,125, + 88,1,144,134,100,2,148,139,109,1,156,146,116,1,161,152,125,1,175,166, + 143,1,196,191,171,1,219,218,206,1,240,251,235,1,212,237,217,1,146,194, + 165,1,70,152,110,1,8,116,66,1,11,177,130,1,41,220,172,1,36,181, + 146,1,143,224,183,1,56,84,51,1,190,246,220,1,243,254,244,17,190,246, + 220,3,164,234,212,4,190,246,220,1,182,245,228,2,243,254,244,4,219,251, + 232,1,170,213,186,1,64,96,66,1,86,108,72,1,166,203,172,1,188,234, + 204,1,120,176,139,1,124,160,128,1,131,177,148,1,177,204,185,1,237,240, + 229,1,225,228,214,1,183,176,156,1,148,139,109,1,136,125,88,1,122,109, + 68,1,107,96,52,1,101,87,41,4,107,96,52,1,114,102,60,2,124,114, + 76,1,131,118,84,1,156,146,116,1,164,158,132,1,183,176,156,1,196,191, + 171,1,201,197,180,1,213,211,195,1,204,203,188,2,201,197,180,1,194,186, + 172,1,188,183,164,1,175,166,143,1,164,158,132,1,161,152,125,1,156,146, + 116,1,148,139,109,2,144,134,100,3,136,125,88,1,144,134,100,1,136,125, + 88,1,136,130,100,1,136,125,88,1,144,134,100,3,156,146,116,1,164,158, + 132,1,171,176,148,1,201,197,180,1,219,218,206,1,243,254,244,1,180,218, + 196,1,123,183,147,1,60,141,100,1,12,136,83,1,32,183,128,1,22,148, + 91,1,188,234,204,1,46,73,42,1,190,246,220,1,243,254,244,33,179,236, + 213,1,133,183,157,1,46,73,42,1,140,152,126,1,210,250,218,1,192,216, + 196,1,168,197,172,1,175,198,183,1,230,237,219,1,237,240,229,1,196,191, + 171,1,161,152,125,1,131,118,84,1,114,102,60,1,101,87,41,2,88,75, + 26,1,101,87,41,4,114,102,60,1,124,114,76,1,144,134,100,1,140,152, + 126,1,183,176,156,1,201,197,180,1,219,218,206,1,237,240,229,2,240,251, + 235,1,225,239,228,1,219,218,206,1,213,211,195,1,201,197,180,1,183,176, + 156,1,175,166,143,1,164,158,132,1,156,146,116,2,148,139,109,1,136,130, + 100,1,144,134,100,2,136,125,88,1,144,134,100,1,136,125,88,1,144,134, + 100,2,136,125,88,1,148,139,109,1,144,134,100,1,148,139,109,1,161,152, + 125,1,164,158,132,1,188,183,164,1,201,197,180,1,230,237,219,1,240,251, + 235,1,180,218,196,1,95,171,130,1,24,129,86,1,37,124,76,2,232,248, + 219,1,21,58,27,1,243,254,244,36,188,234,204,1,68,115,88,1,81,88, + 63,1,126,170,142,1,212,237,217,1,243,254,244,1,240,251,235,1,230,237, + 219,1,196,191,171,1,156,146,116,1,122,109,68,1,107,96,52,1,88,75, + 26,1,71,73,27,2,69,65,21,2,88,75,26,1,101,87,41,1,107,96, + 52,1,124,114,76,1,148,139,109,1,183,176,156,1,213,211,195,1,240,251, + 235,1,219,251,232,1,225,239,228,1,199,228,209,1,225,239,228,1,237,240, + 229,1,243,254,244,1,225,239,228,1,219,218,206,1,201,197,180,1,188,183, + 164,1,175,166,143,1,164,158,132,1,156,146,116,1,148,139,109,1,144,134, + 100,2,136,125,88,1,144,134,100,1,136,130,100,1,136,125,88,1,136,130, + 100,1,136,125,88,3,144,134,100,2,148,139,109,1,156,146,116,1,164,158, + 132,1,188,183,164,1,204,203,188,1,225,239,228,1,219,251,232,1,170,213, + 186,1,120,168,132,1,54,147,99,1,123,183,147,1,169,195,161,1,87,116, + 86,1,243,254,244,38,157,204,180,1,64,96,66,1,62,86,60,1,120,139, + 109,1,164,158,132,1,169,167,132,1,156,146,116,1,136,125,88,1,114,102, + 60,1,88,75,26,1,65,60,12,2,69,65,21,2,65,60,12,2,71,73, + 27,1,101,87,41,1,124,114,76,1,164,158,132,1,213,211,195,1,240,251, + 235,1,176,226,194,1,152,201,171,1,123,183,147,1,128,191,155,1,146,194, + 165,1,170,213,186,1,199,228,209,1,240,251,235,1,237,240,229,1,219,218, + 206,1,194,186,172,1,183,176,156,1,164,158,132,1,156,146,116,1,148,139, + 109,1,136,130,100,1,144,134,100,2,136,125,88,1,136,130,100,1,136,125, + 88,7,144,134,100,1,148,139,109,1,156,146,116,1,164,158,132,1,175,166, + 143,1,201,197,180,1,220,226,195,1,243,254,244,1,192,216,196,1,175,198, + 183,1,232,248,219,1,99,127,96,1,168,197,172,1,243,254,244,39,219,251, + 232,1,180,218,196,1,124,160,128,1,56,84,51,1,41,57,22,1,45,62, + 27,1,41,57,22,1,45,62,27,1,114,102,60,1,99,127,96,1,142,147, + 115,1,124,160,128,1,100,150,112,1,106,138,100,1,107,96,52,1,41,57, + 22,1,88,75,26,1,131,118,84,1,171,176,148,1,240,251,235,1,157,204, + 180,1,104,150,124,1,51,136,90,1,11,125,74,1,30,136,84,1,70,152, + 110,1,99,173,140,1,152,201,171,1,193,220,204,1,243,254,244,1,230,237, + 219,1,213,211,195,1,194,186,172,1,175,166,143,1,161,152,125,1,156,146, + 116,1,148,139,109,1,144,134,100,1,136,125,88,1,144,134,100,1,136,125, + 88,4,131,118,84,1,136,125,88,5,144,134,100,2,156,146,116,1,164,158, + 132,1,188,183,164,1,213,211,195,1,230,237,219,1,232,248,219,1,150,185, + 158,1,21,58,27,1,188,250,211,1,243,254,244,38,164,234,212,1,243,254, + 244,4,188,250,211,1,190,246,220,4,243,254,244,3,190,246,220,1,173,226, + 206,1,146,194,165,1,120,149,116,1,41,57,22,1,107,96,52,1,171,176, + 148,1,240,251,235,1,120,168,132,1,8,116,66,1,9,160,109,1,34,164, + 113,1,11,150,100,1,8,116,66,1,30,136,84,1,95,171,130,1,149,209, + 171,1,225,228,214,1,243,254,244,1,225,228,214,1,194,186,172,1,175,166, + 143,1,164,158,132,1,156,146,116,1,144,134,100,2,136,130,100,1,136,125, + 88,6,124,114,76,1,131,118,84,3,136,125,88,1,131,118,84,1,136,125, + 88,1,136,130,100,1,144,134,100,1,148,139,109,1,161,152,125,1,157,165, + 141,1,164,158,132,1,64,96,66,1,131,177,148,1,243,254,244,54,188,250, + 211,1,243,254,244,1,170,213,186,1,80,97,65,1,80,102,76,1,192,216, + 196,1,123,183,147,1,34,137,95,1,46,211,164,1,40,236,193,1,28,213, + 162,1,11,177,130,1,11,125,74,1,34,137,95,1,120,176,139,1,148,214, + 196,1,237,240,229,1,225,239,228,1,204,203,188,1,183,176,156,1,164,158, + 132,1,156,146,116,1,148,139,109,1,144,134,100,1,136,125,88,1,136,130, + 100,1,136,125,88,1,131,118,84,1,136,125,88,2,131,118,84,1,136,125, + 88,2,124,114,76,4,122,109,68,5,114,102,60,1,84,84,41,1,95,117, + 76,1,243,254,244,58,188,250,211,1,102,139,110,1,87,116,86,1,219,251, + 232,1,34,137,95,1,41,220,172,1,46,237,209,1,41,247,222,1,21,213, + 172,1,16,169,116,1,8,116,66,1,73,159,115,1,146,194,165,1,212,237, + 217,1,243,254,244,1,213,211,195,1,188,183,164,1,164,158,132,1,156,146, + 116,1,144,134,100,2,136,125,88,2,131,118,84,1,136,125,88,2,124,114, + 76,1,136,125,88,1,124,114,76,1,131,118,84,1,136,125,88,1,124,114, + 76,1,122,109,68,3,114,102,60,1,107,96,52,1,101,87,41,2,65,60, + 12,1,86,108,72,1,180,218,196,1,243,254,244,59,190,246,220,1,99,127, + 96,1,106,138,100,1,124,214,180,1,30,172,142,1,29,237,208,1,18,226, + 208,1,43,249,210,1,18,195,149,1,12,136,83,1,34,137,95,1,123,183, + 147,1,193,220,204,1,243,254,244,1,219,218,206,1,196,191,171,1,175,166, + 143,1,156,146,116,1,144,134,100,2,136,125,88,4,131,118,84,1,136,125, + 88,1,131,118,84,1,136,125,88,1,124,114,76,3,122,109,68,2,114,102, + 60,1,107,96,52,1,101,87,41,1,88,75,26,1,65,60,12,1,101,87, + 41,1,120,168,132,1,243,254,244,1,182,245,228,1,243,254,244,59,176,226, + 194,1,21,58,27,1,170,213,186,1,24,129,86,1,71,239,220,1,18,226, + 208,1,29,237,208,1,26,216,182,1,16,169,116,1,11,125,74,1,95,171, + 130,1,170,213,186,1,243,254,244,1,219,218,206,1,196,191,171,1,164,158, + 132,1,156,146,116,1,148,139,109,1,136,125,88,4,131,118,84,3,136,125, + 88,1,122,109,68,1,131,118,84,1,124,114,76,1,122,109,68,2,114,102, + 60,1,107,96,52,1,101,87,41,2,65,60,12,2,95,117,76,1,149,209, + 171,1,243,254,244,60,182,245,228,1,243,254,244,1,133,183,157,1,87,116, + 86,1,143,224,183,1,39,186,167,1,16,214,196,1,18,226,208,1,41,247, + 222,1,11,177,130,1,8,116,66,1,73,159,115,1,157,204,180,1,219,251, + 232,1,225,228,214,1,194,186,172,1,175,166,143,1,156,146,116,1,136,130, + 100,2,131,118,84,4,136,125,88,1,131,118,84,2,136,125,88,1,124,114, + 76,3,122,109,68,1,114,102,60,1,107,96,52,1,101,87,41,1,88,75, + 26,1,69,65,21,1,65,60,12,1,99,127,96,1,154,213,186,1,243,254, + 244,62,173,226,206,1,21,58,27,1,188,234,204,1,16,110,76,1,46,237, + 209,1,13,215,208,1,43,238,223,1,20,203,154,1,12,136,83,1,54,147, + 99,1,146,194,165,1,225,239,228,1,225,228,214,1,196,191,171,1,175,166, + 143,1,148,139,109,1,144,134,100,1,136,125,88,1,136,130,100,1,124,114, + 76,1,136,125,88,1,131,118,84,3,122,109,68,1,124,114,76,2,122,109, + 68,2,114,102,60,2,107,96,52,1,101,87,41,1,87,78,36,1,88,75, + 26,1,65,60,12,1,95,117,76,1,152,201,171,1,243,254,244,63,124,160, + 128,1,100,150,112,1,97,184,143,1,68,218,191,1,13,215,208,1,29,237, + 208,1,36,225,183,1,11,150,100,1,34,137,95,1,128,191,155,1,212,237, + 217,1,225,239,228,1,196,191,171,1,175,166,143,1,148,139,109,1,136,130, + 100,1,136,125,88,1,124,114,76,1,136,125,88,1,124,114,76,1,131,118, + 84,1,124,114,76,1,131,118,84,1,136,125,88,1,124,114,76,3,122,109, + 68,2,114,102,60,1,107,96,52,2,88,75,26,2,65,60,12,1,107,96, + 52,1,123,183,147,1,243,254,244,63,190,225,195,1,56,84,51,1,186,254, + 239,1,36,151,114,1,40,226,207,1,29,237,208,1,43,227,196,1,16,169, + 116,1,11,125,74,1,123,183,147,1,212,237,217,1,230,237,219,1,196,191, + 171,1,157,165,141,1,148,139,109,1,144,134,100,1,131,118,84,2,124,114, + 76,1,131,118,84,1,124,114,76,1,131,118,84,1,124,114,76,4,122,109, + 68,2,114,102,60,2,101,87,41,2,87,78,36,1,88,75,26,1,69,65, + 21,2,124,160,128,1,190,246,220,1,243,254,244,63,80,102,76,1,123,183, + 147,1,104,150,124,1,43,227,196,1,29,237,208,1,40,236,193,1,11,177, + 130,1,11,125,74,1,97,184,143,1,199,228,209,1,225,239,228,1,196,191, + 171,1,164,158,132,1,148,139,109,1,136,125,88,1,131,118,84,1,124,114, + 76,1,131,118,84,1,124,114,76,1,131,118,84,1,124,114,76,4,122,109, + 68,3,114,102,60,2,107,96,52,2,101,87,41,2,88,75,26,1,65,60, + 12,1,87,116,86,1,188,250,211,1,243,254,244,63,140,202,184,1,80,102, + 76,1,188,234,204,1,10,166,125,1,63,249,210,1,43,249,210,1,11,177, + 130,1,11,125,74,1,95,171,130,1,199,228,209,1,230,237,219,1,196,191, + 171,1,164,158,132,1,144,134,100,1,131,118,84,2,124,114,76,7,122,109, + 68,1,124,114,76,1,122,109,68,2,114,102,60,3,107,96,52,1,101,87, + 41,3,84,84,41,1,46,73,42,1,188,234,204,1,243,254,244,63,182,245, + 228,1,56,84,51,1,146,192,155,1,36,151,114,1,46,211,164,1,36,225, + 183,1,18,195,149,1,8,116,66,1,95,171,130,1,199,228,209,1,230,237, + 219,1,188,183,164,1,161,152,125,1,144,134,100,1,131,118,84,1,124,114, + 76,5,136,125,88,1,122,109,68,1,124,114,76,3,114,102,60,1,122,109, + 68,1,114,102,60,2,107,96,52,2,114,102,60,2,107,96,52,2,41,57, + 22,1,188,234,204,1,243,254,244,64,146,194,165,1,63,106,73,1,188,250, + 211,1,24,129,86,1,43,202,153,1,32,183,128,1,11,125,74,1,87,160, + 116,1,173,226,206,1,230,237,219,1,194,186,172,1,156,146,116,1,136,130, + 100,1,131,118,84,1,122,109,68,1,124,114,76,1,122,109,68,1,124,114, + 76,1,122,109,68,2,124,114,76,1,122,109,68,4,114,102,60,6,124,114, + 76,1,136,125,88,1,114,102,60,1,41,57,22,1,188,234,204,1,182,245, + 228,1,243,254,244,63,210,250,218,1,64,96,66,1,120,176,139,1,97,184, + 143,1,11,150,100,1,11,177,130,1,8,116,66,1,91,164,127,1,199,228, + 209,1,230,237,219,1,183,176,156,1,156,146,116,1,131,118,84,1,124,114, + 76,1,122,109,68,10,114,102,60,4,122,109,68,2,131,118,84,1,136,125, + 88,1,144,134,100,1,124,114,76,1,46,73,42,1,210,250,218,1,243,254, + 244,30,15,0,0,0,248,255,255,255,31,240,127,0,12,0,0,0,63,1, + 0,0,248,255,255,255,31,252,255,161,15,0,0,0,255,0,0,0,240,255, + 255,255,31,254,255,195,15,0,0,0,255,3,0,0,232,255,255,255,143,255, + 255,239,15,0,0,0,255,7,0,0,192,255,255,255,143,255,255,255,15,0, + 0,0,255,15,0,0,128,255,255,255,231,255,255,255,15,0,0,0,255,63, + 0,0,0,254,255,255,195,255,255,255,15,0,0,0,255,127,0,0,0,252, + 255,255,225,255,255,255,15,0,0,0,255,127,1,0,0,128,255,255,224,255, + 255,255,15,0,0,0,255,255,0,0,0,0,252,127,232,255,255,255,15,0, + 0,0,255,255,1,0,0,0,224,31,240,255,255,255,11,0,0,0,255,255, + 5,0,0,0,0,7,240,255,253,255,7,0,0,0,254,255,3,0,0,0, + 0,0,240,127,255,255,15,0,0,0,255,255,3,0,0,0,0,0,224,223, + 255,255,15,0,0,0,247,255,3,0,0,0,0,0,224,255,255,255,15,0, + 0,0,159,255,3,0,0,0,0,0,224,255,255,255,15,0,0,0,255,235, + 3,0,0,0,0,0,192,255,255,255,15,0,0,0,255,255,1,0,0,0, + 0,0,128,255,255,255,15,0,0,0,255,255,3,0,0,0,0,0,0,255, + 255,255,15,0,0,0,255,255,1,0,0,0,0,0,128,254,255,255,15,0, + 0,0,255,255,1,0,0,0,0,0,0,254,255,255,15,0,0,0,255,255, + 3,0,0,32,0,0,0,254,255,255,15,0,0,0,255,255,3,0,0,0, + 0,0,0,252,255,255,15,0,0,0,255,255,7,0,0,0,0,0,0,252, + 255,255,15,0,0,0,255,255,15,0,0,0,0,0,0,252,255,255,15,0, + 0,0,255,255,7,0,7,0,0,0,0,252,255,255,15,0,0,0,255,255, + 7,240,127,0,0,0,0,252,255,255,15,0,0,0,255,255,7,248,255,1, + 0,0,0,253,255,255,15,0,0,0,255,255,7,254,255,1,0,0,0,252, + 255,255,15,0,0,0,255,255,3,255,255,3,0,0,0,252,207,255,15,0, + 0,0,255,255,7,255,255,7,0,0,0,252,255,254,15,0,0,0,255,255, + 1,255,191,7,0,0,0,248,255,247,15,0,0,0,255,255,129,255,223,7, + 0,0,0,248,255,239,15,0,0,0,255,255,128,255,255,7,0,0,0,240, + 255,255,15,0,0,0,255,127,128,255,255,15,0,0,0,224,255,127,15,0, + 0,0,255,127,128,191,255,95,0,0,0,192,255,255,14,0,0,0,255,63, + 128,255,255,63,0,0,0,192,255,255,13,0,0,0,255,31,128,255,255,127, + 1,0,0,244,255,255,13,0,0,0,255,15,0,255,255,255,0,0,0,254, + 255,255,15,0,0,0,255,7,0,255,255,255,0,0,144,255,255,255,15,0, + 0,0,255,0,0,255,255,255,0,0,224,255,255,255,1,0,0,0,0,0, + 0,255,255,255,0,0,248,255,255,7,0,0,0,0,0,0,0,255,255,223, + 1,0,252,255,255,15,0,0,0,0,2,0,0,255,255,255,0,64,255,255, + 255,47,4,0,0,0,3,0,0,255,255,255,0,128,255,255,255,255,15,0, + 0,0,7,0,128,255,255,127,0,224,255,255,255,255,15,0,0,0,15,0, + 0,255,255,239,0,248,255,255,251,255,7,0,0,0,31,0,0,255,255,63, + 0,255,255,255,255,255,15,0,0,0,63,0,0,254,255,63,240,255,255,127, + 255,255,15,0,0,0,255,0,0,252,255,95,253,255,255,255,255,255,15,0, + 0,0,255,0,0,248,255,15,255,255,255,239,255,255,15,0,0,0,255,0, + 0,240,255,239,255,255,255,251,255,255,15,0,0,0,255,1,0,192,255,241, + 255,255,255,254,255,255,11,0,0,0,255,1,0,0,0,248,255,255,191,255, + 255,255,15,0,0,0,255,7,0,0,0,252,255,255,247,255,255,255,15,0, + 0,0,255,3,0,0,0,255,255,255,252,255,255,255,7,0,0,0,255,7, + 0,0,128,255,255,207,255,255,255,255,15,0,0,0,254,15,0,0,224,255, + 255,254,255,255,255,255,15,0,0,0,255,31,0,0,240,255,239,255,255,255, + 255,255,15,0,0,0,253,31,0,0,250,255,255,255,255,255,255,255,15,0, + 0,0,255,31,0,0,252,255,255,255,255,255,255,255,15,0,0,0,255,63, + 0,0,255,255,255,255,255,255,255,255,15,0,0,0,255,255,1,128,255,255, + 255,255,255,255,255,255,15,0,0,0,255,255,175,234,255,255,255,255,255,255, + 255,255,15,0,0,0,255,255,255,241,255,255,255,255,255,255,255,255,15,0, + 0,0,127,255,255,255,255,251,255,255,255,255,255,255,15,0,0,0,255,253, + 255,255,255,255,255,255,199,255,255,255,15,0,0,0,255,255,255,255,255,253, + 255,255,255,254,255,255,15,0,0,0,255,191,255,255,255,255,255,127,255,251, + 255,255,15,0,0,0,255,255,254,255,255,255,255,255,255,255,255,255,15,0, + 0,0,255,255,255,255,127,255,255,255,255,255,255,255,15,0,0,0,255,255, + 223,255,255,255,255,255,255,255,255,255,15,0,0,0,255,255,127,255,255,255, + 255,223,255,255,255,255,15,0,0,0,255,255,255,255,255,255,255,255,255,255, + 255,255,15,0,0,0,197,255,255,239,247,255,255,255,255,255,239,127,0,0, + 0,0,255,254,255,255,255,255,255,255,255,255,255,255,15,0,0,0,255,255, + 255,255,255,255,255,255,255,255,255,255,15,0,0,0,255,247,255,255,255,255, + 255,223,255,253,255,255,15,0,0,0,255,239,255,255,255,255,255,255,255,129, + 255,255,15,0,0,0,255,223,255,255,255,255,255,255,255,1,244,255,15,0, + 0,0,255,255,255,255,255,255,255,255,255,1,0,252,15,0,0,0,240,255, + 255,255,255,255,255,127,255,1,0,0,0,0,0,0,192,255,255,255,255,255, + 255,255,255,0,0,0,0,0,0,0,0,223,255,255,191,255,255,255,255,0, + 0,0,0,0,0,0,0,252,255,255,255,255,255,255,251,0,0,0,0,0, + 0,0,0,248,255,255,255,254,255,255,255,0,0,0,0,0,0,0,0,132, + 143,255,255,253,255,255,127,0,0,0,0,0,0,0,0,0,0,250,255,255, + 255,255,63,0,0,0,0,0,0,0,0,0,0,240,255,251,255,255,63,0, + 0,0,0,0,0,0,0,0,0,224,255,251,255,255,95,0,0,0,0,0, + 0,0,0,0,0,192,255,251,255,255,31,0,0,0,0,0,0,0,0,0, + 0,160,255,255,255,255,31,0,0,0,0,0,0,0,0,0,0,128,255,255, + 255,255,31,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,31,0, + 0,0,0,0,0,0,0,0,0,0,255,255,255,255,63,0,0,0,0,0, + 0,0,0,0,0,0,254,255,255,255,63,0,0,0,0,0,0,0,0,0, + 0,0,254,255,255,255,63,0,0,0,0,0,0,0,0,0,0,0,254,255, + 255,255,63,0,0,0,0,0,0,0,0,0,0,0,252,255,255,255,127,0, + 0,0,0,0,0,0,0,0,0,0,252,255,255,255,63,0,0,0,0,0, + 0,0,19,102,97,99,101,46,102,97,100,101,95,112,111,115,46,99,111,117, + 110,116,2,5,19,102,97,99,101,46,102,97,100,101,95,112,111,115,46,105, + 116,101,109,115,1,2,0,5,205,204,204,204,204,204,204,204,252,63,5,0, + 0,0,0,0,0,0,128,254,63,5,205,204,204,204,204,204,204,204,254,63, + 2,1,0,21,102,97,99,101,46,102,97,100,101,95,99,111,108,111,114,46, + 99,111,117,110,116,2,5,21,102,97,99,101,46,102,97,100,101,95,99,111, + 108,111,114,46,105,116,101,109,115,1,4,255,255,255,0,4,128,128,128,0, + 4,64,64,64,0,4,128,128,128,0,4,255,255,255,0,0,19,102,97,99, + 101,46,102,97,100,101,95,100,105,114,101,99,116,105,111,110,7,5,103,100, + 95,117,112,15,102,97,99,101,46,108,111,99,97,108,112,114,111,112,115,11, + 11,102,97,108,95,111,112,116,105,111,110,115,15,102,97,108,95,102,97,100, + 105,114,101,99,116,105,111,110,13,102,97,108,95,102,97,111,112,97,99,105, + 116,121,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100, + 115,95,120,3,144,1,8,98,111,117,110,100,115,95,121,2,40,9,98,111, + 117,110,100,115,95,99,120,3,132,0,9,98,111,117,110,100,115,95,99,121, + 2,52,8,115,116,97,116,102,105,108,101,7,10,116,115,116,97,116,102,105, + 108,101,49,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0, + 0,11,116,115,116,114,105,110,103,101,100,105,116,12,116,115,116,114,105,110, + 103,101,100,105,116,56,5,99,111,108,111,114,4,3,0,0,128,12,102,114, + 97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,102, + 114,97,109,101,105,95,108,101,102,116,2,4,18,102,114,97,109,101,46,102, + 114,97,109,101,105,95,114,105,103,104,116,2,4,21,102,114,97,109,101,46, + 102,114,97,109,101,105,109,97,103,101,95,108,105,115,116,7,4,105,109,108, + 105,28,102,114,97,109,101,46,102,114,97,109,101,105,109,97,103,101,95,111, + 102,102,115,101,116,109,111,117,115,101,2,8,30,102,114,97,109,101,46,102, + 114,97,109,101,105,109,97,103,101,95,111,102,102,115,101,116,99,108,105,99, + 107,101,100,2,8,29,102,114,97,109,101,46,102,114,97,109,101,105,109,97, + 103,101,95,111,102,102,115,101,116,97,99,116,105,118,101,2,24,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 114,108,95,108,101,118,101,108,111,10,102,114,108,95,108,101,118,101,108,105, + 14,102,114,108,95,102,114,97,109,101,119,105,100,116,104,10,102,114,108,95, + 102,105,108,101,102,116,11,102,114,108,95,102,105,114,105,103,104,116,18,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,108,105,115,116,25,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111, + 117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,15,102, + 114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,12,102,97,99,101, + 46,111,112,116,105,111,110,115,11,18,102,97,111,95,97,108,112,104,97,102, + 97,100,101,105,109,97,103,101,0,20,102,97,99,101,46,105,109,97,103,101, + 46,97,108,105,103,110,109,101,110,116,11,12,97,108,95,120,99,101,110,116, + 101,114,101,100,12,97,108,95,121,99,101,110,116,101,114,101,100,8,97,108, + 95,116,105,108,101,100,0,16,102,97,99,101,46,105,109,97,103,101,46,105, + 109,97,103,101,10,160,11,0,0,0,0,0,0,0,0,0,0,32,0,0, + 0,32,0,0,0,108,11,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,189,189,189,1,181,181,181,1,189,189,189,4,198,198,198,1,206,206,206, + 1,222,222,222,3,214,214,214,1,156,156,156,1,148,148,148,1,206,206,206, + 1,222,222,222,2,181,181,181,2,189,189,189,1,222,222,222,3,214,214,214, + 1,198,198,198,2,189,189,189,1,181,181,181,2,189,189,189,1,148,148,148, + 1,156,156,156,1,189,189,189,1,173,173,173,2,156,156,156,1,148,148,148, + 1,156,156,156,1,165,165,165,1,189,189,189,1,165,165,165,1,156,156,156, + 1,148,148,148,2,214,214,214,1,148,148,148,2,222,222,222,1,189,189,189, + 2,181,181,181,1,189,189,189,1,156,156,156,2,165,165,165,1,173,173,173, + 1,165,165,165,2,156,156,156,1,148,148,148,1,156,156,156,1,181,181,181, + 1,156,156,156,1,206,206,206,2,198,198,198,1,173,173,173,1,181,181,181, + 1,214,214,214,1,222,222,222,2,206,206,206,1,198,198,198,1,189,189,189, + 3,222,222,222,1,206,206,206,1,173,173,173,1,189,189,189,1,156,156,156, + 1,173,173,173,1,222,222,222,1,206,206,206,1,181,181,181,1,198,198,198, + 3,214,214,214,1,222,222,222,2,206,206,206,1,148,148,148,1,181,181,181, + 1,214,214,214,1,189,189,189,1,198,198,198,1,222,222,222,1,148,148,148, + 1,181,181,181,2,222,222,222,4,189,189,189,1,206,206,206,1,222,222,222, + 3,181,181,181,2,156,156,156,1,214,214,214,1,222,222,222,3,189,189,189, + 1,206,206,206,1,222,222,222,3,206,206,206,1,156,156,156,1,189,189,189, + 1,181,181,181,1,222,222,222,1,165,165,165,1,222,222,222,2,156,156,156, + 1,189,189,189,2,181,181,181,3,189,189,189,1,181,181,181,2,189,189,189, + 1,181,181,181,1,206,206,206,1,214,214,214,1,156,156,156,1,181,181,181, + 1,222,222,222,1,189,189,189,1,181,181,181,1,189,189,189,1,181,181,181, + 2,189,189,189,1,181,181,181,2,156,156,156,1,148,148,148,1,156,156,156, + 1,181,181,181,1,222,222,222,3,198,198,198,1,165,165,165,1,222,222,222, + 1,181,181,181,1,189,189,189,1,165,165,165,1,156,156,156,6,189,189,189, + 2,173,173,173,1,148,148,148,1,222,222,222,1,156,156,156,1,148,148,148, + 1,156,156,156,5,173,173,173,1,156,156,156,1,206,206,206,1,181,181,181, + 1,148,148,148,1,222,222,222,3,181,181,181,1,148,148,148,1,222,222,222, + 1,206,206,206,1,148,148,148,2,214,214,214,1,222,222,222,6,165,165,165, + 2,189,189,189,1,198,198,198,1,222,222,222,6,189,189,189,3,222,222,222, + 1,189,189,189,1,148,148,148,1,222,222,222,3,173,173,173,1,148,148,148, + 1,222,222,222,2,189,189,189,1,181,181,181,2,214,214,214,1,222,222,222, + 3,165,165,165,1,214,214,214,1,156,156,156,1,189,189,189,1,156,156,156, + 1,181,181,181,2,189,189,189,1,222,222,222,3,198,198,198,1,156,156,156, + 1,165,165,165,1,222,222,222,2,198,198,198,1,173,173,173,1,206,206,206, + 1,222,222,222,2,148,148,148,1,181,181,181,1,222,222,222,2,189,189,189, + 1,165,165,165,1,156,156,156,1,181,181,181,1,222,222,222,3,198,198,198, + 2,165,165,165,1,214,214,214,1,181,181,181,1,148,148,148,1,206,206,206, + 2,222,222,222,2,206,206,206,1,165,165,165,1,181,181,181,1,148,148,148, + 1,222,222,222,3,156,156,156,1,189,189,189,1,222,222,222,1,198,198,198, + 1,181,181,181,1,198,198,198,1,222,222,222,2,181,181,181,1,148,148,148, + 1,198,198,198,1,165,165,165,1,173,173,173,1,189,189,189,3,181,181,181, + 1,156,156,156,1,222,222,222,1,181,181,181,1,165,165,165,1,181,181,181, + 3,189,189,189,1,165,165,165,2,189,189,189,1,156,156,156,1,222,222,222, + 3,165,165,165,1,148,148,148,1,222,222,222,1,181,181,181,1,156,156,156, + 1,222,222,222,3,173,173,173,2,222,222,222,1,198,198,198,1,156,156,156, + 1,173,173,173,1,148,148,148,2,156,156,156,2,222,222,222,1,181,181,181, + 1,173,173,173,1,156,156,156,3,181,181,181,1,165,165,165,1,222,222,222, + 1,206,206,206,1,189,189,189,1,206,206,206,1,222,222,222,2,189,189,189, + 1,165,165,165,1,214,214,214,1,173,173,173,1,189,189,189,1,222,222,222, + 3,156,156,156,1,181,181,181,1,222,222,222,2,198,198,198,1,173,173,173, + 1,156,156,156,1,206,206,206,1,189,189,189,1,156,156,156,1,222,222,222, + 1,181,181,181,1,156,156,156,1,222,222,222,1,189,189,189,1,165,165,165, + 1,173,173,173,1,214,214,214,1,222,222,222,2,156,156,156,1,189,189,189, + 1,222,222,222,2,214,214,214,1,165,165,165,1,214,214,214,1,222,222,222, + 5,156,156,156,1,181,181,181,1,189,189,189,1,148,148,148,2,206,206,206, + 1,165,165,165,2,214,214,214,1,165,165,165,1,198,198,198,1,148,148,148, + 1,181,181,181,1,189,189,189,1,165,165,165,1,198,198,198,1,173,173,173, + 1,156,156,156,1,165,165,165,1,181,181,181,1,156,156,156,1,181,181,181, + 1,222,222,222,6,206,206,206,1,214,214,214,1,189,189,189,1,156,156,156, + 1,181,181,181,1,156,156,156,2,214,214,214,1,198,198,198,1,148,148,148, + 1,181,181,181,1,189,189,189,1,156,156,156,1,165,165,165,1,181,181,181, + 1,156,156,156,1,189,189,189,1,173,173,173,1,189,189,189,1,156,156,156, + 1,165,165,165,1,206,206,206,1,173,173,173,1,156,156,156,1,173,173,173, + 1,156,156,156,1,173,173,173,1,206,206,206,2,222,222,222,2,206,206,206, + 1,156,156,156,2,165,165,165,1,181,181,181,1,156,156,156,1,214,214,214, + 1,222,222,222,1,181,181,181,1,206,206,206,2,181,181,181,2,148,148,148, + 1,189,189,189,1,181,181,181,2,173,173,173,1,181,181,181,1,165,165,165, + 1,181,181,181,1,222,222,222,1,173,173,173,1,198,198,198,1,222,222,222, + 1,189,189,189,1,181,181,181,1,148,148,148,1,173,173,173,1,165,165,165, + 1,181,181,181,1,222,222,222,1,156,156,156,1,173,173,173,1,189,189,189, + 1,214,214,214,1,222,222,222,6,189,189,189,1,156,156,156,1,222,222,222, + 1,206,206,206,1,156,156,156,1,189,189,189,2,181,181,181,1,222,222,222, + 1,181,181,181,1,156,156,156,1,222,222,222,7,198,198,198,1,173,173,173, + 2,148,148,148,1,181,181,181,2,156,156,156,1,181,181,181,1,206,206,206, + 2,222,222,222,2,206,206,206,1,214,214,214,1,198,198,198,1,165,165,165, + 1,214,214,214,1,181,181,181,1,173,173,173,1,189,189,189,2,148,148,148, + 1,206,206,206,1,181,181,181,1,148,148,148,1,222,222,222,1,214,214,214, + 1,222,222,222,2,206,206,206,2,189,189,189,1,156,156,156,1,165,165,165, + 1,148,148,148,1,189,189,189,1,222,222,222,1,173,173,173,1,189,189,189, + 1,148,148,148,1,173,173,173,1,165,165,165,1,181,181,181,1,189,189,189, + 1,173,173,173,1,206,206,206,1,189,189,189,1,165,165,165,1,148,148,148, + 1,181,181,181,1,173,173,173,2,165,165,165,3,173,173,173,1,181,181,181, + 1,206,206,206,1,165,165,165,1,198,198,198,1,181,181,181,1,165,165,165, + 1,156,156,156,1,173,173,173,2,165,165,165,1,206,206,206,1,222,222,222, + 5,198,198,198,1,156,156,156,2,165,165,165,4,173,173,173,1,165,165,165, + 1,189,189,189,1,148,148,148,1,189,189,189,1,148,148,148,1,189,189,189, + 1,148,148,148,1,181,181,181,1,156,156,156,1,181,181,181,1,156,156,156, + 1,189,189,189,1,156,156,156,1,181,181,181,2,206,206,206,1,222,222,222, + 4,198,198,198,1,206,206,206,1,222,222,222,3,156,156,156,1,189,189,189, + 1,214,214,214,1,189,189,189,1,198,198,198,1,173,173,173,1,181,181,181, + 1,189,189,189,1,198,198,198,1,173,173,173,1,206,206,206,1,181,181,181, + 1,165,165,165,1,214,214,214,1,148,148,148,1,156,156,156,1,214,214,214, + 1,189,189,189,1,206,206,206,1,222,222,222,1,148,148,148,1,181,181,181, + 1,222,222,222,3,198,198,198,1,214,214,214,1,165,165,165,1,173,173,173, + 1,222,222,222,3,156,156,156,1,181,181,181,1,222,222,222,1,214,214,214, + 1,173,173,173,2,206,206,206,1,181,181,181,2,156,156,156,1,222,222,222, + 1,181,181,181,1,156,156,156,1,189,189,189,2,198,198,198,1,156,156,156, + 1,198,198,198,1,222,222,222,2,165,165,165,1,189,189,189,1,222,222,222, + 2,206,206,206,1,181,181,181,1,206,206,206,1,181,181,181,1,156,156,156, + 1,214,214,214,1,222,222,222,2,181,181,181,1,156,156,156,1,214,214,214, + 1,181,181,181,1,173,173,173,1,156,156,156,2,148,148,148,1,156,156,156, + 1,148,148,148,1,222,222,222,1,181,181,181,1,173,173,173,1,148,148,148, + 3,156,156,156,1,165,165,165,1,198,198,198,2,165,165,165,1,222,222,222, + 3,189,189,189,1,148,148,148,1,222,222,222,1,206,206,206,1,165,165,165, + 1,189,189,189,1,222,222,222,2,181,181,181,1,156,156,156,1,181,181,181, + 1,156,156,156,1,206,206,206,1,222,222,222,3,189,189,189,1,156,156,156, + 1,222,222,222,1,181,181,181,1,148,148,148,1,222,222,222,4,181,181,181, + 1,165,165,165,1,189,189,189,1,148,148,148,1,222,222,222,3,148,148,148, + 1,181,181,181,1,222,222,222,2,156,156,156,1,181,181,181,1,222,222,222, + 2,189,189,189,2,165,165,165,1,198,198,198,1,222,222,222,3,165,165,165, + 1,214,214,214,1,173,173,173,1,198,198,198,1,156,156,156,1,181,181,181, + 1,173,173,173,1,189,189,189,1,222,222,222,3,156,156,156,1,181,181,181, + 1,156,156,156,1,222,222,222,2,206,206,206,1,173,173,173,1,198,198,198, + 1,222,222,222,2,181,181,181,1,148,148,148,1,222,222,222,2,181,181,181, + 1,173,173,173,1,198,198,198,1,222,222,222,4,198,198,198,1,214,214,214, + 1,148,148,148,1,189,189,189,1,156,156,156,1,189,189,189,1,206,206,206, + 2,222,222,222,4,156,156,156,2,206,206,206,1,222,222,222,1,181,181,181, + 1,156,156,156,1,222,222,222,3,189,189,189,1,156,156,156,1,222,222,222, + 1,198,198,198,1,173,173,173,1,198,198,198,1,181,181,181,2,189,189,189, + 1,181,181,181,3,206,206,206,1,181,181,181,2,165,165,165,1,214,214,214, + 1,189,189,189,1,181,181,181,2,189,189,189,1,181,181,181,2,189,189,189, + 1,173,173,173,1,156,156,156,1,222,222,222,1,181,181,181,1,148,148,148, + 1,222,222,222,3,214,214,214,1,181,181,181,1,198,198,198,1,148,148,148, + 1,156,156,156,1,148,148,148,2,156,156,156,1,148,148,148,4,198,198,198, + 1,206,206,206,1,165,165,165,1,181,181,181,1,222,222,222,1,148,148,148, + 1,156,156,156,4,148,148,148,3,189,189,189,1,181,181,181,1,165,165,165, + 1,181,181,181,1,222,222,222,2,214,214,214,1,222,222,222,1,156,156,156, + 1,173,173,173,1,148,148,148,1,206,206,206,1,222,222,222,8,198,198,198, + 1,173,173,173,1,156,156,156,1,222,222,222,9,181,181,181,1,189,189,189, + 1,173,173,173,1,189,189,189,1,222,222,222,1,198,198,198,2,222,222,222, + 1,148,148,148,1,156,156,156,1,206,206,206,1,222,222,222,4,165,165,165, + 1,198,198,198,1,222,222,222,3,165,165,165,2,189,189,189,1,198,198,198, + 1,222,222,222,3,165,165,165,1,198,198,198,1,222,222,222,4,165,165,165, + 1,173,173,173,1,181,181,181,1,222,222,222,1,156,156,156,1,214,214,214, + 1,148,148,148,1,173,173,173,1,189,189,189,2,181,181,181,2,173,173,173, + 1,165,165,165,2,156,156,156,2,222,222,222,1,181,181,181,1,165,165,165, + 1,206,206,206,1,181,181,181,1,156,156,156,1,206,206,206,1,198,198,198, + 1,156,156,156,1,165,165,165,3,189,189,189,1,181,181,181,3,198,198,198, + 1,156,156,156,1,189,189,189,1,222,222,222,1,148,148,148,1,165,165,165, + 1,156,156,156,1,148,148,148,1,156,156,156,2,165,165,165,2,189,189,189, + 1,181,181,181,2,198,198,198,1,189,189,189,2,181,181,181,1,222,222,222, + 1,206,206,206,1,156,156,156,1,148,148,148,1,214,214,214,1,181,181,181, + 4,165,165,165,2,148,148,148,1,156,156,156,2,148,148,148,1,181,181,181, + 2,156,156,156,1,206,206,206,1,222,222,222,9,206,206,206,1,165,165,165, + 1,181,181,181,1,222,222,222,3,206,206,206,1,165,165,165,2,222,222,222, + 10,181,181,181,2,19,102,97,99,101,46,102,97,100,101,95,112,111,115,46, + 99,111,117,110,116,2,3,19,102,97,99,101,46,102,97,100,101,95,112,111, + 115,46,105,116,101,109,115,1,2,0,5,0,0,0,0,0,0,0,128,254, + 63,2,1,0,21,102,97,99,101,46,102,97,100,101,95,99,111,108,111,114, + 46,99,111,117,110,116,2,3,21,102,97,99,101,46,102,97,100,101,95,99, + 111,108,111,114,46,105,116,101,109,115,1,4,255,255,255,0,2,0,4,255, + 255,255,0,0,15,102,97,99,101,46,108,111,99,97,108,112,114,111,112,115, + 11,11,102,97,108,95,111,112,116,105,111,110,115,13,102,97,108,95,102,97, + 111,112,97,99,105,116,121,0,8,116,97,98,111,114,100,101,114,2,7,8, + 98,111,117,110,100,115,95,120,3,144,1,8,98,111,117,110,100,115,95,121, + 3,168,0,9,98,111,117,110,100,115,95,99,120,3,132,0,9,98,111,117, + 110,100,115,95,99,121,2,52,8,115,116,97,116,102,105,108,101,7,10,116, + 115,116,97,116,102,105,108,101,49,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,14,0,0,9,116,102,97,99,101,99,111,109,112,11,98,117, + 116,116,111,110,102,97,99,101,49,23,116,101,109,112,108,97,116,101,46,102, + 97,100,101,95,112,111,115,46,99,111,117,110,116,2,2,23,116,101,109,112, + 108,97,116,101,46,102,97,100,101,95,112,111,115,46,105,116,101,109,115,1, + 2,0,2,1,0,25,116,101,109,112,108,97,116,101,46,102,97,100,101,95, + 99,111,108,111,114,46,99,111,117,110,116,2,2,25,116,101,109,112,108,97, + 116,101,46,102,97,100,101,95,99,111,108,111,114,46,105,116,101,109,115,1, + 4,5,0,0,160,4,4,0,0,160,0,23,116,101,109,112,108,97,116,101, + 46,102,97,100,101,95,100,105,114,101,99,116,105,111,110,7,7,103,100,95, + 100,111,119,110,4,108,101,102,116,2,16,3,116,111,112,2,72,0,0,9, + 116,109,97,105,110,109,101,110,117,9,109,97,105,110,109,101,110,117,49,18, + 112,111,112,117,112,102,114,97,109,101,116,101,109,112,108,97,116,101,7,10, + 112,111,112,117,112,102,114,97,109,101,22,112,111,112,117,112,105,116,101,109, + 102,114,97,109,101,116,101,109,112,108,97,116,101,7,14,112,111,112,117,112, + 105,116,101,109,102,114,97,109,101,21,112,111,112,117,112,105,116,101,109,102, + 97,99,101,116,101,109,112,108,97,116,101,7,11,98,117,116,116,111,110,102, + 97,99,101,50,28,112,111,112,117,112,105,116,101,109,102,114,97,109,101,116, + 101,109,112,108,97,116,101,97,99,116,105,118,101,7,14,112,111,112,117,112, + 105,116,101,109,102,114,97,109,101,27,112,111,112,117,112,105,116,101,109,102, + 97,99,101,116,101,109,112,108,97,116,101,97,99,116,105,118,101,7,11,98, + 117,116,116,111,110,102,97,99,101,50,13,102,114,97,109,101,116,101,109,112, + 108,97,116,101,7,13,109,97,105,110,109,101,110,117,102,114,97,109,101,12, + 102,97,99,101,116,101,109,112,108,97,116,101,7,11,98,117,116,116,111,110, + 102,97,99,101,49,17,105,116,101,109,102,114,97,109,101,116,101,109,112,108, + 97,116,101,7,17,109,97,105,110,109,101,110,117,105,116,101,109,102,114,97, + 109,101,16,105,116,101,109,102,97,99,101,116,101,109,112,108,97,116,101,7, + 11,98,117,116,116,111,110,102,97,99,101,50,23,105,116,101,109,102,114,97, + 109,101,116,101,109,112,108,97,116,101,97,99,116,105,118,101,7,17,109,97, + 105,110,109,101,110,117,105,116,101,109,102,114,97,109,101,22,105,116,101,109, + 102,97,99,101,116,101,109,112,108,97,116,101,97,99,116,105,118,101,7,11, + 98,117,116,116,111,110,102,97,99,101,50,18,109,101,110,117,46,115,117,98, + 109,101,110,117,46,99,111,117,110,116,2,4,18,109,101,110,117,46,115,117, + 98,109,101,110,117,46,105,116,101,109,115,14,1,13,115,117,98,109,101,110, + 117,46,99,111,117,110,116,2,4,13,115,117,98,109,101,110,117,46,105,116, + 101,109,115,14,1,13,115,117,98,109,101,110,117,46,99,111,117,110,116,2, + 6,13,115,117,98,109,101,110,117,46,105,116,101,109,115,14,1,7,99,97, + 112,116,105,111,110,6,13,101,119,114,103,113,101,103,32,113,101,119,114,32, + 5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116, + 105,111,110,0,0,1,7,99,97,112,116,105,111,110,6,9,113,101,114,32, + 113,119,101,116,114,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,0,0,1,7,99,97,112,116,105,111,110,6, + 10,117,122,107,109,101,53,54,97,114,101,5,115,116,97,116,101,11,15,97, + 115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,0,1,7,99,97, + 112,116,105,111,110,6,12,119,52,51,53,32,101,114,116,114,104,52,54,5, + 115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105, + 111,110,0,0,1,7,99,97,112,116,105,111,110,6,12,52,119,53,103,98, + 115,103,102,100,98,115,119,5,115,116,97,116,101,11,15,97,115,95,108,111, + 99,97,108,99,97,112,116,105,111,110,0,0,1,7,99,97,112,116,105,111, + 110,6,14,97,101,114,103,97,32,97,101,114,103,51,52,53,32,5,115,116, + 97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110, + 0,0,0,7,99,97,112,116,105,111,110,6,11,38,49,49,49,49,49,49, + 49,49,49,49,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,0,0,1,7,99,97,112,116,105,111,110,6,9, + 38,50,50,50,50,50,50,50,50,5,115,116,97,116,101,11,15,97,115,95, + 108,111,99,97,108,99,97,112,116,105,111,110,0,0,1,7,99,97,112,116, + 105,111,110,6,10,38,51,51,51,51,51,51,51,51,51,5,115,116,97,116, + 101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,0, + 1,7,99,97,112,116,105,111,110,6,11,38,52,52,52,52,52,52,52,52, + 52,52,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97, + 112,116,105,111,110,0,0,0,7,99,97,112,116,105,111,110,6,8,38,65, + 97,97,97,97,97,97,5,115,116,97,116,101,11,15,97,115,95,108,111,99, + 97,108,99,97,112,116,105,111,110,0,0,1,7,99,97,112,116,105,111,110, + 6,7,38,66,98,98,98,98,98,5,115,116,97,116,101,11,15,97,115,95, + 108,111,99,97,108,99,97,112,116,105,111,110,0,0,1,7,99,97,112,116, + 105,111,110,6,9,38,67,99,99,99,99,99,99,99,5,115,116,97,116,101, + 11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,0,1, + 7,99,97,112,116,105,111,110,6,6,38,68,100,100,100,100,5,115,116,97, + 116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0, + 0,0,4,108,101,102,116,2,24,3,116,111,112,2,40,0,0,10,116,102, + 114,97,109,101,99,111,109,112,13,109,97,105,110,109,101,110,117,102,114,97, + 109,101,15,116,101,109,112,108,97,116,101,46,108,101,118,101,108,105,2,1, + 4,108,101,102,116,3,144,0,3,116,111,112,2,36,0,0,10,116,102,114, + 97,109,101,99,111,109,112,17,109,97,105,110,109,101,110,117,105,116,101,109, + 102,114,97,109,101,15,116,101,109,112,108,97,116,101,46,108,101,118,101,108, + 111,2,255,15,116,101,109,112,108,97,116,101,46,108,101,118,101,108,105,2, + 1,19,116,101,109,112,108,97,116,101,46,102,114,97,109,101,119,105,100,116, + 104,2,2,19,116,101,109,112,108,97,116,101,46,99,111,108,111,114,102,114, + 97,109,101,4,3,0,0,128,20,116,101,109,112,108,97,116,101,46,102,114, + 97,109,101,105,95,108,101,102,116,2,2,19,116,101,109,112,108,97,116,101, + 46,102,114,97,109,101,105,95,116,111,112,2,2,21,116,101,109,112,108,97, + 116,101,46,102,114,97,109,101,105,95,114,105,103,104,116,2,2,22,116,101, + 109,112,108,97,116,101,46,102,114,97,109,101,105,95,98,111,116,116,111,109, + 2,2,4,108,101,102,116,3,32,1,3,116,111,112,2,36,0,0,9,116, + 102,97,99,101,99,111,109,112,11,98,117,116,116,111,110,102,97,99,101,50, + 23,116,101,109,112,108,97,116,101,46,102,97,100,101,95,112,111,115,46,99, + 111,117,110,116,2,2,23,116,101,109,112,108,97,116,101,46,102,97,100,101, + 95,112,111,115,46,105,116,101,109,115,1,2,0,2,1,0,25,116,101,109, + 112,108,97,116,101,46,102,97,100,101,95,99,111,108,111,114,46,99,111,117, + 110,116,2,2,25,116,101,109,112,108,97,116,101,46,102,97,100,101,95,99, + 111,108,111,114,46,105,116,101,109,115,1,4,5,0,0,160,4,4,0,0, + 160,0,23,116,101,109,112,108,97,116,101,46,102,97,100,101,95,100,105,114, + 101,99,116,105,111,110,7,5,103,100,95,117,112,4,108,101,102,116,2,16, + 3,116,111,112,2,104,0,0,10,116,102,114,97,109,101,99,111,109,112,14, + 112,111,112,117,112,105,116,101,109,102,114,97,109,101,15,116,101,109,112,108, + 97,116,101,46,108,101,118,101,108,111,2,255,15,116,101,109,112,108,97,116, + 101,46,108,101,118,101,108,105,2,1,19,116,101,109,112,108,97,116,101,46, + 102,114,97,109,101,105,95,116,111,112,2,1,22,116,101,109,112,108,97,116, + 101,46,102,114,97,109,101,105,95,98,111,116,116,111,109,2,1,4,108,101, + 102,116,3,186,1,3,116,111,112,2,63,0,0,10,116,102,114,97,109,101, + 99,111,109,112,10,112,111,112,117,112,102,114,97,109,101,15,116,101,109,112, + 108,97,116,101,46,108,101,118,101,108,111,2,2,19,116,101,109,112,108,97, + 116,101,46,102,114,97,109,101,119,105,100,116,104,2,1,4,108,101,102,116, + 3,187,1,3,116,111,112,2,35,0,0,9,116,115,116,97,116,102,105,108, + 101,10,116,115,116,97,116,102,105,108,101,49,8,102,105,108,101,110,97,109, + 101,6,10,115,116,97,116,117,115,46,115,116,97,4,108,101,102,116,2,19, + 3,116,111,112,3,195,0,0,0,10,116,105,109,97,103,101,108,105,115,116, + 4,105,109,108,105,5,119,105,100,116,104,2,4,6,104,101,105,103,104,116, + 2,4,7,111,112,116,105,111,110,115,11,0,5,99,111,117,110,116,2,51, + 4,108,101,102,116,3,192,1,3,116,111,112,2,112,5,105,109,97,103,101, + 10,84,11,0,0,0,0,0,0,0,0,0,0,32,0,0,0,32,0,0, + 0,32,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,213,231,233, + 1,206,223,228,1,202,221,225,1,201,220,224,1,202,221,225,1,116,60,0, + 1,252,253,253,2,204,222,227,1,126,77,22,1,202,199,191,1,214,223,226, + 1,213,222,225,4,205,215,219,1,189,189,182,1,126,77,22,1,230,241,243, + 1,218,226,228,1,212,221,224,1,116,60,0,1,226,238,241,1,202,221,225, + 1,203,222,226,1,206,223,228,1,213,231,233,1,201,220,224,4,206,223,228, + 1,208,225,230,1,168,149,122,1,131,87,37,1,202,221,225,1,116,60,0, + 1,252,253,253,2,207,225,229,1,160,135,102,1,147,113,74,1,180,174,163, + 1,197,208,214,4,182,183,177,1,144,110,72,1,162,139,106,1,235,244,245, + 1,218,226,228,1,212,221,224,1,116,60,0,1,226,238,241,1,126,77,22, + 1,160,136,103,1,210,228,232,2,116,60,0,4,203,222,226,1,168,149,122, + 1,162,125,85,1,221,207,192,1,202,221,225,1,116,60,0,1,252,253,253, + 2,212,230,233,1,216,233,236,1,170,153,125,1,131,87,37,1,116,60,0, + 4,126,77,22,1,164,140,108,1,234,244,244,1,238,246,247,1,218,226,228, + 1,212,221,224,1,116,60,0,1,226,238,241,1,232,223,213,1,162,125,85, + 1,169,149,123,1,213,231,233,1,255,255,255,4,203,222,226,1,131,87,37, + 1,220,206,191,1,254,254,254,1,202,221,225,1,116,60,0,1,252,253,253, + 2,218,234,237,1,223,237,239,1,231,241,243,1,237,245,246,1,240,246,248, + 4,242,247,248,1,242,248,249,1,241,247,248,1,222,237,239,1,218,226,228, + 1,212,221,224,1,116,60,0,1,226,238,241,1,253,254,254,1,219,206,191, + 1,131,87,37,1,218,234,237,1,254,254,254,4,213,231,233,1,206,223,228, + 1,202,221,225,1,201,220,224,1,202,221,225,1,116,60,0,1,245,211,186, + 1,246,211,186,1,204,222,227,1,126,77,22,1,228,173,137,8,126,77,22, + 1,230,241,243,1,228,173,137,2,116,60,0,1,226,238,241,1,202,221,225, + 1,203,222,226,1,206,223,228,1,213,231,233,1,201,220,224,4,206,223,228, + 1,208,225,230,1,168,149,122,1,131,87,37,1,202,221,225,1,116,60,0, + 1,245,211,186,1,246,211,186,1,207,225,229,1,160,135,102,1,133,77,39, + 1,193,125,77,1,238,130,105,5,133,77,39,1,162,139,106,1,235,244,245, + 1,228,173,137,2,116,60,0,1,226,238,241,1,126,77,22,1,160,136,103, + 1,210,228,232,2,116,60,0,4,203,222,226,1,168,149,122,1,133,77,39, + 1,255,231,206,1,202,221,225,1,116,60,0,1,245,211,186,1,246,211,186, + 1,212,230,233,1,216,233,236,1,170,153,125,1,131,87,37,1,116,60,0, + 4,126,77,22,1,164,140,108,1,234,244,244,1,238,246,247,1,228,173,137, + 2,116,60,0,1,226,238,241,1,255,231,206,1,133,77,39,1,169,149,123, + 1,213,231,233,1,255,231,206,4,203,222,226,1,131,87,37,1,246,212,188, + 2,202,221,225,1,116,60,0,1,245,211,186,1,246,211,186,1,218,234,237, + 1,223,237,239,1,231,241,243,1,237,245,246,1,239,246,247,4,242,247,248, + 1,242,248,249,1,241,247,248,1,222,237,239,1,228,173,137,2,116,60,0, + 1,226,238,241,1,246,212,188,2,131,87,37,1,218,234,237,1,246,212,188, + 4,213,231,233,1,206,223,228,1,202,221,225,1,201,220,224,1,203,222,226, + 1,116,60,0,1,207,216,218,1,215,222,224,1,204,222,227,1,126,77,22, + 1,199,197,188,1,222,230,230,1,227,233,234,4,218,211,202,1,210,206,196, + 1,126,77,22,1,230,241,243,1,223,229,230,2,116,60,0,1,226,238,241, + 1,202,221,225,1,203,222,226,1,206,223,228,1,213,231,233,1,201,220,224, + 4,206,223,228,1,208,225,230,1,168,149,122,1,131,87,37,1,203,222,226, + 1,116,60,0,1,207,216,218,1,215,222,224,1,207,225,229,1,160,135,102, + 1,152,117,77,1,203,193,178,1,238,241,242,4,218,211,202,1,155,119,79, + 1,162,139,106,1,235,244,245,1,223,229,230,2,116,60,0,1,226,238,241, + 1,126,77,22,1,160,136,103,1,210,228,232,2,116,60,0,4,203,222,226, + 1,168,149,122,1,142,109,70,1,172,168,157,1,203,222,226,1,116,60,0, + 1,207,216,218,1,215,222,224,1,212,230,233,1,216,233,236,1,170,153,125, + 1,131,87,37,1,116,60,0,4,126,77,22,1,164,140,108,1,234,244,244, + 1,238,246,247,1,223,229,230,2,116,60,0,1,226,238,241,1,183,183,177, + 1,146,112,73,1,169,149,123,1,213,231,233,1,193,204,209,4,203,222,226, + 1,131,87,37,1,177,171,160,1,198,208,214,1,203,222,226,1,116,60,0, + 1,207,216,218,1,215,222,224,1,218,234,237,1,223,237,239,1,231,241,243, + 1,237,245,246,1,240,247,248,4,242,247,248,1,242,248,249,1,241,247,248, + 1,222,237,239,1,223,229,230,2,116,60,0,1,226,238,241,1,206,215,219, + 1,189,181,169,1,131,87,37,1,218,234,237,1,207,216,220,4,207,227,229, + 1,187,206,213,1,178,200,208,1,177,199,205,1,178,200,208,1,116,60,0, + 1,154,223,254,1,121,210,252,1,184,204,212,1,125,76,20,1,73,181,239, + 1,48,178,248,1,48,179,248,4,48,178,248,1,71,181,237,1,125,76,20, + 1,245,249,250,1,51,180,248,1,53,180,248,1,116,60,0,1,238,245,247, + 1,178,200,208,1,182,203,209,1,187,206,213,1,207,227,229,1,162,187,196, + 4,187,206,213,1,200,217,225,1,159,134,101,1,130,84,34,1,178,200,208, + 1,116,60,0,1,154,223,254,1,121,210,252,1,191,210,218,1,153,123,86, + 1,113,134,132,1,0,151,229,6,111,132,131,1,157,130,94,1,250,252,252, + 1,51,180,248,1,53,180,248,1,116,60,0,1,238,245,247,1,125,76,20, + 1,153,124,87,1,204,223,227,1,198,219,224,1,116,60,0,4,182,203,209, + 1,159,134,101,1,161,158,141,1,210,232,239,1,178,200,208,1,116,60,0, + 1,154,223,254,1,121,210,252,1,204,224,227,1,216,233,236,1,162,139,106, + 1,130,84,34,1,116,60,0,4,125,76,20,1,159,132,97,1,240,248,248, + 1,252,253,254,1,51,180,248,1,53,180,248,1,116,60,0,1,238,245,247, + 1,211,237,248,1,161,158,141,1,160,133,101,1,207,227,229,1,207,240,255, + 4,182,203,209,1,130,84,34,1,173,220,238,1,121,210,252,1,178,200,208, + 1,116,60,0,1,154,223,254,1,121,210,252,1,220,236,239,1,234,243,244, + 1,246,249,251,1,251,253,253,1,255,255,255,4,254,254,254,2,253,254,254, + 1,232,242,244,1,51,180,248,1,53,180,248,1,116,60,0,1,238,245,247, + 1,121,210,252,1,173,220,238,1,130,84,34,1,222,236,239,1,137,216,253, + 4,207,227,229,1,187,206,213,1,178,200,208,1,177,199,205,1,178,200,208, + 1,116,60,0,1,154,223,254,1,121,210,252,1,184,204,212,1,125,76,20, + 1,73,181,239,1,48,178,248,1,48,179,248,4,48,178,248,1,71,181,237, + 1,125,76,20,1,245,249,250,1,51,180,248,1,53,180,248,1,116,60,0, + 1,238,245,247,1,178,200,208,1,182,203,209,1,187,206,213,1,207,227,229, + 1,162,187,196,4,187,206,213,1,200,217,225,1,159,134,101,1,130,84,34, + 1,178,200,208,1,116,60,0,1,154,223,254,1,121,210,252,1,191,210,218, + 1,153,123,86,1,113,134,132,1,0,151,229,6,111,132,131,1,157,130,94, + 1,250,252,252,1,51,180,248,1,53,180,248,1,116,60,0,1,238,245,247, + 1,125,76,20,1,153,124,87,1,204,223,227,1,198,219,224,1,116,60,0, + 4,182,203,209,1,159,134,101,1,161,158,141,1,210,232,239,1,178,200,208, + 1,116,60,0,1,154,223,254,1,121,210,252,1,204,224,227,1,216,233,236, + 1,162,139,106,1,130,84,34,1,116,60,0,4,125,76,20,1,159,132,97, + 1,240,248,248,1,252,253,254,1,51,180,248,1,53,180,248,1,116,60,0, + 1,238,245,247,1,211,237,248,1,161,158,141,1,160,133,101,1,207,227,229, + 1,207,240,255,4,182,203,209,1,130,84,34,1,173,220,238,1,121,210,252, + 1,178,200,208,1,116,60,0,1,154,223,254,1,121,210,252,1,220,236,239, + 1,234,243,244,1,246,249,251,1,251,253,253,1,255,255,255,4,254,254,254, + 2,253,254,254,1,232,242,244,1,51,180,248,1,53,180,248,1,116,60,0, + 1,238,245,247,1,121,210,252,1,173,220,238,1,130,84,34,1,222,236,239, + 1,137,216,253,4,213,231,233,1,206,223,228,1,202,221,225,1,201,220,224, + 1,203,222,226,1,116,60,0,1,207,216,218,1,215,222,224,1,204,222,227, + 1,126,77,22,1,199,197,188,1,222,230,230,1,227,233,234,4,218,211,202, + 1,210,206,196,1,126,77,22,1,230,241,243,1,223,229,230,2,116,60,0, + 1,226,238,241,1,202,221,225,1,203,222,226,1,206,223,228,1,213,231,233, + 1,201,220,224,4,206,223,228,1,208,225,230,1,168,149,122,1,131,87,37, + 1,203,222,226,1,116,60,0,1,207,216,218,1,215,222,224,1,207,225,229, + 1,160,135,102,1,152,117,77,1,203,193,178,1,238,241,242,4,218,211,202, + 1,155,119,79,1,162,139,106,1,235,244,245,1,223,229,230,2,116,60,0, + 1,226,238,241,1,126,77,22,1,160,136,103,1,210,228,232,2,116,60,0, + 4,203,222,226,1,168,149,122,1,142,109,70,1,172,168,157,1,203,222,226, + 1,116,60,0,1,207,216,218,1,215,222,224,1,212,230,233,1,216,233,236, + 1,170,153,125,1,131,87,37,1,116,60,0,4,126,77,22,1,164,140,108, + 1,234,244,244,1,238,246,247,1,223,229,230,2,116,60,0,1,226,238,241, + 1,183,183,177,1,146,112,73,1,169,149,123,1,213,231,233,1,193,204,209, + 4,203,222,226,1,131,87,37,1,177,171,160,1,198,208,214,1,203,222,226, + 1,116,60,0,1,207,216,218,1,215,222,224,1,218,234,237,1,223,237,239, + 1,231,241,243,1,237,245,246,1,240,247,248,4,242,247,248,1,242,248,249, + 1,241,247,248,1,222,237,239,1,223,229,230,2,116,60,0,1,226,238,241, + 1,206,215,219,1,189,181,169,1,131,87,37,1,218,234,237,1,207,216,220, + 4,201,220,224,4,255,255,255,8,201,220,224,4,202,221,225,1,203,222,226, + 1,206,223,228,1,213,231,233,1,228,173,137,2,116,60,0,1,226,238,241, + 1,228,173,137,2,126,77,22,1,230,241,243,1,228,173,137,4,116,60,0, + 4,255,255,255,8,116,60,0,4,126,77,22,1,160,136,103,1,210,228,232, + 2,228,173,137,2,116,60,0,1,226,238,241,1,238,130,105,1,133,77,39, + 1,162,139,106,1,235,244,245,1,238,130,105,4,255,231,206,4,255,255,255, + 8,255,231,206,5,133,77,39,1,169,149,123,1,213,231,233,1,228,173,137, + 2,116,60,0,1,226,238,241,1,126,77,22,1,164,140,108,1,234,244,244, + 1,238,246,247,1,116,60,0,4,246,212,188,4,255,255,255,8,246,212,188, + 6,131,87,37,1,218,234,237,1,228,173,137,2,116,60,0,1,226,238,241, + 1,242,247,248,1,242,248,249,1,241,247,248,1,222,237,239,1,239,246,247, + 4,204,222,227,1,126,77,22,1,228,173,137,2,202,221,225,1,116,60,0, + 1,245,211,186,1,246,211,186,1,213,231,233,1,206,223,228,1,202,221,225, + 1,201,220,224,1,208,208,208,2,206,206,206,1,119,119,119,1,33,33,33, + 1,6,6,6,1,37,37,37,1,144,144,144,1,208,208,208,2,0,0,0, + 1,208,208,208,3,0,0,0,1,208,208,208,3,0,0,0,1,208,208,208, + 1,207,225,229,1,160,135,102,1,133,77,39,1,193,125,77,1,202,221,225, + 1,116,60,0,1,245,211,186,1,246,211,186,1,206,223,228,1,208,225,230, + 1,168,149,122,1,131,87,37,1,208,208,208,20,212,230,233,1,216,233,236, + 1,170,153,125,1,131,87,37,1,202,221,225,1,116,60,0,1,245,211,186, + 1,246,211,186,1,203,222,226,1,168,149,122,1,133,77,39,1,255,231,206, + 1,208,208,208,20,218,234,237,1,223,237,239,1,231,241,243,1,237,245,246, + 1,202,221,225,1,116,60,0,1,245,211,186,1,246,211,186,1,203,222,226, + 1,131,87,37,1,246,212,188,2,208,208,208,9,255,255,255,1,128,128,128, + 1,208,208,208,9,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tmainfo,''); +end. diff --git a/mseide-msegui/apps/i18ndemo/de/dummy.txt b/mseide-msegui/apps/i18ndemo/de/dummy.txt new file mode 100644 index 0000000..53e3a6e --- /dev/null +++ b/mseide-msegui/apps/i18ndemo/de/dummy.txt @@ -0,0 +1 @@ +Placeholder for git. diff --git a/mseide-msegui/apps/i18ndemo/fr/dummy.txt b/mseide-msegui/apps/i18ndemo/fr/dummy.txt new file mode 100644 index 0000000..53e3a6e --- /dev/null +++ b/mseide-msegui/apps/i18ndemo/fr/dummy.txt @@ -0,0 +1 @@ +Placeholder for git. diff --git a/mseide-msegui/apps/i18ndemo/i18ndemo.pas b/mseide-msegui/apps/i18ndemo/i18ndemo.pas new file mode 100644 index 0000000..debd6ed --- /dev/null +++ b/mseide-msegui/apps/i18ndemo/i18ndemo.pas @@ -0,0 +1,27 @@ +{ MSEide Copyright (c) 1999-2011 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +program i18ndemo; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifdef FPC} + {$ifdef mswindows}{$apptype gui}{$endif} +{$endif} +uses + {$ifdef FPC}{$ifdef unix}cthreads,{$endif}{$endif}msegui,mseforms,main; +begin + application.createform(tmainfo,mainfo); + application.run; +end. diff --git a/mseide-msegui/apps/i18ndemo/i18ndemo.prj b/mseide-msegui/apps/i18ndemo/i18ndemo.prj new file mode 100644 index 0000000..6ae5d32 --- /dev/null +++ b/mseide-msegui/apps/i18ndemo/i18ndemo.prj @@ -0,0 +1,1200 @@ +[componentpalette] +order0=0 +order1=0 +order2=0 +order3=0 +order4=0 +order5=0 +order6=0 +order7=0 +order8=0 +order9=0 +order10=0 +order11=0 +order12=0 +order13=0 +order14=0 +order15=0 +order16=0 +[projectoptions] +projectdir=/D:/mse/packs/standard/git/mseide-msegui/apps/i18ndemo +projectfilename=/D:/mse/packs/standard/git/mseide-msegui/apps/i18ndemo/i18ndemo.prj +finddialog=8 + [finddialogfo.selectedonly] + value=0 + [finddialogfo] + stackedunder= + x=319 + y=205 + cx=371 + cy=93 +options=128 + [projectoptionsfo.toolshortcuts] + dropdowncolwidths=3 + 70 + 70 + 70 + [projectoptionsfo.twidgetgrid3] + propcolwidthref=723 + sortdescend0=0 + sortdescend1=0 + sortdescend2=0 + sortdescend3=0 + width4=97 + sortdescend4=0 + width5=78 + sortdescend5=0 + width6=50 + sortdescend6=0 + width7=50 + sortdescend7=0 + width8=99 + sortdescend8=0 + width9=295 + sortdescend9=0 + [projectoptionsfo.twidgetgrid4] + propcolwidthref=549 + width0=96 + sortdescend0=0 + sortdescend1=0 + width2=73 + sortdescend2=0 + width3=263 + sortdescend3=0 + width4=276 + sortdescend4=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=15 + [projectoptionsfo.newfile] + firsttab=0 + index=0 + [projectoptionsfo.fontaliasgrid] + propcolwidthref=386 + width0=98 + sortdescend0=0 + width1=375 + sortdescend1=0 + width2=50 + sortdescend2=0 + width3=50 + sortdescend3=0 + width4=50 + sortdescend4=0 + width5=50 + sortdescend5=0 + width6=70 + sortdescend6=0 + [projectoptionsfo.macrosplitter] + x=0 + y=122 + xprop=1 + yprop=0.24084778420039 + [projectoptionsfo.macrogrid] + propcolwidthref=530 + sortdescend0=0 + sortdescend1=0 + sortdescend2=0 + sortdescend3=0 + sortdescend4=0 + sortdescend5=0 + width6=146 + sortdescend6=0 + width7=518 + sortdescend7=0 + [projectoptionsfo.makeoptionsgrid] + propcolwidthref=619 + values0=4 + + + + + width0=57 + sortdescend0=0 + sortdescend1=0 + sortdescend2=0 + sortdescend3=0 + sortdescend4=0 + sortdescend5=0 + sortdescend6=0 + values7=4 + -l -Mobjfpc -Sh -Fcutf8 + -gl -O- + -B + -O2 -XX -Xs -CX + sortdescend7=0 + [projectoptionsfo.makegroupbox] + firsttab=0 + index=1 + [projectoptionsfo.exceptionsgrid] + propcolwidthref=707 + width0=47 + sortdescend0=0 + width1=701 + sortdescend1=0 + [projectoptionsfo.ttabwidget1] + firsttab=0 + index=0 + [projectoptionsfo.filefiltergrid] + propcolwidthref=615 + width0=112 + sortdescend0=0 + width1=608 + sortdescend1=0 + [projectoptionsfo.ttabwidget2] + firsttab=0 + index=0 + [projectoptionsfo.ttabwidget3] + firsttab=0 + index=0 + [projectoptionsfo.tabwidget] + firsttab=0 + index=2 + [projectoptionsfo] + stackedunder= + x=28 + y=159 + cx=756 + cy=568 +settings=14 + [settingsfo.macrogrid] + propcolwidthref=524 + width0=149 + sortdescend0=0 + width1=368 + sortdescend1=0 + [settingsfo] + x=100 + y=106 + cx=570 + cy=570 + wsize=0 + active=1 + visible=1 +sourcefilemasks=3 + "*.pas" "*.dpr" "*.lpr" "*.pp" "*.inc" + "*.c" "*.cc" "*.h" + "*.mfm" +syntaxdeffiles=3 + ${SYNTAXDEFDIR}pascal.sdef + ${SYNTAXDEFDIR}cpp.sdef + ${SYNTAXDEFDIR}objecttext.sdef +filemasknames=3 + Source + Forms + All Files +filemasks=3 + "*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + *.mfm + * +codetemplatedirs=1 + ${TEMPLATEDIR} +showgrid=1 +snaptogrid=1 +moveonfirstclick=1 +noformdesignerdocking=0 +componenthints=1 +gridsizex=8 +gridsizey=8 +autoindent=1 +blockindent=1 +linenumberson=0 +rightmarginon=1 +rightmarginchars=80 +scrollheight=0 +tabstops=4 +spacetabs=0 +showtabs=0 +tabindent=0 +editfontname=mseide_source +editfontheight=0 +editfontwidth=0 +editfontextraspace=0 +editfontcolor=-1879048183 +editbkcolor=-1879048186 +statementcolor=14745599 +pairmarkcolor=-2147483642 +pairmaxrowcount=100 +editfontantialiased=1 +editmarkbrackets=1 +editmarkpairwords=0 +backupfilecount=2 +encoding=1 +eolstyle=1 +trimtrailingwhitespace=0 +debugcommand=${DEBUGGER} +debugoptions= +debugtarget= +runcommand= +xtermcommand=xterm -S${PTSN}/${PTSH} +remoteconnection= +uploadcommand= +gdbprocessor=auto +gdbservercommand= +gdbservercommandattach= +beforeconnect= +afterconnect= +beforeload= +afterload= +beforerun= +sourcebase= +sourcedirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ + ./ +defines=0 +progparameters= +progworkingdirectory= +envvarnames=0 +envvarvalues=0 +defineson=0 +stoponexception=0 +valuehints=1 +activateonbreak=1 +raiseonbreak=1 +showconsole=0 +externalconsole=0 +settty=1 +gdbdownload=0 +downloadalways=0 +startupbkpt=0 +startupbkpton=0 +gdbsimulator=0 +gdbserverstartonce=0 +gdbloadtimeout= +gdbserverwait=0 +nogdbserverexit=0 +gdbservertty=0 +exceptclassnames=1 + EconvertError +exceptignore=1 + 0 +nodebugbeginend=0 +fpcgdbworkaround=1 +mainfile=i18ndemo.pas +targetfile=i18ndemo${EXEEXT} +makecommand=${COMPILER} +makedir= +unitdirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}kernel/ + ${MSELIBDIR}*/ +unitpref=-Fu +incpref=-Fi +libpref=-Fl +objpref=-Fo +targpref=-o +befcommand=0 +aftcommand=0 +makeoptions=4 + -l -Mobjfpc -Sh -Fcutf8 + -gl -O- + -B + -O2 -XX -Xs -CX +reversepathorder=0 +makeoptpurpose=0 +befcommandon=0 +makeoptionson=4 + 63 + 31 + 34 + 32 +aftcommandon=0 +unitdirson=3 + 65599 + 196671 + 65599 +uid=0 +macroon=0 +macronames=0 +macrovalues=0 +groupcomments=6 + + + + + + +fontalias=0 +fontnames=0 +fontancestors=0 +fontoptions=0 +fontheights=0 +fontwidths=0 +fontxscales=0 +usercolors=30 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +usercolorcomment=30 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +formatmacronames=0 +formatmacrovalues=0 +scriptbeforecopy= +scriptaftercopy= +newprojectfiles=4 + ${TEMPLATEDIR}default/project.pas + ${TEMPLATEDIR}default/main.pas + ${TEMPLATEDIR}default/main.mfm + ${TEMPLATEDIR}default/main_mfm.pas +newprojectfilesdest=4 + ${%PROJECTNAME%}.pas + + + +newfinames=3 + Program + Unit + Textfile +newfifilters=3 + "*.pas" "*.pp" + "*.pas" "*.pp" + +newfiexts=3 + pas + pas + +newfisources=3 + ${TEMPLATEDIR}default/program.pas + ${TEMPLATEDIR}default/unit.pas + +newfonames=11 + Mainform + Simple Form + Docking Form + Datamodule + Subform + Scrollboxform + Tabform + Dockpanel + Report + Scriptform + Inherited Form +newfonamebases=11 + form + form + form + module + form + form + form + form + report + script + form +newfosources=11 + ${TEMPLATEDIR}default/mainform.pas + ${TEMPLATEDIR}default/simpleform.pas + ${TEMPLATEDIR}default/dockingform.pas + ${TEMPLATEDIR}default/datamodule.pas + ${TEMPLATEDIR}default/subform.pas + ${TEMPLATEDIR}default/scrollboxform.pas + ${TEMPLATEDIR}default/tabform.pas + ${TEMPLATEDIR}default/dockpanelform.pas + ${TEMPLATEDIR}default/report.pas + ${TEMPLATEDIR}default/pascform.pas + ${TEMPLATEDIR}default/inheritedform.pas +newfoforms=11 + ${TEMPLATEDIR}default/mainform.mfm + ${TEMPLATEDIR}default/simpleform.mfm + ${TEMPLATEDIR}default/dockingform.mfm + ${TEMPLATEDIR}default/datamodule.mfm + ${TEMPLATEDIR}default/subform.mfm + ${TEMPLATEDIR}default/scrollboxform.mfm + ${TEMPLATEDIR}default/tabform.mfm + ${TEMPLATEDIR}default/dockpanelform.mfm + ${TEMPLATEDIR}default/report.mfm + ${TEMPLATEDIR}default/pascform.mfm + ${TEMPLATEDIR}default/inheritedform.mfm +expandprojectfilemacros=4 + 1 + 1 + 1 + 0 +loadprojectfile=4 + 1 + 1 + 1 + 0 +newinheritedforms=11 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 +toolmenus=0 +toolfiles=0 +toolparams=0 +toolsave=0 +toolhide=0 +toolparse=0 +toolmessages=0 +toolshortcuts=0 +settingsfile= +settingsautoload=0 +settingsautosave=0 +settingseditor=0 +settingsdebugger=0 +settingsmake=1 +settingsmacros=0 +settingsfontalias=0 +settingsusercolors=0 +settingsformatmacros=0 +settingstemplates=0 +settingstools=0 +settingsstorage=0 +settingscomponentstore=0 +settingsprojecttree=0 +settingslayout=0 +messageoutputfile= +modulenames=1 + MAINFO +moduletypes=1 + TMAINFO +modulefiles=1 + /D:/mse/packs/standard/git/mseide-msegui/apps/i18ndemo/main.mfm +macrogroup=0 +forcezorder=0 +stripmessageesc=0 +copymessages=0 +closemessages=1 +checkmethods=1 +colorerror=-1610612712 +colorwarning=-1610612717 +colornote=-1610612716 +sigsettings=27 + 1,1,T,F + 3,3,T,F + 4,4,T,F + 6,6,T,F + 7,7,T,F + 8,8,T,F + 9,9,T,F + 10,10,T,F + 11,11,T,F + 12,12,T,F + 13,13,T,F + 15,15,T,F + 16,16,T,F + 17,17,F,F + 18,18,T,F + 19,19,T,F + 20,20,T,F + 21,21,T,F + 22,22,T,F + 23,23,T,F + 24,24,T,F + 25,25,T,F + 26,26,T,F + 27,27,T,F + 28,28,T,F + 29,29,T,F + 30,30,T,F +defaultmake=1 +units= + ( + a=0,8228,6,Pascal Units + ) +cmodules= + ( + a=0,8228,6,C Modules + ) +files= + ( + a=0,8228,6,Text Files + ) +[breakpoints] +on=0 +path=0 +line=0 +address=0 +addbkpt=0 +ignore=0 +condition=0 +panels=2 + panel1 + panel2 +[componentstore] +storedir=/D:/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ +filename= +[components] +[selecteditpage] +colwidth=100 +x=0 +y=0 +cx=0 +cy=0 +[progparams] +progparamhistory=0 +workdirparamhistory=0 +envvarons=0 +[edit] +hintwidth=0 +hintheight=0 +finddtext=fdir +findhistory=1 + fdir +findoptions=1 +editpos=2 + 55,1 + 0,-1073741823 +bookmarks0=0 +bookmarks1=0 +sourcefiles=2 + /D:/mse/packs/standard/git/mseide-msegui/apps/i18ndemo/main.pas + /D:/mse/packs/standard/git/mseide-msegui/lib/common/i18n/msei18nutils.pas +relpaths=2 + main.pas + ../../lib/common/i18n/msei18nutils.pas +ismoduletexts=2 + 0 + 0 +modules=1 + /D:/mse/packs/standard/git/mseide-msegui/apps/i18ndemo/main.mfm +moduleoptions=1 + 0 +visiblemodules=1 + -1 +nomenumodules=1 + 0 +[sourcefo.tabwidget] +tabsize=117 +firsttab=0 +index=0 +[layout] +windowlayout=568 + [mainfo.openform] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.projectfiledia] + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + [mainfo.openfile] + filenames=0 + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + filehistory=1 + /home/mse/packs/standard/git/mseide-msegui/apps/i18ndemo/main.pas + filefilterindex=0 + filefilter="*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + [mainfo.basedock] + splitdir=2 + useroptions=268582016 + [mainfo] + splitdir=0 + useroptions=838860923 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=8 + y=30 + cx=323 + cy=64 + rcx=0 + rcy=0 + wsize=0 + active=1 + visible=1 + [targetconsolefo] + splitdir=0 + useroptions=805322857 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=209 + y=385 + cx=368 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [threadsfo] + splitdir=0 + useroptions=805322857 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=0 + cy=0 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo] + splitdir=0 + useroptions=805322875 + stackedunder=cpuc86_64fo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=100 + y=100 + cx=453 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo.add] + value=0 + [memoryfo.memon] + value=0 + [memoryfo.bitwidth] + value=0 + [memoryfo.cnt] + value=0 + [disassfo] + splitdir=0 + useroptions=805322859 + stackedunder=breakpointsfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=162 + y=502 + cx=564 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [findinfilefo] + splitdir=0 + useroptions=268451947 + stackedunder=disassfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=548 + y=115 + cx=369 + cy=198 + rcx=0 + rcy=0 + [projecttreefo] + splitdir=0 + useroptions=805322859 + stackedunder=memoryfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=263 + y=431 + cx=286 + cy=201 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [projecttreefo.grid] + propcolwidthref=135 + width0=141 + sortdescend0=0 + width1=129 + sortdescend1=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=16 + [stackfo] + splitdir=0 + useroptions=805331049 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=295 + rcx=0 + rcy=0 + [watchpointsfo] + splitdir=0 + useroptions=805322857 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=120 + y=368 + cx=483 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [watchpointsfo.grid] + propcolwidthref=332 + sortdescend0=0 + values1=0 + values1_ci=-1 + width1=33 + sortdescend1=0 + values2=0 + width2=149 + sortdescend2=0 + width4=34 + sortdescend4=0 + values5=0 + values5_ci=-1 + width5=38 + sortdescend5=0 + values6=0 + width6=172 + sortdescend6=0 + [breakpointsfo] + splitdir=0 + useroptions=268451947 + stackedunder=projecttreefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=107 + y=404 + cx=636 + cy=128 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [breakpointsfo.bkptson] + value=1 + [objectinspectorfo] + splitdir=0 + useroptions=805322859 + stackedunder=targetconsolefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=724 + y=157 + cx=296 + cy=566 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [objectinspectorfo.grid] + propcolwidthref=286 + width0=105 + sortdescend0=0 + width1=175 + sortdescend1=0 + [symbolfo] + splitdir=0 + useroptions=805322875 + stackedunder=findinfilefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=142 + y=257 + cx=361 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [symbolfo.grid] + propcolwidthref=222 + values0=18 + + + + + + + + + + + + + + + + + + + width0=111 + sortdescend0=0 + width1=135 + sortdescend1=0 + [symbolfo.symbol] + [watchfo] + splitdir=0 + useroptions=805331049 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=298 + cx=313 + cy=236 + rcx=0 + rcy=0 + [watchfo.grid] + propcolwidthref=116 + values0=0 + values0_ci=-1 + sortdescend0=0 + values1=0 + width1=152 + sortdescend1=0 + values3=0 + values3_ci=-1 + sortdescend3=0 + values4=0 + values4_ci=-1 + width4=13 + sortdescend4=0 + [watchfo.watchon] + [watchfo.expression] + [watchfo.watcheson] + value=1 + [messagefo] + splitdir=0 + useroptions=805355627 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=680 + cx=983 + cy=200 + rcx=0 + rcy=0 + [componentstorefo] + splitdir=0 + useroptions=805331067 + stackedunder=symbolfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=305 + y=101 + cx=445 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentstorefo.grid] + propcolwidthref=435 + width0=111 + sortdescend0=0 + sortdescend1=0 + width2=112 + sortdescend2=0 + width3=185 + sortdescend3=0 + [componentstorefo.storefiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.groupfiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.compfiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentpalettefo] + splitdir=0 + useroptions=805331051 + stackedunder=objectinspectorfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=30 + cx=685 + cy=103 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [componentpalettefo.componentpages] + activetab=0 + [debuggerfo] + splitdir=0 + useroptions=268460139 + parent=mainfo.basedock + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=30 + rcx=0 + rcy=0 + [sourcefo] + splitdir=0 + useroptions=805322857 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=983 + cy=677 + rcx=0 + rcy=0 + [actionsmo.watchesonact] + checked=1 + [actionsmo.bluedotsonact] + checked=1 + [cpuc86_64fo] + irqoff=0 + splitdir=0 + useroptions=268451947 + stackedunder=watchpointsfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=183 + y=113 + cx=352 + cy=277 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [mainfo.panel1] + splitdir=2 + useroptions=838893035 + stackedunder=mainfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=8 + y=118 + cx=993 + cy=880 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel2] + splitdir=2 + useroptions=838893035 + stackedunder=mainfo.panel1 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=189 + cx=323 + cy=534 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [_mse_mainfo_mse_] + splitdir=0 + useroptions=805322875 + stackedunder=mainfo.panel2 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=291 + y=247 + cx=413 + cy=196 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 +[targetconsole] +finddtext= +findhistory=0 +findoptions=1 diff --git a/mseide-msegui/apps/i18ndemo/i18ndemo.trd b/mseide-msegui/apps/i18ndemo/i18ndemo.trd new file mode 100644 index 0000000..6d5babe --- /dev/null +++ b/mseide-msegui/apps/i18ndemo/i18ndemo.trd @@ -0,0 +1,86 @@ +name,type,notranslate,comment,value,de,fr +main.rsj,vaNull,F,,,, +"main.rsj,main",vaNull,F,,,, +"main.rsj,main,rs1",vaWString,F,,This is the first resource text.,Das ist der erste Text,C'est le premier texte +"main.rsj,main,rs2",vaWString,F,,This is the second resource text.,This ist der zweite Text,C'est le deuxième texte +mainfo,vaNull,F,,,, +"mainfo,bounds_x",vaInt16,F,,291,, +"mainfo,bounds_y",vaInt16,F,,247,, +"mainfo,bounds_cx",vaInt16,F,,403,, +"mainfo,bounds_cy",vaInt16,F,,196,, +"mainfo,container.bounds",vaList,F,,,, +"mainfo,container.bounds,0:",vaInt8,F,,0,, +"mainfo,container.bounds,1:",vaInt8,F,,0,, +"mainfo,container.bounds,2:",vaInt16,F,,403,, +"mainfo,container.bounds,3:",vaInt16,F,,196,, +"mainfo,optionswindow",vaSet,F,,[wo_groupleader],, +"mainfo,options",vaSet,F,,"[fo_main,fo_terminateonclose,fo_autoreadstat,fo_autowritestat,fo_savepos,fo_savestate]",, +"mainfo,caption",vaString,F,,MSEi18n Demo,MSEi18n Demo,MSEi18n Demo +"mainfo,oneventloopstart",vaIdent,F,,formonloaded,, +"mainfo,moduleclassname",vaString,T,,tmseform,tmseform,tmseform +"mainfo,disp1",vaNull,F,,,, +"mainfo,disp1,frame.caption",vaString,F,,Text of resource string 1,Text von resourcestring 1,Texte du resourcestring 1 +"mainfo,disp1,frame.dummy",vaInt8,F,,0,, +"mainfo,disp1,frame.outerframe",vaList,F,,,, +"mainfo,disp1,frame.outerframe,0:",vaInt8,F,,0,, +"mainfo,disp1,frame.outerframe,1:",vaInt8,F,,17,, +"mainfo,disp1,frame.outerframe,2:",vaInt8,F,,0,, +"mainfo,disp1,frame.outerframe,3:",vaInt8,F,,0,, +"mainfo,disp1,taborder",vaInt8,F,,4,, +"mainfo,disp1,bounds_x",vaInt8,F,,16,, +"mainfo,disp1,bounds_y",vaInt8,F,,71,, +"mainfo,disp1,bounds_cx",vaInt16,F,,372,, +"mainfo,disp1,bounds_cy",vaInt8,F,,37,, +"mainfo,disp1,reffontheight",vaInt8,F,,14,, +"mainfo,disp2",vaNull,F,,,, +"mainfo,disp2,frame.caption",vaString,F,,Text of resource string 2,Text von resourcestring 2,Texte du resourcestring 2 +"mainfo,disp2,frame.dummy",vaInt8,F,,0,, +"mainfo,disp2,frame.outerframe",vaList,F,,,, +"mainfo,disp2,frame.outerframe,0:",vaInt8,F,,0,, +"mainfo,disp2,frame.outerframe,1:",vaInt8,F,,17,, +"mainfo,disp2,frame.outerframe,2:",vaInt8,F,,0,, +"mainfo,disp2,frame.outerframe,3:",vaInt8,F,,0,, +"mainfo,disp2,taborder",vaInt8,F,,3,, +"mainfo,disp2,bounds_x",vaInt8,F,,16,, +"mainfo,disp2,bounds_y",vaInt8,F,,127,, +"mainfo,disp2,bounds_cx",vaInt16,F,,372,, +"mainfo,disp2,bounds_cy",vaInt8,F,,37,, +"mainfo,disp2,reffontheight",vaInt8,F,,14,, +"mainfo,default",vaNull,F,,,, +"mainfo,default,bounds_x",vaInt8,F,,16,, +"mainfo,default,bounds_y",vaInt8,F,,24,, +"mainfo,default,bounds_cx",vaInt8,F,,114,, +"mainfo,default,bounds_cy",vaInt8,F,,30,, +"mainfo,default,state",vaSet,F,,"[as_localcaption,as_localonexecute]",, +"mainfo,default,caption",vaString,T,,Default,Default,Default +"mainfo,default,font.height",vaInt8,F,,18,14, +"mainfo,default,font.name",vaString,T,,stf_default,stf_default,stf_default +"mainfo,default,font.xscale",vaInt8,F,,1,, +"mainfo,default,font.dummy",vaInt8,F,,0,, +"mainfo,default,onexecute",vaIdent,F,,defaultexe,, +"mainfo,deutsch",vaNull,F,,,, +"mainfo,deutsch,taborder",vaInt8,F,,1,, +"mainfo,deutsch,bounds_x",vaInt16,F,,144,, +"mainfo,deutsch,bounds_y",vaInt8,F,,24,, +"mainfo,deutsch,bounds_cx",vaInt8,F,,114,, +"mainfo,deutsch,bounds_cy",vaInt8,F,,30,, +"mainfo,deutsch,state",vaSet,F,,"[as_localcaption,as_localonexecute]",, +"mainfo,deutsch,caption",vaString,T,,Deutsch,Deutsch,Deutsch +"mainfo,deutsch,font.height",vaInt8,F,,14,18,14 +"mainfo,deutsch,font.name",vaString,T,,stf_default,stf_default,stf_default +"mainfo,deutsch,font.xscale",vaInt8,F,,1,, +"mainfo,deutsch,font.dummy",vaInt8,F,,0,, +"mainfo,deutsch,onexecute",vaIdent,F,,deutschexe,, +"mainfo,francais",vaNull,F,,,, +"mainfo,francais,taborder",vaInt8,F,,2,, +"mainfo,francais,bounds_x",vaInt16,F,,272,, +"mainfo,francais,bounds_y",vaInt8,F,,24,, +"mainfo,francais,bounds_cx",vaInt8,F,,114,, +"mainfo,francais,bounds_cy",vaInt8,F,,30,, +"mainfo,francais,state",vaSet,F,,"[as_localcaption,as_localonexecute]",, +"mainfo,francais,caption",vaWString,T,,Français,Français,Français +"mainfo,francais,font.height",vaInt8,F,,14,14,18 +"mainfo,francais,font.name",vaString,T,,stf_default,stf_default,stf_default +"mainfo,francais,font.xscale",vaInt8,F,,1,, +"mainfo,francais,font.dummy",vaInt8,F,,0,, +"mainfo,francais,onexecute",vaIdent,F,,francaisexe,, diff --git a/mseide-msegui/apps/i18ndemo/i18ndemo.trp b/mseide-msegui/apps/i18ndemo/i18ndemo.trp new file mode 100644 index 0000000..1bc579b --- /dev/null +++ b/mseide-msegui/apps/i18ndemo/i18ndemo.trp @@ -0,0 +1,133 @@ +[projectfo.projectstat] +colcount=7 +[projectfo.impexpfiledialog] +filenames=1 + /home/mse/proj/msegui/trunk/apps/i18ndemo/test.csv +filecolwidth=174 +x=0 +y=0 +cx=0 +cy=0 +lastdir=/home/mse/proj/msegui/trunk/apps/i18ndemo/ +filefilterindex=0 +filefilter=*.csv +[projectfo.aftermake] +value= +[projectfo.beforemake] +value= +[projectfo.destname] +value= +[projectfo.makeon] +value=1 +[projectfo.makecommand] +value=${COMPILER} -B -Cg -Fu${MSELIBDIR}i18n ${LIBFILE} +[projectfo.grid2] +propcolwidthref=581 +values0=2 + de + fr +width0=102 +sortdescend0=0 +values1=2 + ./de/ + ./fr/ +[projectfo.datafilename] +filenames=1 + i18ndemo.trd +filecolwidth=174 +x=0 +y=0 +cx=0 +cy=0 +lastdir= +filefilterindex=3 +filefilter= +[projectfo.grid] +propcolwidthref=428 +values0=2 + main.rsj + mainfo +width0=72 +sortdescend0=0 +values1=2 + main.rsj + main.mfm +values2=2 + 3 + 0 +values2_ci=-1 +width2=183 +sortdescend2=0 +[projectfo.impexpencoding] +value=1 +[projectfo] +x=149 +y=167 +cx=683 +cy=698 +wsize=0 +active=0 +visible=0 +[mainfo] +stackedunder= +x=518 +y=230 +cx=724 +cy=264 +wsize=0 +active=1 +visible=1 +[mainfo.grid] +propcolwidthref=613 +width0=167 +sortdescend0=0 +width1=50 +sortdescend1=0 +width2=20 +sortdescend2=0 +width3=100 +sortdescend3=0 +width4=101 +sortdescend4=0 +values5=5 + Das ist der erste Text + This ist der zweite Text + MSEi18n Demo + Text von resourcestring 1 + Text von resourcestring 2 +width5=117 +sortdescend5=0 +values6=5 + C'est le premier texte + C'est le deuxième texte + MSEi18n Demo + Texte du resourcestring 1 + Texte du resourcestring 2 +width6=109 +sortdescend6=0 +width7=50 +sortdescend7=0 +width8=50 +sortdescend8=0 +width9=50 +sortdescend9=0 +width10=50 +sortdescend10=0 +width11=50 +sortdescend11=0 +rowstate=5 + 0 0 + 0 0 + 0 0 + 0 0 + 0 0 +[mainfo.flat] +value=1 +[mainfo.stringonly] +value=1 +[mainfo.nont] +value=1 +[mainfo.ntonly] +value=0 +[mainfo.coloron] +value=1 diff --git a/mseide-msegui/apps/i18ndemo/main.mfm b/mseide-msegui/apps/i18ndemo/main.mfm new file mode 100644 index 0000000..2b8fa16 --- /dev/null +++ b/mseide-msegui/apps/i18ndemo/main.mfm @@ -0,0 +1,90 @@ +object mainfo: tmainfo + bounds_x = 291 + bounds_y = 247 + bounds_cx = 403 + bounds_cy = 196 + container.bounds = ( + 0 + 0 + 403 + 196 + ) + optionswindow = [wo_groupleader] + options = [fo_main, fo_terminateonclose, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savestate] + caption = 'MSEi18n Demo' + oneventloopstart = formonloaded + moduleclassname = 'tmseform' + object disp1: tstringdisp + frame.caption = 'Text of resource string 1' + frame.dummy = 0 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 4 + bounds_x = 16 + bounds_y = 71 + bounds_cx = 372 + bounds_cy = 37 + reffontheight = 14 + end + object disp2: tstringdisp + frame.caption = 'Text of resource string 2' + frame.dummy = 0 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 3 + bounds_x = 16 + bounds_y = 127 + bounds_cx = 372 + bounds_cy = 37 + reffontheight = 14 + end + object default: tbutton + bounds_x = 16 + bounds_y = 24 + bounds_cx = 114 + bounds_cy = 30 + state = [as_localcaption, as_localonexecute] + caption = 'Default' + font.height = 18 + font.name = 'stf_default' + font.xscale = 1 + font.dummy = 0 + onexecute = defaultexe + end + object deutsch: tbutton + taborder = 1 + bounds_x = 144 + bounds_y = 24 + bounds_cx = 114 + bounds_cy = 30 + state = [as_localcaption, as_localonexecute] + caption = 'Deutsch' + font.height = 14 + font.name = 'stf_default' + font.xscale = 1 + font.dummy = 0 + onexecute = deutschexe + end + object francais: tbutton + taborder = 2 + bounds_x = 272 + bounds_y = 24 + bounds_cx = 114 + bounds_cy = 30 + state = [as_localcaption, as_localonexecute] + caption = 'Fran'#231'ais' + font.height = 14 + font.name = 'stf_default' + font.xscale = 1 + font.dummy = 0 + onexecute = francaisexe + end +end diff --git a/mseide-msegui/apps/i18ndemo/main.pas b/mseide-msegui/apps/i18ndemo/main.pas new file mode 100644 index 0000000..2e0d973 --- /dev/null +++ b/mseide-msegui/apps/i18ndemo/main.pas @@ -0,0 +1,57 @@ +unit main; +{$ifdef FPC}{$mode objfpc}{$h+}{$codepage utf8}{$endif} +interface +uses + msegui,mseclasses,mseforms,msedispwidgets,msegraphedits,msesimplewidgets; + +type + tmainfo = class(tmseform) + disp1: tstringdisp; + disp2: tstringdisp; + default: tbutton; + deutsch: tbutton; + francais: tbutton; + procedure formonloaded(const sender: TObject); + procedure defaultexe(const sender: TObject); + procedure deutschexe(const sender: TObject); + procedure francaisexe(const sender: TObject); + protected + procedure updatedisp; + end; +var + mainfo: tmainfo; +implementation +uses + main_mfm,msei18nutils,msestrings; + +resourcestring + rs1 = 'This is the first resource text.'; + rs2 = 'This is the second resource text.'; + +procedure tmainfo.formonloaded(const sender: TObject); +begin + updatedisp; +end; + +procedure tmainfo.updatedisp; +begin + disp1.value:= utf8tostring(rs1); + disp2.value:= utf8tostring(rs2); +end; + +procedure tmainfo.defaultexe(const sender: TObject); +begin + loadlangunit(''); +end; + +procedure tmainfo.deutschexe(const sender: TObject); +begin + loadlangunit('i18ndemo_de'); +end; + +procedure tmainfo.francaisexe(const sender: TObject); +begin + loadlangunit('i18ndemo_fr'); +end; + +end. diff --git a/mseide-msegui/apps/i18ndemo/main_mfm.pas b/mseide-msegui/apps/i18ndemo/main_mfm.pas new file mode 100644 index 0000000..00b84aa --- /dev/null +++ b/mseide-msegui/apps/i18ndemo/main_mfm.pas @@ -0,0 +1,84 @@ +unit main_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,main; + +const + objdata: record size: integer; data: array[0..1321] of byte end = + (size: 1322; data: ( + 84,80,70,48,7,116,109,97,105,110,102,111,6,109,97,105,110,102,111,8, + 98,111,117,110,100,115,95,120,3,35,1,8,98,111,117,110,100,115,95,121, + 3,247,0,9,98,111,117,110,100,115,95,99,120,3,147,1,9,98,111,117, + 110,100,115,95,99,121,3,196,0,16,99,111,110,116,97,105,110,101,114,46, + 98,111,117,110,100,115,1,2,0,2,0,3,147,1,3,196,0,0,13,111, + 112,116,105,111,110,115,119,105,110,100,111,119,11,14,119,111,95,103,114,111, + 117,112,108,101,97,100,101,114,0,7,111,112,116,105,111,110,115,11,7,102, + 111,95,109,97,105,110,19,102,111,95,116,101,114,109,105,110,97,116,101,111, + 110,99,108,111,115,101,15,102,111,95,97,117,116,111,114,101,97,100,115,116, + 97,116,16,102,111,95,97,117,116,111,119,114,105,116,101,115,116,97,116,10, + 102,111,95,115,97,118,101,112,111,115,12,102,111,95,115,97,118,101,115,116, + 97,116,101,0,7,99,97,112,116,105,111,110,6,12,77,83,69,105,49,56, + 110,32,68,101,109,111,16,111,110,101,118,101,110,116,108,111,111,112,115,116, + 97,114,116,7,12,102,111,114,109,111,110,108,111,97,100,101,100,15,109,111, + 100,117,108,101,99,108,97,115,115,110,97,109,101,6,8,116,109,115,101,102, + 111,114,109,0,11,116,115,116,114,105,110,103,100,105,115,112,5,100,105,115, + 112,49,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,25,84,101, + 120,116,32,111,102,32,114,101,115,111,117,114,99,101,32,115,116,114,105,110, + 103,32,49,11,102,114,97,109,101,46,100,117,109,109,121,2,0,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2, + 0,2,0,0,8,116,97,98,111,114,100,101,114,2,4,8,98,111,117,110, + 100,115,95,120,2,16,8,98,111,117,110,100,115,95,121,2,71,9,98,111, + 117,110,100,115,95,99,120,3,116,1,9,98,111,117,110,100,115,95,99,121, + 2,37,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0, + 11,116,115,116,114,105,110,103,100,105,115,112,5,100,105,115,112,50,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,25,84,101,120,116,32,111, + 102,32,114,101,115,111,117,114,99,101,32,115,116,114,105,110,103,32,50,11, + 102,114,97,109,101,46,100,117,109,109,121,2,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0, + 8,116,97,98,111,114,100,101,114,2,3,8,98,111,117,110,100,115,95,120, + 2,16,8,98,111,117,110,100,115,95,121,2,127,9,98,111,117,110,100,115, + 95,99,120,3,116,1,9,98,111,117,110,100,115,95,99,121,2,37,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,7,116,98,117, + 116,116,111,110,7,100,101,102,97,117,108,116,8,98,111,117,110,100,115,95, + 120,2,16,8,98,111,117,110,100,115,95,121,2,24,9,98,111,117,110,100, + 115,95,99,120,2,114,9,98,111,117,110,100,115,95,99,121,2,30,5,115, + 116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111, + 110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0, + 7,99,97,112,116,105,111,110,6,7,68,101,102,97,117,108,116,11,102,111, + 110,116,46,104,101,105,103,104,116,2,18,9,102,111,110,116,46,110,97,109, + 101,6,11,115,116,102,95,100,101,102,97,117,108,116,11,102,111,110,116,46, + 120,115,99,97,108,101,2,1,10,102,111,110,116,46,100,117,109,109,121,2, + 0,9,111,110,101,120,101,99,117,116,101,7,10,100,101,102,97,117,108,116, + 101,120,101,0,0,7,116,98,117,116,116,111,110,7,100,101,117,116,115,99, + 104,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95, + 120,3,144,0,8,98,111,117,110,100,115,95,121,2,24,9,98,111,117,110, + 100,115,95,99,120,2,114,9,98,111,117,110,100,115,95,99,121,2,30,5, + 115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105, + 111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101, + 0,7,99,97,112,116,105,111,110,6,7,68,101,117,116,115,99,104,11,102, + 111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97, + 109,101,6,11,115,116,102,95,100,101,102,97,117,108,116,11,102,111,110,116, + 46,120,115,99,97,108,101,2,1,10,102,111,110,116,46,100,117,109,109,121, + 2,0,9,111,110,101,120,101,99,117,116,101,7,10,100,101,117,116,115,99, + 104,101,120,101,0,0,7,116,98,117,116,116,111,110,8,102,114,97,110,99, + 97,105,115,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100, + 115,95,120,3,16,1,8,98,111,117,110,100,115,95,121,2,24,9,98,111, + 117,110,100,115,95,99,120,2,114,9,98,111,117,110,100,115,95,99,121,2, + 30,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112, + 116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117, + 116,101,0,7,99,97,112,116,105,111,110,18,8,0,0,0,70,0,114,0, + 97,0,110,0,231,0,97,0,105,0,115,0,11,102,111,110,116,46,104,101, + 105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,11,115,116, + 102,95,100,101,102,97,117,108,116,11,102,111,110,116,46,120,115,99,97,108, + 101,2,1,10,102,111,110,116,46,100,117,109,109,121,2,0,9,111,110,101, + 120,101,99,117,116,101,7,11,102,114,97,110,99,97,105,115,101,120,101,0, + 0,0) + ); + +initialization + registerobjectdata(@objdata,tmainfo,''); +end. diff --git a/mseide-msegui/apps/ide/COPYING.GPL b/mseide-msegui/apps/ide/COPYING.GPL new file mode 100644 index 0000000..5b6e7c6 --- /dev/null +++ b/mseide-msegui/apps/ide/COPYING.GPL @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/mseide-msegui/apps/ide/COPYING.IDE b/mseide-msegui/apps/ide/COPYING.IDE new file mode 100644 index 0000000..098aa98 --- /dev/null +++ b/mseide-msegui/apps/ide/COPYING.IDE @@ -0,0 +1,17 @@ +This is the file COPYING.IDE, it applies to MSEide. + +The source code of the MSEide is +distributed under the GNU General Public License (GPL) +(see the file COPYING.GPL) with the following modification: + +As a special exception, the copyright holders of MSEide give you +permission to link MSEide with non GPL runtime component unit modules by the +-dmorecomponents mechanism described in README.TXT. +Design time parts of the components and its unit modules must be GPL. + +If you didn't receive a copy of the file COPYING.GPL, contact: + Free Software Foundation + 675 Mass Ave + Cambridge, MA 02139 + USA + diff --git a/mseide-msegui/apps/ide/actionsmodule.mfm b/mseide-msegui/apps/ide/actionsmodule.mfm new file mode 100644 index 0000000..eb8d49e --- /dev/null +++ b/mseide-msegui/apps/ide/actionsmodule.mfm @@ -0,0 +1,2605 @@ +object actionsmo: tactionsmo + bounds_cx = 543 + bounds_cy = 435 + left = 7 + top = 198 + moduleclassname = 'tmsedatamodule' + object makeact: taction + Tag = 1 + caption = '&Make' + onexecute = makeactonexecute + left = 8 + top = 294 + end + object run: taction + caption = '&Run' + imagenr = 0 + hint = 'Run' + left = 80 + top = 191 + end + object step: taction + imagelist = buttonicons + caption = '&Step' + imagenr = 1 + imagenrdisabled = 18 + hint = 'Step' + onexecute = stepactonexecute + left = 8 + top = 222 + sc = ( + 1 + 310 + ) + end + object next: taction + imagelist = buttonicons + caption = '&Next' + imagenr = 2 + imagenrdisabled = 22 + hint = 'Next' + onexecute = nextactonexecute + left = 8 + top = 206 + sc = ( + 1 + 311 + ) + end + object continue: taction + imagelist = buttonicons + caption = '&Continue' + imagenr = 4 + imagenrdisabled = 17 + hint = 'Continue' + onexecute = continueactonexecute + left = 8 + top = 254 + sc = ( + 1 + 312 + ) + end + object interrupt: taction + imagelist = buttonicons + caption = '&Interrupt' + imagenr = 5 + imagenrdisabled = 16 + hint = 'Interrupt' + onexecute = interruptactonexecute + left = 9 + top = 269 + end + object reset: taction + imagelist = buttonicons + caption = '&Reset' + imagenr = 6 + imagenrdisabled = 15 + hint = 'Reset' + onexecute = resetactonexecute + left = 7 + top = 191 + end + object opensource: taction + caption = '&Open' + onexecute = opensourceactonexecute + left = 8 + top = 4 + sc = ( + 1 + 16463 + ) + end + object finish: taction + imagelist = buttonicons + caption = '&Finish' + imagenr = 3 + imagenrdisabled = 20 + hint = 'Finish' + onexecute = finishactonexecute + left = 8 + top = 238 + sc = ( + 1 + 8502 + ) + end + object save: taction + caption = '&Save' + onexecute = saveactonexecute + left = 8 + top = 20 + sc = ( + 1 + 16467 + ) + end + object close: taction + caption = '&Close' + onexecute = closeactonexecute + left = 8 + top = 68 + sc = ( + 1 + 16691 + ) + end + object abortmakeact: taction + caption = '&Abort Make' + onexecute = abortmakeactonexecute + left = 8 + top = 402 + end + object undo: taction + caption = '&Undo' + onexecute = undoactonexecute + left = 280 + top = 4 + sc = ( + 1 + 16474 + ) + end + object redo: taction + caption = '&Redo' + onexecute = redoactonexecute + left = 280 + top = 20 + sc = ( + 1 + 24666 + ) + end + object cut: taction + caption = 'Cu&t' + onexecute = cutactonexecute + left = 280 + top = 36 + sc = ( + 1 + 16472 + ) + sc1 = ( + 1 + 8455 + ) + end + object copy: taction + caption = '&Copy' + onexecute = copyactonexecute + left = 280 + top = 52 + sc = ( + 1 + 16451 + ) + end + object paste: taction + caption = '&Paste' + onexecute = pasteactonexecute + left = 280 + top = 68 + sc = ( + 1 + 16470 + ) + sc1 = ( + 1 + 8454 + ) + end + object delete: taction + caption = '&Delete' + onexecute = deleteactonexecute + left = 280 + top = 84 + end + object saveall: taction + caption = 'Sa&ve all' + onexecute = saveallactonexecute + left = 8 + top = 36 + end + object find: taction + caption = '&Find' + onexecute = findactonexecute + onupdate = findupdateexe + left = 152 + top = 28 + sc = ( + 1 + 16454 + ) + end + object repeatfind: taction + caption = '&Search again' + onexecute = repeatfindactonexecute + left = 152 + top = 44 + sc = ( + 1 + 306 + ) + end + object findinfile: taction + caption = 'Find in F&iles' + onexecute = findinfileonexecute + left = 152 + top = 76 + sc = ( + 1 + 24646 + ) + end + object closeall: taction + caption = 'C&lose all' + onexecute = closeallactonexecute + left = 8 + top = 84 + end + object saveas: taction + caption = 'Save &as' + onexecute = saveasactonexecute + left = 8 + top = 52 + end + object bkptsonact: taction + imagelist = buttonicons + caption = '&Breakpoints on' + state = [as_checked] + imagenr = 7 + hint = 'Breakpoints on/off' + onexecute = bkptsononexecute + left = 152 + top = 236 + sc = ( + 1 + 16450 + ) + end + object watchesonact: taction + imagelist = buttonicons + caption = '&Watches on' + state = [as_checked] + imagenr = 9 + hint = 'Watches on/off' + statfile = mainfo.projectstatfile + onexecute = watchesononexecute + left = 152 + top = 252 + sc = ( + 1 + 16471 + ) + end + object line: taction + caption = '&Line' + onexecute = lineactonexecute + left = 152 + top = 12 + sc = ( + 1 + 16460 + ) + end + object togglebkpt: taction + caption = '&Toggle Breakpoint' + onexecute = togglebreakpointexe + left = 152 + top = 204 + sc = ( + 1 + 308 + ) + end + object togglebkptenable: taction + caption = 'Toggle Bkpt. &enabled' + onexecute = togglebkptenableactonexecute + left = 152 + top = 220 + sc = ( + 1 + 8500 + ) + end + object buttonicons: timagelist + width = 24 + height = 24 + options = [bmo_masked, bmo_colormask] + count = 24 + left = 352 + top = 32 + image = { + 00000000060000007800000078000000583A0000000000000000000000000000 + 0000000000000000000000000000000000000000C0C0C018D0D0D00600A50903 + D0D0D01A00000001D0D0D00200000001D0D0D00B00000001D0D0D00200000001 + D0D0D02AC0C0C018D0D0D00600A5090110A8100100A50902D0D0D01900000005 + D0D0D00A00000005D0D0D029C0C0C018D0D0D00600A5090126BB20011EB41A01 + 00A50902D0D0D01A00000002D0D0D00D00000009D0D0D00500A30803D0D0D01B + C0C0C00D80000002C0C0C009D0D0D00600A5090132CE2E013CD3330122BD2001 + 00A50902D0D0D00100000001D0D0D00200000001D0D0D02500000007D0D0D005 + 0AB7070118D002010AB707010015000100000001D0D0D00700A9090104B40A01 + 00000001D0D0D00FC0C0C00D80000002C0C0C009D0D0D00600A509013BDF3801 + 4CED440143E23D0127C6260100A5090200000005D0D0D0240000000B00BF0001 + 0FBD050120DF00010DB304010004000100000001D0D0D00700A708010DC50A01 + 089A0B01002B0001D0D0D00EC0C0C005808080068000000380808001C0C0C009 + D0D0D00302A8090107B207010BB7060107B107013CE1390152FA4D0154FD4F01 + 4CF247012CD02C0100A50902D0D0D00100000009D0D0D00300AA000108B20801 + 0AB706010CBB06010EBE06010EBD06040AB7070100920701D0D0D0100000000B + 00AA000110C0040120DF00010EB204010008000100000001D0D0D00700A70801 + 15D50B0124DD19010CA1100100590001D0D0D00DC0C0C0088080800180000005 + C0C0C00AD0D0D00206AF07010EBD05011FDD000120DF000112C5040134D32F01 + 49E840014BED43014EF2470146ED42011FC5230100A50901D0D0D00300000007 + D0D0D00200A70A0109B507011BD7010120DF000718D00201003E030100000001 + D0D0D00B00000004D0D0D00B00A30C0112C3040120DF00010CAB050100020001 + 00000001D0D0D00700A7080115D50B012CE71D0137E52B0113A8150100680601 + 00000001D0D0D00BC0C0C0048080800480000006C0C0C00AD0D0D00102A80901 + 10C1050120DF00021CD7010109AF06012DC526013FD5330142DA370140DB3701 + 28C827010061050100120101D0D0D00300000007D0D0D00100AA000109B50601 + 1FDE000120DF00011DD8010113C403010FB604010FB504010EB404010EB20401 + 0EB1040109AE0601003E030100000001D0D0D00100000003D0D0D00200000001 + D0D0D00400000004D0D0D00A00A8070107B107011CD7010120DF0001099C0601 + 00000002D0D0D00700A7080115D50B012CE71D013CEA2E014AEB3D011FB32101 + 0A7C0D0100000001D0D0D00AC0C0C008800000018080800180000005C0C0C009 + D0D0D00108B307011FDD000120DF00010BA90501036C0501004B040126B71C01 + 35C2270134C5280121BB1E010061050100120101D0D0D00400000007D0D0D001 + 06AF08011AD6010120DF000112BA0301047B0501002C020100100001000F0001 + 000B000100080001000600010002000100000002D0D0D00100000007D0D0D004 + 04B2080108B507010BB806010EBC06010EBD060914C903011EDB010120DF0001 + 1DDA01010584050100000002D0D0D00700A7080115D50B012CE71D013CEA2E01 + 4CEC3F015CEF500131C13101108A170100000001D0D0D009C0C0C00580808005 + 80000006C0C0C008D0D0D0010DBB050120DF00011CD70101036C050100000001 + 006A06011FA9130129AF19011AAE14010061050100120101D0D0D00100000004 + D0D0D0080BB9050120DF00011FDE0001068A0601000000010027040100910701 + 00970F0100000005D0D0D00400000001D0D0D00300000001D0D0D00308AF0801 + 12C3040120DF000E1CD80101089E0601000D000100000002D0D0D00700A70801 + 15D50B012CE71D013CEA2E014CEC3F015CEF50016BF260014BCF480117961C01 + 00000001D0D0D008C0C0C0098000000480808001C0C0C00180000002C0C0C007 + 00A509010FBF050120DF000111BB04010022020100000001009A0801159C0A01 + 13A10B010061050100120101D0D0D00200000004D0D0D0080DBC050120DF0001 + 17CC0201014B03010000000100A3080110A9110100A40901009F1001D0D0D00F + 06AA060112C5040120DF000216CC02010EB204010DB104010DB204010EB20402 + 0EB304010FB504020FB6040110B704010CAD0401089A0601047B0501000B0001 + 00000002D0D0D00800A7080115D50B012CE71D013CEA2E014CEC3F015CEF5001 + 6BF260017BF5710168E064011D9D220100550001D0D0D007C0C0C00580000002 + C0C0C0028000000580808001C0C0C00180808001C0C0C007D0D0D0010DBB0501 + 20DF00011CD70101036E05010000000100A30901099B06010061050100120101 + 00000001D0D0D00E0CBA060120DF000117CC0201014B03010000000100A30801 + 26BB21011EB31A01009D0901009F1001D0D0D00E09B307011FDF000120DF0001 + 09A3050102450301001B010100430401001701010006000100080001000A0001 + 000C0001000D0001000F0001001302010002000100000005D0D0D00800A70801 + 15D50B012CE71D013CEA2E014CEC3F015CEF50016BF260017BF571018BF78201 + 86EE800126A7290100620A01D0D0D006C0C0C004808080018000000380808001 + 800000028080800180000003C0C0C009D0D0D00108B107011FDE000120DF0001 + 0AA60501015D0501007A070100A3090100120101D0D0D0100AB6070120DF0001 + 1FDE0001068A06010000000100A3080132CE2D013CD3340122BD2001009D0901 + 009F1001D0D0D00D0AB9060120DF00011AD40201015B040100000001006C0601 + 11A91001009C0801006105010000000BD0D0D00900A7080115D50B012CE71D01 + 3CEA2E014CEC3F015CEF50016BF260017BF571018BF7820186EE800124A02701 + 0018020100000001D0D0D005C0C0C004800000018080800180000005C0C0C001 + 8080800180000002C0C0C009D0D0D001018F070110BA040120DF00011FDE0001 + 14C403010EB905010DBB05010DBC05080CB9060109B3060106AB070100290201 + 00000001D0D0D00405AE080117CA030120DF000112BA03010491060100A40801 + 3BDF38014CED440143E23D0127C62601009D0901009F1001D0D0D00C0CBA0601 + 20DF000113C003010029020100000001009A080126BC21011EB41A0100A50902 + D0D0D01300A7080115D50B012CE71D013CEA2E014CEC3F015CEF50016BF26001 + 7BF5710168E064011A901F010007000100000001D0D0D006C0C0C00780808001 + 80000002C0C0C0028080800180000002C0C0C009D0D0D0010000000105930601 + 0DB105011FDE000120DF000D1BD40201069E060100000002D0D0D00406A60601 + 1DDB010120DF00011DD801010EBD04013CE1390152FA4D0154FD4F014CF24701 + 2CCF2C01009D0901009F1001D0D0D00200000008D0D0D0010AB7060120DF0001 + 1DDA0101057D05010000000100A3090133CF2E013DD3330123BD200100A50902 + 00000006D0D0D00C00A7080115D50B012CE71D013CEA2E014CEC3F015CEF5001 + 6BF260014BCF4801137B170100000002D0D0D007C0C0C00C8000000280808001 + C0C0C009D0D0D00200000001014504010692060109A105010CAE05010DB00509 + 13C103011EDB010120DF000117CA0201036C050100000002D0D0D00300930001 + 0699060119D0020120DF000118D0020134D22F0149E840014BED43014EF24701 + 46ED42011FC6230100940701D0D0D00200000008D0D0D00107AF07011FDC0001 + 20DF00010EB3040104850601009B08013BE039014CED450144E33D0127C72601 + 00A509010040030100000005D0D0D00C00A7080115D50B012CE71D013CEA2E01 + 4CEC3F015CEF500130C030010B5F100100000002D0D0D008C0C0C00B80808001 + 8000000180808001C0C0C00AD0D0D0030000000D002C0201069206011CD70101 + 20DF00010896050100000002D0D0D004000E0001047A04010898060108AA0601 + 2DC526013FD5330142DA370140DB370128C827010060050100120201D0D0D00B + 008607010EB8040120DF000218D1020108B106013CE23A0153FB4D0154FE4F01 + 4CF347012CD02C0100A50902D0D0D00200000007D0D0D00700A7080115D50B01 + 2CE71D013CEA2E014AEB3D011FB22001053F060100000002D0D0D009C0C0C00B + 8000000280808002C0C0C009D0D0D0030000000E004A040110BE040120DF0001 + 0BA7050100000002D0D0D00500000002004F040126B71C0135C2270134C52801 + 21BA1E010060050100120201D0D0D00C00000001059307010EB104011FDF0001 + 20DF000112C5040135D3300149E841014CED44014EF2470147ED43011FC52301 + 00A50901D0D0D00200000007D0D0D00700A7080115D50B012CE71D0137E52B01 + 13A415010021020100000002D0D0D00AC0C0C00B80000004C0C0C009D0D0D005 + 00000009D0D0D003008507010FBE050120DF00010EB205010008000100000001 + D0D0D00700A108011FA8120129AF19011AAE14010060050100120201D0D0D00E + 00000001004D0301079205010BA3040107AC06012EC526013FD5340142DB3701 + 41DC380128C927010061050100120101D0D0D00200000008D0D0D00600A70801 + 15D50B0124DD19010B980F01000F000100000002D0D0D00BC0C0C018D0D0D007 + 00000007D0D0D00300A509010EBD050120DF00010DB205010005000100000001 + D0D0D00700A30801149D0A0113A00B010060050100120201D0D0D01000000003 + 004C040126B81D0136C3270134C6290121BB1E01006105010012010100000004 + D0D0D00100000002D0D0D00A00A708010DC50A0107890A010003000100000001 + D0D0D00DC0C0C018D0D0D0070000000B0AB6060118D0020109AE060100010001 + 00000001D0D0D00700A308010A9905010166050100120201D0D0D01200000002 + 009408011FA9130129AF19011AAE1501006105010012010100000005D0D0D00D + 00A9090104B30A0100000002D0D0D00EC0C0C018D0D0D00500000009D0D0D001 + 0000000300910801004604010042040100000002D0D0D007009F100100A10801 + 00120201D0D0D00200000004D0D0D00F00A50901169C0A0113A10C0100610501 + 00120101D0D0D01500000001D0D0D00FC0C0C018D0D0D00300000004D0D0D00B + 00000005D0D0D00C00000004D0D0D00F00A50901099B06010061050100120101 + D0D0D026C0C0C018D0D0D00600000001D0D0D02F00A50901009E090100120101 + D0D0D06FF8FCF818D0D0D060F8FCF818D0D0D038000094010000A3010000AC01 + 0000B6020000AA0100009F010000850100000002D0D0D01EF8FCF80200000002 + F8FCF81000000002F8FCF802D0D0D036000095010000A9010000D9010000F501 + 0000FF040000F5010000D7010000A0010000540100000001D0D0D01DF8FCF802 + 00000003F8FCF80E00000003F8FCF802D0D0D01EF2301401F5563102F02D1201 + D0D0D004F0301401F5583202F22E1201D0D0D00B0000A2010000BE010000FB01 + 0000FF030909FF010E0EFF011111FF020E0EFF010909FB010101B40100008501 + 00000002D0D0D01BF8FCF80300000003F8FCF80C00000003F8FCF803D0D0D01E + F4502D01FDA36E02E44A290102000001D0D0D003F4502D01FDA36E02E44A2901 + 02000001D0D0D0090000A2010000DC010000FF020101FF010E0EFF011A1AFF01 + 2323FF012929FF012D2DFF022929FF012323FF011A1AFF010A0AD60100007601 + 00000002D0D0D01AF8FCF80400000003F8FCF80A00000003F8FCF804D0D0D01E + F44D2901FC996602E447270104000001D0D0D003F44D2901FC996602E4472701 + 04000001D0D0D008000095010000BE010000FF010000F50104049C011515EB01 + 2626FF013333FF013E3EFF014545FF014848FF023F3FE90126269C013232F501 + 2727FF010909B00100002B0100000001D0D0D01AF8FCF80500000003F8FCF803 + 0000F802F8FCF80300000003F8FCF805D0D0D01EF3482601FB8F5E02E5442401 + 05000001D0D0D003F3482601FB8F5F02E544250105000001D0D0D0080000A901 + 0000FB010000FF0104049C0100000001070728013737E7014C4CFF015757FF01 + 5F5FFF016464FF015B5BE7010F0F2801000000012E2E9C013E3EFF012B2BFB01 + 05058F0100000002D0D0D00A06069F010C0CAF011313B9011919BA011515AE01 + 0C0C9C01D0D0D009F8FCF806000000030000F80600000003F8FCF806D0D0D005 + 00000002D0D0D00400000002D0D0D00400000003D0D0D00AF3442301FA855702 + E341220107000001D0D0D003F3442301FA855702E341220107000001D0D0D007 + 000094010000D9010000FF021515E90107072801000000010D0D28015A5AE701 + 7171FF017A7AFF017373E7011414280100000001121228015C5CEB015353FF01 + 4141FF011D1DD2010000360100000002D0D0D0080404AB010E0ECC012828FE01 + 3434FF014040FF014B4BFE012E2EC30114149101D0D0D008F8FCF80700000003 + 0000F80400000003F8FCF807D0D0D0030000000CD0D0D00100000006D0D0D008 + F3402001F97B4F02E33D1F0109000001D0D0D003F3402001F97B4F02E33D1F01 + 09000001D0D0D0070000A3010000F5010000FF010E0EFF012525FF013636E701 + 0D0D280100000001131328017878E7017C7CE701161628010000000115152801 + 7878E7017A7AFF016767FF015353FF013838F5010404690100000002D0D0D007 + 00009F010909CC011C1CFF012828FF013434FF014040FF014C4CFF015858FF01 + 3232BE0105053E01D0D0D007F8FCF8070000F801000000030000F80200000003 + 0000F801F8FCF807D0D0D00300000014D0D0D007F23C1C01F8714702E3391C01 + 0B020001D0D0D003F23C1C01F8714702E3391C010B020001D0D0D0070000AC01 + 0000FF021919FF013232FF014A4AFF015858E701131328010000000114142401 + 1515240100000001181828018585E7018D8DFF018686FF017878FF016262FF01 + 4A4AFF010B0B8A0100000002D0D0D0070101AF011111FE011C1CFF012828FF01 + 3434FF014040FF014C4CFF015858FF016363FE011818870100000001D0D0D006 + F8FCF8070000F802000000060000F802F8FCF807D0D0D00300000014D0D0D007 + F2371901F7673F02E13619010C020001D0D0D003F2371901F7673F02E1361901 + 0C020001D0D0D0070000B6010000FF010707FF012121FF013A3AFF015454FF01 + 6D6DFF017777E7011414240100000002171724019292E7019D9DFF019595FF01 + 8C8CFF018383FF016D6DFF015454FF011313A10100000002D0D0D0070303B901 + 1111FF011C1CFF012828FF013434FF014040FF014C4CFF015858FF016464FF01 + 25259F0100000001D0D0D006F8FCF8060000F804000000040000F804F8FCF806 + D0D0D00300000014D0D0D007F2341601F65D3702E23216010C020001D0D0D003 + F2341601F65D3702E23217010C020001D0D0D0070000B6010000FF010B0BFF01 + 2626FF014040FF015A5AFF017575FF017979E701151524010000000218182401 + 9C9CE701A5A5FF019B9BFF019191FF018686FF017575FF015B5BFF011515A001 + 00000002D0D0D0070303BA011111FF011C1CFF012828FF013434FF014040FF01 + 4C4CFF015858FF016464FF0125259F0100000001D0D0D006F8FCF8060000F804 + 000000040000F804F8FCF806D0D0D00400000013D0D0D007F12F1301F5533002 + E12D14010E020001D0D0D003F12F1301F5533001F5543001E12F14010E020001 + D0D0D0070000AA010000FF010D0DFF012727FF014242FF015D5DFF016C6CE701 + 15152801000000011717240118182401000000011C1C28019898E7019D9DFF01 + 9393FF018888FF017777FF015D5DFF010E0E890100000002D0D0D0070101AE01 + 1111FE011C1CFF012828FF013434FF014040FF014C4CFF015858FF016363FE01 + 1818870100000001D0D0D006F8FCF8070000F802000000060000F802F8FCF807 + D0D0D00500000004D0D0D00200000004D0D0D00200000005D0D0D008F12C1101 + F4492802E02A110110020001D0D0D003F12C1101F44A2802E02A110110020001 + D0D0D00700009F010000F5010B0BFF012626FF014040FF015252E70112122801 + 00000001171728018C8CE7019595E7011B1B2801000000011A1A28018C8CE701 + 9191FF018686FF017575FF015252F5010808650100000002D0D0D00700009C01 + 0909C3011C1CFF012828FF013434FF014040FF014C4CFF015858FF013333BE01 + 0303250100000001D0D0D006F8FCF8070000F801000000030000F80200000003 + 0000F801F8FCF807D0D0D00500000004D0D0D00200000004D0D0D00200000004 + D0D0D009F1280D01F3402002E0260E0112020001D0D0D003F1280D01F3402002 + E0260E0112020001D0D0D007000085010000D7010707FF012121FF013636EB01 + 0D0D280100000001151528017F7FE7019595FF019D9DFF019292E70119192801 + 00000001171728018080E9018383FF016D6DFF013636D30100002B0100000002 + D0D0D008020291010F0FBE012828FE013434FF014040FF014B4BFE012C2CBE01 + 0C0C5C0100000002D0D0D006F8FCF807000000030000F80400000003F8FCF807 + D0D0D00500000003D0D0D00300000003D0D0D00300000004D0D0D009F0230901 + F2361802DF230B0113020001D0D0D003F0230901F2361802DF230B0113020001 + D0D0D007000000010000A0010000FB011919FF011F1F9C01000000010F0F2801 + 6D6DE7018686FF018D8DFF019393FF019696FF018888E7011717280100000001 + 52529C017878FF015E5EFB010F0F8B0100000003D0D0D00900003E0108088701 + 12129F0115159F01111187010202250100000002D0D0D007F8FCF80600000003 + 0000F80600000003F8FCF806D0D0D00500000004D0D0D00200000004D0D0D002 + 00000004D0D0D009F0200601F12C1002E01F060115020001D0D0D003F0200601 + F12C1002E01F070115020001D0D0D00700000001000054010000B4010E0EFF01 + 2525F50125259C014C4CE9016767FF017A7AFF018484FF018989FF018B8BFF02 + 7E7EEB0151519C017474F5016767FF012020AE010000150100000003D0D0D00A + 00000006D0D0D008F8FCF80500000003F8FCF8030000F802F8FCF80300000003 + F8FCF805D0D0D00600000002D0D0D00400000002D0D0D00400000002D0D0D00A + F01B0401F0220802DE1A030117020001D0D0D003F01B0401F0220902DE1A0401 + 17020001D0D0D00800000001000085010101D6011717FF012D2DFF014141FF01 + 5353FF016464FF017171FF017B7BFF017F7FFF027A7AFF017171FF016363FF01 + 3939D6010606580100000003D0D0D019F8FCF80400000003F8FCF80A00000003 + F8FCF804D0D0D01EEE180001DF160001DE160001E016000118020001D0D0D003 + EF170001DE150001DB150001DE15000118020001D0D0D0090000000100007601 + 0303B0011919FB012D2DFF013E3EFF014C4CFF015858FF016060FF016464FF02 + 5F5FFF015454FB011E1EAE010606580100000003D0D0D01AF8FCF80300000003 + F8FCF80C00000003F8FCF803D0D0D01EFF2B0001090000010400000100000002 + D0D0D00400000004D0D0D0090000000200002C0101018F010E0ED2012424F501 + 3434FF013E3EFF014545FF014848FF014242F5012C2CD3010D0D8B0100001501 + 00000004D0D0D01AF8FCF80200000003F8FCF80E00000003F8FCF802D0D0D035 + 000000030000360101016901060689010B0BA1010D0DA0010A0A890105056501 + 00002B0100000005D0D0D01BF8FCF80200000002F8FCF81000000002F8FCF802 + D0D0D0370000000CD0D0D01DF8FCF818D0D0D0380000000AD0D0D01EF8FCF818 + D0D0D018C0C0C030D0D0D0060000BC03D0D0D01A00000001D0D0D00200000001 + D0D0D021C0C0C030D0D0D0060000BC011A1AD5010000BC02D0D0D01900000005 + D0D0D020C0C0C030D0D0D0060000BC014949EA013636E2010000BC02D0D0D01A + 00000002D0D0D021C0C0C030D0D0D0060000BC016B6BEE017D7DFB014545E201 + 0000BC02D0D0D00100000001D0D0D00200000001D0D0D037C0C0C030D0D0D006 + 0000BC018686EE01A9A9FF019595FB015454E2010000BC0200000005D0D0D036 + C0C0C030D0D0D0030606CF011A1AD7012626DC011818D2018888EA01BDBDFC01 + C3C3FF01ADADFB016262E2010000BC02D0D0D00100000009D0D0D0030000AA01 + 1717D7012323DC012B2BDF013030E1013030E0042222DB010000B601D0D0D022 + C0C0C030D0D0D0021414D5012F2FE1016C6CFD016F6FFF013E3EE4017070E301 + 9E9EF201A7A7F501AFAFF801A1A1F2014848D4010000BC01D0D0D00300000007 + D0D0D0020000CE011F1FDB015F5FF8016F6FFF075353F20100004E0100000001 + D0D0D021C0C0C00B0000F802C0C0C0170000F801C0C0C00BD0D0D0010505CE01 + 3636E5016F6FFF026060F7011E1ECF015858DB017F7FE8018888EB018787EB01 + 5656D90100006F0100001401D0D0D00300000007D0D0D0010000AA012121DB01 + 6C6CFE016F6FFF016363FA014545E5013535D7013434D7013232D5013030D401 + 2E2ED3012121D00100004D0100000001D0D0D00100000003D0D0D00200000001 + D0D0D00BFF041F01FF0F2701FF0E2701FF031D01FF001A02D0D0D009C0C0C00B + 0000F802C0C0C0170000F801C0C0C00BD0D0D0011B1BD8016C6CFE016F6FFF01 + 2727CA010C0C8301000057014141D4016060DE016161DF013F3FD20100006F01 + 00001401D0D0D00400000007D0D0D0011414D6015C5CF7016F6FFF013C3CDB01 + 0E0E9601000037010000130200000D0100000A01000006010000020100000002 + D0D0D00100000007D0D0D009FF0F2601FF2A3F01FF394D02FF2A3F01FF0F2701 + FE001A01DF001601D0D0D008C0C0C00B0000F802C0C0C0170000F801C0C0C00B + D0D0D0012B2BDE016F6FFF016060F7010C0C840100000001000079012A2ACC01 + 3D3DD2012929CB0100006F0100001401D0D0D00100000004D0D0D0082424DD01 + 6F6FFF016C6CFE011313A8010000000100002F010000A6010000B50100000005 + D0D0D00400000001D0D0D00300000001D0D0D008FF041F01FF2B3F01FF4C5E01 + FF627202FF4C5E01FF2B4001FF041E01FE001A0188000E01D0D0D007C0C0C00B + 0000F802C0C0C0170000F801C0C0C00B0000CC013333E2016F6FFF013A3ADC01 + 00002A01000000010000B0011111C4011313C40100006F0100001401D0D0D002 + 00000004D0D0D0082C2CE0016F6FFF014F4FED0104045C01000000010000BB01 + 1A1AD5010000BD010000BF01D0D0D015FF112A01FF3D5101FF677601FF9FA902 + FF677601FF3D5101FF122A01FF001A01CC00150100000001D0D0D006C0C0C00B + 0000F802C0C0C0170000F801C0C0C00BD0D0D0012D2DDF016F6FFF016060F701 + 0C0C8601000000010000BA010000BD0100006F010000140100000001D0D0D00E + 2B2BDF016F6FFF014F4FED0104045C01000000010000BB014949EA013636E201 + 0000B5010000BF01D0D0D014FF152D01FF425501FF6E7C01FFBBC302FF6E7C01 + FF425501FF152D01FF001A01F000180100000001D0D0D006C0C0C00B0000F802 + C0C0C0170000F801C0C0C00BD0D0D0011D1DD6016C6CFE016F6FFF012323C701 + 0303730100008B010000BA0100001401D0D0D0102121DB016F6FFF016C6CFE01 + 1313A801000000010000BB016B6BEE017D7DFB014545E2010000B5010000BF01 + D0D0D013FF0D2601FF374B01FF5D6D01FF828E02FF5D6D01FF374B01FF0D2601 + FF001A01F000180100000001D0D0D006C0C0C00B0000F802C0C0C0170000F801 + C0C0C00BD0D0D0010505B0013535DD016F6FFF016D6DFE014444E6012F2FDC01 + 2E2EDF092929DD012020D7011515CF010000330100000001D0D0D0041212D301 + 4D4DEC016F6FFF013C3CDB011010B0010000BE018686EE01A9A9FF019595FB01 + 5454E2010000B5010000BF01D0D0D012FF001A01FF203601FF3E5101FF516202 + FF3E5101FF203601FF001A02CC00150100000001D0D0D006C0C0C0240000F801 + C0C0C00BD0D0D001000000011111B3012D2DD3016C6CFE016F6FFF0D5C5CF501 + 1616BF0100000002D0D0D0041818C8016666FB016F6FFF016363FA013333DC01 + 8888EA01BDBDFC01C3C3FF01ADADFB016262E2010000B5010000BF01D0D0D002 + 00000008D0D0D007FF001A01FE011B01FF193101FF273D02FF193101FF011B01 + FF001A01FE001A015900090100000001D0D0D006C0C0C030D0D0D00200000001 + 020256011616B0012121C0012A2AD0012C2CD2094242E3016868FC016F6FFF01 + 4F4FEB010A0A830100000002D0D0D0030000B7011515B9015959F2016F6FFF01 + 5353EE017070E3019E9EF201A7A7F501AFAFF801A1A1F3014848D4010000A901 + D0D0D00200000008D0D0D008DF001601FE001A01FF001A04FE001A019E001001 + 00000002D0D0D006C0C0C00B0000F802C0C0C0170000F801C0C0C00BD0D0D003 + 0000000D010136011313B1016060F7016F6FFF011A1AB50100000002D0D0D004 + 00000E010E0E93011C1CB7011D1DC8015858DB017F7FE8018888EB018787EB01 + 5656DA0100006F0100001601D0D0D01388000E01CC001501F0001802CC001501 + 5900090100000002D0D0D007C0C0C00B0000F802C0C0C023D0D0D0030000000E + 00005C013939E0016F6FFF012525C80100000002D0D0D0050000000200005A01 + 4141D4016060DE016161DF013F3FD30100006F0100001601D0D0D01500000006 + D0D0D008C0C0C030D0D0D00500000009D0D0D0030000A5013636E1016F6FFF01 + 2F2FD40100000A0100000001D0D0D0070000B9012A2ACC013D3DD3012929CC01 + 00006F0100001601D0D0D024C0C0C030D0D0D00700000007D0D0D0030000CC01 + 3131E1016F6FFF012F2FD3010000060100000001D0D0D0070000BB011111C401 + 1313C40100006F0100001601D0D0D025C0C0C030D0D0D0070000000B2222DA01 + 5353F2012121D1010000020100000001D0D0D0070000BB010000BE0100006F01 + 00001601D0D0D026C0C0C030D0D0D00500000009D0D0D001000000030000B301 + 000057010000520100000002D0D0D0070000BF010000B90100001501D0D0D002 + 00000004D0D0D021C0C0C030D0D0D00300000004D0D0D00B00000005D0D0D00C + 00000004D0D0D021C0C0C030D0D0D00600000001D0D0D0AC00000001D0D0D002 + 00000001D0D0D0579F9F9F01A0A0A001D0D0D01B00000005D0D0D00FBFBFBF01 + A1A1A1019F9F9F01A0A0A0049F9F9F01A1A1A101BFBFBF01D0D0D03D9F9F9F01 + A0A0A001A3A3A301D0D0D01C00000002D0D0D00FA2A2A201A0A0A009A6A6A601 + A8A8A801D0D0D0259F9F9F01D0D0D0169F9F9F01A0A0A002A3A3A301D0D0D003 + 00000001D0D0D00200000001D0D0D023FFFFFF01A1A1A101A0A0A00BA2A2A201 + B1B1B101FFFFFF01D0D0D00AA0A0A004D0D0D004A0A0A004D0D0D00DA0A0A001 + BFBFBF01D0D0D0159F9F9F01A0A0A003A3A3A301D0D0D00200000005D0D0D022 + A1A1A101A0A0A00EC2C2C201FFFFFF01D0D0D009A0A0A004FFFFFF01D0D0D003 + A0A0A004FFFFFF01D0D0D00CA0A0A001A2A2A201BBBBBB01D0D0D011A0A0A008 + A3A3A301D0D0D00300000009D0D0D003929292019F9F9F01A0A0A008FFFFFF01 + D0D0D00DA2A2A201A0A0A0029F9F9F01959595019E9E9E01A0A0A0069D9D9D01 + 949494019F9F9F01A0A0A001A3A3A301E3E3E301D0D0D009A0A0A004FFFFFF01 + D0D0D003A0A0A004FFFFFF01D0D0D00CA0A0A003B8B8B801FFFFFF01D0D0D00E + A0A0A00AA3A3A301D0D0D00400000007D0D0D0029F9F9F01A0A0A00AFFFFFF01 + D0D0D00CBFBFBF01A0A0A00392929201808080018D8D8D01A5A5A501A0A0A004 + 9D9D9D018585850180808001ACACAC01A5A5A501A0A0A001B2B2B201F9F9F901 + D0D0D008A0A0A004FFFFFF01D0D0D003A0A0A004FFFFFF01D0D0D00CA0A0A004 + B3B3B302D0D0D00CA0A0A00AA3A3A301FFFFFF02D0D0D00300000007D0D0D001 + 99999901A0A0A00BFFFFFF01D0D0D00200000003D0D0D00200000001D0D0D004 + A1A1A101A0A0A0039D9D9D018A8A8A018080800194949401A5A5A501A0A0A002 + 9D9D9D01858585018080800192929201F5F5F501C7C7C701A0A0A002DEDEDE01 + FFFFFF01D0D0D007A0A0A004FFFFFF01D0D0D003A0A0A004FFFFFF01D0D0D00C + A0A0A005AEAEAE01B7B7B701D0D0D00BA0A0A003ACACAC01E5E5E501F8F8F801 + A0A0A003A3A3A301FFFFFF02D0D0D00400000007D0D0D001A0A0A003A3A3A301 + D5D5D501F3F3F301FFFFFF07D0D0D00200000007D0D0D003A1A1A101A0A0A004 + A3A3A301909090018080800193939301A6A6A6019D9D9D018585850180808001 + 92929201F3F3F301F0F0F001A8A8A801A0A0A002D0D0D001FFFFFF01D0D0D007 + A0A0A004FFFFFF01D0D0D003A0A0A004FFFFFF01D0D0D00CA0A0A006A9A9A901 + BCBCBC01D0D0D00AA0A0A003E5E5E501FFFFFF01F5F5F501A0A0A002A3A3A301 + FFFFFF02D0D0D00100000004D0D0D008A0A0A003D4D4D401FFFFFF03D0D0D00A + 00000001D0D0D00300000001D0D0D003A0A0A006A4A4A4019090900180808001 + 92929201868686018080800192929201F3F3F301F0F0F001A9A9A901A0A0A003 + BCBCBC01FFFFFF01D0D0D007A0A0A004FFFFFF01D0D0D003A0A0A004FFFFFF01 + D0D0D00CA0A0A007A4A4A401BDBDBD01D0D0D008A0A0A004FBFBFB01FFFFFF01 + 9F9F9F01A0A0A001A1A1A101FFFFFF02D0D0D00200000004D0D0D008A0A0A003 + F3F3F301FFFFFF01D0D0D001A0A0A001D0D0D012A0A0A007A3A3A3018F8F8F01 + 8080800291919101F3F3F301F0F0F001A9A9A901A0A0A004A9A9A901FFFFFF01 + D0D0D007A0A0A004FFFFFF01D0D0D003A0A0A004FFFFFF01D0D0D00CA0A0A008 + A1A1A101BBBBBB01D0D0D008A0A0A003EAEAEA01FFFFFF019F9F9F01A0A0A001 + FFFFFF02D0D0D00FA0A0A003F3F3F301FFFFFF01D0D0D001A0A0A002FFFFFF01 + D0D0D010A0A0A0079D9D9D01868686018080800292929201E7E7E701A9A9A901 + A0A0A005A9A9A901FFFFFF01D0D0D007A0A0A004FFFFFF01D0D0D003A0A0A004 + FFFFFF01D0D0D00CA0A0A008A1A1A101D7D7D701FFFFFF01D0D0D007A0A0A003 + AFAFAF01C6C6C601A0A0A001FFFFFF02D0D0D010A0A0A003D2D2D201FFFFFF01 + D0D0D001A0A0A003FFFFFF01D0D0D00FA0A0A0069D9D9D018585850180808001 + 90909001949494018080800191919101A7A7A701A0A0A005BCBCBC01FFFFFF01 + D0D0D007A0A0A004FFFFFF01D0D0D003A0A0A004FFFFFF01D0D0D00CA0A0A007 + A5A5A501E4E4E401FFFFFF02D0D0D007A0A0A001A1A1A101A0A0A011D0D0D005 + A0A0A003A3A3A301C5C5C5019C9C9C01A0A0A004FFFFFF01D0D0D00EA1A1A101 + A0A0A0049D9D9D01858585018080800192929201F3F3F301E8E8E80193939301 + 8080800191919101A7A7A701A0A0A004D0D0D001FFFFFF01D0D0D007A0A0A004 + FFFFFF01D0D0D003A0A0A004FFFFFF01D0D0D00CA0A0A006ABABAB01EEEEEE01 + FFFFFF02D0D0D009B2B2B201A3A3A301A0A0A00FB3B3B301ECECEC01D0D0D004 + AAAAAA01A8A8A801A0A0A009FFFFFF01D0D0D00300000008D0D0D002A1A1A101 + A0A0A0039D9D9D01858585018080800192929201F3F3F301F0F0F001A9A9A901 + A3A3A301939393018080800190909001A9A9A901A0A0A003E3E3E301FFFFFF01 + D0D0D007A0A0A004FFFFFF01D0D0D003A0A0A004FFFFFF01D0D0D00CA0A0A005 + B4B4B401F6F6F601FFFFFF02D0D0D00BDFDFDF01C2C2C201B0B0B001A1A1A101 + A0A0A00DCCCCCC01FFFFFF01D0D0D004A1A1A101AFAFAF01A0A0A009FFFFFF01 + D0D0D00200000008D0D0D002BFBFBF01A6A6A601A0A0A0029494940180808001 + 92929201F3F3F301F0F0F001A9A9A901A0A0A002A3A3A3019494940180808001 + C4C4C401ACACAC01A0A0A001B3B3B301FEFEFE01FFFFFF01D0D0D007A0A0A004 + FFFFFF01D0D0D003A0A0A004FFFFFF01D0D0D00CA0A0A004BFBFBF01FCFCFC01 + FFFFFF02D0D0D00C00000001FFFFFF02F1F1F101FFFFFF09F4F4F401C5C5C501 + A0A0A002C0C0C001FFFFFF01D0D0D005F0F0F001CACACA01B9B9B901A7A7A701 + A0A0A005FFFFFF02D0D0D00DA8A8A801A2A2A201A0A0A0019F9F9F01A9A9A901 + F4F4F401F0F0F001A9A9A901A0A0A004A3A3A301C4C4C401FBFBFB01CACACA01 + A3A3A301F0F0F001FFFFFF02D0D0D007A0A0A004FFFFFF01D0D0D003A0A0A004 + FFFFFF01D0D0D00CA0A0A003CDCDCD01FFFFFF03D0D0D00D00000005D0D0D009 + BFBFBF01A0A0A002AEAEAE01FFFFFF01D0D0D006FFFFFF03A0A0A004FFFFFF02 + D0D0D00FB1B1B101A0A0A002A2A2A201C2C2C201A8A8A801A0A0A006A4A4A401 + BFBFBF01A3A3A301D5D5D501FFFFFF02D0D0D008A0A0A004FFFFFF01D0D0D003 + A0A0A004FFFFFF01D0D0D00CA0A0A001A2A2A201DBDBDB01FFFFFF03D0D0D010 + 00000009D0D0D003A0A0A003A5A5A501FFFFFF01D0D0D009A0A0A003FFFFFF02 + D0D0D010FFFFFF01C2C2C201A3A3A301A0A0A00AA3A3A301D5D5D501FFFFFF02 + D0D0D009A0A0A004FFFFFF01D0D0D003A0A0A004FFFFFF01D0D0D00CA0A0A001 + E8E8E801FFFFFF02D0D0D01400000007D0D0D003A0A0A003A3A3A301FFFFFF01 + D0D0D009A0A0A002FFFFFF02D0D0D012FFFFFF01E3E3E301B2B2B201A0A0A008 + B3B3B301F0F0F001FFFFFF03D0D0D00AFFFFFF04D0D0D004FFFFFF04D0D0D00C + 9F9F9F01FFFFFF02D0D0D0150000000A1D1D1D01A0A0A002A3A3A301FFFFFF01 + D0D0D009A0A0A001FCFCFC01FFFFFF01D0D0D015F9F9F901DEDEDE01CFCFCF01 + BCBCBC01A9A9A902BCBCBC01CFCFCF01E3E3E301FEFEFE01FFFFFF02D0D0D025 + FFFFFF01D0D0D01400000009D0D0D00100000003C3C3C301FFFFFF03D0D0D009 + FFFFFF02D0D0D00200000004D0D0D011FFFFFF0AD0D0D03900000004D0D0D00C + FFFFFF01D0D0D00F00000004D0D0D05700000001D0D0D02B00000001D0D0D002 + 00000001D0D0D03500000001D0D0D00200000001D0D0D00B00000001D0D0D002 + 00000001D0D0D02C00000005D0D0D0179F9F9F01A0A0A001D0D0D01B00000005 + D0D0D00A00000005D0D0D02D00000009D0D0D005A0A0A001D0D0D00B9F9F9F01 + A0A0A001A3A3A301D0D0D01C00000002D0D0D00D00000009D0D0D0050000CD01 + 0000CB02D0D0D02100000007D0D0D004A0A0A004D0D0D0099F9F9F01A0A0A002 + A3A3A301D0D0D00300000001D0D0D00200000001D0D0D02500000007D0D0D005 + 2222DB015353F2012323DB010000150100000001D0D0D01F0000000BA0A0A003 + A3A3A301FFFFFF01D0D0D0089F9F9F01A0A0A003A3A3A301D0D0D00200000005 + D0D0D0240000000B0000BF013030E1016F6FFF012F2FD4010000040100000001 + D0D0D01F0000000BA0A0A003A5A5A501FFFFFF01D0D0D005A0A0A008A3A3A301 + D0D0D00300000009D0D0D003929292019F9F9F01A0A0A008FFFFFF01D0D0D010 + 0000000B0000D5013737E4016F6FFF013030D40100000A0100000001D0D0D01B + 00000004D0D0D00BA0A0A003AEAEAE01FFFFFF01D0D0D004A0A0A00AA3A3A301 + D0D0D00400000007D0D0D0029F9F9F01A0A0A00AFFFFFF01D0D0D00C00000004 + D0D0D00B0000C6013A3AE5016F6FFF012929CC010000020100000001D0D0D01B + 00000004D0D0D00AA0A0A004C0C0C001FFFFFF01D0D0D003A0A0A00AA3A3A301 + FFFFFF02D0D0D00300000007D0D0D00199999901A0A0A00BFFFFFF01D0D0D002 + 00000003D0D0D00200000001D0D0D00400000004D0D0D00A0000D0011919D501 + 6161F8016F6FFF012020BB0100000002D0D0D00A00009F010000AF010000BA02 + 0000AE0100009C01D0D0D00CA0A0A011D6D6D601FFFFFF01D0D0D003A0A0A003 + ACACAC01E5E5E501F8F8F801A0A0A003A3A3A301FFFFFF02D0D0D00400000007 + D0D0D001A0A0A003A3A3A301D5D5D501F3F3F301FFFFFF07D0D0D00200000007 + D0D0D0040F0FD1011D1DD9012828DD012F2FE0013030E0094545EB016767FB01 + 6F6FFF016565FA0111119F0100000002D0D0D0090000AB010000CB010000FE01 + 0000FF020000FE010000C40100009101D0D0D00AA0A0A011BFBFBF01FEFEFE01 + FFFFFF01D0D0D003A0A0A003E5E5E501FFFFFF01F5F5F501A0A0A002A3A3A301 + FFFFFF02D0D0D00100000004D0D0D008A0A0A003D4D4D401FFFFFF03D0D0D00A + 00000001D0D0D00300000001D0D0D0031717D6013C3CE7016F6FFF0E6363F801 + 1B1BBF010000110100000002D0D0D00800009F010000CB010000FF060000BE01 + 00003E01D0D0D008A0A0A00FA7A7A701B8B8B801CCCCCC01FCFCFC01FFFFFF02 + D0D0D002A0A0A004FBFBFB01FFFFFF019F9F9F01A0A0A001A1A1A101FFFFFF02 + D0D0D00200000004D0D0D008A0A0A003F3F3F301FFFFFF01D0D0D001A0A0A001 + D0D0D0110C0CCE013E3EE7016F6FFF024F4FED013131D5012C2CD3012F2FD301 + 3030D4023030D5013333D6013333D7013434D7013535D8012B2BCD011E1EB801 + 0F0F960100000D0100000002D0D0D0090000AF010000FE010000FF060000FE01 + 0000870100000001D0D0D007A0A0A003AFAFAF01E8E8E801FCFCFC01FFFFFF0E + D0D0D004A0A0A003EAEAEA01FFFFFF019F9F9F01A0A0A001FFFFFF02D0D0D00F + A0A0A003F3F3F301FFFFFF01D0D0D001A0A0A002FFFFFF01D0D0D00F1D1DD801 + 6D6DFE016F6FFF011F1FC40103035401000021010000520100001B0100000601 + 00000A0100000C0100000F010000110100001301000017010000020100000005 + D0D0D0090000BA010000FF080000A00100000001D0D0D007A0A0A003EAEAEA01 + FFFFFF01F4F4F401A0A0A001D0D0D011A0A0A003AFAFAF01C6C6C601A0A0A001 + FFFFFF02D0D0D010A0A0A003D2D2D201FFFFFF01D0D0D001A0A0A003FFFFFF01 + D0D0D00E2626DB016F6FFF015B5BF5010707700100000001000086011A1ADF01 + 0000C001000078010000000BD0D0D00A0000BA010000FF0800009F0100000001 + D0D0D006A0A0A004FBFBFB01FFFFFF019F9F9F01A0A0A001A1A1A101D0D0D010 + A0A0A001A1A1A101A0A0A011D0D0D005A0A0A003A3A3A301C5C5C5019C9C9C01 + A0A0A004FFFFFF01D0D0D00D2B2BDD016F6FFF013F3FE2010000330100000001 + 0000BF014949EF013636E9010000CC02D0D0D0140000AE010000FE010000FF06 + 0000FE010000870100000001D0D0D007A0A0A003E5E5E501FFFFFF019F9F9F01 + A0A0A002A3A3A301D0D0D00200000006D0D0D008B2B2B201A3A3A301A0A0A00F + B3B3B301ECECEC01D0D0D004AAAAAA01A8A8A801A0A0A009FFFFFF01D0D0D003 + 00000008D0D0D0012525DA016F6FFF016565FB0111119801000000010000CA01 + 6B6BF2017D7DFC014545E9010000CC0200000006D0D0D00D00009C010000C401 + 0000FF060000BE010000240100000001D0D0D007A0A0A003ACACAC01C8C8C801 + A0A0A004A3A3A301D0D0D00100000006D0D0D009DFDFDF01C2C2C201B0B0B001 + A1A1A101A0A0A00DCCCCCC01FFFFFF01D0D0D004A1A1A101AFAFAF01A0A0A009 + FFFFFF01D0D0D00200000008D0D0D0011A1AD4016B6BFD016F6FFF013232D401 + 0C0CA3010000BF018686F201A9A9FF019595FC015454E9010000CC0100004F01 + 00000005D0D0D00E000091010000BE010000FE010000FF020000FE010000BE01 + 00005C0100000002D0D0D007A0A0A001A3A3A301A0A0A008A3A3A301D0D0D004 + 00000007D0D0D00400000001FFFFFF02F1F1F101FFFFFF09F4F4F401C5C5C501 + A0A0A002C0C0C001FFFFFF01D0D0D005F0F0F001CACACA01B9B9B901A7A7A701 + A0A0A005FFFFFF02D0D0D00B0000A4013131DB016F6FFF025757F3011D1DD601 + 8888EE01BDBDFC01C3C3FF01ADADFC016262E9010000CC02D0D0D00200000007 + D0D0D00A00003E01000087010000A00100009F01000087010000240100000002 + D0D0D009B3B3B301A5A5A501A0A0A008A3A3A301D0D0D00300000007D0D0D004 + 00000005D0D0D009BFBFBF01A0A0A002AEAEAE01FFFFFF01D0D0D006FFFFFF03 + A0A0A004FFFFFF02D0D0D00C000000011010B2012E2ED3016D6DFE016F6FFF01 + 3E3EE8017070E7019E9EF201A7A7F501AFAFF801A1A1F4014848DE010000CC01 + D0D0D00200000007D0D0D00B00000006D0D0D00BE0E0E001C3C3C301B0B0B001 + A1A1A101A0A0A004A3A3A301FFFFFF02D0D0D00200000008D0D0D00500000009 + D0D0D003A0A0A003A5A5A501FFFFFF01D0D0D009A0A0A003FFFFFF02D0D0D00E + 0000000103035D011717B0012525C3011A1AD0015858DF017F7FE8018888EB01 + 8787EC015656E0010000780100001701D0D0D00200000008D0D0D01CFFFFFF02 + FBFBFB01A0A0A003A3A3A301FFFFFF01FCFCFC0100000004D0D0D00100000002 + D0D0D00B00000007D0D0D003A0A0A003A3A3A301FFFFFF01D0D0D009A0A0A002 + FFFFFF02D0D0D0100000000300005E014141D8016060DE016161E0013F3FD901 + 000078010000170100000004D0D0D00100000002D0D0D0229F9F9F01A0A0A002 + A3A3A301FFFFFF0200000005D0D0D00E0000000A1D1D1D01A0A0A002A3A3A301 + FFFFFF01D0D0D009A0A0A001FCFCFC01FFFFFF01D0D0D012000000020000B701 + 2A2AD0013D3DD3012929D201000078010000170100000005D0D0D0259F9F9F01 + A0A0A001A3A3A301FFFFFF02D0D0D01200000009D0D0D00100000003C3C3C301 + FFFFFF03D0D0D009FFFFFF02D0D0D00200000004D0D0D00F0000CC011111C901 + 1313CB010000780100001701D0D0D02B9F9F9F01A0A0A001FFFFFF02D0D0D011 + 00000004D0D0D00CFFFFFF01D0D0D00F00000004D0D0D00F0000CC010000C801 + 0000780100001701D0D0D02DFFFFFF02D0D0D01500000001D0D0D02F0000CC01 + 0000C30100001701D0D0D027543A00000000001E101010014040400110101001 + 0000001A0C0C0C01000000020C0C0C010000000B0C0C0C01000000020C0C0C01 + 0000004840404001FFFFFF017070700110101001000000194646460169696901 + 6464640168686801707070010000000A46464601696969016464640168686801 + 707070010000004740404001FFFFFF0270707001101010010000001A13131301 + 171717010000000D13131301171717021A1A1A013B3B3B010B0B0B0117171701 + 2828280111111101000000053D3D3D014040400200000028FFFFFF020000000F + 40404001FFFFFF037070700110101001000000010C0C0C01000000020C0C0C01 + 00000025414141014D4D4D01494949011A1A1A01353535014747470124242401 + 00000005E6E6E601FFFFFF01E9E9E9010C0C0C0101010101000000073B3B3B01 + 7B7B7B01010101010000001CFFFFFF020000000F40404001FFFFFF0470707001 + 1010100160606001727272016262620164646401545454010000002426262601 + 2F2F2F01353535014747470136363601303030011E1E1E012A2A2A011F1F1F01 + 4D4D4D012828280104040401E3E3E301FFFFFF01F0F0F001747474010B0B0B01 + 0000000740404001F6F6F601BABABA010606060100000013FFFFFF0A0000000C + 20202001ACACAC01C8C8C801ECECEC01FFFFFF05707070011010100100000001 + 212121010A0A0A011A1A1A01282828012C2C2C01121212011010100132323201 + 08080801000000030303030185858501B8B8B801D3D3D301E0E0E001E1E1E104 + E9E9E90147474701000000102F2F2F014C4C4C0157575701393939013D3D3D01 + 2E2E2E012323230124242401181818013D3D3D01161616010C0C0C01E5E5E501 + FFFFFF01F1F1F101808080010C0C0C010000000740404001FFFFFF01FCFCFC01 + D3D3D3011414140100000015FFFFFF060000000C5B5B5B01DEDEDE01FFFFFF09 + 404040010000000350505001595959012D2D2D012A2A2A012424240152525201 + 1B1B1B01000000021A1A1A01C4C4C401FDFDFD01FFFFFF08A7A7A70101010101 + 0000000B2D2D2D01464646014A4A4A01505050010000000B16161601E8E8E801 + FFFFFF01EDEDED017A7A7A010B0B0B010000000740404001FFFFFF03E2E2E201 + 2C2C2C01010101010000000FFFFFFF0A0000000B25252501E3E3E301FFFFFF03 + F8F8F801FFFFFF05BFBFBF0193939301000000032B2B2B012F2F2F0138383801 + 4D4D4D0133333301373737011F1F1F010000000103030301CCCCCC01FFFFFF03 + F9F9F901F3F3F301F2F2F202F1F1F102F5F5F501A8A8A8010101010100000001 + 0C0C0C010404040111111101000000021919190100000004111111011D1D1D01 + 1F1F1F012A2A2A010000000A26262601B8B8B801FCFCFC01FFFFFF01E2E2E201 + 6E6E6E010A0A0A010000000740404001FFFFFF04EBEBEB015050500101010101 + 00000012FFFFFF070000000AB7B7B701FFFFFF02EBEBEB01C0C0C001AAAAAA01 + FFFFFF04BFBFBF019393930100000004353535014E4E4E015A5A5A013E3E3E01 + 41414101383838011C1C1C01000000017D7D7D01FBFBFB01FFFFFF01F3F3F301 + CCCCCC019E9E9E01919191018989890187878701868686018585850183838301 + 8282820101010101000000015656560163636301606060012B2B2B0146464601 + 62626201222222010000000442424201B8B8B801CECECE01DFDFDF01E1E1E109 + EFEFEF01FFFFFF03CFCFCF0159595901080808010000000740404001FFFFFF05 + F1F1F1017C7C7C01010101010000000EFFFFFF0B00000009D3D3D301FFFFFF02 + C0C0C0017070700163636301FFFFFF03BFBFBF01939393010000000144444401 + 494949014E4E4E013939390100000008BDBDBD01FFFFFF02D8D8D80184848401 + 4242420148484801111111010101010500000004010101010000000308080801 + 0000000383838301E9E9E901FFFFFF0FE7E7E701878787013D3D3D0105050501 + 0000000740404001FFFFFF06F6F6F601A3A3A3010202020100000011FFFFFF05 + 00000001FFFFFF020000000706060601E1E1E101FFFFFF01F4F4F40192929201 + 3131310144444401FFFFFF02BFBFBF0193939301000000021E1E1E0117171701 + 222222012020200100000008D1D1D101FFFFFF01FCFCFC01AEAEAE013B3B3B01 + 40404001FFFFFF0170707001101010010000000F2A2A2A01E8E8E801FFFFFF02 + FCFCFC01F2F2F201F1F1F104F2F2F204F3F3F301EDEDED01E1E1E101CBCBCB01 + 87878701585858010D0D0D010000000840404001FFFFFF07FAFAFA01C4C4C401 + 090909010000000CFFFFFF0200000002FFFFFF0600000001FFFFFF0100000008 + D2D2D201FFFFFF02BBBBBB011818180141414101FFFFFF01BFBFBF0193939301 + 020202010000000ED0D0D001FFFFFF01FCFCFC01AEAEAE011111110140404001 + FFFFFF0275757501101010010000000EB0B0B001FFFFFF02EAEAEA01AAAAAA01 + 8E8E8E01A1A1A101898989018282820183838301848484018585850286868601 + 8787870180808001777777016262620147474701101010010101010100000008 + 40404001FFFFFF08FEFEFE01D9D9D9011A1A1A010000000AFFFFFF0B0000000A + B5B5B501FFFFFF02E9E9E9015757570116161601414141019393930100000010 + B9B9B901FFFFFF02D7D7D7011414140140404001FFFFFF037575750110101001 + 0000000DC7C7C701FFFFFF02B7B7B7016C6C6C0162626201FFFFFF0177777701 + 1B1B1B010C0C0C070B0B0B010909090106060601010101010000000940404001 + FFFFFF08FEFEFE01E2E2E201696969010101010100000009FFFFFF0700000001 + FFFFFF030000000A29292901EBEBEB01FFFFFF02F7F7F701E4E4E401DEDEDE02 + DDDDDD07D2D2D201BDBDBD018C8C8C0108080801010101010000000461616101 + F8F8F801FFFFFF01F3F3F301AEAEAE0161616101FFFFFF047575750110101001 + 0000000CD2D2D201FFFFFF01F7F7F701959595012B2B2B0144444401FFFFFF02 + 70707001101010010000001340404001FFFFFF07FAFAFA01D6D6D6016A6A6A01 + 0C0C0C010000000DFFFFFF0300000002FFFFFF030000000A010101016D6D6D01 + EDEDED01FFFFFF0EFCFCFC01C6C6C601121212010202020100000004C7C7C701 + FFFFFF03F8F8F801FFFFFF057575750110101001000000021010100113131302 + 2E2E2E0112121201131313010D0D0D011616160100000001C8C8C801FFFFFF02 + C6C6C6011515150141414101FFFFFF037070700110101001282828012E2E2E02 + 3F3F3F0135353501020202010000000C40404001FFFFFF06F6F6F601C7C7C701 + 565656010505050100000013FFFFFF030000000B050505014D4D4D01D2D2D201 + E4E4E401EFEFEF01F1F1F109F8F8F801FFFFFF02FAFAFA01989898010E0E0E01 + 01010101000000030E0E0E01D6D6D601FCFCFC01FFFFFF084747470100000002 + 4C4C4C016C6C6C0176767601585858015D5D5D014F4F4F012D2D2D0131313101 + 00000001ADADAD01FFFFFF02EFEFEF017F7F7F014A4A4A01FFFFFF0470707001 + 292929013D3D3D014B4B4B015F5F5F0133333301040404010000000C40404001 + FFFFFF05F2F2F201B4B4B401424242010202020100000013FFFFFF030000000D + 121212011F1F1F0150505001717171017D7D7D018080800893939301DADADA01 + FEFEFE01FFFFFF01DCDCDC013F3F3F01060606010000000412121201B2B2B201 + E0E0E001F2F2F201FFFFFF05BFBFBF018C8C8C010000000B22222201EBEBEB01 + FFFFFF02FDFDFD01F2F2F201FFFFFF057070700110101001000000022F2F2F01 + 545454015E5E5E012C2C2C015757570132323201303030010000000740404001 + FFFFFF04EDEDED019F9F9F012F2F2F010101010100000014FFFFFF040000000C + 77777701767676017575750168686801464646010C0C0C080D0D0D012F2F2F01 + EEEEEE01FFFFFF01E9E9E9015C5C5C010808080100000005030303013D3D3D01 + 88888801FFFFFF04BFBFBF018C8C8C010000000C010101016D6D6D01ECECEC01 + FFFFFF0940404001000000020E0E0E011B1B1B021D1D1D010C0C0C011D1D1D01 + 242424010000000740404001FFFFFF03E7E7E7018B8B8B011F1F1F0101010101 + 00000015FFFFFF040000000E29292901010101013D3D3D01464646013A3A3A01 + 2626260115151501444444010E0E0E01000000030F0F0F01E7E7E701FFFFFF01 + F1F1F101757575010B0B0B010000000741414101FFFFFF03BFBFBF018C8C8C01 + 0000000E0505050150505001D0D0D001E5E5E501F7F7F701FFFFFF05BFBFBF01 + 8F8F8F01000000024141410168686801717171016B6B6B016D6D6D015B5B5B01 + 4A4A4A01575757010000000640404001FFFFFF01FCFCFC01DFDFDF0177777701 + 13131301010101010000002A353535013E3E3E011C1C1C012222220112121201 + 3F3F3F01161616010000000304040401E2E2E201FFFFFF01F1F1F1017F7F7F01 + 0C0C0C010000000740404001FFFFFF02BFBFBF018C8C8C010000001006060601 + 1E1E1E015252520192929201FFFFFF04BFBFBF01909090011212120110101001 + 2A2A2A01020202010000000114141401010101010000000A40404001F6F6F601 + D1D1D10164646401090909010000002C414141015A5A5A01515151015D5D5D01 + 4C4C4C015454540139393901292929015C5C5C01515151010E0E0E01E7E7E701 + FFFFFF01F4F4F401808080010C0C0C010000000740404001FFFFFF01C3C3C301 + 8C8C8C0100000012020202010707070147474701FFFFFF03BFBFBF018F8F8F01 + 282828015C5C5C014F4F4F0154545401060606010000000D3B3B3B017C7C7C01 + 4F4F4F01040404010000002B0A0A0A0103030301222222013030300131313101 + 21212101222222011C1C1C010E0E0E0100000001101010011111110116161601 + 4545450197979701A0A0A001737373010D0D0D01000000071010100141414101 + 919191010000000218181801303030023F3F3F010000000F40404001FFFFFF02 + BFBFBF018F8F8F0100000015010101010000002A707070027878780129292901 + 0000000B010101010C0C0C020B0B0B01010101010000000C2626260136363601 + 393939013A3A3A010000000F40404001FFFFFF01BFBFBF018F8F8F0100000044 + 080808010000002F10101001434343018F8F8F01000000FF0000003832323201 + 7F7F7F01AEAEAE01C8C8C801C9C9C901AFAFAF01828282013737370104040401 + 0101010100000020FFFFFF0200000010FFFFFF020000003818181801BBBBBB01 + F4F4F401FFFFFF06F6F6F601C3C3C30125252501030303010000001FFFFFFF03 + 0000000EFFFFFF0300000020D9D9D901DCDCDC02E2E2E20100000004DDDDDD01 + E0E0E002E5E5E5010000000B68686801DADADA01FFFFFF0AE7E7E7017C7C7C01 + 09090901010101010000001EFFFFFF030000000CFFFFFF0300000021D8D8D801 + FFFFFF02F2F2F2018C8C8C0100000003D8D8D801FFFFFF02F2F2F2018C8C8C01 + 0000000968686801F0F0F001FFFFFF0CF6F6F6018C8C8C010D0D0D0101010101 + 0000001EFFFFFF030000000AFFFFFF0300000022D8D8D801FFFFFF02F2F2F201 + 8D8D8D0100000003D8D8D801FFFFFF02F2F2F2018D8D8D010000000818181801 + DADADA01FFFFFF0EEBEBEB0153535301090909010000001FFFFFFF0300000003 + FFFFFF0200000003FFFFFF0300000023D8D8D801FFFFFF02F1F1F1018D8D8D01 + 00000003D8D8D801FFFFFF02F1F1F1018D8D8D0100000008BBBBBB01FFFFFF10 + D9D9D90125252501030303010000000A2D2D2D01ACACAC01C5C5C501C4C4C401 + ABABAB012C2C2C010000000FFFFFFF0C0000000B212121010303030100000004 + 171717010D0D0D0100000004090909011A1A1A01010101010000000AD8D8D801 + FFFFFF02F1F1F1018E8E8E0100000003D8D8D801FFFFFF02F1F1F1018E8E8E01 + 0000000732323201F4F4F401FFFFFF10F8F8F8017F7F7F011010100101010101 + 0000000873737301E5E5E501FFFFFF04EEEEEE017D7D7D010000000FFFFFFF0A + 0000000A36363601D0D0D001B3B3B301D4D4D40168686801020202010A0A0A01 + BEBEBE01BFBFBF01CCCCCC01A2A2A20103030301000000018A8A8A01D0D0D001 + BABABA01C4C4C401202020010101010100000008D8D8D801FFFFFF02F1F1F101 + 8E8E8E0100000003D8D8D801FFFFFF02F1F1F1018E8E8E01000000077F7F7F01 + FFFFFF12BBBBBB012F2F2F0104040401000000072D2D2D01E5E5E501FFFFFF06 + F1F1F1015F5F5F010000000EFFFFFF0A0000000AB5B5B5016D6D6D0169696901 + 6A6A6A01F1F1F101414141016F6F6F01A4A4A4016161610162626201DCDCDC01 + 8181810129292901E2E2E2014D4D4D0169696901ADADAD01B9B9B90113131301 + 0101010100000007D8D8D801FFFFFF02F2F2F2018F8F8F0100000003D8D8D801 + FFFFFF02F2F2F2018F8F8F0100000007AEAEAE01FFFFFF12D5D5D50146464601 + 0808080100000007ACACAC01FFFFFF08D5D5D501202020010000000DFFFFFF0A + 0000000A2D2D2D015C5C5C013131310110101001ECECEC018181810127272701 + 464646015252520107070701B1B1B1019E9E9E0133333301353535016F6F6F01 + 0A0A0A0169696901BFBFBF01494949010303030100000007D8D8D801FFFFFF02 + F2F2F2018F8F8F0100000003D8D8D801FFFFFF02F2F2F2018F8F8F0100000007 + C8C8C801FFFFFF12E3E3E3015C5C5C010A0A0A0100000007C5C5C501FFFFFF08 + E4E4E401606060010000000CFFFFFF0C0000000901010101171717010D0D0D01 + BABABA018686860177777701101010020D0D0D017C7C7C01C1C1C10160606001 + 323232010A0A0A01131313013E3E3E01E0E0E001575757015555550103030301 + 00000007D8D8D801FFFFFF02F1F1F1019090900100000003D8D8D801FFFFFF02 + F1F1F1019090900100000007C9C9C901FFFFFF12E3E3E301707070010D0D0D01 + 00000007C4C4C401FFFFFF08E4E4E4017E7E7E010000000CFFFFFF0C0000000A + 0101010198989801959595015E5E5E0144444401030303010101010150505001 + CCCCCC014B4B4B0161616101080808010101010116161601E3E3E3014E4E4E01 + 6F6F6F01191919010101010100000007D8D8D801FFFFFF02F1F1F10190909001 + 00000003D8D8D801FFFFFF02F1F1F1019090900100000007AFAFAF01FFFFFF12 + D7D7D701707070010D0D0D0100000007ABABAB01FFFFFF08D6D6D6017E7E7E01 + 0000000DFFFFFF0A0000000CDDDDDD01616161014C4C4C010505050100000002 + 969696017E7E7E01666666010E0E0E01000000024D4D4D01B1B1B10172727201 + 1F1F1F010202020100000008D8D8D801FFFFFF02F2F2F2019191910100000003 + D8D8D801FFFFFF02F2F2F201919191010000000782828201FFFFFF12C0C0C001 + 5C5C5C010A0A0A01000000072C2C2C01EEEEEE01FFFFFF06F1F1F1019D9D9D01 + 606060010000000DFFFFFF0A0000000C23232301707070011313130101010101 + 0000000218181801555555013535350102020201000000020E0E0E013B3B3B01 + 585858010404040100000009D8D8D801FFFFFF02F2F2F2019191910100000003 + D8D8D801FFFFFF02F2F2F201919191010000000737373701F6F6F601FFFFFF10 + F8F8F8019A9A9A014646460108080801000000087D7D7D01F1F1F101FFFFFF04 + F1F1F101B9B9B9018B8B8B01202020010000000DFFFFFF0A0000000CF8F8F801 + 3B3B3B010404040100000003AFAFAF01797979010B0B0B010000000366666601 + BBBBBB01121212010101010100000009D8D8D801FFFFFF02F2F2F20191919101 + 00000003D8D8D801FFFFFF02F2F2F201919191010000000704040401C3C3C301 + FFFFFF10DCDCDC017F7F7F012F2F2F0104040401000000095F5F5F01D5D5D501 + E4E4E402D6D6D6019D9D9D018B8B8B01424242010000000DFFFFFF0C0000000B + 0404040177777701181818010101010100000002030303015656560139393901 + 020202010000000202020201343434015B5B5B010303030100000009D8D8D801 + FFFFFF02F1F1F1019292920100000003D8D8D801FFFFFF02F1F1F10192929201 + 000000070101010125252501E7E7E701FFFFFF0EEDEDED019292920162626201 + 10101001010101010000000A20202001606060017E7E7E026060600120202001 + 0000000DFFFFFF0300000003FFFFFF0200000003FFFFFF030000000B04040401 + 010101010000000403030301020202010000000402020201030303010000000A + D8D8D801FFFFFF02F2F2F2019292920100000003D8D8D801FFFFFF02F2F2F201 + 9292920100000008030303017C7C7C01F6F6F601FFFFFF0CF8F8F801B9B9B901 + 7777770125252501030303010000001DFFFFFF030000000AFFFFFF0300000022 + DEDEDE01F1F1F102F2F2F2019393930100000003DEDEDE01F0F0F002F1F1F101 + 9393930100000009090909018D8D8D01EBEBEB01FFFFFF0AEDEDED01B9B9B901 + 7D7D7D0141414101090909010000001DFFFFFF030000000CFFFFFF0300000021 + 060606018E8E8E018D8D8D018C8C8C02000000048C8C8C040000000901010101 + 0D0D0D0152525201D9D9D901F8F8F801FFFFFF06F8F8F801DCDCDC0192929201 + 77777701404040010D0D0D01010101010000001CFFFFFF030000000EFFFFFF03 + 000000370101010109090901252525017F7F7F01BBBBBB01D4D4D401E3E3E302 + D7D7D701C0C0C0019A9A9A017F7F7F0162626201252525010909090101010101 + 0000001DFFFFFF0200000010FFFFFF020000003903030301101010012F2F2F01 + 464646015C5C5C01707070025C5C5C01464646012F2F2F011010100103030301 + 0000006D0101010104040401080808010A0A0A010D0D0D020A0A0A0108080801 + 0404040101010101000000841010100140404001101010010000001A0C0C0C01 + 000000020C0C0C010000005740404001FFFFFF01707070011010100100000019 + 46464601696969016464640168686801707070010000005640404001FFFFFF02 + 70707001101010010000001A13131301171717010000005740404001FFFFFF03 + 7070700110101001000000010C0C0C01000000020C0C0C010000006D40404001 + FFFFFF0470707001101010016060600172727201626262016464640154545401 + 0000006920202001ACACAC01C8C8C801ECECEC01FFFFFF057070700110101001 + 00000001212121010A0A0A011A1A1A01282828012C2C2C011212120110101001 + 3232320108080801000000030303030185858501B8B8B801D3D3D301E0E0E001 + E1E1E104E9E9E90147474701000000545B5B5B01DEDEDE01FFFFFF0940404001 + 0000000350505001595959012D2D2D012A2A2A0124242401525252011B1B1B01 + 000000021A1A1A01C4C4C401FDFDFD01FFFFFF08A7A7A701010101010000002C + FFFFFF0200000017FFFFFF010000000C25252501E3E3E301FFFFFF03F8F8F801 + FFFFFF05BFBFBF0193939301000000032B2B2B012F2F2F01383838014D4D4D01 + 33333301373737011F1F1F010000000103030301CCCCCC01FFFFFF03F9F9F901 + F3F3F301F2F2F202F1F1F102F5F5F501A8A8A80101010101000000010C0C0C01 + 040404011111110100000002191919010000000B3A3A3A01AFAFAF01E5E5E502 + AFAFAF013A3A3A0100000014FFFFFF0200000017FFFFFF010000000CB7B7B701 + FFFFFF02EBEBEB01C0C0C001AAAAAA01FFFFFF04BFBFBF019393930100000004 + 353535014E4E4E015A5A5A013E3E3E0141414101383838011C1C1C0100000001 + 7D7D7D01FBFBFB01FFFFFF01F3F3F301CCCCCC019E9E9E019191910189898901 + 8787870186868601858585018383830182828201010101010000000156565601 + 63636301606060012B2B2B014646460162626201222222010000000978787801 + FDFDFD01FFFFFF04FEFEFE018989890100000013FFFFFF0200000017FFFFFF01 + 0000000CD3D3D301FFFFFF02C0C0C0017070700163636301FFFFFF03BFBFBF01 + 939393010000000144444401494949014E4E4E013939390100000008BDBDBD01 + FFFFFF02D8D8D801848484014242420148484801111111010101010500000004 + 010101010000000308080801000000083A3A3A01FDFDFD01FFFFFF06FEFEFE01 + 6D6D6D0100000012FFFFFF0200000017FFFFFF010000000B06060601E1E1E101 + FFFFFF01F4F4F401929292013131310144444401FFFFFF02BFBFBF0193939301 + 000000021E1E1E0117171701222222012020200100000008D1D1D101FFFFFF01 + FCFCFC01AEAEAE013B3B3B0140404001FFFFFF01707070011010100100000015 + AFAFAF01FFFFFF08DBDBDB012020200100000011FFFFFF0200000017FFFFFF01 + 0000000CD2D2D201FFFFFF02BBBBBB011818180141414101FFFFFF01BFBFBF01 + 93939301020202010000000ED0D0D001FFFFFF01FCFCFC01AEAEAE0111111101 + 40404001FFFFFF02757575011010100100000014E5E5E501FFFFFF08F3F3F301 + 6060600100000011FFFFFF0200000017FFFFFF010000000CB5B5B501FFFFFF02 + E9E9E9015757570116161601414141019393930100000010B9B9B901FFFFFF02 + D7D7D7011414140140404001FFFFFF03757575011010100100000013E5E5E501 + FFFFFF08F3F3F3017E7E7E0100000011FFFFFF0200000017FFFFFF010000000C + 29292901EBEBEB01FFFFFF02F7F7F701E4E4E401DEDEDE02DDDDDD07D2D2D201 + BDBDBD018C8C8C0108080801010101010000000461616101F8F8F801FFFFFF01 + F3F3F301AEAEAE0161616101FFFFFF04757575011010100100000012AFAFAF01 + FFFFFF08DBDBDB017E7E7E010000002AFFFFFF010000000C010101016D6D6D01 + EDEDED01FFFFFF0EFCFCFC01C6C6C601121212010202020100000004C7C7C701 + FFFFFF03F8F8F801FFFFFF057575750110101001000000021010100113131302 + 2E2E2E0112121201131313010D0D0D0116161601000000073A3A3A01FEFEFE01 + FFFFFF06FEFEFE01A6A6A6016060600100000038050505014D4D4D01D2D2D201 + E4E4E401EFEFEF01F1F1F109F8F8F801FFFFFF02FAFAFA01989898010E0E0E01 + 01010101000000030E0E0E01D6D6D601FCFCFC01FFFFFF084747470100000002 + 4C4C4C016C6C6C0176767601585858015D5D5D014F4F4F012D2D2D0131313101 + 0000000889898901FEFEFE01FFFFFF04FEFEFE01C2C2C2018B8B8B0120202001 + 00000011FFFFFF0200000017FFFFFF010000000E121212011F1F1F0150505001 + 717171017D7D7D018080800893939301DADADA01FEFEFE01FFFFFF01DCDCDC01 + 3F3F3F01060606010000000412121201B2B2B201E0E0E001F2F2F201FFFFFF05 + BFBFBF018C8C8C01000000136D6D6D01DBDBDB01F3F3F302DBDBDB01A6A6A601 + 8B8B8B014242420100000012FFFFFF0200000026777777017676760175757501 + 68686801464646010C0C0C080D0D0D012F2F2F01EEEEEE01FFFFFF01E9E9E901 + 5C5C5C010808080100000005030303013D3D3D0188888801FFFFFF04BFBFBF01 + 8C8C8C010000001520202001606060017E7E7E0260606001202020010000003D + 29292901010101013D3D3D01464646013A3A3A01262626011515150144444401 + 0E0E0E01000000030F0F0F01E7E7E701FFFFFF01F1F1F101757575010B0B0B01 + 0000000741414101FFFFFF03BFBFBF018C8C8C010000005B353535013E3E3E01 + 1C1C1C0122222201121212013F3F3F01161616010000000304040401E2E2E201 + FFFFFF01F1F1F1017F7F7F010C0C0C010000000740404001FFFFFF02BFBFBF01 + 8C8C8C010000005C414141015A5A5A01515151015D5D5D014C4C4C0154545401 + 39393901292929015C5C5C01515151010E0E0E01E7E7E701FFFFFF01F4F4F401 + 808080010C0C0C010000000740404001FFFFFF01BFBFBF018C8C8C010000005B + 0A0A0A010303030122222201303030013131310121212101222222011C1C1C01 + 0E0E0E01000000011010100111111101161616014545450197979701A0A0A001 + 737373010D0D0D01000000071010100141414101919191010000000218181801 + 303030023F3F3F01000000547070700278787801292929010000000B01010101 + 0C0C0C020B0B0B01010101010000000C2626260136363601393939013A3A3A01 + 0000005708080801000000AC0C0C0C01000000020C0C0C010000005708080801 + F8F8F8010000001B46464601696969016464640168686801707070010000000F + 040404014C4C4C0180808001B3B3B301E6E6E602B3B3B301808080014C4C4C01 + 040404010000003D08080801FFFFFF020000001C13131301171717010000000F + 29292901CBCBCB01FFFFFF08DADADA012C2C2C01000000252525250100000016 + 08080801FFFFFF03000000030C0C0C01000000020C0C0C010000002301010101 + 72727201F7F7F701FFFFFF0AFDFDFD0189898901010101010000000AFFFFFF04 + 00000004FFFFFF040000000DEDEDED015B5B5B010000001508080801FFFFFF04 + 0000000260606001727272016262620164646401545454010000002272727201 + FFFFFF0EB1B1B1010101010100000009FFFFFF0500000003FFFFFF050000000C + FFFFFF028787870100000011222222019F9F9F01D3D3D301FCFCFC01FFFFFF05 + 00000003212121010A0A0A011A1A1A01282828012C2C2C011212120110101001 + 323232010808080100000003070707017D7D7D01BCBCBC01EDEDED01FFFFFF06 + 101010010000000D29292901F7F7F701FFFFFF0F8989890100000009FFFFFF05 + 00000003FFFFFF050000000CFFFFFF03B4B4B401010101010000000E52525201 + F1F1F101FFFFFF090000000450505001595959012D2D2D012A2A2A0124242401 + 525252011B1B1B010000000228282801D1D1D101FFFFFF0A0000000C04040401 + CBCBCB01FFFFFF10FDFDFD012C2C2C0100000008FFFFFF0500000003FFFFFF05 + 0000000CFFFFFF04D7D7D7010A0A0A010000000C1E1E1E01F4F4F401FFFFFF0A + F8F8F801000000032B2B2B012F2F2F01383838014D4D4D013333330137373701 + 1F1F1F010000000105050501D6D6D601FFFFFF0B000000020C0C0C0104040401 + 111111010000000219191901000000044C4C4C01FFFFFF12DADADA0104040401 + 00000007FFFFFF0500000003FFFFFF050000000CFFFFFF05EDEDED0120202001 + 0000000B9E9E9E01FFFFFF0AF8F8F80100000004353535014E4E4E015A5A5A01 + 3E3E3E0141414101383838011C1C1C01000000016E6E6E01FFFFFF06F0F0F006 + 000000025656560163636301606060012B2B2B01464646016262620122222201 + 000000037F7F7F01FFFFFF134C4C4C0100000007FFFFFF0500000003FFFFFF05 + 0000000CFFFFFF06F9F9F901414141010000000AD8D8D801FFFFFF03DEDEDE01 + 4B4B4B01FFFFFF04F8F8F8010000000144444401494949014E4E4E0139393901 + 00000008B9B9B901FFFFFF03F3F3F30161616101121212010000000A01010101 + 000000030808080100000003B3B3B301FFFFFF137F7F7F0100000007FFFFFF05 + 00000003FFFFFF050000000CFFFFFF07FDFDFD01696969010000000801010101 + FAFAFA01FFFFFF034545450108080801FFFFFF03F8F8F801000000021E1E1E01 + 17171701222222012020200100000008E5E5E501FFFFFF036B6B6B0100000001 + FFFFFF0100000012E6E6E601FFFFFF13B3B3B30100000007FFFFFF0500000003 + FFFFFF050000000CFFFFFF099696960100000008DDDDDD01FFFFFF030B0B0B01 + 08080801F8F8F801FFFFFF01FCFCFC010000000FE5E5E501FFFFFF031D1D1D01 + 00000001FFFFFF021010100100000010E6E6E601FFFFFF13E6E6E60100000007 + FFFFFF0500000003FFFFFF050000000CFFFFFF09FDFDFD016C6C6C0100000007 + A5A5A501FFFFFF03696969010909090108080801F8F8F80100000010B9B9B901 + FFFFFF032323230100000001FFFFFF03101010010000000FB3B3B301FFFFFF13 + E6E6E60100000007FFFFFF0500000003FFFFFF050000000CFFFFFF09FCFCFC01 + 6C6C6C010000000725252501FDFDFD01FFFFFF0DEDEDED01BEBEBE018A8A8A01 + 080808010000000569696901FFFFFF03B9B9B9011F1F1F01FFFFFF0410101001 + 0000000E7F7F7F01FFFFFF13B3B3B30100000007FFFFFF0500000003FFFFFF05 + 0000000CFFFFFF08F2F2F201494949010000000977777701FFFFFF10D9D9D901 + 0A0A0A010000000403030301E2E2E201FFFFFF09101010010000000310101001 + 131313022E2E2E0112121201131313010D0D0D0116161601000000024C4C4C01 + FFFFFF137F7F7F0100000007FFFFFF0500000003FFFFFF050000000CFFFFFF07 + E1E1E1012D2D2D010000000B7A7A7A01FCFCFC01FFFFFF0FD1D1D10102020201 + 0000000426262601F4F4F401FFFFFF0910101001000000024C4C4C016C6C6C01 + 76767601585858015D5D5D014F4F4F012D2D2D01313131010000000204040401 + DADADA01FFFFFF124C4C4C0100000007FFFFFF0500000003FFFFFF050000000C + FFFFFF06C9C9C901181818010000000C0C0C0C0129292901A1A1A101D6D6D601 + FCFCFC01FFFFFF0D6F6F6F010000000521212101E1E1E101FFFFFF08F0F0F001 + 0000000D2C2C2C01FDFDFD01FFFFFF10CBCBCB010404040100000007FFFFFF05 + 00000003FFFFFF050000000CFFFFFF05ABABAB01090909010000000D77777701 + 7575750171717101626262013D3D3D010000000948484801FFFFFF03A9A9A901 + 00000006040404016F6F6F01ACACAC01FFFFFF05F0F0F0010000000F89898901 + FFFFFF0FF7F7F7012929290100000008FFFFFF0500000003FFFFFF050000000C + FFFFFF0486868601010101010000001029292901010101013D3D3D0146464601 + 3A3A3A012626260115151501444444010E0E0E01000000030E0E0E01FFFFFF03 + D9D9D90100000009FFFFFF04F0F0F0010000001001010101B1B1B101FFFFFF0E + 7272720100000009FFFFFF0500000003FFFFFF050000000CEDEDED01FFFFFF01 + F9F9F9016060600100000014353535013E3E3E011C1C1C012222220112121201 + 3F3F3F01161616010000000308080801FFFFFF03F2F2F20100000009FFFFFF03 + F0F0F001000000120101010189898901FDFDFD01FFFFFF0AF7F7F70172727201 + 010101010000000AFFFFFF0400000004FFFFFF040000000C25252501EDEDED01 + 3F3F3F0100000015414141015A5A5A01515151015D5D5D014C4C4C0154545401 + 39393901292929015C5C5C015151510111111101FFFFFF03F7F7F70100000009 + FFFFFF02F0F0F001000000152C2C2C01DADADA01FFFFFF08CBCBCB0129292901 + 0000002525252501000000140A0A0A0103030301222222013030300131313101 + 21212101222222011C1C1C010E0E0E0100000001101010011111110116161601 + 08080801FFFFFF02F8F8F8010000000902020201FBFBFB010000000218181801 + 303030023F3F3F0100000011040404014C4C4C0180808001B3B3B301E6E6E602 + B3B3B301808080014C4C4C010404040100000039707070027878780129292901 + 0000000C050505010000000F2626260136363601393939013A3A3A0100000057 + 080808010000002B0C0C0C01000000020C0C0C01000000350C0C0C0100000002 + 0C0C0C010000000B0C0C0C01000000020C0C0C010000002C4646460169696901 + 6464640168686801707070010000001708080801F8F8F8010000001B46464601 + 696969016464640168686801707070010000000A464646016969690164646401 + 68686801707070010000002D13131301171717021A1A1A013B3B3B010B0B0B01 + 17171701282828011111110100000005050505010000000B08080801FFFFFF02 + 0000001C13131301171717010000000D13131301171717021A1A1A013B3B3B01 + 0B0B0B01171717012828280111111101000000053D3D3D014040400200000021 + 414141014D4D4D01494949011A1A1A0135353501474747012424240100000004 + 03030301FFFFFF02F8F8F8010000000908080801FFFFFF03000000030C0C0C01 + 000000020C0C0C0100000025414141014D4D4D01494949011A1A1A0135353501 + 474747012424240100000005E6E6E601FFFFFF01E9E9E9010C0C0C0101010101 + 0000001F262626012F2F2F01353535014747470136363601303030011E1E1E01 + 2A2A2A011F1F1F014D4D4D012828280108080801FFFFFF03F8F8F80100000008 + 08080801FFFFFF04000000026060600172727201626262016464640154545401 + 00000024262626012F2F2F01353535014747470136363601303030011E1E1E01 + 2A2A2A011F1F1F014D4D4D012828280104040401E3E3E301FFFFFF01F0F0F001 + 747474010B0B0B010000001F2F2F2F014C4C4C0157575701393939013D3D3D01 + 2E2E2E012323230124242401181818013D3D3D01161616010E0E0E01FFFFFF03 + F7F7F70100000005222222019F9F9F01D3D3D301FCFCFC01FFFFFF0500000003 + 212121010A0A0A011A1A1A01282828012C2C2C01121212011010100132323201 + 0808080100000003070707017D7D7D01BCBCBC01EDEDED01FFFFFF0610101001 + 000000102F2F2F014C4C4C0157575701393939013D3D3D012E2E2E0123232301 + 24242401181818013D3D3D01161616010C0C0C01E5E5E501FFFFFF01F1F1F101 + 808080010C0C0C010000001B2D2D2D01464646014A4A4A01505050010000000B + 30303001FFFFFF03F2F2F2010000000452525201F1F1F101FFFFFF0900000004 + 50505001595959012D2D2D012A2A2A0124242401525252011B1B1B0100000002 + 28282801D1D1D101FFFFFF0A0000000C2D2D2D01464646014A4A4A0150505001 + 0000000B16161601E8E8E801FFFFFF01EDEDED017A7A7A010B0B0B010000001B + 111111011D1D1D011F1F1F012A2A2A010000000A1D1D1D019B9B9B01FFFFFF03 + D9D9D901000000031E1E1E01F4F4F401FFFFFF0AF8F8F801000000032B2B2B01 + 2F2F2F01383838014D4D4D0133333301373737011F1F1F010000000105050501 + D6D6D601FFFFFF0B000000020C0C0C0104040401111111010000000219191901 + 00000004111111011D1D1D011F1F1F012A2A2A010000000A26262601B8B8B801 + FCFCFC01FFFFFF01E2E2E2016E6E6E010A0A0A010000000A2D2D2D01ACACAC01 + C5C5C501C4C4C401ABABAB012C2C2C010000000C29292901A1A1A101D4D4D401 + FCFCFC01FFFFFF0EA9A9A901000000039E9E9E01FFFFFF0AF8F8F80100000004 + 353535014E4E4E015A5A5A013E3E3E0141414101383838011C1C1C0100000001 + 6E6E6E01FFFFFF06F0F0F006000000025656560163636301606060012B2B2B01 + 4646460162626201222222010000000442424201B8B8B801CECECE01DFDFDF01 + E1E1E109EFEFEF01FFFFFF03CFCFCF0159595901080808010000000973737301 + E5E5E501FFFFFF04EEEEEE017D7D7D010000000A60606001F6F6F601FFFFFF11 + 6F6F6F0100000003D8D8D801FFFFFF03DEDEDE014B4B4B01FFFFFF04F8F8F801 + 0000000144444401494949014E4E4E013939390100000008B9B9B901FFFFFF03 + F3F3F30161616101121212010000000A01010101000000030808080100000003 + 83838301E9E9E901FFFFFF0FE7E7E701878787013D3D3D010505050100000008 + 2D2D2D01E5E5E501FFFFFF06F1F1F1015F5F5F010000000825252501FAFAFA01 + FFFFFF11ADADAD01020202010000000201010101FAFAFA01FFFFFF0345454501 + 08080801FFFFFF03F8F8F801000000021E1E1E01171717012222220120202001 + 00000008E5E5E501FFFFFF036B6B6B0100000001FFFFFF01000000112A2A2A01 + E8E8E801FFFFFF02FCFCFC01F2F2F201F1F1F104F2F2F204F3F3F301EDEDED01 + E1E1E101CBCBCB0187878701585858010D0D0D0100000009ACACAC01FFFFFF08 + D5D5D5012020200100000007A5A5A501FFFFFF0FEDEDED01BEBEBE018A8A8A01 + 0808080100000004DDDDDD01FFFFFF030B0B0B0108080801F8F8F801FFFFFF01 + FCFCFC010000000FE5E5E501FFFFFF031D1D1D0100000001FFFFFF0210101001 + 0000000FB0B0B001FFFFFF02EAEAEA01AAAAAA018E8E8E01A1A1A10189898901 + 8282820183838301848484018585850286868601878787018080800177777701 + 6262620147474701101010010101010100000009C5C5C501FFFFFF08E4E4E401 + 6060600100000007DDDDDD01FFFFFF03D6D6D60145454501F8F8F80100000011 + A5A5A501FFFFFF03696969010909090108080801F8F8F80100000010B9B9B901 + FFFFFF032323230100000001FFFFFF03101010010000000EC7C7C701FFFFFF02 + B7B7B7016C6C6C0162626201FFFFFF01777777011B1B1B010C0C0C070B0B0B01 + 0909090106060601010101010000000AC4C4C401FFFFFF08E4E4E4017E7E7E01 + 0000000601010101FAFAFA01FFFFFF033838380108080801FFFFFF0200000010 + 25252501FDFDFD01FFFFFF0DEDEDED01BEBEBE018A8A8A010808080100000005 + 69696901FFFFFF03B9B9B9011F1F1F01FFFFFF04101010010000000DD2D2D201 + FFFFFF01F7F7F701959595012B2B2B0144444401FFFFFF027070700110101001 + 00000014ABABAB01FFFFFF08D6D6D6017E7E7E0100000007D8D8D801FFFFFF03 + 0B0B0B0108080801FFFFFF0300000002282828012E2E2E023F3F3F0135353501 + 020202010000000877777701FFFFFF10D9D9D9010A0A0A010000000403030301 + E2E2E201FFFFFF09101010010000000310101001131313022E2E2E0112121201 + 131313010D0D0D011616160100000001C8C8C801FFFFFF02C6C6C60115151501 + 41414101FFFFFF037070700110101001282828012E2E2E023F3F3F0135353501 + 020202010000000D2C2C2C01EEEEEE01FFFFFF06F1F1F1019D9D9D0160606001 + 000000079E9E9E01FFFFFF037777770112121201FFFFFF04000000011B1B1B01 + 3D3D3D014B4B4B015F5F5F013333330104040401000000097A7A7A01FCFCFC01 + FFFFFF0FD1D1D101020202010000000426262601F4F4F401FFFFFF0910101001 + 000000024C4C4C016C6C6C0176767601585858015D5D5D014F4F4F012D2D2D01 + 3131310100000001ADADAD01FFFFFF02EFEFEF017F7F7F014A4A4A01FFFFFF04 + 70707001292929013D3D3D014B4B4B015F5F5F0133333301040404010000000E + 7D7D7D01F1F1F101FFFFFF04F1F1F101B9B9B9018B8B8B012020200100000007 + 1E1E1E01FBFBFB01FFFFFF09000000042F2F2F01545454015E5E5E012C2C2C01 + 575757013232320130303001000000040C0C0C0129292901A1A1A101D6D6D601 + FCFCFC01FFFFFF0D6F6F6F010000000521212101E1E1E101FFFFFF08F0F0F001 + 0000000B22222201EBEBEB01FFFFFF02FDFDFD01F2F2F201FFFFFF0570707001 + 10101001000000022F2F2F01545454015E5E5E012C2C2C015757570132323201 + 303030010000000A5F5F5F01D5D5D501E4E4E402D6D6D6019D9D9D018B8B8B01 + 424242010000000966666601FEFEFE01FFFFFF09000000030E0E0E011B1B1B02 + 1D1D1D010C0C0C011D1D1D012424240100000004777777017575750171717101 + 626262013D3D3D010000000948484801FFFFFF03A9A9A9010000000604040401 + 6F6F6F01ACACAC01FFFFFF05F0F0F0010000000C010101016D6D6D01ECECEC01 + FFFFFF0940404001000000020E0E0E011B1B1B021D1D1D010C0C0C011D1D1D01 + 242424010000000B20202001606060017E7E7E0260606001202020010000000B + 69696901FAFAFA01FFFFFF08F8F8F80100000002414141016868680171717101 + 6B6B6B016D6D6D015B5B5B014A4A4A0157575701000000052929290101010101 + 3D3D3D01464646013A3A3A012626260115151501444444010E0E0E0100000003 + 0E0E0E01FFFFFF03D9D9D90100000009FFFFFF04F0F0F0010000000E05050501 + 50505001D0D0D001E5E5E501F7F7F701FFFFFF05BFBFBF018F8F8F0100000002 + 4141410168686801717171016B6B6B016D6D6D015B5B5B014A4A4A0157575701 + 0000001C222222019F9F9F01D4D4D401FFFFFF05F8F8F8011212120110101001 + 2A2A2A01020202010000000114141401010101010000000B353535013E3E3E01 + 1C1C1C0122222201121212013F3F3F01161616010000000308080801FFFFFF03 + F2F2F20100000009FFFFFF03F0F0F00100000010060606011E1E1E0152525201 + 92929201FFFFFF04BFBFBF019090900112121201101010012A2A2A0102020201 + 0000000114141401010101010000002208080801FFFFFF04F8F8F80128282801 + 5C5C5C014F4F4F0154545401060606010000000E414141015A5A5A0151515101 + 5D5D5D014C4C4C015454540139393901292929015C5C5C015151510111111101 + FFFFFF03F7F7F70100000009FFFFFF02F0F0F001000000120202020107070701 + 47474701FFFFFF03BFBFBF018F8F8F01282828015C5C5C014F4F4F0154545401 + 060606010000002508080801FFFFFF03F8F8F801000000120A0A0A0103030301 + 22222201303030013131310121212101222222011C1C1C010E0E0E0100000001 + 10101001111111011616160108080801FFFFFF02F8F8F8010000000902020201 + FBFBFB010000000218181801303030023F3F3F010000000F40404001FFFFFF02 + BFBFBF018F8F8F010000002B08080801F8F8F801FFFFFF01F8F8F80100000011 + 7070700278787801292929010000000C050505010000000F2626260136363601 + 393939013A3A3A010000000F40404001FFFFFF01BFBFBF018F8F8F010000002D + 08080801F8F8F80100000015080808010000002F10101001434343018F8F8F01 + 00000027 + } + end + object selecteditpage: taction + caption = 'Select &Edit Page' + options = [ao_globalshortcut] + onexecute = selecteditpageonexecute + left = 280 + top = 120 + sc = ( + 1 + 16453 + ) + end + object indent: taction + caption = '&Indent' + onexecute = indentonexecute + left = 280 + top = 136 + sc = ( + 1 + 16457 + ) + end + object unindent: taction + caption = 'U&nindent' + onexecute = unidentonexecute + left = 280 + top = 152 + sc = ( + 1 + 16469 + ) + end + object toggleformunit: taction + caption = 'Toggle Form/&Unit' + onexecute = toggleformunitonexecute + left = 152 + top = 104 + sc = ( + 1 + 315 + ) + end + object nexti: taction + imagelist = buttonicons + caption = 'Next Instruction' + imagenr = 13 + imagenrdisabled = 19 + onexecute = nextiactonexecute + left = 80 + top = 208 + sc = ( + 1 + 24887 + ) + end + object stepi: taction + imagelist = buttonicons + caption = 'Step Instruction' + imagenr = 12 + imagenrdisabled = 21 + onexecute = stepiactonexecute + left = 80 + top = 224 + sc = ( + 1 + 24886 + ) + end + object bluedotsonact: taction + imagelist = buttonicons + caption = 'Exec Line Hint on' + state = [as_checked] + imagenr = 14 + hint = 'Executable lines hint on/off' + statfile = mainfo.projectstatfile + onchange = bluedotsononchange + left = 152 + top = 269 + end + object replace: taction + caption = 'Find && &Replace' + onexecute = replaceactonexecute + left = 208 + top = 16 + sc = ( + 1 + 16466 + ) + end + object print: taction + caption = '&Print' + onexecute = printactonexecute + left = 8 + top = 100 + end + object detachtarget: taction + caption = 'Detach' + onexecute = ondetachtarget + left = 8 + top = 136 + end + object attachprocess: taction + caption = 'Attach Process' + onexecute = onattachprocess + left = 8 + top = 152 + end + object lowercase: taction + caption = '&Lowercase' + onexecute = lowercaseexecute + onupdate = enableonselect + left = 360 + top = 136 + end + object uppercase: taction + caption = '&Uppercase' + onexecute = uppercaseexecute + onupdate = enableonselect + left = 360 + top = 152 + end + object shortcuts: tshortcutcontroller + actions.count = 98 + actions.items = < + item + dispname = 'File' + end + item + action = opensource + dispname = 'Open' + sc = ( + 1 + 16463 + ) + end + item + action = save + dispname = 'Save' + sc = ( + 1 + 16467 + ) + end + item + action = saveall + dispname = 'Save all' + end + item + action = saveas + dispname = 'Save as' + end + item + action = close + dispname = 'Close' + sc = ( + 1 + 16691 + ) + end + item + action = closeall + dispname = 'Close all' + end + item + action = print + dispname = 'Print' + end + item + dispname = 'Search' + end + item + action = line + dispname = 'Line' + sc = ( + 1 + 16460 + ) + end + item + action = find + dispname = 'Find' + sc = ( + 1 + 16454 + ) + end + item + action = repeatfind + dispname = 'Search again' + sc = ( + 1 + 306 + ) + end + item + action = findback + dispname = 'Search back' + sc = ( + 1 + 8498 + ) + end + item + action = replace + dispname = 'Find and replace' + sc = ( + 1 + 16466 + ) + end + item + action = findinfile + dispname = 'Find in File' + sc = ( + 1 + 24646 + ) + end + item + dispname = 'Edit' + end + item + action = selecteditpage + dispname = 'Select Editpage' + sc = ( + 1 + 16453 + ) + end + item + action = copyword + dispname = 'Copy Word at Cursor' + sc = ( + 1 + 24663 + ) + end + item + action = indent + dispname = 'Indent' + sc = ( + 1 + 16457 + ) + end + item + action = unindent + dispname = 'Unindent' + sc = ( + 1 + 16469 + ) + end + item + action = comment + dispname = 'Comment Selection' + sc = ( + 2 + 16459 + 67 + ) + end + item + action = uncomment + dispname = 'Uncomment Selection' + sc = ( + 2 + 16459 + 85 + ) + end + item + action = lowercase + dispname = 'Lowercase' + end + item + action = uppercase + dispname = 'Uppercase' + end + item + action = copylatexact + dispname = 'Copy LaTeX' + sc = ( + 2 + 16459 + 76 + ) + end + item + action = sourcefo.completeclassact + dispname = 'Complete Class' + sc = ( + 1 + 24641 + ) + end + item + action = instemplate + dispname = 'Insert Template' + sc = ( + 1 + 16468 + ) + end + item + action = sourcefo.navigbackact + dispname = 'Navigate Back' + sc = ( + 1 + 16456 + ) + end + item + action = sourcefo.navigforwardact + dispname = 'Navigate Forward' + sc = ( + 1 + 24648 + ) + end + item + dispname = 'Set Bookmark' + end + item + action = setbm0 + dispname = 'Set Bookmark 0' + sc = ( + 1 + 24624 + ) + end + item + action = setbm1 + dispname = 'Set Bookmark 1' + sc = ( + 1 + 24625 + ) + end + item + action = setbm2 + dispname = 'Set Bookmark 2' + sc = ( + 1 + 24626 + ) + end + item + action = setbm3 + dispname = 'Set Bookmark 3' + sc = ( + 1 + 24627 + ) + end + item + action = setbm4 + dispname = 'Set Bookmark 4' + sc = ( + 1 + 24628 + ) + end + item + action = setbm5 + dispname = 'Set Bookmark 5' + sc = ( + 1 + 24629 + ) + end + item + action = setbm6 + dispname = 'Set Bookmark 6' + sc = ( + 1 + 24630 + ) + end + item + action = setbm7 + dispname = 'Set Bookmark 7' + sc = ( + 1 + 24631 + ) + end + item + action = setbm8 + dispname = 'Set Bookmark 8' + sc = ( + 1 + 24632 + ) + end + item + action = setbm9 + dispname = 'Set Bookmark 9' + sc = ( + 1 + 24633 + ) + end + item + action = setbmnone + dispname = 'Clear Bookmark' + end + item + dispname = 'Find Bookmark' + end + item + action = findbm0 + dispname = 'Find Bookmark 0' + sc = ( + 1 + 16432 + ) + end + item + action = findbm1 + dispname = 'Find Bookmark 1' + sc = ( + 1 + 16433 + ) + end + item + action = findbm2 + dispname = 'Find Bookmark 2' + sc = ( + 1 + 16434 + ) + end + item + action = findbm3 + dispname = 'Find Bookmark 3' + sc = ( + 1 + 16435 + ) + end + item + action = findbm4 + dispname = 'Find Bookmark 4' + sc = ( + 1 + 16436 + ) + end + item + action = findbm5 + dispname = 'Find Bookmark 5' + sc = ( + 1 + 16437 + ) + end + item + action = findbm6 + dispname = 'Find Bookmark 6' + sc = ( + 1 + 16438 + ) + end + item + action = findbm7 + dispname = 'Find Bookmark 7' + sc = ( + 1 + 16439 + ) + end + item + action = findbm8 + dispname = 'Find Bookmark 8' + sc = ( + 1 + 16440 + ) + end + item + action = findbm9 + dispname = 'Find Bookmark 9' + sc = ( + 1 + 16441 + ) + end + item + dispname = 'Target' + end + item + action = attachprocess + dispname = 'Attach Process' + end + item + action = detachtarget + dispname = 'Detach Target' + end + item + action = continue + dispname = 'Continue' + sc = ( + 1 + 312 + ) + end + item + action = reset + dispname = 'Reset' + end + item + action = interrupt + dispname = 'Interrupt' + end + item + action = next + dispname = 'Next' + sc = ( + 1 + 311 + ) + end + item + action = nexti + dispname = 'Next Instruction' + sc = ( + 1 + 24887 + ) + end + item + action = step + dispname = 'Step' + sc = ( + 1 + 310 + ) + end + item + action = stepi + dispname = 'Step Instruction' + sc = ( + 1 + 24886 + ) + end + item + action = finish + dispname = 'Finish' + sc = ( + 1 + 8502 + ) + end + item + action = bkptsonact + dispname = 'Breakpoints on/off' + sc = ( + 1 + 16450 + ) + end + item + action = togglebkpt + dispname = 'Toggle Breakpoint' + sc = ( + 1 + 308 + ) + end + item + action = togglebkptenable + dispname = 'Toggle Breakpoint enabled' + sc = ( + 1 + 8500 + ) + end + item + action = watchesonact + dispname = 'Watches on/off' + sc = ( + 1 + 16471 + ) + end + item + action = bluedotsonact + dispname = 'Exec Line Hints on/off' + end + item + dispname = 'View' + end + item + action = toggleinspector + dispname = 'Toggle Form/Object Inspector' + sc = ( + 1 + 314 + ) + end + item + action = toggleformunit + dispname = 'Toggle Form/Unit' + sc = ( + 1 + 315 + ) + end + item + dispname = 'Project' + end + item + action = makeact + dispname = 'Make' + end + item + action = buildact + dispname = 'Build' + end + item + action = make1act + dispname = 'Make 1' + end + item + action = make2act + dispname = 'Make 2' + end + item + action = make3act + dispname = 'Make 3' + end + item + action = make4act + dispname = 'Make 4' + end + item + action = abortmakeact + dispname = 'Abort Make' + end + item + action = projectoptionsact + dispname = 'Options' + end + item + action = projectopenact + dispname = 'Open' + end + item + action = projectsaveact + dispname = 'Save' + end + item + action = projecttreeact + dispname = 'Tree' + end + item + action = projectsourceact + dispname = 'Source' + end + item + action = projectcloseact + dispname = 'Close' + end + item + dispname = 'Help' + end + item + action = helpact + dispname = 'Help' + sc = ( + 1 + 304 + ) + end + item + dispname = 'Tools' + end + item + action = tool0 + dispname = 'Tool 1' + end + item + action = tool1 + dispname = 'Tool 2' + end + item + action = tool2 + dispname = 'Tool 3' + end + item + action = tool3 + dispname = 'Tool 4' + end + item + action = tool4 + dispname = 'Tool 5' + end + item + action = tool5 + dispname = 'Tool 6' + end + item + action = tool6 + dispname = 'Tool 7' + end + item + action = tool7 + dispname = 'Tool 8' + end + item + action = tool8 + dispname = 'Tool 9' + end + item + action = tool9 + dispname = 'Tool 10' + end> + sysshortcuts.count = 11 + sysshortcuts.items = ( + 16451 + 16470 + 16472 + 16449 + 16646 + 24838 + 16647 + 24643 + 24662 + 16474 + 24666 + ) + sysshortcuts1.count = 11 + sysshortcuts1.items = ( + 0 + 8454 + 8455 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + ) + assistiveshortcuts.count = 9 + assistiveshortcuts.items = ( + ( + 16416 + ) + ( + 24608 + ) + ( + 16473 + 70 + ) + ( + 16473 + 76 + ) + ( + 16473 + 67 + ) + ( + 18477 + ) + ( + 18475 + ) + ( + 26669 + ) + ( + 26667 + ) + ) + assistiveshortcuts1.count = 9 + assistiveshortcuts1.items = ( + ( + 18692 + ) + ( + 26884 + ) + ( ) + ( ) + ( ) + ( ) + ( ) + ( ) + ( ) + ) + statfile = mainfo.mainstatfile + onafterupdate = updateshortcuts + left = 352 + top = 8 + end + object toggleinspector: taction + caption = 'Toggle Form/Inspector' + left = 152 + top = 120 + sc = ( + 1 + 314 + ) + end + object buildact: taction + onexecute = makeactonexecute + left = 8 + top = 312 + end + object make1act: taction + onexecute = makeactonexecute + left = 8 + top = 330 + end + object make2act: taction + onexecute = makeactonexecute + left = 8 + top = 348 + end + object make3act: taction + onexecute = makeactonexecute + left = 8 + top = 366 + end + object make4act: taction + onexecute = makeactonexecute + left = 8 + top = 384 + end + object download: taction + caption = 'Download' + onexecute = downloadexe + left = 8 + top = 168 + end + object helpact: taction + options = [ao_globalshortcut] + onexecute = helpex + left = 280 + top = 400 + sc = ( + 1 + 304 + ) + end + object attachtarget: taction + caption = 'Attach Target' + onexecute = onattachtarget + left = 8 + top = 120 + end + object setbm0: taction + caption = 'Bookmark &0' + onexecute = setbmexec + left = 280 + top = 208 + sc = ( + 1 + 24624 + ) + end + object findbm0: taction + caption = 'Bookmark &0' + onexecute = findbmexec + left = 360 + top = 208 + sc = ( + 1 + 16432 + ) + end + object findbm1: taction + caption = 'Bookmark &1' + tagaction = 1 + onexecute = findbmexec + left = 360 + top = 224 + sc = ( + 1 + 16433 + ) + end + object setbm1: taction + caption = 'Bookmark &1' + tagaction = 1 + onexecute = setbmexec + left = 280 + top = 224 + sc = ( + 1 + 24625 + ) + end + object findbm2: taction + caption = 'Bookmark &2' + tagaction = 2 + onexecute = findbmexec + left = 360 + top = 240 + sc = ( + 1 + 16434 + ) + end + object setbm2: taction + caption = 'Bookmark &2' + tagaction = 2 + onexecute = setbmexec + left = 280 + top = 240 + sc = ( + 1 + 24626 + ) + end + object findbm3: taction + caption = 'Bookmark &3' + tagaction = 3 + onexecute = findbmexec + left = 360 + top = 256 + sc = ( + 1 + 16435 + ) + end + object setbm3: taction + caption = 'Bookmark &3' + tagaction = 3 + onexecute = setbmexec + left = 280 + top = 256 + sc = ( + 1 + 24627 + ) + end + object findbm4: taction + caption = 'Bookmark &4' + tagaction = 4 + onexecute = findbmexec + left = 360 + top = 272 + sc = ( + 1 + 16436 + ) + end + object setbm4: taction + caption = 'Bookmark &4' + tagaction = 4 + onexecute = setbmexec + left = 280 + top = 272 + sc = ( + 1 + 24628 + ) + end + object findbm5: taction + caption = 'Bookmark &5' + tagaction = 5 + onexecute = findbmexec + left = 360 + top = 288 + sc = ( + 1 + 16437 + ) + end + object setbm5: taction + caption = 'Bookmark &5' + tagaction = 5 + onexecute = setbmexec + left = 280 + top = 288 + sc = ( + 1 + 24629 + ) + end + object findbm6: taction + caption = 'Bookmark &6' + tagaction = 6 + onexecute = findbmexec + left = 360 + top = 304 + sc = ( + 1 + 16438 + ) + end + object setbm6: taction + Tag = 6 + caption = 'Bookmark &6' + tagaction = 6 + onexecute = setbmexec + left = 280 + top = 304 + sc = ( + 1 + 24630 + ) + end + object findbm7: taction + caption = 'Bookmark &7' + tagaction = 7 + onexecute = findbmexec + left = 360 + top = 320 + sc = ( + 1 + 16439 + ) + end + object setbm7: taction + caption = 'Bookmark &7' + tagaction = 7 + onexecute = setbmexec + left = 280 + top = 320 + sc = ( + 1 + 24631 + ) + end + object findbm8: taction + caption = 'Bookmark &8' + tagaction = 8 + onexecute = findbmexec + left = 360 + top = 336 + sc = ( + 1 + 16440 + ) + end + object setbm8: taction + caption = 'Bookmark &8' + tagaction = 8 + onexecute = setbmexec + left = 280 + top = 336 + sc = ( + 1 + 24632 + ) + end + object findbm9: taction + caption = 'Bookmark &9' + tagaction = 9 + onexecute = findbmexec + left = 360 + top = 352 + sc = ( + 1 + 16441 + ) + end + object setbm9: taction + caption = 'Bookmark &9' + tagaction = 9 + onexecute = setbmexec + left = 280 + top = 352 + sc = ( + 1 + 24633 + ) + end + object setbmnone: taction + caption = 'none' + tagaction = -1 + onexecute = setbmexec + left = 280 + top = 368 + end + object instemplate: taction + onexecute = instemplateactonexecute + left = 368 + top = 96 + sc = ( + 1 + 16468 + ) + end + object projectopenact: taction + caption = 'O&pen' + onexecute = projectopenexe + left = 112 + top = 296 + end + object projectoptionsact: taction + caption = '&Options' + onexecute = projectoptionsexe + left = 112 + top = 312 + end + object projecttreeact: taction + caption = '&Tree' + onexecute = projecttreeexe + left = 112 + top = 328 + end + object projectsourceact: taction + caption = 'So&urce' + onexecute = projectsourceexe + left = 112 + top = 344 + end + object projectsaveact: taction + caption = '&Save' + onexecute = projectsaveexe + left = 112 + top = 360 + end + object projectcloseact: taction + caption = '&Close' + onexecute = projectcloeseexe + left = 112 + top = 376 + end + object c: tstringcontainer + onreadstate = creadstateexe + strings.data = ( + 'Configure MSEide' + 'Process ID' + 'Attach to process' + 'Unknown moduleclass for "' + 'Inherited component "' + '" can not be deleted.' + 'ERROR' + 'Make aborted.' + 'Download aborted.' + 'Runerror with "' + 'Error: Timeout.' + 'Making.' + 'Make not running.' + 'Downloading.' + 'Download not running.' + '" running.' + 'Script' + 'Recursive form inheritance of "' + 'Component "' + '" exists.' + 'Ancestor for "' + '" not found.' + 'Module "' + 'Invalid name "' + 'Invalid methodname' + 'Module not found' + 'Method not found' + 'Published (managed) method' + 'does not exist.' + 'Do you wish to delete the event?' + 'WARNING' + 'Method' + 'has different parameters.' + 'A module "' + '" is already open.' + 'Unresolved reference(s) to' + 'Module(s):' + 'Can not read formfile "' + 'Invalid component name.' + 'Invalid exception' + 'T&ools' + 'Forms' + 'Source' + 'All Files' + 'Program' + 'Unit' + 'Textfile' + 'Mainform' + 'Simple Form' + 'Docking Form' + 'Datamodule' + 'Subform' + 'Scrollboxform' + 'Tabform' + 'Dockpanel' + 'Report' + 'Scriptform' + 'Inherited Form' + 'Do you want to replace the settings by' + 'File "' + 'Do you want to overwrite?' + 'Unknown' + 'Error' + 'Startup' + 'Exception' + 'GDB died' + 'Breakpoint hit' + 'Watchpoint triggered' + 'Read Watchpoint triggered' + 'Access Watchpoint triggered' + 'End stepping range' + 'Function finished' + 'Exited normally' + 'Exited' + 'Detached' + 'Signal received' + 'Stop error' + 'Can not read project' + 'About' + 'Object Inspector' + 'Store Component' + 'Attaching Process' + 'Loading' + 'Sizing Form' + ) + left = 392 + top = 400 + end + object copylatexact: taction + caption = 'Copy &LaTeX' + onexecute = copylatexactonexecute + left = 368 + top = 80 + sc = ( + 2 + 16459 + 76 + ) + end + object findcompact: taction + onexecute = findcompexe + left = 152 + top = 152 + sc = ( + 1 + 16454 + ) + end + object findcompallact: taction + caption = '&Find Component' + onexecute = findcompallexe + left = 152 + top = 168 + end + object forcezorderact: taction + caption = 'Force &Z-Order' + onchange = forcezorderexe + left = 136 + top = 400 + end + object tool0: taction + left = 472 + top = 8 + end + object tool1: taction + left = 472 + top = 24 + end + object tool2: taction + left = 472 + top = 40 + end + object tool3: taction + left = 472 + top = 56 + end + object tool4: taction + left = 472 + top = 72 + end + object tool5: taction + left = 472 + top = 88 + end + object tool6: taction + left = 472 + top = 104 + end + object tool7: taction + left = 472 + top = 120 + end + object tool8: taction + left = 472 + top = 136 + end + object tool9: taction + left = 472 + top = 152 + end + object comment: taction + caption = '&Comment' + onexecute = commentonexecute + onupdate = enablecomment + left = 280 + top = 168 + sc = ( + 2 + 16459 + 67 + ) + end + object uncomment: taction + caption = 'Unc&omment' + onexecute = uncommentonexecute + onupdate = enableuncomment + left = 280 + top = 184 + sc = ( + 2 + 16459 + 85 + ) + end + object copyword: taction + caption = 'Copy &Word at Cursor' + options = [ao_globalshortcut] + onexecute = selectwordactiononexecute + left = 280 + top = 100 + sc = ( + 1 + 24663 + ) + end + object selectall: taction + caption = 'Select &all' + onexecute = seleclallactonexecute + left = 344 + top = 56 + sc = ( + 1 + 16449 + ) + end + object tabtospace: taction + caption = '&Tabs to space' + onexecute = tabtospaceexecute + onupdate = enableonselect + left = 360 + top = 168 + end + object findback: taction + caption = 'Search &back' + onexecute = findbackonexecute + left = 152 + top = 60 + sc = ( + 1 + 8498 + ) + end +end diff --git a/mseide-msegui/apps/ide/actionsmodule.pas b/mseide-msegui/apps/ide/actionsmodule.pas new file mode 100644 index 0000000..3d6ea73 --- /dev/null +++ b/mseide-msegui/apps/ide/actionsmodule.pas @@ -0,0 +1,918 @@ +{ MSEide Copyright (c) 1999-2014 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit actionsmodule; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + classes,mseclasses,mseact,mseactions,msebitmap,msestrings,msegui, + msedatamodules,mseglob,msestat,mseifiglob,msegraphics,msegraphutils,mseguiglob, + msemenus,msesimplewidgets,msewidgets,projecttreeform,msestringcontainer, + targetconsole,mseificomp,mseificompglob,mclasses; + +type + stringconsts = ( + ac_configuremseide, //0 Configure MSEide + ac_processid, //1 Process ID + ac_attachtoprocess, //2 Attach to process + ac_unknownmodclass, //3 Unknown moduleclass for " + ac_inheritedcomp, //4 Inherited component " + ac_cannotdel, //5 " can not be deleted. + ac_error, //6 ERROR + ac_makeaborted, //7 Make aborted. + ac_downloadaborted, //8 Download aborted. + ac_runerrorwith, //9 Runerror with " + ac_errortimeout, //10 Error: Timeout. + ac_making, //11 Making. + ac_makenotrunning, //12 Make not running. + ac_downloading, //13 Downloading. + ac_downloadnotrunning, //14 Download not running. + ac_running, //15 " running. + ac_script, //16 Script + ac_recursiveforminheritance, //17 Recursive form inheritance of " + ac_component, //18 Component " + ac_exists, //19 " exists. + ac_ancestorfor, //20 Ancestor for " + ac_notfound, //21 " not found. + ac_module, //22 Module " + ac_invalidname, //23 Invalid name " + ac_invalidmethodname, //24 Invalid methodname + ac_modulenotfound, //25 Module not found + ac_methodnotfound, //26 Method not found + ac_publishedmeth, //27 Published (managed) method + ac_doesnotexist, //28 does not exist. + ac_wishdelete, //29 Do you wish to delete the event? + ac_warning, //30 WARNING + ac_method, //31 Method + ac_differentparams, //32 has different parameters. + ac_amodule, //33 A module " + ac_isopen, //34 " is already open. + ac_unresolvedref, //35 Unresolved reference(s) to + ac_modules, //36 Module(s): + ac_cannotreadform, //37 Can not read formfile " + ac_invalidcompname,//38 Invalid component name. + ac_invalidexception, //39 Invalid exception + ac_tools, //40 T&ools + ac_forms, //41 Forms + ac_source, //42 Source + ac_allfiles, //43 All Files + ac_program, //44 Program + ac_unit, //45 Unit + ac_textfile, //46 Textfile + ac_mainform, //47 Mainform + ac_simpleform, //48 Simple Form + ac_dockingform, //49 Docking Form + ac_datamodule, //50 Datamodule + ac_subform, //51 Subform + ac_scrollboxform, //52 Scrollboxform + ac_tabform, //53 Tabform + ac_dockpanel, //54 Dockpanel + ac_report, //55 Report + ac_scriptform, //56 Scriptform + ac_inheritedform, //57 Inherited Form + ac_replacesettings, //58 Do you want to replace the settings by + ac_file, //59 File " + ac_wantoverwrite, //60 Do you want to overwrite? + ac_sr_unknown, //61 Unknown + ac_sr_error, //62 Error + ac_sr_startup, //63 Startup + ac_sr_exception, //64 Exception + ac_sr_gdbdied, //65 GDB died + ac_sr_breakpoint_hit, //66 Breakpoint hit + ac_sr_watchpointtrigger, //67 Watchpoint triggered + ac_sr_readwatchpointtrigger, //68 Read Watchpoint triggered + ac_sr_accesswatchpointtrigger, //69 Access Watchpoint triggered + ac_sr_end_stepping_range, //70 End stepping range + ac_sr_function_finished, //71 Function finished + ac_sr_exited_normally, //72 Exited normally + ac_sr_exited, //73 Exited + ac_sr_detached, //74 Detached + ac_sr_signal_received, //75 Signal received + ac_stoperror, //76 Stop error + ac_cannotreadproject, //77 Can not read project + ac_about, //78 About + ac_objectinspector, //79 Object Inspector + ac_storecomponent, //80 Store Component + ac_attachingprocess, //81 Attaching Process + ac_loading, //82 Loading + ac_sizingform //83 Sizing Form + ); + +type + tactionsmo = class(tmsedatamodule) + buttonicons: timagelist; + + opensource: taction; + saveall: taction; + saveas: taction; + save: taction; + close: taction; + closeall: taction; + + reset: taction; + interrupt: taction; + next: taction; + step: taction; + finish: taction; + continue: taction; +// run: taction; + + line: taction; + find: taction; + repeatfind: taction; + findinfile: taction; + + indent: taction; + nexti: taction; + stepi: taction; + bluedotsonact: taction; + replace: taction; + print: taction; + detachtarget: taction; + attachprocess: taction; + lowercase: taction; + uppercase: taction; + toggleformunit: taction; + unindent: taction; + undo: taction; + redo: taction; + cut: taction; + copy: taction; + paste: taction; + delete: taction; + + togglebkpt: taction; + togglebkptenable: taction; + bkptsonact: taction; + watchesonact: taction; + + abortmakeact: taction; + makeact: taction; + selecteditpage: taction; + + run: taction; + //common + shortcuts: tshortcutcontroller; + toggleinspector: taction; + buildact: taction; + make1act: taction; + make2act: taction; + make3act: taction; + make4act: taction; + download: taction; + helpact: taction; + attachtarget: taction; + setbm0: taction; + findbm0: taction; + findbm1: taction; + setbm1: taction; + findbm2: taction; + setbm2: taction; + findbm3: taction; + setbm3: taction; + findbm4: taction; + setbm4: taction; + findbm5: taction; + setbm5: taction; + findbm6: taction; + setbm6: taction; + findbm7: taction; + setbm7: taction; + findbm8: taction; + setbm8: taction; + findbm9: taction; + setbm9: taction; + setbmnone: taction; + instemplate: taction; + projectopenact: taction; + projectoptionsact: taction; + projecttreeact: taction; + projectsourceact: taction; + projectsaveact: taction; + projectcloseact: taction; + c: tstringcontainer; + copylatexact: taction; + findcompact: taction; + findcompallact: taction; + forcezorderact: taction; + tool0: taction; + tool1: taction; + tool2: taction; + tool3: taction; + tool4: taction; + tool5: taction; + tool6: taction; + tool7: taction; + tool8: taction; + tool9: taction; + comment: taction; + uncomment: taction; + copyword: taction; + selectall: taction; + tabtospace: taction; + findback: taction; + procedure findinfileonexecute(const sender: tobject); + + //file + procedure opensourceactonexecute(const sender: tobject); + procedure saveactonexecute(const sender: tobject); + procedure saveasactonexecute(const sender: TObject); + procedure saveallactonexecute(const sender: tobject); + procedure closeactonexecute(const sender: tobject); + procedure closeallactonexecute(const sender: tobject); + + //editor + procedure seleclallactonexecute(const sender: TObject); + procedure pasteactonexecute(const sender: tobject); + procedure deleteactonexecute(const sender: tobject); + procedure selecteditpageonexecute(const sender: TObject); + procedure undoactonexecute(const sender: tobject); + procedure redoactonexecute(const sender: tobject); + procedure copyactonexecute(const sender: tobject); + procedure cutactonexecute(const sender: tobject); + + procedure indentonexecute(const sender: TObject); + procedure unidentonexecute(const sender: TObject); + procedure lowercaseexecute(const sender: TObject); + procedure uppercaseexecute(const sender: TObject); + procedure enableonselect(const sender: tcustomaction); + + procedure lineactonexecute(const sender: TObject); + procedure findactonexecute(const sender: tobject); + procedure repeatfindactonexecute(const sender: tobject); + procedure replaceactonexecute(const sender: TObject); + + procedure togglebreakpointexe(const sender: TObject); + procedure togglebkptenableactonexecute(const sender: TObject); + procedure toggleformunitonexecute(const sender: TObject); + + //make + procedure makeactonexecute(const sender: tobject); + procedure abortmakeactonexecute(const sender: tobject); + + //debugger + procedure resetactonexecute(const sender: tobject); + procedure interruptactonexecute(const sender: tobject); + procedure continueactonexecute(const sender: tobject); + procedure nextactonexecute(const sender: tobject); + procedure finishactonexecute(const sender: tobject); + procedure stepactonexecute(const sender: tobject); + procedure stepiactonexecute(const sender: TObject); + procedure nextiactonexecute(const sender: TObject); + procedure bkptsononexecute(const sender: TObject); + procedure watchesononexecute(const sender: TObject); + procedure bluedotsononchange(const sender: TObject); + procedure printactonexecute(const sender: TObject); + procedure ondetachtarget(const sender: TObject); + procedure onattachprocess(const sender: TObject); + procedure updateshortcuts(const sender: tshortcutcontroller); + procedure downloadexe(const sender: TObject); + procedure helpex(const sender: TObject); + procedure onattachtarget(const sender: TObject); + procedure setbmexec(const sender: TObject); + procedure findbmexec(const sender: TObject); + procedure instemplateactonexecute(const sender: TObject); + procedure projectopenexe(const sender: TObject); + procedure projectoptionsexe(const sender: TObject); + procedure projecttreeexe(const sender: TObject); + procedure projectsourceexe(const sender: TObject); + procedure projectsaveexe(const sender: TObject); + procedure projectcloeseexe(const sender: TObject); + procedure creadstateexe(const sender: TObject); + procedure findupdateexe(const sender: tcustomaction); + procedure copylatexactonexecute(const sender: TObject); + procedure findcompexe(const sender: TObject); + procedure findcompallexe(const sender: TObject); + procedure forcezorderexe(const sender: TObject); + procedure commentonexecute(const sender: TObject); + procedure uncommentonexecute(const sender: TObject); + procedure enablecomment(const sender: tcustomaction); + procedure enableuncomment(const sender: tcustomaction); + procedure selectwordactiononexecute(const sender: TObject); + procedure tabtospaceexecute(const sender: TObject); + procedure findbackonexecute(const sender: TObject); + private + function filterfindcomp(const acomponent: tcomponent): boolean; + public + function gettoolshortcutaction(const index: int32; + out act: taction): boolean; + end; + +var + actionsmo: tactionsmo; + +procedure configureide; + +implementation +uses + main,make,actionsmodule_mfm,sourceform,msedesigner,msetypes,msefiledialog, + projectoptionsform,findinfileform,breakpointsform,watchform,selecteditpageform, + disassform,printform,msegdbutils,mseintegerenter,msesettings, + componentstore,cpuform,sysutils,msecomptree,mseformatstr; + +procedure configureide; +begin + disassfo.resetshortcuts(); + if editsettings(actionsmo.c[ord(ac_configuremseide)], + actionsmo.shortcuts) then begin + mainfo.mainstatfile.writestat(); + expandprojectmacros(); + end; +end; + +{ tactionsmo } + +function tactionsmo.gettoolshortcutaction(const index: int32; + out act: taction): boolean; +begin + case index of + 0: act:= tool0; + 1: act:= tool1; + 2: act:= tool2; + 3: act:= tool3; + 4: act:= tool4; + 5: act:= tool5; + 6: act:= tool6; + 7: act:= tool7; + 8: act:= tool8; + 9:act:= tool9; + else act:= nil; + end; + result:= act <> nil; +end; + +procedure tactionsmo.updateshortcuts(const sender: tshortcutcontroller); +begin + undo.shortcut:= sysshortcuts[sho_groupundo]; + undo.shortcut1:= sysshortcuts1[sho_groupundo]; + redo.shortcut:= sysshortcuts[sho_groupredo]; + redo.shortcut1:= sysshortcuts1[sho_groupredo]; + copy.shortcut:= sysshortcuts[sho_copy]; + copy.shortcut1:= sysshortcuts1[sho_copy]; + cut.shortcut:= sysshortcuts[sho_cut]; + cut.shortcut1:= sysshortcuts1[sho_cut]; + paste.shortcut:= sysshortcuts[sho_paste]; + paste.shortcut1:= sysshortcuts1[sho_paste]; + selectall.shortcut:= sysshortcuts[sho_selectall]; + selectall.shortcut1:= sysshortcuts1[sho_selectall]; + findcompact.shortcut:= find.shortcut; + findcompact.shortcut1:= find.shortcut1; + findcompallact.shortcut:= find.shortcut; + findcompallact.shortcut1:= find.shortcut1; +end; + +//common +procedure tactionsmo.findinfileonexecute(const sender: tobject); +begin + dofindinfile; +end; + +//file + +procedure tactionsmo.opensourceactonexecute(const sender: tobject); +begin + with mainfo do begin + opensource(fk_source,false); + end; +end; + +procedure tactionsmo.saveactonexecute(const sender: tobject); +begin + with mainfo do begin + if factivedesignmodule <> nil then begin + designer.saveformfile(factivedesignmodule,factivedesignmodule^.filename,true); + updatemodifiedforms; + end + else begin + sourcefo.saveactivepage; + end; + end; +end; + +procedure tactionsmo.saveasactonexecute(const sender: TObject); +var + namebefore,str1: filenamety; + po1: pmoduleinfoty; +begin + with mainfo do begin + if factivedesignmodule <> nil then begin + str1:= factivedesignmodule^.filename; + if openfile.controller.execute(str1,fdk_save) then begin + designer.saveformfile(factivedesignmodule,str1,true); + end; + end + else begin + str1:= sourcefo.activepage.filepath; + namebefore:= str1; + if openfile.controller.execute(str1,fdk_save) then begin + sourcefo.saveactivepage(str1); + po1:= designer.modules.findmodule(designer.sourcenametoformname(namebefore)); + if po1 <> nil then begin + str1:= designer.sourcenametoformname(str1); + designer.saveformfile(po1,str1,true); + po1^.filename:= str1; + updatemodifiedforms; + end; + end; + end; + end; +end; + +procedure tactionsmo.saveallactonexecute(const sender: tobject); +begin + with mainfo do begin + sourcefo.saveall(true); + designer.saveall(true,true); + componentstorefo.saveall(true); + saveprojectoptions; + updatemodifiedforms; + end; +end; + +procedure tactionsmo.closeactonexecute(const sender: tobject); +begin + with mainfo do begin + if factivedesignmodule <> nil then begin + if closemodule(factivedesignmodule,true) then begin + factivedesignmodule:= nil; + end; + end + else begin + sourcefo.closeactivepage; + end; + end; +end; + +procedure tactionsmo.closeallactonexecute(const sender: tobject); +begin + with mainfo do begin + closeall(false); + end; +end; + +//editor + +procedure tactionsmo.seleclallactonexecute(const sender: TObject); +begin + sourcefo.activepage.edit.selectall(); +end; + +procedure tactionsmo.pasteactonexecute(const sender: tobject); +begin + sourcefo.activepage.edit.paste; +end; + +procedure tactionsmo.deleteactonexecute(const sender: tobject); +begin + sourcefo.activepage.edit.deleteselection; +end; + +procedure tactionsmo.selectwordactiononexecute(const sender: TObject); +begin + sourcefo.activepage.copywordatcursor(); +end; + +procedure tactionsmo.selecteditpageonexecute(const sender: TObject); +begin + selecteditpageform.selecteditpage; +end; + +procedure tactionsmo.toggleformunitonexecute(const sender: TObject); +begin + mainfo.toggleformunit; +end; + +procedure tactionsmo.undoactonexecute(const sender: tobject); +begin + sourcefo.activepage.doundo; +end; + +procedure tactionsmo.redoactonexecute(const sender: tobject); +begin + sourcefo.activepage.doredo; +end; + +procedure tactionsmo.copyactonexecute(const sender: tobject); +begin + sourcefo.activepage.edit.copyselection; +end; + +procedure tactionsmo.copylatexactonexecute(const sender: TObject); +begin + sourcefo.activepage.copylatex; +end; + +procedure tactionsmo.cutactonexecute(const sender: tobject); +begin + sourcefo.activepage.edit.cutselection; +end; + +procedure tactionsmo.indentonexecute(const sender: TObject); +begin + sourcefo.activepage.edit.indent(projectoptions.e.blockindent, + projectoptions.e.tabindent); +end; + +procedure tactionsmo.unidentonexecute(const sender: TObject); +begin + sourcefo.activepage.edit.unindent(projectoptions.e.blockindent); +end; + +procedure tactionsmo.lowercaseexecute(const sender: TObject); +begin + sourcefo.activepage.edit.lowercase; +end; + +procedure tactionsmo.uppercaseexecute(const sender: TObject); +begin + sourcefo.activepage.edit.uppercase; +end; + +procedure tactionsmo.tabtospaceexecute(const sender: TObject); +begin + sourcefo.activepage.edit.tabtospace; +end; + +procedure tactionsmo.enableonselect(const sender: tcustomaction); +begin + sender.enabled:= (sourcefo.activepage <> nil) and + sourcefo.activepage.edit.hasselection; +end; + +procedure tactionsmo.enablecomment(const sender: tcustomaction); +begin + enableonselect(sender); + sender.enabled:= sender.enabled and sourcefo.activepage.cancomment(); +end; + +procedure tactionsmo.enableuncomment(const sender: tcustomaction); +begin + enableonselect(sender); + sender.enabled:= sender.enabled and sourcefo.activepage.canuncomment(); +end; + +procedure tactionsmo.commentonexecute(const sender: TObject); +begin + sourcefo.activepage.commentselection(); +end; + +procedure tactionsmo.uncommentonexecute(const sender: TObject); +begin + sourcefo.activepage.uncommentselection(); +end; + +procedure tactionsmo.lineactonexecute(const sender: TObject); +begin + sourcefo.activepage.doline; +end; + +procedure tactionsmo.findactonexecute(const sender: tobject); +begin + if targetconsolefo.activeentered then begin + targetconsolefo.dofind; + end + else begin + sourcefo.activepage.dofind; + end; +end; + +procedure tactionsmo.repeatfindactonexecute(const sender: tobject); +begin + if targetconsolefo.activeentered then begin + targetconsolefo.repeatfind; + end + else begin + sourcefo.activepage.repeatfind; + end; +end; + +procedure tactionsmo.findbackonexecute(const sender: TObject); +begin + if targetconsolefo.activeentered then begin + targetconsolefo.findback; + end + else begin + sourcefo.activepage.findback; + end; +end; + +procedure tactionsmo.replaceactonexecute(const sender: tobject); +begin + sourcefo.activepage.doreplace; +end; + +procedure tactionsmo.togglebreakpointexe(const sender: TObject); +begin + sourcefo.activepage.togglebreakpoint; +end; + +procedure tactionsmo.togglebkptenableactonexecute(const sender: TObject); +begin + sourcefo.activepage.togglebreakpointenabled; +end; + +procedure tactionsmo.instemplateactonexecute(const sender: TObject); +begin + sourcefo.activepage.inserttemplate; +end; + + +//make + +procedure tactionsmo.abortmakeactonexecute(const sender: tobject); +begin + make.abortmake; +end; + +procedure tactionsmo.makeactonexecute(const sender: tobject); +begin + with mainfo do begin + if sender is tmenuitem then begin + domake(tmenuitem(sender).tag); + end + else begin + domake(0); + end; + resetstartcommand; + end; +end; + +//debugger + +procedure tactionsmo.resetactonexecute(const sender: tobject); +begin + with mainfo do begin + gdb.abort; + killtarget; //if running + programfinished; + setstattext(''); + startgdb(false); + end; +end; + +procedure tactionsmo.interruptactonexecute(const sender: tobject); +begin + with mainfo do begin + gdb.interrupt; + end; +end; + +procedure tactionsmo.continueactonexecute(const sender: tobject); +begin + with mainfo do begin + if checkremake(sc_continue) then begin + cpufo.beforecontinue; + gdb.continue; + end; + end; +end; + +procedure tactionsmo.stepactonexecute(const sender: tobject); +begin + with mainfo do begin + if checkremake(sc_step) then begin + gdb.step; + end; + end; +end; + +procedure tactionsmo.stepiactonexecute(const sender: TObject); +begin + with mainfo do begin + if checkremake(sc_step) then begin + gdb.stepi; + end; + end; +end; + +procedure tactionsmo.nextactonexecute(const sender: tobject); +begin + with mainfo do begin + if checkremake(sc_step) then begin + gdb.next; + end; + end; +end; + +procedure tactionsmo.nextiactonexecute(const sender: TObject); +begin + with mainfo do begin + if checkremake(sc_step) then begin + gdb.nexti; + end; + end; +end; + +procedure tactionsmo.finishactonexecute(const sender: tobject); +begin + with mainfo do begin + if checkremake(sc_continue) then begin + gdb.finish; + end; + end; +end; + +procedure tactionsmo.bkptsononexecute(const sender: TObject); +begin + breakpointsfo.bkptson.value:= bkptsonact.checked; +end; + +procedure tactionsmo.watchesononexecute(const sender: TObject); +begin + watchfo.watcheson.value:= watchesonact.checked; +end; + +procedure tactionsmo.bluedotsononchange(const sender: TObject); +begin + mainfo.checkbluedots; +end; + +procedure tactionsmo.printactonexecute(const sender: TObject); +begin + printform.print; +end; + +procedure tactionsmo.ondetachtarget(const sender: TObject); +begin + if mainfo.checkgdberror(mainfo.gdb.detach) then begin + mainfo.startgdb(false); + end; +end; + +procedure tactionsmo.onattachprocess(const sender: TObject); +var + int1: integer; + info: stopinfoty; +begin + with mainfo do begin + int1:= 0; + if integerenter(int1,minint,maxint,self.c[ord(ac_processid)], + self.c[ord(ac_attachtoprocess)]) = mr_ok then begin + setstattext(self.c[ord(ac_attachingprocess)]+' '+ + inttostrmse(int1),mtk_running); + application.processmessages; + startgdb(false); + gdb.attach(int1,info); + loadexec(true,false); + refreshstopinfo(info); + breakpointsfo.updatebreakpoints(); + end; + end; +end; + +procedure tactionsmo.onattachtarget(const sender: TObject); +var + info: stopinfoty; +begin + with mainfo do begin + startgdb(false); + if checkgdberror(gdb.filesymbol(gettargetfile)) and + startgdbconnection(true) then begin + gdb.attachtarget(info); + loadexec(true,false); + refreshstopinfo(info); + breakpointsfo.updatebreakpoints(); + end; + end; +end; + +procedure tactionsmo.downloadexe(const sender: TObject); +begin + mainfo.loadexec(false,true); +end; + +procedure tactionsmo.helpex(const sender: TObject); +begin + application.help(application.activewidget); +end; + +procedure tactionsmo.setbmexec(const sender: TObject); +begin + sourcefo.setbmexec(sender); +end; + +procedure tactionsmo.findbmexec(const sender: TObject); +begin + sourcefo.findbmexec(sender); +end; + +procedure tactionsmo.projectopenexe(const sender: TObject); +var + fna1: filenamety; +begin + if projectfiledialog(fna1,false) = mr_ok then begin + mainfo.openproject(fna1); + end; +end; + +procedure tactionsmo.projectoptionsexe(const sender: TObject); +begin + editprojectoptions; +end; + +procedure tactionsmo.projecttreeexe(const sender: TObject); +begin + projecttreefo.activate; +end; + +procedure tactionsmo.projectsourceexe(const sender: TObject); +begin + sourcefo.openfile(projectoptions.k.texp.mainfile,true); +end; + +procedure tactionsmo.projectsaveexe(const sender: TObject); +begin + if projectoptions.projectfilename = '' then begin + mainfo.saveprojectasonexecute(sender); + end + else begin + mainfo.saveproject(projectoptions.projectfilename); + end; +end; + +procedure tactionsmo.projectcloeseexe(const sender: TObject); +begin + mainfo.closeprojectactonexecute (sender); +end; + +procedure tactionsmo.creadstateexe(const sender: TObject); +begin + msegdbutils.localizetext; +end; + +procedure tactionsmo.findupdateexe(const sender: tcustomaction); +begin + if targetconsolefo.activeentered then begin + find.enabled:= true; + repeatfind.enabled:= projectoptions.targetconsolefindinfo.text <> '' + end + else begin + find.enabled:= (sourcefo.activepage <> nil) and + sourcefo.activepage.activeentered; + repeatfind.enabled:= find.enabled and + (projectoptions.findreplaceinfo.find.text <> ''); + end; + findback.enabled:= repeatfind.enabled; + findcompallact.enabled:= not find.enabled; +end; + +procedure tactionsmo.findcompexe(const sender: TObject); +begin + if mainfo.factivedesignmodule <> nil then begin + mainfo.factivedesignmodule^.designformintf.findcompdialog(); + end; +end; + +function tactionsmo.filterfindcomp( + const acomponent: tcomponent): boolean; +begin + result:= not (cssubcomponent in acomponent.componentstyle) and + (not (acomponent is twidget) or + (ws_iswidget in twidget(acomponent).widgetstate)); +end; + +procedure tactionsmo.findcompallexe(const sender: TObject); +var + name1: msestring; + comp1: tcomponent; + po1: pmoduleinfoty; +begin + name1:= ''; + with designer do begin + if selections.count > 0 then begin + name1:= msestring(ownernamepath(selections[0])); + end; + if compnamedialog(designer.getcomponentnametree(nil,true,true,nil, + @filterfindcomp,nil),name1,true) = mr_ok then begin + replacechar1(name1,':','.'); + comp1:= designer.getcomponent(ansistring(name1),po1); + designer.showformdesigner(po1); + designer.selectcomponent(comp1); + end; + end; +end; + +procedure tactionsmo.forcezorderexe(const sender: TObject); +begin + if projectoptions.s <> nil then begin + projectoptions.s.forcezorder:= taction(sender).checked; + projectoptionsmodified(); + end; +end; + +end. diff --git a/mseide-msegui/apps/ide/actionsmodule_mfm.pas b/mseide-msegui/apps/ide/actionsmodule_mfm.pas new file mode 100644 index 0000000..06dd7ef --- /dev/null +++ b/mseide-msegui/apps/ide/actionsmodule_mfm.pas @@ -0,0 +1,2295 @@ +unit actionsmodule_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,actionsmodule; + +const + objdata: record size: integer; data: array[0..45557] of byte end = + (size: 45558; data: ( + 84,80,70,48,10,116,97,99,116,105,111,110,115,109,111,9,97,99,116,105, + 111,110,115,109,111,9,98,111,117,110,100,115,95,99,120,3,31,2,9,98, + 111,117,110,100,115,95,99,121,3,179,1,4,108,101,102,116,2,7,3,116, + 111,112,3,198,0,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109, + 101,6,14,116,109,115,101,100,97,116,97,109,111,100,117,108,101,0,7,116, + 97,99,116,105,111,110,7,109,97,107,101,97,99,116,3,84,97,103,2,1, + 7,99,97,112,116,105,111,110,6,5,38,77,97,107,101,9,111,110,101,120, + 101,99,117,116,101,7,16,109,97,107,101,97,99,116,111,110,101,120,101,99, + 117,116,101,4,108,101,102,116,2,8,3,116,111,112,3,38,1,0,0,7, + 116,97,99,116,105,111,110,3,114,117,110,7,99,97,112,116,105,111,110,6, + 4,38,82,117,110,7,105,109,97,103,101,110,114,2,0,4,104,105,110,116, + 6,3,82,117,110,4,108,101,102,116,2,80,3,116,111,112,3,191,0,0, + 0,7,116,97,99,116,105,111,110,4,115,116,101,112,9,105,109,97,103,101, + 108,105,115,116,7,11,98,117,116,116,111,110,105,99,111,110,115,7,99,97, + 112,116,105,111,110,6,5,38,83,116,101,112,7,105,109,97,103,101,110,114, + 2,1,15,105,109,97,103,101,110,114,100,105,115,97,98,108,101,100,2,18, + 4,104,105,110,116,6,4,83,116,101,112,9,111,110,101,120,101,99,117,116, + 101,7,16,115,116,101,112,97,99,116,111,110,101,120,101,99,117,116,101,4, + 108,101,102,116,2,8,3,116,111,112,3,222,0,2,115,99,1,2,1,3, + 54,1,0,0,0,7,116,97,99,116,105,111,110,4,110,101,120,116,9,105, + 109,97,103,101,108,105,115,116,7,11,98,117,116,116,111,110,105,99,111,110, + 115,7,99,97,112,116,105,111,110,6,5,38,78,101,120,116,7,105,109,97, + 103,101,110,114,2,2,15,105,109,97,103,101,110,114,100,105,115,97,98,108, + 101,100,2,22,4,104,105,110,116,6,4,78,101,120,116,9,111,110,101,120, + 101,99,117,116,101,7,16,110,101,120,116,97,99,116,111,110,101,120,101,99, + 117,116,101,4,108,101,102,116,2,8,3,116,111,112,3,206,0,2,115,99, + 1,2,1,3,55,1,0,0,0,7,116,97,99,116,105,111,110,8,99,111, + 110,116,105,110,117,101,9,105,109,97,103,101,108,105,115,116,7,11,98,117, + 116,116,111,110,105,99,111,110,115,7,99,97,112,116,105,111,110,6,9,38, + 67,111,110,116,105,110,117,101,7,105,109,97,103,101,110,114,2,4,15,105, + 109,97,103,101,110,114,100,105,115,97,98,108,101,100,2,17,4,104,105,110, + 116,6,8,67,111,110,116,105,110,117,101,9,111,110,101,120,101,99,117,116, + 101,7,20,99,111,110,116,105,110,117,101,97,99,116,111,110,101,120,101,99, + 117,116,101,4,108,101,102,116,2,8,3,116,111,112,3,254,0,2,115,99, + 1,2,1,3,56,1,0,0,0,7,116,97,99,116,105,111,110,9,105,110, + 116,101,114,114,117,112,116,9,105,109,97,103,101,108,105,115,116,7,11,98, + 117,116,116,111,110,105,99,111,110,115,7,99,97,112,116,105,111,110,6,10, + 38,73,110,116,101,114,114,117,112,116,7,105,109,97,103,101,110,114,2,5, + 15,105,109,97,103,101,110,114,100,105,115,97,98,108,101,100,2,16,4,104, + 105,110,116,6,9,73,110,116,101,114,114,117,112,116,9,111,110,101,120,101, + 99,117,116,101,7,21,105,110,116,101,114,114,117,112,116,97,99,116,111,110, + 101,120,101,99,117,116,101,4,108,101,102,116,2,9,3,116,111,112,3,13, + 1,0,0,7,116,97,99,116,105,111,110,5,114,101,115,101,116,9,105,109, + 97,103,101,108,105,115,116,7,11,98,117,116,116,111,110,105,99,111,110,115, + 7,99,97,112,116,105,111,110,6,6,38,82,101,115,101,116,7,105,109,97, + 103,101,110,114,2,6,15,105,109,97,103,101,110,114,100,105,115,97,98,108, + 101,100,2,15,4,104,105,110,116,6,5,82,101,115,101,116,9,111,110,101, + 120,101,99,117,116,101,7,17,114,101,115,101,116,97,99,116,111,110,101,120, + 101,99,117,116,101,4,108,101,102,116,2,7,3,116,111,112,3,191,0,0, + 0,7,116,97,99,116,105,111,110,10,111,112,101,110,115,111,117,114,99,101, + 7,99,97,112,116,105,111,110,6,5,38,79,112,101,110,9,111,110,101,120, + 101,99,117,116,101,7,22,111,112,101,110,115,111,117,114,99,101,97,99,116, + 111,110,101,120,101,99,117,116,101,4,108,101,102,116,2,8,3,116,111,112, + 2,4,2,115,99,1,2,1,3,79,64,0,0,0,7,116,97,99,116,105, + 111,110,6,102,105,110,105,115,104,9,105,109,97,103,101,108,105,115,116,7, + 11,98,117,116,116,111,110,105,99,111,110,115,7,99,97,112,116,105,111,110, + 6,7,38,70,105,110,105,115,104,7,105,109,97,103,101,110,114,2,3,15, + 105,109,97,103,101,110,114,100,105,115,97,98,108,101,100,2,20,4,104,105, + 110,116,6,6,70,105,110,105,115,104,9,111,110,101,120,101,99,117,116,101, + 7,18,102,105,110,105,115,104,97,99,116,111,110,101,120,101,99,117,116,101, + 4,108,101,102,116,2,8,3,116,111,112,3,238,0,2,115,99,1,2,1, + 3,54,33,0,0,0,7,116,97,99,116,105,111,110,4,115,97,118,101,7, + 99,97,112,116,105,111,110,6,5,38,83,97,118,101,9,111,110,101,120,101, + 99,117,116,101,7,16,115,97,118,101,97,99,116,111,110,101,120,101,99,117, + 116,101,4,108,101,102,116,2,8,3,116,111,112,2,20,2,115,99,1,2, + 1,3,83,64,0,0,0,7,116,97,99,116,105,111,110,5,99,108,111,115, + 101,7,99,97,112,116,105,111,110,6,6,38,67,108,111,115,101,9,111,110, + 101,120,101,99,117,116,101,7,17,99,108,111,115,101,97,99,116,111,110,101, + 120,101,99,117,116,101,4,108,101,102,116,2,8,3,116,111,112,2,68,2, + 115,99,1,2,1,3,51,65,0,0,0,7,116,97,99,116,105,111,110,12, + 97,98,111,114,116,109,97,107,101,97,99,116,7,99,97,112,116,105,111,110, + 6,11,38,65,98,111,114,116,32,77,97,107,101,9,111,110,101,120,101,99, + 117,116,101,7,21,97,98,111,114,116,109,97,107,101,97,99,116,111,110,101, + 120,101,99,117,116,101,4,108,101,102,116,2,8,3,116,111,112,3,146,1, + 0,0,7,116,97,99,116,105,111,110,4,117,110,100,111,7,99,97,112,116, + 105,111,110,6,5,38,85,110,100,111,9,111,110,101,120,101,99,117,116,101, + 7,16,117,110,100,111,97,99,116,111,110,101,120,101,99,117,116,101,4,108, + 101,102,116,3,24,1,3,116,111,112,2,4,2,115,99,1,2,1,3,90, + 64,0,0,0,7,116,97,99,116,105,111,110,4,114,101,100,111,7,99,97, + 112,116,105,111,110,6,5,38,82,101,100,111,9,111,110,101,120,101,99,117, + 116,101,7,16,114,101,100,111,97,99,116,111,110,101,120,101,99,117,116,101, + 4,108,101,102,116,3,24,1,3,116,111,112,2,20,2,115,99,1,2,1, + 3,90,96,0,0,0,7,116,97,99,116,105,111,110,3,99,117,116,7,99, + 97,112,116,105,111,110,6,4,67,117,38,116,9,111,110,101,120,101,99,117, + 116,101,7,15,99,117,116,97,99,116,111,110,101,120,101,99,117,116,101,4, + 108,101,102,116,3,24,1,3,116,111,112,2,36,2,115,99,1,2,1,3, + 88,64,0,3,115,99,49,1,2,1,3,7,33,0,0,0,7,116,97,99, + 116,105,111,110,4,99,111,112,121,7,99,97,112,116,105,111,110,6,5,38, + 67,111,112,121,9,111,110,101,120,101,99,117,116,101,7,16,99,111,112,121, + 97,99,116,111,110,101,120,101,99,117,116,101,4,108,101,102,116,3,24,1, + 3,116,111,112,2,52,2,115,99,1,2,1,3,67,64,0,0,0,7,116, + 97,99,116,105,111,110,5,112,97,115,116,101,7,99,97,112,116,105,111,110, + 6,6,38,80,97,115,116,101,9,111,110,101,120,101,99,117,116,101,7,17, + 112,97,115,116,101,97,99,116,111,110,101,120,101,99,117,116,101,4,108,101, + 102,116,3,24,1,3,116,111,112,2,68,2,115,99,1,2,1,3,86,64, + 0,3,115,99,49,1,2,1,3,6,33,0,0,0,7,116,97,99,116,105, + 111,110,6,100,101,108,101,116,101,7,99,97,112,116,105,111,110,6,7,38, + 68,101,108,101,116,101,9,111,110,101,120,101,99,117,116,101,7,18,100,101, + 108,101,116,101,97,99,116,111,110,101,120,101,99,117,116,101,4,108,101,102, + 116,3,24,1,3,116,111,112,2,84,0,0,7,116,97,99,116,105,111,110, + 7,115,97,118,101,97,108,108,7,99,97,112,116,105,111,110,6,9,83,97, + 38,118,101,32,97,108,108,9,111,110,101,120,101,99,117,116,101,7,19,115, + 97,118,101,97,108,108,97,99,116,111,110,101,120,101,99,117,116,101,4,108, + 101,102,116,2,8,3,116,111,112,2,36,0,0,7,116,97,99,116,105,111, + 110,4,102,105,110,100,7,99,97,112,116,105,111,110,6,5,38,70,105,110, + 100,9,111,110,101,120,101,99,117,116,101,7,16,102,105,110,100,97,99,116, + 111,110,101,120,101,99,117,116,101,8,111,110,117,112,100,97,116,101,7,13, + 102,105,110,100,117,112,100,97,116,101,101,120,101,4,108,101,102,116,3,152, + 0,3,116,111,112,2,28,2,115,99,1,2,1,3,70,64,0,0,0,7, + 116,97,99,116,105,111,110,10,114,101,112,101,97,116,102,105,110,100,7,99, + 97,112,116,105,111,110,6,13,38,83,101,97,114,99,104,32,97,103,97,105, + 110,9,111,110,101,120,101,99,117,116,101,7,22,114,101,112,101,97,116,102, + 105,110,100,97,99,116,111,110,101,120,101,99,117,116,101,4,108,101,102,116, + 3,152,0,3,116,111,112,2,44,2,115,99,1,2,1,3,50,1,0,0, + 0,7,116,97,99,116,105,111,110,10,102,105,110,100,105,110,102,105,108,101, + 7,99,97,112,116,105,111,110,6,14,70,105,110,100,32,105,110,32,70,38, + 105,108,101,115,9,111,110,101,120,101,99,117,116,101,7,19,102,105,110,100, + 105,110,102,105,108,101,111,110,101,120,101,99,117,116,101,4,108,101,102,116, + 3,152,0,3,116,111,112,2,76,2,115,99,1,2,1,3,70,96,0,0, + 0,7,116,97,99,116,105,111,110,8,99,108,111,115,101,97,108,108,7,99, + 97,112,116,105,111,110,6,10,67,38,108,111,115,101,32,97,108,108,9,111, + 110,101,120,101,99,117,116,101,7,20,99,108,111,115,101,97,108,108,97,99, + 116,111,110,101,120,101,99,117,116,101,4,108,101,102,116,2,8,3,116,111, + 112,2,84,0,0,7,116,97,99,116,105,111,110,6,115,97,118,101,97,115, + 7,99,97,112,116,105,111,110,6,8,83,97,118,101,32,38,97,115,9,111, + 110,101,120,101,99,117,116,101,7,18,115,97,118,101,97,115,97,99,116,111, + 110,101,120,101,99,117,116,101,4,108,101,102,116,2,8,3,116,111,112,2, + 52,0,0,7,116,97,99,116,105,111,110,10,98,107,112,116,115,111,110,97, + 99,116,9,105,109,97,103,101,108,105,115,116,7,11,98,117,116,116,111,110, + 105,99,111,110,115,7,99,97,112,116,105,111,110,6,15,38,66,114,101,97, + 107,112,111,105,110,116,115,32,111,110,5,115,116,97,116,101,11,10,97,115, + 95,99,104,101,99,107,101,100,0,7,105,109,97,103,101,110,114,2,7,4, + 104,105,110,116,6,18,66,114,101,97,107,112,111,105,110,116,115,32,111,110, + 47,111,102,102,9,111,110,101,120,101,99,117,116,101,7,16,98,107,112,116, + 115,111,110,111,110,101,120,101,99,117,116,101,4,108,101,102,116,3,152,0, + 3,116,111,112,3,236,0,2,115,99,1,2,1,3,66,64,0,0,0,7, + 116,97,99,116,105,111,110,12,119,97,116,99,104,101,115,111,110,97,99,116, + 9,105,109,97,103,101,108,105,115,116,7,11,98,117,116,116,111,110,105,99, + 111,110,115,7,99,97,112,116,105,111,110,6,11,38,87,97,116,99,104,101, + 115,32,111,110,5,115,116,97,116,101,11,10,97,115,95,99,104,101,99,107, + 101,100,0,7,105,109,97,103,101,110,114,2,9,4,104,105,110,116,6,14, + 87,97,116,99,104,101,115,32,111,110,47,111,102,102,8,115,116,97,116,102, + 105,108,101,7,22,109,97,105,110,102,111,46,112,114,111,106,101,99,116,115, + 116,97,116,102,105,108,101,9,111,110,101,120,101,99,117,116,101,7,18,119, + 97,116,99,104,101,115,111,110,111,110,101,120,101,99,117,116,101,4,108,101, + 102,116,3,152,0,3,116,111,112,3,252,0,2,115,99,1,2,1,3,87, + 64,0,0,0,7,116,97,99,116,105,111,110,4,108,105,110,101,7,99,97, + 112,116,105,111,110,6,5,38,76,105,110,101,9,111,110,101,120,101,99,117, + 116,101,7,16,108,105,110,101,97,99,116,111,110,101,120,101,99,117,116,101, + 4,108,101,102,116,3,152,0,3,116,111,112,2,12,2,115,99,1,2,1, + 3,76,64,0,0,0,7,116,97,99,116,105,111,110,10,116,111,103,103,108, + 101,98,107,112,116,7,99,97,112,116,105,111,110,6,18,38,84,111,103,103, + 108,101,32,66,114,101,97,107,112,111,105,110,116,9,111,110,101,120,101,99, + 117,116,101,7,19,116,111,103,103,108,101,98,114,101,97,107,112,111,105,110, + 116,101,120,101,4,108,101,102,116,3,152,0,3,116,111,112,3,204,0,2, + 115,99,1,2,1,3,52,1,0,0,0,7,116,97,99,116,105,111,110,16, + 116,111,103,103,108,101,98,107,112,116,101,110,97,98,108,101,7,99,97,112, + 116,105,111,110,6,21,84,111,103,103,108,101,32,66,107,112,116,46,32,38, + 101,110,97,98,108,101,100,9,111,110,101,120,101,99,117,116,101,7,28,116, + 111,103,103,108,101,98,107,112,116,101,110,97,98,108,101,97,99,116,111,110, + 101,120,101,99,117,116,101,4,108,101,102,116,3,152,0,3,116,111,112,3, + 220,0,2,115,99,1,2,1,3,52,33,0,0,0,10,116,105,109,97,103, + 101,108,105,115,116,11,98,117,116,116,111,110,105,99,111,110,115,5,119,105, + 100,116,104,2,24,6,104,101,105,103,104,116,2,24,7,111,112,116,105,111, + 110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99, + 111,108,111,114,109,97,115,107,0,5,99,111,117,110,116,2,24,4,108,101, + 102,116,3,96,1,3,116,111,112,2,32,5,105,109,97,103,101,10,228,116, + 0,0,0,0,0,0,6,0,0,0,120,0,0,0,120,0,0,0,88,58, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,192,192,24,208,208, + 208,6,0,165,9,3,208,208,208,26,0,0,0,1,208,208,208,2,0,0, + 0,1,208,208,208,11,0,0,0,1,208,208,208,2,0,0,0,1,208,208, + 208,42,192,192,192,24,208,208,208,6,0,165,9,1,16,168,16,1,0,165, + 9,2,208,208,208,25,0,0,0,5,208,208,208,10,0,0,0,5,208,208, + 208,41,192,192,192,24,208,208,208,6,0,165,9,1,38,187,32,1,30,180, + 26,1,0,165,9,2,208,208,208,26,0,0,0,2,208,208,208,13,0,0, + 0,9,208,208,208,5,0,163,8,3,208,208,208,27,192,192,192,13,128,0, + 0,2,192,192,192,9,208,208,208,6,0,165,9,1,50,206,46,1,60,211, + 51,1,34,189,32,1,0,165,9,2,208,208,208,1,0,0,0,1,208,208, + 208,2,0,0,0,1,208,208,208,37,0,0,0,7,208,208,208,5,10,183, + 7,1,24,208,2,1,10,183,7,1,0,21,0,1,0,0,0,1,208,208, + 208,7,0,169,9,1,4,180,10,1,0,0,0,1,208,208,208,15,192,192, + 192,13,128,0,0,2,192,192,192,9,208,208,208,6,0,165,9,1,59,223, + 56,1,76,237,68,1,67,226,61,1,39,198,38,1,0,165,9,2,0,0, + 0,5,208,208,208,36,0,0,0,11,0,191,0,1,15,189,5,1,32,223, + 0,1,13,179,4,1,0,4,0,1,0,0,0,1,208,208,208,7,0,167, + 8,1,13,197,10,1,8,154,11,1,0,43,0,1,208,208,208,14,192,192, + 192,5,128,128,128,6,128,0,0,3,128,128,128,1,192,192,192,9,208,208, + 208,3,2,168,9,1,7,178,7,1,11,183,6,1,7,177,7,1,60,225, + 57,1,82,250,77,1,84,253,79,1,76,242,71,1,44,208,44,1,0,165, + 9,2,208,208,208,1,0,0,0,9,208,208,208,3,0,170,0,1,8,178, + 8,1,10,183,6,1,12,187,6,1,14,190,6,1,14,189,6,4,10,183, + 7,1,0,146,7,1,208,208,208,16,0,0,0,11,0,170,0,1,16,192, + 4,1,32,223,0,1,14,178,4,1,0,8,0,1,0,0,0,1,208,208, + 208,7,0,167,8,1,21,213,11,1,36,221,25,1,12,161,16,1,0,89, + 0,1,208,208,208,13,192,192,192,8,128,128,128,1,128,0,0,5,192,192, + 192,10,208,208,208,2,6,175,7,1,14,189,5,1,31,221,0,1,32,223, + 0,1,18,197,4,1,52,211,47,1,73,232,64,1,75,237,67,1,78,242, + 71,1,70,237,66,1,31,197,35,1,0,165,9,1,208,208,208,3,0,0, + 0,7,208,208,208,2,0,167,10,1,9,181,7,1,27,215,1,1,32,223, + 0,7,24,208,2,1,0,62,3,1,0,0,0,1,208,208,208,11,0,0, + 0,4,208,208,208,11,0,163,12,1,18,195,4,1,32,223,0,1,12,171, + 5,1,0,2,0,1,0,0,0,1,208,208,208,7,0,167,8,1,21,213, + 11,1,44,231,29,1,55,229,43,1,19,168,21,1,0,104,6,1,0,0, + 0,1,208,208,208,11,192,192,192,4,128,128,128,4,128,0,0,6,192,192, + 192,10,208,208,208,1,2,168,9,1,16,193,5,1,32,223,0,2,28,215, + 1,1,9,175,6,1,45,197,38,1,63,213,51,1,66,218,55,1,64,219, + 55,1,40,200,39,1,0,97,5,1,0,18,1,1,208,208,208,3,0,0, + 0,7,208,208,208,1,0,170,0,1,9,181,6,1,31,222,0,1,32,223, + 0,1,29,216,1,1,19,196,3,1,15,182,4,1,15,181,4,1,14,180, + 4,1,14,178,4,1,14,177,4,1,9,174,6,1,0,62,3,1,0,0, + 0,1,208,208,208,1,0,0,0,3,208,208,208,2,0,0,0,1,208,208, + 208,4,0,0,0,4,208,208,208,10,0,168,7,1,7,177,7,1,28,215, + 1,1,32,223,0,1,9,156,6,1,0,0,0,2,208,208,208,7,0,167, + 8,1,21,213,11,1,44,231,29,1,60,234,46,1,74,235,61,1,31,179, + 33,1,10,124,13,1,0,0,0,1,208,208,208,10,192,192,192,8,128,0, + 0,1,128,128,128,1,128,0,0,5,192,192,192,9,208,208,208,1,8,179, + 7,1,31,221,0,1,32,223,0,1,11,169,5,1,3,108,5,1,0,75, + 4,1,38,183,28,1,53,194,39,1,52,197,40,1,33,187,30,1,0,97, + 5,1,0,18,1,1,208,208,208,4,0,0,0,7,208,208,208,1,6,175, + 8,1,26,214,1,1,32,223,0,1,18,186,3,1,4,123,5,1,0,44, + 2,1,0,16,0,1,0,15,0,1,0,11,0,1,0,8,0,1,0,6, + 0,1,0,2,0,1,0,0,0,2,208,208,208,1,0,0,0,7,208,208, + 208,4,4,178,8,1,8,181,7,1,11,184,6,1,14,188,6,1,14,189, + 6,9,20,201,3,1,30,219,1,1,32,223,0,1,29,218,1,1,5,132, + 5,1,0,0,0,2,208,208,208,7,0,167,8,1,21,213,11,1,44,231, + 29,1,60,234,46,1,76,236,63,1,92,239,80,1,49,193,49,1,16,138, + 23,1,0,0,0,1,208,208,208,9,192,192,192,5,128,128,128,5,128,0, + 0,6,192,192,192,8,208,208,208,1,13,187,5,1,32,223,0,1,28,215, + 1,1,3,108,5,1,0,0,0,1,0,106,6,1,31,169,19,1,41,175, + 25,1,26,174,20,1,0,97,5,1,0,18,1,1,208,208,208,1,0,0, + 0,4,208,208,208,8,11,185,5,1,32,223,0,1,31,222,0,1,6,138, + 6,1,0,0,0,1,0,39,4,1,0,145,7,1,0,151,15,1,0,0, + 0,5,208,208,208,4,0,0,0,1,208,208,208,3,0,0,0,1,208,208, + 208,3,8,175,8,1,18,195,4,1,32,223,0,14,28,216,1,1,8,158, + 6,1,0,13,0,1,0,0,0,2,208,208,208,7,0,167,8,1,21,213, + 11,1,44,231,29,1,60,234,46,1,76,236,63,1,92,239,80,1,107,242, + 96,1,75,207,72,1,23,150,28,1,0,0,0,1,208,208,208,8,192,192, + 192,9,128,0,0,4,128,128,128,1,192,192,192,1,128,0,0,2,192,192, + 192,7,0,165,9,1,15,191,5,1,32,223,0,1,17,187,4,1,0,34, + 2,1,0,0,0,1,0,154,8,1,21,156,10,1,19,161,11,1,0,97, + 5,1,0,18,1,1,208,208,208,2,0,0,0,4,208,208,208,8,13,188, + 5,1,32,223,0,1,23,204,2,1,1,75,3,1,0,0,0,1,0,163, + 8,1,16,169,17,1,0,164,9,1,0,159,16,1,208,208,208,15,6,170, + 6,1,18,197,4,1,32,223,0,2,22,204,2,1,14,178,4,1,13,177, + 4,1,13,178,4,1,14,178,4,2,14,179,4,1,15,181,4,2,15,182, + 4,1,16,183,4,1,12,173,4,1,8,154,6,1,4,123,5,1,0,11, + 0,1,0,0,0,2,208,208,208,8,0,167,8,1,21,213,11,1,44,231, + 29,1,60,234,46,1,76,236,63,1,92,239,80,1,107,242,96,1,123,245, + 113,1,104,224,100,1,29,157,34,1,0,85,0,1,208,208,208,7,192,192, + 192,5,128,0,0,2,192,192,192,2,128,0,0,5,128,128,128,1,192,192, + 192,1,128,128,128,1,192,192,192,7,208,208,208,1,13,187,5,1,32,223, + 0,1,28,215,1,1,3,110,5,1,0,0,0,1,0,163,9,1,9,155, + 6,1,0,97,5,1,0,18,1,1,0,0,0,1,208,208,208,14,12,186, + 6,1,32,223,0,1,23,204,2,1,1,75,3,1,0,0,0,1,0,163, + 8,1,38,187,33,1,30,179,26,1,0,157,9,1,0,159,16,1,208,208, + 208,14,9,179,7,1,31,223,0,1,32,223,0,1,9,163,5,1,2,69, + 3,1,0,27,1,1,0,67,4,1,0,23,1,1,0,6,0,1,0,8, + 0,1,0,10,0,1,0,12,0,1,0,13,0,1,0,15,0,1,0,19, + 2,1,0,2,0,1,0,0,0,5,208,208,208,8,0,167,8,1,21,213, + 11,1,44,231,29,1,60,234,46,1,76,236,63,1,92,239,80,1,107,242, + 96,1,123,245,113,1,139,247,130,1,134,238,128,1,38,167,41,1,0,98, + 10,1,208,208,208,6,192,192,192,4,128,128,128,1,128,0,0,3,128,128, + 128,1,128,0,0,2,128,128,128,1,128,0,0,3,192,192,192,9,208,208, + 208,1,8,177,7,1,31,222,0,1,32,223,0,1,10,166,5,1,1,93, + 5,1,0,122,7,1,0,163,9,1,0,18,1,1,208,208,208,16,10,182, + 7,1,32,223,0,1,31,222,0,1,6,138,6,1,0,0,0,1,0,163, + 8,1,50,206,45,1,60,211,52,1,34,189,32,1,0,157,9,1,0,159, + 16,1,208,208,208,13,10,185,6,1,32,223,0,1,26,212,2,1,1,91, + 4,1,0,0,0,1,0,108,6,1,17,169,16,1,0,156,8,1,0,97, + 5,1,0,0,0,11,208,208,208,9,0,167,8,1,21,213,11,1,44,231, + 29,1,60,234,46,1,76,236,63,1,92,239,80,1,107,242,96,1,123,245, + 113,1,139,247,130,1,134,238,128,1,36,160,39,1,0,24,2,1,0,0, + 0,1,208,208,208,5,192,192,192,4,128,0,0,1,128,128,128,1,128,0, + 0,5,192,192,192,1,128,128,128,1,128,0,0,2,192,192,192,9,208,208, + 208,1,1,143,7,1,16,186,4,1,32,223,0,1,31,222,0,1,20,196, + 3,1,14,185,5,1,13,187,5,1,13,188,5,8,12,185,6,1,9,179, + 6,1,6,171,7,1,0,41,2,1,0,0,0,1,208,208,208,4,5,174, + 8,1,23,202,3,1,32,223,0,1,18,186,3,1,4,145,6,1,0,164, + 8,1,59,223,56,1,76,237,68,1,67,226,61,1,39,198,38,1,0,157, + 9,1,0,159,16,1,208,208,208,12,12,186,6,1,32,223,0,1,19,192, + 3,1,0,41,2,1,0,0,0,1,0,154,8,1,38,188,33,1,30,180, + 26,1,0,165,9,2,208,208,208,19,0,167,8,1,21,213,11,1,44,231, + 29,1,60,234,46,1,76,236,63,1,92,239,80,1,107,242,96,1,123,245, + 113,1,104,224,100,1,26,144,31,1,0,7,0,1,0,0,0,1,208,208, + 208,6,192,192,192,7,128,128,128,1,128,0,0,2,192,192,192,2,128,128, + 128,1,128,0,0,2,192,192,192,9,208,208,208,1,0,0,0,1,5,147, + 6,1,13,177,5,1,31,222,0,1,32,223,0,13,27,212,2,1,6,158, + 6,1,0,0,0,2,208,208,208,4,6,166,6,1,29,219,1,1,32,223, + 0,1,29,216,1,1,14,189,4,1,60,225,57,1,82,250,77,1,84,253, + 79,1,76,242,71,1,44,207,44,1,0,157,9,1,0,159,16,1,208,208, + 208,2,0,0,0,8,208,208,208,1,10,183,6,1,32,223,0,1,29,218, + 1,1,5,125,5,1,0,0,0,1,0,163,9,1,51,207,46,1,61,211, + 51,1,35,189,32,1,0,165,9,2,0,0,0,6,208,208,208,12,0,167, + 8,1,21,213,11,1,44,231,29,1,60,234,46,1,76,236,63,1,92,239, + 80,1,107,242,96,1,75,207,72,1,19,123,23,1,0,0,0,2,208,208, + 208,7,192,192,192,12,128,0,0,2,128,128,128,1,192,192,192,9,208,208, + 208,2,0,0,0,1,1,69,4,1,6,146,6,1,9,161,5,1,12,174, + 5,1,13,176,5,9,19,193,3,1,30,219,1,1,32,223,0,1,23,202, + 2,1,3,108,5,1,0,0,0,2,208,208,208,3,0,147,0,1,6,153, + 6,1,25,208,2,1,32,223,0,1,24,208,2,1,52,210,47,1,73,232, + 64,1,75,237,67,1,78,242,71,1,70,237,66,1,31,198,35,1,0,148, + 7,1,208,208,208,2,0,0,0,8,208,208,208,1,7,175,7,1,31,220, + 0,1,32,223,0,1,14,179,4,1,4,133,6,1,0,155,8,1,59,224, + 57,1,76,237,69,1,68,227,61,1,39,199,38,1,0,165,9,1,0,64, + 3,1,0,0,0,5,208,208,208,12,0,167,8,1,21,213,11,1,44,231, + 29,1,60,234,46,1,76,236,63,1,92,239,80,1,48,192,48,1,11,95, + 16,1,0,0,0,2,208,208,208,8,192,192,192,11,128,128,128,1,128,0, + 0,1,128,128,128,1,192,192,192,10,208,208,208,3,0,0,0,13,0,44, + 2,1,6,146,6,1,28,215,1,1,32,223,0,1,8,150,5,1,0,0, + 0,2,208,208,208,4,0,14,0,1,4,122,4,1,8,152,6,1,8,170, + 6,1,45,197,38,1,63,213,51,1,66,218,55,1,64,219,55,1,40,200, + 39,1,0,96,5,1,0,18,2,1,208,208,208,11,0,134,7,1,14,184, + 4,1,32,223,0,2,24,209,2,1,8,177,6,1,60,226,58,1,83,251, + 77,1,84,254,79,1,76,243,71,1,44,208,44,1,0,165,9,2,208,208, + 208,2,0,0,0,7,208,208,208,7,0,167,8,1,21,213,11,1,44,231, + 29,1,60,234,46,1,74,235,61,1,31,178,32,1,5,63,6,1,0,0, + 0,2,208,208,208,9,192,192,192,11,128,0,0,2,128,128,128,2,192,192, + 192,9,208,208,208,3,0,0,0,14,0,74,4,1,16,190,4,1,32,223, + 0,1,11,167,5,1,0,0,0,2,208,208,208,5,0,0,0,2,0,79, + 4,1,38,183,28,1,53,194,39,1,52,197,40,1,33,186,30,1,0,96, + 5,1,0,18,2,1,208,208,208,12,0,0,0,1,5,147,7,1,14,177, + 4,1,31,223,0,1,32,223,0,1,18,197,4,1,53,211,48,1,73,232, + 65,1,76,237,68,1,78,242,71,1,71,237,67,1,31,197,35,1,0,165, + 9,1,208,208,208,2,0,0,0,7,208,208,208,7,0,167,8,1,21,213, + 11,1,44,231,29,1,55,229,43,1,19,164,21,1,0,33,2,1,0,0, + 0,2,208,208,208,10,192,192,192,11,128,0,0,4,192,192,192,9,208,208, + 208,5,0,0,0,9,208,208,208,3,0,133,7,1,15,190,5,1,32,223, + 0,1,14,178,5,1,0,8,0,1,0,0,0,1,208,208,208,7,0,161, + 8,1,31,168,18,1,41,175,25,1,26,174,20,1,0,96,5,1,0,18, + 2,1,208,208,208,14,0,0,0,1,0,77,3,1,7,146,5,1,11,163, + 4,1,7,172,6,1,46,197,38,1,63,213,52,1,66,219,55,1,65,220, + 56,1,40,201,39,1,0,97,5,1,0,18,1,1,208,208,208,2,0,0, + 0,8,208,208,208,6,0,167,8,1,21,213,11,1,36,221,25,1,11,152, + 15,1,0,15,0,1,0,0,0,2,208,208,208,11,192,192,192,24,208,208, + 208,7,0,0,0,7,208,208,208,3,0,165,9,1,14,189,5,1,32,223, + 0,1,13,178,5,1,0,5,0,1,0,0,0,1,208,208,208,7,0,163, + 8,1,20,157,10,1,19,160,11,1,0,96,5,1,0,18,2,1,208,208, + 208,16,0,0,0,3,0,76,4,1,38,184,29,1,54,195,39,1,52,198, + 41,1,33,187,30,1,0,97,5,1,0,18,1,1,0,0,0,4,208,208, + 208,1,0,0,0,2,208,208,208,10,0,167,8,1,13,197,10,1,7,137, + 10,1,0,3,0,1,0,0,0,1,208,208,208,13,192,192,192,24,208,208, + 208,7,0,0,0,11,10,182,6,1,24,208,2,1,9,174,6,1,0,1, + 0,1,0,0,0,1,208,208,208,7,0,163,8,1,10,153,5,1,1,102, + 5,1,0,18,2,1,208,208,208,18,0,0,0,2,0,148,8,1,31,169, + 19,1,41,175,25,1,26,174,21,1,0,97,5,1,0,18,1,1,0,0, + 0,5,208,208,208,13,0,169,9,1,4,179,10,1,0,0,0,2,208,208, + 208,14,192,192,192,24,208,208,208,5,0,0,0,9,208,208,208,1,0,0, + 0,3,0,145,8,1,0,70,4,1,0,66,4,1,0,0,0,2,208,208, + 208,7,0,159,16,1,0,161,8,1,0,18,2,1,208,208,208,2,0,0, + 0,4,208,208,208,15,0,165,9,1,22,156,10,1,19,161,12,1,0,97, + 5,1,0,18,1,1,208,208,208,21,0,0,0,1,208,208,208,15,192,192, + 192,24,208,208,208,3,0,0,0,4,208,208,208,11,0,0,0,5,208,208, + 208,12,0,0,0,4,208,208,208,15,0,165,9,1,9,155,6,1,0,97, + 5,1,0,18,1,1,208,208,208,38,192,192,192,24,208,208,208,6,0,0, + 0,1,208,208,208,47,0,165,9,1,0,158,9,1,0,18,1,1,208,208, + 208,111,248,252,248,24,208,208,208,96,248,252,248,24,208,208,208,56,0,0, + 148,1,0,0,163,1,0,0,172,1,0,0,182,2,0,0,170,1,0,0, + 159,1,0,0,133,1,0,0,0,2,208,208,208,30,248,252,248,2,0,0, + 0,2,248,252,248,16,0,0,0,2,248,252,248,2,208,208,208,54,0,0, + 149,1,0,0,169,1,0,0,217,1,0,0,245,1,0,0,255,4,0,0, + 245,1,0,0,215,1,0,0,160,1,0,0,84,1,0,0,0,1,208,208, + 208,29,248,252,248,2,0,0,0,3,248,252,248,14,0,0,0,3,248,252, + 248,2,208,208,208,30,242,48,20,1,245,86,49,2,240,45,18,1,208,208, + 208,4,240,48,20,1,245,88,50,2,242,46,18,1,208,208,208,11,0,0, + 162,1,0,0,190,1,0,0,251,1,0,0,255,3,9,9,255,1,14,14, + 255,1,17,17,255,2,14,14,255,1,9,9,251,1,1,1,180,1,0,0, + 133,1,0,0,0,2,208,208,208,27,248,252,248,3,0,0,0,3,248,252, + 248,12,0,0,0,3,248,252,248,3,208,208,208,30,244,80,45,1,253,163, + 110,2,228,74,41,1,2,0,0,1,208,208,208,3,244,80,45,1,253,163, + 110,2,228,74,41,1,2,0,0,1,208,208,208,9,0,0,162,1,0,0, + 220,1,0,0,255,2,1,1,255,1,14,14,255,1,26,26,255,1,35,35, + 255,1,41,41,255,1,45,45,255,2,41,41,255,1,35,35,255,1,26,26, + 255,1,10,10,214,1,0,0,118,1,0,0,0,2,208,208,208,26,248,252, + 248,4,0,0,0,3,248,252,248,10,0,0,0,3,248,252,248,4,208,208, + 208,30,244,77,41,1,252,153,102,2,228,71,39,1,4,0,0,1,208,208, + 208,3,244,77,41,1,252,153,102,2,228,71,39,1,4,0,0,1,208,208, + 208,8,0,0,149,1,0,0,190,1,0,0,255,1,0,0,245,1,4,4, + 156,1,21,21,235,1,38,38,255,1,51,51,255,1,62,62,255,1,69,69, + 255,1,72,72,255,2,63,63,233,1,38,38,156,1,50,50,245,1,39,39, + 255,1,9,9,176,1,0,0,43,1,0,0,0,1,208,208,208,26,248,252, + 248,5,0,0,0,3,248,252,248,3,0,0,248,2,248,252,248,3,0,0, + 0,3,248,252,248,5,208,208,208,30,243,72,38,1,251,143,94,2,229,68, + 36,1,5,0,0,1,208,208,208,3,243,72,38,1,251,143,95,2,229,68, + 37,1,5,0,0,1,208,208,208,8,0,0,169,1,0,0,251,1,0,0, + 255,1,4,4,156,1,0,0,0,1,7,7,40,1,55,55,231,1,76,76, + 255,1,87,87,255,1,95,95,255,1,100,100,255,1,91,91,231,1,15,15, + 40,1,0,0,0,1,46,46,156,1,62,62,255,1,43,43,251,1,5,5, + 143,1,0,0,0,2,208,208,208,10,6,6,159,1,12,12,175,1,19,19, + 185,1,25,25,186,1,21,21,174,1,12,12,156,1,208,208,208,9,248,252, + 248,6,0,0,0,3,0,0,248,6,0,0,0,3,248,252,248,6,208,208, + 208,5,0,0,0,2,208,208,208,4,0,0,0,2,208,208,208,4,0,0, + 0,3,208,208,208,10,243,68,35,1,250,133,87,2,227,65,34,1,7,0, + 0,1,208,208,208,3,243,68,35,1,250,133,87,2,227,65,34,1,7,0, + 0,1,208,208,208,7,0,0,148,1,0,0,217,1,0,0,255,2,21,21, + 233,1,7,7,40,1,0,0,0,1,13,13,40,1,90,90,231,1,113,113, + 255,1,122,122,255,1,115,115,231,1,20,20,40,1,0,0,0,1,18,18, + 40,1,92,92,235,1,83,83,255,1,65,65,255,1,29,29,210,1,0,0, + 54,1,0,0,0,2,208,208,208,8,4,4,171,1,14,14,204,1,40,40, + 254,1,52,52,255,1,64,64,255,1,75,75,254,1,46,46,195,1,20,20, + 145,1,208,208,208,8,248,252,248,7,0,0,0,3,0,0,248,4,0,0, + 0,3,248,252,248,7,208,208,208,3,0,0,0,12,208,208,208,1,0,0, + 0,6,208,208,208,8,243,64,32,1,249,123,79,2,227,61,31,1,9,0, + 0,1,208,208,208,3,243,64,32,1,249,123,79,2,227,61,31,1,9,0, + 0,1,208,208,208,7,0,0,163,1,0,0,245,1,0,0,255,1,14,14, + 255,1,37,37,255,1,54,54,231,1,13,13,40,1,0,0,0,1,19,19, + 40,1,120,120,231,1,124,124,231,1,22,22,40,1,0,0,0,1,21,21, + 40,1,120,120,231,1,122,122,255,1,103,103,255,1,83,83,255,1,56,56, + 245,1,4,4,105,1,0,0,0,2,208,208,208,7,0,0,159,1,9,9, + 204,1,28,28,255,1,40,40,255,1,52,52,255,1,64,64,255,1,76,76, + 255,1,88,88,255,1,50,50,190,1,5,5,62,1,208,208,208,7,248,252, + 248,7,0,0,248,1,0,0,0,3,0,0,248,2,0,0,0,3,0,0, + 248,1,248,252,248,7,208,208,208,3,0,0,0,20,208,208,208,7,242,60, + 28,1,248,113,71,2,227,57,28,1,11,2,0,1,208,208,208,3,242,60, + 28,1,248,113,71,2,227,57,28,1,11,2,0,1,208,208,208,7,0,0, + 172,1,0,0,255,2,25,25,255,1,50,50,255,1,74,74,255,1,88,88, + 231,1,19,19,40,1,0,0,0,1,20,20,36,1,21,21,36,1,0,0, + 0,1,24,24,40,1,133,133,231,1,141,141,255,1,134,134,255,1,120,120, + 255,1,98,98,255,1,74,74,255,1,11,11,138,1,0,0,0,2,208,208, + 208,7,1,1,175,1,17,17,254,1,28,28,255,1,40,40,255,1,52,52, + 255,1,64,64,255,1,76,76,255,1,88,88,255,1,99,99,254,1,24,24, + 135,1,0,0,0,1,208,208,208,6,248,252,248,7,0,0,248,2,0,0, + 0,6,0,0,248,2,248,252,248,7,208,208,208,3,0,0,0,20,208,208, + 208,7,242,55,25,1,247,103,63,2,225,54,25,1,12,2,0,1,208,208, + 208,3,242,55,25,1,247,103,63,2,225,54,25,1,12,2,0,1,208,208, + 208,7,0,0,182,1,0,0,255,1,7,7,255,1,33,33,255,1,58,58, + 255,1,84,84,255,1,109,109,255,1,119,119,231,1,20,20,36,1,0,0, + 0,2,23,23,36,1,146,146,231,1,157,157,255,1,149,149,255,1,140,140, + 255,1,131,131,255,1,109,109,255,1,84,84,255,1,19,19,161,1,0,0, + 0,2,208,208,208,7,3,3,185,1,17,17,255,1,28,28,255,1,40,40, + 255,1,52,52,255,1,64,64,255,1,76,76,255,1,88,88,255,1,100,100, + 255,1,37,37,159,1,0,0,0,1,208,208,208,6,248,252,248,6,0,0, + 248,4,0,0,0,4,0,0,248,4,248,252,248,6,208,208,208,3,0,0, + 0,20,208,208,208,7,242,52,22,1,246,93,55,2,226,50,22,1,12,2, + 0,1,208,208,208,3,242,52,22,1,246,93,55,2,226,50,23,1,12,2, + 0,1,208,208,208,7,0,0,182,1,0,0,255,1,11,11,255,1,38,38, + 255,1,64,64,255,1,90,90,255,1,117,117,255,1,121,121,231,1,21,21, + 36,1,0,0,0,2,24,24,36,1,156,156,231,1,165,165,255,1,155,155, + 255,1,145,145,255,1,134,134,255,1,117,117,255,1,91,91,255,1,21,21, + 160,1,0,0,0,2,208,208,208,7,3,3,186,1,17,17,255,1,28,28, + 255,1,40,40,255,1,52,52,255,1,64,64,255,1,76,76,255,1,88,88, + 255,1,100,100,255,1,37,37,159,1,0,0,0,1,208,208,208,6,248,252, + 248,6,0,0,248,4,0,0,0,4,0,0,248,4,248,252,248,6,208,208, + 208,4,0,0,0,19,208,208,208,7,241,47,19,1,245,83,48,2,225,45, + 20,1,14,2,0,1,208,208,208,3,241,47,19,1,245,83,48,1,245,84, + 48,1,225,47,20,1,14,2,0,1,208,208,208,7,0,0,170,1,0,0, + 255,1,13,13,255,1,39,39,255,1,66,66,255,1,93,93,255,1,108,108, + 231,1,21,21,40,1,0,0,0,1,23,23,36,1,24,24,36,1,0,0, + 0,1,28,28,40,1,152,152,231,1,157,157,255,1,147,147,255,1,136,136, + 255,1,119,119,255,1,93,93,255,1,14,14,137,1,0,0,0,2,208,208, + 208,7,1,1,174,1,17,17,254,1,28,28,255,1,40,40,255,1,52,52, + 255,1,64,64,255,1,76,76,255,1,88,88,255,1,99,99,254,1,24,24, + 135,1,0,0,0,1,208,208,208,6,248,252,248,7,0,0,248,2,0,0, + 0,6,0,0,248,2,248,252,248,7,208,208,208,5,0,0,0,4,208,208, + 208,2,0,0,0,4,208,208,208,2,0,0,0,5,208,208,208,8,241,44, + 17,1,244,73,40,2,224,42,17,1,16,2,0,1,208,208,208,3,241,44, + 17,1,244,74,40,2,224,42,17,1,16,2,0,1,208,208,208,7,0,0, + 159,1,0,0,245,1,11,11,255,1,38,38,255,1,64,64,255,1,82,82, + 231,1,18,18,40,1,0,0,0,1,23,23,40,1,140,140,231,1,149,149, + 231,1,27,27,40,1,0,0,0,1,26,26,40,1,140,140,231,1,145,145, + 255,1,134,134,255,1,117,117,255,1,82,82,245,1,8,8,101,1,0,0, + 0,2,208,208,208,7,0,0,156,1,9,9,195,1,28,28,255,1,40,40, + 255,1,52,52,255,1,64,64,255,1,76,76,255,1,88,88,255,1,51,51, + 190,1,3,3,37,1,0,0,0,1,208,208,208,6,248,252,248,7,0,0, + 248,1,0,0,0,3,0,0,248,2,0,0,0,3,0,0,248,1,248,252, + 248,7,208,208,208,5,0,0,0,4,208,208,208,2,0,0,0,4,208,208, + 208,2,0,0,0,4,208,208,208,9,241,40,13,1,243,64,32,2,224,38, + 14,1,18,2,0,1,208,208,208,3,241,40,13,1,243,64,32,2,224,38, + 14,1,18,2,0,1,208,208,208,7,0,0,133,1,0,0,215,1,7,7, + 255,1,33,33,255,1,54,54,235,1,13,13,40,1,0,0,0,1,21,21, + 40,1,127,127,231,1,149,149,255,1,157,157,255,1,146,146,231,1,25,25, + 40,1,0,0,0,1,23,23,40,1,128,128,233,1,131,131,255,1,109,109, + 255,1,54,54,211,1,0,0,43,1,0,0,0,2,208,208,208,8,2,2, + 145,1,15,15,190,1,40,40,254,1,52,52,255,1,64,64,255,1,75,75, + 254,1,44,44,190,1,12,12,92,1,0,0,0,2,208,208,208,6,248,252, + 248,7,0,0,0,3,0,0,248,4,0,0,0,3,248,252,248,7,208,208, + 208,5,0,0,0,3,208,208,208,3,0,0,0,3,208,208,208,3,0,0, + 0,4,208,208,208,9,240,35,9,1,242,54,24,2,223,35,11,1,19,2, + 0,1,208,208,208,3,240,35,9,1,242,54,24,2,223,35,11,1,19,2, + 0,1,208,208,208,7,0,0,0,1,0,0,160,1,0,0,251,1,25,25, + 255,1,31,31,156,1,0,0,0,1,15,15,40,1,109,109,231,1,134,134, + 255,1,141,141,255,1,147,147,255,1,150,150,255,1,136,136,231,1,23,23, + 40,1,0,0,0,1,82,82,156,1,120,120,255,1,94,94,251,1,15,15, + 139,1,0,0,0,3,208,208,208,9,0,0,62,1,8,8,135,1,18,18, + 159,1,21,21,159,1,17,17,135,1,2,2,37,1,0,0,0,2,208,208, + 208,7,248,252,248,6,0,0,0,3,0,0,248,6,0,0,0,3,248,252, + 248,6,208,208,208,5,0,0,0,4,208,208,208,2,0,0,0,4,208,208, + 208,2,0,0,0,4,208,208,208,9,240,32,6,1,241,44,16,2,224,31, + 6,1,21,2,0,1,208,208,208,3,240,32,6,1,241,44,16,2,224,31, + 7,1,21,2,0,1,208,208,208,7,0,0,0,1,0,0,84,1,0,0, + 180,1,14,14,255,1,37,37,245,1,37,37,156,1,76,76,233,1,103,103, + 255,1,122,122,255,1,132,132,255,1,137,137,255,1,139,139,255,2,126,126, + 235,1,81,81,156,1,116,116,245,1,103,103,255,1,32,32,174,1,0,0, + 21,1,0,0,0,3,208,208,208,10,0,0,0,6,208,208,208,8,248,252, + 248,5,0,0,0,3,248,252,248,3,0,0,248,2,248,252,248,3,0,0, + 0,3,248,252,248,5,208,208,208,6,0,0,0,2,208,208,208,4,0,0, + 0,2,208,208,208,4,0,0,0,2,208,208,208,10,240,27,4,1,240,34, + 8,2,222,26,3,1,23,2,0,1,208,208,208,3,240,27,4,1,240,34, + 9,2,222,26,4,1,23,2,0,1,208,208,208,8,0,0,0,1,0,0, + 133,1,1,1,214,1,23,23,255,1,45,45,255,1,65,65,255,1,83,83, + 255,1,100,100,255,1,113,113,255,1,123,123,255,1,127,127,255,2,122,122, + 255,1,113,113,255,1,99,99,255,1,57,57,214,1,6,6,88,1,0,0, + 0,3,208,208,208,25,248,252,248,4,0,0,0,3,248,252,248,10,0,0, + 0,3,248,252,248,4,208,208,208,30,238,24,0,1,223,22,0,1,222,22, + 0,1,224,22,0,1,24,2,0,1,208,208,208,3,239,23,0,1,222,21, + 0,1,219,21,0,1,222,21,0,1,24,2,0,1,208,208,208,9,0,0, + 0,1,0,0,118,1,3,3,176,1,25,25,251,1,45,45,255,1,62,62, + 255,1,76,76,255,1,88,88,255,1,96,96,255,1,100,100,255,2,95,95, + 255,1,84,84,251,1,30,30,174,1,6,6,88,1,0,0,0,3,208,208, + 208,26,248,252,248,3,0,0,0,3,248,252,248,12,0,0,0,3,248,252, + 248,3,208,208,208,30,255,43,0,1,9,0,0,1,4,0,0,1,0,0, + 0,2,208,208,208,4,0,0,0,4,208,208,208,9,0,0,0,2,0,0, + 44,1,1,1,143,1,14,14,210,1,36,36,245,1,52,52,255,1,62,62, + 255,1,69,69,255,1,72,72,255,1,66,66,245,1,44,44,211,1,13,13, + 139,1,0,0,21,1,0,0,0,4,208,208,208,26,248,252,248,2,0,0, + 0,3,248,252,248,14,0,0,0,3,248,252,248,2,208,208,208,53,0,0, + 0,3,0,0,54,1,1,1,105,1,6,6,137,1,11,11,161,1,13,13, + 160,1,10,10,137,1,5,5,101,1,0,0,43,1,0,0,0,5,208,208, + 208,27,248,252,248,2,0,0,0,2,248,252,248,16,0,0,0,2,248,252, + 248,2,208,208,208,55,0,0,0,12,208,208,208,29,248,252,248,24,208,208, + 208,56,0,0,0,10,208,208,208,30,248,252,248,24,208,208,208,24,192,192, + 192,48,208,208,208,6,0,0,188,3,208,208,208,26,0,0,0,1,208,208, + 208,2,0,0,0,1,208,208,208,33,192,192,192,48,208,208,208,6,0,0, + 188,1,26,26,213,1,0,0,188,2,208,208,208,25,0,0,0,5,208,208, + 208,32,192,192,192,48,208,208,208,6,0,0,188,1,73,73,234,1,54,54, + 226,1,0,0,188,2,208,208,208,26,0,0,0,2,208,208,208,33,192,192, + 192,48,208,208,208,6,0,0,188,1,107,107,238,1,125,125,251,1,69,69, + 226,1,0,0,188,2,208,208,208,1,0,0,0,1,208,208,208,2,0,0, + 0,1,208,208,208,55,192,192,192,48,208,208,208,6,0,0,188,1,134,134, + 238,1,169,169,255,1,149,149,251,1,84,84,226,1,0,0,188,2,0,0, + 0,5,208,208,208,54,192,192,192,48,208,208,208,3,6,6,207,1,26,26, + 215,1,38,38,220,1,24,24,210,1,136,136,234,1,189,189,252,1,195,195, + 255,1,173,173,251,1,98,98,226,1,0,0,188,2,208,208,208,1,0,0, + 0,9,208,208,208,3,0,0,170,1,23,23,215,1,35,35,220,1,43,43, + 223,1,48,48,225,1,48,48,224,4,34,34,219,1,0,0,182,1,208,208, + 208,34,192,192,192,48,208,208,208,2,20,20,213,1,47,47,225,1,108,108, + 253,1,111,111,255,1,62,62,228,1,112,112,227,1,158,158,242,1,167,167, + 245,1,175,175,248,1,161,161,242,1,72,72,212,1,0,0,188,1,208,208, + 208,3,0,0,0,7,208,208,208,2,0,0,206,1,31,31,219,1,95,95, + 248,1,111,111,255,7,83,83,242,1,0,0,78,1,0,0,0,1,208,208, + 208,33,192,192,192,11,0,0,248,2,192,192,192,23,0,0,248,1,192,192, + 192,11,208,208,208,1,5,5,206,1,54,54,229,1,111,111,255,2,96,96, + 247,1,30,30,207,1,88,88,219,1,127,127,232,1,136,136,235,1,135,135, + 235,1,86,86,217,1,0,0,111,1,0,0,20,1,208,208,208,3,0,0, + 0,7,208,208,208,1,0,0,170,1,33,33,219,1,108,108,254,1,111,111, + 255,1,99,99,250,1,69,69,229,1,53,53,215,1,52,52,215,1,50,50, + 213,1,48,48,212,1,46,46,211,1,33,33,208,1,0,0,77,1,0,0, + 0,1,208,208,208,1,0,0,0,3,208,208,208,2,0,0,0,1,208,208, + 208,11,255,4,31,1,255,15,39,1,255,14,39,1,255,3,29,1,255,0, + 26,2,208,208,208,9,192,192,192,11,0,0,248,2,192,192,192,23,0,0, + 248,1,192,192,192,11,208,208,208,1,27,27,216,1,108,108,254,1,111,111, + 255,1,39,39,202,1,12,12,131,1,0,0,87,1,65,65,212,1,96,96, + 222,1,97,97,223,1,63,63,210,1,0,0,111,1,0,0,20,1,208,208, + 208,4,0,0,0,7,208,208,208,1,20,20,214,1,92,92,247,1,111,111, + 255,1,60,60,219,1,14,14,150,1,0,0,55,1,0,0,19,2,0,0, + 13,1,0,0,10,1,0,0,6,1,0,0,2,1,0,0,0,2,208,208, + 208,1,0,0,0,7,208,208,208,9,255,15,38,1,255,42,63,1,255,57, + 77,2,255,42,63,1,255,15,39,1,254,0,26,1,223,0,22,1,208,208, + 208,8,192,192,192,11,0,0,248,2,192,192,192,23,0,0,248,1,192,192, + 192,11,208,208,208,1,43,43,222,1,111,111,255,1,96,96,247,1,12,12, + 132,1,0,0,0,1,0,0,121,1,42,42,204,1,61,61,210,1,41,41, + 203,1,0,0,111,1,0,0,20,1,208,208,208,1,0,0,0,4,208,208, + 208,8,36,36,221,1,111,111,255,1,108,108,254,1,19,19,168,1,0,0, + 0,1,0,0,47,1,0,0,166,1,0,0,181,1,0,0,0,5,208,208, + 208,4,0,0,0,1,208,208,208,3,0,0,0,1,208,208,208,8,255,4, + 31,1,255,43,63,1,255,76,94,1,255,98,114,2,255,76,94,1,255,43, + 64,1,255,4,30,1,254,0,26,1,136,0,14,1,208,208,208,7,192,192, + 192,11,0,0,248,2,192,192,192,23,0,0,248,1,192,192,192,11,0,0, + 204,1,51,51,226,1,111,111,255,1,58,58,220,1,0,0,42,1,0,0, + 0,1,0,0,176,1,17,17,196,1,19,19,196,1,0,0,111,1,0,0, + 20,1,208,208,208,2,0,0,0,4,208,208,208,8,44,44,224,1,111,111, + 255,1,79,79,237,1,4,4,92,1,0,0,0,1,0,0,187,1,26,26, + 213,1,0,0,189,1,0,0,191,1,208,208,208,21,255,17,42,1,255,61, + 81,1,255,103,118,1,255,159,169,2,255,103,118,1,255,61,81,1,255,18, + 42,1,255,0,26,1,204,0,21,1,0,0,0,1,208,208,208,6,192,192, + 192,11,0,0,248,2,192,192,192,23,0,0,248,1,192,192,192,11,208,208, + 208,1,45,45,223,1,111,111,255,1,96,96,247,1,12,12,134,1,0,0, + 0,1,0,0,186,1,0,0,189,1,0,0,111,1,0,0,20,1,0,0, + 0,1,208,208,208,14,43,43,223,1,111,111,255,1,79,79,237,1,4,4, + 92,1,0,0,0,1,0,0,187,1,73,73,234,1,54,54,226,1,0,0, + 181,1,0,0,191,1,208,208,208,20,255,21,45,1,255,66,85,1,255,110, + 124,1,255,187,195,2,255,110,124,1,255,66,85,1,255,21,45,1,255,0, + 26,1,240,0,24,1,0,0,0,1,208,208,208,6,192,192,192,11,0,0, + 248,2,192,192,192,23,0,0,248,1,192,192,192,11,208,208,208,1,29,29, + 214,1,108,108,254,1,111,111,255,1,35,35,199,1,3,3,115,1,0,0, + 139,1,0,0,186,1,0,0,20,1,208,208,208,16,33,33,219,1,111,111, + 255,1,108,108,254,1,19,19,168,1,0,0,0,1,0,0,187,1,107,107, + 238,1,125,125,251,1,69,69,226,1,0,0,181,1,0,0,191,1,208,208, + 208,19,255,13,38,1,255,55,75,1,255,93,109,1,255,130,142,2,255,93, + 109,1,255,55,75,1,255,13,38,1,255,0,26,1,240,0,24,1,0,0, + 0,1,208,208,208,6,192,192,192,11,0,0,248,2,192,192,192,23,0,0, + 248,1,192,192,192,11,208,208,208,1,5,5,176,1,53,53,221,1,111,111, + 255,1,109,109,254,1,68,68,230,1,47,47,220,1,46,46,223,9,41,41, + 221,1,32,32,215,1,21,21,207,1,0,0,51,1,0,0,0,1,208,208, + 208,4,18,18,211,1,77,77,236,1,111,111,255,1,60,60,219,1,16,16, + 176,1,0,0,190,1,134,134,238,1,169,169,255,1,149,149,251,1,84,84, + 226,1,0,0,181,1,0,0,191,1,208,208,208,18,255,0,26,1,255,32, + 54,1,255,62,81,1,255,81,98,2,255,62,81,1,255,32,54,1,255,0, + 26,2,204,0,21,1,0,0,0,1,208,208,208,6,192,192,192,36,0,0, + 248,1,192,192,192,11,208,208,208,1,0,0,0,1,17,17,179,1,45,45, + 211,1,108,108,254,1,111,111,255,13,92,92,245,1,22,22,191,1,0,0, + 0,2,208,208,208,4,24,24,200,1,102,102,251,1,111,111,255,1,99,99, + 250,1,51,51,220,1,136,136,234,1,189,189,252,1,195,195,255,1,173,173, + 251,1,98,98,226,1,0,0,181,1,0,0,191,1,208,208,208,2,0,0, + 0,8,208,208,208,7,255,0,26,1,254,1,27,1,255,25,49,1,255,39, + 61,2,255,25,49,1,255,1,27,1,255,0,26,1,254,0,26,1,89,0, + 9,1,0,0,0,1,208,208,208,6,192,192,192,48,208,208,208,2,0,0, + 0,1,2,2,86,1,22,22,176,1,33,33,192,1,42,42,208,1,44,44, + 210,9,66,66,227,1,104,104,252,1,111,111,255,1,79,79,235,1,10,10, + 131,1,0,0,0,2,208,208,208,3,0,0,183,1,21,21,185,1,89,89, + 242,1,111,111,255,1,83,83,238,1,112,112,227,1,158,158,242,1,167,167, + 245,1,175,175,248,1,161,161,243,1,72,72,212,1,0,0,169,1,208,208, + 208,2,0,0,0,8,208,208,208,8,223,0,22,1,254,0,26,1,255,0, + 26,4,254,0,26,1,158,0,16,1,0,0,0,2,208,208,208,6,192,192, + 192,11,0,0,248,2,192,192,192,23,0,0,248,1,192,192,192,11,208,208, + 208,3,0,0,0,13,1,1,54,1,19,19,177,1,96,96,247,1,111,111, + 255,1,26,26,181,1,0,0,0,2,208,208,208,4,0,0,14,1,14,14, + 147,1,28,28,183,1,29,29,200,1,88,88,219,1,127,127,232,1,136,136, + 235,1,135,135,235,1,86,86,218,1,0,0,111,1,0,0,22,1,208,208, + 208,19,136,0,14,1,204,0,21,1,240,0,24,2,204,0,21,1,89,0, + 9,1,0,0,0,2,208,208,208,7,192,192,192,11,0,0,248,2,192,192, + 192,35,208,208,208,3,0,0,0,14,0,0,92,1,57,57,224,1,111,111, + 255,1,37,37,200,1,0,0,0,2,208,208,208,5,0,0,0,2,0,0, + 90,1,65,65,212,1,96,96,222,1,97,97,223,1,63,63,211,1,0,0, + 111,1,0,0,22,1,208,208,208,21,0,0,0,6,208,208,208,8,192,192, + 192,48,208,208,208,5,0,0,0,9,208,208,208,3,0,0,165,1,54,54, + 225,1,111,111,255,1,47,47,212,1,0,0,10,1,0,0,0,1,208,208, + 208,7,0,0,185,1,42,42,204,1,61,61,211,1,41,41,204,1,0,0, + 111,1,0,0,22,1,208,208,208,36,192,192,192,48,208,208,208,7,0,0, + 0,7,208,208,208,3,0,0,204,1,49,49,225,1,111,111,255,1,47,47, + 211,1,0,0,6,1,0,0,0,1,208,208,208,7,0,0,187,1,17,17, + 196,1,19,19,196,1,0,0,111,1,0,0,22,1,208,208,208,37,192,192, + 192,48,208,208,208,7,0,0,0,11,34,34,218,1,83,83,242,1,33,33, + 209,1,0,0,2,1,0,0,0,1,208,208,208,7,0,0,187,1,0,0, + 190,1,0,0,111,1,0,0,22,1,208,208,208,38,192,192,192,48,208,208, + 208,5,0,0,0,9,208,208,208,1,0,0,0,3,0,0,179,1,0,0, + 87,1,0,0,82,1,0,0,0,2,208,208,208,7,0,0,191,1,0,0, + 185,1,0,0,21,1,208,208,208,2,0,0,0,4,208,208,208,33,192,192, + 192,48,208,208,208,3,0,0,0,4,208,208,208,11,0,0,0,5,208,208, + 208,12,0,0,0,4,208,208,208,33,192,192,192,48,208,208,208,6,0,0, + 0,1,208,208,208,172,0,0,0,1,208,208,208,2,0,0,0,1,208,208, + 208,87,159,159,159,1,160,160,160,1,208,208,208,27,0,0,0,5,208,208, + 208,15,191,191,191,1,161,161,161,1,159,159,159,1,160,160,160,4,159,159, + 159,1,161,161,161,1,191,191,191,1,208,208,208,61,159,159,159,1,160,160, + 160,1,163,163,163,1,208,208,208,28,0,0,0,2,208,208,208,15,162,162, + 162,1,160,160,160,9,166,166,166,1,168,168,168,1,208,208,208,37,159,159, + 159,1,208,208,208,22,159,159,159,1,160,160,160,2,163,163,163,1,208,208, + 208,3,0,0,0,1,208,208,208,2,0,0,0,1,208,208,208,35,255,255, + 255,1,161,161,161,1,160,160,160,11,162,162,162,1,177,177,177,1,255,255, + 255,1,208,208,208,10,160,160,160,4,208,208,208,4,160,160,160,4,208,208, + 208,13,160,160,160,1,191,191,191,1,208,208,208,21,159,159,159,1,160,160, + 160,3,163,163,163,1,208,208,208,2,0,0,0,5,208,208,208,34,161,161, + 161,1,160,160,160,14,194,194,194,1,255,255,255,1,208,208,208,9,160,160, + 160,4,255,255,255,1,208,208,208,3,160,160,160,4,255,255,255,1,208,208, + 208,12,160,160,160,1,162,162,162,1,187,187,187,1,208,208,208,17,160,160, + 160,8,163,163,163,1,208,208,208,3,0,0,0,9,208,208,208,3,146,146, + 146,1,159,159,159,1,160,160,160,8,255,255,255,1,208,208,208,13,162,162, + 162,1,160,160,160,2,159,159,159,1,149,149,149,1,158,158,158,1,160,160, + 160,6,157,157,157,1,148,148,148,1,159,159,159,1,160,160,160,1,163,163, + 163,1,227,227,227,1,208,208,208,9,160,160,160,4,255,255,255,1,208,208, + 208,3,160,160,160,4,255,255,255,1,208,208,208,12,160,160,160,3,184,184, + 184,1,255,255,255,1,208,208,208,14,160,160,160,10,163,163,163,1,208,208, + 208,4,0,0,0,7,208,208,208,2,159,159,159,1,160,160,160,10,255,255, + 255,1,208,208,208,12,191,191,191,1,160,160,160,3,146,146,146,1,128,128, + 128,1,141,141,141,1,165,165,165,1,160,160,160,4,157,157,157,1,133,133, + 133,1,128,128,128,1,172,172,172,1,165,165,165,1,160,160,160,1,178,178, + 178,1,249,249,249,1,208,208,208,8,160,160,160,4,255,255,255,1,208,208, + 208,3,160,160,160,4,255,255,255,1,208,208,208,12,160,160,160,4,179,179, + 179,2,208,208,208,12,160,160,160,10,163,163,163,1,255,255,255,2,208,208, + 208,3,0,0,0,7,208,208,208,1,153,153,153,1,160,160,160,11,255,255, + 255,1,208,208,208,2,0,0,0,3,208,208,208,2,0,0,0,1,208,208, + 208,4,161,161,161,1,160,160,160,3,157,157,157,1,138,138,138,1,128,128, + 128,1,148,148,148,1,165,165,165,1,160,160,160,2,157,157,157,1,133,133, + 133,1,128,128,128,1,146,146,146,1,245,245,245,1,199,199,199,1,160,160, + 160,2,222,222,222,1,255,255,255,1,208,208,208,7,160,160,160,4,255,255, + 255,1,208,208,208,3,160,160,160,4,255,255,255,1,208,208,208,12,160,160, + 160,5,174,174,174,1,183,183,183,1,208,208,208,11,160,160,160,3,172,172, + 172,1,229,229,229,1,248,248,248,1,160,160,160,3,163,163,163,1,255,255, + 255,2,208,208,208,4,0,0,0,7,208,208,208,1,160,160,160,3,163,163, + 163,1,213,213,213,1,243,243,243,1,255,255,255,7,208,208,208,2,0,0, + 0,7,208,208,208,3,161,161,161,1,160,160,160,4,163,163,163,1,144,144, + 144,1,128,128,128,1,147,147,147,1,166,166,166,1,157,157,157,1,133,133, + 133,1,128,128,128,1,146,146,146,1,243,243,243,1,240,240,240,1,168,168, + 168,1,160,160,160,2,208,208,208,1,255,255,255,1,208,208,208,7,160,160, + 160,4,255,255,255,1,208,208,208,3,160,160,160,4,255,255,255,1,208,208, + 208,12,160,160,160,6,169,169,169,1,188,188,188,1,208,208,208,10,160,160, + 160,3,229,229,229,1,255,255,255,1,245,245,245,1,160,160,160,2,163,163, + 163,1,255,255,255,2,208,208,208,1,0,0,0,4,208,208,208,8,160,160, + 160,3,212,212,212,1,255,255,255,3,208,208,208,10,0,0,0,1,208,208, + 208,3,0,0,0,1,208,208,208,3,160,160,160,6,164,164,164,1,144,144, + 144,1,128,128,128,1,146,146,146,1,134,134,134,1,128,128,128,1,146,146, + 146,1,243,243,243,1,240,240,240,1,169,169,169,1,160,160,160,3,188,188, + 188,1,255,255,255,1,208,208,208,7,160,160,160,4,255,255,255,1,208,208, + 208,3,160,160,160,4,255,255,255,1,208,208,208,12,160,160,160,7,164,164, + 164,1,189,189,189,1,208,208,208,8,160,160,160,4,251,251,251,1,255,255, + 255,1,159,159,159,1,160,160,160,1,161,161,161,1,255,255,255,2,208,208, + 208,2,0,0,0,4,208,208,208,8,160,160,160,3,243,243,243,1,255,255, + 255,1,208,208,208,1,160,160,160,1,208,208,208,18,160,160,160,7,163,163, + 163,1,143,143,143,1,128,128,128,2,145,145,145,1,243,243,243,1,240,240, + 240,1,169,169,169,1,160,160,160,4,169,169,169,1,255,255,255,1,208,208, + 208,7,160,160,160,4,255,255,255,1,208,208,208,3,160,160,160,4,255,255, + 255,1,208,208,208,12,160,160,160,8,161,161,161,1,187,187,187,1,208,208, + 208,8,160,160,160,3,234,234,234,1,255,255,255,1,159,159,159,1,160,160, + 160,1,255,255,255,2,208,208,208,15,160,160,160,3,243,243,243,1,255,255, + 255,1,208,208,208,1,160,160,160,2,255,255,255,1,208,208,208,16,160,160, + 160,7,157,157,157,1,134,134,134,1,128,128,128,2,146,146,146,1,231,231, + 231,1,169,169,169,1,160,160,160,5,169,169,169,1,255,255,255,1,208,208, + 208,7,160,160,160,4,255,255,255,1,208,208,208,3,160,160,160,4,255,255, + 255,1,208,208,208,12,160,160,160,8,161,161,161,1,215,215,215,1,255,255, + 255,1,208,208,208,7,160,160,160,3,175,175,175,1,198,198,198,1,160,160, + 160,1,255,255,255,2,208,208,208,16,160,160,160,3,210,210,210,1,255,255, + 255,1,208,208,208,1,160,160,160,3,255,255,255,1,208,208,208,15,160,160, + 160,6,157,157,157,1,133,133,133,1,128,128,128,1,144,144,144,1,148,148, + 148,1,128,128,128,1,145,145,145,1,167,167,167,1,160,160,160,5,188,188, + 188,1,255,255,255,1,208,208,208,7,160,160,160,4,255,255,255,1,208,208, + 208,3,160,160,160,4,255,255,255,1,208,208,208,12,160,160,160,7,165,165, + 165,1,228,228,228,1,255,255,255,2,208,208,208,7,160,160,160,1,161,161, + 161,1,160,160,160,17,208,208,208,5,160,160,160,3,163,163,163,1,197,197, + 197,1,156,156,156,1,160,160,160,4,255,255,255,1,208,208,208,14,161,161, + 161,1,160,160,160,4,157,157,157,1,133,133,133,1,128,128,128,1,146,146, + 146,1,243,243,243,1,232,232,232,1,147,147,147,1,128,128,128,1,145,145, + 145,1,167,167,167,1,160,160,160,4,208,208,208,1,255,255,255,1,208,208, + 208,7,160,160,160,4,255,255,255,1,208,208,208,3,160,160,160,4,255,255, + 255,1,208,208,208,12,160,160,160,6,171,171,171,1,238,238,238,1,255,255, + 255,2,208,208,208,9,178,178,178,1,163,163,163,1,160,160,160,15,179,179, + 179,1,236,236,236,1,208,208,208,4,170,170,170,1,168,168,168,1,160,160, + 160,9,255,255,255,1,208,208,208,3,0,0,0,8,208,208,208,2,161,161, + 161,1,160,160,160,3,157,157,157,1,133,133,133,1,128,128,128,1,146,146, + 146,1,243,243,243,1,240,240,240,1,169,169,169,1,163,163,163,1,147,147, + 147,1,128,128,128,1,144,144,144,1,169,169,169,1,160,160,160,3,227,227, + 227,1,255,255,255,1,208,208,208,7,160,160,160,4,255,255,255,1,208,208, + 208,3,160,160,160,4,255,255,255,1,208,208,208,12,160,160,160,5,180,180, + 180,1,246,246,246,1,255,255,255,2,208,208,208,11,223,223,223,1,194,194, + 194,1,176,176,176,1,161,161,161,1,160,160,160,13,204,204,204,1,255,255, + 255,1,208,208,208,4,161,161,161,1,175,175,175,1,160,160,160,9,255,255, + 255,1,208,208,208,2,0,0,0,8,208,208,208,2,191,191,191,1,166,166, + 166,1,160,160,160,2,148,148,148,1,128,128,128,1,146,146,146,1,243,243, + 243,1,240,240,240,1,169,169,169,1,160,160,160,2,163,163,163,1,148,148, + 148,1,128,128,128,1,196,196,196,1,172,172,172,1,160,160,160,1,179,179, + 179,1,254,254,254,1,255,255,255,1,208,208,208,7,160,160,160,4,255,255, + 255,1,208,208,208,3,160,160,160,4,255,255,255,1,208,208,208,12,160,160, + 160,4,191,191,191,1,252,252,252,1,255,255,255,2,208,208,208,12,0,0, + 0,1,255,255,255,2,241,241,241,1,255,255,255,9,244,244,244,1,197,197, + 197,1,160,160,160,2,192,192,192,1,255,255,255,1,208,208,208,5,240,240, + 240,1,202,202,202,1,185,185,185,1,167,167,167,1,160,160,160,5,255,255, + 255,2,208,208,208,13,168,168,168,1,162,162,162,1,160,160,160,1,159,159, + 159,1,169,169,169,1,244,244,244,1,240,240,240,1,169,169,169,1,160,160, + 160,4,163,163,163,1,196,196,196,1,251,251,251,1,202,202,202,1,163,163, + 163,1,240,240,240,1,255,255,255,2,208,208,208,7,160,160,160,4,255,255, + 255,1,208,208,208,3,160,160,160,4,255,255,255,1,208,208,208,12,160,160, + 160,3,205,205,205,1,255,255,255,3,208,208,208,13,0,0,0,5,208,208, + 208,9,191,191,191,1,160,160,160,2,174,174,174,1,255,255,255,1,208,208, + 208,6,255,255,255,3,160,160,160,4,255,255,255,2,208,208,208,15,177,177, + 177,1,160,160,160,2,162,162,162,1,194,194,194,1,168,168,168,1,160,160, + 160,6,164,164,164,1,191,191,191,1,163,163,163,1,213,213,213,1,255,255, + 255,2,208,208,208,8,160,160,160,4,255,255,255,1,208,208,208,3,160,160, + 160,4,255,255,255,1,208,208,208,12,160,160,160,1,162,162,162,1,219,219, + 219,1,255,255,255,3,208,208,208,16,0,0,0,9,208,208,208,3,160,160, + 160,3,165,165,165,1,255,255,255,1,208,208,208,9,160,160,160,3,255,255, + 255,2,208,208,208,16,255,255,255,1,194,194,194,1,163,163,163,1,160,160, + 160,10,163,163,163,1,213,213,213,1,255,255,255,2,208,208,208,9,160,160, + 160,4,255,255,255,1,208,208,208,3,160,160,160,4,255,255,255,1,208,208, + 208,12,160,160,160,1,232,232,232,1,255,255,255,2,208,208,208,20,0,0, + 0,7,208,208,208,3,160,160,160,3,163,163,163,1,255,255,255,1,208,208, + 208,9,160,160,160,2,255,255,255,2,208,208,208,18,255,255,255,1,227,227, + 227,1,178,178,178,1,160,160,160,8,179,179,179,1,240,240,240,1,255,255, + 255,3,208,208,208,10,255,255,255,4,208,208,208,4,255,255,255,4,208,208, + 208,12,159,159,159,1,255,255,255,2,208,208,208,21,0,0,0,10,29,29, + 29,1,160,160,160,2,163,163,163,1,255,255,255,1,208,208,208,9,160,160, + 160,1,252,252,252,1,255,255,255,1,208,208,208,21,249,249,249,1,222,222, + 222,1,207,207,207,1,188,188,188,1,169,169,169,2,188,188,188,1,207,207, + 207,1,227,227,227,1,254,254,254,1,255,255,255,2,208,208,208,37,255,255, + 255,1,208,208,208,20,0,0,0,9,208,208,208,1,0,0,0,3,195,195, + 195,1,255,255,255,3,208,208,208,9,255,255,255,2,208,208,208,2,0,0, + 0,4,208,208,208,17,255,255,255,10,208,208,208,57,0,0,0,4,208,208, + 208,12,255,255,255,1,208,208,208,15,0,0,0,4,208,208,208,87,0,0, + 0,1,208,208,208,43,0,0,0,1,208,208,208,2,0,0,0,1,208,208, + 208,53,0,0,0,1,208,208,208,2,0,0,0,1,208,208,208,11,0,0, + 0,1,208,208,208,2,0,0,0,1,208,208,208,44,0,0,0,5,208,208, + 208,23,159,159,159,1,160,160,160,1,208,208,208,27,0,0,0,5,208,208, + 208,10,0,0,0,5,208,208,208,45,0,0,0,9,208,208,208,5,160,160, + 160,1,208,208,208,11,159,159,159,1,160,160,160,1,163,163,163,1,208,208, + 208,28,0,0,0,2,208,208,208,13,0,0,0,9,208,208,208,5,0,0, + 205,1,0,0,203,2,208,208,208,33,0,0,0,7,208,208,208,4,160,160, + 160,4,208,208,208,9,159,159,159,1,160,160,160,2,163,163,163,1,208,208, + 208,3,0,0,0,1,208,208,208,2,0,0,0,1,208,208,208,37,0,0, + 0,7,208,208,208,5,34,34,219,1,83,83,242,1,35,35,219,1,0,0, + 21,1,0,0,0,1,208,208,208,31,0,0,0,11,160,160,160,3,163,163, + 163,1,255,255,255,1,208,208,208,8,159,159,159,1,160,160,160,3,163,163, + 163,1,208,208,208,2,0,0,0,5,208,208,208,36,0,0,0,11,0,0, + 191,1,48,48,225,1,111,111,255,1,47,47,212,1,0,0,4,1,0,0, + 0,1,208,208,208,31,0,0,0,11,160,160,160,3,165,165,165,1,255,255, + 255,1,208,208,208,5,160,160,160,8,163,163,163,1,208,208,208,3,0,0, + 0,9,208,208,208,3,146,146,146,1,159,159,159,1,160,160,160,8,255,255, + 255,1,208,208,208,16,0,0,0,11,0,0,213,1,55,55,228,1,111,111, + 255,1,48,48,212,1,0,0,10,1,0,0,0,1,208,208,208,27,0,0, + 0,4,208,208,208,11,160,160,160,3,174,174,174,1,255,255,255,1,208,208, + 208,4,160,160,160,10,163,163,163,1,208,208,208,4,0,0,0,7,208,208, + 208,2,159,159,159,1,160,160,160,10,255,255,255,1,208,208,208,12,0,0, + 0,4,208,208,208,11,0,0,198,1,58,58,229,1,111,111,255,1,41,41, + 204,1,0,0,2,1,0,0,0,1,208,208,208,27,0,0,0,4,208,208, + 208,10,160,160,160,4,192,192,192,1,255,255,255,1,208,208,208,3,160,160, + 160,10,163,163,163,1,255,255,255,2,208,208,208,3,0,0,0,7,208,208, + 208,1,153,153,153,1,160,160,160,11,255,255,255,1,208,208,208,2,0,0, + 0,3,208,208,208,2,0,0,0,1,208,208,208,4,0,0,0,4,208,208, + 208,10,0,0,208,1,25,25,213,1,97,97,248,1,111,111,255,1,32,32, + 187,1,0,0,0,2,208,208,208,10,0,0,159,1,0,0,175,1,0,0, + 186,2,0,0,174,1,0,0,156,1,208,208,208,12,160,160,160,17,214,214, + 214,1,255,255,255,1,208,208,208,3,160,160,160,3,172,172,172,1,229,229, + 229,1,248,248,248,1,160,160,160,3,163,163,163,1,255,255,255,2,208,208, + 208,4,0,0,0,7,208,208,208,1,160,160,160,3,163,163,163,1,213,213, + 213,1,243,243,243,1,255,255,255,7,208,208,208,2,0,0,0,7,208,208, + 208,4,15,15,209,1,29,29,217,1,40,40,221,1,47,47,224,1,48,48, + 224,9,69,69,235,1,103,103,251,1,111,111,255,1,101,101,250,1,17,17, + 159,1,0,0,0,2,208,208,208,9,0,0,171,1,0,0,203,1,0,0, + 254,1,0,0,255,2,0,0,254,1,0,0,196,1,0,0,145,1,208,208, + 208,10,160,160,160,17,191,191,191,1,254,254,254,1,255,255,255,1,208,208, + 208,3,160,160,160,3,229,229,229,1,255,255,255,1,245,245,245,1,160,160, + 160,2,163,163,163,1,255,255,255,2,208,208,208,1,0,0,0,4,208,208, + 208,8,160,160,160,3,212,212,212,1,255,255,255,3,208,208,208,10,0,0, + 0,1,208,208,208,3,0,0,0,1,208,208,208,3,23,23,214,1,60,60, + 231,1,111,111,255,14,99,99,248,1,27,27,191,1,0,0,17,1,0,0, + 0,2,208,208,208,8,0,0,159,1,0,0,203,1,0,0,255,6,0,0, + 190,1,0,0,62,1,208,208,208,8,160,160,160,15,167,167,167,1,184,184, + 184,1,204,204,204,1,252,252,252,1,255,255,255,2,208,208,208,2,160,160, + 160,4,251,251,251,1,255,255,255,1,159,159,159,1,160,160,160,1,161,161, + 161,1,255,255,255,2,208,208,208,2,0,0,0,4,208,208,208,8,160,160, + 160,3,243,243,243,1,255,255,255,1,208,208,208,1,160,160,160,1,208,208, + 208,17,12,12,206,1,62,62,231,1,111,111,255,2,79,79,237,1,49,49, + 213,1,44,44,211,1,47,47,211,1,48,48,212,2,48,48,213,1,51,51, + 214,1,51,51,215,1,52,52,215,1,53,53,216,1,43,43,205,1,30,30, + 184,1,15,15,150,1,0,0,13,1,0,0,0,2,208,208,208,9,0,0, + 175,1,0,0,254,1,0,0,255,6,0,0,254,1,0,0,135,1,0,0, + 0,1,208,208,208,7,160,160,160,3,175,175,175,1,232,232,232,1,252,252, + 252,1,255,255,255,14,208,208,208,4,160,160,160,3,234,234,234,1,255,255, + 255,1,159,159,159,1,160,160,160,1,255,255,255,2,208,208,208,15,160,160, + 160,3,243,243,243,1,255,255,255,1,208,208,208,1,160,160,160,2,255,255, + 255,1,208,208,208,15,29,29,216,1,109,109,254,1,111,111,255,1,31,31, + 196,1,3,3,84,1,0,0,33,1,0,0,82,1,0,0,27,1,0,0, + 6,1,0,0,10,1,0,0,12,1,0,0,15,1,0,0,17,1,0,0, + 19,1,0,0,23,1,0,0,2,1,0,0,0,5,208,208,208,9,0,0, + 186,1,0,0,255,8,0,0,160,1,0,0,0,1,208,208,208,7,160,160, + 160,3,234,234,234,1,255,255,255,1,244,244,244,1,160,160,160,1,208,208, + 208,17,160,160,160,3,175,175,175,1,198,198,198,1,160,160,160,1,255,255, + 255,2,208,208,208,16,160,160,160,3,210,210,210,1,255,255,255,1,208,208, + 208,1,160,160,160,3,255,255,255,1,208,208,208,14,38,38,219,1,111,111, + 255,1,91,91,245,1,7,7,112,1,0,0,0,1,0,0,134,1,26,26, + 223,1,0,0,192,1,0,0,120,1,0,0,0,11,208,208,208,10,0,0, + 186,1,0,0,255,8,0,0,159,1,0,0,0,1,208,208,208,6,160,160, + 160,4,251,251,251,1,255,255,255,1,159,159,159,1,160,160,160,1,161,161, + 161,1,208,208,208,16,160,160,160,1,161,161,161,1,160,160,160,17,208,208, + 208,5,160,160,160,3,163,163,163,1,197,197,197,1,156,156,156,1,160,160, + 160,4,255,255,255,1,208,208,208,13,43,43,221,1,111,111,255,1,63,63, + 226,1,0,0,51,1,0,0,0,1,0,0,191,1,73,73,239,1,54,54, + 233,1,0,0,204,2,208,208,208,20,0,0,174,1,0,0,254,1,0,0, + 255,6,0,0,254,1,0,0,135,1,0,0,0,1,208,208,208,7,160,160, + 160,3,229,229,229,1,255,255,255,1,159,159,159,1,160,160,160,2,163,163, + 163,1,208,208,208,2,0,0,0,6,208,208,208,8,178,178,178,1,163,163, + 163,1,160,160,160,15,179,179,179,1,236,236,236,1,208,208,208,4,170,170, + 170,1,168,168,168,1,160,160,160,9,255,255,255,1,208,208,208,3,0,0, + 0,8,208,208,208,1,37,37,218,1,111,111,255,1,101,101,251,1,17,17, + 152,1,0,0,0,1,0,0,202,1,107,107,242,1,125,125,252,1,69,69, + 233,1,0,0,204,2,0,0,0,6,208,208,208,13,0,0,156,1,0,0, + 196,1,0,0,255,6,0,0,190,1,0,0,36,1,0,0,0,1,208,208, + 208,7,160,160,160,3,172,172,172,1,200,200,200,1,160,160,160,4,163,163, + 163,1,208,208,208,1,0,0,0,6,208,208,208,9,223,223,223,1,194,194, + 194,1,176,176,176,1,161,161,161,1,160,160,160,13,204,204,204,1,255,255, + 255,1,208,208,208,4,161,161,161,1,175,175,175,1,160,160,160,9,255,255, + 255,1,208,208,208,2,0,0,0,8,208,208,208,1,26,26,212,1,107,107, + 253,1,111,111,255,1,50,50,212,1,12,12,163,1,0,0,191,1,134,134, + 242,1,169,169,255,1,149,149,252,1,84,84,233,1,0,0,204,1,0,0, + 79,1,0,0,0,5,208,208,208,14,0,0,145,1,0,0,190,1,0,0, + 254,1,0,0,255,2,0,0,254,1,0,0,190,1,0,0,92,1,0,0, + 0,2,208,208,208,7,160,160,160,1,163,163,163,1,160,160,160,8,163,163, + 163,1,208,208,208,4,0,0,0,7,208,208,208,4,0,0,0,1,255,255, + 255,2,241,241,241,1,255,255,255,9,244,244,244,1,197,197,197,1,160,160, + 160,2,192,192,192,1,255,255,255,1,208,208,208,5,240,240,240,1,202,202, + 202,1,185,185,185,1,167,167,167,1,160,160,160,5,255,255,255,2,208,208, + 208,11,0,0,164,1,49,49,219,1,111,111,255,2,87,87,243,1,29,29, + 214,1,136,136,238,1,189,189,252,1,195,195,255,1,173,173,252,1,98,98, + 233,1,0,0,204,2,208,208,208,2,0,0,0,7,208,208,208,10,0,0, + 62,1,0,0,135,1,0,0,160,1,0,0,159,1,0,0,135,1,0,0, + 36,1,0,0,0,2,208,208,208,9,179,179,179,1,165,165,165,1,160,160, + 160,8,163,163,163,1,208,208,208,3,0,0,0,7,208,208,208,4,0,0, + 0,5,208,208,208,9,191,191,191,1,160,160,160,2,174,174,174,1,255,255, + 255,1,208,208,208,6,255,255,255,3,160,160,160,4,255,255,255,2,208,208, + 208,12,0,0,0,1,16,16,178,1,46,46,211,1,109,109,254,1,111,111, + 255,1,62,62,232,1,112,112,231,1,158,158,242,1,167,167,245,1,175,175, + 248,1,161,161,244,1,72,72,222,1,0,0,204,1,208,208,208,2,0,0, + 0,7,208,208,208,11,0,0,0,6,208,208,208,11,224,224,224,1,195,195, + 195,1,176,176,176,1,161,161,161,1,160,160,160,4,163,163,163,1,255,255, + 255,2,208,208,208,2,0,0,0,8,208,208,208,5,0,0,0,9,208,208, + 208,3,160,160,160,3,165,165,165,1,255,255,255,1,208,208,208,9,160,160, + 160,3,255,255,255,2,208,208,208,14,0,0,0,1,3,3,93,1,23,23, + 176,1,37,37,195,1,26,26,208,1,88,88,223,1,127,127,232,1,136,136, + 235,1,135,135,236,1,86,86,224,1,0,0,120,1,0,0,23,1,208,208, + 208,2,0,0,0,8,208,208,208,28,255,255,255,2,251,251,251,1,160,160, + 160,3,163,163,163,1,255,255,255,1,252,252,252,1,0,0,0,4,208,208, + 208,1,0,0,0,2,208,208,208,11,0,0,0,7,208,208,208,3,160,160, + 160,3,163,163,163,1,255,255,255,1,208,208,208,9,160,160,160,2,255,255, + 255,2,208,208,208,16,0,0,0,3,0,0,94,1,65,65,216,1,96,96, + 222,1,97,97,224,1,63,63,217,1,0,0,120,1,0,0,23,1,0,0, + 0,4,208,208,208,1,0,0,0,2,208,208,208,34,159,159,159,1,160,160, + 160,2,163,163,163,1,255,255,255,2,0,0,0,5,208,208,208,14,0,0, + 0,10,29,29,29,1,160,160,160,2,163,163,163,1,255,255,255,1,208,208, + 208,9,160,160,160,1,252,252,252,1,255,255,255,1,208,208,208,18,0,0, + 0,2,0,0,183,1,42,42,208,1,61,61,211,1,41,41,210,1,0,0, + 120,1,0,0,23,1,0,0,0,5,208,208,208,37,159,159,159,1,160,160, + 160,1,163,163,163,1,255,255,255,2,208,208,208,18,0,0,0,9,208,208, + 208,1,0,0,0,3,195,195,195,1,255,255,255,3,208,208,208,9,255,255, + 255,2,208,208,208,2,0,0,0,4,208,208,208,15,0,0,204,1,17,17, + 201,1,19,19,203,1,0,0,120,1,0,0,23,1,208,208,208,43,159,159, + 159,1,160,160,160,1,255,255,255,2,208,208,208,17,0,0,0,4,208,208, + 208,12,255,255,255,1,208,208,208,15,0,0,0,4,208,208,208,15,0,0, + 204,1,0,0,200,1,0,0,120,1,0,0,23,1,208,208,208,45,255,255, + 255,2,208,208,208,21,0,0,0,1,208,208,208,47,0,0,204,1,0,0, + 195,1,0,0,23,1,208,208,208,39,84,58,0,0,0,0,0,30,16,16, + 16,1,64,64,64,1,16,16,16,1,0,0,0,26,12,12,12,1,0,0, + 0,2,12,12,12,1,0,0,0,11,12,12,12,1,0,0,0,2,12,12, + 12,1,0,0,0,72,64,64,64,1,255,255,255,1,112,112,112,1,16,16, + 16,1,0,0,0,25,70,70,70,1,105,105,105,1,100,100,100,1,104,104, + 104,1,112,112,112,1,0,0,0,10,70,70,70,1,105,105,105,1,100,100, + 100,1,104,104,104,1,112,112,112,1,0,0,0,71,64,64,64,1,255,255, + 255,2,112,112,112,1,16,16,16,1,0,0,0,26,19,19,19,1,23,23, + 23,1,0,0,0,13,19,19,19,1,23,23,23,2,26,26,26,1,59,59, + 59,1,11,11,11,1,23,23,23,1,40,40,40,1,17,17,17,1,0,0, + 0,5,61,61,61,1,64,64,64,2,0,0,0,40,255,255,255,2,0,0, + 0,15,64,64,64,1,255,255,255,3,112,112,112,1,16,16,16,1,0,0, + 0,1,12,12,12,1,0,0,0,2,12,12,12,1,0,0,0,37,65,65, + 65,1,77,77,77,1,73,73,73,1,26,26,26,1,53,53,53,1,71,71, + 71,1,36,36,36,1,0,0,0,5,230,230,230,1,255,255,255,1,233,233, + 233,1,12,12,12,1,1,1,1,1,0,0,0,7,59,59,59,1,123,123, + 123,1,1,1,1,1,0,0,0,28,255,255,255,2,0,0,0,15,64,64, + 64,1,255,255,255,4,112,112,112,1,16,16,16,1,96,96,96,1,114,114, + 114,1,98,98,98,1,100,100,100,1,84,84,84,1,0,0,0,36,38,38, + 38,1,47,47,47,1,53,53,53,1,71,71,71,1,54,54,54,1,48,48, + 48,1,30,30,30,1,42,42,42,1,31,31,31,1,77,77,77,1,40,40, + 40,1,4,4,4,1,227,227,227,1,255,255,255,1,240,240,240,1,116,116, + 116,1,11,11,11,1,0,0,0,7,64,64,64,1,246,246,246,1,186,186, + 186,1,6,6,6,1,0,0,0,19,255,255,255,10,0,0,0,12,32,32, + 32,1,172,172,172,1,200,200,200,1,236,236,236,1,255,255,255,5,112,112, + 112,1,16,16,16,1,0,0,0,1,33,33,33,1,10,10,10,1,26,26, + 26,1,40,40,40,1,44,44,44,1,18,18,18,1,16,16,16,1,50,50, + 50,1,8,8,8,1,0,0,0,3,3,3,3,1,133,133,133,1,184,184, + 184,1,211,211,211,1,224,224,224,1,225,225,225,4,233,233,233,1,71,71, + 71,1,0,0,0,16,47,47,47,1,76,76,76,1,87,87,87,1,57,57, + 57,1,61,61,61,1,46,46,46,1,35,35,35,1,36,36,36,1,24,24, + 24,1,61,61,61,1,22,22,22,1,12,12,12,1,229,229,229,1,255,255, + 255,1,241,241,241,1,128,128,128,1,12,12,12,1,0,0,0,7,64,64, + 64,1,255,255,255,1,252,252,252,1,211,211,211,1,20,20,20,1,0,0, + 0,21,255,255,255,6,0,0,0,12,91,91,91,1,222,222,222,1,255,255, + 255,9,64,64,64,1,0,0,0,3,80,80,80,1,89,89,89,1,45,45, + 45,1,42,42,42,1,36,36,36,1,82,82,82,1,27,27,27,1,0,0, + 0,2,26,26,26,1,196,196,196,1,253,253,253,1,255,255,255,8,167,167, + 167,1,1,1,1,1,0,0,0,11,45,45,45,1,70,70,70,1,74,74, + 74,1,80,80,80,1,0,0,0,11,22,22,22,1,232,232,232,1,255,255, + 255,1,237,237,237,1,122,122,122,1,11,11,11,1,0,0,0,7,64,64, + 64,1,255,255,255,3,226,226,226,1,44,44,44,1,1,1,1,1,0,0, + 0,15,255,255,255,10,0,0,0,11,37,37,37,1,227,227,227,1,255,255, + 255,3,248,248,248,1,255,255,255,5,191,191,191,1,147,147,147,1,0,0, + 0,3,43,43,43,1,47,47,47,1,56,56,56,1,77,77,77,1,51,51, + 51,1,55,55,55,1,31,31,31,1,0,0,0,1,3,3,3,1,204,204, + 204,1,255,255,255,3,249,249,249,1,243,243,243,1,242,242,242,2,241,241, + 241,2,245,245,245,1,168,168,168,1,1,1,1,1,0,0,0,1,12,12, + 12,1,4,4,4,1,17,17,17,1,0,0,0,2,25,25,25,1,0,0, + 0,4,17,17,17,1,29,29,29,1,31,31,31,1,42,42,42,1,0,0, + 0,10,38,38,38,1,184,184,184,1,252,252,252,1,255,255,255,1,226,226, + 226,1,110,110,110,1,10,10,10,1,0,0,0,7,64,64,64,1,255,255, + 255,4,235,235,235,1,80,80,80,1,1,1,1,1,0,0,0,18,255,255, + 255,7,0,0,0,10,183,183,183,1,255,255,255,2,235,235,235,1,192,192, + 192,1,170,170,170,1,255,255,255,4,191,191,191,1,147,147,147,1,0,0, + 0,4,53,53,53,1,78,78,78,1,90,90,90,1,62,62,62,1,65,65, + 65,1,56,56,56,1,28,28,28,1,0,0,0,1,125,125,125,1,251,251, + 251,1,255,255,255,1,243,243,243,1,204,204,204,1,158,158,158,1,145,145, + 145,1,137,137,137,1,135,135,135,1,134,134,134,1,133,133,133,1,131,131, + 131,1,130,130,130,1,1,1,1,1,0,0,0,1,86,86,86,1,99,99, + 99,1,96,96,96,1,43,43,43,1,70,70,70,1,98,98,98,1,34,34, + 34,1,0,0,0,4,66,66,66,1,184,184,184,1,206,206,206,1,223,223, + 223,1,225,225,225,9,239,239,239,1,255,255,255,3,207,207,207,1,89,89, + 89,1,8,8,8,1,0,0,0,7,64,64,64,1,255,255,255,5,241,241, + 241,1,124,124,124,1,1,1,1,1,0,0,0,14,255,255,255,11,0,0, + 0,9,211,211,211,1,255,255,255,2,192,192,192,1,112,112,112,1,99,99, + 99,1,255,255,255,3,191,191,191,1,147,147,147,1,0,0,0,1,68,68, + 68,1,73,73,73,1,78,78,78,1,57,57,57,1,0,0,0,8,189,189, + 189,1,255,255,255,2,216,216,216,1,132,132,132,1,66,66,66,1,72,72, + 72,1,17,17,17,1,1,1,1,5,0,0,0,4,1,1,1,1,0,0, + 0,3,8,8,8,1,0,0,0,3,131,131,131,1,233,233,233,1,255,255, + 255,15,231,231,231,1,135,135,135,1,61,61,61,1,5,5,5,1,0,0, + 0,7,64,64,64,1,255,255,255,6,246,246,246,1,163,163,163,1,2,2, + 2,1,0,0,0,17,255,255,255,5,0,0,0,1,255,255,255,2,0,0, + 0,7,6,6,6,1,225,225,225,1,255,255,255,1,244,244,244,1,146,146, + 146,1,49,49,49,1,68,68,68,1,255,255,255,2,191,191,191,1,147,147, + 147,1,0,0,0,2,30,30,30,1,23,23,23,1,34,34,34,1,32,32, + 32,1,0,0,0,8,209,209,209,1,255,255,255,1,252,252,252,1,174,174, + 174,1,59,59,59,1,64,64,64,1,255,255,255,1,112,112,112,1,16,16, + 16,1,0,0,0,15,42,42,42,1,232,232,232,1,255,255,255,2,252,252, + 252,1,242,242,242,1,241,241,241,4,242,242,242,4,243,243,243,1,237,237, + 237,1,225,225,225,1,203,203,203,1,135,135,135,1,88,88,88,1,13,13, + 13,1,0,0,0,8,64,64,64,1,255,255,255,7,250,250,250,1,196,196, + 196,1,9,9,9,1,0,0,0,12,255,255,255,2,0,0,0,2,255,255, + 255,6,0,0,0,1,255,255,255,1,0,0,0,8,210,210,210,1,255,255, + 255,2,187,187,187,1,24,24,24,1,65,65,65,1,255,255,255,1,191,191, + 191,1,147,147,147,1,2,2,2,1,0,0,0,14,208,208,208,1,255,255, + 255,1,252,252,252,1,174,174,174,1,17,17,17,1,64,64,64,1,255,255, + 255,2,117,117,117,1,16,16,16,1,0,0,0,14,176,176,176,1,255,255, + 255,2,234,234,234,1,170,170,170,1,142,142,142,1,161,161,161,1,137,137, + 137,1,130,130,130,1,131,131,131,1,132,132,132,1,133,133,133,2,134,134, + 134,1,135,135,135,1,128,128,128,1,119,119,119,1,98,98,98,1,71,71, + 71,1,16,16,16,1,1,1,1,1,0,0,0,8,64,64,64,1,255,255, + 255,8,254,254,254,1,217,217,217,1,26,26,26,1,0,0,0,10,255,255, + 255,11,0,0,0,10,181,181,181,1,255,255,255,2,233,233,233,1,87,87, + 87,1,22,22,22,1,65,65,65,1,147,147,147,1,0,0,0,16,185,185, + 185,1,255,255,255,2,215,215,215,1,20,20,20,1,64,64,64,1,255,255, + 255,3,117,117,117,1,16,16,16,1,0,0,0,13,199,199,199,1,255,255, + 255,2,183,183,183,1,108,108,108,1,98,98,98,1,255,255,255,1,119,119, + 119,1,27,27,27,1,12,12,12,7,11,11,11,1,9,9,9,1,6,6, + 6,1,1,1,1,1,0,0,0,9,64,64,64,1,255,255,255,8,254,254, + 254,1,226,226,226,1,105,105,105,1,1,1,1,1,0,0,0,9,255,255, + 255,7,0,0,0,1,255,255,255,3,0,0,0,10,41,41,41,1,235,235, + 235,1,255,255,255,2,247,247,247,1,228,228,228,1,222,222,222,2,221,221, + 221,7,210,210,210,1,189,189,189,1,140,140,140,1,8,8,8,1,1,1, + 1,1,0,0,0,4,97,97,97,1,248,248,248,1,255,255,255,1,243,243, + 243,1,174,174,174,1,97,97,97,1,255,255,255,4,117,117,117,1,16,16, + 16,1,0,0,0,12,210,210,210,1,255,255,255,1,247,247,247,1,149,149, + 149,1,43,43,43,1,68,68,68,1,255,255,255,2,112,112,112,1,16,16, + 16,1,0,0,0,19,64,64,64,1,255,255,255,7,250,250,250,1,214,214, + 214,1,106,106,106,1,12,12,12,1,0,0,0,13,255,255,255,3,0,0, + 0,2,255,255,255,3,0,0,0,10,1,1,1,1,109,109,109,1,237,237, + 237,1,255,255,255,14,252,252,252,1,198,198,198,1,18,18,18,1,2,2, + 2,1,0,0,0,4,199,199,199,1,255,255,255,3,248,248,248,1,255,255, + 255,5,117,117,117,1,16,16,16,1,0,0,0,2,16,16,16,1,19,19, + 19,2,46,46,46,1,18,18,18,1,19,19,19,1,13,13,13,1,22,22, + 22,1,0,0,0,1,200,200,200,1,255,255,255,2,198,198,198,1,21,21, + 21,1,65,65,65,1,255,255,255,3,112,112,112,1,16,16,16,1,40,40, + 40,1,46,46,46,2,63,63,63,1,53,53,53,1,2,2,2,1,0,0, + 0,12,64,64,64,1,255,255,255,6,246,246,246,1,199,199,199,1,86,86, + 86,1,5,5,5,1,0,0,0,19,255,255,255,3,0,0,0,11,5,5, + 5,1,77,77,77,1,210,210,210,1,228,228,228,1,239,239,239,1,241,241, + 241,9,248,248,248,1,255,255,255,2,250,250,250,1,152,152,152,1,14,14, + 14,1,1,1,1,1,0,0,0,3,14,14,14,1,214,214,214,1,252,252, + 252,1,255,255,255,8,71,71,71,1,0,0,0,2,76,76,76,1,108,108, + 108,1,118,118,118,1,88,88,88,1,93,93,93,1,79,79,79,1,45,45, + 45,1,49,49,49,1,0,0,0,1,173,173,173,1,255,255,255,2,239,239, + 239,1,127,127,127,1,74,74,74,1,255,255,255,4,112,112,112,1,41,41, + 41,1,61,61,61,1,75,75,75,1,95,95,95,1,51,51,51,1,4,4, + 4,1,0,0,0,12,64,64,64,1,255,255,255,5,242,242,242,1,180,180, + 180,1,66,66,66,1,2,2,2,1,0,0,0,19,255,255,255,3,0,0, + 0,13,18,18,18,1,31,31,31,1,80,80,80,1,113,113,113,1,125,125, + 125,1,128,128,128,8,147,147,147,1,218,218,218,1,254,254,254,1,255,255, + 255,1,220,220,220,1,63,63,63,1,6,6,6,1,0,0,0,4,18,18, + 18,1,178,178,178,1,224,224,224,1,242,242,242,1,255,255,255,5,191,191, + 191,1,140,140,140,1,0,0,0,11,34,34,34,1,235,235,235,1,255,255, + 255,2,253,253,253,1,242,242,242,1,255,255,255,5,112,112,112,1,16,16, + 16,1,0,0,0,2,47,47,47,1,84,84,84,1,94,94,94,1,44,44, + 44,1,87,87,87,1,50,50,50,1,48,48,48,1,0,0,0,7,64,64, + 64,1,255,255,255,4,237,237,237,1,159,159,159,1,47,47,47,1,1,1, + 1,1,0,0,0,20,255,255,255,4,0,0,0,12,119,119,119,1,118,118, + 118,1,117,117,117,1,104,104,104,1,70,70,70,1,12,12,12,8,13,13, + 13,1,47,47,47,1,238,238,238,1,255,255,255,1,233,233,233,1,92,92, + 92,1,8,8,8,1,0,0,0,5,3,3,3,1,61,61,61,1,136,136, + 136,1,255,255,255,4,191,191,191,1,140,140,140,1,0,0,0,12,1,1, + 1,1,109,109,109,1,236,236,236,1,255,255,255,9,64,64,64,1,0,0, + 0,2,14,14,14,1,27,27,27,2,29,29,29,1,12,12,12,1,29,29, + 29,1,36,36,36,1,0,0,0,7,64,64,64,1,255,255,255,3,231,231, + 231,1,139,139,139,1,31,31,31,1,1,1,1,1,0,0,0,21,255,255, + 255,4,0,0,0,14,41,41,41,1,1,1,1,1,61,61,61,1,70,70, + 70,1,58,58,58,1,38,38,38,1,21,21,21,1,68,68,68,1,14,14, + 14,1,0,0,0,3,15,15,15,1,231,231,231,1,255,255,255,1,241,241, + 241,1,117,117,117,1,11,11,11,1,0,0,0,7,65,65,65,1,255,255, + 255,3,191,191,191,1,140,140,140,1,0,0,0,14,5,5,5,1,80,80, + 80,1,208,208,208,1,229,229,229,1,247,247,247,1,255,255,255,5,191,191, + 191,1,143,143,143,1,0,0,0,2,65,65,65,1,104,104,104,1,113,113, + 113,1,107,107,107,1,109,109,109,1,91,91,91,1,74,74,74,1,87,87, + 87,1,0,0,0,6,64,64,64,1,255,255,255,1,252,252,252,1,223,223, + 223,1,119,119,119,1,19,19,19,1,1,1,1,1,0,0,0,42,53,53, + 53,1,62,62,62,1,28,28,28,1,34,34,34,1,18,18,18,1,63,63, + 63,1,22,22,22,1,0,0,0,3,4,4,4,1,226,226,226,1,255,255, + 255,1,241,241,241,1,127,127,127,1,12,12,12,1,0,0,0,7,64,64, + 64,1,255,255,255,2,191,191,191,1,140,140,140,1,0,0,0,16,6,6, + 6,1,30,30,30,1,82,82,82,1,146,146,146,1,255,255,255,4,191,191, + 191,1,144,144,144,1,18,18,18,1,16,16,16,1,42,42,42,1,2,2, + 2,1,0,0,0,1,20,20,20,1,1,1,1,1,0,0,0,10,64,64, + 64,1,246,246,246,1,209,209,209,1,100,100,100,1,9,9,9,1,0,0, + 0,44,65,65,65,1,90,90,90,1,81,81,81,1,93,93,93,1,76,76, + 76,1,84,84,84,1,57,57,57,1,41,41,41,1,92,92,92,1,81,81, + 81,1,14,14,14,1,231,231,231,1,255,255,255,1,244,244,244,1,128,128, + 128,1,12,12,12,1,0,0,0,7,64,64,64,1,255,255,255,1,195,195, + 195,1,140,140,140,1,0,0,0,18,2,2,2,1,7,7,7,1,71,71, + 71,1,255,255,255,3,191,191,191,1,143,143,143,1,40,40,40,1,92,92, + 92,1,79,79,79,1,84,84,84,1,6,6,6,1,0,0,0,13,59,59, + 59,1,124,124,124,1,79,79,79,1,4,4,4,1,0,0,0,43,10,10, + 10,1,3,3,3,1,34,34,34,1,48,48,48,1,49,49,49,1,33,33, + 33,1,34,34,34,1,28,28,28,1,14,14,14,1,0,0,0,1,16,16, + 16,1,17,17,17,1,22,22,22,1,69,69,69,1,151,151,151,1,160,160, + 160,1,115,115,115,1,13,13,13,1,0,0,0,7,16,16,16,1,65,65, + 65,1,145,145,145,1,0,0,0,2,24,24,24,1,48,48,48,2,63,63, + 63,1,0,0,0,15,64,64,64,1,255,255,255,2,191,191,191,1,143,143, + 143,1,0,0,0,21,1,1,1,1,0,0,0,42,112,112,112,2,120,120, + 120,1,41,41,41,1,0,0,0,11,1,1,1,1,12,12,12,2,11,11, + 11,1,1,1,1,1,0,0,0,12,38,38,38,1,54,54,54,1,57,57, + 57,1,58,58,58,1,0,0,0,15,64,64,64,1,255,255,255,1,191,191, + 191,1,143,143,143,1,0,0,0,68,8,8,8,1,0,0,0,47,16,16, + 16,1,67,67,67,1,143,143,143,1,0,0,0,255,0,0,0,56,50,50, + 50,1,127,127,127,1,174,174,174,1,200,200,200,1,201,201,201,1,175,175, + 175,1,130,130,130,1,55,55,55,1,4,4,4,1,1,1,1,1,0,0, + 0,32,255,255,255,2,0,0,0,16,255,255,255,2,0,0,0,56,24,24, + 24,1,187,187,187,1,244,244,244,1,255,255,255,6,246,246,246,1,195,195, + 195,1,37,37,37,1,3,3,3,1,0,0,0,31,255,255,255,3,0,0, + 0,14,255,255,255,3,0,0,0,32,217,217,217,1,220,220,220,2,226,226, + 226,1,0,0,0,4,221,221,221,1,224,224,224,2,229,229,229,1,0,0, + 0,11,104,104,104,1,218,218,218,1,255,255,255,10,231,231,231,1,124,124, + 124,1,9,9,9,1,1,1,1,1,0,0,0,30,255,255,255,3,0,0, + 0,12,255,255,255,3,0,0,0,33,216,216,216,1,255,255,255,2,242,242, + 242,1,140,140,140,1,0,0,0,3,216,216,216,1,255,255,255,2,242,242, + 242,1,140,140,140,1,0,0,0,9,104,104,104,1,240,240,240,1,255,255, + 255,12,246,246,246,1,140,140,140,1,13,13,13,1,1,1,1,1,0,0, + 0,30,255,255,255,3,0,0,0,10,255,255,255,3,0,0,0,34,216,216, + 216,1,255,255,255,2,242,242,242,1,141,141,141,1,0,0,0,3,216,216, + 216,1,255,255,255,2,242,242,242,1,141,141,141,1,0,0,0,8,24,24, + 24,1,218,218,218,1,255,255,255,14,235,235,235,1,83,83,83,1,9,9, + 9,1,0,0,0,31,255,255,255,3,0,0,0,3,255,255,255,2,0,0, + 0,3,255,255,255,3,0,0,0,35,216,216,216,1,255,255,255,2,241,241, + 241,1,141,141,141,1,0,0,0,3,216,216,216,1,255,255,255,2,241,241, + 241,1,141,141,141,1,0,0,0,8,187,187,187,1,255,255,255,16,217,217, + 217,1,37,37,37,1,3,3,3,1,0,0,0,10,45,45,45,1,172,172, + 172,1,197,197,197,1,196,196,196,1,171,171,171,1,44,44,44,1,0,0, + 0,15,255,255,255,12,0,0,0,11,33,33,33,1,3,3,3,1,0,0, + 0,4,23,23,23,1,13,13,13,1,0,0,0,4,9,9,9,1,26,26, + 26,1,1,1,1,1,0,0,0,10,216,216,216,1,255,255,255,2,241,241, + 241,1,142,142,142,1,0,0,0,3,216,216,216,1,255,255,255,2,241,241, + 241,1,142,142,142,1,0,0,0,7,50,50,50,1,244,244,244,1,255,255, + 255,16,248,248,248,1,127,127,127,1,16,16,16,1,1,1,1,1,0,0, + 0,8,115,115,115,1,229,229,229,1,255,255,255,4,238,238,238,1,125,125, + 125,1,0,0,0,15,255,255,255,10,0,0,0,10,54,54,54,1,208,208, + 208,1,179,179,179,1,212,212,212,1,104,104,104,1,2,2,2,1,10,10, + 10,1,190,190,190,1,191,191,191,1,204,204,204,1,162,162,162,1,3,3, + 3,1,0,0,0,1,138,138,138,1,208,208,208,1,186,186,186,1,196,196, + 196,1,32,32,32,1,1,1,1,1,0,0,0,8,216,216,216,1,255,255, + 255,2,241,241,241,1,142,142,142,1,0,0,0,3,216,216,216,1,255,255, + 255,2,241,241,241,1,142,142,142,1,0,0,0,7,127,127,127,1,255,255, + 255,18,187,187,187,1,47,47,47,1,4,4,4,1,0,0,0,7,45,45, + 45,1,229,229,229,1,255,255,255,6,241,241,241,1,95,95,95,1,0,0, + 0,14,255,255,255,10,0,0,0,10,181,181,181,1,109,109,109,1,105,105, + 105,1,106,106,106,1,241,241,241,1,65,65,65,1,111,111,111,1,164,164, + 164,1,97,97,97,1,98,98,98,1,220,220,220,1,129,129,129,1,41,41, + 41,1,226,226,226,1,77,77,77,1,105,105,105,1,173,173,173,1,185,185, + 185,1,19,19,19,1,1,1,1,1,0,0,0,7,216,216,216,1,255,255, + 255,2,242,242,242,1,143,143,143,1,0,0,0,3,216,216,216,1,255,255, + 255,2,242,242,242,1,143,143,143,1,0,0,0,7,174,174,174,1,255,255, + 255,18,213,213,213,1,70,70,70,1,8,8,8,1,0,0,0,7,172,172, + 172,1,255,255,255,8,213,213,213,1,32,32,32,1,0,0,0,13,255,255, + 255,10,0,0,0,10,45,45,45,1,92,92,92,1,49,49,49,1,16,16, + 16,1,236,236,236,1,129,129,129,1,39,39,39,1,70,70,70,1,82,82, + 82,1,7,7,7,1,177,177,177,1,158,158,158,1,51,51,51,1,53,53, + 53,1,111,111,111,1,10,10,10,1,105,105,105,1,191,191,191,1,73,73, + 73,1,3,3,3,1,0,0,0,7,216,216,216,1,255,255,255,2,242,242, + 242,1,143,143,143,1,0,0,0,3,216,216,216,1,255,255,255,2,242,242, + 242,1,143,143,143,1,0,0,0,7,200,200,200,1,255,255,255,18,227,227, + 227,1,92,92,92,1,10,10,10,1,0,0,0,7,197,197,197,1,255,255, + 255,8,228,228,228,1,96,96,96,1,0,0,0,12,255,255,255,12,0,0, + 0,9,1,1,1,1,23,23,23,1,13,13,13,1,186,186,186,1,134,134, + 134,1,119,119,119,1,16,16,16,2,13,13,13,1,124,124,124,1,193,193, + 193,1,96,96,96,1,50,50,50,1,10,10,10,1,19,19,19,1,62,62, + 62,1,224,224,224,1,87,87,87,1,85,85,85,1,3,3,3,1,0,0, + 0,7,216,216,216,1,255,255,255,2,241,241,241,1,144,144,144,1,0,0, + 0,3,216,216,216,1,255,255,255,2,241,241,241,1,144,144,144,1,0,0, + 0,7,201,201,201,1,255,255,255,18,227,227,227,1,112,112,112,1,13,13, + 13,1,0,0,0,7,196,196,196,1,255,255,255,8,228,228,228,1,126,126, + 126,1,0,0,0,12,255,255,255,12,0,0,0,10,1,1,1,1,152,152, + 152,1,149,149,149,1,94,94,94,1,68,68,68,1,3,3,3,1,1,1, + 1,1,80,80,80,1,204,204,204,1,75,75,75,1,97,97,97,1,8,8, + 8,1,1,1,1,1,22,22,22,1,227,227,227,1,78,78,78,1,111,111, + 111,1,25,25,25,1,1,1,1,1,0,0,0,7,216,216,216,1,255,255, + 255,2,241,241,241,1,144,144,144,1,0,0,0,3,216,216,216,1,255,255, + 255,2,241,241,241,1,144,144,144,1,0,0,0,7,175,175,175,1,255,255, + 255,18,215,215,215,1,112,112,112,1,13,13,13,1,0,0,0,7,171,171, + 171,1,255,255,255,8,214,214,214,1,126,126,126,1,0,0,0,13,255,255, + 255,10,0,0,0,12,221,221,221,1,97,97,97,1,76,76,76,1,5,5, + 5,1,0,0,0,2,150,150,150,1,126,126,126,1,102,102,102,1,14,14, + 14,1,0,0,0,2,77,77,77,1,177,177,177,1,114,114,114,1,31,31, + 31,1,2,2,2,1,0,0,0,8,216,216,216,1,255,255,255,2,242,242, + 242,1,145,145,145,1,0,0,0,3,216,216,216,1,255,255,255,2,242,242, + 242,1,145,145,145,1,0,0,0,7,130,130,130,1,255,255,255,18,192,192, + 192,1,92,92,92,1,10,10,10,1,0,0,0,7,44,44,44,1,238,238, + 238,1,255,255,255,6,241,241,241,1,157,157,157,1,96,96,96,1,0,0, + 0,13,255,255,255,10,0,0,0,12,35,35,35,1,112,112,112,1,19,19, + 19,1,1,1,1,1,0,0,0,2,24,24,24,1,85,85,85,1,53,53, + 53,1,2,2,2,1,0,0,0,2,14,14,14,1,59,59,59,1,88,88, + 88,1,4,4,4,1,0,0,0,9,216,216,216,1,255,255,255,2,242,242, + 242,1,145,145,145,1,0,0,0,3,216,216,216,1,255,255,255,2,242,242, + 242,1,145,145,145,1,0,0,0,7,55,55,55,1,246,246,246,1,255,255, + 255,16,248,248,248,1,154,154,154,1,70,70,70,1,8,8,8,1,0,0, + 0,8,125,125,125,1,241,241,241,1,255,255,255,4,241,241,241,1,185,185, + 185,1,139,139,139,1,32,32,32,1,0,0,0,13,255,255,255,10,0,0, + 0,12,248,248,248,1,59,59,59,1,4,4,4,1,0,0,0,3,175,175, + 175,1,121,121,121,1,11,11,11,1,0,0,0,3,102,102,102,1,187,187, + 187,1,18,18,18,1,1,1,1,1,0,0,0,9,216,216,216,1,255,255, + 255,2,242,242,242,1,145,145,145,1,0,0,0,3,216,216,216,1,255,255, + 255,2,242,242,242,1,145,145,145,1,0,0,0,7,4,4,4,1,195,195, + 195,1,255,255,255,16,220,220,220,1,127,127,127,1,47,47,47,1,4,4, + 4,1,0,0,0,9,95,95,95,1,213,213,213,1,228,228,228,2,214,214, + 214,1,157,157,157,1,139,139,139,1,66,66,66,1,0,0,0,13,255,255, + 255,12,0,0,0,11,4,4,4,1,119,119,119,1,24,24,24,1,1,1, + 1,1,0,0,0,2,3,3,3,1,86,86,86,1,57,57,57,1,2,2, + 2,1,0,0,0,2,2,2,2,1,52,52,52,1,91,91,91,1,3,3, + 3,1,0,0,0,9,216,216,216,1,255,255,255,2,241,241,241,1,146,146, + 146,1,0,0,0,3,216,216,216,1,255,255,255,2,241,241,241,1,146,146, + 146,1,0,0,0,7,1,1,1,1,37,37,37,1,231,231,231,1,255,255, + 255,14,237,237,237,1,146,146,146,1,98,98,98,1,16,16,16,1,1,1, + 1,1,0,0,0,10,32,32,32,1,96,96,96,1,126,126,126,2,96,96, + 96,1,32,32,32,1,0,0,0,13,255,255,255,3,0,0,0,3,255,255, + 255,2,0,0,0,3,255,255,255,3,0,0,0,11,4,4,4,1,1,1, + 1,1,0,0,0,4,3,3,3,1,2,2,2,1,0,0,0,4,2,2, + 2,1,3,3,3,1,0,0,0,10,216,216,216,1,255,255,255,2,242,242, + 242,1,146,146,146,1,0,0,0,3,216,216,216,1,255,255,255,2,242,242, + 242,1,146,146,146,1,0,0,0,8,3,3,3,1,124,124,124,1,246,246, + 246,1,255,255,255,12,248,248,248,1,185,185,185,1,119,119,119,1,37,37, + 37,1,3,3,3,1,0,0,0,29,255,255,255,3,0,0,0,10,255,255, + 255,3,0,0,0,34,222,222,222,1,241,241,241,2,242,242,242,1,147,147, + 147,1,0,0,0,3,222,222,222,1,240,240,240,2,241,241,241,1,147,147, + 147,1,0,0,0,9,9,9,9,1,141,141,141,1,235,235,235,1,255,255, + 255,10,237,237,237,1,185,185,185,1,125,125,125,1,65,65,65,1,9,9, + 9,1,0,0,0,29,255,255,255,3,0,0,0,12,255,255,255,3,0,0, + 0,33,6,6,6,1,142,142,142,1,141,141,141,1,140,140,140,2,0,0, + 0,4,140,140,140,4,0,0,0,9,1,1,1,1,13,13,13,1,82,82, + 82,1,217,217,217,1,248,248,248,1,255,255,255,6,248,248,248,1,220,220, + 220,1,146,146,146,1,119,119,119,1,64,64,64,1,13,13,13,1,1,1, + 1,1,0,0,0,28,255,255,255,3,0,0,0,14,255,255,255,3,0,0, + 0,55,1,1,1,1,9,9,9,1,37,37,37,1,127,127,127,1,187,187, + 187,1,212,212,212,1,227,227,227,2,215,215,215,1,192,192,192,1,154,154, + 154,1,127,127,127,1,98,98,98,1,37,37,37,1,9,9,9,1,1,1, + 1,1,0,0,0,29,255,255,255,2,0,0,0,16,255,255,255,2,0,0, + 0,57,3,3,3,1,16,16,16,1,47,47,47,1,70,70,70,1,92,92, + 92,1,112,112,112,2,92,92,92,1,70,70,70,1,47,47,47,1,16,16, + 16,1,3,3,3,1,0,0,0,109,1,1,1,1,4,4,4,1,8,8, + 8,1,10,10,10,1,13,13,13,2,10,10,10,1,8,8,8,1,4,4, + 4,1,1,1,1,1,0,0,0,132,16,16,16,1,64,64,64,1,16,16, + 16,1,0,0,0,26,12,12,12,1,0,0,0,2,12,12,12,1,0,0, + 0,87,64,64,64,1,255,255,255,1,112,112,112,1,16,16,16,1,0,0, + 0,25,70,70,70,1,105,105,105,1,100,100,100,1,104,104,104,1,112,112, + 112,1,0,0,0,86,64,64,64,1,255,255,255,2,112,112,112,1,16,16, + 16,1,0,0,0,26,19,19,19,1,23,23,23,1,0,0,0,87,64,64, + 64,1,255,255,255,3,112,112,112,1,16,16,16,1,0,0,0,1,12,12, + 12,1,0,0,0,2,12,12,12,1,0,0,0,109,64,64,64,1,255,255, + 255,4,112,112,112,1,16,16,16,1,96,96,96,1,114,114,114,1,98,98, + 98,1,100,100,100,1,84,84,84,1,0,0,0,105,32,32,32,1,172,172, + 172,1,200,200,200,1,236,236,236,1,255,255,255,5,112,112,112,1,16,16, + 16,1,0,0,0,1,33,33,33,1,10,10,10,1,26,26,26,1,40,40, + 40,1,44,44,44,1,18,18,18,1,16,16,16,1,50,50,50,1,8,8, + 8,1,0,0,0,3,3,3,3,1,133,133,133,1,184,184,184,1,211,211, + 211,1,224,224,224,1,225,225,225,4,233,233,233,1,71,71,71,1,0,0, + 0,84,91,91,91,1,222,222,222,1,255,255,255,9,64,64,64,1,0,0, + 0,3,80,80,80,1,89,89,89,1,45,45,45,1,42,42,42,1,36,36, + 36,1,82,82,82,1,27,27,27,1,0,0,0,2,26,26,26,1,196,196, + 196,1,253,253,253,1,255,255,255,8,167,167,167,1,1,1,1,1,0,0, + 0,44,255,255,255,2,0,0,0,23,255,255,255,1,0,0,0,12,37,37, + 37,1,227,227,227,1,255,255,255,3,248,248,248,1,255,255,255,5,191,191, + 191,1,147,147,147,1,0,0,0,3,43,43,43,1,47,47,47,1,56,56, + 56,1,77,77,77,1,51,51,51,1,55,55,55,1,31,31,31,1,0,0, + 0,1,3,3,3,1,204,204,204,1,255,255,255,3,249,249,249,1,243,243, + 243,1,242,242,242,2,241,241,241,2,245,245,245,1,168,168,168,1,1,1, + 1,1,0,0,0,1,12,12,12,1,4,4,4,1,17,17,17,1,0,0, + 0,2,25,25,25,1,0,0,0,11,58,58,58,1,175,175,175,1,229,229, + 229,2,175,175,175,1,58,58,58,1,0,0,0,20,255,255,255,2,0,0, + 0,23,255,255,255,1,0,0,0,12,183,183,183,1,255,255,255,2,235,235, + 235,1,192,192,192,1,170,170,170,1,255,255,255,4,191,191,191,1,147,147, + 147,1,0,0,0,4,53,53,53,1,78,78,78,1,90,90,90,1,62,62, + 62,1,65,65,65,1,56,56,56,1,28,28,28,1,0,0,0,1,125,125, + 125,1,251,251,251,1,255,255,255,1,243,243,243,1,204,204,204,1,158,158, + 158,1,145,145,145,1,137,137,137,1,135,135,135,1,134,134,134,1,133,133, + 133,1,131,131,131,1,130,130,130,1,1,1,1,1,0,0,0,1,86,86, + 86,1,99,99,99,1,96,96,96,1,43,43,43,1,70,70,70,1,98,98, + 98,1,34,34,34,1,0,0,0,9,120,120,120,1,253,253,253,1,255,255, + 255,4,254,254,254,1,137,137,137,1,0,0,0,19,255,255,255,2,0,0, + 0,23,255,255,255,1,0,0,0,12,211,211,211,1,255,255,255,2,192,192, + 192,1,112,112,112,1,99,99,99,1,255,255,255,3,191,191,191,1,147,147, + 147,1,0,0,0,1,68,68,68,1,73,73,73,1,78,78,78,1,57,57, + 57,1,0,0,0,8,189,189,189,1,255,255,255,2,216,216,216,1,132,132, + 132,1,66,66,66,1,72,72,72,1,17,17,17,1,1,1,1,5,0,0, + 0,4,1,1,1,1,0,0,0,3,8,8,8,1,0,0,0,8,58,58, + 58,1,253,253,253,1,255,255,255,6,254,254,254,1,109,109,109,1,0,0, + 0,18,255,255,255,2,0,0,0,23,255,255,255,1,0,0,0,11,6,6, + 6,1,225,225,225,1,255,255,255,1,244,244,244,1,146,146,146,1,49,49, + 49,1,68,68,68,1,255,255,255,2,191,191,191,1,147,147,147,1,0,0, + 0,2,30,30,30,1,23,23,23,1,34,34,34,1,32,32,32,1,0,0, + 0,8,209,209,209,1,255,255,255,1,252,252,252,1,174,174,174,1,59,59, + 59,1,64,64,64,1,255,255,255,1,112,112,112,1,16,16,16,1,0,0, + 0,21,175,175,175,1,255,255,255,8,219,219,219,1,32,32,32,1,0,0, + 0,17,255,255,255,2,0,0,0,23,255,255,255,1,0,0,0,12,210,210, + 210,1,255,255,255,2,187,187,187,1,24,24,24,1,65,65,65,1,255,255, + 255,1,191,191,191,1,147,147,147,1,2,2,2,1,0,0,0,14,208,208, + 208,1,255,255,255,1,252,252,252,1,174,174,174,1,17,17,17,1,64,64, + 64,1,255,255,255,2,117,117,117,1,16,16,16,1,0,0,0,20,229,229, + 229,1,255,255,255,8,243,243,243,1,96,96,96,1,0,0,0,17,255,255, + 255,2,0,0,0,23,255,255,255,1,0,0,0,12,181,181,181,1,255,255, + 255,2,233,233,233,1,87,87,87,1,22,22,22,1,65,65,65,1,147,147, + 147,1,0,0,0,16,185,185,185,1,255,255,255,2,215,215,215,1,20,20, + 20,1,64,64,64,1,255,255,255,3,117,117,117,1,16,16,16,1,0,0, + 0,19,229,229,229,1,255,255,255,8,243,243,243,1,126,126,126,1,0,0, + 0,17,255,255,255,2,0,0,0,23,255,255,255,1,0,0,0,12,41,41, + 41,1,235,235,235,1,255,255,255,2,247,247,247,1,228,228,228,1,222,222, + 222,2,221,221,221,7,210,210,210,1,189,189,189,1,140,140,140,1,8,8, + 8,1,1,1,1,1,0,0,0,4,97,97,97,1,248,248,248,1,255,255, + 255,1,243,243,243,1,174,174,174,1,97,97,97,1,255,255,255,4,117,117, + 117,1,16,16,16,1,0,0,0,18,175,175,175,1,255,255,255,8,219,219, + 219,1,126,126,126,1,0,0,0,42,255,255,255,1,0,0,0,12,1,1, + 1,1,109,109,109,1,237,237,237,1,255,255,255,14,252,252,252,1,198,198, + 198,1,18,18,18,1,2,2,2,1,0,0,0,4,199,199,199,1,255,255, + 255,3,248,248,248,1,255,255,255,5,117,117,117,1,16,16,16,1,0,0, + 0,2,16,16,16,1,19,19,19,2,46,46,46,1,18,18,18,1,19,19, + 19,1,13,13,13,1,22,22,22,1,0,0,0,7,58,58,58,1,254,254, + 254,1,255,255,255,6,254,254,254,1,166,166,166,1,96,96,96,1,0,0, + 0,56,5,5,5,1,77,77,77,1,210,210,210,1,228,228,228,1,239,239, + 239,1,241,241,241,9,248,248,248,1,255,255,255,2,250,250,250,1,152,152, + 152,1,14,14,14,1,1,1,1,1,0,0,0,3,14,14,14,1,214,214, + 214,1,252,252,252,1,255,255,255,8,71,71,71,1,0,0,0,2,76,76, + 76,1,108,108,108,1,118,118,118,1,88,88,88,1,93,93,93,1,79,79, + 79,1,45,45,45,1,49,49,49,1,0,0,0,8,137,137,137,1,254,254, + 254,1,255,255,255,4,254,254,254,1,194,194,194,1,139,139,139,1,32,32, + 32,1,0,0,0,17,255,255,255,2,0,0,0,23,255,255,255,1,0,0, + 0,14,18,18,18,1,31,31,31,1,80,80,80,1,113,113,113,1,125,125, + 125,1,128,128,128,8,147,147,147,1,218,218,218,1,254,254,254,1,255,255, + 255,1,220,220,220,1,63,63,63,1,6,6,6,1,0,0,0,4,18,18, + 18,1,178,178,178,1,224,224,224,1,242,242,242,1,255,255,255,5,191,191, + 191,1,140,140,140,1,0,0,0,19,109,109,109,1,219,219,219,1,243,243, + 243,2,219,219,219,1,166,166,166,1,139,139,139,1,66,66,66,1,0,0, + 0,18,255,255,255,2,0,0,0,38,119,119,119,1,118,118,118,1,117,117, + 117,1,104,104,104,1,70,70,70,1,12,12,12,8,13,13,13,1,47,47, + 47,1,238,238,238,1,255,255,255,1,233,233,233,1,92,92,92,1,8,8, + 8,1,0,0,0,5,3,3,3,1,61,61,61,1,136,136,136,1,255,255, + 255,4,191,191,191,1,140,140,140,1,0,0,0,21,32,32,32,1,96,96, + 96,1,126,126,126,2,96,96,96,1,32,32,32,1,0,0,0,61,41,41, + 41,1,1,1,1,1,61,61,61,1,70,70,70,1,58,58,58,1,38,38, + 38,1,21,21,21,1,68,68,68,1,14,14,14,1,0,0,0,3,15,15, + 15,1,231,231,231,1,255,255,255,1,241,241,241,1,117,117,117,1,11,11, + 11,1,0,0,0,7,65,65,65,1,255,255,255,3,191,191,191,1,140,140, + 140,1,0,0,0,91,53,53,53,1,62,62,62,1,28,28,28,1,34,34, + 34,1,18,18,18,1,63,63,63,1,22,22,22,1,0,0,0,3,4,4, + 4,1,226,226,226,1,255,255,255,1,241,241,241,1,127,127,127,1,12,12, + 12,1,0,0,0,7,64,64,64,1,255,255,255,2,191,191,191,1,140,140, + 140,1,0,0,0,92,65,65,65,1,90,90,90,1,81,81,81,1,93,93, + 93,1,76,76,76,1,84,84,84,1,57,57,57,1,41,41,41,1,92,92, + 92,1,81,81,81,1,14,14,14,1,231,231,231,1,255,255,255,1,244,244, + 244,1,128,128,128,1,12,12,12,1,0,0,0,7,64,64,64,1,255,255, + 255,1,191,191,191,1,140,140,140,1,0,0,0,91,10,10,10,1,3,3, + 3,1,34,34,34,1,48,48,48,1,49,49,49,1,33,33,33,1,34,34, + 34,1,28,28,28,1,14,14,14,1,0,0,0,1,16,16,16,1,17,17, + 17,1,22,22,22,1,69,69,69,1,151,151,151,1,160,160,160,1,115,115, + 115,1,13,13,13,1,0,0,0,7,16,16,16,1,65,65,65,1,145,145, + 145,1,0,0,0,2,24,24,24,1,48,48,48,2,63,63,63,1,0,0, + 0,84,112,112,112,2,120,120,120,1,41,41,41,1,0,0,0,11,1,1, + 1,1,12,12,12,2,11,11,11,1,1,1,1,1,0,0,0,12,38,38, + 38,1,54,54,54,1,57,57,57,1,58,58,58,1,0,0,0,87,8,8, + 8,1,0,0,0,172,12,12,12,1,0,0,0,2,12,12,12,1,0,0, + 0,87,8,8,8,1,248,248,248,1,0,0,0,27,70,70,70,1,105,105, + 105,1,100,100,100,1,104,104,104,1,112,112,112,1,0,0,0,15,4,4, + 4,1,76,76,76,1,128,128,128,1,179,179,179,1,230,230,230,2,179,179, + 179,1,128,128,128,1,76,76,76,1,4,4,4,1,0,0,0,61,8,8, + 8,1,255,255,255,2,0,0,0,28,19,19,19,1,23,23,23,1,0,0, + 0,15,41,41,41,1,203,203,203,1,255,255,255,8,218,218,218,1,44,44, + 44,1,0,0,0,37,37,37,37,1,0,0,0,22,8,8,8,1,255,255, + 255,3,0,0,0,3,12,12,12,1,0,0,0,2,12,12,12,1,0,0, + 0,35,1,1,1,1,114,114,114,1,247,247,247,1,255,255,255,10,253,253, + 253,1,137,137,137,1,1,1,1,1,0,0,0,10,255,255,255,4,0,0, + 0,4,255,255,255,4,0,0,0,13,237,237,237,1,91,91,91,1,0,0, + 0,21,8,8,8,1,255,255,255,4,0,0,0,2,96,96,96,1,114,114, + 114,1,98,98,98,1,100,100,100,1,84,84,84,1,0,0,0,34,114,114, + 114,1,255,255,255,14,177,177,177,1,1,1,1,1,0,0,0,9,255,255, + 255,5,0,0,0,3,255,255,255,5,0,0,0,12,255,255,255,2,135,135, + 135,1,0,0,0,17,34,34,34,1,159,159,159,1,211,211,211,1,252,252, + 252,1,255,255,255,5,0,0,0,3,33,33,33,1,10,10,10,1,26,26, + 26,1,40,40,40,1,44,44,44,1,18,18,18,1,16,16,16,1,50,50, + 50,1,8,8,8,1,0,0,0,3,7,7,7,1,125,125,125,1,188,188, + 188,1,237,237,237,1,255,255,255,6,16,16,16,1,0,0,0,13,41,41, + 41,1,247,247,247,1,255,255,255,15,137,137,137,1,0,0,0,9,255,255, + 255,5,0,0,0,3,255,255,255,5,0,0,0,12,255,255,255,3,180,180, + 180,1,1,1,1,1,0,0,0,14,82,82,82,1,241,241,241,1,255,255, + 255,9,0,0,0,4,80,80,80,1,89,89,89,1,45,45,45,1,42,42, + 42,1,36,36,36,1,82,82,82,1,27,27,27,1,0,0,0,2,40,40, + 40,1,209,209,209,1,255,255,255,10,0,0,0,12,4,4,4,1,203,203, + 203,1,255,255,255,16,253,253,253,1,44,44,44,1,0,0,0,8,255,255, + 255,5,0,0,0,3,255,255,255,5,0,0,0,12,255,255,255,4,215,215, + 215,1,10,10,10,1,0,0,0,12,30,30,30,1,244,244,244,1,255,255, + 255,10,248,248,248,1,0,0,0,3,43,43,43,1,47,47,47,1,56,56, + 56,1,77,77,77,1,51,51,51,1,55,55,55,1,31,31,31,1,0,0, + 0,1,5,5,5,1,214,214,214,1,255,255,255,11,0,0,0,2,12,12, + 12,1,4,4,4,1,17,17,17,1,0,0,0,2,25,25,25,1,0,0, + 0,4,76,76,76,1,255,255,255,18,218,218,218,1,4,4,4,1,0,0, + 0,7,255,255,255,5,0,0,0,3,255,255,255,5,0,0,0,12,255,255, + 255,5,237,237,237,1,32,32,32,1,0,0,0,11,158,158,158,1,255,255, + 255,10,248,248,248,1,0,0,0,4,53,53,53,1,78,78,78,1,90,90, + 90,1,62,62,62,1,65,65,65,1,56,56,56,1,28,28,28,1,0,0, + 0,1,110,110,110,1,255,255,255,6,240,240,240,6,0,0,0,2,86,86, + 86,1,99,99,99,1,96,96,96,1,43,43,43,1,70,70,70,1,98,98, + 98,1,34,34,34,1,0,0,0,3,127,127,127,1,255,255,255,19,76,76, + 76,1,0,0,0,7,255,255,255,5,0,0,0,3,255,255,255,5,0,0, + 0,12,255,255,255,6,249,249,249,1,65,65,65,1,0,0,0,10,216,216, + 216,1,255,255,255,3,222,222,222,1,75,75,75,1,255,255,255,4,248,248, + 248,1,0,0,0,1,68,68,68,1,73,73,73,1,78,78,78,1,57,57, + 57,1,0,0,0,8,185,185,185,1,255,255,255,3,243,243,243,1,97,97, + 97,1,18,18,18,1,0,0,0,10,1,1,1,1,0,0,0,3,8,8, + 8,1,0,0,0,3,179,179,179,1,255,255,255,19,127,127,127,1,0,0, + 0,7,255,255,255,5,0,0,0,3,255,255,255,5,0,0,0,12,255,255, + 255,7,253,253,253,1,105,105,105,1,0,0,0,8,1,1,1,1,250,250, + 250,1,255,255,255,3,69,69,69,1,8,8,8,1,255,255,255,3,248,248, + 248,1,0,0,0,2,30,30,30,1,23,23,23,1,34,34,34,1,32,32, + 32,1,0,0,0,8,229,229,229,1,255,255,255,3,107,107,107,1,0,0, + 0,1,255,255,255,1,0,0,0,18,230,230,230,1,255,255,255,19,179,179, + 179,1,0,0,0,7,255,255,255,5,0,0,0,3,255,255,255,5,0,0, + 0,12,255,255,255,9,150,150,150,1,0,0,0,8,221,221,221,1,255,255, + 255,3,11,11,11,1,8,8,8,1,248,248,248,1,255,255,255,1,252,252, + 252,1,0,0,0,15,229,229,229,1,255,255,255,3,29,29,29,1,0,0, + 0,1,255,255,255,2,16,16,16,1,0,0,0,16,230,230,230,1,255,255, + 255,19,230,230,230,1,0,0,0,7,255,255,255,5,0,0,0,3,255,255, + 255,5,0,0,0,12,255,255,255,9,253,253,253,1,108,108,108,1,0,0, + 0,7,165,165,165,1,255,255,255,3,105,105,105,1,9,9,9,1,8,8, + 8,1,248,248,248,1,0,0,0,16,185,185,185,1,255,255,255,3,35,35, + 35,1,0,0,0,1,255,255,255,3,16,16,16,1,0,0,0,15,179,179, + 179,1,255,255,255,19,230,230,230,1,0,0,0,7,255,255,255,5,0,0, + 0,3,255,255,255,5,0,0,0,12,255,255,255,9,252,252,252,1,108,108, + 108,1,0,0,0,7,37,37,37,1,253,253,253,1,255,255,255,13,237,237, + 237,1,190,190,190,1,138,138,138,1,8,8,8,1,0,0,0,5,105,105, + 105,1,255,255,255,3,185,185,185,1,31,31,31,1,255,255,255,4,16,16, + 16,1,0,0,0,14,127,127,127,1,255,255,255,19,179,179,179,1,0,0, + 0,7,255,255,255,5,0,0,0,3,255,255,255,5,0,0,0,12,255,255, + 255,8,242,242,242,1,73,73,73,1,0,0,0,9,119,119,119,1,255,255, + 255,16,217,217,217,1,10,10,10,1,0,0,0,4,3,3,3,1,226,226, + 226,1,255,255,255,9,16,16,16,1,0,0,0,3,16,16,16,1,19,19, + 19,2,46,46,46,1,18,18,18,1,19,19,19,1,13,13,13,1,22,22, + 22,1,0,0,0,2,76,76,76,1,255,255,255,19,127,127,127,1,0,0, + 0,7,255,255,255,5,0,0,0,3,255,255,255,5,0,0,0,12,255,255, + 255,7,225,225,225,1,45,45,45,1,0,0,0,11,122,122,122,1,252,252, + 252,1,255,255,255,15,209,209,209,1,2,2,2,1,0,0,0,4,38,38, + 38,1,244,244,244,1,255,255,255,9,16,16,16,1,0,0,0,2,76,76, + 76,1,108,108,108,1,118,118,118,1,88,88,88,1,93,93,93,1,79,79, + 79,1,45,45,45,1,49,49,49,1,0,0,0,2,4,4,4,1,218,218, + 218,1,255,255,255,18,76,76,76,1,0,0,0,7,255,255,255,5,0,0, + 0,3,255,255,255,5,0,0,0,12,255,255,255,6,201,201,201,1,24,24, + 24,1,0,0,0,12,12,12,12,1,41,41,41,1,161,161,161,1,214,214, + 214,1,252,252,252,1,255,255,255,13,111,111,111,1,0,0,0,5,33,33, + 33,1,225,225,225,1,255,255,255,8,240,240,240,1,0,0,0,13,44,44, + 44,1,253,253,253,1,255,255,255,16,203,203,203,1,4,4,4,1,0,0, + 0,7,255,255,255,5,0,0,0,3,255,255,255,5,0,0,0,12,255,255, + 255,5,171,171,171,1,9,9,9,1,0,0,0,13,119,119,119,1,117,117, + 117,1,113,113,113,1,98,98,98,1,61,61,61,1,0,0,0,9,72,72, + 72,1,255,255,255,3,169,169,169,1,0,0,0,6,4,4,4,1,111,111, + 111,1,172,172,172,1,255,255,255,5,240,240,240,1,0,0,0,15,137,137, + 137,1,255,255,255,15,247,247,247,1,41,41,41,1,0,0,0,8,255,255, + 255,5,0,0,0,3,255,255,255,5,0,0,0,12,255,255,255,4,134,134, + 134,1,1,1,1,1,0,0,0,16,41,41,41,1,1,1,1,1,61,61, + 61,1,70,70,70,1,58,58,58,1,38,38,38,1,21,21,21,1,68,68, + 68,1,14,14,14,1,0,0,0,3,14,14,14,1,255,255,255,3,217,217, + 217,1,0,0,0,9,255,255,255,4,240,240,240,1,0,0,0,16,1,1, + 1,1,177,177,177,1,255,255,255,14,114,114,114,1,0,0,0,9,255,255, + 255,5,0,0,0,3,255,255,255,5,0,0,0,12,237,237,237,1,255,255, + 255,1,249,249,249,1,96,96,96,1,0,0,0,20,53,53,53,1,62,62, + 62,1,28,28,28,1,34,34,34,1,18,18,18,1,63,63,63,1,22,22, + 22,1,0,0,0,3,8,8,8,1,255,255,255,3,242,242,242,1,0,0, + 0,9,255,255,255,3,240,240,240,1,0,0,0,18,1,1,1,1,137,137, + 137,1,253,253,253,1,255,255,255,10,247,247,247,1,114,114,114,1,1,1, + 1,1,0,0,0,10,255,255,255,4,0,0,0,4,255,255,255,4,0,0, + 0,12,37,37,37,1,237,237,237,1,63,63,63,1,0,0,0,21,65,65, + 65,1,90,90,90,1,81,81,81,1,93,93,93,1,76,76,76,1,84,84, + 84,1,57,57,57,1,41,41,41,1,92,92,92,1,81,81,81,1,17,17, + 17,1,255,255,255,3,247,247,247,1,0,0,0,9,255,255,255,2,240,240, + 240,1,0,0,0,21,44,44,44,1,218,218,218,1,255,255,255,8,203,203, + 203,1,41,41,41,1,0,0,0,37,37,37,37,1,0,0,0,20,10,10, + 10,1,3,3,3,1,34,34,34,1,48,48,48,1,49,49,49,1,33,33, + 33,1,34,34,34,1,28,28,28,1,14,14,14,1,0,0,0,1,16,16, + 16,1,17,17,17,1,22,22,22,1,8,8,8,1,255,255,255,2,248,248, + 248,1,0,0,0,9,2,2,2,1,251,251,251,1,0,0,0,2,24,24, + 24,1,48,48,48,2,63,63,63,1,0,0,0,17,4,4,4,1,76,76, + 76,1,128,128,128,1,179,179,179,1,230,230,230,2,179,179,179,1,128,128, + 128,1,76,76,76,1,4,4,4,1,0,0,0,57,112,112,112,2,120,120, + 120,1,41,41,41,1,0,0,0,12,5,5,5,1,0,0,0,15,38,38, + 38,1,54,54,54,1,57,57,57,1,58,58,58,1,0,0,0,87,8,8, + 8,1,0,0,0,43,12,12,12,1,0,0,0,2,12,12,12,1,0,0, + 0,53,12,12,12,1,0,0,0,2,12,12,12,1,0,0,0,11,12,12, + 12,1,0,0,0,2,12,12,12,1,0,0,0,44,70,70,70,1,105,105, + 105,1,100,100,100,1,104,104,104,1,112,112,112,1,0,0,0,23,8,8, + 8,1,248,248,248,1,0,0,0,27,70,70,70,1,105,105,105,1,100,100, + 100,1,104,104,104,1,112,112,112,1,0,0,0,10,70,70,70,1,105,105, + 105,1,100,100,100,1,104,104,104,1,112,112,112,1,0,0,0,45,19,19, + 19,1,23,23,23,2,26,26,26,1,59,59,59,1,11,11,11,1,23,23, + 23,1,40,40,40,1,17,17,17,1,0,0,0,5,5,5,5,1,0,0, + 0,11,8,8,8,1,255,255,255,2,0,0,0,28,19,19,19,1,23,23, + 23,1,0,0,0,13,19,19,19,1,23,23,23,2,26,26,26,1,59,59, + 59,1,11,11,11,1,23,23,23,1,40,40,40,1,17,17,17,1,0,0, + 0,5,61,61,61,1,64,64,64,2,0,0,0,33,65,65,65,1,77,77, + 77,1,73,73,73,1,26,26,26,1,53,53,53,1,71,71,71,1,36,36, + 36,1,0,0,0,4,3,3,3,1,255,255,255,2,248,248,248,1,0,0, + 0,9,8,8,8,1,255,255,255,3,0,0,0,3,12,12,12,1,0,0, + 0,2,12,12,12,1,0,0,0,37,65,65,65,1,77,77,77,1,73,73, + 73,1,26,26,26,1,53,53,53,1,71,71,71,1,36,36,36,1,0,0, + 0,5,230,230,230,1,255,255,255,1,233,233,233,1,12,12,12,1,1,1, + 1,1,0,0,0,31,38,38,38,1,47,47,47,1,53,53,53,1,71,71, + 71,1,54,54,54,1,48,48,48,1,30,30,30,1,42,42,42,1,31,31, + 31,1,77,77,77,1,40,40,40,1,8,8,8,1,255,255,255,3,248,248, + 248,1,0,0,0,8,8,8,8,1,255,255,255,4,0,0,0,2,96,96, + 96,1,114,114,114,1,98,98,98,1,100,100,100,1,84,84,84,1,0,0, + 0,36,38,38,38,1,47,47,47,1,53,53,53,1,71,71,71,1,54,54, + 54,1,48,48,48,1,30,30,30,1,42,42,42,1,31,31,31,1,77,77, + 77,1,40,40,40,1,4,4,4,1,227,227,227,1,255,255,255,1,240,240, + 240,1,116,116,116,1,11,11,11,1,0,0,0,31,47,47,47,1,76,76, + 76,1,87,87,87,1,57,57,57,1,61,61,61,1,46,46,46,1,35,35, + 35,1,36,36,36,1,24,24,24,1,61,61,61,1,22,22,22,1,14,14, + 14,1,255,255,255,3,247,247,247,1,0,0,0,5,34,34,34,1,159,159, + 159,1,211,211,211,1,252,252,252,1,255,255,255,5,0,0,0,3,33,33, + 33,1,10,10,10,1,26,26,26,1,40,40,40,1,44,44,44,1,18,18, + 18,1,16,16,16,1,50,50,50,1,8,8,8,1,0,0,0,3,7,7, + 7,1,125,125,125,1,188,188,188,1,237,237,237,1,255,255,255,6,16,16, + 16,1,0,0,0,16,47,47,47,1,76,76,76,1,87,87,87,1,57,57, + 57,1,61,61,61,1,46,46,46,1,35,35,35,1,36,36,36,1,24,24, + 24,1,61,61,61,1,22,22,22,1,12,12,12,1,229,229,229,1,255,255, + 255,1,241,241,241,1,128,128,128,1,12,12,12,1,0,0,0,27,45,45, + 45,1,70,70,70,1,74,74,74,1,80,80,80,1,0,0,0,11,48,48, + 48,1,255,255,255,3,242,242,242,1,0,0,0,4,82,82,82,1,241,241, + 241,1,255,255,255,9,0,0,0,4,80,80,80,1,89,89,89,1,45,45, + 45,1,42,42,42,1,36,36,36,1,82,82,82,1,27,27,27,1,0,0, + 0,2,40,40,40,1,209,209,209,1,255,255,255,10,0,0,0,12,45,45, + 45,1,70,70,70,1,74,74,74,1,80,80,80,1,0,0,0,11,22,22, + 22,1,232,232,232,1,255,255,255,1,237,237,237,1,122,122,122,1,11,11, + 11,1,0,0,0,27,17,17,17,1,29,29,29,1,31,31,31,1,42,42, + 42,1,0,0,0,10,29,29,29,1,155,155,155,1,255,255,255,3,217,217, + 217,1,0,0,0,3,30,30,30,1,244,244,244,1,255,255,255,10,248,248, + 248,1,0,0,0,3,43,43,43,1,47,47,47,1,56,56,56,1,77,77, + 77,1,51,51,51,1,55,55,55,1,31,31,31,1,0,0,0,1,5,5, + 5,1,214,214,214,1,255,255,255,11,0,0,0,2,12,12,12,1,4,4, + 4,1,17,17,17,1,0,0,0,2,25,25,25,1,0,0,0,4,17,17, + 17,1,29,29,29,1,31,31,31,1,42,42,42,1,0,0,0,10,38,38, + 38,1,184,184,184,1,252,252,252,1,255,255,255,1,226,226,226,1,110,110, + 110,1,10,10,10,1,0,0,0,10,45,45,45,1,172,172,172,1,197,197, + 197,1,196,196,196,1,171,171,171,1,44,44,44,1,0,0,0,12,41,41, + 41,1,161,161,161,1,212,212,212,1,252,252,252,1,255,255,255,14,169,169, + 169,1,0,0,0,3,158,158,158,1,255,255,255,10,248,248,248,1,0,0, + 0,4,53,53,53,1,78,78,78,1,90,90,90,1,62,62,62,1,65,65, + 65,1,56,56,56,1,28,28,28,1,0,0,0,1,110,110,110,1,255,255, + 255,6,240,240,240,6,0,0,0,2,86,86,86,1,99,99,99,1,96,96, + 96,1,43,43,43,1,70,70,70,1,98,98,98,1,34,34,34,1,0,0, + 0,4,66,66,66,1,184,184,184,1,206,206,206,1,223,223,223,1,225,225, + 225,9,239,239,239,1,255,255,255,3,207,207,207,1,89,89,89,1,8,8, + 8,1,0,0,0,9,115,115,115,1,229,229,229,1,255,255,255,4,238,238, + 238,1,125,125,125,1,0,0,0,10,96,96,96,1,246,246,246,1,255,255, + 255,17,111,111,111,1,0,0,0,3,216,216,216,1,255,255,255,3,222,222, + 222,1,75,75,75,1,255,255,255,4,248,248,248,1,0,0,0,1,68,68, + 68,1,73,73,73,1,78,78,78,1,57,57,57,1,0,0,0,8,185,185, + 185,1,255,255,255,3,243,243,243,1,97,97,97,1,18,18,18,1,0,0, + 0,10,1,1,1,1,0,0,0,3,8,8,8,1,0,0,0,3,131,131, + 131,1,233,233,233,1,255,255,255,15,231,231,231,1,135,135,135,1,61,61, + 61,1,5,5,5,1,0,0,0,8,45,45,45,1,229,229,229,1,255,255, + 255,6,241,241,241,1,95,95,95,1,0,0,0,8,37,37,37,1,250,250, + 250,1,255,255,255,17,173,173,173,1,2,2,2,1,0,0,0,2,1,1, + 1,1,250,250,250,1,255,255,255,3,69,69,69,1,8,8,8,1,255,255, + 255,3,248,248,248,1,0,0,0,2,30,30,30,1,23,23,23,1,34,34, + 34,1,32,32,32,1,0,0,0,8,229,229,229,1,255,255,255,3,107,107, + 107,1,0,0,0,1,255,255,255,1,0,0,0,17,42,42,42,1,232,232, + 232,1,255,255,255,2,252,252,252,1,242,242,242,1,241,241,241,4,242,242, + 242,4,243,243,243,1,237,237,237,1,225,225,225,1,203,203,203,1,135,135, + 135,1,88,88,88,1,13,13,13,1,0,0,0,9,172,172,172,1,255,255, + 255,8,213,213,213,1,32,32,32,1,0,0,0,7,165,165,165,1,255,255, + 255,15,237,237,237,1,190,190,190,1,138,138,138,1,8,8,8,1,0,0, + 0,4,221,221,221,1,255,255,255,3,11,11,11,1,8,8,8,1,248,248, + 248,1,255,255,255,1,252,252,252,1,0,0,0,15,229,229,229,1,255,255, + 255,3,29,29,29,1,0,0,0,1,255,255,255,2,16,16,16,1,0,0, + 0,15,176,176,176,1,255,255,255,2,234,234,234,1,170,170,170,1,142,142, + 142,1,161,161,161,1,137,137,137,1,130,130,130,1,131,131,131,1,132,132, + 132,1,133,133,133,2,134,134,134,1,135,135,135,1,128,128,128,1,119,119, + 119,1,98,98,98,1,71,71,71,1,16,16,16,1,1,1,1,1,0,0, + 0,9,197,197,197,1,255,255,255,8,228,228,228,1,96,96,96,1,0,0, + 0,7,221,221,221,1,255,255,255,3,214,214,214,1,69,69,69,1,248,248, + 248,1,0,0,0,17,165,165,165,1,255,255,255,3,105,105,105,1,9,9, + 9,1,8,8,8,1,248,248,248,1,0,0,0,16,185,185,185,1,255,255, + 255,3,35,35,35,1,0,0,0,1,255,255,255,3,16,16,16,1,0,0, + 0,14,199,199,199,1,255,255,255,2,183,183,183,1,108,108,108,1,98,98, + 98,1,255,255,255,1,119,119,119,1,27,27,27,1,12,12,12,7,11,11, + 11,1,9,9,9,1,6,6,6,1,1,1,1,1,0,0,0,10,196,196, + 196,1,255,255,255,8,228,228,228,1,126,126,126,1,0,0,0,6,1,1, + 1,1,250,250,250,1,255,255,255,3,56,56,56,1,8,8,8,1,255,255, + 255,2,0,0,0,16,37,37,37,1,253,253,253,1,255,255,255,13,237,237, + 237,1,190,190,190,1,138,138,138,1,8,8,8,1,0,0,0,5,105,105, + 105,1,255,255,255,3,185,185,185,1,31,31,31,1,255,255,255,4,16,16, + 16,1,0,0,0,13,210,210,210,1,255,255,255,1,247,247,247,1,149,149, + 149,1,43,43,43,1,68,68,68,1,255,255,255,2,112,112,112,1,16,16, + 16,1,0,0,0,20,171,171,171,1,255,255,255,8,214,214,214,1,126,126, + 126,1,0,0,0,7,216,216,216,1,255,255,255,3,11,11,11,1,8,8, + 8,1,255,255,255,3,0,0,0,2,40,40,40,1,46,46,46,2,63,63, + 63,1,53,53,53,1,2,2,2,1,0,0,0,8,119,119,119,1,255,255, + 255,16,217,217,217,1,10,10,10,1,0,0,0,4,3,3,3,1,226,226, + 226,1,255,255,255,9,16,16,16,1,0,0,0,3,16,16,16,1,19,19, + 19,2,46,46,46,1,18,18,18,1,19,19,19,1,13,13,13,1,22,22, + 22,1,0,0,0,1,200,200,200,1,255,255,255,2,198,198,198,1,21,21, + 21,1,65,65,65,1,255,255,255,3,112,112,112,1,16,16,16,1,40,40, + 40,1,46,46,46,2,63,63,63,1,53,53,53,1,2,2,2,1,0,0, + 0,13,44,44,44,1,238,238,238,1,255,255,255,6,241,241,241,1,157,157, + 157,1,96,96,96,1,0,0,0,7,158,158,158,1,255,255,255,3,119,119, + 119,1,18,18,18,1,255,255,255,4,0,0,0,1,27,27,27,1,61,61, + 61,1,75,75,75,1,95,95,95,1,51,51,51,1,4,4,4,1,0,0, + 0,9,122,122,122,1,252,252,252,1,255,255,255,15,209,209,209,1,2,2, + 2,1,0,0,0,4,38,38,38,1,244,244,244,1,255,255,255,9,16,16, + 16,1,0,0,0,2,76,76,76,1,108,108,108,1,118,118,118,1,88,88, + 88,1,93,93,93,1,79,79,79,1,45,45,45,1,49,49,49,1,0,0, + 0,1,173,173,173,1,255,255,255,2,239,239,239,1,127,127,127,1,74,74, + 74,1,255,255,255,4,112,112,112,1,41,41,41,1,61,61,61,1,75,75, + 75,1,95,95,95,1,51,51,51,1,4,4,4,1,0,0,0,14,125,125, + 125,1,241,241,241,1,255,255,255,4,241,241,241,1,185,185,185,1,139,139, + 139,1,32,32,32,1,0,0,0,7,30,30,30,1,251,251,251,1,255,255, + 255,9,0,0,0,4,47,47,47,1,84,84,84,1,94,94,94,1,44,44, + 44,1,87,87,87,1,50,50,50,1,48,48,48,1,0,0,0,4,12,12, + 12,1,41,41,41,1,161,161,161,1,214,214,214,1,252,252,252,1,255,255, + 255,13,111,111,111,1,0,0,0,5,33,33,33,1,225,225,225,1,255,255, + 255,8,240,240,240,1,0,0,0,11,34,34,34,1,235,235,235,1,255,255, + 255,2,253,253,253,1,242,242,242,1,255,255,255,5,112,112,112,1,16,16, + 16,1,0,0,0,2,47,47,47,1,84,84,84,1,94,94,94,1,44,44, + 44,1,87,87,87,1,50,50,50,1,48,48,48,1,0,0,0,10,95,95, + 95,1,213,213,213,1,228,228,228,2,214,214,214,1,157,157,157,1,139,139, + 139,1,66,66,66,1,0,0,0,9,102,102,102,1,254,254,254,1,255,255, + 255,9,0,0,0,3,14,14,14,1,27,27,27,2,29,29,29,1,12,12, + 12,1,29,29,29,1,36,36,36,1,0,0,0,4,119,119,119,1,117,117, + 117,1,113,113,113,1,98,98,98,1,61,61,61,1,0,0,0,9,72,72, + 72,1,255,255,255,3,169,169,169,1,0,0,0,6,4,4,4,1,111,111, + 111,1,172,172,172,1,255,255,255,5,240,240,240,1,0,0,0,12,1,1, + 1,1,109,109,109,1,236,236,236,1,255,255,255,9,64,64,64,1,0,0, + 0,2,14,14,14,1,27,27,27,2,29,29,29,1,12,12,12,1,29,29, + 29,1,36,36,36,1,0,0,0,11,32,32,32,1,96,96,96,1,126,126, + 126,2,96,96,96,1,32,32,32,1,0,0,0,11,105,105,105,1,250,250, + 250,1,255,255,255,8,248,248,248,1,0,0,0,2,65,65,65,1,104,104, + 104,1,113,113,113,1,107,107,107,1,109,109,109,1,91,91,91,1,74,74, + 74,1,87,87,87,1,0,0,0,5,41,41,41,1,1,1,1,1,61,61, + 61,1,70,70,70,1,58,58,58,1,38,38,38,1,21,21,21,1,68,68, + 68,1,14,14,14,1,0,0,0,3,14,14,14,1,255,255,255,3,217,217, + 217,1,0,0,0,9,255,255,255,4,240,240,240,1,0,0,0,14,5,5, + 5,1,80,80,80,1,208,208,208,1,229,229,229,1,247,247,247,1,255,255, + 255,5,191,191,191,1,143,143,143,1,0,0,0,2,65,65,65,1,104,104, + 104,1,113,113,113,1,107,107,107,1,109,109,109,1,91,91,91,1,74,74, + 74,1,87,87,87,1,0,0,0,28,34,34,34,1,159,159,159,1,212,212, + 212,1,255,255,255,5,248,248,248,1,18,18,18,1,16,16,16,1,42,42, + 42,1,2,2,2,1,0,0,0,1,20,20,20,1,1,1,1,1,0,0, + 0,11,53,53,53,1,62,62,62,1,28,28,28,1,34,34,34,1,18,18, + 18,1,63,63,63,1,22,22,22,1,0,0,0,3,8,8,8,1,255,255, + 255,3,242,242,242,1,0,0,0,9,255,255,255,3,240,240,240,1,0,0, + 0,16,6,6,6,1,30,30,30,1,82,82,82,1,146,146,146,1,255,255, + 255,4,191,191,191,1,144,144,144,1,18,18,18,1,16,16,16,1,42,42, + 42,1,2,2,2,1,0,0,0,1,20,20,20,1,1,1,1,1,0,0, + 0,34,8,8,8,1,255,255,255,4,248,248,248,1,40,40,40,1,92,92, + 92,1,79,79,79,1,84,84,84,1,6,6,6,1,0,0,0,14,65,65, + 65,1,90,90,90,1,81,81,81,1,93,93,93,1,76,76,76,1,84,84, + 84,1,57,57,57,1,41,41,41,1,92,92,92,1,81,81,81,1,17,17, + 17,1,255,255,255,3,247,247,247,1,0,0,0,9,255,255,255,2,240,240, + 240,1,0,0,0,18,2,2,2,1,7,7,7,1,71,71,71,1,255,255, + 255,3,191,191,191,1,143,143,143,1,40,40,40,1,92,92,92,1,79,79, + 79,1,84,84,84,1,6,6,6,1,0,0,0,37,8,8,8,1,255,255, + 255,3,248,248,248,1,0,0,0,18,10,10,10,1,3,3,3,1,34,34, + 34,1,48,48,48,1,49,49,49,1,33,33,33,1,34,34,34,1,28,28, + 28,1,14,14,14,1,0,0,0,1,16,16,16,1,17,17,17,1,22,22, + 22,1,8,8,8,1,255,255,255,2,248,248,248,1,0,0,0,9,2,2, + 2,1,251,251,251,1,0,0,0,2,24,24,24,1,48,48,48,2,63,63, + 63,1,0,0,0,15,64,64,64,1,255,255,255,2,191,191,191,1,143,143, + 143,1,0,0,0,43,8,8,8,1,248,248,248,1,255,255,255,1,248,248, + 248,1,0,0,0,17,112,112,112,2,120,120,120,1,41,41,41,1,0,0, + 0,12,5,5,5,1,0,0,0,15,38,38,38,1,54,54,54,1,57,57, + 57,1,58,58,58,1,0,0,0,15,64,64,64,1,255,255,255,1,191,191, + 191,1,143,143,143,1,0,0,0,45,8,8,8,1,248,248,248,1,0,0, + 0,21,8,8,8,1,0,0,0,47,16,16,16,1,67,67,67,1,143,143, + 143,1,0,0,0,39,0,0,7,116,97,99,116,105,111,110,14,115,101,108, + 101,99,116,101,100,105,116,112,97,103,101,7,99,97,112,116,105,111,110,6, + 17,83,101,108,101,99,116,32,38,69,100,105,116,32,80,97,103,101,7,111, + 112,116,105,111,110,115,11,17,97,111,95,103,108,111,98,97,108,115,104,111, + 114,116,99,117,116,0,9,111,110,101,120,101,99,117,116,101,7,23,115,101, + 108,101,99,116,101,100,105,116,112,97,103,101,111,110,101,120,101,99,117,116, + 101,4,108,101,102,116,3,24,1,3,116,111,112,2,120,2,115,99,1,2, + 1,3,69,64,0,0,0,7,116,97,99,116,105,111,110,6,105,110,100,101, + 110,116,7,99,97,112,116,105,111,110,6,7,38,73,110,100,101,110,116,9, + 111,110,101,120,101,99,117,116,101,7,15,105,110,100,101,110,116,111,110,101, + 120,101,99,117,116,101,4,108,101,102,116,3,24,1,3,116,111,112,3,136, + 0,2,115,99,1,2,1,3,73,64,0,0,0,7,116,97,99,116,105,111, + 110,8,117,110,105,110,100,101,110,116,7,99,97,112,116,105,111,110,6,9, + 85,38,110,105,110,100,101,110,116,9,111,110,101,120,101,99,117,116,101,7, + 16,117,110,105,100,101,110,116,111,110,101,120,101,99,117,116,101,4,108,101, + 102,116,3,24,1,3,116,111,112,3,152,0,2,115,99,1,2,1,3,85, + 64,0,0,0,7,116,97,99,116,105,111,110,14,116,111,103,103,108,101,102, + 111,114,109,117,110,105,116,7,99,97,112,116,105,111,110,6,17,84,111,103, + 103,108,101,32,70,111,114,109,47,38,85,110,105,116,9,111,110,101,120,101, + 99,117,116,101,7,23,116,111,103,103,108,101,102,111,114,109,117,110,105,116, + 111,110,101,120,101,99,117,116,101,4,108,101,102,116,3,152,0,3,116,111, + 112,2,104,2,115,99,1,2,1,3,59,1,0,0,0,7,116,97,99,116, + 105,111,110,5,110,101,120,116,105,9,105,109,97,103,101,108,105,115,116,7, + 11,98,117,116,116,111,110,105,99,111,110,115,7,99,97,112,116,105,111,110, + 6,16,78,101,120,116,32,73,110,115,116,114,117,99,116,105,111,110,7,105, + 109,97,103,101,110,114,2,13,15,105,109,97,103,101,110,114,100,105,115,97, + 98,108,101,100,2,19,9,111,110,101,120,101,99,117,116,101,7,17,110,101, + 120,116,105,97,99,116,111,110,101,120,101,99,117,116,101,4,108,101,102,116, + 2,80,3,116,111,112,3,208,0,2,115,99,1,2,1,3,55,97,0,0, + 0,7,116,97,99,116,105,111,110,5,115,116,101,112,105,9,105,109,97,103, + 101,108,105,115,116,7,11,98,117,116,116,111,110,105,99,111,110,115,7,99, + 97,112,116,105,111,110,6,16,83,116,101,112,32,73,110,115,116,114,117,99, + 116,105,111,110,7,105,109,97,103,101,110,114,2,12,15,105,109,97,103,101, + 110,114,100,105,115,97,98,108,101,100,2,21,9,111,110,101,120,101,99,117, + 116,101,7,17,115,116,101,112,105,97,99,116,111,110,101,120,101,99,117,116, + 101,4,108,101,102,116,2,80,3,116,111,112,3,224,0,2,115,99,1,2, + 1,3,54,97,0,0,0,7,116,97,99,116,105,111,110,13,98,108,117,101, + 100,111,116,115,111,110,97,99,116,9,105,109,97,103,101,108,105,115,116,7, + 11,98,117,116,116,111,110,105,99,111,110,115,7,99,97,112,116,105,111,110, + 6,17,69,120,101,99,32,76,105,110,101,32,72,105,110,116,32,111,110,5, + 115,116,97,116,101,11,10,97,115,95,99,104,101,99,107,101,100,0,7,105, + 109,97,103,101,110,114,2,14,4,104,105,110,116,6,28,69,120,101,99,117, + 116,97,98,108,101,32,108,105,110,101,115,32,104,105,110,116,32,111,110,47, + 111,102,102,8,115,116,97,116,102,105,108,101,7,22,109,97,105,110,102,111, + 46,112,114,111,106,101,99,116,115,116,97,116,102,105,108,101,8,111,110,99, + 104,97,110,103,101,7,18,98,108,117,101,100,111,116,115,111,110,111,110,99, + 104,97,110,103,101,4,108,101,102,116,3,152,0,3,116,111,112,3,13,1, + 0,0,7,116,97,99,116,105,111,110,7,114,101,112,108,97,99,101,7,99, + 97,112,116,105,111,110,6,16,70,105,110,100,32,38,38,32,38,82,101,112, + 108,97,99,101,9,111,110,101,120,101,99,117,116,101,7,19,114,101,112,108, + 97,99,101,97,99,116,111,110,101,120,101,99,117,116,101,4,108,101,102,116, + 3,208,0,3,116,111,112,2,16,2,115,99,1,2,1,3,82,64,0,0, + 0,7,116,97,99,116,105,111,110,5,112,114,105,110,116,7,99,97,112,116, + 105,111,110,6,6,38,80,114,105,110,116,9,111,110,101,120,101,99,117,116, + 101,7,17,112,114,105,110,116,97,99,116,111,110,101,120,101,99,117,116,101, + 4,108,101,102,116,2,8,3,116,111,112,2,100,0,0,7,116,97,99,116, + 105,111,110,12,100,101,116,97,99,104,116,97,114,103,101,116,7,99,97,112, + 116,105,111,110,6,6,68,101,116,97,99,104,9,111,110,101,120,101,99,117, + 116,101,7,14,111,110,100,101,116,97,99,104,116,97,114,103,101,116,4,108, + 101,102,116,2,8,3,116,111,112,3,136,0,0,0,7,116,97,99,116,105, + 111,110,13,97,116,116,97,99,104,112,114,111,99,101,115,115,7,99,97,112, + 116,105,111,110,6,14,65,116,116,97,99,104,32,80,114,111,99,101,115,115, + 9,111,110,101,120,101,99,117,116,101,7,15,111,110,97,116,116,97,99,104, + 112,114,111,99,101,115,115,4,108,101,102,116,2,8,3,116,111,112,3,152, + 0,0,0,7,116,97,99,116,105,111,110,9,108,111,119,101,114,99,97,115, + 101,7,99,97,112,116,105,111,110,6,10,38,76,111,119,101,114,99,97,115, + 101,9,111,110,101,120,101,99,117,116,101,7,16,108,111,119,101,114,99,97, + 115,101,101,120,101,99,117,116,101,8,111,110,117,112,100,97,116,101,7,14, + 101,110,97,98,108,101,111,110,115,101,108,101,99,116,4,108,101,102,116,3, + 104,1,3,116,111,112,3,136,0,0,0,7,116,97,99,116,105,111,110,9, + 117,112,112,101,114,99,97,115,101,7,99,97,112,116,105,111,110,6,10,38, + 85,112,112,101,114,99,97,115,101,9,111,110,101,120,101,99,117,116,101,7, + 16,117,112,112,101,114,99,97,115,101,101,120,101,99,117,116,101,8,111,110, + 117,112,100,97,116,101,7,14,101,110,97,98,108,101,111,110,115,101,108,101, + 99,116,4,108,101,102,116,3,104,1,3,116,111,112,3,152,0,0,0,19, + 116,115,104,111,114,116,99,117,116,99,111,110,116,114,111,108,108,101,114,9, + 115,104,111,114,116,99,117,116,115,13,97,99,116,105,111,110,115,46,99,111, + 117,110,116,2,98,13,97,99,116,105,111,110,115,46,105,116,101,109,115,14, + 1,8,100,105,115,112,110,97,109,101,6,4,70,105,108,101,0,1,6,97, + 99,116,105,111,110,7,10,111,112,101,110,115,111,117,114,99,101,8,100,105, + 115,112,110,97,109,101,6,4,79,112,101,110,2,115,99,1,2,1,3,79, + 64,0,0,1,6,97,99,116,105,111,110,7,4,115,97,118,101,8,100,105, + 115,112,110,97,109,101,6,4,83,97,118,101,2,115,99,1,2,1,3,83, + 64,0,0,1,6,97,99,116,105,111,110,7,7,115,97,118,101,97,108,108, + 8,100,105,115,112,110,97,109,101,6,8,83,97,118,101,32,97,108,108,0, + 1,6,97,99,116,105,111,110,7,6,115,97,118,101,97,115,8,100,105,115, + 112,110,97,109,101,6,7,83,97,118,101,32,97,115,0,1,6,97,99,116, + 105,111,110,7,5,99,108,111,115,101,8,100,105,115,112,110,97,109,101,6, + 5,67,108,111,115,101,2,115,99,1,2,1,3,51,65,0,0,1,6,97, + 99,116,105,111,110,7,8,99,108,111,115,101,97,108,108,8,100,105,115,112, + 110,97,109,101,6,9,67,108,111,115,101,32,97,108,108,0,1,6,97,99, + 116,105,111,110,7,5,112,114,105,110,116,8,100,105,115,112,110,97,109,101, + 6,5,80,114,105,110,116,0,1,8,100,105,115,112,110,97,109,101,6,6, + 83,101,97,114,99,104,0,1,6,97,99,116,105,111,110,7,4,108,105,110, + 101,8,100,105,115,112,110,97,109,101,6,4,76,105,110,101,2,115,99,1, + 2,1,3,76,64,0,0,1,6,97,99,116,105,111,110,7,4,102,105,110, + 100,8,100,105,115,112,110,97,109,101,6,4,70,105,110,100,2,115,99,1, + 2,1,3,70,64,0,0,1,6,97,99,116,105,111,110,7,10,114,101,112, + 101,97,116,102,105,110,100,8,100,105,115,112,110,97,109,101,6,12,83,101, + 97,114,99,104,32,97,103,97,105,110,2,115,99,1,2,1,3,50,1,0, + 0,1,6,97,99,116,105,111,110,7,8,102,105,110,100,98,97,99,107,8, + 100,105,115,112,110,97,109,101,6,11,83,101,97,114,99,104,32,98,97,99, + 107,2,115,99,1,2,1,3,50,33,0,0,1,6,97,99,116,105,111,110, + 7,7,114,101,112,108,97,99,101,8,100,105,115,112,110,97,109,101,6,16, + 70,105,110,100,32,97,110,100,32,114,101,112,108,97,99,101,2,115,99,1, + 2,1,3,82,64,0,0,1,6,97,99,116,105,111,110,7,10,102,105,110, + 100,105,110,102,105,108,101,8,100,105,115,112,110,97,109,101,6,12,70,105, + 110,100,32,105,110,32,70,105,108,101,2,115,99,1,2,1,3,70,96,0, + 0,1,8,100,105,115,112,110,97,109,101,6,4,69,100,105,116,0,1,6, + 97,99,116,105,111,110,7,14,115,101,108,101,99,116,101,100,105,116,112,97, + 103,101,8,100,105,115,112,110,97,109,101,6,15,83,101,108,101,99,116,32, + 69,100,105,116,112,97,103,101,2,115,99,1,2,1,3,69,64,0,0,1, + 6,97,99,116,105,111,110,7,8,99,111,112,121,119,111,114,100,8,100,105, + 115,112,110,97,109,101,6,19,67,111,112,121,32,87,111,114,100,32,97,116, + 32,67,117,114,115,111,114,2,115,99,1,2,1,3,87,96,0,0,1,6, + 97,99,116,105,111,110,7,6,105,110,100,101,110,116,8,100,105,115,112,110, + 97,109,101,6,6,73,110,100,101,110,116,2,115,99,1,2,1,3,73,64, + 0,0,1,6,97,99,116,105,111,110,7,8,117,110,105,110,100,101,110,116, + 8,100,105,115,112,110,97,109,101,6,8,85,110,105,110,100,101,110,116,2, + 115,99,1,2,1,3,85,64,0,0,1,6,97,99,116,105,111,110,7,7, + 99,111,109,109,101,110,116,8,100,105,115,112,110,97,109,101,6,17,67,111, + 109,109,101,110,116,32,83,101,108,101,99,116,105,111,110,2,115,99,1,2, + 2,3,75,64,2,67,0,0,1,6,97,99,116,105,111,110,7,9,117,110, + 99,111,109,109,101,110,116,8,100,105,115,112,110,97,109,101,6,19,85,110, + 99,111,109,109,101,110,116,32,83,101,108,101,99,116,105,111,110,2,115,99, + 1,2,2,3,75,64,2,85,0,0,1,6,97,99,116,105,111,110,7,9, + 108,111,119,101,114,99,97,115,101,8,100,105,115,112,110,97,109,101,6,9, + 76,111,119,101,114,99,97,115,101,0,1,6,97,99,116,105,111,110,7,9, + 117,112,112,101,114,99,97,115,101,8,100,105,115,112,110,97,109,101,6,9, + 85,112,112,101,114,99,97,115,101,0,1,6,97,99,116,105,111,110,7,12, + 99,111,112,121,108,97,116,101,120,97,99,116,8,100,105,115,112,110,97,109, + 101,6,10,67,111,112,121,32,76,97,84,101,88,2,115,99,1,2,2,3, + 75,64,2,76,0,0,1,6,97,99,116,105,111,110,7,25,115,111,117,114, + 99,101,102,111,46,99,111,109,112,108,101,116,101,99,108,97,115,115,97,99, + 116,8,100,105,115,112,110,97,109,101,6,14,67,111,109,112,108,101,116,101, + 32,67,108,97,115,115,2,115,99,1,2,1,3,65,96,0,0,1,6,97, + 99,116,105,111,110,7,11,105,110,115,116,101,109,112,108,97,116,101,8,100, + 105,115,112,110,97,109,101,6,15,73,110,115,101,114,116,32,84,101,109,112, + 108,97,116,101,2,115,99,1,2,1,3,84,64,0,0,1,6,97,99,116, + 105,111,110,7,21,115,111,117,114,99,101,102,111,46,110,97,118,105,103,98, + 97,99,107,97,99,116,8,100,105,115,112,110,97,109,101,6,13,78,97,118, + 105,103,97,116,101,32,66,97,99,107,2,115,99,1,2,1,3,72,64,0, + 0,1,6,97,99,116,105,111,110,7,24,115,111,117,114,99,101,102,111,46, + 110,97,118,105,103,102,111,114,119,97,114,100,97,99,116,8,100,105,115,112, + 110,97,109,101,6,16,78,97,118,105,103,97,116,101,32,70,111,114,119,97, + 114,100,2,115,99,1,2,1,3,72,96,0,0,1,8,100,105,115,112,110, + 97,109,101,6,12,83,101,116,32,66,111,111,107,109,97,114,107,0,1,6, + 97,99,116,105,111,110,7,6,115,101,116,98,109,48,8,100,105,115,112,110, + 97,109,101,6,14,83,101,116,32,66,111,111,107,109,97,114,107,32,48,2, + 115,99,1,2,1,3,48,96,0,0,1,6,97,99,116,105,111,110,7,6, + 115,101,116,98,109,49,8,100,105,115,112,110,97,109,101,6,14,83,101,116, + 32,66,111,111,107,109,97,114,107,32,49,2,115,99,1,2,1,3,49,96, + 0,0,1,6,97,99,116,105,111,110,7,6,115,101,116,98,109,50,8,100, + 105,115,112,110,97,109,101,6,14,83,101,116,32,66,111,111,107,109,97,114, + 107,32,50,2,115,99,1,2,1,3,50,96,0,0,1,6,97,99,116,105, + 111,110,7,6,115,101,116,98,109,51,8,100,105,115,112,110,97,109,101,6, + 14,83,101,116,32,66,111,111,107,109,97,114,107,32,51,2,115,99,1,2, + 1,3,51,96,0,0,1,6,97,99,116,105,111,110,7,6,115,101,116,98, + 109,52,8,100,105,115,112,110,97,109,101,6,14,83,101,116,32,66,111,111, + 107,109,97,114,107,32,52,2,115,99,1,2,1,3,52,96,0,0,1,6, + 97,99,116,105,111,110,7,6,115,101,116,98,109,53,8,100,105,115,112,110, + 97,109,101,6,14,83,101,116,32,66,111,111,107,109,97,114,107,32,53,2, + 115,99,1,2,1,3,53,96,0,0,1,6,97,99,116,105,111,110,7,6, + 115,101,116,98,109,54,8,100,105,115,112,110,97,109,101,6,14,83,101,116, + 32,66,111,111,107,109,97,114,107,32,54,2,115,99,1,2,1,3,54,96, + 0,0,1,6,97,99,116,105,111,110,7,6,115,101,116,98,109,55,8,100, + 105,115,112,110,97,109,101,6,14,83,101,116,32,66,111,111,107,109,97,114, + 107,32,55,2,115,99,1,2,1,3,55,96,0,0,1,6,97,99,116,105, + 111,110,7,6,115,101,116,98,109,56,8,100,105,115,112,110,97,109,101,6, + 14,83,101,116,32,66,111,111,107,109,97,114,107,32,56,2,115,99,1,2, + 1,3,56,96,0,0,1,6,97,99,116,105,111,110,7,6,115,101,116,98, + 109,57,8,100,105,115,112,110,97,109,101,6,14,83,101,116,32,66,111,111, + 107,109,97,114,107,32,57,2,115,99,1,2,1,3,57,96,0,0,1,6, + 97,99,116,105,111,110,7,9,115,101,116,98,109,110,111,110,101,8,100,105, + 115,112,110,97,109,101,6,14,67,108,101,97,114,32,66,111,111,107,109,97, + 114,107,0,1,8,100,105,115,112,110,97,109,101,6,13,70,105,110,100,32, + 66,111,111,107,109,97,114,107,0,1,6,97,99,116,105,111,110,7,7,102, + 105,110,100,98,109,48,8,100,105,115,112,110,97,109,101,6,15,70,105,110, + 100,32,66,111,111,107,109,97,114,107,32,48,2,115,99,1,2,1,3,48, + 64,0,0,1,6,97,99,116,105,111,110,7,7,102,105,110,100,98,109,49, + 8,100,105,115,112,110,97,109,101,6,15,70,105,110,100,32,66,111,111,107, + 109,97,114,107,32,49,2,115,99,1,2,1,3,49,64,0,0,1,6,97, + 99,116,105,111,110,7,7,102,105,110,100,98,109,50,8,100,105,115,112,110, + 97,109,101,6,15,70,105,110,100,32,66,111,111,107,109,97,114,107,32,50, + 2,115,99,1,2,1,3,50,64,0,0,1,6,97,99,116,105,111,110,7, + 7,102,105,110,100,98,109,51,8,100,105,115,112,110,97,109,101,6,15,70, + 105,110,100,32,66,111,111,107,109,97,114,107,32,51,2,115,99,1,2,1, + 3,51,64,0,0,1,6,97,99,116,105,111,110,7,7,102,105,110,100,98, + 109,52,8,100,105,115,112,110,97,109,101,6,15,70,105,110,100,32,66,111, + 111,107,109,97,114,107,32,52,2,115,99,1,2,1,3,52,64,0,0,1, + 6,97,99,116,105,111,110,7,7,102,105,110,100,98,109,53,8,100,105,115, + 112,110,97,109,101,6,15,70,105,110,100,32,66,111,111,107,109,97,114,107, + 32,53,2,115,99,1,2,1,3,53,64,0,0,1,6,97,99,116,105,111, + 110,7,7,102,105,110,100,98,109,54,8,100,105,115,112,110,97,109,101,6, + 15,70,105,110,100,32,66,111,111,107,109,97,114,107,32,54,2,115,99,1, + 2,1,3,54,64,0,0,1,6,97,99,116,105,111,110,7,7,102,105,110, + 100,98,109,55,8,100,105,115,112,110,97,109,101,6,15,70,105,110,100,32, + 66,111,111,107,109,97,114,107,32,55,2,115,99,1,2,1,3,55,64,0, + 0,1,6,97,99,116,105,111,110,7,7,102,105,110,100,98,109,56,8,100, + 105,115,112,110,97,109,101,6,15,70,105,110,100,32,66,111,111,107,109,97, + 114,107,32,56,2,115,99,1,2,1,3,56,64,0,0,1,6,97,99,116, + 105,111,110,7,7,102,105,110,100,98,109,57,8,100,105,115,112,110,97,109, + 101,6,15,70,105,110,100,32,66,111,111,107,109,97,114,107,32,57,2,115, + 99,1,2,1,3,57,64,0,0,1,8,100,105,115,112,110,97,109,101,6, + 6,84,97,114,103,101,116,0,1,6,97,99,116,105,111,110,7,13,97,116, + 116,97,99,104,112,114,111,99,101,115,115,8,100,105,115,112,110,97,109,101, + 6,14,65,116,116,97,99,104,32,80,114,111,99,101,115,115,0,1,6,97, + 99,116,105,111,110,7,12,100,101,116,97,99,104,116,97,114,103,101,116,8, + 100,105,115,112,110,97,109,101,6,13,68,101,116,97,99,104,32,84,97,114, + 103,101,116,0,1,6,97,99,116,105,111,110,7,8,99,111,110,116,105,110, + 117,101,8,100,105,115,112,110,97,109,101,6,8,67,111,110,116,105,110,117, + 101,2,115,99,1,2,1,3,56,1,0,0,1,6,97,99,116,105,111,110, + 7,5,114,101,115,101,116,8,100,105,115,112,110,97,109,101,6,5,82,101, + 115,101,116,0,1,6,97,99,116,105,111,110,7,9,105,110,116,101,114,114, + 117,112,116,8,100,105,115,112,110,97,109,101,6,9,73,110,116,101,114,114, + 117,112,116,0,1,6,97,99,116,105,111,110,7,4,110,101,120,116,8,100, + 105,115,112,110,97,109,101,6,4,78,101,120,116,2,115,99,1,2,1,3, + 55,1,0,0,1,6,97,99,116,105,111,110,7,5,110,101,120,116,105,8, + 100,105,115,112,110,97,109,101,6,16,78,101,120,116,32,73,110,115,116,114, + 117,99,116,105,111,110,2,115,99,1,2,1,3,55,97,0,0,1,6,97, + 99,116,105,111,110,7,4,115,116,101,112,8,100,105,115,112,110,97,109,101, + 6,4,83,116,101,112,2,115,99,1,2,1,3,54,1,0,0,1,6,97, + 99,116,105,111,110,7,5,115,116,101,112,105,8,100,105,115,112,110,97,109, + 101,6,16,83,116,101,112,32,73,110,115,116,114,117,99,116,105,111,110,2, + 115,99,1,2,1,3,54,97,0,0,1,6,97,99,116,105,111,110,7,6, + 102,105,110,105,115,104,8,100,105,115,112,110,97,109,101,6,6,70,105,110, + 105,115,104,2,115,99,1,2,1,3,54,33,0,0,1,6,97,99,116,105, + 111,110,7,10,98,107,112,116,115,111,110,97,99,116,8,100,105,115,112,110, + 97,109,101,6,18,66,114,101,97,107,112,111,105,110,116,115,32,111,110,47, + 111,102,102,2,115,99,1,2,1,3,66,64,0,0,1,6,97,99,116,105, + 111,110,7,10,116,111,103,103,108,101,98,107,112,116,8,100,105,115,112,110, + 97,109,101,6,17,84,111,103,103,108,101,32,66,114,101,97,107,112,111,105, + 110,116,2,115,99,1,2,1,3,52,1,0,0,1,6,97,99,116,105,111, + 110,7,16,116,111,103,103,108,101,98,107,112,116,101,110,97,98,108,101,8, + 100,105,115,112,110,97,109,101,6,25,84,111,103,103,108,101,32,66,114,101, + 97,107,112,111,105,110,116,32,101,110,97,98,108,101,100,2,115,99,1,2, + 1,3,52,33,0,0,1,6,97,99,116,105,111,110,7,12,119,97,116,99, + 104,101,115,111,110,97,99,116,8,100,105,115,112,110,97,109,101,6,14,87, + 97,116,99,104,101,115,32,111,110,47,111,102,102,2,115,99,1,2,1,3, + 87,64,0,0,1,6,97,99,116,105,111,110,7,13,98,108,117,101,100,111, + 116,115,111,110,97,99,116,8,100,105,115,112,110,97,109,101,6,22,69,120, + 101,99,32,76,105,110,101,32,72,105,110,116,115,32,111,110,47,111,102,102, + 0,1,8,100,105,115,112,110,97,109,101,6,4,86,105,101,119,0,1,6, + 97,99,116,105,111,110,7,15,116,111,103,103,108,101,105,110,115,112,101,99, + 116,111,114,8,100,105,115,112,110,97,109,101,6,28,84,111,103,103,108,101, + 32,70,111,114,109,47,79,98,106,101,99,116,32,73,110,115,112,101,99,116, + 111,114,2,115,99,1,2,1,3,58,1,0,0,1,6,97,99,116,105,111, + 110,7,14,116,111,103,103,108,101,102,111,114,109,117,110,105,116,8,100,105, + 115,112,110,97,109,101,6,16,84,111,103,103,108,101,32,70,111,114,109,47, + 85,110,105,116,2,115,99,1,2,1,3,59,1,0,0,1,8,100,105,115, + 112,110,97,109,101,6,7,80,114,111,106,101,99,116,0,1,6,97,99,116, + 105,111,110,7,7,109,97,107,101,97,99,116,8,100,105,115,112,110,97,109, + 101,6,4,77,97,107,101,0,1,6,97,99,116,105,111,110,7,8,98,117, + 105,108,100,97,99,116,8,100,105,115,112,110,97,109,101,6,5,66,117,105, + 108,100,0,1,6,97,99,116,105,111,110,7,8,109,97,107,101,49,97,99, + 116,8,100,105,115,112,110,97,109,101,6,6,77,97,107,101,32,49,0,1, + 6,97,99,116,105,111,110,7,8,109,97,107,101,50,97,99,116,8,100,105, + 115,112,110,97,109,101,6,6,77,97,107,101,32,50,0,1,6,97,99,116, + 105,111,110,7,8,109,97,107,101,51,97,99,116,8,100,105,115,112,110,97, + 109,101,6,6,77,97,107,101,32,51,0,1,6,97,99,116,105,111,110,7, + 8,109,97,107,101,52,97,99,116,8,100,105,115,112,110,97,109,101,6,6, + 77,97,107,101,32,52,0,1,6,97,99,116,105,111,110,7,12,97,98,111, + 114,116,109,97,107,101,97,99,116,8,100,105,115,112,110,97,109,101,6,10, + 65,98,111,114,116,32,77,97,107,101,0,1,6,97,99,116,105,111,110,7, + 17,112,114,111,106,101,99,116,111,112,116,105,111,110,115,97,99,116,8,100, + 105,115,112,110,97,109,101,6,7,79,112,116,105,111,110,115,0,1,6,97, + 99,116,105,111,110,7,14,112,114,111,106,101,99,116,111,112,101,110,97,99, + 116,8,100,105,115,112,110,97,109,101,6,4,79,112,101,110,0,1,6,97, + 99,116,105,111,110,7,14,112,114,111,106,101,99,116,115,97,118,101,97,99, + 116,8,100,105,115,112,110,97,109,101,6,4,83,97,118,101,0,1,6,97, + 99,116,105,111,110,7,14,112,114,111,106,101,99,116,116,114,101,101,97,99, + 116,8,100,105,115,112,110,97,109,101,6,4,84,114,101,101,0,1,6,97, + 99,116,105,111,110,7,16,112,114,111,106,101,99,116,115,111,117,114,99,101, + 97,99,116,8,100,105,115,112,110,97,109,101,6,6,83,111,117,114,99,101, + 0,1,6,97,99,116,105,111,110,7,15,112,114,111,106,101,99,116,99,108, + 111,115,101,97,99,116,8,100,105,115,112,110,97,109,101,6,5,67,108,111, + 115,101,0,1,8,100,105,115,112,110,97,109,101,6,4,72,101,108,112,0, + 1,6,97,99,116,105,111,110,7,7,104,101,108,112,97,99,116,8,100,105, + 115,112,110,97,109,101,6,4,72,101,108,112,2,115,99,1,2,1,3,48, + 1,0,0,1,8,100,105,115,112,110,97,109,101,6,5,84,111,111,108,115, + 0,1,6,97,99,116,105,111,110,7,5,116,111,111,108,48,8,100,105,115, + 112,110,97,109,101,6,6,84,111,111,108,32,49,0,1,6,97,99,116,105, + 111,110,7,5,116,111,111,108,49,8,100,105,115,112,110,97,109,101,6,6, + 84,111,111,108,32,50,0,1,6,97,99,116,105,111,110,7,5,116,111,111, + 108,50,8,100,105,115,112,110,97,109,101,6,6,84,111,111,108,32,51,0, + 1,6,97,99,116,105,111,110,7,5,116,111,111,108,51,8,100,105,115,112, + 110,97,109,101,6,6,84,111,111,108,32,52,0,1,6,97,99,116,105,111, + 110,7,5,116,111,111,108,52,8,100,105,115,112,110,97,109,101,6,6,84, + 111,111,108,32,53,0,1,6,97,99,116,105,111,110,7,5,116,111,111,108, + 53,8,100,105,115,112,110,97,109,101,6,6,84,111,111,108,32,54,0,1, + 6,97,99,116,105,111,110,7,5,116,111,111,108,54,8,100,105,115,112,110, + 97,109,101,6,6,84,111,111,108,32,55,0,1,6,97,99,116,105,111,110, + 7,5,116,111,111,108,55,8,100,105,115,112,110,97,109,101,6,6,84,111, + 111,108,32,56,0,1,6,97,99,116,105,111,110,7,5,116,111,111,108,56, + 8,100,105,115,112,110,97,109,101,6,6,84,111,111,108,32,57,0,1,6, + 97,99,116,105,111,110,7,5,116,111,111,108,57,8,100,105,115,112,110,97, + 109,101,6,7,84,111,111,108,32,49,48,0,0,18,115,121,115,115,104,111, + 114,116,99,117,116,115,46,99,111,117,110,116,2,11,18,115,121,115,115,104, + 111,114,116,99,117,116,115,46,105,116,101,109,115,1,3,67,64,3,86,64, + 3,88,64,3,65,64,3,6,65,3,6,97,3,7,65,3,67,96,3,86, + 96,3,90,64,3,90,96,0,19,115,121,115,115,104,111,114,116,99,117,116, + 115,49,46,99,111,117,110,116,2,11,19,115,121,115,115,104,111,114,116,99, + 117,116,115,49,46,105,116,101,109,115,1,2,0,3,6,33,3,7,33,2, + 0,2,0,2,0,2,0,2,0,2,0,2,0,2,0,0,24,97,115,115, + 105,115,116,105,118,101,115,104,111,114,116,99,117,116,115,46,99,111,117,110, + 116,2,9,24,97,115,115,105,115,116,105,118,101,115,104,111,114,116,99,117, + 116,115,46,105,116,101,109,115,1,1,3,32,64,0,1,3,32,96,0,1, + 3,89,64,2,70,0,1,3,89,64,2,76,0,1,3,89,64,2,67,0, + 1,3,45,72,0,1,3,43,72,0,1,3,45,104,0,1,3,43,104,0, + 0,25,97,115,115,105,115,116,105,118,101,115,104,111,114,116,99,117,116,115, + 49,46,99,111,117,110,116,2,9,25,97,115,115,105,115,116,105,118,101,115, + 104,111,114,116,99,117,116,115,49,46,105,116,101,109,115,1,1,3,4,73, + 0,1,3,4,105,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0, + 0,8,115,116,97,116,102,105,108,101,7,19,109,97,105,110,102,111,46,109, + 97,105,110,115,116,97,116,102,105,108,101,13,111,110,97,102,116,101,114,117, + 112,100,97,116,101,7,15,117,112,100,97,116,101,115,104,111,114,116,99,117, + 116,115,4,108,101,102,116,3,96,1,3,116,111,112,2,8,0,0,7,116, + 97,99,116,105,111,110,15,116,111,103,103,108,101,105,110,115,112,101,99,116, + 111,114,7,99,97,112,116,105,111,110,6,21,84,111,103,103,108,101,32,70, + 111,114,109,47,73,110,115,112,101,99,116,111,114,4,108,101,102,116,3,152, + 0,3,116,111,112,2,120,2,115,99,1,2,1,3,58,1,0,0,0,7, + 116,97,99,116,105,111,110,8,98,117,105,108,100,97,99,116,9,111,110,101, + 120,101,99,117,116,101,7,16,109,97,107,101,97,99,116,111,110,101,120,101, + 99,117,116,101,4,108,101,102,116,2,8,3,116,111,112,3,56,1,0,0, + 7,116,97,99,116,105,111,110,8,109,97,107,101,49,97,99,116,9,111,110, + 101,120,101,99,117,116,101,7,16,109,97,107,101,97,99,116,111,110,101,120, + 101,99,117,116,101,4,108,101,102,116,2,8,3,116,111,112,3,74,1,0, + 0,7,116,97,99,116,105,111,110,8,109,97,107,101,50,97,99,116,9,111, + 110,101,120,101,99,117,116,101,7,16,109,97,107,101,97,99,116,111,110,101, + 120,101,99,117,116,101,4,108,101,102,116,2,8,3,116,111,112,3,92,1, + 0,0,7,116,97,99,116,105,111,110,8,109,97,107,101,51,97,99,116,9, + 111,110,101,120,101,99,117,116,101,7,16,109,97,107,101,97,99,116,111,110, + 101,120,101,99,117,116,101,4,108,101,102,116,2,8,3,116,111,112,3,110, + 1,0,0,7,116,97,99,116,105,111,110,8,109,97,107,101,52,97,99,116, + 9,111,110,101,120,101,99,117,116,101,7,16,109,97,107,101,97,99,116,111, + 110,101,120,101,99,117,116,101,4,108,101,102,116,2,8,3,116,111,112,3, + 128,1,0,0,7,116,97,99,116,105,111,110,8,100,111,119,110,108,111,97, + 100,7,99,97,112,116,105,111,110,6,8,68,111,119,110,108,111,97,100,9, + 111,110,101,120,101,99,117,116,101,7,11,100,111,119,110,108,111,97,100,101, + 120,101,4,108,101,102,116,2,8,3,116,111,112,3,168,0,0,0,7,116, + 97,99,116,105,111,110,7,104,101,108,112,97,99,116,7,111,112,116,105,111, + 110,115,11,17,97,111,95,103,108,111,98,97,108,115,104,111,114,116,99,117, + 116,0,9,111,110,101,120,101,99,117,116,101,7,6,104,101,108,112,101,120, + 4,108,101,102,116,3,24,1,3,116,111,112,3,144,1,2,115,99,1,2, + 1,3,48,1,0,0,0,7,116,97,99,116,105,111,110,12,97,116,116,97, + 99,104,116,97,114,103,101,116,7,99,97,112,116,105,111,110,6,13,65,116, + 116,97,99,104,32,84,97,114,103,101,116,9,111,110,101,120,101,99,117,116, + 101,7,14,111,110,97,116,116,97,99,104,116,97,114,103,101,116,4,108,101, + 102,116,2,8,3,116,111,112,2,120,0,0,7,116,97,99,116,105,111,110, + 6,115,101,116,98,109,48,7,99,97,112,116,105,111,110,6,11,66,111,111, + 107,109,97,114,107,32,38,48,9,111,110,101,120,101,99,117,116,101,7,9, + 115,101,116,98,109,101,120,101,99,4,108,101,102,116,3,24,1,3,116,111, + 112,3,208,0,2,115,99,1,2,1,3,48,96,0,0,0,7,116,97,99, + 116,105,111,110,7,102,105,110,100,98,109,48,7,99,97,112,116,105,111,110, + 6,11,66,111,111,107,109,97,114,107,32,38,48,9,111,110,101,120,101,99, + 117,116,101,7,10,102,105,110,100,98,109,101,120,101,99,4,108,101,102,116, + 3,104,1,3,116,111,112,3,208,0,2,115,99,1,2,1,3,48,64,0, + 0,0,7,116,97,99,116,105,111,110,7,102,105,110,100,98,109,49,7,99, + 97,112,116,105,111,110,6,11,66,111,111,107,109,97,114,107,32,38,49,9, + 116,97,103,97,99,116,105,111,110,2,1,9,111,110,101,120,101,99,117,116, + 101,7,10,102,105,110,100,98,109,101,120,101,99,4,108,101,102,116,3,104, + 1,3,116,111,112,3,224,0,2,115,99,1,2,1,3,49,64,0,0,0, + 7,116,97,99,116,105,111,110,6,115,101,116,98,109,49,7,99,97,112,116, + 105,111,110,6,11,66,111,111,107,109,97,114,107,32,38,49,9,116,97,103, + 97,99,116,105,111,110,2,1,9,111,110,101,120,101,99,117,116,101,7,9, + 115,101,116,98,109,101,120,101,99,4,108,101,102,116,3,24,1,3,116,111, + 112,3,224,0,2,115,99,1,2,1,3,49,96,0,0,0,7,116,97,99, + 116,105,111,110,7,102,105,110,100,98,109,50,7,99,97,112,116,105,111,110, + 6,11,66,111,111,107,109,97,114,107,32,38,50,9,116,97,103,97,99,116, + 105,111,110,2,2,9,111,110,101,120,101,99,117,116,101,7,10,102,105,110, + 100,98,109,101,120,101,99,4,108,101,102,116,3,104,1,3,116,111,112,3, + 240,0,2,115,99,1,2,1,3,50,64,0,0,0,7,116,97,99,116,105, + 111,110,6,115,101,116,98,109,50,7,99,97,112,116,105,111,110,6,11,66, + 111,111,107,109,97,114,107,32,38,50,9,116,97,103,97,99,116,105,111,110, + 2,2,9,111,110,101,120,101,99,117,116,101,7,9,115,101,116,98,109,101, + 120,101,99,4,108,101,102,116,3,24,1,3,116,111,112,3,240,0,2,115, + 99,1,2,1,3,50,96,0,0,0,7,116,97,99,116,105,111,110,7,102, + 105,110,100,98,109,51,7,99,97,112,116,105,111,110,6,11,66,111,111,107, + 109,97,114,107,32,38,51,9,116,97,103,97,99,116,105,111,110,2,3,9, + 111,110,101,120,101,99,117,116,101,7,10,102,105,110,100,98,109,101,120,101, + 99,4,108,101,102,116,3,104,1,3,116,111,112,3,0,1,2,115,99,1, + 2,1,3,51,64,0,0,0,7,116,97,99,116,105,111,110,6,115,101,116, + 98,109,51,7,99,97,112,116,105,111,110,6,11,66,111,111,107,109,97,114, + 107,32,38,51,9,116,97,103,97,99,116,105,111,110,2,3,9,111,110,101, + 120,101,99,117,116,101,7,9,115,101,116,98,109,101,120,101,99,4,108,101, + 102,116,3,24,1,3,116,111,112,3,0,1,2,115,99,1,2,1,3,51, + 96,0,0,0,7,116,97,99,116,105,111,110,7,102,105,110,100,98,109,52, + 7,99,97,112,116,105,111,110,6,11,66,111,111,107,109,97,114,107,32,38, + 52,9,116,97,103,97,99,116,105,111,110,2,4,9,111,110,101,120,101,99, + 117,116,101,7,10,102,105,110,100,98,109,101,120,101,99,4,108,101,102,116, + 3,104,1,3,116,111,112,3,16,1,2,115,99,1,2,1,3,52,64,0, + 0,0,7,116,97,99,116,105,111,110,6,115,101,116,98,109,52,7,99,97, + 112,116,105,111,110,6,11,66,111,111,107,109,97,114,107,32,38,52,9,116, + 97,103,97,99,116,105,111,110,2,4,9,111,110,101,120,101,99,117,116,101, + 7,9,115,101,116,98,109,101,120,101,99,4,108,101,102,116,3,24,1,3, + 116,111,112,3,16,1,2,115,99,1,2,1,3,52,96,0,0,0,7,116, + 97,99,116,105,111,110,7,102,105,110,100,98,109,53,7,99,97,112,116,105, + 111,110,6,11,66,111,111,107,109,97,114,107,32,38,53,9,116,97,103,97, + 99,116,105,111,110,2,5,9,111,110,101,120,101,99,117,116,101,7,10,102, + 105,110,100,98,109,101,120,101,99,4,108,101,102,116,3,104,1,3,116,111, + 112,3,32,1,2,115,99,1,2,1,3,53,64,0,0,0,7,116,97,99, + 116,105,111,110,6,115,101,116,98,109,53,7,99,97,112,116,105,111,110,6, + 11,66,111,111,107,109,97,114,107,32,38,53,9,116,97,103,97,99,116,105, + 111,110,2,5,9,111,110,101,120,101,99,117,116,101,7,9,115,101,116,98, + 109,101,120,101,99,4,108,101,102,116,3,24,1,3,116,111,112,3,32,1, + 2,115,99,1,2,1,3,53,96,0,0,0,7,116,97,99,116,105,111,110, + 7,102,105,110,100,98,109,54,7,99,97,112,116,105,111,110,6,11,66,111, + 111,107,109,97,114,107,32,38,54,9,116,97,103,97,99,116,105,111,110,2, + 6,9,111,110,101,120,101,99,117,116,101,7,10,102,105,110,100,98,109,101, + 120,101,99,4,108,101,102,116,3,104,1,3,116,111,112,3,48,1,2,115, + 99,1,2,1,3,54,64,0,0,0,7,116,97,99,116,105,111,110,6,115, + 101,116,98,109,54,3,84,97,103,2,6,7,99,97,112,116,105,111,110,6, + 11,66,111,111,107,109,97,114,107,32,38,54,9,116,97,103,97,99,116,105, + 111,110,2,6,9,111,110,101,120,101,99,117,116,101,7,9,115,101,116,98, + 109,101,120,101,99,4,108,101,102,116,3,24,1,3,116,111,112,3,48,1, + 2,115,99,1,2,1,3,54,96,0,0,0,7,116,97,99,116,105,111,110, + 7,102,105,110,100,98,109,55,7,99,97,112,116,105,111,110,6,11,66,111, + 111,107,109,97,114,107,32,38,55,9,116,97,103,97,99,116,105,111,110,2, + 7,9,111,110,101,120,101,99,117,116,101,7,10,102,105,110,100,98,109,101, + 120,101,99,4,108,101,102,116,3,104,1,3,116,111,112,3,64,1,2,115, + 99,1,2,1,3,55,64,0,0,0,7,116,97,99,116,105,111,110,6,115, + 101,116,98,109,55,7,99,97,112,116,105,111,110,6,11,66,111,111,107,109, + 97,114,107,32,38,55,9,116,97,103,97,99,116,105,111,110,2,7,9,111, + 110,101,120,101,99,117,116,101,7,9,115,101,116,98,109,101,120,101,99,4, + 108,101,102,116,3,24,1,3,116,111,112,3,64,1,2,115,99,1,2,1, + 3,55,96,0,0,0,7,116,97,99,116,105,111,110,7,102,105,110,100,98, + 109,56,7,99,97,112,116,105,111,110,6,11,66,111,111,107,109,97,114,107, + 32,38,56,9,116,97,103,97,99,116,105,111,110,2,8,9,111,110,101,120, + 101,99,117,116,101,7,10,102,105,110,100,98,109,101,120,101,99,4,108,101, + 102,116,3,104,1,3,116,111,112,3,80,1,2,115,99,1,2,1,3,56, + 64,0,0,0,7,116,97,99,116,105,111,110,6,115,101,116,98,109,56,7, + 99,97,112,116,105,111,110,6,11,66,111,111,107,109,97,114,107,32,38,56, + 9,116,97,103,97,99,116,105,111,110,2,8,9,111,110,101,120,101,99,117, + 116,101,7,9,115,101,116,98,109,101,120,101,99,4,108,101,102,116,3,24, + 1,3,116,111,112,3,80,1,2,115,99,1,2,1,3,56,96,0,0,0, + 7,116,97,99,116,105,111,110,7,102,105,110,100,98,109,57,7,99,97,112, + 116,105,111,110,6,11,66,111,111,107,109,97,114,107,32,38,57,9,116,97, + 103,97,99,116,105,111,110,2,9,9,111,110,101,120,101,99,117,116,101,7, + 10,102,105,110,100,98,109,101,120,101,99,4,108,101,102,116,3,104,1,3, + 116,111,112,3,96,1,2,115,99,1,2,1,3,57,64,0,0,0,7,116, + 97,99,116,105,111,110,6,115,101,116,98,109,57,7,99,97,112,116,105,111, + 110,6,11,66,111,111,107,109,97,114,107,32,38,57,9,116,97,103,97,99, + 116,105,111,110,2,9,9,111,110,101,120,101,99,117,116,101,7,9,115,101, + 116,98,109,101,120,101,99,4,108,101,102,116,3,24,1,3,116,111,112,3, + 96,1,2,115,99,1,2,1,3,57,96,0,0,0,7,116,97,99,116,105, + 111,110,9,115,101,116,98,109,110,111,110,101,7,99,97,112,116,105,111,110, + 6,4,110,111,110,101,9,116,97,103,97,99,116,105,111,110,2,255,9,111, + 110,101,120,101,99,117,116,101,7,9,115,101,116,98,109,101,120,101,99,4, + 108,101,102,116,3,24,1,3,116,111,112,3,112,1,0,0,7,116,97,99, + 116,105,111,110,11,105,110,115,116,101,109,112,108,97,116,101,9,111,110,101, + 120,101,99,117,116,101,7,23,105,110,115,116,101,109,112,108,97,116,101,97, + 99,116,111,110,101,120,101,99,117,116,101,4,108,101,102,116,3,112,1,3, + 116,111,112,2,96,2,115,99,1,2,1,3,84,64,0,0,0,7,116,97, + 99,116,105,111,110,14,112,114,111,106,101,99,116,111,112,101,110,97,99,116, + 7,99,97,112,116,105,111,110,6,5,79,38,112,101,110,9,111,110,101,120, + 101,99,117,116,101,7,14,112,114,111,106,101,99,116,111,112,101,110,101,120, + 101,4,108,101,102,116,2,112,3,116,111,112,3,40,1,0,0,7,116,97, + 99,116,105,111,110,17,112,114,111,106,101,99,116,111,112,116,105,111,110,115, + 97,99,116,7,99,97,112,116,105,111,110,6,8,38,79,112,116,105,111,110, + 115,9,111,110,101,120,101,99,117,116,101,7,17,112,114,111,106,101,99,116, + 111,112,116,105,111,110,115,101,120,101,4,108,101,102,116,2,112,3,116,111, + 112,3,56,1,0,0,7,116,97,99,116,105,111,110,14,112,114,111,106,101, + 99,116,116,114,101,101,97,99,116,7,99,97,112,116,105,111,110,6,5,38, + 84,114,101,101,9,111,110,101,120,101,99,117,116,101,7,14,112,114,111,106, + 101,99,116,116,114,101,101,101,120,101,4,108,101,102,116,2,112,3,116,111, + 112,3,72,1,0,0,7,116,97,99,116,105,111,110,16,112,114,111,106,101, + 99,116,115,111,117,114,99,101,97,99,116,7,99,97,112,116,105,111,110,6, + 7,83,111,38,117,114,99,101,9,111,110,101,120,101,99,117,116,101,7,16, + 112,114,111,106,101,99,116,115,111,117,114,99,101,101,120,101,4,108,101,102, + 116,2,112,3,116,111,112,3,88,1,0,0,7,116,97,99,116,105,111,110, + 14,112,114,111,106,101,99,116,115,97,118,101,97,99,116,7,99,97,112,116, + 105,111,110,6,5,38,83,97,118,101,9,111,110,101,120,101,99,117,116,101, + 7,14,112,114,111,106,101,99,116,115,97,118,101,101,120,101,4,108,101,102, + 116,2,112,3,116,111,112,3,104,1,0,0,7,116,97,99,116,105,111,110, + 15,112,114,111,106,101,99,116,99,108,111,115,101,97,99,116,7,99,97,112, + 116,105,111,110,6,6,38,67,108,111,115,101,9,111,110,101,120,101,99,117, + 116,101,7,16,112,114,111,106,101,99,116,99,108,111,101,115,101,101,120,101, + 4,108,101,102,116,2,112,3,116,111,112,3,120,1,0,0,16,116,115,116, + 114,105,110,103,99,111,110,116,97,105,110,101,114,1,99,11,111,110,114,101, + 97,100,115,116,97,116,101,7,13,99,114,101,97,100,115,116,97,116,101,101, + 120,101,12,115,116,114,105,110,103,115,46,100,97,116,97,1,6,16,67,111, + 110,102,105,103,117,114,101,32,77,83,69,105,100,101,6,10,80,114,111,99, + 101,115,115,32,73,68,6,17,65,116,116,97,99,104,32,116,111,32,112,114, + 111,99,101,115,115,6,25,85,110,107,110,111,119,110,32,109,111,100,117,108, + 101,99,108,97,115,115,32,102,111,114,32,34,6,21,73,110,104,101,114,105, + 116,101,100,32,99,111,109,112,111,110,101,110,116,32,34,6,21,34,32,99, + 97,110,32,110,111,116,32,98,101,32,100,101,108,101,116,101,100,46,6,5, + 69,82,82,79,82,6,13,77,97,107,101,32,97,98,111,114,116,101,100,46, + 6,17,68,111,119,110,108,111,97,100,32,97,98,111,114,116,101,100,46,6, + 15,82,117,110,101,114,114,111,114,32,119,105,116,104,32,34,6,15,69,114, + 114,111,114,58,32,84,105,109,101,111,117,116,46,6,7,77,97,107,105,110, + 103,46,6,17,77,97,107,101,32,110,111,116,32,114,117,110,110,105,110,103, + 46,6,12,68,111,119,110,108,111,97,100,105,110,103,46,6,21,68,111,119, + 110,108,111,97,100,32,110,111,116,32,114,117,110,110,105,110,103,46,6,10, + 34,32,114,117,110,110,105,110,103,46,6,6,83,99,114,105,112,116,6,31, + 82,101,99,117,114,115,105,118,101,32,102,111,114,109,32,105,110,104,101,114, + 105,116,97,110,99,101,32,111,102,32,34,6,11,67,111,109,112,111,110,101, + 110,116,32,34,6,9,34,32,101,120,105,115,116,115,46,6,14,65,110,99, + 101,115,116,111,114,32,102,111,114,32,34,6,12,34,32,110,111,116,32,102, + 111,117,110,100,46,6,8,77,111,100,117,108,101,32,34,6,14,73,110,118, + 97,108,105,100,32,110,97,109,101,32,34,6,18,73,110,118,97,108,105,100, + 32,109,101,116,104,111,100,110,97,109,101,6,16,77,111,100,117,108,101,32, + 110,111,116,32,102,111,117,110,100,6,16,77,101,116,104,111,100,32,110,111, + 116,32,102,111,117,110,100,6,26,80,117,98,108,105,115,104,101,100,32,40, + 109,97,110,97,103,101,100,41,32,109,101,116,104,111,100,6,15,100,111,101, + 115,32,110,111,116,32,101,120,105,115,116,46,6,32,68,111,32,121,111,117, + 32,119,105,115,104,32,116,111,32,100,101,108,101,116,101,32,116,104,101,32, + 101,118,101,110,116,63,6,7,87,65,82,78,73,78,71,6,6,77,101,116, + 104,111,100,6,25,104,97,115,32,100,105,102,102,101,114,101,110,116,32,112, + 97,114,97,109,101,116,101,114,115,46,6,10,65,32,109,111,100,117,108,101, + 32,34,6,18,34,32,105,115,32,97,108,114,101,97,100,121,32,111,112,101, + 110,46,6,26,85,110,114,101,115,111,108,118,101,100,32,114,101,102,101,114, + 101,110,99,101,40,115,41,32,116,111,6,10,77,111,100,117,108,101,40,115, + 41,58,6,23,67,97,110,32,110,111,116,32,114,101,97,100,32,102,111,114, + 109,102,105,108,101,32,34,6,23,73,110,118,97,108,105,100,32,99,111,109, + 112,111,110,101,110,116,32,110,97,109,101,46,6,17,73,110,118,97,108,105, + 100,32,101,120,99,101,112,116,105,111,110,6,6,84,38,111,111,108,115,6, + 5,70,111,114,109,115,6,6,83,111,117,114,99,101,6,9,65,108,108,32, + 70,105,108,101,115,6,7,80,114,111,103,114,97,109,6,4,85,110,105,116, + 6,8,84,101,120,116,102,105,108,101,6,8,77,97,105,110,102,111,114,109, + 6,11,83,105,109,112,108,101,32,70,111,114,109,6,12,68,111,99,107,105, + 110,103,32,70,111,114,109,6,10,68,97,116,97,109,111,100,117,108,101,6, + 7,83,117,98,102,111,114,109,6,13,83,99,114,111,108,108,98,111,120,102, + 111,114,109,6,7,84,97,98,102,111,114,109,6,9,68,111,99,107,112,97, + 110,101,108,6,6,82,101,112,111,114,116,6,10,83,99,114,105,112,116,102, + 111,114,109,6,14,73,110,104,101,114,105,116,101,100,32,70,111,114,109,6, + 38,68,111,32,121,111,117,32,119,97,110,116,32,116,111,32,114,101,112,108, + 97,99,101,32,116,104,101,32,115,101,116,116,105,110,103,115,32,98,121,6, + 6,70,105,108,101,32,34,6,25,68,111,32,121,111,117,32,119,97,110,116, + 32,116,111,32,111,118,101,114,119,114,105,116,101,63,6,7,85,110,107,110, + 111,119,110,6,5,69,114,114,111,114,6,7,83,116,97,114,116,117,112,6, + 9,69,120,99,101,112,116,105,111,110,6,8,71,68,66,32,100,105,101,100, + 6,14,66,114,101,97,107,112,111,105,110,116,32,104,105,116,6,20,87,97, + 116,99,104,112,111,105,110,116,32,116,114,105,103,103,101,114,101,100,6,25, + 82,101,97,100,32,87,97,116,99,104,112,111,105,110,116,32,116,114,105,103, + 103,101,114,101,100,6,27,65,99,99,101,115,115,32,87,97,116,99,104,112, + 111,105,110,116,32,116,114,105,103,103,101,114,101,100,6,18,69,110,100,32, + 115,116,101,112,112,105,110,103,32,114,97,110,103,101,6,17,70,117,110,99, + 116,105,111,110,32,102,105,110,105,115,104,101,100,6,15,69,120,105,116,101, + 100,32,110,111,114,109,97,108,108,121,6,6,69,120,105,116,101,100,6,8, + 68,101,116,97,99,104,101,100,6,15,83,105,103,110,97,108,32,114,101,99, + 101,105,118,101,100,6,10,83,116,111,112,32,101,114,114,111,114,6,20,67, + 97,110,32,110,111,116,32,114,101,97,100,32,112,114,111,106,101,99,116,6, + 5,65,98,111,117,116,6,16,79,98,106,101,99,116,32,73,110,115,112,101, + 99,116,111,114,6,15,83,116,111,114,101,32,67,111,109,112,111,110,101,110, + 116,6,17,65,116,116,97,99,104,105,110,103,32,80,114,111,99,101,115,115, + 6,7,76,111,97,100,105,110,103,6,11,83,105,122,105,110,103,32,70,111, + 114,109,0,4,108,101,102,116,3,136,1,3,116,111,112,3,144,1,0,0, + 7,116,97,99,116,105,111,110,12,99,111,112,121,108,97,116,101,120,97,99, + 116,7,99,97,112,116,105,111,110,6,11,67,111,112,121,32,38,76,97,84, + 101,88,9,111,110,101,120,101,99,117,116,101,7,21,99,111,112,121,108,97, + 116,101,120,97,99,116,111,110,101,120,101,99,117,116,101,4,108,101,102,116, + 3,112,1,3,116,111,112,2,80,2,115,99,1,2,2,3,75,64,2,76, + 0,0,0,7,116,97,99,116,105,111,110,11,102,105,110,100,99,111,109,112, + 97,99,116,9,111,110,101,120,101,99,117,116,101,7,11,102,105,110,100,99, + 111,109,112,101,120,101,4,108,101,102,116,3,152,0,3,116,111,112,3,152, + 0,2,115,99,1,2,1,3,70,64,0,0,0,7,116,97,99,116,105,111, + 110,14,102,105,110,100,99,111,109,112,97,108,108,97,99,116,7,99,97,112, + 116,105,111,110,6,15,38,70,105,110,100,32,67,111,109,112,111,110,101,110, + 116,9,111,110,101,120,101,99,117,116,101,7,14,102,105,110,100,99,111,109, + 112,97,108,108,101,120,101,4,108,101,102,116,3,152,0,3,116,111,112,3, + 168,0,0,0,7,116,97,99,116,105,111,110,14,102,111,114,99,101,122,111, + 114,100,101,114,97,99,116,7,99,97,112,116,105,111,110,6,14,70,111,114, + 99,101,32,38,90,45,79,114,100,101,114,8,111,110,99,104,97,110,103,101, + 7,14,102,111,114,99,101,122,111,114,100,101,114,101,120,101,4,108,101,102, + 116,3,136,0,3,116,111,112,3,144,1,0,0,7,116,97,99,116,105,111, + 110,5,116,111,111,108,48,4,108,101,102,116,3,216,1,3,116,111,112,2, + 8,0,0,7,116,97,99,116,105,111,110,5,116,111,111,108,49,4,108,101, + 102,116,3,216,1,3,116,111,112,2,24,0,0,7,116,97,99,116,105,111, + 110,5,116,111,111,108,50,4,108,101,102,116,3,216,1,3,116,111,112,2, + 40,0,0,7,116,97,99,116,105,111,110,5,116,111,111,108,51,4,108,101, + 102,116,3,216,1,3,116,111,112,2,56,0,0,7,116,97,99,116,105,111, + 110,5,116,111,111,108,52,4,108,101,102,116,3,216,1,3,116,111,112,2, + 72,0,0,7,116,97,99,116,105,111,110,5,116,111,111,108,53,4,108,101, + 102,116,3,216,1,3,116,111,112,2,88,0,0,7,116,97,99,116,105,111, + 110,5,116,111,111,108,54,4,108,101,102,116,3,216,1,3,116,111,112,2, + 104,0,0,7,116,97,99,116,105,111,110,5,116,111,111,108,55,4,108,101, + 102,116,3,216,1,3,116,111,112,2,120,0,0,7,116,97,99,116,105,111, + 110,5,116,111,111,108,56,4,108,101,102,116,3,216,1,3,116,111,112,3, + 136,0,0,0,7,116,97,99,116,105,111,110,5,116,111,111,108,57,4,108, + 101,102,116,3,216,1,3,116,111,112,3,152,0,0,0,7,116,97,99,116, + 105,111,110,7,99,111,109,109,101,110,116,7,99,97,112,116,105,111,110,6, + 8,38,67,111,109,109,101,110,116,9,111,110,101,120,101,99,117,116,101,7, + 16,99,111,109,109,101,110,116,111,110,101,120,101,99,117,116,101,8,111,110, + 117,112,100,97,116,101,7,13,101,110,97,98,108,101,99,111,109,109,101,110, + 116,4,108,101,102,116,3,24,1,3,116,111,112,3,168,0,2,115,99,1, + 2,2,3,75,64,2,67,0,0,0,7,116,97,99,116,105,111,110,9,117, + 110,99,111,109,109,101,110,116,7,99,97,112,116,105,111,110,6,10,85,110, + 99,38,111,109,109,101,110,116,9,111,110,101,120,101,99,117,116,101,7,18, + 117,110,99,111,109,109,101,110,116,111,110,101,120,101,99,117,116,101,8,111, + 110,117,112,100,97,116,101,7,15,101,110,97,98,108,101,117,110,99,111,109, + 109,101,110,116,4,108,101,102,116,3,24,1,3,116,111,112,3,184,0,2, + 115,99,1,2,2,3,75,64,2,85,0,0,0,7,116,97,99,116,105,111, + 110,8,99,111,112,121,119,111,114,100,7,99,97,112,116,105,111,110,6,20, + 67,111,112,121,32,38,87,111,114,100,32,97,116,32,67,117,114,115,111,114, + 7,111,112,116,105,111,110,115,11,17,97,111,95,103,108,111,98,97,108,115, + 104,111,114,116,99,117,116,0,9,111,110,101,120,101,99,117,116,101,7,25, + 115,101,108,101,99,116,119,111,114,100,97,99,116,105,111,110,111,110,101,120, + 101,99,117,116,101,4,108,101,102,116,3,24,1,3,116,111,112,2,100,2, + 115,99,1,2,1,3,87,96,0,0,0,7,116,97,99,116,105,111,110,9, + 115,101,108,101,99,116,97,108,108,7,99,97,112,116,105,111,110,6,11,83, + 101,108,101,99,116,32,38,97,108,108,9,111,110,101,120,101,99,117,116,101, + 7,21,115,101,108,101,99,108,97,108,108,97,99,116,111,110,101,120,101,99, + 117,116,101,4,108,101,102,116,3,88,1,3,116,111,112,2,56,2,115,99, + 1,2,1,3,65,64,0,0,0,7,116,97,99,116,105,111,110,10,116,97, + 98,116,111,115,112,97,99,101,7,99,97,112,116,105,111,110,6,14,38,84, + 97,98,115,32,116,111,32,115,112,97,99,101,9,111,110,101,120,101,99,117, + 116,101,7,17,116,97,98,116,111,115,112,97,99,101,101,120,101,99,117,116, + 101,8,111,110,117,112,100,97,116,101,7,14,101,110,97,98,108,101,111,110, + 115,101,108,101,99,116,4,108,101,102,116,3,104,1,3,116,111,112,3,168, + 0,0,0,7,116,97,99,116,105,111,110,8,102,105,110,100,98,97,99,107, + 7,99,97,112,116,105,111,110,6,12,83,101,97,114,99,104,32,38,98,97, + 99,107,9,111,110,101,120,101,99,117,116,101,7,17,102,105,110,100,98,97, + 99,107,111,110,101,120,101,99,117,116,101,4,108,101,102,116,3,152,0,3, + 116,111,112,2,60,2,115,99,1,2,1,3,50,33,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tactionsmo,''); +end. diff --git a/mseide-msegui/apps/ide/breakpointsform.mfm b/mseide-msegui/apps/ide/breakpointsform.mfm new file mode 100644 index 0000000..2f4f27a --- /dev/null +++ b/mseide-msegui/apps/ide/breakpointsform.mfm @@ -0,0 +1,471 @@ +object breakpointsfo: tbreakpointsfo + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_floatbutton, go_topbutton, go_backgroundbutton, go_nolockbutton] + visible = False + bounds_x = 107 + bounds_y = 404 + bounds_cx = 636 + bounds_cy = 128 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 626 + 128 + ) + dragdock.splitter_size = 0 + dragdock.optionsdock = [od_savepos, od_savezorder, od_canmove, od_canfloat, od_candock, od_propsize, od_captionhint] + options = [fo_savepos, fo_savezorder, fo_savestate] + statfile = mainfo.projectstatfile + caption = 'Breakpoints' + icon.transparentcolor = -2147483642 + icon.image = { + 00000000000000001800000018000000CC060000000000000000000000000000 + 0000000000000000000000000000000000000000F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E1E1E601B9B9EA01 + 8989EE018888ED01B5B5E601DBDBE001DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01E4E4EA017171F4010707FE010000FF04 + 0707FE016A6AED01D5D5DB01DADADA01D8D8D801D7D7D701D5D5D501D3D3D301 + D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01EDEDED01 + C5C5EE012828FB010000FF081F1FF201B4B4DD01D7D7D702D5D5D501D3D3D301 + D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01E7E7ED01 + 2929FC010000FF0A1818EB01C5C5CB01D6D6D601D5D5D501D3D3D301D2D2D201 + D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE017373F6010000FF0C + 3636B901C9C9C901D4D4D401D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301 + F2F2F201F0F0F001E9E9EE010707FE010000FF0C0303FA0186868B01D2D2D201 + D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001C0C0F101 + 0000FF0E51518201B0B0B001D2D2D202D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F0019090F5010000FF0E3C3CA10191919101D1D1D101D2D2D201D0D0D001 + F5F5F501F3F3F301F2F2F201F0F0F0019090F5010000FF0E3B3BA0017A7A7A01 + D1D1D101D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001C0C0F101 + 0000FF0E4E4E7F016A6A6A01D0D0D001D2D2D201D0D0D001F5F5F501F3F3F301 + F2F2F201F0F0F001E9E9EE010707FE010000FF0C0303FA01606065017A7A7A01 + D1D1D101D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01 + 7272F5010000FF0C2F2FB2016363630191919101D1D1D101D2D2D201D0D0D001 + F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01E6E6EC012121F4010000FF0A + 1111E4015F5F650164646401B0B0B001D2D2D202D0D0D001F5F5F501F3F3F301 + F2F2F201F0F0F001EEEEEE01EDEDED01C2C2EB011A1AED010000FF081111E401 + 52527B016363630189898901D2D2D201D3D3D301D2D2D201D0D0D001F5F5F501 + F3F3F301F2F2F201F0F0F001EEEEEE01EDEDED01EAEAEA01D5D5DB013A3ABD01 + 0303FA010000FF040303FA013131B401616167016464640170707001C9C9C901 + D4D4D401D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001 + EEEEEE01EDEDED01EBEBEB01E9E9E901D9D9D9018F8F9401565687013F3FA401 + 3E3EA3015252830163636801656565028A8A8A01CACACA01D6D6D601D5D5D501 + D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01 + EDEDED01EBEBEB01EAEAEA01E7E7E701E3E3E301BDBDBD019A9A9A0181818101 + 707070018080800196969601B5B5B501D7D7D703D5D5D501D3D3D301D2D2D201 + D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01EDEDED01EBEBEB01 + EAEAEA01E8E8E801E6E6E601E4E4E401E1E1E101DFDFDF01DDDDDD01DCDCDC01 + DBDBDB01DADADA02D8D8D801D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001 + F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01 + E8E8E801E6E6E601E5E5E501E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01 + DBDBDB01DADADA01D8D8D801D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001 + F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01 + E8E8E801E6E6E601E5E5E501E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01 + DBDBDB01DADADA01D8D8D801D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001 + } + onshow = breakpointsonshow + moduleclassname = 'tdockform' + object grid: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + frame.localprops = [] + frame.localprops1 = [] + taborder = 1 + popupmenu = gripopup + bounds_x = 0 + bounds_y = 24 + bounds_cx = 626 + bounds_cy = 104 + anchors = [an_top, an_bottom] + optionsgrid = [og_colsizing, og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_colchangeontabkey, og_wrapcol, og_autopopup] + fixcols.count = 1 + fixcols.items = < + item + width = 20 + numstart = 1 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 11 + captions.items = < + item + caption = 'on' + end + item + caption = 'File' + end + item + end + item + caption = 'Line Nr.' + end + item + caption = 'Address' + end + item + end + item + end + item + caption = 'Count' + end + item + caption = 'Ignore' + end + item + end + item + caption = 'Condition' + end> + end> + datacols.count = 13 + datacols.items = < + item[bkpton] + linecolorfix = -1610612733 + width = 16 + options = [co_drawfocus, co_fixwidth, co_savestate] + widgetname = 'bkpton' + dataclass = tgridintegerdatalist + end + item[filename] + linecolorfix = -1610612733 + width = 158 + options = [co_savevalue, co_savestate] + widgetname = 'filename' + dataclass = tgridmsestringdatalist + end + item[path] + linecolorfix = -1610612733 + options = [co_invisible, co_savevalue] + widgetname = 'path' + dataclass = tgridmsestringdatalist + end + item[line] + linecolorfix = -1610612733 + options = [co_savevalue, co_savestate] + widgetname = 'line' + dataclass = tgridintegerdatalist + end + item[address] + width = 61 + onbeforedrawcell = adbefdrawcell + widgetname = 'address' + dataclass = tgridint64datalist + end + item[addressbkpt] + width = 6 + options = [co_invisible, co_drawfocus, co_savevalue, co_savestate, co_mousescrollrow] + widgetname = 'addressbkpt' + dataclass = tgridintegerdatalist + end + item[bkptno] + linecolorfix = -1610612733 + width = 19 + options = [co_invisible, co_savevalue] + widgetname = 'bkptno' + dataclass = tgridintegerdatalist + end + item[count] + color = -1879048185 + linecolorfix = -1610612733 + width = 31 + options = [co_readonly, co_nofocus, co_savevalue, co_savestate] + widgetname = 'count' + dataclass = tgridintegerdatalist + end + item[ignore] + linecolorfix = -1610612733 + width = 30 + options = [co_savevalue, co_savestate] + widgetname = 'ignore' + dataclass = tgridintegerdatalist + end + item[conderr] + linecolorfix = -1610612733 + width = 7 + options = [co_readonly, co_nofocus, co_fixwidth, co_savestate] + onshowhint = errhint + widgetname = 'conderr' + dataclass = tgridintegerdatalist + end + item[condition] + linecolorfix = -1610612733 + width = 124 + options = [co_fill, co_savevalue, co_savestate] + widthmin = 0 + widgetname = 'condition' + dataclass = tgridmsestringdatalist + end + item[errormessage] + width = 19 + options = [co_invisible, co_mousescrollrow] + widgetname = 'errormessage' + dataclass = tgridmsestringdatalist + end + item[flags] + width = 17 + options = [co_invisible, co_savevalue, co_savestate] + widgetname = 'flags' + dataclass = tgridintegerdatalist + end> + datarowheight = 16 + onrowsdeleting = gridonrowsdeleting + onrowsdeleted = gridonrowsdeleted + oncellevent = gridoncellevent + reffontheight = 14 + object bkpton: tbooleanedit + optionsskin = [osk_framebuttononly] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 16 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + ondataentered = ondataentered + visible = False + onsetvalue = ononsetvalue + valuedefault = True + end + object filename: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 2 + visible = False + bounds_x = 17 + bounds_y = 0 + bounds_cx = 158 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + ondataentered = ondataenterednewbkpt + onsetvalue = filenameonsetvalue + reffontheight = 14 + end + object path: tstringedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 3 + visible = False + bounds_x = 176 + bounds_y = 0 + bounds_cx = 50 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + reffontheight = 14 + end + object line: tintegeredit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 4 + visible = False + bounds_x = 227 + bounds_y = 0 + bounds_cx = 50 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + ondataentered = ondataenterednewbkpt + onsetvalue = lineonsetvalue + min = 1 + reffontheight = 14 + end + object address: tint64edit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + taborder = 5 + visible = False + bounds_x = 278 + bounds_y = 0 + bounds_cx = 61 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + ondataentered = addressentered + base = nb_hex + max = -1 + reffontheight = 14 + end + object addressbkpt: tbooleanedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + taborder = 6 + bounds_x = 340 + bounds_y = 0 + bounds_cx = 6 + bounds_cy = 16 + visible = False + reffontheight = 14 + end + object bkptno: tintegeredit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 7 + visible = False + bounds_x = 347 + bounds_y = 0 + bounds_cx = 19 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + reffontheight = 14 + end + object count: tintegeredit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 8 + visible = False + bounds_x = 367 + bounds_y = 0 + bounds_cx = 31 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + object ignore: tintegeredit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 9 + visible = False + bounds_x = 399 + bounds_y = 0 + bounds_cx = 30 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_forcereturncheckvalue, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + ondataentered = ondataentered + onsetvalue = ignoreonsetvalue + reffontheight = 14 + end + object conderr: tdataicon + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 10 + bounds_x = 430 + bounds_y = 0 + bounds_cx = 7 + bounds_cy = 16 + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + imagelist = actionsmo.buttonicons + imageoffset = 10 + reffontheight = 14 + end + object condition: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 11 + visible = False + bounds_x = 438 + bounds_y = 0 + bounds_cx = 124 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick, oe_trimright, oe_trimleft] + ondataentered = ondataentered + onsetvalue = conditiononsetvalue + reffontheight = 14 + end + object errormessage: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 12 + visible = False + bounds_x = 563 + bounds_y = 0 + bounds_cx = 19 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + object flags: tintegeredit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 13 + visible = False + bounds_x = 583 + bounds_y = 0 + bounds_cx = 17 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + reffontheight = 14 + end + end + object bkptson: tbooleanedit + frame.caption = 'Breakpoints &on' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 98 + 2 + ) + bounds_x = 8 + bounds_y = 4 + bounds_cx = 111 + bounds_cy = 16 + statfile = mainfo.projectstatfile + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + onchange = bkptsononchange + onsetvalue = bkptsononsetvalue + value = True + end + object gripopup: tpopupmenu + menu.submenu.count = 1 + menu.submenu.items = < + item + caption = 'Delete all' + state = [as_localcaption, as_localonexecute] + onexecute = deleteallexecute + end> + menu.name = 'gridpopup' + left = 168 + end + object c: tstringcontainer + strings.data = ( + 'Breakpoint error.' + 'BREAKPOINT ERROR' + 'Do you wish to delete all breakpoints?' + 'Confirmation' + ) + left = 344 + top = 80 + end +end diff --git a/mseide-msegui/apps/ide/breakpointsform.pas b/mseide-msegui/apps/ide/breakpointsform.pas new file mode 100644 index 0000000..0405a4d --- /dev/null +++ b/mseide-msegui/apps/ide/breakpointsform.pas @@ -0,0 +1,822 @@ +{ MSEide Copyright (c) 1999-2013 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit breakpointsform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + mseforms,msewidgetgrid,msedataedits,msegdbutils,msetypes,msegrids, + msegraphedits,msestat,msemenuwidgets,msemenus,msestrings,mseedit,mseevent, + msegui,msegraphics,mseguiglob,msestringcontainer; + +type + bkptstatety = (bkpts_none,bkpts_normal,bkpts_disabled,bkpts_error); + + bkptlineinfoty = record + line: integer; + state: bkptstatety; + end; + bkptlineinfoarty = array of bkptlineinfoty; + + tbreakpointsfo = class(tdockform) + grid: twidgetgrid; + filename: tstringedit; + path: tstringedit; + line: tintegeredit; + bkptno: tintegeredit; + bkpton: tbooleanedit; + bkptson: tbooleanedit; + condition: tstringedit; + conderr: tdataicon; + ignore: tintegeredit; + count: tintegeredit; + gridpopup: tpopupmenu; + flags: tintegeredit; + address: tint64edit; + addressbkpt: tbooleanedit; + errormessage: tstringedit; + c: tstringcontainer; + procedure bkptsononchange(const sender: TObject); + procedure bkptsononsetvalue(const sender: TObject; var avalue: boolean; + var accept: Boolean); + + procedure breakpointsonshow(const sender: TObject); + procedure gridoncellevent(const sender: TObject; var info: celleventinfoty); + procedure gridonrowsdeleted(const sender: tcustomgrid; const aindex: Integer; + const acount: Integer); + procedure gridonrowsdeleting(const sender: tcustomgrid; var aindex,acount: integer); + + procedure ononsetvalue(const sender: TObject; var avalue: Boolean; + var accept: Boolean); + procedure ignoreonsetvalue(const sender: TObject; var avalue: Integer; var accept: Boolean); + procedure conditiononsetvalue(const sender: TObject; var avalue: mseString; var accept: Boolean); + procedure ondataentered(const sender: tobject); + + procedure lineonsetvalue(const sender: TObject; var avalue: Integer; var accept: Boolean); + procedure filenameonsetvalue(const sender: tobject; var avalue: msestring; var accept: boolean); + procedure ondataenterednewbkpt(const sender: tobject); + + procedure deleteallexecute(const sender: TObject); + procedure addressentered(const sender: TObject); + procedure adbefdrawcell(const sender: tcol; const canvas: tcanvas; + var cellinfo: cellinfoty; var processed: Boolean); + procedure errhint(const sender: tdatacol; const arow: Integer; + var info: hintinfoty); + private + fbreakpointsvalid: boolean; + function infotolineinfo(const info: breakpointinfoty): bkptlineinfoty; + function breakpointerror(const error: gdbresultty; + out errme: msestring): boolean; + procedure removeactbreakpoint; + function findbreakpointrow(const anum: integer): integer; + procedure newbkpt(const addressbp: boolean); + procedure updaterow(const arow: integer); + protected + procedure infotolist(const index: integer; var info: breakpointinfoty; + const nobkpton: boolean); + procedure listtoinfo(const index: integer; var info: breakpointinfoty); + procedure changed; + procedure insertbkpt(index: integer; + withcondition,witherrormessage: boolean); + public + gdb: tgdbmi; + + breakpointpaths: msestringarty; + breakpointlines: integerarty; + breakpointaddress: int64arty; + addressbreakpoints: longboolarty; + breakpointons: longboolarty; + breakpointignore: integerarty; + breakpointconditions: msestringarty; + + procedure clear; + procedure refresh; + procedure updatestat(const statfiler: tstatfiler); + function addbreakpoint(var info: breakpointinfoty): boolean; + //true if gdb ok + procedure deletebreakpoint(var info: breakpointinfoty); + function updatebreakpointon(var info: breakpointinfoty): boolean; + //true if gdb ok + function getbreakpointlines(const filepath: filenamety): bkptlineinfoarty; + procedure sourcelinesinserted(const filepath: filenamety; + const aindex,acount: integer); + procedure sourcelinesdeleted(const filepath: filenamety; + const aindex,acount: integer); + + procedure updatebreakpoints; //transfer breakpoints to gdb + procedure showbreakpoint(const filepath: filenamety; + const aline: integer; const focus: boolean); + procedure showbreakpoint(const aaddress: int64; focus: boolean); + function checkbreakpointcontinue(const stopinfo: stopinfoty): boolean; + //set condition + function isactivebreakpoint(const addr: qword): boolean; + procedure toggleaddrbreakpoint(const addr: qword); + end; + +var + breakpointsfo: tbreakpointsfo; + +implementation +uses + breakpointsform_mfm,msefileutils,sourceform,projectoptionsform,msedatalist, + main,msewidgets,actionsmodule,watchpointsform,mseformatstr,msegraphutils, + disassform; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + stringconsts = ( + breakpointerror0, //0 Breakpoint error. + breakpointerror1, //1 BREAKPOINT ERROR + delbr, //2 Do you wish to delete all breakpoints? + confirmation //3 Confirmation + ); + +{ tbreakpointsfo } + +procedure tbreakpointsfo.updatestat(const statfiler: tstatfiler); +var + int1: integer; +begin + with statfiler,projectoptions do begin + setsection('breakpoints'); + updatevalue('on',breakpointons); + updatevalue('path',breakpointpaths); + updatevalue('line',breakpointlines); + updatevalue('address',breakpointaddress); + updatevalue('addbkpt',addressbreakpoints); + updatevalue('ignore',breakpointignore); + updatevalue('condition',breakpointconditions); + if not iswriter then begin + ignore.gridvalues:= breakpointignore; + condition.gridvalues:= breakpointconditions; + bkpton.gridvalues:= breakpointons; + path.gridvalues:= breakpointpaths; + line.gridvalues:= breakpointlines; + address.gridvalues:= breakpointaddress; + addressbkpt.gridvalues:= addressbreakpoints; +// updatebreakpoints(true); + end; +// updatestat(istatfile(bkptson)); +// updatestat(istatfile(grid)); + end; + for int1:= 0 to grid.rowhigh do begin + filename[int1]:= msefileutils.filename(path[int1]); + end; +end; + +procedure tbreakpointsfo.infotolist(const index: integer; + var info: breakpointinfoty; const nobkpton: boolean); +var + int1: integer; + lineinfo: bkptlineinfoty; + info1: breakpointinfoty; +// bo1: boolean; +begin + if gdb.execloaded and not gdb.running then begin + gdb.infobreakpoint(info,info.addressbreakpoint); + //update adress or fileinfo + end; + addressbkpt[index]:= info.addressbreakpoint; + path[index]:= info.path; + filename[index]:= msefileutils.filename(info.path); + line[index]:= info.line; + address[index]:= info.address; + bkptno[index]:= info.bkptno; + if not nobkpton then begin + bkpton[index]:= info.bkpton; + end; + ignore[index]:= info.ignore; + if info.conditionmessage <> '' then begin + int1:= 0; + end + else begin + int1:= -1; + end; + conderr[index]:= int1; + condition[index]:= msestring(info.condition); + info1:= info; + info1.bkpton:= bkpton[index]; + lineinfo:= infotolineinfo(info1); + sourcefo.updatebreakpointicon(info.path,lineinfo); +end; + +procedure tbreakpointsfo.listtoinfo(const index: integer; + var info: breakpointinfoty); +begin + info.addressbreakpoint:= addressbkpt[index]; + info.path:= path[index]; + info.line:= line[index]; + info.address:= address[index]; + info.bkptno:= bkptno[index]; + info.bkpton:= bkpton[index] and bkptson.value; + info.ignore:= ignore[index]; + info.condition:= ansistring(condition[index]); + if (info.conditionmessage = '') and (conderr[index] = 0) then begin + info.conditionmessage:= ' '; //old error + end; +end; + +procedure tbreakpointsfo.bkptsononchange(const sender: TObject); +var + int1: integer; + bo1: boolean; +begin + projectoptions.modified:= true; + if gdb.execloaded then begin + bo1:= bkptson.value; + gdb.interrupttarget; + for int1:= 0 to grid.rowhigh do begin + if bkpton[int1] then begin + gdb.breakenable(bkptno[int1],bo1); + end; + end; + gdb.restarttarget; + end; +end; + +procedure tbreakpointsfo.bkptsononsetvalue( + const sender: TObject; var avalue: boolean; var accept: Boolean); +begin + actionsmo.bkptsonact.checked:= avalue; +end; + +procedure tbreakpointsfo.breakpointsonshow(const sender: TObject); +begin + refresh; +end; + +procedure tbreakpointsfo.gridoncellevent(const sender: TObject; + var info: celleventinfoty); +begin + if iscellclick(info,[ccr_dblclick]) then begin + sourcefo.showsourceline(path[info.cell.row],line[info.cell.row]-1,0,true); + end; +end; + +procedure tbreakpointsfo.gridonrowsdeleted(const sender: tcustomgrid; + const aindex: Integer; const acount: Integer); +begin + changed; +end; + +procedure tbreakpointsfo.gridonrowsdeleting(const sender: tcustomgrid; + var aindex, acount: integer); +var + int1,int2: integer; + info: bkptlineinfoty; +begin + if gdb.execloaded then begin + for int1:= aindex to aindex + acount - 1 do begin + int2:= bkptno[int1]; + if int2 > 0 then begin + gdb.breakdelete(int2); + end; + end; + end; + for int1:= aindex to aindex + acount - 1 do begin + info.line:= line[int1]; + if info.line > 0 then begin + info.state:= bkpts_none; + sourcefo.updatebreakpointicon(path[int1],info); + end; + end; +end; + +procedure tbreakpointsfo.deletebreakpoint(var info: breakpointinfoty); +var + int1: integer; + wstr1: msestring; +begin + wstr1:= msefileutils.filename(info.path); + for int1:= grid.rowcount - 1 downto 0 do begin + if (line[int1] = info.line) and (filename[int1] = wstr1) then begin + grid.deleterow(int1); + end; + end; +end; + +function tbreakpointsfo.infotolineinfo( + const info: breakpointinfoty): bkptlineinfoty; +begin + result.line:= info.line; + if info.bkpton then begin + if info.conditionmessage <> '' then begin + result.state:= bkpts_error; + end + else begin + result.state:= bkpts_normal; + end; + end + else begin + result.state:= bkpts_disabled; + end; +end; + +function tbreakpointsfo.getbreakpointlines( + const filepath: filenamety): bkptlineinfoarty; +var + int1,int2: integer; + wstr1: filenamety; +begin + int2:= 0; + wstr1:= msefileutils.filename(filepath); + setlength(result,grid.rowcount); + for int1:= 0 to grid.rowcount - 1 do begin + if issamefilename(filename[int1],wstr1) then begin + with result[int2] do begin + line:= self.line[int1]; + if bkpton[int1] then begin + state:= bkpts_normal; + end + else begin + state:= bkpts_disabled; + end; + end; + inc(int2); + end; + end; + setlength(result,int2); +end; + +function tbreakpointsfo.breakpointerror(const error: gdbresultty; + out errme: msestring): boolean; +var + str1: msestring; +begin + result:= error <> gdb_ok; + errme:= ''; + if result then begin + if error = gdb_message then begin + str1:= msestring(gdb.errormessage); + end + else begin + str1:= c[ord(breakpointerror0)]; + end; + errme:= str1; + showmessage(str1,c[ord(breakpointerror1)]); + end; +end; + +procedure tbreakpointsfo.insertbkpt(index: integer; + withcondition,witherrormessage: boolean); +var + info: breakpointinfoty; + str1: string; + mstr1: msestring; +begin + fillchar(info,sizeof(info),0); + listtoinfo(index,info); + str1:= info.condition; + if not withcondition then begin + info.condition:= ''; + end; + if gdb.execloaded then begin + if witherrormessage then begin + if breakpointerror(gdb.breakinsert(info),mstr1) then begin + errormessage[index]:= mstr1; + end; + end + else begin + gdb.breakinsert(info); + end; + end; + info.condition:= str1; + infotolist(index,info,true); +end; + +function tbreakpointsfo.addbreakpoint(var info: breakpointinfoty): boolean; +var + int1: integer; + info1: breakpointinfoty; +begin + info1:= info; + info1.bkpton:= info1.bkpton and bkptson.value; + if gdb.execloaded then begin + result:= gdb.breakinsert(info1) = gdb_ok; + end + else begin + result:= true; + end; + if result then begin + if (grid.rowcount = 0) or + not grid.datacols.rowempty(grid.rowcount - 1) then begin + int1:= grid.appendrow; + end + else begin + int1:= grid.rowcount - 1; + end; + info1.bkpton:= info.bkpton; + infotolist(int1,info1,false); + changed; + end; +end; + +procedure tbreakpointsfo.updatebreakpoints; +var + int1: integer; +begin + if gdb.active then begin + gdb.breakdelete(0); + flags.fillcol(0); +// gdb.breakinsert('main'); + for int1:= 0 to grid.rowhigh do begin + insertbkpt(int1,false,false); + end; + fbreakpointsvalid:= true; + end + else begin + fbreakpointsvalid:= false; + end; +end; + +function tbreakpointsfo.findbreakpointrow(const anum: integer): integer; +var + int1: integer; +begin + result:= -1; + for int1:= 0 to grid.rowhigh do begin + if bkptno[int1] = anum then begin + result:= int1; + break; + end; + end; +end; + +function tbreakpointsfo.checkbreakpointcontinue( + const stopinfo: stopinfoty): boolean; + //set condition +var + int1: integer; + str1,str2: string; + ptrint1: ptruint; + inf1: breakpointinfoty; + mstr1: msestring; +begin + result:= false; + if (stopinfo.reason = sr_breakpoint_hit) then begin + int1:= findbreakpointrow(stopinfo.bkptno); + if int1 >= 0 then begin + if (condition[int1] <> '') and (flags[int1] = 0) then begin + flags[int1]:= 1; + str1:= ansistring(condition[int1]); + if breakpointerror(gdb.breakcondition(stopinfo.bkptno,str1), + mstr1) then begin + conderr[int1]:= 0; + errormessage[int1]:= mstr1; + end + else begin + conderr[int1]:= -1; + gdb.evaluateexpression(str1,str2); + if not (str2 = 'true') or trystrtoptruint(str2,ptrint1) and + (ptrint1 <> 0) then begin + flags[int1]:= 2; //count has to be decremented + result:= true; + end; + end; + listtoinfo(int1,inf1); + infotolist(int1,inf1,true); + end; + end; + end; +end; + +function tbreakpointsfo.isactivebreakpoint(const addr: qword): boolean; +var + int1: integer; + po1: pqwordaty; + po2: plongboolaty; +begin + result:= false; + po1:= address.griddata.datapo; + po2:= bkpton.griddata.datapo; + for int1:= 0 to grid.rowhigh do begin + if po2^[int1] and (po1^[int1] = addr) then begin + result:= true; + break; + end; + end; +end; + +procedure tbreakpointsfo.toggleaddrbreakpoint(const addr: qword); +var + int1: integer; + po1: pqwordaty; + info1: breakpointinfoty; +begin + po1:= address.griddata.datapo; + for int1:= 0 to grid.rowhigh do begin + if po1^[int1] = addr then begin + if addressbkpt[int1] then begin + grid.deleterow(int1); + end + else begin + bkpton[int1]:= not bkpton[int1]; + updaterow(int1); + end; + exit; + end; + end; + fillchar(info1,sizeof(info1),0); + info1.address:= addr; + info1.addressbreakpoint:= true; + info1.bkpton:= true; + addbreakpoint(info1); +end; + +function tbreakpointsfo.updatebreakpointon(var info: breakpointinfoty): boolean; +var + int1: integer; + wstr1: filenamety; +begin + result:= true; + wstr1:= msefileutils.filename(info.path); + for int1:= grid.rowcount - 1 downto 0 do begin + if (line[int1] = info.line) and (filename[int1] = wstr1) then begin + bkpton[int1]:= info.bkpton; + if gdb.execloaded then begin + result:= gdb.breakenable(bkptno[int1],info.bkpton and + bkptson.value) = gdb_ok; + end; + if conderr[int1] >= 0 then begin + info.conditionmessage:= ' '; + end + else begin + info.conditionmessage:= ''; + end; + sourcefo.updatebreakpointicon(path[int1],infotolineinfo(info)); + if not result then begin + break; + end; + end; + end; + changed; +end; + +procedure tbreakpointsfo.ononsetvalue(const sender: TObject; + var avalue: Boolean; var accept: Boolean); +begin + if gdb.execloaded then begin + gdb.breakenable(bkptno.value,avalue and bkptson.value) + end; +end; + +procedure tbreakpointsfo.ignoreonsetvalue(const sender: TObject; + var avalue: Integer; var accept: Boolean); +begin + if gdb.execloaded then begin + gdb.breakafter(bkptno.value,avalue) + end; +end; + +procedure tbreakpointsfo.conditiononsetvalue(const sender: TObject; + var avalue: mseString; var accept: Boolean); +var + mstr1: msestring; +begin + if gdb.execloaded then begin + if breakpointerror(gdb.breakcondition(bkptno.value,ansistring(avalue)), + mstr1) then begin + conderr.value:= 0; + errormessage.value:= mstr1; + end + else begin + conderr.value:= -1; + end; + end; +end; + +procedure tbreakpointsfo.updaterow(const arow: integer); +var + info: breakpointinfoty; +begin + fillchar(info,sizeof(info),0); + listtoinfo(arow,info); + infotolist(arow,info,true); + changed; +end; + +procedure tbreakpointsfo.ondataentered(const sender: tobject); +begin + updaterow(grid.row); +end; + +procedure tbreakpointsfo.newbkpt(const addressbp: boolean); +begin + addressbkpt.value:= addressbp; + insertbkpt(grid.row,true,true); + changed; +end; + +procedure tbreakpointsfo.ondataenterednewbkpt(const sender: tobject); +begin + newbkpt(false); +end; + +procedure tbreakpointsfo.addressentered(const sender: TObject); +begin + filename.value:= ''; + newbkpt(true); +end; + +procedure tbreakpointsfo.removeactbreakpoint; +var + int1,int2: integer; +begin + int1:= grid.row; + int2:= 1; + gridonrowsdeleting(nil,int1,int2); +end; + +procedure tbreakpointsfo.lineonsetvalue(const sender: TObject; + var avalue: Integer; var accept: Boolean); +begin + removeactbreakpoint; +end; + +procedure tbreakpointsfo.filenameonsetvalue(const sender: tobject; + var avalue: msestring; var accept: boolean); +begin + removeactbreakpoint; + path.value:= filepath(avalue); +end; + +procedure tbreakpointsfo.sourcelinesdeleted(const filepath: msestring; + const aindex, acount: integer); +var + int1: integer; +begin + for int1:= grid.rowcount - 1 downto 0 do begin + if (line[int1] >= aindex) and (path[int1] = filepath) then begin + if line[int1] < aindex + acount then begin + grid.deleterow(int1); + end + else begin + line[int1]:= line[int1] - acount; + end; + end; + end; + changed; +end; + +procedure tbreakpointsfo.sourcelinesinserted(const filepath: msestring; + const aindex, acount: integer); +var + int1: integer; +begin + for int1:= 0 to grid.rowcount - 1 do begin + if (line[int1] >= aindex) and (path[int1] = filepath) then begin + line[int1]:= line[int1] + acount; + end; + end; + changed; +end; + +procedure tbreakpointsfo.changed; +begin + fbreakpointsvalid:= false; + with projectoptions do begin + modified:= true; + addressbreakpoints:= addressbkpt.gridvalues; + breakpointons:= bkpton.gridvalues; + breakpointpaths:= path.gridvalues; + breakpointlines:= line.gridvalues; + breakpointaddress:= address.gridvalues; + breakpointignore:= ignore.gridvalues; + breakpointconditions:= condition.gridvalues; + end; + disassfo.invalidate; +end; + +procedure tbreakpointsfo.refresh; +var + breakpoints: breakpointinfoarty; + int1,int2: integer; +// po1: pintegeraty; +begin + if gdb.active and (visible or watchpointsfo.visible) then begin + gdb.breaklist(breakpoints,false); + if visible then begin + for int1:= 0 to grid.rowhigh do begin + count[int1]:= 0; + for int2:= 0 to high(breakpoints) do begin + with breakpoints[int2] do begin + if bkptno = self.bkptno[int1] then begin + count[int1]:= passcount; + end; + end; + end; + end; +{ + po1:= bkptno.griddata.datapo; + for int1:= 0 to high(breakpoints) do begin + with breakpoints[int1] do begin + for int2:= 0 to grid.rowhigh do begin + if po1^[int2] = bkptno then begin + count[int2]:= passcount; + end; + end; + end; + end; +} + end; + if watchpointsfo.visible then begin + watchpointsfo.refresh(breakpoints); + end; + end; +end; + +procedure tbreakpointsfo.showbreakpoint(const filepath: filenamety; + const aline: integer; const focus: boolean); +var + int1: integer; +begin + for int1:= 0 to grid.rowhigh do begin + if (line[int1] = aline) and issamefilename(filepath,path[int1]) then begin + grid.row:= int1; + show; + if focus then begin + grid.setfocus; + window.bringtofront; + end; + end; + end; +end; + +procedure tbreakpointsfo.showbreakpoint(const aaddress: int64; focus: boolean); +var + int1: integer; +begin + for int1:= 0 to grid.rowhigh do begin + if address[int1] = aaddress then begin + grid.row:= int1; + show(); + if focus then begin + grid.setfocus(); + window.bringtofront(); + end; + end; + end; +end; + +procedure tbreakpointsfo.deleteallexecute(const sender: TObject); +begin + if askok(c[ord(delbr)],c[ord(confirmation)]) then begin + grid.deleterow(0,grid.rowcount); + end; +end; + +procedure tbreakpointsfo.clear; +begin + grid.clear; +end; + +procedure tbreakpointsfo.adbefdrawcell(const sender: tcol; + const canvas: tcanvas; var cellinfo: cellinfoty; + var processed: Boolean); +begin + with cellinfo do begin + if not addressbkpt[cell.row] then begin + color:= cl_active; + end; + end; +end; + +procedure tbreakpointsfo.errhint(const sender: tdatacol; const arow: Integer; + var info: hintinfoty); +begin + if conderr[arow] >= 0 then begin + info.caption:= errormessage[arow]; + end; +end; + +end. diff --git a/mseide-msegui/apps/ide/breakpointsform_mfm.pas b/mseide-msegui/apps/ide/breakpointsform_mfm.pas new file mode 100644 index 0000000..d65f13f --- /dev/null +++ b/mseide-msegui/apps/ide/breakpointsform_mfm.pas @@ -0,0 +1,569 @@ +unit breakpointsform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,breakpointsform; + +const + objdata: record size: integer; data: array[0..11030] of byte end = + (size: 11031; data: ( + 84,80,70,48,14,116,98,114,101,97,107,112,111,105,110,116,115,102,111,13, + 98,114,101,97,107,112,111,105,110,116,115,102,111,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,15,102,114,97,109,101,46,103, + 114,105,112,95,115,105,122,101,2,10,18,102,114,97,109,101,46,103,114,105, + 112,95,111,112,116,105,111,110,115,11,14,103,111,95,99,108,111,115,101,98, + 117,116,116,111,110,16,103,111,95,102,105,120,115,105,122,101,98,117,116,116, + 111,110,14,103,111,95,102,108,111,97,116,98,117,116,116,111,110,12,103,111, + 95,116,111,112,98,117,116,116,111,110,19,103,111,95,98,97,99,107,103,114, + 111,117,110,100,98,117,116,116,111,110,15,103,111,95,110,111,108,111,99,107, + 98,117,116,116,111,110,0,7,118,105,115,105,98,108,101,8,8,98,111,117, + 110,100,115,95,120,2,107,8,98,111,117,110,100,115,95,121,3,148,1,9, + 98,111,117,110,100,115,95,99,120,3,124,2,9,98,111,117,110,100,115,95, + 99,121,3,128,0,26,99,111,110,116,97,105,110,101,114,46,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,0,27,99,111,110,116,97, + 105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100, + 115,1,2,0,2,0,3,114,2,3,128,0,0,22,100,114,97,103,100,111, + 99,107,46,115,112,108,105,116,116,101,114,95,115,105,122,101,2,0,20,100, + 114,97,103,100,111,99,107,46,111,112,116,105,111,110,115,100,111,99,107,11, + 10,111,100,95,115,97,118,101,112,111,115,13,111,100,95,115,97,118,101,122, + 111,114,100,101,114,10,111,100,95,99,97,110,109,111,118,101,11,111,100,95, + 99,97,110,102,108,111,97,116,10,111,100,95,99,97,110,100,111,99,107,11, + 111,100,95,112,114,111,112,115,105,122,101,14,111,100,95,99,97,112,116,105, + 111,110,104,105,110,116,0,7,111,112,116,105,111,110,115,11,10,102,111,95, + 115,97,118,101,112,111,115,13,102,111,95,115,97,118,101,122,111,114,100,101, + 114,12,102,111,95,115,97,118,101,115,116,97,116,101,0,8,115,116,97,116, + 102,105,108,101,7,22,109,97,105,110,102,111,46,112,114,111,106,101,99,116, + 115,116,97,116,102,105,108,101,7,99,97,112,116,105,111,110,6,11,66,114, + 101,97,107,112,111,105,110,116,115,21,105,99,111,110,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,10,105,99,111, + 110,46,105,109,97,103,101,10,0,7,0,0,0,0,0,0,0,0,0,0, + 24,0,0,0,24,0,0,0,204,6,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1, + 238,238,238,1,237,237,237,1,235,235,235,1,234,234,234,1,232,232,232,1, + 230,230,230,1,229,229,229,1,227,227,227,1,226,226,226,1,224,224,224,1, + 223,223,223,1,221,221,221,1,219,219,219,1,218,218,218,1,216,216,216,1, + 215,215,215,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1, + 245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1, + 237,237,237,1,235,235,235,1,234,234,234,1,232,232,232,1,230,230,230,1, + 229,229,229,1,227,227,227,1,226,226,226,1,224,224,224,1,223,223,223,1, + 221,221,221,1,219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1, + 213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1, + 243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1, + 235,235,235,1,234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1, + 227,227,227,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1, + 219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1, + 211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1, + 242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1,235,235,235,1, + 234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1,227,227,227,1, + 226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219,219,1, + 218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1, + 210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1, + 240,240,240,1,238,238,238,1,237,237,237,1,235,235,235,1,234,234,234,1, + 232,232,232,1,225,225,230,1,185,185,234,1,137,137,238,1,136,136,237,1, + 181,181,230,1,219,219,224,1,221,221,221,1,219,219,219,1,218,218,218,1, + 216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1,210,210,210,1, + 208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1, + 238,238,238,1,237,237,237,1,235,235,235,1,228,228,234,1,113,113,244,1, + 7,7,254,1,0,0,255,4,7,7,254,1,106,106,237,1,213,213,219,1, + 218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1, + 210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1, + 240,240,240,1,238,238,238,1,237,237,237,1,197,197,238,1,40,40,251,1, + 0,0,255,8,31,31,242,1,180,180,221,1,215,215,215,2,213,213,213,1, + 211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1, + 242,242,242,1,240,240,240,1,238,238,238,1,231,231,237,1,41,41,252,1, + 0,0,255,10,24,24,235,1,197,197,203,1,214,214,214,1,213,213,213,1, + 211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1, + 242,242,242,1,240,240,240,1,238,238,238,1,115,115,246,1,0,0,255,12, + 54,54,185,1,201,201,201,1,212,212,212,1,211,211,211,1,210,210,210,1, + 208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1, + 233,233,238,1,7,7,254,1,0,0,255,12,3,3,250,1,134,134,139,1, + 210,210,210,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1, + 243,243,243,1,242,242,242,1,240,240,240,1,192,192,241,1,0,0,255,14, + 81,81,130,1,176,176,176,1,210,210,210,2,208,208,208,1,245,245,245,1, + 243,243,243,1,242,242,242,1,240,240,240,1,144,144,245,1,0,0,255,14, + 60,60,161,1,145,145,145,1,209,209,209,1,210,210,210,1,208,208,208,1, + 245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1,144,144,245,1, + 0,0,255,14,59,59,160,1,122,122,122,1,209,209,209,1,210,210,210,1, + 208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1, + 192,192,241,1,0,0,255,14,78,78,127,1,106,106,106,1,208,208,208,1, + 210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1, + 240,240,240,1,233,233,238,1,7,7,254,1,0,0,255,12,3,3,250,1, + 96,96,101,1,122,122,122,1,209,209,209,1,210,210,210,1,208,208,208,1, + 245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1, + 114,114,245,1,0,0,255,12,47,47,178,1,99,99,99,1,145,145,145,1, + 209,209,209,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1, + 242,242,242,1,240,240,240,1,238,238,238,1,230,230,236,1,33,33,244,1, + 0,0,255,10,17,17,228,1,95,95,101,1,100,100,100,1,176,176,176,1, + 210,210,210,2,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1, + 240,240,240,1,238,238,238,1,237,237,237,1,194,194,235,1,26,26,237,1, + 0,0,255,8,17,17,228,1,82,82,123,1,99,99,99,1,137,137,137,1, + 210,210,210,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1, + 243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1, + 234,234,234,1,213,213,219,1,58,58,189,1,3,3,250,1,0,0,255,4, + 3,3,250,1,49,49,180,1,97,97,103,1,100,100,100,1,112,112,112,1, + 201,201,201,1,212,212,212,1,211,211,211,1,210,210,210,1,208,208,208,1, + 245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1, + 237,237,237,1,235,235,235,1,233,233,233,1,217,217,217,1,143,143,148,1, + 86,86,135,1,63,63,164,1,62,62,163,1,82,82,131,1,99,99,104,1, + 101,101,101,2,138,138,138,1,202,202,202,1,214,214,214,1,213,213,213,1, + 211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1, + 242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1,235,235,235,1, + 234,234,234,1,231,231,231,1,227,227,227,1,189,189,189,1,154,154,154,1, + 129,129,129,1,112,112,112,1,128,128,128,1,150,150,150,1,181,181,181,1, + 215,215,215,3,213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1, + 245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1, + 237,237,237,1,235,235,235,1,234,234,234,1,232,232,232,1,230,230,230,1, + 228,228,228,1,225,225,225,1,223,223,223,1,221,221,221,1,220,220,220,1, + 219,219,219,1,218,218,218,2,216,216,216,1,215,215,215,1,213,213,213,1, + 211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1, + 242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1,235,235,235,1, + 234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1,227,227,227,1, + 226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219,219,1, + 218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1, + 210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1, + 240,240,240,1,238,238,238,1,237,237,237,1,235,235,235,1,234,234,234,1, + 232,232,232,1,230,230,230,1,229,229,229,1,227,227,227,1,226,226,226,1, + 224,224,224,1,223,223,223,1,221,221,221,1,219,219,219,1,218,218,218,1, + 216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1,210,210,210,1, + 208,208,208,1,6,111,110,115,104,111,119,7,17,98,114,101,97,107,112,111, + 105,110,116,115,111,110,115,104,111,119,15,109,111,100,117,108,101,99,108,97, + 115,115,110,97,109,101,6,9,116,100,111,99,107,102,111,114,109,0,11,116, + 119,105,100,103,101,116,103,114,105,100,4,103,114,105,100,13,111,112,116,105, + 111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102, + 111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95, + 97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102, + 111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115, + 111,117,116,17,111,119,95,102,111,99,117,115,98,97,99,107,111,110,101,115, + 99,13,111,119,95,109,111,117,115,101,119,104,101,101,108,17,111,119,95,100, + 101,115,116,114,111,121,119,105,100,103,101,116,115,0,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100, + 101,114,2,1,9,112,111,112,117,112,109,101,110,117,7,8,103,114,105,112, + 111,112,117,112,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110, + 100,115,95,121,2,24,9,98,111,117,110,100,115,95,99,120,3,114,2,9, + 98,111,117,110,100,115,95,99,121,2,104,7,97,110,99,104,111,114,115,11, + 6,97,110,95,116,111,112,9,97,110,95,98,111,116,116,111,109,0,11,111, + 112,116,105,111,110,115,103,114,105,100,11,12,111,103,95,99,111,108,115,105, + 122,105,110,103,12,111,103,95,114,111,119,109,111,118,105,110,103,15,111,103, + 95,107,101,121,114,111,119,109,111,118,105,110,103,15,111,103,95,114,111,119, + 105,110,115,101,114,116,105,110,103,14,111,103,95,114,111,119,100,101,108,101, + 116,105,110,103,19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101, + 110,116,101,114,15,111,103,95,97,117,116,111,102,105,114,115,116,114,111,119, + 13,111,103,95,97,117,116,111,97,112,112,101,110,100,20,111,103,95,99,111, + 108,99,104,97,110,103,101,111,110,116,97,98,107,101,121,10,111,103,95,119, + 114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112,117,112,0, + 13,102,105,120,99,111,108,115,46,99,111,117,110,116,2,1,13,102,105,120, + 99,111,108,115,46,105,116,101,109,115,14,1,5,119,105,100,116,104,2,20, + 8,110,117,109,115,116,97,114,116,2,1,7,110,117,109,115,116,101,112,2, + 1,0,0,13,102,105,120,114,111,119,115,46,99,111,117,110,116,2,1,13, + 102,105,120,114,111,119,115,46,105,116,101,109,115,14,1,6,104,101,105,103, + 104,116,2,16,14,99,97,112,116,105,111,110,115,46,99,111,117,110,116,2, + 11,14,99,97,112,116,105,111,110,115,46,105,116,101,109,115,14,1,7,99, + 97,112,116,105,111,110,6,2,111,110,0,1,7,99,97,112,116,105,111,110, + 6,4,70,105,108,101,0,1,0,1,7,99,97,112,116,105,111,110,6,8, + 76,105,110,101,32,78,114,46,0,1,7,99,97,112,116,105,111,110,6,7, + 65,100,100,114,101,115,115,0,1,0,1,0,1,7,99,97,112,116,105,111, + 110,6,5,67,111,117,110,116,0,1,7,99,97,112,116,105,111,110,6,6, + 73,103,110,111,114,101,0,1,0,1,7,99,97,112,116,105,111,110,6,9, + 67,111,110,100,105,116,105,111,110,0,0,0,0,14,100,97,116,97,99,111, + 108,115,46,99,111,117,110,116,2,13,14,100,97,116,97,99,111,108,115,46, + 105,116,101,109,115,14,7,6,98,107,112,116,111,110,1,12,108,105,110,101, + 99,111,108,111,114,102,105,120,4,3,0,0,160,5,119,105,100,116,104,2, + 16,7,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111, + 99,117,115,11,99,111,95,102,105,120,119,105,100,116,104,12,99,111,95,115, + 97,118,101,115,116,97,116,101,0,10,119,105,100,103,101,116,110,97,109,101, + 6,6,98,107,112,116,111,110,9,100,97,116,97,99,108,97,115,115,7,20, + 116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116, + 0,7,8,102,105,108,101,110,97,109,101,1,12,108,105,110,101,99,111,108, + 111,114,102,105,120,4,3,0,0,160,5,119,105,100,116,104,3,158,0,7, + 111,112,116,105,111,110,115,11,12,99,111,95,115,97,118,101,118,97,108,117, + 101,12,99,111,95,115,97,118,101,115,116,97,116,101,0,10,119,105,100,103, + 101,116,110,97,109,101,6,8,102,105,108,101,110,97,109,101,9,100,97,116, + 97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116,114,105, + 110,103,100,97,116,97,108,105,115,116,0,7,4,112,97,116,104,1,12,108, + 105,110,101,99,111,108,111,114,102,105,120,4,3,0,0,160,7,111,112,116, + 105,111,110,115,11,12,99,111,95,105,110,118,105,115,105,98,108,101,12,99, + 111,95,115,97,118,101,118,97,108,117,101,0,10,119,105,100,103,101,116,110, + 97,109,101,6,4,112,97,116,104,9,100,97,116,97,99,108,97,115,115,7, + 22,116,103,114,105,100,109,115,101,115,116,114,105,110,103,100,97,116,97,108, + 105,115,116,0,7,4,108,105,110,101,1,12,108,105,110,101,99,111,108,111, + 114,102,105,120,4,3,0,0,160,7,111,112,116,105,111,110,115,11,12,99, + 111,95,115,97,118,101,118,97,108,117,101,12,99,111,95,115,97,118,101,115, + 116,97,116,101,0,10,119,105,100,103,101,116,110,97,109,101,6,4,108,105, + 110,101,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100,105, + 110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,7,97,100,100, + 114,101,115,115,1,5,119,105,100,116,104,2,61,16,111,110,98,101,102,111, + 114,101,100,114,97,119,99,101,108,108,7,13,97,100,98,101,102,100,114,97, + 119,99,101,108,108,10,119,105,100,103,101,116,110,97,109,101,6,7,97,100, + 100,114,101,115,115,9,100,97,116,97,99,108,97,115,115,7,18,116,103,114, + 105,100,105,110,116,54,52,100,97,116,97,108,105,115,116,0,7,11,97,100, + 100,114,101,115,115,98,107,112,116,1,5,119,105,100,116,104,2,6,7,111, + 112,116,105,111,110,115,11,12,99,111,95,105,110,118,105,115,105,98,108,101, + 12,99,111,95,100,114,97,119,102,111,99,117,115,12,99,111,95,115,97,118, + 101,118,97,108,117,101,12,99,111,95,115,97,118,101,115,116,97,116,101,17, + 99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119, + 105,100,103,101,116,110,97,109,101,6,11,97,100,100,114,101,115,115,98,107, + 112,116,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100,105, + 110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,6,98,107,112, + 116,110,111,1,12,108,105,110,101,99,111,108,111,114,102,105,120,4,3,0, + 0,160,5,119,105,100,116,104,2,19,7,111,112,116,105,111,110,115,11,12, + 99,111,95,105,110,118,105,115,105,98,108,101,12,99,111,95,115,97,118,101, + 118,97,108,117,101,0,10,119,105,100,103,101,116,110,97,109,101,6,6,98, + 107,112,116,110,111,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114, + 105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,5, + 99,111,117,110,116,1,5,99,111,108,111,114,4,7,0,0,144,12,108,105, + 110,101,99,111,108,111,114,102,105,120,4,3,0,0,160,5,119,105,100,116, + 104,2,31,7,111,112,116,105,111,110,115,11,11,99,111,95,114,101,97,100, + 111,110,108,121,10,99,111,95,110,111,102,111,99,117,115,12,99,111,95,115, + 97,118,101,118,97,108,117,101,12,99,111,95,115,97,118,101,115,116,97,116, + 101,0,10,119,105,100,103,101,116,110,97,109,101,6,5,99,111,117,110,116, + 9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100,105,110,116, + 101,103,101,114,100,97,116,97,108,105,115,116,0,7,6,105,103,110,111,114, + 101,1,12,108,105,110,101,99,111,108,111,114,102,105,120,4,3,0,0,160, + 5,119,105,100,116,104,2,30,7,111,112,116,105,111,110,115,11,12,99,111, + 95,115,97,118,101,118,97,108,117,101,12,99,111,95,115,97,118,101,115,116, + 97,116,101,0,10,119,105,100,103,101,116,110,97,109,101,6,6,105,103,110, + 111,114,101,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100, + 105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,7,99,111, + 110,100,101,114,114,1,12,108,105,110,101,99,111,108,111,114,102,105,120,4, + 3,0,0,160,5,119,105,100,116,104,2,7,7,111,112,116,105,111,110,115, + 11,11,99,111,95,114,101,97,100,111,110,108,121,10,99,111,95,110,111,102, + 111,99,117,115,11,99,111,95,102,105,120,119,105,100,116,104,12,99,111,95, + 115,97,118,101,115,116,97,116,101,0,10,111,110,115,104,111,119,104,105,110, + 116,7,7,101,114,114,104,105,110,116,10,119,105,100,103,101,116,110,97,109, + 101,6,7,99,111,110,100,101,114,114,9,100,97,116,97,99,108,97,115,115, + 7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105, + 115,116,0,7,9,99,111,110,100,105,116,105,111,110,1,12,108,105,110,101, + 99,111,108,111,114,102,105,120,4,3,0,0,160,5,119,105,100,116,104,2, + 124,7,111,112,116,105,111,110,115,11,7,99,111,95,102,105,108,108,12,99, + 111,95,115,97,118,101,118,97,108,117,101,12,99,111,95,115,97,118,101,115, + 116,97,116,101,0,8,119,105,100,116,104,109,105,110,2,0,10,119,105,100, + 103,101,116,110,97,109,101,6,9,99,111,110,100,105,116,105,111,110,9,100, + 97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116, + 114,105,110,103,100,97,116,97,108,105,115,116,0,7,12,101,114,114,111,114, + 109,101,115,115,97,103,101,1,5,119,105,100,116,104,2,19,7,111,112,116, + 105,111,110,115,11,12,99,111,95,105,110,118,105,115,105,98,108,101,17,99, + 111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105, + 100,103,101,116,110,97,109,101,6,12,101,114,114,111,114,109,101,115,115,97, + 103,101,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109, + 115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,5,102, + 108,97,103,115,1,5,119,105,100,116,104,2,17,7,111,112,116,105,111,110, + 115,11,12,99,111,95,105,110,118,105,115,105,98,108,101,12,99,111,95,115, + 97,118,101,118,97,108,117,101,12,99,111,95,115,97,118,101,115,116,97,116, + 101,0,10,119,105,100,103,101,116,110,97,109,101,6,5,102,108,97,103,115, + 9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100,105,110,116, + 101,103,101,114,100,97,116,97,108,105,115,116,0,0,13,100,97,116,97,114, + 111,119,104,101,105,103,104,116,2,16,14,111,110,114,111,119,115,100,101,108, + 101,116,105,110,103,7,18,103,114,105,100,111,110,114,111,119,115,100,101,108, + 101,116,105,110,103,13,111,110,114,111,119,115,100,101,108,101,116,101,100,7, + 17,103,114,105,100,111,110,114,111,119,115,100,101,108,101,116,101,100,11,111, + 110,99,101,108,108,101,118,101,110,116,7,15,103,114,105,100,111,110,99,101, + 108,108,101,118,101,110,116,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,12,116,98,111,111,108,101,97,110,101,100,105,116,6,98,107, + 112,116,111,110,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115, + 107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116, + 97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,2,16,9,98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105, + 111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115, + 99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99, + 104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114, + 101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116, + 111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115, + 111,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95, + 97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105, + 99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101, + 49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95, + 107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115, + 116,97,116,101,0,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7, + 13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,118,105,115,105,98, + 108,101,8,10,111,110,115,101,116,118,97,108,117,101,7,12,111,110,111,110, + 115,101,116,118,97,108,117,101,12,118,97,108,117,101,100,101,102,97,117,108, + 116,9,0,0,11,116,115,116,114,105,110,103,101,100,105,116,8,102,105,108, + 101,110,97,109,101,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49, + 11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104, + 116,0,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119, + 95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111, + 99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119, + 95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114, + 111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111, + 121,119,105,100,103,101,116,115,0,11,111,112,116,105,111,110,115,115,107,105, + 110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110, + 108,121,0,8,116,97,98,111,114,100,101,114,2,2,7,118,105,115,105,98, + 108,101,8,8,98,111,117,110,100,115,95,120,2,17,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,158,0,9,98, + 111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100, + 105,116,49,11,13,111,101,49,95,115,97,118,101,118,97,108,117,101,0,13, + 111,110,100,97,116,97,101,110,116,101,114,101,100,7,20,111,110,100,97,116, + 97,101,110,116,101,114,101,100,110,101,119,98,107,112,116,10,111,110,115,101, + 116,118,97,108,117,101,7,18,102,105,108,101,110,97,109,101,111,110,115,101, + 116,118,97,108,117,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,11,116,115,116,114,105,110,103,101,100,105,116,4,112,97,116, + 104,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95, + 97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111, + 119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121, + 119,105,100,103,101,116,115,0,11,111,112,116,105,111,110,115,115,107,105,110, + 11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108, + 121,0,8,116,97,98,111,114,100,101,114,2,3,7,118,105,115,105,98,108, + 101,8,8,98,111,117,110,100,115,95,120,3,176,0,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,50,9,98,111, + 117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105, + 116,49,11,13,111,101,49,95,115,97,118,101,118,97,108,117,101,0,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,12,116,105,110, + 116,101,103,101,114,101,100,105,116,4,108,105,110,101,14,111,112,116,105,111, + 110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103, + 108,121,112,104,104,101,105,103,104,116,0,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115, + 105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,11,111, + 112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109, + 101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101, + 114,2,4,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95, + 120,3,227,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,16,12, + 111,112,116,105,111,110,115,101,100,105,116,49,11,13,111,101,49,95,115,97, + 118,101,118,97,108,117,101,0,13,111,110,100,97,116,97,101,110,116,101,114, + 101,100,7,20,111,110,100,97,116,97,101,110,116,101,114,101,100,110,101,119, + 98,107,112,116,10,111,110,115,101,116,118,97,108,117,101,7,14,108,105,110, + 101,111,110,115,101,116,118,97,108,117,101,3,109,105,110,2,1,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,10,116,105,110,116, + 54,52,101,100,105,116,7,97,100,100,114,101,115,115,14,111,112,116,105,111, + 110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103, + 108,121,112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110,115,115, + 107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110, + 111,110,108,121,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0, + 17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,3, + 0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,114,108,95,108,101,118,101,108,111,10,102,114,108,95,108,101,118, + 101,108,105,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 8,116,97,98,111,114,100,101,114,2,5,7,118,105,115,105,98,108,101,8, + 8,98,111,117,110,100,115,95,120,3,22,1,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,120,2,61,9,98,111,117,110, + 100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49, + 11,13,111,101,49,95,115,97,118,101,118,97,108,117,101,0,9,102,111,110, + 116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111, + 110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0, + 13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,14,97,100,100,114, + 101,115,115,101,110,116,101,114,101,100,4,98,97,115,101,7,6,110,98,95, + 104,101,120,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,14,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116, + 11,97,100,100,114,101,115,115,98,107,112,116,14,111,112,116,105,111,110,115, + 119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121, + 112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110,115,115,107,105, + 110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110, + 108,121,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102, + 114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,3,0,0, + 128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,10,102,114,108,95,108,101,118,101,108, + 105,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116, + 97,98,111,114,100,101,114,2,6,8,98,111,117,110,100,115,95,120,3,84, + 1,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,2,6,9,98,111,117,110,100,115,95,99,121,2,16,7,118,105,115, + 105,98,108,101,8,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,6,98,107,112, + 116,110,111,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19, + 111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0, + 13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109, + 111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117, + 115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97, + 114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119, + 102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,0,11,111,112,116,105,111,110,115,115,107,105,110,11, + 19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121, + 0,8,116,97,98,111,114,100,101,114,2,7,7,118,105,115,105,98,108,101, + 8,8,98,111,117,110,100,115,95,120,3,91,1,8,98,111,117,110,100,115, + 95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,19,9,98,111,117, + 110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116, + 49,11,13,111,101,49,95,115,97,118,101,118,97,108,117,101,0,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,12,116,105,110,116, + 101,103,101,114,101,100,105,116,5,99,111,117,110,116,14,111,112,116,105,111, + 110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103, + 108,121,112,104,104,101,105,103,104,116,0,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115, + 105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,11,111, + 112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109, + 101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101, + 114,2,8,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95, + 120,3,111,1,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,120,2,31,9,98,111,117,110,100,115,95,99,121,2,16,12, + 111,112,116,105,111,110,115,101,100,105,116,49,11,13,111,101,49,95,115,97, + 118,101,118,97,108,117,101,0,11,111,112,116,105,111,110,115,101,100,105,116, + 11,11,111,101,95,114,101,97,100,111,110,108,121,12,111,101,95,117,110,100, + 111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121, + 16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101, + 95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115, + 101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111, + 110,99,117,114,115,111,114,13,111,101,95,97,117,116,111,115,101,108,101,99, + 116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114, + 115,116,99,108,105,99,107,0,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,14,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,6, + 105,103,110,111,114,101,14,111,112,116,105,111,110,115,119,105,100,103,101,116, + 49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103, + 104,116,0,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,11,111,112,116,105,111,110,115,115,107, + 105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111, + 110,108,121,0,8,116,97,98,111,114,100,101,114,2,9,7,118,105,115,105, + 98,108,101,8,8,98,111,117,110,100,115,95,120,3,143,1,8,98,111,117, + 110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,30,9, + 98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101, + 100,105,116,49,11,13,111,101,49,95,115,97,118,101,118,97,108,117,101,0, + 11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100, + 111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121, + 16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101, + 95,115,104,105,102,116,114,101,116,117,114,110,24,111,101,95,102,111,114,99, + 101,114,101,116,117,114,110,99,104,101,99,107,118,97,108,117,101,12,111,101, + 95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115, + 101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111, + 110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101, + 114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97, + 117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99, + 107,0,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,13,111,110, + 100,97,116,97,101,110,116,101,114,101,100,10,111,110,115,101,116,118,97,108, + 117,101,7,16,105,103,110,111,114,101,111,110,115,101,116,118,97,108,117,101, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,9,116, + 100,97,116,97,105,99,111,110,7,99,111,110,100,101,114,114,14,111,112,116, + 105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110, + 116,103,108,121,112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110, + 115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116, + 111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,10,8,98, + 111,117,110,100,115,95,120,3,174,1,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,2,7,9,98,111,117,110,100,115, + 95,99,121,2,16,11,111,112,116,105,111,110,115,101,100,105,116,11,11,111, + 101,95,114,101,97,100,111,110,108,121,12,111,101,95,117,110,100,111,111,110, + 101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101, + 95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101,97, + 116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101, + 99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117, + 114,115,111,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111, + 101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99, + 108,105,99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17, + 111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101, + 49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118, + 101,115,116,97,116,101,0,7,118,105,115,105,98,108,101,8,9,105,109,97, + 103,101,108,105,115,116,7,21,97,99,116,105,111,110,115,109,111,46,98,117, + 116,116,111,110,105,99,111,110,115,11,105,109,97,103,101,111,102,102,115,101, + 116,2,10,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0, + 0,11,116,115,116,114,105,110,103,101,100,105,116,9,99,111,110,100,105,116, + 105,111,110,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19, + 111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0, + 13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109, + 111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117, + 115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97, + 114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119, + 102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,0,11,111,112,116,105,111,110,115,115,107,105,110,11, + 19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121, + 0,8,116,97,98,111,114,100,101,114,2,11,7,118,105,115,105,98,108,101, + 8,8,98,111,117,110,100,115,95,120,3,182,1,8,98,111,117,110,100,115, + 95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,124,9,98,111,117, + 110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116, + 49,11,13,111,101,49,95,115,97,118,101,118,97,108,117,101,0,11,111,112, + 116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110, + 101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101, + 95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101,97, + 116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101, + 99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117, + 114,115,111,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111, + 101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99, + 108,105,99,107,12,111,101,95,116,114,105,109,114,105,103,104,116,11,111,101, + 95,116,114,105,109,108,101,102,116,0,13,111,110,100,97,116,97,101,110,116, + 101,114,101,100,7,13,111,110,100,97,116,97,101,110,116,101,114,101,100,10, + 111,110,115,101,116,118,97,108,117,101,7,19,99,111,110,100,105,116,105,111, + 110,111,110,115,101,116,118,97,108,117,101,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,0,11,116,115,116,114,105,110,103,101,100,105, + 116,12,101,114,114,111,114,109,101,115,115,97,103,101,14,111,112,116,105,111, + 110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103, + 108,121,112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110,115,115, + 107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110, + 111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,12,7,118,105,115, + 105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,51,2,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,19, + 9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115, + 101,100,105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105,116,11, + 12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111, + 115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97, + 110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12, + 111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101, + 116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105, + 116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110, + 116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101, + 95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108, + 105,99,107,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,5,102,108,97,103, + 115,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119, + 49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,13,111, + 112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117, + 115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13, + 111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114, + 111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111, + 99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100, + 103,101,116,115,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111, + 115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8, + 116,97,98,111,114,100,101,114,2,13,7,118,105,115,105,98,108,101,8,8, + 98,111,117,110,100,115,95,120,3,71,2,8,98,111,117,110,100,115,95,121, + 2,0,9,98,111,117,110,100,115,95,99,120,2,17,9,98,111,117,110,100, + 115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11, + 13,111,101,49,95,115,97,118,101,118,97,108,117,101,0,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,0,12,116,98,111,111,108, + 101,97,110,101,100,105,116,7,98,107,112,116,115,111,110,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,15,66,114,101,97,107,112,111,105,110, + 116,115,32,38,111,110,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,1,2,98,2,2,0,8,98,111,117,110,100,115,95, + 120,2,8,8,98,111,117,110,100,115,95,121,2,4,9,98,111,117,110,100, + 115,95,99,120,2,111,9,98,111,117,110,100,115,95,99,121,2,16,8,115, + 116,97,116,102,105,108,101,7,22,109,97,105,110,102,111,46,112,114,111,106, + 101,99,116,115,116,97,116,102,105,108,101,11,111,112,116,105,111,110,115,101, + 100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101, + 95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107, + 109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117,114, + 110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120, + 105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111, + 101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111, + 115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,8, + 111,110,99,104,97,110,103,101,7,15,98,107,112,116,115,111,110,111,110,99, + 104,97,110,103,101,10,111,110,115,101,116,118,97,108,117,101,7,17,98,107, + 112,116,115,111,110,111,110,115,101,116,118,97,108,117,101,5,118,97,108,117, + 101,9,0,0,10,116,112,111,112,117,112,109,101,110,117,8,103,114,105,112, + 111,112,117,112,18,109,101,110,117,46,115,117,98,109,101,110,117,46,99,111, + 117,110,116,2,1,18,109,101,110,117,46,115,117,98,109,101,110,117,46,105, + 116,101,109,115,14,1,7,99,97,112,116,105,111,110,6,10,68,101,108,101, + 116,101,32,97,108,108,5,115,116,97,116,101,11,15,97,115,95,108,111,99, + 97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110, + 101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7,16, + 100,101,108,101,116,101,97,108,108,101,120,101,99,117,116,101,0,0,9,109, + 101,110,117,46,110,97,109,101,6,9,103,114,105,100,112,111,112,117,112,4, + 108,101,102,116,3,168,0,0,0,16,116,115,116,114,105,110,103,99,111,110, + 116,97,105,110,101,114,1,99,12,115,116,114,105,110,103,115,46,100,97,116, + 97,1,6,17,66,114,101,97,107,112,111,105,110,116,32,101,114,114,111,114, + 46,6,16,66,82,69,65,75,80,79,73,78,84,32,69,82,82,79,82,6, + 38,68,111,32,121,111,117,32,119,105,115,104,32,116,111,32,100,101,108,101, + 116,101,32,97,108,108,32,98,114,101,97,107,112,111,105,110,116,115,63,6, + 12,67,111,110,102,105,114,109,97,116,105,111,110,0,4,108,101,102,116,3, + 88,1,3,116,111,112,2,80,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tbreakpointsfo,''); +end. diff --git a/mseide-msegui/apps/ide/cdesignparser.pas b/mseide-msegui/apps/ide/cdesignparser.pas new file mode 100644 index 0000000..7833144 --- /dev/null +++ b/mseide-msegui/apps/ide/cdesignparser.pas @@ -0,0 +1,637 @@ +{ MSEide Copyright (c) 2012 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit cdesignparser; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseparser,msedesignparser,mselist,msestrings,msehash; + +type + + tcdesignparser = class(tcparser,idesignparser) + private + funitinfopo: punitinfoty; +// fimplementation: boolean; +// finterface: boolean; + finterfaceonly: boolean; + fnoautoparse: boolean; + ffunctionlevel: integer; + protected + function parsefunction: boolean; + function parsefunctionparams: boolean; + function parseblock: boolean; + function parsetypedef: boolean; + function parsevardef: boolean; + function parsestatement: boolean; + public + constructor create(unitinfopo: punitinfoty; + const afilelist: tmseindexednamelist; + const getincludefile: getincludefileeventty; + const ainterfaceonly: boolean); overload; + constructor create(const afilelist: tmseindexednamelist; + const atext: string); overload; + procedure initidents; override; + function dogetincludefile(const afilename: filenamety; + const astatementstart,astatementend: sourceposty): tscanner; override; + procedure parse; override; + procedure clear; override; + end; + + tcfunctions = class(tfunctions) + end; + + tcunitinfo = class(tunitinfo) + public + constructor create; + destructor destroy; override; + end; + + tcrootdeflist = class(trootdeflist) + protected + procedure finalizerecord(var item); override; + end; + + cglobfuncinfoty = record + list: tcrootdeflist; + id: integer; + end; + pcglobfuncinfoty = ^cglobfuncinfoty; + cglobfunchashdataty = record + header: hashheaderty; + data: cglobfuncinfoty; + end; + pcglobfunchashdataty = ^cglobfunchashdataty; + + tcglobals = class(thashdatalist) + private + fclosing: boolean; + flistparam: tcrootdeflist; + fidparam: integer; + fansistringparam: ansistring; + procedure checkfunctioninfo(const aitem: phashdataty; var accept: boolean); + procedure checkfindname(var stop: boolean); + protected + procedure add(const alist: tcrootdeflist; const aid: integer); +// procedure checkexact(const aitemdata; var accept: boolean); override; + function hashkey(const akey): hashvaluety; override; + function checkkey(const akey; const aitem: phashdataty): boolean; override; + procedure delete(const alist: tcrootdeflist; const aid: integer); + function checkfind(const aname: ansistring): pcglobfuncinfoty; + function getrecordsize(): int32 override; + public + property closing: boolean read fclosing; +// constructor create; + function finddef(const aname: ansistring): pdefinfoty; + function findfunction(const aname: ansistring): pfunctioninfoty; + end; + + tcprocdeflist = class(tdeflist) + end; + +procedure parsecdef(const adef: pdefinfoty; out atext: string; out scope: tdeflist); +function cglobals: tcglobals; +procedure beginfinalizecglobals; +procedure finalizecglobals; + +implementation +uses + sourceupdate,msedesigner,sysutils,projecttreeform; +var + fcglobals: tcglobals; + +function cglobals: tcglobals; +begin + if fcglobals = nil then begin + fcglobals:= tcglobals.create; + end; + result:= fcglobals; +end; + +procedure finalizecglobals; +begin + freeandnil(fcglobals); +end; + +procedure beginfinalizecglobals; +begin + if fcglobals <> nil then begin + fcglobals.fclosing:= true; + end; +end; + +procedure parsecdef(const adef: pdefinfoty; out atext: string; out scope: tdeflist); + //add used identifiers +var + parser: tcparser; + + procedure doaddidents; + begin + with parser do begin + while checkoperator('*') do begin + end; + scope.addidentpath(parser,'.'); + if checkoperator('[') then begin + findoperator(']'); + end; + while checkoperator('*') do begin + end; + scope.addidentpath(parser,'.'); + end; + end; + + procedure dofunctionparameters; + begin + with parser do begin + while not eof do begin + doaddidents; //type, parameter + if checkoperator(')') then begin + break; + end; + if not checkoperator(';') then begin + nexttoken; + end; + end; + end; + end; + +begin + scope:= tdeflist.create(adef^.kind,true); + atext:= sourceupdater.getdefinfotext(adef); + if atext <> '' then begin + parser:= tcparser.create(designer.designfiles,atext); + try + with parser do begin + doaddidents; //type, function name + if checkoperator('(') then begin + dofunctionparameters; + end; + if checkoperator('{') then begin + repeat + doaddidents; + if checkoperator('=') then begin //assignment + doaddidents; + checkoperator(';'); + end + else begin + if checkoperator('(') then begin + dofunctionparameters; + end + else begin + nexttoken; + end; + end; + until eof or checkoperator('}'); + end; + end; + finally + parser.free; + end; + end; +end; + +{ tcdesignparser } + +constructor tcdesignparser.create(unitinfopo: punitinfoty; + const afilelist: tmseindexednamelist; + const getincludefile: getincludefileeventty; + const ainterfaceonly: boolean); +begin + finterfaceonly:= ainterfaceonly; + inherited create(afilelist); + funitinfopo:= unitinfopo; + funitinfopo^.interfacecompiled:= false; + funitinfopo^.implementationcompiled:= false; + ongetincludefile:= getincludefile; +end; + +constructor tcdesignparser.create(const afilelist: tmseindexednamelist; + const atext: string); +begin + fnoautoparse:= true; + inherited create(afilelist,atext); +end; + +{ +constructor tcdesignparser.create(unitinfopo: punitinfoty; + const afilelist: tmseindexednamelist; + const getincludefile: getincludefileeventty; + const ainterfaceonly: boolean; const atext: ansistring); +begin + create(unitinfopo,afilelist,getincludefile,ainterfaceonly); + create(afilelist,atext); +end; +} +function tcdesignparser.parsetypedef: boolean; +begin + result:= false; +end; + +function tcdesignparser.parsevardef: boolean; +begin + result:= false; +end; + +function tcdesignparser.parsefunctionparams: boolean; +begin + result:= false; + mark; + if checkoperator('(') then begin + result:= findoperator(')'); + end; + if result then begin + pop; + end + else begin + back; + end; +end; + +function tcdesignparser.parseblock: boolean; +var + ch1: char; +begin + result:= true; + skipwhitespace; + mark; + if checkoperator('{') then begin + while not eof do begin + ch1:= getoperator; + case ch1 of + '}': begin + break; + end; + '{': begin + parseblock(); + end; + else begin + parsestatement; + end; + end; + end; + end; + if result then begin + pop; + end + else begin + back; + end; +end; + +function tcdesignparser.parsefunction: boolean; //todo: optimize +var + {lstr1,}lstr2: lstringty; + str1: string; +// ch1: char; + pos1: sourceposty; +// po1: pfunctioninfoty; + po2: pfunctionheaderinfoty; + static: boolean; + bo1: boolean; +begin + inc(ffunctionlevel); + result:= false; + skipwhitespace; + mark; + pos1:= sourcepos; + with funitinfopo^ do begin + static:= false; + bo1:= false; + while not eof do begin + case fto^.kind of + tk_name: begin + if checkident(ord(cid_static)) then begin + static:= true; + end + else begin + nexttoken; + end; + end; + tk_operator: begin + if fto^.op = '(' then begin + bo1:= true; + break; + end + else begin + if fto^.op = ';' then begin + break; + end; + nexttoken; + end; + end; + else begin + nexttoken; + end; + end; + end; + if bo1 then begin + lastnonwhitetoken; + if getorigname(lstr2) then begin //function name + if parsefunctionparams then begin + if (ffunctionlevel = 1) and testoperator(';') then begin + po2:= c.functionheaders.newitem; + po2^.name:= lstringtostring(lstr2); + deflist.add(pos1,sourcepos,po2); + nexttoken; + result:= true; //header + end + else begin + if testoperator('{') then begin + result:= true; + str1:= lstringtostring(lstr2); + with deflist.beginnode(str1,syk_procimp,pos1,sourcepos)^ do begin + //new scope + if ffunctionlevel = 1 then begin + include(symbolflags,syf_global); + c.functions.add(str1,pos1,sourcepos); + end; + end; + parseblock; + deflist.endnode(sourcepos); + if not static and (ffunctionlevel = 1) then begin + cglobals.add(tcrootdeflist(deflist),deflist.infocount-1); + end; + end; + end; + end; + end; + end; + end; + if result then begin + pop; + end + else begin + back; + end; + dec(ffunctionlevel); +end; + +function tcdesignparser.parsestatement: boolean; +var + lstr1{,lstr2}: lstringty; + ch1: char; + bo1: boolean; + pos1: sourceposty; +begin + result:= true; + bo1:= ffunctionlevel = 0; + skipwhitespace; + mark; + if not bo1 then begin //in function body + skipidents; //remove keywords + pos1:= sourcepos; + if getnamenoident(lstr1) then begin + repeat + ch1:= getoperator; + case ch1 of + '(': begin + funitinfopo^.deflist.actnode.startident(pos1,lstr1.len); +// funitinfopo^.deflist.actnode.addident(pos1,lstr1.len); + findclosingbracket; //function call + funitinfopo^.deflist.actnode.endident(self); + end; + '=': begin + skipstatement; //assignment + break; + end; + ';': begin + break; + end; + else begin + bo1:= true; + break; + end; + end; + until ch1 = #0; + end + else begin + if checkoperator('{') then begin + parseblock; + end + else begin + bo1:= true; + end; + end; + end; + if bo1 then begin + back; + if not parsefunction then begin + if not parsetypedef then begin + if not parsevardef then begin + skipstatement; + end; + end; + end; + end + else begin + pop; + end; +end; + +procedure tcdesignparser.parse; +//var +// po1: pfunctioninfoty; +// int1: integer; +begin + inherited; + if fnoautoparse then begin + exit; + end; + initcompinfo(funitinfopo^); + while not eof do begin + parsestatement; + end; + afterparse(self,funitinfopo^,true); + projecttree.cmodules.modulecompiled(funitinfopo^.sourcefilename); +end; + +procedure tcdesignparser.clear; +begin + inherited; + ffunctionlevel:= 0; +end; + +function tcdesignparser.dogetincludefile(const afilename: filenamety; + const astatementstart: sourceposty; + const astatementend: sourceposty): tscanner; +begin + result:= inherited dogetincludefile(afilename,astatementstart,astatementend); + if result <> nil then begin + addincludefile(funitinfopo^,afilename,astatementstart,astatementend); + end; +end; + +procedure tcdesignparser.initidents; +begin + setidents(cidents); +end; + +{ tcunitinfo } + +constructor tcunitinfo.create; +begin + with info do begin + proglang:= pl_c; + c.functionheaders:= tfunctionheaders.create; + c.functions:= tcfunctions.create; + if deflist = nil then begin + deflist:= tcrootdeflist.create(@info); + end; + end; + inherited; +end; + +destructor tcunitinfo.destroy; +//var +// int1: integer; +// po1: pfunctioninfoty; +begin + with info do begin + c.functionheaders.free; + c.functions.free; + end; + inherited; +end; + +{ tcglobals } +{ +constructor tcglobals.create; +begin + inherited create(sizeof(cglobfuncinfoty)); +end; +} +procedure tcglobals.add(const alist: tcrootdeflist; const aid: integer); +var + po1: pcglobfunchashdataty; +begin + with alist.finfos[aid] do begin + po1:= pcglobfunchashdataty(internaladd(name)); + end; + with po1^.data do begin + list:= alist; + id:= aid; + end; +end; + +function tcglobals.hashkey(const akey): hashvaluety; +begin + result:= stringhash(ansistring(akey)); +end; + +procedure tcglobals.checkfunctioninfo(const aitem: phashdataty; + var accept: boolean); +begin + with pcglobfunchashdataty(aitem)^.data do begin + accept:= (list = flistparam) and (id = fidparam); + end; +end; + +procedure tcglobals.delete(const alist: tcrootdeflist; const aid: integer); +var + po1: phashdataty; +begin + flistparam:= alist; + fidparam:= aid; + with alist.finfos[aid] do begin + po1:= internalfind(name,{$ifdef FPC}@{$endif}checkfunctioninfo); + end; + if po1 <> nil then begin + internaldeleteitem(po1); + end; +end; + +function tcglobals.checkkey(const akey; const aitem: phashdataty): boolean; +begin + with pcglobfunchashdataty(aitem)^.data do begin + with list.finfos[id] do begin + result:= ansistring(akey) = name; + end; + end; +end; + +procedure tcglobals.checkfindname(var stop: boolean); +begin + stop:= internalfind(fansistringparam) <> nil; +end; + +function tcglobals.checkfind(const aname: ansistring): pcglobfuncinfoty; +var + po1: pcglobfunchashdataty; +begin + result:= nil; + po1:= pcglobfunchashdataty(internalfind(aname)); + if po1 = nil then begin + fansistringparam:= aname; + projecttree.cmodules.parse({$ifdef FPC}@{$endif}checkfindname); + po1:= pcglobfunchashdataty(internalfind(aname)); + end; + if po1 <> nil then begin + result:= @po1^.data; + end; +end; + +function tcglobals.getrecordsize(): int32; +begin + result:= sizeof(cglobfunchashdataty); +end; + +function tcglobals.finddef(const aname: ansistring): pdefinfoty; +var + po1: pcglobfuncinfoty; +begin + result:= nil; + po1:= checkfind(aname); + if po1 <> nil then begin + with po1^ do begin + result:= @list.finfos[id]; + end; + end; +end; + +function tcglobals.findfunction(const aname: ansistring): pfunctioninfoty; +var + po1: pcglobfunchashdataty; +begin + result:= nil; + po1:= pcglobfunchashdataty(internalfind(aname)); + if po1 <> nil then begin + with po1^.data do begin + with list.unitinfopo^ do begin + if proglang = pl_c then begin + result:= c.functions.find(aname); + end; + end; + end; + end; +end; + +{ tcrootdeflist } + +procedure tcrootdeflist.finalizerecord(var item); +begin + if (fcglobals <> nil) and not fcglobals.closing then begin + with finfos[defnamety(item).id] do begin + if (kind = syk_procimp) and (syf_global in symbolflags) then begin + fcglobals.delete(self,defnamety(item).id); + end; + end; + end; + inherited; +end; +initialization +finalization + finalizecglobals; +end. diff --git a/mseide-msegui/apps/ide/commandlineform.mfm b/mseide-msegui/apps/ide/commandlineform.mfm new file mode 100644 index 0000000..9dd3098 --- /dev/null +++ b/mseide-msegui/apps/ide/commandlineform.mfm @@ -0,0 +1,41 @@ +object commandlinefo: tcommandlinefo + optionswidget = [ow_arrowfocus, ow_subfocus, ow_destroywidgets, ow_hinton] + bounds_x = 241 + bounds_y = 310 + bounds_cx = 542 + bounds_cy = 100 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.bounds = ( + 0 + 0 + 542 + 100 + ) + options = [fo_screencentered, fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder, fo_savestate] + caption = 'Command Line' + moduleclassname = 'tmseform' + object disp: tmemoedit + frame.framei_left = 3 + frame.framei_top = 3 + frame.framei_right = 3 + frame.framei_bottom = 3 + frame.sbhorz.pagesize = 1 + frame.sbvert.pagesize = 1 + frame.localprops = [frl_colorclient] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 542 + bounds_cy = 100 + anchors = [] + optionsedit1 = [oe1_multiline, oe1_autopopupmenu, oe1_keyexecute, oe1_savevalue, oe1_savestate] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_linebreak, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + object c: tstringcontainer + strings.data = ( + 'Make disabled by Default make col!' + ) + left = 184 + top = 32 + end +end diff --git a/mseide-msegui/apps/ide/commandlineform.pas b/mseide-msegui/apps/ide/commandlineform.pas new file mode 100644 index 0000000..61ff50b --- /dev/null +++ b/mseide-msegui/apps/ide/commandlineform.pas @@ -0,0 +1,59 @@ +{ MSEide Copyright (c) 1999-2006 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit commandlineform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msegui,mseclasses,mseforms,msedataedits,msestringcontainer,msestrings; + +type + stringconsts = ( + makedisabled //0 Make disabled by Default make col! + ); + + tcommandlinefo = class(tmseform) + disp: tmemoedit; + c: tstringcontainer; + end; + +procedure showcommandline; + +implementation +uses + commandlineform_mfm,make,projectoptionsform; + +procedure showcommandline; +var + fo: tcommandlinefo; +begin + fo:= tcommandlinefo.create(nil); + try + if projectoptions.defaultmake >= maxdefaultmake then begin + fo.disp.value:= fo.c[ord(makedisabled)]; + end + else begin + fo.disp.value:= buildmakecommandline(projectoptions.defaultmake); + end; + fo.show(true); + finally + fo.Free; + end; +end; + +end. diff --git a/mseide-msegui/apps/ide/commandlineform_mfm.pas b/mseide-msegui/apps/ide/commandlineform_mfm.pas new file mode 100644 index 0000000..a5664f1 --- /dev/null +++ b/mseide-msegui/apps/ide/commandlineform_mfm.pas @@ -0,0 +1,72 @@ +unit commandlineform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,commandlineform; + +const + objdata: record size: integer; data: array[0..1091] of byte end = + (size: 1092; data: ( + 84,80,70,48,14,116,99,111,109,109,97,110,100,108,105,110,101,102,111,13, + 99,111,109,109,97,110,100,108,105,110,101,102,111,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,9,111,119,95,104,105,110,116, + 111,110,0,8,98,111,117,110,100,115,95,120,3,241,0,8,98,111,117,110, + 100,115,95,121,3,54,1,9,98,111,117,110,100,115,95,99,120,3,30,2, + 9,98,111,117,110,100,115,95,99,121,2,100,23,99,111,110,116,97,105,110, + 101,114,46,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119, + 95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111, + 99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,11,111,119, + 95,115,117,98,102,111,99,117,115,19,111,119,95,109,111,117,115,101,116,114, + 97,110,115,112,97,114,101,110,116,17,111,119,95,100,101,115,116,114,111,121, + 119,105,100,103,101,116,115,0,16,99,111,110,116,97,105,110,101,114,46,98, + 111,117,110,100,115,1,2,0,2,0,3,30,2,2,100,0,7,111,112,116, + 105,111,110,115,11,17,102,111,95,115,99,114,101,101,110,99,101,110,116,101, + 114,101,100,13,102,111,95,99,108,111,115,101,111,110,101,115,99,15,102,111, + 95,97,117,116,111,114,101,97,100,115,116,97,116,16,102,111,95,97,117,116, + 111,119,114,105,116,101,115,116,97,116,10,102,111,95,115,97,118,101,112,111, + 115,13,102,111,95,115,97,118,101,122,111,114,100,101,114,12,102,111,95,115, + 97,118,101,115,116,97,116,101,0,7,99,97,112,116,105,111,110,6,12,67, + 111,109,109,97,110,100,32,76,105,110,101,15,109,111,100,117,108,101,99,108, + 97,115,115,110,97,109,101,6,8,116,109,115,101,102,111,114,109,0,9,116, + 109,101,109,111,101,100,105,116,4,100,105,115,112,17,102,114,97,109,101,46, + 102,114,97,109,101,105,95,108,101,102,116,2,3,16,102,114,97,109,101,46, + 102,114,97,109,101,105,95,116,111,112,2,3,18,102,114,97,109,101,46,102, + 114,97,109,101,105,95,114,105,103,104,116,2,3,19,102,114,97,109,101,46, + 102,114,97,109,101,105,95,98,111,116,116,111,109,2,3,21,102,114,97,109, + 101,46,115,98,104,111,114,122,46,112,97,103,101,115,105,122,101,2,1,21, + 102,114,97,109,101,46,115,98,118,101,114,116,46,112,97,103,101,115,105,122, + 101,2,1,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,8,98, + 111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0, + 9,98,111,117,110,100,115,95,99,120,3,30,2,9,98,111,117,110,100,115, + 95,99,121,2,100,7,97,110,99,104,111,114,115,11,0,12,111,112,116,105, + 111,110,115,101,100,105,116,49,11,13,111,101,49,95,109,117,108,116,105,108, + 105,110,101,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110, + 117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49, + 95,115,97,118,101,118,97,108,117,101,13,111,101,49,95,115,97,118,101,115, + 116,97,116,101,0,11,111,112,116,105,111,110,115,101,100,105,116,11,11,111, + 101,95,114,101,97,100,111,110,108,121,12,111,101,95,117,110,100,111,111,110, + 101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101, + 95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,108,105, + 110,101,98,114,101,97,107,14,111,101,95,115,104,105,102,116,114,101,116,117, + 114,110,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114, + 101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95, + 101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111, + 110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116, + 25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115, + 116,99,108,105,99,107,0,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,0,16,116,115,116,114,105,110,103,99,111,110,116,97,105,110, + 101,114,1,99,12,115,116,114,105,110,103,115,46,100,97,116,97,1,6,34, + 77,97,107,101,32,100,105,115,97,98,108,101,100,32,98,121,32,68,101,102, + 97,117,108,116,32,109,97,107,101,32,99,111,108,33,0,4,108,101,102,116, + 3,184,0,3,116,111,112,2,32,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tcommandlinefo,''); +end. diff --git a/mseide-msegui/apps/ide/componentpaletteform.mfm b/mseide-msegui/apps/ide/componentpaletteform.mfm new file mode 100644 index 0000000..6e30f4f --- /dev/null +++ b/mseide-msegui/apps/ide/componentpaletteform.mfm @@ -0,0 +1,134 @@ +object componentpalettefo: tcomponentpalettefo + optionswidget = [ow_arrowfocus, ow_subfocus, ow_destroywidgets, ow_hinton] + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_floatbutton, go_topbutton, go_backgroundbutton, go_nolockbutton, go_buttonhints] + visible = False + bounds_x = 131 + bounds_y = 289 + bounds_cx = 738 + bounds_cy = 69 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.frame.localprops = [] + container.frame.localprops1 = [] + container.onlayout = componentgrouponchildscaled + container.bounds = ( + 0 + 0 + 728 + 69 + ) + dragdock.caption = 'Component Palette' + dragdock.optionsdock = [od_savepos, od_savezorder, od_canmove, od_canfloat, od_candock, od_proportional, od_propsize, od_captionhint, od_childicons] + options = [fo_savepos, fo_savezorder, fo_savestate] + statfile = mainfo.projectstatfile + icon.transparentcolor = -2147483642 + icon.options = [bmo_masked] + icon.image = { + 0000000002000000180000001800000064070000000000000000000000000000 + 0000000000000000000000000000000000000000D0D0D00AFFFFFF0AD0D0D004 + FFFFFF0BD0D0D001B7B7B701C6C6C601CACACA01C8C8C801D0D0D00385858501 + D0D0D004FFFFFF01BABABA01AFAFAF01C1C1C101D0D0D00585858501FFFFFF01 + ACACAC01878787018D8D8D019494940181818101D0D0D00385858501D0D0D004 + FFFFFF019D9D9D018D8D8D018A8A8A019494940189898901D0D0D00385858501 + FFFFFF01C5C5C501C4C4C401BDBDBD01B9B9B901B5B5B501D0D0D00385858501 + D0D0D004FFFFFF01C0C0C001B3B3B301BDBDBD01BCBCBC01B3B3B301D0D0D003 + 8585850FF5F5F501F3F3F301F2F2F201E8EEEE01EEEEEE01EDEDED01EBEBEB01 + EAEAEA01E8E8E801E6E6E601E5E5E501E3E3E301E2E2E201E0E0E001DFDFDF01 + DDDDDD01DBDBDB01DADADA01D8D8D801D7D7D701D5D5D501D3D3D301D2D2D201 + D0D0D001F5F5F501C7E8E80147CBCD011EC4C7013AC8CA01B8E1E101EBEBEB01 + EAEAEA01E8E8E801E6E6E601E5E5E501E3E3E301E2E2E201CEDCDC0164CBCC01 + 1DBFC1015AC8C901C5D7D701D8D8D801D7D7D701D5D5D501D3D3D301D2D2D201 + D0D0D001F1F4F40123C3C50162E8F4017AF1FF0145E9F60117C3C501DBE7E701 + EAEAEA01E8E8E801E6E6E601E5E5E501E3E3E301E1E2E20121C0C1014ADDE801 + 6EF1FF0133DFEB0117BEC001D3D7D701D7D7D701D5D5D501D3D3D301D2D2D201 + D0D0D001A9E2E2013ED4DB01B4F3FF01C1F3FF017BF1FF011FD9E30185D5D601 + EAEAEA01E8E8E801E6E6E601E5E5E501E3E3E301A8D6D60138D0D601ACF2FF01 + B6F3FF0175F1FF011CD3DB0192CECE01D7D7D701D5D5D501D3D3D301D2D2D201 + D0D0D00160D2D30152E2ED01C0F3FF01D0F4FF0181F1FF0126E6F40141C9CB01 + DADAE8018383E101E6E6E601E5E5E501E3E3E30158CBCC0154E2ED01C5F3FF01 + D0F5FF0183F1FF0125E5F20141C4C601D0D0D7019595D601D3D3D301D2D2D201 + D0D0D001BFE7E7012ECFD50186F1FF018EF1FF015DF0FF0115D4DD019CDADA01 + 6A6AE3010E0EDC01DDDDE501E5E5E501E3E3E301A0D6D60131D1D80191F2FF01 + 99F2FF0164F0FF0115D5DE0188CDCD017373D9011515DB01D1D1D301D2D2D201 + D0D0D001F5F5F50129C4C6012DDAE40141EDFD011BDCE7011BC1C201DBE0E901 + 1919DF010808F0017777E101E5E5E501E3E3E301DFE1E1011CC1C2013BE3F001 + 4FF0FF0124E4F20116C1C201CDD3D6011C1CDD010C0CEB018787D601D2D2D201 + D0D0D001F5F5F501E9F1F10183D8D90125C4C50173D4D501DFEAEA017A7AE401 + 0808EF010404FF011D1DDF01E1E1E501E3E3E301E2E2E201BFD9D9014AC7C801 + 18C1C30142C4C601B5D4D4018383D9010B0BED010404FD012020DC01D2D2D201 + D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01E8E8EC011A1ADF01 + 0404FE010404FF010A0AEE018686E101E3E3E301E2E2E201E0E0E001DFDFDF01 + DBDCDC01DBDBDB01D9D9DA011F1FDD010404FE010404FF010E0EE9019191D401 + D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE018A8AE6010A0AED01 + 0404FF020404FE012020DF01E1E1E301E2E2E201E0E0E001DFDFDF01DDDDDD01 + DBDBDB019393DA010E0EEA010404FF020404FC012323DB01D0D0D001F5F5F501 + C2211F01C91D1F01C81C1E01C71C1F012605B6011905C8012020E1031515DD01 + A4A4E001E2E2E201C4333101C52525032106BC011206D3011717E2030A0ADA01 + 9D9DD201F5F5F501CB262801FF002004CA272901EAEAEA01E8E8E801E6E6E601 + E5E5E501E3E3E301E2E2E201C9242601FF002003EF002C01BB223101CACAD701 + C8C8D501C6C6D301C5C5D201CACAD001F5F5F501CB262801FF002004CA272901 + EAEAEA01E8E8E801E6E6E601E5E5E501E3E3E301E2E2E201C9242601FF002004 + C7242601D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501CB262801 + FF002004CA272901EAEAEA01E8E8E801E6E6E601E5E5E501E3E3E301E2E2E201 + C9242601FF002004C7242601D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001 + F5F5F501CB262801FF002004CA272901EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201C9242601FF002004C7242601D7D7D701D5D5D501D3D3D301 + D2D2D201D0D0D001F5F5F501C8373601CB282A02CA272902C8393801EAEAEA01 + E8E8E801E6E6E601E5E5E501E3E3E301E2E2E201BF1E1C01CA1B1F01C91A1E03 + C0222001D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301 + F2F2F201F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601 + E5E5E501E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01 + D8D8D801D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301 + F2F2F201F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601 + E5E5E501E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01 + D8D8D801D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301 + F2F2F201F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601 + E5E5E501E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01 + D8D8D801D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001FFFFFF08FFFFFF08 + FFFFFFBFFFFFFF08FFFFFF00FFFFFF08FFFFFF03FFFFFFC0FFFFFF00FFFFFF0A + FFFFFF00FFFFFF08FFFFFF08FFFFFF08FFFFFFBFFFFFFF08FFFFFF00FFFFFF03 + FFFFFF08FFFFFF00FFFFFF00FFFFFFBFFFFFFF00FFFFFF08 + } + onstatread = foonreadstat + onlayout = componentgrouponchildscaled + moduleclassname = 'tdockform' + object componentpalette: ttoolbar + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_destroywidgets, ow_hinton] + optionsskin = [osk_container] + frame.localprops = [] + frame.localprops1 = [] + taborder = 1 + bounds_x = 0 + bounds_y = 26 + bounds_cx = 728 + bounds_cy = 30 + anchors = [an_top, an_bottom] + buttons.width = 26 + buttons.height = 26 + options = [tbo_dragsource, tbo_dragdest] + onbuttonchanged = componentpalettebuttonchanged + drag.onafterdragdrop = componentpalettedragdrop + left = 128 + top = 8 + end + object componentpages: ttabbar + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autoheight] + optionswidget = [ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.localprops = [] + frame.localprops1 = [] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 728 + bounds_cy = 18 + bounds_cymin = 15 + anchors = [an_top] + statfile = mainfo.projectstatfile + onactivetabchange = componentpagesactivetabchange + options = [tabo_dragsource, tabo_dragdest] + left = 128 + top = 72 + reffontheight = 14 + end +end diff --git a/mseide-msegui/apps/ide/componentpaletteform.pas b/mseide-msegui/apps/ide/componentpaletteform.pas new file mode 100644 index 0000000..544aaa9 --- /dev/null +++ b/mseide-msegui/apps/ide/componentpaletteform.pas @@ -0,0 +1,155 @@ +{ MSEide Copyright (c) 1999-2013 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit componentpaletteform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msegui,mseclasses,mseforms,msetabs,msetoolbar,msegraphutils,msestat,mseguiglob, + msedragglob,msetypes{msestrings}; + +type + tcomponentpalettefo = class(tdockform) + componentpages: ttabbar; + componentpalette: ttoolbar; + procedure componentgrouponchildscaled(const sender: TObject); + procedure componentpalettedragdrop(const sender: TObject; + const apos: pointty; var dragobject: tdragobject; var processed: boolean); + procedure componentpagesactivetabchange(const sender: TObject); + procedure componentpalettebuttonchanged(const sender: tobject; + const button: tcustomtoolbutton); + procedure foonreadstat(const sender: TObject; const reader: tstatreader); + public + procedure updatecomponentpalette(init: boolean); + procedure resetselected; + end; + +var + componentpalettefo: tcomponentpalettefo; + +implementation +uses + componentpaletteform_mfm,main,projectoptionsform,msedesignintf,mseshapes, + mseactions,classes,mclasses,mseact,componentstore; + +procedure tcomponentpalettefo.componentpalettedragdrop(const sender: TObject; + const apos: pointty; var dragobject: tdragobject; var processed: boolean); +begin + registeredcomponents.pagecomporders[componentpages.activetag - 1]:= + ttoolbar(sender).buttons.idents; + projectoptionsmodified; +end; + +procedure tcomponentpalettefo.componentpagesactivetabchange(const sender: TObject); +begin + updatecomponentpalette(false); + componentpalette.firstbutton:= 0; +end; + +procedure tcomponentpalettefo.componentpalettebuttonchanged(const sender: TObject; + const button: tcustomtoolbutton); +begin + if not application.terminated then begin + with registeredcomponents do begin + if tclass(button.tagpo) = selectedclass then begin + selectedclass:= nil; + end; + if as_checked in button.state then begin + componentstorefo.resetselected; + selectedclass:= mclasses.tcomponentclass(button.tagpo); + end; + end; + end; +end; + +procedure tcomponentpalettefo.componentgrouponchildscaled(const sender: TObject); +begin + placeyorder(0,[0],[componentpages,componentpalette],0); +end; + +procedure tcomponentpalettefo.updatecomponentpalette(init: boolean); +var + int1,int2: integer; + ar1: comppagearty; +begin + resetselected; + if init then begin + with componentpages do begin + beginupdate; + try + tabs.count:= 0; + ar1:= registeredcomponents.pagenames; + tabs.count:= length(ar1); +// tabs.additems(registeredcomponents.pagenames); + if tabs.count > 0 then begin + activetab:= 0; + end; + for int1:= 0 to tabs.count - 1 do begin + with tabs[int1] do begin + tag:= int1 + 1; + caption:= ar1[int1].caption; + hint:= ar1[int1].hint; + end; + end; + finally + componentpages.endupdate; + end; + end; + end; + + componentpalette.beginupdate; + registeredcomponents.defaultorder:= true; + try + int2:= componentpages.activetag - 1; + componentpalette.buttons.count:= 0; + if int2 >= 0 then begin + for int1:= 0 to registeredcomponents.count - 1 do begin + with registeredcomponents.itempo(int1)^ do begin + if page = int2 then begin + with componentpalette.buttons.add do begin + options:= [mao_checkbox,mao_radiobutton]; + imagelist:= registeredcomponents.imagelist; + imagenr:= icon; + hint:= msestring(classtyp.classname); + tagpo:= classtyp; + end; + end; + end; + end; + if int2 <= registeredcomponents.pagehigh then begin + componentpalette.buttons.order(registeredcomponents.pagecomporders[int2]); + end; + end; + finally + registeredcomponents.defaultorder:= false; + componentpalette.endupdate; + end; +end; + +procedure tcomponentpalettefo.foonreadstat(const sender: TObject; + const reader: tstatreader); +begin + updatecomponentpalette(true); +end; + +procedure tcomponentpalettefo.resetselected; +begin + componentpalette.buttons.resetradioitems(0); +end; + +end. diff --git a/mseide-msegui/apps/ide/componentpaletteform_mfm.pas b/mseide-msegui/apps/ide/componentpaletteform_mfm.pas new file mode 100644 index 0000000..81508cc --- /dev/null +++ b/mseide-msegui/apps/ide/componentpaletteform_mfm.pas @@ -0,0 +1,214 @@ +unit componentpaletteform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,componentpaletteform; + +const + objdata: record size: integer; data: array[0..3938] of byte end = + (size: 3939; data: ( + 84,80,70,48,19,116,99,111,109,112,111,110,101,110,116,112,97,108,101,116, + 116,101,102,111,18,99,111,109,112,111,110,101,110,116,112,97,108,101,116,116, + 101,102,111,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,11,111,119,95,115,117,98,102, + 111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,9,111,119,95,104,105,110,116,111,110,0,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,15,102,114,97,109,101,46,103, + 114,105,112,95,115,105,122,101,2,10,18,102,114,97,109,101,46,103,114,105, + 112,95,111,112,116,105,111,110,115,11,14,103,111,95,99,108,111,115,101,98, + 117,116,116,111,110,16,103,111,95,102,105,120,115,105,122,101,98,117,116,116, + 111,110,14,103,111,95,102,108,111,97,116,98,117,116,116,111,110,12,103,111, + 95,116,111,112,98,117,116,116,111,110,19,103,111,95,98,97,99,107,103,114, + 111,117,110,100,98,117,116,116,111,110,15,103,111,95,110,111,108,111,99,107, + 98,117,116,116,111,110,14,103,111,95,98,117,116,116,111,110,104,105,110,116, + 115,0,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120, + 3,131,0,8,98,111,117,110,100,115,95,121,3,33,1,9,98,111,117,110, + 100,115,95,99,120,3,226,2,9,98,111,117,110,100,115,95,99,121,2,69, + 23,99,111,110,116,97,105,110,101,114,46,111,112,116,105,111,110,115,119,105, + 100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11, + 111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119, + 102,111,99,117,115,11,111,119,95,115,117,98,102,111,99,117,115,19,111,119, + 95,109,111,117,115,101,116,114,97,110,115,112,97,114,101,110,116,17,111,119, + 95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,26,99,111,110, + 116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,0,27,99,111,110,116,97,105,110,101,114,46,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,18,99,111,110,116, + 97,105,110,101,114,46,111,110,108,97,121,111,117,116,7,27,99,111,109,112, + 111,110,101,110,116,103,114,111,117,112,111,110,99,104,105,108,100,115,99,97, + 108,101,100,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115, + 1,2,0,2,0,3,216,2,2,69,0,16,100,114,97,103,100,111,99,107, + 46,99,97,112,116,105,111,110,6,17,67,111,109,112,111,110,101,110,116,32, + 80,97,108,101,116,116,101,20,100,114,97,103,100,111,99,107,46,111,112,116, + 105,111,110,115,100,111,99,107,11,10,111,100,95,115,97,118,101,112,111,115, + 13,111,100,95,115,97,118,101,122,111,114,100,101,114,10,111,100,95,99,97, + 110,109,111,118,101,11,111,100,95,99,97,110,102,108,111,97,116,10,111,100, + 95,99,97,110,100,111,99,107,15,111,100,95,112,114,111,112,111,114,116,105, + 111,110,97,108,11,111,100,95,112,114,111,112,115,105,122,101,14,111,100,95, + 99,97,112,116,105,111,110,104,105,110,116,13,111,100,95,99,104,105,108,100, + 105,99,111,110,115,0,7,111,112,116,105,111,110,115,11,10,102,111,95,115, + 97,118,101,112,111,115,13,102,111,95,115,97,118,101,122,111,114,100,101,114, + 12,102,111,95,115,97,118,101,115,116,97,116,101,0,8,115,116,97,116,102, + 105,108,101,7,22,109,97,105,110,102,111,46,112,114,111,106,101,99,116,115, + 116,97,116,102,105,108,101,21,105,99,111,110,46,116,114,97,110,115,112,97, + 114,101,110,116,99,111,108,111,114,4,6,0,0,128,12,105,99,111,110,46, + 111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,0, + 10,105,99,111,110,46,105,109,97,103,101,10,248,7,0,0,0,0,0,0, + 2,0,0,0,24,0,0,0,24,0,0,0,100,7,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,208,208,208,10,255,255,255,10,208,208,208,4, + 255,255,255,11,208,208,208,1,183,183,183,1,198,198,198,1,202,202,202,1, + 200,200,200,1,208,208,208,3,133,133,133,1,208,208,208,4,255,255,255,1, + 186,186,186,1,175,175,175,1,193,193,193,1,208,208,208,5,133,133,133,1, + 255,255,255,1,172,172,172,1,135,135,135,1,141,141,141,1,148,148,148,1, + 129,129,129,1,208,208,208,3,133,133,133,1,208,208,208,4,255,255,255,1, + 157,157,157,1,141,141,141,1,138,138,138,1,148,148,148,1,137,137,137,1, + 208,208,208,3,133,133,133,1,255,255,255,1,197,197,197,1,196,196,196,1, + 189,189,189,1,185,185,185,1,181,181,181,1,208,208,208,3,133,133,133,1, + 208,208,208,4,255,255,255,1,192,192,192,1,179,179,179,1,189,189,189,1, + 188,188,188,1,179,179,179,1,208,208,208,3,133,133,133,15,245,245,245,1, + 243,243,243,1,242,242,242,1,232,238,238,1,238,238,238,1,237,237,237,1, + 235,235,235,1,234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1, + 227,227,227,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1, + 219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1, + 211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,199,232,232,1, + 71,203,205,1,30,196,199,1,58,200,202,1,184,225,225,1,235,235,235,1, + 234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1,227,227,227,1, + 226,226,226,1,206,220,220,1,100,203,204,1,29,191,193,1,90,200,201,1, + 197,215,215,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1, + 210,210,210,1,208,208,208,1,241,244,244,1,35,195,197,1,98,232,244,1, + 122,241,255,1,69,233,246,1,23,195,197,1,219,231,231,1,234,234,234,1, + 232,232,232,1,230,230,230,1,229,229,229,1,227,227,227,1,225,226,226,1, + 33,192,193,1,74,221,232,1,110,241,255,1,51,223,235,1,23,190,192,1, + 211,215,215,1,215,215,215,1,213,213,213,1,211,211,211,1,210,210,210,1, + 208,208,208,1,169,226,226,1,62,212,219,1,180,243,255,1,193,243,255,1, + 123,241,255,1,31,217,227,1,133,213,214,1,234,234,234,1,232,232,232,1, + 230,230,230,1,229,229,229,1,227,227,227,1,168,214,214,1,56,208,214,1, + 172,242,255,1,182,243,255,1,117,241,255,1,28,211,219,1,146,206,206,1, + 215,215,215,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1, + 96,210,211,1,82,226,237,1,192,243,255,1,208,244,255,1,129,241,255,1, + 38,230,244,1,65,201,203,1,218,218,232,1,131,131,225,1,230,230,230,1, + 229,229,229,1,227,227,227,1,88,203,204,1,84,226,237,1,197,243,255,1, + 208,245,255,1,131,241,255,1,37,229,242,1,65,196,198,1,208,208,215,1, + 149,149,214,1,211,211,211,1,210,210,210,1,208,208,208,1,191,231,231,1, + 46,207,213,1,134,241,255,1,142,241,255,1,93,240,255,1,21,212,221,1, + 156,218,218,1,106,106,227,1,14,14,220,1,221,221,229,1,229,229,229,1, + 227,227,227,1,160,214,214,1,49,209,216,1,145,242,255,1,153,242,255,1, + 100,240,255,1,21,213,222,1,136,205,205,1,115,115,217,1,21,21,219,1, + 209,209,211,1,210,210,210,1,208,208,208,1,245,245,245,1,41,196,198,1, + 45,218,228,1,65,237,253,1,27,220,231,1,27,193,194,1,219,224,233,1, + 25,25,223,1,8,8,240,1,119,119,225,1,229,229,229,1,227,227,227,1, + 223,225,225,1,28,193,194,1,59,227,240,1,79,240,255,1,36,228,242,1, + 22,193,194,1,205,211,214,1,28,28,221,1,12,12,235,1,135,135,214,1, + 210,210,210,1,208,208,208,1,245,245,245,1,233,241,241,1,131,216,217,1, + 37,196,197,1,115,212,213,1,223,234,234,1,122,122,228,1,8,8,239,1, + 4,4,255,1,29,29,223,1,225,225,229,1,227,227,227,1,226,226,226,1, + 191,217,217,1,74,199,200,1,24,193,195,1,66,196,198,1,181,212,212,1, + 131,131,217,1,11,11,237,1,4,4,253,1,32,32,220,1,210,210,210,1, + 208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1, + 238,238,238,1,232,232,236,1,26,26,223,1,4,4,254,1,4,4,255,1, + 10,10,238,1,134,134,225,1,227,227,227,1,226,226,226,1,224,224,224,1, + 223,223,223,1,219,220,220,1,219,219,219,1,217,217,218,1,31,31,221,1, + 4,4,254,1,4,4,255,1,14,14,233,1,145,145,212,1,208,208,208,1, + 245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1, + 138,138,230,1,10,10,237,1,4,4,255,2,4,4,254,1,32,32,223,1, + 225,225,227,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1, + 219,219,219,1,147,147,218,1,14,14,234,1,4,4,255,2,4,4,252,1, + 35,35,219,1,208,208,208,1,245,245,245,1,194,33,31,1,201,29,31,1, + 200,28,30,1,199,28,31,1,38,5,182,1,25,5,200,1,32,32,225,3, + 21,21,221,1,164,164,224,1,226,226,226,1,196,51,49,1,197,37,37,3, + 33,6,188,1,18,6,211,1,23,23,226,3,10,10,218,1,157,157,210,1, + 245,245,245,1,203,38,40,1,255,0,32,4,202,39,41,1,234,234,234,1, + 232,232,232,1,230,230,230,1,229,229,229,1,227,227,227,1,226,226,226,1, + 201,36,38,1,255,0,32,3,239,0,44,1,187,34,49,1,202,202,215,1, + 200,200,213,1,198,198,211,1,197,197,210,1,202,202,208,1,245,245,245,1, + 203,38,40,1,255,0,32,4,202,39,41,1,234,234,234,1,232,232,232,1, + 230,230,230,1,229,229,229,1,227,227,227,1,226,226,226,1,201,36,38,1, + 255,0,32,4,199,36,38,1,215,215,215,1,213,213,213,1,211,211,211,1, + 210,210,210,1,208,208,208,1,245,245,245,1,203,38,40,1,255,0,32,4, + 202,39,41,1,234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1, + 227,227,227,1,226,226,226,1,201,36,38,1,255,0,32,4,199,36,38,1, + 215,215,215,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1, + 245,245,245,1,203,38,40,1,255,0,32,4,202,39,41,1,234,234,234,1, + 232,232,232,1,230,230,230,1,229,229,229,1,227,227,227,1,226,226,226,1, + 201,36,38,1,255,0,32,4,199,36,38,1,215,215,215,1,213,213,213,1, + 211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,200,55,54,1, + 203,40,42,2,202,39,41,2,200,57,56,1,234,234,234,1,232,232,232,1, + 230,230,230,1,229,229,229,1,227,227,227,1,226,226,226,1,191,30,28,1, + 202,27,31,1,201,26,30,3,192,34,32,1,215,215,215,1,213,213,213,1, + 211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1, + 242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1,235,235,235,1, + 234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1,227,227,227,1, + 226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219,219,1, + 218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1, + 210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1, + 240,240,240,1,238,238,238,1,237,237,237,1,235,235,235,1,234,234,234,1, + 232,232,232,1,230,230,230,1,229,229,229,1,227,227,227,1,226,226,226,1, + 224,224,224,1,223,223,223,1,221,221,221,1,219,219,219,1,218,218,218,1, + 216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1,210,210,210,1, + 208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1, + 238,238,238,1,237,237,237,1,235,235,235,1,234,234,234,1,232,232,232,1, + 230,230,230,1,229,229,229,1,227,227,227,1,226,226,226,1,224,224,224,1, + 223,223,223,1,221,221,221,1,219,219,219,1,218,218,218,1,216,216,216,1, + 215,215,215,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1, + 255,255,255,8,255,255,255,8,255,255,255,191,255,255,255,8,255,255,255,0, + 255,255,255,8,255,255,255,3,255,255,255,192,255,255,255,0,255,255,255,10, + 255,255,255,0,255,255,255,8,255,255,255,8,255,255,255,8,255,255,255,191, + 255,255,255,8,255,255,255,0,255,255,255,3,255,255,255,8,255,255,255,0, + 255,255,255,0,255,255,255,191,255,255,255,0,255,255,255,8,10,111,110,115, + 116,97,116,114,101,97,100,7,12,102,111,111,110,114,101,97,100,115,116,97, + 116,8,111,110,108,97,121,111,117,116,7,27,99,111,109,112,111,110,101,110, + 116,103,114,111,117,112,111,110,99,104,105,108,100,115,99,97,108,101,100,15, + 109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,9,116,100,111, + 99,107,102,111,114,109,0,8,116,116,111,111,108,98,97,114,16,99,111,109, + 112,111,110,101,110,116,112,97,108,101,116,116,101,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,9,111,119,95,104,105,110,116,111,110,0,11,111,112, + 116,105,111,110,115,115,107,105,110,11,13,111,115,107,95,99,111,110,116,97, + 105,110,101,114,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110, + 100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,26,9,98,111, + 117,110,100,115,95,99,120,3,216,2,9,98,111,117,110,100,115,95,99,121, + 2,30,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,9,97, + 110,95,98,111,116,116,111,109,0,13,98,117,116,116,111,110,115,46,119,105, + 100,116,104,2,26,14,98,117,116,116,111,110,115,46,104,101,105,103,104,116, + 2,26,7,111,112,116,105,111,110,115,11,14,116,98,111,95,100,114,97,103, + 115,111,117,114,99,101,12,116,98,111,95,100,114,97,103,100,101,115,116,0, + 15,111,110,98,117,116,116,111,110,99,104,97,110,103,101,100,7,29,99,111, + 109,112,111,110,101,110,116,112,97,108,101,116,116,101,98,117,116,116,111,110, + 99,104,97,110,103,101,100,20,100,114,97,103,46,111,110,97,102,116,101,114, + 100,114,97,103,100,114,111,112,7,24,99,111,109,112,111,110,101,110,116,112, + 97,108,101,116,116,101,100,114,97,103,100,114,111,112,4,108,101,102,116,3, + 128,0,3,116,111,112,2,8,0,0,7,116,116,97,98,98,97,114,14,99, + 111,109,112,111,110,101,110,116,112,97,103,101,115,14,111,112,116,105,111,110, + 115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108, + 121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99, + 97,108,101,14,111,119,49,95,97,117,116,111,104,101,105,103,104,116,0,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,15,111,119,95,97,114, + 114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102, + 111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,216,2, + 9,98,111,117,110,100,115,95,99,121,2,18,12,98,111,117,110,100,115,95, + 99,121,109,105,110,2,15,7,97,110,99,104,111,114,115,11,6,97,110,95, + 116,111,112,0,8,115,116,97,116,102,105,108,101,7,22,109,97,105,110,102, + 111,46,112,114,111,106,101,99,116,115,116,97,116,102,105,108,101,17,111,110, + 97,99,116,105,118,101,116,97,98,99,104,97,110,103,101,7,29,99,111,109, + 112,111,110,101,110,116,112,97,103,101,115,97,99,116,105,118,101,116,97,98, + 99,104,97,110,103,101,7,111,112,116,105,111,110,115,11,15,116,97,98,111, + 95,100,114,97,103,115,111,117,114,99,101,13,116,97,98,111,95,100,114,97, + 103,100,101,115,116,0,4,108,101,102,116,3,128,0,3,116,111,112,2,72, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tcomponentpalettefo,''); +end. diff --git a/mseide-msegui/apps/ide/componentstore.mfm b/mseide-msegui/apps/ide/componentstore.mfm new file mode 100644 index 0000000..7bd41b0 --- /dev/null +++ b/mseide-msegui/apps/ide/componentstore.mfm @@ -0,0 +1,469 @@ +object componentstorefo: tcomponentstorefo + optionswidget = [ow_arrowfocus, ow_subfocus, ow_mousewheel, ow_destroywidgets, ow_hinton] + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_floatbutton, go_topbutton, go_backgroundbutton, go_nolockbutton, go_buttonhints] + visible = False + bounds_x = 305 + bounds_y = 101 + bounds_cx = 445 + bounds_cy = 354 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 435 + 354 + ) + dragdock.caption = 'Component Store' + dragdock.optionsdock = [od_savepos, od_savezorder, od_canmove, od_cansize, od_canfloat, od_candock, od_proportional, od_propsize, od_captionhint, od_childicons] + options = [fo_savepos, fo_savezorder, fo_savestate] + statfile = mainfo.projectstatfile + icon.transparentcolor = -2147483642 + icon.image = { + 00000000000000001800000018000000A0070000000000000000000000000000 + 0000000000000000000000000000000000000000F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001E9E9E901B2B2B2019A9A9A029B9B9B029C9C9C019B9B9B019D9D9D01 + 9C9C9C019D9D9D019C9C9C029E9E9E019D9D9D019E9E9E01A4A4A401D3D3D301 + D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201E2E2E201A5A5A501BCBCBC01 + DEDEDE01DFDFDF01DEDEDE04DDDDDD02DCDCDC04CBCBCB019C9C9C019B9B9B01 + D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F2018D8D8D018686860E + 8D8D8D01BBBBBB019B9B9B01D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301 + F2F2F20186868601AAAAFF01AEAEFF01B2B2FF01B6B6FF01BBBBFF01BFBFFF01 + C3C3FF01C8C8FF01CCCCFF01D0D0FF01D4D4FF01D6D6FF0387878701D6D6D601 + 9A9A9A01D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F20186868601 + AAAAFF01AEAEFF01B2B2FF01B6B6FF01BBBBFF01BFBFFF01C3C3FF0100000001 + CCCCFF01D0D0FF01D4D4FF01D6D6FF0387878701D7D7D7019A9A9A01D3D3D301 + D2D2D201D0D0D001F5F5F501F3F3F301F2F2F20186868601AAAAFF01AEAEFF01 + B2B2FF01B6B6FF01BBBBFF01BFBFFF01C3C3FF01C8C8FF01CCCCFF01D0D0FF01 + D4D4FF01D6D6FF0387878701D7D7D7019B9B9B01D3D3D301D2D2D201D0D0D001 + F5F5F501F3F3F301F2F2F20186868601AAAAFF01AEAEFF01B2B2FF01B6B6FF01 + BBBBFF01BFBFFF01C3C3FF01C8C8FF01CCCCFF01D0D0FF01D4D4FF01D6D6FF03 + 87878701D7D7D7019C9C9C01D2D2D202D0D0D001F5F5F501F3F3F301F2F2F201 + 868686018A8A8A038B8B8B058C8C8C0687878701D7D7D7019C9C9C01D1D1D101 + D2D2D201D0D0D001F5F5F501F3F3F301F2F2F20186868601AAFFF601AEFFF701 + B2FFF701B6FFF801BBFFF901BFFFF901C3FFFA01C8FFFB01CCFFFC01D0FFFC01 + D4FFFD01D6FFFD02D8FCFB0187878701D7D7D7019C9C9C01D1D1D101D2D2D201 + D0D0D001F5F5F501F3F3F301F2F2F20186868601AAFFF601AEFFF701B2FFF701 + B6FFF801BBFFF901BFFFF901C3FFFA0100000001CCFFFC01D0FFFC01D4FFFD01 + D6FFFD02D9FDFB0187878701D7D7D7019D9D9D01D0D0D001D2D2D201D0D0D001 + F5F5F501F3F3F301F2F2F20186868601AAFFF601AEFFF701B2FFF701B6FFF801 + BBFFF901BFFFF901C3FFFA01C8FFFB01CCFFFC01D0FFFC01D4FFFD01D6FFFD02 + D9FDFB0187878701D7D7D7019E9E9E01D0D0D001D2D2D201D0D0D001F5F5F501 + F3F3F301F2F2F20186868601AAFFF601AEFFF701B2FFF701B6FFF801BBFFF901 + BFFFF901C3FFFA01C8FFFB01CCFFFC01D0FFFC01D4FFFD01D6FFFD02D9FDFB01 + 87878701D6D6D6019E9E9E01CFCFCF01D2D2D201D0D0D001F5F5F501F3F3F301 + F2F2F201868686018A8A8A038B8B8B058C8C8C0687878701D6D6D6019F9F9F01 + CECECE01D2D2D201D0D0D001F5F5F501F3F3F301F2F2F2019D8C8F01FFAAB901 + FFAFBB01FFB3BE01FFB7C101FFBBC401FFBFC701FFC4CA01FFC8CD01FFCCD001 + FFD0D301FFD5D601FFD6D70387878701D6D6D6019F9F9F01CECECE01D2D2D201 + D0D0D001F5F5F501F3F3F301F2F2F2019D8C8F01FFAAB901FFAFBB01FFB3BE01 + FFB7C101FFBBC401FFBFC701FFC4CA0100000001FFCCD001FFD0D301FFD5D601 + FFD6D70387878701C4C4C401A3A3A301D2D2D202D0D0D001F5F5F501F3F3F301 + F2F2F2019D8C8F01FFAAB901FFAFBB01FFB3BE01FFB7C101FFBBC401FFBFC701 + FFC4CA01FFC8CD01FFCCD001FFD0D301FFD5D601FFD6D70387878701A2A2A201 + C4C4C401D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F2019D8C8F01 + FFAAB901FFAFBB01FFB3BE01FFB7C101FFBBC401FFBFC701FFC4CA01FFC8CD01 + FFCCD001FFD0D301FFD5D601FFD6D70387878701ACACAC01D5D5D501D3D3D301 + D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201919191018888880B89898901 + 888888028E8E8E01CACACA01D3D3D302D2D2D201D0D0D001F5F5F501F3F3F301 + F2F2F201E9E9E901C6C6C601818181017272720271717101707070026F6F6F02 + 6E6E6E016D6D6D016C6C6C016B6B6B037C7C7C01BFBFBF01D1D1D101D2D2D201 + D0D0D001F5F5F501F3F3F301F0F0F001D8D8D8018C8C8C017575750172727202 + 71717101707070016F6F6F016E6E6E026D6D6D016C6C6C016B6B6B016A6A6A02 + 71717101A9A9A901CFCFCF01D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301 + F2F2F201EEEEEE01E7E7E701E6E6E601E3E3E301E2E2E201E0E0E001DEDEDE01 + DDDDDD01DBDBDB01DADADA01D8D8D801D7D7D701D5D5D501D3D3D301D2D2D201 + D1D1D101D4D4D402D3D3D301D2D2D201D0D0D001 + } + oncreate = createexe + moduleclassname = 'tdockform' + object grid: twidgetgrid + frame.localprops = [] + frame.localprops1 = [] + popupmenu = tpopupmenu1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 435 + bounds_cy = 354 + anchors = [] + optionsgrid = [og_colsizing, og_focuscellonenter, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 4 + captions.items = < + item + caption = 'Name' + end + item + caption = 'Sel' + hint = 'Select item for inserting' + end + item + caption = 'Description' + end + item + caption = 'File' + end> + end> + datacols.count = 4 + datacols.options = [co_proportional, co_savestate, co_mousescrollrow] + datacols.items = < + item[node] + width = 110 + options = [co_drawfocus, co_proportional, co_savestate, co_mousescrollrow] + widgetname = 'node' + dataclass = ttreeitemeditlist + datalist.imnr_expanded = 1 + datalist.imagelist = filedialogres.images + datalist.imagewidth = 16 + datalist.imageheight = 16 + datalist.onstatreaditem = dostatreaditem + datalist.ondragover = drago + datalist.ondragdrop = dragdro + end + item[sel] + color = -2147483646 + width = 28 + options = [co_fixwidth, co_proportional, co_savestate, co_mousescrollrow] + widthmin = 0 + widgetname = 'sel' + dataclass = tgridintegerdatalist + end + item[compdesc] + width = 103 + options = [co_fill, co_savestate, co_mousescrollrow] + widgetname = 'compdesc' + dataclass = tgridmsestringdatalist + end + item[filepath] + width = 186 + options = [co_proportional, co_savestate, co_mousescrollrow] + widgetname = 'filepath' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + statfile = mainfo.projectstatfile + oncellevent = docellevent + drag.onbeforedragbegin = beforedrag + reffontheight = 14 + object node: ttreeitemedit + optionswidget1 = [ow1_fontglyphheight] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + taborder = 1 + onenter = nodeenter + onexit = nodeexit + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 110 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_hintclippedtext, oe_locate] + ondataentered = datent + onsetvalue = compnamesetva + onupdaterowvalues = doupdaterowvalues + options = [teo_treecolnavig, teo_keyrowmoving] + reffontheight = 14 + end + object sel: tdatabutton + taborder = 2 + bounds_x = 111 + bounds_y = 0 + bounds_cx = 28 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + options = [bo_executeonclick, bo_executeonkey, bo_executeonshortcut, bo_executedefaultonenterkey, bo_radioitemcol, bo_cantoggle, bo_resetcheckedonrowexit] + state = [as_invisible, as_localinvisible] + valuefaces.count = 1 + valuefaces.items = < + item + fade_pos.count = 2 + fade_pos.items = ( + 0 + 1 + ) + fade_color.count = 2 + fade_color.items = ( + -1610612729 + 16768903 + ) + fade_direction = gd_down + localprops = [fal_fadirection] + end> + onsetvalue = setval + end + object compdesc: tmemodialogedit + optionswidget1 = [ow1_fontglyphheight] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + taborder = 3 + visible = False + bounds_x = 140 + bounds_y = 0 + bounds_cx = 103 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext] + ondataentered = datent + onsetvalue = compdescsetva + reffontheight = 14 + end + object filepath: tfilenameedit + optionswidget1 = [ow1_fontglyphheight] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 4 + visible = False + bounds_x = 244 + bounds_y = 0 + bounds_cx = 186 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext] + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + ondataentered = datent + onsetvalue = filenamesetva + controller.filterlist.data = ( + ( + 'Component File' + '*.cmp' + ) + ( + 'All Files' + '*' + ) + ) + controller.defaultext = 'cmp' + reffontheight = 14 + end + end + object copycompact: taction + caption = '&Copy Component' + options = [ao_localshortcut] + onexecute = docopycomponent + onupdate = copyupda + left = 176 + top = 64 + end + object pastecompact: taction + caption = '&Paste Component(s)' + options = [ao_localshortcut] + onexecute = dopastecomponent + onupdate = pasteupda + left = 176 + top = 88 + end + object tpopupmenu1: tpopupmenu + onupdate = popupupdate + menu.submenu.count = 18 + menu.submenu.items = < + item + action = copycompact + caption = '&Copy Component(s)' + state = [as_localcaption] + end + item + action = pastecompact + end + item + action = addfileact + end + item + caption = 'Update Component(s)' + name = 'updatenode' + state = [as_localcaption, as_localonexecute] + onexecute = doupdatecomponent + end + item + caption = 'Remove Component(s)' + name = 'removecomp' + state = [as_localcaption, as_localonexecute] + onexecute = removecomp + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = 'New Node' + name = 'addnode' + state = [as_localcaption, as_localonexecute] + onexecute = donewnode + end + item + caption = 'Remove Node' + name = 'removenode' + state = [as_localcaption, as_localonexecute] + onexecute = delnode + end + item + caption = 'Copy Node' + name = 'copynode' + state = [as_localcaption, as_localonexecute] + onexecute = copynodeex + end + item + caption = 'Paste Node' + name = 'pastenode' + state = [as_localcaption, as_localonexecute] + onexecute = pastenodeex + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = 'New Store' + state = [as_localcaption, as_localonexecute] + onexecute = newstoreex + end + item + caption = 'Add Store' + state = [as_localcaption, as_localonexecute] + onexecute = addstoreex + end + item + caption = 'Remove Store' + name = 'removestore' + state = [as_localcaption, as_localonexecute] + onexecute = removestoreex + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = 'Open Store Group' + state = [as_localcaption, as_localonexecute] + onexecute = opengroup + end + item + caption = 'Save Store Group' + state = [as_localcaption, as_localonexecute] + onexecute = savegroup + end + item + caption = 'Save Store Group as' + state = [as_localcaption, as_localonexecute] + onexecute = savegroupas + end> + left = 40 + top = 88 + end + object storefile: tstatfile + filename = 'store.sta' + onstatread = statreadexe + onstatwrite = statwriteexe + left = 296 + top = 88 + end + object storefiledialog: tfiledialog + statfile = mainfo.projectstatfile + controller.filterlist.data = ( + ( + 'Component Stores' + '*.sto' + ) + ) + controller.defaultext = 'sto' + controller.options = [fdo_checkexist, fdo_savelastdir] + controller.captionopen = 'Load Component Store' + controller.captionsave = 'New Component Store' + left = 40 + top = 136 + end + object groupfiledialog: tfiledialog + statfile = mainfo.projectstatfile + controller.filterlist.data = ( + ( + 'Store Groups' + '*.stg' + ) + ) + controller.defaultext = 'stg' + controller.captionopen = 'Open Store Group' + controller.captionsave = 'Save Store Group' + left = 40 + top = 168 + end + object addfileact: taction + caption = 'Add Componentfile' + onexecute = doaddfile + onupdate = pasteupda + left = 176 + top = 112 + end + object compfiledialog: tfiledialog + statfile = mainfo.projectstatfile + controller.filterlist.data = ( + ( + 'Component File' + '*.cmp' + ) + ( + 'All Files' + '*' + ) + ) + controller.defaultext = 'cmp' + controller.options = [fdo_checkexist, fdo_savelastdir] + controller.captionopen = 'Select Component File' + left = 40 + top = 200 + end + object c: tstringcontainer + strings.data = ( + 'Component Store' + 'Component read error.' + 'Do you want to overwrite "' + '" with current clipboard content?' + 'WARNING' + 'No component(s) in clipboard.' + 'Error while writing the storegroup.' + 'ERROR' + 'Do you want to remove "' + '"?' + '" branch?' + 'File "' + '" does not exist, do you want to create it?' + 'Save Component Store Group' + ) + left = 296 + top = 144 + end +end diff --git a/mseide-msegui/apps/ide/componentstore.pas b/mseide-msegui/apps/ide/componentstore.pas new file mode 100644 index 0000000..3d5538d --- /dev/null +++ b/mseide-msegui/apps/ide/componentstore.pas @@ -0,0 +1,1071 @@ +{ MSEide Copyright (c) 2008-2013 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit componentstore; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,mseglob,mseguiglob,mseapplication,msestat,msemenus,msegui, + msegraphics,msedragglob,msegraphutils,mseevent,mseclasses,mseforms,msedock, + mseact,mseactions,msestrings,msedataedits,mseedit,msegrids,msetypes, + msewidgetgrid,msedatanodes,mselistbrowser,msewidgets,msestatfile,msebitmap, + msefiledialog,msesys,msedialog,msememodialog,msesimplewidgets,msegridsglob, + msegraphedits,msestringcontainer,msesplitter; + +type + storedcomponentinfoty = record + compclass: ansistring; + componentname: ansistring; + compname: msestring; + compdesc: msestring; + filepath: filenamety; + storedir: filenamety; + end; + pstoredcomponentinfoty = ^storedcomponentinfoty; + + tstoredcomponent = class(ttreelistedititem) + private + finfo: storedcomponentinfoty; + fisnode: boolean; + fpasting: boolean; + procedure setinfo(const avalue: storedcomponentinfoty); + procedure setcompname(const avalue: msestring); + procedure checkisnode; + procedure setfilepath(const avalue: filenamety); + function getfilepath: msestring; + procedure setcompdesc(const avalue: msestring); + protected + procedure setcaption(const avalue: msestring); override; + public + constructor create(const aowner: tcustomitemlist = nil; + const aparent: ttreelistitem = nil); overload; override; + constructor create(const isnode: boolean); overload; + property info: storedcomponentinfoty read finfo write setinfo; + property compclass: ansistring read finfo.compclass write finfo.compclass; + property componentname: ansistring read finfo.componentname write + finfo.componentname; + property compname: msestring read finfo.compname write setcompname; + property compdesc: msestring read finfo.compdesc write setcompdesc; + property filepath: msestring read getfilepath write setfilepath; + property storedir: msestring read finfo.storedir write finfo.storedir; + property isnode: boolean read fisnode; + + procedure updatestoredir; + procedure dostatread(const reader: tstatreader); override; + procedure dostatwrite(const writer: tstatwriter); override; + end; + + storedcomponentarty = array of tstoredcomponent; + + tcomponentstorefo = class(tdockform) + grid: twidgetgrid; + node: ttreeitemedit; + copycompact: taction; + pastecompact: taction; + tpopupmenu1: tpopupmenu; + storefile: tstatfile; + filepath: tfilenameedit; + compdesc: tmemodialogedit; + storefiledialog: tfiledialog; + groupfiledialog: tfiledialog; + addfileact: taction; + compfiledialog: tfiledialog; + sel: tdatabutton; + c: tstringcontainer; + procedure createexe(const sender: TObject); + procedure dopastecomponent(const sender: TObject); + procedure statreadexe(const sender: TObject; const reader: tstatreader); + procedure statwriteexe(const sender: TObject; const writer: tstatwriter); + procedure dostatreaditem(const sender: TObject; const reader: tstatreader; + var aitem: ttreelistitem); + procedure doupdaterowvalues(const sender: TObject; const aindex: Integer; + const aitem: tlistitem); + procedure filenamesetva(const sender: TObject; var avalue: msestring; + var accept: Boolean); + procedure docopycomponent(const sender: TObject); + procedure donewnode(const sender: TObject); + procedure popupupdate(const sender: tcustommenu); + procedure copyupda(const sender: tcustomaction); + procedure pasteupda(const sender: tcustomaction); + procedure docellevent(const sender: TObject; var info: celleventinfoty); + procedure newstoreex(const sender: TObject); + procedure addstoreex(const sender: TObject); + procedure removestoreex(const sender: TObject); + procedure compdescsetva(const sender: TObject; var avalue: msestring; + var accept: Boolean); + procedure compnamesetva(const sender: TObject; var avalue: msestring; + var accept: Boolean); + procedure delnode(const sender: TObject); + procedure copynodeex(const sender: TObject); + procedure pastenodeex(const sender: TObject); + procedure beforedrag(const sender: TObject; const apos: pointty; + var dragobject: tdragobject; var processed: Boolean); + procedure drago(const sender: ttreeitemedit; const source: ttreelistitem; + const dest: ttreelistitem; + var dragobject: ttreeitemdragobject; var accept: Boolean; + var processed: Boolean); + procedure dragdro(const sender: ttreeitemedit; const source: ttreelistitem; + const dest: ttreelistitem; + var dragobject: ttreeitemdragobject; var processed: Boolean); + procedure removecomp(const sender: TObject); + procedure datent(const sender: TObject); + procedure opengroup(const sender: TObject); + procedure savegroupas(const sender: TObject); + procedure savegroup(const sender: TObject); + procedure nodeenter(const sender: TObject); + procedure nodeexit(const sender: TObject); + procedure doupdatecomponent(const sender: TObject); + procedure doaddfile(const sender: TObject); + procedure setval(const sender: TObject; var avalue: Integer; + var accept: Boolean); + private + far1: storedcomponentarty; + fstoredir: msestring; + fchanged: boolean; + fgroupfilename: filenamety; + function dosavegroupas: modalresultty; + procedure initcomponentinfo(out ainfo: storedcomponentinfoty); + function isnode: boolean; + function iscomp: boolean; + function dogetstorerec(const index: integer): msestring; + procedure dosetstorescount(const count: integer); + procedure dosetstorerec(const index: integer; const avalue: msestring); + procedure readstore(const aitem: tstoredcomponent); + procedure checkchanged; + procedure storechanged; + function writestoregroup(const afilename: filenamety): modalresultty; + function readstoregroup(const afilename: filenamety): boolean; + //false if file not found + procedure pasteoradd(const apaste: boolean); + function copycomponent: string; + public + procedure updatestat(afiler: tstatfiler); + function saveall(const quiet: boolean): modalresultty; + procedure resetselected; + function hasselection: boolean; + function copyselected: string; + end; + +var + componentstorefo: tcomponentstorefo; + +implementation +uses + componentstore_mfm,msestream,storedcomponentinfodialog,msedatalist,msefileutils, + sysutils,projectoptionsform,componentpaletteform,mseobjecttext,msearrayutils; +type + treader1 = class(treader); + strconsts = ( + storecaption, //0 Component Store + compreaderror, //1 Component read error. + wantoverwrite, //2 Do you want to overwrite " + withcurrent, //3 " with current clipboard content? + warning, //4 WARNING + nocomps, //5 No component(s) in clipboard. + errorwriting, //6 Error while writing the storegroup. + error, //7 ERROR + wantremove, //8 Do you want to remove " + qm, //9 "? + branch, //10 " branch? + str_file, //11 File " + doesnotexist, //12 " does not exist, do you want to create it? + savecompstore //13 Save Component Store Group + ); + +function getstoredir: filenamety; +begin + result:= filepath(expandprmacros('${COMPSTOREDIR}'),fk_dir); +end; + +{ tstoredcomponent } + +constructor tstoredcomponent.create(const aowner: tcustomitemlist = nil; + const aparent: ttreelistitem = nil); +begin + inherited; + include(fstate1,ns1_candrag); +end; + +constructor tstoredcomponent.create(const isnode: boolean); +begin + include(fstate1,ns1_rootchange); + fisnode:= isnode; + create(nil,nil); + checkisnode; +end; + +procedure tstoredcomponent.setinfo(const avalue: storedcomponentinfoty); +begin + finfo:= avalue; + caption:= finfo.compname; +end; + +procedure tstoredcomponent.dostatread(const reader: tstatreader); +begin + inherited; + + if not fpasting and isroot then begin + caption:= compname; //restore + end + else begin + with reader do begin + fisnode:= readboolean('isnode',fisnode); + compname:= readmsestring('compname',compname); + compclass:= readstring('compclass',compclass); + compdesc:= readmsestring('compdesc',compdesc); + finfo.filepath:= readmsestring('filepath',filepath); + finfo.storedir:= readmsestring('storedir',storedir); + end; + end; + checkisnode; +end; + +procedure tstoredcomponent.dostatwrite(const writer: tstatwriter); +begin + inherited; + with writer do begin + writeboolean('isnode',fisnode); + writemsestring('compname',compname); + writestring('compclass',compclass); + writemsestring('compdesc',compdesc); + writemsestring('filepath',finfo.filepath); + writemsestring('storedir',storedir); + end; +end; + +procedure tstoredcomponent.setcompname(const avalue: msestring); +begin + finfo.compname:= avalue; + caption:= avalue; +end; + +procedure tstoredcomponent.setcaption(const avalue: msestring); +begin + finfo.compname:= avalue; + inherited; +end; + +procedure tstoredcomponent.checkisnode; +begin + if not fisnode then begin + fimagenr:= 2; + end + else begin + if not isroot then begin + finfo.filepath:= ''; + end; + fimagenr:= 0; + end; +end; + +procedure tstoredcomponent.updatestoredir; +begin + finfo.storedir:= getstoredir; +end; + +procedure tstoredcomponent.setfilepath(const avalue: filenamety); +begin + finfo.filepath:= avalue; + statechanged; + updatestoredir; +end; + +function tstoredcomponent.getfilepath: msestring; +begin + relocatepath(finfo.storedir,getstoredir,finfo.filepath); + result:= finfo.filepath; +end; + +procedure tstoredcomponent.setcompdesc(const avalue: msestring); +begin + finfo.compdesc:= avalue; + statechanged; +end; + +{ tcomponentstorefo } + +procedure tcomponentstorefo.createexe(const sender: TObject); +begin +{ + frootnode:= tstoredcomponent.create(true); + frootnode.caption:= 'Root'; + node.itemlist.add(frootnode); + } +end; + +procedure tcomponentstorefo.initcomponentinfo(out ainfo: storedcomponentinfoty); +begin + fillchar(ainfo,sizeof(ainfo),0); + ainfo.filepath:= storefiledialog.controller.lastdir; +end; + +procedure tcomponentstorefo.pasteoradd(const apaste: boolean); +var + str1: ansistring; + str2: msestring; + stream1: tstringcopystream; + stream2: ttextstream; + stream3: ttextstream; + reader1: treader; + info: storedcomponentinfoty; + flags: tfilerflags; + int1: integer; +// compname1: string; + node1: tstoredcomponent; + statwriter1: tstatwriter; + dialogfo: tstoredcomponentinfodialogfo; +begin + statwriter1:= nil; + stream1:= nil; + stream2:= nil; + stream3:= nil; + reader1:= nil; + initcomponentinfo(info); + try + if apaste then begin + if not pastefromclipboard(str2) then begin + exit; + end; + str1:= ansistring(str2); + end + else begin + if compfiledialog.execute <> mr_ok then begin + exit; + end; + stream2:= ttextstream.create(compfiledialog.controller.filename,fm_read); + try + str1:= stream2.readdatastring; + finally + stream2.free; + end; + end; + + stream1:= tstringcopystream.create(str1); + stream2:= ttextstream.create; + try + objecttexttobinarymse(stream1,stream2); + stream2.position:= 0; + reader1:= treader.create(stream2,4096); + with info,treader1(reader1) do begin + driver.beginrootcomponent; + driver.begincomponent(flags,int1,compclass,componentname); + end; + except + if not apaste then begin + showerror(c[ord(compreaderror)]); + end; + exit; //invalid + end; + info.compname:= msestring(info.compclass); + dialogfo:= tstoredcomponentinfodialogfo.create(info); + if apaste then begin + dialogfo.checkfilename; + end + else begin + dialogfo.filepath.value:= compfiledialog.controller.filename; + end; + if dialogfo.show(true) = mr_ok then begin + stream3:= ttextstream.create(info.filepath,fm_create); + node1:= tstoredcomponent.create(false); + node1.info:= info; + node.item.add(node1); + node1.statechanged; + stream3.writedatastring(str1); + storechanged; + end; + finally + statwriter1.free; + reader1.free; + stream1.free; + stream2.free; + stream3.free; + end; +end; + +procedure tcomponentstorefo.dopastecomponent(const sender: TObject); +begin + pasteoradd(true); +end; + +procedure tcomponentstorefo.doaddfile(const sender: TObject); +begin + pasteoradd(false); +end; + +procedure tcomponentstorefo.doupdatecomponent(const sender: TObject); +var + mstr1: msestring; + str1: ansistring; + bo1: boolean; + stream1,stream2: tstream; + stream3: ttextstream; +begin + if askyesno(c[ord(wantoverwrite)]+filepath.value+c[ord(withcurrent)], + c[ord(warning)]) then begin + bo1:= false; + if pastefromclipboard(mstr1) then begin + str1:= ansistring(mstr1); + stream1:= tstringcopystream.create(str1); + stream2:= ttextstream.create; + try + objecttexttobinarymse(stream1,stream2); + bo1:= true; //no error + except + end; + stream1.free; + stream2.free; + if bo1 then begin + stream3:= ttextstream.create(filepath.value,fm_create); + try + stream3.writedatastring(str1); + finally + stream3.free; + end; + end; + end; + if not bo1 then begin + showerror(c[ord(nocomps)]); + end; + end; +end; + +function tcomponentstorefo.copycomponent: string; +var + stream1: ttextstream; +begin + with tstoredcomponent(node.item) do begin + stream1:= ttextstream.create(filepath); + try + result:= stream1.readdatastring; + finally + stream1.free; + end; + end; +end; + +procedure tcomponentstorefo.docopycomponent(const sender: TObject); +begin + copytoclipboard(msestring(copycomponent)); +end; + +procedure tcomponentstorefo.statreadexe(const sender: TObject; + const reader: tstatreader); +begin +// frootnode.dostatread(reader); +end; + +procedure tcomponentstorefo.statwriteexe(const sender: TObject; + const writer: tstatwriter); +begin +// frootnode.dostatwrite(writer); +end; + +procedure tcomponentstorefo.dostatreaditem(const sender: TObject; + const reader: tstatreader; var aitem: ttreelistitem); +begin + aitem:= tstoredcomponent.create(true); +end; + +function tcomponentstorefo.dogetstorerec(const index: integer): msestring; +begin + with far1[index].finfo do begin + result:= encoderecord([compname,filepath,compdesc]); + end; +end; + +procedure tcomponentstorefo.dosetstorescount(const count: integer); +var + int1: integer; +begin + setlength(far1,count); + for int1:= 0 to high(far1) do begin + far1[int1]:= tstoredcomponent.create(true); + end; +end; + +procedure tcomponentstorefo.dosetstorerec(const index: integer; + const avalue: msestring); +var + mstr1,mstr2,mstr3: msestring; +begin + if not decoderecord(avalue,[@mstr1,@mstr2,@mstr3],'SSS') then begin + freeandnil(far1[index]); + end + else begin + with far1[index] do begin + compname:= mstr1; + finfo.filepath:= mstr2; + compdesc:= mstr3; + end; + end; +end; + +procedure tcomponentstorefo.readstore(const aitem: tstoredcomponent); +var + reader1: tstatreader; +begin + with aitem do begin + reader1:= tstatreader.create(finfo.filepath,ce_utf8); + try + reader1.setsection('store'); + aitem.dostatread(reader1); + finally + reader1.free; + end; + end; +end; + +function tcomponentstorefo.writestoregroup( + const afilename: filenamety): modalresultty; +var + item1: tstoredcomponent; + int1: integer; + writer1,writer2: tstatwriter; +begin + result:= mr_ok; + fchanged:= false; + fgroupfilename:= msefileutils.filepath(afilename); + writer2:= nil; + try + writer2:= tstatwriter.create(fgroupfilename,ce_utf8,true); + with writer2,node do begin + for int1:= 0 to itemlist.count - 1 do begin + item1:= tstoredcomponent(items[int1]); + if item1.isroot then begin + additem(pointerarty(far1),item1); + end; + end; + writesection('componentstore'); + writerecordarray('stores',length(far1),{$ifdef FPC}@{$endif}dogetstorerec); +// try + for int1:= 0 to high(far1) do begin + with far1[int1] do begin + if isstatechanged then begin + writer1:= tstatwriter.create(finfo.filepath,ce_utf8,true); + try + writer1.writesection('store'); + far1[int1].dostatwrite(writer1); + finally + writer1.free; + end; + end; + end; + end; +// except +// application.handleexception(self); +// end; + end; + except + on e: exception do begin + fchanged:= true; + result:= showmessage(c[ord(errorwriting)]+lineend+ + msestring(e.message),c[ord(error)],[mr_cancel,mr_ignore]); + if result = mr_ignore then begin + result:= mr_ok; + end; + end; + end; + far1:= nil; + writer2.free; + checkchanged; +end; + +function tcomponentstorefo.readstoregroup(const afilename: filenamety): boolean; +var + int1: integer; + {reader1,}reader2: tstatreader; + item1: tstoredcomponent; + storedir1: filenamety; +begin + grid.clear; + reader2:= nil; + result:= afilename <> ''; + if result then begin + try + fgroupfilename:= msefileutils.filepath(afilename); + storedir1:= getstoredir; + reader2:= tstatreader.create(fgroupfilename,ce_utf8); + with reader2,node do begin + setsection('componentstore'); + readrecordarray('stores',{$ifdef FPC}@{$endif}dosetstorescount, + {$ifdef FPC}@{$endif}dosetstorerec); + try + for int1:= 0 to high(far1) do begin + item1:= far1[int1]; + if item1 <> nil then begin + with item1 do begin + if relocatepath(fstoredir,storedir1,finfo.filepath) then begin + readstore(item1); + end; + end; + end; + end; + except + application.handleexception(self); + end; + for int1:= 0 to high(far1) do begin + if far1[int1] <> nil then begin + node.itemlist.add(far1[int1]); + end; + end; + end; + except + result:= false; + end; + far1:= nil; + reader2.free; + end + else begin + fgroupfilename:= ''; + end; + fchanged:= false; + checkchanged; +end; + +procedure tcomponentstorefo.updatestat(afiler: tstatfiler); +begin + if afiler.iswriter then begin + with tstatwriter(afiler) do begin + writesection('componentstore'); + writemsestring('storedir',getstoredir); + writemsestring('filename',fgroupfilename); + end; + end + else begin + with tstatreader(afiler) do begin + setsection('componentstore'); + fstoredir:= readmsestring('storedir',getstoredir); + storefiledialog.controller.filename:= fstoredir; + groupfiledialog.controller.filename:= fstoredir; + fgroupfilename:= readmsestring('filename',fstoredir+'default.stg'); + if not readstoregroup(fgroupfilename) then begin + fgroupfilename:= ''; + end; + end; + end; +end; + +procedure tcomponentstorefo.doupdaterowvalues(const sender: TObject; + const aindex: Integer; const aitem: tlistitem); +begin + with tstoredcomponent(aitem).info do begin + self.filepath[aindex]:= filepath; + self.compdesc[aindex]:= compdesc; + end; +end; + +procedure tcomponentstorefo.filenamesetva(const sender: TObject; + var avalue: msestring; var accept: Boolean); +begin + tstoredcomponent(node.item).filepath:= avalue; +end; + +procedure tcomponentstorefo.compdescsetva(const sender: TObject; + var avalue: msestring; var accept: Boolean); +begin + tstoredcomponent(node.item).compdesc:= avalue; +end; + +procedure tcomponentstorefo.compnamesetva(const sender: TObject; + var avalue: msestring; var accept: Boolean); +begin + tstoredcomponent(node.item).compname:= avalue; +end; + +procedure tcomponentstorefo.donewnode(const sender: TObject); +var + int1: integer; +begin + with node.item do begin + int1:= add(tstoredcomponent.create(true)); + expanded:= true; + end; + grid.row:= grid.row + int1 + 1; + node.beginedit; +end; + +function tcomponentstorefo.isnode: boolean; +begin + result:= (node.item <> nil) and (tstoredcomponent(node.item).fisnode); +end; + +function tcomponentstorefo.iscomp: boolean; +begin + result:= (node.item <> nil) and not(tstoredcomponent(node.item).fisnode); +end; + +procedure tcomponentstorefo.popupupdate(const sender: tcustommenu); +var + bo1,bo2: boolean; +begin + bo1:= isnode; + bo2:= iscomp; + sender.menu.submenu.itembyname('addnode').enabled:= bo1; + sender.menu.submenu.itembyname('pastenode').enabled:= bo1; + sender.menu.submenu.itembyname('updatenode').enabled:= bo2; + sender.menu.submenu.itembyname('removestore').enabled:= bo1 and + node.item.isroot; + sender.menu.submenu.itembyname('removecomp').enabled:= bo2; + bo1:= isnode and not node.item.isroot; + sender.menu.submenu.itembyname('removenode').enabled:= bo1; + sender.menu.submenu.itembyname('copynode').enabled:= bo1; +end; + +procedure tcomponentstorefo.copyupda(const sender: tcustomaction); +begin + sender.enabled:= iscomp; +end; + +procedure tcomponentstorefo.pasteupda(const sender: tcustomaction); +begin + sender.enabled:= isnode; +end; + +procedure tcomponentstorefo.docellevent(const sender: TObject; + var info: celleventinfoty); +var + bo1: boolean; +begin +// if isrowexit(info) then begin +// resetselected; +// end; + case info.eventkind of + cek_enter: begin + with tstoredcomponent(node.item) do begin + bo1:= fisnode; + self.filepath.readonly:= bo1;; + if bo1 and (treelevel > 0) then begin + self.filepath.value:= ''; + end; + end; + end; + end; +end; + +//todo: check duplicates +procedure tcomponentstorefo.newstoreex(const sender: TObject); +var + stream1: ttextstream; + node1: tstoredcomponent; +begin + with storefiledialog do begin + if execute(fdk_save) = mr_ok then begin + stream1:= ttextstream.create(controller.filename,fm_create); + stream1.free; + node1:= tstoredcomponent.create(true); + with node1.finfo do begin + filepath:= controller.filename; + compname:= removefileext(filename(filepath)); + node1.caption:= compname; + end; + node.itemlist.add(node1); + storechanged; + end; + end; +end; + +//todo: check duplicates +procedure tcomponentstorefo.addstoreex(const sender: TObject); +var +// stream1: ttextstream; + node1: tstoredcomponent; +begin + with storefiledialog do begin + if execute(fdk_open) = mr_ok then begin + node1:= tstoredcomponent.create(true); + with node1.finfo do begin + storedir:= getstoredir; + filepath:= controller.filename; + compname:= removefileext(filename(filepath)); + node1.caption:= compname; + end; + readstore(node1); + node.itemlist.add(node1); + storechanged; + end; + end; +end; + +procedure tcomponentstorefo.removestoreex(const sender: TObject); +begin + with tstoredcomponent(node.item).finfo do begin + if askyesno(c[ord(wantremove)]+compname+c[ord(qm)]) then begin + tstoredcomponent(node.item).free; + storechanged; + end; + end; +end; + +procedure tcomponentstorefo.delnode(const sender: TObject); +begin + with tstoredcomponent(node.item).finfo do begin + if askyesno(c[ord(wantremove)]+compname+c[ord(branch)]) then begin + tstoredcomponent(node.item).free; + storechanged; + end; + end; +end; + +procedure tcomponentstorefo.removecomp(const sender: TObject); +begin + with tstoredcomponent(node.item).finfo do begin + if askyesno(c[ord(wantremove)]+compname+c[ord(qm)]) then begin + tstoredcomponent(node.item).free; + storechanged; + end; + end; +end; + +const + nodecopysig = '{DEA80549-4F45-4117-B182-A0EF49C4A097}'; + +procedure tcomponentstorefo.copynodeex(const sender: TObject); +var + stream1: ttextstream; + writer1: tstatwriter; +begin + stream1:= ttextstream.create; //memory stream + writer1:= tstatwriter.create(stream1,ce_utf8); +// stream1.encoding:= ce_utf8n; + try + writer1.writesection('nodecopy'); + writer1.writemsestring('signature',nodecopysig); + node.item.dostatwrite(writer1); + stream1.position:= 0; + copytoclipboard(utf8tostringansi(stream1.readdatastring)); + finally + writer1.free; + stream1.free; + end; +end; + +procedure tcomponentstorefo.pastenodeex(const sender: TObject); +var + reader1: tstatreader; + stream1: ttextstream; + node1: tstoredcomponent; + mstr1: msestring; +begin + if pastefromclipboard(mstr1) then begin + reader1:= nil; + stream1:= nil; + try + stream1:= ttextstream.createdata(stringtoutf8ansi(mstr1)); +// stream1.encoding:= ce_utf8n; + reader1:= tstatreader.create(stream1,ce_utf8); + if reader1.findsection('nodecopy') and + (reader1.readmsestring('signature','') = nodecopysig) then begin + node1:= tstoredcomponent.create(true); + node1.fpasting:= true; + node1.dostatread(reader1); + node1.fpasting:= false; + with node.item do begin + expanded:= true; + add(node1); + grid.row:= grid.row + count; + end; + storechanged; + end; + finally + reader1.free; + stream1.free; + end; + end; +end; + +procedure tcomponentstorefo.beforedrag(const sender: TObject; + const apos: pointty; var dragobject: tdragobject; + var processed: Boolean); +//var +// widget1: twidget; +begin +end; + +procedure tcomponentstorefo.drago(const sender: ttreeitemedit; + const source: ttreelistitem; const dest: ttreelistitem; + var dragobject: ttreeitemdragobject; var accept: Boolean; + var processed: Boolean); +begin + accept:= not dest.checkancestor(source) and + not ((source.parent = nil) and (dest.parent <> nil)) and + not (tstoredcomponent(source).isnode and + not tstoredcomponent(dest).isnode); +end; + +procedure tcomponentstorefo.dragdro(const sender: ttreeitemedit; + const source: ttreelistitem; const dest: ttreelistitem; + var dragobject: ttreeitemdragobject; var processed: Boolean); +begin + if tstoredcomponent(dest).isnode then begin + dest.add(source); + end + else begin + sender.itemlist.moverow(dest.index,source.index); + end; + storechanged; +end; + +procedure tcomponentstorefo.datent(const sender: TObject); +begin + storechanged; +end; + +procedure tcomponentstorefo.checkchanged; +var + mstr1,mstr2: msestring; +begin + if fchanged then begin + mstr1:= '*'; + end + else begin + mstr1:= ''; + end; + if fgroupfilename = '' then begin + mstr2:= ''; + end + else begin + mstr2:= filename(fgroupfilename); + end; + dragdock.caption:= mstr1+c[ord(storecaption)]+' ('+mstr2+')'; +end; + +procedure tcomponentstorefo.storechanged; +begin + fchanged:= true; + checkchanged; +end; + +function tcomponentstorefo.saveall(const quiet: boolean): modalresultty; +begin + result:= mr_none; + if fchanged then begin + if fgroupfilename = '' then begin + result:= dosavegroupas(); + end + else begin + if quiet or confirmsavechangedfile(fgroupfilename,result) then begin + result:= writestoregroup(fgroupfilename); + end; + end; + end; +end; + +procedure tcomponentstorefo.opengroup(const sender: TObject); +begin + if canclose(nil) and (saveall(false) <> mr_cancel) then begin + with groupfiledialog,controller do begin + filename:= fgroupfilename; + if execute(fdk_open) = mr_ok then begin + if not findfile(filename) then begin + if askyesno(c[ord(str_file)]+filename+c[ord(doesnotexist)]) then begin + writestoregroup(filename); + end; + end + else begin + readstoregroup(filename); + end; + end; + end; + end; +end; + +procedure tcomponentstorefo.savegroup(const sender: TObject); +begin + if canclose(nil) then begin + if fgroupfilename = '' then begin + savegroupas(sender); + end + else begin + writestoregroup(fgroupfilename); + end; + end; +end; + +function tcomponentstorefo.dosavegroupas: modalresultty; +begin + with groupfiledialog,controller do begin + filename:= fgroupfilename; + result:= execute(fdk_save,c[ord(savecompstore)],[fdo_checkexist]); + if result = mr_ok then begin + result:= writestoregroup(filename); + end; + end; +end; + +procedure tcomponentstorefo.savegroupas(const sender: TObject); +begin + if canclose(nil) then begin + dosavegroupas; + end; +end; + +procedure tcomponentstorefo.nodeenter(const sender: TObject); +begin + copycompact.shortcut:= sysshortcuts[sho_copy]; + pastecompact.shortcut:= sysshortcuts[sho_paste]; +end; + +procedure tcomponentstorefo.nodeexit(const sender: TObject); +begin + copycompact.shortcut:= 0; + pastecompact.shortcut:= 0; +end; + +procedure tcomponentstorefo.setval(const sender: TObject; var avalue: Integer; + var accept: Boolean); +begin + if not iscomp and (avalue <> -1) then begin + accept:= false; + end + else begin + if avalue >= 0 then begin + componentpalettefo.resetselected; + end; + end; +end; + +procedure tcomponentstorefo.resetselected; +begin + sel.value:= -1; +end; + +function tcomponentstorefo.copyselected: string; +begin + result:= ''; + if sel.checkedrow >= 0 then begin + result:= copycomponent; + resetselected; + end; +end; + +function tcomponentstorefo.hasselection: boolean; +begin + result:= sel.checkedrow >= 0; +end; +{ +procedure tcomponentstorefo.selcha(const sender: tdatacol; + const aindex: Integer); +begin + if aindex >= 0 then begin + if tstoredcomponent(node[aindex]).fisnode then begin + if sel[aindex] <> -1 then begin //no recursion + sel[aindex]:= -1; + end; + end; + end; +end; +} +end. diff --git a/mseide-msegui/apps/ide/componentstore_mfm.pas b/mseide-msegui/apps/ide/componentstore_mfm.pas new file mode 100644 index 0000000..4708019 --- /dev/null +++ b/mseide-msegui/apps/ide/componentstore_mfm.pas @@ -0,0 +1,524 @@ +unit componentstore_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,componentstore; + +const + objdata: record size: integer; data: array[0..10139] of byte end = + (size: 10140; data: ( + 84,80,70,48,17,116,99,111,109,112,111,110,101,110,116,115,116,111,114,101, + 102,111,16,99,111,109,112,111,110,101,110,116,115,116,111,114,101,102,111,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,11,111,119,95,115,117,98,102,111,99,117,115, + 13,111,119,95,109,111,117,115,101,119,104,101,101,108,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,9,111,119,95,104,105,110,116, + 111,110,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,15,102,114,97,109,101,46,103,114,105,112,95,115,105,122,101,2,10, + 18,102,114,97,109,101,46,103,114,105,112,95,111,112,116,105,111,110,115,11, + 14,103,111,95,99,108,111,115,101,98,117,116,116,111,110,16,103,111,95,102, + 105,120,115,105,122,101,98,117,116,116,111,110,14,103,111,95,102,108,111,97, + 116,98,117,116,116,111,110,12,103,111,95,116,111,112,98,117,116,116,111,110, + 19,103,111,95,98,97,99,107,103,114,111,117,110,100,98,117,116,116,111,110, + 15,103,111,95,110,111,108,111,99,107,98,117,116,116,111,110,14,103,111,95, + 98,117,116,116,111,110,104,105,110,116,115,0,7,118,105,115,105,98,108,101, + 8,8,98,111,117,110,100,115,95,120,3,49,1,8,98,111,117,110,100,115, + 95,121,2,101,9,98,111,117,110,100,115,95,99,120,3,189,1,9,98,111, + 117,110,100,115,95,99,121,3,98,1,26,99,111,110,116,97,105,110,101,114, + 46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,27, + 99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,16,99,111,110,116,97,105,110,101,114,46, + 98,111,117,110,100,115,1,2,0,2,0,3,179,1,3,98,1,0,16,100, + 114,97,103,100,111,99,107,46,99,97,112,116,105,111,110,6,15,67,111,109, + 112,111,110,101,110,116,32,83,116,111,114,101,20,100,114,97,103,100,111,99, + 107,46,111,112,116,105,111,110,115,100,111,99,107,11,10,111,100,95,115,97, + 118,101,112,111,115,13,111,100,95,115,97,118,101,122,111,114,100,101,114,10, + 111,100,95,99,97,110,109,111,118,101,10,111,100,95,99,97,110,115,105,122, + 101,11,111,100,95,99,97,110,102,108,111,97,116,10,111,100,95,99,97,110, + 100,111,99,107,15,111,100,95,112,114,111,112,111,114,116,105,111,110,97,108, + 11,111,100,95,112,114,111,112,115,105,122,101,14,111,100,95,99,97,112,116, + 105,111,110,104,105,110,116,13,111,100,95,99,104,105,108,100,105,99,111,110, + 115,0,7,111,112,116,105,111,110,115,11,10,102,111,95,115,97,118,101,112, + 111,115,13,102,111,95,115,97,118,101,122,111,114,100,101,114,12,102,111,95, + 115,97,118,101,115,116,97,116,101,0,8,115,116,97,116,102,105,108,101,7, + 22,109,97,105,110,102,111,46,112,114,111,106,101,99,116,115,116,97,116,102, + 105,108,101,21,105,99,111,110,46,116,114,97,110,115,112,97,114,101,110,116, + 99,111,108,111,114,4,6,0,0,128,10,105,99,111,110,46,105,109,97,103, + 101,10,212,7,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0, + 0,0,160,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,245,245, + 245,1,243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1,237,237, + 237,1,235,235,235,1,234,234,234,1,232,232,232,1,230,230,230,1,229,229, + 229,1,227,227,227,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221, + 221,1,219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213, + 213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243, + 243,1,242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1,235,235, + 235,1,234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1,227,227, + 227,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219, + 219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211, + 211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242, + 242,1,240,240,240,1,238,238,238,1,237,237,237,1,235,235,235,1,234,234, + 234,1,232,232,232,1,230,230,230,1,229,229,229,1,227,227,227,1,226,226, + 226,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219,219,1,218,218, + 218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1,210,210, + 210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240, + 240,1,233,233,233,1,178,178,178,1,154,154,154,2,155,155,155,2,156,156, + 156,1,155,155,155,1,157,157,157,1,156,156,156,1,157,157,157,1,156,156, + 156,2,158,158,158,1,157,157,157,1,158,158,158,1,164,164,164,1,211,211, + 211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242, + 242,1,226,226,226,1,165,165,165,1,188,188,188,1,222,222,222,1,223,223, + 223,1,222,222,222,4,221,221,221,2,220,220,220,4,203,203,203,1,156,156, + 156,1,155,155,155,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245, + 245,1,243,243,243,1,242,242,242,1,141,141,141,1,134,134,134,14,141,141, + 141,1,187,187,187,1,155,155,155,1,211,211,211,1,210,210,210,1,208,208, + 208,1,245,245,245,1,243,243,243,1,242,242,242,1,134,134,134,1,170,170, + 255,1,174,174,255,1,178,178,255,1,182,182,255,1,187,187,255,1,191,191, + 255,1,195,195,255,1,200,200,255,1,204,204,255,1,208,208,255,1,212,212, + 255,1,214,214,255,3,135,135,135,1,214,214,214,1,154,154,154,1,211,211, + 211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242, + 242,1,134,134,134,1,170,170,255,1,174,174,255,1,178,178,255,1,182,182, + 255,1,187,187,255,1,191,191,255,1,195,195,255,1,0,0,0,1,204,204, + 255,1,208,208,255,1,212,212,255,1,214,214,255,3,135,135,135,1,215,215, + 215,1,154,154,154,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245, + 245,1,243,243,243,1,242,242,242,1,134,134,134,1,170,170,255,1,174,174, + 255,1,178,178,255,1,182,182,255,1,187,187,255,1,191,191,255,1,195,195, + 255,1,200,200,255,1,204,204,255,1,208,208,255,1,212,212,255,1,214,214, + 255,3,135,135,135,1,215,215,215,1,155,155,155,1,211,211,211,1,210,210, + 210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,134,134, + 134,1,170,170,255,1,174,174,255,1,178,178,255,1,182,182,255,1,187,187, + 255,1,191,191,255,1,195,195,255,1,200,200,255,1,204,204,255,1,208,208, + 255,1,212,212,255,1,214,214,255,3,135,135,135,1,215,215,215,1,156,156, + 156,1,210,210,210,2,208,208,208,1,245,245,245,1,243,243,243,1,242,242, + 242,1,134,134,134,1,138,138,138,3,139,139,139,5,140,140,140,6,135,135, + 135,1,215,215,215,1,156,156,156,1,209,209,209,1,210,210,210,1,208,208, + 208,1,245,245,245,1,243,243,243,1,242,242,242,1,134,134,134,1,170,255, + 246,1,174,255,247,1,178,255,247,1,182,255,248,1,187,255,249,1,191,255, + 249,1,195,255,250,1,200,255,251,1,204,255,252,1,208,255,252,1,212,255, + 253,1,214,255,253,2,216,252,251,1,135,135,135,1,215,215,215,1,156,156, + 156,1,209,209,209,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243, + 243,1,242,242,242,1,134,134,134,1,170,255,246,1,174,255,247,1,178,255, + 247,1,182,255,248,1,187,255,249,1,191,255,249,1,195,255,250,1,0,0, + 0,1,204,255,252,1,208,255,252,1,212,255,253,1,214,255,253,2,217,253, + 251,1,135,135,135,1,215,215,215,1,157,157,157,1,208,208,208,1,210,210, + 210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,134,134, + 134,1,170,255,246,1,174,255,247,1,178,255,247,1,182,255,248,1,187,255, + 249,1,191,255,249,1,195,255,250,1,200,255,251,1,204,255,252,1,208,255, + 252,1,212,255,253,1,214,255,253,2,217,253,251,1,135,135,135,1,215,215, + 215,1,158,158,158,1,208,208,208,1,210,210,210,1,208,208,208,1,245,245, + 245,1,243,243,243,1,242,242,242,1,134,134,134,1,170,255,246,1,174,255, + 247,1,178,255,247,1,182,255,248,1,187,255,249,1,191,255,249,1,195,255, + 250,1,200,255,251,1,204,255,252,1,208,255,252,1,212,255,253,1,214,255, + 253,2,217,253,251,1,135,135,135,1,214,214,214,1,158,158,158,1,207,207, + 207,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242, + 242,1,134,134,134,1,138,138,138,3,139,139,139,5,140,140,140,6,135,135, + 135,1,214,214,214,1,159,159,159,1,206,206,206,1,210,210,210,1,208,208, + 208,1,245,245,245,1,243,243,243,1,242,242,242,1,157,140,143,1,255,170, + 185,1,255,175,187,1,255,179,190,1,255,183,193,1,255,187,196,1,255,191, + 199,1,255,196,202,1,255,200,205,1,255,204,208,1,255,208,211,1,255,213, + 214,1,255,214,215,3,135,135,135,1,214,214,214,1,159,159,159,1,206,206, + 206,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242, + 242,1,157,140,143,1,255,170,185,1,255,175,187,1,255,179,190,1,255,183, + 193,1,255,187,196,1,255,191,199,1,255,196,202,1,0,0,0,1,255,204, + 208,1,255,208,211,1,255,213,214,1,255,214,215,3,135,135,135,1,196,196, + 196,1,163,163,163,1,210,210,210,2,208,208,208,1,245,245,245,1,243,243, + 243,1,242,242,242,1,157,140,143,1,255,170,185,1,255,175,187,1,255,179, + 190,1,255,183,193,1,255,187,196,1,255,191,199,1,255,196,202,1,255,200, + 205,1,255,204,208,1,255,208,211,1,255,213,214,1,255,214,215,3,135,135, + 135,1,162,162,162,1,196,196,196,1,211,211,211,1,210,210,210,1,208,208, + 208,1,245,245,245,1,243,243,243,1,242,242,242,1,157,140,143,1,255,170, + 185,1,255,175,187,1,255,179,190,1,255,183,193,1,255,187,196,1,255,191, + 199,1,255,196,202,1,255,200,205,1,255,204,208,1,255,208,211,1,255,213, + 214,1,255,214,215,3,135,135,135,1,172,172,172,1,213,213,213,1,211,211, + 211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242, + 242,1,145,145,145,1,136,136,136,11,137,137,137,1,136,136,136,2,142,142, + 142,1,202,202,202,1,211,211,211,2,210,210,210,1,208,208,208,1,245,245, + 245,1,243,243,243,1,242,242,242,1,233,233,233,1,198,198,198,1,129,129, + 129,1,114,114,114,2,113,113,113,1,112,112,112,2,111,111,111,2,110,110, + 110,1,109,109,109,1,108,108,108,1,107,107,107,3,124,124,124,1,191,191, + 191,1,209,209,209,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243, + 243,1,240,240,240,1,216,216,216,1,140,140,140,1,117,117,117,1,114,114, + 114,2,113,113,113,1,112,112,112,1,111,111,111,1,110,110,110,2,109,109, + 109,1,108,108,108,1,107,107,107,1,106,106,106,2,113,113,113,1,169,169, + 169,1,207,207,207,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245, + 245,1,243,243,243,1,242,242,242,1,238,238,238,1,231,231,231,1,230,230, + 230,1,227,227,227,1,226,226,226,1,224,224,224,1,222,222,222,1,221,221, + 221,1,219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213, + 213,1,211,211,211,1,210,210,210,1,209,209,209,1,212,212,212,2,211,211, + 211,1,210,210,210,1,208,208,208,1,8,111,110,99,114,101,97,116,101,7, + 9,99,114,101,97,116,101,101,120,101,15,109,111,100,117,108,101,99,108,97, + 115,115,110,97,109,101,6,9,116,100,111,99,107,102,111,114,109,0,11,116, + 119,105,100,103,101,116,103,114,105,100,4,103,114,105,100,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,9,112,111,112,117,112, + 109,101,110,117,7,11,116,112,111,112,117,112,109,101,110,117,49,8,98,111, + 117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,120,3,179,1,9,98,111,117,110,100,115,95, + 99,121,3,98,1,7,97,110,99,104,111,114,115,11,0,11,111,112,116,105, + 111,110,115,103,114,105,100,11,12,111,103,95,99,111,108,115,105,122,105,110, + 103,19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101, + 114,20,111,103,95,99,111,108,99,104,97,110,103,101,111,110,116,97,98,107, + 101,121,10,111,103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116, + 111,112,111,112,117,112,17,111,103,95,109,111,117,115,101,115,99,114,111,108, + 108,99,111,108,0,13,102,105,120,114,111,119,115,46,99,111,117,110,116,2, + 1,13,102,105,120,114,111,119,115,46,105,116,101,109,115,14,1,6,104,101, + 105,103,104,116,2,16,14,99,97,112,116,105,111,110,115,46,99,111,117,110, + 116,2,4,14,99,97,112,116,105,111,110,115,46,105,116,101,109,115,14,1, + 7,99,97,112,116,105,111,110,6,4,78,97,109,101,0,1,7,99,97,112, + 116,105,111,110,6,3,83,101,108,4,104,105,110,116,6,25,83,101,108,101, + 99,116,32,105,116,101,109,32,102,111,114,32,105,110,115,101,114,116,105,110, + 103,0,1,7,99,97,112,116,105,111,110,6,11,68,101,115,99,114,105,112, + 116,105,111,110,0,1,7,99,97,112,116,105,111,110,6,4,70,105,108,101, + 0,0,0,0,14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2, + 4,16,100,97,116,97,99,111,108,115,46,111,112,116,105,111,110,115,11,15, + 99,111,95,112,114,111,112,111,114,116,105,111,110,97,108,12,99,111,95,115, + 97,118,101,115,116,97,116,101,17,99,111,95,109,111,117,115,101,115,99,114, + 111,108,108,114,111,119,0,14,100,97,116,97,99,111,108,115,46,105,116,101, + 109,115,14,7,4,110,111,100,101,1,5,119,105,100,116,104,2,110,7,111, + 112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117,115, + 15,99,111,95,112,114,111,112,111,114,116,105,111,110,97,108,12,99,111,95, + 115,97,118,101,115,116,97,116,101,17,99,111,95,109,111,117,115,101,115,99, + 114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6, + 4,110,111,100,101,9,100,97,116,97,99,108,97,115,115,7,17,116,116,114, + 101,101,105,116,101,109,101,100,105,116,108,105,115,116,22,100,97,116,97,108, + 105,115,116,46,105,109,110,114,95,101,120,112,97,110,100,101,100,2,1,18, + 100,97,116,97,108,105,115,116,46,105,109,97,103,101,108,105,115,116,7,20, + 102,105,108,101,100,105,97,108,111,103,114,101,115,46,105,109,97,103,101,115, + 19,100,97,116,97,108,105,115,116,46,105,109,97,103,101,119,105,100,116,104, + 2,16,20,100,97,116,97,108,105,115,116,46,105,109,97,103,101,104,101,105, + 103,104,116,2,16,23,100,97,116,97,108,105,115,116,46,111,110,115,116,97, + 116,114,101,97,100,105,116,101,109,7,14,100,111,115,116,97,116,114,101,97, + 100,105,116,101,109,19,100,97,116,97,108,105,115,116,46,111,110,100,114,97, + 103,111,118,101,114,7,5,100,114,97,103,111,19,100,97,116,97,108,105,115, + 116,46,111,110,100,114,97,103,100,114,111,112,7,7,100,114,97,103,100,114, + 111,0,7,3,115,101,108,1,5,99,111,108,111,114,4,2,0,0,128,5, + 119,105,100,116,104,2,28,7,111,112,116,105,111,110,115,11,11,99,111,95, + 102,105,120,119,105,100,116,104,15,99,111,95,112,114,111,112,111,114,116,105, + 111,110,97,108,12,99,111,95,115,97,118,101,115,116,97,116,101,17,99,111, + 95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,8,119,105,100, + 116,104,109,105,110,2,0,10,119,105,100,103,101,116,110,97,109,101,6,3, + 115,101,108,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100, + 105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,8,99,111, + 109,112,100,101,115,99,1,5,119,105,100,116,104,2,103,7,111,112,116,105, + 111,110,115,11,7,99,111,95,102,105,108,108,12,99,111,95,115,97,118,101, + 115,116,97,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108, + 114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,8,99,111,109, + 112,100,101,115,99,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114, + 105,100,109,115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0, + 7,8,102,105,108,101,112,97,116,104,1,5,119,105,100,116,104,3,186,0, + 7,111,112,116,105,111,110,115,11,15,99,111,95,112,114,111,112,111,114,116, + 105,111,110,97,108,12,99,111,95,115,97,118,101,115,116,97,116,101,17,99, + 111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105, + 100,103,101,116,110,97,109,101,6,8,102,105,108,101,112,97,116,104,9,100, + 97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116, + 114,105,110,103,100,97,116,97,108,105,115,116,0,0,13,100,97,116,97,114, + 111,119,104,101,105,103,104,116,2,16,8,115,116,97,116,102,105,108,101,7, + 22,109,97,105,110,102,111,46,112,114,111,106,101,99,116,115,116,97,116,102, + 105,108,101,11,111,110,99,101,108,108,101,118,101,110,116,7,11,100,111,99, + 101,108,108,101,118,101,110,116,22,100,114,97,103,46,111,110,98,101,102,111, + 114,101,100,114,97,103,98,101,103,105,110,7,10,98,101,102,111,114,101,100, + 114,97,103,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0, + 13,116,116,114,101,101,105,116,101,109,101,100,105,116,4,110,111,100,101,14, + 111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95, + 102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,12,102,114,97, + 109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99,111, + 108,111,114,99,108,105,101,110,116,4,3,0,0,128,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,10,102,114,108,95,108,101,118,101,108,105,15,102,114,108,95,99, + 111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114, + 2,1,7,111,110,101,110,116,101,114,7,9,110,111,100,101,101,110,116,101, + 114,6,111,110,101,120,105,116,7,8,110,111,100,101,101,120,105,116,7,118, + 105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,0,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2, + 110,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110, + 115,101,100,105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105,116, + 11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108, + 111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99, + 97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110, + 12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115, + 101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120, + 105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101, + 110,116,101,114,18,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116, + 101,120,116,9,111,101,95,108,111,99,97,116,101,0,13,111,110,100,97,116, + 97,101,110,116,101,114,101,100,7,6,100,97,116,101,110,116,10,111,110,115, + 101,116,118,97,108,117,101,7,13,99,111,109,112,110,97,109,101,115,101,116, + 118,97,17,111,110,117,112,100,97,116,101,114,111,119,118,97,108,117,101,115, + 7,17,100,111,117,112,100,97,116,101,114,111,119,118,97,108,117,101,115,7, + 111,112,116,105,111,110,115,11,16,116,101,111,95,116,114,101,101,99,111,108, + 110,97,118,105,103,16,116,101,111,95,107,101,121,114,111,119,109,111,118,105, + 110,103,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0, + 0,11,116,100,97,116,97,98,117,116,116,111,110,3,115,101,108,8,116,97, + 98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,2,111,8, + 98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120, + 2,28,9,98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105,111, + 110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99, + 13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104, + 101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105,102,116, + 114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114,110,20, + 111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116, + 15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95, + 101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101, + 108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110, + 102,105,114,115,116,99,108,105,99,107,0,12,111,112,116,105,111,110,115,101, + 100,105,116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109, + 101,110,117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111, + 101,49,95,115,97,118,101,115,116,97,116,101,0,7,111,112,116,105,111,110, + 115,11,17,98,111,95,101,120,101,99,117,116,101,111,110,99,108,105,99,107, + 15,98,111,95,101,120,101,99,117,116,101,111,110,107,101,121,20,98,111,95, + 101,120,101,99,117,116,101,111,110,115,104,111,114,116,99,117,116,27,98,111, + 95,101,120,101,99,117,116,101,100,101,102,97,117,108,116,111,110,101,110,116, + 101,114,107,101,121,15,98,111,95,114,97,100,105,111,105,116,101,109,99,111, + 108,12,98,111,95,99,97,110,116,111,103,103,108,101,24,98,111,95,114,101, + 115,101,116,99,104,101,99,107,101,100,111,110,114,111,119,101,120,105,116,0, + 5,115,116,97,116,101,11,12,97,115,95,105,110,118,105,115,105,98,108,101, + 17,97,115,95,108,111,99,97,108,105,110,118,105,115,105,98,108,101,0,16, + 118,97,108,117,101,102,97,99,101,115,46,99,111,117,110,116,2,1,16,118, + 97,108,117,101,102,97,99,101,115,46,105,116,101,109,115,14,1,14,102,97, + 100,101,95,112,111,115,46,99,111,117,110,116,2,2,14,102,97,100,101,95, + 112,111,115,46,105,116,101,109,115,1,2,0,2,1,0,16,102,97,100,101, + 95,99,111,108,111,114,46,99,111,117,110,116,2,2,16,102,97,100,101,95, + 99,111,108,111,114,46,105,116,101,109,115,1,4,7,0,0,160,4,135,223, + 255,0,0,14,102,97,100,101,95,100,105,114,101,99,116,105,111,110,7,7, + 103,100,95,100,111,119,110,10,108,111,99,97,108,112,114,111,112,115,11,15, + 102,97,108,95,102,97,100,105,114,101,99,116,105,111,110,0,0,0,10,111, + 110,115,101,116,118,97,108,117,101,7,6,115,101,116,118,97,108,0,0,15, + 116,109,101,109,111,100,105,97,108,111,103,101,100,105,116,8,99,111,109,112, + 100,101,115,99,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11, + 19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116, + 0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97, + 109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,10,102,114,108,95,108,101,118,101,108,105,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,19,102,114,97, + 109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1,19,102, + 114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1, + 5,99,111,108,111,114,4,2,0,0,128,7,105,109,97,103,101,110,114,2, + 17,0,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108, + 111,114,4,2,0,0,128,20,102,114,97,109,101,46,98,117,116,116,111,110, + 46,105,109,97,103,101,110,114,2,17,8,116,97,98,111,114,100,101,114,2, + 3,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3, + 140,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,2,103,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112, + 116,105,111,110,115,101,100,105,116,49,11,0,11,111,112,116,105,111,110,115, + 101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111, + 101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99, + 107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101, + 116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101, + 95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111, + 101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110, + 100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101, + 99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105, + 114,115,116,99,108,105,99,107,18,111,101,95,104,105,110,116,99,108,105,112, + 112,101,100,116,101,120,116,0,13,111,110,100,97,116,97,101,110,116,101,114, + 101,100,7,6,100,97,116,101,110,116,10,111,110,115,101,116,118,97,108,117, + 101,7,13,99,111,109,112,100,101,115,99,115,101,116,118,97,13,114,101,102, + 102,111,110,116,104,101,105,103,104,116,2,14,0,0,13,116,102,105,108,101, + 110,97,109,101,101,100,105,116,8,102,105,108,101,112,97,116,104,14,111,112, + 116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111, + 110,116,103,108,121,112,104,104,101,105,103,104,116,0,12,102,114,97,109,101, + 46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111, + 114,99,108,105,101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,10,102,114,108,95,108,101,118,101,108,105,15,102,114,108,95,99,111,108, + 111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,19,102,114,97,109,101,46,98,117,116,116, + 111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117, + 116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4, + 5,0,0,144,7,105,109,97,103,101,110,114,2,17,0,0,18,102,114,97, + 109,101,46,98,117,116,116,111,110,46,99,111,108,111,114,4,5,0,0,144, + 20,102,114,97,109,101,46,98,117,116,116,111,110,46,105,109,97,103,101,110, + 114,2,17,8,116,97,98,111,114,100,101,114,2,4,7,118,105,115,105,98, + 108,101,8,8,98,111,117,110,100,115,95,120,3,244,0,8,98,111,117,110, + 100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,186,0,9, + 98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101, + 100,105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105,116,11,12, + 111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115, + 101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110, + 99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111, + 101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116, + 115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116, + 111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116, + 101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95, + 97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105, + 99,107,18,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120, + 116,0,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101, + 110,116,101,114,101,100,11,116,102,95,110,111,115,101,108,101,99,116,14,116, + 102,95,101,108,108,105,112,115,101,108,101,102,116,0,13,111,110,100,97,116, + 97,101,110,116,101,114,101,100,7,6,100,97,116,101,110,116,10,111,110,115, + 101,116,118,97,108,117,101,7,13,102,105,108,101,110,97,109,101,115,101,116, + 118,97,26,99,111,110,116,114,111,108,108,101,114,46,102,105,108,116,101,114, + 108,105,115,116,46,100,97,116,97,1,1,6,14,67,111,109,112,111,110,101, + 110,116,32,70,105,108,101,6,5,42,46,99,109,112,0,1,6,9,65,108, + 108,32,70,105,108,101,115,6,1,42,0,0,21,99,111,110,116,114,111,108, + 108,101,114,46,100,101,102,97,117,108,116,101,120,116,6,3,99,109,112,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,7,116, + 97,99,116,105,111,110,11,99,111,112,121,99,111,109,112,97,99,116,7,99, + 97,112,116,105,111,110,6,15,38,67,111,112,121,32,67,111,109,112,111,110, + 101,110,116,7,111,112,116,105,111,110,115,11,16,97,111,95,108,111,99,97, + 108,115,104,111,114,116,99,117,116,0,9,111,110,101,120,101,99,117,116,101, + 7,15,100,111,99,111,112,121,99,111,109,112,111,110,101,110,116,8,111,110, + 117,112,100,97,116,101,7,8,99,111,112,121,117,112,100,97,4,108,101,102, + 116,3,176,0,3,116,111,112,2,64,0,0,7,116,97,99,116,105,111,110, + 12,112,97,115,116,101,99,111,109,112,97,99,116,7,99,97,112,116,105,111, + 110,6,19,38,80,97,115,116,101,32,67,111,109,112,111,110,101,110,116,40, + 115,41,7,111,112,116,105,111,110,115,11,16,97,111,95,108,111,99,97,108, + 115,104,111,114,116,99,117,116,0,9,111,110,101,120,101,99,117,116,101,7, + 16,100,111,112,97,115,116,101,99,111,109,112,111,110,101,110,116,8,111,110, + 117,112,100,97,116,101,7,9,112,97,115,116,101,117,112,100,97,4,108,101, + 102,116,3,176,0,3,116,111,112,2,88,0,0,10,116,112,111,112,117,112, + 109,101,110,117,11,116,112,111,112,117,112,109,101,110,117,49,8,111,110,117, + 112,100,97,116,101,7,11,112,111,112,117,112,117,112,100,97,116,101,18,109, + 101,110,117,46,115,117,98,109,101,110,117,46,99,111,117,110,116,2,18,18, + 109,101,110,117,46,115,117,98,109,101,110,117,46,105,116,101,109,115,14,1, + 6,97,99,116,105,111,110,7,11,99,111,112,121,99,111,109,112,97,99,116, + 7,99,97,112,116,105,111,110,6,18,38,67,111,112,121,32,67,111,109,112, + 111,110,101,110,116,40,115,41,5,115,116,97,116,101,11,15,97,115,95,108, + 111,99,97,108,99,97,112,116,105,111,110,0,0,1,6,97,99,116,105,111, + 110,7,12,112,97,115,116,101,99,111,109,112,97,99,116,0,1,6,97,99, + 116,105,111,110,7,10,97,100,100,102,105,108,101,97,99,116,0,1,7,99, + 97,112,116,105,111,110,6,19,85,112,100,97,116,101,32,67,111,109,112,111, + 110,101,110,116,40,115,41,4,110,97,109,101,6,10,117,112,100,97,116,101, + 110,111,100,101,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120, + 101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7,17,100,111, + 117,112,100,97,116,101,99,111,109,112,111,110,101,110,116,0,1,7,99,97, + 112,116,105,111,110,6,19,82,101,109,111,118,101,32,67,111,109,112,111,110, + 101,110,116,40,115,41,4,110,97,109,101,6,10,114,101,109,111,118,101,99, + 111,109,112,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99, + 97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101, + 99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7,10,114,101,109, + 111,118,101,99,111,109,112,0,1,7,111,112,116,105,111,110,115,11,13,109, + 97,111,95,115,101,112,97,114,97,116,111,114,19,109,97,111,95,115,104,111, + 114,116,99,117,116,99,97,112,116,105,111,110,0,0,1,7,99,97,112,116, + 105,111,110,6,9,78,101,119,32,32,78,111,100,101,4,110,97,109,101,6, + 7,97,100,100,110,111,100,101,5,115,116,97,116,101,11,15,97,115,95,108, + 111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108, + 111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101, + 7,9,100,111,110,101,119,110,111,100,101,0,1,7,99,97,112,116,105,111, + 110,6,11,82,101,109,111,118,101,32,78,111,100,101,4,110,97,109,101,6, + 10,114,101,109,111,118,101,110,111,100,101,5,115,116,97,116,101,11,15,97, + 115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111, + 99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99, + 117,116,101,7,7,100,101,108,110,111,100,101,0,1,7,99,97,112,116,105, + 111,110,6,9,67,111,112,121,32,78,111,100,101,4,110,97,109,101,6,8, + 99,111,112,121,110,111,100,101,5,115,116,97,116,101,11,15,97,115,95,108, + 111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108, + 111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101, + 7,10,99,111,112,121,110,111,100,101,101,120,0,1,7,99,97,112,116,105, + 111,110,6,10,80,97,115,116,101,32,78,111,100,101,4,110,97,109,101,6, + 9,112,97,115,116,101,110,111,100,101,5,115,116,97,116,101,11,15,97,115, + 95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99, + 97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117, + 116,101,7,11,112,97,115,116,101,110,111,100,101,101,120,0,1,7,111,112, + 116,105,111,110,115,11,13,109,97,111,95,115,101,112,97,114,97,116,111,114, + 19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111,110, + 0,0,1,7,99,97,112,116,105,111,110,6,9,78,101,119,32,83,116,111, + 114,101,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97, + 112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99, + 117,116,101,0,9,111,110,101,120,101,99,117,116,101,7,10,110,101,119,115, + 116,111,114,101,101,120,0,1,7,99,97,112,116,105,111,110,6,9,65,100, + 100,32,83,116,111,114,101,5,115,116,97,116,101,11,15,97,115,95,108,111, + 99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111, + 110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7, + 10,97,100,100,115,116,111,114,101,101,120,0,1,7,99,97,112,116,105,111, + 110,6,12,82,101,109,111,118,101,32,83,116,111,114,101,4,110,97,109,101, + 6,11,114,101,109,111,118,101,115,116,111,114,101,5,115,116,97,116,101,11, + 15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95, + 108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120, + 101,99,117,116,101,7,13,114,101,109,111,118,101,115,116,111,114,101,101,120, + 0,1,7,111,112,116,105,111,110,115,11,13,109,97,111,95,115,101,112,97, + 114,97,116,111,114,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97, + 112,116,105,111,110,0,0,1,7,99,97,112,116,105,111,110,6,16,79,112, + 101,110,32,83,116,111,114,101,32,71,114,111,117,112,5,115,116,97,116,101, + 11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115, + 95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101, + 120,101,99,117,116,101,7,9,111,112,101,110,103,114,111,117,112,0,1,7, + 99,97,112,116,105,111,110,6,16,83,97,118,101,32,83,116,111,114,101,32, + 71,114,111,117,112,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101, + 120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7,9,115, + 97,118,101,103,114,111,117,112,0,1,7,99,97,112,116,105,111,110,6,19, + 83,97,118,101,32,83,116,111,114,101,32,71,114,111,117,112,32,97,115,5, + 115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105, + 111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101, + 0,9,111,110,101,120,101,99,117,116,101,7,11,115,97,118,101,103,114,111, + 117,112,97,115,0,0,4,108,101,102,116,2,40,3,116,111,112,2,88,0, + 0,9,116,115,116,97,116,102,105,108,101,9,115,116,111,114,101,102,105,108, + 101,8,102,105,108,101,110,97,109,101,6,9,115,116,111,114,101,46,115,116, + 97,10,111,110,115,116,97,116,114,101,97,100,7,11,115,116,97,116,114,101, + 97,100,101,120,101,11,111,110,115,116,97,116,119,114,105,116,101,7,12,115, + 116,97,116,119,114,105,116,101,101,120,101,4,108,101,102,116,3,40,1,3, + 116,111,112,2,88,0,0,11,116,102,105,108,101,100,105,97,108,111,103,15, + 115,116,111,114,101,102,105,108,101,100,105,97,108,111,103,8,115,116,97,116, + 102,105,108,101,7,22,109,97,105,110,102,111,46,112,114,111,106,101,99,116, + 115,116,97,116,102,105,108,101,26,99,111,110,116,114,111,108,108,101,114,46, + 102,105,108,116,101,114,108,105,115,116,46,100,97,116,97,1,1,6,16,67, + 111,109,112,111,110,101,110,116,32,83,116,111,114,101,115,6,5,42,46,115, + 116,111,0,0,21,99,111,110,116,114,111,108,108,101,114,46,100,101,102,97, + 117,108,116,101,120,116,6,3,115,116,111,18,99,111,110,116,114,111,108,108, + 101,114,46,111,112,116,105,111,110,115,11,14,102,100,111,95,99,104,101,99, + 107,101,120,105,115,116,15,102,100,111,95,115,97,118,101,108,97,115,116,100, + 105,114,0,22,99,111,110,116,114,111,108,108,101,114,46,99,97,112,116,105, + 111,110,111,112,101,110,6,20,76,111,97,100,32,67,111,109,112,111,110,101, + 110,116,32,83,116,111,114,101,22,99,111,110,116,114,111,108,108,101,114,46, + 99,97,112,116,105,111,110,115,97,118,101,6,19,78,101,119,32,67,111,109, + 112,111,110,101,110,116,32,83,116,111,114,101,4,108,101,102,116,2,40,3, + 116,111,112,3,136,0,0,0,11,116,102,105,108,101,100,105,97,108,111,103, + 15,103,114,111,117,112,102,105,108,101,100,105,97,108,111,103,8,115,116,97, + 116,102,105,108,101,7,22,109,97,105,110,102,111,46,112,114,111,106,101,99, + 116,115,116,97,116,102,105,108,101,26,99,111,110,116,114,111,108,108,101,114, + 46,102,105,108,116,101,114,108,105,115,116,46,100,97,116,97,1,1,6,12, + 83,116,111,114,101,32,71,114,111,117,112,115,6,5,42,46,115,116,103,0, + 0,21,99,111,110,116,114,111,108,108,101,114,46,100,101,102,97,117,108,116, + 101,120,116,6,3,115,116,103,22,99,111,110,116,114,111,108,108,101,114,46, + 99,97,112,116,105,111,110,111,112,101,110,6,16,79,112,101,110,32,83,116, + 111,114,101,32,71,114,111,117,112,22,99,111,110,116,114,111,108,108,101,114, + 46,99,97,112,116,105,111,110,115,97,118,101,6,16,83,97,118,101,32,83, + 116,111,114,101,32,71,114,111,117,112,4,108,101,102,116,2,40,3,116,111, + 112,3,168,0,0,0,7,116,97,99,116,105,111,110,10,97,100,100,102,105, + 108,101,97,99,116,7,99,97,112,116,105,111,110,6,17,65,100,100,32,67, + 111,109,112,111,110,101,110,116,102,105,108,101,9,111,110,101,120,101,99,117, + 116,101,7,9,100,111,97,100,100,102,105,108,101,8,111,110,117,112,100,97, + 116,101,7,9,112,97,115,116,101,117,112,100,97,4,108,101,102,116,3,176, + 0,3,116,111,112,2,112,0,0,11,116,102,105,108,101,100,105,97,108,111, + 103,14,99,111,109,112,102,105,108,101,100,105,97,108,111,103,8,115,116,97, + 116,102,105,108,101,7,22,109,97,105,110,102,111,46,112,114,111,106,101,99, + 116,115,116,97,116,102,105,108,101,26,99,111,110,116,114,111,108,108,101,114, + 46,102,105,108,116,101,114,108,105,115,116,46,100,97,116,97,1,1,6,14, + 67,111,109,112,111,110,101,110,116,32,70,105,108,101,6,5,42,46,99,109, + 112,0,1,6,9,65,108,108,32,70,105,108,101,115,6,1,42,0,0,21, + 99,111,110,116,114,111,108,108,101,114,46,100,101,102,97,117,108,116,101,120, + 116,6,3,99,109,112,18,99,111,110,116,114,111,108,108,101,114,46,111,112, + 116,105,111,110,115,11,14,102,100,111,95,99,104,101,99,107,101,120,105,115, + 116,15,102,100,111,95,115,97,118,101,108,97,115,116,100,105,114,0,22,99, + 111,110,116,114,111,108,108,101,114,46,99,97,112,116,105,111,110,111,112,101, + 110,6,21,83,101,108,101,99,116,32,67,111,109,112,111,110,101,110,116,32, + 70,105,108,101,4,108,101,102,116,2,40,3,116,111,112,3,200,0,0,0, + 16,116,115,116,114,105,110,103,99,111,110,116,97,105,110,101,114,1,99,12, + 115,116,114,105,110,103,115,46,100,97,116,97,1,6,15,67,111,109,112,111, + 110,101,110,116,32,83,116,111,114,101,6,21,67,111,109,112,111,110,101,110, + 116,32,114,101,97,100,32,101,114,114,111,114,46,6,26,68,111,32,121,111, + 117,32,119,97,110,116,32,116,111,32,111,118,101,114,119,114,105,116,101,32, + 34,6,33,34,32,119,105,116,104,32,99,117,114,114,101,110,116,32,99,108, + 105,112,98,111,97,114,100,32,99,111,110,116,101,110,116,63,6,7,87,65, + 82,78,73,78,71,6,29,78,111,32,99,111,109,112,111,110,101,110,116,40, + 115,41,32,105,110,32,99,108,105,112,98,111,97,114,100,46,6,35,69,114, + 114,111,114,32,119,104,105,108,101,32,119,114,105,116,105,110,103,32,116,104, + 101,32,115,116,111,114,101,103,114,111,117,112,46,6,5,69,82,82,79,82, + 6,23,68,111,32,121,111,117,32,119,97,110,116,32,116,111,32,114,101,109, + 111,118,101,32,34,6,2,34,63,6,9,34,32,98,114,97,110,99,104,63, + 6,6,70,105,108,101,32,34,6,43,34,32,100,111,101,115,32,110,111,116, + 32,101,120,105,115,116,44,32,100,111,32,121,111,117,32,119,97,110,116,32, + 116,111,32,99,114,101,97,116,101,32,105,116,63,6,26,83,97,118,101,32, + 67,111,109,112,111,110,101,110,116,32,83,116,111,114,101,32,71,114,111,117, + 112,0,4,108,101,102,116,3,40,1,3,116,111,112,3,144,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tcomponentstorefo,''); +end. diff --git a/mseide-msegui/apps/ide/compstore/dummy b/mseide-msegui/apps/ide/compstore/dummy new file mode 100644 index 0000000..b3eff39 --- /dev/null +++ b/mseide-msegui/apps/ide/compstore/dummy @@ -0,0 +1 @@ +git dummy file for empty directory. diff --git a/mseide-msegui/apps/ide/cpuarmform.mfm b/mseide-msegui/apps/ide/cpuarmform.mfm new file mode 100644 index 0000000..901b7d8 --- /dev/null +++ b/mseide-msegui/apps/ide/cpuarmform.mfm @@ -0,0 +1,997 @@ +inherited cpuarmfo: tcpuarmfo + bounds_x = 174 + bounds_y = 158 + bounds_cx = 264 + bounds_cy = 276 + container.bounds = ( + 0 + 0 + 254 + 276 + ) + caption = 'CPU ARM' + moduleclassname = 'tcpufo' + inherited on: tbooleanedit + bounds_x = 152 + bounds_y = 4 + end + inherited stoptime: tdatetimedisp + bounds_x = 0 + bounds_y = 0 + end + object tspacer1: tspacer[2] + taborder = 2 + visible = True + bounds_x = 0 + bounds_y = 20 + bounds_cx = 248 + bounds_cy = 238 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + linktop = stoptime + object tlayouter1: tlayouter + frame.localprops = [] + frame.localprops1 = [] + bounds_x = 0 + bounds_y = 40 + bounds_cx = 107 + bounds_cy = 198 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + optionslayout = [lao_placey] + place_maxdist = 0 + linkright = tlayouter2 + dist_right = 3 + object r1: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r1' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 13 + 0 + ) + bounds_x = 0 + bounds_y = 22 + bounds_cx = 106 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r0: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r0' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 14 + 0 + ) + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 107 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r4: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r4' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 14 + 0 + ) + taborder = 2 + bounds_x = 0 + bounds_y = 88 + bounds_cx = 107 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r3: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r3' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 14 + 0 + ) + taborder = 3 + bounds_x = 0 + bounds_y = 66 + bounds_cx = 107 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r2: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r2' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 14 + 0 + ) + taborder = 4 + bounds_x = 0 + bounds_y = 44 + bounds_cx = 107 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r5: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r5' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 14 + 0 + ) + taborder = 5 + bounds_x = 0 + bounds_y = 110 + bounds_cx = 107 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r6: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r6' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 14 + 0 + ) + taborder = 6 + bounds_x = 0 + bounds_y = 132 + bounds_cx = 107 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r7: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r7' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 14 + 0 + ) + taborder = 7 + bounds_x = 0 + bounds_y = 154 + bounds_cx = 107 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r8: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r8' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 14 + 0 + ) + taborder = 8 + bounds_x = 0 + bounds_y = 176 + bounds_cx = 107 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + end + object tbooleanedit16: tbooleanedit + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 1 + bounds_x = 237 + bounds_y = 25 + bounds_cx = 11 + bounds_cy = 11 + onsetvalue = flagssetvalue + end + object tbooleanedit17: tbooleanedit + Tag = 1 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'e' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 2 + bounds_x = 226 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit18: tbooleanedit + Tag = 2 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'd' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 3 + bounds_x = 215 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit19: tbooleanedit + Tag = 3 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'o' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 4 + bounds_x = 204 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit20: tbooleanedit + Tag = 4 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'M' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 1 + 0 + ) + taborder = 5 + bounds_x = 193 + bounds_y = 6 + bounds_cx = 12 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit15: tbooleanedit + Tag = 9 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'E' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 6 + bounds_x = 134 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit14: tbooleanedit + Tag = 6 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'F' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 7 + bounds_x = 167 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit13: tbooleanedit + Tag = 8 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'A' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 8 + bounds_x = 145 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit12: tbooleanedit + Tag = 5 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'T' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 9 + bounds_x = 178 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit11: tbooleanedit + Tag = 7 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'I' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 10 + bounds_x = 156 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit10: tbooleanedit + Tag = 19 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 11 + bounds_x = 86 + bounds_y = 25 + bounds_cx = 11 + bounds_cy = 11 + onsetvalue = flagssetvalue + end + object tbooleanedit9: tbooleanedit + Tag = 18 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'G' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 12 + bounds_x = 97 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit8: tbooleanedit + Tag = 17 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'E' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 13 + bounds_x = 108 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit7: tbooleanedit + Tag = 16 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 14 + bounds_x = 119 + bounds_y = 25 + bounds_cx = 11 + bounds_cy = 11 + onsetvalue = flagssetvalue + end + object tbooleanedit6: tbooleanedit + Tag = 24 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'J' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 15 + bounds_x = 68 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit5: tbooleanedit + Tag = 27 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'Q' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 16 + bounds_x = 50 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit4: tbooleanedit + Tag = 28 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'V' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 17 + bounds_x = 39 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit3: tbooleanedit + Tag = 29 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'C' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 18 + bounds_x = 28 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit2: tbooleanedit + Tag = 30 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'Z' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 19 + bounds_x = 17 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object c: tbooleanedit + Tag = 31 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'N' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 20 + bounds_x = 6 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tlayouter2: tlayouter + frame.localprops = [] + frame.localprops1 = [] + taborder = 21 + bounds_x = 110 + bounds_y = 40 + bounds_cx = 121 + bounds_cy = 198 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + optionslayout = [lao_placey] + place_maxdist = 0 + dist_bottom = 3 + object r11: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r11' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + bounds_x = 0 + bounds_y = 44 + bounds_cx = 112 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r10: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r10' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 20 + 0 + ) + taborder = 1 + bounds_x = 0 + bounds_y = 22 + bounds_cx = 113 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r9: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r9' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 14 + 0 + ) + taborder = 2 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 107 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object fps: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'fps' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 21 + 0 + ) + taborder = 3 + bounds_x = 0 + bounds_y = 154 + bounds_cx = 114 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object cpsr: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'cpsr' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 28 + 0 + ) + taborder = 4 + bounds_x = 0 + bounds_y = 176 + bounds_cx = 121 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onchange = flagonchange + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r12: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r12' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 20 + 0 + ) + taborder = 5 + bounds_x = 0 + bounds_y = 66 + bounds_cx = 113 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object sp: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'sp' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 17 + 0 + ) + taborder = 6 + bounds_x = 0 + bounds_y = 132 + bounds_cx = 110 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object lr: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'lr' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 10 + 0 + ) + taborder = 7 + bounds_x = 0 + bounds_y = 110 + bounds_cx = 103 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object pc: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'pc' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 17 + 0 + ) + taborder = 8 + bounds_x = 0 + bounds_y = 88 + bounds_cx = 110 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + end + end +end diff --git a/mseide-msegui/apps/ide/cpuarmform.pas b/mseide-msegui/apps/ide/cpuarmform.pas new file mode 100644 index 0000000..e56e22d --- /dev/null +++ b/mseide-msegui/apps/ide/cpuarmform.pas @@ -0,0 +1,133 @@ +{ MSEide Copyright (c) 1999-2013 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit cpuarmform; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,mseglob,mseguiglob,mseapplication,msestat,msemenus,msegui, + msegraphics, + msegraphutils,mseevent,mseclasses,mseforms,cpuform,msesplitter,msedataedits, + mseedit,msestrings,msetypes,msegraphedits,mseifiglob; + +type + tcpuarmfo = class(tcpufo) + tspacer1: tspacer; + tspacer2: tspacer; + tlayouter1: tlayouter; + r1: tintegeredit; + r0: tintegeredit; + r4: tintegeredit; + r3: tintegeredit; + r2: tintegeredit; + r5: tintegeredit; + tbooleanedit16: tbooleanedit; + tbooleanedit17: tbooleanedit; + tbooleanedit18: tbooleanedit; + tbooleanedit19: tbooleanedit; + tbooleanedit20: tbooleanedit; + tbooleanedit15: tbooleanedit; + tbooleanedit14: tbooleanedit; + tbooleanedit13: tbooleanedit; + tbooleanedit12: tbooleanedit; + tbooleanedit11: tbooleanedit; + tbooleanedit10: tbooleanedit; + tbooleanedit9: tbooleanedit; + tbooleanedit8: tbooleanedit; + tbooleanedit7: tbooleanedit; + tbooleanedit6: tbooleanedit; + tbooleanedit5: tbooleanedit; + tbooleanedit4: tbooleanedit; + tbooleanedit3: tbooleanedit; + tbooleanedit2: tbooleanedit; + c: tbooleanedit; + tlayouter2: tlayouter; + r11: tintegeredit; + r10: tintegeredit; + r9: tintegeredit; + fps: tintegeredit; + cpsr: tintegeredit; + r12: tintegeredit; + sp: tintegeredit; + r6: tintegeredit; + lr: tintegeredit; + pc: tintegeredit; + r7: tintegeredit; + r8: tintegeredit; + procedure regsetvalue(const sender: TObject; var avalue: Integer; + var accept: Boolean); + procedure flagssetvalue(const sender: TObject; var avalue: Boolean; + var accept: Boolean); + procedure flagonchange(const sender: TObject); + protected + procedure updateregisternames() override; + public + constructor create(aowner: tcomponent); override; + function flagedit(const aindex: integer): tcustombooleanedit; override; + end; + +implementation +uses + cpuarmform_mfm; + +{ tcpuarmfo } + +constructor tcpuarmfo.create(aowner: tcomponent); +begin + inherited create(aowner); + fflagswidget:= cpsr; +end; + +procedure tcpuarmfo.updateregisternames(); +var + comp1: tintegeredit; + i1: int32; +begin + comp1:= cpsr; + cpsr.name:= 'cpsr'; + for i1 := high(fregisternames) downto 0 do begin + if fregisternames[i1] = 'xpsr' then begin //for segger j-link + cpsr.name:= 'xpsr'; + break; + end; + end; + cpsr:= comp1; + cpsr.frame.caption:= msestring(cpsr.name); +end; + +procedure tcpuarmfo.regsetvalue(const sender: TObject; var avalue: Integer; + var accept: Boolean); +begin + doregsetvalue(sender,avalue,accept); +end; + +procedure tcpuarmfo.flagssetvalue(const sender: TObject; var avalue: Boolean; + var accept: Boolean); +begin + doflagsetvalue(sender,avalue,accept); +end; + +procedure tcpuarmfo.flagonchange(const sender: TObject); +begin + doflagonchange(sender); +end; + +function tcpuarmfo.flagedit(const aindex: integer): tcustombooleanedit; +begin + result:= c.tagitem(aindex); +end; + +end. diff --git a/mseide-msegui/apps/ide/cpuarmform_mfm.pas b/mseide-msegui/apps/ide/cpuarmform_mfm.pas new file mode 100644 index 0000000..0bf840e --- /dev/null +++ b/mseide-msegui/apps/ide/cpuarmform_mfm.pas @@ -0,0 +1,843 @@ +unit cpuarmform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,cpuarmform; + +const + objdata: record size: integer; data: array[0..16510] of byte end = + (size: 16511; data: ( + 84,80,70,48,241,9,116,99,112,117,97,114,109,102,111,8,99,112,117,97, + 114,109,102,111,8,98,111,117,110,100,115,95,120,3,174,0,8,98,111,117, + 110,100,115,95,121,3,158,0,9,98,111,117,110,100,115,95,99,120,3,8, + 1,9,98,111,117,110,100,115,95,99,121,3,20,1,16,99,111,110,116,97, + 105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0,3,254,0,3, + 20,1,0,7,99,97,112,116,105,111,110,6,7,67,80,85,32,65,82,77, + 15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,6,116,99, + 112,117,102,111,0,241,12,116,98,111,111,108,101,97,110,101,100,105,116,2, + 111,110,8,98,111,117,110,100,115,95,120,3,152,0,8,98,111,117,110,100, + 115,95,121,2,4,0,0,241,13,116,100,97,116,101,116,105,109,101,100,105, + 115,112,8,115,116,111,112,116,105,109,101,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,2,0,0,0,242,2,2,7,116, + 115,112,97,99,101,114,8,116,115,112,97,99,101,114,49,8,116,97,98,111, + 114,100,101,114,2,2,7,118,105,115,105,98,108,101,9,8,98,111,117,110, + 100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,20,9,98,111, + 117,110,100,115,95,99,120,3,248,0,9,98,111,117,110,100,115,95,99,121, + 3,238,0,12,111,112,116,105,111,110,115,115,99,97,108,101,11,11,111,115, + 99,95,101,120,112,97,110,100,120,11,111,115,99,95,115,104,114,105,110,107, + 120,11,111,115,99,95,101,120,112,97,110,100,121,11,111,115,99,95,115,104, + 114,105,110,107,121,0,7,108,105,110,107,116,111,112,7,8,115,116,111,112, + 116,105,109,101,0,9,116,108,97,121,111,117,116,101,114,10,116,108,97,121, + 111,117,116,101,114,49,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,2,40,9,98,111,117,110,100,115,95,99,120,2,107,9, + 98,111,117,110,100,115,95,99,121,3,198,0,12,111,112,116,105,111,110,115, + 115,99,97,108,101,11,11,111,115,99,95,101,120,112,97,110,100,120,11,111, + 115,99,95,115,104,114,105,110,107,120,11,111,115,99,95,101,120,112,97,110, + 100,121,11,111,115,99,95,115,104,114,105,110,107,121,0,13,111,112,116,105, + 111,110,115,108,97,121,111,117,116,11,10,108,97,111,95,112,108,97,99,101, + 121,0,13,112,108,97,99,101,95,109,97,120,100,105,115,116,2,0,9,108, + 105,110,107,114,105,103,104,116,7,10,116,108,97,121,111,117,116,101,114,50, + 10,100,105,115,116,95,114,105,103,104,116,2,3,0,12,116,105,110,116,101, + 103,101,114,101,100,105,116,2,114,49,13,111,112,116,105,111,110,115,119,105, + 100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11, + 111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119, + 102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105, + 110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111, + 119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114, + 97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99, + 111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,2,114,49,22,102,114,97,109,101,46, + 99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,12,116,102, + 95,121,99,101,110,116,101,114,101,100,0,16,102,114,97,109,101,46,99,97, + 112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108, + 95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105, + 101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109, + 101,1,2,0,2,0,2,13,2,0,0,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,2,22,9,98,111,117,110,100,115, + 95,99,120,2,106,9,98,111,117,110,100,115,95,99,121,2,22,11,102,111, + 110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109, + 101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115, + 99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101, + 116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4, + 98,97,115,101,7,6,110,98,95,104,101,120,8,118,97,108,117,101,109,97, + 120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,18,0, + 0,12,116,105,110,116,101,103,101,114,101,100,105,116,2,114,48,13,111,112, + 116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115, + 101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111, + 119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99, + 117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17, + 102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0, + 0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,2,114,48, + 22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108, + 97,103,115,11,12,116,102,95,121,99,101,110,116,101,114,101,100,0,16,102, + 114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95, + 114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99, + 111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117, + 116,101,114,102,114,97,109,101,1,2,0,2,0,2,14,2,0,0,8,116, + 97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,2,107,9,98,111,117,110,100,115,95,99,121,2,22,11,102,111,110,116, + 46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6, + 9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97, + 108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118, + 97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97, + 115,101,7,6,110,98,95,104,101,120,8,118,97,108,117,101,109,97,120,2, + 255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,18,0,0,12, + 116,105,110,116,101,103,101,114,101,100,105,116,2,114,52,13,111,112,116,105, + 111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102, + 111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95, + 97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102, + 111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115, + 111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116, + 115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,2,114,52,22,102, + 114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103, + 115,11,12,116,102,95,121,99,101,110,116,101,114,101,100,0,16,102,114,97, + 109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105, + 103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108, + 111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101, + 114,102,114,97,109,101,1,2,0,2,0,2,14,2,0,0,8,116,97,98, + 111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,2,0,8,98, + 111,117,110,100,115,95,121,2,88,9,98,111,117,110,100,115,95,99,120,2, + 107,9,98,111,117,110,100,115,95,99,121,2,22,11,102,111,110,116,46,104, + 101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115, + 116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101, + 2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108, + 117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101, + 7,6,110,98,95,104,101,120,8,118,97,108,117,101,109,97,120,2,255,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,18,0,0,12,116,105, + 110,116,101,103,101,114,101,100,105,116,2,114,51,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109, + 101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,2,114,51,22,102,114,97, + 109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11, + 12,116,102,95,121,99,101,110,116,101,114,101,100,0,16,102,114,97,109,101, + 46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104, + 116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,0,2,14,2,0,0,8,116,97,98,111,114, + 100,101,114,2,3,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,2,66,9,98,111,117,110,100,115,95,99,120,2,107,9, + 98,111,117,110,100,115,95,99,121,2,22,11,102,111,110,116,46,104,101,105, + 103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102, + 95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1, + 15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108, + 112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101, + 7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6, + 110,98,95,104,101,120,8,118,97,108,117,101,109,97,120,2,255,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,18,0,0,12,116,105,110,116, + 101,103,101,114,101,100,105,116,2,114,50,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115, + 105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,2,114,50,22,102,114,97,109,101, + 46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,12,116, + 102,95,121,99,101,110,116,101,114,101,100,0,16,102,114,97,109,101,46,99, + 97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,0,2,14,2,0,0,8,116,97,98,111,114,100,101, + 114,2,4,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100, + 115,95,121,2,44,9,98,111,117,110,100,115,95,99,120,2,107,9,98,111, + 117,110,100,115,95,99,121,2,22,11,102,111,110,116,46,104,101,105,103,104, + 116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102, + 105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102, + 111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95, + 120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11, + 114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98, + 95,104,101,120,8,118,97,108,117,101,109,97,120,2,255,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,18,0,0,12,116,105,110,116,101,103, + 101,114,101,100,105,116,2,114,53,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111, + 119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102, + 111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110, + 16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119, + 95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97, + 109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111, + 108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,2,114,53,22,102,114,97,109,101,46,99, + 97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,12,116,102,95, + 121,99,101,110,116,101,114,101,100,0,16,102,114,97,109,101,46,99,97,112, + 116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95, + 108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101, + 110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101, + 1,2,0,2,0,2,14,2,0,0,8,116,97,98,111,114,100,101,114,2, + 5,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95, + 121,2,110,9,98,111,117,110,100,115,95,99,120,2,107,9,98,111,117,110, + 100,115,95,99,121,2,22,11,102,111,110,116,46,104,101,105,103,104,116,2, + 14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120, + 101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110, + 116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115, + 99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101, + 103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104, + 101,120,8,118,97,108,117,101,109,97,120,2,255,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,18,0,0,12,116,105,110,116,101,103,101,114, + 101,100,105,116,2,114,54,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95, + 116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111, + 119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100, + 101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101, + 46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111, + 114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99, + 97,112,116,105,111,110,6,2,114,54,22,102,114,97,109,101,46,99,97,112, + 116,105,111,110,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99, + 101,110,116,101,114,101,100,0,16,102,114,97,109,101,46,99,97,112,116,105, + 111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101, + 118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2, + 0,2,0,2,14,2,0,0,8,116,97,98,111,114,100,101,114,2,6,8, + 98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,3, + 132,0,9,98,111,117,110,100,115,95,99,120,2,107,9,98,111,117,110,100, + 115,95,99,121,2,22,11,102,111,110,116,46,104,101,105,103,104,116,2,14, + 9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101, + 100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99, + 97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103, + 115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101, + 120,8,118,97,108,117,101,109,97,120,2,255,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,18,0,0,12,116,105,110,116,101,103,101,114,101, + 100,105,116,2,114,55,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119, + 95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46, + 108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114, + 99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,2,114,55,22,102,114,97,109,101,46,99,97,112,116, + 105,111,110,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101, + 110,116,101,114,101,100,0,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,0,2,14,2,0,0,8,116,97,98,111,114,100,101,114,2,7,8,98, + 111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,3,154, + 0,9,98,111,117,110,100,115,95,99,120,2,107,9,98,111,117,110,100,115, + 95,99,121,2,22,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9, + 102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100, + 11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46, + 108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97, + 108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115, + 101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120, + 8,118,97,108,117,101,109,97,120,2,255,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,18,0,0,12,116,105,110,116,101,103,101,114,101,100, + 105,116,2,114,56,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,2,114,56,22,102,114,97,109,101,46,99,97,112,116,105, + 111,110,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101,110, + 116,101,114,101,100,0,16,102,114,97,109,101,46,99,97,112,116,105,111,110, + 112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101, + 108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2, + 0,2,14,2,0,0,8,116,97,98,111,114,100,101,114,2,8,8,98,111, + 117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,3,176,0, + 9,98,111,117,110,100,115,95,99,120,2,107,9,98,111,117,110,100,115,95, + 99,121,2,22,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102, + 111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11, + 102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108, + 101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101, + 116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8, + 118,97,108,117,101,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,18,0,0,0,12,116,98,111,111,108,101,97,110,101,100, + 105,116,14,116,98,111,111,108,101,97,110,101,100,105,116,49,54,5,99,111, + 108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108, + 111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110, + 116,4,7,0,0,144,16,102,114,97,109,101,46,99,97,112,116,105,111,110, + 112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111, + 15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97, + 98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,3,237,0, + 8,98,111,117,110,100,115,95,121,2,25,9,98,111,117,110,100,115,95,99, + 120,2,11,9,98,111,117,110,100,115,95,99,121,2,11,10,111,110,115,101, + 116,118,97,108,117,101,7,13,102,108,97,103,115,115,101,116,118,97,108,117, + 101,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,14,116,98,111, + 111,108,101,97,110,101,100,105,116,49,55,3,84,97,103,2,1,5,99,111, + 108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108, + 111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110, + 116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,1,101,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115, + 7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114, + 108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101, + 46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,19,2,0,2,0, + 0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95, + 120,3,226,0,8,98,111,117,110,100,115,95,121,2,6,9,98,111,117,110, + 100,115,95,99,120,2,11,9,98,111,117,110,100,115,95,99,121,2,30,10, + 111,110,115,101,116,118,97,108,117,101,7,13,102,108,97,103,115,115,101,116, + 118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116, + 14,116,98,111,111,108,101,97,110,101,100,105,116,49,56,3,84,97,103,2, + 2,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,1,100,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,19, + 2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117, + 110,100,115,95,120,3,215,0,8,98,111,117,110,100,115,95,121,2,6,9, + 98,111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95,99, + 121,2,30,10,111,110,115,101,116,118,97,108,117,101,7,13,102,108,97,103, + 115,115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110, + 101,100,105,116,14,116,98,111,111,108,101,97,110,101,100,105,116,49,57,3, + 84,97,103,2,3,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97, + 109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111, + 108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,1,111,16,102,114,97,109,101,46,99,97, + 112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,19,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,4, + 8,98,111,117,110,100,115,95,120,3,204,0,8,98,111,117,110,100,115,95, + 121,2,6,9,98,111,117,110,100,115,95,99,120,2,11,9,98,111,117,110, + 100,115,95,99,121,2,30,10,111,110,115,101,116,118,97,108,117,101,7,13, + 102,108,97,103,115,115,101,116,118,97,108,117,101,0,0,12,116,98,111,111, + 108,101,97,110,101,100,105,116,14,116,98,111,111,108,101,97,110,101,100,105, + 116,50,48,3,84,97,103,2,4,5,99,111,108,111,114,4,3,0,0,128, + 12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109, + 101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,1,77,16,102,114,97,109, + 101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,19,2,1,2,0,0,8,116,97,98,111,114,100, + 101,114,2,5,8,98,111,117,110,100,115,95,120,3,193,0,8,98,111,117, + 110,100,115,95,121,2,6,9,98,111,117,110,100,115,95,99,120,2,12,9, + 98,111,117,110,100,115,95,99,121,2,30,10,111,110,115,101,116,118,97,108, + 117,101,7,13,102,108,97,103,115,115,101,116,118,97,108,117,101,0,0,12, + 116,98,111,111,108,101,97,110,101,100,105,116,14,116,98,111,111,108,101,97, + 110,101,100,105,116,49,53,3,84,97,103,2,9,5,99,111,108,111,114,4, + 3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17, + 102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0, + 0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1,69,16, + 102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112, + 95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111, + 108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,19,2,0,2,0,0,8,116,97, + 98,111,114,100,101,114,2,6,8,98,111,117,110,100,115,95,120,3,134,0, + 8,98,111,117,110,100,115,95,121,2,6,9,98,111,117,110,100,115,95,99, + 120,2,11,9,98,111,117,110,100,115,95,99,121,2,30,10,111,110,115,101, + 116,118,97,108,117,101,7,13,102,108,97,103,115,115,101,116,118,97,108,117, + 101,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,14,116,98,111, + 111,108,101,97,110,101,100,105,116,49,52,3,84,97,103,2,6,5,99,111, + 108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108, + 111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110, + 116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,1,70,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115, + 7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114, + 108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101, + 46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,19,2,0,2,0, + 0,8,116,97,98,111,114,100,101,114,2,7,8,98,111,117,110,100,115,95, + 120,3,167,0,8,98,111,117,110,100,115,95,121,2,6,9,98,111,117,110, + 100,115,95,99,120,2,11,9,98,111,117,110,100,115,95,99,121,2,30,10, + 111,110,115,101,116,118,97,108,117,101,7,13,102,108,97,103,115,115,101,116, + 118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116, + 14,116,98,111,111,108,101,97,110,101,100,105,116,49,51,3,84,97,103,2, + 8,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,1,65,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,19, + 2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,8,8,98,111,117, + 110,100,115,95,120,3,145,0,8,98,111,117,110,100,115,95,121,2,6,9, + 98,111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95,99, + 121,2,30,10,111,110,115,101,116,118,97,108,117,101,7,13,102,108,97,103, + 115,115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110, + 101,100,105,116,14,116,98,111,111,108,101,97,110,101,100,105,116,49,50,3, + 84,97,103,2,5,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97, + 109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111, + 108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,1,84,16,102,114,97,109,101,46,99,97, + 112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,19,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,9, + 8,98,111,117,110,100,115,95,120,3,178,0,8,98,111,117,110,100,115,95, + 121,2,6,9,98,111,117,110,100,115,95,99,120,2,11,9,98,111,117,110, + 100,115,95,99,121,2,30,10,111,110,115,101,116,118,97,108,117,101,7,13, + 102,108,97,103,115,115,101,116,118,97,108,117,101,0,0,12,116,98,111,111, + 108,101,97,110,101,100,105,116,14,116,98,111,111,108,101,97,110,101,100,105, + 116,49,49,3,84,97,103,2,7,5,99,111,108,111,114,4,3,0,0,128, + 12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109, + 101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,1,73,16,102,114,97,109, + 101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,19,2,0,2,0,0,8,116,97,98,111,114,100, + 101,114,2,10,8,98,111,117,110,100,115,95,120,3,156,0,8,98,111,117, + 110,100,115,95,121,2,6,9,98,111,117,110,100,115,95,99,120,2,11,9, + 98,111,117,110,100,115,95,99,121,2,30,10,111,110,115,101,116,118,97,108, + 117,101,7,13,102,108,97,103,115,115,101,116,118,97,108,117,101,0,0,12, + 116,98,111,111,108,101,97,110,101,100,105,116,14,116,98,111,111,108,101,97, + 110,101,100,105,116,49,48,3,84,97,103,2,19,5,99,111,108,111,114,4, + 3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17, + 102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0, + 0,144,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7, + 6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108, + 95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100, + 101,114,2,11,8,98,111,117,110,100,115,95,120,2,86,8,98,111,117,110, + 100,115,95,121,2,25,9,98,111,117,110,100,115,95,99,120,2,11,9,98, + 111,117,110,100,115,95,99,121,2,11,10,111,110,115,101,116,118,97,108,117, + 101,7,13,102,108,97,103,115,115,101,116,118,97,108,117,101,0,0,12,116, + 98,111,111,108,101,97,110,101,100,105,116,13,116,98,111,111,108,101,97,110, + 101,100,105,116,57,3,84,97,103,2,18,5,99,111,108,111,114,4,3,0, + 0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1,71,16,102,114, + 97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116, + 111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111, + 114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,19,2,0,2,0,0,8,116,97,98,111, + 114,100,101,114,2,12,8,98,111,117,110,100,115,95,120,2,97,8,98,111, + 117,110,100,115,95,121,2,6,9,98,111,117,110,100,115,95,99,120,2,11, + 9,98,111,117,110,100,115,95,99,121,2,30,10,111,110,115,101,116,118,97, + 108,117,101,7,13,102,108,97,103,115,115,101,116,118,97,108,117,101,0,0, + 12,116,98,111,111,108,101,97,110,101,100,105,116,13,116,98,111,111,108,101, + 97,110,101,100,105,116,56,3,84,97,103,2,17,5,99,111,108,111,114,4, + 3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17, + 102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0, + 0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1,69,16, + 102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112, + 95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111, + 108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,19,2,0,2,0,0,8,116,97, + 98,111,114,100,101,114,2,13,8,98,111,117,110,100,115,95,120,2,108,8, + 98,111,117,110,100,115,95,121,2,6,9,98,111,117,110,100,115,95,99,120, + 2,11,9,98,111,117,110,100,115,95,99,121,2,30,10,111,110,115,101,116, + 118,97,108,117,101,7,13,102,108,97,103,115,115,101,116,118,97,108,117,101, + 0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,13,116,98,111,111, + 108,101,97,110,101,100,105,116,55,3,84,97,103,2,16,5,99,111,108,111, + 114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 7,0,0,144,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111, + 115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102, + 114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111, + 114,100,101,114,2,14,8,98,111,117,110,100,115,95,120,2,119,8,98,111, + 117,110,100,115,95,121,2,25,9,98,111,117,110,100,115,95,99,120,2,11, + 9,98,111,117,110,100,115,95,99,121,2,11,10,111,110,115,101,116,118,97, + 108,117,101,7,13,102,108,97,103,115,115,101,116,118,97,108,117,101,0,0, + 12,116,98,111,111,108,101,97,110,101,100,105,116,13,116,98,111,111,108,101, + 97,110,101,100,105,116,54,3,84,97,103,2,24,5,99,111,108,111,114,4, + 3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17, + 102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0, + 0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1,74,16, + 102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112, + 95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111, + 108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,19,2,0,2,0,0,8,116,97, + 98,111,114,100,101,114,2,15,8,98,111,117,110,100,115,95,120,2,68,8, + 98,111,117,110,100,115,95,121,2,6,9,98,111,117,110,100,115,95,99,120, + 2,11,9,98,111,117,110,100,115,95,99,121,2,30,10,111,110,115,101,116, + 118,97,108,117,101,7,13,102,108,97,103,115,115,101,116,118,97,108,117,101, + 0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,13,116,98,111,111, + 108,101,97,110,101,100,105,116,53,3,84,97,103,2,27,5,99,111,108,111, + 114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1, + 81,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6, + 99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95, + 99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,19,2,0,2,0,0,8, + 116,97,98,111,114,100,101,114,2,16,8,98,111,117,110,100,115,95,120,2, + 50,8,98,111,117,110,100,115,95,121,2,6,9,98,111,117,110,100,115,95, + 99,120,2,11,9,98,111,117,110,100,115,95,99,121,2,30,10,111,110,115, + 101,116,118,97,108,117,101,7,13,102,108,97,103,115,115,101,116,118,97,108, + 117,101,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,13,116,98, + 111,111,108,101,97,110,101,100,105,116,52,3,84,97,103,2,28,5,99,111, + 108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108, + 111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110, + 116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,1,86,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115, + 7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114, + 108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101, + 46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,19,2,0,2,0, + 0,8,116,97,98,111,114,100,101,114,2,17,8,98,111,117,110,100,115,95, + 120,2,39,8,98,111,117,110,100,115,95,121,2,6,9,98,111,117,110,100, + 115,95,99,120,2,11,9,98,111,117,110,100,115,95,99,121,2,30,10,111, + 110,115,101,116,118,97,108,117,101,7,13,102,108,97,103,115,115,101,116,118, + 97,108,117,101,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,13, + 116,98,111,111,108,101,97,110,101,100,105,116,51,3,84,97,103,2,29,5, + 99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,1,67,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112, + 111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,19,2,0, + 2,0,0,8,116,97,98,111,114,100,101,114,2,18,8,98,111,117,110,100, + 115,95,120,2,28,8,98,111,117,110,100,115,95,121,2,6,9,98,111,117, + 110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95,99,121,2,30, + 10,111,110,115,101,116,118,97,108,117,101,7,13,102,108,97,103,115,115,101, + 116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110,101,100,105, + 116,13,116,98,111,111,108,101,97,110,101,100,105,116,50,3,84,97,103,2, + 30,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,1,90,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,19, + 2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,19,8,98,111,117, + 110,100,115,95,120,2,17,8,98,111,117,110,100,115,95,121,2,6,9,98, + 111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95,99,121, + 2,30,10,111,110,115,101,116,118,97,108,117,101,7,13,102,108,97,103,115, + 115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110,101, + 100,105,116,1,99,3,84,97,103,2,31,5,99,111,108,111,114,4,3,0, + 0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1,78,16,102,114, + 97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116, + 111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111, + 114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,19,2,0,2,0,0,8,116,97,98,111, + 114,100,101,114,2,20,8,98,111,117,110,100,115,95,120,2,6,8,98,111, + 117,110,100,115,95,121,2,6,9,98,111,117,110,100,115,95,99,120,2,11, + 9,98,111,117,110,100,115,95,99,121,2,30,10,111,110,115,101,116,118,97, + 108,117,101,7,13,102,108,97,103,115,115,101,116,118,97,108,117,101,0,0, + 9,116,108,97,121,111,117,116,101,114,10,116,108,97,121,111,117,116,101,114, + 50,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 8,116,97,98,111,114,100,101,114,2,21,8,98,111,117,110,100,115,95,120, + 2,110,8,98,111,117,110,100,115,95,121,2,40,9,98,111,117,110,100,115, + 95,99,120,2,121,9,98,111,117,110,100,115,95,99,121,3,198,0,12,111, + 112,116,105,111,110,115,115,99,97,108,101,11,11,111,115,99,95,101,120,112, + 97,110,100,120,11,111,115,99,95,115,104,114,105,110,107,120,11,111,115,99, + 95,101,120,112,97,110,100,121,11,111,115,99,95,115,104,114,105,110,107,121, + 0,13,111,112,116,105,111,110,115,108,97,121,111,117,116,11,10,108,97,111, + 95,112,108,97,99,101,121,0,13,112,108,97,99,101,95,109,97,120,100,105, + 115,116,2,0,11,100,105,115,116,95,98,111,116,116,111,109,2,3,0,12, + 116,105,110,116,101,103,101,114,101,100,105,116,3,114,49,49,13,111,112,116, + 105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101, + 102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119, + 95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119, + 102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117, + 115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102, + 114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0, + 144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,3,114,49,49, + 22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108, + 97,103,115,11,12,116,102,95,121,99,101,110,116,101,114,101,100,0,16,102, + 114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95, + 114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99, + 111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117, + 116,101,114,102,114,97,109,101,1,2,0,2,0,2,19,2,0,0,8,98, + 111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,44, + 9,98,111,117,110,100,115,95,99,120,2,112,9,98,111,117,110,100,115,95, + 99,121,2,22,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102, + 111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11, + 102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108, + 101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101, + 116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8, + 118,97,108,117,101,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,18,0,0,12,116,105,110,116,101,103,101,114,101,100,105, + 116,3,114,49,48,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,3,114,49,48,22,102,114,97,109,101,46,99,97,112,116, + 105,111,110,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101, + 110,116,101,114,101,100,0,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,0,2,20,2,0,0,8,116,97,98,111,114,100,101,114,2,1,8,98, + 111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,22, + 9,98,111,117,110,100,115,95,99,120,2,113,9,98,111,117,110,100,115,95, + 99,121,2,22,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102, + 111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11, + 102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108, + 101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101, + 116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8, + 118,97,108,117,101,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,18,0,0,12,116,105,110,116,101,103,101,114,101,100,105, + 116,2,114,57,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13, + 111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98, + 102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15, + 111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97, + 114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116, + 114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101, + 118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108, + 105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116, + 105,111,110,6,2,114,57,22,102,114,97,109,101,46,99,97,112,116,105,111, + 110,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101,110,116, + 101,114,101,100,0,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112, + 111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0, + 2,14,2,0,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117, + 110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,120,2,107,9,98,111,117,110,100,115,95,99,121, + 2,22,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110, + 116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111, + 110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0, + 10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118, + 97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,118,97, + 108,117,101,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,18,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,3, + 102,112,115,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,3,102,112,115,22,102,114,97,109,101,46,99,97,112,116,105,111, + 110,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101,110,116, + 101,114,101,100,0,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112, + 111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0, + 2,21,2,0,0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117, + 110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,3,154,0,9, + 98,111,117,110,100,115,95,99,120,2,114,9,98,111,117,110,100,115,95,99, + 121,2,22,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111, + 110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102, + 111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101, + 0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116, + 118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,118, + 97,108,117,101,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,18,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116, + 4,99,112,115,114,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,4,99,112,115,114,22,102,114,97,109,101,46,99,97,112, + 116,105,111,110,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99, + 101,110,116,101,114,101,100,0,16,102,114,97,109,101,46,99,97,112,116,105, + 111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101, + 118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2, + 0,2,0,2,28,2,0,0,8,116,97,98,111,114,100,101,114,2,4,8, + 98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,3, + 176,0,9,98,111,117,110,100,115,95,99,120,2,121,9,98,111,117,110,100, + 115,95,99,121,2,22,11,102,111,110,116,46,104,101,105,103,104,116,2,14, + 9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101, + 100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99, + 97,108,101,0,8,111,110,99,104,97,110,103,101,7,12,102,108,97,103,111, + 110,99,104,97,110,103,101,10,111,110,115,101,116,118,97,108,117,101,7,11, + 114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98, + 95,104,101,120,8,118,97,108,117,101,109,97,120,2,255,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,18,0,0,12,116,105,110,116,101,103, + 101,114,101,100,105,116,3,114,49,50,13,111,112,116,105,111,110,115,119,105, + 100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11, + 111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119, + 102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105, + 110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111, + 119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114, + 97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99, + 111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,3,114,49,50,22,102,114,97,109,101, + 46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,12,116, + 102,95,121,99,101,110,116,101,114,101,100,0,16,102,114,97,109,101,46,99, + 97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,0,2,20,2,0,0,8,116,97,98,111,114,100,101, + 114,2,5,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100, + 115,95,121,2,66,9,98,111,117,110,100,115,95,99,120,2,113,9,98,111, + 117,110,100,115,95,99,121,2,22,11,102,111,110,116,46,104,101,105,103,104, + 116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102, + 105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102, + 111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95, + 120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11, + 114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98, + 95,104,101,120,8,118,97,108,117,101,109,97,120,2,255,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,18,0,0,12,116,105,110,116,101,103, + 101,114,101,100,105,116,2,115,112,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111, + 119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102, + 111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110, + 16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119, + 95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97, + 109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111, + 108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,2,115,112,22,102,114,97,109,101,46,99, + 97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,12,116,102,95, + 121,99,101,110,116,101,114,101,100,0,16,102,114,97,109,101,46,99,97,112, + 116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95, + 108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101, + 110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101, + 1,2,0,2,0,2,17,2,0,0,8,116,97,98,111,114,100,101,114,2, + 6,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95, + 121,3,132,0,9,98,111,117,110,100,115,95,99,120,2,110,9,98,111,117, + 110,100,115,95,99,121,2,22,11,102,111,110,116,46,104,101,105,103,104,116, + 2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105, + 120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111, + 110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120, + 115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114, + 101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95, + 104,101,120,8,118,97,108,117,101,109,97,120,2,255,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,18,0,0,12,116,105,110,116,101,103,101, + 114,101,100,105,116,2,108,114,13,111,112,116,105,111,110,115,119,105,100,103, + 101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119, + 95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111, + 99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16, + 111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109, + 101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108, + 111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,2,108,114,22,102,114,97,109,101,46,99,97, + 112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121, + 99,101,110,116,101,114,101,100,0,16,102,114,97,109,101,46,99,97,112,116, + 105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,0,2,10,2,0,0,8,116,97,98,111,114,100,101,114,2,7, + 8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121, + 2,110,9,98,111,117,110,100,115,95,99,120,2,103,9,98,111,117,110,100, + 115,95,99,121,2,22,11,102,111,110,116,46,104,101,105,103,104,116,2,14, + 9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101, + 100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99, + 97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103, + 115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101, + 120,8,118,97,108,117,101,109,97,120,2,255,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,18,0,0,12,116,105,110,116,101,103,101,114,101, + 100,105,116,2,112,99,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119, + 95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46, + 108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114, + 99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,2,112,99,22,102,114,97,109,101,46,99,97,112,116, + 105,111,110,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101, + 110,116,101,114,101,100,0,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,0,2,17,2,0,0,8,116,97,98,111,114,100,101,114,2,8,8,98, + 111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,88, + 9,98,111,117,110,100,115,95,99,120,2,110,9,98,111,117,110,100,115,95, + 99,121,2,22,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102, + 111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11, + 102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108, + 101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101, + 116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8, + 118,97,108,117,101,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,18,0,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tcpuarmfo,''); +end. diff --git a/mseide-msegui/apps/ide/cpuarmm3form.mfm b/mseide-msegui/apps/ide/cpuarmm3form.mfm new file mode 100644 index 0000000..bd23253 --- /dev/null +++ b/mseide-msegui/apps/ide/cpuarmm3form.mfm @@ -0,0 +1,285 @@ +inherited cpuarmm3fo: tcpuarmm3fo + bounds_x = 57 + bounds_y = 234 + bounds_cx = 272 + bounds_cy = 266 + container.bounds = ( + 0 + 0 + 262 + 266 + ) + caption = 'CPU ARM M3' + moduleclassname = 'tcpuarmfo' + inherited on: tbooleanedit + end + inherited stoptime: tdatetimedisp + end + inherited tspacer1: tspacer + bounds_cx = 251 + inherited tlayouter1: tlayouter + inherited r1: tintegeredit + end + inherited r0: tintegeredit + end + inherited r4: tintegeredit + end + inherited r3: tintegeredit + end + inherited r2: tintegeredit + end + inherited r5: tintegeredit + end + inherited r6: tintegeredit + end + inherited r7: tintegeredit + end + inherited r8: tintegeredit + end + end + inherited tbooleanedit16: tbooleanedit + frame.caption = 'ISR_NUMBER' + frame.captionpos = cp_topright + frame.outerframe = ( + 63 + 19 + 0 + 0 + ) + bounds_x = 177 + bounds_y = 6 + bounds_cx = 74 + bounds_cy = 30 + end + inherited tbooleanedit17: tbooleanedit + frame.caption = '' + frame.outerframe = ( + 0 + 0 + 0 + 0 + ) + bounds_x = 229 + bounds_y = 25 + bounds_cy = 11 + end + inherited tbooleanedit18: tbooleanedit + frame.caption = '' + frame.outerframe = ( + 0 + 0 + 0 + 0 + ) + bounds_x = 218 + bounds_y = 25 + bounds_cy = 11 + end + inherited tbooleanedit19: tbooleanedit + frame.caption = '' + frame.outerframe = ( + 0 + 0 + 0 + 0 + ) + bounds_x = 207 + bounds_y = 25 + bounds_cy = 11 + end + inherited tbooleanedit20: tbooleanedit + frame.caption = '' + frame.outerframe = ( + 0 + 0 + 0 + 0 + ) + bounds_x = 195 + bounds_y = 25 + bounds_cy = 11 + end + inherited tbooleanedit15: tbooleanedit + Tag = 13 + frame.caption = '' + frame.outerframe = ( + 0 + 0 + 0 + 0 + ) + bounds_x = 104 + bounds_y = 25 + bounds_cy = 11 + end + inherited tbooleanedit14: tbooleanedit + Tag = 10 + frame.caption = 'ICI/IT' + frame.captionpos = cp_topright + frame.outerframe = ( + 22 + 19 + 0 + 0 + ) + bounds_x = 115 + bounds_cx = 33 + end + inherited tbooleanedit13: tbooleanedit + Tag = 12 + frame.caption = '' + frame.outerframe = ( + 0 + 0 + 0 + 0 + ) + bounds_x = 115 + bounds_y = 25 + bounds_cy = 11 + end + inherited tbooleanedit12: tbooleanedit + frame.caption = '' + frame.outerframe = ( + 0 + 0 + 0 + 0 + ) + bounds_x = 184 + bounds_y = 25 + bounds_cy = 11 + end + inherited tbooleanedit11: tbooleanedit + Tag = 11 + frame.caption = '' + frame.outerframe = ( + 0 + 0 + 0 + 0 + ) + bounds_x = 126 + bounds_y = 25 + bounds_cy = 11 + end + inherited tbooleanedit10: tbooleanedit + Tag = 26 + frame.captionpos = cp_topleft + bounds_x = 60 + end + inherited tbooleanedit9: tbooleanedit + Tag = 25 + frame.caption = '' + frame.outerframe = ( + 0 + 0 + 0 + 0 + ) + bounds_x = 71 + bounds_y = 25 + bounds_cy = 11 + end + inherited tbooleanedit8: tbooleanedit + Tag = 15 + frame.caption = '' + frame.outerframe = ( + 0 + 0 + 0 + 0 + ) + bounds_x = 82 + bounds_y = 25 + bounds_cy = 11 + end + inherited tbooleanedit7: tbooleanedit + Tag = 14 + bounds_x = 93 + end + inherited tbooleanedit6: tbooleanedit + frame.caption = 'T' + bounds_x = 77 + bounds_y = 0 + visible = False + end + inherited tbooleanedit5: tbooleanedit + bounds_x = 46 + end + inherited tbooleanedit4: tbooleanedit + bounds_x = 35 + end + inherited tbooleanedit3: tbooleanedit + bounds_x = 24 + end + inherited tbooleanedit2: tbooleanedit + bounds_x = 13 + end + inherited c: tbooleanedit + bounds_x = 2 + end + inherited tlayouter2: tlayouter + inherited r11: tintegeredit + end + inherited r10: tintegeredit + end + inherited r9: tintegeredit + end + inherited fps: tintegeredit + end + inherited cpsr: tintegeredit + end + inherited r12: tintegeredit + end + inherited sp: tintegeredit + end + inherited lr: tintegeredit + end + inherited pc: tintegeredit + end + end + object tbooleanedit21: tbooleanedit[22] + Tag = 6 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 22 + bounds_x = 173 + bounds_y = 25 + bounds_cx = 11 + bounds_cy = 11 + end + object tbooleanedit22: tbooleanedit[23] + Tag = 7 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 23 + bounds_x = 162 + bounds_y = 25 + bounds_cx = 11 + bounds_cy = 11 + end + object tbooleanedit23: tbooleanedit[24] + Tag = 8 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 24 + bounds_x = 151 + bounds_y = 25 + bounds_cx = 11 + bounds_cy = 11 + end + end +end diff --git a/mseide-msegui/apps/ide/cpuarmm3form.pas b/mseide-msegui/apps/ide/cpuarmm3form.pas new file mode 100644 index 0000000..db3e9cd --- /dev/null +++ b/mseide-msegui/apps/ide/cpuarmm3form.pas @@ -0,0 +1,22 @@ +unit cpuarmm3form; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,mseforms,cpuarmform, + msegraphedits,mseifiglob,msetypes; + +type + tcpuarmm3fo = class(tcpuarmfo) + tbooleanedit21: tbooleanedit; + tbooleanedit22: tbooleanedit; + tbooleanedit23: tbooleanedit; + protected + end; +var + cpuarmm3fo: tcpuarmm3fo; +implementation +uses + cpuarmm3form_mfm,msedataedits; + +end. diff --git a/mseide-msegui/apps/ide/cpuarmm3form_mfm.pas b/mseide-msegui/apps/ide/cpuarmm3form_mfm.pas new file mode 100644 index 0000000..9aedc05 --- /dev/null +++ b/mseide-msegui/apps/ide/cpuarmm3form_mfm.pas @@ -0,0 +1,175 @@ +unit cpuarmm3form_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,cpuarmm3form; + +const + objdata: record size: integer; data: array[0..3147] of byte end = + (size: 3148; data: ( + 84,80,70,48,241,11,116,99,112,117,97,114,109,109,51,102,111,10,99,112, + 117,97,114,109,109,51,102,111,8,98,111,117,110,100,115,95,120,2,57,8, + 98,111,117,110,100,115,95,121,3,234,0,9,98,111,117,110,100,115,95,99, + 120,3,16,1,9,98,111,117,110,100,115,95,99,121,3,10,1,16,99,111, + 110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0,3, + 6,1,3,10,1,0,7,99,97,112,116,105,111,110,6,10,67,80,85,32, + 65,82,77,32,77,51,15,109,111,100,117,108,101,99,108,97,115,115,110,97, + 109,101,6,9,116,99,112,117,97,114,109,102,111,0,241,12,116,98,111,111, + 108,101,97,110,101,100,105,116,2,111,110,0,0,241,13,116,100,97,116,101, + 116,105,109,101,100,105,115,112,8,115,116,111,112,116,105,109,101,0,0,241, + 7,116,115,112,97,99,101,114,8,116,115,112,97,99,101,114,49,9,98,111, + 117,110,100,115,95,99,120,3,251,0,0,241,9,116,108,97,121,111,117,116, + 101,114,10,116,108,97,121,111,117,116,101,114,49,0,241,12,116,105,110,116, + 101,103,101,114,101,100,105,116,2,114,49,0,0,241,12,116,105,110,116,101, + 103,101,114,101,100,105,116,2,114,48,0,0,241,12,116,105,110,116,101,103, + 101,114,101,100,105,116,2,114,52,0,0,241,12,116,105,110,116,101,103,101, + 114,101,100,105,116,2,114,51,0,0,241,12,116,105,110,116,101,103,101,114, + 101,100,105,116,2,114,50,0,0,241,12,116,105,110,116,101,103,101,114,101, + 100,105,116,2,114,53,0,0,241,12,116,105,110,116,101,103,101,114,101,100, + 105,116,2,114,54,0,0,241,12,116,105,110,116,101,103,101,114,101,100,105, + 116,2,114,55,0,0,241,12,116,105,110,116,101,103,101,114,101,100,105,116, + 2,114,56,0,0,0,241,12,116,98,111,111,108,101,97,110,101,100,105,116, + 14,116,98,111,111,108,101,97,110,101,100,105,116,49,54,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,10,73,83,82,95,78,85,77,66,69, + 82,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,11, + 99,112,95,116,111,112,114,105,103,104,116,16,102,114,97,109,101,46,111,117, + 116,101,114,102,114,97,109,101,1,2,63,2,19,2,0,2,0,0,8,98, + 111,117,110,100,115,95,120,3,177,0,8,98,111,117,110,100,115,95,121,2, + 6,9,98,111,117,110,100,115,95,99,120,2,74,9,98,111,117,110,100,115, + 95,99,121,2,30,0,0,241,12,116,98,111,111,108,101,97,110,101,100,105, + 116,14,116,98,111,111,108,101,97,110,101,100,105,116,49,55,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,0,2,0,0,8, + 98,111,117,110,100,115,95,120,3,229,0,8,98,111,117,110,100,115,95,121, + 2,25,9,98,111,117,110,100,115,95,99,121,2,11,0,0,241,12,116,98, + 111,111,108,101,97,110,101,100,105,116,14,116,98,111,111,108,101,97,110,101, + 100,105,116,49,56,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2, + 0,2,0,2,0,2,0,0,8,98,111,117,110,100,115,95,120,3,218,0, + 8,98,111,117,110,100,115,95,121,2,25,9,98,111,117,110,100,115,95,99, + 121,2,11,0,0,241,12,116,98,111,111,108,101,97,110,101,100,105,116,14, + 116,98,111,111,108,101,97,110,101,100,105,116,49,57,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,0,2,0,2,0,0,8,98,111, + 117,110,100,115,95,120,3,207,0,8,98,111,117,110,100,115,95,121,2,25, + 9,98,111,117,110,100,115,95,99,121,2,11,0,0,241,12,116,98,111,111, + 108,101,97,110,101,100,105,116,14,116,98,111,111,108,101,97,110,101,100,105, + 116,50,48,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,0,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2, + 0,2,0,2,0,0,8,98,111,117,110,100,115,95,120,3,195,0,8,98, + 111,117,110,100,115,95,121,2,25,9,98,111,117,110,100,115,95,99,121,2, + 11,0,0,241,12,116,98,111,111,108,101,97,110,101,100,105,116,14,116,98, + 111,111,108,101,97,110,101,100,105,116,49,53,3,84,97,103,2,13,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,0,16,102,114,97,109,101, + 46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,0,2,0, + 0,8,98,111,117,110,100,115,95,120,2,104,8,98,111,117,110,100,115,95, + 121,2,25,9,98,111,117,110,100,115,95,99,121,2,11,0,0,241,12,116, + 98,111,111,108,101,97,110,101,100,105,116,14,116,98,111,111,108,101,97,110, + 101,100,105,116,49,52,3,84,97,103,2,10,13,102,114,97,109,101,46,99, + 97,112,116,105,111,110,6,6,73,67,73,47,73,84,16,102,114,97,109,101, + 46,99,97,112,116,105,111,110,112,111,115,7,11,99,112,95,116,111,112,114, + 105,103,104,116,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109, + 101,1,2,22,2,19,2,0,2,0,0,8,98,111,117,110,100,115,95,120, + 2,115,9,98,111,117,110,100,115,95,99,120,2,33,0,0,241,12,116,98, + 111,111,108,101,97,110,101,100,105,116,14,116,98,111,111,108,101,97,110,101, + 100,105,116,49,51,3,84,97,103,2,12,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,0,2,0,2,0,0,8,98,111,117,110,100, + 115,95,120,2,115,8,98,111,117,110,100,115,95,121,2,25,9,98,111,117, + 110,100,115,95,99,121,2,11,0,0,241,12,116,98,111,111,108,101,97,110, + 101,100,105,116,14,116,98,111,111,108,101,97,110,101,100,105,116,49,50,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,0,16,102,114,97,109, + 101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,0,2, + 0,0,8,98,111,117,110,100,115,95,120,3,184,0,8,98,111,117,110,100, + 115,95,121,2,25,9,98,111,117,110,100,115,95,99,121,2,11,0,0,241, + 12,116,98,111,111,108,101,97,110,101,100,105,116,14,116,98,111,111,108,101, + 97,110,101,100,105,116,49,49,3,84,97,103,2,11,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,0,2,0,2,0,0,8,98,111, + 117,110,100,115,95,120,2,126,8,98,111,117,110,100,115,95,121,2,25,9, + 98,111,117,110,100,115,95,99,121,2,11,0,0,241,12,116,98,111,111,108, + 101,97,110,101,100,105,116,14,116,98,111,111,108,101,97,110,101,100,105,116, + 49,48,3,84,97,103,2,26,16,102,114,97,109,101,46,99,97,112,116,105, + 111,110,112,111,115,7,10,99,112,95,116,111,112,108,101,102,116,8,98,111, + 117,110,100,115,95,120,2,60,0,0,241,12,116,98,111,111,108,101,97,110, + 101,100,105,116,13,116,98,111,111,108,101,97,110,101,100,105,116,57,3,84, + 97,103,2,25,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,0,2,0,2,0,0,8,98,111,117,110,100,115,95,120,2,71,8,98, + 111,117,110,100,115,95,121,2,25,9,98,111,117,110,100,115,95,99,121,2, + 11,0,0,241,12,116,98,111,111,108,101,97,110,101,100,105,116,13,116,98, + 111,111,108,101,97,110,101,100,105,116,56,3,84,97,103,2,15,13,102,114, + 97,109,101,46,99,97,112,116,105,111,110,6,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,0,2,0,0, + 8,98,111,117,110,100,115,95,120,2,82,8,98,111,117,110,100,115,95,121, + 2,25,9,98,111,117,110,100,115,95,99,121,2,11,0,0,241,12,116,98, + 111,111,108,101,97,110,101,100,105,116,13,116,98,111,111,108,101,97,110,101, + 100,105,116,55,3,84,97,103,2,14,8,98,111,117,110,100,115,95,120,2, + 93,0,0,241,12,116,98,111,111,108,101,97,110,101,100,105,116,13,116,98, + 111,111,108,101,97,110,101,100,105,116,54,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,1,84,8,98,111,117,110,100,115,95,120,2,77,8, + 98,111,117,110,100,115,95,121,2,0,7,118,105,115,105,98,108,101,8,0, + 0,241,12,116,98,111,111,108,101,97,110,101,100,105,116,13,116,98,111,111, + 108,101,97,110,101,100,105,116,53,8,98,111,117,110,100,115,95,120,2,46, + 0,0,241,12,116,98,111,111,108,101,97,110,101,100,105,116,13,116,98,111, + 111,108,101,97,110,101,100,105,116,52,8,98,111,117,110,100,115,95,120,2, + 35,0,0,241,12,116,98,111,111,108,101,97,110,101,100,105,116,13,116,98, + 111,111,108,101,97,110,101,100,105,116,51,8,98,111,117,110,100,115,95,120, + 2,24,0,0,241,12,116,98,111,111,108,101,97,110,101,100,105,116,13,116, + 98,111,111,108,101,97,110,101,100,105,116,50,8,98,111,117,110,100,115,95, + 120,2,13,0,0,241,12,116,98,111,111,108,101,97,110,101,100,105,116,1, + 99,8,98,111,117,110,100,115,95,120,2,2,0,0,241,9,116,108,97,121, + 111,117,116,101,114,10,116,108,97,121,111,117,116,101,114,50,0,241,12,116, + 105,110,116,101,103,101,114,101,100,105,116,3,114,49,49,0,0,241,12,116, + 105,110,116,101,103,101,114,101,100,105,116,3,114,49,48,0,0,241,12,116, + 105,110,116,101,103,101,114,101,100,105,116,2,114,57,0,0,241,12,116,105, + 110,116,101,103,101,114,101,100,105,116,3,102,112,115,0,0,241,12,116,105, + 110,116,101,103,101,114,101,100,105,116,4,99,112,115,114,0,0,241,12,116, + 105,110,116,101,103,101,114,101,100,105,116,3,114,49,50,0,0,241,12,116, + 105,110,116,101,103,101,114,101,100,105,116,2,115,112,0,0,241,12,116,105, + 110,116,101,103,101,114,101,100,105,116,2,108,114,0,0,241,12,116,105,110, + 116,101,103,101,114,101,100,105,116,2,112,99,0,0,0,242,2,22,12,116, + 98,111,111,108,101,97,110,101,100,105,116,14,116,98,111,111,108,101,97,110, + 101,100,105,116,50,49,3,84,97,103,2,6,5,99,111,108,111,114,4,3, + 0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102, + 114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0, + 144,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6, + 99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95, + 99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101, + 114,2,22,8,98,111,117,110,100,115,95,120,3,173,0,8,98,111,117,110, + 100,115,95,121,2,25,9,98,111,117,110,100,115,95,99,120,2,11,9,98, + 111,117,110,100,115,95,99,121,2,11,0,0,242,2,23,12,116,98,111,111, + 108,101,97,110,101,100,105,116,14,116,98,111,111,108,101,97,110,101,100,105, + 116,50,50,3,84,97,103,2,7,5,99,111,108,111,114,4,3,0,0,128, + 12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109, + 101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,16,102, + 114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95, + 116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108, + 111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,23, + 8,98,111,117,110,100,115,95,120,3,162,0,8,98,111,117,110,100,115,95, + 121,2,25,9,98,111,117,110,100,115,95,99,120,2,11,9,98,111,117,110, + 100,115,95,99,121,2,11,0,0,242,2,24,12,116,98,111,111,108,101,97, + 110,101,100,105,116,14,116,98,111,111,108,101,97,110,101,100,105,116,50,51, + 3,84,97,103,2,8,5,99,111,108,111,114,4,3,0,0,128,12,102,114, + 97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99, + 111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,16,102,114,97,109, + 101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,24,8,98,111, + 117,110,100,115,95,120,3,151,0,8,98,111,117,110,100,115,95,121,2,25, + 9,98,111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95, + 99,121,2,11,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tcpuarmm3fo,''); +end. diff --git a/mseide-msegui/apps/ide/cpuavr32form.mfm b/mseide-msegui/apps/ide/cpuavr32form.mfm new file mode 100644 index 0000000..d96edfc --- /dev/null +++ b/mseide-msegui/apps/ide/cpuavr32form.mfm @@ -0,0 +1,1058 @@ +inherited cpuavr32fo: tcpuavr32fo + bounds_x = 174 + bounds_y = 158 + bounds_cx = 261 + bounds_cy = 280 + container.bounds = ( + 0 + 0 + 251 + 280 + ) + caption = 'CPU AVR32' + left = 2 + moduleclassname = 'tcpufo' + inherited on: tbooleanedit + bounds_x = 152 + bounds_y = 1 + end + inherited stoptime: tdatetimedisp + bounds_x = 0 + bounds_y = 0 + end + object tspacer1: tspacer[2] + taborder = 2 + visible = True + bounds_x = 0 + bounds_y = 20 + bounds_cx = 243 + bounds_cy = 265 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + linktop = stoptime + object tbooleanedit16: tbooleanedit + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'C' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + bounds_x = 232 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit17: tbooleanedit + Tag = 1 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'Z' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 1 + bounds_x = 221 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit18: tbooleanedit + Tag = 2 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'N' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 2 + bounds_x = 210 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit19: tbooleanedit + Tag = 3 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'V' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 3 + bounds_x = 199 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit20: tbooleanedit + Tag = 4 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'Q' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 4 + bounds_x = 188 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit12: tbooleanedit + Tag = 5 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'L' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 5 + bounds_x = 177 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit14: tbooleanedit + Tag = 14 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'T' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 6 + bounds_x = 164 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit11: tbooleanedit + Tag = 15 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'R' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 7 + bounds_x = 153 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object gm: tbooleanedit + Tag = 16 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'G' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 8 + bounds_x = 137 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit15: tbooleanedit + Tag = 17 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = '0' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 9 + bounds_x = 126 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit7: tbooleanedit + Tag = 18 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = '1' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 10 + bounds_x = 115 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit8: tbooleanedit + Tag = 19 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = '2' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 11 + bounds_x = 104 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit21: tbooleanedit + Tag = 20 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'I' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 12 + bounds_x = 93 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit9: tbooleanedit + Tag = 21 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'E' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 13 + bounds_x = 80 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit10: tbooleanedit + Tag = 22 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = '0' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 14 + bounds_x = 69 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit6: tbooleanedit + Tag = 23 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = '1' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 15 + bounds_x = 58 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit5: tbooleanedit + Tag = 24 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'M' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 1 + 0 + ) + taborder = 16 + bounds_x = 47 + bounds_y = 6 + bounds_cx = 12 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit4: tbooleanedit + Tag = 25 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'D' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 17 + bounds_x = 34 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit3: tbooleanedit + Tag = 26 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'M' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 1 + 0 + ) + taborder = 18 + bounds_x = 23 + bounds_y = 6 + bounds_cx = 12 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object tbooleanedit2: tbooleanedit + Tag = 27 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'J' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 19 + bounds_x = 12 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object c: tbooleanedit + Tag = 28 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'H' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 19 + 0 + 0 + ) + taborder = 20 + bounds_x = 1 + bounds_y = 6 + bounds_cx = 11 + bounds_cy = 30 + onsetvalue = flagssetvalue + end + object irqoff: tbooleanedit + frame.caption = 'IRQoff' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 2 + 38 + 3 + ) + taborder = 21 + hint = 'Set global interrupt mask while stepping' + bounds_x = 17 + bounds_y = 235 + bounds_cx = 51 + bounds_cy = 18 + onsetvalue = irqoffset + end + object exceptstack: tbutton + optionswidget1 = [ow1_autowidth, ow1_autoheight] + taborder = 22 + bounds_x = 112 + bounds_y = 243 + bounds_cx = 115 + bounds_cy = 22 + state = [as_disabled, as_localdisabled, as_localcaption, as_localonexecute] + caption = 'Check Exceptstack' + onexecute = checkexcept + end + object tlayouter2: tlayouter + frame.localprops = [] + frame.localprops1 = [] + taborder = 23 + bounds_x = 113 + bounds_y = 40 + bounds_cx = 113 + bounds_cy = 176 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + font.name = 'stf_default' + font.xscale = 1 + font.localprops = [flp_xscale] + optionslayout = [lao_placey] + place_maxdist = 0 + onafterlayout = afterla + dist_bottom = 3 + object r6: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r6' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 14 + 0 + ) + bounds_x = 0 + bounds_y = 0 + bounds_cx = 107 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r7: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r7' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 14 + 0 + ) + taborder = 1 + bounds_x = 0 + bounds_y = 22 + bounds_cx = 107 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r8: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r8' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 14 + 0 + ) + taborder = 2 + bounds_x = 0 + bounds_y = 44 + bounds_cx = 107 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r11: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r11' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + taborder = 5 + bounds_x = 0 + bounds_y = 110 + bounds_cx = 112 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r10: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r10' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 20 + 0 + ) + taborder = 4 + bounds_x = 0 + bounds_y = 88 + bounds_cx = 113 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r9: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r9' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 14 + 0 + ) + taborder = 3 + bounds_x = 0 + bounds_y = 66 + bounds_cx = 107 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r12: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r12' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 20 + 0 + ) + taborder = 6 + bounds_x = 0 + bounds_y = 132 + bounds_cx = 113 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object sr: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'sr' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 14 + 0 + ) + taborder = 7 + bounds_x = 0 + bounds_y = 154 + bounds_cx = 107 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onchange = flagonchange + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + end + object tlayouter1: tlayouter + frame.localprops = [] + frame.localprops1 = [] + taborder = 24 + bounds_x = 0 + bounds_y = 40 + bounds_cx = 110 + bounds_cy = 198 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + font.name = 'stf_default' + font.xscale = 1 + font.localprops = [flp_xscale] + optionslayout = [lao_placey] + place_maxdist = 0 + linkright = tlayouter2 + linkbottom = exceptstack + dist_right = 3 + dist_bottom = 5 + object r1: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r1' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 13 + 0 + ) + taborder = 1 + bounds_x = 0 + bounds_y = 22 + bounds_cx = 106 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r0: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r0' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 14 + 0 + ) + bounds_x = 0 + bounds_y = 0 + bounds_cx = 107 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r4: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r4' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 14 + 0 + ) + taborder = 4 + bounds_x = 0 + bounds_y = 88 + bounds_cx = 107 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r3: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r3' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 14 + 0 + ) + taborder = 3 + bounds_x = 0 + bounds_y = 66 + bounds_cx = 107 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r2: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r2' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 14 + 0 + ) + taborder = 2 + bounds_x = 0 + bounds_y = 44 + bounds_cx = 107 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object r5: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r5' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 14 + 0 + ) + taborder = 5 + bounds_x = 0 + bounds_y = 110 + bounds_cx = 107 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object sp: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'sp' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 17 + 0 + ) + taborder = 6 + bounds_x = 0 + bounds_y = 132 + bounds_cx = 110 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object lr: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'lr' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 10 + 0 + ) + taborder = 7 + bounds_x = 0 + bounds_y = 154 + bounds_cx = 103 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + object pc: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'pc' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 17 + 0 + ) + taborder = 8 + bounds_x = 0 + bounds_y = 176 + bounds_cx = 110 + bounds_cy = 22 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + valuemax = -1 + reffontheight = 18 + end + end + end + object cs: tstringcontainer[3] + strings.data = ( + 'Return address:' + 'Exception return' + ) + left = 128 + top = 224 + end +end diff --git a/mseide-msegui/apps/ide/cpuavr32form.pas b/mseide-msegui/apps/ide/cpuavr32form.pas new file mode 100644 index 0000000..5f040b8 --- /dev/null +++ b/mseide-msegui/apps/ide/cpuavr32form.pas @@ -0,0 +1,305 @@ +{ MSEide Copyright (c) 1999-2013 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit cpuavr32form; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,mseglob,mseguiglob,mseapplication,msestat,msemenus,msegui, + msegraphics, + msegraphutils,mseevent,mseclasses,mseforms,cpuform,msesplitter,msedataedits, + mseedit,msestrings,msetypes,msegraphedits,msesimplewidgets,msewidgets, + msestringcontainer; + +type + tcpuavr32fo = class(tcpufo) + fps: tintegeredit; + tspacer1: tspacer; + tbooleanedit16: tbooleanedit; + tbooleanedit17: tbooleanedit; + tbooleanedit18: tbooleanedit; + tbooleanedit19: tbooleanedit; + tbooleanedit20: tbooleanedit; + tbooleanedit12: tbooleanedit; + tbooleanedit14: tbooleanedit; + tbooleanedit11: tbooleanedit; + gm: tbooleanedit; + tbooleanedit15: tbooleanedit; + tbooleanedit7: tbooleanedit; + tbooleanedit8: tbooleanedit; + tbooleanedit21: tbooleanedit; + tbooleanedit9: tbooleanedit; + tbooleanedit10: tbooleanedit; + tbooleanedit6: tbooleanedit; + tbooleanedit5: tbooleanedit; + tbooleanedit4: tbooleanedit; + tbooleanedit3: tbooleanedit; + tbooleanedit2: tbooleanedit; + c: tbooleanedit; + irqoff: tbooleanedit; + exceptstack: tbutton; + tlayouter2: tlayouter; + r6: tintegeredit; + r7: tintegeredit; + r8: tintegeredit; + r11: tintegeredit; + r10: tintegeredit; + r9: tintegeredit; + r12: tintegeredit; + sr: tintegeredit; + tlayouter1: tlayouter; + r1: tintegeredit; + r0: tintegeredit; + r4: tintegeredit; + r3: tintegeredit; + r2: tintegeredit; + r5: tintegeredit; + sp: tintegeredit; + lr: tintegeredit; + pc: tintegeredit; + cs: tstringcontainer; + procedure regsetvalue(const sender: TObject; var avalue: Integer; + var accept: Boolean); + procedure flagssetvalue(const sender: TObject; var avalue: Boolean; + var accept: Boolean); + procedure flagonchange(const sender: TObject); + function internalrefresh: boolean; override; + procedure checkexcept(const sender: TObject); + procedure irqoffset(const sender: TObject; var avalue: Boolean; + var accept: Boolean); + procedure afterla(const sender: tcustomlayouter); + private + fgmbefore: boolean; + protected + procedure updatereadstatvalues; override; + procedure updatewritestatvalues; override; + procedure doirqoff; + procedure irqrestore; + public + constructor create(aowner: tcomponent); override; + function flagedit(const aindex: integer): tcustombooleanedit; override; + procedure refresh; override; + procedure beforecontinue; override; + end; + +implementation +uses + cpuavr32form_mfm,main,msegdbutils,sourceform,mseformatstr,sysutils, + disassform; +type + stringconsts = ( + retad, //0 Return address: + exceptreturn //1 Exception return + ); + +const + modebits = $01c00000; + gmmask = $00010000; + exceptmode = $00800000; //irq level 0 +{ tcpuavr32fo } + +constructor tcpuavr32fo.create(aowner: tcomponent); +begin + inherited create(aowner); + fflagswidget:= sr; +end; + +procedure tcpuavr32fo.regsetvalue(const sender: TObject; var avalue: Integer; + var accept: Boolean); +//var +// str1: string; +begin + if mainfo.gdb.cancommand then begin + with tintegeredit(sender) do begin + if mainfo.gdb.setsystemregister(0,value) <> gdb_ok then begin + accept:= false; + end; + end; + end + else begin + accept:= false; + end; +end; + +procedure tcpuavr32fo.flagssetvalue(const sender: TObject; var avalue: Boolean; + var accept: Boolean); +begin + doflagsetvalue(sender,avalue,accept); +end; + +procedure tcpuavr32fo.flagonchange(const sender: TObject); +begin + doflagonchange(sender); +end; + +function tcpuavr32fo.internalrefresh: boolean; +var + int1: qword; +begin + result:= inherited internalrefresh; + if result then begin + if mainfo.gdb.getsystemregister(0,int1) = gdb_ok then begin + if sr.value <> int1 then begin + sr.font.color:= cl_red; + end + else begin + sr.font.color:= cl_black; + end; + sr.value:= int1; + result:= true; + exceptstack.enabled:= int1 and modebits >= exceptmode; + end + else begin + result:= false; + end; + end; + if not result then begin + exceptstack.enabled:= false; + end; +end; +//todo: fix 32/64 +procedure tcpuavr32fo.checkexcept(const sender: TObject); + + procedure locateframe(const address: qword); + var + bo1: boolean; + filename: filenamety; + line: integer; + start,stop: qword; + mstr1,mstr2: msestring; + begin + disassfo.refresh(address); + mstr1:= ''; + with mainfo.gdb do begin + bo1:= infoline(address,filename,line,start,stop) = gdb_ok; + if bo1 then begin + if sourcefo.showsourceline(filename,line-1,0,true) <> nil then begin + exit; + end; + mstr1:= filename+':'+inttostrmse(line); + end; + mstr2:= hextostrmse(address,8); + if infosymbol('*0x'+mstr2,mstr1) = gdb_ok then begin + mstr1:= mstr1+lineend+mstr1; + end + else begin + mstr1:= mstr1+lineend+cs[ord(retad)]+' '+mstr2; + end; + end; + showmessage(mstr1,cs[ord(exceptreturn)]); + end; + +var + lwo1,lwo2,{lwo3,}lwo4: longword; + lwo3,framead: qword; +begin + with mainfo.gdb do begin + if (getframeaddress(framead) = gdb_ok) then begin + if readmemorylongword(framead+4,lwo1) = gdb_ok then begin + //pc +// setregistervalue('pc',lwo1); + if readmemorylongword(framead,lwo2) = gdb_ok then begin + //sr + lwo4:= sr.value; //backup + if setsystemregister(0,lwo2) = gdb_ok then begin + //for sp_app access + // if getregistervalue('sp',longint(lwo3)) = gdb_ok then begin + if (getregistervalue('sp',lwo3) = gdb_ok) then begin + if selectstackpointer(lwo3) = gdb_ok then begin + mainfo.refreshframe; + end; + end; + end; + setsystemregister(0,lwo4); //restore + end; + end; + locateframe(lwo1); + end; + end; +end; + +procedure tcpuavr32fo.doirqoff; +begin + fgmbefore:= gm.value; + if not gm.value then begin + gm.value:= true; + gm.checkvalue; + end; +end; + +procedure tcpuavr32fo.irqrestore; +begin + if gm.value <> fgmbefore then begin + gm.value:= fgmbefore; + gm.checkvalue; + end; +end; + +procedure tcpuavr32fo.refresh; +begin + if irqoff.value and mainfo.gdb.cancommand then begin + inherited; + doirqoff; + end + else begin + inherited; + end; +end; + +procedure tcpuavr32fo.beforecontinue; +begin + if irqoff.value and mainfo.gdb.cancommand then begin + irqrestore; + end; + inherited; +end; + +procedure tcpuavr32fo.irqoffset(const sender: TObject; var avalue: Boolean; + var accept: Boolean); +begin + if mainfo.gdb.cancommand then begin + if avalue then begin + doirqoff; + end + else begin + irqrestore; + end; + end; +end; + +procedure tcpuavr32fo.afterla(const sender: tcustomlayouter); +begin + aligny(wam_center,[exceptstack,irqoff]); +end; + +procedure tcpuavr32fo.updatereadstatvalues; +begin + irqoff.value:= irqoffvalue; + inherited; +end; + +procedure tcpuavr32fo.updatewritestatvalues; +begin + irqoffvalue:= irqoff.value; + inherited; +end; + +function tcpuavr32fo.flagedit(const aindex: integer): tcustombooleanedit; +begin + result:= c.tagitem(aindex); +end; + +end. diff --git a/mseide-msegui/apps/ide/cpuavr32form_mfm.pas b/mseide-msegui/apps/ide/cpuavr32form_mfm.pas new file mode 100644 index 0000000..0f938cd --- /dev/null +++ b/mseide-msegui/apps/ide/cpuavr32form_mfm.pas @@ -0,0 +1,876 @@ +unit cpuavr32form_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,cpuavr32form; + +const + objdata: record size: integer; data: array[0..17167] of byte end = + (size: 17168; data: ( + 84,80,70,48,241,11,116,99,112,117,97,118,114,51,50,102,111,10,99,112, + 117,97,118,114,51,50,102,111,8,98,111,117,110,100,115,95,120,3,174,0, + 8,98,111,117,110,100,115,95,121,3,158,0,9,98,111,117,110,100,115,95, + 99,120,3,5,1,9,98,111,117,110,100,115,95,99,121,3,24,1,16,99, + 111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0, + 3,251,0,3,24,1,0,7,99,97,112,116,105,111,110,6,9,67,80,85, + 32,65,86,82,51,50,4,108,101,102,116,2,2,15,109,111,100,117,108,101, + 99,108,97,115,115,110,97,109,101,6,6,116,99,112,117,102,111,0,241,12, + 116,98,111,111,108,101,97,110,101,100,105,116,2,111,110,8,98,111,117,110, + 100,115,95,120,3,152,0,8,98,111,117,110,100,115,95,121,2,1,0,0, + 241,13,116,100,97,116,101,116,105,109,101,100,105,115,112,8,115,116,111,112, + 116,105,109,101,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110, + 100,115,95,121,2,0,0,0,242,2,2,7,116,115,112,97,99,101,114,8, + 116,115,112,97,99,101,114,49,8,116,97,98,111,114,100,101,114,2,2,7, + 118,105,115,105,98,108,101,9,8,98,111,117,110,100,115,95,120,2,0,8, + 98,111,117,110,100,115,95,121,2,20,9,98,111,117,110,100,115,95,99,120, + 3,243,0,9,98,111,117,110,100,115,95,99,121,3,9,1,12,111,112,116, + 105,111,110,115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97,110, + 100,120,11,111,115,99,95,115,104,114,105,110,107,120,11,111,115,99,95,101, + 120,112,97,110,100,121,11,111,115,99,95,115,104,114,105,110,107,121,0,7, + 108,105,110,107,116,111,112,7,8,115,116,111,112,116,105,109,101,0,12,116, + 98,111,111,108,101,97,110,101,100,105,116,14,116,98,111,111,108,101,97,110, + 101,100,105,116,49,54,5,99,111,108,111,114,4,3,0,0,128,12,102,114, + 97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99, + 111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,1,67,16,102,114,97,109,101,46,99, + 97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95, + 108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101, + 110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101, + 1,2,0,2,19,2,0,2,0,0,8,98,111,117,110,100,115,95,120,3, + 232,0,8,98,111,117,110,100,115,95,121,2,6,9,98,111,117,110,100,115, + 95,99,120,2,11,9,98,111,117,110,100,115,95,99,121,2,30,10,111,110, + 115,101,116,118,97,108,117,101,7,13,102,108,97,103,115,115,101,116,118,97, + 108,117,101,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,14,116, + 98,111,111,108,101,97,110,101,100,105,116,49,55,3,84,97,103,2,1,5, + 99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,1,90,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112, + 111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,19,2,0, + 2,0,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100, + 115,95,120,3,221,0,8,98,111,117,110,100,115,95,121,2,6,9,98,111, + 117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95,99,121,2, + 30,10,111,110,115,101,116,118,97,108,117,101,7,13,102,108,97,103,115,115, + 101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110,101,100, + 105,116,14,116,98,111,111,108,101,97,110,101,100,105,116,49,56,3,84,97, + 103,2,2,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101, + 46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111, + 114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99, + 97,112,116,105,111,110,6,1,78,16,102,114,97,109,101,46,99,97,112,116, + 105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,19,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,2,8,98, + 111,117,110,100,115,95,120,3,210,0,8,98,111,117,110,100,115,95,121,2, + 6,9,98,111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115, + 95,99,121,2,30,10,111,110,115,101,116,118,97,108,117,101,7,13,102,108, + 97,103,115,115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101, + 97,110,101,100,105,116,14,116,98,111,111,108,101,97,110,101,100,105,116,49, + 57,3,84,97,103,2,3,5,99,111,108,111,114,4,3,0,0,128,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,1,86,16,102,114,97,109,101,46, + 99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108, + 95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105, + 101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109, + 101,1,2,0,2,19,2,0,2,0,0,8,116,97,98,111,114,100,101,114, + 2,3,8,98,111,117,110,100,115,95,120,3,199,0,8,98,111,117,110,100, + 115,95,121,2,6,9,98,111,117,110,100,115,95,99,120,2,11,9,98,111, + 117,110,100,115,95,99,121,2,30,10,111,110,115,101,116,118,97,108,117,101, + 7,13,102,108,97,103,115,115,101,116,118,97,108,117,101,0,0,12,116,98, + 111,111,108,101,97,110,101,100,105,116,14,116,98,111,111,108,101,97,110,101, + 100,105,116,50,48,3,84,97,103,2,4,5,99,111,108,111,114,4,3,0, + 0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1,81,16,102,114, + 97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116, + 111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111, + 114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,19,2,0,2,0,0,8,116,97,98,111, + 114,100,101,114,2,4,8,98,111,117,110,100,115,95,120,3,188,0,8,98, + 111,117,110,100,115,95,121,2,6,9,98,111,117,110,100,115,95,99,120,2, + 11,9,98,111,117,110,100,115,95,99,121,2,30,10,111,110,115,101,116,118, + 97,108,117,101,7,13,102,108,97,103,115,115,101,116,118,97,108,117,101,0, + 0,12,116,98,111,111,108,101,97,110,101,100,105,116,14,116,98,111,111,108, + 101,97,110,101,100,105,116,49,50,3,84,97,103,2,5,5,99,111,108,111, + 114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1, + 76,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6, + 99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95, + 99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,19,2,0,2,0,0,8, + 116,97,98,111,114,100,101,114,2,5,8,98,111,117,110,100,115,95,120,3, + 177,0,8,98,111,117,110,100,115,95,121,2,6,9,98,111,117,110,100,115, + 95,99,120,2,11,9,98,111,117,110,100,115,95,99,121,2,30,10,111,110, + 115,101,116,118,97,108,117,101,7,13,102,108,97,103,115,115,101,116,118,97, + 108,117,101,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,14,116, + 98,111,111,108,101,97,110,101,100,105,116,49,52,3,84,97,103,2,14,5, + 99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,1,84,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112, + 111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,19,2,0, + 2,0,0,8,116,97,98,111,114,100,101,114,2,6,8,98,111,117,110,100, + 115,95,120,3,164,0,8,98,111,117,110,100,115,95,121,2,6,9,98,111, + 117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95,99,121,2, + 30,10,111,110,115,101,116,118,97,108,117,101,7,13,102,108,97,103,115,115, + 101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110,101,100, + 105,116,14,116,98,111,111,108,101,97,110,101,100,105,116,49,49,3,84,97, + 103,2,15,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101, + 46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111, + 114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99, + 97,112,116,105,111,110,6,1,82,16,102,114,97,109,101,46,99,97,112,116, + 105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,19,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,7,8,98, + 111,117,110,100,115,95,120,3,153,0,8,98,111,117,110,100,115,95,121,2, + 6,9,98,111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115, + 95,99,121,2,30,10,111,110,115,101,116,118,97,108,117,101,7,13,102,108, + 97,103,115,115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101, + 97,110,101,100,105,116,2,103,109,3,84,97,103,2,16,5,99,111,108,111, + 114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1, + 71,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6, + 99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95, + 99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,19,2,0,2,0,0,8, + 116,97,98,111,114,100,101,114,2,8,8,98,111,117,110,100,115,95,120,3, + 137,0,8,98,111,117,110,100,115,95,121,2,6,9,98,111,117,110,100,115, + 95,99,120,2,11,9,98,111,117,110,100,115,95,99,121,2,30,10,111,110, + 115,101,116,118,97,108,117,101,7,13,102,108,97,103,115,115,101,116,118,97, + 108,117,101,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,14,116, + 98,111,111,108,101,97,110,101,100,105,116,49,53,3,84,97,103,2,17,5, + 99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,1,48,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112, + 111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,19,2,0, + 2,0,0,8,116,97,98,111,114,100,101,114,2,9,8,98,111,117,110,100, + 115,95,120,2,126,8,98,111,117,110,100,115,95,121,2,6,9,98,111,117, + 110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95,99,121,2,30, + 10,111,110,115,101,116,118,97,108,117,101,7,13,102,108,97,103,115,115,101, + 116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110,101,100,105, + 116,13,116,98,111,111,108,101,97,110,101,100,105,116,55,3,84,97,103,2, + 18,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,1,49,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,19, + 2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,10,8,98,111,117, + 110,100,115,95,120,2,115,8,98,111,117,110,100,115,95,121,2,6,9,98, + 111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95,99,121, + 2,30,10,111,110,115,101,116,118,97,108,117,101,7,13,102,108,97,103,115, + 115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110,101, + 100,105,116,13,116,98,111,111,108,101,97,110,101,100,105,116,56,3,84,97, + 103,2,19,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101, + 46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111, + 114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99, + 97,112,116,105,111,110,6,1,50,16,102,114,97,109,101,46,99,97,112,116, + 105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,19,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,11,8,98, + 111,117,110,100,115,95,120,2,104,8,98,111,117,110,100,115,95,121,2,6, + 9,98,111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95, + 99,121,2,30,10,111,110,115,101,116,118,97,108,117,101,7,13,102,108,97, + 103,115,115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97, + 110,101,100,105,116,14,116,98,111,111,108,101,97,110,101,100,105,116,50,49, + 3,84,97,103,2,20,5,99,111,108,111,114,4,3,0,0,128,12,102,114, + 97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99, + 111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,1,73,16,102,114,97,109,101,46,99, + 97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95, + 108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101, + 110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101, + 1,2,0,2,19,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2, + 12,8,98,111,117,110,100,115,95,120,2,93,8,98,111,117,110,100,115,95, + 121,2,6,9,98,111,117,110,100,115,95,99,120,2,11,9,98,111,117,110, + 100,115,95,99,121,2,30,10,111,110,115,101,116,118,97,108,117,101,7,13, + 102,108,97,103,115,115,101,116,118,97,108,117,101,0,0,12,116,98,111,111, + 108,101,97,110,101,100,105,116,13,116,98,111,111,108,101,97,110,101,100,105, + 116,57,3,84,97,103,2,21,5,99,111,108,111,114,4,3,0,0,128,12, + 102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101, + 46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114, + 97,109,101,46,99,97,112,116,105,111,110,6,1,69,16,102,114,97,109,101, + 46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,19,2,0,2,0,0,8,116,97,98,111,114,100,101, + 114,2,13,8,98,111,117,110,100,115,95,120,2,80,8,98,111,117,110,100, + 115,95,121,2,6,9,98,111,117,110,100,115,95,99,120,2,11,9,98,111, + 117,110,100,115,95,99,121,2,30,10,111,110,115,101,116,118,97,108,117,101, + 7,13,102,108,97,103,115,115,101,116,118,97,108,117,101,0,0,12,116,98, + 111,111,108,101,97,110,101,100,105,116,14,116,98,111,111,108,101,97,110,101, + 100,105,116,49,48,3,84,97,103,2,22,5,99,111,108,111,114,4,3,0, + 0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1,48,16,102,114, + 97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116, + 111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111, + 114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,19,2,0,2,0,0,8,116,97,98,111, + 114,100,101,114,2,14,8,98,111,117,110,100,115,95,120,2,69,8,98,111, + 117,110,100,115,95,121,2,6,9,98,111,117,110,100,115,95,99,120,2,11, + 9,98,111,117,110,100,115,95,99,121,2,30,10,111,110,115,101,116,118,97, + 108,117,101,7,13,102,108,97,103,115,115,101,116,118,97,108,117,101,0,0, + 12,116,98,111,111,108,101,97,110,101,100,105,116,13,116,98,111,111,108,101, + 97,110,101,100,105,116,54,3,84,97,103,2,23,5,99,111,108,111,114,4, + 3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17, + 102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0, + 0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1,49,16, + 102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112, + 95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111, + 108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,19,2,0,2,0,0,8,116,97, + 98,111,114,100,101,114,2,15,8,98,111,117,110,100,115,95,120,2,58,8, + 98,111,117,110,100,115,95,121,2,6,9,98,111,117,110,100,115,95,99,120, + 2,11,9,98,111,117,110,100,115,95,99,121,2,30,10,111,110,115,101,116, + 118,97,108,117,101,7,13,102,108,97,103,115,115,101,116,118,97,108,117,101, + 0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,13,116,98,111,111, + 108,101,97,110,101,100,105,116,53,3,84,97,103,2,24,5,99,111,108,111, + 114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1, + 77,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6, + 99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95, + 99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,19,2,1,2,0,0,8, + 116,97,98,111,114,100,101,114,2,16,8,98,111,117,110,100,115,95,120,2, + 47,8,98,111,117,110,100,115,95,121,2,6,9,98,111,117,110,100,115,95, + 99,120,2,12,9,98,111,117,110,100,115,95,99,121,2,30,10,111,110,115, + 101,116,118,97,108,117,101,7,13,102,108,97,103,115,115,101,116,118,97,108, + 117,101,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,13,116,98, + 111,111,108,101,97,110,101,100,105,116,52,3,84,97,103,2,25,5,99,111, + 108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108, + 111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110, + 116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,1,68,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115, + 7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114, + 108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101, + 46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,19,2,0,2,0, + 0,8,116,97,98,111,114,100,101,114,2,17,8,98,111,117,110,100,115,95, + 120,2,34,8,98,111,117,110,100,115,95,121,2,6,9,98,111,117,110,100, + 115,95,99,120,2,11,9,98,111,117,110,100,115,95,99,121,2,30,10,111, + 110,115,101,116,118,97,108,117,101,7,13,102,108,97,103,115,115,101,116,118, + 97,108,117,101,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,13, + 116,98,111,111,108,101,97,110,101,100,105,116,51,3,84,97,103,2,26,5, + 99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,1,77,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112, + 111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,19,2,1, + 2,0,0,8,116,97,98,111,114,100,101,114,2,18,8,98,111,117,110,100, + 115,95,120,2,23,8,98,111,117,110,100,115,95,121,2,6,9,98,111,117, + 110,100,115,95,99,120,2,12,9,98,111,117,110,100,115,95,99,121,2,30, + 10,111,110,115,101,116,118,97,108,117,101,7,13,102,108,97,103,115,115,101, + 116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110,101,100,105, + 116,13,116,98,111,111,108,101,97,110,101,100,105,116,50,3,84,97,103,2, + 27,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,1,74,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,19, + 2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,19,8,98,111,117, + 110,100,115,95,120,2,12,8,98,111,117,110,100,115,95,121,2,6,9,98, + 111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95,99,121, + 2,30,10,111,110,115,101,116,118,97,108,117,101,7,13,102,108,97,103,115, + 115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110,101, + 100,105,116,1,99,3,84,97,103,2,28,5,99,111,108,111,114,4,3,0, + 0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1,72,16,102,114, + 97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116, + 111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111, + 114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,19,2,0,2,0,0,8,116,97,98,111, + 114,100,101,114,2,20,8,98,111,117,110,100,115,95,120,2,1,8,98,111, + 117,110,100,115,95,121,2,6,9,98,111,117,110,100,115,95,99,120,2,11, + 9,98,111,117,110,100,115,95,99,121,2,30,10,111,110,115,101,116,118,97, + 108,117,101,7,13,102,108,97,103,115,115,101,116,118,97,108,117,101,0,0, + 12,116,98,111,111,108,101,97,110,101,100,105,116,6,105,114,113,111,102,102, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,6,73,82,81,111, + 102,102,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2, + 0,2,2,2,38,2,3,0,8,116,97,98,111,114,100,101,114,2,21,4, + 104,105,110,116,6,40,83,101,116,32,103,108,111,98,97,108,32,105,110,116, + 101,114,114,117,112,116,32,109,97,115,107,32,119,104,105,108,101,32,115,116, + 101,112,112,105,110,103,8,98,111,117,110,100,115,95,120,2,17,8,98,111, + 117,110,100,115,95,121,3,235,0,9,98,111,117,110,100,115,95,99,120,2, + 51,9,98,111,117,110,100,115,95,99,121,2,18,10,111,110,115,101,116,118, + 97,108,117,101,7,9,105,114,113,111,102,102,115,101,116,0,0,7,116,98, + 117,116,116,111,110,11,101,120,99,101,112,116,115,116,97,99,107,14,111,112, + 116,105,111,110,115,119,105,100,103,101,116,49,11,13,111,119,49,95,97,117, + 116,111,119,105,100,116,104,14,111,119,49,95,97,117,116,111,104,101,105,103, + 104,116,0,8,116,97,98,111,114,100,101,114,2,22,8,98,111,117,110,100, + 115,95,120,2,112,8,98,111,117,110,100,115,95,121,3,243,0,9,98,111, + 117,110,100,115,95,99,120,2,115,9,98,111,117,110,100,115,95,99,121,2, + 22,5,115,116,97,116,101,11,11,97,115,95,100,105,115,97,98,108,101,100, + 16,97,115,95,108,111,99,97,108,100,105,115,97,98,108,101,100,15,97,115, + 95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99, + 97,108,111,110,101,120,101,99,117,116,101,0,7,99,97,112,116,105,111,110, + 6,17,67,104,101,99,107,32,69,120,99,101,112,116,115,116,97,99,107,9, + 111,110,101,120,101,99,117,116,101,7,11,99,104,101,99,107,101,120,99,101, + 112,116,0,0,9,116,108,97,121,111,117,116,101,114,10,116,108,97,121,111, + 117,116,101,114,50,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,8,116,97,98,111,114,100,101,114,2,23,8,98,111,117,110, + 100,115,95,120,2,113,8,98,111,117,110,100,115,95,121,2,40,9,98,111, + 117,110,100,115,95,99,120,2,113,9,98,111,117,110,100,115,95,99,121,3, + 176,0,12,111,112,116,105,111,110,115,115,99,97,108,101,11,11,111,115,99, + 95,101,120,112,97,110,100,120,11,111,115,99,95,115,104,114,105,110,107,120, + 11,111,115,99,95,101,120,112,97,110,100,121,11,111,115,99,95,115,104,114, + 105,110,107,121,0,9,102,111,110,116,46,110,97,109,101,6,11,115,116,102, + 95,100,101,102,97,117,108,116,11,102,111,110,116,46,120,115,99,97,108,101, + 2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,108,112,95,120,115,99,97,108,101,0,13,111,112,116,105,111,110,115,108, + 97,121,111,117,116,11,10,108,97,111,95,112,108,97,99,101,121,0,13,112, + 108,97,99,101,95,109,97,120,100,105,115,116,2,0,13,111,110,97,102,116, + 101,114,108,97,121,111,117,116,7,7,97,102,116,101,114,108,97,11,100,105, + 115,116,95,98,111,116,116,111,109,2,3,0,12,116,105,110,116,101,103,101, + 114,101,100,105,116,2,114,54,13,111,112,116,105,111,110,115,119,105,100,103, + 101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119, + 95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111, + 99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16, + 111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109, + 101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108, + 111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,2,114,54,22,102,114,97,109,101,46,99,97, + 112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121, + 99,101,110,116,101,114,101,100,0,16,102,114,97,109,101,46,99,97,112,116, + 105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,0,2,14,2,0,0,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,2,107,9,98,111,117,110,100,115,95,99,121,2,22,11,102,111,110,116, + 46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6, + 9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97, + 108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118, + 97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97, + 115,101,7,6,110,98,95,104,101,120,8,118,97,108,117,101,109,97,120,2, + 255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,18,0,0,12, + 116,105,110,116,101,103,101,114,101,100,105,116,2,114,55,13,111,112,116,105, + 111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102, + 111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95, + 97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102, + 111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115, + 111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116, + 115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,2,114,55,22,102, + 114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103, + 115,11,12,116,102,95,121,99,101,110,116,101,114,101,100,0,16,102,114,97, + 109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105, + 103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108, + 111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101, + 114,102,114,97,109,101,1,2,0,2,0,2,14,2,0,0,8,116,97,98, + 111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0,8,98, + 111,117,110,100,115,95,121,2,22,9,98,111,117,110,100,115,95,99,120,2, + 107,9,98,111,117,110,100,115,95,99,121,2,22,11,102,111,110,116,46,104, + 101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115, + 116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101, + 2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108, + 117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101, + 7,6,110,98,95,104,101,120,8,118,97,108,117,101,109,97,120,2,255,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,18,0,0,12,116,105, + 110,116,101,103,101,114,101,100,105,116,2,114,56,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109, + 101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,2,114,56,22,102,114,97, + 109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11, + 12,116,102,95,121,99,101,110,116,101,114,101,100,0,16,102,114,97,109,101, + 46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104, + 116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,0,2,14,2,0,0,8,116,97,98,111,114, + 100,101,114,2,2,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,2,44,9,98,111,117,110,100,115,95,99,120,2,107,9, + 98,111,117,110,100,115,95,99,121,2,22,11,102,111,110,116,46,104,101,105, + 103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102, + 95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1, + 15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108, + 112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101, + 7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6, + 110,98,95,104,101,120,8,118,97,108,117,101,109,97,120,2,255,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,18,0,0,12,116,105,110,116, + 101,103,101,114,101,100,105,116,3,114,49,49,13,111,112,116,105,111,110,115, + 119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117, + 115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114, + 111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117, + 115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116, + 17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12, + 102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101, + 46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114, + 97,109,101,46,99,97,112,116,105,111,110,6,3,114,49,49,22,102,114,97, + 109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11, + 12,116,102,95,121,99,101,110,116,101,114,101,100,0,16,102,114,97,109,101, + 46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104, + 116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,0,2,19,2,0,0,8,116,97,98,111,114, + 100,101,114,2,5,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,2,110,9,98,111,117,110,100,115,95,99,120,2,112,9, + 98,111,117,110,100,115,95,99,121,2,22,11,102,111,110,116,46,104,101,105, + 103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102, + 95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1, + 15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108, + 112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101, + 7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6, + 110,98,95,104,101,120,8,118,97,108,117,101,109,97,120,2,255,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,18,0,0,12,116,105,110,116, + 101,103,101,114,101,100,105,116,3,114,49,48,13,111,112,116,105,111,110,115, + 119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117, + 115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114, + 111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117, + 115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116, + 17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12, + 102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101, + 46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114, + 97,109,101,46,99,97,112,116,105,111,110,6,3,114,49,48,22,102,114,97, + 109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11, + 12,116,102,95,121,99,101,110,116,101,114,101,100,0,16,102,114,97,109,101, + 46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104, + 116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,0,2,20,2,0,0,8,116,97,98,111,114, + 100,101,114,2,4,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,2,88,9,98,111,117,110,100,115,95,99,120,2,113,9, + 98,111,117,110,100,115,95,99,121,2,22,11,102,111,110,116,46,104,101,105, + 103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102, + 95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1, + 15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108, + 112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101, + 7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6, + 110,98,95,104,101,120,8,118,97,108,117,101,109,97,120,2,255,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,18,0,0,12,116,105,110,116, + 101,103,101,114,101,100,105,116,2,114,57,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115, + 105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,2,114,57,22,102,114,97,109,101, + 46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,12,116, + 102,95,121,99,101,110,116,101,114,101,100,0,16,102,114,97,109,101,46,99, + 97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,0,2,14,2,0,0,8,116,97,98,111,114,100,101, + 114,2,3,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100, + 115,95,121,2,66,9,98,111,117,110,100,115,95,99,120,2,107,9,98,111, + 117,110,100,115,95,99,121,2,22,11,102,111,110,116,46,104,101,105,103,104, + 116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102, + 105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102, + 111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95, + 120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11, + 114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98, + 95,104,101,120,8,118,97,108,117,101,109,97,120,2,255,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,18,0,0,12,116,105,110,116,101,103, + 101,114,101,100,105,116,3,114,49,50,13,111,112,116,105,111,110,115,119,105, + 100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11, + 111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119, + 102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105, + 110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111, + 119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114, + 97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99, + 111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,3,114,49,50,22,102,114,97,109,101, + 46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,12,116, + 102,95,121,99,101,110,116,101,114,101,100,0,16,102,114,97,109,101,46,99, + 97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,0,2,20,2,0,0,8,116,97,98,111,114,100,101, + 114,2,6,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100, + 115,95,121,3,132,0,9,98,111,117,110,100,115,95,99,120,2,113,9,98, + 111,117,110,100,115,95,99,121,2,22,11,102,111,110,116,46,104,101,105,103, + 104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95, + 102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15, + 102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112, + 95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7, + 11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110, + 98,95,104,101,120,8,118,97,108,117,101,109,97,120,2,255,13,114,101,102, + 102,111,110,116,104,101,105,103,104,116,2,18,0,0,12,116,105,110,116,101, + 103,101,114,101,100,105,116,2,115,114,13,111,112,116,105,111,110,115,119,105, + 100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11, + 111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119, + 102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105, + 110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111, + 119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114, + 97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99, + 111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,2,115,114,22,102,114,97,109,101,46, + 99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,12,116,102, + 95,121,99,101,110,116,101,114,101,100,0,16,102,114,97,109,101,46,99,97, + 112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108, + 95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105, + 101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109, + 101,1,2,0,2,0,2,14,2,0,0,8,116,97,98,111,114,100,101,114, + 2,7,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115, + 95,121,3,154,0,9,98,111,117,110,100,115,95,99,120,2,107,9,98,111, + 117,110,100,115,95,99,121,2,22,11,102,111,110,116,46,104,101,105,103,104, + 116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102, + 105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102, + 111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95, + 120,115,99,97,108,101,0,8,111,110,99,104,97,110,103,101,7,12,102,108, + 97,103,111,110,99,104,97,110,103,101,10,111,110,115,101,116,118,97,108,117, + 101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7, + 6,110,98,95,104,101,120,8,118,97,108,117,101,109,97,120,2,255,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,18,0,0,0,9,116,108, + 97,121,111,117,116,101,114,10,116,108,97,121,111,117,116,101,114,49,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97, + 98,111,114,100,101,114,2,24,8,98,111,117,110,100,115,95,120,2,0,8, + 98,111,117,110,100,115,95,121,2,40,9,98,111,117,110,100,115,95,99,120, + 2,110,9,98,111,117,110,100,115,95,99,121,3,198,0,12,111,112,116,105, + 111,110,115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97,110,100, + 120,11,111,115,99,95,115,104,114,105,110,107,120,11,111,115,99,95,101,120, + 112,97,110,100,121,11,111,115,99,95,115,104,114,105,110,107,121,0,9,102, + 111,110,116,46,110,97,109,101,6,11,115,116,102,95,100,101,102,97,117,108, + 116,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99, + 97,108,101,0,13,111,112,116,105,111,110,115,108,97,121,111,117,116,11,10, + 108,97,111,95,112,108,97,99,101,121,0,13,112,108,97,99,101,95,109,97, + 120,100,105,115,116,2,0,9,108,105,110,107,114,105,103,104,116,7,10,116, + 108,97,121,111,117,116,101,114,50,10,108,105,110,107,98,111,116,116,111,109, + 7,11,101,120,99,101,112,116,115,116,97,99,107,10,100,105,115,116,95,114, + 105,103,104,116,2,3,11,100,105,115,116,95,98,111,116,116,111,109,2,5, + 0,12,116,105,110,116,101,103,101,114,101,100,105,116,2,114,49,13,111,112, + 116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115, + 101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111, + 119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99, + 117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17, + 102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0, + 0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,2,114,49, + 22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108, + 97,103,115,11,12,116,102,95,121,99,101,110,116,101,114,101,100,0,16,102, + 114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95, + 114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99, + 111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117, + 116,101,114,102,114,97,109,101,1,2,0,2,0,2,13,2,0,0,8,116, + 97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,22,9,98,111,117,110,100,115,95,99, + 120,2,106,9,98,111,117,110,100,115,95,99,121,2,22,11,102,111,110,116, + 46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6, + 9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97, + 108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118, + 97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97, + 115,101,7,6,110,98,95,104,101,120,8,118,97,108,117,101,109,97,120,2, + 255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,18,0,0,12, + 116,105,110,116,101,103,101,114,101,100,105,116,2,114,48,13,111,112,116,105, + 111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102, + 111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95, + 97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102, + 111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115, + 111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116, + 115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,2,114,48,22,102, + 114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103, + 115,11,12,116,102,95,121,99,101,110,116,101,114,101,100,0,16,102,114,97, + 109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105, + 103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108, + 111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101, + 114,102,114,97,109,101,1,2,0,2,0,2,14,2,0,0,8,98,111,117, + 110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,120,2,107,9,98,111,117,110,100,115,95,99,121, + 2,22,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110, + 116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111, + 110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0, + 10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118, + 97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,118,97, + 108,117,101,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,18,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,2, + 114,52,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119, + 95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111, + 99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119, + 95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114, + 111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111, + 121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101, + 108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101, + 110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111, + 110,6,2,114,52,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116, + 101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101,110,116,101,114, + 101,100,0,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115, + 7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,14, + 2,0,0,8,116,97,98,111,114,100,101,114,2,4,8,98,111,117,110,100, + 115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,88,9,98,111,117, + 110,100,115,95,99,120,2,107,9,98,111,117,110,100,115,95,99,121,2,22, + 11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46, + 110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116, + 46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111, + 110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108, + 117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,118,97,108,117, + 101,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,18,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,2,114,51, + 13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109, + 111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117, + 115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97, + 114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119, + 102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111, + 2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116, + 4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 2,114,51,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120, + 116,102,108,97,103,115,11,12,116,102,95,121,99,101,110,116,101,114,101,100, + 0,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8, + 99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114, + 108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101, + 46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,14,2,0, + 0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117,110,100,115,95, + 120,2,0,8,98,111,117,110,100,115,95,121,2,66,9,98,111,117,110,100, + 115,95,99,120,2,107,9,98,111,117,110,100,115,95,99,121,2,22,11,102, + 111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97, + 109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120, + 115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115, + 101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101, + 4,98,97,115,101,7,6,110,98,95,104,101,120,8,118,97,108,117,101,109, + 97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,18, + 0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,2,114,50,13,111, + 112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117, + 115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13, + 111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114, + 111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111, + 99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100, + 103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255, + 17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7, + 0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,2,114, + 50,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102, + 108,97,103,115,11,12,116,102,95,121,99,101,110,116,101,114,101,100,0,16, + 102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112, + 95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95, + 99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,14,2,0,0,8, + 116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,2, + 0,8,98,111,117,110,100,115,95,121,2,44,9,98,111,117,110,100,115,95, + 99,120,2,107,9,98,111,117,110,100,115,95,99,121,2,22,11,102,111,110, + 116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101, + 6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99, + 97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116, + 118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98, + 97,115,101,7,6,110,98,95,104,101,120,8,118,97,108,117,101,109,97,120, + 2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,18,0,0, + 12,116,105,110,116,101,103,101,114,101,100,105,116,2,114,53,13,111,112,116, + 105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101, + 102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119, + 95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119, + 102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117, + 115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102, + 114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0, + 144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,2,114,53,22, + 102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97, + 103,115,11,12,116,102,95,121,99,101,110,116,101,114,101,100,0,16,102,114, + 97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114, + 105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111, + 108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,0,2,14,2,0,0,8,116,97, + 98,111,114,100,101,114,2,5,8,98,111,117,110,100,115,95,120,2,0,8, + 98,111,117,110,100,115,95,121,2,110,9,98,111,117,110,100,115,95,99,120, + 2,107,9,98,111,117,110,100,115,95,99,121,2,22,11,102,111,110,116,46, + 104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9, + 115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108, + 101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97, + 108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115, + 101,7,6,110,98,95,104,101,120,8,118,97,108,117,101,109,97,120,2,255, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,18,0,0,12,116, + 105,110,116,101,103,101,114,101,100,105,116,2,115,112,13,111,112,116,105,111, + 110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111, + 99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97, + 114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111, + 99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111, + 117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97, + 109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,2,115,112,22,102,114, + 97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115, + 11,12,116,102,95,121,99,101,110,116,101,114,101,100,0,16,102,114,97,109, + 101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103, + 104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111, + 114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,0,2,17,2,0,0,8,116,97,98,111, + 114,100,101,114,2,6,8,98,111,117,110,100,115,95,120,2,0,8,98,111, + 117,110,100,115,95,121,3,132,0,9,98,111,117,110,100,115,95,99,120,2, + 110,9,98,111,117,110,100,115,95,99,121,2,22,11,102,111,110,116,46,104, + 101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115, + 116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101, + 2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108, + 117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101, + 7,6,110,98,95,104,101,120,8,118,97,108,117,101,109,97,120,2,255,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,18,0,0,12,116,105, + 110,116,101,103,101,114,101,100,105,116,2,108,114,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109, + 101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,2,108,114,22,102,114,97, + 109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11, + 12,116,102,95,121,99,101,110,116,101,114,101,100,0,16,102,114,97,109,101, + 46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104, + 116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,0,2,10,2,0,0,8,116,97,98,111,114, + 100,101,114,2,7,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,3,154,0,9,98,111,117,110,100,115,95,99,120,2,103, + 9,98,111,117,110,100,115,95,99,121,2,22,11,102,111,110,116,46,104,101, + 105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116, + 102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2, + 1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117, + 101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7, + 6,110,98,95,104,101,120,8,118,97,108,117,101,109,97,120,2,255,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,18,0,0,12,116,105,110, + 116,101,103,101,114,101,100,105,116,2,112,99,13,111,112,116,105,111,110,115, + 119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117, + 115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114, + 111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117, + 115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116, + 17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12, + 102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101, + 46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114, + 97,109,101,46,99,97,112,116,105,111,110,6,2,112,99,22,102,114,97,109, + 101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,12, + 116,102,95,121,99,101,110,116,101,114,101,100,0,16,102,114,97,109,101,46, + 99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,0,2,17,2,0,0,8,116,97,98,111,114,100, + 101,114,2,8,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110, + 100,115,95,121,3,176,0,9,98,111,117,110,100,115,95,99,120,2,110,9, + 98,111,117,110,100,115,95,99,121,2,22,11,102,111,110,116,46,104,101,105, + 103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102, + 95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1, + 15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108, + 112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101, + 7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6, + 110,98,95,104,101,120,8,118,97,108,117,101,109,97,120,2,255,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,18,0,0,0,0,242,2,3, + 16,116,115,116,114,105,110,103,99,111,110,116,97,105,110,101,114,2,99,115, + 12,115,116,114,105,110,103,115,46,100,97,116,97,1,6,15,82,101,116,117, + 114,110,32,97,100,100,114,101,115,115,58,6,16,69,120,99,101,112,116,105, + 111,110,32,114,101,116,117,114,110,0,4,108,101,102,116,3,128,0,3,116, + 111,112,3,224,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tcpuavr32fo,''); +end. diff --git a/mseide-msegui/apps/ide/cpucpu32form.mfm b/mseide-msegui/apps/ide/cpucpu32form.mfm new file mode 100644 index 0000000..d47ee7f --- /dev/null +++ b/mseide-msegui/apps/ide/cpucpu32form.mfm @@ -0,0 +1,897 @@ +inherited cpucpu32fo: tcpucpu32fo + bounds_x = 245 + bounds_y = 202 + bounds_cx = 252 + bounds_cy = 291 + container.bounds = ( + 0 + 0 + 242 + 291 + ) + caption = 'CPU CPU32' + icon.image = { + 00000000020000001800000018000000C0020000000000000000000000000000 + 0000000000000000000000000000000000000000804CF09180808016804CF002 + 80808001E0E0E004D8DCD801A8A8A801888C8801B0B0B001E0E0E006C8C8C801 + B0B0B001D0D0D001E0E0E003F8FCF801804CF00280808001E0E0E003D8DCD801 + 40404001080C0801383838010808080150505001D8DCD801E0E0E00290909001 + 1014100100000002888C8801E0E0E003F8FCF801804CF00280808001E0E0E003 + 787C7801080C0801C8C8C801E0E0E001B8BCB8010004000190909001E0E0E002 + A8A8A80190909001B8BCB80100000001888C8801E0E0E003F8FCF801804CF002 + 80808001E0E0E003282C2801585C5801E0E0E0034848480140404001E0E0E005 + 00000001888C8801E0E0E003F8FCF801804CF00280808001E0E0E002D8DCD801 + 0004000188888801E0E0E0037070700118181801E0E0E00500000001888C8801 + E0E0E003F8FCF801804CF00280808001E0E0E002D0D0D0010000000190949001 + E0E0E0038080800108080801E0E0E00500000001888C8801E0E0E003F8FCF801 + 804CF00280808001E0E0E002D0D4D0010000000190949001E0E0E00380808001 + 08080801E0E0E00500000001888C8801E0E0E003F8FCF801804CF00280808001 + E0E0E002D8DCD8010808080180808001E0E0E003686C6801181C1801E0E0E005 + 00000001888C8801E0E0E003F8FCF801804CF00280808001E0E0E00330343001 + 50505001E0E0E00338383801484C4801E0E0E00500000001888C8801E0E0E003 + F8FCF801804CF00280808001E0E0E0039090900100040001A8ACA801E0E0E001 + 989C980100000001A0A4A001E0E0E002D0D4D001B8BCB8020000000178787801 + B8BCB801C8C8C801E0E0E001F8FCF801804CF00280808001E0E0E00468686801 + 00040001101010010004000178787801E0E0E003A0A4A0010000000550545001 + E0E0E001F8FCF801804CF00280808001E0E0E005D0D0D001B8B8B801D0D4D001 + E0E0E00CF8FCF801804CF002F8FCF816804CF061000000000000000000000000 + 000000000000000000000000FEFF7F00FEFF7F00FEFF7F00FEFF7F00FEFF7F00 + FEFF7F00FEFF7F00FEFF7F00FEFF7F00FEFF7F00FEFF7F00FEFF7F00FEFF7F00 + FEFF7F0000000000000000000000000000000000 + } + moduleclassname = 'tcpufo' + inherited on: tbooleanedit + bounds_x = 151 + bounds_y = 1 + end + inherited stoptime: tdatetimedisp + bounds_x = 0 + bounds_y = 0 + end + object tspacer1: tspacer[2] + taborder = 2 + visible = True + bounds_x = 0 + bounds_y = 18 + bounds_cx = 237 + bounds_cy = 254 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + linktop = stoptime + object c: tbooleanedit + Tag = 15 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'T' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + bounds_x = 9 + bounds_y = 3 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagssetvalue + end + object S: tbooleanedit + Tag = 13 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'S' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + bounds_x = 34 + bounds_y = 3 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagssetvalue + end + object tbooleanedit6: tbooleanedit + Tag = 9 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'I' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + bounds_x = 59 + bounds_y = 3 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagssetvalue + end + object tbooleanedit4: tbooleanedit + Tag = 4 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'X' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 3 + bounds_x = 84 + bounds_y = 3 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagssetvalue + end + object tbooleanedit7: tbooleanedit + Tag = 3 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'N' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 4 + bounds_x = 95 + bounds_y = 3 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagssetvalue + end + object tbooleanedit8: tbooleanedit + Tag = 2 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'Z' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 5 + bounds_x = 106 + bounds_y = 3 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagssetvalue + end + object tbooleanedit9: tbooleanedit + Tag = 1 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'V' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 6 + bounds_x = 117 + bounds_y = 3 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagssetvalue + end + object tbooleanedit10: tbooleanedit + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'C' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 7 + bounds_x = 128 + bounds_y = 3 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagssetvalue + end + object tbooleanedit5: tbooleanedit + Tag = 8 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 8 + bounds_x = 70 + bounds_y = 20 + bounds_cx = 11 + bounds_cy = 11 + onsetvalue = flagssetvalue + end + object tbooleanedit3: tbooleanedit + Tag = 10 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 9 + bounds_x = 48 + bounds_y = 20 + bounds_cx = 11 + bounds_cy = 11 + onsetvalue = flagssetvalue + end + object tbooleanedit2: tbooleanedit + Tag = 14 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 10 + bounds_x = 20 + bounds_y = 20 + bounds_cx = 11 + bounds_cy = 11 + onsetvalue = flagssetvalue + end + object tlayouter2: tlayouter + taborder = 11 + bounds_x = 118 + bounds_y = 34 + bounds_cx = 119 + bounds_cy = 220 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + dist_right = 3 + optionslayout = [lao_placey] + place_maxdist = 0 + object a1: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'a1' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + bounds_x = 0 + bounds_y = 20 + bounds_cx = 112 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object a0: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'a0' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 112 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object a4: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'a4' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + taborder = 2 + bounds_x = 0 + bounds_y = 80 + bounds_cx = 112 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object a3: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'a3' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + taborder = 3 + bounds_x = 0 + bounds_y = 60 + bounds_cx = 112 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object a2: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'a2' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + taborder = 4 + bounds_x = 0 + bounds_y = 40 + bounds_cx = 112 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object a5: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'a5' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + taborder = 5 + bounds_x = 0 + bounds_y = 100 + bounds_cx = 112 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object fp: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'fp' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 15 + 0 + ) + taborder = 6 + bounds_x = 0 + bounds_y = 120 + bounds_cx = 108 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object usp: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'usp' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 26 + 0 + ) + taborder = 7 + bounds_x = 0 + bounds_y = 140 + bounds_cx = 119 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object pc: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'pc' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 18 + 0 + ) + taborder = 8 + bounds_x = 0 + bounds_y = 160 + bounds_cx = 111 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object ssp: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'ssp' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 25 + 0 + ) + taborder = 9 + bounds_x = 0 + bounds_y = 180 + bounds_cx = 118 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object vbr: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'vbr' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 22 + 0 + ) + taborder = 10 + bounds_x = 0 + bounds_y = 200 + bounds_cx = 115 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + end + object tlayouter1: tlayouter + taborder = 12 + bounds_x = 0 + bounds_y = 34 + bounds_cx = 115 + bounds_cy = 220 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + linkright = tlayouter2 + dist_right = 3 + optionslayout = [lao_placey] + place_maxdist = 0 + object d1: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'd1' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + bounds_x = 0 + bounds_y = 20 + bounds_cx = 112 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object d0: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'd0' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 112 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object d4: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'd4' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + taborder = 2 + bounds_x = 0 + bounds_y = 80 + bounds_cx = 112 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object d3: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'd3' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + taborder = 3 + bounds_x = 0 + bounds_y = 60 + bounds_cx = 112 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object d2: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'd2' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + taborder = 4 + bounds_x = 0 + bounds_y = 40 + bounds_cx = 112 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object d5: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'd5' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + taborder = 5 + bounds_x = 0 + bounds_y = 100 + bounds_cx = 112 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object d6: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'd6' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + taborder = 6 + bounds_x = 0 + bounds_y = 120 + bounds_cx = 112 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object d7: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'd7' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + taborder = 7 + bounds_x = 0 + bounds_y = 140 + bounds_cx = 112 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object ps: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'ps' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 18 + 0 + ) + taborder = 8 + bounds_x = 0 + bounds_y = 160 + bounds_cx = 111 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object sfc: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'sfc' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 21 + 0 + ) + taborder = 9 + bounds_x = 0 + bounds_y = 180 + bounds_cx = 114 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onchange = flagonchange + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object dfc: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'dfc' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 22 + 0 + ) + taborder = 10 + bounds_x = 0 + bounds_y = 200 + bounds_cx = 115 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + end + end +end diff --git a/mseide-msegui/apps/ide/cpucpu32form.pas b/mseide-msegui/apps/ide/cpucpu32form.pas new file mode 100644 index 0000000..fd676fa --- /dev/null +++ b/mseide-msegui/apps/ide/cpucpu32form.pas @@ -0,0 +1,109 @@ +{ MSEide Copyright (c) 1999-2013 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit cpucpu32form; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,mseglob,mseguiglob,mseapplication,msestat,msemenus,msegui, + msegraphics, + msegraphutils,mseevent,mseclasses,mseforms,cpuform,msesplitter,msedataedits, + mseedit,msestrings,msetypes,msegraphedits; + +type + tcpucpu32fo = class(tcpufo) + tspacer1: tspacer; + c: tbooleanedit; + S: tbooleanedit; + tbooleanedit6: tbooleanedit; + tbooleanedit4: tbooleanedit; + tbooleanedit7: tbooleanedit; + tbooleanedit8: tbooleanedit; + tbooleanedit9: tbooleanedit; + tbooleanedit10: tbooleanedit; + tbooleanedit5: tbooleanedit; + tbooleanedit3: tbooleanedit; + tbooleanedit2: tbooleanedit; + tlayouter2: tlayouter; + a1: tintegeredit; + a0: tintegeredit; + a4: tintegeredit; + a3: tintegeredit; + a2: tintegeredit; + a5: tintegeredit; + fp: tintegeredit; + usp: tintegeredit; + pc: tintegeredit; + ssp: tintegeredit; + vbr: tintegeredit; + tlayouter1: tlayouter; + d1: tintegeredit; + d0: tintegeredit; + d4: tintegeredit; + d3: tintegeredit; + d2: tintegeredit; + d5: tintegeredit; + d6: tintegeredit; + d7: tintegeredit; + ps: tintegeredit; + sfc: tintegeredit; + dfc: tintegeredit; + procedure flagssetvalue(const sender: TObject; var avalue: Boolean; + var accept: Boolean); + procedure regsetvalue(const sender: TObject; var avalue: Integer; + var accept: Boolean); + procedure flagonchange(const sender: TObject); + public + constructor create(aowner: tcomponent); override; + function flagedit(const aindex: integer): tcustombooleanedit; override; + end; + +var + cpucpu32fo: tcpucpu32fo; + +implementation +uses + cpucpu32form_mfm; + +constructor tcpucpu32fo.create(aowner: tcomponent); +begin + inherited create(aowner); + fflagswidget:= ps; +end; + +procedure tcpucpu32fo.flagssetvalue(const sender: TObject; var avalue: Boolean; + var accept: Boolean); +begin + doflagsetvalue(sender,avalue,accept); +end; + +procedure tcpucpu32fo.regsetvalue(const sender: TObject; var avalue: Integer; + var accept: Boolean); +begin + doregsetvalue(sender,avalue,accept); +end; + +procedure tcpucpu32fo.flagonchange(const sender: TObject); +begin + doflagonchange(sender); +end; + +function tcpucpu32fo.flagedit(const aindex: integer): tcustombooleanedit; +begin + result:= c.tagitem(aindex); +end; + +end. diff --git a/mseide-msegui/apps/ide/cpucpu32form_mfm.pas b/mseide-msegui/apps/ide/cpucpu32form_mfm.pas new file mode 100644 index 0000000..be302a0 --- /dev/null +++ b/mseide-msegui/apps/ide/cpucpu32form_mfm.pas @@ -0,0 +1,793 @@ +unit cpucpu32form_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,cpucpu32form; + +const + objdata: record size: integer; data: array[0..15509] of byte end = + (size: 15510; data: ( + 84,80,70,48,241,11,116,99,112,117,99,112,117,51,50,102,111,10,99,112, + 117,99,112,117,51,50,102,111,8,98,111,117,110,100,115,95,120,3,245,0, + 8,98,111,117,110,100,115,95,121,3,202,0,9,98,111,117,110,100,115,95, + 99,120,3,252,0,9,98,111,117,110,100,115,95,99,121,3,35,1,16,99, + 111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0, + 3,242,0,3,35,1,0,7,99,97,112,116,105,111,110,6,9,67,80,85, + 32,67,80,85,51,50,10,105,99,111,110,46,105,109,97,103,101,10,84,3, + 0,0,0,0,0,0,2,0,0,0,24,0,0,0,24,0,0,0,192,2, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,76,240,145,128,128, + 128,22,128,76,240,2,128,128,128,1,224,224,224,4,216,220,216,1,168,168, + 168,1,136,140,136,1,176,176,176,1,224,224,224,6,200,200,200,1,176,176, + 176,1,208,208,208,1,224,224,224,3,248,252,248,1,128,76,240,2,128,128, + 128,1,224,224,224,3,216,220,216,1,64,64,64,1,8,12,8,1,56,56, + 56,1,8,8,8,1,80,80,80,1,216,220,216,1,224,224,224,2,144,144, + 144,1,16,20,16,1,0,0,0,2,136,140,136,1,224,224,224,3,248,252, + 248,1,128,76,240,2,128,128,128,1,224,224,224,3,120,124,120,1,8,12, + 8,1,200,200,200,1,224,224,224,1,184,188,184,1,0,4,0,1,144,144, + 144,1,224,224,224,2,168,168,168,1,144,144,144,1,184,188,184,1,0,0, + 0,1,136,140,136,1,224,224,224,3,248,252,248,1,128,76,240,2,128,128, + 128,1,224,224,224,3,40,44,40,1,88,92,88,1,224,224,224,3,72,72, + 72,1,64,64,64,1,224,224,224,5,0,0,0,1,136,140,136,1,224,224, + 224,3,248,252,248,1,128,76,240,2,128,128,128,1,224,224,224,2,216,220, + 216,1,0,4,0,1,136,136,136,1,224,224,224,3,112,112,112,1,24,24, + 24,1,224,224,224,5,0,0,0,1,136,140,136,1,224,224,224,3,248,252, + 248,1,128,76,240,2,128,128,128,1,224,224,224,2,208,208,208,1,0,0, + 0,1,144,148,144,1,224,224,224,3,128,128,128,1,8,8,8,1,224,224, + 224,5,0,0,0,1,136,140,136,1,224,224,224,3,248,252,248,1,128,76, + 240,2,128,128,128,1,224,224,224,2,208,212,208,1,0,0,0,1,144,148, + 144,1,224,224,224,3,128,128,128,1,8,8,8,1,224,224,224,5,0,0, + 0,1,136,140,136,1,224,224,224,3,248,252,248,1,128,76,240,2,128,128, + 128,1,224,224,224,2,216,220,216,1,8,8,8,1,128,128,128,1,224,224, + 224,3,104,108,104,1,24,28,24,1,224,224,224,5,0,0,0,1,136,140, + 136,1,224,224,224,3,248,252,248,1,128,76,240,2,128,128,128,1,224,224, + 224,3,48,52,48,1,80,80,80,1,224,224,224,3,56,56,56,1,72,76, + 72,1,224,224,224,5,0,0,0,1,136,140,136,1,224,224,224,3,248,252, + 248,1,128,76,240,2,128,128,128,1,224,224,224,3,144,144,144,1,0,4, + 0,1,168,172,168,1,224,224,224,1,152,156,152,1,0,0,0,1,160,164, + 160,1,224,224,224,2,208,212,208,1,184,188,184,2,0,0,0,1,120,120, + 120,1,184,188,184,1,200,200,200,1,224,224,224,1,248,252,248,1,128,76, + 240,2,128,128,128,1,224,224,224,4,104,104,104,1,0,4,0,1,16,16, + 16,1,0,4,0,1,120,120,120,1,224,224,224,3,160,164,160,1,0,0, + 0,5,80,84,80,1,224,224,224,1,248,252,248,1,128,76,240,2,128,128, + 128,1,224,224,224,5,208,208,208,1,184,184,184,1,208,212,208,1,224,224, + 224,12,248,252,248,1,128,76,240,2,248,252,248,22,128,76,240,97,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,254,255,127,0,254,255,127,0,254,255,127,0,254,255,127,0,254,255, + 127,0,254,255,127,0,254,255,127,0,254,255,127,0,254,255,127,0,254,255, + 127,0,254,255,127,0,254,255,127,0,254,255,127,0,254,255,127,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,109,111,100,117,108, + 101,99,108,97,115,115,110,97,109,101,6,6,116,99,112,117,102,111,0,241, + 12,116,98,111,111,108,101,97,110,101,100,105,116,2,111,110,8,98,111,117, + 110,100,115,95,120,3,151,0,8,98,111,117,110,100,115,95,121,2,1,0, + 0,241,13,116,100,97,116,101,116,105,109,101,100,105,115,112,8,115,116,111, + 112,116,105,109,101,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,2,0,0,0,242,2,2,7,116,115,112,97,99,101,114, + 8,116,115,112,97,99,101,114,49,8,116,97,98,111,114,100,101,114,2,2, + 7,118,105,115,105,98,108,101,9,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,18,9,98,111,117,110,100,115,95,99, + 120,3,237,0,9,98,111,117,110,100,115,95,99,121,3,254,0,12,111,112, + 116,105,111,110,115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97, + 110,100,120,11,111,115,99,95,115,104,114,105,110,107,120,11,111,115,99,95, + 101,120,112,97,110,100,121,11,111,115,99,95,115,104,114,105,110,107,121,0, + 7,108,105,110,107,116,111,112,7,8,115,116,111,112,116,105,109,101,0,12, + 116,98,111,111,108,101,97,110,101,100,105,116,1,99,3,84,97,103,2,15, + 5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101, + 118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108, + 105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116, + 105,111,110,6,1,84,16,102,114,97,109,101,46,99,97,112,116,105,111,110, + 112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111, + 15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2, + 0,2,0,0,8,98,111,117,110,100,115,95,120,2,9,8,98,111,117,110, + 100,115,95,121,2,3,9,98,111,117,110,100,115,95,99,120,2,11,9,98, + 111,117,110,100,115,95,99,121,2,28,10,111,110,115,101,116,118,97,108,117, + 101,7,13,102,108,97,103,115,115,101,116,118,97,108,117,101,0,0,12,116, + 98,111,111,108,101,97,110,101,100,105,116,1,83,3,84,97,103,2,13,5, + 99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,1,83,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112, + 111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0, + 2,0,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100, + 115,95,120,2,34,8,98,111,117,110,100,115,95,121,2,3,9,98,111,117, + 110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95,99,121,2,28, + 10,111,110,115,101,116,118,97,108,117,101,7,13,102,108,97,103,115,115,101, + 116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110,101,100,105, + 116,13,116,98,111,111,108,101,97,110,101,100,105,116,54,3,84,97,103,2, + 9,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,1,73,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17, + 2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117, + 110,100,115,95,120,2,59,8,98,111,117,110,100,115,95,121,2,3,9,98, + 111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95,99,121, + 2,28,10,111,110,115,101,116,118,97,108,117,101,7,13,102,108,97,103,115, + 115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110,101, + 100,105,116,13,116,98,111,111,108,101,97,110,101,100,105,116,52,3,84,97, + 103,2,4,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101, + 46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111, + 114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99, + 97,112,116,105,111,110,6,1,88,16,102,114,97,109,101,46,99,97,112,116, + 105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,3,8,98, + 111,117,110,100,115,95,120,2,84,8,98,111,117,110,100,115,95,121,2,3, + 9,98,111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95, + 99,121,2,28,10,111,110,115,101,116,118,97,108,117,101,7,13,102,108,97, + 103,115,115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97, + 110,101,100,105,116,13,116,98,111,111,108,101,97,110,101,100,105,116,55,3, + 84,97,103,2,3,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97, + 109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111, + 108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,1,78,16,102,114,97,109,101,46,99,97, + 112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,4, + 8,98,111,117,110,100,115,95,120,2,95,8,98,111,117,110,100,115,95,121, + 2,3,9,98,111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100, + 115,95,99,121,2,28,10,111,110,115,101,116,118,97,108,117,101,7,13,102, + 108,97,103,115,115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108, + 101,97,110,101,100,105,116,13,116,98,111,111,108,101,97,110,101,100,105,116, + 56,3,84,97,103,2,2,5,99,111,108,111,114,4,3,0,0,128,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,1,90,16,102,114,97,109,101,46, + 99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108, + 95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105, + 101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109, + 101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114, + 2,5,8,98,111,117,110,100,115,95,120,2,106,8,98,111,117,110,100,115, + 95,121,2,3,9,98,111,117,110,100,115,95,99,120,2,11,9,98,111,117, + 110,100,115,95,99,121,2,28,10,111,110,115,101,116,118,97,108,117,101,7, + 13,102,108,97,103,115,115,101,116,118,97,108,117,101,0,0,12,116,98,111, + 111,108,101,97,110,101,100,105,116,13,116,98,111,111,108,101,97,110,101,100, + 105,116,57,3,84,97,103,2,1,5,99,111,108,111,114,4,3,0,0,128, + 12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109, + 101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,1,86,16,102,114,97,109, + 101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100, + 101,114,2,6,8,98,111,117,110,100,115,95,120,2,117,8,98,111,117,110, + 100,115,95,121,2,3,9,98,111,117,110,100,115,95,99,120,2,11,9,98, + 111,117,110,100,115,95,99,121,2,28,10,111,110,115,101,116,118,97,108,117, + 101,7,13,102,108,97,103,115,115,101,116,118,97,108,117,101,0,0,12,116, + 98,111,111,108,101,97,110,101,100,105,116,14,116,98,111,111,108,101,97,110, + 101,100,105,116,49,48,5,99,111,108,111,114,4,3,0,0,128,12,102,114, + 97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99, + 111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,1,67,16,102,114,97,109,101,46,99, + 97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95, + 108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101, + 110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101, + 1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2, + 7,8,98,111,117,110,100,115,95,120,3,128,0,8,98,111,117,110,100,115, + 95,121,2,3,9,98,111,117,110,100,115,95,99,120,2,11,9,98,111,117, + 110,100,115,95,99,121,2,28,10,111,110,115,101,116,118,97,108,117,101,7, + 13,102,108,97,103,115,115,101,116,118,97,108,117,101,0,0,12,116,98,111, + 111,108,101,97,110,101,100,105,116,13,116,98,111,111,108,101,97,110,101,100, + 105,116,53,3,84,97,103,2,8,5,99,111,108,111,114,4,3,0,0,128, + 12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109, + 101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,16,102, + 114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95, + 116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108, + 111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,8, + 8,98,111,117,110,100,115,95,120,2,70,8,98,111,117,110,100,115,95,121, + 2,20,9,98,111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100, + 115,95,99,121,2,11,10,111,110,115,101,116,118,97,108,117,101,7,13,102, + 108,97,103,115,115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108, + 101,97,110,101,100,105,116,13,116,98,111,111,108,101,97,110,101,100,105,116, + 51,3,84,97,103,2,10,5,99,111,108,111,114,4,3,0,0,128,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,16,102,114,97, + 109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111, + 112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,9,8,98, + 111,117,110,100,115,95,120,2,48,8,98,111,117,110,100,115,95,121,2,20, + 9,98,111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95, + 99,121,2,11,10,111,110,115,101,116,118,97,108,117,101,7,13,102,108,97, + 103,115,115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97, + 110,101,100,105,116,13,116,98,111,111,108,101,97,110,101,100,105,116,50,3, + 84,97,103,2,14,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97, + 109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111, + 108,111,114,99,108,105,101,110,116,4,7,0,0,144,16,102,114,97,109,101, + 46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,10,8,98,111,117, + 110,100,115,95,120,2,20,8,98,111,117,110,100,115,95,121,2,20,9,98, + 111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95,99,121, + 2,11,10,111,110,115,101,116,118,97,108,117,101,7,13,102,108,97,103,115, + 115,101,116,118,97,108,117,101,0,0,9,116,108,97,121,111,117,116,101,114, + 10,116,108,97,121,111,117,116,101,114,50,8,116,97,98,111,114,100,101,114, + 2,11,8,98,111,117,110,100,115,95,120,2,118,8,98,111,117,110,100,115, + 95,121,2,34,9,98,111,117,110,100,115,95,99,120,2,119,9,98,111,117, + 110,100,115,95,99,121,3,220,0,12,111,112,116,105,111,110,115,115,99,97, + 108,101,11,11,111,115,99,95,101,120,112,97,110,100,120,11,111,115,99,95, + 115,104,114,105,110,107,120,11,111,115,99,95,101,120,112,97,110,100,121,11, + 111,115,99,95,115,104,114,105,110,107,121,0,10,100,105,115,116,95,114,105, + 103,104,116,2,3,13,111,112,116,105,111,110,115,108,97,121,111,117,116,11, + 10,108,97,111,95,112,108,97,99,101,121,0,13,112,108,97,99,101,95,109, + 97,120,100,105,115,116,2,0,0,12,116,105,110,116,101,103,101,114,101,100, + 105,116,2,97,49,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,2,97,49,16,102,114,97,109,101,46,99,97,112,116,105, + 111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101, + 118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2, + 0,2,0,2,19,2,0,0,8,98,111,117,110,100,115,95,120,2,0,8, + 98,111,117,110,100,115,95,121,2,20,9,98,111,117,110,100,115,95,99,120, + 2,112,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110, + 116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111, + 110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0, + 10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118, + 97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,3,109,97, + 120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0, + 0,12,116,105,110,116,101,103,101,114,101,100,105,116,2,97,48,13,111,112, + 116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115, + 101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111, + 119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99, + 117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17, + 102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0, + 0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,2,97,48, + 16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99, + 112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108, + 95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,19,2,0,0, + 8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,2,112,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9, + 102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100, + 11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46, + 108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97, + 108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115, + 101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120, + 3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,16,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,2,97,52, + 13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109, + 111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117, + 115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97, + 114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119, + 102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111, + 2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116, + 4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 2,97,52,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115, + 7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,19, + 2,0,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100, + 115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,80,9,98,111,117, + 110,100,115,95,99,120,2,112,11,102,111,110,116,46,104,101,105,103,104,116, + 2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105, + 120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111, + 110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120, + 115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114, + 101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95, + 104,101,120,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,16,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116, + 2,97,51,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,2,97,51,16,102,114,97,109,101,46,99,97,112,116,105,111,110, + 112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101, + 108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2, + 0,2,19,2,0,0,8,116,97,98,111,114,100,101,114,2,3,8,98,111, + 117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,60,9, + 98,111,117,110,100,115,95,99,120,2,112,11,102,111,110,116,46,104,101,105, + 103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102, + 95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1, + 15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108, + 112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101, + 7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6, + 110,98,95,104,101,120,3,109,97,120,2,255,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,16,0,0,12,116,105,110,116,101,103,101,114,101, + 100,105,116,2,97,50,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119, + 95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46, + 108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114, + 99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,2,97,50,16,102,114,97,109,101,46,99,97,112,116, + 105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,0,2,19,2,0,0,8,116,97,98,111,114,100,101,114,2,4, + 8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121, + 2,40,9,98,111,117,110,100,115,95,99,120,2,112,11,102,111,110,116,46, + 104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9, + 115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108, + 101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97, + 108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115, + 101,7,6,110,98,95,104,101,120,3,109,97,120,2,255,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,16,0,0,12,116,105,110,116,101,103, + 101,114,101,100,105,116,2,97,53,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111, + 119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102, + 111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110, + 16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119, + 95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97, + 109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111, + 108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,2,97,53,16,102,114,97,109,101,46,99, + 97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,0,2,19,2,0,0,8,116,97,98,111,114,100,101, + 114,2,5,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100, + 115,95,121,2,100,9,98,111,117,110,100,115,95,99,120,2,112,11,102,111, + 110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109, + 101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115, + 99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101, + 116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4, + 98,97,115,101,7,6,110,98,95,104,101,120,3,109,97,120,2,255,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,12,116,105,110, + 116,101,103,101,114,101,100,105,116,2,102,112,13,111,112,116,105,111,110,115, + 119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117, + 115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114, + 111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117, + 115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116, + 17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12, + 102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101, + 46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114, + 97,109,101,46,99,97,112,116,105,111,110,6,2,102,112,16,102,114,97,109, + 101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103, + 104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111, + 114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,0,2,15,2,0,0,8,116,97,98,111, + 114,100,101,114,2,6,8,98,111,117,110,100,115,95,120,2,0,8,98,111, + 117,110,100,115,95,121,2,120,9,98,111,117,110,100,115,95,99,120,2,108, + 11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46, + 110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116, + 46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111, + 110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108, + 117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,3,109,97,120,2, + 255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,12, + 116,105,110,116,101,103,101,114,101,100,105,116,3,117,115,112,13,111,112,116, + 105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101, + 102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119, + 95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119, + 102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117, + 115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102, + 114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0, + 144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,3,117,115,112, + 16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99, + 112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108, + 95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,26,2,0,0, + 8,116,97,98,111,114,100,101,114,2,7,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,3,140,0,9,98,111,117,110,100, + 115,95,99,120,2,119,11,102,111,110,116,46,104,101,105,103,104,116,2,14, + 9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101, + 100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99, + 97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103, + 115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101, + 120,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,16,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,2,112, + 99,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95, + 97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111, + 119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121, + 119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108, + 111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110, + 116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,2,112,99,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111, + 115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111, + 15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2, + 18,2,0,0,8,116,97,98,111,114,100,101,114,2,8,8,98,111,117,110, + 100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,3,160,0,9,98, + 111,117,110,100,115,95,99,120,2,111,11,102,111,110,116,46,104,101,105,103, + 104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95, + 102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15, + 102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112, + 95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7, + 11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110, + 98,95,104,101,120,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,16,0,0,12,116,105,110,116,101,103,101,114,101,100, + 105,116,3,115,115,112,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119, + 95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46, + 108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114, + 99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,3,115,115,112,16,102,114,97,109,101,46,99,97,112, + 116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95, + 108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101, + 110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101, + 1,2,0,2,0,2,25,2,0,0,8,116,97,98,111,114,100,101,114,2, + 9,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95, + 121,3,180,0,9,98,111,117,110,100,115,95,99,120,2,118,11,102,111,110, + 116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101, + 6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99, + 97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116, + 118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98, + 97,115,101,7,6,110,98,95,104,101,120,3,109,97,120,2,255,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,12,116,105,110,116, + 101,103,101,114,101,100,105,116,3,118,98,114,13,111,112,116,105,111,110,115, + 119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117, + 115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114, + 111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117, + 115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116, + 17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12, + 102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101, + 46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114, + 97,109,101,46,99,97,112,116,105,111,110,6,3,118,98,114,16,102,114,97, + 109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105, + 103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108, + 111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101, + 114,102,114,97,109,101,1,2,0,2,0,2,22,2,0,0,8,116,97,98, + 111,114,100,101,114,2,10,8,98,111,117,110,100,115,95,120,2,0,8,98, + 111,117,110,100,115,95,121,3,200,0,9,98,111,117,110,100,115,95,99,120, + 2,115,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110, + 116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111, + 110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0, + 10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118, + 97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,3,109,97, + 120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0, + 0,0,9,116,108,97,121,111,117,116,101,114,10,116,108,97,121,111,117,116, + 101,114,49,8,116,97,98,111,114,100,101,114,2,12,8,98,111,117,110,100, + 115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,34,9,98,111,117, + 110,100,115,95,99,120,2,115,9,98,111,117,110,100,115,95,99,121,3,220, + 0,12,111,112,116,105,111,110,115,115,99,97,108,101,11,11,111,115,99,95, + 101,120,112,97,110,100,120,11,111,115,99,95,115,104,114,105,110,107,120,11, + 111,115,99,95,101,120,112,97,110,100,121,11,111,115,99,95,115,104,114,105, + 110,107,121,0,9,108,105,110,107,114,105,103,104,116,7,10,116,108,97,121, + 111,117,116,101,114,50,10,100,105,115,116,95,114,105,103,104,116,2,3,13, + 111,112,116,105,111,110,115,108,97,121,111,117,116,11,10,108,97,111,95,112, + 108,97,99,101,121,0,13,112,108,97,99,101,95,109,97,120,100,105,115,116, + 2,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,2,100,49,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111, + 117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114, + 114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102, + 111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,2, + 100,49,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7, + 8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102, + 114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109, + 101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,19,2, + 0,0,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115, + 95,121,2,20,9,98,111,117,110,100,115,95,99,120,2,112,11,102,111,110, + 116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101, + 6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99, + 97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116, + 118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98, + 97,115,101,7,6,110,98,95,104,101,120,3,109,97,120,2,255,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,12,116,105,110,116, + 101,103,101,114,101,100,105,116,2,100,48,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115, + 105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,2,100,48,16,102,114,97,109,101, + 46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104, + 116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,0,2,19,2,0,0,8,116,97,98,111,114, + 100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,112,11, + 102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110, + 97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46, + 120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112, + 114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110, + 115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117, + 101,4,98,97,115,101,7,6,110,98,95,104,101,120,3,109,97,120,2,255, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,12,116, + 105,110,116,101,103,101,114,101,100,105,116,2,100,52,13,111,112,116,105,111, + 110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111, + 99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97, + 114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111, + 99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111, + 117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97, + 109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,2,100,52,16,102,114, + 97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114, + 105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111, + 108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,0,2,19,2,0,0,8,116,97, + 98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,2,0,8, + 98,111,117,110,100,115,95,121,2,80,9,98,111,117,110,100,115,95,99,120, + 2,112,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110, + 116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111, + 110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0, + 10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118, + 97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,3,109,97, + 120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0, + 0,12,116,105,110,116,101,103,101,114,101,100,105,116,2,100,51,13,111,112, + 116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115, + 101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111, + 119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99, + 117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17, + 102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0, + 0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,2,100,51, + 16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99, + 112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108, + 95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,19,2,0,0, + 8,116,97,98,111,114,100,101,114,2,3,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,2,60,9,98,111,117,110,100,115, + 95,99,120,2,112,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9, + 102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100, + 11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46, + 108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97, + 108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115, + 101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120, + 3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,16,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,2,100,50, + 13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109, + 111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117, + 115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97, + 114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119, + 102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111, + 2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116, + 4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 2,100,50,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115, + 7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,19, + 2,0,0,8,116,97,98,111,114,100,101,114,2,4,8,98,111,117,110,100, + 115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,40,9,98,111,117, + 110,100,115,95,99,120,2,112,11,102,111,110,116,46,104,101,105,103,104,116, + 2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105, + 120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111, + 110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120, + 115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114, + 101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95, + 104,101,120,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,16,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116, + 2,100,53,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,2,100,53,16,102,114,97,109,101,46,99,97,112,116,105,111,110, + 112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101, + 108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2, + 0,2,19,2,0,0,8,116,97,98,111,114,100,101,114,2,5,8,98,111, + 117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,100,9, + 98,111,117,110,100,115,95,99,120,2,112,11,102,111,110,116,46,104,101,105, + 103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102, + 95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1, + 15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108, + 112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101, + 7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6, + 110,98,95,104,101,120,3,109,97,120,2,255,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,16,0,0,12,116,105,110,116,101,103,101,114,101, + 100,105,116,2,100,54,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119, + 95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46, + 108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114, + 99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,2,100,54,16,102,114,97,109,101,46,99,97,112,116, + 105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,0,2,19,2,0,0,8,116,97,98,111,114,100,101,114,2,6, + 8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121, + 2,120,9,98,111,117,110,100,115,95,99,120,2,112,11,102,111,110,116,46, + 104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9, + 115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108, + 101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97, + 108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115, + 101,7,6,110,98,95,104,101,120,3,109,97,120,2,255,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,16,0,0,12,116,105,110,116,101,103, + 101,114,101,100,105,116,2,100,55,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111, + 119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102, + 111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110, + 16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119, + 95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97, + 109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111, + 108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,2,100,55,16,102,114,97,109,101,46,99, + 97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,0,2,19,2,0,0,8,116,97,98,111,114,100,101, + 114,2,7,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100, + 115,95,121,3,140,0,9,98,111,117,110,100,115,95,99,120,2,112,11,102, + 111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97, + 109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120, + 115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115, + 101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101, + 4,98,97,115,101,7,6,110,98,95,104,101,120,3,109,97,120,2,255,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,12,116,105, + 110,116,101,103,101,114,101,100,105,116,2,112,115,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109, + 101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,2,112,115,16,102,114,97, + 109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105, + 103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108, + 111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101, + 114,102,114,97,109,101,1,2,0,2,0,2,18,2,0,0,8,116,97,98, + 111,114,100,101,114,2,8,8,98,111,117,110,100,115,95,120,2,0,8,98, + 111,117,110,100,115,95,121,3,160,0,9,98,111,117,110,100,115,95,99,120, + 2,111,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110, + 116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111, + 110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0, + 10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118, + 97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,98,105, + 116,99,111,117,110,116,2,16,3,109,97,120,2,255,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,16,0,0,12,116,105,110,116,101,103,101, + 114,101,100,105,116,3,115,102,99,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111, + 119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102, + 111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110, + 16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119, + 95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97, + 109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111, + 108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,3,115,102,99,16,102,114,97,109,101,46, + 99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,0,2,21,2,0,0,8,116,97,98,111,114,100, + 101,114,2,9,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110, + 100,115,95,121,3,180,0,9,98,111,117,110,100,115,95,99,120,2,114,11, + 102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110, + 97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46, + 120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112, + 114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,8,111,110, + 99,104,97,110,103,101,7,12,102,108,97,103,111,110,99,104,97,110,103,101, + 10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118, + 97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,3,109,97, + 120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0, + 0,12,116,105,110,116,101,103,101,114,101,100,105,116,3,100,102,99,13,111, + 112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117, + 115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13, + 111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114, + 111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111, + 99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100, + 103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255, + 17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7, + 0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,3,100, + 102,99,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7, + 8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102, + 114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109, + 101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,22,2, + 0,0,8,116,97,98,111,114,100,101,114,2,10,8,98,111,117,110,100,115, + 95,120,2,0,8,98,111,117,110,100,115,95,121,3,200,0,9,98,111,117, + 110,100,115,95,99,120,2,115,11,102,111,110,116,46,104,101,105,103,104,116, + 2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105, + 120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111, + 110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120, + 115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114, + 101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95, + 104,101,120,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,16,0,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tcpucpu32fo,''); +end. diff --git a/mseide-msegui/apps/ide/cpuform.mfm b/mseide-msegui/apps/ide/cpuform.mfm new file mode 100644 index 0000000..29475fe --- /dev/null +++ b/mseide-msegui/apps/ide/cpuform.mfm @@ -0,0 +1,99 @@ +object cpufo: tcpufo + optionswidget = [ow_mousefocus, ow_arrowfocus, ow_mousewheel, ow_destroywidgets, ow_hinton] + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_floatbutton, go_topbutton, go_backgroundbutton, go_nolockbutton, go_buttonhints] + visible = False + bounds_x = 192 + bounds_y = 451 + bounds_cx = 387 + bounds_cy = 207 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 377 + 207 + ) + dragdock.splitter_size = 0 + dragdock.caption = 'CPU' + dragdock.optionsdock = [od_savepos, od_savezorder, od_canmove, od_canfloat, od_candock, od_propsize, od_captionhint] + options = [fo_savepos, fo_savezorder, fo_savestate] + statfile = mainfo.projectstatfile + caption = 'CPU' + icon.transparentcolor = -2147483642 + icon.options = [bmo_masked] + icon.image = { + 000000000200000018000000180000003C030000000000000000000000000000 + 0000000000000000000000000000000000000000D0D0D0607C7C7C19D9D9D916 + FFFFFF017C7C7C01D9D9D904BFBFBF01D9D9D906B1B1B101D9D9D905BCBCBC01 + D9D9D904FFFFFF017C7C7C01D9D9D9027D7D7D01101010010707070128282801 + CCCCCC01D9D9D9039797970105050501D9D9D9039C9C9C011717170107070701 + 18181801B8B8B801D9D9D902FFFFFF017C7C7C01D9D9D901CCCCCC0110101001 + 89898901C2C2C2012626260156565601D9D9D902808080010D0D0D0101010101 + D9D9D9032222220161616101CFCFCF013C3C3C0136363601D9D9D902FFFFFF01 + 7C7C7C01D9D9D901868686011F1F1F01D9D9D902828282011C1C1C01D9D9D901 + AEAEAE010B0B0B016F6F6F0101010101D9D9D902BBBBBB0109090901D5D5D501 + D9D9D901B4B4B40106060601D9D9D902FFFFFF017C7C7C01D9D9D90169696901 + 35353501D9D9D902A8A8A8010D0D0D01D9D9D901CCCCCC01C5C5C501C8C8C801 + 01010101D9D9D902959595011A1A1A01D9D9D90303030301BFBFBF01D9D9D901 + FFFFFF017C7C7C01D9D9D901525252013E3E3E01D9D9D902BBBBBB0103030301 + D9D9D903C8C8C80101010101D9D9D9027979790122222201D9D9D9030A0A0A01 + A7A7A701D9D9D901FFFFFF017C7C7C01D9D9D9015B5B5B0138383801D9D9D902 + AEAEAE010B0B0B01D9D9D903C8C8C80101010101D9D9D902848484011D1D1D01 + D9D9D90305050501BFBFBF01D9D9D901FFFFFF017C7C7C01D9D9D9016F6F6F01 + 28282801D9D9D902929292011A1A1A01D9D9D903C8C8C80101010101D9D9D902 + 9C9C9C0110101001D9D9D902C8C8C80104040401D9D9D902FFFFFF017C7C7C01 + D9D9D901B9B9B9010A0A0A01BFBFBF01D9D9D901414141013F3F3F01D9D9D903 + C8C8C80101010101D9D9D902D5D5D5010F0F0F019A9A9A01D9D9D90163636301 + 23232301D9D9D902FFFFFF017C7C7C01D9D9D902494949010909090123232301 + 0B0B0B01BFBFBF01D9D9D903C8C8C80101010101D9D9D9036B6B6B0105050501 + 2A2A2A01040404019B9B9B01D9D9D902FFFFFF017C7C7C01D9D9D9038D8D8D01 + 79797901CFCFCF01D9D9D904D5D5D50189898901D9D9D9049C9C9C0173737301 + C2C2C201D9D9D903FFFFFF017C7C7C01D9D9D916FFFFFF017C7C7C01D9D9D916 + FFFFFF017C7C7C01FFFFFF17D0D0D06000000000000000000000000000000000 + FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00 + FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00 + 00000000000000000000000000000000 + } + onshow = cpuonshow + onasyncevent = asynceventexe + onstatupdate = updastat + onstatafterread = aftread + onstatbeforewrite = befwrite + moduleclassname = 'tdockform' + object on: tbooleanedit + Tag = -1 + frame.caption = 'CPU &on' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 48 + 2 + ) + bounds_x = 7 + bounds_y = 9 + bounds_cx = 61 + bounds_cy = 16 + onchange = ononchange + value = True + end + object stoptime: tdatetimedisp + frame.localprops = [] + frame.localprops1 = [] + taborder = 1 + bounds_x = 80 + bounds_y = 8 + bounds_cx = 124 + bounds_cy = 18 + textflags = [tf_xcentered, tf_right, tf_ycentered] + format = 'yy-mm-dd hh:mm:ss' + kind = dtk_datetime + value = -Inf + reffontheight = 14 + end +end diff --git a/mseide-msegui/apps/ide/cpuform.pas b/mseide-msegui/apps/ide/cpuform.pas new file mode 100644 index 0000000..d4e5b4d --- /dev/null +++ b/mseide-msegui/apps/ide/cpuform.pas @@ -0,0 +1,372 @@ +{ MSEide Copyright (c) 1999-2013 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit cpuform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +uses + classes,mclasses,msegui,mseclasses,mseforms,msegdbutils,msetypes,msedataedits, + msegraphics,msegraphedits,mseevent,msemenus,msestat,msedispwidgets; + +type + + tcpufo = class(tdockform) + on: tbooleanedit; + stoptime: tdatetimedisp; + procedure cpuonshow(const sender: TObject); + procedure ononchange(const sender: TObject); + procedure updastat(const sender: TObject; const filer: tstatfiler); virtual; + procedure aftread(const sender: TObject); + procedure befwrite(const sender: TObject); + procedure asynceventexe(const sender: TObject; var atag: Integer); + protected + fflagswidget: tintegeredit; + fflagswidget64: tint64edit; + fregisternames: stringarty; + fedits: array of tdataedit; + irqoffvalue: boolean; + fneedsrefresh: boolean; + procedure doregsetvalue(const sender: TObject; var avalue: Integer; var accept: Boolean); + procedure doregset64value(const sender: TObject; var avalue: Int64; var accept: Boolean); + procedure doflagsetvalue(const sender: TObject; + var avalue: Boolean; var accept: Boolean); + procedure doflagonchange(const sender: TObject); + function internalrefresh: boolean; virtual; + procedure updatereadstatvalues; virtual; + procedure updatewritestatvalues; virtual; + procedure updatelayout(const dsender: twidget); override; + procedure updateregisternames() virtual; + public + constructor create(aowner: tcomponent); override; + procedure refresh; virtual; + procedure beforecontinue; virtual; + function flagedit(const aindex: integer): tcustombooleanedit; virtual; + end; + +var + cpufo: tcpufo; + +procedure createcpufo; + +implementation +uses + cpuform_mfm,main,sysutils,mseformatstr,msebits,msestrings,msegraphutils, + cpui386form,cpux86_64form,cpuarmform,cpuarmm3form, + cpucpu32form,cpuavr32form,cpurl78form, + projectoptionsform; +const + refreshtag = 738952; +var + currentproc: processorty; + +procedure createcpufo; +begin + mainfo.gdb.processorname:= ansistring(projectoptions.d.texp.gdbprocessor); + if (cpufo = nil) or (currentproc <> mainfo.gdb.processor) then begin + freeandnil(cpufo); + currentproc:= mainfo.gdb.processor; + case mainfo.gdb.processor of + pro_i386: begin + application.createform(tcpui386fo,cpufo); + end; + pro_x86_64: begin + application.createform(tcpux86_64fo,cpufo); + end; + pro_arm: begin + application.createform(tcpuarmfo,cpufo); + end; + pro_armm3: begin + application.createform(tcpuarmm3fo,cpufo); + end; + pro_cpu32: begin + application.createform(tcpucpu32fo,cpufo); + end; + pro_avr32: begin + application.createform(tcpuavr32fo,cpufo); + end; + pro_rl78: begin + application.createform(tcpurl78fo,cpufo); + end; + else begin + application.createform(tcpufo,cpufo); + end; + end; + end; + cpufo.fregisternames:= nil; +end; + +{ tcpufo } + +function tcpufo.internalrefresh: boolean; +var + ar1: registerinfoarty; + int1,int2: integer; + comp1: tcomponent; + ed1: tdataedit; + str1: msestring; +begin + result:= false; + if fregisternames = nil then begin + if mainfo.gdb.listregisternames(fregisternames) <> gdb_ok then begin + exit; + end; + updateregisternames(); + fedits:= nil; + setlength(fedits,length(fregisternames)); + for int1:= 0 to high(fregisternames) do begin + if fregisternames[int1] <> '' then begin + for int2:= 0 to componentcount - 1 do begin + comp1:= components[int2]; + if (comp1.Name = fregisternames[int1]) then begin + if (comp1 is tdataedit) then begin + fedits[int1]:= tdataedit(comp1); + comp1.Tag:= int1; + end; + break; + end; + end; + end; + end; + end; + if mainfo.gdb.listregistervalues(ar1) = gdb_ok then begin + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + if (num >= 0) and (num <= high(fedits)) then begin + ed1:= fedits[num]; + if ed1 <> nil then begin + str1:= ed1.text; + ed1.text:= msestring(ar1[int1].bits); + ed1.checkvalue(true); + if ed1.text <> str1 then begin + ed1.font.color:= cl_red; + end + else begin + ed1.font.color:= cl_black; + end; + end; + end; + end; + end; + result:= true; + end; +end; + +procedure tcpufo.refresh; +begin + if visible and mainfo.gdb.cancommand and on.value then begin + internalrefresh; + end; +end; + +procedure tcpufo.cpuonshow(const sender: TObject); +begin + refresh; +end; + +procedure tcpufo.ononchange(const sender: TObject); +var + int1: integer; +begin + if on.value then begin + for int1:= 0 to childrencount - 1 do begin + children[int1].enabled:= true; + end; + refresh; + end + else begin + for int1:= 0 to childrencount - 1 do begin + if children[int1] <> sender then begin + children[int1].enabled:= false; + end; + end; + end; +end; + +procedure tcpufo.doregsetvalue(const sender: TObject; var avalue: Integer; + var accept: Boolean); +begin + if mainfo.gdb.cancommand then begin + with tintegeredit(sender) do begin + if (mainfo.gdb.setregistervalue( + fregisternames[tag],avalue) <> gdb_ok) then begin + accept:= false; + end + else begin + if fneedsrefresh then begin + self.asyncevent(refreshtag); + end; + end; + end; + end + else begin + accept:= false; + end; +end; + +procedure tcpufo.doregset64value(const sender: TObject; var avalue: Int64; + var accept: Boolean); +begin + if mainfo.gdb.cancommand then begin + with tintegeredit(sender) do begin + if mainfo.gdb.setregistervalue(fregisternames[tag],avalue) <> gdb_ok then begin + accept:= false; + end + else begin + if fneedsrefresh then begin + self.asyncevent(refreshtag); + end; + end; + end; + end + else begin + accept:= false; + end; +end; + +procedure tcpufo.doflagsetvalue(const sender: TObject; + var avalue: Boolean; var accept: Boolean); +begin + if fflagswidget <> nil then begin + with tbooleanedit(sender) do begin + if avalue then begin + fflagswidget.value:= longword(fflagswidget.value) or bits[tag]; + end + else begin + fflagswidget.value:= longword(fflagswidget.value) and not bits[tag]; + end; + fflagswidget.checkvalue; + end; + end + else begin + if fflagswidget64 <> nil then begin + with tbooleanedit(sender) do begin + if avalue then begin + fflagswidget64.value:= longword(fflagswidget64.value) or bits[tag]; + end + else begin + fflagswidget64.value:= longword(fflagswidget64.value) and not bits[tag]; + end; + fflagswidget64.checkvalue; + end; + end; + end; +end; + +function tcpufo.flagedit(const aindex: integer): tcustombooleanedit; +begin + result:= nil; +end; + +procedure tcpufo.doflagonchange(const sender: TObject); +var + int1: integer; + ed1: tcustombooleanedit; + bo1: boolean; + ca1: longword; +begin + if fflagswidget <> nil then begin + ca1:= fflagswidget.value; + for int1:= 0 to 31 do begin + ed1:= flagedit(int1); + if (ed1 <> nil) then begin + bo1:= bits[int1] and ca1 <> 0; + if ed1.value <> bo1 then begin + ed1.frame.colorclient:= cl_ltred; + end + else begin + ed1.frame.colorclient:= cl_active; + end; + ed1.value:= bo1; + end; + end; + end + else begin + if fflagswidget64 <> nil then begin + ca1:= fflagswidget64.value; + for int1:= 0 to 31 do begin + ed1:= flagedit(int1); + if (ed1 <> nil) then begin + bo1:= bits[int1] and ca1 <> 0; + if ed1.value <> bo1 then begin + ed1.frame.colorclient:= cl_ltred; + end + else begin + ed1.frame.colorclient:= cl_active; + end; + ed1.value:= bo1; + end; + end; + end; + end; +end; + +procedure tcpufo.beforecontinue; +begin + //dummy +end; + +procedure tcpufo.updastat(const sender: TObject; const filer: tstatfiler); +begin + filer.updatevalue('irqoff',irqoffvalue); +end; + +procedure tcpufo.updatereadstatvalues; +begin + //dummy +end; + +procedure tcpufo.updatewritestatvalues; +begin + //dummy +end; + +procedure tcpufo.aftread(const sender: TObject); +begin + updatereadstatvalues; +end; + +procedure tcpufo.befwrite(const sender: TObject); +begin + updatewritestatvalues; +end; + +constructor tcpufo.create(aowner: tcomponent); +begin + inherited create(aowner); +end; + +procedure tcpufo.updatelayout(const dsender: twidget); +begin + aligny(wam_center,[stoptime,on]); + inherited; +end; + +procedure tcpufo.updateregisternames(); +begin + //dummy +end; + +procedure tcpufo.asynceventexe(const sender: TObject; var atag: Integer); +begin + if atag = refreshtag then begin + refresh; + end; +end; + +end. diff --git a/mseide-msegui/apps/ide/cpuform_mfm.pas b/mseide-msegui/apps/ide/cpuform_mfm.pas new file mode 100644 index 0000000..095327a --- /dev/null +++ b/mseide-msegui/apps/ide/cpuform_mfm.pas @@ -0,0 +1,133 @@ +unit cpuform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,cpuform; + +const + objdata: record size: integer; data: array[0..2317] of byte end = + (size: 2318; data: ( + 84,80,70,48,6,116,99,112,117,102,111,5,99,112,117,102,111,13,111,112, + 116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115, + 101,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 13,111,119,95,109,111,117,115,101,119,104,101,101,108,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,9,111,119,95,104,105,110,116, + 111,110,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,15,102,114,97,109,101,46,103,114,105,112,95,115,105,122,101,2,10, + 18,102,114,97,109,101,46,103,114,105,112,95,111,112,116,105,111,110,115,11, + 14,103,111,95,99,108,111,115,101,98,117,116,116,111,110,16,103,111,95,102, + 105,120,115,105,122,101,98,117,116,116,111,110,14,103,111,95,102,108,111,97, + 116,98,117,116,116,111,110,12,103,111,95,116,111,112,98,117,116,116,111,110, + 19,103,111,95,98,97,99,107,103,114,111,117,110,100,98,117,116,116,111,110, + 15,103,111,95,110,111,108,111,99,107,98,117,116,116,111,110,14,103,111,95, + 98,117,116,116,111,110,104,105,110,116,115,0,7,118,105,115,105,98,108,101, + 8,8,98,111,117,110,100,115,95,120,3,192,0,8,98,111,117,110,100,115, + 95,121,3,195,1,9,98,111,117,110,100,115,95,99,120,3,131,1,9,98, + 111,117,110,100,115,95,99,121,3,207,0,26,99,111,110,116,97,105,110,101, + 114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0, + 27,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,16,99,111,110,116,97,105,110,101,114, + 46,98,111,117,110,100,115,1,2,0,2,0,3,121,1,3,207,0,0,22, + 100,114,97,103,100,111,99,107,46,115,112,108,105,116,116,101,114,95,115,105, + 122,101,2,0,16,100,114,97,103,100,111,99,107,46,99,97,112,116,105,111, + 110,6,3,67,80,85,20,100,114,97,103,100,111,99,107,46,111,112,116,105, + 111,110,115,100,111,99,107,11,10,111,100,95,115,97,118,101,112,111,115,13, + 111,100,95,115,97,118,101,122,111,114,100,101,114,10,111,100,95,99,97,110, + 109,111,118,101,11,111,100,95,99,97,110,102,108,111,97,116,10,111,100,95, + 99,97,110,100,111,99,107,11,111,100,95,112,114,111,112,115,105,122,101,14, + 111,100,95,99,97,112,116,105,111,110,104,105,110,116,0,7,111,112,116,105, + 111,110,115,11,10,102,111,95,115,97,118,101,112,111,115,13,102,111,95,115, + 97,118,101,122,111,114,100,101,114,12,102,111,95,115,97,118,101,115,116,97, + 116,101,0,8,115,116,97,116,102,105,108,101,7,22,109,97,105,110,102,111, + 46,112,114,111,106,101,99,116,115,116,97,116,102,105,108,101,7,99,97,112, + 116,105,111,110,6,3,67,80,85,21,105,99,111,110,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,12,105,99,111, + 110,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101, + 100,0,10,105,99,111,110,46,105,109,97,103,101,10,208,3,0,0,0,0, + 0,0,2,0,0,0,24,0,0,0,24,0,0,0,60,3,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,208,208,208,96,124,124,124,25,217,217, + 217,22,255,255,255,1,124,124,124,1,217,217,217,4,191,191,191,1,217,217, + 217,6,177,177,177,1,217,217,217,5,188,188,188,1,217,217,217,4,255,255, + 255,1,124,124,124,1,217,217,217,2,125,125,125,1,16,16,16,1,7,7, + 7,1,40,40,40,1,204,204,204,1,217,217,217,3,151,151,151,1,5,5, + 5,1,217,217,217,3,156,156,156,1,23,23,23,1,7,7,7,1,24,24, + 24,1,184,184,184,1,217,217,217,2,255,255,255,1,124,124,124,1,217,217, + 217,1,204,204,204,1,16,16,16,1,137,137,137,1,194,194,194,1,38,38, + 38,1,86,86,86,1,217,217,217,2,128,128,128,1,13,13,13,1,1,1, + 1,1,217,217,217,3,34,34,34,1,97,97,97,1,207,207,207,1,60,60, + 60,1,54,54,54,1,217,217,217,2,255,255,255,1,124,124,124,1,217,217, + 217,1,134,134,134,1,31,31,31,1,217,217,217,2,130,130,130,1,28,28, + 28,1,217,217,217,1,174,174,174,1,11,11,11,1,111,111,111,1,1,1, + 1,1,217,217,217,2,187,187,187,1,9,9,9,1,213,213,213,1,217,217, + 217,1,180,180,180,1,6,6,6,1,217,217,217,2,255,255,255,1,124,124, + 124,1,217,217,217,1,105,105,105,1,53,53,53,1,217,217,217,2,168,168, + 168,1,13,13,13,1,217,217,217,1,204,204,204,1,197,197,197,1,200,200, + 200,1,1,1,1,1,217,217,217,2,149,149,149,1,26,26,26,1,217,217, + 217,3,3,3,3,1,191,191,191,1,217,217,217,1,255,255,255,1,124,124, + 124,1,217,217,217,1,82,82,82,1,62,62,62,1,217,217,217,2,187,187, + 187,1,3,3,3,1,217,217,217,3,200,200,200,1,1,1,1,1,217,217, + 217,2,121,121,121,1,34,34,34,1,217,217,217,3,10,10,10,1,167,167, + 167,1,217,217,217,1,255,255,255,1,124,124,124,1,217,217,217,1,91,91, + 91,1,56,56,56,1,217,217,217,2,174,174,174,1,11,11,11,1,217,217, + 217,3,200,200,200,1,1,1,1,1,217,217,217,2,132,132,132,1,29,29, + 29,1,217,217,217,3,5,5,5,1,191,191,191,1,217,217,217,1,255,255, + 255,1,124,124,124,1,217,217,217,1,111,111,111,1,40,40,40,1,217,217, + 217,2,146,146,146,1,26,26,26,1,217,217,217,3,200,200,200,1,1,1, + 1,1,217,217,217,2,156,156,156,1,16,16,16,1,217,217,217,2,200,200, + 200,1,4,4,4,1,217,217,217,2,255,255,255,1,124,124,124,1,217,217, + 217,1,185,185,185,1,10,10,10,1,191,191,191,1,217,217,217,1,65,65, + 65,1,63,63,63,1,217,217,217,3,200,200,200,1,1,1,1,1,217,217, + 217,2,213,213,213,1,15,15,15,1,154,154,154,1,217,217,217,1,99,99, + 99,1,35,35,35,1,217,217,217,2,255,255,255,1,124,124,124,1,217,217, + 217,2,73,73,73,1,9,9,9,1,35,35,35,1,11,11,11,1,191,191, + 191,1,217,217,217,3,200,200,200,1,1,1,1,1,217,217,217,3,107,107, + 107,1,5,5,5,1,42,42,42,1,4,4,4,1,155,155,155,1,217,217, + 217,2,255,255,255,1,124,124,124,1,217,217,217,3,141,141,141,1,121,121, + 121,1,207,207,207,1,217,217,217,4,213,213,213,1,137,137,137,1,217,217, + 217,4,156,156,156,1,115,115,115,1,194,194,194,1,217,217,217,3,255,255, + 255,1,124,124,124,1,217,217,217,22,255,255,255,1,124,124,124,1,217,217, + 217,22,255,255,255,1,124,124,124,1,255,255,255,23,208,208,208,96,0,0, + 0,0,0,0,0,0,0,0,0,0,0,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,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,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,111,110,115,104,111, + 119,7,9,99,112,117,111,110,115,104,111,119,12,111,110,97,115,121,110,99, + 101,118,101,110,116,7,13,97,115,121,110,99,101,118,101,110,116,101,120,101, + 12,111,110,115,116,97,116,117,112,100,97,116,101,7,8,117,112,100,97,115, + 116,97,116,15,111,110,115,116,97,116,97,102,116,101,114,114,101,97,100,7, + 7,97,102,116,114,101,97,100,17,111,110,115,116,97,116,98,101,102,111,114, + 101,119,114,105,116,101,7,8,98,101,102,119,114,105,116,101,15,109,111,100, + 117,108,101,99,108,97,115,115,110,97,109,101,6,9,116,100,111,99,107,102, + 111,114,109,0,12,116,98,111,111,108,101,97,110,101,100,105,116,2,111,110, + 3,84,97,103,2,255,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,7,67,80,85,32,38,111,110,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,1,2,48,2,2,0,8,98,111,117,110, + 100,115,95,120,2,7,8,98,111,117,110,100,115,95,121,2,9,9,98,111, + 117,110,100,115,95,99,120,2,61,9,98,111,117,110,100,115,95,99,121,2, + 16,8,111,110,99,104,97,110,103,101,7,10,111,110,111,110,99,104,97,110, + 103,101,5,118,97,108,117,101,9,0,0,13,116,100,97,116,101,116,105,109, + 101,100,105,115,112,8,115,116,111,112,116,105,109,101,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100, + 101,114,2,1,8,98,111,117,110,100,115,95,120,2,80,8,98,111,117,110, + 100,115,95,121,2,8,9,98,111,117,110,100,115,95,99,120,2,124,9,98, + 111,117,110,100,115,95,99,121,2,18,9,116,101,120,116,102,108,97,103,115, + 11,12,116,102,95,120,99,101,110,116,101,114,101,100,8,116,102,95,114,105, + 103,104,116,12,116,102,95,121,99,101,110,116,101,114,101,100,0,6,102,111, + 114,109,97,116,6,17,121,121,45,109,109,45,100,100,32,104,104,58,109,109, + 58,115,115,4,107,105,110,100,7,12,100,116,107,95,100,97,116,101,116,105, + 109,101,5,118,97,108,117,101,5,0,0,0,0,0,0,0,128,255,255,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tcpufo,''); +end. diff --git a/mseide-msegui/apps/ide/cpui386form.mfm b/mseide-msegui/apps/ide/cpui386form.mfm new file mode 100644 index 0000000..4129d16 --- /dev/null +++ b/mseide-msegui/apps/ide/cpui386form.mfm @@ -0,0 +1,757 @@ +inherited cpui386fo: tcpui386fo + bounds_x = 337 + bounds_y = 295 + bounds_cx = 273 + container.onlayout = cpufoonchildscaled + container.bounds = ( + 0 + 0 + 263 + 207 + ) + caption = 'CPU I386' + onlayout = cpufoonchildscaled + top = 4 + moduleclassname = 'tcpufo' + inherited on: tbooleanedit + bounds_x = 167 + bounds_y = 1 + end + inherited stoptime: tdatetimedisp + bounds_x = 0 + bounds_y = 0 + end + object tspacer1: tspacer[2] + taborder = 2 + visible = True + bounds_x = 0 + bounds_y = 18 + bounds_cx = 254 + bounds_cy = 182 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + linktop = stoptime + object c: tbooleanedit + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'C' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + bounds_x = 158 + bounds_y = 5 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object p: tbooleanedit + Tag = 2 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'P' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + bounds_x = 147 + bounds_y = 5 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object a: tbooleanedit + Tag = 4 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'A' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + bounds_x = 136 + bounds_y = 5 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object z: tbooleanedit + Tag = 6 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'Z' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 3 + bounds_x = 125 + bounds_y = 5 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object s: tbooleanedit + Tag = 7 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'S' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 4 + bounds_x = 114 + bounds_y = 5 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object t: tbooleanedit + Tag = 8 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'T' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 5 + bounds_x = 103 + bounds_y = 5 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object i: tbooleanedit + Tag = 9 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'I' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 6 + bounds_x = 92 + bounds_y = 5 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object d: tbooleanedit + Tag = 10 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'D' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 7 + bounds_x = 81 + bounds_y = 5 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object o: tbooleanedit + Tag = 11 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'O' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 8 + bounds_x = 70 + bounds_y = 5 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object io: tbooleanedit + Tag = 12 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'IO' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 1 + 17 + 2 + 0 + ) + taborder = 9 + bounds_x = 54 + bounds_y = 5 + bounds_cx = 14 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object nt: tbooleanedit + Tag = 15 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'NT' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 3 + 17 + 4 + 0 + ) + taborder = 10 + bounds_x = 34 + bounds_y = 5 + bounds_cx = 18 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object r: tbooleanedit + Tag = 16 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'R' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 11 + bounds_x = 20 + bounds_y = 5 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object v: tbooleanedit + Tag = 17 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'V' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 12 + bounds_x = 4 + bounds_y = 5 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object ss: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'ss' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 17 + 0 + ) + taborder = 13 + bounds_x = 187 + bounds_y = 162 + bounds_cx = 58 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object gs: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'gs' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 18 + 0 + ) + taborder = 14 + bounds_x = 187 + bounds_y = 141 + bounds_cx = 59 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object fs: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'fs' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 14 + 0 + ) + taborder = 15 + bounds_x = 187 + bounds_y = 120 + bounds_cx = 55 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object es: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'es' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 18 + 0 + ) + taborder = 16 + bounds_x = 128 + bounds_y = 162 + bounds_cx = 59 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object ds: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'ds' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 18 + 0 + ) + taborder = 17 + bounds_x = 128 + bounds_y = 141 + bounds_cx = 59 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object cs: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'cs' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 17 + 0 + ) + taborder = 18 + bounds_x = 128 + bounds_y = 120 + bounds_cx = 58 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object eflags: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'efl' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 18 + 0 + ) + taborder = 19 + bounds_x = 128 + bounds_y = 36 + bounds_cx = 118 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onchange = flagonchange + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object eip: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'eip' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 22 + 0 + ) + taborder = 20 + bounds_x = 128 + bounds_y = 78 + bounds_cx = 122 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object esp: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'esp' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 26 + 0 + ) + taborder = 21 + bounds_x = 128 + bounds_y = 57 + bounds_cx = 126 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object ebp: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'ebp' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 27 + 0 + ) + taborder = 22 + bounds_x = 0 + bounds_y = 162 + bounds_cx = 120 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object edi: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'edi' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 22 + 0 + ) + taborder = 23 + bounds_x = 0 + bounds_y = 141 + bounds_cx = 115 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object esi: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'esi' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 21 + 0 + ) + taborder = 24 + bounds_x = 0 + bounds_y = 120 + bounds_cx = 114 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object edx: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'edx' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 25 + 0 + ) + taborder = 25 + bounds_x = 0 + bounds_y = 99 + bounds_cx = 118 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object ecx: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'ecx' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 24 + 0 + ) + taborder = 26 + bounds_x = 0 + bounds_y = 78 + bounds_cx = 117 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object ebx: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'ebx' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 25 + 0 + ) + taborder = 27 + bounds_x = 0 + bounds_y = 57 + bounds_cx = 118 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object eax: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'eax' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 25 + 0 + ) + taborder = 28 + bounds_x = 0 + bounds_y = 36 + bounds_cx = 118 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + end +end diff --git a/mseide-msegui/apps/ide/cpui386form.pas b/mseide-msegui/apps/ide/cpui386form.pas new file mode 100644 index 0000000..68e225e --- /dev/null +++ b/mseide-msegui/apps/ide/cpui386form.pas @@ -0,0 +1,131 @@ +{ MSEide Copyright (c) 1999-2013 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit cpui386form; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +uses + classes,mclasses,msegui,mseclasses,mseforms,msegdbutils,msetypes,msedataedits, + msegraphics,msegraphedits,cpuform,mseguiglob,msemenus,msesplitter,mseedit, + msestrings; + +type + + tcpui386fo = class(tcpufo) + tspacer1: tspacer; + c: tbooleanedit; + p: tbooleanedit; + a: tbooleanedit; + z: tbooleanedit; + s: tbooleanedit; + t: tbooleanedit; + i: tbooleanedit; + d: tbooleanedit; + o: tbooleanedit; + io: tbooleanedit; + nt: tbooleanedit; + r: tbooleanedit; + v: tbooleanedit; + ss: tintegeredit; + gs: tintegeredit; + fs: tintegeredit; + es: tintegeredit; + ds: tintegeredit; + cs: tintegeredit; + eflags: tintegeredit; + eip: tintegeredit; + esp: tintegeredit; + ebp: tintegeredit; + edi: tintegeredit; + esi: tintegeredit; + edx: tintegeredit; + ecx: tintegeredit; + ebx: tintegeredit; + eax: tintegeredit; + procedure flagonchange(const sender: TObject); + procedure flagsetvalue(const sender: TObject; var avalue: Boolean; var accept: Boolean); +// procedure ononchange(const sender: TObject); + procedure regsetvalue(const sender: TObject; var avalue: Integer; var accept: Boolean); + procedure cpufoonchildscaled(const sender: TObject); + public + constructor create(aowner: tcomponent); override; + function flagedit(const aindex: integer): tcustombooleanedit; override; + end; + +implementation +uses + cpui386form_mfm,main,sysutils,mseformatstr,msebits,msegraphutils; + +{ tcpui386fo } + +constructor tcpui386fo.create(aowner: tcomponent); +begin + inherited create(aowner); + fflagswidget:= eflags; +end; + +function tcpui386fo.flagedit(const aindex: integer): tcustombooleanedit; +begin + result:= c.tagitem(aindex); +end; + +procedure tcpui386fo.flagonchange(const sender: TObject); +begin + doflagonchange(sender); +end; + +procedure tcpui386fo.flagsetvalue(const sender: TObject; + var avalue: Boolean; var accept: Boolean); +begin + doflagsetvalue(sender,avalue,accept); +end; +{ +procedure tcpui386fo.ononchange(const sender: TObject); +var + int1: integer; +begin + if on.value then begin + for int1:= 0 to childrencount - 1 do begin + children[int1].enabled:= true; + end; + refresh; + end + else begin + for int1:= 0 to childrencount - 1 do begin + if children[int1] <> sender then begin + children[int1].enabled:= false; + end; + end; + end; +end; +} +procedure tcpui386fo.regsetvalue(const sender: TObject; var avalue: Integer; var accept: Boolean); +begin + doregsetvalue(sender,avalue,accept); +end; + +procedure tcpui386fo.cpufoonchildscaled(const sender: TObject); +begin + placeyorder(eax.bounds_y,[0],[eax,ebx,ecx,edx,esi,edi,ebp]); + placeyorder(eflags.bounds_y,[0],[eflags,esp,eip]); + placeyorder(esi.bounds_y,[0],[cs,ds,es]); + placeyorder(esi.bounds_y,[0],[fs,gs,ss]); +end; + +end. diff --git a/mseide-msegui/apps/ide/cpui386form_mfm.pas b/mseide-msegui/apps/ide/cpui386form_mfm.pas new file mode 100644 index 0000000..8eb2063 --- /dev/null +++ b/mseide-msegui/apps/ide/cpui386form_mfm.pas @@ -0,0 +1,621 @@ +unit cpui386form_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,cpui386form; + +const + objdata: record size: integer; data: array[0..12072] of byte end = + (size: 12073; data: ( + 84,80,70,48,241,10,116,99,112,117,105,51,56,54,102,111,9,99,112,117, + 105,51,56,54,102,111,8,98,111,117,110,100,115,95,120,3,81,1,8,98, + 111,117,110,100,115,95,121,3,39,1,9,98,111,117,110,100,115,95,99,120, + 3,17,1,18,99,111,110,116,97,105,110,101,114,46,111,110,108,97,121,111, + 117,116,7,18,99,112,117,102,111,111,110,99,104,105,108,100,115,99,97,108, + 101,100,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1, + 2,0,2,0,3,7,1,3,207,0,0,7,99,97,112,116,105,111,110,6, + 8,67,80,85,32,73,51,56,54,8,111,110,108,97,121,111,117,116,7,18, + 99,112,117,102,111,111,110,99,104,105,108,100,115,99,97,108,101,100,3,116, + 111,112,2,4,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101, + 6,6,116,99,112,117,102,111,0,241,12,116,98,111,111,108,101,97,110,101, + 100,105,116,2,111,110,8,98,111,117,110,100,115,95,120,3,167,0,8,98, + 111,117,110,100,115,95,121,2,1,0,0,241,13,116,100,97,116,101,116,105, + 109,101,100,105,115,112,8,115,116,111,112,116,105,109,101,8,98,111,117,110, + 100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,0,0,242, + 2,2,7,116,115,112,97,99,101,114,8,116,115,112,97,99,101,114,49,8, + 116,97,98,111,114,100,101,114,2,2,7,118,105,115,105,98,108,101,9,8, + 98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2, + 18,9,98,111,117,110,100,115,95,99,120,3,254,0,9,98,111,117,110,100, + 115,95,99,121,3,182,0,12,111,112,116,105,111,110,115,115,99,97,108,101, + 11,11,111,115,99,95,101,120,112,97,110,100,120,11,111,115,99,95,115,104, + 114,105,110,107,120,11,111,115,99,95,101,120,112,97,110,100,121,11,111,115, + 99,95,115,104,114,105,110,107,121,0,7,108,105,110,107,116,111,112,7,8, + 115,116,111,112,116,105,109,101,0,12,116,98,111,111,108,101,97,110,101,100, + 105,116,1,99,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109, + 101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108, + 111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,1,67,16,102,114,97,109,101,46,99,97,112, + 116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101, + 118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2, + 0,2,17,2,0,2,0,0,8,98,111,117,110,100,115,95,120,3,158,0, + 8,98,111,117,110,100,115,95,121,2,5,9,98,111,117,110,100,115,95,99, + 120,2,11,9,98,111,117,110,100,115,95,99,121,2,28,10,111,110,115,101, + 116,118,97,108,117,101,7,12,102,108,97,103,115,101,116,118,97,108,117,101, + 0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,1,112,3,84,97, + 103,2,2,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101, + 46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111, + 114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99, + 97,112,116,105,111,110,6,1,80,16,102,114,97,109,101,46,99,97,112,116, + 105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,1,8,98, + 111,117,110,100,115,95,120,3,147,0,8,98,111,117,110,100,115,95,121,2, + 5,9,98,111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115, + 95,99,121,2,28,10,111,110,115,101,116,118,97,108,117,101,7,12,102,108, + 97,103,115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97, + 110,101,100,105,116,1,97,3,84,97,103,2,4,5,99,111,108,111,114,4, + 3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17, + 102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0, + 0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1,65,16, + 102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112, + 95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111, + 108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97, + 98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,3,136,0, + 8,98,111,117,110,100,115,95,121,2,5,9,98,111,117,110,100,115,95,99, + 120,2,11,9,98,111,117,110,100,115,95,99,121,2,28,10,111,110,115,101, + 116,118,97,108,117,101,7,12,102,108,97,103,115,101,116,118,97,108,117,101, + 0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,1,122,3,84,97, + 103,2,6,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101, + 46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111, + 114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99, + 97,112,116,105,111,110,6,1,90,16,102,114,97,109,101,46,99,97,112,116, + 105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,3,8,98, + 111,117,110,100,115,95,120,2,125,8,98,111,117,110,100,115,95,121,2,5, + 9,98,111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95, + 99,121,2,28,10,111,110,115,101,116,118,97,108,117,101,7,12,102,108,97, + 103,115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110, + 101,100,105,116,1,115,3,84,97,103,2,7,5,99,111,108,111,114,4,3, + 0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102, + 114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0, + 144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1,83,16,102, + 114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95, + 116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108, + 111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101, + 114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98, + 111,114,100,101,114,2,4,8,98,111,117,110,100,115,95,120,2,114,8,98, + 111,117,110,100,115,95,121,2,5,9,98,111,117,110,100,115,95,99,120,2, + 11,9,98,111,117,110,100,115,95,99,121,2,28,10,111,110,115,101,116,118, + 97,108,117,101,7,12,102,108,97,103,115,101,116,118,97,108,117,101,0,0, + 12,116,98,111,111,108,101,97,110,101,100,105,116,1,116,3,84,97,103,2, + 8,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,1,84,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17, + 2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,5,8,98,111,117, + 110,100,115,95,120,2,103,8,98,111,117,110,100,115,95,121,2,5,9,98, + 111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95,99,121, + 2,28,10,111,110,115,101,116,118,97,108,117,101,7,12,102,108,97,103,115, + 101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110,101,100, + 105,116,1,105,3,84,97,103,2,9,5,99,111,108,111,114,4,3,0,0, + 128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97, + 109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,1,73,16,102,114,97, + 109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111, + 112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114, + 100,101,114,2,6,8,98,111,117,110,100,115,95,120,2,92,8,98,111,117, + 110,100,115,95,121,2,5,9,98,111,117,110,100,115,95,99,120,2,11,9, + 98,111,117,110,100,115,95,99,121,2,28,10,111,110,115,101,116,118,97,108, + 117,101,7,12,102,108,97,103,115,101,116,118,97,108,117,101,0,0,12,116, + 98,111,111,108,101,97,110,101,100,105,116,1,100,3,84,97,103,2,10,5, + 99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,1,68,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112, + 111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0, + 2,0,0,8,116,97,98,111,114,100,101,114,2,7,8,98,111,117,110,100, + 115,95,120,2,81,8,98,111,117,110,100,115,95,121,2,5,9,98,111,117, + 110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95,99,121,2,28, + 10,111,110,115,101,116,118,97,108,117,101,7,12,102,108,97,103,115,101,116, + 118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116, + 1,111,3,84,97,103,2,11,5,99,111,108,111,114,4,3,0,0,128,12, + 102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101, + 46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114, + 97,109,101,46,99,97,112,116,105,111,110,6,1,79,16,102,114,97,109,101, + 46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101, + 114,2,8,8,98,111,117,110,100,115,95,120,2,70,8,98,111,117,110,100, + 115,95,121,2,5,9,98,111,117,110,100,115,95,99,120,2,11,9,98,111, + 117,110,100,115,95,99,121,2,28,10,111,110,115,101,116,118,97,108,117,101, + 7,12,102,108,97,103,115,101,116,118,97,108,117,101,0,0,12,116,98,111, + 111,108,101,97,110,101,100,105,116,2,105,111,3,84,97,103,2,12,5,99, + 111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118,101, + 108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101, + 110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111, + 110,6,2,73,79,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112, + 111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,1,2,17,2,2, + 2,0,0,8,116,97,98,111,114,100,101,114,2,9,8,98,111,117,110,100, + 115,95,120,2,54,8,98,111,117,110,100,115,95,121,2,5,9,98,111,117, + 110,100,115,95,99,120,2,14,9,98,111,117,110,100,115,95,99,121,2,28, + 10,111,110,115,101,116,118,97,108,117,101,7,12,102,108,97,103,115,101,116, + 118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116, + 2,110,116,3,84,97,103,2,15,5,99,111,108,111,114,4,3,0,0,128, + 12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109, + 101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,2,78,84,16,102,114,97, + 109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111, + 112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,3,2,17,2,4,2,0,0,8,116,97,98,111,114, + 100,101,114,2,10,8,98,111,117,110,100,115,95,120,2,34,8,98,111,117, + 110,100,115,95,121,2,5,9,98,111,117,110,100,115,95,99,120,2,18,9, + 98,111,117,110,100,115,95,99,121,2,28,10,111,110,115,101,116,118,97,108, + 117,101,7,12,102,108,97,103,115,101,116,118,97,108,117,101,0,0,12,116, + 98,111,111,108,101,97,110,101,100,105,116,1,114,3,84,97,103,2,16,5, + 99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,1,82,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112, + 111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0, + 2,0,0,8,116,97,98,111,114,100,101,114,2,11,8,98,111,117,110,100, + 115,95,120,2,20,8,98,111,117,110,100,115,95,121,2,5,9,98,111,117, + 110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95,99,121,2,28, + 10,111,110,115,101,116,118,97,108,117,101,7,12,102,108,97,103,115,101,116, + 118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116, + 1,118,3,84,97,103,2,17,5,99,111,108,111,114,4,3,0,0,128,12, + 102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101, + 46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114, + 97,109,101,46,99,97,112,116,105,111,110,6,1,86,16,102,114,97,109,101, + 46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101, + 114,2,12,8,98,111,117,110,100,115,95,120,2,4,8,98,111,117,110,100, + 115,95,121,2,5,9,98,111,117,110,100,115,95,99,120,2,11,9,98,111, + 117,110,100,115,95,99,121,2,28,10,111,110,115,101,116,118,97,108,117,101, + 7,12,102,108,97,103,115,101,116,118,97,108,117,101,0,0,12,116,105,110, + 116,101,103,101,114,101,100,105,116,2,115,115,13,111,112,116,105,111,110,115, + 119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117, + 115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114, + 111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117, + 115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116, + 17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12, + 102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101, + 46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114, + 97,109,101,46,99,97,112,116,105,111,110,6,2,115,115,16,102,114,97,109, + 101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103, + 104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111, + 114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,0,2,17,2,0,0,8,116,97,98,111, + 114,100,101,114,2,13,8,98,111,117,110,100,115,95,120,3,187,0,8,98, + 111,117,110,100,115,95,121,3,162,0,9,98,111,117,110,100,115,95,99,120, + 2,58,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110, + 116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111, + 110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0, + 10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118, + 97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,98,105, + 116,99,111,117,110,116,2,16,3,109,97,120,2,255,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,16,0,0,12,116,105,110,116,101,103,101, + 114,101,100,105,116,2,103,115,13,111,112,116,105,111,110,115,119,105,100,103, + 101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119, + 95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111, + 99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16, + 111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109, + 101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108, + 111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,2,103,115,16,102,114,97,109,101,46,99,97, + 112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108, + 95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105, + 101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109, + 101,1,2,0,2,0,2,18,2,0,0,8,116,97,98,111,114,100,101,114, + 2,14,8,98,111,117,110,100,115,95,120,3,187,0,8,98,111,117,110,100, + 115,95,121,3,141,0,9,98,111,117,110,100,115,95,99,120,2,59,11,102, + 111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97, + 109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120, + 115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115, + 101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101, + 4,98,97,115,101,7,6,110,98,95,104,101,120,8,98,105,116,99,111,117, + 110,116,2,16,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,16,0,0,12,116,105,110,116,101,103,101,114,101,100,105, + 116,2,102,115,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13, + 111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98, + 102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15, + 111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97, + 114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116, + 114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101, + 118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108, + 105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116, + 105,111,110,6,2,102,115,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,0,2,14,2,0,0,8,116,97,98,111,114,100,101,114,2,15,8,98, + 111,117,110,100,115,95,120,3,187,0,8,98,111,117,110,100,115,95,121,2, + 120,9,98,111,117,110,100,115,95,99,120,2,55,11,102,111,110,116,46,104, + 101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115, + 116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101, + 2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108, + 117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101, + 7,6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2,16,3, + 109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 16,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,2,101,115,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111, + 117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114, + 114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102, + 111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,2, + 101,115,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7, + 8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102, + 114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109, + 101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,18,2, + 0,0,8,116,97,98,111,114,100,101,114,2,16,8,98,111,117,110,100,115, + 95,120,3,128,0,8,98,111,117,110,100,115,95,121,3,162,0,9,98,111, + 117,110,100,115,95,99,120,2,59,11,102,111,110,116,46,104,101,105,103,104, + 116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102, + 105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102, + 111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95, + 120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11, + 114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98, + 95,104,101,120,8,98,105,116,99,111,117,110,116,2,16,3,109,97,120,2, + 255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,12, + 116,105,110,116,101,103,101,114,101,100,105,116,2,100,115,13,111,112,116,105, + 111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102, + 111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95, + 97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102, + 111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115, + 111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116, + 115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,2,100,115,16,102, + 114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95, + 114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99, + 111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117, + 116,101,114,102,114,97,109,101,1,2,0,2,0,2,18,2,0,0,8,116, + 97,98,111,114,100,101,114,2,17,8,98,111,117,110,100,115,95,120,3,128, + 0,8,98,111,117,110,100,115,95,121,3,141,0,9,98,111,117,110,100,115, + 95,99,120,2,59,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9, + 102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100, + 11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46, + 108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97, + 108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115, + 101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120, + 8,98,105,116,99,111,117,110,116,2,16,3,109,97,120,2,255,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,12,116,105,110,116, + 101,103,101,114,101,100,105,116,2,99,115,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115, + 105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,2,99,115,16,102,114,97,109,101, + 46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104, + 116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,0,2,17,2,0,0,8,116,97,98,111,114, + 100,101,114,2,18,8,98,111,117,110,100,115,95,120,3,128,0,8,98,111, + 117,110,100,115,95,121,2,120,9,98,111,117,110,100,115,95,99,120,2,58, + 11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46, + 110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116, + 46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111, + 110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108, + 117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,98,105,116,99, + 111,117,110,116,2,16,3,109,97,120,2,255,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,16,0,0,12,116,105,110,116,101,103,101,114,101, + 100,105,116,6,101,102,108,97,103,115,13,111,112,116,105,111,110,115,119,105, + 100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11, + 111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119, + 102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105, + 110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111, + 119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114, + 97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99, + 111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,3,101,102,108,16,102,114,97,109,101, + 46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104, + 116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,0,2,18,2,0,0,8,116,97,98,111,114, + 100,101,114,2,19,8,98,111,117,110,100,115,95,120,3,128,0,8,98,111, + 117,110,100,115,95,121,2,36,9,98,111,117,110,100,115,95,99,120,2,118, + 11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46, + 110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116, + 46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,8,111, + 110,99,104,97,110,103,101,7,12,102,108,97,103,111,110,99,104,97,110,103, + 101,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116, + 118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,3,109, + 97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16, + 0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,3,101,105,112,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111, + 117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114, + 114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102, + 111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,3, + 101,105,112,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115, + 7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,22, + 2,0,0,8,116,97,98,111,114,100,101,114,2,20,8,98,111,117,110,100, + 115,95,120,3,128,0,8,98,111,117,110,100,115,95,121,2,78,9,98,111, + 117,110,100,115,95,99,120,2,122,11,102,111,110,116,46,104,101,105,103,104, + 116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102, + 105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102, + 111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95, + 120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11, + 114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98, + 95,104,101,120,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,16,0,0,12,116,105,110,116,101,103,101,114,101,100,105, + 116,3,101,115,112,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,3,101,115,112,16,102,114,97,109,101,46,99,97,112,116, + 105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,0,2,26,2,0,0,8,116,97,98,111,114,100,101,114,2,21, + 8,98,111,117,110,100,115,95,120,3,128,0,8,98,111,117,110,100,115,95, + 121,2,57,9,98,111,117,110,100,115,95,99,120,2,126,11,102,111,110,116, + 46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6, + 9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97, + 108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118, + 97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97, + 115,101,7,6,110,98,95,104,101,120,3,109,97,120,2,255,13,114,101,102, + 102,111,110,116,104,101,105,103,104,116,2,16,0,0,12,116,105,110,116,101, + 103,101,114,101,100,105,116,3,101,98,112,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115, + 105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,3,101,98,112,16,102,114,97,109, + 101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103, + 104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111, + 114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,0,2,27,2,0,0,8,116,97,98,111, + 114,100,101,114,2,22,8,98,111,117,110,100,115,95,120,2,0,8,98,111, + 117,110,100,115,95,121,3,162,0,9,98,111,117,110,100,115,95,99,120,2, + 120,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116, + 46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110, + 116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10, + 111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97, + 108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,3,109,97,120, + 2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0, + 12,116,105,110,116,101,103,101,114,101,100,105,116,3,101,100,105,13,111,112, + 116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115, + 101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111, + 119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99, + 117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17, + 102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0, + 0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,3,101,100, + 105,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8, + 99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114, + 108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101, + 46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,22,2,0, + 0,8,116,97,98,111,114,100,101,114,2,23,8,98,111,117,110,100,115,95, + 120,2,0,8,98,111,117,110,100,115,95,121,3,141,0,9,98,111,117,110, + 100,115,95,99,120,2,115,11,102,111,110,116,46,104,101,105,103,104,116,2, + 14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120, + 101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110, + 116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115, + 99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101, + 103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104, + 101,120,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,16,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,3, + 101,115,105,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,3,101,115,105,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,0,2,21,2,0,0,8,116,97,98,111,114,100,101,114,2,24,8,98, + 111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,120, + 9,98,111,117,110,100,115,95,99,120,2,114,11,102,111,110,116,46,104,101, + 105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116, + 102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2, + 1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117, + 101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7, + 6,110,98,95,104,101,120,3,109,97,120,2,255,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,16,0,0,12,116,105,110,116,101,103,101,114, + 101,100,105,116,3,101,100,120,13,111,112,116,105,111,110,115,119,105,100,103, + 101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119, + 95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111, + 99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16, + 111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109, + 101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108, + 111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,3,101,100,120,16,102,114,97,109,101,46,99, + 97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,0,2,25,2,0,0,8,116,97,98,111,114,100,101, + 114,2,25,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100, + 115,95,121,2,99,9,98,111,117,110,100,115,95,99,120,2,118,11,102,111, + 110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109, + 101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115, + 99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101, + 116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4, + 98,97,115,101,7,6,110,98,95,104,101,120,3,109,97,120,2,255,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,12,116,105,110, + 116,101,103,101,114,101,100,105,116,3,101,99,120,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109, + 101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,3,101,99,120,16,102,114, + 97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114, + 105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111, + 108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,0,2,24,2,0,0,8,116,97, + 98,111,114,100,101,114,2,26,8,98,111,117,110,100,115,95,120,2,0,8, + 98,111,117,110,100,115,95,121,2,78,9,98,111,117,110,100,115,95,99,120, + 2,117,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110, + 116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111, + 110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0, + 10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118, + 97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,3,109,97, + 120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0, + 0,12,116,105,110,116,101,103,101,114,101,100,105,116,3,101,98,120,13,111, + 112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117, + 115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13, + 111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114, + 111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111, + 99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100, + 103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255, + 17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7, + 0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,3,101, + 98,120,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7, + 8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102, + 114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109, + 101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,25,2, + 0,0,8,116,97,98,111,114,100,101,114,2,27,8,98,111,117,110,100,115, + 95,120,2,0,8,98,111,117,110,100,115,95,121,2,57,9,98,111,117,110, + 100,115,95,99,120,2,118,11,102,111,110,116,46,104,101,105,103,104,116,2, + 14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120, + 101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110, + 116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115, + 99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101, + 103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104, + 101,120,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,16,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,3, + 101,97,120,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,3,101,97,120,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,0,2,25,2,0,0,8,116,97,98,111,114,100,101,114,2,28,8,98, + 111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,36, + 9,98,111,117,110,100,115,95,99,120,2,118,11,102,111,110,116,46,104,101, + 105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116, + 102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2, + 1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117, + 101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7, + 6,110,98,95,104,101,120,3,109,97,120,2,255,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,16,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tcpui386fo,''); +end. diff --git a/mseide-msegui/apps/ide/cpurl78form.mfm b/mseide-msegui/apps/ide/cpurl78form.mfm new file mode 100644 index 0000000..85a515d --- /dev/null +++ b/mseide-msegui/apps/ide/cpurl78form.mfm @@ -0,0 +1,1743 @@ +inherited cpurl78fo: tcpurl78fo + bounds_x = 24 + bounds_y = 391 + bounds_cx = 377 + bounds_cy = 271 + container.bounds = ( + 0 + 0 + 367 + 271 + ) + moduleclassname = 'tcpufo' + inherited on: tbooleanedit + end + inherited stoptime: tdatetimedisp + taborder = 69 + bounds_x = 72 + end + object a: tintegeredit[2] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'A' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + bounds_x = 72 + bounds_y = 31 + bounds_cx = 25 + bounds_cy = 37 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object x: tintegeredit[3] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'X' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + bounds_x = 97 + bounds_y = 31 + bounds_cx = 25 + bounds_cy = 37 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object ax: tintegeredit[4] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 9 + bounds_x = 72 + bounds_y = 69 + bounds_cx = 50 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object bc: tintegeredit[5] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 10 + bounds_x = 123 + bounds_y = 69 + bounds_cx = 50 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object b: tintegeredit[6] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'B' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 3 + bounds_x = 123 + bounds_y = 31 + bounds_cx = 25 + bounds_cy = 37 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object c: tintegeredit[7] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'C' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 4 + bounds_x = 148 + bounds_y = 31 + bounds_cx = 25 + bounds_cy = 37 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object de: tintegeredit[8] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 11 + bounds_x = 174 + bounds_y = 69 + bounds_cx = 50 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object d: tintegeredit[9] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'D' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 5 + bounds_x = 174 + bounds_y = 31 + bounds_cx = 25 + bounds_cy = 37 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object e: tintegeredit[10] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'E' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 6 + bounds_x = 199 + bounds_y = 31 + bounds_cx = 25 + bounds_cy = 37 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object hl: tintegeredit[11] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 12 + bounds_x = 225 + bounds_y = 69 + bounds_cx = 50 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object h: tintegeredit[12] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'H' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 7 + bounds_x = 225 + bounds_y = 31 + bounds_cx = 25 + bounds_cy = 37 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object l: tintegeredit[13] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'L' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 8 + bounds_x = 250 + bounds_y = 31 + bounds_cx = 25 + bounds_cy = 37 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object psw: tintegeredit[14] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'PSW' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 2 + 17 + 2 + 0 + ) + taborder = 68 + bounds_x = 6 + bounds_y = 175 + bounds_cx = 29 + bounds_cy = 37 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onchange = flagonchange + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object tgroupbox1: tgroupbox[15] + taborder = 67 + bounds_x = 0 + bounds_y = 32 + bounds_cx = 54 + bounds_cy = 138 + optionsscale = [osc_expandx] + object tbooleanedit9: tbooleanedit + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'CY' + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 2 + 18 + 3 + ) + taborder = 1 + bounds_x = 8 + bounds_y = 24 + bounds_cx = 29 + bounds_cy = 16 + onsetvalue = flagsetvalue + end + object tbooleanedit8: tbooleanedit + Tag = 1 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'ISP0' + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 2 + 30 + 3 + ) + taborder = 5 + bounds_x = 8 + bounds_y = 88 + bounds_cx = 41 + bounds_cy = 16 + onsetvalue = flagsetvalue + end + object tbooleanedit7: tbooleanedit + Tag = 2 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'ISP1' + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 2 + 30 + 3 + ) + taborder = 4 + bounds_x = 8 + bounds_y = 72 + bounds_cx = 41 + bounds_cy = 16 + onsetvalue = flagsetvalue + end + object tbooleanedit6: tbooleanedit + Tag = 3 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'RBS0' + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 2 + 35 + 3 + ) + taborder = 7 + bounds_x = 8 + bounds_y = 120 + bounds_cx = 46 + bounds_cy = 16 + onsetvalue = flagsetvalue + end + object tbooleanedit5: tbooleanedit + Tag = 4 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'AC' + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 2 + 19 + 3 + ) + taborder = 2 + bounds_x = 8 + bounds_y = 40 + bounds_cx = 30 + bounds_cy = 16 + onsetvalue = flagsetvalue + end + object tbooleanedit4: tbooleanedit + Tag = 5 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'RBS1' + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 2 + 35 + 3 + ) + taborder = 6 + bounds_x = 8 + bounds_y = 104 + bounds_cx = 46 + bounds_cy = 16 + onsetvalue = flagsetvalue + end + object z: tbooleanedit + Tag = 6 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'Z' + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 2 + 12 + 3 + ) + bounds_x = 8 + bounds_y = 8 + bounds_cx = 23 + bounds_cy = 16 + onsetvalue = flagsetvalue + end + object tbooleanedit2: tbooleanedit + Tag = 7 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'IE' + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 2 + 14 + 3 + ) + taborder = 3 + bounds_x = 8 + bounds_y = 56 + bounds_cx = 25 + bounds_cy = 16 + onsetvalue = flagsetvalue + end + end + object sp: tintegeredit[16] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'SP' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + taborder = 61 + bounds_x = 281 + bounds_y = 48 + bounds_cx = 69 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object pc: tintegeredit[17] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'PC' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + taborder = 62 + bounds_x = 281 + bounds_y = 69 + bounds_cx = 69 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object es: tintegeredit[18] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'ES' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + taborder = 63 + bounds_x = 281 + bounds_y = 93 + bounds_cx = 69 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object cs: tintegeredit[19] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'CS' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + taborder = 64 + bounds_x = 281 + bounds_y = 114 + bounds_cx = 69 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object pmc: tintegeredit[20] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'PMC' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 29 + 0 + ) + taborder = 65 + bounds_x = 281 + bounds_y = 136 + bounds_cx = 79 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank0_r6: tintegeredit[21] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 20 + bounds_x = 250 + bounds_y = 93 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank0_r7: tintegeredit[22] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 19 + bounds_x = 225 + bounds_y = 93 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank0_rp3: tintegeredit[23] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 24 + bounds_x = 225 + bounds_y = 114 + bounds_cx = 50 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object bank0_r4: tintegeredit[24] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 18 + bounds_x = 199 + bounds_y = 93 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank0_r5: tintegeredit[25] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 17 + bounds_x = 174 + bounds_y = 93 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank0_rp2: tintegeredit[26] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 23 + bounds_x = 174 + bounds_y = 114 + bounds_cx = 50 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object bank0_r2: tintegeredit[27] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 16 + bounds_x = 148 + bounds_y = 93 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank0_r3: tintegeredit[28] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 15 + bounds_x = 123 + bounds_y = 93 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank0_rp1: tintegeredit[29] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 22 + bounds_x = 123 + bounds_y = 114 + bounds_cx = 50 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object bank0_rp0: tintegeredit[30] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 21 + bounds_x = 72 + bounds_y = 114 + bounds_cx = 50 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object bank0_r0: tintegeredit[31] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 14 + bounds_x = 97 + bounds_y = 93 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank0_r1: tintegeredit[32] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = '0' + frame.captionpos = cp_left + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 11 + 0 + 0 + 0 + ) + taborder = 13 + bounds_x = 61 + bounds_y = 93 + bounds_cx = 36 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank1_r1: tintegeredit[33] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = '1' + frame.captionpos = cp_left + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 11 + 0 + 0 + 0 + ) + taborder = 25 + bounds_x = 61 + bounds_y = 136 + bounds_cx = 36 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank1_r0: tintegeredit[34] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 26 + bounds_x = 97 + bounds_y = 136 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank1_rp0: tintegeredit[35] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 33 + bounds_x = 72 + bounds_y = 157 + bounds_cx = 50 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object bank1_rp1: tintegeredit[36] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 34 + bounds_x = 123 + bounds_y = 157 + bounds_cx = 50 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object bank1_r3: tintegeredit[37] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 27 + bounds_x = 123 + bounds_y = 136 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank1_r2: tintegeredit[38] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 28 + bounds_x = 148 + bounds_y = 136 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank1_rp2: tintegeredit[39] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 35 + bounds_x = 174 + bounds_y = 157 + bounds_cx = 50 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object bank1_r5: tintegeredit[40] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 29 + bounds_x = 174 + bounds_y = 136 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank1_r4: tintegeredit[41] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 30 + bounds_x = 199 + bounds_y = 136 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank1_rp3: tintegeredit[42] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 36 + bounds_x = 225 + bounds_y = 157 + bounds_cx = 50 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object bank1_r7: tintegeredit[43] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 31 + bounds_x = 225 + bounds_y = 136 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank1_r6: tintegeredit[44] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 32 + bounds_x = 250 + bounds_y = 136 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank2_r1: tintegeredit[45] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = '2' + frame.captionpos = cp_left + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 11 + 0 + 0 + 0 + ) + taborder = 37 + bounds_x = 61 + bounds_y = 179 + bounds_cx = 36 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank2_r0: tintegeredit[46] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 38 + bounds_x = 97 + bounds_y = 179 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank2_rp0: tintegeredit[47] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 45 + bounds_x = 72 + bounds_y = 200 + bounds_cx = 50 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object bank2_rp1: tintegeredit[48] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 46 + bounds_x = 123 + bounds_y = 200 + bounds_cx = 50 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object bank2_r3: tintegeredit[49] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 39 + bounds_x = 123 + bounds_y = 179 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank2_r2: tintegeredit[50] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 40 + bounds_x = 148 + bounds_y = 179 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank2_rp2: tintegeredit[51] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 47 + bounds_x = 174 + bounds_y = 200 + bounds_cx = 50 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object bank2_r5: tintegeredit[52] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 41 + bounds_x = 174 + bounds_y = 179 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank2_r4: tintegeredit[53] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 42 + bounds_x = 199 + bounds_y = 179 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank2_rp3: tintegeredit[54] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 48 + bounds_x = 225 + bounds_y = 200 + bounds_cx = 50 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object bank2_r7: tintegeredit[55] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 43 + bounds_x = 225 + bounds_y = 179 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank2_r6: tintegeredit[56] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 44 + bounds_x = 250 + bounds_y = 179 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank3_r1: tintegeredit[57] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = '3' + frame.captionpos = cp_left + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 11 + 0 + 0 + 0 + ) + taborder = 49 + bounds_x = 61 + bounds_y = 222 + bounds_cx = 36 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank3_r0: tintegeredit[58] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 50 + bounds_x = 97 + bounds_y = 222 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank3_rp0: tintegeredit[59] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 57 + bounds_x = 72 + bounds_y = 243 + bounds_cx = 50 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object bank3_rp1: tintegeredit[60] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 58 + bounds_x = 123 + bounds_y = 243 + bounds_cx = 50 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object bank3_r3: tintegeredit[61] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 51 + bounds_x = 123 + bounds_y = 222 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank3_r2: tintegeredit[62] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 52 + bounds_x = 148 + bounds_y = 222 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank3_rp2: tintegeredit[63] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 59 + bounds_x = 174 + bounds_y = 243 + bounds_cx = 50 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object bank3_r5: tintegeredit[64] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 53 + bounds_x = 174 + bounds_y = 222 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank3_r4: tintegeredit[65] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 54 + bounds_x = 199 + bounds_y = 222 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank3_rp3: tintegeredit[66] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 60 + bounds_x = 225 + bounds_y = 243 + bounds_cx = 50 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 16 + max = -1 + reffontheight = 16 + end + object bank3_r7: tintegeredit[67] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 55 + bounds_x = 225 + bounds_y = 222 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object bank3_r6: tintegeredit[68] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 56 + bounds_x = 250 + bounds_y = 222 + bounds_cx = 25 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end + object mem: tintegeredit[69] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'MEM' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 31 + 0 + ) + taborder = 66 + bounds_x = 281 + bounds_y = 157 + bounds_cx = 81 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + bitcount = 8 + max = -1 + reffontheight = 16 + end +end diff --git a/mseide-msegui/apps/ide/cpurl78form.pas b/mseide-msegui/apps/ide/cpurl78form.pas new file mode 100644 index 0000000..f3842bd --- /dev/null +++ b/mseide-msegui/apps/ide/cpurl78form.pas @@ -0,0 +1,149 @@ +{ MSEide Copyright (c) 1999-2013 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit cpurl78form; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,mseforms,cpuform,msedataedits, + mseedit,mseifiglob,msestrings,msetypes,classes,mclasses,msegraphedits, + msesimplewidgets,msewidgets; + +type + tcpurl78fo = class(tcpufo) + a: tintegeredit; + x: tintegeredit; + ax: tintegeredit; + bc: tintegeredit; + b: tintegeredit; + c: tintegeredit; + de: tintegeredit; + d: tintegeredit; + e: tintegeredit; + hl: tintegeredit; + h: tintegeredit; + l: tintegeredit; + psw: tintegeredit; + tgroupbox1: tgroupbox; + tbooleanedit9: tbooleanedit; + tbooleanedit8: tbooleanedit; + tbooleanedit7: tbooleanedit; + tbooleanedit6: tbooleanedit; + tbooleanedit5: tbooleanedit; + tbooleanedit4: tbooleanedit; + z: tbooleanedit; + tbooleanedit2: tbooleanedit; + sp: tintegeredit; + pc: tintegeredit; + es: tintegeredit; + cs: tintegeredit; + pmc: tintegeredit; + bank0_r6: tintegeredit; + bank0_r7: tintegeredit; + bank0_rp3: tintegeredit; + bank0_r4: tintegeredit; + bank0_r5: tintegeredit; + bank0_rp2: tintegeredit; + bank0_r2: tintegeredit; + bank0_r3: tintegeredit; + bank0_rp1: tintegeredit; + bank0_rp0: tintegeredit; + bank0_r0: tintegeredit; + bank0_r1: tintegeredit; + bank1_r1: tintegeredit; + bank1_r0: tintegeredit; + bank1_rp0: tintegeredit; + bank1_rp1: tintegeredit; + bank1_r3: tintegeredit; + bank1_r2: tintegeredit; + bank1_rp2: tintegeredit; + bank1_r5: tintegeredit; + bank1_r4: tintegeredit; + bank1_rp3: tintegeredit; + bank1_r7: tintegeredit; + bank1_r6: tintegeredit; + bank2_r1: tintegeredit; + bank2_r0: tintegeredit; + bank2_rp0: tintegeredit; + bank2_rp1: tintegeredit; + bank2_r3: tintegeredit; + bank2_r2: tintegeredit; + bank2_rp2: tintegeredit; + bank2_r5: tintegeredit; + bank2_r4: tintegeredit; + bank2_rp3: tintegeredit; + bank2_r7: tintegeredit; + bank2_r6: tintegeredit; + bank3_r1: tintegeredit; + bank3_r0: tintegeredit; + bank3_rp0: tintegeredit; + bank3_rp1: tintegeredit; + bank3_r3: tintegeredit; + bank3_r2: tintegeredit; + bank3_rp2: tintegeredit; + bank3_r5: tintegeredit; + bank3_r4: tintegeredit; + bank3_rp3: tintegeredit; + bank3_r7: tintegeredit; + bank3_r6: tintegeredit; + mem: tintegeredit; + procedure regsetvalue(const sender: TObject; var avalue: Integer; + var accept: Boolean); + procedure flagsetvalue(const sender: TObject; var avalue: Boolean; + var accept: Boolean); + procedure flagonchange(const sender: TObject); + function flagedit(const aindex: integer): tcustombooleanedit; override; + public + constructor create(aowner: tcomponent); override; + end; + +var + cpurl78fo: tcpurl78fo; +implementation +uses + cpurl78form_mfm; + +constructor tcpurl78fo.create(aowner: tcomponent); +begin + fneedsrefresh:= true; + inherited; + fflagswidget:= psw; +end; + +procedure tcpurl78fo.regsetvalue(const sender: TObject; var avalue: Integer; + var accept: Boolean); +begin + doregsetvalue(sender,avalue,accept); +end; + +procedure tcpurl78fo.flagsetvalue(const sender: TObject; var avalue: Boolean; + var accept: Boolean); +begin + doflagsetvalue(sender,avalue,accept); +end; + +procedure tcpurl78fo.flagonchange(const sender: TObject); +begin + doflagonchange(sender); +end; + +function tcpurl78fo.flagedit(const aindex: integer): tcustombooleanedit; +begin + result:= z.tagitem(aindex); +end; + +end. diff --git a/mseide-msegui/apps/ide/cpurl78form_mfm.pas b/mseide-msegui/apps/ide/cpurl78form_mfm.pas new file mode 100644 index 0000000..f7f23ba --- /dev/null +++ b/mseide-msegui/apps/ide/cpurl78form_mfm.pas @@ -0,0 +1,1721 @@ +unit cpurl78form_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,cpurl78form; + +const + objdata: record size: integer; data: array[0..34063] of byte end = + (size: 34064; data: ( + 84,80,70,48,241,10,116,99,112,117,114,108,55,56,102,111,9,99,112,117, + 114,108,55,56,102,111,8,98,111,117,110,100,115,95,120,2,24,8,98,111, + 117,110,100,115,95,121,3,135,1,9,98,111,117,110,100,115,95,99,120,3, + 121,1,9,98,111,117,110,100,115,95,99,121,3,15,1,16,99,111,110,116, + 97,105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0,3,111,1, + 3,15,1,0,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101, + 6,6,116,99,112,117,102,111,0,241,12,116,98,111,111,108,101,97,110,101, + 100,105,116,2,111,110,0,0,241,13,116,100,97,116,101,116,105,109,101,100, + 105,115,112,8,115,116,111,112,116,105,109,101,8,116,97,98,111,114,100,101, + 114,2,69,8,98,111,117,110,100,115,95,120,2,72,0,0,242,2,2,12, + 116,105,110,116,101,103,101,114,101,100,105,116,1,97,13,111,112,116,105,111, + 110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111, + 99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97, + 114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111, + 99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111, + 117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97, + 109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,1,65,16,102,114,97, + 109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111, + 112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114, + 100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,72,8,98,111,117, + 110,100,115,95,121,2,31,9,98,111,117,110,100,115,95,99,120,2,25,9, + 98,111,117,110,100,115,95,99,121,2,37,11,102,111,110,116,46,104,101,105, + 103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102, + 95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1, + 15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108, + 112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101, + 7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6, + 110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2,8,3,109,97, + 120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0, + 0,242,2,3,12,116,105,110,116,101,103,101,114,101,100,105,116,1,120,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111, + 117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114, + 114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102, + 111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1, + 88,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6, + 99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95, + 99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8, + 116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,2, + 97,8,98,111,117,110,100,115,95,121,2,31,9,98,111,117,110,100,115,95, + 99,120,2,25,9,98,111,117,110,100,115,95,99,121,2,37,11,102,111,110, + 116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101, + 6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99, + 97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116, + 118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98, + 97,115,101,7,6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116, + 2,8,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,16,0,0,242,2,4,12,116,105,110,116,101,103,101,114,101,100, + 105,116,2,97,120,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,7,0,0,144,16,102,114,97,109,101,46,99,97,112, + 116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95, + 108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101, + 110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,8,116,97,98,111,114,100,101,114,2,9,8,98,111,117,110,100, + 115,95,120,2,72,8,98,111,117,110,100,115,95,121,2,69,9,98,111,117, + 110,100,115,95,99,120,2,50,11,102,111,110,116,46,104,101,105,103,104,116, + 2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105, + 120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111, + 110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120, + 115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114, + 101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95, + 104,101,120,8,98,105,116,99,111,117,110,116,2,16,3,109,97,120,2,255, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,242,2, + 5,12,116,105,110,116,101,103,101,114,101,100,105,116,2,98,99,13,111,112, + 116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115, + 101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111, + 119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99, + 117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17, + 102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0, + 0,144,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7, + 8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102, + 114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111, + 114,100,101,114,2,10,8,98,111,117,110,100,115,95,120,2,123,8,98,111, + 117,110,100,115,95,121,2,69,9,98,111,117,110,100,115,95,99,120,2,50, + 11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46, + 110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116, + 46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111, + 110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108, + 117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,98,105,116,99, + 111,117,110,116,2,16,3,109,97,120,2,255,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,16,0,0,242,2,6,12,116,105,110,116,101,103, + 101,114,101,100,105,116,1,98,13,111,112,116,105,111,110,115,119,105,100,103, + 101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119, + 95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111, + 99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16, + 111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109, + 101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108, + 111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,1,66,16,102,114,97,109,101,46,99,97,112, + 116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101, + 118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2, + 0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,3,8, + 98,111,117,110,100,115,95,120,2,123,8,98,111,117,110,100,115,95,121,2, + 31,9,98,111,117,110,100,115,95,99,120,2,25,9,98,111,117,110,100,115, + 95,99,121,2,37,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9, + 102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100, + 11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46, + 108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97, + 108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115, + 101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120, + 8,98,105,116,99,111,117,110,116,2,8,3,109,97,120,2,255,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,242,2,7,12,116, + 105,110,116,101,103,101,114,101,100,105,116,1,99,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109, + 101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,1,67,16,102,114,97,109, + 101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100, + 101,114,2,4,8,98,111,117,110,100,115,95,120,3,148,0,8,98,111,117, + 110,100,115,95,121,2,31,9,98,111,117,110,100,115,95,99,120,2,25,9, + 98,111,117,110,100,115,95,99,121,2,37,11,102,111,110,116,46,104,101,105, + 103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102, + 95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1, + 15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108, + 112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101, + 7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6, + 110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2,8,3,109,97, + 120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0, + 0,242,2,8,12,116,105,110,116,101,103,101,114,101,100,105,116,2,100,101, + 13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109, + 111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117, + 115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97, + 114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119, + 102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111, + 2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116, + 4,7,0,0,144,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112, + 111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116, + 97,98,111,114,100,101,114,2,11,8,98,111,117,110,100,115,95,120,3,174, + 0,8,98,111,117,110,100,115,95,121,2,69,9,98,111,117,110,100,115,95, + 99,120,2,50,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102, + 111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11, + 102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108, + 101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101, + 116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8, + 98,105,116,99,111,117,110,116,2,16,3,109,97,120,2,255,13,114,101,102, + 102,111,110,116,104,101,105,103,104,116,2,16,0,0,242,2,9,12,116,105, + 110,116,101,103,101,114,101,100,105,116,1,100,13,111,112,116,105,111,110,115, + 119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117, + 115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114, + 111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117, + 115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116, + 17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12, + 102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101, + 46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114, + 97,109,101,46,99,97,112,116,105,111,110,6,1,68,16,102,114,97,109,101, + 46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101, + 114,2,5,8,98,111,117,110,100,115,95,120,3,174,0,8,98,111,117,110, + 100,115,95,121,2,31,9,98,111,117,110,100,115,95,99,120,2,25,9,98, + 111,117,110,100,115,95,99,121,2,37,11,102,111,110,116,46,104,101,105,103, + 104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95, + 102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15, + 102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112, + 95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7, + 11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110, + 98,95,104,101,120,8,98,105,116,99,111,117,110,116,2,8,3,109,97,120, + 2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0, + 242,2,10,12,116,105,110,116,101,103,101,114,101,100,105,116,1,101,13,111, + 112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117, + 115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13, + 111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114, + 111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111, + 99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100, + 103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255, + 17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7, + 0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1,69, + 16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99, + 112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99, + 111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117, + 116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116, + 97,98,111,114,100,101,114,2,6,8,98,111,117,110,100,115,95,120,3,199, + 0,8,98,111,117,110,100,115,95,121,2,31,9,98,111,117,110,100,115,95, + 99,120,2,25,9,98,111,117,110,100,115,95,99,121,2,37,11,102,111,110, + 116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101, + 6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99, + 97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116, + 118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98, + 97,115,101,7,6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116, + 2,8,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,16,0,0,242,2,11,12,116,105,110,116,101,103,101,114,101,100, + 105,116,2,104,108,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,7,0,0,144,16,102,114,97,109,101,46,99,97,112, + 116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95, + 108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101, + 110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,8,116,97,98,111,114,100,101,114,2,12,8,98,111,117,110,100, + 115,95,120,3,225,0,8,98,111,117,110,100,115,95,121,2,69,9,98,111, + 117,110,100,115,95,99,120,2,50,11,102,111,110,116,46,104,101,105,103,104, + 116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102, + 105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102, + 111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95, + 120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11, + 114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98, + 95,104,101,120,8,98,105,116,99,111,117,110,116,2,16,3,109,97,120,2, + 255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,242, + 2,12,12,116,105,110,116,101,103,101,114,101,100,105,116,1,104,13,111,112, + 116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115, + 101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111, + 119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99, + 117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17, + 102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0, + 0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1,72,16, + 102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112, + 95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111, + 108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97, + 98,111,114,100,101,114,2,7,8,98,111,117,110,100,115,95,120,3,225,0, + 8,98,111,117,110,100,115,95,121,2,31,9,98,111,117,110,100,115,95,99, + 120,2,25,9,98,111,117,110,100,115,95,99,121,2,37,11,102,111,110,116, + 46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6, + 9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97, + 108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118, + 97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97, + 115,101,7,6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2, + 8,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,16,0,0,242,2,13,12,116,105,110,116,101,103,101,114,101,100,105, + 116,1,108,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,1,76,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112, + 111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0, + 2,0,0,8,116,97,98,111,114,100,101,114,2,8,8,98,111,117,110,100, + 115,95,120,3,250,0,8,98,111,117,110,100,115,95,121,2,31,9,98,111, + 117,110,100,115,95,99,120,2,25,9,98,111,117,110,100,115,95,99,121,2, + 37,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116, + 46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110, + 116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10, + 111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97, + 108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,98,105,116, + 99,111,117,110,116,2,8,3,109,97,120,2,255,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,16,0,0,242,2,14,12,116,105,110,116,101, + 103,101,114,101,100,105,116,3,112,115,119,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115, + 105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,3,80,83,87,16,102,114,97,109, + 101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,2,2,17,2,2,2,0,0,8,116,97,98,111,114,100, + 101,114,2,68,8,98,111,117,110,100,115,95,120,2,6,8,98,111,117,110, + 100,115,95,121,3,175,0,9,98,111,117,110,100,115,95,99,120,2,29,9, + 98,111,117,110,100,115,95,99,121,2,37,11,102,111,110,116,46,104,101,105, + 103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102, + 95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1, + 15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108, + 112,95,120,115,99,97,108,101,0,8,111,110,99,104,97,110,103,101,7,12, + 102,108,97,103,111,110,99,104,97,110,103,101,10,111,110,115,101,116,118,97, + 108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115, + 101,7,6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2,8, + 3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,16,0,0,242,2,15,9,116,103,114,111,117,112,98,111,120,10,116,103, + 114,111,117,112,98,111,120,49,8,116,97,98,111,114,100,101,114,2,67,8, + 98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2, + 32,9,98,111,117,110,100,115,95,99,120,2,54,9,98,111,117,110,100,115, + 95,99,121,3,138,0,12,111,112,116,105,111,110,115,115,99,97,108,101,11, + 11,111,115,99,95,101,120,112,97,110,100,120,0,0,12,116,98,111,111,108, + 101,97,110,101,100,105,116,13,116,98,111,111,108,101,97,110,101,100,105,116, + 57,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,2,67,89,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114, + 108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101, + 46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,2,2,18,2,3, + 0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95, + 120,2,8,8,98,111,117,110,100,115,95,121,2,24,9,98,111,117,110,100, + 115,95,99,120,2,29,9,98,111,117,110,100,115,95,99,121,2,16,10,111, + 110,115,101,116,118,97,108,117,101,7,12,102,108,97,103,115,101,116,118,97, + 108,117,101,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,13,116, + 98,111,111,108,101,97,110,101,100,105,116,56,3,84,97,103,2,1,5,99, + 111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118,101, + 108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101, + 110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111, + 110,6,4,73,83,80,48,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108, + 95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,2,2,30,2,3,0, + 8,116,97,98,111,114,100,101,114,2,5,8,98,111,117,110,100,115,95,120, + 2,8,8,98,111,117,110,100,115,95,121,2,88,9,98,111,117,110,100,115, + 95,99,120,2,41,9,98,111,117,110,100,115,95,99,121,2,16,10,111,110, + 115,101,116,118,97,108,117,101,7,12,102,108,97,103,115,101,116,118,97,108, + 117,101,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,13,116,98, + 111,111,108,101,97,110,101,100,105,116,55,3,84,97,103,2,2,5,99,111, + 108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108, + 111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110, + 116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,4,73,83,80,49,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95, + 99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,2,2,30,2,3,0,8, + 116,97,98,111,114,100,101,114,2,4,8,98,111,117,110,100,115,95,120,2, + 8,8,98,111,117,110,100,115,95,121,2,72,9,98,111,117,110,100,115,95, + 99,120,2,41,9,98,111,117,110,100,115,95,99,121,2,16,10,111,110,115, + 101,116,118,97,108,117,101,7,12,102,108,97,103,115,101,116,118,97,108,117, + 101,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,13,116,98,111, + 111,108,101,97,110,101,100,105,116,54,3,84,97,103,2,3,5,99,111,108, + 111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111, + 2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116, + 4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 4,82,66,83,48,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99, + 111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117, + 116,101,114,102,114,97,109,101,1,2,0,2,2,2,35,2,3,0,8,116, + 97,98,111,114,100,101,114,2,7,8,98,111,117,110,100,115,95,120,2,8, + 8,98,111,117,110,100,115,95,121,2,120,9,98,111,117,110,100,115,95,99, + 120,2,46,9,98,111,117,110,100,115,95,99,121,2,16,10,111,110,115,101, + 116,118,97,108,117,101,7,12,102,108,97,103,115,101,116,118,97,108,117,101, + 0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,13,116,98,111,111, + 108,101,97,110,101,100,105,116,53,3,84,97,103,2,4,5,99,111,108,111, + 114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,2, + 65,67,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111, + 114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,2,2,19,2,3,0,8,116,97,98,111, + 114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,2,8,8,98,111, + 117,110,100,115,95,121,2,40,9,98,111,117,110,100,115,95,99,120,2,30, + 9,98,111,117,110,100,115,95,99,121,2,16,10,111,110,115,101,116,118,97, + 108,117,101,7,12,102,108,97,103,115,101,116,118,97,108,117,101,0,0,12, + 116,98,111,111,108,101,97,110,101,100,105,116,13,116,98,111,111,108,101,97, + 110,101,100,105,116,52,3,84,97,103,2,5,5,99,111,108,111,114,4,3, + 0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102, + 114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0, + 144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,4,82,66,83, + 49,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,2,2,35,2,3,0,8,116,97,98,111,114, + 100,101,114,2,6,8,98,111,117,110,100,115,95,120,2,8,8,98,111,117, + 110,100,115,95,121,2,104,9,98,111,117,110,100,115,95,99,120,2,46,9, + 98,111,117,110,100,115,95,99,121,2,16,10,111,110,115,101,116,118,97,108, + 117,101,7,12,102,108,97,103,115,101,116,118,97,108,117,101,0,0,12,116, + 98,111,111,108,101,97,110,101,100,105,116,1,122,3,84,97,103,2,6,5, + 99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,1,90,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99, + 111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117, + 116,101,114,102,114,97,109,101,1,2,0,2,2,2,12,2,3,0,8,98, + 111,117,110,100,115,95,120,2,8,8,98,111,117,110,100,115,95,121,2,8, + 9,98,111,117,110,100,115,95,99,120,2,23,9,98,111,117,110,100,115,95, + 99,121,2,16,10,111,110,115,101,116,118,97,108,117,101,7,12,102,108,97, + 103,115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110, + 101,100,105,116,13,116,98,111,111,108,101,97,110,101,100,105,116,50,3,84, + 97,103,2,7,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109, + 101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108, + 111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,2,73,69,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111, + 15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,2,2, + 14,2,3,0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117,110, + 100,115,95,120,2,8,8,98,111,117,110,100,115,95,121,2,56,9,98,111, + 117,110,100,115,95,99,120,2,25,9,98,111,117,110,100,115,95,99,121,2, + 16,10,111,110,115,101,116,118,97,108,117,101,7,12,102,108,97,103,115,101, + 116,118,97,108,117,101,0,0,0,242,2,16,12,116,105,110,116,101,103,101, + 114,101,100,105,116,2,115,112,13,111,112,116,105,111,110,115,119,105,100,103, + 101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119, + 95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111, + 99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16, + 111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109, + 101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108, + 111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,2,83,80,16,102,114,97,109,101,46,99,97, + 112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108, + 95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105, + 101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109, + 101,1,2,0,2,0,2,19,2,0,0,8,116,97,98,111,114,100,101,114, + 2,61,8,98,111,117,110,100,115,95,120,3,25,1,8,98,111,117,110,100, + 115,95,121,2,48,9,98,111,117,110,100,115,95,99,120,2,69,11,102,111, + 110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109, + 101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115, + 99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101, + 116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4, + 98,97,115,101,7,6,110,98,95,104,101,120,8,98,105,116,99,111,117,110, + 116,2,16,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,16,0,0,242,2,17,12,116,105,110,116,101,103,101,114,101, + 100,105,116,2,112,99,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119, + 95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46, + 108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114, + 99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,2,80,67,16,102,114,97,109,101,46,99,97,112,116, + 105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,0,2,19,2,0,0,8,116,97,98,111,114,100,101,114,2,62, + 8,98,111,117,110,100,115,95,120,3,25,1,8,98,111,117,110,100,115,95, + 121,2,69,9,98,111,117,110,100,115,95,99,120,2,69,11,102,111,110,116, + 46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6, + 9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97, + 108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118, + 97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97, + 115,101,7,6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2, + 16,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,16,0,0,242,2,18,12,116,105,110,116,101,103,101,114,101,100,105, + 116,2,101,115,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13, + 111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98, + 102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15, + 111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97, + 114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116, + 114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101, + 118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108, + 105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116, + 105,111,110,6,2,69,83,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,0,2,19,2,0,0,8,116,97,98,111,114,100,101,114,2,63,8,98, + 111,117,110,100,115,95,120,3,25,1,8,98,111,117,110,100,115,95,121,2, + 93,9,98,111,117,110,100,115,95,99,120,2,69,11,102,111,110,116,46,104, + 101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115, + 116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101, + 2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108, + 117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101, + 7,6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2,16,3, + 109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 16,0,0,242,2,19,12,116,105,110,116,101,103,101,114,101,100,105,116,2, + 99,115,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119, + 95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111, + 99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119, + 95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114, + 111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111, + 121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101, + 108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101, + 110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111, + 110,6,2,67,83,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112, + 111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0, + 2,19,2,0,0,8,116,97,98,111,114,100,101,114,2,64,8,98,111,117, + 110,100,115,95,120,3,25,1,8,98,111,117,110,100,115,95,121,2,114,9, + 98,111,117,110,100,115,95,99,120,2,69,11,102,111,110,116,46,104,101,105, + 103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102, + 95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1, + 15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108, + 112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101, + 7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6, + 110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2,16,3,109,97, + 120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0, + 0,242,2,20,12,116,105,110,116,101,103,101,114,101,100,105,116,3,112,109, + 99,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95, + 97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111, + 119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121, + 119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108, + 111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110, + 116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,3,80,77,67,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112, + 111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0, + 2,29,2,0,0,8,116,97,98,111,114,100,101,114,2,65,8,98,111,117, + 110,100,115,95,120,3,25,1,8,98,111,117,110,100,115,95,121,3,136,0, + 9,98,111,117,110,100,115,95,99,120,2,79,11,102,111,110,116,46,104,101, + 105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116, + 102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2, + 1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117, + 101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7, + 6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2,8,3,109, + 97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16, + 0,0,242,2,21,12,116,105,110,116,101,103,101,114,101,100,105,116,8,98, + 97,110,107,48,95,114,54,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95, + 116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111, + 119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100, + 101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101, + 46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111, + 114,99,108,105,101,110,116,4,7,0,0,144,16,102,114,97,109,101,46,99, + 97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95, + 108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101, + 110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,8,116,97,98,111,114,100,101,114,2,20,8,98,111,117,110,100, + 115,95,120,3,250,0,8,98,111,117,110,100,115,95,121,2,93,9,98,111, + 117,110,100,115,95,99,120,2,25,11,102,111,110,116,46,104,101,105,103,104, + 116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102, + 105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102, + 111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95, + 120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11, + 114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98, + 95,104,101,120,8,98,105,116,99,111,117,110,116,2,8,3,109,97,120,2, + 255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,242, + 2,22,12,116,105,110,116,101,103,101,114,101,100,105,116,8,98,97,110,107, + 48,95,114,55,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13, + 111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98, + 102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15, + 111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97, + 114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116, + 114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101, + 118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108, + 105,101,110,116,4,7,0,0,144,16,102,114,97,109,101,46,99,97,112,116, + 105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 8,116,97,98,111,114,100,101,114,2,19,8,98,111,117,110,100,115,95,120, + 3,225,0,8,98,111,117,110,100,115,95,121,2,93,9,98,111,117,110,100, + 115,95,99,120,2,25,11,102,111,110,116,46,104,101,105,103,104,116,2,14, + 9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101, + 100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99, + 97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103, + 115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101, + 120,8,98,105,116,99,111,117,110,116,2,8,3,109,97,120,2,255,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,242,2,23,12, + 116,105,110,116,101,103,101,114,101,100,105,116,9,98,97,110,107,48,95,114, + 112,51,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119, + 95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111, + 99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119, + 95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114, + 111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111, + 121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101, + 108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101, + 110,116,4,7,0,0,144,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 8,116,97,98,111,114,100,101,114,2,24,8,98,111,117,110,100,115,95,120, + 3,225,0,8,98,111,117,110,100,115,95,121,2,114,9,98,111,117,110,100, + 115,95,99,120,2,50,11,102,111,110,116,46,104,101,105,103,104,116,2,14, + 9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101, + 100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99, + 97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103, + 115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101, + 120,8,98,105,116,99,111,117,110,116,2,16,3,109,97,120,2,255,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,242,2,24,12, + 116,105,110,116,101,103,101,114,101,100,105,116,8,98,97,110,107,48,95,114, + 52,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95, + 97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111, + 119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121, + 119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108, + 111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110, + 116,4,7,0,0,144,16,102,114,97,109,101,46,99,97,112,116,105,111,110, + 112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111, + 15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97, + 98,111,114,100,101,114,2,18,8,98,111,117,110,100,115,95,120,3,199,0, + 8,98,111,117,110,100,115,95,121,2,93,9,98,111,117,110,100,115,95,99, + 120,2,25,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111, + 110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102, + 111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101, + 0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116, + 118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,98, + 105,116,99,111,117,110,116,2,8,3,109,97,120,2,255,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,16,0,0,242,2,25,12,116,105,110, + 116,101,103,101,114,101,100,105,116,8,98,97,110,107,48,95,114,53,13,111, + 112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117, + 115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13, + 111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114, + 111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111, + 99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100, + 103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255, + 17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7, + 0,0,144,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115, + 7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114, + 108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114, + 100,101,114,2,17,8,98,111,117,110,100,115,95,120,3,174,0,8,98,111, + 117,110,100,115,95,121,2,93,9,98,111,117,110,100,115,95,99,120,2,25, + 11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46, + 110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116, + 46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111, + 110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108, + 117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,98,105,116,99, + 111,117,110,116,2,8,3,109,97,120,2,255,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,16,0,0,242,2,26,12,116,105,110,116,101,103, + 101,114,101,100,105,116,9,98,97,110,107,48,95,114,112,50,13,111,112,116, + 105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101, + 102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119, + 95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119, + 102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117, + 115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102, + 114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0, + 144,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8, + 99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114, + 108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114, + 100,101,114,2,23,8,98,111,117,110,100,115,95,120,3,174,0,8,98,111, + 117,110,100,115,95,121,2,114,9,98,111,117,110,100,115,95,99,120,2,50, + 11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46, + 110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116, + 46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111, + 110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108, + 117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,98,105,116,99, + 111,117,110,116,2,16,3,109,97,120,2,255,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,16,0,0,242,2,27,12,116,105,110,116,101,103, + 101,114,101,100,105,116,8,98,97,110,107,48,95,114,50,13,111,112,116,105, + 111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102, + 111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95, + 97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102, + 111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115, + 111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116, + 115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144, + 16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99, + 112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99, + 111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114, + 2,16,8,98,111,117,110,100,115,95,120,3,148,0,8,98,111,117,110,100, + 115,95,121,2,93,9,98,111,117,110,100,115,95,99,120,2,25,11,102,111, + 110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109, + 101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115, + 99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101, + 116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4, + 98,97,115,101,7,6,110,98,95,104,101,120,8,98,105,116,99,111,117,110, + 116,2,8,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,16,0,0,242,2,28,12,116,105,110,116,101,103,101,114,101, + 100,105,116,8,98,97,110,107,48,95,114,51,13,111,112,116,105,111,110,115, + 119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117, + 115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114, + 111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117, + 115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116, + 17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12, + 102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101, + 46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,16,102,114, + 97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116, + 111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111, + 114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,15,8, + 98,111,117,110,100,115,95,120,2,123,8,98,111,117,110,100,115,95,121,2, + 93,9,98,111,117,110,100,115,95,99,120,2,25,11,102,111,110,116,46,104, + 101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115, + 116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101, + 2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108, + 117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101, + 7,6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2,8,3, + 109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 16,0,0,242,2,29,12,116,105,110,116,101,103,101,114,101,100,105,116,9, + 98,97,110,107,48,95,114,112,49,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111, + 119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102, + 111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110, + 16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119, + 95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97, + 109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111, + 108,111,114,99,108,105,101,110,116,4,7,0,0,144,16,102,114,97,109,101, + 46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104, + 116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,22,8,98, + 111,117,110,100,115,95,120,2,123,8,98,111,117,110,100,115,95,121,2,114, + 9,98,111,117,110,100,115,95,99,120,2,50,11,102,111,110,116,46,104,101, + 105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116, + 102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2, + 1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117, + 101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7, + 6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2,16,3,109, + 97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16, + 0,0,242,2,30,12,116,105,110,116,101,103,101,114,101,100,105,116,9,98, + 97,110,107,48,95,114,112,48,13,111,112,116,105,111,110,115,119,105,100,103, + 101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119, + 95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111, + 99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16, + 111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109, + 101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108, + 111,114,99,108,105,101,110,116,4,7,0,0,144,16,102,114,97,109,101,46, + 99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,21,8,98,111, + 117,110,100,115,95,120,2,72,8,98,111,117,110,100,115,95,121,2,114,9, + 98,111,117,110,100,115,95,99,120,2,50,11,102,111,110,116,46,104,101,105, + 103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102, + 95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1, + 15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108, + 112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101, + 7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6, + 110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2,16,3,109,97, + 120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0, + 0,242,2,31,12,116,105,110,116,101,103,101,114,101,100,105,116,8,98,97, + 110,107,48,95,114,48,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119, + 95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46, + 108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114, + 99,108,105,101,110,116,4,7,0,0,144,16,102,114,97,109,101,46,99,97, + 112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,8,116,97,98,111,114,100,101,114,2,14,8,98,111,117,110,100,115, + 95,120,2,97,8,98,111,117,110,100,115,95,121,2,93,9,98,111,117,110, + 100,115,95,99,120,2,25,11,102,111,110,116,46,104,101,105,103,104,116,2, + 14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120, + 101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110, + 116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115, + 99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101, + 103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104, + 101,120,8,98,105,116,99,111,117,110,116,2,8,3,109,97,120,2,255,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,242,2,32, + 12,116,105,110,116,101,103,101,114,101,100,105,116,8,98,97,110,107,48,95, + 114,49,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119, + 95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111, + 99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119, + 95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114, + 111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111, + 121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101, + 108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101, + 110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111, + 110,6,1,48,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111, + 115,7,7,99,112,95,108,101,102,116,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,11,2,0,2,0, + 2,0,0,8,116,97,98,111,114,100,101,114,2,13,8,98,111,117,110,100, + 115,95,120,2,61,8,98,111,117,110,100,115,95,121,2,93,9,98,111,117, + 110,100,115,95,99,120,2,36,11,102,111,110,116,46,104,101,105,103,104,116, + 2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105, + 120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111, + 110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120, + 115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114, + 101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95, + 104,101,120,8,98,105,116,99,111,117,110,116,2,8,3,109,97,120,2,255, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,242,2, + 33,12,116,105,110,116,101,103,101,114,101,100,105,116,8,98,97,110,107,49, + 95,114,49,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,1,49,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112, + 111,115,7,7,99,112,95,108,101,102,116,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111, + 15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,11,2,0,2, + 0,2,0,0,8,116,97,98,111,114,100,101,114,2,25,8,98,111,117,110, + 100,115,95,120,2,61,8,98,111,117,110,100,115,95,121,3,136,0,9,98, + 111,117,110,100,115,95,99,120,2,36,11,102,111,110,116,46,104,101,105,103, + 104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95, + 102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15, + 102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112, + 95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7, + 11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110, + 98,95,104,101,120,8,98,105,116,99,111,117,110,116,2,8,3,109,97,120, + 2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0, + 242,2,34,12,116,105,110,116,101,103,101,114,101,100,105,116,8,98,97,110, + 107,49,95,114,48,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,7,0,0,144,16,102,114,97,109,101,46,99,97,112, + 116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101, + 118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 0,8,116,97,98,111,114,100,101,114,2,26,8,98,111,117,110,100,115,95, + 120,2,97,8,98,111,117,110,100,115,95,121,3,136,0,9,98,111,117,110, + 100,115,95,99,120,2,25,11,102,111,110,116,46,104,101,105,103,104,116,2, + 14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120, + 101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110, + 116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115, + 99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101, + 103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104, + 101,120,8,98,105,116,99,111,117,110,116,2,8,3,109,97,120,2,255,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,242,2,35, + 12,116,105,110,116,101,103,101,114,101,100,105,116,9,98,97,110,107,49,95, + 114,112,48,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,16,102,114,97,109,101,46,99,97,112,116,105, + 111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101, + 118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 0,8,116,97,98,111,114,100,101,114,2,33,8,98,111,117,110,100,115,95, + 120,2,72,8,98,111,117,110,100,115,95,121,3,157,0,9,98,111,117,110, + 100,115,95,99,120,2,50,11,102,111,110,116,46,104,101,105,103,104,116,2, + 14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120, + 101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110, + 116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115, + 99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101, + 103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104, + 101,120,8,98,105,116,99,111,117,110,116,2,16,3,109,97,120,2,255,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,242,2,36, + 12,116,105,110,116,101,103,101,114,101,100,105,116,9,98,97,110,107,49,95, + 114,112,49,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,16,102,114,97,109,101,46,99,97,112,116,105, + 111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101, + 118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 0,8,116,97,98,111,114,100,101,114,2,34,8,98,111,117,110,100,115,95, + 120,2,123,8,98,111,117,110,100,115,95,121,3,157,0,9,98,111,117,110, + 100,115,95,99,120,2,50,11,102,111,110,116,46,104,101,105,103,104,116,2, + 14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120, + 101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110, + 116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115, + 99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101, + 103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104, + 101,120,8,98,105,116,99,111,117,110,116,2,16,3,109,97,120,2,255,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,242,2,37, + 12,116,105,110,116,101,103,101,114,101,100,105,116,8,98,97,110,107,49,95, + 114,51,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119, + 95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111, + 99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119, + 95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114, + 111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111, + 121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101, + 108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101, + 110,116,4,7,0,0,144,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116, + 97,98,111,114,100,101,114,2,27,8,98,111,117,110,100,115,95,120,2,123, + 8,98,111,117,110,100,115,95,121,3,136,0,9,98,111,117,110,100,115,95, + 99,120,2,25,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102, + 111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11, + 102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108, + 101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101, + 116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8, + 98,105,116,99,111,117,110,116,2,8,3,109,97,120,2,255,13,114,101,102, + 102,111,110,116,104,101,105,103,104,116,2,16,0,0,242,2,38,12,116,105, + 110,116,101,103,101,114,101,100,105,116,8,98,97,110,107,49,95,114,50,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111, + 117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114, + 114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102, + 111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 7,0,0,144,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111, + 115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102, + 114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111, + 114,100,101,114,2,28,8,98,111,117,110,100,115,95,120,3,148,0,8,98, + 111,117,110,100,115,95,121,3,136,0,9,98,111,117,110,100,115,95,99,120, + 2,25,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110, + 116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111, + 110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0, + 10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118, + 97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,98,105, + 116,99,111,117,110,116,2,8,3,109,97,120,2,255,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,16,0,0,242,2,39,12,116,105,110,116, + 101,103,101,114,101,100,105,116,9,98,97,110,107,49,95,114,112,50,13,111, + 112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117, + 115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13, + 111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114, + 111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111, + 99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100, + 103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255, + 17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7, + 0,0,144,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115, + 7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98, + 111,114,100,101,114,2,35,8,98,111,117,110,100,115,95,120,3,174,0,8, + 98,111,117,110,100,115,95,121,3,157,0,9,98,111,117,110,100,115,95,99, + 120,2,50,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111, + 110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102, + 111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101, + 0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116, + 118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,98, + 105,116,99,111,117,110,116,2,16,3,109,97,120,2,255,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,16,0,0,242,2,40,12,116,105,110, + 116,101,103,101,114,101,100,105,116,8,98,97,110,107,49,95,114,53,13,111, + 112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117, + 115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13, + 111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114, + 111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111, + 99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100, + 103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255, + 17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7, + 0,0,144,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115, + 7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114, + 108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114, + 100,101,114,2,29,8,98,111,117,110,100,115,95,120,3,174,0,8,98,111, + 117,110,100,115,95,121,3,136,0,9,98,111,117,110,100,115,95,99,120,2, + 25,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116, + 46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110, + 116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10, + 111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97, + 108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,98,105,116, + 99,111,117,110,116,2,8,3,109,97,120,2,255,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,16,0,0,242,2,41,12,116,105,110,116,101, + 103,101,114,101,100,105,116,8,98,97,110,107,49,95,114,52,13,111,112,116, + 105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101, + 102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119, + 95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119, + 102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117, + 115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102, + 114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0, + 144,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6, + 99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95, + 99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101, + 114,2,30,8,98,111,117,110,100,115,95,120,3,199,0,8,98,111,117,110, + 100,115,95,121,3,136,0,9,98,111,117,110,100,115,95,99,120,2,25,11, + 102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110, + 97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46, + 120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112, + 114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110, + 115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117, + 101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,98,105,116,99,111, + 117,110,116,2,8,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,16,0,0,242,2,42,12,116,105,110,116,101,103,101, + 114,101,100,105,116,9,98,97,110,107,49,95,114,112,51,13,111,112,116,105, + 111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102, + 111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95, + 97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102, + 111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115, + 111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116, + 115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144, + 16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99, + 112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108, + 95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100, + 101,114,2,36,8,98,111,117,110,100,115,95,120,3,225,0,8,98,111,117, + 110,100,115,95,121,3,157,0,9,98,111,117,110,100,115,95,99,120,2,50, + 11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46, + 110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116, + 46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111, + 110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108, + 117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,98,105,116,99, + 111,117,110,116,2,16,3,109,97,120,2,255,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,16,0,0,242,2,43,12,116,105,110,116,101,103, + 101,114,101,100,105,116,8,98,97,110,107,49,95,114,55,13,111,112,116,105, + 111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102, + 111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95, + 97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102, + 111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115, + 111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116, + 115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144, + 16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99, + 112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99, + 111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114, + 2,31,8,98,111,117,110,100,115,95,120,3,225,0,8,98,111,117,110,100, + 115,95,121,3,136,0,9,98,111,117,110,100,115,95,99,120,2,25,11,102, + 111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97, + 109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120, + 115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115, + 101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101, + 4,98,97,115,101,7,6,110,98,95,104,101,120,8,98,105,116,99,111,117, + 110,116,2,8,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,16,0,0,242,2,44,12,116,105,110,116,101,103,101,114, + 101,100,105,116,8,98,97,110,107,49,95,114,54,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109, + 101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,16,102, + 114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95, + 116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108, + 111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,32, + 8,98,111,117,110,100,115,95,120,3,250,0,8,98,111,117,110,100,115,95, + 121,3,136,0,9,98,111,117,110,100,115,95,99,120,2,25,11,102,111,110, + 116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101, + 6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99, + 97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116, + 118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98, + 97,115,101,7,6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116, + 2,8,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,16,0,0,242,2,45,12,116,105,110,116,101,103,101,114,101,100, + 105,116,8,98,97,110,107,50,95,114,49,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115, + 105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,1,50,16,102,114,97,109,101,46, + 99,97,112,116,105,111,110,112,111,115,7,7,99,112,95,108,101,102,116,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,11,2,0,2,0,2,0,0,8,116,97,98,111,114,100,101, + 114,2,37,8,98,111,117,110,100,115,95,120,2,61,8,98,111,117,110,100, + 115,95,121,3,179,0,9,98,111,117,110,100,115,95,99,120,2,36,11,102, + 111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97, + 109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120, + 115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115, + 101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101, + 4,98,97,115,101,7,6,110,98,95,104,101,120,8,98,105,116,99,111,117, + 110,116,2,8,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,16,0,0,242,2,46,12,116,105,110,116,101,103,101,114, + 101,100,105,116,8,98,97,110,107,50,95,114,48,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109, + 101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,16,102, + 114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95, + 116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108, + 111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,38, + 8,98,111,117,110,100,115,95,120,2,97,8,98,111,117,110,100,115,95,121, + 3,179,0,9,98,111,117,110,100,115,95,99,120,2,25,11,102,111,110,116, + 46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6, + 9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97, + 108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118, + 97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97, + 115,101,7,6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2, + 8,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,16,0,0,242,2,47,12,116,105,110,116,101,103,101,114,101,100,105, + 116,9,98,97,110,107,50,95,114,112,48,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115, + 105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,16,102,114,97, + 109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105, + 103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108, + 111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,45, + 8,98,111,117,110,100,115,95,120,2,72,8,98,111,117,110,100,115,95,121, + 3,200,0,9,98,111,117,110,100,115,95,99,120,2,50,11,102,111,110,116, + 46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6, + 9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97, + 108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118, + 97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97, + 115,101,7,6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2, + 16,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,16,0,0,242,2,48,12,116,105,110,116,101,103,101,114,101,100,105, + 116,9,98,97,110,107,50,95,114,112,49,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115, + 105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,16,102,114,97, + 109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105, + 103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108, + 111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,46, + 8,98,111,117,110,100,115,95,120,2,123,8,98,111,117,110,100,115,95,121, + 3,200,0,9,98,111,117,110,100,115,95,99,120,2,50,11,102,111,110,116, + 46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6, + 9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97, + 108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118, + 97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97, + 115,101,7,6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2, + 16,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,16,0,0,242,2,49,12,116,105,110,116,101,103,101,114,101,100,105, + 116,8,98,97,110,107,50,95,114,51,13,111,112,116,105,111,110,115,119,105, + 100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11, + 111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119, + 102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105, + 110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111, + 119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114, + 97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99, + 111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,16,102,114,97,109, + 101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,39,8,98,111, + 117,110,100,115,95,120,2,123,8,98,111,117,110,100,115,95,121,3,179,0, + 9,98,111,117,110,100,115,95,99,120,2,25,11,102,111,110,116,46,104,101, + 105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116, + 102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2, + 1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117, + 101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7, + 6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2,8,3,109, + 97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16, + 0,0,242,2,50,12,116,105,110,116,101,103,101,114,101,100,105,116,8,98, + 97,110,107,50,95,114,50,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95, + 116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111, + 119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100, + 101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101, + 46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111, + 114,99,108,105,101,110,116,4,7,0,0,144,16,102,114,97,109,101,46,99, + 97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95, + 108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101, + 110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,8,116,97,98,111,114,100,101,114,2,40,8,98,111,117,110,100, + 115,95,120,3,148,0,8,98,111,117,110,100,115,95,121,3,179,0,9,98, + 111,117,110,100,115,95,99,120,2,25,11,102,111,110,116,46,104,101,105,103, + 104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95, + 102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15, + 102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112, + 95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7, + 11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110, + 98,95,104,101,120,8,98,105,116,99,111,117,110,116,2,8,3,109,97,120, + 2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0, + 242,2,51,12,116,105,110,116,101,103,101,114,101,100,105,116,9,98,97,110, + 107,50,95,114,112,50,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119, + 95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46, + 108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114, + 99,108,105,101,110,116,4,7,0,0,144,16,102,114,97,109,101,46,99,97, + 112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108, + 95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105, + 101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,8,116,97,98,111,114,100,101,114,2,47,8,98,111,117,110, + 100,115,95,120,3,174,0,8,98,111,117,110,100,115,95,121,3,200,0,9, + 98,111,117,110,100,115,95,99,120,2,50,11,102,111,110,116,46,104,101,105, + 103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102, + 95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1, + 15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108, + 112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101, + 7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6, + 110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2,16,3,109,97, + 120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0, + 0,242,2,52,12,116,105,110,116,101,103,101,114,101,100,105,116,8,98,97, + 110,107,50,95,114,53,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119, + 95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46, + 108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114, + 99,108,105,101,110,116,4,7,0,0,144,16,102,114,97,109,101,46,99,97, + 112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,8,116,97,98,111,114,100,101,114,2,41,8,98,111,117,110,100,115, + 95,120,3,174,0,8,98,111,117,110,100,115,95,121,3,179,0,9,98,111, + 117,110,100,115,95,99,120,2,25,11,102,111,110,116,46,104,101,105,103,104, + 116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102, + 105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102, + 111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95, + 120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11, + 114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98, + 95,104,101,120,8,98,105,116,99,111,117,110,116,2,8,3,109,97,120,2, + 255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,242, + 2,53,12,116,105,110,116,101,103,101,114,101,100,105,116,8,98,97,110,107, + 50,95,114,52,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13, + 111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98, + 102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15, + 111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97, + 114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116, + 114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101, + 118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108, + 105,101,110,116,4,7,0,0,144,16,102,114,97,109,101,46,99,97,112,116, + 105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 8,116,97,98,111,114,100,101,114,2,42,8,98,111,117,110,100,115,95,120, + 3,199,0,8,98,111,117,110,100,115,95,121,3,179,0,9,98,111,117,110, + 100,115,95,99,120,2,25,11,102,111,110,116,46,104,101,105,103,104,116,2, + 14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120, + 101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110, + 116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115, + 99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101, + 103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104, + 101,120,8,98,105,116,99,111,117,110,116,2,8,3,109,97,120,2,255,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,242,2,54, + 12,116,105,110,116,101,103,101,114,101,100,105,116,9,98,97,110,107,50,95, + 114,112,51,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,16,102,114,97,109,101,46,99,97,112,116,105, + 111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101, + 118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 0,8,116,97,98,111,114,100,101,114,2,48,8,98,111,117,110,100,115,95, + 120,3,225,0,8,98,111,117,110,100,115,95,121,3,200,0,9,98,111,117, + 110,100,115,95,99,120,2,50,11,102,111,110,116,46,104,101,105,103,104,116, + 2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105, + 120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111, + 110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120, + 115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114, + 101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95, + 104,101,120,8,98,105,116,99,111,117,110,116,2,16,3,109,97,120,2,255, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,242,2, + 55,12,116,105,110,116,101,103,101,114,101,100,105,116,8,98,97,110,107,50, + 95,114,55,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,16,102,114,97,109,101,46,99,97,112,116,105, + 111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101, + 108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8, + 116,97,98,111,114,100,101,114,2,43,8,98,111,117,110,100,115,95,120,3, + 225,0,8,98,111,117,110,100,115,95,121,3,179,0,9,98,111,117,110,100, + 115,95,99,120,2,25,11,102,111,110,116,46,104,101,105,103,104,116,2,14, + 9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101, + 100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99, + 97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103, + 115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101, + 120,8,98,105,116,99,111,117,110,116,2,8,3,109,97,120,2,255,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,242,2,56,12, + 116,105,110,116,101,103,101,114,101,100,105,116,8,98,97,110,107,50,95,114, + 54,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95, + 97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111, + 119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121, + 119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108, + 111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110, + 116,4,7,0,0,144,16,102,114,97,109,101,46,99,97,112,116,105,111,110, + 112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111, + 15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97, + 98,111,114,100,101,114,2,44,8,98,111,117,110,100,115,95,120,3,250,0, + 8,98,111,117,110,100,115,95,121,3,179,0,9,98,111,117,110,100,115,95, + 99,120,2,25,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102, + 111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11, + 102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108, + 101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101, + 116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8, + 98,105,116,99,111,117,110,116,2,8,3,109,97,120,2,255,13,114,101,102, + 102,111,110,116,104,101,105,103,104,116,2,16,0,0,242,2,57,12,116,105, + 110,116,101,103,101,114,101,100,105,116,8,98,97,110,107,51,95,114,49,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111, + 117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114, + 114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102, + 111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1, + 51,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,7, + 99,112,95,108,101,102,116,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108, + 95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,11,2,0,2,0,2,0,0, + 8,116,97,98,111,114,100,101,114,2,49,8,98,111,117,110,100,115,95,120, + 2,61,8,98,111,117,110,100,115,95,121,3,222,0,9,98,111,117,110,100, + 115,95,99,120,2,36,11,102,111,110,116,46,104,101,105,103,104,116,2,14, + 9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101, + 100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99, + 97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103, + 115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101, + 120,8,98,105,116,99,111,117,110,116,2,8,3,109,97,120,2,255,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,242,2,58,12, + 116,105,110,116,101,103,101,114,101,100,105,116,8,98,97,110,107,51,95,114, + 48,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95, + 97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111, + 119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121, + 119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108, + 111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110, + 116,4,7,0,0,144,16,102,114,97,109,101,46,99,97,112,116,105,111,110, + 112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111, + 15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97, + 98,111,114,100,101,114,2,50,8,98,111,117,110,100,115,95,120,2,97,8, + 98,111,117,110,100,115,95,121,3,222,0,9,98,111,117,110,100,115,95,99, + 120,2,25,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111, + 110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102, + 111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101, + 0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116, + 118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,98, + 105,116,99,111,117,110,116,2,8,3,109,97,120,2,255,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,16,0,0,242,2,59,12,116,105,110, + 116,101,103,101,114,101,100,105,116,9,98,97,110,107,51,95,114,112,48,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111, + 117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114, + 114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102, + 111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 7,0,0,144,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111, + 115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111, + 15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97, + 98,111,114,100,101,114,2,57,8,98,111,117,110,100,115,95,120,2,72,8, + 98,111,117,110,100,115,95,121,3,243,0,9,98,111,117,110,100,115,95,99, + 120,2,50,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111, + 110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102, + 111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101, + 0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116, + 118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,98, + 105,116,99,111,117,110,116,2,16,3,109,97,120,2,255,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,16,0,0,242,2,60,12,116,105,110, + 116,101,103,101,114,101,100,105,116,9,98,97,110,107,51,95,114,112,49,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111, + 117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114, + 114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102, + 111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 7,0,0,144,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111, + 115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111, + 15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97, + 98,111,114,100,101,114,2,58,8,98,111,117,110,100,115,95,120,2,123,8, + 98,111,117,110,100,115,95,121,3,243,0,9,98,111,117,110,100,115,95,99, + 120,2,50,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111, + 110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102, + 111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101, + 0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116, + 118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,98, + 105,116,99,111,117,110,116,2,16,3,109,97,120,2,255,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,16,0,0,242,2,61,12,116,105,110, + 116,101,103,101,114,101,100,105,116,8,98,97,110,107,51,95,114,51,13,111, + 112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117, + 115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13, + 111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114, + 111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111, + 99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100, + 103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255, + 17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7, + 0,0,144,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115, + 7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114, + 108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114, + 100,101,114,2,51,8,98,111,117,110,100,115,95,120,2,123,8,98,111,117, + 110,100,115,95,121,3,222,0,9,98,111,117,110,100,115,95,99,120,2,25, + 11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46, + 110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116, + 46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111, + 110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108, + 117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,98,105,116,99, + 111,117,110,116,2,8,3,109,97,120,2,255,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,16,0,0,242,2,62,12,116,105,110,116,101,103, + 101,114,101,100,105,116,8,98,97,110,107,51,95,114,50,13,111,112,116,105, + 111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102, + 111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95, + 97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102, + 111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115, + 111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116, + 115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144, + 16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99, + 112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99, + 111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114, + 2,52,8,98,111,117,110,100,115,95,120,3,148,0,8,98,111,117,110,100, + 115,95,121,3,222,0,9,98,111,117,110,100,115,95,99,120,2,25,11,102, + 111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97, + 109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120, + 115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115, + 101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101, + 4,98,97,115,101,7,6,110,98,95,104,101,120,8,98,105,116,99,111,117, + 110,116,2,8,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,16,0,0,242,2,63,12,116,105,110,116,101,103,101,114, + 101,100,105,116,9,98,97,110,107,51,95,114,112,50,13,111,112,116,105,111, + 110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111, + 99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97, + 114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111, + 99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111, + 117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97, + 109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,16, + 102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112, + 95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95, + 99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101, + 114,2,59,8,98,111,117,110,100,115,95,120,3,174,0,8,98,111,117,110, + 100,115,95,121,3,243,0,9,98,111,117,110,100,115,95,99,120,2,50,11, + 102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110, + 97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46, + 120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112, + 114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110, + 115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117, + 101,4,98,97,115,101,7,6,110,98,95,104,101,120,8,98,105,116,99,111, + 117,110,116,2,16,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,16,0,0,242,2,64,12,116,105,110,116,101,103,101, + 114,101,100,105,116,8,98,97,110,107,51,95,114,53,13,111,112,116,105,111, + 110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111, + 99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97, + 114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111, + 99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111, + 117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97, + 109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,16, + 102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112, + 95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111, + 108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2, + 53,8,98,111,117,110,100,115,95,120,3,174,0,8,98,111,117,110,100,115, + 95,121,3,222,0,9,98,111,117,110,100,115,95,99,120,2,25,11,102,111, + 110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109, + 101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115, + 99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101, + 116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4, + 98,97,115,101,7,6,110,98,95,104,101,120,8,98,105,116,99,111,117,110, + 116,2,8,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,16,0,0,242,2,65,12,116,105,110,116,101,103,101,114,101, + 100,105,116,8,98,97,110,107,51,95,114,52,13,111,112,116,105,111,110,115, + 119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117, + 115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114, + 111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117, + 115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116, + 17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12, + 102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101, + 46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,16,102,114, + 97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116, + 111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111, + 114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,54,8, + 98,111,117,110,100,115,95,120,3,199,0,8,98,111,117,110,100,115,95,121, + 3,222,0,9,98,111,117,110,100,115,95,99,120,2,25,11,102,111,110,116, + 46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6, + 9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97, + 108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118, + 97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97, + 115,101,7,6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2, + 8,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,16,0,0,242,2,66,12,116,105,110,116,101,103,101,114,101,100,105, + 116,9,98,97,110,107,51,95,114,112,51,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115, + 105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,16,102,114,97, + 109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105, + 103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108, + 111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,60, + 8,98,111,117,110,100,115,95,120,3,225,0,8,98,111,117,110,100,115,95, + 121,3,243,0,9,98,111,117,110,100,115,95,99,120,2,50,11,102,111,110, + 116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101, + 6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99, + 97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116, + 118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98, + 97,115,101,7,6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116, + 2,16,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,16,0,0,242,2,67,12,116,105,110,116,101,103,101,114,101,100, + 105,116,8,98,97,110,107,51,95,114,55,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115, + 105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,16,102,114,97, + 109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111, + 112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,55,8,98, + 111,117,110,100,115,95,120,3,225,0,8,98,111,117,110,100,115,95,121,3, + 222,0,9,98,111,117,110,100,115,95,99,120,2,25,11,102,111,110,116,46, + 104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9, + 115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108, + 101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97, + 108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115, + 101,7,6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2,8, + 3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,16,0,0,242,2,68,12,116,105,110,116,101,103,101,114,101,100,105,116, + 8,98,97,110,107,51,95,114,54,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111, + 119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102, + 111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110, + 16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119, + 95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97, + 109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111, + 108,111,114,99,108,105,101,110,116,4,7,0,0,144,16,102,114,97,109,101, + 46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,56,8,98,111,117, + 110,100,115,95,120,3,250,0,8,98,111,117,110,100,115,95,121,3,222,0, + 9,98,111,117,110,100,115,95,99,120,2,25,11,102,111,110,116,46,104,101, + 105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116, + 102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2, + 1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117, + 101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7, + 6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2,8,3,109, + 97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16, + 0,0,242,2,69,12,116,105,110,116,101,103,101,114,101,100,105,116,3,109, + 101,109,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119, + 95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111, + 99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119, + 95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114, + 111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111, + 121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101, + 108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101, + 110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111, + 110,6,3,77,69,77,16,102,114,97,109,101,46,99,97,112,116,105,111,110, + 112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101, + 108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2, + 0,2,31,2,0,0,8,116,97,98,111,114,100,101,114,2,66,8,98,111, + 117,110,100,115,95,120,3,25,1,8,98,111,117,110,100,115,95,121,3,157, + 0,9,98,111,117,110,100,115,95,99,120,2,81,11,102,111,110,116,46,104, + 101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115, + 116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101, + 2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108, + 117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101, + 7,6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2,8,3, + 109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 16,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tcpurl78fo,''); +end. diff --git a/mseide-msegui/apps/ide/cpux86_64form.mfm b/mseide-msegui/apps/ide/cpux86_64form.mfm new file mode 100644 index 0000000..790b363 --- /dev/null +++ b/mseide-msegui/apps/ide/cpux86_64form.mfm @@ -0,0 +1,807 @@ +inherited cpuc86_64fo: tcpux86_64fo + optionswidget = [ow_arrowfocus, ow_subfocus, ow_mousewheel, ow_destroywidgets, ow_hinton] + bounds_x = 183 + bounds_y = 113 + bounds_cx = 352 + bounds_cy = 277 + container.onlayout = cpufoonchildscaled + container.bounds = ( + 0 + 0 + 342 + 277 + ) + caption = 'CPU X68_64' + onlayout = cpufoonchildscaled + moduleclassname = 'tcpufo' + inherited on: tbooleanedit + bounds_x = 215 + bounds_y = 1 + end + inherited stoptime: tdatetimedisp + bounds_x = -8 + bounds_y = 0 + bounds_cx = 141 + end + object tspacer1: tspacer[2] + taborder = 2 + visible = True + bounds_x = 0 + bounds_y = 18 + bounds_cx = 341 + bounds_cy = 249 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + linktop = stoptime + object r14: tint64edit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r14' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 24 + 0 + ) + bounds_x = 176 + bounds_y = 208 + bounds_cx = 165 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object r13: tint64edit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r13' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 24 + 0 + ) + taborder = 1 + bounds_x = 176 + bounds_y = 187 + bounds_cx = 165 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object r12: tint64edit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r12' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 24 + 0 + ) + taborder = 2 + bounds_x = 176 + bounds_y = 166 + bounds_cx = 165 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object r11: tint64edit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r11' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 24 + 0 + ) + taborder = 3 + bounds_x = 176 + bounds_y = 145 + bounds_cx = 165 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object r10: tint64edit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r10' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 24 + 0 + ) + taborder = 4 + bounds_x = 176 + bounds_y = 124 + bounds_cx = 165 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object r15: tint64edit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r15' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 24 + 0 + ) + taborder = 5 + bounds_x = 176 + bounds_y = 229 + bounds_cx = 165 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object r9: tint64edit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r9' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 16 + 0 + ) + taborder = 6 + bounds_x = 0 + bounds_y = 229 + bounds_cx = 157 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object r8: tint64edit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'r8' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 16 + 0 + ) + taborder = 7 + bounds_x = 0 + bounds_y = 208 + bounds_cx = 157 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object io: tbooleanedit + Tag = 12 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'IO' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 1 + 17 + 2 + 0 + ) + taborder = 8 + bounds_x = 57 + bounds_y = 9 + bounds_cx = 14 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object nt: tbooleanedit + Tag = 15 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'NT' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 3 + 17 + 4 + 0 + ) + taborder = 9 + bounds_x = 37 + bounds_y = 9 + bounds_cx = 18 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object c: tbooleanedit + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'C' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 10 + bounds_x = 161 + bounds_y = 9 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object p: tbooleanedit + Tag = 2 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'P' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 11 + bounds_x = 150 + bounds_y = 9 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object a: tbooleanedit + Tag = 4 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'A' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 12 + bounds_x = 139 + bounds_y = 9 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object z: tbooleanedit + Tag = 6 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'Z' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 13 + bounds_x = 128 + bounds_y = 9 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object s: tbooleanedit + Tag = 7 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'S' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 14 + bounds_x = 117 + bounds_y = 9 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object t: tbooleanedit + Tag = 8 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'T' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 15 + bounds_x = 106 + bounds_y = 9 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object i: tbooleanedit + Tag = 9 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'I' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 16 + bounds_x = 95 + bounds_y = 9 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object d: tbooleanedit + Tag = 10 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'D' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 17 + bounds_x = 84 + bounds_y = 9 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object o: tbooleanedit + Tag = 11 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'O' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 18 + bounds_x = 73 + bounds_y = 9 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object eflags: tint64edit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'rfl' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 15 + 0 + ) + taborder = 19 + bounds_x = 176 + bounds_y = 40 + bounds_cx = 155 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onchange = flagonchange + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object rip: tint64edit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'rip' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + taborder = 20 + bounds_x = 176 + bounds_y = 82 + bounds_cx = 159 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object rsp: tint64edit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'rsp' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 23 + 0 + ) + taborder = 21 + bounds_x = 176 + bounds_y = 61 + bounds_cx = 163 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object rbp: tint64edit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'rbp' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 24 + 0 + ) + taborder = 22 + bounds_x = 0 + bounds_y = 124 + bounds_cx = 165 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object rdi: tint64edit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'rdi' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 19 + 0 + ) + taborder = 23 + bounds_x = 0 + bounds_y = 166 + bounds_cx = 160 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object rsi: tint64edit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'rsi' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 18 + 0 + ) + taborder = 24 + bounds_x = 0 + bounds_y = 145 + bounds_cx = 159 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object rdx: tint64edit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'rdx' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 22 + 0 + ) + taborder = 25 + bounds_x = 0 + bounds_y = 103 + bounds_cx = 163 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object rcx: tint64edit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'rcx' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 21 + 0 + ) + taborder = 26 + bounds_x = 0 + bounds_y = 82 + bounds_cx = 162 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object rbx: tint64edit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'rbx' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 22 + 0 + ) + taborder = 27 + bounds_x = 0 + bounds_y = 61 + bounds_cx = 163 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object rax: tint64edit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'rax' + frame.captionpos = cp_right + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 22 + 0 + ) + taborder = 28 + bounds_x = 0 + bounds_y = 40 + bounds_cx = 163 + font.height = 14 + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + onsetvalue = regsetvalue + base = nb_hex + max = -1 + reffontheight = 16 + end + object r: tbooleanedit + Tag = 16 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'R' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 29 + bounds_x = 23 + bounds_y = 9 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + object v: tbooleanedit + Tag = 17 + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -1879048185 + frame.caption = 'V' + frame.captionpos = cp_top + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 30 + bounds_x = 7 + bounds_y = 9 + bounds_cx = 11 + bounds_cy = 28 + onsetvalue = flagsetvalue + end + end +end diff --git a/mseide-msegui/apps/ide/cpux86_64form.pas b/mseide-msegui/apps/ide/cpux86_64form.pas new file mode 100644 index 0000000..65dc549 --- /dev/null +++ b/mseide-msegui/apps/ide/cpux86_64form.pas @@ -0,0 +1,133 @@ +{ MSEide Copyright (c) 2009-2013 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit cpux86_64form; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +uses + classes,mclasses,msegui,mseclasses,mseforms,msegdbutils,msetypes,msedataedits, + msegraphics,msegraphedits,cpuform,msegraphutils,mseguiglob,msemenus, + msesimplewidgets,msewidgets,mseedit,msestrings,msesplitter; + +type + + tcpux86_64fo = class(tcpufo) + tspacer1: tspacer; + r14: tint64edit; + r13: tint64edit; + r12: tint64edit; + r11: tint64edit; + r10: tint64edit; + r15: tint64edit; + r9: tint64edit; + r8: tint64edit; + io: tbooleanedit; + nt: tbooleanedit; + c: tbooleanedit; + p: tbooleanedit; + a: tbooleanedit; + z: tbooleanedit; + s: tbooleanedit; + t: tbooleanedit; + i: tbooleanedit; + d: tbooleanedit; + o: tbooleanedit; + eflags: tint64edit; + rip: tint64edit; + rsp: tint64edit; + rbp: tint64edit; + rdi: tint64edit; + rsi: tint64edit; + rdx: tint64edit; + rcx: tint64edit; + rbx: tint64edit; + rax: tint64edit; + r: tbooleanedit; + v: tbooleanedit; + procedure flagonchange(const sender: TObject); + procedure flagsetvalue(const sender: TObject; var avalue: Boolean; var accept: Boolean); +// procedure ononchange(const sender: TObject); + procedure regsetvalue(const sender: TObject; var avalue: Int64; var accept: Boolean); + procedure cpufoonchildscaled(const sender: TObject); + public + constructor create(aowner: tcomponent); override; + function flagedit(const aindex: integer): tcustombooleanedit; override; + end; + +implementation +uses + cpux86_64form_mfm,main,sysutils,mseformatstr,msebits; + +{ tcpux86_64fo } + +constructor tcpux86_64fo.create(aowner: tcomponent); +begin + inherited create(aowner); + fflagswidget64:= eflags; +end; + +procedure tcpux86_64fo.flagonchange(const sender: TObject); +begin + doflagonchange(sender); +end; + +procedure tcpux86_64fo.flagsetvalue(const sender: TObject; + var avalue: Boolean; var accept: Boolean); +begin + doflagsetvalue(sender,avalue,accept); +end; +{ +procedure tcpux86_64fo.ononchange(const sender: TObject); +var + int1: integer; +begin + if on.value then begin + for int1:= 0 to childrencount - 1 do begin + children[int1].enabled:= true; + end; + refresh; + end + else begin + for int1:= 0 to childrencount - 1 do begin + if children[int1] <> sender then begin + children[int1].enabled:= false; + end; + end; + end; +end; +} +procedure tcpux86_64fo.regsetvalue(const sender: TObject; var avalue: Int64; var accept: Boolean); +begin + doregset64value(sender,avalue,accept); +end; + +procedure tcpux86_64fo.cpufoonchildscaled(const sender: TObject); +begin + placeyorder(rax.bounds_y,[0],[rax,rbx,rcx,rdx,rbp,rsi,rdi]); + placeyorder(rdi.bounds_y+2*rdi.bounds_cy,[0],[r8,r9]); + placeyorder(eflags.bounds_y,[0],[eflags,rsp,rip]); + placeyorder(rbp.bounds_y,[0],[r10,r11,r12,r13,r14,r15]); +end; + +function tcpux86_64fo.flagedit(const aindex: integer): tcustombooleanedit; +begin + result:= c.tagitem(aindex); +end; + +end. diff --git a/mseide-msegui/apps/ide/cpux86_64form_mfm.pas b/mseide-msegui/apps/ide/cpux86_64form_mfm.pas new file mode 100644 index 0000000..2a88609 --- /dev/null +++ b/mseide-msegui/apps/ide/cpux86_64form_mfm.pas @@ -0,0 +1,671 @@ +unit cpux86_64form_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,cpux86_64form; + +const + objdata: record size: integer; data: array[0..13079] of byte end = + (size: 13080; data: ( + 84,80,70,48,241,12,116,99,112,117,120,56,54,95,54,52,102,111,11,99, + 112,117,99,56,54,95,54,52,102,111,13,111,112,116,105,111,110,115,119,105, + 100,103,101,116,11,13,111,119,95,97,114,114,111,119,102,111,99,117,115,11, + 111,119,95,115,117,98,102,111,99,117,115,13,111,119,95,109,111,117,115,101, + 119,104,101,101,108,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,9,111,119,95,104,105,110,116,111,110,0,8,98,111,117,110,100, + 115,95,120,3,183,0,8,98,111,117,110,100,115,95,121,2,113,9,98,111, + 117,110,100,115,95,99,120,3,96,1,9,98,111,117,110,100,115,95,99,121, + 3,21,1,18,99,111,110,116,97,105,110,101,114,46,111,110,108,97,121,111, + 117,116,7,18,99,112,117,102,111,111,110,99,104,105,108,100,115,99,97,108, + 101,100,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1, + 2,0,2,0,3,86,1,3,21,1,0,7,99,97,112,116,105,111,110,6, + 10,67,80,85,32,88,54,56,95,54,52,8,111,110,108,97,121,111,117,116, + 7,18,99,112,117,102,111,111,110,99,104,105,108,100,115,99,97,108,101,100, + 15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,6,116,99, + 112,117,102,111,0,241,12,116,98,111,111,108,101,97,110,101,100,105,116,2, + 111,110,8,98,111,117,110,100,115,95,120,3,215,0,8,98,111,117,110,100, + 115,95,121,2,1,0,0,241,13,116,100,97,116,101,116,105,109,101,100,105, + 115,112,8,115,116,111,112,116,105,109,101,8,98,111,117,110,100,115,95,120, + 2,248,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,3,141,0,0,0,242,2,2,7,116,115,112,97,99,101,114,8, + 116,115,112,97,99,101,114,49,8,116,97,98,111,114,100,101,114,2,2,7, + 118,105,115,105,98,108,101,9,8,98,111,117,110,100,115,95,120,2,0,8, + 98,111,117,110,100,115,95,121,2,18,9,98,111,117,110,100,115,95,99,120, + 3,85,1,9,98,111,117,110,100,115,95,99,121,3,249,0,12,111,112,116, + 105,111,110,115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97,110, + 100,120,11,111,115,99,95,115,104,114,105,110,107,120,11,111,115,99,95,101, + 120,112,97,110,100,121,11,111,115,99,95,115,104,114,105,110,107,121,0,7, + 108,105,110,107,116,111,112,7,8,115,116,111,112,116,105,109,101,0,10,116, + 105,110,116,54,52,101,100,105,116,3,114,49,52,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109, + 101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,3,114,49,52,16,102,114, + 97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114, + 105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111, + 108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,0,2,24,2,0,0,8,98,111, + 117,110,100,115,95,120,3,176,0,8,98,111,117,110,100,115,95,121,3,208, + 0,9,98,111,117,110,100,115,95,99,120,3,165,0,11,102,111,110,116,46, + 104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9, + 115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108, + 101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97, + 108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115, + 101,7,6,110,98,95,104,101,120,3,109,97,120,2,255,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,16,0,0,10,116,105,110,116,54,52, + 101,100,105,116,3,114,49,51,13,111,112,116,105,111,110,115,119,105,100,103, + 101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119, + 95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111, + 99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16, + 111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109, + 101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108, + 111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,3,114,49,51,16,102,114,97,109,101,46,99, + 97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,0,2,24,2,0,0,8,116,97,98,111,114,100,101, + 114,2,1,8,98,111,117,110,100,115,95,120,3,176,0,8,98,111,117,110, + 100,115,95,121,3,187,0,9,98,111,117,110,100,115,95,99,120,3,165,0, + 11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46, + 110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116, + 46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111, + 110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108, + 117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,3,109,97,120,2, + 255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,10, + 116,105,110,116,54,52,101,100,105,116,3,114,49,50,13,111,112,116,105,111, + 110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111, + 99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97, + 114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111, + 99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111, + 117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97, + 109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,3,114,49,50,16,102, + 114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95, + 114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99, + 111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117, + 116,101,114,102,114,97,109,101,1,2,0,2,0,2,24,2,0,0,8,116, + 97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,3,176, + 0,8,98,111,117,110,100,115,95,121,3,166,0,9,98,111,117,110,100,115, + 95,99,120,3,165,0,11,102,111,110,116,46,104,101,105,103,104,116,2,14, + 9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101, + 100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99, + 97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103, + 115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101, + 120,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,16,0,0,10,116,105,110,116,54,52,101,100,105,116,3,114,49,49, + 13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109, + 111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117, + 115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97, + 114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119, + 102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111, + 2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116, + 4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 3,114,49,49,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111, + 115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111, + 15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2, + 24,2,0,0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117,110, + 100,115,95,120,3,176,0,8,98,111,117,110,100,115,95,121,3,145,0,9, + 98,111,117,110,100,115,95,99,120,3,165,0,11,102,111,110,116,46,104,101, + 105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116, + 102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2, + 1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117, + 101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7, + 6,110,98,95,104,101,120,3,109,97,120,2,255,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,16,0,0,10,116,105,110,116,54,52,101,100, + 105,116,3,114,49,48,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119, + 95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46, + 108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114, + 99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,3,114,49,48,16,102,114,97,109,101,46,99,97,112, + 116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95, + 108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101, + 110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101, + 1,2,0,2,0,2,24,2,0,0,8,116,97,98,111,114,100,101,114,2, + 4,8,98,111,117,110,100,115,95,120,3,176,0,8,98,111,117,110,100,115, + 95,121,2,124,9,98,111,117,110,100,115,95,99,120,3,165,0,11,102,111, + 110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109, + 101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115, + 99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101, + 116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4, + 98,97,115,101,7,6,110,98,95,104,101,120,3,109,97,120,2,255,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,10,116,105,110, + 116,54,52,101,100,105,116,3,114,49,53,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115, + 105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,3,114,49,53,16,102,114,97,109, + 101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103, + 104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111, + 114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,0,2,24,2,0,0,8,116,97,98,111, + 114,100,101,114,2,5,8,98,111,117,110,100,115,95,120,3,176,0,8,98, + 111,117,110,100,115,95,121,3,229,0,9,98,111,117,110,100,115,95,99,120, + 3,165,0,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111, + 110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102, + 111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101, + 0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116, + 118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,3,109, + 97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16, + 0,0,10,116,105,110,116,54,52,101,100,105,116,2,114,57,13,111,112,116, + 105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101, + 102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119, + 95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119, + 102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117, + 115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102, + 114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0, + 144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,2,114,57,16, + 102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112, + 95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95, + 99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,16,2,0,0,8, + 116,97,98,111,114,100,101,114,2,6,8,98,111,117,110,100,115,95,120,2, + 0,8,98,111,117,110,100,115,95,121,3,229,0,9,98,111,117,110,100,115, + 95,99,120,3,157,0,11,102,111,110,116,46,104,101,105,103,104,116,2,14, + 9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101, + 100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99, + 97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103, + 115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101, + 120,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,16,0,0,10,116,105,110,116,54,52,101,100,105,116,2,114,56,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111, + 117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114, + 114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102, + 111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,2, + 114,56,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7, + 8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102, + 114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109, + 101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,16,2, + 0,0,8,116,97,98,111,114,100,101,114,2,7,8,98,111,117,110,100,115, + 95,120,2,0,8,98,111,117,110,100,115,95,121,3,208,0,9,98,111,117, + 110,100,115,95,99,120,3,157,0,11,102,111,110,116,46,104,101,105,103,104, + 116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102, + 105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102, + 111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95, + 120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11, + 114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98, + 95,104,101,120,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,16,0,0,12,116,98,111,111,108,101,97,110,101,100,105, + 116,2,105,111,3,84,97,103,2,12,5,99,111,108,111,114,4,3,0,0, + 128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97, + 109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,2,73,79,16,102,114, + 97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116, + 111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111, + 114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,1,2,17,2,2,2,0,0,8,116,97,98,111, + 114,100,101,114,2,8,8,98,111,117,110,100,115,95,120,2,57,8,98,111, + 117,110,100,115,95,121,2,9,9,98,111,117,110,100,115,95,99,120,2,14, + 9,98,111,117,110,100,115,95,99,121,2,28,10,111,110,115,101,116,118,97, + 108,117,101,7,12,102,108,97,103,115,101,116,118,97,108,117,101,0,0,12, + 116,98,111,111,108,101,97,110,101,100,105,116,2,110,116,3,84,97,103,2, + 15,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,2,78,84,16,102,114,97,109,101,46,99,97,112,116,105, + 111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101, + 108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,3,2, + 17,2,4,2,0,0,8,116,97,98,111,114,100,101,114,2,9,8,98,111, + 117,110,100,115,95,120,2,37,8,98,111,117,110,100,115,95,121,2,9,9, + 98,111,117,110,100,115,95,99,120,2,18,9,98,111,117,110,100,115,95,99, + 121,2,28,10,111,110,115,101,116,118,97,108,117,101,7,12,102,108,97,103, + 115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110,101, + 100,105,116,1,99,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97, + 109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111, + 108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,1,67,16,102,114,97,109,101,46,99,97, + 112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,10, + 8,98,111,117,110,100,115,95,120,3,161,0,8,98,111,117,110,100,115,95, + 121,2,9,9,98,111,117,110,100,115,95,99,120,2,11,9,98,111,117,110, + 100,115,95,99,121,2,28,10,111,110,115,101,116,118,97,108,117,101,7,12, + 102,108,97,103,115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108, + 101,97,110,101,100,105,116,1,112,3,84,97,103,2,2,5,99,111,108,111, + 114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1, + 80,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6, + 99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95, + 99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8, + 116,97,98,111,114,100,101,114,2,11,8,98,111,117,110,100,115,95,120,3, + 150,0,8,98,111,117,110,100,115,95,121,2,9,9,98,111,117,110,100,115, + 95,99,120,2,11,9,98,111,117,110,100,115,95,99,121,2,28,10,111,110, + 115,101,116,118,97,108,117,101,7,12,102,108,97,103,115,101,116,118,97,108, + 117,101,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,1,97,3, + 84,97,103,2,4,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97, + 109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111, + 108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,1,65,16,102,114,97,109,101,46,99,97, + 112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,12, + 8,98,111,117,110,100,115,95,120,3,139,0,8,98,111,117,110,100,115,95, + 121,2,9,9,98,111,117,110,100,115,95,99,120,2,11,9,98,111,117,110, + 100,115,95,99,121,2,28,10,111,110,115,101,116,118,97,108,117,101,7,12, + 102,108,97,103,115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108, + 101,97,110,101,100,105,116,1,122,3,84,97,103,2,6,5,99,111,108,111, + 114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1, + 90,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6, + 99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95, + 99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8, + 116,97,98,111,114,100,101,114,2,13,8,98,111,117,110,100,115,95,120,3, + 128,0,8,98,111,117,110,100,115,95,121,2,9,9,98,111,117,110,100,115, + 95,99,120,2,11,9,98,111,117,110,100,115,95,99,121,2,28,10,111,110, + 115,101,116,118,97,108,117,101,7,12,102,108,97,103,115,101,116,118,97,108, + 117,101,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,1,115,3, + 84,97,103,2,7,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97, + 109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111, + 108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,1,83,16,102,114,97,109,101,46,99,97, + 112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,14, + 8,98,111,117,110,100,115,95,120,2,117,8,98,111,117,110,100,115,95,121, + 2,9,9,98,111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100, + 115,95,99,121,2,28,10,111,110,115,101,116,118,97,108,117,101,7,12,102, + 108,97,103,115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101, + 97,110,101,100,105,116,1,116,3,84,97,103,2,8,5,99,111,108,111,114, + 4,3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255, + 17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7, + 0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1,84, + 16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99, + 112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99, + 111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117, + 116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116, + 97,98,111,114,100,101,114,2,15,8,98,111,117,110,100,115,95,120,2,106, + 8,98,111,117,110,100,115,95,121,2,9,9,98,111,117,110,100,115,95,99, + 120,2,11,9,98,111,117,110,100,115,95,99,121,2,28,10,111,110,115,101, + 116,118,97,108,117,101,7,12,102,108,97,103,115,101,116,118,97,108,117,101, + 0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,1,105,3,84,97, + 103,2,9,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101, + 46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111, + 114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99, + 97,112,116,105,111,110,6,1,73,16,102,114,97,109,101,46,99,97,112,116, + 105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,16,8,98, + 111,117,110,100,115,95,120,2,95,8,98,111,117,110,100,115,95,121,2,9, + 9,98,111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95, + 99,121,2,28,10,111,110,115,101,116,118,97,108,117,101,7,12,102,108,97, + 103,115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110, + 101,100,105,116,1,100,3,84,97,103,2,10,5,99,111,108,111,114,4,3, + 0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102, + 114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0, + 144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,1,68,16,102, + 114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95, + 116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108, + 111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101, + 114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98, + 111,114,100,101,114,2,17,8,98,111,117,110,100,115,95,120,2,84,8,98, + 111,117,110,100,115,95,121,2,9,9,98,111,117,110,100,115,95,99,120,2, + 11,9,98,111,117,110,100,115,95,99,121,2,28,10,111,110,115,101,116,118, + 97,108,117,101,7,12,102,108,97,103,115,101,116,118,97,108,117,101,0,0, + 12,116,98,111,111,108,101,97,110,101,100,105,116,1,111,3,84,97,103,2, + 11,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,1,79,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17, + 2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,18,8,98,111,117, + 110,100,115,95,120,2,73,8,98,111,117,110,100,115,95,121,2,9,9,98, + 111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95,99,121, + 2,28,10,111,110,115,101,116,118,97,108,117,101,7,12,102,108,97,103,115, + 101,116,118,97,108,117,101,0,0,10,116,105,110,116,54,52,101,100,105,116, + 6,101,102,108,97,103,115,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95, + 116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111, + 119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100, + 101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101, + 46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111, + 114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99, + 97,112,116,105,111,110,6,3,114,102,108,16,102,114,97,109,101,46,99,97, + 112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108, + 95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105, + 101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109, + 101,1,2,0,2,0,2,15,2,0,0,8,116,97,98,111,114,100,101,114, + 2,19,8,98,111,117,110,100,115,95,120,3,176,0,8,98,111,117,110,100, + 115,95,121,2,40,9,98,111,117,110,100,115,95,99,120,3,155,0,11,102, + 111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97, + 109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120, + 115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,8,111,110,99, + 104,97,110,103,101,7,12,102,108,97,103,111,110,99,104,97,110,103,101,10, + 111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97, + 108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,3,109,97,120, + 2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0, + 10,116,105,110,116,54,52,101,100,105,116,3,114,105,112,13,111,112,116,105, + 111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102, + 111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95, + 97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102, + 111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115, + 111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116, + 115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,3,114,105,112,16, + 102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112, + 95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95, + 99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,19,2,0,0,8, + 116,97,98,111,114,100,101,114,2,20,8,98,111,117,110,100,115,95,120,3, + 176,0,8,98,111,117,110,100,115,95,121,2,82,9,98,111,117,110,100,115, + 95,99,120,3,159,0,11,102,111,110,116,46,104,101,105,103,104,116,2,14, + 9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101, + 100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99, + 97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103, + 115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101, + 120,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,16,0,0,10,116,105,110,116,54,52,101,100,105,116,3,114,115,112, + 13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109, + 111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117, + 115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97, + 114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119, + 102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111, + 2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116, + 4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 3,114,115,112,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111, + 115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111, + 15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2, + 23,2,0,0,8,116,97,98,111,114,100,101,114,2,21,8,98,111,117,110, + 100,115,95,120,3,176,0,8,98,111,117,110,100,115,95,121,2,61,9,98, + 111,117,110,100,115,95,99,120,3,163,0,11,102,111,110,116,46,104,101,105, + 103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102, + 95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1, + 15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108, + 112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101, + 7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6, + 110,98,95,104,101,120,3,109,97,120,2,255,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,16,0,0,10,116,105,110,116,54,52,101,100,105, + 116,3,114,98,112,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,3,114,98,112,16,102,114,97,109,101,46,99,97,112,116, + 105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,0,2,24,2,0,0,8,116,97,98,111,114,100,101,114,2,22, + 8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121, + 2,124,9,98,111,117,110,100,115,95,99,120,3,165,0,11,102,111,110,116, + 46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6, + 9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97, + 108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118, + 97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97, + 115,101,7,6,110,98,95,104,101,120,3,109,97,120,2,255,13,114,101,102, + 102,111,110,116,104,101,105,103,104,116,2,16,0,0,10,116,105,110,116,54, + 52,101,100,105,116,3,114,100,105,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111, + 119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102, + 111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110, + 16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119, + 95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97, + 109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111, + 108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,3,114,100,105,16,102,114,97,109,101,46, + 99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,0,2,19,2,0,0,8,116,97,98,111,114,100, + 101,114,2,23,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110, + 100,115,95,121,3,166,0,9,98,111,117,110,100,115,95,99,120,3,160,0, + 11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46, + 110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116, + 46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111, + 110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108, + 117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,3,109,97,120,2, + 255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,10, + 116,105,110,116,54,52,101,100,105,116,3,114,115,105,13,111,112,116,105,111, + 110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111, + 99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97, + 114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111, + 99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111, + 117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97, + 109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,3,114,115,105,16,102, + 114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95, + 114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99, + 111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117, + 116,101,114,102,114,97,109,101,1,2,0,2,0,2,18,2,0,0,8,116, + 97,98,111,114,100,101,114,2,24,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,3,145,0,9,98,111,117,110,100,115,95, + 99,120,3,159,0,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9, + 102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100, + 11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46, + 108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97, + 108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115, + 101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120, + 3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,16,0,0,10,116,105,110,116,54,52,101,100,105,116,3,114,100,120,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111, + 117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114, + 114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102, + 111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,3, + 114,100,120,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115, + 7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,22, + 2,0,0,8,116,97,98,111,114,100,101,114,2,25,8,98,111,117,110,100, + 115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,103,9,98,111,117, + 110,100,115,95,99,120,3,163,0,11,102,111,110,116,46,104,101,105,103,104, + 116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102, + 105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102, + 111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95, + 120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108,117,101,7,11, + 114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101,7,6,110,98, + 95,104,101,120,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,16,0,0,10,116,105,110,116,54,52,101,100,105,116,3, + 114,99,120,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,3,114,99,120,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,0,2,21,2,0,0,8,116,97,98,111,114,100,101,114,2,26,8,98, + 111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,82, + 9,98,111,117,110,100,115,95,99,120,3,162,0,11,102,111,110,116,46,104, + 101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109,101,6,9,115, + 116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101, + 2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101,116,118,97,108, + 117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4,98,97,115,101, + 7,6,110,98,95,104,101,120,3,109,97,120,2,255,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,16,0,0,10,116,105,110,116,54,52,101, + 100,105,116,3,114,98,120,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95, + 116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111, + 119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100, + 101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102,114,97,109,101, + 46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111, + 114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99, + 97,112,116,105,111,110,6,3,114,98,120,16,102,114,97,109,101,46,99,97, + 112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108, + 95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105, + 101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109, + 101,1,2,0,2,0,2,22,2,0,0,8,116,97,98,111,114,100,101,114, + 2,27,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115, + 95,121,2,61,9,98,111,117,110,100,115,95,99,120,3,163,0,11,102,111, + 110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116,46,110,97,109, + 101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115, + 99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10,111,110,115,101, + 116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97,108,117,101,4, + 98,97,115,101,7,6,110,98,95,104,101,120,3,109,97,120,2,255,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,10,116,105,110, + 116,54,52,101,100,105,116,3,114,97,120,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115, + 105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,3,114,97,120,16,102,114,97,109, + 101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103, + 104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111, + 114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,0,2,22,2,0,0,8,116,97,98,111, + 114,100,101,114,2,28,8,98,111,117,110,100,115,95,120,2,0,8,98,111, + 117,110,100,115,95,121,2,40,9,98,111,117,110,100,115,95,99,120,3,163, + 0,11,102,111,110,116,46,104,101,105,103,104,116,2,14,9,102,111,110,116, + 46,110,97,109,101,6,9,115,116,102,95,102,105,120,101,100,11,102,111,110, + 116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,10, + 111,110,115,101,116,118,97,108,117,101,7,11,114,101,103,115,101,116,118,97, + 108,117,101,4,98,97,115,101,7,6,110,98,95,104,101,120,3,109,97,120, + 2,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0, + 12,116,98,111,111,108,101,97,110,101,100,105,116,1,114,3,84,97,103,2, + 16,5,99,111,108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,1,82,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17, + 2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,29,8,98,111,117, + 110,100,115,95,120,2,23,8,98,111,117,110,100,115,95,121,2,9,9,98, + 111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95,99,121, + 2,28,10,111,110,115,101,116,118,97,108,117,101,7,12,102,108,97,103,115, + 101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110,101,100, + 105,116,1,118,3,84,97,103,2,17,5,99,111,108,111,114,4,3,0,0, + 128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97, + 109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,7,0,0,144,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,1,86,16,102,114,97, + 109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116,111, + 112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114, + 100,101,114,2,30,8,98,111,117,110,100,115,95,120,2,7,8,98,111,117, + 110,100,115,95,121,2,9,9,98,111,117,110,100,115,95,99,120,2,11,9, + 98,111,117,110,100,115,95,99,121,2,28,10,111,110,115,101,116,118,97,108, + 117,101,7,12,102,108,97,103,115,101,116,118,97,108,117,101,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tcpux86_64fo,''); +end. diff --git a/mseide-msegui/apps/ide/debuggerform.mfm b/mseide-msegui/apps/ide/debuggerform.mfm new file mode 100644 index 0000000..08dcc10 --- /dev/null +++ b/mseide-msegui/apps/ide/debuggerform.mfm @@ -0,0 +1,164 @@ +object debuggerfo: tdebuggerfo + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_floatbutton, go_topbutton, go_backgroundbutton, go_nolockbutton, go_buttonhints] + visible = False + bounds_x = 116 + bounds_y = 131 + bounds_cx = 441 + bounds_cy = 100 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 431 + 100 + ) + dragdock.caption = 'Debugger' + dragdock.optionsdock = [od_savepos, od_savezorder, od_canmove, od_canfloat, od_candock, od_proportional, od_propsize, od_captionhint] + options = [fo_savepos, fo_savezorder, fo_savestate] + statfile = mainfo.projectstatfile + icon.image = { + 00000000000000001800000018000000D4080000000000000000000000000000 + 0000000000000000000000000000000000000000E6E6E601E5E5E501E4E4E401 + E3E3E301E2E2E201E1E1E101E0E0E001DFDFDF01DEDEDE01DDDDDD01DCDCDC01 + DBDBDB02DADADA01D9D9D901D8D8D801D7D7D701D6D6D601D5D5D501D4D4D401 + D3D3D301D2D2D201D1D1D101D0D0D001E6E6E601E5E5E501E4E4E401E3E3E301 + E2E2E201D7DED701E0E0E001DFDFDF01DEDEDE01DDDDDD01DCDCDC01DBDBDB02 + DADADA01D9D9D901D8D8D801D7D7D701D6D6D601D5D5D501D4D4D401D3D3D301 + D2D2D201D1D1D101D0D0D001E6E6E601E5E5E501E4E4E401E3E3E301E2E2E201 + 22B52701C1D9C201DFDFDF01DEDEDE01DDDDDD01DCDCDC01DBDBDB02DADADA01 + D9D9D901D8D8D801D7D7D701D6D6D601D5D5D501D4D4D401D3D3D301D2D2D201 + D1D1D101D0D0D001E6E6E601E5E5E501E4E4E401E3E3E301E2E2E20122C42101 + 2BC62A019CD09D01DEDEDE01DDDDDD01DCDCDC01DBDBDB02DADADA01D9D9D901 + D8D8D801D7D7D701D6D6D601D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101 + D0D0D001E6E6E601E5E5E501E4E4E401E3E3E301E2E2E20123C6220125E61501 + 27C9220171C67401DDDDDD01DCDCDC01DBDBDB02DADADA01D9D9D901D8D8D801 + D7D7D701D6D6D601D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101D0D0D001 + E6E6E601E5E5E501E4E4E401E3E3E301E2E2E20123C6220125E6150132E82301 + 34D72B014EBD5201D6DAD601DBDBDB02DADADA01D9D9D901D8D8D801D7D7D701 + D6D6D601D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101D0D0D001E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E20123C6220125E6150132E8230140EA3201 + 45E53B013DBD3F01C4D4C501DBDBDB01DADADA01D9D9D901D8D8D801D7D7D701 + D6D6D601D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101D0D0D001E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E20123C6220125E6150132E8230140EA3201 + 4EED410158ED4D013BC03C01A7CFA901DADADA01D9D9D901D8D8D801D7D7D701 + D6D6D601D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101D0D0D001E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E20123C6220125E6150132E8230140EA3201 + 4EED41015BEF4F0169F15D0148CA470183C78501D9D9D901D8D8D801D7D7D701 + D6D6D601D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101D0D0D001E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E20123C6220125E6150132E8230140EA3201 + 4EED41015BEF4F0169F15D0176F46C0161DB5B0161C06401D4D6D401D7D7D701 + D6D6D601D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101D0D0D001E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E20123C6220125E6150132E8230140EA3201 + 4EED41015BEF4F0169F15D0176F46C0184F67A017CEB76014EBD5101C7D2C801 + D6D6D601D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101D0D0D001E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E20123C6220125E6150132E8230140EA3201 + 4EED41015BEF4F0169F15D0176F46C0184F67A0191F8890197F68F014FC15201 + AECCAF01D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101D0D0D001E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E20123C6220125E6150132E8230140EA3201 + 4EED41015BEF4F0169F15D0176F46C0184F67A0191F8890197F68F0142B44501 + 809E8101D0D0D001D4D4D401D3D3D301D2D2D201D1D1D101D0D0D001E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E20123C6220125E6150132E8230140EA3201 + 4EED41015BEF4F0169F15D0176F46C0184F67A017CEB760137A63A015B665C01 + 67676701A4A4A401D2D2D201D3D3D301D2D2D201D1D1D101D0D0D001E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E20123C6220125E6150132E8230140EA3201 + 4EED41015BEF4F0169F15D0176F46C015FD9590139983C016163610166666601 + 99999901D0D0D001D4D4D401D3D3D301D2D2D201D1D1D101D0D0D001E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E20123C6220125E6150132E8230140EA3201 + 4EED41015BEF4F0169F15D0142C4410143874501626262016C6C6C01ADADAD01 + D2D2D201D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101D0D0D001E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E20123C6220125E6150132E8230140EA3201 + 4EED410158ED4D0130B531014F7751016464640176767601BDBDBD01D5D5D501 + D6D6D601D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101D0D0D001E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E20123C6220125E6150132E8230140EA3201 + 45E53B0129A92B015A6A5B016666660184848401CACACA01D7D7D702D6D6D601 + D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101D0D0D001E6E6E601E5E5E501 + E4E4E401E3E3E301E2E2E20123C6220125E6150132E8230133D62A012C9B3001 + 616561016767670197979701D3D3D301D9D9D901D8D8D801D7D7D701D6D6D601 + D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101D0D0D001E6E6E601E5E5E501 + E4E4E401E3E3E301E2E2E20123C6220125E6150123C51E01388D3B0164646401 + 6B6B6B01AAAAAA01D7D7D701DADADA01D9D9D901D8D8D801D7D7D701D6D6D601 + D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101D0D0D001E6E6E601E5E5E501 + E4E4E401E3E3E301E2E2E20122C4210127C226014B7F4C016666660174747401 + BDBDBD01D8D8D801DBDBDB01DADADA01D9D9D901D8D8D801D7D7D701D6D6D601 + D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101D0D0D001E6E6E601E5E5E501 + E4E4E401E3E3E301E2E2E20122B52701A5BDA6016A6A6A0182828201CACACA01 + DBDBDB03DADADA01D9D9D901D8D8D801D7D7D701D6D6D601D5D5D501D4D4D401 + D3D3D301D2D2D201D1D1D101D0D0D001E6E6E601E5E5E501E4E4E401E3E3E301 + E2E2E201D6DDD601C2C2C20196969601D5D5D501DDDDDD01DCDCDC01DBDBDB02 + DADADA01D9D9D901D8D8D801D7D7D701D6D6D601D5D5D501D4D4D401D3D3D301 + D2D2D201D1D1D101D0D0D001E6E6E601E5E5E501E4E4E401E3E3E301E2E2E201 + E1E1E101DBDBDB01DCDCDC01DEDEDE01DDDDDD01DCDCDC01DBDBDB02DADADA01 + D9D9D901D8D8D801D7D7D701D6D6D601D5D5D501D4D4D401D3D3D301D2D2D201 + D1D1D101D0D0D001 + } + moduleclassname = 'tdockform' + object gdbtoolbar: ttoolbar + optionswidget = [ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets, ow_timedhint] + color = -2147483645 + frame.localprops = [] + frame.localprops1 = [] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 431 + bounds_cy = 100 + anchors = [] + buttons.count = 13 + buttons.width = 24 + buttons.height = 24 + buttons.items = < + item + action = actionsmo.reset + end + item + action = actionsmo.interrupt + end + item + action = actionsmo.continue + end + item + action = actionsmo.next + end + item + action = actionsmo.step + end + item + action = actionsmo.finish + end + item + options = [mao_separator] + end + item + hint = 'Next instruction' + action = actionsmo.nexti + state = [as_localhint] + end + item + hint = 'Step instruction' + action = actionsmo.stepi + state = [as_localhint] + end + item + options = [mao_separator] + end + item + action = actionsmo.bkptsonact + state = [as_checked] + options = [mao_checkbox] + end + item + action = actionsmo.watchesonact + state = [as_checked] + options = [mao_checkbox] + end + item + action = actionsmo.bluedotsonact + state = [as_checked] + options = [mao_checkbox] + end> + options = [tbo_dragsourceenabledonly, tbo_dragdestenabledonly] + end +end diff --git a/mseide-msegui/apps/ide/debuggerform.pas b/mseide-msegui/apps/ide/debuggerform.pas new file mode 100644 index 0000000..7b57cf3 --- /dev/null +++ b/mseide-msegui/apps/ide/debuggerform.pas @@ -0,0 +1,33 @@ +{ MSEide Copyright (c) 1999-2006 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit debuggerform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msegui,mseclasses,mseforms; + +type + tdebuggerfo = class(tdockform) + end; +var + debuggerfo: tdebuggerfo; +implementation +uses + debuggerform_mfm; +end. diff --git a/mseide-msegui/apps/ide/debuggerform_mfm.pas b/mseide-msegui/apps/ide/debuggerform_mfm.pas new file mode 100644 index 0000000..2a366b7 --- /dev/null +++ b/mseide-msegui/apps/ide/debuggerform_mfm.pas @@ -0,0 +1,211 @@ +unit debuggerform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,debuggerform; + +const + objdata: record size: integer; data: array[0..3861] of byte end = + (size: 3862; data: ( + 84,80,70,48,11,116,100,101,98,117,103,103,101,114,102,111,10,100,101,98, + 117,103,103,101,114,102,111,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,15,102,114,97,109,101,46,103,114,105,112,95,115,105, + 122,101,2,10,18,102,114,97,109,101,46,103,114,105,112,95,111,112,116,105, + 111,110,115,11,14,103,111,95,99,108,111,115,101,98,117,116,116,111,110,16, + 103,111,95,102,105,120,115,105,122,101,98,117,116,116,111,110,14,103,111,95, + 102,108,111,97,116,98,117,116,116,111,110,12,103,111,95,116,111,112,98,117, + 116,116,111,110,19,103,111,95,98,97,99,107,103,114,111,117,110,100,98,117, + 116,116,111,110,15,103,111,95,110,111,108,111,99,107,98,117,116,116,111,110, + 14,103,111,95,98,117,116,116,111,110,104,105,110,116,115,0,7,118,105,115, + 105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,116,8,98,111,117, + 110,100,115,95,121,3,131,0,9,98,111,117,110,100,115,95,99,120,3,185, + 1,9,98,111,117,110,100,115,95,99,121,2,100,26,99,111,110,116,97,105, + 110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,0,27,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,99,111,110,116,97,105,110, + 101,114,46,98,111,117,110,100,115,1,2,0,2,0,3,175,1,2,100,0, + 16,100,114,97,103,100,111,99,107,46,99,97,112,116,105,111,110,6,8,68, + 101,98,117,103,103,101,114,20,100,114,97,103,100,111,99,107,46,111,112,116, + 105,111,110,115,100,111,99,107,11,10,111,100,95,115,97,118,101,112,111,115, + 13,111,100,95,115,97,118,101,122,111,114,100,101,114,10,111,100,95,99,97, + 110,109,111,118,101,11,111,100,95,99,97,110,102,108,111,97,116,10,111,100, + 95,99,97,110,100,111,99,107,15,111,100,95,112,114,111,112,111,114,116,105, + 111,110,97,108,11,111,100,95,112,114,111,112,115,105,122,101,14,111,100,95, + 99,97,112,116,105,111,110,104,105,110,116,0,7,111,112,116,105,111,110,115, + 11,10,102,111,95,115,97,118,101,112,111,115,13,102,111,95,115,97,118,101, + 122,111,114,100,101,114,12,102,111,95,115,97,118,101,115,116,97,116,101,0, + 8,115,116,97,116,102,105,108,101,7,22,109,97,105,110,102,111,46,112,114, + 111,106,101,99,116,115,116,97,116,102,105,108,101,10,105,99,111,110,46,105, + 109,97,103,101,10,8,9,0,0,0,0,0,0,0,0,0,0,24,0,0, + 0,24,0,0,0,212,8,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226, + 1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221, + 1,220,220,220,1,219,219,219,2,218,218,218,1,217,217,217,1,216,216,216, + 1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211, + 1,210,210,210,1,209,209,209,1,208,208,208,1,230,230,230,1,229,229,229, + 1,228,228,228,1,227,227,227,1,226,226,226,1,215,222,215,1,224,224,224, + 1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219, + 2,218,218,218,1,217,217,217,1,216,216,216,1,215,215,215,1,214,214,214, + 1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209, + 1,208,208,208,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227, + 1,226,226,226,1,34,181,39,1,193,217,194,1,223,223,223,1,222,222,222, + 1,221,221,221,1,220,220,220,1,219,219,219,2,218,218,218,1,217,217,217, + 1,216,216,216,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212, + 1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,230,230,230, + 1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,34,196,33, + 1,43,198,42,1,156,208,157,1,222,222,222,1,221,221,221,1,220,220,220, + 1,219,219,219,2,218,218,218,1,217,217,217,1,216,216,216,1,215,215,215, + 1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210, + 1,209,209,209,1,208,208,208,1,230,230,230,1,229,229,229,1,228,228,228, + 1,227,227,227,1,226,226,226,1,35,198,34,1,37,230,21,1,39,201,34, + 1,113,198,116,1,221,221,221,1,220,220,220,1,219,219,219,2,218,218,218, + 1,217,217,217,1,216,216,216,1,215,215,215,1,214,214,214,1,213,213,213, + 1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208, + 1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226, + 1,35,198,34,1,37,230,21,1,50,232,35,1,52,215,43,1,78,189,82, + 1,214,218,214,1,219,219,219,2,218,218,218,1,217,217,217,1,216,216,216, + 1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211, + 1,210,210,210,1,209,209,209,1,208,208,208,1,230,230,230,1,229,229,229, + 1,228,228,228,1,227,227,227,1,226,226,226,1,35,198,34,1,37,230,21, + 1,50,232,35,1,64,234,50,1,69,229,59,1,61,189,63,1,196,212,197, + 1,219,219,219,1,218,218,218,1,217,217,217,1,216,216,216,1,215,215,215, + 1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210, + 1,209,209,209,1,208,208,208,1,230,230,230,1,229,229,229,1,228,228,228, + 1,227,227,227,1,226,226,226,1,35,198,34,1,37,230,21,1,50,232,35, + 1,64,234,50,1,78,237,65,1,88,237,77,1,59,192,60,1,167,207,169, + 1,218,218,218,1,217,217,217,1,216,216,216,1,215,215,215,1,214,214,214, + 1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209, + 1,208,208,208,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227, + 1,226,226,226,1,35,198,34,1,37,230,21,1,50,232,35,1,64,234,50, + 1,78,237,65,1,91,239,79,1,105,241,93,1,72,202,71,1,131,199,133, + 1,217,217,217,1,216,216,216,1,215,215,215,1,214,214,214,1,213,213,213, + 1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208, + 1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226, + 1,35,198,34,1,37,230,21,1,50,232,35,1,64,234,50,1,78,237,65, + 1,91,239,79,1,105,241,93,1,118,244,108,1,97,219,91,1,97,192,100, + 1,212,214,212,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212, + 1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,230,230,230, + 1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,35,198,34, + 1,37,230,21,1,50,232,35,1,64,234,50,1,78,237,65,1,91,239,79, + 1,105,241,93,1,118,244,108,1,132,246,122,1,124,235,118,1,78,189,81, + 1,199,210,200,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211, + 1,210,210,210,1,209,209,209,1,208,208,208,1,230,230,230,1,229,229,229, + 1,228,228,228,1,227,227,227,1,226,226,226,1,35,198,34,1,37,230,21, + 1,50,232,35,1,64,234,50,1,78,237,65,1,91,239,79,1,105,241,93, + 1,118,244,108,1,132,246,122,1,145,248,137,1,151,246,143,1,79,193,82, + 1,174,204,175,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210, + 1,209,209,209,1,208,208,208,1,230,230,230,1,229,229,229,1,228,228,228, + 1,227,227,227,1,226,226,226,1,35,198,34,1,37,230,21,1,50,232,35, + 1,64,234,50,1,78,237,65,1,91,239,79,1,105,241,93,1,118,244,108, + 1,132,246,122,1,145,248,137,1,151,246,143,1,66,180,69,1,128,158,129, + 1,208,208,208,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209, + 1,208,208,208,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227, + 1,226,226,226,1,35,198,34,1,37,230,21,1,50,232,35,1,64,234,50, + 1,78,237,65,1,91,239,79,1,105,241,93,1,118,244,108,1,132,246,122, + 1,124,235,118,1,55,166,58,1,91,102,92,1,103,103,103,1,164,164,164, + 1,210,210,210,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208, + 1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226, + 1,35,198,34,1,37,230,21,1,50,232,35,1,64,234,50,1,78,237,65, + 1,91,239,79,1,105,241,93,1,118,244,108,1,95,217,89,1,57,152,60, + 1,97,99,97,1,102,102,102,1,153,153,153,1,208,208,208,1,212,212,212, + 1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,230,230,230, + 1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,35,198,34, + 1,37,230,21,1,50,232,35,1,64,234,50,1,78,237,65,1,91,239,79, + 1,105,241,93,1,66,196,65,1,67,135,69,1,98,98,98,1,108,108,108, + 1,173,173,173,1,210,210,210,1,213,213,213,1,212,212,212,1,211,211,211, + 1,210,210,210,1,209,209,209,1,208,208,208,1,230,230,230,1,229,229,229, + 1,228,228,228,1,227,227,227,1,226,226,226,1,35,198,34,1,37,230,21, + 1,50,232,35,1,64,234,50,1,78,237,65,1,88,237,77,1,48,181,49, + 1,79,119,81,1,100,100,100,1,118,118,118,1,189,189,189,1,213,213,213, + 1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210, + 1,209,209,209,1,208,208,208,1,230,230,230,1,229,229,229,1,228,228,228, + 1,227,227,227,1,226,226,226,1,35,198,34,1,37,230,21,1,50,232,35, + 1,64,234,50,1,69,229,59,1,41,169,43,1,90,106,91,1,102,102,102, + 1,132,132,132,1,202,202,202,1,215,215,215,2,214,214,214,1,213,213,213, + 1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208, + 1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226, + 1,35,198,34,1,37,230,21,1,50,232,35,1,51,214,42,1,44,155,48, + 1,97,101,97,1,103,103,103,1,151,151,151,1,211,211,211,1,217,217,217, + 1,216,216,216,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212, + 1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,230,230,230, + 1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,35,198,34, + 1,37,230,21,1,35,197,30,1,56,141,59,1,100,100,100,1,107,107,107, + 1,170,170,170,1,215,215,215,1,218,218,218,1,217,217,217,1,216,216,216, + 1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211, + 1,210,210,210,1,209,209,209,1,208,208,208,1,230,230,230,1,229,229,229, + 1,228,228,228,1,227,227,227,1,226,226,226,1,34,196,33,1,39,194,38, + 1,75,127,76,1,102,102,102,1,116,116,116,1,189,189,189,1,216,216,216, + 1,219,219,219,1,218,218,218,1,217,217,217,1,216,216,216,1,215,215,215, + 1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210, + 1,209,209,209,1,208,208,208,1,230,230,230,1,229,229,229,1,228,228,228, + 1,227,227,227,1,226,226,226,1,34,181,39,1,165,189,166,1,106,106,106, + 1,130,130,130,1,202,202,202,1,219,219,219,3,218,218,218,1,217,217,217, + 1,216,216,216,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212, + 1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,230,230,230, + 1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,214,221,214, + 1,194,194,194,1,150,150,150,1,213,213,213,1,221,221,221,1,220,220,220, + 1,219,219,219,2,218,218,218,1,217,217,217,1,216,216,216,1,215,215,215, + 1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210, + 1,209,209,209,1,208,208,208,1,230,230,230,1,229,229,229,1,228,228,228, + 1,227,227,227,1,226,226,226,1,225,225,225,1,219,219,219,1,220,220,220, + 1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,2,218,218,218, + 1,217,217,217,1,216,216,216,1,215,215,215,1,214,214,214,1,213,213,213, + 1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208, + 1,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,9,116, + 100,111,99,107,102,111,114,109,0,8,116,116,111,111,108,98,97,114,10,103, + 100,98,116,111,111,108,98,97,114,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110, + 16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119, + 95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,12,111,119,95,116, + 105,109,101,100,104,105,110,116,0,5,99,111,108,111,114,4,3,0,0,128, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8, + 98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,3,175,1,9,98,111,117,110,100, + 115,95,99,121,2,100,7,97,110,99,104,111,114,115,11,0,13,98,117,116, + 116,111,110,115,46,99,111,117,110,116,2,13,13,98,117,116,116,111,110,115, + 46,119,105,100,116,104,2,24,14,98,117,116,116,111,110,115,46,104,101,105, + 103,104,116,2,24,13,98,117,116,116,111,110,115,46,105,116,101,109,115,14, + 1,6,97,99,116,105,111,110,7,15,97,99,116,105,111,110,115,109,111,46, + 114,101,115,101,116,0,1,6,97,99,116,105,111,110,7,19,97,99,116,105, + 111,110,115,109,111,46,105,110,116,101,114,114,117,112,116,0,1,6,97,99, + 116,105,111,110,7,18,97,99,116,105,111,110,115,109,111,46,99,111,110,116, + 105,110,117,101,0,1,6,97,99,116,105,111,110,7,14,97,99,116,105,111, + 110,115,109,111,46,110,101,120,116,0,1,6,97,99,116,105,111,110,7,14, + 97,99,116,105,111,110,115,109,111,46,115,116,101,112,0,1,6,97,99,116, + 105,111,110,7,16,97,99,116,105,111,110,115,109,111,46,102,105,110,105,115, + 104,0,1,7,111,112,116,105,111,110,115,11,13,109,97,111,95,115,101,112, + 97,114,97,116,111,114,0,0,1,4,104,105,110,116,6,16,78,101,120,116, + 32,105,110,115,116,114,117,99,116,105,111,110,6,97,99,116,105,111,110,7, + 15,97,99,116,105,111,110,115,109,111,46,110,101,120,116,105,5,115,116,97, + 116,101,11,12,97,115,95,108,111,99,97,108,104,105,110,116,0,0,1,4, + 104,105,110,116,6,16,83,116,101,112,32,105,110,115,116,114,117,99,116,105, + 111,110,6,97,99,116,105,111,110,7,15,97,99,116,105,111,110,115,109,111, + 46,115,116,101,112,105,5,115,116,97,116,101,11,12,97,115,95,108,111,99, + 97,108,104,105,110,116,0,0,1,7,111,112,116,105,111,110,115,11,13,109, + 97,111,95,115,101,112,97,114,97,116,111,114,0,0,1,6,97,99,116,105, + 111,110,7,20,97,99,116,105,111,110,115,109,111,46,98,107,112,116,115,111, + 110,97,99,116,5,115,116,97,116,101,11,10,97,115,95,99,104,101,99,107, + 101,100,0,7,111,112,116,105,111,110,115,11,12,109,97,111,95,99,104,101, + 99,107,98,111,120,0,0,1,6,97,99,116,105,111,110,7,22,97,99,116, + 105,111,110,115,109,111,46,119,97,116,99,104,101,115,111,110,97,99,116,5, + 115,116,97,116,101,11,10,97,115,95,99,104,101,99,107,101,100,0,7,111, + 112,116,105,111,110,115,11,12,109,97,111,95,99,104,101,99,107,98,111,120, + 0,0,1,6,97,99,116,105,111,110,7,23,97,99,116,105,111,110,115,109, + 111,46,98,108,117,101,100,111,116,115,111,110,97,99,116,5,115,116,97,116, + 101,11,10,97,115,95,99,104,101,99,107,101,100,0,7,111,112,116,105,111, + 110,115,11,12,109,97,111,95,99,104,101,99,107,98,111,120,0,0,0,7, + 111,112,116,105,111,110,115,11,25,116,98,111,95,100,114,97,103,115,111,117, + 114,99,101,101,110,97,98,108,101,100,111,110,108,121,23,116,98,111,95,100, + 114,97,103,100,101,115,116,101,110,97,98,108,101,100,111,110,108,121,0,0, + 0,0) + ); + +initialization + registerobjectdata(@objdata,tdebuggerfo,''); +end. diff --git a/mseide-msegui/apps/ide/disassform.mfm b/mseide-msegui/apps/ide/disassform.mfm new file mode 100644 index 0000000..5b7df81 --- /dev/null +++ b/mseide-msegui/apps/ide/disassform.mfm @@ -0,0 +1,166 @@ +object disassfo: tdisassfo + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_floatbutton, go_topbutton, go_backgroundbutton, go_nolockbutton, go_buttonhints] + onactivate = act + ondeactivate = deact + visible = False + bounds_x = 162 + bounds_y = 502 + bounds_cx = 564 + bounds_cy = 210 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 554 + 210 + ) + dragdock.splitter_size = 0 + dragdock.caption = 'Assembler' + dragdock.optionsdock = [od_savepos, od_savezorder, od_canmove, od_canfloat, od_candock, od_propsize, od_captionhint, od_childicons] + options = [fo_savepos, fo_savezorder, fo_savestate] + statfile = mainfo.projectstatfile + caption = 'Assembler' + icon.transparentcolor = -2147483642 + icon.options = [bmo_masked] + icon.image = { + 00000000020000001800000018000000F4060000000000000000000000000000 + 0000000000000000000000000000000000000000D0D0D0198888880D82888801 + 88888801D0D0D00988888801B3F8FE01B6F8FE01B9F9FE01BCFAFE01BFFAFE01 + C2FBFE01C6FBFE01C9FCFE01CCFDFE01CFFDFE01D2FEFE01D5FEFE017F878701 + 9FC5C80188888801D0D0D00888888801B3F8FE01B6F8FE01B9F9FE01BCFAFE01 + BFFAFE01C2FBFE01C6FBFE01C9FCFE01CCFDFE01CFFDFE01D2FEFE01D5FEFE01 + 83898A01C6F9FF019EC5C80188888801D0D0D00788888801B3F8FE01B6F8FE01 + B9F9FE01BCFAFE01BFFAFE01C2FBFE01C6FBFE01C9FCFE01CCFDFE01CFFDFE01 + D2FEFE01D5FEFE01858A8A01E2FCFF01C5F9FF019EC5C80188888801D0D0D006 + 88888801B3F8FE01B6F8FE01B9F9FE01BCFAFE01BFFAFE01C2FBFE01C6FBFE01 + C9FCFE01CCFDFE01CFFDFE01D2FEFE01D5FEFE0182898A01FEFEFF01E1FCFF01 + C3F9FF019EC5C80188888801D0D0D00588888801B3F8FE01B6F8FE01B9F9FE01 + BCFAFE01BFFAFE01C2FBFE01C6FBFE01C9FCFE01CCFDFE01CFFDFE01D2FEFE01 + D5FEFE017F898A01DFFCFF01FCFEFF01DFFCFF01C2F9FF019DC4C80188888801 + D0D0D00488888801B3F8FE01B6F8FE01B9F9FE01BCFAFE01BFFAFE01C2FBFE01 + C6FBFE01C9FCFE01CCFDFE01CFFDFE01D2FEFE01D5FEFE017C898A01BEF9FF01 + E1FCFF01FAFEFF01DDFCFF01C0F9FF019DC4C80188888801D0D0D00388888801 + B3F8FE01B6F8FE01B9F9FE01BCFAFE01BFFAFE01C2FBFE01C6FBFE01C9FCFE01 + CCFDFE01CFFDFE01D2FEFE01D5FEFE0179898A019EF6FF01C0F9FF01E3FCFF01 + F9FEFF01DCFBFF01BEF9FF019DC4C80188888801D0D0D00288888801B3F8FE01 + B6F8FE01B9F9FE01BCFAFE01BFFAFE01C2FBFE01C6FBFE01C9FCFE01CCFDFE01 + CFFDFE01D2FEFE01D5FEFE018296970178898A017A898A017C898A017E898A02 + 7A898A017786870181888801D0D0D00288888801B3F8FE01B6F8FE01B9F9FE01 + BCFAFE01BFFAFE01C2FBFE01C6FBFE01C9FCFE01CCFDFE01CFFDFE01D2FEFE01 + D5FEFE01CEFDFE01BFFCFE01B0FAFE01A2F8FE0193F6FE0184F4FE0175F3FE01 + 66F1FE0188888801D0D0D00288888801B3F8FE01B6F8FE01B9F9FE01BCFAFE01 + BFFAFE01C2FBFE01C6FBFE01C9FCFE01CCFDFE01CFFDFE01D2FEFE01D5FEFE01 + CEFDFE01BFFCFE01B0FAFE01A2F8FE0193F6FE0184F4FE0175F3FE0166F1FE01 + 88888801D0D0D00288888801B3F8FE01B6F8FE01AFEBF0015774760137494A01 + 7DA1A301C6FBFE01C9FCFE01CCFDFE01C6F2F30149595901D5FEFE01CEFDFE01 + BFFCFE016D9B9D01314B4D01426F730180EDF70175F3FE0166F1FE0188888801 + D0D0D00288888801B3F8FE01B6F8FE014D686A0162828401AADFE2012A363701 + 9DC7C901C9FCFE01ADD6D701323D3D010D101001D5FEFE01CEFDFE018EBCBD01 + 2C3F400194E3E801447276013D71760175F3FE0166F1FE0188888801D0D0D002 + 88888801B3F8FE01B6F8FE01141A1B01A7DEE101BFFAFE01638081015E777901 + C9FCFE015E7576019DC0C1011A1F1F01D5FEFE01CEFDFE01546F7001618A8C01 + A2F8FE017CCFD6011322240175F3FE0166F1FE0188888801D0D0D00288888801 + B3F8FE01B2F3F90110151601BCFAFE01BFFAFE0184AAAC01475A5B01C9FCFE01 + CCFDFE01CFFDFE011A1F1F01D5FEFE01CEFDFE013D50510183BABD01A2F8FE01 + 91F2FA01070D0E0175F3FE0166F1FE0188888801D0D0D00288888801B3F8FE01 + B3F4FA010C101001BCFAFE01BFFAFE017EA2A4014E626401C9FCFE01CCFDFE01 + CFFDFE011A1F1F01D5FEFE01CEFDFE013D51520180B5B801A2F8FE018EEEF601 + 0911120175F3FE0166F1FE0188888801D0D0D00288888801B3F8FE01B6F8FE01 + 11171801A7DFE201BFFAFE015D787A0168848501C9FCFE01CCFDFE01CFFDFE01 + 1A1F1F01D5FEFE01CEFDFE01526C6D01628B8D01A2F8FE0177C8CE01192F3101 + 75F3FE0166F1FE0188888801D0D0D00288888801B3F8FE01B6F8FE015B7A7D01 + 4B6466018DB8BB01242E2F01ADDCDE01C9FCFE01CCFDFE01CFFDFE011A1F1F01 + D5FEFE01CEFDFE019ACCCD01243334017ABBBF01315255014E90960175F3FE01 + 66F1FE0188888801D0D0D00288888801B3F8FE01B6F8FE01B9F9FE018CBABD01 + 5B7779019DCBCD01C6FBFE01C9FCFE01CCFDFE01CFFDFE01768E8E01D5FEFE01 + CEFDFE01BFFCFE019BDCDF014F7A7D0161A3A80183F3FD0175F3FE0166F1FE01 + 88888801D0D0D00288888801B3F8FE01B6F8FE01B9F9FE01BCFAFE01BFFAFE01 + C2FBFE01C6FBFE01C9FCFE01CCFDFE01CFFDFE01D2FEFE01D5FEFE01CEFDFE01 + BFFCFE01B0FAFE01A2F8FE0193F6FE0184F4FE0175F3FE0166F1FE0188888801 + D0D0D00288888801B3F8FE01B6F8FE01B9F9FE01BCFAFE01BFFAFE01C2FBFE01 + C6FBFE01C9FCFE01CCFDFE01CFFDFE01D2FEFE01D5FEFE01CEFDFE01BFFCFE01 + B0FAFE01A2F8FE0193F6FE0184F4FE0175F3FE0166F1FE0188888801D0D0D002 + 88888816D0D0D01900000008FEFF0008FEFF01BFFEFF0308FEFF0700FEFF0F08 + FEFF1F02FEFF3FC0FEFF7F00FEFF7F08FEFF7F00FEFF7F08FEFF7F08FEFF7F08 + FEFF7FBFFEFF7F08FEFF7F00FEFF7F02FEFF7F08FEFF7F00FEFF7F00FEFF7FBF + FEFF7F0000000008 + } + onshow = disassfoonshow + moduleclassname = 'tdockform' + object grid: tstringgrid + color = -1879048187 + frame.sbvert.options = [sbo_thumbtrack, sbo_show] + frame.localprops = [] + frame.localprops1 = [] + popupmenu = popupmen + bounds_x = 0 + bounds_y = 0 + bounds_cx = 554 + bounds_cy = 210 + anchors = [] + onkeydown = keydo + optionsgrid = [og_colsizing, og_colchangeontabkey, og_wrapcol, og_autopopup] + datacols.count = 4 + datacols.options = [co_readonly, co_drawfocus, co_savestate] + datacols.items = < + item + width = 76 + onbeforedrawcell = befdrawcell + options = [co_readonly, co_drawfocus, co_savestate] + oncellevent = addrcellevent + textflags = [tf_right, tf_ycentered, tf_noselect] + textflagsactive = [tf_right, tf_ycentered] + optionsedit = [scoe_eatreturn, scoe_hintclippedtext] + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + valuefalse = '0' + valuetrue = '1' + end + item + width = 355 + options = [co_readonly, co_drawfocus, co_fill, co_savestate] + textflags = [tf_ycentered, tf_noselect, tf_tabtospace] + textflagsactive = [tf_ycentered, tf_tabtospace] + optionsedit = [scoe_eatreturn, scoe_hintclippedtext] + valuefalse = '0' + valuetrue = '1' + end + item + options = [co_readonly, co_invisible, co_drawfocus, co_savestate] + valuefalse = '0' + valuetrue = '1' + end + item + options = [co_readonly, co_invisible, co_drawfocus, co_savestate] + valuefalse = '0' + valuetrue = '1' + end> + rowcolors.count = 2 + rowcolors.items = ( + 14745599 + 16777184 + ) + datarowheight = 16 + onscrollrows = scrollrows + oncellevent = celleventexe + reffontheight = 13 + end + object popupmen: tpopupmenu + onupdate = popupupdate + menu.submenu.count = 1 + menu.submenu.items = < + item + caption = 'Show &Breakpoint' + name = 'showbreak' + state = [as_localcaption, as_localonexecute] + onexecute = showbreakexe + end> + left = 120 + top = 24 + end +end diff --git a/mseide-msegui/apps/ide/disassform.pas b/mseide-msegui/apps/ide/disassform.pas new file mode 100644 index 0000000..1c65cf9 --- /dev/null +++ b/mseide-msegui/apps/ide/disassform.pas @@ -0,0 +1,339 @@ +{ MSEide Copyright (c) 1999-2014 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit disassform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msegui,mseclasses,mseforms,msegdbutils,msegrids,msetypes,msestrings,mseevent, + msegraphics,mseguiglob,msemenus; + +type + tdisassfo = class(tdockform) + grid: tstringgrid; + popupmen: tpopupmenu; + procedure disassfoonshow(const sender: TObject); + procedure keydo(const sender: twidget; var info: keyeventinfoty); + procedure deact(const sender: TObject); + procedure act(const sender: TObject); + procedure befdrawcell(const sender: tcol; const canvas: tcanvas; + var cellinfo: cellinfoty; var processed: Boolean); + procedure addrcellevent(const sender: TObject; var info: celleventinfoty); + procedure scrollrows(const sender: tcustomgrid; var step: Integer); + procedure celleventexe(const sender: TObject; var info: celleventinfoty); + procedure popupupdate(const sender: tcustommenu); + procedure showbreakexe(const sender: TObject); + private + faddress: qword; + ffirstaddress: qword; + flastaddress: qword; + factiverow: integer; + fshortcutsswapped: boolean; + procedure swapshortcuts; + procedure internalrefresh; + procedure addlines(const aaddress: qword; const alinecount: integer); + procedure addpreviouslines(const asetrow: boolean); + public + gdb: tgdbmi; + procedure refresh(const addr: qword); + procedure clear; + procedure resetactiverow; + procedure resetshortcuts; + end; + +var + disassfo: tdisassfo; + +implementation + +uses + disassform_mfm,sourceform,sourcepage,mseformatstr,sysutils,msekeyboard,mseglob, + actionsmodule,breakpointsform,msegraphutils,mseeditglob,msegridsglob; + +{ tdisassfo } + +procedure tdisassfo.disassfoonshow(const sender: TObject); +begin + internalrefresh; +end; + +procedure tdisassfo.clear; +begin + grid.clear; +end; + +procedure tdisassfo.addlines(const aaddress: qword; const alinecount: integer); +var + ar1: asmlinearty; + int1,int2: integer; + apage: tsourcepage; + aline: integer; + start,stop: qword; + fname1: filenamety; + ca1,ca2: qword; + endrow: integer; + digits: integer; + +begin + int2:= grid.rowcount; + endrow:= int2 + alinecount; + digits:= gdb.pointerhexdigits; + if gdb.infoline(aaddress,fname1,aline,start,stop) <> gdb_ok then begin + start:= aaddress; + stop:= aaddress + $100; + aline:= 0; + end; + if start < ffirstaddress then begin + ffirstaddress:= start; + end; + grid.beginupdate; + try + while int2 < endrow do begin + flastaddress:= stop; + if gdb.disassemble(ar1,start,stop) = gdb_ok then begin + if aline > 0 then begin + apage:= sourcefo.openfile(fname1); + grid.rowcount:= int2 + 1 + length(ar1); + grid[3][int2]:= inttostrmse(aline-1); + if (apage <> nil) and (aline > 0) and + (aline <= apage.grid.rowcount) then begin + grid[1][int2]:= apage.edit[aline-1]; + grid[2][int2]:= fname1; + end + else begin + grid[1][int2]:= ''; + end; + grid.rowcolorstate[int2]:= 1; + inc(int2); + end + else begin + grid.rowcount:= int2 + length(ar1); + end; + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + grid[0][int2]:= hextostrmse(address,digits); + grid[1][int2]:= msestring(instruction); + if address = faddress then begin + factiverow:= int2; + grid.rowcolorstate[int2]:= 0; + end; + end; + inc(int2); + end; + if gdb.infoline(stop,fname1,aline,ca1,ca2) = gdb_ok then begin + start:= ca1; + stop:= ca2; + end + else begin + break; + end; + end + else begin + break; + end; + end; + if (factiverow >= 0) and (factiverow <= grid.rowcount) then begin + grid.showcell(makegridcoord(invalidaxis,factiverow)); + end; + finally + grid.endupdate; + end; +end; + +procedure tdisassfo.internalrefresh; +begin + if showing and gdb.cancommand then begin + grid.beginupdate; + try + grid.rowcount:= 0; + addlines(faddress,grid.rowsperpage); + finally + grid.endupdate; + end; + end; +end; + +procedure tdisassfo.refresh(const addr: qword); +begin + ffirstaddress:= not qword(0); + faddress:= addr; + internalrefresh; +end; + +procedure tdisassfo.resetactiverow; +begin + if (factiverow < grid.rowcount) then begin + grid.rowcolorstate[factiverow]:= -1; + end; +end; + +procedure tdisassfo.addpreviouslines(const asetrow: boolean); +var + rowcountbefore,rowbefore,activerowbefore{,firstvisiblerowbefore}: integer; +// int1: integer; +begin + with grid do begin + rowcountbefore:= rowcount; +// firstvisiblerowbefore:= firstvisiblerow; + rowbefore:= row; + activerowbefore:= factiverow; + clear; + addlines((ffirstaddress and not qword($7))-$40,rowcountbefore+$48); + if asetrow then begin + row:= rowbefore + factiverow - activerowbefore; + end + else begin + showcell(makegridcoord(col,factiverow-activerowbefore),cep_top,true); + end; + end; +end; + +procedure tdisassfo.scrollrows(const sender: tcustomgrid; var step: Integer); +begin + if (step > 0) then begin + if sender.firstvisiblerow = 0 then begin + addpreviouslines(false); + end; + end + else begin + if sender.lastvisiblerow = sender.rowhigh then begin + addlines(flastaddress,grid.rowsperpage); + end; + end; +end; + +procedure tdisassfo.keydo(const sender: twidget; var info: keyeventinfoty); +begin + if visible and gdb.cancommand then begin + with grid,info do begin + if (shiftstate = []) then begin + if ((key = key_down) or (key = key_pagedown)) and (row = rowhigh) then begin + addlines(flastaddress,grid.rowsperpage); + end + else begin + if ((key = key_up) or (key = key_pageup)) and (row = 0) then begin + addpreviouslines(true); + showcell(focusedcell,cep_top); + end; + end; + end; + end; + end; +end; + +procedure tdisassfo.swapshortcuts; +var + sho1: shortcutty; +begin + with actionsmo do begin + sho1:= step.shortcut; + step.shortcut:= stepi.shortcut; + stepi.shortcut:= sho1; + sho1:= next.shortcut; + next.shortcut:= nexti.shortcut; + nexti.shortcut:= sho1; + end; +end; + +procedure tdisassfo.resetshortcuts; +begin + if fshortcutsswapped then begin + swapshortcuts; + fshortcutsswapped:= false; + end; +end; + +procedure tdisassfo.deact(const sender: TObject); +begin + if (application.inactivewindow <> window) then begin + resetshortcuts; + end; +end; + +procedure tdisassfo.act(const sender: TObject); +begin + if not fshortcutsswapped then begin + swapshortcuts; + fshortcutsswapped:= true; + end; +end; + +procedure tdisassfo.befdrawcell(const sender: tcol; const canvas: tcanvas; + var cellinfo: cellinfoty; var processed: Boolean); +begin + with cellinfo do begin + if pmsestring(datapo)^ <> '' then begin + if breakpointsfo.isactivebreakpoint( + strtohex64(ansistring(pmsestring(datapo)^))) then begin + color:= cl_ltred; + end; + end; + end; +end; + +procedure tdisassfo.addrcellevent(const sender: TObject; + var info: celleventinfoty); +begin + with info do begin + if iscellclick(info,[ccr_buttonpress,ccr_data]) then begin + breakpointsfo.toggleaddrbreakpoint( + strtohex64(ansistring(self.grid[cell.col][cell.row]))); + grid.invalidatecell(cell); + end; + end; +end; + +procedure tdisassfo.celleventexe(const sender: TObject; + var info: celleventinfoty); +var + int1: integer; +begin + if (info.cell.col = 1) and iscellclick(info,[ccr_dblclick]) then begin + int1:= info.cell.row; + if int1 >= 0 then begin + while (int1 >= 0) and (grid[2][int1] = '') do begin + dec(int1); + end; + if int1 < 0 then begin + int1:= info.cell.row; + while (int1 < grid.rowcount) and (grid[2][int1] = '') do begin + inc(int1); + end; + end; + if (int1 >= 0) and (int1 < grid.rowcount) then begin + sourcefo.showsourceline(grid[2][int1],strtoint64( + ansistring(grid[3][int1])),0,true); + end; + end; + end; +end; + +procedure tdisassfo.popupupdate(const sender: tcustommenu); +begin + popupmen.menu.itembyname('showbreak').enabled:= grid.focusedcellvalid and + (grid[0][grid.row] <> '') and + breakpointsfo.isactivebreakpoint(strtohex64(ansistring(grid[0][grid.row]))); +end; + +procedure tdisassfo.showbreakexe(const sender: TObject); +begin + breakpointsfo.showbreakpoint( + strtohex64(ansistring(self.grid[0][grid.row])),true); +end; + +end. diff --git a/mseide-msegui/apps/ide/disassform_mfm.pas b/mseide-msegui/apps/ide/disassform_mfm.pas new file mode 100644 index 0000000..adc185f --- /dev/null +++ b/mseide-msegui/apps/ide/disassform_mfm.pas @@ -0,0 +1,227 @@ +unit disassform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,disassform; + +const + objdata: record size: integer; data: array[0..4193] of byte end = + (size: 4194; data: ( + 84,80,70,48,9,116,100,105,115,97,115,115,102,111,8,100,105,115,97,115, + 115,102,111,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,15,102,114,97,109,101,46,103,114,105,112,95,115,105,122,101,2,10, + 18,102,114,97,109,101,46,103,114,105,112,95,111,112,116,105,111,110,115,11, + 14,103,111,95,99,108,111,115,101,98,117,116,116,111,110,16,103,111,95,102, + 105,120,115,105,122,101,98,117,116,116,111,110,14,103,111,95,102,108,111,97, + 116,98,117,116,116,111,110,12,103,111,95,116,111,112,98,117,116,116,111,110, + 19,103,111,95,98,97,99,107,103,114,111,117,110,100,98,117,116,116,111,110, + 15,103,111,95,110,111,108,111,99,107,98,117,116,116,111,110,14,103,111,95, + 98,117,116,116,111,110,104,105,110,116,115,0,10,111,110,97,99,116,105,118, + 97,116,101,7,3,97,99,116,12,111,110,100,101,97,99,116,105,118,97,116, + 101,7,5,100,101,97,99,116,7,118,105,115,105,98,108,101,8,8,98,111, + 117,110,100,115,95,120,3,162,0,8,98,111,117,110,100,115,95,121,3,246, + 1,9,98,111,117,110,100,115,95,99,120,3,52,2,9,98,111,117,110,100, + 115,95,99,121,3,210,0,26,99,111,110,116,97,105,110,101,114,46,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,27,99,111,110, + 116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,16,99,111,110,116,97,105,110,101,114,46,98,111,117, + 110,100,115,1,2,0,2,0,3,42,2,3,210,0,0,22,100,114,97,103, + 100,111,99,107,46,115,112,108,105,116,116,101,114,95,115,105,122,101,2,0, + 16,100,114,97,103,100,111,99,107,46,99,97,112,116,105,111,110,6,9,65, + 115,115,101,109,98,108,101,114,20,100,114,97,103,100,111,99,107,46,111,112, + 116,105,111,110,115,100,111,99,107,11,10,111,100,95,115,97,118,101,112,111, + 115,13,111,100,95,115,97,118,101,122,111,114,100,101,114,10,111,100,95,99, + 97,110,109,111,118,101,11,111,100,95,99,97,110,102,108,111,97,116,10,111, + 100,95,99,97,110,100,111,99,107,11,111,100,95,112,114,111,112,115,105,122, + 101,14,111,100,95,99,97,112,116,105,111,110,104,105,110,116,13,111,100,95, + 99,104,105,108,100,105,99,111,110,115,0,7,111,112,116,105,111,110,115,11, + 10,102,111,95,115,97,118,101,112,111,115,13,102,111,95,115,97,118,101,122, + 111,114,100,101,114,12,102,111,95,115,97,118,101,115,116,97,116,101,0,8, + 115,116,97,116,102,105,108,101,7,22,109,97,105,110,102,111,46,112,114,111, + 106,101,99,116,115,116,97,116,102,105,108,101,7,99,97,112,116,105,111,110, + 6,9,65,115,115,101,109,98,108,101,114,21,105,99,111,110,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,12,105, + 99,111,110,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,0,10,105,99,111,110,46,105,109,97,103,101,10,136,7,0,0, + 0,0,0,0,2,0,0,0,24,0,0,0,24,0,0,0,244,6,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,208,208,208,25,136,136,136,13, + 130,136,136,1,136,136,136,1,208,208,208,9,136,136,136,1,179,248,254,1, + 182,248,254,1,185,249,254,1,188,250,254,1,191,250,254,1,194,251,254,1, + 198,251,254,1,201,252,254,1,204,253,254,1,207,253,254,1,210,254,254,1, + 213,254,254,1,127,135,135,1,159,197,200,1,136,136,136,1,208,208,208,8, + 136,136,136,1,179,248,254,1,182,248,254,1,185,249,254,1,188,250,254,1, + 191,250,254,1,194,251,254,1,198,251,254,1,201,252,254,1,204,253,254,1, + 207,253,254,1,210,254,254,1,213,254,254,1,131,137,138,1,198,249,255,1, + 158,197,200,1,136,136,136,1,208,208,208,7,136,136,136,1,179,248,254,1, + 182,248,254,1,185,249,254,1,188,250,254,1,191,250,254,1,194,251,254,1, + 198,251,254,1,201,252,254,1,204,253,254,1,207,253,254,1,210,254,254,1, + 213,254,254,1,133,138,138,1,226,252,255,1,197,249,255,1,158,197,200,1, + 136,136,136,1,208,208,208,6,136,136,136,1,179,248,254,1,182,248,254,1, + 185,249,254,1,188,250,254,1,191,250,254,1,194,251,254,1,198,251,254,1, + 201,252,254,1,204,253,254,1,207,253,254,1,210,254,254,1,213,254,254,1, + 130,137,138,1,254,254,255,1,225,252,255,1,195,249,255,1,158,197,200,1, + 136,136,136,1,208,208,208,5,136,136,136,1,179,248,254,1,182,248,254,1, + 185,249,254,1,188,250,254,1,191,250,254,1,194,251,254,1,198,251,254,1, + 201,252,254,1,204,253,254,1,207,253,254,1,210,254,254,1,213,254,254,1, + 127,137,138,1,223,252,255,1,252,254,255,1,223,252,255,1,194,249,255,1, + 157,196,200,1,136,136,136,1,208,208,208,4,136,136,136,1,179,248,254,1, + 182,248,254,1,185,249,254,1,188,250,254,1,191,250,254,1,194,251,254,1, + 198,251,254,1,201,252,254,1,204,253,254,1,207,253,254,1,210,254,254,1, + 213,254,254,1,124,137,138,1,190,249,255,1,225,252,255,1,250,254,255,1, + 221,252,255,1,192,249,255,1,157,196,200,1,136,136,136,1,208,208,208,3, + 136,136,136,1,179,248,254,1,182,248,254,1,185,249,254,1,188,250,254,1, + 191,250,254,1,194,251,254,1,198,251,254,1,201,252,254,1,204,253,254,1, + 207,253,254,1,210,254,254,1,213,254,254,1,121,137,138,1,158,246,255,1, + 192,249,255,1,227,252,255,1,249,254,255,1,220,251,255,1,190,249,255,1, + 157,196,200,1,136,136,136,1,208,208,208,2,136,136,136,1,179,248,254,1, + 182,248,254,1,185,249,254,1,188,250,254,1,191,250,254,1,194,251,254,1, + 198,251,254,1,201,252,254,1,204,253,254,1,207,253,254,1,210,254,254,1, + 213,254,254,1,130,150,151,1,120,137,138,1,122,137,138,1,124,137,138,1, + 126,137,138,2,122,137,138,1,119,134,135,1,129,136,136,1,208,208,208,2, + 136,136,136,1,179,248,254,1,182,248,254,1,185,249,254,1,188,250,254,1, + 191,250,254,1,194,251,254,1,198,251,254,1,201,252,254,1,204,253,254,1, + 207,253,254,1,210,254,254,1,213,254,254,1,206,253,254,1,191,252,254,1, + 176,250,254,1,162,248,254,1,147,246,254,1,132,244,254,1,117,243,254,1, + 102,241,254,1,136,136,136,1,208,208,208,2,136,136,136,1,179,248,254,1, + 182,248,254,1,185,249,254,1,188,250,254,1,191,250,254,1,194,251,254,1, + 198,251,254,1,201,252,254,1,204,253,254,1,207,253,254,1,210,254,254,1, + 213,254,254,1,206,253,254,1,191,252,254,1,176,250,254,1,162,248,254,1, + 147,246,254,1,132,244,254,1,117,243,254,1,102,241,254,1,136,136,136,1, + 208,208,208,2,136,136,136,1,179,248,254,1,182,248,254,1,175,235,240,1, + 87,116,118,1,55,73,74,1,125,161,163,1,198,251,254,1,201,252,254,1, + 204,253,254,1,198,242,243,1,73,89,89,1,213,254,254,1,206,253,254,1, + 191,252,254,1,109,155,157,1,49,75,77,1,66,111,115,1,128,237,247,1, + 117,243,254,1,102,241,254,1,136,136,136,1,208,208,208,2,136,136,136,1, + 179,248,254,1,182,248,254,1,77,104,106,1,98,130,132,1,170,223,226,1, + 42,54,55,1,157,199,201,1,201,252,254,1,173,214,215,1,50,61,61,1, + 13,16,16,1,213,254,254,1,206,253,254,1,142,188,189,1,44,63,64,1, + 148,227,232,1,68,114,118,1,61,113,118,1,117,243,254,1,102,241,254,1, + 136,136,136,1,208,208,208,2,136,136,136,1,179,248,254,1,182,248,254,1, + 20,26,27,1,167,222,225,1,191,250,254,1,99,128,129,1,94,119,121,1, + 201,252,254,1,94,117,118,1,157,192,193,1,26,31,31,1,213,254,254,1, + 206,253,254,1,84,111,112,1,97,138,140,1,162,248,254,1,124,207,214,1, + 19,34,36,1,117,243,254,1,102,241,254,1,136,136,136,1,208,208,208,2, + 136,136,136,1,179,248,254,1,178,243,249,1,16,21,22,1,188,250,254,1, + 191,250,254,1,132,170,172,1,71,90,91,1,201,252,254,1,204,253,254,1, + 207,253,254,1,26,31,31,1,213,254,254,1,206,253,254,1,61,80,81,1, + 131,186,189,1,162,248,254,1,145,242,250,1,7,13,14,1,117,243,254,1, + 102,241,254,1,136,136,136,1,208,208,208,2,136,136,136,1,179,248,254,1, + 179,244,250,1,12,16,16,1,188,250,254,1,191,250,254,1,126,162,164,1, + 78,98,100,1,201,252,254,1,204,253,254,1,207,253,254,1,26,31,31,1, + 213,254,254,1,206,253,254,1,61,81,82,1,128,181,184,1,162,248,254,1, + 142,238,246,1,9,17,18,1,117,243,254,1,102,241,254,1,136,136,136,1, + 208,208,208,2,136,136,136,1,179,248,254,1,182,248,254,1,17,23,24,1, + 167,223,226,1,191,250,254,1,93,120,122,1,104,132,133,1,201,252,254,1, + 204,253,254,1,207,253,254,1,26,31,31,1,213,254,254,1,206,253,254,1, + 82,108,109,1,98,139,141,1,162,248,254,1,119,200,206,1,25,47,49,1, + 117,243,254,1,102,241,254,1,136,136,136,1,208,208,208,2,136,136,136,1, + 179,248,254,1,182,248,254,1,91,122,125,1,75,100,102,1,141,184,187,1, + 36,46,47,1,173,220,222,1,201,252,254,1,204,253,254,1,207,253,254,1, + 26,31,31,1,213,254,254,1,206,253,254,1,154,204,205,1,36,51,52,1, + 122,187,191,1,49,82,85,1,78,144,150,1,117,243,254,1,102,241,254,1, + 136,136,136,1,208,208,208,2,136,136,136,1,179,248,254,1,182,248,254,1, + 185,249,254,1,140,186,189,1,91,119,121,1,157,203,205,1,198,251,254,1, + 201,252,254,1,204,253,254,1,207,253,254,1,118,142,142,1,213,254,254,1, + 206,253,254,1,191,252,254,1,155,220,223,1,79,122,125,1,97,163,168,1, + 131,243,253,1,117,243,254,1,102,241,254,1,136,136,136,1,208,208,208,2, + 136,136,136,1,179,248,254,1,182,248,254,1,185,249,254,1,188,250,254,1, + 191,250,254,1,194,251,254,1,198,251,254,1,201,252,254,1,204,253,254,1, + 207,253,254,1,210,254,254,1,213,254,254,1,206,253,254,1,191,252,254,1, + 176,250,254,1,162,248,254,1,147,246,254,1,132,244,254,1,117,243,254,1, + 102,241,254,1,136,136,136,1,208,208,208,2,136,136,136,1,179,248,254,1, + 182,248,254,1,185,249,254,1,188,250,254,1,191,250,254,1,194,251,254,1, + 198,251,254,1,201,252,254,1,204,253,254,1,207,253,254,1,210,254,254,1, + 213,254,254,1,206,253,254,1,191,252,254,1,176,250,254,1,162,248,254,1, + 147,246,254,1,132,244,254,1,117,243,254,1,102,241,254,1,136,136,136,1, + 208,208,208,2,136,136,136,22,208,208,208,25,0,0,0,8,254,255,0,8, + 254,255,1,191,254,255,3,8,254,255,7,0,254,255,15,8,254,255,31,2, + 254,255,63,192,254,255,127,0,254,255,127,8,254,255,127,0,254,255,127,8, + 254,255,127,8,254,255,127,8,254,255,127,191,254,255,127,8,254,255,127,0, + 254,255,127,2,254,255,127,8,254,255,127,0,254,255,127,0,254,255,127,191, + 254,255,127,0,0,0,0,8,6,111,110,115,104,111,119,7,14,100,105,115, + 97,115,115,102,111,111,110,115,104,111,119,15,109,111,100,117,108,101,99,108, + 97,115,115,110,97,109,101,6,9,116,100,111,99,107,102,111,114,109,0,11, + 116,115,116,114,105,110,103,103,114,105,100,4,103,114,105,100,5,99,111,108, + 111,114,4,5,0,0,144,20,102,114,97,109,101,46,115,98,118,101,114,116, + 46,111,112,116,105,111,110,115,11,14,115,98,111,95,116,104,117,109,98,116, + 114,97,99,107,8,115,98,111,95,115,104,111,119,0,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,9,112,111,112,117,112,109, + 101,110,117,7,8,112,111,112,117,112,109,101,110,8,98,111,117,110,100,115, + 95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,120,3,42,2,9,98,111,117,110,100,115,95,99,121,3,210, + 0,7,97,110,99,104,111,114,115,11,0,9,111,110,107,101,121,100,111,119, + 110,7,5,107,101,121,100,111,11,111,112,116,105,111,110,115,103,114,105,100, + 11,12,111,103,95,99,111,108,115,105,122,105,110,103,20,111,103,95,99,111, + 108,99,104,97,110,103,101,111,110,116,97,98,107,101,121,10,111,103,95,119, + 114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112,117,112,0, + 14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,4,16,100,97, + 116,97,99,111,108,115,46,111,112,116,105,111,110,115,11,11,99,111,95,114, + 101,97,100,111,110,108,121,12,99,111,95,100,114,97,119,102,111,99,117,115, + 12,99,111,95,115,97,118,101,115,116,97,116,101,0,14,100,97,116,97,99, + 111,108,115,46,105,116,101,109,115,14,1,5,119,105,100,116,104,2,76,16, + 111,110,98,101,102,111,114,101,100,114,97,119,99,101,108,108,7,11,98,101, + 102,100,114,97,119,99,101,108,108,7,111,112,116,105,111,110,115,11,11,99, + 111,95,114,101,97,100,111,110,108,121,12,99,111,95,100,114,97,119,102,111, + 99,117,115,12,99,111,95,115,97,118,101,115,116,97,116,101,0,11,111,110, + 99,101,108,108,101,118,101,110,116,7,13,97,100,100,114,99,101,108,108,101, + 118,101,110,116,9,116,101,120,116,102,108,97,103,115,11,8,116,102,95,114, + 105,103,104,116,12,116,102,95,121,99,101,110,116,101,114,101,100,11,116,102, + 95,110,111,115,101,108,101,99,116,0,15,116,101,120,116,102,108,97,103,115, + 97,99,116,105,118,101,11,8,116,102,95,114,105,103,104,116,12,116,102,95, + 121,99,101,110,116,101,114,101,100,0,11,111,112,116,105,111,110,115,101,100, + 105,116,11,14,115,99,111,101,95,101,97,116,114,101,116,117,114,110,20,115, + 99,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116,0, + 9,102,111,110,116,46,110,97,109,101,6,9,115,116,102,95,102,105,120,101, + 100,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99, + 97,108,101,0,10,118,97,108,117,101,102,97,108,115,101,6,1,48,9,118, + 97,108,117,101,116,114,117,101,6,1,49,0,1,5,119,105,100,116,104,3, + 99,1,7,111,112,116,105,111,110,115,11,11,99,111,95,114,101,97,100,111, + 110,108,121,12,99,111,95,100,114,97,119,102,111,99,117,115,7,99,111,95, + 102,105,108,108,12,99,111,95,115,97,118,101,115,116,97,116,101,0,9,116, + 101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101,110,116,101,114, + 101,100,11,116,102,95,110,111,115,101,108,101,99,116,13,116,102,95,116,97, + 98,116,111,115,112,97,99,101,0,15,116,101,120,116,102,108,97,103,115,97, + 99,116,105,118,101,11,12,116,102,95,121,99,101,110,116,101,114,101,100,13, + 116,102,95,116,97,98,116,111,115,112,97,99,101,0,11,111,112,116,105,111, + 110,115,101,100,105,116,11,14,115,99,111,101,95,101,97,116,114,101,116,117, + 114,110,20,115,99,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116, + 101,120,116,0,10,118,97,108,117,101,102,97,108,115,101,6,1,48,9,118, + 97,108,117,101,116,114,117,101,6,1,49,0,1,7,111,112,116,105,111,110, + 115,11,11,99,111,95,114,101,97,100,111,110,108,121,12,99,111,95,105,110, + 118,105,115,105,98,108,101,12,99,111,95,100,114,97,119,102,111,99,117,115, + 12,99,111,95,115,97,118,101,115,116,97,116,101,0,10,118,97,108,117,101, + 102,97,108,115,101,6,1,48,9,118,97,108,117,101,116,114,117,101,6,1, + 49,0,1,7,111,112,116,105,111,110,115,11,11,99,111,95,114,101,97,100, + 111,110,108,121,12,99,111,95,105,110,118,105,115,105,98,108,101,12,99,111, + 95,100,114,97,119,102,111,99,117,115,12,99,111,95,115,97,118,101,115,116, + 97,116,101,0,10,118,97,108,117,101,102,97,108,115,101,6,1,48,9,118, + 97,108,117,101,116,114,117,101,6,1,49,0,0,15,114,111,119,99,111,108, + 111,114,115,46,99,111,117,110,116,2,2,15,114,111,119,99,111,108,111,114, + 115,46,105,116,101,109,115,1,4,255,255,224,0,4,224,255,255,0,0,13, + 100,97,116,97,114,111,119,104,101,105,103,104,116,2,16,12,111,110,115,99, + 114,111,108,108,114,111,119,115,7,10,115,99,114,111,108,108,114,111,119,115, + 11,111,110,99,101,108,108,101,118,101,110,116,7,12,99,101,108,108,101,118, + 101,110,116,101,120,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,13,0,0,10,116,112,111,112,117,112,109,101,110,117,8,112,111,112,117, + 112,109,101,110,8,111,110,117,112,100,97,116,101,7,11,112,111,112,117,112, + 117,112,100,97,116,101,18,109,101,110,117,46,115,117,98,109,101,110,117,46, + 99,111,117,110,116,2,1,18,109,101,110,117,46,115,117,98,109,101,110,117, + 46,105,116,101,109,115,14,1,7,99,97,112,116,105,111,110,6,16,83,104, + 111,119,32,38,66,114,101,97,107,112,111,105,110,116,4,110,97,109,101,6, + 9,115,104,111,119,98,114,101,97,107,5,115,116,97,116,101,11,15,97,115, + 95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99, + 97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117, + 116,101,7,12,115,104,111,119,98,114,101,97,107,101,120,101,0,0,4,108, + 101,102,116,2,120,3,116,111,112,2,24,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tdisassfo,''); +end. diff --git a/mseide-msegui/apps/ide/dumpunitgroups.pas b/mseide-msegui/apps/ide/dumpunitgroups.pas new file mode 100644 index 0000000..55f9951 --- /dev/null +++ b/mseide-msegui/apps/ide/dumpunitgroups.pas @@ -0,0 +1,236 @@ +{ MSEgui Copyright (c) 2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit dumpunitgroups; +{$ifdef FPC}{$mode objfpc}{$h+}{$INTERFACES CORBA}{$endif} +interface +procedure dumpunitgr; +implementation +uses + msedesigner,msedesignintf,typinfo,mseclasses,pascaldesignparser,msearrayutils, + sourceupdate,msestrings,msearrayprops,msetypes,msedatalist,msedesignparser; + +procedure dumpunitgr; +const + systypes: array[0..9] of string = ('Boolean','Integer','AnsiString', + 'Pointer','LongInt','LongWord','Variant','Int64','QWord','Currency'); +type + unitnamety = record + name: string; + uppername: string; + end; + unitnamearty = array of unitnamety; + unitgroupty = record + group: unitnamety; + units: unitnamearty; + end; + punitgroupty = ^unitgroupty; + unitgrouparty = array of unitgroupty; +var + groupar: unitgrouparty; + + function findgroup(const unitname: string): punitgroupty; + var + str1: string; + int1,int2: integer; + begin + str1:= struppercase(unitname); + int2:= length(groupar); + for int1:= 0 to int2 - 1 do begin + if str1 = groupar[int1].group.uppername then begin + int2:= int1; + break; + end; + end; + if int2 > high(groupar) then begin + setlength(groupar,int2+1); + with groupar[int2] do begin + group.name:= unitname; + group.uppername:= struppercase(unitname); + end; + end; + result:= @groupar[int2]; + end; + + procedure adddependency(const agroup: punitgroupty; const unitname: string); + var + str1: string; + int1,int2: integer; + begin + str1:= struppercase(unitname); + if str1 <> 'SYSTEM' then begin + with agroup^do begin + if str1 <> group.uppername then begin + int2:= length(units); + for int1:= 0 to int2 - 1 do begin + if units[int1].uppername = str1 then begin + int2:= int1; + break; + end; + end; + if int2> high(units) then begin + setlength(units,int2+1); + with units[int2] do begin + name:= unitname; + uppername:= str1; + end; + end; + end; + end; + end; + end; + +var + classn: string; + parsedclasses: classarty; + po6: punitgroupty; + + function isnotparsed(const aclass: tclass): boolean; + var + int1: integer; + begin + for int1:= 0 to high(parsedclasses) do begin + if parsedclasses[int1] = aclass then begin + result:= false; + exit; + end; + end; + additem(pointerarty(parsedclasses),aclass); + result:= true; + end; + + procedure dumpclass(po2: ptypeinfo); + var + po4: punitinfoty; + ar1: propinfopoarty; + int2,int3,int4: integer; + bo1: boolean; + defunitna,propna,typena,unitn: string; + po5: pdefinfoty; + methinfo: methodparaminfoty; + po3: ptypeinfo; + class1: tclass; + begin + if po2 = nil then begin + exit; + end; + unitn:= gettypedata(po2)^.unitname; + po4:= sourceupdater.updateunitinterface(unitn); + if po4 <> nil then begin + ar1:= getpropinfoar(po2); + for int2:= 0 to high(ar1) do begin + po2:= ar1[int2]^.proptype; + if po2^.kind = tkmethod then begin + getmethodparaminfo(po2,methinfo); + propna:= ar1[int2]^.name; + // writeln(' ',propna); + for int3:= 0 to high(methinfo.params) do begin + typena:= methinfo.params[int3].typename; + bo1:= false; + for int4:= 0 to high(systypes) do begin + bo1:= typena = systypes[int4]; + if bo1 then begin + break; + end; + end; + if not bo1 then begin + po5:= sourceupdater.finddef(po4,typena); + if po5 <> nil then begin + defunitna:= po5^.owner.rootlist.unitinfopo^.origunitname; + adddependency(po6,defunitna); + // writeln(' ',typena,' ',defunitna); + end + else begin + if typena = 'Exception' then begin + adddependency(po6,'sysutils'); + end + else begin + writeln(unitn,'.',classn,'.',propna,' "',typena+'" def unit not found.'); + end; + end; + end; + end; + end + else begin + if po2^.kind = tkclass then begin + class1:= gettypedata(po2)^.classtype; + if class1 = nil then begin + writeln(unitn,'.',classn,'.',propna, + ' "',typena+' '+po2^.name+'" typedata nil.'); + end + else begin + if isnotparsed(class1) then begin + po3:= class1.classinfo; + dumpclass(po3); + if class1.inheritsfrom(tpersistentarrayprop) then begin + class1:= persistentarraypropclassty(class1).getitemclasstype; + if class1 = nil then begin + writeln(unitn,'.',classn,'.',propna, + ' "',typena+' '+po3^.name+'" itemclasstype nil.'); + end + else begin + po3:= class1.classinfo; + dumpclass(po3); + end; + end; + end; + end; + end; + end; + end; + end + else begin + writeln('"'+unitn+'"'+'for '+'"'+classn+'" not found.'); + end; + end; //dumpclass + +var + int1,int2: integer; + po1: pcomponentclassinfoty; + po2: ptypeinfo; +// po3: ptypedata; + +begin + parsedclasses:= nil; + with registeredcomponents do begin + if count > 0 then begin + po1:= itempo(0); + for int1:= 0 to count - 1 do begin + classn:= po1^.classtyp.classname; +// writeln(classn); + po2:= po1^.classtyp.classinfo; + if isnotparsed(po1^.classtyp) then begin + po6:= findgroup(gettypedata(po2)^.unitname); + dumpclass(po2); + end; + inc(po1); + end; + end; + end; + writeln; + for int1:= 0 to high(groupar) do begin + with groupar[int1] do begin + if high(units) >= 0 then begin + write(' registerunitgroup(['''+group.name+'''],['); + for int2:= 0 to high(units) do begin + write(''''+units[int2].name+''''); + if int2 = high(units) then begin + write(']);'); + end + else begin + write(','); + end; + end; + writeln; + end; + end; + end; +end; + +end. diff --git a/mseide-msegui/apps/ide/finddialogform.mfm b/mseide-msegui/apps/ide/finddialogform.mfm new file mode 100644 index 0000000..671c690 --- /dev/null +++ b/mseide-msegui/apps/ide/finddialogform.mfm @@ -0,0 +1,213 @@ +object finddialogfo: tfinddialogfo + optionswidget = [ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets, ow_hinton] + visible = False + bounds_x = 319 + bounds_y = 205 + bounds_cx = 371 + bounds_cy = 93 + anchors = [an_left, an_top, an_right] + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 371 + 93 + ) + options = [fo_closeonesc, fo_localshortcuts, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder] + statfile = statfile1 + caption = 'Find Text' + moduleclassname = 'tmseform' + object findtext: thistoryedit + frame.caption = '&Text to find' + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + end> + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + bounds_x = 8 + bounds_y = 6 + bounds_cx = 356 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + optionsedit1 = [oe1_autopopupmenu, oe1_savevalue, oe1_savestate] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + reffontheight = 14 + end + object tlayouter4: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + taborder = 1 + bounds_x = 8 + bounds_y = 47 + bounds_cx = 358 + bounds_cy = 36 + anchors = [an_left, an_top, an_right] + optionsscale = [osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_placex, lao_aligny] + align_glue = wam_start + place_mindist = 4 + place_maxdist = 4 + place_options = [plo_endmargin] + linktop = findtext + dist_top = 4 + object tlayouter3: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + taborder = 1 + bounds_x = 105 + bounds_y = 0 + bounds_cx = 86 + bounds_cy = 36 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_alignx, lao_placey] + align_glue = wam_start + place_mindist = 4 + place_maxdist = 4 + object wholeword: tbooleanedit + frame.caption = '&whole word' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 73 + 2 + ) + bounds_x = 0 + bounds_y = 0 + bounds_cx = 86 + bounds_cy = 16 + end + object backward: tbooleanedit + frame.caption = '&backward' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 63 + 2 + ) + taborder = 1 + bounds_x = 0 + bounds_y = 20 + bounds_cx = 76 + bounds_cy = 16 + end + end + object tlayouter2: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + frame.localprops = [] + frame.localprops1 = [] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 101 + bounds_cy = 36 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_alignx, lao_placey] + align_glue = wam_start + place_mindist = 4 + place_maxdist = 4 + dist_top = 4 + dist_bottom = 4 + object casesensitive: tbooleanedit + frame.caption = 'c&asesensitive' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 88 + 2 + ) + bounds_x = 0 + bounds_y = 0 + bounds_cx = 101 + bounds_cy = 16 + end + object selectedonly: tbooleanedit + frame.caption = '&selected only' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 86 + 2 + ) + taborder = 1 + bounds_x = 0 + bounds_y = 20 + bounds_cx = 99 + bounds_cy = 16 + statfile = statfile1 + end + end + object tlayouter1: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + taborder = 2 + bounds_x = 195 + bounds_y = 8 + bounds_cx = 163 + bounds_cy = 20 + anchors = [an_left, an_top, an_right] + optionsscale = [osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_aligny] + align_glue = wam_start + place_options = [plo_endmargin] + object tlayouter5: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + frame.localprops = [] + frame.localprops1 = [] + bounds_x = 51 + bounds_y = 0 + bounds_cx = 109 + bounds_cy = 20 + anchors = [an_top, an_right] + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + optionslayout = [lao_placex, lao_aligny, lao_syncmaxautosize] + align_glue = wam_start + place_mindist = 5 + place_maxdist = 5 + place_mode = wam_end + object cancel: tbutton + taborder = 1 + bounds_x = 57 + bounds_y = 0 + bounds_cx = 52 + bounds_cy = 20 + anchors = [an_top, an_right] + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + end + object tbutton2: tbutton + bounds_x = 0 + bounds_y = 0 + bounds_cx = 52 + bounds_cy = 20 + anchors = [an_top, an_right] + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + end + end + end + end + object statfile1: tstatfile + filename = 'finddialogfo.sta' + options = [sfo_memory] + left = 112 + end +end diff --git a/mseide-msegui/apps/ide/finddialogform.pas b/mseide-msegui/apps/ide/finddialogform.pas new file mode 100644 index 0000000..f882a8e --- /dev/null +++ b/mseide-msegui/apps/ide/finddialogform.pas @@ -0,0 +1,113 @@ +{ MSEide Copyright (c) 1999-2013 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit finddialogform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseforms,msesimplewidgets,msedataedits,msegraphedits,msetextedit,msestrings, + msetypes,msestat,msestatfile,projectoptionsform,mseglob,mseevent,msegui, + msemenus,msesplitter,msegraphics,msegraphutils,msewidgets,mseguiglob, + mseificomp,mseificompglob,mseifiglob,msescrollbar; + +type + + tfinddialogfo = class(tmseform) + findtext: thistoryedit; + statfile1: tstatfile; + ok: tbutton; + tlayouter4: tlayouter; + tlayouter3: tlayouter; + wholeword: tbooleanedit; + backward: tbooleanedit; + tlayouter2: tlayouter; + casesensitive: tbooleanedit; + selectedonly: tbooleanedit; + tlayouter1: tlayouter; + tlayouter5: tlayouter; + cancel: tbutton; + tbutton2: tbutton; + private + procedure valuestoinfo(out info: findinfoty); + procedure infotovalues(const info: findinfoty); + end; + +procedure updatefindvalues(const astatfiler: tstatfiler; + var aoptions: findinfoty); +function finddialogexecute(var info: findinfoty): boolean; + +implementation +uses + finddialogform_mfm; + +procedure updatefindvalues(const astatfiler: tstatfiler; + var aoptions: findinfoty); +var + int1: integer; +begin + with astatfiler,aoptions do begin + updatevalue('finddtext',text); + updatevalue('findhistory',history); + int1:= {$ifdef FPC}longword{$else}byte{$endif}(options); + updatevalue('findoptions',int1); + options:= searchoptionsty({$ifdef FPC}longword{$else}byte{$endif}(int1)); + end; +end; + +function finddialogexecute(var info: findinfoty): boolean; +var + fo: tfinddialogfo; +begin + fo:= tfinddialogfo.create(nil); + try + fo.infotovalues(info); + result:= fo.show(true,nil) = mr_ok; + if result then begin + fo.valuestoinfo(info); + end; + finally + fo.Free; + end; +end; + +{ tfinddialogfo } + +procedure tfinddialogfo.valuestoinfo(out info: findinfoty); +begin + with info do begin + text:= findtext.value; + history:= findtext.dropdown.valuelist.asarray; + options:= encodesearchoptions(not casesensitive.value,wholeword.value, + false,backward.value); + selectedonly:= self.selectedonly.value; + end; +end; + +procedure tfinddialogfo.infotovalues(const info: findinfoty); +begin + with info do begin + findtext.value:= text; + findtext.dropdown.valuelist.asarray:= history; + casesensitive.value:= not (so_caseinsensitive in options); + wholeword.value:= so_wholeword in options; + backward.value:= so_backward in options; +// self.selectedonly.value:= selectedonly; + end; +end; + +end. diff --git a/mseide-msegui/apps/ide/finddialogform_mfm.pas b/mseide-msegui/apps/ide/finddialogform_mfm.pas new file mode 100644 index 0000000..d9634e1 --- /dev/null +++ b/mseide-msegui/apps/ide/finddialogform_mfm.pas @@ -0,0 +1,238 @@ +unit finddialogform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,finddialogform; + +const + objdata: record size: integer; data: array[0..4417] of byte end = + (size: 4418; data: ( + 84,80,70,48,13,116,102,105,110,100,100,105,97,108,111,103,102,111,12,102, + 105,110,100,100,105,97,108,111,103,102,111,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,11,111,119,95,116,97,98,102,111,99,117,115,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111, + 119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99, + 117,115,111,117,116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119, + 95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,9,111,119,95,104, + 105,110,116,111,110,0,7,118,105,115,105,98,108,101,8,8,98,111,117,110, + 100,115,95,120,3,63,1,8,98,111,117,110,100,115,95,121,3,205,0,9, + 98,111,117,110,100,115,95,99,120,3,115,1,9,98,111,117,110,100,115,95, + 99,121,2,93,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102, + 116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,23,99, + 111,110,116,97,105,110,101,114,46,111,112,116,105,111,110,115,119,105,100,103, + 101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119, + 95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111, + 99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16, + 111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95, + 115,117,98,102,111,99,117,115,19,111,119,95,109,111,117,115,101,116,114,97, + 110,115,112,97,114,101,110,116,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,0,26,99,111,110,116,97,105,110,101,114,46,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,27,99,111,110, + 116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,16,99,111,110,116,97,105,110,101,114,46,98,111,117, + 110,100,115,1,2,0,2,0,3,115,1,2,93,0,7,111,112,116,105,111, + 110,115,11,13,102,111,95,99,108,111,115,101,111,110,101,115,99,17,102,111, + 95,108,111,99,97,108,115,104,111,114,116,99,117,116,115,15,102,111,95,97, + 117,116,111,114,101,97,100,115,116,97,116,16,102,111,95,97,117,116,111,119, + 114,105,116,101,115,116,97,116,10,102,111,95,115,97,118,101,112,111,115,13, + 102,111,95,115,97,118,101,122,111,114,100,101,114,0,8,115,116,97,116,102, + 105,108,101,7,9,115,116,97,116,102,105,108,101,49,7,99,97,112,116,105, + 111,110,6,9,70,105,110,100,32,84,101,120,116,15,109,111,100,117,108,101, + 99,108,97,115,115,110,97,109,101,6,8,116,109,115,101,102,111,114,109,0, + 12,116,104,105,115,116,111,114,121,101,100,105,116,8,102,105,110,100,116,101, + 120,116,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,13,38,84, + 101,120,116,32,116,111,32,102,105,110,100,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,19,102,114,97,109,101,46,98,117,116, + 116,111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98, + 117,116,116,111,110,115,46,105,116,101,109,115,14,1,0,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0, + 2,0,0,8,98,111,117,110,100,115,95,120,2,8,8,98,111,117,110,100, + 115,95,121,2,6,9,98,111,117,110,100,115,95,99,120,3,100,1,9,98, + 111,117,110,100,115,95,99,121,2,37,7,97,110,99,104,111,114,115,11,7, + 97,110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105, + 103,104,116,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111, + 101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,13,111,101,49, + 95,115,97,118,101,118,97,108,117,101,13,111,101,49,95,115,97,118,101,115, + 116,97,116,101,0,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111, + 101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101, + 113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99, + 101,108,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101, + 120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13, + 111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116, + 111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0, + 19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,99,111,117,110,116, + 2,1,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,105,116,101, + 109,115,14,1,0,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,9,116,108,97,121,111,117,116,101,114,10,116,108,97,121,111, + 117,116,101,114,52,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 11,111,119,95,116,97,98,102,111,99,117,115,17,111,119,95,112,97,114,101, + 110,116,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102, + 111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110, + 16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119, + 95,115,117,98,102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121, + 119,105,100,103,101,116,115,0,8,116,97,98,111,114,100,101,114,2,1,8, + 98,111,117,110,100,115,95,120,2,8,8,98,111,117,110,100,115,95,121,2, + 47,9,98,111,117,110,100,115,95,99,120,3,102,1,9,98,111,117,110,100, + 115,95,99,121,2,36,7,97,110,99,104,111,114,115,11,7,97,110,95,108, + 101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0, + 12,111,112,116,105,111,110,115,115,99,97,108,101,11,11,111,115,99,95,101, + 120,112,97,110,100,121,11,111,115,99,95,115,104,114,105,110,107,121,17,111, + 115,99,95,101,120,112,97,110,100,115,104,114,105,110,107,120,17,111,115,99, + 95,101,120,112,97,110,100,115,104,114,105,110,107,121,0,13,111,112,116,105, + 111,110,115,108,97,121,111,117,116,11,10,108,97,111,95,112,108,97,99,101, + 120,10,108,97,111,95,97,108,105,103,110,121,0,10,97,108,105,103,110,95, + 103,108,117,101,7,9,119,97,109,95,115,116,97,114,116,13,112,108,97,99, + 101,95,109,105,110,100,105,115,116,2,4,13,112,108,97,99,101,95,109,97, + 120,100,105,115,116,2,4,13,112,108,97,99,101,95,111,112,116,105,111,110, + 115,11,13,112,108,111,95,101,110,100,109,97,114,103,105,110,0,7,108,105, + 110,107,116,111,112,7,8,102,105,110,100,116,101,120,116,8,100,105,115,116, + 95,116,111,112,2,4,0,9,116,108,97,121,111,117,116,101,114,10,116,108, + 97,121,111,117,116,101,114,51,13,111,112,116,105,111,110,115,119,105,100,103, + 101,116,11,11,111,119,95,116,97,98,102,111,99,117,115,17,111,119,95,112, + 97,114,101,110,116,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114, + 111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117, + 115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116, + 11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95,100,101,115,116, + 114,111,121,119,105,100,103,101,116,115,0,8,116,97,98,111,114,100,101,114, + 2,1,8,98,111,117,110,100,115,95,120,2,105,8,98,111,117,110,100,115, + 95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,86,9,98,111,117, + 110,100,115,95,99,121,2,36,12,111,112,116,105,111,110,115,115,99,97,108, + 101,11,11,111,115,99,95,101,120,112,97,110,100,120,11,111,115,99,95,115, + 104,114,105,110,107,120,11,111,115,99,95,101,120,112,97,110,100,121,11,111, + 115,99,95,115,104,114,105,110,107,121,17,111,115,99,95,101,120,112,97,110, + 100,115,104,114,105,110,107,120,17,111,115,99,95,101,120,112,97,110,100,115, + 104,114,105,110,107,121,0,13,111,112,116,105,111,110,115,108,97,121,111,117, + 116,11,10,108,97,111,95,97,108,105,103,110,120,10,108,97,111,95,112,108, + 97,99,101,121,0,10,97,108,105,103,110,95,103,108,117,101,7,9,119,97, + 109,95,115,116,97,114,116,13,112,108,97,99,101,95,109,105,110,100,105,115, + 116,2,4,13,112,108,97,99,101,95,109,97,120,100,105,115,116,2,4,0, + 12,116,98,111,111,108,101,97,110,101,100,105,116,9,119,104,111,108,101,119, + 111,114,100,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,11,38, + 119,104,111,108,101,32,119,111,114,100,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101, + 114,102,114,97,109,101,1,2,0,2,1,2,73,2,2,0,8,98,111,117, + 110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,120,2,86,9,98,111,117,110,100,115,95,99,121, + 2,16,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,8,98,97, + 99,107,119,97,114,100,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,9,38,98,97,99,107,119,97,114,100,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,1,2,63,2,2,0,8,116,97, + 98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0,8, + 98,111,117,110,100,115,95,121,2,20,9,98,111,117,110,100,115,95,99,120, + 2,76,9,98,111,117,110,100,115,95,99,121,2,16,0,0,0,9,116,108, + 97,121,111,117,116,101,114,10,116,108,97,121,111,117,116,101,114,50,13,111, + 112,116,105,111,110,115,119,105,100,103,101,116,11,11,111,119,95,116,97,98, + 102,111,99,117,115,17,111,119,95,112,97,114,101,110,116,116,97,98,102,111, + 99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119, + 95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114, + 111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111,99, + 117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121, + 2,0,9,98,111,117,110,100,115,95,99,120,2,101,9,98,111,117,110,100, + 115,95,99,121,2,36,12,111,112,116,105,111,110,115,115,99,97,108,101,11, + 11,111,115,99,95,101,120,112,97,110,100,120,11,111,115,99,95,115,104,114, + 105,110,107,120,11,111,115,99,95,101,120,112,97,110,100,121,11,111,115,99, + 95,115,104,114,105,110,107,121,17,111,115,99,95,101,120,112,97,110,100,115, + 104,114,105,110,107,120,17,111,115,99,95,101,120,112,97,110,100,115,104,114, + 105,110,107,121,0,13,111,112,116,105,111,110,115,108,97,121,111,117,116,11, + 10,108,97,111,95,97,108,105,103,110,120,10,108,97,111,95,112,108,97,99, + 101,121,0,10,97,108,105,103,110,95,103,108,117,101,7,9,119,97,109,95, + 115,116,97,114,116,13,112,108,97,99,101,95,109,105,110,100,105,115,116,2, + 4,13,112,108,97,99,101,95,109,97,120,100,105,115,116,2,4,8,100,105, + 115,116,95,116,111,112,2,4,11,100,105,115,116,95,98,111,116,116,111,109, + 2,4,0,12,116,98,111,111,108,101,97,110,101,100,105,116,13,99,97,115, + 101,115,101,110,115,105,116,105,118,101,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,14,99,38,97,115,101,115,101,110,115,105,116,105,118,101, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2, + 1,2,88,2,2,0,8,98,111,117,110,100,115,95,120,2,0,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,101, + 9,98,111,117,110,100,115,95,99,121,2,16,0,0,12,116,98,111,111,108, + 101,97,110,101,100,105,116,12,115,101,108,101,99,116,101,100,111,110,108,121, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,14,38,115,101,108, + 101,99,116,101,100,32,111,110,108,121,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101, + 114,102,114,97,109,101,1,2,0,2,1,2,86,2,2,0,8,116,97,98, + 111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0,8,98, + 111,117,110,100,115,95,121,2,20,9,98,111,117,110,100,115,95,99,120,2, + 99,9,98,111,117,110,100,115,95,99,121,2,16,8,115,116,97,116,102,105, + 108,101,7,9,115,116,97,116,102,105,108,101,49,0,0,0,9,116,108,97, + 121,111,117,116,101,114,10,116,108,97,121,111,117,116,101,114,49,13,111,112, + 116,105,111,110,115,119,105,100,103,101,116,11,11,111,119,95,116,97,98,102, + 111,99,117,115,17,111,119,95,112,97,114,101,110,116,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95, + 97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111, + 119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111,99,117, + 115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120, + 3,195,0,8,98,111,117,110,100,115,95,121,2,8,9,98,111,117,110,100, + 115,95,99,120,3,163,0,9,98,111,117,110,100,115,95,99,121,2,20,7, + 97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110,95, + 116,111,112,8,97,110,95,114,105,103,104,116,0,12,111,112,116,105,111,110, + 115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97,110,100,121,11, + 111,115,99,95,115,104,114,105,110,107,121,17,111,115,99,95,101,120,112,97, + 110,100,115,104,114,105,110,107,120,17,111,115,99,95,101,120,112,97,110,100, + 115,104,114,105,110,107,121,0,13,111,112,116,105,111,110,115,108,97,121,111, + 117,116,11,10,108,97,111,95,97,108,105,103,110,121,0,10,97,108,105,103, + 110,95,103,108,117,101,7,9,119,97,109,95,115,116,97,114,116,13,112,108, + 97,99,101,95,111,112,116,105,111,110,115,11,13,112,108,111,95,101,110,100, + 109,97,114,103,105,110,0,0,9,116,108,97,121,111,117,116,101,114,10,116, + 108,97,121,111,117,116,101,114,53,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,11,111,119,95,116,97,98,102,111,99,117,115,17,111,119,95, + 112,97,114,101,110,116,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,8,98,111,117,110,100,115,95,120, + 2,51,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,2,109,9,98,111,117,110,100,115,95,99,121,2,20,7,97,110, + 99,104,111,114,115,11,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,0,12,111,112,116,105,111,110,115,115,99,97,108,101,11,11,111,115, + 99,95,101,120,112,97,110,100,120,11,111,115,99,95,115,104,114,105,110,107, + 120,11,111,115,99,95,101,120,112,97,110,100,121,11,111,115,99,95,115,104, + 114,105,110,107,121,0,13,111,112,116,105,111,110,115,108,97,121,111,117,116, + 11,10,108,97,111,95,112,108,97,99,101,120,10,108,97,111,95,97,108,105, + 103,110,121,19,108,97,111,95,115,121,110,99,109,97,120,97,117,116,111,115, + 105,122,101,0,10,97,108,105,103,110,95,103,108,117,101,7,9,119,97,109, + 95,115,116,97,114,116,13,112,108,97,99,101,95,109,105,110,100,105,115,116, + 2,5,13,112,108,97,99,101,95,109,97,120,100,105,115,116,2,5,10,112, + 108,97,99,101,95,109,111,100,101,7,7,119,97,109,95,101,110,100,0,7, + 116,98,117,116,116,111,110,6,99,97,110,99,101,108,8,116,97,98,111,114, + 100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,57,8,98,111,117, + 110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,52,9, + 98,111,117,110,100,115,95,99,121,2,20,7,97,110,99,104,111,114,115,11, + 6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,5,115,116, + 97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110, + 0,7,99,97,112,116,105,111,110,6,7,38,67,97,110,99,101,108,11,109, + 111,100,97,108,114,101,115,117,108,116,7,9,109,114,95,99,97,110,99,101, + 108,0,0,7,116,98,117,116,116,111,110,8,116,98,117,116,116,111,110,50, + 8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121, + 2,0,9,98,111,117,110,100,115,95,99,120,2,52,9,98,111,117,110,100, + 115,95,99,121,2,20,7,97,110,99,104,111,114,115,11,6,97,110,95,116, + 111,112,8,97,110,95,114,105,103,104,116,0,5,115,116,97,116,101,11,10, + 97,115,95,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,100, + 101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,99,97,112,116,105, + 111,110,0,7,99,97,112,116,105,111,110,6,3,38,79,75,11,109,111,100, + 97,108,114,101,115,117,108,116,7,5,109,114,95,111,107,0,0,0,0,0, + 9,116,115,116,97,116,102,105,108,101,9,115,116,97,116,102,105,108,101,49, + 8,102,105,108,101,110,97,109,101,6,16,102,105,110,100,100,105,97,108,111, + 103,102,111,46,115,116,97,7,111,112,116,105,111,110,115,11,10,115,102,111, + 95,109,101,109,111,114,121,0,4,108,101,102,116,2,112,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tfinddialogfo,''); +end. diff --git a/mseide-msegui/apps/ide/findinfiledialogform.mfm b/mseide-msegui/apps/ide/findinfiledialogform.mfm new file mode 100644 index 0000000..45895af --- /dev/null +++ b/mseide-msegui/apps/ide/findinfiledialogform.mfm @@ -0,0 +1,308 @@ +object findinfileadialogfo: tfindinfiledialogfo + optionswidget = [ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets, ow_hinton] + visible = False + bounds_x = 268 + bounds_y = 415 + bounds_cx = 339 + bounds_cy = 275 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 339 + 275 + ) + options = [fo_closeonesc, fo_localshortcuts, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder] + statfile = statfile1 + caption = 'Find Text in Files' + oncreate = cereateev + moduleclassname = 'tmseform' + object findtext: thistoryedit + frame.caption = '&Text to find' + frame.localprops = [] + frame.localprops1 = [] + frame.button.color = -2147483646 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + bounds_x = 8 + bounds_y = 9 + bounds_cx = 321 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + statfile = statfile1 + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + reffontheight = 14 + end + object dir: tfilenameedit + frame.caption = '&Directory' + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 3 + onshowhint = dirshowhint + bounds_x = 8 + bounds_y = 137 + bounds_cx = 321 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + statfile = statfile1 + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + onsetvalue = dirsetvalue + controller.options = [fdo_directory] + controller.ongetfilename = dirgetfilenameexe + controller.onbeforeexecute = dironbeforeexecute + reffontheight = 14 + end + object mask: thistoryedit + frame.caption = '&File Mask' + frame.localprops = [] + frame.localprops1 = [] + frame.button.color = -2147483646 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 4 + bounds_x = 8 + bounds_y = 185 + bounds_cx = 321 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + statfile = statfile1 + value = '"*.pas" "*.pp" "*.inc"' + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + reffontheight = 14 + end + object tlayouter1: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + taborder = 1 + bounds_x = 0 + bounds_y = 48 + bounds_cx = 154 + bounds_cy = 80 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + linkright = tlayouter2 + object indirectories: tbooleaneditradio + frame.caption = 'Search in &directories' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 133 + 2 + ) + taborder = 2 + bounds_x = 8 + bounds_y = 64 + bounds_cx = 146 + bounds_cy = 16 + statfile = statfile1 + ondataentered = sourcechangeexe + onsetvalue = dirsetval + end + object casesensitive: tbooleanedit + frame.caption = 'C&asesensitive' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 89 + 2 + ) + bounds_x = 8 + bounds_y = 16 + bounds_cx = 102 + bounds_cy = 16 + statfile = statfile1 + end + object inprojectdir: tbooleaneditradio + frame.caption = 'Search in &project dir' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 130 + 2 + ) + taborder = 1 + bounds_x = 8 + bounds_y = 40 + bounds_cx = 143 + bounds_cy = 16 + statfile = statfile1 + ondataentered = sourcechangeexe + onsetvalue = dirsetval + value = True + end + end + object tlayouter2: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + taborder = 2 + bounds_x = 154 + bounds_y = 48 + bounds_cx = 155 + bounds_cy = 82 + optionsscale = [osc_expandx, osc_shrinkx] + object wholeword: tbooleanedit + frame.caption = '&Whole word' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 75 + 2 + ) + bounds_x = 8 + bounds_y = 16 + bounds_cx = 88 + bounds_cy = 16 + statfile = statfile1 + end + object inopenfiles: tbooleaneditradio + Tag = 1 + frame.caption = 'Search in &open files' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 127 + 2 + ) + taborder = 1 + bounds_x = 8 + bounds_y = 40 + bounds_cx = 140 + bounds_cy = 16 + statfile = statfile1 + ondataentered = sourcechangeexe + onsetvalue = opensetval + end + object incurrentfile: tbooleaneditradio + Tag = 1 + frame.caption = 'Search in ¤t file' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 134 + 2 + ) + taborder = 2 + bounds_x = 8 + bounds_y = 64 + bounds_cx = 147 + bounds_cy = 16 + statfile = statfile1 + ondataentered = sourcechangeexe + onsetvalue = currentsetval + end + end + object tlayouter4: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + taborder = 5 + bounds_x = 0 + bounds_y = 232 + bounds_cx = 339 + bounds_cy = 30 + anchors = [an_top] + optionsscale = [osc_expandy, osc_shrinky] + optionslayout = [lao_aligny] + align_glue = wam_start + object tlayouter3: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + frame.framei_top = 5 + frame.framei_bottom = 5 + frame.localprops = [frl_fitop, frl_fibottom] + frame.localprops1 = [] + bounds_x = 218 + bounds_y = 0 + bounds_cx = 119 + bounds_cy = 30 + anchors = [an_top, an_right] + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + optionslayout = [lao_placex, lao_aligny] + align_glue = wam_start + place_mindist = 5 + place_maxdist = 5 + place_mode = wam_end + place_options = [plo_propmargin, plo_syncmaxautosize] + object ok: tbutton + bounds_x = 5 + bounds_y = 5 + bounds_cx = 52 + bounds_cy = 20 + anchors = [an_top, an_right] + state = [as_default, as_localdefault, as_localcaption] + caption = 'OK' + modalresult = mr_ok + end + object cancel: tbutton + taborder = 1 + bounds_x = 62 + bounds_y = 5 + bounds_cx = 52 + bounds_cy = 20 + anchors = [an_top, an_right] + state = [as_localcaption] + caption = 'Cancel' + modalresult = mr_cancel + end + end + object subdirs: tbooleanedit + frame.caption = '&Include subdirectories' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 142 + 2 + ) + taborder = 1 + bounds_x = 8 + bounds_y = 8 + bounds_cx = 155 + bounds_cy = 16 + statfile = statfile1 + end + end + object statfile1: tstatfile + filename = 'findinfiledialogfo.sta' + options = [sfo_memory] + left = 248 + top = 72 + end +end diff --git a/mseide-msegui/apps/ide/findinfiledialogform.pas b/mseide-msegui/apps/ide/findinfiledialogform.pas new file mode 100644 index 0000000..3af960f --- /dev/null +++ b/mseide-msegui/apps/ide/findinfiledialogform.pas @@ -0,0 +1,244 @@ +{ MSEide Copyright (c) 1999-2016 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit findinfiledialogform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + finddialogform,findinfileform,mseforms,msedataedits,msesimplewidgets, + msegraphedits,msefiledialog,msetypes,mseglob,mseguiglob,msegui,msestat, + msestatfile,mseevent,msemenus,msesplitter,msegraphics,msegraphutils,msewidgets, + msestrings,mseificomp,mseificompglob,mseifiglob,msescrollbar; + +type + + tfindinfiledialogfo = class(tmseform) + findtext: thistoryedit; + statfile1: tstatfile; + dir: tfilenameedit; + mask: thistoryedit; + tlayouter1: tlayouter; + indirectories: tbooleaneditradio; + casesensitive: tbooleanedit; + tlayouter2: tlayouter; + wholeword: tbooleanedit; + inopenfiles: tbooleaneditradio; + tlayouter4: tlayouter; + tlayouter3: tlayouter; + ok: tbutton; + cancel: tbutton; + subdirs: tbooleanedit; + inprojectdir: tbooleaneditradio; + incurrentfile: tbooleaneditradio; + procedure dironbeforeexecute(const sender: tfiledialogcontroller; + var dialogkind: filedialogkindty; var aresult: modalresultty); + procedure dirshowhint(const sender: TObject; var info: hintinfoty); + procedure sourcechangeexe(const sender: TObject); +// procedure chainopenfiles(const sender: TObject); + procedure dirgetfilenameexe(const sender: TObject; var avalue: msestring; + var accept: Boolean); + procedure dirsetval(const sender: TObject; var avalue: Boolean; + var accept: Boolean); + procedure opensetval(const sender: TObject; var avalue: Boolean; + var accept: Boolean); + procedure dirsetvalue(const sender: TObject; var avalue: msestring; + var accept: Boolean); + procedure cereateev(const sender: TObject); + procedure currentsetval(const sender: TObject; var avalue: Boolean; + var accept: Boolean); + private + procedure valuestoinfo(out info: findinfileinfoty); + procedure infotovalues(const info: findinfileinfoty); + end; + +function findinfiledialogexecute(var info: findinfileinfoty; + const useinfo: boolean): boolean; + +implementation +uses + msebits,findinfiledialogform_mfm,projectoptionsform,main,msefileutils, + sourceform; + +function findinfiledialogexecute(var info: findinfileinfoty; + const useinfo: boolean): boolean; +var + fo: tfindinfiledialogfo; +begin + fo:= tfindinfiledialogfo.create(nil); + try + if useinfo then begin + fo.infotovalues(info); + end; + result:= fo.show(true,nil) = mr_ok; + if result then begin + fo.valuestoinfo(info); + end; + finally + fo.Free; + end; +end; + +{ tfindinfiledialogfo } + +procedure tfindinfiledialogfo.dironbeforeexecute( + const sender: tfiledialogcontroller; var dialogkind: filedialogkindty; + var aresult: modalresultty); +begin + sender.filterlist.asarrayb:= mask.dropdown.valuelist.asarray; + sender.filter:= mask.value; +end; + +procedure tfindinfiledialogfo.valuestoinfo(out info: findinfileinfoty); +begin +{$warnings off} + with info.findinfo do begin + text:= findtext.value; + history:= findtext.dropdown.valuelist.asarray; + options:= encodesearchoptions(not casesensitive.value,wholeword.value); + end; + with info do begin + directory:= dir.value; + filemask:= mask.value; + updatebit({$ifdef FPC}longword{$else}byte{$endif}(options),ord(fifo_subdirs),subdirs.value); + if inopenfiles.value then begin + source:= fs_inopenfiles; + end + else begin + if indirectories.value then begin + source:= fs_indirectories; + end + else begin + if incurrentfile.value then begin + source:= fs_incurrentfile; + end + else begin + source:= fs_inprojectdir; + end; + end; + end; + end; +end; +{$warnings on} +procedure tfindinfiledialogfo.infotovalues(const info: findinfileinfoty); +begin + with info.findinfo do begin + findtext.value:= text; + findtext.dropdown.valuelist.asarray:= history; + casesensitive.value:= not (so_caseinsensitive in options); + wholeword.value:= so_wholeword in options; + end; + with info do begin + dir.value:= directory; + mask.value:= filemask; + subdirs.value:= fifo_subdirs in options; + case source of + fs_inopenfiles: begin + inopenfiles.value:= true; + end; + fs_indirectories: begin + indirectories.value:= true; + end; + fs_inprojectdir: begin + inprojectdir.value:= true; + end; + fs_incurrentfile: begin + incurrentfile.value:= true; + end; + end; + end; +end; + +procedure tfindinfiledialogfo.dirshowhint(const sender: TObject; + var info: hintinfoty); +begin + hintmacros(tcustomstringedit(sender),info); + info.caption:= info.caption+lineend+'Empty -> project directory'; +end; + +procedure tfindinfiledialogfo.dirgetfilenameexe(const sender: TObject; + var avalue: msestring; var accept: Boolean); +begin + expandprmacros1(avalue); +end; + +procedure tfindinfiledialogfo.sourcechangeexe(const sender: TObject); +begin + if indirectories.value then begin +// inopenfiles.value:= false; + dir.enabled:= true; + mask.enabled:= true; + subdirs.enabled:= true; + end + else begin + if inopenfiles.value or incurrentfile.value then begin + dir.enabled:= false; + mask.enabled:= false; + subdirs.enabled:= false; + end + else begin // + dir.enabled:= false; + mask.enabled:= true; + subdirs.enabled:= true; + end; + end; +end; + +procedure tfindinfiledialogfo.dirsetval(const sender: TObject; + var avalue: Boolean; var accept: Boolean); +begin + if avalue then begin + inopenfiles.value:= false; + incurrentfile.value:= false; + end; +end; + +procedure tfindinfiledialogfo.opensetval(const sender: TObject; + var avalue: Boolean; var accept: Boolean); +begin + if avalue then begin + inprojectdir.value:= false; + indirectories.value:= false; + end; +end; + +procedure tfindinfiledialogfo.currentsetval(const sender: TObject; + var avalue: Boolean; var accept: Boolean); +begin + if avalue then begin + inprojectdir.value:= false; + indirectories.value:= false; + end; +end; + + +procedure tfindinfiledialogfo.dirsetvalue(const sender: TObject; + var avalue: msestring; var accept: Boolean); +begin + if avalue = '' then begin + avalue:= filedir(mainfo.projectname); + end; +end; + +procedure tfindinfiledialogfo.cereateev(const sender: TObject); +begin + if sourcefo.activepage = nil then begin + incurrentfile.enabled:= false; + end; +end; + +end. diff --git a/mseide-msegui/apps/ide/findinfiledialogform_mfm.pas b/mseide-msegui/apps/ide/findinfiledialogform_mfm.pas new file mode 100644 index 0000000..fdd9fb4 --- /dev/null +++ b/mseide-msegui/apps/ide/findinfiledialogform_mfm.pas @@ -0,0 +1,286 @@ +unit findinfiledialogform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,findinfiledialogform; + +const + objdata: record size: integer; data: array[0..5371] of byte end = + (size: 5372; data: ( + 84,80,70,48,19,116,102,105,110,100,105,110,102,105,108,101,100,105,97,108, + 111,103,102,111,19,102,105,110,100,105,110,102,105,108,101,97,100,105,97,108, + 111,103,102,111,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,11, + 111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119, + 102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105, + 110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,11,111, + 119,95,115,117,98,102,111,99,117,115,17,111,119,95,100,101,115,116,114,111, + 121,119,105,100,103,101,116,115,9,111,119,95,104,105,110,116,111,110,0,7, + 118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,12,1, + 8,98,111,117,110,100,115,95,121,3,159,1,9,98,111,117,110,100,115,95, + 99,120,3,83,1,9,98,111,117,110,100,115,95,99,121,3,19,1,23,99, + 111,110,116,97,105,110,101,114,46,111,112,116,105,111,110,115,119,105,100,103, + 101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119, + 95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111, + 99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16, + 111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95, + 115,117,98,102,111,99,117,115,19,111,119,95,109,111,117,115,101,116,114,97, + 110,115,112,97,114,101,110,116,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,0,26,99,111,110,116,97,105,110,101,114,46,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,27,99,111,110, + 116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,16,99,111,110,116,97,105,110,101,114,46,98,111,117, + 110,100,115,1,2,0,2,0,3,83,1,3,19,1,0,7,111,112,116,105, + 111,110,115,11,13,102,111,95,99,108,111,115,101,111,110,101,115,99,17,102, + 111,95,108,111,99,97,108,115,104,111,114,116,99,117,116,115,15,102,111,95, + 97,117,116,111,114,101,97,100,115,116,97,116,16,102,111,95,97,117,116,111, + 119,114,105,116,101,115,116,97,116,10,102,111,95,115,97,118,101,112,111,115, + 13,102,111,95,115,97,118,101,122,111,114,100,101,114,0,8,115,116,97,116, + 102,105,108,101,7,9,115,116,97,116,102,105,108,101,49,7,99,97,112,116, + 105,111,110,6,18,70,105,110,100,32,84,101,120,116,32,105,110,32,70,105, + 108,101,115,8,111,110,99,114,101,97,116,101,7,9,99,101,114,101,97,116, + 101,101,118,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6, + 8,116,109,115,101,102,111,114,109,0,12,116,104,105,115,116,111,114,121,101, + 100,105,116,8,102,105,110,100,116,101,120,116,13,102,114,97,109,101,46,99, + 97,112,116,105,111,110,6,13,38,84,101,120,116,32,116,111,32,102,105,110, + 100,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111,114,4, + 2,0,0,128,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109, + 101,1,2,0,2,17,2,0,2,0,0,8,98,111,117,110,100,115,95,120, + 2,8,8,98,111,117,110,100,115,95,121,2,9,9,98,111,117,110,100,115, + 95,99,120,3,65,1,9,98,111,117,110,100,115,95,99,121,2,37,7,97, + 110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110,95,116, + 111,112,8,97,110,95,114,105,103,104,116,0,8,115,116,97,116,102,105,108, + 101,7,9,115,116,97,116,102,105,108,101,49,19,100,114,111,112,100,111,119, + 110,46,99,111,108,115,46,99,111,117,110,116,2,1,19,100,114,111,112,100, + 111,119,110,46,99,111,108,115,46,105,116,101,109,115,14,1,0,0,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,13,116,102,105, + 108,101,110,97,109,101,101,100,105,116,3,100,105,114,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,10,38,68,105,114,101,99,116,111,114,121, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,19, + 102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2, + 1,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109, + 115,14,1,5,99,111,108,111,114,4,2,0,0,128,7,105,109,97,103,101, + 110,114,2,17,0,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46, + 99,111,108,111,114,4,2,0,0,128,20,102,114,97,109,101,46,98,117,116, + 116,111,110,46,105,109,97,103,101,110,114,2,17,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0, + 8,116,97,98,111,114,100,101,114,2,3,10,111,110,115,104,111,119,104,105, + 110,116,7,11,100,105,114,115,104,111,119,104,105,110,116,8,98,111,117,110, + 100,115,95,120,2,8,8,98,111,117,110,100,115,95,121,3,137,0,9,98, + 111,117,110,100,115,95,99,120,3,65,1,9,98,111,117,110,100,115,95,99, + 121,2,37,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116, + 6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,8,115,116, + 97,116,102,105,108,101,7,9,115,116,97,116,102,105,108,101,49,9,116,101, + 120,116,102,108,97,103,115,11,12,116,102,95,121,99,101,110,116,101,114,101, + 100,11,116,102,95,110,111,115,101,108,101,99,116,14,116,102,95,101,108,108, + 105,112,115,101,108,101,102,116,0,10,111,110,115,101,116,118,97,108,117,101, + 7,11,100,105,114,115,101,116,118,97,108,117,101,18,99,111,110,116,114,111, + 108,108,101,114,46,111,112,116,105,111,110,115,11,13,102,100,111,95,100,105, + 114,101,99,116,111,114,121,0,24,99,111,110,116,114,111,108,108,101,114,46, + 111,110,103,101,116,102,105,108,101,110,97,109,101,7,17,100,105,114,103,101, + 116,102,105,108,101,110,97,109,101,101,120,101,26,99,111,110,116,114,111,108, + 108,101,114,46,111,110,98,101,102,111,114,101,101,120,101,99,117,116,101,7, + 18,100,105,114,111,110,98,101,102,111,114,101,101,120,101,99,117,116,101,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,12,116,104, + 105,115,116,111,114,121,101,100,105,116,4,109,97,115,107,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,10,38,70,105,108,101,32,77,97,115, + 107,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111,114,4, + 2,0,0,128,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109, + 101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114, + 2,4,8,98,111,117,110,100,115,95,120,2,8,8,98,111,117,110,100,115, + 95,121,3,185,0,9,98,111,117,110,100,115,95,99,120,3,65,1,9,98, + 111,117,110,100,115,95,99,121,2,37,7,97,110,99,104,111,114,115,11,7, + 97,110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105, + 103,104,116,0,8,115,116,97,116,102,105,108,101,7,9,115,116,97,116,102, + 105,108,101,49,5,118,97,108,117,101,6,22,34,42,46,112,97,115,34,32, + 34,42,46,112,112,34,32,34,42,46,105,110,99,34,19,100,114,111,112,100, + 111,119,110,46,99,111,108,115,46,99,111,117,110,116,2,1,19,100,114,111, + 112,100,111,119,110,46,99,111,108,115,46,105,116,101,109,115,14,1,0,0, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,9,116, + 108,97,121,111,117,116,101,114,10,116,108,97,121,111,117,116,101,114,49,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,11,111,119,95,116,97, + 98,102,111,99,117,115,17,111,119,95,112,97,114,101,110,116,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111, + 99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116, + 115,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115, + 95,120,2,0,8,98,111,117,110,100,115,95,121,2,48,9,98,111,117,110, + 100,115,95,99,120,3,154,0,9,98,111,117,110,100,115,95,99,121,2,80, + 12,111,112,116,105,111,110,115,115,99,97,108,101,11,11,111,115,99,95,101, + 120,112,97,110,100,120,11,111,115,99,95,115,104,114,105,110,107,120,11,111, + 115,99,95,101,120,112,97,110,100,121,11,111,115,99,95,115,104,114,105,110, + 107,121,0,9,108,105,110,107,114,105,103,104,116,7,10,116,108,97,121,111, + 117,116,101,114,50,0,17,116,98,111,111,108,101,97,110,101,100,105,116,114, + 97,100,105,111,13,105,110,100,105,114,101,99,116,111,114,105,101,115,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,22,83,101,97,114,99,104, + 32,105,110,32,38,100,105,114,101,99,116,111,114,105,101,115,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109, + 101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,3,133,0, + 2,2,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100, + 115,95,120,2,8,8,98,111,117,110,100,115,95,121,2,64,9,98,111,117, + 110,100,115,95,99,120,3,146,0,9,98,111,117,110,100,115,95,99,121,2, + 16,8,115,116,97,116,102,105,108,101,7,9,115,116,97,116,102,105,108,101, + 49,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,15,115,111,117, + 114,99,101,99,104,97,110,103,101,101,120,101,10,111,110,115,101,116,118,97, + 108,117,101,7,9,100,105,114,115,101,116,118,97,108,0,0,12,116,98,111, + 111,108,101,97,110,101,100,105,116,13,99,97,115,101,115,101,110,115,105,116, + 105,118,101,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,14,67, + 38,97,115,101,115,101,110,115,105,116,105,118,101,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,1,2,89,2,2,0,8, + 98,111,117,110,100,115,95,120,2,8,8,98,111,117,110,100,115,95,121,2, + 16,9,98,111,117,110,100,115,95,99,120,2,102,9,98,111,117,110,100,115, + 95,99,121,2,16,8,115,116,97,116,102,105,108,101,7,9,115,116,97,116, + 102,105,108,101,49,0,0,17,116,98,111,111,108,101,97,110,101,100,105,116, + 114,97,100,105,111,12,105,110,112,114,111,106,101,99,116,100,105,114,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,22,83,101,97,114,99,104, + 32,105,110,32,38,112,114,111,106,101,99,116,32,100,105,114,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109, + 101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,3,130,0, + 2,2,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100, + 115,95,120,2,8,8,98,111,117,110,100,115,95,121,2,40,9,98,111,117, + 110,100,115,95,99,120,3,143,0,9,98,111,117,110,100,115,95,99,121,2, + 16,8,115,116,97,116,102,105,108,101,7,9,115,116,97,116,102,105,108,101, + 49,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,15,115,111,117, + 114,99,101,99,104,97,110,103,101,101,120,101,10,111,110,115,101,116,118,97, + 108,117,101,7,9,100,105,114,115,101,116,118,97,108,5,118,97,108,117,101, + 9,0,0,0,9,116,108,97,121,111,117,116,101,114,10,116,108,97,121,111, + 117,116,101,114,50,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 11,111,119,95,116,97,98,102,111,99,117,115,17,111,119,95,112,97,114,101, + 110,116,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102, + 111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110, + 16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119, + 95,115,117,98,102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121, + 119,105,100,103,101,116,115,0,8,116,97,98,111,114,100,101,114,2,2,8, + 98,111,117,110,100,115,95,120,3,154,0,8,98,111,117,110,100,115,95,121, + 2,48,9,98,111,117,110,100,115,95,99,120,3,155,0,9,98,111,117,110, + 100,115,95,99,121,2,82,12,111,112,116,105,111,110,115,115,99,97,108,101, + 11,11,111,115,99,95,101,120,112,97,110,100,120,11,111,115,99,95,115,104, + 114,105,110,107,120,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116, + 9,119,104,111,108,101,119,111,114,100,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,11,38,87,104,111,108,101,32,119,111,114,100,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,2,75, + 2,2,0,8,98,111,117,110,100,115,95,120,2,8,8,98,111,117,110,100, + 115,95,121,2,16,9,98,111,117,110,100,115,95,99,120,2,88,9,98,111, + 117,110,100,115,95,99,121,2,16,8,115,116,97,116,102,105,108,101,7,9, + 115,116,97,116,102,105,108,101,49,0,0,17,116,98,111,111,108,101,97,110, + 101,100,105,116,114,97,100,105,111,11,105,110,111,112,101,110,102,105,108,101, + 115,3,84,97,103,2,1,13,102,114,97,109,101,46,99,97,112,116,105,111, + 110,6,21,83,101,97,114,99,104,32,105,110,32,38,111,112,101,110,32,102, + 105,108,101,115,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101, + 1,2,0,2,1,2,127,2,2,0,8,116,97,98,111,114,100,101,114,2, + 1,8,98,111,117,110,100,115,95,120,2,8,8,98,111,117,110,100,115,95, + 121,2,40,9,98,111,117,110,100,115,95,99,120,3,140,0,9,98,111,117, + 110,100,115,95,99,121,2,16,8,115,116,97,116,102,105,108,101,7,9,115, + 116,97,116,102,105,108,101,49,13,111,110,100,97,116,97,101,110,116,101,114, + 101,100,7,15,115,111,117,114,99,101,99,104,97,110,103,101,101,120,101,10, + 111,110,115,101,116,118,97,108,117,101,7,10,111,112,101,110,115,101,116,118, + 97,108,0,0,17,116,98,111,111,108,101,97,110,101,100,105,116,114,97,100, + 105,111,13,105,110,99,117,114,114,101,110,116,102,105,108,101,3,84,97,103, + 2,1,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,23,83,101, + 97,114,99,104,32,105,110,32,38,99,117,114,114,101,110,116,32,102,105,108, + 101,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,1,3,134,0,2,2,0,8,116,97,98,111,114,100,101,114,2,2,8, + 98,111,117,110,100,115,95,120,2,8,8,98,111,117,110,100,115,95,121,2, + 64,9,98,111,117,110,100,115,95,99,120,3,147,0,9,98,111,117,110,100, + 115,95,99,121,2,16,8,115,116,97,116,102,105,108,101,7,9,115,116,97, + 116,102,105,108,101,49,13,111,110,100,97,116,97,101,110,116,101,114,101,100, + 7,15,115,111,117,114,99,101,99,104,97,110,103,101,101,120,101,10,111,110, + 115,101,116,118,97,108,117,101,7,13,99,117,114,114,101,110,116,115,101,116, + 118,97,108,0,0,0,9,116,108,97,121,111,117,116,101,114,10,116,108,97, + 121,111,117,116,101,114,52,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,11,111,119,95,116,97,98,102,111,99,117,115,17,111,119,95,112,97, + 114,101,110,116,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115, + 105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,11, + 111,119,95,115,117,98,102,111,99,117,115,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,8,116,97,98,111,114,100,101,114,2, + 5,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95, + 121,3,232,0,9,98,111,117,110,100,115,95,99,120,3,83,1,9,98,111, + 117,110,100,115,95,99,121,2,30,7,97,110,99,104,111,114,115,11,6,97, + 110,95,116,111,112,0,12,111,112,116,105,111,110,115,115,99,97,108,101,11, + 11,111,115,99,95,101,120,112,97,110,100,121,11,111,115,99,95,115,104,114, + 105,110,107,121,0,13,111,112,116,105,111,110,115,108,97,121,111,117,116,11, + 10,108,97,111,95,97,108,105,103,110,121,0,10,97,108,105,103,110,95,103, + 108,117,101,7,9,119,97,109,95,115,116,97,114,116,0,9,116,108,97,121, + 111,117,116,101,114,10,116,108,97,121,111,117,116,101,114,51,13,111,112,116, + 105,111,110,115,119,105,100,103,101,116,11,11,111,119,95,116,97,98,102,111, + 99,117,115,17,111,119,95,112,97,114,101,110,116,116,97,98,102,111,99,117, + 115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97, + 114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119, + 102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111,99,117,115, + 17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,16, + 102,114,97,109,101,46,102,114,97,109,101,105,95,116,111,112,2,5,19,102, + 114,97,109,101,46,102,114,97,109,101,105,95,98,111,116,116,111,109,2,5, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,9,102, + 114,108,95,102,105,116,111,112,12,102,114,108,95,102,105,98,111,116,116,111, + 109,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,8,98,111,117,110,100,115,95,120,3,218,0,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,119,9,98,111, + 117,110,100,115,95,99,121,2,30,7,97,110,99,104,111,114,115,11,6,97, + 110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,12,111,112,116,105, + 111,110,115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97,110,100, + 120,11,111,115,99,95,115,104,114,105,110,107,120,11,111,115,99,95,101,120, + 112,97,110,100,121,11,111,115,99,95,115,104,114,105,110,107,121,0,13,111, + 112,116,105,111,110,115,108,97,121,111,117,116,11,10,108,97,111,95,112,108, + 97,99,101,120,10,108,97,111,95,97,108,105,103,110,121,0,10,97,108,105, + 103,110,95,103,108,117,101,7,9,119,97,109,95,115,116,97,114,116,13,112, + 108,97,99,101,95,109,105,110,100,105,115,116,2,5,13,112,108,97,99,101, + 95,109,97,120,100,105,115,116,2,5,10,112,108,97,99,101,95,109,111,100, + 101,7,7,119,97,109,95,101,110,100,13,112,108,97,99,101,95,111,112,116, + 105,111,110,115,11,14,112,108,111,95,112,114,111,112,109,97,114,103,105,110, + 19,112,108,111,95,115,121,110,99,109,97,120,97,117,116,111,115,105,122,101, + 0,0,7,116,98,117,116,116,111,110,2,111,107,8,98,111,117,110,100,115, + 95,120,2,5,8,98,111,117,110,100,115,95,121,2,5,9,98,111,117,110, + 100,115,95,99,120,2,52,9,98,111,117,110,100,115,95,99,121,2,20,7, + 97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,8,97,110,95,114, + 105,103,104,116,0,5,115,116,97,116,101,11,10,97,115,95,100,101,102,97, + 117,108,116,15,97,115,95,108,111,99,97,108,100,101,102,97,117,108,116,15, + 97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,7,99,97,112, + 116,105,111,110,6,2,79,75,11,109,111,100,97,108,114,101,115,117,108,116, + 7,5,109,114,95,111,107,0,0,7,116,98,117,116,116,111,110,6,99,97, + 110,99,101,108,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110, + 100,115,95,120,2,62,8,98,111,117,110,100,115,95,121,2,5,9,98,111, + 117,110,100,115,95,99,120,2,52,9,98,111,117,110,100,115,95,99,121,2, + 20,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,8,97,110, + 95,114,105,103,104,116,0,5,115,116,97,116,101,11,15,97,115,95,108,111, + 99,97,108,99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6, + 6,67,97,110,99,101,108,11,109,111,100,97,108,114,101,115,117,108,116,7, + 9,109,114,95,99,97,110,99,101,108,0,0,0,12,116,98,111,111,108,101, + 97,110,101,100,105,116,7,115,117,98,100,105,114,115,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,23,38,73,110,99,108,117,100,101,32,115, + 117,98,100,105,114,101,99,116,111,114,105,101,115,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,1,3,142,0,2,2,0, + 8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120, + 2,8,8,98,111,117,110,100,115,95,121,2,8,9,98,111,117,110,100,115, + 95,99,120,3,155,0,9,98,111,117,110,100,115,95,99,121,2,16,8,115, + 116,97,116,102,105,108,101,7,9,115,116,97,116,102,105,108,101,49,0,0, + 0,9,116,115,116,97,116,102,105,108,101,9,115,116,97,116,102,105,108,101, + 49,8,102,105,108,101,110,97,109,101,6,22,102,105,110,100,105,110,102,105, + 108,101,100,105,97,108,111,103,102,111,46,115,116,97,7,111,112,116,105,111, + 110,115,11,10,115,102,111,95,109,101,109,111,114,121,0,4,108,101,102,116, + 3,248,0,3,116,111,112,2,72,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tfindinfiledialogfo,''); +end. diff --git a/mseide-msegui/apps/ide/findinfileform.mfm b/mseide-msegui/apps/ide/findinfileform.mfm new file mode 100644 index 0000000..9255ee0 --- /dev/null +++ b/mseide-msegui/apps/ide/findinfileform.mfm @@ -0,0 +1,111 @@ +object findinfilefo: tfindinfilefo + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_topbutton, go_nolockbutton] + visible = False + bounds_x = 548 + bounds_y = 115 + bounds_cx = 369 + bounds_cy = 198 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 359 + 198 + ) + dragdock.splitter_size = 0 + dragdock.caption = 'Findresults' + dragdock.optionsdock = [od_savepos, od_savezorder, od_canmove, od_canfloat, od_candock, od_propsize, od_captionhint] + options = [fo_savepos, fo_savezorder] + statfile = mainfo.projectstatfile + caption = 'Find in file results' + icon.transparentcolor = -2147483642 + icon.image = { + 0000000000000000180000001800000078080000000000000000000000000000 + 0000000000000000000000000000000000000000F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E0E0E001D3D3D301 + DDDDDD01E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01D9D9D901B4B4B401A3A3A30199999903A2A2A201 + AFAFAF01CCCCCC01DBDBDB02DADADA01D8D8D801D7D7D701D5D5D501D3D3D301 + D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001EBEBEB01BFBFBF01 + 9A9A9A01A2A0A001BBB4B401D0C7C801E1D2D401D1C4C501BCB3B401A29F9F01 + 9A9A9A01A9A9A901D2D2D201D9D9D901D8D8D801D7D7D701D5D5D501D3D3D301 + D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201EAEAEA01A7A7A70199999901 + C1B7B701F6E2E401FDEBED01FFEBED01FFE8EB01FFE6E901FFE3E601FBDEE101 + C4B6B80199999902C6C6C601D5D5D501D7D7D701D5D5D501D3D3D301D2D2D201 + D0D0D001F5F5F501F3F3F301F2F2F201B9B9B9019A9A9A01DBCACB01FAE4E601 + FDE9EB01FFEBEE01FFE9EB01FFE6E901FFE4E701FFE1E501FFDFE201FFDCE001 + E1C6CA01999999018D8D8D01B6B6B601D4D4D401D5D5D501D3D3D301D2D2D201 + D0D0D001F5F5F501F3F3F301D7D7D70199999901C6BABB01F9E3E401FCE8EA01 + FFECEE01CFBEC00174696A012F2A2B0149414201BEA6A901FFDDE101FFDADE01 + FFD8DC01CAB6B8019999990181818101C6C6C601D4D4D401D3D3D301D2D2D201 + D0D0D001F5F5F501F3F3F301A7A6A601A9A5A601F6E1E201FBE7E801FEECEE01 + F1DDDF010F0E0E017A6E6F01CFB7BB017C6D6E010A090901EECCD001FFD8DD01 + FFD6DA01FDD3D801AAA3A4019392920191919101CDCDCD01D3D3D301D2D2D201 + D0D0D001F5F5F501EDEDED0199999901CBBFC001FAE6E701FDEBED01FFEBED01 + 928587012E292A01FFE3E601FFE1E401FFDEE201372F30018C777901FFD6DB01 + FFD4D902CFB8BB01999999016D6D6D01B4B4B401D1D1D101D2D2D201D0D0D001 + F5F5F501DADADA0199999901DFCFD101FDE9EB01FFEBEE01FFE9EB01FFE6E901 + FBE0E301FFE1E501FFDFE201F9D7DB012A242501957E8101FFD4D903E3C4C701 + 99999901737373019A9A9A01CFCFCF01D2D2D201D0D0D001F5F5F501CACACA01 + 99999901F3E1E301FFECEE01FFE9EC01FFE7EA01FFE4E701FFE2E501FFDFE301 + FAD9DD0152464701382F3001F6CDD201FFD4D903F6CFD301999999017D7D7D01 + 84848401CDCDCD01D2D2D201D0D0D001F5F5F501D1D1D10199999901ECDDDF01 + FFEAEC01FFE8EA01FFE5E801FFE2E601FFE0E301FFDDE101655758012F282901 + EBC5C901FFD4D904EDCACE01999999017777770170707001CCCCCC01D2D2D201 + D0D0D001F5F5F501E3E3E30199999901D9CCCE01FFE8EB01FFE6E801FFE3E601 + FFE0E401FFDEE201F9D6DA0103030301D0AFB301FFD4D905D9BEC10199999901 + 6B6B6B0170707001CCCCCC01D2D2D201D0D0D001F5F5F501F2F2F2019C9C9C01 + C3BABB01FFE6E901FFE4E701FFE1E401FFDFE201FFDCE001EECBCF0167575801 + F7CDD201FFD4D905C3B1B401989898016565650183838301CCCCCC01D2D2D201 + D0D0D001F5F5F501F3F3F301B7B7B7019B9A9A01ECD6D801FFE2E501FFDFE301 + FFDDE101FFDADE01EFCACE01A78B8F01F2C9CE01FFD4D904ECC9CD019A999901 + 858585016565650198989801CFCFCF01D2D2D201D0D0D001F5F5F501F3F3F301 + E8E8E8019E9E9E01ABA6A701FDDFE201FFDDE101FFDBDF01FFD8DD01D0AEB201 + 00000001D7B3B701FFD4D903FDD3D801ABA3A4019697980158809301696B6C01 + B2B2B201D1D1D101D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201CECECE01 + 99999901B2AAAB01F3D3D701FFD9DD01FFD6DB01FFD4D905F3CDD201B2A7A901 + 999999018CADBE0166A4C3015488A201B7B9BA01D3D3D301D2D2D201D0D0D001 + F5F5F501F3F3F301F2F2F201EFEFEF01C0C0C001999898019D9B9B01D3BCBF01 + F1CCD001FFD4D903F1CCD001D3BBBD019D9B9B019898990196B0BD01A7CADD01 + 86B7D00167A4C3015489A301BEC0C101D2D2D201D0D0D001F5F5F501F3F3F301 + F2F2F201F0F0F001EAEAEA01BFBFBF0193929201999999029D9B9C01ACA3A401 + 9D9B9C01999999028C8B8B01618BA00174ACC90194BFD501A7CADD0187B7D001 + 67A4C301578BA501B9BBBC01D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001 + EEEEEE01E9E9E901D5D5D5019797970181818101878787018E8E8E0185858501 + 7B7B7B01727272016A6A6A01696F72015A93B00174ACC80194BFD501A7CADD01 + 87B7D00167A4C3015489A301B7B9BA01F5F5F501F3F3F301F2F2F201F0F0F001 + EEEEEE01EDEDED01EAEAEA01E2E2E201C0C0C001A2A2A2018989890175757501 + 74747401868686019D9D9D01B7B7B701C0C6C9015D96B30174ACC80194BFD501 + A7CADD0187B7D00167A4C3015F879B01F5F5F501F3F3F301F2F2F201F0F0F001 + EEEEEE01EDEDED01EBEBEB01EAEAEA01E5E5E501E1E1E101DEDEDE01DADADA01 + D9D9D902DBDBDB01DADADA01DBDBDB01C7CDD0015E97B40174ACC80194BFD501 + A7CBDD0186B6CD0162737C01F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01 + EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501E3E3E301E2E2E201 + E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01C5CBCE015E97B30174ACC801 + 93BDD201758086015E5E5E01F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01 + EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501E3E3E301E2E2E201 + E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801C4CACD016995AB01 + 6C7C85015F5F5F017D7D7D01 + } + moduleclassname = 'tdockform' + object tabs: ttabwidget + bounds_x = 0 + bounds_y = 0 + bounds_cx = 359 + bounds_cy = 198 + anchors = [] + tab_options = [tabo_dragsource, tabo_dragdest, tabo_opposite, tabo_dblclickedtabfirst, tabo_hintclippedtext] + tab_frame.buttonslast = True + tab_frame.localprops = [] + tab_frame.localprops1 = [] + tab_size = 18 + end +end diff --git a/mseide-msegui/apps/ide/findinfileform.pas b/mseide-msegui/apps/ide/findinfileform.pas new file mode 100644 index 0000000..a9600e6 --- /dev/null +++ b/mseide-msegui/apps/ide/findinfileform.pas @@ -0,0 +1,77 @@ +{ MSEide Copyright (c) 1999-2014 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit findinfileform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + finddialogform,mseforms,msegrids,msethreadcomp,msesimplewidgets, + msesysutils,msedispwidgets,msetypes,msestrings,msewidgetgrid,msetextedit, + msestat,msetabs,projectoptionsform; + +type + + filesourcety = (fs_indirectories,fs_inopenfiles,fs_inprojectdir, + fs_incurrentfile); + findinfileoptionty = (fifo_subdirs); + findinfileoptionsty = set of findinfileoptionty; + + findinfileinfoty = record + findinfo: findinfoty; + options: findinfileoptionsty; + directory: filenamety; + filemask: msestring; + resultlist: ttextedit; + source: filesourcety; + end; + + tfindinfilefo = class(tdockform) + tabs: ttabwidget; + private + public + procedure newsearch(const info: findinfileinfoty); + end; + +procedure dofindinfile; + +var + findinfilefo: tfindinfilefo; + findinfileinfo: findinfileinfoty; + +implementation +uses + findinfiledialogform,main,findinfileform_mfm,msefileutils,msestream, + msesys,msegui,sysutils,mserichstring,msegraphics,sourceform,sourcepage, + findinfilepage,mseeditglob; + +procedure dofindinfile; +begin + if findinfiledialogexecute(findinfileinfo,false) then begin + findinfilefo.newsearch(findinfileinfo); + findinfilefo.activate; + end; +end; + +{ tfindinfilefo } + +procedure tfindinfilefo.newsearch(const info: findinfileinfoty); +begin + tabs.add(itabpage(tfindinfilepagefo.create(self,info))); +end; + +end. diff --git a/mseide-msegui/apps/ide/findinfileform_mfm.pas b/mseide-msegui/apps/ide/findinfileform_mfm.pas new file mode 100644 index 0000000..058f214 --- /dev/null +++ b/mseide-msegui/apps/ide/findinfileform_mfm.pas @@ -0,0 +1,174 @@ +unit findinfileform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,findinfileform; + +const + objdata: record size: integer; data: array[0..3129] of byte end = + (size: 3130; data: ( + 84,80,70,48,13,116,102,105,110,100,105,110,102,105,108,101,102,111,12,102, + 105,110,100,105,110,102,105,108,101,102,111,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,15,102,114,97,109,101,46,103,114,105, + 112,95,115,105,122,101,2,10,18,102,114,97,109,101,46,103,114,105,112,95, + 111,112,116,105,111,110,115,11,14,103,111,95,99,108,111,115,101,98,117,116, + 116,111,110,16,103,111,95,102,105,120,115,105,122,101,98,117,116,116,111,110, + 12,103,111,95,116,111,112,98,117,116,116,111,110,15,103,111,95,110,111,108, + 111,99,107,98,117,116,116,111,110,0,7,118,105,115,105,98,108,101,8,8, + 98,111,117,110,100,115,95,120,3,36,2,8,98,111,117,110,100,115,95,121, + 2,115,9,98,111,117,110,100,115,95,99,120,3,113,1,9,98,111,117,110, + 100,115,95,99,121,3,198,0,26,99,111,110,116,97,105,110,101,114,46,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,27,99,111, + 110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,99,111,110,116,97,105,110,101,114,46,98,111, + 117,110,100,115,1,2,0,2,0,3,103,1,3,198,0,0,22,100,114,97, + 103,100,111,99,107,46,115,112,108,105,116,116,101,114,95,115,105,122,101,2, + 0,16,100,114,97,103,100,111,99,107,46,99,97,112,116,105,111,110,6,11, + 70,105,110,100,114,101,115,117,108,116,115,20,100,114,97,103,100,111,99,107, + 46,111,112,116,105,111,110,115,100,111,99,107,11,10,111,100,95,115,97,118, + 101,112,111,115,13,111,100,95,115,97,118,101,122,111,114,100,101,114,10,111, + 100,95,99,97,110,109,111,118,101,11,111,100,95,99,97,110,102,108,111,97, + 116,10,111,100,95,99,97,110,100,111,99,107,11,111,100,95,112,114,111,112, + 115,105,122,101,14,111,100,95,99,97,112,116,105,111,110,104,105,110,116,0, + 7,111,112,116,105,111,110,115,11,10,102,111,95,115,97,118,101,112,111,115, + 13,102,111,95,115,97,118,101,122,111,114,100,101,114,0,8,115,116,97,116, + 102,105,108,101,7,22,109,97,105,110,102,111,46,112,114,111,106,101,99,116, + 115,116,97,116,102,105,108,101,7,99,97,112,116,105,111,110,6,20,70,105, + 110,100,32,105,110,32,102,105,108,101,32,114,101,115,117,108,116,115,21,105, + 99,111,110,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,10,105,99,111,110,46,105,109,97,103,101,10,172,8,0, + 0,0,0,0,0,0,0,0,0,24,0,0,0,24,0,0,0,120,8,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,245,245,245,1,243,243,243, + 1,242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1,235,235,235, + 1,234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1,227,227,227, + 1,226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219,219, + 1,218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211,211, + 1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242, + 1,240,240,240,1,238,238,238,1,237,237,237,1,235,235,235,1,234,234,234, + 1,232,232,232,1,224,224,224,1,211,211,211,1,221,221,221,1,226,226,226, + 1,224,224,224,1,223,223,223,1,221,221,221,1,219,219,219,1,218,218,218, + 1,216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1,210,210,210, + 1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240,240, + 1,238,238,238,1,237,237,237,1,217,217,217,1,180,180,180,1,163,163,163, + 1,153,153,153,3,162,162,162,1,175,175,175,1,204,204,204,1,219,219,219, + 2,218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211,211, + 1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242, + 1,240,240,240,1,235,235,235,1,191,191,191,1,154,154,154,1,162,160,160, + 1,187,180,180,1,208,199,200,1,225,210,212,1,209,196,197,1,188,179,180, + 1,162,159,159,1,154,154,154,1,169,169,169,1,210,210,210,1,217,217,217, + 1,216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1,210,210,210, + 1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,234,234,234, + 1,167,167,167,1,153,153,153,1,193,183,183,1,246,226,228,1,253,235,237, + 1,255,235,237,1,255,232,235,1,255,230,233,1,255,227,230,1,251,222,225, + 1,196,182,184,1,153,153,153,2,198,198,198,1,213,213,213,1,215,215,215, + 1,213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245,245, + 1,243,243,243,1,242,242,242,1,185,185,185,1,154,154,154,1,219,202,203, + 1,250,228,230,1,253,233,235,1,255,235,238,1,255,233,235,1,255,230,233, + 1,255,228,231,1,255,225,229,1,255,223,226,1,255,220,224,1,225,198,202, + 1,153,153,153,1,141,141,141,1,182,182,182,1,212,212,212,1,213,213,213, + 1,211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243, + 1,215,215,215,1,153,153,153,1,198,186,187,1,249,227,228,1,252,232,234, + 1,255,236,238,1,207,190,192,1,116,105,106,1,47,42,43,1,73,65,66, + 1,190,166,169,1,255,221,225,1,255,218,222,1,255,216,220,1,202,182,184, + 1,153,153,153,1,129,129,129,1,198,198,198,1,212,212,212,1,211,211,211, + 1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,167,166,166, + 1,169,165,166,1,246,225,226,1,251,231,232,1,254,236,238,1,241,221,223, + 1,15,14,14,1,122,110,111,1,207,183,187,1,124,109,110,1,10,9,9, + 1,238,204,208,1,255,216,221,1,255,214,218,1,253,211,216,1,170,163,164, + 1,147,146,146,1,145,145,145,1,205,205,205,1,211,211,211,1,210,210,210, + 1,208,208,208,1,245,245,245,1,237,237,237,1,153,153,153,1,203,191,192, + 1,250,230,231,1,253,235,237,1,255,235,237,1,146,133,135,1,46,41,42, + 1,255,227,230,1,255,225,228,1,255,222,226,1,55,47,48,1,140,119,121, + 1,255,214,219,1,255,212,217,2,207,184,187,1,153,153,153,1,109,109,109, + 1,180,180,180,1,209,209,209,1,210,210,210,1,208,208,208,1,245,245,245, + 1,218,218,218,1,153,153,153,1,223,207,209,1,253,233,235,1,255,235,238, + 1,255,233,235,1,255,230,233,1,251,224,227,1,255,225,229,1,255,223,226, + 1,249,215,219,1,42,36,37,1,149,126,129,1,255,212,217,3,227,196,199, + 1,153,153,153,1,115,115,115,1,154,154,154,1,207,207,207,1,210,210,210, + 1,208,208,208,1,245,245,245,1,202,202,202,1,153,153,153,1,243,225,227, + 1,255,236,238,1,255,233,236,1,255,231,234,1,255,228,231,1,255,226,229, + 1,255,223,227,1,250,217,221,1,82,70,71,1,56,47,48,1,246,205,210, + 1,255,212,217,3,246,207,211,1,153,153,153,1,125,125,125,1,132,132,132, + 1,205,205,205,1,210,210,210,1,208,208,208,1,245,245,245,1,209,209,209, + 1,153,153,153,1,236,221,223,1,255,234,236,1,255,232,234,1,255,229,232, + 1,255,226,230,1,255,224,227,1,255,221,225,1,101,87,88,1,47,40,41, + 1,235,197,201,1,255,212,217,4,237,202,206,1,153,153,153,1,119,119,119, + 1,112,112,112,1,204,204,204,1,210,210,210,1,208,208,208,1,245,245,245, + 1,227,227,227,1,153,153,153,1,217,204,206,1,255,232,235,1,255,230,232, + 1,255,227,230,1,255,224,228,1,255,222,226,1,249,214,218,1,3,3,3, + 1,208,175,179,1,255,212,217,5,217,190,193,1,153,153,153,1,107,107,107, + 1,112,112,112,1,204,204,204,1,210,210,210,1,208,208,208,1,245,245,245, + 1,242,242,242,1,156,156,156,1,195,186,187,1,255,230,233,1,255,228,231, + 1,255,225,228,1,255,223,226,1,255,220,224,1,238,203,207,1,103,87,88, + 1,247,205,210,1,255,212,217,5,195,177,180,1,152,152,152,1,101,101,101, + 1,131,131,131,1,204,204,204,1,210,210,210,1,208,208,208,1,245,245,245, + 1,243,243,243,1,183,183,183,1,155,154,154,1,236,214,216,1,255,226,229, + 1,255,223,227,1,255,221,225,1,255,218,222,1,239,202,206,1,167,139,143, + 1,242,201,206,1,255,212,217,4,236,201,205,1,154,153,153,1,133,133,133, + 1,101,101,101,1,152,152,152,1,207,207,207,1,210,210,210,1,208,208,208, + 1,245,245,245,1,243,243,243,1,232,232,232,1,158,158,158,1,171,166,167, + 1,253,223,226,1,255,221,225,1,255,219,223,1,255,216,221,1,208,174,178, + 1,0,0,0,1,215,179,183,1,255,212,217,3,253,211,216,1,171,163,164, + 1,150,151,152,1,88,128,147,1,105,107,108,1,178,178,178,1,209,209,209, + 1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242, + 1,206,206,206,1,153,153,153,1,178,170,171,1,243,211,215,1,255,217,221, + 1,255,214,219,1,255,212,217,5,243,205,210,1,178,167,169,1,153,153,153, + 1,140,173,190,1,102,164,195,1,84,136,162,1,183,185,186,1,211,211,211, + 1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242, + 1,239,239,239,1,192,192,192,1,153,152,152,1,157,155,155,1,211,188,191, + 1,241,204,208,1,255,212,217,3,241,204,208,1,211,187,189,1,157,155,155, + 1,152,152,153,1,150,176,189,1,167,202,221,1,134,183,208,1,103,164,195, + 1,84,137,163,1,190,192,193,1,210,210,210,1,208,208,208,1,245,245,245, + 1,243,243,243,1,242,242,242,1,240,240,240,1,234,234,234,1,191,191,191, + 1,147,146,146,1,153,153,153,2,157,155,156,1,172,163,164,1,157,155,156, + 1,153,153,153,2,140,139,139,1,97,139,160,1,116,172,201,1,148,191,213, + 1,167,202,221,1,135,183,208,1,103,164,195,1,87,139,165,1,185,187,188, + 1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240,240, + 1,238,238,238,1,233,233,233,1,213,213,213,1,151,151,151,1,129,129,129, + 1,135,135,135,1,142,142,142,1,133,133,133,1,123,123,123,1,114,114,114, + 1,106,106,106,1,105,111,114,1,90,147,176,1,116,172,200,1,148,191,213, + 1,167,202,221,1,135,183,208,1,103,164,195,1,84,137,163,1,183,185,186, + 1,245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1,238,238,238, + 1,237,237,237,1,234,234,234,1,226,226,226,1,192,192,192,1,162,162,162, + 1,137,137,137,1,117,117,117,1,116,116,116,1,134,134,134,1,157,157,157, + 1,183,183,183,1,192,198,201,1,93,150,179,1,116,172,200,1,148,191,213, + 1,167,202,221,1,135,183,208,1,103,164,195,1,95,135,155,1,245,245,245, + 1,243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1,237,237,237, + 1,235,235,235,1,234,234,234,1,229,229,229,1,225,225,225,1,222,222,222, + 1,218,218,218,1,217,217,217,2,219,219,219,1,218,218,218,1,219,219,219, + 1,199,205,208,1,94,151,180,1,116,172,200,1,148,191,213,1,167,203,221, + 1,134,182,205,1,98,115,124,1,245,245,245,1,243,243,243,1,242,242,242, + 1,240,240,240,1,238,238,238,1,237,237,237,1,235,235,235,1,234,234,234, + 1,232,232,232,1,230,230,230,1,229,229,229,1,227,227,227,1,226,226,226, + 1,224,224,224,1,223,223,223,1,221,221,221,1,219,219,219,1,218,218,218, + 1,197,203,206,1,94,151,179,1,116,172,200,1,147,189,210,1,117,128,134, + 1,94,94,94,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240,240, + 1,238,238,238,1,237,237,237,1,235,235,235,1,234,234,234,1,232,232,232, + 1,230,230,230,1,229,229,229,1,227,227,227,1,226,226,226,1,224,224,224, + 1,223,223,223,1,221,221,221,1,219,219,219,1,218,218,218,1,216,216,216, + 1,196,202,205,1,105,149,171,1,108,124,133,1,95,95,95,1,125,125,125, + 1,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,9,116, + 100,111,99,107,102,111,114,109,0,10,116,116,97,98,119,105,100,103,101,116, + 4,116,97,98,115,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,103,1, + 9,98,111,117,110,100,115,95,99,121,3,198,0,7,97,110,99,104,111,114, + 115,11,0,11,116,97,98,95,111,112,116,105,111,110,115,11,15,116,97,98, + 111,95,100,114,97,103,115,111,117,114,99,101,13,116,97,98,111,95,100,114, + 97,103,100,101,115,116,13,116,97,98,111,95,111,112,112,111,115,105,116,101, + 23,116,97,98,111,95,100,98,108,99,108,105,99,107,101,100,116,97,98,102, + 105,114,115,116,20,116,97,98,111,95,104,105,110,116,99,108,105,112,112,101, + 100,116,101,120,116,0,21,116,97,98,95,102,114,97,109,101,46,98,117,116, + 116,111,110,115,108,97,115,116,9,20,116,97,98,95,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,0,21,116,97,98,95,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98, + 95,115,105,122,101,2,18,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tfindinfilefo,''); +end. diff --git a/mseide-msegui/apps/ide/findinfilepage.mfm b/mseide-msegui/apps/ide/findinfilepage.mfm new file mode 100644 index 0000000..2688793 --- /dev/null +++ b/mseide-msegui/apps/ide/findinfilepage.mfm @@ -0,0 +1,158 @@ +object findinfilepagefo: tfindinfilepagefo + optionswidget = [ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets, ow_hinton] + visible = False + bounds_x = 382 + bounds_y = 163 + bounds_cx = 573 + bounds_cy = 310 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.frame.localprops = [] + container.frame.localprops1 = [] + container.onlayout = childscaled + container.bounds = ( + 0 + 0 + 573 + 310 + ) + icon.options = [bmo_masked] + ondestroy = formdestroy + onlayout = childscaled + moduleclassname = 'tmseform' + object grid: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + color = -1879048187 + frame.localprops = [] + frame.localprops1 = [] + taborder = 1 + bounds_x = 0 + bounds_y = 24 + bounds_cx = 571 + bounds_cy = 284 + anchors = [an_left, an_top, an_right, an_bottom] + fixcols.count = 1 + fixcols.items = < + item + width = 38 + textflags = [tf_right, tf_ycentered] + numstart = 1 + numstep = 1 + end> + rowcount = 1 + datacols.count = 1 + datacols.items = < + item[foundlist] + width = 1500 + options = [co_readonly, co_fill] + widthmin = 1500 + widgetname = 'foundlist' + dataclass = tgridrichstringdatalist + data = ( + ( + '' + ) + ) + end> + datarowheight = 16 + oncellevent = foundlistoncellevent + reffontheight = 14 + object foundlist: ttextedit + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + color = -1879048185 + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 1500 + bounds_cy = 16 + optionsedit1 = [oe1_keyexecute, oe1_savestate] + optionsedit = [oe_readonly, oe_closequery, oe_checkmrcancel, oe_linebreak, oe_eatreturn, oe_exitoncursor] + oncellevent = foundlistoncellevent + reffontheight = 14 + end + end + object filename: tstringdisp + frame.localprops = [] + frame.localprops1 = [] + taborder = 3 + bounds_x = 1 + bounds_y = 0 + bounds_cx = 406 + bounds_cy = 18 + bounds_cxmin = 140 + anchors = [an_left, an_top, an_right] + textflags = [tf_ycentered, tf_ellipseleft] + reffontheight = 14 + end + object foundcount: tintegerdisp + frame.localprops = [] + frame.localprops1 = [] + taborder = 2 + bounds_x = 407 + bounds_y = 0 + bounds_cx = 44 + bounds_cy = 18 + anchors = [an_top, an_right] + reffontheight = 14 + end + object cancel: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_tabfocus, ow_arrowfocus, ow_mousewheel, ow_destroywidgets] + color = -2147483645 + taborder = 5 + bounds_x = 453 + bounds_y = 1 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_top, an_right] + state = [as_disabled, as_localdisabled, as_localcaption, as_localonexecute] + caption = '&Cancel' + onexecute = cancelonexecute + reffontheight = 14 + end + object again: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_tabfocus, ow_arrowfocus, ow_mousewheel, ow_destroywidgets] + color = -2147483645 + taborder = 4 + bounds_x = 503 + bounds_y = 1 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_top, an_right] + state = [as_localcaption, as_localonexecute] + caption = '&again' + onexecute = againonexecute + reffontheight = 14 + end + object closepage: tstockglyphbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_tabfocus, ow_arrowfocus, ow_mousewheel, ow_destroywidgets] + color = -2147483645 + bounds_x = 553 + bounds_y = 1 + bounds_cx = 18 + bounds_cy = 20 + anchors = [an_top, an_right] + state = [as_localimagelist, as_localimagenr, as_localonexecute] + glyph = stg_checked + onexecute = closebuonexecute + reffontheight = 14 + end + object thread: tthreadcomp + onstart = threadonstart + onexecute = threadonexecute + onterminate = threadonterminate + left = 16 + top = 72 + end + object c: tstringcontainer + strings.data = ( + '*** CANCELED ***' + 'FINISHED' + ) + left = 136 + top = 64 + end +end diff --git a/mseide-msegui/apps/ide/findinfilepage.pas b/mseide-msegui/apps/ide/findinfilepage.pas new file mode 100644 index 0000000..4b1b659 --- /dev/null +++ b/mseide-msegui/apps/ide/findinfilepage.pas @@ -0,0 +1,368 @@ +{ MSEide Copyright (c) 1999-2016 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit findinfilepage; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msetypes,msegui,mseclasses,mseforms,msetabs,msetextedit,msewidgetgrid,msegrids, + msethreadcomp,findinfileform,msesimplewidgets,msedispwidgets,msestrings, + classes,mclasses,msestringcontainer; + +type + + tfindinfilepagefo = class(ttabform) + cancel: tbutton; + filename: tstringdisp; + foundcount: tintegerdisp; + foundlist: ttextedit; + grid: twidgetgrid; + again: tbutton; + thread: tthreadcomp; + closepage: tstockglyphbutton; + c: tstringcontainer; + procedure foundlistoncellevent(const sender: tobject; var info: celleventinfoty); + procedure threadonexecute(const sender: tthreadcomp); + procedure threadonstart(const sender: tthreadcomp); + procedure threadonterminate(const sender: tthreadcomp); + procedure cancelonexecute(const sender: tobject); + procedure closebuonexecute(const sender: TObject); + procedure againonexecute(const sender: TObject); + procedure childscaled(const sender: TObject); + procedure formdestroy(const sender: TObject); + private + finfo: findinfileinfoty; + procedure dorun; + protected + procedure addfoundline(const text: string; const linenr: integer; col: integer); + procedure startfile(const afilename: filenamety); + public + constructor create(const aowner: tcomponent; + const findinfo: findinfileinfoty); reintroduce; + procedure cancelsearch; + end; + +implementation +uses + findinfilepage_mfm,sourcepage,sourceform,mseeditglob,sysutils,mserichstring, + msegraphics,msestream,msefileutils,msesys,findinfiledialogform,msegraphutils, + projectoptionsform,msesystypes,mseformatstr,main; + +type + stringconsts = ( + canceled, //0 *** CANCELED *** + finished //1 FINISHED + ); + +{ tfindinfilepagefo} + +constructor tfindinfilepagefo.create(const aowner: tcomponent; + const findinfo: findinfileinfoty); +begin + finfo:= findinfo; + inherited create(aowner); + name:= ''; + dorun; +end; + +procedure tfindinfilepagefo.foundlistoncellevent(const sender: tobject; + var info: celleventinfoty); +var + page: tsourcepage; +begin + if iscellclick(info,[ccr_dblclick]) then begin + locateerrormessage(foundlist[info.cell.row],page); + if page <> nil then begin + with page.edit do begin + setselection(editpos,makegridcoord(editpos.col + length(finfo.findinfo.text), + editpos.row),true); + end; + end; + end; +end; + +procedure tfindinfilepagefo.cancelsearch; +begin + thread.terminate; + thread.waitfor; + filename.value:= c[ord(canceled)]; +end; + +procedure tfindinfilepagefo.startfile(const afilename: filenamety); +begin + application.lock; + try + filename.value:= afilename; + finally + application.unlock; + end; +end; + +procedure tfindinfilepagefo.addfoundline(const text: string; + const linenr: integer; col: integer); +const + maxfoundpos = 80; + maxcenteredpos = maxfoundpos div 2; + maxfoundlength = maxfoundpos + maxcenteredpos; +var + int1: integer; + str1,str2: msestring; +begin + if foundlist <> nil then begin + application.lock; + try + str1:= filename.value+'('+inttostrmse(linenr+1)+','+inttostrmse(col+1)+'): '; + if col > maxfoundpos then begin + int1:= col - maxcenteredpos; + str2:= '...'+msestring(copy(text,int1,maxfoundlength)); + col:= maxcenteredpos + 4; + if length(text) > length(str2) + int1 - 4 then begin + str2:= str2 + '...'; + end; + end + else begin + str2:= msestring(copy(text,1,maxfoundlength)); + if length(text) > length(str2) then begin + str2:= str2 + '...'; + end; + end; + int1:= foundlist.appendrow(str1+str2); + foundcount.value:= foundcount.value + 1; + updatefontstyle1(foundlist.datalist.richitemspo[int1]^.format,length(str1)+col, + length(finfo.findinfo.text),fs_bold,true); + finally + application.unlock; + end; + end; +end; + +procedure tfindinfilepagefo.threadonexecute(const sender: tthreadcomp); + + procedure searchstream(const stream: ttextstream; const afilename: filenamety); + var + str1: string; + begin + case projectoptions.e.encoding of + 1: begin + stream.encoding:= ce_utf8; + end; + 2: begin + stream.encoding:= ce_iso8859_1; + end; + end; + with sender,tfindinfilepagefo(datapo),finfo do begin + stream.buflen:= 4096; + with stream do begin + msesearchtext:= findinfo.text; + searchoptions:= findinfo.options; + startfile(afilename); + while searchnext and not terminated do begin + Position:= searchlinestartpos; + readln(str1); + addfoundline(str1,searchlinenumber,searchfoundpos-searchlinestartpos); + end; + end; + end; + end; + + procedure searchdirectory(const adir: filenamety); + var + stream1: ttextstream; + filelist: tfiledatalist; + int1,int2: integer; + ar1: filenamearty; + begin + with sender,tfindinfilepagefo(datapo),finfo do begin + filelist:= tfiledatalist.create; + filelist.options:= [flo_sortname]; + try + unquotefilename(adir,ar1); + for int2:= 0 to high(ar1) do begin + ar1[int2]:= filepath(ar1[int2],fk_file); + if fifo_subdirs in options then begin + {$ifndef FPC} + if filelist.adddirectory2(ar1[int2],fil_ext1,'', + [fa_dir],[],[],nil,true) then begin + {$else} + if filelist.adddirectory(ar1[int2],fil_ext1,'', + [fa_dir],[],[],nil,true) then begin + {$endif} + for int1:= 0 to filelist.count - 1 do begin + if terminated then begin + break; + end; + with filelist[int1] do begin + searchdirectory(ar1[int2]+'/'+ name); + end; + end; + end; + end; + filelist.clear; + {$ifndef FPC} + if filelist.adddirectory2(ar1[int2],fil_ext1,filemask, + [fa_all],[fa_dir],[],nil,true) then begin + {$else} + if filelist.adddirectory(ar1[int2],fil_ext1,filemask, + [fa_all],[fa_dir],[],nil,true) then begin + {$endif} + for int1:= 0 to filelist.count - 1 do begin + if terminated then begin + break; + end; + with filelist[int1] do begin + try + if ttextstream.trycreate( + stream1,ar1[int2]+'/'+name,fm_read) = sye_ok then begin + try + searchstream(stream1,stream1.filename); + finally + stream1.free; + end; + end; + except + end; + end; + end; + end; + end; + finally + filelist.Free; + end; + end; + end; //searchdirectory + +var + int1: integer; + stream1: ttextstream; + bo1: boolean; + mstr1: filenamety; + +begin + if finfo.source in [fs_inopenfiles,fs_incurrentfile] then begin + int1:= 0; + if finfo.source = fs_incurrentfile then begin + int1:= sourcefo.activepage.tabindex; + end; + with sender,tfindinfilepagefo(datapo),finfo do begin + while not terminated do begin + bo1:= false; + application.lock; + try + if int1 < sourcefo.count then begin + with sourcefo.items[int1] do begin + if fileloaded then begin + stream1:= ttextstream.create; //memorystream + edit.savetostream(stream1,false); + end + else begin + stream1:= ttextstream.create(filepath); + end; + application.unlock; + bo1:= true; + try + searchstream(stream1,filepath); + finally + stream1.free; + end; + end; + end + else begin + break; + end; + finally + if not bo1 then begin + application.unlock; + end; + end; + if finfo.source = fs_incurrentfile then begin + break; + end; + inc(int1); + end; + end; + end + else begin + if finfo.source = fs_inprojectdir then begin + application.lock(); + mstr1:= filedir(mainfo.projectname); + application.unlock(); + end + else begin + mstr1:= tfindinfilepagefo(sender.datapo).finfo.directory; + application.lock; + expandprmacros1(mstr1); + application.unlock; + end; + searchdirectory(mstr1); + end; +end; + +procedure tfindinfilepagefo.threadonstart(const sender: tthreadcomp); +begin + cancel.enabled:= true; + again.enabled:= false; +end; + +procedure tfindinfilepagefo.threadonterminate(const sender: tthreadcomp); +begin + if not application.terminated then begin + cancel.enabled:= false; + again.enabled:= true; + filename.value:= c[ord(finished)]; + end; +end; + +procedure tfindinfilepagefo.childscaled(const sender: TObject); +begin + placeyorder(0,[1],[cancel,grid],0); + aligny(wam_center,[cancel,filename,foundcount,again,closepage]); +end; + +procedure tfindinfilepagefo.closebuonexecute(const sender: TObject); +begin + release; +end; + +procedure tfindinfilepagefo.cancelonexecute(const sender: tobject); +begin + cancelsearch; +end; + +procedure tfindinfilepagefo.dorun; +begin + caption:= finfo.findinfo.text; + foundlist.clear; + foundcount.value:= 0; + thread.run(self); +end; + +procedure tfindinfilepagefo.againonexecute(const sender: TObject); +begin + findinfilefo.show; + if findinfiledialogexecute(finfo,true) then begin + dorun; + end; +end; + +procedure tfindinfilepagefo.formdestroy(const sender: TObject); +begin + thread.terminate; + thread.waitfor; +end; + +end. diff --git a/mseide-msegui/apps/ide/findinfilepage_mfm.pas b/mseide-msegui/apps/ide/findinfilepage_mfm.pas new file mode 100644 index 0000000..c4284ad --- /dev/null +++ b/mseide-msegui/apps/ide/findinfilepage_mfm.pas @@ -0,0 +1,184 @@ +unit findinfilepage_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,findinfilepage; + +const + objdata: record size: integer; data: array[0..3320] of byte end = + (size: 3321; data: ( + 84,80,70,48,17,116,102,105,110,100,105,110,102,105,108,101,112,97,103,101, + 102,111,16,102,105,110,100,105,110,102,105,108,101,112,97,103,101,102,111,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,9,111,119,95,104,105,110,116,111, + 110,0,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120, + 3,126,1,8,98,111,117,110,100,115,95,121,3,163,0,9,98,111,117,110, + 100,115,95,99,120,3,61,2,9,98,111,117,110,100,115,95,99,121,3,54, + 1,23,99,111,110,116,97,105,110,101,114,46,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115, + 105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,11, + 111,119,95,115,117,98,102,111,99,117,115,19,111,119,95,109,111,117,115,101, + 116,114,97,110,115,112,97,114,101,110,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,26,99,111,110,116,97,105,110,101,114, + 46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,27, + 99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,18,99,111,110,116,97,105,110,101,114,46, + 111,110,108,97,121,111,117,116,7,11,99,104,105,108,100,115,99,97,108,101, + 100,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2, + 0,2,0,3,61,2,3,54,1,0,12,105,99,111,110,46,111,112,116,105, + 111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,0,9,111,110,100, + 101,115,116,114,111,121,7,11,102,111,114,109,100,101,115,116,114,111,121,8, + 111,110,108,97,121,111,117,116,7,11,99,104,105,108,100,115,99,97,108,101, + 100,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,8,116, + 109,115,101,102,111,114,109,0,11,116,119,105,100,103,101,116,103,114,105,100, + 4,103,114,105,100,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,102,111,99, + 117,115,98,97,99,107,111,110,101,115,99,13,111,119,95,109,111,117,115,101, + 119,104,101,101,108,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,5,99,111,108,111,114,4,5,0,0,144,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114, + 100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,2,24,9,98,111,117,110,100,115,95,99,120,3,59,2, + 9,98,111,117,110,100,115,95,99,121,3,28,1,7,97,110,99,104,111,114, + 115,11,7,97,110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110, + 95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,13,102,105, + 120,99,111,108,115,46,99,111,117,110,116,2,1,13,102,105,120,99,111,108, + 115,46,105,116,101,109,115,14,1,5,119,105,100,116,104,2,38,9,116,101, + 120,116,102,108,97,103,115,11,8,116,102,95,114,105,103,104,116,12,116,102, + 95,121,99,101,110,116,101,114,101,100,0,8,110,117,109,115,116,97,114,116, + 2,1,7,110,117,109,115,116,101,112,2,1,0,0,8,114,111,119,99,111, + 117,110,116,2,1,14,100,97,116,97,99,111,108,115,46,99,111,117,110,116, + 2,1,14,100,97,116,97,99,111,108,115,46,105,116,101,109,115,14,7,9, + 102,111,117,110,100,108,105,115,116,1,5,119,105,100,116,104,3,220,5,7, + 111,112,116,105,111,110,115,11,11,99,111,95,114,101,97,100,111,110,108,121, + 7,99,111,95,102,105,108,108,0,8,119,105,100,116,104,109,105,110,3,220, + 5,10,119,105,100,103,101,116,110,97,109,101,6,9,102,111,117,110,100,108, + 105,115,116,9,100,97,116,97,99,108,97,115,115,7,23,116,103,114,105,100, + 114,105,99,104,115,116,114,105,110,103,100,97,116,97,108,105,115,116,4,100, + 97,116,97,1,1,6,0,0,0,0,0,13,100,97,116,97,114,111,119,104, + 101,105,103,104,116,2,16,11,111,110,99,101,108,108,101,118,101,110,116,7, + 20,102,111,117,110,100,108,105,115,116,111,110,99,101,108,108,101,118,101,110, + 116,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,9,116, + 116,101,120,116,101,100,105,116,9,102,111,117,110,100,108,105,115,116,14,111, + 112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102, + 111,110,116,103,108,121,112,104,104,101,105,103,104,116,13,111,119,49,95,97, + 117,116,111,115,99,97,108,101,0,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111, + 119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102, + 111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110, + 16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119, + 95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,5,99,111,108, + 111,114,4,7,0,0,144,8,116,97,98,111,114,100,101,114,2,1,7,118, + 105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,0,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3, + 220,5,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111, + 110,115,101,100,105,116,49,11,14,111,101,49,95,107,101,121,101,120,101,99, + 117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0,11,111, + 112,116,105,111,110,115,101,100,105,116,11,11,111,101,95,114,101,97,100,111, + 110,108,121,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101, + 95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,108,105, + 110,101,98,114,101,97,107,12,111,101,95,101,97,116,114,101,116,117,114,110, + 15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,0,11,111,110, + 99,101,108,108,101,118,101,110,116,7,20,102,111,117,110,100,108,105,115,116, + 111,110,99,101,108,108,101,118,101,110,116,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,0,0,11,116,115,116,114,105,110,103,100,105, + 115,112,8,102,105,108,101,110,97,109,101,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2, + 3,8,98,111,117,110,100,115,95,120,2,1,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,120,3,150,1,9,98,111,117, + 110,100,115,95,99,121,2,18,12,98,111,117,110,100,115,95,99,120,109,105, + 110,3,140,0,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102, + 116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,9,116, + 101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101,110,116,101,114, + 101,100,14,116,102,95,101,108,108,105,112,115,101,108,101,102,116,0,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,12,116,105,110, + 116,101,103,101,114,100,105,115,112,10,102,111,117,110,100,99,111,117,110,116, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8, + 116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,3, + 151,1,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,2,44,9,98,111,117,110,100,115,95,99,121,2,18,7,97,110, + 99,104,111,114,115,11,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0, + 0,7,116,98,117,116,116,111,110,6,99,97,110,99,101,108,14,111,112,116, + 105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110, + 116,103,108,121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116, + 111,115,99,97,108,101,0,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,13,111,119,95,109,111,117,115,101,119,104,101, + 101,108,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 0,5,99,111,108,111,114,4,3,0,0,128,8,116,97,98,111,114,100,101, + 114,2,5,8,98,111,117,110,100,115,95,120,3,197,1,8,98,111,117,110, + 100,115,95,121,2,1,9,98,111,117,110,100,115,95,99,120,2,50,9,98, + 111,117,110,100,115,95,99,121,2,20,7,97,110,99,104,111,114,115,11,6, + 97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,5,115,116,97, + 116,101,11,11,97,115,95,100,105,115,97,98,108,101,100,16,97,115,95,108, + 111,99,97,108,100,105,115,97,98,108,101,100,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101, + 120,101,99,117,116,101,0,7,99,97,112,116,105,111,110,6,7,38,67,97, + 110,99,101,108,9,111,110,101,120,101,99,117,116,101,7,15,99,97,110,99, + 101,108,111,110,101,120,101,99,117,116,101,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,0,7,116,98,117,116,116,111,110,5,97,103, + 97,105,110,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19, + 111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,13, + 111,119,49,95,97,117,116,111,115,99,97,108,101,0,13,111,112,116,105,111, + 110,115,119,105,100,103,101,116,11,11,111,119,95,116,97,98,102,111,99,117, + 115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,13,111,119,95,109, + 111,117,115,101,119,104,101,101,108,17,111,119,95,100,101,115,116,114,111,121, + 119,105,100,103,101,116,115,0,5,99,111,108,111,114,4,3,0,0,128,8, + 116,97,98,111,114,100,101,114,2,4,8,98,111,117,110,100,115,95,120,3, + 247,1,8,98,111,117,110,100,115,95,121,2,1,9,98,111,117,110,100,115, + 95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,20,7,97,110, + 99,104,111,114,115,11,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,0,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99, + 97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101, + 99,117,116,101,0,7,99,97,112,116,105,111,110,6,6,38,97,103,97,105, + 110,9,111,110,101,120,101,99,117,116,101,7,14,97,103,97,105,110,111,110, + 101,120,101,99,117,116,101,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,0,17,116,115,116,111,99,107,103,108,121,112,104,98,117,116, + 116,111,110,9,99,108,111,115,101,112,97,103,101,14,111,112,116,105,111,110, + 115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108, + 121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99, + 97,108,101,0,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,11, + 111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119, + 102,111,99,117,115,13,111,119,95,109,111,117,115,101,119,104,101,101,108,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,5,99, + 111,108,111,114,4,3,0,0,128,8,98,111,117,110,100,115,95,120,3,41, + 2,8,98,111,117,110,100,115,95,121,2,1,9,98,111,117,110,100,115,95, + 99,120,2,18,9,98,111,117,110,100,115,95,99,121,2,20,7,97,110,99, + 104,111,114,115,11,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104, + 116,0,5,115,116,97,116,101,11,17,97,115,95,108,111,99,97,108,105,109, + 97,103,101,108,105,115,116,15,97,115,95,108,111,99,97,108,105,109,97,103, + 101,110,114,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116, + 101,0,5,103,108,121,112,104,7,11,115,116,103,95,99,104,101,99,107,101, + 100,9,111,110,101,120,101,99,117,116,101,7,16,99,108,111,115,101,98,117, + 111,110,101,120,101,99,117,116,101,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,14,0,0,11,116,116,104,114,101,97,100,99,111,109,112,6, + 116,104,114,101,97,100,7,111,110,115,116,97,114,116,7,13,116,104,114,101, + 97,100,111,110,115,116,97,114,116,9,111,110,101,120,101,99,117,116,101,7, + 15,116,104,114,101,97,100,111,110,101,120,101,99,117,116,101,11,111,110,116, + 101,114,109,105,110,97,116,101,7,17,116,104,114,101,97,100,111,110,116,101, + 114,109,105,110,97,116,101,4,108,101,102,116,2,16,3,116,111,112,2,72, + 0,0,16,116,115,116,114,105,110,103,99,111,110,116,97,105,110,101,114,1, + 99,12,115,116,114,105,110,103,115,46,100,97,116,97,1,6,16,42,42,42, + 32,67,65,78,67,69,76,69,68,32,42,42,42,6,8,70,73,78,73,83, + 72,69,68,0,4,108,101,102,116,3,136,0,3,116,111,112,2,64,0,0, + 0) + ); + +initialization + registerobjectdata(@objdata,tfindinfilepagefo,''); +end. diff --git a/mseide-msegui/apps/ide/formdesigner.mfm b/mseide-msegui/apps/ide/formdesigner.mfm new file mode 100644 index 0000000..80eacdd --- /dev/null +++ b/mseide-msegui/apps/ide/formdesigner.mfm @@ -0,0 +1,338 @@ +object formdesignerfo: tformdesignerfo + optionswidget = [ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_mousewheel, ow_hinton] + optionsskin = [osk_framebuttononly] + color = -1879048187 + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 0 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_floatbutton, go_topbutton, go_backgroundbutton, go_buttonhints] + frame.grip_face.fade_pos.count = 1 + frame.grip_face.fade_pos.items = ( + 0 + ) + frame.grip_face.fade_color.count = 1 + frame.grip_face.fade_color.items = ( + -1610612717 + ) + frame.grip_face.localprops = [] + popupmenu = popupme + onenter = enterexe + onactivate = enterexe + visible = False + bounds_x = 68 + bounds_y = 277 + bounds_cx = 287 + bounds_cy = 300 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_mousetransparent, ow_mousewheel] + container.color = -1879048187 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.oncalcminscrollsize = calcscrollsize + container.bounds = ( + 0 + 0 + 287 + 300 + ) + dragdock.optionsdock = [od_savepos, od_savezorder, od_canmove, od_cansize, od_canfloat, od_candock, od_propsize, od_captionhint, od_childicons] + dragdock.onbeforefloat = beffloatexe + dragdock.onfloat = floatexe + optionswindow = [wo_notaskbar] + options = [fo_savepos, fo_savezorder, fo_savestate] + statfile = mainfo.projectstatfile + icon.transparentcolor = -2147483642 + icon.image = { + 00000000000000001800000018000000A4070000000000000000000000000000 + 0000000000000000000000000000000000000000FFFFFF19F2A69501DDD8D301 + F2A69501FF866D02794034019D534301BB625001D06D5902F7826A01D46F5B01 + FF866D04A0A0A00680808001FFFFFF01DDD8D30107EFFF01DDD8D301FF866D02 + 783F3301C96A5601B55F4D0187473A01D6705B018B493B01A3564601F27F6701 + FF866D03A0A0A001D4D4D40180808001A0A0A001D1D1D10180808002FFFFFF01 + F2A69501DDD8D301F2A69501FF866D02D46F5B01FF866D01DA735D01CC6B5701 + B45F4D01DE755F01B8614F01FD856C01FF866D03A0A0A001D4D4D40180808001 + A0A0A001D1D1D10180808002FFFFFF019718001080808007FFFFFF01E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E201E1E1E101E0E0E001DFDFDF01DEDEDE01 + DDDDDD01DCDCDC01DBDBDB01DADADA01D9D9D901D7D7D701D6D6D601D5D5D501 + D4D4D401D3D3D301D2D2D201D1D1D101D0D0D00180808001FFFFFF01E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E201E1E1E101E0E0E001DFDFDF01DEDEDE01 + DDDDDD01DCDCDC01DBDBDB01DADADA01D9D9D901D7D7D701D6D6D601D5D5D501 + D4D4D401D3D3D301D2D2D201D1D1D101D0D0D00180808001FFFFFF01E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E201E1E1E101E0E0E001DFDFDF01DEDEDE01 + DDDDDD01DCDCDC01DBDBDB01DADADA01D9D9D901D7D7D701D6D6D601D5D5D501 + D4D4D401D3D3D301D2D2D201D1D1D101D0D0D00180808001FFFFFF01E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E201E1E1E101E0E0E001DFDFDF01DEDEDE01 + DDDDDD01DCDCDC01DBDBDB01DADADA01D9D9D901D7D7D701D6D6D601D5D5D501 + D4D4D401D3D3D301D2D2D201D1D1D101D0D0D00180808001FFFFFF01E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E201E1E1E101E0E0E001DFDFDF01DEDEDE01 + DDDDDD01DCDCDC01DBDBDB01DADADA01D9D9D901D7D7D701D6D6D601D5D5D501 + D4D4D401D3D3D301D2D2D201D1D1D101D0D0D00180808001FFFFFF01E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E201E1E1E101E0E0E001DFDFDF01DEDEDE01 + DDDDDD01DCDCDC01DBDBDB01DADADA01D9D9D901D7D7D701D6D6D601D5D5D501 + D4D4D401D3D3D301D2D2D201D1D1D101D0D0D00180808001FFFFFF01E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E201E1E1E101E0E0E001DFDFDF01DEDEDE01 + DDDDDD01DCDCDC01DBDBDB01DADADA01D9D9D901D7D7D701D6D6D601D5D5D501 + D4D4D401D3D3D301D2D2D201D1D1D101D0D0D00180808001FFFFFF01E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E201E1E1E101E0E0E001DFDFDF01DEDEDE01 + DDDDDD01DCDCDC01DBDBDB01DADADA01D9D9D901D7D7D701D6D6D601D5D5D501 + D4D4D401D3D3D301D2D2D201D1D1D101D0D0D00180808001FFFFFF01E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E201E1E1E101E0E0E001DFDFDF01DEDEDE01 + DDDDDD01DCDCDC01DBDBDB01DADADA01D9D9D901D7D7D701D6D6D601D5D5D501 + D4D4D401D3D3D301D2D2D201D1D1D101D0D0D00180808001FFFFFF01E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E201E1E1E101E0E0E001DFDFDF01DEDEDE01 + DDDDDD01DCDCDC01DBDBDB01DADADA01D9D9D901D7D7D701D6D6D601D5D5D501 + D4D4D401D3D3D301D2D2D201D1D1D101D0D0D00180808001FFFFFF01E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E201E1E1E101E0E0E001DFDFDF01DEDEDE01 + DDDDDD01DCDCDC01DBDBDB01DADADA01D9D9D901D7D7D701D6D6D601D5D5D501 + D4D4D401D3D3D301D2D2D201D1D1D101D0D0D00180808001FFFFFF01E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E201E1E1E101E0E0E001DFDFDF01DEDEDE01 + DDDDDD01DCDCDC01DBDBDB01DADADA01D9D9D901D7D7D701D6D6D601D5D5D501 + D4D4D401D3D3D301D2D2D201D1D1D101D0D0D00180808001FFFFFF01E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E201E1E1E101E0E0E001DFDFDF01DEDEDE01 + DDDDDD01DCDCDC01DBDBDB01DADADA01D9D9D901D7D7D701D6D6D601D5D5D501 + D4D4D401D3D3D301D2D2D201D1D1D101D0D0D00180808001FFFFFF01E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E201E1E1E101E0E0E001DFDFDF01DEDEDE01 + DDDDDD01DCDCDC01DBDBDB01DADADA01D9D9D901D7D7D701D6D6D601D5D5D501 + D4D4D401D3D3D301D2D2D201D1D1D101D0D0D00180808001FFFFFF01E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E201E1E1E101E0E0E001DFDFDF01DEDEDE01 + DDDDDD01DCDCDC01DBDBDB01DADADA01D9D9D901D7D7D701D6D6D601D5D5D501 + D4D4D401D3D3D301D2D2D201D1D1D101D0D0D00180808001FFFFFF01E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E201E1E1E101E0E0E001DFDFDF01DEDEDE01 + DDDDDD01DCDCDC01DBDBDB01DADADA01D9D9D901D7D7D701D6D6D601D5D5D501 + D4D4D401D3D3D301D2D2D201D1D1D101D0D0D00180808001FFFFFF01E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E201E1E1E101E0E0E001DFDFDF01DEDEDE01 + DDDDDD01DCDCDC01DBDBDB01DADADA01D9D9D901D7D7D701D6D6D601D5D5D501 + D4D4D401D3D3D301D2D2D201D1D1D101D0D0D00180808001FFFFFF01E6E6E601 + E5E5E501E4E4E401E3E3E301E2E2E201E1E1E101E0E0E001DFDFDF01DEDEDE01 + DDDDDD01DCDCDC01DBDBDB01DADADA01D9D9D901D7D7D701D6D6D601D5D5D501 + D4D4D401D3D3D301D2D2D201D1D1D101D0D0D00180808019 + } + onclose = formdeonclose + left = 239 + top = 180 + moduleclassname = 'tdockform' + object popupme: tpopupmenu + menu.submenu.count = 33 + menu.submenu.items = < + item + caption = 'Show objectinspector' + state = [as_localcaption, as_localonexecute] + onexecute = doshowobjectinspector + end + item + caption = 'Show componentpalette' + state = [as_localcaption, as_localonexecute] + onexecute = doshowcomponentpalette + end + item + caption = 'Show as Text' + state = [as_localcaption, as_localonexecute] + options = [mao_shortcutcaption, mao_asyncexecute] + onexecute = doshowastext + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + action = hidecompact + options = [mao_checkbox, mao_shortcutcaption] + end + item + action = hidewidgetact + options = [mao_checkbox, mao_shortcutcaption] + end + item + action = togglehideact + end + item + action = showallact + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = 'Copy Component(s)' + name = 'copy' + state = [as_localcaption, as_localshortcut, as_localonexecute] + onexecute = copyexe + sc = ( + 1 + 16451 + ) + end + item + caption = 'Cut Component(s)' + name = 'cut' + state = [as_localcaption, as_localshortcut, as_localonexecute] + options = [mao_shortcutcaption, mao_asyncexecute] + onexecute = cutexe + sc = ( + 1 + 16472 + ) + end + item + caption = 'Paste Component(s)' + name = 'paste' + state = [as_localcaption, as_localshortcut, as_localonexecute] + onexecute = pasteexe + sc = ( + 1 + 16470 + ) + end + item + caption = 'Delete Component(s)' + name = 'delete' + state = [as_localcaption, as_localshortcut, as_localonexecute] + options = [mao_shortcutcaption, mao_asyncexecute] + onexecute = deleteexe + sc = ( + 1 + 263 + ) + end + item + caption = 'Undelete Component(s)' + name = 'undelete' + state = [as_localcaption, as_localonexecute] + onexecute = undeleteexe + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + action = actionsmo.findcompallact + caption = 'Find Component' + state = [as_localcaption] + end + item + caption = 'Select Childwidget' + name = 'selectchild' + state = [as_localcaption] + end + item + caption = '&Iconify' + name = 'iconify' + state = [as_localcaption, as_localonexecute] + onexecute = doiconify + end + item + caption = '&Deiconify' + name = 'deiconify' + state = [as_localcaption, as_localonexecute] + onexecute = dodeiconify + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = '&Edit Component' + name = 'editcomp' + state = [as_localcaption, as_localonexecute] + onexecute = doeditcomponent + end + item + caption = 'Sync. to Font Height' + name = 'synctofo' + state = [as_localcaption, as_localonexecute] + onexecute = dosyncfontheight + end + item + caption = 'Bring to Front' + name = 'bringtofro' + state = [as_localcaption, as_localonexecute] + onexecute = dobringtofront + end + item + caption = 'Send to Back' + name = 'sendtoba' + state = [as_localcaption, as_localonexecute] + onexecute = dosendtoback + end + item + caption = 'Set Widget Order' + name = 'setwidgetord' + state = [as_localcaption, as_localonexecute] + onexecute = dosetwidgetorder + end + item + caption = 'Set Tab Order' + name = 'settabord' + state = [as_localcaption, as_localonexecute] + onexecute = dosettaborder + end + item + caption = 'Set Creation Order' + state = [as_localcaption, as_localonexecute] + onexecute = dosetcreationorder + end + item + caption = 'Revert to inherited' + name = 'revert' + state = [as_localcaption, as_localonexecute] + options = [mao_shortcutcaption, mao_asyncexecute] + onexecute = revertexe + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = 'Touch Form' + state = [as_localcaption, as_localonexecute] + onexecute = dotouch + end + item + caption = 'Touch all Forms' + state = [as_localcaption, as_localonexecute] + onexecute = touchallexe + end + item + caption = 'Insert Submodule' + name = 'insertsub' + state = [as_localcaption, as_localonexecute] + onexecute = doinsertsubmodule + end + item + caption = 'Insert Component' + name = 'insertcomp' + state = [as_localcaption, as_localonexecute] + onexecute = doinsertcomponent + end> + left = 48 + top = 40 + end + object hidecompact: taction + caption = 'Hide &Components' + onchange = hidecompexe + left = 144 + top = 40 + end + object hidewidgetact: taction + caption = 'Hide &Widgets' + onupdate = updatewidgethideexe + onchange = hidewidgetexe + left = 144 + top = 56 + end + object togglehideact: taction + caption = '&Hide Widgets<>Components' + onexecute = togglehideexe + left = 144 + top = 72 + end + object showallact: taction + caption = '&Show all' + onexecute = showallexe + left = 144 + top = 88 + end + object c: tstringcontainer + strings.data = ( + 'Do you wish to revert to inherited' + 'the selected component?' + 'Do you want to touch all loaded forms?' + ) + left = 48 + top = 72 + end +end diff --git a/mseide-msegui/apps/ide/formdesigner.pas b/mseide-msegui/apps/ide/formdesigner.pas new file mode 100644 index 0000000..cf26f2d --- /dev/null +++ b/mseide-msegui/apps/ide/formdesigner.pas @@ -0,0 +1,4178 @@ +{ MSEide Copyright (c) 1999-2017 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit formdesigner; +{$ifdef FPC}{$mode objfpc}{$h+}{$GOTO ON}{$interfaces corba}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + msetypes,classes,mclasses,mseforms,mseguiglob,msegui,mseevent,msegraphutils, + msegraphics, + msedesignintf,mseclasses,msemenuwidgets,msemenus,msefiledialog,msedesigner, + typinfo,componentpaletteform,msestrings,msewidgets,msepointer, + mseglob{$ifndef mse_no_db}{$ifdef FPC},msereport{$endif}{$endif},msetimer, + mseact,mseactions,mseifiglob,msestringcontainer,mseificomp,mseificompglob, + msesimplewidgets,msestat,msedock; + +type + areaty = (ar_none,ar_component,ar_componentmove,ar_selectrect,ht_topleft, + ht_top,ht_topright,ht_right, + ht_bottomright,ht_bottom,ht_bottomleft,ht_left); + areasty = set of areaty; + markerty = (mt_topleft,mt_topright,mt_bottomright,mt_bottomleft); + +const + firsthandle = ht_topleft; + lasthandle = ht_left; + defaultgridsizex = 8; + defaultgridsizey = 8; + handlesize = 5; + componentsize = 24; + complabelleftmargin = 2; + complabelrightmargin = 2 + handlesize div 2; + movethreshold = 3; + +type + formselectedinfoty = record + selectedinfo: selectedinfoty; + rect: rectty; + nohandles: boolean; + handles: array[firsthandle..lasthandle] of rectty; + markers: array[markerty] of rectty; + end; + + pformselectedinfoty = ^formselectedinfoty; + + tformdesignerfo = class; + + markerkindty = (mak_none,mak_module,mak_all); + + tformdesignerselections = class(tdesignerselections) + private + fowner: tformdesignerfo; + finfovalid: boolean; + fmovingchecked: boolean; + fcandelete: boolean; + procedure paint(const canvas: tcanvas); + procedure beforepaintmoving; + procedure paintmoving(const canvas: tcanvas; const pos: pointty); + function move(const dist: pointty): boolean; + //false if nothing is moved + procedure resize(const dist: pointty); + procedure deletecomponents; + function getareainfo(const pos: pointty; out index: integer): areaty; + function getcandelete: boolean; + procedure updateinfos; + protected + function checkmarker(const ainfo: formselectedinfoty): markerkindty; + function getrecordsize: integer; override; + procedure externalcomponentchanged(const acomponent: tobject); + procedure removeforeign(const checkmove: boolean); + //removes form and components in other modules + property candelete: boolean read getcandelete; + public + constructor create(const owner: tformdesignerfo); + function assign(const source: idesignerselections): boolean; + //true if owned components involved + function remove(const ainstance: tcomponent): integer; override; + procedure change; override; + procedure dochanged; override; + procedure componentschanged; + function itempo(const index: integer): pformselectedinfoty; + end; + + selectmodety = (sm_select,sm_add,sm_flip,sm_remove); + + tformcontainer = class(tformscrollbox) + private + fdesignfo: tformdesignerfo; + protected + function isdesignwidget(): boolean; override; + procedure widgetregionchanged(const sender: twidget); override; + public + constructor create(const aowner: tformdesignerfo); + end; + + formdesignerstatety = (fds_loaded,fds_sizesyncing); + formdesignerstatesty = set of formdesignerstatety; + + tformdesignerdockcontroller = class(tformdockcontroller) + protected + procedure dostatplace(const aparent: twidget; + const avisible: boolean; arect: rectty); override; + end; + + tformdesignerfo = class(tdockform,iformdesigner,idesignnotification) + popupme: tpopupmenu; + hidecompact: taction; + hidewidgetact: taction; + togglehideact: taction; + showallact: taction; + c: tstringcontainer; + procedure doshowobjectinspector(const sender: tobject); + procedure doshowcomponentpalette(const sender: tobject); + procedure doshowastext(const sender: tobject); + procedure doeditcomponent(const sender: tobject); + procedure doinsertsubmodule(const sender: tobject); + procedure dobringtofront(const sender: tobject); + procedure dosendtoback(const sender: tobject); + procedure dosettaborder(const sender: tobject); + procedure dosyncfontheight(const sender: tobject); + procedure copyexe(const sender: TObject); + procedure pasteexe(const sender: TObject); + procedure deleteexe(const sender: TObject); + procedure undeleteexe(const sender: TObject); + procedure cutexe(const sender: TObject); + procedure calcscrollsize(const sender: tscrollingwidgetnwr; + var asize: sizety); + procedure formdeonclose(const sender: TObject); + procedure revertexe(const sender: TObject); + procedure doinsertcomponent(const sender: TObject); + procedure dotouch(const sender: TObject); + procedure dosetcreationorder(const sender: TObject); + procedure doiconify(const sender: TObject); + procedure dodeiconify(const sender: TObject); + procedure hidecompexe(const sender: TObject); + procedure updatewidgethideexe(const sender: tcustomaction); virtual; + procedure hidewidgetexe(const sender: TObject); + procedure togglehideexe(const sender: TObject); + procedure showallexe(const sender: TObject); + procedure touchallexe(const sender: TObject); + procedure beffloatexe(const sender: twidget; var arect: rectty); + procedure floatexe(const sender: TObject); + procedure enterexe(const sender: TObject); + procedure dosetwidgetorder(const sender: TObject); + private + fdesigner: tdesigner; + fform: twidget; + fmodule: tmsecomponent; + fmoduleintf: pdesignmoduleintfty; + fmodulesetting: integer; + fmoduleoptions: moduleoptionsty; + fsizeerrorcount: integer; + fupdatecaptionpending: boolean; + + fpickpos: pointty; + fmousepos: pointty; + fpickwidget: twidget; + fsizerect,factsizerect: rectty; + fxorpicoffset: pointty; + fxorpicactive: boolean; + fxorpicshowed: boolean; + factarea: areaty; + fmovearea: areaty; + factcompindex: integer; + fselecting: integer; + fgridsizex: integer; + fgridsizey: integer; + fsnaptogrid: boolean; + fshowgrid: boolean; + fdelobjs: objinfoarty; + fclipinitcomps: boolean; + finitcompsoffset: pointty; + fuseinitcompsoffset: boolean; + fcompsoffsetused: boolean; + fclickedcompbefore: tcomponent; + fselectwidget: twidget; + fselectcomp: tcomponent; + fclientsizevalid: boolean; + fcompoffsbefore: pointty; + fsizebefore: sizety; + fshift: pointty; + fshiftroot: tcomponent; + fhintedcomp: tcomponent; + procedure drawgrid(const canvas: tcanvas); + procedure hidexorpic(const canvas: tcanvas); + procedure showxorpic(const canvas: tcanvas); + procedure paintxorpic(const canvas: tcanvas); + procedure checkdelobjs(const aitem: tcomponent); + + procedure doaddcomponent(acomponent: tcomponent); + procedure doinitcomponent(const acomponent: tcomponent; + const parent: tcomponent); + procedure shiftcomp(child: tcomponent); + + procedure setshowgrid(const avalue: boolean); + procedure setgridsizex(const avalue: integer); + procedure setgridsizey(const avalue: integer); + procedure doundelete; + procedure dopaste(const usemousepos: boolean; const adata: string); + procedure docopy(const noclear: boolean); + procedure docut; + procedure clientsizechanged; + procedure adjustchildcomponentpos(var apos: pointty); + procedure readjustchildcomponentpos(var apos: pointty); + procedure widgetscrolled(const sender: tobject); + + + procedure setmodule(const value: tmsecomponent); + function getselections: tformdesignerselections; + function filterfindcomp(const acomponent: tcomponent): boolean; + function getmodulerect: rectty; + procedure setactarea(const avalue: areaty); + property actarea: areaty read factarea write setactarea; + protected + fselections: tformdesignerselections; + fformcont: tformcontainer; + ffostate: formdesignerstatesty; + fmoduleinfo: pmoduleinfoty; + fmodulepos: pointty; + fmodulesize: sizety; + //iformdesigner + function getmodulepos_x(): integer; + function getmodulepos_y(): integer; + procedure setmodulepos_x(const avalue: integer); + procedure setmodulepos_y(const avalue: integer); + function getdockcontroller(): tdockcontroller; + function isdesignwidget(): boolean; override; + + function getsnaptogrid: boolean; virtual; + function getshowgrid: boolean; virtual; + function getgridsizex: integer; virtual; + function getgridsizey: integer; virtual; + + procedure designmouseevent(var info: moeventinfoty; + capture: twidget); override; + procedure designkeyevent(const eventkind: eventkindty; + var info: keyeventinfoty); override; + + function getcomponentrect(const component: tcomponent; + const shiftoffset: boolean): rectty; + //embedded + + function dosnaptogrid(const apos: pointty): pointty; + function snaptogriddelta(const apos: pointty): pointty; + + function iswidgetcomp(const acomp: tcomponent): boolean; + function getcomponentrect1(const component: tcomponent): rectty; + //top level + function componentscrollsize: sizety; + function componentoffset(): pointty; + function componentatpos(const apos: pointty): tcomponent; + function widgetatpos(const apos: pointty; const onlywidgets: boolean; + const everywhere: boolean = false): twidget; + procedure updateselections; + + procedure setrootpos(const component: tcomponent; const apos: pointty); + procedure beginselect; + procedure endselect; + procedure updatecursorshape(const ashiftstate: shiftstatesty; + const area: areaty); + procedure updateclickedcomponent; + procedure deletecomponent(const component: tcomponent); + procedure selectparentwidget(const awidget: twidget); + procedure domodified; + + procedure selectchildexec(const sender: tobject); + procedure dopopup(var info: mouseeventinfoty); reintroduce; + + property selections: tformdesignerselections read getselections; + procedure formcontainerscrolled(); + procedure updatemodulename(); + procedure doupdatecaption(); + procedure updatedockinfo(); + procedure updateformcont(); + procedure checksynctoformsize(); + procedure checksynctomodulepos(); + procedure formcontainerwidgetregionchanged(const sender: twidget); + procedure rootchanged(const aflags: rootchangeflagsty); override; + procedure parentchanged(); override; + procedure poschanged; override; + procedure sizechanged; override; + procedure clientrectchanged(); override; + procedure doasyncevent(var atag: integer); override; + procedure dobeforepaint(const canvas: tcanvas); override; + procedure doafterpaint(const canvas: tcanvas); override; + procedure doactivate; override; + procedure validaterename(acomponent: tcomponent; + const curname, newname: string); override; + procedure notification(acomponent: tcomponent; + operation: toperation); override; + procedure doshow; override; + + procedure componentselected( + const aselections: tformdesignerselections); virtual; + function getmoduleparent: twidget; virtual; + function getmodulesize: sizety; virtual; + function insertoffset: pointty; virtual; + function gridoffset: pointty; virtual; + function gridrect: rectty; virtual; + function markerrect: rectty; virtual; + function widgetrefpoint: pointty; virtual; + function compplacementrect: rectty; virtual; + procedure recalcclientsize; + procedure setcomponentscrollsize(const avalue: sizety); virtual; + function fixformsize: boolean; virtual; + function getdesignrect: rectty; virtual; + procedure setdesignrect(const arect: rectty); virtual; + function checkdelete(): boolean; virtual; + function dodelete: boolean; //true if ok + procedure componentmoving(const apos: pointty); virtual; + procedure placecomponent(const component: tcomponent; const apos: pointty; + aparent: tcomponent = nil); virtual; + function getmoduleoptions: moduleoptionsty; + procedure setmoduleoptions(const aoptions: moduleoptionsty); virtual; + + //idesignnotification + procedure itemdeleted(const adesigner: idesigner; + const amodule: tmsecomponent; const aitem: tcomponent); + procedure iteminserted(const adesigner: idesigner; + const amodule: tmsecomponent; const aitem: tcomponent); + procedure itemsmodified(const adesigner: idesigner; const aitem: tobject); + procedure componentnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const aitem: tcomponent; + const newname: string); + procedure moduleclassnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); + procedure instancevarnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); + procedure selectionchanged(const adesigner: idesigner; + const aselection: idesignerselections); + procedure moduleactivated(const adesigner: idesigner; + const amodule: tmsecomponent); + procedure moduledeactivated(const adesigner: idesigner; + const amodule: tmsecomponent); + procedure moduledestroyed(const adesigner: idesigner; + const amodule: tmsecomponent); + procedure methodcreated(const adesigner: idesigner; + const amodule: tmsecomponent; + const aname: string; const atype: ptypeinfo); + procedure methodnamechanged(const adesigner: idesigner; + const amodule: tmsecomponent; + const newname,oldname: string; + const atypeinfo: ptypeinfo); + procedure showobjecttext(const adesigner: idesigner; + const afilename: filenamety; const backupcreated: boolean); + procedure closeobjecttext(const adesigner: idesigner; + const afilename: filenamety; var cancel: boolean); + procedure beforefilesave(const adesigner: idesigner; + const afilename: filenamety); + procedure beforemake(const adesigner: idesigner; const maketag: integer; + var abort: boolean); + procedure aftermake(const adesigner: idesigner; const exitcode: integer); + + public + constructor create(const aowner: tcomponent; const adesigner: tdesigner; + const aintf: pdesignmoduleintfty; + const amoduleinfo: pmoduleinfoty); reintroduce; virtual; + + destructor destroy(); override; + procedure updateprojectoptions(); + + function designnotification: idesignnotification; + //idesignform + property moduleoptions: moduleoptionsty read getmoduleoptions + write setmoduleoptions; + function clickedcomponent: tcomponent; + property modulerect: rectty read getmodulerect; + procedure updatecaption(); + procedure placemodule(); virtual; + procedure beginplacement(); + procedure endplacement(); + procedure beginstreaming(); virtual; + procedure endstreaming(); virtual; + procedure findcompdialog(); + procedure clearselection; + procedure selectcomponent(const component: tcomponent; + mode: selectmodety = sm_select); + //component can be nil + + property module: tmsecomponent read fmodule write setmodule; + property form: twidget read fform; + + property snaptogrid: boolean read getsnaptogrid write + fsnaptogrid default true; + property showgrid: boolean read getshowgrid write setshowgrid default true; + property gridsizex: integer read getgridsizex write setgridsizex + default defaultgridsizex; + property gridsizey: integer read getgridsizey write setgridsizey + default defaultgridsizey; + end; + + designformclassty = class of tformdesignerfo; +{ + tdesignwindow = class(twindow) + private + protected + procedure movewindowrect(const dist: pointty; const rect: rectty); override; + public + constructor create(const aowner: tformdesignerfo); +// destructor destroy; override; + end; +} +procedure registerdesignmoduleclass(const aclass: tcomponentclass; + const aintf: pdesignmoduleintfty; + const adesignformclass: designformclassty = nil); +function createdesignmodule(const amodule: pmoduleinfoty; designmoduleclassname: string; + const aclassname: pshortstring): tmsecomponent; +function createdesignform(const aowner: tdesigner; + const amodule: pmoduleinfoty): tformdesignerfo; +function selectinheritedmodule(const amodule: pmoduleinfoty; + const caption: msestring = ''): pmoduleinfoty; +function getdesignform(const acomp: tcomponent): tformdesignerfo; + +implementation +uses + formdesigner_mfm,mselist,msekeyboard,msebits,sysutils, + msestockobjects,msedrawtext,selectsubmoduledialogform,mseshapes,settaborderform, + msedatalist,objectinspector,projectoptionsform,main,msedatamodules, + setcreateorderform,componentstore,msearrayutils,actionsmodule,msecomptree + {$ifndef FPC},classes_del{$endif}; + +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + stringconsts = ( + sc_wishrevert, //0 Do you wish to revert to inherited + sc_selectedcomp, //1 the selected component? + sc_touchall //2 Do you want to touch all loaded forms? + ); + + tcomponent1 = class(tcomponent); + tmsecomponent1 = class(tmsecomponent); + twidget1 = class(twidget); + tmseform1 = class(tmseform); + tframe1 = class(tframe); + tscrollingwidget1 = class(tscrollingwidget); + twindow1 = class(twindow); + tcustomframe1 = class(tcustomframe); + + designerfoeventty = (fde_none,fde_syncsize,fde_updatecaption,fde_scrolled, + fde_showastext); + + designmoduleinfoty = record + classtype: tcomponentclass; + intf: pdesignmoduleintfty; + formclass: designformclassty; + end; + designmoduleinfoarty = array of designmoduleinfoty; + + tdesignmoduleinfoar = class + private + flist: designmoduleinfoarty; + end; + +var + fregistereddesignmoduleclasses: tdesignmoduleinfoar; + +function registereddesignmoduleclasses: tdesignmoduleinfoar; +begin + if fregistereddesignmoduleclasses = nil then begin + fregistereddesignmoduleclasses:= tdesignmoduleinfoar.create; + end; + result:= fregistereddesignmoduleclasses; +end; + +procedure registerdesignmoduleclass(const aclass: tcomponentclass; + const aintf: pdesignmoduleintfty; + const adesignformclass: designformclassty = nil); +var + int1: integer; +begin + with registereddesignmoduleclasses do begin + for int1:= 0 to high(flist) do begin + with flist[int1] do begin + if classtype = aclass then begin + intf:= aintf; + formclass:= adesignformclass; + exit; + end; + end; + end; + registerclass(aclass); + setlength(flist,high(flist)+2); + with flist[high(flist)] do begin + classtype:= aclass; + intf:= aintf; + formclass:= adesignformclass; + end; + end; +end; + +function createdesignmodule(const amodule: pmoduleinfoty; designmoduleclassname: string; + const aclassname: pshortstring): tmsecomponent; +var + int1: integer; +begin + with amodule^ do begin + if designmoduleclassname = '' then begin + designmoduleclassname:= defaultmoduleclassname; + end; + designmoduleclassname:= uppercase(designmoduleclassname); + with registereddesignmoduleclasses do begin + for int1:= 0 to high(flist) do begin + with flist[int1] do begin + if uppercase(classtype.classname) = designmoduleclassname then begin + designformclass:= formclass; + moduleintf:= intf; + result:= intf^.createfunc(classtype,aclassname); + exit; + end; + end; + end; + end; + end; + raise exception.Create(ansistring(actionsmo.c[ord(ac_unknownmodclass)]+ + msestring(aclassname^) +'": "'+ msestring(designmoduleclassname)+'".')); +end; + +function createdesignform(const aowner: tdesigner; + const amodule: pmoduleinfoty): tformdesignerfo; +begin + with amodule^ do begin + if designformclass = nil then begin + designformclass:= tformdesignerfo; + end; + result:= designformclassty(designformclass).create(nil,aowner, + moduleintf,amodule); + result.module:= instance; + end; +end; +{ +function getcomponentrect(const sender: twidget; + const component: tcomponent): rectty; +begin + result.pos:= getcomponentpos(component); + addpoint1(result.pos,tdesignwindow(sender.window).componentoffset); + result.cx:= componentsize + complabelleftmargin + + sender.getcanvas.getstringwidth(component.name) + + complabelrightmargin; + result.cy:= componentsize; +end; + +function getcomponentrect1(const sender: twidget; const component: tcomponent; + const module: tcomponent): rectty; +var + comp1: tcomponent; + bo1: boolean; +begin + result:= getcomponentrect(sender,component); + if module is twidget then begin + comp1:= component; + bo1:= false; + while (comp1 <> module) and (comp1 <> nil) do begin + if comp1 is twidget then begin + if not bo1 then begin + tdesignwindow(sender.window).adjustchildcomponentpos(result.pos); + bo1:= true; + end; + addpoint1(result.pos,twidget(comp1).pos); + end; + comp1:= comp1.owner; + end; + end; +end; +} + +{ tformdesignerselections } + +constructor tformdesignerselections.create(const owner: tformdesignerfo); +begin + fowner:= owner; + inherited create; +end; + +function tformdesignerselections.assign( + const source: idesignerselections): boolean; + //true if owned components involved +var + amodule: tmsecomponent; + ar1: booleanarty; + + procedure checkowned; + var + int1: integer; + comp1: tcomponent; + po1: pformselectedinfoty; + begin + result:= false; + setlength(ar1,count); + po1:= datapo; + for int1:= 0 to count - 1 do begin + result:= po1^.selectedinfo.instance = amodule; + comp1:= po1^.selectedinfo.instance; + while comp1 <> nil do begin + if comp1 = amodule then begin + result:= true; + ar1[int1]:= true; + break; + end; + comp1:= comp1.owner; + end; + inc(po1); + end; + end; + +var + int1: integer; + po1: pformselectedinfoty; + comp1: tcomponent; + bo1,bo2: boolean; +begin + result:= false; + ar1:= nil; + amodule:= fowner.fmodule; + checkowned; + inherited assign(source); + if not result then begin + checkowned; + end; + if result then begin + bo1:= false; + bo2:= false; + po1:= datapo; + for int1:= 0 to count - 1 do begin + comp1:= po1^.selectedinfo.instance; + while (comp1 <> nil) and (comp1 <> amodule) do begin + if ar1[int1] then begin + if (comp1 is tmsedatamodule) and (comp1 <> + po1^.selectedinfo.instance) then begin + with tmsedatamodule(comp1) do begin + options:= options - [dmo_iconic]; + end; + end; + + if fowner.iswidgetcomp(comp1) then begin + bo1:= true; + end + else begin + bo2:= true; + end; + end; + comp1:= comp1.owner; + end; + inc(po1); + end; + with fowner do begin + if bo1 then begin + hidewidgetact.checked:= false; + end; + if bo2 then begin + hidecompact.checked:= false; + end; + end; + end; +end; + +procedure tformdesignerselections.updateinfos; +var + marker: markerty; + int1: integer; +begin + if not finfovalid then begin + fcandelete:= count > 0; + for int1:= 0 to count - 1 do begin + with itempo(int1)^,selectedinfo do begin + if fowner.iswidgetcomp(instance) then begin + with twidget1(instance) do begin + nohandles:= ws1_nodesignhandles in fwidgetstate1; + fcandelete:= fcandelete and not (ws1_nodesigndelete in fwidgetstate1); + rect:= makerect(translatewidgetpoint(pos,parentwidget,fowner),size); + end; + end + else begin + nohandles:= false; + if instance is tcomponent then begin + rect:= fowner.getcomponentrect1(tcomponent(instance)); + end + else begin + rect:= nullrect; + end; + end; + with rect do begin + centerrect(pos,handlesize,handles[ht_topleft]); + centerrect(makepoint(x+cx div 2,y),handlesize,handles[ht_top]); + centerrect(makepoint(x+cx-1,y),handlesize,handles[ht_topright]); + centerrect(makepoint(x+cx-1,y+cy div 2),handlesize,handles[ht_right]); + centerrect(makepoint(x+cx-1,y+cy-1),handlesize,handles[ht_bottomright]); + centerrect(makepoint(x+cx div 2,y+cy-1),handlesize,handles[ht_bottom]); + centerrect(makepoint(x,y+cy-1),handlesize,handles[ht_bottomleft]); + centerrect(makepoint(x,y+cy div 2),handlesize,handles[ht_left]); + + for marker:= low(marker) to high(marker) do begin + markers[marker].cx:= handlesize; + markers[marker].cy:= handlesize; + end; + markers[mt_topleft].pos:= pos; + markers[mt_topright].x:= x + cx - handlesize; + markers[mt_topright].y:= y; + markers[mt_bottomright].x:= x + cx - handlesize; + markers[mt_bottomright].y:= y + cy - handlesize; + markers[mt_bottomleft].x:= x; + markers[mt_bottomleft].y:= y + cy - handlesize; + + end; + end; + end; + end; + finfovalid:= true; +end; + +procedure tformdesignerselections.beforepaintmoving; +begin + if not fmovingchecked then begin + removeforeign(true); + fmovingchecked:= true; + end; + updateinfos; +end; + +procedure tformdesignerselections.paintmoving(const canvas: tcanvas; + const pos: pointty); +var + int1: integer; + po1: pformselectedinfoty; +begin +// beforepaintmoving; + with canvas do begin + save; + move(pos); + rasterop:= rop_xor; + for int1:= 0 to count-1 do begin + po1:= itempo(int1); + if po1^.selectedinfo.instance <> fowner.module then begin + drawframe(itempo(int1)^.rect,-2,cl_white); + end; + end; + restore; + end; +end; + +function tformdesignerselections.checkmarker( + const ainfo: formselectedinfoty): markerkindty; +begin + result:= mak_none; + with ainfo do begin + if not nohandles then begin + if fowner.module.checkowned(selectedinfo.instance) then begin + if (selectedinfo.instance <> fowner.module) then begin + if (selectedinfo.instance is twidget) and + (ws1_nodesignmove in + twidget1(selectedinfo.instance).fwidgetstate1) then begin + result:= mak_module; + end + else begin + result:= mak_all; + end; + end + else begin + if (fowner.parentwidget <> nil) and (fowner.fform <> nil) and + (fowner.fformcont.visible) then begin //docked + result:= mak_module; + end; + end; + end; + end; + end; +end; + +procedure tformdesignerselections.paint(const canvas: tcanvas); + +var + int1: integer; + handle: areaty; + marker: markerty; + po1: pformselectedinfoty; +begin + updateinfos(); + po1:= datapo; + with canvas do begin + if count > 1 then begin + for int1:= 0 to count - 1 do begin + case checkmarker(po1^) of + mak_all: begin + for marker:= low(markerty) to high(markerty) do begin + fillrect(po1^.markers[marker],cl_dkgray); + end; + end; + mak_module: begin + canvas.save(); + canvas.addcliprect(fowner.markerrect); + fillrect(po1^.markers[mt_bottomright],cl_dkgray); + canvas.restore; + end; + end; + inc(po1); + end; + end + else begin + for int1:= 0 to count - 1 do begin + case checkmarker(po1^) of + mak_all: begin + for handle:= firsthandle to lasthandle do begin + fillrect(po1^.handles[handle],cl_black); + end; + end; + mak_module: begin + canvas.save(); + canvas.addcliprect(fowner.markerrect); + fillrect(po1^.handles[ht_right],cl_black); + fillrect(po1^.handles[ht_bottomright],cl_black); + fillrect(po1^.handles[ht_bottom],cl_black); + canvas.restore(); + end; + end; + inc(po1); + end; + end; + end; +end; + +function tformdesignerselections.move(const dist: pointty): boolean; +var + int1,int2: integer; + widget1: twidget; + comp1,comp2: tcomponent; + rect1,rect2: rectty; + pt1: pointty; + ar1: componentarty; +begin + result:= false; + if (dist.x <> 0) or (dist.y <> 0) then begin + setlength(ar1,count); + for int1:= 0 to high(ar1) do begin + comp1:= items[int1]; + while fowner.iswidgetcomp(comp1) and + (cs_parentwidgetrect in twidget1(comp1).fmsecomponentstate) do begin + comp1:= twidget(comp1).parentwidget; + end; + ar1[int1]:= comp1; + end; + for int1:= 0 to high(ar1) do begin + comp1:= ar1[int1]; + for int2:= int1 + 1 to high(ar1) do begin + if ar1[int2] = comp1 then begin + ar1[int2]:= nil; //remove duplicates + end; + end; + end; + for int1:= 0 to count - 1 do begin + comp1:= ar1[int1]; + if comp1 <> nil then begin + with itempo(int1)^,selectedinfo do begin + if fowner.iswidgetcomp(comp1) and (comp1 <> fowner.module) then begin + if not nohandles then begin + widget1:= twidget(comp1).parentwidget; + while widget1 <> nil do begin + if (widget1 <> fowner.form) and (indexof(widget1) >= 0) then begin + break; //moved by parent + end; + widget1:= widget1.parentwidget; + end; + if widget1 = nil then begin + with twidget(comp1) do begin + pos:= addpoint(pos,dist); + result:= true; + end; + end; + end; + end + else begin + comp2:= tcomponent(comp1).owner; + while comp2 <> nil do begin + if (comp2 <> fowner.module) and + (fowner.iswidgetcomp(comp2) or isdatasubmodule(comp2)) and + (indexof(comp2) >= 0) then begin + break; //moved by owner + end; + comp2:= comp2.owner; + end; + if comp2 = nil then begin + rect1:= fowner.getcomponentrect1(tcomponent(comp1)); + fowner.invalidaterect(rect1); + pt1:= rect1.pos; + addpoint1(rect1.pos,dist); + with fowner do begin + rect2:= compplacementrect; + if form <> nil then begin + shiftinrect(rect1,rect2); + end + else begin + if rect1.x < rect2.x then begin + rect1.x:= rect2.x; + end; + if rect1.y < rect2.y then begin + rect1.y:= rect2.y; + end; + end; + end; + setcomponentpos(comp1,addpoint(getcomponentpos(comp1), + subpoint(rect1.pos,pt1))); + fowner.invalidaterect(rect1); + result:= true; + end; + end; + end; + end; + end; + componentschanged; + end; +end; + +procedure tformdesignerselections.resize(const dist: pointty); +var + int1: integer; +begin + if (dist.x <> 0) or (dist.y <> 0) then begin + for int1:= 0 to count - 1 do begin + with itempo(int1)^,selectedinfo do begin + if not nohandles then begin + if fowner.iswidgetcomp(instance) then begin + with twidget(instance) do begin + size:= sizety(addpoint(pointty(size),dist)); + end; + end + else begin + if isdatasubmodule(instance) then begin + with tmsedatamodule(instance) do begin + size:= sizety(addpoint(pointty(size),dist)); + end; + end; + end; + end; + end; + end; + componentschanged; + end; +end; + +procedure tformdesignerselections.change; +begin + finfovalid:= false; + fmovingchecked:= false; + inherited; +end; + +procedure tformdesignerselections.dochanged; +begin + inherited; + fowner.invalidate; +end; + +procedure tformdesignerselections.componentschanged; +var + int1: integer; +begin + change; + for int1:= 0 to count - 1 do begin + fowner.fdesigner.componentmodified(items[int1]); + end; +end; + +procedure tformdesignerselections.externalcomponentchanged( + const acomponent: tobject); +begin + finfovalid:= false; + if count > 0 then begin + fowner.invalidate; + end; +end; + +const + validhandles: array[markerkindty] of areasty = ( + [], //mak_none + [ht_right,ht_bottomright,ht_bottom], //mak_module + [ht_topleft,ht_top,ht_topright,ht_right, + ht_bottomright,ht_bottom,ht_bottomleft,ht_left] //mak_all + ); + +function tformdesignerselections.getareainfo(const pos: pointty; + out index: integer): areaty; +var + handle: areaty; + int1: integer; + po1: pformselectedinfoty; + markerkind1: markerkindty; + bo1: boolean; +begin + updateinfos; + result:= ar_none; + index:= -1; + if pointinrect(pos,fowner.markerrect) then begin + bo1:= pointinrect(pos,fowner.gridrect); + po1:= datapo; + if count = 1 then begin + markerkind1:= checkmarker(po1^); + if (markerkind1 = mak_module) or bo1 then begin + with po1^,selectedinfo do begin + if not nohandles then begin + if instance is tcomponent then begin + if isdatasubmodule(instance) or fowner.iswidgetcomp(instance) and + not (cs_parentwidgetrect in + twidget1(instance).fmsecomponentstate) then begin + for handle:= firsthandle to lasthandle do begin + if pointinrect(pos,handles[handle]) then begin + if handle in validhandles[markerkind1] then begin + result:= handle; + index:= 0; + exit; + end; + end; + end; + end; + if pointinrect(pos,rect) then begin + result:= ar_component; + index:= 0; + exit; + end; + end; + end; + end; + end; + end + else begin + for int1:= 0 to count - 1 do begin + with po1^,selectedinfo do begin + if not nohandles then begin + if pointinrect(pos,rect) and (instance is tcomponent) and + (bo1 or (checkmarker(po1^) = mak_module)) then begin + result:= ar_component; + index:= int1; + break; + end; + end; + end; + inc(po1); + end; + end; + end; +end; + +procedure tformdesignerselections.deletecomponents; +begin + fowner.fDesigner.DeleteSelection; +end; + +function tformdesignerselections.getrecordsize: integer; +begin + result:= sizeof(formselectedinfoty); +end; + +function tformdesignerselections.itempo( + const index: integer): pformselectedinfoty; +begin + result:= pformselectedinfoty(getitempo(index)); +end; + +function tformdesignerselections.remove( + const ainstance: tcomponent): integer; +begin + if ainstance = fowner.fpickwidget then begin + fowner.fpickwidget:= nil; + end; + result:= inherited remove(ainstance); +end; + +procedure tformdesignerselections.removeforeign(const checkmove: boolean); + //removes form and components in other modules +var + int1: integer; + co1: tcomponent; +begin + beginupdate; + for int1:= count - 1 downto 0 do begin + co1:= items[int1]; + if (co1 = fowner.module) or not fowner.module.checkowned(co1) or + (checkmove and (co1 is twidget) and + (ws1_nodesignmove in twidget1(co1).fwidgetstate1)) then begin + delete(int1); + end; + end; + endupdate; + fowner.updateselections; +end; + +function tformdesignerselections.getcandelete: boolean; +begin + updateinfos; + result:= fcandelete; +end; + +{ tformcontainer } + +constructor tformcontainer.create(const aowner: tformdesignerfo); +begin + fdesignfo:= aowner; + inherited create(nil,aowner,false); + with tcustomframe1(fframe),fi.innerframe do begin + left:= 0; + top:= 0; + right:= 0; + bottom:= 0; + internalupdatestate(); + end; + createface(); + face.image.source:= mainfo.formbg; + face.image.alignment:= [al_tiled]; + color:= cl_background; + optionsskin:= [osk_framebuttononly]; + updateskin(); +end; + +procedure tformcontainer.widgetregionchanged(const sender: twidget); +begin + inherited; + fdesignfo.formcontainerwidgetregionchanged(sender); +end; + +function tformcontainer.isdesignwidget: boolean; +begin + result:= true; +end; + +{ tformdesignerfo } + +constructor tformdesignerfo.create(const aowner: tcomponent; + const adesigner: tdesigner; + const aintf: pdesignmoduleintfty; + const amoduleinfo: pmoduleinfoty); +begin + fdesigner:= adesigner; + fmoduleintf:= aintf; + fmoduleinfo:= amoduleinfo; + + fshowgrid:= true; + fsnaptogrid:= true; + fgridsizex:= defaultgridsizex; + fgridsizey:= defaultgridsizey; + fselections:= tformdesignerselections.create(self); + fformcont:= tformcontainer.create(self); + fdragdock:= tformdesignerdockcontroller.create(self); + + createwindow(); + inherited create(aowner); + updateprojectoptions(); + designnotifications.registernotification(idesignnotification(self)); + include(ffostate,fds_loaded); +end; + +destructor tformdesignerfo.destroy; +begin + if fwindow <> nil then begin + fwindow.unregisteronscroll(@widgetscrolled); + end; + designer.modules.designformdestroyed(self); + fmodule.free(); + designnotifications.unregisternotification(idesignnotification(self)); + inherited; + fformcont.free(); + fselections.free(); +end; + +procedure tformdesignerfo.rootchanged(const aflags: rootchangeflagsty); +begin + if (rcf_windowremove in aflags) and (fwindow <> nil) then begin + fwindow.unregisteronscroll(@widgetscrolled); + end; + inherited; + if (rcf_windowset in aflags) then begin + window.registeronscroll(@widgetscrolled); + end; +end; + +procedure tformdesignerfo.parentchanged(); +begin + inherited; +// checksynctoformsize(); + updateformcont(); + updatedockinfo(); +end; + +procedure tformdesignerfo.ValidateRename(AComponent: TComponent; + const CurName, NewName: string); +begin + inherited; + if (fdesigner <> nil) and (acomponent <> nil) and + not (csdestroying in acomponent.componentstate) then begin + fdesigner.validaterename(acomponent,curname,newname); + end; +end; + +procedure tformdesignerfo.notification(acomponent: tcomponent; + operation: toperation); +begin + if (operation = opremove) then begin + if (acomponent = fmodule) then begin + fmodule:= nil; + end; + if (acomponent = fhintedcomp) then begin + fhintedcomp:= nil; + end; + end; + inherited; +end; +{ +procedure tformdesignerfo.createwindow; +begin + tdesignwindow.create(self); +end; +} +function tformdesignerfo.designnotification: idesignnotification; +begin + result:= idesignnotification(self); +end; + +function tformdesignerfo.getcomponentrect1(const component: tcomponent): rectty; +var + comp1: tcomponent; + bo1: boolean; +begin + result:= getcomponentrect(component,true); + comp1:= component.owner; + while comp1 <> nil do begin + if isdatasubmodule(comp1) then begin //adjust submodulepos + addpoint1(result.pos,getcomponentpos(comp1)); + end; + comp1:= comp1.owner; + end; + if fform <> nil then begin + comp1:= component.owner; + bo1:= false; + while (comp1 <> module) and (comp1 <> nil) do begin + if iswidgetcomp(comp1) then begin + if not bo1 then begin + adjustchildcomponentpos(result.pos); + bo1:= true; + end; + addpoint1(result.pos,twidget(comp1).pos); + end; + comp1:= comp1.owner; + end; + end; +end; + +function tformdesignerfo.iswidgetcomp(const acomp: tcomponent): boolean; +begin + result:= (acomp is twidget) and (form <> nil) and + (twidget(acomp).parentwidget <> nil); +end; + +procedure tformdesignerfo.paintxorpic(const canvas: tcanvas); +begin + if fxorpicactive then begin + canvas.save; + canvas.setcliprect(markerrect); + case actarea of + firsthandle..lasthandle: begin + with canvas do begin + save; + rasterop:= rop_xor; + drawframe(factsizerect,-2,cl_white); + restore; + end; + end; + ar_componentmove: begin + fselections.paintmoving(canvas,fxorpicoffset); + end; + ar_selectrect: begin + with canvas do begin + drawxorframe(fpickpos,fxorpicoffset,1,stockobjects.bitmaps[stb_block3]); + end; + end; + end; + canvas.restore; + end; +end; + +procedure tformdesignerfo.hidexorpic(const canvas: tcanvas); +begin + if fxorpicshowed then begin + paintxorpic(canvas); + fxorpicshowed:= false; + end; +end; + +procedure tformdesignerfo.showxorpic(const canvas: tcanvas); +begin + if not fxorpicshowed then begin + paintxorpic(canvas); + fxorpicshowed:= true; + end; +end; + +procedure tformdesignerfo.adjustchildcomponentpos(var apos: pointty); +begin + subpoint1(apos,componentoffset); + addpoint1(apos,widgetrefpoint); +end; + +procedure tformdesignerfo.readjustchildcomponentpos(var apos: pointty); +begin + addpoint1(apos,componentoffset); + subpoint1(apos,widgetrefpoint); +end; + +procedure tformdesignerfo.widgetscrolled(const sender: tobject); +begin + fselections.change(); +end; + +function tformdesignerfo.getcomponentrect(const component: tcomponent; + const shiftoffset: boolean): rectty; +var + bo1: boolean; +begin + result.pos:= getcomponentpos(component); + if shiftoffset then begin + addpoint1(result.pos,componentoffset); + end; + bo1:= (component is tmsedatamodule) and + (csinline in tmsedatamodule(component).componentstate); + if bo1 and not (dmo_iconic in tmsedatamodule(component).options) then begin + result.size:= tmsedatamodule(component).size; + end + else begin + result.cx:= complabelleftmargin + + getcanvas.getstringwidth(msestring(component.name)) + + complabelrightmargin; + if not bo1 then begin + result.cx:= result.cx + componentsize; + end; + result.cy:= componentsize; + end; +end; + +function tformdesignerfo.componentscrollsize: sizety; + + procedure check(const acomponent: tcomponent; const shift: pointty); + var + int1,int2: integer; + component: tcomponent; + rect1: rectty; + begin + if acomponent <> nil then begin + with acomponent do begin + for int1:= 0 to componentcount - 1 do begin + component:= components[int1]; + if not iswidgetcomp(component) then begin + rect1:= getcomponentrect(component,false); + addpoint1(rect1.pos,shift); + int2:= rect1.x + rect1.cx; + if int2 > result.cx then begin + result.cx:= int2; + end; + int2:= rect1.y + rect1.cy; + if int2 > result.cy then begin + result.cy:= int2; + end; + if isdatasubmodule(component) then begin + check(component,rect1.pos); + end; + end; + end; + end; + end; + end; //check + +begin + result:= nullsize; + check(fmodule,nullpoint); + inc(result.cx,handlesize); + inc(result.cy,handlesize); +end; + +procedure tformdesignerfo.doaddcomponent(acomponent: tcomponent); +var + comp1: tcomponent; + comps: tfplist; +begin + comp1:= acomponent.owner; + if (comp1 <> nil) and not issubcomponent(fmodule,comp1) then begin + {$ifdef FPC}{$warnings off}{$endif} + with tcomponent1(comp1) do begin + {$ifdef FPC}{$warnings on}{$endif} + comps:= fcomponents; + fcomponents:= nil; //do not propagate freenotifiaction to children + comp1.removecomponent(acomponent); + if comps <> nil then begin + comps.remove(acomponent); + if comps.count = 0 then begin + comps.free; + end + else begin + fcomponents:= comps; + end; + end; + end; + end; + fdesigner.addcomponent(module,acomponent); +// if csinline in component.ComponentState then begin + if acomponent.ComponentState * [csancestor,csinline] <> [] then begin + tcomponent1(acomponent).getchildren( + {$ifdef FPC}@{$endif}doaddcomponent,acomponent); + if comp1 <> nil then begin + tcomponent1(acomponent).getchildren( + {$ifdef FPC}@{$endif}doaddcomponent,comp1); + end; + end + else begin +// if comp1 <> nil then begin //else submodule + tcomponent1(acomponent).getchildren( + {$ifdef FPC}@{$endif}doaddcomponent,comp1); + end; +end; + +procedure tformdesignerfo.shiftcomp(child: tcomponent); +begin + setcomponentpos(child,addpoint(getcomponentpos(child),fshift)); + tcomponent1(child).getchildren(@shiftcomp,fshiftroot); +end; + +procedure tformdesignerfo.doinitcomponent(const acomponent: tcomponent; + const parent: tcomponent); +var + rect1: rectty; + pt1,pt2: pointty; +begin + doaddcomponent(acomponent); + if (acomponent is twidget) and (parent is twidget) then begin + with twidget(acomponent) do begin + if fuseinitcompsoffset then begin + pt1:= finitcompsoffset; + subpoint1(finitcompsoffset,pos); + fcompsoffsetused:= true; + fuseinitcompsoffset:= false; + end + else begin + if fcompsoffsetused then begin + pt1:= addpoint(pos,finitcompsoffset); + end + else begin + pt1:= addpoint(pos,twidget(parent).containeroffset); + end; + end; + end; + twidget(parent).insertwidget(twidget(acomponent),pt1); + if fclipinitcomps then begin + rect1:= twidget(acomponent).widgetrect; + shiftinrect(rect1,twidget(acomponent).parentwidget.clientwidgetrect); + twidget(acomponent).widgetrect:= rect1; + end; + end + else begin + pt2:= getcomponentpos(acomponent); + if fuseinitcompsoffset then begin + pt1:= finitcompsoffset; + subpoint1(finitcompsoffset,pt2); + fcompsoffsetused:= true; + fuseinitcompsoffset:= false; + end + else begin + pt1:= pt2; + if fcompsoffsetused then begin + addpoint1(pt1,finitcompsoffset); + end; + end; + setcomponentpos(acomponent,pt1); + fshiftroot:= acomponent.owner; + fshift:= subpoint(pt1,pt2); + tcomponent1(acomponent).getchildren(@shiftcomp,fshiftroot); + end; +end; + +procedure tformdesignerfo.docopy(const noclear: boolean); +var + int1: integer; + widget1: twidget; +begin + fselections.remove(module); + fselections.copytoclipboard; + if not noclear then begin + if form = nil then begin + selectcomponent(fmodule); + end + else begin + widget1:= nil; + if (fselections.count > 0) and iswidgetcomp(fselections[0]) then begin + widget1:= twidget(fselections[0]).parentofcontainer; + for int1:= 1 to fselections.count - 1 do begin + if not iswidgetcomp(fselections[int1]) or + (twidget(fselections[int1]).parentofcontainer <> widget1) then begin + widget1:= nil; //no common parent + break; + end; + end; + end; + if widget1 = nil then begin + selectcomponent(module); + end + else begin + selectcomponent(widget1); + end; + end; + end; +end; + +procedure tformdesignerfo.docut(); +begin + docopy(true); + dodelete(); +end; + +procedure tformdesignerfo.dopaste(const usemousepos: boolean; + const adata: string); +var + comp1: tcomponent; + bo1: boolean; +begin + try +// if form <> nil then begin + fclipinitcomps:= not usemousepos; + comp1:= module; + bo1:= true; + fuseinitcompsoffset:= usemousepos; + fcompsoffsetused:= false; + finitcompsoffset:= dosnaptogrid(fmousepos); + with fselections do begin + if count = 1 then begin + comp1:= items[0]; + if iswidgetcomp(comp1) then begin + bo1:= form.checkdescendent(twidget(comp1)); + if usemousepos then begin + finitcompsoffset:= + translatewidgetpoint(finitcompsoffset,self,twidget(comp1)); + end; + end; + end; + if bo1 then begin + clear; + if adata <> '' then begin + pastefromobjecttext(adata,module,comp1, + {$ifdef FPC}@{$endif}doinitcomponent); + end + else begin + pastefromclipboard(module,comp1,{$ifdef FPC}@{$endif}doinitcomponent); + end; + updateselections; + designer.componentmodified(module); + end; + end; + finally + fclipinitcomps:= false; + end; + clientsizechanged; +end; + +procedure tformdesignerfo.doundelete(); +var + int1: integer; + ar1: componentarty; +begin + if fdelobjs <> nil then begin + with fselections do begin + clear; + for int1:= 0 to high(fdelobjs) do begin + with fdelobjs[int1] do begin + ar1:= pastefromobjecttext(objtext,owner,parent, + {$ifdef FPC}@{$endif}doinitcomponent); + if ar1 <> nil then begin + if (owner <> nil) and (ownerindex >= 0) then begin + ar1[0].componentindex:= ownerindex; + end; + if (parent <> nil) and (parentindex >= 0) then begin + {$warnings off} + tcomponent1(parent).setchildorder(ar1[0],parentindex); + {$warnings on} + end; + end; + if parent <> nil then begin + + designer.componentmodified(parent); + end + else begin + designer.componentmodified(owner); + end; + end; + end; + for int1:= count-1 downto 0 do begin + if isembedded(items[int1]) then begin + delete(int1); + end; + end; + end; + updateselections; + fdelobjs:= nil; + clientsizechanged; + end; +end; + +function tformdesignerfo.dodelete(): boolean; +var + int1: integer; +begin + result:= false; + if checkdelete() then begin + with fselections do begin + for int1:= 0 to count - 1 do begin + with items[int1] do begin + if componentstate * [csancestor,csinline] = [csancestor] then begin + showmessage(actionsmo.c[ord(ac_inheritedcomp)]+msestring(name)+ + actionsmo.c[ord(ac_cannotdel)],actionsmo.c[ord(ac_error)]); + exit; + end; + end; + end; + removeforeign(false); + fdelobjs:= fselections.getobjinfoar; + deletecomponents; + end; + // domodified; + clientsizechanged; + result:= true; + end; +end; + + +procedure tformdesignerfo.selectchildexec(const sender: tobject); +var + ar1: msestringarty; + comp1: tcomponent; +begin + with tmenuitem(sender) do begin + ar1:= splitstring(caption,widechar(' ')); + if fselectwidget <> nil then begin + comp1:= fselectwidget.findlogicalchild(ansistring(ar1[0])); + end + else begin + comp1:= fselectcomp.findcomponent(ansistring(ar1[0])); + end; + if comp1 <> nil then begin + selectcomponent(comp1,sm_select); + end; + end; +end; + +procedure tformdesignerfo.dopopup(var info: mouseeventinfoty); + +var + bo1,bo2,bo3,bo4: boolean; + item1: tmenuitem; + ar1: msestringarty; + ar2: componentarty; + int1: integer; + selectcomp: tcomponent; + comp1: tcomponent; +begin + with popupme,menu do begin + selectcomp:= nil; + if fselections.count = 1 then begin + selectcomp:= fselections[0]; + end; + bo1:= (fselections.count > 0) and (fselections[0] <> module); + bo2:= bo1 and fselections.candelete; + itembyname('copy').enabled:= bo1; + itembyname('cut').enabled:= bo2; + itembyname('delete').enabled:= bo2; + itembyname('undelete').enabled:= fdelobjs <> nil; + itembyname('paste').enabled:= iswidgetcomp(selectcomp) or (fform = nil); + itembyname('editcomp').enabled:= designer.componentcanedit; + { + bo1:= not( + (fselections.count <> 1) or + not(fselections.items[0] is twidget) or + not fowner.checkdescendent(twidget(fselections.items[0])) + ); + } + bo1:= iswidgetcomp(selectcomp) and + checkdescendent(twidget(selectcomp)); + itembyname('insertsub').enabled:= bo1 or (selectcomp = module) or + isdatasubmodule(selectcomp); + + itembyname('revert').enabled:= (fselections.count = 1) and + (fselections[0].componentstate * [csinline,csancestor] <> []); + itembyname('insertcomp').enabled:= designer.hascurrentcomponent and + (fselections.count = 1); + itembyname('bringtofro').enabled:= bo1; + itembyname('sendtoba').enabled:= bo1; + + bo3:= false; + bo4:= false; + for int1:= 0 to fselections.count - 1 do begin + comp1:= fselections[int1]; + if not (comp1 is tmsedatamodule) or + not (csinline in comp1.componentstate) then begin + bo3:= false; + bo4:= false; + break; + end; + if dmo_iconic in tmsedatamodule(comp1).options then begin + bo4:= true; + end + else begin + bo3:= true; + end; + end; + itembyname('iconify').enabled:= bo3; + itembyname('deiconify').enabled:= bo4; + + itembyname('setwidgetord').enabled:= bo1; + itembyname('settabord').enabled:= bo1 and + (twidget(fselections.items[0]).parentwidget.childrencount >= 2); + itembyname('synctofo').enabled:= fselections.count > 0; + item1:= itembyname('selectchild'); + item1.enabled:= iswidgetcomp(selectcomp) and + (twidget(selectcomp).container.widgetcount > 0) or + isdatasubmodule(selectcomp) and + (selectcomp.componentcount > 0); + if item1.enabled then begin + if iswidgetcomp(selectcomp) then begin + fselectwidget:= twidget(selectcomp); + ar2:= componentarty(fselectwidget.getlogicalchildren); + end + else begin + fselectwidget:= nil; + fselectcomp:= selectcomp; + setlength(ar2,fselectcomp.componentcount); + for int1:= 0 to high(ar2) do begin + ar2[int1]:= fselectcomp.components[int1]; + end; + end; + setlength(ar1,length(ar2)); + for int1:= 0 to high(ar1) do begin + with ar2[int1] do begin + ar1[int1]:= msestring(name + ' (' + classname+')'); + end; + end; + sortarray(ar1); + item1.submenu.count:= length(ar1); + for int1:= 0 to high(ar1) do begin + with item1.submenu[int1] do begin + caption:= ar1[int1]; + onexecute:= {$ifdef FPC}@{$endif}selectchildexec; + end; + end; + end; + show(self,info); + item1.submenu.clear; + end; +end; + +function tformdesignerfo.widgetatpos(const apos: pointty; + const onlywidgets: boolean; const everywhere: boolean = false): twidget; +var + widgetinfo: widgetatposinfoty; +begin + result:= nil; + if everywhere or pointinrect(apos,gridrect) then begin + fillchar(widgetinfo,sizeof(widgetinfo),0); + with widgetinfo do begin + pos:= translatewidgetpoint(apos,self,form); +// pos:= subpoint(apos,form.rootpos); + if onlywidgets then begin + childstate:= [ws_designing,ws_iswidget,ws_isvisible]; + end + else begin + childstate:= [ws_isvisible]; + end; + parentstate:= [ws_isvisible]; + end; + result:= form.widgetatpos(widgetinfo); + end; +end; + +procedure tformdesignerfo.clientsizechanged(); +begin + fclientsizevalid:= false; +end; + +procedure tformdesignerfo.poschanged(); +begin + inherited; + if not (fos_statreading in fformstate) and (fmodulesetting = 0) and + (fparentwidget = nil) then begin //not docked + fmodulepos:= translatewidgetpoint(paintpos,self,nil); + doModified; + end; + updatedockinfo(); +end; + +procedure tformdesignerfo.sizechanged(); +begin + inherited; + updatedockinfo(); +end; + +procedure tformdesignerfo.drawgrid(const canvas: tcanvas); +var + po1: pointty; + rect1,rect2: rectty; + endy: integer; + offset: pointty; + points1: pointarty; + int1,gridcx,gridcy: integer; +begin + if showgrid then begin + rect2:= gridrect; + msegraphutils.intersectrect(canvas.clipbox,rect2,rect1); + offset:= gridoffset; + gridcx:= gridsizex; + gridcy:= gridsizey; + with rect1 do begin + po1.x:= ((x - offset.x) div gridcx) * gridcx + offset.x; + po1.y:= ((y - offset.y) div gridcy) * gridcy + offset.y; + endy:= y + cy; + end; + setlength(points1, rect1.cx div gridcx + 2); + for int1:= 0 to high(points1) do begin + points1[int1].x:= po1.x; + inc(po1.x,gridcx); + end; + while po1.y < endy do begin + for int1:= 0 to high(points1) do begin + points1[int1].y:= po1.y; + end; + canvas.drawpoints(points1,cl_black); + inc(po1.y,gridcy); + end; + end; +end; + +procedure tformdesignerfo.clearselection(); +begin + fdesigner.noselection; +end; + +procedure tformdesignerfo.deletecomponent(const component: tcomponent); +begin + fdesigner.selectcomponent(component); + fdesigner.deleteselection(true); + domodified; + clientsizechanged; +end; + +procedure tformdesignerfo.selectcomponent(const component: tcomponent; +// const bymouse: boolean; + mode: selectmodety = sm_select); +begin + if component <> nil then begin + if mode = sm_remove then begin + fselections.remove(component); + factcompindex:= -1; + end + else begin + if mode = sm_select then begin + fselections.clear; + end; + factcompindex:= fselections.indexof(component); + if factcompindex < 0 then begin + factcompindex:= fselections.add(component); + end + else begin + if mode = sm_flip then begin + fselections.remove(component); + factcompindex:= -1; + end; + end; + end; + if factcompindex < 0 then begin + actarea:= ar_none; + end; + updateselections; + end; +end; + +procedure tformdesignerfo.selectparentwidget(const awidget: twidget); +var + int1: integer; +begin + with fselections do begin + beginupdate; + try + for int1:= count-1 downto 0 do begin + with itempo(int1)^ do begin + if (selectedinfo.instance is twidget) and + awidget.checkdescendent(twidget(selectedinfo.instance)) then begin + delete(int1); + end; + end; + end; + add(awidget); + factcompindex:= indexof(awidget); + finally + endupdate; + end; + end; + updateselections; +end; + +procedure tformdesignerfo.setrootpos(const component: tcomponent; + const apos: pointty); +begin + setcomponentpos(component,apos); +end; + +procedure tformdesignerfo.updateselections; +begin + if fselecting = 0 then begin + case fselections.count of + 0: begin + fdesigner.SelectComponent(nil); + end; + 1: begin + designer.SelectComponent(fselections[0]); + end + else begin + fdesigner.SetSelections(idesignerselections(fselections)); + end; + end; + end; +end; + +procedure tformdesignerfo.updateclickedcomponent; +begin + objectinspectorfo.clickedcomponentchanged(clickedcomponent); +end; + +procedure tformdesignerfo.beginselect; +begin + inc(fselecting); + fselections.beginupdate; +end; + +procedure tformdesignerfo.endselect; +begin + dec(fselecting); + fselections.endupdate; + if fselecting = 0 then begin + updateselections; + end; +end; + +procedure tformdesignerfo.domodified; +begin + invalidate; + if fds_loaded in ffostate then begin + fdesigner.componentmodified(fmodule); + end; +end; + +procedure tformdesignerfo.methodcreated(const adesigner: idesigner; + const amodule: tmsecomponent; const aname: string; + const atype: ptypeinfo); +begin + //dummy +end; + +procedure tformdesignerfo.methodnamechanged(const adesigner: idesigner; + const amodule: tmsecomponent; const newname, oldname: string; + const atypeinfo: ptypeinfo); +begin + //dummy +end; + +procedure tformdesignerfo.showobjecttext(const adesigner: idesigner; + const afilename: filenamety; const backupcreated: boolean); +begin + //dummy +end; + +procedure tformdesignerfo.closeobjecttext(const adesigner: idesigner; + const afilename: filenamety; var cancel: boolean); +begin + //dummy +end; + +procedure tformdesignerfo.moduleactivated(const adesigner: idesigner; + const amodule: tmsecomponent); +begin + //dummy +end; + +procedure tformdesignerfo.moduledeactivated(const adesigner: idesigner; const amodule: tmsecomponent); +begin + //dummy +end; + +procedure tformdesignerfo.checkdelobjs(const aitem: tcomponent); +var + int1: integer; +begin + for int1:= 0 to high(fdelobjs) do begin + with fdelobjs[int1] do begin + if (owner = aitem) or (parent = aitem) then begin + owner:= nil; + parent:= nil; + objtext:= ''; + end; + end; + end; +end; + +procedure tformdesignerfo.moduledestroyed(const adesigner: idesigner; + const amodule: tmsecomponent); +begin + checkdelobjs(amodule); +end; + +procedure tformdesignerfo.ItemDeleted(const ADesigner: IDesigner; + const amodule: tmsecomponent; const AItem: tcomponent); +begin + fselections.remove(aitem); + checkdelobjs(aitem); +end; + +procedure tformdesignerfo.ItemInserted(const ADesigner: IDesigner; + const amodule: tmsecomponent; const AItem: tcomponent); +begin + //dummy +end; + +procedure tformdesignerfo.ItemsModified(const ADesigner: IDesigner; + const AItem: tobject); +begin + fselections.externalcomponentchanged(aitem); + if isdatasubmodule(aitem,false,true) then begin //iconic state could be changed + clientsizechanged; + end; +end; + +procedure tformdesignerfo.componentnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const aitem: tcomponent; + const newname: string); +begin + if (amodule = fmodule) then begin + if not (aitem is twidget) then begin + fclientsizevalid:= false; + end; + updatemodulename(); + end; +end; + +procedure tformdesignerfo.moduleclassnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); +begin + //dummy +end; + +procedure tformdesignerfo.instancevarnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); +begin + //dummy +end; + +procedure tformdesignerfo.setshowgrid(const avalue: boolean); +begin + if fshowgrid <> avalue then begin + fshowgrid:= avalue; + invalidate(); + end; +end; + +procedure tformdesignerfo.setgridsizex(const avalue: integer); +begin + if fgridsizex <> avalue then begin + fgridsizex:= avalue; + invalidate(); + end; +end; + +procedure tformdesignerfo.setgridsizey(const avalue: integer); +begin + if fgridsizey <> avalue then begin + fgridsizey:= avalue; + invalidate(); + end; +end; + +procedure tformdesignerfo.updateprojectoptions(); +begin + with projectoptions do begin + showgrid:= e.showgrid; + snaptogrid:= e.snaptogrid; + gridsizex:= e.gridsizex; + gridsizey:= e.gridsizey; + if not e.noformdesignerdocking xor (frame.grip_size <> 0) then begin + beginplacement(); + if not e.noformdesignerdocking then begin + frame.grip_size:= 10; + end + else begin + frame.grip_size:= 0; + dragdock.optionsdock:= dragdock.optionsdock - [od_top,od_background]; + dragdock.float(); + end; + if not fixformsize then begin + checksynctoformsize(); + end; + endplacement(); + end; + end; + invalidate(); +end; + +procedure tformdesignerfo.beforemake(const adesigner: idesigner; + const maketag: integer; var abort: boolean); +begin + //dummy +end; + +procedure tformdesignerfo.aftermake(const adesigner: idesigner; + const exitcode: integer); +begin + //dummy +end; + +procedure tformdesignerfo.beforefilesave(const adesigner: idesigner; + const afilename: filenamety); +begin + //dummy +end; + +function tformdesignerfo.componentoffset: pointty; +begin +// result:= tformdesignerfo(fowner).gridrect.pos; + result:= gridoffset; +end; + +function tformdesignerfo.snaptogriddelta(const apos: pointty): pointty; +begin + if snaptogrid then begin + result.x:= roundint(apos.x,gridsizex); + result.y:= roundint(apos.y,gridsizey); + end + else begin + result:= apos; + end; +end; + +function tformdesignerfo.dosnaptogrid(const apos: pointty): pointty; +begin + if snaptogrid then begin + result:= snaptogriddelta(subpoint(apos,gridoffset)); + addpoint1(result,gridoffset); + end + else begin + result:= apos; + end; +end; + + +procedure tformdesignerfo.selectionchanged(const adesigner: idesigner; + const aselection: idesignerselections); +begin + try + fselections.beginupdate; + if fselections.assign(aselection) then begin + componentselected(fselections); + invalidate(); + end; + finally + fselections.decupdate; + end; +end; + +function tformdesignerfo.componentatpos(const apos: pointty): tcomponent; + +var + isdatamodule: boolean; + toplevel: boolean; + compoff,widoff: boolean; + + function checkcomponent(const component: tcomponent; + const pos: pointty; const shiftoffset: boolean): tcomponent; + var + int1: integer; + pt1: pointty; + bo1,bo2: boolean; + shift1: boolean; + rect1: rectty; + comp1: tcomponent; + begin + result:= nil; + bo2:= iswidgetcomp(component); + if ((bo2 and widoff) or (not bo2 and compoff)) and + (component.owner <> nil) then begin + exit; + end; + bo1:= not isdatamodule and bo2 and + (twidget(component).parentwidget <> nil); + bo2:= false; + shift1:= shiftoffset; //for chidren + pt1:= pos; + rect1:= getcomponentrect(component,shiftoffset); + if bo1 and not toplevel then begin + subpoint1(pt1,twidget(component).pos); + if (component.owner = module) and (module is twidget) then begin +// tdesignwindow(twidget(component).window).readjustchildcomponentpos(pt1); + readjustchildcomponentpos(pt1); + end; + end + else begin + if isdatasubmodule(component) then begin + bo2:= pointinrect(pt1,rect1); + subpoint1(pt1,rect1.pos); + shift1:= false; + end; + end; + if toplevel or + (not isdatamodule and bo1 or bo2) and + not (cssubcomponent in component.componentstyle) and + (component.componentstate * [csinline,csancestor] <> []) then begin + toplevel:= false; + for int1:= component.componentcount - 1 downto 0 do begin + comp1:= component.components[int1]; + if isdatasubmodule(comp1) then begin + result:= checkcomponent(comp1,pt1,shift1); + if result <> nil then begin + exit; + end; + end; + end; + for int1:= component.componentcount - 1 downto 0 do begin + comp1:= component.components[int1]; + if not isdatasubmodule(comp1) then begin + result:= checkcomponent(comp1,pt1,shift1); + if result <> nil then begin + exit; + end; + end; + end; + end; + if not bo1 {or isdatamodule} then begin + if pointinrect(pos,rect1) then begin + result:= component; + end; + end; + end; + +begin + isdatamodule:= fform = nil; + widoff:= hidewidgetact.checked; + compoff:= hidecompact.checked; + toplevel:= true; + result:= checkcomponent(fmodule,apos,true); + if result = fmodule then begin + result:= nil; + end; +end; + + +procedure tformdesignerfo.doafterpaint(const canvas: tcanvas); +var + offs: pointty; + gridrect1: rectty; + + procedure clipchildren(const acomp: tcomponent; const aindex: integer; + const shiftoffset: boolean); + var + int1: integer; + comp1: tcomponent; + rect1: rectty; + begin + for int1:= aindex to acomp.componentcount - 1 do begin + comp1:= acomp.components[int1]; + if isdatasubmodule(comp1) then begin + rect1:= mr(getcomponentpos(comp1),tmsedatamodule(comp1).size); + if shiftoffset then begin + addpoint1(rect1.pos,offs); + end; + canvas.subcliprect(rect1); + end; + end; + end; + +var + level: integer; + + procedure drawcomponent(const component: tcomponent); + var + rect1: rectty; + int1: integer; + isroot,iswidget,issub: boolean; + comp1: tcomponent; +// bo1: boolean; + label + endlab; + begin + isroot:= level = 0; + inc(level); + if not (cssubcomponent in component.componentstyle) then begin + iswidget:= false; + issub:= false; + if isroot then begin + iswidget:= true; + end + else begin + iswidget:= iswidgetcomp(component); + if not iswidget then begin + issub:= isdatasubmodule(component); + end; + end; + if iswidget then begin + if isroot then begin + rect1:= gridrect1; + end + else begin + if hidewidgetact.checked then begin + goto endlab; + end; + rect1:= twidget(component).widgetrect; + if level = 2 then begin + addpoint1(rect1.pos,gridrect1.pos); + end; + end + end + else begin + rect1:= getcomponentrect(component,level <= 2); + end; + if not (iswidget or issub) then begin + if isdatasubmodule(component,true) then begin + canvas.fillrect(rect1,cl_ltgray); + drawtext(canvas,msestring(component.name),rect1,[tf_ycentered,tf_xcentered], + stockobjects.fonts[stf_default]); + end + else begin + rect1.cx:= rect1.cx - complabelrightmargin; + drawtext(canvas,msestring(component.name),rect1,[tf_ycentered,tf_right], + stockobjects.fonts[stf_default]); + rect1.cx:= rect1.cy; + registeredcomponents.drawcomponenticon(component,canvas,rect1); + end; + end + else begin + if component.componentcount > 0 then begin + canvas.save; + if not issub then begin + canvas.intersectcliprect(rect1); + end; + if not isroot then begin + canvas.move(rect1.pos); + end; + clipchildren(component,0,isroot); + + for int1:= 0 to component.componentcount - 1 do begin + comp1:= component.components[int1]; + if not isdatasubmodule(comp1) then begin + drawcomponent(comp1); + end; + end; + canvas.restore; + if not isroot then begin + canvas.move(rect1.pos); + end; + for int1:= 0 to component.componentcount - 1 do begin + comp1:= component.components[int1]; + if isdatasubmodule(comp1) then begin + canvas.save; + clipchildren(component,int1+1,isroot); + drawcomponent(comp1); + canvas.restore; + end; + end; + if not isroot then begin + canvas.remove(rect1.pos); + end; + end; + if issub then begin + canvas.dashes:= #3#3; + dec(rect1.cx); + dec(rect1.cy); + canvas.drawrect(rect1); + canvas.dashes:= ''; + end; + end; + end; + endlab: + dec(level); + end; + +begin + inherited; + offs:= componentoffset; + if not pointisequal(offs,fcompoffsbefore) then begin + fcompoffsbefore:= offs; + fselections.finfovalid:= false; + end; + gridrect1:= gridrect(); + if fmodule <> nil then begin +// canvas.save(); + canvas.intersectcliprect(gridrect1); + if not hidecompact.checked then begin + level:= 0; + drawcomponent(fmodule); + end; + if form <> nil then begin + drawgrid(canvas); + end; +// canvas.restore(); +// canvas.intersectcliprect(markerrect); + fselections.paint(canvas); + showxorpic(canvas); + end; +end; + +procedure tformdesignerfo.dobeforepaint(const canvas: tcanvas); +begin + hidexorpic(canvas); + inherited; + if not fclientsizevalid then begin + recalcclientsize(); + fclientsizevalid:= true; + fselections.finfovalid:= false; + end; +end; + +procedure tformdesignerfo.doactivate; +begin + fdesigner.setactivemodule(self); + inherited; +end; + +function tformdesignerfo.fixformsize: boolean; +begin + result:= parentwidget <> nil; //docked +end; + +procedure tformdesignerfo.doupdatecaption(); +var + mstr1: msestring; +begin + if fmodule <> nil then begin + mstr1:= msestring(fmodule.name); + if fmoduleoptions <> [] then begin + mstr1:= '-'+mstr1; + end; + if fdesigner.modules.findmodule(fmodule)^.modified then begin + mstr1:= '*'+mstr1; + end; + caption:= mstr1; + dragdock.caption:= mstr1; + end; +end; + +procedure tformdesignerfo.doasyncevent(var atag: integer); +var + rect1: rectty; +begin + case designerfoeventty(atag) of + fde_updatecaption: begin + fupdatecaptionpending:= false; + doupdatecaption(); + end; + fde_syncsize: begin + if not fixformsize then begin + rect1:= paintrect; + if form <> nil then begin + form.widgetrect:= rect1; + if sizeisequal(form.size,rect1.size) or + not sizeisequal(rect1.size,fsizebefore) then begin + fsizeerrorcount:= 0; + end; + fsizebefore:= rect1.size; + if fsizeerrorcount < 4 then begin + inc(fsizeerrorcount); + include(ffostate,fds_sizesyncing); + try + paintsize:= form.size; + finally + exclude(ffostate,fds_sizesyncing); + end; + end; + end + else begin + if module is tmsedatamodule then begin + tmsedatamodule(module).size:= rect1.size; + end; + end; + if parentwidget = nil then begin //not docked + fmodulepos:= translatewidgetpoint(rect1.pos,self,nil); + end; + domodified(); + end + else begin + if parentwidget = nil then begin //not docked + fmodulesize:= paintsize; + domodified(); + end; + end; + end; + fde_scrolled: begin + fselections.change(); + end; + fde_showastext: begin + fdesigner.showastext(fdesigner.modules.findmodule(fmodule)); + end; + end; +end; + +procedure tformdesignerfo.updatecaption; +begin + if not fupdatecaptionpending then begin + fupdatecaptionpending:= true; + asyncevent(integer(fde_updatecaption)); + end; +end; + +procedure tformdesignerfo.formcontainerscrolled; +begin + asyncevent(ord(fde_scrolled)); +end; + +procedure tformdesignerfo.checksynctoformsize(); +begin + if (fparentwidget = nil) and (fds_loaded in ffostate) then begin + if (fform <> nil) and not fixformsize then begin + fformcont.size:= fform.size; //not docked + paintsize:= fformcont.size; + end + else begin + paintsize:= getmodulesize(); + end; + end; +end; + +procedure tformdesignerfo.checksynctomodulepos(); +begin + if (fparentwidget = nil) and (fds_loaded in ffostate) then begin + if fform <> nil then begin + pos:= translatewidgetpoint(fmodulepos,fform.parentwidget,self); + end + else begin + pos:= translatewidgetpoint(fmodulepos,fscrollbox,self); + end; + end; +end; + +procedure tformdesignerfo.updateformcont(); +var + si1: sizety; + + function updatesi(const source: sizety): sizety; + begin + result:= source; + if result.cx <> 0 then begin + inc(result.cx,si1.cx); + end; + if result.cy <> 0 then begin + inc(result.cy,si1.cy); + end; + end; //updatesi + +begin + if (fparentwidget = nil) and (form <> nil) then begin + si1:= framedim; + minsize:= updatesi(form.minsize); + maxsize:= updatesi(form.maxsize); + end + else begin + minsize:= nullsize; + maxsize:= nullsize; + end; + fformcont.widgetrect:= paintrect; +end; + +procedure tformdesignerfo.formcontainerwidgetregionchanged( + const sender: twidget); +begin + if (fform <> nil) and (sender = fform) and + not(ws1_anchorsizing in fform.widgetstate1) and + not (csdestroying in fform.componentstate) and + not (csdestroying in componentstate) then begin + checksynctoformsize(); + end; +end; + +procedure tformdesignerfo.beffloatexe(const sender: twidget; + var arect: rectty); +begin + inc(fmodulesetting); + visible:= false; +end; + +procedure tformdesignerfo.floatexe(const sender: TObject); +begin + checksynctoformsize(); + if fform <> nil then begin + pos:= translatewidgetpoint(fmodulepos,fform.parentwidget,self); + end + else begin + pos:= translatewidgetpoint(fmodulepos,fscrollbox,self); + end; + visible:= true; + dec(fmodulesetting); +end; + +procedure tformdesignerfo.clientrectchanged(); + +begin + inherited; + updateformcont(); + if not (ws_loadedproc in widgetstate) and (fmodulesetting = 0) and + (ffostate * [fds_sizesyncing,fds_loaded] = [fds_loaded]) then begin + asyncevent(ord(fde_syncsize)); + end; +end; + +procedure tformdesignerfo.doshow; +begin + inherited; + updatecaption; +end; + +procedure tformdesignerfo.beginplacement; +begin + inc(fmodulesetting); +end; + +procedure tformdesignerfo.endplacement; +begin + dec(fmodulesetting); +end; + +function tformdesignerfo.getdesignrect: rectty; +begin + result:= twidget(fmodule).widgetrect; +end; + +procedure tformdesignerfo.setdesignrect(const arect: rectty); +begin +end; +procedure tformdesignerfo.updatemodulename; +begin + name:= '_mse_'+fmodule.name+'_mse_'; + updatecaption(); +end; + +procedure tformdesignerfo.placemodule; +var +// asize: sizety; +// po1: pointty; +// int1: integer; + rect1: rectty; +begin + beginplacement; + try + updatemodulename(); + if fmodule is twidget then begin + fmodulepos:= twidget(fmodule).pos; + fmodulesize:= twidget(fmodule).size; + setlinkedvar(fmodule,tmsecomponent(fform)); + rect1:= getdesignrect; + widgetrect:= inflaterect(rect1,frame.paintframe); + twidget(fmodule).parentwidget:= getmoduleparent; + twidget(fmodule).pos:= nullpoint; + twidget(fmodule).taborder:= 0; + end + else begin + fform:= nil; + fmodulepos:= getcomponentpos(fmodule); + fmodulesize:= getmodulesize(); + widgetrect:= inflaterect(mr(fmodulepos,fmodulesize),frame.paintframe); + end; + doupdatecaption(); + finally + endplacement; + end; +end; + +procedure tformdesignerfo.setmodule(const Value: tmsecomponent); +begin + if fmodule <> value then begin + fmodule.free; + fmodule:= Value; + if fmodule <> nil then begin + fmodule.freenotification(self); +// insertcomponent(value); + placemodule; + end; + end; +end; + +procedure tformdesignerfo.doshowobjectinspector(const sender: tobject); +begin + designer.showobjectinspector; +// objectinspectorfo.activate; +end; + +procedure tformdesignerfo.doshowcomponentpalette(const sender: tobject); +begin + componentpalettefo.window.bringtofront; + componentpalettefo.show; +end; + +procedure tformdesignerfo.doshowastext(const sender: tobject); +begin + asyncevent(ord(fde_showastext)); +end; + +procedure tformdesignerfo.doeditcomponent(const sender: tobject); +begin + designer.getcomponenteditor.edit; +end; + +function selectinheritedmodule(const amodule: pmoduleinfoty; + const caption: msestring = ''): pmoduleinfoty; +var + fo: tselectsubmoduledialogfo; + ar1: msestringarty; + int1: integer; + ar2: componentarty; +begin + result:= nil; + fo:= tselectsubmoduledialogfo.create(nil); + try + if caption <> '' then begin + fo.caption:= caption; + end; + if amodule <> nil then begin + ar2:= designer.descendentinstancelist.getancestorsandchildren(amodule^.instance); + additem(pointerarty(ar2),amodule^.instance); + end + else begin + ar2:= nil; + end; + ar1:= nil; + with designer.modules do begin + for int1:= 0 to count - 1 do begin + with itempo[int1]^ do begin + if finditem(pointerarty(ar2),instance) < 0 then begin + additem(ar1,filename); + end; + end; + end; + end; + fo.submodule.dropdown.cols[0].asarray:= ar1; + if fo.show(true) = mr_ok then begin + result:= designer.modules.findmodule(fo.submodule.value); + end; + finally + fo.Free; + end; +end; + +function getdesignform(const acomp: tcomponent): tformdesignerfo; +var + comp1: tcomponent; + p1: pmoduleinfoty; +begin + result:= nil; + comp1:= rootcomponent(acomp); + if comp1 <> nil then begin + p1:= designer.modules.findmodulebyinstance(comp1); + if p1 <> nil then begin + pointer(result):= p1^.designform; + if not (result is tformdesignerfo) then begin + result:= nil; + end; + end; + end; +end; + +procedure tformdesignerfo.placecomponent(const component: tcomponent; + const apos: pointty; aparent: tcomponent = nil); +var +// widget1: twidget; + po1: pointty; + rea1: real; + str1,str2: string; + int1,int2: integer; + ar1: componentarty; + bo1: boolean; + comp1: tcomponent; +begin +// with tdesignwindow(window) do begin + try + rea1:= 1.0; + if component is tmsecomponent then begin + with fmoduleintf^ do begin + if assigned(getscale) then begin + rea1:= getscale(module); + end; + end; + tmsecomponent(component).initnewcomponent(rea1); + end; + if (component is twidget) and (form <> nil) then begin + if (aparent = nil) or not (aparent is twidget) then begin + aparent:= widgetatpos(apos,true); + end; + if aparent <> nil then begin + comp1:= aparent.findcomponent(component.name); + if (comp1 <> nil) and (comp1 <> component) then begin + str1:= component.name; + int1:= length(str1); + while (int1 > 1) and (str1[int1] >= '0') and (str1[int1] <= '9') do begin + dec(int1); + end; + setlength(str1,int1); //remove trailing nums + int1:= 1; + ar1:= designer.descendentinstancelist.getdescendents(fmodule); + additem(pointerarty(ar1),module); + additem(pointerarty(ar1),aparent); + str2:= str1+'1'; + repeat + bo1:= true; + for int2:= 0 to high(ar1) do begin + if ar1[int2].findcomponent(str2) <> nil then begin + inc(int1); + str2:= str1 + inttostr(int1); + bo1:= false; + break; + end; + end; + until bo1; + component.name:= str2; + end; +// po1:= subpoint(dosnaptogrid(apos),form.rootpos); + po1:= dosnaptogrid(apos); + twidget(aparent).insertwidget(twidget(component), + translatewidgetpoint(po1,self,twidget(aparent))); + twidget(component).initnewwidget(rea1); + end; + end + else begin + setrootpos(component,subpoint(dosnaptogrid(apos),insertoffset)); + end; + tcomponent1(component).loaded; + domodified; + except + deletecomponent(component); + raise; + end; + selectcomponent(component); + recalcclientsize; +// end; +end; + +procedure tformdesignerfo.doinsertsubmodule(const sender: tobject); +var + comp: tmsecomponent; + po1: pmoduleinfoty; +begin + po1:= selectinheritedmodule(fdesigner.modules.findmodulebyinstance(module)); + if po1 <> nil then begin + comp:= fdesigner.copycomponent(po1^.instance,po1^.instance,false,false); + initinline(comp); + comp.name:= po1^.instance.name; + fdesigner.addancestorinfo(comp,po1^.instance); +// with tdesignwindow(window) do begin + doaddcomponent(comp); + placecomponent(comp,fmousepos,fselections[0]); +// end; + end; +end; + +procedure tformdesignerfo.doinsertcomponent(const sender: TObject); +var + comp1: tcomponent; +begin + comp1:= fdesigner.createcurrentcomponent(module); +// with tdesignwindow(window) do begin + placecomponent(comp1,fmousepos,fselections[0]); +// end; +end; + +procedure tformdesignerfo.dotouch(const sender: TObject); +begin + fdesigner.touch(fmodule); +// tdesignwindow(window).domodified; +end; + +procedure tformdesignerfo.touchallexe(const sender: TObject); +begin + if askconfirmation(c[ord(sc_touchall)]) then begin + fdesigner.touchall; + end; +end; + +procedure tformdesignerfo.dobringtofront(const sender: tobject); +begin +// with tdesignwindow(window) do begin + twidget(fselections[0]).bringtofront; + domodified; +// end; +end; + +procedure tformdesignerfo.dosendtoback(const sender: tobject); +begin +// with tdesignwindow(window) do begin + twidget(fselections[0]).sendtoback; + domodified; +// end; +end; + +procedure tformdesignerfo.doiconify(const sender: TObject); +var + int1: integer; +begin +// with tdesignwindow(window) do begin + for int1:= 0 to fselections.count - 1 do begin + with tmsedatamodule(fselections[int1]) do begin + options:= options + [dmo_iconic]; + end; + end; +// end; +end; + +procedure tformdesignerfo.dodeiconify(const sender: TObject); +var + int1: integer; +begin +// with tdesignwindow(window) do begin + for int1:= 0 to fselections.count - 1 do begin + with tmsedatamodule(fselections[int1]) do begin + options:= options - [dmo_iconic]; + end; + end; +// end; +end; + +procedure tformdesignerfo.dosettaborder(const sender: tobject); +begin + settaborderdialog(twidget(fselections.items[0]),false); +end; + +procedure tformdesignerfo.dosetwidgetorder(const sender: TObject); +begin + settaborderdialog(twidget(fselections.items[0]),true); +end; + +procedure tformdesignerfo.dosetcreationorder(const sender: TObject); +var + fo: tsetcreateorderfo; + str1: string; + comp1: tcomponent; +begin +// with tdesignwindow(window) do begin + comp1:= nil; + str1:= ''; + if (fselections.count = 1) then begin + comp1:= selections[0].owner; + end; + if comp1 = nil then begin + comp1:= module; + end + else begin + str1:= fselections[0].name; + end; +// end; + fo:= tsetcreateorderfo.create(comp1,str1); + try + fo.show(true,window); + finally + fo.free; + end; +end; + +procedure tformdesignerfo.dosyncfontheight(const sender: tobject); +var + int1: integer; + comp1: tcomponent; +begin +// with tdesignwindow(window) do begin + for int1:= 0 to fselections.count - 1 do begin + comp1:= fselections[int1]; + if comp1 is twidget then begin + twidget(comp1).synctofontheight; + fdesigner.componentmodified(comp1); + end; + end; +// end; +end; + +procedure tformdesignerfo.copyexe(const sender: TObject); +begin +// tdesignwindow(twidget(tmenuitem(sender).owner.owner).window).docopy(false); + docopy(false); +end; + +procedure tformdesignerfo.pasteexe(const sender: TObject); +begin +// tdesignwindow(twidget(tmenuitem(sender).owner.owner).window).dopaste(true,''); + dopaste(true,''); +end; + +procedure tformdesignerfo.deleteexe(const sender: TObject); +begin +// tdesignwindow(twidget(tmenuitem(sender).owner.owner).window).dodelete; + dodelete(); +end; + +procedure tformdesignerfo.undeleteexe(const sender: TObject); +begin +// tdesignwindow(twidget(tmenuitem(sender).owner.owner).window).doundelete; + doundelete(); +end; + +procedure tformdesignerfo.cutexe(const sender: TObject); +begin +// tdesignwindow(twidget(tmenuitem(sender).owner.owner).window).docut; + docut(); +end; + +procedure tformdesignerfo.setcomponentscrollsize(const avalue: sizety); +begin + if fform is tcustommseform then begin +{$warnings off} + with tscrollingwidget1(tcustommseform(fform).container) do begin +{$warnings on} + fminminclientsize:= avalue; + clientsize:= clientsize; + end; + end; +end; + +procedure tformdesignerfo.calcscrollsize(const sender: tscrollingwidgetnwr; + var asize: sizety); +var + size1: sizety; +begin + size1:= componentscrollsize(); + setcomponentscrollsize(size1); + if asize.cx < size1.cx then begin + asize.cx:= size1.cx; + end; + if asize.cy < size1.cy then begin + asize.cy:= size1.cy; + end; +end; + +procedure tformdesignerfo.recalcclientsize; +begin + if (fform = nil) or not fformcont.visible then begin +{$warnings off} + with twidget1(container) do begin +{$warnings on} + exclude(fwidgetstate,ws_minclientsizevalid); + tframe1(frame).updatestate; + end; + end + else begin + setcomponentscrollsize(componentscrollsize); + end; +end; + +procedure tformdesignerfo.formdeonclose(const sender: TObject); +var + int1: integer; + bo1: boolean; +begin + with {tdesignwindow(window),}fselections do begin + bo1:= false; + for int1:= count - 1 downto 0 do begin + if (items[int1] = fmodule) or (items[int1].owner = fmodule) then begin + delete(int1); + bo1:= true; + end; + end; + if bo1 then begin + updateselections; + end; + end; +end; + +procedure tformdesignerfo.revertexe(const sender: TObject); +begin + if askok(c[ord(sc_wishrevert)]+lineend+c[ord(sc_selectedcomp)]) then begin + fdesigner.revert(fselections[0]); + objectinspectorfo.refresh; + end; +end; + +function tformdesignerfo.insertoffset: pointty; +var + widget1: twidget; +begin + if (form = nil) or not fformcont.visible then begin + widget1:= container; + end + else begin + if form <> nil then begin + widget1:= form.container; + end + else begin + widget1:= fformcont; + end; + end; + result:= translatewidgetpoint(widget1.clientwidgetpos,widget1,self); +end; + +function tformdesignerfo.gridoffset: pointty; +begin + result:= insertoffset; +end; + +function tformdesignerfo.gridrect: rectty; +begin + if (form = nil) or hidewidgetact.checked then begin + result:= mr(translatewidgetpoint(container.paintpos,container,self), + container.paintsize); + end + else begin + result:= mr(translatewidgetpoint(form.container.paintpos,form.container,self), + form.container.paintsize); + intersectrect1(result, + mr(translatewidgetpoint(fformcont.paintpos,fformcont,self), + fformcont.paintsize)); + end; +end; + +function tformdesignerfo.markerrect: rectty; +var + widget1: twidget; +begin + if (form = nil) or hidewidgetact.checked then begin + widget1:= container; + end + else begin + widget1:= fformcont; + end; + result:= mr(translatewidgetpoint(widget1.paintpos,widget1,self), + widget1.paintsize); +end; + +function tformdesignerfo.widgetrefpoint: pointty; +begin + if form = nil then begin + result:= paintpos; + end + else begin + result:= translatewidgetpoint(form.container.pos,form.container,self); +// result:= form.container.rootpos; + end; +end; + +function tformdesignerfo.compplacementrect: rectty; +begin + if form = nil then begin + result:= container.clientrect; + end + else begin + result:= form.container.clientwidgetrect; + translatewidgetpoint1(result.pos,form.container,self); +// addpoint1(result.pos,form.container.rootpos); + end; +end; + +function tformdesignerfo.getmoduleparent: twidget; +begin +// result:= self; + result:= fformcont; + fscrollbox.visible:= false; +end; + +procedure tformdesignerfo.componentselected(const aselections: tformdesignerselections); +begin + //dummy +end; + +procedure tformdesignerfo.beginstreaming; +var + pt1: pointty; +begin + pt1:= modulerect.pos; //screen pos + if fmodule is twidget then begin + twidget1(fmodule).fwidgetrect.pos:= pt1; + end + else begin + setcomponentpos(fmodule,pt1); + end; + if fform is tcustommseform then begin + tcustommseform(fform).container.frame.scrollpos:= nullpoint; + end; + fformcont.frame.scrollpos:= nullpoint; +end; + +procedure tformdesignerfo.endstreaming; +begin + if fmodule is twidget then begin + with twidget1(fmodule) do begin + fwidgetrect.pos:= self.paintpos; + rootchanged([rcf_widgetregioninvalid]); + end; + end; +end; +{ +function tformdesignerfo.candelete(const acomponent: tcomponent): boolean; +begin + result:= true; +end; +} +{ +function tformdesignerfo.gridsizex: integer; +begin + result:= tdesignwindow(window).fgridsizex; +end; + +function tformdesignerfo.gridsizey: integer; +begin + result:= tdesignwindow(window).fgridsizey; +end; + +function tformdesignerfo.showgrid: boolean; +begin + result:= tdesignwindow(window).fshowgrid; +end; + +function tformdesignerfo.snaptogrid: boolean; +begin + result:= tdesignwindow(window).fsnaptogrid; +end; +} +procedure tformdesignerfo.componentmoving(const apos: pointty); +begin + //dummy +end; + +function tformdesignerfo.getselections: tformdesignerselections; +begin + result:= fselections; +end; +{ +procedure tformdesignerfo.deletecomponent(const comp: tcomponent); +begin + with tdesignwindow(fwindow) do begin + fselections.clear; + fselections.add(comp); + dodelete; + end; +end; +} +function tformdesignerfo.clickedcomponent: tcomponent; +begin + result:= nil; +// with tdesignwindow(fwindow) do begin + if (factcompindex >= 0) and (factcompindex < fselections.count) then begin + result:= fselections[factcompindex]; + end; +// end; +end; + +procedure tformdesignerfo.setmoduleoptions(const aoptions: moduleoptionsty); +var + changes: moduleoptionsty; +begin + if fform <> nil then begin + {$ifdef FPC} + changes:= aoptions> [] then begin + fmoduleoptions:= aoptions; + hidewidgetact.checked:= mo_hidewidgets in aoptions; + hidecompact.checked:= mo_hidecomp in aoptions; + updatecaption; + if mo_hidecomp in changes then begin + clientrectchanged; + if mo_hidecomp in fmoduleoptions then begin + designer.noselection; + end; + end; + if mo_hidewidgets in changes then begin + if mo_hidewidgets in fmoduleoptions then begin + designer.noselection; + fscrollbox.visible:= true; + end + else begin + fscrollbox.visible:= false; + end; + fformcont.visible:= not fscrollbox.visible; + end; + end; + end; +end; + +procedure tformdesignerfo.hidecompexe(const sender: TObject); +begin + clientrectchanged; + if hidecompact.checked then begin + moduleoptions:= moduleoptions + [mo_hidecomp]; + end + else begin + moduleoptions:= moduleoptions - [mo_hidecomp]; + end; +end; + +procedure tformdesignerfo.hidewidgetexe(const sender: TObject); +begin + if hidewidgetact.checked then begin + moduleoptions:= moduleoptions + [mo_hidewidgets]; + end + else begin + moduleoptions:= moduleoptions - [mo_hidewidgets]; + end; +end; + +procedure tformdesignerfo.updatewidgethideexe(const sender: tcustomaction); +begin + hidecompact.enabled:= fform <> nil; + hidewidgetact.enabled:= fform <> nil; + togglehideact.enabled:= fform <> nil; + showallact.enabled:= fform <> nil; +end; + +function tformdesignerfo.getmoduleoptions: moduleoptionsty; +begin + result:= fmoduleoptions; +end; + +procedure tformdesignerfo.togglehideexe(const sender: TObject); +begin + if hidewidgetact.checked then begin + if hidecompact.enabled then begin + hidecompact.checked:= true; + end; + hidewidgetact.checked:= false; + end + else begin + if hidecompact.checked then begin + if hidewidgetact.enabled then begin + hidewidgetact.checked:= true; + end; + hidecompact.checked:= false; + end + else begin + if hidecompact.enabled then begin + hidecompact.checked:= true; + end; + end; + end; +end; + +procedure tformdesignerfo.showallexe(const sender: TObject); +begin + moduleoptions:= moduleoptions - [mo_hidewidgets,mo_hidecomp]; +end; + +function tformdesignerfo.filterfindcomp( + const acomponent: tcomponent): boolean; +begin + result:= not (cssubcomponent in acomponent.componentstyle) and + (not (acomponent is twidget) or + (ws_iswidget in twidget(acomponent).widgetstate)); +end; + +procedure tformdesignerfo.findcompdialog; +var + name1: msestring; +begin + name1:= ''; +// with tdesignwindow(fwindow) do begin + if fselections.count > 0 then begin + name1:= msestring(ownernamepath(fselections[0])); + end; + if compnamedialog(designer.getcomponentnametree(nil,true,true,nil, + @filterfindcomp,fmodule),name1,true) = mr_ok then begin + if name1 = msestring(fmodule.name) then begin + designer.selectcomponent(fmodule); + end + else begin + replacechar1(name1,':','.'); + designer.selectcomponent( + designer.modules.findmodule(fmodule)^. + components.getcomponent(ansistring(name1),true)); + end; + end; +// end; +end; + +function tformdesignerfo.getsnaptogrid: boolean; +begin + result:= fsnaptogrid; +end; + +function tformdesignerfo.getshowgrid: boolean; +begin + result:= fshowgrid; +end; + +function tformdesignerfo.getgridsizex: integer; +begin + result:= fgridsizex; +end; + +function tformdesignerfo.getgridsizey: integer; +begin + result:= fgridsizey; +end; + +procedure tformdesignerfo.updatecursorshape(const ashiftstate: shiftstatesty; + const area: areaty); +var + shape: cursorshapety; +begin + shape:= cr_arrow; + if ashiftstate = [] then begin + case area of + ht_topleft: shape:= cr_topleftcorner; + ht_bottomright: shape:= cr_bottomrightcorner; + ht_topright: shape:= cr_toprightcorner; + ht_bottomleft: shape:= cr_bottomleftcorner; + ht_top,ht_bottom: shape:= cr_sizever; + ht_left,ht_right: shape:= cr_sizehor; + end; + end; + application.widgetcursorshape:= shape; +end; + +procedure tformdesignerfo.designmouseevent(var info: moeventinfoty; + capture: twidget); +var + mousepos1: pointty; + ss1: shiftstatesty; + + function griddelta: pointty; + begin + result:= snaptogriddelta(subpoint(mousepos1,fpickpos)); + end; + + procedure updatesizerect; + var + pos1,posbefore: pointty; + begin + pos1:= griddelta; + posbefore:= pos1; + with fsizerect,pos1 do begin + case actarea of + ht_topleft,ht_left,ht_bottomleft: begin + if x > size.cx then begin + x:= size.cx + end; + factsizerect.pos.x:= pos.x + x; + factsizerect.size.cx:= size.cx - x; + end; + ht_topright,ht_right,ht_bottomright: begin + if x < -size.cx then begin + x:= -size.cx; + end; + factsizerect.size.cx:= size.cx + x; + end; + end; + case actarea of + ht_topleft,ht_top,ht_topright: begin + if y > size.cy then begin + y:= size.cy + end; + factsizerect.pos.y:= pos.y + y; + factsizerect.size.cy:= size.cy - y; + end; + ht_bottomleft,ht_bottom,ht_bottomright: begin + if y < -size.cy then begin + y:= -size.cy; + end; + factsizerect.size.cy:= size.cy + y; + end; + end; + end; + case actarea of + ht_top,ht_bottom: begin + mousepos1.x:= fpickpos.x; + end; + ht_left,ht_right: begin + mousepos1.y:= fpickpos.y; + end; + end; + application.mouse.move(subpoint(pos1,posbefore)); + end; + + function getcompatpos(const mousepos: pointty; out dest: tcomponent): boolean; + //true if widget + begin + result:= false; + dest:= componentatpos(mousepos); + if (dest = nil) then begin + if (form <> nil) and + not hidewidgetact.checked then begin + dest:= widgetatpos(mousepos,true,true); + result:= true; + end + else begin + dest:= module; + end; + end; + end; //getcompatpos + + function getcompatpos(const mousepos: pointty): tcomponent; + begin + getcompatpos(mousepos,result); + end; + + procedure removehint(); + begin + if fhintedcomp <> nil then begin + application.hidehint(); + fhintedcomp:= nil; + end; + end; //removehint + +var + component: tcomponent; + int1: integer; + bo1,bo2: boolean; + widget1: twidget; + rect1: rectty; + selectmode: selectmodety; + area1: areaty; + isinpaintrect: boolean; + designactive: boolean; + po1: pformselectedinfoty; + pt1: pointty; + hintinfo1: hintinfoty; +label + 1; +begin + if (module = nil) or (info.mouse.eventkind = ek_mousewheel) then begin + exit; //continue normal handling + end; + if info.mouse.eventkind in [ek_mouseleave,ek_mouseenter] then begin + removehint(); + fclickedcompbefore:= nil; + include(info.mouse.eventstate,es_processed); + exit; + end; +// twindow1(window).checkmousewidget(info.mouse,capture); + with info.mouse do begin + designactive:= (capture <> nil) and + (ws1_designactive in twidget1(capture).fwidgetstate1); + mousepos1:= translatewidgetpoint(pos,window.owner,self); + ss1:= shiftstate * (shiftstatesmask); + isinpaintrect:= pointinrect(mousepos1,gridrect); + if eventkind in [ek_buttonpress,ek_buttonrelease] then begin + fmousepos:= mousepos1; + end; + if (fhintedcomp <> nil) and + (info.mouse.eventkind in mouseposevents) then begin + if getcompatpos(mousepos1) <> fhintedcomp then begin + removehint(); + end; + end; + if (info.mouse.eventkind = ek_mousepark) and application.active and + projectoptions.e.componenthints and (fhintedcomp = nil) then begin + bo1:= getcompatpos(mousepos1,fhintedcomp); + if (fhintedcomp <> nil) then begin + if bo1 then begin + widget1:= twidget(fhintedcomp); + end + else begin + if fform <> nil then begin + widget1:= fform; + end + else begin + widget1:= fformcont; + end; + end; + application.inithintinfo(hintinfo1,widget1); + hintinfo1.caption:= msestring( + fhintedcomp.name+' ('+fhintedcomp.classname+')'); + application.showhint(widget1,hintinfo1); + end; + end; + component:= nil; + if not (es_processed in eventstate) then begin + bo1:= false; + if (eventkind = ek_buttonpress) and (button = mb_left) then begin + fpickpos:= mousepos1; + if (ss1 = [ss_left]) or (ss1 = [ss_left,ss_ctrl]){ or + (ss1 = [ss_left,ss_ctrl,ss_shift])} then begin + actarea:= fselections.getareainfo(mousepos1,factcompindex); + if factcompindex >= 0 then begin + fsizerect:= fselections.itempo(factcompindex)^.rect; + factsizerect:= fsizerect; + end; + if (actarea in [ar_component,ar_none]) and + not (ss_shift in ss1) then begin + if isinpaintrect then begin + component:= getcompatpos(mousepos1); + end; + if component <> nil then begin + if (factcompindex < 0) or + (component <> fselections[factcompindex]) then begin + actarea:= ar_none; + end; + bo1:= true; + end + else begin + actarea:= ar_none; + end; + fclickedcompbefore:= component; + end + else begin + capturemouse; + include(eventstate,es_processed); + end; + end + end; + if (eventkind = ek_buttonrelease) and (button = mb_right) and + not (es_processed in eventstate) then begin + pt1:= info.mouse.pos; + try + translatewidgetpoint1(info.mouse.pos,window.owner,self); + dopopup(info.mouse); + finally + info.mouse.pos:= pt1; + end; + end; + if not (es_processed in eventstate) and + (ss1 <> [ss_left,ss_shift,ss_ctrl]) then begin + area1:= fselections.getareainfo(mousepos1,int1); + bo2:= not ((eventkind = ek_buttonpress) and (button = mb_left) and + (ss1 = [ss_left])); + if not ((ss_double in shiftstate) and (eventkind = ek_buttonpress) + or (ss1 = [ss_left,ss_shift])) and + (bo2 or + ((area1 < firsthandle) or (area1 > lasthandle)) and + (not (fdesigner.hascurrentcomponent or + componentstorefo.hasselection)) + ) and + ((actarea < firsthandle) or (actarea > lasthandle)) and + (actarea <> ar_componentmove) then begin + twindow1(window).dispatchmouseevent(info,capture); //"inherited" + if not designactive then begin + exclude(eventstate,es_processed); + end; + if es_processed in eventstate then begin + releasemouse(); + end; + end; + if bo1 then begin + if ss_ctrl in ss1 then begin + selectcomponent(component,sm_flip); + end + else begin + bo2:= fselections.indexof(component) < 0; + if (component = form) and (fselections.count > 1) or bo2 then begin + selectcomponent(component,sm_select); + if projectoptions.e.moveonfirstclick then begin + actarea:= ar_component; + end; + end + else begin + if not bo2 then begin + updateclickedcomponent; + end; + end; + end; + if not (es_processed in eventstate) then begin + if not designactive then begin + capturemouse; //capture mouse + end; + updatecursorshape(ss1,actarea); + end + else begin + actarea:= ar_none; + end; + end; + end; + if not (es_processed in eventstate) then begin + if (eventkind = ek_buttonpress) and (button = mb_left) then begin + if (ss1 = [ss_left]) or (ss1 = [ss_left,ss_shift,ss_ctrl]) then begin + if isinpaintrect then begin + component:= fdesigner.createcurrentcomponent(module); + if (component = nil) and componentstorefo.hasselection then begin + dopaste(true,componentstorefo.copyselected); + end; + end; + if component <> nil then begin + if (ss1 = [ss_left,ss_shift,ss_ctrl]) and + (fselections.count = 1) then begin + //insert in current selected widget + placecomponent(component,mousepos1,fselections[0]); + end + else begin + placecomponent(component,mousepos1); + end; + end; + end + else begin + if (ss1 = [ss_left,ss_shift]) and isinpaintrect then begin + actarea:= ar_selectrect; + capturemouse(); + fxorpicoffset:= mousepos1; + if form <> nil then begin + fpickwidget:= widgetatpos(mousepos1,false); + end + else begin + fpickwidget:= self; + end; + end; + end; + end; + if (eventkind = ek_buttonrelease) and (button = mb_left) then begin + hidexorpic(getcanvas(org_widget)); + fxorpicactive:= false; + case actarea of + firsthandle..lasthandle: begin + if (factcompindex >= 0) and + (factcompindex < fselections.count) then begin + component:= tcomponent( + fselections.itempo(factcompindex)^.selectedinfo.instance); + if (component is twidget) and (form <> nil) then begin + with twidget(component) do begin + translatewidgetpoint1(factsizerect.pos,self,parentwidget); + widgetrect:= factsizerect; + end; + fselections.componentschanged; + end + else begin + if component is tmsedatamodule then begin + rect1:= getcomponentrect1(component); + with tmsedatamodule(component) do begin + subpoint1(factsizerect.pos,rect1.pos); + setcomponentpos(component, + addpoint(getcomponentpos(component),factsizerect.pos)); + size:= factsizerect.size; + end; + fselections.componentschanged; + end; + end; + end; + invalidate(); + end; + ar_componentmove: begin + if fselections.move(griddelta) then begin + invalidate(); //redraw handles + clientsizechanged; + end; + end; + ar_component: begin + if ss_double in shiftstate then begin + designer.showobjectinspector; + end; + end; + ar_selectrect: begin + if fpickwidget <> nil then begin + rect1.pos:= fpickpos; + rect1.cx:= mousepos1.x - fpickpos.x; + rect1.cy:= mousepos1.y - fpickpos.y; + if (rect1.cx < 0) or (rect1.cy < 0) then begin + selectmode:= sm_remove; + end + else begin + selectmode:= sm_add; + end; + beginselect; + try + if (selectmode = sm_add) and (fselections.count = 1) and + (fselections[0] = module) then begin + fselections.clear; //remove underlaying form + end; + for int1:= 0 to module.componentcount - 1 do begin + component:= module.Components[int1]; + if (form = nil) or (not (component is twidget)) then begin + if rectinrect(getcomponentrect1(component),rect1) then begin + selectcomponent(component,selectmode); + end; + end; + end; + if fpickwidget <> self then begin + rect1.pos:= translatewidgetpoint(fpickpos,self,fpickwidget); + for int1:= 0 to fpickwidget.widgetcount -1 do begin + widget1:= fpickwidget.widgets[int1]; + if rectinrect(widget1.widgetrect,rect1) and + (ws_iswidget in widget1.widgetstate) then begin + selectcomponent(widget1,selectmode); + end; + end; + end; + finally + endselect; + end; + end; + end; + end; + fpickwidget:= nil; + actarea:= ar_none; + if factcompindex >= 0 then begin + factcompindex:= -1; + updateclickedcomponent; //update objectionspector componentname + end; + releasemouse(); + end; + + if not (es_processed in eventstate) then begin + if (eventkind = ek_mousemove) or (eventkind = ek_mousepark) then begin + hidexorpic(getcanvas(org_widget)); + bo1:= true; + case actarea of + firsthandle..lasthandle: begin + updatesizerect; + end; + ar_component: begin + if (distance(fpickpos,mousepos1) > movethreshold) then begin + fxorpicoffset:= griddelta; + actarea:= ar_componentmove; + capturemouse(); + end + else begin + bo1:= false; + end; + end; + ar_componentmove: begin + fxorpicoffset:= griddelta; + end; + ar_selectrect: begin + fxorpicoffset:= mousepos1; + end; + else begin + bo1:= false; + fmovearea:= fselections.getareainfo(mousepos1,int1); + updatecursorshape(ss1,fmovearea); + end; + end; + if bo1 then begin + fxorpicactive:= true; + if not (actarea in [ar_component,firsthandle..lasthandle]) then begin + fselections.beforepaintmoving; //resets canvas + end; + showxorpic(getcanvas(org_widget)); + end; + end; + end; + end; + end; +1: + if (eventkind in mouseposevents) and (fselections.count = 1) then begin + fselections.updateinfos; + po1:= fselections.itempo(0); + if po1^.selectedinfo.instance <> fmodule then begin + bo1:= true; + case actarea of + ar_component: begin + if (eventkind = ek_buttonpress) and (button = mb_left) then begin + pt1:= rectcenter(po1^.handles[ht_topleft]); + end + else begin + bo1:= false; + end; + end; + ht_topleft: begin + pt1:= factsizerect.pos; + end; + ht_left: begin + with factsizerect do begin + pt1.x:= x; + pt1.y:= y + cy div 2; + end; + end; + ht_bottomleft: begin + with factsizerect do begin + pt1.x:= x; + pt1.y:= y + cy; + end; + end; + ht_bottom: begin + with factsizerect do begin + pt1.x:= x + cx div 2; + pt1.y:= y + cy ; + end; + end; + ht_bottomright: begin + with factsizerect do begin + pt1.x:= x + cx; + pt1.y:= y + cy; + end; + end; + ht_right: begin + with factsizerect do begin + pt1.x:= x + cx; + pt1.y:= y + cy div 2; + end; + end; + ht_topright: begin + with factsizerect do begin + pt1.x:= x + cx; + pt1.y:= y; + end; + end; + ht_top: begin + with factsizerect do begin + pt1.x:= x + cx div 2; + pt1.y:= y; + end; + end; + ar_componentmove: begin + pt1:= addpoint(rectcenter(po1^.handles[ht_topleft]),fxorpicoffset); + end; + else begin + bo1:= false; + end; + end; + if bo1 then begin + componentmoving(pt1); + end; + end; + end; + end; + include(info.mouse.eventstate,es_processed); +end; + +procedure tformdesignerfo.designkeyevent(const eventkind: eventkindty; + var info: keyeventinfoty); +var + po1: pointty; + comp1: tcomponent; + shiftstate1: shiftstatesty; + actareabefore: areaty; +begin + if module = nil then begin + exit; + end; + shiftstate1:= info.shiftstate * keyshiftstatesmask; + if actarea = ar_none then begin + updatecursorshape(shiftstate1,fmovearea); + end; + if eventkind = ek_keypress then begin + with info do begin + if shiftstate1 = [] then begin + include(eventstate,es_processed); + case key of + key_return: begin + if not designer.editcomponent(module) then begin + exclude(eventstate,es_processed); + end; + end; + key_escape: begin + if not (actarea in [ar_none,ar_component]) then begin + hidexorpic(getcanvas(org_widget)); + fxorpicactive:= false; + actarea:= ar_none; + end + else begin + if (fselections.count > 1) and (actarea <> ar_component) then begin + selectcomponent(module); + end + else begin + if fselections.count > 0 then begin + if actarea = ar_component then begin + comp1:= fselections[factcompindex]; + end + else begin + comp1:= fselections[0]; + end; + if iswidgetcomp(comp1) then begin + repeat + comp1:= twidget(comp1).parentwidget; + until (comp1 = nil) or (ws_iswidget in twidget(comp1).widgetstate); + actareabefore:= actarea; + if (comp1 <> nil) and (comp1 <> self) then begin + if fselections.count > 1 then begin + selectparentwidget(twidget(comp1)); + end + else begin + selectcomponent(comp1); + end; + end + else begin + selectcomponent(module); + end; + actarea:= actareabefore; + end + else begin +// if isdatasubmodule(comp1.owner) then begin + selectcomponent(comp1.owner); +// end +// else begin +// selectcomponent(module); +// end; + end; + end; + end; + end; + end; + key_delete: begin + if fselections.candelete then begin + dodelete; + end; + end; + else begin + exclude(eventstate,es_processed); + end; + end; + end + else begin + if (shiftstate1 = [ss_ctrl]) or (shiftstate1 = [ss_shift]) then begin + include(eventstate,es_processed); + po1:= nullpoint; + case key of + key_right: po1.x:= 1; + key_up: po1.y:= -1; + key_left: po1.x:= -1; + key_down: po1.y:= 1; + else exclude(eventstate,es_processed); + end; + if (es_processed in eventstate) then begin + if shiftstate1 = [ss_ctrl] then begin + fselections.move(po1); + if fselections.count > 0 then begin + fselections.updateinfos; + componentmoving(rectcenter(fselections.itempo(0)^.handles[ht_topleft])); + end; + end + else begin + fselections.resize(po1); + if fselections.count > 0 then begin + fselections.updateinfos; + with fselections.itempo(0)^.handles[ht_bottomright] do begin + componentmoving(makepoint(x+cx div 2 + 1,y+cy div 2 +1)); + end; + end; + end; + invalidate(); + clientsizechanged(); + end; + end; + end; + if not (es_processed in eventstate) then begin + if issysshortcut(sho_copy,info) then begin + docopy(false); + include(eventstate,es_processed); + end + else begin + if issysshortcut(sho_cut,info) then begin + docut; + include(eventstate,es_processed); + end + else begin + if issysshortcut(sho_paste,info) then begin + dopaste(false,''); + include(eventstate,es_processed); + end; + end; + end; + end; + end; + end; +end; + +function tformdesignerfo.isdesignwidget(): boolean; +begin + result:= true; +end; + +function tformdesignerfo.getmodulesize: sizety; +var + asize: sizety; + int1: integer; + pt1: pointty; +begin + if fform <> nil then begin + result:= fform.size; + end + else begin + if fmodule is tmsedatamodule then begin + result:= tmsedatamodule(fmodule).size; + end + else begin + asize:= nullsize; + for int1:= 0 to fmodule.ComponentCount - 1 do begin + pt1:= getcomponentpos(fmodule.Components[int1]); + if pt1.x > asize.cx then begin + asize.cx:= pt1.x; + end; + if pt1.y > asize.cy then begin + asize.cy:= pt1.y; + end; + end; + inc(asize.cx,80); + inc(asize.cy,30); //todo: correct size, scrollbox + result:= asize; + end; + end; +end; + +function tformdesignerfo.getmodulerect: rectty; +begin + result.pos:= fmodulepos; + result.size:= getmodulesize(); +end; + +function tformdesignerfo.getmodulepos_x: integer; +begin + result:= fmodulepos.x; +end; + +function tformdesignerfo.getmodulepos_y: integer; +begin + result:= fmodulepos.y; +end; + +procedure tformdesignerfo.setmodulepos_x(const avalue: integer); +begin + if fmodulepos.x <> avalue then begin + fmodulepos.x:= avalue; + checksynctomodulepos(); + end; +end; + +procedure tformdesignerfo.setmodulepos_y(const avalue: integer); +begin + if fmodulepos.y <> avalue then begin + fmodulepos.y:= avalue; + checksynctomodulepos(); + end; +end; + +function tformdesignerfo.getdockcontroller(): tdockcontroller; +begin + result:= dragdock; +end; + +procedure tformdesignerfo.updatedockinfo(); +begin +{ + with fmoduleinfo^.dockinfo do begin + panelname:= dragdock.dockparentname(); + rect:= widgetrect; + end; +} +end; + +function tformdesignerfo.checkdelete: boolean; +begin + result:= true; +end; + +procedure tformdesignerfo.enterexe(const sender: TObject); +begin + mainfo.designformactivated(self); +end; + +procedure tformdesignerfo.setactarea(const avalue: areaty); +begin + factarea:= avalue; + fmovearea:= factarea; +end; + + +{ tformdesignerdockcontroller } + +procedure tformdesignerdockcontroller.dostatplace(const aparent: twidget; + const avisible: boolean; arect: rectty); +begin + if (aparent <> nil) then begin //do not change undocked position + inherited; + end; +end; + +initialization +finalization + freeandnil(fregistereddesignmoduleclasses); +end. diff --git a/mseide-msegui/apps/ide/formdesigner_mfm.pas b/mseide-msegui/apps/ide/formdesigner_mfm.pas new file mode 100644 index 0000000..941f026 --- /dev/null +++ b/mseide-msegui/apps/ide/formdesigner_mfm.pas @@ -0,0 +1,375 @@ +unit formdesigner_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,formdesigner; + +const + objdata: record size: integer; data: array[0..7146] of byte end = + (size: 7147; data: ( + 84,80,70,48,15,116,102,111,114,109,100,101,115,105,103,110,101,114,102,111, + 14,102,111,114,109,100,101,115,105,103,110,101,114,102,111,13,111,112,116,105, + 111,110,115,119,105,100,103,101,116,11,11,111,119,95,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95, + 97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111, + 119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111,99,117, + 115,13,111,119,95,109,111,117,115,101,119,104,101,101,108,9,111,119,95,104, + 105,110,116,111,110,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19, + 111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0, + 5,99,111,108,111,114,4,5,0,0,144,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,15,102,114,97,109,101,46,103,114,105, + 112,95,115,105,122,101,2,0,18,102,114,97,109,101,46,103,114,105,112,95, + 111,112,116,105,111,110,115,11,14,103,111,95,99,108,111,115,101,98,117,116, + 116,111,110,16,103,111,95,102,105,120,115,105,122,101,98,117,116,116,111,110, + 14,103,111,95,102,108,111,97,116,98,117,116,116,111,110,12,103,111,95,116, + 111,112,98,117,116,116,111,110,19,103,111,95,98,97,99,107,103,114,111,117, + 110,100,98,117,116,116,111,110,14,103,111,95,98,117,116,116,111,110,104,105, + 110,116,115,0,30,102,114,97,109,101,46,103,114,105,112,95,102,97,99,101, + 46,102,97,100,101,95,112,111,115,46,99,111,117,110,116,2,1,30,102,114, + 97,109,101,46,103,114,105,112,95,102,97,99,101,46,102,97,100,101,95,112, + 111,115,46,105,116,101,109,115,1,2,0,0,32,102,114,97,109,101,46,103, + 114,105,112,95,102,97,99,101,46,102,97,100,101,95,99,111,108,111,114,46, + 99,111,117,110,116,2,1,32,102,114,97,109,101,46,103,114,105,112,95,102, + 97,99,101,46,102,97,100,101,95,99,111,108,111,114,46,105,116,101,109,115, + 1,4,19,0,0,160,0,26,102,114,97,109,101,46,103,114,105,112,95,102, + 97,99,101,46,108,111,99,97,108,112,114,111,112,115,11,0,9,112,111,112, + 117,112,109,101,110,117,7,7,112,111,112,117,112,109,101,7,111,110,101,110, + 116,101,114,7,8,101,110,116,101,114,101,120,101,10,111,110,97,99,116,105, + 118,97,116,101,7,8,101,110,116,101,114,101,120,101,7,118,105,115,105,98, + 108,101,8,8,98,111,117,110,100,115,95,120,2,68,8,98,111,117,110,100, + 115,95,121,3,21,1,9,98,111,117,110,100,115,95,99,120,3,31,1,9, + 98,111,117,110,100,115,95,99,121,3,44,1,23,99,111,110,116,97,105,110, + 101,114,46,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119, + 95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111, + 99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119, + 95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114, + 111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111,99, + 117,115,19,111,119,95,109,111,117,115,101,116,114,97,110,115,112,97,114,101, + 110,116,13,111,119,95,109,111,117,115,101,119,104,101,101,108,0,15,99,111, + 110,116,97,105,110,101,114,46,99,111,108,111,114,4,5,0,0,144,26,99, + 111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,0,27,99,111,110,116,97,105,110,101,114,46,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,29,99,111, + 110,116,97,105,110,101,114,46,111,110,99,97,108,99,109,105,110,115,99,114, + 111,108,108,115,105,122,101,7,14,99,97,108,99,115,99,114,111,108,108,115, + 105,122,101,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115, + 1,2,0,2,0,3,31,1,3,44,1,0,20,100,114,97,103,100,111,99, + 107,46,111,112,116,105,111,110,115,100,111,99,107,11,10,111,100,95,115,97, + 118,101,112,111,115,13,111,100,95,115,97,118,101,122,111,114,100,101,114,10, + 111,100,95,99,97,110,109,111,118,101,10,111,100,95,99,97,110,115,105,122, + 101,11,111,100,95,99,97,110,102,108,111,97,116,10,111,100,95,99,97,110, + 100,111,99,107,11,111,100,95,112,114,111,112,115,105,122,101,14,111,100,95, + 99,97,112,116,105,111,110,104,105,110,116,13,111,100,95,99,104,105,108,100, + 105,99,111,110,115,0,22,100,114,97,103,100,111,99,107,46,111,110,98,101, + 102,111,114,101,102,108,111,97,116,7,11,98,101,102,102,108,111,97,116,101, + 120,101,16,100,114,97,103,100,111,99,107,46,111,110,102,108,111,97,116,7, + 8,102,108,111,97,116,101,120,101,13,111,112,116,105,111,110,115,119,105,110, + 100,111,119,11,12,119,111,95,110,111,116,97,115,107,98,97,114,0,7,111, + 112,116,105,111,110,115,11,10,102,111,95,115,97,118,101,112,111,115,13,102, + 111,95,115,97,118,101,122,111,114,100,101,114,12,102,111,95,115,97,118,101, + 115,116,97,116,101,0,8,115,116,97,116,102,105,108,101,7,22,109,97,105, + 110,102,111,46,112,114,111,106,101,99,116,115,116,97,116,102,105,108,101,21, + 105,99,111,110,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111, + 114,4,6,0,0,128,10,105,99,111,110,46,105,109,97,103,101,10,216,7, + 0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0,0,0,164,7, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,25,242,166, + 149,1,221,216,211,1,242,166,149,1,255,134,109,2,121,64,52,1,157,83, + 67,1,187,98,80,1,208,109,89,2,247,130,106,1,212,111,91,1,255,134, + 109,4,160,160,160,6,128,128,128,1,255,255,255,1,221,216,211,1,7,239, + 255,1,221,216,211,1,255,134,109,2,120,63,51,1,201,106,86,1,181,95, + 77,1,135,71,58,1,214,112,91,1,139,73,59,1,163,86,70,1,242,127, + 103,1,255,134,109,3,160,160,160,1,212,212,212,1,128,128,128,1,160,160, + 160,1,209,209,209,1,128,128,128,2,255,255,255,1,242,166,149,1,221,216, + 211,1,242,166,149,1,255,134,109,2,212,111,91,1,255,134,109,1,218,115, + 93,1,204,107,87,1,180,95,77,1,222,117,95,1,184,97,79,1,253,133, + 108,1,255,134,109,3,160,160,160,1,212,212,212,1,128,128,128,1,160,160, + 160,1,209,209,209,1,128,128,128,2,255,255,255,1,151,24,0,16,128,128, + 128,7,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227, + 227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222, + 222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217, + 217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211, + 211,1,210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1,255,255, + 255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226, + 226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221, + 221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215, + 215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210, + 210,1,209,209,209,1,208,208,208,1,128,128,128,1,255,255,255,1,230,230, + 230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225, + 225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220, + 220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214, + 214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209, + 209,1,208,208,208,1,128,128,128,1,255,255,255,1,230,230,230,1,229,229, + 229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224, + 224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219, + 219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213, + 213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208, + 208,1,128,128,128,1,255,255,255,1,230,230,230,1,229,229,229,1,228,228, + 228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223, + 223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218, + 218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212, + 212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,128,128, + 128,1,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227, + 227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222, + 222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217, + 217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211, + 211,1,210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1,255,255, + 255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226, + 226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221, + 221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215, + 215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210, + 210,1,209,209,209,1,208,208,208,1,128,128,128,1,255,255,255,1,230,230, + 230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225, + 225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220, + 220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214, + 214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209, + 209,1,208,208,208,1,128,128,128,1,255,255,255,1,230,230,230,1,229,229, + 229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224, + 224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219, + 219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213, + 213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208, + 208,1,128,128,128,1,255,255,255,1,230,230,230,1,229,229,229,1,228,228, + 228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223, + 223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218, + 218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212, + 212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,128,128, + 128,1,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227, + 227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222, + 222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217, + 217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211, + 211,1,210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1,255,255, + 255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226, + 226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221, + 221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215, + 215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210, + 210,1,209,209,209,1,208,208,208,1,128,128,128,1,255,255,255,1,230,230, + 230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225, + 225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220, + 220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214, + 214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209, + 209,1,208,208,208,1,128,128,128,1,255,255,255,1,230,230,230,1,229,229, + 229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224, + 224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219, + 219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213, + 213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208, + 208,1,128,128,128,1,255,255,255,1,230,230,230,1,229,229,229,1,228,228, + 228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223, + 223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218, + 218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212, + 212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,128,128, + 128,1,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227, + 227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222, + 222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217, + 217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211, + 211,1,210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1,255,255, + 255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226, + 226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221, + 221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215, + 215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210, + 210,1,209,209,209,1,208,208,208,1,128,128,128,1,255,255,255,1,230,230, + 230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225, + 225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220, + 220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214, + 214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209, + 209,1,208,208,208,1,128,128,128,25,7,111,110,99,108,111,115,101,7,13, + 102,111,114,109,100,101,111,110,99,108,111,115,101,4,108,101,102,116,3,239, + 0,3,116,111,112,3,180,0,15,109,111,100,117,108,101,99,108,97,115,115, + 110,97,109,101,6,9,116,100,111,99,107,102,111,114,109,0,10,116,112,111, + 112,117,112,109,101,110,117,7,112,111,112,117,112,109,101,18,109,101,110,117, + 46,115,117,98,109,101,110,117,46,99,111,117,110,116,2,33,18,109,101,110, + 117,46,115,117,98,109,101,110,117,46,105,116,101,109,115,14,1,7,99,97, + 112,116,105,111,110,6,20,83,104,111,119,32,111,98,106,101,99,116,105,110, + 115,112,101,99,116,111,114,5,115,116,97,116,101,11,15,97,115,95,108,111, + 99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111, + 110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7, + 21,100,111,115,104,111,119,111,98,106,101,99,116,105,110,115,112,101,99,116, + 111,114,0,1,7,99,97,112,116,105,111,110,6,21,83,104,111,119,32,99, + 111,109,112,111,110,101,110,116,112,97,108,101,116,116,101,5,115,116,97,116, + 101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97, + 115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110, + 101,120,101,99,117,116,101,7,22,100,111,115,104,111,119,99,111,109,112,111, + 110,101,110,116,112,97,108,101,116,116,101,0,1,7,99,97,112,116,105,111, + 110,6,12,83,104,111,119,32,97,115,32,84,101,120,116,5,115,116,97,116, + 101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97, + 115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,7,111,112, + 116,105,111,110,115,11,19,109,97,111,95,115,104,111,114,116,99,117,116,99, + 97,112,116,105,111,110,16,109,97,111,95,97,115,121,110,99,101,120,101,99, + 117,116,101,0,9,111,110,101,120,101,99,117,116,101,7,12,100,111,115,104, + 111,119,97,115,116,101,120,116,0,1,7,111,112,116,105,111,110,115,11,13, + 109,97,111,95,115,101,112,97,114,97,116,111,114,19,109,97,111,95,115,104, + 111,114,116,99,117,116,99,97,112,116,105,111,110,0,0,1,6,97,99,116, + 105,111,110,7,11,104,105,100,101,99,111,109,112,97,99,116,7,111,112,116, + 105,111,110,115,11,12,109,97,111,95,99,104,101,99,107,98,111,120,19,109, + 97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111,110,0,0, + 1,6,97,99,116,105,111,110,7,13,104,105,100,101,119,105,100,103,101,116, + 97,99,116,7,111,112,116,105,111,110,115,11,12,109,97,111,95,99,104,101, + 99,107,98,111,120,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97, + 112,116,105,111,110,0,0,1,6,97,99,116,105,111,110,7,13,116,111,103, + 103,108,101,104,105,100,101,97,99,116,0,1,6,97,99,116,105,111,110,7, + 10,115,104,111,119,97,108,108,97,99,116,0,1,7,111,112,116,105,111,110, + 115,11,13,109,97,111,95,115,101,112,97,114,97,116,111,114,19,109,97,111, + 95,115,104,111,114,116,99,117,116,99,97,112,116,105,111,110,0,0,1,7, + 99,97,112,116,105,111,110,6,17,67,111,112,121,32,67,111,109,112,111,110, + 101,110,116,40,115,41,4,110,97,109,101,6,4,99,111,112,121,5,115,116, + 97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110, + 16,97,115,95,108,111,99,97,108,115,104,111,114,116,99,117,116,17,97,115, + 95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101, + 120,101,99,117,116,101,7,7,99,111,112,121,101,120,101,2,115,99,1,2, + 1,3,67,64,0,0,1,7,99,97,112,116,105,111,110,6,16,67,117,116, + 32,67,111,109,112,111,110,101,110,116,40,115,41,4,110,97,109,101,6,3, + 99,117,116,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99, + 97,112,116,105,111,110,16,97,115,95,108,111,99,97,108,115,104,111,114,116, + 99,117,116,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116, + 101,0,7,111,112,116,105,111,110,115,11,19,109,97,111,95,115,104,111,114, + 116,99,117,116,99,97,112,116,105,111,110,16,109,97,111,95,97,115,121,110, + 99,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7, + 6,99,117,116,101,120,101,2,115,99,1,2,1,3,88,64,0,0,1,7, + 99,97,112,116,105,111,110,6,18,80,97,115,116,101,32,67,111,109,112,111, + 110,101,110,116,40,115,41,4,110,97,109,101,6,5,112,97,115,116,101,5, + 115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105, + 111,110,16,97,115,95,108,111,99,97,108,115,104,111,114,116,99,117,116,17, + 97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111, + 110,101,120,101,99,117,116,101,7,8,112,97,115,116,101,101,120,101,2,115, + 99,1,2,1,3,86,64,0,0,1,7,99,97,112,116,105,111,110,6,19, + 68,101,108,101,116,101,32,67,111,109,112,111,110,101,110,116,40,115,41,4, + 110,97,109,101,6,6,100,101,108,101,116,101,5,115,116,97,116,101,11,15, + 97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,16,97,115,95,108, + 111,99,97,108,115,104,111,114,116,99,117,116,17,97,115,95,108,111,99,97, + 108,111,110,101,120,101,99,117,116,101,0,7,111,112,116,105,111,110,115,11, + 19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111,110, + 16,109,97,111,95,97,115,121,110,99,101,120,101,99,117,116,101,0,9,111, + 110,101,120,101,99,117,116,101,7,9,100,101,108,101,116,101,101,120,101,2, + 115,99,1,2,1,3,7,1,0,0,1,7,99,97,112,116,105,111,110,6, + 21,85,110,100,101,108,101,116,101,32,67,111,109,112,111,110,101,110,116,40, + 115,41,4,110,97,109,101,6,8,117,110,100,101,108,101,116,101,5,115,116, + 97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110, + 17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9, + 111,110,101,120,101,99,117,116,101,7,11,117,110,100,101,108,101,116,101,101, + 120,101,0,1,7,111,112,116,105,111,110,115,11,13,109,97,111,95,115,101, + 112,97,114,97,116,111,114,19,109,97,111,95,115,104,111,114,116,99,117,116, + 99,97,112,116,105,111,110,0,0,1,6,97,99,116,105,111,110,7,24,97, + 99,116,105,111,110,115,109,111,46,102,105,110,100,99,111,109,112,97,108,108, + 97,99,116,7,99,97,112,116,105,111,110,6,14,70,105,110,100,32,67,111, + 109,112,111,110,101,110,116,5,115,116,97,116,101,11,15,97,115,95,108,111, + 99,97,108,99,97,112,116,105,111,110,0,0,1,7,99,97,112,116,105,111, + 110,6,18,83,101,108,101,99,116,32,67,104,105,108,100,119,105,100,103,101, + 116,4,110,97,109,101,6,11,115,101,108,101,99,116,99,104,105,108,100,5, + 115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105, + 111,110,0,0,1,7,99,97,112,116,105,111,110,6,8,38,73,99,111,110, + 105,102,121,4,110,97,109,101,6,7,105,99,111,110,105,102,121,5,115,116, + 97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110, + 17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9, + 111,110,101,120,101,99,117,116,101,7,9,100,111,105,99,111,110,105,102,121, + 0,1,7,99,97,112,116,105,111,110,6,10,38,68,101,105,99,111,110,105, + 102,121,4,110,97,109,101,6,9,100,101,105,99,111,110,105,102,121,5,115, + 116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111, + 110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0, + 9,111,110,101,120,101,99,117,116,101,7,11,100,111,100,101,105,99,111,110, + 105,102,121,0,1,7,111,112,116,105,111,110,115,11,13,109,97,111,95,115, + 101,112,97,114,97,116,111,114,19,109,97,111,95,115,104,111,114,116,99,117, + 116,99,97,112,116,105,111,110,0,0,1,7,99,97,112,116,105,111,110,6, + 15,38,69,100,105,116,32,67,111,109,112,111,110,101,110,116,4,110,97,109, + 101,6,8,101,100,105,116,99,111,109,112,5,115,116,97,116,101,11,15,97, + 115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111, + 99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99, + 117,116,101,7,15,100,111,101,100,105,116,99,111,109,112,111,110,101,110,116, + 0,1,7,99,97,112,116,105,111,110,6,20,83,121,110,99,46,32,116,111, + 32,70,111,110,116,32,72,101,105,103,104,116,4,110,97,109,101,6,8,115, + 121,110,99,116,111,102,111,5,115,116,97,116,101,11,15,97,115,95,108,111, + 99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111, + 110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7, + 16,100,111,115,121,110,99,102,111,110,116,104,101,105,103,104,116,0,1,7, + 99,97,112,116,105,111,110,6,14,66,114,105,110,103,32,116,111,32,70,114, + 111,110,116,4,110,97,109,101,6,10,98,114,105,110,103,116,111,102,114,111, + 5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116, + 105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116, + 101,0,9,111,110,101,120,101,99,117,116,101,7,14,100,111,98,114,105,110, + 103,116,111,102,114,111,110,116,0,1,7,99,97,112,116,105,111,110,6,12, + 83,101,110,100,32,116,111,32,66,97,99,107,4,110,97,109,101,6,8,115, + 101,110,100,116,111,98,97,5,115,116,97,116,101,11,15,97,115,95,108,111, + 99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111, + 110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7, + 12,100,111,115,101,110,100,116,111,98,97,99,107,0,1,7,99,97,112,116, + 105,111,110,6,16,83,101,116,32,87,105,100,103,101,116,32,79,114,100,101, + 114,4,110,97,109,101,6,12,115,101,116,119,105,100,103,101,116,111,114,100, + 5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116, + 105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116, + 101,0,9,111,110,101,120,101,99,117,116,101,7,16,100,111,115,101,116,119, + 105,100,103,101,116,111,114,100,101,114,0,1,7,99,97,112,116,105,111,110, + 6,13,83,101,116,32,84,97,98,32,79,114,100,101,114,4,110,97,109,101, + 6,9,115,101,116,116,97,98,111,114,100,5,115,116,97,116,101,11,15,97, + 115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111, + 99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99, + 117,116,101,7,13,100,111,115,101,116,116,97,98,111,114,100,101,114,0,1, + 7,99,97,112,116,105,111,110,6,18,83,101,116,32,67,114,101,97,116,105, + 111,110,32,79,114,100,101,114,5,115,116,97,116,101,11,15,97,115,95,108, + 111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108, + 111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101, + 7,18,100,111,115,101,116,99,114,101,97,116,105,111,110,111,114,100,101,114, + 0,1,7,99,97,112,116,105,111,110,6,19,82,101,118,101,114,116,32,116, + 111,32,105,110,104,101,114,105,116,101,100,4,110,97,109,101,6,6,114,101, + 118,101,114,116,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120, + 101,99,117,116,101,0,7,111,112,116,105,111,110,115,11,19,109,97,111,95, + 115,104,111,114,116,99,117,116,99,97,112,116,105,111,110,16,109,97,111,95, + 97,115,121,110,99,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99, + 117,116,101,7,9,114,101,118,101,114,116,101,120,101,0,1,7,111,112,116, + 105,111,110,115,11,13,109,97,111,95,115,101,112,97,114,97,116,111,114,19, + 109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111,110,0, + 0,1,7,99,97,112,116,105,111,110,6,10,84,111,117,99,104,32,70,111, + 114,109,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97, + 112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99, + 117,116,101,0,9,111,110,101,120,101,99,117,116,101,7,7,100,111,116,111, + 117,99,104,0,1,7,99,97,112,116,105,111,110,6,15,84,111,117,99,104, + 32,97,108,108,32,70,111,114,109,115,5,115,116,97,116,101,11,15,97,115, + 95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99, + 97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117, + 116,101,7,11,116,111,117,99,104,97,108,108,101,120,101,0,1,7,99,97, + 112,116,105,111,110,6,16,73,110,115,101,114,116,32,83,117,98,109,111,100, + 117,108,101,4,110,97,109,101,6,9,105,110,115,101,114,116,115,117,98,5, + 115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105, + 111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101, + 0,9,111,110,101,120,101,99,117,116,101,7,17,100,111,105,110,115,101,114, + 116,115,117,98,109,111,100,117,108,101,0,1,7,99,97,112,116,105,111,110, + 6,16,73,110,115,101,114,116,32,67,111,109,112,111,110,101,110,116,4,110, + 97,109,101,6,10,105,110,115,101,114,116,99,111,109,112,5,115,116,97,116, + 101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97, + 115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110, + 101,120,101,99,117,116,101,7,17,100,111,105,110,115,101,114,116,99,111,109, + 112,111,110,101,110,116,0,0,4,108,101,102,116,2,48,3,116,111,112,2, + 40,0,0,7,116,97,99,116,105,111,110,11,104,105,100,101,99,111,109,112, + 97,99,116,7,99,97,112,116,105,111,110,6,16,72,105,100,101,32,38,67, + 111,109,112,111,110,101,110,116,115,8,111,110,99,104,97,110,103,101,7,11, + 104,105,100,101,99,111,109,112,101,120,101,4,108,101,102,116,3,144,0,3, + 116,111,112,2,40,0,0,7,116,97,99,116,105,111,110,13,104,105,100,101, + 119,105,100,103,101,116,97,99,116,7,99,97,112,116,105,111,110,6,13,72, + 105,100,101,32,38,87,105,100,103,101,116,115,8,111,110,117,112,100,97,116, + 101,7,19,117,112,100,97,116,101,119,105,100,103,101,116,104,105,100,101,101, + 120,101,8,111,110,99,104,97,110,103,101,7,13,104,105,100,101,119,105,100, + 103,101,116,101,120,101,4,108,101,102,116,3,144,0,3,116,111,112,2,56, + 0,0,7,116,97,99,116,105,111,110,13,116,111,103,103,108,101,104,105,100, + 101,97,99,116,7,99,97,112,116,105,111,110,6,25,38,72,105,100,101,32, + 87,105,100,103,101,116,115,60,62,67,111,109,112,111,110,101,110,116,115,9, + 111,110,101,120,101,99,117,116,101,7,13,116,111,103,103,108,101,104,105,100, + 101,101,120,101,4,108,101,102,116,3,144,0,3,116,111,112,2,72,0,0, + 7,116,97,99,116,105,111,110,10,115,104,111,119,97,108,108,97,99,116,7, + 99,97,112,116,105,111,110,6,9,38,83,104,111,119,32,97,108,108,9,111, + 110,101,120,101,99,117,116,101,7,10,115,104,111,119,97,108,108,101,120,101, + 4,108,101,102,116,3,144,0,3,116,111,112,2,88,0,0,16,116,115,116, + 114,105,110,103,99,111,110,116,97,105,110,101,114,1,99,12,115,116,114,105, + 110,103,115,46,100,97,116,97,1,6,34,68,111,32,121,111,117,32,119,105, + 115,104,32,116,111,32,114,101,118,101,114,116,32,116,111,32,105,110,104,101, + 114,105,116,101,100,6,23,116,104,101,32,115,101,108,101,99,116,101,100,32, + 99,111,109,112,111,110,101,110,116,63,6,38,68,111,32,121,111,117,32,119, + 97,110,116,32,116,111,32,116,111,117,99,104,32,97,108,108,32,108,111,97, + 100,101,100,32,102,111,114,109,115,63,0,4,108,101,102,116,2,48,3,116, + 111,112,2,72,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tformdesignerfo,''); +end. diff --git a/mseide-msegui/apps/ide/guitemplates.mfm b/mseide-msegui/apps/ide/guitemplates.mfm new file mode 100644 index 0000000..5cd4dfe --- /dev/null +++ b/mseide-msegui/apps/ide/guitemplates.mfm @@ -0,0 +1,426 @@ +object guitemplatesmo: tguitemplatesmo + bounds_cx = 483 + bounds_cy = 132 + onloaded = loadedexe + left = 99 + top = 135 + moduleclassname = 'tmsedatamodule' + object fadevertkonvex: tfacecomp + template.fade_pos.count = 2 + template.fade_pos.items = ( + 0 + 1 + ) + template.fade_color.count = 2 + template.fade_color.items = ( + 14408667 + 13158600 + ) + template.fade_direction = gd_down + left = 24 + top = 16 + end + object fadehorzconvex: tfacecomp + template.fade_pos.count = 2 + template.fade_pos.items = ( + 0 + 1 + ) + template.fade_color.count = 2 + template.fade_color.items = ( + 14408667 + 13158600 + ) + left = 24 + top = 40 + end + object fadehorzconcave: tfacecomp + template.fade_pos.count = 2 + template.fade_pos.items = ( + 0 + 1 + ) + template.fade_color.count = 2 + template.fade_color.items = ( + 14408667 + 13158600 + ) + template.fade_direction = gd_left + left = 144 + top = 40 + end + object fadevertconcave: tfacecomp + template.fade_pos.count = 2 + template.fade_pos.items = ( + 0 + 1 + ) + template.fade_color.count = 2 + template.fade_color.items = ( + 14408667 + 13158600 + ) + template.fade_direction = gd_up + left = 144 + top = 16 + end + object skin: tskincontroller + extenders = 0 + sb_horz_facebutton = fadevertkonvex + sb_horz_faceendbutton = fadevertkonvex + sb_vert_facebutton = fadehorzconvex + sb_vert_faceendbutton = fadehorzconvex + stepbutton_face = fadehorzconvex + widget_color = -2147483645 + container_face = fadehorzconvex + grid_fixrows_face = fadevertkonvex + button_face = fadevertkonvex + databutton_face = fadevertkonvex + framebutton_face = fadehorzconvex + tabbar_horz_face = fadevertconcave + tabbar_horz_tab_face = fadevertkonvex + tabbar_horzopo_face = fadevertconcave + tabbar_horzopo_tab_face = fadevertkonvex + tabbar_vert_face = fadehorzconcave + tabbar_vert_tab_face = fadevertkonvex + tabbar_vertopo_face = fadehorzconcave + tabbar_vertopo_tab_face = fadevertkonvex + mainmenu_face = fadevertconcave + left = 24 + top = 72 + end + object fadecontainer: tfacecomp + template.fade_pos.count = 2 + template.fade_pos.items = ( + 0 + 1 + ) + template.fade_color.count = 2 + template.fade_color.items = ( + -1610612731 + 13421772 + ) + left = 144 + top = 72 + end + object nullface: tfacecomp + left = 272 + top = 16 + end + object sysenv: tsysenvmanager + helpheader = 'MSEide Copyright 1999-2015 by Martin Schreiber'#10'Usage: mseide [OPTION]... [PROJECTFILE]'#10#10'Options:' + helpfooter = #10'Environment variables'#10'FPCDIR, FPCLIBDIR, MSEDIR, MSELIBDIR'#10'SYNTAXDEFDIR, TEMPLATEDIR, COMPSTOREDIR'#10'COMPILER, DEBUGGER, EXEEXT,TARGET,TARGETOSDIR'#10'can be used to override the settings macros.'#10#10'Have a lot of fun!'#10#10'Martin' + left = 24 + top = 96 + defs = ( + ( + ak_pararg + '-globstatfile' + ( ) + [] + '' + '' + 'Set path to global status file.' + '' + '' + ) + ( + ak_pararg + '-macrodef' + ( ) + [] + '' + ',{,,}' + 'Macro definition, will be overridden by ''Project''-''Options''-''Macros''.'#10' Example:'#10' --macrodef=MAC1,abc,MAC2,def' + '' + '' + ) + ( + ak_par + '-storeglobalmacros' + ( ) + [] + '' + '' + 'Store --macrodef values as global macros and terminate MSEide. ' + '' + '' + ) + ( + ak_pararg + '-macrogroup' + ( ) + [] + '' + '' + 'Use ''Project''-''Options''-''Macros''-''Active group'' number ,'#10' = 1..6.' + '' + '' + ) + ( + ak_par + 'np' + ( ) + [] + '' + '' + 'Do not load a project.' + '' + '' + ) + ( + ak_par + 'ns' + ( ) + [] + '' + '' + 'Do not use a skin, no fades.' + '' + '' + ) + ( + ak_par + '-help' + ( ) + [arf_help] + '' + '' + 'Display this help and exit.' + '' + ' ' + ) + ( + ak_envvar + 'FPCDIR' + ( ) + [] + '' + '' + '' + '' + '' + ) + ( + ak_envvar + 'FPCLIBDIR' + ( ) + [] + '' + '' + '' + '' + '' + ) + ( + ak_envvar + 'MSEDIR' + ( ) + [] + '' + '' + '' + '' + '' + ) + ( + ak_envvar + 'MSELIBDIR' + ( ) + [] + '' + '' + '' + '' + '' + ) + ( + ak_envvar + 'SYNTAXDEFDIR' + ( ) + [] + '' + '' + '' + '' + '' + ) + ( + ak_envvar + 'TEMPLATEDIR' + ( ) + [] + '' + '' + '' + '' + '' + ) + ( + ak_envvar + 'COMPSTOREDIR' + ( ) + [] + '' + '' + '' + '' + '' + ) + ( + ak_envvar + 'COMPILER' + ( ) + [] + '' + '' + '' + '' + '' + ) + ( + ak_envvar + 'DEBUGGER' + ( ) + [] + '' + '' + '' + '' + '' + ) + ( + ak_envvar + 'EXEEXT' + ( ) + [] + '' + '' + '' + '' + '' + ) + ( + ak_envvar + 'TARGET' + ( ) + [] + '' + '' + '' + '' + '' + ) + ( + ak_envvar + 'TARGETOSDIR' + ( ) + [] + '' + '' + '' + '' + '' + ) + ( + ak_arg + '' + ( ) + [] + '' + '' + '' + '' + '' + ) + ( + ak_par + '-NOZORDERHANDLING' + ( ) + [] + '' + '' + 'Do not touch Z-order of the windows.' + '' + '' + ) + ( + ak_par + '-NORESTACKWINDOW' + ( ) + [] + '' + '' + 'Do not use the NET_RESTACK_WINDOW protocol.' + '' + '' + ) + ( + ak_par + '-RESTACKWINDOW' + ( ) + [] + '' + '' + 'Use the NET_RESTACK_WINDOW protocol.' + '' + '' + ) + ( + ak_par + '-NORECONFIGUREWMWINDOW' + ( ) + [] + '' + '' + 'Do not use xreconfigurewmwindow() for window stacking operation.' + '' + '' + ) + ( + ak_par + '-RECONFIGUREWMWINDOW' + ( ) + [] + '' + '' + 'Use xreconfigurewmwindow() for window stacking operation.' + '' + '' + ) + ( + ak_par + '-STACKMODEBELOWWORKAROUND' + ( ) + [] + '' + '' + 'Necessarry for windowmanagers with buggy xreconfigurewmwindow() handling.' + '' + '' + ) + ( + ak_par + '-NOSTACKMODEBELOWWORKAROUND' + ( ) + [] + '' + '' + 'No workaround.' + '' + '' + ) + ( + ak_par + '-TOPLEVELRAISE' + ( ) + [] + '' + '' + 'Use the top level frame window id instead of the application client window id'#10'for window raise operation. Implies --NORESTACKWINDOW and'#10' --NORECONFIGUREWMWINDOW.' + '' + '' + ) + ) + end +end diff --git a/mseide-msegui/apps/ide/guitemplates.pas b/mseide-msegui/apps/ide/guitemplates.pas new file mode 100644 index 0000000..ccb92b6 --- /dev/null +++ b/mseide-msegui/apps/ide/guitemplates.pas @@ -0,0 +1,113 @@ +unit guitemplates; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseglob,mseapplication,mseclasses,msedatamodules,msegui,mseskin,msestrings, + msesysenv,msemacros; + +type + envvarty = (env_globstatfile,env_macrodef,env_storeglobalmacros,env_vargroup, + env_np,env_ns,env_help, + env_fpcdir,env_fpclibdir,env_msedir,env_mselibdir,env_syntaxdefdir, + env_templatedir,env_compstoredir,env_compiler,env_debugger, + env_exeext,env_target,env_targetosdir, + env_filename); +const +{ + sysenvvalues: array[envvarty] of argumentdefty = + ((kind: ak_pararg; name: '-macrodef'; anames: nil; flags: []; initvalue: ''), + (kind: ak_pararg; name: '-macrogroup'; anames: nil; flags: []; initvalue: ''), + (kind: ak_par; name: 'np'; anames: nil; flags: []; initvalue: ''), //no project + (kind: ak_par; name: 'ns'; anames: nil; flags: []; initvalue: ''), //no skin + (kind: ak_envvar; name: 'FPCDIR'; anames: nil; flags: []; initvalue: ''), + (kind: ak_envvar; name: 'FPCLIBDIR'; anames: nil; flags: []; initvalue: ''), + (kind: ak_envvar; name: 'MSEDIR'; anames: nil; flags: []; initvalue: ''), + (kind: ak_envvar; name: 'MSELIBDIR'; anames: nil; flags: []; initvalue: ''), + (kind: ak_envvar; name: 'SYNTAXDEFDIR'; anames: nil; flags: []; initvalue: ''), + (kind: ak_envvar; name: 'TEMPLATEDIR'; anames: nil; flags: []; initvalue: ''), + (kind: ak_envvar; name: 'COMPSTOREDIR'; anames: nil; flags: []; initvalue: ''), + (kind: ak_envvar; name: 'COMPILER'; anames: nil; flags: []; initvalue: ''), + (kind: ak_envvar; name: 'DEBUGGER'; anames: nil; flags: []; initvalue: ''), + (kind: ak_envvar; name: 'EXEEXT'; anames: nil; flags: []; initvalue: ''), + (kind: ak_envvar; name: 'TARGET'; anames: nil; flags: []; initvalue: ''), + (kind: ak_envvar; name: 'TARGETOSDIR'; anames: nil; flags: []; initvalue: ''), + (kind: ak_arg; name: ''; anames: nil; flags: []; initvalue: '')); +} + firstenvvarmacro = env_fpcdir; + lastenvvarmacro = env_target; + +type + tguitemplatesmo = class(tmsedatamodule) + fadevertkonvex: tfacecomp; + fadehorzconvex: tfacecomp; + fadehorzconcave: tfacecomp; + fadevertconcave: tfacecomp; + skin: tskincontroller; + fadecontainer: tfacecomp; + nullface: tfacecomp; + sysenv: tsysenvmanager; + procedure loadedexe(const sender: TObject); + end; + +function getcommandlinemacros: macroinfoarty; + +var + guitemplatesmo: tguitemplatesmo; +implementation +uses + guitemplates_mfm; + +function getcommandlinemacros: macroinfoarty; +begin + result:= guitemplatesmo.sysenv.getcommandlinemacros( + ord(env_macrodef),ord(firstenvvarmacro),ord(lastenvvarmacro)); +end; + +(* +function getcommandlinemacros: macroinfoarty; +var + ar1,ar2: msestringarty; + int1,int2,int3,int4: integer; +begin + result:= nil; + with guitemplatesmo.sysenv do begin + for int1:= ord(firstenvvarmacro) to ord(lastenvvarmacro) do begin + //envvar macros can be overridden by --macrodef + if defined[int1] then begin + setlength(result,high(result) + 2); + with result[high(result)] do begin + name:= sysenvvalues[envvarty(int1)].name; + value:= guitemplatesmo.sysenv.value[int1]; + end; + end; + end; + ar1:= values[ord(env_macrodef)]; + for int1:= 0 to high(ar1) do begin + ar2:= nil; + splitstringquoted(ar1[int1],ar2,msechar('"'),msechar(',')); + if ar2 <> nil then begin + int3:= length(result); + int4:= (high(ar2)+2) div 2; //pair count + setlength(result,int3+int4); + for int2:= 0 to int4-1 do begin + with result[int2+int3] do begin + int4:= int2 * 2; + name:= ar2[int4]; + if int4 < high(ar2) then begin + value:= ar2[int4+1] + end; + end; + end; + end; + end; + end; +end; +*) + +procedure tguitemplatesmo.loadedexe(const sender: TObject); +begin +// sysenv.init(sysenvvalues); + skin.active:= not sysenv.defined[ord(env_ns)]; +end; + +end. diff --git a/mseide-msegui/apps/ide/guitemplates_mfm.pas b/mseide-msegui/apps/ide/guitemplates_mfm.pas new file mode 100644 index 0000000..df58ae3 --- /dev/null +++ b/mseide-msegui/apps/ide/guitemplates_mfm.pas @@ -0,0 +1,226 @@ +unit guitemplates_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,guitemplates; + +const + objdata: record size: integer; data: array[0..4168] of byte end = + (size: 4169; data: ( + 84,80,70,48,15,116,103,117,105,116,101,109,112,108,97,116,101,115,109,111, + 14,103,117,105,116,101,109,112,108,97,116,101,115,109,111,9,98,111,117,110, + 100,115,95,99,120,3,227,1,9,98,111,117,110,100,115,95,99,121,3,132, + 0,8,111,110,108,111,97,100,101,100,7,9,108,111,97,100,101,100,101,120, + 101,4,108,101,102,116,2,99,3,116,111,112,3,135,0,15,109,111,100,117, + 108,101,99,108,97,115,115,110,97,109,101,6,14,116,109,115,101,100,97,116, + 97,109,111,100,117,108,101,0,9,116,102,97,99,101,99,111,109,112,14,102, + 97,100,101,118,101,114,116,107,111,110,118,101,120,23,116,101,109,112,108,97, + 116,101,46,102,97,100,101,95,112,111,115,46,99,111,117,110,116,2,2,23, + 116,101,109,112,108,97,116,101,46,102,97,100,101,95,112,111,115,46,105,116, + 101,109,115,1,2,0,2,1,0,25,116,101,109,112,108,97,116,101,46,102, + 97,100,101,95,99,111,108,111,114,46,99,111,117,110,116,2,2,25,116,101, + 109,112,108,97,116,101,46,102,97,100,101,95,99,111,108,111,114,46,105,116, + 101,109,115,1,4,219,219,219,0,4,200,200,200,0,0,23,116,101,109,112, + 108,97,116,101,46,102,97,100,101,95,100,105,114,101,99,116,105,111,110,7, + 7,103,100,95,100,111,119,110,4,108,101,102,116,2,24,3,116,111,112,2, + 16,0,0,9,116,102,97,99,101,99,111,109,112,14,102,97,100,101,104,111, + 114,122,99,111,110,118,101,120,23,116,101,109,112,108,97,116,101,46,102,97, + 100,101,95,112,111,115,46,99,111,117,110,116,2,2,23,116,101,109,112,108, + 97,116,101,46,102,97,100,101,95,112,111,115,46,105,116,101,109,115,1,2, + 0,2,1,0,25,116,101,109,112,108,97,116,101,46,102,97,100,101,95,99, + 111,108,111,114,46,99,111,117,110,116,2,2,25,116,101,109,112,108,97,116, + 101,46,102,97,100,101,95,99,111,108,111,114,46,105,116,101,109,115,1,4, + 219,219,219,0,4,200,200,200,0,0,4,108,101,102,116,2,24,3,116,111, + 112,2,40,0,0,9,116,102,97,99,101,99,111,109,112,15,102,97,100,101, + 104,111,114,122,99,111,110,99,97,118,101,23,116,101,109,112,108,97,116,101, + 46,102,97,100,101,95,112,111,115,46,99,111,117,110,116,2,2,23,116,101, + 109,112,108,97,116,101,46,102,97,100,101,95,112,111,115,46,105,116,101,109, + 115,1,2,0,2,1,0,25,116,101,109,112,108,97,116,101,46,102,97,100, + 101,95,99,111,108,111,114,46,99,111,117,110,116,2,2,25,116,101,109,112, + 108,97,116,101,46,102,97,100,101,95,99,111,108,111,114,46,105,116,101,109, + 115,1,4,219,219,219,0,4,200,200,200,0,0,23,116,101,109,112,108,97, + 116,101,46,102,97,100,101,95,100,105,114,101,99,116,105,111,110,7,7,103, + 100,95,108,101,102,116,4,108,101,102,116,3,144,0,3,116,111,112,2,40, + 0,0,9,116,102,97,99,101,99,111,109,112,15,102,97,100,101,118,101,114, + 116,99,111,110,99,97,118,101,23,116,101,109,112,108,97,116,101,46,102,97, + 100,101,95,112,111,115,46,99,111,117,110,116,2,2,23,116,101,109,112,108, + 97,116,101,46,102,97,100,101,95,112,111,115,46,105,116,101,109,115,1,2, + 0,2,1,0,25,116,101,109,112,108,97,116,101,46,102,97,100,101,95,99, + 111,108,111,114,46,99,111,117,110,116,2,2,25,116,101,109,112,108,97,116, + 101,46,102,97,100,101,95,99,111,108,111,114,46,105,116,101,109,115,1,4, + 219,219,219,0,4,200,200,200,0,0,23,116,101,109,112,108,97,116,101,46, + 102,97,100,101,95,100,105,114,101,99,116,105,111,110,7,5,103,100,95,117, + 112,4,108,101,102,116,3,144,0,3,116,111,112,2,16,0,0,15,116,115, + 107,105,110,99,111,110,116,114,111,108,108,101,114,4,115,107,105,110,9,101, + 120,116,101,110,100,101,114,115,2,0,18,115,98,95,104,111,114,122,95,102, + 97,99,101,98,117,116,116,111,110,7,14,102,97,100,101,118,101,114,116,107, + 111,110,118,101,120,21,115,98,95,104,111,114,122,95,102,97,99,101,101,110, + 100,98,117,116,116,111,110,7,14,102,97,100,101,118,101,114,116,107,111,110, + 118,101,120,18,115,98,95,118,101,114,116,95,102,97,99,101,98,117,116,116, + 111,110,7,14,102,97,100,101,104,111,114,122,99,111,110,118,101,120,21,115, + 98,95,118,101,114,116,95,102,97,99,101,101,110,100,98,117,116,116,111,110, + 7,14,102,97,100,101,104,111,114,122,99,111,110,118,101,120,15,115,116,101, + 112,98,117,116,116,111,110,95,102,97,99,101,7,14,102,97,100,101,104,111, + 114,122,99,111,110,118,101,120,12,119,105,100,103,101,116,95,99,111,108,111, + 114,4,3,0,0,128,14,99,111,110,116,97,105,110,101,114,95,102,97,99, + 101,7,14,102,97,100,101,104,111,114,122,99,111,110,118,101,120,17,103,114, + 105,100,95,102,105,120,114,111,119,115,95,102,97,99,101,7,14,102,97,100, + 101,118,101,114,116,107,111,110,118,101,120,11,98,117,116,116,111,110,95,102, + 97,99,101,7,14,102,97,100,101,118,101,114,116,107,111,110,118,101,120,15, + 100,97,116,97,98,117,116,116,111,110,95,102,97,99,101,7,14,102,97,100, + 101,118,101,114,116,107,111,110,118,101,120,16,102,114,97,109,101,98,117,116, + 116,111,110,95,102,97,99,101,7,14,102,97,100,101,104,111,114,122,99,111, + 110,118,101,120,16,116,97,98,98,97,114,95,104,111,114,122,95,102,97,99, + 101,7,15,102,97,100,101,118,101,114,116,99,111,110,99,97,118,101,20,116, + 97,98,98,97,114,95,104,111,114,122,95,116,97,98,95,102,97,99,101,7, + 14,102,97,100,101,118,101,114,116,107,111,110,118,101,120,19,116,97,98,98, + 97,114,95,104,111,114,122,111,112,111,95,102,97,99,101,7,15,102,97,100, + 101,118,101,114,116,99,111,110,99,97,118,101,23,116,97,98,98,97,114,95, + 104,111,114,122,111,112,111,95,116,97,98,95,102,97,99,101,7,14,102,97, + 100,101,118,101,114,116,107,111,110,118,101,120,16,116,97,98,98,97,114,95, + 118,101,114,116,95,102,97,99,101,7,15,102,97,100,101,104,111,114,122,99, + 111,110,99,97,118,101,20,116,97,98,98,97,114,95,118,101,114,116,95,116, + 97,98,95,102,97,99,101,7,14,102,97,100,101,118,101,114,116,107,111,110, + 118,101,120,19,116,97,98,98,97,114,95,118,101,114,116,111,112,111,95,102, + 97,99,101,7,15,102,97,100,101,104,111,114,122,99,111,110,99,97,118,101, + 23,116,97,98,98,97,114,95,118,101,114,116,111,112,111,95,116,97,98,95, + 102,97,99,101,7,14,102,97,100,101,118,101,114,116,107,111,110,118,101,120, + 13,109,97,105,110,109,101,110,117,95,102,97,99,101,7,15,102,97,100,101, + 118,101,114,116,99,111,110,99,97,118,101,4,108,101,102,116,2,24,3,116, + 111,112,2,72,0,0,9,116,102,97,99,101,99,111,109,112,13,102,97,100, + 101,99,111,110,116,97,105,110,101,114,23,116,101,109,112,108,97,116,101,46, + 102,97,100,101,95,112,111,115,46,99,111,117,110,116,2,2,23,116,101,109, + 112,108,97,116,101,46,102,97,100,101,95,112,111,115,46,105,116,101,109,115, + 1,2,0,2,1,0,25,116,101,109,112,108,97,116,101,46,102,97,100,101, + 95,99,111,108,111,114,46,99,111,117,110,116,2,2,25,116,101,109,112,108, + 97,116,101,46,102,97,100,101,95,99,111,108,111,114,46,105,116,101,109,115, + 1,4,5,0,0,160,4,204,204,204,0,0,4,108,101,102,116,3,144,0, + 3,116,111,112,2,72,0,0,9,116,102,97,99,101,99,111,109,112,8,110, + 117,108,108,102,97,99,101,4,108,101,102,116,3,16,1,3,116,111,112,2, + 16,0,0,14,116,115,121,115,101,110,118,109,97,110,97,103,101,114,6,115, + 121,115,101,110,118,10,104,101,108,112,104,101,97,100,101,114,6,96,77,83, + 69,105,100,101,32,67,111,112,121,114,105,103,104,116,32,49,57,57,57,45, + 50,48,49,53,32,98,121,32,77,97,114,116,105,110,32,83,99,104,114,101, + 105,98,101,114,10,85,115,97,103,101,58,32,109,115,101,105,100,101,32,91, + 79,80,84,73,79,78,93,46,46,46,32,91,80,82,79,74,69,67,84,70, + 73,76,69,93,10,10,79,112,116,105,111,110,115,58,10,104,101,108,112,102, + 111,111,116,101,114,6,218,10,69,110,118,105,114,111,110,109,101,110,116,32, + 118,97,114,105,97,98,108,101,115,10,70,80,67,68,73,82,44,32,70,80, + 67,76,73,66,68,73,82,44,32,77,83,69,68,73,82,44,32,77,83,69, + 76,73,66,68,73,82,10,83,89,78,84,65,88,68,69,70,68,73,82,44, + 32,84,69,77,80,76,65,84,69,68,73,82,44,32,67,79,77,80,83,84, + 79,82,69,68,73,82,10,67,79,77,80,73,76,69,82,44,32,68,69,66, + 85,71,71,69,82,44,32,69,88,69,69,88,84,44,84,65,82,71,69,84, + 44,84,65,82,71,69,84,79,83,68,73,82,10,99,97,110,32,98,101,32, + 117,115,101,100,32,116,111,32,111,118,101,114,114,105,100,101,32,116,104,101, + 32,115,101,116,116,105,110,103,115,32,109,97,99,114,111,115,46,10,10,72, + 97,118,101,32,97,32,108,111,116,32,111,102,32,102,117,110,33,10,10,77, + 97,114,116,105,110,4,108,101,102,116,2,24,3,116,111,112,2,96,4,100, + 101,102,115,1,1,7,9,97,107,95,112,97,114,97,114,103,6,13,45,103, + 108,111,98,115,116,97,116,102,105,108,101,1,0,11,0,6,0,6,10,60, + 102,105,108,101,112,97,116,104,62,6,31,83,101,116,32,112,97,116,104,32, + 116,111,32,103,108,111,98,97,108,32,115,116,97,116,117,115,32,102,105,108, + 101,46,6,0,6,0,0,1,7,9,97,107,95,112,97,114,97,114,103,6, + 9,45,109,97,99,114,111,100,101,102,1,0,11,0,6,0,6,31,60,110, + 97,109,101,62,44,60,118,97,108,117,101,62,123,44,60,110,97,109,101,62, + 44,60,118,97,108,117,101,62,125,6,109,77,97,99,114,111,32,100,101,102, + 105,110,105,116,105,111,110,44,32,119,105,108,108,32,98,101,32,111,118,101, + 114,114,105,100,100,101,110,32,98,121,32,39,80,114,111,106,101,99,116,39, + 45,39,79,112,116,105,111,110,115,39,45,39,77,97,99,114,111,115,39,46, + 10,32,69,120,97,109,112,108,101,58,10,32,45,45,109,97,99,114,111,100, + 101,102,61,77,65,67,49,44,97,98,99,44,77,65,67,50,44,100,101,102, + 6,0,6,0,0,1,7,6,97,107,95,112,97,114,6,18,45,115,116,111, + 114,101,103,108,111,98,97,108,109,97,99,114,111,115,1,0,11,0,6,0, + 6,0,6,63,83,116,111,114,101,32,45,45,109,97,99,114,111,100,101,102, + 32,118,97,108,117,101,115,32,97,115,32,103,108,111,98,97,108,32,109,97, + 99,114,111,115,32,97,110,100,32,116,101,114,109,105,110,97,116,101,32,77, + 83,69,105,100,101,46,32,6,0,6,0,0,1,7,9,97,107,95,112,97, + 114,97,114,103,6,11,45,109,97,99,114,111,103,114,111,117,112,1,0,11, + 0,6,0,6,3,60,110,62,6,71,85,115,101,32,39,80,114,111,106,101, + 99,116,39,45,39,79,112,116,105,111,110,115,39,45,39,77,97,99,114,111, + 115,39,45,39,65,99,116,105,118,101,32,103,114,111,117,112,39,32,110,117, + 109,98,101,114,32,60,110,62,44,10,60,110,62,32,61,32,49,46,46,54, + 46,6,0,6,0,0,1,7,6,97,107,95,112,97,114,6,2,110,112,1, + 0,11,0,6,0,6,0,6,22,68,111,32,110,111,116,32,108,111,97,100, + 32,97,32,112,114,111,106,101,99,116,46,6,0,6,0,0,1,7,6,97, + 107,95,112,97,114,6,2,110,115,1,0,11,0,6,0,6,0,6,28,68, + 111,32,110,111,116,32,117,115,101,32,97,32,115,107,105,110,44,32,110,111, + 32,102,97,100,101,115,46,6,0,6,0,0,1,7,6,97,107,95,112,97, + 114,6,5,45,104,101,108,112,1,0,11,8,97,114,102,95,104,101,108,112, + 0,6,0,6,0,6,27,68,105,115,112,108,97,121,32,116,104,105,115,32, + 104,101,108,112,32,97,110,100,32,101,120,105,116,46,6,0,6,1,32,0, + 1,7,9,97,107,95,101,110,118,118,97,114,6,6,70,80,67,68,73,82, + 1,0,11,0,6,0,6,0,6,0,6,0,6,0,0,1,7,9,97,107, + 95,101,110,118,118,97,114,6,9,70,80,67,76,73,66,68,73,82,1,0, + 11,0,6,0,6,0,6,0,6,0,6,0,0,1,7,9,97,107,95,101, + 110,118,118,97,114,6,6,77,83,69,68,73,82,1,0,11,0,6,0,6, + 0,6,0,6,0,6,0,0,1,7,9,97,107,95,101,110,118,118,97,114, + 6,9,77,83,69,76,73,66,68,73,82,1,0,11,0,6,0,6,0,6, + 0,6,0,6,0,0,1,7,9,97,107,95,101,110,118,118,97,114,6,12, + 83,89,78,84,65,88,68,69,70,68,73,82,1,0,11,0,6,0,6,0, + 6,0,6,0,6,0,0,1,7,9,97,107,95,101,110,118,118,97,114,6, + 11,84,69,77,80,76,65,84,69,68,73,82,1,0,11,0,6,0,6,0, + 6,0,6,0,6,0,0,1,7,9,97,107,95,101,110,118,118,97,114,6, + 12,67,79,77,80,83,84,79,82,69,68,73,82,1,0,11,0,6,0,6, + 0,6,0,6,0,6,0,0,1,7,9,97,107,95,101,110,118,118,97,114, + 6,8,67,79,77,80,73,76,69,82,1,0,11,0,6,0,6,0,6,0, + 6,0,6,0,0,1,7,9,97,107,95,101,110,118,118,97,114,6,8,68, + 69,66,85,71,71,69,82,1,0,11,0,6,0,6,0,6,0,6,0,6, + 0,0,1,7,9,97,107,95,101,110,118,118,97,114,6,6,69,88,69,69, + 88,84,1,0,11,0,6,0,6,0,6,0,6,0,6,0,0,1,7,9, + 97,107,95,101,110,118,118,97,114,6,6,84,65,82,71,69,84,1,0,11, + 0,6,0,6,0,6,0,6,0,6,0,0,1,7,9,97,107,95,101,110, + 118,118,97,114,6,11,84,65,82,71,69,84,79,83,68,73,82,1,0,11, + 0,6,0,6,0,6,0,6,0,6,0,0,1,7,6,97,107,95,97,114, + 103,6,0,1,0,11,0,6,0,6,0,6,0,6,0,6,0,0,1,7, + 6,97,107,95,112,97,114,6,17,45,78,79,90,79,82,68,69,82,72,65, + 78,68,76,73,78,71,1,0,11,0,6,0,6,0,6,36,68,111,32,110, + 111,116,32,116,111,117,99,104,32,90,45,111,114,100,101,114,32,111,102,32, + 116,104,101,32,119,105,110,100,111,119,115,46,6,0,6,0,0,1,7,6, + 97,107,95,112,97,114,6,16,45,78,79,82,69,83,84,65,67,75,87,73, + 78,68,79,87,1,0,11,0,6,0,6,0,6,43,68,111,32,110,111,116, + 32,117,115,101,32,116,104,101,32,78,69,84,95,82,69,83,84,65,67,75, + 95,87,73,78,68,79,87,32,112,114,111,116,111,99,111,108,46,6,0,6, + 0,0,1,7,6,97,107,95,112,97,114,6,14,45,82,69,83,84,65,67, + 75,87,73,78,68,79,87,1,0,11,0,6,0,6,0,6,36,85,115,101, + 32,116,104,101,32,78,69,84,95,82,69,83,84,65,67,75,95,87,73,78, + 68,79,87,32,112,114,111,116,111,99,111,108,46,6,0,6,0,0,1,7, + 6,97,107,95,112,97,114,6,22,45,78,79,82,69,67,79,78,70,73,71, + 85,82,69,87,77,87,73,78,68,79,87,1,0,11,0,6,0,6,0,6, + 64,68,111,32,110,111,116,32,117,115,101,32,120,114,101,99,111,110,102,105, + 103,117,114,101,119,109,119,105,110,100,111,119,40,41,32,102,111,114,32,119, + 105,110,100,111,119,32,115,116,97,99,107,105,110,103,32,111,112,101,114,97, + 116,105,111,110,46,6,0,6,0,0,1,7,6,97,107,95,112,97,114,6, + 20,45,82,69,67,79,78,70,73,71,85,82,69,87,77,87,73,78,68,79, + 87,1,0,11,0,6,0,6,0,6,57,85,115,101,32,120,114,101,99,111, + 110,102,105,103,117,114,101,119,109,119,105,110,100,111,119,40,41,32,102,111, + 114,32,119,105,110,100,111,119,32,115,116,97,99,107,105,110,103,32,111,112, + 101,114,97,116,105,111,110,46,6,0,6,0,0,1,7,6,97,107,95,112, + 97,114,6,25,45,83,84,65,67,75,77,79,68,69,66,69,76,79,87,87, + 79,82,75,65,82,79,85,78,68,1,0,11,0,6,0,6,0,6,73,78, + 101,99,101,115,115,97,114,114,121,32,102,111,114,32,119,105,110,100,111,119, + 109,97,110,97,103,101,114,115,32,119,105,116,104,32,98,117,103,103,121,32, + 120,114,101,99,111,110,102,105,103,117,114,101,119,109,119,105,110,100,111,119, + 40,41,32,104,97,110,100,108,105,110,103,46,6,0,6,0,0,1,7,6, + 97,107,95,112,97,114,6,27,45,78,79,83,84,65,67,75,77,79,68,69, + 66,69,76,79,87,87,79,82,75,65,82,79,85,78,68,1,0,11,0,6, + 0,6,0,6,14,78,111,32,119,111,114,107,97,114,111,117,110,100,46,6, + 0,6,0,0,1,7,6,97,107,95,112,97,114,6,14,45,84,79,80,76, + 69,86,69,76,82,65,73,83,69,1,0,11,0,6,0,6,0,6,161,85, + 115,101,32,116,104,101,32,116,111,112,32,108,101,118,101,108,32,102,114,97, + 109,101,32,119,105,110,100,111,119,32,105,100,32,105,110,115,116,101,97,100, + 32,111,102,32,116,104,101,32,97,112,112,108,105,99,97,116,105,111,110,32, + 99,108,105,101,110,116,32,119,105,110,100,111,119,32,105,100,10,102,111,114, + 32,119,105,110,100,111,119,32,114,97,105,115,101,32,111,112,101,114,97,116, + 105,111,110,46,32,73,109,112,108,105,101,115,32,45,45,78,79,82,69,83, + 84,65,67,75,87,73,78,68,79,87,32,97,110,100,10,32,45,45,78,79, + 82,69,67,79,78,70,73,71,85,82,69,87,77,87,73,78,68,79,87,46, + 6,0,6,0,0,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tguitemplatesmo,''); +end. diff --git a/mseide-msegui/apps/ide/main.mfm b/mseide-msegui/apps/ide/main.mfm new file mode 100644 index 0000000..b5b778b --- /dev/null +++ b/mseide-msegui/apps/ide/main.mfm @@ -0,0 +1,1572 @@ +object mainfo: tmainfo + optionswidget = [ow_arrowfocus, ow_subfocus, ow_destroywidgets, ow_hinton] + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_fixsizebutton, go_floatbutton, go_topbutton, go_backgroundbutton, go_lockbutton, go_nolockbutton, go_buttonhints] + visible = False + bounds_x = 740 + bounds_y = 149 + bounds_cx = 459 + bounds_cy = 149 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.frame.framei_left = 0 + container.frame.framei_top = 0 + container.frame.framei_right = 0 + container.frame.framei_bottom = 0 + container.frame.localprops = [frl_fileft, frl_fitop, frl_firight, frl_fibottom] + container.frame.localprops1 = [] + container.frame.sbhorz.options = [sbo_moveauto, sbo_showauto] + container.frame.sbvert.options = [sbo_moveauto, sbo_showauto] + container.onlayout = onscale + container.bounds = ( + 0 + 16 + 449 + 133 + ) + dragdock.optionsdock = [od_savepos, od_savezorder, od_canmove, od_cansize, od_canfloat, od_candock, od_captionhint] + dragdock.optionsdockform = [odf_main, odf_childicons] + optionswindow = [wo_taskbar] + mainmenu = mainmenu1 + options = [fo_main, fo_terminateonclose, fo_globalshortcuts, fo_savepos, fo_savezorder, fo_savestate] + statfile = projectstatfile + caption = 'MSEide' + oncreate = mainfooncreate + oneventloopstart = mainonloaded + ondestroy = mainfoondestroy + onterminatequery = mainfoonterminate + onlayout = onscale + left = 8 + top = 80 + moduleclassname = 'tdockform' + object basedock: tdockpanel + optionswidget1 = [ow1_autoscale, ow1_noparentheightextend] + optionswidget = [ow_background, ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_subfocus, ow_destroywidgets] + onpaint = basedockpaintexe + bounds_x = 0 + bounds_y = 19 + bounds_cx = 449 + bounds_cy = 114 + anchors = [an_top, an_bottom] + dragdock.optionsdock = [od_acceptsdock, od_splitvert, od_splithorz, od_tabed, od_proportional, od_background, od_captionhint] + statfile = projectstatfile + end + object statdisp: tstringdisp + optionswidget = [ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.colorclient = -2147483645 + frame.localprops = [frl_colorclient] + frame.localprops1 = [] + taborder = 1 + bounds_x = 0 + bounds_y = 1 + bounds_cx = 449 + bounds_cy = 18 + anchors = [an_top] + font.name = 'stf_default' + font.xscale = 1 + font.localprops = [flp_xscale] + options = [dwo_hintclippedtext] + reffontheight = 14 + end + object gdb: tgdbmi + guiintf = True + gdbdownload = False + simulator = False + startupbkpt = 0 + startupbkpton = False + onevent = gdbonevent + overloadsleepus = 10000 + left = 120 + top = 32 + end + object mainstatfile: tstatfile + filename = 'mseide.sta' + filedir = '"^/.mseide"' + options = [sfo_createpath, sfo_transaction, sfo_activatorread, sfo_activatorwrite] + onstatupdate = mainstatfileonupdatestat + onstatbeforewrite = mainstatbeforewriteexe + top = 32 + end + object mainmenu1: tmainmenu + options = [mo_shortcutright, mo_activate, mo_updateonidle] + onupdate = mainmenuonupdate + menu.submenu.count = 7 + menu.submenu.items = < + item + submenu.count = 10 + submenu.items = < + item + submenu.count = 1 + submenu.items = < + item + submenu.count = 9 + submenu.items = < + item + caption = '&Mainform' + state = [as_localcaption, as_localonexecute] + onexecute = newformonexecute + end + item + caption = '&Simple Form' + state = [as_localcaption, as_localtag, as_localonexecute] + options = [mao_shortcutcaption, mao_asyncexecute] + tag = 1 + onexecute = newformonexecute + end + item + caption = '&Docking Form' + state = [as_localcaption, as_localtag, as_localonexecute] + options = [mao_shortcutcaption, mao_asyncexecute] + tag = 2 + onexecute = newformonexecute + end + item + caption = 'D&atamodule' + state = [as_localcaption, as_localtag, as_localonexecute] + options = [mao_shortcutcaption, mao_asyncexecute] + tag = 3 + onexecute = newformonexecute + end + item + caption = 'S&ubform' + state = [as_localcaption, as_localtag, as_localonexecute] + tag = 4 + onexecute = newformonexecute + end + item + caption = '&Report' + state = [as_localcaption, as_localtag, as_localonexecute] + tag = 5 + onexecute = newformonexecute + end + item + caption = 'S&criptform' + name = 'pascform' + state = [as_localcaption, as_localtag, as_localonexecute] + tag = 6 + onexecute = newformonexecute + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = '&Inherited' + state = [as_localcaption, as_localtag, as_localonexecute] + tag = 7 + onexecute = newformonexecute + end> + caption = '&Form' + name = 'form' + state = [as_localcaption] + end> + caption = '&New' + name = 'new' + state = [as_localcaption] + end + item + action = actionsmo.opensource + end + item + action = actionsmo.save + end + item + action = actionsmo.saveas + end + item + action = actionsmo.saveall + end + item + action = actionsmo.close + end + item + action = actionsmo.closeall + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + action = actionsmo.print + end + item + caption = 'E&xit' + state = [as_localcaption, as_localonexecute] + options = [mao_shortcutcaption, mao_asyncexecute] + onexecute = exitonexecute + end> + caption = '&File' + name = 'file' + state = [as_localcaption] + end + item + submenu.count = 7 + submenu.items = < + item + action = actionsmo.line + end + item + action = actionsmo.find + end + item + action = actionsmo.repeatfind + end + item + action = actionsmo.findback + end + item + action = actionsmo.replace + end + item + action = actionsmo.findinfile + end + item + action = actionsmo.findcompallact + caption = 'Find &Component' + state = [as_localcaption, as_localshortcut, as_localshortcut1] + end> + caption = '&Search' + name = 'search' + state = [as_localcaption] + end + item + submenu.count = 15 + submenu.items = < + item + action = actionsmo.selecteditpage + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + action = actionsmo.undo + end + item + action = actionsmo.redo + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + action = actionsmo.copy + end + item + action = actionsmo.copylatexact + end + item + action = actionsmo.copyword + end + item + action = actionsmo.cut + end + item + action = actionsmo.paste + end + item + action = actionsmo.delete + end + item + action = actionsmo.selectall + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + action = actionsmo.indent + end + item + action = actionsmo.unindent + end> + caption = '&Edit' + name = 'edit' + state = [as_localcaption] + end + item + submenu.count = 22 + submenu.items = < + item + caption = 'En&vironment' + state = [as_localcaption, as_localimagelist, as_localonexecute] + imagelist = dummyimagelist + onexecute = parametersonexecute + end + item + caption = 'Restart Debugger' + state = [as_localcaption, as_localimagelist, as_localonexecute] + imagelist = dummyimagelist + onexecute = restartgdbonexecute + end + item + action = actionsmo.attachprocess + state = [as_localimagelist] + imagelist = dummyimagelist + end + item + action = actionsmo.attachtarget + state = [as_localimagelist] + imagelist = dummyimagelist + end + item + action = actionsmo.detachtarget + state = [as_localimagelist] + imagelist = dummyimagelist + end + item + action = actionsmo.download + state = [as_localimagelist] + imagelist = dummyimagelist + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + action = actionsmo.continue + end + item + action = actionsmo.reset + end + item + action = actionsmo.interrupt + end + item + action = actionsmo.step + end + item + action = actionsmo.stepi + end + item + action = actionsmo.next + end + item + action = actionsmo.nexti + end + item + action = actionsmo.finish + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + action = actionsmo.bkptsonact + state = [as_checked] + options = [mao_checkbox, mao_shortcutcaption] + end + item + action = actionsmo.togglebkpt + state = [as_localimagelist] + imagelist = dummyimagelist + end + item + action = actionsmo.togglebkptenable + state = [as_localimagelist] + imagelist = dummyimagelist + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + action = actionsmo.watchesonact + state = [as_checked] + options = [mao_checkbox, mao_shortcutcaption] + end + item + action = actionsmo.bluedotsonact + state = [as_checked] + options = [mao_checkbox, mao_shortcutcaption] + end> + caption = '&Target' + name = 'target' + state = [as_localcaption] + end + item + submenu.count = 28 + submenu.items = < + item + submenu.count = 2 + submenu.items = < + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = '&New Panel' + state = [as_localcaption, as_localonexecute] + onexecute = newpanelonexecute + end> + caption = 'Pan&els' + name = 'panels' + state = [as_localcaption, as_localimagelist, as_localimagenr] + imagelist = vievmenuicons + imagenr = 0 + end + item + action = actionsmo.forcezorderact + state = [as_localimagelist] + options = [mao_checkbox, mao_shortcutcaption] + imagelist = vievmenuicons + end + item + caption = 'Load Wi&ndow Layout' + state = [as_localcaption, as_localimagelist, as_localonexecute] + imagelist = vievmenuicons + onexecute = loadwindowlayoutexe + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = 'Component &Palette' + state = [as_localcaption, as_localimagelist, as_localimagenr, as_localonexecute] + imagelist = vievmenuicons + imagenr = 1 + onexecute = viewcomponentpaletteonexecute + end + item + caption = 'Component Sto&re' + state = [as_localcaption, as_localimagelist, as_localimagenr, as_localonexecute] + imagelist = vievmenuicons + imagenr = 16 + onexecute = viewcomponentstoreonexecute + end + item + caption = 'Object &Inspector' + state = [as_localcaption, as_localimagelist, as_localimagenr, as_localonexecute] + imagelist = vievmenuicons + imagenr = 14 + onexecute = viewobjectinspectoronexecute + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = 'So&urce' + state = [as_localcaption, as_localimagelist, as_localimagenr, as_localonexecute] + options = [mao_shortcutcaption, mao_asyncexecute] + imagelist = vievmenuicons + imagenr = 5 + onexecute = viewsourceonexecute + end + item + caption = '&Messages' + state = [as_localcaption, as_localimagelist, as_localimagenr, as_localonexecute] + options = [mao_shortcutcaption, mao_asyncexecute] + imagelist = vievmenuicons + imagenr = 4 + onexecute = viewmessagesonexecute + end + item + caption = '&Find Results' + state = [as_localcaption, as_localimagelist, as_localimagenr, as_localonexecute] + imagelist = vievmenuicons + imagenr = 15 + onexecute = viewfindresults + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = '&Debugger' + state = [as_localcaption, as_localimagelist, as_localimagenr, as_localonexecute] + imagelist = vievmenuicons + imagenr = 2 + onexecute = viewdebuggertoolbaronexecute + end + item + caption = 'Symbo&ls' + state = [as_localcaption, as_localimagelist, as_localimagenr, as_localonexecute] + imagelist = vievmenuicons + imagenr = 18 + onexecute = viewsymbolsonexecute + end + item + caption = '&Watches' + state = [as_localcaption, as_localimagelist, as_localimagenr, as_localonexecute] + options = [mao_shortcutcaption, mao_asyncexecute] + imagelist = vievmenuicons + imagenr = 8 + onexecute = viewwatchesonexecute + end + item + caption = '&Stack' + state = [as_localcaption, as_localimagelist, as_localimagenr, as_localonexecute] + options = [mao_shortcutcaption, mao_asyncexecute] + imagelist = vievmenuicons + imagenr = 9 + onexecute = viewstackonexecute + end + item + caption = 'T&hreads' + state = [as_localcaption, as_localimagelist, as_localimagenr, as_localonexecute] + imagelist = vievmenuicons + imagenr = 10 + onexecute = viewthreadsonexecute + end + item + caption = '&CPU' + state = [as_localcaption, as_localimagelist, as_localimagenr, as_localonexecute] + imagelist = vievmenuicons + imagenr = 11 + onexecute = viewcpuonexecute + end + item + caption = '&Assembler' + state = [as_localcaption, as_localimagelist, as_localimagenr, as_localonexecute] + imagelist = vievmenuicons + imagenr = 12 + onexecute = viewassembleronexecute + end + item + caption = 'Memor&y' + state = [as_localcaption, as_localimagelist, as_localimagenr, as_localonexecute] + imagelist = vievmenuicons + imagenr = 17 + onexecute = viewmemoryonexecute + end + item + caption = '&Target Console' + state = [as_localcaption, as_localimagelist, as_localimagenr, as_localonexecute] + imagelist = vievmenuicons + imagenr = 13 + onexecute = viewconsoleonexecute + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = '&Breakpoints' + state = [as_localcaption, as_localimagelist, as_localimagenr, as_localonexecute] + options = [mao_shortcutcaption, mao_asyncexecute] + imagelist = vievmenuicons + imagenr = 6 + onexecute = viewbreakpointsonexecute + end + item + caption = 'Watchp&oints' + state = [as_localcaption, as_localimagelist, as_localimagenr, as_localonexecute] + imagelist = vievmenuicons + imagenr = 7 + onexecute = viewwatchpointsonexecute + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + action = actionsmo.toggleinspector + state = [as_localimagelist, as_localonexecute] + options = [mao_shortcutcaption, mao_asyncexecute] + imagelist = vievmenuicons + onexecute = toggleobjectinspectoronexecute + end + item + action = actionsmo.toggleformunit + caption = 'Toggle Form/Unit' + state = [as_localcaption, as_localimagelist] + options = [mao_shortcutcaption, mao_asyncexecute] + imagelist = vievmenuicons + end + item + name = 'formmenuitemstart' + options = [mao_separator, mao_shortcutcaption] + end> + caption = '&View' + name = 'view' + state = [as_localcaption] + end + item + submenu.count = 19 + submenu.items = < + item + action = actionsmo.makeact + caption = '&Make' + state = [as_localcaption, as_localtag] + tag = 1 + end + item + action = actionsmo.buildact + caption = '&Build' + state = [as_localcaption, as_localtag] + tag = 2 + end + item + action = actionsmo.make1act + caption = 'Make &1' + state = [as_localcaption, as_localtag] + tag = 4 + end + item + action = actionsmo.make2act + caption = 'Make &2' + state = [as_localcaption, as_localtag] + tag = 8 + end + item + action = actionsmo.make3act + caption = 'Make &3' + state = [as_localcaption, as_localtag] + tag = 16 + end + item + action = actionsmo.make4act + caption = 'Make &4' + state = [as_localcaption, as_localtag] + tag = 32 + end + item + action = actionsmo.abortmakeact + caption = '&Abort Make' + state = [as_localcaption, as_localtag] + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + action = actionsmo.projectoptionsact + end + item + action = actionsmo.projecttreeact + end + item + action = actionsmo.projectsourceact + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + submenu.count = 3 + submenu.items = < + item + caption = 'From &Template' + state = [as_localcaption, as_localonexecute] + onexecute = newprojectonexecute + end + item + caption = 'From &Program' + state = [as_localcaption, as_localonexecute] + onexecute = newprojectfromprogramexe + end + item + caption = '&Empty' + state = [as_localcaption, as_localonexecute] + onexecute = newemptyprojectexe + end> + caption = '&New' + state = [as_localcaption] + end + item + action = actionsmo.projectopenact + end + item + caption = 'Open copy' + state = [as_localcaption, as_localonexecute] + onexecute = openprojectcopyexecute + end + item + action = actionsmo.projectsaveact + end + item + caption = 'Save &as' + state = [as_localcaption, as_localonexecute] + onexecute = saveprojectasonexecute + end + item + caption = 'Save as copy' + state = [as_localcaption, as_localonexecute] + onexecute = saveprojectcopyexecute + end + item + action = actionsmo.projectcloseact + caption = '&Close' + name = 'close' + state = [as_localcaption, as_localonexecute] + onexecute = closeprojectactonexecute + end> + caption = '&Project' + name = 'project' + state = [as_localcaption, as_localonexecute] + onexecute = aboutonexecute + end + item + submenu.count = 2 + submenu.items = < + item + caption = '&About' + state = [as_localcaption, as_localonexecute] + onexecute = aboutonexecute + end + item + caption = '&Configure MSEide' + state = [as_localcaption, as_localonexecute] + onexecute = configureexecute + end> + caption = 'Sett&ings' + name = 'settings' + state = [as_localcaption, as_localonexecute] + onexecute = aboutonexecute + end> + left = 103 + top = 96 + end + object openfile: tfiledialog + statfile = projectstatfile + controller.options = [fdo_checkexist] + controller.captionopen = 'Open file' + controller.captionsave = 'Save file as' + top = 1 + end + object projectstatfile: tstatfile + filename = 'status.sta' + onstatbeforeread = statbefread + onstatafterread = statafterread + top = 64 + end + object vievmenuicons: timagelist + width = 18 + height = 18 + options = [bmo_masked, bmo_colormask] + count = 19 + left = 313 + top = 96 + image = { + 00000000060000005A0000005A000000883D0000000000000000000000000000 + 0000000000000000000000000000000000000000FFFFFF06CB582601C5440B01 + FFFFFF03C23B0001FFFFFF06A8A8A801B8B8B807D4D4D401E9E9E908E5E5E501 + ADADAD01BEBEBE11D0D0D001FFFFFF11E0E0E001FFFFFF10D0D0D001FFFFFF02 + C6390001FF000001FFFFFF01FD430901DF8C6A01DF886401EA370501EA360501 + DD522201DA815C01DE3E0601FD430901FFFFFF04DCDCDC01CACACA07FFFFFF08 + CACACA01A7A7A701BEBEBE01D0D0D0113C3C3C01D0D0D0108DB4B701D0D0D001 + 7C7C7C0FFFFFFF010000FF01FFFFFF02CD623201DD937201D9603201EB370501 + DF7F5D01FCF7F401D75A3101D43F1501EDC0AF01EEC3B101DD330201EB370501 + F63E0801FFFFFF03E9E9E901FFFFFF08CACACA01C4C4C401C5C5C501C8C8C802 + CACACA0185858501CACACA018A8A8A01BEBEBE01D0D0D00302AC080101AA0901 + D0D0D00CB5F8FE01D0D0D010FFFFFF017C7C7C02E8E8E80EFFFFFF01D0D0D001 + FFFFFF02C5491601EEC5B401F7E2DA01DB755101D24B2101FBF2EE01F1CDBF01 + D6664101FFFFFF01E2957A01D3270001D92C0101E5330401DA673B01D4744A01 + FFFFFF01E9E9E901FFFFFF01B5B5B501B7B7B701BEBEBE01D8D8D801E0E0E001 + 85858501FFFFFF01B1B1B1017D7D7D01979797019A9A9A0187878701CACACA01 + 85858501CACACA018A8A8A01BEBEBE01D0D0D00304B206010DB40D0108AD0E01 + D0D0D00B6FC7CE01D0D0D0102F2F2F01D0D0D0017C7C7C01E8E8E80EFFFFFF01 + 74959601FFFFFF02F63E0801DC785201FEFDFC01FFFFFF01E8AE9901D8734F01 + FCF6F301D4684201F6DFD601DA725201D36A4001D0421901DD836201F7E6DE01 + D9744B01FFFFFF01E5E5E501FFFFFF0195959501919191018F8F8F01ACACAC01 + E0E0E00185858501FFFFFF01B5B5B501B1B1B101A5A5A501A6A6A601A0A0A001 + CACACA0185858501CACACA01A7A7A701BEBEBE01D0D0D00305B3060122CD1501 + 1DB81B010EAD1301D0D0D00A181818017C7C7C0FFFFFFF0100000001D0D0D001 + 7C7C7C01E8E8E80EFFFFFF0100000001FFFFFF01FD430901EB370501D43E1101 + DB7B5901FFFFFF01FCF4F101C8523201CC715501A65642016A9A8C01D13E1D01 + D66A4801F5DED401FFFEFE01DA744F01E8380501FD430901DBDBDB01F0F0F001 + E0E0E005FFFFFF0AFCFCFC01BEBEBE01D0D0D00305B3060122CD150138D42C01 + 35C8310114AD190100A90901D0D0D0097C7C7C01E8E8E80EFFFFFF017A7AFF01 + 9BBABA017C7C7C01E8E8E80EFFFFFF010000FF01FFFFFF01F53D0701E2310301 + DC815F01D97A5601D86F4E01D97253011EECE5014EB3AE017A7E7B0128E0DB01 + D5412901FCF7F401FFFFFF01E3957B01D22B0401E2310301F53D0701DFDFDF01 + F5F5F501D3EBEB01E5EFEF01F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01 + E8E8E801CAE0E001E0E4E401E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01 + E1E1E101BEBEBE01D0D0D00305B3060122CD150138D42C014DDB420154D94C01 + 1DB1210100A90901D0D0D0070404FF017C7C7C01E8E8E8017B7B7B014F4F4F01 + 74747401E8E8E802BABABA0160606001E8E8E801E6E6E6015F5F5F014A4A4A01 + 98989801E8E8E801FFFFFF01FF002601D0D0D0017C7C7C01E8E8E80192929201 + 31313101E8E8E802C1C1C10115151501E8E8E801454545014F4F4F03BABABA01 + E8E8E801FFFFFF01E0E0E001FFFFFF01EB390501D6401301D3593101D5664201 + DC765901D654370181777501BA6F7301D6CDCE01B74E52015CA49F01CF775B01 + DA7B5B01D34E2901D6583201D64C2001E93905017ACACC0160D6D90137D7DE01 + 32D2D80198DEDF01EEEEEE01EDEDED01EBEBEB01EAEAEA0157D0D30135D5DC01 + 31CDD201ACDADB01E2E2E201E0E0E001DFDFDF01DDDDDD01DEDEDE01BEBEBE01 + D0D0D00305B3060122CD150138D42C014DDB420162E2580171E669012EB83101 + 13B21A01D0D0D0067272FF017C7C7C01C6C6C60155555501E8E8E80153535301 + CBCBCB01ACACAC015353530150505001E8E8E8019999990182828201E8E8E801 + 37373701E7E7E701FFFFFF02000068017C7C7C01E8E8E801898989012C2C2C01 + BCBCBC01E8E8E8017474740124242401E8E8E80139393901E8E8E805FFFFFF01 + E0E0E001C23B0001D6744B01F8E8E101FFFFFF03D16D55014AB8B601C1737B01 + D6B2B601A7636B0123E6E201BB533C01EAB4A101FEFBFA01FCF4F101E39F8401 + D857270145C3C7013DD5DB01B2F3FF0184F1FF013ED1D501EEEEEE01E0E0EC01 + EBEBEB01CEE4E40140D7DF01B0F3FF0176F1FF0147CFD101E2E2E201D3D3E001 + DFDFDF01DDDDDD01DEDEDE01BEBEBE01D0D0D00305B3060122CD150138D42C01 + 4DDB420162E2580177E96E018BF084014CC64D0121B42701D0D0D0059797FF01 + 7C7C7C01A1A1A10182828201E8E8E8017E7E7E01A4A4A401E3E3E301E1E1E101 + 50505001E8E8E80172727201B1B1B101E8E8E8014F4F4F01D3D3D301FFFFFF01 + D0D0D0010000FF017C7C7C01E8E8E801898989017B7B7B016E6E6E01E8E8E801 + 6060600139393901E8E8E8013636360174747403DEDEDE01E8E8E801FFFFFF01 + 67676701FFFFFF01DE441301D8674101E8AC9601FCF6F301DE856A01BC453201 + 25E3DF019D4E5A0158A3A9019C515C01D75B4401DD745B01D55E3B01D9624501 + D2431D01D42A0001EA36050138C3CA013FD8E001C7F3FF0190F2FF0134D1D501 + EEEEEE013434DF01E5E5EA01ACDEDE014CDFE901D0F4FF0186F1FF0138CED101 + E2E2E2013434DD01D0D0DF01DDDDDD01D9D9DE01BEBEBE01D0D0D00305B30601 + 22CD150138D42C014DDB420162E2580177E96E018BF084014AC14B01146D1701 + 00000001D0D0D0057C7C7C01B1B1B10180808001E8E8E8017B7B7B01A8A8A801 + E8E8E801E1E1E10150505001E8E8E80181818101B0B0B001E8E8E8014C4C4C01 + D8D8D801FFFFFF01888888017C7C7C02E8E8E801898989019F9F9F0149494901 + BBBBBB018C8C8C0139393901E8E8E80138383801C4C4C403E5E5E501E8E8E801 + FFFFFF010000FF01FFFFFF01EB370501D72A0001D3260401D2502A01E1927A01 + D7694901DB655101D35C470140C2C20195686301F6E1D901FFFFFF01F6E0D701 + D8674601D3290701D72A0001EB37050138C3C9013CCED20151E6F30138DEE901 + 6BD6D701ACACE9010C0CEC018383E601E8E9E90130CACE015FEBF90136DEE801 + 74D2D301B8B8E0010F0FEA016666DF01DDDDDD01B9B9DE01BEBEBE01D0D0D003 + 05B3060122CD150138D42C014DDB420162E2580171E669012BAE2E0106370801 + 00000002D0D0D004000000017C7C7C01E3E3E30156565601E8E8E8014E4E4E01 + CFCFCF01E8E8E801E1E1E10150505001E8E8E801BBBBBB017E7E7E01E4E4E401 + 39393901E8E8E801FFFFFF037C7C7C01E8E8E801898989019F9F9F0177777701 + 46464601D8D8D80139393901E8E8E80139393901E8E8E805FFFFFF01D0D0D001 + FFFFFF01EF390601DB2C0101D33F1901EEBFAF01F0C7BA01DA7B5E01FFFFFF01 + EFC7BA01D2321F01DC765D01D66A4A01FCF5F201FFFFFF01FFFEFE01DF886901 + D9320601EF39060143BDC101EAE4E40182CDCE01A6D3D401ECE1E1014141E501 + 0404FF013333E601E9E6E601D3D6D60165C3C5019ACBCB01E0D5D5014646E101 + 0404FE012929E501DADADD016B6BDF01BEBEBE01D0D0D00305B3060122CD1501 + 38D42C014DDB420154D94C011A9D1D010015010100000002D0D0D005FFFFFF01 + 7C7C7C01E8E8E801959595015A5A5A0190909001E8E8E802E3E3E30176767601 + E8E8E801E6E6E6017B7B7B0159595901AEAEAE01E8E8E801FFFFFF0200000001 + 7C7C7C01E8E8E801A1A1A101B1B1B101C7C7C70165656501E8E8E80165656501 + E8E8E801606060014F4F4F03A6A6A601E8E8E801FFFFFF0188888801FFFFFF01 + F53D0701DB481B01EAB39E01FFFFFF01D8704E01F9E7E101FFFFFF01E2937C01 + D2402201FCF4F101E9AB9901D55F3C01DD7C6101E18E7301E49F8601D4613501 + F53D0701C8CECE01D4161E01DE1B2802AD1A3A011818ED010404FF010E0EF301 + AC7FAC01D3151D01DC192602B71B2E011B1BE9010404FF010707F6018888DD01 + 3C3CE301BEBEBE01D0D0D00305B3060122CD150138D42C0136C7300110891401 + 0004000100000001D0D0D007FFFFFF017C7C7C01E8E8E80EFFFFFF02D0D0D001 + 7C7C7C01E8E8E80EFFFFFF0100000001FFFFFF01FD430901D56A3E01E08C6D01 + DA6C4B01D86D4A01FFFFFF01E9AE9C01D45D3B01D8664901E9AE9A01FFFFFF01 + DC735601D5200501D4240201DA2B0101E6380501FD430901C6434901ED011801 + FF002002791278013838E6013C3CE7013B3BE6017D50AA01ED011801FF002002 + 8B1467013333E3013939E4013838E3015757DE011B1BEF01BEBEBE01D0D0D003 + 05B3060122CD15011CB51A01096B0C0100000002D0D0D008FFFFFF017C7C7C01 + FFFFFF0FD0D0D001FFFFFF017C7C7C01E8E8E80EFFFFFF04E83C0601E6330401 + D62B0001E0937601DB795901D32F1201E0896F01DD7D6101D9684A01FFFFFF01 + DF886B01D4240201D72A0001E6330401F63E0801FFFFFF01CF081801ED011801 + FF002002D8202901EEEEEE01EDEDED01EBEBEB01DDB0AF01ED011801FF002002 + D71F2801E2E2E201E0E0E001DFDFDF01DDDDDD012929E901BEBEBE01D0D0D003 + 04B206010CAE0D010343060100000002D0D0D009FFFFFF01D0D0D0108A8A8A01 + FFFFFF017C7C7C01E8E8E80EFFFFFF05F43D0701E2340401D5502501D4260001 + D4240201D9755201D3462201D3320E01EFC7B801E1947801DA2B0101E6330401 + F43D0701FFFFFF02D8001501D01A2001D9202A02C61D1E01EEEEEE01EDEDED01 + EBEBEB01DDB0AF01CF181E01D71F2802C51C1C01E2E2E201E0E0E001DFDFDF01 + DDDDDD017E7EE101BEBEBE01D0D0D00302AC08010033030100000002D0D0D00A + F5E1E201D0D0D0100000FF01D0D0D0017C7C7C01E8E8E80EFFFFFF01D0D0D001 + FFFFFF04F63E0801EB370501E2310301DB2C0101D62B0001D5290001D72A0001 + D96B4401DE846201EB370501F63E0801FFFFFF03D2061701F5F5F501F3F3F301 + F2F2F201F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601 + E5E5E501E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DEDEDE01BEBEBE01 + D0D0D00400000002D0D0D01CFF00FF01888888017C7C7C01FFFFFF15FD430901 + F53D0701EF390601EB370501EA360501EB370501E5400D01E04E1A01FD430901 + FFFFFF04C0282D01D92F3801DB313A01D3303501D25D5E01EDEDED02EBEBEB01 + E3CBCA01D87A7C01D22A3001D82F3702CB2D2F01D6969601E1E1E101DFDFDF01 + DEDEDE01BEBEBE01D0D0D00281C283010E8F1301002A0201000400010C0C0C01 + 80808001D0D0D00979797901FFFFFF10C9C9C9017C7C7C01FFFFFF103BEFFF01 + D0D0D001FFFFFF10E0E0E001D0D0D012FFFFFF09C0C0C001FFFFFF08D0D0D012 + 00000001FFFFFF0F00000001D0D0D012E0E0E001D0D0D0390000FF01D0D0D00D + 010101011C1C1C01D0D0D00188888808878E8E018686860100000001D0D0D004 + 7C7C7C01D0D0D011D9D9D901D0D0D00600000006D0D0D005FFFFFF01D0D0D011 + 80808001E0E0E001D0D0D0020000FF02D0D0D00100000008D0D0D003D9D9D902 + D0D0D00188888801B5F8FE01BAF9FE01BFFAFE01C4FBFE01C9FCFE01CEFDFE01 + D3FEFE01A0AFB0019EC1C5016363630100000001D0D0D0030000FF01D0D0D008 + 0000B602D0D0D008FFFFFF01D0D0D00400000008D0D0D004E9A49101D0D0D012 + 000000010000FF0500000008D0D0D003353535013E3E3E01D0D0D00188888801 + B5F8FE01BAF9FE01BFFAFE01C4FBFE01C9FCFE01CEFDFE01D3FEFE01A7B6B701 + E0FCFF019CC1C5016565650100000001D0D0D0090505C6010B0BCE011515D501 + 1A1AD5011616CE010D0DC601D0D0D006FFFFFF01D0D0D0040000000218189B01 + 3434FF013F3FFE012D2D9B0100000002D0D0D004FCF3F001D0D0D0017C7C7C0F + FFFFFF01D0D0D0014E4E4E010000FF01D0D0D0010000FF02D0D0D00400000003 + D0D0D00100000001D0D0D00300000002D0D0D00188888801B5F8FE018BBABD01 + 97C6C90197C2C401ACD7D901B2DADB019DBDBD019AB5B701F0FDFF01DDFCFF01 + 9BC2C5016767670100000001D0D0D001A7CDCE01D0D0D0050303C8011515E901 + 2929FF013434FF014040FF014B4BFF013A3AE4011313BB01D0D0D005F3C3B601 + D0D0D0030000000100000101060638012929FF013434FF014040FF014B4BFF01 + 191948010000010100000001D0D0D003E0E0E001D0D0D0017C7C7C01E8E8E80E + FFFFFF01D0D0D001D9D9D9010000FF01D0D0D0010000FF02D0D0D00400000005 + D0D0D0030000FF01D0D0D00288888801B5F8FE017CA6A90175999B0174959601 + 8DB1B2018BABAB0195B3B3018DB4B701BCF8FF01F3FDFF01DBFBFF019BC4C701 + 686A6A0100000001D0D0D0050303C6010D0DE9011E1EFF012929FF013434FF01 + 4040FF014B4BFF015656FF014242E2010D0D8E01D0D0D003DADADA01804CF001 + D0D0D0030404EA010E0ED3011919DE012929FF013434FF014040FF014B4BFF01 + 1F1F5C0104040B0139398301D0D0D0057C7C7C01E8E8E8016161610162626201 + 61616101E7E7E7019C9C9C015D5D5D0158585801BABABA01D9D9D90156565601 + 616161017C7C7C01E8E8E801FFFFFF0180808001D0D0D0010000FF01D0D0D007 + 00000005D0D0D003C9F6F601B2F3F601D0D0D00188888801B5F8FE01BAF9FE01 + BFFAFE01C4FBFE01C9FCFE01CEFDFE01D3FEFE0193B9BB0188B3B70190B4B701 + 98B5B7018BAFB301858C8C01000000010000FD01D0D0D0040303CE011212FF01 + 1E1EFF012929FF013434FF014040FF014B4BFF015656FF016262FF011B1BB401 + 00000001D0D0D0029523410100FCF801D0D0D0030606FF011111FF011D1DFF01 + 2929FF013434FF014040FF013636B6010202050124245E015757CC0100000001 + D0D0D00209A40001D0D0D0017C7C7C01CACACA0192929201E8E8E80174747401 + B4B4B40175757501E6E6E601D1D1D10157575701AAAAAA01B1B1B101E8E8E801 + 4A4A4A01E0E0E001FFFFFF01D0D0D001B5F8FE010000FF01D0D0D00400000006 + D0D0D0020000FF03D0D0D0010606FC01D0D0D00188888801B5F8FE01BAF9FE01 + BFFAFE01C4FBFE01B5E2E401A7CDCE019BBABA01A9CFCF0194CACC017FC3C801 + 89F5FE0172F2FE018888880100000001E0E0E001EEEEEE01D0D0D0020000B601 + 0202D5011212FF011E1EFF012929FF013434FF014040FF014B4BFF015656FF01 + 6262FF012929C40100000D01D0D0D002000000010DB60001D0D0D0030606FF01 + 1111FF011D1DFF012929FF013434FF012E2EB8010303090114143B016060F701 + 6868F00100000001D0D0D00280808001E07000017C7C7C01E8E8E802CFCFCF01 + 48484801DEDEDE01E8E8E80267676701A6A6A601E8E8E802B4B4B40158585801 + E8E8E801FFFFFF010000010176D3DB010000FF01D0D0D00400000006D0D0D004 + 0000FF01BDBDBD01D0D0D00288888801B5F8FE01BAF9FE01BFFAFE01C4FBFE01 + A8D2D40191B3B30197B5B5019FC3C30183B2B4016BA5A90189F5FE0172F2FE01 + 8888880100000001E0E0E001FFFFFF01D0D0D0020000B6010202D5011212FF01 + 1E1EFF012929FF013434FF014040FF014B4BFF015656FF016262FF012929C401 + 00000A01D0D0D00200000001D0D0D0040606FF011111FF011D1DFF012929FF01 + 2B2BD301020206010E0E31015151EE016363FF016868F00100000001D0D0D002 + FFFFFF01000000017C7C7C01E8E8E80251515101D1D1D101E8E8E8029F9F9F01 + 83838301E8E8E802E7E7E70142424201E2E2E201E8E8E801FFFFFF0100000001 + 0F0F56010000FF01D0D0D00E0000FF01A3A3A30103030301D0D0D00188888801 + B5F8FE01BAF9FE01BFFAFE01C4FBFE01C9FCFE01B0D8D901CEF8F801C9F6F601 + B2F3F6019FF5FB0186F0F90172F2FE018888880100000001FFFFFF0100000001 + D0D0D0030303CE011212FF011E1EFF012929FF013434FF014040FF014B4BFF01 + 5656FF016262FF011A1AB30100000001D0D0D002FFFFFF014F4F4F01D0D0D003 + 0606FF011111FF011D1DFF012929FF0113135F0103030C014545E9015757FF01 + 6363FF015757CC0100000001D0D0D00247474701FFFFFF017C7C7C01E8E8E802 + ABABAB01E8E8E803C0C0C001D4D4D401E8E8E802E3E3E301B1B1B101E8E8E802 + FFFFFF0100000001E0E0E0010000FF01D0D0D00E0000FF01D0D0D00388888801 + B5F8FE01BAF9FE01BFFAFE01C4FBFE019AC2C3018DADAD01839D9D017A959501 + 83B3B5015B8C8F0154979C0172F2FE018888880100000002FFFFFF01D0D0D003 + 0303C6010C0CE4011E1EFF012929FF013434FF014040FF014B4BFF015656FF01 + 4242E2010A0A6C0100000001D0D0D00200000001FFFFFF01D0D0D0030404FF01 + 1111FE011D1DFF012929FF010B0B36010F0F3D014B4BFF015757FF016262FE01 + 2626590100000001D0D0D002CE331101FFFFFF017C7C7C01E8E8E80260606001 + E8E8E80391919101B8B8B801E8E8E802D7D7D70172727201E8E8E802FFFFFF02 + E0E0E0010000FF01D0D0D00200000008D0D0D0040000FF01D0D0D00388888801 + B5F8FE01BAF9FE01BCF6FA01C4FBFE01BCECEE01AFD7D8018DA9A901B3DBDB01 + 8FC3C50180C4C90176D3DB0172F2FE0188888801000000010000FF0100000001 + D0D0D0040303BB011414E2012929FF013434FF014040FF014B4BFF013939E201 + 0F0F9A0100000002D0D0D002FFFFFF02D0D0D0040F0FDF011D1DFE012929FF01 + 2626BC013232C7014B4BFF015656FE013E3E9E0100000002D0D0D002CF350B01 + 000000017C7C7C01E8E8E80EFFFFFF0100000001D0D0D0010000FF02D0D0D001 + 00000008D0D0D0010000FF02D0D0D0010000FF01D0D0D00388888801B5F8FE01 + 92C3C70190BCBF0193BCBE017592930192B4B401CCF5F501CFFEFE01B8FBFE01 + A1F8FE0189F5FE0172F2FE018888880100000001FFFFFF0100000001D0D0D005 + 04048E010A0AB4011313C4011717C4011313B30107076C0100000002D0D0D003 + 8C8C8C01D5503001D0D0D005101088012121CC012222A7012B2BAC013B3BCC01 + 1F1F590100000002D0D0D00380808001FFFFFF017C7C7C01FFFFFF0F00000001 + FFFFFF01D0D0D00A00000001D0D0D0010000FF02D0D0D0010000FF01FFFFFF02 + D0D0D00188888801B5F8FE017AA3A60189B3B6018FB7B90188AAAB0191B3B301 + CDF7F701CFFEFE01B8FBFE01A1F8FE0189F5FE0172F2FE018888880100000001 + FFFFFF018C8C8C01D0D0D0060000000100000D0100000A0100000003D0D0D004 + F5F5F501804CF001D0D0D00600000006D0D0D005FFFFFF01D0D0D0108C8C8C01 + FFFFFF01D0D0D003000000080000FF05D0D0D0038888880E00000001D0D0D001 + FFFFFF01D0D0D010FFFFFF02D0D0D00700000002D0D0D007FFFFFF0100000001 + D0D0D010FFFFFF01FF1E4001D0D0D00300000008D0D0D0010000FF02D0D0D005 + 0000000F88888801C6C6C601D0D0D010FFFFFF02D0D0D010FFFFFF01D7D7D701 + D0D0D010E4E4E401D0D0D00E0000FF01D0D0D004FFFFFF0C00000003FFFFFF01 + D0D0D001FFFFFF0C00000001FFFFFF05E0E0E001FFFFFF10D0D0D001BBBBBB01 + B0B0B001DBDBDB01A2A2A201BABABA01E3E3E3018C8C8C01E3E3E3019E9E9E03 + 8D8D8D018C8C8C01FFFFFF057C7C7C01FFFFFF10CEFDFE01ADADAD01DE445B01 + E91B3A02DE435A01BEBEBE0DFFFFFF0AC2C2C2013A3A3A013B3B3B01C6C6C601 + FFFFFF03E07C6101D0D0D001FFFFFF10D0D0D002FFFFFF1000000001D0D0D001 + FFFFFF11BEBEBE01D0D0D001FF1E4003D0D0D00D00000001D0D0D010804CF001 + D0D0D011959595010000FF017C7C7C0FFFFFFF01BAF9FE01BCF8FF01D0D0D004 + 0DEEFF01D0D0D00BFFFFFF01BEBEBE01D0D0D001FF1E4004D0D0D00CCD2D0401 + D0D0D010F8FCF8017C7C7C01D0D0D00188888808878E8E018686860100000001 + D0D0D00488888801000000017C7C7C01E8E8E80EFFFFFF0167676701FFFFFF01 + D0D0D00233EFFF0147EFFF0142EFFF0127EEFF010DEEFF01D0D0D00927EEFF01 + BEBEBE01D0D0D003FF1E4004D0D0D00AF8FCF801D0D0D0114A4A4A01D0D0D001 + 88888801B5F8FE01BAF9FE01BFFAFE01C4FBFE01C9FCFE01CEFDFE01D3FEFE01 + A0AFB0019EC1C5016363630100000001D0D0D0037ABCC0018DB1B2017C7C7C01 + E8E8E80EFFFFFF010000FF01F3F3F301D0D0D0013BEFFF016FF1FF018EF1FF01 + 87F1FF015FF0FF0128EEFF010AB2BF01D0D0D009BEBEBE01D0D0D004FF1E4005 + D0D0D0097C7C7C0FFFFFFF01D9D9D9018AB4B701D0D0D00188888801B5F8FE01 + BAF9FE01BFFAFE01C4FBFE01C9FCFE01CEFDFE01D3FEFE01A7B6B701E0FCFF01 + 9CC1C5016565650100000001D0D0D0021C1C1C01D0D0D0017C7C7C01E8E8E80E + FFFFFF01E0E0E001D0D0D00258F0FF019AF2FF01D0F4FF01C1F3FF0184F1FF01 + 42EFFF010CD6E50100000001D0D0D007FF002601B8BFC101D0D0D006FF1E4004 + D0D0D006C8D0D301D0D0D0017C7C7C01E8E8E80EFFFFFF013C3C3C0188888801 + D0D0D00188888801B5F8FE01BAF9FE01BFFAFE01C4FBFE01C9FCFE01CEFDFE01 + D3FEFE019AB5B701F0FDFF01DDFCFF019BC2C5016767670100000001D0D0D001 + FFFFFF010000FF017C7C7C01E8E8E80EFFFFFF016262F1018080FF01D0D0D001 + 58F0FF019AF2FF01D0F4FF01C1F3FF0184F1FF0142EFFF010DE6F70100000001 + D0D0D0020808FF01D0D0D0043838380183C8E5018ADCFF018EDEFF01D0D0D006 + FF1E4004D0D0D00276D7FF018ADCFF017FD6FA01323232017C7C7C01E8E8E801 + 7B7B7B014F4F4F0174747401E8E8E802BABABA0160606001E8E8E801E6E6E601 + 5F5F5F014A4A4A0198989801E8E8E801FFFFFF02B2B2B201D0D0D00188888801 + B5F8FE01BAF9FE01BFFAFE01C4FBFE01C9FCFE01CEFDFE01D3FEFE018DB4B701 + BCF8FF01F3FDFF01DBFBFF019BC4C701686A6A01000000010404FF01E0E0E001 + 7C7C7C01E8E8E807BDBDBD018E8E8E01E0E0E001E8E8E804FFFFFF01D9D9D901 + A1A1FF01D0D0D0013BEFFF016FF1FF018EF1FF0187F1FF015FF0FF0128EEFF01 + 0BC0CE0100000001D0D0D0010000FF010404FF0100008F01D0D0D003D9D9D901 + 9AD1E901B4E9FF0190DEFF018FDEFF01D0D0D006FF1E4003D0D0D0018BDDFF01 + 9BE1FF01B4E9FF0193DFFF01B8B8B8017C7C7C01C6C6C60155555501E8E8E801 + 53535301CBCBCB01ACACAC015353530150505001E8E8E8019999990182828201 + E8E8E80137373701E7E7E701FFFFFF02FF002001D0D0D00188888801B5F8FE01 + BAF9FE01BFFAFE01C4FBFE01C9FCFE01CEFDFE01D3FEFE0193B9BB0188B3B701 + 90B4B70198B5B7018BAFB301858C8C0100000001FF002601E0E0E0017C7C7C01 + E8E8E807D2D2D2015D5D5D011A1A1A0169696901C9C9C901E8E8E802FFFFFF03 + D0D0D0010DEEFF0131E5F50147EFFF0142EFFF0127EEFF010CE1F10103333601 + 00000001D0D0D0010303FF010404FF010303BB0100000001D0D0D002CEFDFE01 + BADBE901DDF5FF0192DFFF0191DEFF01FF002601D0D0D001FF002601D0D0D001 + FF002601D0D0D001FF002601D0D0D001FF002601D0D0D001B6E9FF01C6EEFF01 + DDF5FF01B5E9FF01FFFFFF017C7C7C01A1A1A10182828201E8E8E8017E7E7E01 + A4A4A401E3E3E301E1E1E10150505001E8E8E80172727201B1B1B101E8E8E801 + 4F4F4F01D3D3D301FFFFFF01AE755801D0D0D00288888801B5F8FE01A8E2E601 + 85AEB001BEF3F601C9FCFE01CEFDFE01A8CACA01CFFEFE01B8FBFE017ABCC001 + 6FC7CE0172F2FE0188888801000000019F9FFF01929292017C7C7C01E7E7E701 + 858585012E2E2E0153535301A4A4A401B4B4B4018C8C8C01E8E8E802DBDBDB01 + 888888012B2B2B0144444401E2E2E201FFFFFF0100000001D0D0D00306747C01 + 08949E010AAFBB01088E9801011A1C01000000020707FF010404FF020404FC01 + 02025501D0D0D002FFFFFF01D4E2E801F8FBFD0195DFFF0194DFFF01FF002601 + A3E4FF01FF002601A3E4FF01FF002601A3E4FF01FF002601A3E4FF01FF002601 + A3E4FF01E1F6FF01F1FAFF01F8FBFD01D9F3FE01CB2203017C7C7C01B1B1B101 + 80808001E8E8E8017B7B7B01A8A8A801E8E8E801E1E1E10150505001E8E8E801 + 81818101B0B0B001E8E8E8014C4C4C01D8D8D801FFFFFF01E0E0E001D0D0D002 + 88888801B3F5FB0142585A018AB4B701556C6E01C9FCFE01708A8A01343F3F01 + CFFEFE017AA6A8015E9194013A686C015EC7D1018888880100000001D0D0D002 + 7C7C7C01E2E2E20169696901AEAEAE01777777012B2B2B0124242401A0A0A001 + E8E8E802DFDFDF018D8D8D012D2D2D0143434301E2E2E201FFFFFF0192C3C701 + 88888801D0D0D00300000005D0D0D0010505FF010404FF030404C70100000001 + D0D0D001FFFFFF01DBE1E501D7EAF30188D6F7018FDBFB01FF002601FFFFFF01 + FF002601FFFFFF01FF002601FFFFFF01FF002601FFFFFF01FF002601FFFFFF01 + F4F9FB01E7F3F801D7EAF301EEF8FD01DA644B017C7C7C01E3E3E30156565601 + E8E8E8014E4E4E01CFCFCF01E8E8E801E1E1E10150505001E8E8E801BBBBBB01 + 7E7E7E01E4E4E40139393901E8E8E801FFFFFF0160E84801D0D0D00288888801 + 9CD6DB015B7A7D01BFFAFE0144585901C9FCFE01A8CECF0155676701CFFEFE01 + 4B66680199EBF1016BBFC601418B910188888801000000020000FF017C7C7C01 + E8E8E807D6D6D601696969011D1D1D0166666601C7C7C701E8E8E802FFFFFF01 + 72F2FE01FFFFFF01D0D0D001FF002006D0D0D0010505FF010404FF040404FE01 + 02026701D0D0D00100000001C2D4DD01B6D9E90173C7EB017BCDEF01FF002601 + B6D9E901FF002601B6D9E901FF002601B6D9E901FF002601B6D9E901FF002601 + B6D9E901D2E8F101C5E1EE01B6D9E901E2F0F601E0E0E0017C7C7C01E8E8E801 + 959595015A5A5A0190909001E8E8E802E3E3E30176767601E8E8E801E6E6E601 + 7B7B7B0159595901AEAEAE01E8E8E801FFFFFF0100000001FFFFFF01D0D0D001 + 888888019FDADF0162848601BFFAFE014B5F6101C9FCFE01CEFDFE0155676701 + CFFEFE014F6C6E019DF2F8016FC7CE01418A90018888880100000001FFFFFF01 + 888888017C7C7C01E8E8E807BBBBBB0188888801DDDDDD01E8E8E804FFFFFF01 + D0D0D001FFFFFF01D0D0D001FF002006000000010404FF060303D50100000001 + FFFFFF01A8C7D50194C8DF015EB9DF0166BEE301FF0026016DB4D401FF002601 + 6DB4D401FF0026016DB4D401FF0026016DB4D401FF0026016DB4D401AFD6E701 + A3D0E30194C8DF01C6E1EE01D0D0D0017C7C7C01E8E8E80EFFFFFF01D0D0D001 + FFFFFF01D0D0D00188888801B5F8FE014D686A01B1E7EB01495E5F01C9FCFE01 + CEFDFE0155676701CFFEFE0178A3A50179BBBF014D898E0155B4BD0188888801 + 00000001FFFFFF01D0D0D0017C7C7C01E8E8E80EFFFFFF01E0E0E001FFFFFF01 + D0D0D001FF00200600000001D0D0D00100000007D0D0D0018FBACE0173B8D601 + 4AABD30151B0D701FF002601248FBE01FF002601248FBE01FF002601248FBE01 + FF002601248FBE01FF002601248FBE018DC5DD0180BED90173B8D601AAD3E501 + D0D0D0017C7C7C01FFFFFF0FD0D0D001EC25EC01D0D0D00188888801B5F8FE01 + 96C8CC0162808201ADDDE001C9FCFE01CEFDFE0194B2B201CFFEFE01B3F4F701 + 62979A0155999E0172F2FE018888880100000001FFFFFF027C7C7C01E8E8E80E + FFFFFF02D0D0D002FF00200600000001D0D0D008FF00FF0175AEC70152A7CC01 + 359CC7013DA1CC01FF002601D0D0D001FF002601D0D0D001FF002601D0D0D001 + FF002601D0D0D001FF002601D0D0D0016BB3D3015EADCF0152A7CC018DC4DC01 + D0D0D011FFFFFF02D0D0D00188888801B5F8FE01BAF9FE01BFFAFE01C4FBFE01 + C9FCFE01CEFDFE01D3FEFE01CFFEFE01B8FBFE01A1F8FE0189F5FE0172F2FE01 + 8888880100000001FFFFFF027C7C7C01E8E8E80EFFFFFF02D0D0D002FF002006 + 00000001D0D0D008FF00FF015CA1BF013196C201218EBB012893C001D0D0D00A + 49A2C9013C9BC5013196C20170B6D401FFFFFF01D0D0D010FFFFFF01D5D5D501 + D0D0D0018888880E00000001B6AFAF01D0D0D0017C7C7C01E8E8E80EFFFFFF02 + 0000FF01D0D0D001FF00200600000001D0D0D008FFFFFF014394B8011085B801 + 0C7FB001D0D0D00C198ABB011085B80154A8CC01FFFFFF01D0D0D011D5D5D501 + D0D0D00100000010FFFFFF017C7C7C01FFFFFF0FD0D0D001E21BE201D0D0D002 + 00000006D0D0D008D4D4D4012A87B001238EBB012C93BE0175AFC701D0D0D00B + 9CBECD014DA2C8013899C30188888801FFFFFF10D0D0D001FCE0E301FFFFFF10 + 797979016FF1FF01FFFFFF10D0D0D001C1C1C101FFFFFF10D0D0D001DADADA01 + FFFFFF10D9D9D901ADADAD01999999018E8E8E028C8C8C0C8D8D8D0194949401 + FFFFFF12D0D0D012D4D4D413D0D0D0103931320199999901D0D0D0019A9A9A01 + 9E9E9E019A9A9A0B9E9E9E01D0D0D0019F9F9F01804CF0017C7C7C0FFFFFFF01 + D0D0D013D4D4D401D0D0D010D4D4D401D0D0D0059B9B9B019C9A9A019E9D9D01 + A09D9E019C9A9A0199999901D0D0D00679797901848484019A9A9A019D9D9D01 + BABABA01DEDEDE01DFDFDF08CFCFCF019D9D9D019A9A9A01D0D0D0019E9E9E01 + D0D0D0017C7C7C01C0C0C002A9A9A901BABABA01AAAAAA01A6A6A601A9A9A901 + AEAEAE01A5A5A5018E8E8E01A9A9A901BCBCBC01ACACAC01A0A0A001FFFFFF01 + D0D0D013D4D4D401D0D0D00500000006D0D0D005FFD4D902D0D0D00295959501 + 9E9E9E01A29F9F01CBC0C101E1D4D501E1D1D201CCBEC0019F9C9C018B8B8B01 + 8A8A8A01D0D0D004FF0000017C7C7C018A8A8A018686860B8B8B8B01BEBEBE01 + 9A9A9A01D0D0D0019E9E9E01D0D0D0017C7C7C018B8B8B0198989801A9A9A901 + B7B7B70194949402A9A9A901989898018181810170707001A9A9A901B8B8B801 + 8E8E8E018D8D8D01FFFFFF027E7E7E018B8B8B108F8F8F0199989801D0D0D004 + 00000008D0D0D00479797902D0D0D0029C9B9B01B6AFAF01F5E1E201FEECEE01 + FEE8EA01FEE4E701FFE1E401FADADD01B6ABAC018381810100000001D0D0D003 + 9C9C9C017A7A7A0186868601AAAAFF01AEAEFF01B2B2FF01B6B6FF01BBBBFF01 + BFBFFF01C3C3FF01C8C8FF01CCCCFF01D0D0FF01D4D4FF0186868601D7D7D701 + 9A9A9A01D0D0D0019E9E9E017C7C7C02ABABAB01B4B4B401A9A9A901C0C0C001 + ACACAC01A4A4A401A9A9A901C0C0C003A9A9A901C0C0C001B5B5B501A9A9A901 + FFFFFF028B8B8B01D9D9D902C5C5C501C8C8C801D9D9D901CDCDCD01D2D2D201 + D9D9D901D8D8D801CDCDCD02C9C9C901D9D9D902D0D0D001CECECE01F9F9F901 + 78AECA01D0D0D0040000000200009B010000FF010000FE0100009B0100000002 + D0D0D004FF00FF0179797901D0D0D00198989801A3A1A101F5E0E101FDEBEC01 + 9F929301554D4E01564C4D019B878901FFDADF01FBD3D801A09C9C014D4D4D01 + 00000001D0D0D002F1F1F1017A7A7A0186868601AAAAFF01AEAEFF01B2B2FF01 + B6B6FF01BBBBFF0100000001C3C3FF01C8C8FF01CCCCFF01D0D0FF01D4D4FF01 + 86868601D7D7D7019A9A9A01D0D0D0019E9E9E01FFFFFF017C7C7C01A9A9A90E + FFFFFF028B8B8B01D9D9D9017E7E7E01212121012C2C2C01ABABAB0188888801 + 80808001D9D9D901C3C3C30161616101666666013C3C3C01D4D4D401D9D9D901 + 6868680179797901F9F9F90100FFFF01D0D0D003000000010000010100003801 + 0000FF04000048010000010100000001D0D0D003E1E1E10180808001D0D0D001 + 9E9D9D01D3C5C601FCE9EA01FDE9EB01524A4B01FCE0E301FEDEE201322B2C01 + FCD4D901FFD4D901D8BDC0018683840100000001D0D0D002D4D4D4017A7A7A01 + 86868601AAAAFF01AEAEFF01B2B2FF01B6B6FF01BBBBFF01BFBFFF01C3C3FF01 + C8C8FF01CCCCFF01D0D0FF01D4D4FF0186868601D7D7D7019A9A9A01D0D0D001 + 9E9E9E01FFFFFF017C7C7C01C2C2C201C0C0C001A9A9A901D3D3D301BABABA01 + ADADAD01A9A9A901E7E7E701CDCDCD01BDBDBD01A9A9A901E2E2E201B6B6B601 + BDBDBD01FFFFFF01D75835018B8B8B01CECECE012D2D2D01BFBFBF0193939301 + 50505001BFBFBF014A4A4A01C5C5C5018989890176767601666666011F1F1F01 + ABABAB01D9D9D9012B2B2B016D6D6D01F9F9F901C902C901D0D0D0030000EA01 + 0000D3010000DE010000FF0400005C0100000B0100008301D0D0D003D4D4D402 + D0D0D0019D9C9C01EBDADB01FFECEE01FFE8EA01FFE4E701FFE0E401CCB0B301 + 443A3B01FFD4D902EECACE019896960100000002D0D0D001D4D4D4017A7A7A01 + 8686860DD7D7D7019A9A9A01D0D0D0019E9E9E01BC8C75017C7C7C01A0A0A001 + A6A6A601A9A9A901C7C7C70187878701B3B3B301A9A9A901ADADAD01A6A6A601 + 9D9D9D01A9A9A901FFFFFF01B3B3B302FFFFFF01E0E0E0018B8B8B01CBCBCB01 + 353535018D8D8D01BCBCBC01A5A5A501D3D3D301696969018E8E8E013C3C3C01 + B9B9B901676767013F3F3F0188888801C4C4C4012D2D2D0171717101F9F9F901 + 42424201D0D0D0030000FF060000B6010000050100005E010000CC0100000001 + D0D0D002FFFFFF01D0D0D0029C9B9B01F4E3E501FFE9EB01FFE5E801FFE1E401 + E5C6CA0139313201E9C3C701FFD4D902F4CED2019998980100000002D0D0D001 + DADADA017A7A7A0186868601ADF9F101ADFFF701B2FFF701B6FFF801BAFFF901 + BFFFF901C3FFFA01C7FFFB01CBFFFC01D0FFFC01D4FFFD0190959501D7D7D701 + 9A9A9A01D0D0D0019E9E9E0100FCF8017C7C7C01B9B9B901B0B0B001A9A9A901 + FFFFFF03A9A9A901EFEFEF01CCCCCC01BABABA01A9A9A901FFFFFF040EB50001 + 8B8B8B01D9D9D9019A9A9A012A2A2A012B2B2B01A7A7A701D9D9D901A6A6A601 + 262626016A6A6A01D8D8D801676767015C5C5C0176767601828282015C5C5C01 + 71717101F9F9F901D2D2D201D0D0D0030000FF050000B8010000090100003B01 + 0000F7010000F00100000001D0D0D002D2D2D202D0D0D001A19EA001E0D1D301 + FFE6E901FFE2E501FFDEE201A68E9101A48A8D01FFD4D903E0C2C5018E8B8B01 + 00000002D0D0D001D2D2D2017A7A7A0186868601ADF9F101ADFFF701B2FFF701 + B6FFF801BAFFF90100000001C3FFFA01C7FFFB01CBFFFC01D0FFFC01D4FFFD01 + 90959501D7D7D7019A9A9A01D0D0D0019E9E9E01E0E0E0017C7C7C01A9A9A90E + FFFFFF01D0D0D0018B8B8B01D2D2D201C7C7C701D4D4D401888888012F2F2F01 + D9D9D9022E2E2E01D1D1D101D9D9D901676767016565650241414101A5A5A501 + 71717101F9F9F901D2D2D201D0D0D0030000FF040000D3010000060100003101 + 0000EE010000FF010000F00100000001D0D0D002D2D2D202D0D0D0019B9B9B01 + B6AFAF01FFE3E601FFDFE301FFDBDF01CFAFB301D2AFB301FFD4D903B5A8A901 + 6464640100000002D0D0D001D2D2D2017A7A7A0186868601ADF9F101ADFFF701 + B2FFF701B6FFF801BAFFF901BFFFF901C3FFFA01C7FFFB01CBFFFC01D0FFFC01 + D4FFFD0190959501D7D7D7019A9A9A01D0D0D0019E9E9E010DB600017C7C7C01 + BABABA01C0C0C001A9A9A901E2E2E201CFCFCF01BABABA01A9A9A901E2E2E201 + CFCFCF01BABABA01A9A9A901DDDDDD01CFCFCF01BEBEBE01FFFFFF01CFCFCF01 + 8B8B8B01B2B2B20149494901D1D1D101C6C6C60133333301D9D9D90230303001 + D6D6D601D9D9D90167676701717171016565650134343401BABABA0171717101 + F9F9F901D2D2D201D0D0D0030000FF0400005F0100000C010000E9010000FF02 + 0000CC0100000001D0D0D002D2D2D202D0D0D0019292920199989801D8C5C701 + FFDCE001FFD8DD01C3A2A601C7A5A901FFD4D902D8BDC1019596990135678101 + 05090C0100000001D0D0D001D2D2D2017A7A7A018686860DD7D7D7019A9A9A01 + D0D0D0019E9E9E017C7C7C02A1A1A101C0C0C001A9A9A901AEAEAE018A8A8A01 + 88888801A9A9A901AEAEAE018A8A8A0188888801A9A9A901AEAEAE0180808001 + 96969601FFFFFF028B8B8B01D4D4D401505050012D2D2D013131310169696901 + D9D9D90230303001D6D6D601D9D9D901676767017C7C7C01757575015B5B5B01 + BABABA0171717101F9F9F901D2D2D201D0D0D0030000FF010000FE010000FF02 + 0000360100003D010000FF020000FE010000590100000001D0D0D002D2D2D202 + D0D0D0029696960197959601BAADAE01F1CDD101FFD4D902F1CCD001BAABAD01 + 98989901A5C2D10178AECA013D7C9B010C181E01D0D0D001808080017A7A7A01 + 86868601FFAAB801FFAEBB01FFB2BE01FFB6C101FFBBC401FFBFC701FFC3CA01 + FFC8CD01FFCCD001FFD0D301FFD4D60186868601D7D7D7019A9A9A01D0D0D001 + 9E9E9E01FFFFFF017C7C7C01A4A4A401C0C0C001A9A9A901ECECEC01DBDBDB01 + C9C9C901A9A9A901ECECEC01DBDBDB01C9C9C901A9A9A901E7E7E701DBDBDB01 + CCCCCC01FFFFFF028B8B8B01D9D9D9029F9F9F019D9D9D01D4D4D401D9D9D902 + A4A4A401D9D9D902BBBBBB01C2C2C201C0C0C001C4C4C401CFCFCF01B9B9B901 + F9F9F901D2D2D201D0D0D0040000DF010000FE010000FF010000BC010000C701 + 0000FF010000FE0100009E0100000002D0D0D002D2D2D202D0D0D0033F3F3F01 + 78777701969495019998980296949501706F6F01406F870183B5CE01A8CBDD01 + 78AFCA013D7C9B0112252E01D2D2D2017A7A7A0186868601FFAAB801FFAEBB01 + FFB2BE01FFB6C101FFBBC40100000001FFC3CA01FFC8CD01FFCCD001FFD0D301 + FFD4D60186868601B6B6B6019E9E9E01D0D0D0019E9E9E01FFFFFF017C7C7C01 + A9A9A90EFFFFFF01CE3006018B8B8B01D9D9D910F9F9F901D2D2D201D0D0D005 + 000088010000CC010000A7010000AC010000CC010000590100000002D0D0D003 + D2D2D202D0D0D00400000002181818011414140100000002070E12014A88A801 + 83B5CE01A8CBDD0178AFCA01346A8501D2D2D2017A7A7A0186868601FFAAB801 + FFAEBB01FFB2BE01FFB6C101FFBBC401FFBFC701FFC3CA01FFC8CD01FFCCD001 + FFD0D301FFD4D60186868601969696011818180100000001A0A0A001FFFFFF01 + 7C7C7C01C5C5C501C0C0C001A9A9A901E0E0E001D8D8D801CFCFCF01A9A9A901 + EAEAEA01D8D8D802A9A9A901FDFDFD01D0D0D001D2D2D201FFFFFF0100000001 + 8F8F8F01F8F8F810FEFEFE01D2D2D201D0D0D00600000006D0D0D004D2D2D202 + D0D0D00600000004D0D0D0011B3846014987A60182B5CE01A8CADC01364E5A01 + D2D2D2017A7A7A01888888018686860B898989012B2B2B0100000001D0D0D001 + 68686801FFFFFF017C7C7C01A1A1A10191919101A9A9A901A6A6A601ADADAD01 + AAAAAA01A9A9A901EAEAEA01A9A9A901B3B3B301A9A9A901F3F3F301A6A6A601 + 60606001FFFFFF02D0D0D012D2D2D201D0D0D00700000002D0D0D007D2D2D202 + D0D0D00C28506501417893013C53600100000001DADADA017A7A7A010000000E + D0D0D00214141401FFFFFF017C7C7C01F6F6F601FFFFFF0FD0D0D025D2D2D210 + D0D0D001727272017B7B7B0D7C7C7C015A5A5A012121210120202001D0D0D001 + FFFFFF10E0E0E001D0D0D024C8CAC001CBCCC701C8CBC802D1D1D102D0D0D00B + D1D1D10100000001FFFFFF1063636301D0D0D047D1CDCC01BFFAFE01D0D0D047 + D0CDCB01D0D0D010D1D1D10100000001D0D0D011D9D9D904FFFFFF0180808001 + D9D9D904D0D0D02CD1CFCF01D0D0D0070000B602D0D0D007CFCFCF010000FF01 + D0D0D0070000B602D0D0D0076262F101D0D0D036D1D1D101D0D0D0050000C301 + 0000CE010000D6020000CE010000C301D0D0D005D0CAC901E0E0E001D0D0D005 + 0000C3010000CE010000D6020000CE010000C301D0D0D005D9D9D901D0D0D036 + D0CCCA01D0D0D0040000C8010000E9010000FF040000E4010000BB01D0D0D004 + D1CDCC01E0E0E001D0D0D0040000C8010000E9010000FF040000E4010000BB01 + D0D0D00436363601D0D0D036CFC7C501D0D0D0030000C3010000E9010000FF06 + 0000E20100008C01D0D0D003D2D2D201D9D9D901D0D0D0030000C3010000E901 + 0000FF060000E20100008C01D0D0D004DADADA01D9D9D907FFFFFF0180808001 + D9D9D904D0D0D028D2D2D201D0D0D0030000CE010000FF080000B40100000001 + D0D0D002CFCFCF010000FF01D0D0D0030000CE010000FF080000B40100000001 + D0D0D002888888010000000162021101E8A52301221041010000000188090001 + 401D2801141D280100000002241D28010000000200000101D0D0D00400000002 + ECECEC22D1D1D101D0D0D0020000B6010000D6010000FF080000C50100000D01 + D0D0D002CFC8C60100000001D0D0D0020000B6010000D6010000FF080000C501 + 00000D01D0D0D00280C4C90100000036D0CBC901D0D0D0020000B6010000D601 + 0000FF080000C50100000A01D0D0D002CFC9C70190BCBF01D0D0D0020000B601 + 0000D6010000FF080000C50100000A01D0D0D002A3A3A6010000002AFFFFFF0C + CDC7C601D0D0D0030000CE010000FF080000B30100000001D0D0D002D1CFCE01 + 88888801D0D0D0030000CE010000FF080000B30100000001D0D0D00300000003 + 26262601010101010000001BFFFFFF018C8C8C0EFFFFFF0100000002FFFFFF04 + CFC8C601D0D0D0030000C3010000E4010000FF060000E20100006B0100000001 + D0D0D002D0CFCE01D0D0D0040000C3010000E4010000FF060000E20100006B01 + 00000001D0D0D002E0E0E00100000016FFFFFF018C8C8C0EFFFFFF0100000001 + FFFFFF0E00000001D1D1D101D0D0D0040000BB010000E2010000FF040000E201 + 00009A0100000002D0D0D002D2D2D201E0E0E001D0D0D0040000BB010000E201 + 0000FF040000E20100009A0100000002D0D0D003FFFFFF0D8C8C8C0EFFFFFF11 + 00000001FFFFFF09D1CDCC01D0D0D00500008C010000B4010000C5020000B301 + 00006B0100000002D0D0D003D0CECE01FFFFFF01D0D0D00500008C010000B401 + 0000C5020000B30100006B0100000002D0D0D003FFFFFF018C8C8C01FFFFFF02 + 8C8C8C0EFFFFFF1100000001FFFFFF0F0000000380808001D0D2D201D0D0D006 + 0000000100000D0100000A0100000003D0D0D004D2D2D201FFFFFF01D0D0D006 + 0000000100000D0100000A0100000003D0D0D004FFFFFF018C8C8C01DDDDDD01 + D8D8D803A3A3A3018C8C8C01FFFFFF1100000001FFFFFF0F0000000380808001 + FFFFFF05B6B6B6010707070100000003D2D2D201D0D0D010D0CCCA01D0D0D011 + FF1E4001FFFFFF0E00000001FFFFFF0F0000000380808001FFFFFF06DBDBDB01 + 1E1E1E0100000004FFFFFF01AFAFAF01BFBFBF018C8C8C01C0C0C001AEAEAE01 + 8F8F8F0190909001D1D1D101D0D0D010CFC9C701D0D0D012FFFFFF0400000001 + FFFFFF0F0000000380808001FFFFFF06E6E6E6017D7D7D010E0E0E0100000003 + FFFFFF01A8A8A801BFBFBF018C8C8C01C2C2C201ACACAC018C8C8C0190909001 + D7D7D7018C8C8C01BFBFBF01A8A8A8018C8C8C01DADADA0194949401FFFFFF02 + 8C8C8C01D1C4C001D0CAC801CFC8C601CFC7C401D0C9C701D0CCCB01D1D1D101 + D1CECD01D0CAC801D0C6C401CFC7C501D0C9C703CFC9C601CFC6C601CEC8C801 + CDC0C001FF1E4001FFFFFF107C7C7C01FFFFFF0A0000000380808001FFFFFF05 + D4D4D4018F8F8F016E6E6E010E0E0E0100000003FFFFFF018F8F8F01D4D4D401 + 8C8C8C01D8D8D801989898018C8C8C0190909001D7D7D7018C8C8C01A2A2A201 + C1C1C1018E8E8E01E3E3E3018C8C8C01FFFFFF028C8C8C01BBBBBB01B0B0B001 + C4C4C401DCDCDC0194949401E3E3E3018C8C8C01E3E3E3018C8C8C02501B0000 + 000000062E2E2E01151515010000000305050501000000500909090102020201 + 0000000106060601CFCFCF01D4D4D401747474017A7A7A01A1A1A101E8E8E801 + 575757010606060100000005FFFFFF1000000026FFFFFF0F8080800100000003 + 66666601CDCDCD018080800172727201E7E7E701FFFFFF01F7F7F701F8F8F801 + FDFDFD02B3B3B301727272013030300100000004FFFFFF10000000059B9B9B01 + 1B1B1B010000001FFFFFFF100000000323232301F1F1F101FDFDFD01F5F5F501 + FFFFFF07DBDBDB01939393019F9F9F01ACACAC0100000002FFFFFF1000000005 + C4C4C401DDDDDD01414141010000001EFFFFFF100000000330303001DEDEDE01 + FFFFFF0AFBFBFB01FFFFFF01ADADAD0100000002FFFFFF1000000005C0C0C001 + FFFFFF01EFEFEF01767676010000000BFFFFFF1000000002FFFFFF1000000002 + 0606060172727201E7E7E701FFFFFF0BF6F6F601767676010606060100000001 + FFFFFF1000000005C0C0C001FFFFFF02F8F8F801A7A7A7010303030100000009 + FFFFFF1000000002FFFFFF100000000237373701A9A9A901FFFFFF0DA9A9A901 + 3737370100000002FFFFFF0F00000005C0C0C001FFFFFF03FEFEFE01CACACA01 + 1212120100000008FFFFFF1000000002FFFFFF100000000261616101E2E2E201 + FFFFFF0DE6E6E6016363630100000001FFFFFF1000000005C0C0C001FFFFFF05 + DEDEDE013232320100000007FFFFFF1000000002FFFFFF100000000118181801 + EFEFEF01FFFFFF0EFDFDFD01B9B9B90100000001FFFFFF1000000005C0C0C001 + FFFFFF06EBEBEB016565650100000006FFFFFF1000000002FFFFFF1000000002 + 99999901FBFBFB01FFFFFF0DF6F6F6017A7A7A0100000001FFFFFF1000000005 + C0C0C001FFFFFF06F1F1F101A6A6A6010E0E0E0100000005FFFFFF1000000002 + FFFFFF100000000272727201ECECEC01FFFFFF0DECECEC017272720100000001 + FFFFFF1000000005C0C0C001FFFFFF05EBEBEB01A2A2A2016E6E6E010E0E0E01 + 00000005FFFFFF1000000002FFFFFF10000000025B5B5B01D2D2D201FFFFFF0D + D7D7D7015B5B5B0100000001FFFFFF1000000005C0C0C001FFFFFF03FEFEFE01 + E3E3E30194949401575757010404040100000006FFFFFF1000000002FFFFFF10 + 0000000237373701C3C3C301FFFFFF0DEBEBEB013737370100000001FFFFFF10 + 00000005C0C0C001FFFFFF02F9F9F901D4D4D4018B8B8B013D3D3D0100000008 + FFFFFF1000000002FFFFFF100000000206060601E7E7E701F8F8F801FFFFFF0B + DCDCDC01787878010606060100000001FFFFFF1000000005C0C0C001FFFFFF01 + F3F3F301BFBFBF01828282012525250100000009FFFFFF1000000002FFFFFF10 + 000000033F3F3F0191919101EDEDED01FFFFFF09ECECEC019191910130303001 + 00000002FFFFFF1000000005C4C4C401E4E4E401A9A9A9017474740113131301 + 0000001CFFFFFF10000000043E3E3E0199999901EEEEEE01FFFFFF07DBDBDB01 + 919191013E3E3E0100000003FFFFFF10000000059B9B9B015A5A5A0160606001 + 070707010000001DFFFFFF10000000053030300172727201A9A9A901D2D2D201 + EDEDED01F5F5F501ECECEC01F1F1F101EEEEEE01727272013030300100000005 + FFFFFF0F0000000615151501010101010000001EFFFFFF0180808001FFFFFF0E + 0000000606060601373737015B5B5B01727272017A7A7A01727272016F6F6F01 + 5D5D5D0106060601000000F1FFFFFF0100000010FFFFFF08FBFBFB0146464601 + 010101010000001D08080801656565019595950194949401696969010A0A0A01 + 0000001BFFFFFF020000000109090901151515011B1B1B021616160133333301 + 202020013939390100000006FFFFFF09FDFDFD0167676701010101010000000C + 070707020000000D1D1D1D01E0E0E001FFFFFF01D7D7D701DADADA01FFFFFF01 + E1E1E1012424240100000018FFFFFF0534343401626262015B5B5B0152525201 + 4A4A4A01383838016B6B6B013A3A3A0100000006FFFFFF0AFDFDFD016F6F6F01 + 010101010000000966666601C9C9C901DCDCDC02C9C9C901666666010000000B + B9B9B901FFFFFF01C7C7C701E5E5E502C7C7C701FEFEFE01C3C3C30100000006 + FFFFFF1000000002FFFFFF0100000001FFFFFF02000000040E0E0E0106060601 + 0E0E0E01000000010E0E0E0100000006FFFFFF0BFDFDFD017777770101010101 + 00000007A6A6A601F2F2F201FFFFFF04F7F7F701B1B1B1010000000911111101 + FDFDFD01FFFFFF06FEFEFE010D0D0D0100000005FFFFFF1000000002FFFFFF01 + 00000001FFFFFF0108080801000000045E5E5E014E4E4E015D5D5D0150505001 + 4C4C4C0100000006FFFFFF0CFDFDFD0180808001020202010000000566666601 + F2F2F201FFFFFF06F9F9F9018E8E8E01000000083E3E3E01FDFDFD01FFFFFF07 + 6F6F6F0100000005FFFFFF1000000002FFFFFF01000000072D2D2D0131313101 + 2F2F2F013D3D3D011C1C1C0100000006FFFFFF0E3636360100000005C9C9C901 + FFFFFF08E6E6E6012020200100000007AFAFAF01FFFFFF08DBDBDB0120202001 + 00000004FFFFFF1000000002FFFFFF0100000004141414012B2B2B0128282801 + 57575701232323011212120100000002FFFFFF0300000003FFFFFF0E88888801 + 0000000407070701DCDCDC01FFFFFF08EFEFEF016464640100000007E5E5E501 + FFFFFF08F3F3F3016060600100000004FFFFFF1000000002FFFFFF0100000004 + 2A2A2A014F4F4F01505050015E5E5E014A4A4A012929290100000004FFFFFF01 + 00000003FFFFFF0E8A8A8A010000000407070701DCDCDC01FFFFFF08EFEFEF01 + 8282820100000007E5E5E501FFFFFF08F3F3F3017E7E7E0100000004FFFFFF10 + 00000002FFFFFF010000000EFFFFFF0100000003FFFFFF0E8A8A8A0100000005 + C9C9C901FFFFFF08E7E7E7017E7E7E0100000007AFAFAF01FFFFFF08DBDBDB01 + 7E7E7E0100000004FFFFFF1000000002FFFFFF010000000EFFFFFF0100000003 + FFFFFF0E8A8A8A010000000566666601F7F7F701FFFFFF06F9F9F901BABABA01 + 60606001000000073A3A3A01FEFEFE01FFFFFF06FEFEFE01A6A6A60160606001 + 00000004FFFFFF1000000002FFFFFF01000000023B3B3B012D2D2D0114141401 + 1A1A1A011C1C1C01030303011A1A1A011313130100000004FFFFFF0100000003 + FFFFFF0E8A8A8A0100000006B1B1B101F9F9F901FFFFFF04F9F9F901D7D7D701 + 8B8B8B01202020010000000889898901FEFEFE01FFFFFF04FEFEFE01C2C2C201 + 8B8B8B012020200100000004FFFFFF1000000002FFFFFF02000000014E4E4E01 + 3D3D3D015B5B5B01646464016D6D6D0124242401656565013030300100000001 + 08080801FFFFFF0100000001FFFFFF0100000003FFFFFF0E8A8A8A0100000007 + 8E8E8E01E6E6E601EFEFEF02E7E7E701BABABA018B8B8B01424242010000000A + 6D6D6D01DBDBDB01F7F7F701F6F6F601DBDBDB01A6A6A6018B8B8B0142424201 + 00000005FFFFFF100000000C1212120100000001FFFFFF0200000001FFFFFF01 + 00000003FFFFFF0E8A8A8A01000000082020200164646401828282017E7E7E01 + 60606001202020010000000C20202001F6F6F601EFEFEF017E7E7E0160606001 + 202020010000001B6969690153535301525252015B5B5B015D5D5D017C7C7C01 + 4545450139393901FFFFFF0500000003FFFFFF0E8A8A8A010000001B78787801 + 707070010000001E262626011F1F1F011D1D1D0121212101222222012C2C2C01 + 1A1A1A010D0D0D0100000001FFFFFF020000000502020201888888018A8A8A0C + 8888880100000045FFFFFF01000000B9767676017C7C7C010707070100000032 + FFFFFF1000000006010101010000000E20202001B0B0B001DBDBDB0149494901 + 00000020FFFFFF08FBFBFB01464646010101010100000006FFFFFF1000000004 + 56565601D2D2D201F9F9F901D2D2D201565656010000000E49494901DBDBDB01 + AFAFAF01202020010000001EFFFFFF09FDFDFD01676767010101010100000005 + FFFFFF10000000035A5A5A01FFFFFF05787878010000000E070707017C7C7C01 + ECECEC017C7C7C010707070100000009FFFFFF1000000003FFFFFF0AFDFDFD01 + 6F6F6F010101010100000004FFFFFF1000000003D3D3D301FFFFFF05EBEBEB01 + 313131010000000F20202001B0B0B001DBDBDB014949490100000008FFFFFF10 + 00000003FFFFFF0BFDFDFD01777777010101010100000003FFFFFF1000000003 + F0F0F001FFFFFF05F8F8F80174747401000000022222220100000006FFFFFF01 + 555555010000000649494901DBDBDB01B0B0B001202020010000000255555501 + FFFFFF0100000002FFFFFF1000000003FFFFFF0CFDFDFD018080800102020201 + 00000002FFFFFF1000000003B2B2B201FFFFFF05DCDCDC018484840100000001 + 16161601E6E6E6012727270100000005FFFFFF01EAEAEA011515150100000006 + 070707017C7C7C01767676010000000115151501EAEAEA01FFFFFF0100000002 + FFFFFF1000000003FFFFFF0E3636360100000002FFFFFF100000000321212101 + F0F0F001FFFFFF03F4F4F4019B9B9B01626262010000000193939301FFFFFF01 + C8C8C8010C0C0C0100000004FFFFFF02AAAAAA01FFFFFF0100000001FFFFFF01 + 00000001FFFFFF0100000001FFFFFF0100000001FFFFFF0100000001AAAAAA01 + FFFFFF0200000002FFFFFF1000000003FFFFFF0E8888880100000002FFFFFF10 + 0000000421212101B8B8B801D1D1D101BFBFBF01939393017E7E7E0112121201 + 23232301FAFAFA01FFFFFF01FDFDFD016969690100000004FFFFFF1000000002 + FFFFFF1000000003FFFFFF0E8A8A8A0100000002FFFFFF100000000509090901 + 3F3F3F01555555013F3F3F010909090100000001A7A7A701FFFFFF03D6D6D601 + 1313130100000003FFFFFF1000000002FFFFFF1000000003FFFFFF0E8A8A8A01 + 00000002FFFFFF1000000003FFFFFF060000000132323201FEFEFE01FFFFFF04 + 7C7C7C0100000003FFFFFF1000000002FFFFFF1000000003FFFFFF0E8A8A8A01 + 00000002FFFFFF1000000003FFFFFF068C8C8C01BBBBBB01FFFFFF05E0E0E001 + 1B1B1B0100000002FFFFFF1000000002FFFFFF1000000003FFFFFF0E8A8A8A01 + 00000002FFFFFF1000000003FFFFFF068C8C8C0100000001676767018C8C8C05 + 6767670100000002FFFFFF1000000002FFFFFF1000000003FFFFFF0E8A8A8A01 + 00000002FFFFFF1000000003FFFFFF068C8C8C010000000AFFFFFF02AAAAAA01 + FFFFFF0100000001FFFFFF0100000001FFFFFF0100000001FFFFFF0100000001 + FFFFFF0100000001AAAAAA01FFFFFF0200000015FFFFFF0E8A8A8A0100000002 + FFFFFF1000000003FFFFFF068C8C8C010000000AFFFFFF01EAEAEA0115151501 + 0000000A15151501EAEAEA01FFFFFF0100000015FFFFFF0E8A8A8A0100000002 + FFFFFF1000000003FFFFFF068C8C8C010000000AFFFFFF01555555010000000C + 55555501FFFFFF010000001502020201888888018A8A8A0C8888880100000002 + FFFFFF0180808001FFFFFF0E000000048C8C8C06000000D110101001C0C0C001 + FFFFFF0BECECEC0100000003FFFFFF100000002A3D3D3D0193939301D1D1D102 + 939393013E3E3E01000000082C2C2C01E6E6E601F8F8F801FFFFFF0AFEFEFE01 + FFFFFF0100000003FFFFFF100000001908080801656565019595950194949401 + 696969010A0A0A01000000090C0C0C019E9E9E01F3F3F301FEFEFE01FFFFFF03 + F8F8F801B3B3B3010D0D0D0100000006F8F8F801FFFFFF0E00000003FFFFFF10 + 00000001FCFCFC01EDEDED10FCFCFC01000000051D1D1D01E0E0E001FFFFFF01 + D7D7D701DADADA01FFFFFF01E1E1E1012424240100000008ADADAD01F7F7F701 + FFFFFF06FBFBFB01D0D0D0010F0F0F0100000005FFFFFF0F00000003FFFFFF10 + 00000001EDEDED018C8C8C02929292028C8C8C01909090018E8E8E018C8C8C01 + 8D8D8D0190909002919191018C8C8C028F8F8F0190909001EBEBEB0100000005 + B9B9B901FFFFFF01C7C7C701E5E5E502C7C7C701FEFEFE01C3C3C30100000007 + 4D4D4D01F4F4F401FFFFFF08FAFAFA01999999010101010100000004FFFFFF0F + 00000003FFFFFF1000000001EDEDED018C8C8C01B0B0B001EBEBEB01E2E2E201 + 9F9F9F01ACACAC01B7B7B7018C8C8C0196969601BEBEBE01BABABA01DCDCDC01 + 8E8E8E018C8C8C01BBBBBB01BEBEBE01EBEBEB010000000411111101FDFDFD01 + FFFFFF06FEFEFE010D0D0D0100000006BBBBBB01FFFFFF0ADEDEDE0138383801 + 00000004FFFFFF0F00000003FFFFFF01FAFAFA01FFFFFF02989898019F9F9F01 + A4A4A401FFFFFF01929292019A9A9A019E9E9E01FFFFFF0194949401A1A1A101 + 9E9E9E01FFFFFF0100000001EDEDED018F8F8F01E2E2E20194949401A9A9A901 + C4C4C40198989801CACACA0194949401ADADAD01BBBBBB02E8E8E8019D9D9D01 + 8C8C8C01DDDDDD01C3C3C301EBEBEB01000000043E3E3E01FDFDFD01FFFFFF07 + 6F6F6F0100000006EDEDED01FFFFFF0AF7F7F7016B6B6B010101010100000003 + FFFFFF0F00000003FFFFFF01FAFAFA01FFFFFF029B9B9B01B2B2B201A2A2A201 + FFFFFF01A4A4A401A6A6A601A9A9A901FFFFFF018C8C8C01A2A2A202FFFFFF01 + 00000001EDEDED0190909001DBDBDB01AEAEAE0196969601A0A0A0018E8E8E01 + BFBFBF01ACACAC01D4D4D40198989801BBBBBB01CFCFCF01B0B0B00193939301 + DBDBDB01C0C0C001EBEBEB0100000004AFAFAF01FFFFFF08DBDBDB0120202001 + 00000005F7F7F701FFFFFF0AFBFBFB01848484010101010100000003FFFFFF0F + 00000003FFFFFF01F7F7F701FFFFFF028C8C8C03FFFFFF01909090019A9A9A01 + 9F9F9F01FFFFFF018C8C8C03FFFFFF0100000001EDEDED018C8C8C01A6A6A601 + DDDDDD01E3E3E301A0A0A0018C8C8C01A0A0A001E5E5E501BABABA018C8C8C01 + BBBBBB01BEBEBE01BBBBBB01ADADAD01C0C0C002EBEBEB0100000004E5E5E501 + FFFFFF08F3F3F3016060600100000005CECECE01FFFFFF0AE9E9E90184848401 + 0101010100000003FFFFFF0F00000003FFFFFF1000000001EDEDED018F8F8F01 + 939393018E8E8E01ADADAD01DADADA018C8C8C02E4E4E4018E8E8E018C8C8C01 + BBBBBB01B9B9B901BABABA01CECECE01A2A2A201C0C0C001EBEBEB0100000004 + E5E5E501FFFFFF08F3F3F3017E7E7E01000000057F7F7F01F9F9F901FFFFFF08 + FAFAFA01C5C5C5016B6B6B010101010100000003FFFFFF0F00000003FFFFFF01 + F5F5F501FFFFFF0294949401999999019F9F9F01FFFFFF019494940199999901 + 9F9F9F01FFFFFF0195959501999999019E9E9E01FFFFFF0100000001EDEDED01 + 9A9A9A01CCCCCC018E8E8E0192929201DBDBDB018C8C8C02E2E2E2018D8D8D01 + 8C8C8C01BBBBBB01B3B3B301BCBCBC01D6D6D6019C9C9C01C0C0C001EBEBEB01 + 00000004AFAFAF01FFFFFF08DBDBDB017E7E7E010000000507070701E6E6E601 + FFFFFF08F7F7F701CDCDCD013F3F3F010202020100000003FFFFFF0F00000003 + FFFFFF01F5F5F501FFFFFF02A3A3A301B1B1B102FFFFFF01A3A3A301B1B1B102 + FFFFFF01A3A3A301B5B5B501ACACAC01FFFFFF0100000001EDEDED018E8E8E01 + C9C9C901E2E2E201DDDDDD01BBBBBB018C8C8C02E2E2E2018D8D8D018C8C8C01 + BBBBBB01AFAFAF01BDBDBD01BFBFBF019C9C9C01C0C0C001EBEBEB0100000004 + 3A3A3A01FEFEFE01FFFFFF06FEFEFE01A6A6A60160606001000000062E2E2E01 + F1F1F101FAFAFA01FFFFFF04FAFAFA01F9F9F901FFFFFF02C9C9C90119191901 + 00000003FFFFFF0F00000003FFFFFF01F4F4F401FFFFFF029191910195959501 + 9B9B9B01FFFFFF0191919101959595019B9B9B01FFFFFF019292920195959501 + 9A9A9A01FFFFFF0100000001EDEDED018C8C8C02A0A0A001A2A2A2018E8E8E01 + 8C8C8C029E9E9E018C8C8C02969696019393930194949401929292018F8F8F01 + 97979701EBEBEB010000000589898901FEFEFE01FFFFFF04FEFEFE01C2C2C201 + 8B8B8B01202020010000000718181801C1C1C101F4F4F401FDFDFD02F5F5F501 + CECECE01CFCFCF01FFFFFF03CACACA011010100100000002FFFFFF0DF8F8F801 + BFBFBF0100000003FFFFFF1000000001EDEDED018C8C8C10EBEBEB0100000006 + 6D6D6D01DBDBDB01F7F7F701F6F6F601DBDBDB01A6A6A6018B8B8B0142424201 + 000000090101010138383801767676018D8D8D01848484016B6B6B013E3E3E01 + C5C5C501FFFFFF03B3B3B30100000002FFFFFF0DEFEFEF016868680107070701 + 00000002FFFFFF01EFEFEF01FFFFFF02949494019696960199999901FFFFFF01 + 9191910196969602FFFFFF018C8C8C019999990198989801FFFFFF0100000001 + FCFCFC01EBEBEB10FCFCFC010000000720202001F6F6F601EFEFEF017E7E7E01 + 60606001202020010000000C010101040000000110101001C8C8C801FFFFFF01 + FDFDFD01AFAFAF0100000002E8E8E801FFFFFF0BFCFCFC019F9F9F012A2A2A01 + 00000003FFFFFF01F1F1F101FFFFFF02A6A6A601A4A4A401A5A5A501FFFFFF01 + 91919101A5A5A501A2A2A201FFFFFF018F8F8F01A6A6A601C3C3C301FFFFFF01 + 0000001B7878780170707001000000150B0B0B01AAAAAA01A8A8A80179797901 + 00000002161616014646460C3131310100000004FFFFFF0184848401FFFFFF0E + 000000A3FFFFFF3600000024FFFFFF3600000024FFFFFF360000000807070702 + 000000100707070200000008FFFFFF360000000666666601C9C9C901DCDCDC02 + C9C9C901666666010000000C66666601C9C9C901DCDCDC02C9C9C90166666601 + 00000006FFFFFF3600000005A6A6A601F2F2F201FFFFFF04F7F7F701B1B1B101 + 0000000AA6A6A601F2F2F201FFFFFF04F7F7F701B1B1B10100000005FFFFFF36 + 0000000466666601F2F2F201FFFFFF06F9F9F9018E8E8E010000000866666601 + F2F2F201FFFFFF06F9F9F9018E8E8E0100000004FFFFFF3600000004C9C9C901 + FFFFFF08E6E6E6012020200100000007C9C9C901FFFFFF08E6E6E60120202001 + 00000003FFFFFF360000000307070701DCDCDC01FFFFFF08EFEFEF0164646401 + 0000000607070701DCDCDC01FFFFFF08EFEFEF016464640100000003FFFFFF36 + 0000000307070701DCDCDC01FFFFFF08EFEFEF01828282010000000607070701 + DCDCDC01FFFFFF08EFEFEF018282820100000003FFFFFF3600000004C9C9C901 + FFFFFF08E7E7E7017E7E7E0100000007C9C9C901FFFFFF08E7E7E7017E7E7E01 + 00000003FFFFFF360000000466666601F7F7F701FFFFFF06F9F9F901BABABA01 + 606060010000000766666601F7F7F701FFFFFF06F9F9F901BABABA0160606001 + 00000003FFFFFF3600000005B1B1B101F9F9F901FFFFFF04F9F9F901D7D7D701 + 8B8B8B012020200100000008B1B1B101F9F9F901FFFFFF04F9F9F901D7D7D701 + 8B8B8B012020200100000003FFFFFF36000000068E8E8E01E6E6E601EFEFEF02 + E7E7E701BABABA018B8B8B01424242010000000A8E8E8E01E6E6E601EFEFEF02 + E7E7E701BABABA018B8B8B014242420100000004FFFFFF360000000720202001 + 64646401828282017E7E7E0160606001202020010000000C2020200164646401 + 828282017E7E7E01606060012020200100000005FFFFFF3600000024FFFFFF36 + 00000024FFFFFF3600000024FFFFFF36 + } + end + object dummyimagelist: timagelist + width = 24 + left = 120 + top = 64 + end + object viewmenu: tframecomp + left = 208 + top = 96 + end + object runprocmon: tprocessmonitor + onchilddied = runprocdied + left = 192 + top = 32 + end + object statoptions: trttistat + ongetobjects = getstatobjs + top = 96 + end + object projectfiledia: tfiledialog + statfile = projectstatfile + controller.filterlist.data = ( + ( + 'Project files' + '*.prj' + ) + ( + 'All Files' + '*' + ) + ) + controller.defaultext = 'prj' + controller.captionopen = 'Open Project' + controller.captionsave = 'Save Project' + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate, oe1_checkvalueafterstatread] + left = 256 + top = 1 + end + object targetpipe: tpipereadercomp + oninputavailable = targetpipeinput + left = 312 + top = 32 + end + object c: tstringcontainer + strings.data = ( + 'Unresolved references in' + 'to' + 'Do you wish to search the formfile?' + 'WARNING' + 'Formfile for' + 'Formfiles' + 'Recursive form hierarchy for "' + 'ERROR' + 'Classtype' + 'not found.' + 'Project' + 'is modified. Save?' + 'Confirmation' + 'Unable to open file "' + '*** Running ***' + 'Downloading' + 'Downloaded' + 'Start gdb server command "' + '" running.' + 'Start gdb Server' + 'gdb server start error' + 'gdb server start canceled.' + 'Can not run start gdb command.' + 'Uploadcommand "' + 'Download ***ERROR***' + 'Download finished.' + 'Download canceled.' + 'File "' + '" not found.' + '" exists.' + 'New' + 'Select ancestor' + 'New form' + 'Pascal Files' + 'new' + 'Can not load Project "' + 'Select project template' + 'Project files' + 'All files' + 'Select program file' + 'Pascal program files' + 'C program files' + 'New Project' + 'Can not start process' + 'Process' + 'running' + 'Process terminated. Exitcode: ' + 'Process terminated normally.' + 'Make ***ERROR***' + 'Make OK.' + 'Source has changed, do you wish to remake project?' + 'Load Window Layout' + 'Docking Area' + ) + left = 256 + top = 64 + end + object openform: tfiledialog + statfile = projectstatfile + controller.filterlist.data = ( + ( + 'Form Files' + '*.mfm' + ) + ) + controller.defaultext = 'mfm' + controller.options = [fdo_checkexist] + controller.captionopen = 'Open Form File' + left = 120 + top = 1 + end + object formbg: tbitmapcomp + bitmap.origformat = 'png' + bitmap.alignment = [al_tiled] + bitmap.image = { + 000000000000000010000000100000007C000000000000000000000000000000 + 0000000000000000000000000000000000000000B8B8B808C7C7C708B8B8B808 + C7C7C708B8B8B808C7C7C708B8B8B808C7C7C708B8B8B808C7C7C708B8B8B808 + C7C7C708B8B8B808C7C7C708B8B8B808C7C7C710B8B8B808C7C7C708B8B8B808 + C7C7C708B8B8B808C7C7C708B8B8B808C7C7C708B8B8B808C7C7C708B8B8B808 + C7C7C708B8B8B808C7C7C708B8B8B808 + } + left = 312 + top = 64 + end +end diff --git a/mseide-msegui/apps/ide/main.pas b/mseide-msegui/apps/ide/main.pas new file mode 100644 index 0000000..ddcc8f9 --- /dev/null +++ b/mseide-msegui/apps/ide/main.pas @@ -0,0 +1,3125 @@ +{ MSEide Copyright (c) 1999-2017 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit main; +{$ifdef linux}{$define unix}{$endif} +{$ifdef FPC} + {$mode objfpc}{$h+}{$goto on} +{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} +{$ifdef mse_no_ifi} + {$define mse_no_db} +{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + mseforms,msesimplewidgets,mseguiglob,msegui,msegdbutils,mseactions, + msedispwidgets,msedataedits,msestat,msestatfile,msemenus,msebitmap,msetoolbar, + msegrids,msefiledialog,msetypes,sourcepage,msetabs,msedesignintf,msedesigner, + classes,mclasses,mseclasses,msegraphutils,typinfo,msedock,sysutils,msesysenv, + msemacros,msestrings,msepostscriptprinter,msegraphics,mseglob,msestream, + mseprocmonitorcomp,msesystypes,mserttistat,msedatanodes,mseedit,mseifiglob, + mselistbrowser,projecttreeform,msepipestream,msestringcontainer,msesys, + msewidgets; +const + versiontext = '4.6.3'; + idecaption = 'MSEide'; + statname = 'mseide'; + +type + stringconsts = ( + unresreferences, //0 Unresolved references in + str_to, //1 to + wishsearch, //2 Do you wish to search the formfile? + warning, //3 WARNING + formfile, //4 Formfile for + formfiles, //5 Formfiles + recursive, //6 Recursive form hierarchy for " + error, //7 ERROR + str_classtype, //8 Classtype + notfound, //9 not found. + project, //10 Project + ismodified, //11 is modified. Save? + confirmation, //12 Confirmation + unableopen, //13 Unable to open file " + running, //14 *** Running *** + str_downloading, //15 Downloading + str_downloaded, //16 Downloaded + startgdbservercommand, //17 Start gdb server command " + running2, //18 " running. + startgdbserver, //19 Start gdb Server + gdbserverstarterror,//20 gdb server start error + gdbservercanceled, //21 gdb server start canceled. + cannotrunstartgdb, //22 Can not run start gdb command. + str_uploadcommand, //23 Uploadcommand " + downloaderror, //24 Download ***ERROR*** + downloadfinished, //25 Download finished. + downloadcanceled, //26 Download canceled. + str_file, //27 File " + notfound2, //28 " not found. + exists, //29 " exists. + str_new, //30 New + selectancestor, //31 Select ancestor + newform, //32 New form + pascalfiles, //33 Pascal Files + new2, //34 new + cannotloadproj, //35 Can not load Project " + selecttemplate, //36 Select project template + projectfiles, //37 Project files + str_allfiles, //38 All files + selectprogramfile, //39 Select program file + pascalprogfiles, //40 Pascal program files + cfiles, //41 C program files + str_newproject, //42 New Project + cannotstartprocess, //43 Can not start process + process, //44 Process + running3, //45 running. + processterminated, //46 Process terminated + proctermnormally, //47 Process terminated normally. + makeerror, //48 Make ***ERROR*** + makeok, //49 Make OK. + str_sourcechanged, //50 Source has changed, do you wish to remake project? + str_loadwindowlayout, //51 Load Window Layout + dockingarea //52 Docking Area + ); + + filekindty = (fk_none,fk_source,fk_unit); + messagetextkindty = (mtk_info,mtk_running,mtk_finished,mtk_error,mtk_signal); + + startcommandty = (sc_none,sc_step,sc_continue); +// formkindty = (fok_main,fok_simple,fok_dock,fok_data,fok_subform, +// fok_report,fok_script,fok_inherited); + + tmainfo = class(tdockform,idesignnotification) + gdb: tgdbmi; + filedisp: tstringdisp; + linedisp: tintegerdisp; + projectstatfile: tstatfile; + reasondisp: tintegerdisp; + expr: tstringedit; + exprdisp: tstringdisp; + symboltype: tstringedit; + symboltypedisp: tstringdisp; + mainstatfile: tstatfile; + mainmenu1: tmainmenu; + statdisp: tstringdisp; + errordisp: tstringdisp; + basedock: tdockpanel; + + openfile: tfiledialog; + + dummyimagelist: timagelist; + vievmenuicons: timagelist; + + viewmenu: tframecomp; + runprocmon: tprocessmonitor; + statoptions: trttistat; + projectfiledia: tfiledialog; + targetpipe: tpipereadercomp; + c: tstringcontainer; + openform: tfiledialog; + formbg: tbitmapcomp; + procedure newfileonexecute(const sender: tobject); + procedure newformonexecute(const sender: TObject); + + procedure mainfooncreate(const sender: tobject); + procedure mainfoondestroy(const sender: tobject); + procedure mainstatfileonupdatestat(const sender: tobject; const filer: tstatfiler); + procedure mainfoonterminate(var terminate: Boolean); + procedure mainonloaded(const sender: TObject); + + procedure mainmenuonupdate(const sender: tcustommenu); + procedure onscale(const sender: TObject); + procedure parametersonexecute(const sender: TObject); + procedure buildactonexecute(const sender: TObject); + procedure saveprojectasonexecute(const sender: tobject); + procedure newprojectonexecute(const sender: TObject); + procedure closeprojectactonexecute(const sender: TObject); + procedure exitonexecute(const sender: tobject); + procedure newpanelonexecute(const sender: TObject); + + procedure viewassembleronexecute(const sender: TObject); + procedure viewcpuonexecute(const sender: TObject); + procedure viewmessagesonexecute(const sender: TObject); + procedure viewsourceonexecute(const sender: tobject); + procedure viewbreakpointsonexecute(const sender: tobject); + procedure viewwatchesonexecute(const sender: tobject); + procedure viewstackonexecute(const sender: tobject); + procedure viewobjectinspectoronexecute(const sender: TObject); + procedure toggleobjectinspectoronexecute(const sender: tobject); + procedure viewcomponentpaletteonexecute(const sender: TObject); + procedure viewcomponentstoreonexecute(const sender: TObject); + procedure viewdebuggertoolbaronexecute(const sender: TObject); + procedure viewwatchpointsonexecute(const sender: TObject); + procedure viewthreadsonexecute(const sender: TObject); + procedure viewconsoleonexecute(const sender: TObject); + procedure viewfindresults(const sender: TObject); + procedure aboutonexecute(const sender: TObject); + procedure configureexecute(const sender: TObject); + + //debugger + procedure restartgdbonexecute(const sender: tobject); + procedure runexec(const sender: tobject); + procedure gdbonevent(const sender: tgdbmi; var eventkind: gdbeventkindty; + const values: resultinfoarty; const stopinfo: stopinfoty); + procedure expronsetvalue(const sender: tobject; var avalue: msestring; + var accept: boolean); + procedure symboltypeonsetvalue(const sender: tobject; var avalue: msestring; + var accept: boolean); + procedure openprojectcopyexecute(const sender: TObject); + procedure saveprojectcopyexecute(const sender: TObject); + procedure newprojectfromprogramexe(const sender: TObject); + procedure newemptyprojectexe(const sender: TObject); + procedure viewmemoryonexecute(const sender: TObject); + procedure runprocdied(const sender: TObject; const prochandle: prochandlety; + const execresult: Integer; const data: Pointer); + procedure statbefread(const sender: TObject); + procedure viewsymbolsonexecute(const sender: TObject); + procedure loadwindowlayoutexe(const sender: TObject); + procedure getstatobjs(const sender: TObject; var aobjects: objectinfoarty); + procedure targetpipeinput(const sender: tpipereader); + procedure mainstatbeforewriteexe(const sender: TObject); + procedure statafterread(const sender: TObject); + procedure basedockpaintexe(const sender: twidget; const acanvas: tcanvas); + private + fstartcommand: startcommandty; + fnoremakecheck: boolean; + fcurrent: boolean; + flastform: tcustommseform; + flastdesignform: tcustommseform; + fexecstamp: integer; + fprojectname: filenamety; + fcheckmodulelevel: integer; + fgdbserverprocid: integer; + fgdbserverexitcode: integer; + fgdbservertimeout: longword; + ftargetfilemodified: boolean; + frunningprocess: prochandlety; + flayoutloading: boolean; + fstopinfo: stopinfoty; + fgdbdownloaded: boolean; + procedure dorun; + function runtarget: boolean; //true if run possible + procedure newproject(const fromprogram,empty: boolean); + procedure doshowform(const sender: tobject); + procedure setprojectname(aname: filenamety); + //not const because of not refcounted widestrings + procedure dofindmodulebyname(const amodule: pmoduleinfoty; const aname: string; + var action: modalresultty); + procedure dofindmodulebytype(const atypename: string); + + //idesignnotification + procedure ItemDeleted(const ADesigner: IDesigner; + const amodule: tmsecomponent; const AItem: tcomponent); + procedure ItemInserted(const ADesigner: IDesigner; + const amodule: tmsecomponent; const AItem: tcomponent); + procedure ItemsModified(const ADesigner: IDesigner; const AItem: tobject); + procedure componentnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const aitem: tcomponent; + const newname: string); + procedure moduleclassnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); + procedure instancevarnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); + procedure SelectionChanged(const ADesigner: IDesigner; + const ASelection: IDesignerSelections); + procedure moduleactivated(const adesigner: idesigner; const amodule: tmsecomponent); + procedure moduledeactivated(const adesigner: idesigner; const amodule: tmsecomponent); + procedure moduledestroyed(const adesigner: idesigner; const amodule: tmsecomponent); + procedure methodcreated(const adesigner: idesigner; + const amodule: tmsecomponent; + const aname: string; const atype: ptypeinfo); + procedure methodnamechanged(const adesigner: idesigner; + const amodule: tmsecomponent; + const newname,oldname: string; const atypeinfo: ptypeinfo); + procedure showobjecttext(const adesigner: idesigner; + const afilename: filenamety; const backupcreated: boolean); + procedure closeobjecttext(const adesigner: idesigner; + const afilename: filenamety; var cancel: boolean); + procedure beforefilesave(const adesigner: idesigner; + const afilename: filenamety); + procedure beforemake(const adesigner: idesigner; const maketag: integer; + var abort: boolean); + procedure aftermake(const adesigner: idesigner; const exitcode: integer); + + function checksave: modalresultty; + procedure unloadexec; + procedure cleardebugdisp; + procedure resetdebugdisp; //called before running debuggee + procedure createprogramfile(const aname: filenamety); + function copynewfile(const aname,newname: filenamety; + const autoincrement: boolean; + const canoverwrite: boolean; + const macronames: array of msestring; + const macrovalues: array of msestring): boolean; + //true if ok + procedure createform(const aname: filenamety; const namebase: string; + const formsuffix: string; + const ancestor: string); + procedure removemodulemenuitem(const amodule: pmoduleinfoty); + procedure uploadexe(const sender: tguiapplication; var again: boolean); + procedure uploadcancel(const sender: tobject); + procedure gdbserverexe(const sender: tguiapplication; var again: boolean); + function terminategdbserver(const force: boolean): boolean; + procedure gdbservercancel(const sender: tobject); + procedure updatetargetenvironment; + function needsdownload: boolean; + function candebug: boolean; //run command empty or process attached + procedure startconsole(); + public + factivedesignmodule: pmoduleinfoty; + fprojectloaded: boolean; + errorformfilename: filenamety; + constructor create(aowner: tcomponent); override; + destructor destroy; override; + + procedure designformactivated(const sender: tcustommseform); + procedure startgdb(const killserver: boolean); + function checkgdberror(aresult: gdbresultty): boolean; + function startgdbconnection(const attach: boolean): boolean; + function loadexec(isattach: boolean; + const forcedownload: boolean): boolean; //true if ok + procedure setstattext(const atext: msestring; const akind: messagetextkindty = mtk_info); + procedure refreshstopinfo(const astopinfo: stopinfoty); + procedure updatemodifiedforms; + function checkremake(startcommand: startcommandty): boolean; + //true if running possible + procedure resetstartcommand; + procedure killtarget; + procedure domake(atag: integer); + procedure targetfilemodified; + function checksavecancel(const aresult: modalresultty): modalresultty; + function closeall(const nosave: boolean): boolean; //false in cancel + function closemodule(const amodule: pmoduleinfoty; + const achecksave: boolean; + nocheckclose: boolean = false): boolean; + function openproject(const aname: filenamety; + const ascopy: boolean = false): boolean; + procedure saveproject(aname: filenamety; const ascopy: boolean = false); + procedure savewindowlayout(const astream: ttextstream); + procedure savewindowlayout(const awriter: tstatwriter); + procedure loadwindowlayout(const astream: ttextstream); + procedure loadwindowlayout(const areader: tstatreader); + + procedure sourcechanged(const sender: tsourcepage); + function opensource(const filekind: filekindty; const addtoproject: boolean; + const aactivate: boolean = true; + const currentnode: tprojectnode = nil): boolean; + //true if filedialog not canceled + function openformfile(const filename: filenamety; + const ashow,aactivate,showsource,createmenu, + skipexisting: boolean): pmoduleinfoty; + procedure createmodulemenuitem(const amodule: pmoduleinfoty); + function formmenuitemstart: integer; + procedure loadformbysource(const sourcefilename: filenamety); + procedure loadsourcebyform(const formfilename: filenamety; + const aactivate: boolean = false); + procedure checkbluedots; + procedure updatesigsettings; + procedure runtool(const sender: tobject); + + procedure downloaded; + procedure programfinished; + procedure showfirsterror; + procedure stackframechanged(const frameno: integer); + procedure refreshframe; + procedure toggleformunit; + property projectname: filenamety read fprojectname; + property lastform: tcustommseform read flastform; + property execstamp: integer read fexecstamp; + property stopinfo: stopinfoty read fstopinfo; + end; + +var + mainfo: tmainfo; + +procedure handleerror(const e: exception; const text: string); +implementation +uses + regwidgets,regeditwidgets,regdialogs,regkernel,regprinter,msearrayutils, + toolhandlermodule, +{$ifndef mse_no_math} + regmath,regmm, +{$endif} +{$ifndef mse_no_db} + regdb,regreport, +{$endif} +{$ifdef mse_with_ifi} + regifi,{$ifndef mse_no_ifirem}regifirem,{$endif} +{$endif} +{$ifdef mse_with_pascalscript} + regpascalscript, +{$endif} +{$ifdef mse_with_zeoslib} + regzeoslib, +{$endif} + regdesignutils,regsysutils,regcrypto,regserialcomm,regexperimental, +{$ifndef mse_no_deprecated} + regdeprecated, +{$endif} + {$ifdef morecomponents} + {$include regcomponents.inc} + {$endif} + + mseparser,msesysintf,memoryform,msedrawtext,mseformatstr, + main_mfm,sourceform,watchform,breakpointsform,stackform, + guitemplates,projectoptionsform,make,msepropertyeditors, + skeletons,msedatamodules,mseact, + mseformdatatools,mseshapes,msefileutils,mseeditglob, + findinfileform,formdesigner,sourceupdate,actionsmodule,programparametersform, + objectinspector,msesysutils,cpuform,disassform, + panelform,watchpointsform,threadsform,targetconsole, + debuggerform,componentpaletteform,componentstore, + messageform,msesettings,mseintegerenter,symbolform + {$ifdef unix},mselibc {$endif}, //SIGRT* + mseprocutils + {$ifdef mse_dumpunitgroups},dumpunitgroups{$endif}; + +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +procedure handleerror(const e: exception; const text: string); +begin + if text <> '' then begin + writestderr(text+' '+e.message,true); + end + else begin + writestderr(e.message,true); + end; +end; + +{ tmainfo } + +constructor tmainfo.create(aowner: tcomponent); +begin + frunningprocess:= invalidprochandle; + fgdbserverprocid:= invalidprochandle; + inherited create(aowner); +end; + +destructor tmainfo.destroy; +begin + terminategdbserver(true); + inherited; +end; + +//common + +procedure tmainfo.mainfooncreate(const sender: tobject); +begin + designer.ongetmodulenamefile:= {$ifdef FPC}@{$endif}dofindmodulebyname; + designer.ongetmoduletypefile:= {$ifdef FPC}@{$endif}dofindmodulebytype; + + designer.objformat:= of_fp; + componentpalettefo.updatecomponentpalette(true); + designnotifications.Registernotification(idesignnotification(self)); + watchfo.gdb:= gdb; + breakpointsfo.gdb:= gdb; + watchpointsfo.gdb:= gdb; + stackfo.gdb:= gdb; + threadsfo.gdb:= gdb; + disassfo.gdb:= gdb; + initprojectoptions; + sourceupdate.init(designer); +{$ifndef mse_with_pascalscript} + mainmenu1.menu.deleteitembynames(['file','new','form','pascform']); +{$endif} +end; + +procedure tmainfo.mainfoondestroy(const sender: tobject); +begin + designnotifications.unRegisternotification(idesignnotification(self)); + abortmake; + abortdownload; + sourceupdate.deinit(designer); +end; + +procedure tmainfo.dofindmodulebyname(const amodule: pmoduleinfoty; + const aname: string; var action: modalresultty); +var + wstr2: msestring; + + function dofind(const modulenames: array of msestring; + const modulefilenames: array of filenamety): boolean; + var + int1: integer; + wstr1: msestring; + po1: pmoduleinfoty; + begin + result:= false; + for int1:= 0 to high(modulenames) do begin + if modulenames[int1] = wstr2 then begin + if int1 <= high(modulefilenames) then begin + wstr1:= modulefilenames[int1]; + if relocatepath(projectoptions.projectdir,'',wstr1,[pro_preferenew]) or + findfile(modulefilenames[int1], + projectoptions.d.texp.sourcedirs,wstr1) or + findfile(filename(modulefilenames[int1]), + projectoptions.d.texp.sourcedirs,wstr1) then begin + try + po1:= openformfile(wstr1,false,false,false,false,false); + result:= (po1 <> nil) and + (msestring(struppercase(po1^.instancevarname)) = wstr2); + except + application.handleexception; + result:= false; + end; + end; + end; + break; + end; + end; + end; + +var + bo1: boolean; + int1: integer; + mstr1: filenamety; + +begin + wstr2:= msestring(struppercase(aname)); + int1:= findchar(wstr2,'.'); + if int1 > 0 then begin + setlength(wstr2,int1-1); //main name only + end; + with projectoptions do begin + bo1:= dofind(s.modulenames,s.modulefiles); + end; + if not bo1 and + projecttree.units.findformbyname(ansistring(wstr2),mstr1) then begin + bo1:= dofind([wstr2],[mstr1]); + end; + if bo1 then begin + action:= mr_ok; + end + else begin + action:= showmessage(c[ord(unresreferences)]+' '+ + msestring(amodule^.moduleclassname)+' '+ + c[ord(str_to)]+' ' + + msestring(aname) + '.'+lineend+ + ' '+c[ord(wishsearch)],c[ord(warning)], + [mr_ok,mr_cancel],mr_ok); + case action of + mr_ok: begin + wstr2:= ''; +// openform.controller.filename:= ''; +// openform.controller.captionopen:= c[ord(formfile)]+' '+ aname; + if openform.controller.execute(wstr2,fdk_open, + c[ord(formfile)]+' '+ msestring(aname)) then begin +// action:= filedialog(wstr2,[fdo_checkexist],c[ord(formfile)]+' '+ aname, +// [c[ord(formfiles)]],['*.mfm'],'',nil,nil,nil,[fa_all],[fa_hidden]); +// //defaultvalues don't work on kylix +// if action = mr_ok then begin +// openformfile(openform.controller.filename,false,false,true,true,false); + openformfile(wstr2,false,false,true,true,false); + end; + end; + end; + end; +end; + +procedure tmainfo.dofindmodulebytype(const atypename: string); +var + wstr2: msestring; + int1: integer; + po1: pmoduleinfoty; + + procedure checkmodule(fname: filenamety); + var + wstr1: filenamety; + begin + with projectoptions do begin + if findfile(fname,d.texp.sourcedirs,wstr1) or + findfile(fname,d.texp.sourcedirs,wstr1) then begin + try + po1:= openformfile(wstr1,false,false,false,false,false); + except + on e: eabort do begin + raise; + end + else begin + po1:= nil; + application.handleexception; + end; + end; + end; + end; + end; + +var +// ar1: msestringarty; + mstr1: filenamety; + +begin +// ar1:= nil; //compilerwarning + if fcheckmodulelevel >= 16 then begin + showmessage(c[ord(recursive)]+msestring(atypename)+'"',c[ord(error)]); + sysutils.abort; + end; + inc(fcheckmodulelevel); + try + with projectoptions do begin + po1:= nil; + wstr2:= msestring(struppercase(atypename)); + for int1:= 0 to high(s.moduletypes) do begin + if s.moduletypes[int1] = wstr2 then begin + if int1 <= high(s.modulefiles) then begin + checkmodule(s.modulefiles[int1]); + end; + break; + end; + end; + end; + if po1 = nil then begin + if projecttree.units.findformbyclass(ansistring(wstr2),mstr1) then begin + checkmodule(mstr1); + end; + { + ar1:= projecttree.units.moduleclassnames; + for int1:= 0 to high(ar1) do begin + if ar1[int1] = wstr2 then begin + checkmodule(projecttree.units.modulefilenames[int1]); + break; + end; + end; + } + end; + if (po1 = nil) or + (stringicomp(po1^.moduleclassname,atypename) <> 0) then begin + if showmessage(c[ord(str_classtype)]+' '+msestring(atypename)+ + ' '+c[ord(notfound)]+lineend+ + ' '+c[ord(wishsearch)],c[ord(warning)], + [mr_yes,mr_cancel]) = mr_yes then begin + wstr2:= ''; +// if filedialog(wstr2,[fdo_checkexist],c[ord(formfile)]+' '+ +// msestring(atypename), +// [c[ord(formfiles)]],['*.mfm']) = mr_ok then begin + if openform.controller.execute(wstr2,fdk_open,c[ord(formfile)]+' '+ + msestring(atypename),[fdo_checkexist]) then begin + openformfile(wstr2,false,false,false,false,false); + end; + end; + end; + finally + dec(fcheckmodulelevel); + end; +end; + +//editor +//formdesigner + + +procedure Tmainfo.doshowform(const sender: tobject); +begin + with tmenuitem(sender) do begin + designer.showformdesigner(pmoduleinfoty(tagpo)); + end; +end; + +procedure tmainfo.toggleobjectinspectoronexecute(const sender: tobject); +begin + if (flastform = objectinspectorfo) then begin + if flastdesignform <> nil then begin + flastdesignform.activate(true); + end; + end + else begin + objectinspectorfo.activate(true); + end; +end; + +procedure tmainfo.viewobjectinspectoronexecute(const sender: TObject); +begin + objectinspectorfo.activate(true); +end; + + //idesignnotification + +procedure Tmainfo.ItemDeleted(const ADesigner: IDesigner; + const amodule: tmsecomponent; const AItem: tcomponent); +begin + +end; + +procedure Tmainfo.ItemInserted(const ADesigner: IDesigner; + const amodule: tmsecomponent; const AItem: tcomponent); +begin + componentpalettefo.resetselected; +end; + +procedure tmainfo.moduleactivated(const adesigner: idesigner; const amodule: tmsecomponent); +begin + factivedesignmodule:= designer.actmodulepo; + setlinkedvar(factivedesignmodule^.designform,tmsecomponent(flastdesignform)); +end; + +procedure tmainfo.moduledeactivated(const adesigner: idesigner; const amodule: tmsecomponent); +begin +// factivedesignmodule:= nil; +end; +{ +procedure tmainfo.sourceformactivated; +begin + factivedesignmodule:= nil; +end; +} +function tmainfo.checksave: modalresultty; +var + str1: filenamety; +begin + result:= sourcefo.saveall(false); + if result <> mr_cancel then begin + result:= designer.saveall(result = mr_all,true); + if result <> mr_cancel then begin + result:= componentstorefo.saveall(false); + if result <> mr_cancel then begin + with projectoptions,s,texp do begin + if modified and not savechecked then begin + result:= showmessage(c[ord(project)]+' '+fprojectname+' '+ + c[ord(ismodified)],c[ord(confirmation)], + [mr_yes,mr_no,mr_cancel],mr_yes); + if result = mr_yes then begin + if projectfilename = '' then begin + result:= projectfiledialog(str1,true); + if result <> mr_ok then begin + result:= mr_cancel; + end; + end + else begin + str1:= projectfilename; + end; + if result <> mr_cancel then begin + saveproject(str1); + end; + end + else begin + if result <> mr_no then begin + result:= mr_cancel; + end; + end; + savechecked:= true; + end + else begin + saveproject(projectfilename); + end; + end; + end; + end; + end; + + checksavecancel(result); +end; + +procedure tmainfo.updatemodifiedforms(); +var + int1: integer; +begin + with mainmenu1.menu.itembyname('view') do begin + for int1:= itembyname('formmenuitemstart').index+1 to count - 1 do begin + with items[int1] do begin + with pmoduleinfoty(tagpo)^ do begin + if modified then begin + caption:= '*'+msefileutils.filename(filename); + end + else begin + caption:= msefileutils.filename(filename); + end; + if (designform is tformdesignerfo) and designform.visible then begin + tformdesignerfo(designform).updatecaption; + end; + end; + end; + end; + end; +end; + +procedure Tmainfo.ItemsModified(const ADesigner: IDesigner; const AItem: tobject); +begin + updatemodifiedforms; + sourcechanged(nil); +end; + +procedure tmainfo.componentnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const aitem: tcomponent; + const newname: string); +begin + //dummy +end; + +procedure tmainfo.moduleclassnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); +begin + //dummy +end; + +procedure tmainfo.instancevarnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); +begin +end; + +procedure Tmainfo.SelectionChanged(const ADesigner: IDesigner; + const ASelection: IDesignerSelections); +begin + if (aselection.Count > 0) and (factivedesignmodule <> nil) then begin +// objectinspectorfo.bringtofront; + objectinspectorfo.show; + if not objectinspectorfo.active then begin + objectinspectorfo.window.stackunder(factivedesignmodule^.designform.window); + end; + end; +end; + +//debugger + +procedure tmainfo.expronsetvalue(const sender: tobject; + var avalue: msestring; var accept: boolean); +var + expres: string; +begin + gdb.evaluateexpression(ansistring(avalue),expres); + exprdisp.value:= msestring(expres); +end; + +procedure tmainfo.refreshframe; +var + pc: qword; +begin + cpufo.refresh; + if gdb.getpc(pc) = gdb_ok then begin + disassfo.refresh(pc); + end + else begin + disassfo.clear; + end; + watchfo.refresh; +end; + +procedure tmainfo.stackframechanged(const frameno: integer); +begin + if gdb.cancommand then begin + gdb.selectstackframe(frameno); + refreshframe; + end; +end; + +procedure tmainfo.toggleformunit; +var + po1: pmoduleinfoty; + page1: tsourcepage; + str1,str2: filenamety; +begin + if sourcefo.checkancestor(flastform) then begin + page1:= sourcefo.activepage; + if (page1 <> nil) then begin + str2:= fileext(page1.filepath); + if str2 = pasfileext then begin + str1:= replacefileext(page1.filepath,formfileext); + po1:= designer.modules.findmodule(str1); + if po1 <> nil then begin + createmodulemenuitem(po1); + po1^.designform.activate(true); + page1:= nil; + end + else begin + page1:= sourcefo.findsourcepage(str1); + if page1 = nil then begin //mfm not loaded in editor + po1:= designer.loadformfile(str1,false); + if po1 <> nil then begin + createmodulemenuitem(po1); + po1^.designform.activate(true); + end; + end; + end; + end + else begin + if str2 = formfileext then begin + page1:= sourcefo.findsourcepage( + replacefileext(page1.filepath,pasfileext)); + end; + end; + if page1 <> nil then begin + page1.activate; + end; + end; + end + else begin + po1:= designer.actmodulepo; + if po1 <> nil then begin + str1:= replacefileext(po1^.filename,pasfileext); + if sourcefo.openfile(str1,true) = nil then begin + raise exception.create(ansistring(c[ord(unableopen)]+str1+'".')); + end; + end + else begin + if designer.modules.count > 0 then begin + designer.modules[0]^.designform.activate(true); + end; + end; + end; +end; + +procedure tmainfo.setstattext(const atext: msestring; + const akind: messagetextkindty = mtk_info); +begin + with statdisp do begin + value:= removelinebreaks(atext); + case akind of + mtk_finished: color:= cl_ltgreen; + mtk_error: color:= cl_ltyellow; + mtk_signal: color:= cl_ltred; + else color:= cl_parent; + end; + case akind of + mtk_running: font.color:= cl_red; + else font.color:= cl_black; + end; + end; +end; + +procedure tmainfo.cleardebugdisp; +begin + resetdebugdisp; + stackfo.clear; + threadsfo.clear; + disassfo.clear; +end; + +procedure tmainfo.resetdebugdisp; +begin + setstattext('',mtk_info); + if sourcefo.gdbpage <> nil then begin + sourcefo.gdbpage.hidehint; + end; + sourcefo.resetactiverow; + disassfo.resetactiverow; +end; + +procedure tmainfo.programfinished; +begin + sourcefo.resetactiverow; + watchpointsfo.clear; + disassfo.clear; + watchfo.clear; + stackfo.clear; + threadsfo.clear; +end; + +procedure tmainfo.refreshstopinfo(const astopinfo: stopinfoty); +begin + fstopinfo:= astopinfo; + with astopinfo do begin + case reason of + sr_signal_received: begin + setstattext(msestring(messagetext),mtk_signal); + end; + sr_error: begin + setstattext(msestring(messagetext),mtk_error); + end; + sr_exception: begin + end; + else begin + setstattext(msestring(messagetext),mtk_finished); + end; + end; + watchfo.refresh; + breakpointsfo.refresh; + stackfo.refresh; + threadsfo.refresh; + threadsfo.stopinfo:= astopinfo; + cpufo.refresh; + disassfo.refresh(addr); + if (reason = sr_exception) then begin + setstattext(msestring(messagetext)+' '+stackfo.infotext(1),mtk_signal); + if not stackfo.showsource(1) then begin + sourcefo.locate(stopinfo); + end; + end + else begin + sourcefo.locate(stopinfo); + end; + if reason in [sr_exited,sr_exited_normally,sr_detached] then begin + programfinished; + end; + if projectoptions.d.activateonbreak then begin + application.activate(); + { + if application.activewindow <> nil then begin + application.activewindow.activate; + end + else begin + if flastform <> nil then begin + flastform.activate(); + end + else begin + sourcefo.activate(); + end; + end; + } + end; + if projectoptions.d.raiseonbreak then begin + application.packwindowzorder(); + end; + end; +end; + +procedure tmainfo.gdbonevent(const sender: tgdbmi; + var eventkind: gdbeventkindty; const values: resultinfoarty; + const stopinfo: stopinfoty); +begin + cpufo.stoptime.value:= gdb.stoptime; + case eventkind of + gek_stopped: begin + with stopinfo do begin + if (reason = sr_startup) and + (fstartcommand = sc_continue) then begin + gdb.continue; + end + else begin + if breakpointsfo.checkbreakpointcontinue(stopinfo) then begin + gdb.continue; + end + else begin + if reason = sr_detached then begin + cleardebugdisp; + setstattext(msestring(stopinfo.messagetext),mtk_finished); + programfinished; + end + else begin + gdb.debugbegin; + refreshstopinfo(stopinfo); + end; + end; + end; + end; + fstartcommand:= sc_none; + end; + gek_running: begin + resetdebugdisp; + setstattext(c[ord(running)],mtk_running); + end; + gek_error,gek_writeerror,gek_gdbdied: begin + setstattext('GDB: '+msestring(stopinfo.messagetext),mtk_error); + end; + gek_targetoutput: begin + targetconsolefo.addtext(values[0].value); + end; + gek_download: begin + with stopinfo do begin + if sectionsize > 0 then begin + setstattext(c[ord(str_downloading)]+' '+msestring(section)+' '+ + inttostrmse(round(sectionsent/sectionsize*100))+'%',mtk_running); + end; + end; + end; + gek_done: begin + if sender.downloaded then begin + downloaded; + setstattext(c[ord(str_downloaded)]+' '+formatfloatmse( + stopinfo.totalsent/1024,'0.00,')+'kB',mtk_finished); +// sender.abort; + end; + end; + gek_loaded: begin + symbolfo.updatesymbols; + end; + end; +end; + +procedure tmainfo.gdbserverexe(const sender: tguiapplication; + var again: boolean); +begin + sys_schedyield; + if timeout(fgdbservertimeout) and + ((getprocessexitcode(fgdbserverprocid,fgdbserverexitcode,100000) = pee_ok) or + projectoptions.d.nogdbserverexit) then begin + sender.terminatewait; + end + else begin + sender.idlesleep(100000); + again:= true; + end; +end; + +function tmainfo.terminategdbserver(const force: boolean): boolean; +var + int1: integer; +begin + result:= false; + if (fgdbserverprocid <> invalidprochandle) and + (not projectoptions.d.gdbserverstartonce or force) then begin + result:= true; + try + if (getprocessexitcode(fgdbserverprocid,int1) <> pee_ok) then begin + killprocesstree(fgdbserverprocid); + end; + except + end; + fgdbserverprocid:= invalidprochandle; + end; +end; + +procedure tmainfo.gdbservercancel(const sender: tobject); +begin + terminategdbserver(true); +end; + +procedure tmainfo.targetpipeinput(const sender: tpipereader); +begin + messagefo.messages[0].readpipe(sender); +end; + +function tmainfo.startgdbconnection(const attach: boolean): boolean; +var + mstr1: msestring; +begin + result:= false; + with projectoptions,d.texp do begin + if attach then begin + mstr1:= gdbservercommandattach; + end + else begin + mstr1:= gdbservercommand; + end; + if mstr1 <> '' then begin + if terminategdbserver(false) then begin +// sleep(1000); + end; + if d.gdbserverstartonce and gdb.tryconnect then begin + result:= true; + exit; + end; + if d.gdbservertty then begin + fgdbserverprocid:= execmse2(syscommandline(mstr1),nil, + targetpipe.pipereader,targetpipe.pipereader,-1,[exo_tty]); + end + else begin + fgdbserverprocid:= execmse2(syscommandline(mstr1),nil, + nil,nil,-1,[]); + end; + if fgdbserverprocid <> invalidprochandle then begin + fgdbservertimeout:= timestep(round(1000000*d.gdbserverwait)); + if application.waitdialog(nil,c[ord(startgdbservercommand)]+ + mstr1+c[ord(running2)],c[ord(startgdbserver)], + {$ifdef FPC}@{$endif}gdbservercancel,nil, + {$ifdef FPC}@{$endif}gdbserverexe) then begin + if (fgdbserverexitcode <> 0) and + not (projectoptions.d.nogdbserverexit and + (fgdbserverexitcode = -1)) then begin + setstattext(c[ord(gdbserverstarterror)]+' '+ + inttostrmse(fgdbserverexitcode)+'.',mtk_error); + exit; + end; + end + else begin + setstattext(c[ord(gdbservercanceled)],mtk_error); + exit; + end; + end + else begin + setstattext(c[ord(cannotrunstartgdb)],mtk_error); + exit; + end; + end; + end; + result:= true; +end; + +function tmainfo.checkgdberror(aresult: gdbresultty): boolean; +begin + result:= aresult = gdb_ok; + if not result then begin + setstattext(msestring('GDB: ' + gdb.geterrormessage(aresult)),mtk_error); + end; +end; + +procedure tmainfo.checkbluedots; +begin + if (sourcefo <> nil) and (sourcefo.activepage <> nil) then begin + if (gdb.execloaded or gdb.attached) and actionsmo.bluedotsonact.checked then begin + sourcefo.activepage.updatedebuglines; + end + else begin + sourcefo.activepage.cleardebuglines; + end; + end; +end; + +procedure tmainfo.updatesigsettings; +var + int1,int2: integer; + str1: string; + bo1: boolean; +begin + if gdb.active then begin + bo1:= gdb.running; + if bo1 then begin + gdb.interrupttarget; + end; + gdb.ignoreexceptionclasses:= projectoptions.ignoreexceptionclasses; + gdb.stoponexception:= projectoptions.d.stoponexception; + str1:= ''; + {$ifndef mswindows} + for int1:= sigrtmin to sigrtmax do begin + str1:= str1 + 'SIG' + inttostr(int1) + ' '; + end; + {$endif} + if (gdb.handle(str1,[]) = gdb_ok) then begin + for int1:= 0 to high(projectoptions.sigsettings) do begin + with projectoptions.sigsettings[int1] do begin + if num > 0 then begin + for int2:= num to numto do begin + gdb.handle(getsigname(int2),flags); + end; + end; + end; + end; + end; + if bo1 then begin + gdb.restarttarget; + end; + end; + gdb.newconsole:= projectoptions.d.externalconsole; + {$ifdef mswindows} +// gdb.newconsole:= projectoptions.d.externalconsole; + {$else} + gdb.settty:= projectoptions.d.settty; + gdb.xtermcommand:= projectoptions.d.texp.xtermcommand; + {$endif} +end; + +procedure tmainfo.uploadexe(const sender: tguiapplication; var again: boolean); +begin + if not downloading then begin + sender.terminatewait; + end + else begin + sender.idlesleep(100000); + again:= true; + end; +end; + +procedure tmainfo.uploadcancel(const sender: tobject); +begin + abortdownload; +// killprocess(fuploadprocid); +end; + +function tmainfo.needsdownload: boolean; +begin + result:= ftargetfilemodified or projectoptions.d.downloadalways; +end; + +function tmainfo.candebug: boolean; //run command empty or process attached +begin + result:= (projectoptions.d.texp.runcommand = '') or gdb.started; +end; + +procedure tmainfo.downloaded; +begin + ftargetfilemodified:= false; + if fgdbdownloaded then begin + fgdbdownloaded:= false; + if projectoptions.d.restartgdbbeforeload then begin + mainfo.startgdb(false); + end; + end; +end; + +procedure tmainfo.updatetargetenvironment; + //todo: implement for run without gdb +var + int1: integer; +begin + with projectoptions,d.texp do begin + gdb.progparameters:= ansistring(progparameters); + gdb.workingdirectory:= progworkingdirectory; + gdb.clearenvvars; + for int1:= 0 to high(envvarons) do begin + if (int1 > high(envvarnames)) or + (int1 > high(envvarnames)) then begin + break; + end; + if envvarons[int1] then begin + gdb.setenvvar(ansistring(envvarnames[int1]),ansistring(envvarvalues[int1])); + end + else begin + gdb.unsetenvvar(ansistring(envvarnames[int1])); + end; + end; + end; +end; + +procedure tmainfo.startconsole(); +begin + targetconsolefo.clear; + if projectoptions.d.showconsole then begin + targetconsolefo.activate; + end; +end; + +function tmainfo.loadexec(isattach: boolean; + const forcedownload: boolean): boolean; +var + str1: filenamety; +begin + setstattext(''); + result:= false; + if isattach then begin + inc(fexecstamp); + breakpointsfo.updatebreakpoints; + checkbluedots; + end + else begin + if not gdb.execloaded or forcedownload then begin + with projectoptions,d.texp do begin + if d.restartgdbbeforeload or not gdb.active then begin + startgdb(false); + end; + str1:= gettargetfile; + if not d.gdbdownload and not d.gdbsimulator and (uploadcommand <> '') and + (needsdownload or forcedownload) then begin + dodownload; + if application.waitdialog(nil,c[ord(str_uploadcommand)]+uploadcommand+ + c[ord(running2)], + c[ord(str_downloading)],{$ifdef FPC}@{$endif}uploadcancel,nil, + {$ifdef FPC}@{$endif}uploadexe) then begin + if downloadresult <> 0 then begin + setstattext(c[ord(downloaderror)]+' '+ + inttostrmse(downloadresult)+'.',mtk_error); + exit; + end + else begin + setstattext(c[ord(downloadfinished)],mtk_finished); + downloaded; + if projectoptions.s.closemessages then begin + messagefo.hide; + end; + end; + end + else begin + setstattext(c[ord(downloadcanceled)],mtk_error); + exit; + end; + end + end; + mainfo.setstattext(actionsmo.c[ord(ac_loading)]+'.',mtk_running); + application.processmessages(); + application.beginwait(); + if checkgdberror(gdb.fileexec(str1,forcedownload)) then begin + inc(fexecstamp); + breakpointsfo.updatebreakpoints; + mainfo.setstattext('',mtk_info); + end; + application.endwait(); + checkbluedots; + end; + end; + result:= gdb.execloaded or gdb.attached; + if result then begin + updatetargetenvironment; + watchpointsfo.clear; + startconsole(); + if forcedownload and projectoptions.d.gdbdownload then begin + if startgdbconnection(false) then begin + if checkgdberror(gdb.download(false)) then begin + fgdbdownloaded:= true; + end; + end; + end; + end; +end; + +procedure tmainfo.unloadexec; +begin + if gdb.active then begin + gdb.fileexec(''); //unload exec + end; + resetdebugdisp; + checkbluedots; +end; + +procedure tmainfo.startgdb(const killserver: boolean); +begin + terminategdbserver(killserver); + with projectoptions,d.texp do begin + if d.gdbloadtimeout = emptyreal then begin + gdb.loadtimeoutus:= 0; + end + else begin + gdb.loadtimeoutus:= round(d.gdbloadtimeout*1000000); + end; + gdb.remoteconnection:= remoteconnection; + gdb.gdbdownload:= d.gdbdownload; + gdb.simulator:= d.gdbsimulator; + gdb.processorname:= ansistring(gdbprocessor); + gdb.guiintf:= not d.nodebugbeginend; + gdb.beforeconnect:= beforeconnect; + gdb.afterconnect:= afterconnect; + gdb.beforeload:= beforeload; + gdb.afterload:= afterload; + gdb.beforerun:= beforerun; + gdb.startupbkpt:= d.startupbkpt; + gdb.startupbkpton:= d.startupbkpton; + gdb.startgdb(quotefilename(debugcommand)+ ' ' + debugoptions); + end; + updatesigsettings; + cleardebugdisp; + checkbluedots; +end; + +procedure tmainfo.restartgdbonexecute(const sender: tobject); +begin + startgdb(true); +end; + +procedure tmainfo.symboltypeonsetvalue(const sender: tobject; + var avalue: msestring; var accept: boolean); +var + expres: string; +begin + gdb.symboltype(ansistring(avalue),expres); + symboltypedisp.value:= msestring(expres); +end; + +procedure tmainfo.viewbreakpointsonexecute(const sender: tobject); +begin + breakpointsfo.activate; +end; + +procedure tmainfo.viewwatchesonexecute(const sender: tobject); +begin + watchfo.activate; +end; + +procedure tmainfo.viewstackonexecute(const sender: tobject); +begin + stackfo.activate; +end; + +procedure tmainfo.onscale(const sender: TObject); +begin + basedock.bounds_y:= statdisp.bottom + 1; + basedock.bounds_cy:= container.paintrect.cy - basedock.bounds_y; +end; + +procedure tmainfo.parametersonexecute(const sender: TObject); +begin + editprogramparameters; +end; + +procedure tmainfo.viewassembleronexecute(const sender: TObject); +begin + disassfo.activate; +end; + +procedure tmainfo.viewmemoryonexecute(const sender: TObject); +begin + memoryfo.activate; +end; + +procedure tmainfo.viewcpuonexecute(const sender: TObject); +begin + cpufo.activate; +end; + +procedure tmainfo.viewmessagesonexecute(const sender: TObject); +begin + messagefo.activate; +end; + +procedure tmainfo.viewsourceonexecute(const sender: tobject); +begin + sourcefo.activate; +end; + +procedure tmainfo.mainmenuonupdate(const sender: tcustommenu); +var + bo1: boolean; +begin + with projectoptions,d.texp,actionsmo do begin + detachtarget.enabled:= gdb.execloaded or gdb.attached; + download.enabled:= not gdb.started and not gdb.downloading and + ((uploadcommand <> '') or d.gdbdownload); + attachprocess.enabled:= not (gdb.execloaded or gdb.attached); + attachtarget.enabled:= attachprocess.enabled; + run.enabled:= not gdb.running and not gdb.downloading; + bo1:= candebug; + step.enabled:= not gdb.running and not gdb.downloading and bo1; + stepi.enabled:= not gdb.running and not gdb.downloading and bo1; + next.enabled:= not gdb.running and not gdb.downloading and bo1; + nexti.enabled:= not gdb.running and not gdb.downloading and bo1; + finish.enabled:= not gdb.running and gdb.started and bo1; + continue.enabled:= not gdb.running and not gdb.downloading and + (bo1 or (frunningprocess = invalidprochandle)); + interrupt.enabled:= gdb.running and not gdb.downloading and bo1; + reset.enabled:= (gdb.started or gdb.attached or gdb.downloading) or + not bo1 and (frunningprocess <> invalidprochandle); + makeact.enabled:= not making; + buildact.enabled:= not making; + make1act.enabled:= not making; + make2act.enabled:= not making; + make3act.enabled:= not making; + make4act.enabled:= not making; + abortmakeact.enabled:= making; + saveall.enabled:= sourcefo.modified or designer.modified or + projectoptions.modified; + actionsmo.toggleformunit.enabled:= (flastform <> nil) or + (designer.modules.count > 0); + if (sourcefo.activepage <> nil) and + sourcefo.activepage.activeentered then begin + setbm0.enabled:= true; + setbm1.enabled:= true; + setbm2.enabled:= true; + setbm3.enabled:= true; + setbm4.enabled:= true; + setbm5.enabled:= true; + setbm6.enabled:= true; + setbm7.enabled:= true; + setbm8.enabled:= true; + setbm8.enabled:= true; + setbm9.enabled:= true; + setbmnone.enabled:= true; + findbm0.enabled:= true; + findbm1.enabled:= true; + findbm2.enabled:= true; + findbm3.enabled:= true; + findbm4.enabled:= true; + findbm5.enabled:= true; + findbm6.enabled:= true; + findbm7.enabled:= true; + findbm8.enabled:= true; + findbm9.enabled:= true; + print.enabled:= true; + with sourcefo.activepage do begin + actionsmo.save.enabled:= modified; + undo.enabled:= edit.canundo; + redo.enabled:= edit.canredo; + copy.enabled:= edit.hasselection; + copylatexact.enabled:= edit.hasselection; + cut.enabled:= edit.hasselection; + paste.enabled:= edit.canpaste; + delete.enabled:= edit.hasselection; + indent.enabled:= true; + unindent.enabled:= true; + line.enabled:= grid.rowcount > 0; + togglebkpt.enabled:= line.enabled; + togglebkptenable.enabled:= togglebkpt.enabled; +// find.enabled:= true; + replace.enabled:= true; + copyword.enabled:= true; +// actionsmo.repeatfind.enabled:= find.enabled and +// (projectoptions.findreplaceinfo.find.text <> ''); + end; + end + else begin + setbm0.enabled:= false; + setbm1.enabled:= false; + setbm2.enabled:= false; + setbm3.enabled:= false; + setbm4.enabled:= false; + setbm5.enabled:= false; + setbm6.enabled:= false; + setbm7.enabled:= false; + setbm8.enabled:= false; + setbm8.enabled:= false; + setbm9.enabled:= false; + setbmnone.enabled:= false; + findbm0.enabled:= false; + findbm1.enabled:= false; + findbm2.enabled:= false; + findbm3.enabled:= false; + findbm4.enabled:= false; + findbm5.enabled:= false; + findbm6.enabled:= false; + findbm7.enabled:= false; + findbm8.enabled:= false; + findbm9.enabled:= false; + + print.enabled:= false; + save.enabled:= false; + undo.enabled:= false; + redo.enabled:= false; + copy.enabled:= false; + copylatexact.enabled:= false; + cut.enabled:= false; + paste.enabled:= false; + delete.enabled:= false; + indent.enabled:= false; + unindent.enabled:= false; + line.enabled:= false; + togglebkpt.enabled:= false; + togglebkptenable.enabled:= false; +// find.enabled:= false; +// actionsmo.repeatfind.enabled:= false; + replace.enabled:= false; + copyword.enabled:= false; + end; + if (factivedesignmodule <> nil) then begin + save.enabled:= factivedesignmodule^.modified; + close.enabled:= true; + end + else begin + close.enabled:= sourcefo.count > 0; + end; + closeall.enabled:= (sourcefo.count > 0) or (designer.modules.count > 0); + saveas.enabled:= (factivedesignmodule <> nil) or (sourcefo.activepage <> nil); + mainmenu1.menu.itembyname('project').itembyname('close').enabled:= + fprojectloaded; + end; +end; + +function tmainfo.formmenuitemstart: integer; +begin + result:= mainmenu1.menu.itembyname('view').itembyname( + 'formmenuitemstart').index + 1; +end; + +procedure tmainfo.createmodulemenuitem(const amodule: pmoduleinfoty); +var + int1: integer; + item1: tmenuitem; +begin + with mainmenu1.menu.itembyname('view') do begin + for int1:= formmenuitemstart to submenu.count-1 do begin + if submenu[int1].tagpo = amodule then begin + exit; + end; + end; + amodule^.hasmenuitem:= true; + item1:= tmenuitem.create; + with item1 do begin + if amodule^.modified then begin + caption:= '*'+msefileutils.filename(amodule^.filename); + end + else begin + caption:= msefileutils.filename(amodule^.filename); + end; + onexecute:= {$ifdef FPC}@{$endif}doshowform; + tagpo:= amodule; + options:= options + [mao_asyncexecute]; + end; + for int1:= formmenuitemstart to submenu.count-1 do begin + if submenu[int1].caption > item1.caption then begin + submenu.insert(int1,item1); + exit; + end; + end; + submenu.insert(bigint,item1); + end; +end; + +function tmainfo.openformfile(const filename: filenamety; + const ashow,aactivate,showsource,createmenu, + skipexisting: boolean): pmoduleinfoty; +var +// item1: tmenuitem; + wstr1,wstr2: filenamety; +// bo1: boolean; +// int1: integer; +begin + result:= designer.modules.findmodule(filename); + if result = nil then begin + wstr2:= msefileutils.filename(filename); + if findfile(filename) then begin + wstr1:= filename; + end + else begin + wstr1:= searchfile(wstr2,projectoptions.d.texp.sourcedirs); + if wstr1 = '' then begin + wstr1:= filename; //to raise exception + end + else begin + wstr1:= wstr1 + wstr2; + end; + end; + try + result:= designer.loadformfile(wstr1,skipexisting); + if result <> nil then begin + result^.filetag:= sourcefo.newfiletag; + sourcefo.filechangenotifyer.addnotification(wstr1,result^.filetag); + end; + except + showobjecttext(nil,wstr1,false); + errorformfilename:= wstr1; + raise; + end; + if result <> nil then begin + if showsource then begin + loadsourcebyform(wstr1); + end; + end; + end; + if result <> nil then begin + if createmenu then begin + createmodulemenuitem(result); + end; + if ashow then begin + result^.designform.show; + if aactivate then begin + result^.designform.activate; + end; + end; + if result^.modified then begin + sourcechanged(nil); + end; + end; +end; + +procedure tmainfo.loadformbysource(const sourcefilename: filenamety); +var + str1: filenamety; + activebefore: pmoduleinfoty; +begin + if fileext(sourcefilename) = pasfileext then begin + str1:= replacefileext(sourcefilename,formfileext); + if findfile(str1) then begin + activebefore:= factivedesignmodule; + try + openformfile(str1,true,false,false,true,true); + finally + factivedesignmodule:= activebefore; + end; + end; + end; +end; + +procedure tmainfo.loadsourcebyform(const formfilename: filenamety; + const aactivate: boolean = false); +begin + sourcefo.openfile(replacefileext(formfilename,pasfileext),aactivate); +end; + +function tmainfo.opensource(const filekind: filekindty; + const addtoproject: boolean; const aactivate: boolean = true; + const currentnode: tprojectnode = nil): boolean; + +var + unitnode: tunitnode; + +var + int1: integer; + page: tsourcepage; + str1: filenamety; + po1: pmoduleinfoty; + +begin //opensourceactonexecute + result:= openfile.execute = mr_ok; + if result then begin + page:= nil; + po1:= nil; + unitnode:= nil; //compilerwarning + designer.beginskipall; + try + with openfile.controller do begin + for int1:= 0 to high(filenames) do begin + if checkfileext(filenames[int1],[formfileext]) then begin + page:= sourcefo.findsourcepage(filenames[int1]); + if page = nil then begin + po1:= openformfile(filenames[int1],true,false,false,true,false); + end; + end + else begin + page:= sourcefo.openfile(filenames[int1]); + if addtoproject then begin + unitnode:= projecttree.units.addfile(currentnode,filenames[int1]); + end; + str1:= designer.sourcenametoformname(filenames[int1]); + if findfile(str1) then begin + po1:= openformfile(str1,true,false,false,true,false); + if addtoproject then begin + unitnode.setformfile(str1); + end; + end; + end; + end; + end; + finally + designer.endskipall; + end; + if aactivate then begin + if page <> nil then begin + page.activate(true,true); + end + else begin + if po1 <> nil then begin + po1^.designform.activate(true,true); + end; + end; + end; + end; +end; + +procedure tmainfo.designformactivated(const sender: tcustommseform); +begin + setlinkedvar(sender,tmsecomponent(flastform)); + if sourcefo = flastform then begin + factivedesignmodule:= nil; + setlinkedvar(sender,tmsecomponent(flastdesignform)); + end + else begin + if (designer.actmodulepo <> nil) and + (designer.actmodulepo^.designform = flastform) then begin + factivedesignmodule:= designer.actmodulepo; + setlinkedvar(sender,tmsecomponent(flastdesignform)); + end; + end; +end; + +procedure tmainfo.viewcomponentpaletteonexecute(const sender: TObject); +begin + componentpalettefo.show; + componentpalettefo.window.bringtofront; +end; + +procedure tmainfo.viewcomponentstoreonexecute(const sender: TObject); +begin + componentstorefo.activate; +end; + +procedure tmainfo.viewdebuggertoolbaronexecute(const sender: TObject); +begin + debuggerfo.show; + debuggerfo.window.bringtofront; +end; + +procedure tmainfo.mainonloaded(const sender: tobject); +var + wstr1: msestring; +label + endlab; +begin + try + if guitemplatesmo.sysenv.defined[ord(env_globstatfile)] then begin + wstr1:= guitemplatesmo.sysenv.value[ord(env_globstatfile)]; + if wstr1 <> '' then begin + mainstatfile.filename:= wstr1; + goto endlab; + end; + end; + wstr1:= filepath(statdirname); + if not finddir(wstr1) then begin + createdir(wstr1); + end; + {$ifdef mswindows} + mainstatfile.filename:= statname+'wi.sta'; + {$endif} + {$ifdef linux} + mainstatfile.filename:= statname+'li.sta'; + {$endif} + {$ifdef openbsd} + mainstatfile.filename:= statname+'obsd.sta'; + {$endif} + {$ifdef bsd} + mainstatfile.filename:= statname+'bsd.sta'; + {$endif} +endlab: + mainstatfile.readstat; + expandprojectmacros; + onscale(nil); + finally + if not application.terminated then begin + mainfo.activate; + end; + end; + {$ifdef mse_dumpunitgroups} + dumpunitgr; + {$endif} +end; + +function getmodulename(const aname,suffix,formsuffix: msestring): msestring; +var + int1: integer; +begin + int1:= length(aname) - length(suffix); + if (int1 >= 0) and + (msestringcomp(copy(aname,int1+1,bigint),suffix) = 0) then begin + result:= copy(aname,1,int1) + formsuffix; + end + else begin + result:= aname + formsuffix; + end; +end; + +procedure tmainfo.createform(const aname: filenamety; const namebase: string; + const formsuffix: string; const ancestor: string); +var + stream1: ttextstream; + str1,str2,str3: msestring; + po1: pmoduleinfoty; +begin + str3:= removefileext(filename(aname)); + str2:= msestring(getmodulename(str3,msestring(namebase), + msestring(formsuffix))); + stream1:= ttextstream.create(aname,fm_create); + try + formskeleton(stream1,ansistring(filename(str3)),ansistring(str2),ancestor); + finally + stream1.Free; + end; + sourcefo.showsourceline(aname,0,0,true); + str1:= replacefileext(aname,formfileext); + closemodule(designer.modules.findmodule(str1),false); + stream1:= ttextstream.create(str1,fm_create); + try + with stream1 do begin + writeln('object '+str2+': t'+str2); + writeln(' moduleclassname = '''+ancestor+''''); + writeln('end'); + end; + finally + stream1.Free; + end; + po1:= openformfile(str1,true,false,true,true,false); +{ + if kind = fok_main then begin + with tmseform(po1^.instance) do begin + options:= options + [fo_main,fo_terminateonclose]; + optionswindow:= optionswindow + [wo_groupleader]; + end; + end; +} + po1^.modified:= true; //initial create of ..._mfm.pas +end; + +procedure tmainfo.createprogramfile(const aname: filenamety); +var + stream1: ttextstream; +begin + stream1:= ttextstream.create(aname,fm_create); + try + programskeleton(stream1,ansistring(removefileext(filename(aname)))); + finally + stream1.Free; + end; + sourcefo.showsourceline(aname,0,0,true); +end; + +function tmainfo.copynewfile(const aname,newname: filenamety; + const autoincrement: boolean; + const canoverwrite: boolean; + const macronames: array of msestring; + const macrovalues: array of msestring): boolean; + //true if ok +var + int1: integer; + dir,base,ext: filenamety; + path1,path2: filenamety; + macrolist: tmacrolist; + instream,outstream: ttextstream; + text: msestringarty; + +begin + result:= false; + path1:= searchfile(aname); + if path1 = '' then begin + showmessage(c[ord(str_file)]+aname+c[ord(notfound2)],c[ord(warning)]); + end + else begin + path2:= filepath(newname); + if not canoverwrite and findfile(path2) then begin + if not autoincrement then begin + showerror(c[ord(str_file)]+newname+c[ord(exists)]); + exit; + end + else begin + splitfilepath(filepath(aname),dir,base,ext); + base:= base + dir; + int1:= 1; + repeat + path2:= base+inttostrmse(int1)+ext; + inc(int1); + until not findfile(path2); + end; + end; + splitfilepath(path2,dir,base,ext); + macrolist:= tmacrolist.create([mao_curlybraceonly]); + try + macrolist.add(['%FILEPATH%','%FILENAME%','%FILENAMEBASE%'], + [path2,base+ext,base],[]); + macrolist.add(macronames,macrovalues,[]); + instream:= ttextstream.create(path1); + try + text:= instream.readmsestrings; + macrolist.expandmacros1(text); + outstream:= ttextstream.create(path2,fm_create); + try + outstream.writemsestrings(text); + finally + outstream.free; + end; + finally + instream.free; + end; + finally + macrolist.free; + end; + result:= true; + end; +end; + +procedure tmainfo.newfileonexecute(const sender: TObject); +var + str1: filenamety; + int1: integer; +begin + str1:= ''; + int1:= tmenuitem(sender).tag; + with projectoptions.p.texp do begin + if newfisources[int1] = '' then begin + sourcefo.newpage; + end + else begin + if filedialog(str1,[fdo_save,fdo_checkexist],c[ord(str_new)]+' '+ + newfinames[int1],[newfinames[int1]], + [newfifilters[int1]],newfiexts[int1]) = mr_ok then begin + copynewfile(newfisources[int1],str1,false,true, + ['%PROGRAMNAME%','%UNITNAME%'],['${%FILENAMEBASE%}', + '${%FILENAMEBASE%}']); + sourcefo.openfile(str1,true); + end; + end; + end; +end; + +procedure tmainfo.newformonexecute(const sender: TObject); +var + str1,str2,str3,str4,str5,str6: filenamety; + dir,base,ext: filenamety; + po1: pmoduleinfoty; + ancestorclass,ancestorunit: msestring; + +begin +// if formkindty(tmenuitem(sender).tag) = fok_inherited then begin + if projectoptions.p.newinheritedforms[tmenuitem(sender).tag] then begin + po1:= selectinheritedmodule(nil,c[ord(selectancestor)]); + if po1 = nil then begin + exit; + end; + ancestorclass:= msestring(po1^.moduleclassname); + ancestorunit:= filenamebase(po1^.filename); + end + else begin + ancestorclass:= ''; + ancestorunit:= ''; + po1:= nil; + end; + str1:= ''; + if filedialog(str1,[fdo_save,fdo_checkexist],c[ord(newform)], + [c[ord(pascalfiles)]], + ['"*.pas" "*.pp" "*.mla"'],'pas') = mr_ok then begin + with projectoptions.p.texp do begin + str4:= newfonamebases[tmenuitem(sender).tag]; + str6:= newfoformsuffixes[tmenuitem(sender).tag]; + str2:= newfosources[tmenuitem(sender).tag]; + str3:= newfoforms[tmenuitem(sender).tag]; + end; + if (str2 <> '') or (str3 <> '') then begin + if str2 <> '' then begin + str2:= filepath(str2); //sourcesource + end; + if str3 <> '' then begin + str3:= filepath(str3); //formsource + end; + splitfilepath(str1,dir,base,ext); + str4:= getmodulename(base,str4,str6); + str5:= replacefileext(str1,'mfm'); + if str2 <> '' then begin + copynewfile(str2,str1,false,true, + ['%UNITNAME%','%FORMNAME%','%ANCESTORUNIT%','%ANCESTORCLASS%'], + ['${%FILENAMEBASE%}',str4,ancestorunit,ancestorclass]); //source + end; + if str3 <> '' then begin + copynewfile(str3,str5,false,true, + ['%UNITNAME%','%FORMNAME%','%ANCESTORUNIT%','%ANCESTORCLASS%'], + ['${%FILENAMEBASE%}',str4,ancestorunit,ancestorclass]); //form + end; + if str2 <> '' then begin + sourcefo.openfile(str1,true); + end; + if (str3 <> '') then begin + openformfile(str5,true,false,false,true,false); + po1:= designer.modules.findmodule(str5); + if po1 <> nil then begin + po1^.modified:= true; //initial create of ..._mfm.pas + end; + end; + end + else begin +// createform(str1,formkindty(tmenuitem(sender).tag)); + createform(str1,'form','tmseform','fo'); //default + end; + end; +end; + +procedure tmainfo.removemodulemenuitem(const amodule: pmoduleinfoty); +var + int1: integer; +begin + with mainmenu1.menu.itembyname('view') do begin + for int1:= itembyname('formmenuitemstart').index+1 to count - 1 do begin + if items[int1].tagpo = amodule then begin + submenu.delete(int1); + break; + end; + end; + end; +end; + +function tmainfo.closemodule(const amodule: pmoduleinfoty; + const achecksave: boolean; + nocheckclose: boolean = false): boolean; +var + str1: string; + mstr1: filenamety; +begin + if amodule <> nil then begin + mstr1:= amodule^.filename; + if nocheckclose or designer.checkcanclose(amodule,str1) then begin + result:= designer.closemodule(amodule,achecksave); + end + else begin + amodule^.designform.hide; + result:= true; + removemodulemenuitem(amodule); + amodule^.hasmenuitem:= false; + end; + if result then begin + sourcefo.filechangenotifyer.removenotification(mstr1); + if factivedesignmodule = amodule then begin + factivedesignmodule:= nil; + end; + end; + end + else begin + result:= true; + end; +end; + +function tmainfo.checksavecancel(const aresult: modalresultty): modalresultty; +begin + if aresult = mr_cancel then begin + projectoptions.savechecked:= false; + sourcefo.savecanceled; + designer.savecanceled; + end; + result:= aresult; +end; + +function tmainfo.closeall(const nosave: boolean): boolean; +begin + result:= nosave or (checksavecancel(sourcefo.saveall(false)) <> mr_cancel); + if result then begin + result:= nosave or + (checksavecancel(designer.saveall(false,true)) <> mr_cancel); + if result then begin + sourcefo.closeall(true); + while designer.modules.count > 0 do begin + closemodule(designer.modules.itempo[designer.modules.count-1],not nosave,true); + end; + end; + end; +end; + +procedure tmainfo.buildactonexecute(const sender: TObject); +begin + domake(2); +end; + +procedure tmainfo.showfirsterror; +var + int1: integer; + apage: tsourcepage; +begin + with messagefo do begin + for int1:= 0 to messages.rowcount - 1 do begin + if locateerrormessage(messages[0][int1],apage,el_error) then begin + messages.focuscell(makegridcoord(0,int1)); + setstattext(messages[0][int1],mtk_error); + break; + end; + end; + end; +end; +{ +procedure tmainfo.mainfoonclosequery(const sender: tcustommseform; + var modalresult: modalresultty); +begin + if checksave = mr_cancel then begin + modalresult:= mr_none; + end + else begin + sourcefo.filechangenotifyer.clear; + mainstatfile.writestat; + end; +end; +} +procedure tmainfo.mainfoonterminate(var terminate: Boolean); +//var +// modres: modalresultty; +begin + if checksave = mr_cancel then begin + terminate:= false; + end + else begin + sourcefo.filechangenotifyer.clear; + mainstatfile.writestat; + end; + { + modres:= mr_windowclosed; + mainfoonclosequery(nil,modres); + if modres <> mr_windowclosed then begin + terminate:= false; + end; + end; + } +end; + +procedure tmainfo.setprojectname(aname: filenamety); +begin + fprojectname:= aname; + if aname = '' then begin + caption:= idecaption+' (<'+c[ord(new2)]+'>)'; + end + else begin + caption:= idecaption+' ('+filename(aname)+')'; + setcurrentdirmse(filedir(aname)); + openfile.controller.filename:= ''; + end; + dragdock.layoutchanged; //refresh possible dockpanel caption +end; + +function tmainfo.openproject(const aname: filenamety; + const ascopy: boolean = false): boolean; + + procedure closepro; + begin + gdb.abort; + sourceupdater.clear; + initprojectoptions; + projectoptions.projectfilename:= ''; + setprojectname(''); + projecttreefo.clear; + watchfo.clear(true); + breakpointsfo.clear; + watchpointsfo.clear(true); + cleardebugdisp; + designer.savecanceled(); //reset saveall flag + end; + +var + namebefore: msestring; + projectfilebefore: msestring; + projectdirbefore: msestring; + +begin + gdb.abort; + terminategdbserver(true); + result:= false; + projectfilebefore:= projectoptions.projectfilename; + projectdirbefore:= projectoptions.projectdir; + namebefore:= fprojectname; + if (checksave <> mr_cancel) and closeall(true) then begin + closepro; + if aname <> '' then begin + try + setcurrentdirmse(removelastpathsection(aname)); + except + application.handleexception(nil,c[ord(cannotloadproj)]+aname+'": '); + exit; + end; + if not readprojectoptions(aname) then begin + closepro; + end + else begin + fcurrent:= false; + gdb.closegdb; + cleardebugdisp; + if not ascopy then begin + setprojectname(aname); + end + else begin + projectoptions.projectfilename:= projectfilebefore; + projectoptions.projectdir:= projectdirbefore; + expandprojectmacros; + setprojectname(namebefore); + end; + end; + end; + result:= true; + fprojectloaded:= true; + end; +end; + +procedure tmainfo.saveproject(aname: filenamety; + const ascopy: boolean = false); +begin + if aname <> '' then begin + try + saveprojectoptions(aname); + if not ascopy then begin + setprojectname(aname); + expandprojectmacros; + end; + except + application.handleexception(nil); + end; + end; +end; + +procedure tmainfo.newproject(const fromprogram,empty: boolean); +var + aname: filenamety; + mstr1,mstr2: msestring; + i1: integer; + curdir,source,dest: filenamety; + macrolist: tmacrolist; + copiedfiles: filenamearty; + bo1: boolean; +label + endlab; +begin + mstr2:= projecttemplatedir; //use macros of current project + if fromprogram then begin + if (checksave() = mr_cancel) or not closeall(false) then begin + exit; + end; + setprojectname(''); + end; + if fromprogram or openproject('') then begin + gdb.closegdb; + cleardebugdisp; + sourcechanged(nil); + mstr1:= ''; + if not fromprogram then begin + if not empty then begin + aname:= mstr2 + 'default.prj'; + if filedialog(aname,[fdo_checkexist],c[ord(selecttemplate)], + [c[ord(projectfiles)],c[ord(str_allfiles)]], + ['*.prj','*'],'prj') = mr_ok then begin + readprojectoptions(aname); + end; + end; + aname:= ''; + end + else begin + aname:= ''; + if filedialog(aname,[fdo_checkexist],c[ord(selectprogramfile)], + [c[ord(pascalprogfiles)],c[ord(cfiles)],c[ord(str_allfiles)]], + ['"*.pas" "*.pp" "*.mla" "*.dpr" "*.lpr"','"*.c" "*.cc" "*.cpp"','*'], + 'pas') = mr_ok then begin + setcurrentdirmse(filedir(aname)); + with projectoptions do begin + with k.t do begin + mainfile:= filename(aname); + aname:= removefileext(mainfile); + targetfile:= aname+'${EXEEXT}' + end; + expandprojectmacros; + end; + aname:= aname + '.prj'; + end + else begin + goto endlab; + end; + end; + if filedialog(aname,[fdo_save,fdo_checkexist],c[ord(str_newproject)], + [c[ord(projectfiles)],c[ord(str_allfiles)]], + ['*.prj','*'],'prj') = mr_ok then begin + curdir:= filedir(aname); + setcurrentdirmse(curdir); + insertitem(projecthistory,0,aname); + i1:= 1; + while i1 <= high(projecthistory) do begin + if projecthistory[i1] = aname then begin + deleteitem(projecthistory,i1); + end; + inc(i1); + end; + if high(projecthistory) >= + projectfiledia.controller.historymaxcount then begin + setlength(projecthistory,projectfiledia.controller.historymaxcount); + end; + if not fromprogram then begin + mstr1:= removefileext(filename(aname)); + with projectoptions,s do begin + projectfilename:= aname; + projectdir:= curdir; + expandprojectmacros; + with p.texp do begin + setlength(copiedfiles,length(newprojectfiles)); + macrolist:= tmacrolist.create([mao_curlybraceonly]); + try + macrolist.add(['%PROJECTNAME%','%PROJECTDIR%'],[mstr1,curdir],[]); + if runscript(scriptbeforecopy,true,false) then begin + for i1:= 0 to high(newprojectfiles) do begin + source:= filepath(newprojectfiles[i1]); + if i1 <= high(newprojectfilesdest) then begin + dest:= newprojectfilesdest[i1]; + end + else begin + dest:= ''; + end; + if dest <> '' then begin + macrolist.expandmacros1(dest); + if source = '' then begin + createdirpath(dest); + end + else begin + createdirpath(filedir(dest)); + end; + end + else begin + dest:= filename(source); + end; + copiedfiles[i1]:= dest; + if newprojectfiles[i1] <> '' then begin + if (i1 <= high(p.expandprojectfilemacros)) and + p.expandprojectfilemacros[i1] then begin + copynewfile(source,dest,false,false,['%PROJECTNAME%','%PROJECTDIR%'], + [mstr1,curdir]); + end + else begin + try + if not copyfile(source,dest,false) then begin + showerror(c[ord(str_file)]+dest+c[ord(exists)]); + end; + except + application.handleexception(nil); + end; + end; + end; + end; + runscript(scriptaftercopy,false,false); + end; + finally + macrolist.free; + end; + end; + saveproject(aname); + bo1:= true; + for i1:= 0 to high(copiedfiles) do begin + if i1 > high(p.loadprojectfile) then begin + break; + end; + if p.loadprojectfile[i1] then begin + if checkfileext(copiedfiles[i1],[formfileext])then begin + openformfile(copiedfiles[i1],true,false,false,true,false); + end + else begin + sourcefo.openfile(copiedfiles[i1],bo1); + bo1:= false; + end; + end; + end; + end; + end + else begin + saveproject(aname); + sourcefo.openfile(projectoptions.k.texp.mainfile,true); + end; + end + else begin +endlab: + projectoptions.projectfilename:= ''; + projectoptions.modified:= true; + end; + end; +end; + +procedure tmainfo.newprojectonexecute(const sender: tobject); +begin + newproject(false,false); +end; + +procedure tmainfo.newprojectfromprogramexe(const sender: TObject); +begin + newproject(true,false); +end; + +procedure tmainfo.newemptyprojectexe(const sender: TObject); +begin + newproject(false,true); +end; + +procedure tmainfo.openprojectcopyexecute(const sender: TObject); +var + str1: filenamety; +begin + if projectfiledialog(str1,false) = mr_ok then begin + openproject(str1,true); + end; +end; + +procedure tmainfo.saveprojectasonexecute(const sender: tobject); +var + str1: filenamety; +begin + if projectfiledialog(str1,true) = mr_ok then begin + saveproject(str1); + end; +end; + +procedure tmainfo.saveprojectcopyexecute(const sender: TObject); +var + str1: filenamety; +begin + if projectfiledialog(str1,true) = mr_ok then begin + saveproject(str1,true); + end; +end; + +procedure tmainfo.mainstatfileonupdatestat(const sender: tobject; + const filer: tstatfiler); +var + mstr1: filenamety; + mstr2: msestring; + ar1: msestringarty; + int1,i2: integer; + ar2: macroinfoarty; + ma1: settingsmacroty; + bo1: boolean; +begin + ar1:= nil; //compiler warning + updatesettings(filer); + + mstr1:= projectoptions.projectfilename; + filer.updatevalue('projectname',mstr1); + filer.updatevalue('projecthistory',projecthistory); + filer.updatevalue('windowlayoutfile',windowlayoutfile); + filer.updatevalue('windowlayouthistory',windowlayouthistory); + + if not filer.iswriter then begin + if guitemplatesmo.sysenv.defined[ord(env_storeglobalmacros)] then begin + ar2:= guitemplatesmo.sysenv.getcommandlinemacros(ord(env_macrodef)); + with settings.macros do begin + for int1:= 0 to high(ar2) do begin + mstr2:= ar2[int1].name; + bo1:= false; + for ma1:= low(settingsmacroty) to high(settingsmacroty) do begin + if msecomparetext(mstr2,settingsmacronames[ma1]) = 0 then begin + macros[ma1]:= ar2[int1].value; + bo1:= true; + break; + end; + end; + if not bo1 then begin + bo1:= false; + for i2:= 0 to high(globmacronames) do begin + if msecomparetext(mstr2,globmacronames[i2]) = 0 then begin + bo1:= true; + if high(globmacrovalues) < i2 then begin + setlength(globmacrovalues,i2+1); + end; + globmacronames[i2]:= ar2[int1].name; + globmacrovalues[i2]:= ar2[int1].value; + end; + end; + if not bo1 then begin + additem(globmacronames,ar2[int1].name); + if high(globmacrovalues) < high(globmacronames) then begin + setlength(globmacrovalues,high(globmacronames)+1); + end; + globmacrovalues[high(globmacronames)]:= ar2[int1].value; + end; + end; + end; + end; + application.terminated:= true; + projectoptions.projectfilename:= mstr1; + mainstatfile.writestat(); + exit(); + end; + if guitemplatesmo.sysenv.defined[ord(env_filename)] then begin + ar1:= guitemplatesmo.sysenv.values[ord(env_filename)]; + if (high(ar1) = 0) and (fileext(ar1[0]) = 'prj') then begin + mstr1:= filepath(ar1[0]); + end + else begin + if high(ar1) >= 0 then begin + for int1:= 0 to high(ar1) do begin + sourcefo.openfile(ar1[int1],int1 = 0); + end; + end; + exit; + end; + end; + end; + if not filer.iswriter and (mstr1 <> '') and + not guitemplatesmo.sysenv.defined[ord(env_np)] then begin + openproject(mstr1); + end; +end; + +procedure tmainfo.targetfilemodified; +begin + ftargetfilemodified:= true; +end; + +procedure tmainfo.domake(atag: integer); +begin + unloadexec; + if designer.beforemake and + (checksavecancel(sourcefo.saveall(true)) <> mr_cancel) and + (checksavecancel(designer.saveall(true,true)) <> mr_cancel) then begin + updatemodifiedforms; + ftargetfilemodified:= false; + make.domake(atag); + end; +end; + +procedure tmainfo.dorun; +var + mstr1: msestring; + pwdbefore: msestring; +begin + if projectoptions.d.texp.runcommand = '' then begin + if not projectoptions.d.gdbsimulator then begin + if startgdbconnection(false) then begin + gdb.gdbdownload:= projectoptions.d.gdbdownload and needsdownload; + checkgdberror(gdb.run); + end; + end + else begin + checkgdberror(gdb.run); + end; + end + else begin + with projectoptions,d.texp do begin + mstr1:= runcommand; + if progparameters <> '' then begin + mstr1:= mstr1 + ' ' + progparameters; + end; + if progworkingdirectory <> '' then begin + pwdbefore:= setcurrentdirmse(progworkingdirectory); + end; + try + if projectoptions.d.externalconsole then begin + frunningprocess:= execmse4(mstr1,[exo_newconsole]); + end + else begin + startconsole(); + frunningprocess:= targetconsolefo.terminal.execprog(mstr1); + end; + if frunningprocess = invalidprochandle then begin + setstattext(c[ord(cannotstartprocess)],mtk_error); + exit; + end; + runprocmon.listentoprocess(frunningprocess); + finally + if progworkingdirectory <> '' then begin + setcurrentdirmse(pwdbefore); + end; + end; + end; + setstattext('*** '+c[ord(process)]+' '+inttostrmse(frunningprocess)+' '+ + c[ord(running3)]+' ***',mtk_running); + end; +end; + +procedure tmainfo.runprocdied(const sender: TObject; + const prochandle: prochandlety; + const execresult: Integer; const data: Pointer); +begin + if prochandle = frunningprocess then begin + frunningprocess:= invalidprochandle; + if execresult <> 0 then begin + setstattext(c[ord(processterminated)]+' '+inttostrmse(execresult){+'.'}, + mtk_finished); + end + else begin + setstattext(c[ord(proctermnormally)],mtk_finished); + end; + end; +end; + +function tmainfo.runtarget: boolean; + //true if run possible +begin + result:= true; + if not gdb.attached then begin + if (projectoptions.d.texp.runcommand = '') and + (projectoptions.d.t.debugcommand <> '') then begin + if not gdb.started then begin + if loadexec(false,false) then begin + result:= false; + dorun; + end; + end; + end + else begin + result:= false; + if (projectoptions.d.texp.runcommand <> '') then begin + dorun; + end; + end; + end; +end; + +function tmainfo.checkremake(startcommand: startcommandty): boolean; + //true if running possible +begin + if not objectinspectorfo.canclose(nil) then begin + result:= false; + exit; + end; + result:= true; + fstartcommand:= startcommand; + if not gdb.active then begin + startgdb(false); + end; + if not gdb.attached then begin + if (not gdb.started or not fnoremakecheck) and not fcurrent then begin + if (projectoptions.defaultmake <= maxdefaultmake) and + (not gdb.started or askconfirmation(c[ord(str_sourcechanged)])) then begin + result:= false; + watchpointsfo.clear; + domake(projectoptions.defaultmake); + end; + fnoremakecheck:= true; + end; + if result then begin + result:= runtarget; + end; + end + else begin + if not gdb.started then begin + result:= false; + dorun; + end; + end; +end; + +procedure tmainfo.runexec(const sender: tobject); +begin + if checkremake(sc_continue) then begin + dorun; + end; +end; + +procedure tmainfo.aftermake(const adesigner: idesigner; + const exitcode: integer); +begin + if exitcode <> 0 then begin + setstattext(c[ord(makeerror)]+' '+inttostrmse(exitcode)+'.',mtk_error); + showfirsterror; + end + else begin + setstattext(c[ord(makeok)],mtk_finished); + fcurrent:= true; + fnoremakecheck:= false; + messagefo.messages.lastrow; + if projectoptions.s.closemessages then begin + messagefo.hide; + end; + if fstartcommand <> sc_none then begin + runtarget; + end; + end; +end; + +procedure Tmainfo.resetstartcommand; +begin + fstartcommand:= sc_none; +end; + +procedure tmainfo.killtarget; +begin + if frunningprocess <> invalidprochandle then begin + killprocess(frunningprocess); + frunningprocess:= invalidprochandle; + end; +end; + +procedure tmainfo.sourcechanged(const sender: tsourcepage); +begin + fnoremakecheck:= false; + fcurrent:= false; + if sender = nil then begin + updatemodifiedforms; + end; +end; + +procedure tmainfo.exitonexecute(const sender: tobject); +begin + window.close; +end; + +procedure tmainfo.moduledestroyed(const adesigner: idesigner; + const amodule: tmsecomponent); +var + po1: pmoduleinfoty; +begin + po1:= designer.modules.findmodulebyinstance(amodule); + removemodulemenuitem(po1); + if po1 = factivedesignmodule then begin + factivedesignmodule:= nil; + end; +end; + +procedure tmainfo.methodcreated(const adesigner: idesigner; + const amodule: tmsecomponent; const aname: string; + const atype: ptypeinfo); +begin + //dummy +end; + +procedure tmainfo.methodnamechanged(const adesigner: idesigner; + const amodule: tmsecomponent; const newname, oldname: string; const atypeinfo: ptypeinfo); +begin + //dummy +end; + +procedure tmainfo.showobjecttext(const adesigner: idesigner; + const afilename: filenamety; const backupcreated: boolean); +var + page: tsourcepage; +begin + page:= sourcefo.openfile(afilename,true); + if page <> nil then begin + page.ismoduletext:= true; + if backupcreated then begin + page.setbackupcreated; + end; + end; +end; + +procedure tmainfo.closeobjecttext(const adesigner: idesigner; + const afilename: filenamety; var cancel: boolean); +begin + cancel:= not sourcefo.closepage(afilename); +end; + +procedure tmainfo.newpanelonexecute(const sender: TObject); +begin + newpanel.activate; +end; + +procedure tmainfo.viewwatchpointsonexecute(const sender: TObject); +begin + watchpointsfo.activate; +end; + +procedure tmainfo.viewsymbolsonexecute(const sender: TObject); +begin + symbolfo.activate; +end; + +procedure tmainfo.viewthreadsonexecute(const sender: TObject); +begin + threadsfo.activate; +end; + +procedure tmainfo.viewconsoleonexecute(const sender: TObject); +begin + targetconsolefo.activate; +end; + +procedure tmainfo.viewfindresults(const sender: TObject); +begin + findinfilefo.activate; +end; + +procedure tmainfo.aboutonexecute(const sender: TObject); +begin + showmessage('MSEide version: '+versiontext+c_linefeed+ + 'MSEgui version: '+mseguiversiontext+c_linefeed+ + 'Host: '+ platformtext+ c_linefeed+ + c_linefeed+ + copyrighttext+c_linefeed+ + 'by Martin Schreiber' + ,actionsmo.c[ord(ac_about)]+' MSEide'); +end; + +procedure tmainfo.configureexecute(const sender: TObject); +begin + configureide; +end; + +procedure tmainfo.beforemake(const adesigner: idesigner; + const maketag: integer; var abort: boolean); +begin + //dummy +end; + + +procedure tmainfo.beforefilesave(const adesigner: idesigner; + const afilename: filenamety); +begin + //dummy +end; + +procedure tmainfo.runtool(const sender: tobject); +var + str1: msestring; + mstr1: msestring; + macrolist: tmacrolist; +// gridcoord1: gridcoordty; + cursourcefile,curmodulefile, + cursselection,cursword,cursdefinition: msestring; + curcomponentclass,curproperty: msestring; + spos1: sourceposty; + ar1: componentarty; + propit: tpropertyitem; + opt1: execoptionsty; +begin + with tmenuitem(sender),projectoptions,t,texp do begin + str1:= tosysfilepath(toolfiles[index]); + if str1 <> '' then begin + if (index <= high(toolfiles)) and (toolparams[index] <> '') then begin + if (index <= high(toolsave)) and toolsave[index] then begin + actionsmo.saveallactonexecute(nil); + end; + if sourcefo.activepage <> nil then begin + with sourcefo.activepage do begin + cursourcefile:= tosysfilepath(sourcefo.currentfilename); + cursselection:= sourcefo.currentselection;//edit.selectedtext; + cursword:= sourcefo.currentwordatcursor;//getpascalvarname(edit,edit.editpos,gridcoord1); + if (index <= high(toolparse)) and toolparse[index] then begin + spos1.pos:= edit.editpos; + spos1.filename:= designer.designfiles.find(edit.filename); + application.beginwait; + try + findlinkdest(edit,spos1,cursdefinition); + finally + application.endwait; + end; + end; + end + end + else begin + cursourcefile:= ''; + cursselection:= ''; + cursword:= ''; + cursdefinition:= ''; + end; + curcomponentclass:= ''; + curproperty:= ''; + if factivedesignmodule <> nil then begin + curmodulefile:= tosysfilepath(factivedesignmodule^.filename); + ar1:= designer.selectedcomponents; + if high(ar1) = 0 then begin + with gettypedata(ar1[0].classinfo)^ do begin + curcomponentclass:= msestring(uppercase(unitname+'.'+ar1[0].classname)); + end; + propit:= tpropertyitem(objectinspectorfo.props.item); + if propit <> nil then begin + curproperty:= curcomponentclass+'.' + uppercase(propit.rootpath); + end; + end; + end + else begin + curmodulefile:= ''; + end; + mstr1:= toolparams[index]; + if mstr1 <> '' then begin + macrolist:= tmacrolist.create([mao_caseinsensitive]); + macrolist.add(getprojectmacros); + macrolist.add(['CURSOURCEFILE','CURMODULEFILE', + 'CURSSELECTION','CURSWORD','CURSDEFINITION', + 'CURCOMPONENTCLASS','CURPROPERTY'], + [cursourcefile,curmodulefile, + cursselection,cursword,cursdefinition, + curcomponentclass,curproperty],[]); + macrolist.expandmacros1(mstr1); + macrolist.free; + str1:= str1 + ' ' + mstr1; + end; + end; + opt1:= [exo_nostdhandle]; + if not((index > high(toolhide)) or toolhide[index]) then begin + include(opt1,exo_inactive); + end; + if (index <= high(toolmessages)) and toolmessages[index] then begin + ttoolhandlermo.create(self,str1,opt1); + end + else begin + execmse(str1,opt1{not((index > high(toolhide)) or toolhide[index]),true}); + end; + end; + end; +end; + +procedure tmainfo.statbefread(const sender: TObject); +begin + createcpufo; +end; + +procedure tmainfo.getstatobjs(const sender: TObject; + var aobjects: objectinfoarty); +begin + with projectoptions do begin +{ + if not (sg_options in disabled) then begin + addobjectinfoitem(aobjects,o); + end; +} + if not (sg_editor in disabled) then begin + addobjectinfoitem(aobjects,e); + end; + if not (sg_debugger in disabled) then begin + addobjectinfoitem(aobjects,d); + end; + if not (sg_make in disabled) then begin + addobjectinfoitem(aobjects,k); + end; + if not (sg_macros in disabled) then begin + addobjectinfoitem(aobjects,m); + end; + if not (sg_fontalias in disabled) then begin + addobjectinfoitem(aobjects,a); + end; + if not (sg_usercolors in disabled) then begin + addobjectinfoitem(aobjects,u); + end; + if not (sg_formatmacros in disabled) then begin + addobjectinfoitem(aobjects,f); + end; + if not (sg_templates in disabled) then begin + addobjectinfoitem(aobjects,p); + end; + if not (sg_tools in disabled) then begin + addobjectinfoitem(aobjects,t); + end; + if not (sg_storage in disabled) then begin + addobjectinfoitem(aobjects,r); + end; + if not (sg_state in disabled) then begin + addobjectinfoitem(aobjects,s); + end; + end; +end; + +procedure tmainfo.savewindowlayout(const awriter: tstatwriter); +var + opt1: statfileoptionsty; +begin + opt1:= projectstatfile.options; + projectstatfile.options:= mainfo.projectstatfile.options + + [sfo_nodata,sfo_nooptions]; + awriter.setsection('breakpoints'); + beginpanelplacement(); + try + panelform.updatestat(awriter); + awriter.setsection('layout'); + projectstatfile.updatestat('windowlayout',awriter); + finally + endpanelplacement(); + mainfo.projectstatfile.options:= opt1; + end; +end; + +procedure tmainfo.savewindowlayout(const astream: ttextstream); +var + statwriter: tstatwriter; +begin + statwriter:= tstatwriter.create(astream,ce_utf8); + try + savewindowlayout(statwriter); + finally + statwriter.free; + end; +end; + +procedure tmainfo.loadwindowlayout(const areader: tstatreader); +begin + beginpanelplacement(); + try + areader.setsection('breakpoints'); + panelform.updatestat(areader); + areader.setsection('layout'); + projectstatfile.options:= projectstatfile.options + + [sfo_nodata,sfo_nooptions]; + flayoutloading:= true; + projectstatfile.readstat('windowlayout',areader); + finally + flayoutloading:= false; + projectstatfile.options:= projectstatfile.options - + [sfo_nodata,sfo_nooptions]; + endpanelplacement(); + end; +end; + +procedure tmainfo.loadwindowlayout(const astream: ttextstream); +var + statreader: tstatreader; +begin + statreader:= tstatreader.create(astream,ce_utf8); + try + loadwindowlayout(statreader); + finally + statreader.free; + end; +end; + +procedure tmainfo.loadwindowlayoutexe(const sender: TObject); +var + str1: ttextstream; +begin + if filedialog(windowlayoutfile,[fdo_checkexist],c[ord(str_loadwindowlayout)], + [c[ord(projectfiles)],c[ord(str_allfiles)]],['*.prj','*'],'prj', + nil,nil,nil,[fa_all],[fa_hidden], + @windowlayouthistory) = mr_ok then begin + str1:= ttextstream.create(windowlayoutfile); + try + loadwindowlayout(str1); + finally + str1.destroy(); + end; + end; +end; + +procedure tmainfo.closeprojectactonexecute(const sender: TObject); +begin + if mainfo.openproject('') then begin + caption:= idecaption; + fprojectloaded:= false; + end; +end; + +procedure tmainfo.mainstatbeforewriteexe(const sender: TObject); +begin + disassfo.resetshortcuts(); +end; + +procedure tmainfo.statafterread(const sender: TObject); +begin + actionsmo.forcezorderact.checked:= projectoptions.s.forcezorder; +end; + +procedure tmainfo.basedockpaintexe(const sender: twidget; + const acanvas: tcanvas); +begin + paintdockingareacaption(acanvas,sender,mainfo.c[ord(dockingarea)]); +end; + +end. diff --git a/mseide-msegui/apps/ide/main_mfm.pas b/mseide-msegui/apps/ide/main_mfm.pas new file mode 100644 index 0000000..d29c2be --- /dev/null +++ b/mseide-msegui/apps/ide/main_mfm.pas @@ -0,0 +1,1950 @@ +unit main_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,main; + +const + objdata: record size: integer; data: array[0..38640] of byte end = + (size: 38641; data: ( + 84,80,70,48,7,116,109,97,105,110,102,111,6,109,97,105,110,102,111,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,11,111,119,95,115,117,98,102,111,99,117,115, + 17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,9,111, + 119,95,104,105,110,116,111,110,0,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,15,102,114,97,109,101,46,103,114,105,112,95, + 115,105,122,101,2,10,18,102,114,97,109,101,46,103,114,105,112,95,111,112, + 116,105,111,110,115,11,16,103,111,95,102,105,120,115,105,122,101,98,117,116, + 116,111,110,14,103,111,95,102,108,111,97,116,98,117,116,116,111,110,12,103, + 111,95,116,111,112,98,117,116,116,111,110,19,103,111,95,98,97,99,107,103, + 114,111,117,110,100,98,117,116,116,111,110,13,103,111,95,108,111,99,107,98, + 117,116,116,111,110,15,103,111,95,110,111,108,111,99,107,98,117,116,116,111, + 110,14,103,111,95,98,117,116,116,111,110,104,105,110,116,115,0,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,228,2,8,98, + 111,117,110,100,115,95,121,3,149,0,9,98,111,117,110,100,115,95,99,120, + 3,203,1,9,98,111,117,110,100,115,95,99,121,3,149,0,23,99,111,110, + 116,97,105,110,101,114,46,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,11,111,119,95,115,117,98,102,111,99,117,115,19,111,119,95,109,111,117, + 115,101,116,114,97,110,115,112,97,114,101,110,116,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,27,99,111,110,116,97,105,110, + 101,114,46,102,114,97,109,101,46,102,114,97,109,101,105,95,108,101,102,116, + 2,0,26,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,102, + 114,97,109,101,105,95,116,111,112,2,0,28,99,111,110,116,97,105,110,101, + 114,46,102,114,97,109,101,46,102,114,97,109,101,105,95,114,105,103,104,116, + 2,0,29,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,102, + 114,97,109,101,105,95,98,111,116,116,111,109,2,0,26,99,111,110,116,97, + 105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,114,108,95,102,105,108,101,102,116,9,102,114,108,95,102,105, + 116,111,112,11,102,114,108,95,102,105,114,105,103,104,116,12,102,114,108,95, + 102,105,98,111,116,116,111,109,0,27,99,111,110,116,97,105,110,101,114,46, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,30, + 99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,115,98,104,111, + 114,122,46,111,112,116,105,111,110,115,11,12,115,98,111,95,109,111,118,101, + 97,117,116,111,12,115,98,111,95,115,104,111,119,97,117,116,111,0,30,99, + 111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,115,98,118,101,114, + 116,46,111,112,116,105,111,110,115,11,12,115,98,111,95,109,111,118,101,97, + 117,116,111,12,115,98,111,95,115,104,111,119,97,117,116,111,0,18,99,111, + 110,116,97,105,110,101,114,46,111,110,108,97,121,111,117,116,7,7,111,110, + 115,99,97,108,101,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110, + 100,115,1,2,0,2,16,3,193,1,3,133,0,0,20,100,114,97,103,100, + 111,99,107,46,111,112,116,105,111,110,115,100,111,99,107,11,10,111,100,95, + 115,97,118,101,112,111,115,13,111,100,95,115,97,118,101,122,111,114,100,101, + 114,10,111,100,95,99,97,110,109,111,118,101,10,111,100,95,99,97,110,115, + 105,122,101,11,111,100,95,99,97,110,102,108,111,97,116,10,111,100,95,99, + 97,110,100,111,99,107,14,111,100,95,99,97,112,116,105,111,110,104,105,110, + 116,0,24,100,114,97,103,100,111,99,107,46,111,112,116,105,111,110,115,100, + 111,99,107,102,111,114,109,11,8,111,100,102,95,109,97,105,110,14,111,100, + 102,95,99,104,105,108,100,105,99,111,110,115,0,13,111,112,116,105,111,110, + 115,119,105,110,100,111,119,11,10,119,111,95,116,97,115,107,98,97,114,0, + 8,109,97,105,110,109,101,110,117,7,9,109,97,105,110,109,101,110,117,49, + 7,111,112,116,105,111,110,115,11,7,102,111,95,109,97,105,110,19,102,111, + 95,116,101,114,109,105,110,97,116,101,111,110,99,108,111,115,101,18,102,111, + 95,103,108,111,98,97,108,115,104,111,114,116,99,117,116,115,10,102,111,95, + 115,97,118,101,112,111,115,13,102,111,95,115,97,118,101,122,111,114,100,101, + 114,12,102,111,95,115,97,118,101,115,116,97,116,101,0,8,115,116,97,116, + 102,105,108,101,7,15,112,114,111,106,101,99,116,115,116,97,116,102,105,108, + 101,7,99,97,112,116,105,111,110,6,6,77,83,69,105,100,101,8,111,110, + 99,114,101,97,116,101,7,14,109,97,105,110,102,111,111,110,99,114,101,97, + 116,101,16,111,110,101,118,101,110,116,108,111,111,112,115,116,97,114,116,7, + 12,109,97,105,110,111,110,108,111,97,100,101,100,9,111,110,100,101,115,116, + 114,111,121,7,15,109,97,105,110,102,111,111,110,100,101,115,116,114,111,121, + 16,111,110,116,101,114,109,105,110,97,116,101,113,117,101,114,121,7,17,109, + 97,105,110,102,111,111,110,116,101,114,109,105,110,97,116,101,8,111,110,108, + 97,121,111,117,116,7,7,111,110,115,99,97,108,101,4,108,101,102,116,2, + 8,3,116,111,112,2,80,15,109,111,100,117,108,101,99,108,97,115,115,110, + 97,109,101,6,9,116,100,111,99,107,102,111,114,109,0,10,116,100,111,99, + 107,112,97,110,101,108,8,98,97,115,101,100,111,99,107,14,111,112,116,105, + 111,110,115,119,105,100,103,101,116,49,11,13,111,119,49,95,97,117,116,111, + 115,99,97,108,101,24,111,119,49,95,110,111,112,97,114,101,110,116,104,101, + 105,103,104,116,101,120,116,101,110,100,0,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,98,97,99,107,103,114,111,117,110,100, + 13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95,100,101,115,116, + 114,111,121,119,105,100,103,101,116,115,0,7,111,110,112,97,105,110,116,7, + 16,98,97,115,101,100,111,99,107,112,97,105,110,116,101,120,101,8,98,111, + 117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,19,9, + 98,111,117,110,100,115,95,99,120,3,193,1,9,98,111,117,110,100,115,95, + 99,121,2,114,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112, + 9,97,110,95,98,111,116,116,111,109,0,20,100,114,97,103,100,111,99,107, + 46,111,112,116,105,111,110,115,100,111,99,107,11,14,111,100,95,97,99,99, + 101,112,116,115,100,111,99,107,12,111,100,95,115,112,108,105,116,118,101,114, + 116,12,111,100,95,115,112,108,105,116,104,111,114,122,8,111,100,95,116,97, + 98,101,100,15,111,100,95,112,114,111,112,111,114,116,105,111,110,97,108,13, + 111,100,95,98,97,99,107,103,114,111,117,110,100,14,111,100,95,99,97,112, + 116,105,111,110,104,105,110,116,0,8,115,116,97,116,102,105,108,101,7,15, + 112,114,111,106,101,99,116,115,116,97,116,102,105,108,101,0,0,11,116,115, + 116,114,105,110,103,100,105,115,112,8,115,116,97,116,100,105,115,112,13,111, + 112,116,105,111,110,115,119,105,100,103,101,116,11,15,111,119,95,97,114,114, + 111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111, + 99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100, + 103,101,116,115,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,15,102,114,108,95,99,111,108,111,114,99,108,105,101, + 110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100, + 115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,1,9,98,111,117, + 110,100,115,95,99,120,3,193,1,9,98,111,117,110,100,115,95,99,121,2, + 18,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,0,9,102, + 111,110,116,46,110,97,109,101,6,11,115,116,102,95,100,101,102,97,117,108, + 116,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115,99, + 97,108,101,0,7,111,112,116,105,111,110,115,11,19,100,119,111,95,104,105, + 110,116,99,108,105,112,112,101,100,116,101,120,116,0,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,14,0,0,6,116,103,100,98,109,105,3, + 103,100,98,7,103,117,105,105,110,116,102,9,11,103,100,98,100,111,119,110, + 108,111,97,100,8,9,115,105,109,117,108,97,116,111,114,8,11,115,116,97, + 114,116,117,112,98,107,112,116,2,0,13,115,116,97,114,116,117,112,98,107, + 112,116,111,110,8,7,111,110,101,118,101,110,116,7,10,103,100,98,111,110, + 101,118,101,110,116,15,111,118,101,114,108,111,97,100,115,108,101,101,112,117, + 115,3,16,39,4,108,101,102,116,2,120,3,116,111,112,2,32,0,0,9, + 116,115,116,97,116,102,105,108,101,12,109,97,105,110,115,116,97,116,102,105, + 108,101,8,102,105,108,101,110,97,109,101,6,10,109,115,101,105,100,101,46, + 115,116,97,7,102,105,108,101,100,105,114,6,11,34,94,47,46,109,115,101, + 105,100,101,34,7,111,112,116,105,111,110,115,11,14,115,102,111,95,99,114, + 101,97,116,101,112,97,116,104,15,115,102,111,95,116,114,97,110,115,97,99, + 116,105,111,110,17,115,102,111,95,97,99,116,105,118,97,116,111,114,114,101, + 97,100,18,115,102,111,95,97,99,116,105,118,97,116,111,114,119,114,105,116, + 101,0,12,111,110,115,116,97,116,117,112,100,97,116,101,7,24,109,97,105, + 110,115,116,97,116,102,105,108,101,111,110,117,112,100,97,116,101,115,116,97, + 116,17,111,110,115,116,97,116,98,101,102,111,114,101,119,114,105,116,101,7, + 22,109,97,105,110,115,116,97,116,98,101,102,111,114,101,119,114,105,116,101, + 101,120,101,3,116,111,112,2,32,0,0,9,116,109,97,105,110,109,101,110, + 117,9,109,97,105,110,109,101,110,117,49,7,111,112,116,105,111,110,115,11, + 16,109,111,95,115,104,111,114,116,99,117,116,114,105,103,104,116,11,109,111, + 95,97,99,116,105,118,97,116,101,15,109,111,95,117,112,100,97,116,101,111, + 110,105,100,108,101,0,8,111,110,117,112,100,97,116,101,7,16,109,97,105, + 110,109,101,110,117,111,110,117,112,100,97,116,101,18,109,101,110,117,46,115, + 117,98,109,101,110,117,46,99,111,117,110,116,2,7,18,109,101,110,117,46, + 115,117,98,109,101,110,117,46,105,116,101,109,115,14,1,13,115,117,98,109, + 101,110,117,46,99,111,117,110,116,2,10,13,115,117,98,109,101,110,117,46, + 105,116,101,109,115,14,1,13,115,117,98,109,101,110,117,46,99,111,117,110, + 116,2,1,13,115,117,98,109,101,110,117,46,105,116,101,109,115,14,1,13, + 115,117,98,109,101,110,117,46,99,111,117,110,116,2,9,13,115,117,98,109, + 101,110,117,46,105,116,101,109,115,14,1,7,99,97,112,116,105,111,110,6, + 9,38,77,97,105,110,102,111,114,109,5,115,116,97,116,101,11,15,97,115, + 95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99, + 97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117, + 116,101,7,16,110,101,119,102,111,114,109,111,110,101,120,101,99,117,116,101, + 0,1,7,99,97,112,116,105,111,110,6,12,38,83,105,109,112,108,101,32, + 70,111,114,109,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,11,97,115,95,108,111,99,97,108,116,97,103,17, + 97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,7,111, + 112,116,105,111,110,115,11,19,109,97,111,95,115,104,111,114,116,99,117,116, + 99,97,112,116,105,111,110,16,109,97,111,95,97,115,121,110,99,101,120,101, + 99,117,116,101,0,3,116,97,103,2,1,9,111,110,101,120,101,99,117,116, + 101,7,16,110,101,119,102,111,114,109,111,110,101,120,101,99,117,116,101,0, + 1,7,99,97,112,116,105,111,110,6,13,38,68,111,99,107,105,110,103,32, + 70,111,114,109,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,11,97,115,95,108,111,99,97,108,116,97,103,17, + 97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,7,111, + 112,116,105,111,110,115,11,19,109,97,111,95,115,104,111,114,116,99,117,116, + 99,97,112,116,105,111,110,16,109,97,111,95,97,115,121,110,99,101,120,101, + 99,117,116,101,0,3,116,97,103,2,2,9,111,110,101,120,101,99,117,116, + 101,7,16,110,101,119,102,111,114,109,111,110,101,120,101,99,117,116,101,0, + 1,7,99,97,112,116,105,111,110,6,11,68,38,97,116,97,109,111,100,117, + 108,101,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97, + 112,116,105,111,110,11,97,115,95,108,111,99,97,108,116,97,103,17,97,115, + 95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,7,111,112,116, + 105,111,110,115,11,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97, + 112,116,105,111,110,16,109,97,111,95,97,115,121,110,99,101,120,101,99,117, + 116,101,0,3,116,97,103,2,3,9,111,110,101,120,101,99,117,116,101,7, + 16,110,101,119,102,111,114,109,111,110,101,120,101,99,117,116,101,0,1,7, + 99,97,112,116,105,111,110,6,8,83,38,117,98,102,111,114,109,5,115,116, + 97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110, + 11,97,115,95,108,111,99,97,108,116,97,103,17,97,115,95,108,111,99,97, + 108,111,110,101,120,101,99,117,116,101,0,3,116,97,103,2,4,9,111,110, + 101,120,101,99,117,116,101,7,16,110,101,119,102,111,114,109,111,110,101,120, + 101,99,117,116,101,0,1,7,99,97,112,116,105,111,110,6,7,38,82,101, + 112,111,114,116,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,11,97,115,95,108,111,99,97,108,116,97,103,17, + 97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,3,116, + 97,103,2,5,9,111,110,101,120,101,99,117,116,101,7,16,110,101,119,102, + 111,114,109,111,110,101,120,101,99,117,116,101,0,1,7,99,97,112,116,105, + 111,110,6,11,83,38,99,114,105,112,116,102,111,114,109,4,110,97,109,101, + 6,8,112,97,115,99,102,111,114,109,5,115,116,97,116,101,11,15,97,115, + 95,108,111,99,97,108,99,97,112,116,105,111,110,11,97,115,95,108,111,99, + 97,108,116,97,103,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99, + 117,116,101,0,3,116,97,103,2,6,9,111,110,101,120,101,99,117,116,101, + 7,16,110,101,119,102,111,114,109,111,110,101,120,101,99,117,116,101,0,1, + 7,111,112,116,105,111,110,115,11,13,109,97,111,95,115,101,112,97,114,97, + 116,111,114,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116, + 105,111,110,0,0,1,7,99,97,112,116,105,111,110,6,10,38,73,110,104, + 101,114,105,116,101,100,5,115,116,97,116,101,11,15,97,115,95,108,111,99, + 97,108,99,97,112,116,105,111,110,11,97,115,95,108,111,99,97,108,116,97, + 103,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0, + 3,116,97,103,2,7,9,111,110,101,120,101,99,117,116,101,7,16,110,101, + 119,102,111,114,109,111,110,101,120,101,99,117,116,101,0,0,7,99,97,112, + 116,105,111,110,6,5,38,70,111,114,109,4,110,97,109,101,6,4,102,111, + 114,109,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97, + 112,116,105,111,110,0,0,0,7,99,97,112,116,105,111,110,6,4,38,78, + 101,119,4,110,97,109,101,6,3,110,101,119,5,115,116,97,116,101,11,15, + 97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,0,1,6,97, + 99,116,105,111,110,7,20,97,99,116,105,111,110,115,109,111,46,111,112,101, + 110,115,111,117,114,99,101,0,1,6,97,99,116,105,111,110,7,14,97,99, + 116,105,111,110,115,109,111,46,115,97,118,101,0,1,6,97,99,116,105,111, + 110,7,16,97,99,116,105,111,110,115,109,111,46,115,97,118,101,97,115,0, + 1,6,97,99,116,105,111,110,7,17,97,99,116,105,111,110,115,109,111,46, + 115,97,118,101,97,108,108,0,1,6,97,99,116,105,111,110,7,15,97,99, + 116,105,111,110,115,109,111,46,99,108,111,115,101,0,1,6,97,99,116,105, + 111,110,7,18,97,99,116,105,111,110,115,109,111,46,99,108,111,115,101,97, + 108,108,0,1,7,111,112,116,105,111,110,115,11,13,109,97,111,95,115,101, + 112,97,114,97,116,111,114,19,109,97,111,95,115,104,111,114,116,99,117,116, + 99,97,112,116,105,111,110,0,0,1,6,97,99,116,105,111,110,7,15,97, + 99,116,105,111,110,115,109,111,46,112,114,105,110,116,0,1,7,99,97,112, + 116,105,111,110,6,5,69,38,120,105,116,5,115,116,97,116,101,11,15,97, + 115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111, + 99,97,108,111,110,101,120,101,99,117,116,101,0,7,111,112,116,105,111,110, + 115,11,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105, + 111,110,16,109,97,111,95,97,115,121,110,99,101,120,101,99,117,116,101,0, + 9,111,110,101,120,101,99,117,116,101,7,13,101,120,105,116,111,110,101,120, + 101,99,117,116,101,0,0,7,99,97,112,116,105,111,110,6,5,38,70,105, + 108,101,4,110,97,109,101,6,4,102,105,108,101,5,115,116,97,116,101,11, + 15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,0,1,13, + 115,117,98,109,101,110,117,46,99,111,117,110,116,2,7,13,115,117,98,109, + 101,110,117,46,105,116,101,109,115,14,1,6,97,99,116,105,111,110,7,14, + 97,99,116,105,111,110,115,109,111,46,108,105,110,101,0,1,6,97,99,116, + 105,111,110,7,14,97,99,116,105,111,110,115,109,111,46,102,105,110,100,0, + 1,6,97,99,116,105,111,110,7,20,97,99,116,105,111,110,115,109,111,46, + 114,101,112,101,97,116,102,105,110,100,0,1,6,97,99,116,105,111,110,7, + 18,97,99,116,105,111,110,115,109,111,46,102,105,110,100,98,97,99,107,0, + 1,6,97,99,116,105,111,110,7,17,97,99,116,105,111,110,115,109,111,46, + 114,101,112,108,97,99,101,0,1,6,97,99,116,105,111,110,7,20,97,99, + 116,105,111,110,115,109,111,46,102,105,110,100,105,110,102,105,108,101,0,1, + 6,97,99,116,105,111,110,7,24,97,99,116,105,111,110,115,109,111,46,102, + 105,110,100,99,111,109,112,97,108,108,97,99,116,7,99,97,112,116,105,111, + 110,6,15,70,105,110,100,32,38,67,111,109,112,111,110,101,110,116,5,115, + 116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111, + 110,16,97,115,95,108,111,99,97,108,115,104,111,114,116,99,117,116,17,97, + 115,95,108,111,99,97,108,115,104,111,114,116,99,117,116,49,0,0,0,7, + 99,97,112,116,105,111,110,6,7,38,83,101,97,114,99,104,4,110,97,109, + 101,6,6,115,101,97,114,99,104,5,115,116,97,116,101,11,15,97,115,95, + 108,111,99,97,108,99,97,112,116,105,111,110,0,0,1,13,115,117,98,109, + 101,110,117,46,99,111,117,110,116,2,15,13,115,117,98,109,101,110,117,46, + 105,116,101,109,115,14,1,6,97,99,116,105,111,110,7,24,97,99,116,105, + 111,110,115,109,111,46,115,101,108,101,99,116,101,100,105,116,112,97,103,101, + 0,1,7,111,112,116,105,111,110,115,11,13,109,97,111,95,115,101,112,97, + 114,97,116,111,114,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97, + 112,116,105,111,110,0,0,1,6,97,99,116,105,111,110,7,14,97,99,116, + 105,111,110,115,109,111,46,117,110,100,111,0,1,6,97,99,116,105,111,110, + 7,14,97,99,116,105,111,110,115,109,111,46,114,101,100,111,0,1,7,111, + 112,116,105,111,110,115,11,13,109,97,111,95,115,101,112,97,114,97,116,111, + 114,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111, + 110,0,0,1,6,97,99,116,105,111,110,7,14,97,99,116,105,111,110,115, + 109,111,46,99,111,112,121,0,1,6,97,99,116,105,111,110,7,22,97,99, + 116,105,111,110,115,109,111,46,99,111,112,121,108,97,116,101,120,97,99,116, + 0,1,6,97,99,116,105,111,110,7,18,97,99,116,105,111,110,115,109,111, + 46,99,111,112,121,119,111,114,100,0,1,6,97,99,116,105,111,110,7,13, + 97,99,116,105,111,110,115,109,111,46,99,117,116,0,1,6,97,99,116,105, + 111,110,7,15,97,99,116,105,111,110,115,109,111,46,112,97,115,116,101,0, + 1,6,97,99,116,105,111,110,7,16,97,99,116,105,111,110,115,109,111,46, + 100,101,108,101,116,101,0,1,6,97,99,116,105,111,110,7,19,97,99,116, + 105,111,110,115,109,111,46,115,101,108,101,99,116,97,108,108,0,1,7,111, + 112,116,105,111,110,115,11,13,109,97,111,95,115,101,112,97,114,97,116,111, + 114,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111, + 110,0,0,1,6,97,99,116,105,111,110,7,16,97,99,116,105,111,110,115, + 109,111,46,105,110,100,101,110,116,0,1,6,97,99,116,105,111,110,7,18, + 97,99,116,105,111,110,115,109,111,46,117,110,105,110,100,101,110,116,0,0, + 7,99,97,112,116,105,111,110,6,5,38,69,100,105,116,4,110,97,109,101, + 6,4,101,100,105,116,5,115,116,97,116,101,11,15,97,115,95,108,111,99, + 97,108,99,97,112,116,105,111,110,0,0,1,13,115,117,98,109,101,110,117, + 46,99,111,117,110,116,2,22,13,115,117,98,109,101,110,117,46,105,116,101, + 109,115,14,1,7,99,97,112,116,105,111,110,6,12,69,110,38,118,105,114, + 111,110,109,101,110,116,5,115,116,97,116,101,11,15,97,115,95,108,111,99, + 97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,105,109, + 97,103,101,108,105,115,116,17,97,115,95,108,111,99,97,108,111,110,101,120, + 101,99,117,116,101,0,9,105,109,97,103,101,108,105,115,116,7,14,100,117, + 109,109,121,105,109,97,103,101,108,105,115,116,9,111,110,101,120,101,99,117, + 116,101,7,19,112,97,114,97,109,101,116,101,114,115,111,110,101,120,101,99, + 117,116,101,0,1,7,99,97,112,116,105,111,110,6,16,82,101,115,116,97, + 114,116,32,68,101,98,117,103,103,101,114,5,115,116,97,116,101,11,15,97, + 115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111, + 99,97,108,105,109,97,103,101,108,105,115,116,17,97,115,95,108,111,99,97, + 108,111,110,101,120,101,99,117,116,101,0,9,105,109,97,103,101,108,105,115, + 116,7,14,100,117,109,109,121,105,109,97,103,101,108,105,115,116,9,111,110, + 101,120,101,99,117,116,101,7,19,114,101,115,116,97,114,116,103,100,98,111, + 110,101,120,101,99,117,116,101,0,1,6,97,99,116,105,111,110,7,23,97, + 99,116,105,111,110,115,109,111,46,97,116,116,97,99,104,112,114,111,99,101, + 115,115,5,115,116,97,116,101,11,17,97,115,95,108,111,99,97,108,105,109, + 97,103,101,108,105,115,116,0,9,105,109,97,103,101,108,105,115,116,7,14, + 100,117,109,109,121,105,109,97,103,101,108,105,115,116,0,1,6,97,99,116, + 105,111,110,7,22,97,99,116,105,111,110,115,109,111,46,97,116,116,97,99, + 104,116,97,114,103,101,116,5,115,116,97,116,101,11,17,97,115,95,108,111, + 99,97,108,105,109,97,103,101,108,105,115,116,0,9,105,109,97,103,101,108, + 105,115,116,7,14,100,117,109,109,121,105,109,97,103,101,108,105,115,116,0, + 1,6,97,99,116,105,111,110,7,22,97,99,116,105,111,110,115,109,111,46, + 100,101,116,97,99,104,116,97,114,103,101,116,5,115,116,97,116,101,11,17, + 97,115,95,108,111,99,97,108,105,109,97,103,101,108,105,115,116,0,9,105, + 109,97,103,101,108,105,115,116,7,14,100,117,109,109,121,105,109,97,103,101, + 108,105,115,116,0,1,6,97,99,116,105,111,110,7,18,97,99,116,105,111, + 110,115,109,111,46,100,111,119,110,108,111,97,100,5,115,116,97,116,101,11, + 17,97,115,95,108,111,99,97,108,105,109,97,103,101,108,105,115,116,0,9, + 105,109,97,103,101,108,105,115,116,7,14,100,117,109,109,121,105,109,97,103, + 101,108,105,115,116,0,1,7,111,112,116,105,111,110,115,11,13,109,97,111, + 95,115,101,112,97,114,97,116,111,114,19,109,97,111,95,115,104,111,114,116, + 99,117,116,99,97,112,116,105,111,110,0,0,1,6,97,99,116,105,111,110, + 7,18,97,99,116,105,111,110,115,109,111,46,99,111,110,116,105,110,117,101, + 0,1,6,97,99,116,105,111,110,7,15,97,99,116,105,111,110,115,109,111, + 46,114,101,115,101,116,0,1,6,97,99,116,105,111,110,7,19,97,99,116, + 105,111,110,115,109,111,46,105,110,116,101,114,114,117,112,116,0,1,6,97, + 99,116,105,111,110,7,14,97,99,116,105,111,110,115,109,111,46,115,116,101, + 112,0,1,6,97,99,116,105,111,110,7,15,97,99,116,105,111,110,115,109, + 111,46,115,116,101,112,105,0,1,6,97,99,116,105,111,110,7,14,97,99, + 116,105,111,110,115,109,111,46,110,101,120,116,0,1,6,97,99,116,105,111, + 110,7,15,97,99,116,105,111,110,115,109,111,46,110,101,120,116,105,0,1, + 6,97,99,116,105,111,110,7,16,97,99,116,105,111,110,115,109,111,46,102, + 105,110,105,115,104,0,1,7,111,112,116,105,111,110,115,11,13,109,97,111, + 95,115,101,112,97,114,97,116,111,114,19,109,97,111,95,115,104,111,114,116, + 99,117,116,99,97,112,116,105,111,110,0,0,1,6,97,99,116,105,111,110, + 7,20,97,99,116,105,111,110,115,109,111,46,98,107,112,116,115,111,110,97, + 99,116,5,115,116,97,116,101,11,10,97,115,95,99,104,101,99,107,101,100, + 0,7,111,112,116,105,111,110,115,11,12,109,97,111,95,99,104,101,99,107, + 98,111,120,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116, + 105,111,110,0,0,1,6,97,99,116,105,111,110,7,20,97,99,116,105,111, + 110,115,109,111,46,116,111,103,103,108,101,98,107,112,116,5,115,116,97,116, + 101,11,17,97,115,95,108,111,99,97,108,105,109,97,103,101,108,105,115,116, + 0,9,105,109,97,103,101,108,105,115,116,7,14,100,117,109,109,121,105,109, + 97,103,101,108,105,115,116,0,1,6,97,99,116,105,111,110,7,26,97,99, + 116,105,111,110,115,109,111,46,116,111,103,103,108,101,98,107,112,116,101,110, + 97,98,108,101,5,115,116,97,116,101,11,17,97,115,95,108,111,99,97,108, + 105,109,97,103,101,108,105,115,116,0,9,105,109,97,103,101,108,105,115,116, + 7,14,100,117,109,109,121,105,109,97,103,101,108,105,115,116,0,1,7,111, + 112,116,105,111,110,115,11,13,109,97,111,95,115,101,112,97,114,97,116,111, + 114,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111, + 110,0,0,1,6,97,99,116,105,111,110,7,22,97,99,116,105,111,110,115, + 109,111,46,119,97,116,99,104,101,115,111,110,97,99,116,5,115,116,97,116, + 101,11,10,97,115,95,99,104,101,99,107,101,100,0,7,111,112,116,105,111, + 110,115,11,12,109,97,111,95,99,104,101,99,107,98,111,120,19,109,97,111, + 95,115,104,111,114,116,99,117,116,99,97,112,116,105,111,110,0,0,1,6, + 97,99,116,105,111,110,7,23,97,99,116,105,111,110,115,109,111,46,98,108, + 117,101,100,111,116,115,111,110,97,99,116,5,115,116,97,116,101,11,10,97, + 115,95,99,104,101,99,107,101,100,0,7,111,112,116,105,111,110,115,11,12, + 109,97,111,95,99,104,101,99,107,98,111,120,19,109,97,111,95,115,104,111, + 114,116,99,117,116,99,97,112,116,105,111,110,0,0,0,7,99,97,112,116, + 105,111,110,6,7,38,84,97,114,103,101,116,4,110,97,109,101,6,6,116, + 97,114,103,101,116,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,0,0,1,13,115,117,98,109,101,110,117,46, + 99,111,117,110,116,2,28,13,115,117,98,109,101,110,117,46,105,116,101,109, + 115,14,1,13,115,117,98,109,101,110,117,46,99,111,117,110,116,2,2,13, + 115,117,98,109,101,110,117,46,105,116,101,109,115,14,1,7,111,112,116,105, + 111,110,115,11,13,109,97,111,95,115,101,112,97,114,97,116,111,114,19,109, + 97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111,110,0,0, + 1,7,99,97,112,116,105,111,110,6,10,38,78,101,119,32,80,97,110,101, + 108,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112, + 116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117, + 116,101,0,9,111,110,101,120,101,99,117,116,101,7,17,110,101,119,112,97, + 110,101,108,111,110,101,120,101,99,117,116,101,0,0,7,99,97,112,116,105, + 111,110,6,7,80,97,110,38,101,108,115,4,110,97,109,101,6,6,112,97, + 110,101,108,115,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,105,109,97,103, + 101,108,105,115,116,15,97,115,95,108,111,99,97,108,105,109,97,103,101,110, + 114,0,9,105,109,97,103,101,108,105,115,116,7,13,118,105,101,118,109,101, + 110,117,105,99,111,110,115,7,105,109,97,103,101,110,114,2,0,0,1,6, + 97,99,116,105,111,110,7,24,97,99,116,105,111,110,115,109,111,46,102,111, + 114,99,101,122,111,114,100,101,114,97,99,116,5,115,116,97,116,101,11,17, + 97,115,95,108,111,99,97,108,105,109,97,103,101,108,105,115,116,0,7,111, + 112,116,105,111,110,115,11,12,109,97,111,95,99,104,101,99,107,98,111,120, + 19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111,110, + 0,9,105,109,97,103,101,108,105,115,116,7,13,118,105,101,118,109,101,110, + 117,105,99,111,110,115,0,1,7,99,97,112,116,105,111,110,6,19,76,111, + 97,100,32,87,105,38,110,100,111,119,32,76,97,121,111,117,116,5,115,116, + 97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110, + 17,97,115,95,108,111,99,97,108,105,109,97,103,101,108,105,115,116,17,97, + 115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,105,109, + 97,103,101,108,105,115,116,7,13,118,105,101,118,109,101,110,117,105,99,111, + 110,115,9,111,110,101,120,101,99,117,116,101,7,19,108,111,97,100,119,105, + 110,100,111,119,108,97,121,111,117,116,101,120,101,0,1,7,111,112,116,105, + 111,110,115,11,13,109,97,111,95,115,101,112,97,114,97,116,111,114,19,109, + 97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111,110,0,0, + 1,7,99,97,112,116,105,111,110,6,18,67,111,109,112,111,110,101,110,116, + 32,38,80,97,108,101,116,116,101,5,115,116,97,116,101,11,15,97,115,95, + 108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97, + 108,105,109,97,103,101,108,105,115,116,15,97,115,95,108,111,99,97,108,105, + 109,97,103,101,110,114,17,97,115,95,108,111,99,97,108,111,110,101,120,101, + 99,117,116,101,0,9,105,109,97,103,101,108,105,115,116,7,13,118,105,101, + 118,109,101,110,117,105,99,111,110,115,7,105,109,97,103,101,110,114,2,1, + 9,111,110,101,120,101,99,117,116,101,7,29,118,105,101,119,99,111,109,112, + 111,110,101,110,116,112,97,108,101,116,116,101,111,110,101,120,101,99,117,116, + 101,0,1,7,99,97,112,116,105,111,110,6,16,67,111,109,112,111,110,101, + 110,116,32,83,116,111,38,114,101,5,115,116,97,116,101,11,15,97,115,95, + 108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97, + 108,105,109,97,103,101,108,105,115,116,15,97,115,95,108,111,99,97,108,105, + 109,97,103,101,110,114,17,97,115,95,108,111,99,97,108,111,110,101,120,101, + 99,117,116,101,0,9,105,109,97,103,101,108,105,115,116,7,13,118,105,101, + 118,109,101,110,117,105,99,111,110,115,7,105,109,97,103,101,110,114,2,16, + 9,111,110,101,120,101,99,117,116,101,7,27,118,105,101,119,99,111,109,112, + 111,110,101,110,116,115,116,111,114,101,111,110,101,120,101,99,117,116,101,0, + 1,7,99,97,112,116,105,111,110,6,17,79,98,106,101,99,116,32,38,73, + 110,115,112,101,99,116,111,114,5,115,116,97,116,101,11,15,97,115,95,108, + 111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108, + 105,109,97,103,101,108,105,115,116,15,97,115,95,108,111,99,97,108,105,109, + 97,103,101,110,114,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99, + 117,116,101,0,9,105,109,97,103,101,108,105,115,116,7,13,118,105,101,118, + 109,101,110,117,105,99,111,110,115,7,105,109,97,103,101,110,114,2,14,9, + 111,110,101,120,101,99,117,116,101,7,28,118,105,101,119,111,98,106,101,99, + 116,105,110,115,112,101,99,116,111,114,111,110,101,120,101,99,117,116,101,0, + 1,7,111,112,116,105,111,110,115,11,13,109,97,111,95,115,101,112,97,114, + 97,116,111,114,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112, + 116,105,111,110,0,0,1,7,99,97,112,116,105,111,110,6,7,83,111,38, + 117,114,99,101,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,105,109,97,103, + 101,108,105,115,116,15,97,115,95,108,111,99,97,108,105,109,97,103,101,110, + 114,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0, + 7,111,112,116,105,111,110,115,11,19,109,97,111,95,115,104,111,114,116,99, + 117,116,99,97,112,116,105,111,110,16,109,97,111,95,97,115,121,110,99,101, + 120,101,99,117,116,101,0,9,105,109,97,103,101,108,105,115,116,7,13,118, + 105,101,118,109,101,110,117,105,99,111,110,115,7,105,109,97,103,101,110,114, + 2,5,9,111,110,101,120,101,99,117,116,101,7,19,118,105,101,119,115,111, + 117,114,99,101,111,110,101,120,101,99,117,116,101,0,1,7,99,97,112,116, + 105,111,110,6,9,38,77,101,115,115,97,103,101,115,5,115,116,97,116,101, + 11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115, + 95,108,111,99,97,108,105,109,97,103,101,108,105,115,116,15,97,115,95,108, + 111,99,97,108,105,109,97,103,101,110,114,17,97,115,95,108,111,99,97,108, + 111,110,101,120,101,99,117,116,101,0,7,111,112,116,105,111,110,115,11,19, + 109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111,110,16, + 109,97,111,95,97,115,121,110,99,101,120,101,99,117,116,101,0,9,105,109, + 97,103,101,108,105,115,116,7,13,118,105,101,118,109,101,110,117,105,99,111, + 110,115,7,105,109,97,103,101,110,114,2,4,9,111,110,101,120,101,99,117, + 116,101,7,21,118,105,101,119,109,101,115,115,97,103,101,115,111,110,101,120, + 101,99,117,116,101,0,1,7,99,97,112,116,105,111,110,6,13,38,70,105, + 110,100,32,82,101,115,117,108,116,115,5,115,116,97,116,101,11,15,97,115, + 95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99, + 97,108,105,109,97,103,101,108,105,115,116,15,97,115,95,108,111,99,97,108, + 105,109,97,103,101,110,114,17,97,115,95,108,111,99,97,108,111,110,101,120, + 101,99,117,116,101,0,9,105,109,97,103,101,108,105,115,116,7,13,118,105, + 101,118,109,101,110,117,105,99,111,110,115,7,105,109,97,103,101,110,114,2, + 15,9,111,110,101,120,101,99,117,116,101,7,15,118,105,101,119,102,105,110, + 100,114,101,115,117,108,116,115,0,1,7,111,112,116,105,111,110,115,11,13, + 109,97,111,95,115,101,112,97,114,97,116,111,114,19,109,97,111,95,115,104, + 111,114,116,99,117,116,99,97,112,116,105,111,110,0,0,1,7,99,97,112, + 116,105,111,110,6,9,38,68,101,98,117,103,103,101,114,5,115,116,97,116, + 101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97, + 115,95,108,111,99,97,108,105,109,97,103,101,108,105,115,116,15,97,115,95, + 108,111,99,97,108,105,109,97,103,101,110,114,17,97,115,95,108,111,99,97, + 108,111,110,101,120,101,99,117,116,101,0,9,105,109,97,103,101,108,105,115, + 116,7,13,118,105,101,118,109,101,110,117,105,99,111,110,115,7,105,109,97, + 103,101,110,114,2,2,9,111,110,101,120,101,99,117,116,101,7,28,118,105, + 101,119,100,101,98,117,103,103,101,114,116,111,111,108,98,97,114,111,110,101, + 120,101,99,117,116,101,0,1,7,99,97,112,116,105,111,110,6,8,83,121, + 109,98,111,38,108,115,5,115,116,97,116,101,11,15,97,115,95,108,111,99, + 97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,105,109, + 97,103,101,108,105,115,116,15,97,115,95,108,111,99,97,108,105,109,97,103, + 101,110,114,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116, + 101,0,9,105,109,97,103,101,108,105,115,116,7,13,118,105,101,118,109,101, + 110,117,105,99,111,110,115,7,105,109,97,103,101,110,114,2,18,9,111,110, + 101,120,101,99,117,116,101,7,20,118,105,101,119,115,121,109,98,111,108,115, + 111,110,101,120,101,99,117,116,101,0,1,7,99,97,112,116,105,111,110,6, + 8,38,87,97,116,99,104,101,115,5,115,116,97,116,101,11,15,97,115,95, + 108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97, + 108,105,109,97,103,101,108,105,115,116,15,97,115,95,108,111,99,97,108,105, + 109,97,103,101,110,114,17,97,115,95,108,111,99,97,108,111,110,101,120,101, + 99,117,116,101,0,7,111,112,116,105,111,110,115,11,19,109,97,111,95,115, + 104,111,114,116,99,117,116,99,97,112,116,105,111,110,16,109,97,111,95,97, + 115,121,110,99,101,120,101,99,117,116,101,0,9,105,109,97,103,101,108,105, + 115,116,7,13,118,105,101,118,109,101,110,117,105,99,111,110,115,7,105,109, + 97,103,101,110,114,2,8,9,111,110,101,120,101,99,117,116,101,7,20,118, + 105,101,119,119,97,116,99,104,101,115,111,110,101,120,101,99,117,116,101,0, + 1,7,99,97,112,116,105,111,110,6,6,38,83,116,97,99,107,5,115,116, + 97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110, + 17,97,115,95,108,111,99,97,108,105,109,97,103,101,108,105,115,116,15,97, + 115,95,108,111,99,97,108,105,109,97,103,101,110,114,17,97,115,95,108,111, + 99,97,108,111,110,101,120,101,99,117,116,101,0,7,111,112,116,105,111,110, + 115,11,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105, + 111,110,16,109,97,111,95,97,115,121,110,99,101,120,101,99,117,116,101,0, + 9,105,109,97,103,101,108,105,115,116,7,13,118,105,101,118,109,101,110,117, + 105,99,111,110,115,7,105,109,97,103,101,110,114,2,9,9,111,110,101,120, + 101,99,117,116,101,7,18,118,105,101,119,115,116,97,99,107,111,110,101,120, + 101,99,117,116,101,0,1,7,99,97,112,116,105,111,110,6,8,84,38,104, + 114,101,97,100,115,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,105,109,97, + 103,101,108,105,115,116,15,97,115,95,108,111,99,97,108,105,109,97,103,101, + 110,114,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101, + 0,9,105,109,97,103,101,108,105,115,116,7,13,118,105,101,118,109,101,110, + 117,105,99,111,110,115,7,105,109,97,103,101,110,114,2,10,9,111,110,101, + 120,101,99,117,116,101,7,20,118,105,101,119,116,104,114,101,97,100,115,111, + 110,101,120,101,99,117,116,101,0,1,7,99,97,112,116,105,111,110,6,4, + 38,67,80,85,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,105,109,97,103, + 101,108,105,115,116,15,97,115,95,108,111,99,97,108,105,109,97,103,101,110, + 114,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0, + 9,105,109,97,103,101,108,105,115,116,7,13,118,105,101,118,109,101,110,117, + 105,99,111,110,115,7,105,109,97,103,101,110,114,2,11,9,111,110,101,120, + 101,99,117,116,101,7,16,118,105,101,119,99,112,117,111,110,101,120,101,99, + 117,116,101,0,1,7,99,97,112,116,105,111,110,6,10,38,65,115,115,101, + 109,98,108,101,114,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,105,109,97, + 103,101,108,105,115,116,15,97,115,95,108,111,99,97,108,105,109,97,103,101, + 110,114,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101, + 0,9,105,109,97,103,101,108,105,115,116,7,13,118,105,101,118,109,101,110, + 117,105,99,111,110,115,7,105,109,97,103,101,110,114,2,12,9,111,110,101, + 120,101,99,117,116,101,7,22,118,105,101,119,97,115,115,101,109,98,108,101, + 114,111,110,101,120,101,99,117,116,101,0,1,7,99,97,112,116,105,111,110, + 6,7,77,101,109,111,114,38,121,5,115,116,97,116,101,11,15,97,115,95, + 108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97, + 108,105,109,97,103,101,108,105,115,116,15,97,115,95,108,111,99,97,108,105, + 109,97,103,101,110,114,17,97,115,95,108,111,99,97,108,111,110,101,120,101, + 99,117,116,101,0,9,105,109,97,103,101,108,105,115,116,7,13,118,105,101, + 118,109,101,110,117,105,99,111,110,115,7,105,109,97,103,101,110,114,2,17, + 9,111,110,101,120,101,99,117,116,101,7,19,118,105,101,119,109,101,109,111, + 114,121,111,110,101,120,101,99,117,116,101,0,1,7,99,97,112,116,105,111, + 110,6,15,38,84,97,114,103,101,116,32,67,111,110,115,111,108,101,5,115, + 116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111, + 110,17,97,115,95,108,111,99,97,108,105,109,97,103,101,108,105,115,116,15, + 97,115,95,108,111,99,97,108,105,109,97,103,101,110,114,17,97,115,95,108, + 111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,105,109,97,103,101, + 108,105,115,116,7,13,118,105,101,118,109,101,110,117,105,99,111,110,115,7, + 105,109,97,103,101,110,114,2,13,9,111,110,101,120,101,99,117,116,101,7, + 20,118,105,101,119,99,111,110,115,111,108,101,111,110,101,120,101,99,117,116, + 101,0,1,7,111,112,116,105,111,110,115,11,13,109,97,111,95,115,101,112, + 97,114,97,116,111,114,19,109,97,111,95,115,104,111,114,116,99,117,116,99, + 97,112,116,105,111,110,0,0,1,7,99,97,112,116,105,111,110,6,12,38, + 66,114,101,97,107,112,111,105,110,116,115,5,115,116,97,116,101,11,15,97, + 115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111, + 99,97,108,105,109,97,103,101,108,105,115,116,15,97,115,95,108,111,99,97, + 108,105,109,97,103,101,110,114,17,97,115,95,108,111,99,97,108,111,110,101, + 120,101,99,117,116,101,0,7,111,112,116,105,111,110,115,11,19,109,97,111, + 95,115,104,111,114,116,99,117,116,99,97,112,116,105,111,110,16,109,97,111, + 95,97,115,121,110,99,101,120,101,99,117,116,101,0,9,105,109,97,103,101, + 108,105,115,116,7,13,118,105,101,118,109,101,110,117,105,99,111,110,115,7, + 105,109,97,103,101,110,114,2,6,9,111,110,101,120,101,99,117,116,101,7, + 24,118,105,101,119,98,114,101,97,107,112,111,105,110,116,115,111,110,101,120, + 101,99,117,116,101,0,1,7,99,97,112,116,105,111,110,6,12,87,97,116, + 99,104,112,38,111,105,110,116,115,5,115,116,97,116,101,11,15,97,115,95, + 108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97, + 108,105,109,97,103,101,108,105,115,116,15,97,115,95,108,111,99,97,108,105, + 109,97,103,101,110,114,17,97,115,95,108,111,99,97,108,111,110,101,120,101, + 99,117,116,101,0,9,105,109,97,103,101,108,105,115,116,7,13,118,105,101, + 118,109,101,110,117,105,99,111,110,115,7,105,109,97,103,101,110,114,2,7, + 9,111,110,101,120,101,99,117,116,101,7,24,118,105,101,119,119,97,116,99, + 104,112,111,105,110,116,115,111,110,101,120,101,99,117,116,101,0,1,7,111, + 112,116,105,111,110,115,11,13,109,97,111,95,115,101,112,97,114,97,116,111, + 114,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111, + 110,0,0,1,6,97,99,116,105,111,110,7,25,97,99,116,105,111,110,115, + 109,111,46,116,111,103,103,108,101,105,110,115,112,101,99,116,111,114,5,115, + 116,97,116,101,11,17,97,115,95,108,111,99,97,108,105,109,97,103,101,108, + 105,115,116,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116, + 101,0,7,111,112,116,105,111,110,115,11,19,109,97,111,95,115,104,111,114, + 116,99,117,116,99,97,112,116,105,111,110,16,109,97,111,95,97,115,121,110, + 99,101,120,101,99,117,116,101,0,9,105,109,97,103,101,108,105,115,116,7, + 13,118,105,101,118,109,101,110,117,105,99,111,110,115,9,111,110,101,120,101, + 99,117,116,101,7,30,116,111,103,103,108,101,111,98,106,101,99,116,105,110, + 115,112,101,99,116,111,114,111,110,101,120,101,99,117,116,101,0,1,6,97, + 99,116,105,111,110,7,24,97,99,116,105,111,110,115,109,111,46,116,111,103, + 103,108,101,102,111,114,109,117,110,105,116,7,99,97,112,116,105,111,110,6, + 16,84,111,103,103,108,101,32,70,111,114,109,47,85,110,105,116,5,115,116, + 97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110, + 17,97,115,95,108,111,99,97,108,105,109,97,103,101,108,105,115,116,0,7, + 111,112,116,105,111,110,115,11,19,109,97,111,95,115,104,111,114,116,99,117, + 116,99,97,112,116,105,111,110,16,109,97,111,95,97,115,121,110,99,101,120, + 101,99,117,116,101,0,9,105,109,97,103,101,108,105,115,116,7,13,118,105, + 101,118,109,101,110,117,105,99,111,110,115,0,1,4,110,97,109,101,6,17, + 102,111,114,109,109,101,110,117,105,116,101,109,115,116,97,114,116,7,111,112, + 116,105,111,110,115,11,13,109,97,111,95,115,101,112,97,114,97,116,111,114, + 19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111,110, + 0,0,0,7,99,97,112,116,105,111,110,6,5,38,86,105,101,119,4,110, + 97,109,101,6,4,118,105,101,119,5,115,116,97,116,101,11,15,97,115,95, + 108,111,99,97,108,99,97,112,116,105,111,110,0,0,1,13,115,117,98,109, + 101,110,117,46,99,111,117,110,116,2,19,13,115,117,98,109,101,110,117,46, + 105,116,101,109,115,14,1,6,97,99,116,105,111,110,7,17,97,99,116,105, + 111,110,115,109,111,46,109,97,107,101,97,99,116,7,99,97,112,116,105,111, + 110,6,5,38,77,97,107,101,5,115,116,97,116,101,11,15,97,115,95,108, + 111,99,97,108,99,97,112,116,105,111,110,11,97,115,95,108,111,99,97,108, + 116,97,103,0,3,116,97,103,2,1,0,1,6,97,99,116,105,111,110,7, + 18,97,99,116,105,111,110,115,109,111,46,98,117,105,108,100,97,99,116,7, + 99,97,112,116,105,111,110,6,6,38,66,117,105,108,100,5,115,116,97,116, + 101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,11,97, + 115,95,108,111,99,97,108,116,97,103,0,3,116,97,103,2,2,0,1,6, + 97,99,116,105,111,110,7,18,97,99,116,105,111,110,115,109,111,46,109,97, + 107,101,49,97,99,116,7,99,97,112,116,105,111,110,6,7,77,97,107,101, + 32,38,49,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99, + 97,112,116,105,111,110,11,97,115,95,108,111,99,97,108,116,97,103,0,3, + 116,97,103,2,4,0,1,6,97,99,116,105,111,110,7,18,97,99,116,105, + 111,110,115,109,111,46,109,97,107,101,50,97,99,116,7,99,97,112,116,105, + 111,110,6,7,77,97,107,101,32,38,50,5,115,116,97,116,101,11,15,97, + 115,95,108,111,99,97,108,99,97,112,116,105,111,110,11,97,115,95,108,111, + 99,97,108,116,97,103,0,3,116,97,103,2,8,0,1,6,97,99,116,105, + 111,110,7,18,97,99,116,105,111,110,115,109,111,46,109,97,107,101,51,97, + 99,116,7,99,97,112,116,105,111,110,6,7,77,97,107,101,32,38,51,5, + 115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105, + 111,110,11,97,115,95,108,111,99,97,108,116,97,103,0,3,116,97,103,2, + 16,0,1,6,97,99,116,105,111,110,7,18,97,99,116,105,111,110,115,109, + 111,46,109,97,107,101,52,97,99,116,7,99,97,112,116,105,111,110,6,7, + 77,97,107,101,32,38,52,5,115,116,97,116,101,11,15,97,115,95,108,111, + 99,97,108,99,97,112,116,105,111,110,11,97,115,95,108,111,99,97,108,116, + 97,103,0,3,116,97,103,2,32,0,1,6,97,99,116,105,111,110,7,22, + 97,99,116,105,111,110,115,109,111,46,97,98,111,114,116,109,97,107,101,97, + 99,116,7,99,97,112,116,105,111,110,6,11,38,65,98,111,114,116,32,77, + 97,107,101,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99, + 97,112,116,105,111,110,11,97,115,95,108,111,99,97,108,116,97,103,0,0, + 1,7,111,112,116,105,111,110,115,11,13,109,97,111,95,115,101,112,97,114, + 97,116,111,114,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112, + 116,105,111,110,0,0,1,6,97,99,116,105,111,110,7,27,97,99,116,105, + 111,110,115,109,111,46,112,114,111,106,101,99,116,111,112,116,105,111,110,115, + 97,99,116,0,1,6,97,99,116,105,111,110,7,24,97,99,116,105,111,110, + 115,109,111,46,112,114,111,106,101,99,116,116,114,101,101,97,99,116,0,1, + 6,97,99,116,105,111,110,7,26,97,99,116,105,111,110,115,109,111,46,112, + 114,111,106,101,99,116,115,111,117,114,99,101,97,99,116,0,1,7,111,112, + 116,105,111,110,115,11,13,109,97,111,95,115,101,112,97,114,97,116,111,114, + 19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111,110, + 0,0,1,13,115,117,98,109,101,110,117,46,99,111,117,110,116,2,3,13, + 115,117,98,109,101,110,117,46,105,116,101,109,115,14,1,7,99,97,112,116, + 105,111,110,6,14,70,114,111,109,32,38,84,101,109,112,108,97,116,101,5, + 115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105, + 111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101, + 0,9,111,110,101,120,101,99,117,116,101,7,19,110,101,119,112,114,111,106, + 101,99,116,111,110,101,120,101,99,117,116,101,0,1,7,99,97,112,116,105, + 111,110,6,13,70,114,111,109,32,38,80,114,111,103,114,97,109,5,115,116, + 97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110, + 17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9, + 111,110,101,120,101,99,117,116,101,7,24,110,101,119,112,114,111,106,101,99, + 116,102,114,111,109,112,114,111,103,114,97,109,101,120,101,0,1,7,99,97, + 112,116,105,111,110,6,6,38,69,109,112,116,121,5,115,116,97,116,101,11, + 15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95, + 108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120, + 101,99,117,116,101,7,18,110,101,119,101,109,112,116,121,112,114,111,106,101, + 99,116,101,120,101,0,0,7,99,97,112,116,105,111,110,6,4,38,78,101, + 119,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112, + 116,105,111,110,0,0,1,6,97,99,116,105,111,110,7,24,97,99,116,105, + 111,110,115,109,111,46,112,114,111,106,101,99,116,111,112,101,110,97,99,116, + 0,1,7,99,97,112,116,105,111,110,6,9,79,112,101,110,32,99,111,112, + 121,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112, + 116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117, + 116,101,0,9,111,110,101,120,101,99,117,116,101,7,22,111,112,101,110,112, + 114,111,106,101,99,116,99,111,112,121,101,120,101,99,117,116,101,0,1,6, + 97,99,116,105,111,110,7,24,97,99,116,105,111,110,115,109,111,46,112,114, + 111,106,101,99,116,115,97,118,101,97,99,116,0,1,7,99,97,112,116,105, + 111,110,6,8,83,97,118,101,32,38,97,115,5,115,116,97,116,101,11,15, + 97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108, + 111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101, + 99,117,116,101,7,22,115,97,118,101,112,114,111,106,101,99,116,97,115,111, + 110,101,120,101,99,117,116,101,0,1,7,99,97,112,116,105,111,110,6,12, + 83,97,118,101,32,97,115,32,99,111,112,121,5,115,116,97,116,101,11,15, + 97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108, + 111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101, + 99,117,116,101,7,22,115,97,118,101,112,114,111,106,101,99,116,99,111,112, + 121,101,120,101,99,117,116,101,0,1,6,97,99,116,105,111,110,7,25,97, + 99,116,105,111,110,115,109,111,46,112,114,111,106,101,99,116,99,108,111,115, + 101,97,99,116,7,99,97,112,116,105,111,110,6,6,38,67,108,111,115,101, + 4,110,97,109,101,6,5,99,108,111,115,101,5,115,116,97,116,101,11,15, + 97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108, + 111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101, + 99,117,116,101,7,24,99,108,111,115,101,112,114,111,106,101,99,116,97,99, + 116,111,110,101,120,101,99,117,116,101,0,0,7,99,97,112,116,105,111,110, + 6,8,38,80,114,111,106,101,99,116,4,110,97,109,101,6,7,112,114,111, + 106,101,99,116,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120, + 101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7,14,97,98, + 111,117,116,111,110,101,120,101,99,117,116,101,0,1,13,115,117,98,109,101, + 110,117,46,99,111,117,110,116,2,2,13,115,117,98,109,101,110,117,46,105, + 116,101,109,115,14,1,7,99,97,112,116,105,111,110,6,6,38,65,98,111, + 117,116,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97, + 112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99, + 117,116,101,0,9,111,110,101,120,101,99,117,116,101,7,14,97,98,111,117, + 116,111,110,101,120,101,99,117,116,101,0,1,7,99,97,112,116,105,111,110, + 6,17,38,67,111,110,102,105,103,117,114,101,32,77,83,69,105,100,101,5, + 115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105, + 111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101, + 0,9,111,110,101,120,101,99,117,116,101,7,16,99,111,110,102,105,103,117, + 114,101,101,120,101,99,117,116,101,0,0,7,99,97,112,116,105,111,110,6, + 9,83,101,116,116,38,105,110,103,115,4,110,97,109,101,6,8,115,101,116, + 116,105,110,103,115,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101, + 120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7,14,97, + 98,111,117,116,111,110,101,120,101,99,117,116,101,0,0,4,108,101,102,116, + 2,103,3,116,111,112,2,96,0,0,11,116,102,105,108,101,100,105,97,108, + 111,103,8,111,112,101,110,102,105,108,101,8,115,116,97,116,102,105,108,101, + 7,15,112,114,111,106,101,99,116,115,116,97,116,102,105,108,101,18,99,111, + 110,116,114,111,108,108,101,114,46,111,112,116,105,111,110,115,11,14,102,100, + 111,95,99,104,101,99,107,101,120,105,115,116,0,22,99,111,110,116,114,111, + 108,108,101,114,46,99,97,112,116,105,111,110,111,112,101,110,6,9,79,112, + 101,110,32,102,105,108,101,22,99,111,110,116,114,111,108,108,101,114,46,99, + 97,112,116,105,111,110,115,97,118,101,6,12,83,97,118,101,32,102,105,108, + 101,32,97,115,3,116,111,112,2,1,0,0,9,116,115,116,97,116,102,105, + 108,101,15,112,114,111,106,101,99,116,115,116,97,116,102,105,108,101,8,102, + 105,108,101,110,97,109,101,6,10,115,116,97,116,117,115,46,115,116,97,16, + 111,110,115,116,97,116,98,101,102,111,114,101,114,101,97,100,7,11,115,116, + 97,116,98,101,102,114,101,97,100,15,111,110,115,116,97,116,97,102,116,101, + 114,114,101,97,100,7,13,115,116,97,116,97,102,116,101,114,114,101,97,100, + 3,116,111,112,2,64,0,0,10,116,105,109,97,103,101,108,105,115,116,13, + 118,105,101,118,109,101,110,117,105,99,111,110,115,5,119,105,100,116,104,2, + 18,6,104,101,105,103,104,116,2,18,7,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,5,99,111,117,110,116,2,19,4,108,101,102,116,3,57, + 1,3,116,111,112,2,96,5,105,109,97,103,101,10,16,89,0,0,0,0, + 0,0,6,0,0,0,90,0,0,0,90,0,0,0,136,61,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,255,255,255,6,203,88,38,1,197,68, + 11,1,255,255,255,3,194,59,0,1,255,255,255,6,168,168,168,1,184,184, + 184,7,212,212,212,1,233,233,233,8,229,229,229,1,173,173,173,1,190,190, + 190,17,208,208,208,1,255,255,255,17,224,224,224,1,255,255,255,16,208,208, + 208,1,255,255,255,2,198,57,0,1,255,0,0,1,255,255,255,1,253,67, + 9,1,223,140,106,1,223,136,100,1,234,55,5,1,234,54,5,1,221,82, + 34,1,218,129,92,1,222,62,6,1,253,67,9,1,255,255,255,4,220,220, + 220,1,202,202,202,7,255,255,255,8,202,202,202,1,167,167,167,1,190,190, + 190,1,208,208,208,17,60,60,60,1,208,208,208,16,141,180,183,1,208,208, + 208,1,124,124,124,15,255,255,255,1,0,0,255,1,255,255,255,2,205,98, + 50,1,221,147,114,1,217,96,50,1,235,55,5,1,223,127,93,1,252,247, + 244,1,215,90,49,1,212,63,21,1,237,192,175,1,238,195,177,1,221,51, + 2,1,235,55,5,1,246,62,8,1,255,255,255,3,233,233,233,1,255,255, + 255,8,202,202,202,1,196,196,196,1,197,197,197,1,200,200,200,2,202,202, + 202,1,133,133,133,1,202,202,202,1,138,138,138,1,190,190,190,1,208,208, + 208,3,2,172,8,1,1,170,9,1,208,208,208,12,181,248,254,1,208,208, + 208,16,255,255,255,1,124,124,124,2,232,232,232,14,255,255,255,1,208,208, + 208,1,255,255,255,2,197,73,22,1,238,197,180,1,247,226,218,1,219,117, + 81,1,210,75,33,1,251,242,238,1,241,205,191,1,214,102,65,1,255,255, + 255,1,226,149,122,1,211,39,0,1,217,44,1,1,229,51,4,1,218,103, + 59,1,212,116,74,1,255,255,255,1,233,233,233,1,255,255,255,1,181,181, + 181,1,183,183,183,1,190,190,190,1,216,216,216,1,224,224,224,1,133,133, + 133,1,255,255,255,1,177,177,177,1,125,125,125,1,151,151,151,1,154,154, + 154,1,135,135,135,1,202,202,202,1,133,133,133,1,202,202,202,1,138,138, + 138,1,190,190,190,1,208,208,208,3,4,178,6,1,13,180,13,1,8,173, + 14,1,208,208,208,11,111,199,206,1,208,208,208,16,47,47,47,1,208,208, + 208,1,124,124,124,1,232,232,232,14,255,255,255,1,116,149,150,1,255,255, + 255,2,246,62,8,1,220,120,82,1,254,253,252,1,255,255,255,1,232,174, + 153,1,216,115,79,1,252,246,243,1,212,104,66,1,246,223,214,1,218,114, + 82,1,211,106,64,1,208,66,25,1,221,131,98,1,247,230,222,1,217,116, + 75,1,255,255,255,1,229,229,229,1,255,255,255,1,149,149,149,1,145,145, + 145,1,143,143,143,1,172,172,172,1,224,224,224,1,133,133,133,1,255,255, + 255,1,181,181,181,1,177,177,177,1,165,165,165,1,166,166,166,1,160,160, + 160,1,202,202,202,1,133,133,133,1,202,202,202,1,167,167,167,1,190,190, + 190,1,208,208,208,3,5,179,6,1,34,205,21,1,29,184,27,1,14,173, + 19,1,208,208,208,10,24,24,24,1,124,124,124,15,255,255,255,1,0,0, + 0,1,208,208,208,1,124,124,124,1,232,232,232,14,255,255,255,1,0,0, + 0,1,255,255,255,1,253,67,9,1,235,55,5,1,212,62,17,1,219,123, + 89,1,255,255,255,1,252,244,241,1,200,82,50,1,204,113,85,1,166,86, + 66,1,106,154,140,1,209,62,29,1,214,106,72,1,245,222,212,1,255,254, + 254,1,218,116,79,1,232,56,5,1,253,67,9,1,219,219,219,1,240,240, + 240,1,224,224,224,5,255,255,255,10,252,252,252,1,190,190,190,1,208,208, + 208,3,5,179,6,1,34,205,21,1,56,212,44,1,53,200,49,1,20,173, + 25,1,0,169,9,1,208,208,208,9,124,124,124,1,232,232,232,14,255,255, + 255,1,122,122,255,1,155,186,186,1,124,124,124,1,232,232,232,14,255,255, + 255,1,0,0,255,1,255,255,255,1,245,61,7,1,226,49,3,1,220,129, + 95,1,217,122,86,1,216,111,78,1,217,114,83,1,30,236,229,1,78,179, + 174,1,122,126,123,1,40,224,219,1,213,65,41,1,252,247,244,1,255,255, + 255,1,227,149,123,1,210,43,4,1,226,49,3,1,245,61,7,1,223,223, + 223,1,245,245,245,1,211,235,235,1,229,239,239,1,240,240,240,1,238,238, + 238,1,237,237,237,1,235,235,235,1,234,234,234,1,232,232,232,1,202,224, + 224,1,224,228,228,1,227,227,227,1,226,226,226,1,224,224,224,1,223,223, + 223,1,221,221,221,1,225,225,225,1,190,190,190,1,208,208,208,3,5,179, + 6,1,34,205,21,1,56,212,44,1,77,219,66,1,84,217,76,1,29,177, + 33,1,0,169,9,1,208,208,208,7,4,4,255,1,124,124,124,1,232,232, + 232,1,123,123,123,1,79,79,79,1,116,116,116,1,232,232,232,2,186,186, + 186,1,96,96,96,1,232,232,232,1,230,230,230,1,95,95,95,1,74,74, + 74,1,152,152,152,1,232,232,232,1,255,255,255,1,255,0,38,1,208,208, + 208,1,124,124,124,1,232,232,232,1,146,146,146,1,49,49,49,1,232,232, + 232,2,193,193,193,1,21,21,21,1,232,232,232,1,69,69,69,1,79,79, + 79,3,186,186,186,1,232,232,232,1,255,255,255,1,224,224,224,1,255,255, + 255,1,235,57,5,1,214,64,19,1,211,89,49,1,213,102,66,1,220,118, + 89,1,214,84,55,1,129,119,117,1,186,111,115,1,214,205,206,1,183,78, + 82,1,92,164,159,1,207,119,91,1,218,123,91,1,211,78,41,1,214,88, + 50,1,214,76,32,1,233,57,5,1,122,202,204,1,96,214,217,1,55,215, + 222,1,50,210,216,1,152,222,223,1,238,238,238,1,237,237,237,1,235,235, + 235,1,234,234,234,1,87,208,211,1,53,213,220,1,49,205,210,1,172,218, + 219,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1,222,222, + 222,1,190,190,190,1,208,208,208,3,5,179,6,1,34,205,21,1,56,212, + 44,1,77,219,66,1,98,226,88,1,113,230,105,1,46,184,49,1,19,178, + 26,1,208,208,208,6,114,114,255,1,124,124,124,1,198,198,198,1,85,85, + 85,1,232,232,232,1,83,83,83,1,203,203,203,1,172,172,172,1,83,83, + 83,1,80,80,80,1,232,232,232,1,153,153,153,1,130,130,130,1,232,232, + 232,1,55,55,55,1,231,231,231,1,255,255,255,2,0,0,104,1,124,124, + 124,1,232,232,232,1,137,137,137,1,44,44,44,1,188,188,188,1,232,232, + 232,1,116,116,116,1,36,36,36,1,232,232,232,1,57,57,57,1,232,232, + 232,5,255,255,255,1,224,224,224,1,194,59,0,1,214,116,75,1,248,232, + 225,1,255,255,255,3,209,109,85,1,74,184,182,1,193,115,123,1,214,178, + 182,1,167,99,107,1,35,230,226,1,187,83,60,1,234,180,161,1,254,251, + 250,1,252,244,241,1,227,159,132,1,216,87,39,1,69,195,199,1,61,213, + 219,1,178,243,255,1,132,241,255,1,62,209,213,1,238,238,238,1,224,224, + 236,1,235,235,235,1,206,228,228,1,64,215,223,1,176,243,255,1,118,241, + 255,1,71,207,209,1,226,226,226,1,211,211,224,1,223,223,223,1,221,221, + 221,1,222,222,222,1,190,190,190,1,208,208,208,3,5,179,6,1,34,205, + 21,1,56,212,44,1,77,219,66,1,98,226,88,1,119,233,110,1,139,240, + 132,1,76,198,77,1,33,180,39,1,208,208,208,5,151,151,255,1,124,124, + 124,1,161,161,161,1,130,130,130,1,232,232,232,1,126,126,126,1,164,164, + 164,1,227,227,227,1,225,225,225,1,80,80,80,1,232,232,232,1,114,114, + 114,1,177,177,177,1,232,232,232,1,79,79,79,1,211,211,211,1,255,255, + 255,1,208,208,208,1,0,0,255,1,124,124,124,1,232,232,232,1,137,137, + 137,1,123,123,123,1,110,110,110,1,232,232,232,1,96,96,96,1,57,57, + 57,1,232,232,232,1,54,54,54,1,116,116,116,3,222,222,222,1,232,232, + 232,1,255,255,255,1,103,103,103,1,255,255,255,1,222,68,19,1,216,103, + 65,1,232,172,150,1,252,246,243,1,222,133,106,1,188,69,50,1,37,227, + 223,1,157,78,90,1,88,163,169,1,156,81,92,1,215,91,68,1,221,116, + 91,1,213,94,59,1,217,98,69,1,210,67,29,1,212,42,0,1,234,54, + 5,1,56,195,202,1,63,216,224,1,199,243,255,1,144,242,255,1,52,209, + 213,1,238,238,238,1,52,52,223,1,229,229,234,1,172,222,222,1,76,223, + 233,1,208,244,255,1,134,241,255,1,56,206,209,1,226,226,226,1,52,52, + 221,1,208,208,223,1,221,221,221,1,217,217,222,1,190,190,190,1,208,208, + 208,3,5,179,6,1,34,205,21,1,56,212,44,1,77,219,66,1,98,226, + 88,1,119,233,110,1,139,240,132,1,74,193,75,1,20,109,23,1,0,0, + 0,1,208,208,208,5,124,124,124,1,177,177,177,1,128,128,128,1,232,232, + 232,1,123,123,123,1,168,168,168,1,232,232,232,1,225,225,225,1,80,80, + 80,1,232,232,232,1,129,129,129,1,176,176,176,1,232,232,232,1,76,76, + 76,1,216,216,216,1,255,255,255,1,136,136,136,1,124,124,124,2,232,232, + 232,1,137,137,137,1,159,159,159,1,73,73,73,1,187,187,187,1,140,140, + 140,1,57,57,57,1,232,232,232,1,56,56,56,1,196,196,196,3,229,229, + 229,1,232,232,232,1,255,255,255,1,0,0,255,1,255,255,255,1,235,55, + 5,1,215,42,0,1,211,38,4,1,210,80,42,1,225,146,122,1,215,105, + 73,1,219,101,81,1,211,92,71,1,64,194,194,1,149,104,99,1,246,225, + 217,1,255,255,255,1,246,224,215,1,216,103,70,1,211,41,7,1,215,42, + 0,1,235,55,5,1,56,195,201,1,60,206,210,1,81,230,243,1,56,222, + 233,1,107,214,215,1,172,172,233,1,12,12,236,1,131,131,230,1,232,233, + 233,1,48,202,206,1,95,235,249,1,54,222,232,1,116,210,211,1,184,184, + 224,1,15,15,234,1,102,102,223,1,221,221,221,1,185,185,222,1,190,190, + 190,1,208,208,208,3,5,179,6,1,34,205,21,1,56,212,44,1,77,219, + 66,1,98,226,88,1,113,230,105,1,43,174,46,1,6,55,8,1,0,0, + 0,2,208,208,208,4,0,0,0,1,124,124,124,1,227,227,227,1,86,86, + 86,1,232,232,232,1,78,78,78,1,207,207,207,1,232,232,232,1,225,225, + 225,1,80,80,80,1,232,232,232,1,187,187,187,1,126,126,126,1,228,228, + 228,1,57,57,57,1,232,232,232,1,255,255,255,3,124,124,124,1,232,232, + 232,1,137,137,137,1,159,159,159,1,119,119,119,1,70,70,70,1,216,216, + 216,1,57,57,57,1,232,232,232,1,57,57,57,1,232,232,232,5,255,255, + 255,1,208,208,208,1,255,255,255,1,239,57,6,1,219,44,1,1,211,63, + 25,1,238,191,175,1,240,199,186,1,218,123,94,1,255,255,255,1,239,199, + 186,1,210,50,31,1,220,118,93,1,214,106,74,1,252,245,242,1,255,255, + 255,1,255,254,254,1,223,136,105,1,217,50,6,1,239,57,6,1,67,189, + 193,1,234,228,228,1,130,205,206,1,166,211,212,1,236,225,225,1,65,65, + 229,1,4,4,255,1,51,51,230,1,233,230,230,1,211,214,214,1,101,195, + 197,1,154,203,203,1,224,213,213,1,70,70,225,1,4,4,254,1,41,41, + 229,1,218,218,221,1,107,107,223,1,190,190,190,1,208,208,208,3,5,179, + 6,1,34,205,21,1,56,212,44,1,77,219,66,1,84,217,76,1,26,157, + 29,1,0,21,1,1,0,0,0,2,208,208,208,5,255,255,255,1,124,124, + 124,1,232,232,232,1,149,149,149,1,90,90,90,1,144,144,144,1,232,232, + 232,2,227,227,227,1,118,118,118,1,232,232,232,1,230,230,230,1,123,123, + 123,1,89,89,89,1,174,174,174,1,232,232,232,1,255,255,255,2,0,0, + 0,1,124,124,124,1,232,232,232,1,161,161,161,1,177,177,177,1,199,199, + 199,1,101,101,101,1,232,232,232,1,101,101,101,1,232,232,232,1,96,96, + 96,1,79,79,79,3,166,166,166,1,232,232,232,1,255,255,255,1,136,136, + 136,1,255,255,255,1,245,61,7,1,219,72,27,1,234,179,158,1,255,255, + 255,1,216,112,78,1,249,231,225,1,255,255,255,1,226,147,124,1,210,64, + 34,1,252,244,241,1,233,171,153,1,213,95,60,1,221,124,97,1,225,142, + 115,1,228,159,134,1,212,97,53,1,245,61,7,1,200,206,206,1,212,22, + 30,1,222,27,40,2,173,26,58,1,24,24,237,1,4,4,255,1,14,14, + 243,1,172,127,172,1,211,21,29,1,220,25,38,2,183,27,46,1,27,27, + 233,1,4,4,255,1,7,7,246,1,136,136,221,1,60,60,227,1,190,190, + 190,1,208,208,208,3,5,179,6,1,34,205,21,1,56,212,44,1,54,199, + 48,1,16,137,20,1,0,4,0,1,0,0,0,1,208,208,208,7,255,255, + 255,1,124,124,124,1,232,232,232,14,255,255,255,2,208,208,208,1,124,124, + 124,1,232,232,232,14,255,255,255,1,0,0,0,1,255,255,255,1,253,67, + 9,1,213,106,62,1,224,140,109,1,218,108,75,1,216,109,74,1,255,255, + 255,1,233,174,156,1,212,93,59,1,216,102,73,1,233,174,154,1,255,255, + 255,1,220,115,86,1,213,32,5,1,212,36,2,1,218,43,1,1,230,56, + 5,1,253,67,9,1,198,67,73,1,237,1,24,1,255,0,32,2,121,18, + 120,1,56,56,230,1,60,60,231,1,59,59,230,1,125,80,170,1,237,1, + 24,1,255,0,32,2,139,20,103,1,51,51,227,1,57,57,228,1,56,56, + 227,1,87,87,222,1,27,27,239,1,190,190,190,1,208,208,208,3,5,179, + 6,1,34,205,21,1,28,181,26,1,9,107,12,1,0,0,0,2,208,208, + 208,8,255,255,255,1,124,124,124,1,255,255,255,15,208,208,208,1,255,255, + 255,1,124,124,124,1,232,232,232,14,255,255,255,4,232,60,6,1,230,51, + 4,1,214,43,0,1,224,147,118,1,219,121,89,1,211,47,18,1,224,137, + 111,1,221,125,97,1,217,104,74,1,255,255,255,1,223,136,107,1,212,36, + 2,1,215,42,0,1,230,51,4,1,246,62,8,1,255,255,255,1,207,8, + 24,1,237,1,24,1,255,0,32,2,216,32,41,1,238,238,238,1,237,237, + 237,1,235,235,235,1,221,176,175,1,237,1,24,1,255,0,32,2,215,31, + 40,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1,41,41, + 233,1,190,190,190,1,208,208,208,3,4,178,6,1,12,174,13,1,3,67, + 6,1,0,0,0,2,208,208,208,9,255,255,255,1,208,208,208,16,138,138, + 138,1,255,255,255,1,124,124,124,1,232,232,232,14,255,255,255,5,244,61, + 7,1,226,52,4,1,213,80,37,1,212,38,0,1,212,36,2,1,217,117, + 82,1,211,70,34,1,211,50,14,1,239,199,184,1,225,148,120,1,218,43, + 1,1,230,51,4,1,244,61,7,1,255,255,255,2,216,0,21,1,208,26, + 32,1,217,32,42,2,198,29,30,1,238,238,238,1,237,237,237,1,235,235, + 235,1,221,176,175,1,207,24,30,1,215,31,40,2,197,28,28,1,226,226, + 226,1,224,224,224,1,223,223,223,1,221,221,221,1,126,126,225,1,190,190, + 190,1,208,208,208,3,2,172,8,1,0,51,3,1,0,0,0,2,208,208, + 208,10,245,225,226,1,208,208,208,16,0,0,255,1,208,208,208,1,124,124, + 124,1,232,232,232,14,255,255,255,1,208,208,208,1,255,255,255,4,246,62, + 8,1,235,55,5,1,226,49,3,1,219,44,1,1,214,43,0,1,213,41, + 0,1,215,42,0,1,217,107,68,1,222,132,98,1,235,55,5,1,246,62, + 8,1,255,255,255,3,210,6,23,1,245,245,245,1,243,243,243,1,242,242, + 242,1,240,240,240,1,238,238,238,1,237,237,237,1,235,235,235,1,234,234, + 234,1,232,232,232,1,230,230,230,1,229,229,229,1,227,227,227,1,226,226, + 226,1,224,224,224,1,223,223,223,1,221,221,221,1,222,222,222,1,190,190, + 190,1,208,208,208,4,0,0,0,2,208,208,208,28,255,0,255,1,136,136, + 136,1,124,124,124,1,255,255,255,21,253,67,9,1,245,61,7,1,239,57, + 6,1,235,55,5,1,234,54,5,1,235,55,5,1,229,64,13,1,224,78, + 26,1,253,67,9,1,255,255,255,4,192,40,45,1,217,47,56,1,219,49, + 58,1,211,48,53,1,210,93,94,1,237,237,237,2,235,235,235,1,227,203, + 202,1,216,122,124,1,210,42,48,1,216,47,55,2,203,45,47,1,214,150, + 150,1,225,225,225,1,223,223,223,1,222,222,222,1,190,190,190,1,208,208, + 208,2,129,194,131,1,14,143,19,1,0,42,2,1,0,4,0,1,12,12, + 12,1,128,128,128,1,208,208,208,9,121,121,121,1,255,255,255,16,201,201, + 201,1,124,124,124,1,255,255,255,16,59,239,255,1,208,208,208,1,255,255, + 255,16,224,224,224,1,208,208,208,18,255,255,255,9,192,192,192,1,255,255, + 255,8,208,208,208,18,0,0,0,1,255,255,255,15,0,0,0,1,208,208, + 208,18,224,224,224,1,208,208,208,57,0,0,255,1,208,208,208,13,1,1, + 1,1,28,28,28,1,208,208,208,1,136,136,136,8,135,142,142,1,134,134, + 134,1,0,0,0,1,208,208,208,4,124,124,124,1,208,208,208,17,217,217, + 217,1,208,208,208,6,0,0,0,6,208,208,208,5,255,255,255,1,208,208, + 208,17,128,128,128,1,224,224,224,1,208,208,208,2,0,0,255,2,208,208, + 208,1,0,0,0,8,208,208,208,3,217,217,217,2,208,208,208,1,136,136, + 136,1,181,248,254,1,186,249,254,1,191,250,254,1,196,251,254,1,201,252, + 254,1,206,253,254,1,211,254,254,1,160,175,176,1,158,193,197,1,99,99, + 99,1,0,0,0,1,208,208,208,3,0,0,255,1,208,208,208,8,0,0, + 182,2,208,208,208,8,255,255,255,1,208,208,208,4,0,0,0,8,208,208, + 208,4,233,164,145,1,208,208,208,18,0,0,0,1,0,0,255,5,0,0, + 0,8,208,208,208,3,53,53,53,1,62,62,62,1,208,208,208,1,136,136, + 136,1,181,248,254,1,186,249,254,1,191,250,254,1,196,251,254,1,201,252, + 254,1,206,253,254,1,211,254,254,1,167,182,183,1,224,252,255,1,156,193, + 197,1,101,101,101,1,0,0,0,1,208,208,208,9,5,5,198,1,11,11, + 206,1,21,21,213,1,26,26,213,1,22,22,206,1,13,13,198,1,208,208, + 208,6,255,255,255,1,208,208,208,4,0,0,0,2,24,24,155,1,52,52, + 255,1,63,63,254,1,45,45,155,1,0,0,0,2,208,208,208,4,252,243, + 240,1,208,208,208,1,124,124,124,15,255,255,255,1,208,208,208,1,78,78, + 78,1,0,0,255,1,208,208,208,1,0,0,255,2,208,208,208,4,0,0, + 0,3,208,208,208,1,0,0,0,1,208,208,208,3,0,0,0,2,208,208, + 208,1,136,136,136,1,181,248,254,1,139,186,189,1,151,198,201,1,151,194, + 196,1,172,215,217,1,178,218,219,1,157,189,189,1,154,181,183,1,240,253, + 255,1,221,252,255,1,155,194,197,1,103,103,103,1,0,0,0,1,208,208, + 208,1,167,205,206,1,208,208,208,5,3,3,200,1,21,21,233,1,41,41, + 255,1,52,52,255,1,64,64,255,1,75,75,255,1,58,58,228,1,19,19, + 187,1,208,208,208,5,243,195,182,1,208,208,208,3,0,0,0,1,0,0, + 1,1,6,6,56,1,41,41,255,1,52,52,255,1,64,64,255,1,75,75, + 255,1,25,25,72,1,0,0,1,1,0,0,0,1,208,208,208,3,224,224, + 224,1,208,208,208,1,124,124,124,1,232,232,232,14,255,255,255,1,208,208, + 208,1,217,217,217,1,0,0,255,1,208,208,208,1,0,0,255,2,208,208, + 208,4,0,0,0,5,208,208,208,3,0,0,255,1,208,208,208,2,136,136, + 136,1,181,248,254,1,124,166,169,1,117,153,155,1,116,149,150,1,141,177, + 178,1,139,171,171,1,149,179,179,1,141,180,183,1,188,248,255,1,243,253, + 255,1,219,251,255,1,155,196,199,1,104,106,106,1,0,0,0,1,208,208, + 208,5,3,3,198,1,13,13,233,1,30,30,255,1,41,41,255,1,52,52, + 255,1,64,64,255,1,75,75,255,1,86,86,255,1,66,66,226,1,13,13, + 142,1,208,208,208,3,218,218,218,1,128,76,240,1,208,208,208,3,4,4, + 234,1,14,14,211,1,25,25,222,1,41,41,255,1,52,52,255,1,64,64, + 255,1,75,75,255,1,31,31,92,1,4,4,11,1,57,57,131,1,208,208, + 208,5,124,124,124,1,232,232,232,1,97,97,97,1,98,98,98,1,97,97, + 97,1,231,231,231,1,156,156,156,1,93,93,93,1,88,88,88,1,186,186, + 186,1,217,217,217,1,86,86,86,1,97,97,97,1,124,124,124,1,232,232, + 232,1,255,255,255,1,128,128,128,1,208,208,208,1,0,0,255,1,208,208, + 208,7,0,0,0,5,208,208,208,3,201,246,246,1,178,243,246,1,208,208, + 208,1,136,136,136,1,181,248,254,1,186,249,254,1,191,250,254,1,196,251, + 254,1,201,252,254,1,206,253,254,1,211,254,254,1,147,185,187,1,136,179, + 183,1,144,180,183,1,152,181,183,1,139,175,179,1,133,140,140,1,0,0, + 0,1,0,0,253,1,208,208,208,4,3,3,206,1,18,18,255,1,30,30, + 255,1,41,41,255,1,52,52,255,1,64,64,255,1,75,75,255,1,86,86, + 255,1,98,98,255,1,27,27,180,1,0,0,0,1,208,208,208,2,149,35, + 65,1,0,252,248,1,208,208,208,3,6,6,255,1,17,17,255,1,29,29, + 255,1,41,41,255,1,52,52,255,1,64,64,255,1,54,54,182,1,2,2, + 5,1,36,36,94,1,87,87,204,1,0,0,0,1,208,208,208,2,9,164, + 0,1,208,208,208,1,124,124,124,1,202,202,202,1,146,146,146,1,232,232, + 232,1,116,116,116,1,180,180,180,1,117,117,117,1,230,230,230,1,209,209, + 209,1,87,87,87,1,170,170,170,1,177,177,177,1,232,232,232,1,74,74, + 74,1,224,224,224,1,255,255,255,1,208,208,208,1,181,248,254,1,0,0, + 255,1,208,208,208,4,0,0,0,6,208,208,208,2,0,0,255,3,208,208, + 208,1,6,6,252,1,208,208,208,1,136,136,136,1,181,248,254,1,186,249, + 254,1,191,250,254,1,196,251,254,1,181,226,228,1,167,205,206,1,155,186, + 186,1,169,207,207,1,148,202,204,1,127,195,200,1,137,245,254,1,114,242, + 254,1,136,136,136,1,0,0,0,1,224,224,224,1,238,238,238,1,208,208, + 208,2,0,0,182,1,2,2,213,1,18,18,255,1,30,30,255,1,41,41, + 255,1,52,52,255,1,64,64,255,1,75,75,255,1,86,86,255,1,98,98, + 255,1,41,41,196,1,0,0,13,1,208,208,208,2,0,0,0,1,13,182, + 0,1,208,208,208,3,6,6,255,1,17,17,255,1,29,29,255,1,41,41, + 255,1,52,52,255,1,46,46,184,1,3,3,9,1,20,20,59,1,96,96, + 247,1,104,104,240,1,0,0,0,1,208,208,208,2,128,128,128,1,224,112, + 0,1,124,124,124,1,232,232,232,2,207,207,207,1,72,72,72,1,222,222, + 222,1,232,232,232,2,103,103,103,1,166,166,166,1,232,232,232,2,180,180, + 180,1,88,88,88,1,232,232,232,1,255,255,255,1,0,0,1,1,118,211, + 219,1,0,0,255,1,208,208,208,4,0,0,0,6,208,208,208,4,0,0, + 255,1,189,189,189,1,208,208,208,2,136,136,136,1,181,248,254,1,186,249, + 254,1,191,250,254,1,196,251,254,1,168,210,212,1,145,179,179,1,151,181, + 181,1,159,195,195,1,131,178,180,1,107,165,169,1,137,245,254,1,114,242, + 254,1,136,136,136,1,0,0,0,1,224,224,224,1,255,255,255,1,208,208, + 208,2,0,0,182,1,2,2,213,1,18,18,255,1,30,30,255,1,41,41, + 255,1,52,52,255,1,64,64,255,1,75,75,255,1,86,86,255,1,98,98, + 255,1,41,41,196,1,0,0,10,1,208,208,208,2,0,0,0,1,208,208, + 208,4,6,6,255,1,17,17,255,1,29,29,255,1,41,41,255,1,43,43, + 211,1,2,2,6,1,14,14,49,1,81,81,238,1,99,99,255,1,104,104, + 240,1,0,0,0,1,208,208,208,2,255,255,255,1,0,0,0,1,124,124, + 124,1,232,232,232,2,81,81,81,1,209,209,209,1,232,232,232,2,159,159, + 159,1,131,131,131,1,232,232,232,2,231,231,231,1,66,66,66,1,226,226, + 226,1,232,232,232,1,255,255,255,1,0,0,0,1,15,15,86,1,0,0, + 255,1,208,208,208,14,0,0,255,1,163,163,163,1,3,3,3,1,208,208, + 208,1,136,136,136,1,181,248,254,1,186,249,254,1,191,250,254,1,196,251, + 254,1,201,252,254,1,176,216,217,1,206,248,248,1,201,246,246,1,178,243, + 246,1,159,245,251,1,134,240,249,1,114,242,254,1,136,136,136,1,0,0, + 0,1,255,255,255,1,0,0,0,1,208,208,208,3,3,3,206,1,18,18, + 255,1,30,30,255,1,41,41,255,1,52,52,255,1,64,64,255,1,75,75, + 255,1,86,86,255,1,98,98,255,1,26,26,179,1,0,0,0,1,208,208, + 208,2,255,255,255,1,79,79,79,1,208,208,208,3,6,6,255,1,17,17, + 255,1,29,29,255,1,41,41,255,1,19,19,95,1,3,3,12,1,69,69, + 233,1,87,87,255,1,99,99,255,1,87,87,204,1,0,0,0,1,208,208, + 208,2,71,71,71,1,255,255,255,1,124,124,124,1,232,232,232,2,171,171, + 171,1,232,232,232,3,192,192,192,1,212,212,212,1,232,232,232,2,227,227, + 227,1,177,177,177,1,232,232,232,2,255,255,255,1,0,0,0,1,224,224, + 224,1,0,0,255,1,208,208,208,14,0,0,255,1,208,208,208,3,136,136, + 136,1,181,248,254,1,186,249,254,1,191,250,254,1,196,251,254,1,154,194, + 195,1,141,173,173,1,131,157,157,1,122,149,149,1,131,179,181,1,91,140, + 143,1,84,151,156,1,114,242,254,1,136,136,136,1,0,0,0,2,255,255, + 255,1,208,208,208,3,3,3,198,1,12,12,228,1,30,30,255,1,41,41, + 255,1,52,52,255,1,64,64,255,1,75,75,255,1,86,86,255,1,66,66, + 226,1,10,10,108,1,0,0,0,1,208,208,208,2,0,0,0,1,255,255, + 255,1,208,208,208,3,4,4,255,1,17,17,254,1,29,29,255,1,41,41, + 255,1,11,11,54,1,15,15,61,1,75,75,255,1,87,87,255,1,98,98, + 254,1,38,38,89,1,0,0,0,1,208,208,208,2,206,51,17,1,255,255, + 255,1,124,124,124,1,232,232,232,2,96,96,96,1,232,232,232,3,145,145, + 145,1,184,184,184,1,232,232,232,2,215,215,215,1,114,114,114,1,232,232, + 232,2,255,255,255,2,224,224,224,1,0,0,255,1,208,208,208,2,0,0, + 0,8,208,208,208,4,0,0,255,1,208,208,208,3,136,136,136,1,181,248, + 254,1,186,249,254,1,188,246,250,1,196,251,254,1,188,236,238,1,175,215, + 216,1,141,169,169,1,179,219,219,1,143,195,197,1,128,196,201,1,118,211, + 219,1,114,242,254,1,136,136,136,1,0,0,0,1,0,0,255,1,0,0, + 0,1,208,208,208,4,3,3,187,1,20,20,226,1,41,41,255,1,52,52, + 255,1,64,64,255,1,75,75,255,1,57,57,226,1,15,15,154,1,0,0, + 0,2,208,208,208,2,255,255,255,2,208,208,208,4,15,15,223,1,29,29, + 254,1,41,41,255,1,38,38,188,1,50,50,199,1,75,75,255,1,86,86, + 254,1,62,62,158,1,0,0,0,2,208,208,208,2,207,53,11,1,0,0, + 0,1,124,124,124,1,232,232,232,14,255,255,255,1,0,0,0,1,208,208, + 208,1,0,0,255,2,208,208,208,1,0,0,0,8,208,208,208,1,0,0, + 255,2,208,208,208,1,0,0,255,1,208,208,208,3,136,136,136,1,181,248, + 254,1,146,195,199,1,144,188,191,1,147,188,190,1,117,146,147,1,146,180, + 180,1,204,245,245,1,207,254,254,1,184,251,254,1,161,248,254,1,137,245, + 254,1,114,242,254,1,136,136,136,1,0,0,0,1,255,255,255,1,0,0, + 0,1,208,208,208,5,4,4,142,1,10,10,180,1,19,19,196,1,23,23, + 196,1,19,19,179,1,7,7,108,1,0,0,0,2,208,208,208,3,140,140, + 140,1,213,80,48,1,208,208,208,5,16,16,136,1,33,33,204,1,34,34, + 167,1,43,43,172,1,59,59,204,1,31,31,89,1,0,0,0,2,208,208, + 208,3,128,128,128,1,255,255,255,1,124,124,124,1,255,255,255,15,0,0, + 0,1,255,255,255,1,208,208,208,10,0,0,0,1,208,208,208,1,0,0, + 255,2,208,208,208,1,0,0,255,1,255,255,255,2,208,208,208,1,136,136, + 136,1,181,248,254,1,122,163,166,1,137,179,182,1,143,183,185,1,136,170, + 171,1,145,179,179,1,205,247,247,1,207,254,254,1,184,251,254,1,161,248, + 254,1,137,245,254,1,114,242,254,1,136,136,136,1,0,0,0,1,255,255, + 255,1,140,140,140,1,208,208,208,6,0,0,0,1,0,0,13,1,0,0, + 10,1,0,0,0,3,208,208,208,4,245,245,245,1,128,76,240,1,208,208, + 208,6,0,0,0,6,208,208,208,5,255,255,255,1,208,208,208,16,140,140, + 140,1,255,255,255,1,208,208,208,3,0,0,0,8,0,0,255,5,208,208, + 208,3,136,136,136,14,0,0,0,1,208,208,208,1,255,255,255,1,208,208, + 208,16,255,255,255,2,208,208,208,7,0,0,0,2,208,208,208,7,255,255, + 255,1,0,0,0,1,208,208,208,16,255,255,255,1,255,30,64,1,208,208, + 208,3,0,0,0,8,208,208,208,1,0,0,255,2,208,208,208,5,0,0, + 0,15,136,136,136,1,198,198,198,1,208,208,208,16,255,255,255,2,208,208, + 208,16,255,255,255,1,215,215,215,1,208,208,208,16,228,228,228,1,208,208, + 208,14,0,0,255,1,208,208,208,4,255,255,255,12,0,0,0,3,255,255, + 255,1,208,208,208,1,255,255,255,12,0,0,0,1,255,255,255,5,224,224, + 224,1,255,255,255,16,208,208,208,1,187,187,187,1,176,176,176,1,219,219, + 219,1,162,162,162,1,186,186,186,1,227,227,227,1,140,140,140,1,227,227, + 227,1,158,158,158,3,141,141,141,1,140,140,140,1,255,255,255,5,124,124, + 124,1,255,255,255,16,206,253,254,1,173,173,173,1,222,68,91,1,233,27, + 58,2,222,67,90,1,190,190,190,13,255,255,255,10,194,194,194,1,58,58, + 58,1,59,59,59,1,198,198,198,1,255,255,255,3,224,124,97,1,208,208, + 208,1,255,255,255,16,208,208,208,2,255,255,255,16,0,0,0,1,208,208, + 208,1,255,255,255,17,190,190,190,1,208,208,208,1,255,30,64,3,208,208, + 208,13,0,0,0,1,208,208,208,16,128,76,240,1,208,208,208,17,149,149, + 149,1,0,0,255,1,124,124,124,15,255,255,255,1,186,249,254,1,188,248, + 255,1,208,208,208,4,13,238,255,1,208,208,208,11,255,255,255,1,190,190, + 190,1,208,208,208,1,255,30,64,4,208,208,208,12,205,45,4,1,208,208, + 208,16,248,252,248,1,124,124,124,1,208,208,208,1,136,136,136,8,135,142, + 142,1,134,134,134,1,0,0,0,1,208,208,208,4,136,136,136,1,0,0, + 0,1,124,124,124,1,232,232,232,14,255,255,255,1,103,103,103,1,255,255, + 255,1,208,208,208,2,51,239,255,1,71,239,255,1,66,239,255,1,39,238, + 255,1,13,238,255,1,208,208,208,9,39,238,255,1,190,190,190,1,208,208, + 208,3,255,30,64,4,208,208,208,10,248,252,248,1,208,208,208,17,74,74, + 74,1,208,208,208,1,136,136,136,1,181,248,254,1,186,249,254,1,191,250, + 254,1,196,251,254,1,201,252,254,1,206,253,254,1,211,254,254,1,160,175, + 176,1,158,193,197,1,99,99,99,1,0,0,0,1,208,208,208,3,122,188, + 192,1,141,177,178,1,124,124,124,1,232,232,232,14,255,255,255,1,0,0, + 255,1,243,243,243,1,208,208,208,1,59,239,255,1,111,241,255,1,142,241, + 255,1,135,241,255,1,95,240,255,1,40,238,255,1,10,178,191,1,208,208, + 208,9,190,190,190,1,208,208,208,4,255,30,64,5,208,208,208,9,124,124, + 124,15,255,255,255,1,217,217,217,1,138,180,183,1,208,208,208,1,136,136, + 136,1,181,248,254,1,186,249,254,1,191,250,254,1,196,251,254,1,201,252, + 254,1,206,253,254,1,211,254,254,1,167,182,183,1,224,252,255,1,156,193, + 197,1,101,101,101,1,0,0,0,1,208,208,208,2,28,28,28,1,208,208, + 208,1,124,124,124,1,232,232,232,14,255,255,255,1,224,224,224,1,208,208, + 208,2,88,240,255,1,154,242,255,1,208,244,255,1,193,243,255,1,132,241, + 255,1,66,239,255,1,12,214,229,1,0,0,0,1,208,208,208,7,255,0, + 38,1,184,191,193,1,208,208,208,6,255,30,64,4,208,208,208,6,200,208, + 211,1,208,208,208,1,124,124,124,1,232,232,232,14,255,255,255,1,60,60, + 60,1,136,136,136,1,208,208,208,1,136,136,136,1,181,248,254,1,186,249, + 254,1,191,250,254,1,196,251,254,1,201,252,254,1,206,253,254,1,211,254, + 254,1,154,181,183,1,240,253,255,1,221,252,255,1,155,194,197,1,103,103, + 103,1,0,0,0,1,208,208,208,1,255,255,255,1,0,0,255,1,124,124, + 124,1,232,232,232,14,255,255,255,1,98,98,241,1,128,128,255,1,208,208, + 208,1,88,240,255,1,154,242,255,1,208,244,255,1,193,243,255,1,132,241, + 255,1,66,239,255,1,13,230,247,1,0,0,0,1,208,208,208,2,8,8, + 255,1,208,208,208,4,56,56,56,1,131,200,229,1,138,220,255,1,142,222, + 255,1,208,208,208,6,255,30,64,4,208,208,208,2,118,215,255,1,138,220, + 255,1,127,214,250,1,50,50,50,1,124,124,124,1,232,232,232,1,123,123, + 123,1,79,79,79,1,116,116,116,1,232,232,232,2,186,186,186,1,96,96, + 96,1,232,232,232,1,230,230,230,1,95,95,95,1,74,74,74,1,152,152, + 152,1,232,232,232,1,255,255,255,2,178,178,178,1,208,208,208,1,136,136, + 136,1,181,248,254,1,186,249,254,1,191,250,254,1,196,251,254,1,201,252, + 254,1,206,253,254,1,211,254,254,1,141,180,183,1,188,248,255,1,243,253, + 255,1,219,251,255,1,155,196,199,1,104,106,106,1,0,0,0,1,4,4, + 255,1,224,224,224,1,124,124,124,1,232,232,232,7,189,189,189,1,142,142, + 142,1,224,224,224,1,232,232,232,4,255,255,255,1,217,217,217,1,161,161, + 255,1,208,208,208,1,59,239,255,1,111,241,255,1,142,241,255,1,135,241, + 255,1,95,240,255,1,40,238,255,1,11,192,206,1,0,0,0,1,208,208, + 208,1,0,0,255,1,4,4,255,1,0,0,143,1,208,208,208,3,217,217, + 217,1,154,209,233,1,180,233,255,1,144,222,255,1,143,222,255,1,208,208, + 208,6,255,30,64,3,208,208,208,1,139,221,255,1,155,225,255,1,180,233, + 255,1,147,223,255,1,184,184,184,1,124,124,124,1,198,198,198,1,85,85, + 85,1,232,232,232,1,83,83,83,1,203,203,203,1,172,172,172,1,83,83, + 83,1,80,80,80,1,232,232,232,1,153,153,153,1,130,130,130,1,232,232, + 232,1,55,55,55,1,231,231,231,1,255,255,255,2,255,0,32,1,208,208, + 208,1,136,136,136,1,181,248,254,1,186,249,254,1,191,250,254,1,196,251, + 254,1,201,252,254,1,206,253,254,1,211,254,254,1,147,185,187,1,136,179, + 183,1,144,180,183,1,152,181,183,1,139,175,179,1,133,140,140,1,0,0, + 0,1,255,0,38,1,224,224,224,1,124,124,124,1,232,232,232,7,210,210, + 210,1,93,93,93,1,26,26,26,1,105,105,105,1,201,201,201,1,232,232, + 232,2,255,255,255,3,208,208,208,1,13,238,255,1,49,229,245,1,71,239, + 255,1,66,239,255,1,39,238,255,1,12,225,241,1,3,51,54,1,0,0, + 0,1,208,208,208,1,3,3,255,1,4,4,255,1,3,3,187,1,0,0, + 0,1,208,208,208,2,206,253,254,1,186,219,233,1,221,245,255,1,146,223, + 255,1,145,222,255,1,255,0,38,1,208,208,208,1,255,0,38,1,208,208, + 208,1,255,0,38,1,208,208,208,1,255,0,38,1,208,208,208,1,255,0, + 38,1,208,208,208,1,182,233,255,1,198,238,255,1,221,245,255,1,181,233, + 255,1,255,255,255,1,124,124,124,1,161,161,161,1,130,130,130,1,232,232, + 232,1,126,126,126,1,164,164,164,1,227,227,227,1,225,225,225,1,80,80, + 80,1,232,232,232,1,114,114,114,1,177,177,177,1,232,232,232,1,79,79, + 79,1,211,211,211,1,255,255,255,1,174,117,88,1,208,208,208,2,136,136, + 136,1,181,248,254,1,168,226,230,1,133,174,176,1,190,243,246,1,201,252, + 254,1,206,253,254,1,168,202,202,1,207,254,254,1,184,251,254,1,122,188, + 192,1,111,199,206,1,114,242,254,1,136,136,136,1,0,0,0,1,159,159, + 255,1,146,146,146,1,124,124,124,1,231,231,231,1,133,133,133,1,46,46, + 46,1,83,83,83,1,164,164,164,1,180,180,180,1,140,140,140,1,232,232, + 232,2,219,219,219,1,136,136,136,1,43,43,43,1,68,68,68,1,226,226, + 226,1,255,255,255,1,0,0,0,1,208,208,208,3,6,116,124,1,8,148, + 158,1,10,175,187,1,8,142,152,1,1,26,28,1,0,0,0,2,7,7, + 255,1,4,4,255,2,4,4,252,1,2,2,85,1,208,208,208,2,255,255, + 255,1,212,226,232,1,248,251,253,1,149,223,255,1,148,223,255,1,255,0, + 38,1,163,228,255,1,255,0,38,1,163,228,255,1,255,0,38,1,163,228, + 255,1,255,0,38,1,163,228,255,1,255,0,38,1,163,228,255,1,225,246, + 255,1,241,250,255,1,248,251,253,1,217,243,254,1,203,34,3,1,124,124, + 124,1,177,177,177,1,128,128,128,1,232,232,232,1,123,123,123,1,168,168, + 168,1,232,232,232,1,225,225,225,1,80,80,80,1,232,232,232,1,129,129, + 129,1,176,176,176,1,232,232,232,1,76,76,76,1,216,216,216,1,255,255, + 255,1,224,224,224,1,208,208,208,2,136,136,136,1,179,245,251,1,66,88, + 90,1,138,180,183,1,85,108,110,1,201,252,254,1,112,138,138,1,52,63, + 63,1,207,254,254,1,122,166,168,1,94,145,148,1,58,104,108,1,94,199, + 209,1,136,136,136,1,0,0,0,1,208,208,208,2,124,124,124,1,226,226, + 226,1,105,105,105,1,174,174,174,1,119,119,119,1,43,43,43,1,36,36, + 36,1,160,160,160,1,232,232,232,2,223,223,223,1,141,141,141,1,45,45, + 45,1,67,67,67,1,226,226,226,1,255,255,255,1,146,195,199,1,136,136, + 136,1,208,208,208,3,0,0,0,5,208,208,208,1,5,5,255,1,4,4, + 255,3,4,4,199,1,0,0,0,1,208,208,208,1,255,255,255,1,219,225, + 229,1,215,234,243,1,136,214,247,1,143,219,251,1,255,0,38,1,255,255, + 255,1,255,0,38,1,255,255,255,1,255,0,38,1,255,255,255,1,255,0, + 38,1,255,255,255,1,255,0,38,1,255,255,255,1,244,249,251,1,231,243, + 248,1,215,234,243,1,238,248,253,1,218,100,75,1,124,124,124,1,227,227, + 227,1,86,86,86,1,232,232,232,1,78,78,78,1,207,207,207,1,232,232, + 232,1,225,225,225,1,80,80,80,1,232,232,232,1,187,187,187,1,126,126, + 126,1,228,228,228,1,57,57,57,1,232,232,232,1,255,255,255,1,96,232, + 72,1,208,208,208,2,136,136,136,1,156,214,219,1,91,122,125,1,191,250, + 254,1,68,88,89,1,201,252,254,1,168,206,207,1,85,103,103,1,207,254, + 254,1,75,102,104,1,153,235,241,1,107,191,198,1,65,139,145,1,136,136, + 136,1,0,0,0,2,0,0,255,1,124,124,124,1,232,232,232,7,214,214, + 214,1,105,105,105,1,29,29,29,1,102,102,102,1,199,199,199,1,232,232, + 232,2,255,255,255,1,114,242,254,1,255,255,255,1,208,208,208,1,255,0, + 32,6,208,208,208,1,5,5,255,1,4,4,255,4,4,4,254,1,2,2, + 103,1,208,208,208,1,0,0,0,1,194,212,221,1,182,217,233,1,115,199, + 235,1,123,205,239,1,255,0,38,1,182,217,233,1,255,0,38,1,182,217, + 233,1,255,0,38,1,182,217,233,1,255,0,38,1,182,217,233,1,255,0, + 38,1,182,217,233,1,210,232,241,1,197,225,238,1,182,217,233,1,226,240, + 246,1,224,224,224,1,124,124,124,1,232,232,232,1,149,149,149,1,90,90, + 90,1,144,144,144,1,232,232,232,2,227,227,227,1,118,118,118,1,232,232, + 232,1,230,230,230,1,123,123,123,1,89,89,89,1,174,174,174,1,232,232, + 232,1,255,255,255,1,0,0,0,1,255,255,255,1,208,208,208,1,136,136, + 136,1,159,218,223,1,98,132,134,1,191,250,254,1,75,95,97,1,201,252, + 254,1,206,253,254,1,85,103,103,1,207,254,254,1,79,108,110,1,157,242, + 248,1,111,199,206,1,65,138,144,1,136,136,136,1,0,0,0,1,255,255, + 255,1,136,136,136,1,124,124,124,1,232,232,232,7,187,187,187,1,136,136, + 136,1,221,221,221,1,232,232,232,4,255,255,255,1,208,208,208,1,255,255, + 255,1,208,208,208,1,255,0,32,6,0,0,0,1,4,4,255,6,3,3, + 213,1,0,0,0,1,255,255,255,1,168,199,213,1,148,200,223,1,94,185, + 223,1,102,190,227,1,255,0,38,1,109,180,212,1,255,0,38,1,109,180, + 212,1,255,0,38,1,109,180,212,1,255,0,38,1,109,180,212,1,255,0, + 38,1,109,180,212,1,175,214,231,1,163,208,227,1,148,200,223,1,198,225, + 238,1,208,208,208,1,124,124,124,1,232,232,232,14,255,255,255,1,208,208, + 208,1,255,255,255,1,208,208,208,1,136,136,136,1,181,248,254,1,77,104, + 106,1,177,231,235,1,73,94,95,1,201,252,254,1,206,253,254,1,85,103, + 103,1,207,254,254,1,120,163,165,1,121,187,191,1,77,137,142,1,85,180, + 189,1,136,136,136,1,0,0,0,1,255,255,255,1,208,208,208,1,124,124, + 124,1,232,232,232,14,255,255,255,1,224,224,224,1,255,255,255,1,208,208, + 208,1,255,0,32,6,0,0,0,1,208,208,208,1,0,0,0,7,208,208, + 208,1,143,186,206,1,115,184,214,1,74,171,211,1,81,176,215,1,255,0, + 38,1,36,143,190,1,255,0,38,1,36,143,190,1,255,0,38,1,36,143, + 190,1,255,0,38,1,36,143,190,1,255,0,38,1,36,143,190,1,141,197, + 221,1,128,190,217,1,115,184,214,1,170,211,229,1,208,208,208,1,124,124, + 124,1,255,255,255,15,208,208,208,1,236,37,236,1,208,208,208,1,136,136, + 136,1,181,248,254,1,150,200,204,1,98,128,130,1,173,221,224,1,201,252, + 254,1,206,253,254,1,148,178,178,1,207,254,254,1,179,244,247,1,98,151, + 154,1,85,153,158,1,114,242,254,1,136,136,136,1,0,0,0,1,255,255, + 255,2,124,124,124,1,232,232,232,14,255,255,255,2,208,208,208,2,255,0, + 32,6,0,0,0,1,208,208,208,8,255,0,255,1,117,174,199,1,82,167, + 204,1,53,156,199,1,61,161,204,1,255,0,38,1,208,208,208,1,255,0, + 38,1,208,208,208,1,255,0,38,1,208,208,208,1,255,0,38,1,208,208, + 208,1,255,0,38,1,208,208,208,1,107,179,211,1,94,173,207,1,82,167, + 204,1,141,196,220,1,208,208,208,17,255,255,255,2,208,208,208,1,136,136, + 136,1,181,248,254,1,186,249,254,1,191,250,254,1,196,251,254,1,201,252, + 254,1,206,253,254,1,211,254,254,1,207,254,254,1,184,251,254,1,161,248, + 254,1,137,245,254,1,114,242,254,1,136,136,136,1,0,0,0,1,255,255, + 255,2,124,124,124,1,232,232,232,14,255,255,255,2,208,208,208,2,255,0, + 32,6,0,0,0,1,208,208,208,8,255,0,255,1,92,161,191,1,49,150, + 194,1,33,142,187,1,40,147,192,1,208,208,208,10,73,162,201,1,60,155, + 197,1,49,150,194,1,112,182,212,1,255,255,255,1,208,208,208,16,255,255, + 255,1,213,213,213,1,208,208,208,1,136,136,136,14,0,0,0,1,182,175, + 175,1,208,208,208,1,124,124,124,1,232,232,232,14,255,255,255,2,0,0, + 255,1,208,208,208,1,255,0,32,6,0,0,0,1,208,208,208,8,255,255, + 255,1,67,148,184,1,16,133,184,1,12,127,176,1,208,208,208,12,25,138, + 187,1,16,133,184,1,84,168,204,1,255,255,255,1,208,208,208,17,213,213, + 213,1,208,208,208,1,0,0,0,16,255,255,255,1,124,124,124,1,255,255, + 255,15,208,208,208,1,226,27,226,1,208,208,208,2,0,0,0,6,208,208, + 208,8,212,212,212,1,42,135,176,1,35,142,187,1,44,147,190,1,117,175, + 199,1,208,208,208,11,156,190,205,1,77,162,200,1,56,153,195,1,136,136, + 136,1,255,255,255,16,208,208,208,1,252,224,227,1,255,255,255,16,121,121, + 121,1,111,241,255,1,255,255,255,16,208,208,208,1,193,193,193,1,255,255, + 255,16,208,208,208,1,218,218,218,1,255,255,255,16,217,217,217,1,173,173, + 173,1,153,153,153,1,142,142,142,2,140,140,140,12,141,141,141,1,148,148, + 148,1,255,255,255,18,208,208,208,18,212,212,212,19,208,208,208,16,57,49, + 50,1,153,153,153,1,208,208,208,1,154,154,154,1,158,158,158,1,154,154, + 154,11,158,158,158,1,208,208,208,1,159,159,159,1,128,76,240,1,124,124, + 124,15,255,255,255,1,208,208,208,19,212,212,212,1,208,208,208,16,212,212, + 212,1,208,208,208,5,155,155,155,1,156,154,154,1,158,157,157,1,160,157, + 158,1,156,154,154,1,153,153,153,1,208,208,208,6,121,121,121,1,132,132, + 132,1,154,154,154,1,157,157,157,1,186,186,186,1,222,222,222,1,223,223, + 223,8,207,207,207,1,157,157,157,1,154,154,154,1,208,208,208,1,158,158, + 158,1,208,208,208,1,124,124,124,1,192,192,192,2,169,169,169,1,186,186, + 186,1,170,170,170,1,166,166,166,1,169,169,169,1,174,174,174,1,165,165, + 165,1,142,142,142,1,169,169,169,1,188,188,188,1,172,172,172,1,160,160, + 160,1,255,255,255,1,208,208,208,19,212,212,212,1,208,208,208,5,0,0, + 0,6,208,208,208,5,255,212,217,2,208,208,208,2,149,149,149,1,158,158, + 158,1,162,159,159,1,203,192,193,1,225,212,213,1,225,209,210,1,204,190, + 192,1,159,156,156,1,139,139,139,1,138,138,138,1,208,208,208,4,255,0, + 0,1,124,124,124,1,138,138,138,1,134,134,134,11,139,139,139,1,190,190, + 190,1,154,154,154,1,208,208,208,1,158,158,158,1,208,208,208,1,124,124, + 124,1,139,139,139,1,152,152,152,1,169,169,169,1,183,183,183,1,148,148, + 148,2,169,169,169,1,152,152,152,1,129,129,129,1,112,112,112,1,169,169, + 169,1,184,184,184,1,142,142,142,1,141,141,141,1,255,255,255,2,126,126, + 126,1,139,139,139,16,143,143,143,1,153,152,152,1,208,208,208,4,0,0, + 0,8,208,208,208,4,121,121,121,2,208,208,208,2,156,155,155,1,182,175, + 175,1,245,225,226,1,254,236,238,1,254,232,234,1,254,228,231,1,255,225, + 228,1,250,218,221,1,182,171,172,1,131,129,129,1,0,0,0,1,208,208, + 208,3,156,156,156,1,122,122,122,1,134,134,134,1,170,170,255,1,174,174, + 255,1,178,178,255,1,182,182,255,1,187,187,255,1,191,191,255,1,195,195, + 255,1,200,200,255,1,204,204,255,1,208,208,255,1,212,212,255,1,134,134, + 134,1,215,215,215,1,154,154,154,1,208,208,208,1,158,158,158,1,124,124, + 124,2,171,171,171,1,180,180,180,1,169,169,169,1,192,192,192,1,172,172, + 172,1,164,164,164,1,169,169,169,1,192,192,192,3,169,169,169,1,192,192, + 192,1,181,181,181,1,169,169,169,1,255,255,255,2,139,139,139,1,217,217, + 217,2,197,197,197,1,200,200,200,1,217,217,217,1,205,205,205,1,210,210, + 210,1,217,217,217,1,216,216,216,1,205,205,205,2,201,201,201,1,217,217, + 217,2,208,208,208,1,206,206,206,1,249,249,249,1,120,174,202,1,208,208, + 208,4,0,0,0,2,0,0,155,1,0,0,255,1,0,0,254,1,0,0, + 155,1,0,0,0,2,208,208,208,4,255,0,255,1,121,121,121,1,208,208, + 208,1,152,152,152,1,163,161,161,1,245,224,225,1,253,235,236,1,159,146, + 147,1,85,77,78,1,86,76,77,1,155,135,137,1,255,218,223,1,251,211, + 216,1,160,156,156,1,77,77,77,1,0,0,0,1,208,208,208,2,241,241, + 241,1,122,122,122,1,134,134,134,1,170,170,255,1,174,174,255,1,178,178, + 255,1,182,182,255,1,187,187,255,1,0,0,0,1,195,195,255,1,200,200, + 255,1,204,204,255,1,208,208,255,1,212,212,255,1,134,134,134,1,215,215, + 215,1,154,154,154,1,208,208,208,1,158,158,158,1,255,255,255,1,124,124, + 124,1,169,169,169,14,255,255,255,2,139,139,139,1,217,217,217,1,126,126, + 126,1,33,33,33,1,44,44,44,1,171,171,171,1,136,136,136,1,128,128, + 128,1,217,217,217,1,195,195,195,1,97,97,97,1,102,102,102,1,60,60, + 60,1,212,212,212,1,217,217,217,1,104,104,104,1,121,121,121,1,249,249, + 249,1,0,255,255,1,208,208,208,3,0,0,0,1,0,0,1,1,0,0, + 56,1,0,0,255,4,0,0,72,1,0,0,1,1,0,0,0,1,208,208, + 208,3,225,225,225,1,128,128,128,1,208,208,208,1,158,157,157,1,211,197, + 198,1,252,233,234,1,253,233,235,1,82,74,75,1,252,224,227,1,254,222, + 226,1,50,43,44,1,252,212,217,1,255,212,217,1,216,189,192,1,134,131, + 132,1,0,0,0,1,208,208,208,2,212,212,212,1,122,122,122,1,134,134, + 134,1,170,170,255,1,174,174,255,1,178,178,255,1,182,182,255,1,187,187, + 255,1,191,191,255,1,195,195,255,1,200,200,255,1,204,204,255,1,208,208, + 255,1,212,212,255,1,134,134,134,1,215,215,215,1,154,154,154,1,208,208, + 208,1,158,158,158,1,255,255,255,1,124,124,124,1,194,194,194,1,192,192, + 192,1,169,169,169,1,211,211,211,1,186,186,186,1,173,173,173,1,169,169, + 169,1,231,231,231,1,205,205,205,1,189,189,189,1,169,169,169,1,226,226, + 226,1,182,182,182,1,189,189,189,1,255,255,255,1,215,88,53,1,139,139, + 139,1,206,206,206,1,45,45,45,1,191,191,191,1,147,147,147,1,80,80, + 80,1,191,191,191,1,74,74,74,1,197,197,197,1,137,137,137,1,118,118, + 118,1,102,102,102,1,31,31,31,1,171,171,171,1,217,217,217,1,43,43, + 43,1,109,109,109,1,249,249,249,1,201,2,201,1,208,208,208,3,0,0, + 234,1,0,0,211,1,0,0,222,1,0,0,255,4,0,0,92,1,0,0, + 11,1,0,0,131,1,208,208,208,3,212,212,212,2,208,208,208,1,157,156, + 156,1,235,218,219,1,255,236,238,1,255,232,234,1,255,228,231,1,255,224, + 228,1,204,176,179,1,68,58,59,1,255,212,217,2,238,202,206,1,152,150, + 150,1,0,0,0,2,208,208,208,1,212,212,212,1,122,122,122,1,134,134, + 134,13,215,215,215,1,154,154,154,1,208,208,208,1,158,158,158,1,188,140, + 117,1,124,124,124,1,160,160,160,1,166,166,166,1,169,169,169,1,199,199, + 199,1,135,135,135,1,179,179,179,1,169,169,169,1,173,173,173,1,166,166, + 166,1,157,157,157,1,169,169,169,1,255,255,255,1,179,179,179,2,255,255, + 255,1,224,224,224,1,139,139,139,1,203,203,203,1,53,53,53,1,141,141, + 141,1,188,188,188,1,165,165,165,1,211,211,211,1,105,105,105,1,142,142, + 142,1,60,60,60,1,185,185,185,1,103,103,103,1,63,63,63,1,136,136, + 136,1,196,196,196,1,45,45,45,1,113,113,113,1,249,249,249,1,66,66, + 66,1,208,208,208,3,0,0,255,6,0,0,182,1,0,0,5,1,0,0, + 94,1,0,0,204,1,0,0,0,1,208,208,208,2,255,255,255,1,208,208, + 208,2,156,155,155,1,244,227,229,1,255,233,235,1,255,229,232,1,255,225, + 228,1,229,198,202,1,57,49,50,1,233,195,199,1,255,212,217,2,244,206, + 210,1,153,152,152,1,0,0,0,2,208,208,208,1,218,218,218,1,122,122, + 122,1,134,134,134,1,173,249,241,1,173,255,247,1,178,255,247,1,182,255, + 248,1,186,255,249,1,191,255,249,1,195,255,250,1,199,255,251,1,203,255, + 252,1,208,255,252,1,212,255,253,1,144,149,149,1,215,215,215,1,154,154, + 154,1,208,208,208,1,158,158,158,1,0,252,248,1,124,124,124,1,185,185, + 185,1,176,176,176,1,169,169,169,1,255,255,255,3,169,169,169,1,239,239, + 239,1,204,204,204,1,186,186,186,1,169,169,169,1,255,255,255,4,14,181, + 0,1,139,139,139,1,217,217,217,1,154,154,154,1,42,42,42,1,43,43, + 43,1,167,167,167,1,217,217,217,1,166,166,166,1,38,38,38,1,106,106, + 106,1,216,216,216,1,103,103,103,1,92,92,92,1,118,118,118,1,130,130, + 130,1,92,92,92,1,113,113,113,1,249,249,249,1,210,210,210,1,208,208, + 208,3,0,0,255,5,0,0,184,1,0,0,9,1,0,0,59,1,0,0, + 247,1,0,0,240,1,0,0,0,1,208,208,208,2,210,210,210,2,208,208, + 208,1,161,158,160,1,224,209,211,1,255,230,233,1,255,226,229,1,255,222, + 226,1,166,142,145,1,164,138,141,1,255,212,217,3,224,194,197,1,142,139, + 139,1,0,0,0,2,208,208,208,1,210,210,210,1,122,122,122,1,134,134, + 134,1,173,249,241,1,173,255,247,1,178,255,247,1,182,255,248,1,186,255, + 249,1,0,0,0,1,195,255,250,1,199,255,251,1,203,255,252,1,208,255, + 252,1,212,255,253,1,144,149,149,1,215,215,215,1,154,154,154,1,208,208, + 208,1,158,158,158,1,224,224,224,1,124,124,124,1,169,169,169,14,255,255, + 255,1,208,208,208,1,139,139,139,1,210,210,210,1,199,199,199,1,212,212, + 212,1,136,136,136,1,47,47,47,1,217,217,217,2,46,46,46,1,209,209, + 209,1,217,217,217,1,103,103,103,1,101,101,101,2,65,65,65,1,165,165, + 165,1,113,113,113,1,249,249,249,1,210,210,210,1,208,208,208,3,0,0, + 255,4,0,0,211,1,0,0,6,1,0,0,49,1,0,0,238,1,0,0, + 255,1,0,0,240,1,0,0,0,1,208,208,208,2,210,210,210,2,208,208, + 208,1,155,155,155,1,182,175,175,1,255,227,230,1,255,223,227,1,255,219, + 223,1,207,175,179,1,210,175,179,1,255,212,217,3,181,168,169,1,100,100, + 100,1,0,0,0,2,208,208,208,1,210,210,210,1,122,122,122,1,134,134, + 134,1,173,249,241,1,173,255,247,1,178,255,247,1,182,255,248,1,186,255, + 249,1,191,255,249,1,195,255,250,1,199,255,251,1,203,255,252,1,208,255, + 252,1,212,255,253,1,144,149,149,1,215,215,215,1,154,154,154,1,208,208, + 208,1,158,158,158,1,13,182,0,1,124,124,124,1,186,186,186,1,192,192, + 192,1,169,169,169,1,226,226,226,1,207,207,207,1,186,186,186,1,169,169, + 169,1,226,226,226,1,207,207,207,1,186,186,186,1,169,169,169,1,221,221, + 221,1,207,207,207,1,190,190,190,1,255,255,255,1,207,207,207,1,139,139, + 139,1,178,178,178,1,73,73,73,1,209,209,209,1,198,198,198,1,51,51, + 51,1,217,217,217,2,48,48,48,1,214,214,214,1,217,217,217,1,103,103, + 103,1,113,113,113,1,101,101,101,1,52,52,52,1,186,186,186,1,113,113, + 113,1,249,249,249,1,210,210,210,1,208,208,208,3,0,0,255,4,0,0, + 95,1,0,0,12,1,0,0,233,1,0,0,255,2,0,0,204,1,0,0, + 0,1,208,208,208,2,210,210,210,2,208,208,208,1,146,146,146,1,153,152, + 152,1,216,197,199,1,255,220,224,1,255,216,221,1,195,162,166,1,199,165, + 169,1,255,212,217,2,216,189,193,1,149,150,153,1,53,103,129,1,5,9, + 12,1,0,0,0,1,208,208,208,1,210,210,210,1,122,122,122,1,134,134, + 134,13,215,215,215,1,154,154,154,1,208,208,208,1,158,158,158,1,124,124, + 124,2,161,161,161,1,192,192,192,1,169,169,169,1,174,174,174,1,138,138, + 138,1,136,136,136,1,169,169,169,1,174,174,174,1,138,138,138,1,136,136, + 136,1,169,169,169,1,174,174,174,1,128,128,128,1,150,150,150,1,255,255, + 255,2,139,139,139,1,212,212,212,1,80,80,80,1,45,45,45,1,49,49, + 49,1,105,105,105,1,217,217,217,2,48,48,48,1,214,214,214,1,217,217, + 217,1,103,103,103,1,124,124,124,1,117,117,117,1,91,91,91,1,186,186, + 186,1,113,113,113,1,249,249,249,1,210,210,210,1,208,208,208,3,0,0, + 255,1,0,0,254,1,0,0,255,2,0,0,54,1,0,0,61,1,0,0, + 255,2,0,0,254,1,0,0,89,1,0,0,0,1,208,208,208,2,210,210, + 210,2,208,208,208,2,150,150,150,1,151,149,150,1,186,173,174,1,241,205, + 209,1,255,212,217,2,241,204,208,1,186,171,173,1,152,152,153,1,165,194, + 209,1,120,174,202,1,61,124,155,1,12,24,30,1,208,208,208,1,128,128, + 128,1,122,122,122,1,134,134,134,1,255,170,184,1,255,174,187,1,255,178, + 190,1,255,182,193,1,255,187,196,1,255,191,199,1,255,195,202,1,255,200, + 205,1,255,204,208,1,255,208,211,1,255,212,214,1,134,134,134,1,215,215, + 215,1,154,154,154,1,208,208,208,1,158,158,158,1,255,255,255,1,124,124, + 124,1,164,164,164,1,192,192,192,1,169,169,169,1,236,236,236,1,219,219, + 219,1,201,201,201,1,169,169,169,1,236,236,236,1,219,219,219,1,201,201, + 201,1,169,169,169,1,231,231,231,1,219,219,219,1,204,204,204,1,255,255, + 255,2,139,139,139,1,217,217,217,2,159,159,159,1,157,157,157,1,212,212, + 212,1,217,217,217,2,164,164,164,1,217,217,217,2,187,187,187,1,194,194, + 194,1,192,192,192,1,196,196,196,1,207,207,207,1,185,185,185,1,249,249, + 249,1,210,210,210,1,208,208,208,4,0,0,223,1,0,0,254,1,0,0, + 255,1,0,0,188,1,0,0,199,1,0,0,255,1,0,0,254,1,0,0, + 158,1,0,0,0,2,208,208,208,2,210,210,210,2,208,208,208,3,63,63, + 63,1,120,119,119,1,150,148,149,1,153,152,152,2,150,148,149,1,112,111, + 111,1,64,111,135,1,131,181,206,1,168,203,221,1,120,175,202,1,61,124, + 155,1,18,37,46,1,210,210,210,1,122,122,122,1,134,134,134,1,255,170, + 184,1,255,174,187,1,255,178,190,1,255,182,193,1,255,187,196,1,0,0, + 0,1,255,195,202,1,255,200,205,1,255,204,208,1,255,208,211,1,255,212, + 214,1,134,134,134,1,182,182,182,1,158,158,158,1,208,208,208,1,158,158, + 158,1,255,255,255,1,124,124,124,1,169,169,169,14,255,255,255,1,206,48, + 6,1,139,139,139,1,217,217,217,16,249,249,249,1,210,210,210,1,208,208, + 208,5,0,0,136,1,0,0,204,1,0,0,167,1,0,0,172,1,0,0, + 204,1,0,0,89,1,0,0,0,2,208,208,208,3,210,210,210,2,208,208, + 208,4,0,0,0,2,24,24,24,1,20,20,20,1,0,0,0,2,7,14, + 18,1,74,136,168,1,131,181,206,1,168,203,221,1,120,175,202,1,52,106, + 133,1,210,210,210,1,122,122,122,1,134,134,134,1,255,170,184,1,255,174, + 187,1,255,178,190,1,255,182,193,1,255,187,196,1,255,191,199,1,255,195, + 202,1,255,200,205,1,255,204,208,1,255,208,211,1,255,212,214,1,134,134, + 134,1,150,150,150,1,24,24,24,1,0,0,0,1,160,160,160,1,255,255, + 255,1,124,124,124,1,197,197,197,1,192,192,192,1,169,169,169,1,224,224, + 224,1,216,216,216,1,207,207,207,1,169,169,169,1,234,234,234,1,216,216, + 216,2,169,169,169,1,253,253,253,1,208,208,208,1,210,210,210,1,255,255, + 255,1,0,0,0,1,143,143,143,1,248,248,248,16,254,254,254,1,210,210, + 210,1,208,208,208,6,0,0,0,6,208,208,208,4,210,210,210,2,208,208, + 208,6,0,0,0,4,208,208,208,1,27,56,70,1,73,135,166,1,130,181, + 206,1,168,202,220,1,54,78,90,1,210,210,210,1,122,122,122,1,136,136, + 136,1,134,134,134,11,137,137,137,1,43,43,43,1,0,0,0,1,208,208, + 208,1,104,104,104,1,255,255,255,1,124,124,124,1,161,161,161,1,145,145, + 145,1,169,169,169,1,166,166,166,1,173,173,173,1,170,170,170,1,169,169, + 169,1,234,234,234,1,169,169,169,1,179,179,179,1,169,169,169,1,243,243, + 243,1,166,166,166,1,96,96,96,1,255,255,255,2,208,208,208,18,210,210, + 210,1,208,208,208,7,0,0,0,2,208,208,208,7,210,210,210,2,208,208, + 208,12,40,80,101,1,65,120,147,1,60,83,96,1,0,0,0,1,218,218, + 218,1,122,122,122,1,0,0,0,14,208,208,208,2,20,20,20,1,255,255, + 255,1,124,124,124,1,246,246,246,1,255,255,255,15,208,208,208,37,210,210, + 210,16,208,208,208,1,114,114,114,1,123,123,123,13,124,124,124,1,90,90, + 90,1,33,33,33,1,32,32,32,1,208,208,208,1,255,255,255,16,224,224, + 224,1,208,208,208,36,200,202,192,1,203,204,199,1,200,203,200,2,209,209, + 209,2,208,208,208,11,209,209,209,1,0,0,0,1,255,255,255,16,99,99, + 99,1,208,208,208,71,209,205,204,1,191,250,254,1,208,208,208,71,208,205, + 203,1,208,208,208,16,209,209,209,1,0,0,0,1,208,208,208,17,217,217, + 217,4,255,255,255,1,128,128,128,1,217,217,217,4,208,208,208,44,209,207, + 207,1,208,208,208,7,0,0,182,2,208,208,208,7,207,207,207,1,0,0, + 255,1,208,208,208,7,0,0,182,2,208,208,208,7,98,98,241,1,208,208, + 208,54,209,209,209,1,208,208,208,5,0,0,195,1,0,0,206,1,0,0, + 214,2,0,0,206,1,0,0,195,1,208,208,208,5,208,202,201,1,224,224, + 224,1,208,208,208,5,0,0,195,1,0,0,206,1,0,0,214,2,0,0, + 206,1,0,0,195,1,208,208,208,5,217,217,217,1,208,208,208,54,208,204, + 202,1,208,208,208,4,0,0,200,1,0,0,233,1,0,0,255,4,0,0, + 228,1,0,0,187,1,208,208,208,4,209,205,204,1,224,224,224,1,208,208, + 208,4,0,0,200,1,0,0,233,1,0,0,255,4,0,0,228,1,0,0, + 187,1,208,208,208,4,54,54,54,1,208,208,208,54,207,199,197,1,208,208, + 208,3,0,0,195,1,0,0,233,1,0,0,255,6,0,0,226,1,0,0, + 140,1,208,208,208,3,210,210,210,1,217,217,217,1,208,208,208,3,0,0, + 195,1,0,0,233,1,0,0,255,6,0,0,226,1,0,0,140,1,208,208, + 208,4,218,218,218,1,217,217,217,7,255,255,255,1,128,128,128,1,217,217, + 217,4,208,208,208,40,210,210,210,1,208,208,208,3,0,0,206,1,0,0, + 255,8,0,0,180,1,0,0,0,1,208,208,208,2,207,207,207,1,0,0, + 255,1,208,208,208,3,0,0,206,1,0,0,255,8,0,0,180,1,0,0, + 0,1,208,208,208,2,136,136,136,1,0,0,0,1,98,2,17,1,232,165, + 35,1,34,16,65,1,0,0,0,1,136,9,0,1,64,29,40,1,20,29, + 40,1,0,0,0,2,36,29,40,1,0,0,0,2,0,0,1,1,208,208, + 208,4,0,0,0,2,236,236,236,34,209,209,209,1,208,208,208,2,0,0, + 182,1,0,0,214,1,0,0,255,8,0,0,197,1,0,0,13,1,208,208, + 208,2,207,200,198,1,0,0,0,1,208,208,208,2,0,0,182,1,0,0, + 214,1,0,0,255,8,0,0,197,1,0,0,13,1,208,208,208,2,128,196, + 201,1,0,0,0,54,208,203,201,1,208,208,208,2,0,0,182,1,0,0, + 214,1,0,0,255,8,0,0,197,1,0,0,10,1,208,208,208,2,207,201, + 199,1,144,188,191,1,208,208,208,2,0,0,182,1,0,0,214,1,0,0, + 255,8,0,0,197,1,0,0,10,1,208,208,208,2,163,163,166,1,0,0, + 0,42,255,255,255,12,205,199,198,1,208,208,208,3,0,0,206,1,0,0, + 255,8,0,0,179,1,0,0,0,1,208,208,208,2,209,207,206,1,136,136, + 136,1,208,208,208,3,0,0,206,1,0,0,255,8,0,0,179,1,0,0, + 0,1,208,208,208,3,0,0,0,3,38,38,38,1,1,1,1,1,0,0, + 0,27,255,255,255,1,140,140,140,14,255,255,255,1,0,0,0,2,255,255, + 255,4,207,200,198,1,208,208,208,3,0,0,195,1,0,0,228,1,0,0, + 255,6,0,0,226,1,0,0,107,1,0,0,0,1,208,208,208,2,208,207, + 206,1,208,208,208,4,0,0,195,1,0,0,228,1,0,0,255,6,0,0, + 226,1,0,0,107,1,0,0,0,1,208,208,208,2,224,224,224,1,0,0, + 0,22,255,255,255,1,140,140,140,14,255,255,255,1,0,0,0,1,255,255, + 255,14,0,0,0,1,209,209,209,1,208,208,208,4,0,0,187,1,0,0, + 226,1,0,0,255,4,0,0,226,1,0,0,154,1,0,0,0,2,208,208, + 208,2,210,210,210,1,224,224,224,1,208,208,208,4,0,0,187,1,0,0, + 226,1,0,0,255,4,0,0,226,1,0,0,154,1,0,0,0,2,208,208, + 208,3,255,255,255,13,140,140,140,14,255,255,255,17,0,0,0,1,255,255, + 255,9,209,205,204,1,208,208,208,5,0,0,140,1,0,0,180,1,0,0, + 197,2,0,0,179,1,0,0,107,1,0,0,0,2,208,208,208,3,208,206, + 206,1,255,255,255,1,208,208,208,5,0,0,140,1,0,0,180,1,0,0, + 197,2,0,0,179,1,0,0,107,1,0,0,0,2,208,208,208,3,255,255, + 255,1,140,140,140,1,255,255,255,2,140,140,140,14,255,255,255,17,0,0, + 0,1,255,255,255,15,0,0,0,3,128,128,128,1,208,210,210,1,208,208, + 208,6,0,0,0,1,0,0,13,1,0,0,10,1,0,0,0,3,208,208, + 208,4,210,210,210,1,255,255,255,1,208,208,208,6,0,0,0,1,0,0, + 13,1,0,0,10,1,0,0,0,3,208,208,208,4,255,255,255,1,140,140, + 140,1,221,221,221,1,216,216,216,3,163,163,163,1,140,140,140,1,255,255, + 255,17,0,0,0,1,255,255,255,15,0,0,0,3,128,128,128,1,255,255, + 255,5,182,182,182,1,7,7,7,1,0,0,0,3,210,210,210,1,208,208, + 208,16,208,204,202,1,208,208,208,17,255,30,64,1,255,255,255,14,0,0, + 0,1,255,255,255,15,0,0,0,3,128,128,128,1,255,255,255,6,219,219, + 219,1,30,30,30,1,0,0,0,4,255,255,255,1,175,175,175,1,191,191, + 191,1,140,140,140,1,192,192,192,1,174,174,174,1,143,143,143,1,144,144, + 144,1,209,209,209,1,208,208,208,16,207,201,199,1,208,208,208,18,255,255, + 255,4,0,0,0,1,255,255,255,15,0,0,0,3,128,128,128,1,255,255, + 255,6,230,230,230,1,125,125,125,1,14,14,14,1,0,0,0,3,255,255, + 255,1,168,168,168,1,191,191,191,1,140,140,140,1,194,194,194,1,172,172, + 172,1,140,140,140,1,144,144,144,1,215,215,215,1,140,140,140,1,191,191, + 191,1,168,168,168,1,140,140,140,1,218,218,218,1,148,148,148,1,255,255, + 255,2,140,140,140,1,209,196,192,1,208,202,200,1,207,200,198,1,207,199, + 196,1,208,201,199,1,208,204,203,1,209,209,209,1,209,206,205,1,208,202, + 200,1,208,198,196,1,207,199,197,1,208,201,199,3,207,201,198,1,207,198, + 198,1,206,200,200,1,205,192,192,1,255,30,64,1,255,255,255,16,124,124, + 124,1,255,255,255,10,0,0,0,3,128,128,128,1,255,255,255,5,212,212, + 212,1,143,143,143,1,110,110,110,1,14,14,14,1,0,0,0,3,255,255, + 255,1,143,143,143,1,212,212,212,1,140,140,140,1,216,216,216,1,152,152, + 152,1,140,140,140,1,144,144,144,1,215,215,215,1,140,140,140,1,162,162, + 162,1,193,193,193,1,142,142,142,1,227,227,227,1,140,140,140,1,255,255, + 255,2,140,140,140,1,187,187,187,1,176,176,176,1,196,196,196,1,220,220, + 220,1,148,148,148,1,227,227,227,1,140,140,140,1,227,227,227,1,140,140, + 140,2,80,27,0,0,0,0,0,6,46,46,46,1,21,21,21,1,0,0, + 0,3,5,5,5,1,0,0,0,80,9,9,9,1,2,2,2,1,0,0, + 0,1,6,6,6,1,207,207,207,1,212,212,212,1,116,116,116,1,122,122, + 122,1,161,161,161,1,232,232,232,1,87,87,87,1,6,6,6,1,0,0, + 0,5,255,255,255,16,0,0,0,38,255,255,255,15,128,128,128,1,0,0, + 0,3,102,102,102,1,205,205,205,1,128,128,128,1,114,114,114,1,231,231, + 231,1,255,255,255,1,247,247,247,1,248,248,248,1,253,253,253,2,179,179, + 179,1,114,114,114,1,48,48,48,1,0,0,0,4,255,255,255,16,0,0, + 0,5,155,155,155,1,27,27,27,1,0,0,0,31,255,255,255,16,0,0, + 0,3,35,35,35,1,241,241,241,1,253,253,253,1,245,245,245,1,255,255, + 255,7,219,219,219,1,147,147,147,1,159,159,159,1,172,172,172,1,0,0, + 0,2,255,255,255,16,0,0,0,5,196,196,196,1,221,221,221,1,65,65, + 65,1,0,0,0,30,255,255,255,16,0,0,0,3,48,48,48,1,222,222, + 222,1,255,255,255,10,251,251,251,1,255,255,255,1,173,173,173,1,0,0, + 0,2,255,255,255,16,0,0,0,5,192,192,192,1,255,255,255,1,239,239, + 239,1,118,118,118,1,0,0,0,11,255,255,255,16,0,0,0,2,255,255, + 255,16,0,0,0,2,6,6,6,1,114,114,114,1,231,231,231,1,255,255, + 255,11,246,246,246,1,118,118,118,1,6,6,6,1,0,0,0,1,255,255, + 255,16,0,0,0,5,192,192,192,1,255,255,255,2,248,248,248,1,167,167, + 167,1,3,3,3,1,0,0,0,9,255,255,255,16,0,0,0,2,255,255, + 255,16,0,0,0,2,55,55,55,1,169,169,169,1,255,255,255,13,169,169, + 169,1,55,55,55,1,0,0,0,2,255,255,255,15,0,0,0,5,192,192, + 192,1,255,255,255,3,254,254,254,1,202,202,202,1,18,18,18,1,0,0, + 0,8,255,255,255,16,0,0,0,2,255,255,255,16,0,0,0,2,97,97, + 97,1,226,226,226,1,255,255,255,13,230,230,230,1,99,99,99,1,0,0, + 0,1,255,255,255,16,0,0,0,5,192,192,192,1,255,255,255,5,222,222, + 222,1,50,50,50,1,0,0,0,7,255,255,255,16,0,0,0,2,255,255, + 255,16,0,0,0,1,24,24,24,1,239,239,239,1,255,255,255,14,253,253, + 253,1,185,185,185,1,0,0,0,1,255,255,255,16,0,0,0,5,192,192, + 192,1,255,255,255,6,235,235,235,1,101,101,101,1,0,0,0,6,255,255, + 255,16,0,0,0,2,255,255,255,16,0,0,0,2,153,153,153,1,251,251, + 251,1,255,255,255,13,246,246,246,1,122,122,122,1,0,0,0,1,255,255, + 255,16,0,0,0,5,192,192,192,1,255,255,255,6,241,241,241,1,166,166, + 166,1,14,14,14,1,0,0,0,5,255,255,255,16,0,0,0,2,255,255, + 255,16,0,0,0,2,114,114,114,1,236,236,236,1,255,255,255,13,236,236, + 236,1,114,114,114,1,0,0,0,1,255,255,255,16,0,0,0,5,192,192, + 192,1,255,255,255,5,235,235,235,1,162,162,162,1,110,110,110,1,14,14, + 14,1,0,0,0,5,255,255,255,16,0,0,0,2,255,255,255,16,0,0, + 0,2,91,91,91,1,210,210,210,1,255,255,255,13,215,215,215,1,91,91, + 91,1,0,0,0,1,255,255,255,16,0,0,0,5,192,192,192,1,255,255, + 255,3,254,254,254,1,227,227,227,1,148,148,148,1,87,87,87,1,4,4, + 4,1,0,0,0,6,255,255,255,16,0,0,0,2,255,255,255,16,0,0, + 0,2,55,55,55,1,195,195,195,1,255,255,255,13,235,235,235,1,55,55, + 55,1,0,0,0,1,255,255,255,16,0,0,0,5,192,192,192,1,255,255, + 255,2,249,249,249,1,212,212,212,1,139,139,139,1,61,61,61,1,0,0, + 0,8,255,255,255,16,0,0,0,2,255,255,255,16,0,0,0,2,6,6, + 6,1,231,231,231,1,248,248,248,1,255,255,255,11,220,220,220,1,120,120, + 120,1,6,6,6,1,0,0,0,1,255,255,255,16,0,0,0,5,192,192, + 192,1,255,255,255,1,243,243,243,1,191,191,191,1,130,130,130,1,37,37, + 37,1,0,0,0,9,255,255,255,16,0,0,0,2,255,255,255,16,0,0, + 0,3,63,63,63,1,145,145,145,1,237,237,237,1,255,255,255,9,236,236, + 236,1,145,145,145,1,48,48,48,1,0,0,0,2,255,255,255,16,0,0, + 0,5,196,196,196,1,228,228,228,1,169,169,169,1,116,116,116,1,19,19, + 19,1,0,0,0,28,255,255,255,16,0,0,0,4,62,62,62,1,153,153, + 153,1,238,238,238,1,255,255,255,7,219,219,219,1,145,145,145,1,62,62, + 62,1,0,0,0,3,255,255,255,16,0,0,0,5,155,155,155,1,90,90, + 90,1,96,96,96,1,7,7,7,1,0,0,0,29,255,255,255,16,0,0, + 0,5,48,48,48,1,114,114,114,1,169,169,169,1,210,210,210,1,237,237, + 237,1,245,245,245,1,236,236,236,1,241,241,241,1,238,238,238,1,114,114, + 114,1,48,48,48,1,0,0,0,5,255,255,255,15,0,0,0,6,21,21, + 21,1,1,1,1,1,0,0,0,30,255,255,255,1,128,128,128,1,255,255, + 255,14,0,0,0,6,6,6,6,1,55,55,55,1,91,91,91,1,114,114, + 114,1,122,122,122,1,114,114,114,1,111,111,111,1,93,93,93,1,6,6, + 6,1,0,0,0,241,255,255,255,1,0,0,0,16,255,255,255,8,251,251, + 251,1,70,70,70,1,1,1,1,1,0,0,0,29,8,8,8,1,101,101, + 101,1,149,149,149,1,148,148,148,1,105,105,105,1,10,10,10,1,0,0, + 0,27,255,255,255,2,0,0,0,1,9,9,9,1,21,21,21,1,27,27, + 27,2,22,22,22,1,51,51,51,1,32,32,32,1,57,57,57,1,0,0, + 0,6,255,255,255,9,253,253,253,1,103,103,103,1,1,1,1,1,0,0, + 0,12,7,7,7,2,0,0,0,13,29,29,29,1,224,224,224,1,255,255, + 255,1,215,215,215,1,218,218,218,1,255,255,255,1,225,225,225,1,36,36, + 36,1,0,0,0,24,255,255,255,5,52,52,52,1,98,98,98,1,91,91, + 91,1,82,82,82,1,74,74,74,1,56,56,56,1,107,107,107,1,58,58, + 58,1,0,0,0,6,255,255,255,10,253,253,253,1,111,111,111,1,1,1, + 1,1,0,0,0,9,102,102,102,1,201,201,201,1,220,220,220,2,201,201, + 201,1,102,102,102,1,0,0,0,11,185,185,185,1,255,255,255,1,199,199, + 199,1,229,229,229,2,199,199,199,1,254,254,254,1,195,195,195,1,0,0, + 0,6,255,255,255,16,0,0,0,2,255,255,255,1,0,0,0,1,255,255, + 255,2,0,0,0,4,14,14,14,1,6,6,6,1,14,14,14,1,0,0, + 0,1,14,14,14,1,0,0,0,6,255,255,255,11,253,253,253,1,119,119, + 119,1,1,1,1,1,0,0,0,7,166,166,166,1,242,242,242,1,255,255, + 255,4,247,247,247,1,177,177,177,1,0,0,0,9,17,17,17,1,253,253, + 253,1,255,255,255,6,254,254,254,1,13,13,13,1,0,0,0,5,255,255, + 255,16,0,0,0,2,255,255,255,1,0,0,0,1,255,255,255,1,8,8, + 8,1,0,0,0,4,94,94,94,1,78,78,78,1,93,93,93,1,80,80, + 80,1,76,76,76,1,0,0,0,6,255,255,255,12,253,253,253,1,128,128, + 128,1,2,2,2,1,0,0,0,5,102,102,102,1,242,242,242,1,255,255, + 255,6,249,249,249,1,142,142,142,1,0,0,0,8,62,62,62,1,253,253, + 253,1,255,255,255,7,111,111,111,1,0,0,0,5,255,255,255,16,0,0, + 0,2,255,255,255,1,0,0,0,7,45,45,45,1,49,49,49,1,47,47, + 47,1,61,61,61,1,28,28,28,1,0,0,0,6,255,255,255,14,54,54, + 54,1,0,0,0,5,201,201,201,1,255,255,255,8,230,230,230,1,32,32, + 32,1,0,0,0,7,175,175,175,1,255,255,255,8,219,219,219,1,32,32, + 32,1,0,0,0,4,255,255,255,16,0,0,0,2,255,255,255,1,0,0, + 0,4,20,20,20,1,43,43,43,1,40,40,40,1,87,87,87,1,35,35, + 35,1,18,18,18,1,0,0,0,2,255,255,255,3,0,0,0,3,255,255, + 255,14,136,136,136,1,0,0,0,4,7,7,7,1,220,220,220,1,255,255, + 255,8,239,239,239,1,100,100,100,1,0,0,0,7,229,229,229,1,255,255, + 255,8,243,243,243,1,96,96,96,1,0,0,0,4,255,255,255,16,0,0, + 0,2,255,255,255,1,0,0,0,4,42,42,42,1,79,79,79,1,80,80, + 80,1,94,94,94,1,74,74,74,1,41,41,41,1,0,0,0,4,255,255, + 255,1,0,0,0,3,255,255,255,14,138,138,138,1,0,0,0,4,7,7, + 7,1,220,220,220,1,255,255,255,8,239,239,239,1,130,130,130,1,0,0, + 0,7,229,229,229,1,255,255,255,8,243,243,243,1,126,126,126,1,0,0, + 0,4,255,255,255,16,0,0,0,2,255,255,255,1,0,0,0,14,255,255, + 255,1,0,0,0,3,255,255,255,14,138,138,138,1,0,0,0,5,201,201, + 201,1,255,255,255,8,231,231,231,1,126,126,126,1,0,0,0,7,175,175, + 175,1,255,255,255,8,219,219,219,1,126,126,126,1,0,0,0,4,255,255, + 255,16,0,0,0,2,255,255,255,1,0,0,0,14,255,255,255,1,0,0, + 0,3,255,255,255,14,138,138,138,1,0,0,0,5,102,102,102,1,247,247, + 247,1,255,255,255,6,249,249,249,1,186,186,186,1,96,96,96,1,0,0, + 0,7,58,58,58,1,254,254,254,1,255,255,255,6,254,254,254,1,166,166, + 166,1,96,96,96,1,0,0,0,4,255,255,255,16,0,0,0,2,255,255, + 255,1,0,0,0,2,59,59,59,1,45,45,45,1,20,20,20,1,26,26, + 26,1,28,28,28,1,3,3,3,1,26,26,26,1,19,19,19,1,0,0, + 0,4,255,255,255,1,0,0,0,3,255,255,255,14,138,138,138,1,0,0, + 0,6,177,177,177,1,249,249,249,1,255,255,255,4,249,249,249,1,215,215, + 215,1,139,139,139,1,32,32,32,1,0,0,0,8,137,137,137,1,254,254, + 254,1,255,255,255,4,254,254,254,1,194,194,194,1,139,139,139,1,32,32, + 32,1,0,0,0,4,255,255,255,16,0,0,0,2,255,255,255,2,0,0, + 0,1,78,78,78,1,61,61,61,1,91,91,91,1,100,100,100,1,109,109, + 109,1,36,36,36,1,101,101,101,1,48,48,48,1,0,0,0,1,8,8, + 8,1,255,255,255,1,0,0,0,1,255,255,255,1,0,0,0,3,255,255, + 255,14,138,138,138,1,0,0,0,7,142,142,142,1,230,230,230,1,239,239, + 239,2,231,231,231,1,186,186,186,1,139,139,139,1,66,66,66,1,0,0, + 0,10,109,109,109,1,219,219,219,1,247,247,247,1,246,246,246,1,219,219, + 219,1,166,166,166,1,139,139,139,1,66,66,66,1,0,0,0,5,255,255, + 255,16,0,0,0,12,18,18,18,1,0,0,0,1,255,255,255,2,0,0, + 0,1,255,255,255,1,0,0,0,3,255,255,255,14,138,138,138,1,0,0, + 0,8,32,32,32,1,100,100,100,1,130,130,130,1,126,126,126,1,96,96, + 96,1,32,32,32,1,0,0,0,12,32,32,32,1,246,246,246,1,239,239, + 239,1,126,126,126,1,96,96,96,1,32,32,32,1,0,0,0,27,105,105, + 105,1,83,83,83,1,82,82,82,1,91,91,91,1,93,93,93,1,124,124, + 124,1,69,69,69,1,57,57,57,1,255,255,255,5,0,0,0,3,255,255, + 255,14,138,138,138,1,0,0,0,27,120,120,120,1,112,112,112,1,0,0, + 0,30,38,38,38,1,31,31,31,1,29,29,29,1,33,33,33,1,34,34, + 34,1,44,44,44,1,26,26,26,1,13,13,13,1,0,0,0,1,255,255, + 255,2,0,0,0,5,2,2,2,1,136,136,136,1,138,138,138,12,136,136, + 136,1,0,0,0,69,255,255,255,1,0,0,0,185,118,118,118,1,124,124, + 124,1,7,7,7,1,0,0,0,50,255,255,255,16,0,0,0,6,1,1, + 1,1,0,0,0,14,32,32,32,1,176,176,176,1,219,219,219,1,73,73, + 73,1,0,0,0,32,255,255,255,8,251,251,251,1,70,70,70,1,1,1, + 1,1,0,0,0,6,255,255,255,16,0,0,0,4,86,86,86,1,210,210, + 210,1,249,249,249,1,210,210,210,1,86,86,86,1,0,0,0,14,73,73, + 73,1,219,219,219,1,175,175,175,1,32,32,32,1,0,0,0,30,255,255, + 255,9,253,253,253,1,103,103,103,1,1,1,1,1,0,0,0,5,255,255, + 255,16,0,0,0,3,90,90,90,1,255,255,255,5,120,120,120,1,0,0, + 0,14,7,7,7,1,124,124,124,1,236,236,236,1,124,124,124,1,7,7, + 7,1,0,0,0,9,255,255,255,16,0,0,0,3,255,255,255,10,253,253, + 253,1,111,111,111,1,1,1,1,1,0,0,0,4,255,255,255,16,0,0, + 0,3,211,211,211,1,255,255,255,5,235,235,235,1,49,49,49,1,0,0, + 0,15,32,32,32,1,176,176,176,1,219,219,219,1,73,73,73,1,0,0, + 0,8,255,255,255,16,0,0,0,3,255,255,255,11,253,253,253,1,119,119, + 119,1,1,1,1,1,0,0,0,3,255,255,255,16,0,0,0,3,240,240, + 240,1,255,255,255,5,248,248,248,1,116,116,116,1,0,0,0,2,34,34, + 34,1,0,0,0,6,255,255,255,1,85,85,85,1,0,0,0,6,73,73, + 73,1,219,219,219,1,176,176,176,1,32,32,32,1,0,0,0,2,85,85, + 85,1,255,255,255,1,0,0,0,2,255,255,255,16,0,0,0,3,255,255, + 255,12,253,253,253,1,128,128,128,1,2,2,2,1,0,0,0,2,255,255, + 255,16,0,0,0,3,178,178,178,1,255,255,255,5,220,220,220,1,132,132, + 132,1,0,0,0,1,22,22,22,1,230,230,230,1,39,39,39,1,0,0, + 0,5,255,255,255,1,234,234,234,1,21,21,21,1,0,0,0,6,7,7, + 7,1,124,124,124,1,118,118,118,1,0,0,0,1,21,21,21,1,234,234, + 234,1,255,255,255,1,0,0,0,2,255,255,255,16,0,0,0,3,255,255, + 255,14,54,54,54,1,0,0,0,2,255,255,255,16,0,0,0,3,33,33, + 33,1,240,240,240,1,255,255,255,3,244,244,244,1,155,155,155,1,98,98, + 98,1,0,0,0,1,147,147,147,1,255,255,255,1,200,200,200,1,12,12, + 12,1,0,0,0,4,255,255,255,2,170,170,170,1,255,255,255,1,0,0, + 0,1,255,255,255,1,0,0,0,1,255,255,255,1,0,0,0,1,255,255, + 255,1,0,0,0,1,255,255,255,1,0,0,0,1,170,170,170,1,255,255, + 255,2,0,0,0,2,255,255,255,16,0,0,0,3,255,255,255,14,136,136, + 136,1,0,0,0,2,255,255,255,16,0,0,0,4,33,33,33,1,184,184, + 184,1,209,209,209,1,191,191,191,1,147,147,147,1,126,126,126,1,18,18, + 18,1,35,35,35,1,250,250,250,1,255,255,255,1,253,253,253,1,105,105, + 105,1,0,0,0,4,255,255,255,16,0,0,0,2,255,255,255,16,0,0, + 0,3,255,255,255,14,138,138,138,1,0,0,0,2,255,255,255,16,0,0, + 0,5,9,9,9,1,63,63,63,1,85,85,85,1,63,63,63,1,9,9, + 9,1,0,0,0,1,167,167,167,1,255,255,255,3,214,214,214,1,19,19, + 19,1,0,0,0,3,255,255,255,16,0,0,0,2,255,255,255,16,0,0, + 0,3,255,255,255,14,138,138,138,1,0,0,0,2,255,255,255,16,0,0, + 0,3,255,255,255,6,0,0,0,1,50,50,50,1,254,254,254,1,255,255, + 255,4,124,124,124,1,0,0,0,3,255,255,255,16,0,0,0,2,255,255, + 255,16,0,0,0,3,255,255,255,14,138,138,138,1,0,0,0,2,255,255, + 255,16,0,0,0,3,255,255,255,6,140,140,140,1,187,187,187,1,255,255, + 255,5,224,224,224,1,27,27,27,1,0,0,0,2,255,255,255,16,0,0, + 0,2,255,255,255,16,0,0,0,3,255,255,255,14,138,138,138,1,0,0, + 0,2,255,255,255,16,0,0,0,3,255,255,255,6,140,140,140,1,0,0, + 0,1,103,103,103,1,140,140,140,5,103,103,103,1,0,0,0,2,255,255, + 255,16,0,0,0,2,255,255,255,16,0,0,0,3,255,255,255,14,138,138, + 138,1,0,0,0,2,255,255,255,16,0,0,0,3,255,255,255,6,140,140, + 140,1,0,0,0,10,255,255,255,2,170,170,170,1,255,255,255,1,0,0, + 0,1,255,255,255,1,0,0,0,1,255,255,255,1,0,0,0,1,255,255, + 255,1,0,0,0,1,255,255,255,1,0,0,0,1,170,170,170,1,255,255, + 255,2,0,0,0,21,255,255,255,14,138,138,138,1,0,0,0,2,255,255, + 255,16,0,0,0,3,255,255,255,6,140,140,140,1,0,0,0,10,255,255, + 255,1,234,234,234,1,21,21,21,1,0,0,0,10,21,21,21,1,234,234, + 234,1,255,255,255,1,0,0,0,21,255,255,255,14,138,138,138,1,0,0, + 0,2,255,255,255,16,0,0,0,3,255,255,255,6,140,140,140,1,0,0, + 0,10,255,255,255,1,85,85,85,1,0,0,0,12,85,85,85,1,255,255, + 255,1,0,0,0,21,2,2,2,1,136,136,136,1,138,138,138,12,136,136, + 136,1,0,0,0,2,255,255,255,1,128,128,128,1,255,255,255,14,0,0, + 0,4,140,140,140,6,0,0,0,209,16,16,16,1,192,192,192,1,255,255, + 255,11,236,236,236,1,0,0,0,3,255,255,255,16,0,0,0,42,61,61, + 61,1,147,147,147,1,209,209,209,2,147,147,147,1,62,62,62,1,0,0, + 0,8,44,44,44,1,230,230,230,1,248,248,248,1,255,255,255,10,254,254, + 254,1,255,255,255,1,0,0,0,3,255,255,255,16,0,0,0,25,8,8, + 8,1,101,101,101,1,149,149,149,1,148,148,148,1,105,105,105,1,10,10, + 10,1,0,0,0,9,12,12,12,1,158,158,158,1,243,243,243,1,254,254, + 254,1,255,255,255,3,248,248,248,1,179,179,179,1,13,13,13,1,0,0, + 0,6,248,248,248,1,255,255,255,14,0,0,0,3,255,255,255,16,0,0, + 0,1,252,252,252,1,237,237,237,16,252,252,252,1,0,0,0,5,29,29, + 29,1,224,224,224,1,255,255,255,1,215,215,215,1,218,218,218,1,255,255, + 255,1,225,225,225,1,36,36,36,1,0,0,0,8,173,173,173,1,247,247, + 247,1,255,255,255,6,251,251,251,1,208,208,208,1,15,15,15,1,0,0, + 0,5,255,255,255,15,0,0,0,3,255,255,255,16,0,0,0,1,237,237, + 237,1,140,140,140,2,146,146,146,2,140,140,140,1,144,144,144,1,142,142, + 142,1,140,140,140,1,141,141,141,1,144,144,144,2,145,145,145,1,140,140, + 140,2,143,143,143,1,144,144,144,1,235,235,235,1,0,0,0,5,185,185, + 185,1,255,255,255,1,199,199,199,1,229,229,229,2,199,199,199,1,254,254, + 254,1,195,195,195,1,0,0,0,7,77,77,77,1,244,244,244,1,255,255, + 255,8,250,250,250,1,153,153,153,1,1,1,1,1,0,0,0,4,255,255, + 255,15,0,0,0,3,255,255,255,16,0,0,0,1,237,237,237,1,140,140, + 140,1,176,176,176,1,235,235,235,1,226,226,226,1,159,159,159,1,172,172, + 172,1,183,183,183,1,140,140,140,1,150,150,150,1,190,190,190,1,186,186, + 186,1,220,220,220,1,142,142,142,1,140,140,140,1,187,187,187,1,190,190, + 190,1,235,235,235,1,0,0,0,4,17,17,17,1,253,253,253,1,255,255, + 255,6,254,254,254,1,13,13,13,1,0,0,0,6,187,187,187,1,255,255, + 255,10,222,222,222,1,56,56,56,1,0,0,0,4,255,255,255,15,0,0, + 0,3,255,255,255,1,250,250,250,1,255,255,255,2,152,152,152,1,159,159, + 159,1,164,164,164,1,255,255,255,1,146,146,146,1,154,154,154,1,158,158, + 158,1,255,255,255,1,148,148,148,1,161,161,161,1,158,158,158,1,255,255, + 255,1,0,0,0,1,237,237,237,1,143,143,143,1,226,226,226,1,148,148, + 148,1,169,169,169,1,196,196,196,1,152,152,152,1,202,202,202,1,148,148, + 148,1,173,173,173,1,187,187,187,2,232,232,232,1,157,157,157,1,140,140, + 140,1,221,221,221,1,195,195,195,1,235,235,235,1,0,0,0,4,62,62, + 62,1,253,253,253,1,255,255,255,7,111,111,111,1,0,0,0,6,237,237, + 237,1,255,255,255,10,247,247,247,1,107,107,107,1,1,1,1,1,0,0, + 0,3,255,255,255,15,0,0,0,3,255,255,255,1,250,250,250,1,255,255, + 255,2,155,155,155,1,178,178,178,1,162,162,162,1,255,255,255,1,164,164, + 164,1,166,166,166,1,169,169,169,1,255,255,255,1,140,140,140,1,162,162, + 162,2,255,255,255,1,0,0,0,1,237,237,237,1,144,144,144,1,219,219, + 219,1,174,174,174,1,150,150,150,1,160,160,160,1,142,142,142,1,191,191, + 191,1,172,172,172,1,212,212,212,1,152,152,152,1,187,187,187,1,207,207, + 207,1,176,176,176,1,147,147,147,1,219,219,219,1,192,192,192,1,235,235, + 235,1,0,0,0,4,175,175,175,1,255,255,255,8,219,219,219,1,32,32, + 32,1,0,0,0,5,247,247,247,1,255,255,255,10,251,251,251,1,132,132, + 132,1,1,1,1,1,0,0,0,3,255,255,255,15,0,0,0,3,255,255, + 255,1,247,247,247,1,255,255,255,2,140,140,140,3,255,255,255,1,144,144, + 144,1,154,154,154,1,159,159,159,1,255,255,255,1,140,140,140,3,255,255, + 255,1,0,0,0,1,237,237,237,1,140,140,140,1,166,166,166,1,221,221, + 221,1,227,227,227,1,160,160,160,1,140,140,140,1,160,160,160,1,229,229, + 229,1,186,186,186,1,140,140,140,1,187,187,187,1,190,190,190,1,187,187, + 187,1,173,173,173,1,192,192,192,2,235,235,235,1,0,0,0,4,229,229, + 229,1,255,255,255,8,243,243,243,1,96,96,96,1,0,0,0,5,206,206, + 206,1,255,255,255,10,233,233,233,1,132,132,132,1,1,1,1,1,0,0, + 0,3,255,255,255,15,0,0,0,3,255,255,255,16,0,0,0,1,237,237, + 237,1,143,143,143,1,147,147,147,1,142,142,142,1,173,173,173,1,218,218, + 218,1,140,140,140,2,228,228,228,1,142,142,142,1,140,140,140,1,187,187, + 187,1,185,185,185,1,186,186,186,1,206,206,206,1,162,162,162,1,192,192, + 192,1,235,235,235,1,0,0,0,4,229,229,229,1,255,255,255,8,243,243, + 243,1,126,126,126,1,0,0,0,5,127,127,127,1,249,249,249,1,255,255, + 255,8,250,250,250,1,197,197,197,1,107,107,107,1,1,1,1,1,0,0, + 0,3,255,255,255,15,0,0,0,3,255,255,255,1,245,245,245,1,255,255, + 255,2,148,148,148,1,153,153,153,1,159,159,159,1,255,255,255,1,148,148, + 148,1,153,153,153,1,159,159,159,1,255,255,255,1,149,149,149,1,153,153, + 153,1,158,158,158,1,255,255,255,1,0,0,0,1,237,237,237,1,154,154, + 154,1,204,204,204,1,142,142,142,1,146,146,146,1,219,219,219,1,140,140, + 140,2,226,226,226,1,141,141,141,1,140,140,140,1,187,187,187,1,179,179, + 179,1,188,188,188,1,214,214,214,1,156,156,156,1,192,192,192,1,235,235, + 235,1,0,0,0,4,175,175,175,1,255,255,255,8,219,219,219,1,126,126, + 126,1,0,0,0,5,7,7,7,1,230,230,230,1,255,255,255,8,247,247, + 247,1,205,205,205,1,63,63,63,1,2,2,2,1,0,0,0,3,255,255, + 255,15,0,0,0,3,255,255,255,1,245,245,245,1,255,255,255,2,163,163, + 163,1,177,177,177,2,255,255,255,1,163,163,163,1,177,177,177,2,255,255, + 255,1,163,163,163,1,181,181,181,1,172,172,172,1,255,255,255,1,0,0, + 0,1,237,237,237,1,142,142,142,1,201,201,201,1,226,226,226,1,221,221, + 221,1,187,187,187,1,140,140,140,2,226,226,226,1,141,141,141,1,140,140, + 140,1,187,187,187,1,175,175,175,1,189,189,189,1,191,191,191,1,156,156, + 156,1,192,192,192,1,235,235,235,1,0,0,0,4,58,58,58,1,254,254, + 254,1,255,255,255,6,254,254,254,1,166,166,166,1,96,96,96,1,0,0, + 0,6,46,46,46,1,241,241,241,1,250,250,250,1,255,255,255,4,250,250, + 250,1,249,249,249,1,255,255,255,2,201,201,201,1,25,25,25,1,0,0, + 0,3,255,255,255,15,0,0,0,3,255,255,255,1,244,244,244,1,255,255, + 255,2,145,145,145,1,149,149,149,1,155,155,155,1,255,255,255,1,145,145, + 145,1,149,149,149,1,155,155,155,1,255,255,255,1,146,146,146,1,149,149, + 149,1,154,154,154,1,255,255,255,1,0,0,0,1,237,237,237,1,140,140, + 140,2,160,160,160,1,162,162,162,1,142,142,142,1,140,140,140,2,158,158, + 158,1,140,140,140,2,150,150,150,1,147,147,147,1,148,148,148,1,146,146, + 146,1,143,143,143,1,151,151,151,1,235,235,235,1,0,0,0,5,137,137, + 137,1,254,254,254,1,255,255,255,4,254,254,254,1,194,194,194,1,139,139, + 139,1,32,32,32,1,0,0,0,7,24,24,24,1,193,193,193,1,244,244, + 244,1,253,253,253,2,245,245,245,1,206,206,206,1,207,207,207,1,255,255, + 255,3,202,202,202,1,16,16,16,1,0,0,0,2,255,255,255,13,248,248, + 248,1,191,191,191,1,0,0,0,3,255,255,255,16,0,0,0,1,237,237, + 237,1,140,140,140,16,235,235,235,1,0,0,0,6,109,109,109,1,219,219, + 219,1,247,247,247,1,246,246,246,1,219,219,219,1,166,166,166,1,139,139, + 139,1,66,66,66,1,0,0,0,9,1,1,1,1,56,56,56,1,118,118, + 118,1,141,141,141,1,132,132,132,1,107,107,107,1,62,62,62,1,197,197, + 197,1,255,255,255,3,179,179,179,1,0,0,0,2,255,255,255,13,239,239, + 239,1,104,104,104,1,7,7,7,1,0,0,0,2,255,255,255,1,239,239, + 239,1,255,255,255,2,148,148,148,1,150,150,150,1,153,153,153,1,255,255, + 255,1,145,145,145,1,150,150,150,2,255,255,255,1,140,140,140,1,153,153, + 153,1,152,152,152,1,255,255,255,1,0,0,0,1,252,252,252,1,235,235, + 235,16,252,252,252,1,0,0,0,7,32,32,32,1,246,246,246,1,239,239, + 239,1,126,126,126,1,96,96,96,1,32,32,32,1,0,0,0,12,1,1, + 1,4,0,0,0,1,16,16,16,1,200,200,200,1,255,255,255,1,253,253, + 253,1,175,175,175,1,0,0,0,2,232,232,232,1,255,255,255,11,252,252, + 252,1,159,159,159,1,42,42,42,1,0,0,0,3,255,255,255,1,241,241, + 241,1,255,255,255,2,166,166,166,1,164,164,164,1,165,165,165,1,255,255, + 255,1,145,145,145,1,165,165,165,1,162,162,162,1,255,255,255,1,143,143, + 143,1,166,166,166,1,195,195,195,1,255,255,255,1,0,0,0,27,120,120, + 120,1,112,112,112,1,0,0,0,21,11,11,11,1,170,170,170,1,168,168, + 168,1,121,121,121,1,0,0,0,2,22,22,22,1,70,70,70,12,49,49, + 49,1,0,0,0,4,255,255,255,1,132,132,132,1,255,255,255,14,0,0, + 0,163,255,255,255,54,0,0,0,36,255,255,255,54,0,0,0,36,255,255, + 255,54,0,0,0,8,7,7,7,2,0,0,0,16,7,7,7,2,0,0, + 0,8,255,255,255,54,0,0,0,6,102,102,102,1,201,201,201,1,220,220, + 220,2,201,201,201,1,102,102,102,1,0,0,0,12,102,102,102,1,201,201, + 201,1,220,220,220,2,201,201,201,1,102,102,102,1,0,0,0,6,255,255, + 255,54,0,0,0,5,166,166,166,1,242,242,242,1,255,255,255,4,247,247, + 247,1,177,177,177,1,0,0,0,10,166,166,166,1,242,242,242,1,255,255, + 255,4,247,247,247,1,177,177,177,1,0,0,0,5,255,255,255,54,0,0, + 0,4,102,102,102,1,242,242,242,1,255,255,255,6,249,249,249,1,142,142, + 142,1,0,0,0,8,102,102,102,1,242,242,242,1,255,255,255,6,249,249, + 249,1,142,142,142,1,0,0,0,4,255,255,255,54,0,0,0,4,201,201, + 201,1,255,255,255,8,230,230,230,1,32,32,32,1,0,0,0,7,201,201, + 201,1,255,255,255,8,230,230,230,1,32,32,32,1,0,0,0,3,255,255, + 255,54,0,0,0,3,7,7,7,1,220,220,220,1,255,255,255,8,239,239, + 239,1,100,100,100,1,0,0,0,6,7,7,7,1,220,220,220,1,255,255, + 255,8,239,239,239,1,100,100,100,1,0,0,0,3,255,255,255,54,0,0, + 0,3,7,7,7,1,220,220,220,1,255,255,255,8,239,239,239,1,130,130, + 130,1,0,0,0,6,7,7,7,1,220,220,220,1,255,255,255,8,239,239, + 239,1,130,130,130,1,0,0,0,3,255,255,255,54,0,0,0,4,201,201, + 201,1,255,255,255,8,231,231,231,1,126,126,126,1,0,0,0,7,201,201, + 201,1,255,255,255,8,231,231,231,1,126,126,126,1,0,0,0,3,255,255, + 255,54,0,0,0,4,102,102,102,1,247,247,247,1,255,255,255,6,249,249, + 249,1,186,186,186,1,96,96,96,1,0,0,0,7,102,102,102,1,247,247, + 247,1,255,255,255,6,249,249,249,1,186,186,186,1,96,96,96,1,0,0, + 0,3,255,255,255,54,0,0,0,5,177,177,177,1,249,249,249,1,255,255, + 255,4,249,249,249,1,215,215,215,1,139,139,139,1,32,32,32,1,0,0, + 0,8,177,177,177,1,249,249,249,1,255,255,255,4,249,249,249,1,215,215, + 215,1,139,139,139,1,32,32,32,1,0,0,0,3,255,255,255,54,0,0, + 0,6,142,142,142,1,230,230,230,1,239,239,239,2,231,231,231,1,186,186, + 186,1,139,139,139,1,66,66,66,1,0,0,0,10,142,142,142,1,230,230, + 230,1,239,239,239,2,231,231,231,1,186,186,186,1,139,139,139,1,66,66, + 66,1,0,0,0,4,255,255,255,54,0,0,0,7,32,32,32,1,100,100, + 100,1,130,130,130,1,126,126,126,1,96,96,96,1,32,32,32,1,0,0, + 0,12,32,32,32,1,100,100,100,1,130,130,130,1,126,126,126,1,96,96, + 96,1,32,32,32,1,0,0,0,5,255,255,255,54,0,0,0,36,255,255, + 255,54,0,0,0,36,255,255,255,54,0,0,0,36,255,255,255,54,0,0, + 10,116,105,109,97,103,101,108,105,115,116,14,100,117,109,109,121,105,109,97, + 103,101,108,105,115,116,5,119,105,100,116,104,2,24,4,108,101,102,116,2, + 120,3,116,111,112,2,64,0,0,10,116,102,114,97,109,101,99,111,109,112, + 8,118,105,101,119,109,101,110,117,4,108,101,102,116,3,208,0,3,116,111, + 112,2,96,0,0,15,116,112,114,111,99,101,115,115,109,111,110,105,116,111, + 114,10,114,117,110,112,114,111,99,109,111,110,11,111,110,99,104,105,108,100, + 100,105,101,100,7,11,114,117,110,112,114,111,99,100,105,101,100,4,108,101, + 102,116,3,192,0,3,116,111,112,2,32,0,0,9,116,114,116,116,105,115, + 116,97,116,11,115,116,97,116,111,112,116,105,111,110,115,12,111,110,103,101, + 116,111,98,106,101,99,116,115,7,11,103,101,116,115,116,97,116,111,98,106, + 115,3,116,111,112,2,96,0,0,11,116,102,105,108,101,100,105,97,108,111, + 103,14,112,114,111,106,101,99,116,102,105,108,101,100,105,97,8,115,116,97, + 116,102,105,108,101,7,15,112,114,111,106,101,99,116,115,116,97,116,102,105, + 108,101,26,99,111,110,116,114,111,108,108,101,114,46,102,105,108,116,101,114, + 108,105,115,116,46,100,97,116,97,1,1,6,13,80,114,111,106,101,99,116, + 32,102,105,108,101,115,6,5,42,46,112,114,106,0,1,6,9,65,108,108, + 32,70,105,108,101,115,6,1,42,0,0,21,99,111,110,116,114,111,108,108, + 101,114,46,100,101,102,97,117,108,116,101,120,116,6,3,112,114,106,22,99, + 111,110,116,114,111,108,108,101,114,46,99,97,112,116,105,111,110,111,112,101, + 110,6,12,79,112,101,110,32,80,114,111,106,101,99,116,22,99,111,110,116, + 114,111,108,108,101,114,46,99,97,112,116,105,111,110,115,97,118,101,6,12, + 83,97,118,101,32,80,114,111,106,101,99,116,12,111,112,116,105,111,110,115, + 101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112, + 109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13, + 111,101,49,95,115,97,118,101,115,116,97,116,101,27,111,101,49,95,99,104, + 101,99,107,118,97,108,117,101,97,102,116,101,114,115,116,97,116,114,101,97, + 100,0,4,108,101,102,116,3,0,1,3,116,111,112,2,1,0,0,15,116, + 112,105,112,101,114,101,97,100,101,114,99,111,109,112,10,116,97,114,103,101, + 116,112,105,112,101,16,111,110,105,110,112,117,116,97,118,97,105,108,97,98, + 108,101,7,15,116,97,114,103,101,116,112,105,112,101,105,110,112,117,116,4, + 108,101,102,116,3,56,1,3,116,111,112,2,32,0,0,16,116,115,116,114, + 105,110,103,99,111,110,116,97,105,110,101,114,1,99,12,115,116,114,105,110, + 103,115,46,100,97,116,97,1,6,24,85,110,114,101,115,111,108,118,101,100, + 32,114,101,102,101,114,101,110,99,101,115,32,105,110,6,2,116,111,6,35, + 68,111,32,121,111,117,32,119,105,115,104,32,116,111,32,115,101,97,114,99, + 104,32,116,104,101,32,102,111,114,109,102,105,108,101,63,6,7,87,65,82, + 78,73,78,71,6,12,70,111,114,109,102,105,108,101,32,102,111,114,6,9, + 70,111,114,109,102,105,108,101,115,6,30,82,101,99,117,114,115,105,118,101, + 32,102,111,114,109,32,104,105,101,114,97,114,99,104,121,32,102,111,114,32, + 34,6,5,69,82,82,79,82,6,9,67,108,97,115,115,116,121,112,101,6, + 10,110,111,116,32,102,111,117,110,100,46,6,7,80,114,111,106,101,99,116, + 6,18,105,115,32,109,111,100,105,102,105,101,100,46,32,83,97,118,101,63, + 6,12,67,111,110,102,105,114,109,97,116,105,111,110,6,21,85,110,97,98, + 108,101,32,116,111,32,111,112,101,110,32,102,105,108,101,32,34,6,15,42, + 42,42,32,82,117,110,110,105,110,103,32,42,42,42,6,11,68,111,119,110, + 108,111,97,100,105,110,103,6,10,68,111,119,110,108,111,97,100,101,100,6, + 26,83,116,97,114,116,32,103,100,98,32,115,101,114,118,101,114,32,99,111, + 109,109,97,110,100,32,34,6,10,34,32,114,117,110,110,105,110,103,46,6, + 16,83,116,97,114,116,32,103,100,98,32,83,101,114,118,101,114,6,22,103, + 100,98,32,115,101,114,118,101,114,32,115,116,97,114,116,32,101,114,114,111, + 114,6,26,103,100,98,32,115,101,114,118,101,114,32,115,116,97,114,116,32, + 99,97,110,99,101,108,101,100,46,6,30,67,97,110,32,110,111,116,32,114, + 117,110,32,115,116,97,114,116,32,103,100,98,32,99,111,109,109,97,110,100, + 46,6,15,85,112,108,111,97,100,99,111,109,109,97,110,100,32,34,6,20, + 68,111,119,110,108,111,97,100,32,42,42,42,69,82,82,79,82,42,42,42, + 6,18,68,111,119,110,108,111,97,100,32,102,105,110,105,115,104,101,100,46, + 6,18,68,111,119,110,108,111,97,100,32,99,97,110,99,101,108,101,100,46, + 6,6,70,105,108,101,32,34,6,12,34,32,110,111,116,32,102,111,117,110, + 100,46,6,9,34,32,101,120,105,115,116,115,46,6,3,78,101,119,6,15, + 83,101,108,101,99,116,32,97,110,99,101,115,116,111,114,6,8,78,101,119, + 32,102,111,114,109,6,12,80,97,115,99,97,108,32,70,105,108,101,115,6, + 3,110,101,119,6,22,67,97,110,32,110,111,116,32,108,111,97,100,32,80, + 114,111,106,101,99,116,32,34,6,23,83,101,108,101,99,116,32,112,114,111, + 106,101,99,116,32,116,101,109,112,108,97,116,101,6,13,80,114,111,106,101, + 99,116,32,102,105,108,101,115,6,9,65,108,108,32,102,105,108,101,115,6, + 19,83,101,108,101,99,116,32,112,114,111,103,114,97,109,32,102,105,108,101, + 6,20,80,97,115,99,97,108,32,112,114,111,103,114,97,109,32,102,105,108, + 101,115,6,15,67,32,112,114,111,103,114,97,109,32,102,105,108,101,115,6, + 11,78,101,119,32,80,114,111,106,101,99,116,6,21,67,97,110,32,110,111, + 116,32,115,116,97,114,116,32,112,114,111,99,101,115,115,6,7,80,114,111, + 99,101,115,115,6,7,114,117,110,110,105,110,103,6,30,80,114,111,99,101, + 115,115,32,116,101,114,109,105,110,97,116,101,100,46,32,69,120,105,116,99, + 111,100,101,58,32,6,28,80,114,111,99,101,115,115,32,116,101,114,109,105, + 110,97,116,101,100,32,110,111,114,109,97,108,108,121,46,6,16,77,97,107, + 101,32,42,42,42,69,82,82,79,82,42,42,42,6,8,77,97,107,101,32, + 79,75,46,6,50,83,111,117,114,99,101,32,104,97,115,32,99,104,97,110, + 103,101,100,44,32,100,111,32,121,111,117,32,119,105,115,104,32,116,111,32, + 114,101,109,97,107,101,32,112,114,111,106,101,99,116,63,6,18,76,111,97, + 100,32,87,105,110,100,111,119,32,76,97,121,111,117,116,6,12,68,111,99, + 107,105,110,103,32,65,114,101,97,0,4,108,101,102,116,3,0,1,3,116, + 111,112,2,64,0,0,11,116,102,105,108,101,100,105,97,108,111,103,8,111, + 112,101,110,102,111,114,109,8,115,116,97,116,102,105,108,101,7,15,112,114, + 111,106,101,99,116,115,116,97,116,102,105,108,101,26,99,111,110,116,114,111, + 108,108,101,114,46,102,105,108,116,101,114,108,105,115,116,46,100,97,116,97, + 1,1,6,10,70,111,114,109,32,70,105,108,101,115,6,5,42,46,109,102, + 109,0,0,21,99,111,110,116,114,111,108,108,101,114,46,100,101,102,97,117, + 108,116,101,120,116,6,3,109,102,109,18,99,111,110,116,114,111,108,108,101, + 114,46,111,112,116,105,111,110,115,11,14,102,100,111,95,99,104,101,99,107, + 101,120,105,115,116,0,22,99,111,110,116,114,111,108,108,101,114,46,99,97, + 112,116,105,111,110,111,112,101,110,6,14,79,112,101,110,32,70,111,114,109, + 32,70,105,108,101,4,108,101,102,116,2,120,3,116,111,112,2,1,0,0, + 11,116,98,105,116,109,97,112,99,111,109,112,6,102,111,114,109,98,103,17, + 98,105,116,109,97,112,46,111,114,105,103,102,111,114,109,97,116,6,3,112, + 110,103,16,98,105,116,109,97,112,46,97,108,105,103,110,109,101,110,116,11, + 8,97,108,95,116,105,108,101,100,0,12,98,105,116,109,97,112,46,105,109, + 97,103,101,10,176,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0, + 16,0,0,0,124,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 184,184,184,8,199,199,199,8,184,184,184,8,199,199,199,8,184,184,184,8, + 199,199,199,8,184,184,184,8,199,199,199,8,184,184,184,8,199,199,199,8, + 184,184,184,8,199,199,199,8,184,184,184,8,199,199,199,8,184,184,184,8, + 199,199,199,16,184,184,184,8,199,199,199,8,184,184,184,8,199,199,199,8, + 184,184,184,8,199,199,199,8,184,184,184,8,199,199,199,8,184,184,184,8, + 199,199,199,8,184,184,184,8,199,199,199,8,184,184,184,8,199,199,199,8, + 184,184,184,8,4,108,101,102,116,3,56,1,3,116,111,112,2,64,0,0, + 0) + ); + +initialization + registerobjectdata(@objdata,tmainfo,''); +end. diff --git a/mseide-msegui/apps/ide/make.pas b/mseide-msegui/apps/ide/make.pas new file mode 100644 index 0000000..a23661b --- /dev/null +++ b/mseide-msegui/apps/ide/make.pas @@ -0,0 +1,566 @@ +{ MSEide Copyright (c) 1999-2013 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit make; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msetypes,msestrings,msepipestream,msesystypes; + +procedure domake(atag: integer); +procedure abortmake; +function making: boolean; +function buildmakecommandline(const atag: integer): msestring; +function addmessagetext(const sender: tpipereader; + const procid: pprocidty): string; + +procedure dodownload; +procedure abortdownload; +function downloading: boolean; +function downloadresult: integer; +function runscript(const script: filenamety; + const clearscreen,setmakedir: boolean): boolean; + +implementation +uses + mseprocutils,main,projectoptionsform,sysutils,msegrids, + sourceform,mseeditglob,msefileutils,msesys, + msesysutils,msegraphics,messageform,msedesignintf,msedesigner, + mseprocmonitor,mseevent, + classes,mclasses,mseclasses,mseapplication,msestream, + msegui,actionsmodule; + +type + tprogrunner = class(tactcomponent) + private + fexitcode: integer; + fmessagefile: ttextstream; + fnofilecopy: boolean; + ffinished: boolean; + fmessagefinished: boolean; + fsetmakedir: boolean; + messagepipe: tpipereader; + protected + fcanceled: boolean; + procid: integer; + procedure doasyncevent(var atag: integer); override; + procedure inputavailable(const sender: tpipereader); + procedure messagefinished(const sender: tpipereader); + procedure dofinished; virtual; + function getcommandline: msestring; virtual; + procedure runprog(const acommandline: msestring); + public + constructor create(const aowner: tcomponent; + const clearscreen,setmakedir: boolean); reintroduce; + destructor destroy; override; + end; + + tscriptrunner = class(tprogrunner) + private + fscriptpath: filenamety; + protected + function getcommandline: msestring; override; + procedure dofinished; override; + public + constructor create(const aowner: tcomponent; const ascriptpath: filenamety; + const clearscreen,setmakedir: boolean); + property exitcode: integer read fexitcode; + property canceled: boolean read fcanceled; + end; + + makestepty = (maks_before,maks_make,maks_after,maks_finished); + tmaker = class(tprogrunner) + private + ftargettimestamp: tdatetime; + fmaketag: integer; + fstep: makestepty; + fscriptnum: integer; + fcurrentdir: filenamety; + protected + procedure doasyncevent(var atag: integer); override; + procedure dofinished; override; + function getcommandline: msestring; override; + public + constructor create(atag: integer); reintroduce; + end; + + tloader = class(tprogrunner) + protected + procedure dofinished; override; + function getcommandline: msestring; override; + public + constructor create(aowner: tcomponent); + end; + +var + maker: tmaker; + loader: tloader; + +function making: boolean; +begin + result:= (maker <> nil) and (maker.procid <> invalidprochandle); +end; + +function downloading: boolean; +begin + result:= (loader <> nil) and (loader.procid <> invalidprochandle); +end; + +function downloadresult: integer; +begin + result:= -1; + if loader <> nil then begin + result:= loader.fexitcode; + end; +end; + +procedure killmake; +begin + freeandnil(maker); +end; + +procedure killload; +begin + freeandnil(loader); +end; + +procedure domake(atag: integer); +var + bo1: boolean; +begin + killmake; + bo1:= false; + designnotifications.beforemake(idesigner(designer),atag,bo1); + if not bo1 then begin + maker:= tmaker.Create(atag); + if projectoptions.s.closemessages then begin + messagefo.messages.show; + end; + end; +end; + +procedure abortmake; +begin + if maker <> nil then begin + killmake; + mainfo.setstattext(actionsmo.c[ord(ac_makeaborted)],mtk_error); + end; +end; + +procedure abortdownload; +begin + if loader <> nil then begin + killload; + mainfo.setstattext(actionsmo.c[ord(ac_downloadaborted)],mtk_error); + end; +end; + +function buildmakecommandline(const atag: integer): msestring; + + function normalizename(const aname: filenamety): filenamety; + begin + result:= tosysfilepath(filepath(trim(aname),fk_file,true)); + end; + +var + int1,int2,step: integer; + str1,str2,str3: msestring; + ar1: filenamearty; +// wstr1: filenamety; +begin + with projectoptions,k,texp do begin + if makecommand = '' then begin + result:= ''; + exit; + end; + unquotefilename(makecommand,ar1); + if ar1 <> nil then begin + tosysfilepath1(ar1[0]); + end; + str3:= quotefilename(ar1); + str1:= str3; + if (targetfile <> '') and (targpref <> '') then begin + str1:= str1 + ' '+quotefilename(targpref+normalizename(targetfile)); + end; + int2:= high(unitdirs); + int1:= high(unitdirson); + if int1 < int2 then begin + int2:= int1; + end; + if not projectoptions.k.reversepathorder then begin + int1:= int2; + int2:= -1; + step:= -1; + end + else begin + int1:= 0; + int2:= int2+1; + step:= 1; + end; + while int1 <> int2 do begin +// for int1:= int1 to int2 do begin + if (atag and unitdirson[int1] <> 0) and + (unitdirs[int1] <> '') then begin + str2:= normalizename(unitdirs[int1]); + if unitdirson[int1] and $10000 <> 0 then begin + str1:= str1 + ' ' + quotefilename(unitpref+str2); + end; + if unitdirson[int1] and $20000 <> 0 then begin + str1:= str1 + ' ' + quotefilename(incpref+str2); + end; + if unitdirson[int1] and $40000 <> 0 then begin + str1:= str1 + ' ' + quotefilename(libpref+str2); + end; + if unitdirson[int1] and $80000 <> 0 then begin + str1:= str1 + ' ' + quotefilename(objpref+str2); + end; + end; + inc(int1,step); + end; + for int1:= 0 to high(makeoptions) do begin + if makeoptionson[int1] and optaftermainfilemask = 0 then begin + if (atag and makeoptionson[int1] <> 0) and + (makeoptions[int1] <> '') then begin + str1:= str1 + ' ' + makeoptions[int1]; + end; + end; + end; + str1:= str1 + ' ' + quotefilename(normalizename(mainfile)); + for int1:= 0 to high(makeoptions) do begin + if makeoptionson[int1] and optaftermainfilemask <> 0 then begin + if (atag and makeoptionson[int1] <> 0) and + (makeoptions[int1] <> '') then begin + str1:= str1 + ' ' + makeoptions[int1]; + end; + end; + end; + end; + result:= str1; +end; + +procedure dodownload; +begin + killload; + if projectoptions.s.closemessages then begin + messagefo.messages.show; + end; + loader:= tloader.create(nil); +end; + +function runscript(const script: filenamety; + const clearscreen,setmakedir: boolean): boolean; +var + runner: tscriptrunner; +begin + result:= script = ''; + if not result then begin + runner:= tscriptrunner.create(nil,script,clearscreen,setmakedir); + try + result:= not runner.canceled and (runner.fexitcode = 0); + finally + runner.release; + end; + end; +end; + +{ tprogrunner } + +constructor tprogrunner.create(const aowner: tcomponent; + const clearscreen,setmakedir: boolean); +begin + inherited create(aowner); + with projectoptions,s.texp do begin + if s.copymessages and (messageoutputfile <> '') and not fnofilecopy then begin + fmessagefile:= ttextstream.create(messageoutputfile,fm_create); + end; + messagepipe:= tpipereader.create; + messagepipe.oninputavailable:= {$ifdef FPC}@{$endif}inputavailable; + messagepipe.onpipebroken:= {$ifdef FPC}@{$endif}messagefinished; + if clearscreen then begin + messagefo.messages.rowcount:= 0; + end; + procid:= invalidprochandle; + fsetmakedir:= setmakedir; + runprog(getcommandline); + end; +end; + +destructor tprogrunner.destroy; +begin + if (procid <> invalidprochandle) then begin + try + killprocess(procid); + except + end; + procid:= invalidprochandle; + end; + messagepipe.Free; + fmessagefile.free; + inherited; +end; + +procedure tprogrunner.runprog(const acommandline: msestring); +var + wdbefore: filenamety; +begin + if acommandline = '' then begin + fexitcode:= 0; + fmessagefinished:= true; + ffinished:= true; + exit; + end; + fexitcode:= 1; //defaulterror + fmessagefinished:= false; + ffinished:= false; + procid:= invalidprochandle; + with projectoptions,k.texp do begin + if fsetmakedir and (makedir <> '') then begin + wdbefore:= setcurrentdirmse(makedir); + end; + try + procid:= execmse2(msestring(acommandline),nil,messagepipe,messagepipe,-1, + [exo_inactive,exo_tty]); + except + on e1: exception do begin + fcanceled:= true; + if e1 is eoserror then begin +{$warnings off} + fexitcode:= eoserror(e).error; +{$warnings on} + end; + application.handleexception(nil,actionsmo.c[ord(ac_runerrorwith)]+ + msestring(acommandline)+'": '); + end; + end; + if fsetmakedir and (makedir <> '') then begin + setcurrentdirmse(wdbefore); + end; + end; +end; + +procedure tprogrunner.doasyncevent(var atag: integer); +begin + if getprocessexitcode(procid,fexitcode,5000000) <> pee_ok then begin + messagefo.messages.appendrow([actionsmo.c[ord(ac_errortimeout)]]); + messagefo.messages.appendrow(['']); + killprocess(procid); + end; + procid:= invalidprochandle; +end; + +procedure tprogrunner.dofinished; +begin + ffinished:= true; + asyncevent(0); +end; + +procedure tprogrunner.messagefinished(const sender: tpipereader); +begin + fmessagefinished:= true; + dofinished; +end; + +function addmessagetext(const sender: tpipereader; + const procid: pprocidty): string; +var + str1: string; +begin + result:= ''; + str1:= sender.readdatastring; + while application.checkoverload(-1) do begin + if (procid <> nil) and (procid^ = invalidprochandle) then begin + exit; + end; + application.unlock; + sleepus(100000); + application.lock; + end; + messagefo.addtext(str1); + result:= str1; +end; + +procedure tprogrunner.inputavailable(const sender: tpipereader); +var + str1: string; +begin + str1:= addmessagetext(sender,@procid); + if fmessagefile <> nil then begin + fmessagefile.writestr(str1); + end; +end; + +function tprogrunner.getcommandline: msestring; +begin + result:= ''; //dummy +end; + +{ tmaker } + +constructor tmaker.create(atag: integer); +begin + fstep:= maks_before; + fmaketag:= atag; + ftargettimestamp:= getfilemodtime(gettargetfile); + fcurrentdir:= getcurrentdirmse; + inherited create(nil,true,true); + if procid <> invalidprochandle then begin + mainfo.setstattext(actionsmo.c[ord(ac_making)],mtk_running); + messagefo.messages.font.options:= messagefo.messages.font.options + + [foo_nonantialiased]; + end + else begin + mainfo.setstattext(actionsmo.c[ord(ac_makenotrunning)],mtk_error); + designnotifications.aftermake(idesigner(designer),fexitcode); + end; +end; + +procedure tmaker.dofinished; +begin + if ftargettimestamp <> getfilemodtime(gettargetfile) then begin + mainfo.targetfilemodified; + end; + inherited; +end; + +function tmaker.getcommandline: msestring; +begin + result:= ''; + with projectoptions,k do begin + if fstep = maks_before then begin + while fscriptnum <= high(befcommandon) do begin + if (befcommandon[fscriptnum] and fmaketag <> 0) and + (fscriptnum <= high(texp.befcommand)) then begin + result:= k.texp.befcommand[fscriptnum]; + break; + end; + inc(fscriptnum); + end; + if fscriptnum <= high(befcommandon) then begin + inc(fscriptnum); + exit; + end + else begin + fstep:= maks_make; + end; + end; + if fstep = maks_make then begin + result:= buildmakecommandline(fmaketag); + fscriptnum:= 0; + fstep:= maks_after; + exit; + end; + if fstep = maks_after then begin + while fscriptnum <= high(aftcommandon) do begin + if (aftcommandon[fscriptnum] and fmaketag <> 0) and + (fscriptnum <= high(k.texp.aftcommand)) then begin + result:= k.texp.aftcommand[fscriptnum]; + break; + end; + inc(fscriptnum); + end; + if fscriptnum <= high(aftcommandon) then begin + inc(fscriptnum); + exit; + end + else begin + fstep:= maks_finished; + end; + end; + end; +end; + +procedure tmaker.doasyncevent(var atag: integer); + procedure finished; + begin + setcurrentdirmse(fcurrentdir); + designnotifications.aftermake(idesigner(designer),fexitcode); + messagefo.messages.font.options:= messagefo.messages.font.options + + [foo_antialiased2]; + end; +var + str1: msestring; +begin + inherited; + str1:= getcommandline; + if (fstep = maks_finished) or (fexitcode <> 0) then begin + finished; + end + else begin + runprog(str1); + if procid = invalidprochandle then begin + finished; + end; + end; +end; + +{ tloader } + +constructor tloader.create(aowner: tcomponent); +begin + inherited create(aowner,false,true); + if procid <> invalidprochandle then begin + mainfo.setstattext(actionsmo.c[ord(ac_downloading)],mtk_running); + end + else begin + mainfo.setstattext(actionsmo.c[ord(ac_downloadnotrunning)],mtk_error); + end; +end; + +procedure tloader.dofinished; +begin + inherited; +end; + +function tloader.getcommandline: msestring; +begin + result:= projectoptions.d.texp.uploadcommand; +end; + +{ tscriptrunner } + +constructor tscriptrunner.create(const aowner: tcomponent; + const ascriptpath: filenamety; const clearscreen: boolean; + const setmakedir: boolean); +begin + fscriptpath:= tosysfilepath(ascriptpath); + fnofilecopy:= true; + if clearscreen then begin + messagefo.messages.rowcount:= 0; + end; + messagefo.messages.appendrow(ascriptpath); + messagefo.messages.appendrow(''); + inherited create(aowner,false,setmakedir); + if not fcanceled then begin + fcanceled:= not application.waitdialog(nil,'"'+ascriptpath+ + actionsmo.c[ord(ac_running)], + actionsmo.c[ord(ac_script)],nil,nil,nil); + end; +end; + +function tscriptrunner.getcommandline: msestring; +begin + result:= fscriptpath; +end; + +procedure tscriptrunner.dofinished; +begin + inherited; + application.terminatewait; +end; + +end. diff --git a/mseide-msegui/apps/ide/memoryform.mfm b/mseide-msegui/apps/ide/memoryform.mfm new file mode 100644 index 0000000..72f4f96 --- /dev/null +++ b/mseide-msegui/apps/ide/memoryform.mfm @@ -0,0 +1,501 @@ +object memoryfo: tmemoryfo + optionswidget = [ow_arrowfocus, ow_subfocus, ow_mousewheel, ow_destroywidgets, ow_hinton] + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_floatbutton, go_topbutton, go_backgroundbutton, go_nolockbutton, go_buttonhints] + visible = False + bounds_x = 100 + bounds_y = 100 + bounds_cx = 465 + bounds_cy = 354 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 455 + 354 + ) + dragdock.optionsdock = [od_savepos, od_savezorder, od_canmove, od_cansize, od_canfloat, od_candock, od_propsize, od_captionhint, od_childicons] + options = [fo_savepos, fo_savezorder, fo_savestate] + statfile = mainfo.projectstatfile + caption = 'Memory' + icon.transparentcolor = -2147483642 + icon.options = [bmo_masked] + icon.image = { + 0000000002000000180000001800000068050000000000000000000000000000 + 00000000000000000000000000000000000000007C7C7C17FFFFFF017C7C7C01 + C0C0C004A9A9A901C0C0C005A9A9A901C0C0C005A9A9A901C0C0C005FFFFFF01 + 7C7C7C01C0C0C004A9A9A901C0C0C00182828201ACACAC0186868601B8B8B801 + A9A9A901C0C0C0018E8E8E01A3A3A30185858501B0B0B001A9A9A901C0C0C001 + A4A4A401BEBEBE0186868601B5B5B501FFFFFF017C7C7C01C0C0C0018A8A8A01 + 90909001C0C0C001A9A9A901BFBFBF0182828201BEBEBE0181818101B5B5B501 + A9A9A901B5B5B5016B6B6B018F8F8F01606060019B9B9B01A9A9A901C0C0C001 + 6C6C6C01A7A7A70178787801B2B2B201FFFFFF017C7C7C01BFBFBF0158585801 + 76767601C0C0C001A9A9A901C0C0C001979797019C9C9C0175757501B5B5B501 + A9A9A901C0C0C001888888018E8E8E0188888801A0A0A001A9A9A901C0C0C001 + 8A8A8A01B2B2B201888888019B9B9B01FFFFFF017C7C7C01C0C0C004A9A9A901 + C0C0C005A9A9A901C0C0C005A9A9A901C0C0C005FFFFFF017C7C7C01A9A9A916 + FFFFFF017C7C7C01C0C0C004A9A9A901FFFFFF05A9A9A901FFFFFF05A9A9A901 + FFFFFF067C7C7C01C0C0C004A9A9A901FFFFFF0197979701BABABA018D8D8D01 + F8F8F801A9A9A901FFFFFF01B1B1B101DEDEDE019E9E9E01ECECEC01A9A9A901 + FFFFFF0188888801ECECEC0196969601FFFFFF027C7C7C01C0C0C00182828201 + 91919101C0C0C001A9A9A901FFFFFF017E7E7E01777777018F8F8F01F4F4F401 + A9A9A901EDEDED0168686801ABABAB01B2B2B201A7A7A701A9A9A901FFFFFF01 + 87878701EDEDED0193939301FFFFFF027C7C7C01C0C0C0019898980190909001 + C0C0C001A9A9A901FFFFFF01A1A1A101B2B2B201B3B3B301F6F6F601A9A9A901 + FAFAFA017F7F7F018484840150505001D3D3D301A9A9A901FFFFFF01ABABAB01 + FFFFFF01ABABAB01FFFFFF027C7C7C01C0C0C004A9A9A901FFFFFF05A9A9A901 + FFFFFF05A9A9A901FFFFFF067C7C7C01A9A9A916FFFFFF017C7C7C01C0C0C004 + A9A9A901FFFFFF05A9A9A901FFFFFF05A9A9A901FFFFFF067C7C7C01C0C0C001 + ACACAC01C0C0C002A9A9A901FFFFFF01A0A0A001E3E3E30196969601F3F3F301 + A9A9A901FFFFFF01A1A1A101E2E2E20196969601F1F1F101A9A9A901F8F8F801 + 85858501BABABA0180808001E3E3E301FFFFFF017C7C7C01C0C0C00193939301 + C0C0C002A9A9A901E3E3E301A1A1A10169696901BDBDBD0191919101A9A9A901 + E8E8E8019D9D9D016B6B6B01BABABA0190909001A9A9A901CFCFCF01B7B7B701 + 60606001CCCCCC0199999901FFFFFF017C7C7C01C0C0C00184848401C0C0C002 + A9A9A901FBFBFB01787878018D8D8D0177777701B1B1B101A9A9A901FDFDFD01 + 797979018F8F8F0178787801ADADAD01A9A9A901FDFDFD0185858501AEAEAE01 + 80808001D8D8D801FFFFFF017C7C7C01C0C0C0018F8F8F01C0C0C002A9A9A901 + FFFFFF05A9A9A901FFFFFF05A9A9A901FFFFFF067C7C7C01A9A9A916FFFFFF01 + 7C7C7C01C0C0C004A9A9A901FFFFFF05A9A9A901FFFFFF05A9A9A901FFFFFF06 + 7C7C7C01C0C0C004A9A9A901F3F3F30193939301D8D8D8018C8C8C01FFFFFF01 + A9A9A901FBFBFB018A8A8A01D6D6D601A5A5A501FFFFFF01A9A9A901FFFFFF01 + AAAAAA01D2D2D201BABABA01C7C7C701FFFFFF017C7C7C01C0C0C00190909001 + 7A7A7A01BBBBBB01A9A9A901ABABAB0180808001C0C0C0018F8F8F01FFFFFF01 + A9A9A901F8F8F8018C8C8C01EAEAEA0195959501FFFFFF01A9A9A901FFFFFF01 + BCBCBC01B2B2B20169696901A3A3A301FFFFFF017C7C7C01C0C0C0019D9D9D01 + 7F7F7F01BEBEBE01A9A9A901E7E7E7018D8D8D01C7C7C701ABABAB01FFFFFF01 + A9A9A901FFFFFF01ABABAB01FFFFFF01ABABAB01FFFFFF01A9A9A901FFFFFF01 + DADADA01C1C1C101A0A0A001ABABAB01FFFFFF017C7C7C01FFFFFF17FFFFFF00 + FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00 + FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00 + FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00 + } + onshow = formshow + moduleclassname = 'tdockform' + object grid: tstringgrid + frame.localprops = [] + frame.localprops1 = [] + bounds_x = 0 + bounds_y = 38 + bounds_cx = 455 + bounds_cy = 316 + anchors = [an_top, an_bottom] + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + datacols.count = 16 + datacols.width = 20 + datacols.textflags = [tf_xcentered, tf_ycentered, tf_noselect] + datacols.optionsedit = [scoe_undoonesc, scoe_forcereturncheckvalue, scoe_eatreturn, scoe_autoselect, scoe_autoselectonfirstclick] + datacols.items = < + item + width = 20 + textflags = [tf_xcentered, tf_ycentered, tf_noselect] + optionsedit = [scoe_undoonesc, scoe_forcereturncheckvalue, scoe_eatreturn, scoe_autoselect, scoe_autoselectonfirstclick] + datalist.data = ( + '' + '' + '' + '' + '' + ) + valuefalse = '0' + valuetrue = '1' + onsetvalue = cellsetvalue + ondataentered = adent + end + item + width = 20 + textflags = [tf_xcentered, tf_ycentered, tf_noselect] + optionsedit = [scoe_undoonesc, scoe_forcereturncheckvalue, scoe_eatreturn, scoe_autoselect, scoe_autoselectonfirstclick] + datalist.data = ( + '' + '' + '' + '' + '' + ) + valuefalse = '0' + valuetrue = '1' + end + item + width = 20 + textflags = [tf_xcentered, tf_ycentered, tf_noselect] + optionsedit = [scoe_undoonesc, scoe_forcereturncheckvalue, scoe_eatreturn, scoe_autoselect, scoe_autoselectonfirstclick] + datalist.data = ( + '' + '' + '' + '' + '' + ) + valuefalse = '0' + valuetrue = '1' + end + item + width = 20 + textflags = [tf_xcentered, tf_ycentered, tf_noselect] + optionsedit = [scoe_undoonesc, scoe_forcereturncheckvalue, scoe_eatreturn, scoe_autoselect, scoe_autoselectonfirstclick] + datalist.data = ( + '' + '' + '' + '' + '' + ) + valuefalse = '0' + valuetrue = '1' + end + item + width = 20 + textflags = [tf_xcentered, tf_ycentered, tf_noselect] + optionsedit = [scoe_undoonesc, scoe_forcereturncheckvalue, scoe_eatreturn, scoe_autoselect, scoe_autoselectonfirstclick] + datalist.data = ( + '' + '' + '' + '' + '' + ) + valuefalse = '0' + valuetrue = '1' + end + item + width = 20 + textflags = [tf_xcentered, tf_ycentered, tf_noselect] + optionsedit = [scoe_undoonesc, scoe_forcereturncheckvalue, scoe_eatreturn, scoe_autoselect, scoe_autoselectonfirstclick] + datalist.data = ( + '' + '' + '' + '' + '' + ) + valuefalse = '0' + valuetrue = '1' + end + item + width = 20 + textflags = [tf_xcentered, tf_ycentered, tf_noselect] + optionsedit = [scoe_undoonesc, scoe_forcereturncheckvalue, scoe_eatreturn, scoe_autoselect, scoe_autoselectonfirstclick] + datalist.data = ( + '' + '' + '' + '' + '' + ) + valuefalse = '0' + valuetrue = '1' + end + item + width = 20 + textflags = [tf_xcentered, tf_ycentered, tf_noselect] + optionsedit = [scoe_undoonesc, scoe_forcereturncheckvalue, scoe_eatreturn, scoe_autoselect, scoe_autoselectonfirstclick] + datalist.data = ( + '' + '' + '' + '' + '' + ) + valuefalse = '0' + valuetrue = '1' + end + item + width = 20 + textflags = [tf_xcentered, tf_ycentered, tf_noselect] + optionsedit = [scoe_undoonesc, scoe_forcereturncheckvalue, scoe_eatreturn, scoe_autoselect, scoe_autoselectonfirstclick] + datalist.data = ( + '' + '' + '' + '' + '' + ) + valuefalse = '0' + valuetrue = '1' + end + item + width = 20 + textflags = [tf_xcentered, tf_ycentered, tf_noselect] + optionsedit = [scoe_undoonesc, scoe_forcereturncheckvalue, scoe_eatreturn, scoe_autoselect, scoe_autoselectonfirstclick] + datalist.data = ( + '' + '' + '' + '' + '' + ) + valuefalse = '0' + valuetrue = '1' + end + item + width = 20 + textflags = [tf_xcentered, tf_ycentered, tf_noselect] + optionsedit = [scoe_undoonesc, scoe_forcereturncheckvalue, scoe_eatreturn, scoe_autoselect, scoe_autoselectonfirstclick] + datalist.data = ( + '' + '' + '' + '' + '' + ) + valuefalse = '0' + valuetrue = '1' + end + item + width = 20 + textflags = [tf_xcentered, tf_ycentered, tf_noselect] + optionsedit = [scoe_undoonesc, scoe_forcereturncheckvalue, scoe_eatreturn, scoe_autoselect, scoe_autoselectonfirstclick] + datalist.data = ( + '' + '' + '' + '' + '' + ) + valuefalse = '0' + valuetrue = '1' + end + item + width = 20 + textflags = [tf_xcentered, tf_ycentered, tf_noselect] + optionsedit = [scoe_undoonesc, scoe_forcereturncheckvalue, scoe_eatreturn, scoe_autoselect, scoe_autoselectonfirstclick] + datalist.data = ( + '' + '' + '' + '' + '' + ) + valuefalse = '0' + valuetrue = '1' + end + item + width = 20 + textflags = [tf_xcentered, tf_ycentered, tf_noselect] + optionsedit = [scoe_undoonesc, scoe_forcereturncheckvalue, scoe_eatreturn, scoe_autoselect, scoe_autoselectonfirstclick] + datalist.data = ( + '' + '' + '' + '' + '' + ) + valuefalse = '0' + valuetrue = '1' + end + item + width = 20 + textflags = [tf_xcentered, tf_ycentered, tf_noselect] + optionsedit = [scoe_undoonesc, scoe_forcereturncheckvalue, scoe_eatreturn, scoe_autoselect, scoe_autoselectonfirstclick] + datalist.data = ( + '' + '' + '' + '' + '' + ) + valuefalse = '0' + valuetrue = '1' + end + item + width = 20 + textflags = [tf_xcentered, tf_ycentered, tf_noselect] + optionsedit = [scoe_undoonesc, scoe_forcereturncheckvalue, scoe_eatreturn, scoe_autoselect, scoe_autoselectonfirstclick] + datalist.data = ( + '' + '' + '' + '' + '' + ) + valuefalse = '0' + valuetrue = '1' + end> + fixcols.count = 1 + fixcols.items = < + item + width = 71 + onafterdrawcell = drawfixcol + end> + fixrows.count = 1 + fixrows.items = < + item + height = 18 + captions.count = 16 + captions.items = < + item + caption = '0' + end + item + caption = '1' + end + item + caption = '2' + end + item + caption = '3' + end + item + caption = '4' + end + item + caption = '5' + end + item + caption = '6' + end + item + caption = '7' + end + item + caption = '8' + end + item + caption = '9' + end + item + caption = 'A' + end + item + caption = 'B' + end + item + caption = 'C' + end + item + caption = 'D' + end + item + caption = 'E' + end + item + caption = 'F' + end> + end> + rowcount = 5 + datarowheight = 18 + reffontheight = 16 + end + object tlayouter1: tlayouter + frame.framei_left = 5 + frame.localprops = [frl_fileft] + frame.localprops1 = [] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 433 + bounds_cy = 31 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + optionslayout = [lao_placex, lao_aligny] + place_mindist = 5 + place_maxdist = 5 + linkbottom = grid + dist_bottom = 7 + object add: tint64edit + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + frame.caption = 'Add' + frame.captionpos = cp_right + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 25 + 0 + ) + taborder = 3 + bounds_x = 5 + bounds_y = 9 + bounds_cx = 143 + bounds_cy = 22 + statfile = mainfo.projectstatfile + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_forcereturncheckvalue, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + ondataentered = adent + base = nb_hex + valuemax = -1 + reffontheight = 16 + end + object memon: tbooleanedit + frame.caption = 'Memory &on' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 2 + 64 + 3 + ) + bounds_x = 356 + bounds_y = 12 + bounds_cx = 77 + bounds_cy = 18 + statfile = mainfo.projectstatfile + ondataentered = adent + end + object bitwidth: tenumedit + frame.caption = 'Width' + frame.captionpos = cp_right + frame.localprops = [] + frame.localprops1 = [] + frame.button.color = -2147483646 + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + end> + frame.outerframe = ( + 0 + 0 + 35 + 0 + ) + taborder = 1 + bounds_x = 264 + bounds_y = 9 + bounds_cx = 87 + bounds_cy = 22 + statfile = mainfo.projectstatfile + textflags = [tf_xcentered, tf_ycentered, tf_noselect] + ondataentered = updatelayoutexe + dropdown.cols.count = 1 + dropdown.cols.items = < + item + data = ( + '8' + '16' + '32' + '64' + ) + end> + value = 0 + reffontheight = 16 + end + object cnt: tintegeredit + frame.caption = 'Cnt' + frame.captionpos = cp_right + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 22 + 0 + ) + taborder = 2 + bounds_x = 153 + bounds_y = 9 + bounds_cx = 106 + bounds_cy = 22 + statfile = mainfo.projectstatfile + ondataentered = adent + base = nb_hex + reffontheight = 16 + end + end +end diff --git a/mseide-msegui/apps/ide/memoryform.pas b/mseide-msegui/apps/ide/memoryform.pas new file mode 100644 index 0000000..1b44485 --- /dev/null +++ b/mseide-msegui/apps/ide/memoryform.pas @@ -0,0 +1,254 @@ +unit memoryform; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseglob,mseguiglob,mseapplication,msestat,msemenus,msegui,msegraphics, + msegraphutils,mseevent,mseclasses,mseforms,msedock,msegrids,msestrings, + msetypes,msedataedits,mseedit,msegraphedits,msesplitter; + +type + tmemoryfo = class(tdockform) + grid: tstringgrid; + tlayouter1: tlayouter; + memon: tbooleanedit; + bitwidth: tenumedit; + cnt: tintegeredit; + add: tint64edit; + procedure adent(const sender: TObject); + procedure drawfixcol(const sender: tcol; const canvas: tcanvas; + var cellinfo: cellinfoty); + procedure updatelayoutexe(const sender: TObject); + procedure formshow(const sender: TObject); + procedure cellsetvalue(const sender: TObject; var avalue: msestring; + var accept: Boolean); + private + firstadd: card64; + fhexwidth: int32; + procedure updatecolwidth(); + public + procedure refresh; + end; +var + memoryfo: tmemoryfo; +implementation +uses + memoryform_mfm,mseformatstr,msedrawtext,main,msegdbutils,msewidgets; + +type + bitwidthty = (bw_8,bw_16,bw_32,bw_64); + +procedure tmemoryfo.adent(const sender: TObject); +begin + updatelayoutexe(nil); +end; + +procedure tmemoryfo.refresh; +var + linecount: integer; + int1,int2,int3: integer; + bytes: bytearty; + words: wordarty; + longwords: longwordarty; + qwords: card64arty; +begin + add.bitcount:= mainfo.gdb.pointersize*8; + updatecolwidth(); + if memon.value and isvisible then begin + firstadd:= add.value and $fffffffffffffff0; + linecount:= ((add.value + cnt.value + $f)-firstadd) div $10; + if linecount < 0 then begin + linecount:= 0; + cnt.value:= 0; + end; + if (linecount > 1000) then begin + linecount:= 1000; + cnt.value:= linecount * $10; + end; + grid.rowcount:= linecount; + if mainfo.gdb.cancommand then begin + case bitwidthty(bitwidth.value) of + bw_8: begin + bytes:= nil; + mainfo.gdb.readmemorybytes(add.value,cnt.value,bytes); + int3:= -(add.value and $f); + for int1:= 0 to linecount-1 do begin //todo: optimize + for int2:= 0 to 15 do begin + if (int3 < 0) or (int3 > high(bytes)) then begin + grid[int2][int1]:= ''; + end + else begin + grid[int2][int1]:= hextostrmse(bytes[int3],2); + end; + inc(int3); + end; + end; + end; + bw_16: begin + words:= nil; + mainfo.gdb.readmemorywords(add.value,cnt.value div 2,words); + int3:= -(add.value and $f) div 2; + for int1:= 0 to linecount-1 do begin //todo: optimize + for int2:= 0 to 7 do begin + if (int3 < 0) or (int3 > high(words)) then begin + grid[int2][int1]:= ''; + end + else begin + grid[int2][int1]:= hextostrmse(words[int3],4); + end; + inc(int3); + end; + end; + end; + bw_32: begin + longwords:= nil; + mainfo.gdb.readmemorylongwords(add.value,cnt.value div 4,longwords); + int3:= -(add.value and $f) div 4; + for int1:= 0 to linecount-1 do begin //todo: optimize + for int2:= 0 to 3 do begin + if (int3 < 0) or (int3 > high(longwords)) then begin + grid[int2][int1]:= ''; + end + else begin + grid[int2][int1]:= hextostrmse(longwords[int3],8); + end; + inc(int3); + end; + end; + end; + bw_64: begin + qwords:= nil; + mainfo.gdb.readmemoryqwords(add.value,cnt.value div 8,qwords); + int3:= -(add.value and $f) div 8; + for int1:= 0 to linecount-1 do begin //todo: optimize + for int2:= 0 to 1 do begin + if (int3 < 0) or (int3 > high(qwords)) then begin + grid[int2][int1]:= ''; + end + else begin + grid[int2][int1]:= hextostrmse(qwords[int3],16); + end; + inc(int3); + end; + end; + end; + end; + end; + grid.invalidate; + end + else begin + grid.rowcount:= 0; + end; +end; + +procedure tmemoryfo.drawfixcol(const sender: tcol; const canvas: tcanvas; + var cellinfo: cellinfoty); +begin + drawtext(canvas,hextostrmse(card64(firstadd+cellinfo.cell.row*16),fhexwidth), + cellinfo.innerrect); +end; + +procedure tmemoryfo.updatecolwidth(); +var + mstr1: msestring; +begin + if mainfo.gdb.pointersize = 8 then begin + mstr1:= 'WWWWWWWWWWWWWWWW'; + fhexwidth:= 16; + end + else begin + mstr1:= 'WWWWWWWW'; + fhexwidth:= 8; + end; + grid.fixcols[-1].width:= getcanvas.getstringwidth(mstr1,grid.font)+4; +end; + +procedure tmemoryfo.updatelayoutexe(const sender: TObject); +var + int1: integer; + mstr1: msestring; +begin + mstr1:= ''; + case bitwidthty(bitwidth.value) of + bw_8: begin + mstr1:= 'WW'; + grid.datacols.count:= 16; + for int1:= 0 to 15 do begin + grid.fixrows[-1].captions[int1].caption:= msechar(charhex[int1]); +// grid.datacols[int1].ondataentered:= {$ifdef FPC}@{$endif}celldataentered; + grid.datacols[int1].onsetvalue:= {$ifdef FPC}@{$endif}cellsetvalue; + end; + end; + bw_16: begin + mstr1:= 'WWWW'; + grid.datacols.count:= 8; + for int1:= 0 to 7 do begin + grid.fixrows[-1].captions[int1].caption:= msechar(charhex[int1*2]); +// grid.datacols[int1].ondataentered:= {$ifdef FPC}@{$endif}celldataentered; + grid.datacols[int1].onsetvalue:= {$ifdef FPC}@{$endif}cellsetvalue; + end; + add.value:= add.value and not 3; + end; + bw_32: begin + mstr1:= 'WWWWWWWW'; + grid.datacols.count:= 4; + for int1:= 0 to 3 do begin + grid.fixrows[-1].captions[int1].caption:= msechar(charhex[int1*4]); +// grid.datacols[int1].ondataentered:= {$ifdef FPC}@{$endif}celldataentered; + grid.datacols[int1].onsetvalue:= {$ifdef FPC}@{$endif}cellsetvalue; + end; + add.value:= add.value and not 7; + end; + bw_64: begin + mstr1:= 'WWWWWWWWWWWWWWWW'; + grid.datacols.count:= 2; + for int1:= 0 to 1 do begin + grid.fixrows[-1].captions[int1].caption:= msechar(charhex[int1*8]); +// grid.datacols[int1].ondataentered:= {$ifdef FPC}@{$endif}celldataentered; + grid.datacols[int1].onsetvalue:= {$ifdef FPC}@{$endif}cellsetvalue; + end; + add.value:= add.value and not 15; + end; + end; + int1:= getcanvas.getstringwidth(mstr1,grid.font); + grid.datacols.width:= int1+4; + updatecolwidth(); + refresh; +end; + +procedure tmemoryfo.formshow(const sender: TObject); +begin + refresh; +end; + +procedure tmemoryfo.cellsetvalue(const sender: TObject; var avalue: msestring; + var accept: Boolean); +var + val: card64; + res: gdbresultty; +begin + if mainfo.gdb.cancommand then begin + accept:= false; + val:= strtohex64(ansistring(avalue)); + res:= gdb_error; + case bitwidthty(bitwidth.value) of + bw_8: begin + res:= mainfo.gdb.writememory8(firstadd+grid.row*16+grid.col*8,val); + end; + bw_16: begin + res:= mainfo.gdb.writememory16(firstadd+grid.row*16+grid.col*2,val); + end; + bw_32: begin + res:= mainfo.gdb.writememory32(firstadd+grid.row*16+grid.col*4,val); + end; + bw_64: begin + res:= mainfo.gdb.writememory64(firstadd+grid.row*16+grid.col*8,val); + end; + end; + if res <> gdb_ok then begin + showerror(msestring(mainfo.gdb.errormessage)); + end; + refresh; + end; +end; + +end. diff --git a/mseide-msegui/apps/ide/memoryform_mfm.pas b/mseide-msegui/apps/ide/memoryform_mfm.pas new file mode 100644 index 0000000..23461d4 --- /dev/null +++ b/mseide-msegui/apps/ide/memoryform_mfm.pas @@ -0,0 +1,453 @@ +unit memoryform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,memoryform; + +const + objdata: record size: integer; data: array[0..8712] of byte end = + (size: 8713; data: ( + 84,80,70,48,9,116,109,101,109,111,114,121,102,111,8,109,101,109,111,114, + 121,102,111,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,11,111,119,95,115,117,98,102, + 111,99,117,115,13,111,119,95,109,111,117,115,101,119,104,101,101,108,17,111, + 119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,9,111,119,95, + 104,105,110,116,111,110,0,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,15,102,114,97,109,101,46,103,114,105,112,95,115,105, + 122,101,2,10,18,102,114,97,109,101,46,103,114,105,112,95,111,112,116,105, + 111,110,115,11,14,103,111,95,99,108,111,115,101,98,117,116,116,111,110,16, + 103,111,95,102,105,120,115,105,122,101,98,117,116,116,111,110,14,103,111,95, + 102,108,111,97,116,98,117,116,116,111,110,12,103,111,95,116,111,112,98,117, + 116,116,111,110,19,103,111,95,98,97,99,107,103,114,111,117,110,100,98,117, + 116,116,111,110,15,103,111,95,110,111,108,111,99,107,98,117,116,116,111,110, + 14,103,111,95,98,117,116,116,111,110,104,105,110,116,115,0,7,118,105,115, + 105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,100,8,98,111,117, + 110,100,115,95,121,2,100,9,98,111,117,110,100,115,95,99,120,3,209,1, + 9,98,111,117,110,100,115,95,99,121,3,98,1,26,99,111,110,116,97,105, + 110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,0,27,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,99,111,110,116,97,105,110, + 101,114,46,98,111,117,110,100,115,1,2,0,2,0,3,199,1,3,98,1, + 0,20,100,114,97,103,100,111,99,107,46,111,112,116,105,111,110,115,100,111, + 99,107,11,10,111,100,95,115,97,118,101,112,111,115,13,111,100,95,115,97, + 118,101,122,111,114,100,101,114,10,111,100,95,99,97,110,109,111,118,101,10, + 111,100,95,99,97,110,115,105,122,101,11,111,100,95,99,97,110,102,108,111, + 97,116,10,111,100,95,99,97,110,100,111,99,107,11,111,100,95,112,114,111, + 112,115,105,122,101,14,111,100,95,99,97,112,116,105,111,110,104,105,110,116, + 13,111,100,95,99,104,105,108,100,105,99,111,110,115,0,7,111,112,116,105, + 111,110,115,11,10,102,111,95,115,97,118,101,112,111,115,13,102,111,95,115, + 97,118,101,122,111,114,100,101,114,12,102,111,95,115,97,118,101,115,116,97, + 116,101,0,8,115,116,97,116,102,105,108,101,7,22,109,97,105,110,102,111, + 46,112,114,111,106,101,99,116,115,116,97,116,102,105,108,101,7,99,97,112, + 116,105,111,110,6,6,77,101,109,111,114,121,21,105,99,111,110,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,12, + 105,99,111,110,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,0,10,105,99,111,110,46,105,109,97,103,101,10,252,5,0, + 0,0,0,0,0,2,0,0,0,24,0,0,0,24,0,0,0,104,5,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,124,124,124,23,255,255,255, + 1,124,124,124,1,192,192,192,4,169,169,169,1,192,192,192,5,169,169,169, + 1,192,192,192,5,169,169,169,1,192,192,192,5,255,255,255,1,124,124,124, + 1,192,192,192,4,169,169,169,1,192,192,192,1,130,130,130,1,172,172,172, + 1,134,134,134,1,184,184,184,1,169,169,169,1,192,192,192,1,142,142,142, + 1,163,163,163,1,133,133,133,1,176,176,176,1,169,169,169,1,192,192,192, + 1,164,164,164,1,190,190,190,1,134,134,134,1,181,181,181,1,255,255,255, + 1,124,124,124,1,192,192,192,1,138,138,138,1,144,144,144,1,192,192,192, + 1,169,169,169,1,191,191,191,1,130,130,130,1,190,190,190,1,129,129,129, + 1,181,181,181,1,169,169,169,1,181,181,181,1,107,107,107,1,143,143,143, + 1,96,96,96,1,155,155,155,1,169,169,169,1,192,192,192,1,108,108,108, + 1,167,167,167,1,120,120,120,1,178,178,178,1,255,255,255,1,124,124,124, + 1,191,191,191,1,88,88,88,1,118,118,118,1,192,192,192,1,169,169,169, + 1,192,192,192,1,151,151,151,1,156,156,156,1,117,117,117,1,181,181,181, + 1,169,169,169,1,192,192,192,1,136,136,136,1,142,142,142,1,136,136,136, + 1,160,160,160,1,169,169,169,1,192,192,192,1,138,138,138,1,178,178,178, + 1,136,136,136,1,155,155,155,1,255,255,255,1,124,124,124,1,192,192,192, + 4,169,169,169,1,192,192,192,5,169,169,169,1,192,192,192,5,169,169,169, + 1,192,192,192,5,255,255,255,1,124,124,124,1,169,169,169,22,255,255,255, + 1,124,124,124,1,192,192,192,4,169,169,169,1,255,255,255,5,169,169,169, + 1,255,255,255,5,169,169,169,1,255,255,255,6,124,124,124,1,192,192,192, + 4,169,169,169,1,255,255,255,1,151,151,151,1,186,186,186,1,141,141,141, + 1,248,248,248,1,169,169,169,1,255,255,255,1,177,177,177,1,222,222,222, + 1,158,158,158,1,236,236,236,1,169,169,169,1,255,255,255,1,136,136,136, + 1,236,236,236,1,150,150,150,1,255,255,255,2,124,124,124,1,192,192,192, + 1,130,130,130,1,145,145,145,1,192,192,192,1,169,169,169,1,255,255,255, + 1,126,126,126,1,119,119,119,1,143,143,143,1,244,244,244,1,169,169,169, + 1,237,237,237,1,104,104,104,1,171,171,171,1,178,178,178,1,167,167,167, + 1,169,169,169,1,255,255,255,1,135,135,135,1,237,237,237,1,147,147,147, + 1,255,255,255,2,124,124,124,1,192,192,192,1,152,152,152,1,144,144,144, + 1,192,192,192,1,169,169,169,1,255,255,255,1,161,161,161,1,178,178,178, + 1,179,179,179,1,246,246,246,1,169,169,169,1,250,250,250,1,127,127,127, + 1,132,132,132,1,80,80,80,1,211,211,211,1,169,169,169,1,255,255,255, + 1,171,171,171,1,255,255,255,1,171,171,171,1,255,255,255,2,124,124,124, + 1,192,192,192,4,169,169,169,1,255,255,255,5,169,169,169,1,255,255,255, + 5,169,169,169,1,255,255,255,6,124,124,124,1,169,169,169,22,255,255,255, + 1,124,124,124,1,192,192,192,4,169,169,169,1,255,255,255,5,169,169,169, + 1,255,255,255,5,169,169,169,1,255,255,255,6,124,124,124,1,192,192,192, + 1,172,172,172,1,192,192,192,2,169,169,169,1,255,255,255,1,160,160,160, + 1,227,227,227,1,150,150,150,1,243,243,243,1,169,169,169,1,255,255,255, + 1,161,161,161,1,226,226,226,1,150,150,150,1,241,241,241,1,169,169,169, + 1,248,248,248,1,133,133,133,1,186,186,186,1,128,128,128,1,227,227,227, + 1,255,255,255,1,124,124,124,1,192,192,192,1,147,147,147,1,192,192,192, + 2,169,169,169,1,227,227,227,1,161,161,161,1,105,105,105,1,189,189,189, + 1,145,145,145,1,169,169,169,1,232,232,232,1,157,157,157,1,107,107,107, + 1,186,186,186,1,144,144,144,1,169,169,169,1,207,207,207,1,183,183,183, + 1,96,96,96,1,204,204,204,1,153,153,153,1,255,255,255,1,124,124,124, + 1,192,192,192,1,132,132,132,1,192,192,192,2,169,169,169,1,251,251,251, + 1,120,120,120,1,141,141,141,1,119,119,119,1,177,177,177,1,169,169,169, + 1,253,253,253,1,121,121,121,1,143,143,143,1,120,120,120,1,173,173,173, + 1,169,169,169,1,253,253,253,1,133,133,133,1,174,174,174,1,128,128,128, + 1,216,216,216,1,255,255,255,1,124,124,124,1,192,192,192,1,143,143,143, + 1,192,192,192,2,169,169,169,1,255,255,255,5,169,169,169,1,255,255,255, + 5,169,169,169,1,255,255,255,6,124,124,124,1,169,169,169,22,255,255,255, + 1,124,124,124,1,192,192,192,4,169,169,169,1,255,255,255,5,169,169,169, + 1,255,255,255,5,169,169,169,1,255,255,255,6,124,124,124,1,192,192,192, + 4,169,169,169,1,243,243,243,1,147,147,147,1,216,216,216,1,140,140,140, + 1,255,255,255,1,169,169,169,1,251,251,251,1,138,138,138,1,214,214,214, + 1,165,165,165,1,255,255,255,1,169,169,169,1,255,255,255,1,170,170,170, + 1,210,210,210,1,186,186,186,1,199,199,199,1,255,255,255,1,124,124,124, + 1,192,192,192,1,144,144,144,1,122,122,122,1,187,187,187,1,169,169,169, + 1,171,171,171,1,128,128,128,1,192,192,192,1,143,143,143,1,255,255,255, + 1,169,169,169,1,248,248,248,1,140,140,140,1,234,234,234,1,149,149,149, + 1,255,255,255,1,169,169,169,1,255,255,255,1,188,188,188,1,178,178,178, + 1,105,105,105,1,163,163,163,1,255,255,255,1,124,124,124,1,192,192,192, + 1,157,157,157,1,127,127,127,1,190,190,190,1,169,169,169,1,231,231,231, + 1,141,141,141,1,199,199,199,1,171,171,171,1,255,255,255,1,169,169,169, + 1,255,255,255,1,171,171,171,1,255,255,255,1,171,171,171,1,255,255,255, + 1,169,169,169,1,255,255,255,1,218,218,218,1,193,193,193,1,160,160,160, + 1,171,171,171,1,255,255,255,1,124,124,124,1,255,255,255,23,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,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,6,111,110,115,104,111,119, + 7,8,102,111,114,109,115,104,111,119,15,109,111,100,117,108,101,99,108,97, + 115,115,110,97,109,101,6,9,116,100,111,99,107,102,111,114,109,0,11,116, + 115,116,114,105,110,103,103,114,105,100,4,103,114,105,100,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,98,111,117,110,100, + 115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,38,9,98,111,117, + 110,100,115,95,99,120,3,199,1,9,98,111,117,110,100,115,95,99,121,3, + 60,1,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,9,97, + 110,95,98,111,116,116,111,109,0,9,102,111,110,116,46,110,97,109,101,6, + 9,115,116,102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97, + 108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,108,112,95,120,115,99,97,108,101,0,14,100,97,116,97,99,111, + 108,115,46,99,111,117,110,116,2,16,14,100,97,116,97,99,111,108,115,46, + 119,105,100,116,104,2,20,18,100,97,116,97,99,111,108,115,46,116,101,120, + 116,102,108,97,103,115,11,12,116,102,95,120,99,101,110,116,101,114,101,100, + 12,116,102,95,121,99,101,110,116,101,114,101,100,11,116,102,95,110,111,115, + 101,108,101,99,116,0,20,100,97,116,97,99,111,108,115,46,111,112,116,105, + 111,110,115,101,100,105,116,11,14,115,99,111,101,95,117,110,100,111,111,110, + 101,115,99,26,115,99,111,101,95,102,111,114,99,101,114,101,116,117,114,110, + 99,104,101,99,107,118,97,108,117,101,14,115,99,111,101,95,101,97,116,114, + 101,116,117,114,110,15,115,99,111,101,95,97,117,116,111,115,101,108,101,99, + 116,27,115,99,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102, + 105,114,115,116,99,108,105,99,107,0,14,100,97,116,97,99,111,108,115,46, + 105,116,101,109,115,14,1,5,119,105,100,116,104,2,20,9,116,101,120,116, + 102,108,97,103,115,11,12,116,102,95,120,99,101,110,116,101,114,101,100,12, + 116,102,95,121,99,101,110,116,101,114,101,100,11,116,102,95,110,111,115,101, + 108,101,99,116,0,11,111,112,116,105,111,110,115,101,100,105,116,11,14,115, + 99,111,101,95,117,110,100,111,111,110,101,115,99,26,115,99,111,101,95,102, + 111,114,99,101,114,101,116,117,114,110,99,104,101,99,107,118,97,108,117,101, + 14,115,99,111,101,95,101,97,116,114,101,116,117,114,110,15,115,99,111,101, + 95,97,117,116,111,115,101,108,101,99,116,27,115,99,111,101,95,97,117,116, + 111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0, + 13,100,97,116,97,108,105,115,116,46,100,97,116,97,1,6,0,6,0,6, + 0,6,0,6,0,0,10,118,97,108,117,101,102,97,108,115,101,6,1,48, + 9,118,97,108,117,101,116,114,117,101,6,1,49,10,111,110,115,101,116,118, + 97,108,117,101,7,12,99,101,108,108,115,101,116,118,97,108,117,101,13,111, + 110,100,97,116,97,101,110,116,101,114,101,100,7,5,97,100,101,110,116,0, + 1,5,119,105,100,116,104,2,20,9,116,101,120,116,102,108,97,103,115,11, + 12,116,102,95,120,99,101,110,116,101,114,101,100,12,116,102,95,121,99,101, + 110,116,101,114,101,100,11,116,102,95,110,111,115,101,108,101,99,116,0,11, + 111,112,116,105,111,110,115,101,100,105,116,11,14,115,99,111,101,95,117,110, + 100,111,111,110,101,115,99,26,115,99,111,101,95,102,111,114,99,101,114,101, + 116,117,114,110,99,104,101,99,107,118,97,108,117,101,14,115,99,111,101,95, + 101,97,116,114,101,116,117,114,110,15,115,99,111,101,95,97,117,116,111,115, + 101,108,101,99,116,27,115,99,111,101,95,97,117,116,111,115,101,108,101,99, + 116,111,110,102,105,114,115,116,99,108,105,99,107,0,13,100,97,116,97,108, + 105,115,116,46,100,97,116,97,1,6,0,6,0,6,0,6,0,6,0,0, + 10,118,97,108,117,101,102,97,108,115,101,6,1,48,9,118,97,108,117,101, + 116,114,117,101,6,1,49,0,1,5,119,105,100,116,104,2,20,9,116,101, + 120,116,102,108,97,103,115,11,12,116,102,95,120,99,101,110,116,101,114,101, + 100,12,116,102,95,121,99,101,110,116,101,114,101,100,11,116,102,95,110,111, + 115,101,108,101,99,116,0,11,111,112,116,105,111,110,115,101,100,105,116,11, + 14,115,99,111,101,95,117,110,100,111,111,110,101,115,99,26,115,99,111,101, + 95,102,111,114,99,101,114,101,116,117,114,110,99,104,101,99,107,118,97,108, + 117,101,14,115,99,111,101,95,101,97,116,114,101,116,117,114,110,15,115,99, + 111,101,95,97,117,116,111,115,101,108,101,99,116,27,115,99,111,101,95,97, + 117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99, + 107,0,13,100,97,116,97,108,105,115,116,46,100,97,116,97,1,6,0,6, + 0,6,0,6,0,6,0,0,10,118,97,108,117,101,102,97,108,115,101,6, + 1,48,9,118,97,108,117,101,116,114,117,101,6,1,49,0,1,5,119,105, + 100,116,104,2,20,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95, + 120,99,101,110,116,101,114,101,100,12,116,102,95,121,99,101,110,116,101,114, + 101,100,11,116,102,95,110,111,115,101,108,101,99,116,0,11,111,112,116,105, + 111,110,115,101,100,105,116,11,14,115,99,111,101,95,117,110,100,111,111,110, + 101,115,99,26,115,99,111,101,95,102,111,114,99,101,114,101,116,117,114,110, + 99,104,101,99,107,118,97,108,117,101,14,115,99,111,101,95,101,97,116,114, + 101,116,117,114,110,15,115,99,111,101,95,97,117,116,111,115,101,108,101,99, + 116,27,115,99,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102, + 105,114,115,116,99,108,105,99,107,0,13,100,97,116,97,108,105,115,116,46, + 100,97,116,97,1,6,0,6,0,6,0,6,0,6,0,0,10,118,97,108, + 117,101,102,97,108,115,101,6,1,48,9,118,97,108,117,101,116,114,117,101, + 6,1,49,0,1,5,119,105,100,116,104,2,20,9,116,101,120,116,102,108, + 97,103,115,11,12,116,102,95,120,99,101,110,116,101,114,101,100,12,116,102, + 95,121,99,101,110,116,101,114,101,100,11,116,102,95,110,111,115,101,108,101, + 99,116,0,11,111,112,116,105,111,110,115,101,100,105,116,11,14,115,99,111, + 101,95,117,110,100,111,111,110,101,115,99,26,115,99,111,101,95,102,111,114, + 99,101,114,101,116,117,114,110,99,104,101,99,107,118,97,108,117,101,14,115, + 99,111,101,95,101,97,116,114,101,116,117,114,110,15,115,99,111,101,95,97, + 117,116,111,115,101,108,101,99,116,27,115,99,111,101,95,97,117,116,111,115, + 101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,13,100, + 97,116,97,108,105,115,116,46,100,97,116,97,1,6,0,6,0,6,0,6, + 0,6,0,0,10,118,97,108,117,101,102,97,108,115,101,6,1,48,9,118, + 97,108,117,101,116,114,117,101,6,1,49,0,1,5,119,105,100,116,104,2, + 20,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,120,99,101,110, + 116,101,114,101,100,12,116,102,95,121,99,101,110,116,101,114,101,100,11,116, + 102,95,110,111,115,101,108,101,99,116,0,11,111,112,116,105,111,110,115,101, + 100,105,116,11,14,115,99,111,101,95,117,110,100,111,111,110,101,115,99,26, + 115,99,111,101,95,102,111,114,99,101,114,101,116,117,114,110,99,104,101,99, + 107,118,97,108,117,101,14,115,99,111,101,95,101,97,116,114,101,116,117,114, + 110,15,115,99,111,101,95,97,117,116,111,115,101,108,101,99,116,27,115,99, + 111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116, + 99,108,105,99,107,0,13,100,97,116,97,108,105,115,116,46,100,97,116,97, + 1,6,0,6,0,6,0,6,0,6,0,0,10,118,97,108,117,101,102,97, + 108,115,101,6,1,48,9,118,97,108,117,101,116,114,117,101,6,1,49,0, + 1,5,119,105,100,116,104,2,20,9,116,101,120,116,102,108,97,103,115,11, + 12,116,102,95,120,99,101,110,116,101,114,101,100,12,116,102,95,121,99,101, + 110,116,101,114,101,100,11,116,102,95,110,111,115,101,108,101,99,116,0,11, + 111,112,116,105,111,110,115,101,100,105,116,11,14,115,99,111,101,95,117,110, + 100,111,111,110,101,115,99,26,115,99,111,101,95,102,111,114,99,101,114,101, + 116,117,114,110,99,104,101,99,107,118,97,108,117,101,14,115,99,111,101,95, + 101,97,116,114,101,116,117,114,110,15,115,99,111,101,95,97,117,116,111,115, + 101,108,101,99,116,27,115,99,111,101,95,97,117,116,111,115,101,108,101,99, + 116,111,110,102,105,114,115,116,99,108,105,99,107,0,13,100,97,116,97,108, + 105,115,116,46,100,97,116,97,1,6,0,6,0,6,0,6,0,6,0,0, + 10,118,97,108,117,101,102,97,108,115,101,6,1,48,9,118,97,108,117,101, + 116,114,117,101,6,1,49,0,1,5,119,105,100,116,104,2,20,9,116,101, + 120,116,102,108,97,103,115,11,12,116,102,95,120,99,101,110,116,101,114,101, + 100,12,116,102,95,121,99,101,110,116,101,114,101,100,11,116,102,95,110,111, + 115,101,108,101,99,116,0,11,111,112,116,105,111,110,115,101,100,105,116,11, + 14,115,99,111,101,95,117,110,100,111,111,110,101,115,99,26,115,99,111,101, + 95,102,111,114,99,101,114,101,116,117,114,110,99,104,101,99,107,118,97,108, + 117,101,14,115,99,111,101,95,101,97,116,114,101,116,117,114,110,15,115,99, + 111,101,95,97,117,116,111,115,101,108,101,99,116,27,115,99,111,101,95,97, + 117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99, + 107,0,13,100,97,116,97,108,105,115,116,46,100,97,116,97,1,6,0,6, + 0,6,0,6,0,6,0,0,10,118,97,108,117,101,102,97,108,115,101,6, + 1,48,9,118,97,108,117,101,116,114,117,101,6,1,49,0,1,5,119,105, + 100,116,104,2,20,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95, + 120,99,101,110,116,101,114,101,100,12,116,102,95,121,99,101,110,116,101,114, + 101,100,11,116,102,95,110,111,115,101,108,101,99,116,0,11,111,112,116,105, + 111,110,115,101,100,105,116,11,14,115,99,111,101,95,117,110,100,111,111,110, + 101,115,99,26,115,99,111,101,95,102,111,114,99,101,114,101,116,117,114,110, + 99,104,101,99,107,118,97,108,117,101,14,115,99,111,101,95,101,97,116,114, + 101,116,117,114,110,15,115,99,111,101,95,97,117,116,111,115,101,108,101,99, + 116,27,115,99,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102, + 105,114,115,116,99,108,105,99,107,0,13,100,97,116,97,108,105,115,116,46, + 100,97,116,97,1,6,0,6,0,6,0,6,0,6,0,0,10,118,97,108, + 117,101,102,97,108,115,101,6,1,48,9,118,97,108,117,101,116,114,117,101, + 6,1,49,0,1,5,119,105,100,116,104,2,20,9,116,101,120,116,102,108, + 97,103,115,11,12,116,102,95,120,99,101,110,116,101,114,101,100,12,116,102, + 95,121,99,101,110,116,101,114,101,100,11,116,102,95,110,111,115,101,108,101, + 99,116,0,11,111,112,116,105,111,110,115,101,100,105,116,11,14,115,99,111, + 101,95,117,110,100,111,111,110,101,115,99,26,115,99,111,101,95,102,111,114, + 99,101,114,101,116,117,114,110,99,104,101,99,107,118,97,108,117,101,14,115, + 99,111,101,95,101,97,116,114,101,116,117,114,110,15,115,99,111,101,95,97, + 117,116,111,115,101,108,101,99,116,27,115,99,111,101,95,97,117,116,111,115, + 101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,13,100, + 97,116,97,108,105,115,116,46,100,97,116,97,1,6,0,6,0,6,0,6, + 0,6,0,0,10,118,97,108,117,101,102,97,108,115,101,6,1,48,9,118, + 97,108,117,101,116,114,117,101,6,1,49,0,1,5,119,105,100,116,104,2, + 20,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,120,99,101,110, + 116,101,114,101,100,12,116,102,95,121,99,101,110,116,101,114,101,100,11,116, + 102,95,110,111,115,101,108,101,99,116,0,11,111,112,116,105,111,110,115,101, + 100,105,116,11,14,115,99,111,101,95,117,110,100,111,111,110,101,115,99,26, + 115,99,111,101,95,102,111,114,99,101,114,101,116,117,114,110,99,104,101,99, + 107,118,97,108,117,101,14,115,99,111,101,95,101,97,116,114,101,116,117,114, + 110,15,115,99,111,101,95,97,117,116,111,115,101,108,101,99,116,27,115,99, + 111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116, + 99,108,105,99,107,0,13,100,97,116,97,108,105,115,116,46,100,97,116,97, + 1,6,0,6,0,6,0,6,0,6,0,0,10,118,97,108,117,101,102,97, + 108,115,101,6,1,48,9,118,97,108,117,101,116,114,117,101,6,1,49,0, + 1,5,119,105,100,116,104,2,20,9,116,101,120,116,102,108,97,103,115,11, + 12,116,102,95,120,99,101,110,116,101,114,101,100,12,116,102,95,121,99,101, + 110,116,101,114,101,100,11,116,102,95,110,111,115,101,108,101,99,116,0,11, + 111,112,116,105,111,110,115,101,100,105,116,11,14,115,99,111,101,95,117,110, + 100,111,111,110,101,115,99,26,115,99,111,101,95,102,111,114,99,101,114,101, + 116,117,114,110,99,104,101,99,107,118,97,108,117,101,14,115,99,111,101,95, + 101,97,116,114,101,116,117,114,110,15,115,99,111,101,95,97,117,116,111,115, + 101,108,101,99,116,27,115,99,111,101,95,97,117,116,111,115,101,108,101,99, + 116,111,110,102,105,114,115,116,99,108,105,99,107,0,13,100,97,116,97,108, + 105,115,116,46,100,97,116,97,1,6,0,6,0,6,0,6,0,6,0,0, + 10,118,97,108,117,101,102,97,108,115,101,6,1,48,9,118,97,108,117,101, + 116,114,117,101,6,1,49,0,1,5,119,105,100,116,104,2,20,9,116,101, + 120,116,102,108,97,103,115,11,12,116,102,95,120,99,101,110,116,101,114,101, + 100,12,116,102,95,121,99,101,110,116,101,114,101,100,11,116,102,95,110,111, + 115,101,108,101,99,116,0,11,111,112,116,105,111,110,115,101,100,105,116,11, + 14,115,99,111,101,95,117,110,100,111,111,110,101,115,99,26,115,99,111,101, + 95,102,111,114,99,101,114,101,116,117,114,110,99,104,101,99,107,118,97,108, + 117,101,14,115,99,111,101,95,101,97,116,114,101,116,117,114,110,15,115,99, + 111,101,95,97,117,116,111,115,101,108,101,99,116,27,115,99,111,101,95,97, + 117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99, + 107,0,13,100,97,116,97,108,105,115,116,46,100,97,116,97,1,6,0,6, + 0,6,0,6,0,6,0,0,10,118,97,108,117,101,102,97,108,115,101,6, + 1,48,9,118,97,108,117,101,116,114,117,101,6,1,49,0,1,5,119,105, + 100,116,104,2,20,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95, + 120,99,101,110,116,101,114,101,100,12,116,102,95,121,99,101,110,116,101,114, + 101,100,11,116,102,95,110,111,115,101,108,101,99,116,0,11,111,112,116,105, + 111,110,115,101,100,105,116,11,14,115,99,111,101,95,117,110,100,111,111,110, + 101,115,99,26,115,99,111,101,95,102,111,114,99,101,114,101,116,117,114,110, + 99,104,101,99,107,118,97,108,117,101,14,115,99,111,101,95,101,97,116,114, + 101,116,117,114,110,15,115,99,111,101,95,97,117,116,111,115,101,108,101,99, + 116,27,115,99,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102, + 105,114,115,116,99,108,105,99,107,0,13,100,97,116,97,108,105,115,116,46, + 100,97,116,97,1,6,0,6,0,6,0,6,0,6,0,0,10,118,97,108, + 117,101,102,97,108,115,101,6,1,48,9,118,97,108,117,101,116,114,117,101, + 6,1,49,0,1,5,119,105,100,116,104,2,20,9,116,101,120,116,102,108, + 97,103,115,11,12,116,102,95,120,99,101,110,116,101,114,101,100,12,116,102, + 95,121,99,101,110,116,101,114,101,100,11,116,102,95,110,111,115,101,108,101, + 99,116,0,11,111,112,116,105,111,110,115,101,100,105,116,11,14,115,99,111, + 101,95,117,110,100,111,111,110,101,115,99,26,115,99,111,101,95,102,111,114, + 99,101,114,101,116,117,114,110,99,104,101,99,107,118,97,108,117,101,14,115, + 99,111,101,95,101,97,116,114,101,116,117,114,110,15,115,99,111,101,95,97, + 117,116,111,115,101,108,101,99,116,27,115,99,111,101,95,97,117,116,111,115, + 101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,13,100, + 97,116,97,108,105,115,116,46,100,97,116,97,1,6,0,6,0,6,0,6, + 0,6,0,0,10,118,97,108,117,101,102,97,108,115,101,6,1,48,9,118, + 97,108,117,101,116,114,117,101,6,1,49,0,1,5,119,105,100,116,104,2, + 20,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,120,99,101,110, + 116,101,114,101,100,12,116,102,95,121,99,101,110,116,101,114,101,100,11,116, + 102,95,110,111,115,101,108,101,99,116,0,11,111,112,116,105,111,110,115,101, + 100,105,116,11,14,115,99,111,101,95,117,110,100,111,111,110,101,115,99,26, + 115,99,111,101,95,102,111,114,99,101,114,101,116,117,114,110,99,104,101,99, + 107,118,97,108,117,101,14,115,99,111,101,95,101,97,116,114,101,116,117,114, + 110,15,115,99,111,101,95,97,117,116,111,115,101,108,101,99,116,27,115,99, + 111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116, + 99,108,105,99,107,0,13,100,97,116,97,108,105,115,116,46,100,97,116,97, + 1,6,0,6,0,6,0,6,0,6,0,0,10,118,97,108,117,101,102,97, + 108,115,101,6,1,48,9,118,97,108,117,101,116,114,117,101,6,1,49,0, + 0,13,102,105,120,99,111,108,115,46,99,111,117,110,116,2,1,13,102,105, + 120,99,111,108,115,46,105,116,101,109,115,14,1,5,119,105,100,116,104,2, + 71,15,111,110,97,102,116,101,114,100,114,97,119,99,101,108,108,7,10,100, + 114,97,119,102,105,120,99,111,108,0,0,13,102,105,120,114,111,119,115,46, + 99,111,117,110,116,2,1,13,102,105,120,114,111,119,115,46,105,116,101,109, + 115,14,1,6,104,101,105,103,104,116,2,18,14,99,97,112,116,105,111,110, + 115,46,99,111,117,110,116,2,16,14,99,97,112,116,105,111,110,115,46,105, + 116,101,109,115,14,1,7,99,97,112,116,105,111,110,6,1,48,0,1,7, + 99,97,112,116,105,111,110,6,1,49,0,1,7,99,97,112,116,105,111,110, + 6,1,50,0,1,7,99,97,112,116,105,111,110,6,1,51,0,1,7,99, + 97,112,116,105,111,110,6,1,52,0,1,7,99,97,112,116,105,111,110,6, + 1,53,0,1,7,99,97,112,116,105,111,110,6,1,54,0,1,7,99,97, + 112,116,105,111,110,6,1,55,0,1,7,99,97,112,116,105,111,110,6,1, + 56,0,1,7,99,97,112,116,105,111,110,6,1,57,0,1,7,99,97,112, + 116,105,111,110,6,1,65,0,1,7,99,97,112,116,105,111,110,6,1,66, + 0,1,7,99,97,112,116,105,111,110,6,1,67,0,1,7,99,97,112,116, + 105,111,110,6,1,68,0,1,7,99,97,112,116,105,111,110,6,1,69,0, + 1,7,99,97,112,116,105,111,110,6,1,70,0,0,0,0,8,114,111,119, + 99,111,117,110,116,2,5,13,100,97,116,97,114,111,119,104,101,105,103,104, + 116,2,18,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0, + 0,9,116,108,97,121,111,117,116,101,114,10,116,108,97,121,111,117,116,101, + 114,49,17,102,114,97,109,101,46,102,114,97,109,101,105,95,108,101,102,116, + 2,5,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,114,108,95,102,105,108,101,102,116,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101, + 114,2,1,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,177,1,9,98, + 111,117,110,100,115,95,99,121,2,31,12,111,112,116,105,111,110,115,115,99, + 97,108,101,11,11,111,115,99,95,101,120,112,97,110,100,120,11,111,115,99, + 95,115,104,114,105,110,107,120,11,111,115,99,95,101,120,112,97,110,100,121, + 11,111,115,99,95,115,104,114,105,110,107,121,0,13,111,112,116,105,111,110, + 115,108,97,121,111,117,116,11,10,108,97,111,95,112,108,97,99,101,120,10, + 108,97,111,95,97,108,105,103,110,121,0,13,112,108,97,99,101,95,109,105, + 110,100,105,115,116,2,5,13,112,108,97,99,101,95,109,97,120,100,105,115, + 116,2,5,10,108,105,110,107,98,111,116,116,111,109,7,4,103,114,105,100, + 11,100,105,115,116,95,98,111,116,116,111,109,2,7,0,10,116,105,110,116, + 54,52,101,100,105,116,3,97,100,100,14,111,112,116,105,111,110,115,119,105, + 100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104, + 104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99,97,108,101, + 13,111,119,49,95,97,117,116,111,119,105,100,116,104,0,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,3,65,100,100,16,102,114,97,109,101, + 46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104, + 116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,0,2,25,2,0,0,8,116,97,98,111,114,100,101,114,2,3,8,98, + 111,117,110,100,115,95,120,2,5,8,98,111,117,110,100,115,95,121,2,9, + 9,98,111,117,110,100,115,95,99,120,3,143,0,9,98,111,117,110,100,115, + 95,99,121,2,22,8,115,116,97,116,102,105,108,101,7,22,109,97,105,110, + 102,111,46,112,114,111,106,101,99,116,115,116,97,116,102,105,108,101,11,111, + 112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111, + 110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111, + 101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115, + 104,105,102,116,114,101,116,117,114,110,24,111,101,95,102,111,114,99,101,114, + 101,116,117,114,110,99,104,101,99,107,118,97,108,117,101,12,111,101,95,101, + 97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108, + 101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99, + 117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13, + 111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116, + 111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,22, + 111,101,95,102,111,99,117,115,114,101,99,116,111,110,114,101,97,100,111,110, + 108,121,18,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120, + 116,0,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,5,97,100, + 101,110,116,4,98,97,115,101,7,6,110,98,95,104,101,120,8,118,97,108, + 117,101,109,97,120,2,255,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,16,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,5,109, + 101,109,111,110,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,10, + 77,101,109,111,114,121,32,38,111,110,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101, + 114,102,114,97,109,101,1,2,0,2,2,2,64,2,3,0,8,98,111,117, + 110,100,115,95,120,3,100,1,8,98,111,117,110,100,115,95,121,2,12,9, + 98,111,117,110,100,115,95,99,120,2,77,9,98,111,117,110,100,115,95,99, + 121,2,18,8,115,116,97,116,102,105,108,101,7,22,109,97,105,110,102,111, + 46,112,114,111,106,101,99,116,115,116,97,116,102,105,108,101,13,111,110,100, + 97,116,97,101,110,116,101,114,101,100,7,5,97,100,101,110,116,0,0,9, + 116,101,110,117,109,101,100,105,116,8,98,105,116,119,105,100,116,104,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,5,87,105,100,116,104,16, + 102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112, + 95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99, + 111,108,111,114,4,2,0,0,128,19,102,114,97,109,101,46,98,117,116,116, + 111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117, + 116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4, + 2,0,0,128,0,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,0,2,35,2,0,0,8,116,97,98,111,114,100, + 101,114,2,1,8,98,111,117,110,100,115,95,120,3,8,1,8,98,111,117, + 110,100,115,95,121,2,9,9,98,111,117,110,100,115,95,99,120,2,87,9, + 98,111,117,110,100,115,95,99,121,2,22,8,115,116,97,116,102,105,108,101, + 7,22,109,97,105,110,102,111,46,112,114,111,106,101,99,116,115,116,97,116, + 102,105,108,101,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,120, + 99,101,110,116,101,114,101,100,12,116,102,95,121,99,101,110,116,101,114,101, + 100,11,116,102,95,110,111,115,101,108,101,99,116,0,13,111,110,100,97,116, + 97,101,110,116,101,114,101,100,7,15,117,112,100,97,116,101,108,97,121,111, + 117,116,101,120,101,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46, + 99,111,117,110,116,2,1,19,100,114,111,112,100,111,119,110,46,99,111,108, + 115,46,105,116,101,109,115,14,1,4,100,97,116,97,1,6,1,56,6,2, + 49,54,6,2,51,50,6,2,54,52,0,0,0,5,118,97,108,117,101,2, + 0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,12, + 116,105,110,116,101,103,101,114,101,100,105,116,3,99,110,116,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,3,67,110,116,16,102,114,97,109, + 101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103, + 104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2, + 0,2,0,2,22,2,0,0,8,116,97,98,111,114,100,101,114,2,2,8, + 98,111,117,110,100,115,95,120,3,153,0,8,98,111,117,110,100,115,95,121, + 2,9,9,98,111,117,110,100,115,95,99,120,2,106,9,98,111,117,110,100, + 115,95,99,121,2,22,8,115,116,97,116,102,105,108,101,7,22,109,97,105, + 110,102,111,46,112,114,111,106,101,99,116,115,116,97,116,102,105,108,101,13, + 111,110,100,97,116,97,101,110,116,101,114,101,100,7,5,97,100,101,110,116, + 4,98,97,115,101,7,6,110,98,95,104,101,120,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,16,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tmemoryfo,''); +end. diff --git a/mseide-msegui/apps/ide/menusdesign.pas b/mseide-msegui/apps/ide/menusdesign.pas new file mode 100644 index 0000000..ef72cbc --- /dev/null +++ b/mseide-msegui/apps/ide/menusdesign.pas @@ -0,0 +1,51 @@ +{ MSEide Copyright (c) 2017 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit menusdesign; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +implementation +uses + msemenus,msemenuwidgets,msegui,mclasses,mseclasses,formdesigner, + objectinspector,msearrayutils,msetypes,mseformatstr; + +procedure domenuexe(const sender: tmenuitem); +var + f1: tformdesignerfo; + ar1: msestringarty; + item1: tmenuitem; +begin + f1:= getdesignform(sender.owner); + if f1 <> nil then begin + f1.clearselection(); + f1.selectcomponent(sender.owner); + item1:= sender; + ar1:= nil; //compiler warning + insertitem(ar1,0,'menu'); + while item1.parentmenu <> nil do begin + insertitem(ar1,1,'submenu.count'); + insertitem(ar1,2,'Item '+inttostrmse(item1.index)); + item1:= item1.parentmenu; + end; + if objectinspectorfo.selectprop(ar1,0,true) then begin + objectinspectorfo.asyncactivate(); + end; + end; +end; + +initialization + menuexehandlerdesign:= @domenuexe; +end. diff --git a/mseide-msegui/apps/ide/messageform.mfm b/mseide-msegui/apps/ide/messageform.mfm new file mode 100644 index 0000000..363b6ea --- /dev/null +++ b/mseide-msegui/apps/ide/messageform.mfm @@ -0,0 +1,102 @@ +object messagefo: tmessagefo + optionswidget = [ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets, ow_hinton] + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_floatbutton, go_topbutton, go_backgroundbutton, go_nolockbutton, go_buttonhints] + visible = False + bounds_x = 100 + bounds_y = 100 + bounds_cx = 491 + bounds_cy = 317 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 481 + 317 + ) + dragdock.caption = 'Messages' + dragdock.optionsdock = [od_savepos, od_savezorder, od_canmove, od_canfloat, od_candock, od_propsize, od_captionhint, od_childicons] + options = [fo_savepos, fo_savezorder, fo_savestate] + statfile = mainfo.projectstatfile + icon.image = { + 000000000000000018000000180000001C030000000000000000000000000000 + 00000000000000000000000000000000000000007C7C7C17FFFFFF017C7C7C01 + EAEAEA16FFFFFF017C7C7C01EAEAEA16FFFFFF017C7C7C01EAEAEA16FFFFFF01 + 7C7C7C01EAEAEA16FFFFFF017C7C7C01EAEAEA16FFFFFF017C7C7C01EAEAEA16 + FFFFFF017C7C7C01EAEAEA02E3E3E301AFAFAF01C7C7C701EAEAEA04C9C9C901 + B1B1B101EAEAEA01E0E0E001AFAFAF05B3B3B301EAEAEA03FFFFFF017C7C7C01 + EAEAEA02CCCCCC01000000012C2C2C01EAEAEA043131310106060601EAEAEA01 + C0C0C00102020201323232043C3C3C01EAEAEA03FFFFFF017C7C7C01EAEAEA02 + CCCCCC01060606011E1E1E01C9C9C901EAEAEA02CBCBCB011D1D1D0106060601 + EAEAEA01C0C0C0010C0C0C01EAEAEA08FFFFFF017C7C7C01EAEAEA02CCCCCC01 + 060606016C6C6C017B7B7B01EAEAEA027A7A7A016D6D6D0106060601EAEAEA01 + C0C0C0010C0C0C01EAEAEA08FFFFFF017C7C7C01EAEAEA02CCCCCC0106060601 + BCBCBC012D2D2D01EAEAEA022C2C2C01BDBDBD0106060601EAEAEA01C0C0C001 + 04040401575757048D8D8D01EAEAEA03FFFFFF017C7C7C01EAEAEA02CCCCCC01 + 06060601EAEAEA0121212101CACACA01C3C3C3013C3C3C01D4D4D40106060601 + EAEAEA01C0C0C0010707070192929204B2B2B201EAEAEA03FFFFFF017C7C7C01 + EAEAEA02CCCCCC0106060601EAEAEA01707070017C7C7C01737373018D8D8D01 + D4D4D40106060601EAEAEA01C0C0C0010C0C0C01EAEAEA08FFFFFF017C7C7C01 + EAEAEA02CCCCCC0106060601EAEAEA01BFBFBF013030300128282801DADADA01 + D4D4D40106060601EAEAEA01C0C0C0010C0C0C01EAEAEA08FFFFFF017C7C7C01 + EAEAEA02CCCCCC0106060601EAEAEA022424240147474701EAEAEA01D4D4D401 + 06060601EAEAEA01C0C0C001030303013A3A3A05CCCCCC01EAEAEA02FFFFFF01 + 7C7C7C01EAEAEA02E3E3E301B1B1B101EAEAEA02C5C5C501CECECE01EAEAEA01 + E4E4E401B1B1B101EAEAEA01E0E0E001AFAFAF06E1E1E101EAEAEA02FFFFFF01 + 7C7C7C01EAEAEA16FFFFFF017C7C7C01EAEAEA16FFFFFF017C7C7C01EAEAEA16 + FFFFFF017C7C7C01EAEAEA16FFFFFF017C7C7C01EAEAEA16FFFFFF017C7C7C01 + EAEAEA16FFFFFF017C7C7C01FFFFFF17 + } + moduleclassname = 'tdockform' + object messages: tstringgrid + frame.localprops = [] + frame.localprops1 = [] + popupmenu = tpopupmenu1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 481 + bounds_cy = 317 + anchors = [] + font.name = 'stf_default' + font.options = [foo_antialiased] + font.xscale = 1 + font.localprops = [flp_xscale] + datacols.count = 1 + datacols.linewidth = 0 + datacols.items = < + item + linecolorfix = -1610612733 + width = 3000 + options = [co_readonly, co_drawfocus, co_leftbuttonfocusonly, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_cancopy, co_mousescrollrow] + optionsedit = [] + valuefalse = '0' + valuetrue = '1' + end> + rowcountmax = 5000 + rowcolors.count = 3 + rowcolors.items = ( + -1610612712 + -1610612717 + -1610612716 + ) + datarowlinewidth = 0 + datarowheight = 16 + oncellevent = messagesoncellevent + reffontheight = 14 + end + object tpopupmenu1: tpopupmenu + menu.submenu.count = 1 + menu.submenu.items = < + item + caption = 'Copy to clipboard' + state = [as_localcaption, as_localonexecute] + onexecute = copyexe + end> + left = 88 + top = 72 + end +end diff --git a/mseide-msegui/apps/ide/messageform.pas b/mseide-msegui/apps/ide/messageform.pas new file mode 100644 index 0000000..ea38362 --- /dev/null +++ b/mseide-msegui/apps/ide/messageform.pas @@ -0,0 +1,143 @@ +{ MSEide Copyright (c) 1999-2014 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit messageform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msetypes,msegui,mseclasses,mseforms,msegrids,msemenus,msedataedits, + msesimplewidgets,classes,mclasses,projectoptionsform; + +type + tmessagefo = class(tdockform) + messages: tstringgrid; + tpopupmenu1: tpopupmenu; + procedure messagesoncellevent(const sender: tobject; + var info: celleventinfoty); + procedure copyexe(const sender: TObject); + private + fcolorrow: integer; + public + constructor create(aowner: tcomponent); override; + procedure addtext(const atext: string); + procedure updateprojectoptions; + end; + +var + messagefo: tmessagefo; + +implementation +uses + messageform_mfm,sourcepage,sourceform,msewidgets,msestrings,msedatalist; + +constructor tmessagefo.create(aowner: tcomponent); +begin + fcolorrow:= -1; + inherited create(aowner); +end; + +procedure tmessagefo.messagesoncellevent(const sender: tobject; + var info: celleventinfoty); +var + page: tsourcepage; +begin + if (info.cell.row >= 0) and iscellclick(info,[ccr_dblclick]) then begin + locateerrormessage( + messagefo.messages[0].datalist.getparagraph(info.cell.row),page); + end; +end; + +procedure tmessagefo.copyexe(const sender: TObject); +begin + copytoclipboard(messages.datacols[0].datalist.concatstring('',lineend)); +end; + +procedure tmessagefo.addtext(const atext: string); +var + int1,int2: integer; + lev1: errorlevelty; + col1,row1: integer; + fn1: filenamety; + strcol1: tstringcol; + rowhigh1: integer; + + procedure setrowcolor(const arowcolor: rowstatenumty); + var + int2: integer; + begin + messages.rowcolorstate[int1]:= arowcolor; + for int2:= int1 + 1 to rowhigh1 do begin + if strcol1.noparagraph[int2] then begin + messages.rowcolorstate[int2]:= arowcolor; + end + else begin + break; + end; + end; + end; //setrowcolor + +var + opt1: addcharoptionsty; + +begin + with messages do begin + opt1:= [aco_processeditchars]; + if projectoptions.s.stripmessageesc then begin + include(opt1,aco_stripescsequence); + end; + int1:= datacols[0].readpipe(atext,opt1,120); + rowhigh1:= rowhigh; + int2:= rowhigh1-int1; + if int2 < 0 then begin + int2:= 0; + end; + strcol1:= messages[0]; + with strcol1 do begin + for int1:= rowhigh downto int2 do begin + if not noparagraph[int1] and + checkerrormessage(datalist.getparagraph(int1), + lev1,fn1,col1,row1) then begin + case lev1 of + el_error: begin + setrowcolor(0); + end; + el_warning: begin + setrowcolor(1); + end; + el_note: begin + setrowcolor(2); + end; + end; + end; + end; + end; + showlastrow; + end; +end; + +procedure tmessagefo.updateprojectoptions; +begin + with messages,projectoptions.s do begin + rowcolors[0]:= colorerror; + rowcolors[1]:= colorwarning; + rowcolors[2]:= colornote; + invalidate; + end; +end; + +end. diff --git a/mseide-msegui/apps/ide/messageform_mfm.pas b/mseide-msegui/apps/ide/messageform_mfm.pas new file mode 100644 index 0000000..2ed15d6 --- /dev/null +++ b/mseide-msegui/apps/ide/messageform_mfm.pas @@ -0,0 +1,146 @@ +unit messageform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,messageform; + +const + objdata: record size: integer; data: array[0..2562] of byte end = + (size: 2563; data: ( + 84,80,70,48,10,116,109,101,115,115,97,103,101,102,111,9,109,101,115,115, + 97,103,101,102,111,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114, + 114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102, + 111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111,99,117,115,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,9,111,119, + 95,104,105,110,116,111,110,0,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,15,102,114,97,109,101,46,103,114,105,112,95,115, + 105,122,101,2,10,18,102,114,97,109,101,46,103,114,105,112,95,111,112,116, + 105,111,110,115,11,14,103,111,95,99,108,111,115,101,98,117,116,116,111,110, + 16,103,111,95,102,105,120,115,105,122,101,98,117,116,116,111,110,14,103,111, + 95,102,108,111,97,116,98,117,116,116,111,110,12,103,111,95,116,111,112,98, + 117,116,116,111,110,19,103,111,95,98,97,99,107,103,114,111,117,110,100,98, + 117,116,116,111,110,15,103,111,95,110,111,108,111,99,107,98,117,116,116,111, + 110,14,103,111,95,98,117,116,116,111,110,104,105,110,116,115,0,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,100,8,98,111, + 117,110,100,115,95,121,2,100,9,98,111,117,110,100,115,95,99,120,3,235, + 1,9,98,111,117,110,100,115,95,99,121,3,61,1,23,99,111,110,116,97, + 105,110,101,114,46,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13, + 111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98, + 102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15, + 111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97, + 114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102, + 111,99,117,115,19,111,119,95,109,111,117,115,101,116,114,97,110,115,112,97, + 114,101,110,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,0,26,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,0,27,99,111,110,116,97,105,110, + 101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1, + 2,0,2,0,3,225,1,3,61,1,0,16,100,114,97,103,100,111,99,107, + 46,99,97,112,116,105,111,110,6,8,77,101,115,115,97,103,101,115,20,100, + 114,97,103,100,111,99,107,46,111,112,116,105,111,110,115,100,111,99,107,11, + 10,111,100,95,115,97,118,101,112,111,115,13,111,100,95,115,97,118,101,122, + 111,114,100,101,114,10,111,100,95,99,97,110,109,111,118,101,11,111,100,95, + 99,97,110,102,108,111,97,116,10,111,100,95,99,97,110,100,111,99,107,11, + 111,100,95,112,114,111,112,115,105,122,101,14,111,100,95,99,97,112,116,105, + 111,110,104,105,110,116,13,111,100,95,99,104,105,108,100,105,99,111,110,115, + 0,7,111,112,116,105,111,110,115,11,10,102,111,95,115,97,118,101,112,111, + 115,13,102,111,95,115,97,118,101,122,111,114,100,101,114,12,102,111,95,115, + 97,118,101,115,116,97,116,101,0,8,115,116,97,116,102,105,108,101,7,22, + 109,97,105,110,102,111,46,112,114,111,106,101,99,116,115,116,97,116,102,105, + 108,101,10,105,99,111,110,46,105,109,97,103,101,10,80,3,0,0,0,0, + 0,0,0,0,0,0,24,0,0,0,24,0,0,0,28,3,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,124,124,124,23,255,255,255,1,124,124, + 124,1,234,234,234,22,255,255,255,1,124,124,124,1,234,234,234,22,255,255, + 255,1,124,124,124,1,234,234,234,22,255,255,255,1,124,124,124,1,234,234, + 234,22,255,255,255,1,124,124,124,1,234,234,234,22,255,255,255,1,124,124, + 124,1,234,234,234,22,255,255,255,1,124,124,124,1,234,234,234,2,227,227, + 227,1,175,175,175,1,199,199,199,1,234,234,234,4,201,201,201,1,177,177, + 177,1,234,234,234,1,224,224,224,1,175,175,175,5,179,179,179,1,234,234, + 234,3,255,255,255,1,124,124,124,1,234,234,234,2,204,204,204,1,0,0, + 0,1,44,44,44,1,234,234,234,4,49,49,49,1,6,6,6,1,234,234, + 234,1,192,192,192,1,2,2,2,1,50,50,50,4,60,60,60,1,234,234, + 234,3,255,255,255,1,124,124,124,1,234,234,234,2,204,204,204,1,6,6, + 6,1,30,30,30,1,201,201,201,1,234,234,234,2,203,203,203,1,29,29, + 29,1,6,6,6,1,234,234,234,1,192,192,192,1,12,12,12,1,234,234, + 234,8,255,255,255,1,124,124,124,1,234,234,234,2,204,204,204,1,6,6, + 6,1,108,108,108,1,123,123,123,1,234,234,234,2,122,122,122,1,109,109, + 109,1,6,6,6,1,234,234,234,1,192,192,192,1,12,12,12,1,234,234, + 234,8,255,255,255,1,124,124,124,1,234,234,234,2,204,204,204,1,6,6, + 6,1,188,188,188,1,45,45,45,1,234,234,234,2,44,44,44,1,189,189, + 189,1,6,6,6,1,234,234,234,1,192,192,192,1,4,4,4,1,87,87, + 87,4,141,141,141,1,234,234,234,3,255,255,255,1,124,124,124,1,234,234, + 234,2,204,204,204,1,6,6,6,1,234,234,234,1,33,33,33,1,202,202, + 202,1,195,195,195,1,60,60,60,1,212,212,212,1,6,6,6,1,234,234, + 234,1,192,192,192,1,7,7,7,1,146,146,146,4,178,178,178,1,234,234, + 234,3,255,255,255,1,124,124,124,1,234,234,234,2,204,204,204,1,6,6, + 6,1,234,234,234,1,112,112,112,1,124,124,124,1,115,115,115,1,141,141, + 141,1,212,212,212,1,6,6,6,1,234,234,234,1,192,192,192,1,12,12, + 12,1,234,234,234,8,255,255,255,1,124,124,124,1,234,234,234,2,204,204, + 204,1,6,6,6,1,234,234,234,1,191,191,191,1,48,48,48,1,40,40, + 40,1,218,218,218,1,212,212,212,1,6,6,6,1,234,234,234,1,192,192, + 192,1,12,12,12,1,234,234,234,8,255,255,255,1,124,124,124,1,234,234, + 234,2,204,204,204,1,6,6,6,1,234,234,234,2,36,36,36,1,71,71, + 71,1,234,234,234,1,212,212,212,1,6,6,6,1,234,234,234,1,192,192, + 192,1,3,3,3,1,58,58,58,5,204,204,204,1,234,234,234,2,255,255, + 255,1,124,124,124,1,234,234,234,2,227,227,227,1,177,177,177,1,234,234, + 234,2,197,197,197,1,206,206,206,1,234,234,234,1,228,228,228,1,177,177, + 177,1,234,234,234,1,224,224,224,1,175,175,175,6,225,225,225,1,234,234, + 234,2,255,255,255,1,124,124,124,1,234,234,234,22,255,255,255,1,124,124, + 124,1,234,234,234,22,255,255,255,1,124,124,124,1,234,234,234,22,255,255, + 255,1,124,124,124,1,234,234,234,22,255,255,255,1,124,124,124,1,234,234, + 234,22,255,255,255,1,124,124,124,1,234,234,234,22,255,255,255,1,124,124, + 124,1,255,255,255,23,15,109,111,100,117,108,101,99,108,97,115,115,110,97, + 109,101,6,9,116,100,111,99,107,102,111,114,109,0,11,116,115,116,114,105, + 110,103,103,114,105,100,8,109,101,115,115,97,103,101,115,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,9,112,111,112,117,112, + 109,101,110,117,7,11,116,112,111,112,117,112,109,101,110,117,49,8,98,111, + 117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,120,3,225,1,9,98,111,117,110,100,115,95, + 99,121,3,61,1,7,97,110,99,104,111,114,115,11,0,9,102,111,110,116, + 46,110,97,109,101,6,11,115,116,102,95,100,101,102,97,117,108,116,12,102, + 111,110,116,46,111,112,116,105,111,110,115,11,15,102,111,111,95,97,110,116, + 105,97,108,105,97,115,101,100,0,11,102,111,110,116,46,120,115,99,97,108, + 101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,108,112,95,120,115,99,97,108,101,0,14,100,97,116,97,99,111,108, + 115,46,99,111,117,110,116,2,1,18,100,97,116,97,99,111,108,115,46,108, + 105,110,101,119,105,100,116,104,2,0,14,100,97,116,97,99,111,108,115,46, + 105,116,101,109,115,14,1,12,108,105,110,101,99,111,108,111,114,102,105,120, + 4,3,0,0,160,5,119,105,100,116,104,3,184,11,7,111,112,116,105,111, + 110,115,11,11,99,111,95,114,101,97,100,111,110,108,121,12,99,111,95,100, + 114,97,119,102,111,99,117,115,22,99,111,95,108,101,102,116,98,117,116,116, + 111,110,102,111,99,117,115,111,110,108,121,14,99,111,95,109,111,117,115,101, + 115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14, + 99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111, + 119,115,101,108,101,99,116,10,99,111,95,99,97,110,99,111,112,121,17,99, + 111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,11,111,112, + 116,105,111,110,115,101,100,105,116,11,0,10,118,97,108,117,101,102,97,108, + 115,101,6,1,48,9,118,97,108,117,101,116,114,117,101,6,1,49,0,0, + 11,114,111,119,99,111,117,110,116,109,97,120,3,136,19,15,114,111,119,99, + 111,108,111,114,115,46,99,111,117,110,116,2,3,15,114,111,119,99,111,108, + 111,114,115,46,105,116,101,109,115,1,4,24,0,0,160,4,19,0,0,160, + 4,20,0,0,160,0,16,100,97,116,97,114,111,119,108,105,110,101,119,105, + 100,116,104,2,0,13,100,97,116,97,114,111,119,104,101,105,103,104,116,2, + 16,11,111,110,99,101,108,108,101,118,101,110,116,7,19,109,101,115,115,97, + 103,101,115,111,110,99,101,108,108,101,118,101,110,116,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,14,0,0,10,116,112,111,112,117,112,109, + 101,110,117,11,116,112,111,112,117,112,109,101,110,117,49,18,109,101,110,117, + 46,115,117,98,109,101,110,117,46,99,111,117,110,116,2,1,18,109,101,110, + 117,46,115,117,98,109,101,110,117,46,105,116,101,109,115,14,1,7,99,97, + 112,116,105,111,110,6,17,67,111,112,121,32,116,111,32,99,108,105,112,98, + 111,97,114,100,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120, + 101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7,7,99,111, + 112,121,101,120,101,0,0,4,108,101,102,116,2,88,3,116,111,112,2,72, + 0,0,0) + ); + +initialization + registerobjectdata(@objdata,tmessagefo,''); +end. diff --git a/mseide-msegui/apps/ide/msecodetemplates.pas b/mseide-msegui/apps/ide/msecodetemplates.pas new file mode 100644 index 0000000..1cbd811 --- /dev/null +++ b/mseide-msegui/apps/ide/msecodetemplates.pas @@ -0,0 +1,374 @@ +{ MSEide Copyright (c) 2010 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit msecodetemplates; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +(* +Extension for template files is *.mct +Example of a template file: +" +[header] +name=thename +comment=Comment abcdefg HIKLMNO +params=3 + param1 + param2 + param3 +noselect=1 +cursorcol=12 +cursorrow=1 +[] +The Template Text with macros ${param1} +more text +${param2} ${param3} more params +" +If noselect=0 or not defined the templateblock will be selected in editor. +If noselect=1 the cursor will be placed at the offset by cursorcol, cursorrow. +If indent=1 the inserted block will be indented at cursor column +Minimal template file: +" +[header] +name=thename +[] +" +Parameters can be entered in editor: +" +thename,valueforparam1,valueforparam2 +" +A dialog window will be displayed if there are more params defined than supplied +for param entry or if the template name can not be found. +*) + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + msestrings,msehash,msemacros,msetypes,mseforms; + +type + templateinfoty = record + name: msestring; + path: filenamety; + comment: msestring; + select: boolean; + indent: boolean; + cursorcol: integer; + cursorrow: integer; + params: msestringarty; + paramdefaults: msestringarty; + template: msestring; + cursorpos: gridcoordty; //variable + end; + ptemplateinfoty = ^templateinfoty; + templateinfoarty = array of templateinfoty; + + tcodetemplates = class(tobject) + private + finfos: templateinfoarty; + fmask: filenamety; + flist: tpointermsestringhashdatalist; + protected + function loadfile(const afilename: filenamety; + out ainfo: templateinfoty): boolean; + //true if ok + procedure reload(const selectform: tmseform); //tmsetemplateselectfo + public + constructor create; + destructor destroy; override; + procedure initinfo(out ainfo: templateinfoty); + procedure savefile(const ainfo: templateinfoty); + procedure clear; + procedure scan(const adirectories: filenamearty); + function hastemplate(const aname: msestring): boolean; + function gettemplate(const aname: msestring; out templatetext: msestring; + const amacrolist: tmacrolist = nil): ptemplateinfoty; + property templates: templateinfoarty read finfos; + end; + +implementation +uses + msefileutils,msesys,msestat,msestream,mseparamentryform,mseglob,msearrayutils, + msetemplateselectform,msedataedits; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{ tcodetemplates } + +constructor tcodetemplates.create; +begin + fmask:= '*.mct'; + flist:= tpointermsestringhashdatalist.create; + inherited; +end; + +destructor tcodetemplates.destroy; +begin + clear; + flist.free; + inherited; +end; + +procedure tcodetemplates.clear; +begin + finfos:= nil; + flist.clear; +end; + +function compitems(const l,r): integer; +begin + result:= msecomparetext(templateinfoty(l).name,templateinfoty(r).name); +end; + +procedure tcodetemplates.scan(const adirectories: filenamearty); +var + int1,int2: integer; + ar1: filenamearty; +begin + clear; + ar1:= searchfiles(fmask,adirectories); + int2:= 0; + for int1:= 0 to high(ar1) do begin + if high(finfos) < int2 then begin + setlength(finfos,int2*2+16); + end; + if loadfile(ar1[int1],finfos[int2]) then begin + inc(int2); + end; + end; + setlength(finfos,int2); + sortarray(finfos,sizeof(templateinfoty),@compitems); + for int1:= 0 to high(finfos) do begin + flist.add(finfos[int1].name,pointer(ptruint(int1))); + end; +end; + +procedure tcodetemplates.initinfo(out ainfo: templateinfoty); +begin + finalize(ainfo); + fillchar(ainfo,sizeof(ainfo),0); +end; + +function tcodetemplates.loadfile(const afilename: filenamety; + out ainfo: templateinfoty): boolean; +var + stat: tstatreader; +begin + result:= false; + initinfo(ainfo); + stat:= tstatreader.create(afilename,ce_utf8); + with stat,ainfo do begin + if findsection('header') then begin + name:= readmsestring('name',''); + if name <> '' then begin + path:= afilename; + comment:= readmsestring('comment',''); + select:= readboolean('select',false); + indent:= readboolean('indent',false); + cursorcol:= readinteger('cursorcol',0,0,1000); + cursorrow:= readinteger('cursorrow',0,0,1000000); + params:= readarray('params',msestringarty(nil)); + paramdefaults:= readarray('paramdefaults',msestringarty(nil)); + setlength(paramdefaults,length(params)); + template:= streamtext; + result:= true; + end; + end; + end; + stat.free; +end; + +procedure tcodetemplates.savefile(const ainfo: templateinfoty); +var + stat: tstatwriter; +begin + stat:= tstatwriter.create(ainfo.path,ce_utf8,true); + with stat,ainfo do begin + writesection('header'); + writemsestring('name',name); + writemsestring('comment',comment); + writeboolean('select',select); + writeboolean('indent',indent); + writeinteger('cursorcol',cursorcol); + writeinteger('cursorrow',cursorrow); + writearray('params',params); + writearray('paramdefaults',paramdefaults); + streamtext(template); + end; + stat.free; +end; + +function tcodetemplates.hastemplate(const aname: msestring): boolean; +var + po1: pointer; + ar1: msestringarty; +begin + result:= false; + if aname <> '' then begin + result:= flist.find(aname,po1); + if not result then begin + splitstringquoted(aname,ar1,msechar('"'),msechar(',')); + result:= flist.find(ar1[0],po1); + end; + end; +end; + +function tcodetemplates.gettemplate(const aname: msestring; + out templatetext: msestring; + const amacrolist: tmacrolist = nil): ptemplateinfoty; +var + ar1: msestringarty; + ar2: integerarty; + puint1: ptruint; + mac1: tmacrolist; + fo: tmseparamentryfo; + se: tmsetemplateselectfo; + int1,int2: integer; + bo1: boolean; +begin + result:= nil; + templatetext:= ''; + if aname <> '' then begin + splitstringquoted(aname,ar1,msechar('"'),msechar(',')); + end + else begin + setlength(ar1,1); + end; + if (ar1[0] = '') or not flist.find(ar1[0],pointer(puint1),int1) or + (int1 > 1) then begin + se:= tmsetemplateselectfo.create(self); + try + reload(se); + se.show; + se.grid.setfocus; + se.templatename.editor.filtertext:= ar1[0]; + if (se.show(true) <> mr_ok) or (se.grid.row < 0) or + (se.grid.row > high(finfos)) then begin + exit; + end; + puint1:= se.grid.row; + finally + se.free; + end; + end; + bo1:= true; + mac1:= amacrolist; + if mac1 = nil then begin + mac1:= tmacrolist.create([mao_caseinsensitive,mao_curlybraceonly]); + end; + try + with finfos[puint1] do begin + fo:= tmseparamentryfo.create(nil); + try + fo.caption:= fo.c[ord(codetemplate)]+name+'"'; + fo.comment.caption:= comment; + fo.macroname.gridvalues:= params; + fo.macrovalue.gridvalues:= paramdefaults; + for int1:= 0 to high(params) do begin + if int1 >= high(ar1) then begin + break; + end; + fo.macrovalue[int1]:= ar1[int1+1]; + end; + if high(ar1) <= high(params) then begin + fo.grid.row:= high(ar1); + bo1:= fo.show(true) = mr_ok; + end; + mac1.add(params,fo.macrovalue.gridvalues,[]); + finally + fo.free; + end; + if bo1 then begin + result:= @finfos[puint1]; + cursorpos.col:= cursorcol; + cursorpos.row:= cursorrow; + if (cursorcol > 0) or (cursorrow > 0) then begin + ar1:= breaklines(template); + int2:= 0; + for int1:= 0 to high(ar1) do begin + if int1 >= cursorrow then begin + break; + end; + int2:= int2 + length(ar1[int1]) + length(lineend); + end; + int2:= int2 + cursorcol; + setlength(ar2,1); + ar2[0]:= int2; + templatetext:= concatstrings(ar1,lineend); + mac1.expandmacros1(templatetext,ar2); + ar1:= breaklines(templatetext); + int2:= ar2[0]; + for int1:= 0 to high(ar1) do begin + int2:= int2 - (length(ar1[int1]) + length(lineend)); + if int2 < 0 then begin + cursorpos.row:= int1; + cursorpos.col:= int2 + (length(ar1[int1]) + length(lineend)); + break; + end; + end; + end + else begin + templatetext:= template; + mac1.expandmacros1(templatetext); + end; + end; + end; + finally + if mac1 <> amacrolist then begin + mac1.free; + end; + end; +end; + +procedure tcodetemplates.reload(const selectform: tmseform); +var + se: tmsetemplateselectfo; + int1,int2: integer; + edit1: tstringedit; +begin + se:= selectform as tmsetemplateselectfo; + se.finfos:= finfos; + se.grid.beginupdate; + se.grid.clear; + se.grid.rowcount:= length(finfos)+1; + for int1:= 0 to high(finfos) do begin + with finfos[int1] do begin + se.templatename[int1]:= name; + se.comment[int1]:= comment; + for int2:= 0 to high(params) do begin + edit1:= tstringedit(se.grid.findtagchild(int2+1,tstringedit)); + if edit1 <> nil then begin + edit1[int1]:= params[int2]; + end; + end; + end; + end; + se.grid.endupdate; +end; + +end. diff --git a/mseide-msegui/apps/ide/msecomptree.mfm b/mseide-msegui/apps/ide/msecomptree.mfm new file mode 100644 index 0000000..f2f48e8 --- /dev/null +++ b/mseide-msegui/apps/ide/msecomptree.mfm @@ -0,0 +1,73 @@ +object compnametreefo: tcompnametreefo + visible = False + bounds_x = 80 + bounds_y = 374 + bounds_cx = 300 + bounds_cy = 203 + bounds_cxmin = 200 + container.bounds = ( + 0 + 0 + 300 + 203 + ) + optionswindow = [wo_notaskbar] + options = [fo_screencentered, fo_closeonesc, fo_localshortcuts, fo_autoreadstat, fo_autowritestat, fo_savepos] + statfile = tstatfile1 + caption = 'Select Component' + moduleclassname = 'tmseform' + object grid: twidgetgrid + frame.levelo = 0 + frame.colorframe = -1610612734 + frame.localprops = [frl_levelo, frl_framewidth, frl_colorframe] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 300 + bounds_cy = 203 + anchors = [] + datacols.count = 1 + datacols.items = < + item[treeitem] + width = 299 + options = [co_readonly, co_fill, co_savevalue] + widgetname = 'treeitem' + dataclass = ttreeitemeditlist + datalist.imnr_base = 2 + datalist.imnr_expanded = 1 + datalist.imnr_subitems = -2 + datalist.imagelist = filedialogres.images + datalist.imagewidth = 16 + datalist.imageheight = 16 + datalist.onitemnotification = treeitemonitemnotification + datalist.oncreateitem = treeitemoncreateitem + end> + datarowlinewidth = 0 + datarowheight = 16 + reffontheight = 14 + object treeitem: ttreeitemedit + color = -1879048185 + cursor = cr_arrow + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 299 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_readonly, oe_undoonesc, oe_checkmrcancel, oe_forcereturncheckvalue, oe_locate] + ondataentered = treeitemondataentered + oncellevent = treeitemoncellevent + options = [teo_treecolnavig, teo_enteronimageclick] + reffontheight = 14 + end + end + object tstatfile1: tstatfile + filename = 'compnamedialog.sta' + options = [sfo_memory] + left = 48 + top = 48 + end +end diff --git a/mseide-msegui/apps/ide/msecomptree.pas b/mseide-msegui/apps/ide/msecomptree.pas new file mode 100644 index 0000000..8717662 --- /dev/null +++ b/mseide-msegui/apps/ide/msecomptree.pas @@ -0,0 +1,173 @@ +{ MSEide Copyright (c) 2011 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit msecomptree; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseforms,msewidgetgrid,mselistbrowser,msedatanodes,msetypes,msestrings,msegui, + mseglob,mseclasses,msegrids,msesys,msegridsglob,msestat,msestatfile; + +const + compnamedialogstatname = 'compnamedialog.sta'; + +type + tcompnameitem = class(ttreelistedititem) + public + isvalue: boolean; + end; + + tcompnametreefo = class(tmseform) + grid: twidgetgrid; + treeitem: ttreeitemedit; + tstatfile1: tstatfile; + procedure treeitemoncreateitem(const sender: tcustomitemlist; + var item: ttreelistedititem); virtual; + procedure treeitemonitemnotification(const sender: tlistitem; + var action: nodeactionty); virtual; + procedure treeitemondataentered(const sender: tobject); virtual; + procedure treeitemoncellevent(const sender: tobject; + var info: celleventinfoty); virtual; + private + fselectparent: boolean; + public + end; +{ + tdiredit = class(tstringedit) + private + end; +} +//var +// dirtreefo: tdirtreefo; + +function compnamedialog(const avalues: tcompnameitem; //will be freed + var avalue: msestring; + const selectparent: boolean): modalresultty; + +implementation +uses + msecomptree_mfm,msesysintf,mseeditglob,msefiledialog,msebitmap,mseevent, + mseguiglob; + +function compnamedialog(const avalues: tcompnameitem; var avalue: msestring; + const selectparent: boolean): modalresultty; +var + fo1: tcompnametreefo; + ar1: msestringarty; + item1: ttreelistitem; +begin + fo1:= tcompnametreefo.create(nil); + try + fo1.fselectparent:= selectparent; + ar1:= splitstring(avalue,msechar('.')); + item1:= avalues.finditembycaption(ar1,false,false,true); + if item1 <> nil then begin + item1.expandtoroot(); + item1.expanded:= true; + end; + fo1.treeitem.itemlist.assign(avalues); + if item1 <> nil then begin + fo1.grid.row:= item1.index; + end; + result:= fo1.show(true); + if result = mr_ok then begin + ar1:= tcompnameitem(fo1.treeitem.item).rootcaptions; + avalue:= ar1[0]; + if high(ar1) > 0 then begin + avalue:= ar1[0]+'.'+ar1[1]; + if high(ar1) > 1 then begin + if high(ar1) = 2 then begin + avalue:= avalue+':'+ar1[2]; + end + else begin + avalue:= avalue+':'+concatstrings(copy(ar1,2,bigint),':'); + end; + end; + end; + end; + finally + fo1.free; + end; +end; + +{ tcompnametreefo } + +procedure tcompnametreefo.treeitemoncellevent(const sender: tobject; + var info: celleventinfoty); +begin + case info.eventkind of + cek_enter: begin +// if assigned(fonpathchanged) then begin +// fonpathchanged(self); +// end; + end; + end; + if iscellclick(info) and (info.zone = cz_caption) then begin + treeitem.checkvalue; + end; +end; + +procedure tcompnametreefo.treeitemoncreateitem(const sender: tcustomitemlist; + var item: ttreelistedititem); +begin + item:= tcompnameitem.create(sender); +end; + +procedure tcompnametreefo.treeitemondataentered(const sender: tobject); +begin + if fselectparent or tcompnameitem(treeitem.item).isvalue then begin + window.modalresult:= mr_ok; + end; +end; + +procedure tcompnametreefo.treeitemonitemnotification(const sender: tlistitem; + var action: nodeactionty); +//var +// bo1: boolean; +begin +{ + with tdirlistitem(sender) do begin + case action of + na_expand: begin + include(finfo.state,fis_diropen); + updateinfo; + if (count = 0) or not(dto_checkbox in foptions) then begin + adddir(tdirlistitem(sender)); + end; + if count = 0 then begin + state:= state - [ns_subitems,ns_expanded]; + action:= na_none; + end; + end; + na_collapse: begin + bo1:= count > 0; + if not (dto_checkbox in foptions) then begin + clear; + end; + if bo1 then begin + state:= state + [ns_subitems]; + end; + exclude(finfo.state,fis_diropen); + updateinfo; + end; + end; + end; + } +end; + +end. diff --git a/mseide-msegui/apps/ide/msecomptree_mfm.pas b/mseide-msegui/apps/ide/msecomptree_mfm.pas new file mode 100644 index 0000000..1669ba1 --- /dev/null +++ b/mseide-msegui/apps/ide/msecomptree_mfm.pas @@ -0,0 +1,94 @@ +unit msecomptree_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msecomptree; + +const + objdata: record size: integer; data: array[0..1520] of byte end = + (size: 1521; data: ( + 84,80,70,48,15,116,99,111,109,112,110,97,109,101,116,114,101,101,102,111, + 14,99,111,109,112,110,97,109,101,116,114,101,101,102,111,7,118,105,115,105, + 98,108,101,8,8,98,111,117,110,100,115,95,120,2,80,8,98,111,117,110, + 100,115,95,121,3,118,1,9,98,111,117,110,100,115,95,99,120,3,44,1, + 9,98,111,117,110,100,115,95,99,121,3,203,0,12,98,111,117,110,100,115, + 95,99,120,109,105,110,3,200,0,16,99,111,110,116,97,105,110,101,114,46, + 98,111,117,110,100,115,1,2,0,2,0,3,44,1,3,203,0,0,13,111, + 112,116,105,111,110,115,119,105,110,100,111,119,11,12,119,111,95,110,111,116, + 97,115,107,98,97,114,0,7,111,112,116,105,111,110,115,11,17,102,111,95, + 115,99,114,101,101,110,99,101,110,116,101,114,101,100,13,102,111,95,99,108, + 111,115,101,111,110,101,115,99,17,102,111,95,108,111,99,97,108,115,104,111, + 114,116,99,117,116,115,15,102,111,95,97,117,116,111,114,101,97,100,115,116, + 97,116,16,102,111,95,97,117,116,111,119,114,105,116,101,115,116,97,116,10, + 102,111,95,115,97,118,101,112,111,115,0,8,115,116,97,116,102,105,108,101, + 7,10,116,115,116,97,116,102,105,108,101,49,7,99,97,112,116,105,111,110, + 6,16,83,101,108,101,99,116,32,67,111,109,112,111,110,101,110,116,15,109, + 111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,8,116,109,115,101, + 102,111,114,109,0,11,116,119,105,100,103,101,116,103,114,105,100,4,103,114, + 105,100,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,16,102,114, + 97,109,101,46,99,111,108,111,114,102,114,97,109,101,4,2,0,0,160,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,14,102,114,108,95,102,114,97,109,101,119,105, + 100,116,104,14,102,114,108,95,99,111,108,111,114,102,114,97,109,101,0,8, + 98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,3,44,1,9,98,111,117,110,100, + 115,95,99,121,3,203,0,7,97,110,99,104,111,114,115,11,0,14,100,97, + 116,97,99,111,108,115,46,99,111,117,110,116,2,1,14,100,97,116,97,99, + 111,108,115,46,105,116,101,109,115,14,7,8,116,114,101,101,105,116,101,109, + 1,5,119,105,100,116,104,3,43,1,7,111,112,116,105,111,110,115,11,11, + 99,111,95,114,101,97,100,111,110,108,121,7,99,111,95,102,105,108,108,12, + 99,111,95,115,97,118,101,118,97,108,117,101,0,10,119,105,100,103,101,116, + 110,97,109,101,6,8,116,114,101,101,105,116,101,109,9,100,97,116,97,99, + 108,97,115,115,7,17,116,116,114,101,101,105,116,101,109,101,100,105,116,108, + 105,115,116,18,100,97,116,97,108,105,115,116,46,105,109,110,114,95,98,97, + 115,101,2,2,22,100,97,116,97,108,105,115,116,46,105,109,110,114,95,101, + 120,112,97,110,100,101,100,2,1,22,100,97,116,97,108,105,115,116,46,105, + 109,110,114,95,115,117,98,105,116,101,109,115,2,254,18,100,97,116,97,108, + 105,115,116,46,105,109,97,103,101,108,105,115,116,7,20,102,105,108,101,100, + 105,97,108,111,103,114,101,115,46,105,109,97,103,101,115,19,100,97,116,97, + 108,105,115,116,46,105,109,97,103,101,119,105,100,116,104,2,16,20,100,97, + 116,97,108,105,115,116,46,105,109,97,103,101,104,101,105,103,104,116,2,16, + 27,100,97,116,97,108,105,115,116,46,111,110,105,116,101,109,110,111,116,105, + 102,105,99,97,116,105,111,110,7,26,116,114,101,101,105,116,101,109,111,110, + 105,116,101,109,110,111,116,105,102,105,99,97,116,105,111,110,21,100,97,116, + 97,108,105,115,116,46,111,110,99,114,101,97,116,101,105,116,101,109,7,20, + 116,114,101,101,105,116,101,109,111,110,99,114,101,97,116,101,105,116,101,109, + 0,0,16,100,97,116,97,114,111,119,108,105,110,101,119,105,100,116,104,2, + 0,13,100,97,116,97,114,111,119,104,101,105,103,104,116,2,16,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,13,116,116,114,101,101, + 105,116,101,109,101,100,105,116,8,116,114,101,101,105,116,101,109,5,99,111, + 108,111,114,4,7,0,0,144,6,99,117,114,115,111,114,7,8,99,114,95, + 97,114,114,111,119,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0, + 17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,2, + 0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108, + 111,114,99,108,105,101,110,116,0,8,116,97,98,111,114,100,101,114,2,1, + 7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,3,43,1,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116, + 105,111,110,115,101,100,105,116,49,11,13,111,101,49,95,115,97,118,101,118, + 97,108,117,101,0,11,111,112,116,105,111,110,115,101,100,105,116,11,11,111, + 101,95,114,101,97,100,111,110,108,121,12,111,101,95,117,110,100,111,111,110, + 101,115,99,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108, + 24,111,101,95,102,111,114,99,101,114,101,116,117,114,110,99,104,101,99,107, + 118,97,108,117,101,9,111,101,95,108,111,99,97,116,101,0,13,111,110,100, + 97,116,97,101,110,116,101,114,101,100,7,21,116,114,101,101,105,116,101,109, + 111,110,100,97,116,97,101,110,116,101,114,101,100,11,111,110,99,101,108,108, + 101,118,101,110,116,7,19,116,114,101,101,105,116,101,109,111,110,99,101,108, + 108,101,118,101,110,116,7,111,112,116,105,111,110,115,11,16,116,101,111,95, + 116,114,101,101,99,111,108,110,97,118,105,103,21,116,101,111,95,101,110,116, + 101,114,111,110,105,109,97,103,101,99,108,105,99,107,0,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,0,9,116,115,116,97,116, + 102,105,108,101,10,116,115,116,97,116,102,105,108,101,49,8,102,105,108,101, + 110,97,109,101,6,18,99,111,109,112,110,97,109,101,100,105,97,108,111,103, + 46,115,116,97,7,111,112,116,105,111,110,115,11,10,115,102,111,95,109,101, + 109,111,114,121,0,4,108,101,102,116,2,48,3,116,111,112,2,48,0,0, + 0) + ); + +initialization + registerobjectdata(@objdata,tcompnametreefo,''); +end. diff --git a/mseide-msegui/apps/ide/msedesigner.pas b/mseide-msegui/apps/ide/msedesigner.pas new file mode 100644 index 0000000..602d360 --- /dev/null +++ b/mseide-msegui/apps/ide/msedesigner.pas @@ -0,0 +1,6037 @@ +{ MSEide Copyright (c) 1999-2017 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit msedesigner; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses,msegraphutils,mseglob,mseguiglob,msedesignintf, + mseforms,mselist,msearrayutils,msebitmap,msetypes,sysutils,msehash,mseclasses, + mseformdatatools,typinfo,msepropertyeditors,msecomponenteditors,msegraphics, + mseapplication,msegui,msestrings,msedesignparser,msecomptree,mseevent, + mseinterfaces,msedock; + +{$ifndef mse_methodswap} + {$define mse_nomethodswap} +{$endif} + +const + formfileext = 'mfm'; + pasfileext = 'pas'; + backupext = '.bak'; + subcomponentsplitchar = ':'; + +type + tdesigner = class; + + moduleoptionty = (mo_hidewidgets,mo_hidecomp); + moduleoptionsty = set of moduleoptionty; + + iformdesigner = interface(inullinterface)[miid_iformdesigner] + function clickedcomponent: tcomponent; + function getmoduleoptions: moduleoptionsty; + procedure setmoduleoptions(const aoptions: moduleoptionsty); + property moduleoptions: moduleoptionsty read getmoduleoptions + write setmoduleoptions; + procedure updatecaption(); + procedure findcompdialog(); + function getmodulepos_x(): integer; + function getmodulepos_y(): integer; + procedure setmodulepos_x(const avalue: integer); + procedure setmodulepos_y(const avalue: integer); + function getdockcontroller(): tdockcontroller; + end; + + methodinfoty = record + name: string; + address: pointer; + typeinfo: ptypeinfo; + end; + pmethodinfoty = ^methodinfoty; + tmethods = class; + methodsarty = array of tmethods; + + methodsdataty = record + key: ptruint; + data: methodinfoty; + end; + pmethodsdataty = ^methodsdataty; + methodshashdataty = record + header: hashheaderty; + data: methodsdataty; + end; + pmethodshashdataty = ^methodshashdataty; + + tmethods = class(tptruinthashdatalist) + private + fdesigner: tdesigner; + {fapropname,fapropvalue: string;} +{$ifndef mse_nomethodswap} + fmethodtable: pointer; +{$endif} + protected + procedure finalizeitem(const aitem: phashdataty); override; + procedure deletemethod(const aadress: pointer); + procedure addmethod(const aname: string; const aaddress: pointer; + const atypeinfo: ptypeinfo); + function getrecordsize(): int32 override; + public + constructor create(adesigner: tdesigner); + destructor destroy; override; + function findmethod(const aadress: pointer): pmethodinfoty; + function findmethodbyname(const aname: string; const atype: ptypeinfo; + out namefound: boolean): pmethodinfoty; overload; + function findmethodbyname(const aname: string): pmethodinfoty; overload; +{$ifndef mse_nomethodswap} + function createmethodtable(const ancestors: methodsarty): pointer; + procedure releasemethodtable; +{$endif} + end; + + tmethodnames = class(tansistringptruinthashdatalist) + public + end; + + tcomponents = class; + + tcomponentslink = class(tcomponent) + private + fownercomps: tcomponents; + protected + procedure notification(acomponent: tcomponent; operation: toperation); override; + end; + + componentnamety = record + instance: tcomponent; + dispname: string; + end; + componentnamearty = array of componentnamety; + + moduleinfoty = record + filename: msestring; + filetag: longword; + filechanged: boolean; + savetime: tdatetime; + moduleclassname: string[80]; //can not be ansistring! + instancevarname: string; + instance: tmsecomponent; + moduleintf: pdesignmoduleintfty; + designformclass: pointer; + methods: tmethods; + {$ifndef mse_nomethodswap} + methodtableswapped: integer; + methodtablebefore: pointer; + {$endif} + backupcreated: boolean; + modified: boolean; + readermodified: boolean; + resolved: boolean; + hasmenuitem: boolean; + components: tcomponents; + designform: tcustommseform; + designformintf: iformdesigner; + referencedmodules: stringarty; + loadingstream: tstream; + end; + pmoduleinfoty = ^moduleinfoty; + moduleinfopoarty = array of pmoduleinfoty; + + componentsdataty = record + key: ptruint; + data: componentinfoty; + end; + pcomponentsdataty = ^componentsdataty; + componentshashdataty = record + header: hashheaderty; + data: componentsdataty; + end; + pcomponentshashdataty = ^componentshashdataty; + + tcomponents = class(tptruinthashdatalist) + private + fdesigner: tdesigner; + fcomponent: tcomponentslink; // to receive componentnotifications + fowner: pmoduleinfoty; + protected + procedure finalizeitem(const aitem: phashdataty); override; + function find(const value: tobject): pcomponentshashdataty; + procedure destroynotification(const acomponent: tcomponent); + procedure swapcomponent(const old,new: tcomponent); + function getrecordsize(): int32 override; + public + constructor create(const aowner: pmoduleinfoty; const adesigner: tdesigner); + destructor destroy; override; + procedure assigncomps(const module: tmsecomponent); + procedure add(comp: tcomponent); + function next: pcomponentshashdataty; + function getcomponents: componentarty; + function getdispnames: componentnamearty; + function getcomponent(const aname: string; + const children: boolean = false): tcomponent; + procedure namechanged(const acomponent: tcomponent; const newname: string); + end; + + tmoduleinfo = class(tlinkedobject) + protected + fdesigner: tdesigner; + public + info: moduleinfoty; + constructor create(adesigner: tdesigner); + destructor destroy; override; + end; + + pmoduleinfo = ^tmoduleinfo; + + tmodulelist = class(tlinkedobjectqueue) + private + fdesigner: tdesigner; + fmethodnames: tmethodnames; + function getitempo1(const index: integer): pmoduleinfoty; + protected + function newmodule(const ainherited: boolean; const afilename: msestring; + const amoduleclassname,ainstancevarname, + designmoduleclassname: string): tmoduleinfo; + function findmethodbyname(const name: string; const atype: ptypeinfo; + const amodule: tmsecomponent): tmethod; + function findmethodname(const method: tmethod; const comp: tcomponent): string; + function findform(aform: tcustommseform): pmoduleinfoty; + function removemoduleinfo(po: pmoduleinfoty): integer; + procedure componentmodified(const acomponent: tobject); + procedure freeloadingstreams; + + public + constructor create(adesigner: tdesigner); reintroduce; + destructor destroy; override; + procedure designformdestroyed(const sender: tcustommseform); + function delete(index: integer): pointer; override; + function findmodule(const filename: msestring): pmoduleinfoty; overload; + function findmodule(const amodule: tmsecomponent): pmoduleinfoty; overload; + function findmodule(const po: pmoduleinfoty): integer; overload; + function findmodulebyname(const name: string): pmoduleinfoty; + function findmoduleinstancebyname(const name: string): tcomponent; + function findmoduleinstancebyclass(const aclass: tclass): tcomponent; + function findmodulebyclassname(aclassname: string): pmoduleinfoty; + function findmodulebycomponent(const acomponent: tcomponent): pmoduleinfoty; + function findmodulebyinstance(const ainstance: tcomponent): pmoduleinfoty; + function findownermodule(const acomponent: tcomponent): pmoduleinfoty; + function filenames: filenamearty; + + property itempo[const index: integer]: pmoduleinfoty read getitempo1; default; + end; + + tdesignformlist = class(tcomponentqueue) + private + function getitems(const index: integer): tmseform;//tformdesignerfo; + public + property items[const index: integer]: tmseform read getitems; default; + end; + + ancestorinfoty = record + descendent,ancestor: tmsecomponent + end; + pancestorinfoty = ^ancestorinfoty; + ancestorinfoarty = array of ancestorinfoty; + ancestorinfoaty = array[0..0] of ancestorinfoty; + pancestorinfoaty = ^ancestorinfoaty; + + ancestornameinfoty = record + desc,anc: string; + end; + ancestornameinfoarty = array of ancestornameinfoty; + + tancestorlist = class(tobjectlinkrecordlist) + private + fstreaming: integer; +{$ifndef mse_nomethodswap} + fswappedancestors: componentarty; +{$endif} + protected + procedure dounlink(var item); override; + procedure doitemdestroyed(const sender: tmsecomponent); virtual; + procedure itemdestroyed(const sender: iobjectlink); override; + function getdescendentar(const aancestor: tmsecomponent): msecomponentarty; +{$ifndef mse_nomethodswap} + procedure streamingswapmethodpointer(const acomp: tcomponent); +{$endif} + public + constructor create; + function findancestor(const adescendent: tcomponent): tmsecomponent; + function finddescendent(const aancestor: tcomponent): tmsecomponent; + function finddescendentinfo(const adescendent: tcomponent): pancestorinfoty; + function findancestorinfo(const aancestor: tcomponent): pancestorinfoty; + function findinfo(const ainfo: ancestornameinfoty): pancestorinfoty; + procedure getinfo(const apo: pancestorinfoty; out info: ancestornameinfoty); + procedure add(const adescendent,aancestor: tmsecomponent); + procedure beginstreaming; + procedure endstreaming; + end; + + tdesignerancestorlist = class(tancestorlist) + private + fdesigner: tdesigner; + public + constructor create(aowner: tdesigner); + end; + + tsubmodulelist = class(tdesignerancestorlist,ievent) + //ancestor is copy of old state of descendent, + //descendent is real submodule + protected + frenewbackuplist: msecomponentarty; + procedure finalizerecord(var item); override; + procedure dorenewbackup; + procedure receiveevent(const event: tobjectevent); + procedure doitemdestroyed(const sender: tmsecomponent); override; + public + procedure add(const amodule: tmsecomponent); overload; + procedure renewbackup(const amodule: tmsecomponent); + function findoldancestor(const adescendent: tmsecomponent): tmsecomponent; + end; + + treaderrorhandler = class(tcomponent) + private + fcomponentar: componentarty; + fnewcomponents: componentarty; + froot: tcomponent; + procedure doraise(const acomponent: tcomponent); + procedure ancestornotfound(Reader: TReader; const ComponentName: string; + ComponentClass: TPersistentClass; var Component: TComponent); + procedure onsetname(reader: treader; component: tcomponent; var aname: string); + procedure onerror(reader: treader; const message: string; var handled: boolean); + protected + procedure notification(acomponent: tcomponent; operation: toperation); + override; + public + destructor destroy; override; + end; + + tdescendentinstancelist = class(tdesignerancestorlist) + private + fdelcomps:componentarty; + froot: tcomponent; + fmodule: pmoduleinfoty; + fmodulemodifying: boolean; + fmodifiedmodules: moduleinfopoarty; + frefreshmethods: methodsarty; + fcomponentnamechanging: boolean; + fdeletedcomps: componentarty; + procedure delcomp(child: tcomponent); + procedure addcomp(child: tcomponent); + procedure domodulemodified(const amodule: pmoduleinfoty; + modifylevel: integer; destcompnames,ancestorcompnames: stringarty; + newancestorcomps,oldancestorcomps: msecomponentarty); + {$ifdef mse_nomethodswap} + procedure setrefreshmethod(reader: treader; instance: tpersistent; + propinfo: ppropinfo; const themethodname: string; + var handled: boolean); + {$else} + procedure findrefreshmethod(reader: treader; const amethodname: string; + var address: pointer; var error: boolean); + {$endif} + procedure modulemodified(const amodule: pmoduleinfoty); + procedure componentnamechanged(const amodule: pmoduleinfoty; + const acomponent: tcomponent; const newname: string); + procedure setnodefaultpos(const aroot: twidget); + procedure restorepos(const aroot: twidget); + public + procedure beginstreaming(const amodule: pmoduleinfoty); + procedure add(const instance,ancestor: tmsecomponent; + const submodulelist: tsubmodulelist); overload; + function getclassname(const comp: tcomponent): string; + //returns submodule or root classname if appropriate + function getancestors(const adescendent: tcomponent): componentarty; + function getancestorsandchildren(const adescendent: tcomponent): componentarty; + function getdescendents(const aancestor: tcomponent): componentarty; + end; + + getmoduleeventty = procedure(const amodule: pmoduleinfoty; + const aname: string; var action: modalresultty) of object; + //mr_ignore,mr_ok, cancel otherwise + getmoduletypeeventty = procedure(const atypename: string) of object; + propprocty = procedure(const ainstance: tobject; const data: pointer; + const apropinfo: ppropinfo); + + forallmethpropinfoty = record + root: tcomponent; + dat: pointer; + proc: propprocty; + dochi: boolean; + end; + + designerstatety = (des_pasting,des_inheritednewmodule,des_skipall); + designerstatesty = set of designerstatety; + + tdesigner = class(tactcomponent,idesigner) + private + fselections: tdesignerselections; + factmodulepo: pmoduleinfoty; + floadingmodulepo: pmoduleinfoty; + flastmethodmodulepo: pmoduleinfoty; + fmodules: tmodulelist; + fcomponenteditor: tcomponenteditor; + fobjformat: objformatty; + fsubmoduleinfopo: pmoduleinfoty; + fsubmodulelist: tsubmodulelist; + fdescendentinstancelist: tdescendentinstancelist; + fdesignfiles: tindexedfilenamelist; + fongetmodulenamefile: getmoduleeventty; + fongetmoduletypefile: getmoduletypeeventty; + fnotifymodule: tmsecomponent; + fcomponentmodifying: integer; + floadedsubmodules: componentarty; + fformloadlevel: integer; + fformloadlocklevel: integer; + fnotifydeletedlock: integer; + fallsaved: boolean; + fcreatecomponenttag: integer; //incremented by createcoponent + ffindcompclasstag: integer; //stamp of createcomponenttag + fcheckfixups: moduleinfopoarty; + fskipall: integer; + fstreaming: integer; + function formfiletoname(const filename: msestring): msestring; + {$ifdef mse_nomethodswap} + procedure setmethodproperty(reader: treader; + instance: tpersistent; + propinfo: ppropinfo; const themethodname: string; + var handled: boolean); + {$else} + procedure findmethod(Reader: TReader; const aMethodName: string; + var Address: Pointer; var Error: Boolean); + {$endif} + function getinheritedmodule(const aclassname: string): pmoduleinfoty; + function findcomponentmodule(const acomponent: tcomponent): pmoduleinfoty; + procedure selectionchanged; +{$ifndef mse_nomethodswap} + procedure docopymethods(const source, dest: tcomponent; const force: boolean); +{$endif} + procedure writemodule(const amodule: pmoduleinfoty; const astream: tstream); + procedure notifydeleted(comp: tcomponent); + procedure componentdestroyed(const acomponent: tcomponent; const module: pmoduleinfoty); + procedure dofixup; + {$ifndef mse_nomethodswap} + procedure buildmethodtable(const amodule: pmoduleinfoty); + procedure releasemethodtable(const amodule: pmoduleinfoty); + {$endif} + protected + fstate: designerstatesty; +// procedure doasyncevent(var atag: integer); override; + procedure readererror(reader: treader; const message: string; + var handled: boolean); + procedure readerenumerror(const reader: treader; const atype: ptypeinfo; + const aitemname: string; var avalue: longword); + procedure readerseterror(const reader: treader; const atype: ptypeinfo; + const aitemname: string; var avalue: integer); + procedure forallmethodproperties(const aroot: tcomponent; + const ainstance: tobject; const data: pointer; + const aproc: propprocty; + const dochildren: boolean); + procedure componentevent(const event: tcomponentevent); override; + function checkmodule(const filename: msestring): pmoduleinfoty; + procedure checkident(const aname: string); + procedure beginstreaming({const amodule: pmoduleinfoty}); + procedure endstreaming({const amodule: pmoduleinfoty}); + {$ifndef mse_nomethodswap} + procedure internaldoswapmethodpointers(const aroot: tcomponent; + const ainstance: tobject; const ainit: boolean); + {$endif} + procedure dotouch(const amodule: pmoduleinfoty); + procedure handledesignexception(const sender: tobject); + public + constructor create; reintroduce; + destructor destroy; override; + + procedure begincomponentmodify; + procedure endcomponentmodify; + procedure beginpasting; + procedure endpasting; + + function beforemake: boolean; //true if ok + procedure modulechanged(const amodule: pmoduleinfoty); + procedure touch(const amodule: tmsecomponent); + procedure touchall; + function changemodulename(const filename: msestring; const avalue: string): string; + function changemoduleclassname(const filename: msestring; const avalue: string): string; + function changeinstancevarname(const filename: msestring; const avalue: string): string; + function checksubmodule(const ainstance: tcomponent; + out aancestormodule: pmoduleinfoty): boolean; + function getreferencingmodulenames(const amodule: pmoduleinfoty): stringarty; + function checkmethodtypes(const amodule: pmoduleinfoty; + const init: boolean): boolean; + //false on cancel +{$ifndef mse_nomethodswap} + procedure doswapmethodpointers(const ainstance: tobject; const ainit: boolean); +{$endif} +{$ifdef mse_nomethodswap} + procedure writedesignmethod(writer: twriter; instance: tpersistent; + propinfo: ppropinfo; + const methodvalue, defmethodvalue: tmethod; + var handled: boolean); +{$endif} + procedure ancestornotfound(Reader: TReader; const ComponentName: string; + ComponentClass: TPersistentClass; var Component: TComponent); + procedure findcomponentclass(Reader: TReader; const aClassName: string; + var ComponentClass: TComponentClass); + procedure findancestor(Writer: TWriter; Component: TComponent; + const aName: string; var Ancestor, RootAncestor: TComponent); + function findancestorcomponent(const acomponent: tcomponent): tcomponent; + function getancestormethods(const amodule: pmoduleinfoty): methodsarty; + procedure createcomponent1(reader: treader; componentclass: tcomponentclass; + var component: tcomponent); + function createcomponent: tcreatecomponentevent; + function selectedcomponents: componentarty; + + //idesigner + procedure componentmodified(const component: tobject; + const apropname: string = ''; const apropindex: int32 = -1); + procedure selectcomponent(instance: tcomponent); + procedure setselections(const list: idesignerselections); + function createnewcomponent(const module: tmsecomponent; + const aclass: tcomponentclass): tcomponent; + function createcurrentcomponent(const module: tmsecomponent): tcomponent; + function hascurrentcomponent: boolean; + procedure addcomponent(const module: tmsecomponent; + const acomponent: tcomponent); + procedure deleteselection(adoall: boolean = false); + procedure deletecomponent(const acomponent: tcomponent); + procedure clearselection; + procedure noselection; + + function getmethod(const aname: string; const methodowner: tmsecomponent; + const atype: ptypeinfo; const searchancestors: boolean): tmethod; + function getmethodname(const method: tmethod; const comp: tcomponent): string; + procedure changemethodname(const method: tmethod; newname: string; + const atypeinfo: ptypeinfo); + function createmethod(const aname: string; const module: tmsecomponent; + const atype: ptypeinfo): tmethod; + procedure checkmethod(const method: tmethod; const aname: string; + const module: tmsecomponent; const atype: ptypeinfo); + + function getcomponentname(const comp: tcomponent): string; + //returns qualified name for foreign modules + function getcomponentdispname(const comp: tcomponent): string; + //returns qualified name into root + procedure validaterename(const acomponent: tcomponent; + const curname, newname: string); reintroduce; + function getclassname(const comp: tcomponent): string; + //returns submoduleclassname if appropriate + function getcomponent(const aname: string; + const aroot: tcomponent): tcomponent; + //handles qualified names for foreign forms + function getcomponent(const apath: string; + out amodule: pmoduleinfoty): tcomponent; + function componentcanedit: boolean; + function getcomponenteditor: icomponenteditor; + function editcomponent(const aowner: tcomponent = nil): boolean; //false if no editor available + function getcomponentlist(const acomponentclass: tcomponentclass; + const filter: compfilterfuncty = nil; + const allmodules: boolean = false): componentarty; + function getcomponentnamelist(const acomponents: componentarty; + const amodule: tmsecomponent): msestringarty; overload; + //nil values ignored + function getcomponentnamelist(const acomponentclass: tcomponentclass; + const includeinherited: boolean; + const aowner: tcomponent = nil; + const filter: compfilterfuncty = nil): msestringarty; overload; + function getcomponentnamelist(const acomponentclass: tcomponentclass; + const arootcomp: tcomponent; + const filter: compfilterfuncty = nil): msestringarty; overload; + function getcomponentnametree(const acomponentclass: tcomponentclass; + const includeinherited: boolean; + const findmode: boolean; + const aowner: tcomponent = nil; + const filter: compfilterfuncty = nil; + const amodule: tcomponent = nil): tcompnameitem; + function getwidgetnamelist(const awidgetclass: widgetclassty; + const arootwidget: twidget; + const filter: compfilterfuncty = nil): msestringarty; + function getwidgetnametree(const rootwidget: twidget): tcompnameitem; + + function getancestorclassinfo(const ainstance: tcomponent; + const interfaceonly: boolean): classinfopoarty; + overload; + function getancestorclassinfo(const ainstance: tcomponent; + const interfaceonly: boolean; + out aunits: unitinfopoarty): classinfopoarty; + overload; + + function getmodulex(const amodule: tmsecomponent): integer; + procedure setmodulex(const amodule: tmsecomponent; avalue: integer); + function getmoduley(const amodule: tmsecomponent): integer; + procedure setmoduley(const amodule: tmsecomponent; avalue: integer); + procedure modulesizechanged(const amodule: tmsecomponent); + + function isownedmethod(const root: tcomponent; + const method: tmethod): boolean; + procedure getmethodinfo(const method: tmethod; out moduleinfo: pmoduleinfoty; + out methodinfo: pmethodinfoty); + function getmodules: tmodulelist; + + procedure beginskipall; + procedure endskipall; + function loadformfile(filename: msestring; + const skipexisting: boolean): pmoduleinfoty; + function saveformfile(const modulepo: pmoduleinfoty; + const afilename: msestring; createdatafile: boolean): boolean; + //false if canceled + procedure refreshdatafile(const amodule: pmoduleinfoty); + function saveall(noconfirm,createdatafile: boolean): modalresultty; + procedure savecanceled; //resets fallsaved + procedure setactivemodule(const adesignform: tcustommseform); + function sourcenametoformname(const aname: filenamety): filenamety; + + function closemodule(const amodule: pmoduleinfoty; + const checksave: boolean): boolean; //true if closed + procedure showformdesigner(const amodule: pmoduleinfoty); + procedure showastext(const amodule: pmoduleinfoty); + procedure showobjectinspector; + function actmodulepo: pmoduleinfoty; + function modified: boolean; + function clickedcomp: tcomponent; + procedure moduledestroyed(const amodule: pmoduleinfoty); + procedure addancestorinfo(const ainstance,aancestor: tmsecomponent); + function copycomponent(const source: tmsecomponent; + const root: tmsecomponent; const asinherited: boolean; + const noloading: boolean):tmsecomponent; + procedure revert(const acomponent: tcomponent); + function checkcanclose(const amodule: pmoduleinfoty; out references: string): boolean; + + property modules: tmodulelist read getmodules; + property descendentinstancelist: tdescendentinstancelist read + fdescendentinstancelist; + property selections: tdesignerselections read fselections; + //do not modify! + + property objformat: objformatty read fobjformat write fobjformat default of_default; + property designfiles: tindexedfilenamelist read fdesignfiles; + + property ongetmodulenamefile: getmoduleeventty read fongetmodulenamefile + write fongetmodulenamefile; + property ongetmoduletypefile: getmoduletypeeventty read fongetmoduletypefile + write fongetmoduletypefile; + end; + +procedure createbackupfile(const newname,origname: filenamety; + var backupcreated: boolean; const backupcount: integer); + +function designer: tdesigner; +function isdatasubmodule(const acomponent: tobject; + const iconified: boolean = false; + const both: boolean = false): boolean; + +implementation +uses + msestream,msefileutils, +// {$ifdef mswindows}windows{$else}mselibc{$endif}, + designer_bmp,msesys,msewidgets,formdesigner,objectinspector,mseformatstr, + msefiledialog,projectoptionsform,sourceupdate,sourceform,sourcepage, + pascaldesignparser,msearrayprops,rtlconsts,msedatamodules, + msesimplewidgets,msesysutils,mseobjecttext,msestreaming,msedatanodes,main, + actionsmodule,mseeditglob; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + renewbackuptag = 0; + +type + tcomponent1 = class(tcomponent); + tmsecomponent1 = class(tmsecomponent); + twidget1 = class(twidget); + twriter1 = class(twriter); + treader1 = class(treader); +{$ifdef mse_nomethodswap} + tbinaryobjectwriter1 = class(tbinaryobjectwriter); +{$endif} + moduleeventty = (me_none,me_componentmodified); + +var + fdesigner: tdesigner; + loadingdesigner: tdesigner; + methodaddressdummy: ptruint; + submodulecopy: integer; + +function designer: tdesigner; +begin + result:= fdesigner; +end; + +function isnosubcomp(const acomp: tcomponent): boolean; +begin + result:= (cssubcomponent in acomp.componentstyle) and + (acomp is tmsecomponent) and + not(cs_subcompref in tmsecomponent1(acomp).fmsecomponentstate); +end; + +function isdatasubmodule(const acomponent: tobject; + const iconified: boolean = false; + const both: boolean = false): boolean; +begin + result:= (acomponent <> nil) and (acomponent is tmsedatamodule) and + (csinline in tmsedatamodule(acomponent).componentstate) and + (both or + (iconified = (dmo_iconic in tmsedatamodule(acomponent).options))); +end; + +function issubprop(const obj1: tobject): boolean; +begin + result:= (obj1 <> nil) and (not (obj1 is tcomponent) or + (cssubcomponent in tcomponent(obj1).componentstyle) and + ((tcomponent(obj1).owner = nil) or + (obj1 is tmsecomponent) and + not(cs_subcompref in tmsecomponent1(obj1).fmsecomponentstate))); +end; + +function ismodule(const acomponent: tcomponent): boolean; +begin + result:= (acomponent = nil) or (acomponent.owner = nil); +// result:= (acomponent.owner = nil) or (acomponent.owner.owner = nil); +end; + +function getglobalcomponent(const Name: string): TComponent; +begin + if (loadingdesigner <> nil) or (submodulecopy > 0) then begin + result:= fdesigner.fmodules.findmoduleinstancebyname(name); + end + else begin + result:= nil; + end; +end; + +procedure beginsubmodulecopy; +begin + inc(submodulecopy); + if submodulecopy = 1 then begin + lockfindglobalcomponent; + RegisterFindGlobalComponentProc({$ifdef FPC}@{$endif}getglobalcomponent); + end; +end; + +procedure endsubmodulecopy; +begin + dec(submodulecopy); + if submodulecopy = 0 then begin + unlockfindglobalcomponent; + unregisterFindGlobalComponentProc({$ifdef FPC}@{$endif}getglobalcomponent); + end; +end; + +{ tancestorlist } + +constructor tancestorlist.create; +begin + inherited create(sizeof(ancestorinfoty)); +end; + +procedure tancestorlist.doitemdestroyed(const sender: tmsecomponent); +var + int1: integer; + bo1: boolean; +begin + for int1:= count - 1 downto 0 do begin + with pancestorinfoty(getitempo(int1))^ do begin + bo1:= false; + if descendent = sender then begin + descendent:= nil; + bo1:= true; + end; + if ancestor = sender then begin + ancestor:= nil; + bo1:= true; + end; + if bo1 then begin + delete(int1); + end; + end; + end; +end; + +procedure tancestorlist.itemdestroyed(const sender: iobjectlink); +begin + doitemdestroyed(tmsecomponent(sender.getinstance)); +end; + +function tancestorlist.getdescendentar( + const aancestor: tmsecomponent): msecomponentarty; +var + int1,int2: integer; + po1: pancestorinfoty; +begin + setlength(result,count); + int2:= 0; + po1:= datapo; + for int1:= 0 to high(result) do begin + if po1^.ancestor = aancestor then begin + result[int2]:= po1^.descendent; + inc(int2); + end; + inc(po1); + end; + setlength(result,int2); +end; + +procedure tancestorlist.add(const adescendent, aancestor: tmsecomponent); +var + info: ancestorinfoty; +begin + fillchar(info,sizeof(info),0); + fobjectlinker.link(adescendent); + fobjectlinker.link(aancestor); + info.descendent:= adescendent; + info.ancestor:= aancestor; + inherited add(info); +end; + +procedure tancestorlist.dounlink(var item); +begin + with ancestorinfoty(item) do begin + fobjectlinker.unlink(descendent); + fobjectlinker.unlink(ancestor); + end; +end; + +{$ifndef mse_nomethodswap} +procedure tancestorlist.streamingswapmethodpointer(const acomp: tcomponent); +begin + if (fstreaming > 0) then begin + if finditem(pointerarty(fswappedancestors),acomp) < 0 then begin + designer.doswapmethodpointers(acomp,false); + additem(pointerarty(fswappedancestors),acomp); + end; + end; +end; +{$endif} + +function tancestorlist.findancestor( + const adescendent: tcomponent): tmsecomponent; +var + po1: pancestorinfoty; + int1: integer; +begin + result:= nil; + po1:= datapo; + for int1:= 0 to fcount - 1 do begin + if po1^.descendent = adescendent then begin + result:= po1^.ancestor; + break; + end; + inc(po1); + end; +{$ifndef mse_nomethodswap} + if result <> nil then begin + streamingswapmethodpointer(result); + end; +{$endif} +end; + +procedure tancestorlist.beginstreaming; +begin + inc(fstreaming); +end; + +procedure tancestorlist.endstreaming; +{$ifndef mse_nomethodswap} +var + int1: integer; + ar1: componentarty; +{$endif} +begin + dec(fstreaming); +{$ifndef mse_nomethodswap} + ar1:= nil; //compiler warning + if fstreaming = 0 then begin + ar1:= copy(fswappedancestors); + fswappedancestors:= nil; + for int1:= 0 to high(ar1) do begin + designer.doswapmethodpointers(ar1[int1],true); + end; + end; +{$endif} +end; + +function tancestorlist.finddescendent(const aancestor: tcomponent): tmsecomponent; +var + po1: pancestorinfoty; + int1: integer; +begin + result:= nil; + po1:= datapo; + for int1:= 0 to fcount - 1 do begin + if po1^.ancestor = aancestor then begin + result:= po1^.descendent; + break; + end; + inc(po1); + end; +end; + +function tancestorlist.finddescendentinfo(const adescendent: tcomponent): pancestorinfoty; +var + po1: pancestorinfoty; + int1: integer; +begin + result:= nil; + po1:= datapo; + for int1:= 0 to fcount - 1 do begin + if po1^.descendent = adescendent then begin + result:= po1; + break; + end; + inc(po1); + end; +end; + +function tancestorlist.findancestorinfo(const aancestor: tcomponent): pancestorinfoty; +var + po1: pancestorinfoty; + int1: integer; +begin + result:= nil; + po1:= datapo; + for int1:= 0 to fcount - 1 do begin + if po1^.ancestor = aancestor then begin + result:= po1; + break; + end; + inc(po1); + end; +end; + +function tancestorlist.findinfo(const ainfo: ancestornameinfoty): pancestorinfoty; +var + po1: pancestorinfoty; + int1: integer; +begin + result:= nil; + po1:= datapo; + for int1:= 0 to count - 1 do begin + if (namepathowner(po1^.descendent) = ainfo.desc) and + (namepathowner(po1^.ancestor) = ainfo.anc) then begin + result:= po1; + break; + end; + inc(po1); + end; +end; + +procedure tancestorlist.getinfo(const apo: pancestorinfoty; + out info: ancestornameinfoty); +begin + info.desc:= namepathowner(apo^.descendent); + info.anc:= namepathowner(apo^.ancestor); +end; + +{ tdesignerancestorlist } + +constructor tdesignerancestorlist.create(aowner: tdesigner); +begin + fdesigner:= aowner; + inherited create; +end; + +{ tsubmodulelist } + +procedure tsubmodulelist.finalizerecord(var item); +var + comp: tmsecomponent; +begin + with ancestorinfoty(item) do begin + comp:= ancestor; + ancestor:= nil; + end; + inherited; + if comp <> nil then begin + removefixupreferences(comp,''); + end; + comp.Free; +end; + +procedure tsubmodulelist.add(const amodule: tmsecomponent); +var + comp1: tmsecomponent; +begin + if findancestor(amodule) = nil then begin + comp1:= fdesigner.copycomponent(amodule,amodule,false,false); + if comp1 is twidget then begin + with twidget1(comp1) do begin + if ownswindow1() then begin + freeandnil(fwindow); //never mapped + rootchanged([]); + end; + end; + end; + inherited add(amodule,comp1); +// inherited add(amodule,fdesigner.copycomponent(amodule,nil)); + end; +end; + +procedure tsubmodulelist.dorenewbackup; +var + po1: pancestorinfoty; + comp: tmsecomponent; + amodule: tmsecomponent; + int1: integer; +begin + try + for int1:= 0 to high(frenewbackuplist) do begin + amodule:= frenewbackuplist[int1]; + if amodule <> nil then begin + po1:= finddescendentinfo(amodule); + if po1 <> nil then begin + comp:= po1^.ancestor; + po1^.ancestor:= nil; + if comp <> nil then begin + removefixupreferences(comp,''); + end; + comp.Free; + {$ifdef mse_debugcopycomponent} + debugwriteln('***renewbackup before copy '+amodule.name); + dumpcomponent(amodule,'source:'); + {$endif} +// fdesigner.fsubmoduleinfopo:= nil; + po1^.ancestor:= fdesigner.copycomponent(amodule,amodule,false,false); + {$ifdef mse_debugcopycomponent} + debugwriteln('***renewbackup after copy '+amodule.name); + dumpcomponent(amodule,'source:'); + dumpcomponent(po1^.ancestor,'backup:'); + {$endif} + // po1^.ancestor:= fdesigner.copycomponent(amodule,nil); + fobjectlinker.link(po1^.ancestor); + end; + end; + end; + finally + frenewbackuplist:= nil; + end; +end; + +procedure tsubmodulelist.receiveevent(const event: tobjectevent); +begin + if (event is tasyncevent) and + (tasyncevent(event).tag = renewbackuptag) then begin + dorenewbackup; + end; +end; + +procedure tsubmodulelist.renewbackup(const amodule: tmsecomponent); +begin + if frenewbackuplist = nil then begin + application.postevent(tasyncevent.create(ievent(self),renewbackuptag), + [peo_local]); + end; + additem(pointerarty(frenewbackuplist),amodule); +end; + +function tsubmodulelist.findoldancestor( + const adescendent: tmsecomponent): tmsecomponent; +var + po1: pancestorinfoty; +begin + result:= nil; + po1:= finddescendentinfo(adescendent); + if po1 <> nil then begin + result:= po1^.ancestor; + end; +end; + +procedure tsubmodulelist.doitemdestroyed(const sender: tmsecomponent); +var + int1: integer; +begin + for int1:= 0 to high(frenewbackuplist) do begin + if frenewbackuplist[int1] = sender then begin + frenewbackuplist[int1]:= nil; + end; + end; + inherited; +end; + +const + skipmark = '1w%f62*7/*+z'; + +type + trefreshexception = class(exception) + end; + +{ treaderrorhandler } + +destructor treaderrorhandler.destroy; +var + int1: integer; +begin + for int1:= 0 to high(fcomponentar) do begin + fcomponentar[int1].free; //FPC does not free the component + end; + inherited; +end; + +procedure treaderrorhandler.onerror(reader: treader; const message: string; + var handled: boolean); +begin + if message = skipmark then begin + handled:= true; + end; +end; + +procedure treaderrorhandler.notification(acomponent: tcomponent; operation: toperation); +begin + if (operation = opremove) then begin + removeitem(pointerarty(fcomponentar),acomponent); + removeitem(pointerarty(fnewcomponents),acomponent); + end; + inherited; +end; + +procedure treaderrorhandler.doraise(const acomponent: tcomponent); +begin + if acomponent <> nil then begin + additem(pointerarty(fcomponentar),acomponent); + acomponent.freenotification(self); + end; + raise trefreshexception.create(skipmark); +end; + +procedure treaderrorhandler.ancestornotfound(Reader: TReader; + const ComponentName: string; + ComponentClass: TPersistentClass; var Component: TComponent); +begin + designer.fsubmoduleinfopo:= nil; //reset for createcomponent + component:= findancestorcomponent(reader,componentname); + if component = nil then begin + doraise(nil); //changed name + end; +end; + +procedure treaderrorhandler.onsetname(reader: treader; + component: tcomponent; var aname: string); +begin +// if (component.owner <> nil) and (csinline in component.owner.componentstate) and +// not (csancestor in component.componentstate) then begin + if component.owner = froot then begin + additem(pointerarty(fnewcomponents),component); + component.freenotification(self); +// doraise(component); //new component placed into submodule + end; +end; + +{ tdescendentinstancelist } + +procedure tdescendentinstancelist.delcomp(child: tcomponent); +begin + tcomponent1(child).getchildren({$ifdef FPC}@{$endif}delcomp,froot); + additem(pointerarty(fdelcomps),child); +end; + +procedure tdescendentinstancelist.addcomp(child: tcomponent); +begin + fmodule^.components.add(child); + tcomponent1(child).getchildren({$ifdef FPC}@{$endif}addcomp,child); +end; + +type + tdelcomp = class(tcomponent) + private + fdelcomps: componentarty; + protected + procedure notification(acomponent: tcomponent; operation: toperation); override; + end; + +procedure tdelcomp.notification(acomponent: tcomponent; operation: toperation); +var + int1: integer; +begin + inherited; + if operation = opremove then begin + for int1:= high(fdelcomps) downto 0 do begin + if fdelcomps[int1] = acomponent then begin + fdelcomps[int1]:= nil; + end; + end; + end; +end; + +(* +procedure tdescendentinstancelist.revert(const info: pancestorinfoty; + const module: pmoduleinfoty; out anewinstance: tmsecomponent; + const norootposition: boolean = false; + const initflags: boolean = true); +var + comp1,comp2: tmsecomponent; + decomp: tdelcomp; + parent1: twidget; + str1: string; + int1: integer; + isroot: boolean; + ancestorclassname1: string; + actualclassname1: pshortstring; + pt1: pointty; + ar1: msecomponentarty; + ancestorbefore: tmsecomponent; + infoancestor: tmsecomponent; + po1: pancestorinfoty; +begin +{$ifdef mse_debugsubmodule} + debugwriteln('***revert module'+ module^.instance.name+ + ' dest '+info^.descendent.name+' anch '+info^.ancestor.name); + po1:= datapo; + for int1:= 0 to count-1 do begin + debugwriteln('*'+inttostr(int1)+' '+po1^.ancestor.name+' '+ + po1^.descendent.name); + inc(po1); + end; +{$endif} + comp1:= info^.descendent; + infoancestor:= info^.ancestor; + isroot:= comp1 = module^.instance; + delete((pchar(info)-pchar(datapo)) div recordsize); //remove item + ancestorbefore:= nil; //compiler warning + ar1:= nil; //compiler warning + if isroot then begin + ar1:= getdescendentar(comp1); //restore after revert + po1:= fdesigner.fsubmodulelist.finddescendentinfo(comp1); + if po1 <> nil then begin + ancestorbefore:= po1^.ancestor; + po1^.ancestor:= nil; //don't free + end; + end; + with tmsecomponent1(comp1) do begin + ancestorclassname1:= fancestorclassname; + actualclassname1:= factualclassname; + end; + +// info^.descendent:= nil; //no recursion + if comp1 is twidget then begin + with twidget1(comp1) do begin + parent1:= parentwidget; + pt1:= tformdesignerfo(module^.designform).modulerect.pos; + end; + end + else begin + parent1:= nil; + pt1:= getcomponentpos(comp1); + end; + str1:= comp1.name; +// fobjectlinker.unlink(comp1); + fdelcomps:= nil; + froot:= comp1.owner; + if ismodule(comp1) then begin + froot:= comp1; + end; + delcomp(comp1); + decomp:= tdelcomp.create(nil); + try + decomp.fdelcomps:= fdelcomps; + for int1:= high(fdelcomps) downto 0 do begin + fdelcomps[int1].freenotification(decomp); + end; + for int1:= high(fdelcomps) downto 0 do begin + fdelcomps[int1].free; + end; + finally + decomp.free; + end; + fdelcomps:= nil; + comp2:= fdesigner.copycomponent(infoancestor,infoancestor); + if isroot and initflags then begin + initrootdescendent(comp2); + end; + + { + if not isroot then begin +// comp2:= fdesigner.copycomponent(info^.ancestor,nil); + comp2:= fdesigner.copycomponent(info^.ancestor,info^.ancestor); + end + else begin + comp2:= fdesigner.copycomponent(info^.ancestor,info^.ancestor); + initrootdescendent(comp2); + end; + } +// info^.descendent:= comp2; + comp2.name:= str1; + with tmsecomponent1(comp2) do begin + fancestorclassname:= ancestorclassname1; + factualclassname:= actualclassname1; + end; + if not isroot then begin + initinline(comp2); + end + else begin + tcomponent1(comp2).setancestor(true); + end; + { + if isroot then begin + tcomponent1(comp2).setancestor(true); + end + else begin + tmsecomponent1(comp2).setinline(true); + end; + } +// checkinline(comp2); +// fobjectlinker.link(comp2); + if isroot then begin + module^.instance:= comp2; + if norootposition then begin + if (comp2 is twidget) then begin + with twidget1(comp2) do begin + fwidgetrect.pos:= pt1; //do not restore position + end; + end + else begin + setcomponentpos(comp2,pt1); + end; + end; + tformdesignerfo(module^.designform).module:= comp2; + end + else begin + tmsecomponent1(comp2).setinline(true); + module^.instance.insertcomponent(comp2); + end; + if parent1 <> nil then begin + twidget(comp2).parentwidget:= parent1; + end; + fmodule:= module; + addcomp(comp2); + removefixupreferences(module^.instance,''); + anewinstance:= comp2; + add(comp2,infoancestor); //restore entry +// add(comp2,info^.ancestor); //restore entry + if isroot then begin + for int1:= 0 to high(ar1) do begin + add(ar1[int1],comp2); + //restore entry; + end; + if ancestorbefore = nil then begin +// fdesigner.fsubmodulelist.add(comp2); //should not happen + end + else begin + fdesigner.fsubmodulelist.add(comp2,ancestorbefore); + end; + end; +{$ifdef mse_debugsubmodule} + debugwriteln('***end revert' ); + po1:= datapo; + for int1:= 0 to count-1 do begin + debugwriteln('*'+inttostr(int1)+' '+po1^.ancestor.name+' '+ + po1^.descendent.name); + inc(po1); + end; +{$endif} +end; +*) + +function tdescendentinstancelist.getancestors( + const adescendent: tcomponent): componentarty; + + procedure addancestors(const adescendent: tcomponent); + var + po1: pointer; + int1: integer; + begin + po1:= datapo; + for int1:= 0 to count - 1 do begin + with(pancestorinfoaty(po1)^[int1]) do begin + if descendent = adescendent then begin + if finditem(pointerarty(result),ancestor) < 0 then begin + additem(pointerarty(result),ancestor); + end; + addancestors(ancestor); + end + end; + end; + end; + +begin + result:= nil; + addancestors(adescendent); +end; + +function tdescendentinstancelist.getancestorsandchildren( + const adescendent: tcomponent): componentarty; +var + po1: pointer; + int1: integer; + po2: pmoduleinfoty; +begin + result:= getancestors(adescendent); + po1:= datapo; + for int1:= 0 to count - 1 do begin + with(pancestorinfoaty(po1)^[int1]) do begin + if ancestor = adescendent then begin + po2:= fdesigner.modules.findmodulebycomponent(descendent); + if (po2 <> nil) and (finditem(pointerarty(result),po2^.instance) < 0) then begin + additem(pointerarty(result),po2^.instance); + end; + end; + end; + end; +end; + +function tdescendentinstancelist.getdescendents( + const aancestor: tcomponent): componentarty; +var + recursionlevel: integer; + + procedure adddescendent(const aancestor: tcomponent); + var + int1: integer; + po1: pancestorinfoaty; + begin + dec(recursionlevel); + if recursionlevel > 0 then begin + po1:= datapo; + for int1:= count - 1 downto 0 do begin + with po1^[int1] do begin + if ancestor = aancestor then begin + additem(pointerarty(result),descendent); + adddescendent(descendent); + end; + end; + end; + end; + inc(recursionlevel); + end; + +begin + result:= nil; + recursionlevel:= 32; //max + adddescendent(aancestor); +end; + +{$ifdef mse_nomethodswap} +procedure tdescendentinstancelist.setrefreshmethod(reader: treader; + instance: tpersistent; + propinfo: ppropinfo; const themethodname: string; + var handled: boolean); +var + m1: tmethod; + po1: pmethodinfoty; + int1: integer; +begin + m1.code:= nil; + m1.data:= nil; + for int1:= high(frefreshmethods) downto 0 do begin + if frefreshmethods[int1] <> nil then begin + po1:= frefreshmethods[int1].findmethodbyname(themethodname); + if po1 <> nil then begin + m1.data:= po1^.address; + break; + end; + end; + end; + setmethodprop(instance,propinfo,m1); + handled:= true; +end; +{$else} +procedure tdescendentinstancelist.findrefreshmethod(reader: treader; + const amethodname: string; var address: pointer; var error: boolean); +var +// method: tmethod; + po1: pmethodinfoty; + int1: integer; +begin + if error then begin + for int1:= high(frefreshmethods) downto 0 do begin + po1:= frefreshmethods[int1].findmethodbyname(amethodname); +// po1:= fdesigner.floadingmodulepo^.methods.findmethodbyname(amethodname); + if po1 <> nil then begin + address:= po1^.address; + break; + end; + end; + error:= false; + end; +end; +{$endif} + +procedure tdescendentinstancelist.domodulemodified(const amodule: pmoduleinfoty; + modifylevel: integer; + destcompnames,ancestorcompnames: stringarty; + newancestorcomps,oldancestorcomps: msecomponentarty); + //todo: simplify, optimize +var + dependentmodules: moduleinfopoarty; + dependentmod: moduleinfopoarty; + comp1: tmsecomponent; + newancestor0: tmsecomponent; + oldancestor0: tmsecomponent; + descendent1,newancestor1,oldancestor1: tmsecomponent; + int1,int2,int3,int4: integer; +// str1: string; + destname: string; + po1: pancestorinfoty; + po2: pmoduleinfoty; + bo1,bo2,bo3,newcomponent: boolean; + pt1: pointty; + taborderbefore: integer; + depmodcomps: array of stringarty; + dependentcomponents: array of msecomponentarty; + newancestorcomponents: array of msecomponentarty; + oldancestorcomponents: array of msecomponentarty; +// sourcemethodtab: pointer; + +begin + if modifylevel >= 16 then begin + showmessage(actionsmo.c[ord(ac_recursiveforminheritance)]+ + amodule^.filename+'".',actionsmo.c[ord(ac_error)]); + sysutils.abort; + end; + if modifylevel = 0 then begin + fdeletedcomps:= nil; + begingloballoading; + end; + inc(modifylevel); + try + dependentmodules:= nil; //compilerwarning + {$ifdef mse_debugsubmodule} + debugwriteln('***modulemodified '+inttostr(modifylevel)+' '+ + amodule^.instance.name); + debugwriteln(' destcompnames: '+debugstringarty(destcompnames)); + debugwriteln(' ancestorcompnames: '+debugstringarty(ancestorcompnames)); + debugwriteln(' newancestorcomps: '+ + debugcomprootnames(componentarty(newancestorcomps))); + debugwriteln(' oldancestorcomps: '+ + debugcomprootnames(componentarty(oldancestorcomps))); + // po1:= datapo; + // for int1:= 0 to count-1 do begin + // debugwriteln('*'+inttostr(int1)+' '+po1^.ancestor.name+' '+ + // po1^.descendent.name); + // inc(po1); + // end; + {$endif} + + newancestor0:= amodule^.instance; + oldancestor0:= fdesigner.fsubmodulelist.findoldancestor(amodule^.instance); + po1:= datapo; + int2:= 0; + setlength(dependentmod,fcount); //max + for int1:= 0 to fcount - 1 do begin + if po1^.ancestor = amodule^.instance then begin + // dependentcomponents[int2]:= po1^.descendent; + if ismodule(po1^.descendent) then begin //inherited form + comp1:= po1^.descendent; + destname:= 'OWNER'; + end + else begin + comp1:= tmsecomponent(po1^.descendent.owner); + destname:= po1^.descendent.name; + end; + po2:= fdesigner.modules.findmodule(comp1); + dependentmod[int2]:= po2; + inc(int2); + {$ifdef mse_debugsubmodule} + debugwriteln(' item ancestor: '+po1^.ancestor.name+ ' descendent: '+ + po1^.descendent.name + ' module: '+po2^.instance.name); + {$endif} + int3:= finditem(pointerarty(dependentmodules),po2); + if int3 < 0 then begin + int3:= high(dependentmodules)+2; + setlength(dependentmodules,int3); + setlength(depmodcomps,int3); + setlength(dependentcomponents,int3); + setlength(newancestorcomponents,int3); + setlength(oldancestorcomponents,int3); + dec(int3); + dependentmodules[int3]:= po2; + end; + if (destcompnames = nil) then begin + additem(depmodcomps[int3],destname); + additem(pointerarty(dependentcomponents[int3]),po1^.descendent); + additem(pointerarty(newancestorcomponents[int3]),newancestor0); + additem(pointerarty(oldancestorcomponents[int3]),oldancestor0); + end + else begin + for int4:= 0 to high(destcompnames) do begin + additem(depmodcomps[int3],destname+'.'+destcompnames[int4]); + additem(pointerarty(newancestorcomponents[int3]),newancestorcomps[int4]); + additem(pointerarty(oldancestorcomponents[int3]),oldancestorcomps[int4]); + additem(pointerarty(dependentcomponents[int3]),po1^.descendent); + end; + end; + // adduniqueitem(pointerarty(dependentmodules),po2); + end; + inc(po1); + end; + setlength(dependentmod,int2); + + if int2 > 0 then begin + {$ifdef mse_debugsubmodule} + debugwriteln('*descendents:'); + for int1:= 0 to high(dependentmodules) do begin + debugwriteln('module: '+dependentmodules[int1]^.instance.name); + for int2:= 0 to high(depmodcomps[int1]) do begin + debugwriteln(' '+depmodcomps[int1][int2]); + end; + end; + {$endif} + beginsubmodulecopy; + beginstreaming(amodule); + if modifylevel = 1 then begin + {$ifndef mse_nomethodswap} + streamingswapmethodpointer(amodule^.instance); + {$endif} +// frefreshmethods:= fdesigner.getancestormethods(amodule); + {$ifndef mse_nomethodswap} + amodule^.methods.createmethodtable(frefreshmethods); + {$endif} + end; + insertitem(pointerarty(frefreshmethods),0,nil); +// setlength(frefreshmethods,high(frefreshmethods)+3); +// frefreshmethods[high(frefreshmethods)-1]:= amodule^.methods; + {$ifndef mse_nomethodswap} + for int1:= 0 to high(dependentmodules) do begin + dependentmodules[int1]^.methods.createmethodtable(frefreshmethods); + // fdesigner.getancestormethods(dependentmodules[int1])); + end; + {$endif} + stackarray(pointerarty(dependentmodules),pointerarty(fmodifiedmodules)); + try +// oldancestor0:= fdesigner.fsubmodulelist.findoldancestor(amodule^.instance); + for int1:= 0 to high(dependentmodules) do begin + {$ifndef mse_nomethodswap} + streamingswapmethodpointer(dependentmodules[int1]^.instance); + {$endif} + frefreshmethods[0]:= dependentmodules[int1]^.methods; + newcomponent:= false; + for int2:= 0 to high(depmodcomps[int1]) do begin + descendent1:= dependentcomponents[int1][int2]; + newancestor1:= amodule^.instance; + oldancestor1:= oldancestor0; + descendent1:= tmsecomponent( + findnestedcomponent(dependentmodules[int1]^.instance, + depmodcomps[int1][int2])); + if ancestorcompnames <> nil then begin + int3:= int2 mod length(ancestorcompnames); + newancestor1:= newancestorcomps[int3]; + oldancestor1:= oldancestorcomps[int3]; + {$ifdef mse_debugsubmodule} + debugwriteln('*refreshmain descendent: '+debugcomprootname(descendent1)+ + ' newancestor: '+debugcomprootname(newancestor1)+ + ' oldancestor: '+debugcomprootname(oldancestor1)); + {$endif} + refreshancestor(fdeletedcomps,descendent1,newancestor1, + oldancestor1,false, + {$ifdef FPC}@{$endif}fdesigner.findancestor, + {$ifdef FPC}@{$endif}fdesigner.findcomponentclass, + fdesigner.createcomponent(), + {$ifdef mse_nomethodswap} + {$ifdef FPC}@{$endif}setrefreshmethod, + {$ifdef FPC}@{$endif}fdesigner.writedesignmethod, + @newcomponent + {$else} + {$ifdef FPC}@{$endif}findrefreshmethod, + dependentmod[int1]^.methods.fmethodtable + {amodule^.methods.fmethodtable}, + dependentmod[int1]^.methods.fmethodtable + {$endif}); + end + else begin + if destcompnames <> nil then begin + int3:= int2 mod length(destcompnames); + newancestor1:= newancestorcomps[int3]; + oldancestor1:= oldancestorcomps[int3]; + end; + bo3:= (csinline in descendent1.componentstate) and + (descendent1.owner <> nil); + //whole submodule + bo1:= false; + bo2:= false; + if bo3 then begin //submodule + bo1:= descendent1 is twidget; + if bo1 then begin + pt1:= twidget(descendent1).pos; + taborderbefore:= twidget(descendent1).taborder; + end + else begin + bo2:= isdatasubmodule(descendent1); + if bo2 then begin + pt1:= getcomponentpos(descendent1); + end; + end; + end; + {$ifdef mse_debugsubmodule} + debugwriteln('*refreshcomps descendent: '+debugcomprootname(descendent1)+ + ' newancestor: '+debugcomprootname(newancestor1)+ + ' oldancestor: '+debugcomprootname(oldancestor1)); + {$endif} + refreshancestor(fdeletedcomps,descendent1,newancestor1, + oldancestor1,false, + {$ifdef FPC}@{$endif}fdesigner.findancestor, + {$ifdef FPC}@{$endif}fdesigner.findcomponentclass, + fdesigner.createcomponent(), + {$ifdef mse_nomethodswap} + {$ifdef FPC}@{$endif}setrefreshmethod, + {$ifdef FPC}@{$endif}fdesigner.writedesignmethod, + @newcomponent + {$else} + {$ifdef FPC}@{$endif}findrefreshmethod, + amodule^.methods.fmethodtable, + dependentmod[int1]^.methods.fmethodtable + {$endif}); + if bo2 then begin + end; + if bo1 then begin + twidget(descendent1).pos:= pt1; //restore insert position + twidget(descendent1).taborder:= taborderbefore; + end + else begin + if bo2 then begin + setcomponentpos(descendent1,pt1); //restore insert position + end; + end; + end; + end; + if newcomponent then begin + with dependentmodules[int1]^ do begin + components.assigncomps(instance) + end; + end; + end; + for int1:= 0 to high(dependentmodules) do begin + domodulemodified(dependentmodules[int1],modifylevel, + depmodcomps[int1],destcompnames, + newancestorcomponents[int1],oldancestorcomponents[int1]); + end; + finally + if frefreshmethods <> nil then begin + setlength(frefreshmethods,high(frefreshmethods)); + end; + fdesigner.fsubmodulelist.renewbackup(amodule^.instance); + {$ifndef mse_nomethodswap} + amodule^.methods.releasemethodtable; + {$endif} + endsubmodulecopy; + endstreaming; + end; + end + else begin + fdesigner.fsubmodulelist.renewbackup(amodule^.instance); + end; + {$ifdef mse_debugsubmodule} + debugwriteln('***end modulemodified '+inttostr(modifylevel)+' '+ + amodule^.instance.name); + {$endif} + if modifylevel = 1 then begin + notifygloballoading; + if fdeletedcomps <> nil then begin + freecomponents(fdeletedcomps); + fdeletedcomps:= nil; + modulemodified(amodule); //refresh again + end; + end; + finally + if modifylevel = 1 then begin + endgloballoading; + end; + end; +end; + +procedure tdescendentinstancelist.modulemodified(const amodule: pmoduleinfoty); +var + int1: integer; +begin + if not fmodulemodifying then begin + fmodulemodifying:= true; + fmodifiedmodules:= nil; + try + domodulemodified(amodule,0,nil,nil,nil,nil); + finally + try + {$ifndef mse_nomethodswap} + for int1:= 0 to high(fmodifiedmodules) do begin + fmodifiedmodules[int1]^.methods.releasemethodtable; + end; + {$endif} + for int1:= 0 to high(fmodifiedmodules) do begin + fdesigner.modulechanged(fmodifiedmodules[int1]); + end; + finally + fmodulemodifying:= false; + end; + end; + end; +end; + +procedure tdescendentinstancelist.componentnamechanged( + const amodule: pmoduleinfoty; + const acomponent: tcomponent; const newname: string); +var + reclevel: integer; + namepath: string; + newpath: string; + + procedure donamechange(aancestor: pmoduleinfoty); + var + int1: integer; + po1: pancestorinfoty; + comp1: tcomponent; + begin + if aancestor <> nil then begin + if reclevel >= 16 then begin + showmessage(actionsmo.c[ord(ac_recursiveforminheritance)]+ + amodule^.filename+'".',actionsmo.c[ord(ac_error)]); + sysutils.abort; + end; + inc(reclevel); + po1:= datapo; + for int1:= 0 to count-1 do begin + if po1^.ancestor = aancestor^.instance then begin + comp1:= findnestedcomponent(po1^.descendent,namepath); + if comp1 <> nil then begin + comp1.name:= newname; + end; + donamechange(fdesigner.modules.findmodule(po1^.descendent)); + end; + inc(po1); + end; + dec(reclevel); + end; + end; + + procedure docheckname(aancestor: pmoduleinfoty); + var + int1: integer; + po1: pancestorinfoty; + comp1: tcomponent; + begin + if aancestor <> nil then begin + if reclevel >= 16 then begin + showmessage(actionsmo.c[ord(ac_recursiveforminheritance)]+ + amodule^.filename+'".',actionsmo.c[ord(ac_error)]); + sysutils.abort; + end; + inc(reclevel); + po1:= datapo; + for int1:= 0 to count-1 do begin + if po1^.ancestor = aancestor^.instance then begin + comp1:= findnestedcomponent(po1^.descendent,newpath); + if comp1 <> nil then begin + raise exception.create(po1^.descendent.name+': '+ + ansistring(actionsmo.c[ord(ac_component)])+ + newpath+ansistring(actionsmo.c[ord(ac_exists)])); + end; + donamechange(fdesigner.modules.findmodule(po1^.descendent)); + end; + inc(po1); + end; + dec(reclevel); + end; + end; + +var + ar1: componentarty; + int1: integer; +begin + if not fcomponentnamechanging then begin + fcomponentnamechanging:= true; + try + ar1:= ownercomponentpath(acomponent); + if high(ar1) > 0 then begin + namepath:= ar1[1].name; + for int1:= 2 to high(ar1) do begin + namepath:= namepath+'.'+ar1[int1].name; + end; + if high(ar1) > 1 then begin + newpath:= ar1[1].name; + for int1:= 2 to high(ar1)-1 do begin + namepath:= namepath+'.'+ar1[int1].name; + end; + newpath:= newpath+'.'+newname; + end + else begin + newpath:= newname; + end; + reclevel:= 0; + docheckname(amodule); + reclevel:= 0; + donamechange(amodule); + end; + finally + fcomponentnamechanging:= false; + end; + end; +end; + +procedure tdescendentinstancelist.add(const instance,ancestor: tmsecomponent; + const submodulelist: tsubmodulelist); +begin + submodulelist.add(ancestor); + inherited add(instance,ancestor); +end; + +function tdescendentinstancelist.getclassname(const comp: tcomponent): string; + //returns submoduleclassname if appropriate +var + comp1: tmsecomponent; +begin + if ismodule(comp) then begin + //module, must be tmsecomponent; + result:= tmsecomponent(comp).actualclassname; + end + else begin + if csinline in comp.ComponentState then begin + comp1:= findancestor(comp); + if comp1 <> nil then begin + result:= comp1.actualclassname; + exit; + end; + end; + result:= comp.classname; + end; +end; + +procedure tdescendentinstancelist.setnodefaultpos(const aroot: twidget); +var + po1: pancestorinfoty; + int1: integer; +begin + po1:= datapo; + for int1:= 0 to fcount - 1 do begin + if (po1^.descendent is twidget) and (po1^.descendent <> nil) and //else inherited form + twidget(po1^.descendent).checkancestor(aroot) then begin + twidget1(po1^.ancestor).fwidgetrect.pos:= makepoint(-bigint,-bigint); + end; + inc(po1); + end; +end; + +procedure tdescendentinstancelist.restorepos(const aroot: twidget); +var + po1: pancestorinfoty; + int1: integer; +begin + po1:= datapo; + for int1:= 0 to fcount - 1 do begin + if (po1^.descendent is twidget) and + twidget(po1^.descendent).checkancestor(aroot) then begin + twidget1(po1^.ancestor).fwidgetrect.pos:= nullpoint; + end; + inc(po1); + end; +end; + +procedure tdescendentinstancelist.beginstreaming(const amodule: pmoduleinfoty); +begin + inherited beginstreaming; + if amodule <> nil then begin + frefreshmethods:= fdesigner.getancestormethods(amodule); + end; +end; + +{ tmethods } + +constructor tmethods.create(adesigner: tdesigner); +begin + fdesigner:= adesigner; + inherited create(); + fstate:= fstate + [hls_needsnull,hls_needsfinalize]; +end; + +destructor tmethods.destroy; +begin +{$ifndef mse_nomethodswap} + releasemethodtable; +{$endif} + inherited; +end; + +function tmethods.getrecordsize(): int32; +begin + result:= sizeof(methodshashdataty); +end; + +procedure tmethods.addmethod(const aname: string; const aaddress: pointer; + const atypeinfo: ptypeinfo); +var + po1: pmethodshashdataty; +begin + {$ifdef FPC} {$checkpointer off} {$endif} + po1:= pmethodshashdataty(add(ptruint(aaddress))); + {$ifdef FPC} {$checkpointer default} {$endif} + with po1^.data.data do begin + name:= aname; + address:= aaddress; + typeinfo:= atypeinfo; + end; + fdesigner.fmodules.fmethodnames.add(ptruint(aaddress),aname); +end; + +procedure tmethods.deletemethod(const aadress: pointer); +begin +// inherited delete(aadress); do nothing +end; + +{$ifndef mse_nomethodswap} +type +{$ifdef FPC} + tmethodnamerec = packed record + name : pshortstring; + addr : pointer; + end; + pmethodtableentryty = ^tmethodnamerec; + + tmethodnametable = packed record + count : dword; + entries : packed array[0..0] of tmethodnamerec; + end; + +function tmethods.createmethodtable(const ancestors: methodsarty): pointer; +var + int1,int2,int3: integer; + po1: pmethodinfoty; + po2: pmethodtableentryty; + po3: pchar; + count1: integer; + ar1: methodsarty; +begin + releasemethodtable; + ar1:= copy(ancestors); + additem(pointerarty(ar1),self); + count1:= 0; + for int1:= 0 to high(ar1) do begin + inc(count1,ar1[int1].count); + end; + if count1 > 0 then begin + int2:= count1; //lenbyte + for int3:= 0 to high(ar1) do begin + with ar1[int3] do begin + for int1:= 0 to count -1 do begin + int2:= int2 + length(pmethodsdataty(next)^.data.name); //stringsize + end; + end; + end; + int1:= sizeof(dword) + count1 * sizeof(tmethodnamerec); //tablesize + getmem(fmethodtable,int1+int2); + pdword(fmethodtable)^:= count1; + po2:= pmethodtableentryty(pchar(fmethodtable) + sizeof(dword)); + po3:= pchar(fmethodtable) + int1; //stringtable + for int3:= 0 to high(ar1) do begin + with ar1[int3] do begin + for int1:= 0 to count - 1 do begin + po1:= @pmethodsdataty(next)^.data; + int2:= length(po1^.name); + po2^.name:= pshortstring(po3); + po3^:= char(int2); //namelen + inc(po3); + move(pointer(po1^.name)^,po3^,int2); + inc(po3,int2); + po2^.addr:= po1^.address; + inc(po2); + end; + end; + end; + end; + result:= fmethodtable; +end; + +{$else} + + methodtableentryfixty = packed record + len: word; + addr: pointer; + namlen: byte; +end; + + methodtableentryty = packed record + len: word; + adr: pointer; + name: shortstring; //variable length + end; + pmethodtableentryty = ^methodtableentryty; + +function tmethods.createmethodtable(const ancestors: methodsarty): pointer; +var + int1,int2,int3: integer; + po1: pmethodinfoty; + po2: pmethodtableentryty; + count1: integer; + ar1: methodsarty; + +begin + releasemethodtable; + ar1:= copy(ancestors); + additem(pointerarty(ar1),self); + count1:= 0; + for int1:= 0 to high(ar1) do begin + inc(count1,ar1[int1].count); + end; + if count1 > 0 then begin + int2:= sizeof(word); //numentries + for int3:= 0 to high(ar1) do begin + with ar1[int3] do begin + for int1:= 0 to count -1 do begin + int2:= int2 + length(pmethodsdataty(next)^.data.name); + end; + end; + end; + getmem(fmethodtable,int2 + count1 * sizeof(methodtableentryfixty)); + pword(fmethodtable)^:= count1; + po2:= pmethodtableentryty(pchar(fmethodtable) + sizeof(word)); + for int3:= 0 to high(ar1) do begin + with ar1[int3] do begin + for int1:= 0 to count - 1 do begin + po1:= pmethodinfoty(next); +// po1:= @pmethodstataty(next).data; ???? + int2:= length(po1^.name); + po2^.len:= sizeof(methodtableentryfixty) + int2; + po2^.adr:= po1^.address; + po2^.name[0]:= char(int2); + move(po1^.name[1],po2^.name[1],int2); + inc(pchar(po2),po2^.len); + end; + end; + end; + end; + result:= fmethodtable; +end; + +{$endif} + +procedure tmethods.releasemethodtable; +begin + if fmethodtable <> nil then begin + freemem(fmethodtable); + fmethodtable:= nil; + end; +end; +{$endif mse_nomethodswap} + +function tmethods.findmethod(const aadress: pointer): pmethodinfoty; +begin + result:= pointer(find(ptruint(aadress))); + if result <> nil then begin + result:= @pmethodshashdataty(result)^.data.data; + end; +end; + +function tmethods.findmethodbyname(const aname: string; + const atype: ptypeinfo; out namefound: boolean): pmethodinfoty; +var + int1: integer; + po1: pmethodshashdataty; + str1: string; +begin + str1:= uppercase(aname); + result:= nil; + namefound:= false; + for int1:= 0 to count - 1 do begin + po1:= pmethodshashdataty(next); + if uppercase(po1^.data.data.name) = str1 then begin + namefound:= true; + if (po1^.data.data.typeinfo = atype) then begin + result:= @po1^.data.data; + break; + end; + end; + end; +end; + +function tmethods.findmethodbyname(const aname: string): pmethodinfoty; +var + int1: integer; + po1: pmethodshashdataty; + str1: string; +begin + str1:= uppercase(aname); + result:= nil; + for int1:= 0 to count - 1 do begin + po1:= pmethodshashdataty(next); + if uppercase(po1^.data.data.name) = str1 then begin + result:= @po1^.data.data; + break; + end; + end; +end; + +procedure tmethods.finalizeitem(const aitem: phashdataty); +begin + if fdesigner.fmodules.fmethodnames <> nil then begin + fdesigner.fmodules.fmethodnames.delete( + ptruint(pmethodshashdataty(aitem)^.data.data.address)); + end; + finalize(pmethodshashdataty(aitem)^.data.data); +end; + +{ tcomponents } + +constructor tcomponents.create(const aowner: pmoduleinfoty; + const adesigner: tdesigner); +begin + fowner:= aowner; + fdesigner:= adesigner; + fcomponent:= tcomponentslink.Create(nil); + fcomponent.fownercomps:= self; + inherited create(); + fstate:= fstate + [hls_needsnull,hls_needsfinalize]; +end; + +destructor tcomponents.destroy; +begin + fcomponent.Free; + inherited; +end; + +function tcomponents.getrecordsize(): int32; +begin + result:= sizeof(componentshashdataty); +end; + +procedure tcomponents.destroynotification(const acomponent: tcomponent); +begin + fdesigner.componentdestroyed(acomponent,fowner); + delete(ptruint(acomponent),true); +end; + +procedure tcomponents.finalizeitem(const aitem: phashdataty); +begin + finalize(pcomponentshashdataty(aitem)^.data.data); +end; + +(* +procedure tcomponents.doadd(component: tcomponent); +var + root: tcomponent; +begin + if not(component is twidget) or + (ws_iswidget in twidget1(component).fwidgetstate) then begin + add(component); + end; + root:= famodule; + if csinline in component.componentstate then begin + famodule:= component; + end; + tcomponent1(component).GetChildren({$ifdef FPC}@{$endif}doadd,famodule); + famodule:= root; +end; +*) +procedure tcomponents.assigncomps(const module: tmsecomponent); + procedure addcomp(acomp: tcomponent); + var + ar1: componentarty; + int1: integer; + begin + if not(acomp is twidget) or + (ws_iswidget in twidget1(acomp).fwidgetstate) then begin + add(acomp); + end; + ar1:= getcomponentchildren(acomp,module,true); + for int1:= 0 to high(ar1) do begin + addcomp(ar1[int1]); + end; + end; + +begin + clear; + if module <> nil then begin + addcomp(module); +// famodule:= module; +// doadd(module); + end; +end; + +procedure tcomponents.add(comp: tcomponent); +var + po1: pcomponentshashdataty; +begin + {$ifdef FPC} {$checkpointer off} {$endif} + po1:= pcomponentshashdataty(inherited add(ptruint(comp))); + {$ifdef FPC} {$checkpointer default} {$endif} + with po1^.data.data do begin + instance:= comp; + name:= comp.Name; + end; + comp.freenotification(fcomponent); +end; + +function tcomponents.find(const value: tobject): pcomponentshashdataty; +begin + result:= pcomponentshashdataty(inherited find(ptruint(value))); +end; + +procedure tcomponents.swapcomponent(const old,new: tcomponent); +var + po1: pcomponentshashdataty; +begin + po1:= find(old); + if po1 <> nil then begin + po1^.data.data.instance:= new; + old.removefreenotification(fcomponent); + new.freenotification(fcomponent); + end; +end; + +function tcomponents.getcomponents: componentarty; +var + int1: integer; +begin + setlength(result,count); + for int1:= 0 to count - 1 do begin + result[int1]:= pcomponentsdataty(next)^.data.instance; + end; +end; + +function tcomponents.next: pcomponentshashdataty; +begin + result:= pcomponentshashdataty(inherited next); +end; + +function tcomponents.getcomponent(const aname: string; + const children: boolean = false): tcomponent; +var + int1,int2: integer; + po1: pcomponentshashdataty; + str1: string; + ar1: stringarty; +begin + result:= nil; + str1:= uppercase(aname); + if aname <> '' then begin + if children then begin + ar1:= splitstring(str1,'.'); + deleteitem(ar1,0); + if ar1 = nil then begin + exit; + end; + end + else begin + ar1:= splitstring(str1,subcomponentsplitchar); + end; + for int1:= 0 to count - 1 do begin + po1:= next; + if uppercase(po1^.data.data.name) = ar1[0] then begin + result:= po1^.data.data.instance; + for int2:= 1 to high(ar1) do begin + result:= result.findcomponent(ar1[int2]); + if (result = nil) then begin + break; + end; + if isnosubcomp(result) then begin +// if not(cssubcomponent in result.componentstyle) then begin + result:= nil; + break; + end; + end; + break; + end; + end; + end; +end; + +procedure tcomponents.namechanged(const acomponent: tcomponent; + const newname: string); +var + po1: pcomponentshashdataty; +begin + po1:= find(acomponent); + if po1 <> nil then begin + po1^.data.data.name:= newname; + end; +end; + +function comparecomponentname(const l,r): integer; +begin + result:= comparetext(componentnamety(l).dispname,componentnamety(r).dispname); +end; + +function tcomponents.getdispnames: componentnamearty; +var + int1: integer; +begin + setlength(result,count); + for int1:= 0 to count - 1 do begin + with result[int1] do begin + instance:= next^.data.data.instance; + dispname:= fdesigner.getcomponentdispname(instance); + end; + end; + sortarray(result,sizeof(componentnamety), + {$ifdef FPC}@{$endif}comparecomponentname); +end; + +{ tmoduleinfo } + +constructor tmoduleinfo.create(adesigner: tdesigner); +begin + fdesigner:= adesigner; + with info do begin + methods:= tmethods.create(fdesigner); + components:= tcomponents.create(@info,fdesigner); + end; +end; + +destructor tmoduleinfo.destroy; +begin + inherited; + removeitem(pointerarty(fdesigner.fcheckfixups),@info); + with info do begin + if filetag <> 0 then begin + sourcefo.filechangenotifyer.removenotification(filename,filetag); + end; + freeandnil(loadingstream); + freeandnil(methods); + freeandnil(components); + freeandnil(designform); + end; +end; + +{ tmodulelist } + +constructor tmodulelist.create(adesigner: tdesigner); +begin + fdesigner:= adesigner; + inherited create(true); + fmethodnames:= tmethodnames.create; +end; + +procedure tmodulelist.designformdestroyed(const sender: tcustommseform); +var + po1: pmoduleinfoty; +begin + if not destroying then begin + po1:= findform(sender); + if po1 <> nil then begin + po1^.designform:= nil; + removemoduleinfo(po1); + // fdesigner.moduledestroyed(po1); + end; + end; +end; + +function tmodulelist.getitempo1(const index: integer): pmoduleinfoty; +begin + result:= @(tmoduleinfo(items[index]).info); +end; + +function tmodulelist.findmodule(const filename: msestring): pmoduleinfoty; +var + int1: integer; + po1: ppointeraty; + po2: pmoduleinfoty; +begin + result:= nil; + po1:= datapo; + for int1:= 0 to fcount-1 do begin + po2:= @tmoduleinfo(iobjectlink(po1^[int1]).getinstance).info; + if po2^.filename = filename then begin + result:= po2; + break; + end; + end; +end; + +function tmodulelist.findmodule(const amodule: tmsecomponent): pmoduleinfoty; +var + int1: integer; + po1: ppointeraty; + po2: pmoduleinfoty; +begin + result:= nil; + if amodule <> nil then begin + po1:= datapo; + for int1:= 0 to fcount-1 do begin + po2:= @tmoduleinfo(iobjectlink(po1^[int1]).getinstance).info; + if po2^.instance = amodule then begin + result:= po2; + break; + end; + end; + end; +end; + +function tmodulelist.findownermodule(const acomponent: tcomponent): pmoduleinfoty; +begin + result:= findmodulebyinstance(rootcomponent(acomponent)); +end; + +function tmodulelist.findmodulebyinstance(const ainstance: tcomponent): pmoduleinfoty; +var + int1: integer; + po1: ppointeraty; + po2: pmoduleinfoty; +begin + result:= nil; + po1:= datapo; + for int1:= 0 to fcount-1 do begin + po2:= @tmoduleinfo(iobjectlink(po1^[int1]).getinstance).info; + if po2^.instance = ainstance then begin + result:= po2; + break; + end; + end; +end; + +function tmodulelist.findmodule(const po: pmoduleinfoty): integer; +var + int1: integer; + po1: ppointeraty; +begin + result:= -1; + po1:= datapo; + for int1:= 0 to fcount-1 do begin + if @tmoduleinfo(iobjectlink(po1^[int1]).getinstance).info = po then begin + result:= int1; + break; + end; + end; +end; + +function tmodulelist.findmodulebyname(const name: string): pmoduleinfoty; +var + int1: integer; + po1: ppointeraty; +begin + result:= nil; + po1:= datapo; + for int1:= 0 to fcount-1 do begin + with tmoduleinfo(iobjectlink(po1^[int1]).getinstance) do begin + if info.instancevarname = name then begin + result:= @info; + break; + end; + end; + end; +end; + +function tmodulelist.findmoduleinstancebyname(const name: string): tcomponent; +var + po1: pmoduleinfoty; +begin + po1:= findmodulebyname(name); + if po1 <> nil then begin + result:= po1^.instance; + end + else begin + result:= nil; + end; +end; + +function tmodulelist.findmoduleinstancebyclass(const aclass: tclass): tcomponent; +var + int1: integer; + po1: ppointeraty; +begin + result:= nil; + po1:= datapo; + for int1:= 0 to fcount-1 do begin + with tmoduleinfo(iobjectlink(po1^[int1]).getinstance) do begin + if info.instance.classtype = aclass then begin + if not info.resolved then begin + exit; + end; + result:= info.instance; + break; + end; + end; + end; +end; + +function tmodulelist.findmodulebyclassname(aclassname: string): pmoduleinfoty; +var + int1: integer; + po1: ppointeraty; +begin + result:= nil; + po1:= datapo; + aclassname:= uppercase(aclassname); + for int1:= 0 to fcount-1 do begin + with tmoduleinfo(iobjectlink(po1^[int1]).getinstance) do begin + if uppercase(info.moduleclassname) = aclassname then begin + result:= @info; + break; + end; + end; + end; +end; + +function tmodulelist.newmodule(const ainherited: boolean; + const afilename: msestring; const amoduleclassname,ainstancevarname, + designmoduleclassname: string): tmoduleinfo; +var + po1: pmoduleinfoty; + inheritedbefore: boolean; +begin + po1:= findmodule(afilename); + if po1 <> nil then begin + delete(findmodule(po1)); + end; + result:= tmoduleinfo.create(fdesigner); + with result.info do begin + filename:= afilename; + instancevarname:= ainstancevarname; + moduleclassname:= amoduleclassname; + try + if ainherited then begin + po1:= fdesigner.getinheritedmodule(designmoduleclassname); + if po1 = nil then begin + raise exception.create(ansistring(actionsmo.c[ord(ac_ancestorfor)])+ + designmoduleclassname+ansistring(actionsmo.c[ord(ac_notfound)])); + end; + fdesigner.beginstreaming({po1}); + try + inheritedbefore:= des_inheritednewmodule in fdesigner.fstate; + include(fdesigner.fstate,des_inheritednewmodule); + instance:= fdesigner.copycomponent(po1^.instance,po1^.instance,false,true); + finally + if not inheritedbefore then begin + exclude(fdesigner.fstate,des_inheritednewmodule); + end; + fdesigner.endstreaming({po1}); + end; + moduleintf:= po1^.moduleintf; + designformclass:= po1^.designformclass; +{$warnings off} + tcomponent1(instance).setancestor(true); +{$warnings on} + additem(pointerarty(fdesigner.floadedsubmodules),instance); + fdesigner.fdescendentinstancelist.add(tmsecomponent(instance),po1^.instance, + fdesigner.fsubmodulelist); + tmsecomponent1(instance).factualclassname:= @moduleclassname; + tmsecomponent1(instance).fancestorclassname:= designmoduleclassname; +// initrootdescendent(instance); + tmsecomponent1(instance).setancestor(true); + end + else begin + instance:= createdesignmodule(@result.info,designmoduleclassname,@moduleclassname); + end; +{$warnings off} + tcomponent1(instance).setdesigning(true{$ifndef FPC},true{$endif}); +{$warnings on} + except + result.Free; + raise; + end; + end; +end; + +function tmodulelist.findmethodbyname(const name: string; + const atype: ptypeinfo; + const amodule: tmsecomponent): tmethod; + + procedure getmethod(ainfo: pmoduleinfoty; aname: string); + var + po1: pmethodinfoty; + bo1: boolean; + begin + if ainfo <> nil then begin + po1:= ainfo^.methods.findmethodbyname(aname,atype,bo1); + if po1 <> nil then begin + result.data:= po1^.address; + // result.code:= po1^.address; + // result.Data:= ainfo^.instance; + end +// else begin +// if bo1 then begin +// result.data:= pointer(1); //name found +// end; +// end; + end; + end; + +var + ar1: stringarty; +begin + result:= nullmethod; + if amodule <> nil then begin + getmethod(findmodule(amodule),name); + end + else begin + ar1:= nil; + splitstring(name,ar1,'.'); + if length(ar1) = 2 then begin + getmethod(findmodulebyname(ar1[0]),ar1[1]); + end; + end; +end; + +function tmodulelist.findmethodname(const method: tmethod; const comp: tcomponent): string; +var + int1: integer; + po1: ppointeraty; + po2: pmethodinfoty; +begin + result:= ''; + po1:= datapo; + for int1:= 0 to fcount - 1 do begin + with tmoduleinfo(iobjectlink(po1^[int1]).getinstance) do begin + po2:= info.methods.findmethod(method.data); + if po2 <> nil then begin + if info.components.find(comp) = nil then begin + result:= info.instance.actualclassname + '.' + po2^.name //foreign module + end + else begin + result:= po2^.name; + end; + break; + end; + end; + end; +end; + +function tmodulelist.delete(index: integer): pointer; +begin + fdesigner.moduledestroyed(itempo[index]); + result:= inherited delete(index); +end; + +function tmodulelist.removemoduleinfo(po: pmoduleinfoty): integer; +begin + result:= findmodule(po); + delete(result); +end; + +function tmodulelist.findform(aform: tcustommseform): pmoduleinfoty; +var + int1: integer; + po1: ppointeraty; +begin + result:= nil; + po1:= datapo; + for int1:= 0 to count - 1 do begin + with tmoduleinfo(iobjectlink(po1^[int1]).getinstance) do begin + if info.designform = aform then begin + result:= @info; + break; + end; + end; + end; +end; + +procedure tmodulelist.freeloadingstreams; +var + int1: integer; + po1: ppointeraty; +begin + po1:= datapo; + for int1:= 0 to count - 1 do begin + freeandnil(tmoduleinfo( + iobjectlink(po1^[int1]).getinstance).info.loadingstream); + end; +end; + +procedure tmodulelist.componentmodified(const acomponent: tobject); +var + int1: integer; + po1: ppointeraty; + comp: tcomponent; + +begin + if acomponent is tcomponent then begin + comp:= rootcomponent(tcomponent(acomponent)); + po1:= datapo; + for int1:= 0 to count - 1 do begin + with tmoduleinfo(iobjectlink(po1^[int1]).getinstance) do begin + if info.components.find(comp) <> nil then begin + if not info.modified then begin + info.modified:= true; + if info.designform <> nil then begin + tformdesignerfo(info.designform).updatecaption; + end; + end; + if (info.designform <> nil) and (fdesigner.fcomponentmodifying > 0) then begin + idesignnotification( + tformdesignerfo(info.designform)).itemsmodified(nil,comp); + end; + fdesigner.fdescendentinstancelist.modulemodified(@info); + break; + end; + end; + end; + end; +end; + +function tmodulelist.findmodulebycomponent(const acomponent: tcomponent): pmoduleinfoty; +var + int1: integer; + po1: ppointeraty; + po2: pmoduleinfoty; +// comp1: tcomponent; +begin + result:= nil; + po1:= datapo; +// comp1:= acomponent; +// while comp1 <> nil do begin + for int1:= 0 to fcount-1 do begin + po2:= @tmoduleinfo(iobjectlink(po1^[int1]).getinstance).info; + if po2^.components.find(acomponent) <> nil then begin + result:= po2; + break; + end; + end; +// if result <> nil then begin +// break; +// end; +// if cssubcomponent in comp1.componentstyle then begin +// comp1:= comp1.owner; +// end +// else begin +// comp1:= nil; +// end; +// end; +end; + +function tmodulelist.filenames: filenamearty; +var + int1: integer; + po1: ppointeraty; +begin + setlength(result,count); + po1:= datapo; + for int1:= 0 to high(result) do begin + result[int1]:= tmoduleinfo(iobjectlink(po1^[int1]).getinstance).info.filename; + end; +end; + +destructor tmodulelist.destroy; +begin + freeandnil(fmethodnames); + inherited; +end; + +{ tdesignformlist } + +function tdesignformlist.getitems(const index: integer): tmseform;//tformdesignerfo; +begin + result:= tmseform(inherited getitems(index)); +end; + +type + tselectiondestroytracker = class(tcomponent) + private + fselections: tdesignerselections; + protected + procedure notification(acomponent: tcomponent; + operation: toperation); override; + public + constructor create(const aselections: tdesignerselections); reintroduce; + end; + +{ tselectiondestroytracker } + +constructor tselectiondestroytracker.create( + const aselections: tdesignerselections); +var + int1: integer; +begin + fselections:= aselections; + with fselections do begin + for int1:= 0 to count - 1 do begin + items[int1].freenotification(self); + end; + end; + inherited create(nil); +end; + +procedure tselectiondestroytracker.notification(acomponent: tcomponent; + operation: toperation); +var + po1: pcomponentaty; + int1: integer; +begin + if operation = opremove then begin + po1:= fselections.datapo; + for int1:= 0 to fselections.count-1 do begin + if po1^[int1] = acomponent then begin + po1^[int1]:= nil; + end; + end; + end; + inherited; +end; + +{ tdesigner } + +constructor tdesigner.create; +begin + fobjformat:= of_default; + fselections:= tdesignerselections.create; + fmodules:= tmodulelist.create(self); + fsubmodulelist:= tsubmodulelist.create(self); + fdescendentinstancelist:= tdescendentinstancelist.create(self); + fdesignfiles:= tindexedfilenamelist.create; + ondesignchanged:= @componentmodified; + onfreedesigncomponent:= {$ifdef FPC}@{$endif}deletecomponent; + ondesignvalidaterename:= {$ifdef FPC}@{$endif}validaterename; + ondesignexception:= @handledesignexception; +end; + +destructor tdesigner.destroy; +begin + ondesignchanged:= nil; + fdescendentinstancelist.Free; + fsubmodulelist.Free; + inherited; + fcomponenteditor.Free; + fmodules.free; + fselections.Free; + fdesignfiles.Free; +end; + +procedure tdesigner.ClearSelection; +begin + //dummy +end; + +procedure tdesigner.addcomponent(const module: tmsecomponent; + const acomponent: tcomponent); +var + int1,int2: integer; + str1: string; + bo1: boolean; + classna: string; + ar1: componentarty; + +begin + if (des_pasting in fstate) and (acomponent.name <> '') then begin + addpastedcomponentname(acomponent); + end; + with registeredcomponents do begin + if (acomponent.ComponentState * [csancestor] = []) or + (acomponent.Owner = nil) or (acomponent.Owner = module) then begin //probaly inline + classna:= ''; + str1:= acomponent.Name; + acomponent.name:= ''; + if csinline in acomponent.componentstate then begin + if str1 <> '' then begin + classna:= str1; + str1:= str1 + '1'; + end; + end + else begin + classna:= acomponent.ClassName; + end; + if acomponent.Owner <> nil then begin + acomponent.owner.removecomponent(acomponent); + end; + module.InsertComponent(acomponent); + if str1 = '' then begin + str1:= classna + '1'; + end; + int1:= 1; + ar1:= fdescendentinstancelist.getdescendents(module); + additem(pointerarty(ar1),module); + repeat + bo1:= true; + for int2:= 0 to high(ar1) do begin + if ar1[int2].findcomponent(str1) <> nil then begin + inc(int1); + str1:= classna + inttostr(int1); + bo1:= false; + break; + end; + end; + until bo1; + acomponent.Name:= str1; + fmodules.findmodulebyinstance(module)^.components.add(acomponent); + designnotifications.ItemInserted(self,module,acomponent); + end + else begin + fmodules.findmodulebyinstance(module)^.components.add(acomponent); + end; +/////////// componentmodified(acomponent); + end; +end; + +function tdesigner.createnewcomponent(const module: tmsecomponent; + const aclass: tcomponentclass): tcomponent; +begin + result:= tcomponent(aclass.newinstance); + try + tcomponent1(result).setdesigning(true); + result.create(nil); + except + result.Free; + raise; + end; + with modules.findmodule(module)^.moduleintf^ do begin + if assigned(initnewcomponent) then begin + initnewcomponent(module,result); + end; + end; + addcomponent(module,result); +end; + +function tdesigner.createcurrentcomponent(const module: tmsecomponent): tcomponent; +begin + with registeredcomponents do begin + if selectedclass <> nil then begin + result:= createnewcomponent(module,selectedclass); + end + else begin + result:= nil; + end; + end; +end; + +function tdesigner.hascurrentcomponent: boolean; +begin + result:= registeredcomponents.selectedclass <> nil; +end; + +procedure tdesigner.notifydeleted(comp: tcomponent); +begin + if fnotifydeletedlock = 0 then begin + if comp is twidget then begin + tcomponent1(comp).getchildren({$ifdef FPC}@{$endif}notifydeleted,fnotifymodule); + end; + designnotifications.itemdeleted(idesigner(self),fnotifymodule,comp); + end; +end; + +procedure tdesigner.deleteselection(adoall: boolean); +var + int1: integer; + comp1,comp2: tcomponent; + po1: pmoduleinfoty; + destroytracker: tselectiondestroytracker; + +begin + destroytracker:= tselectiondestroytracker.create(self.fselections); + try + for int1:= 0 to fselections.count - 1 do begin + comp1:= fselections[int1]; + if comp1 <> nil then begin + comp2:= comp1.owner; + po1:= fmodules.findmodulebycomponent(comp1); + if po1 <> nil then begin + fnotifymodule:= po1^.instance; + notifydeleted(comp1); + end; + inc(fnotifydeletedlock); + try + comp1.free; + finally + dec(fnotifydeletedlock); + end; + fmodules.componentmodified(comp2); + end; + end; + fselections.clear; + selectionchanged; + finally + destroytracker.free; + end; +end; + +procedure tdesigner.componentdestroyed(const acomponent: tcomponent; + const module: pmoduleinfoty); +begin + if fnotifydeletedlock = 0 then begin +// designnotifications.itemdeleted(idesigner(self),module^.instance,acomponent); + if fselections.remove(acomponent) >= 0 then begin + selectionchanged; + end; + end; +end; + +procedure tdesigner.deletecomponent(const acomponent: tcomponent); +var + po1: pmoduleinfoty; + notifymodulebefore: tmsecomponent; +begin + if acomponent <> nil then begin + fmodules.componentmodified(acomponent); + po1:= fmodules.findmodulebycomponent(acomponent); + if po1 <> nil then begin + notifymodulebefore:= fnotifymodule; + fnotifymodule:= po1^.instance; + try + notifydeleted(acomponent); +// designnotifications.ItemDeleted(idesigner(self), +// fmodules.findmodulebycomponent(acomponent)^.instance,acomponent); + finally + fnotifymodule:= notifymodulebefore; + end; + end; + acomponent.free; + end; +end; + +{$ifdef mse_nomethodswap} +procedure tdesigner.setmethodproperty(reader: treader; + instance: tpersistent; + propinfo: ppropinfo; const themethodname: string; + var handled: boolean); +var + m1: tmethod; + po1: pmethodinfoty; +begin + po1:= floadingmodulepo^.methods.findmethodbyname(themethodname); + if po1 = nil then begin + m1:= createmethod(themethodname,nil,nil); + end + else begin + m1.data:= po1^.address; + m1.code:= nil; + end; + setmethodprop(instance,propinfo,m1); + handled:= true; +end; +{$else} +procedure tdesigner.findmethod(reader: treader; const amethodname: string; + var address: pointer; var error: boolean); +var + method: tmethod; + po1: pmethodinfoty; +begin + if error then begin + po1:= floadingmodulepo^.methods.findmethodbyname(amethodname); + if po1 = nil then begin + method:= createmethod(amethodname,nil,nil); + address:= method.data; + end + else begin + address:= po1^.address; + end; + error:= false; + end; +end; +{$endif} +{ +procedure tdesigner.findmethod2(Reader: TReader; const aMethodName: string; + var Address: Pointer; var Error: Boolean); +var + po2: pmethodinfoty; +begin + if error then begin + error:= false; //ignore new method error + po2:= flookupmodule^.methods.findmethodbyname(amethodname); + if po2 <> nil then begin + address:= po2^.address; + end; + end; +end; +} +function tdesigner.getinheritedmodule(const aclassname: string): pmoduleinfoty; +begin + result:= fmodules.findmodulebyclassname(aclassname); + if result = nil then begin + if assigned(fongetmoduletypefile) then begin + fongetmoduletypefile(aclassname); + end; + result:= fmodules.findmodulebyclassname(aclassname); + end; +end; + +procedure tdesigner.findcomponentclass(Reader: TReader; const aClassName: string; + var ComponentClass: TComponentClass); + +var + po1: pmoduleinfoty; +begin + fsubmoduleinfopo:= nil; + ffindcompclasstag:= fcreatecomponenttag+1; + if componentclass = nil then begin + po1:= getinheritedmodule(aclassname); + if po1 <> nil then begin + fsubmoduleinfopo:= po1; //used in createcomponent + ffindcompclasstag:= fcreatecomponenttag+1; + componentclass:= tcomponentclass(po1^.instance.classtype); + end; + end; +end; + +procedure tdesigner.ancestornotfound(Reader: TReader; const ComponentName: string; + ComponentClass: TPersistentClass; var Component: TComponent); +begin + fsubmoduleinfopo:= nil; //reset for createcomponent + component:= fmodules.findmoduleinstancebyclass(componentclass); + if component = nil then begin + component:= mseclasses.findancestorcomponent(reader,componentname); + end; +end; + +function tdesigner.findancestorcomponent(const acomponent: tcomponent): tcomponent; +var +// ancestormodule: tmsecomponent; + comp1: tcomponent; + ar1: stringarty; + int1: integer; +begin + result:= nil; + if acomponent.owner = nil then begin //module + result:= descendentinstancelist.findancestor(acomponent); + end + else begin //embedded component + ar1:= nil; + result:= nil; + comp1:= acomponent; + while (comp1.owner <> nil) and + (comp1.componentstate * [csinline,csancestor] <> [csinline]) do begin + if comp1.name = '' then begin + exit; + end; + additem(ar1,comp1.name); + comp1:= comp1.owner; + end; + if (comp1.owner <> nil) and + (csancestor in comp1.owner.componentstate) then begin + //inherited submodule + additem(ar1,comp1.name); + comp1:= comp1.owner; + end; + result:= descendentinstancelist.findancestor(comp1); + for int1:= high(ar1) downto 0 do begin + if result = nil then begin + exit; + end; + result:= result.findcomponent(ar1[int1]); + end; + end; +end; + +procedure tdesigner.createcomponent1(Reader: TReader; + ComponentClass: TComponentClass; var Component: TComponent); +var + asubmoduleinfopo: pmoduleinfoty; + int1: integer; +begin + inc(fcreatecomponenttag); + if fcreatecomponenttag <> ffindcompclasstag then begin + fsubmoduleinfopo:= nil; //invalid + end; + asubmoduleinfopo:= fsubmoduleinfopo; //can be recursive + if asubmoduleinfopo <> nil then begin + fsubmoduleinfopo:= nil; +// component:= copycomponent(asubmoduleinfopo^.instance, +// asubmoduleinfopo^.instance,false,false); + component:= copycomponent(asubmoduleinfopo^.instance, + asubmoduleinfopo^.instance,false,true); + reader.root.insertcomponent(component); + initinline(component); + if (des_inheritednewmodule in fstate) then begin + tcomponent1(component).setancestor(true); + end + else begin + for int1:= 0 to component.componentcount - 1 do begin + tcomponent1(component.components[int1]).setancestor(true); + end; + end; + if (submodulecopy = 0) and + (reader.root.componentstate * [csinline{,csancestor}] = []) then begin + additem(pointerarty(floadedsubmodules),component); + fdescendentinstancelist.add(tmsecomponent(component), + asubmoduleinfopo^.instance,fsubmodulelist); + end; + end; + if reader is tasinheritedreader then begin + tasinheritedreader(reader).newcomp:= true; + end; +end; + +function tdesigner.createcomponent: tcreatecomponentevent; +begin + fsubmoduleinfopo:= nil; //reset + result:= {$ifdef FPC}@{$endif}createcomponent1; +end; + +{$ifndef mse_nomethodswap} +procedure tdesigner.docopymethods(const source,dest: tcomponent; + const force: boolean); + procedure doprops(const source,desc: tobject); + var + ar1: propinfopoarty; + int1: integer; + method1: tmethod; + begin + ar1:= getpropinfoar(desc); + for int1:= 0 to high(ar1) do begin + case ar1[int1]^.proptype^.kind of + tkmethod: begin + method1:= getmethodprop(source,ar1[int1]); + if {force or }(method1.code <> nil) or (method1.data <> nil) then begin + setmethodprop(dest,ar1[int1],method1); + end; + end; + { + tkclass: begin + obj1:= getobjectprop(source,ar1[int1]); + if (obj1 <> nil) and (not (obj1 is tcomponent) or + (cssubcomponent in tcomponent(obj1).componentstyle)) then begin + obj2:= getobjectprop(dest,ar1[int1]); + if obj2 <> nil then begin + doprops(obj1,obj2); + if obj1 is tpersistentarrayprop then begin + int3:= tpersistentarrayprop(obj1).count; + if int3 > tpersistentarrayprop(obj2).count then begin + int3:= tpersistentarrayprop(obj2).count; + end; + for int2:= 0 to int3 - 1 do begin + doprops(tpersistentarrayprop(obj1).items[int2], + tpersistentarrayprop(obj2).items[int2]); + end; + end; + end; //collections? + end; + end; + } + end; + end; + end; + +var + comp1,comp2: tcomponent; + int1: integer; + bo1: boolean; +begin + bo1:= setloading(dest,true); + try + doprops(source,dest); + finally + setloading(dest,bo1); + end; + for int1:= 0 to source.componentcount - 1 do begin + comp1:= source.components[int1]; + comp2:= dest.findcomponent(comp1.name); + if (comp2 <> nil) and + (comp1.classtype = comp2.classtype) then begin + docopymethods(comp1,comp2,force); + end; + end; +end; +{$endif} +{ +procedure tdesigner.docopymethods(const source, dest: tcomponent; + const force: boolean); +var + propar: propinfopoarty; + po1: ^ppropinfo; + int1: integer; + method,method1: tmethod; + comp1,comp2: tcomponent; +begin + propar:= getpropinfoar(source); + po1:= pointer(propar); + for int1:= 0 to high(propar) do begin + if po1^^.proptype^.kind = tkmethod then begin + method:= getmethodprop(source,po1^); + method1:= getmethodprop(dest,po1^); + if (method1.code <> method.code) or (method1.data <> method.data) then begin + setmethodprop(dest,po1^,method); + end; + end; + inc(po1); + end; + for int1:= 0 to source.ComponentCount - 1 do begin + comp1:= source.Components[int1]; + comp2:= dest.FindComponent(comp1.name); + if (comp2 <> nil) and (comp1.ClassType = comp2.ClassType) then begin + docopymethods(comp1,comp2,force); + end; + end; +end; +} +{ +procedure tdesigner.dorefreshmethods(const descendent,newancestor, + oldancestor: tcomponent); + procedure doprops(const desc,newan,oldan: tobject); + var + ar1: propinfopoarty; + int1,int2,int3: integer; + method1,method2,method3: tmethod; + obj1,obj2,obj3: tobject; + begin + ar1:= getpropinfoar(desc); + for int1:= 0 to high(ar1) do begin + case ar1[int1]^.proptype^.kind of + tkmethod: begin + method2:= getmethodprop(newan,ar1[int1]); + if (method2.code <> nil) or (method2.data <> nil) then begin + setmethodprop(desc,ar1[int1],method2); + //refresh ancestor value, it is not possible to override methods + end; + end; + tkclass: begin + obj1:= getobjectprop(desc,ar1[int1]); + obj2:= getobjectprop(newan,ar1[int1]); + obj3:= getobjectprop(oldan,ar1[int1]); + if (obj1 <> nil) and (not (obj1 is tcomponent) or + (cssubcomponent in tcomponent(obj1).componentstyle)) then begin + doprops(obj1,obj2,obj3); + if obj1 is tpersistentarrayprop then begin + int3:= tpersistentarrayprop(obj1).count; + if int3 > tpersistentarrayprop(obj2).count then begin + int3:= tpersistentarrayprop(obj2).count; + end; + if int3 > tpersistentarrayprop(obj3).count then begin + int3:= tpersistentarrayprop(obj3).count; + end; + for int2:= 0 to int3 - 1 do begin + doprops(tpersistentarrayprop(obj1).items[int2], + tpersistentarrayprop(obj2).items[int2], + tpersistentarrayprop(obj3).items[int2]); + end; + end; + end; + end; + end; + end; + end; + +var + comp1,comp2,comp3: tcomponent; + int1: integer; +begin + doprops(descendent,newancestor,oldancestor); + for int1:= 0 to descendent.componentcount - 1 do begin + comp1:= descendent.components[int1]; + comp2:= newancestor.findcomponent(comp1.name); + comp3:= oldancestor.findcomponent(comp1.name); + if (comp2 <> nil) and (comp3 <> nil) and + (comp1.classtype = comp2.classtype) and + (comp1.classtype = comp3.classtype) then begin + dorefreshmethods(comp1,comp2,comp3); + end; + end; +end; +} +{ +procedure tdesigner.forallmethprop(child: tcomponent); +begin + with fforallmethpropsinfo do begin + forallmethodproperties(child,dat,proc,dochi); + end; +end; +} + +procedure tdesigner.forallmethodproperties(const aroot: tcomponent; + const ainstance: tobject; + const data: pointer; const aproc: propprocty; + const dochildren: boolean); +var + ar1: propinfopoarty; + ar2: componentarty; + int1,int2: integer; + obj1: tobject; + bo1{,bo2}: boolean; +// rootbefore: tcomponent; +begin + if ainstance is tcomponent then begin + bo1:= not (csloading in tcomponent(ainstance).componentstate); + if bo1 then begin + setloading(tcomponent(ainstance),true); + end; + end + else begin + bo1:= false; + end; + ar1:= getpropinfoar(ainstance); + for int1:= 0 to high(ar1) do begin + case ar1[int1]^.proptype^.kind of + tkmethod: begin + aproc(ainstance,data,ar1[int1]); + end; + tkclass: begin + obj1:= getobjectprop(ainstance,ar1[int1]); + if issubprop(obj1) then begin + forallmethodproperties(aroot,obj1,data,aproc,dochildren); + if obj1 is tpersistentarrayprop then begin + with tpersistentarrayprop(obj1) do begin + for int2:= 0 to count - 1 do begin + forallmethodproperties(aroot,items[int2],data,aproc,dochildren); + end; + end; + end + else begin + if obj1 is tcollection then begin + with tcollection(obj1) do begin + for int2:= 0 to count - 1 do begin + forallmethodproperties(aroot,items[int2],data,aproc,dochildren); + end; + end; + end; + end; + end; + end; + end; + end; + if (ainstance is tcomponent) then begin + ar2:= getcomponentchildren(tcomponent(ainstance),aroot,true); + for int1:= 0 to high(ar2) do begin + forallmethodproperties(aroot,ar2[int1],data,aproc,dochildren); + end; + end; + if bo1 then begin + setloading(tcomponent(ainstance),false); + end; +end; + +procedure tdesigner.componentevent(const event: tcomponentevent); +begin + with event do begin + if tag = ord(me_componentmodified) then begin + designnotifications.ItemsModified(idesigner(self),sender); + end; + end; + inherited; +end; + +function tdesigner.getmodulex(const amodule: tmsecomponent): integer; +var + po1: pmoduleinfoty; +begin + po1:= fmodules.findmodule(tmsecomponent(amodule)); + if po1 <> nil then begin + result:= po1^.designformintf.getmodulepos_x(); + end + else begin + result:= 0; + end; +end; + +function tdesigner.getmoduley(const amodule: tmsecomponent): integer; +var + po1: pmoduleinfoty; +begin + po1:= fmodules.findmodule(tmsecomponent(amodule)); + if po1 <> nil then begin + result:= po1^.designformintf.getmodulepos_y(); + end + else begin + result:= 0; + end; +end; + +procedure tdesigner.setmodulex(const amodule: tmsecomponent; avalue: integer); +var + po1: pmoduleinfoty; +begin + po1:= fmodules.findmodule(tmsecomponent(amodule)); + if po1 <> nil then begin + po1^.designformintf.setmodulepos_x(avalue); +// po1^.designform.bounds_x:= avalue; + end; +end; + +procedure tdesigner.setmoduley(const amodule: tmsecomponent; avalue: integer); +var + po1: pmoduleinfoty; +begin + po1:= fmodules.findmodule(tmsecomponent(amodule)); + if po1 <> nil then begin + po1^.designformintf.setmodulepos_y(avalue); + end; +end; + +procedure tdesigner.modulesizechanged(const amodule: tmsecomponent); +var + po1: pmoduleinfoty; +begin + po1:= fmodules.findmodule(tmsecomponent(amodule)); + if po1 <> nil then begin +{$warnings off} + twidget1(po1^.designform).sizechanged; +{$warnings on} + end; +end; + +function tdesigner.checkmodule(const filename: msestring): pmoduleinfoty; +begin + result:= fmodules.findmodule(filename); + if result = nil then begin + raise exception.Create(ansistring(actionsmo.c[ord(ac_module)]+ + filename+actionsmo.c[ord(ac_notfound)])); + end; +end; + +procedure tdesigner.beginstreaming({const amodule: pmoduleinfoty}); +var + i1: int32; +begin + if fstreaming = 0 then begin + for i1:= 0 to fmodules.count - 1 do begin + with fmodules[i1]^ do begin + if designform <> nil then begin + tformdesignerfo(designform).beginstreaming; + end; + end; + end; + end; + inc(fstreaming); +{ + with amodule^ do begin + if designform <> nil then begin + tformdesignerfo(designform).beginstreaming; + end; + end; +} +end; + +procedure tdesigner.endstreaming({const amodule: pmoduleinfoty}); +var + i1: int32; +begin + dec(fstreaming); + if fstreaming = 0 then begin + for i1:= 0 to fmodules.count - 1 do begin + with fmodules[i1]^ do begin + if designform <> nil then begin + tformdesignerfo(designform).endstreaming; + end; + end; + end; + end; +{ + with amodule^ do begin + if designform <> nil then begin + tformdesignerfo(designform).endstreaming; + end; + end; +} +end; + +procedure tdesigner.modulechanged(const amodule: pmoduleinfoty); +begin + componentmodified(amodule^.instance); +end; + +procedure tdesigner.dotouch(const amodule: pmoduleinfoty); +begin + fallsaved:= false; + with amodule^ do begin + modified:= true; + designformintf.updatecaption + end; +end; + +procedure tdesigner.touch(const amodule: tmsecomponent); +begin + dotouch(modules.findmodule(amodule)); +end; + +procedure tdesigner.touchall; +var + int1: integer; +begin + for int1:= 0 to modules.count - 1 do begin + dotouch(modules.itempo[int1]); + end; +end; + +procedure tdesigner.beginskipall; +begin + if fskipall = 0 then begin + exclude(fstate,des_skipall); + end; + inc(fskipall); +end; + +procedure tdesigner.endskipall; +begin + dec(fskipall); + if fskipall = 0 then begin + exclude(fstate,des_skipall); + end; +end; + +procedure tdesigner.handledesignexception(const sender: tobject); +var + exceptobj: tobject; + mstr1: msestring; + res1: modalresultsty; +begin + exceptobj:= exceptobject; + if exceptobj is exception then begin + if not (exceptobj is eabort) then begin + if not application.ismainthread then begin + application.showasyncexception(exception(exceptobj)); + end + else begin + if not (des_skipall in fstate) then begin + mstr1:= msestring(exception(exceptobj).message); + res1:= [mr_skip,mr_cancel]; + if fskipall > 0 then begin + include(res1,mr_skipall); + end; + case showmessage(mstr1,'Exception'{$ifdef FPC}, + [mr_skip,mr_skipall,mr_cancel],mr_skip,[],0,lineend+ + getexceptiontext(exceptobj, + exceptaddr,exceptframecount,exceptframes){$endif}) of + mr_skipall: begin + include(fstate,des_skipall); + end; + mr_cancel: begin + abort; + end; + end; + end; + end; + end; + end; +end; + +function tdesigner.changemodulename(const filename: msestring; + const avalue: string): string; +var + po1: pmoduleinfoty; + str1: string; +begin + po1:= checkmodule(filename); + str1:= po1^.instance.name; + po1^.instance.Name:= avalue; + result:= po1^.instance.name; + if result <> str1 then begin + modulechanged(po1); + end; +end; + +function tdesigner.componentcanedit: boolean; +begin + result:= (fcomponenteditor <> nil) and (cs_canedit in fcomponenteditor.state); +end; + +procedure tdesigner.checkident(const aname: string); +begin + if not isvalidident(aname) or (aname = '') then begin + raise exception.Create(ansistring(actionsmo.c[ord(ac_invalidname)])+ + aname+'".'); + end; +end; + +function tdesigner.changemoduleclassname(const filename: msestring; + const avalue: string): string; +var + po1: pmoduleinfoty; +begin + po1:= checkmodule(filename); + checkident(avalue); + designnotifications.moduleclassnamechanging(idesigner(self), + po1^.instance,avalue); + po1^.moduleclassname:= avalue; + result:= po1^.moduleclassname; + modulechanged(po1); +end; + +function tdesigner.changeinstancevarname(const filename: msestring; const avalue: string): string; +var + po1: pmoduleinfoty; +begin + po1:= checkmodule(filename); + checkident(avalue); + designnotifications.instancevarnamechanging(idesigner(self),po1^.instance,avalue); + po1^.instancevarname:= avalue; + result:= po1^.instancevarname; + modulechanged(po1); +end; + +function tdesigner.checksubmodule(const ainstance: tcomponent; + out aancestormodule: pmoduleinfoty): boolean; +begin + aancestormodule:= modules.findmodule( + fdescendentinstancelist.findancestor(ainstance)); + result:= aancestormodule <> nil; +end; + +procedure tdesigner.componentmodified(const component: tobject; + const apropname: string = ''; const apropindex: int32 = -1); +begin + if fformloadlocklevel = 0 then begin + if apropname <> '' then begin + objectinspectorfo.selectprop(component,apropname,apropindex); + end; + fallsaved:= false; + if component <> nil then begin + fmodules.componentmodified(component); + end; + if fcomponentmodifying = 0 then begin + postcomponentevent( + tcomponentevent.create(component,ord(me_componentmodified),false)); + end + end; +end; + +procedure tdesigner.begincomponentmodify; +begin + inc(fcomponentmodifying); +end; + +procedure tdesigner.endcomponentmodify; +begin + dec(fcomponentmodifying); +end; + +procedure tdesigner.beginpasting; +begin + include(fstate,des_pasting); +end; + +procedure tdesigner.endpasting; +begin + exclude(fstate,des_pasting); +end; + +function tdesigner.copycomponent(const source: tmsecomponent; + const root: tmsecomponent; const asinherited: boolean; + const noloading: boolean): tmsecomponent; +var + po1,po2: pmoduleinfoty; + ar1: msecomponentarty; + comp1: tmsecomponent; + int1: integer; + stream1: tmemorystream; + stream2: tstream; + reader: treader; + writer: twritermse; + posbefore: integer; +begin + {$ifdef mse_debugcopycomponent} + dumpcomponent(source,'***designer copycomponent source: '+source.name+' root: '+ + debugcompname(root)); + {$endif} + comp1:= source; + setlength(ar1,1); + ar1[0]:= source; + while true do begin + comp1:= fdescendentinstancelist.findancestor(comp1); + if comp1 = nil then begin + break; + end; + additem(pointerarty(ar1),comp1); + end; + setlength(ar1,high(ar1)+2); //dummy ancestor + beginsubmodulecopy; + if root <> nil then begin + po1:= fmodules.findmodule(root); + if po1 <> nil then begin + beginstreaming({po1}); + {$ifndef mse_nomethodswap} + buildmethodtable(po1); + {$endif} + end; + end + else begin + po1:= nil; + end; + fdescendentinstancelist.beginstreaming(po1); +// doswapmethodpointers(source,false); +{$ifndef mse_nomethodswap} + for int1:= 0 to high(ar1)-1 do begin + doswapmethodpointers(ar1[int1],false); + end; +{$endif} + try + if not noloading then begin + begingloballoading; + end; + result:= tmsecomponent(source.newinstance); +{$warnings off} + tcomponent1(result).setdesigning(true); +{$warnings on} + result.create(nil); + stream1:= tmemorystream.create; + try + for int1:= high(ar1)-1 downto 0 do begin + stream2:= nil; + if high(ar1) < 2 then begin //has no ancestors, loading stream can be used ???? + po2:= fmodules.findmodule(root); + if po2 <> nil then begin + stream2:= po2^.loadingstream; //needs possibly fixup + end; + end; + if stream2 = nil then begin + stream2:= stream1; + stream1.clear; + writer:= twritermse.create(stream1,4096,false); + try + {$ifdef mse_nomethodswap} + writer.onwritemethodproperty:= {$ifdef FPC}@{$endif}writedesignmethod; + {$endif} + writer.onfindancestor:= {$ifdef FPC}@{$endif}findancestor; + writer.writedescendent(ar1[int1],ar1[int1+1]); + result.name:= ar1[int1].name; + finally + writer.free; + end; + end; + {$ifdef mse_debugcopycomponent} + debugstreamout(stream1,'*source '+inttostr(int1)+ ': '+ + debugcompname(ar1[int1])+ + ' ancestor: '+debugcompname(ar1[int1+1])); + {$endif} + posbefore:= stream2.position; + stream2.position:= 0; + if asinherited then begin + reader:= tasinheritedreader.create(stream2,4096,true); + end + else begin + reader:= treader.create(stream2,4096); + end; + try + {$ifdef mse_nomethodswap} + reader.onsetmethodproperty:= + {$ifdef FPC}@{$endif}fdescendentinstancelist.setrefreshmethod; + {$endif} + reader.onfindcomponentclass:= {$ifdef FPC}@{$endif}findcomponentclass; + reader.oncreatecomponent:= createcomponent(); + reader.onancestornotfound:= {$ifdef FPC}@{$endif}ancestornotfound; + {$ifdef mse_debugcopycomponent} + debugwriteln('*read '+inttostr(int1)+' '+ + debugcompname(ar1[int1])+' ancestor: '+debugcompname(ar1[int1+1])); + {$endif} + reader.readrootcomponent(result); + finally + reader.free; + stream2.position:= posbefore; + end; + end; + finally + stream1.free; + end; + tmsecomponent1(result).factualclassname:= + tmsecomponent1(source).factualclassname; + (* + result:= tmsecomponent(mseclasses.copycomponent(source,nil, + {$ifdef FPC}@{$endif}findancestor, + {$ifdef FPC}@{$endif}findcomponentclass, + {$ifdef FPC}@{$endif}createcomponent, + {$ifdef FPC}@{$endif}ancestornotfound)); + *) +{$ifndef mse_nomethodswap} + if po1 = nil then begin + docopymethods(source,result,false); + end; + doswapmethodpointers(result,true); +{$endif} + if not noloading then begin + notifygloballoading; + end; + finally + if not noloading then begin + endgloballoading; + end; +// doswapmethodpointers(source,true); +{$ifndef mse_nomethodswap} + for int1:= 0 to high(ar1)-1 do begin + doswapmethodpointers(ar1[int1],true); + end; +{$endif} + fdescendentinstancelist.endstreaming; + endsubmodulecopy; + if po1 <> nil then begin + endstreaming({po1}); + {$ifndef mse_nomethodswap} + releasemethodtable(po1); + {$endif} + end; + end; + {$ifdef mse_debugcopycomponent} + dumpcomponent(result,'*endcopycomp source: '+source.name+' result:'); + {$endif} +end; + +procedure tdesigner.revert(const acomponent: tcomponent); +var + comp1: tcomponent; +// msecomp1: tmsecomponent; +// po1: pancestorinfoty; + po2: pmoduleinfoty; + po4: pmoduleinfoty; +{$ifndef mse_nomethodswap} + po3: pointer; +{$endif} + bo1,bo2,bo3: boolean; + pt1: pointty; + delcomps: componentarty; +begin + po2:= fmodules.findmodule(tmsecomponent(rootcomponent(acomponent))); + bo3:= (csinline in acomponent.componentstate) and + (acomponent.owner <> nil) and + not (csancestor in acomponent.owner.componentstate); //submodule + if bo3 or (csancestor in acomponent.componentstate) then begin + comp1:= findancestorcomponent(acomponent); + if comp1 <> nil then begin + beginsubmodulecopy; + begingloballoading; + po4:= fmodules.findownermodule(comp1); +{$ifndef mse_nomethodswap} + po3:= po4^.methods.createmethodtable(getancestormethods(po4)); +{$endif} + fdescendentinstancelist.beginstreaming(po4); +{$ifndef mse_nomethodswap} + doswapmethodpointers(acomponent,false); + doswapmethodpointers(comp1,false); +{$endif} + try + bo1:= false; + bo2:= false; + if bo3 then begin //submodule + bo1:= acomponent is twidget; + if bo1 then begin + pt1:= twidget(acomponent).pos; + end + else begin + bo2:= isdatasubmodule(acomponent); + if bo2 then begin + pt1:= getcomponentpos(acomponent); + end; + end; + end; + refreshancestor(delcomps,acomponent,comp1,comp1,true, + {$ifdef FPC}@{$endif}findancestor, + {$ifdef FPC}@{$endif}findcomponentclass, + createcomponent(), + {$ifdef mse_nomethodswap} + {$ifdef FPC}@{$endif}fdescendentinstancelist.setrefreshmethod, + {$ifdef FPC}@{$endif}writedesignmethod + {$else} + nil,po3,po3 + {$endif} + ); +// docopymethods(comp1,acomponent,true); + if bo1 then begin + twidget(acomponent).pos:= pt1; //restore insert position + end + else begin + if bo2 then begin + setcomponentpos(acomponent,pt1); //restore insert position + end; + end; + notifygloballoading; + finally + endsubmodulecopy; + endgloballoading; + {$ifndef mse_nomethodswap} + po4^.methods.releasemethodtable; + doswapmethodpointers(acomponent,true); + doswapmethodpointers(comp1,true); + {$endif} + fdescendentinstancelist.endstreaming; + end; + end; + end; + freecomponents(delcomps); + componentmodified(po2^.instance); +end; + +function tdesigner.getreferencingmodulenames(const amodule: pmoduleinfoty): stringarty; +var + int1,int2: integer; + po1: pancestorinfoaty; + str1: string; + po2: pmoduleinfoty; + bo1: boolean; +begin + result:= nil; + for int1:= 0 to fmodules.count - 1 do begin + with fmodules[int1]^ do begin + for int2:= 0 to high(referencedmodules) do begin + if referencedmodules[int2] = amodule^.instance.Name then begin + additem(result,instance.name); + end; + end; + end; + end; + po1:= fdescendentinstancelist.datapo; + for int1:= 0 to fdescendentinstancelist.count - 1 do begin + with po1^[int1] do begin + if ancestor = amodule^.instance then begin + po2:= fmodules.findmodulebycomponent(descendent); + if po2 <> nil then begin + str1:= po2^.instance.name; + bo1:= false; + for int2:= high(result) downto 0 do begin + if result[int2] = str1 then begin + bo1:= true; + break; + end; + end; + if not bo1 then begin + additem(result,str1); + end; + end; + end; + end; + end; +end; + +function tdesigner.checkcanclose(const amodule: pmoduleinfoty; + out references: string): boolean; +begin + references:= concatstrings(getreferencingmodulenames(amodule),','); + result:= references = ''; +end; + +procedure tdesigner.findancestor(Writer: TWriter; Component: TComponent; + const aName: string; var Ancestor, RootAncestor: TComponent); +var + str1: string; + comp1: tcomponent; +begin + if (csinline in component.ComponentState) then begin + if (ancestor = nil) then begin + ancestor:= fdescendentinstancelist.findancestor(component); + rootancestor:= ancestor; + end; + end; + if csancestor in component.componentstate then begin + if ancestor = nil then begin + str1:= aname; + comp1:= component.owner; + while comp1 <> nil do begin + if csinline in comp1.componentstate then begin + break; + end; + str1:= comp1.name+'.'+str1; + comp1:= comp1.owner; + end; + if comp1 <> nil then begin + comp1:= fdescendentinstancelist.findancestor(comp1); + if comp1 <> nil then begin + ancestor:= findnestedcomponent(comp1,str1); + end; + end; + end; + end + else begin + if not (csinline in component.componentstate) and + (component.owner <> nil) and (csancestor in component.owner.componentstate) then begin + ancestor:= nil; //has name duplicate + end; + end; +end; + +procedure tdesigner.getmethodinfo(const method: tmethod; out moduleinfo: pmoduleinfoty; + out methodinfo: pmethodinfoty); +var + int1: integer; +begin +// moduleinfo:= fmodules.findmodulebyinstance(tcomponent(method.data)); +// if moduleinfo <> nil then begin +// with moduleinfo^.methods do begin +// methodinfo:= findmethod(method.data); +// end; +// end +// else begin + methodinfo:= nil; + for int1:= 0 to fmodules.count - 1 do begin + methodinfo:= fmodules[int1]^.methods.findmethod(method.data); + if methodinfo <> nil then begin + moduleinfo:= fmodules[int1]; + break; + end; + end; +// end; +end; + +function tdesigner.isownedmethod(const root: tcomponent; + const method: tmethod): boolean; +var + po1: pmoduleinfoty; +begin + result:= false; + po1:= fmodules.findmodulebyinstance(root); + if po1 <> nil then begin + result:= po1^.methods.findmethod(method.data) <> nil; + end; +end; + +procedure tdesigner.changemethodname(const method: tmethod; newname: string; + const atypeinfo: ptypeinfo); +var + po1: pmethodinfoty; + po2: pmoduleinfoty; + oldname: string; +begin + if not isvalidident(newname) then begin + raise exception.Create(ansistring(actionsmo.c[ord(ac_invalidmethodname)])+ + ' '''+newname+'''.'); + end; + getmethodinfo(method,po2,po1); + if po2 = nil then begin + raise exception.Create(ansistring(actionsmo.c[ord(ac_modulenotfound)])); + end; + if po1 = nil then begin + raise exception.Create(ansistring(actionsmo.c[ord(ac_methodnotfound)])); + end; + oldname:= po1^.name; + po1^.name:= newname; + fmodules.fmethodnames.setdata(ptruint(po1^.address),newname); + po2^.modified:= true; + designnotifications.methodnamechanged(fdesigner,po2^.instance,newname,oldname,atypeinfo); +end; + +function tdesigner.createmethod(const aname: string; const module: tmsecomponent; + const atype: ptypeinfo): tmethod; +var + po1: pmoduleinfoty; +begin + if module = nil then begin + po1:= floadingmodulepo; + end + else begin + po1:= fmodules.findmodulebyinstance(module); + end; + if po1 <> nil then begin + with po1^.methods do begin + inc(methodaddressdummy); + if methodaddressdummy < 256 then begin + methodaddressdummy:= 256; //0..255 -> special purpose + end; +// result.code:= pointer(methodaddressdummy); +// result.Data:= po1^.instance; + result.data:= pointer(methodaddressdummy); + result.code:= nil; + addmethod(aname,result.data,atype); + end; + if atype <> nil then begin + designnotifications.methodcreated(idesigner(self),module,aname,atype); + end; + end + else begin + result:= nullmethod; + end; +end; + +procedure tdesigner.checkmethod(const method: tmethod; const aname: string; + const module: tmsecomponent; const atype: ptypeinfo); +var + po1: pmethodinfoty; + po2: pmoduleinfoty; +begin + getmethodinfo(method,po2,po1); + if (po1 <> nil) and (po2 <> nil) and (atype <> nil) then begin + designnotifications.methodcreated(idesigner(self),module,aname,atype); + end; +end; + +procedure tdesigner.setactivemodule(const adesignform: tcustommseform); +var + po1: pmoduleinfoty; +begin + if adesignform <> nil then begin + po1:= fmodules.findform(adesignform); + end + else begin + po1:= nil; + end; + floadingmodulepo:= po1; + if po1 <> factmodulepo then begin + if factmodulepo <> nil then begin + designnotifications.moduledeactivated(idesigner(self),factmodulepo^.instance); + end; + if po1 <> nil then begin + factmodulepo:= po1; +// checkobjectinspector; //ev. create + designnotifications.moduleactivated(idesigner(self),factmodulepo^.instance); + end + else begin + factmodulepo:= nil; + end; + end; +end; + +function tdesigner.sourcenametoformname(const aname: filenamety): filenamety; +begin + result:= replacefileext(aname,formfileext); +end; + +procedure tdesigner.moduledestroyed(const amodule: pmoduleinfoty); +var + int1: integer; +begin + removefixupreferences(amodule^.instance,''); + if amodule = flastmethodmodulepo then begin + flastmethodmodulepo:= nil; + end; + if amodule = factmodulepo then begin + setactivemodule(nil); + end; + for int1:= 0 to amodule^.components.count - 1 do begin + fselections.remove(amodule^.components.next^.data.data.instance); + end; + designnotifications.moduledestroyed(idesigner(self),amodule^.instance); + designnotifications.selectionchanged(idesigner(self), + idesignerselections(fselections)); +// designnotifications.moduledestroyed(idesigner(self),amodule^.instance); +end; + +procedure tdesigner.addancestorinfo(const ainstance,aancestor: tmsecomponent); +begin + fdescendentinstancelist.add(ainstance,aancestor,fsubmodulelist); +end; + +procedure tdesigner.showformdesigner(const amodule: pmoduleinfoty); +begin + if amodule <> nil then begin + amodule^.designform.activate; + mainfo.createmodulemenuitem(amodule); + end; +end; + +procedure tdesigner.showastext(const amodule: pmoduleinfoty); +var + mstr1: filenamety; + bo1: boolean; +begin + if (amodule <> nil) then begin + mstr1:= amodule^.filename; + bo1:= amodule^.backupcreated; + if closemodule(amodule,true) then begin + designnotifications.showobjecttext(idesigner(self),mstr1,bo1); + end; + end; +end; + +procedure swapmethodpointer(const ainstance: tobject; const data: pointer; + const apropinfo: ppropinfo); +var + method1: tmethod; +begin + method1:= getmethodprop(ainstance,apropinfo); + if method1.data <> nil then begin + method1.code:= method1.data; + method1.data:= nil; + setmethodprop(ainstance,apropinfo,method1); + end; +end; + +procedure swapinitmethodpointer(const ainstance: tobject; const data: pointer; + const apropinfo: ppropinfo); +var + method1: tmethod; +begin + method1:= getmethodprop(ainstance,apropinfo); + if method1.code <> nil then begin + method1.data:= method1.code; + method1.code:= nil; + setmethodprop(ainstance,apropinfo,method1); + end; +end; + +{$ifndef mse_nomethodswap} +procedure tdesigner.internaldoswapmethodpointers(const aroot: tcomponent; + const ainstance: tobject; + const ainit: boolean); +begin + if finditem(pointerarty(fdescendentinstancelist.fswappedancestors), + ainstance) < 0 then begin + if ainit then begin + forallmethodproperties(aroot,ainstance,nil, + {$ifdef FPC}@{$endif}swapinitmethodpointer,true); + end + else begin + forallmethodproperties(aroot,ainstance,nil, + {$ifdef FPC}@{$endif}swapmethodpointer,true); + end; + end; +end; + +procedure tdesigner.doswapmethodpointers(const ainstance: tobject; + const ainit: boolean); +begin + if ainstance is tcomponent then begin + internaldoswapmethodpointers(rootcomponent(tcomponent(ainstance)), + ainstance,ainit); + end + else begin + internaldoswapmethodpointers(nil,ainstance,ainit); + end; +end; +{$endif} + +{$ifdef mse_nomethodswap} +procedure tdesigner.writedesignmethod(writer: twriter; instance: tpersistent; + propinfo: ppropinfo; const methodvalue: tmethod; + const defmethodvalue: tmethod; var handled: boolean); +var + str1: string; +// po1: pmethodinfoty; +begin + handled:= true; + if (methodvalue.data <> defmethodvalue.data) then begin + with tbinaryobjectwriter1(writer.driver) do begin + beginproperty(writer.propertypath + ppropinfo(propinfo)^.name); + if methodvalue.data = nil then begin + writevalue(vanil); + end + else begin + str1:= fmodules.fmethodnames.find(ptruint(methodvalue.data)); + if str1 = '' then begin + writevalue(vanil); + end + else begin + writevalue(vaident); + writestr(str1); + endproperty; + end; + end; + end; + end; +end; +{$endif} + +{ +procedure tdesigner.doswapmethodpointers(const ainstance: tobject; + const ainit: boolean); +var + propar: propinfopoarty; + int1: integer; + method1: tmethod; + po1: ^ppropinfo; + po2: pointer; +begin + propar:= getpropinfoar(ainstance); + po1:= pointer(propar); + for int1:= high(propar) downto 0 do begin + case po1^^.proptype^.kind of + tkmethod: begin + method1:= getmethodprop(ainstance,po1^); + if ainit then begin + if method1.code <> nil then begin + method1.data:= method1.code; + method1.code:= nil; + setmethodprop(ainstance,po1^,method1); + end; + end + else begin + if method1.data <> nil then begin + method1.code:= method1.data; + method1.data:= nil; + setmethodprop(ainstance,po1^,method1); + end; + end; + end; + end; + inc(po1); + end; +end; +} +function tdesigner.getancestorclassinfo(const ainstance: tcomponent; + const interfaceonly: boolean): classinfopoarty; +var + ar1: componentarty; + ar2: classinfopoarty; + int1{,int2}: integer; + po1: punitinfoty; + po2: pmoduleinfoty; +begin + ar1:= fdescendentinstancelist.getancestors(ainstance); + additem(pointerarty(ar1),ainstance); + setlength(ar2,length(ar1)); + for int1:= 0 to high(ar1) do begin + po2:= modules.findmodule(tmsecomponent(ar1[int1])); + if po2 <> nil then begin + po1:= sourceupdater.updateformunit(po2^.filename,interfaceonly); + if po1 <> nil then begin + ar2[int1]:= findclassinfobyinstance(tmsecomponent(ar1[int1]),po1); + end; + end; + end; + result:= classinfopoarty(packarray(pointerarty(ar2))); +end; + +function tdesigner.getancestorclassinfo(const ainstance: tcomponent; + const interfaceonly: boolean; + out aunits: unitinfopoarty): classinfopoarty; + +var + ar1: componentarty; + ar2: classinfopoarty; + int1{,int2}: integer; + po1: punitinfoty; + po2: pmoduleinfoty; +begin + ar1:= fdescendentinstancelist.getancestors(ainstance); + additem(pointerarty(ar1),ainstance); + setlength(ar2,length(ar1)); + setlength(aunits,length(ar1)); + for int1:= 0 to high(ar1) do begin + po2:= modules.findmodule(tmsecomponent(ar1[int1])); + if po2 <> nil then begin + po1:= sourceupdater.updateformunit(po2^.filename,interfaceonly); + aunits[int1]:= po1; + if po1 <> nil then begin + ar2[int1]:= findclassinfobyinstance(tmsecomponent(ar1[int1]),po1); + end; + end; + end; + result:= ar2; +end; + +function tdesigner.checkmethodtypes(const amodule: pmoduleinfoty; + const init: boolean): boolean; + //false on cancel +var + classinfar: classinfopoarty; + comp1: tcomponent; + + procedure doinit(const instance: tobject); + var + ar1: propinfopoarty; + int1,int2: integer; + method1: tmethod; + po1: pmethodinfoty; + obj1: tobject; + po2: pprocedureinfoty; + mr1: modalresultty; + begin + ar1:= getpropinfoar(instance); + for int1:= 0 to high(ar1) do begin + case ar1[int1]^.proptype^.kind of + tkmethod: begin + method1:= getmethodprop(instance,ar1[int1]); + if (method1.data <> nil) then begin + po1:= amodule^.methods.findmethod(method1.data); + if po1 <> nil then begin + if init then begin + po1^.typeinfo:= ar1[int1]^.proptype{$ifndef FPC}^{$endif}; + end + else begin + po2:= nil; + for int2:= 0 to high(classinfar) do begin + po2:= classinfar[int2]^.procedurelist.finditembyname(po1^.name); + if po2 <> nil then begin + break; + end; + end; + mr1:= mr_none; + if (po2 = nil) or not po2^.managed then begin + mr1:= askyesnocancel(actionsmo.c[ord(ac_publishedmeth)]+ ' '+ + msestring(amodule^.instance.name)+'.'+ + msestring(po1^.name)+' ('+ + msestring(comp1.name)+'.'+msestring(ar1[int1]^.name)+') '+ + actionsmo.c[ord(ac_doesnotexist)]+lineend+ + actionsmo.c[ord(ac_wishdelete)],actionsmo.c[ord(ac_warning)]); + end + else begin + if not parametersmatch(po1^.typeinfo,po2^.params) then begin + mr1:= askyesnocancel( + actionsmo.c[ord(ac_method)]+ + ' '+msestring(amodule^.instance.name)+'.'+ + msestring(po1^.name)+' ('+ + msestring(comp1.name)+'.'+msestring(ar1[int1]^.name)+') '+ + actionsmo.c[ord(ac_differentparams)]+lineend+ + actionsmo.c[ord(ac_wishdelete)],actionsmo.c[ord(ac_warning)]); + end; + end; + if mr1 = mr_yes then begin + setmethodprop(instance,ar1[int1],nullmethod); + modulechanged(amodule); + end + else begin + end; + result:= mr1 in [mr_yes,mr_no,mr_none]; + end; + end; + end; + end; + tkclass: begin + obj1:= getobjectprop(instance,ar1[int1]); + if issubprop(obj1) then begin + doinit(obj1); + if obj1 is tpersistentarrayprop then begin + with tpersistentarrayprop(obj1) do begin + for int2:= 0 to count - 1 do begin + doinit(items[int2]); + if not result then begin + break; + end; + end; + end; + end + else begin + if obj1 is tcollection then begin + with tcollection(obj1) do begin + for int2:= 0 to count - 1 do begin + doinit(items[int2]); + if not result then begin + break; + end; + end; + end; + end; + end; + end; + end; + end; + if not result then begin + break; + end; + end; + end; + +var + int1: integer; + mstr1: msestring; +// po3: punitinfoty; +begin + result:= true; + if not init then begin + mstr1:= replacefileext(amodule^.filename,pasfileext); + if sourcefo.findsourcepage(mstr1) = nil then begin + exit; + end; +// po3:= sourceupdater.updateformunit(amodule^.filename,true); +// if po3= nil then begin +// exit; +// end; + classinfar:= getancestorclassinfo(amodule^.instance,true); +// classinf:= findclassinfobyinstance(amodule^.instance,po3); +// if classinf = nil then begin +// exit; +// end; + end; + with amodule^ do begin + for int1:= 0 to components.count - 1 do begin + comp1:= components.next^.data.data.instance; + doinit(comp1); + if not result then begin + break; + end; + end; + end; +end; + +procedure tdesigner.dofixup; +begin + RegisterFindGlobalComponentProc({$ifdef FPC}@{$endif}getglobalcomponent); + try + globalfixupreferences; + finally + unregisterFindGlobalComponentProc({$ifdef FPC}@{$endif}getglobalcomponent); + end; +end; + +procedure tdesigner.readererror(reader: treader; const message: string; + var handled: boolean); +var + comp1: tcomponent; +begin + comp1:= reader.lookuproot; + if comp1 = nil then begin + comp1:= reader.root; + end; + with exception(ExceptObject) do begin + message:= ansistring(actionsmo.c[ord(ac_component)])+ + ownernamepath(comp1)+'":'+lineend+message; + end; +end; + +procedure tdesigner.readerenumerror(const reader: treader; + const atype: ptypeinfo; const aitemname: string; var avalue: longword); +begin + if atype = typeinfo(charencodingty) then begin + if (aitemname = 'ce_utf8n') then begin + avalue:= ord(ce_utf8); + floadingmodulepo^.readermodified:= true; + end; + end; +end; + +procedure tdesigner.readerseterror(const reader: treader; + const atype: ptypeinfo; const aitemname: string; var avalue: integer); +begin + if atype = typeinfo(optioneditty) then begin + if (aitemname = 'oe_autopopupmenu') or + (aitemname = 'oe_keyexecute') then begin + avalue:= -2; //skip + floadingmodulepo^.readermodified:= true; + end; + end; + if atype = typeinfo(framelocalpropty) then begin + if (aitemname = 'frl_frameimageoffsetactivemouse') or + (aitemname = 'frl_frameimageoffsetactiveclicked') then begin + avalue:= -2; //skip + floadingmodulepo^.readermodified:= true; + end; + end; + if atype = typeinfo(framelocalprop1ty) then begin + if (aitemname = 'frl1_framefaceoffsetactivemouse') or + (aitemname = 'frl1_framefaceoffsetactiveclicked') then begin + avalue:= -2; //skip + floadingmodulepo^.readermodified:= true; + end; + end; +end; + +function tdesigner.loadformfile(filename: msestring; + const skipexisting: boolean): pmoduleinfoty; +var + module: tmsecomponent; + loadedsubmodulesindex: integer; + moduleinfo: tmoduleinfo; + + procedure dodelete; + var + int1: integer; + desfo: tcustommseform; + begin + removefixupreferences(module,''); + for int1:= high(floadedsubmodules) downto loadedsubmodulesindex+1 do begin + removefixupreferences(floadedsubmodules[int1],''); + end; + desfo:= result^.designform; + moduleinfo.free; //frees module by designform + if desfo = nil then begin + module.Free; + end; + module:= nil; + result:= nil; + end; + +var + moduleclassname1,modulename, + designmoduleclassname: string; + stream1: ttextstream; + stream2: tmemorystream; + reader: treader; + flags: tfilerflags; + pos: integer; + rootnames,rootinstancenames: tstringlist; + int1: integer; + wstr1: msestring; + res1: modalresultty; + bo1: boolean; + loadingdesignerbefore: tdesigner; + loadingmodulepobefore: pmoduleinfoty; + isinherited: boolean; + str1: string; + fixupmodule: string; + lastmissed: string; + comp1: tcomponent; + deletefixups: boolean; + exp1: exception; + +begin //loadformfile + filename:= filepath(filename); + result:= fmodules.findmodule(filename); + if result = nil then begin + designnotifications.closeobjecttext(idesigner(self),filename,bo1); + if bo1 then begin + exit; //canceled + end; + exp1:= nil; + stream1:= ttextstream.Create(filename,fm_read); + designmoduleclassname:= ''; + rootnames:= tstringlist.create; + rootinstancenames:= tstringlist.create; + beginskipall; + try + stream2:= tmemorystream.Create; + try + try + objecttexttobinarymse(stream1,stream2); + stream2.position:= 0; + reader:= treader.create(stream2,4096); + try + with treader1(reader) do begin + driver.beginrootcomponent; + driver.begincomponent(flags,pos,moduleclassname1,modulename); + isinherited:= ffinherited in flags; + while not endoflist do begin + str1:= driver.beginproperty; + if str1 = moduleclassnamename then begin + designmoduleclassname:= readstring; + end + else begin + driver.skipvalue; + end; + end; + end; + finally + reader.free; + end; + result:= modules.findmodulebyname(modulename); + if result <> nil then begin + stream2.free; //not listed in loadingstreams + if skipexisting and issamefilepath(result^.filename,filename) then begin + exit; + end; + raise exception.create(ansistring(actionsmo.c[ord(ac_amodule)])+ + modulename+ansistring(actionsmo.c[ord(ac_isopen)])); + end; + stream2.Position:= 0; + loadingdesignerbefore:= loadingdesigner; + loadingdesigner:= self; + inc(fformloadlocklevel); + begingloballoading; + try + try + moduleinfo:= fmodules.newmodule(isinherited,filename,moduleclassname1, + modulename,designmoduleclassname); + fmodules.add(moduleinfo); + result:= @moduleinfo.info; + result^.loadingstream:= stream2; + module:= result^.instance; + stream2.Position:= 0; + reader:= treader.Create(stream2,4096); + loadedsubmodulesindex:= high(floadedsubmodules); + inc(fformloadlevel); + loadingmodulepobefore:= floadingmodulepo; + try + floadingmodulepo:= result; + lockfindglobalcomponent; + try + {$ifdef mse_nomethodswap} + reader.onsetmethodproperty:= {$ifdef FPC}@{$endif}setmethodproperty; + {$else} + reader.onfindmethod:= {$ifdef FPC}@{$endif}findmethod; + {$endif} + reader.onfindcomponentclass:= {$ifdef FPC}@{$endif}findcomponentclass; + reader.onancestornotfound:= {$ifdef FPC}@{$endif}ancestornotfound; + reader.oncreatecomponent:= createcomponent(); + reader.onerror:= {$ifdef FPC}@{$endif}readererror; + reader.onseterror:= @readerseterror; + reader.onenumerror:= @readerenumerror; + module.Name:= modulename; + reader.ReadrootComponent(module); + {$ifndef mse_nomethodswap} + doswapmethodpointers(module,true); + {$endif} + result^.components.assigncomps(module); + getfixupreferencenames(module,rootnames); + setlength(result^.referencedmodules,rootnames.Count); + for int1:= 0 to high(result^.referencedmodules) do begin + result^.referencedmodules[int1]:= rootnames[int1]; + end; + dofixup; + fixupmodule:= ''; + lastmissed:= ''; + deletefixups:= true; + while true do begin + rootnames.clear; + rootinstancenames.clear; + getfixupreferencenames(module,rootnames); + for int1:= rootnames.count - 1 downto 0 do begin + comp1:= fmodules.findmoduleinstancebyname(rootnames[int1]); + if (comp1 <> nil) and (comp1 <> module) and + (csloading in comp1.componentstate) then begin + deletefixups:= false; + additem(pointerarty(fcheckfixups),result); + rootnames.delete(int1); //there is hope + end; + end; + if rootnames.Count > 0 then begin + if assigned(fongetmodulenamefile) then begin + try + res1:= mr_cancel; + if fixupmodule = rootnames[0] then begin + break; + end; + fixupmodule:= rootnames[0]; + getfixupinstancenames(module,fixupmodule,rootinstancenames); + if rootinstancenames.count > 0 then begin + str1:= '.'+rootinstancenames[0]; + end + else begin + str1:= ''; + end; + lastmissed:= fixupmodule + str1; + fongetmodulenamefile(result,lastmissed,res1); + dofixup; + case res1 of + mr_ok: begin + end; + mr_ignore: begin + rootnames.Clear; + break; + end; + else begin + break; + end; + end; + except + application.handleexception(self); + break; + end; + end + else begin + break; + end; + end + else begin + break; + end; + end; + if (module <> nil) and deletefixups then begin + removefixupreferences(module,''); + end; + if rootnames.Count > 0 then begin + wstr1:= msestring(rootnames[0]); + for int1:= 1 to rootnames.Count - 1 do begin + wstr1:= wstr1 + ','+msestring(rootnames[int1]); + end; + raise exception.Create(ansistring( + actionsmo.c[ord(ac_unresolvedref)]+' '+ + msestring(lastmissed)+lineend+ + actionsmo.c[ord(ac_modules)]+' '+wstr1+'.')); + end; + result^.resolved:= true; + except + freeandnil(reader); //used stream will be freed + dodelete; + raise; + end; + finally + reader.free; + floadingmodulepo:= loadingmodulepobefore; + setlength(floadedsubmodules,loadedsubmodulesindex+1); + //remove info + dec(fformloadlevel); + unlockfindglobalcomponent; + end; + if result <> nil then begin + result^.designform:= createdesignform(self,result); + result^.designform.getcorbainterface(typeinfo(iformdesigner), + result^.designformintf); + checkmethodtypes(result,true); + result^.modified:= result^.readermodified; +// if result^.modified then begin +// mainfo.sourcechanged(nil); +// end; + end; + finally + loadingdesigner:= nil; + end; + notifygloballoading; + finally + loadingdesigner:= loadingdesignerbefore; + endgloballoading; + dec(fformloadlocklevel); + end; + except + on e: exception do begin + e.Message:= ansistring(actionsmo.c[ord(ac_cannotreadform)]+filename)+ + '".'+lineend+e.Message; + raise; + end; + end; + finally + if fformloadlevel = 0 then begin + fmodules.freeloadingstreams; + while high(fcheckfixups) >= 0 do begin + rootnames.clear; + with fcheckfixups[high(fcheckfixups)]^ do begin + getfixupreferencenames(instance,rootnames); + if rootnames.count > 0 then begin + designnotifications.showobjecttext( + idesigner(self),filename,backupcreated); + if exp1 = nil then begin + rootinstancenames.clear; + getfixupinstancenames(instance,rootnames[0],rootinstancenames); + if rootinstancenames.count > 0 then begin + str1:= '.'+rootinstancenames[0]; + end + else begin + str1:= ''; + end; + exp1:= exception.create(ansistring( + actionsmo.c[ord(ac_cannotreadform)]+filename+'".'+lineend+ + actionsmo.c[ord(ac_unresolvedref)]+ + msestring(rootnames[0]+str1+'.'))); + end; + instance.free; + fmodules.removemoduleinfo(fcheckfixups[high(fcheckfixups)]); + end + else begin + setlength(fcheckfixups,high(fcheckfixups)); + end; + end; + end; + removefixupreferences(nil,''); + if exp1 <> nil then begin + if result <> nil then begin + dodelete; + end; + raise exp1; + end; + end; + end; + finally + rootnames.free; + rootinstancenames.free; + stream1.Free; + endskipall; + end; + end; + (* + {$ifdef mse_debugsubmodule} + {$ifdef mse_debugmoduleload} + dumpcomponent(result^.instance,filename); + {$endif} + debugbinstreamout(result^.instance,nil, + {$ifdef FPC}@{$endif}fdesigner.findancestor, + '*****loadformfile '+filename); + {$endif} + *) +end; //loadformfile + +procedure createbackupfile(const newname,origname: filenamety; + var backupcreated: boolean; const backupcount: integer); +var + int1: integer; + mstr1: filenamety; + mstr2: filenamety; +begin + if (backupcount > 0) and not backupcreated and + issamefilename(newname,origname) and findfile(origname) then begin + backupcreated:= true; + mstr1:= origname + backupext; + for int1:= backupcount-1 downto 2 do begin + mstr2:= mstr1+inttostrmse(int1-1); + if findfile(mstr2) then begin + msefileutils.renamefile(mstr2,mstr1+inttostrmse(int1)); + end; + end; + if backupcount > 1 then begin + if findfile(mstr1) then begin + msefileutils.renamefile(mstr1,mstr1+'1'); + end; + end; + msefileutils.copyfile(origname,mstr1); + end; +end; + +function tdesigner.getancestormethods(const amodule: pmoduleinfoty): methodsarty; +var + comp1: tcomponent; +begin +{$ifdef mse_nomethodswap} + setlength(result,1); + result[0]:= amodule^.methods; +{$else} + result:= nil; +{$endif} + comp1:= amodule^.instance; + while true do begin + comp1:= fdescendentinstancelist.findancestor(comp1); + if comp1 = nil then begin + break; + end; + additem(pointerarty(result),fmodules.findmodulebyinstance(comp1)^.methods); + end; +end; + +{$ifndef mse_nomethodswap} +procedure tdesigner.buildmethodtable(const amodule: pmoduleinfoty); +begin + if amodule <> nil then begin + with amodule^ do begin + if methodtableswapped = 0 then begin +// flookupmodule:= amodule; + methodtablebefore:= swapmethodtable(instance, + methods.createmethodtable(getancestormethods(amodule))); + end; + inc(methodtableswapped); + end; + end; +end; + +procedure tdesigner.releasemethodtable(const amodule: pmoduleinfoty); +begin + if amodule <> nil then begin + with amodule^ do begin + dec(methodtableswapped); + if methodtableswapped = 0 then begin + swapmethodtable(instance,methodtablebefore); + methods.releasemethodtable; +// flookupmodule:= nil; + end; + end; + end; +end; +{$endif} +procedure tdesigner.writemodule(const amodule: pmoduleinfoty; + const astream: tstream); +var + writer1: twritermse; + ancestor: tcomponent; +begin +{$ifndef mse_nomethodswap} + buildmethodtable(amodule); +{$endif} + with amodule^ do begin + fdescendentinstancelist.beginstreaming(nil); + {$ifndef mse_nomethodswap} + doswapmethodpointers(instance,false); + {$endif} + writer1:= twritermse.create(astream,4096,false); + if instance is twidget then begin + fdescendentinstancelist.setnodefaultpos(twidget(instance)); + end; + beginstreaming({amodule}); + try + if csancestor in instance.componentstate then begin + ancestor:= fdescendentinstancelist.findancestor(instance); + end + else begin + ancestor:= nil; + end; + writer1.onfindancestor:= {$ifdef FPC}@{$endif}findancestor; + {$ifdef mse_nomethodswap} + writer1.onwritemethodproperty:= {$ifdef FPC}@{$endif}writedesignmethod; + {$endif} + writer1.writedescendent(instance,ancestor); + finally + fdescendentinstancelist.endstreaming; + endstreaming({amodule}); + writer1.free; + {$ifndef mse_nomethodswap} + doswapmethodpointers(instance,true); + releasemethodtable(amodule); + {$endif} + if instance is twidget then begin + fdescendentinstancelist.restorepos(twidget(instance)); + end; + end; + end; +end; + +function tdesigner.saveformfile(const modulepo: pmoduleinfoty; + const afilename: msestring; createdatafile: boolean): boolean; + //false if aborted +var + stream1: tmemorystream; + stream2: tbufstream; + info: fileinfoty; +begin + if createdatafile and projectoptions.s.checkmethods + and not checkmethodtypes(modulepo,false{,nil}) then begin + result:= false; + exit; + end; + result:= true; + with modulepo^ do begin + createbackupfile(afilename,filename, + backupcreated,projectoptions.e.backupfilecount); + if createdatafile and (filetag <> 0) then begin + sourcefo.filechangenotifyer.removenotification(filename,filetag); + end; + stream1:= tmemorystream.Create; + application.beginwait(); + try + writemodule(modulepo,stream1); + stream2:= tbufstream.createtransaction(afilename); + stream2.usewritebuffer:= true; + try + stream1.position:= 0; + try + objectbinarytotextmse(stream1,stream2); + except + stream2.cancel; + raise; + end; + finally + stream2.Free; + end; + if issamefilename(afilename,filename) then begin + modified:= false; + if getfileinfo(afilename,info) then begin + savetime:= info.extinfo1.modtime; + end; + end; + if createdatafile then begin + if filetag = 0 then begin + filetag:= sourcefo.newfiletag; + end; + sourcefo.filechangenotifyer.addnotification(filename,filetag,false); + formtexttoobjsource(afilename,moduleclassname,'',fobjformat); + end; + finally + application.endwait(); + stream1.free; + end; + end; +end; + +procedure tdesigner.refreshdatafile(const amodule: pmoduleinfoty); +begin + with amodule^ do begin + formtexttoobjsource(filename,moduleclassname,'',fobjformat); + end; +end; + +function tdesigner.saveall(noconfirm,createdatafile: boolean): modalresultty; +var + int1: integer; + po1: pmoduleinfoty; +begin + result:= mr_none; + for int1:= 0 to modules.count - 1 do begin + po1:= modules[int1]; + with po1^ do begin + if not modified and projectoptions.s.checkmethods then begin + if not checkmethodtypes(po1,false{,nil}) then begin + result:= mr_cancel; + exit; + end; + end; + if modified and (result <> mr_noall) and + (noconfirm or + (result = mr_all) or + not fallsaved and confirmsavechangedfile(filename,result,true)) then begin + if not saveformfile(po1,filename,createdatafile) then begin + result:= mr_cancel; + end; + end; + case result of + mr_cancel: begin + exit; + end; + mr_noall: begin + break; + end; + end; + end; + end; + fallsaved:= fallsaved or not noconfirm; +end; + +function tdesigner.closemodule(const amodule: pmoduleinfoty; + const checksave: boolean): boolean; //true if closed +var + closingmodules: moduleinfopoarty; + + procedure dochecksave(const amodule: pmoduleinfoty); + var + modalresult: modalresultty; + int1: integer; + ar1: stringarty; + ar2: moduleinfopoarty; + begin + ar1:= nil; //compiler warning + if amodule <> nil then begin + modalresult:= mr_none; + for int1:= 0 to high(closingmodules) do begin + if closingmodules[int1] = amodule then begin + exit; //already checked; + end; + end; + with amodule^ do begin + if modified and checksave and + confirmsavechangedfile(filename,modalresult,false) then begin + saveformfile(amodule,filename,true); + end; + end; + result:= modalresult <> mr_cancel; + if result then begin + additem(pointerarty(closingmodules),amodule); + ar1:= getreferencingmodulenames(amodule); + setlength(ar2,length(ar1)); + for int1:= 0 to high(ar1) do begin + ar2[int1]:= modules.findmodulebyname(ar1[int1]); + dochecksave(ar2[int1]); + if not result then begin + break; + end; + end; + end; + end; + end; + +var + int1: integer; + +begin //closemodule + result:= false; + closingmodules:= nil; + dochecksave(amodule); + if result then begin + for int1:= 0 to high(closingmodules) do begin + if closingmodules[int1] <> nil then begin + modules.removemoduleinfo(closingmodules[int1]); + end; + end; + end; +end; //closemodule + +function tdesigner.modified: boolean; +var + int1: integer; +begin + result:= false; + for int1:= 0 to fmodules.count - 1 do begin + if modules[int1]^.modified then begin + result:= true; + break; + end; + end; +end; + +procedure tdesigner.NoSelection; +begin + selectcomponent(nil); +end; + +procedure tdesigner.SelectComponent(Instance: Tcomponent); +var + list: tdesignerselections; +begin + freeandnil(fcomponenteditor); + list:= tdesignerselections.create; + try + if instance <> nil then begin + list.Add(instance); + fcomponenteditor:= componenteditors.geteditorclass( + componentclassty(instance.classtype)).create(idesigner(self),instance); + end; + setselections(idesignerselections(list)); + finally + list.Free; + end; +end; + +procedure tdesigner.selectionchanged; +begin + designnotifications.SelectionChanged( + idesigner(self),idesignerselections(fselections)); +end; + +procedure tdesigner.SetSelections(const List: IDesignerSelections); +var + int1: integer; + component1: tcomponent; +begin + for int1:= 0 to fselections.count - 1 do begin + component1:= fselections[int1]; + if component1 is tmsecomponent then begin + tmsecomponent1(component1).designselected(false); + end; + end; + fselections.assign(list); + for int1:= 0 to fselections.count - 1 do begin + component1:= fselections[int1]; + if component1 is tmsecomponent then begin + tmsecomponent1(component1).designselected(true); + end; + end; + selectionchanged; +end; +{ +procedure tdesigner.checkobjectinspector; +begin + if objectinspectorfo = nil then begin + objectinspectorfo:= tobjectinspectorfo.create(nil,self); + end; +end; +} +procedure tdesigner.showobjectinspector; +begin +// asyncevent(showobjectinspectortag); + //use async because of window stacking problems + objectinspectorfo.activate; +end; + +function tdesigner.formfiletoname(const filename: msestring): msestring; +begin + result:= removefileext(msefileutils.filename(filename)); +end; + +function tdesigner.getmethod(const aname: string; + const methodowner: tmsecomponent; const atype: ptypeinfo; + const searchancestors: boolean): tmethod; +var + ar1: componentarty; + int1: integer; +begin + result:= fmodules.findmethodbyname(aname,atype,methodowner); + if searchancestors and (result.data = nil) then begin + ar1:= fdescendentinstancelist.getancestors(methodowner); + for int1:= high(ar1) downto 0 do begin + result:= fmodules.findmethodbyname(aname,atype,tmsecomponent(ar1[int1])); + if result.data <> nil then begin + break; + end; + end; + end; +end; + +function tdesigner.getmethodname(const Method: TMethod; const comp: tcomponent): string; +begin + result:= fmodules.findmethodname(method,comp); +end; + +function tdesigner.actmodulepo: pmoduleinfoty; +begin + result:= factmodulepo; +end; + +function tdesigner.getcomponentname(const comp: tcomponent): string; +var + int1: integer; + po1: pmoduleinfoty; +begin + result:= ''; + if comp <> nil then begin + if (floadingmodulepo <> nil) and + (comp.Owner = floadingmodulepo^.instance) then begin //??? + result:= comp.name; + end + else begin + for int1:= 0 to fmodules.count - 1 do begin + po1:= fmodules[int1]; + if issubcomponent(po1^.instance,comp) then begin + if po1 = floadingmodulepo then begin + result:= getcomponentdispname(comp); + end + else begin + result:= po1^.instancevarname + '.' + getcomponentdispname(comp); + end; + break; + end; + end; + end; + end; +end; + +function tdesigner.getcomponentdispname(const comp: tcomponent): string; + //returns qualified name +var + comp1: tcomponent; + bo1: boolean; + ch1: char; +begin + result:= comp.Name; + ch1:= subcomponentsplitchar; +// if not (cssubcomponent in comp.componentstyle) then begin +// ch1:= '.'; +// end; + comp1:= comp.owner; + while not ismodule(comp1) do begin + result:= comp1.Name + ch1 + result; + comp1:= comp1.Owner; +// if not (cssubcomponent in comp1.componentstyle) then begin +// ch1:= '.'; +// end; + end; + bo1:= ismodule(comp); + if bo1 or ismodule(comp.owner) then begin + if csancestor in comp.componentstate then begin + if bo1 then begin + comp1:= comp; + end + else begin + comp1:= comp.owner; + end; + comp1:= fdescendentinstancelist.findancestor(comp1); + if comp1 <> nil then begin + result:= result+'<'+comp1.name+'>'; + end; + end; + end; +end; + +function tdesigner.getcomponent(const aname: string; + const aroot: tcomponent): tcomponent; +var + ar1,ar2: stringarty; + po1,po2: pmoduleinfoty; + int1,int2: integer; + bo1: boolean; +// str1: string; +begin + result:= nil; + if (aname <> '') and (floadingmodulepo <> nil) then begin + splitstring(aname,ar2,':'); + result:= floadingmodulepo^.components.getcomponent(ar2[0]); + if result = nil then begin + splitstring(ar2[0],ar1,'.'); + if high(ar1) = 1 then begin + ar1[0]:= uppercase(ar1[0]); + for int1:= 0 to fmodules.count - 1 do begin + po1:= fmodules[int1]; + if stricomp(pchar(po1^.instancevarname),pchar(ar1[0])) = 0 then begin + result:= po1^.components.getcomponent(ar1[1]); + if result <> nil then begin + if (aroot <> nil) and (aroot <> po1^.instance) then begin + po2:= fmodules.findmodulebyinstance(aroot); + if po2 <> nil then begin + bo1:= false; + for int2:= 0 to high(po2^.referencedmodules) do begin + if po2^.referencedmodules[int2] = aroot.name then begin + bo1:= true; + break; + end; + end; + if not bo1 then begin + additem(po2^.referencedmodules,po1^.instance.name); + end; + end; + end; + break; + end; + end; + end; + end; + end; + if (result <> nil) and (high(ar2) > 0) then begin + for int1:= 1 to high(ar2) do begin + result:= result.findcomponent(ar2[int1]); + if result = nil then begin + break; + end; + end; + end; + end; +end; + +function tdesigner.getcomponent(const apath: string; + out amodule: pmoduleinfoty): tcomponent; +var + ar1: stringarty; +begin + result:= nil; + amodule:= nil; + ar1:= splitstring(apath,'.'); + if ar1 <> nil then begin + amodule:= fmodules.findmodulebyname(ar1[0]); + if amodule <> nil then begin + result:= findcomponentbynamepath(apath,amodule^.instance); + end; + end; +end; + +function tdesigner.getcomponentlist( + const acomponentclass: tcomponentclass; + const filter: compfilterfuncty = nil; + const allmodules: boolean = false): componentarty; +var + acount: integer; + + procedure check(const acomp: tcomponent); + begin + if acomp.InheritsFrom(acomponentclass) and + (({$ifndef FPC}@{$endif}filter = nil) or filter(acomp)) and + not isnosubcomp(acomp) then begin + additem(pointerarty(result),acomp,acount); + end; + end; //check + + procedure scanmodule(amodule: pmoduleinfoty); + var + int1,int3: integer; + comp1,comp2: tcomponent; + begin + with amodule^.components do begin +// for int1:= 0 to high(result) do begin +// check(next^.instance); +// end; + for int1:= 0 to count - 1 do begin + comp1:= next^.data.data.instance; + check(comp1); + for int3:= 0 to comp1.componentcount - 1 do begin + comp2:= comp1.components[int3]; + if cssubcomponent in comp2.componentstyle then begin + check(comp2); + end; + end; + end; + end; + end; + +var + int1: integer; + +begin + acount:= 0; + if allmodules then begin + for int1:= 0 to modules.count-1 do begin + scanmodule(modules[int1]); + end; + end + else begin + if floadingmodulepo <> nil then begin + scanmodule(floadingmodulepo); + end; + end; + setlength(result,acount); +end; + +function compcompname(const l,r): integer; +begin + result:= ord(msestring(l)[1])-ord(msestring(r)[1]); + if result = 0 then begin + result:= countchars(msestring(l),msechar('.')) - + countchars(msestring(r),msechar('.')); + if result = 0 then begin + result:= msestringicomp(msestring(l),msestring(r)); + end; + end; +end; + +procedure sortcompnamelist(var avalue: msestringarty); +var + int1: integer; +begin + sortarray(avalue,{$ifdef FPC}@{$endif}compcompname); + for int1:= 0 to high(avalue) do begin + avalue[int1]:= copy(avalue[int1],2,bigint); + end; +end; + +function tdesigner.getcomponentnamelist(const acomponentclass: tcomponentclass; + const includeinherited: boolean; + const aowner: tcomponent = nil; + const filter: compfilterfuncty = nil): msestringarty; +var + str1: msestring; + acount: integer; + + procedure check(const comp1: tcomponent); + var + int3: integer; + comp2: tcomponent; + begin + if comp1.InheritsFrom(acomponentclass) and + (({$ifndef FPC}@{$endif}filter = nil) or filter(comp1)) then begin + if ((aowner = nil) or (aowner = comp1.owner)) and + (includeinherited or + (comp1.componentstate * [csinline,csancestor] = [])) then begin + additem(result,str1+msestring(getcomponentdispname(comp1)),acount); + end; + end; + for int3:= 0 to comp1.componentcount - 1 do begin + comp2:= comp1.components[int3]; + if (cssubcomponent in comp2.componentstyle){ and + not isnosubcomp(comp2)} then begin + check(comp2); + end; + end; + end; + +var + int1,int2{,int3}: integer; + comp1{,comp2}: tcomponent; + po1: pmoduleinfoty; +begin + result:= nil; + acount:= 0; + for int1:= 0 to fmodules.count - 1 do begin + po1:= fmodules[int1]; + if po1 = floadingmodulepo then begin + str1:= ' '; + end + else begin + str1:= msestring('z'+po1^.instancevarname + '.'); + end; + with po1^.components do begin + for int2:= 0 to count - 1 do begin + comp1:= next^.data.data.instance; + check(comp1); + end; + end; + end; + setlength(result,acount); + sortcompnamelist(result); +end; + +function tdesigner.getcomponentnamelist(const acomponentclass: tcomponentclass; + const arootcomp: tcomponent; + const filter: compfilterfuncty = nil): msestringarty; +var + acount: integer; + + procedure check(const acomp: tcomponent; prefix: msestring); + var + i1: int32; + comp1: tcomponent; + begin + if (prefix <> '') then begin + if (acomp is acomponentclass) and filter(acomp) then begin + additem(result,prefix,acount); + end; + prefix:= prefix+'.'; + end; + for i1:= 0 to acomp.componentcount-1 do begin + comp1:= acomp.components[i1]; + check(comp1,prefix+msestring(comp1.name)); + end; + end; + +begin + result:= nil; + acount:= 0; + check(arootcomp,''); + setlength(result,acount); + sortarray(result); +end; + +function tdesigner.getwidgetnamelist(const awidgetclass: widgetclassty; + const arootwidget: twidget; + const filter: compfilterfuncty = nil): msestringarty; +var + acount: integer; + + procedure check(const awidget: twidget; prefix: msestring); + var + i1: int32; + begin + if prefix = '!' then begin //first + prefix:= ''; + end + else begin + if ((awidgetclass = nil) or (awidget is awidgetclass)) and + filter(awidget) then begin + additem(result,prefix+msestring(awidget.name),acount); + end; + if csinline in awidget.componentstate then begin + prefix:= prefix + msestring(awidget.name)+'.'; + end; + end; + for i1:= 0 to awidget.widgetcount-1 do begin + check(awidget.widgets[i1],prefix); + end; + end; + +begin + result:= nil; + acount:= 0; + check(arootwidget,'!'); + setlength(result,acount); + sortarray(result); +end; + +function tdesigner.getcomponentnamelist(const acomponents: componentarty; + const amodule: tmsecomponent): msestringarty; +var + int1,int2: integer; + co1: tcomponent; +begin + setlength(result,length(acomponents)); + int2:= 0; + for int1:= 0 to high(acomponents) do begin + if acomponents[int1] <> nil then begin + co1:= rootcomponent(acomponents[int1]); + if co1 = amodule then begin + result[int2]:= ' '; + end + else begin + result[int2]:= msestring('z'+co1.name + '.'); + end; + result[int2]:= result[int2] + + msestring(getcomponentdispname(acomponents[int1])); + inc(int2); + end; + end; + setlength(result,int2); + sortcompnamelist(result); +end; + +type + tdesigncompnameitem = class(tcompnameitem) + private + fcomp: tcomponent; + public + constructor create(const acomp: tcomponent; + const aisvalue: boolean); reintroduce; + function findcomp(const acomp: tcomponent): tdesigncompnameitem; + end; + +{ tdesigncompnameitem } + +constructor tdesigncompnameitem.create(const acomp: tcomponent; + const aisvalue: boolean); +begin + fcomp:= acomp; + inherited create; + isvalue:= aisvalue; + if acomp <> nil then begin + caption:= msestring(acomp.name); + end; +end; + +function tdesigncompnameitem.findcomp(const acomp: tcomponent): tdesigncompnameitem; +var + int1: integer; +begin + result:= nil; + for int1:= 0 to fcount -1 do begin + if tdesigncompnameitem(fitems[int1]).fcomp = acomp then begin + result:= tdesigncompnameitem(fitems[int1]); + break; + end; + end; +end; + + +function tdesigner.getcomponentnametree(const acomponentclass: tcomponentclass; + const includeinherited: boolean; + const findmode: boolean; + const aowner: tcomponent = nil; + const filter: compfilterfuncty = nil; + const amodule: tcomponent = nil): tcompnameitem; + + procedure check(const acomp: tcomponent); + var + int1,int3: integer; + comp1,comp2: tcomponent; + node1,node2,node3: tdesigncompnameitem; + ar1: componentarty; + begin + if ((acomponentclass = nil) or acomp.InheritsFrom(acomponentclass)) and + ((@filter = nil) or filter(acomp)) then begin + if ((aowner = nil) or (aowner = acomp.owner)) and + (includeinherited or + (acomp.componentstate * [csinline,csancestor] = [])) then begin + node1:= tdesigncompnameitem.create(acomp,true); + node1.imagenr:= 4; + node1.state:= node1.state + [ns_imagenrfix]; + comp1:= acomp.owner; + while comp1 <> nil do begin + additem(pointerarty(ar1),comp1); + comp1:= comp1.owner; + end; + node2:= tdesigncompnameitem(result); + for int1:= high(ar1) downto 0 do begin + node3:= node2.findcomp(ar1[int1]); + if node3 = nil then begin + node3:= tdesigncompnameitem.create(ar1[int1],false); + node2.add(node3); + end; + node3.state:= node3.state - [ns_imagenrfix]; + node2:= node3; + end; + node2.add(node1); + end; + end; + for int3:= 0 to acomp.componentcount - 1 do begin + comp2:= acomp.components[int3]; + if (cssubcomponent in comp2.componentstyle) xor findmode{ and + not isnosubcomp(comp2)} then begin +// node1:= anode.findcomp(comp2); +// if node1 = nil then begin +// node1:= tdesigncompnameitem.create(comp2,false); +// end; + check(comp2); + end; + end; + end; + +var + int1,int2{,int3}: integer; + comp1{,comp2}: tcomponent; + po1: pmoduleinfoty; +begin + result:= tdesigncompnameitem.create(nil,false); + if amodule <> nil then begin + check(amodule); + end + else begin + for int1:= 0 to fmodules.count - 1 do begin + po1:= fmodules[int1]; + if findmode then begin + check(po1^.instance); + end + else begin + with po1^.components do begin + for int2:= 0 to count - 1 do begin + comp1:= next^.data.data.instance; + check(comp1); + end; + end; + end; + end; + end; + result.sort(false,true); +end; + +function tdesigner.getwidgetnametree(const rootwidget: twidget): tcompnameitem; + + procedure check(const aitem: tcompnameitem; awidget: twidget); + var + node1: tdesigncompnameitem; + i1: int32; + begin + if (awidget <> nil) and (ws_iswidget in awidget.widgetstate) then begin + node1:= tdesigncompnameitem.create(awidget,true); + node1.imagenr:= 4; + node1.state:= node1.state + [ns_imagenrfix]; + aitem.add(node1); + for i1:= 0 to high(twidget1(awidget).fwidgets) do begin + check(node1,twidget1(awidget).fwidgets[i1]); + end; + end + else begin + if awidget = nil then begin + awidget:= rootwidget; + end; + for i1:= 0 to high(twidget1(awidget).fwidgets) do begin + check(aitem,twidget1(awidget).fwidgets[i1]); + end; + end; + end; + +begin + result:= tdesigncompnameitem.create(nil,false); + check(result,nil); + result.sort(false,true); +end; + +function tdesigner.getmodules: tmodulelist; +begin + result:= fmodules; +end; + +function tdesigner.findcomponentmodule(const acomponent: tcomponent): pmoduleinfoty; +var + int1: integer; + po1: pmoduleinfoty; +begin + result:= nil; + for int1:= 0 to fmodules.count-1 do begin + po1:= fmodules[int1]; + if po1^.components.find(acomponent) <> nil then begin + result:= po1; + break; + end; + end; +end; + +procedure tdesigner.validaterename(const acomponent: tcomponent; + const curname,NewName: string); +var + po1: pmoduleinfoty; + ar1: objectarty; + int1: integer; + comp1: tcomponent; +begin + ar1:= nil; //compiler warning + if loadingdesigner = nil then begin + po1:= findcomponentmodule(acomponent); + if po1 <> nil then begin + if newname = '' then begin + raise exception.Create(ansistring(actionsmo.c[ord(ac_invalidcompname)])); + end; + if acomponent.name <> newname then begin + if stringicomp(acomponent.name,newname) <> 0 then begin + comp1:= acomponent.getparentcomponent; + if (comp1 <> nil) and (comp1.findcomponent(newname) <> nil) then begin + raise EComponentError.Createfmt(SDuplicateName,[newname]); + end; + end; + po1^.components.namechanged(acomponent,newname); + fdescendentinstancelist.componentnamechanged(po1,acomponent,newname); + + designnotifications.componentnamechanging(idesigner(self),po1^.instance, + acomponent,newname); + if acomponent is tmsecomponent then begin + ar1:= tmsecomponent(acomponent).linkedobjects; + end + else begin + ar1:= objectarty(getlinkedcomponents(acomponent)); + end; + end; + for int1:= 0 to high(ar1) do begin + if ar1[int1] is tcomponent then begin + componentmodified(tcomponent(ar1[int1])); + end; + end; + end; + end; +end; + +function tdesigner.getclassname(const comp: tcomponent): string; + //returns submoduleclass if appropriate +begin + result:= fdescendentinstancelist.getclassname(comp); +end; + +function tdesigner.getcomponenteditor: icomponenteditor; +begin + if fcomponenteditor = nil then begin + result:= nil; + end + else begin + result:= icomponenteditor(fcomponenteditor); + end; +end; + +function tdesigner.editcomponent(const aowner: tcomponent = nil): boolean; + //false if no editor available +begin + result:= componentcanedit and ((aowner = nil) or + (fcomponenteditor.component.owner = aowner)); + if result then begin + fcomponenteditor.edit; + end; +end; + +procedure tdesigner.savecanceled; +begin + fallsaved:= false; +end; + +function tdesigner.beforemake: boolean; +var + int1: integer; + page1: tsourcepage; +begin + result:= true; + for int1:= 0 to fmodules.count - 1 do begin + with fmodules.itempo[int1]^ do begin + if assigned(moduleintf^.sourcetoform) then begin + page1:= sourcefo.findsourcepage(replacefileext(filename,pasfileext),true,true); + if (page1 <> nil) then begin + moduleintf^.sourcetoform(instance,page1.source); + end; + end; + end; + end; +end; + +function tdesigner.selectedcomponents: componentarty; +begin + setlength(result,fselections.count); + move(fselections.datapo^,result[0],length(result)*sizeof(pointer)); +end; + +function tdesigner.clickedcomp: tcomponent; +begin + result:= nil; + if (factmodulepo <> nil) and (factmodulepo^.designformintf <> nil) then begin + result:= factmodulepo^.designformintf.clickedcomponent; + end; +end; + +{ +procedure tdesigner.doasyncevent(var atag: integer); +begin + if atag = showobjectinspectortag then begin + objectinspectorfo.activate; + end; +end; +} +{ tcomponentslink } + +procedure tcomponentslink.notification(acomponent: tcomponent; + operation: toperation); +begin + if operation = opremove then begin + fownercomps.destroynotification(acomponent); + end; + inherited; +end; + +{ tmethodnames } + +initialization + fdesigner:= tdesigner.create; +finalization + fdesigner.Free; +end. diff --git a/mseide-msegui/apps/ide/msedesignparser.pas b/mseide-msegui/apps/ide/msedesignparser.pas new file mode 100644 index 0000000..cec6261 --- /dev/null +++ b/mseide-msegui/apps/ide/msedesignparser.pas @@ -0,0 +1,2210 @@ +{ MSEide Copyright (c) 1999-2018 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit msedesignparser; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +{$if FPC_FULLVERSION >= 030100} {$define mse_fpc_3_2} {$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + mseglob,msedatalist,mselist,mseparser,msetypes,typinfo,msestrings, + msearrayutils; + +type + idesignparser = interface(inullinterface) + end; +type + + sourceitemkindty = (sik_uses,sik_include{,sik_identuse}); + identuseflagty = (idu_first,idu_last); + identuseflagsty = set of identuseflagty; + + sourceitemty = record + filename: nameidty; + startoffset,endoffset: integer; + startpos,endpos: gridcoordty; + case kind: sourceitemkindty of + sik_uses: + (imp: boolean); + sik_include: + (index: integer); + { + sik_identuse: + (identuseflags: identuseflagsty); + } + end; + psourceitemty = ^sourceitemty; + sourceiteminfoaty = array[0..0] of sourceitemty; + psourceiteminfoaty = ^sourceiteminfoaty; + + browserlistitemty = record + index: integer; + end; + pbrowserlistitemty = ^browserlistitemty; + + tsourceitemlist = class(torderedrecordlist) + protected + function getcomparefunc: sortcomparemethodty; override; + function compare(const l,r): integer; + public + constructor create; + function newitem(const astart,aend: sourceposty; + akind: sourceitemkindty): psourceitemty; reintroduce; + procedure updateitem(var aitem: sourceitemty; const astart,aend: sourceposty; + akind: sourceitemkindty); + function find(const apos: sourceposty): psourceitemty; overload; + function find(const apos: sourceposty; + out aindex: integer): psourceitemty; overload; + end; + + tbrowserlist = class(trecordlist) + public + function newitem: pointer; override; + end; + + sourceiteminfoty = record + end; + + compinfoty = record + b: browserlistitemty; + name,uppername: string; + typename,uppertypename: string; + insertpos,namepos,nameend,typepos,typeend,endpos: sourceposty; + end; + pcompinfoty = ^compinfoty; + + tcomponentinfolist = class(tbrowserlist) + protected + function getitempo(const index: integer): pcompinfoty; + procedure finalizerecord(var item); override; + public + constructor create; + function finditembyname(const aname: string): pcompinfoty; + property items[const index: integer]: pcompinfoty read getitempo; default; + end; + + paraminfoty = record + flags: tparamflags; + name: string; + typename: string; + defaultvalue: string; + start,stop: sourceposty; + end; + paraminfoarty = array of paraminfoty; + + methodflagty = (mef_virtual,mef_abstract,mef_inherited,mef_override, + mef_reintroduce,mef_overload{,mef_inline}, + mef_brackets,mef_forward); + methodflagsty = set of methodflagty; + + methodkindty = (mk_none,mk_procedure,mk_procedurefunc,mk_function, + mk_method,mk_methodfunc, + mk_constructor,mk_destructor, + mk_classprocedure,mk_classfunction); + + methodparaminfoty = record + kind: methodkindty; + flags: methodflagsty; + params: paraminfoarty; //last is functionresult + end; + + tdeflist = class; + + procedureinfoty = record + b: browserlistitemty; + params: methodparaminfoty; + name,uppername: string; + intinsertpos,intstartpos,intendpos: sourceposty; + impheaderstartpos: sourceposty; + impheaderendpos: sourceposty; + impendpos: sourceposty; + managed: boolean; + classproc: boolean; + end; + pprocedureinfoty = ^procedureinfoty; + procedureinfoarty = array of procedureinfoty; + procedureinfopoarty = array of pprocedureinfoty; + + tprocedureinfolist = class(tbrowserlist) + private + protected + procedure finalizerecord(var item); override; + function getitempo(const index: integer): pprocedureinfoty; + public + constructor create; + function finditembyname(const aname: string): pprocedureinfoty; + function finditembyuppername(const aname: lstringty; + var info: methodparaminfoty; + const anyparam: boolean = false): pprocedureinfoty; + function matchmethod(const atype: ptypeinfo; + const amanaged: boolean): integerarty; + function matchedmethodnames(const atype: ptypeinfo; + const managed: boolean): msestringarty; + property items[const index: integer]: pprocedureinfoty read getitempo; default; + end; + + interfaceinfoty = record + b: browserlistitemty; + name,uppername: string; + end; + pinterfaceinfoty = ^interfaceinfoty; + + tinterfaceinfolist = class(tbrowserlist) + private + protected + procedure finalizerecord(var item); override; + function getitempo(const index: integer): pinterfaceinfoty; + public + constructor create; + function finditembyname(const aname: string): pinterfaceinfoty; + function finditembyuppername(const aname: lstringty): pinterfaceinfoty; + property items[const index: integer]: pinterfaceinfoty read getitempo; default; + end; + + classinfoty = record + b: browserlistitemty; + deflist: tdeflist; + name,uppername: string; + parentname: string; + componentlist: tcomponentinfolist; + procedurelist: tprocedureinfolist; + headerstop: sourceposty; + managedstart: sourceposty; + procedurestart: sourceposty; + //fileoffset of first line with methods, fileoffset of end of managed + //section if none + managedend: sourceposty; + privatestart: sourceposty; //start of first private segment + privatefieldend: sourceposty; + //before start of first procdef in first private segment + privateend: sourceposty; //end of first private segment + procimpstart,procimpend: sourceposty; + inimplementation: boolean; + end; + pclassinfoty = ^classinfoty; + classinfopoarty = array of pclassinfoty; + + tclassinfolist = class(tbrowserlist) + protected + procedure finalizerecord(var item); override; + procedure initializerecord(var item); override; + function getitempo(const index: integer): pclassinfoty; + public + constructor create; + property items[const index: integer]: pclassinfoty read getitempo; default; + function finditembyname(const aname: lstringty; const interfaceonly: boolean): pclassinfoty; overload; + function finditembyname(const aname: string; const interfaceonly: boolean): pclassinfoty; overload; + end; + + usesinfoty = record + b: browserlistitemty; + name,uppername: string; + end; + pusesinfoty = ^usesinfoty; + usesinfoaty = array[0..0] of usesinfoty; + pusesinfoaty = ^usesinfoaty; + + trootdeflist = class; + + tusesinfolist = class(tbrowserlist) + private + fimplementation: boolean; + function getunitnames(const index: integer): string; + protected + fstartpos,fendpos: sourceposty; + procedure finalizerecord(var item); override; + procedure copyrecord(var item); override; + public + constructor create(aimplementation: boolean); + procedure clear; override; + property startpos: sourceposty read fstartpos; + property endpos: sourceposty read fendpos; + procedure add(const units: lstringarty); + procedure getsourceitems(const alist: tsourceitemlist); + function find(const aname: string): pusesinfoty; + function getunitdeflist(const index: integer): trootdeflist; overload; + function getunitdeflist(const aunitname: string): trootdeflist; overload; + property unitnames[const index: integer]: string read getunitnames; + end; + +// c parser + + functionheaderinfoty = record + b: browserlistitemty; + name: ansistring; + end; + pfunctionheaderinfoty = ^functionheaderinfoty; + + functioninfoty = record +// b: browserlistitemty; + name: ansistring; + start,stop: sourceposty; + end; + pfunctioninfoty = ^functioninfoty; + + identuseinfoty = record + b: browserlistitemty; + startpos: sourceposty; + length: integer; + flags: identuseflagsty; + scope: tdeflist; + end; + pidentuseinfoty = ^identuseinfoty; + identuseinfoaty = array[0..0] of identuseinfoty; + pidentuseinfoaty = ^identuseinfoaty; + + sourcefileinfoty = record + filename: filenamety; + startline,count,includecount: integer; + end; + sourcefileinfoarty = array of sourcefileinfoty; + + includestatementty = record + startpos,endpos: sourceposty; + filename: filenamety; + end; + symbolkindty = (syk_none,syk_nopars,syk_substr,syk_deleted,syk_root,syk_classdef, + syk_procdef,syk_procimp,syk_classprocimp, + syk_vardef,syk_pardef, + syk_constdef,syk_typedef,syk_interfacedef,syk_identuse); + defnamety = record + name: string; + id: nameidty; + end; + pdefnamety = ^defnamety; + defnameaty = array[0..0] of defnamety; + pdefnameaty = ^defnameaty; + + identflagty = (if_first,if_last); + identflagsty = set of identflagty; + varflagty = (vf_property); + varflagsty = set of varflagty; + + symbolflagty = (syf_global); + symbolflagsty = set of symbolflagty; + + definfoty = record + name: string; //'' -> statment + pos,stop1: sourceposty; + owner: tdeflist; + deflist: tdeflist; //can be nil + symbolflags: symbolflagsty; + case kind: symbolkindty of + syk_classdef: (classindex: integer); + syk_procdef,syk_classprocimp,syk_procimp: (procindex: integer); + syk_identuse: (identlen: integer; identflags: identflagsty); + syk_vardef: (varflags: varflagsty); + end; + pdefinfoty = ^definfoty; + definfoarty = array of definfoty; + definfopoarty = array of pdefinfoty; + + defsearchlevelty = (dsl_normal,dsl_qualified,dsl_child,dsl_parent, + dsl_parentclass,dsl_inclass,dsl_unitsearch); + deflistarty = array of tdeflist; + + tdeflist = class(torderedrecordlist) + private + fparent: tdeflist; + fparentid: nameidty; + fparentident: string; + fparentunitindex: integer; + finfocount: integer; + fstart,fstop: sourceposty; + fkind: symbolkindty; + fcasesensitive: boolean; + function comp(const l,r): integer; + function compnopars(const l,r): integer; + function compsubstr(const l,r): integer; + function getname: string; virtual; + function getdefinfopo: pdefinfoty; + function getrootlist: trootdeflist; + function incinfocount: integer; + function internalfinditem(const apos: sourceposty; const firstidentuse,last: boolean; + out scope: tdeflist): pdefinfoty; + protected + finfos: definfoarty; + fparentscope: tdeflist; //class definition + procedure finalizerecord(var item); override; + function getcomparefunc: sortcomparemethodty; override; + function add(const aname: string; const akind: symbolkindty; + const apos,astop: sourceposty): pdefinfoty; overload; + function add(const akind: symbolkindty; const apos,astop: sourceposty): pdefinfoty; overload; + //statment + public + constructor create(const akind: symbolkindty; const acasesensitive: boolean); + procedure clear; override; + procedure startident(const aparser: tparser); overload; + procedure startident(const apos: sourceposty; const alen: integer); overload; + procedure addident(const aparser: tparser); overload; + procedure addident(const apos: sourceposty; const alen: integer); overload; + procedure addemptyident(const aparser: tparser); + procedure endident(const aparser: tparser); overload; + procedure endident(const aparser: tparser; const endpos: sourceposty); overload; + function addidentpath(const aparser: tparser; + const aseparator: char): boolean; + function addidents(const aparser: tparser; + const aseparator: char; const apathseparator: char): boolean; + + function find(const aname: string; + const akind: symbolkindty = syk_none): pdefinfoty; + function getmatchingitems(const aname: string; + const akind: symbolkindty = syk_none): definfopoarty; + function finddef(const anamepath: stringarty; var scopes: deflistarty; + var defs: definfopoarty; + const first: boolean; // break if first found + const level: defsearchlevelty; + const afindkind: symbolkindty = syk_none; + const maxcount: integer = bigint): boolean; overload; virtual; + //true if found + function finddef(const aname: string; const afindkind: symbolkindty; + out ascope: tdeflist): pdefinfoty; overload; + function finditem(const apos: sourceposty; const firstidentuse: boolean; + out scope: tdeflist): pdefinfoty; + function rootnamepath: string; + property parent: tdeflist read fparent; + property parentid: nameidty read fparentid; + property parentscope: tdeflist read fparent; + property kind: symbolkindty read fkind; + property name: string read getname; + property definfopo: pdefinfoty read getdefinfopo; + property rootlist: trootdeflist read getrootlist; + property infos: definfoarty read finfos; + property infocount: integer read finfocount; + end; + + includestatementarty = array of includestatementty; + + proglangty = (pl_pascal,pl_c); + + tfunctionheaders = class; + tfunctions = class; + + cunitinfoty = record + functionheaders: tfunctionheaders; + functions: tfunctions; + end; + + pascalunitinfoty = record + procedurelist: tprocedureinfolist; + interfacelist: tinterfaceinfolist; + classinfolist: tclassinfolist; + interfaceuses,implementationuses: tusesinfolist; + implementationstart: sourceposty; + implementationbodystart: sourceposty; + implementationend: sourceposty; + initializationstart: sourceposty; + finalizationstart: sourceposty; + end; + + unitinfoty = record + interfacecompiled: boolean; + implementationcompiled: boolean; + isprogram: boolean; + itemlist: tsourceitemlist; + deflist: trootdeflist; + sourcefilename: filenamety; + unitname: string; //uppercase + origunitname: string; + formfilename: filenamety; + unitend: sourceposty; + sourceend: sourceposty; + sourcefiles: sourcefileinfoarty; + includestatements: includestatementarty; + case proglang: proglangty of + pl_pascal: + (p: pascalunitinfoty); + pl_c: + (c: cunitinfoty); + end; + punitinfoty = ^unitinfoty; + unitinfopoarty = array of punitinfoty; + + trootdeflist = class(tdeflist) + private + factnode: tdeflist; + funitinfopo: punitinfoty; + flastunitindex: integer; + protected + function getname: string; override; + public + allreadysearched: boolean; + constructor create(const aunitinfopo: punitinfoty); + procedure clear; override; + procedure endnode(const apos: sourceposty); + function beginnode(const aname: string; const akind: symbolkindty; + const apos,astop: sourceposty): pdefinfoty; overload; + function beginnode(const apos: sourceposty; + const aclassinfo: pclassinfoty): tdeflist; overload; + function add(const aname: string; const akind: symbolkindty; + const astart,astop: sourceposty): pdefinfoty; overload; + function add(const apos,astop: sourceposty; + const aprocinfo: pprocedureinfoty): pdefinfoty; overload; + function add(const apos,astop: sourceposty; + const afunctioninfo: pfunctioninfoty): pdefinfoty; overload; + function add(const apos,astop: sourceposty; + const afunctionheaderinfo: pfunctionheaderinfoty): pdefinfoty; overload; + procedure deletenode; + function finddef(const anamepath: stringarty; var scopes: deflistarty; + var defs: definfopoarty; + const first: boolean; // break on first found + const level: defsearchlevelty; + const afindkind: symbolkindty = syk_none; + const maxcount: integer = bigint): boolean; override; + //true if found + function findparentclass(const adescendent: tdeflist; + var defs: definfopoarty): boolean; + + property unitinfopo: punitinfoty read funitinfopo; + property actnode: tdeflist read factnode; + end; + + tfunctionheaders = class(tbrowserlist) + private + function getitempo(const index: integer): pfunctionheaderinfoty; + protected + procedure finalizerecord(var item); override; + public + constructor create; + property items[const index: integer]: pfunctionheaderinfoty + read getitempo; default; + end; + + tfunctions = class(torderedrecordlist) + private + function getitempo(const index: integer): pfunctioninfoty; + function comp(const left,right): integer; + protected + procedure finalizerecord(var item); override; + function getcomparefunc: sortcomparemethodty; override; + public + constructor create; + procedure add(const aname: ansistring; const astart,astop: sourceposty); + function find(const name: ansistring): pfunctioninfoty; + property items[const index: integer]: pfunctioninfoty + read getitempo; default; + end; + + tunitinfo = class + public + info: unitinfoty; + constructor create; + destructor destroy; override; + function infopo: punitinfoty; + end; + + tpascalunitinfo = class(tunitinfo) + public + constructor create; + destructor destroy; override; + end; + +function parametersmatch(const a: ptypeinfo; const b: methodparaminfoty): boolean; +procedure getmethodparaminfo(const atype: ptypeinfo; var info: methodparaminfoty); +function splitidentpath(const atext: string): stringarty; +function mangleprocparams(const aparams: methodparaminfoty): string; +procedure initcompinfo(var info: unitinfoty); +procedure afterparse(const sender: tparser; var unitinfo: unitinfoty; + const aimplementationcompiled: boolean); +function addincludefile(var info: unitinfoty; const afilename: filenamety; + const astatementstart, astatementend: sourceposty): integer; + //returns index + +var + updateunitinterface: function(const unitname: string): punitinfoty of object; + gettype: function (const adef: pdefinfoty): stringarty of object; + resetunitsearched: procedure of object; + +implementation +uses + {sourceupdate,}sysutils,cdesignparser; + //todo: remove cdesignparser, extract c+pascaldesignparser code +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +{$ifdef FPC}{$goto on}{$endif} +type + tparser1 = class(tparser); + +function addincludefile(var info: unitinfoty; const afilename: filenamety; + const astatementstart, astatementend: sourceposty): integer; +begin + with info do begin + result:= length(includestatements); + setlength(includestatements,result+1); + with includestatements[high(includestatements)] do begin + filename:= afilename; + startpos:= astatementstart; + endpos:= astatementend; + end; + end; +end; + +procedure initcompinfo(var info: unitinfoty); +begin + with info do begin + case proglang of + pl_pascal: begin + p.procedurelist.clear; + p.interfacelist.clear; + p.classinfolist.clear; + p.interfaceuses.clear; + p.implementationuses.clear; + p.implementationstart.filenum:= 0; + p.implementationend.filenum:= 0; + p.initializationstart.filenum:= 0; + p.finalizationstart.filenum:= 0; + end; + pl_c: begin + c.functionheaders.clear; + c.functions.clear; + end; + end; + interfacecompiled:= false; + implementationcompiled:= false; + isprogram:= false; + freeandnil(itemlist); + deflist.clear; + unitname:= ''; + origunitname:= ''; + unitend.filenum:= 0; + sourceend.filenum:= 0; + sourcefiles:= nil; + includestatements:= nil; + end; +end; + +procedure afterparse(const sender: tparser; var unitinfo: unitinfoty; + const aimplementationcompiled: boolean); +var + int1: integer; +begin + with tparser1(sender),unitinfo do begin + interfacecompiled:= true; + implementationcompiled:= aimplementationcompiled; + sourceend:= sourcepos; + setlength(sourcefiles,length(fscanners)); + for int1:= 0 to high(fscanners) do begin + sourcefiles[int1].filename:= fscanners[int1].filename; + sourcefiles[int1].startline:= fscanners[int1].startline; + sourcefiles[int1].count:= fscanners[int1].count; + sourcefiles[int1].includecount:= fscanners[int1].includecount; + end; + end; +end; + +function parametersmatch1(const a,b: methodparaminfoty): boolean; +var + int1: integer; +begin + result:= (a.kind = b.kind) and (high(a.params) = high(b.params)); + if result then begin + for int1:= 0 to high(a.params) do begin + with a.params[int1] do begin + if (flags*[pfvar,pfconst,pfout,pfarray] <> + b.params[int1].flags*[pfvar,pfconst,pfout,pfarray]) or + (stringicomp(typename,b.params[int1].typename) <> 0) then begin + result:= false; + break; + end; + end; + end; + end; +end; + +const + tmethodkindtomethodkind: array[tmethodkind] of methodkindty = ( + //mkProcedure, mkFunction, mkConstructor, mkDestructor, + mk_procedure,mk_function,mk_constructor,mk_destructor, + //mkClassProcedure, mkClassFunction, mkClassConstructor, + mk_classprocedure,mk_classfunction,mk_none, + //mkClassDestructor,mkOperatorOverload + mk_none, mk_none + ); + +procedure getmethodparaminfo(const atype: ptypeinfo; + var info: methodparaminfoty); + + function getshortstring(var po: pchar): string; + begin + setlength(result,byte(po^)); + inc(po); + move(po^,pointer(result)^,length(result)); + inc(po,length(result)); + end; + +type + pparamflags = ^tparamflags; + paramrecty = record + Flags : TParamFlags; +// ParamName : ShortString; + end; +var + isfunction: boolean; + int1: integer; + po1: pchar; +begin + with info do begin + kind:= methodkindty(-1); + params:= nil; + if atype^.Kind = tkmethod then begin + with gettypedata(atype)^ do begin + kind:= tmethodkindtomethodkind[methodkind]; + int1:= paramcount; + isfunction:= methodkind = mkfunction; + if isfunction then begin + inc(int1); + end; + if isfunction or (methodkind = mkprocedure) then begin + setlength(params,int1); + po1:= @paramlist; + for int1:= 0 to paramcount - 1 do begin + with params[int1] do begin + flags:= tparamflags( + {$ifdef mse_fpc_3_2}wordset{$else}byteset{$endif}(pbyte(po1)^)); + inc(po1,{$ifdef mse_fpc_3_2}2{$else}1{$endif}); +// inc(po1,sizeof(paramrecty)); +// inc(po1,sizeof(tparamflags)); +// inc(po1,sizeof(byteset)); + name:= getshortstring(po1); + typename:= getshortstring(po1); + if (typename = 'WideString') or (typename = 'UnicodeString') then begin + typename:= 'msestring'; + end + else begin + if typename = 'LongInt' then begin + typename:= 'Integer'; + end + else begin + if typename = 'Double' then begin + typename:= 'Real'; + end; + end; + end; + end; + end; + if isfunction then begin + params[high(params)].typename:= getshortstring(po1); + end; + end; + end; + end; + end; +end; + +function parametersmatch(const a: ptypeinfo; const b: methodparaminfoty): boolean; +var + a1: methodparaminfoty; +begin + getmethodparaminfo(a,a1); + result:= parametersmatch1(a1,b); +end; + +function splitidentpath(const atext: string): stringarty; +begin + result:= nil; + splitstring(atext,result,'.',true); +end; + +function mangleprocparams(const aparams: methodparaminfoty): string; +var + int1: integer; +begin + with aparams do begin + result:= ''; + for int1:= 0 to high(params) do begin + result:= result + '$' + params[int1].typename; + end; + if kind in [mk_function,mk_classfunction, + mk_procedurefunc,mk_methodfunc] then begin + result:= result+'$'; + end; + end; +end; + +{ tsourceitemlist } + +constructor tsourceitemlist.create; +begin + inherited create(sizeof(sourceitemty)); +end; + +function tsourceitemlist.compare(const l,r): integer; +begin + result:= sourceitemty(l).startpos.row - sourceitemty(r).startpos.row; + if result = 0 then begin + result:= sourceitemty(l).startpos.col - sourceitemty(r).startpos.col; + end; +end; + +function tsourceitemlist.getcomparefunc: sortcomparemethodty; +begin + result:= {$ifdef FPC}@{$endif}compare; +end; + +function tsourceitemlist.find(const apos: sourceposty; out aindex: integer): psourceitemty; +var + aitem: sourceitemty; +begin + aitem.startpos.col:= apos.pos.col; + aitem.startpos.row:= apos.line; + if not internalfind(aitem,aindex) then begin + dec(aindex); + end; + if aindex >= 0 then begin + result:= @psourceiteminfoaty(datapo)^[aindex]; + with result^ do begin + if (endpos.row < apos.line) or + (endpos.row = apos.line) and (endpos.col <= apos.pos.col) then begin + result:= nil; + aindex:= -1; + end; + end; + end + else begin + result:= nil; + end; +end; + +function tsourceitemlist.find(const apos: sourceposty): psourceitemty; +var + int1: integer; +begin + result:= find(apos,int1); +end; + +{ +function tsourceitemlist.newitem(const afilename: nameidty; + const startcol,startrow,endcol,endrow: integer; + akind: sourceitemkindty): psourceitemty; +begin + result:= inherited newitem; + with result^ do begin + filename:= afilename; + startpos.col:= startcol; + startpos.row:= startrow; + endpos.row:= endrow; + endpos.col:= endcol; + kind:= akind; + end; +end; +} + +procedure tsourceitemlist.updateitem(var aitem: sourceitemty; + const astart,aend: sourceposty; akind: sourceitemkindty); +begin + with aitem do begin + filename:= astart.filename; + startpos.col:= astart.pos.col; + startpos.row:= astart.line; + startoffset:= astart.offset; + endpos.col:= aend.pos.col; + endpos.row:= aend.line; + endoffset:= aend.offset; + kind:= akind; + end; +end; + +function tsourceitemlist.newitem(const astart,aend: sourceposty; + akind: sourceitemkindty): psourceitemty; +begin + result:= inherited newitem; + updateitem(result^,astart,aend,akind); +end; + +{ tbrowserlist } + +function tbrowserlist.newitem: pointer; +begin + result:= inherited newitem; + pbrowserlistitemty(result)^.index:= count - 1; +end; + +{ tusesinfolist } + +constructor tusesinfolist.create(aimplementation: boolean); +begin + fimplementation:= aimplementation; + inherited create(sizeof(usesinfoty),[rels_needsfinalize,rels_needscopy]); +end; + +procedure tusesinfolist.clear; +begin + inherited; + if not fimplementation then begin + count:= 1; + with pusesinfoty(fdata)^ do begin + name:= 'system'; + uppername:= 'SYSTEM'; + end; + end; +end; + +procedure tusesinfolist.add(const units: lstringarty); +var + int1: integer; + po1: pusesinfoty; +begin + if high(units) >= 0 then begin + int1:= count; + count:= count + length(units); + po1:= getitempo(int1); + for int1:= 0 to high(units) do begin + with po1^ do begin + name:= lstringtostring(units[int1]); + uppername:= struppercase(name); + end; + inc(po1); + end; + end; +end; + +procedure tusesinfolist.getsourceitems(const alist: tsourceitemlist); +var + po1: psourceitemty; +begin + po1:= alist.newitem(fstartpos,fendpos,sik_uses); + with po1^ do begin + imp:= fimplementation; + end; +end; + +procedure tusesinfolist.finalizerecord(var item); +begin + finalize(usesinfoty(item)); +end; + +procedure tusesinfolist.copyrecord(var item); +begin + with usesinfoty(item) do begin + stringaddref(name); + stringaddref(uppername); + end; +end; + +function tusesinfolist.find(const aname: string): pusesinfoty; +var + po1: pusesinfoty; + int1: integer; + str1: string; +begin + result:= nil; + po1:= datapo; + str1:= struppercase(aname); + for int1:= 0 to count - 1 do begin + if str1 = po1^.uppername then begin + result:= po1; + break; + end; + inc(po1); + end; +end; + +function tusesinfolist.getunitdeflist(const index: integer): trootdeflist; +var + po2: punitinfoty; +begin + po2:= {sourceupdater.}updateunitinterface(unitnames[index]); + if po2 <> nil then begin + result:= po2^.deflist; + end + else begin + result:= nil; + end; +end; + +function tusesinfolist.getunitdeflist(const aunitname: string): trootdeflist; +var + po1: pusesinfoty; + po2: punitinfoty; +begin + result:= nil; + po1:= find(aunitname); + if po1 <> nil then begin + po2:= {sourceupdater.}updateunitinterface(aunitname); + if po2 <> nil then begin + result:= po2^.deflist; + end; + end; +end; + +function tusesinfolist.getunitnames(const index: integer): string; +begin + result:= pusesinfoty(getitempo(index))^.name; +end; + +{ tcomponentinfolist } + +constructor tcomponentinfolist.create; +begin + inherited create(sizeof(compinfoty),[rels_needsfinalize]); +end; + +procedure tcomponentinfolist.finalizerecord(var item); +begin + finalize(compinfoty(item)); +end; + +function tcomponentinfolist.getitempo(const index: integer): pcompinfoty; +begin + result:= pcompinfoty(inherited getitempo(index)); +end; + +function tcomponentinfolist.finditembyname(const aname: string): pcompinfoty; +var + po1: pcompinfoty; + int1: integer; +begin + result:= nil; + po1:= datapo; + for int1:= 0 to fcount - 1 do begin + if stringicompupper(aname,po1^.uppername) = 0 then begin + result:= po1; + break; + end; + inc(po1); + end; +end; + +{ tprocedureinfolist } + +constructor tprocedureinfolist.create; +begin + inherited create(sizeof(procedureinfoty),[rels_needsfinalize]); +end; + +procedure tprocedureinfolist.finalizerecord(var item); +begin + finalize(procedureinfoty(item)); +end; + +function tprocedureinfolist.getitempo( + const index: integer): pprocedureinfoty; +begin + result:= pprocedureinfoty(inherited getitempo(index)); +end; + +function tprocedureinfolist.finditembyname(const aname: string): pprocedureinfoty; +var + po1: pprocedureinfoty; + int1: integer; + str1: string; +begin + result:= nil; + po1:= datapo; + str1:= struppercase(aname); + for int1:= 0 to fcount - 1 do begin + if str1 = po1^.uppername then begin + result:= po1; + break; + end; + inc(po1); + end; +end; + +function tprocedureinfolist.finditembyuppername(const aname: lstringty; + var info: methodparaminfoty; + const anyparam: boolean): pprocedureinfoty; +var + po1: pprocedureinfoty; + int1: integer; +begin + result:= nil; + po1:= datapo; + for int1:= 0 to fcount - 1 do begin + if (po1^.params.kind = info.kind) and + (lstringcomp(aname,po1^.uppername) = 0) and + parametersmatch1(info,po1^.params) then begin + result:= po1; + break; + end; + inc(po1); + end; + if (result = nil) and anyparam then begin + po1:= datapo; + for int1:= 0 to fcount - 1 do begin + if (po1^.params.kind = info.kind) and + (lstringcomp(aname,po1^.uppername) = 0) then begin + result:= po1; + info:= po1^.params; + break; + end; + inc(po1); + end; + end; +end; + +function tprocedureinfolist.matchmethod(const atype: ptypeinfo; + const amanaged: boolean): integerarty; +var + info: methodparaminfoty; + int1: integer; + po1: pprocedureinfoty; +begin + result:= nil; + getmethodparaminfo(atype,info); + po1:= datapo; + for int1:= 0 to fcount - 1 do begin + with po1^ do begin + if parametersmatch1(params,info) and (not amanaged or managed) then begin + additem(result,int1); + end; + end; + inc(po1); + end; +end; + +function tprocedureinfolist.matchedmethodnames(const atype: ptypeinfo; + const managed: boolean): msestringarty; +var + ar1: integerarty; + int1: integer; +begin + ar1:= matchmethod(atype,managed); + setlength(result,length(ar1)); + for int1:= 0 to high(ar1) do begin + result[int1]:= msestring(getitempo(ar1[int1])^.name); + end; +end; + +{ tinterfaceinfolist } + +constructor tinterfaceinfolist.create; +begin + inherited create(sizeof(interfaceinfoty),[rels_needsfinalize]); +end; + +procedure tinterfaceinfolist.finalizerecord(var item); +begin + finalize(interfaceinfoty(item)); +end; + +function tinterfaceinfolist.getitempo( + const index: integer): pinterfaceinfoty; +begin + result:= pinterfaceinfoty(inherited getitempo(index)); +end; + +function tinterfaceinfolist.finditembyname(const aname: string): pinterfaceinfoty; +var + po1: pinterfaceinfoty; + int1: integer; + str1: string; +begin + result:= nil; + po1:= datapo; + str1:= struppercase(aname); + for int1:= 0 to fcount - 1 do begin + if str1 = po1^.uppername then begin + result:= po1; + break; + end; + inc(po1); + end; +end; + +function tinterfaceinfolist.finditembyuppername( + const aname: lstringty): pinterfaceinfoty; +var + po1: pinterfaceinfoty; + int1: integer; +begin + result:= nil; + po1:= datapo; + for int1:= 0 to fcount - 1 do begin + if lstringcomp(aname,po1^.uppername) = 0 then begin + result:= po1; + break; + end; + inc(po1); + end; +end; + +{ tclassinfolist } + +constructor tclassinfolist.create; +begin + inherited create(sizeof(classinfoty),[rels_needsfinalize,rels_needsinitialize]); +end; + +procedure tclassinfolist.initializerecord(var item); +begin + with classinfoty(item) do begin + componentlist:= tcomponentinfolist.create; + procedurelist:= tprocedureinfolist.create; + end; +end; + +procedure tclassinfolist.finalizerecord(var item); +begin + with classinfoty(item) do begin + componentlist.free; + procedurelist.free; + end; + finalize(classinfoty(item)); +end; + +function tclassinfolist.getitempo(const index: integer): pclassinfoty; +begin + result:= pclassinfoty(inherited getitempo(index)); +end; + +function tclassinfolist.finditembyname(const aname: lstringty; const interfaceonly: boolean): pclassinfoty; +var + po1: pclassinfoty; + int1: integer; +begin + result:= nil; + po1:= datapo; + for int1:= 0 to fcount - 1 do begin + if lstringicompupper(aname,po1^.uppername) = 0 then begin + if not interfaceonly or not po1^.inimplementation then begin + result:= po1; + end; + break; + end; + inc(po1); + end; +end; + +function tclassinfolist.finditembyname(const aname: string; const interfaceonly: boolean): pclassinfoty; +begin + result:= finditembyname(stringtolstring(aname),interfaceonly); +end; + +{ tidentuselist} +{ +constructor tidentuselist.create; +begin + inherited create(sizeof(identuseinfoty)); +end; + +function tidentuselist.add(const info: identuseinfoty): integer; +begin + result:= inherited add(info); +end; + +procedure tidentuselist.getsourceitems(const alist: tsourceitemlist); +var + po1: psourceitemty; + po2: pidentuseinfoty; + int1: integer; + pos1: sourceposty; +begin + po1:= alist.newitems(count); + po2:= datapo; + for int1:= 0 to count - 1 do begin + pos1:= po2^.startpos; + inc(pos1.offset,po2^.length); + inc(pos1.pos.col,po2^.length); + alist.updateitem(po1^,po2^.startpos,pos1,sik_identuse); + po1^.identuseflags:= po2^.flags; + inc(po1); + inc(po2); + end; +end; +} +{ tdeflist } + +constructor tdeflist.create(const akind: symbolkindty; + const acasesensitive: boolean); +begin + fcasesensitive:= acasesensitive; + fkind:= akind; + inherited create(sizeof(defnamety),[rels_needsfinalize]); +end; + +procedure tdeflist.clear; +begin + inherited; + finfocount:= 0; + finfos:= nil; +end; + +function tdeflist.incinfocount: integer; +begin + result:= finfocount; + inc(finfocount); + if length(finfos) < finfocount then begin + setlength(finfos,finfocount + 4 + finfocount div 4); + end; +end; + +function tdeflist.add(const aname: string; const akind: symbolkindty; + const apos,astop: sourceposty): pdefinfoty; +var + po1: pdefnamety; +begin + po1:= newitem; + if fcasesensitive then begin + po1^.name:= aname; + end + else begin + po1^.name:= struppercase(aname); + end; + po1^.id:= incinfocount; + result:= @finfos[po1^.id]; + with result^ do begin + owner:= self; + name:= aname; + kind:= akind; + pos:= apos; + stop1:= astop; + end; +end; + +function tdeflist.add(const akind: symbolkindty; const apos,astop: sourceposty): pdefinfoty; + //statment +var + int1: integer; +begin + int1:= incinfocount; + result:= @finfos[int1]; + with result^ do begin + owner:= self; + kind:= akind; + pos:= apos; + stop1:= astop; + end; +end; + +procedure tdeflist.startident(const aparser: tparser); +begin + with add(syk_identuse,aparser.sourcepos,emptysourcepos)^ do begin + identflags:= [if_first]; + identlen:= aparser.token^.value.len; + stop1:= pos; + inc(stop1.pos.col,identlen); + end; + aparser.nexttoken; +end; + +procedure tdeflist.startident(const apos: sourceposty; const alen: integer); +begin + with add(syk_identuse,apos,emptysourcepos)^ do begin + identflags:= [if_first]; + identlen:= alen; + stop1:= pos; + inc(stop1.pos.col,alen); + end; +end; + +procedure tdeflist.addident(const aparser: tparser); +begin + with add(syk_identuse,aparser.sourcepos,emptysourcepos)^ do begin + identlen:= aparser.token^.value.len; + stop1:= pos; + inc(stop1.pos.col,identlen); + end; + aparser.nexttoken +end; + +procedure tdeflist.addident(const apos: sourceposty; const alen: integer); +begin + with add(syk_identuse,apos,emptysourcepos)^ do begin + identlen:= alen; + stop1:= pos; + inc(stop1.pos.col,identlen); + end; +end; + +procedure tdeflist.addemptyident(const aparser: tparser); +begin + aparser.lasttoken; + with add(syk_identuse,aparser.sourcepos,emptysourcepos)^ do begin + aparser.nexttoken; + stop1:= aparser.sourcepos; + end; +end; + +procedure tdeflist.endident(const aparser: tparser); +begin + with finfos[finfocount-1] do begin + include(finfos[finfocount-1].identflags,if_last); + stop1:= aparser.sourcepos; + end; +end; + +procedure tdeflist.endident(const aparser: tparser; const endpos: sourceposty); +begin + with finfos[finfocount-1] do begin + include(identflags,if_last); + stop1:= endpos; + end; +end; + +function tdeflist.addidentpath(const aparser: tparser; + const aseparator: char): boolean; +var + ident1: integer; +begin + with aparser do begin + ident1:= getident; + if (token^.kind = tk_name) and (ident1 < 0) then begin + startident(aparser); + while checkoperator(aseparator) do begin + ident1:= getident; + if (token^.kind = tk_name) and (ident1 < 0) then begin + addident(aparser); + end + else begin + break; + end; + end; + endident(aparser); + result:= true; + end + else begin + result:= false; + end; + end; +end; + +function tdeflist.addidents(const aparser: tparser; + const aseparator: char; const apathseparator: char): boolean; +//var +// ident1: integer; +begin + repeat + result:= addidentpath(aparser,apathseparator); + until not result or not aparser.checkoperator(aseparator); +{ + result:= true; + with aparser do begin + repeat + ident1:= getident; + if (token^.kind = tk_name) and (ident1 < 0) then begin + startident(aparser); + endident(aparser); + end + else begin + result:= false; + break; + end; + until not checkoperator(aseparator); + end; +} +end; + +function tdeflist.finddef(const anamepath: stringarty; var scopes: deflistarty; + var defs: definfopoarty; + const first: boolean; // break on first found + const level: defsearchlevelty; + const afindkind: symbolkindty = syk_none; + const maxcount: integer = bigint): boolean; + //true if found +var + ar1: stringarty; + ar3: definfopoarty; + findkind1: symbolkindty; +// po1: pdefinfoty; + ar4: definfopoarty; + int1: integer; + +begin + result:= false; + if first then begin + scopes:= nil; + defs:= nil; + end; + if high(anamepath) >= 0 then begin + setlength(ar4,1); + if high(anamepath) > 0 then begin + findkind1:= syk_none; + ar4[0]:= find(anamepath[0],findkind1); + if ar4[0] = nil then begin + ar4[0]:= find(anamepath[0],syk_nopars); + end; + end + else begin + findkind1:= afindkind; + if first then begin + ar4[0]:= find(anamepath[0],findkind1); + end + else begin + ar4:= getmatchingitems(anamepath[0],findkind1); + additem(pointerarty(ar4),nil); + end; + end; + for int1:= 0 to high(ar4) do begin + if (ar4[int1] = nil) and (fkind = syk_classdef) and + (name <> 'TOBJECT') then begin + //search parent class +// setlength(ar1,1); +// ar1[0]:= fparentident; +// if rootlist.finddef(ar1,ar2,ar3,true,dsl_parentclass,syk_classdef) and +// (ar3[0]^.kind = syk_classdef) then begin + if rootlist.findparentclass(self,ar3) and (ar3[0]^.kind = syk_classdef) then begin + if ar3[0]^.deflist.finddef(anamepath,scopes,defs,first,dsl_inclass, + afindkind,maxcount) then begin + result:= true; + if first then begin + continue; + end; + end; + end; + end; + if ar4[int1] = nil then begin + if (level in [dsl_normal,dsl_parent]) and (fparentscope <> nil) then begin + result:= fparentscope.finddef(anamepath,scopes,defs,first,dsl_parent, + afindkind,maxcount) or result; + end; +// if (not result or not first) and (level = dsl_normal) and +// (fkind in [syk_procimp1,syk_classprocimp]) then begin +// result:= rootlist.finddef(anamepath,scopes,defs,first,level,afindkind) or result; +// end; + if first then begin + continue; + end; + end + else begin + if (ar4[int1]^.kind in [syk_vardef,syk_procdef,syk_procimp]) and (high(anamepath) > 0) then begin + ar1:= {sourceupdater.}gettype(ar4[int1]); + stackarray(copy(anamepath,1,bigint),ar1); + {sourceupdater.}resetunitsearched; + result:= finddef(ar1,scopes,defs,first,dsl_normal,afindkind,maxcount) or result; + continue; + end + else begin + if high(anamepath) > 0 then begin + if ar4[int1]^.deflist <> nil then begin + result:= ar4[int1]^.deflist.finddef(copy(anamepath,1,bigint), + scopes,defs,first,dsl_child,afindkind,maxcount) or result; + end; + end + else begin + result:= true; + if high(defs) <= maxcount then begin + additem(pointerarty(scopes),self); + additem(pointerarty(defs),ar4[int1]); + end + else begin + break; + end; + end; + end; + end; + end; + end; +end; + +function tdeflist.finddef(const aname: string; const afindkind: symbolkindty; + out ascope: tdeflist): pdefinfoty; +var + scopes: deflistarty; + defs: definfopoarty; +begin + if finddef(splitidentpath(aname),scopes,defs,true, + dsl_normal,afindkind) then begin + ascope:= scopes[0]; + result:= defs[0]; + end + else begin + result:= nil; + end; +end; + +function isinrange(const apos: sourceposty; const start: sourceposty; + const stop: sourceposty): boolean; +begin + result:= not((apos.pos.row < start.pos.row) or + (apos.pos.row > stop.pos.row) or + (apos.pos.row = start.pos.row) and + (apos.pos.col < start.pos.col) or + (apos.pos.row = stop.pos.row) and + (apos.pos.col > stop.pos.col) + ); +end; + +function tdeflist.internalfinditem(const apos: sourceposty; + const firstidentuse,last: boolean; out scope: tdeflist): pdefinfoty; +var + int1,int2,lastmatching: integer; +begin + lastmatching:= -1; + if firstidentuse and last then begin + int2:= -1; + for int1:= 0 to finfocount - 1 do begin + with finfos[int1] do begin + if (kind = syk_identuse) and ((stop1.line > apos.line) or + (stop1.line = apos.line) and (stop1.pos.col > apos.pos.col)) then begin + int2:= int1; + break; + end; + end; + end; + end + else begin + int2:= finfocount; + for int1:= 0 to finfocount - 1 do begin + with finfos[int1] do begin + if (kind > syk_deleted) then begin + if isinrange(apos,pos,stop1) then begin + lastmatching:= int1; + end; + if (pos.line > apos.line) or + ((pos.line = apos.line) and (pos.pos.col > apos.pos.col)) then begin + int2:= int1; + if (kind = syk_identuse) and not (if_first in identflags) then begin + with finfos[int1-1] do begin + if (apos.line > pos.line) or (apos.pos.col > pos.pos.col + identlen) then begin + inc(int2); //before next word + end; + end; + end; + break; + end; + end; + end; + end; + dec(int2); + while (int2 >= 0) and (finfos[int2].kind <= syk_deleted) do begin + dec(int2); + end; + end; + if int2 >= 0 then begin + with finfos[int2] do begin + case kind of + syk_vardef,syk_constdef: begin + if (stop1.line < apos.line) or (stop1.line = apos.line) and + (stop1.pos.col <= apos.pos.col) then begin + int2:= lastmatching; + end; + end; + syk_identuse: begin + if (if_last in identflags) and + ((stop1.line < apos.line) or + (stop1.line = apos.line) and + (stop1.pos.col <= apos.pos.col)) then begin + int2:= lastmatching; + end; + end; + else begin + if (deflist <> nil) and + ((deflist.fstop.line < apos.line) or (deflist.fstop.line = apos.line) and + (deflist.fstop.pos.col <= apos.pos.col)) then begin + int2:= lastmatching; + end; + end; + end; + end; + end; + if int2 >= 0 then begin + if finfos[int2].deflist <> nil then begin + result:= finfos[int2].deflist.internalfinditem(apos,firstidentuse,false,scope); + end + else begin + if firstidentuse and not last then begin + result:= internalfinditem(apos,firstidentuse,true,scope); + end + else begin + scope:= self; + result:= @finfos[int2]; + end; + end; + end + else begin + if fparent <> nil then begin + scope:= fparentscope; + result:= @fparent.finfos[fparentid]; + end + else begin + scope:= self; + result:= nil; + end; + end; +end; + +function tdeflist.finditem(const apos: sourceposty; + const firstidentuse: boolean; out scope: tdeflist): pdefinfoty; +begin + result:= internalfinditem(apos,firstidentuse,false,scope); +end; + +procedure tdeflist.finalizerecord(var item); +begin + freeandnil(finfos[defnamety(item).id].deflist); + finalize(defnamety(item)); +end; +{ +procedure tdeflist.comp(const l,r; out result: integer); +var + int1: integer; +begin + result:= (length(defnamety(l).name) - + length(defnamety(r).name)) shl 16; + if result = 0 then begin + for int1:= length(defnamety(l).name) - 1 downto 0 do begin + result:= integer(pcharaty(defnamety(l).name)^[int1]) - + integer(pcharaty(defnamety(r).name)^[int1]); + if result <> 0 then begin + break; + end; + end; + end; +end; +} +function tdeflist.comp(const l,r): integer; +var + po1,po2: pchar; + ch1: shortint; +begin + po1:= pchar(defnamety(l).name); //searchvalue + po2:= pchar(defnamety(r).name); //tableitems + repeat + ch1:= shortint(po1^) - shortint(po2^); + if (ch1 <> 0) or (po1^ = #0) then begin + break; + end; + inc(po2); + inc(po1); + until false; + result:= ch1; +end; + +function tdeflist.compnopars(const l,r): integer; +var + po1,po2: pchar; + ch1: shortint; +begin + po1:= pchar(defnamety(l).name); //searchvalue + po2:= pchar(defnamety(r).name); //tableitems + repeat + ch1:= shortint(po1^) - shortint(po2^); + if (ch1 <> 0) or (po1^ = #0) then begin + break; + end; + inc(po2); + inc(po1); + if po2^ = '$' then begin + if (po1^ = #0) or (po1^ = '$') then begin + break; + end; + end; + until false; + result:= ch1; +end; + +function tdeflist.compsubstr(const l,r): integer; +var + po1,po2: pchar; + ch1: shortint; +begin + po1:= pchar(defnamety(l).name); //searchvalue + po2:= pchar(defnamety(r).name); //tableitems + ch1:= 0; + repeat + if (po1^ = #0) then begin + break; + end; + ch1:= shortint(po1^) - shortint(po2^); + if (ch1 <> 0) then begin + break; + end; + inc(po2); + inc(po1); + until false; + result:= ch1; +end; + +function tdeflist.getcomparefunc: sortcomparemethodty; +begin + result:= {$ifdef FPC}@{$endif}comp; +end; + +function tdeflist.getname: string; +begin + if fparent = nil then begin + result:= ''; + end + else begin + result:= fparent.finfos[fparentid].name; + end; +end; + +function tdeflist.getdefinfopo: pdefinfoty; +begin + if fparent = nil then begin + result:= nil; + end + else begin + result:= @fparent.finfos[fparentid]; + end; +end; + +function tdeflist.getrootlist: trootdeflist; +begin + result:= trootdeflist(self); + while result.fparent <> nil do begin + result:= trootdeflist(result.fparent); + end; +end; + +function tdeflist.find(const aname: string; + const akind: symbolkindty = syk_none): pdefinfoty; +var + int1,int2: integer; + str1: string; +label + exit1; +begin + result:= nil; + if fcasesensitive then begin + str1:= aname; + end + else begin + str1:= struppercase(aname); + end; + sorted:= true; + if akind = syk_nopars then begin + fcomparefunc:= {$ifdef FPC}@{$endif}compnopars; + end + else begin + if akind = syk_substr then begin + fcomparefunc:= {$ifdef FPC}@{$endif}compsubstr; + end + end; + if internalfind(str1,int1) then begin + if akind > syk_deleted then begin + while finfos[pdefnameaty(fdata)^[int1].id].kind <> akind do begin + dec(int1); + if (int1 < 0) then begin + goto exit1; + end; + int2:= comp(str1,pdefnameaty(fdata)^[int1].name); + if (int2 <> 0) then begin + goto exit1; + end; + end; + end; + result:= @finfos[pdefnameaty(fdata)^[int1].id]; + end; +exit1: + fcomparefunc:= {$ifdef FPC}@{$endif}comp; +end; + +function tdeflist.getmatchingitems(const aname: string; + const akind: symbolkindty = syk_none): definfopoarty; +var + int1,int2: integer; + str1: string; + po1: pdefinfoty; +begin + result:= nil; + if fcasesensitive then begin + str1:= aname; + end + else begin + str1:= struppercase(aname); + end; + sorted:= true; + if akind = syk_nopars then begin + fcomparefunc:= {$ifdef FPC}@{$endif}compnopars; + end + else begin + if akind = syk_substr then begin + fcomparefunc:= {$ifdef FPC}@{$endif}compsubstr; + end + end; + if internalfind(str1,int1) then begin + while (int1 >= 0) do begin + int2:= fcomparefunc(str1,pdefnameaty(fdata)^[int1]); + if int2 <> 0 then begin + break; + end; + po1:= @finfos[pdefnameaty(fdata)^[int1].id]; + if po1^.kind <> syk_deleted then begin + additem(pointerarty(result),po1); + end; + dec(int1); + end; + end; + fcomparefunc:= {$ifdef FPC}@{$endif}comp; +end; + +function tdeflist.rootnamepath: string; +var + pa: tdeflist; +begin + result:= name; + pa:= parentscope; + while pa <> nil do begin + result:= pa.name + '.' + result; + pa:= pa.parentscope; + end; +end; + +{ trootdeflist} + +constructor trootdeflist.create(const aunitinfopo: punitinfoty); +begin + funitinfopo:= aunitinfopo; + factnode:= self; + inherited create(syk_root,funitinfopo^.proglang = pl_c); +end; + +procedure trootdeflist.clear; +begin + inherited; + factnode:= self; +end; + +function trootdeflist.beginnode(const aname: string; const akind: symbolkindty; + const apos,astop: sourceposty): pdefinfoty; +begin + result:= factnode.add(aname,akind,apos,astop); + with result^ do begin + deflist:= tdeflist.create(akind,fcasesensitive); + deflist.fparent:= factnode; + deflist.fparentid:= factnode.count - 1; + deflist.fparentscope:= factnode; + deflist.fstart:= apos; + factnode:= deflist; + end; +end; + +procedure trootdeflist.endnode(const apos: sourceposty); +begin + factnode.fstop:= apos; + factnode:= factnode.fparent; +end; + +procedure trootdeflist.deletenode; +begin + with finfos[high(finfos)] do begin + freeandnil(deflist); + kind:= syk_deleted; + end; +end; + +function trootdeflist.beginnode(const apos: sourceposty; + const aclassinfo: pclassinfoty): tdeflist; +begin + with beginnode(aclassinfo^.uppername,syk_classdef,apos,aclassinfo^.headerstop)^ do begin + classindex:= aclassinfo^.b.index; + deflist.fparentident:= aclassinfo^.parentname; + result:= deflist; + end; +end; +{ +procedure trootdeflist.selectnode(const anode: tdeflist); +begin + factnode:= anode; +end; + +procedure trootdeflist.popnode; +begin + factnode:= factnode.fparent; + if factnode = nil then begin + factnode:= self; + end; +end; +} +function trootdeflist.add(const aname: string; const akind: symbolkindty; + const astart,astop: sourceposty): pdefinfoty; +begin + result:= factnode.add(aname,akind,astart,astop); +end; + +function trootdeflist.add(const apos,astop: sourceposty; + const aprocinfo: pprocedureinfoty): pdefinfoty; +begin + result:= factnode.add(aprocinfo^.name+mangleprocparams(aprocinfo^.params), + syk_procdef,apos,astop); + result^.procindex:= aprocinfo^.b.index; +end; + +function trootdeflist.add(const apos,astop: sourceposty; + const afunctioninfo: pfunctioninfoty): pdefinfoty; +begin + result:= factnode.add(afunctioninfo^.name,syk_procimp,apos,astop); + result^.procindex:= -1; //functioninfoty is no browseritem +// result^.procindex:= afunctioninfo^.b.index; +end; + +function trootdeflist.add(const apos,astop: sourceposty; + const afunctionheaderinfo: pfunctionheaderinfoty): pdefinfoty; +begin + result:= factnode.add(afunctionheaderinfo^.name,syk_procdef,apos,astop); + result^.procindex:= afunctionheaderinfo^.b.index; +end; + +function trootdeflist.finddef(const anamepath: stringarty; var scopes: deflistarty; + var defs: definfopoarty; + const first: boolean; // break if first found + const level: defsearchlevelty; + const afindkind: symbolkindty = syk_none; + const maxcount: integer = bigint): boolean; + //true if found + + function unitsearch(alist: trootdeflist): boolean; + begin + if (alist <> nil) and not (alist.allreadysearched and + (level in [dsl_normal,dsl_parent])) then begin + if level in [dsl_normal,dsl_parent] then begin + trootdeflist(alist).allreadysearched:= true; + end; + result:= alist.finddef(anamepath,scopes,defs,first,dsl_unitsearch,afindkind,maxcount); + end + else begin + result:= false; + end; + end; + +var + int1: integer; + alist: trootdeflist; + po1: punitinfoty; + po2: pdefinfoty; +begin + result:= false; + if high(anamepath) >= 0 then begin + alist:= nil; + if (level in [dsl_normal,dsl_parent]) and (high(anamepath) > 0) then begin + //check qualified + if stringicomp(anamepath[0],funitinfopo^.unitname) = 0 then begin + alist:= self; + end + else begin + if funitinfopo^.proglang = pl_pascal then begin + alist:= funitinfopo^.p.interfaceuses.getunitdeflist(anamepath[0]); + if alist = nil then begin + alist:= funitinfopo^.p.implementationuses.getunitdeflist(anamepath[0]); + end; + end; + end; + end; + if alist <> nil then begin + result:= alist.finddef(copy(anamepath,1,bigint),scopes,defs,first, + dsl_qualified,afindkind,maxcount); + end + else begin + flastunitindex:= 0; + if level in [dsl_normal,dsl_parent] then begin + allreadysearched:= true; + end; + result:= inherited finddef(anamepath,scopes,defs,first,level,afindkind,maxcount); + case funitinfopo^.proglang of + pl_pascal: begin + if (not result or not first) and (level in [dsl_normal,dsl_parent,dsl_parentclass]) then begin + for int1:= funitinfopo^.p.implementationuses.count - 1 downto 0 do begin + result:= unitsearch(funitinfopo^.p.implementationuses.getunitdeflist(int1)) or result; + if result and first then begin + flastunitindex:= -int1; + exit; + end; + end; + for int1:= funitinfopo^.p.interfaceuses.count - 1 downto 0 do begin + result:= unitsearch(funitinfopo^.p.interfaceuses.getunitdeflist(int1)) or result; + if result and first then begin + flastunitindex:= int1+1; + exit; + end; + end; + po1:= {sourceupdater.}updateunitinterface('system'); + if po1 <> nil then begin + result:= po1^.deflist.finddef(anamepath,scopes,defs,first, + dsl_unitsearch,afindkind,maxcount) or result; + end; + end; + end; + pl_c: begin + if result and first and (defs[0]^.kind = syk_procdef) then begin + result:= false; + scopes:= nil; + defs:= nil; + end; + if (not result {or not first}) and (level in + [dsl_normal,dsl_parent]) then begin + po2:= cglobals.finddef(anamepath[high(anamepath)]); + if po2 <> nil then begin + result:= true; + additem(pointerarty(defs),pointer(po2)); + end; + end; + end; + end; + end; + end; +end; + +function trootdeflist.findparentclass(const adescendent: tdeflist; + var defs: definfopoarty): boolean; +var + ar1: stringarty; + ar2: deflistarty; +begin + with adescendent do begin + setlength(ar1,1); + ar1[0]:= fparentident; + result:= false; + if adescendent.fparentunitindex > 0 then begin + result:= funitinfopo^.p.interfaceuses. + getunitdeflist(adescendent.fparentunitindex-1). + finddef(ar1,ar2,defs,true,dsl_unitsearch,syk_classdef); + end + else begin + if adescendent.fparentunitindex < 0 then begin + result:= funitinfopo^.p.implementationuses. + getunitdeflist(-adescendent.fparentunitindex). + finddef(ar1,ar2,defs,true,dsl_unitsearch,syk_classdef); + end; + end; + if not result then begin + result:= self.finddef(ar1,ar2,defs,true,dsl_parentclass,syk_classdef); + if result then begin + adescendent.fparentunitindex:= flastunitindex; + end; + end; + end; +end; + +function trootdeflist.getname: string; +begin + result:= funitinfopo^.unitname; +end; + +{ tfunctionheaders } + +constructor tfunctionheaders.create; +begin + inherited create(sizeof(functionheaderinfoty),[rels_needsfinalize]); +end; + +function tfunctionheaders.getitempo(const index: integer): pfunctionheaderinfoty; +begin + result:= pfunctionheaderinfoty(inherited getitempo(index)); +end; + +procedure tfunctionheaders.finalizerecord(var item); +begin + finalize(functionheaderinfoty(item)); +end; + +{ tfunctions } + +constructor tfunctions.create; +begin + inherited create(sizeof(functioninfoty),[rels_needsfinalize]); +end; + +function tfunctions.getitempo(const index: integer): pfunctioninfoty; +begin + result:= pfunctioninfoty(inherited getitempo(index)); +end; + +procedure tfunctions.finalizerecord(var item); +begin + finalize(functioninfoty(item)); +end; + +procedure tfunctions.add(const aname: ansistring; const astart,astop: sourceposty); +begin + with pfunctioninfoty(newitem)^ do begin + name:= aname; + start:= astart; + stop:= astop; + end; +end; + +function tfunctions.comp(const left,right): integer; +begin + result:= stringcomp(ansistring(left),ansistring(right)); +end; + +function tfunctions.getcomparefunc: sortcomparemethodty; +begin + result:= {$ifdef FPC}@{$endif}comp; +end; + +function tfunctions.find(const name: ansistring): pfunctioninfoty; +var + info: functioninfoty; + int1: integer; +begin + result:= nil; + info.name:= name; + if internalfind(info,int1) then begin + result:= items[int1]; + end; +end; + +{ tunitinfo } + +function tunitinfo.infopo: punitinfoty; +begin + result:= @info; +end; + +constructor tunitinfo.create; +begin + with info do begin + if deflist = nil then begin + deflist:= trootdeflist.create(@info); + end; + end; +end; + +destructor tunitinfo.destroy; +begin + with info do begin + itemlist.free; + deflist.Free; + end; + inherited; +end; + +{ tpascalunitinfo } + +constructor tpascalunitinfo.create; +begin + inherited; + with info do begin + proglang:= pl_pascal; + p.procedurelist:= tprocedureinfolist.create; + p.interfacelist:= tinterfaceinfolist.create; + p.classinfolist:= tclassinfolist.create; + p.interfaceuses:= tusesinfolist.create(false); + p.implementationuses:= tusesinfolist.create(true); + end; +end; + +destructor tpascalunitinfo.destroy; +begin + with info do begin + p.procedurelist.Free; + p.interfacelist.Free; + p.classinfolist.Free; + p.interfaceuses.Free; + p.implementationuses.Free; + end; + inherited; +end; + +end. diff --git a/mseide-msegui/apps/ide/mseide.ico b/mseide-msegui/apps/ide/mseide.ico new file mode 100644 index 0000000000000000000000000000000000000000..6a22884dd6b91d5c818266f5e1ad0e2be2e841c9 GIT binary patch literal 12862 zcmeHO2UJwox&~%wYNAGk*rQkg6$J|@L$hH+jZuR&V(-ydqsE3M_HxA-6Qjh64HY$3 zM5gx{hUt|V7#IdL8l#EzeP@myCj)YG-%IXYZ@qVNWbJeIp1r^SKY!mlUS8h#FEP;z ze?RmJjq>se^78Tu#Xr3AT8n?g`*&Rx6%|g`RsQC3xUMqSRr=<#yRH(~RqVQKZ!W9r zDso*Gv$@EqFVd=t)QTcyfkh$1ZN{yXn^X#;R&CI~zI3ij`{vTPF171Yxi00KtI%~R zTvx%HOYXX4GTC2%zsO?Kscj0WP0F_k@{75-#mwurysNg{%eLGc+}7JU);m{<@~&E# zH!R#cCIQPN5f~IQomTS(zV<(YzgVxa7fMS+EIa#VNp6n)`q`44<0Ti4*v}m*&N@(% z^-b}~4BR%{r@pbBK4?96$a>*N>y=YQH?l2vuBeah6bC3{zv>|S27YZ>lh+(M>h?F*O;AH^2~RI5fZ6a7?IvNWXhsMUX~{FEBBb|7cpEW3HW^kQb&sr~lD z+e(2MXtypb**Ld&%~ac}NwzO1SeK5mE=eVBG?tGqS~1bKdWtQ5wsrG-+m0oo(e34P z5?;N0`Rc_B>Ey1$X|V>*9j!zNBK{`)r500Zp~S(yKtoR_}?iI)7V~&&i%D&rF3fb5& zy98Wa@Cku=V!Zj&?xqo)4MV~V$!&D~TFMgYN#pBk5}N3GH`n!TiI@7pp~jCROryKW z1~=ynZuIi`GZOzj-cR|lUgmGp&8H8VuAbKCUDJyAe;Iyzi9=mLu>Iya$GPtuhqn?u z-#Dju*;w1$l%ljmz&56Y>-&AAjSJTFsHg4{sOmuH^`bKq{aJ|toLFB)xL0AQmol7& zE)38xg4hZEmV>KE@c8?nfDQbnjk7KL*O`y*F=l5PZeG-K^Oc1PQ1L(Fzs>4UO3T?d z%degU+a2Ggmu+2WT|BCAbhu`8XVWK<#sO^sTix}&!f+peENt(MTM_2XjP&wf&D z5R7iaVfYrdBi@s@xU&~Cj{cj&_7=aK3H-)|pA@CfF50uwd}yor%=h}MXSM7*ssj0c z8^5E(<|q`GGq08B9CaMs<@m=+`}!Fri$4`4H()0P0HHWGP}$j^f=z&I=Tq3$N7Big z8Ap5m=m8Kuw&@`1(hlCrwnSH9dmlE#SGQ$41s;w2;#>khbY%X=mQ`t%tzVeG-Do=b zjp52^E$g;YE(Hnyvi~Z!l`AFX`9GCk%q-8`UbbtQea#fxyrGr}40d8b$=QFDT|UH0 z^yl`X%R>p+fTwIjBX2>Zw`58;3ZZ;fEU!CV8A9|*I{GlM&~g13Fe_YL9EP7ZeInIG zHmpZBaN_;d-RtW5wK9(CYMR#Hykv}d!(4O5T9BXz39MX2fgB{f2_Fh-jvt)bLMP{z z^YSr*^8ml{GwaL&=F#2seOf>V*>S#xo%6`0pFeq|TJZ@ykto8au(hwU6>;+;eU!_F zQXn6=#9I;KD+#AzBqWOJA{*LGlX)@p!uDRO&H>t_X8I9bj8poU7pD>=>|bX*u^+mi zX6OA${N+Yn+3oZ8lY1SRI~=>06P%wl&^$6qm)KO<5vzC$yLdB`0-ybIpMqgK_B9*U zCXO!ZL{ql%7j&lahc|uk^fz+Aec?@rcVTNkR-B)1^Aze=R6{4~goW6DV0~(6@H;~2GE9gWc z3`jd~MLQoBgJwIvl>&gq)BEKxiR^xLnGCuxf(CiEo!CYWsAONpY{HIocJEqG?>XFm zMYj1v8{_j43Qm#`P9sPd(FKBJS~kwSWufW&E&6kZHMg%6iiIQz?~)&N zzkRkd?_A00J*JE$%4I3+zIA{BlEd%n4ILCj`tVYMDF;MBdj9wq>(R}u1b=RKA9kPG zBwF}c{Fd7@0CQ3!sm9BvzeA{`;V#`LNPvwZz5)cvFfz(CbD(+UB=fE>jhVajIVV-j z+cn^KT8x#VeCO2@ifOTekDEib->&lF`9mcSiYA*G3+v78L5Ec=zj=}x;NEatI|{(8 zSh{pt45SE50O3po47q3Ahmq|^h5`(hw{_`0EZCc`09}AO8^*+#<_$Nmn`zp&#&Gf* z?X~kt0T(1x!+(dPLM5%t%c(g1jeXk!cAr|BwPUL;hc^!jSWJdDJDMg*>ssvqywq=< z0YPFh=<2UVBgo`-Bj|nlv$N{>@>{1sn(`w*Lib^#-jd)2i=-XYMx7d^ni8*=(_g-D zuw=>bf)g39(aYuT`HRzRs1W2;z~&tKx@_}2eOfQ9Xg|Nd>WX+{+P{p+pn-4rDAf)C z+l8Y-xZQjq8yF^t@a3g^Sal?rFBlcV>E#FQmbD`cl(4gpAj+HD(-#&MRu{h|Zy0UN zz#G;SkA-)imN@=ztHx-NuPnA#2`s8^>}?Iqvb<6p;G z!Z3e+M_*wFKl$u;ykRW%u%Z4KkiC7}2s|UXt$XsYQp^mt8#q*NhFPTDIfk;R^+iX9?PyAhLK^# z(S9#4uG&k!Q7s+HjR{aUtjp^jpx-u=8us$VbN$Y_z|8IDlh5!enBVul==N`=7UTld zn5qqMk{M5vFB_%3o~;mYK>{T|m3mbr`+CLMgU*bvN@4J)^hRKY*hUfRjR*lB?s1XE zW5O3ter5Hp1)FdFc7;b5^#}$s<9s#s>vI?Z#V2==?-3UjF6al^!FB|w_Uvz{@ijCc zY1|>f!jU1yL)&zhPAHkVZ}FEqDhoxGx6V6{?JnQGsN{=Lh!b@29}M{QQNqh7c9Sr*JscT3mM)nT1=*AXO{VdCOpZOQHkdRx355hV3_f%UvAwt+GQ2TxZND+T{bM1!D0E64pA9e{o*WEr- zKdIVq=AMSk3wzf!PEIl|pJ3Xx!fkAv`$Ji^lwGP z^Y9~xDiN5qrYk@4<#(gQ2vA8Mxe!b!JI0qkv?)Z|W9fT>8=y|vsGhb?LuI4-qR>EI zWS}tIpULo5%F}!1%*G;TN*6Ml;k6>SG3w_IBhuT1aqYGh(17;s|d@GO{+fW8>Um zru5mygPU~cjwtWmB=9?(gz(=y=lpSpW6J_q9?Qr`ZFK#&!sEiPYU!tH;jd~IC=T^w zG5o-AN|vNkqd75t+~@!R6Q+h*f86A__M`cm<*@wMyLPGn?AP~S{Z8JEA68`bAH<0X zH0@vd4%Dw-SF$c~lItSamWRHMDB#QV!#WzLC!1DJGwxfXJ9Q8$Ad^Zf%IuXgZsoO8 z&L6foHq0uXJqXDxf@A_enUX+wTKUS``XVZ0G5i6N+tZKR9gfM{l(7_!0H%qZ6ew;N zs0^wn>`;pvTMOciVUpIhhhEH~z>|$(moAFh2a3jozYG7xjaYwRsbv z^}u$9$-PZqPBiXbsXwt_edD5BEUYZCLU}8pyx(msT|3n_t)FRNJ0#$w@GIKU5E+6G zm=KQAa%c^LVa4Zt@yH>3D~&feSd%^xtd_T^bEeOLrRf`2u2`MTNY(}hYyBIC8+9J| zo8EUQn!HcM5>*0GNW1-f2D{(;uxZjzm&Af~&^{vT^hWxx>(|;aG2XaztZCLuA2o}I0EuVH?yk7ROp2nkWYdi4s( z@A0mQ#&rN6_)#=bC%U);T@p^0h0zP!&|gP%pU!Pl`{%HyRyhs z$;++0c-XmrHH?pbOq3|04zz|DPggD*R*`?<<+G>m$f-6$WyHhaq^Nzsm7Z}PI2-)_ zND$nyuy*V1Qx|rX%gEjq6{T0B7~0y66v1`*T>=T_^rqNtmE53-yP0XmYX?TvjDwX5Q_}3qLsaEGzgl z3_q8A)&<}3*@H?7Y7GtZfiKyy{wr6n_Q2oh$wN_4N4^^m%`@cD?)N*Jech+s0CK%a@kl4gP*^rM6 z^M=8M8VLNS6dWdrzx41X?tuDmvM?Rg&;LvVa)p^Q(nfpWA9M7ip59C|ZPqL6g2y`RXNgtFGPB1-H#i8AS~v z8ySvPERF9>1#j5mdt? zz(4jxrnF5UG#9ID){RFkvF7E_3!^Qb z7{Q+qN$Bqz`&oWqojNUsodm5RG)TQ}T=D7MnC+iBdSq2FdN4tV6QsedAmO@zU|plO z9^mn)I-7khs+R};S^M|MTh`)7(s@xd(ol=Wv`6m$t65o<5X9IpDe^h-`3ZFChUu`M z9{$TVGg&#Hxu^%7+mp_UBhm`kBGH&o&6-qHxe@$e+CNyNmoJeBK=y>80owN(s^1T0 zg>)iFsMT0mQQ<*?W>~7cQS+e34=57qKYx65WFIgeX|*&h64?aeRpkEU(!8OKQOA=` z?ID{MEuGR0Tp}z|tT%6HGxgpTr2ncpeo(ZhNjlI3aA7^@>^L}IZ;~S6sMeCSZo<(a zoaFjg5lNQngZg(mMRqV~fUR%tZSjX~)L(6I$FDk`w=I|o z%(_i!B&$(VLYlye_vQ8QlZDbnu3Qr7BtOba7~>~PZmb?3ZCI7|hxh>-cs0gv^7b@1 zL>J*+u-M22_?>Ae<_J6bio*PO5p;2=zcToJO}+XFoVyfbqZBfBNC)-wx$0ZFs=T}E z)#=)x7NX{DE-?}`bw9vhPP?|M;P+Uue##{&90)GLng;a{@*$V0HVY`b`~!F;>)~2tR0#~-I(xJGy+_W8k_ZtQqVf|g%?&^*Z z?Vu+Qge_VLTekLikH^txj*G(lQNf_lR&BuUiN=LL*YfNk<}mLjjNzi=^8Z zVW$UpEQd6lll%d=m^*tE{a7tVN)kU45dL5o_P7{Z{T zK=;_Dr!adoD%m+mG~@%CnPvk$;sivM`V~<^=@LLBGQ_SB4OKE! z#jC9aVNvX5a0dtRdicYtpxT44#vkz!{Ggz-AE$lmF{d)?y?6pDpu$TxuP$gEC~fPn zZcS;-)P4f*0H|x)5s_s@-fBR$ouoxw*PrK{l8{-pz z1mY9)dk@tQ5B|76qVmj+^W%3zMWr6i`9&*spOa|6e5qVAgx&W&{gwqp<>BgCC7Bu}$xfLJD>~#Sw(p!>9C|+3gwH4R^`uPD6b7P{}8Ih|-74Z|>xJ+MHjOAUMEUSyeDmXIML(?bsLVh6uel3y9Ak}pPTTK&wlgN4)KK2U-sBW@04v?ie-~V1=hvK~W{R!C% zknDKkLy*E>dhsAAMY@V=1LhG===ex4qvk;apPn_pyGis;>?}Z*Z)cU#a5?`SCM<6{8R>{sA$PZuoUpzQF*k> zZ=S#yPP7l~;qR4Y?!9o?B>sEctM2d7hC@deA{_VNgxWt+$2XQGHvtKvi4l(sa_YCL zRioISw5kC=L4;9PA-wDS=~Vf#-LkQr#N#`VSvEBZ)j&lQUJ@xPuPfmu5ZO{)WCKgP z@Oz_>>(Pan2XUIDBkE(cg7!28!FkX9JKdbY{FEjTCuHI%q+xMK1wfs>$&u^r`R-+PVEkC@Cf3L@D6nC#@8{V`(Tu&At4-wf3*cGgyq=E zbd?u~Afej*Q&Ywo#hTB!quLT5YkUXrpV_-sfmm2Geur!S+LE~yzj8PD*f&SQ&K=l* z2*RU%q#cPGmpqJ!k$yF++>xV=)EGum+=0gL3cVQM(Thjq6ucfZlI^h4sIb+re=WUq zjQ7P5&ZrQq396nH!l2zMMXFWPKZ{>IY^^y7P0dw$O}t*>}+69^J^ zKuC4w4R5NLKM=?*rw;tB=l7`d!ye}+OHb_M^sQZ-wF~%(K$qd8pEt0k^ONgmsb=@Z zmLI!!01BJ=@pRROX_lN5#+w)a?(>r%;r03FKb~Ke&+ErZ@^?7}FV&)yKXZN+3@=zT zOpqGJPYpBO%r= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses +{$ifdef FPC}{$ifdef unix}cthreads,{$endif}{$endif} +// mseopenglgdiinit, + mseskindesign,menusdesign, + msegui,msegraphics,actionsmodule,sourceform,debuggerform, + componentpaletteform,componentstore, + messageform,watchform,objectinspector,breakpointsform,watchpointsform, + stackform,projecttreeform,findinfileform,cpuform,disassform,memoryform, + threadsform,mseguiglob,symbolform, + targetconsole,main,mseguiintf,{msestockobjects,}regunitgroups,guitemplates, + msegraphutils,msefont,stringconsts; +begin + registerfontalias('mseide_source',gui_getdefaultfontnames[stf_courier], + fam_fixnooverwrite,16); + application.createdatamodule(tguitemplatesmo,guitemplatesmo); + if application.terminated then begin + exit; + end; + application.createdatamodule(tstringconstsmo,s); + application.createdatamodule(tactionsmo,actionsmo); + application.createform(tsourcefo, sourcefo); + application.createform(tdebuggerfo,debuggerfo); + application.createform(tcomponentpalettefo,componentpalettefo); + application.createform(tcomponentstorefo,componentstorefo); + application.createform(tmessagefo,messagefo); + application.createform(twatchfo, watchfo); + application.createform(tsymbolfo, symbolfo); + application.createform(tobjectinspectorfo, objectinspectorfo); + application.createform(tbreakpointsfo, breakpointsfo); + application.createform(twatchpointsfo, watchpointsfo); + application.createform(tstackfo, stackfo); + application.createform(tprojecttreefo, projecttreefo); + application.createform(tfindinfilefo, findinfilefo); +// application.createform(tcpufo, cpufo); + application.createform(tdisassfo, disassfo); + application.createform(tmemoryfo, memoryfo); + application.createform(tthreadsfo, threadsfo); + application.createform(ttargetconsolefo,targetconsolefo); + application.createform(tmainfo, mainfo); + createcpufo; + application.run; +end. diff --git a/mseide-msegui/apps/ide/mseide.prj b/mseide-msegui/apps/ide/mseide.prj new file mode 100644 index 0000000..31b76a4 --- /dev/null +++ b/mseide-msegui/apps/ide/mseide.prj @@ -0,0 +1,1047 @@ +[componentpalette] +order0=0 +order1=0 +order2=0 +order3=0 +order4=0 +order5=0 +order6=0 +order7=0 +order8=0 +order9=0 +order10=0 +order11=0 +order12=0 +order13=0 +order14=0 +order15=0 +order16=0 +order17=0 +order18=0 +[projectoptions] +projectdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide +projectfilename=/home/mse/packs/standard/git/mseide-msegui/apps/ide/mseide.prj +mainfile=mseide.pas +targetfile=mseide${EXEEXT} +messageoutputfile= +makecommand=${COMPILER} +makedir= +unitdirs=4 + ${MSEDIR}lib/addon/*/ + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}kernel/ + ${MSELIBDIR}*/ +unitpref=-Fu +incpref=-Fi +libpref=-Fl +objpref=-Fo +targpref=-o +befcommand=0 +aftcommand=0 +makeoptions=4 + -Xg -l -Mobjfpc -Sh -Fcutf8 + -gl -O- + -B + -O2 -XX -Xs -CX +codetemplatedirs=1 + ${TEMPLATEDIR} +toolmenus=0 +toolfiles=0 +toolparams=0 +fontnames=0 +scriptbeforecopy= +scriptaftercopy= +newprojectfiles=4 + ${TEMPLATEDIR}default/project.pas + ${TEMPLATEDIR}default/main.pas + ${TEMPLATEDIR}default/main.mfm + ${TEMPLATEDIR}default/main_mfm.pas +newprojectfilesdest=4 + ${%PROJECTNAME%}.pas + + + +newfinames=3 + Program + Unit + Textfile +newfifilters=3 + "*.pas" "*.pp" + "*.pas" "*.pp" + +newfiexts=3 + pas + pas + +newfisources=3 + ${TEMPLATEDIR}default/program.pas + ${TEMPLATEDIR}default/unit.pas + +newfonames=10 + Mainform + Simple Form + Docking Form + Datamodule + Subform + Scrollboxform + Tabform + Report + Scriptform + Inherited Form +newfonamebases=10 + form + form + form + module + form + form + form + report + script + form +newfosources=10 + ${TEMPLATEDIR}default/mainform.pas + ${TEMPLATEDIR}default/simpleform.pas + ${TEMPLATEDIR}default/dockingform.pas + ${TEMPLATEDIR}default/datamodule.pas + ${TEMPLATEDIR}default/subform.pas + ${TEMPLATEDIR}default/scrollboxform.pas + ${TEMPLATEDIR}default/tabform.pas + ${TEMPLATEDIR}default/report.pas + ${TEMPLATEDIR}default/pascform.pas + ${TEMPLATEDIR}default/inheritedform.pas +newfoforms=10 + ${TEMPLATEDIR}default/mainform.mfm + ${TEMPLATEDIR}default/simpleform.mfm + ${TEMPLATEDIR}default/dockingform.mfm + ${TEMPLATEDIR}default/datamodule.mfm + ${TEMPLATEDIR}default/subform.mfm + ${TEMPLATEDIR}default/scrollboxform.mfm + ${TEMPLATEDIR}default/tabform.mfm + ${TEMPLATEDIR}default/report.mfm + ${TEMPLATEDIR}default/pascform.mfm + ${TEMPLATEDIR}default/inheritedform.mfm +forcezorder=0 +stripmessageesc=0 +copymessages=0 +closemessages=1 +checkmethods=1 +colorerror=-1610612712 +colorwarning=-1610612717 +colornote=-1610612716 +usercolors=30 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +usercolorcomment=30 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +formatmacronames=0 +formatmacrovalues=0 +settingsfile= +settingseditor=0 +settingsdebugger=0 +settingsstorage=0 +settingsprojecttree=0 +settingsautoload=0 +settingsautosave=0 +modulenames=3 + ACTIONSMO + MAINFO + SOURCEFO +moduletypes=3 + TACTIONSMO + TMAINFO + TSOURCEFO +modulefiles=3 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/actionsmodule.mfm + /home/mse/packs/standard/git/mseide-msegui/apps/ide/main.mfm + /home/mse/packs/standard/git/mseide-msegui/apps/ide/sourceform.mfm +befcommandon=0 +makeoptionson=4 + 63 + 31 + 34 + 32 +aftcommandon=0 +unitdirson=4 + 196671 + 65599 + 196671 + 65599 +macroon=0 +macronames=0 +macrovalues=0 +macrogroup=0 +groupcomments=6 + + + + + + +toolsave=0 +toolhide=0 +toolparse=0 +toolmessages=0 +toolshortcuts=0 +fontalias=0 +fontancestors=0 +fontheights=0 +fontwidths=0 +fontoptions=0 +fontxscales=0 +expandprojectfilemacros=4 + 1 + 1 + 1 + 0 +loadprojectfile=4 + 1 + 1 + 1 + 0 +newinheritedforms=10 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 +uid=0 +sourcefilemasks=3 + "*.pas" "*.dpr" "*.lpr" "*.pp" "*.inc" + "*.c" "*.cc" "*.h" + "*.mfm" +syntaxdeffiles=3 + ${SYNTAXDEFDIR}pascal.sdef + ${SYNTAXDEFDIR}cpp.sdef + ${SYNTAXDEFDIR}objecttext.sdef +filemasknames=3 + Source + Forms + All Files +filemasks=3 + "*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + *.mfm + * +showgrid=1 +snaptogrid=1 +moveonfirstclick=1 +noformdesignerdocking=0 +gridsizex=8 +gridsizey=8 +autoindent=1 +blockindent=1 +linenumberson=0 +rightmarginon=1 +rightmarginchars=80 +scrollheight=0 +tabstops=4 +spacetabs=0 +showtabs=0 +tabindent=0 +editfontname=mseide_source +editfontheight=0 +editfontwidth=0 +editfontextraspace=0 +editfontcolor=-1879048183 +editbkcolor=-1879048186 +statementcolor=14745599 +editfontantialiased=1 +editmarkbrackets=1 +backupfilecount=2 +encoding=1 +codetemplatedirs=1 + ${TEMPLATEDIR} +debugcommand=${DEBUGGER} +debugoptions= +debugtarget= +runcommand= +xtermcommand=xterm -S${PTSN}/${PTSH} +remoteconnection= +uploadcommand= +gdbprocessor=auto +gdbservercommand= +gdbservercommandattach= +beforeconnect= +afterconnect= +beforeload= +afterload= +beforerun= +sourcebase= +sourcedirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ + ./ +defines=0 +progparameters= +progworkingdirectory= +envvarnames=0 +envvarvalues=0 +defineson=0 +stoponexception=0 +valuehints=1 +activateonbreak=1 +raiseonbreak=1 +showconsole=0 +externalconsole=0 +settty=1 +gdbdownload=0 +downloadalways=0 +startupbkpt=0 +startupbkpton=0 +gdbsimulator=0 +gdbserverstartonce=0 +gdbloadtimeout= +gdbserverwait=0 +nogdbserverexit=0 +gdbservertty=0 +exceptclassnames=1 + EconvertError +exceptignore=1 + 0 +nodebugbeginend=0 +sigsettings=27 + 1,1,T,F + 3,3,T,F + 4,4,T,F + 6,6,T,F + 7,7,T,F + 8,8,T,F + 9,9,T,F + 10,10,T,F + 11,11,T,F + 12,12,T,F + 13,13,T,F + 15,15,T,F + 16,16,T,F + 17,17,F,F + 18,18,T,F + 19,19,T,F + 20,20,T,F + 21,21,T,F + 22,22,T,F + 23,23,T,F + 24,24,T,F + 25,25,T,F + 26,26,T,F + 27,27,T,F + 28,28,T,F + 29,29,T,F + 30,30,T,F +defaultmake=1 +[breakpoints] +on=0 +path=0 +line=0 +address=0 +addbkpt=0 +ignore=0 +condition=0 +panels=2 + panel1 + panel2 +units= + ( + a=0,4132,6,Pascal Units + ) +cmodules= + ( + a=0,4132,6,C Modules + ) +files= + ( + a=0,4132,6,Text Files + ) +[componentstore] +storedir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ +filename= +[components] +[selecteditpage] +colwidth=100 +x=0 +y=0 +cx=0 +cy=0 +[progparams] +progparamhistory=0 +workdirparamhistory=0 +envvarons=0 +[edit] +hintwidth=0 +hintheight=0 +finddtext= +findhistory=0 +findoptions=1 +editpos=3 + 0,0 + 0,0 + 0,0 +bookmarks0=0 +bookmarks1=0 +bookmarks2=0 +sourcefiles=3 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/main.pas + /home/mse/packs/standard/git/mseide-msegui/apps/ide/sourceform.pas + /home/mse/packs/standard/git/mseide-msegui/apps/ide/actionsmodule.pas +relpaths=3 + main.pas + sourceform.pas + actionsmodule.pas +ismoduletexts=3 + 0 + 0 + 0 +modules=3 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/main.mfm + /home/mse/packs/standard/git/mseide-msegui/apps/ide/actionsmodule.mfm + /home/mse/packs/standard/git/mseide-msegui/apps/ide/sourceform.mfm +moduleoptions=3 + 0 + 0 + 0 +visiblemodules=3 + -1 + -1 + -1 +nomenumodules=3 + 0 + 0 + 0 +[sourcefo.tabwidget] +tabsize=140 +firsttab=0 +index=0 +[layout] +windowlayout=567 + [mainfo.openform] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/sourceform.mfm + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + filehistory=2 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/sourceform.mfm + /home/mse/packs/standard/git/mseide-msegui/apps/ide/actionsmodule.mfm + filefilterindex=0 + filefilter=*.mfm + [mainfo.projectfiledia] + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + [mainfo.openfile] + filenames=0 + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + filehistory=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/main.pas + filefilterindex=0 + filefilter="*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + [mainfo.basedock] + splitdir=2 + useroptions=146560 + [mainfo] + splitdir=0 + useroptions=33554555 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=25 + cx=323 + cy=64 + rcx=0 + rcy=0 + wsize=0 + active=1 + visible=1 + [targetconsolefo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=209 + y=385 + cx=368 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [threadsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=37 + y=270 + cx=349 + cy=276 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo] + splitdir=0 + useroptions=16507 + stackedunder=cpui386fo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=100 + y=100 + cx=453 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo.add] + value=0 + [memoryfo.memon] + value=0 + [memoryfo.bitwidth] + value=0 + [memoryfo.cnt] + value=0 + [disassfo] + splitdir=0 + useroptions=16491 + stackedunder=findinfilefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=162 + y=502 + cx=564 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [findinfilefo] + splitdir=0 + useroptions=16491 + stackedunder=componentpalettefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=548 + y=115 + cx=369 + cy=198 + rcx=0 + rcy=0 + [projecttreefo] + splitdir=0 + useroptions=16491 + stackedunder=memoryfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=263 + y=431 + cx=286 + cy=201 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [projecttreefo.grid] + propcolwidthref=135 + width0=141 + sortdescend0=0 + width1=129 + sortdescend1=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=16 + [stackfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=295 + rcx=0 + rcy=0 + [watchpointsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=120 + y=368 + cx=483 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [watchpointsfo.grid] + propcolwidthref=352 + sortdescend0=0 + values1=0 + values1_ci=-1 + width1=33 + sortdescend1=0 + values2=0 + width2=158 + sortdescend2=0 + width4=34 + sortdescend4=0 + values5=0 + values5_ci=-1 + width5=38 + sortdescend5=0 + values6=0 + width6=184 + sortdescend6=0 + [breakpointsfo] + splitdir=0 + useroptions=16491 + stackedunder=projecttreefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=107 + y=404 + cx=636 + cy=128 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [breakpointsfo.bkptson] + value=1 + [objectinspectorfo] + splitdir=0 + useroptions=16491 + stackedunder=mainfo.panel2 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=724 + y=157 + cx=296 + cy=566 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [objectinspectorfo.grid] + propcolwidthref=286 + width0=105 + sortdescend0=0 + width1=175 + sortdescend1=0 + [symbolfo] + splitdir=0 + useroptions=16507 + stackedunder=disassfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=142 + y=257 + cx=361 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [symbolfo.grid] + propcolwidthref=222 + values0=14 + + + + + + + + + + + + + + + width0=111 + sortdescend0=0 + width1=135 + sortdescend1=0 + [symbolfo.symbol] + [watchfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=298 + cx=313 + cy=236 + rcx=0 + rcy=0 + [watchfo.grid] + propcolwidthref=118 + values0=0 + values0_ci=-1 + sortdescend0=0 + values1=0 + width1=152 + sortdescend1=0 + values3=0 + values3_ci=-1 + sortdescend3=0 + values4=0 + values4_ci=-1 + width4=13 + sortdescend4=0 + [watchfo.watchon] + [watchfo.expression] + [watchfo.watcheson] + value=1 + [messagefo] + splitdir=0 + useroptions=49259 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=510 + cx=675 + cy=95 + rcx=0 + rcy=0 + [componentstorefo] + splitdir=0 + useroptions=24699 + stackedunder=symbolfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=305 + y=101 + cx=445 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentstorefo.grid] + propcolwidthref=435 + width0=111 + sortdescend0=0 + sortdescend1=0 + width2=112 + sortdescend2=0 + width3=185 + sortdescend3=0 + [componentstorefo.storefiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.groupfiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.compfiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentpalettefo] + splitdir=0 + useroptions=24683 + stackedunder=_mse_actionsmo_mse_ + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=25 + cx=685 + cy=103 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [componentpalettefo.componentpages] + activetab=0 + [debuggerfo] + splitdir=0 + useroptions=24683 + parent=mainfo.basedock + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=28 + rcx=0 + rcy=0 + [sourcefo] + splitdir=0 + useroptions=16489 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=675 + cy=507 + rcx=0 + rcy=0 + [actionsmo.watchesonact] + checked=1 + [actionsmo.bluedotsonact] + checked=1 + [cpui386fo] + irqoff=0 + splitdir=0 + useroptions=16491 + stackedunder=componentstorefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=337 + y=295 + cx=273 + cy=207 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [mainfo.panel1] + splitdir=2 + useroptions=33586667 + stackedunder=mainfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=118 + cx=685 + cy=605 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel2] + splitdir=2 + useroptions=33586667 + stackedunder=_mse_mainfo_mse_ + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=189 + cx=323 + cy=534 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [_mse_mainfo_mse_] + splitdir=0 + useroptions=16507 + stackedunder=mainfo.panel1 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=45 + y=165 + cx=469 + cy=149 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 +[targetconsole] +finddtext= +findhistory=0 +findoptions=1 diff --git a/mseide-msegui/apps/ide/mseide.rc b/mseide-msegui/apps/ide/mseide.rc new file mode 100644 index 0000000..8dda4b4 --- /dev/null +++ b/mseide-msegui/apps/ide/mseide.rc @@ -0,0 +1,24 @@ +MAINICON ICON "mseide.ico" +1 VERSIONINFO +FILEVERSION 3,0,0,0 +PRODUCTVERSION 3,0,0,0 +FILEFLAGSMASK 0 +FILEOS 0x40000 +FILETYPE 1 +{ + BLOCK "StringFileInfo" + { + BLOCK "040904E4" + { + VALUE "CompanyName","" + VALUE "FileDescription","MSEide Free Pascal RAD suite" + VALUE "FileVersion","3.3.0.0" + VALUE "InternalName","" + VALUE "LegalCopyright","2013 (c) Martin Schreiber" + VALUE "OriginalFilename","mseide.pas" + VALUE "ProductName","MSEide" + VALUE "ProductVersion","3.0.0" + } + } +} + diff --git a/mseide-msegui/apps/ide/mseide.res b/mseide-msegui/apps/ide/mseide.res new file mode 100644 index 0000000000000000000000000000000000000000..a1069c1a6633cf7fcce073b490346036da5c8674 GIT binary patch literal 13624 zcmeHO2V7J~x4*DUQxh?^*cB{*ih`&pOH&XVYAghe4HbJ=?6H^FV)PSZOpFqHMMaH9 zv9P_dyDZxqu&}T!Xo}Iq`u=w>teXY-^1YXQ-|zk2o8R5txp(Hy{Lh&)XU;h@OArLn z9-lXFs1LG#NCBbM8&=qQwg(`WWBCkL$#bv^!kQtS7gGQy-RVA%GX{wXj zo>cavv?oP%%C{%EJ>^v=nLSCR(!T(IVS!nzGRq}q3EwQpDdyfQX5KbGxM{w3-Fz<# zS5bCW(fu2R4{jDPe<f&V5;YCLNa<*V!-4=Z_R!I$Ct)yP_Ls3xCKgxPL=+;&aaM=KRS$ zW#8@nx8gUOEm~EHlwZotF1?>sdh={)<}u5ebjyi-mZP7Q9NuC%w6WyC+LA9;mF!!I zs~Fe*HN^+ln-6U=AK6xPYNOT1 zXWuEibGh_tM%mdzmSek1ff;CbEh*VHzj(t8^SY_#)su==j4w({CNE@GO)Ok9*}Q(b zdCT0Q9ShBS(?m&KWb>lmyng-W)ho%gUc%G}J?FkAR|q2hCj6xZ#?t&;EAO85Zf4n) z2!8Cx`Oc;T#sf@uRxQ=&|hBTW+{a2Y2t$lH`yQ)+y{ zoS_AaMjIE7$cb>X-M{$8o(hj|;S6nJx^~KN_nMabP$kU;3DwhA@t4fsGM(C*%dtMZ zVZDCRdgfr+*V{`W8(Zg=fUAqgkeDY&nLh4q9Nj}dJW!v|Q5)Y*8tp5IYN(EGsU6Tp z8`lmGb;AM-9|aqe!lc96aE3K~{qhBc{}J!|oCw17)fUtFBgUKObq{W7MEt)Dzoo>g z$|Ko+=aTi(*VbdZNS<$-SG;n9d46JHN(^8d5`%Q{?KP3j)qQ+bJ$;m2>Ae1QW{ejr z#+wu2ArB(*0|-SB4MnJ+W;A0*dlej6M}f!pPkC(MH*T9-aA=e1#C}6&hW^e~4L3)T zF9#L>BmSFMC6Ji+L39wbY-pdbi2gv*` zZn)%uZp;XxA}8}%v0jkWk;CxF?@T_YE^!Zn8A<=mYJQ7f#sq%Dk}-u_<`(W>YdX5i zbm1G_&5IiLePy2Pzm4BoVz%as%bB;zvrbq~?6dx3t!4A9lI0%@5*o8(y@601;iKr` z<$z6s?ChT3$vwBb8#9vj^2tv?_|&Y0s7t!KDLRow`CZ)E3=i$jnGW#CJQm+0@neoG z{HS1EO2MwBrmwac&wQ!BabCm9R>&kE;a^_Aip}MU-1407%dcjXXY484x6-mCbcG+CAL6E1k?25Z zy?qjx<@O>D!&9?mvZIK~6dm8niSknQZm5m#U>MiSm^#RmHr}*#zA1epNYH@<);)Qi z3?x*W4|#Rl4>nD{jdRy_{UphGfL}YMX!c-JQkZUFTg*Xrq=)|V1yt8BpFL5o8H1Hb z6zrbw=b`98Ui=Vu#mW&5kU!bQTkh|X8$?4*NR*?9%4oJvPb)7VgLOe;k<^x`J$ z>BfxpdGX6*2MqJc&)Cp5k#tdanxcc3pa+dVs@1FKzflz)3-3U@^Zh(ok)GNe(;aU) zGO{@gekg>HoZ#p}9o0fNDwrf8Z9D|YczCPf+!5{VOeLT5Px)^vF0%6P^AcO2M<#>d z#5Ld#ZXz1gSQ_P<*PTWxkj`%M&h9J*&3tN?0{}A5AD2TVvf~>v8FXPV4f1S0y_>2~ z$-a)(gx%=u0rj3gvO2#-<@qC8VED)hPLU8qBS{$D6M|%1`H5-g65}^Jb(fB*vv1^! zg%k9@0xn3Xh5uG-g;G-aAgkj1mzLd&*#qmTH%_S89iIG@ z$6_+v*nMfaDZOf~fQPzWvmi(;23_@O5{yi47)kH*A8j@3m)|`L(iH7I$+-_5^_Bzz z8c8#>qbfO6IXy}~Z;))su-vp!d8gB>(92}b{)^3|uMj+_fX+GkS=o*Sx|IIt(Q^4v z%^vZ@cxWY)K?C0~D797q+lAx&xnUlV4O9~Zd+-uJtXUJx7mV}g^!LQZ9&jT72S{Lt97nC+y;EimB+x!PV)a1Xdn)&4i)>u|gESeT89nct}^0QJ`Zm zGYXGwF1vXgOEZj+m%si@y^Dv;D3AQ_FSy{ZFc(ycnH4ur+m7u9^Gg z=>uSx!M2eHxWPiez&$NgyEORf*{`et^`P@jU#)Q|a@>M}%t#M)qedKtck!9M)N|NH z`HSO0JJ=2b)sp$8qkbJ3NE&x|bKzKj!_nQ^Yo`^=dvEcVTPyQLm3J@OPJU6oXIaV8 zaj+A#Q6G|qnO)nH(wN};ize5leVAcvh9_rGL(t+1BXBML{ zxeFFDb_6|lYA9r*))!qK{wR3>1uhuU+^}w%;m~H?`EQijH)K)?#eWFTBM8s+leTYm zlx>-f)z&zoD`^sws}*IH(RqF8&`3W@bDUfLMI|KVmf;R_&iT0`FP;=E?Czs^zcHkU zKdOyp>lDD?_Va>X!kX)>pB=B%%-HUohs+BHG&D?$HLRLs+_y%5@}T1$GW)=n;(8lxZ7fwbqbj=-vfVdh6ywD;hL(V+w!P9N0~R46;#gFm7bMB1h6 zM}i+foua9)ra==$(?+5IA6|%$FvyF^@Q^PU@angxF7<2PqD|A0wb0f4Fn7(sw)zSE z4NJxvKU-}0c8})T83p@c75~+Fj~-sHIG0|&Zw1Wz!ts3_!b56f=wxVS=;wA`!X8lL z1Pn-rLZFlk!~+KBkCKOPF}!*O@!*HlI~O->=}s2Vpy3n1-n&3EMB z;7DhMW15JA-5|;E+OQlO=8rUPnQJ(*U3=-c;^7?x913Xy_PcYmeOOhFVIpLn%zTN;POb#geZoBo?ccw2_LG$14 z)w9uyU*CW8J9V}Ax#HZQp`36Z=8@>sYFsyW~r2ND{q~(eY?}Tbx!fzp>SqlB$N0lmjuGo!9&)`16CP};RTS~ zexBUkSeV?5=_{}hKsB*reZ-x86wQ2vUF&fp>Os6wE!VI9h^tu+@Kk2xwX32oKBDnK z@52B5#|o$gyv`4;vMB6cn;U6b59zF*Ho&-gvf+!hy3>bLKU|fGg_R{mn7oykykBoC z-8jRX8gCrZ84frl{PNB;Scc#O8pJ|baC8HVVfmss+;YgZmBt&^T)ky7SS@SY;KIPc zE4FM~yJmeRBSGWST;tUu$e?w>-|Ded-tv9YmZ)KfLfS2t)7kOwL#Igs>=FysVfK+; zryJaVZM>g;a+G1k1mowcbl)Ao6wVWHE6t`#!Gp?c8MeclN%Ig=; zosm28FqL5sgOj2z-Z%P1y5Ma5`x8O)Zu#~7_RLt)OD3gC+g6m`3}tBQHCAqd!5?5ip~s+_(4b&Ud*1M7tbz6L5Xza;-$M{WNV*g1m{z(8{YVwGbBXTQ zUUk+vIhR!lo0*qgdF5N{{*`$j2jcbIDLpZcFMg_YK&>NVI=q@4;k9=CdKdgnpZzRq z)=lTun!ISOcrCkM>l-g=+DYTnOx(i%yAh)gOq+fwE=uZG52leY(39QYlRdBj=KgQi zB1d<~!*|y1OcjjnKuT*7mF}n2zumx(nGUD(&tO!{VjF_AUfCR}uoSXt~D<3^}fTuF*t-CJ74spRh z;dF+iqYq{-dRK3nh*)CX-JujpTRb_KKPiNqzt#G){O~4KN;o?fvxb~Os!g91pZ@}_ z{nLdWUKNxcR1oY0N%IbnaIJT9ZPQLJ;Bl+Gn0YI-zYG33hxW_b)#HcId7(5)QH#cR zf$#sTNl}v!*w|1hvUyQC(R9hynb4mu>z8?Uf?{wRQ6D3(UJFGeH>x z_?4G3H4U1A#(Deqx3iU?TBl;u?!_~JS-U-jVl`q)a1&Tj9=txD(g3>1?n}a*q5hVXeXS2#)dDz??FQ_N7&6n6zItdri%l-6wTjP z`!Htq=x)d5@&Dvm6;JOjc74hI5fAjH)yXJ3w3m)-8L1@XFS__faorgvd90_LHz}2Vpxum*==mx^PMq=!FP|18vO= z^q%OGAZ`R5#u$u$9rjA*CK@-+s_8#s`~6-1J9Z+#|GarIh`i-a3C2Rh?oa2BZtJ|t zqiYyK?EYS(vd%k0-LxtVa*`7i==_k%56H>J+`-&`qLtJ{?s$UHfzvAJONZrYn8YwH z`c?m^iuJNcRl^Ku!dlZV#B9F5uA}+;C392i!hh=Z40nZQq!-WAnu! zk>D^t#52EDgO9FUa3LXM-0-}%^*G_ALPLP=safa1?2@TuXTi~s4Q_3mHQ4y+bi@8n zb*Iv6#!tu-5H;dgWC*3FH|fZbyFxTX$q*HW}QuUCvNGtS$cb$M|6}LRcU7)<(6!5P$@72;$#E^uvWe&bNp>vm-tEVTh>sA|8bz zOmJ?5x4d`nc=@^#LjJ!`PZ)% zX~WrZ@9B0fCL<3wFDm#Pm-rjlU+xsYEkC#pzKnV1AOupd<0%d%S3L}+Ys*genB7<| zIlXDH4}VthsS+~uVPEoqjk>U*Kzc(OF+61+8Pp|UK0&9EL55IwUbsh2B(3nOd9PGD=vV%;RY z9)`Q+%3((_6&nZ0(yVWOudra^y!!naRSJ;oC~_bu;V-><1eC&EMYI9!h$nS>qLVt> zK?Xz58P|a!{ZrL)AmLJ(#26ukpNO3|l!MKht3~_E5`SR>@;2WDk z%U?Rgxd_G*#rB$Ghs_bJP|)zoHKVaX2C7jLyQ`RMc|mU2^+u@EWgrmoKpk<$=e5WG zDg4DnHYu;--j(vR>5!trw6S0*;5nmm$(P?bjXIpZ?$C$7SC%=KV#%iPKjPkWevUjA zbQHnDaW+mI`$wv%7Se>4AVD-a_=#TTcvrb@9D7WMI`ET37_=3_hqmv}mY@7WI-$FG zVpqz`b~NJ1AR>xY5-uvQ7r9KpvULuLt;&XUu8hz$B!t88sx@E*vm9HQ_V5B}B-FZpYE0iC-!O$ct`j*}6T5={ z%mMZC#KOAqTkZST1sS{Wmb1dgzBwFr?vTc$5#HBb(v6I9$pT3m=~t7|89DNBjiDsP zU1|JYm=}XxN^uLHg4c&eu^n0(5w<$^uO-(`@|F(gjPn<4O|4sgs?P5foAWnLgatzN zi}_oWv5gt+!5P><8rM`6)r?%)>`Mc9$Q#7K(Tflq-( z(3B?f!@u(UfYplQhvJ$2unh-b&q@rr(?VI%9*Sw9BTt_6Z;Cw*41{X^ z$1eD>7Yxaf2OxR|4wC|AIIz^EPQ}B^7)N#gCb~iXFwaal_4F5>-zY2Ne$>`@a5+>r zR$jq4KXdvz>ikT}+9~8gj;Ybq`5A6ZJydhX2Co^C1KX994f{oEb%yKy>C++&1W%RN z*@%-`IG43z!e4uSMmVD{+J}0{-!j$8`r%#YmpB9KJMYC~k>U>d02^ndbU9t3URapu zlwCm)izOTFD?bSP#vcLBHQfW!C{?^$NoeGCo>o`Bgit%))M{FdCCIw?e zv~g{5Y)li=3YX*jm}tNU*fMjDkgx~(C}+hM?p#uMa6{p-J%7vjG5Zl*9KWsg{GMgs z3h=O!bAw_j^c%M1bQAm4dVbHC8Ydps5`u&s5NbN}MzxYJ90KG8XAl3a=l2}vhh5H3 zmYzPyiK}0HZXfWIhAzWhw_r$J=O;JMQO=FSmLGe7Hv*eEQFP_j)Pk(jhC5gP?(>r% zq3ZneAJ4DK7R0k+z3htupcV z=ZA}hIm&G_lv}3j4{!LF&JP>e*#;p;mnXp~=zr_^VVCpg|7*{0Qzz*Ev*+h)|5w2O zKmEVLfhHidCq8f9yiX(&vBVH!1U>_ak@&4n&i^YR|4rgX#KchlDk1-c;zrDOC#wFd z;_LV?3PHU6FUoxPFf^4!j3K7rJDwPg+z@*YQ|$c>LY_?7^vAEs_6UMzzkmB%bxY9g zrPX)juP^#0(B5)lDKUpwNX#Mz;deffik24=Gl@kgt+4++rY8{wO8emx1`H%3KeXls zS{D%uh{Z$->aPaXDY#1|8?~otL>ttpZZi%g%ZTarz80g;Ie2%Wy1qE|<0k1N zTUd%;vh_bAPbONT&EY7YWiKVETnze1F3lol<4uAHMT;S5xjhj8gn{@?MBSx!x)$PY z44%%$eJb9WX77n0qKNuvcVtyNB*)3VtNBCTQQTVq3dr|JegxaOyUb2&FyV#wN8$ZN ZC`&^R%m0AfnU552JZsc<<&ZOP{tH5u>)8MR literal 0 HcmV?d00001 diff --git a/mseide-msegui/apps/ide/mseide_zeos.prj b/mseide-msegui/apps/ide/mseide_zeos.prj new file mode 100644 index 0000000..c9e49cb --- /dev/null +++ b/mseide-msegui/apps/ide/mseide_zeos.prj @@ -0,0 +1,1163 @@ +[componentpalette] +order0=0 +order1=0 +order2=0 +order3=0 +order4=0 +order5=0 +order6=0 +order7=0 +order8=0 +order9=0 +order10=0 +order11=0 +order12=0 +order13=0 +order14=0 +order15=0 +order16=0 +order17=0 +order18=0 +[projectoptions] +projectdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide +projectfilename=/home/mse/packs/standard/git/mseide-msegui/apps/ide/mseide_zeos.prj +options=99 + [projectoptionsfo.twidgetgrid3] + propcolwidthref=788 + sortdescend0=0 + sortdescend1=0 + sortdescend2=0 + sortdescend3=0 + width4=364 + sortdescend4=0 + width5=51 + sortdescend5=0 + width6=322 + sortdescend6=0 + [projectoptionsfo.twidgetgrid4] + propcolwidthref=612 + width0=96 + sortdescend0=0 + sortdescend1=0 + width2=73 + sortdescend2=0 + width3=293 + sortdescend3=0 + width4=309 + sortdescend4=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=16 + [projectoptionsfo.newfile] + firsttab=0 + index=0 + [projectoptionsfo.fontaliasgrid] + propcolwidthref=471 + width0=98 + sortdescend0=0 + width1=460 + sortdescend1=0 + width2=30 + sortdescend2=0 + width3=50 + sortdescend3=0 + width4=50 + sortdescend4=0 + width5=50 + sortdescend5=0 + width6=70 + sortdescend6=0 + [projectoptionsfo.macrosplitter] + x=0 + y=179 + xprop=1 + yprop=0.34942084942085 + [projectoptionsfo.macrogrid] + propcolwidthref=595 + sortdescend0=0 + sortdescend1=0 + sortdescend2=0 + sortdescend3=0 + sortdescend4=0 + sortdescend5=0 + width6=146 + sortdescend6=0 + width7=583 + sortdescend7=0 + [projectoptionsfo.makegroupbox] + firsttab=0 + index=2 + [projectoptionsfo.exceptionsgrid] + propcolwidthref=772 + width0=47 + sortdescend0=0 + width1=766 + sortdescend1=0 + [projectoptionsfo.ttabwidget1] + firsttab=0 + index=0 + [projectoptionsfo.grid] + propcolwidthref=573 + width0=219 + sortdescend0=0 + width1=566 + sortdescend1=0 + [projectoptionsfo.filefiltergrid] + propcolwidthref=680 + width0=112 + sortdescend0=0 + width1=673 + sortdescend1=0 + [projectoptionsfo.ttabwidget2] + firsttab=0 + index=1 + [projectoptionsfo.tabwidget] + firsttab=0 + index=3 + [projectoptionsfo] + stackedunder= + x=151 + y=68 + cx=821 + cy=572 +mainfile=mseide.pas +targetfile=mseide_zeos${EXEEXT} +messageoutputfile= +makecommand=${COMPILER} +makedir= +unitdirs=5 + ${zeosdir}/src/*/ + ${zeosdir}/src/ + ${MSELIBDIR}kernel/$TARGETOSDIR + ${MSELIBDIR}kernel/ + ${MSELIBDIR}*/ +unitpref=-Fu +incpref=-Fi +libpref=-Fl +objpref=-Fo +targpref=-o +befcommand=0 +aftcommand=0 +makeoptions=4 + -Xg -Fcutf8 -dmse_with_zeoslib -dMSEgui + -gl + -B + -O2 -XX -Xs -CX +codetemplatedirs=1 + ${TEMPLATEDIR} +toolmenus=0 +toolfiles=0 +toolparams=0 +fontnames=0 +scriptbeforecopy= +scriptaftercopy= +newprojectfiles=4 + ${TEMPLATEDIR}default/project.pas + ${TEMPLATEDIR}default/main.pas + ${TEMPLATEDIR}default/main.mfm + ${TEMPLATEDIR}default/main_mfm.pas +newprojectfilesdest=4 + ${%PROJECTNAME%}.pas + + + +newfinames=3 + Program + Unit + Textfile +newfifilters=3 + "*.pas" "*.pp" + "*.pas" "*.pp" + +newfiexts=3 + pas + pas + +newfisources=3 + ${TEMPLATEDIR}default/program.pas + ${TEMPLATEDIR}default/unit.pas + +newfonames=11 + Mainform + Simple Form + Docking Form + Datamodule + Subform + Scrollboxform + Tabform + Dockpanel + Report + Scriptform + Inherited Form +newfonamebases=11 + form + form + form + module + form + form + form + form + report + script + form +newfosources=11 + ${TEMPLATEDIR}default/mainform.pas + ${TEMPLATEDIR}default/simpleform.pas + ${TEMPLATEDIR}default/dockingform.pas + ${TEMPLATEDIR}default/datamodule.pas + ${TEMPLATEDIR}default/subform.pas + ${TEMPLATEDIR}default/scrollboxform.pas + ${TEMPLATEDIR}default/tabform.pas + ${TEMPLATEDIR}default/dockpanelform.pas + ${TEMPLATEDIR}default/report.pas + ${TEMPLATEDIR}default/pascform.pas + ${TEMPLATEDIR}default/inheritedform.pas +newfoforms=11 + ${TEMPLATEDIR}default/mainform.mfm + ${TEMPLATEDIR}default/simpleform.mfm + ${TEMPLATEDIR}default/dockingform.mfm + ${TEMPLATEDIR}default/datamodule.mfm + ${TEMPLATEDIR}default/subform.mfm + ${TEMPLATEDIR}default/scrollboxform.mfm + ${TEMPLATEDIR}default/tabform.mfm + ${TEMPLATEDIR}default/dockpanelform.mfm + ${TEMPLATEDIR}default/report.mfm + ${TEMPLATEDIR}default/pascform.mfm + ${TEMPLATEDIR}default/inheritedform.mfm +forcezorder=0 +stripmessageesc=0 +copymessages=0 +closemessages=1 +checkmethods=1 +colorerror=-1610612712 +colorwarning=-1610612717 +colornote=-1610612716 +usercolors=30 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +usercolorcomment=30 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +formatmacronames=0 +formatmacrovalues=0 +settingsfile= +settingseditor=0 +settingsdebugger=0 +settingsstorage=0 +settingsprojecttree=0 +settingsautoload=0 +settingsautosave=0 +modulenames=3 + ACTIONSMO + MAINFO + SOURCEFO +moduletypes=3 + TACTIONSMO + TMAINFO + TSOURCEFO +modulefiles=3 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/actionsmodule.mfm + /home/mse/packs/standard/git/mseide-msegui/apps/ide/main.mfm + /home/mse/packs/standard/git/mseide-msegui/apps/ide/sourceform.mfm +befcommandon=0 +makeoptionson=4 + 63 + 31 + 34 + 32 +aftcommandon=0 +unitdirson=5 + 983103 + 131135 + 65599 + 196671 + 65599 +macroon=1 + 63 +macronames=1 + zeosdir +macrovalues=1 + +macrogroup=0 +groupcomments=6 + + + + + + +toolsave=0 +toolhide=0 +toolparse=0 +toolmessages=0 +toolshortcuts=0 +fontalias=0 +fontancestors=0 +fontheights=0 +fontwidths=0 +fontoptions=0 +fontxscales=0 +expandprojectfilemacros=4 + 1 + 1 + 1 + 0 +loadprojectfile=4 + 1 + 1 + 1 + 0 +newinheritedforms=11 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 +uid=0 +sourcefilemasks=3 + "*.pas" "*.dpr" "*.pp" "*.inc" + "*.c" "*.cc" "*.h" + "*.mfm" +syntaxdeffiles=3 + ${SYNTAXDEFDIR}pascal.sdef + ${SYNTAXDEFDIR}cpp.sdef + ${SYNTAXDEFDIR}objecttext.sdef +filemasknames=3 + Source + Forms + All Files +filemasks=3 + "*.pp" "*.pas" "*.inc" "*.dpr" + *.mfm + * +showgrid=1 +snaptogrid=1 +moveonfirstclick=1 +noformdesignerdocking=0 +gridsizex=8 +gridsizey=8 +autoindent=1 +blockindent=1 +linenumberson=0 +rightmarginon=1 +rightmarginchars=80 +scrollheight=-1 +tabstops=4 +spacetabs=0 +showtabs=0 +tabindent=0 +editfontname=mseide_source +editfontheight=14 +editfontwidth=0 +editfontextraspace=0 +editfontcolor=-1879048183 +editbkcolor=-1879048186 +statementcolor=14745599 +editfontantialiased=1 +editmarkbrackets=1 +backupfilecount=2 +encoding=1 +codetemplatedirs=1 + ${TEMPLATEDIR} +debugcommand=${DEBUGGER} +debugoptions= +debugtarget= +runcommand= +xtermcommand=xterm -S${PTSN}/${PTSH} +remoteconnection= +uploadcommand= +gdbprocessor=auto +gdbservercommand= +gdbservercommandattach= +beforeconnect= +afterconnect= +beforeload= +afterload= +beforerun= +sourcebase= +sourcedirs=5 + ${zeosdir}/src/*/ + ${zeosdir}/src/ + ${MSELIBDIR}kernel/$TARGET/ + ${MSELIBDIR}*/ + ./ +defines=0 +progparameters= +progworkingdirectory= +envvarnames=0 +envvarvalues=0 +defineson=0 +stoponexception=0 +valuehints=1 +activateonbreak=1 +raiseonbreak=1 +showconsole=0 +externalconsole=0 +settty=1 +gdbdownload=0 +downloadalways=0 +startupbkpt=0 +startupbkpton=0 +gdbsimulator=0 +gdbserverstartonce=0 +gdbloadtimeout= +gdbserverwait=0 +nogdbserverexit=0 +gdbservertty=0 +exceptclassnames=1 + EconvertError +exceptignore=1 + 0 +nodebugbeginend=0 +sigsettings=27 + 1,1,T,F + 3,3,T,F + 4,4,T,F + 6,6,T,F + 7,7,T,F + 8,8,T,F + 9,9,T,F + 10,10,T,F + 11,11,T,F + 12,12,T,F + 13,13,T,F + 15,15,T,F + 16,16,T,F + 17,17,F,F + 18,18,T,F + 19,19,T,F + 20,20,T,F + 21,21,T,F + 22,22,T,F + 23,23,T,F + 24,24,T,F + 25,25,T,F + 26,26,T,F + 27,27,T,F + 28,28,T,F + 29,29,T,F + 30,30,T,F +defaultmake=1 +[breakpoints] +on=0 +path=0 +line=0 +address=0 +addbkpt=0 +ignore=0 +condition=0 +panels=2 + panel1 + panel2 +units= + ( + a=0,4132,6,Pascal Units + ) +cmodules= + ( + a=0,4132,6,C Modules + ) +files= + ( + a=0,4132,6,Text Files + ) +[componentstore] +storedir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ +filename= +[components] +[selecteditpage] +colwidth=100 +x=0 +y=0 +cx=0 +cy=0 +[progparams] +progparamhistory=0 +workdirparamhistory=0 +envvarons=0 +[edit] +hintwidth=0 +hintheight=0 +finddtext= +findhistory=0 +findoptions=1 +editpos=3 + 0,0 + 0,0 + 0,0 +bookmarks0=0 +bookmarks1=0 +bookmarks2=0 +sourcefiles=3 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/main.pas + /home/mse/packs/standard/git/mseide-msegui/apps/ide/sourceform.pas + /home/mse/packs/standard/git/mseide-msegui/apps/ide/actionsmodule.pas +relpaths=3 + main.pas + sourceform.pas + actionsmodule.pas +ismoduletexts=3 + 0 + 0 + 0 +modules=3 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/main.mfm + /home/mse/packs/standard/git/mseide-msegui/apps/ide/actionsmodule.mfm + /home/mse/packs/standard/git/mseide-msegui/apps/ide/sourceform.mfm +moduleoptions=3 + 0 + 0 + 0 +visiblemodules=3 + -1 + -1 + -1 +nomenumodules=3 + 0 + 0 + 0 +[sourcefo.tabwidget] +tabsize=134 +firsttab=0 +index=0 +[layout] +windowlayout=571 + [mainfo.openform] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/sourceform.mfm + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + filehistory=2 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/sourceform.mfm + /home/mse/packs/standard/git/mseide-msegui/apps/ide/actionsmodule.mfm + filefilterindex=0 + filefilter=*.mfm + [mainfo.projectfiledia] + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + [mainfo.openfile] + filenames=0 + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + filehistory=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/main.pas + filefilterindex=0 + filefilter="*.pp" "*.pas" "*.inc" "*.dpr" + [mainfo.basedock] + splitdir=2 + useroptions=146560 + [mainfo] + splitdir=0 + useroptions=33554555 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=25 + cx=323 + cy=64 + rcx=0 + rcy=0 + wsize=0 + active=1 + visible=1 + [targetconsolefo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=209 + y=385 + cx=368 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [threadsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=37 + y=270 + cx=349 + cy=276 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo] + splitdir=0 + useroptions=16507 + stackedunder=cpui386fo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=100 + y=100 + cx=453 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo.add] + value=0 + [memoryfo.memon] + value=0 + [memoryfo.bitwidth] + value=0 + [memoryfo.cnt] + value=0 + [disassfo] + splitdir=0 + useroptions=16491 + stackedunder=findinfilefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=162 + y=502 + cx=564 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [findinfilefo] + splitdir=0 + useroptions=16491 + stackedunder=_mse_actionsmo_mse_ + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=548 + y=115 + cx=369 + cy=198 + rcx=0 + rcy=0 + [projecttreefo] + splitdir=0 + useroptions=16491 + stackedunder=memoryfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=263 + y=431 + cx=286 + cy=201 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [projecttreefo.grid] + propcolwidthref=135 + width0=141 + sortdescend0=0 + width1=129 + sortdescend1=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=16 + [stackfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=295 + rcx=0 + rcy=0 + [watchpointsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=120 + y=368 + cx=483 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [watchpointsfo.grid] + propcolwidthref=352 + sortdescend0=0 + values1=1 + 0 + values1_ci=-1 + width1=33 + sortdescend1=0 + values2=1 + pinteger(0x126c6b4)^ + width2=158 + sortdescend2=0 + width4=34 + sortdescend4=0 + values5=1 + 0 + values5_ci=-1 + width5=38 + sortdescend5=0 + values6=1 + + width6=184 + sortdescend6=0 + [breakpointsfo] + splitdir=0 + useroptions=16491 + stackedunder=projecttreefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=107 + y=404 + cx=636 + cy=128 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [breakpointsfo.bkptson] + value=1 + [objectinspectorfo] + splitdir=0 + useroptions=16491 + stackedunder=_mse_mainfo_mse_ + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=724 + y=157 + cx=296 + cy=566 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [objectinspectorfo.grid] + propcolwidthref=286 + width0=105 + sortdescend0=0 + width1=175 + sortdescend1=0 + [symbolfo] + splitdir=0 + useroptions=16507 + stackedunder=disassfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=142 + y=257 + cx=361 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [symbolfo.grid] + propcolwidthref=222 + values0=14 + + + + + + + + + + + + + + + width0=111 + sortdescend0=0 + width1=135 + sortdescend1=0 + [symbolfo.symbol] + [watchfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=298 + cx=313 + cy=236 + rcx=0 + rcy=0 + [watchfo.grid] + propcolwidthref=118 + values0=0 + values0_ci=-1 + sortdescend0=0 + values1=0 + width1=152 + sortdescend1=0 + values3=0 + values3_ci=-1 + sortdescend3=0 + values4=0 + values4_ci=-1 + width4=13 + sortdescend4=0 + [watchfo.watchon] + [watchfo.expression] + [watchfo.watcheson] + value=1 + [messagefo] + splitdir=0 + useroptions=49259 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=510 + cx=675 + cy=95 + rcx=0 + rcy=0 + [componentstorefo] + splitdir=0 + useroptions=24699 + stackedunder=symbolfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=305 + y=101 + cx=445 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentstorefo.grid] + propcolwidthref=435 + width0=111 + sortdescend0=0 + sortdescend1=0 + width2=112 + sortdescend2=0 + width3=185 + sortdescend3=0 + [componentstorefo.storefiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.groupfiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.compfiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentpalettefo] + splitdir=0 + useroptions=24683 + stackedunder=objectinspectorfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=25 + cx=685 + cy=103 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [componentpalettefo.componentpages] + activetab=0 + [debuggerfo] + splitdir=0 + useroptions=24683 + parent=mainfo.basedock + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=28 + rcx=0 + rcy=0 + [sourcefo] + splitdir=0 + useroptions=16489 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=675 + cy=507 + rcx=0 + rcy=0 + [actionsmo.watchesonact] + checked=1 + [actionsmo.bluedotsonact] + checked=1 + [cpui386fo] + irqoff=0 + splitdir=0 + useroptions=16491 + stackedunder=componentstorefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=337 + y=295 + cx=273 + cy=207 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [mainfo.panel1] + splitdir=2 + useroptions=33586667 + stackedunder=mainfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=118 + cx=685 + cy=605 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel2] + splitdir=2 + useroptions=33586667 + stackedunder=componentpalettefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=189 + cx=323 + cy=534 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [_mse_mainfo_mse_] + splitdir=0 + useroptions=16507 + stackedunder=mainfo.panel1 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=45 + y=165 + cx=469 + cy=149 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 +[targetconsole] +finddtext= +findhistory=0 +findoptions=1 diff --git a/mseide-msegui/apps/ide/mseparamentryform.mfm b/mseide-msegui/apps/ide/mseparamentryform.mfm new file mode 100644 index 0000000..5f7dc6f --- /dev/null +++ b/mseide-msegui/apps/ide/mseparamentryform.mfm @@ -0,0 +1,140 @@ +object mseparamentryfo: tmseparamentryfo + visible = False + bounds_x = 222 + bounds_y = 262 + bounds_cx = 371 + bounds_cy = 260 + container.bounds = ( + 0 + 0 + 371 + 260 + ) + options = [fo_screencentered, fo_cancelonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder] + statfile = tstatfile1 + moduleclassname = 'tmseform' + object grid: twidgetgrid + bounds_x = 0 + bounds_y = 0 + bounds_cx = 371 + bounds_cy = 231 + anchors = [an_top] + optionsgrid = [og_colsizing, og_focuscellonenter, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 2 + captions.items = < + item + caption = 'Macro' + end + item + caption = 'Value' + end> + end> + datacols.count = 2 + datacols.options = [co_proportional, co_savestate, co_mousescrollrow] + datacols.items = < + item[macroname] + width = 89 + options = [co_readonly, co_nofocus, co_proportional, co_savestate, co_mousescrollrow] + widgetname = 'macroname' + dataclass = tgridmsestringdatalist + end + item[macrovalue] + width = 276 + options = [co_fill, co_savestate, co_mousescrollrow] + widgetname = 'macrovalue' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + statfile = tstatfile1 + reffontheight = 14 + object macroname: tstringedit + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 89 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + object macrovalue: tmemodialogedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.localprops = [frl_levelo] + frame.button.color = -2147483646 + frame.button.imagenr = 17 + taborder = 2 + visible = False + bounds_x = 90 + bounds_y = 0 + bounds_cx = 276 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + end + object tsplitter1: tsplitter + color = -1879048189 + taborder = 1 + bounds_x = 0 + bounds_y = 231 + bounds_cx = 371 + bounds_cy = 25 + anchors = [an_bottom] + optionsscale = [osc_expandy, osc_shrinky] + linktop = grid + grip = stb_none + object tbutton2: tbutton + bounds_x = 312 + bounds_y = 5 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_top, an_right] + state = [as_localcaption] + caption = 'Cancel' + modalresult = mr_cancel + end + object tbutton1: tbutton + taborder = 1 + bounds_x = 256 + bounds_y = 5 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_top, an_right] + state = [as_default, as_localdefault, as_localcaption] + caption = 'OK' + modalresult = mr_ok + end + object comment: tlabel + optionswidget1 = [ow1_autoheight] + taborder = 2 + bounds_x = 2 + bounds_y = 2 + bounds_cx = 252 + bounds_cy = 14 + anchors = [an_left, an_top, an_right] + caption = 'comment' + textflags = [tf_ycentered, tf_wordbreak] + end + end + object tstatfile1: tstatfile + filename = 'templparam.sta' + options = [sfo_memory, sfo_transaction, sfo_activatorread, sfo_activatorwrite] + left = 40 + top = 80 + end + object c: tstringcontainer + strings.data = ( + 'Code Template "' + ) + left = 40 + top = 120 + end +end diff --git a/mseide-msegui/apps/ide/mseparamentryform.pas b/mseide-msegui/apps/ide/mseparamentryform.pas new file mode 100644 index 0000000..3ff7315 --- /dev/null +++ b/mseide-msegui/apps/ide/mseparamentryform.pas @@ -0,0 +1,46 @@ +{ MSEide Copyright (c) 2010 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit mseparamentryform; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,mseforms,msesimplewidgets, + msewidgets,msedataedits,mseedit,msegrids,msestrings,msetypes,msewidgetgrid, + msememodialog,msesplitter,msestatfile,msestringcontainer; +type + strinconsts = ( + codetemplate //0 Code Template " + ); + + tmseparamentryfo = class(tmseform) + grid: twidgetgrid; + macroname: tstringedit; + macrovalue: tmemodialogedit; + tsplitter1: tsplitter; + tbutton2: tbutton; + tbutton1: tbutton; + comment: tlabel; + tstatfile1: tstatfile; + c: tstringcontainer; + end; +var + mseparamentryfo: tmseparamentryfo; +implementation +uses + mseparamentryform_mfm; +end. diff --git a/mseide-msegui/apps/ide/mseparamentryform_mfm.pas b/mseide-msegui/apps/ide/mseparamentryform_mfm.pas new file mode 100644 index 0000000..bfdab66 --- /dev/null +++ b/mseide-msegui/apps/ide/mseparamentryform_mfm.pas @@ -0,0 +1,153 @@ +unit mseparamentryform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,mseparamentryform; + +const + objdata: record size: integer; data: array[0..2713] of byte end = + (size: 2714; data: ( + 84,80,70,48,16,116,109,115,101,112,97,114,97,109,101,110,116,114,121,102, + 111,15,109,115,101,112,97,114,97,109,101,110,116,114,121,102,111,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,222,0,8,98, + 111,117,110,100,115,95,121,3,6,1,9,98,111,117,110,100,115,95,99,120, + 3,115,1,9,98,111,117,110,100,115,95,99,121,3,4,1,16,99,111,110, + 116,97,105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0,3,115, + 1,3,4,1,0,7,111,112,116,105,111,110,115,11,17,102,111,95,115,99, + 114,101,101,110,99,101,110,116,101,114,101,100,14,102,111,95,99,97,110,99, + 101,108,111,110,101,115,99,15,102,111,95,97,117,116,111,114,101,97,100,115, + 116,97,116,16,102,111,95,97,117,116,111,119,114,105,116,101,115,116,97,116, + 10,102,111,95,115,97,118,101,112,111,115,13,102,111,95,115,97,118,101,122, + 111,114,100,101,114,0,8,115,116,97,116,102,105,108,101,7,10,116,115,116, + 97,116,102,105,108,101,49,15,109,111,100,117,108,101,99,108,97,115,115,110, + 97,109,101,6,8,116,109,115,101,102,111,114,109,0,11,116,119,105,100,103, + 101,116,103,114,105,100,4,103,114,105,100,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,3,115,1,9,98,111,117,110,100,115,95,99,121,3,231,0,7, + 97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,0,11,111,112,116, + 105,111,110,115,103,114,105,100,11,12,111,103,95,99,111,108,115,105,122,105, + 110,103,19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116, + 101,114,20,111,103,95,99,111,108,99,104,97,110,103,101,111,110,116,97,98, + 107,101,121,10,111,103,95,119,114,97,112,99,111,108,12,111,103,95,97,117, + 116,111,112,111,112,117,112,17,111,103,95,109,111,117,115,101,115,99,114,111, + 108,108,99,111,108,0,13,102,105,120,114,111,119,115,46,99,111,117,110,116, + 2,1,13,102,105,120,114,111,119,115,46,105,116,101,109,115,14,1,6,104, + 101,105,103,104,116,2,16,14,99,97,112,116,105,111,110,115,46,99,111,117, + 110,116,2,2,14,99,97,112,116,105,111,110,115,46,105,116,101,109,115,14, + 1,7,99,97,112,116,105,111,110,6,5,77,97,99,114,111,0,1,7,99, + 97,112,116,105,111,110,6,5,86,97,108,117,101,0,0,0,0,14,100,97, + 116,97,99,111,108,115,46,99,111,117,110,116,2,2,16,100,97,116,97,99, + 111,108,115,46,111,112,116,105,111,110,115,11,15,99,111,95,112,114,111,112, + 111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,115,116,97,116, + 101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0, + 14,100,97,116,97,99,111,108,115,46,105,116,101,109,115,14,7,9,109,97, + 99,114,111,110,97,109,101,1,5,119,105,100,116,104,2,89,7,111,112,116, + 105,111,110,115,11,11,99,111,95,114,101,97,100,111,110,108,121,10,99,111, + 95,110,111,102,111,99,117,115,15,99,111,95,112,114,111,112,111,114,116,105, + 111,110,97,108,12,99,111,95,115,97,118,101,115,116,97,116,101,17,99,111, + 95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100, + 103,101,116,110,97,109,101,6,9,109,97,99,114,111,110,97,109,101,9,100, + 97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116, + 114,105,110,103,100,97,116,97,108,105,115,116,0,7,10,109,97,99,114,111, + 118,97,108,117,101,1,5,119,105,100,116,104,3,20,1,7,111,112,116,105, + 111,110,115,11,7,99,111,95,102,105,108,108,12,99,111,95,115,97,118,101, + 115,116,97,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108, + 114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,10,109,97,99, + 114,111,118,97,108,117,101,9,100,97,116,97,99,108,97,115,115,7,22,116, + 103,114,105,100,109,115,101,115,116,114,105,110,103,100,97,116,97,108,105,115, + 116,0,0,13,100,97,116,97,114,111,119,104,101,105,103,104,116,2,16,8, + 115,116,97,116,102,105,108,101,7,10,116,115,116,97,116,102,105,108,101,49, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,11,116,115, + 116,114,105,110,103,101,100,105,116,9,109,97,99,114,111,110,97,109,101,8, + 116,97,98,111,114,100,101,114,2,1,7,118,105,115,105,98,108,101,8,8, + 98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,2,89,9,98,111,117,110,100,115, + 95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,0, + 11,111,112,116,105,111,110,115,101,100,105,116,11,11,111,101,95,114,101,97, + 100,111,110,108,121,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111, + 101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99, + 107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101, + 116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101, + 95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111, + 101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110, + 100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101, + 99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105, + 114,115,116,99,108,105,99,107,0,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,14,0,0,15,116,109,101,109,111,100,105,97,108,111,103,101, + 100,105,116,10,109,97,99,114,111,118,97,108,117,101,14,111,112,116,105,111, + 110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103, + 108,121,112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110,115,115, + 107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110, + 111,110,108,121,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 114,108,95,108,101,118,101,108,111,0,18,102,114,97,109,101,46,98,117,116, + 116,111,110,46,99,111,108,111,114,4,2,0,0,128,20,102,114,97,109,101, + 46,98,117,116,116,111,110,46,105,109,97,103,101,110,114,2,17,8,116,97, + 98,111,114,100,101,114,2,2,7,118,105,115,105,98,108,101,8,8,98,111, + 117,110,100,115,95,120,2,90,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,120,3,20,1,9,98,111,117,110,100,115,95, + 99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,0,11, + 111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111, + 111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16, + 111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95, + 115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101, + 116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111, + 110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111, + 114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97, + 117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108, + 101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,13,114,101,102, + 102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,9,116,115,112,108, + 105,116,116,101,114,10,116,115,112,108,105,116,116,101,114,49,5,99,111,108, + 111,114,4,3,0,0,144,8,116,97,98,111,114,100,101,114,2,1,8,98, + 111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,3,231, + 0,9,98,111,117,110,100,115,95,99,120,3,115,1,9,98,111,117,110,100, + 115,95,99,121,2,25,7,97,110,99,104,111,114,115,11,9,97,110,95,98, + 111,116,116,111,109,0,12,111,112,116,105,111,110,115,115,99,97,108,101,11, + 11,111,115,99,95,101,120,112,97,110,100,121,11,111,115,99,95,115,104,114, + 105,110,107,121,0,7,108,105,110,107,116,111,112,7,4,103,114,105,100,4, + 103,114,105,112,7,8,115,116,98,95,110,111,110,101,0,7,116,98,117,116, + 116,111,110,8,116,98,117,116,116,111,110,50,8,98,111,117,110,100,115,95, + 120,3,56,1,8,98,111,117,110,100,115,95,121,2,5,9,98,111,117,110, + 100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,20,7, + 97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,8,97,110,95,114, + 105,103,104,116,0,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,6,67, + 97,110,99,101,108,11,109,111,100,97,108,114,101,115,117,108,116,7,9,109, + 114,95,99,97,110,99,101,108,0,0,7,116,98,117,116,116,111,110,8,116, + 98,117,116,116,111,110,49,8,116,97,98,111,114,100,101,114,2,1,8,98, + 111,117,110,100,115,95,120,3,0,1,8,98,111,117,110,100,115,95,121,2, + 5,9,98,111,117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115, + 95,99,121,2,20,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111, + 112,8,97,110,95,114,105,103,104,116,0,5,115,116,97,116,101,11,10,97, + 115,95,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,100,101, + 102,97,117,108,116,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111, + 110,0,7,99,97,112,116,105,111,110,6,2,79,75,11,109,111,100,97,108, + 114,101,115,117,108,116,7,5,109,114,95,111,107,0,0,6,116,108,97,98, + 101,108,7,99,111,109,109,101,110,116,14,111,112,116,105,111,110,115,119,105, + 100,103,101,116,49,11,14,111,119,49,95,97,117,116,111,104,101,105,103,104, + 116,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115, + 95,120,2,2,8,98,111,117,110,100,115,95,121,2,2,9,98,111,117,110, + 100,115,95,99,120,3,252,0,9,98,111,117,110,100,115,95,99,121,2,14, + 7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110, + 95,116,111,112,8,97,110,95,114,105,103,104,116,0,7,99,97,112,116,105, + 111,110,6,7,99,111,109,109,101,110,116,9,116,101,120,116,102,108,97,103, + 115,11,12,116,102,95,121,99,101,110,116,101,114,101,100,12,116,102,95,119, + 111,114,100,98,114,101,97,107,0,0,0,0,9,116,115,116,97,116,102,105, + 108,101,10,116,115,116,97,116,102,105,108,101,49,8,102,105,108,101,110,97, + 109,101,6,14,116,101,109,112,108,112,97,114,97,109,46,115,116,97,7,111, + 112,116,105,111,110,115,11,10,115,102,111,95,109,101,109,111,114,121,15,115, + 102,111,95,116,114,97,110,115,97,99,116,105,111,110,17,115,102,111,95,97, + 99,116,105,118,97,116,111,114,114,101,97,100,18,115,102,111,95,97,99,116, + 105,118,97,116,111,114,119,114,105,116,101,0,4,108,101,102,116,2,40,3, + 116,111,112,2,80,0,0,16,116,115,116,114,105,110,103,99,111,110,116,97, + 105,110,101,114,1,99,12,115,116,114,105,110,103,115,46,100,97,116,97,1, + 6,15,67,111,100,101,32,84,101,109,112,108,97,116,101,32,34,0,4,108, + 101,102,116,2,40,3,116,111,112,2,120,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tmseparamentryfo,''); +end. diff --git a/mseide-msegui/apps/ide/msetemplateselectform.mfm b/mseide-msegui/apps/ide/msetemplateselectform.mfm new file mode 100644 index 0000000..2e29f90 --- /dev/null +++ b/mseide-msegui/apps/ide/msetemplateselectform.mfm @@ -0,0 +1,261 @@ +object msetemplateselectfo: tmsetemplateselectfo + visible = False + bounds_x = 152 + bounds_y = 247 + bounds_cx = 569 + bounds_cy = 277 + container.bounds = ( + 0 + 0 + 569 + 277 + ) + options = [fo_screencentered, fo_cancelonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder] + statfile = tstatfile1 + caption = 'Select Code Template' + moduleclassname = 'tmseform' + object tbutton1: tbutton + taborder = 2 + bounds_x = 512 + bounds_y = 251 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_localcaption] + caption = 'Cancel' + modalresult = mr_cancel + end + object tbutton2: tbutton + taborder = 1 + bounds_x = 456 + bounds_y = 251 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_default, as_localdefault, as_localcaption] + caption = 'OK' + modalresult = mr_ok + end + object grid: twidgetgrid + bounds_x = 0 + bounds_y = 0 + bounds_cx = 569 + bounds_cy = 245 + anchors = [an_top, an_bottom] + optionsgrid = [og_colsizing, og_focuscellonenter, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixcols.count = 1 + fixcols.items = < + item + width = 25 + numstart = 1 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 7 + captions.items = < + item + caption = 'Name' + end + item + caption = 'Comment' + end + item + caption = 'Par1' + end + item + caption = 'Par2' + end + item + caption = 'Par3' + end + item + caption = 'Par4' + end + item + caption = 'ed' + end> + end> + datacols.count = 7 + datacols.colorfocused = -1879048185 + datacols.options = [co_nofocus, co_drawfocus, co_proportional, co_savestate, co_mousescrollrow] + datacols.options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcolorfocused] + datacols.items = < + item[templatename] + colorfocused = -1879048185 + width = 60 + options = [co_readonly, co_drawfocus, co_proportional, co_savestate, co_mousescrollrow] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcolorfocused] + widgetname = 'templatename' + dataclass = tgridmsestringdatalist + end + item[comment] + colorfocused = -1879048185 + width = 252 + options = [co_readonly, co_nofocus, co_drawfocus, co_fill, co_savestate, co_mousescrollrow] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcolorfocused] + widgetname = 'comment' + dataclass = tgridmsestringdatalist + end + item[par1] + colorfocused = -1879048185 + width = 51 + options = [co_readonly, co_nofocus, co_drawfocus, co_proportional, co_savestate, co_mousescrollrow] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcolorfocused] + widgetname = 'par1' + dataclass = tgridmsestringdatalist + end + item[par2] + colorfocused = -1879048185 + width = 51 + options = [co_readonly, co_nofocus, co_drawfocus, co_proportional, co_savestate, co_mousescrollrow] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcolorfocused] + widgetname = 'par2' + dataclass = tgridmsestringdatalist + end + item[par3] + colorfocused = -1879048185 + width = 51 + options = [co_readonly, co_nofocus, co_drawfocus, co_proportional, co_savestate, co_mousescrollrow] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcolorfocused] + widgetname = 'par3' + dataclass = tgridmsestringdatalist + end + item[par4] + colorfocused = -1879048185 + width = 51 + options = [co_readonly, co_nofocus, co_drawfocus, co_proportional, co_savestate, co_mousescrollrow] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcolorfocused] + widgetname = 'par4' + dataclass = tgridmsestringdatalist + end + item[tstockglyphdatabutton1] + color = -2147483646 + colorfocused = -1879048185 + width = 16 + options = [co_readonly, co_fixwidth, co_savestate, co_mousescrollrow] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcolorfocused] + widgetname = 'tstockglyphdatabutton1' + dataclass = tgridintegerdatalist + end> + datarowheight = 16 + statfile = tstatfile1 + oncellevent = celle + reffontheight = 14 + object templatename: tstringedit + optionsskin = [osk_framebuttononly] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 60 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext, oe_locate] + reffontheight = 14 + end + object comment: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 2 + visible = False + bounds_x = 61 + bounds_y = 0 + bounds_cx = 252 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext] + reffontheight = 14 + end + object par1: tstringedit + Tag = 1 + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 3 + visible = False + bounds_x = 314 + bounds_y = 0 + bounds_cx = 51 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext] + reffontheight = 14 + end + object par2: tstringedit + Tag = 2 + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 4 + visible = False + bounds_x = 366 + bounds_y = 0 + bounds_cx = 51 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext] + reffontheight = 14 + end + object par3: tstringedit + Tag = 3 + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 5 + visible = False + bounds_x = 418 + bounds_y = 0 + bounds_cx = 51 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext] + reffontheight = 14 + end + object par4: tstringedit + Tag = 4 + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 6 + visible = False + bounds_x = 470 + bounds_y = 0 + bounds_cx = 51 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext] + reffontheight = 14 + end + object tstockglyphdatabutton1: tstockglyphdatabutton + optionsskin = [osk_framebuttononly] + taborder = 7 + bounds_x = 522 + bounds_y = 0 + bounds_cx = 16 + bounds_cy = 16 + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate, oe1_checkvalueafterstatread] + options = [bo_executeonclick, bo_executeonkey, bo_executeonshortcut, bo_executedefaultonenterkey, bo_asyncexecute] + state = [as_invisible, as_localinvisible, as_localimagelist, as_localimagenr, as_localonexecute] + glyph = stg_ellipsesmall + onexecute = edtemplateactonexecute + end + end + object filename: tstringdisp + frame.dummy = 0 + taborder = 3 + bounds_x = 5 + bounds_y = 252 + bounds_cx = 446 + bounds_cy = 18 + anchors = [an_left, an_right, an_bottom] + textflags = [tf_ycentered, tf_ellipseleft] + options = [dwo_hintclippedtext] + reffontheight = 14 + end + object tstatfile1: tstatfile + filename = 'templselect.sta' + options = [sfo_memory, sfo_transaction, sfo_activatorread, sfo_activatorwrite] + left = 40 + top = 80 + end +end diff --git a/mseide-msegui/apps/ide/msetemplateselectform.pas b/mseide-msegui/apps/ide/msetemplateselectform.pas new file mode 100644 index 0000000..0826bcf --- /dev/null +++ b/mseide-msegui/apps/ide/msetemplateselectform.pas @@ -0,0 +1,85 @@ +{ MSEide Copyright (c) 2010 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit msetemplateselectform; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,mseforms,msesimplewidgets, + msewidgets,msedataedits,mseedit,msegrids,msestrings,msetypes,msewidgetgrid, + msedispwidgets,msecodetemplates,msestatfile,msegraphedits; +type + tmsetemplateselectfo = class(tmseform) + tbutton1: tbutton; + tbutton2: tbutton; + grid: twidgetgrid; + templatename: tstringedit; + comment: tstringedit; + par1: tstringedit; + par2: tstringedit; + par3: tstringedit; + par4: tstringedit; + filename: tstringdisp; + tstatfile1: tstatfile; + tstockglyphdatabutton1: tstockglyphdatabutton; + procedure celle(const sender: TObject; var info: celleventinfoty); + procedure edtemplateactonexecute(const sender: TObject); + private + ftemplates: tcodetemplates; + public + finfos: templateinfoarty; + constructor create(const atemplates: tcodetemplates); reintroduce; + end; + +implementation +uses + msetemplateselectform_mfm,templateeditor,projectoptionsform; + +type + tcodetemplates1 = class(tcodetemplates); + +constructor tmsetemplateselectfo.create(const atemplates: tcodetemplates); +begin + ftemplates:= atemplates; + inherited create(nil); +end; + +procedure tmsetemplateselectfo.edtemplateactonexecute(const sender: TObject); +var + mstr1: msestring; +begin + if ttemplateeditorfo.create(grid.row).show(mstr1) = mr_ok then begin + ftemplates.scan(projectoptions.e.texp.codetemplatedirs); + tcodetemplates1(ftemplates).reload(self); + templatename.editor.filtertext:= mstr1; + end; +end; + +procedure tmsetemplateselectfo.celle(const sender: TObject; + var info: celleventinfoty); +begin + if isrowenter(info) then begin + if info.newcell.row > high(finfos) then begin + filename.value:= ''; + end + else begin + filename.value:= finfos[info.newcell.row].path; + end; + end; +end; + +end. diff --git a/mseide-msegui/apps/ide/msetemplateselectform_mfm.pas b/mseide-msegui/apps/ide/msetemplateselectform_mfm.pas new file mode 100644 index 0000000..f047444 --- /dev/null +++ b/mseide-msegui/apps/ide/msetemplateselectform_mfm.pas @@ -0,0 +1,348 @@ +unit msetemplateselectform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msetemplateselectform; + +const + objdata: record size: integer; data: array[0..6609] of byte end = + (size: 6610; data: ( + 84,80,70,48,20,116,109,115,101,116,101,109,112,108,97,116,101,115,101,108, + 101,99,116,102,111,19,109,115,101,116,101,109,112,108,97,116,101,115,101,108, + 101,99,116,102,111,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100, + 115,95,120,3,152,0,8,98,111,117,110,100,115,95,121,3,247,0,9,98, + 111,117,110,100,115,95,99,120,3,57,2,9,98,111,117,110,100,115,95,99, + 121,3,21,1,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100, + 115,1,2,0,2,0,3,57,2,3,21,1,0,7,111,112,116,105,111,110, + 115,11,17,102,111,95,115,99,114,101,101,110,99,101,110,116,101,114,101,100, + 14,102,111,95,99,97,110,99,101,108,111,110,101,115,99,15,102,111,95,97, + 117,116,111,114,101,97,100,115,116,97,116,16,102,111,95,97,117,116,111,119, + 114,105,116,101,115,116,97,116,10,102,111,95,115,97,118,101,112,111,115,13, + 102,111,95,115,97,118,101,122,111,114,100,101,114,0,8,115,116,97,116,102, + 105,108,101,7,10,116,115,116,97,116,102,105,108,101,49,7,99,97,112,116, + 105,111,110,6,20,83,101,108,101,99,116,32,67,111,100,101,32,84,101,109, + 112,108,97,116,101,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109, + 101,6,8,116,109,115,101,102,111,114,109,0,7,116,98,117,116,116,111,110, + 8,116,98,117,116,116,111,110,49,8,116,97,98,111,114,100,101,114,2,2, + 8,98,111,117,110,100,115,95,120,3,0,2,8,98,111,117,110,100,115,95, + 121,3,251,0,9,98,111,117,110,100,115,95,99,120,2,50,9,98,111,117, + 110,100,115,95,99,121,2,20,7,97,110,99,104,111,114,115,11,8,97,110, + 95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,5,115,116, + 97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110, + 0,7,99,97,112,116,105,111,110,6,6,67,97,110,99,101,108,11,109,111, + 100,97,108,114,101,115,117,108,116,7,9,109,114,95,99,97,110,99,101,108, + 0,0,7,116,98,117,116,116,111,110,8,116,98,117,116,116,111,110,50,8, + 116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,3, + 200,1,8,98,111,117,110,100,115,95,121,3,251,0,9,98,111,117,110,100, + 115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,20,7,97, + 110,99,104,111,114,115,11,8,97,110,95,114,105,103,104,116,9,97,110,95, + 98,111,116,116,111,109,0,5,115,116,97,116,101,11,10,97,115,95,100,101, + 102,97,117,108,116,15,97,115,95,108,111,99,97,108,100,101,102,97,117,108, + 116,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,7,99, + 97,112,116,105,111,110,6,2,79,75,11,109,111,100,97,108,114,101,115,117, + 108,116,7,5,109,114,95,111,107,0,0,11,116,119,105,100,103,101,116,103, + 114,105,100,4,103,114,105,100,8,98,111,117,110,100,115,95,120,2,0,8, + 98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120, + 3,57,2,9,98,111,117,110,100,115,95,99,121,3,245,0,7,97,110,99, + 104,111,114,115,11,6,97,110,95,116,111,112,9,97,110,95,98,111,116,116, + 111,109,0,11,111,112,116,105,111,110,115,103,114,105,100,11,12,111,103,95, + 99,111,108,115,105,122,105,110,103,19,111,103,95,102,111,99,117,115,99,101, + 108,108,111,110,101,110,116,101,114,20,111,103,95,99,111,108,99,104,97,110, + 103,101,111,110,116,97,98,107,101,121,10,111,103,95,119,114,97,112,99,111, + 108,12,111,103,95,97,117,116,111,112,111,112,117,112,17,111,103,95,109,111, + 117,115,101,115,99,114,111,108,108,99,111,108,0,13,102,105,120,99,111,108, + 115,46,99,111,117,110,116,2,1,13,102,105,120,99,111,108,115,46,105,116, + 101,109,115,14,1,5,119,105,100,116,104,2,25,8,110,117,109,115,116,97, + 114,116,2,1,7,110,117,109,115,116,101,112,2,1,0,0,13,102,105,120, + 114,111,119,115,46,99,111,117,110,116,2,1,13,102,105,120,114,111,119,115, + 46,105,116,101,109,115,14,1,6,104,101,105,103,104,116,2,16,14,99,97, + 112,116,105,111,110,115,46,99,111,117,110,116,2,7,14,99,97,112,116,105, + 111,110,115,46,105,116,101,109,115,14,1,7,99,97,112,116,105,111,110,6, + 4,78,97,109,101,0,1,7,99,97,112,116,105,111,110,6,7,67,111,109, + 109,101,110,116,0,1,7,99,97,112,116,105,111,110,6,4,80,97,114,49, + 0,1,7,99,97,112,116,105,111,110,6,4,80,97,114,50,0,1,7,99, + 97,112,116,105,111,110,6,4,80,97,114,51,0,1,7,99,97,112,116,105, + 111,110,6,4,80,97,114,52,0,1,7,99,97,112,116,105,111,110,6,2, + 101,100,0,0,0,0,14,100,97,116,97,99,111,108,115,46,99,111,117,110, + 116,2,7,21,100,97,116,97,99,111,108,115,46,99,111,108,111,114,102,111, + 99,117,115,101,100,4,7,0,0,144,16,100,97,116,97,99,111,108,115,46, + 111,112,116,105,111,110,115,11,10,99,111,95,110,111,102,111,99,117,115,12, + 99,111,95,100,114,97,119,102,111,99,117,115,15,99,111,95,112,114,111,112, + 111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,115,116,97,116, + 101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0, + 17,100,97,116,97,99,111,108,115,46,111,112,116,105,111,110,115,49,11,11, + 99,111,49,95,114,111,119,102,111,110,116,12,99,111,49,95,114,111,119,99, + 111,108,111,114,14,99,111,49,95,122,101,98,114,97,99,111,108,111,114,19, + 99,111,49,95,114,111,119,99,111,108,111,114,102,111,99,117,115,101,100,0, + 14,100,97,116,97,99,111,108,115,46,105,116,101,109,115,14,7,12,116,101, + 109,112,108,97,116,101,110,97,109,101,1,12,99,111,108,111,114,102,111,99, + 117,115,101,100,4,7,0,0,144,5,119,105,100,116,104,2,60,7,111,112, + 116,105,111,110,115,11,11,99,111,95,114,101,97,100,111,110,108,121,12,99, + 111,95,100,114,97,119,102,111,99,117,115,15,99,111,95,112,114,111,112,111, + 114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,115,116,97,116,101, + 17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,8, + 111,112,116,105,111,110,115,49,11,11,99,111,49,95,114,111,119,102,111,110, + 116,12,99,111,49,95,114,111,119,99,111,108,111,114,14,99,111,49,95,122, + 101,98,114,97,99,111,108,111,114,19,99,111,49,95,114,111,119,99,111,108, + 111,114,102,111,99,117,115,101,100,0,10,119,105,100,103,101,116,110,97,109, + 101,6,12,116,101,109,112,108,97,116,101,110,97,109,101,9,100,97,116,97, + 99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116,114,105,110, + 103,100,97,116,97,108,105,115,116,0,7,7,99,111,109,109,101,110,116,1, + 12,99,111,108,111,114,102,111,99,117,115,101,100,4,7,0,0,144,5,119, + 105,100,116,104,3,252,0,7,111,112,116,105,111,110,115,11,11,99,111,95, + 114,101,97,100,111,110,108,121,10,99,111,95,110,111,102,111,99,117,115,12, + 99,111,95,100,114,97,119,102,111,99,117,115,7,99,111,95,102,105,108,108, + 12,99,111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109,111,117, + 115,101,115,99,114,111,108,108,114,111,119,0,8,111,112,116,105,111,110,115, + 49,11,11,99,111,49,95,114,111,119,102,111,110,116,12,99,111,49,95,114, + 111,119,99,111,108,111,114,14,99,111,49,95,122,101,98,114,97,99,111,108, + 111,114,19,99,111,49,95,114,111,119,99,111,108,111,114,102,111,99,117,115, + 101,100,0,10,119,105,100,103,101,116,110,97,109,101,6,7,99,111,109,109, + 101,110,116,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100, + 109,115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,4, + 112,97,114,49,1,12,99,111,108,111,114,102,111,99,117,115,101,100,4,7, + 0,0,144,5,119,105,100,116,104,2,51,7,111,112,116,105,111,110,115,11, + 11,99,111,95,114,101,97,100,111,110,108,121,10,99,111,95,110,111,102,111, + 99,117,115,12,99,111,95,100,114,97,119,102,111,99,117,115,15,99,111,95, + 112,114,111,112,111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101, + 115,116,97,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108, + 114,111,119,0,8,111,112,116,105,111,110,115,49,11,11,99,111,49,95,114, + 111,119,102,111,110,116,12,99,111,49,95,114,111,119,99,111,108,111,114,14, + 99,111,49,95,122,101,98,114,97,99,111,108,111,114,19,99,111,49,95,114, + 111,119,99,111,108,111,114,102,111,99,117,115,101,100,0,10,119,105,100,103, + 101,116,110,97,109,101,6,4,112,97,114,49,9,100,97,116,97,99,108,97, + 115,115,7,22,116,103,114,105,100,109,115,101,115,116,114,105,110,103,100,97, + 116,97,108,105,115,116,0,7,4,112,97,114,50,1,12,99,111,108,111,114, + 102,111,99,117,115,101,100,4,7,0,0,144,5,119,105,100,116,104,2,51, + 7,111,112,116,105,111,110,115,11,11,99,111,95,114,101,97,100,111,110,108, + 121,10,99,111,95,110,111,102,111,99,117,115,12,99,111,95,100,114,97,119, + 102,111,99,117,115,15,99,111,95,112,114,111,112,111,114,116,105,111,110,97, + 108,12,99,111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109,111, + 117,115,101,115,99,114,111,108,108,114,111,119,0,8,111,112,116,105,111,110, + 115,49,11,11,99,111,49,95,114,111,119,102,111,110,116,12,99,111,49,95, + 114,111,119,99,111,108,111,114,14,99,111,49,95,122,101,98,114,97,99,111, + 108,111,114,19,99,111,49,95,114,111,119,99,111,108,111,114,102,111,99,117, + 115,101,100,0,10,119,105,100,103,101,116,110,97,109,101,6,4,112,97,114, + 50,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115, + 101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,4,112,97, + 114,51,1,12,99,111,108,111,114,102,111,99,117,115,101,100,4,7,0,0, + 144,5,119,105,100,116,104,2,51,7,111,112,116,105,111,110,115,11,11,99, + 111,95,114,101,97,100,111,110,108,121,10,99,111,95,110,111,102,111,99,117, + 115,12,99,111,95,100,114,97,119,102,111,99,117,115,15,99,111,95,112,114, + 111,112,111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,115,116, + 97,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111, + 119,0,8,111,112,116,105,111,110,115,49,11,11,99,111,49,95,114,111,119, + 102,111,110,116,12,99,111,49,95,114,111,119,99,111,108,111,114,14,99,111, + 49,95,122,101,98,114,97,99,111,108,111,114,19,99,111,49,95,114,111,119, + 99,111,108,111,114,102,111,99,117,115,101,100,0,10,119,105,100,103,101,116, + 110,97,109,101,6,4,112,97,114,51,9,100,97,116,97,99,108,97,115,115, + 7,22,116,103,114,105,100,109,115,101,115,116,114,105,110,103,100,97,116,97, + 108,105,115,116,0,7,4,112,97,114,52,1,12,99,111,108,111,114,102,111, + 99,117,115,101,100,4,7,0,0,144,5,119,105,100,116,104,2,51,7,111, + 112,116,105,111,110,115,11,11,99,111,95,114,101,97,100,111,110,108,121,10, + 99,111,95,110,111,102,111,99,117,115,12,99,111,95,100,114,97,119,102,111, + 99,117,115,15,99,111,95,112,114,111,112,111,114,116,105,111,110,97,108,12, + 99,111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109,111,117,115, + 101,115,99,114,111,108,108,114,111,119,0,8,111,112,116,105,111,110,115,49, + 11,11,99,111,49,95,114,111,119,102,111,110,116,12,99,111,49,95,114,111, + 119,99,111,108,111,114,14,99,111,49,95,122,101,98,114,97,99,111,108,111, + 114,19,99,111,49,95,114,111,119,99,111,108,111,114,102,111,99,117,115,101, + 100,0,10,119,105,100,103,101,116,110,97,109,101,6,4,112,97,114,52,9, + 100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115, + 116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,22,116,115,116,111, + 99,107,103,108,121,112,104,100,97,116,97,98,117,116,116,111,110,49,1,5, + 99,111,108,111,114,4,2,0,0,128,12,99,111,108,111,114,102,111,99,117, + 115,101,100,4,7,0,0,144,5,119,105,100,116,104,2,16,7,111,112,116, + 105,111,110,115,11,11,99,111,95,114,101,97,100,111,110,108,121,11,99,111, + 95,102,105,120,119,105,100,116,104,12,99,111,95,115,97,118,101,115,116,97, + 116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119, + 0,8,111,112,116,105,111,110,115,49,11,11,99,111,49,95,114,111,119,102, + 111,110,116,12,99,111,49,95,114,111,119,99,111,108,111,114,14,99,111,49, + 95,122,101,98,114,97,99,111,108,111,114,19,99,111,49,95,114,111,119,99, + 111,108,111,114,102,111,99,117,115,101,100,0,10,119,105,100,103,101,116,110, + 97,109,101,6,22,116,115,116,111,99,107,103,108,121,112,104,100,97,116,97, + 98,117,116,116,111,110,49,9,100,97,116,97,99,108,97,115,115,7,20,116, + 103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0, + 0,13,100,97,116,97,114,111,119,104,101,105,103,104,116,2,16,8,115,116, + 97,116,102,105,108,101,7,10,116,115,116,97,116,102,105,108,101,49,11,111, + 110,99,101,108,108,101,118,101,110,116,7,5,99,101,108,108,101,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,11,116,115,116,114,105, + 110,103,101,100,105,116,12,116,101,109,112,108,97,116,101,110,97,109,101,11, + 111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97, + 109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100, + 101,114,2,1,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115, + 95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,120,2,60,9,98,111,117,110,100,115,95,99,121,2,16,12, + 111,112,116,105,111,110,115,101,100,105,116,49,11,0,11,111,112,116,105,111, + 110,115,101,100,105,116,11,11,111,101,95,114,101,97,100,111,110,108,121,12, + 111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115, + 101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110, + 99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111, + 101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116, + 115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116, + 111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116, + 101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95, + 97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105, + 99,107,18,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120, + 116,9,111,101,95,108,111,99,97,116,101,0,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,14,0,0,11,116,115,116,114,105,110,103,101,100, + 105,116,7,99,111,109,109,101,110,116,14,111,112,116,105,111,110,115,119,105, + 100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104, + 104,101,105,103,104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11, + 19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121, + 0,8,116,97,98,111,114,100,101,114,2,2,7,118,105,115,105,98,108,101, + 8,8,98,111,117,110,100,115,95,120,2,61,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,120,3,252,0,9,98,111,117, + 110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116, + 49,11,0,11,111,112,116,105,111,110,115,101,100,105,116,11,11,111,101,95, + 114,101,97,100,111,110,108,121,12,111,101,95,117,110,100,111,111,110,101,115, + 99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99, + 104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105,102, + 116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114,110, + 20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105, + 116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101, + 95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115, + 101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111, + 110,102,105,114,115,116,99,108,105,99,107,18,111,101,95,104,105,110,116,99, + 108,105,112,112,101,100,116,101,120,116,0,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,0,11,116,115,116,114,105,110,103,101,100,105, + 116,4,112,97,114,49,3,84,97,103,2,1,14,111,112,116,105,111,110,115, + 119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121, + 112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110,115,115,107,105, + 110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110, + 108,121,0,8,116,97,98,111,114,100,101,114,2,3,7,118,105,115,105,98, + 108,101,8,8,98,111,117,110,100,115,95,120,3,58,1,8,98,111,117,110, + 100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,51,9,98, + 111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100, + 105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105,116,11,11,111, + 101,95,114,101,97,100,111,110,108,121,12,111,101,95,117,110,100,111,111,110, + 101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101, + 95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104, + 105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116,117, + 114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101, + 120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13, + 111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116, + 111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99, + 116,111,110,102,105,114,115,116,99,108,105,99,107,18,111,101,95,104,105,110, + 116,99,108,105,112,112,101,100,116,101,120,116,0,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,14,0,0,11,116,115,116,114,105,110,103,101, + 100,105,116,4,112,97,114,50,3,84,97,103,2,2,14,111,112,116,105,111, + 110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103, + 108,121,112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110,115,115, + 107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110, + 111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,4,7,118,105,115, + 105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,110,1,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,51, + 9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115, + 101,100,105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105,116,11, + 11,111,101,95,114,101,97,100,111,110,108,121,12,111,101,95,117,110,100,111, + 111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16, + 111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95, + 115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101, + 116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111, + 110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111, + 114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97, + 117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108, + 101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,18,111,101,95,104, + 105,110,116,99,108,105,112,112,101,100,116,101,120,116,0,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,11,116,115,116,114,105,110, + 103,101,100,105,116,4,112,97,114,51,3,84,97,103,2,3,14,111,112,116, + 105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110, + 116,103,108,121,112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110, + 115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116, + 111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,5,7,118, + 105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,162,1,8, + 98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120, + 2,51,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111, + 110,115,101,100,105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105, + 116,11,11,111,101,95,114,101,97,100,111,110,108,121,12,111,101,95,117,110, + 100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114, + 121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111, + 101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116, + 114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99, + 116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114, + 115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101, + 95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115, + 101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,18,111,101, + 95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116,0,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,11,116,115,116,114, + 105,110,103,101,100,105,116,4,112,97,114,52,3,84,97,103,2,4,14,111, + 112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102, + 111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,11,111,112,116,105, + 111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117, + 116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,6, + 7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,214, + 1,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,2,51,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116, + 105,111,110,115,101,100,105,116,49,11,0,11,111,112,116,105,111,110,115,101, + 100,105,116,11,11,111,101,95,114,101,97,100,111,110,108,121,12,111,101,95, + 117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117, + 101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108, + 14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101, + 97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108, + 101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99, + 117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13, + 111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116, + 111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,18, + 111,101,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116,0,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,21,116,115, + 116,111,99,107,103,108,121,112,104,100,97,116,97,98,117,116,116,111,110,22, + 116,115,116,111,99,107,103,108,121,112,104,100,97,116,97,98,117,116,116,111, + 110,49,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95, + 102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98, + 111,114,100,101,114,2,7,8,98,111,117,110,100,115,95,120,3,10,2,8, + 98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120, + 2,16,9,98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105,111, + 110,115,101,100,105,116,11,11,111,101,95,114,101,97,100,111,110,108,121,12, + 111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115, + 101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110, + 99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111, + 101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116, + 115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116, + 111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116, + 101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95, + 97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105, + 99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101, + 49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95, + 107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115, + 116,97,116,101,27,111,101,49,95,99,104,101,99,107,118,97,108,117,101,97, + 102,116,101,114,115,116,97,116,114,101,97,100,0,7,111,112,116,105,111,110, + 115,11,17,98,111,95,101,120,101,99,117,116,101,111,110,99,108,105,99,107, + 15,98,111,95,101,120,101,99,117,116,101,111,110,107,101,121,20,98,111,95, + 101,120,101,99,117,116,101,111,110,115,104,111,114,116,99,117,116,27,98,111, + 95,101,120,101,99,117,116,101,100,101,102,97,117,108,116,111,110,101,110,116, + 101,114,107,101,121,15,98,111,95,97,115,121,110,99,101,120,101,99,117,116, + 101,0,5,115,116,97,116,101,11,12,97,115,95,105,110,118,105,115,105,98, + 108,101,17,97,115,95,108,111,99,97,108,105,110,118,105,115,105,98,108,101, + 17,97,115,95,108,111,99,97,108,105,109,97,103,101,108,105,115,116,15,97, + 115,95,108,111,99,97,108,105,109,97,103,101,110,114,17,97,115,95,108,111, + 99,97,108,111,110,101,120,101,99,117,116,101,0,5,103,108,121,112,104,7, + 16,115,116,103,95,101,108,108,105,112,115,101,115,109,97,108,108,9,111,110, + 101,120,101,99,117,116,101,7,22,101,100,116,101,109,112,108,97,116,101,97, + 99,116,111,110,101,120,101,99,117,116,101,0,0,0,11,116,115,116,114,105, + 110,103,100,105,115,112,8,102,105,108,101,110,97,109,101,11,102,114,97,109, + 101,46,100,117,109,109,121,2,0,8,116,97,98,111,114,100,101,114,2,3, + 8,98,111,117,110,100,115,95,120,2,5,8,98,111,117,110,100,115,95,121, + 3,252,0,9,98,111,117,110,100,115,95,99,120,3,190,1,9,98,111,117, + 110,100,115,95,99,121,2,18,7,97,110,99,104,111,114,115,11,7,97,110, + 95,108,101,102,116,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111, + 116,116,111,109,0,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95, + 121,99,101,110,116,101,114,101,100,14,116,102,95,101,108,108,105,112,115,101, + 108,101,102,116,0,7,111,112,116,105,111,110,115,11,19,100,119,111,95,104, + 105,110,116,99,108,105,112,112,101,100,116,101,120,116,0,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,9,116,115,116,97,116,102, + 105,108,101,10,116,115,116,97,116,102,105,108,101,49,8,102,105,108,101,110, + 97,109,101,6,15,116,101,109,112,108,115,101,108,101,99,116,46,115,116,97, + 7,111,112,116,105,111,110,115,11,10,115,102,111,95,109,101,109,111,114,121, + 15,115,102,111,95,116,114,97,110,115,97,99,116,105,111,110,17,115,102,111, + 95,97,99,116,105,118,97,116,111,114,114,101,97,100,18,115,102,111,95,97, + 99,116,105,118,97,116,111,114,119,114,105,116,101,0,4,108,101,102,116,2, + 40,3,116,111,112,2,80,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tmsetemplateselectfo,''); +end. diff --git a/mseide-msegui/apps/ide/objectinspector.mfm b/mseide-msegui/apps/ide/objectinspector.mfm new file mode 100644 index 0000000..07d0282 --- /dev/null +++ b/mseide-msegui/apps/ide/objectinspector.mfm @@ -0,0 +1,366 @@ +object objectinspectorfo: tobjectinspectorfo + optionswidget = [ow_arrowfocus, ow_subfocus, ow_mousewheel, ow_destroywidgets, ow_hinton] + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_floatbutton, go_topbutton, go_backgroundbutton, go_nolockbutton, go_buttonhints] + popupmenu = mainpopup + onenter = enterexe + onactivate = enterexe + visible = False + bounds_x = 185 + bounds_y = 360 + bounds_cx = 254 + bounds_cy = 248 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.onlayout = objectinspectoronchildscaled + container.bounds = ( + 0 + 0 + 244 + 248 + ) + dragdock.splitter_size = 0 + dragdock.caption = 'Objectinspector' + dragdock.optionsdock = [od_savepos, od_savezorder, od_canmove, od_canfloat, od_candock, od_propsize, od_captionhint, od_childicons] + options = [fo_savepos, fo_savezorder, fo_savestate] + statfile = mainfo.projectstatfile + caption = 'Object Inspector' + icon.transparentcolor = -2147483642 + icon.image = { + 0000000000000000180000001800000078070000000000000000000000000000 + 0000000000000000000000000000000000000000F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001D9EEF001AEEEF3018EEDF5019EECF201C5E9EC01E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301EFF2F201 + A0EFF70160F0FF0257F0FF0144EFFF0128EEFF0161EBF501D9E6E701E3E3E301 + E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801D7D7D701 + D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F3019BF1F90174F1FF01 + 8AF1FF0190F2FF0183F1FF016AF0FF0148EFFF0122EEFF0138DDEA01E1E2E201 + E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801D7D7D701 + D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501CFF3F60170F1FF0196F2FF01 + B5F3FF01BFF3FF01ACF2FF0188F1FF0160F0FF0136EFFF010DEEFF0155ADB401 + DDDDDD01E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801D7D7D701 + D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501A1F1F9017CF1FF01A9F2FF01 + D0F4FF01D0F8FF01C5F3FF0198F2FF016BF0FF013EEFFF0111EEFF012AC2CD01 + 96969601E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801D7D7D701 + D5D5D501D3D3D301D2D2D201D0D0D001F5F5F50184F0FB0177F1FF01A2F2FF01 + C8F3FF01D0F5FF01BBF3FF0193F2FF0168F0FF013BEFFF010FEEFF011DD6E401 + 66666601D4D4D401DFDFDF01DDDDDD01DBDBDB01D3D3DB01D8D8D801D7D7D701 + D5D5D501D3D3D301D2D2D201D0D0D001F5F5F5019AF1F90163F0FF0186F1FF01 + A0F2FF01A8F2FF0198F2FF017AF1FF0155F0FF012DEFFF010DEEFF012CC0CB01 + 66666601BABABA01DFDFDF01DDDDDD01ABABE3015B5BF001D8D8D801D7D7D701 + D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501CCF2F50147EFFF0161F0FF01 + 73F1FF0178F1FF016EF0FF0157F0FF0139EFFF0116EEFF010DEEFF0146979D01 + 66666601BCBCBC01DFDFDF01DDDDDD013737F7010707FE019A9AC101D6D6D601 + D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F30187F0F90136EFFF01 + 45EFFF0148EFFF0141EFFF012FEFFF0116EEFF010DEEFF0129C5D10166666602 + D5D5D501DFDFDF019A9AE8010404FF022424D001ABABAB01D5D5D501D3D3D301 + D2D2D201D0D0D001F5F5F501F3F3F301F1F2F20176D3DA011AE6F60118EEFF01 + 12EEFF010DEEFF010FECFD0138B0B901636B6C01666666019B9B9B01E0E0E001 + DCDCDF012626FA010404FF0356569001D1D1D101D3D3D301D2D2D201D0D0D001 + F5F5F501F3F3F301F2F2F201F0F0F0019FAAAB01548D910143A1A8014F909501 + 6175760168686801676767018B8B8B01DEDEDE01E0E0E0018888EC010404FF04 + 1919DC019F9F9F01D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01CFCFCF01969696017C7C7C01767676018F8F8F01BABABA01 + E3E3E301E2E2E201D6D6E1011A1AFC010404FF0548489901CBCBCB01D2D2D201 + D0D0D001F5F5F501F79BA701F9798901F8788801F7778701F6768601F5758502 + F4748401F3738301EABAC001E3E3E301E2E2E2017474EF010404FF061111E701 + 91919501D2D2D201D0D0D001F5F5F501FC445B01FF002008EF8F9B01E3E3E301 + CFCFE5010F0FFD010404FF073C3CA301C4C4C401D0D0D001F5F5F501FC445B01 + FF002008A0404C01767676016161F3010404FF080D0DF10182828E01D0D0D001 + F5F5F501FC445B01FF002008A0404C01757578017878F0017272F0014141BF01 + 3434B2013333B1023232B0033131AF014F4F7C01BBBBBB01F5F5F501FC445B01 + FF002008A0404C0176767601E2E2E201B8B8B801656565016464640163636301 + 6262620161616102606060015F5F5F027D7D7D01F5F5F501FC445B01FF002008 + A0404C0176767601E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01 + D8D8D801D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501FC445B01 + FF002008A0404C0176767601E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01 + DADADA01D8D8D801D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501 + FC445B01FF002008A0404C0176767601E2E2E201E0E0E001DFDFDF01DDDDDD01 + DBDBDB01DADADA01D8D8D801D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001 + F5F5F501FC445B01FF002008A0404C0176767601E2E2E201E0E0E001DFDFDF01 + DDDDDD01DBDBDB01DADADA01D8D8D801D7D7D701D5D5D501D3D3D301D2D2D201 + D0D0D001F5F5F501F79BA701EC6C7C01B6364601B5354504B434440284545A01 + 76767601E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301D9D9D901 + 6C6C6C016B6B6B026A6A6A0269696901686868016767670176767601E2E2E201 + E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801D7D7D701D5D5D501 + D3D3D301D2D2D201D0D0D001 + } + oncreate = createexe + oneventloopstart = objectinspectorfoonloaded + onasyncevent = asyncexe + onlayout = objectinspectoronchildscaled + left = 239 + top = 180 + moduleclassname = 'tdockform' + object compselector: tdropdownlistedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.localprops = [] + frame.localprops1 = [] + frame.button.color = -2147483646 + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + end> + taborder = 2 + bounds_x = 0 + bounds_y = 1 + bounds_cx = 171 + bounds_cy = 22 + anchors = [an_left, an_top, an_right] + onsetvalue = compselectoronsetvalue + dropdown.options = [deo_selectonly, deo_autodropdown, deo_keydropdown] + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + onbeforedropdown = compselectorbeforedropdown + reffontheight = 16 + end + object grid: twidgetgrid + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 1 + popupmenu = gridpopup + bounds_x = 0 + bounds_y = 24 + bounds_cx = 244 + bounds_cy = 224 + anchors = [an_top, an_bottom] + optionsgrid = [og_colsizing, og_colmoving, og_colchangeontabkey, og_wrapcol] + optionsgrid1 = [og1_noresetselect] + rowcolors.count = 1 + rowcolors.items = ( + 16777202 + ) + rowfonts.count = 6 + rowfonts.items = < + item + name = 'stf_default' + xscale = 1 + localprops = [flp_xscale] + end + item + color = 32768 + name = 'stf_default' + xscale = 1 + localprops = [flp_color, flp_xscale] + end + item + color = 32768 + name = 'stf_default' + xscale = 1 + localprops = [flp_color, flp_xscale] + end + item + color = -1610612723 + name = 'stf_default' + xscale = 1 + localprops = [flp_color, flp_xscale] + end + item + style = [fs_bold] + name = 'stf_default' + xscale = 1 + localprops = [flp_style, flp_xscale] + end + item + style = [fs_bold] + name = 'stf_default' + xscale = 1 + localprops = [flp_style, flp_xscale] + end> + datacols.count = 2 + datacols.items = < + item[props] + linecolor = -1610612731 + linecolorfix = -1610612733 + colorselect = -1610612717 + coloractive = -1879048185 + width = 90 + onbeforedrawcell = befdrawcell + options = [co_readonly, co_drawfocus, co_mouseselect, co_keyselect, co_multiselect, co_proportional, co_savestate] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor] + widthmin = 10 + onshowhint = col0onshowhint + onselectionchanged = selchanged + widgetname = 'props' + dataclass = ttreeitemeditlist + end + item[values] + linecolorfix = -1610612733 + width = 148 + rowfontoffset = 4 + options = [co_fill, co_savestate] + options1 = [co1_rowfont, co1_zebracolor] + widthmin = 10 + oncellevent = valuescellevent + onshowhint = col1onshowhint + widgetname = 'values' + dataclass = titemeditlist + end> + datarowlinecolor = -1610612731 + datarowheight = 18 + statfile = mainfo.projectstatfile + onrowsdatachanged = gridrowsdatachanged + oncellevent = gridcellevent + drag.onbeforedragbegin = gridondragbegin + drag.onbeforedragover = gridondragover + drag.onbeforedragdrop = gridondragdrop + reffontheight = 16 + object props: ttreeitemedit + optionswidget1 = [ow1_autoheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_noskin] + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 1 + onpopup = propsonpopup + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 90 + bounds_cy = 18 + optionsedit1 = [] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_resetselectonexit, oe_exitoncursor, oe_hintclippedtext, oe_locate] + onkeydown = propskeydownexe + onupdaterowvalues = propupdaterowvalue + options = [teo_treecolnavig, teo_keyrowmoving] + oncheckrowmove = propsoncheckrowmove + end + object values: tdropdownitemedit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + color = -1879048185 + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.button.width = 15 + frame.button.color = -1879048187 + frame.buttons.count = 2 + frame.buttons.items = < + item + width = 15 + color = -1879048187 + end + item + width = 15 + color = -1879048187 + imagenr = 17 + end> + taborder = 2 + onenter = valuesenterexe + visible = False + bounds_x = 91 + bounds_y = 0 + bounds_cx = 148 + bounds_cy = 18 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_forcereturncheckvalue, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext] + font.name = 'stf_default' + font.xscale = 1 + font.localprops = [flp_xscale] + onkeydown = valueskeydown + onclientmouseevent = valuesonmouseevent + onsetvalue = valuessetvalue + onpaintimage = paintimageexe + onextendimage = extendimageexe + onbuttonaction = valuesbuttonaction + onupdaterowvalues = valueupdaterowvalue + dropdown.options = [deo_autodropdown, deo_keydropdown, deo_cliphint] + dropdown.dropdownrowcount = 16 + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + onbeforedropdown = valuesbeforedropdown + reffontheight = 16 + end + end + object compedit: trichbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets, ow_disabledhint, ow_timedhint] + optionsskin = [osk_noface] + face.fade_pos.count = 2 + face.fade_pos.items = ( + 0 + 1 + ) + face.fade_color.count = 2 + face.fade_color.items = ( + 16760767 + 15571610 + ) + face.fade_direction = gd_down + face.localprops = [fal_fadirection] + hint = 'Show component editor.' + bounds_x = 217 + bounds_y = 2 + bounds_cx = 25 + bounds_cy = 20 + anchors = [an_top, an_right] + state = [as_disabled, as_localdisabled, as_localcaption, as_localhint, as_localonexecute] + facedisabled.localprops = [] + facedisabled.template = guitemplatesmo.fadevertkonvex + caption = '&ED' + onexecute = compeditonexecute + reffontheight = 16 + end + object findbu: tstockglyphbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + taborder = 3 + bounds_x = 197 + bounds_y = 2 + bounds_cx = 18 + bounds_cy = 20 + anchors = [an_top, an_right] + state = [as_localcaption, as_localimagelist, as_localimagenr] + glyph = stg_ellipsesmall + action = actionsmo.findcompallact + reffontheight = 16 + end + object gridpopup: tpopupmenu + onupdate = popupupdate + menu.submenu.count = 3 + menu.submenu.items = < + item + caption = 'Collapse tree' + state = [as_localcaption, as_localonexecute] + onexecute = collapseexe + end + item + caption = 'Revert to inherited' + name = 'revert' + state = [as_localcaption, as_localonexecute] + onexecute = revertexe + end + item + caption = 'Clear Selection' + name = 'clearselect' + state = [as_localcaption, as_localonexecute] + onexecute = clearselect + end> + left = 112 + top = 80 + end + object mainpopup: tpopupmenu + options = [mo_insertfirst, mo_shortcutright] + menu.submenu.count = 1 + menu.submenu.items = < + item + action = actionsmo.findcompallact + end> + left = 56 + top = 56 + end +end diff --git a/mseide-msegui/apps/ide/objectinspector.pas b/mseide-msegui/apps/ide/objectinspector.pas new file mode 100644 index 0000000..8071207 --- /dev/null +++ b/mseide-msegui/apps/ide/objectinspector.pas @@ -0,0 +1,2039 @@ +{ MSEide Copyright (c) 1999-2013 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit objectinspector; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + mseforms,msewidgets,msegrids,msewidgetgrid,classes,mclasses,mseclasses, + msepropertyeditors,mseglob,mseguiglob,msearrayutils,msedragglob,msegui,mseedit, + msedataedits,mselistbrowser,msedatanodes,msedesignintf,typinfo, + msecomponenteditors,msesimplewidgets,msegraphutils,msemenus,mseevent, + msedesigner,msetypes,msestrings,mselist,msegraphics; + +type + tobjectinspectorfo = class; + + tobjectinspectorselections = class(tdesignerselections) + private + fowner: tobjectinspectorfo; + protected + procedure compselectoronsetvalue(const sender: TObject; var avalue: Integer; + var accept: Boolean); + procedure dochanged; override; + public + constructor create(owner: tobjectinspectorfo); + end; + + tpropertyitem = class; + + tproppathinfo = class(ttreelistedititem) + private + fname: msestring; + procedure doexpand(const aitem: tpropertyitem); + public + constructor create(const aprop: tpropertyitem); reintroduce; + procedure save(const aprops: ttreeitemeditlist); + procedure restore(const aprops: ttreeitemeditlist); + end; + + compinfoty = record + instance: tcomponent; + proppathinfo: tproppathinfo; + actprop: msestringarty; + end; + pcompinfoty = ^compinfoty; + + tcomponentinfos = class(torderedrecordlist) + protected + function compare(const l,r): integer; + function getcomparefunc: sortcomparemethodty; override; + procedure finalizerecord(var item); override; + public + constructor create; + function find(const ainstance: tcomponent): integer; + function deleteitem(const ainstance: tcomponent): integer; + function getitem(ainstance: tcomponent): pcompinfoty; + function add(const aitem: compinfoty): integer; + end; + + tobjectinspectorfo = class(tdockform,iobjectinspector,idesignnotification) + compselector: tdropdownlistedit; + grid: twidgetgrid; + props: ttreeitemedit; + gridpopup: tpopupmenu; + values: tdropdownitemedit; + compedit: trichbutton; + findbu: tstockglyphbutton; + mainpopup: tpopupmenu; + procedure propsoncheckrowmove(const curindex: Integer; + const newindex: Integer; var accept: Boolean); + procedure createexe(const sender: TObject); + procedure gridrowsdatachanged(const sender: tcustomgrid; + const acell: gridcoordty; const count: integer); + procedure compselectorbeforedropdown(const sender: TObject); + procedure compselectoronsetvalue(const sender: tobject; var avalue: msestring; + var accept: boolean); + procedure valuesonmouseevent(const sender: twidget; var info: mouseeventinfoty); + procedure valuessetvalue(const sender: TObject; var avalue: mseString; + var accept: Boolean); + procedure gridcellevent(const sender: tobject; var info: celleventinfoty); + procedure valueupdaterowvalue(const sender: tobject; const aindex: integer; + const aitem: tlistitem); + procedure valuesbuttonaction(const sender: tobject; var action: buttonactionty; + const buttonindex: Integer); + procedure valuesbeforedropdown(const sender: TObject); + procedure compeditonexecute(const sender: tobject); + procedure gridondragbegin(const sender: tobject; const apos: pointty; + var dragobject: tdragobject; var processed: boolean); + procedure gridondragover(const sender: tobject; const apos: pointty; + var dragobject: tdragobject; var accept: boolean; var processed: boolean); + procedure gridondragdrop(const sender: tobject; const apos: pointty; + var dragobject: tdragobject; var processed: boolean); + procedure propsonpopup(const sender: tobject; var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); + procedure objectinspectorfoonloaded(const sender: tobject); + procedure objectinspectoronchildscaled(const sender: TObject); + procedure col0onshowhint(const sender: tdatacol; const arow: Integer; var info: hintinfoty); + procedure col1onshowhint(const sender: tdatacol; const arow: Integer; + var info: hintinfoty); + procedure valueskeydown(const sender: twidget; var info: keyeventinfoty); + procedure propupdaterowvalue(const sender: TObject; const aindex: integer; + const aitem: tlistitem); + procedure collapseexe(const sender: TObject); + procedure popupupdate(const sender: tcustommenu); + procedure revertexe(const sender: TObject); + procedure befdrawcell(const sender: tcol; const canvas: tcanvas; + var cellinfo: cellinfoty; var processed: Boolean); + procedure selchanged(const sender: tdatacol); + procedure clearselect(const sender: TObject); + procedure valuescellevent(const sender: TObject; var info: celleventinfoty); + procedure valuesenterexe(const sender: TObject); + procedure asyncexe(const sender: TObject; var atag: Integer); + procedure paintimageexe(const sender: twidget; const acanvas: tcanvas); + procedure extendimageexe(const sender: twidget; + const cellinfopo: pcellinfoty; var info: extrainfoty); + + procedure propskeydownexe(const sender: twidget; var ainfo: keyeventinfoty); + procedure enterexe(const sender: TObject); + private + factmodule: tmsecomponent; + factcomp: tcomponent; + flastcomp: tcomponent; + factcomps: componentarty; + fcomponentnames: componentnamearty; + fcomponentinfos: tcomponentinfos; + fchanging: integer; + frereadprops: boolean; + fsinglecomp: boolean; + function componentdispname(const instance: tcomponent): msestring; + procedure updatecomponentname; + procedure selectedcompchanged; + procedure propscreatenode(const sender: tcustomitemlist; + var node: ttreelistedititem); + procedure valuescreatenode(const sender: tcustomitemlist; + var node: tlistedititem); + procedure propnotification(const sender: tlistitem; var action: nodeactionty); + + procedure readprops(const module: tmsecomponent; const comp: componentarty); + procedure readprops(const module: tmsecomponent; const comp: tcomponent); + function editorstoprops(const editors: propertyeditorarty): treelistitemarty; + function candragsource(const apos: pointty; var row: integer): boolean; + function candragdest(const apos: pointty; var row: integer): boolean; + procedure rereadprops; + protected + procedure updatecompselection; + procedure updatedefaultstate(const aindex: integer); + procedure doasyncevent(var atag: integer); override; + function findvalueeditor(const editor: tpropertyeditor): integer; + function restoreactprop(const acomponent: tcomponent; + acol: integer; exact: boolean = false): boolean; + procedure saveproppath; + procedure clear; + function reviseproperties(const aprops: propertyeditorarty): propertyeditorarty; + procedure loaded; override; + procedure clearselectedprops(const aprop: tpropertyitem); + //clears editor selction of all nodes which are no siblings + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure refresh; + procedure clickedcomponentchanged(const aclickedcomp: tcomponent); + procedure showmethodsource(const aeditor: tmethodpropertyeditor); + function selectprop(const anamepath: msestringarty; + const acol: int32; const exact: boolean): boolean; + function selectprop(const acomponent: tobject; const apropname: string; + const aitemindex: int32): boolean; + procedure asyncactivate(); + + //idesignnotification + procedure itemdeleted(const adesigner: idesigner; + const amodule: tmsecomponent; const aitem: tcomponent); + procedure iteminserted(const adesigner: idesigner; + const amodule: tmsecomponent; const aitem: tcomponent); + procedure itemsmodified(const adesigner: idesigner; const aitem: tobject); + procedure componentnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const aitem: tcomponent; + const newname: string); + procedure moduleclassnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); + procedure instancevarnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); + procedure selectionchanged(const adesigner: idesigner; + const aselection: idesignerselections); + procedure moduleactivated(const adesigner: idesigner; + const amodule: tmsecomponent); + procedure moduledeactivated(const adesigner: idesigner; + const amodule: tmsecomponent); + procedure moduledestroyed(const adesigner: idesigner; + const amodule: tmsecomponent); + procedure methodcreated(const adesigner: idesigner; + const amodule: tmsecomponent; + const aname: string; const atype: ptypeinfo); + procedure methodnamechanged(const adesigner: idesigner; + const amodule: tmsecomponent; + const newname,oldname: string; const atypeinfo: ptypeinfo); + procedure showobjecttext(const adesigner: idesigner; + const afilename: filenamety; const backupcreated: boolean); + procedure closeobjecttext(const adesigner: idesigner; + const afilename: filenamety; var cancel: boolean); + procedure beforefilesave(const adesigner: idesigner; + const afilename: filenamety); + procedure beforemake(const adesigner: idesigner; const maketag: integer; + var abort: boolean); + procedure aftermake(const adesigner: idesigner; const exitcode: integer); + + //iobjectinspector + function getproperties(const objects: objectarty; const amodule: tmsecomponent; + const acomponent: tcomponent): propertyeditorarty; + procedure propertymodified(const sender: tpropertyeditor); + function getmatchingmethods(const sender: tpropertyeditor; + atype: ptypeinfo): msestringarty; + end; + + tpropertyitem = class(ttreelistedititem) + private + function getexpanded: boolean; + protected + feditor: tpropertyeditor; + procedure setexpanded(const Value: boolean) override; + procedure updatestate; + procedure updatesubpropertypath; + function finditembyname(const aname: msestring): tpropertyitem; + public + destructor destroy; override; + property expanded: boolean read getexpanded write setexpanded; + function rootpath: msestring; + end; + +var + objectinspectorfo: Tobjectinspectorfo; + +implementation +uses + objectinspector_mfm,sysutils,msearrayprops,actionsmodule,mseformatstr, + msebitmap,msedrag,mseeditglob,msestockobjects,msedropdownlist, + sourceupdate,sourceform,msekeyboard,main,msedatalist,msecolordialog; + +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + ado_rereadprops = 1; //asyncevent codes + ado_updatecomponentname = 2; + ado_compselection = 3; + ado_activate = 4; + selectcolor = cl_ltred; + +type + defaultmethodty = procedure of object; + + titemlist1 = class(tcustomitemlist); + tpropertyeditor1 = class(tpropertyeditor); + propertyitemarty = array of tpropertyitem; + + tpropertyvalue = class(tlistedititem) + protected + feditor: tpropertyeditor; + public + procedure updatestate(const exitrow: boolean = false); + end; + ppropertyvalue = ^tpropertyvalue; + +{ tproppathinfo } + +constructor tproppathinfo.create(const aprop: tpropertyitem); +var + int1: integer; +begin + inherited create; + if aprop <> nil then begin + fname:= aprop.feditor.name; + if aprop.expanded then begin + for int1:= 0 to aprop.fcount - 1 do begin + add(ttreelistedititem( + tproppathinfo.create(tpropertyitem(aprop[int1])))); + end; + end; + end; +end; + +procedure tproppathinfo.save(const aprops: ttreeitemeditlist); +var + int1: integer; +begin + clear; + for int1:= 0 to aprops.count - 1 do begin + self.add(ttreelistedititem( + tproppathinfo.create(tpropertyitem(aprops[int1])))); + end; +end; + +procedure tproppathinfo.doexpand(const aitem: tpropertyitem); +var + int1,int2: integer; + item1: tpropertyitem; +begin + if aitem.feditor <> nil then begin + try + aitem.expanded:= true; //else root item + except + aitem.expanded:= false; //probably multiselection with less items + exit; + end; + end; + for int1:= 0 to fcount - 1 do begin + with tproppathinfo(fitems[int1]) do begin + if fcount > 0 then begin + for int2:= 0 to aitem.count - 1 do begin + item1:= tpropertyitem(aitem[int2]); + if item1.feditor.name = fname then begin + doexpand(item1); + end; + end; + end; + end; + end; +end; + +procedure tproppathinfo.restore(const aprops: ttreeitemeditlist); +var + item1: tpropertyitem; +begin + item1:= tpropertyitem.create; + try + item1.assign(aprops); + doexpand(item1); + finally + item1.Free; + end; +end; + +{ tcomponentinfos } + +constructor tcomponentinfos.create; +begin + inherited create(sizeof(compinfoty),[rels_needsfinalize]); +end; + +function tcomponentinfos.compare(const l,r): integer; +begin + result:= pchar(compinfoty(l).instance) - pchar(compinfoty(r).instance); +end; + +function tcomponentinfos.getcomparefunc: sortcomparemethodty; +begin + result:= {$ifdef FPC}@{$endif}compare; +end; + +procedure tcomponentinfos.finalizerecord(var item); +begin + finalize(compinfoty(item)); + with compinfoty(item) do begin + proppathinfo.free; + end; +end; + +function tcomponentinfos.find(const ainstance: tcomponent): integer; +var + info: compinfoty; +begin + info.instance:= ainstance; + result:= indexof(info); +end; + +function tcomponentinfos.deleteitem(const ainstance: tcomponent): integer; +begin + result:= find(ainstance); + delete(result); +end; + +function tcomponentinfos.add(const aitem: compinfoty): integer; +begin + result:= inherited add(aitem); +end; + +function tcomponentinfos.getitem(ainstance: tcomponent): pcompinfoty; +var + int1: integer; + info: compinfoty; +begin + int1:= find(ainstance); + if int1 < 0 then begin + fillchar(info,sizeof(info),0); + info.instance:= ainstance; + info.proppathinfo:= tproppathinfo.create(nil); + int1:= add(info); + end; + result:= getitempo(int1); +end; + +{ tobjectinspectorselections } + +constructor tobjectinspectorselections.create(owner: tobjectinspectorfo); +begin + fowner:= owner; + inherited create; +end; + +procedure tobjectinspectorselections.compselectoronsetvalue(const sender: TObject; + var avalue: Integer; var accept: Boolean); +begin +end; + +procedure tobjectinspectorselections.dochanged; +var + int1: integer; +begin + inherited; + with fowner.compselector.dropdown do begin + cols[0].clear; + for int1:= 0 to count-1 do begin + with itempo(int1)^ do begin + cols[0].add(msestring(designer.getcomponentdispname(instance))+ + ' ('+msestring(designer.getclassname(instance))+')'); + end; + end; + end; +end; + +{ tpropertyitem } + +destructor tpropertyitem.destroy; +begin + inherited; + if (feditor <> nil) and not (ps_owned in feditor.state) then begin + feditor.free; + end; +end; + +function tpropertyitem.getexpanded: boolean; +begin + result:= ps_expanded in feditor.state; +end; + +procedure tpropertyitem.setexpanded(const Value: boolean); +begin + inherited; +// inherited expanded:= value; + if value <> getexpanded then begin + feditor.expanded:= value; + updatestate; + end; +end; + +procedure tpropertyitem.updatestate; +var + stat1: propertystatesty; +begin + with feditor do begin + caption:= Name; + stat1:= state; + if ps_subproperties in stat1 then begin + if ps_expanded in stat1 then begin + fimagenr:= 1; + end + else begin + fimagenr:= 2; + end; + end + else begin + fimagenr:= -1; + end; + end; +end; + +procedure tpropertyitem.updatesubpropertypath; +begin + //dummy +end; + +function tpropertyitem.finditembyname(const aname: msestring): tpropertyitem; +var + int1: integer; + item1: tpropertyitem; +begin + result:= nil; + for int1:= 0 to fcount-1 do begin + item1:= tpropertyitem(fitems[int1]); + if item1.feditor.name = aname then begin + result:= item1; + break; + end; + end; +end; + +function tpropertyitem.rootpath: msestring; + +var + prop1: tpropertyitem; +begin + prop1:= self; + result:= ''; + while prop1 <> nil do begin + if (prop1.feditor is tarrayelementeditor) or + (prop1.feditor is tcollectionitemeditor) then begin + result:= '[]'+result; + end + else begin + if prop1.feditor is trecordpropertyeditor then begin + result:= '.'+prop1.feditor.propertyname+'_'+copy(result,2,bigint); + end + else begin + result:= '.'+prop1.feditor.propertyname+result; + end; + end; + prop1:= tpropertyitem(prop1.parent); + end; + result:= copy(result,2,bigint); +end; + +{ tpropertyvalue } + +procedure tpropertyvalue.updatestate(const exitrow: boolean = false); +begin + with feditor do begin + if allequal or + (not exitrow and (objectinspectorfo.values.item = self) and + (objectinspectorfo.grid.col = 1)) then begin + caption:= removelinebreaks(getvalue); + end + else begin + caption:= ''; + end; + end; +end; + +{ tobjectinspectorfo} + +constructor tobjectinspectorfo.create(aowner: tcomponent); +begin + fcomponentinfos:= tcomponentinfos.create; + inherited create(aowner); + designnotifications.Registernotification(idesignnotification(self)); +end; + +destructor tobjectinspectorfo.destroy; +begin + designnotifications.unRegisternotification(idesignnotification(self)); + inherited; + fcomponentinfos.Free; +end; + +procedure Tobjectinspectorfo.propscreatenode(const sender: tcustomitemlist; + var node: ttreelistedititem); +begin + node:= tpropertyitem.create(sender); +end; + +function tobjectinspectorfo.findvalueeditor(const editor: tpropertyeditor): integer; +var + int1: integer; + po1: ppropertyvalue; +begin + result:= -1; +{$warnings off} + po1:= ppropertyvalue(titemlist1(values.itemlist).fdatapo); +{$warnings on} + for int1:= 0 to values.itemlist.count - 1 do begin + if po1^.feditor = editor then begin + result:= int1; + break; + end; + inc(po1); + end; +end; + +procedure Tobjectinspectorfo.valuescreatenode( + const sender: tcustomitemlist; var node: tlistedititem); +begin + node:= tpropertyvalue.create(sender); +end; + +procedure tobjectinspectorfo.showmethodsource( + const aeditor: tmethodpropertyeditor); +begin + if aeditor.method.data <> nil then begin + sourcefo.showsourcepos(sourceupdater.findmethodpos(aeditor.method,true),true); + end; +end; + +procedure tobjectinspectorfo.valuesonmouseevent(const sender: twidget; + var info: mouseeventinfoty); +begin + if sender.isdblclick(info) then begin + with tpropertyitem(props.item) do begin +// if feditor is tmethodpropertyeditor then begin + if not values.edited or values.checkvalue then begin + feditor.valueeditor.navigevent(); +// showmethodsource(tmethodpropertyeditor(feditor)); +// end; + end; + end; + end; +end; + +procedure tobjectinspectorfo.valuessetvalue(const sender: TObject; + var avalue: mseString; var accept: Boolean); +begin + try + tpropertyvalue(titemedit(sender).item).feditor.setvalue(avalue); + except + values.editor.undo; + raise; + end; + avalue:= tpropertyvalue(titemedit(sender).item).feditor.getvalue; +// mainfo.sourcechanged(nil); +end; + +procedure tobjectinspectorfo.propsoncheckrowmove(const curindex: Integer; + const newindex: Integer; var accept: Boolean); +var + editor1: tpropertyeditor; + bo1: boolean; +begin + //simulate dragevent + editor1:= tpropertyitem(props[curindex]).feditor; + editor1.dragbegin(bo1); + if bo1 then begin + with tpropertyitem(props[newindex]).feditor do begin + bo1:= false; + dragover(editor1,bo1); + if bo1 then begin + dragdrop(editor1); + grid.row:= newindex; + end; + end; + end; +end; + +procedure tobjectinspectorfo.createexe(const sender: TObject); +begin + props.itemlist.oncreateitem:= {$ifdef FPC}@{$endif}propscreatenode; + props.itemlist.onitemnotification:= {$ifdef FPC}@{$endif}propnotification; + values.itemlist.oncreateitem:= {$ifdef FPC}@{$endif}valuescreatenode; +end; + +procedure tobjectinspectorfo.gridrowsdatachanged(const sender: tcustomgrid; + const acell: gridcoordty; const count: integer); +var + int1: integer; +begin + props.itemlist.beginupdate; + values.itemlist.beginupdate; + try + for int1:= acell.row to acell.row + count - 1 do begin + tpropertyitem(props.itemlist[int1]).updatestate; + tpropertyvalue(values.itemlist[int1]).feditor:= + tpropertyitem(props.itemlist[int1]).feditor; + if not grid.cellexiting then begin + tpropertyvalue(values.itemlist[int1]).updatestate; + end; + end; + finally + props.itemlist.endupdate; + values.itemlist.endupdate; + end; +end; + +procedure tobjectinspectorfo.valuesenterexe(const sender: TObject); +begin + tpropertyvalue(values.item).updatestate; +end; + +procedure tobjectinspectorfo.moduleactivated(const adesigner: idesigner; + const amodule: tmsecomponent); +begin + factmodule:= amodule; + caption:= actionsmo.c[ord(ac_objectinspector)] + ' (' + + msestring(amodule.Name)+')'; + updatecomponentname; +// clear; +end; + +procedure tobjectinspectorfo.moduledeactivated(const adesigner: idesigner; + const amodule: tmsecomponent); +begin + caption:= actionsmo.c[ord(ac_objectinspector)]; +// clear; + factmodule:= nil; +end; + +procedure tobjectinspectorfo.moduledestroyed(const adesigner: idesigner; + const amodule: tmsecomponent); +begin + //dummy +end; + +procedure tobjectinspectorfo.ItemDeleted(const ADesigner: IDesigner; + const amodule: tmsecomponent; const AItem: tcomponent); +begin + if factcomp = aitem then begin + clear; + end; + if flastcomp = aitem then begin + flastcomp:= nil; + end; + fcomponentinfos.deleteitem(aitem); +end; + +procedure tobjectinspectorfo.ItemInserted(const ADesigner: IDesigner; + const amodule: tmsecomponent; const AItem: tcomponent); +begin + //dummy; +end; + +function tobjectinspectorfo.reviseproperties( + const aprops: propertyeditorarty): propertyeditorarty; +var + int1,int2,int3,int4: integer; + str1: msestring; + edar1: propertyeditorarty; + amodule: tmsecomponent; + acomponent: tcomponent; +begin + result:= aprops; + if length(result) > 0 then begin + int2:= 0; + int3:= 1; + for int1:= 1 to high(result) do begin + if result[int1].name = result[int2].name then begin + result[int1].free; //remove duplicates + end + else begin + result[int3]:= result[int1]; + inc(int3); + int2:= int1; + end; + end; + setlength(result,int3); + with tpropertyeditor1(result[0]) do begin + amodule:= fmodule; + acomponent:= fcomponent; + end; + int1:= 0; + while int1 <= high(result) do begin + str1:= result[int1].name; +// int2:= msestrscan(str1,msechar('_')); + int2:= findchar(str1,msechar('_')); + if int2 > 0 then begin + int3:= int1+1; + while (int3 <= high(result)) and + (msestrlcomp(pmsechar(str1),pmsechar(result[int3].name),int2) = 0) do begin + inc(int3); + end; + setlength(edar1,int3-int1); + move(result[int1],edar1[0],length(edar1) * sizeof(edar1[0])); + inc(int2); + for int4:= 0 to high(edar1) do begin + tpropertyeditor1(edar1[int4]).fname:= + copy(tpropertyeditor1(edar1[int4]).fname,int2,bigint); + end; + fillchar(result[int1],length(edar1)*sizeof(result[0]),0); + result[int1]:= trecordpropertyeditor.create(designer,amodule,acomponent, + iobjectinspector(self),ansistring(copy(str1,1,int2-2)), + reviseproperties(edar1)); + int1:= int3; + end + else begin + inc(int1); + end; + end; + int2:= 0; + for int1:= 0 to high(result) do begin + if result[int1] <> nil then begin + result[int2]:= result[int1]; + inc(int2); + end; + end; + setlength(result,int2); + end; +end; + +function comparepropertyeditor(const l,r): integer; +begin + result:= tpropertyeditor(l).sortlevel - tpropertyeditor(r).sortlevel; + if result = 0 then begin +// result:= msecomparetext(tpropertyeditor(l).name,tpropertyeditor(r).name); + //has problems with underscores + result:= msestringicomp(tpropertyeditor(l).name,tpropertyeditor(r).name); + end; +end; + +function tobjectinspectorfo.getproperties(const objects: objectarty; + const amodule: tmsecomponent; + const acomponent: tcomponent): propertyeditorarty; +type + propinfopoararty = array of propinfopoarty; +var + ar1: propinfopoararty; + master: integer; + + function isok(const index: integer; var indexes: integerarty): boolean; + + function check(info: ppropinfo; ar: propinfopoarty; var foundindex: integer): boolean; + var + int1: integer; + kind: ttypekind; + typedata: ptypedata; + begin + result:= false; + kind:= info^.proptype^.Kind; + typedata:= gettypedata(info^.proptype{$ifndef FPC}^{$endif}); + for int1:= 0 to high(ar) do begin + if (ar[int1]^.proptype^.Kind = kind) and (info^.Name = ar[int1]^.Name) then begin + if not ((kind = tkset) and + (typedata^.comptype <> + gettypedata(ar[int1]^.proptype{$ifndef FPC}^{$endif})^.CompType) or + (kind = tkenumeration) and + (typedata^.basetype <> + gettypedata(ar[int1]^.proptype{$ifndef FPC}^{$endif})^.basetype)) then begin + foundindex:= int1; + result:= true; + break; + end; + end; + end; + end; + + var + int1: integer; + begin //isok + result:= true; + for int1:= 0 to high(ar1) do begin + if int1 <> master then begin + result:= check(ar1[master][index],ar1[int1],indexes[int1]); + if not result then begin + break; + end; + end + else begin + indexes[int1]:= index; + end; + end; + end; //isok + +var + ar2: propinfopoararty; + int1,int2,int3: integer; + propar: propinstancearty; + intar: integerarty; + +begin + result:= nil; + if (amodule <> nil) and (acomponent <> nil) and (high(objects) >= 0) then begin + setlength(ar1,length(objects)); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= getpropinfoar(objects[int1]); + end; + if high(objects) > 0 then begin + master:= 0; + int2:= high(ar1[0]); + for int1:= 1 to high(ar1) do begin + if high(ar1[int1]) < int2 then begin + master:= int1; + int2:= high(ar1[int1]); + end; + end; + inc(int2); + setlength(ar2,length(ar1)); + for int1:= 0 to high(ar1) do begin + setlength(ar2[int1],int2); + end; + int2:= 0; + setlength(intar,length(ar1)); + for int1:= 0 to high(ar1[master]) do begin + if isok(int1,intar) then begin + for int3:= 0 to high(ar1) do begin + ar2[int3][int2]:= ar1[int3][intar[int3]]; + end; + inc(int2); + end; + end; + for int3:= 0 to high(ar1) do begin + setlength(ar2[int3],int2); + end; + end + else begin + ar2:= ar1; + int2:= length(ar2[0]); + end; + setlength(result,int2); + setlength(propar,length(objects)); + for int1:= 0 to high(propar) do begin + propar[int1].instance:= objects[int1]; + end; + for int1:= 0 to int2 - 1 do begin + for int3:= 0 to high(propar) do begin + propar[int3].propinfo:= ar2[int3][int1]; + end; + result[int1]:= propertyeditors.geteditorclass( + ar2[0][int1]^.proptype{$ifndef FPC}^{$endif}, + objects[0].ClassType,ar2[0][int1]^.Name).create( + designer,amodule,acomponent,iobjectinspector(self), + propar,ar2[0][int1]^.proptype{$ifndef FPC}^{$endif}); + end; + sortarray(pointerarty(result),{$ifdef FPC}@{$endif}comparepropertyeditor); + result:= reviseproperties(result); + end; +end; +{ +function tobjectinspectorfo.selectprop(const anamepath: msestringarty; + const acol: int32; const exact: boolean): boolean; +var + i1: integer; + item1,item2,item3: tpropertyitem; +begin + result:= false; + if anamepath <> nil then begin + item1:= tpropertyitem.create; + try + item1.assign(props.itemlist); + item2:= item1; + result:= true; + item3:= item2; //compiler warning + for i1:= 0 to high(anamepath) do begin + item3:= item2; + item2:= item2.finditembyname(anamepath[i1]); + if item2 = nil then begin + result:= not exact; + break; + end; + end; + if result then begin + if item2 = nil then begin + item2:= item3; + end; + grid.focuscell(makegridcoord(acol,item2.findex)); + end; + finally + item1.Free; + end; + end; +end; +} +function tobjectinspectorfo.selectprop(const anamepath: msestringarty; + const acol: int32; const exact: boolean): boolean; +var + i1: integer; + p1,pe,p2: ^tpropertyitem; + item1: tpropertyitem; +begin + result:= false; + if anamepath <> nil then begin + p1:= props.itemlist.datapo; + pe:= p1 + props.itemlist.count; + while p1 < pe do begin + if (p1^.treelevel = 0) and (p1^.caption = anamepath[0]) then begin + break; + end; + inc(p1); + end; + if p1 < pe then begin + result:= true; + item1:= p1^; + p1:= @item1; + for i1:= 1 to high(anamepath) do begin + p1^.expanded:= true; + p2:= p1; + p1:= pointer(p1^.fitems); + pe:= p1 + p2^.count; + while p1 < pe do begin + if p1^.fcaption = anamepath[i1] then begin + break; + end; + inc(p1); + end; + if p1 = pe then begin + result:= not exact; + if p1 <> nil then begin + dec(p1); + end; + break; + end; + end; + if p1 = nil then begin + result:= false; + end; + if result then begin + grid.focuscell(makegridcoord(acol,p1^.findex)); + end; + end; + end; +end; + +function tobjectinspectorfo.selectprop(const acomponent: tobject; + const apropname: string; const aitemindex: int32): boolean; +var + ar1: msestringarty; +begin + result:= false; + if (apropname <> '') and (factcomp = acomponent) then begin + setlength(ar1,1); + ar1[0]:= msestring(apropname); + if aitemindex >= 0 then begin + ar1[0]:= ar1[0]+'.count'; + setlength(ar1,2); + ar1[1]:= 'Item '+inttostrmse(aitemindex); //todo: use correct propertyname + end; + result:= selectprop(ar1,0,true); + end; +end; + +procedure tobjectinspectorfo.asyncactivate(); +begin + asyncevent(ado_activate,[peo_modaldefer]); +end; + +function tobjectinspectorfo.restoreactprop(const acomponent: tcomponent; + acol: integer; exact: boolean = false): boolean; +var + po1: pcompinfoty; +begin + result:= false; + if acomponent <> nil then begin + po1:= fcomponentinfos.getitempo(fcomponentinfos.find(acomponent)); + if po1 <> nil then begin + result:= selectprop(po1^.actprop,acol,exact); + end; + end; +end; + +procedure tobjectinspectorfo.readprops(const module: tmsecomponent; + const comp: componentarty); +var + po1: pcompinfoty; + acol: integer; + int1: integer; +begin + try + grid.canclose; //save pending edits + except + on e: exception do begin + grid.rowcount:= 0; + raise; + end; + end; + acol:= grid.col; + if acol < 0 then begin + acol:= 1; + end; + grid.rowcount:= 0; + if high(comp) >= 0 then begin + props.itemlist.Assign(listitemarty(editorstoprops( + getproperties(objectarty(comp),module,comp[0])))); + po1:= fcomponentinfos.getitempo(fcomponentinfos.find(comp[0])); + if (po1 = nil) and (flastcomp <> nil) then begin + po1:= fcomponentinfos.getitempo(fcomponentinfos.find(flastcomp)); + end; + if po1 <> nil then begin + po1^.proppathinfo.restore(props.itemlist); + end; + if not restoreactprop(flastcomp,acol,true) then begin + restoreactprop(comp[0],acol); + end; + for int1:= 0 to grid.rowhigh do begin + updatedefaultstate(int1); + end; + end; +end; + +procedure tobjectinspectorfo.readprops(const module: tmsecomponent; + const comp: tcomponent); +var + ar1: componentarty; +begin + setlength(ar1,1); + ar1[0]:= comp; + readprops(module,ar1); +end; + +function tobjectinspectorfo.editorstoprops( + const editors: propertyeditorarty): treelistitemarty; +var + int1: integer; +begin + setlength(result,length(editors)); + for int1:= 0 to high(result) do begin + result[int1]:= tpropertyitem.create; + with tpropertyitem(result[int1]) do begin + feditor:= editors[int1]; + feditor.expanded:= false; + fcaption:= feditor.name{.fprops[0].propinfo^.Name}; + if ps_subproperties in feditor.state then begin + state:= state + [ns_subitems]; + end; + end; + end; +end; + +procedure tobjectinspectorfo.rereadprops; +var + scrpos: integer; +begin + saveproppath; +// grid.beginupdate; + scrpos:= grid.frame.scrollpos_y; + try + grid.defocusrow; + readprops(factmodule,factcomps); + finally + frereadprops:= false; +// grid.endupdate; + end; + grid.frame.scrollpos_y:= scrpos; + grid.showcell(grid.focusedcell); +end; + +procedure tobjectinspectorfo.ItemsModified(const ADesigner: IDesigner; + const AItem: tobject); +begin + if (aitem = nil) or (aitem = factcomp) and (fchanging = 0) then begin + refresh; + end; +end; + +procedure tobjectinspectorfo.doasyncevent(var atag: integer); +begin + inherited; + case atag of + ado_rereadprops: begin + rereadprops; + end; + ado_updatecomponentname: begin + updatecomponentname; + end; + ado_activate: begin + activate(); + end; + end; +end; + +procedure tobjectinspectorfo.refresh; +begin + if not frereadprops and (fchanging = 0) then begin + asyncevent(ado_rereadprops,[peo_modaldefer]); + frereadprops:= true; + end; +end; + +procedure tobjectinspectorfo.propertymodified(const sender: tpropertyeditor); + + procedure compmodified; + var + int1: integer; + props1: propinstancearty; + comps: componentarty; + begin + props1:= nil; //compiler warning + inc(fchanging); + try + comps:= sender.propowner; + if length(comps) > 0 then begin + for int1:= 0 to high(comps) do begin + designer.componentmodified(comps[int1]); + end; + end + else begin + props1:= sender.rootprops; + for int1:= 0 to high(props1) do begin + designer.componentmodified(props1[int1].instance); + end; + end; + finally + dec(fchanging); + end; + end; + +var + po1,po2: tpropertyvalue; + int1,int2,int3: integer; + bo1: boolean; + +begin + designer.begincomponentmodify; + props.itemlist.beginupdate; + values.itemlist.beginupdate; + try + if ps_volatile in sender.state then begin + refresh; + compmodified; + end + else begin +// designer.begincomponentmodify; +// try + if (props.item <> nil) and + (tpropertyvalue(values.item).feditor = sender) then begin + po1:= tpropertyvalue(values.item); + end + else begin + int1:= findvalueeditor(sender); + if int1 >= 0 then begin + po1:= tpropertyvalue(values.itemlist[int1]); + end + else begin + po1:= nil; + end; + end; + if po1 <> nil then begin + po1.updatestate; + updatedefaultstate(po1.index); + bo1:= (ps_refreshall in sender.state); + for int1:= 0 to grid.rowcount - 1 do begin + po2:= tpropertyvalue(values[int1]); + if (po2 <> po1) and (bo1 or (ps_refresh in po2.feditor.state)) then begin + with tpropertyitem(props[int1]) do begin + if feditor <> nil then begin + feditor.updatedefaultvalue; + end; + end; + po2.updatestate; + updatedefaultstate(int1); + int3:= props[int1].treelevel; + for int2:= int1 + 1 to grid.rowcount - 1 do begin + if props[int2].treelevel <= int3 then begin + break; + end + else begin + tpropertyvalue(values[int2]).updatestate; + end; + end; + end; + end; + end; + compmodified; + end; + mainfo.sourcechanged(nil); + finally + props.itemlist.endupdate; + values.itemlist.endupdate; + designer.endcomponentmodify; + end; +end; + +procedure tobjectinspectorfo.clickedcomponentchanged( + const aclickedcomp: tcomponent); +begin + with compselector do begin + if fsinglecomp then begin + value:= componentdispname(factcomp); + end + else begin + if aclickedcomp <> nil then begin + value:= componentdispname(aclickedcomp); + end + else begin + value:= ''; + end; + end; + if focused then begin + initfocus; + end; + end; +end; + +procedure tobjectinspectorfo.updatecomponentname; +begin + clickedcomponentchanged(designer.clickedcomp); +end; + +function tobjectinspectorfo.componentdispname( + const instance: tcomponent): msestring; +begin + result:= ''; + if instance <> nil then begin + if (factmodule <> nil) and not factmodule.checkowned(instance) and + (factmodule <> instance) and (instance.owner <> nil) then begin + result:= msestring(instance.owner.name)+'.'; + end; + result:= result + msestring(designer.getcomponentdispname(instance)) + + ' (' + msestring(designer.getclassname(instance))+')'; + end; +end; + +procedure tobjectinspectorfo.compselectorbeforedropdown( + const sender: TObject); +var + po1: pmoduleinfoty; + int1,int2: integer; + str1: msestring; +begin + with compselector,dropdown do begin + str1:= text; + cols.clear; + if factmodule <> nil then begin + int2:= -1; + po1:= designer.modules.findmodulebyinstance(factmodule); + if po1 <> nil then begin + fcomponentnames:= po1^.components.getdispnames; + cols[0].count:= po1^.components.count; + for int1:= 0 to cols[0].count-1 do begin + with fcomponentnames[int1] do begin + cols[0][int1]:= msestring(dispname) + ' (' + + msestring(designer.getclassname(instance))+')'; + if cols[0][int1] = str1 then begin + int2:= int1; + end; + end; + end; + itemindex:= int2; + end; + end; + text:= str1; + if editor.sellength > 0 then begin + editor.selectall; + end + else begin + editor.curindex:= length(str1); + end; + end; +end; + +procedure tobjectinspectorfo.updatecompselection; +var + comp1: tcomponent; +begin + comp1:= factcomp; + with compselector.dropdown do begin + if itemindex < 0 then begin + clear; + factcomp:= nil; + end + else begin + factcomp:= fcomponentnames[itemindex].instance; + end; + end; + if comp1 <> factcomp then begin + selectedcompchanged; + end; +end; + +procedure tobjectinspectorfo.compselectoronsetvalue(const sender: tobject; + var avalue: msestring; var accept: boolean); +begin + asyncevent(ado_compselection); +end; + +procedure tobjectinspectorfo.SelectionChanged(const ADesigner: IDesigner; + const ASelection: IDesignerSelections); +begin + saveproppath; + with aselection do begin + if count > 0 then begin + factcomp:= items[0]; + end + else begin + factcomp:= nil; + end; + factcomps:= getarray; + if count = 1 then begin + fsinglecomp:= true; + updatecomponentname; + readprops(factmodule,factcomp); + end + else begin + fsinglecomp:= false; + updatecomponentname; +// compselector.value:= ''; + readprops(factmodule,factcomps); + end; + inc(fchanging); + try + selectedcompchanged; + finally + dec(fchanging); + end; + end; +end; + +procedure tobjectinspectorfo.selectedcompchanged; +begin + if fchanging = 0 then begin + designer.selectcomponent(factcomp); + end; + compedit.enabled:= designer.componentcanedit; +end; + +procedure tobjectinspectorfo.saveproppath; +var + po1: pcompinfoty; +begin + if (factcomp <> nil) and (props.itemlist.count > 0) then begin + po1:= fcomponentinfos.getitem(factcomp); + po1^.proppathinfo.save(props.itemlist); + if props.item <> nil then begin + po1^.actprop:= props.item.rootcaptions; + end; + flastcomp:= factcomp; + end; +end; + +procedure tobjectinspectorfo.clear; +begin + saveproppath; + compselector.value:= ''; + grid.clear; +// values.itemlist.clear; + frereadprops:= false; +end; + +procedure tobjectinspectorfo.loaded; +begin + inherited; + clear; +end; + +procedure tobjectinspectorfo.propnotification(const sender: tlistitem; + var action: nodeactionty); +begin + with tpropertyitem(sender) do begin + case action of + na_expand: begin + feditor.expanded:= true; + if count = 0 then begin + add(editorstoprops(feditor.subproperties)); + end; + end; + na_collapse: begin + feditor.expanded:= false; + end; + end; + end; +end; + +procedure tobjectinspectorfo.gridcellevent(const sender: tobject; + var info: celleventinfoty); +begin + if isrowenter(info) then begin + values.itemlist.beginupdate; + try + with tpropertyvalue(values.item) do begin + if ps_valuelist in feditor.state then begin + values.dropdown.options:= values.dropdown.options - [deo_disabled]; + end + else begin + values.dropdown.options:= values.dropdown.options + [deo_disabled]; + end; + values.frame.buttons[1].visible:= ps_dialog in feditor.state; + end; + finally + values.itemlist.decupdate; + end; + tpropertyitem(props.item).feditor.focused(); +// tpropertyvalue(values[info.cellbefore.row]).updatestate(false); + end + else begin + if not frereadprops and isrowexit(info,true) and + (info.cellbefore.row < grid.rowcount) then begin + tpropertyvalue(values[info.cellbefore.row]).updatestate(true); + end; + end; +end; + +procedure tobjectinspectorfo.valuesbuttonaction(const sender: tobject; + var action: buttonactionty; const buttonindex: Integer); +begin + with titemedit(sender) do begin + if action = ba_click then begin + case buttonindex of + 1: begin + tpropertyvalue(item).feditor.edit; + end; + end; + end; + end; +end; + +procedure tobjectinspectorfo.valueskeydown(const sender: twidget; + var info: keyeventinfoty); +begin + if isenterkey(nil,info.key) and (info.shiftstate = []) and + not values.edited then begin + with tpropertyvalue(values.item),feditor do begin + if ps_dialog in state then begin + include(info.eventstate,es_processed); + edit; + end + else begin + feditor.valueeditor.navigevent(); + { + if (feditor is tmethodpropertyeditor) then begin + showmethodsource(tmethodpropertyeditor(feditor)); + end; + } + end; + end; + end; +end; + +procedure tobjectinspectorfo.valuesbeforedropdown(const sender: TObject); +begin + with tdropdownitemedit(sender) do begin + dropdown.cols.clear; + with tpropertyvalue(item).feditor do begin + if ps_sortlist in state then begin + dropdown.options:= dropdown.options + [deo_sorted]; + end + else begin + dropdown.options:= dropdown.options - [deo_sorted]; + end; + dropdown.cols[0].asarray:= getvalues; + end; + end; +end; + +procedure tobjectinspectorfo.propupdaterowvalue(const sender: TObject; + const aindex: Integer; const aitem: tlistitem); +begin + updatedefaultstate(aindex); +end; + +procedure tobjectinspectorfo.valueupdaterowvalue(const sender: tobject; + const aindex: integer; const aitem: tlistitem); +begin + if (aitem <> nil) and (tpropertyvalue(aitem).feditor <> nil) then begin + with tpropertyvalue(aitem).feditor do begin + if (aindex = values.activerow) or allequal then begin + aitem.caption:= removelinebreaks(getvalue); + end + else begin + aitem.caption:= ''; + end; + end; + end; +end; + +procedure tobjectinspectorfo.updatedefaultstate(const aindex: integer); +type + fontmarkty = (modified,iscomponent,issubproperty); + fontmarksty = set of fontmarkty; +var + mark: fontmarksty; +const + marktable: array[0..7] of integer = ( + //issubbroperty iscomponent modified + -1, // 0 0 0 + 0, // 0 0 1 + 3, // 0 1 0 + -1, // 0 1 1 invalid + 2, // 1 0 0 + 1, // 1 0 1 + 2, // 1 1 0 + -1 // 1 1 1 invalid + ); +begin + with tpropertyvalue(values[aindex]) do begin + if feditor <> nil then begin + mark:= []; + if ps_modified in feditor.state then begin + include(mark,modified); + end; + if ps_component in feditor.state then begin + include(mark,iscomponent); + end; + if ps_subprop in feditor.state then begin + include(mark,issubproperty); + end; + grid.rowfontstate[aindex]:= marktable[ + {$ifdef FPC}longword{$else}byte{$endif}(mark)]; + if feditor.sortlevel > 0 then begin + grid.rowcolorstate[aindex]:= 0; + end + else begin + grid.rowcolorstate[aindex]:= -1; + end; + end; + end; +end; + +procedure tobjectinspectorfo.componentnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const aitem: tcomponent; + const newname: string); +begin + if factcomp = aitem then begin + asyncevent(ado_updatecomponentname); + end; +end; + +procedure tobjectinspectorfo.moduleclassnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); +begin + if factcomp = amodule then begin + asyncevent(ado_updatecomponentname); + end; +end; + +procedure tobjectinspectorfo.instancevarnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); +begin + //dummy +end; + +procedure init; +begin + registerpropertyeditor(typeinfo(integer),nil,'',tordinalpropertyeditor); + registerpropertyeditor(typeinfo(longint),nil,'',tordinalpropertyeditor); + registerpropertyeditor(typeinfo(longword),nil,'',tordinalpropertyeditor); + registerpropertyeditor(typeinfo(word),nil,'',tordinalpropertyeditor); + registerpropertyeditor(typeinfo(byte),nil,'',tordinalpropertyeditor); + registerpropertyeditor(typeinfo(int64),nil,'',tint64propertyeditor); + registerpropertyeditor(typeinfo(uint64),nil,'',tint64propertyeditor); + registerpropertyeditor(typeinfo(currency),nil,'',tcurrencypropertyeditor); + registerpropertyeditor(typeinfo(real),nil,'',trealpropertyeditor); + registerpropertyeditor(typeinfo(double),nil,'',trealpropertyeditor); + registerpropertyeditor(typeinfo(realty),nil,'',trealtypropertyeditor); + registerpropertyeditor(typeinfo(tdatetime),nil,'',tdatetimepropertyeditor); + registerpropertyeditor(typeinfo(variant),nil,'',tvariantpropertyeditor); + registerpropertyeditor(typeinfo(char),nil,'',tcharpropertyeditor); + registerpropertyeditor(typeinfo(widechar),nil,'',twidecharpropertyeditor); + registerpropertyeditor(typeinfo(defaultenumerationty),nil,'',tenumpropertyeditor); + {$ifdef FPC} + registerpropertyeditor(typeinfo(boolean),nil,'',tbooleanpropertyeditor); //for fpc + {$endif} + registerpropertyeditor(typeinfo(string),nil,'',tstringpropertyeditor); + registerpropertyeditor(typeinfo(utf8string),nil,'',tutf8stringpropertyeditor); + registerpropertyeditor(typeinfo(string),tcomponent,'Name',tnamepropertyeditor); + registerpropertyeditor(typeinfo(msestring),nil,'',tmsestringpropertyeditor); + registerpropertyeditor(typeinfo(colorty),nil,'',tcolorpropertyeditor); +// registerpropertyeditor(typeinfo(msechar),nil,'',tmsestringpropertyeditor); + //??? + registerpropertyeditor({$ifdef FPC}tpersistent.classinfo{$else}typeinfo(tpersistent){$endif}, + nil,'',tclasspropertyeditor); + registerpropertyeditor(tparentfont.classinfo,nil,'',tparentfontpropertyeditor); + + registerpropertyeditor(tcomponent.classinfo,nil,'',tcomponentpropertyeditor); + registerpropertyeditor(typeinfo(defaultmethodty),nil,'',tmethodpropertyeditor); + registerpropertyeditor(typeinfo(defaultsetty),nil,'',tsetpropertyeditor); + registerpropertyeditor(tarrayprop.classinfo,nil,'',tarraypropertyeditor); + registerpropertyeditor(tpersistentarrayprop.classinfo,nil,'', + tpersistentarraypropertyeditor); + registerpropertyeditor(tintegerarrayprop.classinfo,nil,'', + tintegerarraypropertyeditor); + registerpropertyeditor(tsetarrayprop.classinfo,nil,'', + tsetarraypropertyeditor); + registerpropertyeditor(tcolorarrayprop.classinfo,nil,'', + tcolorarraypropertyeditor); + registerpropertyeditor(trealarrayprop.classinfo,nil,'', + trealarraypropertyeditor); + registerpropertyeditor(tstringarrayprop.classinfo,nil,'', + tstringarraypropertyeditor); + registerpropertyeditor(tmsestringarrayprop.classinfo,nil,'', + tmsestringarraypropertyeditor); + registerpropertyeditor(tmaskedbitmap.classinfo,nil,'',tbitmappropertyeditor); + registerpropertyeditor(tstrings.classinfo,nil,'',tstringspropertyeditor); + registerpropertyeditor(tmsestringdatalist.classinfo,nil,'', + tmsestringdatalistpropertyeditor); + registerpropertyeditor(tdoublemsestringdatalist.classinfo,nil,'', + tdoublemsestringdatalistpropertyeditor); + registerpropertyeditor(typeinfo(tmsestringintdatalist),nil,'', + tmsestringintdatalistpropertyeditor); + registerpropertyeditor(tdatalist.classinfo,nil,'',tdatalistpropertyeditor); +{ + info.editorclass:= timagelisteditor; + info.propertytype:= typeinfo(timagelist);//tobject.classinfo; + apropertyeditors.adddata(info); +} + registercomponenteditor(tcomponent,tcomponenteditor); + registercomponenteditor(timagelist,timagelisteditor); +end; + +procedure tobjectinspectorfo.compeditonexecute(const sender: tobject); +begin + designer.getcomponenteditor.edit; +end; + +function tobjectinspectorfo.candragsource(const apos: pointty; var row: integer): boolean; +var + widget1: twidget; + cell: gridcoordty; +begin + widget1:= grid.editwidgetatpos(apos,cell); + row:= cell.row; + if (widget1 = props) and (not values.edited or values.checkvalue) then begin + result:= props.candragsource(translateclientpoint(apos,grid,widget1)); + end + else begin + result:= false; + end; +end; + +function tobjectinspectorfo.candragdest(const apos: pointty; var row: integer): boolean; +var + widget1: twidget; + cell: gridcoordty; +begin + widget1:= grid.editwidgetatpos(apos,cell); + row:= cell.row; + result:= widget1 = props; +end; + +procedure tobjectinspectorfo.gridondragbegin(const sender: tobject; + const apos: pointty; var dragobject: tdragobject; var processed: boolean); +var + row: integer; + bo1: boolean; +begin + if candragsource(apos,row) then begin + bo1:= false; + tpropertyitem(props[row]).feditor.dragbegin(bo1); + if bo1 then begin + tobjectdragobject.create(sender,dragobject,nullpoint, + tpropertyitem(props[row]).feditor); + end; + end; +end; + +procedure tobjectinspectorfo.gridondragdrop(const sender: tobject; + const apos: pointty; var dragobject: tdragobject; var processed: boolean); +var + row: integer; +begin + if candragdest(apos,row) then begin + tpropertyitem(props[row]).feditor.dragdrop( + tpropertyeditor(tobjectdragobject(dragobject).data)); + grid.row:= row; + end; +end; + +procedure tobjectinspectorfo.gridondragover(const sender: tobject; + const apos: pointty; var dragobject: tdragobject; + var accept: boolean; var processed: boolean); +var + row: integer; +begin + if candragdest(apos,row) then begin + tpropertyitem(props[row]).feditor.dragover( + tpropertyeditor(tobjectdragobject(dragobject).data),accept); + end; +end; + +procedure tobjectinspectorfo.propsonpopup(const sender: tobject; + var amenu: tpopupmenu; var mouseinfo: mouseeventinfoty); +begin + tpropertyitem(props.item).feditor.dopopup(amenu,props,mouseinfo); +end; + +procedure tobjectinspectorfo.propskeydownexe(const sender: twidget; + var ainfo: keyeventinfoty); +begin + tpropertyitem(props.item).feditor.dokeydown(ainfo); +end; + +procedure tobjectinspectorfo.objectinspectorfoonloaded(const sender: tobject); +begin + grid.top:= compselector.bottom + 1; + grid.height:= height-grid.top; +// compedit.width:= compedit.height+6; +// compedit.left:= compedit.right - compedit.height-; + findbu.right:= compedit.left; + compselector.right:= findbu.left - 1; +// with values.frame.buttons[0] do begin +// imagelist:= stockobjects.glyphs; +// imagenr:= ord(stg_ellipsesmall); +// end; +end; + +procedure tobjectinspectorfo.methodcreated(const adesigner: idesigner; + const amodule: tmsecomponent; const aname: string; + const atype: ptypeinfo); +begin + //dummy +end; + +function tobjectinspectorfo.getmatchingmethods( + const sender: tpropertyeditor; atype: ptypeinfo): msestringarty; +var + ar1: componentarty; + int1,int2: integer; + mstr1: msestring; +begin + ar1:= designer.descendentinstancelist.getancestors(sender.module); + additem(pointerarty(ar1),sender.module); + result:= nil; + for int1:= 0 to high(ar1) do begin + stackarray(sourceupdater.getmatchingmethods(tmsecomponent(ar1[int1]),atype), + result); + end; + for int1:= 0 to high(result) do begin + mstr1:= struppercase(result[int1]); + for int2:= int1 + 1 to high(result) do begin + if msestringicompupper(result[int2],mstr1) = 0 then begin + result[int2]:= ''; + end; + end; + end; + result:= packarray(result); +end; + +procedure tobjectinspectorfo.methodnamechanged(const adesigner: idesigner; + const amodule: tmsecomponent; const newname, oldname: string; const atypeinfo: ptypeinfo); +begin + //dummy +end; + +procedure tobjectinspectorfo.showobjecttext(const adesigner: idesigner; + const afilename: filenamety; const backupcreated: boolean); +begin + //dummy +end; + +procedure tobjectinspectorfo.closeobjecttext(const adesigner: idesigner; + const afilename: filenamety; var cancel: boolean); +begin + //dummy +end; + +procedure tobjectinspectorfo.objectinspectoronchildscaled(const sender: TObject); +begin + placeyorder(0,[2],[compselector,grid]); + aligny(wam_center,[compselector,findbu,compedit]); +end; + +procedure tobjectinspectorfo.col0onshowhint(const sender: tdatacol; + const arow: Integer; var info: hintinfoty); +begin + if (props[arow] <> nil) and props[arow].captionclipped then begin + info.caption:= props[arow].caption; + end; +end; + +procedure tobjectinspectorfo.col1onshowhint(const sender: tdatacol; + const arow: Integer; var info: hintinfoty); +begin + if (values[arow] <> nil) and values[arow].captionclipped then begin + info.caption:= values[arow].caption; + end; +end; + +procedure tobjectinspectorfo.collapseexe(const sender: TObject); +var + int1: integer; +begin + for int1:= grid.rowhigh downto 0 do begin + props[int1].expanded:= false; + end; +end; + +procedure tobjectinspectorfo.beforemake(const adesigner: idesigner; + const maketag: integer; var abort: boolean); +begin + //dummy +end; + +procedure tobjectinspectorfo.aftermake(const adesigner: idesigner; + const exitcode: integer); +begin + //dummy +end; + +procedure tobjectinspectorfo.beforefilesave(const adesigner: idesigner; + const afilename: filenamety); +begin + //dummy +end; + +procedure tobjectinspectorfo.popupupdate(const sender: tcustommenu); +begin + with sender.menu.itembyname('revert') do begin + enabled:= (props.item <> nil) and (tpropertyitem(props.item).feditor <> nil) and + tpropertyitem(props.item).feditor.canrevert; + end; + sender.menu.itembyname('clearselect').enabled:= + grid.datacols[0].selectedcellcount > 0; +end; + +procedure tobjectinspectorfo.revertexe(const sender: TObject); +var + comp1: tcomponent; +begin + with tpropertyitem(props.item).feditor do begin + comp1:= designer.findancestorcomponent(component); + if comp1 <> nil then begin + copyproperty(comp1); + end; + end; +end; + +procedure tobjectinspectorfo.befdrawcell(const sender: tcol; + const canvas: tcanvas; var cellinfo: cellinfoty; + var processed: Boolean); +var + editor1: tpropertyeditor; +begin +exit; + editor1:= tpropertyitem(cellinfo.datapo^).feditor; + if (editor1 <> nil) and editor1.selected then begin + cellinfo.color:= selectcolor; + end; +end; + +procedure tobjectinspectorfo.clearselectedprops(const aprop: tpropertyitem); + //clears editor selction of all nodes which are no siblings + procedure doclear(const prop: tpropertyitem); + var + int1: integer; + begin + if (aprop = nil) or (prop.parent <> aprop.parent) then begin + prop.feditor.selected:= false; + end; + for int1:= 0 to prop.count-1 do begin + doclear(tpropertyitem(prop[int1])); + end; + end; +var + int1: integer; +begin + for int1:= 0 to grid.rowhigh do begin + if props[int1].parent = nil then begin + doclear(tpropertyitem(props[int1])); + end; + end; + grid.datacols[0].invalidate; +end; + +procedure tobjectinspectorfo.selchanged(const sender: tdatacol); +var + ar1: integerarty; + int1: integer; +begin + sender.grid.beginupdate; + ar1:= sender.selectedcells; + clearselectedprops(nil); + if props.item <> nil then begin + for int1:= 0 to high(ar1) do begin + tpropertyitem(props[ar1[int1]]).feditor.selected:= true; + end; + clearselectedprops(tpropertyitem(props.item)); + for int1:= 0 to high(ar1) do begin + if not tpropertyitem(props[ar1[int1]]).feditor.selected then begin + sender.selected[ar1[int1]]:= false; + end; + end; + end; + sender.grid.endupdate; +end; + +procedure tobjectinspectorfo.clearselect(const sender: TObject); +begin + grid.datacols[0].clearselection; +end; + +procedure tobjectinspectorfo.valuescellevent(const sender: TObject; + var info: celleventinfoty); +var + comp1: tcomponent; +begin + if iscellclick(info,[ccr_dblclick,ccr_nokeyreturn]) then begin + comp1:= tpropertyitem(props.item).feditor.linkcomponent; + if comp1 <> nil then begin + designer.showformdesigner(designer.modules.findmodulebycomponent(comp1)); + designer.selectcomponent(comp1); + end; + end; +end; + +procedure tobjectinspectorfo.asyncexe(const sender: TObject; var atag: Integer); +begin + case atag of + ado_compselection: begin + updatecompselection; + end; + end; +end; + +var + wascolorprop: boolean; + propcolor: colorty; + +function iscolorprop(const sender: twidget; const cellinfopo: pcellinfoty; + out acolor: colorty): boolean; + +var + propval: tpropertyvalue; +begin + if cellinfopo = nil then begin + propval:= tpropertyvalue(titemedit(sender).item); + end + else begin + pointer(propval):= ppointer(cellinfopo^.datapo)^; + end; + result:= (propval.feditor.typinfo = typeinfo(colorty)) and + propval.feditor.allequal; + if result then begin + acolor:= tpropertyeditor1(propval.feditor).getordvalue; + end; +end; + +procedure tobjectinspectorfo.paintimageexe(const sender: twidget; + const acanvas: tcanvas); +begin + if wascolorprop then begin + paintcolorimage(sender,acanvas,propcolor); + end; +end; + +procedure tobjectinspectorfo.extendimageexe(const sender: twidget; + const cellinfopo: pcellinfoty; var info: extrainfoty); +begin + wascolorprop:= iscolorprop(sender,cellinfopo,propcolor); + if wascolorprop then begin + info.image.cx:= info.image.cx+sender.clientheight; + end; +end; + +procedure tobjectinspectorfo.enterexe(const sender: TObject); +begin + mainfo.designformactivated(self); +end; + +initialization + init; +end. diff --git a/mseide-msegui/apps/ide/objectinspector_mfm.pas b/mseide-msegui/apps/ide/objectinspector_mfm.pas new file mode 100644 index 0000000..ba2a433 --- /dev/null +++ b/mseide-msegui/apps/ide/objectinspector_mfm.pas @@ -0,0 +1,457 @@ +unit objectinspector_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,objectinspector; + +const + objdata: record size: integer; data: array[0..8790] of byte end = + (size: 8791; data: ( + 84,80,70,48,18,116,111,98,106,101,99,116,105,110,115,112,101,99,116,111, + 114,102,111,17,111,98,106,101,99,116,105,110,115,112,101,99,116,111,114,102, + 111,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 97,114,114,111,119,102,111,99,117,115,11,111,119,95,115,117,98,102,111,99, + 117,115,13,111,119,95,109,111,117,115,101,119,104,101,101,108,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,9,111,119,95,104,105, + 110,116,111,110,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,15,102,114,97,109,101,46,103,114,105,112,95,115,105,122,101, + 2,10,18,102,114,97,109,101,46,103,114,105,112,95,111,112,116,105,111,110, + 115,11,14,103,111,95,99,108,111,115,101,98,117,116,116,111,110,16,103,111, + 95,102,105,120,115,105,122,101,98,117,116,116,111,110,14,103,111,95,102,108, + 111,97,116,98,117,116,116,111,110,12,103,111,95,116,111,112,98,117,116,116, + 111,110,19,103,111,95,98,97,99,107,103,114,111,117,110,100,98,117,116,116, + 111,110,15,103,111,95,110,111,108,111,99,107,98,117,116,116,111,110,14,103, + 111,95,98,117,116,116,111,110,104,105,110,116,115,0,9,112,111,112,117,112, + 109,101,110,117,7,9,109,97,105,110,112,111,112,117,112,7,111,110,101,110, + 116,101,114,7,8,101,110,116,101,114,101,120,101,10,111,110,97,99,116,105, + 118,97,116,101,7,8,101,110,116,101,114,101,120,101,7,118,105,115,105,98, + 108,101,8,8,98,111,117,110,100,115,95,120,3,185,0,8,98,111,117,110, + 100,115,95,121,3,104,1,9,98,111,117,110,100,115,95,99,120,3,254,0, + 9,98,111,117,110,100,115,95,99,121,3,248,0,26,99,111,110,116,97,105, + 110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,0,27,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,18,99,111,110,116,97,105,110, + 101,114,46,111,110,108,97,121,111,117,116,7,28,111,98,106,101,99,116,105, + 110,115,112,101,99,116,111,114,111,110,99,104,105,108,100,115,99,97,108,101, + 100,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2, + 0,2,0,3,244,0,3,248,0,0,22,100,114,97,103,100,111,99,107,46, + 115,112,108,105,116,116,101,114,95,115,105,122,101,2,0,16,100,114,97,103, + 100,111,99,107,46,99,97,112,116,105,111,110,6,15,79,98,106,101,99,116, + 105,110,115,112,101,99,116,111,114,20,100,114,97,103,100,111,99,107,46,111, + 112,116,105,111,110,115,100,111,99,107,11,10,111,100,95,115,97,118,101,112, + 111,115,13,111,100,95,115,97,118,101,122,111,114,100,101,114,10,111,100,95, + 99,97,110,109,111,118,101,11,111,100,95,99,97,110,102,108,111,97,116,10, + 111,100,95,99,97,110,100,111,99,107,11,111,100,95,112,114,111,112,115,105, + 122,101,14,111,100,95,99,97,112,116,105,111,110,104,105,110,116,13,111,100, + 95,99,104,105,108,100,105,99,111,110,115,0,7,111,112,116,105,111,110,115, + 11,10,102,111,95,115,97,118,101,112,111,115,13,102,111,95,115,97,118,101, + 122,111,114,100,101,114,12,102,111,95,115,97,118,101,115,116,97,116,101,0, + 8,115,116,97,116,102,105,108,101,7,22,109,97,105,110,102,111,46,112,114, + 111,106,101,99,116,115,116,97,116,102,105,108,101,7,99,97,112,116,105,111, + 110,6,16,79,98,106,101,99,116,32,73,110,115,112,101,99,116,111,114,21, + 105,99,111,110,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111, + 114,4,6,0,0,128,10,105,99,111,110,46,105,109,97,103,101,10,172,7, + 0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0,0,0,120,7, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,245,245,245,1,243,243, + 243,1,242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1,235,235, + 235,1,234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1,227,227, + 227,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219, + 219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211, + 211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242, + 242,1,240,240,240,1,217,238,240,1,174,238,243,1,142,237,245,1,158,236, + 242,1,197,233,236,1,230,230,230,1,229,229,229,1,227,227,227,1,226,226, + 226,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219,219,1,218,218, + 218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1,210,210, + 210,1,208,208,208,1,245,245,245,1,243,243,243,1,239,242,242,1,160,239, + 247,1,96,240,255,2,87,240,255,1,68,239,255,1,40,238,255,1,97,235, + 245,1,217,230,231,1,227,227,227,1,226,226,226,1,224,224,224,1,223,223, + 223,1,221,221,221,1,219,219,219,1,218,218,218,1,216,216,216,1,215,215, + 215,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245, + 245,1,243,243,243,1,155,241,249,1,116,241,255,1,138,241,255,1,144,242, + 255,1,131,241,255,1,106,240,255,1,72,239,255,1,34,238,255,1,56,221, + 234,1,225,226,226,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221, + 221,1,219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213, + 213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,207,243, + 246,1,112,241,255,1,150,242,255,1,181,243,255,1,191,243,255,1,172,242, + 255,1,136,241,255,1,96,240,255,1,54,239,255,1,13,238,255,1,85,173, + 180,1,221,221,221,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219, + 219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211, + 211,1,210,210,210,1,208,208,208,1,245,245,245,1,161,241,249,1,124,241, + 255,1,169,242,255,1,208,244,255,1,208,248,255,1,197,243,255,1,152,242, + 255,1,107,240,255,1,62,239,255,1,17,238,255,1,42,194,205,1,150,150, + 150,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219,219,1,218,218, + 218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1,210,210, + 210,1,208,208,208,1,245,245,245,1,132,240,251,1,119,241,255,1,162,242, + 255,1,200,243,255,1,208,245,255,1,187,243,255,1,147,242,255,1,104,240, + 255,1,59,239,255,1,15,238,255,1,29,214,228,1,102,102,102,1,212,212, + 212,1,223,223,223,1,221,221,221,1,219,219,219,1,211,211,219,1,216,216, + 216,1,215,215,215,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208, + 208,1,245,245,245,1,154,241,249,1,99,240,255,1,134,241,255,1,160,242, + 255,1,168,242,255,1,152,242,255,1,122,241,255,1,85,240,255,1,45,239, + 255,1,13,238,255,1,44,192,203,1,102,102,102,1,186,186,186,1,223,223, + 223,1,221,221,221,1,171,171,227,1,91,91,240,1,216,216,216,1,215,215, + 215,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245, + 245,1,204,242,245,1,71,239,255,1,97,240,255,1,115,241,255,1,120,241, + 255,1,110,240,255,1,87,240,255,1,57,239,255,1,22,238,255,1,13,238, + 255,1,70,151,157,1,102,102,102,1,188,188,188,1,223,223,223,1,221,221, + 221,1,55,55,247,1,7,7,254,1,154,154,193,1,214,214,214,1,213,213, + 213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243, + 243,1,135,240,249,1,54,239,255,1,69,239,255,1,72,239,255,1,65,239, + 255,1,47,239,255,1,22,238,255,1,13,238,255,1,41,197,209,1,102,102, + 102,2,213,213,213,1,223,223,223,1,154,154,232,1,4,4,255,2,36,36, + 208,1,171,171,171,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208, + 208,1,245,245,245,1,243,243,243,1,241,242,242,1,118,211,218,1,26,230, + 246,1,24,238,255,1,18,238,255,1,13,238,255,1,15,236,253,1,56,176, + 185,1,99,107,108,1,102,102,102,1,155,155,155,1,224,224,224,1,220,220, + 223,1,38,38,250,1,4,4,255,3,86,86,144,1,209,209,209,1,211,211, + 211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242, + 242,1,240,240,240,1,159,170,171,1,84,141,145,1,67,161,168,1,79,144, + 149,1,97,117,118,1,104,104,104,1,103,103,103,1,139,139,139,1,222,222, + 222,1,224,224,224,1,136,136,236,1,4,4,255,4,25,25,220,1,159,159, + 159,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243, + 243,1,242,242,242,1,240,240,240,1,238,238,238,1,207,207,207,1,150,150, + 150,1,124,124,124,1,118,118,118,1,143,143,143,1,186,186,186,1,227,227, + 227,1,226,226,226,1,214,214,225,1,26,26,252,1,4,4,255,5,72,72, + 153,1,203,203,203,1,210,210,210,1,208,208,208,1,245,245,245,1,247,155, + 167,1,249,121,137,1,248,120,136,1,247,119,135,1,246,118,134,1,245,117, + 133,2,244,116,132,1,243,115,131,1,234,186,192,1,227,227,227,1,226,226, + 226,1,116,116,239,1,4,4,255,6,17,17,231,1,145,145,149,1,210,210, + 210,1,208,208,208,1,245,245,245,1,252,68,91,1,255,0,32,8,239,143, + 155,1,227,227,227,1,207,207,229,1,15,15,253,1,4,4,255,7,60,60, + 163,1,196,196,196,1,208,208,208,1,245,245,245,1,252,68,91,1,255,0, + 32,8,160,64,76,1,118,118,118,1,97,97,243,1,4,4,255,8,13,13, + 241,1,130,130,142,1,208,208,208,1,245,245,245,1,252,68,91,1,255,0, + 32,8,160,64,76,1,117,117,120,1,120,120,240,1,114,114,240,1,65,65, + 191,1,52,52,178,1,51,51,177,2,50,50,176,3,49,49,175,1,79,79, + 124,1,187,187,187,1,245,245,245,1,252,68,91,1,255,0,32,8,160,64, + 76,1,118,118,118,1,226,226,226,1,184,184,184,1,101,101,101,1,100,100, + 100,1,99,99,99,1,98,98,98,1,97,97,97,2,96,96,96,1,95,95, + 95,2,125,125,125,1,245,245,245,1,252,68,91,1,255,0,32,8,160,64, + 76,1,118,118,118,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221, + 221,1,219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213, + 213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,252,68, + 91,1,255,0,32,8,160,64,76,1,118,118,118,1,226,226,226,1,224,224, + 224,1,223,223,223,1,221,221,221,1,219,219,219,1,218,218,218,1,216,216, + 216,1,215,215,215,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208, + 208,1,245,245,245,1,252,68,91,1,255,0,32,8,160,64,76,1,118,118, + 118,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219, + 219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211, + 211,1,210,210,210,1,208,208,208,1,245,245,245,1,252,68,91,1,255,0, + 32,8,160,64,76,1,118,118,118,1,226,226,226,1,224,224,224,1,223,223, + 223,1,221,221,221,1,219,219,219,1,218,218,218,1,216,216,216,1,215,215, + 215,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245, + 245,1,247,155,167,1,236,108,124,1,182,54,70,1,181,53,69,4,180,52, + 68,2,132,84,90,1,118,118,118,1,226,226,226,1,224,224,224,1,223,223, + 223,1,221,221,221,1,219,219,219,1,218,218,218,1,216,216,216,1,215,215, + 215,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245, + 245,1,243,243,243,1,217,217,217,1,108,108,108,1,107,107,107,2,106,106, + 106,2,105,105,105,1,104,104,104,1,103,103,103,1,118,118,118,1,226,226, + 226,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219,219,1,218,218, + 218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1,210,210, + 210,1,208,208,208,1,8,111,110,99,114,101,97,116,101,7,9,99,114,101, + 97,116,101,101,120,101,16,111,110,101,118,101,110,116,108,111,111,112,115,116, + 97,114,116,7,25,111,98,106,101,99,116,105,110,115,112,101,99,116,111,114, + 102,111,111,110,108,111,97,100,101,100,12,111,110,97,115,121,110,99,101,118, + 101,110,116,7,8,97,115,121,110,99,101,120,101,8,111,110,108,97,121,111, + 117,116,7,28,111,98,106,101,99,116,105,110,115,112,101,99,116,111,114,111, + 110,99,104,105,108,100,115,99,97,108,101,100,4,108,101,102,116,3,239,0, + 3,116,111,112,3,180,0,15,109,111,100,117,108,101,99,108,97,115,115,110, + 97,109,101,6,9,116,100,111,99,107,102,111,114,109,0,17,116,100,114,111, + 112,100,111,119,110,108,105,115,116,101,100,105,116,12,99,111,109,112,115,101, + 108,101,99,116,111,114,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119, + 95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,0,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,18,102,114,97,109,101,46,98, + 117,116,116,111,110,46,99,111,108,111,114,4,2,0,0,128,19,102,114,97, + 109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1,19,102, + 114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1, + 5,99,111,108,111,114,4,2,0,0,128,0,0,8,116,97,98,111,114,100, + 101,114,2,2,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110, + 100,115,95,121,2,1,9,98,111,117,110,100,115,95,99,120,3,171,0,9, + 98,111,117,110,100,115,95,99,121,2,22,7,97,110,99,104,111,114,115,11, + 7,97,110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114, + 105,103,104,116,0,10,111,110,115,101,116,118,97,108,117,101,7,22,99,111, + 109,112,115,101,108,101,99,116,111,114,111,110,115,101,116,118,97,108,117,101, + 16,100,114,111,112,100,111,119,110,46,111,112,116,105,111,110,115,11,14,100, + 101,111,95,115,101,108,101,99,116,111,110,108,121,16,100,101,111,95,97,117, + 116,111,100,114,111,112,100,111,119,110,15,100,101,111,95,107,101,121,100,114, + 111,112,100,111,119,110,0,19,100,114,111,112,100,111,119,110,46,99,111,108, + 115,46,99,111,117,110,116,2,1,19,100,114,111,112,100,111,119,110,46,99, + 111,108,115,46,105,116,101,109,115,14,1,0,0,16,111,110,98,101,102,111, + 114,101,100,114,111,112,100,111,119,110,7,26,99,111,109,112,115,101,108,101, + 99,116,111,114,98,101,102,111,114,101,100,114,111,112,100,111,119,110,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,11,116,119,105, + 100,103,101,116,103,114,105,100,4,103,114,105,100,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101, + 108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8, + 116,97,98,111,114,100,101,114,2,1,9,112,111,112,117,112,109,101,110,117, + 7,9,103,114,105,100,112,111,112,117,112,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,2,24,9,98,111,117,110,100,115, + 95,99,120,3,244,0,9,98,111,117,110,100,115,95,99,121,3,224,0,7, + 97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,9,97,110,95,98, + 111,116,116,111,109,0,11,111,112,116,105,111,110,115,103,114,105,100,11,12, + 111,103,95,99,111,108,115,105,122,105,110,103,12,111,103,95,99,111,108,109, + 111,118,105,110,103,20,111,103,95,99,111,108,99,104,97,110,103,101,111,110, + 116,97,98,107,101,121,10,111,103,95,119,114,97,112,99,111,108,0,12,111, + 112,116,105,111,110,115,103,114,105,100,49,11,17,111,103,49,95,110,111,114, + 101,115,101,116,115,101,108,101,99,116,0,15,114,111,119,99,111,108,111,114, + 115,46,99,111,117,110,116,2,1,15,114,111,119,99,111,108,111,114,115,46, + 105,116,101,109,115,1,4,242,255,255,0,0,14,114,111,119,102,111,110,116, + 115,46,99,111,117,110,116,2,6,14,114,111,119,102,111,110,116,115,46,105, + 116,101,109,115,14,1,4,110,97,109,101,6,11,115,116,102,95,100,101,102, + 97,117,108,116,6,120,115,99,97,108,101,2,1,10,108,111,99,97,108,112, + 114,111,112,115,11,10,102,108,112,95,120,115,99,97,108,101,0,0,1,5, + 99,111,108,111,114,4,0,128,0,0,4,110,97,109,101,6,11,115,116,102, + 95,100,101,102,97,117,108,116,6,120,115,99,97,108,101,2,1,10,108,111, + 99,97,108,112,114,111,112,115,11,9,102,108,112,95,99,111,108,111,114,10, + 102,108,112,95,120,115,99,97,108,101,0,0,1,5,99,111,108,111,114,4, + 0,128,0,0,4,110,97,109,101,6,11,115,116,102,95,100,101,102,97,117, + 108,116,6,120,115,99,97,108,101,2,1,10,108,111,99,97,108,112,114,111, + 112,115,11,9,102,108,112,95,99,111,108,111,114,10,102,108,112,95,120,115, + 99,97,108,101,0,0,1,5,99,111,108,111,114,4,13,0,0,160,4,110, + 97,109,101,6,11,115,116,102,95,100,101,102,97,117,108,116,6,120,115,99, + 97,108,101,2,1,10,108,111,99,97,108,112,114,111,112,115,11,9,102,108, + 112,95,99,111,108,111,114,10,102,108,112,95,120,115,99,97,108,101,0,0, + 1,5,115,116,121,108,101,11,7,102,115,95,98,111,108,100,0,4,110,97, + 109,101,6,11,115,116,102,95,100,101,102,97,117,108,116,6,120,115,99,97, + 108,101,2,1,10,108,111,99,97,108,112,114,111,112,115,11,9,102,108,112, + 95,115,116,121,108,101,10,102,108,112,95,120,115,99,97,108,101,0,0,1, + 5,115,116,121,108,101,11,7,102,115,95,98,111,108,100,0,4,110,97,109, + 101,6,11,115,116,102,95,100,101,102,97,117,108,116,6,120,115,99,97,108, + 101,2,1,10,108,111,99,97,108,112,114,111,112,115,11,9,102,108,112,95, + 115,116,121,108,101,10,102,108,112,95,120,115,99,97,108,101,0,0,0,14, + 100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,2,14,100,97,116, + 97,99,111,108,115,46,105,116,101,109,115,14,7,5,112,114,111,112,115,1, + 9,108,105,110,101,99,111,108,111,114,4,5,0,0,160,12,108,105,110,101, + 99,111,108,111,114,102,105,120,4,3,0,0,160,11,99,111,108,111,114,115, + 101,108,101,99,116,4,19,0,0,160,11,99,111,108,111,114,97,99,116,105, + 118,101,4,7,0,0,144,5,119,105,100,116,104,2,90,16,111,110,98,101, + 102,111,114,101,100,114,97,119,99,101,108,108,7,11,98,101,102,100,114,97, + 119,99,101,108,108,7,111,112,116,105,111,110,115,11,11,99,111,95,114,101, + 97,100,111,110,108,121,12,99,111,95,100,114,97,119,102,111,99,117,115,14, + 99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101, + 121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101, + 99,116,15,99,111,95,112,114,111,112,111,114,116,105,111,110,97,108,12,99, + 111,95,115,97,118,101,115,116,97,116,101,0,8,111,112,116,105,111,110,115, + 49,11,11,99,111,49,95,114,111,119,102,111,110,116,12,99,111,49,95,114, + 111,119,99,111,108,111,114,14,99,111,49,95,122,101,98,114,97,99,111,108, + 111,114,0,8,119,105,100,116,104,109,105,110,2,10,10,111,110,115,104,111, + 119,104,105,110,116,7,14,99,111,108,48,111,110,115,104,111,119,104,105,110, + 116,18,111,110,115,101,108,101,99,116,105,111,110,99,104,97,110,103,101,100, + 7,10,115,101,108,99,104,97,110,103,101,100,10,119,105,100,103,101,116,110, + 97,109,101,6,5,112,114,111,112,115,9,100,97,116,97,99,108,97,115,115, + 7,17,116,116,114,101,101,105,116,101,109,101,100,105,116,108,105,115,116,0, + 7,6,118,97,108,117,101,115,1,12,108,105,110,101,99,111,108,111,114,102, + 105,120,4,3,0,0,160,5,119,105,100,116,104,3,148,0,13,114,111,119, + 102,111,110,116,111,102,102,115,101,116,2,4,7,111,112,116,105,111,110,115, + 11,7,99,111,95,102,105,108,108,12,99,111,95,115,97,118,101,115,116,97, + 116,101,0,8,111,112,116,105,111,110,115,49,11,11,99,111,49,95,114,111, + 119,102,111,110,116,14,99,111,49,95,122,101,98,114,97,99,111,108,111,114, + 0,8,119,105,100,116,104,109,105,110,2,10,11,111,110,99,101,108,108,101, + 118,101,110,116,7,15,118,97,108,117,101,115,99,101,108,108,101,118,101,110, + 116,10,111,110,115,104,111,119,104,105,110,116,7,14,99,111,108,49,111,110, + 115,104,111,119,104,105,110,116,10,119,105,100,103,101,116,110,97,109,101,6, + 6,118,97,108,117,101,115,9,100,97,116,97,99,108,97,115,115,7,13,116, + 105,116,101,109,101,100,105,116,108,105,115,116,0,0,16,100,97,116,97,114, + 111,119,108,105,110,101,99,111,108,111,114,4,5,0,0,160,13,100,97,116, + 97,114,111,119,104,101,105,103,104,116,2,18,8,115,116,97,116,102,105,108, + 101,7,22,109,97,105,110,102,111,46,112,114,111,106,101,99,116,115,116,97, + 116,102,105,108,101,17,111,110,114,111,119,115,100,97,116,97,99,104,97,110, + 103,101,100,7,19,103,114,105,100,114,111,119,115,100,97,116,97,99,104,97, + 110,103,101,100,11,111,110,99,101,108,108,101,118,101,110,116,7,13,103,114, + 105,100,99,101,108,108,101,118,101,110,116,22,100,114,97,103,46,111,110,98, + 101,102,111,114,101,100,114,97,103,98,101,103,105,110,7,15,103,114,105,100, + 111,110,100,114,97,103,98,101,103,105,110,21,100,114,97,103,46,111,110,98, + 101,102,111,114,101,100,114,97,103,111,118,101,114,7,14,103,114,105,100,111, + 110,100,114,97,103,111,118,101,114,21,100,114,97,103,46,111,110,98,101,102, + 111,114,101,100,114,97,103,100,114,111,112,7,14,103,114,105,100,111,110,100, + 114,97,103,100,114,111,112,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,16,0,13,116,116,114,101,101,105,116,101,109,101,100,105,116,5,112, + 114,111,112,115,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11, + 14,111,119,49,95,97,117,116,111,104,101,105,103,104,116,0,13,111,112,116, + 105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101, + 102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119, + 95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119, + 102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117, + 115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,0,11,111,112,116,105,111,110,115,115,107,105,110,11,10,111,115,107, + 95,110,111,115,107,105,110,0,12,102,114,97,109,101,46,108,101,118,101,108, + 111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110, + 116,4,2,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95, + 99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101, + 114,2,1,7,111,110,112,111,112,117,112,7,12,112,114,111,112,115,111,110, + 112,111,112,117,112,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100, + 115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,120,2,90,9,98,111,117,110,100,115,95,99,121,2,18, + 12,111,112,116,105,111,110,115,101,100,105,116,49,11,0,11,111,112,116,105, + 111,110,115,101,100,105,116,11,11,111,101,95,114,101,97,100,111,110,108,121, + 12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111, + 115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97, + 110,99,101,108,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111, + 110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111, + 114,18,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116, + 9,111,101,95,108,111,99,97,116,101,0,9,111,110,107,101,121,100,111,119, + 110,7,15,112,114,111,112,115,107,101,121,100,111,119,110,101,120,101,17,111, + 110,117,112,100,97,116,101,114,111,119,118,97,108,117,101,115,7,18,112,114, + 111,112,117,112,100,97,116,101,114,111,119,118,97,108,117,101,7,111,112,116, + 105,111,110,115,11,16,116,101,111,95,116,114,101,101,99,111,108,110,97,118, + 105,103,16,116,101,111,95,107,101,121,114,111,119,109,111,118,105,110,103,0, + 14,111,110,99,104,101,99,107,114,111,119,109,111,118,101,7,19,112,114,111, + 112,115,111,110,99,104,101,99,107,114,111,119,109,111,118,101,0,0,17,116, + 100,114,111,112,100,111,119,110,105,116,101,109,101,100,105,116,6,118,97,108, + 117,101,115,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19, + 111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0, + 13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109, + 111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117, + 115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97, + 114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119, + 102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,0,5,99,111,108,111,114,4,7,0,0,144,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,2,0,0,128,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,119,105,100,116, + 104,2,15,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108, + 111,114,4,5,0,0,144,19,102,114,97,109,101,46,98,117,116,116,111,110, + 115,46,99,111,117,110,116,2,2,19,102,114,97,109,101,46,98,117,116,116, + 111,110,115,46,105,116,101,109,115,14,1,5,119,105,100,116,104,2,15,5, + 99,111,108,111,114,4,5,0,0,144,0,1,5,119,105,100,116,104,2,15, + 5,99,111,108,111,114,4,5,0,0,144,7,105,109,97,103,101,110,114,2, + 17,0,0,8,116,97,98,111,114,100,101,114,2,2,7,111,110,101,110,116, + 101,114,7,14,118,97,108,117,101,115,101,110,116,101,114,101,120,101,7,118, + 105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,91,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3, + 148,0,9,98,111,117,110,100,115,95,99,121,2,18,12,111,112,116,105,111, + 110,115,101,100,105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105, + 116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99, + 108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114, + 99,97,110,99,101,108,24,111,101,95,102,111,114,99,101,114,101,116,117,114, + 110,99,104,101,99,107,118,97,108,117,101,20,111,101,95,114,101,115,101,116, + 115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116, + 111,110,99,117,114,115,111,114,13,111,101,95,97,117,116,111,115,101,108,101, + 99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105, + 114,115,116,99,108,105,99,107,18,111,101,95,104,105,110,116,99,108,105,112, + 112,101,100,116,101,120,116,0,9,102,111,110,116,46,110,97,109,101,6,11, + 115,116,102,95,100,101,102,97,117,108,116,11,102,111,110,116,46,120,115,99, + 97,108,101,2,1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,108,112,95,120,115,99,97,108,101,0,9,111,110,107,101,121, + 100,111,119,110,7,13,118,97,108,117,101,115,107,101,121,100,111,119,110,18, + 111,110,99,108,105,101,110,116,109,111,117,115,101,101,118,101,110,116,7,18, + 118,97,108,117,101,115,111,110,109,111,117,115,101,101,118,101,110,116,10,111, + 110,115,101,116,118,97,108,117,101,7,14,118,97,108,117,101,115,115,101,116, + 118,97,108,117,101,12,111,110,112,97,105,110,116,105,109,97,103,101,7,13, + 112,97,105,110,116,105,109,97,103,101,101,120,101,13,111,110,101,120,116,101, + 110,100,105,109,97,103,101,7,14,101,120,116,101,110,100,105,109,97,103,101, + 101,120,101,14,111,110,98,117,116,116,111,110,97,99,116,105,111,110,7,18, + 118,97,108,117,101,115,98,117,116,116,111,110,97,99,116,105,111,110,17,111, + 110,117,112,100,97,116,101,114,111,119,118,97,108,117,101,115,7,19,118,97, + 108,117,101,117,112,100,97,116,101,114,111,119,118,97,108,117,101,16,100,114, + 111,112,100,111,119,110,46,111,112,116,105,111,110,115,11,16,100,101,111,95, + 97,117,116,111,100,114,111,112,100,111,119,110,15,100,101,111,95,107,101,121, + 100,114,111,112,100,111,119,110,12,100,101,111,95,99,108,105,112,104,105,110, + 116,0,25,100,114,111,112,100,111,119,110,46,100,114,111,112,100,111,119,110, + 114,111,119,99,111,117,110,116,2,16,19,100,114,111,112,100,111,119,110,46, + 99,111,108,115,46,99,111,117,110,116,2,1,19,100,114,111,112,100,111,119, + 110,46,99,111,108,115,46,105,116,101,109,115,14,1,0,0,16,111,110,98, + 101,102,111,114,101,100,114,111,112,100,111,119,110,7,20,118,97,108,117,101, + 115,98,101,102,111,114,101,100,114,111,112,100,111,119,110,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,16,0,0,0,11,116,114,105,99,104, + 98,117,116,116,111,110,8,99,111,109,112,101,100,105,116,14,111,112,116,105, + 111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116, + 103,108,121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111, + 115,99,97,108,101,13,111,119,49,95,97,117,116,111,119,105,100,116,104,0, + 13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109, + 111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117, + 115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97, + 114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119, + 102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,15,111,119,95,100,105,115,97,98,108,101,100,104,105, + 110,116,12,111,119,95,116,105,109,101,100,104,105,110,116,0,11,111,112,116, + 105,111,110,115,115,107,105,110,11,10,111,115,107,95,110,111,102,97,99,101, + 0,19,102,97,99,101,46,102,97,100,101,95,112,111,115,46,99,111,117,110, + 116,2,2,19,102,97,99,101,46,102,97,100,101,95,112,111,115,46,105,116, + 101,109,115,1,2,0,2,1,0,21,102,97,99,101,46,102,97,100,101,95, + 99,111,108,111,114,46,99,111,117,110,116,2,2,21,102,97,99,101,46,102, + 97,100,101,95,99,111,108,111,114,46,105,116,101,109,115,1,4,191,191,255, + 0,4,154,154,237,0,0,19,102,97,99,101,46,102,97,100,101,95,100,105, + 114,101,99,116,105,111,110,7,7,103,100,95,100,111,119,110,15,102,97,99, + 101,46,108,111,99,97,108,112,114,111,112,115,11,15,102,97,108,95,102,97, + 100,105,114,101,99,116,105,111,110,0,4,104,105,110,116,6,22,83,104,111, + 119,32,99,111,109,112,111,110,101,110,116,32,101,100,105,116,111,114,46,8, + 98,111,117,110,100,115,95,120,3,217,0,8,98,111,117,110,100,115,95,121, + 2,2,9,98,111,117,110,100,115,95,99,120,2,25,9,98,111,117,110,100, + 115,95,99,121,2,20,7,97,110,99,104,111,114,115,11,6,97,110,95,116, + 111,112,8,97,110,95,114,105,103,104,116,0,5,115,116,97,116,101,11,11, + 97,115,95,100,105,115,97,98,108,101,100,16,97,115,95,108,111,99,97,108, + 100,105,115,97,98,108,101,100,15,97,115,95,108,111,99,97,108,99,97,112, + 116,105,111,110,12,97,115,95,108,111,99,97,108,104,105,110,116,17,97,115, + 95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,23,102,97,99, + 101,100,105,115,97,98,108,101,100,46,108,111,99,97,108,112,114,111,112,115, + 11,0,21,102,97,99,101,100,105,115,97,98,108,101,100,46,116,101,109,112, + 108,97,116,101,7,29,103,117,105,116,101,109,112,108,97,116,101,115,109,111, + 46,102,97,100,101,118,101,114,116,107,111,110,118,101,120,7,99,97,112,116, + 105,111,110,6,3,38,69,68,9,111,110,101,120,101,99,117,116,101,7,17, + 99,111,109,112,101,100,105,116,111,110,101,120,101,99,117,116,101,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,17,116,115,116,111, + 99,107,103,108,121,112,104,98,117,116,116,111,110,6,102,105,110,100,98,117, + 14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49, + 95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,13,111,119,49, + 95,97,117,116,111,115,99,97,108,101,0,8,116,97,98,111,114,100,101,114, + 2,3,8,98,111,117,110,100,115,95,120,3,197,0,8,98,111,117,110,100, + 115,95,121,2,2,9,98,111,117,110,100,115,95,99,120,2,18,9,98,111, + 117,110,100,115,95,99,121,2,20,7,97,110,99,104,111,114,115,11,6,97, + 110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,5,115,116,97,116, + 101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97, + 115,95,108,111,99,97,108,105,109,97,103,101,108,105,115,116,15,97,115,95, + 108,111,99,97,108,105,109,97,103,101,110,114,0,5,103,108,121,112,104,7, + 16,115,116,103,95,101,108,108,105,112,115,101,115,109,97,108,108,6,97,99, + 116,105,111,110,7,24,97,99,116,105,111,110,115,109,111,46,102,105,110,100, + 99,111,109,112,97,108,108,97,99,116,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,16,0,0,10,116,112,111,112,117,112,109,101,110,117,9, + 103,114,105,100,112,111,112,117,112,8,111,110,117,112,100,97,116,101,7,11, + 112,111,112,117,112,117,112,100,97,116,101,18,109,101,110,117,46,115,117,98, + 109,101,110,117,46,99,111,117,110,116,2,3,18,109,101,110,117,46,115,117, + 98,109,101,110,117,46,105,116,101,109,115,14,1,7,99,97,112,116,105,111, + 110,6,13,67,111,108,108,97,112,115,101,32,116,114,101,101,5,115,116,97, + 116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17, + 97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111, + 110,101,120,101,99,117,116,101,7,11,99,111,108,108,97,112,115,101,101,120, + 101,0,1,7,99,97,112,116,105,111,110,6,19,82,101,118,101,114,116,32, + 116,111,32,105,110,104,101,114,105,116,101,100,4,110,97,109,101,6,6,114, + 101,118,101,114,116,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101, + 120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7,9,114, + 101,118,101,114,116,101,120,101,0,1,7,99,97,112,116,105,111,110,6,15, + 67,108,101,97,114,32,83,101,108,101,99,116,105,111,110,4,110,97,109,101, + 6,11,99,108,101,97,114,115,101,108,101,99,116,5,115,116,97,116,101,11, + 15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95, + 108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120, + 101,99,117,116,101,7,11,99,108,101,97,114,115,101,108,101,99,116,0,0, + 4,108,101,102,116,2,112,3,116,111,112,2,80,0,0,10,116,112,111,112, + 117,112,109,101,110,117,9,109,97,105,110,112,111,112,117,112,7,111,112,116, + 105,111,110,115,11,14,109,111,95,105,110,115,101,114,116,102,105,114,115,116, + 16,109,111,95,115,104,111,114,116,99,117,116,114,105,103,104,116,0,18,109, + 101,110,117,46,115,117,98,109,101,110,117,46,99,111,117,110,116,2,1,18, + 109,101,110,117,46,115,117,98,109,101,110,117,46,105,116,101,109,115,14,1, + 6,97,99,116,105,111,110,7,24,97,99,116,105,111,110,115,109,111,46,102, + 105,110,100,99,111,109,112,97,108,108,97,99,116,0,0,4,108,101,102,116, + 2,56,3,116,111,112,2,56,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tobjectinspectorfo,''); +end. diff --git a/mseide-msegui/apps/ide/panelform.mfm b/mseide-msegui/apps/ide/panelform.mfm new file mode 100644 index 0000000..87675c5 --- /dev/null +++ b/mseide-msegui/apps/ide/panelform.mfm @@ -0,0 +1,38 @@ +object panelfo: tpanelfo + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_hinton] + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_floatbutton, go_topbutton, go_backgroundbutton, go_lockbutton, go_nolockbutton, go_buttonhints] + onpaint = paintexe + visible = False + bounds_x = 157 + bounds_y = 493 + bounds_cx = 323 + bounds_cy = 195 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_mousetransparent] + container.frame.framei_left = 0 + container.frame.framei_top = 0 + container.frame.framei_right = 0 + container.frame.framei_bottom = 0 + container.frame.localprops = [frl_fileft, frl_fitop, frl_firight, frl_fibottom] + container.frame.localprops1 = [] + container.onpaint = paintexe + container.bounds = ( + 0 + 0 + 313 + 195 + ) + dragdock.tab_options = [tabo_dragsource, tabo_dragdest, tabo_hintclippedtext] + dragdock.tab_textflags = [tf_ycentered, tf_ellipseright] + dragdock.tab_widthmax = 100 + dragdock.caption = 'Mainwindow' + dragdock.optionsdock = [od_savepos, od_savezorder, od_canmove, od_canfloat, od_candock, od_acceptsdock, od_dockparent, od_splitvert, od_splithorz, od_tabed, od_proportional, od_propsize, od_captionhint] + dragdock.onlayoutchanged = panellayoutchanged + dragdock.oncaptionchanged = panellayoutchanged + options = [fo_savepos, fo_savezorder, fo_savestate] + statfile = mainfo.projectstatfile + onclose = onclo + moduleclassname = 'tdockform' +end diff --git a/mseide-msegui/apps/ide/panelform.pas b/mseide-msegui/apps/ide/panelform.pas new file mode 100644 index 0000000..ac3c908 --- /dev/null +++ b/mseide-msegui/apps/ide/panelform.pas @@ -0,0 +1,314 @@ +{ MSEide Copyright (c) 1999-2013 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit panelform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses,msegui,mseclasses,mseforms,msemenus,msestat, + msetypes{msestrings}, + msedock,msegraphutils,msegraphics,mseguiglob,msesimplewidgets,msewidgets, + msestringcontainer; + +type + + tpanelfo = class(tdockform) + procedure onclo(const sender: TObject); + procedure panellayoutchanged(const sender: tdockcontroller); + procedure paintexe(const sender: twidget; const acanvas: tcanvas); + private + fmenuitem: tmenuitem; + fnameindex: integer; //0 for unnumbered + procedure showexecute(const sender: tobject); + protected + procedure updatecaption(acaption: msestring); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function canclose(const newfocus: twidget): boolean; override; + end; + +function newpanel(aname: string = ''): tpanelfo; +procedure updatestat(const filer: tstatfiler); +procedure docktopanel(const controller: tdockcontroller; + const panelname: string; const arect: rectty); +procedure beginpanelplacement(); +procedure endpanelplacement(); + +implementation + +uses + panelform_mfm,main,sysutils,msekeyboard,mselist,msedatalist, + msearrayutils,mseformatstr; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +var + panellist: tpointerlist; + +procedure updatestat(const filer: tstatfiler); +var + ar1: msestringarty; + int1: integer; +begin + ar1:= nil; + if filer.iswriter then begin + setlength(ar1,panellist.count); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= msestring(tpanelfo(panellist[int1]).name); + end; + end; + filer.updatevalue('panels',ar1); + if not filer.iswriter then begin + for int1:= panellist.count - 1 downto 0 do begin + tpanelfo(panellist[int1]).free; + end; + for int1:= 0 to high(ar1) do begin + try + newpanel(ansistring(ar1[int1])); + except + end; + end; + end; +end; + +procedure docktopanel(const controller: tdockcontroller; + const panelname: string; const arect: rectty); +var + int1: integer; +begin + for int1:= 0 to panellist.count-1 do begin + with tpanelfo(panellist[int1]) do begin + if name = panelname then begin + dragdock.dock(controller,arect); + break; + end; + end; + end; +end; + +procedure beginpanelplacement(); +var + int1: integer; +begin + for int1:= 0 to panellist.count-1 do begin + with tpanelfo(panellist[int1]) do begin + dragdock.beginplacement(); + end; + end; +end; + +procedure endpanelplacement(); +var + int1: integer; +begin + for int1:= 0 to panellist.count-1 do begin + with tpanelfo(panellist[int1]) do begin + try + dragdock.endplacement(); + except + application.handleexception(); + end; + end; + end; +end; + +function newpanel(aname: string = ''): tpanelfo; +var + item1: tmenuitem; + int1,int2: integer; + ar1: integerarty; +begin + item1:= mainfo.mainmenu.menu.itembyname('view').itembyname('panels'); + if aname = '' then begin + setlength(ar1,panellist.count); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= tpanelfo(panellist[int1]).fnameindex; + end; + sortarray(ar1); + int2:= length(ar1); + for int1:= 0 to high(ar1) do begin //find first gap + if ar1[int1] <> int1 then begin + int2:= int1; + break; + end; + end; + end + else begin + int2:= strtoint(copy(aname,6,bigint))-1; + end; + result:= tpanelfo.create(mainfo); + int1:= int2 + 1; + if aname = '' then begin + aname:= 'panel'+inttostr(int1); + end; + with result do begin + name:= aname; + fnameindex:= int2; + fmenuitem:= tmenuitem.create(nil,nil); + updatecaption(''); + end; + if int2 > item1.count - 2 then begin + int2:= item1.count - 2; + end; + item1.submenu.insert(int2,result.fmenuitem); +end; + +{ tpanelfo } + +constructor tpanelfo.create(aowner: tcomponent); +begin + inherited create(aowner); + panellist.add(self); +end; + +destructor tpanelfo.destroy; +begin + if panellist <> nil then begin + panellist.remove(self); + end; + if not (csdestroying in mainfo.componentstate) then begin + fmenuitem.parentmenu.submenu.delete(fmenuitem.index); + end; + inherited; +end; + +procedure tpanelfo.updatecaption(acaption: msestring); + +begin + if acaption = '' then begin + acaption:= 'Panel'; + end; + if length(acaption) > 40 then begin + setlength(acaption,40); + acaption:= acaption+'...'; + end; + with fmenuitem do begin + onexecute:= {$ifdef FPC}@{$endif}showexecute; + if fnameindex < 9 then begin + shortcut:= (ord(key_f1) or key_modctrl) + fnameindex; + caption:= '&' + inttostrmse(fnameindex+1)+' '+acaption; + end + else begin + shortcut:= 0; + caption:= acaption; + end; + if shortcut <> 0 then begin + acaption:= acaption + ' (Ctrl+F' + inttostrmse(fnameindex+1)+')'; + end; + self.caption:= acaption; + end; +end; + +procedure tpanelfo.showexecute(const sender: tobject); +begin + activate; +end; + +function tpanelfo.canclose(const newfocus: twidget): boolean; + + function containerempty: boolean; + var + int1: integer; + begin + result:= container.widgetcount = 0; + if not result then begin + for int1:= 0 to container.widgetcount - 1 do begin + if container.widgets[int1].visible then begin + exit; + end; + end; + end; + result:= true; + end; + +begin + result:= inherited canclose(newfocus); + { + if result and (newfocus = nil) and containerempty then begin + release; + end; + } +end; + +procedure tpanelfo.onclo(const sender: TObject); + function containerempty: boolean; + var + int1: integer; + begin + result:= container.widgetcount = 0; + if not result then begin + for int1:= 0 to container.widgetcount - 1 do begin + if container.widgets[int1].visible then begin + exit; + end; + end; + end; + result:= true; + end; +begin + if containerempty then begin + release; + end; +end; + +procedure tpanelfo.panellayoutchanged(const sender: tdockcontroller); +var + intf1: idocktarget; + mstr1: msestring; + int1: integer; + ar1: widgetarty; +begin + mstr1:= ''; + ar1:= sender.getitems; + for int1:= 0 to high(ar1) do begin + if ar1[int1].getcorbainterface(typeinfo(idocktarget),intf1) then begin + mstr1:= mstr1 + intf1.getdockcontroller.getdockcaption+','; + end; + end; + if mstr1 <> '' then begin + setlength(mstr1,length(mstr1)-1); + end; + fdragdock.caption:= mstr1; + updatecaption(mstr1); +end; + +procedure tpanelfo.paintexe(const sender: twidget; const acanvas: tcanvas); +begin + paintdockingareacaption(acanvas,sender,mainfo.c[ord(dockingarea)]); +end; + +initialization + panellist:= tpointerlist.Create; +finalization + freeandnil(panellist); +end. diff --git a/mseide-msegui/apps/ide/panelform_mfm.pas b/mseide-msegui/apps/ide/panelform_mfm.pas new file mode 100644 index 0000000..aba635e --- /dev/null +++ b/mseide-msegui/apps/ide/panelform_mfm.pas @@ -0,0 +1,88 @@ +unit panelform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,panelform; + +const + objdata: record size: integer; data: array[0..1412] of byte end = + (size: 1413; data: ( + 84,80,70,48,8,116,112,97,110,101,108,102,111,7,112,97,110,101,108,102, + 111,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95, + 97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111, + 119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111,99,117, + 115,9,111,119,95,104,105,110,116,111,110,0,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,15,102,114,97,109,101,46,103,114, + 105,112,95,115,105,122,101,2,10,18,102,114,97,109,101,46,103,114,105,112, + 95,111,112,116,105,111,110,115,11,14,103,111,95,99,108,111,115,101,98,117, + 116,116,111,110,16,103,111,95,102,105,120,115,105,122,101,98,117,116,116,111, + 110,14,103,111,95,102,108,111,97,116,98,117,116,116,111,110,12,103,111,95, + 116,111,112,98,117,116,116,111,110,19,103,111,95,98,97,99,107,103,114,111, + 117,110,100,98,117,116,116,111,110,13,103,111,95,108,111,99,107,98,117,116, + 116,111,110,15,103,111,95,110,111,108,111,99,107,98,117,116,116,111,110,14, + 103,111,95,98,117,116,116,111,110,104,105,110,116,115,0,7,111,110,112,97, + 105,110,116,7,8,112,97,105,110,116,101,120,101,7,118,105,115,105,98,108, + 101,8,8,98,111,117,110,100,115,95,120,3,157,0,8,98,111,117,110,100, + 115,95,121,3,237,1,9,98,111,117,110,100,115,95,99,120,3,67,1,9, + 98,111,117,110,100,115,95,99,121,3,195,0,23,99,111,110,116,97,105,110, + 101,114,46,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119, + 95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111, + 99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119, + 95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114, + 111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111,99, + 117,115,19,111,119,95,109,111,117,115,101,116,114,97,110,115,112,97,114,101, + 110,116,0,27,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46, + 102,114,97,109,101,105,95,108,101,102,116,2,0,26,99,111,110,116,97,105, + 110,101,114,46,102,114,97,109,101,46,102,114,97,109,101,105,95,116,111,112, + 2,0,28,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,102, + 114,97,109,101,105,95,114,105,103,104,116,2,0,29,99,111,110,116,97,105, + 110,101,114,46,102,114,97,109,101,46,102,114,97,109,101,105,95,98,111,116, + 116,111,109,2,0,26,99,111,110,116,97,105,110,101,114,46,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,102,105, + 108,101,102,116,9,102,114,108,95,102,105,116,111,112,11,102,114,108,95,102, + 105,114,105,103,104,116,12,102,114,108,95,102,105,98,111,116,116,111,109,0, + 27,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,17,99,111,110,116,97,105,110,101,114, + 46,111,110,112,97,105,110,116,7,8,112,97,105,110,116,101,120,101,16,99, + 111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0, + 3,57,1,3,195,0,0,20,100,114,97,103,100,111,99,107,46,116,97,98, + 95,111,112,116,105,111,110,115,11,15,116,97,98,111,95,100,114,97,103,115, + 111,117,114,99,101,13,116,97,98,111,95,100,114,97,103,100,101,115,116,20, + 116,97,98,111,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116, + 0,22,100,114,97,103,100,111,99,107,46,116,97,98,95,116,101,120,116,102, + 108,97,103,115,11,12,116,102,95,121,99,101,110,116,101,114,101,100,15,116, + 102,95,101,108,108,105,112,115,101,114,105,103,104,116,0,21,100,114,97,103, + 100,111,99,107,46,116,97,98,95,119,105,100,116,104,109,97,120,2,100,16, + 100,114,97,103,100,111,99,107,46,99,97,112,116,105,111,110,6,10,77,97, + 105,110,119,105,110,100,111,119,20,100,114,97,103,100,111,99,107,46,111,112, + 116,105,111,110,115,100,111,99,107,11,10,111,100,95,115,97,118,101,112,111, + 115,13,111,100,95,115,97,118,101,122,111,114,100,101,114,10,111,100,95,99, + 97,110,109,111,118,101,11,111,100,95,99,97,110,102,108,111,97,116,10,111, + 100,95,99,97,110,100,111,99,107,14,111,100,95,97,99,99,101,112,116,115, + 100,111,99,107,13,111,100,95,100,111,99,107,112,97,114,101,110,116,12,111, + 100,95,115,112,108,105,116,118,101,114,116,12,111,100,95,115,112,108,105,116, + 104,111,114,122,8,111,100,95,116,97,98,101,100,15,111,100,95,112,114,111, + 112,111,114,116,105,111,110,97,108,11,111,100,95,112,114,111,112,115,105,122, + 101,14,111,100,95,99,97,112,116,105,111,110,104,105,110,116,0,24,100,114, + 97,103,100,111,99,107,46,111,110,108,97,121,111,117,116,99,104,97,110,103, + 101,100,7,18,112,97,110,101,108,108,97,121,111,117,116,99,104,97,110,103, + 101,100,25,100,114,97,103,100,111,99,107,46,111,110,99,97,112,116,105,111, + 110,99,104,97,110,103,101,100,7,18,112,97,110,101,108,108,97,121,111,117, + 116,99,104,97,110,103,101,100,7,111,112,116,105,111,110,115,11,10,102,111, + 95,115,97,118,101,112,111,115,13,102,111,95,115,97,118,101,122,111,114,100, + 101,114,12,102,111,95,115,97,118,101,115,116,97,116,101,0,8,115,116,97, + 116,102,105,108,101,7,22,109,97,105,110,102,111,46,112,114,111,106,101,99, + 116,115,116,97,116,102,105,108,101,7,111,110,99,108,111,115,101,7,5,111, + 110,99,108,111,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101, + 6,9,116,100,111,99,107,102,111,114,109,0,0) + ); + +initialization + registerobjectdata(@objdata,tpanelfo,''); +end. diff --git a/mseide-msegui/apps/ide/pascaldesignparser.pas b/mseide-msegui/apps/ide/pascaldesignparser.pas new file mode 100644 index 0000000..bbe55ea --- /dev/null +++ b/mseide-msegui/apps/ide/pascaldesignparser.pas @@ -0,0 +1,1504 @@ +{ MSEide Copyright (c) 1999-2018 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit pascaldesignparser; + +{$ifdef FPC}{$mode objfpc}{$h+}{$GOTO ON}{$endif} + +interface +uses + classes,mseparser,typinfo,msetypes,mselist,msestrings,mseclasses, + msedesignparser; + +type + + tpascaldesignparser = class(tpascalparser,idesignparser) + private + funitinfopo: punitinfoty; + fimplementation: boolean; + finterface: boolean; + finterfaceonly: boolean; + protected + function skipexpression: boolean; + procedure parsetype; + procedure parselabel; + procedure parseconst; + procedure parsevar; + function parseclasstype: boolean; + function parseinterfacetype: boolean; + function parserecord: boolean; + function parseobject: boolean; + function parseprocparams(var akind: methodkindty; + var aflags: methodflagsty; var params: paraminfoarty; + const acceptnameonly: boolean): boolean; + function parseclassprocedureheader(atoken: pascalidentty; + classinfopo: pclassinfoty; const managed: boolean): boolean; + function skipprocedureparams(atoken: pascalidentty): boolean; + function skipprocedureheader(atoken: pascalidentty): boolean; + procedure parseprocedurebody; + procedure parseimplementation; + public + constructor create(unitinfopo: punitinfoty; + const afilelist: tmseindexednamelist; + const getincludefile: getincludefileeventty; + const ainterfaceonly: boolean); overload; + constructor create(const afilelist: tmseindexednamelist; + const atext: string); overload; + procedure parse; override; + function dogetincludefile(const afilename: filenamety; + const astatementstart,astatementend: sourceposty): tscanner override; + function parseprocedureheader(atoken: pascalidentty; + procedureinfopo: pprocedureinfoty): boolean; + end; + +function findclassinfobyinstance(const ainstance: tmsecomponent; + const infopo: punitinfoty): pclassinfoty; +function isemptysourcepos(const apos: sourceposty): boolean; +function isinrowrange(const apos,startpos,endpos: sourceposty): boolean; +procedure parsepascaldef(const adef: pdefinfoty; out atext: string; + out scope: tdeflist); + +implementation +uses + sysutils,msedatalist,msefileutils,msedesigner,sourceupdate,msestream; +type + tdeflist1 = class(tdeflist); + tusesinfolist1 = class(tusesinfolist); + +procedure parsepascaldef(const adef: pdefinfoty; out atext: string; + out scope: tdeflist); +var + parser: tpascalparser; + + procedure doaddidents; + begin + with parser do begin + while checkoperator('^') do begin + end; + if checkident(ord(pid_array)) then begin + if checkoperator('[') then begin + findoperator(']'); + end; + checkident(ord(pid_of)); + while checkoperator('^') do begin + end; + end; + scope.addidentpath(parser,'.'); + end; + end; + + procedure parsecase; + var + ident1: pascalidentty; + int1: integer; + begin + with parser do begin + if not checkname then begin + exit; + end; + if checkoperator(':') then begin + if not checkname then begin + exit; + end; + end; + if pascalidentty(getident) <> pid_of then begin + exit; + end; + repeat + if not findoperator(':') then begin + exit; + end; + if not checkoperator('(') then begin + exit; + end; + while not checkoperator(')') and not eof do begin + if not getnameorident(int1) then begin + exit; + end; + ident1:= pascalidentty(int1); + if ident1 = pid_case then begin + parsecase; + end + else begin + skipnamelist; + if not checkoperator(':') then begin + exit; + end; + doaddidents; + end; + checkoperator(';'); + end; + checkoperator(';'); + until eof or testident(ord(pid_end)); + end; + end; + + procedure parsetypedef; + var + ident1: pascalidentty; + int1: integer; + begin + with parser do begin + while checkoperator('^') do begin + end; + ident1:= pascalidentty(getident); + case ident1 of + pid_case: begin + parsecase; + end; + pid_record: begin + repeat + if not getnameorident(int1) then begin + nexttoken; + break; + end; + ident1:= pascalidentty(int1); + if ident1 = pid_case then begin + parsecase; + end + else begin + skipnamelist; + if checkoperator(':') then begin + parsetypedef; + end + else begin + nexttoken; + break; + end; + end; + until eof or checkident(ord(pid_end)); + end; + else begin + lasttoken; + doaddidents; + end; + end; + checkoperator(';'); + end; + end; + +var + bo1: boolean; +begin + scope:= tdeflist.create(adef^.kind,false); + atext:= sourceupdater.getdefinfotext(adef); + if atext <> '' then begin + parser:= tpascalparser.create(designer.designfiles,atext); + try + with parser do begin + if adef^.kind in [syk_procdef,syk_classprocimp,syk_procimp] then begin + nextnonwhitetoken; //procedure or function + if adef^.kind = syk_classprocimp then begin + nextnonwhitetoken; //classname + nextnonwhitetoken; //dot + end; + nextnonwhitetoken; //procname + if checkoperator('(') then begin + repeat + while not eof and not checkoperator(':') do begin + nexttoken; + end; + doaddidents; + while not eof and not checkoperator(';') do begin + if checkoperator(')') then begin + break; + end; + nexttoken; + end; + until eof; + end; + if checkoperator(':') then begin + doaddidents; + end; + end + else begin +// ident1:= getident; + if skipnamenoident then begin + case adef^.kind of + syk_typedef: begin + if checkoperator('=') then begin + parsetypedef; + end; + end; + syk_vardef,syk_pardef: begin + bo1:= true; + while bo1 and checkoperator(',') do begin + bo1:= checknamenoident; + end; + if bo1 and checkoperator(':') then begin + doaddidents; + end; + end; + syk_classdef: begin + if checkoperator('=') and + (checkident([ord(pid_class),ord(pid_object)]) >= 0) and + checkoperator('(') then begin + scope.addidents(parser,',','.'); +// doaddidents; + end; + end; + syk_interfacedef: begin + if checkoperator('=') and checkident(ord(pid_interface)) + and checkoperator('(') then begin + scope.addidents(parser,#0,'.'); + end; + end; + end; + end; + end; + end; + finally + parser.Free; + end; + end; +end; + +function isemptysourcepos(const apos: sourceposty): boolean; +begin + with apos do begin + result:= (filenum = 0) {and (pos.col = 0) and (pos.row = 0)}; + end; +end; + +function isinrowrange(const apos,startpos,endpos: sourceposty): boolean; +begin +// result:= (apos.filenum = startpos.filenum) and (apos.filenum = endpos.filenum) and +// (apos.pos.row >= startpos.line) and (apos.pos.row <= endpos.line); + result:= (apos.line >= startpos.line) and (apos.line <= endpos.line); +end; + +function findclassinfobyinstance(const ainstance: tmsecomponent; const infopo: punitinfoty): pclassinfoty; +var + po1: pmoduleinfoty; +begin + result:= nil; + if infopo <> nil then begin + po1:= designer.modules.findmodule(ainstance); + if po1 <> nil then begin + result:= infopo^.p.classinfolist.finditembyname(po1^.moduleclassname,true); + end; + end; +end; + +{ tpascaldesignparser } + +constructor tpascaldesignparser.create(unitinfopo: punitinfoty; + const afilelist: tmseindexednamelist; + const getincludefile: getincludefileeventty; + const ainterfaceonly: boolean); +begin + finterfaceonly:= ainterfaceonly; + inherited create(afilelist); + funitinfopo:= unitinfopo; + funitinfopo^.interfacecompiled:= false; + funitinfopo^.implementationcompiled:= false; + ongetincludefile:= getincludefile; +end; + +constructor tpascaldesignparser.create(const afilelist: tmseindexednamelist; + const atext: string); +begin + fnoautoparse:= true; + inherited create(afilelist,atext); +end; + +function tpascaldesignparser.skipexpression: boolean; +var + bracketlevel: integer; + ch1: char; + str1: string; +begin + result:= true; + bracketlevel:= 0; + repeat + ch1:= getoperator; + case ch1 of + '(','[': inc(bracketlevel); + ')',']': dec(bracketlevel); + '*','/','+','-','^',',': begin + end; + else begin + if ch1 <> #0 then begin + lasttoken; //' for pascalstring + end; + if getvaluestring(str1) = vk_none then begin + if ch1 <> #0 then begin + break; //error + end + else begin + nexttoken; //was ident + end; + end; + end; + end; + until eof or (bracketlevel < 0); + if bracketlevel < 0 then begin + lasttoken; + end; +end; + +function tpascaldesignparser.parseprocparams(var akind: methodkindty; + var aflags: methodflagsty; + var params: paraminfoarty; + const acceptnameonly: boolean): boolean; +var + ar1: stringarty; + paraflags: tparamflags; + defaultstr: string; + apos,epos: sourceposty; + + procedure putparams(const atypename: string); + var + int1,int2: integer; + begin + int2:= length(params); + setlength(params,int2+length(ar1)); + for int1:= 0 to high(ar1) do begin + with params[int2] do begin + name:= ar1[int1]; + flags:= paraflags; + typename:= atypename; + defaultvalue:= defaultstr; + start:= apos; + stop:= epos; + end; + inc(int2); + end; + end; + +var + str1: string; + int1: integer; + po1: pchar; + +begin + ar1:= nil; //compiler warning + params:= nil; + result:= false; + if checkoperator(';') then begin + if not (akind in [mk_function,mk_classfunction]) or acceptnameonly then begin + result:= true; //no params + end; + end + else begin + if checkoperator('(') then begin + include(aflags,mef_brackets); + if checkoperator(')') then begin + apos:= sourcepos; + result:= true; //no params + end + else begin + while not eof do begin + defaultstr:= ''; + int1:= getident; + case pascalidentty(int1) of + pid_const: paraflags:= [pfconst]; + pid_var: paraflags:= [pfvar]; + pid_out: paraflags:= [pfout]; + else paraflags:= []; + end; + if (paraflags = []) and (int1 >= 0) then begin + break; + end; + apos:= sourcepos; + ar1:= lstringartostringar(getorignamelist); + if not checkoperator(':') then begin + epos:= sourcepos; + putparams(''); //untyped + end + else begin + if checkident(ord(pid_array)) then begin + include(paraflags,pfarray); + checkident(ord(pid_of)); + if checkident(ord(pid_const)) then begin + str1:= 'TVarRec'; + end + else begin + str1:= getorigname; + end; + end + else begin + str1:= getorigname; + end; + if str1 = '' then begin + break; + end; + if checkoperator('=') then begin + skipwhitespace; + po1:= fto^.value.po; + skipexpression; + defaultstr:= getorigtext(po1); + end; + epos:= sourcepos; + putparams(str1); + end; + if checkoperator(')') then begin + apos:= sourcepos; + result:= true; + break; + end; + if not checkoperator(';') then begin + break; + end; + end; + end; + end + else begin + apos:= sourcepos; + result:= true; + end; + if result then begin + if checkoperator(':') then begin + setlength(params,length(params)+1); + with params[high(params)] do begin + name:= 'result'; + flags:= [pfvar]; + typename:= getorigname; + start:= apos; + stop:= sourcepos; + end; + case akind of + mk_procedure: begin + akind:= mk_procedurefunc; + end; + mk_method: begin + akind:= mk_methodfunc; + end; + end; + end + else begin + if (akind in [mk_function,mk_classfunction]) then begin + result:= acceptnameonly; + end; + end; + end; + if result then begin + checkoperator(';'); + mark(); + if checkident(ord(pid_inline)) then begin + pop(); + checkoperator(';'); + end + else begin + back(); //after semicolon + end; + end; + end; +end; + +function tpascaldesignparser.parseprocedureheader(atoken: pascalidentty; + procedureinfopo: pprocedureinfoty): boolean; +begin +// result:= false; + with procedureinfopo^ do begin + intinsertpos:= lasttokenpos; + skipwhitespace; + intstartpos:= sourcepos; + case atoken of + pid_function: params.kind:= mk_function; + pid_method: params.kind:= mk_method; + pid_constructor: params.kind:= mk_constructor; + pid_destructor: params.kind:= mk_destructor; + else params.kind:= mk_procedure; + end; + name:= getorigname; + result:= not checkoperator('.'); //interface proc definition? + if result then begin + uppername:= uppercase(name); + result:= parseprocparams(params.kind,params.flags,params.params,false); + if result then begin + intendpos:= sourcepos; + end; + end; + end; +end; + +function tpascaldesignparser.parseclassprocedureheader(atoken: pascalidentty; + classinfopo: pclassinfoty; const managed: boolean): boolean; +var + po1: pprocedureinfoty; + token1: tokenidty; + pos1,pos2: sourceposty; + bo1: boolean; + int1: integer; +begin + result:= false; + bo1:= atoken = pid_class; + if bo1 then begin + if getident(int1) then begin + atoken:= pascalidentty(int1); + if not ((atoken = pid_function) or (atoken = pid_procedure) or + (atoken = pid_method)) then begin + lasttoken; + exit; + end; + end + else begin + exit; + end; + end; + with classinfopo^ do begin + po1:= procedurelist.newitem; + token1:= acttoken; + po1^.managed:= managed; + po1^.classproc:= bo1; + result:= parseprocedureheader(atoken,po1); + pos2:= sourcepos; + if result then begin + while true do begin + case pascalidentty(getclassident) of + pid_abstract: include(po1^.params.flags,mef_abstract); + pid_inherited: include(po1^.params.flags,mef_inherited); + pid_overload: include(po1^.params.flags,mef_overload); + pid_override: include(po1^.params.flags,mef_override); + pid_virtual: include(po1^.params.flags,mef_virtual); + pid_inline: begin end; //include(po1^.params.flags,mef_inline); + pid_invalid: break; + else + lasttoken; + break; + end; + if not checkoperator(';') then begin + break; + end; + end; + if isemptysourcepos(procedurestart) then begin + procedurestart:= po1^.intinsertpos; + end; + pos1:= getsourcepos(token1); + dec(pos1.offset,pos1.pos.col); + pos1.pos.col:= 0; + funitinfopo^.deflist.add(pos1,pos2,po1); + end + else begin + procedurelist.deletelast; + end; + end; +end; + +function tpascaldesignparser.skipprocedureparams(atoken: pascalidentty): boolean; +var + ar1: paraminfoarty; + flags1: methodflagsty; + kind1: methodkindty; +begin + case atoken of + pid_procedure,pid_method,pid_function: begin + kind1:= mk_procedure; + result:= parseprocparams(kind1,flags1,ar1,false); + end; + else begin + result:= false; + end; + end; +{ + case atoken of + pid_procedure,pid_method: begin + result:= parseprocparams(mk_procedure,flags1,ar1,false); + end; + pid_function: begin + result:= parseprocparams(mk_function,flags1,ar1,false); + end + else begin + result:= false; + end; + end; +} +end; + +function tpascaldesignparser.skipprocedureheader(atoken: pascalidentty): boolean; +var + lstr1: lstringty; +begin + if getnamenoident(lstr1) then begin + result:= skipprocedureparams(atoken); + end + else begin + result:= false; + end; +end; + +function tpascaldesignparser.parseinterfacetype: boolean; +var + value: lstringty; + ident1: pascalidentty; + intfinfopo: pinterfaceinfoty; +begin + result:= getorignamenoident(value) and checkoperator('=') and + checkident(integer(pid_interface)); + if result then begin + while not eof do begin + ident1:= pascalidentty(getident); + case ident1 of + pid_end: begin + intfinfopo:= funitinfopo^.p.interfacelist.newitem; + with intfinfopo^ do begin + name:= lstringtostring(value); + uppername:= uppercase(name); + end; + break; + end; + pid_implementation: begin + break; + end; + pid_procedure,pid_function,pid_method: begin + skipprocedureheader(ident1); + end; + else begin + nexttoken; + end; + end; + end; + end; +end; + +function tpascaldesignparser.parseclasstype: boolean; +var + value: lstringty; + ar1: lstringarty; + classinfopo: pclassinfoty; + pos1: sourceposty; + ident1: pascalidentty; + lstr2: lstringty; + pc,pc1: pcompinfoty; + pd: pdefinfoty; + bo1: boolean; + token1: tokenidty; + first: boolean; + int1: integer; + +begin + ar1:= nil; //compiler warning + token1:= acttoken; + result:= getorignamenoident(value) and checkoperator('=') and + (checkident([integer(pid_class),integer(pid_object)]) >= 0); + if result then begin + if checkoperator(';') then begin + lasttoken; //forward declaration + end + else begin + if checkident(integer(pid_of)) then begin + result:= checkname and checkoperator(';'); + if result then begin + funitinfopo^.deflist.add(lstringtostring(value),syk_typedef, + getsourcepos(token1),sourcepos); + end; + exit; + end; + classinfopo:= funitinfopo^.p.classinfolist.newitem; + with classinfopo^ do begin + inimplementation:= fimplementation; + managedstart:= lasttokenpos; + name:= lstringtostring(value); + uppername:= uppercase(name); + if checkoperator('(') then begin + ar1:= getnamelist; + result:= checkoperator(')'); + end + else begin + ar1:= nil; + end; + headerstop:= getsourcepos(acttoken); + if ar1 <> nil then begin + parentname:= lstringtostring(ar1[0]); + end + else begin + parentname:= 'TObject'; + end; + if result then begin + deflist:= funitinfopo^.deflist.beginnode(getsourcepos(token1),classinfopo); + first:= true; + while not eof do begin + ident1:= getclassident; + case ident1 of + pid_end,pid_private,pid_protected,pid_public,pid_published,pid_automated, + pid_implementation: begin + if isemptysourcepos(managedend) then begin + managedend:= lasttokenpos; + end; + if isemptysourcepos(procedurestart) then begin + procedurestart:= managedend; + end; + if (ident1 = pid_private) then begin + if isemptysourcepos(privatestart) then begin + privatestart:= sourcepos; + end; + end + else begin + if not isemptysourcepos(privatestart) and + isemptysourcepos(privateend) then begin + privateend:= lasttokenpos; + if isemptysourcepos(privatefieldend) then begin + privatefieldend:= privateend; + end; + end; + end; + if ident1 = pid_end then begin + break; + end; + end; + pid_class,pid_procedure,pid_method,pid_function, + pid_constructor,pid_destructor: begin + if isemptysourcepos(privatefieldend) and + not isemptysourcepos(privatestart) and + isemptysourcepos(privateend) then begin + privatefieldend:= lasttokenpos; + end; + parseclassprocedureheader(ident1,classinfopo, + isemptysourcepos(managedend)); + end; + else begin + pos1:= sourcepos; + ar1:= getorignamelist; + if high(ar1) >= 0 then begin + if isemptysourcepos(managedend) and (ident1 <> pid_property) then begin + pc:= componentlist.newitem; //managed component + bo1:= false; + with pc^ do begin + insertpos:= lasttokenpos; + namepos:= pos1; + nameend:= sourcepos; + if checkoperator(':') then begin + skipwhitespace; + typepos:= sourcepos; + if getorigname(lstr2) then begin + typeend:= sourcepos; + name:= lstringtostring(ar1[0]); + uppername:= uppercase(name); + typename:= lstringtostring(lstr2); + uppertypename:= uppercase(typename); + checkoperator(';'); + checknewline; + endpos:= sourcepos; + bo1:= true; + funitinfopo^.deflist.add(name,syk_vardef,namepos,endpos); + end; + end; + end; + if not bo1 then begin + componentlist.deletelast; + nexttoken; + end + else begin + for int1:= 1 to high(ar1) do begin + pc1:= componentlist.newitem; //managed component + pc1^:= pc^; + pc1^.name:= lstringtostring(ar1[int1]); + pc1^.uppername:= uppercase(pc1^.name); + end; + end; + end + else begin + if ident1 = pid_property then begin + if checkoperator('[') then begin + while not eof and not checkoperator(']') do begin + nexttoken; + end; + end; + end; + if checkoperator(':') then begin + while not eof and not checkoperator(';') do begin + nexttoken; + end; + pd:= funitinfopo^.deflist.add(lstringtostring(ar1[0]), + syk_vardef,pos1,sourcepos); + if ident1 = pid_property then begin + pd^.varflags:= [vf_property]; + end; + for int1:= 1 to high(ar1) do begin + funitinfopo^.deflist.add(lstringtostring(ar1[int1]), + syk_vardef,pos1,sourcepos) + end; + end; + end; + end + else begin + if first and (getoperator = ';') then begin + break; //xxx = class(tclassxx); + end; + nexttoken; + end; + end; + end; + first:= false; + end; + if result then begin + funitinfopo^.deflist.endnode(sourcepos); + end + else begin + funitinfopo^.deflist.deletenode; + end; + end; + end; + if not result then begin + funitinfopo^.p.classinfolist.deletelast; + end; + end; + end; +end; + +function tpascaldesignparser.parserecord: boolean; + //todo: parse subitems +var + ident1: pascalidentty; + blocklevel: integer; +begin + result:= true; + blocklevel:= 1; + while not eof and (blocklevel > 0) do begin + ident1:= pascalidentty(getident); + case ident1 of + pid_end: begin + dec(blocklevel) + end; + pid_begin,pid_record: begin + inc(blocklevel) + end; + end; + nexttoken; + end; +end; + +function tpascaldesignparser.parseobject: boolean; + //todo: parse subitems +var + ident1: pascalidentty; + blocklevel: integer; +begin + result:= true; + blocklevel:= 1; + while not eof and (blocklevel > 0) do begin + ident1:= pascalidentty(getident); + case ident1 of + pid_end: begin + dec(blocklevel); + nexttoken; + end; + pid_begin,pid_record: begin + inc(blocklevel); + nexttoken; + end; + pid_procedure,pid_method,pid_function: begin + skipprocedureheader(ident1); + end; + else begin + nexttoken; + end; + end; + end; +end; + +procedure tpascaldesignparser.parselabel; +var + ident1: pascalidentty; +begin + while not eof do begin + skipwhitespace; + ident1:= pascalidentty(getident); + case ident1 of + pid_type,pid_const,pid_var,pid_implementation,pid_function, + pid_procedure,pid_method, + pid_constructor,pid_destructor,pid_begin: begin + lasttoken; + break; + end; + pid_label: begin + end; + else begin + nexttoken; + end; + end; + end; +end; + +procedure tpascaldesignparser.parsetype; +var + statementstart: tokenidty; + ident1: pascalidentty; + lstr1: lstringty; +// bo1: boolean; +begin + while not eof do begin + skipwhitespace; + statementstart:= acttoken; + ident1:= pascalidentty(getident); + case ident1 of + pid_label,pid_const,pid_var,pid_implementation,pid_function, + pid_procedure,pid_method, + pid_constructor,pid_destructor,pid_begin: begin + lasttoken; + break; + end; + pid_type: begin + end; + else begin + if (ident1 = pid_invalid) and getorigname(lstr1) and + checkoperator('=') then begin + ident1:= pascalidentty(getident); + case ident1 of + pid_interface: begin + mark; + acttoken:= statementstart; + if parseinterfacetype then begin + pop; + funitinfopo^.deflist.add(lstringtostring(lstr1),syk_interfacedef, + getsourcepos(statementstart),sourcepos); + end + else begin + back; + end; + end; + pid_class,pid_object: begin + mark; + acttoken:= statementstart; + if parseclasstype then begin + pop; + end + else begin + back; + end; + end; + { + pid_object: begin + parseobject; + funitinfopo^.deflist.add(lstringtostring(lstr1),syk_typedef, + getsourcepos(statementstart),sourcepos); + end; + } + pid_record: begin + parserecord; + funitinfopo^.deflist.add(lstringtostring(lstr1),syk_typedef, + getsourcepos(statementstart),sourcepos); + end; + pid_procedure,pid_method,pid_function: begin + if skipprocedureparams(ident1) then begin + if checkident(ord(pid_of)) then begin + checkident(ord(pid_object)); + end; + checkoperator(';'); + funitinfopo^.deflist.add(lstringtostring(lstr1),syk_typedef, + getsourcepos(statementstart),sourcepos); + end; + end; + else begin + while not eof and not checkoperator(';') do begin + nexttoken; + end; + funitinfopo^.deflist.add(lstringtostring(lstr1),syk_typedef, + getsourcepos(statementstart),sourcepos); + end; + end; + end + else begin + nexttoken; //invalid + end; + end; + end; + end; +end; + +procedure tpascaldesignparser.parseconst; +var + ident1: integer; + apos: sourceposty; + str1: string; + +begin + while not eof do begin + ident1:= getident; + if ident1 >= 0 then begin + lasttoken; + break; + end; + if (fto^.kind = tk_name) then begin + apos:= sourcepos; + str1:= self.getorigtoken; + if checkoperator('=') then begin + //todo: parse typed constants + while not eof and not checkoperator(';') do begin + nexttoken; + end; + funitinfopo^.deflist.add(str1,syk_constdef,apos,sourcepos); + end + else begin + while not eof and not checkoperator(';') do begin + nexttoken; + end; + end; + end + else begin + nexttoken; + end; + end; +end; + +procedure tpascaldesignparser.parsevar; +var + ident1: integer; + apos: sourceposty; + ar1: lstringarty; + int1: integer; + +begin + ar1:= nil; //compiler warning + while not eof do begin + ident1:= getident; + if (ident1 >= 0) and (ident1 <> ord(pid_threadvar)) then begin + lasttoken; + break; + end; + if fto^.kind = tk_name then begin + apos:= sourcepos; + ar1:= getorignamelist; + if checkoperator(':') then begin + while not eof and not checkoperator(';') do begin + nexttoken; + end; + for int1:= 0 to high(ar1) do begin + funitinfopo^.deflist.add(lstringtostring(ar1[int1]),syk_vardef, + apos,sourcepos); + end; + end + else begin + while not eof and not checkoperator(';') do begin + nexttoken; + end; + end; + end + else begin + nexttoken; + end; + end; +end; + +procedure tpascaldesignparser.parseprocedurebody; + + procedure getidentinfo; + var + bracketlevel: integer; + pos1: sourceposty; + begin + funitinfopo^.deflist.actnode.startident(self); + while checkoperator('.') do begin + skipwhitespace; + if fto^.kind = tk_name then begin + funitinfopo^.deflist.actnode.addident(self); + end + else begin + funitinfopo^.deflist.actnode.addemptyident(self); + end; + end; + if checkoperator('(') then begin + mark; + bracketlevel:= 0; + while not eof and (bracketlevel >= 0) do begin + if checkoperator('(') then begin + inc(bracketlevel); + end + else begin + if checkoperator(')') then begin + dec(bracketlevel); + end + else begin + nexttoken; + end; + end; + end; + pos1:= sourcepos; + back; + funitinfopo^.deflist.actnode.endident(self,pos1); + end + else begin + skipwhitespace; + funitinfopo^.deflist.actnode.endident(self); + end; + end; + +var + blocklevel: integer; + aident: integer; + str1: string; + +begin + blocklevel:= 0; + while not eof and (blocklevel >= 0) do begin + if getident(aident) then begin + case pascalidentty(aident) of + pid_begin,pid_try,pid_case: begin + inc(blocklevel); + end; + pid_end: begin + dec(blocklevel); + end; + end; + end + else begin + if (fto^.kind = tk_name) then begin + getidentinfo; + end + else begin + if (fto^.kind = tk_operator) and (fto^.op = '''') and + getpascalstring(str1) then begin + + end + else begin + nexttoken; + end; + end; + end; + end; +end; + +procedure tpascaldesignparser.parseimplementation; + +var + procnestinglevel: integer; + + procedure parseprocedure(const akind: methodkindty); + var + classname,procname: lstringty; + po1: pclassinfoty; + po2: pprocedureinfoty; + po3: pdefinfoty; + methodinfo: methodparaminfoty; + aident: integer; + deflist1: tdeflist1; + + procedure setprocinfo(const ainfo: pprocedureinfoty); + var + lstr1: lstringty; + begin + with ainfo^ do begin + params:= methodinfo; + lstr1:= procname; + inc(lstr1.po,origoffset); + name:= lstringtostring(lstr1); + uppername:= lstringtostring(procname); + end; + end;//setprocinfo + var + pos1,pos2: sourceposty; + i1: int32; + isforward: boolean; + kind1: symbolkindty; + label + endlab; + begin + if procnestinglevel < 32 then begin + isforward:= false; + classname.po:= nil; + classname.len:= 0; + inc(procnestinglevel); + lasttoken; + pos1:= sourcepos; + nexttoken; + if getname(procname) then begin + if checkoperator('.') then begin + classname:= procname; + getname(procname); + po1:= funitinfopo^.p.classinfolist.finditembyname(classname,false); + if (po1 <> nil) and isemptysourcepos(po1^.procimpstart) then begin + po1^.procimpstart:= pos1; + end; + end + else begin + po1:= nil; + end; + methodinfo.kind:= akind; + methodinfo.flags:= []; + if parseprocparams(methodinfo.kind,methodinfo.flags, + methodinfo.params,classname.po <> nil) then begin + pos2:= sourcepos; + if po1 <> nil then begin //class or object + po2:= po1^.procedurelist.finditembyuppername(procname,methodinfo,true); + //can update methodinfo + if po2 = nil then begin + po2:= po1^.procedurelist.newitem; + setprocinfo(po2); + end; + po3:= funitinfopo^.deflist.beginnode( + lstringtostring(classname)+'.'+lstringtostring(procname)+ + mangleprocparams(methodinfo), + syk_classprocimp,pos1,sourcepos); + deflist1:= tdeflist1(po3^.deflist); +// if po2 <> nil then begin +// po2^.impheaderstartpos:= pos1; +// po2^.impheaderendpos:= sourcepos; +// end; + deflist1.fparentscope:= po1^.deflist; + end + else begin + if checkident(ord(pid_forward)) then begin + include(methodinfo.flags,mef_forward); + isforward:= true; + checkoperator(';'); + skipwhitespaceonly(); + pos2:= sourcepos; + end; + po2:= nil; + if not isforward then begin + po2:= funitinfopo^.p.procedurelist.finditembyuppername( + procname,methodinfo,false); + end; + if po2 = nil then begin + po2:= funitinfopo^.p.procedurelist.newitem; + setprocinfo(po2) + end; + kind1:= syk_procimp; + if isforward then begin + kind1:= syk_procdef; + end; + po3:= funitinfopo^.deflist.beginnode( + lstringtostring(procname)+mangleprocparams(methodinfo), + kind1,pos1,pos2); + deflist1:= tdeflist1(po3^.deflist); + po3^.procindex:= po2^.b.index; + po2:= nil; + end; + if po2 <> nil then begin + po3^.procindex:= po2^.b.index; + po2^.impheaderstartpos:= pos1; + po2^.impheaderendpos:= pos2; + end; + if not isforward then begin + for i1:= 0 to high(methodinfo.params) do begin + with methodinfo.params[i1] do begin + funitinfopo^.deflist.add(name,syk_pardef,start,stop); + end; + end; + end; + if isforward then begin + funitinfopo^.deflist.endnode(pos2); + goto endlab; + end; + while not eof do begin + if getident(aident) then begin + case pascalidentty(aident) of + pid_var: begin + parsevar; + end; + pid_const: begin + parseconst; + end; + pid_type: begin + parsetype; + end; + pid_label: begin + parselabel; + end; + pid_procedure,pid_method: begin + parseprocedure(mk_procedure); + end; + pid_function: begin + parseprocedure(mk_function); + end; + pid_begin: begin + parseprocedurebody; + break; + end; + else begin + break; + end; + end; + end + else begin + nexttoken; + end; + end; + checkoperator(';'); + checknewline; + pos1:= sourcepos; + funitinfopo^.deflist.endnode(pos1); + if po1 <> nil then begin + po1^.procimpend:= pos1; + if po2 <> nil then begin + po2^.impendpos:= po1^.procimpend; + end; + end; + end; + end; + endlab: + dec(procnestinglevel); + end; + end; + + procedure checkend; + begin + if isemptysourcepos(funitinfopo^.p.implementationend) then begin + lasttoken; + funitinfopo^.p.implementationend:= sourcepos; + nexttoken; + end; + end; + +var + aident: integer; + +begin + finterface:= false; + fimplementation:= true; + funitinfopo^.p.implementationstart:= sourcepos; + funitinfopo^.p.implementationbodystart:= funitinfopo^.p.implementationstart; + procnestinglevel:= 0; + while not eof do begin + if getident(aident) then begin; + case pascalidentty(aident) of + pid_procedure: begin + parseprocedure(mk_procedure); + end; + pid_method: begin + parseprocedure(mk_method); + end; + pid_function: begin + parseprocedure(mk_function); + end; + pid_constructor: begin + parseprocedure(mk_constructor); + end; + pid_destructor: begin + parseprocedure(mk_destructor); + end; + pid_type: begin + parsetype; + end; + pid_var: begin + parsevar; + end; + pid_uses: begin + with tusesinfolist1(funitinfopo^.p.implementationuses) do begin + fstartpos:= sourcepos; + add(getorignamelist); + fendpos:= sourcepos; + end; + checkoperator(';'); + checknewline; + funitinfopo^.p.implementationbodystart:= sourcepos; + end; + pid_begin: begin + if funitinfopo^.isprogram then begin + parseprocedurebody; + end; + end; + pid_initialization: begin + checkend; + funitinfopo^.p.initializationstart:= nexttokenornewlinepos; + end; + pid_finalization: begin + checkend; + funitinfopo^.p.finalizationstart:= nexttokenornewlinepos; + end; + pid_end: begin + if checkoperator('.') then begin + lasttoken; + checkend; + nexttoken; + break; + end; + end; + end; + end + else begin + nexttoken; + end; + end; + funitinfopo^.unitend:= sourcepos; + if isemptysourcepos(funitinfopo^.p.implementationend) then begin + lasttoken; + funitinfopo^.p.implementationend:= sourcepos; + end; +end; + +procedure tpascaldesignparser.parse; +var + int1: integer; + po1: pprocedureinfoty; + pos1: sourceposty; +begin + inherited parse; + if fnoautoparse then begin + exit; + end; + initcompinfo(funitinfopo^); + with funitinfopo^ do begin + int1:= getident; + isprogram:= pascalidentty(int1) = pid_program; + if isprogram or (pascalidentty(int1) = pid_unit) then begin + origunitname:= getorigname; + unitname:= uppercase(origunitname); + end; + if isprogram then begin + parseimplementation; + end + else begin + while not eof do begin + skipwhitespace; + pos1:= sourcepos; + int1:= getident; + case pascalidentty(int1) of + pid_type: begin + parsetype; + end; + pid_const: begin + parseconst; + end; + pid_var: begin + parsevar; + end; + pid_procedure,pid_method,pid_function: begin + po1:= p.procedurelist.newitem; + if parseprocedureheader(pascalidentty(int1),po1) then begin + deflist.add(pos1,sourcepos,po1); + end + else begin + p.procedurelist.deletelast; + end; + end; + pid_interface: begin + finterface:= true; + end; + pid_uses: begin + with tusesinfolist1(funitinfopo^.p.interfaceuses) do begin + fstartpos:= sourcepos; + add(getorignamelist); + fendpos:= sourcepos; + end; + end; + pid_implementation: begin + if not finterfaceonly then begin + parseimplementation; + end; + break; + end; + else begin + nexttoken; + end; + end; + end; + end; + afterparse(self,funitinfopo^,isprogram or not finterfaceonly); + end; +end; + +function tpascaldesignparser.dogetincludefile(const afilename: filenamety; + const astatementstart, astatementend: sourceposty): tscanner; +begin + result:= inherited dogetincludefile(afilename,astatementstart,astatementend); + if result <> nil then begin + addincludefile(funitinfopo^,afilename,astatementstart,astatementend); + end; +end; + +end. diff --git a/mseide-msegui/apps/ide/printform.mfm b/mseide-msegui/apps/ide/printform.mfm new file mode 100644 index 0000000..d10532c --- /dev/null +++ b/mseide-msegui/apps/ide/printform.mfm @@ -0,0 +1,252 @@ +object printfo: tprintfo + optionswidget = [ow_arrowfocus, ow_subfocus, ow_destroywidgets, ow_hinton] + visible = False + bounds_x = 166 + bounds_y = 216 + bounds_cx = 392 + bounds_cy = 281 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.bounds = ( + 0 + 0 + 392 + 281 + ) + options = [fo_screencentered, fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder, fo_savestate] + statfile = tstatfile1 + caption = 'Print File' + onidle = printidle + moduleclassname = 'tmseform' + object ok: tbutton + bounds_x = 264 + bounds_y = 232 + bounds_cx = 50 + bounds_cy = 22 + anchors = [an_top, an_right] + state = [as_default, as_localdefault, as_localcaption, as_localonexecute] + caption = '&Ok' + onexecute = runonexecute + end + object cancel: tbutton + taborder = 1 + bounds_x = 328 + bounds_y = 232 + bounds_cx = 50 + bounds_cy = 22 + anchors = [an_top, an_right] + state = [as_localcaption, as_localonexecute] + caption = 'Cancel' + onexecute = cancelexec + end + object linenum: tbooleanedit + frame.caption = 'Print line'#10'&numbers' + frame.dummy = 0 + frame.outerframe = ( + 0 + 8 + 58 + 9 + ) + taborder = 6 + bounds_x = 112 + bounds_y = 68 + bounds_cx = 71 + bounds_cy = 30 + statfile = tstatfile1 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + end + object fontsize: trealedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_destroywidgets] + frame.caption = 'Font &size (Pt)' + frame.dummy = 0 + frame.outerframe = ( + 0 + 17 + 16 + 0 + ) + taborder = 5 + bounds_x = 16 + bounds_y = 55 + bounds_cx = 84 + bounds_cy = 37 + statfile = tstatfile1 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + value = 35.2778 + valuedefault = -Inf + formatedit = '0.0' + formatdisp = '0.0' + valuerange = 0.28346438836889 + valuestart = 0 + min = 21.1667 + max = 49.3889 + reffontheight = 14 + end + object titlefont: tstringedit + frame.caption = '&Title font' + frame.dummy = 0 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 9 + bounds_x = 16 + bounds_y = 119 + bounds_cx = 361 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + statfile = tstatfile1 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + value = 'Helvetica' + onsetvalue = titlefosetvalue + reffontheight = 14 + end + object sourcefont: tstringedit + frame.caption = 'So&urce font' + frame.dummy = 0 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 10 + bounds_x = 16 + bounds_y = 167 + bounds_cx = 361 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + statfile = tstatfile1 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + value = 'Courier' + onsetvalue = sourcefosetvalue + reffontheight = 14 + end + object colorset: tbooleanedit + frame.caption = '&Color' + frame.dummy = 0 + frame.outerframe = ( + 0 + 1 + 35 + 2 + ) + taborder = 7 + bounds_x = 192 + bounds_y = 75 + bounds_cx = 48 + bounds_cy = 16 + statfile = tstatfile1 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + end + object tpagesizeselector1: tpagesizeselector + frame.caption = 'Paper size' + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 3 + bounds_x = 184 + bounds_y = 7 + bounds_cx = 79 + bounds_cy = 37 + anchors = [an_top, an_right] + dropdown.width = 180 + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + printer = printer + reffontheight = 14 + end + object tpageorientationselector1: tpageorientationselector + frame.caption = 'Paper orientation' + frame.outerframe = ( + 0 + 17 + 10 + 0 + ) + taborder = 4 + bounds_x = 275 + bounds_y = 7 + bounds_cx = 112 + bounds_cy = 37 + anchors = [an_top, an_right] + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + printer = printer + reffontheight = 14 + end + object rotate: tbooleanedit + frame.caption = 'Rotate CCW' + frame.dummy = 0 + frame.outerframe = ( + 0 + 1 + 76 + 2 + ) + taborder = 8 + bounds_x = 283 + bounds_y = 75 + bounds_cx = 89 + bounds_cy = 16 + statfile = tstatfile1 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + end + object pages: tstringedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_mousewheel, ow_destroywidgets] + frame.caption = 'Pages' + frame.dummy = 0 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + bounds_x = 16 + bounds_y = 7 + bounds_cx = 156 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + onsetvalue = pagessetvalue + reffontheight = 14 + end + object printer: tpostscriptprinter + canvas.font.color = -1610612734 + canvas.font.xscale = 1 + canvas.font.dummy = 0 + canvas.ppmm = 10 + onpagestart = pronpagestart + pa_width = 210 + pa_height = 297 + pa_size = sps_a4 + tabulators.defaultdist = 0 + statfile = tstatfile1 + printcommand = 'lp -' + left = 184 + top = 96 + end + object tstatfile1: tstatfile + filename = 'printer.sta' + options = [sfo_memory] + left = 80 + top = 112 + end + object c: tstringcontainer + strings.data = ( + 'Page' + 'Do you wish to cancel printing?' + ) + left = 80 + top = 216 + end +end diff --git a/mseide-msegui/apps/ide/printform.pas b/mseide-msegui/apps/ide/printform.pas new file mode 100644 index 0000000..e609296 --- /dev/null +++ b/mseide-msegui/apps/ide/printform.pas @@ -0,0 +1,178 @@ +unit printform; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msegui,mseclasses,mseforms,msesimplewidgets,msepostscriptprinter,mseprinter, + msedataedits,msethreadcomp,msegraphedits,msestrings,msegraphics,msestat, + msestatfile,msetypes,mseglob,msestringcontainer; + +type + tprintfo = class(tmseform) + ok: tbutton; + cancel: tbutton; + printer: tpostscriptprinter; + linenum: tbooleanedit; + fontsize: trealedit; + colorset: tbooleanedit; + rotate: tbooleanedit; + titlefont: tstringedit; + sourcefont: tstringedit; + tpageorientationselector1: tpageorientationselector; + tpagesizeselector1: tpagesizeselector; + tstatfile1: tstatfile; + pages: tstringedit; + c: tstringcontainer; + procedure pronpagestart(const sender: tcustomprinter); + procedure printidle(var again: Boolean); + procedure runonexecute(const sender: TObject); + procedure cancelexec(const sender: TObject); + procedure sourcefosetvalue(const sender: TObject; var avalue: msestring; + var accept: Boolean); + procedure titlefosetvalue(const sender: TObject; var avalue: msestring; + var accept: Boolean); + procedure pagessetvalue(const sender: TObject; var avalue: msestring; + var accept: Boolean); + protected + run,started: boolean; + rowindex: integer; + font1: tfont; + end; + +procedure print; + +implementation +uses + printform_mfm,main,sourceform,msestream,msesys,msegraphutils,msedrawtext, + msesettings,msereal,msewidgets,sysutils,projectoptionsform,mserichstring, + mseguiglob,mseformatstr; +type + stringconsts = ( + page, //0 Page + wishcancel //1 Do you wish to cancel printing? + ); + +procedure tprintfo.printidle(var again: Boolean); +begin + try + with printer,canvas do begin + if run then begin + if not started then begin + pagesstring:= self.pages.value; + started:= true; + beginprint(getprintcommand); + if colorset.value then begin + colorspace:= cos_rgb; + end + else begin + colorspace:= cos_gray; + end; + if rotate.value then begin + printorientation:= pao_landscape; + end + else begin + printorientation:= pao_portrait; + end; + font.name:= ansistring(sourcefont.value); + font.height:= round(fontsize.value); + headerheight:= round(fontsize.value*5/3); + if linenum.value then begin + indentx:= round(4*fontsize.value); + end; + font1.assign(font); + font1.name:= ansistring(titlefont.value); + end; + with sourcefo.activepage.edit do begin + if rowindex >= datalist.count then begin + run:= false; + self.window.modalresult:= mr_ok; + end + else begin + if linenum.value then begin + drawtext(inttostrmse(linenumber+1), + makerect(0,liney,round(3*fontsize.value),0),[tf_right],font1); + end; + writeln(expandtabs(richlines[rowindex],projectoptions.e.tabstops)); + inc(rowindex); + again:= true; + end; + end; + end; + end; + except + run:= false; + window.modalresult:= mr_exception; + raise; + end; +end; + +procedure print; +var + fo1: tprintfo; +begin + fo1:= tprintfo.create(nil); + fo1.font1:= tfont.create; + try + fo1.show(true); + finally + fo1.font1.free; + fo1.free; + end; +end; + +procedure tprintfo.pronpagestart(const sender: tcustomprinter); +begin + with sender.canvas do begin + save; + font.name:= ansistring(titlefont.value); + drawtext(sourcefo.activepage.filepath,makerect(0,0,clientsize.cx- + round(10*fontsize.value),0),[tf_ellipseleft]); + drawtext(c[ord(page)]+' '+inttostrmse(pagenumber+1), + makerect(clientsize.cx,0,0,0),[tf_right]); + restore; + end; +end; + +procedure tprintfo.runonexecute(const sender: TObject); +begin + if window.candefocus then begin + run:= true; + ok.enabled:= false; + end; +end; + +procedure tprintfo.cancelexec(const sender: TObject); +begin + if run then begin + if askyesno(c[ord(wishcancel)]) then begin + run:= false; + window.modalresult:= mr_cancel; + end; + end + else begin + window.modalresult:= mr_cancel; + end; +end; + +procedure tprintfo.sourcefosetvalue(const sender: TObject; var avalue: msestring; + var accept: Boolean); +begin + if avalue = '' then begin + avalue:= defaultsourceprintfont; + end; +end; + +procedure tprintfo.titlefosetvalue(const sender: TObject; var avalue: msestring; + var accept: Boolean); +begin + if avalue = '' then begin + avalue:= defaulttitleprintfont; + end; +end; + +procedure tprintfo.pagessetvalue(const sender: TObject; var avalue: msestring; + var accept: Boolean); +begin + stringtopages(avalue); +end; + +end. diff --git a/mseide-msegui/apps/ide/printform_mfm.pas b/mseide-msegui/apps/ide/printform_mfm.pas new file mode 100644 index 0000000..7486b92 --- /dev/null +++ b/mseide-msegui/apps/ide/printform_mfm.pas @@ -0,0 +1,246 @@ +unit printform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,printform; + +const + objdata: record size: integer; data: array[0..4560] of byte end = + (size: 4561; data: ( + 84,80,70,48,8,116,112,114,105,110,116,102,111,7,112,114,105,110,116,102, + 111,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 97,114,114,111,119,102,111,99,117,115,11,111,119,95,115,117,98,102,111,99, + 117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 9,111,119,95,104,105,110,116,111,110,0,7,118,105,115,105,98,108,101,8, + 8,98,111,117,110,100,115,95,120,3,166,0,8,98,111,117,110,100,115,95, + 121,3,216,0,9,98,111,117,110,100,115,95,99,120,3,136,1,9,98,111, + 117,110,100,115,95,99,121,3,25,1,23,99,111,110,116,97,105,110,101,114, + 46,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109, + 111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117, + 115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,11,111,119,95,115, + 117,98,102,111,99,117,115,19,111,119,95,109,111,117,115,101,116,114,97,110, + 115,112,97,114,101,110,116,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,0,16,99,111,110,116,97,105,110,101,114,46,98,111,117, + 110,100,115,1,2,0,2,0,3,136,1,3,25,1,0,7,111,112,116,105, + 111,110,115,11,17,102,111,95,115,99,114,101,101,110,99,101,110,116,101,114, + 101,100,13,102,111,95,99,108,111,115,101,111,110,101,115,99,15,102,111,95, + 97,117,116,111,114,101,97,100,115,116,97,116,16,102,111,95,97,117,116,111, + 119,114,105,116,101,115,116,97,116,10,102,111,95,115,97,118,101,112,111,115, + 13,102,111,95,115,97,118,101,122,111,114,100,101,114,12,102,111,95,115,97, + 118,101,115,116,97,116,101,0,8,115,116,97,116,102,105,108,101,7,10,116, + 115,116,97,116,102,105,108,101,49,7,99,97,112,116,105,111,110,6,10,80, + 114,105,110,116,32,70,105,108,101,6,111,110,105,100,108,101,7,9,112,114, + 105,110,116,105,100,108,101,15,109,111,100,117,108,101,99,108,97,115,115,110, + 97,109,101,6,8,116,109,115,101,102,111,114,109,0,7,116,98,117,116,116, + 111,110,2,111,107,8,98,111,117,110,100,115,95,120,3,8,1,8,98,111, + 117,110,100,115,95,121,3,232,0,9,98,111,117,110,100,115,95,99,120,2, + 50,9,98,111,117,110,100,115,95,99,121,2,22,7,97,110,99,104,111,114, + 115,11,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,5, + 115,116,97,116,101,11,10,97,115,95,100,101,102,97,117,108,116,15,97,115, + 95,108,111,99,97,108,100,101,102,97,117,108,116,15,97,115,95,108,111,99, + 97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110, + 101,120,101,99,117,116,101,0,7,99,97,112,116,105,111,110,6,3,38,79, + 107,9,111,110,101,120,101,99,117,116,101,7,12,114,117,110,111,110,101,120, + 101,99,117,116,101,0,0,7,116,98,117,116,116,111,110,6,99,97,110,99, + 101,108,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115, + 95,120,3,72,1,8,98,111,117,110,100,115,95,121,3,232,0,9,98,111, + 117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2, + 22,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,8,97,110, + 95,114,105,103,104,116,0,5,115,116,97,116,101,11,15,97,115,95,108,111, + 99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111, + 110,101,120,101,99,117,116,101,0,7,99,97,112,116,105,111,110,6,6,67, + 97,110,99,101,108,9,111,110,101,120,101,99,117,116,101,7,10,99,97,110, + 99,101,108,101,120,101,99,0,0,12,116,98,111,111,108,101,97,110,101,100, + 105,116,7,108,105,110,101,110,117,109,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,19,80,114,105,110,116,32,108,105,110,101,10,38,110,117, + 109,98,101,114,115,11,102,114,97,109,101,46,100,117,109,109,121,2,0,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2, + 8,2,58,2,9,0,8,116,97,98,111,114,100,101,114,2,6,8,98,111, + 117,110,100,115,95,120,2,112,8,98,111,117,110,100,115,95,121,2,68,9, + 98,111,117,110,100,115,95,99,120,2,71,9,98,111,117,110,100,115,95,99, + 121,2,30,8,115,116,97,116,102,105,108,101,7,10,116,115,116,97,116,102, + 105,108,101,49,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101, + 95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113, + 117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101, + 108,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101, + 115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101, + 120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110, + 101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25, + 111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116, + 99,108,105,99,107,0,0,0,9,116,114,101,97,108,101,100,105,116,8,102, + 111,110,116,115,105,122,101,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95, + 116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 0,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,15,70,111,110, + 116,32,38,115,105,122,101,32,40,80,116,41,11,102,114,97,109,101,46,100, + 117,109,109,121,2,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,17,2,16,2,0,0,8,116,97,98,111,114,100, + 101,114,2,5,8,98,111,117,110,100,115,95,120,2,16,8,98,111,117,110, + 100,115,95,121,2,55,9,98,111,117,110,100,115,95,99,120,2,84,9,98, + 111,117,110,100,115,95,99,121,2,37,8,115,116,97,116,102,105,108,101,7, + 10,116,115,116,97,116,102,105,108,101,49,11,111,112,116,105,111,110,115,101, + 100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101, + 95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107, + 109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117,114, + 110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120, + 105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111, + 101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111, + 115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116, + 111,110,102,105,114,115,116,99,108,105,99,107,0,5,118,97,108,117,101,5, + 242,176,80,107,154,119,28,141,4,64,12,118,97,108,117,101,100,101,102,97, + 117,108,116,5,0,0,0,0,0,0,0,128,255,255,10,102,111,114,109,97, + 116,101,100,105,116,6,3,48,46,48,10,102,111,114,109,97,116,100,105,115, + 112,6,3,48,46,48,10,118,97,108,117,101,114,97,110,103,101,5,16,82, + 3,64,139,62,34,145,253,63,10,118,97,108,117,101,115,116,97,114,116,2, + 0,3,109,105,110,5,215,18,242,65,207,102,85,169,3,64,3,109,97,120, + 5,121,88,168,53,205,59,142,197,4,64,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,0,11,116,115,116,114,105,110,103,101,100,105, + 116,9,116,105,116,108,101,102,111,110,116,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,11,38,84,105,116,108,101,32,102,111,110,116,11,102, + 114,97,109,101,46,100,117,109,109,121,2,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8, + 116,97,98,111,114,100,101,114,2,9,8,98,111,117,110,100,115,95,120,2, + 16,8,98,111,117,110,100,115,95,121,2,119,9,98,111,117,110,100,115,95, + 99,120,3,105,1,9,98,111,117,110,100,115,95,99,121,2,37,7,97,110, + 99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110,95,116,111, + 112,8,97,110,95,114,105,103,104,116,0,8,115,116,97,116,102,105,108,101, + 7,10,116,115,116,97,116,102,105,108,101,49,11,111,112,116,105,111,110,115, + 101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111, + 101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99, + 107,109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117, + 114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101, + 120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13, + 111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116, + 111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99, + 116,111,110,102,105,114,115,116,99,108,105,99,107,0,5,118,97,108,117,101, + 6,9,72,101,108,118,101,116,105,99,97,10,111,110,115,101,116,118,97,108, + 117,101,7,15,116,105,116,108,101,102,111,115,101,116,118,97,108,117,101,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,11,116,115, + 116,114,105,110,103,101,100,105,116,10,115,111,117,114,99,101,102,111,110,116, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,12,83,111,38,117, + 114,99,101,32,102,111,110,116,11,102,114,97,109,101,46,100,117,109,109,121, + 2,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,10, + 8,98,111,117,110,100,115,95,120,2,16,8,98,111,117,110,100,115,95,121, + 3,167,0,9,98,111,117,110,100,115,95,99,120,3,105,1,9,98,111,117, + 110,100,115,95,99,121,2,37,7,97,110,99,104,111,114,115,11,7,97,110, + 95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104, + 116,0,8,115,116,97,116,102,105,108,101,7,10,116,115,116,97,116,102,105, + 108,101,49,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95, + 117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117, + 101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108, + 12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115, + 101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120, + 105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101, + 110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111, + 101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99, + 108,105,99,107,0,5,118,97,108,117,101,6,7,67,111,117,114,105,101,114, + 10,111,110,115,101,116,118,97,108,117,101,7,16,115,111,117,114,99,101,102, + 111,115,101,116,118,97,108,117,101,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,14,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116, + 8,99,111,108,111,114,115,101,116,13,102,114,97,109,101,46,99,97,112,116, + 105,111,110,6,6,38,67,111,108,111,114,11,102,114,97,109,101,46,100,117, + 109,109,121,2,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,1,2,35,2,2,0,8,116,97,98,111,114,100,101, + 114,2,7,8,98,111,117,110,100,115,95,120,3,192,0,8,98,111,117,110, + 100,115,95,121,2,75,9,98,111,117,110,100,115,95,99,120,2,48,9,98, + 111,117,110,100,115,95,99,121,2,16,8,115,116,97,116,102,105,108,101,7, + 10,116,115,116,97,116,102,105,108,101,49,11,111,112,116,105,111,110,115,101, + 100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101, + 95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107, + 109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117,114, + 110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120, + 105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111, + 101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111, + 115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116, + 111,110,102,105,114,115,116,99,108,105,99,107,0,0,0,17,116,112,97,103, + 101,115,105,122,101,115,101,108,101,99,116,111,114,18,116,112,97,103,101,115, + 105,122,101,115,101,108,101,99,116,111,114,49,13,102,114,97,109,101,46,99, + 97,112,116,105,111,110,6,10,80,97,112,101,114,32,115,105,122,101,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17, + 2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117, + 110,100,115,95,120,3,184,0,8,98,111,117,110,100,115,95,121,2,7,9, + 98,111,117,110,100,115,95,99,120,2,79,9,98,111,117,110,100,115,95,99, + 121,2,37,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,8, + 97,110,95,114,105,103,104,116,0,14,100,114,111,112,100,111,119,110,46,119, + 105,100,116,104,3,180,0,19,100,114,111,112,100,111,119,110,46,99,111,108, + 115,46,99,111,117,110,116,2,1,19,100,114,111,112,100,111,119,110,46,99, + 111,108,115,46,105,116,101,109,115,14,1,0,0,7,112,114,105,110,116,101, + 114,7,7,112,114,105,110,116,101,114,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,14,0,0,24,116,112,97,103,101,111,114,105,101,110,116, + 97,116,105,111,110,115,101,108,101,99,116,111,114,25,116,112,97,103,101,111, + 114,105,101,110,116,97,116,105,111,110,115,101,108,101,99,116,111,114,49,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,17,80,97,112,101,114, + 32,111,114,105,101,110,116,97,116,105,111,110,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,10,2,0,0,8, + 116,97,98,111,114,100,101,114,2,4,8,98,111,117,110,100,115,95,120,3, + 19,1,8,98,111,117,110,100,115,95,121,2,7,9,98,111,117,110,100,115, + 95,99,120,2,112,9,98,111,117,110,100,115,95,99,121,2,37,7,97,110, + 99,104,111,114,115,11,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,0,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,99,111, + 117,110,116,2,1,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46, + 105,116,101,109,115,14,1,0,0,7,112,114,105,110,116,101,114,7,7,112, + 114,105,110,116,101,114,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,6,114,111, + 116,97,116,101,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,10, + 82,111,116,97,116,101,32,67,67,87,11,102,114,97,109,101,46,100,117,109, + 109,121,2,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109, + 101,1,2,0,2,1,2,76,2,2,0,8,116,97,98,111,114,100,101,114, + 2,8,8,98,111,117,110,100,115,95,120,3,27,1,8,98,111,117,110,100, + 115,95,121,2,75,9,98,111,117,110,100,115,95,99,120,2,89,9,98,111, + 117,110,100,115,95,99,121,2,16,8,115,116,97,116,102,105,108,101,7,10, + 116,115,116,97,116,102,105,108,101,49,11,111,112,116,105,111,110,115,101,100, + 105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95, + 99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109, + 114,99,97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117,114,110, + 20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105, + 116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101, + 95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115, + 101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111, + 110,102,105,114,115,116,99,108,105,99,107,0,0,0,11,116,115,116,114,105, + 110,103,101,100,105,116,5,112,97,103,101,115,13,111,112,116,105,111,110,115, + 119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117, + 115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114, + 111,119,102,111,99,117,115,13,111,119,95,109,111,117,115,101,119,104,101,101, + 108,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,5,80,97,103,101, + 115,11,102,114,97,109,101,46,100,117,109,109,121,2,0,16,102,114,97,109, + 101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2, + 0,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115, + 95,120,2,16,8,98,111,117,110,100,115,95,121,2,7,9,98,111,117,110, + 100,115,95,99,120,3,156,0,9,98,111,117,110,100,115,95,99,121,2,37, + 7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110, + 95,116,111,112,8,97,110,95,114,105,103,104,116,0,10,111,110,115,101,116, + 118,97,108,117,101,7,13,112,97,103,101,115,115,101,116,118,97,108,117,101, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,18,116, + 112,111,115,116,115,99,114,105,112,116,112,114,105,110,116,101,114,7,112,114, + 105,110,116,101,114,17,99,97,110,118,97,115,46,102,111,110,116,46,99,111, + 108,111,114,4,2,0,0,160,18,99,97,110,118,97,115,46,102,111,110,116, + 46,120,115,99,97,108,101,2,1,17,99,97,110,118,97,115,46,102,111,110, + 116,46,100,117,109,109,121,2,0,11,99,97,110,118,97,115,46,112,112,109, + 109,2,10,11,111,110,112,97,103,101,115,116,97,114,116,7,13,112,114,111, + 110,112,97,103,101,115,116,97,114,116,8,112,97,95,119,105,100,116,104,3, + 210,0,9,112,97,95,104,101,105,103,104,116,3,41,1,7,112,97,95,115, + 105,122,101,7,6,115,112,115,95,97,52,22,116,97,98,117,108,97,116,111, + 114,115,46,100,101,102,97,117,108,116,100,105,115,116,2,0,8,115,116,97, + 116,102,105,108,101,7,10,116,115,116,97,116,102,105,108,101,49,12,112,114, + 105,110,116,99,111,109,109,97,110,100,6,4,108,112,32,45,4,108,101,102, + 116,3,184,0,3,116,111,112,2,96,0,0,9,116,115,116,97,116,102,105, + 108,101,10,116,115,116,97,116,102,105,108,101,49,8,102,105,108,101,110,97, + 109,101,6,11,112,114,105,110,116,101,114,46,115,116,97,7,111,112,116,105, + 111,110,115,11,10,115,102,111,95,109,101,109,111,114,121,0,4,108,101,102, + 116,2,80,3,116,111,112,2,112,0,0,16,116,115,116,114,105,110,103,99, + 111,110,116,97,105,110,101,114,1,99,12,115,116,114,105,110,103,115,46,100, + 97,116,97,1,6,4,80,97,103,101,6,31,68,111,32,121,111,117,32,119, + 105,115,104,32,116,111,32,99,97,110,99,101,108,32,112,114,105,110,116,105, + 110,103,63,0,4,108,101,102,116,2,80,3,116,111,112,3,216,0,0,0, + 0) + ); + +initialization + registerobjectdata(@objdata,tprintfo,''); +end. diff --git a/mseide-msegui/apps/ide/programparametersform.mfm b/mseide-msegui/apps/ide/programparametersform.mfm new file mode 100644 index 0000000..8d146bf --- /dev/null +++ b/mseide-msegui/apps/ide/programparametersform.mfm @@ -0,0 +1,230 @@ +object programparametersfo: tprogramparametersfo + visible = False + bounds_x = 272 + bounds_y = 243 + bounds_cx = 328 + bounds_cy = 348 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 328 + 348 + ) + options = [fo_closeonesc, fo_localshortcuts, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder] + statfile = statfile1 + caption = 'Target Environment' + windowopacity = -Inf + moduleclassname = 'tmseform' + object workingdirectory: tfilenameedit + frame.caption = '&Working directory' + frame.captiontextflags = [tf_bottom] + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + onshowhint = hintexpandedmacros + bounds_x = 2 + bounds_y = 9 + bounds_cx = 324 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + controller.options = [fdo_directory] + controller.captionopen = 'Select program working directory' + controller.ongetfilename = expandfilename + reffontheight = 14 + end + object ok: tbutton + taborder = 4 + bounds_x = 216 + bounds_y = 320 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_default, as_localdefault, as_localcaption] + caption = 'OK' + modalresult = mr_ok + end + object tbutton2: tbutton + bounds_x = 272 + bounds_y = 320 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_localcaption] + caption = 'Cancel' + modalresult = mr_cancel + end + object parameters: tmemodialoghistoryedit + frame.caption = '&Parameters' + frame.captiontextflags = [tf_bottom] + frame.localprops = [] + frame.localprops1 = [] + frame.button.color = -2147483646 + frame.buttons.count = 2 + frame.buttons.items = < + item + color = -2147483646 + end + item + color = -2147483646 + imagenr = 17 + end> + frame.buttondialog.color = -2147483646 + frame.buttondialog.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + onshowhint = hintexpandedmacros + bounds_x = 2 + bounds_y = 57 + bounds_cx = 324 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + dropdown.options = [deo_keydropdown, deo_autosavehistory, deo_cliphint] + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + reffontheight = 14 + end + object grid: twidgetgrid + frame.caption = 'Environment variables' + frame.captiontextflags = [tf_bottom] + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 3 + bounds_x = 2 + bounds_y = 111 + bounds_cx = 324 + bounds_cy = 195 + anchors = [an_left, an_top, an_right, an_bottom] + optionsgrid = [og_colsizing, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_savestate, og_colchangeontabkey, og_wrapcol, og_autopopup] + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 3 + captions.items = < + item + caption = 'on' + end + item + caption = 'Name' + end + item + caption = 'Value' + end> + end> + datacols.count = 3 + datacols.options = [co_savestate] + datacols.items = < + item[envvaron] + width = 20 + options = [co_drawfocus, co_savestate] + widgetname = 'envvaron' + dataclass = tgridintegerdatalist + end + item[envvarname] + width = 103 + options = [co_proportional, co_savestate] + widgetname = 'envvarname' + dataclass = tgridmsestringdatalist + end + item[envvarvalue] + width = 194 + options = [co_fill, co_savestate] + widgetname = 'envvarvalue' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + statfile = statfile1 + reffontheight = 14 + object envvaron: tbooleanedit + optionswidget1 = [] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 20 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object envvarname: tstringedit + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 2 + visible = False + bounds_x = 21 + bounds_y = 0 + bounds_cx = 103 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext] + reffontheight = 14 + end + object envvarvalue: tmemodialogedit + optionswidget1 = [ow1_fontglyphheight] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + taborder = 3 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 125 + bounds_y = 0 + bounds_cx = 194 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext] + reffontheight = 14 + end + end + object statfile1: tstatfile + filename = 'programparametersfo.sta' + options = [sfo_memory] + left = 176 + top = 96 + end +end diff --git a/mseide-msegui/apps/ide/programparametersform.pas b/mseide-msegui/apps/ide/programparametersform.pas new file mode 100644 index 0000000..d88305d --- /dev/null +++ b/mseide-msegui/apps/ide/programparametersform.pas @@ -0,0 +1,123 @@ +{ MSEide Copyright (c) 1999-2010 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit programparametersform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseforms,msestat,mseglob,msestatfile,msesimplewidgets,msedataedits,msefiledialog, + msewidgetgrid,msegraphedits,msememodialog,msegui,msetypes{msestrings}; + +type + tprogramparametersfo = class(tmseform) + + ok: tbutton; + envvaron: tbooleanedit; + tbutton2: tbutton; + parameters: tmemodialoghistoryedit; + statfile1: tstatfile; + envvarname: tstringedit; + envvarvalue: tmemodialogedit; + grid: twidgetgrid; + workingdirectory: tfilenameedit; + procedure hintexpandedmacros(const sender: TObject; var info: hintinfoty); + procedure expandfilename(const sender: TObject; var avalue: msestring; + var accept: Boolean); + end; + +procedure editprogramparameters; +procedure updatestat(const filer: tstatfiler); + +implementation +uses + programparametersform_mfm,projectoptionsform,mseguiglob,mseedit; + +procedure editprogramparameters; +var + fo: tprogramparametersfo; +begin + fo:= tprogramparametersfo.create(nil); + try + with projectoptions,d.t do begin + fo.parameters.value:= progparameters; + fo.parameters.dropdown.valuelist.asarray:= progparamhistory; + fo.workingdirectory.value:= progworkingdirectory; + fo.workingdirectory.controller.history:= workdirparamhistory; + fo.envvaron.gridvalues:= envvarons; + fo.envvarname.gridvalues:= envvarnames; + fo.envvarvalue.gridvalues:= envvarvalues; + end; + if fo.show(true,nil) = mr_ok then begin + fo.grid.removeappendedrow; + with projectoptions,d.t do begin + progparameters:= fo.parameters.value; + progparamhistory:= fo.parameters.dropdown.valuelist.asarray; + progworkingdirectory:= fo.workingdirectory.value; + workdirparamhistory:= fo.workingdirectory.controller.history; + envvarons:= fo.envvaron.gridvalues; + envvarnames:= fo.envvarname.gridvalues; + envvarvalues:= fo.envvarvalue.gridvalues; + end; + expandprojectmacros; + end; + finally + fo.Free; + end; +end; + +procedure updatestat(const filer: tstatfiler); +begin + filer.setsection('progparams'); //backward compatibility + with projectoptions,d,tstatreader(filer) do begin + if not filer.iswriter then begin + with t do begin + progparameters:= readmsestring('parameters',progparameters); +// progparamhistory:= readarray('progparamhistory',propgparamhistory); + progworkingdirectory:= + readmsestring('workingdirectory',progworkingdirectory); +// envvarons:= readarray('envvarons',envvarons); + envvarnames:= readarray('envvarnames',envvarnames); + envvarvalues:= readarray('envvarvalues',envvarvalues); + end; + end; + +// filer.updatevalue('parameters',progparameters); + filer.updatevalue('progparamhistory',progparamhistory); + filer.updatevalue('workdirparamhistory',workdirparamhistory); +// filer.updatevalue('workingdirectory',progworkingdirectory); + filer.updatevalue('envvarons',envvarons); + // filer.updatevalue('envvarnames',envvarnames); +// filer.updatevalue('envvarvalues',envvarvalues); + end; +end; + +procedure tprogramparametersfo.hintexpandedmacros(const sender: TObject; + var info: hintinfoty); +begin + info.caption:= tcustomedit(sender).text; + expandprmacros1(info.caption); + include(info.flags,hfl_show); //show empty caption +end; + +procedure tprogramparametersfo.expandfilename(const sender: TObject; + var avalue: msestring; var accept: Boolean); +begin + expandprmacros1(avalue); +end; + +end. diff --git a/mseide-msegui/apps/ide/programparametersform_mfm.pas b/mseide-msegui/apps/ide/programparametersform_mfm.pas new file mode 100644 index 0000000..320de8d --- /dev/null +++ b/mseide-msegui/apps/ide/programparametersform_mfm.pas @@ -0,0 +1,241 @@ +unit programparametersform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,programparametersform; + +const + objdata: record size: integer; data: array[0..4464] of byte end = + (size: 4465; data: ( + 84,80,70,48,20,116,112,114,111,103,114,97,109,112,97,114,97,109,101,116, + 101,114,115,102,111,19,112,114,111,103,114,97,109,112,97,114,97,109,101,116, + 101,114,115,102,111,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100, + 115,95,120,3,16,1,8,98,111,117,110,100,115,95,121,3,243,0,9,98, + 111,117,110,100,115,95,99,120,3,72,1,9,98,111,117,110,100,115,95,99, + 121,3,92,1,26,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,0,27,99,111,110,116,97,105, + 110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115, + 1,2,0,2,0,3,72,1,3,92,1,0,7,111,112,116,105,111,110,115, + 11,13,102,111,95,99,108,111,115,101,111,110,101,115,99,17,102,111,95,108, + 111,99,97,108,115,104,111,114,116,99,117,116,115,15,102,111,95,97,117,116, + 111,114,101,97,100,115,116,97,116,16,102,111,95,97,117,116,111,119,114,105, + 116,101,115,116,97,116,10,102,111,95,115,97,118,101,112,111,115,13,102,111, + 95,115,97,118,101,122,111,114,100,101,114,0,8,115,116,97,116,102,105,108, + 101,7,9,115,116,97,116,102,105,108,101,49,7,99,97,112,116,105,111,110, + 6,18,84,97,114,103,101,116,32,69,110,118,105,114,111,110,109,101,110,116, + 13,119,105,110,100,111,119,111,112,97,99,105,116,121,5,0,0,0,0,0, + 0,0,128,255,255,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109, + 101,6,8,116,109,115,101,102,111,114,109,0,13,116,102,105,108,101,110,97, + 109,101,101,100,105,116,16,119,111,114,107,105,110,103,100,105,114,101,99,116, + 111,114,121,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,18,38, + 87,111,114,107,105,110,103,32,100,105,114,101,99,116,111,114,121,22,102,114, + 97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115, + 11,9,116,102,95,98,111,116,116,111,109,0,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,19,102,114,97,109,101,46,98,117, + 116,116,111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46, + 98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111, + 114,4,2,0,0,128,7,105,109,97,103,101,110,114,2,17,0,0,18,102, + 114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111,114,4,2,0, + 0,128,20,102,114,97,109,101,46,98,117,116,116,111,110,46,105,109,97,103, + 101,110,114,2,17,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101, + 114,2,1,10,111,110,115,104,111,119,104,105,110,116,7,18,104,105,110,116, + 101,120,112,97,110,100,101,100,109,97,99,114,111,115,8,98,111,117,110,100, + 115,95,120,2,2,8,98,111,117,110,100,115,95,121,2,9,9,98,111,117, + 110,100,115,95,99,120,3,68,1,9,98,111,117,110,100,115,95,99,121,2, + 37,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97, + 110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,18,99,111,110,116, + 114,111,108,108,101,114,46,111,112,116,105,111,110,115,11,13,102,100,111,95, + 100,105,114,101,99,116,111,114,121,0,22,99,111,110,116,114,111,108,108,101, + 114,46,99,97,112,116,105,111,110,111,112,101,110,6,32,83,101,108,101,99, + 116,32,112,114,111,103,114,97,109,32,119,111,114,107,105,110,103,32,100,105, + 114,101,99,116,111,114,121,24,99,111,110,116,114,111,108,108,101,114,46,111, + 110,103,101,116,102,105,108,101,110,97,109,101,7,14,101,120,112,97,110,100, + 102,105,108,101,110,97,109,101,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,14,0,0,7,116,98,117,116,116,111,110,2,111,107,8,116,97, + 98,111,114,100,101,114,2,4,8,98,111,117,110,100,115,95,120,3,216,0, + 8,98,111,117,110,100,115,95,121,3,64,1,9,98,111,117,110,100,115,95, + 99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,20,7,97,110,99, + 104,111,114,115,11,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111, + 116,116,111,109,0,5,115,116,97,116,101,11,10,97,115,95,100,101,102,97, + 117,108,116,15,97,115,95,108,111,99,97,108,100,101,102,97,117,108,116,15, + 97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,7,99,97,112, + 116,105,111,110,6,2,79,75,11,109,111,100,97,108,114,101,115,117,108,116, + 7,5,109,114,95,111,107,0,0,7,116,98,117,116,116,111,110,8,116,98, + 117,116,116,111,110,50,8,98,111,117,110,100,115,95,120,3,16,1,8,98, + 111,117,110,100,115,95,121,3,64,1,9,98,111,117,110,100,115,95,99,120, + 2,50,9,98,111,117,110,100,115,95,99,121,2,20,7,97,110,99,104,111, + 114,115,11,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116,116, + 111,109,0,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99, + 97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,6,67,97,110, + 99,101,108,11,109,111,100,97,108,114,101,115,117,108,116,7,9,109,114,95, + 99,97,110,99,101,108,0,0,22,116,109,101,109,111,100,105,97,108,111,103, + 104,105,115,116,111,114,121,101,100,105,116,10,112,97,114,97,109,101,116,101, + 114,115,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,11,38,80, + 97,114,97,109,101,116,101,114,115,22,102,114,97,109,101,46,99,97,112,116, + 105,111,110,116,101,120,116,102,108,97,103,115,11,9,116,102,95,98,111,116, + 116,111,109,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108, + 111,114,4,2,0,0,128,19,102,114,97,109,101,46,98,117,116,116,111,110, + 115,46,99,111,117,110,116,2,2,19,102,114,97,109,101,46,98,117,116,116, + 111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4,2,0, + 0,128,0,1,5,99,111,108,111,114,4,2,0,0,128,7,105,109,97,103, + 101,110,114,2,17,0,0,24,102,114,97,109,101,46,98,117,116,116,111,110, + 100,105,97,108,111,103,46,99,111,108,111,114,4,2,0,0,128,26,102,114, + 97,109,101,46,98,117,116,116,111,110,100,105,97,108,111,103,46,105,109,97, + 103,101,110,114,2,17,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100, + 101,114,2,2,10,111,110,115,104,111,119,104,105,110,116,7,18,104,105,110, + 116,101,120,112,97,110,100,101,100,109,97,99,114,111,115,8,98,111,117,110, + 100,115,95,120,2,2,8,98,111,117,110,100,115,95,121,2,57,9,98,111, + 117,110,100,115,95,99,120,3,68,1,9,98,111,117,110,100,115,95,99,121, + 2,37,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6, + 97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,16,100,114,111, + 112,100,111,119,110,46,111,112,116,105,111,110,115,11,15,100,101,111,95,107, + 101,121,100,114,111,112,100,111,119,110,19,100,101,111,95,97,117,116,111,115, + 97,118,101,104,105,115,116,111,114,121,12,100,101,111,95,99,108,105,112,104, + 105,110,116,0,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,99, + 111,117,110,116,2,1,19,100,114,111,112,100,111,119,110,46,99,111,108,115, + 46,105,116,101,109,115,14,1,0,0,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,14,0,0,11,116,119,105,100,103,101,116,103,114,105,100, + 4,103,114,105,100,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 21,69,110,118,105,114,111,110,109,101,110,116,32,118,97,114,105,97,98,108, + 101,115,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116, + 102,108,97,103,115,11,9,116,102,95,98,111,116,116,111,109,0,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0, + 2,0,0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117,110,100, + 115,95,120,2,2,8,98,111,117,110,100,115,95,121,2,111,9,98,111,117, + 110,100,115,95,99,120,3,68,1,9,98,111,117,110,100,115,95,99,121,3, + 195,0,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6, + 97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,9,97,110,95,98, + 111,116,116,111,109,0,11,111,112,116,105,111,110,115,103,114,105,100,11,12, + 111,103,95,99,111,108,115,105,122,105,110,103,15,111,103,95,107,101,121,114, + 111,119,109,111,118,105,110,103,15,111,103,95,114,111,119,105,110,115,101,114, + 116,105,110,103,14,111,103,95,114,111,119,100,101,108,101,116,105,110,103,19, + 111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101,114,15, + 111,103,95,97,117,116,111,102,105,114,115,116,114,111,119,13,111,103,95,97, + 117,116,111,97,112,112,101,110,100,12,111,103,95,115,97,118,101,115,116,97, + 116,101,20,111,103,95,99,111,108,99,104,97,110,103,101,111,110,116,97,98, + 107,101,121,10,111,103,95,119,114,97,112,99,111,108,12,111,103,95,97,117, + 116,111,112,111,112,117,112,0,13,102,105,120,114,111,119,115,46,99,111,117, + 110,116,2,1,13,102,105,120,114,111,119,115,46,105,116,101,109,115,14,1, + 6,104,101,105,103,104,116,2,16,14,99,97,112,116,105,111,110,115,46,99, + 111,117,110,116,2,3,14,99,97,112,116,105,111,110,115,46,105,116,101,109, + 115,14,1,7,99,97,112,116,105,111,110,6,2,111,110,0,1,7,99,97, + 112,116,105,111,110,6,4,78,97,109,101,0,1,7,99,97,112,116,105,111, + 110,6,5,86,97,108,117,101,0,0,0,0,14,100,97,116,97,99,111,108, + 115,46,99,111,117,110,116,2,3,16,100,97,116,97,99,111,108,115,46,111, + 112,116,105,111,110,115,11,12,99,111,95,115,97,118,101,115,116,97,116,101, + 0,14,100,97,116,97,99,111,108,115,46,105,116,101,109,115,14,7,8,101, + 110,118,118,97,114,111,110,1,5,119,105,100,116,104,2,20,7,111,112,116, + 105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117,115,12,99, + 111,95,115,97,118,101,115,116,97,116,101,0,10,119,105,100,103,101,116,110, + 97,109,101,6,8,101,110,118,118,97,114,111,110,9,100,97,116,97,99,108, + 97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116, + 97,108,105,115,116,0,7,10,101,110,118,118,97,114,110,97,109,101,1,5, + 119,105,100,116,104,2,103,7,111,112,116,105,111,110,115,11,15,99,111,95, + 112,114,111,112,111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101, + 115,116,97,116,101,0,10,119,105,100,103,101,116,110,97,109,101,6,10,101, + 110,118,118,97,114,110,97,109,101,9,100,97,116,97,99,108,97,115,115,7, + 22,116,103,114,105,100,109,115,101,115,116,114,105,110,103,100,97,116,97,108, + 105,115,116,0,7,11,101,110,118,118,97,114,118,97,108,117,101,1,5,119, + 105,100,116,104,3,194,0,7,111,112,116,105,111,110,115,11,7,99,111,95, + 102,105,108,108,12,99,111,95,115,97,118,101,115,116,97,116,101,0,10,119, + 105,100,103,101,116,110,97,109,101,6,11,101,110,118,118,97,114,118,97,108, + 117,101,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109, + 115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,0,13,100, + 97,116,97,114,111,119,104,101,105,103,104,116,2,16,8,115,116,97,116,102, + 105,108,101,7,9,115,116,97,116,102,105,108,101,49,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,14,0,12,116,98,111,111,108,101,97,110, + 101,100,105,116,8,101,110,118,118,97,114,111,110,14,111,112,116,105,111,110, + 115,119,105,100,103,101,116,49,11,0,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114, + 108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114, + 100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,20,9, + 98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105,111,110,115,101, + 100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101, + 95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107, + 109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117,114, + 110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120, + 105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111, + 101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111, + 115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116, + 111,110,102,105,114,115,116,99,108,105,99,107,0,12,111,112,116,105,111,110, + 115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117, + 112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101, + 13,111,101,49,95,115,97,118,101,115,116,97,116,101,0,7,118,105,115,105, + 98,108,101,8,12,118,97,108,117,101,100,101,102,97,117,108,116,9,0,0, + 11,116,115,116,114,105,110,103,101,100,105,116,10,101,110,118,118,97,114,110, + 97,109,101,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102, + 114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,3,0,0, + 128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,2,7,118, + 105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,21,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2, + 103,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110, + 115,101,100,105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105,116, + 11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108, + 111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99, + 97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110, + 12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115, + 101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120, + 105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101, + 110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111, + 101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99, + 108,105,99,107,18,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116, + 101,120,116,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,0,15,116,109,101,109,111,100,105,97,108,111,103,101,100,105,116,11,101, + 110,118,118,97,114,118,97,108,117,101,14,111,112,116,105,111,110,115,119,105, + 100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104, + 104,101,105,103,104,116,0,12,102,114,97,109,101,46,108,101,118,101,108,111, + 2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116, + 4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99, + 111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,19,102,114,97,109,101,46,98,117, + 116,116,111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46, + 98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111, + 114,4,2,0,0,128,7,105,109,97,103,101,110,114,2,17,0,0,18,102, + 114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111,114,4,2,0, + 0,128,20,102,114,97,109,101,46,98,117,116,116,111,110,46,105,109,97,103, + 101,110,114,2,17,8,116,97,98,111,114,100,101,114,2,3,10,111,110,115, + 104,111,119,104,105,110,116,7,18,104,105,110,116,101,120,112,97,110,100,101, + 100,109,97,99,114,111,115,7,118,105,115,105,98,108,101,8,8,98,111,117, + 110,100,115,95,120,2,125,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,120,3,194,0,9,98,111,117,110,100,115,95,99, + 121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,0,11,111, + 112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111, + 110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111, + 101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115, + 104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116, + 117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110, + 101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114, + 13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117, + 116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101, + 99,116,111,110,102,105,114,115,116,99,108,105,99,107,18,111,101,95,104,105, + 110,116,99,108,105,112,112,101,100,116,101,120,116,0,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,14,0,0,0,9,116,115,116,97,116,102, + 105,108,101,9,115,116,97,116,102,105,108,101,49,8,102,105,108,101,110,97, + 109,101,6,23,112,114,111,103,114,97,109,112,97,114,97,109,101,116,101,114, + 115,102,111,46,115,116,97,7,111,112,116,105,111,110,115,11,10,115,102,111, + 95,109,101,109,111,114,121,0,4,108,101,102,116,3,176,0,3,116,111,112, + 2,96,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tprogramparametersfo,''); +end. diff --git a/mseide-msegui/apps/ide/projectoptionsform.mfm b/mseide-msegui/apps/ide/projectoptionsform.mfm new file mode 100644 index 0000000..9b730d7 --- /dev/null +++ b/mseide-msegui/apps/ide/projectoptionsform.mfm @@ -0,0 +1,6790 @@ +object projectoptionsfo: tprojectoptionsfo + optionswidget = [ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets, ow_hinton] + visible = False + bounds_x = 205 + bounds_y = 177 + bounds_cx = 832 + bounds_cy = 581 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.color = -2147483645 + container.frame.framei_bottom = 0 + container.frame.localprops = [frl_fibottom, frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + container.frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + container.frame.sbhorz.options = [sbo_moveauto, sbo_showauto] + container.face.localprops = [] + container.bounds = ( + 0 + 0 + 832 + 581 + ) + options = [fo_closeonesc, fo_localshortcuts, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder] + statfile = statfile1 + caption = 'Project Options' + windowopacity = -Inf + oncreate = createexe + moduleclassname = 'tmseform' + object tlayouter9: tlayouter + bounds_x = 0 + bounds_y = 0 + bounds_cx = 832 + bounds_cy = 581 + anchors = [] + optionslayout = [lao_placey] + place_maxdist = 0 + place_options = [plo_endmargin] + object tlayouter8: tlayouter + color = -2147483645 + frame.framei_top = 5 + frame.framei_bottom = 5 + frame.localprops = [frl_fitop, frl_fibottom] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + bounds_x = 0 + bounds_y = 551 + bounds_cx = 832 + bounds_cy = 30 + anchors = [an_bottom] + optionsscale = [osc_expandy, osc_shrinky] + optionslayout = [lao_placex, lao_aligny, lao_syncmaxautosize] + align_glue = wam_center + place_mindist = 5 + place_maxdist = 5 + place_mode = wam_end + place_options = [plo_propmargin] + linktop = tabwidget + object cancel: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + color = -2147483645 + bounds_x = 775 + bounds_y = 5 + bounds_cx = 52 + bounds_cy = 20 + state = [as_localcaption, as_localcolor] + caption = 'Cancel' + modalresult = mr_cancel + reffontheight = 14 + end + object ok: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + color = -2147483645 + taborder = 1 + bounds_x = 718 + bounds_y = 5 + bounds_cx = 52 + bounds_cy = 20 + state = [as_default, as_localdefault, as_localcaption, as_localcolor] + caption = 'Ok' + modalresult = mr_ok + reffontheight = 14 + end + end + object tabwidget: ttabwidget + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + optionswidget1 = [ow1_fontglyphheight] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 832 + bounds_cy = 551 + color = -1879048187 + frame.levelo = -1 + frame.captionoffset = 3 + frame.localprops = [frl_levelo] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + anchors = [an_top, an_bottom] + taborder = 1 + activepageindex = 2 + tab_frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + tab_frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + tab_color = -2147483645 + tab_size = 19 + statfile = statfile1 + reffontheight = 14 + object editorpage: ttabpage + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + frame.framei_bottom = 0 + frame.localprops = [frl_fibottom, frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 5 + bounds_x = 1 + bounds_y = 20 + bounds_cx = 830 + bounds_cy = 530 + anchors = [an_top] + caption = '&Editor' + reffontheight = 14 + object ttabwidget3: ttabwidget + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_mousewheel, ow_destroywidgets] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 830 + bounds_cy = 530 + anchors = [] + activepageindex = 0 + tab_frame.localprops = [] + tab_frame.localprops1 = [] + tab_size = 19 + statfile = statfile1 + object ttabpage23: ttabpage + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_mousewheel, ow_destroywidgets] + frame.localprops = [] + frame.localprops1 = [] + taborder = 2 + bounds_x = 0 + bounds_y = 19 + bounds_cx = 830 + bounds_cy = 511 + anchors = [an_left, an_top, an_right, an_bottom] + caption = 'Source' + object ttabwidget2: ttabwidget + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + bounds_x = 0 + bounds_y = 295 + bounds_cx = 830 + bounds_cy = 216 + bounds_cymin = 84 + anchors = [an_top, an_bottom] + taborder = 1 + activepageindex = 0 + tab_frame.localprops = [] + tab_frame.localprops1 = [] + tab_color = -2147483645 + tab_size = 19 + statfile = statfile1 + reffontheight = 14 + object ttabpage13: ttabpage + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + color = -2147483645 + frame.framei_bottom = 0 + frame.localprops = [frl_fibottom, frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 1 + bounds_x = 0 + bounds_y = 19 + bounds_cx = 830 + bounds_cy = 197 + anchors = [an_left, an_top, an_right, an_bottom] + caption = 'File filter' + reffontheight = 14 + object filefiltergrid: tstringgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 830 + bounds_cy = 197 + anchors = [] + optionsgrid = [og_colsizing, og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_selectedrowsdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + datacols.count = 2 + datacols.options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item + width = 112 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + valuefalse = '0' + valuetrue = '1' + end + item + width = 684 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + valuefalse = '0' + valuetrue = '1' + end> + fixcols.count = 1 + fixcols.items = < + item + width = 27 + numstart = 1 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 2 + captions.items = < + item + caption = 'Name' + end + item + caption = 'File mask' + end> + end> + datarowheight = 16 + statfile = statfile1 + reffontheight = 14 + end + end + object ttabpage14: ttabpage + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 2 + bounds_x = 0 + bounds_y = 19 + bounds_cx = 830 + bounds_cy = 197 + anchors = [an_left, an_top, an_right, an_bottom] + caption = 'Syntax definition files' + reffontheight = 14 + object twidgetgrid6: twidgetgrid + frame.localprops = [] + frame.localprops1 = [] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 830 + bounds_cy = 197 + anchors = [] + optionsgrid = [og_colsizing, og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixcols.count = 1 + fixcols.items = < + item + width = 26 + numstart = 1 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 2 + captions.items = < + item + caption = 'Syntax definition file' + end + item + caption = 'File mask' + end> + end> + datacols.count = 2 + datacols.options = [co_proportional, co_savevalue, co_savestate, co_mousescrollrow] + datacols.items = < + item[syntaxdeffile] + width = 251 + options = [co_proportional, co_savevalue, co_savestate, co_mousescrollrow] + onshowhint = colonshowhint + widgetname = 'syntaxdeffile' + dataclass = tgridmsestringdatalist + end + item[syntaxdeffilemask] + width = 546 + options = [co_fill, co_savevalue, co_savestate, co_mousescrollrow] + widgetname = 'syntaxdeffilemask' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + reffontheight = 14 + object syntaxdeffile: tfilenameedit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 1 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 251 + bounds_cy = 16 + textflags = [tf_noselect, tf_ellipseleft] + controller.filterlist.data = ( + ( + 'Syntaxdef files' + '*.sdef' + ) + ) + controller.ongetfilename = expandfilename + reffontheight = 14 + end + object syntaxdeffilemask: tmemodialogedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.localprops = [frl_levelo] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 2 + visible = False + bounds_x = 252 + bounds_y = 0 + bounds_cx = 546 + bounds_cy = 16 + reffontheight = 14 + end + end + end + object ttabpage19: ttabpage + frame.localprops = [] + frame.localprops1 = [] + taborder = 3 + bounds_x = 0 + bounds_y = 19 + bounds_cx = 830 + bounds_cy = 197 + anchors = [an_left, an_top, an_right, an_bottom] + caption = 'Code templates' + object twidgetgrid5: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + frame.options = [cfo_fixtop, cfo_fixbottom] + frame.caption = 'Code template directories, file extension = .mct' + frame.captiontextflags = [tf_bottom] + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + bounds_x = 0 + bounds_y = 0 + bounds_cx = 830 + bounds_cy = 197 + bounds_cymin = 40 + anchors = [an_top, an_bottom] + optionsgrid = [og_keyrowmoving, og_rowinserting, og_rowdeleting, og_selectedrowsdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_wrapcol, og_autopopup] + fixcols.count = 1 + fixcols.items = < + item + width = 28 + numstart = 1 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 11 + captions.items = < + item + caption = 'Directory' + end + item + caption = 'O' + hint = 'Add to object file search path' + end + item + caption = 'L' + hint = 'Add to library search path' + end + item + caption = 'I' + hint = 'Add to include file search path' + end + item + caption = 'U' + hint = 'Add to unit file search path' + end + item + caption = '4' + hint = 'Use in Make 4' + end + item + caption = '3' + hint = 'Use in Make 3' + end + item + caption = '2' + hint = 'Use in Make 2' + end + item + caption = '1' + hint = 'Use in Make 1' + end + item + caption = 'B' + hint = 'Use in Build' + end + item + caption = 'M' + hint = 'Use in Make' + end> + end> + datacols.count = 1 + datacols.width = 13 + datacols.options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[codetemplatedirs] + linecolorfix = -1610612733 + width = 796 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savevalue, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + onshowhint = colonshowhint + widgetname = 'codetemplatedirs' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + reffontheight = 14 + object codetemplatedirs: tfilenameedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + taborder = 1 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 796 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + controller.options = [fdo_directory] + controller.historymaxcount = 0 + controller.captionopen = 'Select unit directory' + controller.ongetfilename = expandfilename + reffontheight = 14 + end + end + end + end + object tlayouter13: tlayouter + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 830 + bounds_cy = 293 + anchors = [an_top] + optionsscale = [osc_expandx, osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_placey] + place_mindist = 2 + place_maxdist = 2 + place_options = [plo_endmargin] + linkbottom = ttabwidget2 + dist_bottom = 2 + object dispgrid: twidgetgrid + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + frame.caption = 'Test' + frame.captiontextflags = [tf_bottom] + frame.captionpos = cp_topright + frame.font.xscale = 1 + frame.font.localprops = [flp_xscale] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 4 + bounds_x = 6 + bounds_y = 202 + bounds_cx = 817 + bounds_cy = 91 + anchors = [an_left, an_top, an_right] + font.xscale = 1 + font.localprops = [flp_xscale] + optionsgrid = [og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_wrapcol, og_autopopup] + rowcount = 2 + rowcolors.count = 1 + rowcolors.items = ( + 14745599 + ) + datacols.count = 1 + datacols.linewidth = 0 + datacols.options = [co_fill, co_savestate] + datacols.items = < + item[fontdisp] + width = 812 + options = [co_fill, co_savestate] + widgetname = 'fontdisp' + dataclass = tgridrichstringdatalist + data = ( + ( + '' + '' + ) + ) + end> + datarowlinewidth = 0 + datarowheight = 14 + reffontheight = 14 + object fontdisp: ttextedit + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 812 + bounds_cy = 14 + font.name = 'stf_default' + font.xscale = 1 + font.localprops = [flp_xscale] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + optionsedit = [oe_closequery, oe_checkmrcancel, oe_linebreak, oe_eatreturn, oe_exitoncursor, oe_nofirstarrownavig] + reffontheight = 14 + end + end + object tlayouter12: tlayouter + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 3 + bounds_x = 0 + bounds_y = 163 + bounds_cx = 600 + bounds_cy = 37 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + optionslayout = [lao_aligny] + align_glue = wam_start + object editfontextraspace: tintegeredit + color = -2147483645 + frame.caption = 'ExtSp' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 1 + 0 + ) + taborder = 3 + hint = 'Extra space between lines' + bounds_x = 247 + bounds_y = 0 + bounds_cx = 37 + bounds_cy = 37 + ondataentered = fontondataentered + valuemin = -1000 + valuemax = 1000 + reffontheight = 14 + end + object editfontwidth: tintegeredit + frame.caption = 'Width' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 1 + 0 + ) + taborder = 2 + bounds_x = 199 + bounds_y = 0 + bounds_cx = 37 + bounds_cy = 37 + ondataentered = fontondataentered + reffontheight = 14 + end + object editfontheight: tintegeredit + frame.caption = 'Height' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 7 + 0 + ) + taborder = 1 + bounds_x = 151 + bounds_y = 0 + bounds_cx = 43 + bounds_cy = 37 + ondataentered = fontondataentered + reffontheight = 14 + end + object editfontname: tstringedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusout, ow_destroywidgets] + frame.caption = 'Font' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + bounds_x = 7 + bounds_y = 0 + bounds_cx = 124 + bounds_cy = 37 + ondataentered = fontondataentered + value = 'mseide_source' + reffontheight = 14 + end + object editfontcolor: tcoloredit + frame.caption = 'Color' + frame.captiontextflags = [tf_bottom] + frame.localprops = [] + frame.localprops1 = [] + frame.button.color = -2147483646 + frame.button.options = [fbo_inactiveinvisible] + frame.buttons.count = 2 + frame.buttons.items = < + item + color = -2147483646 + options = [fbo_inactiveinvisible] + end + item + color = -2147483646 + imagenr = 17 + options = [fbo_inactiveinvisible] + end> + frame.buttonellipse.color = -2147483646 + frame.buttonellipse.imagenr = 17 + frame.buttonellipse.options = [fbo_inactiveinvisible] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 4 + bounds_x = 303 + bounds_y = 0 + bounds_cy = 37 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savevalue, oe1_savestate] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext] + ondataentered = fontondataentered + value = -1879048183 + dropdown.options = [deo_autodropdown, deo_keydropdown, deo_cliphint] + reffontheight = 14 + end + object editbkcolor: tcoloredit + frame.caption = 'Bk. Color' + frame.captiontextflags = [tf_bottom] + frame.localprops = [] + frame.localprops1 = [] + frame.button.color = -2147483646 + frame.button.options = [fbo_inactiveinvisible] + frame.buttons.count = 2 + frame.buttons.items = < + item + color = -2147483646 + options = [fbo_inactiveinvisible] + end + item + color = -2147483646 + imagenr = 17 + options = [fbo_inactiveinvisible] + end> + frame.buttonellipse.color = -2147483646 + frame.buttonellipse.imagenr = 17 + frame.buttonellipse.options = [fbo_inactiveinvisible] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 5 + bounds_x = 407 + bounds_y = 0 + bounds_cy = 37 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savevalue, oe1_savestate] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext] + ondataentered = fontondataentered + value = -1879048186 + dropdown.options = [deo_autodropdown, deo_keydropdown, deo_cliphint] + reffontheight = 14 + end + object editfontantialiased: tbooleanedit + frame.caption = 'Anti aliased' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 1 + 76 + 2 + ) + taborder = 6 + bounds_x = 511 + bounds_y = 20 + bounds_cx = 89 + bounds_cy = 16 + ondataentered = fontondataentered + value = True + end + end + object tlayouter11: tlayouter + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 2 + bounds_x = 0 + bounds_y = 91 + bounds_cx = 572 + bounds_cy = 70 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + optionslayout = [lao_aligny] + align_glue = wam_start + object tlayouter14: tlayouter + bounds_x = 7 + bounds_y = 0 + bounds_cx = 121 + bounds_cy = 70 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + optionslayout = [lao_placey] + place_mindist = 2 + place_maxdist = 2 + object rightmarginon: tbooleanedit + frame.caption = 'Right margin line' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 1 + 108 + 2 + ) + taborder = 3 + bounds_x = 0 + bounds_y = 54 + bounds_cx = 121 + bounds_cy = 16 + value = True + end + object linenumberson: tbooleanedit + frame.caption = 'Line numbers' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 87 + 2 + ) + bounds_x = 0 + bounds_y = 0 + bounds_cx = 100 + bounds_cy = 16 + end + object editmarkbrackets: tbooleanedit + frame.caption = 'Mark brackets' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 1 + 92 + 2 + ) + taborder = 1 + bounds_x = 0 + bounds_y = 18 + bounds_cx = 105 + bounds_cy = 16 + value = True + end + object editmarkpairwords: tbooleanedit + frame.caption = 'Mark pairwords' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 1 + 98 + 2 + ) + taborder = 2 + hint = 'Mark in syntax definition file defined word pairs.' + bounds_x = 0 + bounds_y = 36 + bounds_cx = 111 + bounds_cy = 16 + value = True + end + end + object tlayouter15: tlayouter + taborder = 1 + bounds_x = 143 + bounds_y = 10 + bounds_cx = 429 + bounds_cy = 51 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_aligny] + align_glue = wam_start + object pairmarkcolor: tcoloredit + frame.caption = 'Mark'#10'color' + frame.captiontextflags = [tf_bottom] + frame.localprops = [] + frame.localprops1 = [] + frame.button.color = -2147483646 + frame.button.options = [fbo_inactiveinvisible] + frame.buttons.count = 2 + frame.buttons.items = < + item + color = -2147483646 + options = [fbo_inactiveinvisible] + end + item + color = -2147483646 + imagenr = 17 + options = [fbo_inactiveinvisible] + end> + frame.buttonellipse.color = -2147483646 + frame.buttonellipse.imagenr = 17 + frame.buttonellipse.options = [fbo_inactiveinvisible] + frame.outerframe = ( + 0 + 31 + 0 + 0 + ) + taborder = 3 + hint = 'Background color of marked brackets and word pairs.'#10'Will be overridden by setting in syntax definition file.'#10'cl_none -> force none.' + onshowhint = colorhint + bounds_x = 264 + bounds_y = 0 + bounds_cy = 51 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savevalue, oe1_savestate] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext] + dropdown.options = [deo_autodropdown, deo_keydropdown, deo_cliphint] + reffontheight = 14 + end + object statementcolor: tcoloredit + frame.caption = 'Statement'#10'color' + frame.captiontextflags = [tf_bottom] + frame.localprops = [] + frame.localprops1 = [] + frame.button.color = -2147483646 + frame.button.options = [fbo_inactiveinvisible] + frame.buttons.count = 2 + frame.buttons.items = < + item + color = -2147483646 + options = [fbo_inactiveinvisible] + end + item + color = -2147483646 + imagenr = 17 + options = [fbo_inactiveinvisible] + end> + frame.buttonellipse.color = -2147483646 + frame.buttonellipse.imagenr = 17 + frame.buttonellipse.options = [fbo_inactiveinvisible] + frame.outerframe = ( + 0 + 31 + 0 + 0 + ) + taborder = 2 + hint = 'Background color of the active row while debugging.'#10'Will be overridden by setting in syntax definition file.'#10'cl_none -> force none.' + onshowhint = colorhint + bounds_x = 160 + bounds_y = 0 + bounds_cy = 51 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savevalue, oe1_savestate] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext] + ondataentered = fontondataentered + value = 14745599 + dropdown.options = [deo_autodropdown, deo_keydropdown, deo_cliphint] + reffontheight = 14 + end + object scrollheight: tintegeredit + frame.caption = 'Scroll'#10'height' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 31 + 6 + 0 + ) + taborder = 1 + hint = '0 -> accelerated,'#10'-1 -> paged' + bounds_x = 104 + bounds_y = 0 + bounds_cx = 42 + bounds_cy = 51 + valuemin = -1 + valuemax = 1000 + reffontheight = 14 + end + object rightmarginchars: tintegeredit + frame.caption = 'Characters' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 35 + 0 + ) + bounds_x = 8 + bounds_y = 14 + bounds_cx = 71 + bounds_cy = 37 + optionsedit1 = [oe1_autopopupmenu, oe1_savevalue, oe1_savestate] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + value = 80 + valuemin = 1 + valuemax = 100 + reffontheight = 14 + end + object pairmaxrowcount: tintegeredit + frame.caption = 'Mark max'#10'rowcount' + frame.captiontextflags = [tf_bottom] + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 31 + 1 + 0 + ) + taborder = 4 + bounds_x = 368 + bounds_y = 0 + bounds_cx = 61 + bounds_cy = 51 + value = 100 + valuemin = 1 + reffontheight = 14 + end + end + end + object tlayouter10: tlayouter + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 1 + bounds_x = 0 + bounds_y = 52 + bounds_cx = 830 + bounds_cy = 37 + anchors = [an_top] + optionsscale = [osc_expandy, osc_shrinky] + optionslayout = [lao_aligny] + align_glue = wam_start + object spacetabs: tbooleanedit + frame.caption = 'Space' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 1 + 42 + 2 + ) + taborder = 4 + bounds_x = 303 + bounds_y = 20 + bounds_cx = 55 + bounds_cy = 16 + end + object blockindent: tintegeredit + frame.caption = 'Block Indent' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 43 + 0 + ) + taborder = 1 + bounds_x = 151 + bounds_y = 0 + bounds_cx = 79 + bounds_cy = 37 + optionsedit1 = [oe1_autopopupmenu, oe1_savevalue, oe1_savestate] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + value = 1 + valuemin = 1 + valuemax = 100 + reffontheight = 14 + end + object autoindent: tbooleanedit + frame.caption = 'Auto indent' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 1 + 76 + 2 + ) + bounds_x = 7 + bounds_y = 20 + bounds_cx = 89 + bounds_cy = 16 + value = True + end + object tabindent: tbooleanedit + frame.caption = 'Tab' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 26 + 2 + ) + taborder = 2 + bounds_x = 191 + bounds_y = 20 + bounds_cx = 39 + bounds_cy = 16 + end + object tabstops: tintegeredit + frame.caption = 'Tabstops' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 24 + 0 + ) + taborder = 3 + bounds_x = 247 + bounds_y = 0 + bounds_cx = 60 + bounds_cy = 37 + value = 4 + valuemin = 1 + valuemax = 50 + reffontheight = 14 + end + object showtabs: tbooleanedit + frame.caption = 'Show tabs' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 68 + 2 + ) + taborder = 5 + bounds_x = 407 + bounds_y = 20 + bounds_cx = 81 + bounds_cy = 16 + end + end + object tlayouter16: tlayouter + bounds_x = 0 + bounds_y = 0 + bounds_cx = 830 + bounds_cy = 50 + anchors = [an_top] + optionsscale = [osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_aligny] + align_glue = wam_start + object eolstyle: tenumtypeedit + frame.caption = 'Eolstyle' + frame.captiontextflags = [tf_bottom] + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + end> + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + hint = 'End of line style for writing. eol_default -> use original style.' + bounds_x = 247 + bounds_y = 0 + bounds_cx = 116 + bounds_cy = 37 + value = 1 + valuemin = 0 + valuemax = 3 + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + oninit = initeolstyleexe + reffontheight = 14 + end + object trimtrailingwhitespace: tbooleanedit + frame.caption = 'Trim trailing'#10'whitespace'#10'on save' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 15 + 76 + 16 + ) + bounds_x = 7 + bounds_y = 6 + bounds_cx = 89 + bounds_cy = 44 + end + object encoding: tenumedit + frame.caption = 'Encoding' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.button.color = -2147483646 + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + end> + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + bounds_x = 151 + bounds_y = 0 + bounds_cx = 92 + bounds_cy = 37 + dropdown.options = [deo_selectonly, deo_forceselect, deo_autodropdown, deo_keydropdown] + dropdown.cols.count = 1 + dropdown.cols.items = < + item + data = ( + 'Locale' + 'utf8' + 'iso8859-1' + ) + end> + value = 0 + onsetvalue = encodingsetvalue + reffontheight = 14 + end + object backupfilecount: tintegeredit + frame.caption = 'Backup file count' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 74 + 0 + ) + taborder = 3 + bounds_x = 407 + bounds_y = 0 + bounds_cx = 110 + bounds_cy = 37 + value = 2 + valuemax = 10 + reffontheight = 14 + end + end + end + end + object ttabpage22: ttabpage + frame.localprops = [] + frame.localprops1 = [] + taborder = 1 + bounds_x = 0 + bounds_y = 19 + bounds_cx = 830 + bounds_cy = 511 + anchors = [an_left, an_top, an_right, an_bottom] + caption = 'Form' + object componenthints: tbooleanedit + frame.caption = 'Component hints' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 1 + 110 + 2 + ) + taborder = 6 + bounds_x = 511 + bounds_y = 18 + bounds_cx = 123 + bounds_cy = 16 + end + object noformdesignerdocking: tbooleanedit + frame.caption = 'Docking' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 1 + 53 + 2 + ) + taborder = 4 + bounds_x = 359 + bounds_y = 18 + bounds_cx = 66 + bounds_cy = 16 + options = [bo_executeonclick, bo_executeonkey, bo_executeonshortcut, bo_executedefaultonenterkey, bo_reversed] + end + object moveonfirstclick: tbooleanedit + frame.caption = 'Move on first click' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 1 + 114 + 2 + ) + taborder = 5 + bounds_x = 359 + bounds_y = 42 + bounds_cx = 127 + bounds_cy = 16 + value = True + end + object gridsizey: tintegeredit + frame.caption = 'Grid size Y' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 29 + 0 + ) + taborder = 3 + bounds_x = 247 + bounds_y = 18 + bounds_cx = 65 + bounds_cy = 37 + value = 8 + valuemin = 1 + valuemax = 1000 + reffontheight = 14 + end + object gridsizex: tintegeredit + frame.caption = 'Grid size X' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 29 + 0 + ) + taborder = 2 + bounds_x = 151 + bounds_y = 18 + bounds_cx = 65 + bounds_cy = 37 + value = 8 + valuemin = 1 + valuemax = 1000 + reffontheight = 14 + object tintegeredit2: tintegeredit + frame.caption = 'Grid size X' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 29 + 0 + ) + bounds_x = 136 + bounds_y = 29 + bounds_cx = 65 + bounds_cy = 37 + reffontheight = 14 + end + end + object snaptogrid: tbooleanedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_destroywidgets, ow_hinton] + frame.caption = 'Snap to Grid' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 1 + 81 + 2 + ) + taborder = 1 + hint = 'Hint:'#10'Use Ctrl + arrow keys to move selected components without grid snap,'#10'use Shift + arrow keys to resize selected components without grid snap.' + bounds_x = 7 + bounds_y = 42 + bounds_cx = 94 + bounds_cy = 16 + value = True + end + object showgrid: tbooleanedit + frame.caption = 'Show Grid' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 1 + 65 + 2 + ) + bounds_x = 7 + bounds_y = 18 + bounds_cx = 78 + bounds_cy = 16 + value = True + end + end + end + end + object debuggerpage: ttabpage + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_mousewheel, ow_destroywidgets] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 4 + bounds_x = 1 + bounds_y = 20 + bounds_cx = 830 + bounds_cy = 530 + anchors = [an_left, an_top, an_right, an_bottom] + caption = '&Debugger' + onlayout = debuggerlayoutexe + object debugcommand: tfilenameedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.options = [cfo_fixtop] + frame.caption = '&Debug command' + frame.captiontextflags = [tf_bottom] + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + onshowhint = hintexpandedmacros + bounds_x = 1 + bounds_y = 57 + bounds_cx = 302 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + controller.options = [fdo_quotesingle] + controller.historymaxcount = 0 + controller.ongetfilename = expandfilename + reffontheight = 14 + end + object debugoptions: tmemodialogedit + frame.options = [cfo_fixtop] + frame.caption = 'Debug &options' + frame.captiontextflags = [tf_bottom] + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + imagenr = 17 + end> + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + hint = '"--tty DEVICE" to set target terminal' + onshowhint = hintexpandedmacros + bounds_x = 306 + bounds_y = 57 + bounds_cx = 523 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + reffontheight = 14 + end + object ttabwidget1: ttabwidget + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + optionswidget1 = [ow1_fontglyphheight] + bounds_x = 0 + bounds_y = 204 + bounds_cx = 830 + bounds_cy = 326 + anchors = [an_left, an_top, an_right, an_bottom] + taborder = 6 + activepageindex = 0 + tab_frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + tab_frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + tab_face.localprops = [fal_frameimageoffset] + tab_color = -2147483645 + tab_size = 19 + statfile = statfile1 + reffontheight = 14 + object ttabpage6: ttabpage + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 4 + bounds_x = 0 + bounds_y = 19 + bounds_cx = 830 + bounds_cy = 307 + anchors = [an_left, an_top, an_right, an_bottom] + caption = 'Source &directories' + reffontheight = 14 + object sourcedirgrid: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + color = -2147483645 + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + bounds_x = 0 + bounds_y = 24 + bounds_cx = 830 + bounds_cy = 283 + bounds_cymin = 40 + anchors = [an_top, an_bottom] + optionsgrid = [og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_selectedrowsdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_wrapcol, og_autopopup] + datacols.count = 1 + datacols.options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[sourcedirs] + linecolorfix = -1610612733 + width = 825 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savevalue, co_cancopy, co_canpaste, co_mousescrollrow] + onshowhint = colonshowhint + widgetname = 'sourcedirs' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + reffontheight = 14 + object sourcedirs: tfilenameedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 1 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 825 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + controller.include = [fa_dir, fa_all] + controller.options = [fdo_directory] + controller.historymaxcount = 0 + controller.captionopen = 'Select source directory' + controller.ongetfilename = expandfilename + reffontheight = 14 + end + end + object sourcebase: tfilenameedit + frame.caption = 'Object &Base Directory (empty = Make Directory)' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + imagenr = 17 + end> + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 0 + 301 + 0 + ) + taborder = 1 + onshowhint = sourcedirhint + bounds_x = 1 + bounds_y = 2 + bounds_cx = 827 + anchors = [an_left, an_top, an_right] + textflags = [tf_noselect, tf_ellipseleft] + controller.options = [fdo_directory] + controller.captionopen = 'Select source base directory' + controller.ongetfilename = expandfilename + reffontheight = 14 + end + object tspacer7: tspacer + taborder = 2 + bounds_x = 527 + bounds_y = 22 + bounds_cx = 50 + bounds_cy = 2 + linktop = sourcebase + linkbottom = sourcedirgrid + end + end + object ttabpage9: ttabpage + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 1 + bounds_x = 0 + bounds_y = 19 + bounds_cx = 830 + bounds_cy = 307 + anchors = [an_left, an_top, an_right, an_bottom] + caption = 'Defi&nes' + reffontheight = 14 + object twidgetgrid2: twidgetgrid + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 830 + bounds_cy = 307 + anchors = [] + optionsgrid = [og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_colchangeontabkey, og_wrapcol, og_autopopup] + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 2 + captions.items = < + item + caption = 'on' + end + item + caption = 'Space separated defines for {$ifdef}' + end> + end> + datacols.count = 2 + datacols.options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[defineson] + width = 22 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'defineson' + dataclass = tgridintegerdatalist + end + item[defines] + width = 802 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + onshowhint = colonshowhint + widgetname = 'defines' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + reffontheight = 14 + object defineson: tbooleanedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_mousewheel, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 22 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate, oe1_checkvalueafterstatread] + visible = False + valuedefault = True + end + object defines: tstringedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_mousewheel, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 2 + visible = False + bounds_x = 23 + bounds_y = 0 + bounds_cx = 802 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + end + end + object ttabpage7: ttabpage + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 3 + bounds_x = 0 + bounds_y = 19 + bounds_cx = 830 + bounds_cy = 307 + anchors = [an_left, an_top, an_right, an_bottom] + caption = '&Signals' + reffontheight = 14 + object signalgrid: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + color = -2147483645 + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 830 + bounds_cy = 307 + bounds_cymin = 40 + anchors = [] + optionsgrid = [og_colsizing, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_sorted, og_wrapcol, og_autopopup] + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 5 + captions.items = < + item + caption = 'Stop' + end + item + caption = 'Handle' + end + item + caption = 'Signum' + end + item + caption = '.. to' + end + item + caption = 'Name' + textflags = [tf_ycentered] + end> + end> + datacols.count = 5 + datacols.options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_nosort, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[sigstop] + width = 32 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_nosort, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'sigstop' + dataclass = tgridintegerdatalist + end + item[sighandle] + width = 43 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_nosort, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'sighandle' + dataclass = tgridintegerdatalist + end + item[signum] + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savevalue, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'signum' + dataclass = tgridintegerdatalist + end + item[signumto] + width = 39 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savevalue, co_savestate, co_nosort, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'signumto' + dataclass = tgridintegerdatalist + end + item[signame] + width = 657 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savevalue, co_savestate, co_nosort, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'signame' + dataclass = tgridenumdatalist + end> + datarowheight = 16 + reffontheight = 14 + object sigstop: tbooleanedit + optionswidget1 = [] + optionsskin = [osk_framebuttononly] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 32 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + value = True + valuedefault = True + end + object sighandle: tbooleanedit + optionswidget1 = [] + optionsskin = [osk_framebuttononly] + taborder = 2 + bounds_x = 33 + bounds_y = 0 + bounds_cx = 43 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + end + object signum: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 3 + visible = False + bounds_x = 77 + bounds_y = 0 + bounds_cx = 50 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + onsetvalue = signumonsetvalue + valuemax = 255 + reffontheight = 14 + end + object signumto: tintegeredit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 4 + visible = False + bounds_x = 128 + bounds_y = 0 + bounds_cx = 39 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + onsetvalue = signumtoonsetvalue + valuemax = 255 + reffontheight = 14 + end + object signame: tselector + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.button.color = -1879048187 + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + end> + taborder = 5 + visible = False + bounds_x = 168 + bounds_y = 0 + bounds_cx = 657 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + dropdownitems.count = 2 + dropdownitems.items = < + item + end + item + end> + onsetvalue = signameonsetvalue + dropdown.cols.count = 1 + dropdown.cols.items = < + item + width = 100 + end> + reffontheight = 14 + end + end + end + object ttabpage8: ttabpage + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 2 + bounds_x = 0 + bounds_y = 19 + bounds_cx = 830 + bounds_cy = 307 + anchors = [an_left, an_top, an_right, an_bottom] + caption = '&Exceptions' + reffontheight = 14 + object exceptionsgrid: twidgetgrid + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 830 + bounds_cy = 307 + anchors = [] + optionsgrid = [og_colsizing, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_colchangeontabkey, og_wrapcol, og_autopopup] + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 2 + captions.items = < + item + caption = 'ignore' + end + item + caption = 'Exception class' + end> + end> + datacols.count = 2 + datacols.options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[exceptignore] + width = 47 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste] + widgetname = 'exceptignore' + dataclass = tgridintegerdatalist + end + item[exceptclassnames] + width = 777 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savestate, co_cancopy, co_canpaste] + widgetname = 'exceptclassnames' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + statfile = statfile1 + reffontheight = 14 + object exceptignore: tbooleanedit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 47 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + end + object exceptclassnames: tstringedit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 2 + visible = False + bounds_x = 48 + bounds_y = 0 + bounds_cx = 777 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_trimright, oe_trimleft] + reffontheight = 14 + end + end + end + object ttabpage16: ttabpage + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 5 + bounds_x = 0 + bounds_y = 19 + bounds_cx = 830 + bounds_cy = 307 + anchors = [an_left, an_top, an_right, an_bottom] + taborderoverride.items = ( + 'uploadcommand' + 'gdbloadtimeout' + 'gdbloadtimeout' + 'gdbservercommand' + 'gdbservercommand' + 'gdbserverwait' + 'gdbserverstartonce' + 'gdbservercommandattach' + 'gdbservercommandattach' + 'nogdbserverexit' + ) + caption = '&Target' + onlayout = debugtargetlayoutev + reffontheight = 14 + object remoteconnection: tstringedit + frame.caption = 'Target connection' + frame.captiontextflags = [tf_bottom] + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + hint = '"--tty DEVICE" to set target terminal' + onshowhint = hintexpandedmacros + bounds_x = 1 + bounds_y = 112 + bounds_cx = 828 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + reffontheight = 14 + end + object tlayouter4: tlayouter + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 2 + bounds_x = 0 + bounds_y = 192 + bounds_cx = 830 + bounds_cy = 37 + anchors = [an_top] + optionsscale = [osc_expandy, osc_shrinky] + optionslayout = [lao_aligny] + align_glue = wam_start + linkbottom = tlayouter5 + object beforeconnect: tfilenameedit + frame.caption = 'Before connect gdb script' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + onshowhint = hintexpandedmacros + bounds_x = 1 + bounds_y = 0 + bounds_cx = 214 + bounds_cy = 37 + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + controller.filterlist.data = ( + ( + 'gdb Scripts' + '*.gdb' + ) + ) + controller.options = [fdo_checkexist, fdo_savelastdir] + reffontheight = 14 + end + object tsplitter7: tsplitter + color = -1879048189 + taborder = 1 + visible = False + bounds_x = 215 + bounds_y = 17 + bounds_cx = 3 + bounds_cy = 20 + options = [spo_hprop, spo_dockleft, spo_docktop, spo_dockright, spo_dockbottom] + linkleft = beforeconnect + linkright = beforeload + end + object beforeload: tfilenameedit + frame.caption = 'Before load gdb script' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + onshowhint = hintexpandedmacros + bounds_x = 218 + bounds_y = 0 + bounds_cx = 221 + bounds_cy = 37 + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + controller.filterlist.data = ( + ( + 'gdb Scripts' + '*.gdb' + ) + ) + controller.options = [fdo_checkexist, fdo_savelastdir] + reffontheight = 14 + end + object tsplitter9: tsplitter + color = -1879048189 + taborder = 3 + visible = False + bounds_x = 439 + bounds_y = 17 + bounds_cx = 3 + bounds_cy = 20 + options = [spo_hprop, spo_dockleft, spo_docktop, spo_dockright, spo_dockbottom] + linkleft = beforeload + linkright = beforerun + end + object beforerun: tfilenameedit + frame.caption = 'Before run gdb script' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 4 + onshowhint = hintexpandedmacros + bounds_x = 442 + bounds_y = 0 + bounds_cx = 387 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + controller.filterlist.data = ( + ( + 'gdb Scripts' + '*.gdb' + ) + ) + controller.options = [fdo_checkexist, fdo_savelastdir] + reffontheight = 14 + end + end + object tlayouter5: tlayouter + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 3 + bounds_x = 0 + bounds_y = 243 + bounds_cx = 830 + bounds_cy = 37 + anchors = [an_top] + optionsscale = [osc_expandy, osc_shrinky] + optionslayout = [lao_aligny] + align_glue = wam_start + object afterconnect: tfilenameedit + frame.caption = 'After connect gdb script' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + onshowhint = hintexpandedmacros + bounds_x = 1 + bounds_y = 0 + bounds_cx = 214 + bounds_cy = 37 + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + controller.filterlist.data = ( + ( + 'gdb Scripts' + '*.gdb' + ) + ) + controller.options = [fdo_checkexist, fdo_savelastdir] + reffontheight = 14 + end + object tsplitter8: tsplitter + color = -1879048189 + taborder = 1 + visible = False + bounds_x = 215 + bounds_y = 17 + bounds_cx = 3 + bounds_cy = 20 + options = [spo_hprop, spo_dockleft, spo_docktop, spo_dockright, spo_dockbottom] + linkleft = afterconnect + linkright = afterload + end + object afterload: tfilenameedit + frame.caption = 'After load gdb script' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + onshowhint = hintexpandedmacros + bounds_x = 218 + bounds_y = 0 + bounds_cx = 221 + bounds_cy = 37 + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + controller.filterlist.data = ( + ( + 'gdb Scripts' + '*.gdb' + ) + ) + controller.options = [fdo_checkexist, fdo_savelastdir] + reffontheight = 14 + end + object tsplitter10: tsplitter + color = -1879048189 + taborder = 3 + visible = False + bounds_x = 439 + bounds_y = 17 + bounds_cx = 3 + bounds_cy = 20 + options = [spo_hprop, spo_dockleft, spo_docktop, spo_dockright, spo_dockbottom] + linkleft = afterload + end + end + object tlayouter3: tlayouter + color = -2147483645 + frame.framei_left = 1 + frame.localprops = [frl_fileft, frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 1 + bounds_x = 0 + bounds_y = 149 + bounds_cx = 618 + bounds_cy = 43 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + optionslayout = [lao_placex, lao_aligny] + align_glue = wam_start + place_mindist = 5 + place_maxdist = 5 + linktop = remoteconnection + linkbottom = tlayouter4 + object gdbprocessor: tdropdownlistedit + frame.options = [cfo_fixtop] + frame.caption = 'Processor' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.button.color = -2147483646 + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + end> + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + onshowhint = hintexpandedmacros + bounds_x = 1 + bounds_y = 0 + bounds_cx = 84 + bounds_cy = 37 + onchange = processorchange + value = 'i386' + dropdown.options = [deo_autodropdown, deo_keydropdown] + dropdown.cols.count = 1 + dropdown.cols.items = < + item + data = ( + 'auto' + 'i386' + 'x86_64' + 'arm' + 'armm3' + 'cpu32' + 'avr32' + 'rl78' + ) + end> + reffontheight = 14 + end + object gdbsimulator: tbooleanedit + frame.caption = 'Simulator' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 1 + 62 + 2 + ) + taborder = 1 + bounds_x = 90 + bounds_y = 20 + bounds_cx = 75 + bounds_cy = 16 + onchange = downloadchange + end + object gdbdownload: tbooleanedit + frame.caption = 'gdb download' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 1 + 91 + 2 + ) + taborder = 2 + bounds_x = 170 + bounds_y = 20 + bounds_cx = 104 + bounds_cy = 16 + onchange = downloadchange + end + object downloadalways: tbooleanedit + frame.caption = 'Always download'#10'before run' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 8 + 108 + 9 + ) + taborder = 3 + bounds_x = 279 + bounds_y = 13 + bounds_cx = 121 + bounds_cy = 30 + end + object startupbkpt: tintegeredit + frame.options = [cfo_fixtop] + frame.caption = 'Startup BKPT' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 5 + bounds_x = 500 + bounds_y = 0 + bounds_cy = 37 + base = nb_hex + valuemax = -1 + reffontheight = 14 + end + object startupbkpton: tbooleanedit + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 6 + bounds_x = 605 + bounds_y = 21 + onchange = downloadchange + end + object restartgdbbeforeload: tbooleanedit + frame.caption = 'Restart gdb'#10'before load' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 8 + 77 + 9 + ) + taborder = 4 + bounds_x = 405 + bounds_y = 13 + bounds_cx = 90 + bounds_cy = 30 + end + end + object downloadlayouter: tlayouter + taborder = 4 + bounds_x = 1 + bounds_y = 1 + bounds_cx = 609 + bounds_cy = 111 + anchors = [an_left, an_top, an_right] + optionsscale = [osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_placey] + place_maxdist = 0 + linkright = texpandingwidget1 + linkbottom = remoteconnection + dist_right = 2 + options = [spao_glueright] + object gdbservercommandattach: tfilenameedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.options = [cfo_fixtop] + frame.caption = 'Start gdb server command attach target' + frame.captiontextflags = [tf_bottom] + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + onshowhint = hintexpandedmacros + bounds_x = 0 + bounds_y = 74 + bounds_cx = 609 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + controller.options = [fdo_params] + controller.historymaxcount = 0 + reffontheight = 14 + end + object gdbservercommand: tfilenameedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.options = [cfo_fixtop] + frame.caption = 'Start gdb server command run target' + frame.captiontextflags = [tf_bottom] + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + onshowhint = hintexpandedmacros + bounds_x = 0 + bounds_y = 37 + bounds_cx = 609 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + controller.options = [fdo_params] + controller.historymaxcount = 0 + reffontheight = 14 + end + object uploadcommand: tfilenameedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.options = [cfo_fixtop] + frame.caption = 'Download command' + frame.captiontextflags = [tf_bottom] + frame.captionoffset = 3 + frame.font.name = 'stf_default' + frame.font.xscale = 1 + frame.font.localprops = [flp_xscale] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + onshowhint = hintexpandedmacros + bounds_x = 0 + bounds_y = 0 + bounds_cx = 609 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + controller.options = [fdo_params] + controller.historymaxcount = 0 + reffontheight = 14 + end + end + object texpandingwidget1: texpandingwidget + taborder = 5 + bounds_x = 612 + bounds_y = 1 + bounds_cx = 214 + bounds_cy = 111 + anchors = [an_top, an_right] + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + object gdbloadtimeout: trealedit + frame.options = [cfo_fixtop] + frame.caption = 'Load Timeout' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 14 + 0 + ) + bounds_x = 0 + bounds_y = 0 + bounds_cx = 86 + bounds_cy = 37 + value = -Inf + valuedefault = -Inf + formatedit = '0.#' + formatdisp = '0.#sec' + valuerange = 1 + valuestart = 0 + valuemin = -Inf + valuemax = 200 + reffontheight = 14 + end + object serverla: tlayouter + color = -2147483645 + frame.framei_left = 1 + frame.localprops = [frl_fileft, frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 1 + bounds_x = 0 + bounds_y = 37 + bounds_cx = 214 + bounds_cy = 37 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_placex, lao_aligny] + align_glue = wam_start + place_mindist = 2 + place_maxdist = 2 + place_options = [plo_endmargin] + linktop = gdbloadtimeout + object gdbserverwait: trealedit + frame.caption = 'Wait before connect' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 58 + 0 + ) + bounds_x = 1 + bounds_y = 0 + bounds_cx = 129 + bounds_cy = 37 + anchors = [an_top, an_right] + value = 0 + valuedefault = -Inf + formatedit = '0.#' + formatdisp = '0.#sec' + valuerange = 1 + valuestart = 0 + valuemin = 0 + valuemax = 200 + reffontheight = 14 + end + object gdbserverstartonce: tbooleanedit + frame.caption = 'Start once' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 69 + 2 + ) + taborder = 1 + bounds_x = 132 + bounds_y = 20 + bounds_cx = 82 + bounds_cy = 16 + end + end + object tlayouter2: tlayouter + color = -2147483645 + frame.framei_left = 1 + frame.framei_right = 2 + frame.localprops = [frl_fileft, frl_firight] + frame.localprops1 = [] + taborder = 2 + bounds_x = 0 + bounds_y = 74 + bounds_cx = 164 + bounds_cy = 37 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_placex, lao_aligny] + align_glue = wam_start + place_mindist = 2 + place_maxdist = 2 + place_options = [plo_noinvisible] + linktop = serverla + object nogdbserverexit: tbooleanedit + frame.caption = 'no wait for exit' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 95 + 2 + ) + bounds_x = 1 + bounds_y = 20 + bounds_cx = 108 + bounds_cy = 16 + anchors = [an_top, an_right] + end + object gdbservertty: tbooleanedit + frame.caption = 'TTY' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 24 + 2 + ) + taborder = 1 + bounds_x = 111 + bounds_y = 20 + bounds_cx = 37 + bounds_cy = 16 + end + object tstringedit1: tstringedit + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_invisibleparentsizeextend] + frame.caption = 'a' + frame.captiontextflags = [tf_bottom] + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + visible = False + bounds_x = 150 + bounds_y = 0 + bounds_cx = 12 + bounds_cy = 37 + reffontheight = 14 + end + end + end + end + end + object tlayouter1: tlayouter + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 5 + bounds_x = 7 + bounds_y = 164 + bounds_cx = 744 + bounds_cy = 30 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + optionslayout = [lao_placex, lao_aligny] + align_glue = wam_start + place_mindist = 10 + place_maxdist = 10 + place_options = [plo_noinvisible] + linkbottom = ttabwidget1 + dist_bottom = 10 + object externalconsole: tbooleanedit + frame.caption = '&External'#10'Console' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 8 + 54 + 9 + ) + taborder = 7 + bounds_x = 620 + bounds_y = 0 + bounds_cx = 67 + bounds_cy = 30 + onchange = updatedebugenabled + end + object showconsole: tbooleanedit + frame.caption = 'Show &Cons.'#10'on Run' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 8 + 75 + 9 + ) + taborder = 5 + hint = 'Show console on run' + bounds_x = 475 + bounds_y = 0 + bounds_cx = 88 + bounds_cy = 30 + end + object stoponexception: tbooleanedit + frame.caption = '&Stop'#10'on Excep.' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 8 + 64 + 9 + ) + taborder = 4 + hint = 'Stop on exceptions' + bounds_x = 388 + bounds_y = 0 + bounds_cx = 77 + bounds_cy = 30 + end + object activateonbreak: tbooleanedit + frame.caption = '&Activate'#10'on Break' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 8 + 59 + 9 + ) + taborder = 1 + bounds_x = 61 + bounds_y = 0 + bounds_cx = 72 + bounds_cy = 30 + onsetvalue = activateonbreakset + end + object valuehints: tbooleanedit + frame.caption = '&Value'#10'Hints' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 8 + 38 + 9 + ) + bounds_x = 0 + bounds_y = 0 + bounds_cx = 51 + bounds_cy = 30 + end + object nodebugbeginend: tbooleanedit + frame.caption = 'Call GUI_DEBUGBEGIN/'#10'GUI_DEBUGEND' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 8 + 140 + 9 + ) + taborder = 3 + hint = 'Release mouse grab by target stop. gdb sometimes crashes with this option.' + bounds_x = 225 + bounds_y = 0 + bounds_cx = 153 + bounds_cy = 30 + options = [bo_executeonclick, bo_executeonkey, bo_executeonshortcut, bo_executedefaultonenterkey, bo_reversed] + end + object settty: tbooleanedit + frame.caption = 'Set'#10'TT&Y' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 8 + 24 + 9 + ) + taborder = 6 + bounds_x = 573 + bounds_y = 0 + bounds_cx = 37 + bounds_cy = 30 + visible = False + end + object raiseonbreak: tbooleanedit + frame.caption = '&Raise'#10'on Break' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 8 + 59 + 9 + ) + taborder = 2 + bounds_x = 143 + bounds_y = 0 + bounds_cx = 72 + bounds_cy = 30 + end + object fpcgdbworkaround: tbooleanedit + frame.caption = '&FPC'#10'bugs' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 8 + 34 + 9 + ) + taborder = 8 + hint = 'Use workarounds for FPC/gdb bugs' + bounds_x = 697 + bounds_y = 0 + bounds_cx = 47 + bounds_cy = 30 + end + end + object debugtarget: tfilenameedit + frame.options = [cfo_fixtop, cfo_autowidth] + frame.caption = 'Debug &target (empty = make targetfile)' + frame.captiontextflags = [tf_bottom] + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 3 + onshowhint = hintexpandedmacros + bounds_x = 1 + bounds_y = 104 + bounds_cx = 302 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + controller.options = [] + controller.historymaxcount = 0 + controller.ongetfilename = expandfilename + reffontheight = 14 + end + object debugtargetsplitter: tsplitter + color = -1879048189 + taborder = 7 + visible = False + bounds_x = 303 + bounds_y = 109 + bounds_cx = 3 + bounds_cy = 34 + options = [spo_hprop, spo_dockleft, spo_docktop, spo_dockright, spo_dockbottom] + linkleft = debugtarget + linkright = xtermcommand + end + object xtermcommand: tmemodialogedit + frame.caption = 'xterm command' + frame.captiontextflags = [tf_bottom, tf_grayed] + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + imagenr = 17 + end> + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 4 + onshowhint = hintexpandedmacros + enabled = False + bounds_x = 306 + bounds_y = 104 + bounds_cx = 523 + bounds_cy = 37 + anchors = [an_top, an_right] + onsetvalue = setxtermcommandexe + reffontheight = 14 + end + object debugsplitter: tsplitter + color = -1879048189 + taborder = 8 + visible = False + bounds_x = 303 + bounds_y = 69 + bounds_cx = 3 + bounds_cy = 26 + options = [spo_hprop, spo_dockleft, spo_docktop, spo_dockright, spo_dockbottom] + linkleft = debugcommand + linkright = debugoptions + end + object runcommand: tfilenameedit + frame.options = [cfo_fixtop, cfo_autowidth] + frame.caption = '&Run command (empty = start debugger)' + frame.captiontextflags = [tf_bottom] + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + onshowhint = hintexpandedmacros + bounds_x = 1 + bounds_y = 21 + bounds_cx = 828 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + onchange = updatedebugenabled + controller.options = [fdo_params] + controller.historymaxcount = 0 + controller.ongetfilename = expandfilename + reffontheight = 14 + end + end + object makepage: ttabpage + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_mousewheel, ow_destroywidgets] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 6 + bounds_x = 1 + bounds_y = 20 + bounds_cx = 830 + bounds_cy = 530 + anchors = [an_top, an_bottom] + caption = '&Make' + onlayout = makepageonchildscaled + object tspacer2: tspacer + color = -2147483645 + taborder = 18 + bounds_x = 341 + bounds_y = 108 + bounds_cx = 10 + bounds_cy = 26 + linkleft = colornote + linkright = copymessages + end + object defaultmake: tenumedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.caption = 'Default make col' + frame.captiontextflags = [tf_bottom] + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.button.color = -2147483646 + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + end> + frame.outerframe = ( + 0 + 17 + 14 + 0 + ) + taborder = 11 + bounds_x = 1 + bounds_y = 123 + bounds_cx = 110 + bounds_cy = 37 + optionsedit1 = [oe1_autopopupmenu, oe1_savevalue, oe1_savestate] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + textflags = [tf_xcentered, tf_ycentered, tf_noselect] + dropdown.options = [deo_selectonly, deo_forceselect, deo_autodropdown] + dropdown.cols.count = 1 + dropdown.cols.items = < + item + data = ( + 'M (Make)' + 'B (Build)' + '1 (Make 1)' + '2 (Make 2)' + '3 (Make 3)' + '4 (Make 4)' + 'None' + ) + end> + value = 0 + reffontheight = 14 + end + object mainfile: tfilenameedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.caption = '&Mainfile' + frame.captiontextflags = [tf_bottom] + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + onshowhint = hintexpandedmacros + bounds_x = 1 + bounds_y = 2 + bounds_cx = 246 + bounds_cy = 37 + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + controller.options = [fdo_link] + controller.historymaxcount = 0 + controller.captionopen = 'Select mainfile' + controller.ongetfilename = expandfilename + reffontheight = 14 + end + object targetfile: tfilenameedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.caption = '&Targetfile' + frame.captiontextflags = [tf_bottom] + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + onshowhint = hintexpandedmacros + bounds_x = 250 + bounds_y = 2 + bounds_cx = 205 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + controller.options = [fdo_link] + controller.historymaxcount = 0 + controller.captionopen = 'Select target file' + controller.ongetfilename = expandfilename + reffontheight = 14 + end + object makecommand: tfilenameedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.caption = 'Make &Program' + frame.captiontextflags = [tf_bottom] + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 3 + onshowhint = hintexpandedmacros + bounds_x = 1 + bounds_y = 43 + bounds_cx = 246 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + controller.options = [] + controller.historymaxcount = 0 + controller.captionopen = 'Select make command' + controller.ongetfilename = expandfilename + reffontheight = 14 + end + object showcommandline: tbutton + optionswidget1 = [ow1_autowidth, ow1_autoheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + color = -2147483645 + taborder = 12 + bounds_x = 109 + bounds_y = 140 + bounds_cx = 134 + bounds_cy = 20 + state = [as_localcaption, as_localcolor, as_localonexecute] + caption = 'Show command line' + onexecute = showcommandlineonexecute + end + object messageoutputfile: tfilenameedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.caption = 'Message &output file' + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 5 + onshowhint = hintexpandedmacros + enabled = False + bounds_x = 458 + bounds_y = 43 + bounds_cx = 371 + bounds_cy = 37 + anchors = [an_top, an_right] + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + controller.ongetfilename = expandfilename + reffontheight = 14 + end + object copymessages: tbooleanedit + frame.caption = 'Copy messages to &file' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 1 + 140 + 2 + ) + taborder = 9 + bounds_x = 351 + bounds_y = 99 + bounds_cx = 153 + bounds_cy = 16 + onchange = copymessagechanged + end + object closemessages: tbooleanedit + frame.caption = 'Close messages window after compile' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 1 + 240 + 2 + ) + taborder = 14 + bounds_x = 257 + bounds_y = 151 + bounds_cx = 253 + bounds_cy = 16 + value = True + end + object checkmethods: tbooleanedit + frame.caption = 'Check method headers' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 1 + 149 + 2 + ) + taborder = 13 + bounds_x = 257 + bounds_y = 135 + bounds_cx = 162 + bounds_cy = 16 + value = True + end + object makegroupbox: ttabwidget + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + bounds_x = 0 + bounds_y = 187 + bounds_cx = 830 + bounds_cy = 345 + anchors = [an_top, an_bottom] + taborder = 15 + activepageindex = 1 + tab_frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + tab_frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + tab_face.localprops = [fal_frameimageoffset] + tab_color = -2147483645 + tab_size = 19 + statfile = statfile1 + reffontheight = 14 + object ttabpage17: ttabpage + frame.localprops = [] + frame.localprops1 = [] + taborder = 3 + bounds_x = 0 + bounds_y = 19 + bounds_cx = 830 + bounds_cy = 326 + anchors = [an_left, an_top, an_right, an_bottom] + caption = 'Command before' + object befcommandgrid: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + color = -2147483645 + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 830 + bounds_cy = 326 + bounds_cymin = 40 + anchors = [] + optionsgrid = [og_keyrowmoving, og_rowinserting, og_rowdeleting, og_selectedrowsdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_wrapcol, og_autopopup] + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 7 + captions.items = < + item + caption = 'M' + hint = 'Use in Make' + end + item + caption = 'B' + hint = 'Use in Build' + end + item + caption = '1' + hint = 'Use in Make 1' + end + item + caption = '2' + hint = 'Use in Make 2' + end + item + caption = '3' + hint = 'Use in Make 3' + end + item + caption = '4' + hint = 'Use in Make 4' + end + item + caption = 'Command' + end> + end> + datacols.count = 7 + datacols.options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[befmakeon] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'befmakeon' + dataclass = tgridintegerdatalist + end + item[befbuildon] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'befbuildon' + dataclass = tgridintegerdatalist + end + item[befmake1on] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'befmake1on' + dataclass = tgridintegerdatalist + end + item[befmake2on] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'befmake2on' + dataclass = tgridintegerdatalist + end + item[befmake3on] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'befmake3on' + dataclass = tgridintegerdatalist + end + item[befmake4on] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'befmake4on' + dataclass = tgridintegerdatalist + end + item[befcommand] + width = 741 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savevalue, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'befcommand' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + reffontheight = 14 + object befmakeon: tbooleanedit + Tag = 1 + optionsskin = [osk_framebuttononly] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object befbuildon: tbooleanedit + Tag = 2 + optionsskin = [osk_framebuttononly] + taborder = 2 + bounds_x = 14 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object befmake1on: tbooleanedit + Tag = 4 + optionsskin = [osk_framebuttononly] + taborder = 3 + bounds_x = 28 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object befmake2on: tbooleanedit + Tag = 8 + optionsskin = [osk_framebuttononly] + taborder = 4 + bounds_x = 42 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object befmake3on: tbooleanedit + Tag = 16 + optionsskin = [osk_framebuttononly] + taborder = 5 + bounds_x = 56 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object befmake4on: tbooleanedit + Tag = 32 + optionsskin = [osk_framebuttononly] + taborder = 6 + bounds_x = 70 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object befcommand: tmemodialogedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 7 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 84 + bounds_y = 0 + bounds_cx = 741 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + end + end + object ttabpage12: ttabpage + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + face.localprops = [fal_frameimageoffset] + taborder = 2 + bounds_x = 0 + bounds_y = 19 + bounds_cx = 830 + bounds_cy = 326 + anchors = [an_left, an_top, an_right, an_bottom] + caption = 'Make options' + reffontheight = 14 + object makeoptionsgrid: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + color = -2147483645 + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 830 + bounds_cy = 326 + bounds_cymin = 40 + anchors = [] + optionsgrid = [og_colsizing, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_selectedrowsdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_wrapcol, og_autopopup] + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 10 + captions.items = < + item + caption = 'Purpose' + end + item + caption = 'M' + hint = 'Use in Make' + end + item + caption = 'B' + hint = 'Use in Build' + end + item + caption = '1' + hint = 'Use in Make 1' + end + item + caption = '2' + hint = 'Use in Make 2' + end + item + caption = '3' + hint = 'Use in Make 3' + end + item + caption = '4' + hint = 'Use in Make 4' + end + item + caption = 'A' + hint = 'After mainfile' + end + item + caption = 'Command line options' + end + item + end> + end> + datacols.count = 9 + datacols.options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[makeoptpurpose] + width = 57 + options = [co_invisible, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savevalue, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'makeoptpurpose' + dataclass = tgridmsestringdatalist + datalist.facultative = True + end + item[makeon] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'makeon' + dataclass = tgridintegerdatalist + end + item[buildon] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'buildon' + dataclass = tgridintegerdatalist + end + item[make1on] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'make1on' + dataclass = tgridintegerdatalist + end + item[make2on] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'make2on' + dataclass = tgridintegerdatalist + end + item[make3on] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'make3on' + dataclass = tgridintegerdatalist + end + item[make4on] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'make4on' + dataclass = tgridintegerdatalist + end + item[optafter] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'optafter' + dataclass = tgridintegerdatalist + end + item[makeoptions] + width = 669 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_fill, co_savevalue, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + onshowhint = colonshowhint + widgetname = 'makeoptions' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + statfile = statfile1 + reffontheight = 14 + object makeoptpurpose: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 57 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + reffontheight = 14 + end + object makeon: tbooleanedit + Tag = 1 + optionsskin = [osk_framebuttononly] + taborder = 2 + bounds_x = 58 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object buildon: tbooleanedit + Tag = 2 + optionsskin = [osk_framebuttononly] + taborder = 3 + bounds_x = 72 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object make1on: tbooleanedit + Tag = 4 + optionsskin = [osk_framebuttononly] + taborder = 4 + bounds_x = 86 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object make2on: tbooleanedit + Tag = 8 + optionsskin = [osk_framebuttononly] + taborder = 5 + bounds_x = 100 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object make3on: tbooleanedit + Tag = 16 + optionsskin = [osk_framebuttononly] + taborder = 6 + bounds_x = 114 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object make4on: tbooleanedit + Tag = 32 + optionsskin = [osk_framebuttononly] + taborder = 7 + bounds_x = 128 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object optafter: tbooleanedit + Tag = 1073741824 + optionswidget1 = [] + optionsskin = [osk_framebuttononly] + taborder = 8 + bounds_x = 142 + bounds_y = 0 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate, oe1_checkvalueafterstatread] + visible = False + end + object makeoptions: tmemodialogedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 9 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 156 + bounds_y = 0 + bounds_cx = 669 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + end + end + object ttabpage11: ttabpage + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 1 + bounds_x = 0 + bounds_y = 19 + bounds_cx = 830 + bounds_cy = 326 + anchors = [an_left, an_top, an_right, an_bottom] + caption = 'Directories' + reffontheight = 14 + object unitdirgrid: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + frame.caption = 'Unit, include and library &directories' + frame.captiontextflags = [tf_bottom] + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + bounds_x = 0 + bounds_y = 46 + bounds_cx = 830 + bounds_cy = 280 + bounds_cymin = 40 + anchors = [an_top, an_bottom] + optionsgrid = [og_keyrowmoving, og_rowinserting, og_rowdeleting, og_selectedrowsdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_wrapcol, og_autopopup] + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 11 + captions.items = < + item + caption = 'M' + hint = 'Use in Make' + end + item + caption = 'B' + hint = 'Use in Build' + end + item + caption = '1' + hint = 'Use in Make 1' + end + item + caption = '2' + hint = 'Use in Make 2' + end + item + caption = '3' + hint = 'Use in Make 3' + end + item + caption = '4' + hint = 'Use in Make 4' + end + item + caption = 'U' + hint = 'Add to unit file search path' + end + item + caption = 'I' + hint = 'Add to include file search path' + end + item + caption = 'L' + hint = 'Add to library search path' + end + item + caption = 'O' + hint = 'Add to object file search path' + end + item + caption = 'Directory' + end> + end> + datacols.count = 11 + datacols.width = 13 + datacols.options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[dmakeon] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'dmakeon' + dataclass = tgridintegerdatalist + end + item[dbuildon] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'dbuildon' + dataclass = tgridintegerdatalist + end + item[dmake1on] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'dmake1on' + dataclass = tgridintegerdatalist + end + item[dmake2on] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'dmake2on' + dataclass = tgridintegerdatalist + end + item[dmake3on] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'dmake3on' + dataclass = tgridintegerdatalist + end + item[dmake4on] + linewidth = 2 + linecolorfix = -1610612733 + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'dmake4on' + dataclass = tgridintegerdatalist + end + item[duniton] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'duniton' + dataclass = tgridintegerdatalist + end + item[dincludeon] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'dincludeon' + dataclass = tgridintegerdatalist + end + item[dlibon] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'dlibon' + dataclass = tgridintegerdatalist + end + item[dobjon] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'dobjon' + dataclass = tgridintegerdatalist + end + item[unitdirs] + linecolorfix = -1610612733 + width = 684 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savevalue, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + onshowhint = colonshowhint + widgetname = 'unitdirs' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + reffontheight = 14 + object dmakeon: tbooleanedit + Tag = 1 + optionsskin = [osk_framebuttononly] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object dbuildon: tbooleanedit + Tag = 2 + optionsskin = [osk_framebuttononly] + taborder = 2 + bounds_x = 14 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object dmake1on: tbooleanedit + Tag = 4 + optionsskin = [osk_framebuttononly] + taborder = 3 + bounds_x = 28 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object dmake2on: tbooleanedit + Tag = 8 + optionsskin = [osk_framebuttononly] + taborder = 4 + bounds_x = 42 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object dmake3on: tbooleanedit + Tag = 16 + optionsskin = [osk_framebuttononly] + taborder = 5 + bounds_x = 56 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object dmake4on: tbooleanedit + Tag = 32 + optionsskin = [osk_framebuttononly] + taborder = 6 + bounds_x = 70 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object duniton: tbooleanedit + Tag = 65536 + optionsskin = [osk_framebuttononly] + taborder = 7 + bounds_x = 85 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object dincludeon: tbooleanedit + Tag = 131072 + optionsskin = [osk_framebuttononly] + taborder = 8 + bounds_x = 99 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object dlibon: tbooleanedit + Tag = 262144 + optionsskin = [osk_framebuttononly] + taborder = 9 + bounds_x = 113 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object dobjon: tbooleanedit + Tag = 524288 + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 10 + bounds_x = 127 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object unitdirs: tfilenameedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 11 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 141 + bounds_y = 0 + bounds_cx = 684 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + controller.options = [fdo_directory, fdo_file] + controller.historymaxcount = 0 + controller.captionopen = 'Select unit directory' + controller.ongetfilename = expandfilename + reffontheight = 14 + end + end + object tspacer1: tspacer + color = -2147483645 + taborder = 1 + bounds_x = 287 + bounds_y = 41 + bounds_cx = 50 + bounds_cy = 5 + linktop = tlayouter17 + linkbottom = unitdirgrid + end + object tlayouter17: tlayouter + taborder = 2 + bounds_x = 0 + bounds_y = 4 + bounds_cx = 830 + bounds_cy = 37 + anchors = [an_top] + optionsscale = [osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_placex, lao_aligny] + align_glue = wam_start + place_mindist = 4 + place_maxdist = 4 + object objpref: tstringedit + frame.caption = 'Obj pref. (-Fo)' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 4 + 0 + ) + onshowhint = hintexpandedmacros + bounds_x = 269 + bounds_y = 0 + bounds_cx = 88 + bounds_cy = 37 + reffontheight = 14 + end + object libpref: tstringedit + frame.caption = 'Lib pref.(-Fl)' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + onshowhint = hintexpandedmacros + bounds_x = 181 + bounds_y = 0 + bounds_cx = 84 + bounds_cy = 37 + reffontheight = 14 + end + object incpref: tstringedit + frame.caption = 'Inc pref.(-Fi)' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + onshowhint = hintexpandedmacros + bounds_x = 93 + bounds_y = 0 + bounds_cx = 84 + bounds_cy = 37 + reffontheight = 14 + end + object unitpref: tstringedit + frame.caption = 'Unit pref.(-Fu)' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 5 + 0 + ) + taborder = 3 + onshowhint = hintexpandedmacros + bounds_x = 0 + bounds_y = 0 + bounds_cx = 89 + bounds_cy = 37 + reffontheight = 14 + end + object reversepathorder: tbooleanedit + frame.caption = 'Reverse directory order' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 150 + 2 + ) + taborder = 4 + bounds_x = 391 + bounds_y = 20 + bounds_cx = 163 + bounds_cy = 16 + end + object tsimplewidget1: tsimplewidget + taborder = 5 + bounds_x = 361 + bounds_y = 22 + bounds_cx = 26 + bounds_cy = 10 + end + end + end + object ttabpage18: ttabpage + frame.localprops = [] + frame.localprops1 = [] + taborder = 4 + bounds_x = 0 + bounds_y = 19 + bounds_cx = 830 + bounds_cy = 326 + anchors = [an_left, an_top, an_right, an_bottom] + caption = 'Command after' + object aftcommandgrid: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + color = -2147483645 + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 830 + bounds_cy = 326 + bounds_cymin = 40 + anchors = [] + optionsgrid = [og_keyrowmoving, og_rowinserting, og_rowdeleting, og_selectedrowsdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_wrapcol, og_autopopup] + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 7 + captions.items = < + item + caption = 'M' + hint = 'Use in Make' + end + item + caption = 'B' + hint = 'Use in Build' + end + item + caption = '1' + hint = 'Use in Make 1' + end + item + caption = '2' + hint = 'Use in Make 2' + end + item + caption = '3' + hint = 'Use in Make 3' + end + item + caption = '4' + hint = 'Use in Make 4' + end + item + caption = 'Command' + end> + end> + datacols.count = 7 + datacols.options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[aftmakeon] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'aftmakeon' + dataclass = tgridintegerdatalist + end + item[aftbuildon] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'aftbuildon' + dataclass = tgridintegerdatalist + end + item[aftmake1on] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'aftmake1on' + dataclass = tgridintegerdatalist + end + item[aftmake2on] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'aftmake2on' + dataclass = tgridintegerdatalist + end + item[aftmake3on] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'aftmake3on' + dataclass = tgridintegerdatalist + end + item[aftmake4on] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'aftmake4on' + dataclass = tgridintegerdatalist + end + item[aftcommand] + width = 741 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savevalue, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'aftcommand' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + reffontheight = 14 + object aftmakeon: tbooleanedit + Tag = 1 + optionsskin = [osk_framebuttononly] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object aftbuildon: tbooleanedit + Tag = 2 + optionsskin = [osk_framebuttononly] + taborder = 2 + bounds_x = 14 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object aftmake1on: tbooleanedit + Tag = 4 + optionsskin = [osk_framebuttononly] + taborder = 3 + bounds_x = 28 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object aftmake2on: tbooleanedit + Tag = 8 + optionsskin = [osk_framebuttononly] + taborder = 4 + bounds_x = 42 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object aftmake3on: tbooleanedit + Tag = 16 + optionsskin = [osk_framebuttononly] + taborder = 5 + bounds_x = 56 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object aftmake4on: tbooleanedit + Tag = 32 + optionsskin = [osk_framebuttononly] + taborder = 6 + bounds_x = 70 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + valuedefault = True + end + object aftcommand: tmemodialogedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 7 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 84 + bounds_y = 0 + bounds_cx = 741 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + end + end + end + object targpref: tstringedit + frame.caption = 'Targ. pref. (-o)' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + onshowhint = hintexpandedmacros + bounds_x = 458 + bounds_y = 2 + bounds_cx = 371 + bounds_cy = 37 + anchors = [an_top, an_right] + reffontheight = 14 + end + object makedir: tfilenameedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.caption = 'Make &Directory' + frame.captiontextflags = [tf_bottom] + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 4 + onshowhint = hintexpandedmacros + bounds_x = 250 + bounds_y = 43 + bounds_cx = 205 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + controller.options = [fdo_directory] + controller.historymaxcount = 0 + controller.captionopen = 'Select make directory' + controller.ongetfilename = expandfilename + reffontheight = 14 + end + object tsplitter1: tsplitter + color = -1879048189 + taborder = 16 + visible = False + bounds_x = 247 + bounds_y = 61 + bounds_cx = 3 + bounds_cy = 20 + options = [spo_hprop, spo_dockleft, spo_docktop, spo_dockright, spo_dockbottom] + linkleft = makecommand + linkright = makedir + end + object tsplitter2: tsplitter + color = -1879048189 + taborder = 17 + visible = False + bounds_x = 247 + bounds_y = 20 + bounds_cx = 3 + bounds_cy = 20 + options = [spo_hprop, spo_dockleft, spo_docktop, spo_dockright, spo_dockbottom] + linkleft = mainfile + linkright = targetfile + end + object tsplitter4: tsplitter + color = -1879048189 + taborder = 19 + visible = False + bounds_x = 455 + bounds_y = 20 + bounds_cx = 3 + bounds_cy = 20 + options = [spo_hprop, spo_dockleft, spo_docktop, spo_dockright, spo_dockbottom] + linkleft = targetfile + linkright = targpref + end + object tsplitter5: tsplitter + color = -1879048189 + taborder = 20 + visible = False + bounds_x = 455 + bounds_y = 60 + bounds_cx = 3 + bounds_cy = 20 + options = [spo_hprop, spo_dockleft, spo_docktop, spo_dockright, spo_dockbottom] + linkleft = makedir + linkright = messageoutputfile + end + object colorerror: tcoloredit + frame.caption = 'Error Color' + frame.captiontextflags = [tf_bottom] + frame.localprops = [] + frame.localprops1 = [] + frame.button.options = [fbo_inactiveinvisible] + frame.buttons.count = 2 + frame.buttons.items = < + item + options = [fbo_inactiveinvisible] + end + item + imagenr = 17 + options = [fbo_inactiveinvisible] + end> + frame.buttonellipse.imagenr = 17 + frame.buttonellipse.options = [fbo_inactiveinvisible] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 6 + bounds_x = 1 + bounds_y = 87 + bounds_cx = 108 + bounds_cy = 37 + value = -1610612712 + reffontheight = 14 + end + object tspacer5: tspacer + taborder = 21 + bounds_x = 109 + bounds_y = 109 + bounds_cx = 8 + bounds_cy = 18 + linkleft = colorerror + linkright = colorwarning + end + object colorwarning: tcoloredit + frame.caption = 'Warning Color' + frame.captiontextflags = [tf_bottom] + frame.localprops = [] + frame.localprops1 = [] + frame.button.options = [fbo_inactiveinvisible] + frame.buttons.count = 2 + frame.buttons.items = < + item + options = [fbo_inactiveinvisible] + end + item + imagenr = 17 + options = [fbo_inactiveinvisible] + end> + frame.buttonellipse.imagenr = 17 + frame.buttonellipse.options = [fbo_inactiveinvisible] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 7 + bounds_x = 117 + bounds_y = 87 + bounds_cx = 108 + bounds_cy = 37 + value = -1610612717 + reffontheight = 14 + end + object tspacer6: tspacer + taborder = 22 + bounds_x = 225 + bounds_y = 109 + bounds_cx = 8 + bounds_cy = 18 + linkleft = colorwarning + linkright = colornote + end + object colornote: tcoloredit + frame.caption = 'Note Color' + frame.captiontextflags = [tf_bottom] + frame.localprops = [] + frame.localprops1 = [] + frame.button.options = [fbo_inactiveinvisible] + frame.buttons.count = 2 + frame.buttons.items = < + item + options = [fbo_inactiveinvisible] + end + item + imagenr = 17 + options = [fbo_inactiveinvisible] + end> + frame.buttonellipse.imagenr = 17 + frame.buttonellipse.options = [fbo_inactiveinvisible] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 8 + bounds_x = 233 + bounds_y = 87 + bounds_cx = 108 + bounds_cy = 37 + value = -1610612716 + reffontheight = 14 + end + object tspacer4: tspacer + color = -2147483645 + taborder = 23 + bounds_x = 341 + bounds_y = 92 + bounds_cx = 10 + bounds_cy = 26 + linkleft = colornote + linkright = stripmessageesc + end + object stripmessageesc: tbooleanedit + frame.caption = 'Strip ESC sequences' + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 1 + 133 + 2 + ) + taborder = 10 + bounds_x = 351 + bounds_y = 115 + bounds_cx = 146 + bounds_cy = 16 + end + end + object ttabpage1: ttabpage + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 3 + bounds_x = 1 + bounds_y = 20 + bounds_cx = 830 + bounds_cy = 530 + anchors = [an_left, an_top, an_right, an_bottom] + caption = 'M&acros' + onlayout = macronchildscaled + object macrogrid: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 1 + bounds_x = 0 + bounds_y = 124 + bounds_cx = 830 + bounds_cy = 405 + bounds_cymin = 40 + anchors = [an_top, an_bottom] + optionsgrid = [og_colsizing, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_selectedrowsdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_wrapcol, og_autopopup] + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 8 + captions.items = < + item + caption = '1' + end + item + caption = '2' + end + item + caption = '3' + end + item + caption = '4' + end + item + caption = '5' + end + item + caption = '6' + end + item + caption = 'Name' + end + item + caption = 'Value' + end> + end> + datacols.count = 8 + datacols.width = 13 + datacols.options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[e0] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'e0' + dataclass = tgridintegerdatalist + end + item[e1] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'e1' + dataclass = tgridintegerdatalist + end + item[e2] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'e2' + dataclass = tgridintegerdatalist + end + item[e3] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'e3' + dataclass = tgridintegerdatalist + end + item[e4] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'e4' + dataclass = tgridintegerdatalist + end + item[e5] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'e5' + dataclass = tgridintegerdatalist + end + item[macronames] + width = 146 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'macronames' + dataclass = tgridmsestringdatalist + end + item[macrovalues] + width = 594 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + onshowhint = colonshowhint + widgetname = 'macrovalues' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + statfile = statfile1 + reffontheight = 14 + object e0: tbooleanedit + Tag = 1 + optionsskin = [osk_framebuttononly] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + value = True + valuedefault = True + end + object e1: tbooleanedit + Tag = 2 + optionsskin = [osk_framebuttononly] + taborder = 2 + bounds_x = 14 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + value = True + valuedefault = True + end + object e2: tbooleanedit + Tag = 4 + optionsskin = [osk_framebuttononly] + taborder = 3 + bounds_x = 28 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + value = True + valuedefault = True + end + object e3: tbooleanedit + Tag = 8 + optionsskin = [osk_framebuttononly] + taborder = 4 + bounds_x = 42 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + value = True + valuedefault = True + end + object e4: tbooleanedit + Tag = 16 + optionsskin = [osk_framebuttononly] + taborder = 5 + bounds_x = 56 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + value = True + valuedefault = True + end + object e5: tbooleanedit + Tag = 32 + optionsskin = [osk_framebuttononly] + taborder = 6 + bounds_x = 70 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + value = True + valuedefault = True + end + object macronames: tstringedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 7 + visible = False + bounds_x = 84 + bounds_y = 0 + bounds_cx = 146 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + object macrovalues: tmemodialogedit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 8 + visible = False + bounds_x = 231 + bounds_y = 0 + bounds_cx = 594 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + end + object selectactivegroupgrid: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + frame.caption = 'Active group' + frame.captiontextflags = [tf_bottom] + frame.captionoffset = 3 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + bounds_x = 0 + bounds_y = 0 + bounds_cx = 830 + bounds_cy = 121 + bounds_cymin = 40 + anchors = [an_top] + optionsgrid = [og_rowmoving, og_keyrowmoving, og_focuscellonenter, og_wrapcol, og_autopopup] + fixcols.count = 1 + fixcols.items = < + item + width = 13 + numstart = 1 + numstep = 1 + end> + rowcount = 6 + datacols.count = 2 + datacols.options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[activemacroselect] + width = 14 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste] + widgetname = 'activemacroselect' + dataclass = tgridintegerdatalist + data = ( + ( + 0 + 0 + 0 + 0 + 0 + 0 + ) + ) + end + item[groupcomment] + width = 781 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savestate, co_cancopy, co_canpaste] + widgetname = 'groupcomment' + dataclass = tgridmsestringdatalist + data = ( + ( + '' + '' + '' + '' + '' + '' + ) + ) + end> + datarowheight = 16 + onrowsmoved = selectactiveonrowsmoved + reffontheight = 14 + object activemacroselect: tbooleaneditradio + optionsskin = [osk_framebuttononly] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 14 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + ondataentered = acttiveselectondataentered + visible = False + end + object groupcomment: tstringedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 2 + visible = False + bounds_x = 15 + bounds_y = 0 + bounds_cx = 781 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + end + object macrosplitter: tsplitter + color = -1879048189 + taborder = 2 + bounds_x = 0 + bounds_y = 121 + bounds_cx = 830 + bounds_cy = 3 + anchors = [an_top] + options = [spo_vmove, spo_vprop, spo_docktop, spo_dockbottom] + linktop = selectactivegroupgrid + linkbottom = macrogrid + statfile = statfile1 + end + end + object fontaliaspage: ttabpage + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 2 + bounds_x = 1 + bounds_y = 20 + bounds_cx = 830 + bounds_cy = 530 + anchors = [an_left, an_top, an_right, an_bottom] + caption = '&Font Alias' + object fontaliasgrid: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_focusbackonesc, ow_destroywidgets] + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 830 + bounds_cy = 530 + anchors = [] + optionsgrid = [og_colsizing, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_wrapcol, og_autopopup] + fixrows.count = 1 + fixrows.items = < + item + height = 15 + captions.count = 7 + captions.items = < + item + caption = 'Alias' + end + item + caption = 'Font name' + end + item + caption = 'Height' + end + item + caption = 'Width' + end + item + caption = 'Options' + end + item + caption = 'Xscale' + end + item + caption = 'Ancestor' + end> + end> + datacols.count = 7 + datacols.options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[fontalias] + width = 98 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + onshowhint = colonshowhint + widgetname = 'fontalias' + dataclass = tgridmsestringdatalist + end + item[fontname] + width = 451 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savestate, co_cancopy, co_canpaste] + onshowhint = colonshowhint + widgetname = 'fontname' + dataclass = tgridmsestringdatalist + end + item[fontheight] + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'fontheight' + dataclass = tgridintegerdatalist + end + item[fontwidth] + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'fontwidth' + dataclass = tgridintegerdatalist + end + item[fontoptions] + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + onshowhint = colonshowhint + widgetname = 'fontoptions' + dataclass = tgridmsestringdatalist + end + item[fontxscale] + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'fontxscale' + dataclass = tgridrealdatalist + end + item[fontancestors] + width = 70 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + onshowhint = colonshowhint + widgetname = 'fontancestors' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + statfile = statfile1 + reffontheight = 14 + object fontalias: tstringedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 1 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 98 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + object fontname: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 2 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 99 + bounds_y = 0 + bounds_cx = 451 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + object fontheight: tintegeredit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 3 + visible = False + bounds_x = 551 + bounds_y = 0 + bounds_cx = 50 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + object fontwidth: tintegeredit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 4 + visible = False + bounds_x = 602 + bounds_y = 0 + bounds_cx = 50 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + object fontoptions: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 5 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 653 + bounds_y = 0 + bounds_cx = 50 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + object fontxscale: trealedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 6 + visible = False + bounds_x = 704 + bounds_y = 0 + bounds_cx = 50 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + value = 1 + valuedefault = -Inf + valuerange = 1 + valuestart = 0 + valuemin = 0 + valuemax = 1E+038 + reffontheight = 14 + end + object fontancestors: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 7 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 755 + bounds_y = 0 + bounds_cx = 70 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + valuedefault = 'stf_default' + reffontheight = 14 + end + end + end + object ttabpage10: ttabpage + frame.framei_bottom = 0 + frame.localprops = [frl_fibottom, frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 7 + bounds_x = 1 + bounds_y = 20 + bounds_cx = 830 + bounds_cy = 530 + anchors = [an_left, an_top, an_right, an_bottom] + caption = 'User &Colors' + object tlayouter7: tlayouter + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 1 + bounds_x = 0 + bounds_y = 1013 + bounds_cx = 830 + bounds_cy = 42 + anchors = [an_bottom] + optionslayout = [lao_aligny] + align_glue = wam_center + object tbutton1: tbutton + optionswidget1 = [ow1_autowidth, ow1_autoheight] + color = -2147483645 + bounds_x = 15 + bounds_y = 11 + bounds_cx = 279 + bounds_cy = 20 + anchors = [an_left, an_bottom] + state = [as_localcaption, as_localcolor, as_localonexecute] + caption = 'Copy "setcolormapvalue" code to clipboard' + onexecute = copycolorcode + end + end + object colgrid: twidgetgrid + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 830 + bounds_cy = 530 + anchors = [] + optionsgrid = [og_rowmoving, og_keyrowmoving, og_focuscellonenter, og_colchangeontabkey, og_autopopup, og_mousescrollcol] + fixcols.count = 1 + fixcols.items = < + item + color = -1879048185 + width = 80 + textflags = [tf_ycentered] + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 3 + captions.items = < + item + end + item + caption = 'Color' + end + item + caption = 'Comment' + end> + captionsfix.count = 1 + captionsfix.items = < + item + caption = 'Name' + end> + end> + datacols.count = 3 + datacols.options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[coldi] + width = 22 + options = [co_readonly, co_nofocus, co_invisible, co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_mousescrollrow] + widgetname = 'coldi' + dataclass = tgridpointerdatalist + end + item[usercolors] + width = 97 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'usercolors' + dataclass = tgridenumdatalist + end + item[usercolorcomment] + width = 623 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widthmin = 100 + widgetname = 'usercolorcomment' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + reffontheight = 14 + object coldi: tpointeredit + optionsskin = [osk_framebuttononly] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 22 + bounds_cy = 16 + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + onpaintglyph = drawcol + end + object usercolors: tcoloredit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.button.color = -1879048187 + frame.buttons.count = 2 + frame.buttons.items = < + item + color = -1879048187 + end + item + color = -1879048187 + imagenr = 17 + end> + frame.buttonellipse.color = -1879048187 + frame.buttonellipse.imagenr = 17 + taborder = 2 + visible = False + bounds_x = 23 + bounds_y = 0 + bounds_cx = 97 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + value = 0 + valuedefault = 0 + onsetvalue = colsetvalue + reffontheight = 14 + end + object usercolorcomment: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 3 + visible = False + bounds_x = 121 + bounds_y = 0 + bounds_cx = 623 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + end + end + object ttabpage21: ttabpage + frame.localprops = [] + frame.localprops1 = [] + taborder = 10 + bounds_x = 1 + bounds_y = 20 + bounds_cx = 830 + bounds_cy = 530 + anchors = [an_left, an_top, an_right, an_bottom] + caption = 'F&ormat Macros' + tabhint = 'Used by formatfloatmse() and formatdatetimemse()' + object formatmacrogrid: twidgetgrid + frame.localprops = [] + frame.localprops1 = [] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 830 + bounds_cy = 530 + anchors = [] + optionsgrid = [og_focuscellonenter, og_autofirstrow, og_autoappend, og_savestate, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 2 + captions.items = < + item + caption = 'Name' + end + item + caption = 'Value' + end> + end> + datacols.count = 2 + datacols.options = [co_savestate, co_mousescrollrow] + datacols.items = < + item[formatmacronames] + width = 157 + options = [co_proportional, co_savestate, co_mousescrollrow] + onshowhint = colonshowhint + widgetname = 'formatmacronames' + dataclass = tgridmsestringdatalist + end + item[formatmacrovalues] + width = 667 + options = [co_fill, co_savestate, co_mousescrollrow] + onshowhint = colonshowhint + widgetname = 'formatmacrovalues' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + reffontheight = 14 + object formatmacronames: tstringedit + optionsskin = [osk_framebuttononly] + taborder = 1 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 157 + bounds_cy = 16 + optionsedit1 = [] + reffontheight = 14 + end + object formatmacrovalues: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 2 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 158 + bounds_y = 0 + bounds_cx = 667 + bounds_cy = 16 + optionsedit1 = [] + reffontheight = 14 + end + end + end + object ttabpage2: ttabpage + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 1 + bounds_x = 1 + bounds_y = 20 + bounds_cx = 830 + bounds_cy = 530 + anchors = [an_left, an_top, an_right, an_bottom] + caption = '&Templates' + object newfile: ttabwidget + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 830 + bounds_cy = 530 + anchors = [] + activepageindex = 0 + tab_frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + tab_frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + tab_color = -2147483645 + tab_size = 19 + statfile = statfile1 + reffontheight = 14 + object ttabpage3: ttabpage + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 3 + bounds_x = 0 + bounds_y = 19 + bounds_cx = 830 + bounds_cy = 511 + anchors = [an_left, an_top, an_right, an_bottom] + caption = 'New Project' + onlayout = newprojectchildscaled + reffontheight = 14 + object copygrid: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_focusbackonesc, ow_destroywidgets] + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + bounds_x = 0 + bounds_y = 86 + bounds_cx = 830 + bounds_cy = 423 + anchors = [an_top, an_bottom] + optionsgrid = [og_colsizing, og_keycolmoving, og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_colchangeontabkey, og_wrapcol, og_autopopup] + fixrows.count = 1 + fixrows.items = < + item + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + height = 16 + captions.count = 4 + captions.items = < + item + caption = 'L' + hint = 'Load file in editor' + end + item + caption = 'M' + hint = 'Expand macros' + end + item + caption = 'Copied Files' + end + item + caption = 'Destination' + end> + end> + datacols.count = 4 + datacols.options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savevalue, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[loadprojectfile] + width = 18 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste] + widgetname = 'loadprojectfile' + dataclass = tgridintegerdatalist + end + item[expandprojectfilemacros] + width = 18 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste] + widgetname = 'expandprojectfilemacros' + dataclass = tgridintegerdatalist + end + item[newprojectfiles] + width = 417 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savevalue, co_savestate, co_cancopy, co_canpaste] + onshowhint = colonshowhint + widgetname = 'newprojectfiles' + dataclass = tgridmsestringdatalist + end + item[newprojectfilesdest] + width = 369 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savevalue, co_savestate, co_cancopy, co_canpaste] + onshowhint = colonshowhint + widgetname = 'newprojectfilesdest' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + reffontheight = 14 + object loadprojectfile: tbooleanedit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 18 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + end + object expandprojectfilemacros: tbooleanedit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 2 + bounds_x = 19 + bounds_y = 0 + bounds_cx = 18 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + end + object newprojectfiles: tfilenameedit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 3 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 38 + bounds_y = 0 + bounds_cx = 417 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + controller.ongetfilename = expandfilename + reffontheight = 14 + end + object newprojectfilesdest: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 4 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 456 + bounds_y = 0 + bounds_cx = 369 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_trimright, oe_trimleft] + reffontheight = 14 + end + end + object scriptbeforecopy: tfilenameedit + optionsskin = [osk_framebuttononly] + frame.caption = 'Script before copy' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + onshowhint = hintexpandedmacros + bounds_x = 0 + bounds_y = 3 + bounds_cx = 830 + bounds_cy = 37 + anchors = [an_top] + controller.ongetfilename = expandfilename + reffontheight = 14 + end + object scriptaftercopy: tfilenameedit + optionsskin = [osk_framebuttononly] + frame.caption = 'Script after copy' + frame.captiontextflags = [tf_bottom] + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + onshowhint = hintexpandedmacros + bounds_x = 0 + bounds_y = 40 + bounds_cx = 830 + bounds_cy = 37 + anchors = [an_top] + controller.ongetfilename = expandfilename + reffontheight = 14 + end + end + object ttabpage4: ttabpage + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 2 + bounds_x = 0 + bounds_y = 19 + bounds_cx = 830 + bounds_cy = 511 + anchors = [an_left, an_top, an_right, an_bottom] + caption = 'New File' + reffontheight = 14 + object twidgetgrid1: twidgetgrid + color = -2147483645 + frame.localprops = [] + frame.localprops1 = [] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 830 + bounds_cy = 511 + anchors = [] + optionsgrid = [og_colsizing, og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixcols.count = 1 + fixcols.items = < + item + width = 27 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 5 + captions.items = < + item + caption = 'Kind' + end + item + caption = 'Filter' + end + item + caption = 'Ext' + end + item + caption = 'Source' + end + item + end> + end> + datacols.count = 4 + datacols.options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[newfinames] + width = 124 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + onshowhint = colonshowhint + widgetname = 'newfinames' + dataclass = tgridmsestringdatalist + end + item[newfifilters] + width = 110 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + onshowhint = colonshowhint + widgetname = 'newfifilters' + dataclass = tgridmsestringdatalist + end + item[newfiexts] + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + onshowhint = colonshowhint + widgetname = 'newfiexts' + dataclass = tgridmsestringdatalist + end + item[newfisources] + width = 510 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + onshowhint = colonshowhint + widgetname = 'newfisources' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + reffontheight = 14 + object newfinames: tstringedit + optionsskin = [osk_framebuttononly] + taborder = 1 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 124 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter] + reffontheight = 14 + end + object newfifilters: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 2 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 125 + bounds_y = 0 + bounds_cx = 110 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter] + reffontheight = 14 + end + object newfiexts: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 3 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 236 + bounds_y = 0 + bounds_cx = 50 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter] + reffontheight = 14 + end + object newfisources: tfilenameedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 4 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 287 + bounds_y = 0 + bounds_cx = 510 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter] + reffontheight = 14 + end + end + end + object ttabpage5: ttabpage + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + color = -2147483645 + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 1 + bounds_x = 0 + bounds_y = 19 + bounds_cx = 830 + bounds_cy = 511 + anchors = [an_left, an_top, an_right, an_bottom] + caption = 'New Form' + onlayout = formtemplateonchildscaled + reffontheight = 14 + object twidgetgrid4: twidgetgrid + color = -2147483645 + frame.localprops = [] + frame.localprops1 = [] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 830 + bounds_cy = 511 + anchors = [] + optionsgrid = [og_colsizing, og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_savestate, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixcols.count = 1 + fixcols.items = < + item + width = 23 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 6 + captions.items = < + item + caption = 'Kind' + end + item + caption = 'I' + hint = 'Inherited' + end + item + caption = 'Namebase' + end + item + caption = 'Formsuffix' + end + item + caption = 'Source File' + end + item + caption = 'Form File' + end> + end> + datacols.count = 6 + datacols.options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[newfonames] + width = 96 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + name = 'newfonames' + onshowhint = colonshowhint + widgetname = 'newfonames' + dataclass = tgridmsestringdatalist + end + item[newinheritedforms] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + name = 'newinheritedforms' + widgetname = 'newinheritedforms' + dataclass = tgridintegerdatalist + end + item[newfonamebases] + width = 73 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + name = 'newfonamebases' + onshowhint = colonshowhint + widgetname = 'newfonamebases' + dataclass = tgridmsestringdatalist + end + item[newfoformsuffixes] + width = 69 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + name = 'newfoformsuffix' + widgetname = 'newfoformsuffixes' + dataclass = tgridmsestringdatalist + end + item[newfosources] + width = 293 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + name = 'newfosources' + onshowhint = colonshowhint + widgetname = 'newfosources' + dataclass = tgridmsestringdatalist + end + item[newfoforms] + width = 252 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + name = 'mewfoforms' + onshowhint = colonshowhint + widgetname = 'newfoforms' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + statfile = statfile1 + reffontheight = 14 + object newfonames: tstringedit + optionsskin = [osk_framebuttononly] + taborder = 1 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 96 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext] + reffontheight = 14 + end + object newinheritedforms: tbooleanedit + optionsskin = [osk_framebuttononly] + taborder = 2 + bounds_x = 97 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + end + object newfonamebases: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 3 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 111 + bounds_y = 0 + bounds_cx = 73 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + object newfoformsuffixes: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 4 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 185 + bounds_y = 0 + bounds_cx = 69 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + object newfosources: tfilenameedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 5 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 255 + bounds_y = 0 + bounds_cx = 293 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + controller.filterlist.data = ( + ( + 'Source' + '"*.pas" "*.pp"' + ) + ( + 'All Files' + '*' + ) + ) + controller.ongetfilename = expandfilename + reffontheight = 14 + end + object newfoforms: tfilenameedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 6 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 549 + bounds_y = 0 + bounds_cx = 252 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + controller.filterlist.data = ( + ( + 'Form Files' + '*.mfm' + ) + ( + 'All Files' + '*' + ) + ) + controller.ongetfilename = expandfilename + reffontheight = 14 + end + end + end + end + end + object ttabpage15: ttabpage + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 8 + bounds_x = 1 + bounds_y = 20 + bounds_cx = 830 + bounds_cy = 530 + anchors = [an_left, an_top, an_right, an_bottom] + caption = 'Too&ls' + reffontheight = 14 + object twidgetgrid3: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 830 + bounds_cy = 530 + anchors = [] + optionsgrid = [og_colsizing, og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixcols.count = 1 + fixcols.items = < + item + width = 18 + numstart = 1 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 10 + captions.items = < + item + caption = 'S' + hint = 'Save files' + end + item + caption = 'P' + hint = 'Parse source' + end + item + caption = 'H' + hint = 'Hide console (win32 only)' + end + item + caption = 'M' + hint = 'Show output in messages window' + end + item + caption = 'Menu' + end + item + caption = 'Shortcut' + hint = 'Select item from ''Settings''-''Configure MSEide''-''Shortcuts'''#10'''Tool 1''..''Tool 10''.' + end + item + caption = 'Sc.Key' + hint = 'Shortcut key' + end + item + caption = 'Alt.Sc.' + hint = 'Alternate shortcut key' + end + item + caption = 'File' + end + item + caption = 'Parameters' + end> + end> + datacols.count = 10 + datacols.options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[toolsave] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widthmin = 13 + widthmax = 13 + widgetname = 'toolsave' + dataclass = tgridintegerdatalist + end + item[toolparse] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widthmin = 13 + widthmax = 13 + widgetname = 'toolparse' + dataclass = tgridintegerdatalist + end + item[toolhide] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widthmin = 13 + widthmax = 13 + widgetname = 'toolhide' + dataclass = tgridintegerdatalist + end + item[toolmessages] + width = 13 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'toolmessages' + dataclass = tgridintegerdatalist + end + item[toolmenus] + width = 107 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + onshowhint = colonshowhint + widgetname = 'toolmenus' + dataclass = tgridmsestringdatalist + end + item[toolshortcuts] + width = 86 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow, co_rowdatachange] + widgetname = 'toolshortcuts' + dataclass = tgridenumdatalist + end + item[toolsc] + color = -1879048185 + coloractive = -2147483647 + width = 55 + options = [co_readonly, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'toolsc' + dataclass = tgridmsestringdatalist + end + item[toolscalt] + color = -1879048185 + width = 55 + options = [co_readonly, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'toolscalt' + dataclass = tgridmsestringdatalist + end + item[toolfiles] + width = 116 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + onshowhint = colonshowhint + widgetname = 'toolfiles' + dataclass = tgridmsestringdatalist + end + item[toolparams] + width = 326 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + onshowhint = colonshowhint + widgetname = 'toolparams' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + statfile = statfile1 + onrowdatachanged = toolsrowdatachanged + reffontheight = 14 + object toolsave: tbooleanedit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_fileft, frl_fitop, frl_firight, frl_fibottom, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + end + object toolparse: tbooleanedit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_fileft, frl_fitop, frl_firight, frl_fibottom, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 2 + bounds_x = 14 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + end + object toolhide: tbooleanedit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_fileft, frl_fitop, frl_firight, frl_fibottom, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 3 + bounds_x = 28 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + end + object toolmessages: tbooleanedit + optionswidget1 = [] + optionsskin = [osk_framebuttononly] + taborder = 4 + bounds_x = 42 + bounds_y = 0 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + end + object toolmenus: tstringedit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 5 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 56 + bounds_y = 0 + bounds_cx = 107 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter] + reffontheight = 14 + end + object toolshortcuts: tenumedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.button.color = -1879048187 + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + end> + taborder = 6 + visible = False + bounds_x = 164 + bounds_y = 0 + bounds_cx = 86 + bounds_cy = 16 + statfile = statfile1 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate, oe1_checkvalueafterstatread] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + dropdown.options = [deo_selectonly, deo_autodropdown, deo_keydropdown, deo_cliphint, deo_colsizing, deo_savestate] + dropdown.width = -1 + dropdown.cols.count = 3 + dropdown.cols.width = 70 + dropdown.cols.options = [co_readonly, co_mousemovefocus, co_focusselect, co_rowselect] + dropdown.cols.linewidth = 1 + dropdown.cols.items = < + item + options = [co_readonly, co_mousemovefocus, co_focusselect, co_rowselect] + width = 70 + linewidth = 1 + caption = 'Item' + data = ( + 'Tool 1' + 'Tool 2' + 'Tool 3' + 'Tool 4' + 'Tool 5' + 'Tool 6' + 'Tool 7' + 'Tool 8' + 'Tool 9' + 'Tool 10' + ) + end + item + options = [co_readonly, co_mousemovefocus, co_focusselect, co_rowselect] + width = 70 + linewidth = 1 + caption = 'Shortcut' + data = ( + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + ) + end + item + options = [co_readonly, co_mousemovefocus, co_focusselect, co_rowselect] + width = 70 + linewidth = 1 + caption = 'Alternate' + data = ( + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + ) + end> + valuemax = 9 + onbeforedropdown = toolshortcutdropdown + reffontheight = 14 + end + object toolsc: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 7 + visible = False + bounds_x = 251 + bounds_y = 0 + bounds_cx = 55 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate, oe1_checkvalueafterstatread] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + reffontheight = 14 + end + object toolscalt: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 8 + visible = False + bounds_x = 307 + bounds_y = 0 + bounds_cx = 55 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate, oe1_checkvalueafterstatread] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + reffontheight = 14 + end + object toolfiles: tfilenameedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 9 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 363 + bounds_y = 0 + bounds_cx = 116 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter] + controller.include = [fa_xusr, fa_xgrp, fa_xoth] + reffontheight = 14 + end + object toolparams: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + taborder = 10 + onshowhint = hintexpandedmacros + visible = False + bounds_x = 480 + bounds_y = 0 + bounds_cx = 326 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter] + reffontheight = 14 + end + end + end + object ttabpage20: ttabpage + frame.localprops = [] + frame.localprops1 = [] + taborder = 9 + bounds_x = 1 + bounds_y = 20 + bounds_cx = 830 + bounds_cy = 530 + anchors = [an_left, an_top, an_right, an_bottom] + caption = '&Storage' + object settingseditor: tbooleanedit + optionsskin = [osk_nolayoutcx, osk_nolayoutcy] + frame.caption = 'Editor' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 40 + 2 + ) + taborder = 3 + bounds_x = 15 + bounds_y = 108 + bounds_cx = 54 + bounds_cy = 16 + end + object settingsautoload: tbooleanedit + frame.caption = 'Auto load' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 63 + 2 + ) + taborder = 1 + bounds_x = 15 + bounds_y = 52 + bounds_cx = 76 + bounds_cy = 16 + end + object settingsautosave: tbooleanedit + frame.caption = 'Auto save' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 65 + 2 + ) + taborder = 2 + bounds_x = 183 + bounds_y = 52 + bounds_cx = 78 + bounds_cy = 16 + end + object tlayouter6: tlayouter + frame.framei_left = 5 + frame.framei_top = 5 + frame.framei_right = 5 + frame.framei_bottom = 5 + frame.localprops = [frl_fileft, frl_fitop, frl_firight, frl_fibottom] + frame.localprops1 = [] + bounds_x = 0 + bounds_y = 13 + bounds_cx = 830 + bounds_cy = 31 + anchors = [an_top] + optionsscale = [osc_expandy, osc_shrinky] + optionslayout = [lao_placex, lao_aligny] + align_glue = wam_start + place_mindist = 5 + place_maxdist = 5 + place_options = [plo_endmargin] + object savebu: tbutton + optionswidget1 = [ow1_fontlineheight, ow1_autoscale] + taborder = 2 + bounds_x = 776 + bounds_y = 5 + bounds_cx = 49 + bounds_cy = 21 + anchors = [an_top, an_right] + state = [as_disabled, as_localdisabled, as_localcaption, as_localonexecute] + caption = 'Save' + onexecute = saveexe + reffontheight = 14 + end + object loadbu: tbutton + optionswidget1 = [ow1_fontlineheight, ow1_autoscale] + taborder = 1 + bounds_x = 722 + bounds_y = 5 + bounds_cx = 49 + bounds_cy = 21 + anchors = [an_top, an_right] + state = [as_disabled, as_localdisabled, as_localcaption, as_localonexecute] + caption = 'Load' + onexecute = loadexe + reffontheight = 14 + end + object settingsfile: tfilenameedit + optionsskin = [osk_nolayoutcx, osk_nolayoutcy] + frame.caption = 'Settings File' + frame.captiontextflags = [tf_ycentered] + frame.captionpos = cp_right + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 0 + 80 + 0 + ) + onshowhint = hintexpandedmacros + bounds_x = 5 + bounds_y = 5 + bounds_cx = 712 + anchors = [an_left, an_top, an_right] + ondataentered = settingsdataent + controller.filterlist.data = ( + ( + 'Project Files' + '*.prj' + ) + ( + 'All Files' + '*' + ) + ) + controller.defaultext = 'prj' + controller.captionopen = 'Enter Settings File' + reffontheight = 14 + end + end + object settingsdebugger: tbooleanedit + optionsskin = [osk_nolayoutcx, osk_nolayoutcy] + frame.caption = 'Debugger' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 65 + 2 + ) + taborder = 4 + bounds_x = 15 + bounds_y = 132 + bounds_cx = 79 + bounds_cy = 16 + end + object settingsstorage: tbooleanedit + optionsskin = [osk_nolayoutcx, osk_nolayoutcy] + frame.caption = 'Storage' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 53 + 2 + ) + taborder = 12 + bounds_x = 15 + bounds_y = 324 + bounds_cx = 67 + bounds_cy = 16 + end + object settingsprojecttree: tbooleanedit + optionsskin = [osk_nolayoutcx, osk_nolayoutcy] + frame.caption = 'Project Tree' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 79 + 2 + ) + taborder = 14 + bounds_x = 183 + bounds_y = 132 + bounds_cx = 93 + bounds_cy = 16 + end + object settingsmacros: tbooleanedit + optionsskin = [osk_nolayoutcx, osk_nolayoutcy] + frame.caption = 'Macros' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 48 + 2 + ) + taborder = 6 + bounds_x = 15 + bounds_y = 180 + bounds_cx = 62 + bounds_cy = 16 + end + object settingstools: tbooleanedit + optionsskin = [osk_nolayoutcx, osk_nolayoutcy] + frame.caption = 'Tools' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 36 + 2 + ) + taborder = 11 + bounds_x = 15 + bounds_y = 300 + bounds_cx = 50 + bounds_cy = 16 + end + object settingstemplates: tbooleanedit + optionsskin = [osk_nolayoutcx, osk_nolayoutcy] + frame.caption = 'Templates' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 68 + 2 + ) + taborder = 10 + bounds_x = 15 + bounds_y = 276 + bounds_cx = 82 + bounds_cy = 16 + end + object settingscomponentstore: tbooleanedit + optionsskin = [osk_nolayoutcx, osk_nolayoutcy] + frame.caption = 'Component Store' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 113 + 2 + ) + taborder = 13 + bounds_x = 183 + bounds_y = 108 + bounds_cx = 127 + bounds_cy = 16 + end + object settingslayout: tbooleanedit + optionsskin = [osk_nolayoutcx, osk_nolayoutcy] + frame.caption = 'Window Layout' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 95 + 2 + ) + taborder = 15 + bounds_x = 183 + bounds_y = 156 + bounds_cx = 109 + bounds_cy = 16 + end + object tlabel1: tlabel + taborder = 16 + bounds_x = 15 + bounds_y = 84 + bounds_cx = 118 + bounds_cy = 14 + caption = 'Load/save settings' + reffontheight = 14 + end + object settingsmake: tbooleanedit + optionsskin = [osk_nolayoutcx, osk_nolayoutcy] + frame.caption = 'Make' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 36 + 2 + ) + taborder = 5 + bounds_x = 15 + bounds_y = 156 + bounds_cx = 50 + bounds_cy = 16 + value = True + end + object settingsusercolors: tbooleanedit + optionsskin = [osk_nolayoutcx, osk_nolayoutcy] + frame.caption = 'User Colors' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 75 + 2 + ) + taborder = 8 + bounds_x = 15 + bounds_y = 228 + bounds_cx = 89 + bounds_cy = 16 + end + object settingsformatmacros: tbooleanedit + optionsskin = [osk_nolayoutcx, osk_nolayoutcy] + frame.caption = 'Format Macros' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 96 + 2 + ) + taborder = 9 + bounds_x = 15 + bounds_y = 252 + bounds_cx = 110 + bounds_cy = 16 + end + object settingsfontalias: tbooleanedit + optionsskin = [osk_nolayoutcx, osk_nolayoutcy] + frame.caption = 'Font Alias' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 64 + 2 + ) + taborder = 7 + bounds_x = 15 + bounds_y = 204 + bounds_cx = 78 + bounds_cy = 16 + end + end + end + end + object statfile1: tstatfile + filename = 'optionsfo.sta' + options = [sfo_memory] + left = 144 + top = 536 + end + object c: tstringcontainer + strings.data = ( + 'Wrong encoding can damage your source files.' + 'Do you wish to set encoding to' + '*** WARNING ***' + 'Hangup' + 'Interrupt' + 'Quit' + 'Illegal instruction' + 'Trace trap' + 'Abort' + 'BUS error' + 'Floating-point exception' + 'Kill' + 'User-defined signal 1' + 'Segmentation violation' + 'User-defined signal 2' + 'Broken pipe' + 'Alarm clock' + 'Termination' + 'Stack fault' + 'Child status has changed' + 'Continue' + 'Stop, unblockable' + 'Keyboard stop' + 'Background read from tty' + 'Background write to tty' + 'Urgent condition on socket' + 'CPU limit exceeded' + 'File size limit exceeded' + 'Virtual alarm clock' + 'Profiling alarm clock' + 'Window size change' + 'I/O now possible' + 'Power failure restart' + ) + left = 216 + top = 536 + end +end diff --git a/mseide-msegui/apps/ide/projectoptionsform.pas b/mseide-msegui/apps/ide/projectoptionsform.pas new file mode 100644 index 0000000..1ed0718 --- /dev/null +++ b/mseide-msegui/apps/ide/projectoptionsform.pas @@ -0,0 +1,3602 @@ +{ MSEide Copyright (c) 1999-2018 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit projectoptionsform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +{$ifndef mse_no_ifi} + {$define mse_with_ifi} + //MSEide needs mse_with_ifi, switch for compiling test only +{$endif} +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +interface +uses + mseforms,msefiledialog,mseapplication,msegui,msestat,msestatfile,msetabs, + msesimplewidgets,msetypes,msestrings,msedataedits,msetextedit,msegraphedits, + msewidgetgrid,msegrids,msesplitter,msemacros,msegdbutils,msedispwidgets,msesys, + mseclasses,msegraphutils,mseevent,msetabsglob,msearrayutils,msegraphics, + msedropdownlist,mseformatstr,mseinplaceedit,msedatanodes,mselistbrowser, + msebitmap,msecolordialog,msedrawtext,msewidgets,msepointer,mseguiglob, + msepipestream,msemenus,sysutils,mseglob,mseedit,msedialog,msescrollbar, + msememodialog,msecodetemplates,mseifiglob,msestream,msestringcontainer, + mserttistat,mseificomp,mseificompglob,msedragglob,mseeditglob,mseact; + +const + defaultsourceprintfont = 'Courier'; + defaulttitleprintfont = 'Helvetica'; + defaultprintfontsize = 35.2778; //10 point + maxdefaultmake = $40-1; + defaultxtermcommand = 'xterm -S${PTSN}/${PTSH}'; + optaftermainfilemask = $40000000; + +type + settinggroupty = (sg_editor,sg_debugger,sg_make,sg_templates, + sg_macros,sg_fontalias,sg_usercolors, + sg_formatmacros,sg_tools,sg_storage, + sg_state); + settinggroupsty = set of settinggroupty; + + findinfoty = record + text: msestring; + options: searchoptionsty; + selectedonly: boolean; + history: msestringarty; + end; + + replaceinfoty = record + find: findinfoty; + replacetext: msestring; + prompt: boolean; + end; + + sigsetinfoty = record + num: integer; + numto: integer; + flags: sigflagsty; + end; + sigsetinfoarty = array of sigsetinfoty; + + ttexttoolsoptions = class(toptions) + private + ftoolmenus: msestringarty; + ftoolfiles: msestringarty; + ftoolparams: msestringarty; + published + property toolmenus: msestringarty read ftoolmenus write ftoolmenus; + property toolfiles: msestringarty read ftoolfiles write ftoolfiles; + property toolparams: msestringarty read ftoolparams write ftoolparams; + end; + + ttoolsoptions = class(toptions) + private + ft: ttexttoolsoptions; + ftexp: ttexttoolsoptions; + ftoolsave: longboolarty; + ftoolhide: longboolarty; + ftoolparse: longboolarty; + ftoolmessages: longboolarty; + ftoolshortcuts: integerarty; + protected + function gett: tobject; override; + function gettexp: tobject; override; + public + constructor create; + property texp: ttexttoolsoptions read ftexp; + published + property t: ttexttoolsoptions read ft; + property toolsave: longboolarty read ftoolsave write ftoolsave; + property toolhide: longboolarty read ftoolhide write ftoolhide; + property toolparse: longboolarty read ftoolparse write ftoolparse; + property toolmessages: longboolarty read ftoolmessages write ftoolmessages; + property toolshortcuts: integerarty read ftoolshortcuts write ftoolshortcuts; + end; + + ttexttemplatesoptions = class(toptions) + private + fscriptbeforecopy: msestring; + fscriptaftercopy: msestring; + fnewprojectfiles: filenamearty; + fnewprojectfilesdest: filenamearty; + fnewfinames: msestringarty; + fnewfifilters: msestringarty; + fnewfiexts: msestringarty; + fnewfisources: filenamearty; + fnewfonames: msestringarty; + fnewfonamebases: msestringarty; + fnewfoformsuffixes: msestringarty; + fnewfosources: msestringarty; + fnewfoforms: msestringarty; + published + property scriptbeforecopy: msestring read fscriptbeforecopy + write fscriptbeforecopy; + property scriptaftercopy: msestring read fscriptaftercopy + write fscriptaftercopy; + property newprojectfiles: filenamearty read fnewprojectfiles + write fnewprojectfiles; + property newprojectfilesdest: filenamearty read fnewprojectfilesdest + write fnewprojectfilesdest; + property newfinames: msestringarty read fnewfinames write fnewfinames; + property newfifilters: msestringarty read fnewfifilters + write fnewfifilters; + property newfiexts: msestringarty read fnewfiexts write fnewfiexts; + property newfisources: filenamearty read fnewfisources write fnewfisources; + + property newfonames: msestringarty read fnewfonames write fnewfonames; + property newfonamebases: msestringarty read fnewfonamebases + write fnewfonamebases; + property newfoformsuffixes: msestringarty read fnewfoformsuffixes + write fnewfoformsuffixes; + property newfosources: msestringarty read fnewfosources + write fnewfosources; + property newfoforms: msestringarty read fnewfoforms write fnewfoforms; + end; + + ttemplatesoptions = class(toptions) + private + ft: ttexttemplatesoptions; + ftexp: ttexttemplatesoptions; + fexpandprojectfilemacros: longboolarty; + floadprojectfile: longboolarty; + fnewinheritedforms: longboolarty; + protected + function gett: tobject; override; + function gettexp: tobject; override; + public + constructor create; + property texp: ttexttemplatesoptions read ftexp; + published + property t: ttexttemplatesoptions read ft; + property expandprojectfilemacros: longboolarty read fexpandprojectfilemacros + write fexpandprojectfilemacros; + property loadprojectfile: longboolarty read floadprojectfile + write floadprojectfile; + property newinheritedforms: longboolarty read fnewinheritedforms + write fnewinheritedforms; + end; + + ttexteditoptions = class(toptions) + private + fsourcefilemasks: msestringarty; + fsyntaxdeffiles: msestringarty; + ffilemasknames: msestringarty; + ffilemasks: msestringarty; + public + fcodetemplatedirs: msestringarty; + published + property sourcefilemasks: msestringarty read fsourcefilemasks + write fsourcefilemasks; + property syntaxdeffiles: msestringarty read fsyntaxdeffiles + write fsyntaxdeffiles; + property filemasknames: msestringarty read ffilemasknames + write ffilemasknames; + property filemasks: msestringarty read ffilemasks write ffilemasks; + property codetemplatedirs: msestringarty read fcodetemplatedirs write + fcodetemplatedirs; + end; + + teditoptions = class(toptions) + private + ft: ttexteditoptions; + ftexp: ttexteditoptions; + + fshowgrid: boolean; + fsnaptogrid: boolean; + fmoveonfirstclick: boolean; + fgridsizex: integer; + fgridsizey: integer; + fautoindent: boolean; + fblockindent: integer; + flinenumberson: boolean; + frightmarginon: boolean; + frightmarginchars: integer; + fscrollheight: integer; + ftabstops: integer; + fspacetabs: boolean; + fshowtabs: boolean; + ftabindent: boolean; + feditfontname: msestring; + feditfontheight: integer; + feditfontwidth: integer; + feditfontextraspace: integer; + feditfontcolor: integer; + feditbkcolor: integer; + fstatementcolor: integer; + feditfontantialiased: boolean; + feditmarkbrackets: boolean; + feditmarkpairwords: boolean; + fbackupfilecount: integer; + fencoding: integer; + feolstyle: integer; + fnoformdesignerdocking: boolean; + ftrimtrailingwhitespace: boolean; + fpairmarkcolor: integer; + fpairmaxrowcount: integer; + fcomponenthints: boolean; + function limitgridsize(const avalue: integer): integer; + procedure setgridsizex(const avalue: integer); + procedure setgridsizey(const avalue: integer); +// function getcodetemplatedirs: msestringarty; +// procedure setcodetemplatedirs(const avalue: msestringarty); + protected + function gett: tobject; override; + function gettexp: tobject; override; + public + constructor create; + property texp: ttexteditoptions read ftexp; + published + property t: ttexteditoptions read ft; + + property showgrid: boolean read fshowgrid write fshowgrid; + property snaptogrid: boolean read fsnaptogrid write fsnaptogrid; + property moveonfirstclick: boolean read fmoveonfirstclick + write fmoveonfirstclick; + property noformdesignerdocking: boolean read fnoformdesignerdocking + write fnoformdesignerdocking; + property componenthints: boolean read fcomponenthints + write fcomponenthints; + property gridsizex: integer read fgridsizex write setgridsizex; + property gridsizey: integer read fgridsizey write setgridsizey; + property autoindent: boolean read fautoindent write fautoindent; + property blockindent: integer read fblockindent write fblockindent; + property linenumberson: boolean read flinenumberson write flinenumberson; + property rightmarginon: boolean read frightmarginon write frightmarginon; + property rightmarginchars: integer read frightmarginchars + write frightmarginchars; + property scrollheight: integer read fscrollheight write fscrollheight; + property tabstops: integer read ftabstops write ftabstops; + property spacetabs: boolean read fspacetabs write fspacetabs; + property showtabs: boolean read fshowtabs write fshowtabs; + property tabindent: boolean read ftabindent write ftabindent; + property editfontname: msestring read feditfontname write feditfontname; + property editfontheight: integer read feditfontheight write feditfontheight; + property editfontwidth: integer read feditfontwidth write feditfontwidth; + property editfontextraspace: integer read feditfontextraspace + write feditfontextraspace; + property editfontcolor: integer read feditfontcolor write feditfontcolor; + property editbkcolor: integer read feditbkcolor write feditbkcolor; + property statementcolor: integer read fstatementcolor write fstatementcolor; + property pairmarkcolor: integer read fpairmarkcolor + write fpairmarkcolor; + property pairmaxrowcount: integer read fpairmaxrowcount + write fpairmaxrowcount; + + property editfontantialiased: boolean read feditfontantialiased + write feditfontantialiased; + property editmarkbrackets: boolean read feditmarkbrackets + write feditmarkbrackets; + property editmarkpairwords: boolean read feditmarkpairwords + write feditmarkpairwords; + property backupfilecount: integer read fbackupfilecount + write fbackupfilecount; + property encoding: integer read fencoding write fencoding; + property eolstyle: integer read feolstyle write feolstyle; + property trimtrailingwhitespace: boolean read ftrimtrailingwhitespace + write ftrimtrailingwhitespace; +// property codetemplatedirs: msestringarty read getcodetemplatedirs write +// setcodetemplatedirs; + end; + + ttextdebugoptions = class(toptions) + private + fdebugcommand: filenamety; + fdebugoptions: msestring; + fdebugtarget: filenamety; + fruncommand: filenamety; + fremoteconnection: msestring; + fuploadcommand: filenamety; + fgdbprocessor: msestring; + fgdbservercommand: filenamety; + fgdbservercommandattach: filenamety; + fbeforeload: filenamety; + fafterload: filenamety; + fbeforerun: filenamety; + fsourcedirs: msestringarty; + fdefines: msestringarty; + + fprogparameters: msestring; + fprogworkingdirectory: filenamety; + fenvvarnames: msestringarty; + fenvvarvalues: msestringarty; + fbeforeconnect: filenamety; + fafterconnect: filenamety; + fxtermcommand: msestring; + fsourcebase: msestring; + protected + public + constructor create; + published + property debugcommand: filenamety read fdebugcommand write fdebugcommand; + property debugoptions: msestring read fdebugoptions write fdebugoptions; + property debugtarget: filenamety read fdebugtarget write fdebugtarget; + property runcommand: filenamety read fruncommand write fruncommand; + property xtermcommand: msestring read fxtermcommand write fxtermcommand; + property remoteconnection: msestring read fremoteconnection + write fremoteconnection; + property uploadcommand: filenamety read fuploadcommand + write fuploadcommand; + property gdbprocessor: msestring read fgdbprocessor write fgdbprocessor; + property gdbservercommand: filenamety read fgdbservercommand + write fgdbservercommand; + property gdbservercommandattach: filenamety read fgdbservercommandattach + write fgdbservercommandattach; + property beforeconnect: filenamety read fbeforeconnect write fbeforeconnect; + property afterconnect: filenamety read fafterconnect write fafterconnect; + property beforeload: filenamety read fbeforeload write fbeforeload; + property afterload: filenamety read fafterload write fafterload; + property beforerun: filenamety read fbeforerun write fbeforerun; + property sourcebase: msestring read fsourcebase write fsourcebase; + property sourcedirs: msestringarty read fsourcedirs write fsourcedirs; + property defines: msestringarty read fdefines write fdefines; + + property progparameters: msestring read fprogparameters + write fprogparameters; + property progworkingdirectory: filenamety read fprogworkingdirectory + write fprogworkingdirectory; + property envvarnames: msestringarty read fenvvarnames write fenvvarnames; + property envvarvalues: msestringarty read fenvvarvalues write fenvvarvalues; + end; + + tdebugoptions = class(toptions) + private + ft: ttextdebugoptions; + ftexp: ttextdebugoptions; + fdefineson: longboolarty; + fstoponexception: boolean; + fvaluehints: boolean; + factivateonbreak: boolean; + fshowconsole: boolean; + fexternalconsole: boolean; + fgdbdownload: boolean; + fdownloadalways: boolean; + frestartgdbbeforeload: boolean; + fstartupbkpt: integer; + fstartupbkpton: boolean; + fgdbsimulator: boolean; + fgdbserverwait: real; + fexceptclassnames: msestringarty; + fexceptignore: booleanarty; + fnogdbserverexit: boolean; + fgdbservertty: boolean; + fnodebugbeginend: boolean; + fsettty: boolean; + fgdbserverstartonce: boolean; + fraiseonbreak: boolean; + fgdbloadtimeout: realty; + ffpcgdbworkaround: boolean; + protected + function gett: tobject; override; + function gettexp: tobject; override; + public + constructor create; + property texp: ttextdebugoptions read ftexp; + published + property t: ttextdebugoptions read ft; + property defineson: longboolarty read fdefineson write fdefineson; + property stoponexception: boolean read fstoponexception write fstoponexception; + property valuehints: boolean read fvaluehints write fvaluehints; + property activateonbreak: boolean read factivateonbreak write factivateonbreak; + property raiseonbreak: boolean read fraiseonbreak write fraiseonbreak; + property showconsole: boolean read fshowconsole write fshowconsole; + property externalconsole: boolean read fexternalconsole write fexternalconsole; + property settty: boolean read fsettty write fsettty; + property gdbdownload: boolean read fgdbdownload write fgdbdownload; + property downloadalways: boolean read fdownloadalways write fdownloadalways; + property restartgdbbeforeload: boolean read frestartgdbbeforeload + write frestartgdbbeforeload; + property startupbkpt: integer read fstartupbkpt write fstartupbkpt; + property startupbkpton: boolean read fstartupbkpton write fstartupbkpton; + property gdbsimulator: boolean read fgdbsimulator write fgdbsimulator; + property gdbserverstartonce: boolean read fgdbserverstartonce + write fgdbserverstartonce; + property gdbloadtimeout: real read fgdbloadtimeout write fgdbloadtimeout; + property gdbserverwait: real read fgdbserverwait write fgdbserverwait; + property nogdbserverexit: boolean read fnogdbserverexit + write fnogdbserverexit; + property gdbservertty: boolean read fgdbservertty + write fgdbservertty; + property exceptclassnames: msestringarty read fexceptclassnames + write fexceptclassnames; + property exceptignore: booleanarty read fexceptignore + write fexceptignore; + property nodebugbeginend: boolean read fnodebugbeginend + write fnodebugbeginend; + property fpcgdbworkaround: boolean read ffpcgdbworkaround + write ffpcgdbworkaround; + end; + + tmacrooptions = class(toptions) + private + fmacroon: integerarty; + fmacronames: msestringarty; + fmacrovalues: msestringarty; + fgroupcomments: msestringarty; + published + property macroon: integerarty read fmacroon write fmacroon; + property macronames: msestringarty read fmacronames write fmacronames; + property macrovalues: msestringarty read fmacrovalues write fmacrovalues; + property groupcomments: msestringarty read fgroupcomments + write fgroupcomments; + end; + + ttextprojectstate = class(toptions) + private + fmessageoutputfile: filenamety; + published + property messageoutputfile: filenamety read fmessageoutputfile + write fmessageoutputfile; + end; + + tprojectstate = class(toptions) + private + ft: ttextprojectstate; + ftexp: ttextprojectstate; + + fmodulenames: msestringarty; + fmoduletypes: msestringarty; + fmodulefiles: filenamearty; + fmacrogroup: integer; + + fforcezorder: longbool; + fstripmessageesc: boolean; + fcopymessages: boolean; + fcheckmethods: boolean; + fclosemessages: boolean; + fcolorerror: colorty; + fcolorwarning: colorty; + fcolornote: colorty; +// fsettingsautoload: boolean; +// fsettingsautosave: boolean; + procedure setforcezorder(const avalue: longbool); + protected + function gett: tobject; override; + function gettexp: tobject; override; + public + constructor create(); + property texp: ttextprojectstate read ftexp; + published + property t: ttextprojectstate read ft; + property modulenames: msestringarty read fmodulenames write fmodulenames; + property moduletypes: msestringarty read fmoduletypes write fmoduletypes; + property modulefiles: filenamearty read fmodulefiles write fmodulefiles; + property macrogroup: integer read fmacrogroup write fmacrogroup; + + property forcezorder: longbool read fforcezorder write setforcezorder; + property stripmessageesc: boolean read fstripmessageesc + write fstripmessageesc; + property copymessages: boolean read fcopymessages write fcopymessages; + property closemessages: boolean read fclosemessages write fclosemessages; + property checkmethods: boolean read fcheckmethods write fcheckmethods; + property colorerror: colorty read fcolorerror write fcolorerror; + property colorwarning: colorty read fcolorwarning write fcolorwarning; + property colornote: colorty read fcolornote write fcolornote; +{ + property settingsautoload: boolean read fsettingsautoload + write fsettingsautoload; + property settingsautosave: boolean read fsettingsautosave + write fsettingsautosave; +} + end; + + ttextfontaliasoptions = class(toptions) + private + ffontalias: msestringarty; + ffontnames: msestringarty; + ffontancestors: msestringarty; + ffontoptions: msestringarty; + published + property fontalias: msestringarty read ffontalias write ffontalias; + property fontnames: msestringarty read ffontnames write ffontnames; + property fontancestors: msestringarty read ffontancestors + write ffontancestors; + property fontoptions: msestringarty read ffontoptions write ffontoptions; + end; + + tfontaliasoptions = class(toptions) + private + ft: ttextfontaliasoptions; + ftexp: ttextfontaliasoptions; + ffontheights: integerarty; + ffontwidths: integerarty; + ffontxscales: realarty; + protected + function gett: tobject; override; + function gettexp: tobject; override; + public + constructor create(); + property texp: ttextfontaliasoptions read ftexp; + published + property t: ttextfontaliasoptions read ft; + property fontheights: integerarty read ffontheights write ffontheights; + property fontwidths: integerarty read ffontwidths write ffontwidths; + property fontxscales: realarty read ffontxscales write ffontxscales; + + end; + + ttextusercoloroptions = class(toptions) + end; + + tusercoloroptions = class(toptions) + private + ft: ttextusercoloroptions; + ftexp: ttextusercoloroptions; + fusercolors: colorarty; + fusercolorcomment: msestringarty; + protected + function gett: tobject; override; + function gettexp: tobject; override; + public + constructor create(); + property texp: ttextusercoloroptions read ftexp; + published + property t: ttextusercoloroptions read ft; + property usercolors: colorarty read fusercolors write fusercolors; + property usercolorcomment: msestringarty read fusercolorcomment + write fusercolorcomment; + end; + + ttextformatmacrooptions = class(toptions) + private + fformatmacronames: msestringarty; + fformatmacrovalues: msestringarty; + published + property formatmacronames: msestringarty read fformatmacronames + write fformatmacronames; + property formatmacrovalues: msestringarty read fformatmacrovalues + write fformatmacrovalues; + end; + + tformatmacrooptions = class(toptions) + private + ft: ttextformatmacrooptions; + ftexp: ttextformatmacrooptions; + protected + function gett: tobject; override; + function gettexp: tobject; override; + public + constructor create(); + property texp: ttextformatmacrooptions read ftexp; + published + property t: ttextformatmacrooptions read ft; + end; + + tstorageoptions = class(toptions) + private + fsettingsfile: filenamety; + fsettingseditor: boolean; + fsettingsdebugger: boolean; + fsettingsmake: boolean; + fsettingsmacros: boolean; + fsettingsfontalias: boolean; + fsettingsusercolors: boolean; + fsettingsformatmacros: boolean; + fsettingstemplates: boolean; + fsettingstools: boolean; + fsettingsstorage: boolean; + fsettingscomponentstore: boolean; + fsettingsprojecttree: boolean; + fsettingslayout: boolean; + fsettingsautoload: boolean; + fsettingsautosave: boolean; + public + constructor create(); + published + property settingsfile: filenamety read fsettingsfile write fsettingsfile; + property settingsautoload: boolean read fsettingsautoload + write fsettingsautoload; + property settingsautosave: boolean read fsettingsautosave + write fsettingsautosave; + property settingseditor: boolean read fsettingseditor write fsettingseditor; + property settingsdebugger: boolean read fsettingsdebugger + write fsettingsdebugger; + property settingsmake: boolean read fsettingsmake + write fsettingsmake; + property settingsmacros: boolean read fsettingsmacros + write fsettingsmacros; + property settingsfontalias: boolean read fsettingsfontalias + write fsettingsfontalias; + property settingsusercolors: boolean read fsettingsusercolors + write fsettingsusercolors; + property settingsformatmacros: boolean read fsettingsformatmacros + write fsettingsformatmacros; + property settingstemplates: boolean read fsettingstemplates + write fsettingstemplates; + property settingstools: boolean read fsettingstools + write fsettingstools; + property settingsstorage: boolean read fsettingsstorage + write fsettingsstorage; + property settingscomponentstore: boolean read fsettingscomponentstore + write fsettingscomponentstore; + property settingsprojecttree: boolean read fsettingsprojecttree + write fsettingsprojecttree; + property settingslayout: boolean read fsettingslayout + write fsettingslayout; + end; + + ttextmakeoptions = class(toptions) + private + fmainfile: filenamety; + ftargetfile: filenamety; + fmakecommand: filenamety; + fmakedir: filenamety; + funitdirs: msestringarty; + funitpref: msestring; + fincpref: msestring; + flibpref: msestring; + fobjpref: msestring; + ftargpref: msestring; + fbefcommand: msestringarty; + faftcommand: msestringarty; + fmakeoptions: msestringarty; +// ffontnames: msestringarty; + public +// fcodetemplatedirs: msestringarty; + published + property mainfile: filenamety read fmainfile write fmainfile; + property targetfile: filenamety read ftargetfile write ftargetfile; + property makecommand: filenamety read fmakecommand write fmakecommand; + property makedir: filenamety read fmakedir write fmakedir; + property unitdirs: msestringarty read funitdirs write funitdirs; + property unitpref: msestring read funitpref write funitpref; + property incpref: msestring read fincpref write fincpref; + property libpref: msestring read flibpref write flibpref; + property objpref: msestring read fobjpref write fobjpref; + property targpref: msestring read ftargpref write ftargpref; + + property befcommand: msestringarty read fbefcommand write fbefcommand; + property aftcommand: msestringarty read faftcommand write faftcommand; + property makeoptions: msestringarty read fmakeoptions write fmakeoptions; + +// property codetemplatedirs: msestringarty read fcodetemplatedirs +// write fcodetemplatedirs; + end; + + tmakeoptions = class(toptions) + private + ft: ttextmakeoptions; + ftexp: ttextmakeoptions; + +// fusercolors: colorarty; +// fusercolorcomment: msestringarty; + +// fformatmacronames: msestringarty; +// fformatmacrovalues: msestringarty; +{ + fsettingsfile: filenamety; + fsettingseditor: boolean; + fsettingsdebugger: boolean; + fsettingsmake: boolean; + fsettingsmacros: boolean; + fsettingsfontalias: boolean; + fsettingsusercolors: boolean; + fsettingsformatmacros: boolean; + fsettingstemplates: boolean; + fsettingstools: boolean; + fsettingsstorage: boolean; + fsettingscomponentstore: boolean; + fsettingsprojecttree: boolean; + fsettingslayout: boolean; + fsettingsautoload: boolean; + fsettingsautosave: boolean; +} +// fmoduleoptions: integerarty; + fmakeoptpurpose: msestringarty; + fbefcommandon: integerarty; + fmakeoptionson: integerarty; + faftcommandon: integerarty; + funitdirson: integerarty; +{ + ffontalias: msestringarty; + ffontancestors: msestringarty; + ffontheights: integerarty; + ffontwidths: integerarty; + ffontoptions: msestringarty; + ffontxscales: realarty; + } + fuid: integer; + freversepathorder: boolean; + protected + function gett: tobject; override; + function gettexp: tobject; override; + public + constructor create; + property texp: ttextmakeoptions read ftexp; + published + property t: ttextmakeoptions read ft; + + property reversepathorder: boolean read freversepathorder + write freversepathorder; + + property makeoptpurpose: msestringarty read fmakeoptpurpose + write fmakeoptpurpose; + property befcommandon: integerarty read fbefcommandon write fbefcommandon; + property makeoptionson: integerarty read fmakeoptionson write fmakeoptionson; + property aftcommandon: integerarty read faftcommandon write faftcommandon; + property unitdirson: integerarty read funitdirson write funitdirson; + + property uid: integer read fuid write fuid; //for insert UID + end; +{ + ttextprojectoptions = class(toptions) + end; + + tprojectoptions = class(toptions) + private + ft: ttextprojectoptions; + ftexp: ttextprojectoptions; + protected + function gett: tobject; override; + function gettexp: tobject; override; + public + constructor create(); + property texp: ttextprojectoptions read ftexp; + published + property t: ttextprojectoptions read ft; + end; +} +{$M-} + + projectoptionsty = record + disabled: settinggroupsty; +// o: tprojectoptions; + e: teditoptions; + d: tdebugoptions; + k: tmakeoptions; + m: tmacrooptions; + a: tfontaliasoptions; + u: tusercoloroptions; + f: tformatmacrooptions; + p: ttemplatesoptions; + t: ttoolsoptions; + r: tstorageoptions; + s: tprojectstate; + modified: boolean; + savechecked: boolean; + ignoreexceptionclasses: stringarty; + projectfilename: filenamety; + projectdir: filenamety; + defaultmake: integer; + sigsettings: sigsetinfoarty; + progparamhistory: msestringarty; + workdirparamhistory: msestringarty; + envvarons: longboolarty; + findreplaceinfo: replaceinfoty; + targetconsolefindinfo: findinfoty; + end; + + tprojectoptionsfo = class(tmseform) + statfile1: tstatfile; + tlayouter9: tlayouter; + tlayouter8: tlayouter; + cancel: tbutton; + ok: tbutton; + tabwidget: ttabwidget; + editorpage: ttabpage; + debuggerpage: ttabpage; + debugcommand: tfilenameedit; + debugoptions: tmemodialogedit; + ttabwidget1: ttabwidget; + ttabpage6: ttabpage; + sourcedirgrid: twidgetgrid; + sourcedirs: tfilenameedit; + ttabpage9: ttabpage; + twidgetgrid2: twidgetgrid; + defineson: tbooleanedit; + defines: tstringedit; + ttabpage7: ttabpage; + signalgrid: twidgetgrid; + sigstop: tbooleanedit; + sighandle: tbooleanedit; + signum: tintegeredit; + signumto: tintegeredit; + signame: tselector; + ttabpage8: ttabpage; + exceptionsgrid: twidgetgrid; + exceptignore: tbooleanedit; + exceptclassnames: tstringedit; + ttabpage16: ttabpage; + remoteconnection: tstringedit; + tlayouter3: tlayouter; + gdbprocessor: tdropdownlistedit; + gdbsimulator: tbooleanedit; + gdbdownload: tbooleanedit; + tlayouter4: tlayouter; + beforeconnect: tfilenameedit; + tsplitter7: tsplitter; + beforeload: tfilenameedit; + tlayouter5: tlayouter; + afterconnect: tfilenameedit; + tsplitter8: tsplitter; + tlayouter1: tlayouter; + externalconsole: tbooleanedit; + showconsole: tbooleanedit; + stoponexception: tbooleanedit; + activateonbreak: tbooleanedit; + makepage: ttabpage; + tspacer2: tspacer; + defaultmake: tenumedit; + mainfile: tfilenameedit; + targetfile: tfilenameedit; + makecommand: tfilenameedit; + showcommandline: tbutton; + messageoutputfile: tfilenameedit; + copymessages: tbooleanedit; + closemessages: tbooleanedit; + checkmethods: tbooleanedit; + makegroupbox: ttabwidget; + ttabpage12: ttabpage; + makeoptionsgrid: twidgetgrid; + makeon: tbooleanedit; + buildon: tbooleanedit; + make1on: tbooleanedit; + make2on: tbooleanedit; + make3on: tbooleanedit; + make4on: tbooleanedit; + makeoptions: tmemodialogedit; + ttabpage11: ttabpage; + unitdirgrid: twidgetgrid; + dmakeon: tbooleanedit; + dbuildon: tbooleanedit; + dmake1on: tbooleanedit; + dmake2on: tbooleanedit; + dmake3on: tbooleanedit; + dmake4on: tbooleanedit; + duniton: tbooleanedit; + dincludeon: tbooleanedit; + dlibon: tbooleanedit; + dobjon: tbooleanedit; + unitdirs: tfilenameedit; + tspacer1: tspacer; + targpref: tstringedit; + makedir: tfilenameedit; + tsplitter1: tsplitter; + tsplitter2: tsplitter; + tsplitter4: tsplitter; + tsplitter5: tsplitter; + ttabpage1: ttabpage; + macrogrid: twidgetgrid; + e0: tbooleanedit; + e1: tbooleanedit; + e2: tbooleanedit; + e3: tbooleanedit; + e4: tbooleanedit; + e5: tbooleanedit; + macronames: tstringedit; + macrovalues: tmemodialogedit; + selectactivegroupgrid: twidgetgrid; + activemacroselect: tbooleaneditradio; + groupcomment: tstringedit; + macrosplitter: tsplitter; + fontaliaspage: ttabpage; + fontaliasgrid: twidgetgrid; + fontalias: tstringedit; + fontname: tstringedit; + fontheight: tintegeredit; + ttabpage10: ttabpage; + tlayouter7: tlayouter; + tbutton1: tbutton; + colgrid: twidgetgrid; + coldi: tpointeredit; + usercolors: tcoloredit; + usercolorcomment: tstringedit; + ttabpage2: ttabpage; + newfile: ttabwidget; + ttabpage3: ttabpage; + copygrid: twidgetgrid; + loadprojectfile: tbooleanedit; + expandprojectfilemacros: tbooleanedit; + newprojectfiles: tfilenameedit; + newprojectfilesdest: tstringedit; + ttabpage4: ttabpage; + ttabpage5: ttabpage; + ttabpage15: ttabpage; + twidgetgrid3: twidgetgrid; + toolsave: tbooleanedit; + toolparse: tbooleanedit; + toolhide: tbooleanedit; + toolmenus: tstringedit; + toolfiles: tfilenameedit; + toolparams: tstringedit; + downloadalways: tbooleanedit; + startupbkpt: tintegeredit; + startupbkpton: tbooleanedit; + valuehints: tbooleanedit; + debugtarget: tfilenameedit; + debugtargetsplitter: tsplitter; + fontwidth: tintegeredit; + fontoptions: tstringedit; + fontxscale: trealedit; + twidgetgrid4: twidgetgrid; + newfonames: tstringedit; + newfosources: tfilenameedit; + newfoforms: tfilenameedit; + scriptbeforecopy: tfilenameedit; + scriptaftercopy: tfilenameedit; + newinheritedforms: tbooleanedit; + newfonamebases: tstringedit; + twidgetgrid1: twidgetgrid; + newfinames: tstringedit; + newfisources: tfilenameedit; + newfifilters: tstringedit; + newfiexts: tstringedit; + fontancestors: tstringedit; + ttabpage17: ttabpage; + ttabpage18: ttabpage; + befcommandgrid: twidgetgrid; + befmakeon: tbooleanedit; + befbuildon: tbooleanedit; + befmake1on: tbooleanedit; + befmake2on: tbooleanedit; + befmake3on: tbooleanedit; + befmake4on: tbooleanedit; + befcommand: tmemodialogedit; + aftcommandgrid: twidgetgrid; + aftmakeon: tbooleanedit; + aftbuildon: tbooleanedit; + aftmake1on: tbooleanedit; + aftmake2on: tbooleanedit; + aftmake3on: tbooleanedit; + aftmake4on: tbooleanedit; + aftcommand: tmemodialogedit; + ttabpage20: ttabpage; + settingseditor: tbooleanedit; + settingsautoload: tbooleanedit; + settingsautosave: tbooleanedit; + tlayouter6: tlayouter; + savebu: tbutton; + loadbu: tbutton; + settingsfile: tfilenameedit; + settingsdebugger: tbooleanedit; + settingsstorage: tbooleanedit; + settingsprojecttree: tbooleanedit; + nodebugbeginend: tbooleanedit; + toolmessages: tbooleanedit; + settty: tbooleanedit; + tsplitter9: tsplitter; + beforerun: tfilenameedit; + afterload: tfilenameedit; + tsplitter10: tsplitter; + ttabpage21: ttabpage; + formatmacrogrid: twidgetgrid; + formatmacronames: tstringedit; + formatmacrovalues: tstringedit; + colorerror: tcoloredit; + tspacer5: tspacer; + colorwarning: tcoloredit; + tspacer6: tspacer; + colornote: tcoloredit; + c: tstringcontainer; + xtermcommand: tmemodialogedit; + debugsplitter: tsplitter; + tspacer4: tspacer; + stripmessageesc: tbooleanedit; + raiseonbreak: tbooleanedit; + runcommand: tfilenameedit; + sourcebase: tfilenameedit; + tspacer7: tspacer; + toolshortcuts: tenumedit; + toolsc: tstringedit; + toolscalt: tstringedit; + fpcgdbworkaround: tbooleanedit; + ttabwidget3: ttabwidget; + ttabpage22: ttabpage; + componenthints: tbooleanedit; + noformdesignerdocking: tbooleanedit; + moveonfirstclick: tbooleanedit; + gridsizey: tintegeredit; + gridsizex: tintegeredit; + tintegeredit2: tintegeredit; + snaptogrid: tbooleanedit; + showgrid: tbooleanedit; + ttabpage23: ttabpage; + ttabwidget2: ttabwidget; + ttabpage13: ttabpage; + filefiltergrid: tstringgrid; + ttabpage14: ttabpage; + twidgetgrid6: twidgetgrid; + syntaxdeffile: tfilenameedit; + syntaxdeffilemask: tmemodialogedit; + ttabpage19: ttabpage; + twidgetgrid5: twidgetgrid; + codetemplatedirs: tfilenameedit; + tlayouter13: tlayouter; + dispgrid: twidgetgrid; + fontdisp: ttextedit; + tlayouter12: tlayouter; + editfontextraspace: tintegeredit; + editfontwidth: tintegeredit; + editfontheight: tintegeredit; + editfontname: tstringedit; + editfontcolor: tcoloredit; + editbkcolor: tcoloredit; + editfontantialiased: tbooleanedit; + tlayouter11: tlayouter; + tlayouter14: tlayouter; + rightmarginon: tbooleanedit; + linenumberson: tbooleanedit; + editmarkbrackets: tbooleanedit; + editmarkpairwords: tbooleanedit; + tlayouter15: tlayouter; + pairmarkcolor: tcoloredit; + statementcolor: tcoloredit; + scrollheight: tintegeredit; + rightmarginchars: tintegeredit; + tlayouter10: tlayouter; + spacetabs: tbooleanedit; + blockindent: tintegeredit; + autoindent: tbooleanedit; + tabindent: tbooleanedit; + tabstops: tintegeredit; + showtabs: tbooleanedit; + tlayouter16: tlayouter; + eolstyle: tenumtypeedit; + trimtrailingwhitespace: tbooleanedit; + encoding: tenumedit; + backupfilecount: tintegeredit; + tlayouter17: tlayouter; + objpref: tstringedit; + libpref: tstringedit; + incpref: tstringedit; + unitpref: tstringedit; + reversepathorder: tbooleanedit; + settingsmacros: tbooleanedit; + settingstools: tbooleanedit; + settingstemplates: tbooleanedit; + tsimplewidget1: tsimplewidget; + settingscomponentstore: tbooleanedit; + settingslayout: tbooleanedit; + tlabel1: tlabel; + settingsmake: tbooleanedit; + settingsusercolors: tbooleanedit; + settingsformatmacros: tbooleanedit; + settingsfontalias: tbooleanedit; + makeoptpurpose: tstringedit; + pairmaxrowcount: tintegeredit; + newfoformsuffixes: tstringedit; + downloadlayouter: tlayouter; + gdbservercommand: tfilenameedit; + gdbservercommandattach: tfilenameedit; + uploadcommand: tfilenameedit; + texpandingwidget1: texpandingwidget; + gdbloadtimeout: trealedit; + serverla: tlayouter; + gdbserverwait: trealedit; + gdbserverstartonce: tbooleanedit; + tlayouter2: tlayouter; + nogdbserverexit: tbooleanedit; + gdbservertty: tbooleanedit; + tstringedit1: tstringedit; + optafter: tbooleanedit; + restartgdbbeforeload: tbooleanedit; + procedure acttiveselectondataentered(const sender: TObject); + procedure colonshowhint(const sender: tdatacol; const arow: Integer; + var info: hintinfoty); + procedure hintexpandedmacros(const sender: TObject; var info: hintinfoty); + procedure selectactiveonrowsmoved(const sender: tcustomgrid; + const fromindex: Integer; const toindex: Integer; + const acount: Integer); + procedure expandfilename(const sender: TObject; var avalue: mseString; + var accept: Boolean); + procedure showcommandlineonexecute(const sender: TObject); + procedure signameonsetvalue(const sender: TObject; var avalue: integer; + var accept: Boolean); + procedure signumonsetvalue(const sender: TObject; var avalue: integer; + var accept: Boolean); + procedure signumtoonsetvalue(const sender: TObject; var avalue: Integer; + var accept: Boolean); + procedure fontondataentered(const sender: TObject); + procedure makepageonchildscaled(const sender: TObject); + procedure debuggerlayoutexe(const sender: TObject); + procedure macronchildscaled(const sender: TObject); + procedure formtemplateonchildscaled(const sender: TObject); + procedure encodingsetvalue(const sender: TObject; var avalue: integer; + var accept: Boolean); + procedure createexe(const sender: TObject); + procedure drawcol(const sender: tpointeredit; const acanvas: tcanvas; + const avalue: Pointer; const arow: Integer); + procedure colsetvalue(const sender: TObject; var avalue: colorty; + var accept: Boolean); + procedure copycolorcode(const sender: TObject); + procedure downloadchange(const sender: TObject); + procedure processorchange(const sender: TObject); + procedure copymessagechanged(const sender: TObject); + procedure updatedebugenabled(const sender: TObject); + procedure newprojectchildscaled(const sender: TObject); + procedure saveexe(const sender: TObject); + procedure settingsdataent(const sender: TObject); + procedure loadexe(const sender: TObject); +// procedure extconschangeexe(const sender: TObject); + procedure setxtermcommandexe(const sender: TObject; var avalue: msestring; + var accept: Boolean); + procedure activateonbreakset(const sender: TObject; var avalue: Boolean; + var accept: Boolean); + procedure sourcedirhint(const sender: TObject; var info: hintinfoty); + procedure toolshortcutdropdown(const sender: TObject); + procedure toolsrowdatachanged(const sender: tcustomgrid; + const acell: gridcoordty); + procedure colorhint(const sender: TObject; var info: hintinfoty); + procedure initeolstyleexe(const sender: tenumtypeedit); + procedure debugtargetlayoutev(const sender: TObject); + private + procedure activegroupchanged; + end; + +function readprojectoptions(const filename: filenamety): boolean; + //true if ok +procedure saveprojectoptions(filename: filenamety = ''); +procedure initprojectoptions; +function editprojectoptions: boolean; + //true if not aborted +function getprojectmacros: macroinfoarty; +procedure expandprojectmacros; +function expandprmacros(const atext: msestring): msestring; +procedure expandprmacros1(var atext: msestring); +function projecttemplatedir: filenamety; +function projectfiledialog(var aname: filenamety; save: boolean): modalresultty; +procedure projectoptionsmodified; +function checkprojectloadabort: boolean; //true on load abort + +function getsigname(const anum: integer): string; +procedure projectoptionstofont(const afont: tfont); +function objpath(const aname: filenamety): filenamety; +function sourcepath(const aname: filenamety): filenamety; +function gettargetfile: filenamety; +function getmacros: tmacrolist; +procedure hintmacros(const sender: tcustomedit; var info: hintinfoty); + +var + projectoptions: projectoptionsty; + projecthistory: filenamearty; + windowlayoutfile: filenamety; + windowlayouthistory: filenamearty; + codetemplates: tcodetemplates; + +implementation +uses + projectoptionsform_mfm,breakpointsform,sourceform,msereal, + objectinspector,msebits,msefileutils,msedesignintf,guitemplates, + watchform,stackform,main,projecttreeform,findinfileform, + selecteditpageform,programparametersform,sourceupdate,mseimagelisteditor, + msesysenvmanagereditor,targetconsole,actionsmodule,mseactions, + msefilemacros,mseenvmacros,msemacmacros,mseexecmacros,msestrmacros, + msedesigner,panelform,watchpointsform,commandlineform,messageform, + componentpaletteform,mserichstring,msesettings,formdesigner, + msestringlisteditor,msetexteditor,msepropertyeditors,mseshapes, + componentstore,cpuform,msesysutils,msecomptree,msefont,typinfo + {$ifndef mse_no_db}{$ifdef FPC},msedbfieldeditor{$endif}{$endif} + {$ifndef mse_no_ifi}{$ifdef FPC},mseificomponenteditors, + mseififieldeditor{$endif}{$endif}; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +var + projectoptionsfo: tprojectoptionsfo; +type + + stringconststy = ( + wrongencoding, //0 Wrong encoding can damage your source files. + wishsetencoding, //1 Do you wish to set encoding to + warning, //2 *** WARNING *** + c_SIGHUP, //3 Hangup + c_SIGINT, //4 Interrupt + c_SIGQUIT, //5 Quit + c_SIGILL, //6 Illegal instruction + c_SIGTRAP, //7 Trace trap + c_SIGABRT, //8 Abort + c_SIGBUS, //9 BUS error + c_SIGFPE, //10 Floating-point exception + c_SIGKILL, //11 Kill + c_SIGUSR1, //12 User-defined signal 1 + c_SIGSEGV, //13 Segmentation violation + c_SIGUSR2, //14 User-defined signal 2 + c_SIGPIPE, //15 Broken pipe + c_SIGALRM, //16 Alarm clock + c_SIGTERM, //17 Termination + c_SIGSTKFLT, //18 Stack fault + c_SIGCHLD, //19 Child status has changed + c_SIGCONT, //20 Continue + c_SIGSTOP, //21 Stop, unblockable + c_SIGTSTP, //22 Keyboard stop + c_SIGTTIN, //23 Background read from tty + c_SIGTTOU, //24 Background write to tty + c_SIGURG, //25 Urgent condition on socket + c_SIGXCPU, //26 CPU limit exceeded + c_SIGXFSZ, //27 File size limit exceeded + c_SIGTALRM, //28 Virtual alarm clock + c_SIGPROF, //29 Profiling alarm clock + c_SIGWINCH, //30 Window size change + c_SIGIO, //31 I/O now possible + c_SIGPWR //32 Power failure restart + ); +const + firstsiginfocomment = c_sighup; + lastsiginfocomment = c_sigpwr; + +type + signalinfoty = record + num: integer; + flags: sigflagsty; + name: string; + comment: string; + end; + +const + findinfiledialogstatname = 'findinfiledialogfo.sta'; + finddialogstatname = 'finddialogfo.sta'; + replacedialogstatname = 'replacedialogfo.sta'; + optionsstatname = 'optionsfo.sta'; + settaborderstatname = 'settaborderfo.sta'; + setcreateorderstatname = 'setcreateorderfo.sta'; + programparametersstatname = 'programparametersfo.sta'; + settingsstatname = 'settingsfo.sta'; + printerstatname = 'printer.sta'; + imageselectorstatname = 'imageselector.sta'; + fadeeditorstatname = 'fadeeditor.sta'; + codetemplateselectstatname ='templselect.sta'; + codetemplateparamstatname = 'templparam.sta'; + codetemplateeditstatname = 'templedit.sta'; + cornermaskeditstatname = 'cornermask.sta'; + memodialogstatname = 'memodialog.sta'; + richmemodialogstatname = 'richmemodialog.sta'; + fontformatdialogstatname = 'fontformatdialog.sta'; + taborderoverridedialogstatname = 'taborderoverrideeditor.sta'; + + siginfocount = 30; +var + siginfos: array[0..siginfocount-1] of signalinfoty = ( + (num: 1; flags: [sfl_stop]; name: 'SIGHUP'; comment: 'Hangup'), + (num: 2; flags: [sfl_stop,sfl_internal,sfl_handle]; name: 'SIGINT'; comment: 'Interrupt'), + (num: 3; flags: [sfl_stop]; name: 'SIGQUIT'; comment: 'Quit'), + (num: 4; flags: [sfl_stop]; name: 'SIGILL'; comment: 'Illegal instruction'), + (num: 5; flags: [sfl_stop,sfl_internal,sfl_handle]; name: 'SIGTRAP'; comment: 'Trace trap'), + (num: 6; flags: [sfl_stop]; name: 'SIGABRT'; comment: 'Abort'), + (num: 7; flags: [sfl_stop]; name: 'SIGBUS'; comment: 'BUS error'), + (num: 8; flags: [sfl_stop]; name: 'SIGFPE'; comment: 'Floating-point exception'), + (num: 9; flags: [sfl_stop]; name: 'SIGKILL'; comment: 'Kill, unblockable'), + (num: 10; flags: [sfl_stop]; name: 'SIGUSR1'; comment: 'User-defined signal 1'), + (num: 11; flags: [sfl_stop]; name: 'SIGSEGV'; comment: 'Segmentation violation'), + (num: 12; flags: [sfl_stop]; name: 'SIGUSR2'; comment: 'User-defined signal 2'), + (num: 13; flags: [sfl_stop]; name: 'SIGPIPE'; comment: 'Broken pipe'), + (num: 14; flags: [sfl_internal]; name: 'SIGALRM'; comment: 'Alarm clock'), + (num: 15; flags: [sfl_stop]; name: 'SIGTERM'; comment: 'Termination'), + (num: 16; flags: [sfl_stop]; name: 'SIGSTKFLT'; comment: 'Stack fault'), + (num: 17; flags: [{sfl_stop}]; name: 'SIGCHLD'; comment: 'Child status has changed'), + (num: 18; flags: [sfl_stop]; name: 'SIGCONT'; comment: 'Continue'), + (num: 19; flags: [sfl_stop]; name: 'SIGSTOP'; comment: 'Stop, unblockable'), + (num: 20; flags: [sfl_stop]; name: 'SIGTSTP'; comment: 'Keyboard stop'), + (num: 21; flags: [sfl_stop]; name: 'SIGTTIN'; comment: 'Background read from tty'), + (num: 22; flags: [sfl_stop]; name: 'SIGTTOU'; comment: 'Background write to tty'), + (num: 23; flags: [sfl_stop]; name: 'SIGURG'; comment: 'Urgent condition on socket'), + (num: 24; flags: [sfl_stop]; name: 'SIGXCPU'; comment: 'CPU limit exceeded'), + (num: 25; flags: [sfl_stop]; name: 'SIGXFSZ'; comment: 'File size limit exceeded'), + (num: 26; flags: [sfl_stop]; name: 'SIGTALRM'; comment: 'Virtual alarm clock'), + (num: 27; flags: [sfl_stop]; name: 'SIGPROF'; comment: 'Profiling alarm clock'), + (num: 28; flags: [sfl_stop]; name: 'SIGWINCH'; comment: 'Window size change'), + (num: 29; flags: [sfl_stop]; name: 'SIGIO'; comment: 'I/O now possible'), + (num: 30; flags: [sfl_stop]; name: 'SIGPWR'; comment: 'Power failure restart') + ); + +function getsigname(const anum: integer): string; +var + int1: integer; +begin + result:= ''; + for int1:= 0 to high(siginfos) do begin + if siginfos[int1].num = anum then begin + result:= siginfos[int1].name; + break; + end; + end; + if result = '' then begin + result:= 'SIG'+inttostr(anum); + end; +end; + +function objpath(const aname: filenamety): filenamety; +begin + result:= ''; + if aname <> '' then begin + result:= filepath(projectoptions.k.texp.makedir,aname); + end; +end; + +function sourcepath(const aname: filenamety): filenamety; +begin + result:= ''; + if aname <> '' then begin + if projectoptions.d.t.sourcebase <> '' then begin + result:= filepath(projectoptions.d.texp.sourcebase,aname); + end + else begin + result:= objpath(aname); + end; + end; +end; + +function getprojectmacros: macroinfoarty; +var + int1,int2: integer; +begin + setlength(result,6); + with projectoptions,k do begin + with result[0] do begin + name:= 'PROJECTNAME'; + value:= removefileext(filename(projectfilename)) + end; + with result[1] do begin + name:= 'PROJECTDIR'; + value:= tosysfilepath(getcurrentdirmse)+pathdelim; + end; + with result[2] do begin + name:= 'MAINFILE'; + if projectoptionsfo = nil then begin + value:= t.mainfile; + end + else begin + value:= projectoptionsfo.mainfile.value; + end; + end; + with result[3] do begin + name:= 'TARGETFILE'; + if projectoptionsfo = nil then begin + value:= t.targetfile; + end + else begin + value:= projectoptionsfo.targetfile.value; + end; + end; + with result[4] do begin + name:= 'TARGETENV'; + int2:= high(envvarons); + if int2 > high(d.t.envvarnames) then begin + int2:= high(d.t.envvarnames); + end; + if int2 > high(d.t.envvarvalues) then begin + int2:= high(d.t.envvarvalues); + end; + for int1:= 0 to int2 do begin + if envvarons[int1] then begin + value:= value+d.t.envvarnames[int1]+'='+d.t.envvarvalues[int1]+' '; + end + else begin + value:= value+'--unset='+d.t.envvarnames[int1]+' '; + end; + end; + end; + with result[5] do begin + name:= 'TARGETPARAMS'; + value:= d.t.progparameters; + end; + end; + result:= initmacros([result,macmacros,filemacros,envmacros,execmacros, + strmacros]); +end; + +procedure hintmacros(const sender: tcustomedit; var info: hintinfoty); +begin + info.caption:= tcustomedit(sender).text; + expandprmacros1(info.caption); + include(info.flags,hfl_show); //show empty caption +end; + +function gettargetfile: filenamety; +begin + with projectoptions,d.texp do begin + if trim(debugtarget) <> '' then begin + result:= objpath(debugtarget); + end + else begin + result:= objpath(k.texp.targetfile); + end; + end; +end; + +procedure projectoptionstofont(const afont: tfont); +begin + with projectoptions,afont do begin + name:= ansistring(e.editfontname); + height:= e.editfontheight; + width:= e.editfontwidth; + extraspace:= e.editfontextraspace; + if e.editfontantialiased then begin + options:= options + [foo_antialiased2]; + end + else begin + options:= options + [foo_nonantialiased]; + end; + color:= e.editfontcolor; + end; +end; + +function checkprojectloadabort: boolean; +begin + result:= false; + if exceptobject is exception then begin + if showmessage(msestring(exception(exceptobject).Message), + actionsmo.c[ord(ac_error)],[mr_skip,mr_cancel]) <> mr_skip then begin + result:= true; + end; + end + else begin + raise exception.create(ansistring(actionsmo.c[ord(ac_invalidexception)])); + end; +end; + +function projectfiledialog(var aname: filenamety; save: boolean): modalresultty; +begin + with mainfo.projectfiledia.controller do begin + filename:= projectoptions.projectfilename; + history:= projecthistory; + if save then begin + result:= execute(fdk_save,[fdo_save,fdo_checkexist]); + end + else begin + result:= execute(fdk_open,[fdo_checkexist]); + end; + aname:= filename; + projecthistory:= history; + end; +end; + +function getmacros: tmacrolist; +var + ar1: macroinfoarty; + int1,int2: integer; + mask: integer; + +begin + with projectoptions.m do begin + result:= tmacrolist.create([mao_caseinsensitive]); + result.add(getsettingsmacros); + result.add(getcommandlinemacros); + result.add(getprojectmacros); + mask:= bits[projectoptions.s.macrogroup]; + setlength(fmacrovalues,length(macronames)); + setlength(ar1,length(macronames)); //max + int2:= 0; + for int1:= 0 to high(ar1) do begin + if macroon[int1] and mask <> 0 then begin + ar1[int2].name:= macronames[int1]; + ar1[int2].value:= macrovalues[int1]; + inc(int2); + end; + end; + setlength(ar1,int2); + result.add(ar1); + end; +end; + +procedure expandprmacros1(var atext: msestring); +var + li: tmacrolist; +begin + li:= getmacros; + li.expandmacros1(atext); + li.Free; +end; + +function projecttemplatedir: filenamety; +begin + result:= expandprmacros('${TEMPLATEDIR}'); +end; + +function expandprmacros(const atext: msestring): msestring; +begin + result:= atext; + expandprmacros1(result); +end; + +var + initfontaliascount: integer; + +procedure expandprojectmacros; +var + li: tmacrolist; + int1,int2: integer; + bo1: boolean; + item1: tmenuitem; + act1: taction; +begin + li:= getmacros; + with projectoptions do begin +// o.expandmacros(li); + e.expandmacros(li); + d.expandmacros(li); + m.expandmacros(li); + k.expandmacros(li); + a.expandmacros(li); + u.expandmacros(li); + f.expandmacros(li); + p.expandmacros(li); + t.expandmacros(li); + r.expandmacros(li); + s.expandmacros(li); + with a,texp do begin + if initfontaliascount = 0 then begin + initfontaliascount:= fontaliascount; + end; + setfontaliascount(initfontaliascount); + int2:= high(fontalias); + int1:= high(fontancestors); + setlength(ffontancestors,int2+1); //additional field + for int1:= int1+1 to int2 do begin + fontancestors[int1]:= 'sft_default'; + end; + if int2 > high(fontnames) then begin + int2:= high(fontnames); + end; + if int2 > high(fontheights) then begin + int2:= high(fontheights); + end; + if int2 > high(fontwidths) then begin + int2:= high(fontwidths); + end; + if int2 > high(fontoptions) then begin + int2:= high(fontoptions); + end; + if int2 > high(fontxscales) then begin + int2:= high(fontxscales); + end; + for int1:= 0 to int2 do begin + try + registerfontalias(ansistring(fontalias[int1]), + ansistring(fontnames[int1]),fam_overwrite, + fontheights[int1],fontwidths[int1], + fontoptioncharstooptions(ansistring(fontoptions[int1])), + fontxscales[int1],ansistring(fontancestors[int1])); + except + application.handleexception; + end; + end; + if sourceupdater <> nil then begin + sourceupdater.maxlinelength:= e.rightmarginchars; + end; + fontaliasnames:= fontalias; + end; + with s,texp do begin + with sourcefo.syntaxpainter do begin + bo1:= not cmparray(defdefs.asarraya,e.texp.sourcefilemasks) or + not cmparray(defdefs.asarrayb,e.texp.syntaxdeffiles); + defdefs.asarraya:= e.texp.sourcefilemasks; + defdefs.asarrayb:= e.texp.syntaxdeffiles; + if bo1 then begin + sourcefo.syntaxpainter.clear; + try + for int1:= 0 to sourcefo.count - 1 do begin + sourcefo.items[int1].edit.setsyntaxdef(sourcefo.items[int1].edit.filename); + end; + except + application.handleexception; + end; + end; + end; + for int1:= 0 to sourcefo.count - 1 do begin + sourcefo.items[int1].updatestatvalues; + end; + with mainfo.openfile.controller.filterlist do begin + asarraya:= e.texp.filemasknames; + asarrayb:= e.texp.filemasks; + end; + item1:= mainfo.mainmenu1.menu.itembynames(['file','new']); + item1.submenu.count:= 1; + with p.texp do begin + item1.submenu.count:= length(newfinames)+1; + for int1:= 0 to high(newfinames) do begin + with item1.submenu[int1+1] do begin + caption:= newfinames[int1]; + tag:= int1; + onexecute:= {$ifdef FPC}@{$endif}mainfo.newfileonexecute; + end; + end; + + item1:= mainfo.mainmenu1.menu.itembynames(['file','new','form']); + item1.submenu.count:= 0; + item1.submenu.count:= length(newfonames)+1; + int2:= 0; + for int1:= 0 to high(newfonames) do begin + if not p.newinheritedforms[int1] then begin + with item1.submenu[int2] do begin + caption:= newfonames[int1]; + tag:= int1; + onexecute:= {$ifdef FPC}@{$endif}mainfo.newformonexecute; + end; + inc(int2); + end; + end; + item1.submenu[int2].options:= [mao_separator]; + inc(int2); + for int1:= 0 to high(newfonames) do begin + if p.newinheritedforms[int1] then begin + with item1.submenu[int2] do begin + caption:= newfonames[int1]; + tag:= int1; + onexecute:= {$ifdef FPC}@{$endif}mainfo.newformonexecute; + end; + inc(int2); + end; + end; + end; + with mainfo.mainmenu1.menu.submenu do begin + item1:= itembyname('tools'); + with projectoptions.t,texp do begin + if toolmenus <> nil then begin + if item1 = nil then begin + item1:= tmenuitem.create; + item1.name:= 'tools'; + item1.caption:= actionsmo.c[ord(ac_tools)]; + insert(itemindexbyname('settings'),item1); + end; + with item1.submenu do begin + clear; + for int1:= 0 to high(toolmenus) do begin + if (int1 > high(toolfiles)) or (int1 > high(toolparams)) then begin + break; + end; + int2:= insert(bigint,[toolmenus[int1]], + [[mao_asyncexecute,mao_shortcutcaption]], + [],[{$ifdef FPC}@{$endif}mainfo.runtool]); + if (int1 <= high(toolshortcuts)) and + actionsmo.gettoolshortcutaction(toolshortcuts[int1],act1) then begin + with items[int2] do begin + shortcuts:= act1.shortcuts; + shortcuts1:= act1.shortcuts1; + end; + end; + end; + end; + end + else begin + if item1 <> nil then begin + delete(item1.index); + end; + end; + end; + end; + end; + ignoreexceptionclasses:= nil; + for int1:= 0 to high(d.exceptignore) do begin + if int1 > high(d.exceptclassnames) then begin + break; + end; + if d.exceptignore[int1] then begin + additem(ignoreexceptionclasses,ansistring(d.exceptclassnames[int1])); + end; + end; + for int1:= 0 to usercolorcount - 1 do begin + if int1 > high(u.usercolors) then begin + break; + end; + setcolormapvalue(cl_user + longword(int1),u.usercolors[int1]); + end; + clearformatmacros; + for int1:= 0 to high(f.texp.formatmacronames) do begin + if int1 > high(f.texp.formatmacrovalues) then begin + break; + end; + formatmacros.add(f.texp.formatmacronames[int1],f.texp.formatmacrovalues[int1],[]); + end; + + codetemplates.scan(e.texp.codetemplatedirs); + end; + li.free; + mainfo.updatesigsettings; +end; + +function defaultsigsettings: sigsetinfoarty; +var + int1,int2: integer; +begin + setlength(result,siginfocount); + int2:= 0; + for int1:= 0 to siginfocount - 1 do begin + with result[int2] do begin + if not (sfl_internal in siginfos[int1].flags) then begin + num:= siginfos[int1].num; + numto:= num; + flags:= siginfos[int1].flags; + inc(int2); + end; + end; + end; + setlength(result,int2); +end; + +procedure freeoptions(); +begin +// projectoptions.o.free(); + projectoptions.e.free(); + projectoptions.d.free(); + projectoptions.k.free(); + projectoptions.m.free(); + projectoptions.a.free(); + projectoptions.u.free(); + projectoptions.f.free(); + projectoptions.t.free(); + projectoptions.r.free(); + projectoptions.p.free(); + projectoptions.s.free(); +end; + +procedure createoptions(); +begin +// projectoptions.o:= tprojectoptions.create(); + projectoptions.e:= teditoptions.create(); + projectoptions.d:= tdebugoptions.create(); + projectoptions.k:= tmakeoptions.create(); + projectoptions.m:= tmacrooptions.create(); + projectoptions.a:= tfontaliasoptions.create(); + projectoptions.u:= tusercoloroptions.create(); + projectoptions.f:= tformatmacrooptions.create(); + projectoptions.t:= ttoolsoptions.create(); + projectoptions.r:= tstorageoptions.create(); + projectoptions.p:= ttemplatesoptions.create(); + projectoptions.s:= tprojectstate.create(); +end; + +procedure initpr(const expand: boolean); +const + alloptionson = 1+2+4+8+16+32; + unitson = 1+2+4+8+16+32+$10000; + allon = unitson+$20000+$40000; +var + int1: integer; +begin + freeoptions(); + codetemplates.clear(); + finalize(projectoptions); + fillchar(projectoptions,sizeof(projectoptions),0); + createoptions(); + with projectoptions,k,t do begin + if expand then begin + deletememorystatstream(findinfiledialogstatname); + deletememorystatstream(finddialogstatname); + deletememorystatstream(replacedialogstatname); + deletememorystatstream(optionsstatname); + deletememorystatstream(settaborderstatname); + deletememorystatstream(setcreateorderstatname); + deletememorystatstream(programparametersstatname); + deletememorystatstream(printerstatname); + deletememorystatstream(imageselectorstatname); + deletememorystatstream(stringlisteditorstatname); + deletememorystatstream(texteditorstatname); + deletememorystatstream(colordialogstatname); + deletememorystatstream(compnamedialogstatname); + deletememorystatstream(bmpfiledialogstatname); + deletememorystatstream(fadeeditorstatname); + deletememorystatstream(codetemplateselectstatname); + deletememorystatstream(codetemplateparamstatname); + deletememorystatstream(codetemplateeditstatname); + deletememorystatstream(cornermaskeditstatname); + deletememorystatstream(memodialogstatname); + deletememorystatstream(richmemodialogstatname); + deletememorystatstream(fontformatdialogstatname); + deletememorystatstream(taborderoverridedialogstatname); + {$ifndef mse_no_db}{$ifdef FPC} + deletememorystatstream(dbfieldeditorstatname); + {$endif}{$endif} + {$ifndef mse_no_ifi}{$ifdef FPC} + deletememorystatstream(ificlienteditorstatname); + deletememorystatstream(ififieldeditorstatname); + {$endif}{$endif} + modified:= false; + savechecked:= false; + findreplaceinfo.find.options:= [so_caseinsensitive]; + targetconsolefindinfo.options:= [so_caseinsensitive]; + end; + sigsettings:= defaultsigsettings; + ignoreexceptionclasses:= nil; + + additem(fmakeoptions,'-l -Mobjfpc -Sh -Fcutf8'); + additem(fmakeoptions,'-gl -O-'); + additem(fmakeoptions,'-B'); + additem(fmakeoptions,'-O2 -XX -CX -Xs'); + setlength(fmakeoptionson,length(fmakeoptions)); + for int1:= 0 to high(fmakeoptionson) do begin + fmakeoptionson[int1]:= alloptionson; + end; + fmakeoptionson[1]:= alloptionson and not bits[5]; + //all but make 4 + fmakeoptionson[2]:= bits[1] or bits[5]; //build + make 4 + fmakeoptionson[3]:= bits[5]; //make 4 + defaultmake:= 1; //make + additem(funitdirs,'${MSELIBDIR}*/'); +// additem(funitdirs,'${MSELIBDIR}kernel/'); + additem(funitdirs,'${MSELIBDIR}kernel/$TARGETOSDIR/'); + setlength(funitdirson,length(unitdirs)); + for int1:= 0 to high(funitdirson) do begin + funitdirson[int1]:= unitson; + end; +// funitdirson[1]:= unitson + $20000; //kernel include + unitdirs:= reversearray(unitdirs); + unitdirson:= reversearray(unitdirson); + unitpref:= '-Fu'; + incpref:= '-Fi'; + libpref:= '-Fl'; + objpref:= '-Fo'; + targpref:= '-o'; + makecommand:= '${COMPILER}'; + with p,t do begin + setlength(fnewfinames,3); + setlength(fnewfifilters,3); + setlength(fnewfiexts,3); + setlength(fnewfisources,3); + + newfinames[0]:= actionsmo.c[ord(ac_program)]; + newfifilters[0]:= '"*.pas" "*.pp"'; + newfiexts[0]:= 'pas'; + newfisources[0]:= '${TEMPLATEDIR}default/program.pas'; + + newfinames[1]:= actionsmo.c[ord(ac_unit)]; + newfifilters[1]:= '"*.pas" "*.pp"'; + newfiexts[1]:= 'pas'; + newfisources[1]:= '${TEMPLATEDIR}default/unit.pas'; + + newfinames[2]:= actionsmo.c[ord(ac_textfile)]; + newfifilters[2]:= ''; + newfiexts[2]:= ''; + newfisources[2]:= ''; + + setlength(fnewfonames,12); + setlength(fnewfonamebases,12); + setlength(fnewfoformsuffixes,12); + setlength(p.fnewinheritedforms,12); + setlength(fnewfosources,12); + setlength(fnewfoforms,12); + + newfonames[0]:= actionsmo.c[ord(ac_mainform)]; + newfonamebases[0]:= 'form'; + newfoformsuffixes[0]:= 'fo'; + newinheritedforms[0]:= false; + newfosources[0]:= '${TEMPLATEDIR}default/mainform.pas'; + newfoforms[0]:= '${TEMPLATEDIR}default/mainform.mfm'; + + newfonames[1]:= actionsmo.c[ord(ac_simpleform)]; + newfonamebases[1]:= 'form'; + newfoformsuffixes[1]:= 'fo'; + newinheritedforms[1]:= false; + newfosources[1]:= '${TEMPLATEDIR}default/simpleform.pas'; + newfoforms[1]:= '${TEMPLATEDIR}default/simpleform.mfm'; + + newfonames[2]:= actionsmo.c[ord(ac_dockingform)]; + newfonamebases[2]:= 'form'; + newfoformsuffixes[2]:= 'fo'; + newinheritedforms[2]:= false; + newfosources[2]:= '${TEMPLATEDIR}default/dockingform.pas'; + newfoforms[2]:= '${TEMPLATEDIR}default/dockingform.mfm'; + + newfonames[3]:= actionsmo.c[ord(ac_sizingform)]; + newfonamebases[3]:= 'form'; + newfoformsuffixes[3]:= 'fo'; + newinheritedforms[3]:= false; + newfosources[3]:= '${TEMPLATEDIR}default/sizingform.pas'; + newfoforms[3]:= '${TEMPLATEDIR}default/sizingform.mfm'; + + newfonames[4]:= actionsmo.c[ord(ac_datamodule)]; + newfonamebases[4]:= 'module'; + newfoformsuffixes[4]:= 'mo'; + newinheritedforms[4]:= false; + newfosources[4]:= '${TEMPLATEDIR}default/datamodule.pas'; + newfoforms[4]:= '${TEMPLATEDIR}default/datamodule.mfm'; + + newfonames[5]:= actionsmo.c[ord(ac_subform)]; + newfonamebases[5]:= 'form'; + newfoformsuffixes[5]:= 'fo'; + newinheritedforms[5]:= false; + newfosources[5]:= '${TEMPLATEDIR}default/subform.pas'; + newfoforms[5]:= '${TEMPLATEDIR}default/subform.mfm'; + + newfonames[6]:= actionsmo.c[ord(ac_scrollboxform)]; + newfonamebases[6]:= 'form'; + newfoformsuffixes[6]:= 'fo'; + newinheritedforms[6]:= false; + newfosources[6]:= '${TEMPLATEDIR}default/scrollboxform.pas'; + newfoforms[6]:= '${TEMPLATEDIR}default/scrollboxform.mfm'; + + newfonames[7]:= actionsmo.c[ord(ac_tabform)]; + newfonamebases[7]:= 'form'; + newfoformsuffixes[7]:= 'fo'; + newinheritedforms[7]:= false; + newfosources[7]:= '${TEMPLATEDIR}default/tabform.pas'; + newfoforms[7]:= '${TEMPLATEDIR}default/tabform.mfm'; + + newfonames[8]:= actionsmo.c[ord(ac_dockpanel)]; + newfonamebases[8]:= 'form'; + newfoformsuffixes[8]:= 'fo'; + newinheritedforms[8]:= false; + newfosources[8]:= '${TEMPLATEDIR}default/dockpanelform.pas'; + newfoforms[8]:= '${TEMPLATEDIR}default/dockpanelform.mfm'; + + newfonames[9]:= actionsmo.c[ord(ac_report)]; + newfonamebases[9]:= 'report'; + newfoformsuffixes[9]:= 're'; + newinheritedforms[9]:= false; + newfosources[9]:= '${TEMPLATEDIR}default/report.pas'; + newfoforms[9]:= '${TEMPLATEDIR}default/report.mfm'; + + newfonames[10]:= actionsmo.c[ord(ac_scriptform)]; + newfonamebases[10]:= 'script'; + newfoformsuffixes[10]:= 'sc'; + newinheritedforms[10]:= false; + newfosources[10]:= '${TEMPLATEDIR}default/pascform.pas'; + newfoforms[10]:= '${TEMPLATEDIR}default/pascform.mfm'; + + newfonames[11]:= actionsmo.c[ord(ac_inheritedform)]; + newfonamebases[11]:= 'form'; + newfoformsuffixes[11]:= 'fo'; + newinheritedforms[11]:= true; + newfosources[11]:= '${TEMPLATEDIR}default/inheritedform.pas'; + newfoforms[11]:= '${TEMPLATEDIR}default/inheritedform.mfm'; + end; + + end; + with projectoptions,e,t do begin + + additem(fsourcefilemasks,'"*.pas" "*.dpr" "*.lpr" "*.pp" "*.inc"'); + additem(fsyntaxdeffiles,'${SYNTAXDEFDIR}pascal.sdef'); + additem(fsourcefilemasks,'"*.c" "*.cc" "*.h"'); + additem(fsyntaxdeffiles,'${SYNTAXDEFDIR}cpp.sdef'); + additem(fsourcefilemasks,'"*.mfm"'); + additem(fsyntaxdeffiles,'${SYNTAXDEFDIR}objecttext.sdef'); + + additem(ffilemasknames,actionsmo.c[ord(ac_source)]); + additem(ffilemasks,'"*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr"'); + additem(ffilemasknames,actionsmo.c[ord(ac_forms)]); + additem(ffilemasks,'*.mfm'); + additem(ffilemasknames,actionsmo.c[ord(ac_allfiles)]); + additem(ffilemasks,'*'); + + end; + with projectoptions,d,t do begin + debugcommand:= '${DEBUGGER}'; + gdbprocessor:= 'auto'; + additem(fsourcedirs,'./'); + additem(fsourcedirs,'${MSELIBDIR}*/'); + additem(fsourcedirs,'${MSELIBDIR}kernel/$TARGETOSDIR/'); + sourcedirs:= reversearray(sourcedirs); + end; + if expand then begin + expandprojectmacros; + end; +end; + +procedure initprojectoptions; +begin + initpr(true); +end; + +procedure projectoptionsmodified; +begin + projectoptions.modified:= true; + projectoptions.savechecked:= false; +end; + +procedure setsignalinfocount(const count: integer); +begin + if count = 0 then begin + projectoptions.sigsettings:= defaultsigsettings; + end + else begin + setlength(projectoptions.sigsettings,count); + end; +end; + +procedure storesignalinforec(const index: integer; + const avalue: msestring); +var + stop,handle: boolean; +begin + with projectoptions.sigsettings[index] do begin + decoderecord(avalue,[@num,@numto,@stop,@handle],'iibb'); + updatebit({$ifdef FPC}longword{$else}byte{$endif}(flags),ord(sfl_stop),stop); + updatebit({$ifdef FPC}longword{$else}byte{$endif}(flags),ord(sfl_handle),handle); + end; +end; + +function getsignalinforec(const index: integer): msestring; +var + stop,handle: boolean; +begin + with projectoptions.sigsettings[index] do begin + stop:= sfl_stop in flags; + handle:= sfl_handle in flags; + result:= encoderecord([num,numto,stop,handle]); + end; +end; + +procedure updateprojectsettings(const statfiler: tstatfiler; + const disabledoptions: settinggroupsty); +var + int1: integer; + i2: int32; +begin + with statfiler,projectoptions,s,t do begin + + if iswriter then begin + mainfo.statoptions.writestat(tstatwriter(statfiler)); + end + else begin + mainfo.statoptions.readstat(tstatreader(statfiler)); + with projectoptions.t do begin + setlength(ftoolmessages,length(ftoolsave)); + end; + end; + if not (sg_debugger in disabledoptions) then begin + if iswriter then begin + with tstatwriter(statfiler) do begin + writerecordarray('sigsettings',length(sigsettings), + {$ifdef FPC}@{$endif}getsignalinforec); + end; + end + else begin + with tstatreader(statfiler) do begin + readrecordarray('sigsettings',{$ifdef FPC}@{$endif}setsignalinfocount, + {$ifdef FPC}@{$endif}storesignalinforec); + end; + end; + end; + if not (sg_state in disabledoptions) then begin + updatevalue('defaultmake',defaultmake,1,maxdefaultmake+1); + end; + with p,t do begin + if not iswriter then begin + int1:= length(newfinames); + if int1 > length(newfifilters) then begin + int1:= length(newfifilters); + end; + if int1 > length(newfiexts) then begin + int1:= length(newfiexts); + end; + if int1 > length(newfisources) then begin + int1:= length(newfisources); + end; + setlength(fnewfinames,int1); + setlength(fnewfifilters,int1); + setlength(fnewfiexts,int1); + setlength(fnewfisources,int1); + end; + + if not iswriter then begin + int1:= length(newfonames); + if int1 > length(newfonamebases) then begin + int1:= length(newfonamebases); + end; + if high(newfoformsuffixes) <> high(newfonamebases) then begin + //probably old statfile + setlength(fnewfoformsuffixes,length(newfonamebases)); + for i2:= 0 to high(fnewfoformsuffixes) do begin + fnewfoformsuffixes[i2]:= copy(fnewfonamebases[i2],1,2) + end; + end; + if int1 > length(newfoformsuffixes) then begin + int1:= length(newfoformsuffixes); + end; + if int1 > length(newinheritedforms) then begin + int1:= length(newinheritedforms); + end; + if int1 > length(newfosources) then begin + int1:= length(newfosources); + end; + if int1 > length(newfoforms) then begin + int1:= length(newfoforms); + end; + setlength(fnewfonames,int1); + setlength(fnewfonamebases,int1); + setlength(fnewfoformsuffixes,int1); + setlength(fnewinheritedforms,int1); + setlength(fnewfosources,int1); + setlength(fnewfoforms,int1); + end; + end; + end; +end; + +procedure doloadexe(const sender: tprojectoptionsfo); forward; +procedure dosaveexe(const sender: tprojectoptionsfo); forward; + +function getdisabledoptions: settinggroupsty; +begin + result:= [sg_state]; + with projectoptions do begin + if not r.settingseditor then begin + include(result,sg_editor); + end; + if not r.settingsdebugger then begin + include(result,sg_debugger); + end; + if not r.settingsmake then begin + include(result,sg_make); + end; + if not r.settingsmacros then begin + include(result,sg_macros); + end; + if not r.settingsfontalias then begin + include(result,sg_fontalias); + end; + if not r.settingsusercolors then begin + include(result,sg_usercolors); + end; + if not r.settingsformatmacros then begin + include(result,sg_formatmacros); + end; + if not r.settingstemplates then begin + include(result,sg_templates); + end; + if not r.settingstools then begin + include(result,sg_tools); + end; + if not r.settingsstorage then begin + include(result,sg_storage); + end; + end; +end; + +procedure updateprojectoptions(const statfiler: tstatfiler; + const afilename: filenamety); +var + int1,int2,int3: integer; + b1: boolean; + modulenames1: msestringarty; + moduletypes1: msestringarty; + + modulefiles1: filenamearty; +// moduledock1: msestringarty; +begin + with statfiler,projectoptions do begin + if iswriter then begin + projectdir:= getcurrentdirmse; + with mainfo,mainmenu1.menu.itembyname('view') do begin + int3:= formmenuitemstart; + int2:= count - int3; + setlength(modulenames1,int2); + setlength(moduletypes1,int2); + setlength(modulefiles1,int2); +// setlength(moduledock1,int2); + for int1:= 0 to high(modulenames1) do begin + with pmoduleinfoty(submenu[int1+int3].tagpo)^ do begin + modulenames1[int1]:= msestring(struppercase(instance.name)); + moduletypes1[int1]:= msestring(struppercase(string(moduleclassname))); + modulefiles1[int1]:= filename; + end; + end; + s.modulenames:= modulenames1; + s.moduletypes:= moduletypes1; + s.modulefiles:= modulefiles1; + end; + end; + registeredcomponents.updatestat(statfiler); + setsection('projectoptions'); + updatevalue('projectdir',projectdir); + updatevalue('projectfilename',projectfilename); + projectfilename:= afilename; + updatememorystatstream('findinfiledialog',findinfiledialogstatname); + updatememorystatstream('finddialog',finddialogstatname); + updatememorystatstream('replacedialog',replacedialogstatname); + updatememorystatstream('options',optionsstatname); + updatememorystatstream('settaborder',settaborderstatname); + updatememorystatstream('setcreateorder',setcreateorderstatname); + updatememorystatstream('programparameters',programparametersstatname); + updatememorystatstream('settings',settingsstatname); + updatememorystatstream('printer',printerstatname); + updatememorystatstream('imageselector',imageselectorstatname); + updatememorystatstream('fadeeditor',fadeeditorstatname); + updatememorystatstream('stringlisteditor',stringlisteditorstatname); + updatememorystatstream('imagelisteditor',imagelisteditorstatname); + updatememorystatstream('sysenvmanagereditor',sysenvmanagereditorstatname); + updatememorystatstream('texteditor',texteditorstatname); + updatememorystatstream('colordialog',colordialogstatname); + updatememorystatstream('compnamedialog',compnamedialogstatname); + updatememorystatstream('bmpfiledialog',bmpfiledialogstatname); + updatememorystatstream('codetemplateselect',codetemplateselectstatname); + updatememorystatstream('codetemplateparam',codetemplateparamstatname); + updatememorystatstream('codetemplateedit',codetemplateeditstatname); + updatememorystatstream('cornermaskedit',cornermaskeditstatname); + updatememorystatstream('memodialog',memodialogstatname); + updatememorystatstream('richmemodialog',richmemodialogstatname); + updatememorystatstream('fontformatdialog',fontformatdialogstatname); + updatememorystatstream('taborderoverridedialog', + taborderoverridedialogstatname); +{$ifndef mse_no_db}{$ifdef FPC} + updatememorystatstream('dbfieldeditor',dbfieldeditorstatname); +{$endif}{$endif} +{$ifndef mse_no_ifi}{$ifdef FPC} + updatememorystatstream('ificlienteditor',ificlienteditorstatname); + updatememorystatstream('ififieldeditor',ififieldeditorstatname); +{$endif}{$endif} + + updateprojectsettings(statfiler,[]); + b1:= projecttree.updatestat(statfiler) or statfiler.iswriter; + breakpointsfo.updatestat(statfiler); + panelform.updatestat(statfiler); //uses section breakpoints! + if not b1 then begin + projecttree.updatestat(statfiler); //backward compatibility with section + //breakpoints + end; + componentstorefo.updatestat(statfiler); + + setsection('components'); + selecteditpageform.updatestat(statfiler); + programparametersform.updatestat(statfiler); + projectoptionstofont(textpropertyfont); + + if not iswriter then begin + if guitemplatesmo.sysenv.getintegervalue(int1, + ord(env_vargroup),1,6) then begin + s.macrogroup:= int1-1; + end; + expandprojectmacros; + projecttree.updatelist; + end; + + beginpanelplacement(); + try + sourcefo.updatestat(statfiler); //needs actual fontalias + setsection('layout'); + mainfo.projectstatfile.updatestat('windowlayout',statfiler); + finally + endpanelplacement(); + end; + setsection('targetconsole'); + targetconsole.updatestat(statfiler); + + modified:= false; + savechecked:= false; + + if iswriter then begin + if r.settingsautosave then begin + dosaveexe(nil); + end; + end + else begin + if r.settingsautoload then begin + doloadexe(nil); + end; + end; + end; +end; + +procedure projectoptionstoform(fo: tprojectoptionsfo); +var + int1,int2: integer; +begin + fo.optafter.tag:= optaftermainfilemask; + with projectoptions do begin + int1:= length(t.toolshortcuts); + setlength(t.ftoolshortcuts,length(t.t.toolmenus)); + for int2:= int1 to high(t.toolshortcuts) do begin + t.toolshortcuts[int2]:= -1; //init for backward compatibility + end; + end; + {$ifdef mse_with_ifi} + mainfo.statoptions.objtovalues(fo); + {$endif} + fo.colgrid.rowcount:= usercolorcount; + fo.colgrid.fixcols[-1].captions.count:= usercolorcount; + with fo,projectoptions do begin + for int1:= 0 to colgrid.rowhigh do begin + colgrid.fixcols[-1].captions[int1]:= + msestring(colortostring(cl_user+longword(int1))); + end; + end; + with fo.signame do begin + setlength(enums,siginfocount); + int2:= 0; + for int1:= 0 to siginfocount - 1 do begin + with siginfos[int1] do begin + if not (sfl_internal in flags) then begin + enums[int2]:= num; + dropdownitems.addrow([msestring(name),msestring(comment)]); + dropdown.cols.addrow([msestring(comment)+ ' ('+msestring(name)+')']); + inc(int2); + end; + end; + end; + setlength(enums,int2); + end; + with projectoptions{,t} do begin + fo.signalgrid.rowcount:= length(sigsettings); + for int1:= 0 to high(sigsettings) do begin + with sigsettings[int1] do begin + fo.signum[int1]:= num; + fo.signumto[int1]:= numto; + if num = numto then begin + fo.signame[int1]:= num; + end + else begin + fo.signame[int1]:= -1; + end; + fo.sigstop[int1]:= sfl_stop in flags; + fo.sighandle[int1]:= sfl_handle in flags; + end; + end; + fo.fontondataentered(nil); + fo.defaultmake.value:= lowestbit(defaultmake); + for int1:= 0 to fo.makeoptionsgrid.rowhigh do begin + if int1 > high(k.makeoptionson) then begin + break; + end; + fo.makeon.gridupdatetagvalue(int1,k.makeoptionson[int1]); + fo.buildon.gridupdatetagvalue(int1,k.makeoptionson[int1]); + fo.make1on.gridupdatetagvalue(int1,k.makeoptionson[int1]); + fo.make2on.gridupdatetagvalue(int1,k.makeoptionson[int1]); + fo.make3on.gridupdatetagvalue(int1,k.makeoptionson[int1]); + fo.make4on.gridupdatetagvalue(int1,k.makeoptionson[int1]); + fo.optafter.gridupdatetagvalue(int1,k.makeoptionson[int1]); + end; + + for int1:= 0 to fo.befcommandgrid.rowhigh do begin + if int1 > high(k.befcommandon) then begin + break; + end; + fo.befmakeon.gridupdatetagvalue(int1,k.befcommandon[int1]); + fo.befbuildon.gridupdatetagvalue(int1,k.befcommandon[int1]); + fo.befmake1on.gridupdatetagvalue(int1,k.befcommandon[int1]); + fo.befmake2on.gridupdatetagvalue(int1,k.befcommandon[int1]); + fo.befmake3on.gridupdatetagvalue(int1,k.befcommandon[int1]); + fo.befmake4on.gridupdatetagvalue(int1,k.befcommandon[int1]); + end; + + for int1:= 0 to fo.aftcommandgrid.rowhigh do begin + if int1 > high(k.aftcommandon) then begin + break; + end; + fo.aftmakeon.gridupdatetagvalue(int1,k.aftcommandon[int1]); + fo.aftbuildon.gridupdatetagvalue(int1,k.aftcommandon[int1]); + fo.aftmake1on.gridupdatetagvalue(int1,k.aftcommandon[int1]); + fo.aftmake2on.gridupdatetagvalue(int1,k.aftcommandon[int1]); + fo.aftmake3on.gridupdatetagvalue(int1,k.aftcommandon[int1]); + fo.aftmake4on.gridupdatetagvalue(int1,k.aftcommandon[int1]); + end; + + fo.unitdirs.gridvalues:= reversearray(k.t.unitdirs); + int2:= high(k.t.unitdirs); + for int1:= 0 to int2 do begin + if int1 > high(k.unitdirson) then begin + break; + end; + fo.dmakeon.gridupdatetagvalue(int2,k.unitdirson[int1]); + fo.dbuildon.gridupdatetagvalue(int2,k.unitdirson[int1]); + fo.dmake1on.gridupdatetagvalue(int2,k.unitdirson[int1]); + fo.dmake2on.gridupdatetagvalue(int2,k.unitdirson[int1]); + fo.dmake3on.gridupdatetagvalue(int2,k.unitdirson[int1]); + fo.dmake4on.gridupdatetagvalue(int2,k.unitdirson[int1]); + fo.duniton.gridupdatetagvalue(int2,k.unitdirson[int1]); + fo.dincludeon.gridupdatetagvalue(int2,k.unitdirson[int1]); + fo.dlibon.gridupdatetagvalue(int2,k.unitdirson[int1]); + fo.dobjon.gridupdatetagvalue(int2,k.unitdirson[int1]); + dec(int2); + end; + fo.activemacroselect[s.macrogroup]:= true; + fo.activegroupchanged; + setlength(m.fgroupcomments,6); + fo.groupcomment.gridvalues:= m.groupcomments; + + for int1:= 0 to fo.macrogrid.rowhigh do begin + if int1 > high(m.macroon) then begin + break; + end; + fo.e0.gridupdatetagvalue(int1,m.macroon[int1]); + fo.e1.gridupdatetagvalue(int1,m.macroon[int1]); + fo.e2.gridupdatetagvalue(int1,m.macroon[int1]); + fo.e3.gridupdatetagvalue(int1,m.macroon[int1]); + fo.e4.gridupdatetagvalue(int1,m.macroon[int1]); + fo.e5.gridupdatetagvalue(int1,m.macroon[int1]); + end; + + fo.sourcedirs.gridvalues:= reversearray(d.t.sourcedirs); + fo.syntaxdeffile.gridvalues:= e.t.syntaxdeffiles; + fo.syntaxdeffilemask.gridvalues:= e.t.sourcefilemasks; +// fo.grid[0].datalist.asarray:= e.t.syntaxdeffiles; +// fo.grid[1].datalist.asarray:= e.t.sourcefilemasks; + fo.filefiltergrid[0].datalist.asarray:= e.t.filemasknames; + fo.filefiltergrid[1].datalist.asarray:= e.t.filemasks; + fo.settingsdataent(nil); + + end; +end; + +procedure storemacros(fo: tprojectoptionsfo); +var + int1: integer; +begin + with projectoptions,m do begin + macronames:= fo.macronames.gridvalues; + macrovalues:= fo.macrovalues.gridvalues; + setlength(fmacroon,fo.macrogrid.rowcount); + for int1:= 0 to high(macroon) do begin + macroon[int1]:= fo.e0.gridvaluetag(int1,0) or fo.e1.gridvaluetag(int1,0) or + fo.e2.gridvaluetag(int1,0) or fo.e3.gridvaluetag(int1,0) or + fo.e4.gridvaluetag(int1,0) or fo.e5.gridvaluetag(int1,0); + end; + groupcomments:= fo.groupcomment.gridvalues; + end; +end; + +procedure formtoprojectoptions(fo: tprojectoptionsfo); +var + int1: integer; +begin +{$ifdef mse_with_ifi} + mainfo.statoptions.valuestoobj(fo); +{$endif} + fo.optafter.tag:= optaftermainfilemask; + with projectoptions do begin + setlength(sigsettings,fo.signalgrid.rowcount); + for int1:= 0 to high(sigsettings) do begin + with sigsettings[int1] do begin + num:= fo.signum[int1]; + numto:= fo.signumto[int1]; + updatebit({$ifdef FPC}longword{$else}byte{$endif}(flags),ord(sfl_stop), + fo.sigstop[int1]); + updatebit({$ifdef FPC}longword{$else}byte{$endif}(flags),ord(sfl_handle), + fo.sighandle[int1]); + end; + end; + + for int1:= high(a.fontxscales) downto 0 do begin + if a.fontxscales[int1] = emptyreal then begin + a.fontxscales[int1]:= 1.0; + end; + end; + + defaultmake:= 1 shl fo.defaultmake.value; + setlength(k.fmakeoptionson,fo.makeoptionsgrid.rowcount); + for int1:= 0 to high(k.fmakeoptionson) do begin + k.fmakeoptionson[int1]:= + fo.makeon.gridvaluetag(int1,0) or fo.buildon.gridvaluetag(int1,0) or + fo.make1on.gridvaluetag(int1,0) or fo.make2on.gridvaluetag(int1,0) or + fo.make3on.gridvaluetag(int1,0) or fo.make4on.gridvaluetag(int1,0) or + fo.optafter.gridvaluetag(int1,0); + end; + + setlength(k.fbefcommandon,fo.befcommandgrid.rowcount); + for int1:= 0 to high(k.fbefcommandon) do begin + k.fbefcommandon[int1]:= + fo.befmakeon.gridvaluetag(int1,0) or fo.befbuildon.gridvaluetag(int1,0) or + fo.befmake1on.gridvaluetag(int1,0) or fo.befmake2on.gridvaluetag(int1,0) or + fo.befmake3on.gridvaluetag(int1,0) or fo.befmake4on.gridvaluetag(int1,0); + end; + setlength(k.faftcommandon,fo.aftcommandgrid.rowcount); + for int1:= 0 to high(k.faftcommandon) do begin + k.faftcommandon[int1]:= + fo.aftmakeon.gridvaluetag(int1,0) or fo.aftbuildon.gridvaluetag(int1,0) or + fo.aftmake1on.gridvaluetag(int1,0) or fo.aftmake2on.gridvaluetag(int1,0) or + fo.aftmake3on.gridvaluetag(int1,0) or fo.aftmake4on.gridvaluetag(int1,0); + end; + + k.t.unitdirs:= reversearray(fo.unitdirs.gridvalues); + setlength(k.funitdirson,length(k.t.unitdirs)); + for int1:= 0 to high(k.funitdirson) do begin + k.funitdirson[high(k.funitdirson)-int1]:= + fo.dmakeon.gridvaluetag(int1,0) or fo.dbuildon.gridvaluetag(int1,0) or + fo.dmake1on.gridvaluetag(int1,0) or fo.dmake2on.gridvaluetag(int1,0) or + fo.dmake3on.gridvaluetag(int1,0) or fo.dmake4on.gridvaluetag(int1,0) or + fo.duniton.gridvaluetag(int1,0) or fo.dincludeon.gridvaluetag(int1,0) or + fo.dlibon.gridvaluetag(int1,0) or fo.dobjon.gridvaluetag(int1,0); + end; + storemacros(fo); + d.t.sourcedirs:= reversearray(fo.sourcedirs.gridvalues); + e.t.syntaxdeffiles:= fo.syntaxdeffile.gridvalues; + e.t.sourcefilemasks:= fo.syntaxdeffilemask.gridvalues; +// e.t.syntaxdeffiles:= fo.grid[0].datalist.asarray; +// e.t.sourcefilemasks:= fo.grid[1].datalist.asarray; + e.t.filemasknames:= fo.filefiltergrid[0].datalist.asarray; + e.t.filemasks:= fo.filefiltergrid[1].datalist.asarray; + end; + expandprojectmacros; +end; + +procedure projectoptionschanged; +var + int1: integer; +begin + projecttree.updatelist; + createcpufo; + mainfo.gdb.fpcworkaround:= projectoptions.d.fpcgdbworkaround; + sourceupdater.unitchanged; + for int1:= 0 to designer.modules.count - 1 do begin + tformdesignerfo(designer.modules[int1]^.designform).updateprojectoptions(); + end; + messagefo.updateprojectoptions; +end; + +function readprojectoptions(const filename: filenamety): boolean; +var + statreader: tstatreader; +begin + result:= false; + try + statreader:= tstatreader.create(filename,ce_utf8); + try + application.beginwait; + updateprojectoptions(statreader,filename); + finally + statreader.free; + application.endwait; + projectoptionschanged; + end; + result:= true; + except + on e: exception do begin + showerror(actionsmo.c[ord(ac_cannotreadproject)]+' "'+filename+'".'+ + lineend+msestring(e.message),actionsmo.c[ord(ac_error)]); + end; + end; +end; + +procedure saveprojectoptions(filename: filenamety = ''); +var + statwriter: tstatwriter; +begin + if filename = '' then begin + filename:= projectoptions.projectfilename; + end; + statwriter:= tstatwriter.create(filename,ce_utf8,true); + try + updateprojectoptions(statwriter,filename); + finally + statwriter.free; + end; +end; + +function editprojectoptions: boolean; +var + fo: tprojectoptionsfo; +begin + fo:= tprojectoptionsfo.create(nil); + projectoptionstoform(fo); + try + projectoptionsfo:= fo; + result:= fo.show(true,nil) = mr_ok; + projectoptionsfo:= nil; + if result then begin + with mainfo.gdb do begin + if not started then begin + closegdb; + end; + end; + fo.window.nofocus; //remove empty grid lines + formtoprojectoptions(fo); + projectoptionsmodified; + projectoptionschanged; + end; + finally + projectoptionsfo:= nil; + fo.Free; + end; +end; + +procedure tprojectoptionsfo.activegroupchanged; +var + int1,int2: integer; +begin + int2:= 0; + for int1:= 0 to selectactivegroupgrid.rowcount-1 do begin + if activemacroselect[int1] then begin + int2:= int1; + break; + end; + end; + for int1:= 0 to 5 do begin + if int1 = int2 then begin + macrogrid.datacols[int1].color:= cl_infobackground; + end + else begin + macrogrid.datacols[int1].color:= cl_default; + end; + end; + projectoptions.s.macrogroup:= int2; +end; + +procedure tprojectoptionsfo.acttiveselectondataentered(const sender: TObject); +var + int1: integer; +begin + for int1:= 0 to selectactivegroupgrid.rowcount-1 do begin + activemacroselect[int1]:= false; + end; + tbooleaneditradio(sender).value:= true; + activegroupchanged; + projectoptions.s.macrogroup:= selectactivegroupgrid.row; +end; + +procedure tprojectoptionsfo.colonshowhint(const sender: tdatacol; + const arow: Integer; var info: hintinfoty); +begin + storemacros(self); + if sender is twidgetcol then begin + info.caption:= tcustomstringedit(twidgetcol(sender).editwidget).gridvalue[arow]; + end + else begin + info.caption:= tstringcol(sender)[arow]; + end; + expandprmacros1(info.caption); + include(info.flags,hfl_show); //show empty caption +end; + +procedure tprojectoptionsfo.hintexpandedmacros(const sender: TObject; + var info: hintinfoty); +begin + storemacros(self); + hintmacros(tcustomedit(sender),info); +end; + +procedure tprojectoptionsfo.selectactiveonrowsmoved(const sender: tcustomgrid; + const fromindex: Integer; const toindex: Integer; const acount: Integer); +var + ar1: array of longboolarty; + int1: integer; +begin + setlength(ar1,selectactivegroupgrid.rowcount); + with macrogrid do begin + beginupdate; + for int1:= 0 to high(ar1) do begin + ar1[int1]:= tbooleanedit(datacols[int1].editwidget).gridvalues; + end; + moveitem(pointerarty(ar1),fromindex,toindex); + for int1:= 0 to high(ar1) do begin + tbooleanedit(datacols[int1].editwidget).gridvalues:= ar1[int1]; + end; + endupdate; + end; + activegroupchanged; +end; + +procedure tprojectoptionsfo.expandfilename(const sender: TObject; + var avalue: mseString; var accept: Boolean); +begin + expandprmacros1(avalue); +end; + +procedure tprojectoptionsfo.showcommandlineonexecute(const sender: TObject); +var + info1: projectoptionsty; +begin + info1:= projectoptions; + formtoprojectoptions(self); + commandlineform.showcommandline; + projectoptions:= info1; +end; + +procedure tprojectoptionsfo.signameonsetvalue(const sender: TObject; var avalue: LongInt; var accept: Boolean); +begin + signum.value:= avalue; + signumto.value:= avalue; +end; + +procedure tprojectoptionsfo.signumonsetvalue(const sender: TObject; var avalue: LongInt; var accept: Boolean); +begin + signame.value:= avalue; + signumto.value:= avalue; +end; + +procedure tprojectoptionsfo.signumtoonsetvalue(const sender: TObject; var avalue: Integer; var accept: Boolean); +begin + if avalue <= signum.value then begin + signum.value:= avalue; + signame.value:= avalue; + end + else begin + signame.value:= -1; + end; +end; + +procedure tprojectoptionsfo.fontondataentered(const sender: TObject); +const + teststring = 'ABCDEFGabcdefgy0123WWWiii '; +var + format1: formatinfoarty; +begin + with fontdisp.font do begin + name:= ansistring(editfontname.value); + height:= editfontheight.value; + width:= editfontwidth.value; + extraspace:= editfontextraspace.value; + color:= editfontcolor.value; + dispgrid.frame.colorclient:= editbkcolor.value; + if editfontantialiased.value then begin + options:= options + [foo_antialiased2]; + end + else begin + options:= options + [foo_nonantialiased]; + end; + dispgrid.datarowheight:= lineheight; + fontdisp[0]:= teststring+teststring+teststring+teststring; + format1:= nil; + updatefontstyle1(format1,length(teststring),length(teststring),fs_bold,true); + updatefontstyle1(format1,2*length(teststring),2*length(teststring),fs_italic,true); + updatefontstyle1(format1,3*length(teststring),length(teststring),fs_bold,true); + fontdisp.richformats[0]:= format1; + fontdisp[1]:= + 'Ascent: '+inttostrmse(ascent)+' Descent: '+inttostrmse(descent)+ + ' Linespacing: '+inttostrmse(lineheight); + end; + dispgrid.rowcolorstate[1]:= 0; + dispgrid.rowcolors[0]:= statementcolor.value; +end; + +procedure tprojectoptionsfo.makepageonchildscaled(const sender: TObject); +var + int1: integer; +begin + placeyorder(0,[0,0,0,15],[mainfile,makecommand,colorerror, + defaultmake,makegroupbox],0); + aligny(wam_center,[mainfile,targetfile,targpref]); + aligny(wam_center,[makecommand,makedir,messageoutputfile]); + int1:= aligny(wam_center,[colorerror,colorwarning,colornote,stripmessageesc]); + with copymessages do begin + bounds_y:= int1 - bounds_cy - 2; + end; + with stripmessageesc do begin + pos:= makepoint(copymessages.bounds_x,int1); + end; + + placexorder(defaultmake.bounds_x,[10-defaultmake.frame.outerframe.right,10], + [defaultmake,showcommandline,checkmethods]); + int1:= aligny(wam_center,[defaultmake,showcommandline]); + with checkmethods do begin + bounds_y:= int1 - bounds_cy - 2; + end; + with closemessages do begin + pos:= makepoint(checkmethods.bounds_x,int1); + end; +end; + +procedure tprojectoptionsfo.debuggerlayoutexe(const sender: TObject); +begin +//{$ifdef mswindows} + placeyorder(2,[0,0,10],[runcommand,debugcommand,debugtarget,tlayouter1]); +//{$else} +// placeyorder(0,[0,0,2],[debugcommand,debugoptions,debugtarget,tlayouter1]); +//{$endif} + aligny(wam_center,[debugcommand,debugoptions]); + aligny(wam_center,[debugtarget,xtermcommand]); +end; + +procedure tprojectoptionsfo.macronchildscaled(const sender: TObject); +var + int1: integer; +begin + int1:= macrosplitter.bounds_y; + placeyorder(0,[0],[selectactivegroupgrid,macrosplitter,macrogrid],0); + macrosplitter.move(makepoint(0,int1-macrosplitter.bounds_y)); +end; + + +procedure tprojectoptionsfo.formtemplateonchildscaled(const sender: TObject); +begin +{ + placeyorder(0,[0],[mainfosource,mainfoform,simplefosource,simplefoform, + dockingfosource,dockingfoform,datamodsource,datamodform, + subfosource,subfoform,reportsource,reportform, + inheritedsource,inheritedform]); +} +end; + +procedure tprojectoptionsfo.encodingsetvalue(const sender: TObject; + var avalue: LongInt; var accept: Boolean); +var + mstr1: msestring; +begin + mstr1:= encoding.dropdown.valuelist[avalue]; + accept:= askyesno(c[ord(wrongencoding)]+lineend+ + c[ord(wishsetencoding)]+' '+mstr1+'?',c[ord(warning)]); +end; + +procedure tprojectoptionsfo.createexe(const sender: TObject); +var + int1: integer; +begin + {$ifdef mswindows} +// externalconsole.visible:= true; + {$else} + settty.visible:= true; +// xtermoptions.visible:= true; + {$endif} + for int1:= ord(firstsiginfocomment) to ord(lastsiginfocomment) do begin + siginfos[int1-ord(firstsiginfocomment)].comment:= ansistring(c[int1]); + end; +end; + +procedure tprojectoptionsfo.drawcol(const sender: tpointeredit; + const acanvas: tcanvas; const avalue: Pointer; + const arow: Integer); +begin + with pcellinfoty(acanvas.drawinfopo)^ do begin + acanvas.fillrect(innerrect,usercolors[arow]); + end; +end; + +procedure tprojectoptionsfo.colsetvalue(const sender: TObject; + var avalue: colorty; var accept: Boolean); +begin + colgrid.invalidaterow(colgrid.row); +end; + +procedure tprojectoptionsfo.copycolorcode(const sender: TObject); +var + str1: msestring; + int1: integer; +begin + str1:= ''; + for int1:= 0 to colgrid.rowhigh do begin + if usercolors[int1] <> 0 then begin + str1:= str1 + ' setcolormapvalue('+ + msestring(colortostring(cl_user+longword(int1)))+','+ + msestring(colortostring(usercolors[int1]))+');'; + if usercolorcomment[int1] <> '' then begin + str1:= str1 + ' //'+usercolorcomment[int1]; + end; + str1:= str1+lineend; + end; + end; + copytoclipboard(str1); +end; + +procedure tprojectoptionsfo.downloadchange(const sender: TObject); +begin + uploadcommand.enabled:= not gdbdownload.value and not gdbsimulator.value; + beforeload.enabled:= gdbdownload.value and not gdbsimulator.value; + afterload.enabled:= gdbdownload.value and not gdbsimulator.value; + gdbservercommand.enabled:= not gdbsimulator.value; + gdbservercommandattach.enabled:= not gdbsimulator.value; + gdbserverwait.enabled:= not gdbsimulator.value; + nogdbserverexit.enabled:= gdbserverwait.enabled; + gdbservertty.enabled:= not gdbsimulator.value; + remoteconnection.enabled:= not gdbsimulator.value; + gdbdownload.enabled:= not gdbsimulator.value; + downloadalways.enabled:= not gdbsimulator.value; + startupbkpt.enabled:= startupbkpton.value; +end; + +procedure tprojectoptionsfo.processorchange(const sender: TObject); +begin + mainfo.gdb.processorname:= ansistring(gdbprocessor.value); + if not (mainfo.gdb.processor in simulatorprocessors) then begin + gdbsimulator.value:= false; + gdbsimulator.enabled:= false; + end + else begin + gdbsimulator.enabled:= true; + end; +end; + +procedure tprojectoptionsfo.copymessagechanged(const sender: TObject); +begin + messageoutputfile.enabled:= copymessages.value; +end; + +procedure tprojectoptionsfo.updatedebugenabled(const sender: TObject); +var + bo1: boolean; +begin + bo1:= runcommand.value = ''; + debugcommand.enabled:= bo1; + debugoptions.enabled:= bo1; + debugtarget.enabled:= bo1; +{$ifndef mswindows} + xtermcommand.enabled:= bo1 and externalconsole.value; +{$endif} + activateonbreak.enabled:= bo1; + raiseonbreak.enabled:= bo1; + nodebugbeginend.enabled:= bo1; + stoponexception.enabled:= bo1; + stoponexception.enabled:= bo1; + showconsole.enabled:= not externalconsole.value; + settty.enabled:= bo1; +end; + +procedure tprojectoptionsfo.newprojectchildscaled(const sender: TObject); +begin + placeyorder(4,[4,4],[scriptbeforecopy,scriptaftercopy,copygrid],0); +end; + +type + valuebufferty = record + settingsfile: filenamety; + settingseditor: boolean; + settingsdebugger: boolean; + settingsmake: boolean; + settingsmacros: boolean; + settingsfontalias: boolean; + settingsusercolors: boolean; + settingsformatmacros: boolean; + settingstemplates: boolean; + settingstools: boolean; + settingsstorage: boolean; + settingscomponentstore: boolean; + settingsprojecttree: boolean; + settingslayout: boolean; +// settingsautoload: boolean; +// settingsautosave: boolean; + projectfilename: filenamety; + projectdir: filenamety; + end; + +procedure savesettingsvalues(fo: tprojectoptionsfo; out buffer: valuebufferty); +begin + with buffer do begin + projectfilename:= projectoptions.projectfilename; + projectdir:= projectoptions.projectdir; + if fo <> nil then begin + settingsfile:= fo.settingsfile.value; + settingseditor:= fo.settingseditor.value; + settingsdebugger:= fo.settingsdebugger.value; + settingsmake:= fo.settingsmake.value; + settingsmacros:= fo.settingsmacros.value; + settingsfontalias:= fo.settingsfontalias.value; + settingsusercolors:= fo.settingsusercolors.value; + settingsformatmacros:= fo.settingsformatmacros.value; + settingstemplates:= fo.settingstemplates.value; + settingstools:= fo.settingstools.value; + settingsstorage:= fo.settingsstorage.value; + settingscomponentstore:= fo.settingscomponentstore.value; + settingsprojecttree:= fo.settingsprojecttree.value; + settingslayout:= fo.settingslayout.value; +// settingsautoload:= fo.settingsautoload.value; +// settingsautosave:= fo.settingsautosave.value; + end + else begin + settingsfile:= projectoptions.r.settingsfile; + settingseditor:= projectoptions.r.settingseditor; + settingsdebugger:= projectoptions.r.settingsdebugger; + settingsmake:= projectoptions.r.settingsmake; + settingsmacros:= projectoptions.r.settingsmacros; + settingsfontalias:= projectoptions.r.settingsfontalias; + settingsusercolors:= projectoptions.r.settingsusercolors; + settingsformatmacros:= projectoptions.r.settingsformatmacros; + settingstemplates:= projectoptions.r.settingstemplates; + settingstools:= projectoptions.r.settingstools; + settingsstorage:= projectoptions.r.settingsstorage; + settingscomponentstore:= projectoptions.r.settingscomponentstore; + settingsprojecttree:= projectoptions.r.settingsprojecttree; + settingslayout:= projectoptions.r.settingslayout; +// settingsautoload:= projectoptions.r.settingsautoload; +// settingsautosave:= projectoptions.r.settingsautosave; + end; + end; +end; + +procedure restoresettingsvalues(fo: tprojectoptionsfo; + const buffer: valuebufferty); +begin + with buffer do begin + projectoptions.projectfilename:= projectfilename; + projectoptions.projectdir:= projectdir; + if fo <> nil then begin + if not settingsstorage then begin + fo.settingsfile.value:= settingsfile; + fo.settingseditor.value:= settingseditor; + fo.settingsdebugger.value:= settingsdebugger; + fo.settingsmake.value:= settingsmake; + fo.settingsmacros.value:= settingsmacros; + fo.settingsfontalias.value:= settingsfontalias; + fo.settingsusercolors.value:= settingsusercolors; + fo.settingsformatmacros.value:= settingsformatmacros; + fo.settingstemplates.value:= settingstemplates; + fo.settingstools.value:= settingstools; + fo.settingsstorage.value:= settingsstorage; + fo.settingscomponentstore.value:= settingscomponentstore; + fo.settingsprojecttree.value:= settingsprojecttree; + fo.settingslayout.value:= settingslayout; +// fo.settingsautoload.value:= settingsautoload; +// fo.settingsautosave.value:= settingsautosave; + end; + fo.fontondataentered(nil); + fo.settingsdataent(nil); + end + else begin + if not settingsstorage then begin + projectoptions.r.settingsfile:= settingsfile; + projectoptions.r.settingseditor:= settingseditor; + projectoptions.r.settingsdebugger:= settingsdebugger; + projectoptions.r.settingsmake:= settingsmake; + projectoptions.r.settingsmacros:= settingsmacros; + projectoptions.r.settingsfontalias:= settingsfontalias; + projectoptions.r.settingsusercolors:= settingsusercolors; + projectoptions.r.settingsformatmacros:= settingsformatmacros; + projectoptions.r.settingstemplates:= settingstemplates; + projectoptions.r.settingstools:= settingstools; + projectoptions.r.settingsstorage:= settingsstorage; + projectoptions.r.settingscomponentstore:= settingscomponentstore; + projectoptions.r.settingsprojecttree:= settingsprojecttree; + projectoptions.r.settingslayout:= settingslayout; +// projectoptions.r.settingsautoload:= settingsautoload; +// projectoptions.r.settingsautosave:= settingsautosave; + end; + end; + end; +end; + +procedure savestat(out astream: ttextstream); +var + write1: tstatwriter; +begin + astream:= ttextstream.create; //memory stream + write1:= tstatwriter.create(astream,ce_utf8); + try + write1.setsection('projectoptions'); + updateprojectsettings(write1,[]); //save projectoptions state + finally + write1.free; + end; +end; + +procedure restorestat(var astream: ttextstream); +var + read1: tstatreader; +begin + astream.position:= 0; + read1:= tstatreader.create(astream,ce_utf8); + try + read1.setsection('projectoptions'); + updateprojectsettings(read1,[]); //restore projectoptions state + finally + read1.free; + astream.free; + end; +end; + +procedure doloadexe(const sender: tprojectoptionsfo); +var + read1: tstatreader; + buffer: valuebufferty; + stream1: ttextstream; + fname1: filenamety; +begin + if (sender <> nil) then begin + storemacros(sender); + fname1:= sender.settingsfile.value; + expandprmacros1(fname1); + if not askyesno(actionsmo.c[ord(ac_replacesettings)]+lineend+ + '"'+fname1+'"?', + actionsmo.c[ord(ac_warning)]) then begin + exit; + end; + end + else begin + fname1:= projectoptions.r.settingsfile; + expandprmacros1(fname1); + end; + if fname1 <> '' then begin + savesettingsvalues(sender,buffer); + savestat(stream1); + if sender <> nil then begin //manual + formtoprojectoptions(sender); + end; + projectoptions.disabled:= getdisabledoptions; + try + read1:= tstatreader.create(fname1,ce_utf8); + try + if projectoptions.r.settingscomponentstore then begin + componentstorefo.updatestat(read1); + end; + if projectoptions.r.settingslayout then begin + mainfo.loadwindowlayout(read1); + end; + read1.setsection('projectoptions'); + if projectoptions.r.settingsprojecttree then begin + projecttree.updatestat(read1); + projecttree.updatelist; + end; + updateprojectsettings(read1,[]); + finally + read1.free; + end; + if sender <> nil then begin + projectoptionstoform(sender); + end; + restoresettingsvalues(sender,buffer); + except + application.handleexception; + end; + projectoptions.disabled:= []; + if sender <> nil then begin //manual + restorestat(stream1); + end + else begin + stream1.free; + expandprojectmacros; + end; + end; +end; + +procedure tprojectoptionsfo.loadexe(const sender: TObject); +begin + doloadexe(self); +end; + +procedure dosaveexe(const sender: tprojectoptionsfo); +var + stat1: tstatwriter; + stream1: ttextstream; + fname1: filenamety; +begin + if sender <> nil then begin //manual save + storemacros(sender); + fname1:= sender.settingsfile.value; + expandprmacros1(fname1); + if findfile(fname1) and not askyesno(actionsmo.c[ord(ac_file)]+fname1+ + actionsmo.c[ord(ac_exists)]+lineend+ + actionsmo.c[ord(ac_wantoverwrite)],actionsmo.c[ord(ac_warning)]) then begin + exit; + end; + end + else begin + fname1:= projectoptions.r.settingsfile; + expandprmacros1(fname1); + end; + if fname1 <> '' then begin + stat1:= tstatwriter.create(fname1,ce_utf8,true); + with projectoptions do begin + try + savestat(stream1); + if sender <> nil then begin + formtoprojectoptions(sender); + end; + disabled:= getdisabledoptions; + if r.settingscomponentstore then begin + componentstorefo.updatestat(stat1); + end; + if r.settingslayout then begin + mainfo.savewindowlayout(stat1); + end; + stat1.setsection('projectoptions'); + if r.settingsprojecttree then begin + projecttree.updatestat(stat1); + end; + if not r.settingsstorage then begin + r.settingsfile:= ''; + r.settingseditor:= false; + r.settingsdebugger:= false; + r.settingsmake:= false; + r.settingsmacros:= false; + r.settingsfontalias:= false; + r.settingsusercolors:= false; + r.settingsformatmacros:= false; + r.settingstemplates:= false; + r.settingstools:= false; + r.settingsstorage:= false; + r.settingscomponentstore:= false; + r.settingsprojecttree:= false; + r.settingslayout:= false; +// r.settingsautoload:= false; +// r.settingsautosave:= false; + end; + updateprojectsettings(stat1,disabled); + finally + disabled:= []; + stat1.free; + restorestat(stream1); + end; + end; + end; +end; + +procedure tprojectoptionsfo.saveexe(const sender: TObject); +begin + dosaveexe(self); +end; + +procedure tprojectoptionsfo.settingsdataent(const sender: TObject); +var + bo1: boolean; +begin + bo1:= settingsfile.value <> ''; + savebu.enabled:= bo1; + loadbu.enabled:= bo1; +end; +(* +procedure tprojectoptionsfo.extconschangeexe(const sender: TObject); +begin +{$ifndef mswindows} + xtermcommand.enabled:= externalconsole.value; +{$endif} +end; +*) +procedure tprojectoptionsfo.setxtermcommandexe(const sender: TObject; + var avalue: msestring; var accept: Boolean); +begin + if avalue = '' then begin + avalue:= defaultxtermcommand; + end; +end; + +procedure tprojectoptionsfo.activateonbreakset(const sender: TObject; + var avalue: Boolean; var accept: Boolean); +begin + raiseonbreak.enabled:= avalue; +end; + +procedure tprojectoptionsfo.sourcedirhint(const sender: TObject; + var info: hintinfoty); +begin + if tcustomedit(sender).text = '' then begin + hintexpandedmacros(makedir,info); + end + else begin + hintexpandedmacros(sender,info); + end; +end; + +procedure tprojectoptionsfo.toolshortcutdropdown(const sender: TObject); +var + i1: int32; + act1: taction; +begin + with toolshortcuts.dropdown do begin + for i1:= 0 to valuelist.count-1 do begin + if actionsmo.gettoolshortcutaction(i1,act1) then begin + with act1 do begin + cols[1][i1]:= encodeshortcutname(shortcuts); + cols[2][i1]:= encodeshortcutname(shortcuts1); + end; + end; + end; + end; +end; + +procedure tprojectoptionsfo.toolsrowdatachanged(const sender: tcustomgrid; + const acell: gridcoordty); +var + act1: taction; +begin + if actionsmo.gettoolshortcutaction(toolshortcuts[acell.row],act1) then begin + with act1 do begin + toolsc[acell.row]:= encodeshortcutname(shortcuts); + toolscalt[acell.row]:= encodeshortcutname(shortcuts1); + end; + end; +end; + +procedure tprojectoptionsfo.colorhint(const sender: TObject; + var info: hintinfoty); +begin + info.caption:= tcustomedit(sender).text + lineend + info.caption; +end; + +procedure tprojectoptionsfo.initeolstyleexe(const sender: tenumtypeedit); +begin + sender.typeinfopo:= typeinfo(eolstylety); +end; + +procedure tprojectoptionsfo.debugtargetlayoutev(const sender: TObject); +begin + serverla.width:= serverla.width + uploadcommand.width-gdbservercommand.width; +end; +(* +{ tprojectoptions } + +constructor tprojectoptions.create; +begin + ft:= ttextprojectoptions.create; + ftexp:= ttextprojectoptions.create; + inherited; +end; + +function tprojectoptions.gett: tobject; +begin + result:= ft; +end; + +function tprojectoptions.gettexp: tobject; +begin + result:= ftexp; +end; +*) +{ teditoptions } + +constructor teditoptions.create; +var + ar1: msestringarty; +begin + ft:= ttexteditoptions.create; + ftexp:= ttexteditoptions.create; + + showgrid:= true; + snaptogrid:= true; + moveonfirstclick:= true; + componenthints:= true; + gridsizex:= defaultgridsizex; + gridsizey:= defaultgridsizey; + encoding:= 1; //utf8n + eolstyle:= 1; //eol_system + autoindent:= true; + blockindent:= 1; + rightmarginon:= true; + rightmarginchars:= 80; + tabstops:= 4; + editfontname:= 'mseide_source'; + editfontcolor:= integer(cl_text); + editbkcolor:= integer(cl_foreground); + statementcolor:= $E0FFFF; +// pairmarkcolor:= int32(cl_ltyellow); + pairmarkcolor:= int32(cl_none); + pairmaxrowcount:= 100; + editfontantialiased:= true; + editmarkbrackets:= true; +// editmarkpairwords:= true; + backupfilecount:= 2; + setlength(ar1,1); + ar1[0]:= '${TEMPLATEDIR}'; + ft.codetemplatedirs:= ar1; + inherited; +end; + +function teditoptions.limitgridsize(const avalue: integer): integer; +begin + result:= avalue; + if result < 1 then begin + result:= 1; + end; + if result > 1000 then begin + result:= 1000; + end; +end; + +procedure teditoptions.setgridsizex(const avalue: integer); +begin + fgridsizex:= limitgridsize(avalue); +end; + +procedure teditoptions.setgridsizey(const avalue: integer); +begin + fgridsizey:= limitgridsize(avalue); +end; +{ +function teditoptions.getcodetemplatedirs: msestringarty; +begin + result:= projectoptions.k.t.codetemplatedirs; +end; + +procedure teditoptions.setcodetemplatedirs(const avalue: msestringarty); +begin + projectoptions.k.t.codetemplatedirs:= avalue; +end; +} +function teditoptions.gett: tobject; +begin + result:= ft; +end; + +function teditoptions.gettexp: tobject; +begin + result:= ftexp; +end; + +{ tdebugoptions } + +constructor tdebugoptions.create; +begin + ft:= ttextdebugoptions.create; + ftexp:= ttextdebugoptions.create; + + valuehints:= true; + activateonbreak:= true; + raiseonbreak:= true; + settty:= true; + additem(fexceptclassnames,'EconvertError'); + additem(fexceptignore,false); + fgdbloadtimeout:= emptyreal; + fpcgdbworkaround:= true; + inherited; +end; + +function tdebugoptions.gett: tobject; +begin + result:= ft; +end; + +function tdebugoptions.gettexp: tobject; +begin + result:= ftexp; +end; + +{ ttextdebugoptions } + +constructor ttextdebugoptions.create; +begin + fxtermcommand:= defaultxtermcommand; +end; + +{ tmakeoptions } + +constructor tmakeoptions.create; +begin + ft:= ttextmakeoptions.create; + ftexp:= ttextmakeoptions.create; + inherited; +end; + +function tmakeoptions.gett: tobject; +begin + result:= ft; +end; + +function tmakeoptions.gettexp: tobject; +begin + result:= ftexp; +end; + +{ ttoolsoptions } + +constructor ttoolsoptions.create; +begin + ft:= ttexttoolsoptions.create(); + ftexp:= ttexttoolsoptions.create(); + inherited; +end; + +function ttoolsoptions.gett: tobject; +begin + result:= ft; +end; + +function ttoolsoptions.gettexp: tobject; +begin + result:= ftexp; +end; + +{ ttemplatesoptions } + +constructor ttemplatesoptions.create; +begin + ft:= ttexttemplatesoptions.create(); + ftexp:= ttexttemplatesoptions.create(); + inherited; +end; + +function ttemplatesoptions.gett: tobject; +begin + result:= ft; +end; + +function ttemplatesoptions.gettexp: tobject; +begin + result:= ftexp; +end; + +{ tprojectstate } + +constructor tprojectstate.create(); +begin + ft:= ttextprojectstate.create(); + ftexp:= ttextprojectstate.create(); + closemessages:= true; + checkmethods:= true; + fcolorerror:= cl_ltyellow; + fcolorwarning:= cl_ltred; + fcolornote:= cl_ltgreen; + inherited; +end; + +procedure tprojectstate.setforcezorder(const avalue: longbool); +begin + fforcezorder:= avalue; + application.forcezorder:= avalue; +end; + +function tprojectstate.gett: tobject; +begin + result:= ft; +end; + +function tprojectstate.gettexp: tobject; +begin + result:= ftexp; +end; + +{ tfontaliasoptions } + +constructor tfontaliasoptions.create(); +begin + ft:= ttextfontaliasoptions.create(); + ftexp:= ttextfontaliasoptions.create(); + inherited; +end; + +function tfontaliasoptions.gett: tobject; +begin + result:= ft; +end; + +function tfontaliasoptions.gettexp: tobject; +begin + result:= ftexp; +end; + +{ tusercoloroptions } + +constructor tusercoloroptions.create(); +begin + ft:= ttextusercoloroptions.create(); + ftexp:= ttextusercoloroptions.create(); + inherited; +end; + +function tusercoloroptions.gett: tobject; +begin + result:= ft; +end; + +function tusercoloroptions.gettexp: tobject; +begin + result:= ftexp; +end; + +{ tformatmacrooptions } + +constructor tformatmacrooptions.create(); +begin + ft:= ttextformatmacrooptions.create(); + ftexp:= ttextformatmacrooptions.create(); + inherited; +end; + +function tformatmacrooptions.gett: tobject; +begin + result:= ft; +end; + +function tformatmacrooptions.gettexp: tobject; +begin + result:= ftexp; +end; + +{ ttextfontaliasoptions } + +{ tstorageoptions } + +constructor tstorageoptions.create(); +begin + fsettingsmake:= true; + inherited; +end; + +{ ttexttemplatesoptions } + +initialization + codetemplates:= tcodetemplates.create; +finalization + freeoptions(); +{ + projectoptions.o.free(); + projectoptions.e.free(); + projectoptions.d.free(); + projectoptions.m.free(); + projectoptions.a.free(); + projectoptions.u.free(); + projectoptions.f.free(); + projectoptions.p.free(); + projectoptions.t.free(); + projectoptions.r.free(); + projectoptions.s.free(); +} + freeandnil(codetemplates); +end. diff --git a/mseide-msegui/apps/ide/projectoptionsform_mfm.pas b/mseide-msegui/apps/ide/projectoptionsform_mfm.pas new file mode 100644 index 0000000..9eeb5d6 --- /dev/null +++ b/mseide-msegui/apps/ide/projectoptionsform_mfm.pas @@ -0,0 +1,9382 @@ +unit projectoptionsform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,projectoptionsform; + +const + objdata: record size: integer; data: array[0..187294] of byte end = + (size: 187295; data: ( + 84,80,70,48,17,116,112,114,111,106,101,99,116,111,112,116,105,111,110,115, + 102,111,16,112,114,111,106,101,99,116,111,112,116,105,111,110,115,102,111,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,9,111,119,95,104,105,110,116,111, + 110,0,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120, + 3,205,0,8,98,111,117,110,100,115,95,121,3,177,0,9,98,111,117,110, + 100,115,95,99,120,3,64,3,9,98,111,117,110,100,115,95,99,121,3,69, + 2,23,99,111,110,116,97,105,110,101,114,46,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115, + 105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,11, + 111,119,95,115,117,98,102,111,99,117,115,19,111,119,95,109,111,117,115,101, + 116,114,97,110,115,112,97,114,101,110,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,15,99,111,110,116,97,105,110,101,114, + 46,99,111,108,111,114,4,3,0,0,128,29,99,111,110,116,97,105,110,101, + 114,46,102,114,97,109,101,46,102,114,97,109,101,105,95,98,111,116,116,111, + 109,2,0,26,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,12,102,114,108,95,102,105,98,111, + 116,116,111,109,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108, + 101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111, + 112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104, + 116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116, + 111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99, + 116,105,118,101,0,27,99,111,110,116,97,105,110,101,114,46,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97, + 98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97, + 99,116,105,118,101,0,30,99,111,110,116,97,105,110,101,114,46,102,114,97, + 109,101,46,115,98,104,111,114,122,46,111,112,116,105,111,110,115,11,12,115, + 98,111,95,109,111,118,101,97,117,116,111,12,115,98,111,95,115,104,111,119, + 97,117,116,111,0,25,99,111,110,116,97,105,110,101,114,46,102,97,99,101, + 46,108,111,99,97,108,112,114,111,112,115,11,0,16,99,111,110,116,97,105, + 110,101,114,46,98,111,117,110,100,115,1,2,0,2,0,3,64,3,3,69, + 2,0,7,111,112,116,105,111,110,115,11,13,102,111,95,99,108,111,115,101, + 111,110,101,115,99,17,102,111,95,108,111,99,97,108,115,104,111,114,116,99, + 117,116,115,15,102,111,95,97,117,116,111,114,101,97,100,115,116,97,116,16, + 102,111,95,97,117,116,111,119,114,105,116,101,115,116,97,116,10,102,111,95, + 115,97,118,101,112,111,115,13,102,111,95,115,97,118,101,122,111,114,100,101, + 114,0,8,115,116,97,116,102,105,108,101,7,9,115,116,97,116,102,105,108, + 101,49,7,99,97,112,116,105,111,110,6,15,80,114,111,106,101,99,116,32, + 79,112,116,105,111,110,115,13,119,105,110,100,111,119,111,112,97,99,105,116, + 121,5,0,0,0,0,0,0,0,128,255,255,8,111,110,99,114,101,97,116, + 101,7,9,99,114,101,97,116,101,101,120,101,15,109,111,100,117,108,101,99, + 108,97,115,115,110,97,109,101,6,8,116,109,115,101,102,111,114,109,0,9, + 116,108,97,121,111,117,116,101,114,10,116,108,97,121,111,117,116,101,114,57, + 8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121, + 2,0,9,98,111,117,110,100,115,95,99,120,3,64,3,9,98,111,117,110, + 100,115,95,99,121,3,69,2,7,97,110,99,104,111,114,115,11,0,13,111, + 112,116,105,111,110,115,108,97,121,111,117,116,11,10,108,97,111,95,112,108, + 97,99,101,121,0,13,112,108,97,99,101,95,109,97,120,100,105,115,116,2, + 0,13,112,108,97,99,101,95,111,112,116,105,111,110,115,11,13,112,108,111, + 95,101,110,100,109,97,114,103,105,110,0,0,9,116,108,97,121,111,117,116, + 101,114,10,116,108,97,121,111,117,116,101,114,56,5,99,111,108,111,114,4, + 3,0,0,128,16,102,114,97,109,101,46,102,114,97,109,101,105,95,116,111, + 112,2,5,19,102,114,97,109,101,46,102,114,97,109,101,105,95,98,111,116, + 116,111,109,2,5,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,9,102,114,108,95,102,105,116,111,112,12,102,114,108,95,102,105, + 98,111,116,116,111,109,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117, + 115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,8,98, + 111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,3,39, + 2,9,98,111,117,110,100,115,95,99,120,3,64,3,9,98,111,117,110,100, + 115,95,99,121,2,30,7,97,110,99,104,111,114,115,11,9,97,110,95,98, + 111,116,116,111,109,0,12,111,112,116,105,111,110,115,115,99,97,108,101,11, + 11,111,115,99,95,101,120,112,97,110,100,121,11,111,115,99,95,115,104,114, + 105,110,107,121,0,13,111,112,116,105,111,110,115,108,97,121,111,117,116,11, + 10,108,97,111,95,112,108,97,99,101,120,10,108,97,111,95,97,108,105,103, + 110,121,19,108,97,111,95,115,121,110,99,109,97,120,97,117,116,111,115,105, + 122,101,0,10,97,108,105,103,110,95,103,108,117,101,7,10,119,97,109,95, + 99,101,110,116,101,114,13,112,108,97,99,101,95,109,105,110,100,105,115,116, + 2,5,13,112,108,97,99,101,95,109,97,120,100,105,115,116,2,5,10,112, + 108,97,99,101,95,109,111,100,101,7,7,119,97,109,95,101,110,100,13,112, + 108,97,99,101,95,111,112,116,105,111,110,115,11,14,112,108,111,95,112,114, + 111,112,109,97,114,103,105,110,0,7,108,105,110,107,116,111,112,7,9,116, + 97,98,119,105,100,103,101,116,0,7,116,98,117,116,116,111,110,6,99,97, + 110,99,101,108,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11, + 19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116, + 13,111,119,49,95,97,117,116,111,115,99,97,108,101,0,13,111,112,116,105, + 111,110,115,119,105,100,103,101,116,11,11,111,119,95,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95, + 97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111, + 119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121, + 119,105,100,103,101,116,115,0,5,99,111,108,111,114,4,3,0,0,128,8, + 98,111,117,110,100,115,95,120,3,7,3,8,98,111,117,110,100,115,95,121, + 2,5,9,98,111,117,110,100,115,95,99,120,2,52,9,98,111,117,110,100, + 115,95,99,121,2,20,5,115,116,97,116,101,11,15,97,115,95,108,111,99, + 97,108,99,97,112,116,105,111,110,13,97,115,95,108,111,99,97,108,99,111, + 108,111,114,0,7,99,97,112,116,105,111,110,6,6,67,97,110,99,101,108, + 11,109,111,100,97,108,114,101,115,117,108,116,7,9,109,114,95,99,97,110, + 99,101,108,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0, + 0,7,116,98,117,116,116,111,110,2,111,107,14,111,112,116,105,111,110,115, + 119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121, + 112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99,97, + 108,101,0,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,11,111, + 119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102, + 111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110, + 16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119, + 95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,5,99,111,108, + 111,114,4,3,0,0,128,8,116,97,98,111,114,100,101,114,2,1,8,98, + 111,117,110,100,115,95,120,3,206,2,8,98,111,117,110,100,115,95,121,2, + 5,9,98,111,117,110,100,115,95,99,120,2,52,9,98,111,117,110,100,115, + 95,99,121,2,20,5,115,116,97,116,101,11,10,97,115,95,100,101,102,97, + 117,108,116,15,97,115,95,108,111,99,97,108,100,101,102,97,117,108,116,15, + 97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,13,97,115,95,108, + 111,99,97,108,99,111,108,111,114,0,7,99,97,112,116,105,111,110,6,2, + 79,107,11,109,111,100,97,108,114,101,115,117,108,116,7,5,109,114,95,111, + 107,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0, + 10,116,116,97,98,119,105,100,103,101,116,9,116,97,98,119,105,100,103,101, + 116,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95, + 97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111, + 119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111,99,117, + 115,17,111,119,95,102,111,99,117,115,98,97,99,107,111,110,101,115,99,13, + 111,119,95,109,111,117,115,101,119,104,101,101,108,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,14,111,112,116,105,111,110,115, + 119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121, + 112,104,104,101,105,103,104,116,0,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,3,64,3,9,98,111,117,110,100,115,95,99,121,3,39,2,5,99,111, + 108,111,114,4,5,0,0,144,12,102,114,97,109,101,46,108,101,118,101,108, + 111,2,255,19,102,114,97,109,101,46,99,97,112,116,105,111,110,111,102,102, + 115,101,116,2,3,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97, + 98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97, + 99,116,105,118,101,0,7,97,110,99,104,111,114,115,11,6,97,110,95,116, + 111,112,9,97,110,95,98,111,116,116,111,109,0,8,116,97,98,111,114,100, + 101,114,2,1,15,97,99,116,105,118,101,112,97,103,101,105,110,100,101,120, + 2,2,20,116,97,98,95,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108, + 101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111, + 112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104, + 116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116, + 111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99, + 116,105,118,101,15,102,114,108,95,111,112,116,105,111,110,115,115,107,105,110, + 0,21,116,97,98,95,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101, + 27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,9,116,97,98, + 95,99,111,108,111,114,4,3,0,0,128,8,116,97,98,95,115,105,122,101, + 2,19,8,115,116,97,116,102,105,108,101,7,9,115,116,97,116,102,105,108, + 101,49,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,8, + 116,116,97,98,112,97,103,101,10,101,100,105,116,111,114,112,97,103,101,14, + 111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95, + 102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,13,111,112,116, + 105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101, + 102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119, + 95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119, + 102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117, + 115,111,117,116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,19,102,114,97,109, + 101,46,102,114,97,109,101,105,95,98,111,116,116,111,109,2,0,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,12,102,114,108,95, + 102,105,98,111,116,116,111,109,18,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101, + 100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109, + 111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0, + 8,116,97,98,111,114,100,101,114,2,5,8,98,111,117,110,100,115,95,120, + 2,1,8,98,111,117,110,100,115,95,121,2,20,9,98,111,117,110,100,115, + 95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,3,18,2,7, + 97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,0,7,99,97,112, + 116,105,111,110,6,7,38,69,100,105,116,111,114,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,14,0,10,116,116,97,98,119,105,100,103,101, + 116,11,116,116,97,98,119,105,100,103,101,116,51,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,11,111,119,95,115,117,98,102,111,99,117,115,13,111,119,95,109,111,117, + 115,101,119,104,101,101,108,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,0,8,98,111,117,110,100,115,95,120,2,0,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,62, + 3,9,98,111,117,110,100,115,95,99,121,3,18,2,7,97,110,99,104,111, + 114,115,11,0,15,97,99,116,105,118,101,112,97,103,101,105,110,100,101,120, + 2,0,20,116,97,98,95,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,0,21,116,97,98,95,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,8,116,97,98,95,115,105,122,101,2,19, + 8,115,116,97,116,102,105,108,101,7,9,115,116,97,116,102,105,108,101,49, + 0,8,116,116,97,98,112,97,103,101,10,116,116,97,98,112,97,103,101,50, + 51,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95, + 97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111, + 119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111,99,117, + 115,13,111,119,95,109,111,117,115,101,119,104,101,101,108,17,111,119,95,100, + 101,115,116,114,111,121,119,105,100,103,101,116,115,0,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100, + 101,114,2,2,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110, + 100,115,95,121,2,19,9,98,111,117,110,100,115,95,99,120,3,62,3,9, + 98,111,117,110,100,115,95,99,121,3,255,1,7,97,110,99,104,111,114,115, + 11,7,97,110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95, + 114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,7,99,97,112, + 116,105,111,110,6,6,83,111,117,114,99,101,0,10,116,116,97,98,119,105, + 100,103,101,116,11,116,116,97,98,119,105,100,103,101,116,50,13,111,112,116, + 105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101, + 102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119, + 95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119, + 102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117, + 115,111,117,116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,14,111,112,116,105, + 111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116, + 103,108,121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111, + 115,99,97,108,101,0,8,98,111,117,110,100,115,95,120,2,0,8,98,111, + 117,110,100,115,95,121,3,39,1,9,98,111,117,110,100,115,95,99,120,3, + 62,3,9,98,111,117,110,100,115,95,99,121,3,216,0,12,98,111,117,110, + 100,115,95,99,121,109,105,110,2,84,7,97,110,99,104,111,114,115,11,6, + 97,110,95,116,111,112,9,97,110,95,98,111,116,116,111,109,0,8,116,97, + 98,111,114,100,101,114,2,1,15,97,99,116,105,118,101,112,97,103,101,105, + 110,100,101,120,2,0,20,116,97,98,95,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,0,21,116,97,98,95,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,9,116,97,98,95,99,111, + 108,111,114,4,3,0,0,128,8,116,97,98,95,115,105,122,101,2,19,8, + 115,116,97,116,102,105,108,101,7,9,115,116,97,116,102,105,108,101,49,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,8,116,116,97, + 98,112,97,103,101,10,116,116,97,98,112,97,103,101,49,51,14,111,112,116, + 105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110, + 116,103,108,121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116, + 111,115,99,97,108,101,0,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95, + 116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111, + 119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115, + 117,98,102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,0,5,99,111,108,111,114,4,3,0,0,128,19,102,114, + 97,109,101,46,102,114,97,109,101,105,95,98,111,116,116,111,109,2,0,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,12,102,114, + 108,95,102,105,98,111,116,116,111,109,18,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99, + 107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100, + 25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118, + 101,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115, + 95,120,2,0,8,98,111,117,110,100,115,95,121,2,19,9,98,111,117,110, + 100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,3,197, + 0,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97, + 110,95,116,111,112,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111, + 116,116,111,109,0,7,99,97,112,116,105,111,110,6,11,70,105,108,101,32, + 102,105,108,116,101,114,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,11,116,115,116,114,105,110,103,103,114,105,100,14,102,105,108,101, + 102,105,108,116,101,114,103,114,105,100,13,111,112,116,105,111,110,115,119,105, + 100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11, + 111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119, + 102,111,99,117,115,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111, + 117,116,17,111,119,95,102,111,99,117,115,98,97,99,107,111,110,101,115,99, + 13,111,119,95,109,111,117,115,101,119,104,101,101,108,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,0,5,99,111,108,111,114,4, + 3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102, + 116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109, + 20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101, + 116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105, + 118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99, + 108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,97,99,116,105,118,101,0,8,98,111,117,110,100, + 115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,3, + 197,0,7,97,110,99,104,111,114,115,11,0,11,111,112,116,105,111,110,115, + 103,114,105,100,11,12,111,103,95,99,111,108,115,105,122,105,110,103,12,111, + 103,95,114,111,119,109,111,118,105,110,103,15,111,103,95,107,101,121,114,111, + 119,109,111,118,105,110,103,15,111,103,95,114,111,119,105,110,115,101,114,116, + 105,110,103,14,111,103,95,114,111,119,100,101,108,101,116,105,110,103,23,111, + 103,95,115,101,108,101,99,116,101,100,114,111,119,115,100,101,108,101,116,105, + 110,103,19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116, + 101,114,15,111,103,95,97,117,116,111,102,105,114,115,116,114,111,119,13,111, + 103,95,97,117,116,111,97,112,112,101,110,100,20,111,103,95,99,111,108,99, + 104,97,110,103,101,111,110,116,97,98,107,101,121,10,111,103,95,119,114,97, + 112,99,111,108,12,111,103,95,97,117,116,111,112,111,112,117,112,17,111,103, + 95,109,111,117,115,101,115,99,114,111,108,108,99,111,108,0,14,100,97,116, + 97,99,111,108,115,46,99,111,117,110,116,2,2,16,100,97,116,97,99,111, + 108,115,46,111,112,116,105,111,110,115,11,14,99,111,95,102,111,99,117,115, + 115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99, + 116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117, + 108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101, + 99,116,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99, + 97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99, + 111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,14,100,97, + 116,97,99,111,108,115,46,105,116,101,109,115,14,1,5,119,105,100,116,104, + 2,112,7,111,112,116,105,111,110,115,11,14,99,111,95,102,111,99,117,115, + 115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99, + 116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117, + 108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101, + 99,116,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99, + 97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99, + 111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,118,97, + 108,117,101,102,97,108,115,101,6,1,48,9,118,97,108,117,101,116,114,117, + 101,6,1,49,0,1,5,119,105,100,116,104,3,172,2,7,111,112,116,105, + 111,110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14, + 99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101, + 121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101, + 99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,7,99,111,95,102, + 105,108,108,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95, + 99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17, + 99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,118, + 97,108,117,101,102,97,108,115,101,6,1,48,9,118,97,108,117,101,116,114, + 117,101,6,1,49,0,0,13,102,105,120,99,111,108,115,46,99,111,117,110, + 116,2,1,13,102,105,120,99,111,108,115,46,105,116,101,109,115,14,1,5, + 119,105,100,116,104,2,27,8,110,117,109,115,116,97,114,116,2,1,7,110, + 117,109,115,116,101,112,2,1,0,0,13,102,105,120,114,111,119,115,46,99, + 111,117,110,116,2,1,13,102,105,120,114,111,119,115,46,105,116,101,109,115, + 14,1,6,104,101,105,103,104,116,2,16,14,99,97,112,116,105,111,110,115, + 46,99,111,117,110,116,2,2,14,99,97,112,116,105,111,110,115,46,105,116, + 101,109,115,14,1,7,99,97,112,116,105,111,110,6,4,78,97,109,101,0, + 1,7,99,97,112,116,105,111,110,6,9,70,105,108,101,32,109,97,115,107, + 0,0,0,0,13,100,97,116,97,114,111,119,104,101,105,103,104,116,2,16, + 8,115,116,97,116,102,105,108,101,7,9,115,116,97,116,102,105,108,101,49, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,8, + 116,116,97,98,112,97,103,101,10,116,116,97,98,112,97,103,101,49,52,14, + 111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95, + 102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,13,111,119,49,95, + 97,117,116,111,115,99,97,108,101,0,13,111,112,116,105,111,110,115,119,105, + 100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11, + 111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119, + 102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105, + 110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,11,111, + 119,95,115,117,98,102,111,99,117,115,17,111,119,95,100,101,115,116,114,111, + 121,119,105,100,103,101,116,115,0,5,99,111,108,111,114,4,3,0,0,128, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111, + 117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107, + 101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,97,99,116,105,118,101,0,8,116,97,98,111,114,100,101,114,2, + 2,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95, + 121,2,19,9,98,111,117,110,100,115,95,99,120,3,62,3,9,98,111,117, + 110,100,115,95,99,121,3,197,0,7,97,110,99,104,111,114,115,11,7,97, + 110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,9,97,110,95,98,111,116,116,111,109,0,7,99,97,112,116,105,111, + 110,6,23,83,121,110,116,97,120,32,100,101,102,105,110,105,116,105,111,110, + 32,102,105,108,101,115,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,11,116,119,105,100,103,101,116,103,114,105,100,12,116,119,105,100, + 103,101,116,103,114,105,100,54,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,8,98,111,117,110,100,115,95,120,2,0,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3, + 62,3,9,98,111,117,110,100,115,95,99,121,3,197,0,7,97,110,99,104, + 111,114,115,11,0,11,111,112,116,105,111,110,115,103,114,105,100,11,12,111, + 103,95,99,111,108,115,105,122,105,110,103,12,111,103,95,114,111,119,109,111, + 118,105,110,103,15,111,103,95,107,101,121,114,111,119,109,111,118,105,110,103, + 15,111,103,95,114,111,119,105,110,115,101,114,116,105,110,103,14,111,103,95, + 114,111,119,100,101,108,101,116,105,110,103,19,111,103,95,102,111,99,117,115, + 99,101,108,108,111,110,101,110,116,101,114,15,111,103,95,97,117,116,111,102, + 105,114,115,116,114,111,119,13,111,103,95,97,117,116,111,97,112,112,101,110, + 100,20,111,103,95,99,111,108,99,104,97,110,103,101,111,110,116,97,98,107, + 101,121,10,111,103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116, + 111,112,111,112,117,112,17,111,103,95,109,111,117,115,101,115,99,114,111,108, + 108,99,111,108,0,13,102,105,120,99,111,108,115,46,99,111,117,110,116,2, + 1,13,102,105,120,99,111,108,115,46,105,116,101,109,115,14,1,5,119,105, + 100,116,104,2,26,8,110,117,109,115,116,97,114,116,2,1,7,110,117,109, + 115,116,101,112,2,1,0,0,13,102,105,120,114,111,119,115,46,99,111,117, + 110,116,2,1,13,102,105,120,114,111,119,115,46,105,116,101,109,115,14,1, + 6,104,101,105,103,104,116,2,16,14,99,97,112,116,105,111,110,115,46,99, + 111,117,110,116,2,2,14,99,97,112,116,105,111,110,115,46,105,116,101,109, + 115,14,1,7,99,97,112,116,105,111,110,6,22,83,121,110,116,97,120,32, + 100,101,102,105,110,105,116,105,111,110,32,102,105,108,101,0,1,7,99,97, + 112,116,105,111,110,6,9,70,105,108,101,32,109,97,115,107,0,0,0,0, + 14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,2,16,100,97, + 116,97,99,111,108,115,46,111,112,116,105,111,110,115,11,15,99,111,95,112, + 114,111,112,111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,118, + 97,108,117,101,12,99,111,95,115,97,118,101,115,116,97,116,101,17,99,111, + 95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,14,100,97,116, + 97,99,111,108,115,46,105,116,101,109,115,14,7,13,115,121,110,116,97,120, + 100,101,102,102,105,108,101,1,5,119,105,100,116,104,3,251,0,7,111,112, + 116,105,111,110,115,11,15,99,111,95,112,114,111,112,111,114,116,105,111,110, + 97,108,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111,95,115, + 97,118,101,115,116,97,116,101,17,99,111,95,109,111,117,115,101,115,99,114, + 111,108,108,114,111,119,0,10,111,110,115,104,111,119,104,105,110,116,7,13, + 99,111,108,111,110,115,104,111,119,104,105,110,116,10,119,105,100,103,101,116, + 110,97,109,101,6,13,115,121,110,116,97,120,100,101,102,102,105,108,101,9, + 100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115, + 116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,17,115,121,110,116, + 97,120,100,101,102,102,105,108,101,109,97,115,107,1,5,119,105,100,116,104, + 3,34,2,7,111,112,116,105,111,110,115,11,7,99,111,95,102,105,108,108, + 12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111,95,115,97,118, + 101,115,116,97,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108, + 108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,17,115,121, + 110,116,97,120,100,101,102,102,105,108,101,109,97,115,107,9,100,97,116,97, + 99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116,114,105,110, + 103,100,97,116,97,108,105,115,116,0,0,13,100,97,116,97,114,111,119,104, + 101,105,103,104,116,2,16,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,13,116,102,105,108,101,110,97,109,101,101,100,105,116,13,115, + 121,110,116,97,120,100,101,102,102,105,108,101,11,111,112,116,105,111,110,115, + 115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111, + 110,111,110,108,121,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,114,108,95,108,101,118,101,108,111,10,102,114,108,95,108,101, + 118,101,108,105,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 0,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110, + 116,2,1,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116, + 101,109,115,14,1,5,99,111,108,111,114,4,5,0,0,144,7,105,109,97, + 103,101,110,114,2,17,0,0,18,102,114,97,109,101,46,98,117,116,116,111, + 110,46,99,111,108,111,114,4,5,0,0,144,20,102,114,97,109,101,46,98, + 117,116,116,111,110,46,105,109,97,103,101,110,114,2,17,8,116,97,98,111, + 114,100,101,114,2,1,10,111,110,115,104,111,119,104,105,110,116,7,18,104, + 105,110,116,101,120,112,97,110,100,101,100,109,97,99,114,111,115,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,0,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,251, + 0,9,98,111,117,110,100,115,95,99,121,2,16,9,116,101,120,116,102,108, + 97,103,115,11,11,116,102,95,110,111,115,101,108,101,99,116,14,116,102,95, + 101,108,108,105,112,115,101,108,101,102,116,0,26,99,111,110,116,114,111,108, + 108,101,114,46,102,105,108,116,101,114,108,105,115,116,46,100,97,116,97,1, + 1,6,15,83,121,110,116,97,120,100,101,102,32,102,105,108,101,115,6,6, + 42,46,115,100,101,102,0,0,24,99,111,110,116,114,111,108,108,101,114,46, + 111,110,103,101,116,102,105,108,101,110,97,109,101,7,14,101,120,112,97,110, + 100,102,105,108,101,110,97,109,101,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,14,0,0,15,116,109,101,109,111,100,105,97,108,111,103,101, + 100,105,116,17,115,121,110,116,97,120,100,101,102,102,105,108,101,109,97,115, + 107,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119, + 49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,11,111, + 112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109, + 101,98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,0,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,19,102,114, + 97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1,19, + 102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14, + 1,5,99,111,108,111,114,4,5,0,0,144,7,105,109,97,103,101,110,114, + 2,17,0,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111, + 108,111,114,4,5,0,0,144,20,102,114,97,109,101,46,98,117,116,116,111, + 110,46,105,109,97,103,101,110,114,2,17,8,116,97,98,111,114,100,101,114, + 2,2,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120, + 3,252,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100, + 115,95,99,120,3,34,2,9,98,111,117,110,100,115,95,99,121,2,16,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,0,8, + 116,116,97,98,112,97,103,101,10,116,116,97,98,112,97,103,101,49,57,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116, + 97,98,111,114,100,101,114,2,3,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,19,9,98,111,117,110,100,115,95,99, + 120,3,62,3,9,98,111,117,110,100,115,95,99,121,3,197,0,7,97,110, + 99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110,95,116,111, + 112,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109, + 0,7,99,97,112,116,105,111,110,6,14,67,111,100,101,32,116,101,109,112, + 108,97,116,101,115,0,11,116,119,105,100,103,101,116,103,114,105,100,12,116, + 119,105,100,103,101,116,103,114,105,100,53,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,16,111,119,95,97,114,114,111,119,102,111,99,117,115, + 111,117,116,17,111,119,95,102,111,99,117,115,98,97,99,107,111,110,101,115, + 99,13,111,119,95,109,111,117,115,101,119,104,101,101,108,17,111,119,95,100, + 101,115,116,114,111,121,119,105,100,103,101,116,115,0,13,102,114,97,109,101, + 46,111,112,116,105,111,110,115,11,10,99,102,111,95,102,105,120,116,111,112, + 13,99,102,111,95,102,105,120,98,111,116,116,111,109,0,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,48,67,111,100,101,32,116,101,109,112, + 108,97,116,101,32,100,105,114,101,99,116,111,114,105,101,115,44,32,102,105, + 108,101,32,101,120,116,101,110,115,105,111,110,32,61,32,46,109,99,116,22, + 102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97, + 103,115,11,9,116,102,95,98,111,116,116,111,109,0,19,102,114,97,109,101, + 46,99,97,112,116,105,111,110,111,102,102,115,101,116,2,3,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97, + 98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97, + 99,116,105,118,101,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,17,2,0,2,0,0,8,98,111,117,110,100,115, + 95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,3,197, + 0,12,98,111,117,110,100,115,95,99,121,109,105,110,2,40,7,97,110,99, + 104,111,114,115,11,6,97,110,95,116,111,112,9,97,110,95,98,111,116,116, + 111,109,0,11,111,112,116,105,111,110,115,103,114,105,100,11,15,111,103,95, + 107,101,121,114,111,119,109,111,118,105,110,103,15,111,103,95,114,111,119,105, + 110,115,101,114,116,105,110,103,14,111,103,95,114,111,119,100,101,108,101,116, + 105,110,103,23,111,103,95,115,101,108,101,99,116,101,100,114,111,119,115,100, + 101,108,101,116,105,110,103,19,111,103,95,102,111,99,117,115,99,101,108,108, + 111,110,101,110,116,101,114,15,111,103,95,97,117,116,111,102,105,114,115,116, + 114,111,119,13,111,103,95,97,117,116,111,97,112,112,101,110,100,10,111,103, + 95,119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112,117, + 112,0,13,102,105,120,99,111,108,115,46,99,111,117,110,116,2,1,13,102, + 105,120,99,111,108,115,46,105,116,101,109,115,14,1,5,119,105,100,116,104, + 2,28,8,110,117,109,115,116,97,114,116,2,1,7,110,117,109,115,116,101, + 112,2,1,0,0,13,102,105,120,114,111,119,115,46,99,111,117,110,116,2, + 1,13,102,105,120,114,111,119,115,46,105,116,101,109,115,14,1,6,104,101, + 105,103,104,116,2,16,14,99,97,112,116,105,111,110,115,46,99,111,117,110, + 116,2,11,14,99,97,112,116,105,111,110,115,46,105,116,101,109,115,14,1, + 7,99,97,112,116,105,111,110,6,9,68,105,114,101,99,116,111,114,121,0, + 1,7,99,97,112,116,105,111,110,6,1,79,4,104,105,110,116,6,30,65, + 100,100,32,116,111,32,111,98,106,101,99,116,32,102,105,108,101,32,115,101, + 97,114,99,104,32,112,97,116,104,0,1,7,99,97,112,116,105,111,110,6, + 1,76,4,104,105,110,116,6,26,65,100,100,32,116,111,32,108,105,98,114, + 97,114,121,32,115,101,97,114,99,104,32,112,97,116,104,0,1,7,99,97, + 112,116,105,111,110,6,1,73,4,104,105,110,116,6,31,65,100,100,32,116, + 111,32,105,110,99,108,117,100,101,32,102,105,108,101,32,115,101,97,114,99, + 104,32,112,97,116,104,0,1,7,99,97,112,116,105,111,110,6,1,85,4, + 104,105,110,116,6,28,65,100,100,32,116,111,32,117,110,105,116,32,102,105, + 108,101,32,115,101,97,114,99,104,32,112,97,116,104,0,1,7,99,97,112, + 116,105,111,110,6,1,52,4,104,105,110,116,6,13,85,115,101,32,105,110, + 32,77,97,107,101,32,52,0,1,7,99,97,112,116,105,111,110,6,1,51, + 4,104,105,110,116,6,13,85,115,101,32,105,110,32,77,97,107,101,32,51, + 0,1,7,99,97,112,116,105,111,110,6,1,50,4,104,105,110,116,6,13, + 85,115,101,32,105,110,32,77,97,107,101,32,50,0,1,7,99,97,112,116, + 105,111,110,6,1,49,4,104,105,110,116,6,13,85,115,101,32,105,110,32, + 77,97,107,101,32,49,0,1,7,99,97,112,116,105,111,110,6,1,66,4, + 104,105,110,116,6,12,85,115,101,32,105,110,32,66,117,105,108,100,0,1, + 7,99,97,112,116,105,111,110,6,1,77,4,104,105,110,116,6,11,85,115, + 101,32,105,110,32,77,97,107,101,0,0,0,0,14,100,97,116,97,99,111, + 108,115,46,99,111,117,110,116,2,1,14,100,97,116,97,99,111,108,115,46, + 119,105,100,116,104,2,13,16,100,97,116,97,99,111,108,115,46,111,112,116, + 105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117,115,14,99, + 111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117, + 115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99, + 116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95, + 114,111,119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116,97, + 116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110, + 112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108, + 114,111,119,0,14,100,97,116,97,99,111,108,115,46,105,116,101,109,115,14, + 7,16,99,111,100,101,116,101,109,112,108,97,116,101,100,105,114,115,1,12, + 108,105,110,101,99,111,108,111,114,102,105,120,4,3,0,0,160,5,119,105, + 100,116,104,3,28,3,7,111,112,116,105,111,110,115,11,14,99,111,95,102, + 111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115, + 101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99, + 111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119, + 115,101,108,101,99,116,7,99,111,95,102,105,108,108,12,99,111,95,115,97, + 118,101,118,97,108,117,101,12,99,111,95,115,97,118,101,115,116,97,116,101, + 10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97, + 115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111, + 119,0,10,111,110,115,104,111,119,104,105,110,116,7,13,99,111,108,111,110, + 115,104,111,119,104,105,110,116,10,119,105,100,103,101,116,110,97,109,101,6, + 16,99,111,100,101,116,101,109,112,108,97,116,101,100,105,114,115,9,100,97, + 116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116,114, + 105,110,103,100,97,116,97,108,105,115,116,0,0,13,100,97,116,97,114,111, + 119,104,101,105,103,104,116,2,16,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,14,0,13,116,102,105,108,101,110,97,109,101,101,100,105,116, + 16,99,111,100,101,116,101,109,112,108,97,116,101,100,105,114,115,13,111,112, + 116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115, + 101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111, + 119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99, + 117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115, + 107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,2,0,0,128,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108, + 105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,97,99,116,105,118,101,0,19,102,114,97,109,101,46, + 98,117,116,116,111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109, + 101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111, + 108,111,114,4,2,0,0,128,7,105,109,97,103,101,110,114,2,17,0,0, + 18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111,114,4, + 2,0,0,128,20,102,114,97,109,101,46,98,117,116,116,111,110,46,105,109, + 97,103,101,110,114,2,17,8,116,97,98,111,114,100,101,114,2,1,10,111, + 110,115,104,111,119,104,105,110,116,7,18,104,105,110,116,101,120,112,97,110, + 100,101,100,109,97,99,114,111,115,7,118,105,115,105,98,108,101,8,8,98, + 111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0, + 9,98,111,117,110,100,115,95,99,120,3,28,3,9,98,111,117,110,100,115, + 95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,13, + 111,101,49,95,115,97,118,101,118,97,108,117,101,0,11,111,112,116,105,111, + 110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99, + 13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104, + 101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105,102,116, + 114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114,110,20, + 111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116, + 15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95, + 101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101, + 108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110, + 102,105,114,115,116,99,108,105,99,107,0,18,99,111,110,116,114,111,108,108, + 101,114,46,111,112,116,105,111,110,115,11,13,102,100,111,95,100,105,114,101, + 99,116,111,114,121,0,26,99,111,110,116,114,111,108,108,101,114,46,104,105, + 115,116,111,114,121,109,97,120,99,111,117,110,116,2,0,22,99,111,110,116, + 114,111,108,108,101,114,46,99,97,112,116,105,111,110,111,112,101,110,6,21, + 83,101,108,101,99,116,32,117,110,105,116,32,100,105,114,101,99,116,111,114, + 121,24,99,111,110,116,114,111,108,108,101,114,46,111,110,103,101,116,102,105, + 108,101,110,97,109,101,7,14,101,120,112,97,110,100,102,105,108,101,110,97, + 109,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0, + 0,0,0,9,116,108,97,121,111,117,116,101,114,11,116,108,97,121,111,117, + 116,101,114,49,51,5,99,111,108,111,114,4,3,0,0,128,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,28,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,100,105,115,97,98,108, + 101,100,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116, + 105,118,101,15,102,114,108,95,111,112,116,105,111,110,115,115,107,105,110,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99, + 107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,97,99,116,105,118,101,0,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,3,37,1,7, + 97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,0,12,111,112,116, + 105,111,110,115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97,110, + 100,120,11,111,115,99,95,101,120,112,97,110,100,121,11,111,115,99,95,115, + 104,114,105,110,107,121,17,111,115,99,95,101,120,112,97,110,100,115,104,114, + 105,110,107,120,17,111,115,99,95,101,120,112,97,110,100,115,104,114,105,110, + 107,121,0,13,111,112,116,105,111,110,115,108,97,121,111,117,116,11,10,108, + 97,111,95,112,108,97,99,101,121,0,13,112,108,97,99,101,95,109,105,110, + 100,105,115,116,2,2,13,112,108,97,99,101,95,109,97,120,100,105,115,116, + 2,2,13,112,108,97,99,101,95,111,112,116,105,111,110,115,11,13,112,108, + 111,95,101,110,100,109,97,114,103,105,110,0,10,108,105,110,107,98,111,116, + 116,111,109,7,11,116,116,97,98,119,105,100,103,101,116,50,11,100,105,115, + 116,95,98,111,116,116,111,109,2,2,0,11,116,119,105,100,103,101,116,103, + 114,105,100,8,100,105,115,112,103,114,105,100,14,111,112,116,105,111,110,115, + 119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121, + 112,104,104,101,105,103,104,116,0,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111, + 119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102, + 111,99,117,115,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,17,111,119,95,102,111,99,117,115,98,97,99,107,111,110,101,115,99,13, + 111,119,95,109,111,117,115,101,119,104,101,101,108,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,13,102,114,97,109,101,46,99, + 97,112,116,105,111,110,6,4,84,101,115,116,22,102,114,97,109,101,46,99, + 97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,9,116,102,95, + 98,111,116,116,111,109,0,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,11,99,112,95,116,111,112,114,105,103,104,116,17,102,114, + 97,109,101,46,102,111,110,116,46,120,115,99,97,108,101,2,1,21,102,114, + 97,109,101,46,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,108,112,95,120,115,99,97,108,101,0,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99, + 107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100, + 25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118, + 101,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,4, + 8,98,111,117,110,100,115,95,120,2,6,8,98,111,117,110,100,115,95,121, + 3,202,0,9,98,111,117,110,100,115,95,99,120,3,49,3,9,98,111,117, + 110,100,115,95,99,121,2,91,7,97,110,99,104,111,114,115,11,7,97,110, + 95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104, + 116,0,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110, + 116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115, + 99,97,108,101,0,11,111,112,116,105,111,110,115,103,114,105,100,11,15,111, + 103,95,114,111,119,105,110,115,101,114,116,105,110,103,14,111,103,95,114,111, + 119,100,101,108,101,116,105,110,103,19,111,103,95,102,111,99,117,115,99,101, + 108,108,111,110,101,110,116,101,114,15,111,103,95,97,117,116,111,102,105,114, + 115,116,114,111,119,13,111,103,95,97,117,116,111,97,112,112,101,110,100,10, + 111,103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111, + 112,117,112,0,8,114,111,119,99,111,117,110,116,2,2,15,114,111,119,99, + 111,108,111,114,115,46,99,111,117,110,116,2,1,15,114,111,119,99,111,108, + 111,114,115,46,105,116,101,109,115,1,4,255,255,224,0,0,14,100,97,116, + 97,99,111,108,115,46,99,111,117,110,116,2,1,18,100,97,116,97,99,111, + 108,115,46,108,105,110,101,119,105,100,116,104,2,0,16,100,97,116,97,99, + 111,108,115,46,111,112,116,105,111,110,115,11,7,99,111,95,102,105,108,108, + 12,99,111,95,115,97,118,101,115,116,97,116,101,0,14,100,97,116,97,99, + 111,108,115,46,105,116,101,109,115,14,7,8,102,111,110,116,100,105,115,112, + 1,5,119,105,100,116,104,3,44,3,7,111,112,116,105,111,110,115,11,7, + 99,111,95,102,105,108,108,12,99,111,95,115,97,118,101,115,116,97,116,101, + 0,10,119,105,100,103,101,116,110,97,109,101,6,8,102,111,110,116,100,105, + 115,112,9,100,97,116,97,99,108,97,115,115,7,23,116,103,114,105,100,114, + 105,99,104,115,116,114,105,110,103,100,97,116,97,108,105,115,116,4,100,97, + 116,97,1,1,6,0,6,0,0,0,0,0,16,100,97,116,97,114,111,119, + 108,105,110,101,119,105,100,116,104,2,0,13,100,97,116,97,114,111,119,104, + 101,105,103,104,116,2,14,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,9,116,116,101,120,116,101,100,105,116,8,102,111,110,116,100, + 105,115,112,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19, + 111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,13, + 111,119,49,95,97,117,116,111,115,99,97,108,101,0,13,111,112,116,105,111, + 110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111, + 99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97, + 114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111, + 99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111, + 117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102, + 114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98,111, + 114,100,101,114,2,1,7,118,105,115,105,98,108,101,8,8,98,111,117,110, + 100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,120,3,44,3,9,98,111,117,110,100,115,95,99,121, + 2,14,9,102,111,110,116,46,110,97,109,101,6,11,115,116,102,95,100,101, + 102,97,117,108,116,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15, + 102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112, + 95,120,115,99,97,108,101,0,12,111,112,116,105,111,110,115,101,100,105,116, + 49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117, + 14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95, + 115,97,118,101,115,116,97,116,101,0,11,111,112,116,105,111,110,115,101,100, + 105,116,11,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101, + 95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,108,105, + 110,101,98,114,101,97,107,12,111,101,95,101,97,116,114,101,116,117,114,110, + 15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,20,111,101,95, + 110,111,102,105,114,115,116,97,114,114,111,119,110,97,118,105,103,0,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,9,116,108, + 97,121,111,117,116,101,114,11,116,108,97,121,111,117,116,101,114,49,50,5, + 99,111,108,111,114,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,28,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117, + 115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,15,102,114, + 108,95,111,112,116,105,111,110,115,115,107,105,110,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98, + 108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99, + 116,105,118,101,0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117, + 110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,3,163,0,9, + 98,111,117,110,100,115,95,99,120,3,88,2,9,98,111,117,110,100,115,95, + 99,121,2,37,12,111,112,116,105,111,110,115,115,99,97,108,101,11,11,111, + 115,99,95,101,120,112,97,110,100,120,11,111,115,99,95,115,104,114,105,110, + 107,120,11,111,115,99,95,101,120,112,97,110,100,121,11,111,115,99,95,115, + 104,114,105,110,107,121,0,13,111,112,116,105,111,110,115,108,97,121,111,117, + 116,11,10,108,97,111,95,97,108,105,103,110,121,0,10,97,108,105,103,110, + 95,103,108,117,101,7,9,119,97,109,95,115,116,97,114,116,0,12,116,105, + 110,116,101,103,101,114,101,100,105,116,18,101,100,105,116,102,111,110,116,101, + 120,116,114,97,115,112,97,99,101,5,99,111,108,111,114,4,3,0,0,128, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,5,69,120,116,83, + 112,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102, + 108,97,103,115,11,9,116,102,95,98,111,116,116,111,109,0,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97, + 98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97, + 99,116,105,118,101,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,17,2,1,2,0,0,8,116,97,98,111,114,100, + 101,114,2,3,4,104,105,110,116,6,25,69,120,116,114,97,32,115,112,97, + 99,101,32,98,101,116,119,101,101,110,32,108,105,110,101,115,8,98,111,117, + 110,100,115,95,120,3,247,0,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,120,2,37,9,98,111,117,110,100,115,95,99, + 121,2,37,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,17,102, + 111,110,116,111,110,100,97,116,97,101,110,116,101,114,101,100,8,118,97,108, + 117,101,109,105,110,3,24,252,8,118,97,108,117,101,109,97,120,3,232,3, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,12,116, + 105,110,116,101,103,101,114,101,100,105,116,13,101,100,105,116,102,111,110,116, + 119,105,100,116,104,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 5,87,105,100,116,104,22,102,114,97,109,101,46,99,97,112,116,105,111,110, + 116,101,120,116,102,108,97,103,115,11,9,116,102,95,98,111,116,116,111,109, + 0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109, + 111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99, + 107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,97,99,116,105,118,101,0,16,102,114,97,109,101,46,111,117, + 116,101,114,102,114,97,109,101,1,2,0,2,17,2,1,2,0,0,8,116, + 97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,3,199, + 0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,2,37,9,98,111,117,110,100,115,95,99,121,2,37,13,111,110,100, + 97,116,97,101,110,116,101,114,101,100,7,17,102,111,110,116,111,110,100,97, + 116,97,101,110,116,101,114,101,100,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,14,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116, + 14,101,100,105,116,102,111,110,116,104,101,105,103,104,116,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,6,72,101,105,103,104,116,22,102,114, + 97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115, + 11,9,116,102,95,98,111,116,116,111,109,0,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99, + 107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100, + 25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118, + 101,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,17,2,7,2,0,0,8,116,97,98,111,114,100,101,114,2,1, + 8,98,111,117,110,100,115,95,120,3,151,0,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,120,2,43,9,98,111,117,110, + 100,115,95,99,121,2,37,13,111,110,100,97,116,97,101,110,116,101,114,101, + 100,7,17,102,111,110,116,111,110,100,97,116,97,101,110,116,101,114,101,100, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,11,116, + 115,116,114,105,110,103,101,100,105,116,12,101,100,105,116,102,111,110,116,110, + 97,109,101,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,16,111, + 119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100, + 101,115,116,114,111,121,119,105,100,103,101,116,115,0,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,4,70,111,110,116,22,102,114,97,109,101, + 46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,9,116, + 102,95,98,111,116,116,111,109,0,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114, + 105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98, + 111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100, + 26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101, + 116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111, + 117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2, + 17,2,0,2,0,0,8,98,111,117,110,100,115,95,120,2,7,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,124, + 9,98,111,117,110,100,115,95,99,121,2,37,13,111,110,100,97,116,97,101, + 110,116,101,114,101,100,7,17,102,111,110,116,111,110,100,97,116,97,101,110, + 116,101,114,101,100,5,118,97,108,117,101,6,13,109,115,101,105,100,101,95, + 115,111,117,114,99,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,10,116,99,111,108,111,114,101,100,105,116,13,101,100,105,116, + 102,111,110,116,99,111,108,111,114,13,102,114,97,109,101,46,99,97,112,116, + 105,111,110,6,5,67,111,108,111,114,22,102,114,97,109,101,46,99,97,112, + 116,105,111,110,116,101,120,116,102,108,97,103,115,11,9,116,102,95,98,111, + 116,116,111,109,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111, + 108,111,114,4,2,0,0,128,20,102,114,97,109,101,46,98,117,116,116,111, + 110,46,111,112,116,105,111,110,115,11,21,102,98,111,95,105,110,97,99,116, + 105,118,101,105,110,118,105,115,105,98,108,101,0,19,102,114,97,109,101,46, + 98,117,116,116,111,110,115,46,99,111,117,110,116,2,2,19,102,114,97,109, + 101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111, + 108,111,114,4,2,0,0,128,7,111,112,116,105,111,110,115,11,21,102,98, + 111,95,105,110,97,99,116,105,118,101,105,110,118,105,115,105,98,108,101,0, + 0,1,5,99,111,108,111,114,4,2,0,0,128,7,105,109,97,103,101,110, + 114,2,17,7,111,112,116,105,111,110,115,11,21,102,98,111,95,105,110,97, + 99,116,105,118,101,105,110,118,105,115,105,98,108,101,0,0,0,25,102,114, + 97,109,101,46,98,117,116,116,111,110,101,108,108,105,112,115,101,46,99,111, + 108,111,114,4,2,0,0,128,27,102,114,97,109,101,46,98,117,116,116,111, + 110,101,108,108,105,112,115,101,46,105,109,97,103,101,110,114,2,17,27,102, + 114,97,109,101,46,98,117,116,116,111,110,101,108,108,105,112,115,101,46,111, + 112,116,105,111,110,115,11,21,102,98,111,95,105,110,97,99,116,105,118,101, + 105,110,118,105,115,105,98,108,101,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97, + 98,111,114,100,101,114,2,4,8,98,111,117,110,100,115,95,120,3,47,1, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 121,2,37,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101, + 49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95, + 107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,118, + 97,108,117,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0,11, + 111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111, + 111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16, + 111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95, + 115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101, + 116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111, + 110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111, + 114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97, + 117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108, + 101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,18,111,101,95,104, + 105,110,116,99,108,105,112,112,101,100,116,101,120,116,0,13,111,110,100,97, + 116,97,101,110,116,101,114,101,100,7,17,102,111,110,116,111,110,100,97,116, + 97,101,110,116,101,114,101,100,5,118,97,108,117,101,4,9,0,0,144,16, + 100,114,111,112,100,111,119,110,46,111,112,116,105,111,110,115,11,16,100,101, + 111,95,97,117,116,111,100,114,111,112,100,111,119,110,15,100,101,111,95,107, + 101,121,100,114,111,112,100,111,119,110,12,100,101,111,95,99,108,105,112,104, + 105,110,116,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,0,10,116,99,111,108,111,114,101,100,105,116,11,101,100,105,116,98,107, + 99,111,108,111,114,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 9,66,107,46,32,67,111,108,111,114,22,102,114,97,109,101,46,99,97,112, + 116,105,111,110,116,101,120,116,102,108,97,103,115,11,9,116,102,95,98,111, + 116,116,111,109,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111, + 108,111,114,4,2,0,0,128,20,102,114,97,109,101,46,98,117,116,116,111, + 110,46,111,112,116,105,111,110,115,11,21,102,98,111,95,105,110,97,99,116, + 105,118,101,105,110,118,105,115,105,98,108,101,0,19,102,114,97,109,101,46, + 98,117,116,116,111,110,115,46,99,111,117,110,116,2,2,19,102,114,97,109, + 101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111, + 108,111,114,4,2,0,0,128,7,111,112,116,105,111,110,115,11,21,102,98, + 111,95,105,110,97,99,116,105,118,101,105,110,118,105,115,105,98,108,101,0, + 0,1,5,99,111,108,111,114,4,2,0,0,128,7,105,109,97,103,101,110, + 114,2,17,7,111,112,116,105,111,110,115,11,21,102,98,111,95,105,110,97, + 99,116,105,118,101,105,110,118,105,115,105,98,108,101,0,0,0,25,102,114, + 97,109,101,46,98,117,116,116,111,110,101,108,108,105,112,115,101,46,99,111, + 108,111,114,4,2,0,0,128,27,102,114,97,109,101,46,98,117,116,116,111, + 110,101,108,108,105,112,115,101,46,105,109,97,103,101,110,114,2,17,27,102, + 114,97,109,101,46,98,117,116,116,111,110,101,108,108,105,112,115,101,46,111, + 112,116,105,111,110,115,11,21,102,98,111,95,105,110,97,99,116,105,118,101, + 105,110,118,105,115,105,98,108,101,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97, + 98,111,114,100,101,114,2,5,8,98,111,117,110,100,115,95,120,3,151,1, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 121,2,37,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101, + 49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95, + 107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,118, + 97,108,117,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0,11, + 111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111, + 111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16, + 111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95, + 115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101, + 116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111, + 110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111, + 114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97, + 117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108, + 101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,18,111,101,95,104, + 105,110,116,99,108,105,112,112,101,100,116,101,120,116,0,13,111,110,100,97, + 116,97,101,110,116,101,114,101,100,7,17,102,111,110,116,111,110,100,97,116, + 97,101,110,116,101,114,101,100,5,118,97,108,117,101,4,6,0,0,144,16, + 100,114,111,112,100,111,119,110,46,111,112,116,105,111,110,115,11,16,100,101, + 111,95,97,117,116,111,100,114,111,112,100,111,119,110,15,100,101,111,95,107, + 101,121,100,114,111,112,100,111,119,110,12,100,101,111,95,99,108,105,112,104, + 105,110,116,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,19,101,100,105,116, + 102,111,110,116,97,110,116,105,97,108,105,97,115,101,100,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,12,65,110,116,105,32,97,108,105,97, + 115,101,100,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116, + 17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101, + 116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118, + 101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108, + 105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,97,99,116,105,118,101,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,2,76,2,2,0, + 8,116,97,98,111,114,100,101,114,2,6,8,98,111,117,110,100,115,95,120, + 3,255,1,8,98,111,117,110,100,115,95,121,2,20,9,98,111,117,110,100, + 115,95,99,120,2,89,9,98,111,117,110,100,115,95,99,121,2,16,13,111, + 110,100,97,116,97,101,110,116,101,114,101,100,7,17,102,111,110,116,111,110, + 100,97,116,97,101,110,116,101,114,101,100,5,118,97,108,117,101,9,0,0, + 0,9,116,108,97,121,111,117,116,101,114,11,116,108,97,121,111,117,116,101, + 114,49,49,5,99,111,108,111,114,4,3,0,0,128,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,28,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100, + 25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101, + 116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118, + 101,15,102,114,108,95,111,112,116,105,111,110,115,115,107,105,110,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100, + 105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101, + 100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,97,99,116,105,118,101,0,8,116,97,98,111,114,100,101,114,2,2, + 8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121, + 2,91,9,98,111,117,110,100,115,95,99,120,3,60,2,9,98,111,117,110, + 100,115,95,99,121,2,70,12,111,112,116,105,111,110,115,115,99,97,108,101, + 11,11,111,115,99,95,101,120,112,97,110,100,120,11,111,115,99,95,115,104, + 114,105,110,107,120,11,111,115,99,95,101,120,112,97,110,100,121,11,111,115, + 99,95,115,104,114,105,110,107,121,0,13,111,112,116,105,111,110,115,108,97, + 121,111,117,116,11,10,108,97,111,95,97,108,105,103,110,121,0,10,97,108, + 105,103,110,95,103,108,117,101,7,9,119,97,109,95,115,116,97,114,116,0, + 9,116,108,97,121,111,117,116,101,114,11,116,108,97,121,111,117,116,101,114, + 49,52,8,98,111,117,110,100,115,95,120,2,7,8,98,111,117,110,100,115, + 95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,121,9,98,111,117, + 110,100,115,95,99,121,2,70,12,111,112,116,105,111,110,115,115,99,97,108, + 101,11,11,111,115,99,95,101,120,112,97,110,100,120,11,111,115,99,95,115, + 104,114,105,110,107,120,11,111,115,99,95,101,120,112,97,110,100,121,11,111, + 115,99,95,115,104,114,105,110,107,121,0,13,111,112,116,105,111,110,115,108, + 97,121,111,117,116,11,10,108,97,111,95,112,108,97,99,101,121,0,13,112, + 108,97,99,101,95,109,105,110,100,105,115,116,2,2,13,112,108,97,99,101, + 95,109,97,120,100,105,115,116,2,2,0,12,116,98,111,111,108,101,97,110, + 101,100,105,116,13,114,105,103,104,116,109,97,114,103,105,110,111,110,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,17,82,105,103,104,116,32, + 109,97,114,103,105,110,32,108,105,110,101,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107, + 101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101, + 0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2, + 0,2,1,2,108,2,2,0,8,116,97,98,111,114,100,101,114,2,3,8, + 98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2, + 54,9,98,111,117,110,100,115,95,99,120,2,121,9,98,111,117,110,100,115, + 95,99,121,2,16,5,118,97,108,117,101,9,0,0,12,116,98,111,111,108, + 101,97,110,101,100,105,116,13,108,105,110,101,110,117,109,98,101,114,115,111, + 110,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,12,76,105,110, + 101,32,110,117,109,98,101,114,115,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,1,2,87,2,2,0,8,98,111,117,110, + 100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,120,2,100,9,98,111,117,110,100,115,95,99,121,2, + 16,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,16,101,100,105, + 116,109,97,114,107,98,114,97,99,107,101,116,115,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,13,77,97,114,107,32,98,114,97,99,107,101, + 116,115,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105, + 99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,97,99,116,105,118,101,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,1,2,92,2,2,0,8, + 116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2, + 0,8,98,111,117,110,100,115,95,121,2,18,9,98,111,117,110,100,115,95, + 99,120,2,105,9,98,111,117,110,100,115,95,99,121,2,16,5,118,97,108, + 117,101,9,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,17,101, + 100,105,116,109,97,114,107,112,97,105,114,119,111,114,100,115,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,14,77,97,114,107,32,112,97,105, + 114,119,111,114,100,115,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108, + 101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111, + 112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104, + 116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116, + 111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99, + 116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101, + 27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,2,98, + 2,2,0,8,116,97,98,111,114,100,101,114,2,2,4,104,105,110,116,6, + 50,77,97,114,107,32,105,110,32,115,121,110,116,97,120,32,100,101,102,105, + 110,105,116,105,111,110,32,102,105,108,101,32,100,101,102,105,110,101,100,32, + 119,111,114,100,32,112,97,105,114,115,46,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,2,36,9,98,111,117,110,100,115, + 95,99,120,2,111,9,98,111,117,110,100,115,95,99,121,2,16,5,118,97, + 108,117,101,9,0,0,0,9,116,108,97,121,111,117,116,101,114,11,116,108, + 97,121,111,117,116,101,114,49,53,8,116,97,98,111,114,100,101,114,2,1, + 8,98,111,117,110,100,115,95,120,3,143,0,8,98,111,117,110,100,115,95, + 121,2,10,9,98,111,117,110,100,115,95,99,120,3,173,1,9,98,111,117, + 110,100,115,95,99,121,2,51,12,111,112,116,105,111,110,115,115,99,97,108, + 101,11,11,111,115,99,95,101,120,112,97,110,100,120,11,111,115,99,95,115, + 104,114,105,110,107,120,11,111,115,99,95,101,120,112,97,110,100,121,11,111, + 115,99,95,115,104,114,105,110,107,121,17,111,115,99,95,101,120,112,97,110, + 100,115,104,114,105,110,107,120,17,111,115,99,95,101,120,112,97,110,100,115, + 104,114,105,110,107,121,0,13,111,112,116,105,111,110,115,108,97,121,111,117, + 116,11,10,108,97,111,95,97,108,105,103,110,121,0,10,97,108,105,103,110, + 95,103,108,117,101,7,9,119,97,109,95,115,116,97,114,116,0,10,116,99, + 111,108,111,114,101,100,105,116,13,112,97,105,114,109,97,114,107,99,111,108, + 111,114,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,10,77,97, + 114,107,10,99,111,108,111,114,22,102,114,97,109,101,46,99,97,112,116,105, + 111,110,116,101,120,116,102,108,97,103,115,11,9,116,102,95,98,111,116,116, + 111,109,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111, + 114,4,2,0,0,128,20,102,114,97,109,101,46,98,117,116,116,111,110,46, + 111,112,116,105,111,110,115,11,21,102,98,111,95,105,110,97,99,116,105,118, + 101,105,110,118,105,115,105,98,108,101,0,19,102,114,97,109,101,46,98,117, + 116,116,111,110,115,46,99,111,117,110,116,2,2,19,102,114,97,109,101,46, + 98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111, + 114,4,2,0,0,128,7,111,112,116,105,111,110,115,11,21,102,98,111,95, + 105,110,97,99,116,105,118,101,105,110,118,105,115,105,98,108,101,0,0,1, + 5,99,111,108,111,114,4,2,0,0,128,7,105,109,97,103,101,110,114,2, + 17,7,111,112,116,105,111,110,115,11,21,102,98,111,95,105,110,97,99,116, + 105,118,101,105,110,118,105,115,105,98,108,101,0,0,0,25,102,114,97,109, + 101,46,98,117,116,116,111,110,101,108,108,105,112,115,101,46,99,111,108,111, + 114,4,2,0,0,128,27,102,114,97,109,101,46,98,117,116,116,111,110,101, + 108,108,105,112,115,101,46,105,109,97,103,101,110,114,2,17,27,102,114,97, + 109,101,46,98,117,116,116,111,110,101,108,108,105,112,115,101,46,111,112,116, + 105,111,110,115,11,21,102,98,111,95,105,110,97,99,116,105,118,101,105,110, + 118,105,115,105,98,108,101,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,31,2,0,2,0,0,8,116,97,98,111, + 114,100,101,114,2,3,4,104,105,110,116,6,131,66,97,99,107,103,114,111, + 117,110,100,32,99,111,108,111,114,32,111,102,32,109,97,114,107,101,100,32, + 98,114,97,99,107,101,116,115,32,97,110,100,32,119,111,114,100,32,112,97, + 105,114,115,46,10,87,105,108,108,32,98,101,32,111,118,101,114,114,105,100, + 100,101,110,32,98,121,32,115,101,116,116,105,110,103,32,105,110,32,115,121, + 110,116,97,120,32,100,101,102,105,110,105,116,105,111,110,32,102,105,108,101, + 46,10,99,108,95,110,111,110,101,32,45,62,32,102,111,114,99,101,32,110, + 111,110,101,46,10,111,110,115,104,111,119,104,105,110,116,7,9,99,111,108, + 111,114,104,105,110,116,8,98,111,117,110,100,115,95,120,3,8,1,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,121,2, + 51,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95, + 97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101, + 121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,118,97,108, + 117,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0,11,111,112, + 116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110, + 101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101, + 95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104, + 105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116,117, + 114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101, + 120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13, + 111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116, + 111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99, + 116,111,110,102,105,114,115,116,99,108,105,99,107,18,111,101,95,104,105,110, + 116,99,108,105,112,112,101,100,116,101,120,116,0,16,100,114,111,112,100,111, + 119,110,46,111,112,116,105,111,110,115,11,16,100,101,111,95,97,117,116,111, + 100,114,111,112,100,111,119,110,15,100,101,111,95,107,101,121,100,114,111,112, + 100,111,119,110,12,100,101,111,95,99,108,105,112,104,105,110,116,0,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,10,116,99,111, + 108,111,114,101,100,105,116,14,115,116,97,116,101,109,101,110,116,99,111,108, + 111,114,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,15,83,116, + 97,116,101,109,101,110,116,10,99,111,108,111,114,22,102,114,97,109,101,46, + 99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,9,116,102, + 95,98,111,116,116,111,109,0,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,18,102,114,97,109,101,46,98,117,116,116,111,110, + 46,99,111,108,111,114,4,2,0,0,128,20,102,114,97,109,101,46,98,117, + 116,116,111,110,46,111,112,116,105,111,110,115,11,21,102,98,111,95,105,110, + 97,99,116,105,118,101,105,110,118,105,115,105,98,108,101,0,19,102,114,97, + 109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,2,19,102, + 114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1, + 5,99,111,108,111,114,4,2,0,0,128,7,111,112,116,105,111,110,115,11, + 21,102,98,111,95,105,110,97,99,116,105,118,101,105,110,118,105,115,105,98, + 108,101,0,0,1,5,99,111,108,111,114,4,2,0,0,128,7,105,109,97, + 103,101,110,114,2,17,7,111,112,116,105,111,110,115,11,21,102,98,111,95, + 105,110,97,99,116,105,118,101,105,110,118,105,115,105,98,108,101,0,0,0, + 25,102,114,97,109,101,46,98,117,116,116,111,110,101,108,108,105,112,115,101, + 46,99,111,108,111,114,4,2,0,0,128,27,102,114,97,109,101,46,98,117, + 116,116,111,110,101,108,108,105,112,115,101,46,105,109,97,103,101,110,114,2, + 17,27,102,114,97,109,101,46,98,117,116,116,111,110,101,108,108,105,112,115, + 101,46,111,112,116,105,111,110,115,11,21,102,98,111,95,105,110,97,99,116, + 105,118,101,105,110,118,105,115,105,98,108,101,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,31,2,0,2,0,0, + 8,116,97,98,111,114,100,101,114,2,2,4,104,105,110,116,6,131,66,97, + 99,107,103,114,111,117,110,100,32,99,111,108,111,114,32,111,102,32,116,104, + 101,32,97,99,116,105,118,101,32,114,111,119,32,119,104,105,108,101,32,100, + 101,98,117,103,103,105,110,103,46,10,87,105,108,108,32,98,101,32,111,118, + 101,114,114,105,100,100,101,110,32,98,121,32,115,101,116,116,105,110,103,32, + 105,110,32,115,121,110,116,97,120,32,100,101,102,105,110,105,116,105,111,110, + 32,102,105,108,101,46,10,99,108,95,110,111,110,101,32,45,62,32,102,111, + 114,99,101,32,110,111,110,101,46,10,111,110,115,104,111,119,104,105,110,116, + 7,9,99,111,108,111,114,104,105,110,116,8,98,111,117,110,100,115,95,120, + 3,160,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100, + 115,95,99,121,2,51,12,111,112,116,105,111,110,115,101,100,105,116,49,11, + 17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111, + 101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97, + 118,101,118,97,108,117,101,13,111,101,49,95,115,97,118,101,115,116,97,116, + 101,0,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117, + 110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101, + 114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14, + 111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97, + 116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101, + 99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117, + 114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111, + 101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111, + 115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,18,111, + 101,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116,0,13,111, + 110,100,97,116,97,101,110,116,101,114,101,100,7,17,102,111,110,116,111,110, + 100,97,116,97,101,110,116,101,114,101,100,5,118,97,108,117,101,4,255,255, + 224,0,16,100,114,111,112,100,111,119,110,46,111,112,116,105,111,110,115,11, + 16,100,101,111,95,97,117,116,111,100,114,111,112,100,111,119,110,15,100,101, + 111,95,107,101,121,100,114,111,112,100,111,119,110,12,100,101,111,95,99,108, + 105,112,104,105,110,116,0,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,12,115, + 99,114,111,108,108,104,101,105,103,104,116,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,13,83,99,114,111,108,108,10,104,101,105,103,104,116, + 22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108, + 97,103,115,11,9,116,102,95,98,111,116,116,111,109,0,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99, + 108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98, + 108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99, + 116,105,118,101,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,31,2,6,2,0,0,8,116,97,98,111,114,100,101, + 114,2,1,4,104,105,110,116,6,29,48,32,45,62,32,97,99,99,101,108, + 101,114,97,116,101,100,44,10,45,49,32,45,62,32,112,97,103,101,100,8, + 98,111,117,110,100,115,95,120,2,104,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,2,42,9,98,111,117,110,100,115, + 95,99,121,2,51,8,118,97,108,117,101,109,105,110,2,255,8,118,97,108, + 117,101,109,97,120,3,232,3,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,14,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,16, + 114,105,103,104,116,109,97,114,103,105,110,99,104,97,114,115,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,10,67,104,97,114,97,99,116,101, + 114,115,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116, + 102,108,97,103,115,11,9,116,102,95,98,111,116,116,111,109,0,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101, + 27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101, + 116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115, + 97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 97,99,116,105,118,101,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,17,2,35,2,0,0,8,98,111,117,110,100, + 115,95,120,2,8,8,98,111,117,110,100,115,95,121,2,14,9,98,111,117, + 110,100,115,95,99,120,2,71,9,98,111,117,110,100,115,95,99,121,2,37, + 12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97, + 117,116,111,112,111,112,117,112,109,101,110,117,13,111,101,49,95,115,97,118, + 101,118,97,108,117,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101, + 0,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110, + 100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114, + 121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111, + 101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116, + 115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116, + 111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116, + 101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95, + 97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105, + 99,107,0,5,118,97,108,117,101,2,80,8,118,97,108,117,101,109,105,110, + 2,1,8,118,97,108,117,101,109,97,120,2,100,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,14,0,0,12,116,105,110,116,101,103,101,114, + 101,100,105,116,15,112,97,105,114,109,97,120,114,111,119,99,111,117,110,116, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,17,77,97,114,107, + 32,109,97,120,10,114,111,119,99,111,117,110,116,22,102,114,97,109,101,46, + 99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,9,116,102, + 95,98,111,116,116,111,109,0,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,31,2,1,2,0,0,8,116,97,98,111,114, + 100,101,114,2,4,8,98,111,117,110,100,115,95,120,3,112,1,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,61, + 9,98,111,117,110,100,115,95,99,121,2,51,5,118,97,108,117,101,2,100, + 8,118,97,108,117,101,109,105,110,2,1,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,0,0,0,9,116,108,97,121,111,117,116,101, + 114,11,116,108,97,121,111,117,116,101,114,49,48,5,99,111,108,111,114,4, + 3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102, + 116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109, + 20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101, + 116,28,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,100,105,115,97,98,108,101,100,25,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105, + 99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,97,99,116,105,118,101,15,102,114,108,95,111,112,116,105, + 111,110,115,115,107,105,110,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111, + 117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,8, + 116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2, + 0,8,98,111,117,110,100,115,95,121,2,52,9,98,111,117,110,100,115,95, + 99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,2,37,7,97,110, + 99,104,111,114,115,11,6,97,110,95,116,111,112,0,12,111,112,116,105,111, + 110,115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97,110,100,121, + 11,111,115,99,95,115,104,114,105,110,107,121,0,13,111,112,116,105,111,110, + 115,108,97,121,111,117,116,11,10,108,97,111,95,97,108,105,103,110,121,0, + 10,97,108,105,103,110,95,103,108,117,101,7,9,119,97,109,95,115,116,97, + 114,116,0,12,116,98,111,111,108,101,97,110,101,100,105,116,9,115,112,97, + 99,101,116,97,98,115,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,5,83,112,97,99,101,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116, + 111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103, + 104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116, + 116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97, + 99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115, + 101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,2, + 42,2,2,0,8,116,97,98,111,114,100,101,114,2,4,8,98,111,117,110, + 100,115,95,120,3,47,1,8,98,111,117,110,100,115,95,121,2,20,9,98, + 111,117,110,100,115,95,99,120,2,55,9,98,111,117,110,100,115,95,99,121, + 2,16,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,11,98,108, + 111,99,107,105,110,100,101,110,116,13,102,114,97,109,101,46,99,97,112,116, + 105,111,110,6,12,66,108,111,99,107,32,73,110,100,101,110,116,22,102,114, + 97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115, + 11,9,116,102,95,98,111,116,116,111,109,0,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99, + 107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100, + 25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118, + 101,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,17,2,43,2,0,0,8,116,97,98,111,114,100,101,114,2,1, + 8,98,111,117,110,100,115,95,120,3,151,0,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,120,2,79,9,98,111,117,110, + 100,115,95,99,121,2,37,12,111,112,116,105,111,110,115,101,100,105,116,49, + 11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,13, + 111,101,49,95,115,97,118,101,118,97,108,117,101,13,111,101,49,95,115,97, + 118,101,115,116,97,116,101,0,11,111,112,116,105,111,110,115,101,100,105,116, + 11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108, + 111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99, + 97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111, + 101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15, + 111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101, + 110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108, + 101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102, + 105,114,115,116,99,108,105,99,107,0,5,118,97,108,117,101,2,1,8,118, + 97,108,117,101,109,105,110,2,1,8,118,97,108,117,101,109,97,120,2,100, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,12,116, + 98,111,111,108,101,97,110,101,100,105,116,10,97,117,116,111,105,110,100,101, + 110,116,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,11,65,117, + 116,111,32,105,110,100,101,110,116,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114, + 105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98, + 111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100, + 26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101, + 116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111, + 117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2, + 1,2,76,2,2,0,8,98,111,117,110,100,115,95,120,2,7,8,98,111, + 117,110,100,115,95,121,2,20,9,98,111,117,110,100,115,95,99,120,2,89, + 9,98,111,117,110,100,115,95,99,121,2,16,5,118,97,108,117,101,9,0, + 0,12,116,98,111,111,108,101,97,110,101,100,105,116,9,116,97,98,105,110, + 100,101,110,116,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,3, + 84,97,98,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,1,2,26,2,2,0,8,116,97,98,111,114,100,101,114,2,2, + 8,98,111,117,110,100,115,95,120,3,191,0,8,98,111,117,110,100,115,95, + 121,2,20,9,98,111,117,110,100,115,95,99,120,2,39,9,98,111,117,110, + 100,115,95,99,121,2,16,0,0,12,116,105,110,116,101,103,101,114,101,100, + 105,116,8,116,97,98,115,116,111,112,115,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,8,84,97,98,115,116,111,112,115,22,102,114,97,109, + 101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,9, + 116,102,95,98,111,116,116,111,109,0,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101, + 100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109, + 111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,17,2,24,2,0,0,8,116,97,98,111,114,100,101,114,2,3,8,98, + 111,117,110,100,115,95,120,3,247,0,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,2,60,9,98,111,117,110,100,115, + 95,99,121,2,37,5,118,97,108,117,101,2,4,8,118,97,108,117,101,109, + 105,110,2,1,8,118,97,108,117,101,109,97,120,2,50,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,12,116,98,111,111,108,101, + 97,110,101,100,105,116,8,115,104,111,119,116,97,98,115,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,9,83,104,111,119,32,116,97,98,115, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2, + 1,2,68,2,2,0,8,116,97,98,111,114,100,101,114,2,5,8,98,111, + 117,110,100,115,95,120,3,151,1,8,98,111,117,110,100,115,95,121,2,20, + 9,98,111,117,110,100,115,95,99,120,2,81,9,98,111,117,110,100,115,95, + 99,121,2,16,0,0,0,9,116,108,97,121,111,117,116,101,114,11,116,108, + 97,121,111,117,116,101,114,49,54,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,3,62,3,9,98,111,117,110,100,115,95,99,121,2,50,7,97,110,99, + 104,111,114,115,11,6,97,110,95,116,111,112,0,12,111,112,116,105,111,110, + 115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97,110,100,121,11, + 111,115,99,95,115,104,114,105,110,107,121,17,111,115,99,95,101,120,112,97, + 110,100,115,104,114,105,110,107,120,17,111,115,99,95,101,120,112,97,110,100, + 115,104,114,105,110,107,121,0,13,111,112,116,105,111,110,115,108,97,121,111, + 117,116,11,10,108,97,111,95,97,108,105,103,110,121,0,10,97,108,105,103, + 110,95,103,108,117,101,7,9,119,97,109,95,115,116,97,114,116,0,13,116, + 101,110,117,109,116,121,112,101,101,100,105,116,8,101,111,108,115,116,121,108, + 101,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,8,69,111,108, + 115,116,121,108,101,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116, + 101,120,116,102,108,97,103,115,11,9,116,102,95,98,111,116,116,111,109,0, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,19, + 102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2, + 1,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109, + 115,14,1,0,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101, + 114,2,2,4,104,105,110,116,6,65,69,110,100,32,111,102,32,108,105,110, + 101,32,115,116,121,108,101,32,102,111,114,32,119,114,105,116,105,110,103,46, + 32,101,111,108,95,100,101,102,97,117,108,116,32,45,62,32,117,115,101,32, + 111,114,105,103,105,110,97,108,32,115,116,121,108,101,46,8,98,111,117,110, + 100,115,95,120,3,247,0,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,120,2,116,9,98,111,117,110,100,115,95,99,121, + 2,37,5,118,97,108,117,101,2,1,8,118,97,108,117,101,109,105,110,2, + 0,8,118,97,108,117,101,109,97,120,2,3,19,100,114,111,112,100,111,119, + 110,46,99,111,108,115,46,99,111,117,110,116,2,1,19,100,114,111,112,100, + 111,119,110,46,99,111,108,115,46,105,116,101,109,115,14,1,0,0,6,111, + 110,105,110,105,116,7,15,105,110,105,116,101,111,108,115,116,121,108,101,101, + 120,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0, + 12,116,98,111,111,108,101,97,110,101,100,105,116,22,116,114,105,109,116,114, + 97,105,108,105,110,103,119,104,105,116,101,115,112,97,99,101,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,32,84,114,105,109,32,116,114,97, + 105,108,105,110,103,10,119,104,105,116,101,115,112,97,99,101,10,111,110,32, + 115,97,118,101,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101, + 1,2,0,2,15,2,76,2,16,0,8,98,111,117,110,100,115,95,120,2, + 7,8,98,111,117,110,100,115,95,121,2,6,9,98,111,117,110,100,115,95, + 99,120,2,89,9,98,111,117,110,100,115,95,99,121,2,44,0,0,9,116, + 101,110,117,109,101,100,105,116,8,101,110,99,111,100,105,110,103,13,102,114, + 97,109,101,46,99,97,112,116,105,111,110,6,8,69,110,99,111,100,105,110, + 103,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102, + 108,97,103,115,11,9,116,102,95,98,111,116,116,111,109,0,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97, + 98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97, + 99,116,105,118,101,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46, + 99,111,108,111,114,4,2,0,0,128,19,102,114,97,109,101,46,98,117,116, + 116,111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98, + 117,116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114, + 4,2,0,0,128,0,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114, + 100,101,114,2,1,8,98,111,117,110,100,115,95,120,3,151,0,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,92, + 9,98,111,117,110,100,115,95,99,121,2,37,16,100,114,111,112,100,111,119, + 110,46,111,112,116,105,111,110,115,11,14,100,101,111,95,115,101,108,101,99, + 116,111,110,108,121,15,100,101,111,95,102,111,114,99,101,115,101,108,101,99, + 116,16,100,101,111,95,97,117,116,111,100,114,111,112,100,111,119,110,15,100, + 101,111,95,107,101,121,100,114,111,112,100,111,119,110,0,19,100,114,111,112, + 100,111,119,110,46,99,111,108,115,46,99,111,117,110,116,2,1,19,100,114, + 111,112,100,111,119,110,46,99,111,108,115,46,105,116,101,109,115,14,1,4, + 100,97,116,97,1,6,6,76,111,99,97,108,101,6,4,117,116,102,56,6, + 9,105,115,111,56,56,53,57,45,49,0,0,0,5,118,97,108,117,101,2, + 0,10,111,110,115,101,116,118,97,108,117,101,7,16,101,110,99,111,100,105, + 110,103,115,101,116,118,97,108,117,101,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,14,0,0,12,116,105,110,116,101,103,101,114,101,100,105, + 116,15,98,97,99,107,117,112,102,105,108,101,99,111,117,110,116,13,102,114, + 97,109,101,46,99,97,112,116,105,111,110,6,17,66,97,99,107,117,112,32, + 102,105,108,101,32,99,111,117,110,116,22,102,114,97,109,101,46,99,97,112, + 116,105,111,110,116,101,120,116,102,108,97,103,115,11,9,116,102,95,98,111, + 116,116,111,109,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101, + 102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112, + 19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116, + 20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111, + 109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116, + 105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,16,102,114,97,109, + 101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,74,2, + 0,0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117,110,100,115, + 95,120,3,151,1,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,120,2,110,9,98,111,117,110,100,115,95,99,121,2,37, + 5,118,97,108,117,101,2,2,8,118,97,108,117,101,109,97,120,2,10,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,0,0, + 8,116,116,97,98,112,97,103,101,10,116,116,97,98,112,97,103,101,50,50, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8, + 116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2, + 0,8,98,111,117,110,100,115,95,121,2,19,9,98,111,117,110,100,115,95, + 99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,3,255,1,7,97, + 110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110,95,116, + 111,112,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116,116,111, + 109,0,7,99,97,112,116,105,111,110,6,4,70,111,114,109,0,12,116,98, + 111,111,108,101,97,110,101,100,105,116,14,99,111,109,112,111,110,101,110,116, + 104,105,110,116,115,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 15,67,111,109,112,111,110,101,110,116,32,104,105,110,116,115,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97, + 98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97, + 99,116,105,118,101,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,1,2,110,2,2,0,8,116,97,98,111,114,100, + 101,114,2,6,8,98,111,117,110,100,115,95,120,3,255,1,8,98,111,117, + 110,100,115,95,121,2,18,9,98,111,117,110,100,115,95,99,120,2,123,9, + 98,111,117,110,100,115,95,99,121,2,16,0,0,12,116,98,111,111,108,101, + 97,110,101,100,105,116,21,110,111,102,111,114,109,100,101,115,105,103,110,101, + 114,100,111,99,107,105,110,103,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,7,68,111,99,107,105,110,103,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107, + 101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101, + 0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2, + 0,2,1,2,53,2,2,0,8,116,97,98,111,114,100,101,114,2,4,8, + 98,111,117,110,100,115,95,120,3,103,1,8,98,111,117,110,100,115,95,121, + 2,18,9,98,111,117,110,100,115,95,99,120,2,66,9,98,111,117,110,100, + 115,95,99,121,2,16,7,111,112,116,105,111,110,115,11,17,98,111,95,101, + 120,101,99,117,116,101,111,110,99,108,105,99,107,15,98,111,95,101,120,101, + 99,117,116,101,111,110,107,101,121,20,98,111,95,101,120,101,99,117,116,101, + 111,110,115,104,111,114,116,99,117,116,27,98,111,95,101,120,101,99,117,116, + 101,100,101,102,97,117,108,116,111,110,101,110,116,101,114,107,101,121,11,98, + 111,95,114,101,118,101,114,115,101,100,0,0,0,12,116,98,111,111,108,101, + 97,110,101,100,105,116,16,109,111,118,101,111,110,102,105,114,115,116,99,108, + 105,99,107,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,19,77, + 111,118,101,32,111,110,32,102,105,114,115,116,32,99,108,105,99,107,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115, + 101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105, + 115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100, + 26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,97,99,116,105,118,101,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,1,2,114,2,2,0,8,116,97,98,111, + 114,100,101,114,2,5,8,98,111,117,110,100,115,95,120,3,103,1,8,98, + 111,117,110,100,115,95,121,2,42,9,98,111,117,110,100,115,95,99,120,2, + 127,9,98,111,117,110,100,115,95,99,121,2,16,5,118,97,108,117,101,9, + 0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,9,103,114,105,100, + 115,105,122,101,121,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 11,71,114,105,100,32,115,105,122,101,32,89,22,102,114,97,109,101,46,99, + 97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,9,116,102,95, + 98,111,116,116,111,109,0,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116, + 111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103, + 104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116, + 116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97, + 99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115, + 101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2, + 29,2,0,0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117,110, + 100,115,95,120,3,247,0,8,98,111,117,110,100,115,95,121,2,18,9,98, + 111,117,110,100,115,95,99,120,2,65,9,98,111,117,110,100,115,95,99,121, + 2,37,5,118,97,108,117,101,2,8,8,118,97,108,117,101,109,105,110,2, + 1,8,118,97,108,117,101,109,97,120,3,232,3,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,14,0,0,12,116,105,110,116,101,103,101,114, + 101,100,105,116,9,103,114,105,100,115,105,122,101,120,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,11,71,114,105,100,32,115,105,122,101,32, + 88,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102, + 108,97,103,115,11,9,116,102,95,98,111,116,116,111,109,0,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97, + 98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97, + 99,116,105,118,101,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,17,2,29,2,0,0,8,116,97,98,111,114,100, + 101,114,2,2,8,98,111,117,110,100,115,95,120,3,151,0,8,98,111,117, + 110,100,115,95,121,2,18,9,98,111,117,110,100,115,95,99,120,2,65,9, + 98,111,117,110,100,115,95,99,121,2,37,5,118,97,108,117,101,2,8,8, + 118,97,108,117,101,109,105,110,2,1,8,118,97,108,117,101,109,97,120,3, + 232,3,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,12, + 116,105,110,116,101,103,101,114,101,100,105,116,13,116,105,110,116,101,103,101, + 114,101,100,105,116,50,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,11,71,114,105,100,32,115,105,122,101,32,88,22,102,114,97,109,101,46, + 99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,9,116,102, + 95,98,111,116,116,111,109,0,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105, + 103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111, + 116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117, + 115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17, + 2,29,2,0,0,8,98,111,117,110,100,115,95,120,3,136,0,8,98,111, + 117,110,100,115,95,121,2,29,9,98,111,117,110,100,115,95,99,120,2,65, + 9,98,111,117,110,100,115,95,99,121,2,37,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,14,0,0,0,12,116,98,111,111,108,101,97,110, + 101,100,105,116,10,115,110,97,112,116,111,103,114,105,100,13,111,112,116,105, + 111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102, + 111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95, + 97,114,114,111,119,102,111,99,117,115,17,111,119,95,100,101,115,116,114,111, + 121,119,105,100,103,101,116,115,9,111,119,95,104,105,110,116,111,110,0,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,12,83,110,97,112,32, + 116,111,32,71,114,105,100,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116, + 111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103, + 104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116, + 116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97, + 99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115, + 101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,2, + 81,2,2,0,8,116,97,98,111,114,100,101,114,2,1,4,104,105,110,116, + 6,146,72,105,110,116,58,10,85,115,101,32,67,116,114,108,32,43,32,97, + 114,114,111,119,32,107,101,121,115,32,116,111,32,109,111,118,101,32,115,101, + 108,101,99,116,101,100,32,99,111,109,112,111,110,101,110,116,115,32,119,105, + 116,104,111,117,116,32,103,114,105,100,32,115,110,97,112,44,10,117,115,101, + 32,83,104,105,102,116,32,43,32,97,114,114,111,119,32,107,101,121,115,32, + 116,111,32,114,101,115,105,122,101,32,115,101,108,101,99,116,101,100,32,99, + 111,109,112,111,110,101,110,116,115,32,119,105,116,104,111,117,116,32,103,114, + 105,100,32,115,110,97,112,46,8,98,111,117,110,100,115,95,120,2,7,8, + 98,111,117,110,100,115,95,121,2,42,9,98,111,117,110,100,115,95,99,120, + 2,94,9,98,111,117,110,100,115,95,99,121,2,16,5,118,97,108,117,101, + 9,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,8,115,104,111, + 119,103,114,105,100,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 9,83,104,111,119,32,71,114,105,100,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101, + 100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109, + 111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,1,2,65,2,2,0,8,98,111,117,110,100,115,95,120,2,7,8,98, + 111,117,110,100,115,95,121,2,18,9,98,111,117,110,100,115,95,99,120,2, + 78,9,98,111,117,110,100,115,95,99,121,2,16,5,118,97,108,117,101,9, + 0,0,0,0,0,8,116,116,97,98,112,97,103,101,12,100,101,98,117,103, + 103,101,114,112,97,103,101,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95, + 116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111, + 119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115, + 117,98,102,111,99,117,115,13,111,119,95,109,111,117,115,101,119,104,101,101, + 108,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111, + 117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107, + 101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,97,99,116,105,118,101,0,8,116,97,98,111,114,100,101,114,2, + 4,8,98,111,117,110,100,115,95,120,2,1,8,98,111,117,110,100,115,95, + 121,2,20,9,98,111,117,110,100,115,95,99,120,3,62,3,9,98,111,117, + 110,100,115,95,99,121,3,18,2,7,97,110,99,104,111,114,115,11,7,97, + 110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,9,97,110,95,98,111,116,116,111,109,0,7,99,97,112,116,105,111, + 110,6,9,38,68,101,98,117,103,103,101,114,8,111,110,108,97,121,111,117, + 116,7,17,100,101,98,117,103,103,101,114,108,97,121,111,117,116,101,120,101, + 0,13,116,102,105,108,101,110,97,109,101,101,100,105,116,12,100,101,98,117, + 103,99,111,109,109,97,110,100,13,111,112,116,105,111,110,115,119,105,100,103, + 101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119, + 95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111, + 99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16, + 111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,13,102,114,97,109, + 101,46,111,112,116,105,111,110,115,11,10,99,102,111,95,102,105,120,116,111, + 112,0,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,14,38,68, + 101,98,117,103,32,99,111,109,109,97,110,100,22,102,114,97,109,101,46,99, + 97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,9,116,102,95, + 98,111,116,116,111,109,0,19,102,114,97,109,101,46,99,97,112,116,105,111, + 110,111,102,102,115,101,116,2,3,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114, + 105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98, + 111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100, + 26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101, + 116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111, + 117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,19, + 102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2, + 1,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109, + 115,14,1,5,99,111,108,111,114,4,2,0,0,128,7,105,109,97,103,101, + 110,114,2,17,0,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46, + 99,111,108,111,114,4,2,0,0,128,20,102,114,97,109,101,46,98,117,116, + 116,111,110,46,105,109,97,103,101,110,114,2,17,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0, + 8,116,97,98,111,114,100,101,114,2,1,10,111,110,115,104,111,119,104,105, + 110,116,7,18,104,105,110,116,101,120,112,97,110,100,101,100,109,97,99,114, + 111,115,8,98,111,117,110,100,115,95,120,2,1,8,98,111,117,110,100,115, + 95,121,2,57,9,98,111,117,110,100,115,95,99,120,3,46,1,9,98,111, + 117,110,100,115,95,99,121,2,37,7,97,110,99,104,111,114,115,11,7,97, + 110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,0,18,99,111,110,116,114,111,108,108,101,114,46,111,112,116,105,111, + 110,115,11,15,102,100,111,95,113,117,111,116,101,115,105,110,103,108,101,0, + 26,99,111,110,116,114,111,108,108,101,114,46,104,105,115,116,111,114,121,109, + 97,120,99,111,117,110,116,2,0,24,99,111,110,116,114,111,108,108,101,114, + 46,111,110,103,101,116,102,105,108,101,110,97,109,101,7,14,101,120,112,97, + 110,100,102,105,108,101,110,97,109,101,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,14,0,0,15,116,109,101,109,111,100,105,97,108,111,103, + 101,100,105,116,12,100,101,98,117,103,111,112,116,105,111,110,115,13,102,114, + 97,109,101,46,111,112,116,105,111,110,115,11,10,99,102,111,95,102,105,120, + 116,111,112,0,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,14, + 68,101,98,117,103,32,38,111,112,116,105,111,110,115,22,102,114,97,109,101, + 46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,9,116, + 102,95,98,111,116,116,111,109,0,19,102,114,97,109,101,46,99,97,112,116, + 105,111,110,111,102,102,115,101,116,2,3,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107, + 101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101, + 0,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110, + 116,2,1,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116, + 101,109,115,14,1,7,105,109,97,103,101,110,114,2,17,0,0,20,102,114, + 97,109,101,46,98,117,116,116,111,110,46,105,109,97,103,101,110,114,2,17, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,2,4,104, + 105,110,116,6,37,34,45,45,116,116,121,32,68,69,86,73,67,69,34,32, + 116,111,32,115,101,116,32,116,97,114,103,101,116,32,116,101,114,109,105,110, + 97,108,10,111,110,115,104,111,119,104,105,110,116,7,18,104,105,110,116,101, + 120,112,97,110,100,101,100,109,97,99,114,111,115,8,98,111,117,110,100,115, + 95,120,3,50,1,8,98,111,117,110,100,115,95,121,2,57,9,98,111,117, + 110,100,115,95,99,120,3,11,2,9,98,111,117,110,100,115,95,99,121,2, + 37,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97, + 110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,10,116,116,97,98,119,105, + 100,103,101,116,11,116,116,97,98,119,105,100,103,101,116,49,13,111,112,116, + 105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101, + 102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119, + 95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119, + 102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117, + 115,111,117,116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,14,111,112,116,105, + 111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116, + 103,108,121,112,104,104,101,105,103,104,116,0,8,98,111,117,110,100,115,95, + 120,2,0,8,98,111,117,110,100,115,95,121,3,204,0,9,98,111,117,110, + 100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,3,70, + 1,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97, + 110,95,116,111,112,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111, + 116,116,111,109,0,8,116,97,98,111,114,100,101,114,2,6,15,97,99,116, + 105,118,101,112,97,103,101,105,110,100,101,120,2,0,20,116,97,98,95,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115, + 101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,15,102,114,108, + 95,111,112,116,105,111,110,115,115,107,105,110,0,21,116,97,98,95,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105, + 115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100, + 26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,97,99,116,105,118,101,0,19,116,97,98,95,102,97,99,101,46,108,111, + 99,97,108,112,114,111,112,115,11,20,102,97,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,0,9,116,97,98,95,99,111,108,111, + 114,4,3,0,0,128,8,116,97,98,95,115,105,122,101,2,19,8,115,116, + 97,116,102,105,108,101,7,9,115,116,97,116,102,105,108,101,49,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,8,116,116,97,98,112, + 97,103,101,9,116,116,97,98,112,97,103,101,54,14,111,112,116,105,111,110, + 115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108, + 121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99, + 97,108,101,0,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13, + 111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98, + 102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15, + 111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97, + 114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102, + 111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,0,5,99,111,108,111,114,4,3,0,0,128,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108, + 105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108, + 101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116, + 105,118,101,0,8,116,97,98,111,114,100,101,114,2,4,8,98,111,117,110, + 100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,19,9,98,111, + 117,110,100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121, + 3,51,1,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116, + 6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,9,97,110,95, + 98,111,116,116,111,109,0,7,99,97,112,116,105,111,110,6,19,83,111,117, + 114,99,101,32,38,100,105,114,101,99,116,111,114,105,101,115,13,114,101,102, + 102,111,110,116,104,101,105,103,104,116,2,14,0,11,116,119,105,100,103,101, + 116,103,114,105,100,13,115,111,117,114,99,101,100,105,114,103,114,105,100,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111, + 117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114, + 114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102, + 111,99,117,115,111,117,116,17,111,119,95,102,111,99,117,115,98,97,99,107, + 111,110,101,115,99,13,111,119,95,109,111,117,115,101,119,104,101,101,108,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,5,99, + 111,108,111,114,4,3,0,0,128,19,102,114,97,109,101,46,99,97,112,116, + 105,111,110,111,102,102,115,101,116,2,3,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107, + 101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101, + 0,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95, + 121,2,24,9,98,111,117,110,100,115,95,99,120,3,62,3,9,98,111,117, + 110,100,115,95,99,121,3,27,1,12,98,111,117,110,100,115,95,99,121,109, + 105,110,2,40,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112, + 9,97,110,95,98,111,116,116,111,109,0,11,111,112,116,105,111,110,115,103, + 114,105,100,11,12,111,103,95,114,111,119,109,111,118,105,110,103,15,111,103, + 95,107,101,121,114,111,119,109,111,118,105,110,103,15,111,103,95,114,111,119, + 105,110,115,101,114,116,105,110,103,14,111,103,95,114,111,119,100,101,108,101, + 116,105,110,103,23,111,103,95,115,101,108,101,99,116,101,100,114,111,119,115, + 100,101,108,101,116,105,110,103,19,111,103,95,102,111,99,117,115,99,101,108, + 108,111,110,101,110,116,101,114,15,111,103,95,97,117,116,111,102,105,114,115, + 116,114,111,119,13,111,103,95,97,117,116,111,97,112,112,101,110,100,10,111, + 103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112, + 117,112,0,14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,1, + 16,100,97,116,97,99,111,108,115,46,111,112,116,105,111,110,115,11,12,99, + 111,95,100,114,97,119,102,111,99,117,115,14,99,111,95,102,111,99,117,115, + 115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99, + 116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117, + 108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101, + 99,116,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99, + 97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99, + 111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,14,100,97, + 116,97,99,111,108,115,46,105,116,101,109,115,14,7,10,115,111,117,114,99, + 101,100,105,114,115,1,12,108,105,110,101,99,111,108,111,114,102,105,120,4, + 3,0,0,160,5,119,105,100,116,104,3,57,3,7,111,112,116,105,111,110, + 115,11,12,99,111,95,100,114,97,119,102,111,99,117,115,14,99,111,95,102, + 111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115, + 101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99, + 111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119, + 115,101,108,101,99,116,7,99,111,95,102,105,108,108,12,99,111,95,115,97, + 118,101,118,97,108,117,101,10,99,111,95,99,97,110,99,111,112,121,11,99, + 111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115, + 99,114,111,108,108,114,111,119,0,10,111,110,115,104,111,119,104,105,110,116, + 7,13,99,111,108,111,110,115,104,111,119,104,105,110,116,10,119,105,100,103, + 101,116,110,97,109,101,6,10,115,111,117,114,99,101,100,105,114,115,9,100, + 97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116, + 114,105,110,103,100,97,116,97,108,105,115,116,0,0,13,100,97,116,97,114, + 111,119,104,101,105,103,104,116,2,16,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,14,0,13,116,102,105,108,101,110,97,109,101,101,100,105, + 116,10,115,111,117,114,99,101,100,105,114,115,13,111,112,116,105,111,110,115, + 119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117, + 115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114, + 111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117, + 115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116, + 17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,11, + 111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97, + 109,101,98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46, + 108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114, + 99,108,105,101,110,116,4,2,0,0,128,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111, + 15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105, + 115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100, + 26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,97,99,116,105,118,101,0,19,102,114,97,109,101,46,98,117,116,116,111, + 110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116, + 116,111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4,5, + 0,0,144,7,105,109,97,103,101,110,114,2,17,0,0,18,102,114,97,109, + 101,46,98,117,116,116,111,110,46,99,111,108,111,114,4,5,0,0,144,20, + 102,114,97,109,101,46,98,117,116,116,111,110,46,105,109,97,103,101,110,114, + 2,17,8,116,97,98,111,114,100,101,114,2,1,10,111,110,115,104,111,119, + 104,105,110,116,7,18,104,105,110,116,101,120,112,97,110,100,101,100,109,97, + 99,114,111,115,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115, + 95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,120,3,57,3,9,98,111,117,110,100,115,95,99,121,2,16, + 12,111,112,116,105,111,110,115,101,100,105,116,49,11,13,111,101,49,95,115, + 97,118,101,118,97,108,117,101,0,11,111,112,116,105,111,110,115,101,100,105, + 116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99, + 108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114, + 99,97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117,114,110,20, + 111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116, + 15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95, + 101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101, + 108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110, + 102,105,114,115,116,99,108,105,99,107,0,18,99,111,110,116,114,111,108,108, + 101,114,46,105,110,99,108,117,100,101,11,6,102,97,95,100,105,114,6,102, + 97,95,97,108,108,0,18,99,111,110,116,114,111,108,108,101,114,46,111,112, + 116,105,111,110,115,11,13,102,100,111,95,100,105,114,101,99,116,111,114,121, + 0,26,99,111,110,116,114,111,108,108,101,114,46,104,105,115,116,111,114,121, + 109,97,120,99,111,117,110,116,2,0,22,99,111,110,116,114,111,108,108,101, + 114,46,99,97,112,116,105,111,110,111,112,101,110,6,23,83,101,108,101,99, + 116,32,115,111,117,114,99,101,32,100,105,114,101,99,116,111,114,121,24,99, + 111,110,116,114,111,108,108,101,114,46,111,110,103,101,116,102,105,108,101,110, + 97,109,101,7,14,101,120,112,97,110,100,102,105,108,101,110,97,109,101,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,13,116, + 102,105,108,101,110,97,109,101,101,100,105,116,10,115,111,117,114,99,101,98, + 97,115,101,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,47,79, + 98,106,101,99,116,32,38,66,97,115,101,32,68,105,114,101,99,116,111,114, + 121,32,40,101,109,112,116,121,32,61,32,77,97,107,101,32,68,105,114,101, + 99,116,111,114,121,41,22,102,114,97,109,101,46,99,97,112,116,105,111,110, + 116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101,110,116,101, + 114,101,100,0,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111, + 115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,19,102,114,97,109,101,46,98,117,116, + 116,111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98, + 117,116,116,111,110,115,46,105,116,101,109,115,14,1,7,105,109,97,103,101, + 110,114,2,17,0,0,20,102,114,97,109,101,46,98,117,116,116,111,110,46, + 105,109,97,103,101,110,114,2,17,16,102,114,97,109,101,46,111,117,116,101, + 114,102,114,97,109,101,1,2,0,2,0,3,45,1,2,0,0,8,116,97, + 98,111,114,100,101,114,2,1,10,111,110,115,104,111,119,104,105,110,116,7, + 13,115,111,117,114,99,101,100,105,114,104,105,110,116,8,98,111,117,110,100, + 115,95,120,2,1,8,98,111,117,110,100,115,95,121,2,2,9,98,111,117, + 110,100,115,95,99,120,3,59,3,7,97,110,99,104,111,114,115,11,7,97, + 110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,0,9,116,101,120,116,102,108,97,103,115,11,11,116,102,95,110,111, + 115,101,108,101,99,116,14,116,102,95,101,108,108,105,112,115,101,108,101,102, + 116,0,18,99,111,110,116,114,111,108,108,101,114,46,111,112,116,105,111,110, + 115,11,13,102,100,111,95,100,105,114,101,99,116,111,114,121,0,22,99,111, + 110,116,114,111,108,108,101,114,46,99,97,112,116,105,111,110,111,112,101,110, + 6,28,83,101,108,101,99,116,32,115,111,117,114,99,101,32,98,97,115,101, + 32,100,105,114,101,99,116,111,114,121,24,99,111,110,116,114,111,108,108,101, + 114,46,111,110,103,101,116,102,105,108,101,110,97,109,101,7,14,101,120,112, + 97,110,100,102,105,108,101,110,97,109,101,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,0,7,116,115,112,97,99,101,114,8,116,115, + 112,97,99,101,114,55,8,116,97,98,111,114,100,101,114,2,2,8,98,111, + 117,110,100,115,95,120,3,15,2,8,98,111,117,110,100,115,95,121,2,22, + 9,98,111,117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95, + 99,121,2,2,7,108,105,110,107,116,111,112,7,10,115,111,117,114,99,101, + 98,97,115,101,10,108,105,110,107,98,111,116,116,111,109,7,13,115,111,117, + 114,99,101,100,105,114,103,114,105,100,0,0,0,8,116,116,97,98,112,97, + 103,101,9,116,116,97,98,112,97,103,101,57,14,111,112,116,105,111,110,115, + 119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121, + 112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99,97, + 108,101,0,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111, + 99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116, + 115,0,5,99,111,108,111,114,4,3,0,0,128,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105, + 99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101, + 100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105, + 118,101,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100, + 115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,19,9,98,111,117, + 110,100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,3, + 51,1,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6, + 97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,9,97,110,95,98, + 111,116,116,111,109,0,7,99,97,112,116,105,111,110,6,8,68,101,102,105, + 38,110,101,115,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,11,116,119,105,100,103,101,116,103,114,105,100,12,116,119,105,100,103,101, + 116,103,114,105,100,50,5,99,111,108,111,114,4,3,0,0,128,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101, + 27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101, + 116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115, + 97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 97,99,116,105,118,101,0,8,98,111,117,110,100,115,95,120,2,0,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3, + 62,3,9,98,111,117,110,100,115,95,99,121,3,51,1,7,97,110,99,104, + 111,114,115,11,0,11,111,112,116,105,111,110,115,103,114,105,100,11,15,111, + 103,95,107,101,121,114,111,119,109,111,118,105,110,103,15,111,103,95,114,111, + 119,105,110,115,101,114,116,105,110,103,14,111,103,95,114,111,119,100,101,108, + 101,116,105,110,103,19,111,103,95,102,111,99,117,115,99,101,108,108,111,110, + 101,110,116,101,114,15,111,103,95,97,117,116,111,102,105,114,115,116,114,111, + 119,13,111,103,95,97,117,116,111,97,112,112,101,110,100,20,111,103,95,99, + 111,108,99,104,97,110,103,101,111,110,116,97,98,107,101,121,10,111,103,95, + 119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112,117,112, + 0,13,102,105,120,114,111,119,115,46,99,111,117,110,116,2,1,13,102,105, + 120,114,111,119,115,46,105,116,101,109,115,14,1,6,104,101,105,103,104,116, + 2,16,14,99,97,112,116,105,111,110,115,46,99,111,117,110,116,2,2,14, + 99,97,112,116,105,111,110,115,46,105,116,101,109,115,14,1,7,99,97,112, + 116,105,111,110,6,2,111,110,0,1,7,99,97,112,116,105,111,110,6,36, + 83,112,97,99,101,32,115,101,112,97,114,97,116,101,100,32,100,101,102,105, + 110,101,115,32,102,111,114,32,123,36,105,102,100,101,102,125,0,0,0,0, + 14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,2,16,100,97, + 116,97,99,111,108,115,46,111,112,116,105,111,110,115,11,12,99,111,95,100, + 114,97,119,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108, + 101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99, + 111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105, + 115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12, + 99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99, + 111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109, + 111,117,115,101,115,99,114,111,108,108,114,111,119,0,14,100,97,116,97,99, + 111,108,115,46,105,116,101,109,115,14,7,9,100,101,102,105,110,101,115,111, + 110,1,5,119,105,100,116,104,2,22,7,111,112,116,105,111,110,115,11,12, + 99,111,95,100,114,97,119,102,111,99,117,115,14,99,111,95,102,111,99,117, + 115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101, + 99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109, + 117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108, + 101,99,116,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95, + 99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17, + 99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119, + 105,100,103,101,116,110,97,109,101,6,9,100,101,102,105,110,101,115,111,110, + 9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100,105,110,116, + 101,103,101,114,100,97,116,97,108,105,115,116,0,7,7,100,101,102,105,110, + 101,115,1,5,119,105,100,116,104,3,34,3,7,111,112,116,105,111,110,115, + 11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95, + 109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101, + 108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12, + 99,111,95,114,111,119,115,101,108,101,99,116,7,99,111,95,102,105,108,108, + 12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110, + 99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95, + 109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,111,110,115,104, + 111,119,104,105,110,116,7,13,99,111,108,111,110,115,104,111,119,104,105,110, + 116,10,119,105,100,103,101,116,110,97,109,101,6,7,100,101,102,105,110,101, + 115,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115, + 101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,0,13,100,97, + 116,97,114,111,119,104,101,105,103,104,116,2,16,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,14,0,12,116,98,111,111,108,101,97,110,101, + 100,105,116,9,100,101,102,105,110,101,115,111,110,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,13,111,119,95,109,111,117,115,101,119,104,101, + 101,108,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102, + 114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109, + 101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108, + 111,114,99,108,105,101,110,116,4,3,0,0,128,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101, + 108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107, + 101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,97,99,116,105,118,101,0,8,116,97,98,111,114,100,101,114,2, + 1,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,120,2,22,9,98,111,117,110, + 100,115,95,99,121,2,16,11,111,112,116,105,111,110,115,101,100,105,116,11, + 12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111, + 115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97, + 110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12, + 111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101, + 116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105, + 116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110, + 116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101, + 95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108, + 105,99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111, + 101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49, + 95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101, + 115,116,97,116,101,27,111,101,49,95,99,104,101,99,107,118,97,108,117,101, + 97,102,116,101,114,115,116,97,116,114,101,97,100,0,7,118,105,115,105,98, + 108,101,8,12,118,97,108,117,101,100,101,102,97,117,108,116,9,0,0,11, + 116,115,116,114,105,110,103,101,100,105,116,7,100,101,102,105,110,101,115,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111, + 117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,13,111,119,95,109,111, + 117,115,101,119,104,101,101,108,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,0,11,111,112,116,105,111,110,115,115,107,105,110,11, + 19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121, + 0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97, + 109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101, + 27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,8,116,97,98, + 111,114,100,101,114,2,2,7,118,105,115,105,98,108,101,8,8,98,111,117, + 110,100,115,95,120,2,23,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,120,3,34,3,9,98,111,117,110,100,115,95,99, + 121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,0,11,111, + 112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111, + 110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111, + 101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115, + 104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116, + 117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110, + 101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114, + 13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117, + 116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101, + 99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,0,0,8,116,116,97,98, + 112,97,103,101,9,116,116,97,98,112,97,103,101,55,14,111,112,116,105,111, + 110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103, + 108,121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115, + 99,97,108,101,0,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98, + 102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,5,99,111,108,111,114,4,3,0,0,128,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99, + 108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98, + 108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99, + 116,105,118,101,0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117, + 110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,19,9,98, + 111,117,110,100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95,99, + 121,3,51,1,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102, + 116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,9,97,110, + 95,98,111,116,116,111,109,0,7,99,97,112,116,105,111,110,6,8,38,83, + 105,103,110,97,108,115,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,11,116,119,105,100,103,101,116,103,114,105,100,10,115,105,103,110, + 97,108,103,114,105,100,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119, + 95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,102,111, + 99,117,115,98,97,99,107,111,110,101,115,99,13,111,119,95,109,111,117,115, + 101,119,104,101,101,108,17,111,119,95,100,101,115,116,114,111,121,119,105,100, + 103,101,116,115,0,5,99,111,108,111,114,4,3,0,0,128,19,102,114,97, + 109,101,46,99,97,112,116,105,111,110,111,102,102,115,101,116,2,3,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115, + 101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105, + 115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100, + 26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,97,99,116,105,118,101,0,8,98,111,117,110,100,115,95,120,2,0,8, + 98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120, + 3,62,3,9,98,111,117,110,100,115,95,99,121,3,51,1,12,98,111,117, + 110,100,115,95,99,121,109,105,110,2,40,7,97,110,99,104,111,114,115,11, + 0,11,111,112,116,105,111,110,115,103,114,105,100,11,12,111,103,95,99,111, + 108,115,105,122,105,110,103,15,111,103,95,114,111,119,105,110,115,101,114,116, + 105,110,103,14,111,103,95,114,111,119,100,101,108,101,116,105,110,103,19,111, + 103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101,114,15,111, + 103,95,97,117,116,111,102,105,114,115,116,114,111,119,13,111,103,95,97,117, + 116,111,97,112,112,101,110,100,9,111,103,95,115,111,114,116,101,100,10,111, + 103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112, + 117,112,0,13,102,105,120,114,111,119,115,46,99,111,117,110,116,2,1,13, + 102,105,120,114,111,119,115,46,105,116,101,109,115,14,1,6,104,101,105,103, + 104,116,2,16,14,99,97,112,116,105,111,110,115,46,99,111,117,110,116,2, + 5,14,99,97,112,116,105,111,110,115,46,105,116,101,109,115,14,1,7,99, + 97,112,116,105,111,110,6,4,83,116,111,112,0,1,7,99,97,112,116,105, + 111,110,6,6,72,97,110,100,108,101,0,1,7,99,97,112,116,105,111,110, + 6,6,83,105,103,110,117,109,0,1,7,99,97,112,116,105,111,110,6,5, + 46,46,32,116,111,0,1,7,99,97,112,116,105,111,110,6,4,78,97,109, + 101,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101,110, + 116,101,114,101,100,0,0,0,0,0,14,100,97,116,97,99,111,108,115,46, + 99,111,117,110,116,2,5,16,100,97,116,97,99,111,108,115,46,111,112,116, + 105,111,110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116, + 14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107, + 101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108, + 101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111,95, + 115,97,118,101,115,116,97,116,101,9,99,111,95,110,111,115,111,114,116,10, + 99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115, + 116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119, + 0,14,100,97,116,97,99,111,108,115,46,105,116,101,109,115,14,7,7,115, + 105,103,115,116,111,112,1,5,119,105,100,116,104,2,32,7,111,112,116,105, + 111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117,115,14,99,111, + 95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115, + 101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116, + 14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114, + 111,119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116,97,116, + 101,9,99,111,95,110,111,115,111,114,116,10,99,111,95,99,97,110,99,111, + 112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111, + 117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116, + 110,97,109,101,6,7,115,105,103,115,116,111,112,9,100,97,116,97,99,108, + 97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116, + 97,108,105,115,116,0,7,9,115,105,103,104,97,110,100,108,101,1,5,119, + 105,100,116,104,2,43,7,111,112,116,105,111,110,115,11,12,99,111,95,100, + 114,97,119,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108, + 101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99, + 111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105, + 115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12, + 99,111,95,115,97,118,101,115,116,97,116,101,9,99,111,95,110,111,115,111, + 114,116,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110, + 112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108, + 114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,9,115,105,103, + 104,97,110,100,108,101,9,100,97,116,97,99,108,97,115,115,7,20,116,103, + 114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,7, + 6,115,105,103,110,117,109,1,7,111,112,116,105,111,110,115,11,14,99,111, + 95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115, + 101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116, + 14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114, + 111,119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,118,97,108,117, + 101,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97, + 110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111, + 95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100, + 103,101,116,110,97,109,101,6,6,115,105,103,110,117,109,9,100,97,116,97, + 99,108,97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100, + 97,116,97,108,105,115,116,0,7,8,115,105,103,110,117,109,116,111,1,5, + 119,105,100,116,104,2,39,7,111,112,116,105,111,110,115,11,14,99,111,95, + 102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101, + 115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14, + 99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111, + 119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,118,97,108,117,101, + 12,99,111,95,115,97,118,101,115,116,97,116,101,9,99,111,95,110,111,115, + 111,114,116,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97, + 110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108, + 108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,8,115,105, + 103,110,117,109,116,111,9,100,97,116,97,99,108,97,115,115,7,20,116,103, + 114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,7, + 7,115,105,103,110,97,109,101,1,5,119,105,100,116,104,3,145,2,7,111, + 112,116,105,111,110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101, + 99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111, + 95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115, + 101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,7,99, + 111,95,102,105,108,108,12,99,111,95,115,97,118,101,118,97,108,117,101,12, + 99,111,95,115,97,118,101,115,116,97,116,101,9,99,111,95,110,111,115,111, + 114,116,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110, + 112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108, + 114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,7,115,105,103, + 110,97,109,101,9,100,97,116,97,99,108,97,115,115,7,17,116,103,114,105, + 100,101,110,117,109,100,97,116,97,108,105,115,116,0,0,13,100,97,116,97, + 114,111,119,104,101,105,103,104,116,2,16,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,12,116,98,111,111,108,101,97,110,101,100,105, + 116,7,115,105,103,115,116,111,112,14,111,112,116,105,111,110,115,119,105,100, + 103,101,116,49,11,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19, + 111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0, + 8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,2,32,9,98,111,117,110,100,115,95,99,121,2,16,11,111,112, + 116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110, + 101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101, + 95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101,97, + 116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101, + 99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117, + 114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111, + 101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111, + 115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,12, + 111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117, + 116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101, + 120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101, + 0,7,118,105,115,105,98,108,101,8,5,118,97,108,117,101,9,12,118,97, + 108,117,101,100,101,102,97,117,108,116,9,0,0,12,116,98,111,111,108,101, + 97,110,101,100,105,116,9,115,105,103,104,97,110,100,108,101,14,111,112,116, + 105,111,110,115,119,105,100,103,101,116,49,11,0,11,111,112,116,105,111,110, + 115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116, + 111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,2,8,98, + 111,117,110,100,115,95,120,2,33,8,98,111,117,110,100,115,95,121,2,0, + 9,98,111,117,110,100,115,95,99,120,2,43,9,98,111,117,110,100,115,95, + 99,121,2,16,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101, + 95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113, + 117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101, + 108,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101, + 115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101, + 120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110, + 101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25, + 111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116, + 99,108,105,99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11, + 17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111, + 101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97, + 118,101,115,116,97,116,101,0,7,118,105,115,105,98,108,101,8,0,0,12, + 116,105,110,116,101,103,101,114,101,100,105,116,6,115,105,103,110,117,109,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111, + 117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114, + 114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102, + 111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19, + 111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0, + 8,116,97,98,111,114,100,101,114,2,3,7,118,105,115,105,98,108,101,8, + 8,98,111,117,110,100,115,95,120,2,77,8,98,111,117,110,100,115,95,121, + 2,0,9,98,111,117,110,100,115,95,99,120,2,50,9,98,111,117,110,100, + 115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11, + 13,111,101,49,95,115,97,118,101,118,97,108,117,101,0,10,111,110,115,101, + 116,118,97,108,117,101,7,16,115,105,103,110,117,109,111,110,115,101,116,118, + 97,108,117,101,8,118,97,108,117,101,109,97,120,3,255,0,13,114,101,102, + 102,111,110,116,104,101,105,103,104,116,2,14,0,0,12,116,105,110,116,101, + 103,101,114,101,100,105,116,8,115,105,103,110,117,109,116,111,14,111,112,116, + 105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110, + 116,103,108,121,112,104,104,101,105,103,104,116,0,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114, + 97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114, + 100,101,114,2,4,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100, + 115,95,120,3,128,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,120,2,39,9,98,111,117,110,100,115,95,99,121,2, + 16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,13,111,101,49,95, + 115,97,118,101,118,97,108,117,101,0,10,111,110,115,101,116,118,97,108,117, + 101,7,18,115,105,103,110,117,109,116,111,111,110,115,101,116,118,97,108,117, + 101,8,118,97,108,117,101,109,97,120,3,255,0,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,14,0,0,9,116,115,101,108,101,99,116,111, + 114,7,115,105,103,110,97,109,101,14,111,112,116,105,111,110,115,119,105,100, + 103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104, + 101,105,103,104,116,0,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119, + 95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,0,11,111,112,116,105,111,110, + 115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116, + 111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101,118,101,108,111, + 2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116, + 4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99, + 111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100, + 25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118, + 101,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111, + 114,4,5,0,0,144,19,102,114,97,109,101,46,98,117,116,116,111,110,115, + 46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116,116,111, + 110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4,5,0,0, + 144,0,0,8,116,97,98,111,114,100,101,114,2,5,7,118,105,115,105,98, + 108,101,8,8,98,111,117,110,100,115,95,120,3,168,0,8,98,111,117,110, + 100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,145,2,9, + 98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101, + 100,105,116,49,11,13,111,101,49,95,115,97,118,101,118,97,108,117,101,0, + 19,100,114,111,112,100,111,119,110,105,116,101,109,115,46,99,111,117,110,116, + 2,2,19,100,114,111,112,100,111,119,110,105,116,101,109,115,46,105,116,101, + 109,115,14,1,0,1,0,0,10,111,110,115,101,116,118,97,108,117,101,7, + 17,115,105,103,110,97,109,101,111,110,115,101,116,118,97,108,117,101,19,100, + 114,111,112,100,111,119,110,46,99,111,108,115,46,99,111,117,110,116,2,1, + 19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,105,116,101,109,115, + 14,1,5,119,105,100,116,104,2,100,0,0,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,14,0,0,0,0,8,116,116,97,98,112,97,103, + 101,9,116,116,97,98,112,97,103,101,56,14,111,112,116,105,111,110,115,119, + 105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112, + 104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99,97,108, + 101,0,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119, + 95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111, + 99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119, + 95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114, + 111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111,99, + 117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 0,5,99,111,108,111,114,4,3,0,0,128,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99, + 107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100, + 25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118, + 101,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115, + 95,120,2,0,8,98,111,117,110,100,115,95,121,2,19,9,98,111,117,110, + 100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,3,51, + 1,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97, + 110,95,116,111,112,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111, + 116,116,111,109,0,7,99,97,112,116,105,111,110,6,11,38,69,120,99,101, + 112,116,105,111,110,115,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,11,116,119,105,100,103,101,116,103,114,105,100,14,101,120,99,101, + 112,116,105,111,110,115,103,114,105,100,5,99,111,108,111,114,4,3,0,0, + 128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109, + 111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99, + 107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,97,99,116,105,118,101,0,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,3,51,1,7, + 97,110,99,104,111,114,115,11,0,11,111,112,116,105,111,110,115,103,114,105, + 100,11,12,111,103,95,99,111,108,115,105,122,105,110,103,15,111,103,95,107, + 101,121,114,111,119,109,111,118,105,110,103,15,111,103,95,114,111,119,105,110, + 115,101,114,116,105,110,103,14,111,103,95,114,111,119,100,101,108,101,116,105, + 110,103,19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116, + 101,114,15,111,103,95,97,117,116,111,102,105,114,115,116,114,111,119,13,111, + 103,95,97,117,116,111,97,112,112,101,110,100,20,111,103,95,99,111,108,99, + 104,97,110,103,101,111,110,116,97,98,107,101,121,10,111,103,95,119,114,97, + 112,99,111,108,12,111,103,95,97,117,116,111,112,111,112,117,112,0,13,102, + 105,120,114,111,119,115,46,99,111,117,110,116,2,1,13,102,105,120,114,111, + 119,115,46,105,116,101,109,115,14,1,6,104,101,105,103,104,116,2,16,14, + 99,97,112,116,105,111,110,115,46,99,111,117,110,116,2,2,14,99,97,112, + 116,105,111,110,115,46,105,116,101,109,115,14,1,7,99,97,112,116,105,111, + 110,6,6,105,103,110,111,114,101,0,1,7,99,97,112,116,105,111,110,6, + 15,69,120,99,101,112,116,105,111,110,32,99,108,97,115,115,0,0,0,0, + 14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,2,16,100,97, + 116,97,99,111,108,115,46,111,112,116,105,111,110,115,11,12,99,111,95,100, + 114,97,119,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108, + 101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99, + 111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105, + 115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12, + 99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99, + 111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109, + 111,117,115,101,115,99,114,111,108,108,114,111,119,0,14,100,97,116,97,99, + 111,108,115,46,105,116,101,109,115,14,7,12,101,120,99,101,112,116,105,103, + 110,111,114,101,1,5,119,105,100,116,104,2,47,7,111,112,116,105,111,110, + 115,11,12,99,111,95,100,114,97,119,102,111,99,117,115,14,99,111,95,102, + 111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115, + 101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99, + 111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119, + 115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116,97,116,101,10, + 99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115, + 116,101,0,10,119,105,100,103,101,116,110,97,109,101,6,12,101,120,99,101, + 112,116,105,103,110,111,114,101,9,100,97,116,97,99,108,97,115,115,7,20, + 116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116, + 0,7,16,101,120,99,101,112,116,99,108,97,115,115,110,97,109,101,115,1, + 5,119,105,100,116,104,3,9,3,7,111,112,116,105,111,110,115,11,14,99, + 111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117, + 115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99, + 116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95, + 114,111,119,115,101,108,101,99,116,7,99,111,95,102,105,108,108,12,99,111, + 95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112, + 121,11,99,111,95,99,97,110,112,97,115,116,101,0,10,119,105,100,103,101, + 116,110,97,109,101,6,16,101,120,99,101,112,116,99,108,97,115,115,110,97, + 109,101,115,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100, + 109,115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,0,13, + 100,97,116,97,114,111,119,104,101,105,103,104,116,2,16,8,115,116,97,116, + 102,105,108,101,7,9,115,116,97,116,102,105,108,101,49,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,12,116,98,111,111,108,101,97, + 110,101,100,105,116,12,101,120,99,101,112,116,105,103,110,111,114,101,11,111, + 112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109, + 101,98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115, + 97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 97,99,116,105,118,101,0,8,116,97,98,111,114,100,101,114,2,1,8,98, + 111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0, + 9,98,111,117,110,100,115,95,99,120,2,47,9,98,111,117,110,100,115,95, + 99,121,2,16,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101, + 95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113, + 117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101, + 108,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101, + 115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101, + 120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110, + 101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25, + 111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116, + 99,108,105,99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11, + 17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111, + 101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97, + 118,101,115,116,97,116,101,0,7,118,105,115,105,98,108,101,8,0,0,11, + 116,115,116,114,105,110,103,101,100,105,116,16,101,120,99,101,112,116,99,108, + 97,115,115,110,97,109,101,115,11,111,112,116,105,111,110,115,115,107,105,110, + 11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108, + 121,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115, + 101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,8,116,97, + 98,111,114,100,101,114,2,2,7,118,105,115,105,98,108,101,8,8,98,111, + 117,110,100,115,95,120,2,48,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,120,3,9,3,9,98,111,117,110,100,115,95, + 99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,0,11, + 111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111, + 111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16, + 111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95, + 101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101, + 108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110, + 99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114, + 13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117, + 116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107, + 12,111,101,95,116,114,105,109,114,105,103,104,116,11,111,101,95,116,114,105, + 109,108,101,102,116,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,0,0,8,116,116,97,98,112,97,103,101,10,116,116,97,98, + 112,97,103,101,49,54,14,111,112,116,105,111,110,115,119,105,100,103,101,116, + 49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103, + 104,116,13,111,119,49,95,97,117,116,111,115,99,97,108,101,0,13,111,112, + 116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115, + 101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111, + 119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99, + 117,115,111,117,116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119, + 95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,5,99,111,108, + 111,114,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116, + 111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103, + 104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116, + 116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97, + 99,116,105,118,101,15,102,114,108,95,111,112,116,105,111,110,115,115,107,105, + 110,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108, + 105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,97,99,116,105,118,101,0,8,116,97,98,111,114,100, + 101,114,2,5,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110, + 100,115,95,121,2,19,9,98,111,117,110,100,115,95,99,120,3,62,3,9, + 98,111,117,110,100,115,95,99,121,3,51,1,7,97,110,99,104,111,114,115, + 11,7,97,110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95, + 114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,22,116,97,98, + 111,114,100,101,114,111,118,101,114,114,105,100,101,46,105,116,101,109,115,1, + 6,13,117,112,108,111,97,100,99,111,109,109,97,110,100,6,14,103,100,98, + 108,111,97,100,116,105,109,101,111,117,116,6,14,103,100,98,108,111,97,100, + 116,105,109,101,111,117,116,6,16,103,100,98,115,101,114,118,101,114,99,111, + 109,109,97,110,100,6,16,103,100,98,115,101,114,118,101,114,99,111,109,109, + 97,110,100,6,13,103,100,98,115,101,114,118,101,114,119,97,105,116,6,18, + 103,100,98,115,101,114,118,101,114,115,116,97,114,116,111,110,99,101,6,22, + 103,100,98,115,101,114,118,101,114,99,111,109,109,97,110,100,97,116,116,97, + 99,104,6,22,103,100,98,115,101,114,118,101,114,99,111,109,109,97,110,100, + 97,116,116,97,99,104,6,15,110,111,103,100,98,115,101,114,118,101,114,101, + 120,105,116,0,7,99,97,112,116,105,111,110,6,7,38,84,97,114,103,101, + 116,8,111,110,108,97,121,111,117,116,7,19,100,101,98,117,103,116,97,114, + 103,101,116,108,97,121,111,117,116,101,118,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,11,116,115,116,114,105,110,103,101,100,105,116, + 16,114,101,109,111,116,101,99,111,110,110,101,99,116,105,111,110,13,102,114, + 97,109,101,46,99,97,112,116,105,111,110,6,17,84,97,114,103,101,116,32, + 99,111,110,110,101,99,116,105,111,110,22,102,114,97,109,101,46,99,97,112, + 116,105,111,110,116,101,120,116,102,108,97,103,115,11,9,116,102,95,98,111, + 116,116,111,109,0,19,102,114,97,109,101,46,99,97,112,116,105,111,110,111, + 102,102,115,101,116,2,3,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116, + 111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103, + 104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116, + 116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97, + 99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115, + 101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2, + 0,2,0,0,4,104,105,110,116,6,37,34,45,45,116,116,121,32,68,69, + 86,73,67,69,34,32,116,111,32,115,101,116,32,116,97,114,103,101,116,32, + 116,101,114,109,105,110,97,108,10,111,110,115,104,111,119,104,105,110,116,7, + 18,104,105,110,116,101,120,112,97,110,100,101,100,109,97,99,114,111,115,8, + 98,111,117,110,100,115,95,120,2,1,8,98,111,117,110,100,115,95,121,2, + 112,9,98,111,117,110,100,115,95,99,120,3,60,3,9,98,111,117,110,100, + 115,95,99,121,2,37,7,97,110,99,104,111,114,115,11,7,97,110,95,108, + 101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,9,116, + 108,97,121,111,117,116,101,114,10,116,108,97,121,111,117,116,101,114,52,5, + 99,111,108,111,114,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,28,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117, + 115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,15,102,114, + 108,95,111,112,116,105,111,110,115,115,107,105,110,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98, + 108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99, + 116,105,118,101,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117, + 110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,3,192,0,9, + 98,111,117,110,100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95, + 99,121,2,37,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112, + 0,12,111,112,116,105,111,110,115,115,99,97,108,101,11,11,111,115,99,95, + 101,120,112,97,110,100,121,11,111,115,99,95,115,104,114,105,110,107,121,0, + 13,111,112,116,105,111,110,115,108,97,121,111,117,116,11,10,108,97,111,95, + 97,108,105,103,110,121,0,10,97,108,105,103,110,95,103,108,117,101,7,9, + 119,97,109,95,115,116,97,114,116,10,108,105,110,107,98,111,116,116,111,109, + 7,10,116,108,97,121,111,117,116,101,114,53,0,13,116,102,105,108,101,110, + 97,109,101,101,100,105,116,13,98,101,102,111,114,101,99,111,110,110,101,99, + 116,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,25,66,101,102, + 111,114,101,32,99,111,110,110,101,99,116,32,103,100,98,32,115,99,114,105, + 112,116,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116, + 102,108,97,103,115,11,9,116,102,95,98,111,116,116,111,109,0,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101, + 27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101, + 116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115, + 97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 97,99,116,105,118,101,0,19,102,114,97,109,101,46,98,117,116,116,111,110, + 115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116,116, + 111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4,2,0, + 0,128,7,105,109,97,103,101,110,114,2,17,0,0,18,102,114,97,109,101, + 46,98,117,116,116,111,110,46,99,111,108,111,114,4,2,0,0,128,20,102, + 114,97,109,101,46,98,117,116,116,111,110,46,105,109,97,103,101,110,114,2, + 17,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2, + 0,2,17,2,0,2,0,0,10,111,110,115,104,111,119,104,105,110,116,7, + 18,104,105,110,116,101,120,112,97,110,100,101,100,109,97,99,114,111,115,8, + 98,111,117,110,100,115,95,120,2,1,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,3,214,0,9,98,111,117,110,100, + 115,95,99,121,2,37,9,116,101,120,116,102,108,97,103,115,11,12,116,102, + 95,121,99,101,110,116,101,114,101,100,11,116,102,95,110,111,115,101,108,101, + 99,116,14,116,102,95,101,108,108,105,112,115,101,108,101,102,116,0,26,99, + 111,110,116,114,111,108,108,101,114,46,102,105,108,116,101,114,108,105,115,116, + 46,100,97,116,97,1,1,6,11,103,100,98,32,83,99,114,105,112,116,115, + 6,5,42,46,103,100,98,0,0,18,99,111,110,116,114,111,108,108,101,114, + 46,111,112,116,105,111,110,115,11,14,102,100,111,95,99,104,101,99,107,101, + 120,105,115,116,15,102,100,111,95,115,97,118,101,108,97,115,116,100,105,114, + 0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,9, + 116,115,112,108,105,116,116,101,114,10,116,115,112,108,105,116,116,101,114,55, + 5,99,111,108,111,114,4,3,0,0,144,8,116,97,98,111,114,100,101,114, + 2,1,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120, + 3,215,0,8,98,111,117,110,100,115,95,121,2,17,9,98,111,117,110,100, + 115,95,99,120,2,3,9,98,111,117,110,100,115,95,99,121,2,20,7,111, + 112,116,105,111,110,115,11,9,115,112,111,95,104,112,114,111,112,12,115,112, + 111,95,100,111,99,107,108,101,102,116,11,115,112,111,95,100,111,99,107,116, + 111,112,13,115,112,111,95,100,111,99,107,114,105,103,104,116,14,115,112,111, + 95,100,111,99,107,98,111,116,116,111,109,0,8,108,105,110,107,108,101,102, + 116,7,13,98,101,102,111,114,101,99,111,110,110,101,99,116,9,108,105,110, + 107,114,105,103,104,116,7,10,98,101,102,111,114,101,108,111,97,100,0,0, + 13,116,102,105,108,101,110,97,109,101,101,100,105,116,10,98,101,102,111,114, + 101,108,111,97,100,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 22,66,101,102,111,114,101,32,108,111,97,100,32,103,100,98,32,115,99,114, + 105,112,116,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120, + 116,102,108,97,103,115,11,9,116,102,95,98,111,116,116,111,109,0,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115, + 101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105, + 115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100, + 26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,97,99,116,105,118,101,0,19,102,114,97,109,101,46,98,117,116,116,111, + 110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116, + 116,111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4,2, + 0,0,128,7,105,109,97,103,101,110,114,2,17,0,0,18,102,114,97,109, + 101,46,98,117,116,116,111,110,46,99,111,108,111,114,4,2,0,0,128,20, + 102,114,97,109,101,46,98,117,116,116,111,110,46,105,109,97,103,101,110,114, + 2,17,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,2, + 10,111,110,115,104,111,119,104,105,110,116,7,18,104,105,110,116,101,120,112, + 97,110,100,101,100,109,97,99,114,111,115,8,98,111,117,110,100,115,95,120, + 3,218,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100, + 115,95,99,120,3,221,0,9,98,111,117,110,100,115,95,99,121,2,37,9, + 116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101,110,116,101, + 114,101,100,11,116,102,95,110,111,115,101,108,101,99,116,14,116,102,95,101, + 108,108,105,112,115,101,108,101,102,116,0,26,99,111,110,116,114,111,108,108, + 101,114,46,102,105,108,116,101,114,108,105,115,116,46,100,97,116,97,1,1, + 6,11,103,100,98,32,83,99,114,105,112,116,115,6,5,42,46,103,100,98, + 0,0,18,99,111,110,116,114,111,108,108,101,114,46,111,112,116,105,111,110, + 115,11,14,102,100,111,95,99,104,101,99,107,101,120,105,115,116,15,102,100, + 111,95,115,97,118,101,108,97,115,116,100,105,114,0,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,14,0,0,9,116,115,112,108,105,116,116, + 101,114,10,116,115,112,108,105,116,116,101,114,57,5,99,111,108,111,114,4, + 3,0,0,144,8,116,97,98,111,114,100,101,114,2,3,7,118,105,115,105, + 98,108,101,8,8,98,111,117,110,100,115,95,120,3,183,1,8,98,111,117, + 110,100,115,95,121,2,17,9,98,111,117,110,100,115,95,99,120,2,3,9, + 98,111,117,110,100,115,95,99,121,2,20,7,111,112,116,105,111,110,115,11, + 9,115,112,111,95,104,112,114,111,112,12,115,112,111,95,100,111,99,107,108, + 101,102,116,11,115,112,111,95,100,111,99,107,116,111,112,13,115,112,111,95, + 100,111,99,107,114,105,103,104,116,14,115,112,111,95,100,111,99,107,98,111, + 116,116,111,109,0,8,108,105,110,107,108,101,102,116,7,10,98,101,102,111, + 114,101,108,111,97,100,9,108,105,110,107,114,105,103,104,116,7,9,98,101, + 102,111,114,101,114,117,110,0,0,13,116,102,105,108,101,110,97,109,101,101, + 100,105,116,9,98,101,102,111,114,101,114,117,110,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,21,66,101,102,111,114,101,32,114,117,110,32, + 103,100,98,32,115,99,114,105,112,116,22,102,114,97,109,101,46,99,97,112, + 116,105,111,110,116,101,120,116,102,108,97,103,115,11,9,116,102,95,98,111, + 116,116,111,109,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101, + 102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112, + 19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116, + 20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111, + 109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116, + 105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,19,102,114,97,109, + 101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1,19,102,114, + 97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,5, + 99,111,108,111,114,4,2,0,0,128,7,105,109,97,103,101,110,114,2,17, + 0,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111, + 114,4,2,0,0,128,20,102,114,97,109,101,46,98,117,116,116,111,110,46, + 105,109,97,103,101,110,114,2,17,16,102,114,97,109,101,46,111,117,116,101, + 114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98, + 111,114,100,101,114,2,4,10,111,110,115,104,111,119,104,105,110,116,7,18, + 104,105,110,116,101,120,112,97,110,100,101,100,109,97,99,114,111,115,8,98, + 111,117,110,100,115,95,120,3,186,1,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,3,131,1,9,98,111,117,110,100, + 115,95,99,121,2,37,7,97,110,99,104,111,114,115,11,7,97,110,95,108, + 101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0, + 9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101,110,116, + 101,114,101,100,11,116,102,95,110,111,115,101,108,101,99,116,14,116,102,95, + 101,108,108,105,112,115,101,108,101,102,116,0,26,99,111,110,116,114,111,108, + 108,101,114,46,102,105,108,116,101,114,108,105,115,116,46,100,97,116,97,1, + 1,6,11,103,100,98,32,83,99,114,105,112,116,115,6,5,42,46,103,100, + 98,0,0,18,99,111,110,116,114,111,108,108,101,114,46,111,112,116,105,111, + 110,115,11,14,102,100,111,95,99,104,101,99,107,101,120,105,115,116,15,102, + 100,111,95,115,97,118,101,108,97,115,116,100,105,114,0,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,0,9,116,108,97,121,111, + 117,116,101,114,10,116,108,97,121,111,117,116,101,114,53,5,99,111,108,111, + 114,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108, + 101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111, + 112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104, + 116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116, + 111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,28,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99, + 108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,97,99,116,105,118,101,15,102,114,108,95,111,112, + 116,105,111,110,115,115,107,105,110,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101, + 0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117,110,100,115,95, + 120,2,0,8,98,111,117,110,100,115,95,121,3,243,0,9,98,111,117,110, + 100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,2,37, + 7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,0,12,111,112, + 116,105,111,110,115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97, + 110,100,121,11,111,115,99,95,115,104,114,105,110,107,121,0,13,111,112,116, + 105,111,110,115,108,97,121,111,117,116,11,10,108,97,111,95,97,108,105,103, + 110,121,0,10,97,108,105,103,110,95,103,108,117,101,7,9,119,97,109,95, + 115,116,97,114,116,0,13,116,102,105,108,101,110,97,109,101,101,100,105,116, + 12,97,102,116,101,114,99,111,110,110,101,99,116,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,24,65,102,116,101,114,32,99,111,110,110,101, + 99,116,32,103,100,98,32,115,99,114,105,112,116,22,102,114,97,109,101,46, + 99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,9,116,102, + 95,98,111,116,116,111,109,0,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105, + 103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111, + 116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117, + 115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,19,102, + 114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1, + 19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115, + 14,1,5,99,111,108,111,114,4,2,0,0,128,7,105,109,97,103,101,110, + 114,2,17,0,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99, + 111,108,111,114,4,2,0,0,128,20,102,114,97,109,101,46,98,117,116,116, + 111,110,46,105,109,97,103,101,110,114,2,17,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,10, + 111,110,115,104,111,119,104,105,110,116,7,18,104,105,110,116,101,120,112,97, + 110,100,101,100,109,97,99,114,111,115,8,98,111,117,110,100,115,95,120,2, + 1,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,3,214,0,9,98,111,117,110,100,115,95,99,121,2,37,9,116,101, + 120,116,102,108,97,103,115,11,12,116,102,95,121,99,101,110,116,101,114,101, + 100,11,116,102,95,110,111,115,101,108,101,99,116,14,116,102,95,101,108,108, + 105,112,115,101,108,101,102,116,0,26,99,111,110,116,114,111,108,108,101,114, + 46,102,105,108,116,101,114,108,105,115,116,46,100,97,116,97,1,1,6,11, + 103,100,98,32,83,99,114,105,112,116,115,6,5,42,46,103,100,98,0,0, + 18,99,111,110,116,114,111,108,108,101,114,46,111,112,116,105,111,110,115,11, + 14,102,100,111,95,99,104,101,99,107,101,120,105,115,116,15,102,100,111,95, + 115,97,118,101,108,97,115,116,100,105,114,0,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,14,0,0,9,116,115,112,108,105,116,116,101,114, + 10,116,115,112,108,105,116,116,101,114,56,5,99,111,108,111,114,4,3,0, + 0,144,8,116,97,98,111,114,100,101,114,2,1,7,118,105,115,105,98,108, + 101,8,8,98,111,117,110,100,115,95,120,3,215,0,8,98,111,117,110,100, + 115,95,121,2,17,9,98,111,117,110,100,115,95,99,120,2,3,9,98,111, + 117,110,100,115,95,99,121,2,20,7,111,112,116,105,111,110,115,11,9,115, + 112,111,95,104,112,114,111,112,12,115,112,111,95,100,111,99,107,108,101,102, + 116,11,115,112,111,95,100,111,99,107,116,111,112,13,115,112,111,95,100,111, + 99,107,114,105,103,104,116,14,115,112,111,95,100,111,99,107,98,111,116,116, + 111,109,0,8,108,105,110,107,108,101,102,116,7,12,97,102,116,101,114,99, + 111,110,110,101,99,116,9,108,105,110,107,114,105,103,104,116,7,9,97,102, + 116,101,114,108,111,97,100,0,0,13,116,102,105,108,101,110,97,109,101,101, + 100,105,116,9,97,102,116,101,114,108,111,97,100,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,21,65,102,116,101,114,32,108,111,97,100,32, + 103,100,98,32,115,99,114,105,112,116,22,102,114,97,109,101,46,99,97,112, + 116,105,111,110,116,101,120,116,102,108,97,103,115,11,9,116,102,95,98,111, + 116,116,111,109,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101, + 102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112, + 19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116, + 20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111, + 109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116, + 105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,19,102,114,97,109, + 101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1,19,102,114, + 97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,5, + 99,111,108,111,114,4,2,0,0,128,7,105,109,97,103,101,110,114,2,17, + 0,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111, + 114,4,2,0,0,128,20,102,114,97,109,101,46,98,117,116,116,111,110,46, + 105,109,97,103,101,110,114,2,17,16,102,114,97,109,101,46,111,117,116,101, + 114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98, + 111,114,100,101,114,2,2,10,111,110,115,104,111,119,104,105,110,116,7,18, + 104,105,110,116,101,120,112,97,110,100,101,100,109,97,99,114,111,115,8,98, + 111,117,110,100,115,95,120,3,218,0,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,3,221,0,9,98,111,117,110,100, + 115,95,99,121,2,37,9,116,101,120,116,102,108,97,103,115,11,12,116,102, + 95,121,99,101,110,116,101,114,101,100,11,116,102,95,110,111,115,101,108,101, + 99,116,14,116,102,95,101,108,108,105,112,115,101,108,101,102,116,0,26,99, + 111,110,116,114,111,108,108,101,114,46,102,105,108,116,101,114,108,105,115,116, + 46,100,97,116,97,1,1,6,11,103,100,98,32,83,99,114,105,112,116,115, + 6,5,42,46,103,100,98,0,0,18,99,111,110,116,114,111,108,108,101,114, + 46,111,112,116,105,111,110,115,11,14,102,100,111,95,99,104,101,99,107,101, + 120,105,115,116,15,102,100,111,95,115,97,118,101,108,97,115,116,100,105,114, + 0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,9, + 116,115,112,108,105,116,116,101,114,11,116,115,112,108,105,116,116,101,114,49, + 48,5,99,111,108,111,114,4,3,0,0,144,8,116,97,98,111,114,100,101, + 114,2,3,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95, + 120,3,183,1,8,98,111,117,110,100,115,95,121,2,17,9,98,111,117,110, + 100,115,95,99,120,2,3,9,98,111,117,110,100,115,95,99,121,2,20,7, + 111,112,116,105,111,110,115,11,9,115,112,111,95,104,112,114,111,112,12,115, + 112,111,95,100,111,99,107,108,101,102,116,11,115,112,111,95,100,111,99,107, + 116,111,112,13,115,112,111,95,100,111,99,107,114,105,103,104,116,14,115,112, + 111,95,100,111,99,107,98,111,116,116,111,109,0,8,108,105,110,107,108,101, + 102,116,7,9,97,102,116,101,114,108,111,97,100,0,0,0,9,116,108,97, + 121,111,117,116,101,114,10,116,108,97,121,111,117,116,101,114,51,5,99,111, + 108,111,114,4,3,0,0,128,17,102,114,97,109,101,46,102,114,97,109,101, + 105,95,108,101,102,116,2,1,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,102,105,108,101,102,116,18,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,28,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,100,105,115, + 97,98,108,101,100,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 97,99,116,105,118,101,15,102,114,108,95,111,112,116,105,111,110,115,115,107, + 105,110,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99, + 108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,97,99,116,105,118,101,0,8,116,97,98,111,114, + 100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,3,149,0,9,98,111,117,110,100,115,95,99,120,3,106, + 2,9,98,111,117,110,100,115,95,99,121,2,43,12,111,112,116,105,111,110, + 115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97,110,100,120,11, + 111,115,99,95,115,104,114,105,110,107,120,11,111,115,99,95,101,120,112,97, + 110,100,121,11,111,115,99,95,115,104,114,105,110,107,121,0,13,111,112,116, + 105,111,110,115,108,97,121,111,117,116,11,10,108,97,111,95,112,108,97,99, + 101,120,10,108,97,111,95,97,108,105,103,110,121,0,10,97,108,105,103,110, + 95,103,108,117,101,7,9,119,97,109,95,115,116,97,114,116,13,112,108,97, + 99,101,95,109,105,110,100,105,115,116,2,5,13,112,108,97,99,101,95,109, + 97,120,100,105,115,116,2,5,7,108,105,110,107,116,111,112,7,16,114,101, + 109,111,116,101,99,111,110,110,101,99,116,105,111,110,10,108,105,110,107,98, + 111,116,116,111,109,7,10,116,108,97,121,111,117,116,101,114,52,0,17,116, + 100,114,111,112,100,111,119,110,108,105,115,116,101,100,105,116,12,103,100,98, + 112,114,111,99,101,115,115,111,114,13,102,114,97,109,101,46,111,112,116,105, + 111,110,115,11,10,99,102,111,95,102,105,120,116,111,112,0,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,9,80,114,111,99,101,115,115,111, + 114,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102, + 108,97,103,115,11,9,116,102,95,98,111,116,116,111,109,0,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97, + 98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97, + 99,116,105,118,101,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46, + 99,111,108,111,114,4,2,0,0,128,19,102,114,97,109,101,46,98,117,116, + 116,111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98, + 117,116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114, + 4,2,0,0,128,0,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,17,2,0,2,0,0,10,111,110,115,104,111, + 119,104,105,110,116,7,18,104,105,110,116,101,120,112,97,110,100,101,100,109, + 97,99,114,111,115,8,98,111,117,110,100,115,95,120,2,1,8,98,111,117, + 110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,84,9, + 98,111,117,110,100,115,95,99,121,2,37,8,111,110,99,104,97,110,103,101, + 7,15,112,114,111,99,101,115,115,111,114,99,104,97,110,103,101,5,118,97, + 108,117,101,6,4,105,51,56,54,16,100,114,111,112,100,111,119,110,46,111, + 112,116,105,111,110,115,11,16,100,101,111,95,97,117,116,111,100,114,111,112, + 100,111,119,110,15,100,101,111,95,107,101,121,100,114,111,112,100,111,119,110, + 0,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,99,111,117,110, + 116,2,1,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,105,116, + 101,109,115,14,1,4,100,97,116,97,1,6,4,97,117,116,111,6,4,105, + 51,56,54,6,6,120,56,54,95,54,52,6,3,97,114,109,6,5,97,114, + 109,109,51,6,5,99,112,117,51,50,6,5,97,118,114,51,50,6,4,114, + 108,55,56,0,0,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,12,103,100, + 98,115,105,109,117,108,97,116,111,114,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,9,83,105,109,117,108,97,116,111,114,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99, + 108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98, + 108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99, + 116,105,118,101,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,1,2,62,2,2,0,8,116,97,98,111,114,100,101, + 114,2,1,8,98,111,117,110,100,115,95,120,2,90,8,98,111,117,110,100, + 115,95,121,2,20,9,98,111,117,110,100,115,95,99,120,2,75,9,98,111, + 117,110,100,115,95,99,121,2,16,8,111,110,99,104,97,110,103,101,7,14, + 100,111,119,110,108,111,97,100,99,104,97,110,103,101,0,0,12,116,98,111, + 111,108,101,97,110,101,100,105,116,11,103,100,98,100,111,119,110,108,111,97, + 100,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,12,103,100,98, + 32,100,111,119,110,108,111,97,100,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114, + 105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98, + 111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100, + 26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101, + 116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111, + 117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2, + 1,2,91,2,2,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111, + 117,110,100,115,95,120,3,170,0,8,98,111,117,110,100,115,95,121,2,20, + 9,98,111,117,110,100,115,95,99,120,2,104,9,98,111,117,110,100,115,95, + 99,121,2,16,8,111,110,99,104,97,110,103,101,7,14,100,111,119,110,108, + 111,97,100,99,104,97,110,103,101,0,0,12,116,98,111,111,108,101,97,110, + 101,100,105,116,14,100,111,119,110,108,111,97,100,97,108,119,97,121,115,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,26,65,108,119,97,121, + 115,32,100,111,119,110,108,111,97,100,10,98,101,102,111,114,101,32,114,117, + 110,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,28,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,100, + 105,115,97,98,108,101,100,25,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101, + 100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109, + 111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,8,2,108,2,9,0,8,116,97,98,111,114,100,101,114,2,3,8,98, + 111,117,110,100,115,95,120,3,23,1,8,98,111,117,110,100,115,95,121,2, + 13,9,98,111,117,110,100,115,95,99,120,2,121,9,98,111,117,110,100,115, + 95,99,121,2,30,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116, + 11,115,116,97,114,116,117,112,98,107,112,116,13,102,114,97,109,101,46,111, + 112,116,105,111,110,115,11,10,99,102,111,95,102,105,120,116,111,112,0,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,12,83,116,97,114,116, + 117,112,32,66,75,80,84,22,102,114,97,109,101,46,99,97,112,116,105,111, + 110,116,101,120,116,102,108,97,103,115,11,9,116,102,95,98,111,116,116,111, + 109,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,28, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 100,105,115,97,98,108,101,100,25,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107, + 101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101, + 0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2, + 0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,5,8, + 98,111,117,110,100,115,95,120,3,244,1,8,98,111,117,110,100,115,95,121, + 2,0,9,98,111,117,110,100,115,95,99,121,2,37,4,98,97,115,101,7, + 6,110,98,95,104,101,120,8,118,97,108,117,101,109,97,120,2,255,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,12,116,98,111, + 111,108,101,97,110,101,100,105,116,13,115,116,97,114,116,117,112,98,107,112, + 116,111,110,5,99,111,108,111,114,4,3,0,0,128,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,28,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100, + 25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101, + 116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118, + 101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108, + 105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,97,99,116,105,118,101,0,8,116,97,98,111,114,100, + 101,114,2,6,8,98,111,117,110,100,115,95,120,3,93,2,8,98,111,117, + 110,100,115,95,121,2,21,8,111,110,99,104,97,110,103,101,7,14,100,111, + 119,110,108,111,97,100,99,104,97,110,103,101,0,0,12,116,98,111,111,108, + 101,97,110,101,100,105,116,20,114,101,115,116,97,114,116,103,100,98,98,101, + 102,111,114,101,108,111,97,100,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,23,82,101,115,116,97,114,116,32,103,100,98,10,98,101,102,111, + 114,101,32,108,111,97,100,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,8,2,77,2,9,0,8,116,97,98,111,114,100, + 101,114,2,4,8,98,111,117,110,100,115,95,120,3,149,1,8,98,111,117, + 110,100,115,95,121,2,13,9,98,111,117,110,100,115,95,99,120,2,90,9, + 98,111,117,110,100,115,95,99,121,2,30,0,0,0,9,116,108,97,121,111, + 117,116,101,114,16,100,111,119,110,108,111,97,100,108,97,121,111,117,116,101, + 114,8,116,97,98,111,114,100,101,114,2,4,8,98,111,117,110,100,115,95, + 120,2,1,8,98,111,117,110,100,115,95,121,2,1,9,98,111,117,110,100, + 115,95,99,120,3,97,2,9,98,111,117,110,100,115,95,99,121,2,111,7, + 97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110,95, + 116,111,112,8,97,110,95,114,105,103,104,116,0,12,111,112,116,105,111,110, + 115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97,110,100,121,11, + 111,115,99,95,115,104,114,105,110,107,121,17,111,115,99,95,101,120,112,97, + 110,100,115,104,114,105,110,107,120,17,111,115,99,95,101,120,112,97,110,100, + 115,104,114,105,110,107,121,0,13,111,112,116,105,111,110,115,108,97,121,111, + 117,116,11,10,108,97,111,95,112,108,97,99,101,121,0,13,112,108,97,99, + 101,95,109,97,120,100,105,115,116,2,0,9,108,105,110,107,114,105,103,104, + 116,7,17,116,101,120,112,97,110,100,105,110,103,119,105,100,103,101,116,49, + 10,108,105,110,107,98,111,116,116,111,109,7,16,114,101,109,111,116,101,99, + 111,110,110,101,99,116,105,111,110,10,100,105,115,116,95,114,105,103,104,116, + 2,2,7,111,112,116,105,111,110,115,11,14,115,112,97,111,95,103,108,117, + 101,114,105,103,104,116,0,0,13,116,102,105,108,101,110,97,109,101,101,100, + 105,116,22,103,100,98,115,101,114,118,101,114,99,111,109,109,97,110,100,97, + 116,116,97,99,104,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,13,102,114,97,109,101,46,111, + 112,116,105,111,110,115,11,10,99,102,111,95,102,105,120,116,111,112,0,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,38,83,116,97,114,116, + 32,103,100,98,32,115,101,114,118,101,114,32,99,111,109,109,97,110,100,32, + 97,116,116,97,99,104,32,116,97,114,103,101,116,22,102,114,97,109,101,46, + 99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,9,116,102, + 95,98,111,116,116,111,109,0,19,102,114,97,109,101,46,99,97,112,116,105, + 111,110,111,102,102,115,101,116,2,3,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101, + 100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109, + 111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0, + 19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116, + 2,1,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101, + 109,115,14,1,5,99,111,108,111,114,4,2,0,0,128,7,105,109,97,103, + 101,110,114,2,17,0,0,18,102,114,97,109,101,46,98,117,116,116,111,110, + 46,99,111,108,111,114,4,2,0,0,128,20,102,114,97,109,101,46,98,117, + 116,116,111,110,46,105,109,97,103,101,110,114,2,17,16,102,114,97,109,101, + 46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0, + 0,8,116,97,98,111,114,100,101,114,2,2,10,111,110,115,104,111,119,104, + 105,110,116,7,18,104,105,110,116,101,120,112,97,110,100,101,100,109,97,99, + 114,111,115,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100, + 115,95,121,2,74,9,98,111,117,110,100,115,95,99,120,3,97,2,9,98, + 111,117,110,100,115,95,99,121,2,37,7,97,110,99,104,111,114,115,11,7, + 97,110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105, + 103,104,116,0,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121, + 99,101,110,116,101,114,101,100,11,116,102,95,110,111,115,101,108,101,99,116, + 14,116,102,95,101,108,108,105,112,115,101,108,101,102,116,0,18,99,111,110, + 116,114,111,108,108,101,114,46,111,112,116,105,111,110,115,11,10,102,100,111, + 95,112,97,114,97,109,115,0,26,99,111,110,116,114,111,108,108,101,114,46, + 104,105,115,116,111,114,121,109,97,120,99,111,117,110,116,2,0,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,13,116,102,105,108, + 101,110,97,109,101,101,100,105,116,16,103,100,98,115,101,114,118,101,114,99, + 111,109,109,97,110,100,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119, + 95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,0,13,102,114,97,109,101,46, + 111,112,116,105,111,110,115,11,10,99,102,111,95,102,105,120,116,111,112,0, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,35,83,116,97,114, + 116,32,103,100,98,32,115,101,114,118,101,114,32,99,111,109,109,97,110,100, + 32,114,117,110,32,116,97,114,103,101,116,22,102,114,97,109,101,46,99,97, + 112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,9,116,102,95,98, + 111,116,116,111,109,0,19,102,114,97,109,101,46,99,97,112,116,105,111,110, + 111,102,102,115,101,116,2,3,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105, + 103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111, + 116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117, + 115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,19,102, + 114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1, + 19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115, + 14,1,5,99,111,108,111,114,4,2,0,0,128,7,105,109,97,103,101,110, + 114,2,17,0,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99, + 111,108,111,114,4,2,0,0,128,20,102,114,97,109,101,46,98,117,116,116, + 111,110,46,105,109,97,103,101,110,114,2,17,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8, + 116,97,98,111,114,100,101,114,2,1,10,111,110,115,104,111,119,104,105,110, + 116,7,18,104,105,110,116,101,120,112,97,110,100,101,100,109,97,99,114,111, + 115,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95, + 121,2,37,9,98,111,117,110,100,115,95,99,120,3,97,2,9,98,111,117, + 110,100,115,95,99,121,2,37,7,97,110,99,104,111,114,115,11,7,97,110, + 95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104, + 116,0,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101, + 110,116,101,114,101,100,11,116,102,95,110,111,115,101,108,101,99,116,14,116, + 102,95,101,108,108,105,112,115,101,108,101,102,116,0,18,99,111,110,116,114, + 111,108,108,101,114,46,111,112,116,105,111,110,115,11,10,102,100,111,95,112, + 97,114,97,109,115,0,26,99,111,110,116,114,111,108,108,101,114,46,104,105, + 115,116,111,114,121,109,97,120,99,111,117,110,116,2,0,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,13,116,102,105,108,101,110, + 97,109,101,101,100,105,116,13,117,112,108,111,97,100,99,111,109,109,97,110, + 100,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95, + 97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111, + 119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121, + 119,105,100,103,101,116,115,0,13,102,114,97,109,101,46,111,112,116,105,111, + 110,115,11,10,99,102,111,95,102,105,120,116,111,112,0,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,16,68,111,119,110,108,111,97,100,32, + 99,111,109,109,97,110,100,22,102,114,97,109,101,46,99,97,112,116,105,111, + 110,116,101,120,116,102,108,97,103,115,11,9,116,102,95,98,111,116,116,111, + 109,0,19,102,114,97,109,101,46,99,97,112,116,105,111,110,111,102,102,115, + 101,116,2,3,15,102,114,97,109,101,46,102,111,110,116,46,110,97,109,101, + 6,11,115,116,102,95,100,101,102,97,117,108,116,17,102,114,97,109,101,46, + 102,111,110,116,46,120,115,99,97,108,101,2,1,21,102,114,97,109,101,46, + 102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112, + 95,120,115,99,97,108,101,0,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105, + 103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111, + 116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117, + 115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,19,102, + 114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1, + 19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115, + 14,1,5,99,111,108,111,114,4,2,0,0,128,7,105,109,97,103,101,110, + 114,2,17,0,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99, + 111,108,111,114,4,2,0,0,128,20,102,114,97,109,101,46,98,117,116,116, + 111,110,46,105,109,97,103,101,110,114,2,17,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,10, + 111,110,115,104,111,119,104,105,110,116,7,18,104,105,110,116,101,120,112,97, + 110,100,101,100,109,97,99,114,111,115,8,98,111,117,110,100,115,95,120,2, + 0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,3,97,2,9,98,111,117,110,100,115,95,99,121,2,37,7,97,110, + 99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110,95,116,111, + 112,8,97,110,95,114,105,103,104,116,0,9,116,101,120,116,102,108,97,103, + 115,11,12,116,102,95,121,99,101,110,116,101,114,101,100,11,116,102,95,110, + 111,115,101,108,101,99,116,14,116,102,95,101,108,108,105,112,115,101,108,101, + 102,116,0,18,99,111,110,116,114,111,108,108,101,114,46,111,112,116,105,111, + 110,115,11,10,102,100,111,95,112,97,114,97,109,115,0,26,99,111,110,116, + 114,111,108,108,101,114,46,104,105,115,116,111,114,121,109,97,120,99,111,117, + 110,116,2,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,0,0,16,116,101,120,112,97,110,100,105,110,103,119,105,100,103,101,116, + 17,116,101,120,112,97,110,100,105,110,103,119,105,100,103,101,116,49,8,116, + 97,98,111,114,100,101,114,2,5,8,98,111,117,110,100,115,95,120,3,100, + 2,8,98,111,117,110,100,115,95,121,2,1,9,98,111,117,110,100,115,95, + 99,120,3,214,0,9,98,111,117,110,100,115,95,99,121,2,111,7,97,110, + 99,104,111,114,115,11,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,0,12,111,112,116,105,111,110,115,115,99,97,108,101,11,11,111,115, + 99,95,101,120,112,97,110,100,120,11,111,115,99,95,115,104,114,105,110,107, + 120,11,111,115,99,95,101,120,112,97,110,100,121,11,111,115,99,95,115,104, + 114,105,110,107,121,17,111,115,99,95,101,120,112,97,110,100,115,104,114,105, + 110,107,120,17,111,115,99,95,101,120,112,97,110,100,115,104,114,105,110,107, + 121,0,0,9,116,114,101,97,108,101,100,105,116,14,103,100,98,108,111,97, + 100,116,105,109,101,111,117,116,13,102,114,97,109,101,46,111,112,116,105,111, + 110,115,11,10,99,102,111,95,102,105,120,116,111,112,0,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,12,76,111,97,100,32,84,105,109,101, + 111,117,116,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120, + 116,102,108,97,103,115,11,9,116,102,95,98,111,116,116,111,109,0,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,28,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,100,105,115,97, + 98,108,101,100,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97, + 99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115, + 101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2, + 14,2,0,0,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110, + 100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,86,9,98, + 111,117,110,100,115,95,99,121,2,37,5,118,97,108,117,101,5,0,0,0, + 0,0,0,0,128,255,255,12,118,97,108,117,101,100,101,102,97,117,108,116, + 5,0,0,0,0,0,0,0,128,255,255,10,102,111,114,109,97,116,101,100, + 105,116,6,3,48,46,35,10,102,111,114,109,97,116,100,105,115,112,6,6, + 48,46,35,115,101,99,10,118,97,108,117,101,114,97,110,103,101,2,1,10, + 118,97,108,117,101,115,116,97,114,116,2,0,8,118,97,108,117,101,109,105, + 110,5,0,0,0,0,0,0,0,128,255,255,8,118,97,108,117,101,109,97, + 120,3,200,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,0,9,116,108,97,121,111,117,116,101,114,8,115,101,114,118,101,114,108, + 97,5,99,111,108,111,114,4,3,0,0,128,17,102,114,97,109,101,46,102, + 114,97,109,101,105,95,108,101,102,116,2,1,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,102,105,108,101,102, + 116,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116, + 17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 28,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101, + 116,100,105,115,97,98,108,101,100,25,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99, + 107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,97,99,116,105,118,101,15,102,114,108,95,111,112,116,105,111, + 110,115,115,107,105,110,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117, + 115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,8,116, + 97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,37,9,98,111,117,110,100,115,95,99, + 120,3,214,0,9,98,111,117,110,100,115,95,99,121,2,37,12,111,112,116, + 105,111,110,115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97,110, + 100,120,11,111,115,99,95,115,104,114,105,110,107,120,11,111,115,99,95,101, + 120,112,97,110,100,121,11,111,115,99,95,115,104,114,105,110,107,121,17,111, + 115,99,95,101,120,112,97,110,100,115,104,114,105,110,107,120,17,111,115,99, + 95,101,120,112,97,110,100,115,104,114,105,110,107,121,0,13,111,112,116,105, + 111,110,115,108,97,121,111,117,116,11,10,108,97,111,95,112,108,97,99,101, + 120,10,108,97,111,95,97,108,105,103,110,121,0,10,97,108,105,103,110,95, + 103,108,117,101,7,9,119,97,109,95,115,116,97,114,116,13,112,108,97,99, + 101,95,109,105,110,100,105,115,116,2,2,13,112,108,97,99,101,95,109,97, + 120,100,105,115,116,2,2,13,112,108,97,99,101,95,111,112,116,105,111,110, + 115,11,13,112,108,111,95,101,110,100,109,97,114,103,105,110,0,7,108,105, + 110,107,116,111,112,7,14,103,100,98,108,111,97,100,116,105,109,101,111,117, + 116,0,9,116,114,101,97,108,101,100,105,116,13,103,100,98,115,101,114,118, + 101,114,119,97,105,116,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,19,87,97,105,116,32,98,101,102,111,114,101,32,99,111,110,110,101,99, + 116,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102, + 108,97,103,115,11,9,116,102,95,98,111,116,116,111,109,0,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,28,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,100,105,115,97,98,108, + 101,100,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116, + 105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,16,102,114,97,109, + 101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,58,2, + 0,0,8,98,111,117,110,100,115,95,120,2,1,8,98,111,117,110,100,115, + 95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,129,0,9,98,111, + 117,110,100,115,95,99,121,2,37,7,97,110,99,104,111,114,115,11,6,97, + 110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,5,118,97,108,117, + 101,2,0,12,118,97,108,117,101,100,101,102,97,117,108,116,5,0,0,0, + 0,0,0,0,128,255,255,10,102,111,114,109,97,116,101,100,105,116,6,3, + 48,46,35,10,102,111,114,109,97,116,100,105,115,112,6,6,48,46,35,115, + 101,99,10,118,97,108,117,101,114,97,110,103,101,2,1,10,118,97,108,117, + 101,115,116,97,114,116,2,0,8,118,97,108,117,101,109,105,110,2,0,8, + 118,97,108,117,101,109,97,120,3,200,0,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,0,12,116,98,111,111,108,101,97,110,101,100, + 105,116,18,103,100,98,115,101,114,118,101,114,115,116,97,114,116,111,110,99, + 101,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,10,83,116,97, + 114,116,32,111,110,99,101,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,1,2,69,2,2,0,8,116,97,98,111,114,100, + 101,114,2,1,8,98,111,117,110,100,115,95,120,3,132,0,8,98,111,117, + 110,100,115,95,121,2,20,9,98,111,117,110,100,115,95,99,120,2,82,9, + 98,111,117,110,100,115,95,99,121,2,16,0,0,0,9,116,108,97,121,111, + 117,116,101,114,10,116,108,97,121,111,117,116,101,114,50,5,99,111,108,111, + 114,4,3,0,0,128,17,102,114,97,109,101,46,102,114,97,109,101,105,95, + 108,101,102,116,2,1,18,102,114,97,109,101,46,102,114,97,109,101,105,95, + 114,105,103,104,116,2,2,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,10,102,114,108,95,102,105,108,101,102,116,11,102,114,108, + 95,102,105,114,105,103,104,116,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,2, + 8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121, + 2,74,9,98,111,117,110,100,115,95,99,120,3,164,0,9,98,111,117,110, + 100,115,95,99,121,2,37,12,111,112,116,105,111,110,115,115,99,97,108,101, + 11,11,111,115,99,95,101,120,112,97,110,100,120,11,111,115,99,95,115,104, + 114,105,110,107,120,11,111,115,99,95,101,120,112,97,110,100,121,11,111,115, + 99,95,115,104,114,105,110,107,121,17,111,115,99,95,101,120,112,97,110,100, + 115,104,114,105,110,107,120,17,111,115,99,95,101,120,112,97,110,100,115,104, + 114,105,110,107,121,0,13,111,112,116,105,111,110,115,108,97,121,111,117,116, + 11,10,108,97,111,95,112,108,97,99,101,120,10,108,97,111,95,97,108,105, + 103,110,121,0,10,97,108,105,103,110,95,103,108,117,101,7,9,119,97,109, + 95,115,116,97,114,116,13,112,108,97,99,101,95,109,105,110,100,105,115,116, + 2,2,13,112,108,97,99,101,95,109,97,120,100,105,115,116,2,2,13,112, + 108,97,99,101,95,111,112,116,105,111,110,115,11,15,112,108,111,95,110,111, + 105,110,118,105,115,105,98,108,101,0,7,108,105,110,107,116,111,112,7,8, + 115,101,114,118,101,114,108,97,0,12,116,98,111,111,108,101,97,110,101,100, + 105,116,15,110,111,103,100,98,115,101,114,118,101,114,101,120,105,116,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,16,110,111,32,119,97,105, + 116,32,102,111,114,32,101,120,105,116,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101, + 114,102,114,97,109,101,1,2,0,2,1,2,95,2,2,0,8,98,111,117, + 110,100,115,95,120,2,1,8,98,111,117,110,100,115,95,121,2,20,9,98, + 111,117,110,100,115,95,99,120,2,108,9,98,111,117,110,100,115,95,99,121, + 2,16,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,8,97, + 110,95,114,105,103,104,116,0,0,0,12,116,98,111,111,108,101,97,110,101, + 100,105,116,12,103,100,98,115,101,114,118,101,114,116,116,121,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,3,84,84,89,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101, + 46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,2,24,2,2, + 0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95, + 120,2,111,8,98,111,117,110,100,115,95,121,2,20,9,98,111,117,110,100, + 115,95,99,120,2,37,9,98,111,117,110,100,115,95,99,121,2,16,0,0, + 11,116,115,116,114,105,110,103,101,100,105,116,12,116,115,116,114,105,110,103, + 101,100,105,116,49,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49, + 11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104, + 116,13,111,119,49,95,97,117,116,111,115,99,97,108,101,29,111,119,49,95, + 105,110,118,105,115,105,98,108,101,112,97,114,101,110,116,115,105,122,101,101, + 120,116,101,110,100,0,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,1,97,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120, + 116,102,108,97,103,115,11,9,116,102,95,98,111,116,116,111,109,0,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2, + 0,2,0,0,8,116,97,98,111,114,100,101,114,2,2,7,118,105,115,105, + 98,108,101,8,8,98,111,117,110,100,115,95,120,3,150,0,8,98,111,117, + 110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,12,9, + 98,111,117,110,100,115,95,99,121,2,37,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,0,0,0,0,0,9,116,108,97,121,111,117, + 116,101,114,10,116,108,97,121,111,117,116,101,114,49,5,99,111,108,111,114, + 4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101, + 102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112, + 19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116, + 20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111, + 109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,28,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108, + 105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 111,102,102,115,101,116,97,99,116,105,118,101,15,102,114,108,95,111,112,116, + 105,111,110,115,115,107,105,110,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109, + 111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0, + 8,116,97,98,111,114,100,101,114,2,5,8,98,111,117,110,100,115,95,120, + 2,7,8,98,111,117,110,100,115,95,121,3,164,0,9,98,111,117,110,100, + 115,95,99,120,3,232,2,9,98,111,117,110,100,115,95,99,121,2,30,12, + 111,112,116,105,111,110,115,115,99,97,108,101,11,11,111,115,99,95,101,120, + 112,97,110,100,120,11,111,115,99,95,115,104,114,105,110,107,120,11,111,115, + 99,95,101,120,112,97,110,100,121,11,111,115,99,95,115,104,114,105,110,107, + 121,0,13,111,112,116,105,111,110,115,108,97,121,111,117,116,11,10,108,97, + 111,95,112,108,97,99,101,120,10,108,97,111,95,97,108,105,103,110,121,0, + 10,97,108,105,103,110,95,103,108,117,101,7,9,119,97,109,95,115,116,97, + 114,116,13,112,108,97,99,101,95,109,105,110,100,105,115,116,2,10,13,112, + 108,97,99,101,95,109,97,120,100,105,115,116,2,10,13,112,108,97,99,101, + 95,111,112,116,105,111,110,115,11,15,112,108,111,95,110,111,105,110,118,105, + 115,105,98,108,101,0,10,108,105,110,107,98,111,116,116,111,109,7,11,116, + 116,97,98,119,105,100,103,101,116,49,11,100,105,115,116,95,98,111,116,116, + 111,109,2,10,0,12,116,98,111,111,108,101,97,110,101,100,105,116,15,101, + 120,116,101,114,110,97,108,99,111,110,115,111,108,101,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,17,38,69,120,116,101,114,110,97,108,10, + 67,111,110,115,111,108,101,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116, + 111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103, + 104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116, + 116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97, + 99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115, + 101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,8,2, + 54,2,9,0,8,116,97,98,111,114,100,101,114,2,7,8,98,111,117,110, + 100,115,95,120,3,108,2,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,120,2,67,9,98,111,117,110,100,115,95,99,121, + 2,30,8,111,110,99,104,97,110,103,101,7,18,117,112,100,97,116,101,100, + 101,98,117,103,101,110,97,98,108,101,100,0,0,12,116,98,111,111,108,101, + 97,110,101,100,105,116,11,115,104,111,119,99,111,110,115,111,108,101,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,18,83,104,111,119,32,38, + 67,111,110,115,46,10,111,110,32,82,117,110,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99, + 107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100, + 25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118, + 101,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,8,2,75,2,9,0,8,116,97,98,111,114,100,101,114,2,5, + 4,104,105,110,116,6,19,83,104,111,119,32,99,111,110,115,111,108,101,32, + 111,110,32,114,117,110,8,98,111,117,110,100,115,95,120,3,219,1,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2, + 88,9,98,111,117,110,100,115,95,99,121,2,30,0,0,12,116,98,111,111, + 108,101,97,110,101,100,105,116,15,115,116,111,112,111,110,101,120,99,101,112, + 116,105,111,110,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,15, + 38,83,116,111,112,10,111,110,32,69,120,99,101,112,46,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99, + 108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98, + 108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99, + 116,105,118,101,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,8,2,64,2,9,0,8,116,97,98,111,114,100,101, + 114,2,4,4,104,105,110,116,6,18,83,116,111,112,32,111,110,32,101,120, + 99,101,112,116,105,111,110,115,8,98,111,117,110,100,115,95,120,3,132,1, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,2,77,9,98,111,117,110,100,115,95,99,121,2,30,0,0,12,116,98, + 111,111,108,101,97,110,101,100,105,116,15,97,99,116,105,118,97,116,101,111, + 110,98,114,101,97,107,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,18,38,65,99,116,105,118,97,116,101,10,111,110,32,66,114,101,97,107, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111, + 117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107, + 101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,97,99,116,105,118,101,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,8,2,59,2,9,0,8,116,97, + 98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,61,8, + 98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120, + 2,72,9,98,111,117,110,100,115,95,99,121,2,30,10,111,110,115,101,116, + 118,97,108,117,101,7,18,97,99,116,105,118,97,116,101,111,110,98,114,101, + 97,107,115,101,116,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116, + 10,118,97,108,117,101,104,105,110,116,115,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,12,38,86,97,108,117,101,10,72,105,110,116,115,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,28,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,100,105,115, + 97,98,108,101,100,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117, + 115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,8, + 2,38,2,9,0,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,51,9, + 98,111,117,110,100,115,95,99,121,2,30,0,0,12,116,98,111,111,108,101, + 97,110,101,100,105,116,15,110,111,100,101,98,117,103,98,101,103,105,110,101, + 110,100,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,33,67,97, + 108,108,32,71,85,73,95,68,69,66,85,71,66,69,71,73,78,47,10,71, + 85,73,95,68,69,66,85,71,69,78,68,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,8,3,140,0,2,9,0,8,116, + 97,98,111,114,100,101,114,2,3,4,104,105,110,116,6,74,82,101,108,101, + 97,115,101,32,109,111,117,115,101,32,103,114,97,98,32,98,121,32,116,97, + 114,103,101,116,32,115,116,111,112,46,32,103,100,98,32,115,111,109,101,116, + 105,109,101,115,32,99,114,97,115,104,101,115,32,119,105,116,104,32,116,104, + 105,115,32,111,112,116,105,111,110,46,8,98,111,117,110,100,115,95,120,3, + 225,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,3,153,0,9,98,111,117,110,100,115,95,99,121,2,30,7,111, + 112,116,105,111,110,115,11,17,98,111,95,101,120,101,99,117,116,101,111,110, + 99,108,105,99,107,15,98,111,95,101,120,101,99,117,116,101,111,110,107,101, + 121,20,98,111,95,101,120,101,99,117,116,101,111,110,115,104,111,114,116,99, + 117,116,27,98,111,95,101,120,101,99,117,116,101,100,101,102,97,117,108,116, + 111,110,101,110,116,101,114,107,101,121,11,98,111,95,114,101,118,101,114,115, + 101,100,0,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,6,115, + 101,116,116,116,121,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 8,83,101,116,10,84,84,38,89,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,8,2,24,2,9,0,8,116,97,98,111, + 114,100,101,114,2,6,8,98,111,117,110,100,115,95,120,3,61,2,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2, + 37,9,98,111,117,110,100,115,95,99,121,2,30,7,118,105,115,105,98,108, + 101,8,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,12,114,97, + 105,115,101,111,110,98,114,101,97,107,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,15,38,82,97,105,115,101,10,111,110,32,66,114,101,97, + 107,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109, + 111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99, + 107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,97,99,116,105,118,101,0,16,102,114,97,109,101,46,111,117, + 116,101,114,102,114,97,109,101,1,2,0,2,8,2,59,2,9,0,8,116, + 97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,3,143, + 0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,2,72,9,98,111,117,110,100,115,95,99,121,2,30,0,0,12,116, + 98,111,111,108,101,97,110,101,100,105,116,16,102,112,99,103,100,98,119,111, + 114,107,97,114,111,117,110,100,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,9,38,70,80,67,10,98,117,103,115,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,8,2,34,2,9,0,8, + 116,97,98,111,114,100,101,114,2,8,4,104,105,110,116,6,32,85,115,101, + 32,119,111,114,107,97,114,111,117,110,100,115,32,102,111,114,32,70,80,67, + 47,103,100,98,32,98,117,103,115,8,98,111,117,110,100,115,95,120,3,185, + 2,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,2,47,9,98,111,117,110,100,115,95,99,121,2,30,0,0,0,13, + 116,102,105,108,101,110,97,109,101,101,100,105,116,11,100,101,98,117,103,116, + 97,114,103,101,116,13,102,114,97,109,101,46,111,112,116,105,111,110,115,11, + 10,99,102,111,95,102,105,120,116,111,112,13,99,102,111,95,97,117,116,111, + 119,105,100,116,104,0,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,39,68,101,98,117,103,32,38,116,97,114,103,101,116,32,40,101,109,112, + 116,121,32,61,32,109,97,107,101,32,116,97,114,103,101,116,102,105,108,101, + 41,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102, + 108,97,103,115,11,9,116,102,95,98,111,116,116,111,109,0,19,102,114,97, + 109,101,46,99,97,112,116,105,111,110,111,102,102,115,101,116,2,3,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115, + 101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105, + 115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100, + 26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,97,99,116,105,118,101,0,19,102,114,97,109,101,46,98,117,116,116,111, + 110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116, + 116,111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4,2, + 0,0,128,7,105,109,97,103,101,110,114,2,17,0,0,18,102,114,97,109, + 101,46,98,117,116,116,111,110,46,99,111,108,111,114,4,2,0,0,128,20, + 102,114,97,109,101,46,98,117,116,116,111,110,46,105,109,97,103,101,110,114, + 2,17,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,3, + 10,111,110,115,104,111,119,104,105,110,116,7,18,104,105,110,116,101,120,112, + 97,110,100,101,100,109,97,99,114,111,115,8,98,111,117,110,100,115,95,120, + 2,1,8,98,111,117,110,100,115,95,121,2,104,9,98,111,117,110,100,115, + 95,99,120,3,46,1,9,98,111,117,110,100,115,95,99,121,2,37,7,97, + 110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110,95,116, + 111,112,8,97,110,95,114,105,103,104,116,0,18,99,111,110,116,114,111,108, + 108,101,114,46,111,112,116,105,111,110,115,11,0,26,99,111,110,116,114,111, + 108,108,101,114,46,104,105,115,116,111,114,121,109,97,120,99,111,117,110,116, + 2,0,24,99,111,110,116,114,111,108,108,101,114,46,111,110,103,101,116,102, + 105,108,101,110,97,109,101,7,14,101,120,112,97,110,100,102,105,108,101,110, + 97,109,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0, + 0,9,116,115,112,108,105,116,116,101,114,19,100,101,98,117,103,116,97,114, + 103,101,116,115,112,108,105,116,116,101,114,5,99,111,108,111,114,4,3,0, + 0,144,8,116,97,98,111,114,100,101,114,2,7,7,118,105,115,105,98,108, + 101,8,8,98,111,117,110,100,115,95,120,3,47,1,8,98,111,117,110,100, + 115,95,121,2,109,9,98,111,117,110,100,115,95,99,120,2,3,9,98,111, + 117,110,100,115,95,99,121,2,34,7,111,112,116,105,111,110,115,11,9,115, + 112,111,95,104,112,114,111,112,12,115,112,111,95,100,111,99,107,108,101,102, + 116,11,115,112,111,95,100,111,99,107,116,111,112,13,115,112,111,95,100,111, + 99,107,114,105,103,104,116,14,115,112,111,95,100,111,99,107,98,111,116,116, + 111,109,0,8,108,105,110,107,108,101,102,116,7,11,100,101,98,117,103,116, + 97,114,103,101,116,9,108,105,110,107,114,105,103,104,116,7,12,120,116,101, + 114,109,99,111,109,109,97,110,100,0,0,15,116,109,101,109,111,100,105,97, + 108,111,103,101,100,105,116,12,120,116,101,114,109,99,111,109,109,97,110,100, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,13,120,116,101,114, + 109,32,99,111,109,109,97,110,100,22,102,114,97,109,101,46,99,97,112,116, + 105,111,110,116,101,120,116,102,108,97,103,115,11,9,116,102,95,98,111,116, + 116,111,109,9,116,102,95,103,114,97,121,101,100,0,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,19,102,114,97,109,101,46, + 98,117,116,116,111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109, + 101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,7,105,109, + 97,103,101,110,114,2,17,0,0,20,102,114,97,109,101,46,98,117,116,116, + 111,110,46,105,109,97,103,101,110,114,2,17,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8, + 116,97,98,111,114,100,101,114,2,4,10,111,110,115,104,111,119,104,105,110, + 116,7,18,104,105,110,116,101,120,112,97,110,100,101,100,109,97,99,114,111, + 115,7,101,110,97,98,108,101,100,8,8,98,111,117,110,100,115,95,120,3, + 50,1,8,98,111,117,110,100,115,95,121,2,104,9,98,111,117,110,100,115, + 95,99,120,3,11,2,9,98,111,117,110,100,115,95,99,121,2,37,7,97, + 110,99,104,111,114,115,11,6,97,110,95,116,111,112,8,97,110,95,114,105, + 103,104,116,0,10,111,110,115,101,116,118,97,108,117,101,7,18,115,101,116, + 120,116,101,114,109,99,111,109,109,97,110,100,101,120,101,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,9,116,115,112,108,105,116, + 116,101,114,13,100,101,98,117,103,115,112,108,105,116,116,101,114,5,99,111, + 108,111,114,4,3,0,0,144,8,116,97,98,111,114,100,101,114,2,8,7, + 118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,47,1, + 8,98,111,117,110,100,115,95,121,2,69,9,98,111,117,110,100,115,95,99, + 120,2,3,9,98,111,117,110,100,115,95,99,121,2,26,7,111,112,116,105, + 111,110,115,11,9,115,112,111,95,104,112,114,111,112,12,115,112,111,95,100, + 111,99,107,108,101,102,116,11,115,112,111,95,100,111,99,107,116,111,112,13, + 115,112,111,95,100,111,99,107,114,105,103,104,116,14,115,112,111,95,100,111, + 99,107,98,111,116,116,111,109,0,8,108,105,110,107,108,101,102,116,7,12, + 100,101,98,117,103,99,111,109,109,97,110,100,9,108,105,110,107,114,105,103, + 104,116,7,12,100,101,98,117,103,111,112,116,105,111,110,115,0,0,13,116, + 102,105,108,101,110,97,109,101,101,100,105,116,10,114,117,110,99,111,109,109, + 97,110,100,13,102,114,97,109,101,46,111,112,116,105,111,110,115,11,10,99, + 102,111,95,102,105,120,116,111,112,13,99,102,111,95,97,117,116,111,119,105, + 100,116,104,0,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,37, + 38,82,117,110,32,99,111,109,109,97,110,100,32,40,101,109,112,116,121,32, + 61,32,115,116,97,114,116,32,100,101,98,117,103,103,101,114,41,22,102,114, + 97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115, + 11,9,116,102,95,98,111,116,116,111,109,0,19,102,114,97,109,101,46,99, + 97,112,116,105,111,110,111,102,102,115,101,116,2,3,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108, + 105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108, + 101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116, + 105,118,101,0,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,99, + 111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116,116,111,110,115, + 46,105,116,101,109,115,14,1,5,99,111,108,111,114,4,2,0,0,128,7, + 105,109,97,103,101,110,114,2,17,0,0,18,102,114,97,109,101,46,98,117, + 116,116,111,110,46,99,111,108,111,114,4,2,0,0,128,20,102,114,97,109, + 101,46,98,117,116,116,111,110,46,105,109,97,103,101,110,114,2,17,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17, + 2,0,2,0,0,10,111,110,115,104,111,119,104,105,110,116,7,18,104,105, + 110,116,101,120,112,97,110,100,101,100,109,97,99,114,111,115,8,98,111,117, + 110,100,115,95,120,2,1,8,98,111,117,110,100,115,95,121,2,21,9,98, + 111,117,110,100,115,95,99,120,3,60,3,9,98,111,117,110,100,115,95,99, + 121,2,37,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116, + 6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,8,111,110, + 99,104,97,110,103,101,7,18,117,112,100,97,116,101,100,101,98,117,103,101, + 110,97,98,108,101,100,18,99,111,110,116,114,111,108,108,101,114,46,111,112, + 116,105,111,110,115,11,10,102,100,111,95,112,97,114,97,109,115,0,26,99, + 111,110,116,114,111,108,108,101,114,46,104,105,115,116,111,114,121,109,97,120, + 99,111,117,110,116,2,0,24,99,111,110,116,114,111,108,108,101,114,46,111, + 110,103,101,116,102,105,108,101,110,97,109,101,7,14,101,120,112,97,110,100, + 102,105,108,101,110,97,109,101,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,14,0,0,0,8,116,116,97,98,112,97,103,101,8,109,97,107, + 101,112,97,103,101,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98, + 102,111,99,117,115,13,111,119,95,109,111,117,115,101,119,104,101,101,108,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115, + 101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105, + 115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100, + 26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,97,99,116,105,118,101,0,8,116,97,98,111,114,100,101,114,2,6,8, + 98,111,117,110,100,115,95,120,2,1,8,98,111,117,110,100,115,95,121,2, + 20,9,98,111,117,110,100,115,95,99,120,3,62,3,9,98,111,117,110,100, + 115,95,99,121,3,18,2,7,97,110,99,104,111,114,115,11,6,97,110,95, + 116,111,112,9,97,110,95,98,111,116,116,111,109,0,7,99,97,112,116,105, + 111,110,6,5,38,77,97,107,101,8,111,110,108,97,121,111,117,116,7,21, + 109,97,107,101,112,97,103,101,111,110,99,104,105,108,100,115,99,97,108,101, + 100,0,7,116,115,112,97,99,101,114,8,116,115,112,97,99,101,114,50,5, + 99,111,108,111,114,4,3,0,0,128,8,116,97,98,111,114,100,101,114,2, + 18,8,98,111,117,110,100,115,95,120,3,85,1,8,98,111,117,110,100,115, + 95,121,2,108,9,98,111,117,110,100,115,95,99,120,2,10,9,98,111,117, + 110,100,115,95,99,121,2,26,8,108,105,110,107,108,101,102,116,7,9,99, + 111,108,111,114,110,111,116,101,9,108,105,110,107,114,105,103,104,116,7,12, + 99,111,112,121,109,101,115,115,97,103,101,115,0,0,9,116,101,110,117,109, + 101,100,105,116,11,100,101,102,97,117,108,116,109,97,107,101,13,111,112,116, + 105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101, + 102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119, + 95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119, + 102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117, + 115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,0,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,16,68, + 101,102,97,117,108,116,32,109,97,107,101,32,99,111,108,22,102,114,97,109, + 101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,9, + 116,102,95,98,111,116,116,111,109,0,19,102,114,97,109,101,46,99,97,112, + 116,105,111,110,111,102,102,115,101,116,2,3,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99, + 107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100, + 25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118, + 101,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111, + 114,4,2,0,0,128,19,102,114,97,109,101,46,98,117,116,116,111,110,115, + 46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116,116,111, + 110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4,2,0,0, + 128,0,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101, + 1,2,0,2,17,2,14,2,0,0,8,116,97,98,111,114,100,101,114,2, + 11,8,98,111,117,110,100,115,95,120,2,1,8,98,111,117,110,100,115,95, + 121,2,123,9,98,111,117,110,100,115,95,99,120,2,110,9,98,111,117,110, + 100,115,95,99,121,2,37,12,111,112,116,105,111,110,115,101,100,105,116,49, + 11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,13, + 111,101,49,95,115,97,118,101,118,97,108,117,101,13,111,101,49,95,115,97, + 118,101,115,116,97,116,101,0,11,111,112,116,105,111,110,115,101,100,105,116, + 11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108, + 111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99, + 97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111, + 101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15, + 111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101, + 110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108, + 101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102, + 105,114,115,116,99,108,105,99,107,0,9,116,101,120,116,102,108,97,103,115, + 11,12,116,102,95,120,99,101,110,116,101,114,101,100,12,116,102,95,121,99, + 101,110,116,101,114,101,100,11,116,102,95,110,111,115,101,108,101,99,116,0, + 16,100,114,111,112,100,111,119,110,46,111,112,116,105,111,110,115,11,14,100, + 101,111,95,115,101,108,101,99,116,111,110,108,121,15,100,101,111,95,102,111, + 114,99,101,115,101,108,101,99,116,16,100,101,111,95,97,117,116,111,100,114, + 111,112,100,111,119,110,0,19,100,114,111,112,100,111,119,110,46,99,111,108, + 115,46,99,111,117,110,116,2,1,19,100,114,111,112,100,111,119,110,46,99, + 111,108,115,46,105,116,101,109,115,14,1,4,100,97,116,97,1,6,8,77, + 32,40,77,97,107,101,41,6,9,66,32,40,66,117,105,108,100,41,6,10, + 49,32,40,77,97,107,101,32,49,41,6,10,50,32,40,77,97,107,101,32, + 50,41,6,10,51,32,40,77,97,107,101,32,51,41,6,10,52,32,40,77, + 97,107,101,32,52,41,6,4,78,111,110,101,0,0,0,5,118,97,108,117, + 101,2,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0, + 0,13,116,102,105,108,101,110,97,109,101,101,100,105,116,8,109,97,105,110, + 102,105,108,101,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13, + 111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98, + 102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15, + 111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97, + 114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116, + 114,111,121,119,105,100,103,101,116,115,0,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,9,38,77,97,105,110,102,105,108,101,22,102,114,97, + 109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11, + 9,116,102,95,98,111,116,116,111,109,0,19,102,114,97,109,101,46,99,97, + 112,116,105,111,110,111,102,102,115,101,116,2,3,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105, + 99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101, + 100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105, + 118,101,0,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111, + 117,110,116,2,1,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46, + 105,116,101,109,115,14,1,5,99,111,108,111,114,4,2,0,0,128,7,105, + 109,97,103,101,110,114,2,17,0,0,18,102,114,97,109,101,46,98,117,116, + 116,111,110,46,99,111,108,111,114,4,2,0,0,128,20,102,114,97,109,101, + 46,98,117,116,116,111,110,46,105,109,97,103,101,110,114,2,17,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2, + 0,2,0,0,10,111,110,115,104,111,119,104,105,110,116,7,18,104,105,110, + 116,101,120,112,97,110,100,101,100,109,97,99,114,111,115,8,98,111,117,110, + 100,115,95,120,2,1,8,98,111,117,110,100,115,95,121,2,2,9,98,111, + 117,110,100,115,95,99,120,3,246,0,9,98,111,117,110,100,115,95,99,121, + 2,37,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101, + 110,116,101,114,101,100,11,116,102,95,110,111,115,101,108,101,99,116,14,116, + 102,95,101,108,108,105,112,115,101,108,101,102,116,0,18,99,111,110,116,114, + 111,108,108,101,114,46,111,112,116,105,111,110,115,11,8,102,100,111,95,108, + 105,110,107,0,26,99,111,110,116,114,111,108,108,101,114,46,104,105,115,116, + 111,114,121,109,97,120,99,111,117,110,116,2,0,22,99,111,110,116,114,111, + 108,108,101,114,46,99,97,112,116,105,111,110,111,112,101,110,6,15,83,101, + 108,101,99,116,32,109,97,105,110,102,105,108,101,24,99,111,110,116,114,111, + 108,108,101,114,46,111,110,103,101,116,102,105,108,101,110,97,109,101,7,14, + 101,120,112,97,110,100,102,105,108,101,110,97,109,101,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,14,0,0,13,116,102,105,108,101,110,97, + 109,101,101,100,105,116,10,116,97,114,103,101,116,102,105,108,101,13,111,112, + 116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115, + 101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111, + 119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99, + 117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,11, + 38,84,97,114,103,101,116,102,105,108,101,22,102,114,97,109,101,46,99,97, + 112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,9,116,102,95,98, + 111,116,116,111,109,0,19,102,114,97,109,101,46,99,97,112,116,105,111,110, + 111,102,102,115,101,116,2,3,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105, + 103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111, + 116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117, + 115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,19,102, + 114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1, + 19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115, + 14,1,5,99,111,108,111,114,4,2,0,0,128,7,105,109,97,103,101,110, + 114,2,17,0,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99, + 111,108,111,114,4,2,0,0,128,20,102,114,97,109,101,46,98,117,116,116, + 111,110,46,105,109,97,103,101,110,114,2,17,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8, + 116,97,98,111,114,100,101,114,2,1,10,111,110,115,104,111,119,104,105,110, + 116,7,18,104,105,110,116,101,120,112,97,110,100,101,100,109,97,99,114,111, + 115,8,98,111,117,110,100,115,95,120,3,250,0,8,98,111,117,110,100,115, + 95,121,2,2,9,98,111,117,110,100,115,95,99,120,3,205,0,9,98,111, + 117,110,100,115,95,99,121,2,37,7,97,110,99,104,111,114,115,11,7,97, + 110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,0,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99, + 101,110,116,101,114,101,100,11,116,102,95,110,111,115,101,108,101,99,116,14, + 116,102,95,101,108,108,105,112,115,101,108,101,102,116,0,18,99,111,110,116, + 114,111,108,108,101,114,46,111,112,116,105,111,110,115,11,8,102,100,111,95, + 108,105,110,107,0,26,99,111,110,116,114,111,108,108,101,114,46,104,105,115, + 116,111,114,121,109,97,120,99,111,117,110,116,2,0,22,99,111,110,116,114, + 111,108,108,101,114,46,99,97,112,116,105,111,110,111,112,101,110,6,18,83, + 101,108,101,99,116,32,116,97,114,103,101,116,32,102,105,108,101,24,99,111, + 110,116,114,111,108,108,101,114,46,111,110,103,101,116,102,105,108,101,110,97, + 109,101,7,14,101,120,112,97,110,100,102,105,108,101,110,97,109,101,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,13,116,102,105, + 108,101,110,97,109,101,101,100,105,116,11,109,97,107,101,99,111,109,109,97, + 110,100,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119, + 95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111, + 99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119, + 95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114, + 111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111, + 121,119,105,100,103,101,116,115,0,13,102,114,97,109,101,46,99,97,112,116, + 105,111,110,6,13,77,97,107,101,32,38,80,114,111,103,114,97,109,22,102, + 114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103, + 115,11,9,116,102,95,98,111,116,116,111,109,0,19,102,114,97,109,101,46, + 99,97,112,116,105,111,110,111,102,102,115,101,116,2,3,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99, + 108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98, + 108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99, + 116,105,118,101,0,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46, + 99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116,116,111,110, + 115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4,2,0,0,128, + 7,105,109,97,103,101,110,114,2,17,0,0,18,102,114,97,109,101,46,98, + 117,116,116,111,110,46,99,111,108,111,114,4,2,0,0,128,20,102,114,97, + 109,101,46,98,117,116,116,111,110,46,105,109,97,103,101,110,114,2,17,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2, + 17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,3,10,111,110, + 115,104,111,119,104,105,110,116,7,18,104,105,110,116,101,120,112,97,110,100, + 101,100,109,97,99,114,111,115,8,98,111,117,110,100,115,95,120,2,1,8, + 98,111,117,110,100,115,95,121,2,43,9,98,111,117,110,100,115,95,99,120, + 3,246,0,9,98,111,117,110,100,115,95,99,121,2,37,7,97,110,99,104, + 111,114,115,11,7,97,110,95,108,101,102,116,6,97,110,95,116,111,112,8, + 97,110,95,114,105,103,104,116,0,9,116,101,120,116,102,108,97,103,115,11, + 12,116,102,95,121,99,101,110,116,101,114,101,100,11,116,102,95,110,111,115, + 101,108,101,99,116,14,116,102,95,101,108,108,105,112,115,101,108,101,102,116, + 0,18,99,111,110,116,114,111,108,108,101,114,46,111,112,116,105,111,110,115, + 11,0,26,99,111,110,116,114,111,108,108,101,114,46,104,105,115,116,111,114, + 121,109,97,120,99,111,117,110,116,2,0,22,99,111,110,116,114,111,108,108, + 101,114,46,99,97,112,116,105,111,110,111,112,101,110,6,19,83,101,108,101, + 99,116,32,109,97,107,101,32,99,111,109,109,97,110,100,24,99,111,110,116, + 114,111,108,108,101,114,46,111,110,103,101,116,102,105,108,101,110,97,109,101, + 7,14,101,120,112,97,110,100,102,105,108,101,110,97,109,101,13,114,101,102, + 102,111,110,116,104,101,105,103,104,116,2,14,0,0,7,116,98,117,116,116, + 111,110,15,115,104,111,119,99,111,109,109,97,110,100,108,105,110,101,14,111, + 112,116,105,111,110,115,119,105,100,103,101,116,49,11,13,111,119,49,95,97, + 117,116,111,119,105,100,116,104,14,111,119,49,95,97,117,116,111,104,101,105, + 103,104,116,0,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13, + 111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98, + 102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15, + 111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97, + 114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116, + 114,111,121,119,105,100,103,101,116,115,0,5,99,111,108,111,114,4,3,0, + 0,128,8,116,97,98,111,114,100,101,114,2,12,8,98,111,117,110,100,115, + 95,120,2,109,8,98,111,117,110,100,115,95,121,3,140,0,9,98,111,117, + 110,100,115,95,99,120,3,134,0,9,98,111,117,110,100,115,95,99,121,2, + 20,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112, + 116,105,111,110,13,97,115,95,108,111,99,97,108,99,111,108,111,114,17,97, + 115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,7,99,97, + 112,116,105,111,110,6,17,83,104,111,119,32,99,111,109,109,97,110,100,32, + 108,105,110,101,9,111,110,101,120,101,99,117,116,101,7,24,115,104,111,119, + 99,111,109,109,97,110,100,108,105,110,101,111,110,101,120,101,99,117,116,101, + 0,0,13,116,102,105,108,101,110,97,109,101,101,100,105,116,17,109,101,115, + 115,97,103,101,111,117,116,112,117,116,102,105,108,101,13,111,112,116,105,111, + 110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111, + 99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97, + 114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111, + 99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111, + 117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 0,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,20,77,101,115, + 115,97,103,101,32,38,111,117,116,112,117,116,32,102,105,108,101,19,102,114, + 97,109,101,46,99,97,112,116,105,111,110,111,102,102,115,101,116,2,3,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117, + 115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100, + 105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101, + 100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,97,99,116,105,118,101,0,19,102,114,97,109,101,46,98,117,116,116, + 111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117, + 116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4, + 2,0,0,128,7,105,109,97,103,101,110,114,2,17,0,0,18,102,114,97, + 109,101,46,98,117,116,116,111,110,46,99,111,108,111,114,4,2,0,0,128, + 20,102,114,97,109,101,46,98,117,116,116,111,110,46,105,109,97,103,101,110, + 114,2,17,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101, + 1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2, + 5,10,111,110,115,104,111,119,104,105,110,116,7,18,104,105,110,116,101,120, + 112,97,110,100,101,100,109,97,99,114,111,115,7,101,110,97,98,108,101,100, + 8,8,98,111,117,110,100,115,95,120,3,202,1,8,98,111,117,110,100,115, + 95,121,2,43,9,98,111,117,110,100,115,95,99,120,3,115,1,9,98,111, + 117,110,100,115,95,99,121,2,37,7,97,110,99,104,111,114,115,11,6,97, + 110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,9,116,101,120,116, + 102,108,97,103,115,11,12,116,102,95,121,99,101,110,116,101,114,101,100,11, + 116,102,95,110,111,115,101,108,101,99,116,14,116,102,95,101,108,108,105,112, + 115,101,108,101,102,116,0,24,99,111,110,116,114,111,108,108,101,114,46,111, + 110,103,101,116,102,105,108,101,110,97,109,101,7,14,101,120,112,97,110,100, + 102,105,108,101,110,97,109,101,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,14,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,12, + 99,111,112,121,109,101,115,115,97,103,101,115,13,102,114,97,109,101,46,99, + 97,112,116,105,111,110,6,22,67,111,112,121,32,109,101,115,115,97,103,101, + 115,32,116,111,32,38,102,105,108,101,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101, + 100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109, + 111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,1,3,140,0,2,2,0,8,116,97,98,111,114,100,101,114,2,9,8, + 98,111,117,110,100,115,95,120,3,95,1,8,98,111,117,110,100,115,95,121, + 2,99,9,98,111,117,110,100,115,95,99,120,3,153,0,9,98,111,117,110, + 100,115,95,99,121,2,16,8,111,110,99,104,97,110,103,101,7,18,99,111, + 112,121,109,101,115,115,97,103,101,99,104,97,110,103,101,100,0,0,12,116, + 98,111,111,108,101,97,110,101,100,105,116,13,99,108,111,115,101,109,101,115, + 115,97,103,101,115,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 35,67,108,111,115,101,32,109,101,115,115,97,103,101,115,32,119,105,110,100, + 111,119,32,97,102,116,101,114,32,99,111,109,112,105,108,101,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97, + 98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97, + 99,116,105,118,101,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,1,3,240,0,2,2,0,8,116,97,98,111,114, + 100,101,114,2,14,8,98,111,117,110,100,115,95,120,3,1,1,8,98,111, + 117,110,100,115,95,121,3,151,0,9,98,111,117,110,100,115,95,99,120,3, + 253,0,9,98,111,117,110,100,115,95,99,121,2,16,5,118,97,108,117,101, + 9,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,12,99,104,101, + 99,107,109,101,116,104,111,100,115,13,102,114,97,109,101,46,99,97,112,116, + 105,111,110,6,20,67,104,101,99,107,32,109,101,116,104,111,100,32,104,101, + 97,100,101,114,115,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101, + 102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112, + 19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116, + 20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111, + 109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116, + 105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,16,102,114,97,109, + 101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,3,149,0, + 2,2,0,8,116,97,98,111,114,100,101,114,2,13,8,98,111,117,110,100, + 115,95,120,3,1,1,8,98,111,117,110,100,115,95,121,3,135,0,9,98, + 111,117,110,100,115,95,99,120,3,162,0,9,98,111,117,110,100,115,95,99, + 121,2,16,5,118,97,108,117,101,9,0,0,10,116,116,97,98,119,105,100, + 103,101,116,12,109,97,107,101,103,114,111,117,112,98,111,120,13,111,112,116, + 105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101, + 102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119, + 95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119, + 102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117, + 115,111,117,116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,14,111,112,116,105, + 111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116, + 103,108,121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111, + 115,99,97,108,101,0,8,98,111,117,110,100,115,95,120,2,0,8,98,111, + 117,110,100,115,95,121,3,187,0,9,98,111,117,110,100,115,95,99,120,3, + 62,3,9,98,111,117,110,100,115,95,99,121,3,89,1,7,97,110,99,104, + 111,114,115,11,6,97,110,95,116,111,112,9,97,110,95,98,111,116,116,111, + 109,0,8,116,97,98,111,114,100,101,114,2,15,15,97,99,116,105,118,101, + 112,97,103,101,105,110,100,101,120,2,1,20,116,97,98,95,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99, + 108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,97,99,116,105,118,101,15,102,114,108,95,111,112, + 116,105,111,110,115,115,107,105,110,0,21,116,97,98,95,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98, + 108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99, + 116,105,118,101,0,19,116,97,98,95,102,97,99,101,46,108,111,99,97,108, + 112,114,111,112,115,11,20,102,97,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,0,9,116,97,98,95,99,111,108,111,114,4,3, + 0,0,128,8,116,97,98,95,115,105,122,101,2,19,8,115,116,97,116,102, + 105,108,101,7,9,115,116,97,116,102,105,108,101,49,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,14,0,8,116,116,97,98,112,97,103,101, + 10,116,116,97,98,112,97,103,101,49,55,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2, + 3,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95, + 121,2,19,9,98,111,117,110,100,115,95,99,120,3,62,3,9,98,111,117, + 110,100,115,95,99,121,3,70,1,7,97,110,99,104,111,114,115,11,7,97, + 110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,9,97,110,95,98,111,116,116,111,109,0,7,99,97,112,116,105,111, + 110,6,14,67,111,109,109,97,110,100,32,98,101,102,111,114,101,0,11,116, + 119,105,100,103,101,116,103,114,105,100,14,98,101,102,99,111,109,109,97,110, + 100,103,114,105,100,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119, + 95,102,111,99,117,115,98,97,99,107,111,110,101,115,99,13,111,119,95,109, + 111,117,115,101,119,104,101,101,108,17,111,119,95,100,101,115,116,114,111,121, + 119,105,100,103,101,116,115,0,5,99,111,108,111,114,4,3,0,0,128,19, + 102,114,97,109,101,46,99,97,112,116,105,111,110,111,102,102,115,101,116,2, + 3,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109, + 111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99, + 107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,97,99,116,105,118,101,0,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,3,70,1,12, + 98,111,117,110,100,115,95,99,121,109,105,110,2,40,7,97,110,99,104,111, + 114,115,11,0,11,111,112,116,105,111,110,115,103,114,105,100,11,15,111,103, + 95,107,101,121,114,111,119,109,111,118,105,110,103,15,111,103,95,114,111,119, + 105,110,115,101,114,116,105,110,103,14,111,103,95,114,111,119,100,101,108,101, + 116,105,110,103,23,111,103,95,115,101,108,101,99,116,101,100,114,111,119,115, + 100,101,108,101,116,105,110,103,19,111,103,95,102,111,99,117,115,99,101,108, + 108,111,110,101,110,116,101,114,15,111,103,95,97,117,116,111,102,105,114,115, + 116,114,111,119,13,111,103,95,97,117,116,111,97,112,112,101,110,100,10,111, + 103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112, + 117,112,0,13,102,105,120,114,111,119,115,46,99,111,117,110,116,2,1,13, + 102,105,120,114,111,119,115,46,105,116,101,109,115,14,1,6,104,101,105,103, + 104,116,2,16,14,99,97,112,116,105,111,110,115,46,99,111,117,110,116,2, + 7,14,99,97,112,116,105,111,110,115,46,105,116,101,109,115,14,1,7,99, + 97,112,116,105,111,110,6,1,77,4,104,105,110,116,6,11,85,115,101,32, + 105,110,32,77,97,107,101,0,1,7,99,97,112,116,105,111,110,6,1,66, + 4,104,105,110,116,6,12,85,115,101,32,105,110,32,66,117,105,108,100,0, + 1,7,99,97,112,116,105,111,110,6,1,49,4,104,105,110,116,6,13,85, + 115,101,32,105,110,32,77,97,107,101,32,49,0,1,7,99,97,112,116,105, + 111,110,6,1,50,4,104,105,110,116,6,13,85,115,101,32,105,110,32,77, + 97,107,101,32,50,0,1,7,99,97,112,116,105,111,110,6,1,51,4,104, + 105,110,116,6,13,85,115,101,32,105,110,32,77,97,107,101,32,51,0,1, + 7,99,97,112,116,105,111,110,6,1,52,4,104,105,110,116,6,13,85,115, + 101,32,105,110,32,77,97,107,101,32,52,0,1,7,99,97,112,116,105,111, + 110,6,7,67,111,109,109,97,110,100,0,0,0,0,14,100,97,116,97,99, + 111,108,115,46,99,111,117,110,116,2,7,16,100,97,116,97,99,111,108,115, + 46,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99, + 117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111, + 95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115, + 101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116, + 12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97,118, + 101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111, + 95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99, + 114,111,108,108,114,111,119,0,14,100,97,116,97,99,111,108,115,46,105,116, + 101,109,115,14,7,9,98,101,102,109,97,107,101,111,110,1,5,119,105,100, + 116,104,2,13,7,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97, + 119,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99, + 116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95, + 107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101, + 108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111, + 95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112, + 121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117, + 115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110, + 97,109,101,6,9,98,101,102,109,97,107,101,111,110,9,100,97,116,97,99, + 108,97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97, + 116,97,108,105,115,116,0,7,10,98,101,102,98,117,105,108,100,111,110,1, + 5,119,105,100,116,104,2,13,7,111,112,116,105,111,110,115,11,12,99,111, + 95,100,114,97,119,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115, + 101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116, + 12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108, + 116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99, + 116,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97, + 110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111, + 95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100, + 103,101,116,110,97,109,101,6,10,98,101,102,98,117,105,108,100,111,110,9, + 100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100,105,110,116,101, + 103,101,114,100,97,116,97,108,105,115,116,0,7,10,98,101,102,109,97,107, + 101,49,111,110,1,5,119,105,100,116,104,2,13,7,111,112,116,105,111,110, + 115,11,12,99,111,95,100,114,97,119,102,111,99,117,115,14,99,111,95,102, + 111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115, + 101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99, + 111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119, + 115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116,97,116,101,10, + 99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115, + 116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119, + 0,10,119,105,100,103,101,116,110,97,109,101,6,10,98,101,102,109,97,107, + 101,49,111,110,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105, + 100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,10,98, + 101,102,109,97,107,101,50,111,110,1,5,119,105,100,116,104,2,13,7,111, + 112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117,115, + 14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109, + 111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108, + 101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99, + 111,95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,115, + 116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99, + 97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111, + 108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,10,98, + 101,102,109,97,107,101,50,111,110,9,100,97,116,97,99,108,97,115,115,7, + 20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115, + 116,0,7,10,98,101,102,109,97,107,101,51,111,110,1,5,119,105,100,116, + 104,2,13,7,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119, + 102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116, + 14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107, + 101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108, + 101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111,95, + 115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121, + 11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115, + 101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97, + 109,101,6,10,98,101,102,109,97,107,101,51,111,110,9,100,97,116,97,99, + 108,97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97, + 116,97,108,105,115,116,0,7,10,98,101,102,109,97,107,101,52,111,110,1, + 5,119,105,100,116,104,2,13,7,111,112,116,105,111,110,115,11,12,99,111, + 95,100,114,97,119,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115, + 101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116, + 12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108, + 116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99, + 116,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97, + 110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111, + 95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100, + 103,101,116,110,97,109,101,6,10,98,101,102,109,97,107,101,52,111,110,9, + 100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100,105,110,116,101, + 103,101,114,100,97,116,97,108,105,115,116,0,7,10,98,101,102,99,111,109, + 109,97,110,100,1,5,119,105,100,116,104,3,229,2,7,111,112,116,105,111, + 110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99, + 111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121, + 115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99, + 116,12,99,111,95,114,111,119,115,101,108,101,99,116,7,99,111,95,102,105, + 108,108,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111,95,115, + 97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11, + 99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101, + 115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109, + 101,6,10,98,101,102,99,111,109,109,97,110,100,9,100,97,116,97,99,108, + 97,115,115,7,22,116,103,114,105,100,109,115,101,115,116,114,105,110,103,100, + 97,116,97,108,105,115,116,0,0,13,100,97,116,97,114,111,119,104,101,105, + 103,104,116,2,16,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,12,116,98,111,111,108,101,97,110,101,100,105,116,9,98,101,102,109, + 97,107,101,111,110,3,84,97,103,2,1,11,111,112,116,105,111,110,115,115, + 107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110, + 111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117, + 110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,121,2,16,11,111,112,116,105,111,110,115,101,100, + 105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95, + 99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109, + 114,99,97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117,114,110, + 20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105, + 116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101, + 95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115, + 101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,12,111, + 112,116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116, + 111,112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120, + 101,99,117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0, + 7,118,105,115,105,98,108,101,8,12,118,97,108,117,101,100,101,102,97,117, + 108,116,9,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,10,98, + 101,102,98,117,105,108,100,111,110,3,84,97,103,2,2,11,111,112,116,105, + 111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117, + 116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,2, + 8,98,111,117,110,100,115,95,120,2,14,8,98,111,117,110,100,115,95,121, + 2,0,9,98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105,111, + 110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99, + 13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104, + 101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114,101, + 116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111, + 110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111, + 114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97, + 117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99, + 107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101,49, + 95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95,107, + 101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115,116, + 97,116,101,0,7,118,105,115,105,98,108,101,8,12,118,97,108,117,101,100, + 101,102,97,117,108,116,9,0,0,12,116,98,111,111,108,101,97,110,101,100, + 105,116,10,98,101,102,109,97,107,101,49,111,110,3,84,97,103,2,4,11, + 111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97, + 109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100, + 101,114,2,3,8,98,111,117,110,100,115,95,120,2,28,8,98,111,117,110, + 100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,121,2,16,11,111, + 112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111, + 110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111, + 101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101, + 97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108, + 101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99, + 117,114,115,111,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25, + 111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116, + 99,108,105,99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11, + 17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111, + 101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97, + 118,101,115,116,97,116,101,0,7,118,105,115,105,98,108,101,8,12,118,97, + 108,117,101,100,101,102,97,117,108,116,9,0,0,12,116,98,111,111,108,101, + 97,110,101,100,105,116,10,98,101,102,109,97,107,101,50,111,110,3,84,97, + 103,2,8,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107, + 95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97, + 98,111,114,100,101,114,2,4,8,98,111,117,110,100,115,95,120,2,42,8, + 98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,121, + 2,16,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117, + 110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101, + 114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12, + 111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101, + 116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105, + 116,111,110,99,117,114,115,111,114,13,111,101,95,97,117,116,111,115,101,108, + 101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102, + 105,114,115,116,99,108,105,99,107,0,12,111,112,116,105,111,110,115,101,100, + 105,116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101, + 110,117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101, + 49,95,115,97,118,101,115,116,97,116,101,0,7,118,105,115,105,98,108,101, + 8,12,118,97,108,117,101,100,101,102,97,117,108,116,9,0,0,12,116,98, + 111,111,108,101,97,110,101,100,105,116,10,98,101,102,109,97,107,101,51,111, + 110,3,84,97,103,2,16,11,111,112,116,105,111,110,115,115,107,105,110,11, + 19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121, + 0,8,116,97,98,111,114,100,101,114,2,5,8,98,111,117,110,100,115,95, + 120,2,56,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100, + 115,95,99,121,2,16,11,111,112,116,105,111,110,115,101,100,105,116,11,12, + 111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115, + 101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110, + 99,101,108,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95, + 114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101, + 95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,97,117,116, + 111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99, + 116,111,110,102,105,114,115,116,99,108,105,99,107,0,12,111,112,116,105,111, + 110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112,111,112, + 117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99,117,116, + 101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0,7,118,105,115, + 105,98,108,101,8,12,118,97,108,117,101,100,101,102,97,117,108,116,9,0, + 0,12,116,98,111,111,108,101,97,110,101,100,105,116,10,98,101,102,109,97, + 107,101,52,111,110,3,84,97,103,2,32,11,111,112,116,105,111,110,115,115, + 107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110, + 111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,6,8,98,111,117, + 110,100,115,95,120,2,70,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,121,2,16,11,111,112,116,105,111,110,115,101,100, + 105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95, + 99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109, + 114,99,97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117,114,110, + 20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105, + 116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101, + 95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115, + 101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,12,111, + 112,116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116, + 111,112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120, + 101,99,117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0, + 7,118,105,115,105,98,108,101,8,12,118,97,108,117,101,100,101,102,97,117, + 108,116,9,0,0,15,116,109,101,109,111,100,105,97,108,111,103,101,100,105, + 116,10,98,101,102,99,111,109,109,97,110,100,13,111,112,116,105,111,110,115, + 119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117, + 115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114, + 111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117, + 115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116, + 17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,11, + 111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97, + 109,101,98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46, + 108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114, + 99,108,105,101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111, + 15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,19,102,114, + 97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1,19, + 102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14, + 1,5,99,111,108,111,114,4,5,0,0,144,7,105,109,97,103,101,110,114, + 2,17,0,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111, + 108,111,114,4,5,0,0,144,20,102,114,97,109,101,46,98,117,116,116,111, + 110,46,105,109,97,103,101,110,114,2,17,8,116,97,98,111,114,100,101,114, + 2,7,10,111,110,115,104,111,119,104,105,110,116,7,18,104,105,110,116,101, + 120,112,97,110,100,101,100,109,97,99,114,111,115,7,118,105,115,105,98,108, + 101,8,8,98,111,117,110,100,115,95,120,2,84,8,98,111,117,110,100,115, + 95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,229,2,9,98,111, + 117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105, + 116,49,11,13,111,101,49,95,115,97,118,101,118,97,108,117,101,0,11,111, + 112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111, + 110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111, + 101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101, + 97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108, + 101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99, + 117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13, + 111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116, + 111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,0, + 8,116,116,97,98,112,97,103,101,10,116,116,97,98,112,97,103,101,49,50, + 14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49, + 95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,13,111,119,49, + 95,97,117,116,111,115,99,97,108,101,0,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,16,111,119,95,97,114,114,111,119,102,111,99,117,115, + 111,117,116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95,100, + 101,115,116,114,111,121,119,105,100,103,101,116,115,0,5,99,111,108,111,114, + 4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101, + 102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112, + 19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116, + 20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111, + 109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116, + 105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,15,102,97,99,101, + 46,108,111,99,97,108,112,114,111,112,115,11,20,102,97,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,0,8,116,97,98,111,114, + 100,101,114,2,2,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,2,19,9,98,111,117,110,100,115,95,99,120,3,62,3, + 9,98,111,117,110,100,115,95,99,121,3,70,1,7,97,110,99,104,111,114, + 115,11,7,97,110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110, + 95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,7,99,97, + 112,116,105,111,110,6,12,77,97,107,101,32,111,112,116,105,111,110,115,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,11,116,119,105, + 100,103,101,116,103,114,105,100,15,109,97,107,101,111,112,116,105,111,110,115, + 103,114,105,100,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13, + 111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98, + 102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,16, + 111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95, + 102,111,99,117,115,98,97,99,107,111,110,101,115,99,13,111,119,95,109,111, + 117,115,101,119,104,101,101,108,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,0,5,99,111,108,111,114,4,3,0,0,128,19,102, + 114,97,109,101,46,99,97,112,116,105,111,110,111,102,102,115,101,116,2,3, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111, + 117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107, + 101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,97,99,116,105,118,101,0,8,98,111,117,110,100,115,95,120,2, + 0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,3,70,1,12,98, + 111,117,110,100,115,95,99,121,109,105,110,2,40,7,97,110,99,104,111,114, + 115,11,0,11,111,112,116,105,111,110,115,103,114,105,100,11,12,111,103,95, + 99,111,108,115,105,122,105,110,103,15,111,103,95,107,101,121,114,111,119,109, + 111,118,105,110,103,15,111,103,95,114,111,119,105,110,115,101,114,116,105,110, + 103,14,111,103,95,114,111,119,100,101,108,101,116,105,110,103,23,111,103,95, + 115,101,108,101,99,116,101,100,114,111,119,115,100,101,108,101,116,105,110,103, + 19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101,114, + 15,111,103,95,97,117,116,111,102,105,114,115,116,114,111,119,13,111,103,95, + 97,117,116,111,97,112,112,101,110,100,10,111,103,95,119,114,97,112,99,111, + 108,12,111,103,95,97,117,116,111,112,111,112,117,112,0,13,102,105,120,114, + 111,119,115,46,99,111,117,110,116,2,1,13,102,105,120,114,111,119,115,46, + 105,116,101,109,115,14,1,6,104,101,105,103,104,116,2,16,14,99,97,112, + 116,105,111,110,115,46,99,111,117,110,116,2,10,14,99,97,112,116,105,111, + 110,115,46,105,116,101,109,115,14,1,7,99,97,112,116,105,111,110,6,7, + 80,117,114,112,111,115,101,0,1,7,99,97,112,116,105,111,110,6,1,77, + 4,104,105,110,116,6,11,85,115,101,32,105,110,32,77,97,107,101,0,1, + 7,99,97,112,116,105,111,110,6,1,66,4,104,105,110,116,6,12,85,115, + 101,32,105,110,32,66,117,105,108,100,0,1,7,99,97,112,116,105,111,110, + 6,1,49,4,104,105,110,116,6,13,85,115,101,32,105,110,32,77,97,107, + 101,32,49,0,1,7,99,97,112,116,105,111,110,6,1,50,4,104,105,110, + 116,6,13,85,115,101,32,105,110,32,77,97,107,101,32,50,0,1,7,99, + 97,112,116,105,111,110,6,1,51,4,104,105,110,116,6,13,85,115,101,32, + 105,110,32,77,97,107,101,32,51,0,1,7,99,97,112,116,105,111,110,6, + 1,52,4,104,105,110,116,6,13,85,115,101,32,105,110,32,77,97,107,101, + 32,52,0,1,7,99,97,112,116,105,111,110,6,1,65,4,104,105,110,116, + 6,14,65,102,116,101,114,32,109,97,105,110,102,105,108,101,0,1,7,99, + 97,112,116,105,111,110,6,20,67,111,109,109,97,110,100,32,108,105,110,101, + 32,111,112,116,105,111,110,115,0,1,0,0,0,0,14,100,97,116,97,99, + 111,108,115,46,99,111,117,110,116,2,9,16,100,97,116,97,99,111,108,115, + 46,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99, + 117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111, + 95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115, + 101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116, + 12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97,118, + 101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111, + 95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99, + 114,111,108,108,114,111,119,0,14,100,97,116,97,99,111,108,115,46,105,116, + 101,109,115,14,7,14,109,97,107,101,111,112,116,112,117,114,112,111,115,101, + 1,5,119,105,100,116,104,2,57,7,111,112,116,105,111,110,115,11,12,99, + 111,95,105,110,118,105,115,105,98,108,101,14,99,111,95,102,111,99,117,115, + 115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99, + 116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117, + 108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101, + 99,116,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111,95,115, + 97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11, + 99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101, + 115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109, + 101,6,14,109,97,107,101,111,112,116,112,117,114,112,111,115,101,9,100,97, + 116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116,114, + 105,110,103,100,97,116,97,108,105,115,116,20,100,97,116,97,108,105,115,116, + 46,102,97,99,117,108,116,97,116,105,118,101,9,0,7,6,109,97,107,101, + 111,110,1,5,119,105,100,116,104,2,13,7,111,112,116,105,111,110,115,11, + 12,99,111,95,100,114,97,119,102,111,99,117,115,14,99,111,95,102,111,99, + 117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108, + 101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95, + 109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101, + 108,101,99,116,11,99,111,95,102,105,120,119,105,100,116,104,12,99,111,95, + 115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121, + 11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115, + 101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97, + 109,101,6,6,109,97,107,101,111,110,9,100,97,116,97,99,108,97,115,115, + 7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105, + 115,116,0,7,7,98,117,105,108,100,111,110,1,5,119,105,100,116,104,2, + 13,7,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111, + 99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99, + 111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121, + 115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99, + 116,12,99,111,95,114,111,119,115,101,108,101,99,116,11,99,111,95,102,105, + 120,119,105,100,116,104,12,99,111,95,115,97,118,101,115,116,97,116,101,10, + 99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115, + 116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119, + 0,10,119,105,100,103,101,116,110,97,109,101,6,7,98,117,105,108,100,111, + 110,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100,105,110, + 116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,7,109,97,107,101, + 49,111,110,1,5,119,105,100,116,104,2,13,7,111,112,116,105,111,110,115, + 11,12,99,111,95,100,114,97,119,102,111,99,117,115,14,99,111,95,102,111, + 99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101, + 108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111, + 95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115, + 101,108,101,99,116,11,99,111,95,102,105,120,119,105,100,116,104,12,99,111, + 95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112, + 121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117, + 115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110, + 97,109,101,6,7,109,97,107,101,49,111,110,9,100,97,116,97,99,108,97, + 115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97, + 108,105,115,116,0,7,7,109,97,107,101,50,111,110,1,5,119,105,100,116, + 104,2,13,7,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119, + 102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116, + 14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107, + 101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108, + 101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,11,99,111,95, + 102,105,120,119,105,100,116,104,12,99,111,95,115,97,118,101,115,116,97,116, + 101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112, + 97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114, + 111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,7,109,97,107,101, + 50,111,110,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100, + 105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,7,109,97, + 107,101,51,111,110,1,5,119,105,100,116,104,2,13,7,111,112,116,105,111, + 110,115,11,12,99,111,95,100,114,97,119,102,111,99,117,115,14,99,111,95, + 102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101, + 115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14, + 99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111, + 119,115,101,108,101,99,116,11,99,111,95,102,105,120,119,105,100,116,104,12, + 99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99, + 111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109, + 111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101, + 116,110,97,109,101,6,7,109,97,107,101,51,111,110,9,100,97,116,97,99, + 108,97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97, + 116,97,108,105,115,116,0,7,7,109,97,107,101,52,111,110,1,5,119,105, + 100,116,104,2,13,7,111,112,116,105,111,110,115,11,12,99,111,95,100,114, + 97,119,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101, + 99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111, + 95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115, + 101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,11,99, + 111,95,102,105,120,119,105,100,116,104,12,99,111,95,115,97,118,101,115,116, + 97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97, + 110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108, + 108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,7,109,97, + 107,101,52,111,110,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114, + 105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,8, + 111,112,116,97,102,116,101,114,1,5,119,105,100,116,104,2,13,7,111,112, + 116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117,115,14, + 99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111, + 117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101, + 99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111, + 95,114,111,119,115,101,108,101,99,116,11,99,111,95,102,105,120,119,105,100, + 116,104,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99, + 97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99, + 111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105, + 100,103,101,116,110,97,109,101,6,8,111,112,116,97,102,116,101,114,9,100, + 97,116,97,99,108,97,115,115,7,20,116,103,114,105,100,105,110,116,101,103, + 101,114,100,97,116,97,108,105,115,116,0,7,11,109,97,107,101,111,112,116, + 105,111,110,115,1,5,119,105,100,116,104,3,157,2,7,111,112,116,105,111, + 110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99, + 111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121, + 115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99, + 116,12,99,111,95,114,111,119,115,101,108,101,99,116,11,99,111,95,102,105, + 120,119,105,100,116,104,7,99,111,95,102,105,108,108,12,99,111,95,115,97, + 118,101,118,97,108,117,101,12,99,111,95,115,97,118,101,115,116,97,116,101, + 10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97, + 115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111, + 119,0,10,111,110,115,104,111,119,104,105,110,116,7,13,99,111,108,111,110, + 115,104,111,119,104,105,110,116,10,119,105,100,103,101,116,110,97,109,101,6, + 11,109,97,107,101,111,112,116,105,111,110,115,9,100,97,116,97,99,108,97, + 115,115,7,22,116,103,114,105,100,109,115,101,115,116,114,105,110,103,100,97, + 116,97,108,105,115,116,0,0,13,100,97,116,97,114,111,119,104,101,105,103, + 104,116,2,16,8,115,116,97,116,102,105,108,101,7,9,115,116,97,116,102, + 105,108,101,49,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,11,116,115,116,114,105,110,103,101,100,105,116,14,109,97,107,101,111,112, + 116,112,117,114,112,111,115,101,14,111,112,116,105,111,110,115,119,105,100,103, + 101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101, + 105,103,104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111, + 115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8, + 116,97,98,111,114,100,101,114,2,1,7,118,105,115,105,98,108,101,8,8, + 98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,2,57,9,98,111,117,110,100,115, + 95,99,121,2,16,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111, + 101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101, + 113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99, + 101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101, + 95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115, + 101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111, + 110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101, + 114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97, + 117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99, + 107,22,111,101,95,102,111,99,117,115,114,101,99,116,111,110,114,101,97,100, + 111,110,108,121,18,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116, + 101,120,116,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,6,109,97,107,101, + 111,110,3,84,97,103,2,1,11,111,112,116,105,111,110,115,115,107,105,110, + 11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108, + 121,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115, + 95,120,2,58,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,121,2,16,11,111,112,116,105,111,110,115,101,100,105,116,11, + 12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111, + 115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97, + 110,99,101,108,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101, + 95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111, + 101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,97,117, + 116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101, + 99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,12,111,112,116,105, + 111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112,111, + 112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99,117, + 116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0,7,118,105, + 115,105,98,108,101,8,12,118,97,108,117,101,100,101,102,97,117,108,116,9, + 0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,7,98,117,105,108, + 100,111,110,3,84,97,103,2,2,11,111,112,116,105,111,110,115,115,107,105, + 110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110, + 108,121,0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117,110,100, + 115,95,120,2,72,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,121,2,16,11,111,112,116,105,111,110,115,101,100,105,116, + 11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108, + 111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99, + 97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111, + 101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15, + 111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,97, + 117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108, + 101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,12,111,112,116, + 105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112, + 111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99, + 117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0,7,118, + 105,115,105,98,108,101,8,12,118,97,108,117,101,100,101,102,97,117,108,116, + 9,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,7,109,97,107, + 101,49,111,110,3,84,97,103,2,4,11,111,112,116,105,111,110,115,115,107, + 105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111, + 110,108,121,0,8,116,97,98,111,114,100,101,114,2,4,8,98,111,117,110, + 100,115,95,120,2,86,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,121,2,16,11,111,112,116,105,111,110,115,101,100,105, + 116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99, + 108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114, + 99,97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117,114,110,20, + 111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116, + 15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95, + 97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101, + 108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,12,111,112, + 116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111, + 112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101, + 99,117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0,7, + 118,105,115,105,98,108,101,8,12,118,97,108,117,101,100,101,102,97,117,108, + 116,9,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,7,109,97, + 107,101,50,111,110,3,84,97,103,2,8,11,111,112,116,105,111,110,115,115, + 107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110, + 111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,5,8,98,111,117, + 110,100,115,95,120,2,100,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,121,2,16,11,111,112,116,105,111,110,115,101,100, + 105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95, + 99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109, + 114,99,97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117,114,110, + 20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105, + 116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101, + 95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115, + 101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,12,111, + 112,116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116, + 111,112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120, + 101,99,117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0, + 7,118,105,115,105,98,108,101,8,12,118,97,108,117,101,100,101,102,97,117, + 108,116,9,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,7,109, + 97,107,101,51,111,110,3,84,97,103,2,16,11,111,112,116,105,111,110,115, + 115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111, + 110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,6,8,98,111, + 117,110,100,115,95,120,2,114,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105,111,110,115,101, + 100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101, + 95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107, + 109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117,114, + 110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120, + 105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111, + 101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111, + 115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,12, + 111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117, + 116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101, + 120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101, + 0,7,118,105,115,105,98,108,101,8,12,118,97,108,117,101,100,101,102,97, + 117,108,116,9,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,7, + 109,97,107,101,52,111,110,3,84,97,103,2,32,11,111,112,116,105,111,110, + 115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116, + 111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,7,8,98, + 111,117,110,100,115,95,120,3,128,0,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105,111,110, + 115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13, + 111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101, + 99,107,109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114,101,116, + 117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110, + 101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114, + 13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117, + 116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107, + 0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95, + 97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101, + 121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115,116,97, + 116,101,0,7,118,105,115,105,98,108,101,8,12,118,97,108,117,101,100,101, + 102,97,117,108,116,9,0,0,12,116,98,111,111,108,101,97,110,101,100,105, + 116,8,111,112,116,97,102,116,101,114,3,84,97,103,4,0,0,0,64,14, + 111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,0,11,111,112,116, + 105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98, + 117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2, + 8,8,98,111,117,110,100,115,95,120,3,142,0,8,98,111,117,110,100,115, + 95,121,2,0,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116, + 105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112, + 111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99, + 117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,27,111,101, + 49,95,99,104,101,99,107,118,97,108,117,101,97,102,116,101,114,115,116,97, + 116,114,101,97,100,0,7,118,105,115,105,98,108,101,8,0,0,15,116,109, + 101,109,111,100,105,97,108,111,103,101,100,105,116,11,109,97,107,101,111,112, + 116,105,111,110,115,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,11,111,112,116,105,111,110,115, + 115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111, + 110,111,110,108,121,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111, + 108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,19,102,114,97,109,101,46,98,117,116, + 116,111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98, + 117,116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114, + 4,5,0,0,144,7,105,109,97,103,101,110,114,2,17,0,0,18,102,114, + 97,109,101,46,98,117,116,116,111,110,46,99,111,108,111,114,4,5,0,0, + 144,20,102,114,97,109,101,46,98,117,116,116,111,110,46,105,109,97,103,101, + 110,114,2,17,8,116,97,98,111,114,100,101,114,2,9,10,111,110,115,104, + 111,119,104,105,110,116,7,18,104,105,110,116,101,120,112,97,110,100,101,100, + 109,97,99,114,111,115,7,118,105,115,105,98,108,101,8,8,98,111,117,110, + 100,115,95,120,3,156,0,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,120,3,157,2,9,98,111,117,110,100,115,95,99, + 121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,13,111,101, + 49,95,115,97,118,101,118,97,108,117,101,0,11,111,112,116,105,111,110,115, + 101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111, + 101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99, + 107,109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117, + 114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101, + 120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13, + 111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116, + 111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99, + 116,111,110,102,105,114,115,116,99,108,105,99,107,0,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,14,0,0,0,0,8,116,116,97,98,112, + 97,103,101,10,116,116,97,98,112,97,103,101,49,49,14,111,112,116,105,111, + 110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103, + 108,121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115, + 99,97,108,101,0,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98, + 102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,5,99,111,108,111,114,4,3,0,0,128,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99, + 108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98, + 108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99, + 116,105,118,101,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117, + 110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,19,9,98, + 111,117,110,100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95,99, + 121,3,70,1,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102, + 116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,9,97,110, + 95,98,111,116,116,111,109,0,7,99,97,112,116,105,111,110,6,11,68,105, + 114,101,99,116,111,114,105,101,115,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,14,0,11,116,119,105,100,103,101,116,103,114,105,100,11,117, + 110,105,116,100,105,114,103,114,105,100,13,111,112,116,105,111,110,115,119,105, + 100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11, + 111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119, + 102,111,99,117,115,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111, + 117,116,17,111,119,95,102,111,99,117,115,98,97,99,107,111,110,101,115,99, + 13,111,119,95,109,111,117,115,101,119,104,101,101,108,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,0,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,38,85,110,105,116,44,32,105,110,99,108,117, + 100,101,32,97,110,100,32,108,105,98,114,97,114,121,32,38,100,105,114,101, + 99,116,111,114,105,101,115,22,102,114,97,109,101,46,99,97,112,116,105,111, + 110,116,101,120,116,102,108,97,103,115,11,9,116,102,95,98,111,116,116,111, + 109,0,19,102,114,97,109,101,46,99,97,112,116,105,111,110,111,102,102,115, + 101,116,2,3,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102, + 116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109, + 20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101, + 116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105, + 118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99, + 108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,97,99,116,105,118,101,0,16,102,114,97,109,101, + 46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0, + 0,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95, + 121,2,46,9,98,111,117,110,100,115,95,99,120,3,62,3,9,98,111,117, + 110,100,115,95,99,121,3,24,1,12,98,111,117,110,100,115,95,99,121,109, + 105,110,2,40,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112, + 9,97,110,95,98,111,116,116,111,109,0,11,111,112,116,105,111,110,115,103, + 114,105,100,11,15,111,103,95,107,101,121,114,111,119,109,111,118,105,110,103, + 15,111,103,95,114,111,119,105,110,115,101,114,116,105,110,103,14,111,103,95, + 114,111,119,100,101,108,101,116,105,110,103,23,111,103,95,115,101,108,101,99, + 116,101,100,114,111,119,115,100,101,108,101,116,105,110,103,19,111,103,95,102, + 111,99,117,115,99,101,108,108,111,110,101,110,116,101,114,15,111,103,95,97, + 117,116,111,102,105,114,115,116,114,111,119,13,111,103,95,97,117,116,111,97, + 112,112,101,110,100,10,111,103,95,119,114,97,112,99,111,108,12,111,103,95, + 97,117,116,111,112,111,112,117,112,0,13,102,105,120,114,111,119,115,46,99, + 111,117,110,116,2,1,13,102,105,120,114,111,119,115,46,105,116,101,109,115, + 14,1,6,104,101,105,103,104,116,2,16,14,99,97,112,116,105,111,110,115, + 46,99,111,117,110,116,2,11,14,99,97,112,116,105,111,110,115,46,105,116, + 101,109,115,14,1,7,99,97,112,116,105,111,110,6,1,77,4,104,105,110, + 116,6,11,85,115,101,32,105,110,32,77,97,107,101,0,1,7,99,97,112, + 116,105,111,110,6,1,66,4,104,105,110,116,6,12,85,115,101,32,105,110, + 32,66,117,105,108,100,0,1,7,99,97,112,116,105,111,110,6,1,49,4, + 104,105,110,116,6,13,85,115,101,32,105,110,32,77,97,107,101,32,49,0, + 1,7,99,97,112,116,105,111,110,6,1,50,4,104,105,110,116,6,13,85, + 115,101,32,105,110,32,77,97,107,101,32,50,0,1,7,99,97,112,116,105, + 111,110,6,1,51,4,104,105,110,116,6,13,85,115,101,32,105,110,32,77, + 97,107,101,32,51,0,1,7,99,97,112,116,105,111,110,6,1,52,4,104, + 105,110,116,6,13,85,115,101,32,105,110,32,77,97,107,101,32,52,0,1, + 7,99,97,112,116,105,111,110,6,1,85,4,104,105,110,116,6,28,65,100, + 100,32,116,111,32,117,110,105,116,32,102,105,108,101,32,115,101,97,114,99, + 104,32,112,97,116,104,0,1,7,99,97,112,116,105,111,110,6,1,73,4, + 104,105,110,116,6,31,65,100,100,32,116,111,32,105,110,99,108,117,100,101, + 32,102,105,108,101,32,115,101,97,114,99,104,32,112,97,116,104,0,1,7, + 99,97,112,116,105,111,110,6,1,76,4,104,105,110,116,6,26,65,100,100, + 32,116,111,32,108,105,98,114,97,114,121,32,115,101,97,114,99,104,32,112, + 97,116,104,0,1,7,99,97,112,116,105,111,110,6,1,79,4,104,105,110, + 116,6,30,65,100,100,32,116,111,32,111,98,106,101,99,116,32,102,105,108, + 101,32,115,101,97,114,99,104,32,112,97,116,104,0,1,7,99,97,112,116, + 105,111,110,6,9,68,105,114,101,99,116,111,114,121,0,0,0,0,14,100, + 97,116,97,99,111,108,115,46,99,111,117,110,116,2,11,14,100,97,116,97, + 99,111,108,115,46,119,105,100,116,104,2,13,16,100,97,116,97,99,111,108, + 115,46,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111, + 99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99, + 111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121, + 115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99, + 116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97, + 118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99, + 111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115, + 99,114,111,108,108,114,111,119,0,14,100,97,116,97,99,111,108,115,46,105, + 116,101,109,115,14,7,7,100,109,97,107,101,111,110,1,5,119,105,100,116, + 104,2,13,7,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119, + 102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116, + 14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107, + 101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108, + 101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111,95, + 115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121, + 11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115, + 101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97, + 109,101,6,7,100,109,97,107,101,111,110,9,100,97,116,97,99,108,97,115, + 115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108, + 105,115,116,0,7,8,100,98,117,105,108,100,111,110,1,5,119,105,100,116, + 104,2,13,7,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119, + 102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116, + 14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107, + 101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108, + 101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111,95, + 115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121, + 11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115, + 101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97, + 109,101,6,8,100,98,117,105,108,100,111,110,9,100,97,116,97,99,108,97, + 115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97, + 108,105,115,116,0,7,8,100,109,97,107,101,49,111,110,1,5,119,105,100, + 116,104,2,13,7,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97, + 119,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99, + 116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95, + 107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101, + 108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111, + 95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112, + 121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117, + 115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110, + 97,109,101,6,8,100,109,97,107,101,49,111,110,9,100,97,116,97,99,108, + 97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116, + 97,108,105,115,116,0,7,8,100,109,97,107,101,50,111,110,1,5,119,105, + 100,116,104,2,13,7,111,112,116,105,111,110,115,11,12,99,111,95,100,114, + 97,119,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101, + 99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111, + 95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115, + 101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99, + 111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111, + 112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111, + 117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116, + 110,97,109,101,6,8,100,109,97,107,101,50,111,110,9,100,97,116,97,99, + 108,97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97, + 116,97,108,105,115,116,0,7,8,100,109,97,107,101,51,111,110,1,5,119, + 105,100,116,104,2,13,7,111,112,116,105,111,110,115,11,12,99,111,95,100, + 114,97,119,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108, + 101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99, + 111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105, + 115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12, + 99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99, + 111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109, + 111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101, + 116,110,97,109,101,6,8,100,109,97,107,101,51,111,110,9,100,97,116,97, + 99,108,97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100, + 97,116,97,108,105,115,116,0,7,8,100,109,97,107,101,52,111,110,1,9, + 108,105,110,101,119,105,100,116,104,2,2,12,108,105,110,101,99,111,108,111, + 114,102,105,120,4,3,0,0,160,5,119,105,100,116,104,2,13,7,111,112, + 116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117,115,14, + 99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111, + 117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101, + 99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111, + 95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116, + 97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97, + 110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108, + 108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,8,100,109, + 97,107,101,52,111,110,9,100,97,116,97,99,108,97,115,115,7,20,116,103, + 114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,7, + 7,100,117,110,105,116,111,110,1,5,119,105,100,116,104,2,13,7,111,112, + 116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117,115,14, + 99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111, + 117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101, + 99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111, + 95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116, + 97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97, + 110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108, + 108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,7,100,117, + 110,105,116,111,110,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114, + 105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,10, + 100,105,110,99,108,117,100,101,111,110,1,5,119,105,100,116,104,2,13,7, + 111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117, + 115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95, + 109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101, + 108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12, + 99,111,95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97,118,101, + 115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95, + 99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114, + 111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,10, + 100,105,110,99,108,117,100,101,111,110,9,100,97,116,97,99,108,97,115,115, + 7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105, + 115,116,0,7,6,100,108,105,98,111,110,1,5,119,105,100,116,104,2,13, + 7,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99, + 117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111, + 95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115, + 101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116, + 12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97,118, + 101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111, + 95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99, + 114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6, + 6,100,108,105,98,111,110,9,100,97,116,97,99,108,97,115,115,7,20,116, + 103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0, + 7,6,100,111,98,106,111,110,1,5,119,105,100,116,104,2,13,7,111,112, + 116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117,115,14, + 99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111, + 117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101, + 99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111, + 95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116, + 97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97, + 110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108, + 108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,6,100,111, + 98,106,111,110,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105, + 100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,8,117, + 110,105,116,100,105,114,115,1,12,108,105,110,101,99,111,108,111,114,102,105, + 120,4,3,0,0,160,5,119,105,100,116,104,3,172,2,7,111,112,116,105, + 111,110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14, + 99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101, + 121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101, + 99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,7,99,111,95,102, + 105,108,108,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111,95, + 115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121, + 11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115, + 101,115,99,114,111,108,108,114,111,119,0,10,111,110,115,104,111,119,104,105, + 110,116,7,13,99,111,108,111,110,115,104,111,119,104,105,110,116,10,119,105, + 100,103,101,116,110,97,109,101,6,8,117,110,105,116,100,105,114,115,9,100, + 97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116, + 114,105,110,103,100,97,116,97,108,105,115,116,0,0,13,100,97,116,97,114, + 111,119,104,101,105,103,104,116,2,16,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,14,0,12,116,98,111,111,108,101,97,110,101,100,105,116, + 7,100,109,97,107,101,111,110,3,84,97,103,2,1,11,111,112,116,105,111, + 110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116, + 116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,1,8, + 98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105,111,110, + 115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13, + 111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101, + 99,107,109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114,101,116, + 117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110, + 101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114, + 13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117, + 116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107, + 0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95, + 97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101, + 121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115,116,97, + 116,101,0,7,118,105,115,105,98,108,101,8,12,118,97,108,117,101,100,101, + 102,97,117,108,116,9,0,0,12,116,98,111,111,108,101,97,110,101,100,105, + 116,8,100,98,117,105,108,100,111,110,3,84,97,103,2,2,11,111,112,116, + 105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98, + 117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2, + 2,8,98,111,117,110,100,115,95,120,2,14,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105, + 111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115, + 99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99, + 104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114, + 101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116, + 111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115, + 111,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95, + 97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105, + 99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101, + 49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95, + 107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115, + 116,97,116,101,0,7,118,105,115,105,98,108,101,8,12,118,97,108,117,101, + 100,101,102,97,117,108,116,9,0,0,12,116,98,111,111,108,101,97,110,101, + 100,105,116,8,100,109,97,107,101,49,111,110,3,84,97,103,2,4,11,111, + 112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109, + 101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101, + 114,2,3,8,98,111,117,110,100,115,95,120,2,28,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,121,2,16,11,111,112, + 116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110, + 101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101, + 95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101,97, + 116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101, + 99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117, + 114,115,111,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111, + 101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99, + 108,105,99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17, + 111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101, + 49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118, + 101,115,116,97,116,101,0,7,118,105,115,105,98,108,101,8,12,118,97,108, + 117,101,100,101,102,97,117,108,116,9,0,0,12,116,98,111,111,108,101,97, + 110,101,100,105,116,8,100,109,97,107,101,50,111,110,3,84,97,103,2,8, + 11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114, + 97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114, + 100,101,114,2,4,8,98,111,117,110,100,115,95,120,2,42,8,98,111,117, + 110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,121,2,16,11, + 111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111, + 111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16, + 111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95, + 101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101, + 108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110, + 99,117,114,115,111,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116, + 25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115, + 116,99,108,105,99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49, + 11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14, + 111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115, + 97,118,101,115,116,97,116,101,0,7,118,105,115,105,98,108,101,8,12,118, + 97,108,117,101,100,101,102,97,117,108,116,9,0,0,12,116,98,111,111,108, + 101,97,110,101,100,105,116,8,100,109,97,107,101,51,111,110,3,84,97,103, + 2,16,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95, + 102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98, + 111,114,100,101,114,2,5,8,98,111,117,110,100,115,95,120,2,56,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,121,2, + 16,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110, + 100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114, + 121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111, + 101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116, + 115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116, + 111,110,99,117,114,115,111,114,13,111,101,95,97,117,116,111,115,101,108,101, + 99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105, + 114,115,116,99,108,105,99,107,0,12,111,112,116,105,111,110,115,101,100,105, + 116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110, + 117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49, + 95,115,97,118,101,115,116,97,116,101,0,7,118,105,115,105,98,108,101,8, + 12,118,97,108,117,101,100,101,102,97,117,108,116,9,0,0,12,116,98,111, + 111,108,101,97,110,101,100,105,116,8,100,109,97,107,101,52,111,110,3,84, + 97,103,2,32,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115, + 107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116, + 97,98,111,114,100,101,114,2,6,8,98,111,117,110,100,115,95,120,2,70, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 121,2,16,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95, + 117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117, + 101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108, + 12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115, + 101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120, + 105,116,111,110,99,117,114,115,111,114,13,111,101,95,97,117,116,111,115,101, + 108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110, + 102,105,114,115,116,99,108,105,99,107,0,12,111,112,116,105,111,110,115,101, + 100,105,116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109, + 101,110,117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111, + 101,49,95,115,97,118,101,115,116,97,116,101,0,7,118,105,115,105,98,108, + 101,8,12,118,97,108,117,101,100,101,102,97,117,108,116,9,0,0,12,116, + 98,111,111,108,101,97,110,101,100,105,116,7,100,117,110,105,116,111,110,3, + 84,97,103,4,0,0,1,0,11,111,112,116,105,111,110,115,115,107,105,110, + 11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108, + 121,0,8,116,97,98,111,114,100,101,114,2,7,8,98,111,117,110,100,115, + 95,120,2,85,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,121,2,16,11,111,112,116,105,111,110,115,101,100,105,116,11, + 12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111, + 115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97, + 110,99,101,108,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101, + 95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111, + 101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,97,117, + 116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101, + 99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,12,111,112,116,105, + 111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112,111, + 112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99,117, + 116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0,7,118,105, + 115,105,98,108,101,8,12,118,97,108,117,101,100,101,102,97,117,108,116,9, + 0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,10,100,105,110,99, + 108,117,100,101,111,110,3,84,97,103,4,0,0,2,0,11,111,112,116,105, + 111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117, + 116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,8, + 8,98,111,117,110,100,115,95,120,2,99,8,98,111,117,110,100,115,95,121, + 2,0,9,98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105,111, + 110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99, + 13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104, + 101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114,101, + 116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111, + 110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111, + 114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97, + 117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99, + 107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101,49, + 95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95,107, + 101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115,116, + 97,116,101,0,7,118,105,115,105,98,108,101,8,12,118,97,108,117,101,100, + 101,102,97,117,108,116,9,0,0,12,116,98,111,111,108,101,97,110,101,100, + 105,116,6,100,108,105,98,111,110,3,84,97,103,4,0,0,4,0,11,111, + 112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109, + 101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101, + 114,2,9,8,98,111,117,110,100,115,95,120,2,113,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,121,2,16,11,111,112, + 116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110, + 101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101, + 95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101,97, + 116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101, + 99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117, + 114,115,111,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111, + 101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99, + 108,105,99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17, + 111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101, + 49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118, + 101,115,116,97,116,101,0,7,118,105,115,105,98,108,101,8,12,118,97,108, + 117,101,100,101,102,97,117,108,116,9,0,0,12,116,98,111,111,108,101,97, + 110,101,100,105,116,6,100,111,98,106,111,110,3,84,97,103,4,0,0,8, + 0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102, + 114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109, + 101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108, + 111,114,99,108,105,101,110,116,4,3,0,0,128,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101, + 108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107, + 101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,97,99,116,105,118,101,0,8,116,97,98,111,114,100,101,114,2, + 10,8,98,111,117,110,100,115,95,120,2,127,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105, + 111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115, + 99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99, + 104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114, + 101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116, + 111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115, + 111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95, + 97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101, + 108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,12,111,112, + 116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111, + 112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101, + 99,117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0,7, + 118,105,115,105,98,108,101,8,12,118,97,108,117,101,100,101,102,97,117,108, + 116,9,0,0,13,116,102,105,108,101,110,97,109,101,101,100,105,116,8,117, + 110,105,116,100,105,114,115,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95, + 116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111, + 119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100, + 101,115,116,114,111,121,119,105,100,103,101,116,115,0,11,111,112,116,105,111, + 110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116, + 116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101,118,101,108, + 111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110, + 116,4,2,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95, + 99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101, + 100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105, + 118,101,0,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111, + 117,110,116,2,1,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46, + 105,116,101,109,115,14,1,5,99,111,108,111,114,4,5,0,0,144,7,105, + 109,97,103,101,110,114,2,17,0,0,18,102,114,97,109,101,46,98,117,116, + 116,111,110,46,99,111,108,111,114,4,5,0,0,144,20,102,114,97,109,101, + 46,98,117,116,116,111,110,46,105,109,97,103,101,110,114,2,17,8,116,97, + 98,111,114,100,101,114,2,11,10,111,110,115,104,111,119,104,105,110,116,7, + 18,104,105,110,116,101,120,112,97,110,100,101,100,109,97,99,114,111,115,7, + 118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,141,0, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,3,172,2,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116, + 105,111,110,115,101,100,105,116,49,11,13,111,101,49,95,115,97,118,101,118, + 97,108,117,101,0,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111, + 101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101, + 113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99, + 101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101, + 95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115, + 101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111, + 110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101, + 114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97, + 117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99, + 107,0,18,99,111,110,116,114,111,108,108,101,114,46,111,112,116,105,111,110, + 115,11,13,102,100,111,95,100,105,114,101,99,116,111,114,121,8,102,100,111, + 95,102,105,108,101,0,26,99,111,110,116,114,111,108,108,101,114,46,104,105, + 115,116,111,114,121,109,97,120,99,111,117,110,116,2,0,22,99,111,110,116, + 114,111,108,108,101,114,46,99,97,112,116,105,111,110,111,112,101,110,6,21, + 83,101,108,101,99,116,32,117,110,105,116,32,100,105,114,101,99,116,111,114, + 121,24,99,111,110,116,114,111,108,108,101,114,46,111,110,103,101,116,102,105, + 108,101,110,97,109,101,7,14,101,120,112,97,110,100,102,105,108,101,110,97, + 109,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0, + 0,7,116,115,112,97,99,101,114,8,116,115,112,97,99,101,114,49,5,99, + 111,108,111,114,4,3,0,0,128,8,116,97,98,111,114,100,101,114,2,1, + 8,98,111,117,110,100,115,95,120,3,31,1,8,98,111,117,110,100,115,95, + 121,2,41,9,98,111,117,110,100,115,95,99,120,2,50,9,98,111,117,110, + 100,115,95,99,121,2,5,7,108,105,110,107,116,111,112,7,11,116,108,97, + 121,111,117,116,101,114,49,55,10,108,105,110,107,98,111,116,116,111,109,7, + 11,117,110,105,116,100,105,114,103,114,105,100,0,0,9,116,108,97,121,111, + 117,116,101,114,11,116,108,97,121,111,117,116,101,114,49,55,8,116,97,98, + 111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,2,0,8,98, + 111,117,110,100,115,95,121,2,4,9,98,111,117,110,100,115,95,99,120,3, + 62,3,9,98,111,117,110,100,115,95,99,121,2,37,7,97,110,99,104,111, + 114,115,11,6,97,110,95,116,111,112,0,12,111,112,116,105,111,110,115,115, + 99,97,108,101,11,11,111,115,99,95,101,120,112,97,110,100,121,11,111,115, + 99,95,115,104,114,105,110,107,121,17,111,115,99,95,101,120,112,97,110,100, + 115,104,114,105,110,107,120,17,111,115,99,95,101,120,112,97,110,100,115,104, + 114,105,110,107,121,0,13,111,112,116,105,111,110,115,108,97,121,111,117,116, + 11,10,108,97,111,95,112,108,97,99,101,120,10,108,97,111,95,97,108,105, + 103,110,121,0,10,97,108,105,103,110,95,103,108,117,101,7,9,119,97,109, + 95,115,116,97,114,116,13,112,108,97,99,101,95,109,105,110,100,105,115,116, + 2,4,13,112,108,97,99,101,95,109,97,120,100,105,115,116,2,4,0,11, + 116,115,116,114,105,110,103,101,100,105,116,7,111,98,106,112,114,101,102,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,15,79,98,106,32,112, + 114,101,102,46,32,40,45,70,111,41,22,102,114,97,109,101,46,99,97,112, + 116,105,111,110,116,101,120,116,102,108,97,103,115,11,9,116,102,95,98,111, + 116,116,111,109,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101, + 102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112, + 19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116, + 20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111, + 109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116, + 105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,16,102,114,97,109, + 101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,4,2, + 0,0,10,111,110,115,104,111,119,104,105,110,116,7,18,104,105,110,116,101, + 120,112,97,110,100,101,100,109,97,99,114,111,115,8,98,111,117,110,100,115, + 95,120,3,13,1,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,120,2,88,9,98,111,117,110,100,115,95,99,121,2,37, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,11,116, + 115,116,114,105,110,103,101,100,105,116,7,108,105,98,112,114,101,102,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,14,76,105,98,32,112,114, + 101,102,46,40,45,70,108,41,22,102,114,97,109,101,46,99,97,112,116,105, + 111,110,116,101,120,116,102,108,97,103,115,11,9,116,102,95,98,111,116,116, + 111,109,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116, + 17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101, + 116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118, + 101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108, + 105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,97,99,116,105,118,101,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0, + 8,116,97,98,111,114,100,101,114,2,1,10,111,110,115,104,111,119,104,105, + 110,116,7,18,104,105,110,116,101,120,112,97,110,100,101,100,109,97,99,114, + 111,115,8,98,111,117,110,100,115,95,120,3,181,0,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,84,9,98,111, + 117,110,100,115,95,99,121,2,37,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,14,0,0,11,116,115,116,114,105,110,103,101,100,105,116,7, + 105,110,99,112,114,101,102,13,102,114,97,109,101,46,99,97,112,116,105,111, + 110,6,14,73,110,99,32,112,114,101,102,46,40,45,70,105,41,22,102,114, + 97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115, + 11,9,116,102,95,98,111,116,116,111,109,0,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99, + 107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100, + 25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118, + 101,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,2, + 10,111,110,115,104,111,119,104,105,110,116,7,18,104,105,110,116,101,120,112, + 97,110,100,101,100,109,97,99,114,111,115,8,98,111,117,110,100,115,95,120, + 2,93,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,2,84,9,98,111,117,110,100,115,95,99,121,2,37,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,11,116,115,116,114, + 105,110,103,101,100,105,116,8,117,110,105,116,112,114,101,102,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,15,85,110,105,116,32,112,114,101, + 102,46,40,45,70,117,41,22,102,114,97,109,101,46,99,97,112,116,105,111, + 110,116,101,120,116,102,108,97,103,115,11,9,116,102,95,98,111,116,116,111, + 109,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105, + 99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,97,99,116,105,118,101,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,5,2,0,0,8, + 116,97,98,111,114,100,101,114,2,3,10,111,110,115,104,111,119,104,105,110, + 116,7,18,104,105,110,116,101,120,112,97,110,100,101,100,109,97,99,114,111, + 115,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,120,2,89,9,98,111,117,110, + 100,115,95,99,121,2,37,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,16,114, + 101,118,101,114,115,101,112,97,116,104,111,114,100,101,114,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,23,82,101,118,101,114,115,101,32,100, + 105,114,101,99,116,111,114,121,32,111,114,100,101,114,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,3,150,0,2,2, + 0,8,116,97,98,111,114,100,101,114,2,4,8,98,111,117,110,100,115,95, + 120,3,135,1,8,98,111,117,110,100,115,95,121,2,20,9,98,111,117,110, + 100,115,95,99,120,3,163,0,9,98,111,117,110,100,115,95,99,121,2,16, + 0,0,13,116,115,105,109,112,108,101,119,105,100,103,101,116,14,116,115,105, + 109,112,108,101,119,105,100,103,101,116,49,8,116,97,98,111,114,100,101,114, + 2,5,8,98,111,117,110,100,115,95,120,3,105,1,8,98,111,117,110,100, + 115,95,121,2,22,9,98,111,117,110,100,115,95,99,120,2,26,9,98,111, + 117,110,100,115,95,99,121,2,10,0,0,0,0,8,116,116,97,98,112,97, + 103,101,10,116,116,97,98,112,97,103,101,49,56,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101, + 114,2,4,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100, + 115,95,121,2,19,9,98,111,117,110,100,115,95,99,120,3,62,3,9,98, + 111,117,110,100,115,95,99,121,3,70,1,7,97,110,99,104,111,114,115,11, + 7,97,110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114, + 105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,7,99,97,112,116, + 105,111,110,6,13,67,111,109,109,97,110,100,32,97,102,116,101,114,0,11, + 116,119,105,100,103,101,116,103,114,105,100,14,97,102,116,99,111,109,109,97, + 110,100,103,114,105,100,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111, + 119,95,102,111,99,117,115,98,97,99,107,111,110,101,115,99,13,111,119,95, + 109,111,117,115,101,119,104,101,101,108,17,111,119,95,100,101,115,116,114,111, + 121,119,105,100,103,101,116,115,0,5,99,111,108,111,114,4,3,0,0,128, + 19,102,114,97,109,101,46,99,97,112,116,105,111,110,111,102,102,115,101,116, + 2,3,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105, + 99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,97,99,116,105,118,101,0,8,98,111,117,110,100,115,95, + 120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100, + 115,95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,3,70,1, + 12,98,111,117,110,100,115,95,99,121,109,105,110,2,40,7,97,110,99,104, + 111,114,115,11,0,11,111,112,116,105,111,110,115,103,114,105,100,11,15,111, + 103,95,107,101,121,114,111,119,109,111,118,105,110,103,15,111,103,95,114,111, + 119,105,110,115,101,114,116,105,110,103,14,111,103,95,114,111,119,100,101,108, + 101,116,105,110,103,23,111,103,95,115,101,108,101,99,116,101,100,114,111,119, + 115,100,101,108,101,116,105,110,103,19,111,103,95,102,111,99,117,115,99,101, + 108,108,111,110,101,110,116,101,114,15,111,103,95,97,117,116,111,102,105,114, + 115,116,114,111,119,13,111,103,95,97,117,116,111,97,112,112,101,110,100,10, + 111,103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111, + 112,117,112,0,13,102,105,120,114,111,119,115,46,99,111,117,110,116,2,1, + 13,102,105,120,114,111,119,115,46,105,116,101,109,115,14,1,6,104,101,105, + 103,104,116,2,16,14,99,97,112,116,105,111,110,115,46,99,111,117,110,116, + 2,7,14,99,97,112,116,105,111,110,115,46,105,116,101,109,115,14,1,7, + 99,97,112,116,105,111,110,6,1,77,4,104,105,110,116,6,11,85,115,101, + 32,105,110,32,77,97,107,101,0,1,7,99,97,112,116,105,111,110,6,1, + 66,4,104,105,110,116,6,12,85,115,101,32,105,110,32,66,117,105,108,100, + 0,1,7,99,97,112,116,105,111,110,6,1,49,4,104,105,110,116,6,13, + 85,115,101,32,105,110,32,77,97,107,101,32,49,0,1,7,99,97,112,116, + 105,111,110,6,1,50,4,104,105,110,116,6,13,85,115,101,32,105,110,32, + 77,97,107,101,32,50,0,1,7,99,97,112,116,105,111,110,6,1,51,4, + 104,105,110,116,6,13,85,115,101,32,105,110,32,77,97,107,101,32,51,0, + 1,7,99,97,112,116,105,111,110,6,1,52,4,104,105,110,116,6,13,85, + 115,101,32,105,110,32,77,97,107,101,32,52,0,1,7,99,97,112,116,105, + 111,110,6,7,67,111,109,109,97,110,100,0,0,0,0,14,100,97,116,97, + 99,111,108,115,46,99,111,117,110,116,2,7,16,100,97,116,97,99,111,108, + 115,46,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111, + 99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99, + 111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121, + 115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99, + 116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97, + 118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99, + 111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115, + 99,114,111,108,108,114,111,119,0,14,100,97,116,97,99,111,108,115,46,105, + 116,101,109,115,14,7,9,97,102,116,109,97,107,101,111,110,1,5,119,105, + 100,116,104,2,13,7,111,112,116,105,111,110,115,11,12,99,111,95,100,114, + 97,119,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101, + 99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111, + 95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115, + 101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99, + 111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111, + 112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111, + 117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116, + 110,97,109,101,6,9,97,102,116,109,97,107,101,111,110,9,100,97,116,97, + 99,108,97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100, + 97,116,97,108,105,115,116,0,7,10,97,102,116,98,117,105,108,100,111,110, + 1,5,119,105,100,116,104,2,13,7,111,112,116,105,111,110,115,11,12,99, + 111,95,100,114,97,119,102,111,99,117,115,14,99,111,95,102,111,99,117,115, + 115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99, + 116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117, + 108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101, + 99,116,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99, + 97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99, + 111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105, + 100,103,101,116,110,97,109,101,6,10,97,102,116,98,117,105,108,100,111,110, + 9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100,105,110,116, + 101,103,101,114,100,97,116,97,108,105,115,116,0,7,10,97,102,116,109,97, + 107,101,49,111,110,1,5,119,105,100,116,104,2,13,7,111,112,116,105,111, + 110,115,11,12,99,111,95,100,114,97,119,102,111,99,117,115,14,99,111,95, + 102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101, + 115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14, + 99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111, + 119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116,97,116,101, + 10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97, + 115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111, + 119,0,10,119,105,100,103,101,116,110,97,109,101,6,10,97,102,116,109,97, + 107,101,49,111,110,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114, + 105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,10, + 97,102,116,109,97,107,101,50,111,110,1,5,119,105,100,116,104,2,13,7, + 111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117, + 115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95, + 109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101, + 108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12, + 99,111,95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97,118,101, + 115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95, + 99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114, + 111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,10, + 97,102,116,109,97,107,101,50,111,110,9,100,97,116,97,99,108,97,115,115, + 7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105, + 115,116,0,7,10,97,102,116,109,97,107,101,51,111,110,1,5,119,105,100, + 116,104,2,13,7,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97, + 119,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99, + 116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95, + 107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101, + 108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111, + 95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112, + 121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117, + 115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110, + 97,109,101,6,10,97,102,116,109,97,107,101,51,111,110,9,100,97,116,97, + 99,108,97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100, + 97,116,97,108,105,115,116,0,7,10,97,102,116,109,97,107,101,52,111,110, + 1,5,119,105,100,116,104,2,13,7,111,112,116,105,111,110,115,11,12,99, + 111,95,100,114,97,119,102,111,99,117,115,14,99,111,95,102,111,99,117,115, + 115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99, + 116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117, + 108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101, + 99,116,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99, + 97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99, + 111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105, + 100,103,101,116,110,97,109,101,6,10,97,102,116,109,97,107,101,52,111,110, + 9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100,105,110,116, + 101,103,101,114,100,97,116,97,108,105,115,116,0,7,10,97,102,116,99,111, + 109,109,97,110,100,1,5,119,105,100,116,104,3,229,2,7,111,112,116,105, + 111,110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14, + 99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101, + 121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101, + 99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,7,99,111,95,102, + 105,108,108,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111,95, + 115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121, + 11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115, + 101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97, + 109,101,6,10,97,102,116,99,111,109,109,97,110,100,9,100,97,116,97,99, + 108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116,114,105,110,103, + 100,97,116,97,108,105,115,116,0,0,13,100,97,116,97,114,111,119,104,101, + 105,103,104,116,2,16,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,12,116,98,111,111,108,101,97,110,101,100,105,116,9,97,102,116, + 109,97,107,101,111,110,3,84,97,103,2,1,11,111,112,116,105,111,110,115, + 115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111, + 110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111, + 117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105,111,110,115,101, + 100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101, + 95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107, + 109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117,114, + 110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120, + 105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111, + 101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111, + 115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,12, + 111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117, + 116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101, + 120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101, + 0,7,118,105,115,105,98,108,101,8,12,118,97,108,117,101,100,101,102,97, + 117,108,116,9,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,10, + 97,102,116,98,117,105,108,100,111,110,3,84,97,103,2,2,11,111,112,116, + 105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98, + 117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2, + 2,8,98,111,117,110,100,115,95,120,2,14,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105, + 111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115, + 99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99, + 104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114, + 101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116, + 111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115, + 111,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95, + 97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105, + 99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101, + 49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95, + 107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115, + 116,97,116,101,0,7,118,105,115,105,98,108,101,8,12,118,97,108,117,101, + 100,101,102,97,117,108,116,9,0,0,12,116,98,111,111,108,101,97,110,101, + 100,105,116,10,97,102,116,109,97,107,101,49,111,110,3,84,97,103,2,4, + 11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114, + 97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114, + 100,101,114,2,3,8,98,111,117,110,100,115,95,120,2,28,8,98,111,117, + 110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,121,2,16,11, + 111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111, + 111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16, + 111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95, + 101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101, + 108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110, + 99,117,114,115,111,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116, + 25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115, + 116,99,108,105,99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49, + 11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14, + 111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115, + 97,118,101,115,116,97,116,101,0,7,118,105,115,105,98,108,101,8,12,118, + 97,108,117,101,100,101,102,97,117,108,116,9,0,0,12,116,98,111,111,108, + 101,97,110,101,100,105,116,10,97,102,116,109,97,107,101,50,111,110,3,84, + 97,103,2,8,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115, + 107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116, + 97,98,111,114,100,101,114,2,4,8,98,111,117,110,100,115,95,120,2,42, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 121,2,16,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95, + 117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117, + 101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108, + 12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115, + 101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120, + 105,116,111,110,99,117,114,115,111,114,13,111,101,95,97,117,116,111,115,101, + 108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110, + 102,105,114,115,116,99,108,105,99,107,0,12,111,112,116,105,111,110,115,101, + 100,105,116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109, + 101,110,117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111, + 101,49,95,115,97,118,101,115,116,97,116,101,0,7,118,105,115,105,98,108, + 101,8,12,118,97,108,117,101,100,101,102,97,117,108,116,9,0,0,12,116, + 98,111,111,108,101,97,110,101,100,105,116,10,97,102,116,109,97,107,101,51, + 111,110,3,84,97,103,2,16,11,111,112,116,105,111,110,115,115,107,105,110, + 11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108, + 121,0,8,116,97,98,111,114,100,101,114,2,5,8,98,111,117,110,100,115, + 95,120,2,56,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,121,2,16,11,111,112,116,105,111,110,115,101,100,105,116,11, + 12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111, + 115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97, + 110,99,101,108,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101, + 95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111, + 101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,97,117, + 116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101, + 99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,12,111,112,116,105, + 111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112,111, + 112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99,117, + 116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0,7,118,105, + 115,105,98,108,101,8,12,118,97,108,117,101,100,101,102,97,117,108,116,9, + 0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,10,97,102,116,109, + 97,107,101,52,111,110,3,84,97,103,2,32,11,111,112,116,105,111,110,115, + 115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111, + 110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,6,8,98,111, + 117,110,100,115,95,120,2,70,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105,111,110,115,101, + 100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101, + 95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107, + 109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117,114, + 110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120, + 105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111, + 101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111, + 115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,12, + 111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117, + 116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101, + 120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101, + 0,7,118,105,115,105,98,108,101,8,12,118,97,108,117,101,100,101,102,97, + 117,108,116,9,0,0,15,116,109,101,109,111,100,105,97,108,111,103,101,100, + 105,116,10,97,102,116,99,111,109,109,97,110,100,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114, + 97,109,101,98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101, + 46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111, + 114,99,108,105,101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,19,102, + 114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1, + 19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115, + 14,1,5,99,111,108,111,114,4,5,0,0,144,7,105,109,97,103,101,110, + 114,2,17,0,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99, + 111,108,111,114,4,5,0,0,144,20,102,114,97,109,101,46,98,117,116,116, + 111,110,46,105,109,97,103,101,110,114,2,17,8,116,97,98,111,114,100,101, + 114,2,7,10,111,110,115,104,111,119,104,105,110,116,7,18,104,105,110,116, + 101,120,112,97,110,100,101,100,109,97,99,114,111,115,7,118,105,115,105,98, + 108,101,8,8,98,111,117,110,100,115,95,120,2,84,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,229,2,9,98, + 111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100, + 105,116,49,11,13,111,101,49,95,115,97,118,101,118,97,108,117,101,0,11, + 111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111, + 111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16, + 111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95, + 101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101, + 108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110, + 99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114, + 13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117, + 116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107, + 0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0, + 0,0,11,116,115,116,114,105,110,103,101,100,105,116,8,116,97,114,103,112, + 114,101,102,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,16,84, + 97,114,103,46,32,112,114,101,102,46,32,40,45,111,41,22,102,114,97,109, + 101,46,99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,9, + 116,102,95,98,111,116,116,111,109,0,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101, + 100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109, + 111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,2,10,111, + 110,115,104,111,119,104,105,110,116,7,18,104,105,110,116,101,120,112,97,110, + 100,101,100,109,97,99,114,111,115,8,98,111,117,110,100,115,95,120,3,202, + 1,8,98,111,117,110,100,115,95,121,2,2,9,98,111,117,110,100,115,95, + 99,120,3,115,1,9,98,111,117,110,100,115,95,99,121,2,37,7,97,110, + 99,104,111,114,115,11,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0, + 0,13,116,102,105,108,101,110,97,109,101,101,100,105,116,7,109,97,107,101, + 100,105,114,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,15,77,97,107,101,32,38,68,105,114,101,99,116,111,114, + 121,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102, + 108,97,103,115,11,9,116,102,95,98,111,116,116,111,109,0,19,102,114,97, + 109,101,46,99,97,112,116,105,111,110,111,102,102,115,101,116,2,3,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115, + 101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105, + 115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100, + 26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,97,99,116,105,118,101,0,19,102,114,97,109,101,46,98,117,116,116,111, + 110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116, + 116,111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4,2, + 0,0,128,7,105,109,97,103,101,110,114,2,17,0,0,18,102,114,97,109, + 101,46,98,117,116,116,111,110,46,99,111,108,111,114,4,2,0,0,128,20, + 102,114,97,109,101,46,98,117,116,116,111,110,46,105,109,97,103,101,110,114, + 2,17,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,4, + 10,111,110,115,104,111,119,104,105,110,116,7,18,104,105,110,116,101,120,112, + 97,110,100,101,100,109,97,99,114,111,115,8,98,111,117,110,100,115,95,120, + 3,250,0,8,98,111,117,110,100,115,95,121,2,43,9,98,111,117,110,100, + 115,95,99,120,3,205,0,9,98,111,117,110,100,115,95,99,121,2,37,7, + 97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110,95, + 116,111,112,8,97,110,95,114,105,103,104,116,0,9,116,101,120,116,102,108, + 97,103,115,11,12,116,102,95,121,99,101,110,116,101,114,101,100,11,116,102, + 95,110,111,115,101,108,101,99,116,14,116,102,95,101,108,108,105,112,115,101, + 108,101,102,116,0,18,99,111,110,116,114,111,108,108,101,114,46,111,112,116, + 105,111,110,115,11,13,102,100,111,95,100,105,114,101,99,116,111,114,121,0, + 26,99,111,110,116,114,111,108,108,101,114,46,104,105,115,116,111,114,121,109, + 97,120,99,111,117,110,116,2,0,22,99,111,110,116,114,111,108,108,101,114, + 46,99,97,112,116,105,111,110,111,112,101,110,6,21,83,101,108,101,99,116, + 32,109,97,107,101,32,100,105,114,101,99,116,111,114,121,24,99,111,110,116, + 114,111,108,108,101,114,46,111,110,103,101,116,102,105,108,101,110,97,109,101, + 7,14,101,120,112,97,110,100,102,105,108,101,110,97,109,101,13,114,101,102, + 102,111,110,116,104,101,105,103,104,116,2,14,0,0,9,116,115,112,108,105, + 116,116,101,114,10,116,115,112,108,105,116,116,101,114,49,5,99,111,108,111, + 114,4,3,0,0,144,8,116,97,98,111,114,100,101,114,2,16,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,247,0,8,98, + 111,117,110,100,115,95,121,2,61,9,98,111,117,110,100,115,95,99,120,2, + 3,9,98,111,117,110,100,115,95,99,121,2,20,7,111,112,116,105,111,110, + 115,11,9,115,112,111,95,104,112,114,111,112,12,115,112,111,95,100,111,99, + 107,108,101,102,116,11,115,112,111,95,100,111,99,107,116,111,112,13,115,112, + 111,95,100,111,99,107,114,105,103,104,116,14,115,112,111,95,100,111,99,107, + 98,111,116,116,111,109,0,8,108,105,110,107,108,101,102,116,7,11,109,97, + 107,101,99,111,109,109,97,110,100,9,108,105,110,107,114,105,103,104,116,7, + 7,109,97,107,101,100,105,114,0,0,9,116,115,112,108,105,116,116,101,114, + 10,116,115,112,108,105,116,116,101,114,50,5,99,111,108,111,114,4,3,0, + 0,144,8,116,97,98,111,114,100,101,114,2,17,7,118,105,115,105,98,108, + 101,8,8,98,111,117,110,100,115,95,120,3,247,0,8,98,111,117,110,100, + 115,95,121,2,20,9,98,111,117,110,100,115,95,99,120,2,3,9,98,111, + 117,110,100,115,95,99,121,2,20,7,111,112,116,105,111,110,115,11,9,115, + 112,111,95,104,112,114,111,112,12,115,112,111,95,100,111,99,107,108,101,102, + 116,11,115,112,111,95,100,111,99,107,116,111,112,13,115,112,111,95,100,111, + 99,107,114,105,103,104,116,14,115,112,111,95,100,111,99,107,98,111,116,116, + 111,109,0,8,108,105,110,107,108,101,102,116,7,8,109,97,105,110,102,105, + 108,101,9,108,105,110,107,114,105,103,104,116,7,10,116,97,114,103,101,116, + 102,105,108,101,0,0,9,116,115,112,108,105,116,116,101,114,10,116,115,112, + 108,105,116,116,101,114,52,5,99,111,108,111,114,4,3,0,0,144,8,116, + 97,98,111,114,100,101,114,2,19,7,118,105,115,105,98,108,101,8,8,98, + 111,117,110,100,115,95,120,3,199,1,8,98,111,117,110,100,115,95,121,2, + 20,9,98,111,117,110,100,115,95,99,120,2,3,9,98,111,117,110,100,115, + 95,99,121,2,20,7,111,112,116,105,111,110,115,11,9,115,112,111,95,104, + 112,114,111,112,12,115,112,111,95,100,111,99,107,108,101,102,116,11,115,112, + 111,95,100,111,99,107,116,111,112,13,115,112,111,95,100,111,99,107,114,105, + 103,104,116,14,115,112,111,95,100,111,99,107,98,111,116,116,111,109,0,8, + 108,105,110,107,108,101,102,116,7,10,116,97,114,103,101,116,102,105,108,101, + 9,108,105,110,107,114,105,103,104,116,7,8,116,97,114,103,112,114,101,102, + 0,0,9,116,115,112,108,105,116,116,101,114,10,116,115,112,108,105,116,116, + 101,114,53,5,99,111,108,111,114,4,3,0,0,144,8,116,97,98,111,114, + 100,101,114,2,20,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100, + 115,95,120,3,199,1,8,98,111,117,110,100,115,95,121,2,60,9,98,111, + 117,110,100,115,95,99,120,2,3,9,98,111,117,110,100,115,95,99,121,2, + 20,7,111,112,116,105,111,110,115,11,9,115,112,111,95,104,112,114,111,112, + 12,115,112,111,95,100,111,99,107,108,101,102,116,11,115,112,111,95,100,111, + 99,107,116,111,112,13,115,112,111,95,100,111,99,107,114,105,103,104,116,14, + 115,112,111,95,100,111,99,107,98,111,116,116,111,109,0,8,108,105,110,107, + 108,101,102,116,7,7,109,97,107,101,100,105,114,9,108,105,110,107,114,105, + 103,104,116,7,17,109,101,115,115,97,103,101,111,117,116,112,117,116,102,105, + 108,101,0,0,10,116,99,111,108,111,114,101,100,105,116,10,99,111,108,111, + 114,101,114,114,111,114,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,11,69,114,114,111,114,32,67,111,108,111,114,22,102,114,97,109,101,46, + 99,97,112,116,105,111,110,116,101,120,116,102,108,97,103,115,11,9,116,102, + 95,98,111,116,116,111,109,0,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,20,102,114,97,109,101,46,98,117,116,116,111,110, + 46,111,112,116,105,111,110,115,11,21,102,98,111,95,105,110,97,99,116,105, + 118,101,105,110,118,105,115,105,98,108,101,0,19,102,114,97,109,101,46,98, + 117,116,116,111,110,115,46,99,111,117,110,116,2,2,19,102,114,97,109,101, + 46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,7,111,112,116, + 105,111,110,115,11,21,102,98,111,95,105,110,97,99,116,105,118,101,105,110, + 118,105,115,105,98,108,101,0,0,1,7,105,109,97,103,101,110,114,2,17, + 7,111,112,116,105,111,110,115,11,21,102,98,111,95,105,110,97,99,116,105, + 118,101,105,110,118,105,115,105,98,108,101,0,0,0,27,102,114,97,109,101, + 46,98,117,116,116,111,110,101,108,108,105,112,115,101,46,105,109,97,103,101, + 110,114,2,17,27,102,114,97,109,101,46,98,117,116,116,111,110,101,108,108, + 105,112,115,101,46,111,112,116,105,111,110,115,11,21,102,98,111,95,105,110, + 97,99,116,105,118,101,105,110,118,105,115,105,98,108,101,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0, + 2,0,0,8,116,97,98,111,114,100,101,114,2,6,8,98,111,117,110,100, + 115,95,120,2,1,8,98,111,117,110,100,115,95,121,2,87,9,98,111,117, + 110,100,115,95,99,120,2,108,9,98,111,117,110,100,115,95,99,121,2,37, + 5,118,97,108,117,101,4,24,0,0,160,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,0,7,116,115,112,97,99,101,114,8,116,115, + 112,97,99,101,114,53,8,116,97,98,111,114,100,101,114,2,21,8,98,111, + 117,110,100,115,95,120,2,109,8,98,111,117,110,100,115,95,121,2,109,9, + 98,111,117,110,100,115,95,99,120,2,8,9,98,111,117,110,100,115,95,99, + 121,2,18,8,108,105,110,107,108,101,102,116,7,10,99,111,108,111,114,101, + 114,114,111,114,9,108,105,110,107,114,105,103,104,116,7,12,99,111,108,111, + 114,119,97,114,110,105,110,103,0,0,10,116,99,111,108,111,114,101,100,105, + 116,12,99,111,108,111,114,119,97,114,110,105,110,103,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,13,87,97,114,110,105,110,103,32,67,111, + 108,111,114,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120, + 116,102,108,97,103,115,11,9,116,102,95,98,111,116,116,111,109,0,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,20,102,114, + 97,109,101,46,98,117,116,116,111,110,46,111,112,116,105,111,110,115,11,21, + 102,98,111,95,105,110,97,99,116,105,118,101,105,110,118,105,115,105,98,108, + 101,0,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117, + 110,116,2,2,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105, + 116,101,109,115,14,1,7,111,112,116,105,111,110,115,11,21,102,98,111,95, + 105,110,97,99,116,105,118,101,105,110,118,105,115,105,98,108,101,0,0,1, + 7,105,109,97,103,101,110,114,2,17,7,111,112,116,105,111,110,115,11,21, + 102,98,111,95,105,110,97,99,116,105,118,101,105,110,118,105,115,105,98,108, + 101,0,0,0,27,102,114,97,109,101,46,98,117,116,116,111,110,101,108,108, + 105,112,115,101,46,105,109,97,103,101,110,114,2,17,27,102,114,97,109,101, + 46,98,117,116,116,111,110,101,108,108,105,112,115,101,46,111,112,116,105,111, + 110,115,11,21,102,98,111,95,105,110,97,99,116,105,118,101,105,110,118,105, + 115,105,98,108,101,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100, + 101,114,2,7,8,98,111,117,110,100,115,95,120,2,117,8,98,111,117,110, + 100,115,95,121,2,87,9,98,111,117,110,100,115,95,99,120,2,108,9,98, + 111,117,110,100,115,95,99,121,2,37,5,118,97,108,117,101,4,19,0,0, + 160,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,7, + 116,115,112,97,99,101,114,8,116,115,112,97,99,101,114,54,8,116,97,98, + 111,114,100,101,114,2,22,8,98,111,117,110,100,115,95,120,3,225,0,8, + 98,111,117,110,100,115,95,121,2,109,9,98,111,117,110,100,115,95,99,120, + 2,8,9,98,111,117,110,100,115,95,99,121,2,18,8,108,105,110,107,108, + 101,102,116,7,12,99,111,108,111,114,119,97,114,110,105,110,103,9,108,105, + 110,107,114,105,103,104,116,7,9,99,111,108,111,114,110,111,116,101,0,0, + 10,116,99,111,108,111,114,101,100,105,116,9,99,111,108,111,114,110,111,116, + 101,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,10,78,111,116, + 101,32,67,111,108,111,114,22,102,114,97,109,101,46,99,97,112,116,105,111, + 110,116,101,120,116,102,108,97,103,115,11,9,116,102,95,98,111,116,116,111, + 109,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 0,20,102,114,97,109,101,46,98,117,116,116,111,110,46,111,112,116,105,111, + 110,115,11,21,102,98,111,95,105,110,97,99,116,105,118,101,105,110,118,105, + 115,105,98,108,101,0,19,102,114,97,109,101,46,98,117,116,116,111,110,115, + 46,99,111,117,110,116,2,2,19,102,114,97,109,101,46,98,117,116,116,111, + 110,115,46,105,116,101,109,115,14,1,7,111,112,116,105,111,110,115,11,21, + 102,98,111,95,105,110,97,99,116,105,118,101,105,110,118,105,115,105,98,108, + 101,0,0,1,7,105,109,97,103,101,110,114,2,17,7,111,112,116,105,111, + 110,115,11,21,102,98,111,95,105,110,97,99,116,105,118,101,105,110,118,105, + 115,105,98,108,101,0,0,0,27,102,114,97,109,101,46,98,117,116,116,111, + 110,101,108,108,105,112,115,101,46,105,109,97,103,101,110,114,2,17,27,102, + 114,97,109,101,46,98,117,116,116,111,110,101,108,108,105,112,115,101,46,111, + 112,116,105,111,110,115,11,21,102,98,111,95,105,110,97,99,116,105,118,101, + 105,110,118,105,115,105,98,108,101,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97, + 98,111,114,100,101,114,2,8,8,98,111,117,110,100,115,95,120,3,233,0, + 8,98,111,117,110,100,115,95,121,2,87,9,98,111,117,110,100,115,95,99, + 120,2,108,9,98,111,117,110,100,115,95,99,121,2,37,5,118,97,108,117, + 101,4,20,0,0,160,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,7,116,115,112,97,99,101,114,8,116,115,112,97,99,101,114, + 52,5,99,111,108,111,114,4,3,0,0,128,8,116,97,98,111,114,100,101, + 114,2,23,8,98,111,117,110,100,115,95,120,3,85,1,8,98,111,117,110, + 100,115,95,121,2,92,9,98,111,117,110,100,115,95,99,120,2,10,9,98, + 111,117,110,100,115,95,99,121,2,26,8,108,105,110,107,108,101,102,116,7, + 9,99,111,108,111,114,110,111,116,101,9,108,105,110,107,114,105,103,104,116, + 7,15,115,116,114,105,112,109,101,115,115,97,103,101,101,115,99,0,0,12, + 116,98,111,111,108,101,97,110,101,100,105,116,15,115,116,114,105,112,109,101, + 115,115,97,103,101,101,115,99,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,19,83,116,114,105,112,32,69,83,67,32,115,101,113,117,101,110, + 99,101,115,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116, + 17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101, + 116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118, + 101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108, + 105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,97,99,116,105,118,101,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,3,133,0,2,2, + 0,8,116,97,98,111,114,100,101,114,2,10,8,98,111,117,110,100,115,95, + 120,3,95,1,8,98,111,117,110,100,115,95,121,2,115,9,98,111,117,110, + 100,115,95,99,120,3,146,0,9,98,111,117,110,100,115,95,99,121,2,16, + 0,0,0,8,116,116,97,98,112,97,103,101,9,116,116,97,98,112,97,103, + 101,49,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119, + 95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111, + 99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119, + 95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114, + 111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111,99, + 117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109, + 111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99, + 107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,97,99,116,105,118,101,0,8,116,97,98,111,114,100,101,114, + 2,3,8,98,111,117,110,100,115,95,120,2,1,8,98,111,117,110,100,115, + 95,121,2,20,9,98,111,117,110,100,115,95,99,120,3,62,3,9,98,111, + 117,110,100,115,95,99,121,3,18,2,7,97,110,99,104,111,114,115,11,7, + 97,110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105, + 103,104,116,9,97,110,95,98,111,116,116,111,109,0,7,99,97,112,116,105, + 111,110,6,7,77,38,97,99,114,111,115,8,111,110,108,97,121,111,117,116, + 7,17,109,97,99,114,111,110,99,104,105,108,100,115,99,97,108,101,100,0, + 11,116,119,105,100,103,101,116,103,114,105,100,9,109,97,99,114,111,103,114, + 105,100,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119, + 95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111, + 99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119, + 95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114, + 111,119,102,111,99,117,115,111,117,116,17,111,119,95,102,111,99,117,115,98, + 97,99,107,111,110,101,115,99,13,111,119,95,109,111,117,115,101,119,104,101, + 101,108,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 0,5,99,111,108,111,114,4,3,0,0,128,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99, + 107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100, + 25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118, + 101,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115, + 95,120,2,0,8,98,111,117,110,100,115,95,121,2,124,9,98,111,117,110, + 100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,3,149, + 1,12,98,111,117,110,100,115,95,99,121,109,105,110,2,40,7,97,110,99, + 104,111,114,115,11,6,97,110,95,116,111,112,9,97,110,95,98,111,116,116, + 111,109,0,11,111,112,116,105,111,110,115,103,114,105,100,11,12,111,103,95, + 99,111,108,115,105,122,105,110,103,15,111,103,95,107,101,121,114,111,119,109, + 111,118,105,110,103,15,111,103,95,114,111,119,105,110,115,101,114,116,105,110, + 103,14,111,103,95,114,111,119,100,101,108,101,116,105,110,103,23,111,103,95, + 115,101,108,101,99,116,101,100,114,111,119,115,100,101,108,101,116,105,110,103, + 19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101,114, + 15,111,103,95,97,117,116,111,102,105,114,115,116,114,111,119,13,111,103,95, + 97,117,116,111,97,112,112,101,110,100,10,111,103,95,119,114,97,112,99,111, + 108,12,111,103,95,97,117,116,111,112,111,112,117,112,0,13,102,105,120,114, + 111,119,115,46,99,111,117,110,116,2,1,13,102,105,120,114,111,119,115,46, + 105,116,101,109,115,14,1,6,104,101,105,103,104,116,2,16,14,99,97,112, + 116,105,111,110,115,46,99,111,117,110,116,2,8,14,99,97,112,116,105,111, + 110,115,46,105,116,101,109,115,14,1,7,99,97,112,116,105,111,110,6,1, + 49,0,1,7,99,97,112,116,105,111,110,6,1,50,0,1,7,99,97,112, + 116,105,111,110,6,1,51,0,1,7,99,97,112,116,105,111,110,6,1,52, + 0,1,7,99,97,112,116,105,111,110,6,1,53,0,1,7,99,97,112,116, + 105,111,110,6,1,54,0,1,7,99,97,112,116,105,111,110,6,4,78,97, + 109,101,0,1,7,99,97,112,116,105,111,110,6,5,86,97,108,117,101,0, + 0,0,0,14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,8, + 14,100,97,116,97,99,111,108,115,46,119,105,100,116,104,2,13,16,100,97, + 116,97,99,111,108,115,46,111,112,116,105,111,110,115,11,12,99,111,95,100, + 114,97,119,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108, + 101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99, + 111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105, + 115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,11, + 99,111,95,102,105,120,119,105,100,116,104,12,99,111,95,115,97,118,101,115, + 116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99, + 97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111, + 108,108,114,111,119,0,14,100,97,116,97,99,111,108,115,46,105,116,101,109, + 115,14,7,2,101,48,1,5,119,105,100,116,104,2,13,7,111,112,116,105, + 111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117,115,14,99,111, + 95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115, + 101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116, + 14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114, + 111,119,115,101,108,101,99,116,11,99,111,95,102,105,120,119,105,100,116,104, + 12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110, + 99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95, + 109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103, + 101,116,110,97,109,101,6,2,101,48,9,100,97,116,97,99,108,97,115,115, + 7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105, + 115,116,0,7,2,101,49,1,5,119,105,100,116,104,2,13,7,111,112,116, + 105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117,115,14,99, + 111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117, + 115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99, + 116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95, + 114,111,119,115,101,108,101,99,116,11,99,111,95,102,105,120,119,105,100,116, + 104,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97, + 110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111, + 95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100, + 103,101,116,110,97,109,101,6,2,101,49,9,100,97,116,97,99,108,97,115, + 115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108, + 105,115,116,0,7,2,101,50,1,5,119,105,100,116,104,2,13,7,111,112, + 116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117,115,14, + 99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111, + 117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101, + 99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111, + 95,114,111,119,115,101,108,101,99,116,11,99,111,95,102,105,120,119,105,100, + 116,104,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99, + 97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99, + 111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105, + 100,103,101,116,110,97,109,101,6,2,101,50,9,100,97,116,97,99,108,97, + 115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97, + 108,105,115,116,0,7,2,101,51,1,5,119,105,100,116,104,2,13,7,111, + 112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117,115, + 14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109, + 111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108, + 101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99, + 111,95,114,111,119,115,101,108,101,99,116,11,99,111,95,102,105,120,119,105, + 100,116,104,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95, + 99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17, + 99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119, + 105,100,103,101,116,110,97,109,101,6,2,101,51,9,100,97,116,97,99,108, + 97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116, + 97,108,105,115,116,0,7,2,101,52,1,5,119,105,100,116,104,2,13,7, + 111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117, + 115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95, + 109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101, + 108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12, + 99,111,95,114,111,119,115,101,108,101,99,116,11,99,111,95,102,105,120,119, + 105,100,116,104,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111, + 95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101, + 17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10, + 119,105,100,103,101,116,110,97,109,101,6,2,101,52,9,100,97,116,97,99, + 108,97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97, + 116,97,108,105,115,116,0,7,2,101,53,1,5,119,105,100,116,104,2,13, + 7,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99, + 117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111, + 95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115, + 101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116, + 12,99,111,95,114,111,119,115,101,108,101,99,116,11,99,111,95,102,105,120, + 119,105,100,116,104,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99, + 111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116, + 101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0, + 10,119,105,100,103,101,116,110,97,109,101,6,2,101,53,9,100,97,116,97, + 99,108,97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100, + 97,116,97,108,105,115,116,0,7,10,109,97,99,114,111,110,97,109,101,115, + 1,5,119,105,100,116,104,3,146,0,7,111,112,116,105,111,110,115,11,14, + 99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111, + 117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101, + 99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111, + 95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116, + 97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97, + 110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108, + 108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,10,109,97, + 99,114,111,110,97,109,101,115,9,100,97,116,97,99,108,97,115,115,7,22, + 116,103,114,105,100,109,115,101,115,116,114,105,110,103,100,97,116,97,108,105, + 115,116,0,7,11,109,97,99,114,111,118,97,108,117,101,115,1,5,119,105, + 100,116,104,3,82,2,7,111,112,116,105,111,110,115,11,14,99,111,95,102, + 111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115, + 101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99, + 111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119, + 115,101,108,101,99,116,7,99,111,95,102,105,108,108,12,99,111,95,115,97, + 118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99, + 111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115, + 99,114,111,108,108,114,111,119,0,10,111,110,115,104,111,119,104,105,110,116, + 7,13,99,111,108,111,110,115,104,111,119,104,105,110,116,10,119,105,100,103, + 101,116,110,97,109,101,6,11,109,97,99,114,111,118,97,108,117,101,115,9, + 100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115, + 116,114,105,110,103,100,97,116,97,108,105,115,116,0,0,13,100,97,116,97, + 114,111,119,104,101,105,103,104,116,2,16,8,115,116,97,116,102,105,108,101, + 7,9,115,116,97,116,102,105,108,101,49,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,12,116,98,111,111,108,101,97,110,101,100,105, + 116,2,101,48,3,84,97,103,2,1,11,111,112,116,105,111,110,115,115,107, + 105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111, + 110,108,121,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110, + 100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,121,2,16,11,111,112,116,105,111,110,115,101,100,105, + 116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99, + 108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114, + 99,97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117,114,110,20, + 111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116, + 15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95, + 97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101, + 108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,12,111,112, + 116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111, + 112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101, + 99,117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0,7, + 118,105,115,105,98,108,101,8,5,118,97,108,117,101,9,12,118,97,108,117, + 101,100,101,102,97,117,108,116,9,0,0,12,116,98,111,111,108,101,97,110, + 101,100,105,116,2,101,49,3,84,97,103,2,2,11,111,112,116,105,111,110, + 115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116, + 111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,2,8,98, + 111,117,110,100,115,95,120,2,14,8,98,111,117,110,100,115,95,121,2,0, + 9,98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105,111,110,115, + 101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111, + 101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99, + 107,109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117, + 114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101, + 120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13, + 111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116, + 111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0, + 12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97, + 117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121, + 101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116, + 101,0,7,118,105,115,105,98,108,101,8,5,118,97,108,117,101,9,12,118, + 97,108,117,101,100,101,102,97,117,108,116,9,0,0,12,116,98,111,111,108, + 101,97,110,101,100,105,116,2,101,50,3,84,97,103,2,4,11,111,112,116, + 105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98, + 117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2, + 3,8,98,111,117,110,100,115,95,120,2,28,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105, + 111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115, + 99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99, + 104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114, + 101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116, + 111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115, + 111,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95, + 97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105, + 99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101, + 49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95, + 107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115, + 116,97,116,101,0,7,118,105,115,105,98,108,101,8,5,118,97,108,117,101, + 9,12,118,97,108,117,101,100,101,102,97,117,108,116,9,0,0,12,116,98, + 111,111,108,101,97,110,101,100,105,116,2,101,51,3,84,97,103,2,8,11, + 111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97, + 109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100, + 101,114,2,4,8,98,111,117,110,100,115,95,120,2,42,8,98,111,117,110, + 100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,121,2,16,11,111, + 112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111, + 110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111, + 101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101, + 97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108, + 101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99, + 117,114,115,111,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25, + 111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116, + 99,108,105,99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11, + 17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111, + 101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97, + 118,101,115,116,97,116,101,0,7,118,105,115,105,98,108,101,8,5,118,97, + 108,117,101,9,12,118,97,108,117,101,100,101,102,97,117,108,116,9,0,0, + 12,116,98,111,111,108,101,97,110,101,100,105,116,2,101,52,3,84,97,103, + 2,16,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95, + 102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98, + 111,114,100,101,114,2,5,8,98,111,117,110,100,115,95,120,2,56,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,121,2, + 16,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110, + 100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114, + 121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111, + 101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116, + 115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116, + 111,110,99,117,114,115,111,114,13,111,101,95,97,117,116,111,115,101,108,101, + 99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105, + 114,115,116,99,108,105,99,107,0,12,111,112,116,105,111,110,115,101,100,105, + 116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110, + 117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49, + 95,115,97,118,101,115,116,97,116,101,0,7,118,105,115,105,98,108,101,8, + 5,118,97,108,117,101,9,12,118,97,108,117,101,100,101,102,97,117,108,116, + 9,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,2,101,53,3, + 84,97,103,2,32,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111, + 115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8, + 116,97,98,111,114,100,101,114,2,6,8,98,111,117,110,100,115,95,120,2, + 70,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,121,2,16,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101, + 95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113, + 117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101, + 108,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101, + 115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101, + 120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,97,117,116,111,115, + 101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111, + 110,102,105,114,115,116,99,108,105,99,107,0,12,111,112,116,105,111,110,115, + 101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112, + 109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13, + 111,101,49,95,115,97,118,101,115,116,97,116,101,0,7,118,105,115,105,98, + 108,101,8,5,118,97,108,117,101,9,12,118,97,108,117,101,100,101,102,97, + 117,108,116,9,0,0,11,116,115,116,114,105,110,103,101,100,105,116,10,109, + 97,99,114,111,110,97,109,101,115,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111, + 119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102, + 111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110, + 16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119, + 95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,11,111,112,116, + 105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98, + 117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2, + 7,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2, + 84,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,3,146,0,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112, + 116,105,111,110,115,101,100,105,116,49,11,0,11,111,112,116,105,111,110,115, + 101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111, + 101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99, + 107,109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114,101,116,117, + 114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101, + 120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13, + 111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116, + 111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99, + 116,111,110,102,105,114,115,116,99,108,105,99,107,0,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,14,0,0,15,116,109,101,109,111,100,105, + 97,108,111,103,101,100,105,116,11,109,97,99,114,111,118,97,108,117,101,115, + 14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49, + 95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,13,111,112, + 116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115, + 101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111, + 119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99, + 117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115, + 107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117, + 110,116,2,1,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105, + 116,101,109,115,14,1,5,99,111,108,111,114,4,5,0,0,144,7,105,109, + 97,103,101,110,114,2,17,0,0,18,102,114,97,109,101,46,98,117,116,116, + 111,110,46,99,111,108,111,114,4,5,0,0,144,20,102,114,97,109,101,46, + 98,117,116,116,111,110,46,105,109,97,103,101,110,114,2,17,8,116,97,98, + 111,114,100,101,114,2,8,7,118,105,115,105,98,108,101,8,8,98,111,117, + 110,100,115,95,120,3,231,0,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,120,3,82,2,9,98,111,117,110,100,115,95, + 99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,0,11, + 111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111, + 111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16, + 111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95, + 101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101, + 108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110, + 99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114, + 13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117, + 116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107, + 0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0, + 11,116,119,105,100,103,101,116,103,114,105,100,21,115,101,108,101,99,116,97, + 99,116,105,118,101,103,114,111,117,112,103,114,105,100,13,111,112,116,105,111, + 110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111, + 99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97, + 114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111, + 99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111, + 117,116,17,111,119,95,102,111,99,117,115,98,97,99,107,111,110,101,115,99, + 13,111,119,95,109,111,117,115,101,119,104,101,101,108,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,0,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,12,65,99,116,105,118,101,32,103,114,111,117, + 112,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102, + 108,97,103,115,11,9,116,102,95,98,111,116,116,111,109,0,19,102,114,97, + 109,101,46,99,97,112,116,105,111,110,111,102,102,115,101,116,2,3,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115, + 101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105, + 115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100, + 26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,97,99,116,105,118,101,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,98,111,117,110, + 100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121, + 2,121,12,98,111,117,110,100,115,95,99,121,109,105,110,2,40,7,97,110, + 99,104,111,114,115,11,6,97,110,95,116,111,112,0,11,111,112,116,105,111, + 110,115,103,114,105,100,11,12,111,103,95,114,111,119,109,111,118,105,110,103, + 15,111,103,95,107,101,121,114,111,119,109,111,118,105,110,103,19,111,103,95, + 102,111,99,117,115,99,101,108,108,111,110,101,110,116,101,114,10,111,103,95, + 119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112,117,112, + 0,13,102,105,120,99,111,108,115,46,99,111,117,110,116,2,1,13,102,105, + 120,99,111,108,115,46,105,116,101,109,115,14,1,5,119,105,100,116,104,2, + 13,8,110,117,109,115,116,97,114,116,2,1,7,110,117,109,115,116,101,112, + 2,1,0,0,8,114,111,119,99,111,117,110,116,2,6,14,100,97,116,97, + 99,111,108,115,46,99,111,117,110,116,2,2,16,100,97,116,97,99,111,108, + 115,46,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111, + 99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99, + 111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121, + 115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99, + 116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97, + 118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99, + 111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115, + 99,114,111,108,108,114,111,119,0,14,100,97,116,97,99,111,108,115,46,105, + 116,101,109,115,14,7,17,97,99,116,105,118,101,109,97,99,114,111,115,101, + 108,101,99,116,1,5,119,105,100,116,104,2,14,7,111,112,116,105,111,110, + 115,11,12,99,111,95,100,114,97,119,102,111,99,117,115,14,99,111,95,102, + 111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115, + 101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99, + 111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119, + 115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116,97,116,101,10, + 99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115, + 116,101,0,10,119,105,100,103,101,116,110,97,109,101,6,17,97,99,116,105, + 118,101,109,97,99,114,111,115,101,108,101,99,116,9,100,97,116,97,99,108, + 97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116, + 97,108,105,115,116,4,100,97,116,97,1,1,2,0,2,0,2,0,2,0, + 2,0,2,0,0,0,0,7,12,103,114,111,117,112,99,111,109,109,101,110, + 116,1,5,119,105,100,116,104,3,13,3,7,111,112,116,105,111,110,115,11, + 14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109, + 111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108, + 101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99, + 111,95,114,111,119,115,101,108,101,99,116,7,99,111,95,102,105,108,108,12, + 99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99, + 111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,0,10,119,105,100, + 103,101,116,110,97,109,101,6,12,103,114,111,117,112,99,111,109,109,101,110, + 116,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115, + 101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,4,100,97,116,97, + 1,1,6,0,6,0,6,0,6,0,6,0,6,0,0,0,0,0,13,100, + 97,116,97,114,111,119,104,101,105,103,104,116,2,16,11,111,110,114,111,119, + 115,109,111,118,101,100,7,23,115,101,108,101,99,116,97,99,116,105,118,101, + 111,110,114,111,119,115,109,111,118,101,100,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,17,116,98,111,111,108,101,97,110,101,100,105, + 116,114,97,100,105,111,17,97,99,116,105,118,101,109,97,99,114,111,115,101, + 108,101,99,116,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115, + 107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116, + 97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,2,14,9,98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105, + 111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115, + 99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99, + 104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101,97,116,114, + 101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116, + 111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115, + 111,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95, + 97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105, + 99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101, + 49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95, + 107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115, + 116,97,116,101,0,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7, + 26,97,99,116,116,105,118,101,115,101,108,101,99,116,111,110,100,97,116,97, + 101,110,116,101,114,101,100,7,118,105,115,105,98,108,101,8,0,0,11,116, + 115,116,114,105,110,103,101,100,105,116,12,103,114,111,117,112,99,111,109,109, + 101,110,116,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,11,111,112,116,105,111,110,115,115,107, + 105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111, + 110,108,121,0,8,116,97,98,111,114,100,101,114,2,2,7,118,105,115,105, + 98,108,101,8,8,98,111,117,110,100,115,95,120,2,15,8,98,111,117,110, + 100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,13,3,9, + 98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101, + 100,105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105,116,11,12, + 111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115, + 101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110, + 99,101,108,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95, + 114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101, + 95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100, + 111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99, + 116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114, + 115,116,99,108,105,99,107,0,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,14,0,0,0,9,116,115,112,108,105,116,116,101,114,13,109,97, + 99,114,111,115,112,108,105,116,116,101,114,5,99,111,108,111,114,4,3,0, + 0,144,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115, + 95,120,2,0,8,98,111,117,110,100,115,95,121,2,121,9,98,111,117,110, + 100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,2,3, + 7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,0,7,111,112, + 116,105,111,110,115,11,9,115,112,111,95,118,109,111,118,101,9,115,112,111, + 95,118,112,114,111,112,11,115,112,111,95,100,111,99,107,116,111,112,14,115, + 112,111,95,100,111,99,107,98,111,116,116,111,109,0,7,108,105,110,107,116, + 111,112,7,21,115,101,108,101,99,116,97,99,116,105,118,101,103,114,111,117, + 112,103,114,105,100,10,108,105,110,107,98,111,116,116,111,109,7,9,109,97, + 99,114,111,103,114,105,100,8,115,116,97,116,102,105,108,101,7,9,115,116, + 97,116,102,105,108,101,49,0,0,0,8,116,116,97,98,112,97,103,101,13, + 102,111,110,116,97,108,105,97,115,112,97,103,101,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99, + 107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100, + 25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118, + 101,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115, + 95,120,2,1,8,98,111,117,110,100,115,95,121,2,20,9,98,111,117,110, + 100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,3,18, + 2,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97, + 110,95,116,111,112,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111, + 116,116,111,109,0,7,99,97,112,116,105,111,110,6,11,38,70,111,110,116, + 32,65,108,105,97,115,0,11,116,119,105,100,103,101,116,103,114,105,100,13, + 102,111,110,116,97,108,105,97,115,103,114,105,100,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,17,111,119,95,102,111,99,117,115,98,97,99,107,111,110,101,115,99,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,5,99, + 111,108,111,114,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114, + 105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98, + 111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100, + 26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101, + 116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111, + 117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,8, + 98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,3,62,3,9,98,111,117,110,100, + 115,95,99,121,3,18,2,7,97,110,99,104,111,114,115,11,0,11,111,112, + 116,105,111,110,115,103,114,105,100,11,12,111,103,95,99,111,108,115,105,122, + 105,110,103,15,111,103,95,107,101,121,114,111,119,109,111,118,105,110,103,15, + 111,103,95,114,111,119,105,110,115,101,114,116,105,110,103,14,111,103,95,114, + 111,119,100,101,108,101,116,105,110,103,19,111,103,95,102,111,99,117,115,99, + 101,108,108,111,110,101,110,116,101,114,15,111,103,95,97,117,116,111,102,105, + 114,115,116,114,111,119,13,111,103,95,97,117,116,111,97,112,112,101,110,100, + 10,111,103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112, + 111,112,117,112,0,13,102,105,120,114,111,119,115,46,99,111,117,110,116,2, + 1,13,102,105,120,114,111,119,115,46,105,116,101,109,115,14,1,6,104,101, + 105,103,104,116,2,15,14,99,97,112,116,105,111,110,115,46,99,111,117,110, + 116,2,7,14,99,97,112,116,105,111,110,115,46,105,116,101,109,115,14,1, + 7,99,97,112,116,105,111,110,6,5,65,108,105,97,115,0,1,7,99,97, + 112,116,105,111,110,6,9,70,111,110,116,32,110,97,109,101,0,1,7,99, + 97,112,116,105,111,110,6,6,72,101,105,103,104,116,0,1,7,99,97,112, + 116,105,111,110,6,5,87,105,100,116,104,0,1,7,99,97,112,116,105,111, + 110,6,7,79,112,116,105,111,110,115,0,1,7,99,97,112,116,105,111,110, + 6,6,88,115,99,97,108,101,0,1,7,99,97,112,116,105,111,110,6,8, + 65,110,99,101,115,116,111,114,0,0,0,0,14,100,97,116,97,99,111,108, + 115,46,99,111,117,110,116,2,7,16,100,97,116,97,99,111,108,115,46,111, + 112,116,105,111,110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101, + 99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111, + 95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115, + 101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99, + 111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111, + 112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111, + 117,115,101,115,99,114,111,108,108,114,111,119,0,14,100,97,116,97,99,111, + 108,115,46,105,116,101,109,115,14,7,9,102,111,110,116,97,108,105,97,115, + 1,5,119,105,100,116,104,2,98,7,111,112,116,105,111,110,115,11,14,99, + 111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117, + 115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99, + 116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95, + 114,111,119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116,97, + 116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110, + 112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108, + 114,111,119,0,10,111,110,115,104,111,119,104,105,110,116,7,13,99,111,108, + 111,110,115,104,111,119,104,105,110,116,10,119,105,100,103,101,116,110,97,109, + 101,6,9,102,111,110,116,97,108,105,97,115,9,100,97,116,97,99,108,97, + 115,115,7,22,116,103,114,105,100,109,115,101,115,116,114,105,110,103,100,97, + 116,97,108,105,115,116,0,7,8,102,111,110,116,110,97,109,101,1,5,119, + 105,100,116,104,3,195,1,7,111,112,116,105,111,110,115,11,14,99,111,95, + 102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101, + 115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14, + 99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111, + 119,115,101,108,101,99,116,7,99,111,95,102,105,108,108,12,99,111,95,115, + 97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11, + 99,111,95,99,97,110,112,97,115,116,101,0,10,111,110,115,104,111,119,104, + 105,110,116,7,13,99,111,108,111,110,115,104,111,119,104,105,110,116,10,119, + 105,100,103,101,116,110,97,109,101,6,8,102,111,110,116,110,97,109,101,9, + 100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115, + 116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,10,102,111,110,116, + 104,101,105,103,104,116,1,7,111,112,116,105,111,110,115,11,14,99,111,95, + 102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101, + 115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14, + 99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111, + 119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116,97,116,101, + 10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97, + 115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111, + 119,0,10,119,105,100,103,101,116,110,97,109,101,6,10,102,111,110,116,104, + 101,105,103,104,116,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114, + 105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,9, + 102,111,110,116,119,105,100,116,104,1,7,111,112,116,105,111,110,115,11,14, + 99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111, + 117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101, + 99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111, + 95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116, + 97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97, + 110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108, + 108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,9,102,111, + 110,116,119,105,100,116,104,9,100,97,116,97,99,108,97,115,115,7,20,116, + 103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0, + 7,11,102,111,110,116,111,112,116,105,111,110,115,1,7,111,112,116,105,111, + 110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99, + 111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121, + 115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99, + 116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97, + 118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99, + 111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115, + 99,114,111,108,108,114,111,119,0,10,111,110,115,104,111,119,104,105,110,116, + 7,13,99,111,108,111,110,115,104,111,119,104,105,110,116,10,119,105,100,103, + 101,116,110,97,109,101,6,11,102,111,110,116,111,112,116,105,111,110,115,9, + 100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115, + 116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,10,102,111,110,116, + 120,115,99,97,108,101,1,7,111,112,116,105,111,110,115,11,14,99,111,95, + 102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101, + 115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14, + 99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111, + 119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116,97,116,101, + 10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97, + 115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111, + 119,0,10,119,105,100,103,101,116,110,97,109,101,6,10,102,111,110,116,120, + 115,99,97,108,101,9,100,97,116,97,99,108,97,115,115,7,17,116,103,114, + 105,100,114,101,97,108,100,97,116,97,108,105,115,116,0,7,13,102,111,110, + 116,97,110,99,101,115,116,111,114,115,1,5,119,105,100,116,104,2,70,7, + 111,112,116,105,111,110,115,11,14,99,111,95,102,111,99,117,115,115,101,108, + 101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99, + 111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105, + 115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12, + 99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99, + 111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109, + 111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,111,110,115,104,111, + 119,104,105,110,116,7,13,99,111,108,111,110,115,104,111,119,104,105,110,116, + 10,119,105,100,103,101,116,110,97,109,101,6,13,102,111,110,116,97,110,99, + 101,115,116,111,114,115,9,100,97,116,97,99,108,97,115,115,7,22,116,103, + 114,105,100,109,115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116, + 0,0,13,100,97,116,97,114,111,119,104,101,105,103,104,116,2,16,8,115, + 116,97,116,102,105,108,101,7,9,115,116,97,116,102,105,108,101,49,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,11,116,115,116,114, + 105,110,103,101,100,105,116,9,102,111,110,116,97,108,105,97,115,13,111,112, + 116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115, + 101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111, + 119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99, + 117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115, + 107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116, + 97,98,111,114,100,101,114,2,1,10,111,110,115,104,111,119,104,105,110,116, + 7,18,104,105,110,116,101,120,112,97,110,100,101,100,109,97,99,114,111,115, + 7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,2,98,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105, + 111,110,115,101,100,105,116,49,11,0,11,111,112,116,105,111,110,115,101,100, + 105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95, + 99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109, + 114,99,97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117, + 114,110,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114, + 101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95, + 101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111, + 110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116, + 25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115, + 116,99,108,105,99,107,0,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,0,11,116,115,116,114,105,110,103,101,100,105,116,8,102,111, + 110,116,110,97,109,101,14,111,112,116,105,111,110,115,119,105,100,103,101,116, + 49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103, + 104,116,0,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,11,111,112,116,105,111,110,115,115,107, + 105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111, + 110,108,121,0,8,116,97,98,111,114,100,101,114,2,2,10,111,110,115,104, + 111,119,104,105,110,116,7,18,104,105,110,116,101,120,112,97,110,100,101,100, + 109,97,99,114,111,115,7,118,105,115,105,98,108,101,8,8,98,111,117,110, + 100,115,95,120,2,99,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,120,3,195,1,9,98,111,117,110,100,115,95,99,121, + 2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,0,11,111,112, + 116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110, + 101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101, + 95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104, + 105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116,117, + 114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101, + 120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13, + 111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116, + 111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99, + 116,111,110,102,105,114,115,116,99,108,105,99,107,0,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,14,0,0,12,116,105,110,116,101,103,101, + 114,101,100,105,116,10,102,111,110,116,104,101,105,103,104,116,14,111,112,116, + 105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110, + 116,103,108,121,112,104,104,101,105,103,104,116,0,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114, + 97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114, + 100,101,114,2,3,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100, + 115,95,120,3,39,2,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2, + 16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,0,11,111,112,116, + 105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101, + 115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95, + 99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105, + 102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114, + 110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120, + 105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111, + 101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111, + 115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116, + 111,110,102,105,114,115,116,99,108,105,99,107,0,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,14,0,0,12,116,105,110,116,101,103,101,114, + 101,100,105,116,9,102,111,110,116,119,105,100,116,104,14,111,112,116,105,111, + 110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103, + 108,121,112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110,115,115, + 107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110, + 111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,4,7,118,105,115, + 105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,90,2,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,50, + 9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115, + 101,100,105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105,116,11, + 12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111, + 115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97, + 110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12, + 111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101, + 116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105, + 116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110, + 116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101, + 95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108, + 105,99,107,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,0,11,116,115,116,114,105,110,103,101,100,105,116,11,102,111,110,116,111, + 112,116,105,111,110,115,14,111,112,116,105,111,110,115,119,105,100,103,101,116, + 49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103, + 104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107, + 95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97, + 98,111,114,100,101,114,2,5,10,111,110,115,104,111,119,104,105,110,116,7, + 18,104,105,110,116,101,120,112,97,110,100,101,100,109,97,99,114,111,115,7, + 118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,141,2, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,2,50,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105, + 111,110,115,101,100,105,116,49,11,0,11,111,112,116,105,111,110,115,101,100, + 105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95, + 99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109, + 114,99,97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117, + 114,110,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114, + 101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95, + 101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111, + 110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116, + 25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115, + 116,99,108,105,99,107,0,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,0,9,116,114,101,97,108,101,100,105,116,10,102,111,110,116, + 120,115,99,97,108,101,14,111,112,116,105,111,110,115,119,105,100,103,101,116, + 49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103, + 104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107, + 95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97, + 98,111,114,100,101,114,2,6,7,118,105,115,105,98,108,101,8,8,98,111, + 117,110,100,115,95,120,3,192,2,8,98,111,117,110,100,115,95,121,2,0, + 9,98,111,117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95, + 99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,0,11, + 111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111, + 111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16, + 111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95, + 115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101, + 116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111, + 110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111, + 114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97, + 117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108, + 101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,5,118,97,108, + 117,101,2,1,12,118,97,108,117,101,100,101,102,97,117,108,116,5,0,0, + 0,0,0,0,0,128,255,255,10,118,97,108,117,101,114,97,110,103,101,2, + 1,10,118,97,108,117,101,115,116,97,114,116,2,0,8,118,97,108,117,101, + 109,105,110,2,0,8,118,97,108,117,101,109,97,120,5,244,136,13,181,80, + 153,118,150,125,64,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,0,11,116,115,116,114,105,110,103,101,100,105,116,13,102,111,110,116, + 97,110,99,101,115,116,111,114,115,14,111,112,116,105,111,110,115,119,105,100, + 103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104, + 101,105,103,104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19, + 111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0, + 8,116,97,98,111,114,100,101,114,2,7,10,111,110,115,104,111,119,104,105, + 110,116,7,18,104,105,110,116,101,120,112,97,110,100,101,100,109,97,99,114, + 111,115,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120, + 3,243,2,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100, + 115,95,99,120,2,70,9,98,111,117,110,100,115,95,99,121,2,16,12,111, + 112,116,105,111,110,115,101,100,105,116,49,11,0,11,111,112,116,105,111,110, + 115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13, + 111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101, + 99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105,102,116,114, + 101,116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111, + 101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15, + 111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101, + 110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108, + 101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102, + 105,114,115,116,99,108,105,99,107,0,12,118,97,108,117,101,100,101,102,97, + 117,108,116,6,11,115,116,102,95,100,101,102,97,117,108,116,13,114,101,102, + 102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,0,8,116,116,97, + 98,112,97,103,101,10,116,116,97,98,112,97,103,101,49,48,19,102,114,97, + 109,101,46,102,114,97,109,101,105,95,98,111,116,116,111,109,2,0,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,12,102,114,108, + 95,102,105,98,111,116,116,111,109,18,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107, + 101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101, + 0,8,116,97,98,111,114,100,101,114,2,7,8,98,111,117,110,100,115,95, + 120,2,1,8,98,111,117,110,100,115,95,121,2,20,9,98,111,117,110,100, + 115,95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,3,18,2, + 7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110, + 95,116,111,112,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116, + 116,111,109,0,7,99,97,112,116,105,111,110,6,12,85,115,101,114,32,38, + 67,111,108,111,114,115,0,9,116,108,97,121,111,117,116,101,114,10,116,108, + 97,121,111,117,116,101,114,55,5,99,111,108,111,114,4,3,0,0,128,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,28,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,100,105,115, + 97,98,108,101,100,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 97,99,116,105,118,101,15,102,114,108,95,111,112,116,105,111,110,115,115,107, + 105,110,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99, + 108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,97,99,116,105,118,101,0,8,116,97,98,111,114, + 100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,3,245,3,9,98,111,117,110,100,115,95,99,120,3,62, + 3,9,98,111,117,110,100,115,95,99,121,2,42,7,97,110,99,104,111,114, + 115,11,9,97,110,95,98,111,116,116,111,109,0,13,111,112,116,105,111,110, + 115,108,97,121,111,117,116,11,10,108,97,111,95,97,108,105,103,110,121,0, + 10,97,108,105,103,110,95,103,108,117,101,7,10,119,97,109,95,99,101,110, + 116,101,114,0,7,116,98,117,116,116,111,110,8,116,98,117,116,116,111,110, + 49,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,13,111,119, + 49,95,97,117,116,111,119,105,100,116,104,14,111,119,49,95,97,117,116,111, + 104,101,105,103,104,116,0,5,99,111,108,111,114,4,3,0,0,128,8,98, + 111,117,110,100,115,95,120,2,15,8,98,111,117,110,100,115,95,121,2,11, + 9,98,111,117,110,100,115,95,99,120,3,23,1,9,98,111,117,110,100,115, + 95,99,121,2,20,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101, + 102,116,9,97,110,95,98,111,116,116,111,109,0,5,115,116,97,116,101,11, + 15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,13,97,115,95, + 108,111,99,97,108,99,111,108,111,114,17,97,115,95,108,111,99,97,108,111, + 110,101,120,101,99,117,116,101,0,7,99,97,112,116,105,111,110,6,41,67, + 111,112,121,32,34,115,101,116,99,111,108,111,114,109,97,112,118,97,108,117, + 101,34,32,99,111,100,101,32,116,111,32,99,108,105,112,98,111,97,114,100, + 9,111,110,101,120,101,99,117,116,101,7,13,99,111,112,121,99,111,108,111, + 114,99,111,100,101,0,0,0,11,116,119,105,100,103,101,116,103,114,105,100, + 7,99,111,108,103,114,105,100,5,99,111,108,111,114,4,3,0,0,128,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117, + 115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100, + 105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101, + 100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,97,99,116,105,118,101,0,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,3,62,3,9,98,111,117,110,100,115,95,99,121,3,18,2,7,97,110, + 99,104,111,114,115,11,0,11,111,112,116,105,111,110,115,103,114,105,100,11, + 12,111,103,95,114,111,119,109,111,118,105,110,103,15,111,103,95,107,101,121, + 114,111,119,109,111,118,105,110,103,19,111,103,95,102,111,99,117,115,99,101, + 108,108,111,110,101,110,116,101,114,20,111,103,95,99,111,108,99,104,97,110, + 103,101,111,110,116,97,98,107,101,121,12,111,103,95,97,117,116,111,112,111, + 112,117,112,17,111,103,95,109,111,117,115,101,115,99,114,111,108,108,99,111, + 108,0,13,102,105,120,99,111,108,115,46,99,111,117,110,116,2,1,13,102, + 105,120,99,111,108,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114, + 4,7,0,0,144,5,119,105,100,116,104,2,80,9,116,101,120,116,102,108, + 97,103,115,11,12,116,102,95,121,99,101,110,116,101,114,101,100,0,0,0, + 13,102,105,120,114,111,119,115,46,99,111,117,110,116,2,1,13,102,105,120, + 114,111,119,115,46,105,116,101,109,115,14,1,6,104,101,105,103,104,116,2, + 16,14,99,97,112,116,105,111,110,115,46,99,111,117,110,116,2,3,14,99, + 97,112,116,105,111,110,115,46,105,116,101,109,115,14,1,0,1,7,99,97, + 112,116,105,111,110,6,5,67,111,108,111,114,0,1,7,99,97,112,116,105, + 111,110,6,7,67,111,109,109,101,110,116,0,0,17,99,97,112,116,105,111, + 110,115,102,105,120,46,99,111,117,110,116,2,1,17,99,97,112,116,105,111, + 110,115,102,105,120,46,105,116,101,109,115,14,1,7,99,97,112,116,105,111, + 110,6,4,78,97,109,101,0,0,0,0,14,100,97,116,97,99,111,108,115, + 46,99,111,117,110,116,2,3,16,100,97,116,97,99,111,108,115,46,111,112, + 116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117,115,14, + 99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111, + 117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101, + 99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111, + 95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116, + 97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97, + 110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108, + 108,114,111,119,0,14,100,97,116,97,99,111,108,115,46,105,116,101,109,115, + 14,7,5,99,111,108,100,105,1,5,119,105,100,116,104,2,22,7,111,112, + 116,105,111,110,115,11,11,99,111,95,114,101,97,100,111,110,108,121,10,99, + 111,95,110,111,102,111,99,117,115,12,99,111,95,105,110,118,105,115,105,98, + 108,101,12,99,111,95,100,114,97,119,102,111,99,117,115,14,99,111,95,102, + 111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115, + 101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99, + 111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119, + 115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116,97,116,101,17, + 99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119, + 105,100,103,101,116,110,97,109,101,6,5,99,111,108,100,105,9,100,97,116, + 97,99,108,97,115,115,7,20,116,103,114,105,100,112,111,105,110,116,101,114, + 100,97,116,97,108,105,115,116,0,7,10,117,115,101,114,99,111,108,111,114, + 115,1,5,119,105,100,116,104,2,97,7,111,112,116,105,111,110,115,11,12, + 99,111,95,100,114,97,119,102,111,99,117,115,14,99,111,95,102,111,99,117, + 115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101, + 99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109, + 117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108, + 101,99,116,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95, + 99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17, + 99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119, + 105,100,103,101,116,110,97,109,101,6,10,117,115,101,114,99,111,108,111,114, + 115,9,100,97,116,97,99,108,97,115,115,7,17,116,103,114,105,100,101,110, + 117,109,100,97,116,97,108,105,115,116,0,7,16,117,115,101,114,99,111,108, + 111,114,99,111,109,109,101,110,116,1,5,119,105,100,116,104,3,111,2,7, + 111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117, + 115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95, + 109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101, + 108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12, + 99,111,95,114,111,119,115,101,108,101,99,116,7,99,111,95,102,105,108,108, + 12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110, + 99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95, + 109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,8,119,105,100,116, + 104,109,105,110,2,100,10,119,105,100,103,101,116,110,97,109,101,6,16,117, + 115,101,114,99,111,108,111,114,99,111,109,109,101,110,116,9,100,97,116,97, + 99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116,114,105,110, + 103,100,97,116,97,108,105,115,116,0,0,13,100,97,116,97,114,111,119,104, + 101,105,103,104,116,2,16,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,12,116,112,111,105,110,116,101,114,101,100,105,116,5,99,111, + 108,100,105,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107, + 95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97, + 98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0,8, + 98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120, + 2,22,9,98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105,111, + 110,115,101,100,105,116,11,11,111,101,95,114,101,97,100,111,110,108,121,12, + 111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115, + 101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110, + 99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111, + 101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116, + 115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116, + 111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116, + 101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95, + 97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105, + 99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101, + 49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95, + 107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115, + 116,97,116,101,0,7,118,105,115,105,98,108,101,8,12,111,110,112,97,105, + 110,116,103,108,121,112,104,7,7,100,114,97,119,99,111,108,0,0,10,116, + 99,111,108,111,114,101,100,105,116,10,117,115,101,114,99,111,108,111,114,115, + 11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114, + 97,109,101,98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101, + 46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111, + 114,99,108,105,101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100, + 105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101, + 100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,97,99,116,105,118,101,0,18,102,114,97,109,101,46,98,117,116,116, + 111,110,46,99,111,108,111,114,4,5,0,0,144,19,102,114,97,109,101,46, + 98,117,116,116,111,110,115,46,99,111,117,110,116,2,2,19,102,114,97,109, + 101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111, + 108,111,114,4,5,0,0,144,0,1,5,99,111,108,111,114,4,5,0,0, + 144,7,105,109,97,103,101,110,114,2,17,0,0,25,102,114,97,109,101,46, + 98,117,116,116,111,110,101,108,108,105,112,115,101,46,99,111,108,111,114,4, + 5,0,0,144,27,102,114,97,109,101,46,98,117,116,116,111,110,101,108,108, + 105,112,115,101,46,105,109,97,103,101,110,114,2,17,8,116,97,98,111,114, + 100,101,114,2,2,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100, + 115,95,120,2,23,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,120,2,97,9,98,111,117,110,100,115,95,99,121,2,16, + 12,111,112,116,105,111,110,115,101,100,105,116,49,11,0,11,111,112,116,105, + 111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115, + 99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99, + 104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105,102, + 116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114,110, + 20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105, + 116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101, + 95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115, + 101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111, + 110,102,105,114,115,116,99,108,105,99,107,0,5,118,97,108,117,101,2,0, + 12,118,97,108,117,101,100,101,102,97,117,108,116,2,0,10,111,110,115,101, + 116,118,97,108,117,101,7,11,99,111,108,115,101,116,118,97,108,117,101,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,11,116,115, + 116,114,105,110,103,101,100,105,116,16,117,115,101,114,99,111,108,111,114,99, + 111,109,109,101,110,116,14,111,112,116,105,111,110,115,119,105,100,103,101,116, + 49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103, + 104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107, + 95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,12,102,114, + 97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99, + 111,108,111,114,99,108,105,101,110,116,4,3,0,0,128,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101, + 118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105, + 99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,97,99,116,105,118,101,0,8,116,97,98,111,114,100,101, + 114,2,3,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95, + 120,2,121,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100, + 115,95,99,120,3,111,2,9,98,111,117,110,100,115,95,99,121,2,16,12, + 111,112,116,105,111,110,115,101,100,105,116,49,11,0,11,111,112,116,105,111, + 110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99, + 13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104, + 101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105,102,116, + 114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114,110,20, + 111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116, + 15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95, + 101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101, + 108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110, + 102,105,114,115,116,99,108,105,99,107,0,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,0,0,0,8,116,116,97,98,112,97,103,101, + 10,116,116,97,98,112,97,103,101,50,49,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2, + 10,8,98,111,117,110,100,115,95,120,2,1,8,98,111,117,110,100,115,95, + 121,2,20,9,98,111,117,110,100,115,95,99,120,3,62,3,9,98,111,117, + 110,100,115,95,99,121,3,18,2,7,97,110,99,104,111,114,115,11,7,97, + 110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,9,97,110,95,98,111,116,116,111,109,0,7,99,97,112,116,105,111, + 110,6,14,70,38,111,114,109,97,116,32,77,97,99,114,111,115,7,116,97, + 98,104,105,110,116,6,48,85,115,101,100,32,98,121,32,102,111,114,109,97, + 116,102,108,111,97,116,109,115,101,40,41,32,97,110,100,32,102,111,114,109, + 97,116,100,97,116,101,116,105,109,101,109,115,101,40,41,0,11,116,119,105, + 100,103,101,116,103,114,105,100,15,102,111,114,109,97,116,109,97,99,114,111, + 103,114,105,100,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,62,3,9,98, + 111,117,110,100,115,95,99,121,3,18,2,7,97,110,99,104,111,114,115,11, + 0,11,111,112,116,105,111,110,115,103,114,105,100,11,19,111,103,95,102,111, + 99,117,115,99,101,108,108,111,110,101,110,116,101,114,15,111,103,95,97,117, + 116,111,102,105,114,115,116,114,111,119,13,111,103,95,97,117,116,111,97,112, + 112,101,110,100,12,111,103,95,115,97,118,101,115,116,97,116,101,20,111,103, + 95,99,111,108,99,104,97,110,103,101,111,110,116,97,98,107,101,121,10,111, + 103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112, + 117,112,17,111,103,95,109,111,117,115,101,115,99,114,111,108,108,99,111,108, + 0,13,102,105,120,114,111,119,115,46,99,111,117,110,116,2,1,13,102,105, + 120,114,111,119,115,46,105,116,101,109,115,14,1,6,104,101,105,103,104,116, + 2,16,14,99,97,112,116,105,111,110,115,46,99,111,117,110,116,2,2,14, + 99,97,112,116,105,111,110,115,46,105,116,101,109,115,14,1,7,99,97,112, + 116,105,111,110,6,4,78,97,109,101,0,1,7,99,97,112,116,105,111,110, + 6,5,86,97,108,117,101,0,0,0,0,14,100,97,116,97,99,111,108,115, + 46,99,111,117,110,116,2,2,16,100,97,116,97,99,111,108,115,46,111,112, + 116,105,111,110,115,11,12,99,111,95,115,97,118,101,115,116,97,116,101,17, + 99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,14,100, + 97,116,97,99,111,108,115,46,105,116,101,109,115,14,7,16,102,111,114,109, + 97,116,109,97,99,114,111,110,97,109,101,115,1,5,119,105,100,116,104,3, + 157,0,7,111,112,116,105,111,110,115,11,15,99,111,95,112,114,111,112,111, + 114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,115,116,97,116,101, + 17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10, + 111,110,115,104,111,119,104,105,110,116,7,13,99,111,108,111,110,115,104,111, + 119,104,105,110,116,10,119,105,100,103,101,116,110,97,109,101,6,16,102,111, + 114,109,97,116,109,97,99,114,111,110,97,109,101,115,9,100,97,116,97,99, + 108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116,114,105,110,103, + 100,97,116,97,108,105,115,116,0,7,17,102,111,114,109,97,116,109,97,99, + 114,111,118,97,108,117,101,115,1,5,119,105,100,116,104,3,155,2,7,111, + 112,116,105,111,110,115,11,7,99,111,95,102,105,108,108,12,99,111,95,115, + 97,118,101,115,116,97,116,101,17,99,111,95,109,111,117,115,101,115,99,114, + 111,108,108,114,111,119,0,10,111,110,115,104,111,119,104,105,110,116,7,13, + 99,111,108,111,110,115,104,111,119,104,105,110,116,10,119,105,100,103,101,116, + 110,97,109,101,6,17,102,111,114,109,97,116,109,97,99,114,111,118,97,108, + 117,101,115,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100, + 109,115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,0,13, + 100,97,116,97,114,111,119,104,101,105,103,104,116,2,16,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,11,116,115,116,114,105,110,103, + 101,100,105,116,16,102,111,114,109,97,116,109,97,99,114,111,110,97,109,101, + 115,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102, + 114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98,111, + 114,100,101,114,2,1,10,111,110,115,104,111,119,104,105,110,116,7,18,104, + 105,110,116,101,120,112,97,110,100,101,100,109,97,99,114,111,115,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,0,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,157, + 0,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110, + 115,101,100,105,116,49,11,0,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,14,0,0,11,116,115,116,114,105,110,103,101,100,105,116,17,102, + 111,114,109,97,116,109,97,99,114,111,118,97,108,117,101,115,14,111,112,116, + 105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110, + 116,103,108,121,112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110, + 115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116, + 111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,2,10,111, + 110,115,104,111,119,104,105,110,116,7,18,104,105,110,116,101,120,112,97,110, + 100,101,100,109,97,99,114,111,115,7,118,105,115,105,98,108,101,8,8,98, + 111,117,110,100,115,95,120,3,158,0,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,3,155,2,9,98,111,117,110,100, + 115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11, + 0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0, + 0,8,116,116,97,98,112,97,103,101,9,116,116,97,98,112,97,103,101,50, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111, + 117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107, + 101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,97,99,116,105,118,101,0,8,116,97,98,111,114,100,101,114,2, + 1,8,98,111,117,110,100,115,95,120,2,1,8,98,111,117,110,100,115,95, + 121,2,20,9,98,111,117,110,100,115,95,99,120,3,62,3,9,98,111,117, + 110,100,115,95,99,121,3,18,2,7,97,110,99,104,111,114,115,11,7,97, + 110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,9,97,110,95,98,111,116,116,111,109,0,7,99,97,112,116,105,111, + 110,6,10,38,84,101,109,112,108,97,116,101,115,0,10,116,116,97,98,119, + 105,100,103,101,116,7,110,101,119,102,105,108,101,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,14,111,112,116,105,111,110,115, + 119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121, + 112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99,97, + 108,101,0,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,62,3,9,98, + 111,117,110,100,115,95,99,121,3,18,2,7,97,110,99,104,111,114,115,11, + 0,15,97,99,116,105,118,101,112,97,103,101,105,110,100,101,120,2,0,20, + 116,97,98,95,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116, + 17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101, + 116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118, + 101,15,102,114,108,95,111,112,116,105,111,110,115,115,107,105,110,0,21,116, + 97,98,95,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108, + 105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,97,99,116,105,118,101,0,9,116,97,98,95,99,111, + 108,111,114,4,3,0,0,128,8,116,97,98,95,115,105,122,101,2,19,8, + 115,116,97,116,102,105,108,101,7,9,115,116,97,116,102,105,108,101,49,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,8,116,116,97, + 98,112,97,103,101,9,116,116,97,98,112,97,103,101,51,14,111,112,116,105, + 111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116, + 103,108,121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111, + 115,99,97,108,101,0,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119, + 95,97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117, + 98,102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100, + 103,101,116,115,0,5,99,111,108,111,114,4,3,0,0,128,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97, + 98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97, + 99,116,105,118,101,0,8,116,97,98,111,114,100,101,114,2,3,8,98,111, + 117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,19,9, + 98,111,117,110,100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95, + 99,121,3,255,1,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101, + 102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,9,97, + 110,95,98,111,116,116,111,109,0,7,99,97,112,116,105,111,110,6,11,78, + 101,119,32,80,114,111,106,101,99,116,8,111,110,108,97,121,111,117,116,7, + 21,110,101,119,112,114,111,106,101,99,116,99,104,105,108,100,115,99,97,108, + 101,100,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,11, + 116,119,105,100,103,101,116,103,114,105,100,8,99,111,112,121,103,114,105,100, + 13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109, + 111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117, + 115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97, + 114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119, + 102,111,99,117,115,111,117,116,17,111,119,95,102,111,99,117,115,98,97,99, + 107,111,110,101,115,99,17,111,119,95,100,101,115,116,114,111,121,119,105,100, + 103,101,116,115,0,5,99,111,108,111,114,4,3,0,0,128,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97, + 98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97, + 99,116,105,118,101,0,8,98,111,117,110,100,115,95,120,2,0,8,98,111, + 117,110,100,115,95,121,2,86,9,98,111,117,110,100,115,95,99,120,3,62, + 3,9,98,111,117,110,100,115,95,99,121,3,167,1,7,97,110,99,104,111, + 114,115,11,6,97,110,95,116,111,112,9,97,110,95,98,111,116,116,111,109, + 0,11,111,112,116,105,111,110,115,103,114,105,100,11,12,111,103,95,99,111, + 108,115,105,122,105,110,103,15,111,103,95,107,101,121,99,111,108,109,111,118, + 105,110,103,12,111,103,95,114,111,119,109,111,118,105,110,103,15,111,103,95, + 107,101,121,114,111,119,109,111,118,105,110,103,15,111,103,95,114,111,119,105, + 110,115,101,114,116,105,110,103,14,111,103,95,114,111,119,100,101,108,101,116, + 105,110,103,19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110, + 116,101,114,15,111,103,95,97,117,116,111,102,105,114,115,116,114,111,119,13, + 111,103,95,97,117,116,111,97,112,112,101,110,100,20,111,103,95,99,111,108, + 99,104,97,110,103,101,111,110,116,97,98,107,101,121,10,111,103,95,119,114, + 97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112,117,112,0,13, + 102,105,120,114,111,119,115,46,99,111,117,110,116,2,1,13,102,105,120,114, + 111,119,115,46,105,116,101,109,115,14,1,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,25,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107, + 101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,97,99,116,105,118,101,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101, + 0,6,104,101,105,103,104,116,2,16,14,99,97,112,116,105,111,110,115,46, + 99,111,117,110,116,2,4,14,99,97,112,116,105,111,110,115,46,105,116,101, + 109,115,14,1,7,99,97,112,116,105,111,110,6,1,76,4,104,105,110,116, + 6,19,76,111,97,100,32,102,105,108,101,32,105,110,32,101,100,105,116,111, + 114,0,1,7,99,97,112,116,105,111,110,6,1,77,4,104,105,110,116,6, + 13,69,120,112,97,110,100,32,109,97,99,114,111,115,0,1,7,99,97,112, + 116,105,111,110,6,12,67,111,112,105,101,100,32,70,105,108,101,115,0,1, + 7,99,97,112,116,105,111,110,6,11,68,101,115,116,105,110,97,116,105,111, + 110,0,0,0,0,14,100,97,116,97,99,111,108,115,46,99,111,117,110,116, + 2,4,16,100,97,116,97,99,111,108,115,46,111,112,116,105,111,110,115,11, + 14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109, + 111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108, + 101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99, + 111,95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,118, + 97,108,117,101,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111, + 95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101, + 17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,14, + 100,97,116,97,99,111,108,115,46,105,116,101,109,115,14,7,15,108,111,97, + 100,112,114,111,106,101,99,116,102,105,108,101,1,5,119,105,100,116,104,2, + 18,7,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111, + 99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99, + 111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121, + 115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99, + 116,12,99,111,95,114,111,119,115,101,108,101,99,116,11,99,111,95,102,105, + 120,119,105,100,116,104,12,99,111,95,115,97,118,101,115,116,97,116,101,10, + 99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115, + 116,101,0,10,119,105,100,103,101,116,110,97,109,101,6,15,108,111,97,100, + 112,114,111,106,101,99,116,102,105,108,101,9,100,97,116,97,99,108,97,115, + 115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108, + 105,115,116,0,7,23,101,120,112,97,110,100,112,114,111,106,101,99,116,102, + 105,108,101,109,97,99,114,111,115,1,5,119,105,100,116,104,2,18,7,111, + 112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117,115, + 14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109, + 111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108, + 101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99, + 111,95,114,111,119,115,101,108,101,99,116,11,99,111,95,102,105,120,119,105, + 100,116,104,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95, + 99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,0, + 10,119,105,100,103,101,116,110,97,109,101,6,23,101,120,112,97,110,100,112, + 114,111,106,101,99,116,102,105,108,101,109,97,99,114,111,115,9,100,97,116, + 97,99,108,97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114, + 100,97,116,97,108,105,115,116,0,7,15,110,101,119,112,114,111,106,101,99, + 116,102,105,108,101,115,1,5,119,105,100,116,104,3,161,1,7,111,112,116, + 105,111,110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116, + 14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107, + 101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108, + 101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,15,99,111,95, + 112,114,111,112,111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101, + 118,97,108,117,101,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99, + 111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116, + 101,0,10,111,110,115,104,111,119,104,105,110,116,7,13,99,111,108,111,110, + 115,104,111,119,104,105,110,116,10,119,105,100,103,101,116,110,97,109,101,6, + 15,110,101,119,112,114,111,106,101,99,116,102,105,108,101,115,9,100,97,116, + 97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116,114,105, + 110,103,100,97,116,97,108,105,115,116,0,7,19,110,101,119,112,114,111,106, + 101,99,116,102,105,108,101,115,100,101,115,116,1,5,119,105,100,116,104,3, + 113,1,7,111,112,116,105,111,110,115,11,14,99,111,95,102,111,99,117,115, + 115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99, + 116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117, + 108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101, + 99,116,7,99,111,95,102,105,108,108,12,99,111,95,115,97,118,101,118,97, + 108,117,101,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95, + 99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,0, + 10,111,110,115,104,111,119,104,105,110,116,7,13,99,111,108,111,110,115,104, + 111,119,104,105,110,116,10,119,105,100,103,101,116,110,97,109,101,6,19,110, + 101,119,112,114,111,106,101,99,116,102,105,108,101,115,100,101,115,116,9,100, + 97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116, + 114,105,110,103,100,97,116,97,108,105,115,116,0,0,13,100,97,116,97,114, + 111,119,104,101,105,103,104,116,2,16,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,14,0,12,116,98,111,111,108,101,97,110,101,100,105,116, + 15,108,111,97,100,112,114,111,106,101,99,116,102,105,108,101,11,111,112,116, + 105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98, + 117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114, + 108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98, + 108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99, + 116,105,118,101,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117, + 110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,120,2,18,9,98,111,117,110,100,115,95,99,121, + 2,16,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117, + 110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101, + 114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12, + 111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101, + 116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105, + 116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110, + 116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101, + 95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108, + 105,99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111, + 101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49, + 95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101, + 115,116,97,116,101,0,7,118,105,115,105,98,108,101,8,0,0,12,116,98, + 111,111,108,101,97,110,101,100,105,116,23,101,120,112,97,110,100,112,114,111, + 106,101,99,116,102,105,108,101,109,97,99,114,111,115,11,111,112,116,105,111, + 110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116, + 116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101,118,101,108, + 111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110, + 116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95, + 99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101, + 100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105, + 118,101,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100, + 115,95,120,2,19,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,120,2,18,9,98,111,117,110,100,115,95,99,121,2,16, + 11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100, + 111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121, + 16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101, + 95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115, + 101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111, + 110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101, + 114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97, + 117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99, + 107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101,49, + 95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95,107, + 101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115,116, + 97,116,101,0,7,118,105,115,105,98,108,101,8,0,0,13,116,102,105,108, + 101,110,97,109,101,101,100,105,116,15,110,101,119,112,114,111,106,101,99,116, + 102,105,108,101,115,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111, + 115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,12, + 102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101, + 46,99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95, + 108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101, + 110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99, + 108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,97,99,116,105,118,101,0,19,102,114,97,109,101, + 46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1,19,102,114,97, + 109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,5,99, + 111,108,111,114,4,5,0,0,144,7,105,109,97,103,101,110,114,2,17,0, + 0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111,114, + 4,5,0,0,144,20,102,114,97,109,101,46,98,117,116,116,111,110,46,105, + 109,97,103,101,110,114,2,17,8,116,97,98,111,114,100,101,114,2,3,10, + 111,110,115,104,111,119,104,105,110,116,7,18,104,105,110,116,101,120,112,97, + 110,100,101,100,109,97,99,114,111,115,7,118,105,115,105,98,108,101,8,8, + 98,111,117,110,100,115,95,120,2,38,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,3,161,1,9,98,111,117,110,100, + 115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11, + 13,111,101,49,95,115,97,118,101,118,97,108,117,101,0,24,99,111,110,116, + 114,111,108,108,101,114,46,111,110,103,101,116,102,105,108,101,110,97,109,101, + 7,14,101,120,112,97,110,100,102,105,108,101,110,97,109,101,13,114,101,102, + 102,111,110,116,104,101,105,103,104,116,2,14,0,0,11,116,115,116,114,105, + 110,103,101,100,105,116,19,110,101,119,112,114,111,106,101,99,116,102,105,108, + 101,115,100,101,115,116,14,111,112,116,105,111,110,115,119,105,100,103,101,116, + 49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103, + 104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107, + 95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,12,102,114, + 97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99, + 111,108,111,114,99,108,105,101,110,116,4,3,0,0,128,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101, + 118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105, + 99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,97,99,116,105,118,101,0,8,116,97,98,111,114,100,101, + 114,2,4,10,111,110,115,104,111,119,104,105,110,116,7,18,104,105,110,116, + 101,120,112,97,110,100,101,100,109,97,99,114,111,115,7,118,105,115,105,98, + 108,101,8,8,98,111,117,110,100,115,95,120,3,200,1,8,98,111,117,110, + 100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,113,1,9, + 98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101, + 100,105,116,49,11,13,111,101,49,95,115,97,118,101,118,97,108,117,101,0, + 11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100, + 111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121, + 16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101, + 95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115, + 101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111, + 110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101, + 114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97, + 117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99, + 107,12,111,101,95,116,114,105,109,114,105,103,104,116,11,111,101,95,116,114, + 105,109,108,101,102,116,0,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,0,0,13,116,102,105,108,101,110,97,109,101,101,100,105,116, + 16,115,99,114,105,112,116,98,101,102,111,114,101,99,111,112,121,11,111,112, + 116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101, + 98,117,116,116,111,110,111,110,108,121,0,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,18,83,99,114,105,112,116,32,98,101,102,111,114,101, + 32,99,111,112,121,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116, + 101,120,116,102,108,97,103,115,11,9,116,102,95,98,111,116,116,111,109,0, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115, + 101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,19,102,114, + 97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1,19, + 102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14, + 1,5,99,111,108,111,114,4,2,0,0,128,7,105,109,97,103,101,110,114, + 2,17,0,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111, + 108,111,114,4,2,0,0,128,20,102,114,97,109,101,46,98,117,116,116,111, + 110,46,105,109,97,103,101,110,114,2,17,16,102,114,97,109,101,46,111,117, + 116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116, + 97,98,111,114,100,101,114,2,1,10,111,110,115,104,111,119,104,105,110,116, + 7,18,104,105,110,116,101,120,112,97,110,100,101,100,109,97,99,114,111,115, + 8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121, + 2,3,9,98,111,117,110,100,115,95,99,120,3,62,3,9,98,111,117,110, + 100,115,95,99,121,2,37,7,97,110,99,104,111,114,115,11,6,97,110,95, + 116,111,112,0,24,99,111,110,116,114,111,108,108,101,114,46,111,110,103,101, + 116,102,105,108,101,110,97,109,101,7,14,101,120,112,97,110,100,102,105,108, + 101,110,97,109,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,0,13,116,102,105,108,101,110,97,109,101,101,100,105,116,15,115,99, + 114,105,112,116,97,102,116,101,114,99,111,112,121,11,111,112,116,105,111,110, + 115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116, + 111,110,111,110,108,121,0,13,102,114,97,109,101,46,99,97,112,116,105,111, + 110,6,17,83,99,114,105,112,116,32,97,102,116,101,114,32,99,111,112,121, + 22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102,108, + 97,103,115,11,9,116,102,95,98,111,116,116,111,109,0,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101, + 118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105, + 99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,97,99,116,105,118,101,0,19,102,114,97,109,101,46,98, + 117,116,116,111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101, + 46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111,108, + 111,114,4,2,0,0,128,7,105,109,97,103,101,110,114,2,17,0,0,18, + 102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111,114,4,2, + 0,0,128,20,102,114,97,109,101,46,98,117,116,116,111,110,46,105,109,97, + 103,101,110,114,2,17,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100, + 101,114,2,2,10,111,110,115,104,111,119,104,105,110,116,7,18,104,105,110, + 116,101,120,112,97,110,100,101,100,109,97,99,114,111,115,8,98,111,117,110, + 100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,40,9,98,111, + 117,110,100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121, + 2,37,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,0,24, + 99,111,110,116,114,111,108,108,101,114,46,111,110,103,101,116,102,105,108,101, + 110,97,109,101,7,14,101,120,112,97,110,100,102,105,108,101,110,97,109,101, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,8, + 116,116,97,98,112,97,103,101,9,116,116,97,98,112,97,103,101,52,14,111, + 112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102, + 111,110,116,103,108,121,112,104,104,101,105,103,104,116,13,111,119,49,95,97, + 117,116,111,115,99,97,108,101,0,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111, + 119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102, + 111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110, + 16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119, + 95,115,117,98,102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121, + 119,105,100,103,101,116,115,0,5,99,111,108,111,114,4,3,0,0,128,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117, + 115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100, + 105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101, + 100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,97,99,116,105,118,101,0,8,116,97,98,111,114,100,101,114,2,2, + 8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121, + 2,19,9,98,111,117,110,100,115,95,99,120,3,62,3,9,98,111,117,110, + 100,115,95,99,121,3,255,1,7,97,110,99,104,111,114,115,11,7,97,110, + 95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104, + 116,9,97,110,95,98,111,116,116,111,109,0,7,99,97,112,116,105,111,110, + 6,8,78,101,119,32,70,105,108,101,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,14,0,11,116,119,105,100,103,101,116,103,114,105,100,12, + 116,119,105,100,103,101,116,103,114,105,100,49,5,99,111,108,111,114,4,3, + 0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115, + 95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,62,3,9,98,111, + 117,110,100,115,95,99,121,3,255,1,7,97,110,99,104,111,114,115,11,0, + 11,111,112,116,105,111,110,115,103,114,105,100,11,12,111,103,95,99,111,108, + 115,105,122,105,110,103,12,111,103,95,114,111,119,109,111,118,105,110,103,15, + 111,103,95,107,101,121,114,111,119,109,111,118,105,110,103,15,111,103,95,114, + 111,119,105,110,115,101,114,116,105,110,103,14,111,103,95,114,111,119,100,101, + 108,101,116,105,110,103,19,111,103,95,102,111,99,117,115,99,101,108,108,111, + 110,101,110,116,101,114,15,111,103,95,97,117,116,111,102,105,114,115,116,114, + 111,119,13,111,103,95,97,117,116,111,97,112,112,101,110,100,20,111,103,95, + 99,111,108,99,104,97,110,103,101,111,110,116,97,98,107,101,121,10,111,103, + 95,119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112,117, + 112,17,111,103,95,109,111,117,115,101,115,99,114,111,108,108,99,111,108,0, + 13,102,105,120,99,111,108,115,46,99,111,117,110,116,2,1,13,102,105,120, + 99,111,108,115,46,105,116,101,109,115,14,1,5,119,105,100,116,104,2,27, + 7,110,117,109,115,116,101,112,2,1,0,0,13,102,105,120,114,111,119,115, + 46,99,111,117,110,116,2,1,13,102,105,120,114,111,119,115,46,105,116,101, + 109,115,14,1,6,104,101,105,103,104,116,2,16,14,99,97,112,116,105,111, + 110,115,46,99,111,117,110,116,2,5,14,99,97,112,116,105,111,110,115,46, + 105,116,101,109,115,14,1,7,99,97,112,116,105,111,110,6,4,75,105,110, + 100,0,1,7,99,97,112,116,105,111,110,6,6,70,105,108,116,101,114,0, + 1,7,99,97,112,116,105,111,110,6,3,69,120,116,0,1,7,99,97,112, + 116,105,111,110,6,6,83,111,117,114,99,101,0,1,0,0,0,0,14,100, + 97,116,97,99,111,108,115,46,99,111,117,110,116,2,4,16,100,97,116,97, + 99,111,108,115,46,111,112,116,105,111,110,115,11,14,99,111,95,102,111,99, + 117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108, + 101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95, + 109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101, + 108,101,99,116,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111, + 95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101, + 17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,14, + 100,97,116,97,99,111,108,115,46,105,116,101,109,115,14,7,10,110,101,119, + 102,105,110,97,109,101,115,1,5,119,105,100,116,104,2,124,7,111,112,116, + 105,111,110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116, + 14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107, + 101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108, + 101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,15,99,111,95, + 112,114,111,112,111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101, + 115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95, + 99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114, + 111,108,108,114,111,119,0,10,111,110,115,104,111,119,104,105,110,116,7,13, + 99,111,108,111,110,115,104,111,119,104,105,110,116,10,119,105,100,103,101,116, + 110,97,109,101,6,10,110,101,119,102,105,110,97,109,101,115,9,100,97,116, + 97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116,114,105, + 110,103,100,97,116,97,108,105,115,116,0,7,12,110,101,119,102,105,102,105, + 108,116,101,114,115,1,5,119,105,100,116,104,2,110,7,111,112,116,105,111, + 110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99, + 111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121, + 115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99, + 116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97, + 118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99, + 111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115, + 99,114,111,108,108,114,111,119,0,10,111,110,115,104,111,119,104,105,110,116, + 7,13,99,111,108,111,110,115,104,111,119,104,105,110,116,10,119,105,100,103, + 101,116,110,97,109,101,6,12,110,101,119,102,105,102,105,108,116,101,114,115, + 9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101, + 115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,9,110,101,119, + 102,105,101,120,116,115,1,7,111,112,116,105,111,110,115,11,14,99,111,95, + 102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101, + 115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14, + 99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111, + 119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116,97,116,101, + 10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97, + 115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111, + 119,0,10,111,110,115,104,111,119,104,105,110,116,7,13,99,111,108,111,110, + 115,104,111,119,104,105,110,116,10,119,105,100,103,101,116,110,97,109,101,6, + 9,110,101,119,102,105,101,120,116,115,9,100,97,116,97,99,108,97,115,115, + 7,22,116,103,114,105,100,109,115,101,115,116,114,105,110,103,100,97,116,97, + 108,105,115,116,0,7,12,110,101,119,102,105,115,111,117,114,99,101,115,1, + 5,119,105,100,116,104,3,254,1,7,111,112,116,105,111,110,115,11,14,99, + 111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117, + 115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99, + 116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95, + 114,111,119,115,101,108,101,99,116,7,99,111,95,102,105,108,108,12,99,111, + 95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112, + 121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117, + 115,101,115,99,114,111,108,108,114,111,119,0,10,111,110,115,104,111,119,104, + 105,110,116,7,13,99,111,108,111,110,115,104,111,119,104,105,110,116,10,119, + 105,100,103,101,116,110,97,109,101,6,12,110,101,119,102,105,115,111,117,114, + 99,101,115,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100, + 109,115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,0,13, + 100,97,116,97,114,111,119,104,101,105,103,104,116,2,16,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,11,116,115,116,114,105,110,103, + 101,100,105,116,10,110,101,119,102,105,110,97,109,101,115,11,111,112,116,105, + 111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117, + 116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,1, + 10,111,110,115,104,111,119,104,105,110,116,7,18,104,105,110,116,101,120,112, + 97,110,100,101,100,109,97,99,114,111,115,7,118,105,115,105,98,108,101,8, + 8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121, + 2,0,9,98,111,117,110,100,115,95,99,120,2,124,9,98,111,117,110,100, + 115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11, + 0,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110, + 100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114, + 121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111, + 101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116, + 114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99, + 116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114, + 115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,0,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,11,116,115,116, + 114,105,110,103,101,100,105,116,12,110,101,119,102,105,102,105,108,116,101,114, + 115,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119, + 49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,11,111, + 112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109, + 101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101, + 114,2,2,10,111,110,115,104,111,119,104,105,110,116,7,18,104,105,110,116, + 101,120,112,97,110,100,101,100,109,97,99,114,111,115,7,118,105,115,105,98, + 108,101,8,8,98,111,117,110,100,115,95,120,2,125,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,110,9,98,111, + 117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105, + 116,49,11,0,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101, + 95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113, + 117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101, + 108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95, + 101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101, + 108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110, + 99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114, + 0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,11, + 116,115,116,114,105,110,103,101,100,105,116,9,110,101,119,102,105,101,120,116, + 115,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119, + 49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,11,111, + 112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109, + 101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101, + 114,2,3,10,111,110,115,104,111,119,104,105,110,116,7,18,104,105,110,116, + 101,120,112,97,110,100,101,100,109,97,99,114,111,115,7,118,105,115,105,98, + 108,101,8,8,98,111,117,110,100,115,95,120,3,236,0,8,98,111,117,110, + 100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,50,9,98, + 111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100, + 105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111, + 101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101, + 113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99, + 101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101, + 95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115, + 101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111, + 110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101, + 114,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0, + 13,116,102,105,108,101,110,97,109,101,101,100,105,116,12,110,101,119,102,105, + 115,111,117,114,99,101,115,14,111,112,116,105,111,110,115,119,105,100,103,101, + 116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105, + 103,104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115, + 107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,10,102,114,108,95,108,101,118,101,108,105,15,102,114,108, + 95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,19,102,114,97,109,101,46, + 98,117,116,116,111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109, + 101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111, + 108,111,114,4,5,0,0,144,7,105,109,97,103,101,110,114,2,17,0,0, + 18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111,114,4, + 5,0,0,144,20,102,114,97,109,101,46,98,117,116,116,111,110,46,105,109, + 97,103,101,110,114,2,17,8,116,97,98,111,114,100,101,114,2,4,10,111, + 110,115,104,111,119,104,105,110,116,7,18,104,105,110,116,101,120,112,97,110, + 100,101,100,109,97,99,114,111,115,7,118,105,115,105,98,108,101,8,8,98, + 111,117,110,100,115,95,120,3,31,1,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,3,254,1,9,98,111,117,110,100, + 115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11, + 0,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110, + 100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114, + 121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111, + 101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116, + 114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99, + 116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114, + 115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,0,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,0,8,116, + 116,97,98,112,97,103,101,9,116,116,97,98,112,97,103,101,53,14,111,112, + 116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111, + 110,116,103,108,121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117, + 116,111,115,99,97,108,101,0,13,111,112,116,105,111,110,115,119,105,100,103, + 101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119, + 95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111, + 99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16, + 111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95, + 115,117,98,102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,0,5,99,111,108,111,114,4,3,0,0,128,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115, + 101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105, + 115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100, + 26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,97,99,116,105,118,101,0,8,116,97,98,111,114,100,101,114,2,1,8, + 98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2, + 19,9,98,111,117,110,100,115,95,99,120,3,62,3,9,98,111,117,110,100, + 115,95,99,121,3,255,1,7,97,110,99,104,111,114,115,11,7,97,110,95, + 108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116, + 9,97,110,95,98,111,116,116,111,109,0,7,99,97,112,116,105,111,110,6, + 8,78,101,119,32,70,111,114,109,8,111,110,108,97,121,111,117,116,7,25, + 102,111,114,109,116,101,109,112,108,97,116,101,111,110,99,104,105,108,100,115, + 99,97,108,101,100,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,11,116,119,105,100,103,101,116,103,114,105,100,12,116,119,105,100,103, + 101,116,103,114,105,100,52,5,99,111,108,111,114,4,3,0,0,128,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,98,111, + 117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95, + 99,121,3,255,1,7,97,110,99,104,111,114,115,11,0,11,111,112,116,105, + 111,110,115,103,114,105,100,11,12,111,103,95,99,111,108,115,105,122,105,110, + 103,12,111,103,95,114,111,119,109,111,118,105,110,103,15,111,103,95,107,101, + 121,114,111,119,109,111,118,105,110,103,15,111,103,95,114,111,119,105,110,115, + 101,114,116,105,110,103,14,111,103,95,114,111,119,100,101,108,101,116,105,110, + 103,19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101, + 114,15,111,103,95,97,117,116,111,102,105,114,115,116,114,111,119,13,111,103, + 95,97,117,116,111,97,112,112,101,110,100,12,111,103,95,115,97,118,101,115, + 116,97,116,101,20,111,103,95,99,111,108,99,104,97,110,103,101,111,110,116, + 97,98,107,101,121,10,111,103,95,119,114,97,112,99,111,108,12,111,103,95, + 97,117,116,111,112,111,112,117,112,17,111,103,95,109,111,117,115,101,115,99, + 114,111,108,108,99,111,108,0,13,102,105,120,99,111,108,115,46,99,111,117, + 110,116,2,1,13,102,105,120,99,111,108,115,46,105,116,101,109,115,14,1, + 5,119,105,100,116,104,2,23,7,110,117,109,115,116,101,112,2,1,0,0, + 13,102,105,120,114,111,119,115,46,99,111,117,110,116,2,1,13,102,105,120, + 114,111,119,115,46,105,116,101,109,115,14,1,6,104,101,105,103,104,116,2, + 16,14,99,97,112,116,105,111,110,115,46,99,111,117,110,116,2,6,14,99, + 97,112,116,105,111,110,115,46,105,116,101,109,115,14,1,7,99,97,112,116, + 105,111,110,6,4,75,105,110,100,0,1,7,99,97,112,116,105,111,110,6, + 1,73,4,104,105,110,116,6,9,73,110,104,101,114,105,116,101,100,0,1, + 7,99,97,112,116,105,111,110,6,8,78,97,109,101,98,97,115,101,0,1, + 7,99,97,112,116,105,111,110,6,10,70,111,114,109,115,117,102,102,105,120, + 0,1,7,99,97,112,116,105,111,110,6,11,83,111,117,114,99,101,32,70, + 105,108,101,0,1,7,99,97,112,116,105,111,110,6,9,70,111,114,109,32, + 70,105,108,101,0,0,0,0,14,100,97,116,97,99,111,108,115,46,99,111, + 117,110,116,2,6,16,100,97,116,97,99,111,108,115,46,111,112,116,105,111, + 110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99, + 111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121, + 115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99, + 116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97, + 118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99, + 111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115, + 99,114,111,108,108,114,111,119,0,14,100,97,116,97,99,111,108,115,46,105, + 116,101,109,115,14,7,10,110,101,119,102,111,110,97,109,101,115,1,5,119, + 105,100,116,104,2,96,7,111,112,116,105,111,110,115,11,14,99,111,95,102, + 111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115, + 101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99, + 111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119, + 115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116,97,116,101,10, + 99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115, + 116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119, + 0,4,110,97,109,101,6,10,110,101,119,102,111,110,97,109,101,115,10,111, + 110,115,104,111,119,104,105,110,116,7,13,99,111,108,111,110,115,104,111,119, + 104,105,110,116,10,119,105,100,103,101,116,110,97,109,101,6,10,110,101,119, + 102,111,110,97,109,101,115,9,100,97,116,97,99,108,97,115,115,7,22,116, + 103,114,105,100,109,115,101,115,116,114,105,110,103,100,97,116,97,108,105,115, + 116,0,7,17,110,101,119,105,110,104,101,114,105,116,101,100,102,111,114,109, + 115,1,5,119,105,100,116,104,2,13,7,111,112,116,105,111,110,115,11,12, + 99,111,95,100,114,97,119,102,111,99,117,115,14,99,111,95,102,111,99,117, + 115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101, + 99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109, + 117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108, + 101,99,116,11,99,111,95,102,105,120,119,105,100,116,104,12,99,111,95,115, + 97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11, + 99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101, + 115,99,114,111,108,108,114,111,119,0,4,110,97,109,101,6,17,110,101,119, + 105,110,104,101,114,105,116,101,100,102,111,114,109,115,10,119,105,100,103,101, + 116,110,97,109,101,6,17,110,101,119,105,110,104,101,114,105,116,101,100,102, + 111,114,109,115,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105, + 100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,14,110, + 101,119,102,111,110,97,109,101,98,97,115,101,115,1,5,119,105,100,116,104, + 2,73,7,111,112,116,105,111,110,115,11,14,99,111,95,102,111,99,117,115, + 115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99, + 116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117, + 108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101, + 99,116,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99, + 97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99, + 111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,4,110,97, + 109,101,6,14,110,101,119,102,111,110,97,109,101,98,97,115,101,115,10,111, + 110,115,104,111,119,104,105,110,116,7,13,99,111,108,111,110,115,104,111,119, + 104,105,110,116,10,119,105,100,103,101,116,110,97,109,101,6,14,110,101,119, + 102,111,110,97,109,101,98,97,115,101,115,9,100,97,116,97,99,108,97,115, + 115,7,22,116,103,114,105,100,109,115,101,115,116,114,105,110,103,100,97,116, + 97,108,105,115,116,0,7,17,110,101,119,102,111,102,111,114,109,115,117,102, + 102,105,120,101,115,1,5,119,105,100,116,104,2,69,7,111,112,116,105,111, + 110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99, + 111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121, + 115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99, + 116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97, + 118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99, + 111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115, + 99,114,111,108,108,114,111,119,0,4,110,97,109,101,6,15,110,101,119,102, + 111,102,111,114,109,115,117,102,102,105,120,10,119,105,100,103,101,116,110,97, + 109,101,6,17,110,101,119,102,111,102,111,114,109,115,117,102,102,105,120,101, + 115,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115, + 101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,12,110,101, + 119,102,111,115,111,117,114,99,101,115,1,5,119,105,100,116,104,3,37,1, + 7,111,112,116,105,111,110,115,11,14,99,111,95,102,111,99,117,115,115,101, + 108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12, + 99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116, + 105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116, + 15,99,111,95,112,114,111,112,111,114,116,105,111,110,97,108,12,99,111,95, + 115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121, + 11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115, + 101,115,99,114,111,108,108,114,111,119,0,4,110,97,109,101,6,12,110,101, + 119,102,111,115,111,117,114,99,101,115,10,111,110,115,104,111,119,104,105,110, + 116,7,13,99,111,108,111,110,115,104,111,119,104,105,110,116,10,119,105,100, + 103,101,116,110,97,109,101,6,12,110,101,119,102,111,115,111,117,114,99,101, + 115,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115, + 101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,10,110,101, + 119,102,111,102,111,114,109,115,1,5,119,105,100,116,104,3,252,0,7,111, + 112,116,105,111,110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101, + 99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111, + 95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115, + 101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,7,99, + 111,95,102,105,108,108,12,99,111,95,115,97,118,101,115,116,97,116,101,10, + 99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115, + 116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119, + 0,4,110,97,109,101,6,10,109,101,119,102,111,102,111,114,109,115,10,111, + 110,115,104,111,119,104,105,110,116,7,13,99,111,108,111,110,115,104,111,119, + 104,105,110,116,10,119,105,100,103,101,116,110,97,109,101,6,10,110,101,119, + 102,111,102,111,114,109,115,9,100,97,116,97,99,108,97,115,115,7,22,116, + 103,114,105,100,109,115,101,115,116,114,105,110,103,100,97,116,97,108,105,115, + 116,0,0,13,100,97,116,97,114,111,119,104,101,105,103,104,116,2,16,8, + 115,116,97,116,102,105,108,101,7,9,115,116,97,116,102,105,108,101,49,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,11,116,115,116, + 114,105,110,103,101,100,105,116,10,110,101,119,102,111,110,97,109,101,115,11, + 111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97, + 109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100, + 101,114,2,1,10,111,110,115,104,111,119,104,105,110,116,7,18,104,105,110, + 116,101,120,112,97,110,100,101,100,109,97,99,114,111,115,7,118,105,115,105, + 98,108,101,8,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110, + 100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,96,9,98, + 111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100, + 105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111, + 101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101, + 113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99, + 101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101, + 95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115, + 101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111, + 110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101, + 114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97, + 117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99, + 107,18,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116, + 0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,12, + 116,98,111,111,108,101,97,110,101,100,105,116,17,110,101,119,105,110,104,101, + 114,105,116,101,100,102,111,114,109,115,11,111,112,116,105,111,110,115,115,107, + 105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111, + 110,108,121,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110, + 100,115,95,120,2,97,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,121,2,16,11,111,112,116,105,111,110,115,101,100,105, + 116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99, + 108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114, + 99,97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114, + 110,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101, + 115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101, + 120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110, + 101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25, + 111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116, + 99,108,105,99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11, + 17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111, + 101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97, + 118,101,115,116,97,116,101,0,7,118,105,115,105,98,108,101,8,0,0,11, + 116,115,116,114,105,110,103,101,100,105,116,14,110,101,119,102,111,110,97,109, + 101,98,97,115,101,115,14,111,112,116,105,111,110,115,119,105,100,103,101,116, + 49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103, + 104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107, + 95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97, + 98,111,114,100,101,114,2,3,10,111,110,115,104,111,119,104,105,110,116,7, + 18,104,105,110,116,101,120,112,97,110,100,101,100,109,97,99,114,111,115,7, + 118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,111,8, + 98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120, + 2,73,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111, + 110,115,101,100,105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105, + 116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99, + 108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114, + 99,97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114, + 110,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101, + 115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101, + 120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110, + 101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25, + 111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116, + 99,108,105,99,107,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,11,116,115,116,114,105,110,103,101,100,105,116,17,110,101,119, + 102,111,102,111,114,109,115,117,102,102,105,120,101,115,14,111,112,116,105,111, + 110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103, + 108,121,112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110,115,115, + 107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110, + 111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,4,10,111,110,115, + 104,111,119,104,105,110,116,7,18,104,105,110,116,101,120,112,97,110,100,101, + 100,109,97,99,114,111,115,7,118,105,115,105,98,108,101,8,8,98,111,117, + 110,100,115,95,120,3,185,0,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,120,2,69,9,98,111,117,110,100,115,95,99, + 121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,0,11,111, + 112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111, + 110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111, + 101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115, + 104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116, + 117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110, + 101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114, + 13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117, + 116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101, + 99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,13,116,102,105,108,101,110, + 97,109,101,101,100,105,116,12,110,101,119,102,111,115,111,117,114,99,101,115, + 14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49, + 95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,11,111,112, + 116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101, + 98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101, + 118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108, + 105,101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,10,102, + 114,108,95,108,101,118,101,108,105,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,19,102,114,97,109,101,46,98,117,116,116,111,110,115, + 46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116,116,111, + 110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4,5,0,0, + 144,7,105,109,97,103,101,110,114,2,17,0,0,18,102,114,97,109,101,46, + 98,117,116,116,111,110,46,99,111,108,111,114,4,5,0,0,144,20,102,114, + 97,109,101,46,98,117,116,116,111,110,46,105,109,97,103,101,110,114,2,17, + 8,116,97,98,111,114,100,101,114,2,5,10,111,110,115,104,111,119,104,105, + 110,116,7,18,104,105,110,116,101,120,112,97,110,100,101,100,109,97,99,114, + 111,115,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120, + 3,255,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100, + 115,95,99,120,3,37,1,9,98,111,117,110,100,115,95,99,121,2,16,12, + 111,112,116,105,111,110,115,101,100,105,116,49,11,0,11,111,112,116,105,111, + 110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99, + 13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104, + 101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105,102,116, + 114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114,110,20, + 111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116, + 15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95, + 101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101, + 108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110, + 102,105,114,115,116,99,108,105,99,107,0,26,99,111,110,116,114,111,108,108, + 101,114,46,102,105,108,116,101,114,108,105,115,116,46,100,97,116,97,1,1, + 6,6,83,111,117,114,99,101,6,14,34,42,46,112,97,115,34,32,34,42, + 46,112,112,34,0,1,6,9,65,108,108,32,70,105,108,101,115,6,1,42, + 0,0,24,99,111,110,116,114,111,108,108,101,114,46,111,110,103,101,116,102, + 105,108,101,110,97,109,101,7,14,101,120,112,97,110,100,102,105,108,101,110, + 97,109,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0, + 0,13,116,102,105,108,101,110,97,109,101,101,100,105,116,10,110,101,119,102, + 111,102,111,114,109,115,14,111,112,116,105,111,110,115,119,105,100,103,101,116, + 49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103, + 104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107, + 95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,12,102,114, + 97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99, + 111,108,111,114,99,108,105,101,110,116,4,3,0,0,128,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101, + 118,101,108,111,10,102,114,108,95,108,101,118,101,108,105,15,102,114,108,95, + 99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,19,102,114,97,109,101,46,98, + 117,116,116,111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101, + 46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111,108, + 111,114,4,5,0,0,144,7,105,109,97,103,101,110,114,2,17,0,0,18, + 102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111,114,4,5, + 0,0,144,20,102,114,97,109,101,46,98,117,116,116,111,110,46,105,109,97, + 103,101,110,114,2,17,8,116,97,98,111,114,100,101,114,2,6,10,111,110, + 115,104,111,119,104,105,110,116,7,18,104,105,110,116,101,120,112,97,110,100, + 101,100,109,97,99,114,111,115,7,118,105,115,105,98,108,101,8,8,98,111, + 117,110,100,115,95,120,3,37,2,8,98,111,117,110,100,115,95,121,2,0, + 9,98,111,117,110,100,115,95,99,120,3,252,0,9,98,111,117,110,100,115, + 95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,0, + 11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100, + 111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121, + 16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101, + 95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114, + 101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116, + 111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115, + 111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95, + 97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101, + 108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,26,99,111, + 110,116,114,111,108,108,101,114,46,102,105,108,116,101,114,108,105,115,116,46, + 100,97,116,97,1,1,6,10,70,111,114,109,32,70,105,108,101,115,6,5, + 42,46,109,102,109,0,1,6,9,65,108,108,32,70,105,108,101,115,6,1, + 42,0,0,24,99,111,110,116,114,111,108,108,101,114,46,111,110,103,101,116, + 102,105,108,101,110,97,109,101,7,14,101,120,112,97,110,100,102,105,108,101, + 110,97,109,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,0,0,0,0,0,8,116,116,97,98,112,97,103,101,10,116,116,97,98, + 112,97,103,101,49,53,14,111,112,116,105,111,110,115,119,105,100,103,101,116, + 49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103, + 104,116,13,111,119,49,95,97,117,116,111,115,99,97,108,101,0,13,111,112, + 116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115, + 101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111, + 119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99, + 117,115,111,117,116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119, + 95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,25,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,97,99,116,105,118,101,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97, + 98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97, + 99,116,105,118,101,0,8,116,97,98,111,114,100,101,114,2,8,8,98,111, + 117,110,100,115,95,120,2,1,8,98,111,117,110,100,115,95,121,2,20,9, + 98,111,117,110,100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95, + 99,121,3,18,2,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101, + 102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,9,97, + 110,95,98,111,116,116,111,109,0,7,99,97,112,116,105,111,110,6,6,84, + 111,111,38,108,115,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,11,116,119,105,100,103,101,116,103,114,105,100,12,116,119,105,100,103, + 101,116,103,114,105,100,51,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95, + 116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111, + 119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,102, + 111,99,117,115,98,97,99,107,111,110,101,115,99,13,111,119,95,109,111,117, + 115,101,119,104,101,101,108,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108, + 101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111, + 112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104, + 116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116, + 111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99, + 116,105,118,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111, + 102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101, + 27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,8,98,111,117, + 110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95,99, + 121,3,18,2,7,97,110,99,104,111,114,115,11,0,11,111,112,116,105,111, + 110,115,103,114,105,100,11,12,111,103,95,99,111,108,115,105,122,105,110,103, + 12,111,103,95,114,111,119,109,111,118,105,110,103,15,111,103,95,107,101,121, + 114,111,119,109,111,118,105,110,103,15,111,103,95,114,111,119,105,110,115,101, + 114,116,105,110,103,14,111,103,95,114,111,119,100,101,108,101,116,105,110,103, + 19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101,114, + 15,111,103,95,97,117,116,111,102,105,114,115,116,114,111,119,13,111,103,95, + 97,117,116,111,97,112,112,101,110,100,20,111,103,95,99,111,108,99,104,97, + 110,103,101,111,110,116,97,98,107,101,121,10,111,103,95,119,114,97,112,99, + 111,108,12,111,103,95,97,117,116,111,112,111,112,117,112,17,111,103,95,109, + 111,117,115,101,115,99,114,111,108,108,99,111,108,0,13,102,105,120,99,111, + 108,115,46,99,111,117,110,116,2,1,13,102,105,120,99,111,108,115,46,105, + 116,101,109,115,14,1,5,119,105,100,116,104,2,18,8,110,117,109,115,116, + 97,114,116,2,1,7,110,117,109,115,116,101,112,2,1,0,0,13,102,105, + 120,114,111,119,115,46,99,111,117,110,116,2,1,13,102,105,120,114,111,119, + 115,46,105,116,101,109,115,14,1,6,104,101,105,103,104,116,2,16,14,99, + 97,112,116,105,111,110,115,46,99,111,117,110,116,2,10,14,99,97,112,116, + 105,111,110,115,46,105,116,101,109,115,14,1,7,99,97,112,116,105,111,110, + 6,1,83,4,104,105,110,116,6,10,83,97,118,101,32,102,105,108,101,115, + 0,1,7,99,97,112,116,105,111,110,6,1,80,4,104,105,110,116,6,12, + 80,97,114,115,101,32,115,111,117,114,99,101,0,1,7,99,97,112,116,105, + 111,110,6,1,72,4,104,105,110,116,6,25,72,105,100,101,32,99,111,110, + 115,111,108,101,32,40,119,105,110,51,50,32,111,110,108,121,41,0,1,7, + 99,97,112,116,105,111,110,6,1,77,4,104,105,110,116,6,30,83,104,111, + 119,32,111,117,116,112,117,116,32,105,110,32,109,101,115,115,97,103,101,115, + 32,119,105,110,100,111,119,0,1,7,99,97,112,116,105,111,110,6,4,77, + 101,110,117,0,1,7,99,97,112,116,105,111,110,6,8,83,104,111,114,116, + 99,117,116,4,104,105,110,116,6,79,83,101,108,101,99,116,32,105,116,101, + 109,32,102,114,111,109,32,39,83,101,116,116,105,110,103,115,39,45,39,67, + 111,110,102,105,103,117,114,101,32,77,83,69,105,100,101,39,45,39,83,104, + 111,114,116,99,117,116,115,39,10,39,84,111,111,108,32,49,39,46,46,39, + 84,111,111,108,32,49,48,39,46,0,1,7,99,97,112,116,105,111,110,6, + 6,83,99,46,75,101,121,4,104,105,110,116,6,12,83,104,111,114,116,99, + 117,116,32,107,101,121,0,1,7,99,97,112,116,105,111,110,6,7,65,108, + 116,46,83,99,46,4,104,105,110,116,6,22,65,108,116,101,114,110,97,116, + 101,32,115,104,111,114,116,99,117,116,32,107,101,121,0,1,7,99,97,112, + 116,105,111,110,6,4,70,105,108,101,0,1,7,99,97,112,116,105,111,110, + 6,10,80,97,114,97,109,101,116,101,114,115,0,0,0,0,14,100,97,116, + 97,99,111,108,115,46,99,111,117,110,116,2,10,16,100,97,116,97,99,111, + 108,115,46,111,112,116,105,111,110,115,11,14,99,111,95,102,111,99,117,115, + 115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99, + 116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117, + 108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101, + 99,116,15,99,111,95,112,114,111,112,111,114,116,105,111,110,97,108,12,99, + 111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111, + 112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111, + 117,115,101,115,99,114,111,108,108,114,111,119,0,14,100,97,116,97,99,111, + 108,115,46,105,116,101,109,115,14,7,8,116,111,111,108,115,97,118,101,1, + 5,119,105,100,116,104,2,13,7,111,112,116,105,111,110,115,11,12,99,111, + 95,100,114,97,119,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115, + 101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116, + 12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108, + 116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99, + 116,11,99,111,95,102,105,120,119,105,100,116,104,15,99,111,95,112,114,111, + 112,111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,115,116,97, + 116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110, + 112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108, + 114,111,119,0,8,119,105,100,116,104,109,105,110,2,13,8,119,105,100,116, + 104,109,97,120,2,13,10,119,105,100,103,101,116,110,97,109,101,6,8,116, + 111,111,108,115,97,118,101,9,100,97,116,97,99,108,97,115,115,7,20,116, + 103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0, + 7,9,116,111,111,108,112,97,114,115,101,1,5,119,105,100,116,104,2,13, + 7,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99, + 117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111, + 95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115, + 101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116, + 12,99,111,95,114,111,119,115,101,108,101,99,116,11,99,111,95,102,105,120, + 119,105,100,116,104,15,99,111,95,112,114,111,112,111,114,116,105,111,110,97, + 108,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97, + 110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111, + 95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,8,119,105,100, + 116,104,109,105,110,2,13,8,119,105,100,116,104,109,97,120,2,13,10,119, + 105,100,103,101,116,110,97,109,101,6,9,116,111,111,108,112,97,114,115,101, + 9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100,105,110,116, + 101,103,101,114,100,97,116,97,108,105,115,116,0,7,8,116,111,111,108,104, + 105,100,101,1,5,119,105,100,116,104,2,13,7,111,112,116,105,111,110,115, + 11,12,99,111,95,100,114,97,119,102,111,99,117,115,14,99,111,95,102,111, + 99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101, + 108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111, + 95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115, + 101,108,101,99,116,11,99,111,95,102,105,120,119,105,100,116,104,15,99,111, + 95,112,114,111,112,111,114,116,105,111,110,97,108,12,99,111,95,115,97,118, + 101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111, + 95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99, + 114,111,108,108,114,111,119,0,8,119,105,100,116,104,109,105,110,2,13,8, + 119,105,100,116,104,109,97,120,2,13,10,119,105,100,103,101,116,110,97,109, + 101,6,8,116,111,111,108,104,105,100,101,9,100,97,116,97,99,108,97,115, + 115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108, + 105,115,116,0,7,12,116,111,111,108,109,101,115,115,97,103,101,115,1,5, + 119,105,100,116,104,2,13,7,111,112,116,105,111,110,115,11,12,99,111,95, + 100,114,97,119,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101, + 108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12, + 99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116, + 105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116, + 11,99,111,95,102,105,120,119,105,100,116,104,12,99,111,95,115,97,118,101, + 115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95, + 99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114, + 111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,12, + 116,111,111,108,109,101,115,115,97,103,101,115,9,100,97,116,97,99,108,97, + 115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97, + 108,105,115,116,0,7,9,116,111,111,108,109,101,110,117,115,1,5,119,105, + 100,116,104,2,107,7,111,112,116,105,111,110,115,11,14,99,111,95,102,111, + 99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101, + 108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111, + 95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115, + 101,108,101,99,116,15,99,111,95,112,114,111,112,111,114,116,105,111,110,97, + 108,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97, + 110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111, + 95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,111,110,115, + 104,111,119,104,105,110,116,7,13,99,111,108,111,110,115,104,111,119,104,105, + 110,116,10,119,105,100,103,101,116,110,97,109,101,6,9,116,111,111,108,109, + 101,110,117,115,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105, + 100,109,115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,7, + 13,116,111,111,108,115,104,111,114,116,99,117,116,115,1,5,119,105,100,116, + 104,2,86,7,111,112,116,105,111,110,115,11,14,99,111,95,102,111,99,117, + 115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101, + 99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109, + 117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108, + 101,99,116,15,99,111,95,112,114,111,112,111,114,116,105,111,110,97,108,12, + 99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99, + 111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109, + 111,117,115,101,115,99,114,111,108,108,114,111,119,16,99,111,95,114,111,119, + 100,97,116,97,99,104,97,110,103,101,0,10,119,105,100,103,101,116,110,97, + 109,101,6,13,116,111,111,108,115,104,111,114,116,99,117,116,115,9,100,97, + 116,97,99,108,97,115,115,7,17,116,103,114,105,100,101,110,117,109,100,97, + 116,97,108,105,115,116,0,7,6,116,111,111,108,115,99,1,5,99,111,108, + 111,114,4,7,0,0,144,11,99,111,108,111,114,97,99,116,105,118,101,4, + 1,0,0,128,5,119,105,100,116,104,2,55,7,111,112,116,105,111,110,115, + 11,11,99,111,95,114,101,97,100,111,110,108,121,14,99,111,95,102,111,99, + 117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108, + 101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95, + 109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101, + 108,101,99,116,15,99,111,95,112,114,111,112,111,114,116,105,111,110,97,108, + 12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110, + 99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95, + 109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103, + 101,116,110,97,109,101,6,6,116,111,111,108,115,99,9,100,97,116,97,99, + 108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116,114,105,110,103, + 100,97,116,97,108,105,115,116,0,7,9,116,111,111,108,115,99,97,108,116, + 1,5,99,111,108,111,114,4,7,0,0,144,5,119,105,100,116,104,2,55, + 7,111,112,116,105,111,110,115,11,11,99,111,95,114,101,97,100,111,110,108, + 121,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95, + 109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101, + 108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12, + 99,111,95,114,111,119,115,101,108,101,99,116,15,99,111,95,112,114,111,112, + 111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,115,116,97,116, + 101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112, + 97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114, + 111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,9,116,111,111,108, + 115,99,97,108,116,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114, + 105,100,109,115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0, + 7,9,116,111,111,108,102,105,108,101,115,1,5,119,105,100,116,104,2,116, + 7,111,112,116,105,111,110,115,11,14,99,111,95,102,111,99,117,115,115,101, + 108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12, + 99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116, + 105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116, + 7,99,111,95,102,105,108,108,12,99,111,95,115,97,118,101,115,116,97,116, + 101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112, + 97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114, + 111,119,0,10,111,110,115,104,111,119,104,105,110,116,7,13,99,111,108,111, + 110,115,104,111,119,104,105,110,116,10,119,105,100,103,101,116,110,97,109,101, + 6,9,116,111,111,108,102,105,108,101,115,9,100,97,116,97,99,108,97,115, + 115,7,22,116,103,114,105,100,109,115,101,115,116,114,105,110,103,100,97,116, + 97,108,105,115,116,0,7,10,116,111,111,108,112,97,114,97,109,115,1,5, + 119,105,100,116,104,3,70,1,7,111,112,116,105,111,110,115,11,14,99,111, + 95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115, + 101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116, + 14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114, + 111,119,115,101,108,101,99,116,15,99,111,95,112,114,111,112,111,114,116,105, + 111,110,97,108,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111, + 95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101, + 17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10, + 111,110,115,104,111,119,104,105,110,116,7,13,99,111,108,111,110,115,104,111, + 119,104,105,110,116,10,119,105,100,103,101,116,110,97,109,101,6,10,116,111, + 111,108,112,97,114,97,109,115,9,100,97,116,97,99,108,97,115,115,7,22, + 116,103,114,105,100,109,115,101,115,116,114,105,110,103,100,97,116,97,108,105, + 115,116,0,0,13,100,97,116,97,114,111,119,104,101,105,103,104,116,2,16, + 8,115,116,97,116,102,105,108,101,7,9,115,116,97,116,102,105,108,101,49, + 16,111,110,114,111,119,100,97,116,97,99,104,97,110,103,101,100,7,19,116, + 111,111,108,115,114,111,119,100,97,116,97,99,104,97,110,103,101,100,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,12,116,98,111,111, + 108,101,97,110,101,100,105,116,8,116,111,111,108,115,97,118,101,11,111,112, + 116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101, + 98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101, + 118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108, + 105,101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,10,102, + 114,108,95,108,101,118,101,108,105,10,102,114,108,95,102,105,108,101,102,116, + 9,102,114,108,95,102,105,116,111,112,11,102,114,108,95,102,105,114,105,103, + 104,116,12,102,114,108,95,102,105,98,111,116,116,111,109,15,102,114,108,95, + 99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101, + 100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105, + 118,101,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100, + 115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,121,2,16,11,111,112,116,105,111,110,115,101,100,105,116, + 11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108, + 111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99, + 97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110, + 12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115, + 101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120, + 105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101, + 110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111, + 101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99, + 108,105,99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17, + 111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101, + 49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118, + 101,115,116,97,116,101,0,7,118,105,115,105,98,108,101,8,0,0,12,116, + 98,111,111,108,101,97,110,101,100,105,116,9,116,111,111,108,112,97,114,115, + 101,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102, + 114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109, + 101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108, + 111,114,99,108,105,101,110,116,4,3,0,0,128,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101, + 108,111,10,102,114,108,95,108,101,118,101,108,105,10,102,114,108,95,102,105, + 108,101,102,116,9,102,114,108,95,102,105,116,111,112,11,102,114,108,95,102, + 105,114,105,103,104,116,12,102,114,108,95,102,105,98,111,116,116,111,109,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115, + 97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 97,99,116,105,118,101,0,8,116,97,98,111,114,100,101,114,2,2,8,98, + 111,117,110,100,115,95,120,2,14,8,98,111,117,110,100,115,95,121,2,0, + 9,98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105,111,110,115, + 101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111, + 101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99, + 107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101, + 116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101, + 95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111, + 101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110, + 100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101, + 99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105, + 114,115,116,99,108,105,99,107,0,12,111,112,116,105,111,110,115,101,100,105, + 116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110, + 117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49, + 95,115,97,118,101,115,116,97,116,101,0,7,118,105,115,105,98,108,101,8, + 0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,8,116,111,111,108, + 104,105,100,101,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115, + 107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,10,102,114,108,95,108,101,118,101,108,105,10,102,114,108, + 95,102,105,108,101,102,116,9,102,114,108,95,102,105,116,111,112,11,102,114, + 108,95,102,105,114,105,103,104,116,12,102,114,108,95,102,105,98,111,116,116, + 111,109,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107, + 101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,97,99,116,105,118,101,0,8,116,97,98,111,114,100,101,114,2, + 3,8,98,111,117,110,100,115,95,120,2,28,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105, + 111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115, + 99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99, + 104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105,102, + 116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114,110, + 20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105, + 116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101, + 95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115, + 101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111, + 110,102,105,114,115,116,99,108,105,99,107,0,12,111,112,116,105,111,110,115, + 101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112, + 109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13, + 111,101,49,95,115,97,118,101,115,116,97,116,101,0,7,118,105,115,105,98, + 108,101,8,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,12,116, + 111,111,108,109,101,115,115,97,103,101,115,14,111,112,116,105,111,110,115,119, + 105,100,103,101,116,49,11,0,11,111,112,116,105,111,110,115,115,107,105,110, + 11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108, + 121,0,8,116,97,98,111,114,100,101,114,2,4,8,98,111,117,110,100,115, + 95,120,2,42,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,121,2,16,11,111,112,116,105,111,110,115,101,100,105,116,11, + 12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111, + 115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97, + 110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12, + 111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101, + 116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105, + 116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110, + 116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101, + 95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108, + 105,99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111, + 101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49, + 95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101, + 115,116,97,116,101,0,7,118,105,115,105,98,108,101,8,0,0,11,116,115, + 116,114,105,110,103,101,100,105,116,9,116,111,111,108,109,101,110,117,115,11, + 111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97, + 109,101,98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46, + 108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114, + 99,108,105,101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111, + 15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105, + 115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100, + 26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,97,99,116,105,118,101,0,8,116,97,98,111,114,100,101,114,2,5,10, + 111,110,115,104,111,119,104,105,110,116,7,18,104,105,110,116,101,120,112,97, + 110,100,101,100,109,97,99,114,111,115,7,118,105,115,105,98,108,101,8,8, + 98,111,117,110,100,115,95,120,2,56,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,2,107,9,98,111,117,110,100,115, + 95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,0, + 11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100, + 111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121, + 16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101, + 95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114, + 101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116, + 111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115, + 111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,0,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,9,116,101,110,117, + 109,101,100,105,116,13,116,111,111,108,115,104,111,114,116,99,117,116,115,14, + 111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95, + 102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,11,111,112,116, + 105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98, + 117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,10,102,114, + 108,95,108,101,118,101,108,105,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99, + 111,108,111,114,4,5,0,0,144,19,102,114,97,109,101,46,98,117,116,116, + 111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117, + 116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4, + 5,0,0,144,0,0,8,116,97,98,111,114,100,101,114,2,6,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,164,0,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2, + 86,9,98,111,117,110,100,115,95,99,121,2,16,8,115,116,97,116,102,105, + 108,101,7,9,115,116,97,116,102,105,108,101,49,12,111,112,116,105,111,110, + 115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117, + 112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101, + 13,111,101,49,95,115,97,118,101,115,116,97,116,101,27,111,101,49,95,99, + 104,101,99,107,118,97,108,117,101,97,102,116,101,114,115,116,97,116,114,101, + 97,100,0,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95, + 117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117, + 101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108, + 14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101, + 97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108, + 101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99, + 117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13, + 111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116, + 111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,22, + 111,101,95,102,111,99,117,115,114,101,99,116,111,110,114,101,97,100,111,110, + 108,121,18,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120, + 116,0,16,100,114,111,112,100,111,119,110,46,111,112,116,105,111,110,115,11, + 14,100,101,111,95,115,101,108,101,99,116,111,110,108,121,16,100,101,111,95, + 97,117,116,111,100,114,111,112,100,111,119,110,15,100,101,111,95,107,101,121, + 100,114,111,112,100,111,119,110,12,100,101,111,95,99,108,105,112,104,105,110, + 116,13,100,101,111,95,99,111,108,115,105,122,105,110,103,13,100,101,111,95, + 115,97,118,101,115,116,97,116,101,0,14,100,114,111,112,100,111,119,110,46, + 119,105,100,116,104,2,255,19,100,114,111,112,100,111,119,110,46,99,111,108, + 115,46,99,111,117,110,116,2,3,19,100,114,111,112,100,111,119,110,46,99, + 111,108,115,46,119,105,100,116,104,2,70,21,100,114,111,112,100,111,119,110, + 46,99,111,108,115,46,111,112,116,105,111,110,115,11,11,99,111,95,114,101, + 97,100,111,110,108,121,17,99,111,95,109,111,117,115,101,109,111,118,101,102, + 111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,12, + 99,111,95,114,111,119,115,101,108,101,99,116,0,23,100,114,111,112,100,111, + 119,110,46,99,111,108,115,46,108,105,110,101,119,105,100,116,104,2,1,19, + 100,114,111,112,100,111,119,110,46,99,111,108,115,46,105,116,101,109,115,14, + 1,7,111,112,116,105,111,110,115,11,11,99,111,95,114,101,97,100,111,110, + 108,121,17,99,111,95,109,111,117,115,101,109,111,118,101,102,111,99,117,115, + 14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,12,99,111,95,114, + 111,119,115,101,108,101,99,116,0,5,119,105,100,116,104,2,70,9,108,105, + 110,101,119,105,100,116,104,2,1,7,99,97,112,116,105,111,110,6,4,73, + 116,101,109,4,100,97,116,97,1,6,6,84,111,111,108,32,49,6,6,84, + 111,111,108,32,50,6,6,84,111,111,108,32,51,6,6,84,111,111,108,32, + 52,6,6,84,111,111,108,32,53,6,6,84,111,111,108,32,54,6,6,84, + 111,111,108,32,55,6,6,84,111,111,108,32,56,6,6,84,111,111,108,32, + 57,6,7,84,111,111,108,32,49,48,0,0,1,7,111,112,116,105,111,110, + 115,11,11,99,111,95,114,101,97,100,111,110,108,121,17,99,111,95,109,111, + 117,115,101,109,111,118,101,102,111,99,117,115,14,99,111,95,102,111,99,117, + 115,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116, + 0,5,119,105,100,116,104,2,70,9,108,105,110,101,119,105,100,116,104,2, + 1,7,99,97,112,116,105,111,110,6,8,83,104,111,114,116,99,117,116,4, + 100,97,116,97,1,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6, + 0,6,0,6,0,0,0,1,7,111,112,116,105,111,110,115,11,11,99,111, + 95,114,101,97,100,111,110,108,121,17,99,111,95,109,111,117,115,101,109,111, + 118,101,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101, + 99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,0,5,119,105,100, + 116,104,2,70,9,108,105,110,101,119,105,100,116,104,2,1,7,99,97,112, + 116,105,111,110,6,9,65,108,116,101,114,110,97,116,101,4,100,97,116,97, + 1,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6, + 0,0,0,0,8,118,97,108,117,101,109,97,120,2,9,16,111,110,98,101, + 102,111,114,101,100,114,111,112,100,111,119,110,7,20,116,111,111,108,115,104, + 111,114,116,99,117,116,100,114,111,112,100,111,119,110,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,14,0,0,11,116,115,116,114,105,110,103, + 101,100,105,116,6,116,111,111,108,115,99,14,111,112,116,105,111,110,115,119, + 105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112, + 104,104,101,105,103,104,116,0,11,111,112,116,105,111,110,115,115,107,105,110, + 11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108, + 121,0,8,116,97,98,111,114,100,101,114,2,7,7,118,105,115,105,98,108, + 101,8,8,98,111,117,110,100,115,95,120,3,251,0,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,55,9,98,111, + 117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105, + 116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110, + 117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49, + 95,115,97,118,101,115,116,97,116,101,27,111,101,49,95,99,104,101,99,107, + 118,97,108,117,101,97,102,116,101,114,115,116,97,116,114,101,97,100,0,11, + 111,112,116,105,111,110,115,101,100,105,116,11,11,111,101,95,114,101,97,100, + 111,110,108,121,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101, + 95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107, + 109,114,99,97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116, + 117,114,110,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95, + 114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101, + 95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100, + 111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99, + 116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114, + 115,116,99,108,105,99,107,22,111,101,95,102,111,99,117,115,114,101,99,116, + 111,110,114,101,97,100,111,110,108,121,18,111,101,95,104,105,110,116,99,108, + 105,112,112,101,100,116,101,120,116,0,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,14,0,0,11,116,115,116,114,105,110,103,101,100,105,116, + 9,116,111,111,108,115,99,97,108,116,14,111,112,116,105,111,110,115,119,105, + 100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104, + 104,101,105,103,104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11, + 19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121, + 0,8,116,97,98,111,114,100,101,114,2,8,7,118,105,115,105,98,108,101, + 8,8,98,111,117,110,100,115,95,120,3,51,1,8,98,111,117,110,100,115, + 95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,55,9,98,111,117, + 110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116, + 49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117, + 14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95, + 115,97,118,101,115,116,97,116,101,27,111,101,49,95,99,104,101,99,107,118, + 97,108,117,101,97,102,116,101,114,115,116,97,116,114,101,97,100,0,11,111, + 112,116,105,111,110,115,101,100,105,116,11,11,111,101,95,114,101,97,100,111, + 110,108,121,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95, + 99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109, + 114,99,97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117, + 114,110,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114, + 101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95, + 101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111, + 110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116, + 25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115, + 116,99,108,105,99,107,22,111,101,95,102,111,99,117,115,114,101,99,116,111, + 110,114,101,97,100,111,110,108,121,18,111,101,95,104,105,110,116,99,108,105, + 112,112,101,100,116,101,120,116,0,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,14,0,0,13,116,102,105,108,101,110,97,109,101,101,100,105, + 116,9,116,111,111,108,102,105,108,101,115,14,111,112,116,105,111,110,115,119, + 105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112, + 104,104,101,105,103,104,116,0,11,111,112,116,105,111,110,115,115,107,105,110, + 11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108, + 121,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115, + 101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,19,102,114, + 97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1,19, + 102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14, + 1,5,99,111,108,111,114,4,5,0,0,144,7,105,109,97,103,101,110,114, + 2,17,0,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111, + 108,111,114,4,5,0,0,144,20,102,114,97,109,101,46,98,117,116,116,111, + 110,46,105,109,97,103,101,110,114,2,17,8,116,97,98,111,114,100,101,114, + 2,9,10,111,110,115,104,111,119,104,105,110,116,7,18,104,105,110,116,101, + 120,112,97,110,100,101,100,109,97,99,114,111,115,7,118,105,115,105,98,108, + 101,8,8,98,111,117,110,100,115,95,120,3,107,1,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,116,9,98,111, + 117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105, + 116,49,11,0,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101, + 95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113, + 117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101, + 108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95, + 101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101, + 108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110, + 99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114, + 0,18,99,111,110,116,114,111,108,108,101,114,46,105,110,99,108,117,100,101, + 11,7,102,97,95,120,117,115,114,7,102,97,95,120,103,114,112,7,102,97, + 95,120,111,116,104,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,11,116,115,116,114,105,110,103,101,100,105,116,10,116,111,111, + 108,112,97,114,97,109,115,14,111,112,116,105,111,110,115,119,105,100,103,101, + 116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105, + 103,104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115, + 107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108, + 105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,97,99,116,105,118,101,0,8,116,97,98,111,114,100, + 101,114,2,10,10,111,110,115,104,111,119,104,105,110,116,7,18,104,105,110, + 116,101,120,112,97,110,100,101,100,109,97,99,114,111,115,7,118,105,115,105, + 98,108,101,8,8,98,111,117,110,100,115,95,120,3,224,1,8,98,111,117, + 110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,70,1, + 9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115, + 101,100,105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105,116,11, + 12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111, + 115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97, + 110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12, + 111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101, + 116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105, + 116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110, + 116,101,114,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,0,0,0,8,116,116,97,98,112,97,103,101,10,116,116,97,98,112,97, + 103,101,50,48,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,8,116,97,98,111,114,100,101,114,2,9,8,98,111,117,110,100, + 115,95,120,2,1,8,98,111,117,110,100,115,95,121,2,20,9,98,111,117, + 110,100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,3, + 18,2,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6, + 97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,9,97,110,95,98, + 111,116,116,111,109,0,7,99,97,112,116,105,111,110,6,8,38,83,116,111, + 114,97,103,101,0,12,116,98,111,111,108,101,97,110,101,100,105,116,14,115, + 101,116,116,105,110,103,115,101,100,105,116,111,114,11,111,112,116,105,111,110, + 115,115,107,105,110,11,14,111,115,107,95,110,111,108,97,121,111,117,116,99, + 120,14,111,115,107,95,110,111,108,97,121,111,117,116,99,121,0,13,102,114, + 97,109,101,46,99,97,112,116,105,111,110,6,6,69,100,105,116,111,114,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,1, + 2,40,2,2,0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117, + 110,100,115,95,120,2,15,8,98,111,117,110,100,115,95,121,2,108,9,98, + 111,117,110,100,115,95,99,120,2,54,9,98,111,117,110,100,115,95,99,121, + 2,16,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,16,115,101, + 116,116,105,110,103,115,97,117,116,111,108,111,97,100,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,9,65,117,116,111,32,108,111,97,100,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,1, + 2,63,2,2,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117, + 110,100,115,95,120,2,15,8,98,111,117,110,100,115,95,121,2,52,9,98, + 111,117,110,100,115,95,99,120,2,76,9,98,111,117,110,100,115,95,99,121, + 2,16,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,16,115,101, + 116,116,105,110,103,115,97,117,116,111,115,97,118,101,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,9,65,117,116,111,32,115,97,118,101,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,1, + 2,65,2,2,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117, + 110,100,115,95,120,3,183,0,8,98,111,117,110,100,115,95,121,2,52,9, + 98,111,117,110,100,115,95,99,120,2,78,9,98,111,117,110,100,115,95,99, + 121,2,16,0,0,9,116,108,97,121,111,117,116,101,114,10,116,108,97,121, + 111,117,116,101,114,54,17,102,114,97,109,101,46,102,114,97,109,101,105,95, + 108,101,102,116,2,5,16,102,114,97,109,101,46,102,114,97,109,101,105,95, + 116,111,112,2,5,18,102,114,97,109,101,46,102,114,97,109,101,105,95,114, + 105,103,104,116,2,5,19,102,114,97,109,101,46,102,114,97,109,101,105,95, + 98,111,116,116,111,109,2,5,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,102,105,108,101,102,116,9,102,114, + 108,95,102,105,116,111,112,11,102,114,108,95,102,105,114,105,103,104,116,12, + 102,114,108,95,102,105,98,111,116,116,111,109,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,8,98,111,117,110,100,115, + 95,120,2,0,8,98,111,117,110,100,115,95,121,2,13,9,98,111,117,110, + 100,115,95,99,120,3,62,3,9,98,111,117,110,100,115,95,99,121,2,31, + 7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,0,12,111,112, + 116,105,111,110,115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97, + 110,100,121,11,111,115,99,95,115,104,114,105,110,107,121,0,13,111,112,116, + 105,111,110,115,108,97,121,111,117,116,11,10,108,97,111,95,112,108,97,99, + 101,120,10,108,97,111,95,97,108,105,103,110,121,0,10,97,108,105,103,110, + 95,103,108,117,101,7,9,119,97,109,95,115,116,97,114,116,13,112,108,97, + 99,101,95,109,105,110,100,105,115,116,2,5,13,112,108,97,99,101,95,109, + 97,120,100,105,115,116,2,5,13,112,108,97,99,101,95,111,112,116,105,111, + 110,115,11,13,112,108,111,95,101,110,100,109,97,114,103,105,110,0,0,7, + 116,98,117,116,116,111,110,6,115,97,118,101,98,117,14,111,112,116,105,111, + 110,115,119,105,100,103,101,116,49,11,18,111,119,49,95,102,111,110,116,108, + 105,110,101,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99, + 97,108,101,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110, + 100,115,95,120,3,8,3,8,98,111,117,110,100,115,95,121,2,5,9,98, + 111,117,110,100,115,95,99,120,2,49,9,98,111,117,110,100,115,95,99,121, + 2,21,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,8,97, + 110,95,114,105,103,104,116,0,5,115,116,97,116,101,11,11,97,115,95,100, + 105,115,97,98,108,101,100,16,97,115,95,108,111,99,97,108,100,105,115,97, + 98,108,101,100,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110, + 17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,7, + 99,97,112,116,105,111,110,6,4,83,97,118,101,9,111,110,101,120,101,99, + 117,116,101,7,7,115,97,118,101,101,120,101,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,14,0,0,7,116,98,117,116,116,111,110,6,108, + 111,97,100,98,117,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49, + 11,18,111,119,49,95,102,111,110,116,108,105,110,101,104,101,105,103,104,116, + 13,111,119,49,95,97,117,116,111,115,99,97,108,101,0,8,116,97,98,111, + 114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,3,210,2,8,98, + 111,117,110,100,115,95,121,2,5,9,98,111,117,110,100,115,95,99,120,2, + 49,9,98,111,117,110,100,115,95,99,121,2,21,7,97,110,99,104,111,114, + 115,11,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,5, + 115,116,97,116,101,11,11,97,115,95,100,105,115,97,98,108,101,100,16,97, + 115,95,108,111,99,97,108,100,105,115,97,98,108,101,100,15,97,115,95,108, + 111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108, + 111,110,101,120,101,99,117,116,101,0,7,99,97,112,116,105,111,110,6,4, + 76,111,97,100,9,111,110,101,120,101,99,117,116,101,7,7,108,111,97,100, + 101,120,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0, + 0,13,116,102,105,108,101,110,97,109,101,101,100,105,116,12,115,101,116,116, + 105,110,103,115,102,105,108,101,11,111,112,116,105,111,110,115,115,107,105,110, + 11,14,111,115,107,95,110,111,108,97,121,111,117,116,99,120,14,111,115,107, + 95,110,111,108,97,121,111,117,116,99,121,0,13,102,114,97,109,101,46,99, + 97,112,116,105,111,110,6,13,83,101,116,116,105,110,103,115,32,70,105,108, + 101,22,102,114,97,109,101,46,99,97,112,116,105,111,110,116,101,120,116,102, + 108,97,103,115,11,12,116,102,95,121,99,101,110,116,101,114,101,100,0,16, + 102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112, + 95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46, + 99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116,116,111,110, + 115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4,2,0,0,128, + 7,105,109,97,103,101,110,114,2,17,0,0,18,102,114,97,109,101,46,98, + 117,116,116,111,110,46,99,111,108,111,114,4,2,0,0,128,20,102,114,97, + 109,101,46,98,117,116,116,111,110,46,105,109,97,103,101,110,114,2,17,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2, + 0,2,80,2,0,0,10,111,110,115,104,111,119,104,105,110,116,7,18,104, + 105,110,116,101,120,112,97,110,100,101,100,109,97,99,114,111,115,8,98,111, + 117,110,100,115,95,120,2,5,8,98,111,117,110,100,115,95,121,2,5,9, + 98,111,117,110,100,115,95,99,120,3,200,2,7,97,110,99,104,111,114,115, + 11,7,97,110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95, + 114,105,103,104,116,0,13,111,110,100,97,116,97,101,110,116,101,114,101,100, + 7,15,115,101,116,116,105,110,103,115,100,97,116,97,101,110,116,26,99,111, + 110,116,114,111,108,108,101,114,46,102,105,108,116,101,114,108,105,115,116,46, + 100,97,116,97,1,1,6,13,80,114,111,106,101,99,116,32,70,105,108,101, + 115,6,5,42,46,112,114,106,0,1,6,9,65,108,108,32,70,105,108,101, + 115,6,1,42,0,0,21,99,111,110,116,114,111,108,108,101,114,46,100,101, + 102,97,117,108,116,101,120,116,6,3,112,114,106,22,99,111,110,116,114,111, + 108,108,101,114,46,99,97,112,116,105,111,110,111,112,101,110,6,19,69,110, + 116,101,114,32,83,101,116,116,105,110,103,115,32,70,105,108,101,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,12,116,98,111, + 111,108,101,97,110,101,100,105,116,16,115,101,116,116,105,110,103,115,100,101, + 98,117,103,103,101,114,11,111,112,116,105,111,110,115,115,107,105,110,11,14, + 111,115,107,95,110,111,108,97,121,111,117,116,99,120,14,111,115,107,95,110, + 111,108,97,121,111,117,116,99,121,0,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,8,68,101,98,117,103,103,101,114,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,2,65,2,2,0, + 8,116,97,98,111,114,100,101,114,2,4,8,98,111,117,110,100,115,95,120, + 2,15,8,98,111,117,110,100,115,95,121,3,132,0,9,98,111,117,110,100, + 115,95,99,120,2,79,9,98,111,117,110,100,115,95,99,121,2,16,0,0, + 12,116,98,111,111,108,101,97,110,101,100,105,116,15,115,101,116,116,105,110, + 103,115,115,116,111,114,97,103,101,11,111,112,116,105,111,110,115,115,107,105, + 110,11,14,111,115,107,95,110,111,108,97,121,111,117,116,99,120,14,111,115, + 107,95,110,111,108,97,121,111,117,116,99,121,0,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,7,83,116,111,114,97,103,101,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109, + 101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,2,53,2, + 2,0,8,116,97,98,111,114,100,101,114,2,12,8,98,111,117,110,100,115, + 95,120,2,15,8,98,111,117,110,100,115,95,121,3,68,1,9,98,111,117, + 110,100,115,95,99,120,2,67,9,98,111,117,110,100,115,95,99,121,2,16, + 0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,19,115,101,116,116, + 105,110,103,115,112,114,111,106,101,99,116,116,114,101,101,11,111,112,116,105, + 111,110,115,115,107,105,110,11,14,111,115,107,95,110,111,108,97,121,111,117, + 116,99,120,14,111,115,107,95,110,111,108,97,121,111,117,116,99,121,0,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,12,80,114,111,106,101, + 99,116,32,84,114,101,101,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,1,2,79,2,2,0,8,116,97,98,111,114,100, + 101,114,2,14,8,98,111,117,110,100,115,95,120,3,183,0,8,98,111,117, + 110,100,115,95,121,3,132,0,9,98,111,117,110,100,115,95,99,120,2,93, + 9,98,111,117,110,100,115,95,99,121,2,16,0,0,12,116,98,111,111,108, + 101,97,110,101,100,105,116,14,115,101,116,116,105,110,103,115,109,97,99,114, + 111,115,11,111,112,116,105,111,110,115,115,107,105,110,11,14,111,115,107,95, + 110,111,108,97,121,111,117,116,99,120,14,111,115,107,95,110,111,108,97,121, + 111,117,116,99,121,0,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,6,77,97,99,114,111,115,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,1,2,48,2,2,0,8,116,97,98,111,114, + 100,101,114,2,6,8,98,111,117,110,100,115,95,120,2,15,8,98,111,117, + 110,100,115,95,121,3,180,0,9,98,111,117,110,100,115,95,99,120,2,62, + 9,98,111,117,110,100,115,95,99,121,2,16,0,0,12,116,98,111,111,108, + 101,97,110,101,100,105,116,13,115,101,116,116,105,110,103,115,116,111,111,108, + 115,11,111,112,116,105,111,110,115,115,107,105,110,11,14,111,115,107,95,110, + 111,108,97,121,111,117,116,99,120,14,111,115,107,95,110,111,108,97,121,111, + 117,116,99,121,0,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 5,84,111,111,108,115,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,1,2,36,2,2,0,8,116,97,98,111,114,100,101, + 114,2,11,8,98,111,117,110,100,115,95,120,2,15,8,98,111,117,110,100, + 115,95,121,3,44,1,9,98,111,117,110,100,115,95,99,120,2,50,9,98, + 111,117,110,100,115,95,99,121,2,16,0,0,12,116,98,111,111,108,101,97, + 110,101,100,105,116,17,115,101,116,116,105,110,103,115,116,101,109,112,108,97, + 116,101,115,11,111,112,116,105,111,110,115,115,107,105,110,11,14,111,115,107, + 95,110,111,108,97,121,111,117,116,99,120,14,111,115,107,95,110,111,108,97, + 121,111,117,116,99,121,0,13,102,114,97,109,101,46,99,97,112,116,105,111, + 110,6,9,84,101,109,112,108,97,116,101,115,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117, + 116,101,114,102,114,97,109,101,1,2,0,2,1,2,68,2,2,0,8,116, + 97,98,111,114,100,101,114,2,10,8,98,111,117,110,100,115,95,120,2,15, + 8,98,111,117,110,100,115,95,121,3,20,1,9,98,111,117,110,100,115,95, + 99,120,2,82,9,98,111,117,110,100,115,95,99,121,2,16,0,0,12,116, + 98,111,111,108,101,97,110,101,100,105,116,22,115,101,116,116,105,110,103,115, + 99,111,109,112,111,110,101,110,116,115,116,111,114,101,11,111,112,116,105,111, + 110,115,115,107,105,110,11,14,111,115,107,95,110,111,108,97,121,111,117,116, + 99,120,14,111,115,107,95,110,111,108,97,121,111,117,116,99,121,0,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,15,67,111,109,112,111,110, + 101,110,116,32,83,116,111,114,101,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,1,2,113,2,2,0,8,116,97,98,111, + 114,100,101,114,2,13,8,98,111,117,110,100,115,95,120,3,183,0,8,98, + 111,117,110,100,115,95,121,2,108,9,98,111,117,110,100,115,95,99,120,2, + 127,9,98,111,117,110,100,115,95,99,121,2,16,0,0,12,116,98,111,111, + 108,101,97,110,101,100,105,116,14,115,101,116,116,105,110,103,115,108,97,121, + 111,117,116,11,111,112,116,105,111,110,115,115,107,105,110,11,14,111,115,107, + 95,110,111,108,97,121,111,117,116,99,120,14,111,115,107,95,110,111,108,97, + 121,111,117,116,99,121,0,13,102,114,97,109,101,46,99,97,112,116,105,111, + 110,6,13,87,105,110,100,111,119,32,76,97,121,111,117,116,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109, + 101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,2,95,2, + 2,0,8,116,97,98,111,114,100,101,114,2,15,8,98,111,117,110,100,115, + 95,120,3,183,0,8,98,111,117,110,100,115,95,121,3,156,0,9,98,111, + 117,110,100,115,95,99,120,2,109,9,98,111,117,110,100,115,95,99,121,2, + 16,0,0,6,116,108,97,98,101,108,7,116,108,97,98,101,108,49,8,116, + 97,98,111,114,100,101,114,2,16,8,98,111,117,110,100,115,95,120,2,15, + 8,98,111,117,110,100,115,95,121,2,84,9,98,111,117,110,100,115,95,99, + 120,2,118,9,98,111,117,110,100,115,95,99,121,2,14,7,99,97,112,116, + 105,111,110,6,18,76,111,97,100,47,115,97,118,101,32,115,101,116,116,105, + 110,103,115,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0, + 0,12,116,98,111,111,108,101,97,110,101,100,105,116,12,115,101,116,116,105, + 110,103,115,109,97,107,101,11,111,112,116,105,111,110,115,115,107,105,110,11, + 14,111,115,107,95,110,111,108,97,121,111,117,116,99,120,14,111,115,107,95, + 110,111,108,97,121,111,117,116,99,121,0,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,4,77,97,107,101,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,1,2,36,2,2,0,8,116,97, + 98,111,114,100,101,114,2,5,8,98,111,117,110,100,115,95,120,2,15,8, + 98,111,117,110,100,115,95,121,3,156,0,9,98,111,117,110,100,115,95,99, + 120,2,50,9,98,111,117,110,100,115,95,99,121,2,16,5,118,97,108,117, + 101,9,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,18,115,101, + 116,116,105,110,103,115,117,115,101,114,99,111,108,111,114,115,11,111,112,116, + 105,111,110,115,115,107,105,110,11,14,111,115,107,95,110,111,108,97,121,111, + 117,116,99,120,14,111,115,107,95,110,111,108,97,121,111,117,116,99,121,0, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,11,85,115,101,114, + 32,67,111,108,111,114,115,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,1,2,75,2,2,0,8,116,97,98,111,114,100, + 101,114,2,8,8,98,111,117,110,100,115,95,120,2,15,8,98,111,117,110, + 100,115,95,121,3,228,0,9,98,111,117,110,100,115,95,99,120,2,89,9, + 98,111,117,110,100,115,95,99,121,2,16,0,0,12,116,98,111,111,108,101, + 97,110,101,100,105,116,20,115,101,116,116,105,110,103,115,102,111,114,109,97, + 116,109,97,99,114,111,115,11,111,112,116,105,111,110,115,115,107,105,110,11, + 14,111,115,107,95,110,111,108,97,121,111,117,116,99,120,14,111,115,107,95, + 110,111,108,97,121,111,117,116,99,121,0,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,13,70,111,114,109,97,116,32,77,97,99,114,111,115, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2, + 1,2,96,2,2,0,8,116,97,98,111,114,100,101,114,2,9,8,98,111, + 117,110,100,115,95,120,2,15,8,98,111,117,110,100,115,95,121,3,252,0, + 9,98,111,117,110,100,115,95,99,120,2,110,9,98,111,117,110,100,115,95, + 99,121,2,16,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,17, + 115,101,116,116,105,110,103,115,102,111,110,116,97,108,105,97,115,11,111,112, + 116,105,111,110,115,115,107,105,110,11,14,111,115,107,95,110,111,108,97,121, + 111,117,116,99,120,14,111,115,107,95,110,111,108,97,121,111,117,116,99,121, + 0,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,10,70,111,110, + 116,32,65,108,105,97,115,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,1,2,64,2,2,0,8,116,97,98,111,114,100, + 101,114,2,7,8,98,111,117,110,100,115,95,120,2,15,8,98,111,117,110, + 100,115,95,121,3,204,0,9,98,111,117,110,100,115,95,99,120,2,78,9, + 98,111,117,110,100,115,95,99,121,2,16,0,0,0,0,0,9,116,115,116, + 97,116,102,105,108,101,9,115,116,97,116,102,105,108,101,49,8,102,105,108, + 101,110,97,109,101,6,13,111,112,116,105,111,110,115,102,111,46,115,116,97, + 7,111,112,116,105,111,110,115,11,10,115,102,111,95,109,101,109,111,114,121, + 0,4,108,101,102,116,3,144,0,3,116,111,112,3,24,2,0,0,16,116, + 115,116,114,105,110,103,99,111,110,116,97,105,110,101,114,1,99,12,115,116, + 114,105,110,103,115,46,100,97,116,97,1,6,44,87,114,111,110,103,32,101, + 110,99,111,100,105,110,103,32,99,97,110,32,100,97,109,97,103,101,32,121, + 111,117,114,32,115,111,117,114,99,101,32,102,105,108,101,115,46,6,30,68, + 111,32,121,111,117,32,119,105,115,104,32,116,111,32,115,101,116,32,101,110, + 99,111,100,105,110,103,32,116,111,6,15,42,42,42,32,87,65,82,78,73, + 78,71,32,42,42,42,6,6,72,97,110,103,117,112,6,9,73,110,116,101, + 114,114,117,112,116,6,4,81,117,105,116,6,19,73,108,108,101,103,97,108, + 32,105,110,115,116,114,117,99,116,105,111,110,6,10,84,114,97,99,101,32, + 116,114,97,112,6,5,65,98,111,114,116,6,9,66,85,83,32,101,114,114, + 111,114,6,24,70,108,111,97,116,105,110,103,45,112,111,105,110,116,32,101, + 120,99,101,112,116,105,111,110,6,4,75,105,108,108,6,21,85,115,101,114, + 45,100,101,102,105,110,101,100,32,115,105,103,110,97,108,32,49,6,22,83, + 101,103,109,101,110,116,97,116,105,111,110,32,118,105,111,108,97,116,105,111, + 110,6,21,85,115,101,114,45,100,101,102,105,110,101,100,32,115,105,103,110, + 97,108,32,50,6,11,66,114,111,107,101,110,32,112,105,112,101,6,11,65, + 108,97,114,109,32,99,108,111,99,107,6,11,84,101,114,109,105,110,97,116, + 105,111,110,6,11,83,116,97,99,107,32,102,97,117,108,116,6,24,67,104, + 105,108,100,32,115,116,97,116,117,115,32,104,97,115,32,99,104,97,110,103, + 101,100,6,8,67,111,110,116,105,110,117,101,6,17,83,116,111,112,44,32, + 117,110,98,108,111,99,107,97,98,108,101,6,13,75,101,121,98,111,97,114, + 100,32,115,116,111,112,6,24,66,97,99,107,103,114,111,117,110,100,32,114, + 101,97,100,32,102,114,111,109,32,116,116,121,6,23,66,97,99,107,103,114, + 111,117,110,100,32,119,114,105,116,101,32,116,111,32,116,116,121,6,26,85, + 114,103,101,110,116,32,99,111,110,100,105,116,105,111,110,32,111,110,32,115, + 111,99,107,101,116,6,18,67,80,85,32,108,105,109,105,116,32,101,120,99, + 101,101,100,101,100,6,24,70,105,108,101,32,115,105,122,101,32,108,105,109, + 105,116,32,101,120,99,101,101,100,101,100,6,19,86,105,114,116,117,97,108, + 32,97,108,97,114,109,32,99,108,111,99,107,6,21,80,114,111,102,105,108, + 105,110,103,32,97,108,97,114,109,32,99,108,111,99,107,6,18,87,105,110, + 100,111,119,32,115,105,122,101,32,99,104,97,110,103,101,6,16,73,47,79, + 32,110,111,119,32,112,111,115,115,105,98,108,101,6,21,80,111,119,101,114, + 32,102,97,105,108,117,114,101,32,114,101,115,116,97,114,116,0,4,108,101, + 102,116,3,216,0,3,116,111,112,3,24,2,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tprojectoptionsfo,''); +end. diff --git a/mseide-msegui/apps/ide/projecttreeform.mfm b/mseide-msegui/apps/ide/projecttreeform.mfm new file mode 100644 index 0000000..c24da08 --- /dev/null +++ b/mseide-msegui/apps/ide/projecttreeform.mfm @@ -0,0 +1,407 @@ +object projecttreefo: tprojecttreefo + optionswidget = [ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets, ow_hinton] + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_topbutton, go_backgroundbutton, go_nolockbutton, go_buttonhints] + visible = False + bounds_x = 263 + bounds_y = 431 + bounds_cx = 286 + bounds_cy = 201 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 276 + 201 + ) + dragdock.splitter_size = 0 + dragdock.optionsdock = [od_savepos, od_savezorder, od_canmove, od_canfloat, od_candock, od_propsize, od_captionhint, od_childicons] + options = [fo_savepos, fo_savezorder, fo_savestate] + statfile = mainfo.projectstatfile + caption = 'Project Tree' + oncreate = projecttreefooncreate + oneventloopstart = projecttreefoonloaded + ondestroy = projecttreefoondestroy + onstatupdate = projecttreeonupdatestat + moduleclassname = 'tdockform' + object grid: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + frame.localprops = [] + frame.localprops1 = [] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 276 + bounds_cy = 201 + anchors = [] + optionsgrid = [og_colsizing, og_focuscellonenter, og_savestate, og_colchangeontabkey, og_wrapcol, og_autopopup] + datacols.count = 2 + datacols.options = [co_savestate, co_mousescrollrow] + datacols.items = < + item[projectedit] + linecolorfix = -1610612733 + width = 141 + options = [co_readonly, co_savestate, co_mousescrollrow] + oncellevent = projecteditoncellevent + widgetname = 'projectedit' + dataclass = ttreeitemeditlist + datalist.imnr_expanded = 1 + datalist.imagelist = nodeicons + datalist.imagewidth = 16 + datalist.imageheight = 16 + datalist.onstatreaditem = projecteditonstatreaditem + datalist.ondragbegin = editdragbegin + datalist.ondragover = editdragover + datalist.ondragdrop = editdragrop + end + item[edit] + linecolorfix = -1610612733 + width = 129 + options = [co_fill, co_savestate, co_mousescrollrow] + onshowhint = colshowhintexe + widgetname = 'edit' + dataclass = titemeditlist + end> + datarowheight = 17 + statfile = mainfo.projectstatfile + oncellevent = gridcellevent + reffontheight = 16 + object projectedit: ttreeitemedit + optionswidget1 = [ow1_autoheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + color = -1879048185 + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 1 + onpopup = projecteditonpopup + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 141 + bounds_cy = 18 + optionsedit1 = [] + optionsedit = [oe_readonly, oe_undoonesc, oe_checkmrcancel, oe_exitoncursor, oe_hintclippedtext, oe_locate] + onchange = projecteditonchange + onsetvalue = captionset + onupdaterowvalues = projecteditonupdaterowvalues + fieldedit = edit + options = [teo_treecolnavig, teo_keyrowmoving] + oncheckrowmove = itemoncheckrowmove + end + object edit: trecordfieldedit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + color = -1879048185 + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.button.color = -2147483646 + frame.button.options = [fbo_invisible] + frame.buttons.count = 2 + frame.buttons.items = < + item + color = -2147483646 + options = [fbo_invisible] + end + item + color = -2147483646 + imagenr = 17 + onexecute = receditdialogexe + end> + taborder = 2 + onshowhint = edithintexe + visible = False + bounds_x = 142 + bounds_y = 0 + bounds_cx = 129 + bounds_cy = 17 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext] + textflags = [tf_ycentered, tf_clipo, tf_noselect, tf_ellipseleft] + oncellevent = editoncellevent + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + reffontheight = 16 + end + end + object unitpopup: tpopupmenu + menu.action = addunitfileact + menu.submenu.count = 6 + menu.submenu.items = < + item + action = addunitfileact + end + item + action = removeunitfileact + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + action = adddiract + end + item + action = removediract + end + item + action = editdiract + end> + left = 8 + top = 8 + end + object addunitfileact: taction + caption = '&Add Unit' + onexecute = addunitfileonexecute + left = 112 + top = 8 + end + object filedialog: tfiledialog + controller.options = [fdo_checkexist, fdo_savelastdir] + controller.historymaxcount = 0 + left = 8 + top = 168 + end + object removeunitfileact: taction + caption = '&Remove Unit' + onexecute = removeunitfileonexecute + onupdate = remfileupdateexe + left = 112 + top = 24 + end + object filepopup: tpopupmenu + menu.submenu.count = 6 + menu.submenu.items = < + item + action = addfileact + end + item + action = removefileact + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + action = adddiract + end + item + action = removediract + end + item + action = editdiract + end> + menu.state = [as_localhint] + left = 8 + top = 40 + end + object addfileact: taction + caption = 'Add Text File' + onexecute = addfileexe + left = 112 + top = 48 + end + object removefileact: taction + caption = 'Remove Text File' + onexecute = removefileonexecute + onupdate = remfileupdateexe + left = 112 + top = 64 + end + object cmodulepopup: tpopupmenu + menu.submenu.count = 6 + menu.submenu.items = < + item + action = addcmoduleact + end + item + action = removecmoduleact + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + action = adddiract + end + item + action = removediract + end + item + action = editdiract + end> + menu.state = [as_localhint] + left = 8 + top = 72 + end + object removecmoduleact: taction + caption = 'Remove C-File' + onexecute = removecmoduleonexecute + onupdate = remfileupdateexe + left = 112 + top = 104 + end + object addcmoduleact: taction + caption = 'Add C-File' + onexecute = addcmoduleonexecute + left = 112 + top = 88 + end + object cmoduledialog: tfiledialog + controller.filterlist.data = ( + ( + 'C-Source (*.c)' + '"*.c"' + ) + ) + controller.options = [fdo_checkexist, fdo_savelastdir] + controller.historymaxcount = 0 + left = 96 + top = 168 + end + object adddiract: taction + caption = 'Add Directory' + onexecute = adddirexe + onupdate = updateadddirexe + top = 104 + end + object removediract: taction + caption = 'Remove Directory' + onexecute = remdirexe + onupdate = updateremdirexe + top = 120 + end + object nodeicons: timagelist + count = 8 + left = 144 + top = 120 + image = { + 00000000020000003000000030000000380A0000000000000000000000000000 + 0000000000000000000000000000000000000000FF00FF6300000006FF00FF0A + 00000006FF00FF0900000006FF00FF0B00000001FFFFFF0400000002FF00FF09 + 00000001FFFFFF0400000002FF00FF0800000001FFFFFF0400000002FF00FF0A + 00000001FFFFFF0400000001FFFFFF0100000001FF00FF0800000001FFFFFF04 + 00000001FFFFFF0100000001FF00FF0700000001FFFFFF0400000001FFFFFF01 + 00000001FF00FF0900000001FFFFFF0400000001FFFFFF0200000001FF00FF07 + 00000001FFFFFF0400000001FFFFFF0200000001FF00FF0600000001FFFFFF02 + FF8E7801E0321005AEAEAE01E032100100000001FF00FF0500000001FFFFFF04 + 00000005FF00FF0600000001FFFFFF0400000005FF00FF0500000001FFFFFF02 + F2F2F201E0E0E00780808001FF00FF0500000001FFFFFF080000000180808001 + FF00FF0500000001FFFFFF080000000180808001FF00FF0400000001FFFFFF02 + F2F2F201E0E0E00780808001FF00FF0500000001FFFFFF080000000180808001 + FF00FF0500000001FFFFFF080000000180808001FF00FF0400000001FFFFFF02 + F2F2F201E0E0E00780808001FF00FF0500000001FFFFFF080000000180808001 + FF00FF0500000001FFFFFF080000000180808001FF00FF0400000001FFFFFF02 + F2F2F201E0E0E001F2F2F205E0E0E00180808001FF00FF0500000001FFFFFF08 + 0000000180808001FF00FF0500000001FFFFFF080000000180808001FF00FF04 + 00000001FFFFFF02F2F2F201E0E0E001F2F2F201E0E0E00380808001E0E0E001 + 80808001FF00FF0500000001FFFFFF080000000180808001FF00FF0500000001 + FFFFFF080000000180808001FF00FF0400000001FFFFFF02F2F2F201E0E0E001 + F2F2F201E0E0E00380808001E0E0E00180808001FF00FF0500000001FFFFFF08 + 0000000180808001FF00FF0500000001FFFFFF080000000180808001FF00FF04 + 00000001FFFFFF02F2F2F201E0E0E001F2F2F20180808004E0E0E00180808001 + FF00FF050000000A80808001FF00FF050000000A80808001FF00FF0400000003 + F2F2F201E0E0E00780808001FF00FF068080800AFF00FF068080800AFF00FF05 + 80808002F2F2F20180808008FF00FF9400000006FF00FF2A00000001FFFFFF04 + 00000002FF00FF0AFF8E7801E0321006AEAEAE01E032100100000001FF00FF06 + FF8E7801E0321006AEAEAE01E032100100000001FF00FF0500000001FFFFFF04 + 00000001FFFFFF0100000001FF00FF09F2F2F201E0E0E00880808001FF00FF06 + F2F2F201E0E0E00880808001FF00FF0500000001FFFFFF02FF8E7801E0321005 + AEAEAE01E032100100000001FF00FF05F2F2F201E0E0E00880808001FF00FF06 + F2F2F201E0E0E00880808001FF00FF0500000001FFFFFF02F2F2F201E0E0E007 + 80808001FF00FF05F2F2F201E0E0E00880808001FF00FF06F2F2F201E0E0E008 + 80808001FF00FF0500000001FFFFFF02F2F2F201E0E0E00780808001FF00FF05 + F2F2F201E0E0E001F2F2F206E0E0E00180808001FF00FF06F2F2F201E0E0E001 + F2F2F206E0E0E00180808001FF00FF0500000001FFFFFF02F2F2F201E0E0E007 + 80808001FF00FF05F2F2F201E0E0E001F2F2F201E0E0E00480808001E0E0E001 + 80808001FF00FF06F2F2F201E0E0E001F2F2F201E0E0E00480808001E0E0E001 + 80808001FF00FF0500000001FFFFFF02F2F2F201E0E0E001F2F2F205E0E0E001 + 80808001FF00FF05F2F2F201E0E0E001F2F2F201E0E0E00480808001E0E0E001 + 80808001FF00FF06F2F2F201E0E0E001F2F2F201E0E0E00480808001E0E0E001 + 80808001FF00FF0500000001FFFFFF02F2F2F201E0E0E001F2F2F201E0E0E003 + 80808001E0E0E00180808001FF00FF05F2F2F201E0E0E001F2F2F20180808005 + E0E0E00180808001FF00FF06F2F2F201E0E0E001F2F2F20180808005E0E0E001 + 80808001FF00FF0500000001FFFFFF02F2F2F201E0E0E001F2F2F201E0E0E003 + 80808001E0E0E00180808001FF00FF05F2F2F201E0E0E00880808001FF00FF06 + F2F2F201E0E0E00880808001FF00FF0500000001FFFFFF02F2F2F201E0E0E001 + F2F2F20180808004E0E0E00180808001FF00FF05F2F2F20180808009FF00FF06 + F2F2F20180808009FF00FF0500000003F2F2F201E0E0E00780808001FF00FF25 + 80808002F2F2F20180808008FF00FFD400000006FF00FF0B7F7F7F0100000004 + 7F7F7F01FF00FF097F7F7F01000000047F7F7F01FF00FF0A00000001FFFFFF04 + 00000002FF00FF0A00000001FFFFFF0100FFFF01FFFFFF0100FFFF0100000001 + FF00FF090000000100FFFF01FFFFFF0100FFFF01FFFFFF0100000001FF00FF0A + 00000001FFFFFF0400000001FFFFFF0100000001FF00FF080000000AFF00FF05 + 0000000100FFFF01FFFFFF0100FFFF01FFFFFF0100FFFF01FFFFFF0100000003 + FF00FF0700000001FFFFFF0400000001FFFFFF0200000001FF00FF0700000001 + FFFFFF0100FFFF01FFFFFF0100FFFF01FFFFFF0100FFFF01FFFFFF0100FFFF01 + FFFFFF0100000001FF00FF0400000001FFFFFF0100FFFF01FFFFFF0100FFFF01 + FFFFFF0100FFFF01FFFFFF0100FFFF01FFFFFF0100000001FF00FF0600000001 + FFFFFF0400000005FF00FF060000000100FFFF01FFFFFF0100FFFF01FFFFFF01 + 00FFFF01FFFFFF0100FFFF01FFFFFF0100FFFF0100000001FF00FF0400000001 + 00FFFF01FFFFFF0100FFFF01FFFFFF0100FFFF01FFFFFF0100FFFF01FFFFFF01 + 00FFFF0100000001FF00FF0600000001FFFFFF02FF8E7801E0321005AEAEAE01 + E032100100000001FF00FF0400000001FFFFFF0100FFFF01FFFFFF0100FFFF01 + FFFFFF0100FFFF01FFFFFF0100FFFF01FFFFFF0100000001FF00FF0400000001 + FFFFFF0100FFFF01FFFFFF010000000AFF00FF0300000001FFFFFF02EBEBEB01 + E0E0E00780808001FF00FF040000000100FFFF01FFFFFF0100FFFF01FFFFFF01 + 00FFFF01FFFFFF0100FFFF01FFFFFF0100FFFF0100000001FF00FF0400000001 + 00FFFF01FFFFFF010000000100FFFF01BFBFBF0100FFFF01BFBFBF0100FFFF01 + BFBFBF0100FFFF01BFBFBF0100FFFF0100000001FF00FF0300000001FFFFFF02 + EBEBEB01E0E0E001EBEBEB0480808001E0E0E00180808001FF00FF0400000001 + FFFFFF0100FFFF01FFFFFF0100FFFF01FFFFFF0100FFFF01FFFFFF0100FFFF01 + FFFFFF0100000001FF00FF0400000001FFFFFF010000000100FFFF01BFBFBF01 + 00FFFF01BFBFBF0100FFFF01BFBFBF0100FFFF01BFBFBF0100FFFF0100000001 + FF00FF0400000001FFFFFF02EBEBEB01E0E0E001EBEBEB01E0E0E00380808001 + E0E0E00180808001FF00FF040000000100FFFF01FFFFFF0100FFFF01FFFFFF01 + 00FFFF01FFFFFF0100FFFF01FFFFFF0100FFFF0100000001FF00FF0400000002 + 00FFFF01BFBFBF0100FFFF01BFBFBF0100FFFF01BFBFBF0100FFFF01BFBFBF01 + 00FFFF0100000001FF00FF0500000001FFFFFF02EBEBEB01E0E0E001EBEBEB01 + E0E0E00380808001E0E0E00180808001FF00FF050000000AFF00FF050000000A + FF00FF0600000001FFFFFF02EBEBEB01E0E0E001EBEBEB0180808004E0E0E001 + 80808001FF00FF2400000003EBEBEB01E0E0E00780808001FF00FF2580808002 + EBEBEB0180808008FF00FF3200000000000000000000000000000000F801F801 + FC000000F803F803FC010000F807F807FC030000F80FF80FFC3F0000F81FF81F + FC3F0000F83FF83FFC3F0000F83FF83FFC3F0000F83FF83FFC3F0000F83FF83F + FC3F0000F83FF83FFC3F0000F83FF83FFC3F0000F83FF83FFC3F0000F03FF03F + F83F0000000000000000000000000000000000000000000000000000FC000000 + 00000000FC01F81FF81F0000FC03F81FF81F0000FC3FF81FF81F0000FC3FF81F + F81F0000FC3FF81FF81F0000FC3FF81FF81F0000FC3FF81FF81F0000FC3FF81F + F81F0000FC3FF81FF81F0000FC3FF81FF81F0000FC3F000000000000F83F0000 + 0000000000000000000000000000000000000000000000000000000000000000 + FC000000F801FC00FC010000F801FC00FC030000FC0FFE07FC070000FC1FFE0F + FC0F0000FC1FFE0FFC3F0000FC1FFE7FFC3F0000FC1FFE7FFC3F0000FC1FFE3F + FC3F0000FC1FFE1FFC3F0000F81FFC0FFC3F000000000000FC3F000000000000 + F83F00000000000000000000 + } + end + object dummyimage: timagelist + width = 0 + height = 0 + left = 144 + top = 144 + end + object editdiract: taction + caption = 'Edit Directory Caption' + onexecute = editdirexe + onupdate = udateeditdirexe + top = 136 + end + object c: tstringcontainer + strings.data = ( + 'Pascal Units' + 'C Modules' + 'Text Files' + 'Do you wish to remove "' + 'Select Directory' + 'Do you want to remove' + 'with the sub-items from project?' + ) + left = 208 + top = 168 + end +end diff --git a/mseide-msegui/apps/ide/projecttreeform.pas b/mseide-msegui/apps/ide/projecttreeform.pas new file mode 100644 index 0000000..b609f2d --- /dev/null +++ b/mseide-msegui/apps/ide/projecttreeform.pas @@ -0,0 +1,1565 @@ +{ MSEide Copyright (c) 1999-2012 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit projecttreeform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +//todo: relative path linking + +interface +uses + mseforms,msewidgetgrid,mselistbrowser,msedatanodes,msetypes,msemenus,mseevent, + mseactions,msefiledialog,msestat,msegrids,msedesigner,msedataedits, + msegraphutils,msegui,msestrings,mseact,mseguiglob,mseclasses,msebitmap,mseedit, + mseglob,msegraphics,msescrollbar,msesys,msehash,mseifiglob,msestringcontainer, + msevaluenodes; + +type + projectnodety = (pnk_none,pnk_source,pnk_form,pnk_files,pnk_dir); +const + filenodes = [pnk_source,pnk_dir,pnk_form]; +type + tdirnode = class; + tprojecttreefo = class(tdockform) + grid: twidgetgrid; + projectedit: ttreeitemedit; + edit: trecordfieldedit; + unitpopup: tpopupmenu; + addunitfileact: taction; + removeunitfileact: taction; + filedialog: tfiledialog; + filepopup: tpopupmenu; + addfileact: taction; + removefileact: taction; + cmodulepopup: tpopupmenu; + removecmoduleact: taction; + addcmoduleact: taction; + cmoduledialog: tfiledialog; + adddiract: taction; + removediract: taction; + nodeicons: timagelist; + dummyimage: timagelist; + editdiract: taction; + c: tstringcontainer; + procedure projecteditonchange(const sender: TObject); + procedure projecteditonstatreaditem(const sender: TObject; + const reader: tstatreader; var aitem: ttreelistitem); + procedure projecteditonupdaterowvalues(const sender: TObject; + const aindex: Integer; const aitem: tlistitem); + procedure projecttreefooncreate(const sender: tobject); + procedure projecttreefoonloaded(const sender: tobject); + procedure projecttreefoondestroy(const sender: tobject); + procedure projecteditonpopup(const sender: tobject; var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); + + procedure addunitfileonexecute(const sender: tobject); + procedure removeunitfileonexecute(const sender: tobject); + + procedure projecttreeonupdatestat(const sender: tobject; + const filer: tstatfiler); + procedure projecteditoncellevent(const sender: tobject; + var info: celleventinfoty); + + procedure itemoncheckrowmove(const curindex: Integer; const newindex: Integer; + var accept: Boolean); + + procedure addfileexe(const sender: TObject); + procedure editdragbegin(const sender: ttreeitemedit; + const aitem: ttreelistitem; var candrag: Boolean; + var dragobject: ttreeitemdragobject; var processed: Boolean); + procedure editdragover(const sender: ttreeitemedit; + const source: ttreelistitem; const dest: ttreelistitem; + var dragobject: ttreeitemdragobject; var accept: Boolean; + var processed: Boolean); + procedure editdragrop(const sender: ttreeitemedit; + const source: ttreelistitem; const dest: ttreelistitem; + var dragobject: ttreeitemdragobject; var processed: Boolean); + procedure editoncellevent(const sender: TObject; var info: celleventinfoty); + procedure removefileonexecute(const sender: TObject); + procedure addcmoduleonexecute(const sender: TObject); + procedure removecmoduleonexecute(const sender: TObject); + procedure adddirexe(const sender: TObject); + procedure receditdialogexe(const sender: TObject); + procedure gridcellevent(const sender: TObject; var info: celleventinfoty); + procedure edithintexe(const sender: TObject; var info: hintinfoty); + procedure colshowhintexe(const sender: tdatacol; const arow: Integer; + var info: hintinfoty); + procedure updateremdirexe(const sender: tcustomaction); + procedure updateadddirexe(const sender: tcustomaction); + procedure remdirexe(const sender: TObject); + procedure remfileupdateexe(const sender: tcustomaction); + procedure udateeditdirexe(const sender: tcustomaction); + procedure editdirexe(const sender: TObject); + procedure captionset(const sender: TObject; var avalue: msestring; + var accept: Boolean); + private + funitloading: boolean; + finited: boolean; + protected + function addirectory(const aname: filenamety): tdirnode; + function gettreedir: filenamety; + public + procedure clear; + end; + + tprojectnode = class(ttreelistedititem) + fkind: projectnodety; + ferror: boolean; + protected + function getcurrentimagenr: integer; virtual; + function compare(const r: tlistitem; + const acasesensitive: boolean): integer; override; + public + constructor create(const akind: projectnodety); reintroduce; + end; + + tfilenode = class(tprojectnode) + private + ffilename: filenamety; + fpath: filenamety; + fmodified: boolean; + protected + function getcurrentimagenr: integer; override; + procedure setfilename(const value: filenamety); virtual; + function parentpath: msestring; + procedure updatepath; + public + constructor create(const akind: projectnodety); + procedure dostatread(const reader: tstatreader); override; + procedure dostatwrite(const writer: tstatwriter); override; + function getvaluetext: msestring; override; + + property filename: filenamety read ffilename write setfilename; + property path: filenamety read fpath; + end; + + tdirnode = class(tfilenode) + protected + fcustomcaption: msestring; + procedure setfilename(const value: filenamety); override; + function getcurrentimagenr: integer; override; + function calccaption: msestring; + public + constructor create; + procedure setvaluetext(var avalue: msestring); override; + procedure dostatread(const reader: tstatreader); override; + procedure dostatwrite(const writer: tstatwriter); override; + end; + + tcmodulenode = class(tfilenode) + end; + + tformnode = class(tfilenode,irecordfield) + private + fclasstype: msestring; + fformname: msestring; + finstancevarname: msestring; + protected + function getcurrentimagenr: integer; override; + procedure setfilename(const value: filenamety); override; + function getfieldtext(const fieldindex: integer): msestring; + procedure setfieldtext(const fieldindex: integer; var avalue: msestring); + public + constructor create; + procedure dostatread(const reader: tstatreader); override; + procedure dostatwrite(const writer: tstatwriter); override; + end; + + tunitnode = class(tfilenode) + private + fformfile: tformnode; + protected + function getcurrentimagenr: integer; override; + public + procedure dostatread(const reader: tstatreader); override; + function setformfile(afilename: filenamety): tformnode; + end; + + tprojectrootnode = class(tprojectnode) + public + function getvaluetext: msestring; override; + end; + + tfilenodehashlist = class(tpointermsestringhashdatalist) + end; + + tnamehashlist = class(tpointeransistringhashdatalist) + end; + + tfilesnode = class(tprojectrootnode) + private + fhashlist: tfilenodehashlist; + fchangedcount: integer; + protected + function getcurrentimagenr: integer; override; + function createsubnode: ttreelistitem; override; + function createnode: tfilenode; virtual; + procedure removefilehash(const anode: tfilenode); virtual; + procedure addfilehash(const anode: tfilenode); virtual; + public + constructor create; + destructor destroy; override; + procedure clear; override; + procedure loadlist; virtual; + function addfile(const currentnode: tprojectnode; + const afilename: filenamety): tfilenode; + procedure addfiles(const currentnode: tprojectnode; + const afilenames: filenamearty); + procedure removefile(const anode: tfilenode); + function findfile(const filename: filenamety): tfilenode; + end; + + tunitsnode = class(tfilesnode) + private +// fmoduleclassnames: filenamearty; +// fmodulenames: filenamearty; +// fmodulefilenames: filenamearty; +// fstatreading: boolean; + fnamelist: tnamehashlist; + fclasstypelist: tnamehashlist; + protected + function createsubnode: ttreelistitem; override; + function createnode: tfilenode; override; + procedure removefilehash(const anode: tfilenode); override; + procedure addfilehash(const anode: tfilenode); override; + public + constructor create; + destructor destroy; override; + procedure clear; override; + procedure loadlist; override; + function addfile(const currentnode: tprojectnode; + const afilename: filenamety): tunitnode; +// function moduleclassnames: msestringarty; +// function modulenames: msestringarty; +// function modulefilenames(const aname: string): filenamearty; + function findformbyname(const aname: string; + out afilename: filenamety): boolean; + function findformbyclass(const aclassname: string; + out afilename: filenamety): boolean; + end; + + stopcheckprocty = procedure (var astop: boolean) of object; + tcmodulesnode = class(tfilesnode) + protected + function createsubnode: ttreelistitem; override; + function createnode(const afilename: filenamety): tfilenode; + reintroduce; virtual; + public + constructor create; + procedure parse(const astopcheckproc: stopcheckprocty = nil); + procedure modulechanged(const aname: filenamety); + procedure modulecompiled(const aname: filenamety); + end; + + tprojecttree = class + private + funits: tunitsnode; + fcmodules: tcmodulesnode; + ffiles: tfilesnode; + procedure docellevent(const projectedit: ttreeitemedit; + var info: celleventinfoty); + protected + public + constructor create; + function units: tunitsnode; + function cmodules: tcmodulesnode; + function files: tfilesnode; + function updatestat(const filer: tstatfiler): boolean; + //true if read data found + procedure updatelist; + end; + +var + projecttreefo: tprojecttreefo; + projecttree: tprojecttree; + +function isformfile(const aname: filenamety): boolean; + +implementation +uses + sysutils,projecttreeform_mfm,msefileutils,main,sourceform,msewidgets, + msedatalist,msedrag,sourceupdate,msemacros,projectoptionsform; +type + stringconsts = ( + pascalunits, //0 Pascal Units + str_cmodules, //1 C Modules + textfiles, //2 Text Files + wishremove, //3 Do you wish to remove " + selectdirectory, //4 Select Directory + wantremove, //5 Do you want to remove + withsubitems //6 with the sub-items from project? + ); +const +// unitscaption = 'Pascal Units'; +// cmodulescaption = 'C Modules'; +// filescaption = 'Text Files'; + mainico = -1; + fileico = 0; + unitico = 2; + formico = 4; + dirico = 6; + +function isformfile(const aname: filenamety): boolean; +begin + result:= issamefilename(aname,replacefileext(aname,formfileext)); +end; + +{ tprojectnode } + +constructor tprojectnode.create(const akind: projectnodety); +begin + fkind:= akind; + inherited create; +// include(fstate1,ns1_customsort); + fstate:= fstate + [ns_sorted]; +end; + +function tprojectnode.compare(const r: tlistitem; + const acasesensitive: boolean): integer; +begin + result:= 0; + if fkind = pnk_dir then begin + dec(result); + end; + if tprojectnode(r).fkind = pnk_dir then begin + inc(result); + end; + if result = 0 then begin + result:= inherited compare(r,acasesensitive); +// result:= msestringicomp(l.caption,r.caption); + end; +end; + +function tprojectnode.getcurrentimagenr: integer; +begin + result:= -1; +end; + +{ tfilenode } + +constructor tfilenode.create(const akind: projectnodety); +begin + fkind:= akind; + inherited create(akind); +// filename:= afilename; + include(fstate,ns_readonly); +end; + +procedure tfilenode.dostatread(const reader: tstatreader); +begin + ffilename:= reader.readmsestring('file',ffilename); +// ffilenamerel:= reader.readmsestring('filerel',ffilename); +// tfilesnode(rootnode).fhashlist.add(ffilename,self); + inherited; +end; + +procedure tfilenode.dostatwrite(const writer: tstatwriter); +begin + writer.writemsestring('file',ffilename); + writer.writeinteger('kind',ord(fkind)); + inherited; +end; + +procedure tfilenode.setfilename(const value: filenamety); +begin + ffilename:= relativepath(value,parentpath); + if fkind <> pnk_dir then begin + caption:= msefileutils.filename(value); + end; + with tfilesnode(rootnode) do begin + removefilehash(self); + self.updatepath; + addfilehash(self); + end; +end; + +function tfilenode.getvaluetext: msestring; +begin + result:= ffilename; +end; +{ +function tfilenode.getpath: filenamety; +begin + result:= ffilename; +end; +} +function tfilenode.parentpath: msestring; +var + n1: tprojectnode; +begin + n1:= self; + repeat + n1:= tprojectnode(n1.fparent); + until (n1 = nil) or (n1.fkind = pnk_dir); + if n1 <> nil then begin + result:= tfilenode(n1).path; + end + else begin + result:= getcurrentdirmse; + end; +end; + +procedure tfilenode.updatepath; +var + mstr1,mstr2: msestring; +begin + mstr1:= filename; + if fkind = pnk_dir then begin + expandprmacros1(mstr1); + end; + mstr2:= parentpath; + fpath:= filepath(mstr2,mstr1); + case fkind of + pnk_dir: begin + with tdirnode(self) do begin + if fcustomcaption <> '' then begin + caption:= fcustomcaption; + end + else begin + if (mstr1 <> '') and (mstr1[1] = '/') then begin + caption:= fpath; + end + else begin + caption:= relativepath(fpath,mstr2); + end; + end; + end; + end; + pnk_source,pnk_form: begin + caption:= msefileutils.filename(fpath); + end; + end; +end; + +function tfilenode.getcurrentimagenr: integer; +begin + result:= fileico; +end; + +{ tformnode } + +constructor tformnode.create; +begin + inherited create(pnk_form); + include(fstate,ns_nosubnodestat); +// filename:= afilename; + add(trecordfielditem.create(irecordfield(self),0,'classtype',true,-1, + projecttreefo.dummyimage)); + add(trecordfielditem.create(irecordfield(self),1,'name',true,-1, + projecttreefo.dummyimage)); + add(trecordfielditem.create(irecordfield(self),2,'instancevarname',true,-1, + projecttreefo.dummyimage)); +end; + +procedure tformnode.dostatread(const reader: tstatreader); +begin + inherited; + fclasstype:= reader.readmsestring('classtype',fclasstype); + fformname:= reader.readmsestring('formname',fformname); + finstancevarname:= reader.readmsestring('instancevarname',finstancevarname); +end; + +procedure tformnode.dostatwrite(const writer: tstatwriter); +begin + inherited; + writer.writemsestring('classtype',fclasstype); + writer.writemsestring('formname',fformname); + writer.writemsestring('instancevarname',finstancevarname); +end; + +procedure tformnode.setfilename(const value: filenamety); +var + po1: pmoduleinfoty; +begin + if value <> '' then begin + po1:= nil; + try + po1:= mainfo.openformfile(value,false,false,false,true,false); + except + end; + if po1 <> nil then begin + fclasstype:= msestring(po1^.moduleclassname); + fformname:= msestring(po1^.instance.Name); + finstancevarname:= msestring(po1^.instancevarname); + end + else begin + fclasstype:= ''; + end; + end; + inherited; + caption:= removefileext(msefileutils.filename(value)); +end; + + +function tformnode.getfieldtext(const fieldindex: integer): msestring; +begin + case fieldindex of + 0: result:= fclasstype; + 1: result:= fformname; + 2: result:= finstancevarname; + else result:= ''; + end; +end; + +procedure tformnode.setfieldtext(const fieldindex: integer; + var avalue: msestring); +var + n1: tfilesnode; +begin + n1:= tfilesnode(rootnode); + n1.removefilehash(self); + case fieldindex of + 0: begin + fclasstype:= msestring(designer.changemoduleclassname(fpath, + ansistring(avalue))); + avalue:= fclasstype; + end; + 1: begin + fformname:= msestring(designer.changemodulename(fpath,ansistring(avalue))); + avalue:= fformname; + end; + 2: begin + finstancevarname:= msestring(designer.changeinstancevarname( + fpath,ansistring(avalue))); + avalue:= finstancevarname; + end; + end; + n1.addfilehash(self); +end; + +function tformnode.getcurrentimagenr: integer; +begin + result:= formico; +end; + +{ tunitnode } + +procedure tunitnode.dostatread(const reader: tstatreader); +begin + inherited;{ + if (ftreelevel = 2) and (fkind = pnk_form) or isformfile(ffilename) then begin + fkind:= pnk_form; + tunitnode(fparent).fformfile:= self; + end; + } +end; + +function tunitnode.getcurrentimagenr: integer; +begin + result:= fileico; + if fcount > 0 then begin + result:= unitico; + end; +end; + +function tunitnode.setformfile(afilename: filenamety): tformnode; +begin + if afilename = '' then begin + fformfile:= nil; + clear; + end + else begin + projecttreefo.projectedit.itemlist.beginupdate(); + try + if fformfile = nil then begin + fformfile:= tformnode.create; + add(ttreelistitem(fformfile)); + end; + fformfile.filename:= afilename; + finally + projecttreefo.projectedit.itemlist.endupdate(); + end; + end; + result:= fformfile; + imagenr:= getcurrentimagenr; +end; + +{ tprojectrootnode } + +function tprojectrootnode.getvaluetext: msestring; +begin + result:= ''; +end; + +{ tfilesnode } + +constructor tfilesnode.create; +begin + fhashlist:= tfilenodehashlist.create; + inherited create(pnk_files); + fstate:= fstate + [ns_readonly,ns_drawemptybox]; + caption:= projecttreefo.c[ord(textfiles)]; +end; + +destructor tfilesnode.destroy; +begin + inherited; + fhashlist.free; +end; + +function tfilesnode.addfile(const currentnode: tprojectnode; + const afilename: filenamety): tfilenode; +var + n1: tprojectnode; + ind1: integer; +begin + result:= findfile(afilename); + if result = nil then begin + projecttreefo.projectedit.itemlist.beginupdate(); + try + n1:= currentnode; + if n1 <> nil then begin + ind1:= n1.count; + end; + while (n1 <> nil) and (n1.fkind <> pnk_dir) do begin + ind1:= n1.parentindex; + n1:= tprojectnode(n1.parent); + end; + if (n1 = nil) then begin + n1:= self; + ind1:= count; + end; + result:= createnode; + n1.insert(ind1,result); + result.filename:= afilename; + fhashlist.add(result.fpath,result); + inc(fchangedcount); + finally + projecttreefo.projectedit.itemlist.endupdate(); + end; + end; +end; + +procedure tfilesnode.removefilehash(const anode: tfilenode); +begin + if anode.fkind <> pnk_dir then begin + fhashlist.delete(anode.fpath,anode); + end; +end; + +procedure tfilesnode.addfilehash(const anode: tfilenode); +begin + if anode.fkind <> pnk_dir then begin + fhashlist.add(anode.fpath,anode); + end; +end; + +procedure tfilesnode.addfiles(const currentnode: tprojectnode; + const afilenames: filenamearty); +var + int1: integer; +begin + beginupdate; + try + for int1:= 0 to high(afilenames) do begin + addfile(currentnode,afilenames[int1]); + end; + finally + endupdate; + end; +end; + +procedure tfilesnode.removefile(const anode: tfilenode); +var + int1: integer; +begin + with anode do begin + if fkind <> pnk_dir then begin + if fmodified then begin + dec(fchangedcount); + end; + removefilehash(anode); + end; + for int1:= 0 to count - 1 do begin + if tprojectnode(fitems[int1]).fkind in [pnk_source,pnk_dir] then begin + removefile(tfilenode(fitems[int1])); + end; + end; + end; +// fhashlist.delete(anode.fpath,anode); +end; + +function tfilesnode.findfile(const filename: filenamety): tfilenode; +//var +// int1: integer; +begin + result:= tfilenode(fhashlist.find(filename)); +end; + +function tfilesnode.createnode: tfilenode; +begin + result:= tfilenode.create(pnk_source); +end; + +function tfilesnode.createsubnode: ttreelistitem; +begin + result:= tfilenode.create(pnk_none); +end; + +procedure tfilesnode.clear; +begin + fhashlist.clear; + inherited; + fchangedcount:= 0; +end; + +procedure tfilesnode.loadlist; +var + li: tmacrolist; + + procedure scan(const anode: tprojectnode; const apath: filenamety); + var + int1: integer; + mstr1: filenamety; + begin + with tfilenode(anode) do begin + if fkind in filenodes then begin + mstr1:= filename; + if fkind = pnk_dir then begin + li.expandmacros1(mstr1); + end; + fpath:= filepath(apath,mstr1); + case fkind of + pnk_dir: begin + with tdirnode(anode) do begin + if fcustomcaption <> '' then begin + fcaption:= fcustomcaption; + end + else begin + if (mstr1 <> '') and (mstr1[1] = '/') then begin + fcaption:= fpath; + end + else begin + fcaption:= relativepath(fpath,apath); + end; + end; + end; + for int1:= 0 to fcount-1 do begin + scan(tprojectnode(fitems[int1]),fpath); + end; + end; + pnk_source,pnk_form: begin +// fhashlist.add(fpath,anode); + addfilehash(tfilenode(anode)); + if fkind = pnk_source then begin + for int1:= 0 to fcount-1 do begin + scan(tprojectnode(fitems[int1]),apath); + end; + end; + end; + end; + end; + end; + anode.imagenr:= anode.getcurrentimagenr; + end; //scan + +var + int1: integer; + mstr1: msestring; + +begin + li:= getmacros; + beginupdate; + try + fhashlist.clear; + mstr1:= getcurrentdirmse; + for int1:= 0 to fcount-1 do begin + scan(tprojectnode(fitems[int1]),mstr1); + end; + imagenr:= getcurrentimagenr; + finally + fchangedcount:= fhashlist.count; + li.Free; + endupdate; + end; +end; + +function tfilesnode.getcurrentimagenr: integer; +begin + result:= dirico; +end; + +{ tunitsnode } + +constructor tunitsnode.create; +begin + inherited create; + caption:= projecttreefo.c[ord(pascalunits)]; + fnamelist:= tnamehashlist.create; + fclasstypelist:= tnamehashlist.create; +end; + +destructor tunitsnode.destroy; +begin + inherited; + fnamelist.free; + fclasstypelist.free; +end; + +function tunitsnode.addfile(const currentnode: tprojectnode; + const afilename: filenamety): tunitnode; +begin + result:= tunitnode(inherited addfile(currentnode,afilename)); +end; + +function tunitsnode.createnode: tfilenode; +begin + result:= tunitnode.create(pnk_source); +end; + +function tunitsnode.createsubnode: ttreelistitem; +begin + result:= tunitnode.create(pnk_none); +end; + +function tunitsnode.findformbyclass(const aclassname: string; + out afilename: filenamety): boolean; +var + n1: tformnode; +begin + afilename:= ''; + result:= fclasstypelist.find(aclassname,pointer(n1)); + if result then begin + afilename:= n1.path; + end; +end; + +function tunitsnode.findformbyname(const aname: string; + out afilename: filenamety): boolean; +var + n1: tformnode; +begin + afilename:= ''; + result:= fnamelist.find(aname,pointer(n1)); + if result then begin + afilename:= n1.path; + end; +end; + +procedure tunitsnode.clear; +begin + fnamelist.clear; + fclasstypelist.clear; + inherited; +end; + +procedure tunitsnode.removefilehash(const anode: tfilenode); +begin + if anode.fkind = pnk_form then begin + with tformnode(anode) do begin + fnamelist.delete(struppercase(string(fformname)),anode); + fclasstypelist.delete(struppercase(string(fclasstype)),anode); + end; + end; + inherited; +end; + +procedure tunitsnode.addfilehash(const anode: tfilenode); +begin + if anode.fkind = pnk_form then begin + with tformnode(anode) do begin + fnamelist.add(struppercase(string(fformname)),anode); + fclasstypelist.add(struppercase(string(fclasstype)),anode); + end; + end; +end; + +procedure tunitsnode.loadlist; +begin + fnamelist.clear; + fclasstypelist.clear; + inherited; +end; + +{ +function tunitsnode.modulefilenames: filenamearty; +var + int1,int2,int3: integer; +begin + if fstatreading then begin + result:= fmodulefilenames; + end + else begin + int2:= 0; + for int1:= 0 to fcount - 1 do begin + with tfilenode(fitems[int1]) do begin + for int3:= 0 to count - 1 do begin + with tfilenode(items[int3]) do begin + if fkind = pnk_form then begin + additem(result,ffilename,int2); + end; + end; + end; + end; + end; + setlength(result,int2); + end; +end; + +function tunitsnode.modulenames: msestringarty; +var + int1,int2,int3: integer; +begin + if fstatreading then begin + result:= fmodulenames; + end + else begin + int2:= 0; + for int1:= 0 to fcount - 1 do begin + with tfilenode(fitems[int1]) do begin + for int3:= 0 to count - 1 do begin + with tformnode(items[int3]) do begin + if fkind = pnk_form then begin + additem(result,struppercase(fformname),int2); + end; + end; + end; + end; + end; + setlength(result,int2); + end; +end; + +function tunitsnode.moduleclassnames: msestringarty; +var + int1,int2,int3: integer; +begin + if fstatreading then begin + result:= fmoduleclassnames; + end + else begin + int2:= 0; + for int1:= 0 to fcount - 1 do begin + with tfilenode(fitems[int1]) do begin + for int3:= 0 to count - 1 do begin + with tformnode(items[int3]) do begin + if fkind = pnk_form then begin + additem(result,struppercase(fclasstype),int2); + end; + end; + end; + end; + end; + setlength(result,int2); + end; +end; +} +{ tcmodulesnode } + +constructor tcmodulesnode.create; +begin + inherited; + caption:= projecttreefo.c[ord(str_cmodules)]; +end; + +procedure tcmodulesnode.parse(const astopcheckproc: stopcheckprocty); +var + int1,int2: integer; + bo1: boolean; +begin + if fchangedcount > 0 then begin + application.beginwait; + try + bo1:= false; + for int1:= 0 to count - 1 do begin + with tcmodulenode(fitems[int1]) do begin + if fmodified then begin + if application.waitescaped then begin + break; + end; + sourceupdater.updatesourceunit(ffilename,int2,false); + end; + end; + if {$ifndef FPC}@{$endif}astopcheckproc <> nil then begin + astopcheckproc(bo1); + if bo1 then begin + break; + end; + end; + end; + finally + application.endwait; + end; + end; +end; + +function tcmodulesnode.createsubnode: ttreelistitem; +begin + result:= tcmodulenode.create(pnk_none); +end; + +function tcmodulesnode.createnode(const afilename: filenamety): tfilenode; +begin + result:= tcmodulenode.create(pnk_source); +end; + +procedure tcmodulesnode.modulechanged(const aname: filenamety); +var + node1: tcmodulenode; +begin + node1:= tcmodulenode(fhashlist.find(aname)); + if (node1 <> nil) and not node1.fmodified then begin + node1.fmodified:= true; + inc(fchangedcount); + end; +end; + +procedure tcmodulesnode.modulecompiled(const aname: filenamety); +var + node1: tcmodulenode; +begin + node1:= tcmodulenode(fhashlist.find(aname)); + if (node1 <> nil) and node1.fmodified then begin + node1.fmodified:= false; + dec(fchangedcount); + end; +end; + +{ tprojecttree } + +constructor tprojecttree.create; +begin + funits:= tunitsnode.create; + fcmodules:= tcmodulesnode.create; + ffiles:= tfilesnode.create; +end; + +function tprojecttree.files: tfilesnode; +begin + result:= ffiles; +end; + +function tprojecttree.units: tunitsnode; +begin + result:= funits; +end; + +function tprojecttree.cmodules: tcmodulesnode; +begin + result:= fcmodules; +end; + +procedure tprojecttree.updatelist; +begin + funits.loadlist; + fcmodules.loadlist; + ffiles.loadlist; + projecttreefo.grid.invalidate; +end; + +function tprojecttree.updatestat(const filer: tstatfiler): boolean; + + procedure scan(const anode: tprojectnode); + var + int1: integer; + begin + with anode do begin + if fkind = pnk_form then begin + with tformnode(anode) do begin + funits.fnamelist.add(struppercase(string(fformname)),anode); + funits.fclasstypelist.add(struppercase(string(fclasstype)),anode); + end; + end; + for int1:= 0 to count-1 do begin + scan(tprojectnode(fitems[int1])); + end; + end; + end; + +begin + result:= false; + if not filer.candata then begin + exit; + end; + if not filer.iswriter then begin + funits.clear; + fcmodules.clear; + ffiles.clear; + with tstatreader(filer) do begin + result:= checkvar('units') or checkvar('cmodules') or checkvar('files'); + end; + end; + projecttreefo.projectedit.itemlist.beginupdate; + try + projecttreefo.funitloading:= true; + projecttreefo.projectedit.itemlist.updatenode('units',filer,funits); + scan(funits); + projecttreefo.funitloading:= false; + projecttreefo.projectedit.itemlist.updatenode('cmodules',filer,fcmodules); + projecttreefo.projectedit.itemlist.updatenode('files',filer,ffiles); + funits.caption:= projecttreefo.c[ord(pascalunits)]; + fcmodules.caption:= projecttreefo.c[ord(str_cmodules)]; + ffiles.caption:= projecttreefo.c[ord(textfiles)]; + finally + projecttreefo.projectedit.itemlist.endupdate; + end; +end; + +procedure tprojecttree.docellevent(const projectedit: ttreeitemedit; + var info: celleventinfoty); +var + node1,node2: ttreelistitem; +begin + if iscellclick(info,[ccr_nodefaultzone,ccr_dblclick]) then begin + if projectedit.item.treelevel > 0 then begin + node1:= projectedit[info.cell.row]; + node2:= node1.rootnode; + if node2 = funits then begin + with tunitnode(node1) do begin + case fkind of + pnk_form: begin + mainfo.openformfile(fpath,true,true,true,true,false); + end; + pnk_source: begin + sourcefo.openfile(fpath,true); + end; + end; + end; + end + else begin + if (node2 = ffiles) or (node2 = fcmodules) then begin + with tfilenode(node1) do begin + if fkind <> pnk_dir then begin + sourcefo.openfile(fpath,true); + end; + end; + end; + end; + end; + end; +end; + +{ tprojecttreefo } + +procedure tprojecttreefo.projecteditonstatreaditem(const sender: TObject; + const reader: tstatreader; var aitem: ttreelistitem); +var + kind: projectnodety; +begin + kind:= projectnodety(reader.readinteger('kind',ord(pnk_none),ord(low(projectnodety)), + ord(high(projectnodety)))); + case kind of + pnk_form: begin + aitem:= tformnode.create; + end; + pnk_source: begin + if funitloading then begin + aitem:= tunitnode.create(kind); + end + else begin + aitem:= tfilenode.create(kind); + end; + end; + pnk_dir: begin + aitem:= tdirnode.create; + end; + end; +end; + +function tprojecttreefo.addirectory(const aname: filenamety): tdirnode; +var + n2: tprojectnode; +begin + result:= tdirnode.create; + result.filename:= relativepath(aname,gettreedir); + n2:= tprojectnode(projectedit.item); + if (n2.fkind = pnk_dir) or (n2.parent = nil) then begin + n2.insert(0,result); + end + else begin + while (n2.treelevel > 1) and + (tprojectnode(n2.parent).fkind <> pnk_dir) do begin + n2:= tprojectnode(n2.parent); + end; + n2.parent.insert(n2.parentindex,result); + end; + tfilesnode(n2.rootnode).loadlist; +end; + +procedure tprojecttreefo.projecteditonupdaterowvalues(const sender: TObject; + const aindex: Integer; const aitem: tlistitem); +begin +{ + if aitem is trecordfielditem then begin + edit[aindex]:= trecordfielditem(aitem).valuetext; + end + else begin + if aitem is tfilenode then begin + edit[aindex]:= tfilenode(aitem).ffilename; + end + else begin + edit[aindex]:= ''; + end; + end; + } +end; + +procedure tprojecttreefo.projecttreefooncreate(const sender: tobject); +begin + projecttree:= tprojecttree.create; +end; + +procedure tprojecttreefo.projecttreefoonloaded(const sender: tobject); +begin + if not finited then begin + finited:= true; + projecttree.units.caption:= projecttreefo.c[ord(pascalunits)]; + projecttree.files.caption:= projecttreefo.c[ord(textfiles)]; + projecttree.cmodules.caption:= projecttreefo.c[ord(str_cmodules)]; + projectedit.itemlist.add(ttreelistedititem(projecttree.units)); + projectedit.itemlist.add(ttreelistedititem(projecttree.cmodules)); + projectedit.itemlist.add(ttreelistedititem(projecttree.files)); + end; +end; + +procedure tprojecttreefo.clear; +begin + projecttree.units.clear; + projecttree.files.clear; + projecttree.cmodules.clear; +end; + +procedure tprojecttreefo.projecttreefoondestroy(const sender: tobject); +begin + projecttree.Free; +end; + +procedure tprojecttreefo.projecteditonpopup(const sender: tobject; + var amenu: tpopupmenu; var mouseinfo: mouseeventinfoty); +begin + if projectedit.item.rootnode = projecttree.units then begin + freeandnil(amenu); + tpopupmenu.additems(amenu,self,mouseinfo,unitpopup); + end + else begin + if projectedit.item.rootnode = projecttree.files then begin + freeandnil(amenu); + tpopupmenu.additems(amenu,self,mouseinfo,filepopup); + end + else begin + if projectedit.item.rootnode = projecttree.cmodules then begin + freeandnil(amenu); + tpopupmenu.additems(amenu,self,mouseinfo,cmodulepopup); + end; + end; + end; +end; + +procedure tprojecttreefo.addunitfileonexecute(const sender: tobject); +begin + mainfo.openfile.controller.filename:= gettreedir; + mainfo.opensource(fk_unit,true,false,tprojectnode(projectedit.item)); + activate; //windowmanager can activate new form window +end; + +procedure tprojecttreefo.removeunitfileonexecute(const sender: tobject); +var + rowbefore: integer; + rnode: ttreelistitem; +begin + with tfilenode(projectedit.item) do begin + if askok(c[ord(wishremove)]+ ffilename + + '"?','') then begin + if sourcefo.closepage(fpath) then begin + rowbefore:= grid.row; + rnode:= rootnode; + if rnode is tfilesnode then begin + tfilesnode(rnode).removefile(tfilenode(projectedit.item)); + end; + projectedit.item.Free; + grid.row:= rowbefore; + end; + end; + end; +end; + +procedure tprojecttreefo.addcmoduleonexecute(const sender: TObject); +begin + cmoduledialog.controller.filename:= gettreedir; + if cmoduledialog.execute = mr_ok then begin + projecttree.cmodules.addfiles(tprojectnode(projectedit.item), + cmoduledialog.controller.filenames); + end; +end; + +procedure tprojecttreefo.removecmoduleonexecute(const sender: TObject); +begin + removeunitfileonexecute(sender); +end; + +procedure tprojecttreefo.addfileexe(const sender: TObject); +begin + with mainfo.openfile do begin + controller.filename:= gettreedir; + if execute = mr_ok then begin + projecttree.files.addfiles(tprojectnode(projectedit.item), + controller.filenames); + end; + end; +end; + +procedure tprojecttreefo.adddirexe(const sender: TObject); +var + int1: integer; +begin + with mainfo.openfile.controller do begin + filename:= gettreedir; + if execute(fdk_open,c[ord(selectdirectory)], + [fdo_directory]) = mr_ok then begin + int1:= addirectory(filename).index; + if int1 >= 0 then begin + grid.row:= int1; + end; + end; + end; +end; + +procedure tprojecttreefo.remdirexe(const sender: TObject); + +begin + if askyesno(c[ord(wantremove)]+' '+lineend+ + tfilenode(projectedit.item).fpath+lineend+ + c[ord(withsubitems)]) then begin + tfilesnode(projectedit.item.rootnode).removefile(tdirnode(projectedit.item)); + projectedit.item.free; + end; +end; + +procedure tprojecttreefo.removefileonexecute(const sender: TObject); +begin + removeunitfileonexecute(sender); +end; + +procedure tprojecttreefo.projecttreeonupdatestat(const sender: tobject; + const filer: tstatfiler); +begin +// projecttree.updatestat(filer); +end; + +procedure tprojecttreefo.projecteditoncellevent(const sender: tobject; + var info: celleventinfoty); +begin + projecttree.docellevent(projectedit,info); +end; + +procedure tprojecttreefo.editoncellevent(const sender: TObject; + var info: celleventinfoty); +begin + projecttree.docellevent(projectedit,info); +end; + +procedure tprojecttreefo.itemoncheckrowmove(const curindex: Integer; const newindex: Integer; + var accept: Boolean); +var + source,dest: ttreelistitem; +begin + source:= projectedit[curindex]; + dest:= projectedit[newindex]; + if (source.treelevel = 1) and (dest.treelevel = 1) and + (source.parent = dest.parent) then begin + accept:= true; + end; +end; + +procedure tprojecttreefo.projecteditonchange(const sender: TObject); +begin +// updatesubmodules; +end; + +procedure tprojecttreefo.editdragbegin(const sender: ttreeitemedit; + const aitem: ttreelistitem; var candrag: Boolean; + var dragobject: ttreeitemdragobject; var processed: Boolean); +begin + candrag:= aitem.treelevel = 1; +end; + +procedure tprojecttreefo.editdragover(const sender: ttreeitemedit; + const source: ttreelistitem; const dest: ttreelistitem; + var dragobject: ttreeitemdragobject; var accept: Boolean; + var processed: Boolean); +begin + accept:= source.parent = dest.parent; +end; + +procedure tprojecttreefo.editdragrop(const sender: ttreeitemedit; + const source: ttreelistitem; const dest: ttreelistitem; + var dragobject: ttreeitemdragobject; var processed: Boolean); +begin + sender.dragdrop(dragobject); +end; + +procedure tprojecttreefo.receditdialogexe(const sender: TObject); +var + fn1: filenamety; + no1: tfilenode; +begin + no1:= tfilenode(projectedit.item); + fn1:= no1.path; + with mainfo.openfile.controller do begin + if execute(fn1,fdk_open,c[ord(selectdirectory)],[fdo_directory]) then begin + no1.filename:= relativepath(fn1,no1.parentpath); + end; + end; +end; + +procedure tprojecttreefo.gridcellevent(const sender: TObject; + var info: celleventinfoty); +begin + if isrowenter(info) then begin + edit.frame.buttons[1].visible:= + tprojectnode(projectedit.item).fkind = pnk_dir; + end; + if isrowexit(info) then begin + projectedit.readonly:= true; + end; +end; + +procedure tprojecttreefo.colshowhintexe(const sender: tdatacol; + const arow: Integer; var info: hintinfoty); +begin + if projectedit.items[arow] is tfilenode then begin + info.caption:= tfilenode(projectedit.items[arow]).path; + end; +end; + +procedure tprojecttreefo.edithintexe(const sender: TObject; + var info: hintinfoty); +begin + if projectedit.item is tfilenode then begin + info.caption:= tfilenode(projectedit.item).path; + end; +end; + +function tprojecttreefo.gettreedir: filenamety; +var + n1: tprojectnode; +begin + result:= ''; + n1:= tprojectnode(projectedit.item); + while (n1 <> nil) and not (n1.fkind in [pnk_dir,pnk_source]) do begin + n1:= tprojectnode(n1.parent); + end; + if n1 <> nil then begin + case n1.fkind of + pnk_dir: begin + result:= tfilenode(n1).path; + end; + pnk_source: begin + result:= tfilenode(n1).parentpath; + end; + end; + end; + if result = '' then begin + result:= getcurrentdirmse; + end; +end; + +procedure tprojecttreefo.updateremdirexe(const sender: tcustomaction); +begin + sender.enabled:= (projectedit.item <> nil) and + (tprojectnode(projectedit.item).fkind = pnk_dir); +end; + +procedure tprojecttreefo.updateadddirexe(const sender: tcustomaction); +begin + sender.enabled:= (projectedit.item <> nil) and + (tprojectnode(projectedit.item).fkind in [pnk_source,pnk_dir,pnk_files]); +end; + +procedure tprojecttreefo.remfileupdateexe(const sender: tcustomaction); +begin + sender.enabled:= tprojectnode(projectedit.item).fkind = pnk_source; +end; + +procedure tprojecttreefo.udateeditdirexe(const sender: tcustomaction); +begin + sender.enabled:= tprojectnode(projectedit.item).fkind = pnk_dir; +end; + +procedure tprojecttreefo.editdirexe(const sender: TObject); +begin + projectedit.readonly:= false; + projectedit.beginedit; +end; + +procedure tprojecttreefo.captionset(const sender: TObject; + var avalue: msestring; var accept: Boolean); +begin + if projectedit.item is tdirnode then begin + with tdirnode(projectedit.item) do begin + fcustomcaption:= avalue; + if avalue = '' then begin + avalue:= calccaption; + end; + end; + end; +end; + +{ tdirnode } + +constructor tdirnode.create; +begin + inherited create(pnk_dir); + exclude(fstate,ns_readonly); +end; + +procedure tdirnode.setvaluetext(var avalue: msestring); +begin + setfilename(avalue); +end; + +procedure tdirnode.setfilename(const value: filenamety); +begin + ffilename:= value; + if fowner <> nil then begin + tfilesnode(rootnode).loadlist; + end; + if fparent <> nil then begin + fparent.sort(false); + end; +end; + +function tdirnode.getcurrentimagenr: integer; +begin + result:= dirico; +end; + +procedure tdirnode.dostatread(const reader: tstatreader); +begin + fcustomcaption:= reader.readmsestring('capt',''); + inherited; +end; + +procedure tdirnode.dostatwrite(const writer: tstatwriter); +begin + writer.writemsestring('capt',fcustomcaption); + inherited; +end; + +function tdirnode.calccaption: msestring; +begin + result:= filename; + expandprmacros(result); + if (result <> '') and (result[1] = '/') then begin + result:= fpath; + end + else begin + result:= relativepath(fpath,parentpath); + end; +end; + +end. \ No newline at end of file diff --git a/mseide-msegui/apps/ide/projecttreeform_mfm.pas b/mseide-msegui/apps/ide/projecttreeform_mfm.pas new file mode 100644 index 0000000..9f2d40e --- /dev/null +++ b/mseide-msegui/apps/ide/projecttreeform_mfm.pas @@ -0,0 +1,475 @@ +unit projecttreeform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,projecttreeform; + +const + objdata: record size: integer; data: array[0..9153] of byte end = + (size: 9154; data: ( + 84,80,70,48,14,116,112,114,111,106,101,99,116,116,114,101,101,102,111,13, + 112,114,111,106,101,99,116,116,114,101,101,102,111,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111, + 119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115, + 117,98,102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,9,111,119,95,104,105,110,116,111,110,0,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,15,102,114,97,109, + 101,46,103,114,105,112,95,115,105,122,101,2,10,18,102,114,97,109,101,46, + 103,114,105,112,95,111,112,116,105,111,110,115,11,14,103,111,95,99,108,111, + 115,101,98,117,116,116,111,110,16,103,111,95,102,105,120,115,105,122,101,98, + 117,116,116,111,110,12,103,111,95,116,111,112,98,117,116,116,111,110,19,103, + 111,95,98,97,99,107,103,114,111,117,110,100,98,117,116,116,111,110,15,103, + 111,95,110,111,108,111,99,107,98,117,116,116,111,110,14,103,111,95,98,117, + 116,116,111,110,104,105,110,116,115,0,7,118,105,115,105,98,108,101,8,8, + 98,111,117,110,100,115,95,120,3,7,1,8,98,111,117,110,100,115,95,121, + 3,175,1,9,98,111,117,110,100,115,95,99,120,3,30,1,9,98,111,117, + 110,100,115,95,99,121,3,201,0,23,99,111,110,116,97,105,110,101,114,46, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111, + 117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114, + 114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102, + 111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111,99,117,115,19, + 111,119,95,109,111,117,115,101,116,114,97,110,115,112,97,114,101,110,116,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,26,99, + 111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,0,27,99,111,110,116,97,105,110,101,114,46,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,99,111, + 110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0,3, + 20,1,3,201,0,0,22,100,114,97,103,100,111,99,107,46,115,112,108,105, + 116,116,101,114,95,115,105,122,101,2,0,20,100,114,97,103,100,111,99,107, + 46,111,112,116,105,111,110,115,100,111,99,107,11,10,111,100,95,115,97,118, + 101,112,111,115,13,111,100,95,115,97,118,101,122,111,114,100,101,114,10,111, + 100,95,99,97,110,109,111,118,101,11,111,100,95,99,97,110,102,108,111,97, + 116,10,111,100,95,99,97,110,100,111,99,107,11,111,100,95,112,114,111,112, + 115,105,122,101,14,111,100,95,99,97,112,116,105,111,110,104,105,110,116,13, + 111,100,95,99,104,105,108,100,105,99,111,110,115,0,7,111,112,116,105,111, + 110,115,11,10,102,111,95,115,97,118,101,112,111,115,13,102,111,95,115,97, + 118,101,122,111,114,100,101,114,12,102,111,95,115,97,118,101,115,116,97,116, + 101,0,8,115,116,97,116,102,105,108,101,7,22,109,97,105,110,102,111,46, + 112,114,111,106,101,99,116,115,116,97,116,102,105,108,101,7,99,97,112,116, + 105,111,110,6,12,80,114,111,106,101,99,116,32,84,114,101,101,8,111,110, + 99,114,101,97,116,101,7,21,112,114,111,106,101,99,116,116,114,101,101,102, + 111,111,110,99,114,101,97,116,101,16,111,110,101,118,101,110,116,108,111,111, + 112,115,116,97,114,116,7,21,112,114,111,106,101,99,116,116,114,101,101,102, + 111,111,110,108,111,97,100,101,100,9,111,110,100,101,115,116,114,111,121,7, + 22,112,114,111,106,101,99,116,116,114,101,101,102,111,111,110,100,101,115,116, + 114,111,121,12,111,110,115,116,97,116,117,112,100,97,116,101,7,23,112,114, + 111,106,101,99,116,116,114,101,101,111,110,117,112,100,97,116,101,115,116,97, + 116,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,9,116, + 100,111,99,107,102,111,114,109,0,11,116,119,105,100,103,101,116,103,114,105, + 100,4,103,114,105,100,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119, + 95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,102,111, + 99,117,115,98,97,99,107,111,110,101,115,99,13,111,119,95,109,111,117,115, + 101,119,104,101,101,108,17,111,119,95,100,101,115,116,114,111,121,119,105,100, + 103,101,116,115,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110, + 100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,20,1,9, + 98,111,117,110,100,115,95,99,121,3,201,0,7,97,110,99,104,111,114,115, + 11,0,11,111,112,116,105,111,110,115,103,114,105,100,11,12,111,103,95,99, + 111,108,115,105,122,105,110,103,19,111,103,95,102,111,99,117,115,99,101,108, + 108,111,110,101,110,116,101,114,12,111,103,95,115,97,118,101,115,116,97,116, + 101,20,111,103,95,99,111,108,99,104,97,110,103,101,111,110,116,97,98,107, + 101,121,10,111,103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116, + 111,112,111,112,117,112,0,14,100,97,116,97,99,111,108,115,46,99,111,117, + 110,116,2,2,16,100,97,116,97,99,111,108,115,46,111,112,116,105,111,110, + 115,11,12,99,111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109, + 111,117,115,101,115,99,114,111,108,108,114,111,119,0,14,100,97,116,97,99, + 111,108,115,46,105,116,101,109,115,14,7,11,112,114,111,106,101,99,116,101, + 100,105,116,1,12,108,105,110,101,99,111,108,111,114,102,105,120,4,3,0, + 0,160,5,119,105,100,116,104,3,141,0,7,111,112,116,105,111,110,115,11, + 11,99,111,95,114,101,97,100,111,110,108,121,12,99,111,95,115,97,118,101, + 115,116,97,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108, + 114,111,119,0,11,111,110,99,101,108,108,101,118,101,110,116,7,22,112,114, + 111,106,101,99,116,101,100,105,116,111,110,99,101,108,108,101,118,101,110,116, + 10,119,105,100,103,101,116,110,97,109,101,6,11,112,114,111,106,101,99,116, + 101,100,105,116,9,100,97,116,97,99,108,97,115,115,7,17,116,116,114,101, + 101,105,116,101,109,101,100,105,116,108,105,115,116,22,100,97,116,97,108,105, + 115,116,46,105,109,110,114,95,101,120,112,97,110,100,101,100,2,1,18,100, + 97,116,97,108,105,115,116,46,105,109,97,103,101,108,105,115,116,7,9,110, + 111,100,101,105,99,111,110,115,19,100,97,116,97,108,105,115,116,46,105,109, + 97,103,101,119,105,100,116,104,2,16,20,100,97,116,97,108,105,115,116,46, + 105,109,97,103,101,104,101,105,103,104,116,2,16,23,100,97,116,97,108,105, + 115,116,46,111,110,115,116,97,116,114,101,97,100,105,116,101,109,7,25,112, + 114,111,106,101,99,116,101,100,105,116,111,110,115,116,97,116,114,101,97,100, + 105,116,101,109,20,100,97,116,97,108,105,115,116,46,111,110,100,114,97,103, + 98,101,103,105,110,7,13,101,100,105,116,100,114,97,103,98,101,103,105,110, + 19,100,97,116,97,108,105,115,116,46,111,110,100,114,97,103,111,118,101,114, + 7,12,101,100,105,116,100,114,97,103,111,118,101,114,19,100,97,116,97,108, + 105,115,116,46,111,110,100,114,97,103,100,114,111,112,7,11,101,100,105,116, + 100,114,97,103,114,111,112,0,7,4,101,100,105,116,1,12,108,105,110,101, + 99,111,108,111,114,102,105,120,4,3,0,0,160,5,119,105,100,116,104,3, + 129,0,7,111,112,116,105,111,110,115,11,7,99,111,95,102,105,108,108,12, + 99,111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109,111,117,115, + 101,115,99,114,111,108,108,114,111,119,0,10,111,110,115,104,111,119,104,105, + 110,116,7,14,99,111,108,115,104,111,119,104,105,110,116,101,120,101,10,119, + 105,100,103,101,116,110,97,109,101,6,4,101,100,105,116,9,100,97,116,97, + 99,108,97,115,115,7,13,116,105,116,101,109,101,100,105,116,108,105,115,116, + 0,0,13,100,97,116,97,114,111,119,104,101,105,103,104,116,2,17,8,115, + 116,97,116,102,105,108,101,7,22,109,97,105,110,102,111,46,112,114,111,106, + 101,99,116,115,116,97,116,102,105,108,101,11,111,110,99,101,108,108,101,118, + 101,110,116,7,13,103,114,105,100,99,101,108,108,101,118,101,110,116,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,13,116,116,114,101, + 101,105,116,101,109,101,100,105,116,11,112,114,111,106,101,99,116,101,100,105, + 116,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,14,111,119, + 49,95,97,117,116,111,104,101,105,103,104,116,0,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 5,99,111,108,111,114,4,7,0,0,144,12,102,114,97,109,101,46,108,101, + 118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108, + 105,101,110,116,4,2,0,0,128,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102, + 114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111, + 114,100,101,114,2,1,7,111,110,112,111,112,117,112,7,18,112,114,111,106, + 101,99,116,101,100,105,116,111,110,112,111,112,117,112,7,118,105,115,105,98, + 108,101,8,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,141,0,9,98, + 111,117,110,100,115,95,99,121,2,18,12,111,112,116,105,111,110,115,101,100, + 105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105,116,11,11,111, + 101,95,114,101,97,100,111,110,108,121,12,111,101,95,117,110,100,111,111,110, + 101,115,99,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108, + 15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,18,111,101,95, + 104,105,110,116,99,108,105,112,112,101,100,116,101,120,116,9,111,101,95,108, + 111,99,97,116,101,0,8,111,110,99,104,97,110,103,101,7,19,112,114,111, + 106,101,99,116,101,100,105,116,111,110,99,104,97,110,103,101,10,111,110,115, + 101,116,118,97,108,117,101,7,10,99,97,112,116,105,111,110,115,101,116,17, + 111,110,117,112,100,97,116,101,114,111,119,118,97,108,117,101,115,7,28,112, + 114,111,106,101,99,116,101,100,105,116,111,110,117,112,100,97,116,101,114,111, + 119,118,97,108,117,101,115,9,102,105,101,108,100,101,100,105,116,7,4,101, + 100,105,116,7,111,112,116,105,111,110,115,11,16,116,101,111,95,116,114,101, + 101,99,111,108,110,97,118,105,103,16,116,101,111,95,107,101,121,114,111,119, + 109,111,118,105,110,103,0,14,111,110,99,104,101,99,107,114,111,119,109,111, + 118,101,7,18,105,116,101,109,111,110,99,104,101,99,107,114,111,119,109,111, + 118,101,0,0,16,116,114,101,99,111,114,100,102,105,101,108,100,101,100,105, + 116,4,101,100,105,116,14,111,112,116,105,111,110,115,119,105,100,103,101,116, + 49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103, + 104,116,0,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,5,99,111,108,111,114,4,7,0,0, + 144,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97, + 109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99, + 111,108,111,114,4,2,0,0,128,20,102,114,97,109,101,46,98,117,116,116, + 111,110,46,111,112,116,105,111,110,115,11,13,102,98,111,95,105,110,118,105, + 115,105,98,108,101,0,19,102,114,97,109,101,46,98,117,116,116,111,110,115, + 46,99,111,117,110,116,2,2,19,102,114,97,109,101,46,98,117,116,116,111, + 110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4,2,0,0, + 128,7,111,112,116,105,111,110,115,11,13,102,98,111,95,105,110,118,105,115, + 105,98,108,101,0,0,1,5,99,111,108,111,114,4,2,0,0,128,7,105, + 109,97,103,101,110,114,2,17,9,111,110,101,120,101,99,117,116,101,7,16, + 114,101,99,101,100,105,116,100,105,97,108,111,103,101,120,101,0,0,8,116, + 97,98,111,114,100,101,114,2,2,10,111,110,115,104,111,119,104,105,110,116, + 7,11,101,100,105,116,104,105,110,116,101,120,101,7,118,105,115,105,98,108, + 101,8,8,98,111,117,110,100,115,95,120,3,142,0,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,129,0,9,98, + 111,117,110,100,115,95,99,121,2,17,12,111,112,116,105,111,110,115,101,100, + 105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111, + 101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101, + 113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99, + 101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101, + 95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115, + 101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111, + 110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101, + 114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97, + 117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99, + 107,18,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116, + 0,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101,110, + 116,101,114,101,100,8,116,102,95,99,108,105,112,111,11,116,102,95,110,111, + 115,101,108,101,99,116,14,116,102,95,101,108,108,105,112,115,101,108,101,102, + 116,0,11,111,110,99,101,108,108,101,118,101,110,116,7,15,101,100,105,116, + 111,110,99,101,108,108,101,118,101,110,116,19,100,114,111,112,100,111,119,110, + 46,99,111,108,115,46,99,111,117,110,116,2,1,19,100,114,111,112,100,111, + 119,110,46,99,111,108,115,46,105,116,101,109,115,14,1,0,0,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,0,10,116,112,111, + 112,117,112,109,101,110,117,9,117,110,105,116,112,111,112,117,112,11,109,101, + 110,117,46,97,99,116,105,111,110,7,14,97,100,100,117,110,105,116,102,105, + 108,101,97,99,116,18,109,101,110,117,46,115,117,98,109,101,110,117,46,99, + 111,117,110,116,2,6,18,109,101,110,117,46,115,117,98,109,101,110,117,46, + 105,116,101,109,115,14,1,6,97,99,116,105,111,110,7,14,97,100,100,117, + 110,105,116,102,105,108,101,97,99,116,0,1,6,97,99,116,105,111,110,7, + 17,114,101,109,111,118,101,117,110,105,116,102,105,108,101,97,99,116,0,1, + 7,111,112,116,105,111,110,115,11,13,109,97,111,95,115,101,112,97,114,97, + 116,111,114,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116, + 105,111,110,0,0,1,6,97,99,116,105,111,110,7,9,97,100,100,100,105, + 114,97,99,116,0,1,6,97,99,116,105,111,110,7,12,114,101,109,111,118, + 101,100,105,114,97,99,116,0,1,6,97,99,116,105,111,110,7,10,101,100, + 105,116,100,105,114,97,99,116,0,0,4,108,101,102,116,2,8,3,116,111, + 112,2,8,0,0,7,116,97,99,116,105,111,110,14,97,100,100,117,110,105, + 116,102,105,108,101,97,99,116,7,99,97,112,116,105,111,110,6,9,38,65, + 100,100,32,85,110,105,116,9,111,110,101,120,101,99,117,116,101,7,20,97, + 100,100,117,110,105,116,102,105,108,101,111,110,101,120,101,99,117,116,101,4, + 108,101,102,116,2,112,3,116,111,112,2,8,0,0,11,116,102,105,108,101, + 100,105,97,108,111,103,10,102,105,108,101,100,105,97,108,111,103,18,99,111, + 110,116,114,111,108,108,101,114,46,111,112,116,105,111,110,115,11,14,102,100, + 111,95,99,104,101,99,107,101,120,105,115,116,15,102,100,111,95,115,97,118, + 101,108,97,115,116,100,105,114,0,26,99,111,110,116,114,111,108,108,101,114, + 46,104,105,115,116,111,114,121,109,97,120,99,111,117,110,116,2,0,4,108, + 101,102,116,2,8,3,116,111,112,3,168,0,0,0,7,116,97,99,116,105, + 111,110,17,114,101,109,111,118,101,117,110,105,116,102,105,108,101,97,99,116, + 7,99,97,112,116,105,111,110,6,12,38,82,101,109,111,118,101,32,85,110, + 105,116,9,111,110,101,120,101,99,117,116,101,7,23,114,101,109,111,118,101, + 117,110,105,116,102,105,108,101,111,110,101,120,101,99,117,116,101,8,111,110, + 117,112,100,97,116,101,7,16,114,101,109,102,105,108,101,117,112,100,97,116, + 101,101,120,101,4,108,101,102,116,2,112,3,116,111,112,2,24,0,0,10, + 116,112,111,112,117,112,109,101,110,117,9,102,105,108,101,112,111,112,117,112, + 18,109,101,110,117,46,115,117,98,109,101,110,117,46,99,111,117,110,116,2, + 6,18,109,101,110,117,46,115,117,98,109,101,110,117,46,105,116,101,109,115, + 14,1,6,97,99,116,105,111,110,7,10,97,100,100,102,105,108,101,97,99, + 116,0,1,6,97,99,116,105,111,110,7,13,114,101,109,111,118,101,102,105, + 108,101,97,99,116,0,1,7,111,112,116,105,111,110,115,11,13,109,97,111, + 95,115,101,112,97,114,97,116,111,114,19,109,97,111,95,115,104,111,114,116, + 99,117,116,99,97,112,116,105,111,110,0,0,1,6,97,99,116,105,111,110, + 7,9,97,100,100,100,105,114,97,99,116,0,1,6,97,99,116,105,111,110, + 7,12,114,101,109,111,118,101,100,105,114,97,99,116,0,1,6,97,99,116, + 105,111,110,7,10,101,100,105,116,100,105,114,97,99,116,0,0,10,109,101, + 110,117,46,115,116,97,116,101,11,12,97,115,95,108,111,99,97,108,104,105, + 110,116,0,4,108,101,102,116,2,8,3,116,111,112,2,40,0,0,7,116, + 97,99,116,105,111,110,10,97,100,100,102,105,108,101,97,99,116,7,99,97, + 112,116,105,111,110,6,13,65,100,100,32,84,101,120,116,32,70,105,108,101, + 9,111,110,101,120,101,99,117,116,101,7,10,97,100,100,102,105,108,101,101, + 120,101,4,108,101,102,116,2,112,3,116,111,112,2,48,0,0,7,116,97, + 99,116,105,111,110,13,114,101,109,111,118,101,102,105,108,101,97,99,116,7, + 99,97,112,116,105,111,110,6,16,82,101,109,111,118,101,32,84,101,120,116, + 32,70,105,108,101,9,111,110,101,120,101,99,117,116,101,7,19,114,101,109, + 111,118,101,102,105,108,101,111,110,101,120,101,99,117,116,101,8,111,110,117, + 112,100,97,116,101,7,16,114,101,109,102,105,108,101,117,112,100,97,116,101, + 101,120,101,4,108,101,102,116,2,112,3,116,111,112,2,64,0,0,10,116, + 112,111,112,117,112,109,101,110,117,12,99,109,111,100,117,108,101,112,111,112, + 117,112,18,109,101,110,117,46,115,117,98,109,101,110,117,46,99,111,117,110, + 116,2,6,18,109,101,110,117,46,115,117,98,109,101,110,117,46,105,116,101, + 109,115,14,1,6,97,99,116,105,111,110,7,13,97,100,100,99,109,111,100, + 117,108,101,97,99,116,0,1,6,97,99,116,105,111,110,7,16,114,101,109, + 111,118,101,99,109,111,100,117,108,101,97,99,116,0,1,7,111,112,116,105, + 111,110,115,11,13,109,97,111,95,115,101,112,97,114,97,116,111,114,19,109, + 97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111,110,0,0, + 1,6,97,99,116,105,111,110,7,9,97,100,100,100,105,114,97,99,116,0, + 1,6,97,99,116,105,111,110,7,12,114,101,109,111,118,101,100,105,114,97, + 99,116,0,1,6,97,99,116,105,111,110,7,10,101,100,105,116,100,105,114, + 97,99,116,0,0,10,109,101,110,117,46,115,116,97,116,101,11,12,97,115, + 95,108,111,99,97,108,104,105,110,116,0,4,108,101,102,116,2,8,3,116, + 111,112,2,72,0,0,7,116,97,99,116,105,111,110,16,114,101,109,111,118, + 101,99,109,111,100,117,108,101,97,99,116,7,99,97,112,116,105,111,110,6, + 13,82,101,109,111,118,101,32,67,45,70,105,108,101,9,111,110,101,120,101, + 99,117,116,101,7,22,114,101,109,111,118,101,99,109,111,100,117,108,101,111, + 110,101,120,101,99,117,116,101,8,111,110,117,112,100,97,116,101,7,16,114, + 101,109,102,105,108,101,117,112,100,97,116,101,101,120,101,4,108,101,102,116, + 2,112,3,116,111,112,2,104,0,0,7,116,97,99,116,105,111,110,13,97, + 100,100,99,109,111,100,117,108,101,97,99,116,7,99,97,112,116,105,111,110, + 6,10,65,100,100,32,67,45,70,105,108,101,9,111,110,101,120,101,99,117, + 116,101,7,19,97,100,100,99,109,111,100,117,108,101,111,110,101,120,101,99, + 117,116,101,4,108,101,102,116,2,112,3,116,111,112,2,88,0,0,11,116, + 102,105,108,101,100,105,97,108,111,103,13,99,109,111,100,117,108,101,100,105, + 97,108,111,103,26,99,111,110,116,114,111,108,108,101,114,46,102,105,108,116, + 101,114,108,105,115,116,46,100,97,116,97,1,1,6,14,67,45,83,111,117, + 114,99,101,32,40,42,46,99,41,6,5,34,42,46,99,34,0,0,18,99, + 111,110,116,114,111,108,108,101,114,46,111,112,116,105,111,110,115,11,14,102, + 100,111,95,99,104,101,99,107,101,120,105,115,116,15,102,100,111,95,115,97, + 118,101,108,97,115,116,100,105,114,0,26,99,111,110,116,114,111,108,108,101, + 114,46,104,105,115,116,111,114,121,109,97,120,99,111,117,110,116,2,0,4, + 108,101,102,116,2,96,3,116,111,112,3,168,0,0,0,7,116,97,99,116, + 105,111,110,9,97,100,100,100,105,114,97,99,116,7,99,97,112,116,105,111, + 110,6,13,65,100,100,32,68,105,114,101,99,116,111,114,121,9,111,110,101, + 120,101,99,117,116,101,7,9,97,100,100,100,105,114,101,120,101,8,111,110, + 117,112,100,97,116,101,7,15,117,112,100,97,116,101,97,100,100,100,105,114, + 101,120,101,3,116,111,112,2,104,0,0,7,116,97,99,116,105,111,110,12, + 114,101,109,111,118,101,100,105,114,97,99,116,7,99,97,112,116,105,111,110, + 6,16,82,101,109,111,118,101,32,68,105,114,101,99,116,111,114,121,9,111, + 110,101,120,101,99,117,116,101,7,9,114,101,109,100,105,114,101,120,101,8, + 111,110,117,112,100,97,116,101,7,15,117,112,100,97,116,101,114,101,109,100, + 105,114,101,120,101,3,116,111,112,2,120,0,0,10,116,105,109,97,103,101, + 108,105,115,116,9,110,111,100,101,105,99,111,110,115,5,99,111,117,110,116, + 2,8,4,108,101,102,116,3,144,0,3,116,111,112,2,120,5,105,109,97, + 103,101,10,236,11,0,0,0,0,0,0,2,0,0,0,48,0,0,0,48, + 0,0,0,56,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255, + 0,255,99,0,0,0,6,255,0,255,10,0,0,0,6,255,0,255,9,0, + 0,0,6,255,0,255,11,0,0,0,1,255,255,255,4,0,0,0,2,255, + 0,255,9,0,0,0,1,255,255,255,4,0,0,0,2,255,0,255,8,0, + 0,0,1,255,255,255,4,0,0,0,2,255,0,255,10,0,0,0,1,255, + 255,255,4,0,0,0,1,255,255,255,1,0,0,0,1,255,0,255,8,0, + 0,0,1,255,255,255,4,0,0,0,1,255,255,255,1,0,0,0,1,255, + 0,255,7,0,0,0,1,255,255,255,4,0,0,0,1,255,255,255,1,0, + 0,0,1,255,0,255,9,0,0,0,1,255,255,255,4,0,0,0,1,255, + 255,255,2,0,0,0,1,255,0,255,7,0,0,0,1,255,255,255,4,0, + 0,0,1,255,255,255,2,0,0,0,1,255,0,255,6,0,0,0,1,255, + 255,255,2,255,142,120,1,224,50,16,5,174,174,174,1,224,50,16,1,0, + 0,0,1,255,0,255,5,0,0,0,1,255,255,255,4,0,0,0,5,255, + 0,255,6,0,0,0,1,255,255,255,4,0,0,0,5,255,0,255,5,0, + 0,0,1,255,255,255,2,242,242,242,1,224,224,224,7,128,128,128,1,255, + 0,255,5,0,0,0,1,255,255,255,8,0,0,0,1,128,128,128,1,255, + 0,255,5,0,0,0,1,255,255,255,8,0,0,0,1,128,128,128,1,255, + 0,255,4,0,0,0,1,255,255,255,2,242,242,242,1,224,224,224,7,128, + 128,128,1,255,0,255,5,0,0,0,1,255,255,255,8,0,0,0,1,128, + 128,128,1,255,0,255,5,0,0,0,1,255,255,255,8,0,0,0,1,128, + 128,128,1,255,0,255,4,0,0,0,1,255,255,255,2,242,242,242,1,224, + 224,224,7,128,128,128,1,255,0,255,5,0,0,0,1,255,255,255,8,0, + 0,0,1,128,128,128,1,255,0,255,5,0,0,0,1,255,255,255,8,0, + 0,0,1,128,128,128,1,255,0,255,4,0,0,0,1,255,255,255,2,242, + 242,242,1,224,224,224,1,242,242,242,5,224,224,224,1,128,128,128,1,255, + 0,255,5,0,0,0,1,255,255,255,8,0,0,0,1,128,128,128,1,255, + 0,255,5,0,0,0,1,255,255,255,8,0,0,0,1,128,128,128,1,255, + 0,255,4,0,0,0,1,255,255,255,2,242,242,242,1,224,224,224,1,242, + 242,242,1,224,224,224,3,128,128,128,1,224,224,224,1,128,128,128,1,255, + 0,255,5,0,0,0,1,255,255,255,8,0,0,0,1,128,128,128,1,255, + 0,255,5,0,0,0,1,255,255,255,8,0,0,0,1,128,128,128,1,255, + 0,255,4,0,0,0,1,255,255,255,2,242,242,242,1,224,224,224,1,242, + 242,242,1,224,224,224,3,128,128,128,1,224,224,224,1,128,128,128,1,255, + 0,255,5,0,0,0,1,255,255,255,8,0,0,0,1,128,128,128,1,255, + 0,255,5,0,0,0,1,255,255,255,8,0,0,0,1,128,128,128,1,255, + 0,255,4,0,0,0,1,255,255,255,2,242,242,242,1,224,224,224,1,242, + 242,242,1,128,128,128,4,224,224,224,1,128,128,128,1,255,0,255,5,0, + 0,0,10,128,128,128,1,255,0,255,5,0,0,0,10,128,128,128,1,255, + 0,255,4,0,0,0,3,242,242,242,1,224,224,224,7,128,128,128,1,255, + 0,255,6,128,128,128,10,255,0,255,6,128,128,128,10,255,0,255,5,128, + 128,128,2,242,242,242,1,128,128,128,8,255,0,255,148,0,0,0,6,255, + 0,255,42,0,0,0,1,255,255,255,4,0,0,0,2,255,0,255,10,255, + 142,120,1,224,50,16,6,174,174,174,1,224,50,16,1,0,0,0,1,255, + 0,255,6,255,142,120,1,224,50,16,6,174,174,174,1,224,50,16,1,0, + 0,0,1,255,0,255,5,0,0,0,1,255,255,255,4,0,0,0,1,255, + 255,255,1,0,0,0,1,255,0,255,9,242,242,242,1,224,224,224,8,128, + 128,128,1,255,0,255,6,242,242,242,1,224,224,224,8,128,128,128,1,255, + 0,255,5,0,0,0,1,255,255,255,2,255,142,120,1,224,50,16,5,174, + 174,174,1,224,50,16,1,0,0,0,1,255,0,255,5,242,242,242,1,224, + 224,224,8,128,128,128,1,255,0,255,6,242,242,242,1,224,224,224,8,128, + 128,128,1,255,0,255,5,0,0,0,1,255,255,255,2,242,242,242,1,224, + 224,224,7,128,128,128,1,255,0,255,5,242,242,242,1,224,224,224,8,128, + 128,128,1,255,0,255,6,242,242,242,1,224,224,224,8,128,128,128,1,255, + 0,255,5,0,0,0,1,255,255,255,2,242,242,242,1,224,224,224,7,128, + 128,128,1,255,0,255,5,242,242,242,1,224,224,224,1,242,242,242,6,224, + 224,224,1,128,128,128,1,255,0,255,6,242,242,242,1,224,224,224,1,242, + 242,242,6,224,224,224,1,128,128,128,1,255,0,255,5,0,0,0,1,255, + 255,255,2,242,242,242,1,224,224,224,7,128,128,128,1,255,0,255,5,242, + 242,242,1,224,224,224,1,242,242,242,1,224,224,224,4,128,128,128,1,224, + 224,224,1,128,128,128,1,255,0,255,6,242,242,242,1,224,224,224,1,242, + 242,242,1,224,224,224,4,128,128,128,1,224,224,224,1,128,128,128,1,255, + 0,255,5,0,0,0,1,255,255,255,2,242,242,242,1,224,224,224,1,242, + 242,242,5,224,224,224,1,128,128,128,1,255,0,255,5,242,242,242,1,224, + 224,224,1,242,242,242,1,224,224,224,4,128,128,128,1,224,224,224,1,128, + 128,128,1,255,0,255,6,242,242,242,1,224,224,224,1,242,242,242,1,224, + 224,224,4,128,128,128,1,224,224,224,1,128,128,128,1,255,0,255,5,0, + 0,0,1,255,255,255,2,242,242,242,1,224,224,224,1,242,242,242,1,224, + 224,224,3,128,128,128,1,224,224,224,1,128,128,128,1,255,0,255,5,242, + 242,242,1,224,224,224,1,242,242,242,1,128,128,128,5,224,224,224,1,128, + 128,128,1,255,0,255,6,242,242,242,1,224,224,224,1,242,242,242,1,128, + 128,128,5,224,224,224,1,128,128,128,1,255,0,255,5,0,0,0,1,255, + 255,255,2,242,242,242,1,224,224,224,1,242,242,242,1,224,224,224,3,128, + 128,128,1,224,224,224,1,128,128,128,1,255,0,255,5,242,242,242,1,224, + 224,224,8,128,128,128,1,255,0,255,6,242,242,242,1,224,224,224,8,128, + 128,128,1,255,0,255,5,0,0,0,1,255,255,255,2,242,242,242,1,224, + 224,224,1,242,242,242,1,128,128,128,4,224,224,224,1,128,128,128,1,255, + 0,255,5,242,242,242,1,128,128,128,9,255,0,255,6,242,242,242,1,128, + 128,128,9,255,0,255,5,0,0,0,3,242,242,242,1,224,224,224,7,128, + 128,128,1,255,0,255,37,128,128,128,2,242,242,242,1,128,128,128,8,255, + 0,255,212,0,0,0,6,255,0,255,11,127,127,127,1,0,0,0,4,127, + 127,127,1,255,0,255,9,127,127,127,1,0,0,0,4,127,127,127,1,255, + 0,255,10,0,0,0,1,255,255,255,4,0,0,0,2,255,0,255,10,0, + 0,0,1,255,255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,0, + 0,0,1,255,0,255,9,0,0,0,1,0,255,255,1,255,255,255,1,0, + 255,255,1,255,255,255,1,0,0,0,1,255,0,255,10,0,0,0,1,255, + 255,255,4,0,0,0,1,255,255,255,1,0,0,0,1,255,0,255,8,0, + 0,0,10,255,0,255,5,0,0,0,1,0,255,255,1,255,255,255,1,0, + 255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0,0,0,3,255, + 0,255,7,0,0,0,1,255,255,255,4,0,0,0,1,255,255,255,2,0, + 0,0,1,255,0,255,7,0,0,0,1,255,255,255,1,0,255,255,1,255, + 255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0, + 255,255,1,255,255,255,1,0,0,0,1,255,0,255,4,0,0,0,1,255, + 255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0, + 255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0,0,0,1,255, + 0,255,6,0,0,0,1,255,255,255,4,0,0,0,5,255,0,255,6,0, + 0,0,1,0,255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0, + 255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,0, + 0,0,1,255,0,255,4,0,0,0,1,0,255,255,1,255,255,255,1,0, + 255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,255, + 255,255,1,0,255,255,1,0,0,0,1,255,0,255,6,0,0,0,1,255, + 255,255,2,255,142,120,1,224,50,16,5,174,174,174,1,224,50,16,1,0, + 0,0,1,255,0,255,4,0,0,0,1,255,255,255,1,0,255,255,1,255, + 255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0, + 255,255,1,255,255,255,1,0,0,0,1,255,0,255,4,0,0,0,1,255, + 255,255,1,0,255,255,1,255,255,255,1,0,0,0,10,255,0,255,3,0, + 0,0,1,255,255,255,2,235,235,235,1,224,224,224,7,128,128,128,1,255, + 0,255,4,0,0,0,1,0,255,255,1,255,255,255,1,0,255,255,1,255, + 255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0, + 255,255,1,0,0,0,1,255,0,255,4,0,0,0,1,0,255,255,1,255, + 255,255,1,0,0,0,1,0,255,255,1,191,191,191,1,0,255,255,1,191, + 191,191,1,0,255,255,1,191,191,191,1,0,255,255,1,191,191,191,1,0, + 255,255,1,0,0,0,1,255,0,255,3,0,0,0,1,255,255,255,2,235, + 235,235,1,224,224,224,1,235,235,235,4,128,128,128,1,224,224,224,1,128, + 128,128,1,255,0,255,4,0,0,0,1,255,255,255,1,0,255,255,1,255, + 255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0, + 255,255,1,255,255,255,1,0,0,0,1,255,0,255,4,0,0,0,1,255, + 255,255,1,0,0,0,1,0,255,255,1,191,191,191,1,0,255,255,1,191, + 191,191,1,0,255,255,1,191,191,191,1,0,255,255,1,191,191,191,1,0, + 255,255,1,0,0,0,1,255,0,255,4,0,0,0,1,255,255,255,2,235, + 235,235,1,224,224,224,1,235,235,235,1,224,224,224,3,128,128,128,1,224, + 224,224,1,128,128,128,1,255,0,255,4,0,0,0,1,0,255,255,1,255, + 255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0, + 255,255,1,255,255,255,1,0,255,255,1,0,0,0,1,255,0,255,4,0, + 0,0,2,0,255,255,1,191,191,191,1,0,255,255,1,191,191,191,1,0, + 255,255,1,191,191,191,1,0,255,255,1,191,191,191,1,0,255,255,1,0, + 0,0,1,255,0,255,5,0,0,0,1,255,255,255,2,235,235,235,1,224, + 224,224,1,235,235,235,1,224,224,224,3,128,128,128,1,224,224,224,1,128, + 128,128,1,255,0,255,5,0,0,0,10,255,0,255,5,0,0,0,10,255, + 0,255,6,0,0,0,1,255,255,255,2,235,235,235,1,224,224,224,1,235, + 235,235,1,128,128,128,4,224,224,224,1,128,128,128,1,255,0,255,36,0, + 0,0,3,235,235,235,1,224,224,224,7,128,128,128,1,255,0,255,37,128, + 128,128,2,235,235,235,1,128,128,128,8,255,0,255,50,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,248,1,248,1,252,0,0,0,248, + 3,248,3,252,1,0,0,248,7,248,7,252,3,0,0,248,15,248,15,252, + 63,0,0,248,31,248,31,252,63,0,0,248,63,248,63,252,63,0,0,248, + 63,248,63,252,63,0,0,248,63,248,63,252,63,0,0,248,63,248,63,252, + 63,0,0,248,63,248,63,252,63,0,0,248,63,248,63,252,63,0,0,248, + 63,248,63,252,63,0,0,240,63,240,63,248,63,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,252, + 0,0,0,0,0,0,0,252,1,248,31,248,31,0,0,252,3,248,31,248, + 31,0,0,252,63,248,31,248,31,0,0,252,63,248,31,248,31,0,0,252, + 63,248,31,248,31,0,0,252,63,248,31,248,31,0,0,252,63,248,31,248, + 31,0,0,252,63,248,31,248,31,0,0,252,63,248,31,248,31,0,0,252, + 63,248,31,248,31,0,0,252,63,0,0,0,0,0,0,248,63,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,252,0,0,0,248,1,252,0,252, + 1,0,0,248,1,252,0,252,3,0,0,252,15,254,7,252,7,0,0,252, + 31,254,15,252,15,0,0,252,31,254,15,252,63,0,0,252,31,254,127,252, + 63,0,0,252,31,254,127,252,63,0,0,252,31,254,63,252,63,0,0,252, + 31,254,31,252,63,0,0,248,31,252,15,252,63,0,0,0,0,0,0,252, + 63,0,0,0,0,0,0,248,63,0,0,0,0,0,0,0,0,0,0,0, + 0,10,116,105,109,97,103,101,108,105,115,116,10,100,117,109,109,121,105,109, + 97,103,101,5,119,105,100,116,104,2,0,6,104,101,105,103,104,116,2,0, + 4,108,101,102,116,3,144,0,3,116,111,112,3,144,0,0,0,7,116,97, + 99,116,105,111,110,10,101,100,105,116,100,105,114,97,99,116,7,99,97,112, + 116,105,111,110,6,22,69,100,105,116,32,68,105,114,101,99,116,111,114,121, + 32,67,97,112,116,105,111,110,9,111,110,101,120,101,99,117,116,101,7,10, + 101,100,105,116,100,105,114,101,120,101,8,111,110,117,112,100,97,116,101,7, + 15,117,100,97,116,101,101,100,105,116,100,105,114,101,120,101,3,116,111,112, + 3,136,0,0,0,16,116,115,116,114,105,110,103,99,111,110,116,97,105,110, + 101,114,1,99,12,115,116,114,105,110,103,115,46,100,97,116,97,1,6,12, + 80,97,115,99,97,108,32,85,110,105,116,115,6,9,67,32,77,111,100,117, + 108,101,115,6,10,84,101,120,116,32,70,105,108,101,115,6,23,68,111,32, + 121,111,117,32,119,105,115,104,32,116,111,32,114,101,109,111,118,101,32,34, + 6,16,83,101,108,101,99,116,32,68,105,114,101,99,116,111,114,121,6,21, + 68,111,32,121,111,117,32,119,97,110,116,32,116,111,32,114,101,109,111,118, + 101,6,32,119,105,116,104,32,116,104,101,32,115,117,98,45,105,116,101,109, + 115,32,102,114,111,109,32,112,114,111,106,101,99,116,63,0,4,108,101,102, + 116,3,208,0,3,116,111,112,3,168,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tprojecttreefo,''); +end. diff --git a/mseide-msegui/apps/ide/replacedialogform.mfm b/mseide-msegui/apps/ide/replacedialogform.mfm new file mode 100644 index 0000000..42a9564 --- /dev/null +++ b/mseide-msegui/apps/ide/replacedialogform.mfm @@ -0,0 +1,167 @@ +object replacedialogfo: treplacedialogfo + visible = False + bounds_x = 142 + bounds_y = 302 + bounds_cx = 427 + bounds_cy = 163 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 427 + 163 + ) + options = [fo_freeonclose, fo_closeonesc, fo_localshortcuts, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder] + statfile = statfile1 + caption = 'Find and Replace Text' + moduleclassname = 'tmseform' + object findtext: thistoryedit + frame.caption = 'Text to &find' + frame.localprops = [] + frame.localprops1 = [] + frame.button.color = -2147483646 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + bounds_x = 8 + bounds_y = 7 + bounds_cx = 410 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + reffontheight = 14 + end + object replacetext: thistoryedit + frame.caption = '&Replace with' + frame.localprops = [] + frame.localprops1 = [] + frame.button.color = -2147483646 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + bounds_x = 8 + bounds_y = 47 + bounds_cx = 410 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + statfile = statfile1 + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + reffontheight = 14 + end + object casesensitive: tbooleanedit + frame.caption = '&casesensitive' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 88 + 2 + ) + taborder = 2 + bounds_x = 8 + bounds_y = 96 + bounds_cx = 101 + bounds_cy = 16 + end + object wholeword: tbooleanedit + frame.caption = '&whole word' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 73 + 2 + ) + taborder = 3 + bounds_x = 112 + bounds_y = 96 + bounds_cx = 86 + bounds_cy = 16 + end + object tintegerbutton1: tbutton + taborder = 6 + bounds_x = 8 + bounds_y = 123 + bounds_cx = 74 + bounds_cy = 20 + state = [as_localcaption] + caption = '&Replace' + modalresult = mr_ok + end + object tintegerbutton2: tbutton + taborder = 7 + bounds_x = 88 + bounds_y = 123 + bounds_cx = 74 + bounds_cy = 20 + state = [as_localcaption] + caption = 'Replace &all' + modalresult = mr_all + end + object selectedonly: tbooleanedit + frame.caption = 'select&ed only' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 86 + 2 + ) + taborder = 4 + bounds_x = 208 + bounds_y = 96 + bounds_cx = 99 + bounds_cy = 16 + statfile = statfile1 + end + object tintegerbutton3: tbutton + taborder = 8 + bounds_x = 168 + bounds_y = 123 + bounds_cx = 74 + bounds_cy = 20 + state = [as_default, as_localdefault, as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + end + object promptonreplace: tbooleanedit + frame.caption = '&prompt on rep.' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 97 + 2 + ) + taborder = 5 + bounds_x = 312 + bounds_y = 96 + bounds_cx = 110 + bounds_cy = 16 + statfile = statfile1 + value = True + end + object statfile1: tstatfile + filename = 'replacedialogfo.sta' + options = [sfo_memory] + left = 112 + end +end diff --git a/mseide-msegui/apps/ide/replacedialogform.pas b/mseide-msegui/apps/ide/replacedialogform.pas new file mode 100644 index 0000000..56dbb79 --- /dev/null +++ b/mseide-msegui/apps/ide/replacedialogform.pas @@ -0,0 +1,93 @@ +{ MSEide Copyright (c) 1999-2006 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit replacedialogform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseguiglob,msegui,mseclasses,mseforms,msegraphedits,msedataedits,msesimplewidgets, + msestat,msestatfile,mseglob, + projectoptionsform; + +type + treplacedialogfo = class(tmseform) + casesensitive: tbooleanedit; + findtext: thistoryedit; + replacetext: thistoryedit; + selectedonly: tbooleanedit; + statfile1: tstatfile; + promptonreplace: tbooleanedit; + tintegerbutton1: tbutton; + tintegerbutton2: tbutton; + tintegerbutton3: tbutton; + wholeword: tbooleanedit; + private + procedure valuestoinfo(out info: replaceinfoty); + procedure infotovalues(const info: replaceinfoty); + end; + +function replacedialogexecute(var info: replaceinfoty): modalresultty; + +implementation +uses + replacedialogform_mfm,msestrings; + +function replacedialogexecute(var info: replaceinfoty): modalresultty; +var + fo: treplacedialogfo; +begin + fo:= treplacedialogfo.create(nil); + try + fo.infotovalues(info); + result:= fo.show(true,nil); + if result in [mr_ok,mr_all] then begin + fo.valuestoinfo(info); + end; + finally + fo.Free; + end; +end; + +{ treplacedialogfo } + +procedure treplacedialogfo.valuestoinfo(out info: replaceinfoty); +begin +{$warnings off} + with info.find do begin + text:= findtext.value; + history:= findtext.dropdown.valuelist.asarray; + options:= encodesearchoptions(not casesensitive.value,wholeword.value); + selectedonly:= self.selectedonly.value; + end; + info.prompt:= promptonreplace.value; + info.replacetext:= replacetext.value; +end; +{$warnings on} + +procedure treplacedialogfo.infotovalues(const info: replaceinfoty); +begin + with info.find do begin + findtext.value:= text; + findtext.dropdown.valuelist.asarray:= history; + casesensitive.value:= not (so_caseinsensitive in options); + wholeword.value:= so_wholeword in options; +// self.selectedonly.value:= selectedonly; + end; +end; + +end. diff --git a/mseide-msegui/apps/ide/replacedialogform_mfm.pas b/mseide-msegui/apps/ide/replacedialogform_mfm.pas new file mode 100644 index 0000000..09f75bb --- /dev/null +++ b/mseide-msegui/apps/ide/replacedialogform_mfm.pas @@ -0,0 +1,133 @@ +unit replacedialogform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,replacedialogform; + +const + objdata: record size: integer; data: array[0..2303] of byte end = + (size: 2304; data: ( + 84,80,70,48,16,116,114,101,112,108,97,99,101,100,105,97,108,111,103,102, + 111,15,114,101,112,108,97,99,101,100,105,97,108,111,103,102,111,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,142,0,8,98, + 111,117,110,100,115,95,121,3,46,1,9,98,111,117,110,100,115,95,99,120, + 3,171,1,9,98,111,117,110,100,115,95,99,121,3,163,0,26,99,111,110, + 116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,0,27,99,111,110,116,97,105,110,101,114,46,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,99,111,110,116, + 97,105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0,3,171,1, + 3,163,0,0,7,111,112,116,105,111,110,115,11,14,102,111,95,102,114,101, + 101,111,110,99,108,111,115,101,13,102,111,95,99,108,111,115,101,111,110,101, + 115,99,17,102,111,95,108,111,99,97,108,115,104,111,114,116,99,117,116,115, + 15,102,111,95,97,117,116,111,114,101,97,100,115,116,97,116,16,102,111,95, + 97,117,116,111,119,114,105,116,101,115,116,97,116,10,102,111,95,115,97,118, + 101,112,111,115,13,102,111,95,115,97,118,101,122,111,114,100,101,114,0,8, + 115,116,97,116,102,105,108,101,7,9,115,116,97,116,102,105,108,101,49,7, + 99,97,112,116,105,111,110,6,21,70,105,110,100,32,97,110,100,32,82,101, + 112,108,97,99,101,32,84,101,120,116,15,109,111,100,117,108,101,99,108,97, + 115,115,110,97,109,101,6,8,116,109,115,101,102,111,114,109,0,12,116,104, + 105,115,116,111,114,121,101,100,105,116,8,102,105,110,100,116,101,120,116,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,13,84,101,120,116,32, + 116,111,32,38,102,105,110,100,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,18,102,114,97,109,101,46,98,117,116,116,111,110, + 46,99,111,108,111,114,4,2,0,0,128,16,102,114,97,109,101,46,111,117, + 116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,98, + 111,117,110,100,115,95,120,2,8,8,98,111,117,110,100,115,95,121,2,7, + 9,98,111,117,110,100,115,95,99,120,3,154,1,9,98,111,117,110,100,115, + 95,99,121,2,37,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101, + 102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,19, + 100,114,111,112,100,111,119,110,46,99,111,108,115,46,99,111,117,110,116,2, + 1,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,105,116,101,109, + 115,14,1,0,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,0,12,116,104,105,115,116,111,114,121,101,100,105,116,11,114,101,112, + 108,97,99,101,116,101,120,116,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,13,38,82,101,112,108,97,99,101,32,119,105,116,104,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,18,102,114,97, + 109,101,46,98,117,116,116,111,110,46,99,111,108,111,114,4,2,0,0,128, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,1,8,98, + 111,117,110,100,115,95,120,2,8,8,98,111,117,110,100,115,95,121,2,47, + 9,98,111,117,110,100,115,95,99,120,3,154,1,9,98,111,117,110,100,115, + 95,99,121,2,37,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101, + 102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,8, + 115,116,97,116,102,105,108,101,7,9,115,116,97,116,102,105,108,101,49,19, + 100,114,111,112,100,111,119,110,46,99,111,108,115,46,99,111,117,110,116,2, + 1,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,105,116,101,109, + 115,14,1,0,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,13,99,97,115, + 101,115,101,110,115,105,116,105,118,101,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,14,38,99,97,115,101,115,101,110,115,105,116,105,118,101, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2, + 1,2,88,2,2,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111, + 117,110,100,115,95,120,2,8,8,98,111,117,110,100,115,95,121,2,96,9, + 98,111,117,110,100,115,95,99,120,2,101,9,98,111,117,110,100,115,95,99, + 121,2,16,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,9,119, + 104,111,108,101,119,111,114,100,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,11,38,119,104,111,108,101,32,119,111,114,100,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101, + 46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,2,73,2,2, + 0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117,110,100,115,95, + 120,2,112,8,98,111,117,110,100,115,95,121,2,96,9,98,111,117,110,100, + 115,95,99,120,2,86,9,98,111,117,110,100,115,95,99,121,2,16,0,0, + 7,116,98,117,116,116,111,110,15,116,105,110,116,101,103,101,114,98,117,116, + 116,111,110,49,8,116,97,98,111,114,100,101,114,2,6,8,98,111,117,110, + 100,115,95,120,2,8,8,98,111,117,110,100,115,95,121,2,123,9,98,111, + 117,110,100,115,95,99,120,2,74,9,98,111,117,110,100,115,95,99,121,2, + 20,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112, + 116,105,111,110,0,7,99,97,112,116,105,111,110,6,8,38,82,101,112,108, + 97,99,101,11,109,111,100,97,108,114,101,115,117,108,116,7,5,109,114,95, + 111,107,0,0,7,116,98,117,116,116,111,110,15,116,105,110,116,101,103,101, + 114,98,117,116,116,111,110,50,8,116,97,98,111,114,100,101,114,2,7,8, + 98,111,117,110,100,115,95,120,2,88,8,98,111,117,110,100,115,95,121,2, + 123,9,98,111,117,110,100,115,95,99,120,2,74,9,98,111,117,110,100,115, + 95,99,121,2,20,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,12,82, + 101,112,108,97,99,101,32,38,97,108,108,11,109,111,100,97,108,114,101,115, + 117,108,116,7,6,109,114,95,97,108,108,0,0,12,116,98,111,111,108,101, + 97,110,101,100,105,116,12,115,101,108,101,99,116,101,100,111,110,108,121,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,14,115,101,108,101,99, + 116,38,101,100,32,111,110,108,121,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,1,2,86,2,2,0,8,116,97,98,111, + 114,100,101,114,2,4,8,98,111,117,110,100,115,95,120,3,208,0,8,98, + 111,117,110,100,115,95,121,2,96,9,98,111,117,110,100,115,95,99,120,2, + 99,9,98,111,117,110,100,115,95,99,121,2,16,8,115,116,97,116,102,105, + 108,101,7,9,115,116,97,116,102,105,108,101,49,0,0,7,116,98,117,116, + 116,111,110,15,116,105,110,116,101,103,101,114,98,117,116,116,111,110,51,8, + 116,97,98,111,114,100,101,114,2,8,8,98,111,117,110,100,115,95,120,3, + 168,0,8,98,111,117,110,100,115,95,121,2,123,9,98,111,117,110,100,115, + 95,99,120,2,74,9,98,111,117,110,100,115,95,99,121,2,20,5,115,116, + 97,116,101,11,10,97,115,95,100,101,102,97,117,108,116,15,97,115,95,108, + 111,99,97,108,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,7,38,67, + 97,110,99,101,108,11,109,111,100,97,108,114,101,115,117,108,116,7,9,109, + 114,95,99,97,110,99,101,108,0,0,12,116,98,111,111,108,101,97,110,101, + 100,105,116,15,112,114,111,109,112,116,111,110,114,101,112,108,97,99,101,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,15,38,112,114,111,109, + 112,116,32,111,110,32,114,101,112,46,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101, + 114,102,114,97,109,101,1,2,0,2,1,2,97,2,2,0,8,116,97,98, + 111,114,100,101,114,2,5,8,98,111,117,110,100,115,95,120,3,56,1,8, + 98,111,117,110,100,115,95,121,2,96,9,98,111,117,110,100,115,95,99,120, + 2,110,9,98,111,117,110,100,115,95,99,121,2,16,8,115,116,97,116,102, + 105,108,101,7,9,115,116,97,116,102,105,108,101,49,5,118,97,108,117,101, + 9,0,0,9,116,115,116,97,116,102,105,108,101,9,115,116,97,116,102,105, + 108,101,49,8,102,105,108,101,110,97,109,101,6,19,114,101,112,108,97,99, + 101,100,105,97,108,111,103,102,111,46,115,116,97,7,111,112,116,105,111,110, + 115,11,10,115,102,111,95,109,101,109,111,114,121,0,4,108,101,102,116,2, + 112,0,0,0) + ); + +initialization + registerobjectdata(@objdata,treplacedialogfo,''); +end. diff --git a/mseide-msegui/apps/ide/reportdesigner.mfm b/mseide-msegui/apps/ide/reportdesigner.mfm new file mode 100644 index 0000000..a18f1b4 --- /dev/null +++ b/mseide-msegui/apps/ide/reportdesigner.mfm @@ -0,0 +1,459 @@ +inherited reportdesignerfo: treportdesignerfo + bounds_x = 198 + bounds_y = 137 + bounds_cx = 343 + bounds_cy = 459 + container.color = -1879048185 + container.onlayout = repchildscaled + container.oncalcminscrollsize = nil + container.onchildmouseevent = reportchildmouseevent + container.bounds = ( + 0 + 0 + 343 + 459 + ) + onclose = nil + onresize = formresized + onlayout = repchildscaled + moduleclassname = 'Tformdesignerfo' + object dialh: tdial[0] + color = -1879048185 + frame.localprops = [frl_fileft] + frame.localprops1 = [] + taborder = 4 + bounds_x = 7 + bounds_y = 19 + bounds_cx = 336 + bounds_cy = 7 + anchors = [an_left, an_top, an_right] + dial.options = [] + dial.widthmm = 0.3 + dial.start = 0 + dial.range = 100 + dial.markers.count = 1 + dial.markers.items = < + item + color = -1610612729 + widthmm = 0 + escapement = 0 + value = -Inf + end> + dial.ticks.count = 3 + dial.ticks.items = < + item + widthmm = 0 + escapement = 0 + intervalcount = 10 + end + item + color = -1610612733 + widthmm = 0 + length = 6 + escapement = 0 + intervalcount = 20 + end + item + color = -1610612733 + widthmm = 0 + length = 3 + escapement = 0 + intervalcount = 100 + end> + dial.angle = 0 + end + object tabbar: ttabbar[1] + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autoheight] + optionswidget = [ow_mousewheel, ow_destroywidgets] + color = -1879048187 + frame.localprops = [] + frame.localprops1 = [] + bounds_x = 120 + bounds_y = 0 + bounds_cx = 221 + bounds_cy = 19 + anchors = [an_left, an_top, an_right] + onactivetabchange = tabcha + ontabmoving = tabmo + onclientmouseevent = tabmouse + options = [tabo_dragsource, tabo_dragdest] + reffontheight = 14 + end + object reportcontainer: tscrollbox[2] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_mousewheel, ow_destroywidgets] + color = -1879048187 + frame.optionsscroll = [oscr_drag, oscr_key, oscr_mousewheel] + frame.colorclient = -1610612730 + frame.localprops = [frl_colorclient] + frame.localprops1 = [] + taborder = 1 + bounds_x = 7 + bounds_y = 26 + bounds_cx = 335 + bounds_cy = 433 + anchors = [an_left, an_top, an_right, an_bottom] + onlayout = repcomtainerchildscaled + onscrolled = reportcontainerscrolled + end + object tspacer1: tspacer[3] + taborder = 2 + bounds_x = 144 + bounds_y = 19 + bounds_cx = 50 + bounds_cy = 5 + linktop = tabbar + linkbottom = dialh + dist_bottom = -5 + end + object dialv: tdial[4] + color = -1879048185 + taborder = 3 + bounds_x = 0 + bounds_y = 26 + bounds_cx = 7 + bounds_cy = 433 + anchors = [an_left, an_top, an_bottom] + dial.widthmm = 0.3 + dial.direction = gd_down + dial.start = 0 + dial.range = 100 + dial.markers.count = 1 + dial.markers.items = < + item + color = -1610612729 + widthmm = 0 + escapement = 0 + value = -Inf + end> + dial.ticks.count = 3 + dial.ticks.items = < + item + widthmm = 0 + escapement = 0 + intervalcount = 10 + end + item + color = -1610612733 + widthmm = 0 + length = 6 + escapement = 0 + intervalcount = 20 + end + item + color = -1610612733 + widthmm = 0 + length = 4 + escapement = 0 + intervalcount = 100 + end> + dial.angle = 0 + end + object tspacer2: tspacer[5] + taborder = 5 + bounds_x = 144 + bounds_y = 26 + bounds_cx = 50 + bounds_cy = 5 + linktop = dialh + linkbottom = reportcontainer + dist_bottom = -5 + end + object tspacer3: tspacer[6] + taborder = 6 + bounds_x = 7 + bounds_y = 173 + bounds_cx = 5 + bounds_cy = 50 + linkleft = dialv + linkright = reportcontainer + dist_right = -5 + end + object xdisp: trealdisp[7] + color = -1879048187 + frame.localprops = [] + frame.localprops1 = [] + taborder = 7 + bounds_x = 52 + bounds_y = 0 + bounds_cx = 68 + bounds_cy = 18 + textflags = [tf_ycentered] + valuerange = 1 + valuestart = 0 + format = '0.0mm' + value = -Inf + reffontheight = 14 + end + object ydisp: trealdisp[8] + color = -1879048187 + frame.localprops = [] + frame.localprops1 = [] + taborder = 8 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 52 + bounds_cy = 18 + valuerange = 1 + valuestart = 0 + format = '0.0' + value = -Inf + reffontheight = 14 + end + object tspacer4: tspacer[9] + taborder = 9 + bounds_x = 16 + bounds_y = 26 + bounds_cx = 50 + bounds_cy = 5 + linktop = dialh + linkbottom = dialv + dist_bottom = -5 + end + inherited popupme: tpopupmenu[10] + menu.submenu.items = < + item + end + item + end + item + end + item + end + item + state = [as_localonexecute] + end + item + state = [as_localdisabled, as_localinvisible, as_localonexecute] + end + item + state = [as_localinvisible, as_localonexecute] + end + item + state = [as_localinvisible, as_localonexecute] + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end> + end + inherited hidecompact: taction[11] + end + inherited hidewidgetact: taction[12] + state = [as_disabled, as_invisible] + end + inherited togglehideact: taction[13] + end + inherited showallact: taction[14] + end + object tpopupmenu3: tpopupmenu[15] + menu.submenu.count = 29 + menu.submenu.items = < + item + caption = 'Show objectinspector' + state = [as_localcaption, as_localonexecute] + end + item + caption = 'Show componentpalette' + state = [as_localcaption, as_localonexecute] + end + item + caption = 'Show as Text' + state = [as_localcaption, as_localonexecute] + options = [mao_shortcutcaption, mao_asyncexecute] + end + item + action = formdesignerfo.hidecompact + options = [mao_separator, mao_shortcutcaption] + end + item + action = formdesignerfo.hidewidgetact + options = [mao_checkbox, mao_shortcutcaption] + end + item + action = hidewidgetact + state = [as_disabled, as_invisible] + options = [mao_checkbox, mao_shortcutcaption] + end + item + action = togglehideact + end + item + action = showallact + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = 'Copy Component(s)' + name = 'copy' + state = [as_localcaption, as_localshortcut, as_localonexecute] + sc = ( + 1 + 16451 + ) + end + item + caption = 'Cut Component(s)' + name = 'cut' + state = [as_localcaption, as_localshortcut, as_localonexecute] + options = [mao_shortcutcaption, mao_asyncexecute] + sc = ( + 1 + 16472 + ) + end + item + caption = 'Paste Component(s)' + name = 'paste' + state = [as_localcaption, as_localshortcut, as_localonexecute] + sc = ( + 1 + 16470 + ) + end + item + caption = 'Delete Component(s)' + name = 'delete' + state = [as_localcaption, as_localshortcut, as_localonexecute] + options = [mao_shortcutcaption, mao_asyncexecute] + sc = ( + 1 + 263 + ) + end + item + caption = 'Undelete Component(s)' + name = 'undelete' + state = [as_localcaption, as_localonexecute] + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = 'Select Childwidget' + name = 'selectchild' + state = [as_localcaption] + end + item + caption = 'Edit Component' + name = 'editcomp' + state = [as_localcaption, as_localonexecute] + end + item + caption = 'Bring to Front' + name = 'bringtofro' + state = [as_localcaption, as_localonexecute] + end + item + caption = 'Send to Back' + name = 'sendtoba' + state = [as_localcaption, as_localonexecute] + end + item + caption = 'Iconify' + name = 'iconify' + state = [as_localcaption, as_localonexecute] + end + item + caption = 'Deiconify' + name = 'deiconify' + state = [as_localcaption, as_localonexecute] + end + item + caption = 'Set Tab Order' + name = 'settabord' + state = [as_localcaption, as_localonexecute] + end + item + caption = 'Set Creation Order' + state = [as_localcaption, as_localonexecute] + end + item + caption = 'Sync. to Font Height' + name = 'synctofo' + state = [as_localcaption, as_localonexecute] + end + item + caption = 'Revert to inherited' + name = 'revert' + state = [as_localcaption, as_localonexecute] + options = [mao_shortcutcaption, mao_asyncexecute] + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = 'Touch Form' + state = [as_localcaption, as_localonexecute] + options = [mao_separator, mao_shortcutcaption] + end + item + caption = 'Add report page' + name = 'addpage' + state = [as_localcaption, as_localonexecute] + end + item + caption = 'Delete report page' + name = 'delpage' + state = [as_localcaption, as_localonexecute] + end> + left = 16 + top = 160 + end + inherited c: tstringcontainer[16] + end + object sc: tstringcontainer[17] + strings.data = ( + 'Do you wish to delete' + 'WARNING' + ) + left = 64 + top = 208 + end +end diff --git a/mseide-msegui/apps/ide/reportdesigner.pas b/mseide-msegui/apps/ide/reportdesigner.pas new file mode 100644 index 0000000..432c98c --- /dev/null +++ b/mseide-msegui/apps/ide/reportdesigner.pas @@ -0,0 +1,630 @@ +{ MSEide Copyright (c) 1999-2014 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit reportdesigner; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,msegui,mseclasses,mseforms,formdesigner,msesimplewidgets, + msetabs,msesplitter,msegraphutils,msedesigner,msedesignintf,msereport,msetypes, + mseevent,mseglob,mseguiglob,msemenus,msedial,msedispwidgets,mseact, + msestringcontainer,msestrings,mseactions,mseificomp,mseificompglob,mseifiglob; + +const + updatetabtag = 83684; + +type + treportdesignerfo = class; + { + treportcontainer = class(tscrollbox) + protected + function isdesignwidget(): boolean; override; + public + constructor create(aowner: tcomponent); override; + end; + } + reportdesignerstatety = (rds_tabupdating,rds_mouseinclient); + reportdesignerstatesty = set of reportdesignerstatety; + + treportdesignerfo = class(tformdesignerfo) + dialh: tdial; + dialv: tdial; + tabbar: ttabbar; + reportcontainer: tscrollbox; + tspacer4: tspacer; + xdisp: trealdisp; + ydisp: trealdisp; + tspacer1: tspacer; + tspacer2: tspacer; + tspacer3: tspacer; + sc: tstringcontainer; + tpopupmenu3: tpopupmenu; + procedure repchildscaled(const sender: TObject); + procedure tabcha(const sender: TObject); + procedure tabmo(const sender: TObject; var curindex: Integer; + var newindex: Integer); + procedure tabmouse(const sender: twidget; var info: mouseeventinfoty); + procedure deletepage(const sender: TObject); + procedure popupupda(const sender: tcustommenu); + procedure addpage(const sender: TObject); + procedure formresized(const sender: TObject); + procedure reportchildmouseevent(const sender: twidget; + var info: mouseeventinfoty); + procedure reportcontainerscrolled(const sender: twidget; + const point: pointty); + procedure repcomtainerchildscaled(const sender: TObject); +// procedure updatewidgethideexe(const sender: tcustomaction); override; +// procedure repshowallexe(const sender: TObject); +// procedure reptoglehideexe(const sender: TObject); +// procedure rephidewidgetexe(const sender: TObject); + private +// freportcontainer: treportcontainer; + fstate: reportdesignerstatesty; + function ppmm: real; + protected + fisreppage: boolean; + procedure setmoduleoptions(const aoptions: moduleoptionsty); override; + function report: tcustomreport; + function reppage: treppageform; + function getdesigninfo(): prepdesigninfoty; + function getmoduleparent: twidget; override; + function markerrect(): rectty; override; + function getdesignrect(): rectty; override; + function getmodulesize(): sizety; override; + function gridrect(): rectty; override; + function insertoffset(): pointty; override; + function widgetrefpoint(): pointty; override; + function getgridsizex(): integer; override; + function getgridsizey(): integer; override; + function getshowgrid(): boolean; override; + function getsnaptogrid(): boolean; override; +// procedure poschanged(); override; +// procedure sizechanged(); override; + procedure checktabs(); + procedure updatetabs(); + procedure validaterename(acomponent: tcomponent; + const curname, newname: string); override; + procedure doasyncevent(var atag: integer); override; + procedure componentselected(const aselections: tformdesignerselections); + override; + procedure placecomponent(const component: tcomponent; const apos: pointty; + aparent: tcomponent = nil); override; + function fixformsize: boolean; override; +// function candelete(const acomponent: tcomponent): boolean; override; + function checkdelete(): boolean; override; + procedure componentmoving(const apos: pointty); override; + procedure updatedials; + procedure setmousemarkers(const avalue: pointty; const source: twidget); + public + constructor create(const aowner: tcomponent; const adesigner: tdesigner; + const aintf: pdesignmoduleintfty; + const amoduleinfo: pmoduleinfoty); override; + procedure placemodule(); override; + procedure beginstreaming(); override; + procedure endstreaming(); override; + end; + +var + reportdesignerfo: treportdesignerfo; + +implementation + +uses + reportdesigner_mfm,msearrayutils,msegraphics,msewidgets,msereal,sysutils; +type + tcustomreport1 = class(tcustomreport); + treppageform1 = class(treppageform); + twidget1 = class(twidget); + + stringconsts = ( + sc_wishdelete, //0 Do you wish to delete + sc_warning //1 WARNING + ); + +{ treportcontainer } +{ +constructor treportcontainer.create(aowner: tcomponent); +begin + inherited; + createframe; + frame.colorclient:= cl_white; + anchors:= [an_top,an_bottom]; +end; + +function treportcontainer.isdesignwidget: boolean; +begin + result:= true; +end; +} +{ treportdesignerfo } + +constructor treportdesignerfo.create(const aowner: tcomponent; + const adesigner: tdesigner; const aintf: pdesignmoduleintfty; + const amoduleinfo: pmoduleinfoty); +begin + fisreppage:= amoduleinfo^.instance is treppageform; + inherited; + include(twidget1(pointer(reportcontainer)).fwidgetstate1,ws1_designwidget); +end; + +function treportdesignerfo.fixformsize: boolean; +begin + result:= true; +end; + +function treportdesignerfo.getmoduleparent: twidget; +begin + result:= reportcontainer; +end; + +function treportdesignerfo.gridrect: rectty; +begin + if reportcontainer.visible then begin + with reportcontainer do begin + result:= intersectrect(inherited gridrect, + makerect(translatewidgetpoint(paintpos,reportcontainer,self),paintsize)); + end; + end + else begin + with reportcontainer do begin + result:= intersectrect(inherited gridrect, + makerect(translatewidgetpoint(pos,reportcontainer.parentwidget,self), + size)); + end; + end; +end; + +function treportdesignerfo.insertoffset: pointty; +begin +// result:= translateclientpoint(nullpoint,reportcontainer,self); + if fformcont.visible then begin + result:= translatewidgetpoint(reportcontainer.clientwidgetpos, + reportcontainer,self); +// result:= translatewidgetpoint(nullpoint,reportcontainer,self); + end + else begin + result:= inherited insertoffset; + end; +end; + +function treportdesignerfo.widgetrefpoint: pointty; +begin + if fformcont.visible then begin + result:= translatewidgetpoint(reportcontainer.pos, + reportcontainer.parentwidget,self); + addpoint1(result,reportcontainer.clientpos); + end + else begin + result:= inherited widgetrefpoint(); + end; +end; + +procedure treportdesignerfo.repchildscaled(const sender: TObject); +begin + ydisp.bounds_cx:= getcanvas.getstringwidth('999.9') + 8; + xdisp.bounds_cx:= getcanvas.getstringwidth('999.9mm') + 8; + placexorder(0,[],[ydisp,xdisp,tabbar],0); +end; + +procedure treportdesignerfo.checktabs; +var + int1: integer; +begin + if not fisreppage and (report <> nil) then begin + if report.reppagecount = 0 then begin + addpage(nil); + exit; + end; + tabbar.tabs.count:= report.reppagecount; + for int1:= 0 to tabbar.tabs.count - 1 do begin + tabbar.tabs[int1].caption:= msestring(report[int1].name); + end; + if (report.reppagecount > 0) then begin + if tabbar.activetab < 0 then begin + tabbar.activetab:= 0; + end + else begin + tabcha(nil); //possibly deleted page + end; + end; + end; +end; + +function treportdesignerfo.report: tcustomreport; +begin + if fisreppage then begin + raise exception.create('No report'); + end; + result:= tcustomreport(module); +end; + +function treportdesignerfo.reppage: treppageform; +begin + if not fisreppage then begin + raise exception.create('No reppageform'); + end; + result:= treppageform(module); +end; + +function treportdesignerfo.getdesigninfo(): prepdesigninfoty; +begin + if fisreppage then begin + result:= @treppageform1(module).frepdesigninfo; + end + else begin + result:= @tcustomreport1(module).frepdesigninfo; + end; +end; + +procedure treportdesignerfo.validaterename(acomponent: tcomponent; + const curname: string; const newname: string); +begin + inherited; + updatetabs; +end; + +procedure treportdesignerfo.doasyncevent(var atag: integer); +begin + if atag = updatetabtag then begin + exclude(fstate,rds_tabupdating); + checktabs; + end + else begin + inherited; + end; +end; + +procedure treportdesignerfo.updatetabs; +begin + if not (rds_tabupdating in fstate) then begin + include(fstate,rds_tabupdating); + asyncevent(updatetabtag); + end; +end; + +procedure treportdesignerfo.tabcha(const sender: TObject); +var + reppage1: tcustomreportpage; + int1: integer; +begin + if tabbar.activetab >= 0 then begin + for int1:= 0 to report.reppagecount - 1 do begin + report[int1].visible:= int1 = tabbar.activetab; + end; + reppage1:= report[tabbar.activetab]; + report.size:= reppage1.size; + reppage1.bringtofront; +// designer.selectcomponent(report); + end; +end; + +procedure treportdesignerfo.componentselected( + const aselections: tformdesignerselections); +var + int1,int2: integer; + widget1: twidget; +begin + if not fisreppage then begin + with tcustomreport1(report) do begin + for int1:= 0 to aselections.count-1 do begin + widget1:= twidget(aselections[int1]); + if widget1 is twidget then begin + for int2:= high(freppages) downto 0 do begin + if widget1.checkancestor(freppages[int2]) then begin + checktabs; + tabbar.activetab:= int2; + exit; + end; + end; + end; + end; + end; + end; +end; + +procedure treportdesignerfo.tabmo(const sender: TObject; var curindex: Integer; + var newindex: Integer); +begin + moveitem(pointerarty(tcustomreport1(report).freppages),curindex,newindex); +end; + +procedure treportdesignerfo.tabmouse(const sender: twidget; + var info: mouseeventinfoty); +begin + with info do begin + if (eventkind = ek_buttonpress) and (button = mb_left) then begin + designer.selectcomponent(module); + end; + end; +end; + +procedure treportdesignerfo.placemodule(); +begin + inherited; + with getdesigninfo^.widgetrect do begin + fmodulepos:= pos; + fmodulesize:= size; + end; +end; + +procedure treportdesignerfo.beginstreaming; +begin +// tcustomreport1(form).frepdesigninfo.widgetrect:= widgetrect; + with getdesigninfo^.widgetrect do begin + pos:= fmodulepos; + size:= fmodulesize; + end; +end; + +procedure treportdesignerfo.endstreaming; +begin + //dummy +end; + +function treportdesignerfo.getdesignrect: rectty; +begin + result:= getdesigninfo^.widgetrect; +end; + +function treportdesignerfo.getmodulesize: sizety; +begin + result:= getdesigninfo^.widgetrect.size; +end; + +procedure treportdesignerfo.popupupda(const sender: tcustommenu); +begin + popupme.menu.itembyname('delpage').enabled:= tabbar.activetab >= 0; +end; +{ +function treportdesignerfo.candelete(const acomponent: tcomponent): boolean; +var + int1: integer; +begin + result:= true; + with report do begin + for int1:= 0 to reppagecount - 1 do begin + if acomponent = reppages[int1] then begin + result:= false; + break; + end; + end; + end; +end; +} + +function treportdesignerfo.checkdelete(): boolean; +var + int1,int2: integer; + comp1: tcomponent; + pages: reportpagearty; + bo1: boolean; +begin + result:= false; + if inherited checkdelete() then begin + if not fisreppage then begin + pages:= tcustomreport1(report).freppages; + bo1:= false; + with fselections do begin + for int1:= 0 to count - 1 do begin + comp1:= items[int1]; + for int2:= 0 to high(pages) do begin + if pages[int2] = comp1 then begin + bo1:= true; + if not askok(sc[ord(sc_wishdelete)]+' '''+ + msestring(comp1.name)+'''?',sc[ord(sc_warning)],mr_cancel) then begin + exit; + end; + end; + end; + end; + end; + if bo1 then begin + updatetabs; + end; + end; + result:= true; + end; +end; + +procedure treportdesignerfo.addpage(const sender: TObject); +var + comp1: tcomponent; +begin + comp1:= designer.createnewcomponent(report,treportpage); + placecomponent(comp1,translatewidgetpoint(reportcontainer.pos, + reportcontainer.parentwidget,self),report); + updatetabs; +end; + +procedure treportdesignerfo.placecomponent(const component: tcomponent; + const apos: pointty; aparent: tcomponent = nil); +begin + if not fisreppage and (component is tcustomreportpage) then begin + inherited placecomponent(component, + translatewidgetpoint(reportcontainer.pos, + reportcontainer.parentwidget,self),report); + end + else begin + inherited; + end; +end; + +procedure treportdesignerfo.deletepage(const sender: TObject); +var + comp1: tcomponent; +begin + comp1:= report[tabbar.activetab]; + if askok(sc[ord(sc_wishdelete)]+' '''+msestring(comp1.name)+'''?', + sc[ord(sc_warning)],mr_cancel) then begin +// designer.deletecomponent(comp1); + deletecomponent(comp1); + updatetabs; + end; +end; + +function treportdesignerfo.getgridsizex: integer; +begin + result:= round(getdesigninfo^.gridsize * ppmm); + if result < 2 then begin + result:= 2; + end; +end; + +function treportdesignerfo.getgridsizey: integer; +begin + result:= gridsizex; +end; + +function treportdesignerfo.getshowgrid: boolean; +begin + result:= getdesigninfo^.showgrid; +end; + +function treportdesignerfo.getsnaptogrid: boolean; +begin + result:= getdesigninfo^.snaptogrid; +end; + +function treportdesignerfo.ppmm: real; +begin + if fisreppage then begin + if reppage = nil then begin + result:= 3; + end + else begin + result:= reppage.ppmm; + end; + end + else begin + if report = nil then begin + result:= 3; + end + else begin + result:= report.ppmm; + end; + end; +end; + +procedure treportdesignerfo.setmousemarkers(const avalue: pointty; + const source: twidget); +var + pt1: pointty; +begin + pt1:= translatewidgetpoint(avalue,source,reportcontainer); + xdisp.value:= pt1.x/ppmm + dialh.dial.start; + dialh.dial.markers[0].value:= xdisp.value; + ydisp.value:= pt1.y/ppmm + dialv.dial.start; + dialv.dial.markers[0].value:= ydisp.value; +end; + +procedure treportdesignerfo.reportchildmouseevent(const sender: twidget; + var info: mouseeventinfoty); +//var +// pt1: pointty; +begin + with info do begin + case eventkind of + ek_mouseleave: begin + exclude(fstate,rds_mouseinclient); + xdisp.value:= emptyreal; + ydisp.value:= emptyreal; + dialh.dial.markers[0].value:= emptyreal; + dialv.dial.markers[0].value:= emptyreal; + end; + ek_mouseenter: begin + include(fstate,rds_mouseinclient); + end; + ek_buttonpress: begin + if (button = mb_left) and (ss_double in shiftstate) and + not reportcontainer.checkdescendent(sender) then begin + designer.showobjectinspector; + include(eventstate,es_processed); + end; + end; + end; + if (eventkind in mouseposevents) and (rds_mouseinclient in fstate) then begin + setmousemarkers(pos,sender); + end; + end; +end; + +procedure treportdesignerfo.updatedials; + procedure adjustticks(const adial: tcustomdialcontroller); + begin + with adial do begin + ticks[0].intervalcount:= range/10.0; + ticks[1].intervalcount:= range/5.0; + ticks[2].intervalcount:= range/1.0; + end; + end; +begin + if dialh.bounds_cx > 0 then begin + dialh.dial.range:= dialh.bounds_cx / ppmm; //mm + end; + if dialv.bounds_cy > 0 then begin + dialv.dial.range:= dialv.bounds_cy / ppmm; //mm + end; + dialh.dial.start:= -reportcontainer.clientpos.x / ppmm; + dialv.dial.start:= -reportcontainer.clientpos.y / ppmm; + adjustticks(dialh.dial); + adjustticks(dialv.dial); +end; + +procedure treportdesignerfo.formresized(const sender: TObject); +begin + updatedials; +end; + +procedure treportdesignerfo.reportcontainerscrolled(const sender: twidget; + const point: pointty); +begin + updatedials; + formcontainerscrolled; +end; + +procedure treportdesignerfo.repcomtainerchildscaled(const sender: TObject); +begin + updatedials; +end; + +procedure treportdesignerfo.componentmoving(const apos: pointty); +begin + setmousemarkers(apos,self); +end; + +procedure treportdesignerfo.setmoduleoptions(const aoptions: moduleoptionsty); +begin + inherited; + if mo_hidewidgets in aoptions then begin + reportcontainer.visible:= false; + end + else begin + reportcontainer.visible:= true; + fscrollbox.visible:= true; + fscrollbox.bringtofront(); + end; +end; + +function treportdesignerfo.markerrect(): rectty; +begin + result:= inherited markerrect(); + intersectrect1(result,mr( + translatewidgetpoint(reportcontainer.paintpos,reportcontainer,self), + reportcontainer.paintsize)); +end; + +end. + diff --git a/mseide-msegui/apps/ide/reportdesigner_mfm.pas b/mseide-msegui/apps/ide/reportdesigner_mfm.pas new file mode 100644 index 0000000..6da1476 --- /dev/null +++ b/mseide-msegui/apps/ide/reportdesigner_mfm.pas @@ -0,0 +1,330 @@ +unit reportdesigner_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,reportdesigner; + +const + objdata: record size: integer; data: array[0..6258] of byte end = + (size: 6259; data: ( + 84,80,70,48,241,17,116,114,101,112,111,114,116,100,101,115,105,103,110,101, + 114,102,111,16,114,101,112,111,114,116,100,101,115,105,103,110,101,114,102,111, + 8,98,111,117,110,100,115,95,120,3,198,0,8,98,111,117,110,100,115,95, + 121,3,137,0,9,98,111,117,110,100,115,95,99,120,3,87,1,9,98,111, + 117,110,100,115,95,99,121,3,203,1,15,99,111,110,116,97,105,110,101,114, + 46,99,111,108,111,114,4,7,0,0,144,18,99,111,110,116,97,105,110,101, + 114,46,111,110,108,97,121,111,117,116,7,14,114,101,112,99,104,105,108,100, + 115,99,97,108,101,100,29,99,111,110,116,97,105,110,101,114,46,111,110,99, + 97,108,99,109,105,110,115,99,114,111,108,108,115,105,122,101,13,27,99,111, + 110,116,97,105,110,101,114,46,111,110,99,104,105,108,100,109,111,117,115,101, + 101,118,101,110,116,7,21,114,101,112,111,114,116,99,104,105,108,100,109,111, + 117,115,101,101,118,101,110,116,16,99,111,110,116,97,105,110,101,114,46,98, + 111,117,110,100,115,1,2,0,2,0,3,87,1,3,203,1,0,7,111,110, + 99,108,111,115,101,13,8,111,110,114,101,115,105,122,101,7,11,102,111,114, + 109,114,101,115,105,122,101,100,8,111,110,108,97,121,111,117,116,7,14,114, + 101,112,99,104,105,108,100,115,99,97,108,101,100,15,109,111,100,117,108,101, + 99,108,97,115,115,110,97,109,101,6,15,84,102,111,114,109,100,101,115,105, + 103,110,101,114,102,111,0,242,2,0,5,116,100,105,97,108,5,100,105,97, + 108,104,5,99,111,108,111,114,4,7,0,0,144,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,102,105,108,101, + 102,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,8,116,97,98,111,114,100,101,114,2,4,8,98,111,117,110,100, + 115,95,120,2,7,8,98,111,117,110,100,115,95,121,2,19,9,98,111,117, + 110,100,115,95,99,120,3,80,1,9,98,111,117,110,100,115,95,99,121,2, + 7,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97, + 110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,12,100,105,97,108, + 46,111,112,116,105,111,110,115,11,0,12,100,105,97,108,46,119,105,100,116, + 104,109,109,5,154,153,153,153,153,153,153,153,253,63,10,100,105,97,108,46, + 115,116,97,114,116,2,0,10,100,105,97,108,46,114,97,110,103,101,2,100, + 18,100,105,97,108,46,109,97,114,107,101,114,115,46,99,111,117,110,116,2, + 1,18,100,105,97,108,46,109,97,114,107,101,114,115,46,105,116,101,109,115, + 14,1,5,99,111,108,111,114,4,7,0,0,160,7,119,105,100,116,104,109, + 109,2,0,10,101,115,99,97,112,101,109,101,110,116,2,0,5,118,97,108, + 117,101,5,0,0,0,0,0,0,0,128,255,255,0,0,16,100,105,97,108, + 46,116,105,99,107,115,46,99,111,117,110,116,2,3,16,100,105,97,108,46, + 116,105,99,107,115,46,105,116,101,109,115,14,1,7,119,105,100,116,104,109, + 109,2,0,10,101,115,99,97,112,101,109,101,110,116,2,0,13,105,110,116, + 101,114,118,97,108,99,111,117,110,116,2,10,0,1,5,99,111,108,111,114, + 4,3,0,0,160,7,119,105,100,116,104,109,109,2,0,6,108,101,110,103, + 116,104,2,6,10,101,115,99,97,112,101,109,101,110,116,2,0,13,105,110, + 116,101,114,118,97,108,99,111,117,110,116,2,20,0,1,5,99,111,108,111, + 114,4,3,0,0,160,7,119,105,100,116,104,109,109,2,0,6,108,101,110, + 103,116,104,2,3,10,101,115,99,97,112,101,109,101,110,116,2,0,13,105, + 110,116,101,114,118,97,108,99,111,117,110,116,2,100,0,0,10,100,105,97, + 108,46,97,110,103,108,101,2,0,0,0,242,2,1,7,116,116,97,98,98, + 97,114,6,116,97,98,98,97,114,14,111,112,116,105,111,110,115,119,105,100, + 103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104, + 101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99,97,108,101,14, + 111,119,49,95,97,117,116,111,104,101,105,103,104,116,0,13,111,112,116,105, + 111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,119, + 104,101,101,108,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,0,5,99,111,108,111,114,4,5,0,0,144,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,8,98,111,117,110,100,115, + 95,120,2,120,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,120,3,221,0,9,98,111,117,110,100,115,95,99,121,2,19, + 7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110, + 95,116,111,112,8,97,110,95,114,105,103,104,116,0,17,111,110,97,99,116, + 105,118,101,116,97,98,99,104,97,110,103,101,7,6,116,97,98,99,104,97, + 11,111,110,116,97,98,109,111,118,105,110,103,7,5,116,97,98,109,111,18, + 111,110,99,108,105,101,110,116,109,111,117,115,101,101,118,101,110,116,7,8, + 116,97,98,109,111,117,115,101,7,111,112,116,105,111,110,115,11,15,116,97, + 98,111,95,100,114,97,103,115,111,117,114,99,101,13,116,97,98,111,95,100, + 114,97,103,100,101,115,116,0,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,14,0,0,242,2,2,10,116,115,99,114,111,108,108,98,111,120, + 15,114,101,112,111,114,116,99,111,110,116,97,105,110,101,114,13,111,112,116, + 105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101, + 102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119, + 95,97,114,114,111,119,102,111,99,117,115,13,111,119,95,109,111,117,115,101, + 119,104,101,101,108,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,5,99,111,108,111,114,4,5,0,0,144,19,102,114,97,109, + 101,46,111,112,116,105,111,110,115,115,99,114,111,108,108,11,9,111,115,99, + 114,95,100,114,97,103,8,111,115,99,114,95,107,101,121,15,111,115,99,114, + 95,109,111,117,115,101,119,104,101,101,108,0,17,102,114,97,109,101,46,99, + 111,108,111,114,99,108,105,101,110,116,4,6,0,0,160,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,15,102,114,108,95,99,111, + 108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2, + 1,8,98,111,117,110,100,115,95,120,2,7,8,98,111,117,110,100,115,95, + 121,2,26,9,98,111,117,110,100,115,95,99,120,3,79,1,9,98,111,117, + 110,100,115,95,99,121,3,177,1,7,97,110,99,104,111,114,115,11,7,97, + 110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,9,97,110,95,98,111,116,116,111,109,0,8,111,110,108,97,121,111, + 117,116,7,23,114,101,112,99,111,109,116,97,105,110,101,114,99,104,105,108, + 100,115,99,97,108,101,100,10,111,110,115,99,114,111,108,108,101,100,7,23, + 114,101,112,111,114,116,99,111,110,116,97,105,110,101,114,115,99,114,111,108, + 108,101,100,0,0,242,2,3,7,116,115,112,97,99,101,114,8,116,115,112, + 97,99,101,114,49,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117, + 110,100,115,95,120,3,144,0,8,98,111,117,110,100,115,95,121,2,19,9, + 98,111,117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99, + 121,2,5,7,108,105,110,107,116,111,112,7,6,116,97,98,98,97,114,10, + 108,105,110,107,98,111,116,116,111,109,7,5,100,105,97,108,104,11,100,105, + 115,116,95,98,111,116,116,111,109,2,251,0,0,242,2,4,5,116,100,105, + 97,108,5,100,105,97,108,118,5,99,111,108,111,114,4,7,0,0,144,8, + 116,97,98,111,114,100,101,114,2,3,8,98,111,117,110,100,115,95,120,2, + 0,8,98,111,117,110,100,115,95,121,2,26,9,98,111,117,110,100,115,95, + 99,120,2,7,9,98,111,117,110,100,115,95,99,121,3,177,1,7,97,110, + 99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110,95,116,111, + 112,9,97,110,95,98,111,116,116,111,109,0,12,100,105,97,108,46,119,105, + 100,116,104,109,109,5,154,153,153,153,153,153,153,153,253,63,14,100,105,97, + 108,46,100,105,114,101,99,116,105,111,110,7,7,103,100,95,100,111,119,110, + 10,100,105,97,108,46,115,116,97,114,116,2,0,10,100,105,97,108,46,114, + 97,110,103,101,2,100,18,100,105,97,108,46,109,97,114,107,101,114,115,46, + 99,111,117,110,116,2,1,18,100,105,97,108,46,109,97,114,107,101,114,115, + 46,105,116,101,109,115,14,1,5,99,111,108,111,114,4,7,0,0,160,7, + 119,105,100,116,104,109,109,2,0,10,101,115,99,97,112,101,109,101,110,116, + 2,0,5,118,97,108,117,101,5,0,0,0,0,0,0,0,128,255,255,0, + 0,16,100,105,97,108,46,116,105,99,107,115,46,99,111,117,110,116,2,3, + 16,100,105,97,108,46,116,105,99,107,115,46,105,116,101,109,115,14,1,7, + 119,105,100,116,104,109,109,2,0,10,101,115,99,97,112,101,109,101,110,116, + 2,0,13,105,110,116,101,114,118,97,108,99,111,117,110,116,2,10,0,1, + 5,99,111,108,111,114,4,3,0,0,160,7,119,105,100,116,104,109,109,2, + 0,6,108,101,110,103,116,104,2,6,10,101,115,99,97,112,101,109,101,110, + 116,2,0,13,105,110,116,101,114,118,97,108,99,111,117,110,116,2,20,0, + 1,5,99,111,108,111,114,4,3,0,0,160,7,119,105,100,116,104,109,109, + 2,0,6,108,101,110,103,116,104,2,4,10,101,115,99,97,112,101,109,101, + 110,116,2,0,13,105,110,116,101,114,118,97,108,99,111,117,110,116,2,100, + 0,0,10,100,105,97,108,46,97,110,103,108,101,2,0,0,0,242,2,5, + 7,116,115,112,97,99,101,114,8,116,115,112,97,99,101,114,50,8,116,97, + 98,111,114,100,101,114,2,5,8,98,111,117,110,100,115,95,120,3,144,0, + 8,98,111,117,110,100,115,95,121,2,26,9,98,111,117,110,100,115,95,99, + 120,2,50,9,98,111,117,110,100,115,95,99,121,2,5,7,108,105,110,107, + 116,111,112,7,5,100,105,97,108,104,10,108,105,110,107,98,111,116,116,111, + 109,7,15,114,101,112,111,114,116,99,111,110,116,97,105,110,101,114,11,100, + 105,115,116,95,98,111,116,116,111,109,2,251,0,0,242,2,6,7,116,115, + 112,97,99,101,114,8,116,115,112,97,99,101,114,51,8,116,97,98,111,114, + 100,101,114,2,6,8,98,111,117,110,100,115,95,120,2,7,8,98,111,117, + 110,100,115,95,121,3,173,0,9,98,111,117,110,100,115,95,99,120,2,5, + 9,98,111,117,110,100,115,95,99,121,2,50,8,108,105,110,107,108,101,102, + 116,7,5,100,105,97,108,118,9,108,105,110,107,114,105,103,104,116,7,15, + 114,101,112,111,114,116,99,111,110,116,97,105,110,101,114,10,100,105,115,116, + 95,114,105,103,104,116,2,251,0,0,242,2,7,9,116,114,101,97,108,100, + 105,115,112,5,120,100,105,115,112,5,99,111,108,111,114,4,5,0,0,144, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8, + 116,97,98,111,114,100,101,114,2,7,8,98,111,117,110,100,115,95,120,2, + 52,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,2,68,9,98,111,117,110,100,115,95,99,121,2,18,9,116,101,120, + 116,102,108,97,103,115,11,12,116,102,95,121,99,101,110,116,101,114,101,100, + 0,10,118,97,108,117,101,114,97,110,103,101,2,1,10,118,97,108,117,101, + 115,116,97,114,116,2,0,6,102,111,114,109,97,116,6,5,48,46,48,109, + 109,5,118,97,108,117,101,5,0,0,0,0,0,0,0,128,255,255,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,242,2,8,9, + 116,114,101,97,108,100,105,115,112,5,121,100,105,115,112,5,99,111,108,111, + 114,4,5,0,0,144,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,8,8,98,111,117, + 110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,120,2,52,9,98,111,117,110,100,115,95,99,121, + 2,18,10,118,97,108,117,101,114,97,110,103,101,2,1,10,118,97,108,117, + 101,115,116,97,114,116,2,0,6,102,111,114,109,97,116,6,3,48,46,48, + 5,118,97,108,117,101,5,0,0,0,0,0,0,0,128,255,255,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,242,2,9,7,116, + 115,112,97,99,101,114,8,116,115,112,97,99,101,114,52,8,116,97,98,111, + 114,100,101,114,2,9,8,98,111,117,110,100,115,95,120,2,16,8,98,111, + 117,110,100,115,95,121,2,26,9,98,111,117,110,100,115,95,99,120,2,50, + 9,98,111,117,110,100,115,95,99,121,2,5,7,108,105,110,107,116,111,112, + 7,5,100,105,97,108,104,10,108,105,110,107,98,111,116,116,111,109,7,5, + 100,105,97,108,118,11,100,105,115,116,95,98,111,116,116,111,109,2,251,0, + 0,243,2,10,10,116,112,111,112,117,112,109,101,110,117,7,112,111,112,117, + 112,109,101,18,109,101,110,117,46,115,117,98,109,101,110,117,46,105,116,101, + 109,115,14,1,0,1,0,1,0,1,0,1,5,115,116,97,116,101,11,17, + 97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,0,1, + 5,115,116,97,116,101,11,16,97,115,95,108,111,99,97,108,100,105,115,97, + 98,108,101,100,17,97,115,95,108,111,99,97,108,105,110,118,105,115,105,98, + 108,101,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101, + 0,0,1,5,115,116,97,116,101,11,17,97,115,95,108,111,99,97,108,105, + 110,118,105,115,105,98,108,101,17,97,115,95,108,111,99,97,108,111,110,101, + 120,101,99,117,116,101,0,0,1,5,115,116,97,116,101,11,17,97,115,95, + 108,111,99,97,108,105,110,118,105,115,105,98,108,101,17,97,115,95,108,111, + 99,97,108,111,110,101,120,101,99,117,116,101,0,0,1,0,1,0,1,0, + 1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0, + 1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0, + 1,0,1,0,0,0,0,243,2,11,7,116,97,99,116,105,111,110,11,104, + 105,100,101,99,111,109,112,97,99,116,0,0,243,2,12,7,116,97,99,116, + 105,111,110,13,104,105,100,101,119,105,100,103,101,116,97,99,116,5,115,116, + 97,116,101,11,11,97,115,95,100,105,115,97,98,108,101,100,12,97,115,95, + 105,110,118,105,115,105,98,108,101,0,0,0,243,2,13,7,116,97,99,116, + 105,111,110,13,116,111,103,103,108,101,104,105,100,101,97,99,116,0,0,243, + 2,14,7,116,97,99,116,105,111,110,10,115,104,111,119,97,108,108,97,99, + 116,0,0,242,2,15,10,116,112,111,112,117,112,109,101,110,117,11,116,112, + 111,112,117,112,109,101,110,117,51,18,109,101,110,117,46,115,117,98,109,101, + 110,117,46,99,111,117,110,116,2,29,18,109,101,110,117,46,115,117,98,109, + 101,110,117,46,105,116,101,109,115,14,1,7,99,97,112,116,105,111,110,6, + 20,83,104,111,119,32,111,98,106,101,99,116,105,110,115,112,101,99,116,111, + 114,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112, + 116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117, + 116,101,0,0,1,7,99,97,112,116,105,111,110,6,21,83,104,111,119,32, + 99,111,109,112,111,110,101,110,116,112,97,108,101,116,116,101,5,115,116,97, + 116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17, + 97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,0,1, + 7,99,97,112,116,105,111,110,6,12,83,104,111,119,32,97,115,32,84,101, + 120,116,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97, + 112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99, + 117,116,101,0,7,111,112,116,105,111,110,115,11,19,109,97,111,95,115,104, + 111,114,116,99,117,116,99,97,112,116,105,111,110,16,109,97,111,95,97,115, + 121,110,99,101,120,101,99,117,116,101,0,0,1,6,97,99,116,105,111,110, + 7,26,102,111,114,109,100,101,115,105,103,110,101,114,102,111,46,104,105,100, + 101,99,111,109,112,97,99,116,7,111,112,116,105,111,110,115,11,13,109,97, + 111,95,115,101,112,97,114,97,116,111,114,19,109,97,111,95,115,104,111,114, + 116,99,117,116,99,97,112,116,105,111,110,0,0,1,6,97,99,116,105,111, + 110,7,28,102,111,114,109,100,101,115,105,103,110,101,114,102,111,46,104,105, + 100,101,119,105,100,103,101,116,97,99,116,7,111,112,116,105,111,110,115,11, + 12,109,97,111,95,99,104,101,99,107,98,111,120,19,109,97,111,95,115,104, + 111,114,116,99,117,116,99,97,112,116,105,111,110,0,0,1,6,97,99,116, + 105,111,110,7,13,104,105,100,101,119,105,100,103,101,116,97,99,116,5,115, + 116,97,116,101,11,11,97,115,95,100,105,115,97,98,108,101,100,12,97,115, + 95,105,110,118,105,115,105,98,108,101,0,7,111,112,116,105,111,110,115,11, + 12,109,97,111,95,99,104,101,99,107,98,111,120,19,109,97,111,95,115,104, + 111,114,116,99,117,116,99,97,112,116,105,111,110,0,0,1,6,97,99,116, + 105,111,110,7,13,116,111,103,103,108,101,104,105,100,101,97,99,116,0,1, + 6,97,99,116,105,111,110,7,10,115,104,111,119,97,108,108,97,99,116,0, + 1,7,111,112,116,105,111,110,115,11,13,109,97,111,95,115,101,112,97,114, + 97,116,111,114,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112, + 116,105,111,110,0,0,1,7,99,97,112,116,105,111,110,6,17,67,111,112, + 121,32,67,111,109,112,111,110,101,110,116,40,115,41,4,110,97,109,101,6, + 4,99,111,112,121,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,16,97,115,95,108,111,99,97,108,115,104,111, + 114,116,99,117,116,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99, + 117,116,101,0,2,115,99,1,2,1,3,67,64,0,0,1,7,99,97,112, + 116,105,111,110,6,16,67,117,116,32,67,111,109,112,111,110,101,110,116,40, + 115,41,4,110,97,109,101,6,3,99,117,116,5,115,116,97,116,101,11,15, + 97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,16,97,115,95,108, + 111,99,97,108,115,104,111,114,116,99,117,116,17,97,115,95,108,111,99,97, + 108,111,110,101,120,101,99,117,116,101,0,7,111,112,116,105,111,110,115,11, + 19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111,110, + 16,109,97,111,95,97,115,121,110,99,101,120,101,99,117,116,101,0,2,115, + 99,1,2,1,3,88,64,0,0,1,7,99,97,112,116,105,111,110,6,18, + 80,97,115,116,101,32,67,111,109,112,111,110,101,110,116,40,115,41,4,110, + 97,109,101,6,5,112,97,115,116,101,5,115,116,97,116,101,11,15,97,115, + 95,108,111,99,97,108,99,97,112,116,105,111,110,16,97,115,95,108,111,99, + 97,108,115,104,111,114,116,99,117,116,17,97,115,95,108,111,99,97,108,111, + 110,101,120,101,99,117,116,101,0,2,115,99,1,2,1,3,86,64,0,0, + 1,7,99,97,112,116,105,111,110,6,19,68,101,108,101,116,101,32,67,111, + 109,112,111,110,101,110,116,40,115,41,4,110,97,109,101,6,6,100,101,108, + 101,116,101,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99, + 97,112,116,105,111,110,16,97,115,95,108,111,99,97,108,115,104,111,114,116, + 99,117,116,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116, + 101,0,7,111,112,116,105,111,110,115,11,19,109,97,111,95,115,104,111,114, + 116,99,117,116,99,97,112,116,105,111,110,16,109,97,111,95,97,115,121,110, + 99,101,120,101,99,117,116,101,0,2,115,99,1,2,1,3,7,1,0,0, + 1,7,99,97,112,116,105,111,110,6,21,85,110,100,101,108,101,116,101,32, + 67,111,109,112,111,110,101,110,116,40,115,41,4,110,97,109,101,6,8,117, + 110,100,101,108,101,116,101,5,115,116,97,116,101,11,15,97,115,95,108,111, + 99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111, + 110,101,120,101,99,117,116,101,0,0,1,7,111,112,116,105,111,110,115,11, + 13,109,97,111,95,115,101,112,97,114,97,116,111,114,19,109,97,111,95,115, + 104,111,114,116,99,117,116,99,97,112,116,105,111,110,0,0,1,7,99,97, + 112,116,105,111,110,6,18,83,101,108,101,99,116,32,67,104,105,108,100,119, + 105,100,103,101,116,4,110,97,109,101,6,11,115,101,108,101,99,116,99,104, + 105,108,100,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99, + 97,112,116,105,111,110,0,0,1,7,99,97,112,116,105,111,110,6,14,69, + 100,105,116,32,67,111,109,112,111,110,101,110,116,4,110,97,109,101,6,8, + 101,100,105,116,99,111,109,112,5,115,116,97,116,101,11,15,97,115,95,108, + 111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108, + 111,110,101,120,101,99,117,116,101,0,0,1,7,99,97,112,116,105,111,110, + 6,14,66,114,105,110,103,32,116,111,32,70,114,111,110,116,4,110,97,109, + 101,6,10,98,114,105,110,103,116,111,102,114,111,5,115,116,97,116,101,11, + 15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95, + 108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,0,1,7,99,97, + 112,116,105,111,110,6,12,83,101,110,100,32,116,111,32,66,97,99,107,4, + 110,97,109,101,6,8,115,101,110,100,116,111,98,97,5,115,116,97,116,101, + 11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115, + 95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,0,1,7,99, + 97,112,116,105,111,110,6,7,73,99,111,110,105,102,121,4,110,97,109,101, + 6,7,105,99,111,110,105,102,121,5,115,116,97,116,101,11,15,97,115,95, + 108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97, + 108,111,110,101,120,101,99,117,116,101,0,0,1,7,99,97,112,116,105,111, + 110,6,9,68,101,105,99,111,110,105,102,121,4,110,97,109,101,6,9,100, + 101,105,99,111,110,105,102,121,5,115,116,97,116,101,11,15,97,115,95,108, + 111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108, + 111,110,101,120,101,99,117,116,101,0,0,1,7,99,97,112,116,105,111,110, + 6,13,83,101,116,32,84,97,98,32,79,114,100,101,114,4,110,97,109,101, + 6,9,115,101,116,116,97,98,111,114,100,5,115,116,97,116,101,11,15,97, + 115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111, + 99,97,108,111,110,101,120,101,99,117,116,101,0,0,1,7,99,97,112,116, + 105,111,110,6,18,83,101,116,32,67,114,101,97,116,105,111,110,32,79,114, + 100,101,114,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99, + 97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101, + 99,117,116,101,0,0,1,7,99,97,112,116,105,111,110,6,20,83,121,110, + 99,46,32,116,111,32,70,111,110,116,32,72,101,105,103,104,116,4,110,97, + 109,101,6,8,115,121,110,99,116,111,102,111,5,115,116,97,116,101,11,15, + 97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108, + 111,99,97,108,111,110,101,120,101,99,117,116,101,0,0,1,7,99,97,112, + 116,105,111,110,6,19,82,101,118,101,114,116,32,116,111,32,105,110,104,101, + 114,105,116,101,100,4,110,97,109,101,6,6,114,101,118,101,114,116,5,115, + 116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111, + 110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0, + 7,111,112,116,105,111,110,115,11,19,109,97,111,95,115,104,111,114,116,99, + 117,116,99,97,112,116,105,111,110,16,109,97,111,95,97,115,121,110,99,101, + 120,101,99,117,116,101,0,0,1,7,111,112,116,105,111,110,115,11,13,109, + 97,111,95,115,101,112,97,114,97,116,111,114,19,109,97,111,95,115,104,111, + 114,116,99,117,116,99,97,112,116,105,111,110,0,0,1,7,99,97,112,116, + 105,111,110,6,10,84,111,117,99,104,32,70,111,114,109,5,115,116,97,116, + 101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97, + 115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,7,111,112, + 116,105,111,110,115,11,13,109,97,111,95,115,101,112,97,114,97,116,111,114, + 19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111,110, + 0,0,1,7,99,97,112,116,105,111,110,6,15,65,100,100,32,114,101,112, + 111,114,116,32,112,97,103,101,4,110,97,109,101,6,7,97,100,100,112,97, + 103,101,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97, + 112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99, + 117,116,101,0,0,1,7,99,97,112,116,105,111,110,6,18,68,101,108,101, + 116,101,32,114,101,112,111,114,116,32,112,97,103,101,4,110,97,109,101,6, + 7,100,101,108,112,97,103,101,5,115,116,97,116,101,11,15,97,115,95,108, + 111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108, + 111,110,101,120,101,99,117,116,101,0,0,0,4,108,101,102,116,2,16,3, + 116,111,112,3,160,0,0,0,243,2,16,16,116,115,116,114,105,110,103,99, + 111,110,116,97,105,110,101,114,1,99,0,0,242,2,17,16,116,115,116,114, + 105,110,103,99,111,110,116,97,105,110,101,114,2,115,99,12,115,116,114,105, + 110,103,115,46,100,97,116,97,1,6,21,68,111,32,121,111,117,32,119,105, + 115,104,32,116,111,32,100,101,108,101,116,101,6,7,87,65,82,78,73,78, + 71,0,4,108,101,102,116,2,64,3,116,111,112,3,208,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,treportdesignerfo,''); +end. diff --git a/mseide-msegui/apps/ide/selecteditpageform.mfm b/mseide-msegui/apps/ide/selecteditpageform.mfm new file mode 100644 index 0000000..da922cc --- /dev/null +++ b/mseide-msegui/apps/ide/selecteditpageform.mfm @@ -0,0 +1,66 @@ +object selecteditpagefo: tselecteditpagefo + visible = False + bounds_x = 160 + bounds_y = 124 + bounds_cx = 704 + bounds_cy = 473 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.onlayout = formonchildscaled + container.bounds = ( + 0 + 0 + 704 + 473 + ) + options = [fo_screencentered, fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder, fo_savestate] + caption = 'Select edit page (Ctrl+E)' + icon.transparentcolor = -2147483648 + oneventloopstart = fooncreate + onlayout = formonchildscaled + moduleclassname = 'tmseform' + object list: tlistview + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets, ow_multiplehint] + frame.colorclient = -1879048187 + frame.localprops = [frl_colorclient] + frame.localprops1 = [] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 704 + bounds_cy = 451 + anchors = [an_top, an_bottom] + datarowlinewidth = 0 + datacollinewidth = 0 + cellwidth = 100 + cellheight = 20 + cellframe.leveli = 1 + cellframe.localprops = [frl_leveli] + cellframe.localprops1 = [] + optionsgrid = [og_colsizing, og_focuscellonenter, og_colchangeontabkey, og_wraprow, og_wrapcol, og_autopopup] + options = [lvo_readonly, lvo_drawfocus, lvo_mousemovefocus, lvo_focusselect, lvo_mouseselect, lvo_locate, lvo_hintclippedtext] + onitemevent = doonitemevent + reffontheight = 16 + end + object pathdisp: tstringdisp + frame.localprops = [] + frame.localprops1 = [] + taborder = 2 + bounds_x = 0 + bounds_y = 452 + bounds_cx = 650 + anchors = [an_left, an_right, an_bottom] + textflags = [tf_ycentered, tf_ellipseleft] + reffontheight = 16 + end + object openfilebutton: tbutton + taborder = 1 + bounds_x = 652 + bounds_y = 452 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_localcaption, as_localonexecute] + caption = '&Open' + onexecute = openfileonexecute + end +end diff --git a/mseide-msegui/apps/ide/selecteditpageform.pas b/mseide-msegui/apps/ide/selecteditpageform.pas new file mode 100644 index 0000000..57a8c21 --- /dev/null +++ b/mseide-msegui/apps/ide/selecteditpageform.pas @@ -0,0 +1,163 @@ +{ MSEide Copyright (c) 1999-2010 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit selecteditpageform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseforms,mselistbrowser,msetypes,msestrings,msegrids,msegui,msedispwidgets, + msestat,msesimplewidgets,mseglob,msegridsglob; + +type + tselecteditpagefo = class(tmseform) + list: tlistview; + pathdisp: tstringdisp; + openfilebutton: tbutton; + procedure doonitemevent(const sender: tcustomlistview; const index: Integer; + var info: celleventinfoty); +// procedure doonshowhint(const sender: TObject; var info: hintinfoty); + procedure fooncreate(const sender: TObject); + procedure openfileonexecute(const sender: TObject); + procedure formonchildscaled(const sender: TObject); + private + fpaths,frelpaths,fnames: filenamearty; + fsortlist: integerarty; + public + end; + +procedure selecteditpage; +procedure updatestat(const filer: tstatfiler); + +implementation + +uses + selecteditpageform_mfm,sourceform,msedatalist,msedatanodes,msegraphutils,main, + msefileutils,mseguiglob,msearrayutils; +var + colwidth: integer; + pos: rectty; + +procedure updatestat(const filer: tstatfiler); +begin + filer.setsection('selecteditpage'); + filer.updatevalue('colwidth',colwidth); + with pos do begin + filer.updatevalue('x',x); + filer.updatevalue('y',y); + filer.updatevalue('cx',cx); + filer.updatevalue('cy',cy); + end; +end; + +procedure selecteditpage; +var + fo: tselecteditpagefo; +begin + fo:= tselecteditpagefo.create(nil); + try + fo.list.cellwidth:= colwidth; + if (pos.cx > 0) and (pos.y > 0) then begin + fo.widgetrect:= pos; + end; + if fo.show(true,sourcefo.window) = mr_ok then begin + sourcefo.show; + sourcefo.setfocus; + end; + colwidth:= fo.list.cellwidth; + pos:= fo.window.normalwindowrect; + finally + fo.Free; + end; +end; + +{ tselecteditpagefo } + +procedure tselecteditpagefo.doonitemevent(const sender: tcustomlistview; + const index: Integer; var info: celleventinfoty); +begin + if iscellclick(info) then begin + sourcefo.tabwidget.activepageindex:= fsortlist[index]; + window.modalresult:= mr_ok; + end + else begin + if info.eventkind = cek_enter then begin + if findfile(frelpaths[fsortlist[index]]) then begin + pathdisp.value:= filepath(frelpaths[fsortlist[index]]); + end + else begin + pathdisp.value:= fpaths[fsortlist[index]]; + end; + end; + end; +end; +{ +procedure tselecteditpagefo.doonshowhint(const sender: TObject; var info: hintinfoty); +var + item1: tlistitem; +begin + item1:= list.itematpos(info.posrect.pos); + if item1 <> nil then begin + with info do begin + caption:= fpaths[fsortlist[item1.index]]; + include(flags,hfl_show); + showtime:= 0; + end; + end; +end; +} +procedure tselecteditpagefo.fooncreate(const sender: TObject); +var + int1,int2: integer; +begin + setlength(fpaths,sourcefo.count); + setlength(frelpaths,sourcefo.count); + setlength(fnames,sourcefo.count); + for int1:= 0 to high(fpaths) do begin + fpaths[int1]:= sourcefo.items[int1].filepath; + frelpaths[int1]:= sourcefo.items[int1].relpath; + fnames[int1]:= sourcefo.items[int1].filename; + end; + sortarray(fnames,sms_upi,fsortlist); + list.itemlist.add(fnames); + int2:= sourcefo.tabwidget.activepageindex; + for int1:= 0 to high(fsortlist) do begin + if fsortlist[int1] = int2 then begin + list.focusedindex:= int1; + break; + end; + end; +end; + +procedure tselecteditpagefo.openfileonexecute(const sender: TObject); +begin + if mainfo.opensource(fk_source,false) then begin + release; + end; +end; + +procedure tselecteditpagefo.formonchildscaled(const sender: TObject); +begin + placeyorder(0,[1],[list,pathdisp],1); + openfilebutton.height:= pathdisp.height; + aligny(wam_center,[pathdisp,openfilebutton]); + list.synctofontheight; +end; + +initialization + colwidth:= 100; +end. diff --git a/mseide-msegui/apps/ide/selecteditpageform_mfm.pas b/mseide-msegui/apps/ide/selecteditpageform_mfm.pas new file mode 100644 index 0000000..829a4b7 --- /dev/null +++ b/mseide-msegui/apps/ide/selecteditpageform_mfm.pas @@ -0,0 +1,98 @@ +unit selecteditpageform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,selecteditpageform; + +const + objdata: record size: integer; data: array[0..1613] of byte end = + (size: 1614; data: ( + 84,80,70,48,17,116,115,101,108,101,99,116,101,100,105,116,112,97,103,101, + 102,111,16,115,101,108,101,99,116,101,100,105,116,112,97,103,101,102,111,7, + 118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,160,0, + 8,98,111,117,110,100,115,95,121,2,124,9,98,111,117,110,100,115,95,99, + 120,3,192,2,9,98,111,117,110,100,115,95,99,121,3,217,1,26,99,111, + 110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,0,27,99,111,110,116,97,105,110,101,114,46,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,18,99,111,110, + 116,97,105,110,101,114,46,111,110,108,97,121,111,117,116,7,17,102,111,114, + 109,111,110,99,104,105,108,100,115,99,97,108,101,100,16,99,111,110,116,97, + 105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0,3,192,2,3, + 217,1,0,7,111,112,116,105,111,110,115,11,17,102,111,95,115,99,114,101, + 101,110,99,101,110,116,101,114,101,100,13,102,111,95,99,108,111,115,101,111, + 110,101,115,99,15,102,111,95,97,117,116,111,114,101,97,100,115,116,97,116, + 16,102,111,95,97,117,116,111,119,114,105,116,101,115,116,97,116,10,102,111, + 95,115,97,118,101,112,111,115,13,102,111,95,115,97,118,101,122,111,114,100, + 101,114,12,102,111,95,115,97,118,101,115,116,97,116,101,0,7,99,97,112, + 116,105,111,110,6,25,83,101,108,101,99,116,32,101,100,105,116,32,112,97, + 103,101,32,40,67,116,114,108,43,69,41,21,105,99,111,110,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,0,0,0,128,16,111, + 110,101,118,101,110,116,108,111,111,112,115,116,97,114,116,7,10,102,111,111, + 110,99,114,101,97,116,101,8,111,110,108,97,121,111,117,116,7,17,102,111, + 114,109,111,110,99,104,105,108,100,115,99,97,108,101,100,15,109,111,100,117, + 108,101,99,108,97,115,115,110,97,109,101,6,8,116,109,115,101,102,111,114, + 109,0,9,116,108,105,115,116,118,105,101,119,4,108,105,115,116,13,111,112, + 116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115, + 101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111, + 119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99, + 117,115,111,117,116,17,111,119,95,102,111,99,117,115,98,97,99,107,111,110, + 101,115,99,13,111,119,95,109,111,117,115,101,119,104,101,101,108,17,111,119, + 95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,15,111,119,95,109, + 117,108,116,105,112,108,101,104,105,110,116,0,17,102,114,97,109,101,46,99, + 111,108,111,114,99,108,105,101,110,116,4,5,0,0,144,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,15,102,114,108,95,99,111, + 108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,8,98,111,117,110,100,115,95,120,2, + 0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,3,192,2,9,98,111,117,110,100,115,95,99,121,3,195,1,7,97, + 110,99,104,111,114,115,11,6,97,110,95,116,111,112,9,97,110,95,98,111, + 116,116,111,109,0,16,100,97,116,97,114,111,119,108,105,110,101,119,105,100, + 116,104,2,0,16,100,97,116,97,99,111,108,108,105,110,101,119,105,100,116, + 104,2,0,9,99,101,108,108,119,105,100,116,104,2,100,10,99,101,108,108, + 104,101,105,103,104,116,2,20,16,99,101,108,108,102,114,97,109,101,46,108, + 101,118,101,108,105,2,1,20,99,101,108,108,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,105, + 0,21,99,101,108,108,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,11,111,112,116,105,111,110,115,103,114,105,100,11,12,111, + 103,95,99,111,108,115,105,122,105,110,103,19,111,103,95,102,111,99,117,115, + 99,101,108,108,111,110,101,110,116,101,114,20,111,103,95,99,111,108,99,104, + 97,110,103,101,111,110,116,97,98,107,101,121,10,111,103,95,119,114,97,112, + 114,111,119,10,111,103,95,119,114,97,112,99,111,108,12,111,103,95,97,117, + 116,111,112,111,112,117,112,0,7,111,112,116,105,111,110,115,11,12,108,118, + 111,95,114,101,97,100,111,110,108,121,13,108,118,111,95,100,114,97,119,102, + 111,99,117,115,18,108,118,111,95,109,111,117,115,101,109,111,118,101,102,111, + 99,117,115,15,108,118,111,95,102,111,99,117,115,115,101,108,101,99,116,15, + 108,118,111,95,109,111,117,115,101,115,101,108,101,99,116,10,108,118,111,95, + 108,111,99,97,116,101,19,108,118,111,95,104,105,110,116,99,108,105,112,112, + 101,100,116,101,120,116,0,11,111,110,105,116,101,109,101,118,101,110,116,7, + 13,100,111,111,110,105,116,101,109,101,118,101,110,116,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,16,0,0,11,116,115,116,114,105,110,103, + 100,105,115,112,8,112,97,116,104,100,105,115,112,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101, + 114,2,2,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100, + 115,95,121,3,196,1,9,98,111,117,110,100,115,95,99,120,3,138,2,7, + 97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,8,97,110,95, + 114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,9,116,101,120, + 116,102,108,97,103,115,11,12,116,102,95,121,99,101,110,116,101,114,101,100, + 14,116,102,95,101,108,108,105,112,115,101,108,101,102,116,0,13,114,101,102, + 102,111,110,116,104,101,105,103,104,116,2,16,0,0,7,116,98,117,116,116, + 111,110,14,111,112,101,110,102,105,108,101,98,117,116,116,111,110,8,116,97, + 98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,3,140,2, + 8,98,111,117,110,100,115,95,121,3,196,1,9,98,111,117,110,100,115,95, + 99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,20,7,97,110,99, + 104,111,114,115,11,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111, + 116,116,111,109,0,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101, + 120,101,99,117,116,101,0,7,99,97,112,116,105,111,110,6,5,38,79,112, + 101,110,9,111,110,101,120,101,99,117,116,101,7,17,111,112,101,110,102,105, + 108,101,111,110,101,120,101,99,117,116,101,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tselecteditpagefo,''); +end. diff --git a/mseide-msegui/apps/ide/selectsubformdialogform.pas b/mseide-msegui/apps/ide/selectsubformdialogform.pas new file mode 100644 index 0000000..84d1e66 --- /dev/null +++ b/mseide-msegui/apps/ide/selectsubformdialogform.pas @@ -0,0 +1,36 @@ +{ MSEide Copyright (c) 1999-2006 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit selectsubformdialogform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseforms,msedataedits,msesimplewidgets; + +type + tselectsubformdialogfo = class(tmseform) + subform: tdropdownlistedit; + ok: tbutton; + cancel: tbutton; + end; + +implementation +uses + selectsubformdialogform_mfm; + +end. diff --git a/mseide-msegui/apps/ide/selectsubformdialogform_mfm.pas b/mseide-msegui/apps/ide/selectsubformdialogform_mfm.pas new file mode 100644 index 0000000..7d28380 --- /dev/null +++ b/mseide-msegui/apps/ide/selectsubformdialogform_mfm.pas @@ -0,0 +1,47 @@ +unit selectsubformdialogform_mfm; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,selectsubformdialogform; + +const + objdata: record size: integer; data: array[0..571] of byte end = + (size: 572; data: ( + 84,80,70,48,22,116,115,101,108,101,99,116,115,117,98,102,111,114,109,100, + 105,97,108,111,103,102,111,21,115,101,108,101,99,116,115,117,98,102,111,114, + 109,100,105,97,108,111,103,102,111,4,98,111,95,120,3,248,0,4,98,111, + 95,121,3,158,1,5,98,111,95,99,120,3,241,0,5,98,111,95,99,121, + 2,81,7,118,105,115,105,98,108,101,8,8,116,97,98,111,114,100,101,114, + 2,0,7,99,97,112,116,105,111,110,6,14,83,101,108,101,99,116,32,115, + 117,98,102,111,114,109,15,109,111,100,117,108,101,99,108,97,115,115,110,97, + 109,101,6,8,116,109,115,101,102,111,114,109,0,7,116,98,117,116,116,111, + 110,2,111,107,4,98,111,95,120,2,120,4,98,111,95,121,2,48,5,98, + 111,95,99,121,2,20,7,97,110,99,104,111,114,115,11,6,97,110,95,116, + 111,112,8,97,110,95,114,105,103,104,116,0,8,116,97,98,111,114,100,101, + 114,2,2,7,99,97,112,116,105,111,110,6,2,79,75,11,109,111,100,97, + 108,114,101,115,117,108,116,7,5,109,114,95,111,107,0,0,7,116,98,117, + 116,116,111,110,6,99,97,110,99,101,108,4,98,111,95,120,3,184,0,4, + 98,111,95,121,2,48,5,98,111,95,99,121,2,20,7,97,110,99,104,111, + 114,115,11,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0, + 8,116,97,98,111,114,100,101,114,2,1,7,99,97,112,116,105,111,110,6, + 6,67,97,110,99,101,108,11,109,111,100,97,108,114,101,115,117,108,116,7, + 9,109,114,95,99,97,110,99,101,108,0,0,17,116,100,114,111,112,100,111, + 119,110,108,105,115,116,101,100,105,116,7,115,117,98,102,111,114,109,4,98, + 111,95,120,2,8,4,98,111,95,121,2,8,5,98,111,95,99,120,3,228, + 0,5,98,111,95,99,121,2,20,12,102,114,97,109,101,46,108,101,118,101, + 108,111,2,254,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102, + 116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,8,116, + 97,98,111,114,100,101,114,2,0,16,100,114,111,112,100,111,119,110,46,111, + 112,116,105,111,110,115,11,14,100,101,111,95,115,101,108,101,99,116,111,110, + 108,121,0,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,99,111, + 117,110,116,2,1,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46, + 105,116,101,109,115,14,1,0,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tselectsubformdialogfo,''); +end. diff --git a/mseide-msegui/apps/ide/selectsubmoduledialogform.mfm b/mseide-msegui/apps/ide/selectsubmoduledialogform.mfm new file mode 100644 index 0000000..0933695 --- /dev/null +++ b/mseide-msegui/apps/ide/selectsubmoduledialogform.mfm @@ -0,0 +1,51 @@ +object selectsubmoduledialogfo: tselectsubmoduledialogfo + visible = False + bounds_x = 391 + bounds_y = 320 + bounds_cx = 241 + bounds_cy = 81 + container.bounds = ( + 0 + 0 + 241 + 81 + ) + options = [fo_screencentered, fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder, fo_savestate] + caption = 'Select subform' + moduleclassname = 'tmseform' + object ok: tbutton + taborder = 1 + bounds_x = 120 + bounds_y = 48 + bounds_cx = 50 + bounds_cy = 22 + anchors = [an_top, an_right] + state = [as_default, as_localdefault, as_localcaption] + caption = 'OK' + modalresult = mr_ok + end + object cancel: tbutton + taborder = 2 + bounds_x = 184 + bounds_y = 48 + bounds_cx = 50 + bounds_cy = 22 + anchors = [an_top, an_right] + state = [as_localcaption] + caption = 'Cancel' + modalresult = mr_cancel + end + object submodule: tdropdownlistedit + bounds_x = 8 + bounds_y = 8 + bounds_cx = 228 + anchors = [an_left, an_top, an_right] + dropdown.options = [deo_selectonly, deo_autodropdown, deo_keydropdown, deo_sorted] + dropdown.cols.count = 1 + dropdown.cols.items = < + item + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + end> + reffontheight = 14 + end +end diff --git a/mseide-msegui/apps/ide/selectsubmoduledialogform.pas b/mseide-msegui/apps/ide/selectsubmoduledialogform.pas new file mode 100644 index 0000000..ed0580f --- /dev/null +++ b/mseide-msegui/apps/ide/selectsubmoduledialogform.pas @@ -0,0 +1,36 @@ +{ MSEide Copyright (c) 1999-2006 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit selectsubmoduledialogform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseforms,msedataedits,msesimplewidgets; + +type + tselectsubmoduledialogfo = class(tmseform) + submodule: tdropdownlistedit; + ok: tbutton; + cancel: tbutton; + end; + +implementation +uses + selectsubmoduledialogform_mfm; + +end. diff --git a/mseide-msegui/apps/ide/selectsubmoduledialogform_mfm.pas b/mseide-msegui/apps/ide/selectsubmoduledialogform_mfm.pas new file mode 100644 index 0000000..5796772 --- /dev/null +++ b/mseide-msegui/apps/ide/selectsubmoduledialogform_mfm.pas @@ -0,0 +1,64 @@ +unit selectsubmoduledialogform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,selectsubmoduledialogform; + +const + objdata: record size: integer; data: array[0..936] of byte end = + (size: 937; data: ( + 84,80,70,48,24,116,115,101,108,101,99,116,115,117,98,109,111,100,117,108, + 101,100,105,97,108,111,103,102,111,23,115,101,108,101,99,116,115,117,98,109, + 111,100,117,108,101,100,105,97,108,111,103,102,111,7,118,105,115,105,98,108, + 101,8,8,98,111,117,110,100,115,95,120,3,135,1,8,98,111,117,110,100, + 115,95,121,3,64,1,9,98,111,117,110,100,115,95,99,120,3,241,0,9, + 98,111,117,110,100,115,95,99,121,2,81,16,99,111,110,116,97,105,110,101, + 114,46,98,111,117,110,100,115,1,2,0,2,0,3,241,0,2,81,0,7, + 111,112,116,105,111,110,115,11,17,102,111,95,115,99,114,101,101,110,99,101, + 110,116,101,114,101,100,13,102,111,95,99,108,111,115,101,111,110,101,115,99, + 15,102,111,95,97,117,116,111,114,101,97,100,115,116,97,116,16,102,111,95, + 97,117,116,111,119,114,105,116,101,115,116,97,116,10,102,111,95,115,97,118, + 101,112,111,115,13,102,111,95,115,97,118,101,122,111,114,100,101,114,12,102, + 111,95,115,97,118,101,115,116,97,116,101,0,7,99,97,112,116,105,111,110, + 6,14,83,101,108,101,99,116,32,115,117,98,102,111,114,109,15,109,111,100, + 117,108,101,99,108,97,115,115,110,97,109,101,6,8,116,109,115,101,102,111, + 114,109,0,7,116,98,117,116,116,111,110,2,111,107,8,116,97,98,111,114, + 100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,120,8,98,111,117, + 110,100,115,95,121,2,48,9,98,111,117,110,100,115,95,99,120,2,50,9, + 98,111,117,110,100,115,95,99,121,2,22,7,97,110,99,104,111,114,115,11, + 6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,5,115,116, + 97,116,101,11,10,97,115,95,100,101,102,97,117,108,116,15,97,115,95,108, + 111,99,97,108,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,2,79,75, + 11,109,111,100,97,108,114,101,115,117,108,116,7,5,109,114,95,111,107,0, + 0,7,116,98,117,116,116,111,110,6,99,97,110,99,101,108,8,116,97,98, + 111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,3,184,0,8, + 98,111,117,110,100,115,95,121,2,48,9,98,111,117,110,100,115,95,99,120, + 2,50,9,98,111,117,110,100,115,95,99,121,2,22,7,97,110,99,104,111, + 114,115,11,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0, + 5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116, + 105,111,110,0,7,99,97,112,116,105,111,110,6,6,67,97,110,99,101,108, + 11,109,111,100,97,108,114,101,115,117,108,116,7,9,109,114,95,99,97,110, + 99,101,108,0,0,17,116,100,114,111,112,100,111,119,110,108,105,115,116,101, + 100,105,116,9,115,117,98,109,111,100,117,108,101,8,98,111,117,110,100,115, + 95,120,2,8,8,98,111,117,110,100,115,95,121,2,8,9,98,111,117,110, + 100,115,95,99,120,3,228,0,7,97,110,99,104,111,114,115,11,7,97,110, + 95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104, + 116,0,16,100,114,111,112,100,111,119,110,46,111,112,116,105,111,110,115,11, + 14,100,101,111,95,115,101,108,101,99,116,111,110,108,121,16,100,101,111,95, + 97,117,116,111,100,114,111,112,100,111,119,110,15,100,101,111,95,107,101,121, + 100,114,111,112,100,111,119,110,10,100,101,111,95,115,111,114,116,101,100,0, + 19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,99,111,117,110,116, + 2,1,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,105,116,101, + 109,115,14,1,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121, + 99,101,110,116,101,114,101,100,11,116,102,95,110,111,115,101,108,101,99,116, + 14,116,102,95,101,108,108,105,112,115,101,108,101,102,116,0,0,0,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tselectsubmoduledialogfo,''); +end. diff --git a/mseide-msegui/apps/ide/setcreateorderform.mfm b/mseide-msegui/apps/ide/setcreateorderform.mfm new file mode 100644 index 0000000..1d61187 --- /dev/null +++ b/mseide-msegui/apps/ide/setcreateorderform.mfm @@ -0,0 +1,109 @@ +object setcreateorderfo: tsetcreateorderfo + bounds_x = 223 + bounds_y = 264 + bounds_cx = 381 + bounds_cy = 340 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 381 + 340 + ) + options = [fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder, fo_savestate] + statfile = statfile1 + onclosequery = formonclosequery + moduleclassname = 'tmseform' + object grid: tstringgrid + frame.localprops = [] + frame.localprops1 = [] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 381 + bounds_cy = 306 + anchors = [an_top, an_bottom] + optionsgrid = [og_colsizing, og_rowmoving, og_keyrowmoving, og_focuscellonenter, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + datacols.count = 2 + datacols.options = [co_readonly, co_focusselect, co_rowselect, co_proportional, co_savestate, co_mousescrollrow] + datacols.items = < + item + width = 165 + options = [co_readonly, co_focusselect, co_rowselect, co_proportional, co_savestate, co_mousescrollrow] + valuefalse = '0' + valuetrue = '1' + end + item + width = 159 + options = [co_readonly, co_focusselect, co_rowselect, co_fill, co_savestate, co_mousescrollrow] + optionsedit = [scoe_undoonesc, scoe_eatreturn, scoe_autoselect, scoe_autoselectonfirstclick, scoe_hintclippedtext] + valuefalse = '0' + valuetrue = '1' + end> + fixcols.count = 1 + fixcols.items = < + item + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 2 + captions.items = < + item + caption = 'Name' + end + item + caption = 'Class' + end> + captionsfix.count = 1 + captionsfix.items = < + item + caption = 'Order' + end> + end> + datarowheight = 16 + statfile = statfile1 + reffontheight = 14 + end + object tbutton1: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + taborder = 1 + bounds_x = 254 + bounds_y = 312 + bounds_cx = 58 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + reffontheight = 14 + end + object tbutton2: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + taborder = 2 + bounds_x = 318 + bounds_y = 312 + bounds_cx = 58 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_localdefault, as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + reffontheight = 14 + end + object statfile1: tstatfile + filename = 'settaborderfo.sta' + options = [sfo_memory] + left = 104 + top = 136 + end + object c: tstringcontainer + strings.data = ( + 'Set Component create Order of' + ) + left = 40 + top = 40 + end +end diff --git a/mseide-msegui/apps/ide/setcreateorderform.pas b/mseide-msegui/apps/ide/setcreateorderform.pas new file mode 100644 index 0000000..3eb4f41 --- /dev/null +++ b/mseide-msegui/apps/ide/setcreateorderform.pas @@ -0,0 +1,89 @@ +{ MSEide Copyright (c) 1999-2013 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit setcreateorderform; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,msegui,mseclasses,mseforms,msestat,msestatfile,msestrings, + msedatalist, + msedrawtext,mseevent,msegraphics,msegraphutils,msegrids,mseguiglob,mseglob, + msepipestream,msetypes,msesimplewidgets,msewidgets,msestringcontainer; + +type + tsetcreateorderfo = class(tmseform) + statfile1: tstatfile; + grid: tstringgrid; + tbutton1: tbutton; + tbutton2: tbutton; + c: tstringcontainer; + procedure formonclosequery(const sender: tcustommseform; + var amodalresult: modalresultty); + private + fmodule: tcomponent; + public + constructor create(const amodule: tcomponent; const acurrentcompname: string); + reintroduce; + end; +var + setcreateorderfo: tsetcreateorderfo; + +implementation +uses + setcreateorderform_mfm,msedesigner; +type + stringconsttsty = ( + setcomponentcreateorder //0 Set Component create Order of + ); + +{ tsetcreateorderfo } + +constructor tsetcreateorderfo.create(const amodule: tcomponent; + const acurrentcompname: string); +var + int1: integer; +// str1: string; +begin + inherited create(nil); + caption:= c[ord(setcomponentcreateorder)]+' '+msestring(amodule.name); + fmodule:= amodule; + with amodule do begin + for int1:= 0 to componentcount - 1 do begin + with components[int1] do begin + if not hasparent or (csinline in componentstate) then begin + grid.appendrow([msestring(name),msestring(classname)]); + if acurrentcompname = name then begin + grid.row:=int1; + end; + end; + end; + end; + end; +end; + +procedure tsetcreateorderfo.formonclosequery(const sender: tcustommseform; + var amodalresult: modalresultty); +//var +// int1: integer; +// comp1: tcomponent; +begin + if amodalresult = mr_ok then begin + setcomponentorder(fmodule,grid[0].datalist.asarray); + designer.componentmodified(fmodule); + end; +end; + +end. diff --git a/mseide-msegui/apps/ide/setcreateorderform_mfm.pas b/mseide-msegui/apps/ide/setcreateorderform_mfm.pas new file mode 100644 index 0000000..bd712d5 --- /dev/null +++ b/mseide-msegui/apps/ide/setcreateorderform_mfm.pas @@ -0,0 +1,121 @@ +unit setcreateorderform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,setcreateorderform; + +const + objdata: record size: integer; data: array[0..2072] of byte end = + (size: 2073; data: ( + 84,80,70,48,17,116,115,101,116,99,114,101,97,116,101,111,114,100,101,114, + 102,111,16,115,101,116,99,114,101,97,116,101,111,114,100,101,114,102,111,8, + 98,111,117,110,100,115,95,120,3,223,0,8,98,111,117,110,100,115,95,121, + 3,8,1,9,98,111,117,110,100,115,95,99,120,3,125,1,9,98,111,117, + 110,100,115,95,99,121,3,84,1,26,99,111,110,116,97,105,110,101,114,46, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,27,99, + 111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,99,111,110,116,97,105,110,101,114,46,98, + 111,117,110,100,115,1,2,0,2,0,3,125,1,3,84,1,0,7,111,112, + 116,105,111,110,115,11,13,102,111,95,99,108,111,115,101,111,110,101,115,99, + 15,102,111,95,97,117,116,111,114,101,97,100,115,116,97,116,16,102,111,95, + 97,117,116,111,119,114,105,116,101,115,116,97,116,10,102,111,95,115,97,118, + 101,112,111,115,13,102,111,95,115,97,118,101,122,111,114,100,101,114,12,102, + 111,95,115,97,118,101,115,116,97,116,101,0,8,115,116,97,116,102,105,108, + 101,7,9,115,116,97,116,102,105,108,101,49,12,111,110,99,108,111,115,101, + 113,117,101,114,121,7,16,102,111,114,109,111,110,99,108,111,115,101,113,117, + 101,114,121,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6, + 8,116,109,115,101,102,111,114,109,0,11,116,115,116,114,105,110,103,103,114, + 105,100,4,103,114,105,100,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,8,98,111,117,110,100,115,95,120,2,0,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,125, + 1,9,98,111,117,110,100,115,95,99,121,3,50,1,7,97,110,99,104,111, + 114,115,11,6,97,110,95,116,111,112,9,97,110,95,98,111,116,116,111,109, + 0,11,111,112,116,105,111,110,115,103,114,105,100,11,12,111,103,95,99,111, + 108,115,105,122,105,110,103,12,111,103,95,114,111,119,109,111,118,105,110,103, + 15,111,103,95,107,101,121,114,111,119,109,111,118,105,110,103,19,111,103,95, + 102,111,99,117,115,99,101,108,108,111,110,101,110,116,101,114,20,111,103,95, + 99,111,108,99,104,97,110,103,101,111,110,116,97,98,107,101,121,10,111,103, + 95,119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112,117, + 112,17,111,103,95,109,111,117,115,101,115,99,114,111,108,108,99,111,108,0, + 14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,2,16,100,97, + 116,97,99,111,108,115,46,111,112,116,105,111,110,115,11,11,99,111,95,114, + 101,97,100,111,110,108,121,14,99,111,95,102,111,99,117,115,115,101,108,101, + 99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,15,99,111,95,112, + 114,111,112,111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,115, + 116,97,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114, + 111,119,0,14,100,97,116,97,99,111,108,115,46,105,116,101,109,115,14,1, + 5,119,105,100,116,104,3,165,0,7,111,112,116,105,111,110,115,11,11,99, + 111,95,114,101,97,100,111,110,108,121,14,99,111,95,102,111,99,117,115,115, + 101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,15,99, + 111,95,112,114,111,112,111,114,116,105,111,110,97,108,12,99,111,95,115,97, + 118,101,115,116,97,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111, + 108,108,114,111,119,0,10,118,97,108,117,101,102,97,108,115,101,6,1,48, + 9,118,97,108,117,101,116,114,117,101,6,1,49,0,1,5,119,105,100,116, + 104,3,159,0,7,111,112,116,105,111,110,115,11,11,99,111,95,114,101,97, + 100,111,110,108,121,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116, + 12,99,111,95,114,111,119,115,101,108,101,99,116,7,99,111,95,102,105,108, + 108,12,99,111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109,111, + 117,115,101,115,99,114,111,108,108,114,111,119,0,11,111,112,116,105,111,110, + 115,101,100,105,116,11,14,115,99,111,101,95,117,110,100,111,111,110,101,115, + 99,14,115,99,111,101,95,101,97,116,114,101,116,117,114,110,15,115,99,111, + 101,95,97,117,116,111,115,101,108,101,99,116,27,115,99,111,101,95,97,117, + 116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107, + 20,115,99,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120, + 116,0,10,118,97,108,117,101,102,97,108,115,101,6,1,48,9,118,97,108, + 117,101,116,114,117,101,6,1,49,0,0,13,102,105,120,99,111,108,115,46, + 99,111,117,110,116,2,1,13,102,105,120,99,111,108,115,46,105,116,101,109, + 115,14,1,7,110,117,109,115,116,101,112,2,1,0,0,13,102,105,120,114, + 111,119,115,46,99,111,117,110,116,2,1,13,102,105,120,114,111,119,115,46, + 105,116,101,109,115,14,1,6,104,101,105,103,104,116,2,16,14,99,97,112, + 116,105,111,110,115,46,99,111,117,110,116,2,2,14,99,97,112,116,105,111, + 110,115,46,105,116,101,109,115,14,1,7,99,97,112,116,105,111,110,6,4, + 78,97,109,101,0,1,7,99,97,112,116,105,111,110,6,5,67,108,97,115, + 115,0,0,17,99,97,112,116,105,111,110,115,102,105,120,46,99,111,117,110, + 116,2,1,17,99,97,112,116,105,111,110,115,102,105,120,46,105,116,101,109, + 115,14,1,7,99,97,112,116,105,111,110,6,5,79,114,100,101,114,0,0, + 0,0,13,100,97,116,97,114,111,119,104,101,105,103,104,116,2,16,8,115, + 116,97,116,102,105,108,101,7,9,115,116,97,116,102,105,108,101,49,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,7,116,98,117, + 116,116,111,110,8,116,98,117,116,116,111,110,49,14,111,112,116,105,111,110, + 115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108, + 121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99, + 97,108,101,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110, + 100,115,95,120,3,254,0,8,98,111,117,110,100,115,95,121,3,56,1,9, + 98,111,117,110,100,115,95,99,120,2,58,9,98,111,117,110,100,115,95,99, + 121,2,20,7,97,110,99,104,111,114,115,11,8,97,110,95,114,105,103,104, + 116,9,97,110,95,98,111,116,116,111,109,0,5,115,116,97,116,101,11,10, + 97,115,95,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,100, + 101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,99,97,112,116,105, + 111,110,0,7,99,97,112,116,105,111,110,6,3,38,79,75,11,109,111,100, + 97,108,114,101,115,117,108,116,7,5,109,114,95,111,107,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,7,116,98,117,116,116,111, + 110,8,116,98,117,116,116,111,110,50,14,111,112,116,105,111,110,115,119,105, + 100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104, + 104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99,97,108,101, + 0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95, + 120,3,62,1,8,98,111,117,110,100,115,95,121,3,56,1,9,98,111,117, + 110,100,115,95,99,120,2,58,9,98,111,117,110,100,115,95,99,121,2,20, + 7,97,110,99,104,111,114,115,11,8,97,110,95,114,105,103,104,116,9,97, + 110,95,98,111,116,116,111,109,0,5,115,116,97,116,101,11,15,97,115,95, + 108,111,99,97,108,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,7,38, + 67,97,110,99,101,108,11,109,111,100,97,108,114,101,115,117,108,116,7,9, + 109,114,95,99,97,110,99,101,108,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,14,0,0,9,116,115,116,97,116,102,105,108,101,9,115,116, + 97,116,102,105,108,101,49,8,102,105,108,101,110,97,109,101,6,17,115,101, + 116,116,97,98,111,114,100,101,114,102,111,46,115,116,97,7,111,112,116,105, + 111,110,115,11,10,115,102,111,95,109,101,109,111,114,121,0,4,108,101,102, + 116,2,104,3,116,111,112,3,136,0,0,0,16,116,115,116,114,105,110,103, + 99,111,110,116,97,105,110,101,114,1,99,12,115,116,114,105,110,103,115,46, + 100,97,116,97,1,6,29,83,101,116,32,67,111,109,112,111,110,101,110,116, + 32,99,114,101,97,116,101,32,79,114,100,101,114,32,111,102,0,4,108,101, + 102,116,2,40,3,116,111,112,2,40,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tsetcreateorderfo,''); +end. diff --git a/mseide-msegui/apps/ide/settaborderform.mfm b/mseide-msegui/apps/ide/settaborderform.mfm new file mode 100644 index 0000000..e60fa5d --- /dev/null +++ b/mseide-msegui/apps/ide/settaborderform.mfm @@ -0,0 +1,162 @@ +object settaborderfo: tsettaborderfo + optionswidget = [ow_arrowfocus, ow_subfocus, ow_destroywidgets, ow_hinton] + bounds_x = 471 + bounds_y = 402 + bounds_cx = 292 + bounds_cy = 205 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 292 + 205 + ) + options = [fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos] + statfile = statfile1 + caption = 'Set Tab Order' + oneventloopstart = formonloaded + onclosequery = formonclosequery + onmouseevent = formmouseevent + moduleclassname = 'tmseform' + object grid: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + frame.localprops = [] + frame.localprops1 = [] + bounds_x = 0 + bounds_y = 29 + bounds_cx = 290 + bounds_cy = 150 + bounds_cymin = 100 + anchors = [an_left, an_top, an_right, an_bottom] + optionsgrid = [og_rowmoving, og_keyrowmoving, og_focuscellonenter, og_colchangeontabkey, og_autopopup] + fixcols.count = 1 + fixcols.items = < + item + width = 32 + numstep = 1 + options = [fco_mousefocus] + end> + datacols.count = 2 + datacols.items = < + item[wname] + colorselect = -1879048185 + width = 201 + options = [co_readonly, co_focusselect, co_fill, co_savevalue, co_savestate] + widgetname = 'wname' + dataclass = tgridmsestringdatalist + end + item[windex] + options = [co_invisible, co_savevalue, co_savestate] + widgetname = 'windex' + dataclass = tgridintegerdatalist + end> + datarowheight = 18 + onrowsmoved = gridonrowsmoved + oncellevent = gridoncellevent + reffontheight = 16 + object wname: tstringedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + color = -1879048185 + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 201 + bounds_cy = 18 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter] + reffontheight = 16 + end + object windex: tintegeredit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 2 + visible = False + bounds_x = 202 + bounds_y = 0 + bounds_cx = 50 + bounds_cy = 18 + optionsedit1 = [oe1_savevalue] + reffontheight = 16 + end + end + object ok: tbutton + taborder = 4 + bounds_x = 37 + bounds_y = 183 + bounds_cx = 47 + bounds_cy = 20 + anchors = [an_left, an_bottom] + state = [as_default, as_localdefault, as_localcaption] + caption = 'OK' + modalresult = mr_ok + end + object cancel: tbutton + taborder = 5 + bounds_x = 92 + bounds_y = 183 + bounds_cx = 47 + bounds_cy = 20 + anchors = [an_left, an_bottom] + state = [as_localcaption] + caption = 'Cancel' + modalresult = mr_cancel + end + object mousetaborder: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.captionpos = cp_right + frame.localprops = [] + frame.localprops1 = [] + taborder = 1 + bounds_x = 3 + bounds_y = 4 + bounds_cx = 60 + onsetvalue = mousetaborderonsetvalue + reffontheight = 16 + end + object start: tbutton + taborder = 2 + bounds_x = 69 + bounds_y = 4 + bounds_cx = 50 + bounds_cy = 20 + state = [as_localcaption, as_localonexecute] + caption = '&Start' + onexecute = startexecute + end + object stop: tbutton + taborder = 3 + bounds_x = 125 + bounds_y = 4 + bounds_cx = 48 + bounds_cy = 20 + state = [as_disabled, as_localdisabled, as_localcaption, as_localonexecute] + caption = 'St&op' + onexecute = stopexecute + end + object tlabel1: tlabel + taborder = 6 + bounds_x = 176 + bounds_y = 5 + bounds_cx = 63 + bounds_cy = 16 + caption = 'Mouse click' + reffontheight = 16 + end + object statfile1: tstatfile + filename = 'settaborderfo.sta' + options = [sfo_memory] + left = 80 + top = 8 + end +end diff --git a/mseide-msegui/apps/ide/settaborderform.pas b/mseide-msegui/apps/ide/settaborderform.pas new file mode 100644 index 0000000..24698f4 --- /dev/null +++ b/mseide-msegui/apps/ide/settaborderform.pas @@ -0,0 +1,259 @@ +{ MSEide Copyright (c) 1999-2013 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit settaborderform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + msetypes,mseforms,msegrids,msegui,msewidgetgrid,msedataedits,msesimplewidgets, + msedesigner, + mseevent,mseglob,mseguiglob,msestat,msestatfile,msegridsglob,msestrings; + +type + + tsettaborderfo = class(tmseform) + grid: twidgetgrid; + ok: tbutton; + cancel: tbutton; + start: tbutton; + stop: tbutton; + mousetaborder: tintegeredit; + statfile1: tstatfile; + tlabel1: tlabel; + windex: tintegeredit; + wname: tstringedit; + procedure formmouseevent(const sender: twidget; var info: mouseeventinfoty); + procedure formonclosequery(const sender: tcustommseform; + var amodalresult: modalresultty); + procedure formonloaded(const sender: TObject); + procedure gridoncellevent(const sender: TObject; var info: celleventinfoty); + procedure mousetaborderonsetvalue(const sender: TObject; var avalue: Integer; var accept: Boolean); + procedure startexecute(const sender: TObject); + procedure stopexecute(const sender: TObject); + procedure gridonrowsmoved(const sender: tcustomgrid; const fromindex: Integer; + const toindex: Integer; const acount: Integer); + private + fwidget: twidget; + fparent: twidget; + fchildren: widgetarty; + fdesigner: tdesigner; + fwidgetorder: boolean; //set Z-order instead of taborder + public + constructor create(awidget: twidget; adesigner: tdesigner; + const awidgetorder: boolean); + end; + +procedure settaborderdialog(const awidget: twidget; + const awidgetorder: boolean); + +implementation +uses + settaborderform_mfm,msegraphutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + twidget1 = class(twidget); + +procedure settaborderdialog(const awidget: twidget; + const awidgetorder: boolean); +var + fo: tsettaborderfo; +begin + fo:= tsettaborderfo.create(awidget,designer,awidgetorder); + try + fo.show(true); + finally + fo.Free; + end; +end; + + {tsettaborderfo} + +constructor tsettaborderfo.create(awidget: twidget; adesigner: tdesigner; + const awidgetorder: boolean); +begin + fwidget:= awidget; + fparent:= awidget.parentwidget; + fdesigner:= adesigner; + fwidgetorder:= awidgetorder; + inherited create(nil); + if fwidgetorder then begin + caption:= 'Set Widget Order'; + end; +end; + +procedure tsettaborderfo.formmouseevent(const sender: twidget; var info: mouseeventinfoty); +var + widget1: twidget; + int1,int2: integer; +begin + with info do begin + if (eventkind = ek_buttonpress) then begin + if stop.enabled and pointinrect(pos,paintrect) then begin +// stopexecute(nil); + end + else begin + if stop.enabled and (button = mb_left) and + (shiftstate * keyshiftstatesmask = []) then begin + widget1:= fparent.childatpos(translatewidgetpoint(pos,self,fparent),false); + if widget1 <> nil then begin + int2:= -1; + for int1:= 0 to high(fchildren) do begin + if widget1 = fchildren[int1] then begin + int2:= int1; + break; + end; + end; + if int2 >= 0 then begin + for int1:= 0 to high(fchildren) do begin + if windex[int1] = int2 then begin + grid.moverow(int1,mousetaborder.value); + break; + end; + end; + if mousetaborder.value = high(fchildren) then begin + stopexecute(nil); + end + else begin + mousetaborder.value:= mousetaborder.value + 1; + end; + grid.row:= mousetaborder.value; + end; + end; + end; + end; + end; + end; +end; + +procedure tsettaborderfo.formonclosequery(const sender: tcustommseform; + var amodalresult: modalresultty); +var + i1: integer; + ar1: widgetarty; +begin + if amodalresult = mr_ok then begin + if fwidgetorder then begin + setlength(ar1,grid.rowcount); + for i1:= 0 to grid.rowcount - 1 do begin + ar1[i1]:= fchildren[windex[i1]]; + end; + with twidget1(fparent.container) do begin + fwidgets:= ar1; + widgetregionchanged(nil); + end; + end + else begin + for i1:= 0 to grid.rowcount - 1 do begin + fchildren[windex[i1]].taborder:= i1; + end; + for i1:= 0 to high(fchildren) do begin + fdesigner.componentmodified(fchildren[i1]); + end; + end; + end; +end; + +procedure tsettaborderfo.formonloaded(const sender: TObject); +var + int1: integer; +begin + if fwidgetorder then begin + fchildren:= twidget1(fparent.container).fwidgets; + end + else begin + fchildren:= fparent.container.gettaborderedwidgets; + end; + grid.rowcount:= length(fchildren); + for int1:= 0 to high(fchildren) do begin + wname[int1]:= msestring(fchildren[int1].Name); + windex[int1]:= int1; + if wname[int1] = msestring(fwidget.name) then begin + grid.row:= int1; + end; + end; + mousetaborder.valuemax:= high(fchildren); +end; + + +procedure tsettaborderfo.stopexecute(const sender: TObject); +begin + start.enabled:= true; + if stop.focused then begin + start.setfocus; + end; + stop.enabled:= false; + window.releasemouse; +end; + +procedure tsettaborderfo.gridoncellevent(const sender: TObject; + var info: celleventinfoty); +var + w1: twidget; +begin + if info.eventkind = cek_enter then begin + mousetaborder.value:= info.newcell.row; + end + else begin + if start.enabled and iscellclick(info,[ccr_dblclick,ccr_nokeyreturn]) then begin + w1:= fchildren[windex[info.cell.row]]; + if w1.childrencount > 0 then begin + settaborderdialog(w1[0],fwidgetorder); + end; + end; + end; +end; + +procedure tsettaborderfo.gridonrowsmoved(const sender: tcustomgrid; + const fromindex: Integer; const toindex: Integer; const acount: Integer); +begin + mousetaborder.value:= toindex; +end; + +procedure tsettaborderfo.mousetaborderonsetvalue(const sender: TObject; var avalue: Integer; var accept: Boolean); +begin + grid.row:= avalue; +end; + +procedure tsettaborderfo.startexecute(const sender: TObject); +begin + stop.enabled:= true; + if start.focused then begin + stop.setfocus; + end; + start.enabled:= false; + window.capturemouse; +// capturemouse(true); +end; + +end. diff --git a/mseide-msegui/apps/ide/settaborderform_mfm.pas b/mseide-msegui/apps/ide/settaborderform_mfm.pas new file mode 100644 index 0000000..64c63d8 --- /dev/null +++ b/mseide-msegui/apps/ide/settaborderform_mfm.pas @@ -0,0 +1,193 @@ +unit settaborderform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,settaborderform; + +const + objdata: record size: integer; data: array[0..3519] of byte end = + (size: 3520; data: ( + 84,80,70,48,14,116,115,101,116,116,97,98,111,114,100,101,114,102,111,13, + 115,101,116,116,97,98,111,114,100,101,114,102,111,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,9,111,119,95,104,105,110,116, + 111,110,0,8,98,111,117,110,100,115,95,120,3,215,1,8,98,111,117,110, + 100,115,95,121,3,146,1,9,98,111,117,110,100,115,95,99,120,3,36,1, + 9,98,111,117,110,100,115,95,99,121,3,205,0,23,99,111,110,116,97,105, + 110,101,114,46,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,11,111, + 119,95,115,117,98,102,111,99,117,115,19,111,119,95,109,111,117,115,101,116, + 114,97,110,115,112,97,114,101,110,116,17,111,119,95,100,101,115,116,114,111, + 121,119,105,100,103,101,116,115,0,26,99,111,110,116,97,105,110,101,114,46, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,27,99, + 111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,99,111,110,116,97,105,110,101,114,46,98, + 111,117,110,100,115,1,2,0,2,0,3,36,1,3,205,0,0,7,111,112, + 116,105,111,110,115,11,13,102,111,95,99,108,111,115,101,111,110,101,115,99, + 15,102,111,95,97,117,116,111,114,101,97,100,115,116,97,116,16,102,111,95, + 97,117,116,111,119,114,105,116,101,115,116,97,116,10,102,111,95,115,97,118, + 101,112,111,115,0,8,115,116,97,116,102,105,108,101,7,9,115,116,97,116, + 102,105,108,101,49,7,99,97,112,116,105,111,110,6,13,83,101,116,32,84, + 97,98,32,79,114,100,101,114,16,111,110,101,118,101,110,116,108,111,111,112, + 115,116,97,114,116,7,12,102,111,114,109,111,110,108,111,97,100,101,100,12, + 111,110,99,108,111,115,101,113,117,101,114,121,7,16,102,111,114,109,111,110, + 99,108,111,115,101,113,117,101,114,121,12,111,110,109,111,117,115,101,101,118, + 101,110,116,7,14,102,111,114,109,109,111,117,115,101,101,118,101,110,116,15, + 109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,8,116,109,115, + 101,102,111,114,109,0,11,116,119,105,100,103,101,116,103,114,105,100,4,103, + 114,105,100,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,102,111,99,117,115, + 98,97,99,107,111,110,101,115,99,13,111,119,95,109,111,117,115,101,119,104, + 101,101,108,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116, + 115,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 0,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95, + 121,2,29,9,98,111,117,110,100,115,95,99,120,3,34,1,9,98,111,117, + 110,100,115,95,99,121,3,150,0,12,98,111,117,110,100,115,95,99,121,109, + 105,110,2,100,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102, + 116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,9,97,110, + 95,98,111,116,116,111,109,0,11,111,112,116,105,111,110,115,103,114,105,100, + 11,12,111,103,95,114,111,119,109,111,118,105,110,103,15,111,103,95,107,101, + 121,114,111,119,109,111,118,105,110,103,19,111,103,95,102,111,99,117,115,99, + 101,108,108,111,110,101,110,116,101,114,20,111,103,95,99,111,108,99,104,97, + 110,103,101,111,110,116,97,98,107,101,121,12,111,103,95,97,117,116,111,112, + 111,112,117,112,0,13,102,105,120,99,111,108,115,46,99,111,117,110,116,2, + 1,13,102,105,120,99,111,108,115,46,105,116,101,109,115,14,1,5,119,105, + 100,116,104,2,32,7,110,117,109,115,116,101,112,2,1,7,111,112,116,105, + 111,110,115,11,14,102,99,111,95,109,111,117,115,101,102,111,99,117,115,0, + 0,0,14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,2,14, + 100,97,116,97,99,111,108,115,46,105,116,101,109,115,14,7,5,119,110,97, + 109,101,1,11,99,111,108,111,114,115,101,108,101,99,116,4,7,0,0,144, + 5,119,105,100,116,104,3,201,0,7,111,112,116,105,111,110,115,11,11,99, + 111,95,114,101,97,100,111,110,108,121,14,99,111,95,102,111,99,117,115,115, + 101,108,101,99,116,7,99,111,95,102,105,108,108,12,99,111,95,115,97,118, + 101,118,97,108,117,101,12,99,111,95,115,97,118,101,115,116,97,116,101,0, + 10,119,105,100,103,101,116,110,97,109,101,6,5,119,110,97,109,101,9,100, + 97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116, + 114,105,110,103,100,97,116,97,108,105,115,116,0,7,6,119,105,110,100,101, + 120,1,7,111,112,116,105,111,110,115,11,12,99,111,95,105,110,118,105,115, + 105,98,108,101,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111, + 95,115,97,118,101,115,116,97,116,101,0,10,119,105,100,103,101,116,110,97, + 109,101,6,6,119,105,110,100,101,120,9,100,97,116,97,99,108,97,115,115, + 7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105, + 115,116,0,0,13,100,97,116,97,114,111,119,104,101,105,103,104,116,2,18, + 11,111,110,114,111,119,115,109,111,118,101,100,7,15,103,114,105,100,111,110, + 114,111,119,115,109,111,118,101,100,11,111,110,99,101,108,108,101,118,101,110, + 116,7,15,103,114,105,100,111,110,99,101,108,108,101,118,101,110,116,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,11,116,115,116,114, + 105,110,103,101,100,105,116,5,119,110,97,109,101,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 5,99,111,108,111,114,4,7,0,0,144,12,102,114,97,109,101,46,108,101, + 118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108, + 105,101,110,116,4,2,0,0,128,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102, + 114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111, + 114,100,101,114,2,1,7,118,105,115,105,98,108,101,8,8,98,111,117,110, + 100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,120,3,201,0,9,98,111,117,110,100,115,95,99,121, + 2,18,12,111,112,116,105,111,110,115,101,100,105,116,49,11,13,111,101,49, + 95,115,97,118,101,118,97,108,117,101,0,11,111,112,116,105,111,110,115,101, + 100,105,116,11,11,111,101,95,114,101,97,100,111,110,108,121,12,111,101,95, + 117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117, + 101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108, + 14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101, + 97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108, + 101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99, + 117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,0, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,12,116, + 105,110,116,101,103,101,114,101,100,105,116,6,119,105,110,100,101,120,14,111, + 112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102, + 111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,13,111,112,116,105, + 111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102, + 111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95, + 97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102, + 111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115, + 111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116, + 115,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,2,0,0,128, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,2,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,202,0,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2, + 50,9,98,111,117,110,100,115,95,99,121,2,18,12,111,112,116,105,111,110, + 115,101,100,105,116,49,11,13,111,101,49,95,115,97,118,101,118,97,108,117, + 101,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0, + 0,7,116,98,117,116,116,111,110,2,111,107,8,116,97,98,111,114,100,101, + 114,2,4,8,98,111,117,110,100,115,95,120,2,37,8,98,111,117,110,100, + 115,95,121,3,183,0,9,98,111,117,110,100,115,95,99,120,2,47,9,98, + 111,117,110,100,115,95,99,121,2,20,7,97,110,99,104,111,114,115,11,7, + 97,110,95,108,101,102,116,9,97,110,95,98,111,116,116,111,109,0,5,115, + 116,97,116,101,11,10,97,115,95,100,101,102,97,117,108,116,15,97,115,95, + 108,111,99,97,108,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,2,79, + 75,11,109,111,100,97,108,114,101,115,117,108,116,7,5,109,114,95,111,107, + 0,0,7,116,98,117,116,116,111,110,6,99,97,110,99,101,108,8,116,97, + 98,111,114,100,101,114,2,5,8,98,111,117,110,100,115,95,120,2,92,8, + 98,111,117,110,100,115,95,121,3,183,0,9,98,111,117,110,100,115,95,99, + 120,2,47,9,98,111,117,110,100,115,95,99,121,2,20,7,97,110,99,104, + 111,114,115,11,7,97,110,95,108,101,102,116,9,97,110,95,98,111,116,116, + 111,109,0,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99, + 97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,6,67,97,110, + 99,101,108,11,109,111,100,97,108,114,101,115,117,108,116,7,9,109,114,95, + 99,97,110,99,101,108,0,0,12,116,105,110,116,101,103,101,114,101,100,105, + 116,13,109,111,117,115,101,116,97,98,111,114,100,101,114,13,111,112,116,105, + 111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102, + 111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95, + 97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102, + 111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115, + 111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116, + 115,0,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7, + 8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,1,8, + 98,111,117,110,100,115,95,120,2,3,8,98,111,117,110,100,115,95,121,2, + 4,9,98,111,117,110,100,115,95,99,120,2,60,10,111,110,115,101,116,118, + 97,108,117,101,7,23,109,111,117,115,101,116,97,98,111,114,100,101,114,111, + 110,115,101,116,118,97,108,117,101,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,16,0,0,7,116,98,117,116,116,111,110,5,115,116,97,114, + 116,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95, + 120,2,69,8,98,111,117,110,100,115,95,121,2,4,9,98,111,117,110,100, + 115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,20,5,115, + 116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111, + 110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0, + 7,99,97,112,116,105,111,110,6,6,38,83,116,97,114,116,9,111,110,101, + 120,101,99,117,116,101,7,12,115,116,97,114,116,101,120,101,99,117,116,101, + 0,0,7,116,98,117,116,116,111,110,4,115,116,111,112,8,116,97,98,111, + 114,100,101,114,2,3,8,98,111,117,110,100,115,95,120,2,125,8,98,111, + 117,110,100,115,95,121,2,4,9,98,111,117,110,100,115,95,99,120,2,48, + 9,98,111,117,110,100,115,95,99,121,2,20,5,115,116,97,116,101,11,11, + 97,115,95,100,105,115,97,98,108,101,100,16,97,115,95,108,111,99,97,108, + 100,105,115,97,98,108,101,100,15,97,115,95,108,111,99,97,108,99,97,112, + 116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117, + 116,101,0,7,99,97,112,116,105,111,110,6,5,83,116,38,111,112,9,111, + 110,101,120,101,99,117,116,101,7,11,115,116,111,112,101,120,101,99,117,116, + 101,0,0,6,116,108,97,98,101,108,7,116,108,97,98,101,108,49,8,116, + 97,98,111,114,100,101,114,2,6,8,98,111,117,110,100,115,95,120,3,176, + 0,8,98,111,117,110,100,115,95,121,2,5,9,98,111,117,110,100,115,95, + 99,120,2,63,9,98,111,117,110,100,115,95,99,121,2,16,7,99,97,112, + 116,105,111,110,6,11,77,111,117,115,101,32,99,108,105,99,107,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,9,116,115,116,97, + 116,102,105,108,101,9,115,116,97,116,102,105,108,101,49,8,102,105,108,101, + 110,97,109,101,6,17,115,101,116,116,97,98,111,114,100,101,114,102,111,46, + 115,116,97,7,111,112,116,105,111,110,115,11,10,115,102,111,95,109,101,109, + 111,114,121,0,4,108,101,102,116,2,80,3,116,111,112,2,8,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tsettaborderfo,''); +end. diff --git a/mseide-msegui/apps/ide/skeletons.pas b/mseide-msegui/apps/ide/skeletons.pas new file mode 100644 index 0000000..5aae1f4 --- /dev/null +++ b/mseide-msegui/apps/ide/skeletons.pas @@ -0,0 +1,84 @@ +{ MSEide Copyright (c) 1999-2006 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit skeletons; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msestream,mseclasses; + +procedure programskeleton(const stream: ttextstream; const name: string); +procedure unitskeleton(const stream: ttextstream; const name: string); +procedure formskeleton(const stream: ttextstream; const unitname,formname,ancestor: string); + +implementation +const + defaults = compilerdefaults; + +procedure programskeleton(const stream: ttextstream; const name: string); +begin + with stream do begin + writeln('program '+name+';'); + writeln(defaults); + writeln('{$ifdef FPC}'); + writeln(' {$ifdef mswindows}{$apptype gui}{$endif}'); + writeln('{$endif}'); + + writeln('uses'); + writeln( +' {$ifdef FPC}{$ifdef unix}cthreads,{$endif}{$endif}msegui,mseforms,main;'); + writeln('begin'); + writeln(' application.createform(tmainfo,mainfo);'); + writeln(' application.run;'); + writeln('end.'); + end; +end; + +procedure unitskeleton(const stream: ttextstream; const name: string); +begin + with stream do begin + writeln('unit '+name+';'); + writeln(defaults); + writeln('interface'); + writeln('implementation'); + writeln('end.'); + end; +end; + +procedure formskeleton(const stream: ttextstream; const unitname,formname,ancestor: string); +begin + with stream do begin + writeln('unit '+unitname+';'); + writeln(defaults); + writeln('interface'); + writeln('uses'); + writeln(' msegui,mseclasses,mseforms,msedatamodules;'); + writeln(''); + writeln('type'); + writeln(' t'+formname+' = class('+ancestor+')'); + writeln(' end;'); + writeln('var'); + writeln(' '+formname+': '+'t'+formname+';'); + writeln('implementation'); + writeln('uses'); + writeln(' '+unitname+'_mfm;'); + writeln('end.'); + end; +end; + +end. diff --git a/mseide-msegui/apps/ide/sourceform.mfm b/mseide-msegui/apps/ide/sourceform.mfm new file mode 100644 index 0000000..ca3a70a --- /dev/null +++ b/mseide-msegui/apps/ide/sourceform.mfm @@ -0,0 +1,568 @@ +object sourcefo: tsourcefo + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_floatbutton, go_topbutton, go_backgroundbutton, go_nolockbutton, go_buttonhints] + onenter = enterexe + onactivate = enterexe + visible = False + bounds_x = 98 + bounds_y = 158 + bounds_cx = 433 + bounds_cy = 327 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.frame.localprops = [] + container.frame.localprops1 = [] + container.frame.sbhorz.options = [sbo_moveauto, sbo_showauto] + container.frame.sbvert.options = [sbo_moveauto, sbo_showauto] + container.bounds = ( + 0 + 0 + 423 + 327 + ) + dragdock.splitter_size = 0 + dragdock.caption = 'Source' + dragdock.optionsdock = [od_savepos, od_canmove, od_canfloat, od_candock, od_propsize, od_captionhint, od_childicons] + options = [fo_savepos, fo_savestate] + statfile = mainfo.projectstatfile + caption = '' + icon.transparentcolor = -2147483642 + icon.options = [bmo_masked] + icon.image = { + 00000000020000001800000018000000F4060000000000000000000000000000 + 0000000000000000000000000000000000000000D0D0D0198888880D82888801 + 88888801D0D0D00988888801B3F8FE01B6F8FE01B9F9FE01BCFAFE01BFFAFE01 + C2FBFE01C6FBFE01C9FCFE01CCFDFE01CFFDFE01D2FEFE01D5FEFE017F878701 + 9FC5C80188888801D0D0D00888888801B3F8FE01B6F8FE01B9F9FE01BCFAFE01 + BFFAFE01C2FBFE01C6FBFE01C9FCFE01CCFDFE01CFFDFE01D2FEFE01D5FEFE01 + 83898A01C6F9FF019EC5C80188888801D0D0D00788888801B3F8FE01B6F8FE01 + B9F9FE01BCFAFE01BFFAFE01C2FBFE01C6FBFE01C9FCFE01CCFDFE01CFFDFE01 + D2FEFE01D5FEFE01858A8A01E2FCFF01C5F9FF019EC5C80188888801D0D0D006 + 88888801B3F8FE01B6F8FE01B9F9FE01BCFAFE01BFFAFE01C2FBFE01C6FBFE01 + C9FCFE01CCFDFE01CFFDFE01D2FEFE01D5FEFE0182898A01FEFEFF01E1FCFF01 + C3F9FF019EC5C80188888801D0D0D00588888801B3F8FE01B6F8FE01B8F7FC01 + 5B797B01BFFAFE0182A8AA01C1F4F701C7F9FB01C4F3F401CDFAFB018EABAB01 + D5FEFE017F898A01DFFCFF01FCFEFF01DFFCFF01C2F9FF019DC4C80188888801 + D0D0D00488888801B3F8FE01B6F8FE0188B7BA016687890197C5C80159737501 + 6F8D8E017592930190B3B3017A95950160747401D5FEFE017C898A01BEF9FF01 + E1FCFF01FAFEFF01DDFCFF01C0F9FF019DC4C80188888801D0D0D00388888801 + B3F8FE01B6F8FE016E949701A4DBDE016D8F91015B7678017C9D9F0180A0A101 + 86A6A6017D99990162777701D5FEFE0179898A019EF6FF01C0F9FF01E3FCFF01 + F9FEFF01DCFBFF01BEF9FF019DC4C80188888801D0D0D00288888801B3F8FE01 + B6F8FE01B9F9FE01BCFAFE01BFFAFE01C2FBFE01C6FBFE01C9FCFE01CCFDFE01 + CFFDFE01D2FEFE01D5FEFE018296970178898A017A898A017C898A017E898A02 + 7A898A017786870181888801D0D0D00288888801B3F8FE01B6F8FE01B9F9FE01 + BCFAFE01BFFAFE01C2FBFE01C6FBFE01C9FCFE01C6F5F601CEFCFD01CCF7F701 + D0F8F801CCFAFB01BBF6F801B0FAFE019CEFF50193F6FE0184F4FE0175F3FE01 + 66F1FE0188888801D0D0D00288888801B3F8FE01B6F8FE01B9F9FE01BCFAFE01 + BFFAFE01C2FBFE01C6FBFE01C3F4F601576C6D01728C8C01748C8C019DBBBB01 + 7E9B9B016A8C8D016A979901476C6F0185DFE60184F4FE0175F3FE0166F1FE01 + 88888801D0D0D00288888801B3F8FE01B6F8FE01B9F9FE01BCFAFE01BFFAFE01 + C2FBFE01C6FBFE01C4F6F8016A84840192B3B3017E98980193AFAF017E9B9B01 + 6788890174A5A701619598018BE8F00184F4FE0175F3FE0166F1FE0188888801 + D0D0D00288888801B3F8FE01B6F8FE01B9F9FE01BCFAFE01BFFAFE01C2FBFE01 + C6FBFE01C9FCFE01CCFDFE01CFFDFE01D2FEFE01D5FEFE01CEFDFE01BFFCFE01 + B0FAFE01A2F8FE0193F6FE0184F4FE0175F3FE0166F1FE0188888801D0D0D002 + 88888801B3F8FE01B6F8FE01B9F9FE01BCFAFE01BFFAFE01C2FBFE01C6FBFE01 + C9FCFE01C3F2F30193B4B401CDF8F801CEF6F601CAF8F901B8F3F501AAF1F501 + 9FF3F9018EEEF60183F3FD0175F3FE0166F1FE0188888801D0D0D00288888801 + B3F8FE01B6F8FE01B9F9FE01BCFAFE01BFFAFE01C2FBFE01C6FBFE01BCECEE01 + 759191016F888801778F8F0164787801748E8E0181AAAB0177A9AB015D8E9101 + 3F696D014783880175F3FE0166F1FE0188888801D0D0D00288888801B3F8FE01 + B6F8FE01B9F9FE01BCFAFE01BFFAFE01C2FBFE01C6FBFE01BEEEF001738F8F01 + 748E8E01839E9E0163777701809E9E01A0D2D40177AAAC015D8E91014D808401 + 5CA9B00175F3FE0166F1FE0188888801D0D0D00288888801B3F8FE01B6F8FE01 + B9F9FE01BCFAFE01BFFAFE01C2FBFE01C6FBFE01C9FCFE01CCFDFE01CFFDFE01 + 96B5B50189A3A301CEFDFE01ADE4E60177A9AB017EC2C60193F6FE0184F4FE01 + 75F3FE0166F1FE0188888801D0D0D00288888801B3F8FE01B6F8FE01B9F9FE01 + B5F1F501A3D6D901C2FBFE01A7D4D60188AAAB01B5E0E101A1C4C501C1E9E901 + D5FEFE01CEFDFE01BFFCFE01B0FAFE01A2F8FE0193F6FE0184F4FE0175F3FE01 + 66F1FE0188888801D0D0D00288888801B3F8FE01B6F8FE016E949701516C6E01 + 74989A017EA2A401789899017D9C9D015B71720194B5B501BDE5E501D5FEFE01 + CEFDFE01BFFCFE01B0FAFE01A2F8FE0193F6FE0184F4FE0175F3FE0166F1FE01 + 88888801D0D0D00288888801B3F8FE01B6F8FE0178A2A50171969801799EA001 + 82A8AA0178999A017D9C9D017D9B9B017F9C9C01BDE5E501D5FEFE01CEFDFE01 + BFFCFE01B0FAFE01A2F8FE0193F6FE0184F4FE0175F3FE0166F1FE0188888801 + D0D0D00288888801B3F8FE01B6F8FE01B9F9FE01BCFAFE01BFFAFE01C2FBFE01 + C6FBFE01C9FCFE01CCFDFE01CFFDFE01D2FEFE01D5FEFE01CEFDFE01BFFCFE01 + B0FAFE01A2F8FE0193F6FE0184F4FE0175F3FE0166F1FE0188888801D0D0D002 + 88888816D0D0D01900000008FEFF0008FEFF01BFFEFF0308FEFF0700FEFF0F08 + FEFF1F02FEFF3FC0FEFF7F00FEFF7F08FEFF7F00FEFF7F08FEFF7F08FEFF7F08 + FEFF7FBFFEFF7F08FEFF7F00FEFF7F02FEFF7F08FEFF7F00FEFF7F00FEFF7FBF + FEFF7F0000000008 + } + onclosequery = sourcefoonclosequery + onidle = formonidle + moduleclassname = 'tdockform' + object tabwidget: ttabwidget + bounds_x = 0 + bounds_y = 0 + bounds_cx = 423 + bounds_cy = 327 + anchors = [] + popupmenu = formpopup + onactivepagechanged = tabwidgetonactivepagechanged + onpageremoved = tabwidgetpageremoved + tab_options = [tabo_dragsource, tabo_dragdest, tabo_vertical, tabo_opposite, tabo_tabsizing, tabo_dblclickedtabfirst, tabo_hintclippedtext] + tab_frame.buttonpos = sbp_top + tab_frame.buttonslast = True + tab_frame.buttonsvisible = [sk_right, sk_up, sk_left, sk_down, sk_first, sk_last] + tab_frame.localprops = [frl_optionsskin] + tab_frame.localprops1 = [] + tab_textflags = [tf_ycentered] + tab_sizemin = 60 + tab_size = 60 + tab_optionswidget1 = [] + object tstockglyphbutton1: tstockglyphbutton + optionswidget = [ow_destroywidgets, ow_disabledhint, ow_timedhint] + taborder = 2 + hint = 'Step back in code navigation' + onshowhint = stephintev + bounds_x = 383 + bounds_y = 0 + bounds_cx = 20 + bounds_cy = 20 + anchors = [an_top, an_right] + state = [as_disabled, as_localimagelist, as_localimagenr, as_localcolorglyph, as_localhint, as_localonexecute] + glyph = stg_arrowleft + action = navigbackact + colorglyph = -1610612727 + onexecute = navigback + end + object tstockglyphbutton2: tstockglyphbutton + optionswidget = [ow_destroywidgets, ow_disabledhint, ow_timedhint] + taborder = 1 + hint = 'Step forward in code navigation' + onshowhint = stephintev + bounds_x = 403 + bounds_y = 0 + bounds_cx = 20 + bounds_cy = 20 + anchors = [an_top, an_right] + state = [as_disabled, as_localimagelist, as_localimagenr, as_localcolorglyph, as_localhint] + glyph = stg_arrowright + action = navigforwardact + colorglyph = -1610612727 + end + end + object syntaxpainter: tsyntaxpainter + defdefs.data = ( + ( + '*.pas' + 'pas.sdef' + ) + ) + left = 32 + top = 64 + end + object imagelist: timagelist + count = 14 + left = 33 + top = 93 + image = { + 00000000020000004000000040000000B80B0000000000000000000000000000 + 0000000000000000000000000000000000000000FFFFFFAA00000001FFFFFF3E + 00000003FFFFFF1D0000FF03FFFFFF0D0000FF03FFFFFF0D00000003FFFFFF1C + 0000FF05FFFFFF0B0000FF01FFFFFF030000FF01FFFFFF0C00000003FFFFFF07 + FF000002FFFFFF120000FF07FFFFFF090000FF01FFFFFF050000FF01FFFFFF0B + 00000003FFFFFF06FF000001FFFF0001FF000002FFFFFF110000FF07FFFFFF09 + 0000FF01FFFFFF050000FF01FFFFFF0B00000003FFFFFF06FF000004FFFFFF11 + 0000FF07FFFFFF090000FF01FFFFFF050000FF01FFFFFF0B00000003FFFFFF07 + FF000002FFFFFF130000FF05FFFFFF0B0000FF01FFFFFF030000FF01FFFFFF0D + 00000001FFFFFF1E0000FF03FFFFFF0D0000FF03FFFFFF4E00000001FFFFFF3E + 00000003FFFFFF3E00000001FFFFFF9A00D90005FFFFFF0B00D90005FFFFFF0B + 00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B + 00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B + 00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B + 00D90005FFFFFF0B00D90005FFFFFF0B00C50001003500010020000100350001 + 00C50001FFFFFF0B00C400010008000100D90003FFFFFF0B003E000100120001 + 001E00010031000100B00001FFFFFF0B009000010036000100220001001F0001 + 00970001FFFFFF0B005800010080000100D900010085000100590001FFFFFF0B + 001600010007000100D90003FFFFFF0B0036000100C1000100D9000100A20001 + 00260001FFFFFF0B00D9000300B6000100140001FFFFFF0B001F000100C80001 + 00D9000100CC000100200001FFFFFF0B00D90001000D000100D90003FFFFFF0B + 00D9000300D60001000E0001FFFFFF0B00D9000200D600010084000100440001 + FFFFFF0B000C000100D90003000F0001FFFFFF0B00D90001000D000100D90003 + FFFFFF0B00D9000300970001003B0001FFFFFF0B00D9000200180001003D0001 + 00C30001FFFFFF0B000C000100D90003000E0001FFFFFF0B00D90001000D0001 + 00D90003FFFFFF0B00D9000200B90001001B000100AE0001FFFFFF0B00D90002 + 00D700010084000100310001FFFFFF0B001F000100CB000100D9000100CC0001 + 001F0001FFFFFF0B00D90001000D000100D90003FFFFFF0B00D9000100A80001 + 0021000100A2000100D90001FFFFFF0B00D9000300D80001000E0001FFFFFF0B + 005800010084000100D900010086000100590001FFFFFF0B00D90001000D0001 + 00D90003FFFFFF0B00800001002C000100BB000100D90002FFFFFF0B00420001 + 00C1000100D900010091000100370001FFFFFF0B00C500010034000100200001 + 0035000100C50001FFFFFF0B002B000100030001002B000200D90001FFFFFF0B + 00000001001A000100210003FFFFFF0B0043000100120001001F000100380001 + 00BE0001FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B + 00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B + 00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B + 00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B + 00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B + 00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B + 00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B + 00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B + 00D90005FFFFFF0B00D90002009700010004000100D90001FFFFFF0B00070001 + 002100020027000100D90001FFFFFF0B00D90001007B00010021000200D30001 + FFFFFF0B0021000400030001FFFFFF0B00D9000100BF00010030000100080001 + 00D90001FFFFFF0B0009000100D90004FFFFFF0B009300010035000100CE0001 + 00D90002FFFFFF0B00D9000300B40001002B0001FFFFFF0B00D5000100360001 + 00B100010009000100D90001FFFFFF0B0009000100D90004FFFFFF0B00390001 + 00A9000100D90003FFFFFF0B00D900030049000100920001FFFFFF0B005F0001 + 0081000100D900010009000100D90001FFFFFF0B0009000100200001002C0001 + 00AA000100D90001FFFFFF0B0013000100470001002200010030000100B20001 + FFFFFF0B00D9000200B700010024000100D70001FFFFFF0AB8B8B801004C0001 + 00D900020009000100D90001FFFFFF0B00D5000100D9000100A9000100270001 + 00D90001FFFFFF0B000B000100BF000100D9000100990001002B0001FFFFFF0B + 00D90002004D00010089000100D90001FFFFFF0A95959501001E000100210002 + 0001000100210001F9F9F901FFFFFF0A00D9000200D80001000E000100D90001 + FFFFFF0B001A000100D1000100D9000100D80001000E0001FFFFFF0B00D90001 + 00BA0001001F000100D6000100D90001FFFFFF0B00D900030009000100D90001 + FFFFFF0B008D000100D90001009A00010034000100D90001FFFFFF0B00560001 + 007F000100D90001009D000100370001FFFFFF0B00D900010051000100810001 + 00D90002FFFFFF0B00D900030009000100D90001FFFFFF0B00360001001E0001 + 0024000100B4000100D90001FFFFFF0B00C9000100390001001F000100310001 + 00BC0001FFFFFF0B00BD0001001A000100D3000100D90002FFFFFF0B00D90005 + FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B00D90005 + FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B00D90005 + FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B00D90005 + FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF0B00D90005 + FFFFFF0B00D90005FFFFFF1B00FF0005FFFFFF0B00D90005FFFFFF0B00D90005 + FFFFFF1B00FF0005FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF1B00FF0005 + FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF1B00FF0005FFFFFF0B00A80001 + 002A0001001F00010025000100A10001FFFFFF0B00BC000100320001001F0001 + 003C000100C80001FFFFFF0CE8F8E8013EC53E0126BD26013EC53E01E8F8E801 + FFFFFF0A00E80001003E000100260001003E000100E80001FFFFFF0B001E0001 + 00B4000100D9000100AE0001001A0001FFFFFF0B003600010097000100D90001 + 0082000100540001FFFFFF0C67D1670196DF9601FFFFFF019CE19C0169D26901 + FFFFFF0A006700010096000100FF0001009C000100690001FFFFFF0B001F0001 + 00AE000100D9000100CB000100210001FFFFFF0B000B000100D6000100D90001 + 00D20001001A0001FFFFFF0C25BD2501EBF9EB01FFFFFF01F0FAF00126BD2601 + FFFFFF0A0025000100EB000100FF000100F0000100260001FFFFFF0B009C0001 + 0005000100420001003A000100940001FFFFFF0B002A00010097000100D90001 + 00C30001000E0001FFFFFF0C0EB60E01FFFFFF0312B71201FFFFFF0A000E0001 + 00FF000300120001FFFFFF0B005600010093000100AD000100450001004D0001 + FFFFFF0B00B2000100310001002300010049000100150001FFFFFF0C0EB60E01 + FFFFFF0311B71101FFFFFF0A000E000100FF000300110001FFFFFF0B000E0001 + 00D6000100D9000100D30001000B0001FFFFFF0B00D9000300AD0001003D0001 + FFFFFF0C24BD2401EFFAEF01FFFFFF01F0FAF00125BD2501FFFFFF0A00240001 + 00EF000100FF000100F0000100250001FFFFFF0B002700010093000100D90001 + 00A6000100280001FFFFFF0B00D9000200D000010039000100940001FFFFFF0C + 67D167019BE19B01FFFFFF019EE29E0168D16801FFFFFF0A00670001009B0001 + 00FF0001009E000100680001FFFFFF0B00AE000100290001001C0001002E0001 + 00B30001FFFFFF0B00D6000100220002007D000100D90001FFFFFF0CE7F8E701 + 3DC43D0126BD26013EC53E01E8F8E801FFFFFF0A00E70001003D000100260001 + 003E000100E80001FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF1B00FF0005 + FFFFFF0B00D90005FFFFFF0B00D90005FFFFFF1B00FF0005FFFFFF0B00D90005 + FFFFFF0B00D90005FFFFFF1B00FF0005FFFFFF0B00D90005FFFFFF0B00D90005 + FFFFFF1B00FF0005FFFFFF060000000000000000000000000000000000000000 + 0004000000000000000E0000000E000E000E0000001F0011000E1800803F8020 + 000E3C00803F8020000E3C00803F8020000E1800001F001100040000000E000E + 00000000000000000004000000000000000E0000000000000004000000000000 + 000000000000000000000000E003E003E003E003E003E003E003E003E003E003 + E003E003E003E003E003E003E003E003E003E003E003E003E003E003E003E003 + E003E003E003E003E003E003E003E003E003E003E003E003E003E003E003E003 + E003E003E003E003E003E003E003E003E003E003E003E003E003E003E003E003 + E003E003E003E003E003E003E003E003E003E003E003E003E003E003E003E003 + E003E003E003E003E003E003E003E003E003E003E003E003E003E003E003E003 + E003E003E003E003E003E003F003E003E003E003F007E003E003E003E003E003 + E003E003E003E003E003E003E003E003E003E003E003E003E003E003E003E003 + E003E003E003E003E003E003E003E0030000E003E003E0030000E003E003E003 + 0000E003E003E0030000E003E003E003C007E003E003E003C006E003E003E003 + C006E003E003E0034004E003E003E0034004E003E003E003C006E003E003E003 + C006E003E003E003C007E003E003E0030000E003E003E0030000E003E003E003 + 0000E003E003E0030000E003 + } + end + object filechangenotifyer: tfilechangenotifyer + onfilechanged = onfilechanged + left = 32 + top = 168 + end + object navigforwardact: taction + state = [as_disabled] + onexecute = navigforward + left = 32 + top = 16 + sc = ( + 1 + 24648 + ) + end + object navigbackact: taction + state = [as_disabled] + onexecute = navigback + left = 32 + top = 40 + sc = ( + 1 + 16456 + ) + end + object formpopup: tpopupmenu + onupdate = popupmonupdate + menu.submenu.count = 30 + menu.submenu.items = < + item + action = actionsmo.selecteditpage + caption = 'Select Page' + state = [as_localcaption, as_localonexecute] + onexecute = doselectpage + end + item + action = actionsmo.opensource + caption = '&Open File' + state = [as_localcaption] + end + item + action = actionsmo.close + caption = '&Close File' + state = [as_localcaption] + options = [mao_shortcutcaption, mao_asyncexecute] + end + item + action = actionsmo.save + caption = '&Save File' + state = [as_localcaption] + end + item + action = actionsmo.saveas + end + item + caption = 'Show as Form' + name = 'showasform' + state = [as_localcaption, as_localonexecute] + onexecute = showasformexe + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + action = actionsmo.delete + end + item + action = actionsmo.cut + end + item + action = actionsmo.copy + end + item + action = actionsmo.copylatexact + end + item + action = actionsmo.paste + end + item + action = actionsmo.selectall + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + action = actionsmo.undo + end + item + action = actionsmo.redo + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + submenu.count = 8 + submenu.items = < + item + action = actionsmo.indent + end + item + action = actionsmo.unindent + end + item + action = actionsmo.comment + end + item + action = actionsmo.uncomment + end + item + action = actionsmo.lowercase + end + item + action = actionsmo.uppercase + end + item + action = actionsmo.tabtospace + end + item + caption = 'Convert to &Pascal string' + name = 'convpas' + state = [as_localcaption, as_localonexecute] + onexecute = convpasex + end> + caption = '&Modify Selection' + name = 'modifyselection' + state = [as_localcaption] + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + action = actionsmo.togglebkpt + end + item + action = actionsmo.togglebkptenable + end + item + caption = '&Edit breakpoint' + name = 'editbreakpoint' + state = [as_localcaption, as_localonexecute] + options = [mao_shortcutcaption, mao_asyncexecute] + onexecute = editbreakpointexec + end + item + caption = 'Add &Watch at Cursor' + name = 'addwatch' + state = [as_localcaption, as_localonexecute] + onexecute = addwatchactonexecute + end + item + submenu.count = 11 + submenu.items = < + item + action = actionsmo.setbm0 + end + item + action = actionsmo.setbm1 + end + item + action = actionsmo.setbm2 + end + item + action = actionsmo.setbm3 + end + item + action = actionsmo.setbm4 + end + item + action = actionsmo.setbm5 + end + item + action = actionsmo.setbm6 + end + item + action = actionsmo.setbm7 + end + item + action = actionsmo.setbm8 + end + item + action = actionsmo.setbm9 + end + item + action = actionsmo.setbmnone + end> + caption = 'Set Bookmark' + name = 'setbm' + state = [as_localcaption] + end + item + submenu.count = 10 + submenu.items = < + item + action = actionsmo.findbm0 + end + item + action = actionsmo.findbm1 + end + item + action = actionsmo.findbm2 + end + item + action = actionsmo.findbm3 + end + item + action = actionsmo.findbm4 + end + item + action = actionsmo.findbm5 + end + item + action = actionsmo.findbm6 + end + item + action = actionsmo.findbm7 + end + item + action = actionsmo.findbm8 + end + item + action = actionsmo.findbm9 + end> + caption = 'Find Bookmark' + state = [as_localcaption] + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = 'Insert GUID' + name = 'insgui' + state = [as_localcaption, as_localonexecute] + onexecute = insguiexec + end + item + caption = 'Insert UID' + name = 'insuid' + state = [as_localcaption, as_localonexecute] + onexecute = insuidexec + end + item + action = actionsmo.instemplate + caption = 'Insert Template' + name = 'instempl' + state = [as_localcaption] + end + item + action = completeclassact + caption = 'Complete Class at Cursor' + state = [as_localcaption] + end> + left = 176 + top = 40 + end + object completeclassact: taction + caption = 'Complete class at cursor' + onexecute = completeclassexecute + left = 32 + top = 208 + sc = ( + 1 + 24641 + ) + end + object c: tstringcontainer + strings.data = ( + 'File "' + '" has changed.' + 'There are modifications in edit buffer also.' + 'Do you wish to reload from disk?' + 'Confirmation' + '' + 'Do you wish to replace:' + 'with:' + '' + 'Syntaxdeffile:' + 'Text' + 'not found.' + 'Restart from begin of file?' + 'Cancel?' + 'Do you wish to to replace this occurence?' + 'Go to line number:' + 'Find line' + 'There are modifications in edit buffer also.' + 'Restart from end of file?' + ) + left = 176 + top = 104 + end +end diff --git a/mseide-msegui/apps/ide/sourceform.pas b/mseide-msegui/apps/ide/sourceform.pas new file mode 100644 index 0000000..bc9cd19 --- /dev/null +++ b/mseide-msegui/apps/ide/sourceform.pas @@ -0,0 +1,1636 @@ +{ MSEide Copyright (c) 1999-2015 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit sourceform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + msetextedit,msewidgetgrid,mseforms,classes,mclasses,msegdbutils, + msegraphedits,mseevent, + msehash,msebitmap,msetabs,sourcepage,mseglob,msetypes,msestrings,mseguiglob, + msegui,msesyntaxpainter,msemenus,mseactions,msesyntaxedit,msestat, + finddialogform,msestream,msefilechange,breakpointsform,mseparser, + msesimplewidgets,msegrids,msegraphutils,mseact,msegridsglob,msestringcontainer; + +type + stringconsts = ( + str_file, //0 File " + haschanged, //1 " has changed. + therearemody, //2 There are modifications in edit buffer also. + wishreload, //3 Do you wish to reload from disk? + confirmation, //4 Confirmation + none, //5 + wishreplace, //6 Do you wish to replace: + str_with, //7 with: + str_new, //8 + syntaxdeffile, //9 Syntaxdeffile: + str_text, //10 Text + str_notfound, //11 not found. + restartbegin, //12 Restart from begin of file? + cancel, //13 Cancel? + replaceoccu, //14 Do you wish to to replace this occurence? + gotoline, //15 Go to line number: + findline, //16 Find line + modieditalso, //17 There are modifications in edit buffer also. + restartend //18 Restart from end of file? + ); + + tsourcefo = class; + + tnaviglist = class(tsourceposlist) + private + fsourcefo: tsourcefo; + findex: integer; + procedure updateshowpos(const acellpos: cellpositionty = cep_rowcenteredif); + public + constructor create; + procedure showsource(const apos: sourceposty; + const asetfocus: boolean = false); + function back: boolean; + function forward: boolean; + end; + + tsourcefo = class(tdockform) + completeclassact: taction; + tpopupmenu1: tpopupmenu; + tabwidget: ttabwidget; + syntaxpainter: tsyntaxpainter; + imagelist: timagelist; + filechangenotifyer: tfilechangenotifyer; + navigforwardact: taction; + navigbackact: taction; + tstockglyphbutton1: tstockglyphbutton; + tstockglyphbutton2: tstockglyphbutton; + c: tstringcontainer; + procedure formonidle(var again: boolean); + procedure doselectpage(const sender: TObject); + + procedure navigback(const sender: TObject); + procedure navigforward(const sender: TObject); + procedure onfilechanged(const sender: tfilechangenotifyer; + const info: filechangeinfoty); + procedure sourcefoonclosequery(const sender: tcustommseform; + var modalresult: modalresultty); + procedure tabwidgetpageremoved(const sender: TObject; const awidget: twidget); + procedure tabwidgetonactivepagechanged(const sender: tobject); + procedure addwatchactonexecute(const sender: tobject); + procedure enterexe(const sender: tobject); + procedure editbreakpointexec(const sender: TObject); + procedure popupmonupdate(const sender: tcustommenu); + procedure completeclassexecute(const sender: TObject); + procedure showasformexe(const sender: TObject); + procedure setbmexec(const sender: TObject); + procedure findbmexec(const sender: TObject); + procedure insguiexec(const sender: TObject); + procedure convpasex(const sender: TObject); + procedure insuidexec(const sender: TObject); + procedure stephintev(const sender: TObject; var info: hintinfoty); + private + fasking: boolean; + fgdbpage: tsourcepage; + ffileloading: boolean; + ffiletag: longword; + fnaviglist: tnaviglist; + fsourcehintwidget: twidget; + feditposar: gridcoordarty; + factbookmark: integer; + fbookmarkar: array of bookmarkarty; + fpagedestroying: integer; + popuprow: integer; + fallsaved: boolean; + flayoutstream: ttextstream; + function geteditpositem(const index: integer): msestring; + procedure seteditposcount(const count: integer); + procedure seteditpositem(const index: integer; const avalue: msestring); + function getbookmarkitem(const index: integer): msestring; + procedure setbookmarkcount(const count: integer); + procedure setbookmarkitem(const index: integer; const avalue: msestring); + function getitems(const index: integer): tsourcepage; + function createnewpage(const afilename: filenamety): tsourcepage; + function getsourcepos: sourceposty; + procedure setsourcehintwidget(const avalue: twidget); + public + hintsize: sizety; + constructor create(aowner: tcomponent); override; + destructor destroy; override; + + procedure updatestat(const statfiler: tstatfiler); + + function hidesourcehint: boolean; //false if no action; + procedure updatebreakpointicon(const path: filenamety; + const info: bkptlineinfoty); + procedure textmodified(const sender: tsourcepage); + function openfile(const filename: filenamety; + aactivate: boolean = false): tsourcepage; //nil if not ok + function showsourceline(const filename: filenamety; + line: integer; col: integer = 0; asetfocus: boolean = false; + const aposition: cellpositionty = cep_rowcentered): tsourcepage; + function showsourcepos(const apos: sourceposty; + asetfocus: boolean = false; + const aposition: cellpositionty = cep_top): tsourcepage; + procedure resetactiverow; + function locate(const info: stopinfoty): tsourcepage; + function count: integer; + function activepage: tsourcepage; + function currentselection: msestring; + function currentfilename: filenamety; + function currentwordatcursor: msestring; + procedure updatecaption; + function newpage: tsourcepage; + function findsourcepage(afilename: filenamety; wholepath: boolean = true; + onlyifloaded: boolean = false): tsourcepage; + procedure saveactivepage(const newname: filenamety = ''); + function saveall(noconfirm: boolean): modalresultty; //false if canceled + procedure savecanceled; //resets fallsaved + property allsaved: boolean read fallsaved; + function closeactivepage: boolean; + function closepage(const apage: tsourcepage; + noclosecheck: boolean = false): boolean; overload; + function closepage(const aname: filenamety): boolean; overload; + function closeall(const nosave: boolean): boolean; //false on cancel + function gdbpage: tsourcepage; + function modified: boolean; + function newfiletag: longword; + property items[const index: integer]: tsourcepage read getitems; default; + property naviglist: tnaviglist read fnaviglist; + function findbookmark(const bookmarknum: integer): boolean; + //true if found + procedure setbookmark(const apage: tsourcepage; const arow: integer; + const bookmarknum: integer); + + function gettextstream(const filename: filenamety; + forwrite: boolean): ttextstream; + function getfiletext(const filename: filenamety; + const startpos,endpos: gridcoordty): msestring; + procedure replacefiletext(const filename: filenamety; + const startpos,endpos: gridcoordty; const newtext: msestring); + property sourcepos: sourceposty read getsourcepos; + property sourcehintwidget: twidget read fsourcehintwidget + write setsourcehintwidget; + end; + + errorlevelty = (el_none,el_all,el_hint,el_note,el_warning,el_error); + +var + sourcefo: tsourcefo; + +function checkerrormessage(const text: msestring; out alevel: errorlevelty; + out afilename: filenamety; out col,row: integer): boolean; +function locateerrormessage(const text: msestring; var apage: tsourcepage; + minlevel: errorlevelty = el_all): boolean; + //true if valid errormessage + +implementation +uses + sourceform_mfm,msefileutils,sysutils,mseformatstr, + projectoptionsform,main,mseeditglob,watchform,msesys,msewidgets,msedesigner, + selecteditpageform,sourceupdate,pascaldesignparser,mseclasses,msearrayutils, + msebits,msesysutils,mseintegerenter,panelform; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tsourcepage1 = class(tsourcepage); + +function checkerrormessage(const text: msestring; out alevel: errorlevelty; + out afilename: filenamety; out col,row: integer): boolean; +var + ar1,ar2,ar3: msestringarty; + int1: integer; +begin + result:= false; + col:= 0; + row:= 0; + alevel:= el_none; + splitstring(text,ar1,msechar('(')); + if length(ar1) > 1 then begin //try FPC + splitstring(ar1[1],ar2,msechar(')')); + if length(ar2) > 1 then begin + splitstring(ar2[0],ar3,msechar(',')); + if (high(ar3) >= 0) then begin + if msestartsstr(' Error:',ar2[1]) or + msestartsstr(' Fatal:',ar2[1]) then begin + alevel:= el_error; + end + else begin + if msestartsstr(' Warning:',ar2[1]) then begin + alevel:= el_warning; + end + else begin + if msestartsstr(' Note:',ar2[1]) then begin + alevel:= el_note; + end + else begin + if msestartsstr(' Hint:',ar2[1]) then begin + alevel:= el_hint; + end; + end; + end; + end; + if trystrtoint(ar3[0],row) then begin + dec(row); + if high(ar3) >= 1 then begin + if trystrtoint(ar3[1],col) then begin + dec(col); + result:= true; + end; + end + else begin + result:= true; + end; + if result then begin + afilename:= ar1[0]; + end; + end; + if result and (alevel = el_none) then begin + alevel:= el_all; + end; + end; + end; + end; + if (alevel = el_none) and not result then begin + ar1:= nil; + ar2:= nil; + splitstring(text,ar1,msechar(':')); + if high(ar1) > 2 then begin + for int1:= 2 to 3 do begin + ar1[int1]:= struppercase(ar1[int1]); + end; + if (ar1[2] = ' ERROR') or (ar1[3] = ' ERROR') then begin + alevel:= el_error; + end + else begin + if (ar1[2] = ' WARNING') or (ar1[3] = ' WARNING') then begin + alevel:= el_warning; + end + else begin + if (ar1[2] = ' HINT') or (ar1[3] = ' HINT') then begin + alevel:= el_hint; + end + else begin + alevel:= el_all; + end; + end; + end; + if alevel <> el_none then begin + if trystrtoint(ar1[1],row) then begin + dec(row); + if trystrtoint(ar1[2],col) then begin + dec(col); + end + else begin + col:= 0; + end; + afilename:= ar1[0]; + result:= true; + end; + end; + end; + end; +end; + +function locateerrormessage(const text: msestring; var apage: tsourcepage; + minlevel: errorlevelty = el_all): boolean; +var + lev1: errorlevelty; + col1,row1: integer; + fna1: filenamety; +begin + apage:= nil; + result:= false; + if checkerrormessage(text,lev1,fna1,col1,row1) and (fna1 <> '') and + (lev1 >= minlevel) then begin + apage:= sourcefo.showsourceline(sourcepath(fna1),row1,col1,true); + result:= true; + end; +end; + +(* +function locateerrormessage(const text: msestring; var apage: tsourcepage; + minlevel: errorlevelty = el_all): boolean; +var + ar1,ar2,ar3: msestringarty; + col,row: integer; + alevel: errorlevelty; + int1: integer; +begin + apage:= nil; + result:= false; + col:= 0; + row:= 0; + alevel:= el_all; + splitstring(text,ar1,msechar('(')); + if length(ar1) > 1 then begin //try FPC + splitstring(ar1[1],ar2,msechar(')')); + if length(ar2) > 1 then begin + splitstring(ar2[0],ar3,msechar(',')); + if (high(ar3) >= 0) then begin + if startsstr(' Error:',ar2[1]) or startsstr(' Fatal:',ar2[1]) then begin + alevel:= el_error; + end + else begin + if startsstr(' Warning:',ar2[1]) then begin + alevel:= el_warning; + end + else begin + if startsstr(' Hint:',ar2[1]) then begin + alevel:= el_hint; + end + else begin + if startsstr(' Note:',ar2[1]) then begin + alevel:= el_hint; + end; + end; + end; + end; + if alevel >= minlevel then begin + if trystrtointmse(ar3[0],row) then begin + dec(row); + if high(ar3) >= 1 then begin + if trystrtointmse(ar3[1],col) then begin + dec(col); + result:= true; + end; + end + else begin + result:= true; + end; + if result then begin + apage:= sourcefo.showsourceline(objpath(ar1[0]),row,col,true); + end; + end; + end; + end; + end; + end; + if (alevel = el_all) and not result then begin + ar1:= nil; + ar2:= nil; + splitstring(text,ar1,msechar(':')); + if high(ar1) > 2 then begin + for int1:= 2 to 3 do begin + ar1[int1]:= struppercase(ar1[int1]); + end; + if (ar1[2] = ' ERROR') or (ar1[3] = ' ERROR') then begin + alevel:= el_error; + end + else begin + if (ar1[2] = ' WARNING') or (ar1[3] = ' WARNING') then begin + alevel:= el_warning; + end + else begin + if (ar1[2] = ' HINT') or (ar1[3] = ' HINT') then begin + alevel:= el_hint; + end + else begin + alevel:= el_all; + end; + end; + end; + if alevel >= minlevel then begin + if trystrtointmse(ar1[1],row) then begin + dec(row); + if trystrtointmse(ar1[2],col) then begin + dec(col); + end + else begin + col:= 0; + end; + apage:= sourcefo.showsourceline(objpath(ar1[0]),row,col,true); + result:= true; + end; + end; + end; + end; +end; +*) + +{ tnaviglist } + +constructor tnaviglist.create; +begin + findex:= -1; + inherited; +end; + +procedure tnaviglist.updateshowpos( + const acellpos: cellpositionty = cep_rowcenteredif); +begin + with fsourcefo do begin + showsourcepos(self.items[findex]^,true,acellpos); + navigforwardact.enabled:= findex < fcount - 1; + navigbackact.enabled:= findex > 0; + end; +end; + +function tnaviglist.back: boolean; +begin + if findex > 0 then begin + result:= true; + dec(findex); + updateshowpos(cep_rowcenteredif); + end + else begin + result:= false; + end; +end; + +function tnaviglist.forward: boolean; +begin + if (findex < count - 1) then begin + result:= true; + inc(findex); + updateshowpos(cep_rowcenteredif); + end + else begin + result:= false; + end; +end; + +procedure tnaviglist.showsource(const apos: sourceposty; + const asetfocus: boolean = false); +begin + count:= findex + 1; + if count = 0 then begin + add(fsourcefo.sourcepos); + end + else begin + items[findex]^:= fsourcefo.sourcepos; + end; + findex:= add(apos); + updateshowpos(cep_none{cep_top}); +end; + +{ tsourcefo } + +constructor tsourcefo.create(aowner: tcomponent); +begin + fnaviglist:= tnaviglist.create; + fnaviglist.fsourcefo:= self; + inherited create(aowner); +end; + +destructor tsourcefo.destroy; +begin + hidesourcehint; + inherited; + fnaviglist.Free; + flayoutstream.free; +end; + +function tsourcefo.hidesourcehint: boolean; +begin + if fsourcehintwidget <> nil then begin + result:= true; + freeandnil(fsourcehintwidget); + end + else begin + result:= false; + end; +end; + +procedure tsourcefo.tabwidgetpageremoved(const sender: TObject; const awidget: twidget); +begin + if awidget = fgdbpage then begin + fgdbpage:= nil; + end; +end; + +procedure tsourcefo.updatestat(const statfiler: tstatfiler); +var + int1: integer; + filenames,relpaths,modulenames: filenamearty; + moduleoptions: integerarty; +// moduledock: stringarty; + ismod: longboolarty; + ar1,ar2: longboolarty; + page1: tsourcepage1; + intar1,intar2: integerarty; + mstr1: filenamety; + bo1: boolean; + po1: pmoduleinfoty; +// ar3: msestringarty; +// pt1: pointty; + +begin + with statfiler do begin + setsection('edit'); + updatevalue('hintwidth',hintsize.cx); + updatevalue('hintheight',hintsize.cy); + updatefindvalues(statfiler,projectoptions.findreplaceinfo.find); + if iswriter then begin + intar1:= tabwidget.idents; + sortarray(intar1,intar2); + setlength(filenames,count); + setlength(relpaths,count); + setlength(feditposar,count); + setlength(fbookmarkar,count); + setlength(ismod,count); + for int1:= 0 to high(filenames) do begin + with items[intar2[int1]] do begin + filenames[int1]:= filepath; + relpaths[int1]:= relpath; + feditposar[int1]:= edit.editpos; + fbookmarkar[int1]:= getbookmarks; + ismod[int1]:= ismoduletext; + end; + end; + setlength(modulenames,designer.modules.count); + setlength(moduleoptions,length(modulenames)); +// setlength(moduledock,length(modulenames)); + setlength(ar1,length(modulenames)); + setlength(ar2,length(modulenames)); + for int1:= 0 to designer.modules.count - 1 do begin + with designer.modules[int1]^ do begin + modulenames[int1]:= filename; + moduleoptions[int1]:= + {$ifdef FPC}longword{$else}byte{$endif}(designformintf.moduleoptions); + ar1[int1]:= designform.visible; + ar2[int1]:= not hasmenuitem; +// moduledock[int1]:= encodemoduledock(dockinfo); + end; + end; + tstatwriter(statfiler).writerecordarray('editpos',length(feditposar), + {$ifdef FPC}@{$endif}geteditpositem); + for int1:= 0 to high(fbookmarkar) do begin + factbookmark:= int1; + tstatwriter(statfiler).writerecordarray('bookmarks'+inttostrmse(int1), + length(fbookmarkar[int1]), + {$ifdef FPC}@{$endif}getbookmarkitem); + end; + end + else begin + tstatreader(statfiler).readrecordarray('editpos', + {$ifdef FPC}@{$endif}seteditposcount, + {$ifdef FPC}@{$endif}seteditpositem); + setlength(fbookmarkar,length(feditposar)); + for int1:= 0 to high(fbookmarkar) do begin + factbookmark:= int1; + tstatreader(statfiler).readrecordarray('bookmarks'+inttostrmse(int1), + {$ifdef FPC}@{$endif}setbookmarkcount, + {$ifdef FPC}@{$endif}setbookmarkitem); + end; + end; + updatevalue('sourcefiles',filenames); + updatevalue('relpaths',relpaths); + updatevalue('ismoduletexts',ismod); + updatevalue('modules',modulenames); + updatevalue('moduleoptions',moduleoptions); +// updatevalue('moduledock',moduledock); + updatevalue('visiblemodules',ar1); + updatevalue('nomenumodules',ar2); + if not iswriter then begin + tabwidget.window.nofocus; + tabwidget.clear; + tabwidget.beginupdate; + try + for int1:= 0 to high(filenames) do begin + page1:= tsourcepage1(createnewpage('')); + if (page1 <> nil) then begin + page1.finitialfilepath:= filenames[int1]; + if int1 <= high(relpaths) then begin + page1.relpath:= relpaths[int1]; + end; + if int1 <= high(ismod) then begin + page1.ismoduletext:= ismod[int1]; + end; + if int1 <= high(feditposar) then begin + page1.finitialeditpos:= feditposar[int1]; + if page1.finitialeditpos.col < 0 then begin + page1.finitialeditpos.col:= 0; + end; + if page1.finitialeditpos.row < 0 then begin + page1.finitialeditpos.row:= 0; + end; + end; + if int1 <= high(fbookmarkar) then begin + page1.finitialbookmarks:= fbookmarkar[int1]; + end; + page1.updatecaption(false); + end; + end; + mainfo.errorformfilename:= ''; + setlength(ar2,length(modulenames)); + setlength(moduleoptions,length(modulenames)); +// setlength(moduledock,length(modulenames)); + designer.beginskipall; + for int1:= 0 to high(modulenames) do begin + try + if int1 > high(ar1) then begin + bo1:= true; + end + else begin + bo1:= ar1[int1]; + end; + mstr1:= modulenames[int1]; + relocatepath(projectoptions.projectdir,'',mstr1, + [pro_preferenew,pro_rootpath]); + po1:= mainfo.openformfile(filepath(mstr1),bo1,false,false, + not ar2[int1],true); +{ + mstr1:= relativepath(modulenames[int1],projectoptions.projectdir); + if findfile(mstr1) then begin + po1:= mainfo.openformfile(filepath(mstr1),bo1,false,false, + not ar2[int1],true); + end + else begin + po1:= mainfo.openformfile(modulenames[int1],bo1,false,false, + not ar2[int1],true); + end; +} + if (po1 <> nil) then begin + with po1^ do begin + designformintf.moduleoptions:= + moduleoptionsty({$ifdef FPC}longword{$else}byte{$endif} + (moduleoptions[int1])) * [mo_hidewidgets,mo_hidecomp]; +// if decodemoduledock(moduledock[int1],dockinfo) then begin +// docktopanel(designformintf.getdockcontroller(),dockinfo.panelname, +// dockinfo.rect); +// end; + end; + end; + except + if checkprojectloadabort then begin + break; //do not load more modules + end; + end; + end; + designer.endskipall; + tabwidget.activepageindex:= -1; //do not load source +// updatestat(istatfile(tabwidget)); + finally + tabwidget.endupdate; + end; + end; +// if visible and (activepage <> nil) then begin +// activepage.sourcefoonshow(nil); +// end; + feditposar:= nil; //no longer used + fbookmarkar:= nil; + updatestat(istatfile(tabwidget)); + if mainfo.errorformfilename <> '' then begin + showsourceline(mainfo.errorformfilename,0,0,true); + end; + if (tabwidget.activepageindex < 0) and (tabwidget.count > 0) then begin + tabwidget.activepageindex:= 0; //default + end; + end; +end; + +procedure tsourcefo.doselectpage(const sender: TObject); +begin + selecteditpage; +end; + +procedure tsourcefo.navigback(const sender: TObject); +begin + fnaviglist.back; +end; + +procedure tsourcefo.navigforward(const sender: TObject); +begin + fnaviglist.forward; +end; + +procedure tsourcefo.formonidle(var again: boolean); + +var + all: boolean; + noall: boolean; + + function ask(const filepath: filenamety; const modified: boolean): boolean; + var + mstr1: msestring; + begin + if noall then begin + result:= false; + end + else begin + if all and not modified then begin + result:= true; + end + else begin + mstr1:= c[ord(str_file)]+filepath+c[ord(haschanged)]; + if modified then begin + mstr1:= mstr1 + ' '+ c[ord(modieditalso)]; + mstr1:= mstr1 + ' '+c[ord(wishreload)]; + result:= askyesno(mstr1,c[ord(confirmation)]); + end + else begin + result:= false; + mstr1:= mstr1 + ' '+c[ord(wishreload)]; + case showmessage(mstr1,c[ord(confirmation)], + [mr_yes,mr_all,mr_no,mr_noall],mr_yes) of + mr_yes: begin + result:= true; + end; + mr_all: begin + result:= true; + all:= true; + end; + mr_noall: begin + noall:= true; + end; + end; + end; + end; + end; + end; + +var + int1: integer; + po1: pmoduleinfoty; + fna1: filenamety; + hasdesignfo1: boolean; + hasmenu1: boolean; + visible1: boolean; + active1: boolean; +begin + if (application.activewindow <> nil) and not fasking and + (application.modallevel = 0) and + (application.keyboardcapturewidget = nil) then begin + fasking:= true; + all:= false; + noall:= false; + try + for int1:= 0 to count - 1 do begin + with items[int1] do begin + if filechanged then begin + filechanged:= false; + if ask(filepath,modified) then begin + filechanged:= false; + reload; + mainfo.sourcechanged(items[int1]); + end + else begin + edit.modified:= true; + end; + mainfo.sourcechanged(items[int1]); + end; + end; + end; + for int1:= 0 to designer.modules.count - 1 do begin + po1:= designer.modules.itempo[int1]; + with po1^ do begin + if filechanged then begin + if flayoutstream = nil then begin + flayoutstream:= ttextstream.create(); + mainfo.savewindowlayout(flayoutstream); + end; + if ask(filename,modified) then begin + fna1:= filename; + hasmenu1:= hasmenuitem; + hasdesignfo1:= designform <> nil; + if hasdesignfo1 then begin + visible1:= designform.visible; + active1:= designform.activeentered; + end; + designform.free(); + if hasdesignfo1 then begin + po1:= mainfo.openformfile(fna1,visible1,active1,false,hasmenu1,false); + end + else begin + po1:= designer.loadformfile(fna1,false); + end; + po1^.filechanged:= true; + end + else begin + designer.modulechanged(po1); + end; + end; + end; + end; + all:= false; + noall:= false; + for int1:= 0 to designer.modules.count - 1 do begin + po1:= designer.modules.itempo[int1]; + with po1^ do begin + if filechanged then begin + filechanged:= false; + designer.refreshdatafile(po1); + end; + end; + end; + if flayoutstream <> nil then begin + try + flayoutstream.position:= 0; + mainfo.loadwindowlayout(flayoutstream); + mainfo.sourcechanged(nil); + finally + freeandnil(flayoutstream); + end; + end; + finally + fasking:= false; + end; + end; +end; + +function modulecanchangenotify(const amodule: pmoduleinfoty; + const info: filechangeinfoty): boolean; +begin + result:= (info.changed - [fc_force,fc_accesstime] <> []); +end; + +procedure tsourcefo.onfilechanged(const sender: tfilechangenotifyer; + const info: filechangeinfoty); +var + int1: integer; + po1: pmoduleinfoty; +begin + for int1:= 0 to count - 1 do begin + with items[int1] do begin + if (longword(info.tag) = filetag) and canchangenotify(info) then begin + filechanged:= true; + application.wakeupmainthread(); + end; + end; + end; + for int1:= 0 to designer.modules.count - 1 do begin + po1:= designer.modules.itempo[int1]; + with po1^ do begin + if (longword(info.tag) = filetag) and + modulecanchangenotify(po1,info) then begin + filechanged:= true; + application.wakeupmainthread(); + end; + end; + end; +end; + +function tsourcefo.count: integer; +begin + result:= tabwidget.count; +end; + +function tsourcefo.getitems(const index: integer): tsourcepage; +begin + result:= tsourcepage(tabwidget[index]); +end; + +function tsourcefo.findsourcepage(afilename: filenamety; + wholepath: boolean = true; + onlyifloaded: boolean = false): tsourcepage; +var + int1: integer; +begin + result:= nil; + if wholepath then begin + for int1:= 0 to count - 1 do begin + if issamefilename(items[int1].filepath,afilename) then begin + result:= items[int1]; + break; + end; + end; + end + else begin + for int1:= 0 to count - 1 do begin + if issamefilename(items[int1].filename,afilename) then begin + result:= items[int1]; + break; + end; + end + end; + if result <> nil then begin + if onlyifloaded then begin + if not result.fileloaded then begin + result:= nil; + end; + end + else begin + result.loadfile; + end; + end; +end; + +function tsourcefo.createnewpage(const afilename: filenamety): tsourcepage; +begin + result:= tsourcepage.create(nil); + try + result.edit.syntaxpainter:= syntaxpainter; + result.dataicon.imagelist:= imagelist; + result.filepath:= afilename; + tabwidget.add(result,tabwidget.activepageindex+1); + if afilename <> '' then begin + filechangenotifyer.addnotification(result.filepath,result.filetag); + designer.designfiles.add(afilename); + end; + except + result.Free; + result:= nil; + application.handleexception(self); + end; +end; + +function tsourcefo.newpage: tsourcepage; +begin + result:= createnewpage(''); + result.updatecaption(false); + result.show; + result.setfocus(true); +end; + +function tsourcefo.openfile(const filename: filenamety; + aactivate: boolean = false): tsourcepage; + //nil if not ok + + function loadfile(aname: filenamety): tsourcepage; + var + po1: pmoduleinfoty; + begin + po1:= designer.modules.findmodule(filepath(aname)); + if not mainfo.closemodule(po1,true) then begin + sysutils.abort; + end; + ffileloading:= true; + try + result:= createnewpage(aname); + if result <> nil then begin + result.ismoduletext:= (po1 <> nil); + mainfo.loadformbysource(aname); + end; + finally + ffileloading:= false; + end; + end; + +var + str1: filenamety; + bo1: boolean; +begin + result:= nil; + if filename = '' then begin + exit; + end; + application.beginwait; + try + bo1:= isrootpath(filename); + if bo1 then begin + result:= findsourcepage(filename); + if result = nil then begin + if findfile(filename) then begin + result:= loadfile(filename); + end; + end; + end; + if result = nil then begin + if bo1 and findfile(msefileutils.filename(filename), + projectoptions.d.texp.sourcedirs,str1) or + not bo1 and + findfile(filename,projectoptions.d.texp.sourcedirs,str1) then begin + result:= findsourcepage(str1); + if result = nil then begin + result:= loadfile(str1); + end; + end; + end; + if (result <> nil) and aactivate then begin + result.activate(true); + end; + finally + application.endwait; + end; +end; + +function tsourcefo.showsourceline(const filename: filenamety; + line: integer; col: integer = 0; asetfocus: boolean = false; + const aposition: cellpositionty = cep_rowcentered): tsourcepage; +var + rowpos1: int32; +begin + rowpos1:= 0; + if activepage <> nil then begin + rowpos1:= activepage.grid.rowwindowpos; //current window pos of focused row + end; + result:= openfile(filename); + if result <> nil then begin + result.show; + if line >= 0 then begin + result.grid.showcell(makegridcoord(0,line),aposition); + if asetfocus then begin + result.edit.editpos:= makegridcoord(col,line); + result.grid.setfocus; + result.window.bringtofront; + end; + if aposition = cep_none then begin + result.grid.rowwindowpos:= rowpos1; + end; + end; + end; +end; + +function tsourcefo.showsourcepos(const apos: sourceposty; + asetfocus: boolean = false; + const aposition: cellpositionty = cep_top): tsourcepage; +var + str1: filenamety; +begin + result:= nil; + str1:= designer.designfiles.getname(apos.filename); + if str1 <> '' then begin + result:= showsourceline(str1,apos.pos.row,apos.pos.col,asetfocus,aposition); + end; +end; + +procedure tsourcefo.resetactiverow; +begin + if fgdbpage <> nil then begin + fgdbpage.activerow:= -1; + end; +end; + +function tsourcefo.locate(const info: stopinfoty): tsourcepage; +begin + resetactiverow; + if info.filename <> '' then begin + result:= openfile(sourcepath(info.filename)); + if result <> nil then begin + result.activerow:= info.line-1; + result.show; + end; + end + else begin + result:= nil; + end; + fgdbpage:= result; +end; + +function tsourcefo.saveall(noconfirm: boolean): modalresultty; +var + int1,int2: integer; +begin + result:= mr_none; + for int1:= 0 to tabwidget.count - 1 do begin + result:= mainfo.checksavecancel( + tsourcepage(tabwidget[int1]).checksave(noconfirm,true)); + case result of + mr_cancel: begin + exit; + end; + mr_noall: begin + break; + end; + mr_all: begin + for int2:= int1 to tabwidget.count - 1 do begin + tsourcepage(tabwidget[int2]).checksave(true,true); + end; + break; + end; + end; + end; + fallsaved:= fallsaved or not noconfirm; +end; + +function tsourcefo.modified: boolean; +var + int1: integer; +begin + result:= false; + if fpagedestroying = 0 then begin + for int1:= 0 to count - 1 do begin + if items[int1].modified then begin + result:= true; + break; + end; + end; + end; +end; + +function tsourcefo.newfiletag: longword; +begin + inc(ffiletag); + if ffiletag = 0 then begin + ffiletag:= 1; + end; + result:= ffiletag; +end; + +procedure tsourcefo.sourcefoonclosequery(const sender: tcustommseform; + var modalresult: modalresultty); +begin +{ + if saveall(false) = mr_cancel then begin + modalresult:= mr_none; + end; +} +end; + +procedure tsourcefo.updatecaption; +var + page: tsourcepage; + +begin + page:= tsourcepage(tabwidget.activepage); + if page <> nil then begin + caption:= page.caption; + end + else begin + caption:= c[ord(none)]; + end; +end; + +procedure tsourcefo.tabwidgetonactivepagechanged(const sender: tobject); +begin + updatecaption; +end; + +procedure tsourcefo.saveactivepage(const newname: filenamety = ''); +begin + if activepage <> nil then begin + activepage.save(newname); + end; +end; + +function tsourcefo.closepage(const apage: tsourcepage; + noclosecheck: boolean = false): boolean; +var + str1: filenamety; + bo1: boolean; +begin + result:= apage = nil; + if not result then begin + if apage.checksave(false,false) <> mr_cancel then begin + str1:= apage.filepath; + if not noclosecheck and (fileext(str1) = pasfileext) then begin + if not mainfo.closemodule( + designer.modules.findmodule(replacefileext(str1,formfileext)),true, + noclosecheck) then begin + exit; + end; + end; + filechangenotifyer.removenotification(str1); + inc(fpagedestroying); + try + bo1:= tabwidget.entered; + apage.free; + if bo1 then begin + tabwidget.setfocus; + end; + finally + dec(fpagedestroying); + end; + result:= true; + end; + end; +end; + +function tsourcefo.closepage(const aname: filenamety): boolean; +begin + result:= closepage(findsourcepage(aname,true,true)); +end; + +function tsourcefo.closeactivepage: boolean; +begin + result:= closepage(activepage); +end; + +function tsourcefo.closeall(const nosave: boolean): boolean; //false on cancel +var + int1: integer; +begin + result:= nosave or (saveall(false) <> mr_cancel); + if result then begin + for int1:= count - 1 downto 0 do begin + items[int1].enabled:= false; //avoid showing + end; + for int1:= count - 1 downto 0 do begin + closepage(items[int1],true); + end; + end; +end; + +function tsourcefo.activepage: tsourcepage; +begin + if fpagedestroying > 0 then begin + result:= nil; + end + else begin + result:= tsourcepage(tabwidget.activepage); + end; +end; + +procedure tsourcefo.textmodified(const sender: tsourcepage); +begin + fallsaved:= false; + if not ffileloading then begin + mainfo.sourcechanged(sender); + end; +end; + +function tsourcefo.gdbpage: tsourcepage; +begin + result:= fgdbpage; +end; + +procedure tsourcefo.addwatchactonexecute(const sender: tobject); +begin + with sender as tmenuitem do begin + watchfo.addwatch(getpascalvarname(activepage.edit, + translateclientpoint(owner.mouseinfopo^.pos, + owner.transientfor,activepage.edit))); + end; +end; + +procedure tsourcefo.updatebreakpointicon(const path: filenamety; const info: bkptlineinfoty); +var + int1: integer; + wstr1: msestring; +begin + wstr1:= filename(path); + for int1:= 0 to count - 1 do begin + with tsourcepage(tabwidget[int1]) do begin + if issamefilename(filename,wstr1) then begin + try + updatebreakpointicon(info); + except + end; + end; + end; + end; +end; + +function tsourcefo.geteditpositem(const index: integer): msestring; +begin + result:= encoderecord([feditposar[index].col,feditposar[index].row]); +end; + +procedure tsourcefo.seteditposcount(const count: integer); +begin + setlength(feditposar,count); +end; + +procedure tsourcefo.seteditpositem(const index: integer; const avalue: msestring); +begin + decoderecord(avalue,[@feditposar[index].col,@feditposar[index].row],'ii'); +end; + +function tsourcefo.getbookmarkitem(const index: integer): msestring; +begin + result:= encoderecord([fbookmarkar[factbookmark][index].row, + fbookmarkar[factbookmark][index].bookmarknum]); +end; + +procedure tsourcefo.setbookmarkcount(const count: integer); +begin + setlength(fbookmarkar[factbookmark],count); +end; + +procedure tsourcefo.setbookmarkitem(const index: integer; const avalue: msestring); +begin + decoderecord(avalue,[@fbookmarkar[factbookmark][index].row, + @fbookmarkar[factbookmark][index].bookmarknum],'ii'); +end; + +procedure tsourcefo.enterexe(const sender: tobject); +begin + mainfo.designformactivated(self); +end; + +function tsourcefo.gettextstream(const filename: filenamety; + forwrite: boolean): ttextstream; +var + page1: tsourcepage; +begin + page1:= findsourcepage(filename,true,true); + if forwrite then begin + if page1 = nil then begin + page1:= openfile(filename); + end; + end; + if page1 <> nil then begin + result:= page1.edit.datalist.dataastextstream; + end + else begin + if not forwrite then begin + result:= ttextstream.create(filename,fm_read); + end + else begin + result:= nil; + end; + end; +end; + +function tsourcefo.getfiletext(const filename: filenamety; + const startpos,endpos: gridcoordty): msestring; +var + apage: tsourcepage; +begin + apage:= openfile(filename); + if apage <> nil then begin + result:= apage.edit.gettext(startpos,endpos); + end + else begin + result:= ''; + end; +end; + +procedure tsourcefo.replacefiletext(const filename: filenamety; + const startpos,endpos: gridcoordty; const newtext: msestring); +var + apage: tsourcepage; +begin + apage:= openfile(filename); + if apage <> nil then begin + apage.edit.deletetext(startpos,endpos); + apage.edit.inserttext(startpos,msestring(newtext)); + end; +end; + +function tsourcefo.getsourcepos: sourceposty; +begin + finalize(result); + fillchar(result,sizeof(result),0); + if activepage <> nil then begin + result.filename:= designer.designfiles.find(activepage.filepath); + result.pos:= activepage.edit.editpos; + end; +end; + +procedure tsourcefo.setsourcehintwidget(const avalue: twidget); +begin + fsourcehintwidget.free; + setlinkedvar(avalue,tmsecomponent(fsourcehintwidget)); +end; + +procedure tsourcefo.editbreakpointexec(const sender: TObject); +begin + breakpointsfo.showbreakpoint(activepage.filepath,popuprow+1,true); +end; +{ +procedure tsourcefo.togglebreakpointexe(const sender: TObject); +begin + activepage.togglebreakpoint(popuprow); +end; +} +procedure tsourcefo.popupmonupdate(const sender: tcustommenu); +//var +// gc1: gridcoordty; +begin + if (activepage <> nil) and (sender.mouseinfopo <> nil) then begin + popuprow:= activepage.grid.cellatpos(translateclientpoint( + sender.mouseinfopo^.pos,activepage,activepage.grid)).row; + end + else begin + popuprow:= invalidaxis; + end; + sender.menu.itembyname('editbreakpoint').enabled:= + (activepage <> nil) and (popuprow >= 0) and + (activepage.getbreakpointstate(popuprow) > bkpts_none); + sender.menu.itembyname('showasform').enabled:= + (activepage <> nil) and activepage.ismoduletext; + sender.menu.itembyname('setbm').enabled:= + (activepage <> nil) and (popuprow >= 0); + sender.menu.itembyname('insgui').enabled:= (activepage <> nil); + sender.menu.itembyname('insuid').enabled:= (activepage <> nil); + sender.menu.itembynames(['modifyselection','convpas']).enabled:= + (activepage <> nil) and activepage.edit.hasselection; + sender.menu.itembyname('addwatch').enabled:= (activepage <> nil) and + (sender.mouseinfopo <> nil) and + (getpascalvarname(activepage.edit, + translateclientpoint(sender.mouseinfopo^.pos, + activepage,activepage.edit)) <> ''); +{ + sender.menu.itembyname('instempl').enabled:= (activepage <> nil) and + codetemplates.hastemplate( + activepage.edit.wordatpos(activepage.edit.editpos,gc1,'',[],true)); +} +end; + +procedure tsourcefo.completeclassexecute(const sender: TObject); +var + pos1: sourceposty; +begin + if activepage <> nil then begin + activepage.edit.editor.begingroup; + try + pos1.pos:= activepage.edit.editpos; + completeclass(activepage.filepath,pos1); + finally + activepage.edit.editor.endgroup; + end; + end; +end; + +procedure tsourcefo.showasformexe(const sender: TObject); +begin + activepage.asyncevent(integer(spat_showasform)); +end; + +procedure tsourcefo.setbookmark(const apage: tsourcepage; const arow: integer; + const bookmarknum: integer); +var + int1: integer; + page1: tsourcepage; + bo1: boolean; +begin + if bookmarknum >= 0 then begin + bo1:= (arow >= 0) and (bookmarknum >= 0); + for int1:= 0 to self.count - 1 do begin + page1:= items[int1]; + if bo1 and (page1 = apage) and (page1.findbookmark(bookmarknum) = arow) then begin + page1.clearbookmark(bookmarknum); + exit; + end; + page1.clearbookmark(bookmarknum); + end; + end; + apage.setbookmark(arow,bookmarknum); +end; + +procedure tsourcefo.setbmexec(const sender: TObject); +begin + setbookmark(activepage,-1,tmenuitem(sender).tag); +end; + +function tsourcefo.findbookmark(const bookmarknum: integer): boolean; +var + int1,int2: integer; +begin + result:= false; + for int1:= 0 to count - 1 do begin + with items[int1] do begin + int2:= findbookmark(bookmarknum); + if int2 >= 0 then begin + grid.showcell(makegridcoord(invalidaxis,int2),cep_rowcenteredif); + edit.editpos:= makegridcoord(0,int2); + activate; + result:= true; + end; + end; + end; +end; + +procedure tsourcefo.findbmexec(const sender: TObject); +begin + findbookmark(tmenuitem(sender).tag); +end; + +procedure tsourcefo.insguiexec(const sender: TObject); +begin + with activepage.edit do begin + inserttext(editpos,'['''+msestring(createguidstring)+''']'); + end; +end; + +procedure tsourcefo.insuidexec(const sender: TObject); +var + id1,int1: integer; + str1: string[4]; + str2: string; +begin + id1:= projectoptions.k.uid; + if integerenter(id1,minint,maxint,'ID','Enter ID') = mr_ok then begin + for int1:= 0 to 3 do begin + str1[int1+1]:= char(bitreverse[byte( + (id1 and ($ff shl (int1*8))shr(int1*8)))]); + end; + str1[0]:= #1; + for int1:= 4 downto 1 do begin + if str1[int1] <> #0 then begin + str1[0]:= char(int1); + break; + end; + end; + str2:= encodebase64(str1); + for int1:= length(str2) downto 1 do begin + if str2[int1] <> '=' then begin + setlength(str2,int1); + break; + end; + end; + + with activepage.edit do begin + inserttext(editpos,'['''+msestring(str2)+''']{'+inttostrmse(id1)+'}'); + end; + projectoptions.k.uid:= id1+1; + end; +end; + +procedure tsourcefo.convpasex(const sender: TObject); + +var + ar1: msestringarty; + + function messagestr(const def: msestring): msestring; + begin + if high(ar1) > 4 then begin + result:= concatstrings(copy(ar1,0,5),lineend); + result:= result+lineend+'...'; + end + else begin + result:= def; + end; + if length(result) > 5*80 then begin + result:= copy(result,1,5*80)+'...'; + end; + end; //msessagestr + +var + mstr1,mstr2,mstr3,mstr4: msestring; + int1: integer; + maxlen: int32; +const + liend = '+lineend+'; + +begin + with activepage.edit do begin + maxlen:= projectoptions.e.rightmarginchars; + if maxlen > 0 then begin //else unlimited + maxlen:= maxlen-length(liend); + if maxlen < 20 then begin + maxlen:= 20; + end; + end; + mstr1:= selectedtext; + ar1:= breaklines(mstr1); + mstr3:= messagestr(mstr1); + for int1:= 0 to high(ar1)-1 do begin + ar1[int1]:= msestring(stringtopascalstring(ar1[int1],maxlen))+liend; + end; + ar1[high(ar1)]:= msestring(stringtopascalstring(ar1[high(ar1)],maxlen)); + mstr2:= concatstrings(ar1,lineend); + mstr4:= messagestr(mstr2); + if askyesno(c[ord(wishreplace)]+lineend+mstr3+lineend+c[ord(str_with)]+lineend+ + mstr4+lineend+'?',c[ord(confirmation)]) then begin + editor.begingroup; + deleteselection; + inserttext(mstr2,true); + editor.endgroup; + end; + end; +end; + +procedure tsourcefo.savecanceled; +begin + fallsaved:= false; +end; + +function tsourcefo.currentselection: msestring; +begin + result:= ''; + if activepage <> nil then begin + with activepage do begin + result:= edit.selectedtext; + end; + end; +end; + +function tsourcefo.currentfilename: filenamety; +begin + result:= ''; + if activepage <> nil then begin + with activepage do begin + result:= filepath; + end; + end; +end; + +function tsourcefo.currentwordatcursor: msestring; +var + gridcoord1: gridcoordty; +begin + result:= ''; + if activepage <> nil then begin + with activepage do begin + result:= getpascalvarname(edit,edit.editpos,gridcoord1); + end; + end; +end; + +procedure tsourcefo.stephintev(const sender: TObject; var info: hintinfoty); +begin + info.caption:= info.caption + '('+ + encodeshortcutname(tstockglyphbutton(sender).shortcut)+').'; +end; + +end. diff --git a/mseide-msegui/apps/ide/sourceform_mfm.pas b/mseide-msegui/apps/ide/sourceform_mfm.pas new file mode 100644 index 0000000..122df0f --- /dev/null +++ b/mseide-msegui/apps/ide/sourceform_mfm.pas @@ -0,0 +1,618 @@ +unit sourceform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,sourceform; + +const + objdata: record size: integer; data: array[0..12007] of byte end = + (size: 12008; data: ( + 84,80,70,48,9,116,115,111,117,114,99,101,102,111,8,115,111,117,114,99, + 101,102,111,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111, + 99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116, + 115,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 0,15,102,114,97,109,101,46,103,114,105,112,95,115,105,122,101,2,10,18, + 102,114,97,109,101,46,103,114,105,112,95,111,112,116,105,111,110,115,11,14, + 103,111,95,99,108,111,115,101,98,117,116,116,111,110,16,103,111,95,102,105, + 120,115,105,122,101,98,117,116,116,111,110,14,103,111,95,102,108,111,97,116, + 98,117,116,116,111,110,12,103,111,95,116,111,112,98,117,116,116,111,110,19, + 103,111,95,98,97,99,107,103,114,111,117,110,100,98,117,116,116,111,110,15, + 103,111,95,110,111,108,111,99,107,98,117,116,116,111,110,14,103,111,95,98, + 117,116,116,111,110,104,105,110,116,115,0,7,111,110,101,110,116,101,114,7, + 8,101,110,116,101,114,101,120,101,10,111,110,97,99,116,105,118,97,116,101, + 7,8,101,110,116,101,114,101,120,101,7,118,105,115,105,98,108,101,8,8, + 98,111,117,110,100,115,95,120,2,98,8,98,111,117,110,100,115,95,121,3, + 158,0,9,98,111,117,110,100,115,95,99,120,3,177,1,9,98,111,117,110, + 100,115,95,99,121,3,71,1,23,99,111,110,116,97,105,110,101,114,46,111, + 112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117, + 115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13, + 111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114, + 111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111, + 99,117,115,111,117,116,11,111,119,95,115,117,98,102,111,99,117,115,19,111, + 119,95,109,111,117,115,101,116,114,97,110,115,112,97,114,101,110,116,17,111, + 119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,26,99,111, + 110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,0,27,99,111,110,116,97,105,110,101,114,46,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,30,99,111,110, + 116,97,105,110,101,114,46,102,114,97,109,101,46,115,98,104,111,114,122,46, + 111,112,116,105,111,110,115,11,12,115,98,111,95,109,111,118,101,97,117,116, + 111,12,115,98,111,95,115,104,111,119,97,117,116,111,0,30,99,111,110,116, + 97,105,110,101,114,46,102,114,97,109,101,46,115,98,118,101,114,116,46,111, + 112,116,105,111,110,115,11,12,115,98,111,95,109,111,118,101,97,117,116,111, + 12,115,98,111,95,115,104,111,119,97,117,116,111,0,16,99,111,110,116,97, + 105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0,3,167,1,3, + 71,1,0,22,100,114,97,103,100,111,99,107,46,115,112,108,105,116,116,101, + 114,95,115,105,122,101,2,0,16,100,114,97,103,100,111,99,107,46,99,97, + 112,116,105,111,110,6,6,83,111,117,114,99,101,20,100,114,97,103,100,111, + 99,107,46,111,112,116,105,111,110,115,100,111,99,107,11,10,111,100,95,115, + 97,118,101,112,111,115,10,111,100,95,99,97,110,109,111,118,101,11,111,100, + 95,99,97,110,102,108,111,97,116,10,111,100,95,99,97,110,100,111,99,107, + 11,111,100,95,112,114,111,112,115,105,122,101,14,111,100,95,99,97,112,116, + 105,111,110,104,105,110,116,13,111,100,95,99,104,105,108,100,105,99,111,110, + 115,0,7,111,112,116,105,111,110,115,11,10,102,111,95,115,97,118,101,112, + 111,115,12,102,111,95,115,97,118,101,115,116,97,116,101,0,8,115,116,97, + 116,102,105,108,101,7,22,109,97,105,110,102,111,46,112,114,111,106,101,99, + 116,115,116,97,116,102,105,108,101,7,99,97,112,116,105,111,110,6,6,60, + 110,111,110,101,62,21,105,99,111,110,46,116,114,97,110,115,112,97,114,101, + 110,116,99,111,108,111,114,4,6,0,0,128,12,105,99,111,110,46,111,112, + 116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,0,10,105, + 99,111,110,46,105,109,97,103,101,10,136,7,0,0,0,0,0,0,2,0, + 0,0,24,0,0,0,24,0,0,0,244,6,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,208,208,208,25,136,136,136,13,130,136,136,1,136,136, + 136,1,208,208,208,9,136,136,136,1,179,248,254,1,182,248,254,1,185,249, + 254,1,188,250,254,1,191,250,254,1,194,251,254,1,198,251,254,1,201,252, + 254,1,204,253,254,1,207,253,254,1,210,254,254,1,213,254,254,1,127,135, + 135,1,159,197,200,1,136,136,136,1,208,208,208,8,136,136,136,1,179,248, + 254,1,182,248,254,1,185,249,254,1,188,250,254,1,191,250,254,1,194,251, + 254,1,198,251,254,1,201,252,254,1,204,253,254,1,207,253,254,1,210,254, + 254,1,213,254,254,1,131,137,138,1,198,249,255,1,158,197,200,1,136,136, + 136,1,208,208,208,7,136,136,136,1,179,248,254,1,182,248,254,1,185,249, + 254,1,188,250,254,1,191,250,254,1,194,251,254,1,198,251,254,1,201,252, + 254,1,204,253,254,1,207,253,254,1,210,254,254,1,213,254,254,1,133,138, + 138,1,226,252,255,1,197,249,255,1,158,197,200,1,136,136,136,1,208,208, + 208,6,136,136,136,1,179,248,254,1,182,248,254,1,185,249,254,1,188,250, + 254,1,191,250,254,1,194,251,254,1,198,251,254,1,201,252,254,1,204,253, + 254,1,207,253,254,1,210,254,254,1,213,254,254,1,130,137,138,1,254,254, + 255,1,225,252,255,1,195,249,255,1,158,197,200,1,136,136,136,1,208,208, + 208,5,136,136,136,1,179,248,254,1,182,248,254,1,184,247,252,1,91,121, + 123,1,191,250,254,1,130,168,170,1,193,244,247,1,199,249,251,1,196,243, + 244,1,205,250,251,1,142,171,171,1,213,254,254,1,127,137,138,1,223,252, + 255,1,252,254,255,1,223,252,255,1,194,249,255,1,157,196,200,1,136,136, + 136,1,208,208,208,4,136,136,136,1,179,248,254,1,182,248,254,1,136,183, + 186,1,102,135,137,1,151,197,200,1,89,115,117,1,111,141,142,1,117,146, + 147,1,144,179,179,1,122,149,149,1,96,116,116,1,213,254,254,1,124,137, + 138,1,190,249,255,1,225,252,255,1,250,254,255,1,221,252,255,1,192,249, + 255,1,157,196,200,1,136,136,136,1,208,208,208,3,136,136,136,1,179,248, + 254,1,182,248,254,1,110,148,151,1,164,219,222,1,109,143,145,1,91,118, + 120,1,124,157,159,1,128,160,161,1,134,166,166,1,125,153,153,1,98,119, + 119,1,213,254,254,1,121,137,138,1,158,246,255,1,192,249,255,1,227,252, + 255,1,249,254,255,1,220,251,255,1,190,249,255,1,157,196,200,1,136,136, + 136,1,208,208,208,2,136,136,136,1,179,248,254,1,182,248,254,1,185,249, + 254,1,188,250,254,1,191,250,254,1,194,251,254,1,198,251,254,1,201,252, + 254,1,204,253,254,1,207,253,254,1,210,254,254,1,213,254,254,1,130,150, + 151,1,120,137,138,1,122,137,138,1,124,137,138,1,126,137,138,2,122,137, + 138,1,119,134,135,1,129,136,136,1,208,208,208,2,136,136,136,1,179,248, + 254,1,182,248,254,1,185,249,254,1,188,250,254,1,191,250,254,1,194,251, + 254,1,198,251,254,1,201,252,254,1,198,245,246,1,206,252,253,1,204,247, + 247,1,208,248,248,1,204,250,251,1,187,246,248,1,176,250,254,1,156,239, + 245,1,147,246,254,1,132,244,254,1,117,243,254,1,102,241,254,1,136,136, + 136,1,208,208,208,2,136,136,136,1,179,248,254,1,182,248,254,1,185,249, + 254,1,188,250,254,1,191,250,254,1,194,251,254,1,198,251,254,1,195,244, + 246,1,87,108,109,1,114,140,140,1,116,140,140,1,157,187,187,1,126,155, + 155,1,106,140,141,1,106,151,153,1,71,108,111,1,133,223,230,1,132,244, + 254,1,117,243,254,1,102,241,254,1,136,136,136,1,208,208,208,2,136,136, + 136,1,179,248,254,1,182,248,254,1,185,249,254,1,188,250,254,1,191,250, + 254,1,194,251,254,1,198,251,254,1,196,246,248,1,106,132,132,1,146,179, + 179,1,126,152,152,1,147,175,175,1,126,155,155,1,103,136,137,1,116,165, + 167,1,97,149,152,1,139,232,240,1,132,244,254,1,117,243,254,1,102,241, + 254,1,136,136,136,1,208,208,208,2,136,136,136,1,179,248,254,1,182,248, + 254,1,185,249,254,1,188,250,254,1,191,250,254,1,194,251,254,1,198,251, + 254,1,201,252,254,1,204,253,254,1,207,253,254,1,210,254,254,1,213,254, + 254,1,206,253,254,1,191,252,254,1,176,250,254,1,162,248,254,1,147,246, + 254,1,132,244,254,1,117,243,254,1,102,241,254,1,136,136,136,1,208,208, + 208,2,136,136,136,1,179,248,254,1,182,248,254,1,185,249,254,1,188,250, + 254,1,191,250,254,1,194,251,254,1,198,251,254,1,201,252,254,1,195,242, + 243,1,147,180,180,1,205,248,248,1,206,246,246,1,202,248,249,1,184,243, + 245,1,170,241,245,1,159,243,249,1,142,238,246,1,131,243,253,1,117,243, + 254,1,102,241,254,1,136,136,136,1,208,208,208,2,136,136,136,1,179,248, + 254,1,182,248,254,1,185,249,254,1,188,250,254,1,191,250,254,1,194,251, + 254,1,198,251,254,1,188,236,238,1,117,145,145,1,111,136,136,1,119,143, + 143,1,100,120,120,1,116,142,142,1,129,170,171,1,119,169,171,1,93,142, + 145,1,63,105,109,1,71,131,136,1,117,243,254,1,102,241,254,1,136,136, + 136,1,208,208,208,2,136,136,136,1,179,248,254,1,182,248,254,1,185,249, + 254,1,188,250,254,1,191,250,254,1,194,251,254,1,198,251,254,1,190,238, + 240,1,115,143,143,1,116,142,142,1,131,158,158,1,99,119,119,1,128,158, + 158,1,160,210,212,1,119,170,172,1,93,142,145,1,77,128,132,1,92,169, + 176,1,117,243,254,1,102,241,254,1,136,136,136,1,208,208,208,2,136,136, + 136,1,179,248,254,1,182,248,254,1,185,249,254,1,188,250,254,1,191,250, + 254,1,194,251,254,1,198,251,254,1,201,252,254,1,204,253,254,1,207,253, + 254,1,150,181,181,1,137,163,163,1,206,253,254,1,173,228,230,1,119,169, + 171,1,126,194,198,1,147,246,254,1,132,244,254,1,117,243,254,1,102,241, + 254,1,136,136,136,1,208,208,208,2,136,136,136,1,179,248,254,1,182,248, + 254,1,185,249,254,1,181,241,245,1,163,214,217,1,194,251,254,1,167,212, + 214,1,136,170,171,1,181,224,225,1,161,196,197,1,193,233,233,1,213,254, + 254,1,206,253,254,1,191,252,254,1,176,250,254,1,162,248,254,1,147,246, + 254,1,132,244,254,1,117,243,254,1,102,241,254,1,136,136,136,1,208,208, + 208,2,136,136,136,1,179,248,254,1,182,248,254,1,110,148,151,1,81,108, + 110,1,116,152,154,1,126,162,164,1,120,152,153,1,125,156,157,1,91,113, + 114,1,148,181,181,1,189,229,229,1,213,254,254,1,206,253,254,1,191,252, + 254,1,176,250,254,1,162,248,254,1,147,246,254,1,132,244,254,1,117,243, + 254,1,102,241,254,1,136,136,136,1,208,208,208,2,136,136,136,1,179,248, + 254,1,182,248,254,1,120,162,165,1,113,150,152,1,121,158,160,1,130,168, + 170,1,120,153,154,1,125,156,157,1,125,155,155,1,127,156,156,1,189,229, + 229,1,213,254,254,1,206,253,254,1,191,252,254,1,176,250,254,1,162,248, + 254,1,147,246,254,1,132,244,254,1,117,243,254,1,102,241,254,1,136,136, + 136,1,208,208,208,2,136,136,136,1,179,248,254,1,182,248,254,1,185,249, + 254,1,188,250,254,1,191,250,254,1,194,251,254,1,198,251,254,1,201,252, + 254,1,204,253,254,1,207,253,254,1,210,254,254,1,213,254,254,1,206,253, + 254,1,191,252,254,1,176,250,254,1,162,248,254,1,147,246,254,1,132,244, + 254,1,117,243,254,1,102,241,254,1,136,136,136,1,208,208,208,2,136,136, + 136,22,208,208,208,25,0,0,0,8,254,255,0,8,254,255,1,191,254,255, + 3,8,254,255,7,0,254,255,15,8,254,255,31,2,254,255,63,192,254,255, + 127,0,254,255,127,8,254,255,127,0,254,255,127,8,254,255,127,8,254,255, + 127,8,254,255,127,191,254,255,127,8,254,255,127,0,254,255,127,2,254,255, + 127,8,254,255,127,0,254,255,127,0,254,255,127,191,254,255,127,0,0,0, + 0,8,12,111,110,99,108,111,115,101,113,117,101,114,121,7,20,115,111,117, + 114,99,101,102,111,111,110,99,108,111,115,101,113,117,101,114,121,6,111,110, + 105,100,108,101,7,10,102,111,114,109,111,110,105,100,108,101,15,109,111,100, + 117,108,101,99,108,97,115,115,110,97,109,101,6,9,116,100,111,99,107,102, + 111,114,109,0,10,116,116,97,98,119,105,100,103,101,116,9,116,97,98,119, + 105,100,103,101,116,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,167,1, + 9,98,111,117,110,100,115,95,99,121,3,71,1,7,97,110,99,104,111,114, + 115,11,0,9,112,111,112,117,112,109,101,110,117,7,9,102,111,114,109,112, + 111,112,117,112,19,111,110,97,99,116,105,118,101,112,97,103,101,99,104,97, + 110,103,101,100,7,28,116,97,98,119,105,100,103,101,116,111,110,97,99,116, + 105,118,101,112,97,103,101,99,104,97,110,103,101,100,13,111,110,112,97,103, + 101,114,101,109,111,118,101,100,7,20,116,97,98,119,105,100,103,101,116,112, + 97,103,101,114,101,109,111,118,101,100,11,116,97,98,95,111,112,116,105,111, + 110,115,11,15,116,97,98,111,95,100,114,97,103,115,111,117,114,99,101,13, + 116,97,98,111,95,100,114,97,103,100,101,115,116,13,116,97,98,111,95,118, + 101,114,116,105,99,97,108,13,116,97,98,111,95,111,112,112,111,115,105,116, + 101,14,116,97,98,111,95,116,97,98,115,105,122,105,110,103,23,116,97,98, + 111,95,100,98,108,99,108,105,99,107,101,100,116,97,98,102,105,114,115,116, + 20,116,97,98,111,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120, + 116,0,19,116,97,98,95,102,114,97,109,101,46,98,117,116,116,111,110,112, + 111,115,7,7,115,98,112,95,116,111,112,21,116,97,98,95,102,114,97,109, + 101,46,98,117,116,116,111,110,115,108,97,115,116,9,24,116,97,98,95,102, + 114,97,109,101,46,98,117,116,116,111,110,115,118,105,115,105,98,108,101,11, + 8,115,107,95,114,105,103,104,116,5,115,107,95,117,112,7,115,107,95,108, + 101,102,116,7,115,107,95,100,111,119,110,8,115,107,95,102,105,114,115,116, + 7,115,107,95,108,97,115,116,0,20,116,97,98,95,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,15,102,114,108,95,111,112,116,105, + 111,110,115,115,107,105,110,0,21,116,97,98,95,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,13,116,97,98,95,116,101,120, + 116,102,108,97,103,115,11,12,116,102,95,121,99,101,110,116,101,114,101,100, + 0,11,116,97,98,95,115,105,122,101,109,105,110,2,60,8,116,97,98,95, + 115,105,122,101,2,60,18,116,97,98,95,111,112,116,105,111,110,115,119,105, + 100,103,101,116,49,11,0,0,17,116,115,116,111,99,107,103,108,121,112,104, + 98,117,116,116,111,110,18,116,115,116,111,99,107,103,108,121,112,104,98,117, + 116,116,111,110,49,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,15,111, + 119,95,100,105,115,97,98,108,101,100,104,105,110,116,12,111,119,95,116,105, + 109,101,100,104,105,110,116,0,8,116,97,98,111,114,100,101,114,2,2,4, + 104,105,110,116,6,28,83,116,101,112,32,98,97,99,107,32,105,110,32,99, + 111,100,101,32,110,97,118,105,103,97,116,105,111,110,10,111,110,115,104,111, + 119,104,105,110,116,7,10,115,116,101,112,104,105,110,116,101,118,8,98,111, + 117,110,100,115,95,120,3,127,1,8,98,111,117,110,100,115,95,121,2,0, + 9,98,111,117,110,100,115,95,99,120,2,20,9,98,111,117,110,100,115,95, + 99,121,2,20,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112, + 8,97,110,95,114,105,103,104,116,0,5,115,116,97,116,101,11,11,97,115, + 95,100,105,115,97,98,108,101,100,17,97,115,95,108,111,99,97,108,105,109, + 97,103,101,108,105,115,116,15,97,115,95,108,111,99,97,108,105,109,97,103, + 101,110,114,18,97,115,95,108,111,99,97,108,99,111,108,111,114,103,108,121, + 112,104,12,97,115,95,108,111,99,97,108,104,105,110,116,17,97,115,95,108, + 111,99,97,108,111,110,101,120,101,99,117,116,101,0,5,103,108,121,112,104, + 7,13,115,116,103,95,97,114,114,111,119,108,101,102,116,6,97,99,116,105, + 111,110,7,12,110,97,118,105,103,98,97,99,107,97,99,116,10,99,111,108, + 111,114,103,108,121,112,104,4,9,0,0,160,9,111,110,101,120,101,99,117, + 116,101,7,9,110,97,118,105,103,98,97,99,107,0,0,17,116,115,116,111, + 99,107,103,108,121,112,104,98,117,116,116,111,110,18,116,115,116,111,99,107, + 103,108,121,112,104,98,117,116,116,111,110,50,13,111,112,116,105,111,110,115, + 119,105,100,103,101,116,11,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,15,111,119,95,100,105,115,97,98,108,101,100,104,105,110, + 116,12,111,119,95,116,105,109,101,100,104,105,110,116,0,8,116,97,98,111, + 114,100,101,114,2,1,4,104,105,110,116,6,31,83,116,101,112,32,102,111, + 114,119,97,114,100,32,105,110,32,99,111,100,101,32,110,97,118,105,103,97, + 116,105,111,110,10,111,110,115,104,111,119,104,105,110,116,7,10,115,116,101, + 112,104,105,110,116,101,118,8,98,111,117,110,100,115,95,120,3,147,1,8, + 98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120, + 2,20,9,98,111,117,110,100,115,95,99,121,2,20,7,97,110,99,104,111, + 114,115,11,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0, + 5,115,116,97,116,101,11,11,97,115,95,100,105,115,97,98,108,101,100,17, + 97,115,95,108,111,99,97,108,105,109,97,103,101,108,105,115,116,15,97,115, + 95,108,111,99,97,108,105,109,97,103,101,110,114,18,97,115,95,108,111,99, + 97,108,99,111,108,111,114,103,108,121,112,104,12,97,115,95,108,111,99,97, + 108,104,105,110,116,0,5,103,108,121,112,104,7,14,115,116,103,95,97,114, + 114,111,119,114,105,103,104,116,6,97,99,116,105,111,110,7,15,110,97,118, + 105,103,102,111,114,119,97,114,100,97,99,116,10,99,111,108,111,114,103,108, + 121,112,104,4,9,0,0,160,0,0,0,14,116,115,121,110,116,97,120,112, + 97,105,110,116,101,114,13,115,121,110,116,97,120,112,97,105,110,116,101,114, + 12,100,101,102,100,101,102,115,46,100,97,116,97,1,1,6,5,42,46,112, + 97,115,6,8,112,97,115,46,115,100,101,102,0,0,4,108,101,102,116,2, + 32,3,116,111,112,2,64,0,0,10,116,105,109,97,103,101,108,105,115,116, + 9,105,109,97,103,101,108,105,115,116,5,99,111,117,110,116,2,14,4,108, + 101,102,116,2,33,3,116,111,112,2,93,5,105,109,97,103,101,10,236,13, + 0,0,0,0,0,0,2,0,0,0,64,0,0,0,64,0,0,0,184,11, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,170,0,0, + 0,1,255,255,255,62,0,0,0,3,255,255,255,29,0,0,255,3,255,255, + 255,13,0,0,255,3,255,255,255,13,0,0,0,3,255,255,255,28,0,0, + 255,5,255,255,255,11,0,0,255,1,255,255,255,3,0,0,255,1,255,255, + 255,12,0,0,0,3,255,255,255,7,255,0,0,2,255,255,255,18,0,0, + 255,7,255,255,255,9,0,0,255,1,255,255,255,5,0,0,255,1,255,255, + 255,11,0,0,0,3,255,255,255,6,255,0,0,1,255,255,0,1,255,0, + 0,2,255,255,255,17,0,0,255,7,255,255,255,9,0,0,255,1,255,255, + 255,5,0,0,255,1,255,255,255,11,0,0,0,3,255,255,255,6,255,0, + 0,4,255,255,255,17,0,0,255,7,255,255,255,9,0,0,255,1,255,255, + 255,5,0,0,255,1,255,255,255,11,0,0,0,3,255,255,255,7,255,0, + 0,2,255,255,255,19,0,0,255,5,255,255,255,11,0,0,255,1,255,255, + 255,3,0,0,255,1,255,255,255,13,0,0,0,1,255,255,255,30,0,0, + 255,3,255,255,255,13,0,0,255,3,255,255,255,78,0,0,0,1,255,255, + 255,62,0,0,0,3,255,255,255,62,0,0,0,1,255,255,255,154,0,217, + 0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255, + 255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217, + 0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255, + 255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217, + 0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255, + 255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217, + 0,5,255,255,255,11,0,197,0,1,0,53,0,1,0,32,0,1,0,53, + 0,1,0,197,0,1,255,255,255,11,0,196,0,1,0,8,0,1,0,217, + 0,3,255,255,255,11,0,62,0,1,0,18,0,1,0,30,0,1,0,49, + 0,1,0,176,0,1,255,255,255,11,0,144,0,1,0,54,0,1,0,34, + 0,1,0,31,0,1,0,151,0,1,255,255,255,11,0,88,0,1,0,128, + 0,1,0,217,0,1,0,133,0,1,0,89,0,1,255,255,255,11,0,22, + 0,1,0,7,0,1,0,217,0,3,255,255,255,11,0,54,0,1,0,193, + 0,1,0,217,0,1,0,162,0,1,0,38,0,1,255,255,255,11,0,217, + 0,3,0,182,0,1,0,20,0,1,255,255,255,11,0,31,0,1,0,200, + 0,1,0,217,0,1,0,204,0,1,0,32,0,1,255,255,255,11,0,217, + 0,1,0,13,0,1,0,217,0,3,255,255,255,11,0,217,0,3,0,214, + 0,1,0,14,0,1,255,255,255,11,0,217,0,2,0,214,0,1,0,132, + 0,1,0,68,0,1,255,255,255,11,0,12,0,1,0,217,0,3,0,15, + 0,1,255,255,255,11,0,217,0,1,0,13,0,1,0,217,0,3,255,255, + 255,11,0,217,0,3,0,151,0,1,0,59,0,1,255,255,255,11,0,217, + 0,2,0,24,0,1,0,61,0,1,0,195,0,1,255,255,255,11,0,12, + 0,1,0,217,0,3,0,14,0,1,255,255,255,11,0,217,0,1,0,13, + 0,1,0,217,0,3,255,255,255,11,0,217,0,2,0,185,0,1,0,27, + 0,1,0,174,0,1,255,255,255,11,0,217,0,2,0,215,0,1,0,132, + 0,1,0,49,0,1,255,255,255,11,0,31,0,1,0,203,0,1,0,217, + 0,1,0,204,0,1,0,31,0,1,255,255,255,11,0,217,0,1,0,13, + 0,1,0,217,0,3,255,255,255,11,0,217,0,1,0,168,0,1,0,33, + 0,1,0,162,0,1,0,217,0,1,255,255,255,11,0,217,0,3,0,216, + 0,1,0,14,0,1,255,255,255,11,0,88,0,1,0,132,0,1,0,217, + 0,1,0,134,0,1,0,89,0,1,255,255,255,11,0,217,0,1,0,13, + 0,1,0,217,0,3,255,255,255,11,0,128,0,1,0,44,0,1,0,187, + 0,1,0,217,0,2,255,255,255,11,0,66,0,1,0,193,0,1,0,217, + 0,1,0,145,0,1,0,55,0,1,255,255,255,11,0,197,0,1,0,52, + 0,1,0,32,0,1,0,53,0,1,0,197,0,1,255,255,255,11,0,43, + 0,1,0,3,0,1,0,43,0,2,0,217,0,1,255,255,255,11,0,0, + 0,1,0,26,0,1,0,33,0,3,255,255,255,11,0,67,0,1,0,18, + 0,1,0,31,0,1,0,56,0,1,0,190,0,1,255,255,255,11,0,217, + 0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255, + 255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217, + 0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255, + 255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217, + 0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255, + 255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217, + 0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255, + 255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217, + 0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255, + 255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217, + 0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255, + 255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217, + 0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217,0,2,0,151, + 0,1,0,4,0,1,0,217,0,1,255,255,255,11,0,7,0,1,0,33, + 0,2,0,39,0,1,0,217,0,1,255,255,255,11,0,217,0,1,0,123, + 0,1,0,33,0,2,0,211,0,1,255,255,255,11,0,33,0,4,0,3, + 0,1,255,255,255,11,0,217,0,1,0,191,0,1,0,48,0,1,0,8, + 0,1,0,217,0,1,255,255,255,11,0,9,0,1,0,217,0,4,255,255, + 255,11,0,147,0,1,0,53,0,1,0,206,0,1,0,217,0,2,255,255, + 255,11,0,217,0,3,0,180,0,1,0,43,0,1,255,255,255,11,0,213, + 0,1,0,54,0,1,0,177,0,1,0,9,0,1,0,217,0,1,255,255, + 255,11,0,9,0,1,0,217,0,4,255,255,255,11,0,57,0,1,0,169, + 0,1,0,217,0,3,255,255,255,11,0,217,0,3,0,73,0,1,0,146, + 0,1,255,255,255,11,0,95,0,1,0,129,0,1,0,217,0,1,0,9, + 0,1,0,217,0,1,255,255,255,11,0,9,0,1,0,32,0,1,0,44, + 0,1,0,170,0,1,0,217,0,1,255,255,255,11,0,19,0,1,0,71, + 0,1,0,34,0,1,0,48,0,1,0,178,0,1,255,255,255,11,0,217, + 0,2,0,183,0,1,0,36,0,1,0,215,0,1,255,255,255,10,184,184, + 184,1,0,76,0,1,0,217,0,2,0,9,0,1,0,217,0,1,255,255, + 255,11,0,213,0,1,0,217,0,1,0,169,0,1,0,39,0,1,0,217, + 0,1,255,255,255,11,0,11,0,1,0,191,0,1,0,217,0,1,0,153, + 0,1,0,43,0,1,255,255,255,11,0,217,0,2,0,77,0,1,0,137, + 0,1,0,217,0,1,255,255,255,10,149,149,149,1,0,30,0,1,0,33, + 0,2,0,1,0,1,0,33,0,1,249,249,249,1,255,255,255,10,0,217, + 0,2,0,216,0,1,0,14,0,1,0,217,0,1,255,255,255,11,0,26, + 0,1,0,209,0,1,0,217,0,1,0,216,0,1,0,14,0,1,255,255, + 255,11,0,217,0,1,0,186,0,1,0,31,0,1,0,214,0,1,0,217, + 0,1,255,255,255,11,0,217,0,3,0,9,0,1,0,217,0,1,255,255, + 255,11,0,141,0,1,0,217,0,1,0,154,0,1,0,52,0,1,0,217, + 0,1,255,255,255,11,0,86,0,1,0,127,0,1,0,217,0,1,0,157, + 0,1,0,55,0,1,255,255,255,11,0,217,0,1,0,81,0,1,0,129, + 0,1,0,217,0,2,255,255,255,11,0,217,0,3,0,9,0,1,0,217, + 0,1,255,255,255,11,0,54,0,1,0,30,0,1,0,36,0,1,0,180, + 0,1,0,217,0,1,255,255,255,11,0,201,0,1,0,57,0,1,0,31, + 0,1,0,49,0,1,0,188,0,1,255,255,255,11,0,189,0,1,0,26, + 0,1,0,211,0,1,0,217,0,2,255,255,255,11,0,217,0,5,255,255, + 255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217, + 0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255, + 255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217, + 0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255, + 255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217, + 0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255, + 255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255,255,27,0,255, + 0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255, + 255,27,0,255,0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217, + 0,5,255,255,255,27,0,255,0,5,255,255,255,11,0,217,0,5,255,255, + 255,11,0,217,0,5,255,255,255,27,0,255,0,5,255,255,255,11,0,168, + 0,1,0,42,0,1,0,31,0,1,0,37,0,1,0,161,0,1,255,255, + 255,11,0,188,0,1,0,50,0,1,0,31,0,1,0,60,0,1,0,200, + 0,1,255,255,255,12,232,248,232,1,62,197,62,1,38,189,38,1,62,197, + 62,1,232,248,232,1,255,255,255,10,0,232,0,1,0,62,0,1,0,38, + 0,1,0,62,0,1,0,232,0,1,255,255,255,11,0,30,0,1,0,180, + 0,1,0,217,0,1,0,174,0,1,0,26,0,1,255,255,255,11,0,54, + 0,1,0,151,0,1,0,217,0,1,0,130,0,1,0,84,0,1,255,255, + 255,12,103,209,103,1,150,223,150,1,255,255,255,1,156,225,156,1,105,210, + 105,1,255,255,255,10,0,103,0,1,0,150,0,1,0,255,0,1,0,156, + 0,1,0,105,0,1,255,255,255,11,0,31,0,1,0,174,0,1,0,217, + 0,1,0,203,0,1,0,33,0,1,255,255,255,11,0,11,0,1,0,214, + 0,1,0,217,0,1,0,210,0,1,0,26,0,1,255,255,255,12,37,189, + 37,1,235,249,235,1,255,255,255,1,240,250,240,1,38,189,38,1,255,255, + 255,10,0,37,0,1,0,235,0,1,0,255,0,1,0,240,0,1,0,38, + 0,1,255,255,255,11,0,156,0,1,0,5,0,1,0,66,0,1,0,58, + 0,1,0,148,0,1,255,255,255,11,0,42,0,1,0,151,0,1,0,217, + 0,1,0,195,0,1,0,14,0,1,255,255,255,12,14,182,14,1,255,255, + 255,3,18,183,18,1,255,255,255,10,0,14,0,1,0,255,0,3,0,18, + 0,1,255,255,255,11,0,86,0,1,0,147,0,1,0,173,0,1,0,69, + 0,1,0,77,0,1,255,255,255,11,0,178,0,1,0,49,0,1,0,35, + 0,1,0,73,0,1,0,21,0,1,255,255,255,12,14,182,14,1,255,255, + 255,3,17,183,17,1,255,255,255,10,0,14,0,1,0,255,0,3,0,17, + 0,1,255,255,255,11,0,14,0,1,0,214,0,1,0,217,0,1,0,211, + 0,1,0,11,0,1,255,255,255,11,0,217,0,3,0,173,0,1,0,61, + 0,1,255,255,255,12,36,189,36,1,239,250,239,1,255,255,255,1,240,250, + 240,1,37,189,37,1,255,255,255,10,0,36,0,1,0,239,0,1,0,255, + 0,1,0,240,0,1,0,37,0,1,255,255,255,11,0,39,0,1,0,147, + 0,1,0,217,0,1,0,166,0,1,0,40,0,1,255,255,255,11,0,217, + 0,2,0,208,0,1,0,57,0,1,0,148,0,1,255,255,255,12,103,209, + 103,1,155,225,155,1,255,255,255,1,158,226,158,1,104,209,104,1,255,255, + 255,10,0,103,0,1,0,155,0,1,0,255,0,1,0,158,0,1,0,104, + 0,1,255,255,255,11,0,174,0,1,0,41,0,1,0,28,0,1,0,46, + 0,1,0,179,0,1,255,255,255,11,0,214,0,1,0,34,0,2,0,125, + 0,1,0,217,0,1,255,255,255,12,231,248,231,1,61,196,61,1,38,189, + 38,1,62,197,62,1,232,248,232,1,255,255,255,10,0,231,0,1,0,61, + 0,1,0,38,0,1,0,62,0,1,0,232,0,1,255,255,255,11,0,217, + 0,5,255,255,255,11,0,217,0,5,255,255,255,27,0,255,0,5,255,255, + 255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255,255,27,0,255, + 0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217,0,5,255,255, + 255,27,0,255,0,5,255,255,255,11,0,217,0,5,255,255,255,11,0,217, + 0,5,255,255,255,27,0,255,0,5,255,255,255,6,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0, + 0,0,0,14,0,0,0,14,0,14,0,14,0,0,0,31,0,17,0,14, + 24,0,128,63,128,32,0,14,60,0,128,63,128,32,0,14,60,0,128,63, + 128,32,0,14,24,0,0,31,0,17,0,4,0,0,0,14,0,14,0,0, + 0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,14,0,0,0,0, + 0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3, + 224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3, + 224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3, + 224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3, + 224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3, + 224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3, + 224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3, + 224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3, + 224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3, + 224,3,224,3,224,3,224,3,224,3,224,3,224,3,240,3,224,3,224,3, + 224,3,240,7,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3, + 224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3, + 224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3,224,3, + 224,3,0,0,224,3,224,3,224,3,0,0,224,3,224,3,224,3,0,0, + 224,3,224,3,224,3,0,0,224,3,224,3,224,3,192,7,224,3,224,3, + 224,3,192,6,224,3,224,3,224,3,192,6,224,3,224,3,224,3,64,4, + 224,3,224,3,224,3,64,4,224,3,224,3,224,3,192,6,224,3,224,3, + 224,3,192,6,224,3,224,3,224,3,192,7,224,3,224,3,224,3,0,0, + 224,3,224,3,224,3,0,0,224,3,224,3,224,3,0,0,224,3,224,3, + 224,3,0,0,224,3,0,0,19,116,102,105,108,101,99,104,97,110,103,101, + 110,111,116,105,102,121,101,114,18,102,105,108,101,99,104,97,110,103,101,110, + 111,116,105,102,121,101,114,13,111,110,102,105,108,101,99,104,97,110,103,101, + 100,7,13,111,110,102,105,108,101,99,104,97,110,103,101,100,4,108,101,102, + 116,2,32,3,116,111,112,3,168,0,0,0,7,116,97,99,116,105,111,110, + 15,110,97,118,105,103,102,111,114,119,97,114,100,97,99,116,5,115,116,97, + 116,101,11,11,97,115,95,100,105,115,97,98,108,101,100,0,9,111,110,101, + 120,101,99,117,116,101,7,12,110,97,118,105,103,102,111,114,119,97,114,100, + 4,108,101,102,116,2,32,3,116,111,112,2,16,2,115,99,1,2,1,3, + 72,96,0,0,0,7,116,97,99,116,105,111,110,12,110,97,118,105,103,98, + 97,99,107,97,99,116,5,115,116,97,116,101,11,11,97,115,95,100,105,115, + 97,98,108,101,100,0,9,111,110,101,120,101,99,117,116,101,7,9,110,97, + 118,105,103,98,97,99,107,4,108,101,102,116,2,32,3,116,111,112,2,40, + 2,115,99,1,2,1,3,72,64,0,0,0,10,116,112,111,112,117,112,109, + 101,110,117,9,102,111,114,109,112,111,112,117,112,8,111,110,117,112,100,97, + 116,101,7,14,112,111,112,117,112,109,111,110,117,112,100,97,116,101,18,109, + 101,110,117,46,115,117,98,109,101,110,117,46,99,111,117,110,116,2,30,18, + 109,101,110,117,46,115,117,98,109,101,110,117,46,105,116,101,109,115,14,1, + 6,97,99,116,105,111,110,7,24,97,99,116,105,111,110,115,109,111,46,115, + 101,108,101,99,116,101,100,105,116,112,97,103,101,7,99,97,112,116,105,111, + 110,6,11,83,101,108,101,99,116,32,80,97,103,101,5,115,116,97,116,101, + 11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115, + 95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101, + 120,101,99,117,116,101,7,12,100,111,115,101,108,101,99,116,112,97,103,101, + 0,1,6,97,99,116,105,111,110,7,20,97,99,116,105,111,110,115,109,111, + 46,111,112,101,110,115,111,117,114,99,101,7,99,97,112,116,105,111,110,6, + 10,38,79,112,101,110,32,70,105,108,101,5,115,116,97,116,101,11,15,97, + 115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,0,1,6,97,99, + 116,105,111,110,7,15,97,99,116,105,111,110,115,109,111,46,99,108,111,115, + 101,7,99,97,112,116,105,111,110,6,11,38,67,108,111,115,101,32,70,105, + 108,101,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97, + 112,116,105,111,110,0,7,111,112,116,105,111,110,115,11,19,109,97,111,95, + 115,104,111,114,116,99,117,116,99,97,112,116,105,111,110,16,109,97,111,95, + 97,115,121,110,99,101,120,101,99,117,116,101,0,0,1,6,97,99,116,105, + 111,110,7,14,97,99,116,105,111,110,115,109,111,46,115,97,118,101,7,99, + 97,112,116,105,111,110,6,10,38,83,97,118,101,32,70,105,108,101,5,115, + 116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111, + 110,0,0,1,6,97,99,116,105,111,110,7,16,97,99,116,105,111,110,115, + 109,111,46,115,97,118,101,97,115,0,1,7,99,97,112,116,105,111,110,6, + 12,83,104,111,119,32,97,115,32,70,111,114,109,4,110,97,109,101,6,10, + 115,104,111,119,97,115,102,111,114,109,5,115,116,97,116,101,11,15,97,115, + 95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99, + 97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117, + 116,101,7,13,115,104,111,119,97,115,102,111,114,109,101,120,101,0,1,7, + 111,112,116,105,111,110,115,11,13,109,97,111,95,115,101,112,97,114,97,116, + 111,114,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105, + 111,110,0,0,1,6,97,99,116,105,111,110,7,16,97,99,116,105,111,110, + 115,109,111,46,100,101,108,101,116,101,0,1,6,97,99,116,105,111,110,7, + 13,97,99,116,105,111,110,115,109,111,46,99,117,116,0,1,6,97,99,116, + 105,111,110,7,14,97,99,116,105,111,110,115,109,111,46,99,111,112,121,0, + 1,6,97,99,116,105,111,110,7,22,97,99,116,105,111,110,115,109,111,46, + 99,111,112,121,108,97,116,101,120,97,99,116,0,1,6,97,99,116,105,111, + 110,7,15,97,99,116,105,111,110,115,109,111,46,112,97,115,116,101,0,1, + 6,97,99,116,105,111,110,7,19,97,99,116,105,111,110,115,109,111,46,115, + 101,108,101,99,116,97,108,108,0,1,7,111,112,116,105,111,110,115,11,13, + 109,97,111,95,115,101,112,97,114,97,116,111,114,19,109,97,111,95,115,104, + 111,114,116,99,117,116,99,97,112,116,105,111,110,0,0,1,6,97,99,116, + 105,111,110,7,14,97,99,116,105,111,110,115,109,111,46,117,110,100,111,0, + 1,6,97,99,116,105,111,110,7,14,97,99,116,105,111,110,115,109,111,46, + 114,101,100,111,0,1,7,111,112,116,105,111,110,115,11,13,109,97,111,95, + 115,101,112,97,114,97,116,111,114,19,109,97,111,95,115,104,111,114,116,99, + 117,116,99,97,112,116,105,111,110,0,0,1,13,115,117,98,109,101,110,117, + 46,99,111,117,110,116,2,8,13,115,117,98,109,101,110,117,46,105,116,101, + 109,115,14,1,6,97,99,116,105,111,110,7,16,97,99,116,105,111,110,115, + 109,111,46,105,110,100,101,110,116,0,1,6,97,99,116,105,111,110,7,18, + 97,99,116,105,111,110,115,109,111,46,117,110,105,110,100,101,110,116,0,1, + 6,97,99,116,105,111,110,7,17,97,99,116,105,111,110,115,109,111,46,99, + 111,109,109,101,110,116,0,1,6,97,99,116,105,111,110,7,19,97,99,116, + 105,111,110,115,109,111,46,117,110,99,111,109,109,101,110,116,0,1,6,97, + 99,116,105,111,110,7,19,97,99,116,105,111,110,115,109,111,46,108,111,119, + 101,114,99,97,115,101,0,1,6,97,99,116,105,111,110,7,19,97,99,116, + 105,111,110,115,109,111,46,117,112,112,101,114,99,97,115,101,0,1,6,97, + 99,116,105,111,110,7,20,97,99,116,105,111,110,115,109,111,46,116,97,98, + 116,111,115,112,97,99,101,0,1,7,99,97,112,116,105,111,110,6,25,67, + 111,110,118,101,114,116,32,116,111,32,38,80,97,115,99,97,108,32,115,116, + 114,105,110,103,4,110,97,109,101,6,7,99,111,110,118,112,97,115,5,115, + 116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111, + 110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0, + 9,111,110,101,120,101,99,117,116,101,7,9,99,111,110,118,112,97,115,101, + 120,0,0,7,99,97,112,116,105,111,110,6,17,38,77,111,100,105,102,121, + 32,83,101,108,101,99,116,105,111,110,4,110,97,109,101,6,15,109,111,100, + 105,102,121,115,101,108,101,99,116,105,111,110,5,115,116,97,116,101,11,15, + 97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,0,1,7,111, + 112,116,105,111,110,115,11,13,109,97,111,95,115,101,112,97,114,97,116,111, + 114,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111, + 110,0,0,1,6,97,99,116,105,111,110,7,20,97,99,116,105,111,110,115, + 109,111,46,116,111,103,103,108,101,98,107,112,116,0,1,6,97,99,116,105, + 111,110,7,26,97,99,116,105,111,110,115,109,111,46,116,111,103,103,108,101, + 98,107,112,116,101,110,97,98,108,101,0,1,7,99,97,112,116,105,111,110, + 6,16,38,69,100,105,116,32,98,114,101,97,107,112,111,105,110,116,4,110, + 97,109,101,6,14,101,100,105,116,98,114,101,97,107,112,111,105,110,116,5, + 115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105, + 111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101, + 0,7,111,112,116,105,111,110,115,11,19,109,97,111,95,115,104,111,114,116, + 99,117,116,99,97,112,116,105,111,110,16,109,97,111,95,97,115,121,110,99, + 101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7,18, + 101,100,105,116,98,114,101,97,107,112,111,105,110,116,101,120,101,99,0,1, + 7,99,97,112,116,105,111,110,6,20,65,100,100,32,38,87,97,116,99,104, + 32,97,116,32,67,117,114,115,111,114,4,110,97,109,101,6,8,97,100,100, + 119,97,116,99,104,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101, + 120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7,20,97, + 100,100,119,97,116,99,104,97,99,116,111,110,101,120,101,99,117,116,101,0, + 1,13,115,117,98,109,101,110,117,46,99,111,117,110,116,2,11,13,115,117, + 98,109,101,110,117,46,105,116,101,109,115,14,1,6,97,99,116,105,111,110, + 7,16,97,99,116,105,111,110,115,109,111,46,115,101,116,98,109,48,0,1, + 6,97,99,116,105,111,110,7,16,97,99,116,105,111,110,115,109,111,46,115, + 101,116,98,109,49,0,1,6,97,99,116,105,111,110,7,16,97,99,116,105, + 111,110,115,109,111,46,115,101,116,98,109,50,0,1,6,97,99,116,105,111, + 110,7,16,97,99,116,105,111,110,115,109,111,46,115,101,116,98,109,51,0, + 1,6,97,99,116,105,111,110,7,16,97,99,116,105,111,110,115,109,111,46, + 115,101,116,98,109,52,0,1,6,97,99,116,105,111,110,7,16,97,99,116, + 105,111,110,115,109,111,46,115,101,116,98,109,53,0,1,6,97,99,116,105, + 111,110,7,16,97,99,116,105,111,110,115,109,111,46,115,101,116,98,109,54, + 0,1,6,97,99,116,105,111,110,7,16,97,99,116,105,111,110,115,109,111, + 46,115,101,116,98,109,55,0,1,6,97,99,116,105,111,110,7,16,97,99, + 116,105,111,110,115,109,111,46,115,101,116,98,109,56,0,1,6,97,99,116, + 105,111,110,7,16,97,99,116,105,111,110,115,109,111,46,115,101,116,98,109, + 57,0,1,6,97,99,116,105,111,110,7,19,97,99,116,105,111,110,115,109, + 111,46,115,101,116,98,109,110,111,110,101,0,0,7,99,97,112,116,105,111, + 110,6,12,83,101,116,32,66,111,111,107,109,97,114,107,4,110,97,109,101, + 6,5,115,101,116,98,109,5,115,116,97,116,101,11,15,97,115,95,108,111, + 99,97,108,99,97,112,116,105,111,110,0,0,1,13,115,117,98,109,101,110, + 117,46,99,111,117,110,116,2,10,13,115,117,98,109,101,110,117,46,105,116, + 101,109,115,14,1,6,97,99,116,105,111,110,7,17,97,99,116,105,111,110, + 115,109,111,46,102,105,110,100,98,109,48,0,1,6,97,99,116,105,111,110, + 7,17,97,99,116,105,111,110,115,109,111,46,102,105,110,100,98,109,49,0, + 1,6,97,99,116,105,111,110,7,17,97,99,116,105,111,110,115,109,111,46, + 102,105,110,100,98,109,50,0,1,6,97,99,116,105,111,110,7,17,97,99, + 116,105,111,110,115,109,111,46,102,105,110,100,98,109,51,0,1,6,97,99, + 116,105,111,110,7,17,97,99,116,105,111,110,115,109,111,46,102,105,110,100, + 98,109,52,0,1,6,97,99,116,105,111,110,7,17,97,99,116,105,111,110, + 115,109,111,46,102,105,110,100,98,109,53,0,1,6,97,99,116,105,111,110, + 7,17,97,99,116,105,111,110,115,109,111,46,102,105,110,100,98,109,54,0, + 1,6,97,99,116,105,111,110,7,17,97,99,116,105,111,110,115,109,111,46, + 102,105,110,100,98,109,55,0,1,6,97,99,116,105,111,110,7,17,97,99, + 116,105,111,110,115,109,111,46,102,105,110,100,98,109,56,0,1,6,97,99, + 116,105,111,110,7,17,97,99,116,105,111,110,115,109,111,46,102,105,110,100, + 98,109,57,0,0,7,99,97,112,116,105,111,110,6,13,70,105,110,100,32, + 66,111,111,107,109,97,114,107,5,115,116,97,116,101,11,15,97,115,95,108, + 111,99,97,108,99,97,112,116,105,111,110,0,0,1,7,111,112,116,105,111, + 110,115,11,13,109,97,111,95,115,101,112,97,114,97,116,111,114,19,109,97, + 111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111,110,0,0,1, + 7,99,97,112,116,105,111,110,6,11,73,110,115,101,114,116,32,71,85,73, + 68,4,110,97,109,101,6,6,105,110,115,103,117,105,5,115,116,97,116,101, + 11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115, + 95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101, + 120,101,99,117,116,101,7,10,105,110,115,103,117,105,101,120,101,99,0,1, + 7,99,97,112,116,105,111,110,6,10,73,110,115,101,114,116,32,85,73,68, + 4,110,97,109,101,6,6,105,110,115,117,105,100,5,115,116,97,116,101,11, + 15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95, + 108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120, + 101,99,117,116,101,7,10,105,110,115,117,105,100,101,120,101,99,0,1,6, + 97,99,116,105,111,110,7,21,97,99,116,105,111,110,115,109,111,46,105,110, + 115,116,101,109,112,108,97,116,101,7,99,97,112,116,105,111,110,6,15,73, + 110,115,101,114,116,32,84,101,109,112,108,97,116,101,4,110,97,109,101,6, + 8,105,110,115,116,101,109,112,108,5,115,116,97,116,101,11,15,97,115,95, + 108,111,99,97,108,99,97,112,116,105,111,110,0,0,1,6,97,99,116,105, + 111,110,7,16,99,111,109,112,108,101,116,101,99,108,97,115,115,97,99,116, + 7,99,97,112,116,105,111,110,6,24,67,111,109,112,108,101,116,101,32,67, + 108,97,115,115,32,97,116,32,67,117,114,115,111,114,5,115,116,97,116,101, + 11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,0,0, + 4,108,101,102,116,3,176,0,3,116,111,112,2,40,0,0,7,116,97,99, + 116,105,111,110,16,99,111,109,112,108,101,116,101,99,108,97,115,115,97,99, + 116,7,99,97,112,116,105,111,110,6,24,67,111,109,112,108,101,116,101,32, + 99,108,97,115,115,32,97,116,32,99,117,114,115,111,114,9,111,110,101,120, + 101,99,117,116,101,7,20,99,111,109,112,108,101,116,101,99,108,97,115,115, + 101,120,101,99,117,116,101,4,108,101,102,116,2,32,3,116,111,112,3,208, + 0,2,115,99,1,2,1,3,65,96,0,0,0,16,116,115,116,114,105,110, + 103,99,111,110,116,97,105,110,101,114,1,99,12,115,116,114,105,110,103,115, + 46,100,97,116,97,1,6,6,70,105,108,101,32,34,6,14,34,32,104,97, + 115,32,99,104,97,110,103,101,100,46,6,44,84,104,101,114,101,32,97,114, + 101,32,109,111,100,105,102,105,99,97,116,105,111,110,115,32,105,110,32,101, + 100,105,116,32,98,117,102,102,101,114,32,97,108,115,111,46,6,32,68,111, + 32,121,111,117,32,119,105,115,104,32,116,111,32,114,101,108,111,97,100,32, + 102,114,111,109,32,100,105,115,107,63,6,12,67,111,110,102,105,114,109,97, + 116,105,111,110,6,6,60,110,111,110,101,62,6,23,68,111,32,121,111,117, + 32,119,105,115,104,32,116,111,32,114,101,112,108,97,99,101,58,6,5,119, + 105,116,104,58,6,5,60,110,101,119,62,6,14,83,121,110,116,97,120,100, + 101,102,102,105,108,101,58,6,4,84,101,120,116,6,10,110,111,116,32,102, + 111,117,110,100,46,6,27,82,101,115,116,97,114,116,32,102,114,111,109,32, + 98,101,103,105,110,32,111,102,32,102,105,108,101,63,6,7,67,97,110,99, + 101,108,63,6,41,68,111,32,121,111,117,32,119,105,115,104,32,116,111,32, + 116,111,32,114,101,112,108,97,99,101,32,116,104,105,115,32,111,99,99,117, + 114,101,110,99,101,63,6,18,71,111,32,116,111,32,108,105,110,101,32,110, + 117,109,98,101,114,58,6,9,70,105,110,100,32,108,105,110,101,6,44,84, + 104,101,114,101,32,97,114,101,32,109,111,100,105,102,105,99,97,116,105,111, + 110,115,32,105,110,32,101,100,105,116,32,98,117,102,102,101,114,32,97,108, + 115,111,46,6,25,82,101,115,116,97,114,116,32,102,114,111,109,32,101,110, + 100,32,111,102,32,102,105,108,101,63,0,4,108,101,102,116,3,176,0,3, + 116,111,112,2,104,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tsourcefo,''); +end. diff --git a/mseide-msegui/apps/ide/sourcehintform.mfm b/mseide-msegui/apps/ide/sourcehintform.mfm new file mode 100644 index 0000000..3dbc793 --- /dev/null +++ b/mseide-msegui/apps/ide/sourcehintform.mfm @@ -0,0 +1,24 @@ +object sourcehintfo: tsourcehintfo + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_subfocus, ow_mousewheel, ow_destroywidgets, ow_hinton] + visible = False + bounds_x = 100 + bounds_y = 291 + bounds_cx = 314 + bounds_cy = 214 + container.frame.framei_left = 0 + container.frame.framei_top = 0 + container.frame.framei_right = 0 + container.frame.framei_bottom = 0 + container.frame.localprops = [frl_fileft, frl_fitop, frl_firight, frl_fibottom] + container.bounds = ( + 0 + 0 + 314 + 214 + ) + optionswindow = [wo_message] + options = [fo_freeonclose, fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savestate] + onclose = sourcehintfoonclose + onresize = formonresize + moduleclassname = 'tmseform' +end diff --git a/mseide-msegui/apps/ide/sourcehintform.pas b/mseide-msegui/apps/ide/sourcehintform.pas new file mode 100644 index 0000000..dbfdf8b --- /dev/null +++ b/mseide-msegui/apps/ide/sourcehintform.pas @@ -0,0 +1,56 @@ +{ MSEide Copyright (c) 1999-2006 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit sourcehintform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msegui,mseclasses,mseforms,mseedit,msegraphutils; + +type + stringeditarty = array of tedit; + tsourcehintfo = class(tmseform) + procedure sourcehintfoonclose(const sender: TObject); + procedure formonresize(const sender: TObject); + public + dispar: stringeditarty; + end; + +implementation +uses + sourceform,sourcehintform_mfm; + +procedure tsourcehintfo.sourcehintfoonclose(const sender: TObject); +begin + sourcefo.hintsize:= size; +end; + +procedure tsourcehintfo.formonresize(const sender: TObject); +var + int1,int3: integer; +begin + int3:= 0; + for int1:= 0 to high(dispar) do begin + dispar[int1].clientheight:= dispar[int1].editor.textrect.cy + 2; + inc(int3,dispar[int1].bounds_cy); + end; + placeyorder(0,[0],widgetarty(dispar)); + bounds_cymax:= int3; +end; + +end. diff --git a/mseide-msegui/apps/ide/sourcehintform_mfm.pas b/mseide-msegui/apps/ide/sourcehintform_mfm.pas new file mode 100644 index 0000000..c690c79 --- /dev/null +++ b/mseide-msegui/apps/ide/sourcehintform_mfm.pas @@ -0,0 +1,49 @@ +unit sourcehintform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,sourcehintform; + +const + objdata: record size: integer; data: array[0..627] of byte end = + (size: 628; data: ( + 84,80,70,48,13,116,115,111,117,114,99,101,104,105,110,116,102,111,12,115, + 111,117,114,99,101,104,105,110,116,102,111,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,11,111,119,95,115,117,98,102,111,99,117,115,13,111, + 119,95,109,111,117,115,101,119,104,101,101,108,17,111,119,95,100,101,115,116, + 114,111,121,119,105,100,103,101,116,115,9,111,119,95,104,105,110,116,111,110, + 0,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2, + 100,8,98,111,117,110,100,115,95,121,3,35,1,9,98,111,117,110,100,115, + 95,99,120,3,58,1,9,98,111,117,110,100,115,95,99,121,3,214,0,27, + 99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,102,114,97,109, + 101,105,95,108,101,102,116,2,0,26,99,111,110,116,97,105,110,101,114,46, + 102,114,97,109,101,46,102,114,97,109,101,105,95,116,111,112,2,0,28,99, + 111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,102,114,97,109,101, + 105,95,114,105,103,104,116,2,0,29,99,111,110,116,97,105,110,101,114,46, + 102,114,97,109,101,46,102,114,97,109,101,105,95,98,111,116,116,111,109,2, + 0,26,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,114,108,95,102,105,108,101,102,116, + 9,102,114,108,95,102,105,116,111,112,11,102,114,108,95,102,105,114,105,103, + 104,116,12,102,114,108,95,102,105,98,111,116,116,111,109,0,16,99,111,110, + 116,97,105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0,3,58, + 1,3,214,0,0,13,111,112,116,105,111,110,115,119,105,110,100,111,119,11, + 10,119,111,95,109,101,115,115,97,103,101,0,7,111,112,116,105,111,110,115, + 11,14,102,111,95,102,114,101,101,111,110,99,108,111,115,101,13,102,111,95, + 99,108,111,115,101,111,110,101,115,99,15,102,111,95,97,117,116,111,114,101, + 97,100,115,116,97,116,16,102,111,95,97,117,116,111,119,114,105,116,101,115, + 116,97,116,10,102,111,95,115,97,118,101,112,111,115,12,102,111,95,115,97, + 118,101,115,116,97,116,101,0,7,111,110,99,108,111,115,101,7,19,115,111, + 117,114,99,101,104,105,110,116,102,111,111,110,99,108,111,115,101,8,111,110, + 114,101,115,105,122,101,7,12,102,111,114,109,111,110,114,101,115,105,122,101, + 15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,8,116,109, + 115,101,102,111,114,109,0,0) + ); + +initialization + registerobjectdata(@objdata,tsourcehintfo,''); +end. diff --git a/mseide-msegui/apps/ide/sourcepage.mfm b/mseide-msegui/apps/ide/sourcepage.mfm new file mode 100644 index 0000000..e1eebc6 --- /dev/null +++ b/mseide-msegui/apps/ide/sourcepage.mfm @@ -0,0 +1,169 @@ +object sourcepage: tsourcepage + optionswidget = [ow_arrowfocus, ow_subfocus, ow_destroywidgets, ow_hinton] + optionsskin = [osk_framebuttononly] + color = -1879048187 + bounds_x = 192 + bounds_y = 245 + bounds_cx = 311 + bounds_cy = 228 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 311 + 228 + ) + icon.transparentcolor = -2147483648 + oncreate = sourcefooncreate + oneventloopstart = sourcefoonloaded + ondestroy = sourcefoondestroy + onshow = sourcefoonshow + onhide = sourcefoondeactivate + moduleclassname = 'ttabform' + object grid: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_mousewheel, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + frame.localprops = [] + frame.localprops1 = [] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 311 + bounds_cy = 206 + anchors = [an_top, an_bottom] + optionsgrid = [og_focuscellonenter, og_autofirstrow, og_wrapcol, og_visiblerowpagestep] + fixcols.count = 1 + fixcols.items = < + item + color = -1610612731 + linewidth = 0 + textflags = [tf_right, tf_ycentered] + numstart = 1 + numstep = 1 + font.color = -1610612733 + font.name = 'stf_default' + font.xscale = 1 + font.localprops = [flp_color, flp_xscale] + end> + gridframecolor = -2147483645 + rowcolors.count = 4 + rowcolors.items = ( + 14745599 + 65535 + 16711680 + -2147483646 + ) + datacols.count = 2 + datacols.items = < + item[dataicon] + linecolor = -1610612732 + width = 15 + options = [co_nofocus, co_nohscroll] + oncellevent = icononcellevent + widgetname = 'dataicon' + dataclass = tgridintegerdatalist + end + item[edit] + width = 2000 + options = [co_leftbuttonfocusonly, co_middlebuttonfocus, co_savestate, co_mousescrollrow] + onchange = textchanged + widgetname = 'edit' + dataclass = tgridrichstringdatalist + end> + datarowlinewidth = 0 + datarowheight = 18 + onrowsinserted = gridonrowsinserted + onrowsdeleted = gridonrowsdeleted + oncellevent = gridoncellevent + reffontheight = 16 + object edit: tsyntaxedit + optionsskin = [osk_framebuttononly] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 2000 + bounds_cy = 18 + font.name = 'mseide_source' + font.xscale = 1 + font.localprops = [flp_xscale] + optionsedit1 = [oe1_noselectall, oe1_savestate] + optionsedit = [oe_closequery, oe_checkmrcancel, oe_linebreak, oe_eatreturn, oe_exitoncursor, oe_nofirstarrownavig] + tabulators.ppmm = 3 + tabulators.defaultdist = 0 + onkeydown = editonkeydown + onfontchanged = editonfontchanged + onmodifiedchanged = editonmodifiedchanged + ontextmouseevent = editontextmouseevent + oneditnotifcation = editoneditnotification + oncellevent = editoncellevent + maxundocount = 10000 + reffontheight = 18 + end + object dataicon: tdataicon + optionsskin = [osk_framebuttononly] + bounds_x = 50 + bounds_y = 0 + bounds_cx = 15 + bounds_cy = 18 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + options = [bo_executeonkey, bo_executeonshortcut, bo_executedefaultonenterkey] + visible = False + valuedefault = -2147483648 + min = -1 + max = 2 + imagenums.count = 14 + imagenums.items = ( + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + ) + end + end + object linedisp: tstringedit + optionsskin = [osk_framebuttononly] + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -2147483645 + frame.localprops = [] + frame.localprops1 = [] + taborder = 2 + bounds_x = 0 + bounds_y = 207 + bounds_cx = 68 + anchors = [an_left, an_bottom] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + textflags = [tf_xcentered, tf_ycentered] + textflagsactive = [tf_xcentered, tf_ycentered] + reffontheight = 16 + end + object pathdisp: tstringedit + optionsskin = [osk_framebuttononly] + color = -2147483645 + frame.levelo = -1 + frame.colorclient = -2147483645 + frame.localprops = [] + frame.localprops1 = [] + taborder = 1 + bounds_x = 68 + bounds_y = 207 + bounds_cx = 243 + anchors = [an_left, an_right, an_bottom] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_caretonreadonly, oe_focusrectonreadonly, oe_hintclippedtext] + textflags = [tf_ycentered, tf_ellipseleft] + reffontheight = 16 + end +end diff --git a/mseide-msegui/apps/ide/sourcepage.pas b/mseide-msegui/apps/ide/sourcepage.pas new file mode 100644 index 0000000..bd64b4a --- /dev/null +++ b/mseide-msegui/apps/ide/sourcepage.pas @@ -0,0 +1,1836 @@ +{ MSEide Copyright (c) 1999-2016 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit sourcepage; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + msetextedit,msewidgetgrid,mseforms,classes,mclasses,msegdbutils, + msegraphedits,mseevent, + msehash,msebitmap,msetabs,msetypes,msedataedits, + mseglob,mseguiglob,msegui,msesyntaxedit,mseeditglob, + mseinplaceedit,msedispwidgets,msegraphutils,msegrids,breakpointsform, + pascaldesignparser,msefilechange,msestrings,mserichstring,mseparser, + msegridsglob,projectoptionsform; + + +type + sourcepageasynctagty = (spat_showasform,{spat_checkbracket,}spat_showsource); + + bookmarkty = record + row: integer; + bookmarknum: integer; + end; + bookmarkarty = array of bookmarkty; + + tsourcepage = class(ttabform) + grid: twidgetgrid; + edit: tsyntaxedit; + dataicon: tdataicon; + linedisp: tstringedit; + pathdisp: tstringedit; + procedure icononcellevent(const sender: tobject; var info: celleventinfoty); + procedure sourcefooncreate(const sender: tobject); + procedure sourcefoondestroy(const sender: tobject); + procedure editoncellevent(const sender: TObject; var info: celleventinfoty); + procedure editonmodifiedchanged(const sender: tobject; const value: boolean); + procedure editontextmouseevent(const sender: tobject; + var info: textmouseeventinfoty); + procedure editoneditnotification(const sender: tobject; + var info: editnotificationinfoty); + procedure gridonrowsdeleted(const sender: tcustomgrid; + const index,count: integer); + procedure gridonrowsinserted(const sender: tcustomgrid; + const index,count: integer); + procedure sourcefoonloaded(const sender: TObject); + procedure textchanged(const sender: tdatacol; const aindex: integer); + procedure sourcefoonshow(const sender: TObject); + procedure editonfontchanged(const sender: TObject); + procedure sourcefoondeactivate(const sender: TObject); + procedure gridoncellevent(const sender: TObject; var info: celleventinfoty); + procedure editonkeydown(const sender: twidget; var info: keyeventinfoty); + private + factiverow: integer; + flasthint: gridcoordty; + flasthintlength: integer; + fbackupcreated: boolean; + ffindpos: gridcoordty; + ffiletag: longword; + fsavetime: tdatetime; + fexecstamp: integer; + fgotoline: integer; + ffileloading: integer; + ffileloaderror: boolean; + frelpath: filenamety; + fshowsourcepos: sourceposty; + procedure setactiverow(const Value: integer); + procedure setgdb(agdb: tgdbmi); + procedure setfilepath(const value: filenamety); + function getfilename: filenamety; + function getfilepath: filenamety; + function getrelpath: filenamety; + procedure replace(all: boolean); + procedure showprocheaders(const apos: gridcoordty); + procedure showsourceitems(const apos: gridcoordty); + procedure showlink(const apos: gridcoordty); + procedure showsourcehint(const apos: gridcoordty; const values: stringarty); + procedure setsyntaxdef(const value: filenamety); + procedure updatelinedisp; + protected + finitialfilepath: filenamety; + finitialeditpos: gridcoordty; + finitialbookmarks: bookmarkarty; + fbracket1,fbracket2: gridcoordty; + procedure doasyncevent(var atag: integer); override; + procedure removebookmark(const bookmarknum: integer); + procedure beginupdate; + procedure endupdate; + function checkfilechanged: boolean; + public + filechanged: boolean; + ismoduletext: boolean; + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure loadfile(value: filenamety); overload; //no const! + procedure loadfile; overload; //loads if needed + function fileloaded: boolean; + procedure setbackupcreated; + procedure updatestatvalues; + procedure updatecaption(const modified: boolean); + procedure updatebreakpointicons; + procedure updatebreakpointicon(const info: bkptlineinfoty); + procedure togglebreakpoint(const arow: integer = -1); + procedure togglebreakpointenabled(const arow: integer = -1); + procedure cleardebuglines; + procedure updatedebuglines; + procedure hidehint; + procedure save(newname: filenamety); + function checksave(noconfirm,multiple: boolean): modalresultty; + function modified: boolean; + function source: trichstringdatalist; + procedure copywordatcursor(); + procedure doline; + procedure dofind; + procedure repeatfind; + procedure findback; + procedure doreplace; + procedure reload; + procedure doundo; + procedure doredo; + procedure inserttemplate; + procedure copylatex; + function cancomment(): boolean; + function canuncomment(): boolean; + procedure commentselection(); + procedure uncommentselection(); + function canchangenotify(const info: filechangeinfoty): boolean; + function getbreakpointstate(arow: integer = -1): bkptstatety; + //-1 -> current row + procedure setbreakpointstate(astate: bkptstatety; arow: integer = -1); + //-1 -> acurrent row + function findbookmark(const bookmarknum: integer): integer; + //returns row, -1 if not found + procedure setbookmark(arow: integer; const bookmarknum: integer); + //arow -1 -> current row, bookmarknum < 1 -> clear + procedure clearbookmark(const bookmarknum: integer); + function getbookmarks: bookmarkarty; + + property activerow: integer read factiverow write setactiverow; + property gdb: tgdbmi write setgdb; + property filename: filenamety read getfilename; + property relpath: filenamety read getrelpath write frelpath; + property filepath: filenamety read getfilepath write setfilepath; + property filetag: longword read ffiletag; + end; + +function getpascalvarname(const edit: tsyntaxedit; pos: gridcoordty; + out startpos: gridcoordty): msestring; overload; +function getpascalvarname(const edit: tsyntaxedit; + const pos: pointty): msestring; overload; +procedure findintextedit(const edit: tcustomtextedit; var info: findinfoty; + var findpos: gridcoordty; const backward: boolean = false); +implementation +uses + sourcepage_mfm,msefileutils,sourceform,main, + sysutils,msewidgets,finddialogform,replacedialogform,msekeyboard, + sourceupdate,msefiledialog,mseintegerenter,msedesigner,mseformatstr, + msesys,make,actionsmodule,msegraphics,sourcehintform, + mseedit,msedrawtext,msebits,msearrayutils,msestream,msedesignintf, + msesysutils,msedesignparser,msesyntaxpainter,msemacros,msecodetemplates, + mselatex,msesystypes; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + pascaldelims = msestring(' :;+-*/(){},=<>' + c_linefeed + c_return + c_tab); + selectdelims = pascaldelims+'.[]''"'; + nodelimstrings: array[0..0] of msestring = ('->'); //for c + bmbitshift = 4; + bmbitmask = integer($3ff0); + findshowpos = cep_rowcentered; + +function getpascalvarname(const edit: tsyntaxedit; pos: gridcoordty; + out startpos: gridcoordty): msestring; +var + int1: integer; +begin + startpos:= edit.wordatpos(pos,result,pascaldelims,nodelimstrings); + if (result = '') and (pos.col > 0) then begin + dec(pos.col); + startpos:= edit.wordatpos(pos,result,pascaldelims,nodelimstrings); + end; + if result <> '' then begin + for int1:= pos.col - startpos.col + 1 to length(result) do begin + if (result[int1] = '.') or (result[int1] = '-') and (result[int1+1] = '>') then begin + setlength(result,int1-1); + break; + end; + end; + end; +end; + +function getpascalvarname(const edit: tsyntaxedit; const pos: pointty): msestring; +var + po1,po2: gridcoordty; +begin + if edit.mousepostotextpos(pos,po1,true) then begin + result:= getpascalvarname(edit,po1,po2); + end + else begin + result:= ''; + end; +end; + +{ tsourcepage } + +constructor tsourcepage.create(aowner: tcomponent); +begin + factiverow:= -1; + fgotoline:= 1; + fbracket1:= invalidcell; + fbracket2:= invalidcell; + inherited create(aowner); + updatestatvalues; +end; + +destructor tsourcepage.destroy; +begin + inherited; +end; + +procedure tsourcepage.doasyncevent(var atag: integer); +var + mstr1: filenamety; + po1: pmoduleinfoty; +begin + case sourcepageasynctagty(atag) of + spat_showasform: begin + mstr1:= filepath; + if sourcefo.closepage(self) then begin + po1:= mainfo.openformfile(mstr1,true,true,false,true,false); + if po1 <> nil then begin + po1^.backupcreated:= fbackupcreated; + designer.modulechanged(po1); + end; + end; + end; +{ + spat_checkbracket: begin + dec(fbracketchecking); + checkbrackets; + end; +} + spat_showsource: begin + sourcefo.naviglist.showsource(fshowsourcepos,true); + end; + end; +end; + +procedure tsourcepage.sourcefoonloaded(const sender: TObject); +begin + updatestatvalues; + grid.bottom:= linedisp.top - 1; +end; + +procedure tsourcepage.textchanged(const sender: tdatacol; + const aindex: integer); +begin + sourcechanged(edit.filename); +end; + +procedure tsourcepage.updatecaption(const modified: boolean); +var + str1: filenamety; +begin + if ffileloading > 0 then begin + exit; + end; + pathdisp.value:= finitialfilepath; + str1:= filename; + if str1 = '' then begin + str1:= sourcefo.c[ord(str_new)]; + end; + if modified then begin + caption:= '*'+str1; + sourcefo.textmodified(self); + end + else begin + caption:= str1; + end; + if isactivepage then begin + tsourcefo(tabwidget.parentofcontainer).updatecaption; + end; +end; + +procedure tsourcepage.updatebreakpointicon(const info: bkptlineinfoty); +var + int1: integer; +begin + with info do begin + int1:= line-1; + if (int1 >= 0) and (int1 <= grid.rowhigh) then begin + setbreakpointstate(state,int1); + end; + end; +end; + +procedure tsourcepage.updatebreakpointicons; +var + int1: integer; + ar1: bkptlineinfoarty; +begin + ar1:= breakpointsfo.getbreakpointlines(edit.filename); + for int1:= 0 to high(ar1) do begin + updatebreakpointicon(ar1[int1]); + end; +end; + +procedure tsourcepage.setsyntaxdef(const value: filenamety); +begin + try + edit.setsyntaxdef(value); + updatestatvalues; + except + on e: exception do begin + handleerror(e,ansistring(sourcefo.c[ord(syntaxdeffile)])); + end; + end; +end; + +procedure tsourcepage.loadfile(value: filenamety); +begin + inc(ffileloading); + try + edit.loadfromfile(value); + ismoduletext:= ismoduletext or (fileext(value) = formfileext); + finitialfilepath:= edit.filename; + setsyntaxdef(value); + updatebreakpointicons; + if mainfo.gdb.execloaded and actionsmo.bluedotsonact.checked then begin + updatedebuglines; + end; + finally + dec(ffileloading); + end; + updatecaption(false); +end; + +function tsourcepage.fileloaded: boolean; +begin + result:= (edit.filename = finitialfilepath) or (finitialfilepath = ''); +end; + +function tsourcepage.getfilepath: filenamety; +begin + result:= finitialfilepath; +end; + +function tsourcepage.getrelpath: filenamety; +begin + if fileloaded or (frelpath = '') then begin + result:= relativepath(finitialfilepath,projectoptions.projectdir); + end + else begin + result:= frelpath; + end; +end; + +function tsourcepage.getfilename: filenamety; +begin + result:= msefileutils.filename(finitialfilepath); +end; + +procedure tsourcepage.loadfile; //loads if needed +var + mstr1: filenamety; + int1: integer; +begin + if not fileloaded then begin + mstr1:= relpath; + if findfile(mstr1) then begin + mstr1:= msefileutils.filepath(mstr1); + end + else begin + mstr1:= finitialfilepath; + end; + setfilepath(mstr1); + sourcefo.filechangenotifyer.addnotification(finitialfilepath,filetag); + edit.editpos:= finitialeditpos; + for int1:= 0 to high(finitialbookmarks) do begin + with finitialbookmarks[int1] do begin + if (row >= 0) and (bookmarknum >= 0) and (row < grid.rowcount) and + (bookmarknum < 10) then begin + setbookmark(row,bookmarknum); + end; + end; + end; + end; +end; + +procedure tsourcepage.setfilepath(const value: filenamety); +begin + if edit.filename <> value then begin + fbackupcreated:= false; + ffiletag:= sourcefo.newfiletag; + loadfile(value); + end; +end; + +procedure tsourcepage.reload; +begin + loadfile(edit.filename); +end; + +procedure tsourcepage.cleardebuglines; +var + po1: pintegeraty; + int1: integer; +begin + if fexecstamp <> 0 then begin + fexecstamp:= 0; + po1:= dataicon.datalist.datapo; + for int1:= 0 to dataicon.datalist.count - 1 do begin + po1^[int1]:= po1^[int1] and (bmbitmask or integer($80000000)); + end; + dataicon.datalist.change(-1); +// dataicon.fillcol(integer($80000000)); + updatebreakpointicons; + end; +end; + +procedure tsourcepage.updatedebuglines; +var + ar1: integerarty; + ar2: qwordarty; + po1: pintegeraty; + int1,int2: integer; +begin + if mainfo.gdb.cancommand then begin + if fexecstamp <> mainfo.execstamp then begin + fexecstamp:= mainfo.execstamp; + application.beginwait; + if mainfo.gdb.listlines(edit.filename,ar1,ar2) = gdb_ok then begin + po1:= pintegeraty(dataicon.datalist.datapo); + for int1:= 0 to dataicon.datalist.count - 1 do begin + po1^[int1]:= po1^[int1] and (bmbitmask or integer($80000000)); + end; + int2:= dataicon.datalist.count; + for int1:= 0 to high(ar1) do begin + if (ar1[int1] > 0) and (ar1[int1] <= int2) then begin + po1^[ar1[int1]-1]:= po1^[ar1[int1]-1] or integer($80000008); + end; + end; + updatebreakpointicons; + dataicon.datalist.change(-1); + end + else begin + cleardebuglines; + end; + application.endwait; + end; + end; +end; + +function tsourcepage.checkfilechanged: boolean; +var + stream1: ttextstream; + int1,int2: integer; + po1: prichstringty; + mstr1: msestring; +begin + result:= modified; + if not result then begin + result:= true; + if ttextstream.trycreate(stream1,edit.filename,fm_read) = sye_ok then begin + //else locked or deleted + try + stream1.encoding:= edit.encoding; + int1:= 0; + int2:= edit.datalist.count - 1; + po1:= edit.datalist.datapo; + for int1:= 0 to int2 do begin + if not stream1.readln(mstr1) then begin + if int1 <> int2 then begin + exit; + end; + end; + if mstr1 <> po1^.text then begin + exit; + end; + inc(po1); + end; + if stream1.eof then begin + result:= false; + end; + finally + stream1.free; + end; + end; + end; +end; + +function tsourcepage.canchangenotify(const info: filechangeinfoty): boolean; +begin + result:= (info.changed - [fc_force,fc_accesstime] <> []) or checkfilechanged(); + with projectoptions,s.texp do begin + if result and making and s.copymessages and + (filepath = msefileutils.filepath(messageoutputfile)) then begin + result:= false; + end; + end; +end; + +procedure tsourcepage.showsourcehint(const apos: gridcoordty; + const values: stringarty); +var + rect1: rectty; + int1: integer; +begin + if high(values) >= 0 then begin + sourcefo.sourcehintwidget:= tsourcehintfo.create(nil); + with tsourcehintfo(sourcefo.sourcehintwidget) do begin + if (sourcefo.hintsize.cx <= 0) or (sourcefo.hintsize.cy <= 0) then begin + sourcefo.hintsize:= size; + end; + rect1:= edit.textpostomouserect(apos,true); + dec(rect1.y,10); + inc(rect1.cy,40); + setlength(dispar,length(values)); + for int1:= 0 to high(values) do begin + dispar[int1]:= tedit.create(sourcefo.sourcehintwidget); + with dispar[int1] do begin + initnewcomponent(1.0); + frame.levelo:= 0; + frame.framewidth:= 1; + frame.colorframe:= cl_dkgray; + + optionsedit:= optionsedit + [oe_readonly]; + textflags:= [tf_wordbreak,tf_noselect]; + textflagsactive:= [tf_wordbreak]; + anchors:= [an_top]; + text:= msestring(values[high(values)-int1]); + end; + end; + for int1:= high(values) downto 0 do begin + dispar[int1].parentwidget:= sourcefo.sourcehintwidget.container; + end; + size:= sourcefo.hintsize; + formonresize(nil); + widgetrect:= placepopuprect(self.window,rect1,cp_bottomleft,size); + show(false,self.window); + end; + end + else begin + sourcefo.hidesourcehint; + end; + activate(false,true); //get focus back +end; + +procedure tsourcepage.showprocheaders(const apos: gridcoordty); +var + ar1: procedureinfoarty; + ar2: stringarty; + int1: integer; + pos1: sourceposty; +begin + pos1.pos:= apos; + ar1:= listprocheaders(edit.filename,pos1); + setlength(ar2,length(ar1)); + for int1:= 0 to high(ar1) do begin + ar2[int1]:= sourceupdater.composeprocedureheader(@ar1[int1],true); + end; + showsourcehint(apos,ar2); +end; + +procedure tsourcepage.showsourceitems(const apos: gridcoordty); +var + scopes: deflistarty; + defs: definfopoarty; + pos1: sourceposty; + ar1: stringarty; + int1: integer; +begin + pos1.pos:= apos; + listsourceitems(edit.filename,pos1,scopes,defs,100); + setlength(ar1,length(defs)); + for int1:= 0 to high(defs) do begin + ar1[int1]:= defs[int1]^.name; + end; + if high(ar1) >= 99 then begin + ar1[high(ar1)]:= '...'; + end; + showsourcehint(apos,ar1); +end; + +procedure tsourcepage.editoncellevent(const sender: TObject; + var info: celleventinfoty); + + procedure checklink; + var + pos2: gridcoordty; + begin + if info.keyeventinfopo^.shiftstate * shiftstatesmask = [ss_ctrl] then begin + if edit.mousepostotextpos(translatewidgetpoint(application.mouse.pos,nil,edit), + pos2,true) then begin + showlink(pos2); + end; + end + else begin + edit.removelink; + end; + end; + +var + pos1,pos2: sourceposty; + page1: tsourcepage; + shiftstate1: shiftstatesty; + bo1: boolean; + cellpos1: cellpositionty; + +begin + if iscellclick(info,[ccr_nokeyreturn,ccr_dblclick]) and + (dataicon[info.cell.row] and integer($80000000) <> 0) and + (info.mouseeventinfopo^.shiftstate = [ss_double]) then begin + include(info.mouseeventinfopo^.eventstate,es_processed); + breakpointsfo.showbreakpoint(filepath,info.cell.row + 1,true); + end; + case info.eventkind of + cek_exit: begin + edit.removelink; + end; + cek_keyup: begin + checklink; + end; + cek_keydown: begin + checklink; + with info.keyeventinfopo^ do begin + shiftstate1:= shiftstate * shiftstatesmask; + if not (es_processed in eventstate) then begin + if ((shiftstate1 = [ss_shift,ss_ctrl]) or + (shiftstate1 = [ss_ctrl])) then begin + include(eventstate,es_processed); + pos1.pos:= edit.editpos; + if (shiftstate1 = [ss_shift,ss_ctrl]) then begin + case key of + key_up,key_down: begin + if switchheaderimplementation(edit.filename,pos1,pos2,bo1) then begin + cellpos1:= cep_none; + if bo1 then begin + cellpos1:= cep_top; + end; + page1:= sourcefo.showsourcepos(pos2,true,cellpos1); + if page1 <> nil then begin + page1.grid.showcell(makegridcoord(1,pos1.pos.row)); + end; + end; + end; + key_space: begin + showprocheaders(edit.editpos); + end; + else begin + exclude(eventstate,es_processed); + end; + end; + end + else begin + case key of + key_space: begin +{$ifdef mse_with_showsourceitems} + showsourceitems(edit.editpos); +{$endif} + end + else begin + exclude(eventstate,es_processed); + end; + end; + end; + end + else begin + if shiftstate1 = [] then begin + include(eventstate,es_processed); + case key of + key_escape: begin + if not sourcefo.hidesourcehint then begin + exclude(eventstate,es_processed); + end; + end; + else begin + exclude(eventstate,es_processed); + end; + end; + end; + end; + end; + end; + end; + end; +end; + +const + convtab: array[0..7] of bkptstatety = + // 000 001 010 011 + (bkpts_none,bkpts_normal,bkpts_disabled,bkpts_none, + // 100 101 110 111 + bkpts_none,bkpts_error,bkpts_none,bkpts_none); + +procedure tsourcepage.icononcellevent(const sender: tobject; + var info: celleventinfoty); +var + bpinfo: breakpointinfoty; + astate: bkptstatety; +begin + with dataicon do begin + if iscellclick(info) then begin + astate:= convtab[gridvalue[info.cell.row] and 7]; + fillchar(bpinfo,sizeof(bpinfo),0); + bpinfo.line:= info.cell.row + 1; + bpinfo.path:= edit.filename; + bpinfo.bkpton:= astate in [bkpts_disabled,bkpts_none]; //for toggle + case astate of + bkpts_none: begin + breakpointsfo.addbreakpoint(bpinfo); + end; + bkpts_normal,bkpts_disabled,bkpts_error: begin + if iscellclick(info,[ccr_dblclick]) then begin + breakpointsfo.deletebreakpoint(bpinfo); + end + else begin + breakpointsfo.updatebreakpointon(bpinfo); + end; + end; + end; + end; + end; +end; + +function tsourcepage.getbreakpointstate(arow: integer = -1): bkptstatety; +begin + if arow = -1 then begin + arow:= grid.row; + end; + if (arow >= 0) and (arow < grid.rowcount) then begin + result:= convtab[dataicon[arow] and 7]; + end + else begin + result:= bkpts_none; + end; +end; + +procedure tsourcepage.setbreakpointstate(astate: bkptstatety; + arow: integer = -1); +begin + if arow = -1 then begin + arow:= grid.row; + end; + if (arow >= 0) and (arow < grid.rowcount) then begin + case astate of + bkpts_none: dataicon[arow]:= dataicon[arow] and not integer($00000007); + bkpts_normal: dataicon[arow]:= dataicon[arow] and not integer($00000007) or + integer($80000001); + bkpts_disabled: dataicon[arow]:= dataicon[arow] and not integer($00000007) or + integer($80000002); + bkpts_error: dataicon[arow]:= dataicon[arow] and not integer($00000007) or + integer($80000005); + end; + end; +end; + +procedure tsourcepage.togglebreakpoint(const arow: integer = -1); +var + bpinfo: breakpointinfoty; + astate: bkptstatety; +begin + astate:= getbreakpointstate(grid.row); + fillchar(bpinfo,sizeof(bpinfo),0); + if arow < 0 then begin + bpinfo.line:= grid.row + 1; + end + else begin + bpinfo.line:= arow + 1; + end; + bpinfo.path:= edit.filename; + case astate of + bkpts_none: begin + bpinfo.bkpton:= true; + breakpointsfo.addbreakpoint(bpinfo); + end + else begin + breakpointsfo.deletebreakpoint(bpinfo); + setbreakpointstate(bkpts_none,grid.row); + //if breakpointinfo is not synchronized + end; + end; +end; + +procedure tsourcepage.togglebreakpointenabled(const arow: integer = -1); +var + bpinfo: breakpointinfoty; + astate: bkptstatety; +begin + astate:= convtab[dataicon.value and 7]; + fillchar(bpinfo,sizeof(bpinfo),0); + if arow < 0 then begin + bpinfo.line:= grid.row + 1; + end + else begin + bpinfo.line:= arow + 1; + end; + bpinfo.path:= edit.filename; + bpinfo.bkpton:= astate in [bkpts_disabled{,bkpts_none}]; //for toggle + if astate = bkpts_none then begin + breakpointsfo.addbreakpoint(bpinfo); + end + else begin + breakpointsfo.updatebreakpointon(bpinfo); + end; +end; + +procedure tsourcepage.setactiverow(const Value: integer); +begin + if factiverow <> value then begin + if (factiverow >= 0) and (factiverow < grid.rowcount) then begin + grid.rowcolorstate[factiverow]:= -1; + end; + if (value >= 0) and (value < grid.rowcount) then begin + grid.rowcolorstate[value]:= 0; + grid.showcell(makegridcoord(0,value),cep_rowcenteredif); + edit.editpos:= makegridcoord(0,value) + end; + end; + factiverow := Value; +end; + +procedure tsourcepage.setgdb(agdb: tgdbmi); +begin +// breakpoints.fgdb:= agdb; +end; + +procedure tsourcepage.sourcefooncreate(const sender: tobject); +begin +// breakpoints:= tbreakpoints.create; +end; + +procedure tsourcepage.sourcefoondestroy(const sender: tobject); +begin +// breakpoints.Free; +end; + +procedure tsourcepage.editonmodifiedchanged(const sender: tobject; + const value: boolean); +begin + updatecaption(value); +end; + +function tsourcepage.checksave(noconfirm,multiple: boolean): modalresultty; +begin + result:= mr_none; + if not sourcefo.allsaved then begin + if edit.modified and (noconfirm or + confirmsavechangedfile(edit.filename,result,multiple)) then begin + save(''); + end; + end; +end; + +procedure tsourcepage.save(newname: filenamety); +var + info: fileinfoty; + po1: prichstringty; + i1: int32; +begin + if newname = '' then begin + if (edit.filename = '') then begin + if filedialog(newname,[fdo_save],'',[],[]) = mr_cancel then begin + exit; + end; + end + else begin + newname:= edit.filename; + end; + end; + createbackupfile(newname,edit.filename,fbackupcreated, + projectoptions.e.backupfilecount); + if newname <> '' then begin + sourcefo.filechangenotifyer.removenotification(filepath); + end; + finitialfilepath:= newname; + try + designnotifications.beforefilesave(idesigner(designer),newname); + except + application.handleexception(nil); + end; + if projectoptions.e.trimtrailingwhitespace then begin + edit.datalist.beginupdate(); + try + po1:= edit.datalist.datapo; + for i1:= 0 to edit.datalist.count - 1 do begin + trimright1(po1^.text); + inc(po1); + end; + finally + edit.datalist.endupdate(); + end; + end; + edit.savetofile(newname); + if newname <> '' then begin + if ffiletag = 0 then begin + ffiletag:= sourcefo.newfiletag; + end; + sourcefo.filechangenotifyer.addnotification(filepath,filetag,true); + end; + setsyntaxdef(newname); + if getfileinfo(newname,info) then begin + fsavetime:= info.extinfo1.modtime; + end; + updatecaption(false); +end; + +function tsourcepage.modified: boolean; +begin + result:= false; + if edit <> nil then begin + result:= edit.modified; + end; +end; + +procedure textnotfound(const ainfo: findinfoty); +begin + showmessage(sourcefo.c[ord(str_text)]+' '''+ + ainfo.text+''' '+ + sourcefo.c[ord(str_notfound)]); +end; + +procedure findintextedit(const edit: tcustomtextedit; var info: findinfoty; + var findpos: gridcoordty; + const backward: boolean = false); +var + pt1: gridcoordty; + isback: boolean; +begin + with info do begin + if text = '' then begin + exit; + end; + if backward then begin + info.options:= info.options >< [so_backward]; + end; + isback:= so_backward in info.options; + if selectedonly then begin + if edit.hasselection then begin + if isback then begin + normalizetextrect(edit.selectstart,edit.selectend,pt1,findpos); + end + else begin + normalizetextrect(edit.selectstart,edit.selectend,findpos,pt1); + end; + if not edit.find(text,options,findpos,pt1,true) then begin + textnotfound(info); + end + else begin + selectedonly:= false; + end; + end; + end + else begin + findpos:= edit.editpos; +// dec(ffindpos.col); + if isback then begin + pt1:= nullcoord; + end + else begin + pt1:= bigcoord; + end; + if not edit.find(text,options,findpos,pt1,true,findshowpos) then begin + if (edit.linecount = 0) or + isback and (findpos.row = edit.linecount-1) and + (findpos.col = length(edit.gridvalue[edit.linecount-1])) or + not isback and (findpos.row = 0) and (findpos.col = 0) then begin + textnotfound(info); + end + else begin + if isback then begin + if askok(sourcefo.c[ord(str_text)]+' '''+text+ + ''' '+sourcefo.c[ord(str_notfound)]+' '+ + sourcefo.c[ord(restartend)]) then begin + findpos:= bigcoord; + if not edit.find(text,options,findpos,edit.editpos,true, + findshowpos) then begin + textnotfound(info); + end; + end; + end + else begin + if askok(sourcefo.c[ord(str_text)]+' '''+text+ + ''' '+sourcefo.c[ord(str_notfound)]+' '+ + sourcefo.c[ord(restartbegin)]) then begin + findpos:= nullcoord; + if not edit.find(text,options,findpos,edit.editpos,true, + findshowpos) then begin + textnotfound(info); + end; + end; + end; + end; + end; + end; + if backward then begin + info.options:= info.options >< [so_backward]; + end; + end; +end; +{ +procedure tsourcepage.find; +begin + findintextedit(edit,projectoptions.findreplaceinfo.find,ffindpos); +end; +} +procedure tsourcepage.beginupdate; +begin + edit.beginupdate; + grid.focuslock; + application.beginwait; +end; + +procedure tsourcepage.endupdate; +begin + application.endwait; + grid.focusunlock; + edit.endupdate; + updatelinedisp; +end; + +procedure tsourcepage.replace(all: boolean); + + function checkescape: boolean; + begin + result:= application.waitescaped; + if result then begin + endupdate; + result:= askyesno(sourcefo.c[ord(cancel)]); + application.processmessages; + beginupdate; + end; + end; + +var + pos1: gridcoordty; + res1: modalresultty; + rect1: rectty; + updatedisabled: boolean; + +begin + with projectoptions.findreplaceinfo,find do begin + updatedisabled:= false; + edit.editor.begingroup; + try + if selectedonly then begin + if not edit.hasselection then begin + exit; + end + else begin + normalizetextrect(edit.selectstart,edit.selectend,ffindpos,pos1); + end; + end + else begin + ffindpos:= edit.editpos; + pos1:= bigcoord; + end; + if not edit.find(text,options,ffindpos,pos1,true,findshowpos) then begin + textnotfound(find); + end + else begin + res1:= mr_yes; + repeat + if prompt then begin + rect1:= edit.textpostomouserect(ffindpos); + res1:= showmessage(sourcefo.c[ord(replaceoccu)],'', + [mr_yes,mr_all,mr_no,mr_cancel],rect1,grid,cp_bottomleft,res1); + end + else begin + res1:= mr_yes; + end; + case res1 of + mr_no: begin + inc(ffindpos.col,length(text)); + end; + mr_yes,mr_all: begin + edit.deleteselection; + edit.inserttext(ffindpos,replacetext); + inc(ffindpos.col,length(replacetext)); + if (res1 = mr_all) or (all and not prompt) then begin + if not updatedisabled then begin + application.processmessages; //remove message window + updatedisabled:= true; + beginupdate; + end; + prompt:= false; + all:= true; + end; + end; + else begin + exit; + end; + end; + until not all or + not edit.find(text,options,ffindpos,pos1,true,findshowpos) or + updatedisabled and checkescape; + end; + finally + if updatedisabled then begin + endupdate; + end; + edit.editor.endgroup; + end; + end; +end; + +procedure tsourcepage.doline; +var + int1: int32; +begin + if integerenter(fgotoline,1,grid.rowcount, + sourcefo.c[ord(gotoline)],sourcefo.c[ord(findline)]) = mr_ok then begin + int1:= grid.rowwindowpos; + grid.row:= fgotoline-1; + grid.rowwindowpos:= int1; + end; +end; + +procedure tsourcepage.dofind; +var + ainfo: findinfoty; +begin + ainfo:= projectoptions.findreplaceinfo.find; + if not edit.hasselection then begin + ainfo.selectedonly:= false; + end; +// ainfo.text:= edit.selectedtext; + if finddialogexecute(ainfo) then begin + projectoptions.findreplaceinfo.find:= ainfo; + findintextedit(edit,projectoptions.findreplaceinfo.find,ffindpos); + end; +end; + +procedure tsourcepage.doreplace; +var + ainfo: replaceinfoty; + res1: modalresultty; +begin + ainfo:= projectoptions.findreplaceinfo; +// ainfo.find.text:= edit.selectedtext; + res1:= replacedialogexecute(ainfo); + if res1 in [mr_ok,mr_all] then begin + projectoptions.findreplaceinfo:= ainfo; + replace(res1 = mr_all); + end; +end; + +procedure tsourcepage.repeatfind; +begin + findintextedit(edit,projectoptions.findreplaceinfo.find,ffindpos); +end; + +procedure tsourcepage.findback; +begin + findintextedit(edit,projectoptions.findreplaceinfo.find,ffindpos,true); +end; + +procedure tsourcepage.hidehint; +begin + flasthint:= invalidcell; + flasthintlength:= 0; + application.hidehint; +end; + +procedure tsourcepage.showlink(const apos: gridcoordty); +begin + edit.showlink(apos,pascaldelims + '.[]'); +end; + +procedure tsourcepage.editontextmouseevent(const sender: tobject; + var info: textmouseeventinfoty); + +var + po1: gridcoordty; + str1,str2: msestring; + pos1: sourceposty; + shiftstate1: shiftstatesty; +begin + shiftstate1:= info.mouseeventinfopo^.shiftstate * shiftstatesmask; + if mainfo.gdb.started and projectoptions.d.valuehints then begin + if info.eventkind = cek_mousepark then begin + str1:= getpascalvarname(edit,info.pos,po1); + if (po1.row <> flasthint.row) or (po1.col <> flasthint.col) or + (length(str1) <> flasthintlength) then begin + if str1 <> '' then begin + if mainfo.gdb.readpascalvariable(ansistring(str1),str2) = gdb_ok then begin + application.showhint(nil,str1 + ' = ' + str2, + inflaterect(edit.textpostomouserect(po1,true),20),cp_bottomleft,0); + end + else begin + hidehint; + end; + flasthint:= po1; + flasthintlength:= length(str1); + end + else begin + hidehint; + flasthintlength:= -1; + end; + end; + end; + end; + with info do begin + case eventkind of + cek_mousemove: begin + if (shiftstate1 = [ss_ctrl]) and active then begin + showlink(info.pos); + end; + end; + cek_mouseleave: begin + edit.removelink; + end; + cek_buttonpress: begin + if (shiftstate1 = [ss_ctrl,ss_left]) {and active} then begin +// include(info.mouseeventinfopo^.eventstate,es_processed); + pos1.pos:= info.pos; + pos1.filename:= designer.designfiles.find(edit.filename); + if findlinkdest(edit,pos1,str1) then begin + fshowsourcepos:= pos1; + asyncevent(ord(spat_showsource)); +// sourcefo.naviglist.showsource(pos1,true); + end; + end + else begin + if edit.isdblclicked(info.mouseeventinfopo^) and + (info.mouseeventinfopo^.shiftstate*[ss_double,ss_shift,ss_left] = + [ss_double,ss_shift,ss_left]) then begin + if ss_triple in info.mouseeventinfopo^.shiftstate then begin + edit.setselection(makegridcoord(0,edit.row), + makegridcoord(bigint,edit.row),true); + end + else begin + edit.selectword(info.pos,selectdelims); + end; + copytoclipboard(edit.selectedtext,cbb_primary); + include(info.mouseeventinfopo^.eventstate,es_processed); + end; + end; + end; + end; + end; +end; + +procedure tsourcepage.updatelinedisp; +begin + linedisp.value:= inttostrmse(edit.editpos.row+1) + ':'+ + inttostrmse(edit.editpos.col+1); +end; + +procedure tsourcepage.editoneditnotification(const sender: tobject; + var info: editnotificationinfoty); +begin +// if (info.action = ea_beforechange) and not edit.syntaxchanging then begin +// clearbrackets; +// end +// else begin + if (info.action = ea_indexmoved) and not grid.updating then begin + updatelinedisp; + end; +// if info.action in [ea_indexmoved,ea_delchar,ea_deleteselection,ea_pasteselection, +// ea_textentered] then begin +// callcheckbrackets; +// end; +// end; +end; + +procedure tsourcepage.gridonrowsdeleted(const sender: tcustomgrid; + const index, count: integer); +begin + breakpointsfo.sourcelinesdeleted(filepath,index+1,count); + if (factiverow >= 0) and (index <= factiverow) then begin + factiverow:= factiverow - count; + if factiverow < index then begin + activerow:= -1; //removed + end; + end; +end; + +procedure tsourcepage.gridonrowsinserted(const sender: tcustomgrid; + const index, count: integer); +begin + breakpointsfo.sourcelinesinserted(filepath,index+1,count); + if (factiverow >= 0) and (index <= factiverow) then begin + factiverow:= factiverow + count; + end; +end; + +procedure tsourcepage.sourcefoonshow(const sender: TObject); +begin + if not ffileloaderror then begin + try + loadfile; + mainfo.checkbluedots; + except + on e: exception do begin + ffileloaderror:= true; + application.showasyncexception(e,''); + hide; + // parentwidget:= nil; + release; + end; + end; + end; +end; + +procedure tsourcepage.updatestatvalues; +var + int1: integer; + colors: syntaxcolorinfoty; +begin + if edit <> nil then begin + projectoptionstofont(edit.font); + with projectoptions do begin + grid.frame.colorclient:= e.editbkcolor; + grid.rowcolors[0]:= e.statementcolor; + grid.datarowheight:= edit.font.lineheight; + int1:= edit.getcanvas.getstringwidth('oo') div 2; + with grid.fixcols[-1] do begin + visible:= e.linenumberson; + font.height:= edit.font.height; + font.name:= edit.font.name; + end; + if e.rightmarginon then begin + edit.marginlinecolor:= cl_gray; + edit.marginlinepos:= int1 * e.rightmarginchars; + end + else begin + edit.marginlinecolor:= cl_none; + end; + if e.tabstops < 1 then begin + e.tabstops:= 1; + end; + if e.showtabs then begin + edit.textflags:= edit.textflags + [tf_showtabs]; + edit.textflagsactive:= edit.textflagsactive + [tf_showtabs]; + end + else begin + edit.textflags:= edit.textflags - [tf_showtabs]; + edit.textflagsactive:= edit.textflagsactive - [tf_showtabs]; + end; + edit.tabulators.clear; + edit.tabulators.defaultdist:= int1 * e.tabstops / edit.tabulators.ppmm; +// edit.tabulators.setdefaulttabs(int1 * tabstops / edit.tabulators.ppmm); + edit.autoindent:= e.autoindent; + edit.markbrackets:= e.editmarkbrackets; + edit.markpairwords:= e.editmarkpairwords; + case e.encoding of + 1: begin + edit.encoding:= ce_utf8; + end; + 2: begin + edit.encoding:= ce_iso8859_1; + end; + else begin + edit.encoding:= ce_locale; + end; + end; + case e.eolstyle of + 1: begin + edit.eolstyle:= eol_system; + end; + 2: begin + edit.eolstyle:= eol_unix; + end; + 3: begin + edit.eolstyle:= eol_windows; + end; + else begin + edit.eolstyle:= eol_default; + end; + end; + grid.wheelscrollheight:= e.scrollheight; + edit.pairmarkbkgcolor:= e.pairmarkcolor; + edit.pairmaxrowcount:= e.pairmaxrowcount; + if edit.syntaxpainterhandle >= 0 then begin + colors:= edit.syntaxpainter.colors[edit.syntaxpainterhandle]; + with colors do begin + if font <> cl_default then begin + edit.font.color:= font; + end; + if background <> cl_default then begin + grid.frame.colorclient:= background; + end; + if (statement <> cl_default) and (grid.rowcolors[0] <> cl_none) then begin + grid.rowcolors[0]:= statement; + end; + end; + end; + end; + end; +end; + +procedure tsourcepage.editonfontchanged(const sender: TObject); +begin +// updatestatvalues; +end; + +procedure tsourcepage.sourcefoondeactivate(const sender: TObject); +begin + sourcefo.hidesourcehint; +end; + +procedure tsourcepage.gridoncellevent(const sender: TObject; + var info: celleventinfoty); +//var +// shiftstate1: shiftstatesty; +begin +{ + if (info.eventkind = cek_keydown) then begin + with info.keyeventinfopo^ do begin + shiftstate1:= shiftstate * shiftstatesmask; + if (shiftstate1 = [ss_ctrl]) and + (key >= key_0) and (key <= key_9) then begin + if sourcefo.findbookmark(ord(key) - ord(key_0)) then begin + include(eventstate,es_processed); + end; + end + else begin + if (shiftstate1 = [ss_ctrl,ss_shift]) and + (keynomod >= key_0) and (keynomod <= key_9) then begin + sourcefo.setbookmark(self,info.cell.row,ord(keynomod) - ord(key_0)); + include(eventstate,es_processed); + end; + end; + end; + end; +} +end; + +function tsourcepage.findbookmark(const bookmarknum: integer): integer; +var + int1,int2,int3: integer; + po1: pintegeraty; +begin + result:= -1; + for int3:= 0 to high(finitialbookmarks) do begin + if finitialbookmarks[int3].bookmarknum = bookmarknum then begin + loadfile; + po1:= dataicon.griddata.datapo; + int2:= 1 shl (bookmarknum + bmbitshift); + for int1:= 0 to grid.rowcount - 1 do begin + if po1^[int1] and bmbitmask = int2 then begin + result:= int1; + break; + end; + end; + end; + end; +end; + +procedure tsourcepage.removebookmark(const bookmarknum: integer); +var + int1: integer; +begin + for int1:= high(finitialbookmarks) downto 0 do begin + if finitialbookmarks[int1].bookmarknum = bookmarknum then begin + deleteitem(finitialbookmarks,typeinfo(bookmarkarty),int1); + end; + end; +end; + +procedure tsourcepage.setbookmark(arow: integer; const bookmarknum: integer); + //arow -1 -> current row, bookmarknum < 1 -> clear +begin + if arow < 0 then begin + arow:= grid.row; + end; + if arow >= 0 then begin + if bookmarknum < 0 then begin + dataicon[arow]:= dataicon[arow] and not bmbitmask; + removebookmark(bookmarknum); + end + else begin + dataicon[arow]:= replacebits(longword(1 shl (bookmarknum + bmbitshift)), + longword(dataicon[arow]),longword(bmbitmask)); + setlength(finitialbookmarks,high(finitialbookmarks)+2); + finitialbookmarks[high(finitialbookmarks)].bookmarknum:= bookmarknum; + end; + end; +end; + +procedure tsourcepage.clearbookmark(const bookmarknum: integer); +var + int1,int2: integer; + po1: pintegeraty; +begin + removebookmark(bookmarknum); + po1:= dataicon.griddata.datapo; + int2:= 1 shl (bookmarknum + bmbitshift); + for int1:= 0 to grid.rowcount - 1 do begin + if po1^[int1] and bmbitmask = int2 then begin + dataicon[int1]:= po1^[int1] and not bmbitmask; + end; + end; +end; + +function tsourcepage.getbookmarks: bookmarkarty; +var + int1,int2: integer; + po1: pintegeraty; + lwo1: longword; +begin + if not fileloaded then begin + result:= copy(finitialbookmarks); + end + else begin + po1:= dataicon.griddata.datapo; + int2:= 0; + result:= nil; + for int1:= 0 to grid.rowcount - 1 do begin + lwo1:= po1^[int1] and bmbitmask; + if lwo1 <> 0 then begin + additem(result,typeinfo(bookmarkarty),int2); + with result[int2-1] do begin + row:= int1; + bookmarknum:= lowestbit(lwo1) - bmbitshift; + end; + end; + end; + setlength(result,int2); + end; +end; + +procedure tsourcepage.setbackupcreated; +begin + fbackupcreated:= true; +end; + +procedure tsourcepage.editonkeydown(const sender: twidget; + var info: keyeventinfoty); +begin + with info,tsyntaxedit(sender).editor,projectoptions do begin + if e.spacetabs and (e.tabstops > 0) and (shiftstate = []) and + (key = key_tab) then begin + chars:= charstring(msechar(' '), + (curindex div e.tabstops + 1) * e.tabstops - curindex); + end; + end; +end; +{ +procedure tsourcepage.clearbrackets; +begin + if (fbracket1.col >= 0) and (fbracketsetting = 0) then begin + inc(fbracketsetting); + try + with edit do begin + setfontstyle(fbracket1,makegridcoord(fbracket1.col+1,fbracket1.row), + fs_bold,false); + setfontstyle(fbracket2,makegridcoord(fbracket2.col+1,fbracket2.row), + fs_bold,false); + refreshsyntax(fbracket1.row,1); + refreshsyntax(fbracket2.row,1); + fbracket1:= invalidcell; + fbracket2:= invalidcell; + if syntaxpainterhandle >= 0 then begin + syntaxpainter.boldchars[syntaxpainterhandle]:= nil; + end; + end; + finally + dec(fbracketsetting); + end; + end; +end; + +procedure tsourcepage.checkbrackets; +var + mch1: msechar; + br1,br2: bracketkindty; + open,open2: boolean; + pt1,pt2: gridcoordty; + ar1: gridcoordarty; +begin + clearbrackets; + pt2:= invalidcell; + with edit do begin + pt1:= editpos; + mch1:= charatpos(pt1); + br1:= checkbracketkind(mch1,open); + if (br1 <> bki_none) and (pt1.col > 0) then begin + dec(pt1.col); + br2:= checkbracketkind(charatpos(pt1),open2); + if (br2 = bki_none) or (open <> open2) then begin + inc(pt1.col); + end + else begin + br1:= br2; + end; + pt2:= matchbracket(pt1,br1,open); + end + else begin + dec(pt1.col); + if pt1.col >= 0 then begin + mch1:= charatpos(pt1); + br1:= checkbracketkind(mch1,open); + if br1 <> bki_none then begin + pt2:= matchbracket(pt1,br1,open); + end; + end; + end; + if pt2.col >= 0 then begin + fbracket1:= pt1; + fbracket2:= pt2; + inc(fbracketsetting); + try + setfontstyle(pt1,makegridcoord(pt1.col+1,pt1.row),fs_bold,true); + setfontstyle(pt2,makegridcoord(pt2.col+1,pt2.row),fs_bold,true); + finally + dec(fbracketsetting); + end; + if syntaxpainterhandle >= 0 then begin + setlength(ar1,2); + ar1[0]:= fbracket1; + ar1[1]:= fbracket2; + syntaxpainter.boldchars[syntaxpainterhandle]:= ar1; + refreshsyntax(fbracket1.row,1); + refreshsyntax(fbracket2.row,1); + end; + end; + end; +end; + +procedure tsourcepage.callcheckbrackets; +begin + if (fbracketchecking = 0) and (projectoptions.e.editmarkbrackets) then begin + inc(fbracketchecking); + asyncevent(ord(spat_checkbracket)); + end; +end; +} +function tsourcepage.source: trichstringdatalist; +begin + result:= edit.datalist; +end; + +procedure tsourcepage.copywordatcursor(); +begin + edit.selectword(edit.editpos,selectdelims); + edit.copyselection(); +end; + +procedure tsourcepage.doundo; +begin + beginupdate; + edit.undo; + endupdate; +end; + +procedure tsourcepage.doredo; +begin + beginupdate; + edit.redo; + endupdate; +end; + +procedure tsourcepage.inserttemplate; +var + mstr1,mstr2: msestring; +// po1: pmsechar; + po2: ptemplateinfoty; + gc1,gc2: gridcoordty; + int1: integer; + mac1: tmacrolist; + ar1: msestringarty; +begin + gc1:= edit.editpos; + if gc1.row >= 0 then begin + mstr1:= edit.wordatpos(gc1,gc2,'',[],true); + if gc2.col < 0 then begin + gc2.col:= gc1.col; + end; + mac1:= getmacros; + try + po2:= codetemplates.gettemplate(mstr1,mstr2,mac1); + if po2 <> nil then begin + with edit,po2^ do begin + editor.begingroup; + gc1.col:= gc2.col+length(mstr1); + deletetext(gc2,gc1); + if indent then begin + ar1:= breaklines(mstr2); + for int1:= 1 to high(ar1) do begin + ar1[int1]:= charstring(msechar(' '),gc2.col)+ar1[int1]; + end; + mstr2:= concatstrings(ar1,lineend); + end; + inserttext(gc2,mstr2,select); + if not select then begin + if indent or (cursorpos.row = 0) then begin + gc2.col:= gc2.col + cursorpos.col; + end + else begin + gc2.col:= cursorpos.col; + end; + gc2.row:= gc2.row + cursorpos.row; + editpos:= gc2; + end; + end; + edit.editor.endgroup; + end; + finally + mac1.free; + end; + end; +end; + +procedure tsourcepage.copylatex; +begin + copytoclipboard(richstringtolatex(edit.selectedrichtext)); +end; + +function tsourcepage.cancomment(): boolean; +begin + result:= edit.hasselection and (edit.selectstart.col = 0) and + (edit.selectend.col = 0); +end; + +function tsourcepage.canuncomment(): boolean; +var + po1,pe: prichstringty; + start,stop: int32; +begin + result:= cancomment(); + if result then begin + edit.getselectedrows(start,stop); + po1:= edit.datalist.getitempo(start); + pe:= po1 + stop - start; + while po1 <= pe do begin + if (length(po1^.text) < 2) or (po1^.text[1] <> '/') or + (po1^.text[2] <> '/') then begin + result:= false; + break; + end; + inc(po1); + end; + end; +end; + +procedure tsourcepage.commentselection(); +var + mstr1: msestring; + i1: int32; + start,stop: int32; +begin + if cancomment() then begin + edit.getselectedrows(start,stop); + edit.editor.begingroup(); + mstr1:= edit.selectedtext; + insert('//',mstr1,1); + i1:= 3; + while mstr1[i1] <> #0 do begin + if mstr1[i1] = c_return then begin + inc(i1); + end; + if mstr1[i1] = c_linefeed then begin + inc(i1); + if mstr1[i1] = #0 then begin + break; + end; + insert('//',mstr1,i1); + end; + inc(i1); + end; + grid.beginupdate(); + edit.deleteselection(); + edit.inserttext(mstr1,true); + grid.endupdate(); + edit.editor.endgroup(); + edit.refreshsyntax(start,stop-start); + end; +end; + +procedure tsourcepage.uncommentselection(); +var + mstr1: msestring; + i1: int32; + start,stop: int32; +begin + if canuncomment() then begin + edit.getselectedrows(start,stop); + edit.editor.begingroup(); + mstr1:= edit.selectedtext; + delete(mstr1,1,2); + i1:= 1; + while mstr1[i1] <> #0 do begin + if mstr1[i1] = c_return then begin + inc(i1); + end; + if mstr1[i1] = c_linefeed then begin + inc(i1); + if mstr1[i1] = #0 then begin + break; + end; + delete(mstr1,i1,2); + dec(i1); + end; + inc(i1); + end; + grid.beginupdate(); + edit.deleteselection(); + edit.inserttext(mstr1,true); + grid.endupdate(); + edit.editor.endgroup(); + edit.refreshsyntax(start,stop-start); + end; +end; + +end. diff --git a/mseide-msegui/apps/ide/sourcepage_mfm.pas b/mseide-msegui/apps/ide/sourcepage_mfm.pas new file mode 100644 index 0000000..ec1b224 --- /dev/null +++ b/mseide-msegui/apps/ide/sourcepage_mfm.pas @@ -0,0 +1,213 @@ +unit sourcepage_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,sourcepage; + +const + objdata: record size: integer; data: array[0..3917] of byte end = + (size: 3918; data: ( + 84,80,70,48,11,116,115,111,117,114,99,101,112,97,103,101,10,115,111,117, + 114,99,101,112,97,103,101,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,13,111,119,95,97,114,114,111,119,102,111,99,117,115,11,111,119,95, + 115,117,98,102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,9,111,119,95,104,105,110,116,111,110,0,11,111,112, + 116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101, + 98,117,116,116,111,110,111,110,108,121,0,5,99,111,108,111,114,4,5,0, + 0,144,8,98,111,117,110,100,115,95,120,3,192,0,8,98,111,117,110,100, + 115,95,121,3,245,0,9,98,111,117,110,100,115,95,99,120,3,55,1,9, + 98,111,117,110,100,115,95,99,121,3,228,0,23,99,111,110,116,97,105,110, + 101,114,46,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119, + 95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111, + 99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,11,111,119, + 95,115,117,98,102,111,99,117,115,19,111,119,95,109,111,117,115,101,116,114, + 97,110,115,112,97,114,101,110,116,17,111,119,95,100,101,115,116,114,111,121, + 119,105,100,103,101,116,115,0,26,99,111,110,116,97,105,110,101,114,46,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,27,99,111, + 110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,99,111,110,116,97,105,110,101,114,46,98,111, + 117,110,100,115,1,2,0,2,0,3,55,1,3,228,0,0,21,105,99,111, + 110,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,0, + 0,0,128,8,111,110,99,114,101,97,116,101,7,16,115,111,117,114,99,101, + 102,111,111,110,99,114,101,97,116,101,16,111,110,101,118,101,110,116,108,111, + 111,112,115,116,97,114,116,7,16,115,111,117,114,99,101,102,111,111,110,108, + 111,97,100,101,100,9,111,110,100,101,115,116,114,111,121,7,17,115,111,117, + 114,99,101,102,111,111,110,100,101,115,116,114,111,121,6,111,110,115,104,111, + 119,7,14,115,111,117,114,99,101,102,111,111,110,115,104,111,119,6,111,110, + 104,105,100,101,7,20,115,111,117,114,99,101,102,111,111,110,100,101,97,99, + 116,105,118,97,116,101,15,109,111,100,117,108,101,99,108,97,115,115,110,97, + 109,101,6,8,116,116,97,98,102,111,114,109,0,11,116,119,105,100,103,101, + 116,103,114,105,100,4,103,114,105,100,13,111,112,116,105,111,110,115,119,105, + 100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11, + 111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119, + 102,111,99,117,115,13,111,119,95,109,111,117,115,101,119,104,101,101,108,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,11,111, + 112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109, + 101,98,117,116,116,111,110,111,110,108,121,0,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,3,55,1,9,98,111,117,110,100,115,95,99,121,3,206,0,7, + 97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,9,97,110,95,98, + 111,116,116,111,109,0,11,111,112,116,105,111,110,115,103,114,105,100,11,19, + 111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101,114,15, + 111,103,95,97,117,116,111,102,105,114,115,116,114,111,119,10,111,103,95,119, + 114,97,112,99,111,108,21,111,103,95,118,105,115,105,98,108,101,114,111,119, + 112,97,103,101,115,116,101,112,0,13,102,105,120,99,111,108,115,46,99,111, + 117,110,116,2,1,13,102,105,120,99,111,108,115,46,105,116,101,109,115,14, + 1,5,99,111,108,111,114,4,5,0,0,160,9,108,105,110,101,119,105,100, + 116,104,2,0,9,116,101,120,116,102,108,97,103,115,11,8,116,102,95,114, + 105,103,104,116,12,116,102,95,121,99,101,110,116,101,114,101,100,0,8,110, + 117,109,115,116,97,114,116,2,1,7,110,117,109,115,116,101,112,2,1,10, + 102,111,110,116,46,99,111,108,111,114,4,3,0,0,160,9,102,111,110,116, + 46,110,97,109,101,6,11,115,116,102,95,100,101,102,97,117,108,116,11,102, + 111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110,116,46,108,111, + 99,97,108,112,114,111,112,115,11,9,102,108,112,95,99,111,108,111,114,10, + 102,108,112,95,120,115,99,97,108,101,0,0,0,14,103,114,105,100,102,114, + 97,109,101,99,111,108,111,114,4,3,0,0,128,15,114,111,119,99,111,108, + 111,114,115,46,99,111,117,110,116,2,4,15,114,111,119,99,111,108,111,114, + 115,46,105,116,101,109,115,1,4,255,255,224,0,4,255,255,0,0,4,0, + 0,255,0,4,2,0,0,128,0,14,100,97,116,97,99,111,108,115,46,99, + 111,117,110,116,2,2,14,100,97,116,97,99,111,108,115,46,105,116,101,109, + 115,14,7,8,100,97,116,97,105,99,111,110,1,9,108,105,110,101,99,111, + 108,111,114,4,4,0,0,160,5,119,105,100,116,104,2,15,7,111,112,116, + 105,111,110,115,11,10,99,111,95,110,111,102,111,99,117,115,12,99,111,95, + 110,111,104,115,99,114,111,108,108,0,11,111,110,99,101,108,108,101,118,101, + 110,116,7,15,105,99,111,110,111,110,99,101,108,108,101,118,101,110,116,10, + 119,105,100,103,101,116,110,97,109,101,6,8,100,97,116,97,105,99,111,110, + 9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100,105,110,116, + 101,103,101,114,100,97,116,97,108,105,115,116,0,7,4,101,100,105,116,1, + 5,119,105,100,116,104,3,208,7,7,111,112,116,105,111,110,115,11,22,99, + 111,95,108,101,102,116,98,117,116,116,111,110,102,111,99,117,115,111,110,108, + 121,20,99,111,95,109,105,100,100,108,101,98,117,116,116,111,110,102,111,99, + 117,115,12,99,111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109, + 111,117,115,101,115,99,114,111,108,108,114,111,119,0,8,111,110,99,104,97, + 110,103,101,7,11,116,101,120,116,99,104,97,110,103,101,100,10,119,105,100, + 103,101,116,110,97,109,101,6,4,101,100,105,116,9,100,97,116,97,99,108, + 97,115,115,7,23,116,103,114,105,100,114,105,99,104,115,116,114,105,110,103, + 100,97,116,97,108,105,115,116,0,0,16,100,97,116,97,114,111,119,108,105, + 110,101,119,105,100,116,104,2,0,13,100,97,116,97,114,111,119,104,101,105, + 103,104,116,2,18,14,111,110,114,111,119,115,105,110,115,101,114,116,101,100, + 7,18,103,114,105,100,111,110,114,111,119,115,105,110,115,101,114,116,101,100, + 13,111,110,114,111,119,115,100,101,108,101,116,101,100,7,17,103,114,105,100, + 111,110,114,111,119,115,100,101,108,101,116,101,100,11,111,110,99,101,108,108, + 101,118,101,110,116,7,15,103,114,105,100,111,110,99,101,108,108,101,118,101, + 110,116,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,11, + 116,115,121,110,116,97,120,101,100,105,116,4,101,100,105,116,11,111,112,116, + 105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98, + 117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2, + 1,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2, + 0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,3,208,7,9,98,111,117,110,100,115,95,99,121,2,18,9,102,111, + 110,116,46,110,97,109,101,6,13,109,115,101,105,100,101,95,115,111,117,114, + 99,101,11,102,111,110,116,46,120,115,99,97,108,101,2,1,15,102,111,110, + 116,46,108,111,99,97,108,112,114,111,112,115,11,10,102,108,112,95,120,115, + 99,97,108,101,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,15, + 111,101,49,95,110,111,115,101,108,101,99,116,97,108,108,13,111,101,49,95, + 115,97,118,101,115,116,97,116,101,0,11,111,112,116,105,111,110,115,101,100, + 105,116,11,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101, + 95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,108,105, + 110,101,98,114,101,97,107,12,111,101,95,101,97,116,114,101,116,117,114,110, + 15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,20,111,101,95, + 110,111,102,105,114,115,116,97,114,114,111,119,110,97,118,105,103,0,15,116, + 97,98,117,108,97,116,111,114,115,46,112,112,109,109,2,3,22,116,97,98, + 117,108,97,116,111,114,115,46,100,101,102,97,117,108,116,100,105,115,116,2, + 0,9,111,110,107,101,121,100,111,119,110,7,13,101,100,105,116,111,110,107, + 101,121,100,111,119,110,13,111,110,102,111,110,116,99,104,97,110,103,101,100, + 7,17,101,100,105,116,111,110,102,111,110,116,99,104,97,110,103,101,100,17, + 111,110,109,111,100,105,102,105,101,100,99,104,97,110,103,101,100,7,21,101, + 100,105,116,111,110,109,111,100,105,102,105,101,100,99,104,97,110,103,101,100, + 16,111,110,116,101,120,116,109,111,117,115,101,101,118,101,110,116,7,20,101, + 100,105,116,111,110,116,101,120,116,109,111,117,115,101,101,118,101,110,116,17, + 111,110,101,100,105,116,110,111,116,105,102,99,97,116,105,111,110,7,22,101, + 100,105,116,111,110,101,100,105,116,110,111,116,105,102,105,99,97,116,105,111, + 110,11,111,110,99,101,108,108,101,118,101,110,116,7,15,101,100,105,116,111, + 110,99,101,108,108,101,118,101,110,116,12,109,97,120,117,110,100,111,99,111, + 117,110,116,3,16,39,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,18,0,0,9,116,100,97,116,97,105,99,111,110,8,100,97,116,97,105, + 99,111,110,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107, + 95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,98,111, + 117,110,100,115,95,120,2,50,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,120,2,15,9,98,111,117,110,100,115,95,99, + 121,2,18,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95, + 117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117, + 101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108, + 12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115, + 101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120, + 105,116,111,110,99,117,114,115,111,114,13,111,101,95,97,117,116,111,115,101, + 108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110, + 102,105,114,115,116,99,108,105,99,107,0,12,111,112,116,105,111,110,115,101, + 100,105,116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109, + 101,110,117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111, + 101,49,95,115,97,118,101,115,116,97,116,101,0,7,111,112,116,105,111,110, + 115,11,15,98,111,95,101,120,101,99,117,116,101,111,110,107,101,121,20,98, + 111,95,101,120,101,99,117,116,101,111,110,115,104,111,114,116,99,117,116,27, + 98,111,95,101,120,101,99,117,116,101,100,101,102,97,117,108,116,111,110,101, + 110,116,101,114,107,101,121,0,7,118,105,115,105,98,108,101,8,12,118,97, + 108,117,101,100,101,102,97,117,108,116,4,0,0,0,128,3,109,105,110,2, + 255,3,109,97,120,2,2,15,105,109,97,103,101,110,117,109,115,46,99,111, + 117,110,116,2,14,15,105,109,97,103,101,110,117,109,115,46,105,116,101,109, + 115,1,2,0,2,1,2,2,2,3,2,4,2,5,2,6,2,7,2,8, + 2,9,2,10,2,11,2,12,2,13,0,0,0,0,11,116,115,116,114,105, + 110,103,101,100,105,116,8,108,105,110,101,100,105,115,112,11,111,112,116,105, + 111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117, + 116,116,111,110,111,110,108,121,0,5,99,111,108,111,114,4,3,0,0,128, + 12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109, + 101,46,99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97, + 98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,2,0,8, + 98,111,117,110,100,115,95,121,3,207,0,9,98,111,117,110,100,115,95,99, + 120,2,68,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116, + 9,97,110,95,98,111,116,116,111,109,0,11,111,112,116,105,111,110,115,101, + 100,105,116,11,11,111,101,95,114,101,97,100,111,110,108,121,12,111,101,95, + 117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117, + 101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108, + 14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101, + 97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108, + 101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99, + 117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13, + 111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116, + 111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,22, + 111,101,95,102,111,99,117,115,114,101,99,116,111,110,114,101,97,100,111,110, + 108,121,18,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120, + 116,0,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,120,99,101, + 110,116,101,114,101,100,12,116,102,95,121,99,101,110,116,101,114,101,100,0, + 15,116,101,120,116,102,108,97,103,115,97,99,116,105,118,101,11,12,116,102, + 95,120,99,101,110,116,101,114,101,100,12,116,102,95,121,99,101,110,116,101, + 114,101,100,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16, + 0,0,11,116,115,116,114,105,110,103,101,100,105,116,8,112,97,116,104,100, + 105,115,112,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107, + 95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,5,99,111, + 108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108, + 111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110, + 116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117, + 110,100,115,95,120,2,68,8,98,111,117,110,100,115,95,121,3,207,0,9, + 98,111,117,110,100,115,95,99,120,3,243,0,7,97,110,99,104,111,114,115, + 11,7,97,110,95,108,101,102,116,8,97,110,95,114,105,103,104,116,9,97, + 110,95,98,111,116,116,111,109,0,11,111,112,116,105,111,110,115,101,100,105, + 116,11,11,111,101,95,114,101,97,100,111,110,108,121,12,111,101,95,117,110, + 100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114, + 121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111, + 101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116, + 114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99, + 116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114, + 115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101, + 95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115, + 101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,18,111,101, + 95,99,97,114,101,116,111,110,114,101,97,100,111,110,108,121,22,111,101,95, + 102,111,99,117,115,114,101,99,116,111,110,114,101,97,100,111,110,108,121,18, + 111,101,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116,0,9, + 116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101,110,116,101, + 114,101,100,14,116,102,95,101,108,108,105,112,115,101,108,101,102,116,0,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tsourcepage,''); +end. diff --git a/mseide-msegui/apps/ide/sourceupdate.pas b/mseide-msegui/apps/ide/sourceupdate.pas new file mode 100644 index 0000000..226e492 --- /dev/null +++ b/mseide-msegui/apps/ide/sourceupdate.pas @@ -0,0 +1,2350 @@ +{ MSEide Copyright (c) 1999-2016 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit sourceupdate; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + msedesigner,mseclasses,msedesignintf,classes,mclasses,typinfo, + msetypes,msestrings,pascaldesignparser,cdesignparser,mseglob, + msestream,mseparser,msesyntaxedit,mselist,msehash,msedesignparser; + +const + procheaderbreakchars = '(;'; +type + unitinfoaty = array[0..0] of tunitinfo; + punitinfoaty = ^unitinfoaty; +// unitinfopoarty = array of punitinfoty; + + tfilenameinfo = class + private + funits: unitinfopoarty; + public + procedure addunitinfo(ainfo: punitinfoty); + end; + + tfilenamelist = class(tobjectmsestringhashdatalist) + public + procedure add(const key: filenamety; info: punitinfoty); + function find(const key: filenamety): tfilenameinfo; + procedure sourcefilemodified(key: filenamety); + end; + + tunitinfolist = class(tobjectqueue) + private +// fnamelist: thashedstrings; + fnamelist: tpointeransistringhashdatalist; + protected + function getitempo(const index: integer): punitinfoty; + public + constructor create; + destructor destroy; override; + procedure clear; override; + function datapo: punitinfoaty; reintroduce; + function newitem(const lang: proglangty): punitinfoty; + property itempo[const index: integer]: punitinfoty read getitempo; default; + function finditembyformfilename(const afilename: filenamety): punitinfoty; + function finditembysourcefilename(const afilename: filenamety; + var filenum: integer): punitinfoty; + function finditembyunitname(const aname: string): punitinfoty; + end; + + tsourceupdater = class(tnullinterfacedobject,idesignnotification) + private + fdesigner: tdesigner; + funitinfolist: tunitinfolist; + ffilenamelist: tfilenamelist; + falphabeticprocorder: boolean; + fmaxlinelength: integer; + protected + //idesignnotification + procedure itemdeleted(const adesigner: idesigner; + const amodule: tmsecomponent; const aitem: tcomponent); + procedure iteminserted(const adesigner: idesigner; + const amodule: tmsecomponent; const aitem: tcomponent); + procedure itemsmodified(const adesigner: idesigner; const aitem: tobject); + //nil for undefined aitem + procedure componentnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const aitem: tcomponent; + const newname: string); + procedure moduleclassnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); + procedure instancevarnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); + procedure selectionchanged(const adesigner: idesigner; + const aselection: idesignerSelections); + procedure moduleactivated(const adesigner: idesigner; + const amodule: tmsecomponent); + procedure moduledeactivated(const adesigner: idesigner; + const amodule: tmsecomponent); + procedure moduledestroyed(const adesigner: idesigner; + const amodule: tmsecomponent); + procedure methodcreated(const adesigner: idesigner; + const amodule: tmsecomponent; + const aname: string; const atype: ptypeinfo); + procedure methodnamechanged(const adesigner: idesigner; + const amodule: tmsecomponent; + const newname,oldname: string; + const atypeinfo: ptypeinfo); + procedure showobjecttext(const adesigner: idesigner; + const afilename: filenamety; const backupcreated: boolean); + procedure closeobjecttext(const adesigner: idesigner; + const afilename: filenamety; var cancel: boolean); + procedure beforefilesave(const adesigner: idesigner; + const afilename: filenamety); + procedure beforemake(const adesigner: idesigner; const maketag: integer; + var abort: boolean); + procedure aftermake(const adesigner: idesigner; const exitcode: integer); + + procedure getincludefile(const sender: tparser; const scanner: tscanner); + procedure updatepascalunit(const infopo: punitinfoty; + const interfaceonly: boolean); overload; + procedure updatecunit(const infopo: punitinfoty; + const interfaceonly: boolean); overload; + procedure updateunit(const infopo: punitinfoty; + const interfaceonly: boolean); overload; + function composeproceduretext(const name: string; const info: methodparaminfoty; + const withdefault: boolean): string; overload; + function composeprocedureheader(const name: string; + const info: methodparaminfoty; const withdefault: boolean; + const classproc: boolean): string; overload; + function composeprocedureheader(const infopo: pprocedureinfoty; + const classinfopo: pclassinfoty; + const withdefault: boolean): string; overload; + function composeprocedureheader(const name: string; const typeinfo: ptypeinfo; + const withdefault: boolean; + const classproc: boolean): string; overload; + procedure createmethodbody(const unitinfopo: punitinfoty; + const classinfopo: pclassinfoty; const aname: string; + const atype: ptypeinfo; beforeitem: integer); + function createscratchfile(const origname: filenamety): ttextstream; + function updateline(module: punitinfoty; var apos: sourceposty): boolean; overload; + function updateline(module: punitinfoty; var apos: sourceposty; + const afilename: filenamety): boolean; overload; + //calculates absolute line number from includefiles, + //false if invalid + procedure updateincludefilenum(module: punitinfoty; + const filename: filenamety; var filenum: integer); + + function findsourceitem1(const infopo: punitinfoty; const apos: sourceposty; + out scope: tdeflist): pdefinfoty; + procedure checkitemlist(const infopo: punitinfoty); + function findsourceitem(const infopo: punitinfoty; + const apos: sourceposty): psourceitemty; overload; + function findsourceitem(const infopo: punitinfoty; const apos: sourceposty; + out aindex: integer): psourceitemty; overload; + function getidentpath(const infopo: punitinfoty; const apos: sourceposty; + const firstidentuse: boolean; + out scope: tdeflist): stringarty; overload; + function getidentpath(const parser: tpascalparser): stringarty; overload; + function switchheaderimplementation(const infopo: punitinfoty; + var headerstart,headerstop: sourceposty; + out isimplementation: boolean): boolean; + function completeclass(const infopo: punitinfoty; + const pos: sourceposty): boolean; //true if changed + procedure sourcechanged(const filename: filenamety); + function listprocheaders(const infopo: punitinfoty; + const apos: sourceposty): procedureinfopoarty; + function listsourceitems(const infopo: punitinfoty; + const apos: sourceposty; out scopes: deflistarty; + out defs: definfopoarty; + const maxcount: integer = 100): boolean; + public + constructor create(const adesigner: tdesigner); + destructor destroy; override; + procedure clear; + + procedure unitchanged(const aunit: punitinfoty = nil); overload; + procedure unitchanged(const asourcefilename: filenamety); overload; + procedure resetunitsearched; //resets all allreadysearchedflags of rootdeflists + + function updateunitinterface(const aunitname: string): punitinfoty; + function updatemodule(const amodule: tmsecomponent): punitinfoty; + function updateformunit(const aformfilename: filenamety; + const interfaceonly: boolean): punitinfoty; + function updatesourceunit(const asourcefilename: filenamety; + out filenum: integer; const interfaceonly: boolean): punitinfoty; + + function gettext(const infopo: punitinfoty; + const startpos,endpos: sourceposty): msestring; + procedure replacetext(const infopo: punitinfoty; + const startpos,endpos: sourceposty; const newtext: msestring); + + function getmatchingmethods(const amodule: tmsecomponent; + const atype: ptypeinfo): msestringarty; + function parsemodule(const amodule: tmsecomponent): pclassinfoty; + function findunitfile(const aunitname: msestring): msestring; + function findmethodpos(const amethod: tmethod; const imp: boolean = false): sourceposty; + function findcfunctionimplementation(const aname: ansistring; + out headerstart,headerstop: sourceposty): boolean; + //true if found + + function composeproceduretext(const infopo: pprocedureinfoty; + const withdefault: boolean): string; overload; + function composeprocedureheader(const infopo: pprocedureinfoty; + const withdefault: boolean): string; overload; + function gettype(const adef: pdefinfoty): stringarty; + function finddef(const infopo: punitinfoty; + const apos: sourceposty): pdefinfoty; overload; + function finddef(const infopo: punitinfoty; + const typename: string): pdefinfoty; overload; + function getitemtext(const aitem: sourceitemty): string; + function getdefinfotext(const adef: pdefinfoty): string; + property maxlinelength: integer read fmaxlinelength + write fmaxlinelength default 80; + end; + +var + sourceupdater: tsourceupdater; + +procedure init(const adesigner: tdesigner); +procedure deinit(const adesigner: tdesigner); + +procedure sourcechanged(const filename: filenamety); +function switchheaderimplementation(const filename: filenamety; + var astart,astop: sourceposty; + out isimplementation: boolean): boolean; +function findlinkdest(const edit: tsyntaxedit; var apos: sourceposty; + out definition: msestring): boolean; + //true if dest found +function listprocheaders(const filename: filenamety; + var apos: sourceposty): procedureinfoarty; +function listsourceitems(const filename: filenamety; + var apos: sourceposty; out scopes: deflistarty; + out defs: definfopoarty; + const maxcount: integer = 100): boolean; + //true if found +function completeclass(const filename: filenamety; var pos: sourceposty): boolean; + //true if source changed +function getimplementationtext(const amodule: tmsecomponent; out aunit: punitinfoty; + out start,stop: sourceposty; out adest: msestring): boolean; + //false if not found +implementation +uses + sysutils,msesys,msefileutils,sourceform,sourcepage,projectoptionsform, + msegui,msearrayutils,projecttreeform; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +function findprogramlanguage(const afilename: filenamety): proglangty; +var + mstr1: msestring; +begin + mstr1:= mseuppercase(fileext(afilename)); + if (mstr1 = 'C') or (mstr1 = 'H') then begin + result:= pl_c; + end + else begin + result:= pl_pascal; + end; +end; + +function limitlinelength(const atext: msestring; const maxlength: integer; + const breakchars: msestring; const indent: integer; + const startoffset: integer = 0): msestring; +var + ar1: msestringarty; + mstr1: msestring; + int1: integer; + po1,po2: pmsechar; + linelength: integer; + bo1: boolean; +begin + result:= ''; + if atext <> '' then begin + ar1:= breaklines(atext); + mstr1:= concatstrings(ar1,' '); + ar1:= nil; + po1:= pmsechar(mstr1); + po2:= po1; + bo1:= false; + while po2^ <> #0 do begin + if bo1 and (findchar(breakchars,po2^) <> 0) then begin + inc(po2); + additem(ar1,stringsegment(po1,po2)); + po1:= po2; + end + else begin + bo1:= true; + inc(po2); + end; + end; + additem(ar1,stringsegment(po1,po2)); + result:= ar1[0]; + linelength:= length(result) + startoffset; + for int1:= 1 to high(ar1) do begin + if (ar1[int1] <> '') and + (length(ar1[int1]) + linelength > maxlength) then begin + result:= result + lineend + charstring(msechar(' '),indent) + ar1[int1]; + linelength:= indent + length(ar1[int1]); + end + else begin + result:= result + ar1[int1]; + linelength:= linelength + length(ar1[int1]); + end; + end; + end; +end; + +procedure init(const adesigner: tdesigner); +begin + sourceupdater:= tsourceupdater.Create(adesigner); + sourceupdater.maxlinelength:= projectoptions.e.rightmarginchars; +end; + +procedure deinit(const adesigner: tdesigner); +begin + freeandnil(sourceupdater); +end; + +procedure sourcechanged(const filename: filenamety); +begin + if sourceupdater <> nil then begin + sourceupdater.sourcechanged(filename); + end; +end; + +function switchheaderimplementation(const filename: filenamety; + var astart,astop: sourceposty; out isimplementation: boolean): boolean; +var + po1: punitinfoty; +begin + with sourceupdater do begin + po1:= updatesourceunit(filename,astart.filenum,false); + if updateline(po1,astart) then begin + result:= switchheaderimplementation(po1,astart,astop,isimplementation); + end + else begin + result:= false; + end; + end; +end; + +function completeclass(const filename: filenamety; var pos: sourceposty): boolean; +var + po1: punitinfoty; +begin + with sourceupdater do begin + po1:= updatesourceunit(filename,pos.filenum,false); + if updateline(po1,pos) then begin + result:= completeclass(po1,pos); + end + else begin + result:= false; + end; + end; +end; + +function getimplementationtext(const amodule: tmsecomponent; + out aunit: punitinfoty; + out start,stop: sourceposty; out adest: msestring): boolean; + //false if not found +begin + result:= false; + with sourceupdater do begin + aunit:= updatemodule(amodule); + if aunit <> nil then begin + with aunit^ do begin + start:= p.implementationbodystart; + if isemptysourcepos(start) then begin + start:= p.implementationstart; + end; + stop:= p.implementationend; + if not isemptysourcepos(start) then begin + adest:= msestring(gettext(aunit,start,stop)); + result:= true; + end; + end; + end; + end; +end; + +function findlinkdest(const edit: tsyntaxedit; var apos: sourceposty; + out definition: msestring): boolean; +var + po1: punitinfoty; + po2: psourceitemty; + str1: msestring; +// coord1: gridcoordty; + po3: pdefinfoty; + int1: integer; + +begin + result:= false; + definition:= ''; + with sourceupdater do begin + application.beginwait; + try + if not application.waitcanceled then begin + po1:= updatesourceunit(edit.filename,apos.filenum,false); + if updateline(po1,apos) then begin + po2:= findsourceitem(po1,apos); + if po2 <> nil then begin + case po2^.kind of + sik_uses: begin + {coord1:= } + edit.wordatpos(apos.pos,str1,defaultdelimchars + ',;{}/',[]); + if str1 <> '' then begin + definition:= str1; + str1:= findunitfile(str1); + if str1 <> '' then begin + result:= true; + apos.filename:= designer.designfiles.add(str1); + apos.pos.col:= 0; + apos.pos.row:= 0; + end; + end; + end; + sik_include: begin + apos.filename:= + designer.designfiles.find(po1^.includestatements[po2^.index].filename); + definition:= designer.designfiles.getname(apos.filename); + apos.pos.col:= 0; + apos.pos.row:= 0; + result:= true; + end; + end; + end + else begin + po3:= finddef(po1,apos); + if po3 <> nil then begin + if po3^.deflist <> nil then begin + definition:= msestring(po3^.deflist.rootnamepath); + end + else begin + definition:= msestring(po3^.owner.rootnamepath+'.'+ + uppercase(po3^.name)); + end; + if po3^.kind in [syk_procdef,syk_procimp] then begin + int1:= findchar(definition,'$'); + if int1> 0 then begin + setlength(definition,int1-1); + end; + end; + apos.filename:= po3^.pos.filename; + apos.pos:= po3^.pos.pos; + result:= true; + end; + end; + end; + end; + finally + application.endwait; + end; + end; +end; + +function listprocheaders(const filename: filenamety; + var apos: sourceposty): procedureinfoarty; +var + po1: punitinfoty; + ar1: procedureinfopoarty; + int1: integer; +begin + ar1:= nil; //compiler warning + with sourceupdater do begin + po1:= updatesourceunit(filename,apos.filenum,false); + if updateline(po1,apos,filename) then begin + ar1:= listprocheaders(po1,apos); + setlength(result,length(ar1)); + for int1:= 0 to high(ar1) do begin + result[int1]:= ar1[int1]^; + end; + end + else begin + result:= nil; + end; + end; +end; + +function listsourceitems(const filename: filenamety; + var apos: sourceposty; out scopes: deflistarty; + out defs: definfopoarty; const maxcount: integer = 100): boolean; +var + po1: punitinfoty; +begin + with sourceupdater do begin + po1:= updatesourceunit(filename,apos.filenum,false); + if updateline(po1,apos,filename) then begin + result:= listsourceitems(po1,apos,scopes,defs,maxcount); + end + else begin + result:= false; + scopes:= nil; + defs:= nil; + end; + end; +end; + +{ tfilenameinfo } + +procedure tfilenameinfo.addunitinfo(ainfo: punitinfoty); +var + int1: integer; +begin + for int1:= 0 to high(funits) do begin + if funits[int1] = ainfo then begin + exit; + end; + end; + setlength(funits,high(funits) + 2); + funits[high(funits)]:= ainfo; +end; + +{ tfilenamelist } + +procedure tfilenamelist.add(const key: filenamety; info: punitinfoty); +var + adata: tfilenameinfo; +begin + adata:= find(key); + if adata = nil then begin + adata:= tfilenameinfo.Create; + if filesystemiscaseinsensitive then begin + inherited add(mseuppercase(key),adata); + end + else begin + inherited add(key,adata); + end; + end; + adata.addunitinfo(info); +end; + +function tfilenamelist.find(const key: filenamety): tfilenameinfo; +begin + if filesystemiscaseinsensitive then begin + result:= tfilenameinfo(inherited find(mseuppercase(key))); + end + else begin + result:= tfilenameinfo(inherited find(key)); + end; +end; + +procedure tfilenamelist.sourcefilemodified(key: filenamety); +var + int1: integer; + ainfo: tfilenameinfo; +begin + ainfo:= find(key); + if ainfo <> nil then begin + for int1:= 0 to high(ainfo.funits) do begin + with ainfo.funits[int1]^ do begin + if interfacecompiled then begin + interfacecompiled:= false; + if (proglang = pl_c) and (deflist <> nil) then begin + deflist.clear; //remove entries in cglobals; + projecttree.cmodules.modulechanged(key); + end; + end; + end; + end; + end; +end; + +{ tunitinfolist } + +constructor tunitinfolist.create; +begin +// fnamelist:= thashedstrings.create; + fnamelist:= tpointeransistringhashdatalist.create; + inherited create(true); +end; + +destructor tunitinfolist.destroy; +begin + inherited; + fnamelist.Free; +end; + +procedure tunitinfolist.clear; +begin + beginfinalizecglobals; + try + inherited; + fnamelist.clear; + finally + finalizecglobals; + end; +end; + +function tunitinfolist.datapo: punitinfoaty; +begin + result:= punitinfoaty(inherited datapo); +end; + +function tunitinfolist.newitem(const lang: proglangty): punitinfoty; +var + aitem: tunitinfo; +begin + case lang of + pl_pascal: begin + aitem:= tpascalunitinfo.create; + end; + pl_c: begin + aitem:= tcunitinfo.create; + end; + else begin + aitem:= tunitinfo.create; + end; + end; + add(aitem); + result:= aitem.infopo; +end; + +function tunitinfolist.getitempo(const index: integer): punitinfoty; +begin + result:= @tunitinfo(items[index]).info; +end; + +function tunitinfolist.finditembyformfilename(const afilename: filenamety): punitinfoty; +var + po1: punitinfoaty; + int1: integer; +begin + result:= nil; + po1:= datapo; + for int1:= 0 to fcount - 1 do begin + if issamefilename(afilename,po1^[int1].info.formfilename) then begin + result:= po1^[int1].infopo; + break; + end; + end; +end; + +function tunitinfolist.finditembysourcefilename(const afilename: filenamety; + var filenum: integer): punitinfoty; +var + po1: punitinfoaty; + int1,int2: integer; +begin + result:= nil; + po1:= datapo; + filenum:= 0; + for int1:= 0 to fcount - 1 do begin //check includefiles first + for int2:= 1 to high(po1^[int1].info.sourcefiles) do begin + if issamefilename(afilename,po1^[int1].info.sourcefiles[int2].filename) then begin + filenum:= int2 + 1; + result:= po1^[int1].infopo; + break; + end; + end; + if result <> nil then begin + exit; + end; + end; + po1:= datapo; + for int1:= 0 to fcount - 1 do begin + if issamefilename(afilename,po1^[int1].info.sourcefilename) then begin + filenum:= 1; + result:= po1^[int1].infopo; + break; + end; + end; +end; + +function tunitinfolist.finditembyunitname(const aname: string): punitinfoty; +begin + result:= fnamelist.find(struppercase(aname)); +end; + +{ tsourceupdater } + +procedure tsourceupdater.sourcechanged(const filename: filenamety); +begin + ffilenamelist.sourcefilemodified(filename); +end; + +function tsourceupdater.createscratchfile(const origname: filenamety): ttextstream; +begin + result:= ttextstream.create(origname + '.$$$',fm_create); +end; + +function tsourceupdater.gettext(const infopo: punitinfoty; + const startpos,endpos: sourceposty): msestring; +begin + result:= sourcefo.getfiletext(infopo^.sourcefilename,startpos.pos,endpos.pos); +end; + +procedure tsourceupdater.replacetext(const infopo: punitinfoty; + const startpos, endpos: sourceposty; const newtext: msestring); +begin + sourcefo.replacefiletext(infopo^.sourcefilename,startpos.pos,endpos.pos,newtext); +end; + +function tsourceupdater.updateline(module: punitinfoty; + var apos: sourceposty): boolean; +var + int1,int2: integer; + aincludefiles: integer; +begin + if apos.filenum > 0 then begin + result:= true; + apos.line:= apos.pos.row; + int2:= apos.filenum - 1; + with module^.sourcefiles[int2] do begin + inc(apos.line,startline); + aincludefiles:= includecount; + end; + for int1:= int2 + 1 to high(module^.sourcefiles) do begin + with module^.sourcefiles[int1] do begin + dec(aincludefiles); + if aincludefiles < 0 then begin + break; + end; + if apos.line <= startline then begin + break; + end; + inc(aincludefiles,includecount); + inc(apos.line,count); + end; + end; + end + else begin + result:= false; + end; +end; + +function tsourceupdater.updateline(module: punitinfoty; var apos: sourceposty; + const afilename: filenamety): boolean; +begin + apos.filename:= designer.designfiles.find(afilename); + result:= (apos.filename >= 0) and updateline(module,apos); +end; + +procedure tsourceupdater.checkitemlist(const infopo: punitinfoty); +var + int1: integer; +begin + with infopo^ do begin + if itemlist = nil then begin + itemlist:= tsourceitemlist.create; + for int1:= 0 to high(includestatements) do begin + with includestatements[int1] do begin + with itemlist.newitem(startpos,endpos,sik_include)^ do begin + index:= int1; + end; + end; + end; + case proglang of + pl_c: begin + end; + else begin + p.interfaceuses.getsourceitems(itemlist); + p.implementationuses.getsourceitems(itemlist); + end; + end; + end; + end; +end; + +function tsourceupdater.findsourceitem(const infopo: punitinfoty; + const apos: sourceposty): psourceitemty; +begin + checkitemlist(infopo); + result:= infopo^.itemlist.find(apos); +end; + +function tsourceupdater.findsourceitem(const infopo: punitinfoty; const apos: sourceposty; + out aindex: integer): psourceitemty; +begin + checkitemlist(infopo); + result:= infopo^.itemlist.find(apos,aindex); +end; + +function tsourceupdater.findsourceitem1(const infopo: punitinfoty; const apos: sourceposty; + out scope: tdeflist): pdefinfoty; +begin + with infopo^.deflist do begin + result:= finditem(apos,false,scope); + end; +end; + +function tsourceupdater.getitemtext(const aitem: sourceitemty): string; +var + infile: ttextstream; + int1: integer; +begin + infile:= sourcefo.gettextstream(designer.designfiles.getname(aitem.filename),false); + if infile <> nil then begin + try + infile.position:= aitem.startoffset; + int1:= aitem.endoffset - aitem.startoffset; + setlength(result,int1); + infile.ReadBuffer(result[1],int1); + finally + infile.Free; + end; + end + else begin + result:= ''; + end; +end; + +function tsourceupdater.getdefinfotext(const adef: pdefinfoty): string; +var + item1: sourceitemty; +begin + if adef^.kind in [syk_typedef,syk_vardef,syk_pardef,syk_classdef, + syk_procdef,syk_procimp, + syk_classprocimp,syk_interfacedef] then begin + item1.filename:= adef^.pos.filename; + item1.startoffset:= adef^.pos.offset; + item1.endoffset:= adef^.stop1.offset; + result:= getitemtext(item1); + end + else begin + result:= ''; + end; +end; + +function tsourceupdater.getidentpath(const infopo: punitinfoty; + const apos: sourceposty; const firstidentuse: boolean; + out scope: tdeflist): stringarty; + + procedure getidents(apo: pdefinfoty; const infile: ttextstream); + var + int1,int2,int3: integer; + begin + if infile <> nil then begin + try + int2:= 0; + if (apo <> nil) and (apo^.kind = syk_identuse) then begin + while (apo^.kind = syk_identuse) and + not (if_first in apo^.identflags) do begin + inc(int2); + dec(apo); + end; + setlength(result,int2+1); + for int1:= 0 to int2 do begin + infile.position:= apo^.pos.offset; + int3:= apo^.identlen; + if not((int1 = int2) and (apos.pos.col <= apo^.pos.pos.col) or + (apos.pos.row < apo^.pos.pos.row)) then begin + setlength(result[int1],int3); + infile.ReadBuffer(result[int1][1],int3); + //else '' + end; + inc(apo); + end; + end; + finally + infile.destroy; + end; + end; + end; + +var + po1: pdefinfoty; + pos1: sourceposty; + str1: string; + list1,list2: tdeflist; + +begin + result:= nil; + po1:= infopo^.deflist.finditem(apos,firstidentuse,scope); + if (po1 <> nil) then begin + case po1^.kind of + syk_identuse: begin + getidents(po1,sourcefo.gettextstream(designer.designfiles.getname( + po1^.pos.filename),false)); + end; + syk_typedef,syk_vardef,syk_pardef,syk_classdef,syk_procdef,syk_classprocimp, + syk_procimp,syk_interfacedef: begin + list1:= nil; + try + case infopo^.proglang of + pl_c: begin + parsecdef(po1,str1,list1); + end + else begin + parsepascaldef(po1,str1,list1); + end; + end; + pos1.line:= apos.line - po1^.pos.line; + if pos1.line = 0 then begin + pos1.pos.col:= apos.pos.col - po1^.pos.pos.col; + end + else begin + pos1.pos.col:= apos.pos.col; + end; + getidents(list1.finditem(pos1,false,list2),ttextstream.createdata(str1)); + finally + list1.Free; + end; + end; + end; + end; +end; + +function tsourceupdater.finddef(const infopo: punitinfoty; + const apos: sourceposty): pdefinfoty; +var + ar1: stringarty; + scope: tdeflist; + scopes: deflistarty; + defs: definfopoarty; +begin + application.beginwait; + try + result:= nil; + resetunitsearched; + ar1:= getidentpath(infopo,apos,false,scope); + if scope.finddef(ar1,scopes,defs,true,dsl_normal,syk_nopars) then begin + result:= defs[0]; + end; + finally + application.endwait; + end; +end; + +function tsourceupdater.finddef(const infopo: punitinfoty; + const typename: string): pdefinfoty; +var + ar1: stringarty; + scope: tdeflist; + scopes: deflistarty; + defs: definfopoarty; +begin + result:= nil; + resetunitsearched; + ar1:= splitstring(typename,'.'); + scope:= infopo^.deflist; + if scope.finddef(ar1,scopes,defs,true,dsl_normal,syk_nopars) then begin + result:= defs[0]; + end; +end; + +function tsourceupdater.listprocheaders(const infopo: punitinfoty; + const apos: sourceposty): procedureinfopoarty; +var + ar1: stringarty; + int1: integer; + scopes: deflistarty; + defs: definfopoarty; + scope1: tdeflist; + +begin + application.beginwait; + try + result:= nil; + resetunitsearched; + ar1:= getidentpath(infopo,apos,true,scope1); + if scope1.finddef(ar1,scopes,defs,false,dsl_normal,syk_nopars) then begin + for int1:= 0 to high(defs) do begin + if defs[int1]^.kind in [syk_procdef,syk_procimp] then begin + case scopes[int1].kind of + syk_classdef: begin + setlength(result,high(result) + 2); + result[high(result)]:= scopes[int1].rootlist.unitinfopo^. + p.classinfolist[scopes[int1].definfopo^.classindex]^. + procedurelist[defs[int1]^.procindex]; + end; + syk_root: begin + setlength(result,high(result) + 2); + result[high(result)]:= trootdeflist(scopes[int1]).rootlist.unitinfopo^. + p.procedurelist[defs[int1]^.procindex]; + end; + end; + end; + end; + end; + removearrayduplicates(pointerarty(result)); + finally + application.endwait; + end; +end; + +function tsourceupdater.listsourceitems(const infopo: punitinfoty; + const apos: sourceposty; out scopes: deflistarty; + out defs: definfopoarty; const maxcount: integer = 100): boolean; +var + ar1: stringarty; + scope1: tdeflist; +// ar2,ar4: deflistarty; +// ar3,ar5: definfopoarty; + int1,int2: integer; + +begin + application.beginwait; + try + resetunitsearched; + ar1:= getidentpath(infopo,apos,false,scope1); + result:= scope1.finddef(ar1,scopes,defs,false,dsl_normal,syk_substr,maxcount); + for int1:= 0 to high(defs) do begin //remove duplicates + if defs[int1] <> nil then begin + for int2:= int1 + 1 to high(defs) do begin + if defs[int2] = defs[int1] then begin + defs[int2]:= nil + end; + end; + end; + end; + int2:= 0; + for int1:= 0 to high(defs) do begin + if defs[int1] <> nil then begin + defs[int2]:= defs[int1]; + scopes[int2]:= scopes[int1]; + inc(int2); + end; + end; + setlength(defs,int2); + setlength(scopes,int2); + finally + application.endwait; + end; +end; + +function tsourceupdater.findunitfile(const aunitname: msestring): msestring; + + function dofind(const aname: filenamety): filenamety; + var + apage: tsourcepage; + begin + apage:= sourcefo.findsourcepage(aname,false); + if apage <> nil then begin + result:= apage.filepath; + end + else begin + result:= ''; + findfile(aname,projectoptions.d.texp.sourcedirs,result); + end; + end; + + function dofind1(const aunitname: filenamety): filenamety; + var + str1: msestring; + begin + result:= dofind(aunitname); + if result = '' then begin + str1:= mselowercase(aunitname); + if str1 <> aunitname then begin + result:= dofind(str1); + end; + if result = '' then begin + str1:= mseuppercase(aunitname); + if str1 <> aunitname then begin + result:= dofind(str1); + end; + end; + end; + end; + +begin + result:= dofind1(aunitname+'.pas'); + if result <> '' then exit; + result:= dofind1(aunitname+'.pp'); + if result <> '' then exit; + result:= dofind1(aunitname+'.mla'); +end; + +function tsourceupdater.findmethodpos(const amethod: tmethod; + const imp: boolean = false): sourceposty; +var + moduleinfo: pmoduleinfoty; + methodinfo: pmethodinfoty; +// unitinfo: punitinfoty; +// classinfo1: pclassinfoty; + procedureinfo: pprocedureinfoty; + ar1: classinfopoarty; + int1: integer; +begin + result:= emptysourcepos; + if amethod.data <> nil then begin + designer.getmethodinfo(amethod,moduleinfo,methodinfo); + if moduleinfo <> nil then begin + ar1:= designer.getancestorclassinfo(moduleinfo^.instance,false); + procedureinfo:= nil; + for int1:= high(ar1) downto 0 do begin + procedureinfo:= ar1[int1]^.procedurelist.finditembyname(methodinfo^.name); + if procedureinfo <> nil then begin + break; + end; + end; +// unitinfo:= updateformunit(moduleinfo^.filename,false); +// if unitinfo <> nil then begin +// classinfo1:= unitinfo^.p.classinfolist.finditembyname( +// moduleinfo^.moduleclassname,true); +// if classinfo1 <> nil then begin +// procedureinfo:= classinfo1^.procedurelist.finditembyname(methodinfo^.name); + if procedureinfo <> nil then begin + with procedureinfo^do begin + if imp and (impheaderendpos.filenum > 0) then begin + result:= impheaderendpos; + end + else begin + if intendpos.filenum > 0 then begin + result:= intendpos; + end + else begin + result:= impheaderendpos; + end; + end; + end; + end; +// end; +// end; + end; + end; +end; + +function tsourceupdater.switchheaderimplementation(const infopo: punitinfoty; + var headerstart,headerstop: sourceposty; + out isimplementation: boolean): boolean; +var + po1,po2: pdefinfoty; + scope: tdeflist; + str1: string; + ar1: stringarty; + bo1: boolean; + scopes: deflistarty; + defs: definfopoarty; + +begin + result:= false; + ar1:= nil; //compiler warning + isimplementation:= false; + with infopo^ do begin + po1:= deflist.finditem(headerstart,false,scope); + if po1 <> nil then begin + po2:= nil; + if po1^.kind = syk_procdef then begin + isimplementation:= true; + if scope.kind = syk_classdef then begin + str1:= scope.name + '.'+ po1^.name; //as direct procparameter delphi bug + po2:= scope.parent.find(str1,syk_classprocimp); + end + else begin + po2:= scope.find(po1^.name,syk_procimp); + if (po2 = nil) and (infopo^.proglang = pl_c) then begin + result:= findcfunctionimplementation(po1^.name,headerstart, + headerstop); + end; + end; + end + else begin + while (scope <> nil) and + not (scope.kind in [syk_root,syk_classdef]) do begin + po1:= scope.definfopo; + scope:= scope.parentscope; + end; + if scope <> nil then begin + ar1:= splitstring(po1^.name,'.'); + if scope.kind = syk_classdef then begin + bo1:= scope.finddef(copy(ar1,high(ar1),1),scopes,defs,true,dsl_normal); + end + else begin + bo1:= scope.finddef(ar1,scopes,defs,true,dsl_normal,syk_procdef); + end; + if bo1 then begin + po2:= defs[0]; + end; + end; + end; + if po2 <> nil then begin + headerstart:= po2^.pos; + headerstop:= po2^.stop1; + result:= true; + end; + end; + end; + if (headerstart.filenum = 0) or (headerstop.filenum = 0) then begin + result:= false; + end; +end; + +type + propinfoty = record + indextext: string; + typetext: stringarty; + getter: string; + setter: string; + end; + propinfoarty = array of propinfoty; + +function tsourceupdater.composeproceduretext(const name: string; + const info: methodparaminfoty; const withdefault: boolean): string; + +var + int1,int2: integer; +begin + result:= name; + with info do begin + int2:= high(params); + if kind in [mk_function,mk_procedurefunc,mk_methodfunc] then begin + dec(int2); + end; + if int2 >= 0 then begin + result:= result + '('; + for int1:= 0 to int2 do begin + with params[int1] do begin //todo: merge equal types + if pfconst in flags then begin + result:= result + 'const '; + end + else begin + if pfvar in flags then begin + result:= result + 'var '; + end + else begin + if pfout in flags then begin + result:= result + 'out '; + end; + end; + end; + result:= result + name; + if typename <> '' then begin + result:= result + ': '; + if pfarray in flags then begin + result:= result + 'array of '; + if typename = 'TVarRec' then begin + result:= result + 'const'; + end + else begin + result:= result + typename; + end; + end + else begin + result:= result + typename; + end; + if withdefault and (defaultvalue <> '') then begin + result:= result + ' = '+defaultvalue; + end; + end; + result:= result + '; '; + end; + end; + setlength(result,length(result)-1); //remove last space + result[length(result)]:= ')'; + end + else begin + if mef_brackets in flags then begin + result:= result + '()'; + end; + end; + if kind in [mk_function,mk_procedurefunc,mk_methodfunc] then begin + result:= result + ': ' + params[high(params)].typename; + end; + result:= result + ';'; + end; +end; + +function tsourceupdater.composeproceduretext(const infopo: pprocedureinfoty; + const withdefault: boolean): string; +begin + with infopo^ do begin + result:= composeproceduretext(name,params,withdefault); + end; +end; + +function tsourceupdater.composeprocedureheader(const infopo: pprocedureinfoty; + const withdefault: boolean): string; +begin + with infopo^ do begin + result:= composeprocedureheader(name,params,withdefault,classproc); + end; +end; + +procedure tsourceupdater.createmethodbody(const unitinfopo: punitinfoty; + const classinfopo: pclassinfoty; const aname: string; + const atype: ptypeinfo; beforeitem: integer); +var + str1: msestring; + pos1: sourceposty; + int1: integer; + bo1: boolean; +begin + pos1:= emptysourcepos; + bo1:= false; + if falphabeticprocorder then begin + with classinfopo^.procedurelist do begin + for int1:= beforeitem to count - 1 do begin + with items[int1]^ do begin + if not isemptysourcepos(impheaderstartpos) then begin + bo1:= true; + pos1:= impheaderstartpos; + break; + end; + end; + end; + end; + end; + if isemptysourcepos(pos1) then begin + pos1:= classinfopo^.procimpend; + if isemptysourcepos(pos1) then begin + pos1:= unitinfopo^.p.implementationend; + bo1:= true; + end; + end; + if pos1.filenum <> unitinfopo^.unitend.filenum then begin + pos1:= unitinfopo^.p.implementationend; + if pos1.filenum <> unitinfopo^.unitend.filenum then begin + pos1:= unitinfopo^.unitend; + end; + end; + if issamesourcepos(unitinfopo^.unitend,pos1) then begin + dec(pos1.line); //no 'end.' + dec(pos1.pos.row); + if pos1.pos.row < 0 then begin + exit; //invalid + end; + end; + if bo1 then begin + str1:= ''; + end + else begin + str1:= lineend; + end; + str1:= str1 + limitlinelength(msestring( + composeprocedureheader(classinfopo^.name+'.'+aname,atype,false,false)), + fmaxlinelength,procheaderbreakchars,14) + lineend; + str1:= str1 + 'begin' + lineend + 'end;' + lineend; + if bo1 then begin + str1:= str1 + lineend; + end; + replacetext(unitinfopo,pos1,pos1,str1); +end; + +function tsourceupdater.completeclass(const infopo: punitinfoty; + const pos: sourceposty): boolean; +var + ppo: pprocedureinfoty; + cpo: pclassinfoty; + scope: tdeflist; + int1: integer; + str1: msestring; + parser: tpascalparser; + po1: pchar; + ar1: propinfoarty; + + procedure insertprivate(const isfield: boolean; const atext: string); + var + int1: integer; + begin + completeclass:= true; + infopo^.interfacecompiled:= false; + int1:= length(breaklines(atext)); + with cpo^ do begin + if isfield then begin + replacetext(infopo,privatefieldend,privatefieldend, + msestring(' '+atext+lineend)); + inc(privatefieldend.pos.row,int1); + end + else begin + replacetext(infopo,privateend,privateend,msestring(' '+atext+lineend)); + end; + inc(privateend.pos.row,int1); + privateend.pos.col:= 0; + end; + end; + + procedure checkfield(const name: string; const propinfo: propinfoty); + var + scope1: tdeflist; + begin + if scope.finddef(name,syk_vardef,scope1) = nil then begin + insertprivate(true,name+': '+concatstrings(propinfo.typetext,'.')+';'); + end; + end; + + procedure checkproc(const issetter: boolean; const propinfo: propinfoty); + + function breakline(const atext: msestring): msestring; + begin + result:= limitlinelength(atext,fmaxlinelength,procheaderbreakchars,18); + end; + + var + scope1: tdeflist; + begin //checkproc + with propinfo do begin + if issetter then begin + if scope.finddef(setter,syk_nopars,scope1) = nil then begin + if indextext <> '' then begin + insertprivate(false,ansistring( + breakline('procedure '+msestring(setter+'('+ + indextext+'; const avalue: ')+ + msestring(concatstrings(typetext,'.')+');')))); + end + else begin + insertprivate(false,ansistring( + breakline('procedure '+msestring(setter)+'(const avalue: '+ + msestring(concatstrings(typetext,'.'))+');'))); + end; + end; + end + else begin + if scope.finddef(getter,syk_nopars,scope1) = nil then begin + if indextext <> '' then begin + insertprivate(false,ansistring( + breakline('function '+msestring(getter)+'('+msestring(indextext)+'): '+ + msestring(concatstrings(typetext,'.'))+';'))); + end + else begin + insertprivate(false,ansistring(breakline('function '+ + msestring(getter)+': '+ + msestring(concatstrings(typetext,'.'))))+';'); + end; + end; + end; + end; + end; + + procedure checklineinsert(const info: classinfoty; const startindex: int32; + const startline: int32; const linecount: int32); + var + po1,pe: pprocedureinfoty; + begin + po1:= info.procedurelist.datapo; + pe:= po1 + info.procedurelist.count; + while po1 < pe do begin + if po1^.impendpos.pos.row >= startindex then begin + inc(po1^.impendpos.pos.row,linecount); + end; + inc(po1); + end; + end; //checklineinsert + +var + po2: pdefinfoty; + atstart: boolean; + classindex1: integer; + str2: string; + i2: int32; + insertpos: sourceposty; + +begin //completeclass + result:= false; + with infopo^ do begin + cpo:= nil; + po2:= deflist.finditem(pos,false,scope); + if po2 <> nil then begin + if po2^.kind = syk_classdef then begin + scope:= po2^.deflist; + end; + if (scope <> nil) and (scope.kind = syk_classdef) then begin + classindex1:= scope.definfopo^.classindex; + cpo:= infopo^.p.classinfolist[classindex1]; + end + end; + if cpo <> nil then begin + with cpo^ do begin + ar1:= nil; + for int1:= 0 to high(scope.infos) do begin + with scope.infos[int1] do begin + if (kind = syk_vardef) and (vf_property in varflags) then begin + str2:= getdefinfotext(@scope.infos[int1]); + if str2 <> '' then begin + parser:= tpascalparser.create(designer.designfiles,str2); + try + with parser do begin + setlength(ar1,high(ar1)+2); + with ar1[high(ar1)] do begin + skipwhitespace; + nexttoken; //skip name + if checkoperator('[') then begin + po1:= token^.value.po; + if findoperator(']') then begin + indextext:= getlastorigtext(po1); + end; + end + else begin + indextext:= ''; + end; + if checkoperator(':') then begin + typetext:= getidentpath(parser); + getter:= ''; + setter:= ''; + if checkpropertyident(pid_read) then begin + getter:= getorigname; + if checkpropertyident(pid_write) then begin + setter:= getorigname; + end; + end + else begin + if checkpropertyident(pid_write) then begin + setter:= getorigname; + if checkpropertyident(pid_read) then begin + getter:= getorigname; + end; + end; + end; + end; + end; + end; + finally + parser.free; + end; + end; + end; + end; + end; + if ar1 <> nil then begin + if isemptysourcepos(privatestart) then begin + result:= true; + replacetext(infopo,managedend,managedend,' private'+lineend); + privatestart:= managedend; + inc(privatestart.pos.row); + privateend:= privatestart; + privateend.pos.col:= 0; + privatefieldend:= privateend; + end; + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + if getter <> '' then begin + if stringicomp(getter,setter) = 0 then begin + checkfield(getter,ar1[int1]); //fieldref + continue; + end + else begin + if startsstr('GET',struppercase(getter)) then begin + checkproc(false,ar1[int1]); + end + else begin + checkfield(getter,ar1[int1]); //fieldref + end; + end; + end; + if setter <> '' then begin + if startsstr('SET',struppercase(setter)) then begin + checkproc(true,ar1[int1]); + end + else begin + checkfield(setter,ar1[int1]); //fieldref + end; + end; + end; + end; + end; + if result then begin + updateunit(infopo,false); + end; + end; + cpo:= infopo^.p.classinfolist[classindex1]; + //cpo is invalid after updateunit + with cpo^ do begin + if isemptysourcepos(procimpstart) then begin + procimpstart:= infopo^.p.implementationend; + replacetext(infopo,procimpstart,procimpstart, + msestring('{ '+name+' }'+lineend+lineend)); + result:= true; + checklineinsert(cpo^,0,procimpstart.pos.row,2); + inc(procimpstart.pos.row,2); + procimpstart.pos.col:= 0; + procimpend:= procimpstart; + end; + insertpos:= procimpstart; + insertpos.pos.col:= 0; + atstart:= true; + for int1:= 0 to procedurelist.count - 1 do begin + ppo:= procedurelist[int1]; + with ppo^ do begin + if not (mef_abstract in params.flags) then begin + if isemptysourcepos(impheaderstartpos) then begin + if atstart then begin + str1:= ''; + end + else begin + str1:= lineend; + end; + str1:= str1 + + limitlinelength(msestring(composeprocedureheader(ppo,cpo,true)), + fmaxlinelength,procheaderbreakchars,14) + lineend + + 'begin'+lineend+ + 'end;'+lineend; + if atstart then begin + str1:= str1 + lineend; + end; + replacetext(infopo,insertpos,insertpos,str1); + result:= true; + i2:= high(breaklines(str1)); + checklineinsert(cpo^,insertpos.pos.row,int1,i2); + inc(insertpos.pos.row,i2); + end + else begin + insertpos.pos.row:= impendpos.pos.row; + atstart:= false; + end; + end; + end; + end; + end; + end; + end; +end; + +procedure tsourceupdater.methodcreated(const adesigner: idesigner; + const amodule: tmsecomponent; const aname: string; + const atype: ptypeinfo); + +var + po1: punitinfoty; + po2: pclassinfoty; + str1: string; + int1: integer; + pos1: sourceposty; + posindex: integer; + ar1: classinfopoarty; +begin + if atype^.Kind = tkmethod then begin + ar1:= designer.getancestorclassinfo(amodule,true); + if ar1 = nil then begin + exit; + end; + for int1:= high(ar1) downto 0 do begin + if ar1[int1]^.procedurelist.finditembyname(aname{,atype}) <> nil then begin + exit; + end; + end; + po2:= ar1[high(ar1)]; + po1:= updatemodule(amodule); +// po2:= findclassinfobyinstance(amodule,po1); +// if (po2 <> nil) and (po2^.procedurelist.finditembyname(aname{,atype}) = nil) then begin + pos1:= emptysourcepos; + str1:= uppercase(aname); + with po2^.procedurelist do begin + posindex:= count; + if falphabeticprocorder then begin + for int1:= 0 to count - 1 do begin + with items[int1]^ do begin + if uppername > str1 then begin + posindex:= int1; + pos1:= intinsertpos; + end; + break; + end; + end; + end; + end; + if isemptysourcepos(pos1) then begin + pos1:= po2^.managedend; + end; + if not isemptysourcepos(pos1) then begin + createmethodbody(po1,po2,aname,atype,posindex); + str1:= composeprocedureheader(aname,atype,false,false); + replacetext(po1,pos1,pos1, + limitlinelength(' ' + msestring(str1), + fmaxlinelength,procheaderbreakchars,18)+lineend); + end; + end; +//end; +end; + +procedure tsourceupdater.methodnamechanged(const adesigner: idesigner; + const amodule: tmsecomponent; const newname, oldname: string; + const atypeinfo: ptypeinfo); +var + po1: punitinfoty; + po2: pclassinfoty; + po3: pprocedureinfoty; + ar1: classinfopoarty; + ar2: unitinfopoarty; + int1: integer; +begin + ar1:= designer.getancestorclassinfo(amodule,false,ar2); + po1:= nil; + po2:= nil; + po3:= nil; + for int1:= high(ar1) downto 0 do begin + po1:= ar2[int1]; + if (po1 <> nil) and (ar1[int1] <> nil) then begin + po3:= ar1[int1]^.procedurelist.finditembyname(oldname); + if po3 <> nil then begin + po2:= ar1[int1]; + break; + end; + end; + end; +// po1:= updatemodule(amodule); +// po2:= findclassinfobyinstance(amodule,po1); +// if po2 <> nil then begin +// po3:= po2^.procedurelist.finditembyname(oldname{,atypeinfo}); + if po3 <> nil then begin + with po3^ do begin + name:= newname; + if not isemptysourcepos(impheaderstartpos) then begin + replacetext(po1,impheaderstartpos,impheaderendpos, + limitlinelength(msestring(composeprocedureheader(po3,po2,false)), + fmaxlinelength,procheaderbreakchars,14,impheaderstartpos.pos.col)); + end; + if not isemptysourcepos(intstartpos) then begin + replacetext(po1,intstartpos,intendpos, + limitlinelength(msestring(composeproceduretext(po3,false)),fmaxlinelength, + procheaderbreakchars,18,intstartpos.pos.col)); + end; + end; + end; +end; + +function tsourceupdater.getidentpath(const parser: tpascalparser): stringarty; +var + ident1: integer; +begin + result:= nil; + with parser do begin + ident1:= getident; + if (token^.kind = tk_name) and (ident1 < 0) then begin + additem(result,getorigname); + while checkoperator('.') do begin + if (token^.kind = tk_name) and (ident1 < 0) then begin + additem(result,getorigname); + end; + end; + end; + end; +end; + +function tsourceupdater.gettype(const adef: pdefinfoty): stringarty; +var + str1: string; + parser: tpascaldesignparser; + ident1: integer; + procinfo: procedureinfoty; +begin + result:= nil; + if adef^.kind in [syk_vardef,syk_procdef,syk_procimp] then begin + str1:= getdefinfotext(adef); + if str1 <> '' then begin + parser:= tpascaldesignparser.create(designer.designfiles,str1); + try + with parser do begin + ident1:= getident; + if adef^.kind = syk_vardef then begin + if (token^.kind = tk_name) and (ident1 < 0) then begin + nexttoken; + if checkoperator(':') then begin + result:= getidentpath(parser); + end; + end; + end + else begin + if ident1 = integer(pid_function) then begin + if parser.parseprocedureheader(pascalidentty(ident1),@procinfo) then begin + result:= splitidentpath( + procinfo.params.params[high(procinfo.params.params)].typename); + end; + end; + end; + end; + finally + parser.Free; + end; + end; + end; +end; + +function tsourceupdater.composeprocedureheader(const name: string; + const info: methodparaminfoty; const withdefault: boolean; + const classproc: boolean): string; +begin + result:= ''; + if classproc then begin + result:= 'class '; + end; + case info.kind of + mk_function: begin + result:= result + 'function '; + end; + mk_method,mk_methodfunc: begin + result:= result + 'method '; + end; + mk_constructor: begin + result:= result + 'constructor '; + end; + mk_destructor: begin + result:= result + 'destructor '; + end; + else begin + result:= result + 'procedure '; + end; + end; + result:= result + composeproceduretext(name,info,withdefault); +end; + +function tsourceupdater.composeprocedureheader(const infopo: pprocedureinfoty; + const classinfopo: pclassinfoty; const withdefault: boolean): string; +var + str1: string; +begin + with infopo^ do begin + if classinfopo <> nil then begin + str1:= classinfopo^.name + '.' + name; + end + else begin + str1:= name; + end; + result:= composeprocedureheader(str1,params,withdefault,infopo^.classproc); + end; +end; + +function tsourceupdater.composeprocedureheader(const name: string; + const typeinfo: ptypeinfo; + const withdefault: boolean; + const classproc: boolean): string; +var + info: methodparaminfoty; +begin + getmethodparaminfo(typeinfo,info); + result:= composeprocedureheader(name,info,withdefault,classproc); +end; + +constructor tsourceupdater.create(const adesigner: tdesigner); +begin + fmaxlinelength:= 80; + fdesigner:= adesigner; + designnotifications.registernotification(idesignnotification(self)); + funitinfolist:= tunitinfolist.create; + ffilenamelist:= tfilenamelist.create; + msedesignparser.updateunitinterface:= {$ifdef FPC}@{$endif}updateunitinterface; + msedesignparser.gettype:= {$ifdef FPC}@{$endif}gettype; + msedesignparser.resetunitsearched:= {$ifdef FPC}@{$endif}resetunitsearched; +end; + +destructor tsourceupdater.destroy; +begin + designnotifications.unregisternotification(idesignnotification(self)); + funitinfolist.free; + ffilenamelist.Free; + inherited; +end; + +procedure tsourceupdater.clear; +begin + funitinfolist.clear; + ffilenamelist.clear; +end; + +procedure tsourceupdater.unitchanged(const aunit: punitinfoty = nil); +var + int1: integer; +begin + if aunit <> nil then begin + aunit^.interfacecompiled:= false; + end + else begin + for int1:= 0 to funitinfolist.count - 1 do begin + funitinfolist[int1]^.interfacecompiled:= false; + end; + end; +end; + +procedure tsourceupdater.unitchanged(const asourcefilename: filenamety); +var + po1: punitinfoty; + int1: integer; +begin + po1:= funitinfolist.finditembysourcefilename(asourcefilename,int1); + if po1 <> nil then begin + unitchanged(po1); + end; +end; + +procedure tsourceupdater.resetunitsearched; + //resets all allreadysearchedflags of rootdeflists +var + int1: integer; +begin + for int1:= 0 to funitinfolist.count - 1 do begin + funitinfolist[int1]^.deflist.allreadysearched:= false; + end; +end; + +function tsourceupdater.getmatchingmethods(const amodule: tmsecomponent; + const atype: ptypeinfo): msestringarty; +var + po1: pclassinfoty; +begin + result:= nil; + po1:= parsemodule(amodule); + if po1 <> nil then begin + result:= po1^.procedurelist.matchedmethodnames(atype,true); + end; +end; + +procedure tsourceupdater.itemsmodified(const adesigner: idesigner; + const aitem: tobject); +begin + //dummy +end; + +procedure tsourceupdater.componentnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const aitem: tcomponent; + const newname: string); +var + po1: punitinfoty; + po2: pclassinfoty; + po3,po4: pcompinfoty; + str1: string; + int1: integer; +begin + try + po1:= updatemodule(amodule); + except + exit; //no source file, no sourcepdate + end; + po2:= findclassinfobyinstance(amodule,po1); + str1:= uppercase(aitem.Name); + if po2 <> nil then begin + with po2^.componentlist do begin + po3:= nil; + po4:= datapo; + for int1:= 0 to count - 1 do begin + if po4^.uppername = str1 then begin + po3:= po4; + break; + end; + inc(po4); + end; + if po3 <> nil then begin + replacetext(po1,po3^.namepos,po3^.nameend,msestring(newname)); + end; + end; + end; +end; + +procedure tsourceupdater.moduleclassnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); +begin +end; + +procedure tsourceupdater.instancevarnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); +begin +end; + +procedure tsourceupdater.iteminserted(const adesigner: idesigner; + const amodule: tmsecomponent; const aitem: tcomponent); +var + po1,po4: punitinfoty; + po2: pclassinfoty; + po3: pmoduleinfoty; + pos1: sourceposty; + str1,str2: msestring; + classna,unitna: string; + int1: integer; + ar1: msestringarty; + ar2: stringarty; + first: boolean; +begin + try + po1:= updatemodule(amodule); + except + exit; //no source file, no sourcepdate + end; + updateunit(po1,true); + po2:= findclassinfobyinstance(amodule,po1); + str1:= msestring(uppercase(aitem.Name)); + pos1:= emptysourcepos; + if po2 <> nil then begin + if (csinline in aitem.componentstate) and + designer.checksubmodule(aitem,po3) then begin + classna:= po3^.moduleclassname; + po4:= updatemodule(po3^.instance); + if po4 <> nil then begin + unitna:= po4^.origunitname; + end; + end + else begin + classna:= aitem.ClassName; + unitna:= gettypedata(ptypeinfo(aitem.classinfo))^.unitname; + end; + if isemptysourcepos(pos1) then begin + pos1:= po2^.procedurestart; + end; + if not isemptysourcepos(pos1) then begin + str1:= msestring(' ' + aitem.Name + ': ' + classna+';' + lineend); + replacetext(po1,pos1,pos1,str1); + end; + with po1^.p.interfaceuses do begin + if (unitna <> '') then begin + if (startpos.filenum = endpos.filenum) and + not isemptysourcepos(startpos) then begin + str2:= gettext(po1,startpos,endpos); + ar2:= unitgroups.getneededunits(unitna); + first:= count = 0; + for int1:= 0 to high(ar2) do begin + if (find(ar2[int1]) = nil) then begin + if not first then begin + str2:= str2 + ','; + end + else begin + first:= false; + end; + str2:= str2 + msestring(ar2[int1]); + end + end; + if str2 <> '' then begin + ar1:= breaklines(str2); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= trim(ar1[int1]); + end; + if ar1[0] = '' then begin + deleteitem(ar1,0); + end; + str2:= concatstrings(ar1,''); + str2:= lineend+' '+ + limitlinelength(str2,fmaxlinelength,',',1,1); + end; + replacetext(po1,startpos,endpos,str2); + end; + end; + end; + end; +end; + +procedure tsourceupdater.itemdeleted(const adesigner: idesigner; + const amodule: tmsecomponent; const aitem: tcomponent); +var + po1: punitinfoty; + po2: pclassinfoty; + po3: pcompinfoty; +begin + try + po1:= updatemodule(amodule); + except + exit; //no source file, no sourcepdate + end; + po2:= findclassinfobyinstance(amodule,po1); + if po2 <> nil then begin + po3:= po2^.componentlist.finditembyname(aitem.name); + if po3 <> nil then begin + with po3^ do begin + replacetext(po1,insertpos,endpos,''); + end; + end; + end; +end; + + +procedure tsourceupdater.showobjecttext(const adesigner: idesigner; + const afilename: filenamety; const backupcreated: boolean); +begin + //dummy +end; + +procedure tsourceupdater.closeobjecttext(const adesigner: idesigner; + const afilename: filenamety; var cancel: boolean); +begin + //dummy +end; + +procedure tsourceupdater.moduleactivated(const adesigner: idesigner; + const amodule: tmsecomponent); +begin + //dummy +end; + +procedure tsourceupdater.moduledeactivated(const adesigner: idesigner; + const amodule: tmsecomponent); +begin + //dummy +end; + +procedure tsourceupdater.moduledestroyed(const adesigner: idesigner; + const amodule: tmsecomponent); +begin + //dummy +end; + +function tsourceupdater.parsemodule(const amodule: tmsecomponent): pclassinfoty; +begin + result:= findclassinfobyinstance(amodule,updatemodule(amodule)); +end; + +procedure tsourceupdater.selectionchanged(const adesigner: idesigner; + const aselection: idesignerSelections); +begin + //dummy +end; + +procedure tsourceupdater.getincludefile(const sender: tparser; const scanner: tscanner); +var + infile: ttextstream; +begin + infile:= sourcefo.gettextstream(scanner.filename,false); + try + scanner.source:= infile.readdatastring; + finally + infile.Free; + end; +end; + +procedure tsourceupdater.updatepascalunit(const infopo: punitinfoty; + const interfaceonly: boolean); +var + scanner: tpascalscanner; + parser: tpascaldesignparser; + infile: ttextstream; + int1,int2,int3: integer; + ar1: stringarty; + ar3: msestringarty; +begin + ar3:= nil; //compiler warning + { + if not infopo^.interfacecompiled or + not infopo^.implementationcompiled and not interfaceonly then begin + if infopo^.unitname <> '' then begin + funitinfolist.fnamelist.delete(infopo^.unitname); + end; + } + scanner:= tpascalscanner.Create; + application.beginwait; + try + infile:= sourcefo.gettextstream(infopo^.sourcefilename,false); + scanner.setfilename(infopo^.sourcefilename,designer.designfiles); + try + scanner.source:= infile.readdatastring; + finally + infile.Free; + end; + parser:= tpascaldesignparser.create(infopo,designer.designfiles, + {$ifdef FPC}@{$endif}getincludefile,interfaceonly); + try + parser.includefiledirs:= projectoptions.d.texp.sourcedirs; + ar1:= nil; + int3:= 0; + for int1:= 0 to high(projectoptions.d.texp.defines) do begin + if int1 > high(projectoptions.d.defineson) then begin + break; + end; + if projectoptions.d.defineson[int1] then begin + ar3:= splitstring(projectoptions.d.texp.defines[int1],msechar(' ')); + for int2:= 0 to high(ar3) do begin + additem(ar1,string(ar3[int2]),int3); + end; + end; + end; + setlength(ar1,int3); + parser.startdefines:= ar1; + parser.scanner:= scanner; + { + if infopo^.unitname <> '' then begin + funitinfolist.fnamelist.add(infopo^.unitname,infopo); + end; + } + finally + parser.Free; + end; + finally + scanner.Free; + application.endwait; + end; +// end; +end; + +procedure tsourceupdater.updatecunit(const infopo: punitinfoty; + const interfaceonly: boolean); +var + scanner: tcscanner; + parser: tcdesignparser; + infile: ttextstream; + int1,int2,int3: integer; + ar1: stringarty; + ar3: msestringarty; +begin + ar3:= nil; //compiler warning + scanner:= tcscanner.Create; + application.beginwait; + try + infile:= sourcefo.gettextstream(infopo^.sourcefilename,false); + scanner.setfilename(infopo^.sourcefilename,designer.designfiles); + try + scanner.source:= infile.readdatastring; + finally + infile.Free; + end; + parser:= tcdesignparser.create(infopo,designer.designfiles, + {$ifdef FPC}@{$endif}getincludefile,interfaceonly); + try + parser.includefiledirs:= projectoptions.d.texp.sourcedirs; + ar1:= nil; + int3:= 0; + for int1:= 0 to high(projectoptions.d.texp.defines) do begin + if int1 > high(projectoptions.d.defineson) then begin + break; + end; + if projectoptions.d.defineson[int1] then begin + ar3:= splitstring(projectoptions.d.texp.defines[int1],msechar(' ')); + for int2:= 0 to high(ar3) do begin + additem(ar1,string(ar3[int2]),int3); + end; + end; + end; + setlength(ar1,int3); + parser.startdefines:= ar1; + parser.scanner:= scanner; + finally + parser.Free; + end; + finally + scanner.Free; + application.endwait; + end; +// end; +end; + +procedure tsourceupdater.updateunit(const infopo: punitinfoty; + const interfaceonly: boolean); +begin + if not infopo^.interfacecompiled or + not infopo^.implementationcompiled and not interfaceonly then begin + if infopo^.unitname <> '' then begin + funitinfolist.fnamelist.delete(ansistring(infopo^.unitname),true); + end; + case infopo^.proglang of + pl_c: begin + updatecunit(infopo,interfaceonly); + end + else begin + updatepascalunit(infopo,interfaceonly); + end; + end; + if infopo^.unitname <> '' then begin + funitinfolist.fnamelist.add(infopo^.unitname,infopo); + end; + end; +end; + +function tsourceupdater.updatemodule(const amodule: tmsecomponent): punitinfoty; +var + po1: pmoduleinfoty; +begin + result:= nil; + po1:= fdesigner.modules.findmodulebyinstance(amodule); + if po1 <> nil then begin + result:= updateformunit(po1^.filename,false); + end; +end; + +function tsourceupdater.updateformunit(const aformfilename: filenamety; + const interfaceonly: boolean): punitinfoty; +begin + result:= funitinfolist.finditembyformfilename(aformfilename); + if result = nil then begin + result:= funitinfolist.newitem(pl_pascal); + with result^ do begin + formfilename:= aformfilename; + sourcefilename:= replacefileext(aformfilename,'pas'); + end; + end; + updateunit(result,interfaceonly); + ffilenamelist.add(result^.sourcefilename,result); +end; + +procedure tsourceupdater.updateincludefilenum(module: punitinfoty; + const filename: filenamety; var filenum: integer); +var + int1: integer; +begin + filenum:= 0; + with module^ do begin + for int1:= 0 to high(sourcefiles) do begin + if issamefilename(filename,sourcefiles[int1].filename) then begin + filenum:= int1 + 1; + break; + end; + end; + end; +end; + +function tsourceupdater.updatesourceunit(const asourcefilename: filenamety; + out filenum: integer; const interfaceonly: boolean): punitinfoty; +begin + result:= funitinfolist.finditembysourcefilename(asourcefilename,filenum); + if result = nil then begin + result:= funitinfolist.newitem(findprogramlanguage(asourcefilename)); + with result^ do begin + formfilename:= replacefileext(asourcefilename,'mfm'); + sourcefilename:= asourcefilename; + end; + filenum:= 1; + end; + updateunit(result,interfaceonly); + ffilenamelist.add(asourcefilename,result); +end; + +function tsourceupdater.updateunitinterface(const aunitname: string): punitinfoty; +var + str1: filenamety; + int1: integer; +begin + result:= funitinfolist.finditembyunitname(aunitname); + if result <> nil then begin + updateunit(result,true); + end + else begin + str1:= findunitfile(msestring(aunitname)); + if str1 <> '' then begin + result:= updatesourceunit(str1,int1,true); + end + else begin + result:= nil; + end; + end; +end; + +procedure tsourceupdater.beforemake(const adesigner: idesigner; + const maketag: integer; var abort: boolean); +begin + //dummy +end; + +procedure tsourceupdater.aftermake(const adesigner: idesigner; + const exitcode: integer); +begin + //dummy +end; + +procedure tsourceupdater.beforefilesave(const adesigner: idesigner; + const afilename: filenamety); +begin + //dummy +end; + +function tsourceupdater.findcfunctionimplementation(const aname: ansistring; + out headerstart: sourceposty; + out headerstop: sourceposty): boolean; +var +// int1: integer; + po3: pfunctioninfoty; +// int2: integer; +// mstr1: filenamety; +begin + result:= false; + po3:= cglobals.findfunction(aname); + if po3 <> nil then begin + headerstart:= po3^.start; + headerstop:= po3^.stop; + result:= true; + end; +end; + +end. + diff --git a/mseide-msegui/apps/ide/stackform.mfm b/mseide-msegui/apps/ide/stackform.mfm new file mode 100644 index 0000000..944ed6f --- /dev/null +++ b/mseide-msegui/apps/ide/stackform.mfm @@ -0,0 +1,199 @@ +object stackfo: tstackfo + optionswidget = [ow_arrowfocus, ow_subfocus, ow_mousewheel, ow_destroywidgets, ow_hinton] + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_floatbutton, go_topbutton, go_backgroundbutton, go_nolockbutton, go_buttonhints] + popupmenu = tpopupmenu1 + visible = False + bounds_x = 407 + bounds_y = 349 + bounds_cx = 254 + bounds_cy = 180 + container.frame.framei_right = 0 + container.frame.localprops = [frl_firight] + container.frame.localprops1 = [] + container.onlayout = formonchildscaled + container.bounds = ( + 0 + 0 + 244 + 180 + ) + dragdock.splitter_size = 0 + dragdock.caption = 'Stack' + dragdock.optionsdock = [od_savepos, od_canmove, od_canfloat, od_candock, od_proportional, od_propsize, od_captionhint, od_childicons] + options = [fo_savepos, fo_savestate] + statfile = mainfo.projectstatfile + caption = 'Stack' + icon.transparentcolor = -2147483642 + icon.image = { + 0000000000000000180000001800000094080000000000000000000000000000 + 0000000000000000000000000000000000000000F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + 0000FF01EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + 0000FF02EDEDED01EBEBEB01EAEAEA01D6D6D601BDBDBD01C6C6C601C9C9C901 + B3B3B301B8B8B801D0D0D001BDBDBD0183838301ADADAD017E7E7E01C1C1C101 + D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F2010000FF03 + EBEBEB01EAEAEA01ACACAC0179797901A0A0A0019E9E9E019191910190909001 + A8A8A801C1C1C101959595017F7F7F0192929201D7D7D701D5D5D501D3D3D301 + D2D2D201D0D0D001F5F5F5010000FF06EAEAEA01BDBDBD01A1A1A101B6B6B601 + B7B7B701BFBFBF01A9A9A901BEBEBE01CFCFCF01B3B3B3019B9B9B01B4B4B401 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F5010000FF01F2F2F201 + 0000FF03EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501E3E3E301AFAFAF01 + DEDEDE01C4C4C401A9A9A901DBDBDB01DADADA01B4B4B401C9C9C901D5D5D501 + D3D3D301D2D2D201D0D0D001F5F5F5010000FF01F2F2F2010000FF02EDEDED01 + EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501E3E3E3017E7E7E019A9A9A01 + 8686860178787801959595019494940179797901CFCFCF01D5D5D501D3D3D301 + D2D2D201D0D0D001F5F5F5010000FF01F2F2F2010000FF01EEEEEE01EDEDED01 + EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501E3E3E3019B9B9B018B8B8B01 + 8F8F8F0198989801727272017070700194949401D7D7D701D5D5D501D3D3D301 + D2D2D201D0D0D001F5F5F5010000FF01F2F2F201F0F0F001EEEEEE01EDEDED01 + EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501E3E3E301E2E2E201E0E0E001 + DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801D7D7D701D5D5D501D3D3D301 + D2D2D201D0D0D001F5F5F5010000FF01F2F2F201F0F0F001EEEEEE01EDEDED01 + EBEBEB01EAEAEA01D6D6D601BDBDBD01C6C6C601C9C9C901BBBBBB01A0A0A001 + B0B0B001D3D3D301DBDBDB01DADADA01D8D8D8016B6BEB010000FF03D0D0D001 + F5F5F5010000FF01F2F2F201F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01 + ACACAC0179797901A0A0A0019E9E9E019B9B9B018E8E8E019090900192929201 + DBDBDB01DADADA01D8D8D801D7D7D701D5D5D501D3D3D3010000FF01D0D0D001 + F5F5F5010000FF01F2F2F201F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01 + BDBDBD01A1A1A101B6B6B601B7B7B701A7A7A701B1B1B101A1A1A101B8B8B801 + DBDBDB01DADADA01D8D8D801D7D7D701D5D5D501D3D3D3010000FF01D0D0D001 + F5F5F5010000FF01F2F2F201F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01 + E8E8E801E6E6E601E5E5E501E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01 + DBDBDB01DADADA01D8D8D801D7D7D701D5D5D501D3D3D3010000FF01D0D0D001 + F5F5F5010000FF01F2F2F201F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01 + E8E8E801E6E6E601E5E5E501E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01 + DBDBDB01DADADA01D8D8D801D7D7D701D5D5D501D3D3D3010000FF01D0D0D001 + F5F5F5010000FF01F2F2F201F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01 + E8E8E801E6E6E601E5E5E501E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01 + DBDBDB01DADADA01D8D8D801D7D7D701D5D5D501D3D3D3010000FF01D0D0D001 + F5F5F5010000FF01F2F2F201F0F0F001C5C5C5019C9C9C01B6B6B601E8E8E802 + E4E4E401E5E5E501E1E1E101E2E2E201DFDFDF01DEDEDE01C6C6C601DBDBDB01 + DADADA01D8D8D801D7D7D701D5D5D501D3D3D3010000FF01D0D0D001F5F5F501 + 0000FF01F2F2F201F0F0F001B2B2B2019B9B9B01B2B2B2015F5F5F01B1B1B101 + 5F5F5F019393930185858501E2E2E2018C8C8C017E7E7E0198989801DBDBDB01 + DADADA01D8D8D801D7D7D7010000FF01D3D3D3010000FF01D0D0D001F5F5F501 + 0000FF02F0F0F001C1C1C101DDDDDD01E7E7E7019D9D9D019898980197979701 + ADADAD0195959501E2E2E2019595950196969601A9A9A901DBDBDB01DADADA01 + D8D8D8010000FF02D3D3D3010000FF01D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01D2D2D201DBDBDB01DADADA010000FF03 + D3D3D3010000FF01D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001D9D9D901 + A4A4A401C1C1C101B0B0B001BABABA01B1B1B102B5B5B501A8A8A801B8B8B801 + 9D9D9D0199999901DBDBDB010000FF06D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001C1C1C1018B8B8B019A9A9A018F8F8F01A4A4A4017C7C7C019B9B9B01 + 80808001929292017A7A7A01A5A5A50196969601DBDBDB01DADADA010000FF03 + D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001E4E4E401 + BFBFBF01D4D4D401C2C2C201C7C7C701C5C5C501BEBEBE01C8C8C801B7B7B701 + CBCBCB01B9B9B901CECECE01DBDBDB01DADADA01D8D8D8010000FF02D3D3D301 + D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01EDEDED01 + EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501E3E3E301E2E2E201E0E0E001 + DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801D7D7D7010000FF01D3D3D301 + D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01EDEDED01 + EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501E3E3E301E2E2E201E0E0E001 + DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801D7D7D701D5D5D501D3D3D301 + D2D2D201D0D0D001 + } + onshow = stackfoonshow + onlayout = formonchildscaled + moduleclassname = 'tdockform' + object grid: tstringgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + color = -1879048187 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 2 + bounds_x = 0 + bounds_y = 20 + bounds_cx = 244 + bounds_cy = 160 + anchors = [an_top, an_bottom] + datacols.count = 5 + datacols.colorfocused = -1879048185 + datacols.options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savevalue, co_savestate, co_cancopy, co_mousescrollrow] + datacols.items = < + item + color = -2147483646 + colorfocused = -1879048185 + width = 31 + options = [co_readonly, co_nofocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy] + textflags = [tf_xcentered, tf_ycentered] + valuefalse = '0' + valuetrue = '1' + end + item + colorselect = -1879048185 + colorfocused = -1879048185 + width = 54 + options = [co_readonly, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_cancopy] + textflags = [tf_ycentered, tf_noselect, tf_ellipseright] + textflagsactive = [tf_ycentered, tf_ellipseright] + optionsedit = [scoe_eatreturn, scoe_homeonenter] + valuefalse = '0' + valuetrue = '1' + end + item + colorfocused = -1879048185 + options = [co_invisible, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy] + optionsedit = [scoe_eatreturn] + valuefalse = '0' + valuetrue = '1' + end + item + colorfocused = -1879048185 + options = [co_invisible, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy] + valuefalse = '0' + valuetrue = '1' + end + item + colorfocused = -1879048185 + options = [co_invisible, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy] + valuefalse = '0' + valuetrue = '1' + end> + datarowheight = 16 + oncellevent = gridoncellevent + reffontheight = 14 + end + object filedisp: tstringdisp + frame.localprops = [] + frame.localprops1 = [] + taborder = 1 + bounds_x = 71 + bounds_y = 0 + bounds_cx = 172 + bounds_cy = 18 + anchors = [an_left, an_top, an_right] + textflags = [tf_ycentered, tf_ellipseleft] + options = [dwo_hintclippedtext] + reffontheight = 14 + end + object address: tstringdisp + frame.localprops = [] + frame.localprops1 = [] + bounds_x = 1 + bounds_y = 0 + bounds_cx = 70 + bounds_cy = 18 + textflags = [tf_xcentered, tf_ycentered] + reffontheight = 14 + end + object tpopupmenu1: tpopupmenu + menu.submenu.count = 1 + menu.submenu.items = < + item + caption = 'Copy to Clipboard' + state = [as_localcaption, as_localonexecute] + onexecute = copytoclipboard + end> + menu.state = [as_localonexecute] + left = 48 + top = 56 + end +end diff --git a/mseide-msegui/apps/ide/stackform.pas b/mseide-msegui/apps/ide/stackform.pas new file mode 100644 index 0000000..b5895e2 --- /dev/null +++ b/mseide-msegui/apps/ide/stackform.pas @@ -0,0 +1,198 @@ +{ MSEide Copyright (c) 1999-2012 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit stackform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseforms,msegrids,msetypes,msegdbutils,msegui,msedispwidgets,msemenus, + mseguiintf,msegridsglob,msestrings; + +type + tstackfo = class(tdockform) + grid: tstringgrid; + filedisp: tstringdisp; + address: tstringdisp; + tpopupmenu1: tpopupmenu; + procedure stackfoonshow(const sender: tobject); + procedure gridoncellevent(const sender: tobject; var info: celleventinfoty); + procedure formonchildscaled(const sender: TObject); + procedure copytoclipboard(const sender: TObject); + private + frameinfo: frameinfoarty; + protected + procedure dispdetails; + public + gdb: tgdbmi; + procedure refresh; + procedure clear; + function showsource(const aframenr: integer): boolean; + function infotext(const aframenr: integer): msestring; + end; + +var + stackfo: tstackfo; + +implementation + +uses + sysutils,stackform_mfm,sourceform,msefileutils,mseformatstr,main,mseguiglob, + msegraphutils,projectoptionsform,msewidgets; + +{ tstackfo } + +function tstackfo.showsource(const aframenr: integer): boolean; +begin + result:= false; + if (aframenr >= 0) and (aframenr <= high(frameinfo)) then begin + grid.row:= aframenr; + with frameinfo[aframenr] do begin + if filename <> '' then begin + result:= sourcefo.showsourceline(sourcepath(filename),line-1,0,true) <> nil; + end; + end; + end; +end; + +function tstackfo.infotext(const aframenr: integer): msestring; +begin + if (aframenr >= 0) and (aframenr <= high(frameinfo)) then begin + with frameinfo[aframenr] do begin + result:= 'File: '+filename+':'+inttostrmse(line)+' '+'Function: '+ + msestring(func); + end; + end + else begin + result:= ''; + end; +end; + +procedure tstackfo.dispdetails; +begin +// if (grid.row < 0) and (grid.rowcount > 0) then begin +// grid.row:= 0; +// exit; +// end; + if grid.row >= 0 then begin + filedisp.value:= grid[2][grid.row]+':'+grid[3][grid.row]; + address.value:= grid[4][grid.row]; + end + else begin + filedisp.value:= ''; + address.value:= ''; + end; +end; + +procedure tstackfo.gridoncellevent(const sender: tobject; + var info: celleventinfoty); +var + rect1: rectty; +begin + with info do begin + case eventkind of + cek_focusedcellchanged: begin + dispdetails; + end; + cek_enter: begin + if (cellbefore.row >= 0) and (cellbefore.row <> newcell.row) then begin + mainfo.stackframechanged(newcell.row); + end; + end; + cek_firstmousepark: begin + if cell.col = 1 then begin + with tstringgrid(sender) do begin + if textclipped(cell,rect1) then begin + inc(rect1.cy,12); + application.showhint(twidget(sender),items[cell],rect1,cp_bottomleft,-1); + end; + end; + end; + end; + end; + if iscellclick(info,[ccr_dblclick]) then begin + showsource(cell.row); + end; + end; +end; + +procedure tstackfo.clear; +begin + grid.rowcount:= 0; + dispdetails; +end; + +procedure tstackfo.refresh; +var + int1,int2: integer; + str1: msestring; +begin + if visible and gdb.cancommand then begin + gdb.stacklistframes(frameinfo); + grid.beginupdate; + grid.row:= -1; + grid.rowcount:= length(frameinfo); + for int1:= 0 to high(frameinfo) do begin + with frameinfo[int1] do begin + grid[0][int1]:= inttostrmse(level); + str1:= msestring(func) + '('; + if high(params) >= 0 then begin + for int2:= 0 to high(params) do begin + str1:= str1 + msestring(params[int2].name) + '=' + + removelinebreaks(msestring(params[int2].value)) + ', '; + end; + setlength(str1,length(str1)-2); + end; + grid[1][int1]:= str1 + ')'; + grid[2][int1]:= filename; + grid[3][int1]:= inttostrmse(line); + grid[4][int1]:= hextostrmse(addr,8); + end; + end; + if grid.rowcount > 0 then begin + grid.row:= 0; + end; + grid.endupdate; + end; +end; + +procedure tstackfo.stackfoonshow(const sender: tobject); +begin + refresh; +end; + +procedure tstackfo.formonchildscaled(const sender: TObject); +begin + placeyorder(0,[0],[address,grid],0); + aligny(wam_center,[address,filedisp]); +end; + +procedure tstackfo.copytoclipboard(const sender: TObject); +var + mstr1: msestring; + int1: integer; +begin + mstr1:= ''; + for int1:= 0 to grid.rowhigh do begin + mstr1:= mstr1 + '#'+inttostrmse(int1)+' '+grid[4][int1]+' '+ + filename(grid[2][int1])+':'+ + grid[3][int1]+' '+grid[1][int1]+lineend; + end; + msewidgets.copytoclipboard(mstr1); +end; + +end. diff --git a/mseide-msegui/apps/ide/stackform_mfm.pas b/mseide-msegui/apps/ide/stackform_mfm.pas new file mode 100644 index 0000000..fdf63d8 --- /dev/null +++ b/mseide-msegui/apps/ide/stackform_mfm.pas @@ -0,0 +1,290 @@ +unit stackform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,stackform; + +const + objdata: record size: integer; data: array[0..5454] of byte end = + (size: 5455; data: ( + 84,80,70,48,8,116,115,116,97,99,107,102,111,7,115,116,97,99,107,102, + 111,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 97,114,114,111,119,102,111,99,117,115,11,111,119,95,115,117,98,102,111,99, + 117,115,13,111,119,95,109,111,117,115,101,119,104,101,101,108,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,9,111,119,95,104,105, + 110,116,111,110,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,15,102,114,97,109,101,46,103,114,105,112,95,115,105,122,101, + 2,10,18,102,114,97,109,101,46,103,114,105,112,95,111,112,116,105,111,110, + 115,11,14,103,111,95,99,108,111,115,101,98,117,116,116,111,110,16,103,111, + 95,102,105,120,115,105,122,101,98,117,116,116,111,110,14,103,111,95,102,108, + 111,97,116,98,117,116,116,111,110,12,103,111,95,116,111,112,98,117,116,116, + 111,110,19,103,111,95,98,97,99,107,103,114,111,117,110,100,98,117,116,116, + 111,110,15,103,111,95,110,111,108,111,99,107,98,117,116,116,111,110,14,103, + 111,95,98,117,116,116,111,110,104,105,110,116,115,0,9,112,111,112,117,112, + 109,101,110,117,7,11,116,112,111,112,117,112,109,101,110,117,49,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,151,1,8,98, + 111,117,110,100,115,95,121,3,93,1,9,98,111,117,110,100,115,95,99,120, + 3,254,0,9,98,111,117,110,100,115,95,99,121,3,180,0,28,99,111,110, + 116,97,105,110,101,114,46,102,114,97,109,101,46,102,114,97,109,101,105,95, + 114,105,103,104,116,2,0,26,99,111,110,116,97,105,110,101,114,46,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,11,102,114,108,95, + 102,105,114,105,103,104,116,0,27,99,111,110,116,97,105,110,101,114,46,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,18,99, + 111,110,116,97,105,110,101,114,46,111,110,108,97,121,111,117,116,7,17,102, + 111,114,109,111,110,99,104,105,108,100,115,99,97,108,101,100,16,99,111,110, + 116,97,105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0,3,244, + 0,3,180,0,0,22,100,114,97,103,100,111,99,107,46,115,112,108,105,116, + 116,101,114,95,115,105,122,101,2,0,16,100,114,97,103,100,111,99,107,46, + 99,97,112,116,105,111,110,6,5,83,116,97,99,107,20,100,114,97,103,100, + 111,99,107,46,111,112,116,105,111,110,115,100,111,99,107,11,10,111,100,95, + 115,97,118,101,112,111,115,10,111,100,95,99,97,110,109,111,118,101,11,111, + 100,95,99,97,110,102,108,111,97,116,10,111,100,95,99,97,110,100,111,99, + 107,15,111,100,95,112,114,111,112,111,114,116,105,111,110,97,108,11,111,100, + 95,112,114,111,112,115,105,122,101,14,111,100,95,99,97,112,116,105,111,110, + 104,105,110,116,13,111,100,95,99,104,105,108,100,105,99,111,110,115,0,7, + 111,112,116,105,111,110,115,11,10,102,111,95,115,97,118,101,112,111,115,12, + 102,111,95,115,97,118,101,115,116,97,116,101,0,8,115,116,97,116,102,105, + 108,101,7,22,109,97,105,110,102,111,46,112,114,111,106,101,99,116,115,116, + 97,116,102,105,108,101,7,99,97,112,116,105,111,110,6,5,83,116,97,99, + 107,21,105,99,111,110,46,116,114,97,110,115,112,97,114,101,110,116,99,111, + 108,111,114,4,6,0,0,128,10,105,99,111,110,46,105,109,97,103,101,10, + 200,8,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0,0,0, + 148,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,245,245,245,1, + 243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1, + 235,235,235,1,234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1, + 227,227,227,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1, + 219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1, + 211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1, + 242,242,242,1,0,0,255,1,238,238,238,1,237,237,237,1,235,235,235,1, + 234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1,227,227,227,1, + 226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219,219,1, + 218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1, + 210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1, + 0,0,255,2,237,237,237,1,235,235,235,1,234,234,234,1,214,214,214,1, + 189,189,189,1,198,198,198,1,201,201,201,1,179,179,179,1,184,184,184,1, + 208,208,208,1,189,189,189,1,131,131,131,1,173,173,173,1,126,126,126,1, + 193,193,193,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1, + 245,245,245,1,243,243,243,1,242,242,242,1,0,0,255,3,235,235,235,1, + 234,234,234,1,172,172,172,1,121,121,121,1,160,160,160,1,158,158,158,1, + 145,145,145,1,144,144,144,1,168,168,168,1,193,193,193,1,149,149,149,1, + 127,127,127,1,146,146,146,1,215,215,215,1,213,213,213,1,211,211,211,1, + 210,210,210,1,208,208,208,1,245,245,245,1,0,0,255,6,234,234,234,1, + 189,189,189,1,161,161,161,1,182,182,182,1,183,183,183,1,191,191,191,1, + 169,169,169,1,190,190,190,1,207,207,207,1,179,179,179,1,155,155,155,1, + 180,180,180,1,215,215,215,1,213,213,213,1,211,211,211,1,210,210,210,1, + 208,208,208,1,245,245,245,1,0,0,255,1,242,242,242,1,0,0,255,3, + 235,235,235,1,234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1, + 227,227,227,1,175,175,175,1,222,222,222,1,196,196,196,1,169,169,169,1, + 219,219,219,1,218,218,218,1,180,180,180,1,201,201,201,1,213,213,213,1, + 211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,0,0,255,1, + 242,242,242,1,0,0,255,2,237,237,237,1,235,235,235,1,234,234,234,1, + 232,232,232,1,230,230,230,1,229,229,229,1,227,227,227,1,126,126,126,1, + 154,154,154,1,134,134,134,1,120,120,120,1,149,149,149,1,148,148,148,1, + 121,121,121,1,207,207,207,1,213,213,213,1,211,211,211,1,210,210,210,1, + 208,208,208,1,245,245,245,1,0,0,255,1,242,242,242,1,0,0,255,1, + 238,238,238,1,237,237,237,1,235,235,235,1,234,234,234,1,232,232,232,1, + 230,230,230,1,229,229,229,1,227,227,227,1,155,155,155,1,139,139,139,1, + 143,143,143,1,152,152,152,1,114,114,114,1,112,112,112,1,148,148,148,1, + 215,215,215,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1, + 245,245,245,1,0,0,255,1,242,242,242,1,240,240,240,1,238,238,238,1, + 237,237,237,1,235,235,235,1,234,234,234,1,232,232,232,1,230,230,230,1, + 229,229,229,1,227,227,227,1,226,226,226,1,224,224,224,1,223,223,223,1, + 221,221,221,1,219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1, + 213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1, + 0,0,255,1,242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1, + 235,235,235,1,234,234,234,1,214,214,214,1,189,189,189,1,198,198,198,1, + 201,201,201,1,187,187,187,1,160,160,160,1,176,176,176,1,211,211,211,1, + 219,219,219,1,218,218,218,1,216,216,216,1,107,107,235,1,0,0,255,3, + 208,208,208,1,245,245,245,1,0,0,255,1,242,242,242,1,240,240,240,1, + 238,238,238,1,237,237,237,1,235,235,235,1,234,234,234,1,172,172,172,1, + 121,121,121,1,160,160,160,1,158,158,158,1,155,155,155,1,142,142,142,1, + 144,144,144,1,146,146,146,1,219,219,219,1,218,218,218,1,216,216,216,1, + 215,215,215,1,213,213,213,1,211,211,211,1,0,0,255,1,208,208,208,1, + 245,245,245,1,0,0,255,1,242,242,242,1,240,240,240,1,238,238,238,1, + 237,237,237,1,235,235,235,1,234,234,234,1,189,189,189,1,161,161,161,1, + 182,182,182,1,183,183,183,1,167,167,167,1,177,177,177,1,161,161,161,1, + 184,184,184,1,219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1, + 213,213,213,1,211,211,211,1,0,0,255,1,208,208,208,1,245,245,245,1, + 0,0,255,1,242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1, + 235,235,235,1,234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1, + 227,227,227,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1, + 219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1, + 211,211,211,1,0,0,255,1,208,208,208,1,245,245,245,1,0,0,255,1, + 242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1,235,235,235,1, + 234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1,227,227,227,1, + 226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219,219,1, + 218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1, + 0,0,255,1,208,208,208,1,245,245,245,1,0,0,255,1,242,242,242,1, + 240,240,240,1,238,238,238,1,237,237,237,1,235,235,235,1,234,234,234,1, + 232,232,232,1,230,230,230,1,229,229,229,1,227,227,227,1,226,226,226,1, + 224,224,224,1,223,223,223,1,221,221,221,1,219,219,219,1,218,218,218,1, + 216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1,0,0,255,1, + 208,208,208,1,245,245,245,1,0,0,255,1,242,242,242,1,240,240,240,1, + 197,197,197,1,156,156,156,1,182,182,182,1,232,232,232,2,228,228,228,1, + 229,229,229,1,225,225,225,1,226,226,226,1,223,223,223,1,222,222,222,1, + 198,198,198,1,219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1, + 213,213,213,1,211,211,211,1,0,0,255,1,208,208,208,1,245,245,245,1, + 0,0,255,1,242,242,242,1,240,240,240,1,178,178,178,1,155,155,155,1, + 178,178,178,1,95,95,95,1,177,177,177,1,95,95,95,1,147,147,147,1, + 133,133,133,1,226,226,226,1,140,140,140,1,126,126,126,1,152,152,152,1, + 219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1,0,0,255,1, + 211,211,211,1,0,0,255,1,208,208,208,1,245,245,245,1,0,0,255,2, + 240,240,240,1,193,193,193,1,221,221,221,1,231,231,231,1,157,157,157,1, + 152,152,152,1,151,151,151,1,173,173,173,1,149,149,149,1,226,226,226,1, + 149,149,149,1,150,150,150,1,169,169,169,1,219,219,219,1,218,218,218,1, + 216,216,216,1,0,0,255,2,211,211,211,1,0,0,255,1,208,208,208,1, + 245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1, + 237,237,237,1,235,235,235,1,234,234,234,1,232,232,232,1,230,230,230,1, + 229,229,229,1,227,227,227,1,226,226,226,1,224,224,224,1,223,223,223,1, + 210,210,210,1,219,219,219,1,218,218,218,1,0,0,255,3,211,211,211,1, + 0,0,255,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1, + 240,240,240,1,217,217,217,1,164,164,164,1,193,193,193,1,176,176,176,1, + 186,186,186,1,177,177,177,2,181,181,181,1,168,168,168,1,184,184,184,1, + 157,157,157,1,153,153,153,1,219,219,219,1,0,0,255,6,208,208,208,1, + 245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1,193,193,193,1, + 139,139,139,1,154,154,154,1,143,143,143,1,164,164,164,1,124,124,124,1, + 155,155,155,1,128,128,128,1,146,146,146,1,122,122,122,1,165,165,165,1, + 150,150,150,1,219,219,219,1,218,218,218,1,0,0,255,3,211,211,211,1, + 210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1, + 240,240,240,1,228,228,228,1,191,191,191,1,212,212,212,1,194,194,194,1, + 199,199,199,1,197,197,197,1,190,190,190,1,200,200,200,1,183,183,183,1, + 203,203,203,1,185,185,185,1,206,206,206,1,219,219,219,1,218,218,218,1, + 216,216,216,1,0,0,255,2,211,211,211,1,210,210,210,1,208,208,208,1, + 245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1, + 237,237,237,1,235,235,235,1,234,234,234,1,232,232,232,1,230,230,230,1, + 229,229,229,1,227,227,227,1,226,226,226,1,224,224,224,1,223,223,223,1, + 221,221,221,1,219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1, + 0,0,255,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1, + 243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1, + 235,235,235,1,234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1, + 227,227,227,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1, + 219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1, + 211,211,211,1,210,210,210,1,208,208,208,1,6,111,110,115,104,111,119,7, + 13,115,116,97,99,107,102,111,111,110,115,104,111,119,8,111,110,108,97,121, + 111,117,116,7,17,102,111,114,109,111,110,99,104,105,108,100,115,99,97,108, + 101,100,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,9, + 116,100,111,99,107,102,111,114,109,0,11,116,115,116,114,105,110,103,103,114, + 105,100,4,103,114,105,100,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95, + 116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111, + 119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,102, + 111,99,117,115,98,97,99,107,111,110,101,115,99,13,111,119,95,109,111,117, + 115,101,119,104,101,101,108,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,0,5,99,111,108,111,114,4,5,0,0,144,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95, + 108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101, + 110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100, + 115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,20,9,98,111,117, + 110,100,115,95,99,120,3,244,0,9,98,111,117,110,100,115,95,99,121,3, + 160,0,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,9,97, + 110,95,98,111,116,116,111,109,0,14,100,97,116,97,99,111,108,115,46,99, + 111,117,110,116,2,5,21,100,97,116,97,99,111,108,115,46,99,111,108,111, + 114,102,111,99,117,115,101,100,4,7,0,0,144,16,100,97,116,97,99,111, + 108,115,46,111,112,116,105,111,110,115,11,14,99,111,95,102,111,99,117,115, + 115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99, + 116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117, + 108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101, + 99,116,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111,95,115, + 97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,17, + 99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,14,100, + 97,116,97,99,111,108,115,46,105,116,101,109,115,14,1,5,99,111,108,111, + 114,4,2,0,0,128,12,99,111,108,111,114,102,111,99,117,115,101,100,4, + 7,0,0,144,5,119,105,100,116,104,2,31,7,111,112,116,105,111,110,115, + 11,11,99,111,95,114,101,97,100,111,110,108,121,10,99,111,95,110,111,102, + 111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14, + 99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101, + 121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101, + 99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111,95,115, + 97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,0, + 9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,120,99,101,110,116, + 101,114,101,100,12,116,102,95,121,99,101,110,116,101,114,101,100,0,10,118, + 97,108,117,101,102,97,108,115,101,6,1,48,9,118,97,108,117,101,116,114, + 117,101,6,1,49,0,1,11,99,111,108,111,114,115,101,108,101,99,116,4, + 7,0,0,144,12,99,111,108,111,114,102,111,99,117,115,101,100,4,7,0, + 0,144,5,119,105,100,116,104,2,54,7,111,112,116,105,111,110,115,11,11, + 99,111,95,114,101,97,100,111,110,108,121,14,99,111,95,102,111,99,117,115, + 115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99, + 116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117, + 108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101, + 99,116,7,99,111,95,102,105,108,108,10,99,111,95,99,97,110,99,111,112, + 121,0,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101, + 110,116,101,114,101,100,11,116,102,95,110,111,115,101,108,101,99,116,15,116, + 102,95,101,108,108,105,112,115,101,114,105,103,104,116,0,15,116,101,120,116, + 102,108,97,103,115,97,99,116,105,118,101,11,12,116,102,95,121,99,101,110, + 116,101,114,101,100,15,116,102,95,101,108,108,105,112,115,101,114,105,103,104, + 116,0,11,111,112,116,105,111,110,115,101,100,105,116,11,14,115,99,111,101, + 95,101,97,116,114,101,116,117,114,110,16,115,99,111,101,95,104,111,109,101, + 111,110,101,110,116,101,114,0,10,118,97,108,117,101,102,97,108,115,101,6, + 1,48,9,118,97,108,117,101,116,114,117,101,6,1,49,0,1,12,99,111, + 108,111,114,102,111,99,117,115,101,100,4,7,0,0,144,7,111,112,116,105, + 111,110,115,11,12,99,111,95,105,110,118,105,115,105,98,108,101,14,99,111, + 95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115, + 101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116, + 14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114, + 111,119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116,97,116, + 101,10,99,111,95,99,97,110,99,111,112,121,0,11,111,112,116,105,111,110, + 115,101,100,105,116,11,14,115,99,111,101,95,101,97,116,114,101,116,117,114, + 110,0,10,118,97,108,117,101,102,97,108,115,101,6,1,48,9,118,97,108, + 117,101,116,114,117,101,6,1,49,0,1,12,99,111,108,111,114,102,111,99, + 117,115,101,100,4,7,0,0,144,7,111,112,116,105,111,110,115,11,12,99, + 111,95,105,110,118,105,115,105,98,108,101,14,99,111,95,102,111,99,117,115, + 115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99, + 116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117, + 108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101, + 99,116,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99, + 97,110,99,111,112,121,0,10,118,97,108,117,101,102,97,108,115,101,6,1, + 48,9,118,97,108,117,101,116,114,117,101,6,1,49,0,1,12,99,111,108, + 111,114,102,111,99,117,115,101,100,4,7,0,0,144,7,111,112,116,105,111, + 110,115,11,12,99,111,95,105,110,118,105,115,105,98,108,101,14,99,111,95, + 102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101, + 115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14, + 99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111, + 119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116,97,116,101, + 10,99,111,95,99,97,110,99,111,112,121,0,10,118,97,108,117,101,102,97, + 108,115,101,6,1,48,9,118,97,108,117,101,116,114,117,101,6,1,49,0, + 0,13,100,97,116,97,114,111,119,104,101,105,103,104,116,2,16,11,111,110, + 99,101,108,108,101,118,101,110,116,7,15,103,114,105,100,111,110,99,101,108, + 108,101,118,101,110,116,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,11,116,115,116,114,105,110,103,100,105,115,112,8,102,105,108, + 101,100,105,115,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110, + 100,115,95,120,2,71,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,120,3,172,0,9,98,111,117,110,100,115,95,99,121, + 2,18,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6, + 97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,9,116,101,120, + 116,102,108,97,103,115,11,12,116,102,95,121,99,101,110,116,101,114,101,100, + 14,116,102,95,101,108,108,105,112,115,101,108,101,102,116,0,7,111,112,116, + 105,111,110,115,11,19,100,119,111,95,104,105,110,116,99,108,105,112,112,101, + 100,116,101,120,116,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,11,116,115,116,114,105,110,103,100,105,115,112,7,97,100,100, + 114,101,115,115,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,8,98,111,117,110,100,115,95,120,2,1,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,70,9,98,111, + 117,110,100,115,95,99,121,2,18,9,116,101,120,116,102,108,97,103,115,11, + 12,116,102,95,120,99,101,110,116,101,114,101,100,12,116,102,95,121,99,101, + 110,116,101,114,101,100,0,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,0,10,116,112,111,112,117,112,109,101,110,117,11,116,112,111, + 112,117,112,109,101,110,117,49,18,109,101,110,117,46,115,117,98,109,101,110, + 117,46,99,111,117,110,116,2,1,18,109,101,110,117,46,115,117,98,109,101, + 110,117,46,105,116,101,109,115,14,1,7,99,97,112,116,105,111,110,6,17, + 67,111,112,121,32,116,111,32,67,108,105,112,98,111,97,114,100,5,115,116, + 97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110, + 17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9, + 111,110,101,120,101,99,117,116,101,7,15,99,111,112,121,116,111,99,108,105, + 112,98,111,97,114,100,0,0,10,109,101,110,117,46,115,116,97,116,101,11, + 17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,4, + 108,101,102,116,2,48,3,116,111,112,2,56,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tstackfo,''); +end. diff --git a/mseide-msegui/apps/ide/storedcomponentinfodialog.mfm b/mseide-msegui/apps/ide/storedcomponentinfodialog.mfm new file mode 100644 index 0000000..f591246 --- /dev/null +++ b/mseide-msegui/apps/ide/storedcomponentinfodialog.mfm @@ -0,0 +1,107 @@ +object storedcomponentinfodialogfo: tstoredcomponentinfodialogfo + bounds_x = 172 + bounds_y = 228 + bounds_cx = 362 + bounds_cy = 255 + container.bounds = ( + 0 + 0 + 362 + 255 + ) + options = [fo_freeonclose, fo_screencentered, fo_cancelonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savestate] + onclosequery = doclosequery + moduleclassname = 'tmseform' + object tbutton1: tbutton + bounds_x = 240 + bounds_y = 224 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + end + object tbutton2: tbutton + taborder = 1 + bounds_x = 304 + bounds_y = 224 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + end + object filepath: tfilenameedit + frame.caption = '&File' + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + bounds_x = 8 + bounds_y = 175 + bounds_cx = 348 + bounds_cy = 37 + anchors = [an_left, an_right, an_bottom] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savevalue, oe1_savestate] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_notnull] + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + controller.filterlist.data = ( + ( + 'Component File' + '*.cmp' + ) + ( + 'All Files' + '*' + ) + ) + controller.defaultext = 'cmp' + controller.options = [fdo_save, fdo_checkexist, fdo_savelastdir] + controller.captionsave = 'Component File' + reffontheight = 14 + end + object compname: tstringedit + frame.caption = '&Name' + frame.dummy = 0 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 3 + bounds_x = 8 + bounds_y = 7 + bounds_cx = 348 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + ondataentered = namedataentered + reffontheight = 14 + end + object compdesc: tmemoedit + frame.sbhorz.pagesize = 1 + frame.sbvert.pagesize = 1 + frame.caption = '&Description' + frame.localprops = [frl_colorclient] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 4 + bounds_x = 8 + bounds_y = 47 + bounds_cx = 348 + bounds_cy = 125 + anchors = [an_left, an_top, an_right, an_bottom] + reffontheight = 14 + end +end diff --git a/mseide-msegui/apps/ide/storedcomponentinfodialog.pas b/mseide-msegui/apps/ide/storedcomponentinfodialog.pas new file mode 100644 index 0000000..704114e --- /dev/null +++ b/mseide-msegui/apps/ide/storedcomponentinfodialog.pas @@ -0,0 +1,88 @@ +{ MSEide Copyright (c) 2008 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit storedcomponentinfodialog; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseglob,mseguiglob,mseapplication,msestat,msemenus,msegui,msegraphics, + msegraphutils,mseevent,mseclasses,mseforms,componentstore,msesimplewidgets, + msewidgets,msebitmap,msedataedits,msedatanodes,mseedit,msefiledialog,msegrids, + mselistbrowser,msestrings,msesys,msetypes; +type + tstoredcomponentinfodialogfo = class(tmseform) + tbutton1: tbutton; + tbutton2: tbutton; + filepath: tfilenameedit; + compname: tstringedit; + compdesc: tmemoedit; + procedure doclosequery(const sender: tcustommseform; + var amodalresult: modalresultty); + procedure namedataentered(const sender: TObject); + private + infopo: pstoredcomponentinfoty; + public + constructor create(var ainfo: storedcomponentinfoty); reintroduce; + procedure checkfilename; + end; +var + storedcomponentinfodialogfo: tstoredcomponentinfodialogfo; + +implementation +uses + storedcomponentinfodialog_mfm,msefileutils,actionsmodule; + +{ tstoredcomponentinfodialogfo } + +constructor tstoredcomponentinfodialogfo.create(var ainfo: storedcomponentinfoty); +begin + infopo:= @ainfo; + inherited create(nil); + with ainfo do begin + self.caption:= actionsmo.c[ord(ac_storecomponent)]+' '+ + msestring(componentname)+': '+msestring(compclass); + self.compname.value:= compname; + self.compdesc.value:= compdesc; + self.filepath.value:= filepath; + end; +end; + +procedure tstoredcomponentinfodialogfo.doclosequery(const sender: tcustommseform; + var amodalresult: modalresultty); +begin + if amodalresult = mr_ok then begin + with infopo^ do begin + compname:= self.compname.value; + compdesc:= self.compdesc.value; + filepath:= self.filepath.value; + end; + end; +end; + +procedure tstoredcomponentinfodialogfo.namedataentered(const sender: TObject); +begin + checkfilename; +end; + +procedure tstoredcomponentinfodialogfo.checkfilename; +begin + if compname.value <> '' then begin + filepath.value:= uniquefilename(filedir(filepath.value) + + replacechar(compname.value,' ','_') + '.cmp'); + end; +end; + +end. diff --git a/mseide-msegui/apps/ide/storedcomponentinfodialog_mfm.pas b/mseide-msegui/apps/ide/storedcomponentinfodialog_mfm.pas new file mode 100644 index 0000000..b7909db --- /dev/null +++ b/mseide-msegui/apps/ide/storedcomponentinfodialog_mfm.pas @@ -0,0 +1,113 @@ +unit storedcomponentinfodialog_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,storedcomponentinfodialog; + +const + objdata: record size: integer; data: array[0..1905] of byte end = + (size: 1906; data: ( + 84,80,70,48,28,116,115,116,111,114,101,100,99,111,109,112,111,110,101,110, + 116,105,110,102,111,100,105,97,108,111,103,102,111,27,115,116,111,114,101,100, + 99,111,109,112,111,110,101,110,116,105,110,102,111,100,105,97,108,111,103,102, + 111,8,98,111,117,110,100,115,95,120,3,172,0,8,98,111,117,110,100,115, + 95,121,3,228,0,9,98,111,117,110,100,115,95,99,120,3,106,1,9,98, + 111,117,110,100,115,95,99,121,3,255,0,16,99,111,110,116,97,105,110,101, + 114,46,98,111,117,110,100,115,1,2,0,2,0,3,106,1,3,255,0,0, + 7,111,112,116,105,111,110,115,11,14,102,111,95,102,114,101,101,111,110,99, + 108,111,115,101,17,102,111,95,115,99,114,101,101,110,99,101,110,116,101,114, + 101,100,14,102,111,95,99,97,110,99,101,108,111,110,101,115,99,15,102,111, + 95,97,117,116,111,114,101,97,100,115,116,97,116,16,102,111,95,97,117,116, + 111,119,114,105,116,101,115,116,97,116,10,102,111,95,115,97,118,101,112,111, + 115,12,102,111,95,115,97,118,101,115,116,97,116,101,0,12,111,110,99,108, + 111,115,101,113,117,101,114,121,7,12,100,111,99,108,111,115,101,113,117,101, + 114,121,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,8, + 116,109,115,101,102,111,114,109,0,7,116,98,117,116,116,111,110,8,116,98, + 117,116,116,111,110,49,8,98,111,117,110,100,115,95,120,3,240,0,8,98, + 111,117,110,100,115,95,121,3,224,0,9,98,111,117,110,100,115,95,99,120, + 2,50,9,98,111,117,110,100,115,95,99,121,2,20,7,97,110,99,104,111, + 114,115,11,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116,116, + 111,109,0,5,115,116,97,116,101,11,10,97,115,95,100,101,102,97,117,108, + 116,15,97,115,95,108,111,99,97,108,100,101,102,97,117,108,116,15,97,115, + 95,108,111,99,97,108,99,97,112,116,105,111,110,0,7,99,97,112,116,105, + 111,110,6,3,38,79,75,11,109,111,100,97,108,114,101,115,117,108,116,7, + 5,109,114,95,111,107,0,0,7,116,98,117,116,116,111,110,8,116,98,117, + 116,116,111,110,50,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117, + 110,100,115,95,120,3,48,1,8,98,111,117,110,100,115,95,121,3,224,0, + 9,98,111,117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95, + 99,121,2,20,7,97,110,99,104,111,114,115,11,8,97,110,95,114,105,103, + 104,116,9,97,110,95,98,111,116,116,111,109,0,5,115,116,97,116,101,11, + 15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,7,99,97, + 112,116,105,111,110,6,7,38,67,97,110,99,101,108,11,109,111,100,97,108, + 114,101,115,117,108,116,7,9,109,114,95,99,97,110,99,101,108,0,0,13, + 116,102,105,108,101,110,97,109,101,101,100,105,116,8,102,105,108,101,112,97, + 116,104,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,5,38,70, + 105,108,101,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108, + 111,114,4,2,0,0,128,20,102,114,97,109,101,46,98,117,116,116,111,110, + 46,105,109,97,103,101,110,114,2,17,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97, + 98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,2,8,8, + 98,111,117,110,100,115,95,121,3,175,0,9,98,111,117,110,100,115,95,99, + 120,3,92,1,9,98,111,117,110,100,115,95,99,121,2,37,7,97,110,99, + 104,111,114,115,11,7,97,110,95,108,101,102,116,8,97,110,95,114,105,103, + 104,116,9,97,110,95,98,111,116,116,111,109,0,12,111,112,116,105,111,110, + 115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117, + 112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101, + 13,111,101,49,95,115,97,118,101,118,97,108,117,101,13,111,101,49,95,115, + 97,118,101,115,116,97,116,101,0,11,111,112,116,105,111,110,115,101,100,105, + 116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99, + 108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114, + 99,97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114, + 110,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101, + 115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101, + 120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110, + 101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25, + 111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116, + 99,108,105,99,107,10,111,101,95,110,111,116,110,117,108,108,0,9,116,101, + 120,116,102,108,97,103,115,11,12,116,102,95,121,99,101,110,116,101,114,101, + 100,11,116,102,95,110,111,115,101,108,101,99,116,14,116,102,95,101,108,108, + 105,112,115,101,108,101,102,116,0,26,99,111,110,116,114,111,108,108,101,114, + 46,102,105,108,116,101,114,108,105,115,116,46,100,97,116,97,1,1,6,14, + 67,111,109,112,111,110,101,110,116,32,70,105,108,101,6,5,42,46,99,109, + 112,0,1,6,9,65,108,108,32,70,105,108,101,115,6,1,42,0,0,21, + 99,111,110,116,114,111,108,108,101,114,46,100,101,102,97,117,108,116,101,120, + 116,6,3,99,109,112,18,99,111,110,116,114,111,108,108,101,114,46,111,112, + 116,105,111,110,115,11,8,102,100,111,95,115,97,118,101,14,102,100,111,95, + 99,104,101,99,107,101,120,105,115,116,15,102,100,111,95,115,97,118,101,108, + 97,115,116,100,105,114,0,22,99,111,110,116,114,111,108,108,101,114,46,99, + 97,112,116,105,111,110,115,97,118,101,6,14,67,111,109,112,111,110,101,110, + 116,32,70,105,108,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,11,116,115,116,114,105,110,103,101,100,105,116,8,99,111,109, + 112,110,97,109,101,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 5,38,78,97,109,101,11,102,114,97,109,101,46,100,117,109,109,121,2,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,3,8,98, + 111,117,110,100,115,95,120,2,8,8,98,111,117,110,100,115,95,121,2,7, + 9,98,111,117,110,100,115,95,99,120,3,92,1,9,98,111,117,110,100,115, + 95,99,121,2,37,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101, + 102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,13, + 111,110,100,97,116,97,101,110,116,101,114,101,100,7,15,110,97,109,101,100, + 97,116,97,101,110,116,101,114,101,100,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,14,0,0,9,116,109,101,109,111,101,100,105,116,8,99, + 111,109,112,100,101,115,99,21,102,114,97,109,101,46,115,98,104,111,114,122, + 46,112,97,103,101,115,105,122,101,2,1,21,102,114,97,109,101,46,115,98, + 118,101,114,116,46,112,97,103,101,115,105,122,101,2,1,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,12,38,68,101,115,99,114,105,112,116, + 105,111,110,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17, + 2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,4,8,98,111,117, + 110,100,115,95,120,2,8,8,98,111,117,110,100,115,95,121,2,47,9,98, + 111,117,110,100,115,95,99,120,3,92,1,9,98,111,117,110,100,115,95,99, + 121,2,125,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116, + 6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,9,97,110,95, + 98,111,116,116,111,109,0,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tstoredcomponentinfodialogfo,''); +end. diff --git a/mseide-msegui/apps/ide/stringconsts.mfm b/mseide-msegui/apps/ide/stringconsts.mfm new file mode 100644 index 0000000..351cd46 --- /dev/null +++ b/mseide-msegui/apps/ide/stringconsts.mfm @@ -0,0 +1,11 @@ +object s: tstringconstsmo + bounds_cx = 287 + bounds_cy = 100 + left = 100 + top = 100 + moduleclassname = 'tmsedatamodule' + object c: tstringcontainer + left = 16 + top = 16 + end +end diff --git a/mseide-msegui/apps/ide/stringconsts.pas b/mseide-msegui/apps/ide/stringconsts.pas new file mode 100644 index 0000000..eb76a47 --- /dev/null +++ b/mseide-msegui/apps/ide/stringconsts.pas @@ -0,0 +1,17 @@ +unit stringconsts; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseglob,mseapplication,mseclasses,msedatamodules,msestringcontainer,msestrings; + +type + tstringconstsmo = class(tmsedatamodule) + c: tstringcontainer; + end; +var + s: tstringconstsmo; + +implementation +uses + stringconsts_mfm; +end. diff --git a/mseide-msegui/apps/ide/stringconsts_mfm.pas b/mseide-msegui/apps/ide/stringconsts_mfm.pas new file mode 100644 index 0000000..8b58533 --- /dev/null +++ b/mseide-msegui/apps/ide/stringconsts_mfm.pas @@ -0,0 +1,24 @@ +unit stringconsts_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,stringconsts; + +const + objdata: record size: integer; data: array[0..127] of byte end = + (size: 128; data: ( + 84,80,70,48,15,116,115,116,114,105,110,103,99,111,110,115,116,115,109,111, + 1,115,9,98,111,117,110,100,115,95,99,120,3,31,1,9,98,111,117,110, + 100,115,95,99,121,2,100,4,108,101,102,116,2,100,3,116,111,112,2,100, + 15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,14,116,109, + 115,101,100,97,116,97,109,111,100,117,108,101,0,16,116,115,116,114,105,110, + 103,99,111,110,116,97,105,110,101,114,1,99,4,108,101,102,116,2,16,3, + 116,111,112,2,16,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tstringconstsmo,''); +end. diff --git a/mseide-msegui/apps/ide/symbolform.mfm b/mseide-msegui/apps/ide/symbolform.mfm new file mode 100644 index 0000000..9e6d693 --- /dev/null +++ b/mseide-msegui/apps/ide/symbolform.mfm @@ -0,0 +1,235 @@ +object symbolfo: tsymbolfo + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_floatbutton, go_topbutton, go_backgroundbutton, go_nolockbutton, go_buttonhints] + visible = False + bounds_x = 142 + bounds_y = 257 + bounds_cx = 506 + bounds_cy = 137 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 496 + 137 + ) + dragdock.optionsdock = [od_savepos, od_savezorder, od_canmove, od_cansize, od_canfloat, od_candock, od_propsize, od_captionhint, od_childicons] + options = [fo_savepos, fo_savezorder, fo_savestate] + statfile = mainfo.projectstatfile + caption = 'Symbols' + icon.transparentcolor = -2147483642 + icon.options = [bmo_masked] + icon.image = { + 00000000020000001800000018000000A8030000000000000000000000000000 + 0000000000000000000000000000000000000000D0D0D0607C7C7C19D9D9D916 + FFFFFF017C7C7C01D9D9D903B6B6B60199999901D5D5D501D9D9D901C2C2C201 + BCBCBC01D9D9D903C8C8C801BBBBBB01C2C2C201B2B2B201D9D9D903CCCCCC01 + AEAEAE01D9D9D901FFFFFF017C7C7C01D9D9D902555555010202020109090901 + 16161601BFBFBF019090900112121201D5D5D501D9D9D9023535350165656501 + 4F4F4F0103030301CCCCCC01D9D9D9026363630102020201D9D9D901FFFFFF01 + 7C7C7C01D9D9D901C7C7C7010B0B0B01B6B6B601D2D2D2013E3E3E014C4C4C01 + D9D9D901242424016F6F6F01D9D9D901AEAEAE0113131301D2D2D2014F4F4F01 + 0707070189898901D9D9D9023333330107070701D9D9D901FFFFFF017C7C7C01 + D9D9D901A4A4A4011F1F1F01D9D9D902A8A8A80165656501D9D9D90189898901 + 18181801D9D9D9013F3F3F0163636301D9D9D9014F4F4F012A2A2A0151515101 + D9D9D902262626010F0F0F01D9D9D901FFFFFF017C7C7C01D9D9D901D5D5D501 + 121212013030300195959501D9D9D9041F1F1F017171710116161601D2D2D201 + D9D9D9014F4F4F015656560126262601D9D9D901A7A7A7013E3E3E010F0F0F01 + D9D9D901FFFFFF017C7C7C01D9D9D902A6A6A6012C2C2C01010101011C1C1C01 + B8B8B801D9D9D902808080010404040163636301D9D9D9024F4F4F016C6C6C01 + 1A1A1A01D5D5D50165656501737373010F0F0F01D9D9D901FFFFFF017C7C7C01 + D9D9D904B4B4B4013B3B3B012B2B2B01D9D9D9030A0A0A01CFCFCF01D9D9D902 + 4F4F4F016C6C6C01393939019595950133333301BCBCBC010F0F0F01D9D9D901 + FFFFFF017C7C7C01D9D9D9017B7B7B015F5F5F01D9D9D902D2D2D20110101001 + D9D9D9030D0D0D01D5D5D501D9D9D9024F4F4F016C6C6C025858580128282801 + D9D9D9010F0F0F01D9D9D901FFFFFF017C7C7C01D9D9D9019B9B9B0116161601 + C4C4C401D9D9D9019292920122222201D9D9D9030D0D0D01D5D5D501D9D9D902 + 4F4F4F016C6C6C01B2B2B201191919013E3E3E01D9D9D9010F0F0F01D9D9D901 + FFFFFF017C7C7C01D9D9D9023C3C3C010909090121212101090909018A8A8A01 + D9D9D9030D0D0D01D5D5D501D9D9D9024F4F4F016C6C6C01D9D9D90111111101 + 73737301D9D9D9010F0F0F01D9D9D901FFFFFF017C7C7C01D9D9D9039B9B9B01 + 71717101B5B5B501D9D9D9048D8D8D01D9D9D903AEAEAE01B9B9B901D9D9D901 + 9C9C9C01C8C8C801D9D9D90190909001D9D9D901FFFFFF017C7C7C01D9D9D916 + FFFFFF017C7C7C01D9D9D916FFFFFF017C7C7C01FFFFFF17D0D0D06000000000 + 000000000000000000000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00 + FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00 + FFFFFF00FFFFFF00FFFFFF0000000000000000000000000000000000 + } + onshow = showex + moduleclassname = 'tdockform' + object grid: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets, ow_hinton] + frame.localprops = [] + frame.localprops1 = [] + popupmenu = tpopupmenu1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 496 + bounds_cy = 137 + anchors = [] + optionsgrid = [og_colsizing, og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_wrapcol, og_autopopup] + fixcols.count = 1 + fixcols.items = < + item + width = 18 + numstart = 1 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 15 + captions.count = 3 + captions.items = < + item + caption = 'Symbol' + end + item + caption = 'Address' + end + item + caption = 'Info' + end> + end> + rowfonts.count = 1 + rowfonts.items = < + item + color = -1610612729 + name = 'stf_default' + xscale = 1 + localprops = [flp_color, flp_xscale] + end> + datacols.count = 5 + datacols.options = [co_savevalue, co_savestate, co_cancopy, co_mousescrollrow] + datacols.items = < + item[symbol] + width = 111 + options = [co_savevalue, co_savestate, co_cancopy, co_canpaste] + options1 = [co1_rowfont, co1_zebracolor] + onchange = symbolcha + widgetname = 'symbol' + dataclass = tgridmsestringdatalist + end + item[symaddr] + width = 200 + options = [co_readonly, co_drawfocus, co_fill, co_savestate, co_cancopy, co_mousescrollrow] + widgetname = 'symaddr' + dataclass = tgridmsestringdatalist + end + item[syminfo] + width = 131 + options = [co_readonly, co_drawfocus, co_proportional, co_cancopy] + widthmin = 0 + widgetname = 'syminfo' + dataclass = tgridmsestringdatalist + end + item[path] + width = 15 + options = [co_invisible, co_cancopy, co_mousescrollrow] + widgetname = 'path' + dataclass = tgridmsestringdatalist + end + item[line] + width = 11 + options = [co_invisible, co_cancopy, co_mousescrollrow] + widgetname = 'line' + dataclass = tgridintegerdatalist + end> + datarowheight = 15 + statfile = mainfo.projectstatfile + oncellevent = cellev + reffontheight = 13 + object symbol: tstringedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 111 + bounds_cy = 15 + statfile = mainfo.projectstatfile + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_forcereturncheckvalue, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext] + ondataentered = symboldataent + reffontheight = 13 + end + object symaddr: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 2 + visible = False + bounds_x = 112 + bounds_y = 0 + bounds_cx = 200 + bounds_cy = 15 + optionsedit1 = [] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_hintclippedtext] + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + reffontheight = 13 + end + object syminfo: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 3 + visible = False + bounds_x = 313 + bounds_y = 0 + bounds_cx = 131 + bounds_cy = 15 + optionsedit1 = [] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_hintclippedtext] + reffontheight = 13 + end + object path: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 4 + visible = False + bounds_x = 445 + bounds_y = 0 + bounds_cx = 15 + bounds_cy = 15 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 13 + end + object line: tintegeredit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 5 + visible = False + bounds_x = 461 + bounds_y = 0 + bounds_cx = 11 + bounds_cy = 15 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 13 + end + end + object tpopupmenu1: tpopupmenu + menu.submenu.count = 1 + menu.submenu.items = < + item + caption = 'Delete all' + state = [as_localcaption, as_localonexecute] + onexecute = deleteallex + end> + left = 80 + top = 72 + end + object c: tstringcontainer + strings.data = ( + 'GDB not active.' + 'Do you wish to delete all symbols?' + ) + left = 192 + top = 56 + end +end diff --git a/mseide-msegui/apps/ide/symbolform.pas b/mseide-msegui/apps/ide/symbolform.pas new file mode 100644 index 0000000..aa9fc3a --- /dev/null +++ b/mseide-msegui/apps/ide/symbolform.pas @@ -0,0 +1,149 @@ +{ MSEide Copyright (c) 2010 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit symbolform; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,mseforms,msedock,msedataedits, + mseedit,msegrids,msestrings,msetypes,msewidgetgrid,msegraphedits, + msestringcontainer; + +type + tsymbolfo = class(tdockform) + grid: twidgetgrid; + symbol: tstringedit; + syminfo: tstringedit; + symaddr: tstringedit; + tpopupmenu1: tpopupmenu; + path: tstringedit; + line: tintegeredit; + c: tstringcontainer; + procedure symboldataent(const sender: TObject); + procedure symbolcha(const sender: tdatacol; const aindex: Integer); + procedure deleteallex(const sender: TObject); + procedure cellev(const sender: TObject; var info: celleventinfoty); + procedure showex(const sender: TObject); + protected + procedure checksymbol(const aindex: integer); + public + procedure updatesymbols; + end; +var + symbolfo: tsymbolfo; + +implementation +uses + symbolform_mfm,msegdbutils,main,sysutils,msewidgets,mseformatstr,sourceform; +type + stringconsts = ( + gdbnotactive, //0 GDB not active. + deleteall //1 Do you wish to delete all symbols? + ); + +procedure tsymbolfo.checksymbol(const aindex: integer); +var + str1,str2: msestring; + err: gdbresultty; + mstr1: msestring; + int1: integer; + ad1,ad2,ad3: qword; +begin + str2:= trim(symbol[aindex]); + if str2 = '' then begin + syminfo[aindex]:= ''; + symaddr[aindex]:= ''; + end + else begin + if (length(str2) > 0) and (str2[1] = '$') then begin + str2:= '0x'+copy(str2,2,bigint); + end; + err:= mainfo.gdb.infosymbol(str2,str1); + if err = gdb_notactive then begin + mstr1:= c[ord(gdbnotactive)]; + syminfo[aindex]:= mstr1; + symaddr[aindex]:= mstr1; + exit; + end; + syminfo[aindex]:= trim(removelinebreaks(str1)); + path[aindex]:= ''; + line[aindex]:= 0; + if not msestartsstr('0x',str2) then begin + mainfo.gdb.infoaddress(str2,str1); + end + else begin + str1:= ''; + if trystrtointvalue64(ansistring(str2),ad1) then begin + if mainfo.gdb.infoline(ad1,mstr1,int1,ad2,ad3) = gdb_ok then begin + path[aindex]:= mstr1; + line[aindex]:= int1; + str1:= mstr1+':'+inttostrmse(int1); + end; + end; + end; + symaddr[aindex]:= trim(removelinebreaks(str1)); + end; +end; + +procedure tsymbolfo.symboldataent(const sender: TObject); +begin + checksymbol(grid.row); +end; + +procedure tsymbolfo.symbolcha(const sender: tdatacol; const aindex: Integer); +var + int1: integer; +begin + if not grid.updating then begin + if aindex < 0 then begin + for int1:= 0 to grid.rowhigh do begin + checksymbol(int1); + end; + end + else begin + checksymbol(aindex); + end; + end; +end; + +procedure tsymbolfo.updatesymbols; +begin + if visible then begin + symbolcha(nil,-1); + end; +end; + +procedure tsymbolfo.deleteallex(const sender: TObject); +begin + if askyesno(c[ord(deleteall)]) then begin + grid.clear; + end; +end; + +procedure tsymbolfo.cellev(const sender: TObject; var info: celleventinfoty); +begin + if iscellclick(info,[ccr_dblclick]) then begin + sourcefo.showsourceline(path[info.cell.row],line[info.cell.row]-1,0,true); + end; +end; + +procedure tsymbolfo.showex(const sender: TObject); +begin + updatesymbols; +end; + +end. diff --git a/mseide-msegui/apps/ide/symbolform_mfm.pas b/mseide-msegui/apps/ide/symbolform_mfm.pas new file mode 100644 index 0000000..70f3f15 --- /dev/null +++ b/mseide-msegui/apps/ide/symbolform_mfm.pas @@ -0,0 +1,316 @@ +unit symbolform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,symbolform; + +const + objdata: record size: integer; data: array[0..5974] of byte end = + (size: 5975; data: ( + 84,80,70,48,9,116,115,121,109,98,111,108,102,111,8,115,121,109,98,111, + 108,102,111,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,15,102,114,97,109,101,46,103,114,105,112,95,115,105,122,101,2,10, + 18,102,114,97,109,101,46,103,114,105,112,95,111,112,116,105,111,110,115,11, + 14,103,111,95,99,108,111,115,101,98,117,116,116,111,110,16,103,111,95,102, + 105,120,115,105,122,101,98,117,116,116,111,110,14,103,111,95,102,108,111,97, + 116,98,117,116,116,111,110,12,103,111,95,116,111,112,98,117,116,116,111,110, + 19,103,111,95,98,97,99,107,103,114,111,117,110,100,98,117,116,116,111,110, + 15,103,111,95,110,111,108,111,99,107,98,117,116,116,111,110,14,103,111,95, + 98,117,116,116,111,110,104,105,110,116,115,0,7,118,105,115,105,98,108,101, + 8,8,98,111,117,110,100,115,95,120,3,142,0,8,98,111,117,110,100,115, + 95,121,3,1,1,9,98,111,117,110,100,115,95,99,120,3,250,1,9,98, + 111,117,110,100,115,95,99,121,3,137,0,26,99,111,110,116,97,105,110,101, + 114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0, + 27,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,16,99,111,110,116,97,105,110,101,114, + 46,98,111,117,110,100,115,1,2,0,2,0,3,240,1,3,137,0,0,20, + 100,114,97,103,100,111,99,107,46,111,112,116,105,111,110,115,100,111,99,107, + 11,10,111,100,95,115,97,118,101,112,111,115,13,111,100,95,115,97,118,101, + 122,111,114,100,101,114,10,111,100,95,99,97,110,109,111,118,101,10,111,100, + 95,99,97,110,115,105,122,101,11,111,100,95,99,97,110,102,108,111,97,116, + 10,111,100,95,99,97,110,100,111,99,107,11,111,100,95,112,114,111,112,115, + 105,122,101,14,111,100,95,99,97,112,116,105,111,110,104,105,110,116,13,111, + 100,95,99,104,105,108,100,105,99,111,110,115,0,7,111,112,116,105,111,110, + 115,11,10,102,111,95,115,97,118,101,112,111,115,13,102,111,95,115,97,118, + 101,122,111,114,100,101,114,12,102,111,95,115,97,118,101,115,116,97,116,101, + 0,8,115,116,97,116,102,105,108,101,7,22,109,97,105,110,102,111,46,112, + 114,111,106,101,99,116,115,116,97,116,102,105,108,101,7,99,97,112,116,105, + 111,110,6,7,83,121,109,98,111,108,115,21,105,99,111,110,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,12,105, + 99,111,110,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,0,10,105,99,111,110,46,105,109,97,103,101,10,60,4,0,0, + 0,0,0,0,2,0,0,0,24,0,0,0,24,0,0,0,168,3,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,208,208,208,96,124,124,124,25, + 217,217,217,22,255,255,255,1,124,124,124,1,217,217,217,3,182,182,182,1, + 153,153,153,1,213,213,213,1,217,217,217,1,194,194,194,1,188,188,188,1, + 217,217,217,3,200,200,200,1,187,187,187,1,194,194,194,1,178,178,178,1, + 217,217,217,3,204,204,204,1,174,174,174,1,217,217,217,1,255,255,255,1, + 124,124,124,1,217,217,217,2,85,85,85,1,2,2,2,1,9,9,9,1, + 22,22,22,1,191,191,191,1,144,144,144,1,18,18,18,1,213,213,213,1, + 217,217,217,2,53,53,53,1,101,101,101,1,79,79,79,1,3,3,3,1, + 204,204,204,1,217,217,217,2,99,99,99,1,2,2,2,1,217,217,217,1, + 255,255,255,1,124,124,124,1,217,217,217,1,199,199,199,1,11,11,11,1, + 182,182,182,1,210,210,210,1,62,62,62,1,76,76,76,1,217,217,217,1, + 36,36,36,1,111,111,111,1,217,217,217,1,174,174,174,1,19,19,19,1, + 210,210,210,1,79,79,79,1,7,7,7,1,137,137,137,1,217,217,217,2, + 51,51,51,1,7,7,7,1,217,217,217,1,255,255,255,1,124,124,124,1, + 217,217,217,1,164,164,164,1,31,31,31,1,217,217,217,2,168,168,168,1, + 101,101,101,1,217,217,217,1,137,137,137,1,24,24,24,1,217,217,217,1, + 63,63,63,1,99,99,99,1,217,217,217,1,79,79,79,1,42,42,42,1, + 81,81,81,1,217,217,217,2,38,38,38,1,15,15,15,1,217,217,217,1, + 255,255,255,1,124,124,124,1,217,217,217,1,213,213,213,1,18,18,18,1, + 48,48,48,1,149,149,149,1,217,217,217,4,31,31,31,1,113,113,113,1, + 22,22,22,1,210,210,210,1,217,217,217,1,79,79,79,1,86,86,86,1, + 38,38,38,1,217,217,217,1,167,167,167,1,62,62,62,1,15,15,15,1, + 217,217,217,1,255,255,255,1,124,124,124,1,217,217,217,2,166,166,166,1, + 44,44,44,1,1,1,1,1,28,28,28,1,184,184,184,1,217,217,217,2, + 128,128,128,1,4,4,4,1,99,99,99,1,217,217,217,2,79,79,79,1, + 108,108,108,1,26,26,26,1,213,213,213,1,101,101,101,1,115,115,115,1, + 15,15,15,1,217,217,217,1,255,255,255,1,124,124,124,1,217,217,217,4, + 180,180,180,1,59,59,59,1,43,43,43,1,217,217,217,3,10,10,10,1, + 207,207,207,1,217,217,217,2,79,79,79,1,108,108,108,1,57,57,57,1, + 149,149,149,1,51,51,51,1,188,188,188,1,15,15,15,1,217,217,217,1, + 255,255,255,1,124,124,124,1,217,217,217,1,123,123,123,1,95,95,95,1, + 217,217,217,2,210,210,210,1,16,16,16,1,217,217,217,3,13,13,13,1, + 213,213,213,1,217,217,217,2,79,79,79,1,108,108,108,2,88,88,88,1, + 40,40,40,1,217,217,217,1,15,15,15,1,217,217,217,1,255,255,255,1, + 124,124,124,1,217,217,217,1,155,155,155,1,22,22,22,1,196,196,196,1, + 217,217,217,1,146,146,146,1,34,34,34,1,217,217,217,3,13,13,13,1, + 213,213,213,1,217,217,217,2,79,79,79,1,108,108,108,1,178,178,178,1, + 25,25,25,1,62,62,62,1,217,217,217,1,15,15,15,1,217,217,217,1, + 255,255,255,1,124,124,124,1,217,217,217,2,60,60,60,1,9,9,9,1, + 33,33,33,1,9,9,9,1,138,138,138,1,217,217,217,3,13,13,13,1, + 213,213,213,1,217,217,217,2,79,79,79,1,108,108,108,1,217,217,217,1, + 17,17,17,1,115,115,115,1,217,217,217,1,15,15,15,1,217,217,217,1, + 255,255,255,1,124,124,124,1,217,217,217,3,155,155,155,1,113,113,113,1, + 181,181,181,1,217,217,217,4,141,141,141,1,217,217,217,3,174,174,174,1, + 185,185,185,1,217,217,217,1,156,156,156,1,200,200,200,1,217,217,217,1, + 144,144,144,1,217,217,217,1,255,255,255,1,124,124,124,1,217,217,217,22, + 255,255,255,1,124,124,124,1,217,217,217,22,255,255,255,1,124,124,124,1, + 255,255,255,23,208,208,208,96,0,0,0,0,0,0,0,0,0,0,0,0, + 0,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,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,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,6,111,110,115,104,111,119,7,6,115,104,111,119,101,120,15, + 109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,9,116,100,111, + 99,107,102,111,114,109,0,11,116,119,105,100,103,101,116,103,114,105,100,4, + 103,114,105,100,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13, + 111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98, + 102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15, + 111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97, + 114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,102,111,99,117, + 115,98,97,99,107,111,110,101,115,99,13,111,119,95,109,111,117,115,101,119, + 104,101,101,108,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,9,111,119,95,104,105,110,116,111,110,0,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,9,112,111,112,117,112,109,101, + 110,117,7,11,116,112,111,112,117,112,109,101,110,117,49,8,98,111,117,110, + 100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,120,3,240,1,9,98,111,117,110,100,115,95,99,121, + 3,137,0,7,97,110,99,104,111,114,115,11,0,11,111,112,116,105,111,110, + 115,103,114,105,100,11,12,111,103,95,99,111,108,115,105,122,105,110,103,12, + 111,103,95,114,111,119,109,111,118,105,110,103,15,111,103,95,107,101,121,114, + 111,119,109,111,118,105,110,103,15,111,103,95,114,111,119,105,110,115,101,114, + 116,105,110,103,14,111,103,95,114,111,119,100,101,108,101,116,105,110,103,19, + 111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101,114,15, + 111,103,95,97,117,116,111,102,105,114,115,116,114,111,119,13,111,103,95,97, + 117,116,111,97,112,112,101,110,100,10,111,103,95,119,114,97,112,99,111,108, + 12,111,103,95,97,117,116,111,112,111,112,117,112,0,13,102,105,120,99,111, + 108,115,46,99,111,117,110,116,2,1,13,102,105,120,99,111,108,115,46,105, + 116,101,109,115,14,1,5,119,105,100,116,104,2,18,8,110,117,109,115,116, + 97,114,116,2,1,7,110,117,109,115,116,101,112,2,1,0,0,13,102,105, + 120,114,111,119,115,46,99,111,117,110,116,2,1,13,102,105,120,114,111,119, + 115,46,105,116,101,109,115,14,1,6,104,101,105,103,104,116,2,15,14,99, + 97,112,116,105,111,110,115,46,99,111,117,110,116,2,3,14,99,97,112,116, + 105,111,110,115,46,105,116,101,109,115,14,1,7,99,97,112,116,105,111,110, + 6,6,83,121,109,98,111,108,0,1,7,99,97,112,116,105,111,110,6,7, + 65,100,100,114,101,115,115,0,1,7,99,97,112,116,105,111,110,6,4,73, + 110,102,111,0,0,0,0,14,114,111,119,102,111,110,116,115,46,99,111,117, + 110,116,2,1,14,114,111,119,102,111,110,116,115,46,105,116,101,109,115,14, + 1,5,99,111,108,111,114,4,7,0,0,160,4,110,97,109,101,6,11,115, + 116,102,95,100,101,102,97,117,108,116,6,120,115,99,97,108,101,2,1,10, + 108,111,99,97,108,112,114,111,112,115,11,9,102,108,112,95,99,111,108,111, + 114,10,102,108,112,95,120,115,99,97,108,101,0,0,0,14,100,97,116,97, + 99,111,108,115,46,99,111,117,110,116,2,5,16,100,97,116,97,99,111,108, + 115,46,111,112,116,105,111,110,115,11,12,99,111,95,115,97,118,101,118,97, + 108,117,101,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95, + 99,97,110,99,111,112,121,17,99,111,95,109,111,117,115,101,115,99,114,111, + 108,108,114,111,119,0,14,100,97,116,97,99,111,108,115,46,105,116,101,109, + 115,14,7,6,115,121,109,98,111,108,1,5,119,105,100,116,104,2,111,7, + 111,112,116,105,111,110,115,11,12,99,111,95,115,97,118,101,118,97,108,117, + 101,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97, + 110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,0,8,111, + 112,116,105,111,110,115,49,11,11,99,111,49,95,114,111,119,102,111,110,116, + 14,99,111,49,95,122,101,98,114,97,99,111,108,111,114,0,8,111,110,99, + 104,97,110,103,101,7,9,115,121,109,98,111,108,99,104,97,10,119,105,100, + 103,101,116,110,97,109,101,6,6,115,121,109,98,111,108,9,100,97,116,97, + 99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116,114,105,110, + 103,100,97,116,97,108,105,115,116,0,7,7,115,121,109,97,100,100,114,1, + 5,119,105,100,116,104,3,200,0,7,111,112,116,105,111,110,115,11,11,99, + 111,95,114,101,97,100,111,110,108,121,12,99,111,95,100,114,97,119,102,111, + 99,117,115,7,99,111,95,102,105,108,108,12,99,111,95,115,97,118,101,115, + 116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,17,99,111,95,109, + 111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101, + 116,110,97,109,101,6,7,115,121,109,97,100,100,114,9,100,97,116,97,99, + 108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116,114,105,110,103, + 100,97,116,97,108,105,115,116,0,7,7,115,121,109,105,110,102,111,1,5, + 119,105,100,116,104,3,131,0,7,111,112,116,105,111,110,115,11,11,99,111, + 95,114,101,97,100,111,110,108,121,12,99,111,95,100,114,97,119,102,111,99, + 117,115,15,99,111,95,112,114,111,112,111,114,116,105,111,110,97,108,10,99, + 111,95,99,97,110,99,111,112,121,0,8,119,105,100,116,104,109,105,110,2, + 0,10,119,105,100,103,101,116,110,97,109,101,6,7,115,121,109,105,110,102, + 111,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115, + 101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,4,112,97, + 116,104,1,5,119,105,100,116,104,2,15,7,111,112,116,105,111,110,115,11, + 12,99,111,95,105,110,118,105,115,105,98,108,101,10,99,111,95,99,97,110, + 99,111,112,121,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114, + 111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,4,112,97,116,104, + 9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101, + 115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,4,108,105,110, + 101,1,5,119,105,100,116,104,2,11,7,111,112,116,105,111,110,115,11,12, + 99,111,95,105,110,118,105,115,105,98,108,101,10,99,111,95,99,97,110,99, + 111,112,121,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111, + 119,0,10,119,105,100,103,101,116,110,97,109,101,6,4,108,105,110,101,9, + 100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100,105,110,116,101, + 103,101,114,100,97,116,97,108,105,115,116,0,0,13,100,97,116,97,114,111, + 119,104,101,105,103,104,116,2,15,8,115,116,97,116,102,105,108,101,7,22, + 109,97,105,110,102,111,46,112,114,111,106,101,99,116,115,116,97,116,102,105, + 108,101,11,111,110,99,101,108,108,101,118,101,110,116,7,6,99,101,108,108, + 101,118,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,13,0,11, + 116,115,116,114,105,110,103,101,100,105,116,6,115,121,109,98,111,108,13,111, + 112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117, + 115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13, + 111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114, + 111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111, + 99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100, + 103,101,116,115,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111, + 115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8, + 116,97,98,111,114,100,101,114,2,1,7,118,105,115,105,98,108,101,8,8, + 98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,2,111,9,98,111,117,110,100,115, + 95,99,121,2,15,8,115,116,97,116,102,105,108,101,7,22,109,97,105,110, + 102,111,46,112,114,111,106,101,99,116,115,116,97,116,102,105,108,101,12,111, + 112,116,105,111,110,115,101,100,105,116,49,11,13,111,101,49,95,115,97,118, + 101,118,97,108,117,101,0,11,111,112,116,105,111,110,115,101,100,105,116,11, + 12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111, + 115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97, + 110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,24, + 111,101,95,102,111,114,99,101,114,101,116,117,114,110,99,104,101,99,107,118, + 97,108,117,101,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101, + 95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111, + 101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110, + 100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101, + 99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105, + 114,115,116,99,108,105,99,107,18,111,101,95,104,105,110,116,99,108,105,112, + 112,101,100,116,101,120,116,0,13,111,110,100,97,116,97,101,110,116,101,114, + 101,100,7,13,115,121,109,98,111,108,100,97,116,97,101,110,116,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,13,0,0,11,116,115,116,114, + 105,110,103,101,100,105,116,7,115,121,109,97,100,100,114,14,111,112,116,105, + 111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116, + 103,108,121,112,104,104,101,105,103,104,116,0,13,111,112,116,105,111,110,115, + 119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117, + 115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114, + 111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117, + 115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116, + 17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,11, + 111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97, + 109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100, + 101,114,2,2,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115, + 95,120,2,112,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,120,3,200,0,9,98,111,117,110,100,115,95,99,121,2,15, + 12,111,112,116,105,111,110,115,101,100,105,116,49,11,0,11,111,112,116,105, + 111,110,115,101,100,105,116,11,11,111,101,95,114,101,97,100,111,110,108,121, + 12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111, + 115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97, + 110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12, + 111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101, + 116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105, + 116,111,110,99,117,114,115,111,114,18,111,101,95,104,105,110,116,99,108,105, + 112,112,101,100,116,101,120,116,0,9,116,101,120,116,102,108,97,103,115,11, + 12,116,102,95,121,99,101,110,116,101,114,101,100,11,116,102,95,110,111,115, + 101,108,101,99,116,14,116,102,95,101,108,108,105,112,115,101,108,101,102,116, + 0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,13,0,0,11, + 116,115,116,114,105,110,103,101,100,105,116,7,115,121,109,105,110,102,111,14, + 111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95, + 102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,13,111,112,116, + 105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101, + 102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119, + 95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119, + 102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117, + 115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107, + 95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97, + 98,111,114,100,101,114,2,3,7,118,105,115,105,98,108,101,8,8,98,111, + 117,110,100,115,95,120,3,57,1,8,98,111,117,110,100,115,95,121,2,0, + 9,98,111,117,110,100,115,95,99,120,3,131,0,9,98,111,117,110,100,115, + 95,99,121,2,15,12,111,112,116,105,111,110,115,101,100,105,116,49,11,0, + 11,111,112,116,105,111,110,115,101,100,105,116,11,11,111,101,95,114,101,97, + 100,111,110,108,121,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111, + 101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99, + 107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101, + 116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101, + 95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111, + 101,95,101,120,105,116,111,110,99,117,114,115,111,114,18,111,101,95,104,105, + 110,116,99,108,105,112,112,101,100,116,101,120,116,0,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,13,0,0,11,116,115,116,114,105,110,103, + 101,100,105,116,4,112,97,116,104,14,111,112,116,105,111,110,115,119,105,100, + 103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104, + 101,105,103,104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19, + 111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0, + 8,116,97,98,111,114,100,101,114,2,4,7,118,105,115,105,98,108,101,8, + 8,98,111,117,110,100,115,95,120,3,189,1,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,120,2,15,9,98,111,117,110, + 100,115,95,99,121,2,15,12,111,112,116,105,111,110,115,101,100,105,116,49, + 11,0,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117, + 110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101, + 114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14, + 111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97, + 116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101, + 99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117, + 114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111, + 101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111, + 115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,13,0,0,12,116,105, + 110,116,101,103,101,114,101,100,105,116,4,108,105,110,101,14,111,112,116,105, + 111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116, + 103,108,121,112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110,115, + 115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111, + 110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,5,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,205,1,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2, + 11,9,98,111,117,110,100,115,95,99,121,2,15,12,111,112,116,105,111,110, + 115,101,100,105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105,116, + 11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108, + 111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99, + 97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110, + 12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115, + 101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120, + 105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101, + 110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111, + 101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99, + 108,105,99,107,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 13,0,0,0,10,116,112,111,112,117,112,109,101,110,117,11,116,112,111,112, + 117,112,109,101,110,117,49,18,109,101,110,117,46,115,117,98,109,101,110,117, + 46,99,111,117,110,116,2,1,18,109,101,110,117,46,115,117,98,109,101,110, + 117,46,105,116,101,109,115,14,1,7,99,97,112,116,105,111,110,6,10,68, + 101,108,101,116,101,32,97,108,108,5,115,116,97,116,101,11,15,97,115,95, + 108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97, + 108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116, + 101,7,11,100,101,108,101,116,101,97,108,108,101,120,0,0,4,108,101,102, + 116,2,80,3,116,111,112,2,72,0,0,16,116,115,116,114,105,110,103,99, + 111,110,116,97,105,110,101,114,1,99,12,115,116,114,105,110,103,115,46,100, + 97,116,97,1,6,15,71,68,66,32,110,111,116,32,97,99,116,105,118,101, + 46,6,34,68,111,32,121,111,117,32,119,105,115,104,32,116,111,32,100,101, + 108,101,116,101,32,97,108,108,32,115,121,109,98,111,108,115,63,0,4,108, + 101,102,116,3,192,0,3,116,111,112,2,56,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tsymbolfo,''); +end. diff --git a/mseide-msegui/apps/ide/syntaxdefs/cpp.sdef b/mseide-msegui/apps/ide/syntaxdefs/cpp.sdef new file mode 100644 index 0000000..51ee909 --- /dev/null +++ b/mseide-msegui/apps/ide/syntaxdefs/cpp.sdef @@ -0,0 +1,80 @@ +styles + default '' + words 'b' + comment 'i' cl_blue + macros 'b' cl_blue + string '' cl_blue + +keyworddefs cpp + '__asm' '_asm' 'asm' 'auto' 'break' 'case' 'catch' 'cdecl' 'char' 'class' 'const' words + 'continue' '__cs' '_cs' 'default' 'delete' 'do' 'double' '__ds' '_ds' 'else' words + 'enum' 'extern' '__far' '_far' 'far' '__fastcall' '_fastcall' 'fastcall' '__finally' words + 'float' 'for' 'friend' 'goto' 'huge' '__huge' '_huge' 'if' '__import' 'inline' words + 'int' 'interrupt' '__interrupt' '_interrupt' '__loaddds' '_loadds' 'long' 'near' words + '_near' '__near' 'new' 'operator' '__pascal' '_pascal' 'pascal' 'private' 'protected' words + 'public' 'register' 'return' '__rtti' '__saveregs' '_saveregs' '__seg' '_seg' 'short' words + 'signed' 'sizeof' '__ss' '_ss' 'static' '__stdcall' '_stdcall' 'struct' 'switch' words + 'template' 'this' '__thread' 'throw' '__try' 'try' 'typedef' 'union' 'unsigned' words + 'virtual' 'void' 'volatile' 'while' words + +scope escapechar string + endtokens +# return on any char + +scope string string + calltokens + '\' escapechar + endtokens + '"' + +scope string1 string + calltokens + '\' escapechar + endtokens + '''' + +scope comment1 comment + endtokens + '*/' + +scope comment2 comment + endtokens + '' + +scope macros macros + + jumptokens + '/*' comment1 + '//' comment2 + + endtokens + '' +scope block + keywords + cpp + + calltokens + '/*' comment1 + '//' comment2 + '#' macros + '"' string + '''' string1 + '{' block default + + endtokens + '}' default + +scope main + + keywords words + cpp + + calltokens + '/*' comment1 + '//' comment2 + '#' macros + '"' string + '''' string1 + '{' block default + + diff --git a/mseide-msegui/apps/ide/syntaxdefs/glsl.sdef b/mseide-msegui/apps/ide/syntaxdefs/glsl.sdef new file mode 100644 index 0000000..ad39fe5 --- /dev/null +++ b/mseide-msegui/apps/ide/syntaxdefs/glsl.sdef @@ -0,0 +1,88 @@ +styles + default '' + words 'b' + comment 'i' cl_blue + macros 'b' cl_blue + string '' cl_blue + +keyworddefs glsl + 'and' 'attribute' 'bool' 'break' 'bvec2' 'bvec3' 'bvec4' 'case' 'centroid' words + 'const' 'continue' 'default' 'discard' 'dmat2' 'dmat2x2' 'dmat2x3' 'dmat2x4' words + 'dmat3' 'dmat3x2' 'dmat3x3' 'dmat3x4' 'dmat4' 'dmat4x2' 'dmat4x3' 'dmat4x4' words + 'do' 'double' 'dvec2' 'dvec3' 'dvec4' 'else' 'flat' 'float' 'for' 'highp' words + 'if' 'in' 'inout' 'int' 'invariant' 'isampler1D' 'isampler1DArray' 'isampler2D' words + 'isampler2DArray' 'isampler2DMS' 'isampler2DMSArray' 'isampler2DRect' 'isampler3D' words + 'isamplerBuffer' 'isamplerCube' 'isamplerCubeArray' 'ivec2' 'ivec3' 'ivec4' words + 'layout' 'lowp' 'mat2' 'mat2x2' 'mat2x3' 'mat2x4' 'mat3' 'mat3x2' 'mat3x3' words + 'mat3x4' 'mat4' 'mat4x2' 'mat4x3' 'mat4x4' 'mediump' 'noperspective' 'out' words + 'patch' 'precision' 'return' 'sample' 'sampler1D' 'sampler1DArray' 'sampler1DArrayShadow' words + 'sampler1DShadow' 'sampler2D' 'sampler2DArray' 'sampler2DArrayShadow' 'sampler2DMS' words + 'sampler2DMSArray' 'sampler2DRect' 'sampler2DRectShadow' 'sampler2DShadow' 'sampler3D' words + 'samplerBuffer' 'samplerCube' 'samplerCubeArray' 'samplerCubeArrayShadow' words + 'samplerCubeShadow' 'smooth' 'struct' 'subroutine' 'switch' 'uint' 'uniform' words + 'usampler1D' 'usampler1DArray' 'usampler2D' 'usampler2DArray' 'usampler2DMS' words + 'usampler2DMSarray' 'usampler2DRect' 'usampler3D' 'usamplerBuffer' 'usamplerCube' words + 'usamplerCubeArray' 'uvec2' 'uvec3' 'uvec4' 'varying' 'vec2' 'vec3' words + 'vec4' 'void' 'while' 'true' 'false' words + +scope escapechar string + endtokens +# return on any char + +scope string string + calltokens + '\' escapechar + endtokens + '"' + +scope string1 string + calltokens + '\' escapechar + endtokens + '''' + +scope comment1 comment + endtokens + '*/' + +scope comment2 comment + endtokens + '' + +scope macros macros + + jumptokens + '/*' comment1 + '//' comment2 + + endtokens + '' + +scope block + keywords + glsl + + calltokens + '/*' comment1 + '//' comment2 + '#' macros + '"' string + '''' string1 + '{' block default + + endtokens + '}' default + +scope main + + keywords words + glsl + + calltokens + '/*' comment1 + '//' comment2 + '#' macros + '"' string + '''' string1 + '{' block default + diff --git a/mseide-msegui/apps/ide/syntaxdefs/grammar.sdef b/mseide-msegui/apps/ide/syntaxdefs/grammar.sdef new file mode 100644 index 0000000..1bde6cd --- /dev/null +++ b/mseide-msegui/apps/ide/syntaxdefs/grammar.sdef @@ -0,0 +1,54 @@ +caseinsensitive +styles + default '' + words 'b' + comment 'i' cl_dkblue + option 'b' cl_dkblue + string '' cl_dkblue + number '' cl_dkred + +keyworddefs grammar + +scope comment2 comment + endtokens + '' + +scope string string + endtokens + '''' '' + +scope hexnumber + jumptokens + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' 'A' 'B' 'C' 'D' 'E' 'F' hexnumber + return + +scope number + jumptokens + '$' hexnumber + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' number + return + +scope word + jumptokens + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' + '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' 'Z' '_' word + return + +scope op number + return + +scope main + + keywords words + grammar + + calltokens + '//' comment2 + '''' string + '#' number string + '"' op + '{' op + '}' op + '@' op + '$' op diff --git a/mseide-msegui/apps/ide/syntaxdefs/ipf.sdef b/mseide-msegui/apps/ide/syntaxdefs/ipf.sdef new file mode 100644 index 0000000..fcd479b --- /dev/null +++ b/mseide-msegui/apps/ide/syntaxdefs/ipf.sdef @@ -0,0 +1,96 @@ +# MSEide syntaxdefinition for IPF format + +STYLES + default '' + words 'b' + comment 'i' cl_dkcyan + tag 'b' cl_dkblue + string '' cl_dkblue + macro '' cl_dkmagenta + +ADDKEYWORDCHARS + '.' + +KEYWORDDEFS control + '.br' '.ce' '.nameit' + +SCOPE tag tag + ENDTOKENS + '.' + +SCOPE comment1 comment + endtokens + '' + +SCOPE macro macro + endtokens + '.' + +SCOPE main + + KEYWORDS tag + control + + CALLTOKENS + ':a' tag +# ':acviewport' tag +# ':artlink' tag +# ':artwork' tag + ':c' tag +# ':caution' tag +# ':cgraphic' tag +# ':color' tag +# ':ctrl' tag +# ':ctrldef' tag + ':d' tag +# ':ddf' tag +# ':dl' tag +# ':docprof' tag + ':e' tag + ':f' tag +# ':fig' tag +# ':figcap' tag +# ':font' tag +# ':fn' tag + ':h' tag +# ':h' tag +# ':hdref' tag +# ':hide' tag +# ':hp' tag + ':i' tag +# ':i' tag +# ':icmd' tag +# ':isyn' tag + ':l' tag +# ':li' tag +# ':lines' tag +# ':link' tag +# ':lm' tag +# ':lp' tag + ':n' tag +# ':note' tag +# ':nt' tag + ':o' tag +# ':ol' tag + ':p' tag +# ':p' tag +# ':parml' tag +# ':pbutton' tag +# ':pd' tag +# ':pt' tag +# ':rm' tag + ':s' tag +# ':sl' tag + ':t' tag +# ':table' tag +# ':title' tag + ':u' tag +# ':ul' tag +# ':userdoc' tag + ':w' tag +# ':warning' tag + ':x' tag +# ':xmp' tag + + '.*' comment1 + '&' macro diff --git a/mseide-msegui/apps/ide/syntaxdefs/ipf2.sdef b/mseide-msegui/apps/ide/syntaxdefs/ipf2.sdef new file mode 100644 index 0000000..3c1ccfc --- /dev/null +++ b/mseide-msegui/apps/ide/syntaxdefs/ipf2.sdef @@ -0,0 +1,131 @@ +# MSEide syntaxdefinition for IPF format + +# Define the textstyles +STYLES + default '' + words 'b' + comment 'i' cl_dkcyan + tag 'b' cl_dkblue + tagparams '' cl_dkblue +# RGB value + string '' $600000 + macro '' cl_dkmagenta + +# Add '.' to the allowed characters in keywords. +# Default is ['A'..'Z','a'..'z','0'..'9','_'] +ADDKEYWORDCHARS + '.' + +# Define control keywords +KEYWORDDEFS control + '.br' '.ce' '.nameit' + +# Scopes must be defined before they can be referenced + +# Define scope string with text style string +scope string string + endtokens + '''' '' + +# Define the scope paramend with no text style +SCOPE paramend + RETURN +# No endtokens, scope terminates imediately + +# Define the scope tagparams with the text style tagparams +SCOPE tagparams tagparams + CALLTOKENS + '''' string + JUMPTOKENS +# Jump to scope paramend with text style tag + '.' paramend tag + +# Define the scope tag with text style tag +SCOPE tag tag + ENDTOKENS + '.' + JUMPTOKENS +# Space -> tagprams scope + ' ' tagparams +# End of line -> tagprams scope + '' tagparams + +SCOPE comment1 comment + endtokens + '' + +SCOPE macro macro + endtokens + '.' + +# Coloring starts with the last scope, the name is irrelevant +SCOPE main + +# Keywords used in ths scope with text style tag + KEYWORDS tag + control + + CALLTOKENS + ':a' tag +# ':acviewport' tag +# ':artlink' tag +# ':artwork' tag + ':c' tag +# ':caution' tag +# ':cgraphic' tag +# ':color' tag +# ':ctrl' tag +# ':ctrldef' tag + ':d' tag +# ':ddf' tag +# ':dl' tag +# ':docprof' tag + ':e' tag + ':f' tag +# ':fig' tag +# ':figcap' tag +# ':font' tag +# ':fn' tag + ':h' tag +# ':h' tag +# ':hdref' tag +# ':hide' tag +# ':hp' tag + ':i' tag +# ':i' tag +# ':icmd' tag +# ':isyn' tag + ':l' tag +# ':li' tag +# ':lines' tag +# ':link' tag +# ':lm' tag +# ':lp' tag + ':n' tag +# ':note' tag +# ':nt' tag + ':o' tag +# ':ol' tag + ':p' tag +# ':p' tag +# ':parml' tag +# ':pbutton' tag +# ':pd' tag +# ':pt' tag +# ':rm' tag + ':s' tag +# ':sl' tag + ':t' tag +# ':table' tag +# ':title' tag + ':u' tag +# ':ul' tag +# ':userdoc' tag + ':w' tag +# ':warning' tag + ':x' tag +# ':xmp' tag + + '.*' comment1 + '&' macro + diff --git a/mseide-msegui/apps/ide/syntaxdefs/java.sdef b/mseide-msegui/apps/ide/syntaxdefs/java.sdef new file mode 100644 index 0000000..0d585aa --- /dev/null +++ b/mseide-msegui/apps/ide/syntaxdefs/java.sdef @@ -0,0 +1,85 @@ +styles + default '' + words 'b' + type 'b' + comment 'i' cl_dkblue + macros 'b' cl_dkred + string '' cl_dkblue + +keyworddefs java + 'abstract' 'assert' 'byte' 'break' 'case' 'catch' 'char' 'const' + 'continue' 'default' 'delete' 'do' 'double' 'else' + 'enum' 'extends' 'instanceof' 'fastcall' 'finally' + 'for' 'false' 'goto' 'if' 'import' 'inline' 'interface' + 'implements' 'interrupt' 'long' 'near' 'new' 'null' 'protected' + 'strictfp' 'return' 'synchronized' 'this' 'throw' 'throws' 'try' 'transient' 'volatile' 'while' + +keyworddefs javaplus + 'void' 'public' 'package' 'private' 'final' 'class' 'static' 'boolean' 'int' 'native' 'float' + +scope escapechar string + endtokens +# return on any char + +scope string string + calltokens + '\' escapechar + endtokens + '"' + +scope string1 string + calltokens + '\' escapechar + endtokens + '''' + +scope comment1 comment + endtokens + '*/' + +scope comment2 comment + endtokens + '' + +scope method1 type + return + +scope macros macros + + jumptokens + '/*' comment1 + '//' comment2 + + endtokens + '' +scope block + keywords + java + javaplus type + + calltokens + '/*' comment1 + '//' comment2 + '#' macros + '"' string + '''' string1 + '{' block default + + endtokens + '}' default + +scope main + + keywords words + java + + javaplus type + + calltokens + '/*' comment1 + '//' comment2 + '#' macros + '"' string + '''' string1 + + diff --git a/mseide-msegui/apps/ide/syntaxdefs/llvm.sdef b/mseide-msegui/apps/ide/syntaxdefs/llvm.sdef new file mode 100644 index 0000000..8e2a47e --- /dev/null +++ b/mseide-msegui/apps/ide/syntaxdefs/llvm.sdef @@ -0,0 +1,45 @@ +caseinsensitive +styles + default '' + words 'b' + comment 'i' cl_dkblue + option 'b' cl_dkblue + string '' cl_dkblue + +keyworddefs llvm + 'RET' 'BR' 'SWITCH' 'INDIRECTBR' 'INVOKE' 'RESUME' 'UNREACHABLE' + 'ADD' 'FADD' 'SUB' 'FSUB' 'MUL' 'FMUL' 'UDIV' 'SDIV' + 'FDIF' 'UREM' 'SREM' 'FREM' 'SHL' 'LSHR' 'ASHR' 'AND' 'OR' 'XOR' + 'EXTRACTELEMENT' 'INSERTELEMENT' 'SHUFFLEVECTOR' + 'EXTRACTVALUE' 'INSERTVALUE' + 'ALLOCA' 'LOAD' 'STORE' 'FENCE' 'CMPXCHG' 'ATOMICRMW' 'GETELEMENTPTR' + 'TRUNC' 'TO' 'ZEXZ' 'SEXT' 'FPTRUNC' 'FPEXT' 'FPTOUI' 'FPTOSI' + 'UITOFP' 'SITOFP' 'PTRTOINT' 'INTTOPTR' 'BITCAST' 'ADDRSPACECAST' + 'ICMP' 'FCMP' 'PHI' 'SELECT' 'CALL' 'VA_ARG' 'LANDINGPAD' + 'LLVM' 'VA_START' 'VA_END' 'VA_COPY' 'GCROOT' 'GCREAD' 'GCWRITE' + 'RETURNADDRESS' 'FRAMEADDRESS' 'READ_REGISTER' 'WRITE_REGISTER' + 'STACKSAVE' 'STACKRESTORE' 'PREFETCH' 'PCMARKER' 'READCYCLECOUNTER' + 'CLEAR_CACHE' 'INSTRPROF_INCREMENT' + 'MEMCPY' 'MEMMOVE' 'MEMSET' 'SQRT' 'POWI' 'SIN' 'COS' 'POW' 'EXP' 'EXP2' + 'LOG' 'LOG10' 'LOG2' 'FMA' 'FABS' 'MINNUM' 'MAXNUM' 'COPYSIGN' 'FLOOR' 'CEIL' + 'TRUNC' 'RINT' 'NEARBYINT' 'ROUND' + 'BSWAP' 'CTPOP' 'CTLZ' 'CTTZ' + 'WITH' 'OVERFLOW' 'SADD' 'UADD' 'SSUB' 'USUB' 'SMUL' 'UMUL' + 'FMULADD' + 'CONVERT' 'FROM' 'FP16' + 'INIT' 'TRAMPOLINE' 'ADJUST' + 'LIFETIME' 'START' 'END' 'INVARIANT' + 'VAR' 'ANNOTATION' 'PTR' 'TRAP' 'DEBUGTRAP' 'STACKPROTECTOR' + 'STACKPROTECTORCHECK' 'OBJECTSIZE' 'EXPECT' 'ASSUME' 'DONOTHING' + +scope comment1 comment + endtokens + '' + +scope main + + keywords words + llvm + calltokens + ';' comment1 + diff --git a/mseide-msegui/apps/ide/syntaxdefs/mselang.sdef b/mseide-msegui/apps/ide/syntaxdefs/mselang.sdef new file mode 100644 index 0000000..f4356c0 --- /dev/null +++ b/mseide-msegui/apps/ide/syntaxdefs/mselang.sdef @@ -0,0 +1,107 @@ +caseinsensitive +colors cl_default cl_default cl_default cl_default +pairwords + 'BEGIN' 'CASE' 'TRY' 'RECORD' 'CLASS' 'OBJECT' 'INTERFACE' 'END' + 'REPEAT' 'UNTIL' + +styles + default '' + words 'b' + comment 'i' cl_dkblue + option 'b' cl_dkblue + string '' cl_dkblue + number '' cl_dkred + +keyworddefs pascal + 'ABSOLUTE' 'ABSTRACT' 'AND' 'ARRAY' 'AS' 'ASM' 'ASSEMBLER' 'BEGIN' + 'BREAK' 'CASE' 'CDECL' 'CLASS' 'CONST' 'CONSTREF' 'CONSTRUCTOR' + 'CONTINUE' 'DEFAULT' 'DEPRECATED' 'DESTRUCTOR' 'DISPOSE' 'DIV' 'DO' 'DOWNTO' + 'ELSE' 'END' 'EXCEPT' 'EXIT' 'EXPORT' 'EXPORTS' 'EXTERNAL' 'FAIL' + 'FALSE' 'FAR' 'FILE' 'FINALIZATION' 'FINALLY' 'FOR' 'FORWARD' 'FUNCTION' 'GOTO' + 'IF' 'IMPLEMENTATION' 'IMPLEMENTS' 'IN' 'INHERITED' + 'INITIALIZATION' 'INLINE' 'INTERFACE' 'INTERRUPT' 'IS' 'LABEL' 'LIBRARY' + 'METHOD' 'MOD' 'NEW' 'NIL' 'NODEFAULT' 'NOT' 'OBJECT' + 'OF' 'ON' 'OPERATOR' 'OR' 'OUT' 'OTHERWISE' 'OVERLOAD' 'OVERRIDE' + 'PACKED' 'POPSTACK' 'PRIVATE' + 'PROCEDURE' 'PROGRAM' 'PROTECTED' + 'PUBLIC' 'PUBLISHED' 'RAISE' 'RECORD' 'REINTRODUCE' 'REPEAT' + 'RESOURCESTRING' + 'SELF' 'SET' 'SHL' 'SHR' + 'STDCALL' 'THEN' 'THREADVAR' 'TO' 'TRUE' 'TRY' 'TYPE' 'UNIT' 'UNTIL' + 'USES' 'VAR' 'VIRTUAL' 'WHILE' 'WITH' 'XOR' + +keyworddefs property + 'DEFAULT' 'INDEX' 'READ' 'STORED' 'WRITE' + +scope option option + endtokens + '}' + +scope comment1 comment + endtokens + '}' + +scope comment2 comment + endtokens + '' + +scope comment3 comment + endtokens + '*)' + +scope string string + endtokens + '''' '' + +scope hexnumber + jumptokens + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' 'A' 'B' 'C' 'D' 'E' 'F' hexnumber + return + +scope number + jumptokens + '$' hexnumber + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' number + return + +scope word + jumptokens + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' + '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' 'Z' '_' word + return + +scope property1 default + keywords words + property + calltokens + '{$' option + '{' comment1 + '//' comment2 + '(*' comment3 + endtokens + ';' + +scope property words + jumptokens + property1 + + +scope main + + keywords words + pascal + + calltokens + '{$' option + '{' comment1 + '//' comment2 + '(*' comment3 + '''' string + '#' number string + .'property'. property + +# '$' hexnumber number +# '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' number number +# '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' 'Z' '_' word diff --git a/mseide-msegui/apps/ide/syntaxdefs/objecttext.sdef b/mseide-msegui/apps/ide/syntaxdefs/objecttext.sdef new file mode 100644 index 0000000..bf34ba6 --- /dev/null +++ b/mseide-msegui/apps/ide/syntaxdefs/objecttext.sdef @@ -0,0 +1,35 @@ +caseinsensitive +addkeywordchars + '()<>=' +styles + default '' + words 'b' + comment 'i' cl_dkblue + option 'b' cl_dkblue + string '' cl_dkblue + +keyworddefs objecttext + 'END' 'END>' 'INHERITED' 'INLINE' 'ITEM' 'OBJECT' +keyworddefs operators + '(' ')' '<' '>' '=' + +scope string string + endtokens + '''' '' + +scope string1 string + calltokens + '''' string + endtokens + ' ' '' + +scope main + + keywords words + objecttext + operators + + calltokens + '''' string + '#' string1 + diff --git a/mseide-msegui/apps/ide/syntaxdefs/pascal.sdef b/mseide-msegui/apps/ide/syntaxdefs/pascal.sdef new file mode 100644 index 0000000..9b43d8f --- /dev/null +++ b/mseide-msegui/apps/ide/syntaxdefs/pascal.sdef @@ -0,0 +1,107 @@ +caseinsensitive +colors cl_default cl_default cl_default cl_default +pairwords + 'BEGIN' 'CASE' 'TRY' 'RECORD' 'CLASS' 'OBJECT' 'INTERFACE' 'END' + 'REPEAT' 'UNTIL' + +styles + default '' + words 'b' + comment 'i' cl_dkblue + option 'b' cl_dkblue + string '' cl_dkblue + number '' cl_dkred + +keyworddefs pascal + 'ABSOLUTE' 'ABSTRACT' 'AND' 'ARRAY' 'AS' 'ASM' 'ASSEMBLER' 'BEGIN' + 'BREAK' 'CASE' 'CDECL' 'CLASS' 'CONST' 'CONSTREF' 'CONSTRUCTOR' + 'CONTINUE' 'DEFAULT' 'DEPRECATED' 'DESTRUCTOR' 'DISPOSE' 'DIV' 'DO' 'DOWNTO' + 'ELSE' 'END' 'EXCEPT' 'EXIT' 'EXPORT' 'EXPORTS' 'EXTERNAL' 'FAIL' + 'FALSE' 'FAR' 'FILE' 'FINALIZATION' 'FINALLY' 'FOR' 'FORWARD' 'FUNCTION' 'GOTO' + 'IF' 'IMPLEMENTATION' 'IMPLEMENTS' 'IN' 'INHERITED' + 'INITIALIZATION' 'INLINE' 'INTERFACE' 'INTERRUPT' 'IS' 'LABEL' 'LIBRARY' + 'MOD' 'NEW' 'NIL' 'NODEFAULT' 'NOT' 'OBJECT' + 'OF' 'ON' 'OPERATOR' 'OR' 'OUT' 'OTHERWISE' 'OVERLOAD' 'OVERRIDE' + 'PACKED' 'POPSTACK' 'PRIVATE' + 'PROCEDURE' 'PROGRAM' 'PROTECTED' + 'PUBLIC' 'PUBLISHED' 'RAISE' 'RECORD' 'REINTRODUCE' 'REPEAT' + 'RESOURCESTRING' + 'SELF' 'SET' 'SHL' 'SHR' + 'STDCALL' 'THEN' 'THREADVAR' 'TO' 'TRUE' 'TRY' 'TYPE' 'UNIT' 'UNTIL' + 'USES' 'VAR' 'VIRTUAL' 'WHILE' 'WITH' 'XOR' + +keyworddefs property + 'DEFAULT' 'INDEX' 'READ' 'STORED' 'WRITE' + +scope option option + endtokens + '}' + +scope comment1 comment + endtokens + '}' + +scope comment2 comment + endtokens + '' + +scope comment3 comment + endtokens + '*)' + +scope string string + endtokens + '''' '' + +scope hexnumber + jumptokens + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' 'A' 'B' 'C' 'D' 'E' 'F' hexnumber + return + +scope number + jumptokens + '$' hexnumber + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' number + return + +scope word + jumptokens + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' + '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' 'Z' '_' word + return + +scope property1 default + keywords words + property + calltokens + '{$' option + '{' comment1 + '//' comment2 + '(*' comment3 + endtokens + ';' + +scope property words + jumptokens + property1 + + +scope main + + keywords words + pascal + + calltokens + '{$' option + '{' comment1 + '//' comment2 + '(*' comment3 + '''' string + '#' number string + .'property'. property + +# '$' hexnumber number +# '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' number number +# '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' 'Z' '_' word diff --git a/mseide-msegui/apps/ide/syntaxdefs/pascal2.sdef b/mseide-msegui/apps/ide/syntaxdefs/pascal2.sdef new file mode 100644 index 0000000..7047fb6 --- /dev/null +++ b/mseide-msegui/apps/ide/syntaxdefs/pascal2.sdef @@ -0,0 +1,109 @@ +caseinsensitive +colors cl_default cl_default cl_default cl_default +pairwords + 'BEGIN' 'CASE' 'TRY' 'RECORD' 'CLASS' 'OBJECT' 'INTERFACE' 'END' + 'REPEAT' 'UNTIL' + +styles + default '' + words 'b' + comment 'i' cl_dkblue + option 'b' cl_dkblue + string '' cl_dkblue + number '' cl_dkred + +keyworddefs pascal + 'ABSOLUTE' 'ABSTRACT' 'AND' 'ARRAY' 'AS' 'ASM' 'ASSEMBLER' 'BEGIN' + 'BREAK' 'CASE' 'CDECL' 'CLASS' 'CONST' 'CONSTREF' 'CONSTRUCTOR' + 'CONTINUE' 'DEFAULT' 'DEPRECATED' 'DESTRUCTOR' 'DISPOSE' 'DIV' 'DO' 'DOWNTO' + 'ELSE' 'END' 'EXCEPT' 'EXIT' 'EXPORT' 'EXPORTS' 'EXTERNAL' 'FAIL' + 'FALSE' 'FAR' 'FILE' 'FINALIZATION' 'FINALLY' 'FOR' 'FORWARD' 'FUNCTION' 'GOTO' + 'IF' 'IMPLEMENTATION' 'IMPLEMENTS' 'IN' 'INDEX' 'INHERITED' + 'INITIALIZATION' 'INLINE' 'INTERFACE' 'INTERRUPT' 'IS' 'LABEL' 'LIBRARY' + 'MOD' 'NEW' 'NIL' 'NODEFAULT' 'NOT' 'OBJECT' + 'OF' 'ON' 'OPERATOR' 'OR' 'OUT' 'OTHERWISE' 'OVERLOAD' 'OVERRIDE' + 'PACKED' 'POPSTACK' 'PRIVATE' + 'PROCEDURE' 'PROGRAM' 'PROTECTED' + 'PUBLIC' 'PUBLISHED' 'RAISE' 'RECORD' 'REINTRODUCE' 'REPEAT' + 'RESOURCESTRING' + 'SELF' 'SET' 'SHL' 'SHR' + 'STDCALL' 'THEN' 'THREADVAR' 'TO' 'TRUE' 'TRY' 'TYPE' 'UNIT' 'UNTIL' + 'USES' 'VAR' 'VIRTUAL' 'WHILE' 'WITH' 'XOR' + +keyworddefs property + 'DEFAULT' 'READ' 'STORED' 'WRITE' + +scope option option + endtokens + '}' + +scope comment1 comment + calltokens + '{' comment1 + endtokens + '}' + +scope comment2 comment + endtokens + '' + +scope comment3 comment + endtokens + '*)' + +scope string string + endtokens + '''' '' + +scope hexnumber + jumptokens + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' 'A' 'B' 'C' 'D' 'E' 'F' hexnumber + return + +scope number + jumptokens + '$' hexnumber + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' number + return + +scope word + jumptokens + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' + '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' 'Z' '_' word + return + +scope property1 default + keywords words + property + calltokens + '{$' option + '{' comment1 + '//' comment2 + '(*' comment3 + endtokens + ';' + +scope property words + jumptokens + property1 + + +scope main + + keywords words + pascal + + calltokens + '{$' option + '{' comment1 + '//' comment2 + '(*' comment3 + '''' string + '#' number string + .'property'. property + +# '$' hexnumber number +# '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' number number +# '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' 'Z' '_' word diff --git a/mseide-msegui/apps/ide/syntaxdefs/pascal_solarized.sdef b/mseide-msegui/apps/ide/syntaxdefs/pascal_solarized.sdef new file mode 100644 index 0000000..82c4f0f --- /dev/null +++ b/mseide-msegui/apps/ide/syntaxdefs/pascal_solarized.sdef @@ -0,0 +1,170 @@ +#for nested {} comments +caseinsensitive +pairwords + 'BEGIN' 'CASE' 'TRY' 'RECORD' 'CLASS' 'OBJECT' 'INTERFACE' 'END' + 'REPEAT' 'UNTIL' + +# COLORS font/paper +COLORS $586e75 $fdf6e3 + +# base03 $002b36 +# base01 $586e75 +# base0 $839496 +# base1 $93a1a1 +# base2 $eee8d5 +# base3 $fdf6e3 +# red $dc322f +# green $859900 +# cyan $2aa198 +# blue $268bd2 + + +styles + default '' + words 'b' $859900 + comment 'i' $93a1a1 + option '' $268bd2 + string '' $2aa198 + symbol '' $dc322f + number '' $2aa198 + +keyworddefs pascal + 'ABSOLUTE' 'ABSTRACT' 'AND' 'ARRAY' 'AS' 'ASM' 'ASSEMBLER' 'BEGIN' + 'BREAK' 'CASE' 'CDECL' 'CLASS' 'CONST' 'CONSTREF' 'CONSTRUCTOR' + 'CONTINUE' 'DEFAULT' 'DEPRECATED' 'DESTRUCTOR' 'DISPOSE' 'DIV' 'DO' 'DOWNTO' + 'ELSE' 'END' 'EXCEPT' 'EXIT' 'EXPORT' 'EXPORTS' 'EXTERNAL' 'FAIL' + 'FALSE' 'FAR' 'FILE' 'FINALIZATION' 'FINALLY' 'FOR' 'FORWARD' 'FUNCTION' 'GOTO' + 'IF' 'IMPLEMENTATION' 'IMPLEMENTS' 'IN' 'INHERITED' + 'INITIALIZATION' 'INLINE' 'INTERFACE' 'INTERRUPT' 'IS' 'LABEL' 'LIBRARY' + 'MOD' 'NEW' 'NIL' 'NODEFAULT' 'NOT' 'OBJECT' + 'OF' 'ON' 'OPERATOR' 'OR' 'OUT' 'OTHERWISE' 'OVERLOAD' 'OVERRIDE' + 'PACKED' 'POPSTACK' 'PRIVATE' + 'PROCEDURE' 'PROGRAM' 'PROTECTED' + 'PUBLIC' 'PUBLISHED' 'RAISE' 'RECORD' 'REINTRODUCE' 'REPEAT' + 'RESOURCESTRING' + 'SELF' 'SET' 'SHL' 'SHR' + 'STDCALL' 'THEN' 'THREADVAR' 'TO' 'TRUE' 'TRY' 'TYPE' 'UNIT' 'UNTIL' + 'USES' 'VAR' 'VIRTUAL' 'WHILE' 'WITH' 'XOR' + +keyworddefs property + 'DEFAULT' 'INDEX' 'READ' 'STORED' 'WRITE' + +scope option option + endtokens + '}' + +scope comment1 comment + calltokens + '{' comment1 + endtokens + '}' + +scope comment2 comment + endtokens + '' + +scope comment3 comment + endtokens + '*)' + +scope string string + endtokens + '''' '' + +scope hexnumber + jumptokens + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' 'A' 'B' 'C' 'D' 'E' 'F' hexnumber + return + +scope number + jumptokens + '$' hexnumber + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' number + return + +scope symbol1 symbol + return + +scope word + jumptokens + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' + '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' 'Z' '_' word + return + +scope property2 symbol + return + +scope property1 default + keywords words + property + jumptokens + ';' property2 + calltokens + '{$' option + '{' comment1 + '//' comment2 + '(*' comment3 + '''' string + '#' number string + ':' symbol1 + '.' symbol1 + ',' symbol1 + '=' symbol1 + '<>' symbol1 + '<' symbol1 + '>' symbol1 + '(' symbol1 + ')' symbol1 + '+' symbol1 + '-' symbol1 + '/' symbol1 + '*' symbol1 + '[' symbol1 + ']' symbol1 + + '$' hexnumber number + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' number number + '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' 'Z' '_' word + +scope property words + jumptokens + property1 + + +scope main + + keywords words + pascal + + calltokens + '{$' option + '{' comment1 + '//' comment2 + '(*' comment3 + '''' string + '#' number string + ':' symbol1 + '.' symbol1 + ';' symbol1 + ',' symbol1 + '=' symbol1 + '<>' symbol1 + '<' symbol1 + '>' symbol1 + '(' symbol1 + ')' symbol1 + '+' symbol1 + '-' symbol1 + '/' symbol1 + '*' symbol1 + '[' symbol1 + ']' symbol1 + .'property'. property + + '$' hexnumber number + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' number number + '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' 'Z' '_' word + \ No newline at end of file diff --git a/mseide-msegui/apps/ide/syntaxdefs/pascal_solarized_dark.sdef b/mseide-msegui/apps/ide/syntaxdefs/pascal_solarized_dark.sdef new file mode 100644 index 0000000..4da6ad2 --- /dev/null +++ b/mseide-msegui/apps/ide/syntaxdefs/pascal_solarized_dark.sdef @@ -0,0 +1,168 @@ +#for nested {} comments +caseinsensitive +pairwords + 'BEGIN' 'CASE' 'TRY' 'RECORD' 'CLASS' 'OBJECT' 'INTERFACE' 'END' + 'REPEAT' 'UNTIL' + +# COLORS font/paper +COLORS $93a1a1 $002b36 + +# base03 $002b36 +# base01 $586e75 +# base0 $839496 +# base1 $93a1a1 +# base2 $eee8d5 +# base3 $fdf6e3 +# red $dc322f +# green $859900 +# cyan $2aa198 +# blue $268bd2 + + +styles + default '' + words 'b' $859900 + comment 'i' $586e75 + option '' $268bd2 + string '' $2aa198 + symbol '' $dc322f + number '' $2aa198 + +keyworddefs pascal + 'ABSOLUTE' 'ABSTRACT' 'AND' 'ARRAY' 'AS' 'ASM' 'ASSEMBLER' 'BEGIN' + 'BREAK' 'CASE' 'CDECL' 'CLASS' 'CONST' 'CONSTREF' 'CONSTRUCTOR' + 'CONTINUE' 'DEFAULT' 'DEPRECATED' 'DESTRUCTOR' 'DISPOSE' 'DIV' 'DO' 'DOWNTO' + 'ELSE' 'END' 'EXCEPT' 'EXIT' 'EXPORT' 'EXPORTS' 'EXTERNAL' 'FAIL' + 'FALSE' 'FAR' 'FILE' 'FINALIZATION' 'FINALLY' 'FOR' 'FORWARD' 'FUNCTION' 'GOTO' + 'IF' 'IMPLEMENTATION' 'IMPLEMENTS' 'IN' 'INHERITED' + 'INITIALIZATION' 'INLINE' 'INTERFACE' 'INTERRUPT' 'IS' 'LABEL' 'LIBRARY' + 'MOD' 'NEW' 'NIL' 'NODEFAULT' 'NOT' 'OBJECT' + 'OF' 'ON' 'OPERATOR' 'OR' 'OUT' 'OTHERWISE' 'OVERLOAD' 'OVERRIDE' + 'PACKED' 'POPSTACK' 'PRIVATE' + 'PROCEDURE' 'PROGRAM' 'PROTECTED' + 'PUBLIC' 'PUBLISHED' 'RAISE' 'RECORD' 'REINTRODUCE' 'REPEAT' + 'RESOURCESTRING' + 'SELF' 'SET' 'SHL' 'SHR' + 'STDCALL' 'THEN' 'THREADVAR' 'TO' 'TRUE' 'TRY' 'TYPE' 'UNIT' 'UNTIL' + 'USES' 'VAR' 'VIRTUAL' 'WHILE' 'WITH' 'XOR' + +keyworddefs property + 'DEFAULT' 'INDEX' 'READ' 'STORED' 'WRITE' + +scope option option + endtokens + '}' + +scope comment1 comment + calltokens + '{' comment1 + endtokens + '}' + +scope comment2 comment + endtokens + '' + +scope comment3 comment + endtokens + '*)' + +scope string string + endtokens + '''' '' + +scope hexnumber + jumptokens + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' 'A' 'B' 'C' 'D' 'E' 'F' hexnumber + return + +scope number + jumptokens + '$' hexnumber + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' number + return + +scope symbol1 symbol + return + +scope word + jumptokens + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' + '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' 'Z' '_' word + return + +scope property2 symbol + return +scope property1 default + keywords words + pascal + jumptokens + ';' property2 + calltokens + '{$' option + '{' comment1 + '//' comment2 + '(*' comment3 + '''' string + '#' number string + ':' symbol1 + '.' symbol1 + ',' symbol1 + '=' symbol1 + '<>' symbol1 + '<' symbol1 + '>' symbol1 + '(' symbol1 + ')' symbol1 + '+' symbol1 + '-' symbol1 + '/' symbol1 + '*' symbol1 + '[' symbol1 + ']' symbol1 + + '$' hexnumber number + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' number number + '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' 'Z' '_' word + +scope property words + jumptokens + property1 + + +scope main + + keywords words + pascal + + calltokens + '{$' option + '{' comment1 + '//' comment2 + '(*' comment3 + '''' string + '#' number string + ':' symbol1 + '.' symbol1 + ';' symbol1 + ',' symbol1 + '=' symbol1 + '<>' symbol1 + '<' symbol1 + '>' symbol1 + '(' symbol1 + ')' symbol1 + '+' symbol1 + '-' symbol1 + '/' symbol1 + '*' symbol1 + '[' symbol1 + ']' symbol1 + .'property'. property + + '$' hexnumber number + '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' number number + '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' 'Z' '_' word diff --git a/mseide-msegui/apps/ide/syntaxdefs/python.sdef b/mseide-msegui/apps/ide/syntaxdefs/python.sdef new file mode 100644 index 0000000..9fe6e02 --- /dev/null +++ b/mseide-msegui/apps/ide/syntaxdefs/python.sdef @@ -0,0 +1,45 @@ +# Python syntax definition +# +styles + default '' + words 'b' + comment 'i' cl_dkblue + option 'b' cl_dkblue + string '' cl_dkblue + +keyworddefs python + 'False' 'class' 'finally' 'is' 'return' + 'None' 'continue' 'for' 'lambda' 'try' + 'True' 'def' 'from' 'nonlocal' 'while' + 'and' 'del' 'global' 'not' 'with' + 'as' 'elif' 'if' 'or' 'yield' + 'assert' 'else' 'import' 'pass' + 'break' 'except' 'in' 'raise' + +scope comment1 comment + endtokens + '' +scope string1 string + endtokens + '''' '' +scope string2 string + endtokens + '"' '' +scope string3 string + endtokens + '''''''' +scope string4 string + endtokens + '"""' + +scope main + + keywords words + python + calltokens + '#' comment1 + '''''''' string3 + '''' string1 + '"""' string4 + '"' string2 + diff --git a/mseide-msegui/apps/ide/syntaxdefs/sql.sdef b/mseide-msegui/apps/ide/syntaxdefs/sql.sdef new file mode 100644 index 0000000..a953f53 --- /dev/null +++ b/mseide-msegui/apps/ide/syntaxdefs/sql.sdef @@ -0,0 +1,82 @@ +caseinsensitive +styles + default '' + words 'b' + comment 'i' cl_dkblue + option 'b' cl_dkblue + string '' cl_dkblue + +keyworddefs sql + 'ACTION' 'ACTIVE' 'ADD' 'ADMIN' 'AFTER' 'ALL' 'ALTER' 'AND' 'ANY' 'AS' 'ASC' + 'ASCENDING' 'AT' 'AUTO' 'AUTODDL' + 'AVG' 'BASED' 'BASENAME' 'BASE_NAME' 'BEFORE' 'BEGIN' 'BETWEEN' 'BLOB' + 'BLOBEDIT' 'BUFFER' 'BY' 'CACHE' + 'CASCADE' 'CASE' 'CAST' 'CHAR' 'CHARACTER' 'CHARACTER_LENGTH' 'CHAR_LENGTH' 'CHECK' + 'CHECK_POINT_LEN' + 'CHECK_POINT_LENGTH' 'COLLATE' 'COLLATION' 'COLUMN' 'COMMIT' 'COMMITTED' + 'COMPILETIME' + 'COMPUTED' 'CLOSE' 'CONDITIONAL' 'CONNECT' 'CONSTRAINT' 'CONTAINING' 'CONTINUE' + 'COUNT' 'CREATE' + 'CSTRING' 'CURRENT' 'CURRENT_DATE' 'CURRENT_TIME' 'CURRENT_TIMESTAMP' 'CURSOR' + 'DATABASE' 'DATE' 'DAY' 'DB_KEY' 'DEBUG' 'DEC' 'DECIMAL' 'DECLARE' 'DEFAULT' + 'DELETE' 'DESC' 'DESCENDING' + 'DESCRIBE' 'DESCRIPTOR' 'DISCONNECT' 'DISPLAY' 'DISTINCT' 'DO' 'DOMAIN' + 'DOUBLE' 'DROP' + 'ECHO' 'EDIT' 'ELSE' 'END' 'ENTRY_POINT' 'ESCAPE' 'EVENT' 'EXCEPTION' 'EXECUTE' + 'EXISTS' 'EXIT' 'EXTERN' 'EXTERNAL' 'EXTRACT' 'FETCH' 'FILE' 'FILTER' 'FLOAT' + 'FOR' 'FOREIGN' 'FOUND' + 'FREE_IT' 'FROM' 'FULL' 'FUNCTION' 'GDSCODE' 'GENERATOR' 'GEN_ID' 'GLOBAL' + 'GOTO' + 'GRANT' 'GROUP' 'GROUP_COMMIT_WAIT' 'GROUP_COMMIT_' 'WAIT_TIME' 'HAVING' 'HELP' + 'HOUR' 'IF' + 'IMMEDIATE' 'IN' 'INACTIVE' 'INDEX' 'INDICATOR' 'INIT' 'INNER' 'INPUT' + 'INPUT_TYPE' + 'INSERT' 'INT' 'INTEGER' 'INTO' 'IS' 'ISOLATION' 'ISQL' 'JOIN' 'KEY' + 'LC_MESSAGES' 'LC_TYPE' 'LEFT' + 'LENGTH' 'LEV' 'LEVEL' 'LIKE' 'LIMIT' + 'LOGFILE' 'LOG_BUFFER_SIZE' 'LOG_BUF_SIZE' + 'LONG' 'MANUAL' + 'MAX' 'MAXIMUM' 'MAXIMUM_SEGMENT' 'MAX_SEGMENT' 'MERGE' 'MESSAGE' 'MIN' + 'MINIMUM' 'MINUTE' + 'MODULE_NAME' 'MONTH' 'NAMES' 'NATIONAL' 'NATURAL' 'NCHAR' 'NO' 'NOAUTO' + 'NOT' + 'NULL' 'NUMERIC' 'NUM_LOG_BUFS' 'NUM_LOG_BUFFERS' 'OCTET_LENGTH' 'OF' 'ON' + 'ONLY' 'OPEN' + 'OPTION' 'OR' 'ORDER' 'OUTER' 'OUTPUT' 'OUTPUT_TYPE' 'OVERFLOW' 'PAGE' + 'PAGELENGTH' + 'PAGES' 'PAGE_SIZE' 'PARAMETER' 'PASSWORD' 'PLAN' 'POSITION' 'POST_EVENT' + 'PRECISION' 'PREPARE' + 'PROCEDURE' 'PROTECTED' 'PRIMARY' 'PRIVILEGES' 'PUBLIC' 'QUIT' + 'RAW_PARTITIONS' 'RDB$DB_KEY' 'READ' 'REAL' 'RECORD_VERSION' 'REFERENCES' + 'RELEASE' 'RESERV' 'RESERVING' 'RESTRICT' 'RETAIN' 'RETURN' + 'RETURNING_VALUES' 'RETURNS' 'REVOKE' 'RIGHT' 'ROLE' 'ROLLBACK' 'RUNTIME' + 'SCHEMA' 'SECOND' + 'SEGMENT' 'SELECT' 'SET' 'SHADOW' 'SHARED' 'SHELL' 'SHOW' 'SINGULAR' 'SIZE' + 'SMALLINT' 'SNAPSHOT' 'SOME' 'SORT' 'SQLCODE' 'SQLERROR' 'SQLWARNING' + 'STABILITY' 'STARTING' + 'STARTS' 'STATEMENT' 'STATIC' 'STATISTICS' 'SUB_TYPE' 'SUM' 'SUSPEND' + 'TABLE' 'TERMINATOR' + 'THEN' 'TIME' 'TIMESTAMP' 'TO' 'TRANSACTION' 'TRANSLATE' 'TRANSLATION' + 'TRIGGER' 'TRIM' + 'TYPE' 'UNCOMMITTED' 'UNION' 'UNIQUE' 'UPDATE' 'UPPER' 'USER' 'USING' + 'VALUE + 'VALUES' 'VARCHAR' 'VARIABLE' 'VARYING' 'VERSION' 'VIEW' 'WAIT' 'WEEKDAY' + 'WHEN' + 'WHENEVER' 'WHERE' 'WHILE' 'WITH' 'WORK' 'WRITE' 'YEAR' 'YEARDAY' + +scope comment1 comment + endtokens + '*/' + +scope string string + endtokens + '''' '' + +scope main + + keywords words + sql + calltokens + '/*' comment1 + '''' string + diff --git a/mseide-msegui/apps/ide/targetconsole.mfm b/mseide-msegui/apps/ide/targetconsole.mfm new file mode 100644 index 0000000..229144a --- /dev/null +++ b/mseide-msegui/apps/ide/targetconsole.mfm @@ -0,0 +1,113 @@ +object targetconsolefo: ttargetconsolefo + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_floatbutton, go_topbutton, go_backgroundbutton, go_nolockbutton, go_buttonhints] + popupmenu = popupmen + visible = False + bounds_x = 209 + bounds_y = 385 + bounds_cx = 368 + bounds_cy = 137 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 358 + 137 + ) + dragdock.optionsdock = [od_savepos, od_canmove, od_canfloat, od_candock, od_propsize, od_captionhint, od_childicons] + options = [fo_savepos, fo_savestate] + statfile = mainfo.projectstatfile + caption = 'Target Console' + icon.transparentcolor = -2147483642 + icon.image = { + 0000000000000000180000001800000074020000000000000000000000000000 + 00000000000000000000000000000000000000007C7C7C17FFFFFF017C7C7C01 + E8E8E816FFFFFF017C7C7C01E8E8E816FFFFFF017C7C7C01E8E8E816FFFFFF01 + 7C7C7C01E8E8E816FFFFFF017C7C7C01E8E8E816FFFFFF017C7C7C01E8E8E816 + FFFFFF017C7C7C01E8E8E816FFFFFF017C7C7C01E8E8E80CDEDEDE0156565601 + B0B0B001E8E8E807FFFFFF017C7C7C01E8E8E80CE2E2E2012D2D2D0100000001 + 222222017B7B7B01D1D1D101E8E8E804FFFFFF017C7C7C01E8E8E804D6D6D601 + E4E4E401E8E8E805E4E4E401E8E8E802BEBEBE01676767011313130104040401 + 46464601A0A0A001E4E4E401E8E8E801FFFFFF017C7C7C01E8E8E80292929201 + 141414010000000105050501414141018C8C8C01D0D0D001BABABA014E4E4E01 + BBBBBB01E8E8E804E3E3E3019F9F9F014747470104040401161616019D9D9D01 + FFFFFF017C7C7C01E8E8E80227272701545454017D7D7D015151510114141401 + 0000000314141401CDCDCD01E8E8E805DDDDDD01909090012A2A2A0100000001 + 7C7C7C01FFFFFF017C7C7C01E8E8E802C0C0C001E8E8E803E4E4E401A6A6A601 + 8282820199999901DADADA01E8E8E803E7E7E701B0B0B001575757010A0A0A01 + 0B0B0B015C5C5C01B8B8B801E8E8E801FFFFFF017C7C7C01E8E8E80CE5E5E501 + 767676011F1F1F0100000001313131018D8D8D01DDDDDD01E8E8E803FFFFFF01 + 7C7C7C01E8E8E80CDCDCDC010F0F0F0162626201BEBEBE01E8E8E806FFFFFF01 + 7C7C7C01E8E8E80CE6E6E601E0E0E001E8E8E808FFFFFF017C7C7C01E8E8E816 + FFFFFF017C7C7C01E8E8E816FFFFFF017C7C7C01E8E8E816FFFFFF017C7C7C01 + E8E8E816FFFFFF017C7C7C01E8E8E816FFFFFF017C7C7C01E8E8E816FFFFFF01 + 7C7C7C01FFFFFF17 + } + onidle = targetconsoleonidle + moduleclassname = 'tdockform' + object grid: twidgetgrid + frame.localprops = [] + frame.localprops1 = [] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 358 + bounds_cy = 137 + anchors = [] + font.name = 'stf_fixed' + font.xscale = 1 + font.localprops = [flp_xscale] + optionsgrid = [og_focuscellonenter, og_autofirstrow, og_colchangeontabkey, og_wrapcol, og_autopopup] + rowcountmax = 5000 + datacols.count = 1 + datacols.items = < + item[terminal] + width = 3000 + options = [co_fill, co_savestate, co_mousescrollrow] + widthmin = 3000 + widgetname = 'terminal' + dataclass = tgridrichstringdatalist + end> + datarowlinewidth = 0 + datarowheight = 14 + reffontheight = 14 + object terminal: tterminal + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 3000 + bounds_cy = 14 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate, oe1_checkvalueafterstatread] + maxchars = 120 + onsendtext = sendtext + reffontheight = 14 + end + end + object popupmen: tpopupmenu + onupdate = popupupdateexe + menu.submenu.count = 5 + menu.submenu.items = < + item + action = actionsmo.find + end + item + action = actionsmo.repeatfind + end + item + action = actionsmo.findback + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = '&Clear' + state = [as_localcaption, as_localonexecute] + onexecute = clearexe + end> + left = 32 + top = 32 + end +end diff --git a/mseide-msegui/apps/ide/targetconsole.pas b/mseide-msegui/apps/ide/targetconsole.pas new file mode 100644 index 0000000..83ec65d --- /dev/null +++ b/mseide-msegui/apps/ide/targetconsole.pas @@ -0,0 +1,153 @@ +{ MSEide Copyright (c) 1999-2013 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit targetconsole; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msegui,mseclasses,mseforms,mseterminal,msewidgetgrid,msestrings,msedatalist, + classes,mclasses,msemenus,msestat,msetypes; + +type + ttargetconsolefo = class(tdockform) + terminal: tterminal; + grid: twidgetgrid; + popupmen: tpopupmenu; + procedure sendtext(const sender: tobject; var atext: msestring; + var donotsend: Boolean); + procedure targetconsoleonidle(var again: Boolean); + procedure clearexe(const sender: TObject); + procedure popupupdateexe(const sender: tcustommenu); + private + fbuffer: tmsestringdatalist; + ffindpos: gridcoordty; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure clear; + procedure addtext(const atext: string); + procedure dofind; + procedure repeatfind; + procedure findback; + end; + +var + targetconsolefo: ttargetconsolefo; + +procedure updatestat(const statfiler: tstatfiler); + +implementation +uses + targetconsole_mfm,msegdbutils,main,finddialogform,projectoptionsform, + actionsmodule,sourcepage; + +procedure updatestat(const statfiler: tstatfiler); +begin + updatefindvalues(statfiler,projectoptions.targetconsolefindinfo); +end; + +procedure ttargetconsolefo.sendtext(const sender: tobject; + var atext: msestring; var donotsend: Boolean); +begin + mainfo.gdb.targetwriteln(ansistring(atext)); + donotsend:= true; + terminal.inputcolindex:= length(terminal.text); + terminal.addline(''); +end; + +procedure ttargetconsolefo.clear; +begin + grid.clear; +end; + +procedure ttargetconsolefo.addtext(const atext: string); +begin + fbuffer.addchars(msestring(atext)); +end; + +constructor ttargetconsolefo.create(aowner: tcomponent); +begin + fbuffer:= tmsestringdatalist.create; + fbuffer.maxcount:= 600; + inherited create(aowner); +end; + +destructor ttargetconsolefo.destroy; +begin + inherited; + fbuffer.free; +end; + +procedure ttargetconsolefo.targetconsoleonidle(var again: Boolean); +var + int1: integer; +begin + if fbuffer.count > 0 then begin + terminal.beginupdate; + try + for int1:= 0 to fbuffer.count - 2 do begin + terminal.addchars(fbuffer[int1]+lineend); + end; + terminal.addchars(fbuffer[fbuffer.count-1]); + fbuffer.clear; + finally + terminal.endupdate; + end; + end; +end; + +procedure ttargetconsolefo.clearexe(const sender: TObject); +begin + grid.clear; +end; + +procedure ttargetconsolefo.dofind; +var + ainfo: findinfoty; +begin + ainfo:= projectoptions.targetconsolefindinfo; + if not terminal.hasselection then begin + ainfo.selectedonly:= false; + end; +// ainfo.text:= edit.selectedtext; + if finddialogexecute(ainfo) then begin + projectoptions.targetconsolefindinfo:= ainfo; + findintextedit(terminal,projectoptions.targetconsolefindinfo,ffindpos); + end; +end; + +procedure ttargetconsolefo.repeatfind; +begin + findintextedit(terminal,projectoptions.targetconsolefindinfo,ffindpos); +end; + +procedure ttargetconsolefo.findback; +begin + findintextedit(terminal,projectoptions.targetconsolefindinfo,ffindpos,true); +end; + +procedure ttargetconsolefo.popupupdateexe(const sender: tcustommenu); +begin + with actionsmo do begin + find.enabled:= true; + repeatfind.enabled:= true; + findback.enabled:= true; + end; +end; + +end. diff --git a/mseide-msegui/apps/ide/targetconsole_mfm.pas b/mseide-msegui/apps/ide/targetconsole_mfm.pas new file mode 100644 index 0000000..819eab7 --- /dev/null +++ b/mseide-msegui/apps/ide/targetconsole_mfm.pas @@ -0,0 +1,139 @@ +unit targetconsole_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,targetconsole; + +const + objdata: record size: integer; data: array[0..2424] of byte end = + (size: 2425; data: ( + 84,80,70,48,16,116,116,97,114,103,101,116,99,111,110,115,111,108,101,102, + 111,15,116,97,114,103,101,116,99,111,110,115,111,108,101,102,111,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,15,102,114,97, + 109,101,46,103,114,105,112,95,115,105,122,101,2,10,18,102,114,97,109,101, + 46,103,114,105,112,95,111,112,116,105,111,110,115,11,14,103,111,95,99,108, + 111,115,101,98,117,116,116,111,110,16,103,111,95,102,105,120,115,105,122,101, + 98,117,116,116,111,110,14,103,111,95,102,108,111,97,116,98,117,116,116,111, + 110,12,103,111,95,116,111,112,98,117,116,116,111,110,19,103,111,95,98,97, + 99,107,103,114,111,117,110,100,98,117,116,116,111,110,15,103,111,95,110,111, + 108,111,99,107,98,117,116,116,111,110,14,103,111,95,98,117,116,116,111,110, + 104,105,110,116,115,0,9,112,111,112,117,112,109,101,110,117,7,8,112,111, + 112,117,112,109,101,110,7,118,105,115,105,98,108,101,8,8,98,111,117,110, + 100,115,95,120,3,209,0,8,98,111,117,110,100,115,95,121,3,129,1,9, + 98,111,117,110,100,115,95,99,120,3,112,1,9,98,111,117,110,100,115,95, + 99,121,3,137,0,26,99,111,110,116,97,105,110,101,114,46,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,0,27,99,111,110,116,97, + 105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100, + 115,1,2,0,2,0,3,102,1,3,137,0,0,20,100,114,97,103,100,111, + 99,107,46,111,112,116,105,111,110,115,100,111,99,107,11,10,111,100,95,115, + 97,118,101,112,111,115,10,111,100,95,99,97,110,109,111,118,101,11,111,100, + 95,99,97,110,102,108,111,97,116,10,111,100,95,99,97,110,100,111,99,107, + 11,111,100,95,112,114,111,112,115,105,122,101,14,111,100,95,99,97,112,116, + 105,111,110,104,105,110,116,13,111,100,95,99,104,105,108,100,105,99,111,110, + 115,0,7,111,112,116,105,111,110,115,11,10,102,111,95,115,97,118,101,112, + 111,115,12,102,111,95,115,97,118,101,115,116,97,116,101,0,8,115,116,97, + 116,102,105,108,101,7,22,109,97,105,110,102,111,46,112,114,111,106,101,99, + 116,115,116,97,116,102,105,108,101,7,99,97,112,116,105,111,110,6,14,84, + 97,114,103,101,116,32,67,111,110,115,111,108,101,21,105,99,111,110,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 10,105,99,111,110,46,105,109,97,103,101,10,168,2,0,0,0,0,0,0, + 0,0,0,0,24,0,0,0,24,0,0,0,116,2,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,124,124,124,23,255,255,255,1,124,124,124,1, + 232,232,232,22,255,255,255,1,124,124,124,1,232,232,232,22,255,255,255,1, + 124,124,124,1,232,232,232,22,255,255,255,1,124,124,124,1,232,232,232,22, + 255,255,255,1,124,124,124,1,232,232,232,22,255,255,255,1,124,124,124,1, + 232,232,232,22,255,255,255,1,124,124,124,1,232,232,232,22,255,255,255,1, + 124,124,124,1,232,232,232,12,222,222,222,1,86,86,86,1,176,176,176,1, + 232,232,232,7,255,255,255,1,124,124,124,1,232,232,232,12,226,226,226,1, + 45,45,45,1,0,0,0,1,34,34,34,1,123,123,123,1,209,209,209,1, + 232,232,232,4,255,255,255,1,124,124,124,1,232,232,232,4,214,214,214,1, + 228,228,228,1,232,232,232,5,228,228,228,1,232,232,232,2,190,190,190,1, + 103,103,103,1,19,19,19,1,4,4,4,1,70,70,70,1,160,160,160,1, + 228,228,228,1,232,232,232,1,255,255,255,1,124,124,124,1,232,232,232,2, + 146,146,146,1,20,20,20,1,0,0,0,1,5,5,5,1,65,65,65,1, + 140,140,140,1,208,208,208,1,186,186,186,1,78,78,78,1,187,187,187,1, + 232,232,232,4,227,227,227,1,159,159,159,1,71,71,71,1,4,4,4,1, + 22,22,22,1,157,157,157,1,255,255,255,1,124,124,124,1,232,232,232,2, + 39,39,39,1,84,84,84,1,125,125,125,1,81,81,81,1,20,20,20,1, + 0,0,0,3,20,20,20,1,205,205,205,1,232,232,232,5,221,221,221,1, + 144,144,144,1,42,42,42,1,0,0,0,1,124,124,124,1,255,255,255,1, + 124,124,124,1,232,232,232,2,192,192,192,1,232,232,232,3,228,228,228,1, + 166,166,166,1,130,130,130,1,153,153,153,1,218,218,218,1,232,232,232,3, + 231,231,231,1,176,176,176,1,87,87,87,1,10,10,10,1,11,11,11,1, + 92,92,92,1,184,184,184,1,232,232,232,1,255,255,255,1,124,124,124,1, + 232,232,232,12,229,229,229,1,118,118,118,1,31,31,31,1,0,0,0,1, + 49,49,49,1,141,141,141,1,221,221,221,1,232,232,232,3,255,255,255,1, + 124,124,124,1,232,232,232,12,220,220,220,1,15,15,15,1,98,98,98,1, + 190,190,190,1,232,232,232,6,255,255,255,1,124,124,124,1,232,232,232,12, + 230,230,230,1,224,224,224,1,232,232,232,8,255,255,255,1,124,124,124,1, + 232,232,232,22,255,255,255,1,124,124,124,1,232,232,232,22,255,255,255,1, + 124,124,124,1,232,232,232,22,255,255,255,1,124,124,124,1,232,232,232,22, + 255,255,255,1,124,124,124,1,232,232,232,22,255,255,255,1,124,124,124,1, + 232,232,232,22,255,255,255,1,124,124,124,1,255,255,255,23,6,111,110,105, + 100,108,101,7,19,116,97,114,103,101,116,99,111,110,115,111,108,101,111,110, + 105,100,108,101,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101, + 6,9,116,100,111,99,107,102,111,114,109,0,11,116,119,105,100,103,101,116, + 103,114,105,100,4,103,114,105,100,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,8,98,111,117,110,100,115,95,120,2,0,8, + 98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120, + 3,102,1,9,98,111,117,110,100,115,95,99,121,3,137,0,7,97,110,99, + 104,111,114,115,11,0,9,102,111,110,116,46,110,97,109,101,6,9,115,116, + 102,95,102,105,120,101,100,11,102,111,110,116,46,120,115,99,97,108,101,2, + 1,15,102,111,110,116,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 108,112,95,120,115,99,97,108,101,0,11,111,112,116,105,111,110,115,103,114, + 105,100,11,19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110, + 116,101,114,15,111,103,95,97,117,116,111,102,105,114,115,116,114,111,119,20, + 111,103,95,99,111,108,99,104,97,110,103,101,111,110,116,97,98,107,101,121, + 10,111,103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112, + 111,112,117,112,0,11,114,111,119,99,111,117,110,116,109,97,120,3,136,19, + 14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,1,14,100,97, + 116,97,99,111,108,115,46,105,116,101,109,115,14,7,8,116,101,114,109,105, + 110,97,108,1,5,119,105,100,116,104,3,184,11,7,111,112,116,105,111,110, + 115,11,7,99,111,95,102,105,108,108,12,99,111,95,115,97,118,101,115,116, + 97,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111, + 119,0,8,119,105,100,116,104,109,105,110,3,184,11,10,119,105,100,103,101, + 116,110,97,109,101,6,8,116,101,114,109,105,110,97,108,9,100,97,116,97, + 99,108,97,115,115,7,23,116,103,114,105,100,114,105,99,104,115,116,114,105, + 110,103,100,97,116,97,108,105,115,116,0,0,16,100,97,116,97,114,111,119, + 108,105,110,101,119,105,100,116,104,2,0,13,100,97,116,97,114,111,119,104, + 101,105,103,104,116,2,14,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,9,116,116,101,114,109,105,110,97,108,8,116,101,114,109,105, + 110,97,108,8,116,97,98,111,114,100,101,114,2,1,7,118,105,115,105,98, + 108,101,8,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,184,11,9,98, + 111,117,110,100,115,95,99,121,2,14,12,111,112,116,105,111,110,115,101,100, + 105,116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101, + 110,117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101, + 49,95,115,97,118,101,115,116,97,116,101,27,111,101,49,95,99,104,101,99, + 107,118,97,108,117,101,97,102,116,101,114,115,116,97,116,114,101,97,100,0, + 8,109,97,120,99,104,97,114,115,2,120,10,111,110,115,101,110,100,116,101, + 120,116,7,8,115,101,110,100,116,101,120,116,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,14,0,0,0,10,116,112,111,112,117,112,109,101, + 110,117,8,112,111,112,117,112,109,101,110,8,111,110,117,112,100,97,116,101, + 7,14,112,111,112,117,112,117,112,100,97,116,101,101,120,101,18,109,101,110, + 117,46,115,117,98,109,101,110,117,46,99,111,117,110,116,2,5,18,109,101, + 110,117,46,115,117,98,109,101,110,117,46,105,116,101,109,115,14,1,6,97, + 99,116,105,111,110,7,14,97,99,116,105,111,110,115,109,111,46,102,105,110, + 100,0,1,6,97,99,116,105,111,110,7,20,97,99,116,105,111,110,115,109, + 111,46,114,101,112,101,97,116,102,105,110,100,0,1,6,97,99,116,105,111, + 110,7,18,97,99,116,105,111,110,115,109,111,46,102,105,110,100,98,97,99, + 107,0,1,7,111,112,116,105,111,110,115,11,13,109,97,111,95,115,101,112, + 97,114,97,116,111,114,19,109,97,111,95,115,104,111,114,116,99,117,116,99, + 97,112,116,105,111,110,0,0,1,7,99,97,112,116,105,111,110,6,6,38, + 67,108,101,97,114,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101, + 120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7,8,99, + 108,101,97,114,101,120,101,0,0,4,108,101,102,116,2,32,3,116,111,112, + 2,32,0,0,0) + ); + +initialization + registerobjectdata(@objdata,ttargetconsolefo,''); +end. diff --git a/mseide-msegui/apps/ide/templateeditor.mfm b/mseide-msegui/apps/ide/templateeditor.mfm new file mode 100644 index 0000000..291914b --- /dev/null +++ b/mseide-msegui/apps/ide/templateeditor.mfm @@ -0,0 +1,372 @@ +object templateeditorfo: ttemplateeditorfo + visible = False + bounds_x = 147 + bounds_y = 120 + bounds_cx = 473 + bounds_cy = 399 + container.frame.clientwidthmin = 473 + container.bounds = ( + 0 + 0 + 473 + 399 + ) + options = [fo_freeonclose, fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder, fo_savestate] + statfile = tstatfile1 + caption = 'Code Template Editor' + onloaded = createexe + onclosequery = closeq + moduleclassname = 'tmseform' + object tbutton1: tbutton + taborder = 12 + bounds_x = 354 + bounds_y = 376 + bounds_cx = 58 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + end + object tbutton2: tbutton + bounds_x = 418 + bounds_y = 376 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + end + object nameed: tstringedit + frame.caption = '&Name' + frame.dummy = 0 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + bounds_x = 0 + bounds_y = 4 + bounds_cx = 109 + bounds_cy = 37 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_notnull] + reffontheight = 14 + end + object commented: tstringedit + frame.caption = 'C&omment' + frame.dummy = 0 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + bounds_x = 112 + bounds_y = 4 + bounds_cx = 361 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + reffontheight = 14 + end + object paramgrid: tstringgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + frame.caption = '&Parameter' + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 3 + bounds_x = 0 + bounds_y = 46 + bounds_cx = 473 + bounds_cy = 122 + anchors = [an_top] + optionsgrid = [og_colsizing, og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + datacols.count = 2 + datacols.options = [co_fill, co_savestate, co_mousescrollrow] + datacols.items = < + item + width = 100 + options = [co_savestate, co_mousescrollrow] + valuefalse = '0' + valuetrue = '1' + end + item + width = 336 + options = [co_fill, co_savestate, co_mousescrollrow] + valuefalse = '0' + valuetrue = '1' + end> + fixcols.count = 1 + fixcols.items = < + item + width = 30 + numstart = 1 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 2 + captions.items = < + item + caption = 'Name' + end + item + caption = 'Default Value' + end> + end> + datarowheight = 16 + statfile = tstatfile1 + reffontheight = 14 + end + object tspacer1: tspacer + taborder = 13 + bounds_x = 192 + bounds_y = 41 + bounds_cx = 50 + bounds_cy = 5 + linktop = commented + linkbottom = paramgrid + end + object tsplitter1: tsplitter + color = -1879048189 + taborder = 14 + bounds_x = 0 + bounds_y = 168 + bounds_cx = 473 + bounds_cy = 3 + anchors = [an_top] + options = [spo_vmove, spo_vprop, spo_dockleft, spo_docktop, spo_dockright, spo_dockbottom] + linktop = paramgrid + linkbottom = templgrid + statfile = tstatfile1 + end + object templgrid: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + taborder = 4 + bounds_x = 0 + bounds_y = 171 + bounds_cx = 473 + bounds_cy = 173 + anchors = [an_top, an_bottom] + optionsgrid = [og_focuscellonenter, og_autofirstrow, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixcols.count = 1 + fixcols.items = < + item + width = 30 + numstart = 1 + numstep = 1 + end> + rowcount = 1 + datacols.count = 1 + datacols.options = [co_leftbuttonfocusonly, co_savevalue, co_savestate, co_mousescrollrow] + datacols.items = < + item[templed] + width = 1016 + options = [co_leftbuttonfocusonly, co_savevalue, co_savestate, co_mousescrollrow] + widgetname = 'templed' + dataclass = tgridrichstringdatalist + data = ( + ( + '' + ) + ) + end> + datarowlinewidth = 0 + datarowheight = 15 + reffontheight = 14 + object templed: tundotextedit + optionsskin = [osk_framebuttononly] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 1016 + bounds_cy = 15 + font.name = 'stf_default' + font.xscale = 1 + font.dummy = 0 + oneditnotifcation = editnotify + reffontheight = 14 + end + end + object cursordisp: tstringdisp + frame.caption = 'Cursor' + frame.captiondist = 2 + frame.localprops1 = [frl1_captiondist] + frame.dummy = 0 + frame.outerframe = ( + 0 + 18 + 0 + 0 + ) + taborder = 15 + bounds_x = 8 + bounds_y = 359 + bounds_cx = 68 + bounds_cy = 36 + anchors = [an_left, an_bottom] + textflags = [tf_xcentered, tf_ycentered] + reffontheight = 14 + end + object tsplitter2: tsplitter + color = -1879048189 + taborder = 16 + visible = False + bounds_x = 109 + bounds_y = 16 + bounds_cx = 3 + bounds_cy = 29 + options = [spo_hprop, spo_dockleft, spo_docktop, spo_dockright, spo_dockbottom] + linkleft = nameed + linkright = commented + statfile = tstatfile1 + end + object coled: tintegeredit + frame.caption = 'Col' + frame.dummy = 0 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 7 + bounds_x = 216 + bounds_y = 359 + bounds_cx = 52 + bounds_cy = 37 + anchors = [an_left, an_bottom] + value = 1 + min = 1 + reffontheight = 14 + end + object rowed: tintegeredit + frame.caption = 'Row' + frame.dummy = 0 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 6 + bounds_x = 160 + bounds_y = 359 + bounds_cx = 52 + bounds_cy = 37 + anchors = [an_left, an_bottom] + value = 1 + min = 1 + reffontheight = 14 + end + object tbutton3: tbutton + taborder = 5 + bounds_x = 80 + bounds_y = 376 + bounds_cx = 74 + bounds_cy = 20 + anchors = [an_left, an_bottom] + state = [as_localcaption, as_localonexecute] + caption = '&Set Cursor' + onexecute = setcursorex + end + object selected: tbooleanedit + frame.caption = '&select' + frame.captionpos = cp_top + frame.captiondist = 4 + frame.localprops1 = [frl1_captiondist] + frame.dummy = 0 + frame.outerframe = ( + 13 + 20 + 14 + 0 + ) + taborder = 8 + bounds_x = 267 + bounds_y = 359 + bounds_cx = 40 + bounds_cy = 33 + anchors = [an_left, an_bottom] + end + object indented: tbooleanedit + frame.caption = '&indent' + frame.captionpos = cp_top + frame.captiondist = 4 + frame.localprops1 = [frl1_captiondist] + frame.dummy = 0 + frame.outerframe = ( + 14 + 20 + 15 + 0 + ) + taborder = 9 + bounds_x = 306 + bounds_y = 359 + bounds_cx = 42 + bounds_cy = 33 + anchors = [an_left, an_bottom] + end + object deletebu: tbutton + taborder = 11 + bounds_x = 418 + bounds_y = 352 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_localcaption, as_localonexecute] + caption = 'Delete' + onexecute = deleteexe + end + object saveasbu: tbutton + taborder = 10 + bounds_x = 354 + bounds_y = 352 + bounds_cx = 58 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_localcaption, as_localonexecute] + caption = 'Filename' + onexecute = saveasexe + end + object tstatfile1: tstatfile + filename = 'templedit.sta' + options = [sfo_memory, sfo_transaction, sfo_activatorread, sfo_activatorwrite] + onstatafterread = afterstatreadexe + left = 104 + top = 192 + end + object savefiledialog: tfiledialog + statfile = tstatfile1 + controller.filterlist.data = ( + ( + 'Code Temlate Files' + '*.mct' + ) + ) + controller.defaultext = 'mct' + controller.options = [fdo_save, fdo_checkexist, fdo_savelastdir] + left = 200 + top = 192 + end + object c: tstringcontainer + strings.data = ( + 'Do you want to delete "' + 'Code Template Editor' + 'has been added to ''Project''-''Options''-''Editor''-''Code Templates''.' + ) + left = 104 + top = 232 + end +end diff --git a/mseide-msegui/apps/ide/templateeditor.pas b/mseide-msegui/apps/ide/templateeditor.pas new file mode 100644 index 0000000..796698d --- /dev/null +++ b/mseide-msegui/apps/ide/templateeditor.pas @@ -0,0 +1,222 @@ +unit templateeditor; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,mseforms,msestatfile, + msesimplewidgets,msewidgets,msedataedits,mseedit,msegrids,msestrings,msetypes, + msewidgetgrid,msegraphedits,msesplitter,mseeditglob,msetextedit,msedispwidgets, + msebitmap,msedatanodes,msefiledialog,mselistbrowser,msescrollbar,msesystypes, + msesys,msestringcontainer; +type + ttemplateeditorfo = class(tmseform) + tstatfile1: tstatfile; + tbutton1: tbutton; + tbutton2: tbutton; + nameed: tstringedit; + commented: tstringedit; + paramgrid: tstringgrid; + tspacer1: tspacer; + tsplitter1: tsplitter; + templgrid: twidgetgrid; + templed: tundotextedit; + cursordisp: tstringdisp; + tsplitter2: tsplitter; + coled: tintegeredit; + rowed: tintegeredit; + tbutton3: tbutton; + selected: tbooleanedit; + indented: tbooleanedit; + savefiledialog: tfiledialog; + deletebu: tbutton; + saveasbu: tbutton; + c: tstringcontainer; + procedure afterstatreadexe(const sender: TObject); + procedure editnotify(const sender: TObject; + var info: editnotificationinfoty); + procedure setcursorex(const sender: TObject); + procedure closeq(const sender: tcustommseform; + var amodalresult: modalresultty); + procedure saveasexe(const sender: TObject); + procedure deleteexe(const sender: TObject); + procedure createexe(const sender: TObject); + private + findex: integer; + fpath: filenamety; + fdeleted: boolean; + procedure setpath(const avalue: filenamety); + property path: filenamety read fpath write setpath; + public + constructor create(const aindex: integer); reintroduce; + function show(out aname: msestring): modalresultty; reintroduce; + end; + +implementation +uses + templateeditor_mfm,msecodetemplates,projectoptionsform,sysutils,msefileutils, + msedatalist,msesysintf,msearrayutils,mseformatstr; +type + stringconststy = ( + wantdelete, //0 Do you want to delete " + codetemped, //1 Code Template Editor + hasbeenaddedto + //2 has been added to 'Project'-'Options'-'Editor'-'Code Templates'. + ); + +constructor ttemplateeditorfo.create(const aindex: integer); +begin + findex:= aindex; + inherited create(nil); +end; + +procedure ttemplateeditorfo.afterstatreadexe(const sender: TObject); +var + dir1: filenamety; +begin + if savefiledialog.controller.lastdir = '' then begin + if findfile('',projectoptions.e.texp.codetemplatedirs,dir1) or + findfile('',[expandprmacros('${TEMPLATEDIR}')],dir1) then begin + savefiledialog.controller.lastdir:= dir1; + end; + end; +end; + +procedure ttemplateeditorfo.createexe(const sender: TObject); +begin + projectoptionstofont(templed.font); + templgrid.datarowheight:= templed.font.lineheight; + if (findex >= 0) and (findex <= high(codetemplates.templates)) then begin + with codetemplates.templates[findex] do begin + self.path:= path; + selected.value:= select; + indented.value:= indent; + coled.value:= cursorcol+1; + rowed.value:= cursorrow+1; + commented.value:= comment; + nameed.value:= name; + paramgrid[0].datalist.asarray:= params; + paramgrid[1].datalist.asarray:= paramdefaults; + templed.settext(template); + end; + end + else begin + path:= ''; + end; +end; + + +procedure ttemplateeditorfo.editnotify(const sender: TObject; + var info: editnotificationinfoty); +begin + case info.action of + ea_indexmoved: begin + with templed.editpos do begin + cursordisp.value:= inttostrmse(row+1) + ':'+inttostrmse(col+1); + end; + end; + end; +end; + +procedure ttemplateeditorfo.setcursorex(const sender: TObject); +begin + if templgrid.isdatacell(templgrid.focusedcell) then begin + with templed.editpos do begin + coled.value:= col+1; + rowed.value:= row+1; + end; + end + else begin + coled.value:= 1; + rowed.value:= 1; + end; +end; + +procedure ttemplateeditorfo.closeq(const sender: tcustommseform; + var amodalresult: modalresultty); +var + info1: templateinfoty; + dir1,pa1: filenamety; + int1: integer; +begin + if fdeleted then begin + amodalresult:= mr_ok; + end + else begin + if amodalresult = mr_ok then begin + codetemplates.initinfo(info1); + with info1 do begin + select:= selected.value; + indent:= indented.value; + cursorcol:= coled.value - 1; + cursorrow:= rowed.value - 1; + comment:= commented.value; + name:= nameed.value; + paramgrid.removeappendedrow; + params:= paramgrid[0].datalist.asarray; + paramdefaults:= paramgrid[1].datalist.asarray; + template:= templed.gettext; + if fpath = '' then begin + if not savefiledialog.controller.execute(fpath) then begin + amodalresult:= mr_cancel; + end; + end; + path:= fpath; + end; + if amodalresult = mr_ok then begin + codetemplates.savefile(info1); + dir1:= filedir(info1.path); + pa1:= intermediatefilename(dir1+'template'); + if sys_openfile(pa1,fm_create,[],[],int1) = sye_ok then begin + sys_closefile(int1); + if not findfile(filename(pa1), + projectoptions.e.texp.codetemplatedirs) then begin + deletefile(pa1); + additem(projectoptions.e.t.fcodetemplatedirs,dir1); + expandprojectmacros; + projectoptionsmodified; + showmessage('"'+dir1+'" '+c[ord(hasbeenaddedto)]); + exit; + end; + end; + deletefile(pa1); + end; + end; + end; +end; + +function ttemplateeditorfo.show(out aname: msestring): modalresultty; +begin + result:= inherited show(true); + aname:= nameed.value; +end; + +procedure ttemplateeditorfo.saveasexe(const sender: TObject); +begin + if savefiledialog.controller.execute(fpath) then begin + path:= fpath; + end; +end; + +procedure ttemplateeditorfo.deleteexe(const sender: TObject); +begin + if askyesno(c[ord(wantdelete)]+fpath+'"?') then begin + deletefile(fpath); + fdeleted:= true; + window.modalresult:= mr_cancel; + end; +end; + +procedure ttemplateeditorfo.setpath(const avalue: filenamety); +begin + fpath:= avalue; + if fpath = '' then begin + caption:= c[ord(codetemped)]; + deletebu.enabled:= false; + end + else begin + caption:= shrinkstring(fpath,40); + deletebu.enabled:= true; + end; +end; + +end. diff --git a/mseide-msegui/apps/ide/templateeditor_mfm.pas b/mseide-msegui/apps/ide/templateeditor_mfm.pas new file mode 100644 index 0000000..92d26e8 --- /dev/null +++ b/mseide-msegui/apps/ide/templateeditor_mfm.pas @@ -0,0 +1,324 @@ +unit templateeditor_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,templateeditor; + +const + objdata: record size: integer; data: array[0..6132] of byte end = + (size: 6133; data: ( + 84,80,70,48,17,116,116,101,109,112,108,97,116,101,101,100,105,116,111,114, + 102,111,16,116,101,109,112,108,97,116,101,101,100,105,116,111,114,102,111,7, + 118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,147,0, + 8,98,111,117,110,100,115,95,121,2,120,9,98,111,117,110,100,115,95,99, + 120,3,217,1,9,98,111,117,110,100,115,95,99,121,3,143,1,30,99,111, + 110,116,97,105,110,101,114,46,102,114,97,109,101,46,99,108,105,101,110,116, + 119,105,100,116,104,109,105,110,3,217,1,16,99,111,110,116,97,105,110,101, + 114,46,98,111,117,110,100,115,1,2,0,2,0,3,217,1,3,143,1,0, + 7,111,112,116,105,111,110,115,11,14,102,111,95,102,114,101,101,111,110,99, + 108,111,115,101,13,102,111,95,99,108,111,115,101,111,110,101,115,99,15,102, + 111,95,97,117,116,111,114,101,97,100,115,116,97,116,16,102,111,95,97,117, + 116,111,119,114,105,116,101,115,116,97,116,10,102,111,95,115,97,118,101,112, + 111,115,13,102,111,95,115,97,118,101,122,111,114,100,101,114,12,102,111,95, + 115,97,118,101,115,116,97,116,101,0,8,115,116,97,116,102,105,108,101,7, + 10,116,115,116,97,116,102,105,108,101,49,7,99,97,112,116,105,111,110,6, + 20,67,111,100,101,32,84,101,109,112,108,97,116,101,32,69,100,105,116,111, + 114,8,111,110,108,111,97,100,101,100,7,9,99,114,101,97,116,101,101,120, + 101,12,111,110,99,108,111,115,101,113,117,101,114,121,7,6,99,108,111,115, + 101,113,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,8, + 116,109,115,101,102,111,114,109,0,7,116,98,117,116,116,111,110,8,116,98, + 117,116,116,111,110,49,8,116,97,98,111,114,100,101,114,2,12,8,98,111, + 117,110,100,115,95,120,3,98,1,8,98,111,117,110,100,115,95,121,3,120, + 1,9,98,111,117,110,100,115,95,99,120,2,58,9,98,111,117,110,100,115, + 95,99,121,2,20,7,97,110,99,104,111,114,115,11,8,97,110,95,114,105, + 103,104,116,9,97,110,95,98,111,116,116,111,109,0,5,115,116,97,116,101, + 11,10,97,115,95,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97, + 108,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,99,97,112, + 116,105,111,110,0,7,99,97,112,116,105,111,110,6,3,38,79,75,11,109, + 111,100,97,108,114,101,115,117,108,116,7,5,109,114,95,111,107,0,0,7, + 116,98,117,116,116,111,110,8,116,98,117,116,116,111,110,50,8,98,111,117, + 110,100,115,95,120,3,162,1,8,98,111,117,110,100,115,95,121,3,120,1, + 9,98,111,117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95, + 99,121,2,20,7,97,110,99,104,111,114,115,11,8,97,110,95,114,105,103, + 104,116,9,97,110,95,98,111,116,116,111,109,0,5,115,116,97,116,101,11, + 15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,7,99,97, + 112,116,105,111,110,6,7,38,67,97,110,99,101,108,11,109,111,100,97,108, + 114,101,115,117,108,116,7,9,109,114,95,99,97,110,99,101,108,0,0,11, + 116,115,116,114,105,110,103,101,100,105,116,6,110,97,109,101,101,100,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,5,38,78,97,109,101,11, + 102,114,97,109,101,46,100,117,109,109,121,2,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0, + 8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,2,4,9,98,111,117,110,100,115, + 95,99,120,2,109,9,98,111,117,110,100,115,95,99,121,2,37,11,111,112, + 116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110, + 101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101, + 95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104, + 105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116,117, + 114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101, + 120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13, + 111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116, + 111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99, + 116,111,110,102,105,114,115,116,99,108,105,99,107,10,111,101,95,110,111,116, + 110,117,108,108,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,0,11,116,115,116,114,105,110,103,101,100,105,116,9,99,111,109,109, + 101,110,116,101,100,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 8,67,38,111,109,109,101,110,116,11,102,114,97,109,101,46,100,117,109,109, + 121,2,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101, + 1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2, + 2,8,98,111,117,110,100,115,95,120,2,112,8,98,111,117,110,100,115,95, + 121,2,4,9,98,111,117,110,100,115,95,99,120,3,105,1,9,98,111,117, + 110,100,115,95,99,121,2,37,7,97,110,99,104,111,114,115,11,7,97,110, + 95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104, + 116,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0, + 11,116,115,116,114,105,110,103,103,114,105,100,9,112,97,114,97,109,103,114, + 105,100,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119, + 95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111, + 99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,16,111,119, + 95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,102,111, + 99,117,115,98,97,99,107,111,110,101,115,99,13,111,119,95,109,111,117,115, + 101,119,104,101,101,108,17,111,119,95,100,101,115,116,114,111,121,119,105,100, + 103,101,116,115,0,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 10,38,80,97,114,97,109,101,116,101,114,16,102,114,97,109,101,46,111,117, + 116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116, + 97,98,111,114,100,101,114,2,3,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,46,9,98,111,117,110,100,115,95,99, + 120,3,217,1,9,98,111,117,110,100,115,95,99,121,2,122,7,97,110,99, + 104,111,114,115,11,6,97,110,95,116,111,112,0,11,111,112,116,105,111,110, + 115,103,114,105,100,11,12,111,103,95,99,111,108,115,105,122,105,110,103,12, + 111,103,95,114,111,119,109,111,118,105,110,103,15,111,103,95,107,101,121,114, + 111,119,109,111,118,105,110,103,15,111,103,95,114,111,119,105,110,115,101,114, + 116,105,110,103,14,111,103,95,114,111,119,100,101,108,101,116,105,110,103,19, + 111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101,114,15, + 111,103,95,97,117,116,111,102,105,114,115,116,114,111,119,13,111,103,95,97, + 117,116,111,97,112,112,101,110,100,20,111,103,95,99,111,108,99,104,97,110, + 103,101,111,110,116,97,98,107,101,121,10,111,103,95,119,114,97,112,99,111, + 108,12,111,103,95,97,117,116,111,112,111,112,117,112,17,111,103,95,109,111, + 117,115,101,115,99,114,111,108,108,99,111,108,0,14,100,97,116,97,99,111, + 108,115,46,99,111,117,110,116,2,2,16,100,97,116,97,99,111,108,115,46, + 111,112,116,105,111,110,115,11,7,99,111,95,102,105,108,108,12,99,111,95, + 115,97,118,101,115,116,97,116,101,17,99,111,95,109,111,117,115,101,115,99, + 114,111,108,108,114,111,119,0,14,100,97,116,97,99,111,108,115,46,105,116, + 101,109,115,14,1,5,119,105,100,116,104,2,100,7,111,112,116,105,111,110, + 115,11,12,99,111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109, + 111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,118,97,108,117,101, + 102,97,108,115,101,6,1,48,9,118,97,108,117,101,116,114,117,101,6,1, + 49,0,1,5,119,105,100,116,104,3,80,1,7,111,112,116,105,111,110,115, + 11,7,99,111,95,102,105,108,108,12,99,111,95,115,97,118,101,115,116,97, + 116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119, + 0,10,118,97,108,117,101,102,97,108,115,101,6,1,48,9,118,97,108,117, + 101,116,114,117,101,6,1,49,0,0,13,102,105,120,99,111,108,115,46,99, + 111,117,110,116,2,1,13,102,105,120,99,111,108,115,46,105,116,101,109,115, + 14,1,5,119,105,100,116,104,2,30,8,110,117,109,115,116,97,114,116,2, + 1,7,110,117,109,115,116,101,112,2,1,0,0,13,102,105,120,114,111,119, + 115,46,99,111,117,110,116,2,1,13,102,105,120,114,111,119,115,46,105,116, + 101,109,115,14,1,6,104,101,105,103,104,116,2,16,14,99,97,112,116,105, + 111,110,115,46,99,111,117,110,116,2,2,14,99,97,112,116,105,111,110,115, + 46,105,116,101,109,115,14,1,7,99,97,112,116,105,111,110,6,4,78,97, + 109,101,0,1,7,99,97,112,116,105,111,110,6,13,68,101,102,97,117,108, + 116,32,86,97,108,117,101,0,0,0,0,13,100,97,116,97,114,111,119,104, + 101,105,103,104,116,2,16,8,115,116,97,116,102,105,108,101,7,10,116,115, + 116,97,116,102,105,108,101,49,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,14,0,0,7,116,115,112,97,99,101,114,8,116,115,112,97,99, + 101,114,49,8,116,97,98,111,114,100,101,114,2,13,8,98,111,117,110,100, + 115,95,120,3,192,0,8,98,111,117,110,100,115,95,121,2,41,9,98,111, + 117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2, + 5,7,108,105,110,107,116,111,112,7,9,99,111,109,109,101,110,116,101,100, + 10,108,105,110,107,98,111,116,116,111,109,7,9,112,97,114,97,109,103,114, + 105,100,0,0,9,116,115,112,108,105,116,116,101,114,10,116,115,112,108,105, + 116,116,101,114,49,5,99,111,108,111,114,4,3,0,0,144,8,116,97,98, + 111,114,100,101,114,2,14,8,98,111,117,110,100,115,95,120,2,0,8,98, + 111,117,110,100,115,95,121,3,168,0,9,98,111,117,110,100,115,95,99,120, + 3,217,1,9,98,111,117,110,100,115,95,99,121,2,3,7,97,110,99,104, + 111,114,115,11,6,97,110,95,116,111,112,0,7,111,112,116,105,111,110,115, + 11,9,115,112,111,95,118,109,111,118,101,9,115,112,111,95,118,112,114,111, + 112,12,115,112,111,95,100,111,99,107,108,101,102,116,11,115,112,111,95,100, + 111,99,107,116,111,112,13,115,112,111,95,100,111,99,107,114,105,103,104,116, + 14,115,112,111,95,100,111,99,107,98,111,116,116,111,109,0,7,108,105,110, + 107,116,111,112,7,9,112,97,114,97,109,103,114,105,100,10,108,105,110,107, + 98,111,116,116,111,109,7,9,116,101,109,112,108,103,114,105,100,8,115,116, + 97,116,102,105,108,101,7,10,116,115,116,97,116,102,105,108,101,49,0,0, + 11,116,119,105,100,103,101,116,103,114,105,100,9,116,101,109,112,108,103,114, + 105,100,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119, + 95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111, + 99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,16,111,119, + 95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,102,111, + 99,117,115,98,97,99,107,111,110,101,115,99,13,111,119,95,109,111,117,115, + 101,119,104,101,101,108,17,111,119,95,100,101,115,116,114,111,121,119,105,100, + 103,101,116,115,0,8,116,97,98,111,114,100,101,114,2,4,8,98,111,117, + 110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,3,171,0,9, + 98,111,117,110,100,115,95,99,120,3,217,1,9,98,111,117,110,100,115,95, + 99,121,3,173,0,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111, + 112,9,97,110,95,98,111,116,116,111,109,0,11,111,112,116,105,111,110,115, + 103,114,105,100,11,19,111,103,95,102,111,99,117,115,99,101,108,108,111,110, + 101,110,116,101,114,15,111,103,95,97,117,116,111,102,105,114,115,116,114,111, + 119,20,111,103,95,99,111,108,99,104,97,110,103,101,111,110,116,97,98,107, + 101,121,10,111,103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116, + 111,112,111,112,117,112,17,111,103,95,109,111,117,115,101,115,99,114,111,108, + 108,99,111,108,0,13,102,105,120,99,111,108,115,46,99,111,117,110,116,2, + 1,13,102,105,120,99,111,108,115,46,105,116,101,109,115,14,1,5,119,105, + 100,116,104,2,30,8,110,117,109,115,116,97,114,116,2,1,7,110,117,109, + 115,116,101,112,2,1,0,0,8,114,111,119,99,111,117,110,116,2,1,14, + 100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,1,16,100,97,116, + 97,99,111,108,115,46,111,112,116,105,111,110,115,11,22,99,111,95,108,101, + 102,116,98,117,116,116,111,110,102,111,99,117,115,111,110,108,121,12,99,111, + 95,115,97,118,101,118,97,108,117,101,12,99,111,95,115,97,118,101,115,116, + 97,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111, + 119,0,14,100,97,116,97,99,111,108,115,46,105,116,101,109,115,14,7,7, + 116,101,109,112,108,101,100,1,5,119,105,100,116,104,3,248,3,7,111,112, + 116,105,111,110,115,11,22,99,111,95,108,101,102,116,98,117,116,116,111,110, + 102,111,99,117,115,111,110,108,121,12,99,111,95,115,97,118,101,118,97,108, + 117,101,12,99,111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109, + 111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101, + 116,110,97,109,101,6,7,116,101,109,112,108,101,100,9,100,97,116,97,99, + 108,97,115,115,7,23,116,103,114,105,100,114,105,99,104,115,116,114,105,110, + 103,100,97,116,97,108,105,115,116,4,100,97,116,97,1,1,6,0,0,0, + 0,0,16,100,97,116,97,114,111,119,108,105,110,101,119,105,100,116,104,2, + 0,13,100,97,116,97,114,111,119,104,101,105,103,104,116,2,15,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,13,116,117,110,100,111, + 116,101,120,116,101,100,105,116,7,116,101,109,112,108,101,100,11,111,112,116, + 105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98, + 117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2, + 1,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2, + 0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,3,248,3,9,98,111,117,110,100,115,95,99,121,2,15,9,102,111, + 110,116,46,110,97,109,101,6,11,115,116,102,95,100,101,102,97,117,108,116, + 11,102,111,110,116,46,120,115,99,97,108,101,2,1,10,102,111,110,116,46, + 100,117,109,109,121,2,0,17,111,110,101,100,105,116,110,111,116,105,102,99, + 97,116,105,111,110,7,10,101,100,105,116,110,111,116,105,102,121,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,11,116,115,116, + 114,105,110,103,100,105,115,112,10,99,117,114,115,111,114,100,105,115,112,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,6,67,117,114,115,111, + 114,17,102,114,97,109,101,46,99,97,112,116,105,111,110,100,105,115,116,2, + 2,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 16,102,114,108,49,95,99,97,112,116,105,111,110,100,105,115,116,0,11,102, + 114,97,109,101,46,100,117,109,109,121,2,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,18,2,0,2,0,0,8, + 116,97,98,111,114,100,101,114,2,15,8,98,111,117,110,100,115,95,120,2, + 8,8,98,111,117,110,100,115,95,121,3,103,1,9,98,111,117,110,100,115, + 95,99,120,2,68,9,98,111,117,110,100,115,95,99,121,2,36,7,97,110, + 99,104,111,114,115,11,7,97,110,95,108,101,102,116,9,97,110,95,98,111, + 116,116,111,109,0,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95, + 120,99,101,110,116,101,114,101,100,12,116,102,95,121,99,101,110,116,101,114, + 101,100,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0, + 0,9,116,115,112,108,105,116,116,101,114,10,116,115,112,108,105,116,116,101, + 114,50,5,99,111,108,111,114,4,3,0,0,144,8,116,97,98,111,114,100, + 101,114,2,16,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115, + 95,120,2,109,8,98,111,117,110,100,115,95,121,2,16,9,98,111,117,110, + 100,115,95,99,120,2,3,9,98,111,117,110,100,115,95,99,121,2,29,7, + 111,112,116,105,111,110,115,11,9,115,112,111,95,104,112,114,111,112,12,115, + 112,111,95,100,111,99,107,108,101,102,116,11,115,112,111,95,100,111,99,107, + 116,111,112,13,115,112,111,95,100,111,99,107,114,105,103,104,116,14,115,112, + 111,95,100,111,99,107,98,111,116,116,111,109,0,8,108,105,110,107,108,101, + 102,116,7,6,110,97,109,101,101,100,9,108,105,110,107,114,105,103,104,116, + 7,9,99,111,109,109,101,110,116,101,100,8,115,116,97,116,102,105,108,101, + 7,10,116,115,116,97,116,102,105,108,101,49,0,0,12,116,105,110,116,101, + 103,101,114,101,100,105,116,5,99,111,108,101,100,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,3,67,111,108,11,102,114,97,109,101,46,100, + 117,109,109,121,2,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100, + 101,114,2,7,8,98,111,117,110,100,115,95,120,3,216,0,8,98,111,117, + 110,100,115,95,121,3,103,1,9,98,111,117,110,100,115,95,99,120,2,52, + 9,98,111,117,110,100,115,95,99,121,2,37,7,97,110,99,104,111,114,115, + 11,7,97,110,95,108,101,102,116,9,97,110,95,98,111,116,116,111,109,0, + 5,118,97,108,117,101,2,1,3,109,105,110,2,1,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,14,0,0,12,116,105,110,116,101,103,101, + 114,101,100,105,116,5,114,111,119,101,100,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,3,82,111,119,11,102,114,97,109,101,46,100,117,109, + 109,121,2,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109, + 101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114, + 2,6,8,98,111,117,110,100,115,95,120,3,160,0,8,98,111,117,110,100, + 115,95,121,3,103,1,9,98,111,117,110,100,115,95,99,120,2,52,9,98, + 111,117,110,100,115,95,99,121,2,37,7,97,110,99,104,111,114,115,11,7, + 97,110,95,108,101,102,116,9,97,110,95,98,111,116,116,111,109,0,5,118, + 97,108,117,101,2,1,3,109,105,110,2,1,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,14,0,0,7,116,98,117,116,116,111,110,8,116, + 98,117,116,116,111,110,51,8,116,97,98,111,114,100,101,114,2,5,8,98, + 111,117,110,100,115,95,120,2,80,8,98,111,117,110,100,115,95,121,3,120, + 1,9,98,111,117,110,100,115,95,99,120,2,74,9,98,111,117,110,100,115, + 95,99,121,2,20,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101, + 102,116,9,97,110,95,98,111,116,116,111,109,0,5,115,116,97,116,101,11, + 15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95, + 108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,7,99,97,112,116, + 105,111,110,6,11,38,83,101,116,32,67,117,114,115,111,114,9,111,110,101, + 120,101,99,117,116,101,7,11,115,101,116,99,117,114,115,111,114,101,120,0, + 0,12,116,98,111,111,108,101,97,110,101,100,105,116,8,115,101,108,101,99, + 116,101,100,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,7,38, + 115,101,108,101,99,116,16,102,114,97,109,101,46,99,97,112,116,105,111,110, + 112,111,115,7,6,99,112,95,116,111,112,17,102,114,97,109,101,46,99,97, + 112,116,105,111,110,100,105,115,116,2,4,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,16,102,114,108,49,95,99,97,112,116, + 105,111,110,100,105,115,116,0,11,102,114,97,109,101,46,100,117,109,109,121, + 2,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,13,2,20,2,14,2,0,0,8,116,97,98,111,114,100,101,114,2,8, + 8,98,111,117,110,100,115,95,120,3,11,1,8,98,111,117,110,100,115,95, + 121,3,103,1,9,98,111,117,110,100,115,95,99,120,2,40,9,98,111,117, + 110,100,115,95,99,121,2,33,7,97,110,99,104,111,114,115,11,7,97,110, + 95,108,101,102,116,9,97,110,95,98,111,116,116,111,109,0,0,0,12,116, + 98,111,111,108,101,97,110,101,100,105,116,8,105,110,100,101,110,116,101,100, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,7,38,105,110,100, + 101,110,116,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115, + 7,6,99,112,95,116,111,112,17,102,114,97,109,101,46,99,97,112,116,105, + 111,110,100,105,115,116,2,4,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,16,102,114,108,49,95,99,97,112,116,105,111,110, + 100,105,115,116,0,11,102,114,97,109,101,46,100,117,109,109,121,2,0,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,14,2, + 20,2,15,2,0,0,8,116,97,98,111,114,100,101,114,2,9,8,98,111, + 117,110,100,115,95,120,3,50,1,8,98,111,117,110,100,115,95,121,3,103, + 1,9,98,111,117,110,100,115,95,99,120,2,42,9,98,111,117,110,100,115, + 95,99,121,2,33,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101, + 102,116,9,97,110,95,98,111,116,116,111,109,0,0,0,7,116,98,117,116, + 116,111,110,8,100,101,108,101,116,101,98,117,8,116,97,98,111,114,100,101, + 114,2,11,8,98,111,117,110,100,115,95,120,3,162,1,8,98,111,117,110, + 100,115,95,121,3,96,1,9,98,111,117,110,100,115,95,99,120,2,50,9, + 98,111,117,110,100,115,95,99,121,2,20,7,97,110,99,104,111,114,115,11, + 8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0, + 5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116, + 105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116, + 101,0,7,99,97,112,116,105,111,110,6,6,68,101,108,101,116,101,9,111, + 110,101,120,101,99,117,116,101,7,9,100,101,108,101,116,101,101,120,101,0, + 0,7,116,98,117,116,116,111,110,8,115,97,118,101,97,115,98,117,8,116, + 97,98,111,114,100,101,114,2,10,8,98,111,117,110,100,115,95,120,3,98, + 1,8,98,111,117,110,100,115,95,121,3,96,1,9,98,111,117,110,100,115, + 95,99,120,2,58,9,98,111,117,110,100,115,95,99,121,2,20,7,97,110, + 99,104,111,114,115,11,8,97,110,95,114,105,103,104,116,9,97,110,95,98, + 111,116,116,111,109,0,5,115,116,97,116,101,11,15,97,115,95,108,111,99, + 97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110, + 101,120,101,99,117,116,101,0,7,99,97,112,116,105,111,110,6,8,70,105, + 108,101,110,97,109,101,9,111,110,101,120,101,99,117,116,101,7,9,115,97, + 118,101,97,115,101,120,101,0,0,9,116,115,116,97,116,102,105,108,101,10, + 116,115,116,97,116,102,105,108,101,49,8,102,105,108,101,110,97,109,101,6, + 13,116,101,109,112,108,101,100,105,116,46,115,116,97,7,111,112,116,105,111, + 110,115,11,10,115,102,111,95,109,101,109,111,114,121,15,115,102,111,95,116, + 114,97,110,115,97,99,116,105,111,110,17,115,102,111,95,97,99,116,105,118, + 97,116,111,114,114,101,97,100,18,115,102,111,95,97,99,116,105,118,97,116, + 111,114,119,114,105,116,101,0,15,111,110,115,116,97,116,97,102,116,101,114, + 114,101,97,100,7,16,97,102,116,101,114,115,116,97,116,114,101,97,100,101, + 120,101,4,108,101,102,116,2,104,3,116,111,112,3,192,0,0,0,11,116, + 102,105,108,101,100,105,97,108,111,103,14,115,97,118,101,102,105,108,101,100, + 105,97,108,111,103,8,115,116,97,116,102,105,108,101,7,10,116,115,116,97, + 116,102,105,108,101,49,26,99,111,110,116,114,111,108,108,101,114,46,102,105, + 108,116,101,114,108,105,115,116,46,100,97,116,97,1,1,6,18,67,111,100, + 101,32,84,101,109,108,97,116,101,32,70,105,108,101,115,6,5,42,46,109, + 99,116,0,0,21,99,111,110,116,114,111,108,108,101,114,46,100,101,102,97, + 117,108,116,101,120,116,6,3,109,99,116,18,99,111,110,116,114,111,108,108, + 101,114,46,111,112,116,105,111,110,115,11,8,102,100,111,95,115,97,118,101, + 14,102,100,111,95,99,104,101,99,107,101,120,105,115,116,15,102,100,111,95, + 115,97,118,101,108,97,115,116,100,105,114,0,4,108,101,102,116,3,200,0, + 3,116,111,112,3,192,0,0,0,16,116,115,116,114,105,110,103,99,111,110, + 116,97,105,110,101,114,1,99,12,115,116,114,105,110,103,115,46,100,97,116, + 97,1,6,23,68,111,32,121,111,117,32,119,97,110,116,32,116,111,32,100, + 101,108,101,116,101,32,34,6,20,67,111,100,101,32,84,101,109,112,108,97, + 116,101,32,69,100,105,116,111,114,6,64,104,97,115,32,98,101,101,110,32, + 97,100,100,101,100,32,116,111,32,39,80,114,111,106,101,99,116,39,45,39, + 79,112,116,105,111,110,115,39,45,39,69,100,105,116,111,114,39,45,39,67, + 111,100,101,32,84,101,109,112,108,97,116,101,115,39,46,0,4,108,101,102, + 116,2,104,3,116,111,112,3,232,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,ttemplateeditorfo,''); +end. diff --git a/mseide-msegui/apps/ide/templates/console.prj b/mseide-msegui/apps/ide/templates/console.prj new file mode 100644 index 0000000..b846217 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/console.prj @@ -0,0 +1,970 @@ +[componentpalette] +order0=0 +order1=0 +order2=0 +order3=0 +order4=0 +order5=0 +order6=0 +order7=0 +order8=0 +order9=0 +order10=0 +order11=0 +order12=0 +order13=0 +order14=0 +order15=0 +order16=0 +order17=0 +order18=0 +[projectoptions] +projectdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/templates +projectfilename=/home/mse/packs/standard/git/mseide-msegui/apps/ide/templates/console.prj +mainfile=${PROJECTNAME}.pas +targetfile=${PROJECTNAME}${EXEEXT} +messageoutputfile= +makecommand=${COMPILER} +makedir= +unitdirs=3 + ${MSEDIR}lib/addon/*/ + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ +unitpref=-Fu +incpref=-Fi +libpref=-Fl +objpref=-Fo +targpref=-o +befcommand=0 +aftcommand=0 +makeoptions=4 + -Xg -l -Mobjfpc -Sh -Fcutf8 + -gl -O- + -B + -O2 -XX -Xs -CX +codetemplatedirs=1 + ${TEMPLATEDIR} +toolmenus=0 +toolfiles=0 +toolparams=0 +fontnames=0 +scriptbeforecopy= +scriptaftercopy= +newprojectfiles=1 + ${TEMPLATEDIR}/console/project.pas +newprojectfilesdest=1 + ${%PROJECTNAME%}.pas +newfinames=3 + Program + Unit + Textfile +newfifilters=3 + "*.pas" "*.pp" + "*.pas" "*.pp" + +newfiexts=3 + pas + pas + +newfisources=3 + ${TEMPLATEDIR}default/program.pas + ${TEMPLATEDIR}default/unit.pas + +newfonames=12 + Mainform + Simple Form + Docking Form + Sizing Form + Datamodule + Subform + Scrollboxform + Tabform + Dockpanel + Report + Scriptform + Inherited Form +newfonamebases=12 + form + form + form + form + module + form + form + form + form + report + script + form +newfosources=12 + ${TEMPLATEDIR}default/mainform.pas + ${TEMPLATEDIR}default/simpleform.pas + ${TEMPLATEDIR}default/dockingform.pas + ${TEMPLATEDIR}default/sizingform.pas + ${TEMPLATEDIR}default/datamodule.pas + ${TEMPLATEDIR}default/subform.pas + ${TEMPLATEDIR}default/scrollboxform.pas + ${TEMPLATEDIR}default/tabform.pas + ${TEMPLATEDIR}default/dockpanelform.pas + ${TEMPLATEDIR}default/report.pas + ${TEMPLATEDIR}default/pascform.pas + ${TEMPLATEDIR}default/inheritedform.pas +newfoforms=12 + ${TEMPLATEDIR}default/mainform.mfm + ${TEMPLATEDIR}default/simpleform.mfm + ${TEMPLATEDIR}default/dockingform.mfm + ${TEMPLATEDIR}default/sizingform.mfm + ${TEMPLATEDIR}default/datamodule.mfm + ${TEMPLATEDIR}default/subform.mfm + ${TEMPLATEDIR}default/scrollboxform.mfm + ${TEMPLATEDIR}default/tabform.mfm + ${TEMPLATEDIR}default/dockpanelform.mfm + ${TEMPLATEDIR}default/report.mfm + ${TEMPLATEDIR}default/pascform.mfm + ${TEMPLATEDIR}default/inheritedform.mfm +forcezorder=0 +stripmessageesc=0 +copymessages=0 +closemessages=1 +checkmethods=1 +colorerror=-1610612712 +colorwarning=-1610612717 +colornote=-1610612716 +usercolors=30 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +usercolorcomment=30 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +formatmacronames=0 +formatmacrovalues=0 +settingsfile= +settingseditor=0 +settingsdebugger=0 +settingsstorage=0 +settingsprojecttree=0 +settingsautoload=0 +settingsautosave=0 +modulenames=0 +moduletypes=0 +modulefiles=0 +befcommandon=0 +makeoptionson=4 + 63 + 31 + 34 + 32 +aftcommandon=0 +unitdirson=3 + 196671 + 65599 + 65599 +macroon=0 +macronames=0 +macrovalues=0 +macrogroup=0 +groupcomments=6 + + + + + + +toolsave=0 +toolhide=0 +toolparse=0 +toolmessages=0 +toolshortcuts=0 +fontalias=0 +fontancestors=0 +fontheights=0 +fontwidths=0 +fontoptions=0 +fontxscales=0 +expandprojectfilemacros=1 + 1 +loadprojectfile=1 + 1 +newinheritedforms=12 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 +uid=0 +sourcefilemasks=3 + "*.pas" "*.dpr" "*.lpr" "*.pp" "*.inc" + "*.c" "*.cc" "*.h" + "*.mfm" +syntaxdeffiles=3 + ${SYNTAXDEFDIR}pascal.sdef + ${SYNTAXDEFDIR}cpp.sdef + ${SYNTAXDEFDIR}objecttext.sdef +filemasknames=3 + Source + Forms + All Files +filemasks=3 + "*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + *.mfm + * +showgrid=1 +snaptogrid=1 +moveonfirstclick=1 +noformdesignerdocking=0 +gridsizex=8 +gridsizey=8 +autoindent=1 +blockindent=1 +linenumberson=0 +rightmarginon=1 +rightmarginchars=80 +scrollheight=0 +tabstops=4 +spacetabs=0 +showtabs=0 +tabindent=0 +editfontname=mseide_source +editfontheight=0 +editfontwidth=0 +editfontextraspace=0 +editfontcolor=-1879048183 +editbkcolor=-1879048186 +statementcolor=14745599 +editfontantialiased=1 +editmarkbrackets=1 +backupfilecount=2 +encoding=1 +codetemplatedirs=1 + ${TEMPLATEDIR} +debugcommand=${DEBUGGER} +debugoptions= +debugtarget= +runcommand= +xtermcommand=xterm -S${PTSN}/${PTSH} +remoteconnection= +uploadcommand= +gdbprocessor=auto +gdbservercommand= +gdbservercommandattach= +beforeconnect= +afterconnect= +beforeload= +afterload= +beforerun= +sourcebase= +sourcedirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ + ./ +defines=0 +progparameters= +progworkingdirectory= +envvarnames=0 +envvarvalues=0 +defineson=0 +stoponexception=0 +valuehints=1 +activateonbreak=1 +raiseonbreak=1 +showconsole=0 +externalconsole=0 +settty=1 +gdbdownload=0 +downloadalways=0 +startupbkpt=0 +startupbkpton=0 +gdbsimulator=0 +gdbserverstartonce=0 +gdbloadtimeout= +gdbserverwait=0 +nogdbserverexit=0 +gdbservertty=0 +exceptclassnames=1 + EconvertError +exceptignore=1 + 0 +nodebugbeginend=0 +sigsettings=27 + 1,1,T,F + 3,3,T,F + 4,4,T,F + 6,6,T,F + 7,7,T,F + 8,8,T,F + 9,9,T,F + 10,10,T,F + 11,11,T,F + 12,12,T,F + 13,13,T,F + 15,15,T,F + 16,16,T,F + 17,17,F,F + 18,18,T,F + 19,19,T,F + 20,20,T,F + 21,21,T,F + 22,22,T,F + 23,23,T,F + 24,24,T,F + 25,25,T,F + 26,26,T,F + 27,27,T,F + 28,28,T,F + 29,29,F,F + 30,30,T,F +defaultmake=1 +[breakpoints] +on=0 +path=0 +line=0 +address=0 +addbkpt=0 +ignore=0 +condition=0 +panels=2 + panel1 + panel2 +units= + ( + a=0,4132,6,Pascal Units + ) +cmodules= + ( + a=0,4132,6,C Modules + ) +files= + ( + a=0,4132,6,Text Files + ) +[componentstore] +storedir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ +filename= +[components] +[selecteditpage] +colwidth=100 +x=0 +y=0 +cx=0 +cy=0 +[progparams] +progparamhistory=0 +workdirparamhistory=0 +envvarons=0 +[edit] +hintwidth=0 +hintheight=0 +finddtext= +findhistory=0 +findoptions=1 +editpos=0 +sourcefiles=0 +relpaths=0 +ismoduletexts=0 +modules=0 +moduleoptions=0 +visiblemodules=0 +nomenumodules=0 +[sourcefo.tabwidget] +tabsize=110 +firsttab=0 +index=-1 +[layout] +windowlayout=530 + [mainfo.openform] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.projectfiledia] + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + [mainfo.openfile] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.basedock] + splitdir=2 + useroptions=146560 + [mainfo] + splitdir=0 + useroptions=33554555 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=25 + cx=323 + cy=64 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [targetconsolefo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=554 + cx=323 + cy=169 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [threadsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=37 + y=270 + cx=349 + cy=276 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo] + splitdir=0 + useroptions=16507 + stackedunder=componentpalettefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=100 + y=100 + cx=453 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo.add] + value=0 + [memoryfo.memon] + value=0 + [memoryfo.bitwidth] + value=0 + [memoryfo.cnt] + value=0 + [disassfo] + splitdir=0 + useroptions=16491 + stackedunder=targetconsolefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=162 + y=502 + cx=564 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [findinfilefo] + splitdir=0 + useroptions=16491 + stackedunder=disassfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=548 + y=115 + cx=369 + cy=198 + rcx=0 + rcy=0 + [projecttreefo] + splitdir=0 + useroptions=16491 + stackedunder=memoryfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=263 + y=431 + cx=286 + cy=201 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [projecttreefo.grid] + propcolwidthref=135 + width0=141 + sortdescend0=0 + width1=129 + sortdescend1=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=16 + [stackfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=276 + rcx=0 + rcy=0 + [watchpointsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=120 + y=368 + cx=483 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [watchpointsfo.grid] + propcolwidthref=352 + sortdescend0=0 + values1=0 + values1_ci=-1 + width1=33 + sortdescend1=0 + values2=0 + width2=158 + sortdescend2=0 + width4=34 + sortdescend4=0 + values5=0 + values5_ci=-1 + width5=38 + sortdescend5=0 + values6=0 + width6=184 + sortdescend6=0 + [breakpointsfo] + splitdir=0 + useroptions=16491 + stackedunder=projecttreefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=107 + y=404 + cx=636 + cy=128 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [breakpointsfo.bkptson] + value=1 + [objectinspectorfo] + splitdir=0 + useroptions=16491 + stackedunder=breakpointsfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=724 + y=157 + cx=296 + cy=566 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [objectinspectorfo.grid] + propcolwidthref=286 + width0=105 + sortdescend0=0 + width1=175 + sortdescend1=0 + [symbolfo] + splitdir=0 + useroptions=16507 + stackedunder=findinfilefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=142 + y=257 + cx=361 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [symbolfo.grid] + propcolwidthref=222 + values0=0 + width0=111 + sortdescend0=0 + width1=135 + sortdescend1=0 + [symbolfo.symbol] + [watchfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=279 + cx=313 + cy=221 + rcx=0 + rcy=0 + [watchfo.grid] + propcolwidthref=118 + values0=0 + values0_ci=-1 + sortdescend0=0 + values1=0 + width1=152 + sortdescend1=0 + values3=0 + values3_ci=-1 + sortdescend3=0 + values4=0 + values4_ci=-1 + width4=13 + sortdescend4=0 + [watchfo.watchon] + [watchfo.expression] + [watchfo.watcheson] + value=1 + [messagefo] + splitdir=0 + useroptions=49259 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=510 + cx=675 + cy=95 + rcx=0 + rcy=0 + [componentstorefo] + splitdir=0 + useroptions=24699 + stackedunder=symbolfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=305 + y=101 + cx=445 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentstorefo.grid] + propcolwidthref=435 + width0=111 + sortdescend0=0 + sortdescend1=0 + width2=112 + sortdescend2=0 + width3=185 + sortdescend3=0 + [componentstorefo.storefiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.groupfiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.compfiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentpalettefo] + splitdir=0 + useroptions=24683 + stackedunder=componentstorefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=25 + cx=685 + cy=103 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentpalettefo.componentpages] + activetab=0 + [debuggerfo] + splitdir=0 + useroptions=24683 + parent=mainfo.basedock + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=28 + rcx=0 + rcy=0 + [sourcefo] + splitdir=0 + useroptions=16489 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=675 + cy=507 + rcx=0 + rcy=0 + [actionsmo.watchesonact] + checked=1 + [actionsmo.bluedotsonact] + checked=1 + [cpui386fo] + irqoff=0 + splitdir=0 + useroptions=16491 + stackedunder=mainfo.panel1 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=25 + cx=273 + cy=207 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel1] + splitdir=2 + useroptions=33586667 + stackedunder=mainfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=118 + cx=685 + cy=605 + rcx=0 + rcy=0 + wsize=0 + active=1 + visible=1 + [mainfo.panel2] + splitdir=2 + useroptions=33586667 + stackedunder=cpui386fo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=25 + cx=323 + cy=500 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 +[targetconsole] +finddtext= +findhistory=0 +findoptions=1 diff --git a/mseide-msegui/apps/ide/templates/console/program.pas b/mseide-msegui/apps/ide/templates/console/program.pas new file mode 100644 index 0000000..0e063a1 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/console/program.pas @@ -0,0 +1,8 @@ +program ${%PROGRAMNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifdef mswindows}{$apptype console}{$endif} +uses + {$ifdef FPC}{$ifdef unix}cthreads,cwstring,{$endif}{$endif} + sysutils; +begin +end. diff --git a/mseide-msegui/apps/ide/templates/console/project.pas b/mseide-msegui/apps/ide/templates/console/project.pas new file mode 100644 index 0000000..c7e5fcf --- /dev/null +++ b/mseide-msegui/apps/ide/templates/console/project.pas @@ -0,0 +1,8 @@ +program ${%PROJECTNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifdef mswindows}{$apptype console}{$endif} +uses + {$ifdef FPC}{$ifdef unix}cthreads,cwstring,{$endif}{$endif} + sysutils; +begin +end. diff --git a/mseide-msegui/apps/ide/templates/console/projectarm.pas b/mseide-msegui/apps/ide/templates/console/projectarm.pas new file mode 100644 index 0000000..c7e5fcf --- /dev/null +++ b/mseide-msegui/apps/ide/templates/console/projectarm.pas @@ -0,0 +1,8 @@ +program ${%PROJECTNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifdef mswindows}{$apptype console}{$endif} +uses + {$ifdef FPC}{$ifdef unix}cthreads,cwstring,{$endif}{$endif} + sysutils; +begin +end. diff --git a/mseide-msegui/apps/ide/templates/console/unit.pas b/mseide-msegui/apps/ide/templates/console/unit.pas new file mode 100644 index 0000000..0cbfb2b --- /dev/null +++ b/mseide-msegui/apps/ide/templates/console/unit.pas @@ -0,0 +1,5 @@ +unit ${%UNITNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +implementation +end. diff --git a/mseide-msegui/apps/ide/templates/copytarget.sh b/mseide-msegui/apps/ide/templates/copytarget.sh new file mode 100755 index 0000000..078d4c1 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/copytarget.sh @@ -0,0 +1,17 @@ +#!/bin/sh +# parameters: +#1 2 [3] +#SOURCE, DEST, --wait +# +echo Copying by scp \"$1\" to \"$2\" +if scp $1 $2 +then + if [[ $3 == "--wait" ]] + then + echo Please press return key + read + fi +else + echo Please press return key + read +fi \ No newline at end of file diff --git a/mseide-msegui/apps/ide/templates/crossarmconsole.prj b/mseide-msegui/apps/ide/templates/crossarmconsole.prj new file mode 100644 index 0000000..11b497b --- /dev/null +++ b/mseide-msegui/apps/ide/templates/crossarmconsole.prj @@ -0,0 +1,1143 @@ +[componentpalette] +order0=0 +order1=0 +order2=0 +order3=0 +order4=0 +order5=0 +order6=0 +order7=0 +order8=0 +order9=0 +order10=0 +order11=0 +order12=0 +order13=0 +order14=0 +order15=0 +order16=0 +[projectoptions] +projectdir=/home/mse/packs/standard/git/mseide-msegui_arm/apps/ide/templates +projectfilename=/home/mse/packs/standard/git/mseide-msegui_arm/apps/ide/templates/crossarmconsole.prj +options=107 + [projectoptionsfo.toolshortcuts] + dropdowncolwidths=3 + 70 + 70 + 70 + [projectoptionsfo.twidgetgrid3] + propcolwidthref=723 + sortdescend0=0 + sortdescend1=0 + sortdescend2=0 + sortdescend3=0 + width4=97 + sortdescend4=0 + width5=78 + sortdescend5=0 + width6=50 + sortdescend6=0 + width7=50 + sortdescend7=0 + width8=99 + sortdescend8=0 + width9=295 + sortdescend9=0 + [projectoptionsfo.twidgetgrid4] + propcolwidthref=549 + width0=96 + sortdescend0=0 + sortdescend1=0 + width2=73 + sortdescend2=0 + width3=263 + sortdescend3=0 + width4=276 + sortdescend4=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=16 + [projectoptionsfo.newfile] + firsttab=0 + index=0 + [projectoptionsfo.fontaliasgrid] + propcolwidthref=386 + width0=98 + sortdescend0=0 + width1=375 + sortdescend1=0 + width2=50 + sortdescend2=0 + width3=50 + sortdescend3=0 + width4=50 + sortdescend4=0 + width5=50 + sortdescend5=0 + width6=70 + sortdescend6=0 + [projectoptionsfo.macrosplitter] + x=0 + y=121 + xprop=1 + yprop=0.23984526112186 + [projectoptionsfo.macrogrid] + propcolwidthref=515 + sortdescend0=0 + sortdescend1=0 + sortdescend2=0 + sortdescend3=0 + sortdescend4=0 + sortdescend5=0 + width6=146 + sortdescend6=0 + width7=503 + sortdescend7=0 + [projectoptionsfo.makegroupbox] + firsttab=0 + index=1 + [projectoptionsfo.exceptionsgrid] + propcolwidthref=707 + width0=47 + sortdescend0=0 + width1=701 + sortdescend1=0 + [projectoptionsfo.ttabwidget1] + firsttab=0 + index=4 + [projectoptionsfo.filefiltergrid] + propcolwidthref=615 + width0=112 + sortdescend0=0 + width1=608 + sortdescend1=0 + [projectoptionsfo.ttabwidget2] + firsttab=0 + index=0 + [projectoptionsfo.ttabwidget3] + firsttab=0 + index=0 + [projectoptionsfo.tabwidget] + firsttab=0 + index=3 + [projectoptionsfo] + stackedunder= + x=19 + y=122 + cx=756 + cy=568 +mainfile=${PROJECTNAME}.pas +targetfile=${PROJECTNAME}${EXEEXT} +makecommand=${COMPILER} +makedir= +unitdirs=0 +unitpref=-Fu +incpref=-Fi +libpref=-Fl +objpref=-Fo +targpref=-o +befcommand=0 +aftcommand=0 +makeoptions=4 + -Xg -l -Mobjfpc -Sh -Fcutf8 ${FPCOPT} + -gl -O- + -B + -O2 -XX -Xs -CX +codetemplatedirs=1 + ${TEMPLATEDIR} +fontnames=0 +reversepathorder=0 +usercolors=30 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +usercolorcomment=30 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +formatmacronames=0 +formatmacrovalues=0 +settingsfile= +settingseditor=0 +settingsdebugger=0 +settingsmacros=0 +settingstemplates=0 +settingstools=0 +settingsstorage=0 +settingscomponentstore=0 +settingsprojecttree=0 +settingslayout=0 +settingsautoload=0 +settingsautosave=0 +befcommandon=0 +makeoptionson=4 + 63 + 31 + 34 + 32 +aftcommandon=0 +unitdirson=0 +fontalias=0 +fontancestors=0 +fontheights=0 +fontwidths=0 +fontoptions=0 +fontxscales=0 +uid=0 +sourcefilemasks=3 + "*.pas" "*.dpr" "*.lpr" "*.pp" "*.inc" + "*.c" "*.cc" "*.h" + "*.mfm" +syntaxdeffiles=3 + ${SYNTAXDEFDIR}pascal.sdef + ${SYNTAXDEFDIR}cpp.sdef + ${SYNTAXDEFDIR}objecttext.sdef +filemasknames=3 + Source + Forms + All Files +filemasks=3 + "*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + *.mfm + * +showgrid=1 +snaptogrid=1 +moveonfirstclick=1 +noformdesignerdocking=0 +componenthints=1 +gridsizex=8 +gridsizey=8 +autoindent=1 +blockindent=1 +linenumberson=0 +rightmarginon=1 +rightmarginchars=80 +scrollheight=0 +tabstops=4 +spacetabs=0 +showtabs=0 +tabindent=0 +editfontname=mseide_source +editfontheight=0 +editfontwidth=0 +editfontextraspace=0 +editfontcolor=-1879048183 +editbkcolor=-1879048186 +statementcolor=14745599 +pairmarkcolor=-2147483642 +editfontantialiased=1 +editmarkbrackets=1 +editmarkpairwords=0 +backupfilecount=2 +encoding=1 +eolstyle=1 +trimtrailingwhitespace=0 +codetemplatedirs=1 + ${TEMPLATEDIR} +debugcommand=${DEBUGGER} +debugoptions= +debugtarget= +runcommand= +xtermcommand=xterm -S${PTSN}/${PTSH} +remoteconnection=${REMOTETARGET} +uploadcommand=${COPYTARGET} +gdbprocessor=arm +gdbservercommand=${RUNTARGET} +gdbservercommandattach= +beforeconnect= +afterconnect= +beforeload= +afterload= +beforerun= +sourcebase= +sourcedirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ + ./ +defines=0 +progparameters= +progworkingdirectory= +envvarnames=0 +envvarvalues=0 +defineson=0 +stoponexception=0 +valuehints=1 +activateonbreak=1 +raiseonbreak=1 +showconsole=0 +externalconsole=0 +settty=1 +gdbdownload=0 +downloadalways=0 +startupbkpt=0 +startupbkpton=0 +gdbsimulator=0 +gdbserverstartonce=0 +gdbloadtimeout= +gdbserverwait=2 +nogdbserverexit=1 +gdbservertty=0 +exceptclassnames=1 + EconvertError +exceptignore=1 + 0 +nodebugbeginend=0 +fpcgdbworkaround=1 +macroon=22 + 6 + 6 + 2 + 4 + 6 + 6 + 6 + 6 + 6 + 6 + 57 + 6 + 57 + 6 + 57 + 6 + 6 + 6 + 6 + 2 + 4 + 57 +macronames=22 + TARGETPROJECTDIR + TARGETENV + ABI + ABI + TARGETDIR + HOSTTARGETDIR + MSEDIR + TARGETEXE + TARGETPATH + COPYTARGET + COPYTARGET + RUNTARGET + RUNTARGET + REMOTETARGET + REMOTETARGET + CROSSFPC + DEBUGGER + COMPILER + FPCOPTIONS + FPCOPT + FPCOPT + FPCOPT +macrovalues=22 + your project dir on target example: /home/pi/proj/test + XAUTHORITY=/home/pi/.Xauthority DISPLAY=:0.0 + eabi + eabihf + ${TARGETPROJECTDIR} + ${CROSSDESTDIR}/${TARGETPROJECTDIR} + ${CROSSMSEDIR}/ + ${PROJECTNAME}${EXEEXT} + ${TARGETDIR}/${TARGETEXE} + xterm -e ${TEMPLATEDIR}copytarget.sh ${TARGETEXE} ${REMOTEUSER}@${REMOTEIP}:${TARGETDIR}/${TARGETEXE} + + xterm -e ${TEMPLATEDIR}runsshgdbserver.sh ${HOSTIP} ${REMOTEIP} ${REMOTEPORT} ${REMOTEUSER} "${TARGETENV}" ${TARGETPATH} ${TARGETPARAMS} + + remote ${REMOTEIP}:${REMOTEPORT} + + ${CROSSFPCDIR}/${ABI} + ${CROSSFPC}/bin/gdb + ${CROSSFPC}/lib/fpc/${CROSSFPCVERSION}/ppcrossarm + -n -Xd -viwn -e${CROSSFPC}/bin -Fl${CROSSFPC}/lib -Fu${CROSSFPC}/lib/fpc/${CROSSFPCVERSION}/units/arm-linux/* + ${FPCOPTIONS} + ${FPCOPTIONS} -CpARMV6 -CfVFPV2 + +groupcomments=6 + Local + Remote eabi + Remote eabihf (Raspberry Pi) + + + +toolmenus=0 +toolfiles=0 +toolparams=0 +toolsave=0 +toolhide=0 +toolparse=0 +toolmessages=0 +toolshortcuts=0 +scriptbeforecopy= +scriptaftercopy= +newprojectfiles=1 + ${TEMPLATEDIR}/console/projectarm.pas +newprojectfilesdest=1 + ${%PROJECTNAME%}.pas +newfinames=3 + Program + Unit + Textfile +newfifilters=3 + "*.pas" "*.pp" + "*.pas" "*.pp" + +newfiexts=3 + pas + pas + +newfisources=3 + ${TEMPLATEDIR}default/program.pas + ${TEMPLATEDIR}default/unit.pas + +newfonames=11 + Mainform + Simple Form + Docking Form + Datamodule + Subform + Scrollboxform + Tabform + Dockpanel + Report + Scriptform + Inherited Form +newfonamebases=11 + form + form + form + module + form + form + form + form + report + script + form +newfosources=11 + ${TEMPLATEDIR}default/mainform.pas + ${TEMPLATEDIR}default/simpleform.pas + ${TEMPLATEDIR}default/dockingform.pas + ${TEMPLATEDIR}default/datamodule.pas + ${TEMPLATEDIR}default/subform.pas + ${TEMPLATEDIR}default/scrollboxform.pas + ${TEMPLATEDIR}default/tabform.pas + ${TEMPLATEDIR}default/dockpanelform.pas + ${TEMPLATEDIR}default/report.pas + ${TEMPLATEDIR}default/pascform.pas + ${TEMPLATEDIR}default/inheritedform.pas +newfoforms=11 + ${TEMPLATEDIR}default/mainform.mfm + ${TEMPLATEDIR}default/simpleform.mfm + ${TEMPLATEDIR}default/dockingform.mfm + ${TEMPLATEDIR}default/datamodule.mfm + ${TEMPLATEDIR}default/subform.mfm + ${TEMPLATEDIR}default/scrollboxform.mfm + ${TEMPLATEDIR}default/tabform.mfm + ${TEMPLATEDIR}default/dockpanelform.mfm + ${TEMPLATEDIR}default/report.mfm + ${TEMPLATEDIR}default/pascform.mfm + ${TEMPLATEDIR}default/inheritedform.mfm +expandprojectfilemacros=1 + 1 +loadprojectfile=1 + 1 +newinheritedforms=11 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 +messageoutputfile= +modulenames=0 +moduletypes=0 +modulefiles=0 +macrogroup=2 +forcezorder=0 +stripmessageesc=0 +copymessages=0 +closemessages=1 +checkmethods=1 +colorerror=-1610612712 +colorwarning=-1610612717 +colornote=-1610612716 +sigsettings=27 + 1,1,T,F + 3,3,T,F + 4,4,T,F + 6,6,T,F + 7,7,T,F + 8,8,T,F + 9,9,T,F + 10,10,T,F + 11,11,T,F + 12,12,T,F + 13,13,T,F + 15,15,T,F + 16,16,T,F + 17,17,F,F + 18,18,T,F + 19,19,T,F + 20,20,T,F + 21,21,T,F + 22,22,T,F + 23,23,T,F + 24,24,T,F + 25,25,T,F + 26,26,T,F + 27,27,T,F + 28,28,T,F + 29,29,F,F + 30,30,T,F +defaultmake=1 +[breakpoints] +on=0 +path=0 +line=0 +address=0 +addbkpt=0 +ignore=0 +condition=0 +panels=2 + panel1 + panel2 +units= + ( + a=0,4132,6,Pascal Units + ) +cmodules= + ( + a=0,4132,6,C Modules + ) +files= + ( + a=0,4132,6,Text Files + ) +[componentstore] +storedir=/home/mse/packs/standard/git/mseide-msegui_arm/apps/ide/compstore/ +filename= +[components] +[selecteditpage] +colwidth=100 +x=0 +y=0 +cx=0 +cy=0 +[progparams] +progparamhistory=0 +workdirparamhistory=0 +envvarons=0 +[edit] +hintwidth=0 +hintheight=0 +finddtext= +findhistory=0 +findoptions=1 +editpos=0 +sourcefiles=0 +relpaths=0 +ismoduletexts=0 +modules=0 +moduleoptions=0 +visiblemodules=0 +nomenumodules=0 +[sourcefo.tabwidget] +tabsize=114 +firsttab=0 +index=-1 +[layout] +windowlayout=530 + [mainfo.openform] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.projectfiledia] + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + [mainfo.openfile] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.basedock] + splitdir=2 + useroptions=268582016 + [mainfo] + splitdir=0 + useroptions=838860923 + stackedunder=targetconsolefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=25 + cx=323 + cy=64 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [targetconsolefo] + splitdir=0 + useroptions=805322857 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=554 + cx=323 + cy=169 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [threadsfo] + splitdir=0 + useroptions=805322857 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=37 + y=270 + cx=349 + cy=276 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo] + splitdir=0 + useroptions=805322875 + stackedunder=componentpalettefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=100 + y=100 + cx=453 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo.add] + value=0 + [memoryfo.memon] + value=0 + [memoryfo.bitwidth] + value=0 + [memoryfo.cnt] + value=0 + [disassfo] + splitdir=0 + useroptions=805322859 + stackedunder=cpuarmfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=162 + y=502 + cx=564 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [findinfilefo] + splitdir=0 + useroptions=268451947 + stackedunder=disassfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=548 + y=115 + cx=369 + cy=198 + rcx=0 + rcy=0 + [projecttreefo] + splitdir=0 + useroptions=805322859 + stackedunder=memoryfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=263 + y=431 + cx=286 + cy=201 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [projecttreefo.grid] + propcolwidthref=135 + width0=141 + sortdescend0=0 + width1=129 + sortdescend1=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=16 + [stackfo] + splitdir=0 + useroptions=805331049 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=276 + rcx=0 + rcy=0 + [watchpointsfo] + splitdir=0 + useroptions=805322857 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=120 + y=368 + cx=483 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [watchpointsfo.grid] + propcolwidthref=352 + sortdescend0=0 + values1=0 + values1_ci=-1 + width1=33 + sortdescend1=0 + values2=0 + width2=158 + sortdescend2=0 + width4=34 + sortdescend4=0 + values5=0 + values5_ci=-1 + width5=38 + sortdescend5=0 + values6=0 + width6=184 + sortdescend6=0 + [breakpointsfo] + splitdir=0 + useroptions=268451947 + stackedunder=projecttreefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=107 + y=404 + cx=636 + cy=128 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [breakpointsfo.bkptson] + value=1 + [objectinspectorfo] + splitdir=0 + useroptions=805322859 + stackedunder=breakpointsfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=724 + y=157 + cx=296 + cy=566 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [objectinspectorfo.grid] + propcolwidthref=286 + width0=105 + sortdescend0=0 + width1=175 + sortdescend1=0 + [symbolfo] + splitdir=0 + useroptions=805322875 + stackedunder=findinfilefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=142 + y=257 + cx=361 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [symbolfo.grid] + propcolwidthref=222 + values0=0 + width0=111 + sortdescend0=0 + width1=135 + sortdescend1=0 + [symbolfo.symbol] + [watchfo] + splitdir=0 + useroptions=805331049 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=279 + cx=313 + cy=221 + rcx=0 + rcy=0 + [watchfo.grid] + propcolwidthref=116 + values0=0 + values0_ci=-1 + sortdescend0=0 + values1=0 + width1=152 + sortdescend1=0 + values3=0 + values3_ci=-1 + sortdescend3=0 + values4=0 + values4_ci=-1 + width4=13 + sortdescend4=0 + [watchfo.watchon] + [watchfo.expression] + [watchfo.watcheson] + value=1 + [messagefo] + splitdir=0 + useroptions=805355627 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=510 + cx=675 + cy=95 + rcx=0 + rcy=0 + [componentstorefo] + splitdir=0 + useroptions=805331067 + stackedunder=symbolfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=305 + y=101 + cx=445 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentstorefo.grid] + propcolwidthref=435 + width0=111 + sortdescend0=0 + sortdescend1=0 + width2=112 + sortdescend2=0 + width3=185 + sortdescend3=0 + [componentstorefo.storefiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui_arm/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui_arm/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.groupfiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui_arm/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui_arm/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.compfiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentpalettefo] + splitdir=0 + useroptions=805331051 + stackedunder=componentstorefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=25 + cx=685 + cy=103 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentpalettefo.componentpages] + activetab=0 + [debuggerfo] + splitdir=0 + useroptions=268460139 + parent=mainfo.basedock + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=28 + rcx=0 + rcy=0 + [sourcefo] + splitdir=0 + useroptions=805322857 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=675 + cy=507 + rcx=0 + rcy=0 + [actionsmo.watchesonact] + checked=1 + [actionsmo.bluedotsonact] + checked=1 + [mainfo.panel1] + splitdir=2 + useroptions=838893035 + stackedunder=mainfo.panel2 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=118 + cx=685 + cy=605 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel2] + splitdir=2 + useroptions=838893035 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=25 + cx=323 + cy=500 + rcx=0 + rcy=0 + wsize=0 + active=1 + visible=1 + [cpuarmfo] + irqoff=0 + splitdir=0 + useroptions=268451947 + stackedunder=mainfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=174 + y=158 + cx=261 + cy=253 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 +[targetconsole] +finddtext= +findhistory=0 +findoptions=1 diff --git a/mseide-msegui/apps/ide/templates/crossarmdefault.prj b/mseide-msegui/apps/ide/templates/crossarmdefault.prj new file mode 100644 index 0000000..f09d00a --- /dev/null +++ b/mseide-msegui/apps/ide/templates/crossarmdefault.prj @@ -0,0 +1,1175 @@ +[componentpalette] +order0=0 +order1=0 +order2=0 +order3=0 +order4=0 +order5=0 +order6=0 +order7=0 +order8=0 +order9=0 +order10=0 +order11=0 +order12=0 +order13=0 +order14=0 +order15=0 +order16=0 +[projectoptions] +projectdir=/home/mse/packs/standard/git/mseide-msegui_arm/apps/ide/templates +projectfilename=/home/mse/packs/standard/git/mseide-msegui_arm/apps/ide/templates/crossarmdefault.prj +options=107 + [projectoptionsfo.toolshortcuts] + dropdowncolwidths=3 + 70 + 70 + 70 + [projectoptionsfo.twidgetgrid3] + propcolwidthref=723 + sortdescend0=0 + sortdescend1=0 + sortdescend2=0 + sortdescend3=0 + width4=97 + sortdescend4=0 + width5=78 + sortdescend5=0 + width6=50 + sortdescend6=0 + width7=50 + sortdescend7=0 + width8=99 + sortdescend8=0 + width9=295 + sortdescend9=0 + [projectoptionsfo.twidgetgrid4] + propcolwidthref=549 + width0=96 + sortdescend0=0 + sortdescend1=0 + width2=73 + sortdescend2=0 + width3=263 + sortdescend3=0 + width4=276 + sortdescend4=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=16 + [projectoptionsfo.newfile] + firsttab=0 + index=0 + [projectoptionsfo.fontaliasgrid] + propcolwidthref=386 + width0=98 + sortdescend0=0 + width1=375 + sortdescend1=0 + width2=50 + sortdescend2=0 + width3=50 + sortdescend3=0 + width4=50 + sortdescend4=0 + width5=50 + sortdescend5=0 + width6=70 + sortdescend6=0 + [projectoptionsfo.macrosplitter] + x=0 + y=121 + xprop=1 + yprop=0.23984526112186 + [projectoptionsfo.macrogrid] + propcolwidthref=515 + sortdescend0=0 + sortdescend1=0 + sortdescend2=0 + sortdescend3=0 + sortdescend4=0 + sortdescend5=0 + width6=146 + sortdescend6=0 + width7=503 + sortdescend7=0 + [projectoptionsfo.makegroupbox] + firsttab=0 + index=1 + [projectoptionsfo.exceptionsgrid] + propcolwidthref=707 + width0=47 + sortdescend0=0 + width1=701 + sortdescend1=0 + [projectoptionsfo.ttabwidget1] + firsttab=0 + index=4 + [projectoptionsfo.filefiltergrid] + propcolwidthref=615 + width0=112 + sortdescend0=0 + width1=608 + sortdescend1=0 + [projectoptionsfo.ttabwidget2] + firsttab=0 + index=0 + [projectoptionsfo.ttabwidget3] + firsttab=0 + index=0 + [projectoptionsfo.tabwidget] + firsttab=0 + index=3 + [projectoptionsfo] + stackedunder= + x=19 + y=122 + cx=756 + cy=568 +mainfile=${PROJECTNAME}.pas +targetfile=${PROJECTNAME}${EXEEXT} +makecommand=${COMPILER} +makedir= +unitdirs=3 + ${MSEDIR}lib/addon/*/ + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ +unitpref=-Fu +incpref=-Fi +libpref=-Fl +objpref=-Fo +targpref=-o +befcommand=0 +aftcommand=0 +makeoptions=4 + -Xg -l -Mobjfpc -Sh -Fcutf8 ${FPCOPT} + -gl -O- + -B + -O2 -XX -Xs -CX +codetemplatedirs=1 + ${TEMPLATEDIR} +fontnames=0 +reversepathorder=0 +usercolors=30 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +usercolorcomment=30 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +formatmacronames=0 +formatmacrovalues=0 +settingsfile= +settingseditor=0 +settingsdebugger=0 +settingsmacros=0 +settingstemplates=0 +settingstools=0 +settingsstorage=0 +settingscomponentstore=0 +settingsprojecttree=0 +settingslayout=0 +settingsautoload=0 +settingsautosave=0 +befcommandon=0 +makeoptionson=4 + 63 + 31 + 34 + 32 +aftcommandon=0 +unitdirson=3 + 196671 + 65599 + 65599 +fontalias=0 +fontancestors=0 +fontheights=0 +fontwidths=0 +fontoptions=0 +fontxscales=0 +uid=0 +sourcefilemasks=3 + "*.pas" "*.dpr" "*.lpr" "*.pp" "*.inc" + "*.c" "*.cc" "*.h" + "*.mfm" +syntaxdeffiles=3 + ${SYNTAXDEFDIR}pascal.sdef + ${SYNTAXDEFDIR}cpp.sdef + ${SYNTAXDEFDIR}objecttext.sdef +filemasknames=3 + Source + Forms + All Files +filemasks=3 + "*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + *.mfm + * +showgrid=1 +snaptogrid=1 +moveonfirstclick=1 +noformdesignerdocking=0 +componenthints=1 +gridsizex=8 +gridsizey=8 +autoindent=1 +blockindent=1 +linenumberson=0 +rightmarginon=1 +rightmarginchars=80 +scrollheight=0 +tabstops=4 +spacetabs=0 +showtabs=0 +tabindent=0 +editfontname=mseide_source +editfontheight=0 +editfontwidth=0 +editfontextraspace=0 +editfontcolor=-1879048183 +editbkcolor=-1879048186 +statementcolor=14745599 +pairmarkcolor=-2147483642 +editfontantialiased=1 +editmarkbrackets=1 +editmarkpairwords=0 +backupfilecount=2 +encoding=1 +eolstyle=1 +trimtrailingwhitespace=0 +codetemplatedirs=1 + ${TEMPLATEDIR} +debugcommand=${DEBUGGER} +debugoptions= +debugtarget= +runcommand= +xtermcommand=xterm -S${PTSN}/${PTSH} +remoteconnection=${REMOTETARGET} +uploadcommand=${COPYTARGET} +gdbprocessor=auto +gdbservercommand=${RUNTARGET} +gdbservercommandattach= +beforeconnect= +afterconnect= +beforeload= +afterload= +beforerun= +sourcebase= +sourcedirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ + ./ +defines=0 +progparameters= +progworkingdirectory= +envvarnames=0 +envvarvalues=0 +defineson=0 +stoponexception=0 +valuehints=1 +activateonbreak=1 +raiseonbreak=1 +showconsole=0 +externalconsole=0 +settty=1 +gdbdownload=0 +downloadalways=0 +startupbkpt=0 +startupbkpton=0 +gdbsimulator=0 +gdbserverstartonce=0 +gdbloadtimeout= +gdbserverwait=2 +nogdbserverexit=1 +gdbservertty=0 +exceptclassnames=1 + EconvertError +exceptignore=1 + 0 +nodebugbeginend=0 +fpcgdbworkaround=1 +macroon=22 + 6 + 6 + 2 + 4 + 6 + 6 + 6 + 6 + 6 + 6 + 57 + 6 + 57 + 6 + 57 + 6 + 6 + 6 + 6 + 2 + 4 + 57 +macronames=22 + TARGETPROJECTDIR + TARGETENV + ABI + ABI + TARGETDIR + HOSTTARGETDIR + MSEDIR + TARGETEXE + TARGETPATH + COPYTARGET + COPYTARGET + RUNTARGET + RUNTARGET + REMOTETARGET + REMOTETARGET + CROSSFPC + DEBUGGER + COMPILER + FPCOPTIONS + FPCOPT + FPCOPT + FPCOPT +macrovalues=22 + your project dir on target example: /home/pi/proj/test + XAUTHORITY=/home/pi/.Xauthority DISPLAY=:0.0 + eabi + eabihf + ${TARGETPROJECTDIR} + ${CROSSDESTDIR}/${TARGETPROJECTDIR} + ${CROSSMSEDIR}/ + ${PROJECTNAME}${EXEEXT} + ${TARGETDIR}/${TARGETEXE} + xterm -e ${TEMPLATEDIR}copytarget.sh ${TARGETEXE} ${REMOTEUSER}@${REMOTEIP}:${TARGETDIR}/${TARGETEXE} + + xterm -e ${TEMPLATEDIR}runsshgdbserver.sh ${HOSTIP} ${REMOTEIP} ${REMOTEPORT} ${REMOTEUSER} "${TARGETENV}" ${TARGETPATH} ${TARGETPARAMS} + + remote ${REMOTEIP}:${REMOTEPORT} + + ${CROSSFPCDIR}/${ABI} + ${CROSSFPC}/bin/gdb + ${CROSSFPC}/lib/fpc/${CROSSFPCVERSION}/ppcrossarm + -n -Xd -viwn -e${CROSSFPC}/bin -Fl${CROSSFPC}/lib -Fu${CROSSFPC}/lib/fpc/${CROSSFPCVERSION}/units/arm-linux/* + ${FPCOPTIONS} + ${FPCOPTIONS} -CpARMV6 -CfVFPV2 + +groupcomments=6 + Local + Remote eabi + Remote eabihf (Raspberry Pi) + + + +toolmenus=0 +toolfiles=0 +toolparams=0 +toolsave=0 +toolhide=0 +toolparse=0 +toolmessages=0 +toolshortcuts=0 +scriptbeforecopy= +scriptaftercopy= +newprojectfiles=4 + ${TEMPLATEDIR}default/project.pas + ${TEMPLATEDIR}default/main.pas + ${TEMPLATEDIR}default/main.mfm + ${TEMPLATEDIR}default/main_mfm.pas +newprojectfilesdest=4 + ${%PROJECTNAME%}.pas + + + +newfinames=3 + Program + Unit + Textfile +newfifilters=3 + "*.pas" "*.pp" + "*.pas" "*.pp" + +newfiexts=3 + pas + pas + +newfisources=3 + ${TEMPLATEDIR}default/program.pas + ${TEMPLATEDIR}default/unit.pas + +newfonames=11 + Mainform + Simple Form + Docking Form + Datamodule + Subform + Scrollboxform + Tabform + Dockpanel + Report + Scriptform + Inherited Form +newfonamebases=11 + form + form + form + module + form + form + form + form + report + script + form +newfosources=11 + ${TEMPLATEDIR}default/mainform.pas + ${TEMPLATEDIR}default/simpleform.pas + ${TEMPLATEDIR}default/dockingform.pas + ${TEMPLATEDIR}default/datamodule.pas + ${TEMPLATEDIR}default/subform.pas + ${TEMPLATEDIR}default/scrollboxform.pas + ${TEMPLATEDIR}default/tabform.pas + ${TEMPLATEDIR}default/dockpanelform.pas + ${TEMPLATEDIR}default/report.pas + ${TEMPLATEDIR}default/pascform.pas + ${TEMPLATEDIR}default/inheritedform.pas +newfoforms=11 + ${TEMPLATEDIR}default/mainform.mfm + ${TEMPLATEDIR}default/simpleform.mfm + ${TEMPLATEDIR}default/dockingform.mfm + ${TEMPLATEDIR}default/datamodule.mfm + ${TEMPLATEDIR}default/subform.mfm + ${TEMPLATEDIR}default/scrollboxform.mfm + ${TEMPLATEDIR}default/tabform.mfm + ${TEMPLATEDIR}default/dockpanelform.mfm + ${TEMPLATEDIR}default/report.mfm + ${TEMPLATEDIR}default/pascform.mfm + ${TEMPLATEDIR}default/inheritedform.mfm +expandprojectfilemacros=4 + 1 + 1 + 1 + 0 +loadprojectfile=4 + 1 + 1 + 1 + 0 +newinheritedforms=11 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 +messageoutputfile= +modulenames=0 +moduletypes=0 +modulefiles=0 +macrogroup=2 +forcezorder=0 +stripmessageesc=0 +copymessages=0 +closemessages=1 +checkmethods=1 +colorerror=-1610612712 +colorwarning=-1610612717 +colornote=-1610612716 +sigsettings=27 + 1,1,T,F + 3,3,T,F + 4,4,T,F + 6,6,T,F + 7,7,T,F + 8,8,T,F + 9,9,T,F + 10,10,T,F + 11,11,T,F + 12,12,T,F + 13,13,T,F + 15,15,T,F + 16,16,T,F + 17,17,F,F + 18,18,T,F + 19,19,T,F + 20,20,T,F + 21,21,T,F + 22,22,T,F + 23,23,T,F + 24,24,T,F + 25,25,T,F + 26,26,T,F + 27,27,T,F + 28,28,T,F + 29,29,F,F + 30,30,T,F +defaultmake=1 +[breakpoints] +on=0 +path=0 +line=0 +address=0 +addbkpt=0 +ignore=0 +condition=0 +panels=2 + panel1 + panel2 +units= + ( + a=0,4132,6,Pascal Units + ) +cmodules= + ( + a=0,4132,6,C Modules + ) +files= + ( + a=0,4132,6,Text Files + ) +[componentstore] +storedir=/home/mse/packs/standard/git/mseide-msegui_arm/apps/ide/compstore/ +filename=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/default.stg +[components] +[selecteditpage] +colwidth=100 +x=0 +y=0 +cx=0 +cy=0 +[progparams] +progparamhistory=0 +workdirparamhistory=0 +envvarons=0 +[edit] +hintwidth=0 +hintheight=0 +finddtext= +findhistory=0 +findoptions=1 +editpos=0 +sourcefiles=0 +relpaths=0 +ismoduletexts=0 +modules=0 +moduleoptions=0 +visiblemodules=0 +nomenumodules=0 +[sourcefo.tabwidget] +tabsize=114 +firsttab=0 +index=-1 +[layout] +windowlayout=544 + [mainfo.openform] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.projectfiledia] + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + [mainfo.openfile] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.basedock] + splitdir=2 + useroptions=268582016 + [mainfo] + splitdir=0 + useroptions=838860923 + stackedunder=mainfo.panel1 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=25 + cx=323 + cy=64 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [targetconsolefo] + splitdir=0 + useroptions=805322857 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=209 + y=385 + cx=368 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [threadsfo] + splitdir=0 + useroptions=805322857 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=37 + y=270 + cx=349 + cy=276 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo] + splitdir=0 + useroptions=805322875 + stackedunder=cpui386fo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=100 + y=100 + cx=453 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo.add] + value=0 + [memoryfo.memon] + value=0 + [memoryfo.bitwidth] + value=0 + [memoryfo.cnt] + value=0 + [disassfo] + splitdir=0 + useroptions=805322859 + stackedunder=mainfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=162 + y=502 + cx=564 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [findinfilefo] + splitdir=0 + useroptions=268451947 + stackedunder=symbolfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=548 + y=115 + cx=369 + cy=198 + rcx=0 + rcy=0 + [projecttreefo] + splitdir=0 + useroptions=805322859 + stackedunder=memoryfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=263 + y=431 + cx=286 + cy=201 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [projecttreefo.grid] + propcolwidthref=135 + width0=141 + sortdescend0=0 + width1=129 + sortdescend1=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=16 + [stackfo] + splitdir=0 + useroptions=805331049 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=295 + rcx=0 + rcy=0 + [watchpointsfo] + splitdir=0 + useroptions=805322857 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=120 + y=368 + cx=483 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [watchpointsfo.grid] + propcolwidthref=352 + sortdescend0=0 + values1=0 + values1_ci=-1 + width1=33 + sortdescend1=0 + values2=0 + width2=158 + sortdescend2=0 + width4=34 + sortdescend4=0 + values5=0 + values5_ci=-1 + width5=38 + sortdescend5=0 + values6=0 + width6=184 + sortdescend6=0 + [breakpointsfo] + splitdir=0 + useroptions=268451947 + stackedunder=projecttreefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=107 + y=404 + cx=636 + cy=128 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [breakpointsfo.bkptson] + value=1 + [objectinspectorfo] + splitdir=0 + useroptions=805322859 + stackedunder=mainfo.panel2 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=724 + y=157 + cx=296 + cy=566 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [objectinspectorfo.grid] + propcolwidthref=286 + width0=105 + sortdescend0=0 + width1=175 + sortdescend1=0 + [symbolfo] + splitdir=0 + useroptions=805322875 + stackedunder=componentstorefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=142 + y=257 + cx=361 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [symbolfo.grid] + propcolwidthref=222 + values0=14 + + + + + + + + + + + + + + + width0=111 + sortdescend0=0 + width1=135 + sortdescend1=0 + [symbolfo.symbol] + [watchfo] + splitdir=0 + useroptions=805331049 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=298 + cx=313 + cy=236 + rcx=0 + rcy=0 + [watchfo.grid] + propcolwidthref=116 + values0=0 + values0_ci=-1 + sortdescend0=0 + values1=0 + width1=152 + sortdescend1=0 + values3=0 + values3_ci=-1 + sortdescend3=0 + values4=0 + values4_ci=-1 + width4=13 + sortdescend4=0 + [watchfo.watchon] + [watchfo.expression] + [watchfo.watcheson] + value=1 + [messagefo] + splitdir=0 + useroptions=805355627 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=510 + cx=675 + cy=95 + rcx=0 + rcy=0 + [componentstorefo] + splitdir=0 + useroptions=805331067 + stackedunder=disassfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=305 + y=101 + cx=445 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentstorefo.grid] + propcolwidthref=435 + width0=111 + sortdescend0=0 + sortdescend1=0 + width2=112 + sortdescend2=0 + width3=185 + sortdescend3=0 + [componentstorefo.storefiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.groupfiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.compfiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentpalettefo] + splitdir=0 + useroptions=805331051 + stackedunder=objectinspectorfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=25 + cx=685 + cy=103 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [componentpalettefo.componentpages] + activetab=0 + [debuggerfo] + splitdir=0 + useroptions=268460139 + parent=mainfo.basedock + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=28 + rcx=0 + rcy=0 + [sourcefo] + splitdir=0 + useroptions=805322857 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=675 + cy=507 + rcx=0 + rcy=0 + [actionsmo.watchesonact] + checked=1 + [actionsmo.bluedotsonact] + checked=1 + [cpui386fo] + irqoff=0 + splitdir=0 + useroptions=268451947 + stackedunder=findinfilefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=337 + y=295 + cx=273 + cy=207 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [mainfo.panel1] + splitdir=2 + useroptions=838893035 + stackedunder=componentpalettefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=118 + cx=685 + cy=605 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel2] + splitdir=2 + useroptions=838893035 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=189 + cx=323 + cy=534 + rcx=0 + rcy=0 + wsize=0 + active=1 + visible=1 +[targetconsole] +finddtext= +findhistory=0 +findoptions=1 diff --git a/mseide-msegui/apps/ide/templates/default.prj b/mseide-msegui/apps/ide/templates/default.prj new file mode 100644 index 0000000..811c221 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default.prj @@ -0,0 +1,971 @@ +[componentpalette] +order0=0 +order1=0 +order2=0 +order3=0 +order4=0 +order5=0 +order6=0 +order7=0 +order8=0 +order9=0 +order10=0 +order11=0 +order12=0 +order13=0 +order14=0 +order15=0 +order16=0 +order17=0 +order18=0 +[projectoptions] +mainfile=${PROJECTNAME}.pas +targetfile=${PROJECTNAME}${EXEEXT} +messageoutputfile= +makecommand=${COMPILER} +makedir= +unitdirs=3 + ${MSEDIR}lib/addon/*/ + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ +unitpref=-Fu +incpref=-Fi +libpref=-Fl +objpref=-Fo +targpref=-o +befcommand=0 +aftcommand=0 +makeoptions=4 + -Xg -l -Mobjfpc -Sh -Fcutf8 + -gl -O- + -B + -O2 -XX -Xs -CX +codetemplatedirs=1 + ${TEMPLATEDIR} +toolmenus=0 +toolfiles=0 +toolparams=0 +fontnames=0 +scriptbeforecopy= +scriptaftercopy= +newprojectfiles=4 + ${TEMPLATEDIR}default/project.pas + ${TEMPLATEDIR}default/main.pas + ${TEMPLATEDIR}default/main.mfm + ${TEMPLATEDIR}default/main_mfm.pas +newprojectfilesdest=4 + ${%PROJECTNAME%}.pas + + + +newfinames=3 + Program + Unit + Textfile +newfifilters=3 + "*.pas" "*.pp" + "*.pas" "*.pp" + +newfiexts=3 + pas + pas + +newfisources=3 + ${TEMPLATEDIR}default/program.pas + ${TEMPLATEDIR}default/unit.pas + +newfonames=12 + Mainform + Simple Form + Docking Form + Sizing Form + Datamodule + Subform + Scrollboxform + Tabform + Dockpanel + Report + Scriptform + Inherited Form +newfonamebases=12 + form + form + form + form + module + form + form + form + form + report + script + form +newfosources=12 + ${TEMPLATEDIR}default/mainform.pas + ${TEMPLATEDIR}default/simpleform.pas + ${TEMPLATEDIR}default/dockingform.pas + ${TEMPLATEDIR}default/sizingform.pas + ${TEMPLATEDIR}default/datamodule.pas + ${TEMPLATEDIR}default/subform.pas + ${TEMPLATEDIR}default/scrollboxform.pas + ${TEMPLATEDIR}default/tabform.pas + ${TEMPLATEDIR}default/dockpanelform.pas + ${TEMPLATEDIR}default/report.pas + ${TEMPLATEDIR}default/pascform.pas + ${TEMPLATEDIR}default/inheritedform.pas +newfoforms=12 + ${TEMPLATEDIR}default/mainform.mfm + ${TEMPLATEDIR}default/simpleform.mfm + ${TEMPLATEDIR}default/dockingform.mfm + ${TEMPLATEDIR}default/sizingform.mfm + ${TEMPLATEDIR}default/datamodule.mfm + ${TEMPLATEDIR}default/subform.mfm + ${TEMPLATEDIR}default/scrollboxform.mfm + ${TEMPLATEDIR}default/tabform.mfm + ${TEMPLATEDIR}default/dockpanelform.mfm + ${TEMPLATEDIR}default/report.mfm + ${TEMPLATEDIR}default/pascform.mfm + ${TEMPLATEDIR}default/inheritedform.mfm +forcezorder=0 +stripmessageesc=0 +copymessages=0 +closemessages=1 +checkmethods=1 +colorerror=-1610612712 +colorwarning=-1610612717 +colornote=-1610612716 +usercolors=30 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +usercolorcomment=30 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +formatmacronames=0 +formatmacrovalues=0 +settingsfile= +settingseditor=0 +settingsdebugger=0 +settingsstorage=0 +settingsprojecttree=0 +settingsautoload=0 +settingsautosave=0 +modulenames=0 +moduletypes=0 +modulefiles=0 +befcommandon=0 +makeoptionson=4 + 63 + 31 + 34 + 32 +aftcommandon=0 +unitdirson=3 + 196671 + 65599 + 65599 +macroon=0 +macronames=0 +macrovalues=0 +macrogroup=0 +groupcomments=6 + + + + + + +toolsave=0 +toolhide=0 +toolparse=0 +toolmessages=0 +toolshortcuts=0 +fontalias=0 +fontancestors=0 +fontheights=0 +fontwidths=0 +fontoptions=0 +fontxscales=0 +expandprojectfilemacros=4 + 1 + 1 + 1 + 0 +loadprojectfile=4 + 1 + 1 + 1 + 0 +newinheritedforms=12 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 +uid=0 +sourcefilemasks=3 + "*.pas" "*.dpr" "*.lpr" "*.pp" "*.inc" + "*.c" "*.cc" "*.h" + "*.mfm" +syntaxdeffiles=3 + ${SYNTAXDEFDIR}pascal.sdef + ${SYNTAXDEFDIR}cpp.sdef + ${SYNTAXDEFDIR}objecttext.sdef +filemasknames=3 + Source + Forms + All Files +filemasks=3 + "*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + *.mfm + * +showgrid=1 +snaptogrid=1 +moveonfirstclick=1 +noformdesignerdocking=0 +gridsizex=8 +gridsizey=8 +autoindent=1 +blockindent=1 +linenumberson=0 +rightmarginon=1 +rightmarginchars=80 +scrollheight=0 +tabstops=4 +spacetabs=0 +showtabs=0 +tabindent=0 +editfontname=mseide_source +editfontheight=0 +editfontwidth=0 +editfontextraspace=0 +editfontcolor=-1879048183 +editbkcolor=-1879048186 +statementcolor=14745599 +editfontantialiased=1 +editmarkbrackets=1 +backupfilecount=2 +encoding=1 +codetemplatedirs=1 + ${TEMPLATEDIR} +debugcommand=${DEBUGGER} +debugoptions= +debugtarget= +runcommand= +xtermcommand=xterm -S${PTSN}/${PTSH} +remoteconnection= +uploadcommand= +gdbprocessor=auto +gdbservercommand= +gdbservercommandattach= +beforeconnect= +afterconnect= +beforeload= +afterload= +beforerun= +sourcebase= +sourcedirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ + ./ +defines=0 +progparameters= +progworkingdirectory= +envvarnames=0 +envvarvalues=0 +defineson=0 +stoponexception=0 +valuehints=1 +activateonbreak=1 +raiseonbreak=1 +showconsole=0 +externalconsole=0 +settty=1 +gdbdownload=0 +downloadalways=0 +startupbkpt=0 +startupbkpton=0 +gdbsimulator=0 +gdbserverstartonce=0 +gdbloadtimeout= +gdbserverwait=0 +nogdbserverexit=0 +gdbservertty=0 +exceptclassnames=1 + EconvertError +exceptignore=1 + 0 +nodebugbeginend=0 +sigsettings=27 + 1,1,T,F + 3,3,T,F + 4,4,T,F + 6,6,T,F + 7,7,T,F + 8,8,T,F + 9,9,T,F + 10,10,T,F + 11,11,T,F + 12,12,T,F + 13,13,T,F + 15,15,T,F + 16,16,T,F + 17,17,F,F + 18,18,T,F + 19,19,T,F + 20,20,T,F + 21,21,T,F + 22,22,T,F + 23,23,T,F + 24,24,T,F + 25,25,T,F + 26,26,T,F + 27,27,T,F + 28,28,T,F + 29,29,F,F + 30,30,T,F +defaultmake=1 +[breakpoints] +on=0 +path=0 +line=0 +address=0 +addbkpt=0 +ignore=0 +condition=0 +panels=2 + panel1 + panel2 +units= + ( + a=0,4132,6,Pascal Units + ) +cmodules= + ( + a=0,4132,6,C Modules + ) +files= + ( + a=0,4132,6,Text Files + ) +[components] +[selecteditpage] +colwidth=100 +x=0 +y=0 +cx=0 +cy=0 +[progparams] +progparamhistory=0 +workdirparamhistory=0 +envvarons=0 +[edit] +hintwidth=0 +hintheight=0 +finddtext= +findhistory=0 +findoptions=1 +editpos=0 +sourcefiles=0 +relpaths=0 +ismoduletexts=0 +modules=0 +moduleoptions=0 +visiblemodules=0 +nomenumodules=0 +[sourcefo.tabwidget] +tabsize=114 +firsttab=0 +index=-1 +[layout] +windowlayout=530 + [mainfo.openform] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.projectfiledia] + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + [mainfo.openfile] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.basedock] + splitdir=2 + useroptions=146560 + [mainfo] + splitdir=0 + useroptions=33554555 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=25 + cx=323 + cy=64 + rcx=0 + rcy=0 + wsize=0 + active=1 + visible=1 + [targetconsolefo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=209 + y=385 + cx=368 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [threadsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=37 + y=270 + cx=349 + cy=276 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo] + splitdir=0 + useroptions=16507 + stackedunder=componentstorefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=100 + y=100 + cx=453 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo.add] + value=0 + [memoryfo.memon] + value=0 + [memoryfo.bitwidth] + value=0 + [memoryfo.cnt] + value=0 + [disassfo] + splitdir=0 + useroptions=16491 + stackedunder=targetconsolefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=162 + y=502 + cx=564 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [findinfilefo] + splitdir=0 + useroptions=16491 + stackedunder=disassfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=548 + y=115 + cx=369 + cy=198 + rcx=0 + rcy=0 + [projecttreefo] + splitdir=0 + useroptions=16491 + stackedunder=memoryfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=263 + y=431 + cx=286 + cy=201 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [projecttreefo.grid] + propcolwidthref=135 + width0=141 + sortdescend0=0 + width1=129 + sortdescend1=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=16 + [stackfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=295 + rcx=0 + rcy=0 + [watchpointsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=120 + y=368 + cx=483 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [watchpointsfo.grid] + propcolwidthref=352 + sortdescend0=0 + values1=0 + values1_ci=-1 + width1=33 + sortdescend1=0 + values2=0 + width2=158 + sortdescend2=0 + width4=34 + sortdescend4=0 + values5=0 + values5_ci=-1 + width5=38 + sortdescend5=0 + values6=0 + width6=184 + sortdescend6=0 + [breakpointsfo] + splitdir=0 + useroptions=16491 + stackedunder=projecttreefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=107 + y=404 + cx=636 + cy=128 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [breakpointsfo.bkptson] + value=1 + [objectinspectorfo] + splitdir=0 + useroptions=16491 + stackedunder=mainfo.panel2 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=724 + y=157 + cx=296 + cy=566 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [objectinspectorfo.grid] + propcolwidthref=286 + width0=105 + sortdescend0=0 + width1=175 + sortdescend1=0 + [symbolfo] + splitdir=0 + useroptions=16507 + stackedunder=findinfilefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=142 + y=257 + cx=361 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [symbolfo.grid] + propcolwidthref=222 + values0=0 + width0=111 + sortdescend0=0 + width1=135 + sortdescend1=0 + [symbolfo.symbol] + [watchfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=298 + cx=313 + cy=236 + rcx=0 + rcy=0 + [watchfo.grid] + propcolwidthref=118 + values0=0 + values0_ci=-1 + sortdescend0=0 + values1=0 + width1=152 + sortdescend1=0 + values3=0 + values3_ci=-1 + sortdescend3=0 + values4=0 + values4_ci=-1 + width4=13 + sortdescend4=0 + [watchfo.watchon] + [watchfo.expression] + [watchfo.watcheson] + value=1 + [messagefo] + splitdir=0 + useroptions=49259 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=510 + cx=675 + cy=95 + rcx=0 + rcy=0 + [componentstorefo] + splitdir=0 + useroptions=24699 + stackedunder=symbolfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=305 + y=101 + cx=445 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentstorefo.grid] + propcolwidthref=435 + width0=111 + sortdescend0=0 + sortdescend1=0 + width2=112 + sortdescend2=0 + width3=185 + sortdescend3=0 + [componentstorefo.storefiledialog] + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.groupfiledialog] + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.compfiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentpalettefo] + splitdir=0 + useroptions=24683 + stackedunder=objectinspectorfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=25 + cx=685 + cy=103 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [componentpalettefo.componentpages] + activetab=0 + [debuggerfo] + splitdir=0 + useroptions=24683 + parent=mainfo.basedock + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=28 + rcx=0 + rcy=0 + [sourcefo] + splitdir=0 + useroptions=16489 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=675 + cy=507 + rcx=0 + rcy=0 + [actionsmo.watchesonact] + checked=1 + [actionsmo.bluedotsonact] + checked=1 + [cpui386fo] + irqoff=0 + splitdir=0 + useroptions=16491 + stackedunder=mainfo.panel1 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=337 + y=295 + cx=273 + cy=207 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [mainfo.panel1] + splitdir=2 + useroptions=33586667 + stackedunder=componentpalettefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=118 + cx=685 + cy=605 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel2] + splitdir=2 + useroptions=33586667 + stackedunder=mainfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=189 + cx=323 + cy=534 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 +[targetconsole] +finddtext= +findhistory=0 +findoptions=1 diff --git a/mseide-msegui/apps/ide/templates/default/datamodule.mfm b/mseide-msegui/apps/ide/templates/default/datamodule.mfm new file mode 100644 index 0000000..7f9ac12 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/datamodule.mfm @@ -0,0 +1,9 @@ +object ${%FORMNAME%}: t${%FORMNAME%} + left = 100 + top = 100 + moduleclassname = 'tmsedatamodule' + size = ( + 100 + 100 + ) +end diff --git a/mseide-msegui/apps/ide/templates/default/datamodule.pas b/mseide-msegui/apps/ide/templates/default/datamodule.pas new file mode 100644 index 0000000..5d9c66d --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/datamodule.pas @@ -0,0 +1,15 @@ +unit ${%UNITNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseapplication,mseclasses,msedatamodules; + +type + t${%FORMNAME%} = class(tmsedatamodule) + end; +var + ${%FORMNAME%}: t${%FORMNAME%}; +implementation +uses + ${%UNITNAME%}_mfm; +end. diff --git a/mseide-msegui/apps/ide/templates/default/dockingform.mfm b/mseide-msegui/apps/ide/templates/default/dockingform.mfm new file mode 100644 index 0000000..a6611ca --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/dockingform.mfm @@ -0,0 +1,7 @@ +object ${%FORMNAME%}: t${%FORMNAME%} + bounds_x = 100 + bounds_y = 100 + bounds_cx = 445 + bounds_cy = 354 + moduleclassname = 'tdockform' +end diff --git a/mseide-msegui/apps/ide/templates/default/dockingform.pas b/mseide-msegui/apps/ide/templates/default/dockingform.pas new file mode 100644 index 0000000..f5b5980 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/dockingform.pas @@ -0,0 +1,16 @@ +unit ${%UNITNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,mseforms,msedock; + +type + t${%FORMNAME%} = class(tdockform) + end; +var + ${%FORMNAME%}: t${%FORMNAME%}; +implementation +uses + ${%UNITNAME%}_mfm; +end. diff --git a/mseide-msegui/apps/ide/templates/default/dockpanelform.mfm b/mseide-msegui/apps/ide/templates/default/dockpanelform.mfm new file mode 100644 index 0000000..427ac5e --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/dockpanelform.mfm @@ -0,0 +1,20 @@ +object ${%FORMNAME%}: t${%FORMNAME%} + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_topbutton, go_backgroundbutton, go_lockbutton] + frame.dummy = 0 + bounds_x = 100 + bounds_y = 100 + container.frame.framei_left = 0 + container.frame.framei_top = 0 + container.frame.framei_right = 0 + container.frame.framei_bottom = 0 + container.frame.localprops = [frl_fileft, frl_fitop, frl_firight, frl_fibottom] + container.bounds = ( + 0 + 0 + 340 + 200 + ) + dragdock.optionsdock = [od_savepos, od_savezorder, od_canmove, od_canfloat, od_candock, od_acceptsdock, od_dockparent, od_splitvert, od_splithorz, od_tabed, od_proportional, od_propsize] + moduleclassname = 'tdockpanelform' +end diff --git a/mseide-msegui/apps/ide/templates/default/dockpanelform.pas b/mseide-msegui/apps/ide/templates/default/dockpanelform.pas new file mode 100644 index 0000000..5477145 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/dockpanelform.pas @@ -0,0 +1,15 @@ +unit ${%UNITNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,mseforms,msedock,msedockpanelform; + +type + t${%FORMNAME%} = class(tdockpanelform) + end; + +implementation +uses + ${%UNITNAME%}_mfm; +end. diff --git a/mseide-msegui/apps/ide/templates/default/inheritedform.mfm b/mseide-msegui/apps/ide/templates/default/inheritedform.mfm new file mode 100644 index 0000000..1b33623 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/inheritedform.mfm @@ -0,0 +1,3 @@ +inherited ${%FORMNAME%}: t${%FORMNAME%} + moduleclassname = '${%ANCESTORCLASS%}' +end diff --git a/mseide-msegui/apps/ide/templates/default/inheritedform.pas b/mseide-msegui/apps/ide/templates/default/inheritedform.pas new file mode 100644 index 0000000..768132d --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/inheritedform.pas @@ -0,0 +1,17 @@ +unit ${%UNITNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,msewidgets,mseforms, + ${%ANCESTORUNIT%}; + +type + t${%FORMNAME%} = class(${%ANCESTORCLASS%}) + end; +var + ${%FORMNAME%}: t${%FORMNAME%}; +implementation +uses + ${%UNITNAME%}_mfm; +end. diff --git a/mseide-msegui/apps/ide/templates/default/main.mfm b/mseide-msegui/apps/ide/templates/default/main.mfm new file mode 100644 index 0000000..866f6ea --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/main.mfm @@ -0,0 +1,7 @@ +object mainfo: tmainfo + bounds_x = 291 + bounds_y = 247 + bounds_cx = 403 + bounds_cy = 280 + moduleclassname = 'tmainform' +end diff --git a/mseide-msegui/apps/ide/templates/default/main.pas b/mseide-msegui/apps/ide/templates/default/main.pas new file mode 100644 index 0000000..f78b670 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/main.pas @@ -0,0 +1,16 @@ +unit main; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,msewidgets,mseforms; + +type + tmainfo = class(tmainform) + end; +var + mainfo: tmainfo; +implementation +uses + main_mfm; +end. diff --git a/mseide-msegui/apps/ide/templates/default/main_mfm.pas b/mseide-msegui/apps/ide/templates/default/main_mfm.pas new file mode 100644 index 0000000..45702d8 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/main_mfm.pas @@ -0,0 +1,22 @@ +unit main_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,main; + +const + objdata: record size: integer; data: array[0..97] of byte end = + (size: 98; data: ( + 84,80,70,48,7,116,109,97,105,110,102,111,6,109,97,105,110,102,111,8, + 98,111,117,110,100,115,95,120,3,35,1,8,98,111,117,110,100,115,95,121, + 3,247,0,9,98,111,117,110,100,115,95,99,120,3,147,1,9,98,111,117, + 110,100,115,95,99,121,3,24,1,15,109,111,100,117,108,101,99,108,97,115, + 115,110,97,109,101,6,9,116,109,97,105,110,102,111,114,109,0,0) + ); + +initialization + registerobjectdata(@objdata,tmainfo,''); +end. diff --git a/mseide-msegui/apps/ide/templates/default/mainform.mfm b/mseide-msegui/apps/ide/templates/default/mainform.mfm new file mode 100644 index 0000000..03c2aca --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/mainform.mfm @@ -0,0 +1,8 @@ +object ${%FORMNAME%}: t${%FORMNAME%} + bounds_x = 290 + bounds_y = 234 + bounds_cx = 403 + bounds_cy = 280 + container.frame.dummy = 0 + moduleclassname = 'tmainform' +end diff --git a/mseide-msegui/apps/ide/templates/default/mainform.pas b/mseide-msegui/apps/ide/templates/default/mainform.pas new file mode 100644 index 0000000..209cf22 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/mainform.pas @@ -0,0 +1,16 @@ +unit ${%UNITNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus, + msegui,msegraphics,msegraphutils,mseevent,mseclasses,msewidgets,mseforms; + +type + t${%FORMNAME%} = class(tmainform) + end; +var + ${%FORMNAME%}: t${%FORMNAME%}; +implementation +uses + ${%UNITNAME%}_mfm; +end. diff --git a/mseide-msegui/apps/ide/templates/default/pascform.mfm b/mseide-msegui/apps/ide/templates/default/pascform.mfm new file mode 100644 index 0000000..738ac5c --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/pascform.mfm @@ -0,0 +1,11 @@ +object ${%FORMNAME%}: t${%FORMNAME%} + container.bounds_cx = 100 + container.bounds_cy = 100 + container.frame.dummy = 0 + bounds_x = 337 + bounds_y = 266 + bounds_cx = 100 + bounds_cy = 100 + color = -1879048187 + moduleclassname = 'tpascform' +end diff --git a/mseide-msegui/apps/ide/templates/default/pascform.pas b/mseide-msegui/apps/ide/templates/default/pascform.pas new file mode 100644 index 0000000..2055013 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/pascform.pas @@ -0,0 +1,16 @@ +unit ${%UNITNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,msewidgets,mseforms, + msepascalscript; +type + t${%FORMNAME%} = class(tpascform) + end; +var + ${%FORMNAME%}: t${%FORMNAME%}; +implementation +uses + ${%UNITNAME%}_mfm; +end. diff --git a/mseide-msegui/apps/ide/templates/default/program.pas b/mseide-msegui/apps/ide/templates/default/program.pas new file mode 100644 index 0000000..b7b663e --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/program.pas @@ -0,0 +1,11 @@ +program ${%PROGRAMNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifdef FPC} + {$ifdef mswindows}{$apptype gui}{$endif} +{$endif} +uses + {$ifdef FPC}{$ifdef unix}cthreads,{$endif}{$endif}msegui,main; +begin + application.createform(tmainfo,mainfo); + application.run; +end. diff --git a/mseide-msegui/apps/ide/templates/default/project.pas b/mseide-msegui/apps/ide/templates/default/project.pas new file mode 100644 index 0000000..b80591b --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/project.pas @@ -0,0 +1,12 @@ +program ${%PROJECTNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifdef FPC} + {$ifdef mswindows}{$apptype gui}{$endif} +{$endif} +uses + {$ifdef FPC}{$ifdef unix}cthreads,{$endif}{$endif} + msegui,main; +begin + application.createform(tmainfo,mainfo); + application.run; +end. diff --git a/mseide-msegui/apps/ide/templates/default/report.mfm b/mseide-msegui/apps/ide/templates/default/report.mfm new file mode 100644 index 0000000..c05cd94 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/report.mfm @@ -0,0 +1,18 @@ +object ${%FORMNAME%}: t${%FORMNAME%} + ppmm = 3 + font.height = 14 + font.name = 'stf_report' + font.dummy = 0 + grid_size = 2 + repdesigninfo = ( + 177 + 159 + 460 + 369 + ) + moduleclassname = 'treport' + object treportpage1: treportpage + pagewidth = 190 + pageheight = 270 + end +end diff --git a/mseide-msegui/apps/ide/templates/default/report.pas b/mseide-msegui/apps/ide/templates/default/report.pas new file mode 100644 index 0000000..4d552dd --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/report.pas @@ -0,0 +1,18 @@ +unit ${%UNITNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseguiglob,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,msewidgets,mseforms, + msereport; + +type + t${%FORMNAME%} = class(treport) + treportpage1: treportpage; + end; +var + ${%FORMNAME%}: t${%FORMNAME%}; +implementation +uses + ${%UNITNAME%}_mfm; +end. diff --git a/mseide-msegui/apps/ide/templates/default/reppageform.mfm b/mseide-msegui/apps/ide/templates/default/reppageform.mfm new file mode 100644 index 0000000..c0c7ccf --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/reppageform.mfm @@ -0,0 +1,14 @@ +object ${%FORMNAME%}: t${%FORMNAME%} + ppmm = 3 + font.height = 14 + font.name = 'stf_report' + font.dummy = 0 + grid_size = 2 + repdesigninfo = ( + 177 + 159 + 460 + 369 + ) + moduleclassname = 'treppageform' +end diff --git a/mseide-msegui/apps/ide/templates/default/reppageform.pas b/mseide-msegui/apps/ide/templates/default/reppageform.pas new file mode 100644 index 0000000..839dda3 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/reppageform.pas @@ -0,0 +1,17 @@ +unit ${%UNITNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseguiglob,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,msewidgets,mseforms, + msereport; + +type + t${%FORMNAME%} = class(treppageform) + end; +var + ${%FORMNAME%}: t${%FORMNAME%}; +implementation +uses + ${%UNITNAME%}_mfm; +end. diff --git a/mseide-msegui/apps/ide/templates/default/scrollboxform.mfm b/mseide-msegui/apps/ide/templates/default/scrollboxform.mfm new file mode 100644 index 0000000..0d2865d --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/scrollboxform.mfm @@ -0,0 +1,7 @@ +object ${%FORMNAME%}: t${%FORMNAME%} + bounds_x = 100 + bounds_y = 100 + bounds_cx = 100 + bounds_cy = 100 + moduleclassname = 'tscrollboxform' +end diff --git a/mseide-msegui/apps/ide/templates/default/scrollboxform.pas b/mseide-msegui/apps/ide/templates/default/scrollboxform.pas new file mode 100644 index 0000000..547c58c --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/scrollboxform.pas @@ -0,0 +1,15 @@ +unit ${%UNITNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,msewidgets,mseforms; +type + t${%FORMNAME%} = class(tscrollboxform) + end; +var + ${%FORMNAME%}: t${%FORMNAME%}; +implementation +uses + ${%UNITNAME%}_mfm; +end. diff --git a/mseide-msegui/apps/ide/templates/default/simpleform.mfm b/mseide-msegui/apps/ide/templates/default/simpleform.mfm new file mode 100644 index 0000000..b6b8846 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/simpleform.mfm @@ -0,0 +1,7 @@ +object ${%FORMNAME%}: t${%FORMNAME%} + bounds_x = 337 + bounds_y = 266 + bounds_cx = 100 + bounds_cy = 100 + moduleclassname = 'tmseform' +end diff --git a/mseide-msegui/apps/ide/templates/default/simpleform.pas b/mseide-msegui/apps/ide/templates/default/simpleform.pas new file mode 100644 index 0000000..1bd02bf --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/simpleform.pas @@ -0,0 +1,15 @@ +unit ${%UNITNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,msewidgets,mseforms; +type + t${%FORMNAME%} = class(tmseform) + end; +var + ${%FORMNAME%}: t${%FORMNAME%}; +implementation +uses + ${%UNITNAME%}_mfm; +end. diff --git a/mseide-msegui/apps/ide/templates/default/sizingform.mfm b/mseide-msegui/apps/ide/templates/default/sizingform.mfm new file mode 100644 index 0000000..bccf9d4 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/sizingform.mfm @@ -0,0 +1,7 @@ +object ${%FORMNAME%}: t${%FORMNAME%} + bounds_x = 100 + bounds_y = 100 + bounds_cx = 445 + bounds_cy = 354 + moduleclassname = 'tsizingform' +end diff --git a/mseide-msegui/apps/ide/templates/default/sizingform.pas b/mseide-msegui/apps/ide/templates/default/sizingform.pas new file mode 100644 index 0000000..e4fa529 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/sizingform.pas @@ -0,0 +1,16 @@ +unit ${%UNITNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,mseforms,msesizingform; + +type + t${%FORMNAME%} = class(tsizingform) + end; +var + ${%FORMNAME%}: t${%FORMNAME%}; +implementation +uses + ${%UNITNAME%}_mfm; +end. diff --git a/mseide-msegui/apps/ide/templates/default/subform.mfm b/mseide-msegui/apps/ide/templates/default/subform.mfm new file mode 100644 index 0000000..2eb70a9 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/subform.mfm @@ -0,0 +1,7 @@ +object ${%FORMNAME%}: t${%FORMNAME%} + bounds_x = 100 + bounds_y = 100 + bounds_cx = 100 + bounds_cy = 100 + moduleclassname = 'tsubform' +end diff --git a/mseide-msegui/apps/ide/templates/default/subform.pas b/mseide-msegui/apps/ide/templates/default/subform.pas new file mode 100644 index 0000000..0d57d3d --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/subform.pas @@ -0,0 +1,15 @@ +unit ${%UNITNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,msewidgets,mseforms; +type + t${%FORMNAME%} = class(tsubform) + end; +var + ${%FORMNAME%}: t${%FORMNAME%}; +implementation +uses + ${%UNITNAME%}_mfm; +end. diff --git a/mseide-msegui/apps/ide/templates/default/tabform.mfm b/mseide-msegui/apps/ide/templates/default/tabform.mfm new file mode 100644 index 0000000..9302e30 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/tabform.mfm @@ -0,0 +1,7 @@ +object ${%FORMNAME%}: t${%FORMNAME%} + bounds_x = 337 + bounds_y = 266 + bounds_cx = 100 + bounds_cy = 100 + moduleclassname = 'ttabform' +end diff --git a/mseide-msegui/apps/ide/templates/default/tabform.pas b/mseide-msegui/apps/ide/templates/default/tabform.pas new file mode 100644 index 0000000..ca704cf --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/tabform.pas @@ -0,0 +1,15 @@ +unit ${%UNITNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,msewidgets,mseforms,msetabs; +type + t${%FORMNAME%} = class(ttabform) + end; +var + ${%FORMNAME%}: t${%FORMNAME%}; +implementation +uses + ${%UNITNAME%}_mfm; +end. diff --git a/mseide-msegui/apps/ide/templates/default/unit.pas b/mseide-msegui/apps/ide/templates/default/unit.pas new file mode 100644 index 0000000..0cbfb2b --- /dev/null +++ b/mseide-msegui/apps/ide/templates/default/unit.pas @@ -0,0 +1,5 @@ +unit ${%UNITNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +implementation +end. diff --git a/mseide-msegui/apps/ide/templates/layoutconsole.prj b/mseide-msegui/apps/ide/templates/layoutconsole.prj new file mode 100644 index 0000000..cf5a3b5 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/layoutconsole.prj @@ -0,0 +1,891 @@ +[componentpalette] +order0=0 +order1=0 +order2=0 +order3=0 +order4=0 +order5=0 +order6=0 +order7=0 +order8=0 +order9=0 +order10=0 +order11=0 +order12=0 +order13=0 +order14=0 +order15=0 +order16=0 +order17=0 +order18=0 +[projectoptions] +projectdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/templates +projectfilename=/home/mse/packs/standard/git/mseide-msegui/apps/ide/templates/layoutconsole.prj +mainfile= +targetfile= +messageoutputfile= +makecommand=${COMPILER} +makedir= +unitdirs=2 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ +unitpref=-Fu +incpref=-Fi +libpref=-Fl +objpref=-Fo +targpref=-o +befcommand=0 +aftcommand=0 +makeoptions=4 + -l -Mobjfpc -Sh -Fcutf8 + -gl -O- + -B + -O2 -XX -CX -Xs +codetemplatedirs=1 + ${TEMPLATEDIR} +toolmenus=0 +toolfiles=0 +toolparams=0 +fontnames=0 +scriptbeforecopy= +scriptaftercopy= +newprojectfiles=0 +newprojectfilesdest=0 +newfinames=3 + Program + Unit + Textfile +newfifilters=3 + "*.pas" "*.pp" + "*.pas" "*.pp" + +newfiexts=3 + pas + pas + +newfisources=3 + ${TEMPLATEDIR}default/program.pas + ${TEMPLATEDIR}default/unit.pas + +newfonames=11 + Mainform + Simple Form + Docking Form + Datamodule + Subform + Scrollboxform + Tabform + Dockpanel + Report + Scriptform + Inherited Form +newfonamebases=11 + form + form + form + module + form + form + form + form + report + script + form +newfosources=11 + ${TEMPLATEDIR}default/mainform.pas + ${TEMPLATEDIR}default/simpleform.pas + ${TEMPLATEDIR}default/dockingform.pas + ${TEMPLATEDIR}default/datamodule.pas + ${TEMPLATEDIR}default/subform.pas + ${TEMPLATEDIR}default/scrollboxform.pas + ${TEMPLATEDIR}default/tabform.pas + ${TEMPLATEDIR}default/dockpanelform.pas + ${TEMPLATEDIR}default/report.pas + ${TEMPLATEDIR}default/pascform.pas + ${TEMPLATEDIR}default/inheritedform.pas +newfoforms=11 + ${TEMPLATEDIR}default/mainform.mfm + ${TEMPLATEDIR}default/simpleform.mfm + ${TEMPLATEDIR}default/dockingform.mfm + ${TEMPLATEDIR}default/datamodule.mfm + ${TEMPLATEDIR}default/subform.mfm + ${TEMPLATEDIR}default/scrollboxform.mfm + ${TEMPLATEDIR}default/tabform.mfm + ${TEMPLATEDIR}default/dockpanelform.mfm + ${TEMPLATEDIR}default/report.mfm + ${TEMPLATEDIR}default/pascform.mfm + ${TEMPLATEDIR}default/inheritedform.mfm +forcezorder=0 +stripmessageesc=0 +copymessages=0 +closemessages=1 +checkmethods=1 +colorerror=-1610612712 +colorwarning=-1610612717 +colornote=-1610612716 +usercolors=0 +usercolorcomment=0 +formatmacronames=0 +formatmacrovalues=0 +settingsfile= +settingseditor=0 +settingsdebugger=0 +settingsstorage=0 +settingsprojecttree=0 +settingsautoload=0 +settingsautosave=0 +modulenames=0 +moduletypes=0 +modulefiles=0 +befcommandon=0 +makeoptionson=4 + 63 + 31 + 34 + 32 +aftcommandon=0 +unitdirson=2 + 65599 + 65599 +macroon=0 +macronames=0 +macrovalues=0 +macrogroup=0 +groupcomments=0 +toolsave=0 +toolhide=0 +toolparse=0 +toolmessages=0 +toolshortcuts=0 +fontalias=0 +fontancestors=0 +fontheights=0 +fontwidths=0 +fontoptions=0 +fontxscales=0 +expandprojectfilemacros=0 +loadprojectfile=0 +newinheritedforms=11 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 +uid=0 +sourcefilemasks=3 + "*.pas" "*.dpr" "*.lpr" "*.pp" "*.inc" + "*.c" "*.cc" "*.h" + "*.mfm" +syntaxdeffiles=3 + ${SYNTAXDEFDIR}pascal.sdef + ${SYNTAXDEFDIR}cpp.sdef + ${SYNTAXDEFDIR}objecttext.sdef +filemasknames=3 + Source + Forms + All Files +filemasks=3 + "*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + *.mfm + * +showgrid=1 +snaptogrid=1 +moveonfirstclick=1 +noformdesignerdocking=0 +gridsizex=8 +gridsizey=8 +autoindent=1 +blockindent=1 +linenumberson=0 +rightmarginon=1 +rightmarginchars=80 +scrollheight=0 +tabstops=4 +spacetabs=0 +showtabs=0 +tabindent=0 +editfontname=mseide_source +editfontheight=0 +editfontwidth=0 +editfontextraspace=0 +editfontcolor=-1879048183 +editbkcolor=-1879048186 +statementcolor=14745599 +editfontantialiased=1 +editmarkbrackets=1 +backupfilecount=2 +encoding=1 +codetemplatedirs=1 + ${TEMPLATEDIR} +debugcommand=${DEBUGGER} +debugoptions= +debugtarget= +runcommand= +xtermcommand=xterm -S${PTSN}/${PTSH} +remoteconnection= +uploadcommand= +gdbprocessor=auto +gdbservercommand= +gdbservercommandattach= +beforeconnect= +afterconnect= +beforeload= +afterload= +beforerun= +sourcebase= +sourcedirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ + ./ +defines=0 +progparameters= +progworkingdirectory= +envvarnames=0 +envvarvalues=0 +defineson=0 +stoponexception=0 +valuehints=1 +activateonbreak=1 +raiseonbreak=1 +showconsole=0 +externalconsole=0 +settty=1 +gdbdownload=0 +downloadalways=0 +startupbkpt=0 +startupbkpton=0 +gdbsimulator=0 +gdbserverstartonce=0 +gdbloadtimeout= +gdbserverwait=0 +nogdbserverexit=0 +gdbservertty=0 +exceptclassnames=1 + EconvertError +exceptignore=1 + 0 +nodebugbeginend=0 +sigsettings=27 + 1,1,T,F + 3,3,T,F + 4,4,T,F + 6,6,T,F + 7,7,T,F + 8,8,T,F + 9,9,T,F + 10,10,T,F + 11,11,T,F + 12,12,T,F + 13,13,T,F + 15,15,T,F + 16,16,T,F + 17,17,F,F + 18,18,T,F + 19,19,T,F + 20,20,T,F + 21,21,T,F + 22,22,T,F + 23,23,T,F + 24,24,T,F + 25,25,T,F + 26,26,T,F + 27,27,T,F + 28,28,T,F + 29,29,T,F + 30,30,T,F +defaultmake=1 +[breakpoints] +on=0 +path=0 +line=0 +address=0 +addbkpt=0 +ignore=0 +condition=0 +panels=2 + panel1 + panel2 +units= + ( + a=0,4132,6,Pascal Units + ) +cmodules= + ( + a=0,4132,6,C Modules + ) +files= + ( + a=0,4132,6,Text Files + ) +[componentstore] +storedir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ +filename= +[components] +[selecteditpage] +colwidth=100 +x=0 +y=0 +cx=0 +cy=0 +[progparams] +progparamhistory=0 +workdirparamhistory=0 +envvarons=0 +[edit] +hintwidth=0 +hintheight=0 +finddtext= +findhistory=0 +findoptions=1 +editpos=0 +sourcefiles=0 +relpaths=0 +ismoduletexts=0 +modules=0 +moduleoptions=0 +visiblemodules=0 +nomenumodules=0 +[sourcefo.tabwidget] +tabsize=127 +firsttab=0 +index=-1 +[layout] +windowlayout=528 + [mainfo.openform] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.projectfiledia] + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + [mainfo.openfile] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.basedock] + splitdir=2 + useroptions=146560 + [mainfo] + splitdir=0 + useroptions=33554555 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=25 + cx=323 + cy=64 + rcx=0 + rcy=0 + wsize=0 + active=1 + visible=1 + [targetconsolefo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=554 + cx=323 + cy=169 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [threadsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=37 + y=270 + cx=349 + cy=276 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo] + splitdir=0 + useroptions=16507 + stackedunder=componentpalettefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=100 + y=100 + cx=453 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo.add] + value=0 + [memoryfo.memon] + value=0 + [memoryfo.bitwidth] + value=0 + [memoryfo.cnt] + value=0 + [disassfo] + splitdir=0 + useroptions=16491 + stackedunder=targetconsolefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=162 + y=502 + cx=564 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [findinfilefo] + splitdir=0 + useroptions=16491 + stackedunder=disassfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=548 + y=115 + cx=369 + cy=198 + rcx=0 + rcy=0 + [projecttreefo] + splitdir=0 + useroptions=16491 + stackedunder=memoryfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=263 + y=431 + cx=286 + cy=201 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [projecttreefo.grid] + propcolwidthref=135 + width0=141 + sortdescend0=0 + width1=129 + sortdescend1=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=16 + [stackfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=276 + rcx=0 + rcy=0 + [watchpointsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=120 + y=368 + cx=483 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [watchpointsfo.grid] + propcolwidthref=352 + sortdescend0=0 + values1=0 + values1_ci=-1 + width1=33 + sortdescend1=0 + values2=0 + width2=158 + sortdescend2=0 + width4=34 + sortdescend4=0 + values5=0 + values5_ci=-1 + width5=38 + sortdescend5=0 + values6=0 + width6=184 + sortdescend6=0 + [breakpointsfo] + splitdir=0 + useroptions=16491 + stackedunder=projecttreefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=107 + y=404 + cx=636 + cy=128 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [breakpointsfo.bkptson] + value=1 + [objectinspectorfo] + splitdir=0 + useroptions=16491 + stackedunder=breakpointsfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=724 + y=157 + cx=296 + cy=566 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [objectinspectorfo.grid] + propcolwidthref=286 + width0=105 + sortdescend0=0 + width1=175 + sortdescend1=0 + [symbolfo] + splitdir=0 + useroptions=16507 + stackedunder=findinfilefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=142 + y=257 + cx=361 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [symbolfo.grid] + propcolwidthref=222 + values0=0 + width0=111 + sortdescend0=0 + width1=135 + sortdescend1=0 + [symbolfo.symbol] + [watchfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=279 + cx=313 + cy=221 + rcx=0 + rcy=0 + [watchfo.grid] + propcolwidthref=118 + values0=0 + values0_ci=-1 + sortdescend0=0 + values1=0 + width1=152 + sortdescend1=0 + values3=0 + values3_ci=-1 + sortdescend3=0 + values4=0 + values4_ci=-1 + width4=13 + sortdescend4=0 + [watchfo.watchon] + [watchfo.expression] + [watchfo.watcheson] + value=1 + [messagefo] + splitdir=0 + useroptions=49259 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=510 + cx=675 + cy=95 + rcx=0 + rcy=0 + [componentstorefo] + splitdir=0 + useroptions=24699 + stackedunder=symbolfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=305 + y=101 + cx=445 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentstorefo.grid] + propcolwidthref=435 + width0=111 + sortdescend0=0 + sortdescend1=0 + width2=112 + sortdescend2=0 + width3=185 + sortdescend3=0 + [componentstorefo.storefiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.groupfiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.compfiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentpalettefo] + splitdir=0 + useroptions=24683 + stackedunder=componentstorefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=25 + cx=685 + cy=103 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentpalettefo.componentpages] + activetab=0 + [debuggerfo] + splitdir=0 + useroptions=24683 + parent=mainfo.basedock + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=28 + rcx=0 + rcy=0 + [sourcefo] + splitdir=0 + useroptions=16489 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=675 + cy=507 + rcx=0 + rcy=0 + [actionsmo.watchesonact] + checked=1 + [actionsmo.bluedotsonact] + checked=1 + [cpui386fo] + irqoff=0 + splitdir=0 + useroptions=16491 + stackedunder=mainfo.panel1 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=25 + cx=273 + cy=207 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel1] + splitdir=2 + useroptions=33586667 + stackedunder=mainfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=118 + cx=685 + cy=605 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel2] + splitdir=2 + useroptions=33586667 + stackedunder=cpui386fo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=25 + cx=323 + cy=500 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 +[targetconsole] +finddtext= +findhistory=0 +findoptions=1 diff --git a/mseide-msegui/apps/ide/templates/layoutdockedforms.prj b/mseide-msegui/apps/ide/templates/layoutdockedforms.prj new file mode 100644 index 0000000..ef2fbf6 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/layoutdockedforms.prj @@ -0,0 +1,956 @@ +[componentpalette] +order0=0 +order1=0 +order2=0 +order3=0 +order4=0 +order5=0 +order6=0 +order7=0 +order8=0 +order9=0 +order10=0 +order11=0 +order12=0 +order13=0 +order14=0 +order15=0 +order16=0 +order17=0 +order18=0 +[projectoptions] +projectdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/templates +projectfilename=/home/mse/packs/standard/git/mseide-msegui/apps/ide/templates/layoutdockedforms.prj +mainfile= +targetfile= +messageoutputfile= +makecommand=${COMPILER} +makedir= +unitdirs=2 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ +unitpref=-Fu +incpref=-Fi +libpref=-Fl +objpref=-Fo +targpref=-o +befcommand=0 +aftcommand=0 +makeoptions=4 + -l -Mobjfpc -Sh -Fcutf8 + -gl -O- + -B + -O2 -XX -CX -Xs +codetemplatedirs=1 + ${TEMPLATEDIR} +toolmenus=0 +toolfiles=0 +toolparams=0 +fontnames=0 +scriptbeforecopy= +scriptaftercopy= +newprojectfiles=0 +newprojectfilesdest=0 +newfinames=3 + Program + Unit + Textfile +newfifilters=3 + "*.pas" "*.pp" + "*.pas" "*.pp" + +newfiexts=3 + pas + pas + +newfisources=3 + ${TEMPLATEDIR}default/program.pas + ${TEMPLATEDIR}default/unit.pas + +newfonames=11 + Mainform + Simple Form + Docking Form + Datamodule + Subform + Scrollboxform + Tabform + Dockpanel + Report + Scriptform + Inherited Form +newfonamebases=11 + form + form + form + module + form + form + form + form + report + script + form +newfosources=11 + ${TEMPLATEDIR}default/mainform.pas + ${TEMPLATEDIR}default/simpleform.pas + ${TEMPLATEDIR}default/dockingform.pas + ${TEMPLATEDIR}default/datamodule.pas + ${TEMPLATEDIR}default/subform.pas + ${TEMPLATEDIR}default/scrollboxform.pas + ${TEMPLATEDIR}default/tabform.pas + ${TEMPLATEDIR}default/dockpanelform.pas + ${TEMPLATEDIR}default/report.pas + ${TEMPLATEDIR}default/pascform.pas + ${TEMPLATEDIR}default/inheritedform.pas +newfoforms=11 + ${TEMPLATEDIR}default/mainform.mfm + ${TEMPLATEDIR}default/simpleform.mfm + ${TEMPLATEDIR}default/dockingform.mfm + ${TEMPLATEDIR}default/datamodule.mfm + ${TEMPLATEDIR}default/subform.mfm + ${TEMPLATEDIR}default/scrollboxform.mfm + ${TEMPLATEDIR}default/tabform.mfm + ${TEMPLATEDIR}default/dockpanelform.mfm + ${TEMPLATEDIR}default/report.mfm + ${TEMPLATEDIR}default/pascform.mfm + ${TEMPLATEDIR}default/inheritedform.mfm +forcezorder=0 +stripmessageesc=0 +copymessages=0 +closemessages=1 +checkmethods=1 +colorerror=-1610612712 +colorwarning=-1610612717 +colornote=-1610612716 +usercolors=0 +usercolorcomment=0 +formatmacronames=0 +formatmacrovalues=0 +settingsfile= +settingseditor=0 +settingsdebugger=0 +settingsstorage=0 +settingsprojecttree=0 +settingsautoload=0 +settingsautosave=0 +modulenames=0 +moduletypes=0 +modulefiles=0 +befcommandon=0 +makeoptionson=4 + 63 + 31 + 34 + 32 +aftcommandon=0 +unitdirson=2 + 65599 + 65599 +macroon=0 +macronames=0 +macrovalues=0 +macrogroup=0 +groupcomments=0 +toolsave=0 +toolhide=0 +toolparse=0 +toolmessages=0 +toolshortcuts=0 +fontalias=0 +fontancestors=0 +fontheights=0 +fontwidths=0 +fontoptions=0 +fontxscales=0 +expandprojectfilemacros=0 +loadprojectfile=0 +newinheritedforms=11 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 +uid=0 +sourcefilemasks=3 + "*.pas" "*.dpr" "*.lpr" "*.pp" "*.inc" + "*.c" "*.cc" "*.h" + "*.mfm" +syntaxdeffiles=3 + ${SYNTAXDEFDIR}pascal.sdef + ${SYNTAXDEFDIR}cpp.sdef + ${SYNTAXDEFDIR}objecttext.sdef +filemasknames=3 + Source + Forms + All Files +filemasks=3 + "*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + *.mfm + * +showgrid=1 +snaptogrid=1 +moveonfirstclick=1 +noformdesignerdocking=0 +gridsizex=8 +gridsizey=8 +autoindent=1 +blockindent=1 +linenumberson=0 +rightmarginon=1 +rightmarginchars=80 +scrollheight=0 +tabstops=4 +spacetabs=0 +showtabs=0 +tabindent=0 +editfontname=mseide_source +editfontheight=0 +editfontwidth=0 +editfontextraspace=0 +editfontcolor=-1879048183 +editbkcolor=-1879048186 +statementcolor=14745599 +editfontantialiased=1 +editmarkbrackets=1 +backupfilecount=2 +encoding=1 +codetemplatedirs=1 + ${TEMPLATEDIR} +debugcommand=${DEBUGGER} +debugoptions= +debugtarget= +runcommand= +xtermcommand=xterm -S${PTSN}/${PTSH} +remoteconnection= +uploadcommand= +gdbprocessor=auto +gdbservercommand= +gdbservercommandattach= +beforeconnect= +afterconnect= +beforeload= +afterload= +beforerun= +sourcebase= +sourcedirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ + ./ +defines=0 +progparameters= +progworkingdirectory= +envvarnames=0 +envvarvalues=0 +defineson=0 +stoponexception=0 +valuehints=1 +activateonbreak=1 +raiseonbreak=1 +showconsole=0 +externalconsole=0 +settty=1 +gdbdownload=0 +downloadalways=0 +startupbkpt=0 +startupbkpton=0 +gdbsimulator=0 +gdbserverstartonce=0 +gdbloadtimeout= +gdbserverwait=0 +nogdbserverexit=0 +gdbservertty=0 +exceptclassnames=1 + EconvertError +exceptignore=1 + 0 +nodebugbeginend=0 +sigsettings=27 + 1,1,T,F + 3,3,T,F + 4,4,T,F + 6,6,T,F + 7,7,T,F + 8,8,T,F + 9,9,T,F + 10,10,T,F + 11,11,T,F + 12,12,T,F + 13,13,T,F + 15,15,T,F + 16,16,T,F + 17,17,F,F + 18,18,T,F + 19,19,T,F + 20,20,T,F + 21,21,T,F + 22,22,T,F + 23,23,T,F + 24,24,T,F + 25,25,T,F + 26,26,T,F + 27,27,T,F + 28,28,T,F + 29,29,T,F + 30,30,T,F +defaultmake=1 +[breakpoints] +on=0 +path=0 +line=0 +address=0 +addbkpt=0 +ignore=0 +condition=0 +panels=6 + panel1 + panel2 + panel3 + panel4 + panel5 + panel6 +units= + ( + a=0,4132,6,Pascal Units + ) +cmodules= + ( + a=0,4132,6,C Modules + ) +files= + ( + a=0,4132,6,Text Files + ) +[componentstore] +storedir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ +filename= +[components] +[selecteditpage] +colwidth=100 +x=0 +y=0 +cx=0 +cy=0 +[progparams] +progparamhistory=0 +workdirparamhistory=0 +envvarons=0 +[edit] +hintwidth=0 +hintheight=0 +finddtext= +findhistory=0 +findoptions=1 +editpos=0 +sourcefiles=0 +relpaths=0 +ismoduletexts=0 +modules=0 +moduleoptions=0 +visiblemodules=0 +nomenumodules=0 +[sourcefo.tabwidget] +tabsize=127 +firsttab=0 +index=-1 +[layout] +windowlayout=589 + [mainfo.openform] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.projectfiledia] + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + [mainfo.openfile] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.basedock] + splitdir=2 + useroptions=146560 + [mainfo] + splitdir=0 + useroptions=33554555 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=25 + cx=323 + cy=64 + rcx=0 + rcy=0 + wsize=0 + active=1 + visible=1 + [targetconsolefo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=209 + y=385 + cx=368 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [threadsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=37 + y=270 + cx=349 + cy=276 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo] + splitdir=0 + useroptions=16507 + stackedunder=componentstorefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=100 + y=100 + cx=453 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo.add] + value=0 + [memoryfo.memon] + value=0 + [memoryfo.bitwidth] + value=0 + [memoryfo.cnt] + value=0 + [disassfo] + splitdir=0 + useroptions=16491 + stackedunder=targetconsolefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=162 + y=502 + cx=564 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [findinfilefo] + splitdir=0 + useroptions=16491 + stackedunder=disassfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=548 + y=115 + cx=369 + cy=198 + rcx=0 + rcy=0 + [projecttreefo] + splitdir=0 + useroptions=16491 + stackedunder=memoryfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=263 + y=431 + cx=286 + cy=201 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [projecttreefo.grid] + propcolwidthref=135 + width0=141 + sortdescend0=0 + width1=129 + sortdescend1=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=16 + [stackfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=295 + rcx=0 + rcy=0 + [watchpointsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=120 + y=368 + cx=483 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [watchpointsfo.grid] + propcolwidthref=352 + sortdescend0=0 + values1=0 + values1_ci=-1 + width1=33 + sortdescend1=0 + values2=0 + width2=158 + sortdescend2=0 + width4=34 + sortdescend4=0 + values5=0 + values5_ci=-1 + width5=38 + sortdescend5=0 + values6=0 + width6=184 + sortdescend6=0 + [breakpointsfo] + splitdir=0 + useroptions=16491 + stackedunder=projecttreefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=107 + y=404 + cx=636 + cy=128 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [breakpointsfo.bkptson] + value=1 + [objectinspectorfo] + splitdir=0 + useroptions=16491 + parent=mainfo.panel5.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=518 + y=0 + cx=233 + cy=517 + rcx=0 + rcy=0 + [objectinspectorfo.grid] + propcolwidthref=233 + width0=86 + sortdescend0=0 + width1=141 + sortdescend1=0 + [symbolfo] + splitdir=0 + useroptions=16507 + stackedunder=findinfilefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=142 + y=257 + cx=361 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [symbolfo.grid] + propcolwidthref=222 + values0=0 + width0=111 + sortdescend0=0 + width1=135 + sortdescend1=0 + [symbolfo.symbol] + [watchfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=298 + cx=313 + cy=236 + rcx=0 + rcy=0 + [watchfo.grid] + propcolwidthref=118 + values0=0 + values0_ci=-1 + sortdescend0=0 + values1=0 + width1=152 + sortdescend1=0 + values3=0 + values3_ci=-1 + sortdescend3=0 + values4=0 + values4_ci=-1 + width4=13 + sortdescend4=0 + [watchfo.watchon] + [watchfo.expression] + [watchfo.watcheson] + value=1 + [messagefo] + splitdir=0 + useroptions=49259 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=510 + cx=675 + cy=95 + rcx=0 + rcy=0 + [componentstorefo] + splitdir=0 + useroptions=24699 + stackedunder=symbolfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=305 + y=101 + cx=445 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentstorefo.grid] + propcolwidthref=435 + width0=111 + sortdescend0=0 + sortdescend1=0 + width2=112 + sortdescend2=0 + width3=185 + sortdescend3=0 + [componentstorefo.storefiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.groupfiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.compfiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentpalettefo] + splitdir=0 + useroptions=24683 + parent=mainfo.panel4.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=761 + cy=75 + rcx=0 + rcy=0 + [componentpalettefo.componentpages] + activetab=0 + [debuggerfo] + splitdir=0 + useroptions=24683 + parent=mainfo.basedock + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=28 + rcx=0 + rcy=0 + [sourcefo] + splitdir=0 + useroptions=16489 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=675 + cy=507 + rcx=0 + rcy=0 + [actionsmo.watchesonact] + checked=1 + [actionsmo.bluedotsonact] + checked=1 + [cpui386fo] + irqoff=0 + splitdir=0 + useroptions=16491 + stackedunder=mainfo.panel2 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=337 + y=295 + cx=273 + cy=207 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [mainfo.panel1] + splitdir=2 + useroptions=33586667 + stackedunder=mainfo.panel3 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=118 + cx=685 + cy=605 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel2] + splitdir=2 + useroptions=33586667 + stackedunder=mainfo.panel1 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=25 + cx=323 + cy=534 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel3] + splitdir=1 + useroptions=32235 + stackedunder=mainfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=249 + y=118 + cx=771 + cy=605 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel4] + splitdir=2 + useroptions=32235 + parent=mainfo.panel3.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=761 + cy=605 + rcx=0 + rcy=0 + [mainfo.panel5] + splitdir=1 + useroptions=32235 + parent=mainfo.panel4.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=78 + cx=761 + cy=517 + rcx=0 + rcy=0 + [mainfo.panel6] + splitdir=2 + useroptions=32235 + parent=mainfo.panel5.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=515 + cy=517 + rcx=0 + rcy=0 +[targetconsole] +finddtext= +findhistory=0 +findoptions=1 diff --git a/mseide-msegui/apps/ide/templates/layoutgui.prj b/mseide-msegui/apps/ide/templates/layoutgui.prj new file mode 100644 index 0000000..04df824 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/layoutgui.prj @@ -0,0 +1,906 @@ +[componentpalette] +order0=0 +order1=0 +order2=0 +order3=0 +order4=0 +order5=0 +order6=0 +order7=0 +order8=0 +order9=0 +order10=0 +order11=0 +order12=0 +order13=0 +order14=0 +order15=0 +order16=0 +order17=0 +order18=0 +order19=0 +order20=0 +[projectoptions] +mainfile= +targetfile= +messageoutputfile= +makecommand=${COMPILER} +makedir= +unitdirs=2 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ +unitpref=-Fu +incpref=-Fi +libpref=-Fl +objpref=-Fo +targpref=-o +befcommand=0 +aftcommand=0 +makeoptions=4 + -l -Mobjfpc -Sh -Fcutf8 + -gl -O- + -B + -O2 -XX -CX -Xs +codetemplatedirs=1 + ${TEMPLATEDIR} +toolmenus=0 +toolfiles=0 +toolparams=0 +fontnames=0 +scriptbeforecopy= +scriptaftercopy= +newprojectfiles=0 +newprojectfilesdest=0 +newfinames=3 + Program + Unit + Textfile +newfifilters=3 + "*.pas" "*.pp" + "*.pas" "*.pp" + +newfiexts=3 + pas + pas + +newfisources=3 + ${TEMPLATEDIR}default/program.pas + ${TEMPLATEDIR}default/unit.pas + +newfonames=11 + Mainform + Simple Form + Docking Form + Datamodule + Subform + Scrollboxform + Tabform + Dockpanel + Report + Scriptform + Inherited Form +newfonamebases=11 + form + form + form + module + form + form + form + form + report + script + form +newfosources=11 + ${TEMPLATEDIR}default/mainform.pas + ${TEMPLATEDIR}default/simpleform.pas + ${TEMPLATEDIR}default/dockingform.pas + ${TEMPLATEDIR}default/datamodule.pas + ${TEMPLATEDIR}default/subform.pas + ${TEMPLATEDIR}default/scrollboxform.pas + ${TEMPLATEDIR}default/tabform.pas + ${TEMPLATEDIR}default/dockpanelform.pas + ${TEMPLATEDIR}default/report.pas + ${TEMPLATEDIR}default/pascform.pas + ${TEMPLATEDIR}default/inheritedform.pas +newfoforms=11 + ${TEMPLATEDIR}default/mainform.mfm + ${TEMPLATEDIR}default/simpleform.mfm + ${TEMPLATEDIR}default/dockingform.mfm + ${TEMPLATEDIR}default/datamodule.mfm + ${TEMPLATEDIR}default/subform.mfm + ${TEMPLATEDIR}default/scrollboxform.mfm + ${TEMPLATEDIR}default/tabform.mfm + ${TEMPLATEDIR}default/dockpanelform.mfm + ${TEMPLATEDIR}default/report.mfm + ${TEMPLATEDIR}default/pascform.mfm + ${TEMPLATEDIR}default/inheritedform.mfm +forcezorder=0 +stripmessageesc=0 +copymessages=0 +closemessages=1 +checkmethods=1 +colorerror=-1610612712 +colorwarning=-1610612717 +colornote=-1610612716 +usercolors=0 +usercolorcomment=0 +formatmacronames=0 +formatmacrovalues=0 +settingsfile= +settingseditor=0 +settingsdebugger=0 +settingsstorage=0 +settingsprojecttree=0 +settingsautoload=0 +settingsautosave=0 +modulenames=0 +moduletypes=0 +modulefiles=0 +befcommandon=0 +makeoptionson=4 + 63 + 31 + 34 + 32 +aftcommandon=0 +unitdirson=2 + 65599 + 65599 +macroon=0 +macronames=0 +macrovalues=0 +macrogroup=0 +groupcomments=0 +toolsave=0 +toolhide=0 +toolparse=0 +toolmessages=0 +toolshortcuts=0 +fontalias=0 +fontancestors=0 +fontheights=0 +fontwidths=0 +fontoptions=0 +fontxscales=0 +expandprojectfilemacros=0 +loadprojectfile=0 +newinheritedforms=11 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 +uid=0 +sourcefilemasks=3 + "*.pas" "*.dpr" "*.lpr" "*.pp" "*.inc" + "*.c" "*.cc" "*.h" + "*.mfm" +syntaxdeffiles=3 + ${SYNTAXDEFDIR}pascal.sdef + ${SYNTAXDEFDIR}cpp.sdef + ${SYNTAXDEFDIR}objecttext.sdef +filemasknames=3 + Source + Forms + All Files +filemasks=3 + "*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + *.mfm + * +showgrid=1 +snaptogrid=1 +moveonfirstclick=1 +noformdesignerdocking=0 +gridsizex=8 +gridsizey=8 +autoindent=1 +blockindent=1 +linenumberson=0 +rightmarginon=1 +rightmarginchars=80 +scrollheight=0 +tabstops=4 +spacetabs=0 +showtabs=0 +tabindent=0 +editfontname=mseide_source +editfontheight=0 +editfontwidth=0 +editfontextraspace=0 +editfontcolor=-1879048183 +editbkcolor=-1879048186 +statementcolor=14745599 +editfontantialiased=1 +editmarkbrackets=1 +backupfilecount=2 +encoding=1 +codetemplatedirs=1 + ${TEMPLATEDIR} +debugcommand=${DEBUGGER} +debugoptions= +debugtarget= +runcommand= +xtermcommand=xterm -S${PTSN}/${PTSH} +remoteconnection= +uploadcommand= +gdbprocessor=auto +gdbservercommand= +gdbservercommandattach= +beforeconnect= +afterconnect= +beforeload= +afterload= +beforerun= +sourcebase= +sourcedirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ + ./ +defines=0 +progparameters= +progworkingdirectory= +envvarnames=0 +envvarvalues=0 +defineson=0 +stoponexception=0 +valuehints=1 +activateonbreak=1 +raiseonbreak=1 +showconsole=0 +externalconsole=0 +settty=1 +gdbdownload=0 +downloadalways=0 +startupbkpt=0 +startupbkpton=0 +gdbsimulator=0 +gdbserverstartonce=0 +gdbloadtimeout= +gdbserverwait=0 +nogdbserverexit=0 +gdbservertty=0 +exceptclassnames=1 + EconvertError +exceptignore=1 + 0 +nodebugbeginend=0 +sigsettings=27 + 1,1,T,F + 3,3,T,F + 4,4,T,F + 6,6,T,F + 7,7,T,F + 8,8,T,F + 9,9,T,F + 10,10,T,F + 11,11,T,F + 12,12,T,F + 13,13,T,F + 15,15,T,F + 16,16,T,F + 17,17,F,F + 18,18,T,F + 19,19,T,F + 20,20,T,F + 21,21,T,F + 22,22,T,F + 23,23,T,F + 24,24,T,F + 25,25,T,F + 26,26,T,F + 27,27,T,F + 28,28,T,F + 29,29,T,F + 30,30,T,F +defaultmake=1 +[breakpoints] +on=0 +path=0 +line=0 +address=0 +addbkpt=0 +ignore=0 +condition=0 +panels=2 + panel1 + panel2 +units= + ( + a=0,4132,0,Pascal Units + ) +cmodules= + ( + a=0,4132,0,C Modules + ) +files= + ( + a=0,4132,0,Text Files + ) +[componentstore] +filename= +[components] +[selecteditpage] +colwidth=100 +x=0 +y=0 +cx=0 +cy=0 +[progparams] +progparamhistory=0 +workdirparamhistory=0 +envvarons=0 +[edit] +hintwidth=0 +hintheight=0 +finddtext= +findhistory=0 +findoptions=1 +editpos=0 +sourcefiles=0 +relpaths=0 +ismoduletexts=0 +modules=0 +moduleoptions=0 +visiblemodules=0 +nomenumodules=0 +[sourcefo.tabwidget] +tabsize=127 +firsttab=0 +index=-1 +[layout] +windowlayout=544 + [mainfo.openform] + filenames=0 + filehistory=0 + filefilterindex=0 + filefilter= + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + [mainfo.projectfiledia] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/templates/layoutgui.prj + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/templates/ + filehistory=10 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/templates/layoutgui.prj + /home/mse/packs/standard/git/mseuniverse/tools/msegit/mse_msegit.prj + /home/mse/packs/standard/git/mseide-msegui/apps/ide/mse_mseide.prj + /home/mse/proj/msegui/testcase/chefou/msegui_zengl/test.prj + /home/mse/packs/standard/git/mseuniverse/samples/widgets/layout/mse_layout.prj + /home/mse/packs/standard/git/mselang/mselang/mse_mselang.prj + /home/mse/packs/standard/git/sak/sak/sak_mse/examples/mse_mse_sak_demo.prj + /home/mse/packs/standard/git/mseuniverse/tools/msespice/mse_msespice.prj + /home/mse/proj/msegui/testcase/mse/process/terminate/terminateprocess.prj + /home/mse/proj/test3/test.prj + filefilterindex=0 + filefilter=*.prj + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + [mainfo.openfile] + filenames=0 + filehistory=0 + filefilterindex=0 + filefilter= + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + [mainfo.basedock] + splitdir=2 + useroptions=146560 + [mainfo] + splitdir=0 + useroptions=33554555 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=25 + cx=323 + cy=64 + rcx=0 + rcy=0 + wsize=0 + active=1 + visible=1 + [targetconsolefo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=209 + y=385 + cx=368 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [threadsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=37 + y=270 + cx=349 + cy=276 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo] + splitdir=0 + useroptions=16507 + stackedunder=cpui386fo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=100 + y=100 + cx=453 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo.add] + value=0 + [memoryfo.memon] + value=0 + [memoryfo.bitwidth] + value=0 + [memoryfo.cnt] + value=0 + [disassfo] + splitdir=0 + useroptions=16491 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=162 + y=502 + cx=564 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [findinfilefo] + splitdir=0 + useroptions=16491 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=548 + y=115 + cx=369 + cy=198 + rcx=0 + rcy=0 + [projecttreefo] + splitdir=0 + useroptions=16491 + stackedunder=memoryfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=263 + y=431 + cx=286 + cy=201 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [projecttreefo.grid] + propcolwidthref=135 + width0=141 + sortdescend0=0 + width1=129 + sortdescend1=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=16 + [stackfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=295 + rcx=0 + rcy=0 + [watchpointsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=120 + y=368 + cx=483 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [watchpointsfo.grid] + propcolwidthref=352 + sortdescend0=0 + values1=0 + values1_ci=-1 + width1=33 + sortdescend1=0 + values2=0 + width2=158 + sortdescend2=0 + width4=34 + sortdescend4=0 + values5=0 + values5_ci=-1 + width5=38 + sortdescend5=0 + values6=0 + width6=184 + sortdescend6=0 + [breakpointsfo] + splitdir=0 + useroptions=16491 + stackedunder=projecttreefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=107 + y=404 + cx=636 + cy=128 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [breakpointsfo.bkptson] + value=1 + [objectinspectorfo] + splitdir=0 + useroptions=16491 + stackedunder=mainfo.panel2 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=724 + y=157 + cx=296 + cy=566 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [objectinspectorfo.grid] + propcolwidthref=286 + width0=105 + sortdescend0=0 + width1=175 + sortdescend1=0 + [symbolfo] + splitdir=0 + useroptions=16507 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=142 + y=257 + cx=361 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [symbolfo.grid] + propcolwidthref=222 + values0=0 + width0=111 + sortdescend0=0 + width1=135 + sortdescend1=0 + [symbolfo.symbol] + [watchfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=298 + cx=313 + cy=236 + rcx=0 + rcy=0 + [watchfo.grid] + propcolwidthref=118 + values0=0 + values0_ci=-1 + sortdescend0=0 + values1=0 + width1=152 + sortdescend1=0 + values3=0 + values3_ci=-1 + sortdescend3=0 + values4=0 + values4_ci=-1 + width4=13 + sortdescend4=0 + [watchfo.watchon] + [watchfo.expression] + [watchfo.watcheson] + value=1 + [messagefo] + splitdir=0 + useroptions=49259 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=510 + cx=675 + cy=95 + rcx=0 + rcy=0 + [componentstorefo] + splitdir=0 + useroptions=24699 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=305 + y=101 + cx=445 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentstorefo.grid] + propcolwidthref=435 + width0=111 + sortdescend0=0 + sortdescend1=0 + width2=112 + sortdescend2=0 + width3=185 + sortdescend3=0 + [componentstorefo.storefiledialog] + filenames=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + [componentstorefo.groupfiledialog] + filenames=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + [componentstorefo.compfiledialog] + filenames=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + [componentpalettefo] + splitdir=0 + useroptions=24683 + stackedunder=objectinspectorfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=25 + cx=685 + cy=103 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [componentpalettefo.componentpages] + activetab=0 + [debuggerfo] + splitdir=0 + useroptions=24683 + parent=mainfo.basedock + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=28 + rcx=0 + rcy=0 + [sourcefo] + splitdir=0 + useroptions=16489 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=675 + cy=507 + rcx=0 + rcy=0 + [actionsmo.watchesonact] + checked=1 + [actionsmo.bluedotsonact] + checked=1 + [cpui386fo] + irqoff=0 + splitdir=0 + useroptions=16491 + stackedunder=mainfo.panel1 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=337 + y=295 + cx=273 + cy=207 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [mainfo.panel1] + splitdir=2 + useroptions=33586667 + stackedunder=componentpalettefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=118 + cx=685 + cy=605 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel2] + splitdir=2 + useroptions=33586667 + stackedunder=mainfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=189 + cx=323 + cy=534 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 +[targetconsole] +finddtext= +findhistory=0 +findoptions=1 diff --git a/mseide-msegui/apps/ide/templates/library.prj b/mseide-msegui/apps/ide/templates/library.prj new file mode 100644 index 0000000..8b39bfd --- /dev/null +++ b/mseide-msegui/apps/ide/templates/library.prj @@ -0,0 +1,263 @@ +[projectoptions] +mainfile=${PROJECTNAME}.pas +targetfile= +messageoutputfile= +makecommand=${COMPILER} +makedir= +unitdirs=3 + ${MSEDIR}lib/addon/*/ + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ +unitpref=-Fu +incpref=-Fi +libpref=-Fl +objpref=-Fo +targpref=-o +befcommand=0 +aftcommand=0 +makeoptions=4 + -Xg -l -Mobjfpc -Sh -Fcutf8 + -gl -O- + -B + -O2 -XX -Xs -CX +codetemplatedirs=1 + ${TEMPLATEDIR} +toolmenus=0 +toolfiles=0 +toolparams=0 +fontnames=0 +scriptbeforecopy= +scriptaftercopy= +newprojectfiles=1 + ${TEMPLATEDIR}/library/project.pas +newprojectfilesdest=1 + ${%PROJECTNAME%}.pas +newfinames=3 + Program + Unit + Textfile +newfifilters=3 + "*.pas" "*.pp" + "*.pas" "*.pp" + +newfiexts=3 + pas + pas + +newfisources=3 + ${TEMPLATEDIR}default/program.pas + ${TEMPLATEDIR}default/unit.pas + +newfonames=12 + Mainform + Simple Form + Docking Form + Sizing Form + Datamodule + Subform + Scrollboxform + Tabform + Dockpanel + Report + Scriptform + Inherited Form +newfonamebases=12 + form + form + form + form + module + form + form + form + form + report + script + form +newfosources=12 + ${TEMPLATEDIR}default/mainform.pas + ${TEMPLATEDIR}default/simpleform.pas + ${TEMPLATEDIR}default/dockingform.pas + ${TEMPLATEDIR}default/sizingform.pas + ${TEMPLATEDIR}default/datamodule.pas + ${TEMPLATEDIR}default/subform.pas + ${TEMPLATEDIR}default/scrollboxform.pas + ${TEMPLATEDIR}default/tabform.pas + ${TEMPLATEDIR}default/dockpanelform.pas + ${TEMPLATEDIR}default/report.pas + ${TEMPLATEDIR}default/pascform.pas + ${TEMPLATEDIR}default/inheritedform.pas +newfoforms=12 + ${TEMPLATEDIR}default/mainform.mfm + ${TEMPLATEDIR}default/simpleform.mfm + ${TEMPLATEDIR}default/dockingform.mfm + ${TEMPLATEDIR}default/sizingform.mfm + ${TEMPLATEDIR}default/datamodule.mfm + ${TEMPLATEDIR}default/subform.mfm + ${TEMPLATEDIR}default/scrollboxform.mfm + ${TEMPLATEDIR}default/tabform.mfm + ${TEMPLATEDIR}default/dockpanelform.mfm + ${TEMPLATEDIR}default/report.mfm + ${TEMPLATEDIR}default/pascform.mfm + ${TEMPLATEDIR}default/inheritedform.mfm +forcezorder=0 +stripmessageesc=0 +copymessages=0 +closemessages=1 +checkmethods=1 +colorerror=-1610612712 +colorwarning=-1610612717 +colornote=-1610612716 +usercolors=30 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +usercolorcomment=30 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +formatmacronames=0 +formatmacrovalues=0 +settingsfile= +settingseditor=0 +settingsdebugger=0 +settingsstorage=0 +settingsprojecttree=0 +settingsautoload=0 +settingsautosave=0 +modulenames=0 +moduletypes=0 +modulefiles=0 +befcommandon=0 +makeoptionson=4 + 63 + 31 + 34 + 32 +aftcommandon=0 +unitdirson=3 + 196671 + 65599 + 65599 +macroon=0 +macronames=0 +macrovalues=0 +macrogroup=0 +groupcomments=6 + + + + + + +toolsave=0 +toolhide=0 +toolparse=0 +toolmessages=0 +toolshortcuts=0 +fontalias=0 +fontancestors=0 +fontheights=0 +fontwidths=0 +fontoptions=0 +fontxscales=0 +expandprojectfilemacros=1 + 1 +loadprojectfile=1 + 1 +newinheritedforms=11 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 +uid=0 +sigsettings=27 + 1,1,T,F + 3,3,T,F + 4,4,T,F + 6,6,T,F + 7,7,T,F + 8,8,T,F + 9,9,T,F + 10,10,T,F + 11,11,T,F + 12,12,T,F + 13,13,T,F + 15,15,T,F + 16,16,T,F + 17,17,F,F + 18,18,T,F + 19,19,T,F + 20,20,T,F + 21,21,T,F + 22,22,T,F + 23,23,T,F + 24,24,T,F + 25,25,T,F + 26,26,T,F + 27,27,T,F + 28,28,T,F + 29,29,F,F + 30,30,T,F +defaultmake=1 diff --git a/mseide-msegui/apps/ide/templates/library/program.pas b/mseide-msegui/apps/ide/templates/library/program.pas new file mode 100644 index 0000000..801d05e --- /dev/null +++ b/mseide-msegui/apps/ide/templates/library/program.pas @@ -0,0 +1,8 @@ +program ${%PROGRAMNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifdef mswindows}{$apptype console}{$endif} +uses + {$ifdef FPC}{$ifdef unix}cthreads,cwstring{$endif}{$endif} + sysutils; +begin +end. diff --git a/mseide-msegui/apps/ide/templates/library/project.pas b/mseide-msegui/apps/ide/templates/library/project.pas new file mode 100644 index 0000000..2d6bf00 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/library/project.pas @@ -0,0 +1,5 @@ +library ${%PROJECTNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +exports +begin +end. diff --git a/mseide-msegui/apps/ide/templates/library/unit.pas b/mseide-msegui/apps/ide/templates/library/unit.pas new file mode 100644 index 0000000..0cbfb2b --- /dev/null +++ b/mseide-msegui/apps/ide/templates/library/unit.pas @@ -0,0 +1,5 @@ +unit ${%UNITNAME%}; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +implementation +end. diff --git a/mseide-msegui/apps/ide/templates/runsshgdbserver.sh b/mseide-msegui/apps/ide/templates/runsshgdbserver.sh new file mode 100755 index 0000000..347b5ea --- /dev/null +++ b/mseide-msegui/apps/ide/templates/runsshgdbserver.sh @@ -0,0 +1,8 @@ +#!/bin/sh +# parameters: +#1 2 3 4 5 6 7 +#HOSTIP, REMOTEIP, REMOTEPORT, REMOTEUSER, TARGETENV, TARGETPATH, TARGETPARAMS, +if ! ssh -t $4@$2 gdbserver --wrapper env $5 -- $1:$3 $6 $7 ; then + echo Please press enter + read +fi \ No newline at end of file diff --git a/mseide-msegui/apps/ide/templates/zeos.prj b/mseide-msegui/apps/ide/templates/zeos.prj new file mode 100644 index 0000000..3cf9b24 --- /dev/null +++ b/mseide-msegui/apps/ide/templates/zeos.prj @@ -0,0 +1,984 @@ +[componentpalette] +order0=0 +order1=0 +order2=0 +order3=0 +order4=0 +order5=0 +order6=0 +order7=0 +order8=0 +order9=0 +order10=0 +order11=0 +order12=0 +order13=0 +order14=0 +order15=0 +order16=0 +order17=0 +order18=0 +[projectoptions] +projectdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/templates +projectfilename=/home/mse/packs/standard/git/mseide-msegui/apps/ide/templates/zeos.prj +mainfile=${PROJECTNAME}.pas +targetfile=${PROJECTNAME}${EXEEXT} +messageoutputfile= +makecommand=${COMPILER} +makedir= +unitdirs=5 + ${MSEDIR}lib/addon/*/ + ${zeosdir}src/*/ + ${zeosdir}src/ + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ +unitpref=-Fu +incpref=-Fi +libpref=-Fl +objpref=-Fo +targpref=-o +befcommand=0 +aftcommand=0 +makeoptions=4 + -l -Mdelphi -Sh + -gl -O- + -B + -OG2p3 -XX -Xs +codetemplatedirs=1 + ${TEMPLATEDIR} +toolmenus=0 +toolfiles=0 +toolparams=0 +fontnames=0 +scriptbeforecopy= +scriptaftercopy= +newprojectfiles=4 + ${TEMPLATEDIR}default/project.pas + ${TEMPLATEDIR}default/main.pas + ${TEMPLATEDIR}default/main.mfm + ${TEMPLATEDIR}default/main_mfm.pas +newprojectfilesdest=4 + ${%PROJECTNAME%}.pas + + + +newfinames=3 + Program + Unit + Textfile +newfifilters=3 + "*.pas" "*.pp" + "*.pas" "*.pp" + +newfiexts=3 + pas + pas + +newfisources=3 + ${TEMPLATEDIR}default/program.pas + ${TEMPLATEDIR}default/unit.pas + +newfonames=11 + Mainform + Simple Form + Docking Form + Datamodule + Subform + Scrollboxform + Tabform + Dockpanel + Report + Scriptform + Inherited Form +newfonamebases=11 + form + form + form + module + form + form + form + form + report + script + form +newfosources=11 + ${TEMPLATEDIR}default/mainform.pas + ${TEMPLATEDIR}default/simpleform.pas + ${TEMPLATEDIR}default/dockingform.pas + ${TEMPLATEDIR}default/datamodule.pas + ${TEMPLATEDIR}default/subform.pas + ${TEMPLATEDIR}default/scrollboxform.pas + ${TEMPLATEDIR}default/tabform.pas + ${TEMPLATEDIR}default/dockpanelform.pas + ${TEMPLATEDIR}default/report.pas + ${TEMPLATEDIR}default/pascform.pas + ${TEMPLATEDIR}default/inheritedform.pas +newfoforms=11 + ${TEMPLATEDIR}default/mainform.mfm + ${TEMPLATEDIR}default/simpleform.mfm + ${TEMPLATEDIR}default/dockingform.mfm + ${TEMPLATEDIR}default/datamodule.mfm + ${TEMPLATEDIR}default/subform.mfm + ${TEMPLATEDIR}default/scrollboxform.mfm + ${TEMPLATEDIR}default/tabform.mfm + ${TEMPLATEDIR}default/dockpanelform.mfm + ${TEMPLATEDIR}default/report.mfm + ${TEMPLATEDIR}default/pascform.mfm + ${TEMPLATEDIR}default/inheritedform.mfm +forcezorder=0 +stripmessageesc=0 +copymessages=0 +closemessages=1 +checkmethods=1 +colorerror=-1610612712 +colorwarning=-1610612717 +colornote=-1610612716 +usercolors=30 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +usercolorcomment=30 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +formatmacronames=0 +formatmacrovalues=0 +settingsfile= +settingseditor=0 +settingsdebugger=0 +settingsstorage=0 +settingsprojecttree=0 +settingsautoload=0 +settingsautosave=0 +modulenames=0 +moduletypes=0 +modulefiles=0 +befcommandon=0 +makeoptionson=4 + 63 + 31 + 34 + 32 +aftcommandon=0 +unitdirson=5 + 196671 + 983103 + 983103 + 65599 + 65599 +macroon=1 + 63 +macronames=1 + zeosdir +macrovalues=1 + /home/mse/packs/standard/svn/zeos/trunk/ +macrogroup=0 +groupcomments=6 + + + + + + +toolsave=0 +toolhide=0 +toolparse=0 +toolmessages=0 +toolshortcuts=0 +fontalias=0 +fontancestors=0 +fontheights=0 +fontwidths=0 +fontoptions=0 +fontxscales=0 +expandprojectfilemacros=4 + 1 + 1 + 1 + 0 +loadprojectfile=4 + 1 + 1 + 1 + 0 +newinheritedforms=11 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 +uid=0 +sourcefilemasks=3 + "*.pas" "*.dpr" "*.lpr" "*.pp" "*.inc" + "*.c" "*.cc" "*.h" + "*.mfm" +syntaxdeffiles=3 + ${SYNTAXDEFDIR}pascal.sdef + ${SYNTAXDEFDIR}cpp.sdef + ${SYNTAXDEFDIR}objecttext.sdef +filemasknames=3 + Source + Forms + All Files +filemasks=3 + "*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + *.mfm + * +showgrid=1 +snaptogrid=1 +moveonfirstclick=1 +noformdesignerdocking=0 +gridsizex=8 +gridsizey=8 +autoindent=1 +blockindent=1 +linenumberson=0 +rightmarginon=1 +rightmarginchars=80 +scrollheight=0 +tabstops=4 +spacetabs=0 +showtabs=0 +tabindent=0 +editfontname=mseide_source +editfontheight=0 +editfontwidth=0 +editfontextraspace=0 +editfontcolor=-1879048183 +editbkcolor=-1879048186 +statementcolor=14745599 +editfontantialiased=1 +editmarkbrackets=1 +backupfilecount=2 +encoding=1 +codetemplatedirs=1 + ${TEMPLATEDIR} +debugcommand=${DEBUGGER} +debugoptions= +debugtarget= +runcommand= +xtermcommand=xterm -S${PTSN}/${PTSH} +remoteconnection= +uploadcommand= +gdbprocessor=auto +gdbservercommand= +gdbservercommandattach= +beforeconnect= +afterconnect= +beforeload= +afterload= +beforerun= +sourcebase= +sourcedirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ + ./ +defines=0 +progparameters= +progworkingdirectory= +envvarnames=0 +envvarvalues=0 +defineson=0 +stoponexception=0 +valuehints=1 +activateonbreak=1 +raiseonbreak=1 +showconsole=0 +externalconsole=0 +settty=1 +gdbdownload=0 +downloadalways=0 +startupbkpt=0 +startupbkpton=0 +gdbsimulator=0 +gdbserverstartonce=0 +gdbloadtimeout= +gdbserverwait=0 +nogdbserverexit=0 +gdbservertty=0 +exceptclassnames=1 + EconvertError +exceptignore=1 + 0 +nodebugbeginend=0 +sigsettings=27 + 1,1,T,F + 3,3,T,F + 4,4,T,F + 6,6,T,F + 7,7,T,F + 8,8,T,F + 9,9,T,F + 10,10,T,F + 11,11,T,F + 12,12,T,F + 13,13,T,F + 15,15,T,F + 16,16,T,F + 17,17,F,F + 18,18,T,F + 19,19,T,F + 20,20,T,F + 21,21,T,F + 22,22,T,F + 23,23,T,F + 24,24,T,F + 25,25,T,F + 26,26,T,F + 27,27,T,F + 28,28,T,F + 29,29,T,F + 30,30,T,F +defaultmake=1 +[breakpoints] +on=0 +path=0 +line=0 +address=0 +addbkpt=0 +ignore=0 +condition=0 +panels=2 + panel1 + panel2 +units= + ( + a=0,4132,6,Pascal Units + ) +cmodules= + ( + a=0,4132,6,C Modules + ) +files= + ( + a=0,4132,6,Text Files + ) +[componentstore] +storedir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ +filename= +[components] +[selecteditpage] +colwidth=100 +x=0 +y=0 +cx=0 +cy=0 +[progparams] +progparamhistory=0 +workdirparamhistory=0 +envvarons=0 +[edit] +hintwidth=0 +hintheight=0 +finddtext= +findhistory=0 +findoptions=1 +editpos=0 +sourcefiles=0 +relpaths=0 +ismoduletexts=0 +modules=0 +moduleoptions=0 +visiblemodules=0 +nomenumodules=0 +[sourcefo.tabwidget] +tabsize=114 +firsttab=0 +index=-1 +[layout] +windowlayout=530 + [mainfo.openform] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.projectfiledia] + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + [mainfo.openfile] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.basedock] + splitdir=2 + useroptions=146560 + [mainfo] + splitdir=0 + useroptions=33554555 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=25 + cx=323 + cy=64 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [targetconsolefo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=209 + y=385 + cx=368 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [threadsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=37 + y=270 + cx=349 + cy=276 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo] + splitdir=0 + useroptions=16507 + stackedunder=cpui386fo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=100 + y=100 + cx=453 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo.add] + value=0 + [memoryfo.memon] + value=0 + [memoryfo.bitwidth] + value=0 + [memoryfo.cnt] + value=0 + [disassfo] + splitdir=0 + useroptions=16491 + stackedunder=mainfo.panel1 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=162 + y=502 + cx=564 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [findinfilefo] + splitdir=0 + useroptions=16491 + stackedunder=disassfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=548 + y=115 + cx=369 + cy=198 + rcx=0 + rcy=0 + [projecttreefo] + splitdir=0 + useroptions=16491 + stackedunder=memoryfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=263 + y=431 + cx=286 + cy=201 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [projecttreefo.grid] + propcolwidthref=135 + width0=141 + sortdescend0=0 + width1=129 + sortdescend1=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=16 + [stackfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=295 + rcx=0 + rcy=0 + [watchpointsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=120 + y=368 + cx=483 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [watchpointsfo.grid] + propcolwidthref=352 + sortdescend0=0 + values1=0 + values1_ci=-1 + width1=33 + sortdescend1=0 + values2=0 + width2=158 + sortdescend2=0 + width4=34 + sortdescend4=0 + values5=0 + values5_ci=-1 + width5=38 + sortdescend5=0 + values6=0 + width6=184 + sortdescend6=0 + [breakpointsfo] + splitdir=0 + useroptions=16491 + stackedunder=projecttreefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=107 + y=404 + cx=636 + cy=128 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [breakpointsfo.bkptson] + value=1 + [objectinspectorfo] + splitdir=0 + useroptions=16491 + stackedunder=mainfo.panel2 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=724 + y=157 + cx=296 + cy=566 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [objectinspectorfo.grid] + propcolwidthref=286 + width0=105 + sortdescend0=0 + width1=175 + sortdescend1=0 + [symbolfo] + splitdir=0 + useroptions=16507 + stackedunder=findinfilefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=142 + y=257 + cx=361 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [symbolfo.grid] + propcolwidthref=222 + values0=0 + width0=111 + sortdescend0=0 + width1=135 + sortdescend1=0 + [symbolfo.symbol] + [watchfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=298 + cx=313 + cy=236 + rcx=0 + rcy=0 + [watchfo.grid] + propcolwidthref=118 + values0=0 + values0_ci=-1 + sortdescend0=0 + values1=0 + width1=152 + sortdescend1=0 + values3=0 + values3_ci=-1 + sortdescend3=0 + values4=0 + values4_ci=-1 + width4=13 + sortdescend4=0 + [watchfo.watchon] + [watchfo.expression] + [watchfo.watcheson] + value=1 + [messagefo] + splitdir=0 + useroptions=49259 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=510 + cx=675 + cy=95 + rcx=0 + rcy=0 + [componentstorefo] + splitdir=0 + useroptions=24699 + stackedunder=symbolfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=305 + y=101 + cx=445 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentstorefo.grid] + propcolwidthref=435 + width0=111 + sortdescend0=0 + sortdescend1=0 + width2=112 + sortdescend2=0 + width3=185 + sortdescend3=0 + [componentstorefo.storefiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.groupfiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.compfiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentpalettefo] + splitdir=0 + useroptions=24683 + stackedunder=objectinspectorfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=25 + cx=685 + cy=103 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [componentpalettefo.componentpages] + activetab=0 + [debuggerfo] + splitdir=0 + useroptions=24683 + parent=mainfo.basedock + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=28 + rcx=0 + rcy=0 + [sourcefo] + splitdir=0 + useroptions=16489 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=675 + cy=507 + rcx=0 + rcy=0 + [actionsmo.watchesonact] + checked=1 + [actionsmo.bluedotsonact] + checked=1 + [cpui386fo] + irqoff=0 + splitdir=0 + useroptions=16491 + stackedunder=componentstorefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=337 + y=295 + cx=273 + cy=207 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [mainfo.panel1] + splitdir=2 + useroptions=33586667 + stackedunder=componentpalettefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=118 + cx=685 + cy=605 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel2] + splitdir=2 + useroptions=33586667 + stackedunder=mainfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=189 + cx=323 + cy=534 + rcx=0 + rcy=0 + wsize=0 + active=1 + visible=1 +[targetconsole] +finddtext= +findhistory=0 +findoptions=1 diff --git a/mseide-msegui/apps/ide/threadsform.mfm b/mseide-msegui/apps/ide/threadsform.mfm new file mode 100644 index 0000000..64c4e1b --- /dev/null +++ b/mseide-msegui/apps/ide/threadsform.mfm @@ -0,0 +1,189 @@ +object threadsfo: tthreadsfo + optionswidget = [ow_arrowfocus, ow_subfocus, ow_mousewheel, ow_destroywidgets, ow_hinton] + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_floatbutton, go_topbutton, go_backgroundbutton, go_nolockbutton, go_buttonhints] + visible = False + bounds_x = 37 + bounds_y = 270 + bounds_cx = 349 + bounds_cy = 276 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 339 + 276 + ) + dragdock.caption = 'Threads' + dragdock.optionsdock = [od_savepos, od_canmove, od_canfloat, od_candock, od_propsize, od_captionhint, od_childicons] + options = [fo_savepos, fo_savestate] + statfile = mainfo.projectstatfile + caption = 'Threads' + icon.transparentcolor = -2147483642 + icon.image = { + 0000000000000000180000001800000000090000000000000000000000000000 + 0000000000000000000000000000000000000000F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01FC446001F5889801EBE5E601E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EFD3D701F95E7501FC3B5801EFAFB801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01F0B0B901FC3B5801F75C7301E8CCD001 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E9E3E401F2859501FD2D4C01 + F1849401E3DDDE01E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E8CCD001 + F65C7301FB3A5701E9A9B201DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F0018ADCFF01CDE8F301EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301EAAAB301FB3A5701F55A7101E1C5C901DBDBDB01DADADA01B7D8E501 + 8ADCFF01D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001B4E9FF0198E0FE01E4EAED01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E1DBDC01EF829201F9415D01DBDBDB01D3DADD01A0E0FC01 + B4E9FF01D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001DDF5FF0192DFFF01AFE2F801FF002601E8E8E801FF002601E5E5E501 + FF002601E2E2E201FF002601DFDFDF01FF002601DBDBDB01C2E4F301C6EEFF01 + DDF5FF01D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001F8FBFD0195DFFF0194DFFF01FF002601A3E4FF01FF002601A3E4FF01 + FF002601A3E4FF01FF002601A3E4FF01FF002601A3E4FF01E1F6FF01F1FAFF01 + F8FBFD01D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001D7EAF30188D6F7018FDBFB01FF002601FFFFFF01FF002601FFFFFF01 + FF002601FFFFFF01FF002601FFFFFF01FF002601FFFFFF01F4F9FB01E7F3F801 + D7EAF301D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001B5D9E90173C7EB017BCDEF01FF002601B5D9E901FF002601B5D9E901 + FF002601B5D9E901FF002601B5D9E901FF002601B5D9E901D2E8F101C5E1EE01 + B5D9E901D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F00194C8DF015EB9DF0166BEE301FF0026016DB4D401FF0026016DB4D401 + FF0026016DB4D401FF0026016DB4D401FF0026016DB4D401AFD6E701A3D0E301 + 94C8DF01D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F00173B8D6014AABD30151B0D701FF002601248FBE01FF002601248FBE01 + FF002601248FBE01FF002601248FBE01FF002601248FBE018DC5DD0180BED901 + 73B8D601D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F00152A7CC01359CC70177B9D601FF002601E8E8E801FF002601E5E5E501 + FF002601E2E2E201FF002601DFDFDF01FF002601DBDBDB0190C0D6015EADCF01 + 52A7CC01D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F0013196C2013296C001DBE4E801EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01CED5D90149A0C701 + 3196C201D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F0011085B801A2C8D901EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA0198BECE01 + 1085B801D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001 + } + onshow = threadsfoonshow + moduleclassname = 'tdockform' + object grid: tstringgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + frame.localprops = [] + frame.localprops1 = [] + popupmenu = tpopupmenu1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 339 + bounds_cy = 276 + anchors = [] + optionsgrid = [og_colsizing, og_focuscellonenter, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + datacols.count = 3 + datacols.options = [co_readonly, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy] + datacols.optionsedit = [scoe_eatreturn, scoe_hintclippedtext] + datacols.items = < + item + options = [co_readonly, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy] + textflags = [tf_right, tf_ycentered] + textflagsactive = [tf_right, tf_ycentered] + optionsedit = [scoe_undoonesc, scoe_eatreturn, scoe_exitoncursor, scoe_autoselect, scoe_autoselectonfirstclick, scoe_hintclippedtext] + valuefalse = '0' + valuetrue = '1' + end + item + width = 56 + options = [co_readonly, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy] + textflags = [tf_xcentered, tf_ycentered] + optionsedit = [scoe_undoonesc, scoe_eatreturn, scoe_exitoncursor, scoe_autoselect, scoe_autoselectonfirstclick, scoe_hintclippedtext] + valuefalse = '0' + valuetrue = '1' + end + item + width = 201 + options = [co_readonly, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savestate, co_cancopy] + optionsedit = [scoe_undoonesc, scoe_eatreturn, scoe_exitoncursor, scoe_autoselect, scoe_autoselectonfirstclick, scoe_hintclippedtext] + valuefalse = '0' + valuetrue = '1' + end> + fixcols.count = 1 + fixcols.items = < + item + width = 24 + numstart = 1 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 15 + captions.count = 3 + captions.items = < + item + caption = 'ID' + end + item + caption = 'State' + end + item + caption = 'Location' + textflags = [tf_ycentered] + end> + end> + datarowheight = 15 + oncellevent = gridoncellevent + reffontheight = 13 + end + object tpopupmenu1: tpopupmenu + menu.submenu.count = 1 + menu.submenu.items = < + item + caption = 'Copy to Clipboard' + state = [as_localcaption, as_localonexecute] + onexecute = copytoclipboardexe + end> + left = 88 + top = 144 + end + object c: tstringcontainer + strings.data = ( + '*active*' + 'unknown' + ) + left = 72 + top = 72 + end +end diff --git a/mseide-msegui/apps/ide/threadsform.pas b/mseide-msegui/apps/ide/threadsform.pas new file mode 100644 index 0000000..1a7a870 --- /dev/null +++ b/mseide-msegui/apps/ide/threadsform.pas @@ -0,0 +1,148 @@ +{ MSEide Copyright (c) 1999-2012 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit threadsform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msegui,mseclasses,mseforms,msegrids,msegdbutils,msetypes,msestrings, + msegridsglob,msemenus,msestringcontainer; + +type + tthreadsfo = class(tdockform) + grid: tstringgrid; + tpopupmenu1: tpopupmenu; + c: tstringcontainer; + procedure threadsfoonshow(const sender: TObject); + procedure gridoncellevent(const sender: TObject; var info: celleventinfoty); + procedure copytoclipboardexe(const sender: TObject); + private + fids: integerarty; + frefreshedrow: integer; + fstopinfo: stopinfoty; + public + gdb: tgdbmi; + procedure refresh; + procedure clear; + property stopinfo: stopinfoty read fstopinfo write fstopinfo; + end; + +var + threadsfo: tthreadsfo; + +implementation +uses + threadsform_mfm,sysutils,sourceform,msefileutils,main,stackform,mseguiintf, + sourcepage,msewidgets,mseformatstr; +type + stringconsts = ( + active, //0 *active* + unknown //1 unknown + ); + +{ tthreadsfo } + +procedure tthreadsfo.clear; +begin + grid.clear; +end; + +procedure tthreadsfo.refresh; +var + int1: integer; + ar1: threadinfoarty; + wstr1: msestring; +begin + frefreshedrow:= -1; + if visible and gdb.cancommand then begin + if gdb.getthreadinfolist(ar1) = gdb_ok then begin + setlength(fids,length(ar1)); + grid.rowcount:= length(ar1); + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + fids[int1]:= id; + grid[0][int1]:= inttostrmse(threadid); + case state of + ts_active: begin + wstr1:= c[ord(active)]; + frefreshedrow:= int1; + grid.row:= int1; + end + else begin + wstr1:= c[ord(unknown)]; + end; + end; + grid[1][int1]:= wstr1; + grid[2][int1]:= msestring(stackframe); + end; + end; + end + else begin + clear; + end; + end; +end; + +procedure tthreadsfo.threadsfoonshow(const sender: TObject); +begin + refresh; +end; + +procedure tthreadsfo.gridoncellevent(const sender: TObject; + var info: celleventinfoty); +var + page1: tsourcepage; +begin + case info.eventkind of + cek_enter: begin + if (frefreshedrow <> info.cell.row) and + (gdb.threadselect(fids[info.cell.row], + fstopinfo.filename,fstopinfo.line) = gdb_ok) then begin + refresh; + stackfo.refresh; + mainfo.refreshframe; + if fstopinfo.filename <> '' then begin + fstopinfo.filedir:= ''; + sourcefo.locate(fstopinfo); + end; + end; + end; + end; + if iscellclick(info,[ccr_dblclick]) then begin + page1:= sourcefo.locate(fstopinfo); + if page1 <> nil then begin + page1.activate; + end; +// sourcefo.activate; + end; +end; + +procedure tthreadsfo.copytoclipboardexe(const sender: TObject); +var + mstr1: msestring; + int1: integer; +begin + mstr1:= ''; + for int1:= 0 to grid.rowhigh do begin + mstr1:= mstr1 + '#'+inttostrmse(int1)+' '+grid[0][int1]+' '+ + grid[1][int1]+' '+grid[2][int1]+lineend; + end; + msewidgets.copytoclipboard(mstr1); +end; + +end. diff --git a/mseide-msegui/apps/ide/threadsform_mfm.pas b/mseide-msegui/apps/ide/threadsform_mfm.pas new file mode 100644 index 0000000..039a10c --- /dev/null +++ b/mseide-msegui/apps/ide/threadsform_mfm.pas @@ -0,0 +1,278 @@ +unit threadsform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,threadsform; + +const + objdata: record size: integer; data: array[0..5204] of byte end = + (size: 5205; data: ( + 84,80,70,48,10,116,116,104,114,101,97,100,115,102,111,9,116,104,114,101, + 97,100,115,102,111,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,11,111,119,95,115,117, + 98,102,111,99,117,115,13,111,119,95,109,111,117,115,101,119,104,101,101,108, + 17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,9,111, + 119,95,104,105,110,116,111,110,0,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,15,102,114,97,109,101,46,103,114,105,112,95, + 115,105,122,101,2,10,18,102,114,97,109,101,46,103,114,105,112,95,111,112, + 116,105,111,110,115,11,14,103,111,95,99,108,111,115,101,98,117,116,116,111, + 110,16,103,111,95,102,105,120,115,105,122,101,98,117,116,116,111,110,14,103, + 111,95,102,108,111,97,116,98,117,116,116,111,110,12,103,111,95,116,111,112, + 98,117,116,116,111,110,19,103,111,95,98,97,99,107,103,114,111,117,110,100, + 98,117,116,116,111,110,15,103,111,95,110,111,108,111,99,107,98,117,116,116, + 111,110,14,103,111,95,98,117,116,116,111,110,104,105,110,116,115,0,7,118, + 105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,37,8,98, + 111,117,110,100,115,95,121,3,14,1,9,98,111,117,110,100,115,95,99,120, + 3,93,1,9,98,111,117,110,100,115,95,99,121,3,20,1,26,99,111,110, + 116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,0,27,99,111,110,116,97,105,110,101,114,46,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,99,111,110,116, + 97,105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0,3,83,1, + 3,20,1,0,16,100,114,97,103,100,111,99,107,46,99,97,112,116,105,111, + 110,6,7,84,104,114,101,97,100,115,20,100,114,97,103,100,111,99,107,46, + 111,112,116,105,111,110,115,100,111,99,107,11,10,111,100,95,115,97,118,101, + 112,111,115,10,111,100,95,99,97,110,109,111,118,101,11,111,100,95,99,97, + 110,102,108,111,97,116,10,111,100,95,99,97,110,100,111,99,107,11,111,100, + 95,112,114,111,112,115,105,122,101,14,111,100,95,99,97,112,116,105,111,110, + 104,105,110,116,13,111,100,95,99,104,105,108,100,105,99,111,110,115,0,7, + 111,112,116,105,111,110,115,11,10,102,111,95,115,97,118,101,112,111,115,12, + 102,111,95,115,97,118,101,115,116,97,116,101,0,8,115,116,97,116,102,105, + 108,101,7,22,109,97,105,110,102,111,46,112,114,111,106,101,99,116,115,116, + 97,116,102,105,108,101,7,99,97,112,116,105,111,110,6,7,84,104,114,101, + 97,100,115,21,105,99,111,110,46,116,114,97,110,115,112,97,114,101,110,116, + 99,111,108,111,114,4,6,0,0,128,10,105,99,111,110,46,105,109,97,103, + 101,10,52,9,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0, + 0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,245,245, + 245,1,243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1,237,237, + 237,1,235,235,235,1,234,234,234,1,232,232,232,1,230,230,230,1,229,229, + 229,1,227,227,227,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221, + 221,1,219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213, + 213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243, + 243,1,242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1,235,235, + 235,1,234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1,227,227, + 227,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219, + 219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211, + 211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242, + 242,1,240,240,240,1,238,238,238,1,237,237,237,1,235,235,235,1,234,234, + 234,1,232,232,232,1,230,230,230,1,229,229,229,1,227,227,227,1,226,226, + 226,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219,219,1,218,218, + 218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1,210,210, + 210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240, + 240,1,238,238,238,1,237,237,237,1,235,235,235,1,234,234,234,1,232,232, + 232,1,230,230,230,1,229,229,229,1,227,227,227,1,226,226,226,1,224,224, + 224,1,223,223,223,1,221,221,221,1,219,219,219,1,218,218,218,1,216,216, + 216,1,215,215,215,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208, + 208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1,238,238, + 238,1,252,68,96,1,245,136,152,1,235,229,230,1,232,232,232,1,230,230, + 230,1,229,229,229,1,227,227,227,1,226,226,226,1,224,224,224,1,223,223, + 223,1,221,221,221,1,219,219,219,1,218,218,218,1,216,216,216,1,215,215, + 215,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245, + 245,1,243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1,239,211, + 215,1,249,94,117,1,252,59,88,1,239,175,184,1,230,230,230,1,229,229, + 229,1,227,227,227,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221, + 221,1,219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213, + 213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243, + 243,1,242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1,235,235, + 235,1,240,176,185,1,252,59,88,1,247,92,115,1,232,204,208,1,227,227, + 227,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219, + 219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211, + 211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242, + 242,1,240,240,240,1,238,238,238,1,237,237,237,1,235,235,235,1,234,234, + 234,1,233,227,228,1,242,133,149,1,253,45,76,1,241,132,148,1,227,221, + 222,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219,219,1,218,218, + 218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1,210,210, + 210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240, + 240,1,238,238,238,1,237,237,237,1,235,235,235,1,234,234,234,1,232,232, + 232,1,230,230,230,1,232,204,208,1,246,92,115,1,251,58,87,1,233,169, + 178,1,223,223,223,1,221,221,221,1,219,219,219,1,218,218,218,1,216,216, + 216,1,215,215,215,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208, + 208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1,138,220, + 255,1,205,232,243,1,235,235,235,1,234,234,234,1,232,232,232,1,230,230, + 230,1,229,229,229,1,227,227,227,1,234,170,179,1,251,58,87,1,245,90, + 113,1,225,197,201,1,219,219,219,1,218,218,218,1,183,216,229,1,138,220, + 255,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245, + 245,1,243,243,243,1,242,242,242,1,240,240,240,1,180,233,255,1,152,224, + 254,1,228,234,237,1,234,234,234,1,232,232,232,1,230,230,230,1,229,229, + 229,1,227,227,227,1,226,226,226,1,225,219,220,1,239,130,146,1,249,65, + 93,1,219,219,219,1,211,218,221,1,160,224,252,1,180,233,255,1,213,213, + 213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243, + 243,1,242,242,242,1,240,240,240,1,221,245,255,1,146,223,255,1,175,226, + 248,1,255,0,38,1,232,232,232,1,255,0,38,1,229,229,229,1,255,0, + 38,1,226,226,226,1,255,0,38,1,223,223,223,1,255,0,38,1,219,219, + 219,1,194,228,243,1,198,238,255,1,221,245,255,1,213,213,213,1,211,211, + 211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242, + 242,1,240,240,240,1,248,251,253,1,149,223,255,1,148,223,255,1,255,0, + 38,1,163,228,255,1,255,0,38,1,163,228,255,1,255,0,38,1,163,228, + 255,1,255,0,38,1,163,228,255,1,255,0,38,1,163,228,255,1,225,246, + 255,1,241,250,255,1,248,251,253,1,213,213,213,1,211,211,211,1,210,210, + 210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240, + 240,1,215,234,243,1,136,214,247,1,143,219,251,1,255,0,38,1,255,255, + 255,1,255,0,38,1,255,255,255,1,255,0,38,1,255,255,255,1,255,0, + 38,1,255,255,255,1,255,0,38,1,255,255,255,1,244,249,251,1,231,243, + 248,1,215,234,243,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208, + 208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1,181,217, + 233,1,115,199,235,1,123,205,239,1,255,0,38,1,181,217,233,1,255,0, + 38,1,181,217,233,1,255,0,38,1,181,217,233,1,255,0,38,1,181,217, + 233,1,255,0,38,1,181,217,233,1,210,232,241,1,197,225,238,1,181,217, + 233,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245, + 245,1,243,243,243,1,242,242,242,1,240,240,240,1,148,200,223,1,94,185, + 223,1,102,190,227,1,255,0,38,1,109,180,212,1,255,0,38,1,109,180, + 212,1,255,0,38,1,109,180,212,1,255,0,38,1,109,180,212,1,255,0, + 38,1,109,180,212,1,175,214,231,1,163,208,227,1,148,200,223,1,213,213, + 213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243, + 243,1,242,242,242,1,240,240,240,1,115,184,214,1,74,171,211,1,81,176, + 215,1,255,0,38,1,36,143,190,1,255,0,38,1,36,143,190,1,255,0, + 38,1,36,143,190,1,255,0,38,1,36,143,190,1,255,0,38,1,36,143, + 190,1,141,197,221,1,128,190,217,1,115,184,214,1,213,213,213,1,211,211, + 211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242, + 242,1,240,240,240,1,82,167,204,1,53,156,199,1,119,185,214,1,255,0, + 38,1,232,232,232,1,255,0,38,1,229,229,229,1,255,0,38,1,226,226, + 226,1,255,0,38,1,223,223,223,1,255,0,38,1,219,219,219,1,144,192, + 214,1,94,173,207,1,82,167,204,1,213,213,213,1,211,211,211,1,210,210, + 210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240, + 240,1,49,150,194,1,50,150,192,1,219,228,232,1,234,234,234,1,232,232, + 232,1,230,230,230,1,229,229,229,1,227,227,227,1,226,226,226,1,224,224, + 224,1,223,223,223,1,221,221,221,1,219,219,219,1,206,213,217,1,73,160, + 199,1,49,150,194,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208, + 208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1,16,133, + 184,1,162,200,217,1,235,235,235,1,234,234,234,1,232,232,232,1,230,230, + 230,1,229,229,229,1,227,227,227,1,226,226,226,1,224,224,224,1,223,223, + 223,1,221,221,221,1,219,219,219,1,218,218,218,1,152,190,206,1,16,133, + 184,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245, + 245,1,243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1,237,237, + 237,1,235,235,235,1,234,234,234,1,232,232,232,1,230,230,230,1,229,229, + 229,1,227,227,227,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221, + 221,1,219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213, + 213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243, + 243,1,242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1,235,235, + 235,1,234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1,227,227, + 227,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219, + 219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211, + 211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242, + 242,1,240,240,240,1,238,238,238,1,237,237,237,1,235,235,235,1,234,234, + 234,1,232,232,232,1,230,230,230,1,229,229,229,1,227,227,227,1,226,226, + 226,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219,219,1,218,218, + 218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1,210,210, + 210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240, + 240,1,238,238,238,1,237,237,237,1,235,235,235,1,234,234,234,1,232,232, + 232,1,230,230,230,1,229,229,229,1,227,227,227,1,226,226,226,1,224,224, + 224,1,223,223,223,1,221,221,221,1,219,219,219,1,218,218,218,1,216,216, + 216,1,215,215,215,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208, + 208,1,6,111,110,115,104,111,119,7,15,116,104,114,101,97,100,115,102,111, + 111,110,115,104,111,119,15,109,111,100,117,108,101,99,108,97,115,115,110,97, + 109,101,6,9,116,100,111,99,107,102,111,114,109,0,11,116,115,116,114,105, + 110,103,103,114,105,100,4,103,114,105,100,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115, + 105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17, + 111,119,95,102,111,99,117,115,98,97,99,107,111,110,101,115,99,13,111,119, + 95,109,111,117,115,101,119,104,101,101,108,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,9,112,111,112,117,112,109,101,110,117,7, + 11,116,112,111,112,117,112,109,101,110,117,49,8,98,111,117,110,100,115,95, + 120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100, + 115,95,99,120,3,83,1,9,98,111,117,110,100,115,95,99,121,3,20,1, + 7,97,110,99,104,111,114,115,11,0,11,111,112,116,105,111,110,115,103,114, + 105,100,11,12,111,103,95,99,111,108,115,105,122,105,110,103,19,111,103,95, + 102,111,99,117,115,99,101,108,108,111,110,101,110,116,101,114,20,111,103,95, + 99,111,108,99,104,97,110,103,101,111,110,116,97,98,107,101,121,10,111,103, + 95,119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112,117, + 112,17,111,103,95,109,111,117,115,101,115,99,114,111,108,108,99,111,108,0, + 14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,3,16,100,97, + 116,97,99,111,108,115,46,111,112,116,105,111,110,115,11,11,99,111,95,114, + 101,97,100,111,110,108,121,14,99,111,95,102,111,99,117,115,115,101,108,101, + 99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111, + 95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115, + 101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99, + 111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111, + 112,121,0,20,100,97,116,97,99,111,108,115,46,111,112,116,105,111,110,115, + 101,100,105,116,11,14,115,99,111,101,95,101,97,116,114,101,116,117,114,110, + 20,115,99,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120, + 116,0,14,100,97,116,97,99,111,108,115,46,105,116,101,109,115,14,1,7, + 111,112,116,105,111,110,115,11,11,99,111,95,114,101,97,100,111,110,108,121, + 14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109, + 111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108, + 101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99, + 111,95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,115, + 116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,0,9,116,101,120, + 116,102,108,97,103,115,11,8,116,102,95,114,105,103,104,116,12,116,102,95, + 121,99,101,110,116,101,114,101,100,0,15,116,101,120,116,102,108,97,103,115, + 97,99,116,105,118,101,11,8,116,102,95,114,105,103,104,116,12,116,102,95, + 121,99,101,110,116,101,114,101,100,0,11,111,112,116,105,111,110,115,101,100, + 105,116,11,14,115,99,111,101,95,117,110,100,111,111,110,101,115,99,14,115, + 99,111,101,95,101,97,116,114,101,116,117,114,110,17,115,99,111,101,95,101, + 120,105,116,111,110,99,117,114,115,111,114,15,115,99,111,101,95,97,117,116, + 111,115,101,108,101,99,116,27,115,99,111,101,95,97,117,116,111,115,101,108, + 101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,20,115,99,111,101, + 95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116,0,10,118,97, + 108,117,101,102,97,108,115,101,6,1,48,9,118,97,108,117,101,116,114,117, + 101,6,1,49,0,1,5,119,105,100,116,104,2,56,7,111,112,116,105,111, + 110,115,11,11,99,111,95,114,101,97,100,111,110,108,121,14,99,111,95,102, + 111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115, + 101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99, + 111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119, + 115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116,97,116,101,10, + 99,111,95,99,97,110,99,111,112,121,0,9,116,101,120,116,102,108,97,103, + 115,11,12,116,102,95,120,99,101,110,116,101,114,101,100,12,116,102,95,121, + 99,101,110,116,101,114,101,100,0,11,111,112,116,105,111,110,115,101,100,105, + 116,11,14,115,99,111,101,95,117,110,100,111,111,110,101,115,99,14,115,99, + 111,101,95,101,97,116,114,101,116,117,114,110,17,115,99,111,101,95,101,120, + 105,116,111,110,99,117,114,115,111,114,15,115,99,111,101,95,97,117,116,111, + 115,101,108,101,99,116,27,115,99,111,101,95,97,117,116,111,115,101,108,101, + 99,116,111,110,102,105,114,115,116,99,108,105,99,107,20,115,99,111,101,95, + 104,105,110,116,99,108,105,112,112,101,100,116,101,120,116,0,10,118,97,108, + 117,101,102,97,108,115,101,6,1,48,9,118,97,108,117,101,116,114,117,101, + 6,1,49,0,1,5,119,105,100,116,104,3,201,0,7,111,112,116,105,111, + 110,115,11,11,99,111,95,114,101,97,100,111,110,108,121,14,99,111,95,102, + 111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115, + 101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99, + 111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119, + 115,101,108,101,99,116,7,99,111,95,102,105,108,108,12,99,111,95,115,97, + 118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,0,11, + 111,112,116,105,111,110,115,101,100,105,116,11,14,115,99,111,101,95,117,110, + 100,111,111,110,101,115,99,14,115,99,111,101,95,101,97,116,114,101,116,117, + 114,110,17,115,99,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114, + 15,115,99,111,101,95,97,117,116,111,115,101,108,101,99,116,27,115,99,111, + 101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99, + 108,105,99,107,20,115,99,111,101,95,104,105,110,116,99,108,105,112,112,101, + 100,116,101,120,116,0,10,118,97,108,117,101,102,97,108,115,101,6,1,48, + 9,118,97,108,117,101,116,114,117,101,6,1,49,0,0,13,102,105,120,99, + 111,108,115,46,99,111,117,110,116,2,1,13,102,105,120,99,111,108,115,46, + 105,116,101,109,115,14,1,5,119,105,100,116,104,2,24,8,110,117,109,115, + 116,97,114,116,2,1,7,110,117,109,115,116,101,112,2,1,0,0,13,102, + 105,120,114,111,119,115,46,99,111,117,110,116,2,1,13,102,105,120,114,111, + 119,115,46,105,116,101,109,115,14,1,6,104,101,105,103,104,116,2,15,14, + 99,97,112,116,105,111,110,115,46,99,111,117,110,116,2,3,14,99,97,112, + 116,105,111,110,115,46,105,116,101,109,115,14,1,7,99,97,112,116,105,111, + 110,6,2,73,68,0,1,7,99,97,112,116,105,111,110,6,5,83,116,97, + 116,101,0,1,7,99,97,112,116,105,111,110,6,8,76,111,99,97,116,105, + 111,110,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101, + 110,116,101,114,101,100,0,0,0,0,0,13,100,97,116,97,114,111,119,104, + 101,105,103,104,116,2,15,11,111,110,99,101,108,108,101,118,101,110,116,7, + 15,103,114,105,100,111,110,99,101,108,108,101,118,101,110,116,13,114,101,102, + 102,111,110,116,104,101,105,103,104,116,2,13,0,0,10,116,112,111,112,117, + 112,109,101,110,117,11,116,112,111,112,117,112,109,101,110,117,49,18,109,101, + 110,117,46,115,117,98,109,101,110,117,46,99,111,117,110,116,2,1,18,109, + 101,110,117,46,115,117,98,109,101,110,117,46,105,116,101,109,115,14,1,7, + 99,97,112,116,105,111,110,6,17,67,111,112,121,32,116,111,32,67,108,105, + 112,98,111,97,114,100,5,115,116,97,116,101,11,15,97,115,95,108,111,99, + 97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110, + 101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7,18, + 99,111,112,121,116,111,99,108,105,112,98,111,97,114,100,101,120,101,0,0, + 4,108,101,102,116,2,88,3,116,111,112,3,144,0,0,0,16,116,115,116, + 114,105,110,103,99,111,110,116,97,105,110,101,114,1,99,12,115,116,114,105, + 110,103,115,46,100,97,116,97,1,6,8,42,97,99,116,105,118,101,42,6, + 7,117,110,107,110,111,119,110,0,4,108,101,102,116,2,72,3,116,111,112, + 2,72,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tthreadsfo,''); +end. diff --git a/mseide-msegui/apps/ide/toolhandlermodule.mfm b/mseide-msegui/apps/ide/toolhandlermodule.mfm new file mode 100644 index 0000000..b7b32c1 --- /dev/null +++ b/mseide-msegui/apps/ide/toolhandlermodule.mfm @@ -0,0 +1,14 @@ +object toolhandlermo: ttoolhandlermo + bounds_cx = 100 + bounds_cy = 100 + left = 100 + top = 100 + moduleclassname = 'tmsedatamodule' + object proc: tmseprocess + options = [pro_output, pro_erroroutput] + output.oninputavailable = inputavailexe + onprocfinished = procfinishedexe + left = 8 + top = 8 + end +end diff --git a/mseide-msegui/apps/ide/toolhandlermodule.pas b/mseide-msegui/apps/ide/toolhandlermodule.pas new file mode 100644 index 0000000..74db181 --- /dev/null +++ b/mseide-msegui/apps/ide/toolhandlermodule.pas @@ -0,0 +1,66 @@ +{ MSEide Copyright (c) 1999-2013 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit toolhandlermodule; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,mseglob,mseapplication,mseclasses,msedatamodules,msepipestream, + mseprocess,mseprocutils,msetypes,msestrings; + +type + ttoolhandlermo = class(tmsedatamodule) + proc: tmseprocess; + procedure inputavailexe(const sender: tpipereader); + procedure procfinishedexe(const sender: TObject); + public + constructor create(const aowner: tcomponent; const acommandline: msestring; + const aoptions: execoptionsty); reintroduce; + end; + +implementation +uses + toolhandlermodule_mfm,make,messageform; + +procedure ttoolhandlermo.inputavailexe(const sender: tpipereader); +begin + addmessagetext(sender,nil); +end; + +procedure ttoolhandlermo.procfinishedexe(const sender: TObject); +begin + release; +end; + +constructor ttoolhandlermo.create(const aowner: tcomponent; + const acommandline: msestring; const aoptions: execoptionsty); +var + opt1: processoptionsty; +begin + inherited create(aowner); + name:= ''; + proc.commandline:= acommandline; + opt1:= [pro_tty,pro_output,pro_errorouttoout]; + if exo_inactive in aoptions then begin + include(opt1,pro_inactive); + end; + proc.options:= opt1; + messagefo.messages.clear; + proc.active:= true; + messagefo.activate; +end; + +end. diff --git a/mseide-msegui/apps/ide/toolhandlermodule_mfm.pas b/mseide-msegui/apps/ide/toolhandlermodule_mfm.pas new file mode 100644 index 0000000..80d6758 --- /dev/null +++ b/mseide-msegui/apps/ide/toolhandlermodule_mfm.pas @@ -0,0 +1,30 @@ +unit toolhandlermodule_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,toolhandlermodule; + +const + objdata: record size: integer; data: array[0..243] of byte end = + (size: 244; data: ( + 84,80,70,48,14,116,116,111,111,108,104,97,110,100,108,101,114,109,111,13, + 116,111,111,108,104,97,110,100,108,101,114,109,111,9,98,111,117,110,100,115, + 95,99,120,2,100,9,98,111,117,110,100,115,95,99,121,2,100,4,108,101, + 102,116,2,100,3,116,111,112,2,100,15,109,111,100,117,108,101,99,108,97, + 115,115,110,97,109,101,6,14,116,109,115,101,100,97,116,97,109,111,100,117, + 108,101,0,11,116,109,115,101,112,114,111,99,101,115,115,4,112,114,111,99, + 7,111,112,116,105,111,110,115,11,10,112,114,111,95,111,117,116,112,117,116, + 15,112,114,111,95,101,114,114,111,114,111,117,116,112,117,116,0,23,111,117, + 116,112,117,116,46,111,110,105,110,112,117,116,97,118,97,105,108,97,98,108, + 101,7,13,105,110,112,117,116,97,118,97,105,108,101,120,101,14,111,110,112, + 114,111,99,102,105,110,105,115,104,101,100,7,15,112,114,111,99,102,105,110, + 105,115,104,101,100,101,120,101,4,108,101,102,116,2,8,3,116,111,112,2, + 8,0,0,0) + ); + +initialization + registerobjectdata(@objdata,ttoolhandlermo,''); +end. diff --git a/mseide-msegui/apps/ide/watchform.mfm b/mseide-msegui/apps/ide/watchform.mfm new file mode 100644 index 0000000..07525f7 --- /dev/null +++ b/mseide-msegui/apps/ide/watchform.mfm @@ -0,0 +1,434 @@ +object watchfo: twatchfo + optionswidget = [ow_tabfocus, ow_arrowfocus, ow_subfocus, ow_destroywidgets] + frame.localprops = [frl_optionsskin] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_floatbutton, go_topbutton, go_backgroundbutton, go_nolockbutton, go_buttonhints] + visible = False + bounds_x = 291 + bounds_y = 247 + bounds_cx = 310 + bounds_cy = 245 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.color = -2147483645 + container.frame.localprops = [frl_optionsskin] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 300 + 245 + ) + dragdock.splitter_size = 0 + dragdock.caption = 'Watches' + dragdock.optionsdock = [od_savepos, od_canmove, od_canfloat, od_candock, od_proportional, od_propsize, od_captionhint, od_childicons] + options = [fo_savepos, fo_savestate] + statfile = mainfo.projectstatfile + caption = 'Watches' + icon.transparentcolor = -2147483642 + icon.options = [bmo_masked] + icon.image = { + 00000000020000001800000018000000CC020000000000000000000000000000 + 0000000000000000000000000000000000000000D0D0D0607C7C7C19D9D9D916 + FFFFFF017C7C7C01D9D9D903C8C8C801A1A1A101D9D9D905A6A6A601C2C2C201 + D9D9D904D2D2D2019A9A9A01D9D9D904FFFFFF017C7C7C01D9D9D9024E4E4E01 + 0D0D0D011818180296969601D9D9D901B8B8B8011E1E1E01161616010E0E0E01 + 36363601D9D9D9026A6A6A010F0F0F011C1C1C011111110177777701D9D9D902 + FFFFFF017C7C7C01D9D9D901B6B6B60108080801BFBFBF01D9D9D90152525201 + 30303001D9D9D9014F4F4F0139393901D9D9D901CCCCCC01121212018A8A8A01 + D2D2D2010E0E0E0197979701D9D9D9017979790117171701D9D9D902FFFFFF01 + 7C7C7C01D9D9D9019C9C9C0169696901D9D9D9029F9F9F010E0E0E01D9D9D901 + 63636301A1A1A101D9D9D9023C3C3C0151515101B5B5B50156565601D9D9D902 + D2D2D20102020201C2C2C201D9D9D901FFFFFF017C7C7C01D9D9D90533333301 + 3C3C3C01D9D9D904ABABAB010B0B0B0196969601D9D9D904535353011F1F1F01 + D9D9D902FFFFFF017C7C7C01D9D9D9044E4E4E011A1A1A01CCCCCC01D9D9D903 + C2C2C201131313015E5E5E01D9D9D904717171010E0E0E01B4B4B401D9D9D902 + FFFFFF017C7C7C01D9D9D903B9B9B90109090901B9B9B901D9D9D9044F4F4F01 + 38383801D9D9D9050D0D0D0195959501D9D9D903FFFFFF017C7C7C01D9D9D903 + 8B8B8B0127272701D9D9D9053535350175757501D9D9D904BCBCBC0110101001 + D9D9D904FFFFFF017C7C7C01D9D9D903D2D2D201C5C5C501D9D9D905C7C7C701 + CFCFCF01D9D9D904D5D5D501C2C2C201D9D9D904FFFFFF017C7C7C01D9D9D903 + 6F6F6F0114141401D9D9D9051F1F1F015D5D5D01D9D9D9049C9C9C0100000001 + D5D5D501D9D9D903FFFFFF017C7C7C01D9D9D903B9B9B90192929201D9D9D905 + 99999901B2B2B201D9D9D904C8C8C80186868601D9D9D904FFFFFF017C7C7C01 + D9D9D916FFFFFF017C7C7C01D9D9D916FFFFFF017C7C7C01FFFFFF17D0D0D060 + 00000000000000000000000000000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00 + FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00 + FFFFFF00FFFFFF00FFFFFF00FFFFFF0000000000000000000000000000000000 + } + moduleclassname = 'tdockform' + object grid: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets, ow_hinton] + frame.localprops = [frl_optionsskin] + frame.localprops1 = [] + taborder = 1 + popupmenu = gripopup + bounds_x = 0 + bounds_y = 24 + bounds_cx = 300 + bounds_cy = 221 + anchors = [an_top, an_bottom] + optionsgrid = [og_colsizing, og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_wrapcol, og_autopopup] + fixcols.count = 1 + fixcols.items = < + item + width = 20 + numstart = 1 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 6 + captions.items = < + item + caption = 'A' + hint = 'Active' + end + item + caption = 'Expression' + hint = 'Expressions starting with # are treated as gdb commands' + end + item + caption = 'Result' + end + item + caption = 'F' + hint = 'Display format'#10'B = Binary'#10'D = Decimal signed'#10'U = Decimal unsigned'#10'H = Hex' + end + item + end + item + end> + end> + rowfonts.count = 1 + rowfonts.items = < + item + color = -1610612729 + name = 'stf_default' + xscale = 1 + localprops = [flp_color, flp_xscale] + end> + datacols.count = 5 + datacols.items = < + item[watchon] + width = 13 + options = [co_drawfocus, co_fixwidth, co_savevalue, co_savestate] + widgetname = 'watchon' + dataclass = tgridintegerdatalist + end + item[expression] + width = 152 + options = [co_savevalue, co_savestate] + options1 = [co1_rowcolor, co1_zebracolor] + widgetname = 'expression' + dataclass = tgridmsestringdatalist + end + item[expresult] + width = 80 + options = [co_fill] + widthmin = 50 + oncellevent = resultcellevent + widgetname = 'expresult' + dataclass = tgridmsestringdatalist + end + item[formatcode] + color = -2147483646 + coloractive = -1879048185 + width = 12 + options = [co_fixwidth, co_savevalue, co_savestate, co_mousescrollrow] + widgetname = 'formatcode' + dataclass = tgridintegerdatalist + end + item[sizecode] + width = 13 + options = [co_invisible, co_savevalue, co_savestate, co_mousescrollrow] + widgetname = 'sizecode' + dataclass = tgridintegerdatalist + end> + datarowheight = 16 + statfile = mainfo.projectstatfile + reffontheight = 14 + object watchon: tbooleanedit + optionsskin = [osk_framebuttononly] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cy = 16 + statfile = mainfo.projectstatfile + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savevalue, oe1_savestate] + ondataentered = expressionondataentered + visible = False + value = True + valuedefault = True + end + object expression: tstringedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 2 + visible = False + bounds_x = 14 + bounds_y = 0 + bounds_cx = 152 + bounds_cy = 16 + statfile = mainfo.projectstatfile + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_forcereturncheckvalue, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext] + ondataentered = expressionondataentered + reffontheight = 14 + end + object expresult: tstringedit + optionswidget1 = [ow1_autoscale] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 3 + visible = False + bounds_x = 167 + bounds_y = 0 + bounds_cx = 80 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext] + textflags = [tf_ycentered, tf_noselect, tf_ellipseright] + onsetvalue = expresultonsetvalue + end + object formatcode: tdatabutton + taborder = 4 + bounds_x = 248 + bounds_y = 0 + bounds_cx = 12 + bounds_cy = 16 + ondataentered = formatent + state = [as_invisible, as_localimagelist] + imagelist = timagelist1 + focusrectdist = 0 + imagenums.count = 5 + imagenums.items = ( + -1 + 0 + 1 + 2 + 3 + ) + value = 0 + valuedefault = 0 + min = 0 + max = 4 + end + object sizecode: tintegeredit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + taborder = 5 + visible = False + bounds_x = 261 + bounds_y = 0 + bounds_cx = 13 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + reffontheight = 14 + end + end + object watcheson: tbooleanedit + frame.caption = 'Watches &on' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 77 + 2 + ) + bounds_x = 8 + bounds_y = 4 + bounds_cx = 90 + bounds_cy = 16 + statfile = mainfo.projectstatfile + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + onchange = watchesononchange + onsetvalue = watchesononsetvalue + value = True + end + object gripopup: tpopupmenu + onupdate = popupdate + menu.submenu.count = 21 + menu.submenu.items = < + item + caption = 'Delete all' + state = [as_localcaption, as_localonexecute] + onexecute = deletallexecute + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = 'Add Watchpoint' + state = [as_localcaption, as_localonexecute] + onexecute = addwatchpoint + end + item + caption = 'Address Watchpoint 8' + state = [as_localcaption, as_localonexecute] + onexecute = addresswatch + end + item + caption = 'Address Watchpoint 16' + state = [as_localcaption, as_localtag, as_localonexecute] + tag = 1 + onexecute = addresswatch + end + item + caption = 'Address Watchpoint 32' + state = [as_localcaption, as_localtag, as_localonexecute] + tag = 2 + onexecute = addresswatch + end + item + caption = 'Address Watchpoint 64' + state = [as_localcaption, as_localtag, as_localonexecute] + tag = 3 + onexecute = addresswatch + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = '&Format default' + name = 'format' + state = [as_localchecked, as_localcaption, as_localonexecute] + options = [mao_radiobutton, mao_shortcutcaption] + onexecute = formatexecute + end + item + caption = '&Binary' + state = [as_localcaption, as_localtag, as_localonexecute] + options = [mao_radiobutton, mao_shortcutcaption] + tag = 1 + onexecute = formatexecute + end + item + caption = 'D&ecimal signed' + state = [as_localcaption, as_localtag, as_localonexecute] + options = [mao_radiobutton, mao_shortcutcaption] + tag = 2 + onexecute = formatexecute + end + item + caption = 'Decimal &unsigned' + state = [as_localcaption, as_localtag, as_localonexecute] + options = [mao_radiobutton, mao_shortcutcaption] + tag = 3 + onexecute = formatexecute + end + item + caption = '&Hex' + state = [as_localcaption, as_localtag, as_localonexecute] + options = [mao_radiobutton, mao_shortcutcaption] + tag = 4 + onexecute = formatexecute + end + item + state = [as_localcaption, as_localtag, as_localonexecute] + options = [mao_separator, mao_shortcutcaption] + tag = 4 + end + item + caption = '&Size default' + name = 'size' + state = [as_checked, as_localchecked, as_localcaption, as_localgroup, as_localonexecute] + options = [mao_radiobutton, mao_shortcutcaption] + group = 1 + onexecute = sizeexecute + end + item + caption = '&8 Bit' + state = [as_localcaption, as_localtag, as_localgroup, as_localonexecute] + options = [mao_radiobutton, mao_shortcutcaption] + tag = 1 + group = 1 + onexecute = sizeexecute + end + item + caption = '&16 Bit' + state = [as_localcaption, as_localtag, as_localgroup, as_localonexecute] + options = [mao_radiobutton, mao_shortcutcaption] + tag = 2 + group = 1 + onexecute = sizeexecute + end + item + caption = '&32 Bit' + state = [as_localcaption, as_localtag, as_localgroup, as_localonexecute] + options = [mao_radiobutton, mao_shortcutcaption] + tag = 3 + group = 1 + onexecute = sizeexecute + end + item + caption = '&64 Bit' + name = '&64 Bit' + state = [as_localcaption, as_localtag, as_localgroup, as_localonexecute] + options = [mao_radiobutton, mao_shortcutcaption] + tag = 4 + group = 1 + onexecute = sizeexecute + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = '&Reset Formats' + state = [as_localcaption, as_localonexecute] + onexecute = resetformats + end> + menu.name = 'gridpopup' + menu.state = [as_localonexecute] + menu.onexecute = deletallexecute + left = 96 + top = 112 + end + object timagelist1: timagelist + width = 10 + height = 18 + count = 4 + left = 96 + top = 152 + image = { + 00000000020000001400000024000000CC010000000000000000000000000000 + 0000000000000000000000000000000000000000FFFFFF6700000003FFFFFF07 + 00000003FFFFFF0700000001FFFFFF0200000001FFFFFF0600000001FFFFFF02 + 00000001FFFFFF0600000001FFFFFF0200000001FFFFFF0600000001FFFFFF02 + 00000001FFFFFF0600000003FFFFFF0700000001FFFFFF0200000001FFFFFF06 + 00000001FFFFFF0200000001FFFFFF0600000001FFFFFF0200000001FFFFFF06 + 00000001FFFFFF0200000001FFFFFF0600000001FFFFFF0200000001FFFFFF06 + 00000001FFFFFF0200000001FFFFFF0600000001FFFFFF0200000001FFFFFF06 + 00000003FFFFFF0700000003FFFFFFCF00000001FFFFFF0200000001FFFFFF06 + 00000001FFFFFF0200000001FFFFFF0600000001FFFFFF0200000001FFFFFF06 + 00000001FFFFFF0200000001FFFFFF0600000001FFFFFF0200000001FFFFFF06 + 00000001FFFFFF0200000001FFFFFF0600000001FFFFFF0200000001FFFFFF06 + 00000001FFFFFF0200000001FFFFFF0600000001FFFFFF0200000001FFFFFF06 + 00000004FFFFFF0600000001FFFFFF0200000001FFFFFF0600000001FFFFFF02 + 00000001FFFFFF0600000001FFFFFF0200000001FFFFFF0600000001FFFFFF02 + 00000001FFFFFF0700000002FFFFFF0700000001FFFFFF0200000001FFFFFF67 + 000010080000D0BF00009008000000000000900838E08005482001C048200100 + 38209108482001004820D1BF4820110838E09008000020080000D0BF00000008 + 000000000000900800008005000000C000000000000090080000000048201108 + 48209108482091084820D1BF48E0010848200100482081053020014000000000 + 00000000000000000000000000000000 + } + end + object c: tstringcontainer + strings.data = ( + 'Do you wish to delete all watches?' + 'Confirmation' + '' + ) + left = 96 + top = 80 + end +end diff --git a/mseide-msegui/apps/ide/watchform.pas b/mseide-msegui/apps/ide/watchform.pas new file mode 100644 index 0000000..9f4c50c --- /dev/null +++ b/mseide-msegui/apps/ide/watchform.pas @@ -0,0 +1,336 @@ +{ MSEide Copyright (c) 1999-2016 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit watchform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +uses + mseforms,msedataedits,msewidgetgrid,msegdbutils,msegraphedits,msedock,msegrids, + msegui,msestrings,msemenus,mseedit,mseevent,msetypes,msegraphics,msebitmap, + msestringcontainer; + +type + twatchfo = class(tdockform) + grid: twidgetgrid; + expression: tstringedit; + expresult: tstringedit; + gripopup: tpopupmenu; + watchon: tbooleanedit; + watcheson: tbooleanedit; + sizecode: tintegeredit; + formatcode: tdatabutton; + timagelist1: timagelist; + c: tstringcontainer; + procedure expressionondataentered(const sender: tobject); + procedure expresultonsetvalue(const sender: tobject; var avalue: msestring; var accept: boolean); + procedure resultcellevent(const sender: TObject; var info: celleventinfoty); + procedure watchesononchange(const sender: TObject); + procedure watchesononsetvalue(const sender: TObject; var avalue: Boolean; + var accept: Boolean); + procedure deletallexecute(const sender: TObject); + procedure formatexecute(const sender: TObject); + procedure popupdate(const sender: tcustommenu); + procedure sizeexecute(const sender: TObject); + procedure addwatchpoint(const sender: TObject); + procedure addresswatch(const sender: TObject); + procedure formatent(const sender: TObject); + procedure resetformats(const sender: TObject); + public + gdb: tgdbmi; + procedure clear(const all: boolean = false); + procedure refresh; + function refreshitem(const index: integer): boolean; //true if no timeout + procedure addwatch(aexpression: msestring); + end; + +var + watchfo: twatchfo; + + +implementation +uses + watchform_mfm,main,msewidgets,projectoptionsform,actionsmodule,msegraphutils, + mseguiglob,mseformatstr,msebits,sysutils,watchpointsform,memoryform; +type + stringconstants = ( + deleteall, //0 Do you wish to delete all watches? + confirmation, //1 Confirmation + disabled //2 + ); + + numformatty = (nf_default,nf_bin,nf_decs,nf_decu,nf_hex); + numsizety = (ns_default,ns_8,ns_16,ns_32,ns_64); + +{ twatchfo } + +procedure twatchfo.watchesononsetvalue(const sender: TObject; var avalue: Boolean; var accept: Boolean); +begin + actionsmo.watchesonact.checked:= avalue; +end; + +procedure twatchfo.resultcellevent(const sender: TObject; var info: celleventinfoty); +//var +// rect1: rectty; +begin +{ + with info,expresult do begin + if (eventkind = cek_firstmousepark) and textclipped(cell.row,rect1) then begin + inc(rect1.cy,12); + application.showhint(grid,gridvalue[cell.row],rect1,cp_bottomleft,-1); + end; + end; + } +end; + +procedure twatchfo.watchesononchange(const sender: TObject); +begin + projectoptions.modified:= true; + refresh; +end; + +procedure twatchfo.expressionondataentered(const sender: tobject); +begin + projectoptions.modified:= true; + refreshitem(grid.row); +end; + +procedure twatchfo.clear(const all: boolean = false); +begin + if all then begin + grid.clear; + end + else begin + expresult.fillcol(''); + end; +end; + +function twatchfo.refreshitem(const index: integer): boolean; +var + mstr1,mstr2: msestring; + str1: ansistring; + fc: numformatty; + fs: numsizety; + int641: int64; + int2: integer; +begin + result:= true; + if (index >= 0) and gdb.cancommand then begin + if watcheson.value and watchon[index] then begin + mstr2:= expression[index]; + if (mstr2 <> '') and (mstr2[1] = '#') then begin + result:= gdb.executecommand(ansistring( + copy(mstr2,2,bigint)),str1) <> gdb_timeout; + mstr1:= msestring(str1); + end + else begin + result:= gdb.readpascalvariable(ansistring(mstr2),mstr1) <> gdb_timeout; + end; + fc:= numformatty(formatcode[index]); + if fc <> nf_default then begin + if trystrtointvalue64(ansistring(mstr1),qword(int641)) then begin + int2:= highestbit64(int641); + if int2 <= 0 then begin + int2:= 1; + end; + fs:= numsizety(sizecode[index]); + case fc of + nf_bin: begin + int2:= int2+1; //bitcount + case fs of + ns_8: int2:= 8; + ns_16: int2:= 16; + ns_32: int2:= 32; + ns_64: int2:= 64; + end; + mstr1:= '%'+msestring(bintostr(qword(int641),int2)); + end; + nf_decs: begin + case fs of + ns_8: mstr1:= inttostrmse(shortint(int641)); + ns_16: mstr1:= inttostrmse(smallint(int641)); + ns_32: mstr1:= inttostrmse(integer(int641)); + else mstr1:= inttostrmse(int641); + end; + end; + nf_decu: begin + mstr1:= inttostrmse(qword(int641)); + end; + nf_hex: begin + int2:= int2 div 4 + 1; //nibble count + case fs of + ns_8: int2:= 2; + ns_16: int2:= 4; + ns_32: int2:= 8; + ns_64: int2:= 16; + end; + mstr1:= '0x'+hextostrmse(qword(int641),int2); + end; + end; + end; + end; + if (expresult[index] <> mstr1) then begin + grid.rowfontstate[index]:= 0; + end + else begin + grid.rowfontstate[index]:= -1; + end; + expresult[index]:= removelinebreaks(mstr1); + end + else begin + grid.rowfontstate[index]:= -1; + expresult[index]:= c[ord(disabled)]; + end; + end + else begin + expresult[index]:= ''; + end; +end; + +procedure twatchfo.refresh; +var + int1: integer; + bo1: boolean; +begin + bo1:= true; + for int1:= 0 to grid.rowcount -1 do begin + bo1:= bo1 and refreshitem(int1); + if not bo1 then begin + expresult[int1]:= ''; + end; + end; + memoryfo.refresh; +end; + +procedure twatchfo.expresultonsetvalue(const sender: tobject; + var avalue: msestring; var accept: boolean); +var + str1: string; +begin + gdb.interrupttarget; + accept:= gdb.writepascalvariable(ansistring(expression.value), + ansistring(avalue),str1) = gdb_ok; + if accept then begin + refresh; + avalue:= msestring(str1); + end + else begin + showerror(msestring(str1)); + tstringedit(sender).editor.undo; + end; + gdb.restarttarget; +end; + +procedure twatchfo.addwatch(aexpression: msestring); +var + int1: integer; +begin + int1:= grid.appendrow; + expression[int1]:= aexpression; + if gdb.cancommand then begin + refreshitem(int1); + end; +end; + +procedure twatchfo.deletallexecute(const sender: TObject); +begin + if askok(c[ord(deleteall)],c[ord(confirmation)]) then begin + grid.clear; + end; +end; + +procedure twatchfo.formatexecute(const sender: TObject); +var + int1: integer; +begin + with tmenuitem(sender) do begin + int1:= checkedtag; + if formatcode.value <> int1 then begin + formatcode.value:= int1; + refreshitem(grid.row); + end; + end; +end; + +procedure twatchfo.formatent(const sender: TObject); +begin + sizecode.value:= 0; //ns_default + refreshitem(grid.row); +end; + +procedure twatchfo.resetformats(const sender: TObject); +begin + formatcode.fillcol(0); + sizecode.fillcol(0); + refresh; +end; + + +procedure twatchfo.sizeexecute(const sender: TObject); +var + int1: integer; +begin + with tmenuitem(sender) do begin + int1:= checkedtag; + if sizecode.value <> int1 then begin + sizecode.value:= int1; + refreshitem(grid.row); + end; + end; +end; + +procedure twatchfo.popupdate(const sender: tcustommenu); +begin + sender.menu.itembyname('format').checkedtag:= formatcode.value; + sender.menu.itembyname('size').checkedtag:= sizecode.value; +end; + +procedure twatchfo.addwatchpoint(const sender: TObject); +begin + watchpointsfo.addwatch(expression.value); +end; + +procedure twatchfo.addresswatch(const sender: TObject); +//todo: make language independent +var + str1: ansistring; +begin + if gdb.symboladdress(ansistring(expression.value),str1) = gdb_ok then begin + str1:= '('+str1+'^)'; + case tmenuitem(sender).tag of + 0: begin + str1:= 'byte'+str1; + end; + 1: begin + str1:= 'word'+str1; + end; + 2: begin + str1:= 'longword'+str1; + end; + 3: begin + str1:= 'qword'+str1; + end; + end; + watchpointsfo.addwatch(msestring(str1)); + end + else begin + showerror(msestring(str1)); + end; +end; + +end. diff --git a/mseide-msegui/apps/ide/watchform_mfm.pas b/mseide-msegui/apps/ide/watchform_mfm.pas new file mode 100644 index 0000000..d543e20 --- /dev/null +++ b/mseide-msegui/apps/ide/watchform_mfm.pas @@ -0,0 +1,509 @@ +unit watchform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,watchform; + +const + objdata: record size: integer; data: array[0..9838] of byte end = + (size: 9839; data: ( + 84,80,70,48,8,116,119,97,116,99,104,102,111,7,119,97,116,99,104,102, + 111,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,11,111,119,95, + 116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,0,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,15,102,114,108,95,111,112,116,105, + 111,110,115,115,107,105,110,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,15,102,114,97,109,101,46,103,114,105,112,95, + 115,105,122,101,2,10,18,102,114,97,109,101,46,103,114,105,112,95,111,112, + 116,105,111,110,115,11,14,103,111,95,99,108,111,115,101,98,117,116,116,111, + 110,16,103,111,95,102,105,120,115,105,122,101,98,117,116,116,111,110,14,103, + 111,95,102,108,111,97,116,98,117,116,116,111,110,12,103,111,95,116,111,112, + 98,117,116,116,111,110,19,103,111,95,98,97,99,107,103,114,111,117,110,100, + 98,117,116,116,111,110,15,103,111,95,110,111,108,111,99,107,98,117,116,116, + 111,110,14,103,111,95,98,117,116,116,111,110,104,105,110,116,115,0,7,118, + 105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,35,1,8, + 98,111,117,110,100,115,95,121,3,247,0,9,98,111,117,110,100,115,95,99, + 120,3,54,1,9,98,111,117,110,100,115,95,99,121,3,245,0,23,99,111, + 110,116,97,105,110,101,114,46,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95, + 116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,11,111,119,95,115,117,98,102,111,99,117,115,19,111,119,95,109,111, + 117,115,101,116,114,97,110,115,112,97,114,101,110,116,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,0,15,99,111,110,116,97,105, + 110,101,114,46,99,111,108,111,114,4,3,0,0,128,26,99,111,110,116,97, + 105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,15,102,114,108,95,111,112,116,105,111,110,115,115,107,105,110,0,27, + 99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,16,99,111,110,116,97,105,110,101,114,46, + 98,111,117,110,100,115,1,2,0,2,0,3,44,1,3,245,0,0,22,100, + 114,97,103,100,111,99,107,46,115,112,108,105,116,116,101,114,95,115,105,122, + 101,2,0,16,100,114,97,103,100,111,99,107,46,99,97,112,116,105,111,110, + 6,7,87,97,116,99,104,101,115,20,100,114,97,103,100,111,99,107,46,111, + 112,116,105,111,110,115,100,111,99,107,11,10,111,100,95,115,97,118,101,112, + 111,115,10,111,100,95,99,97,110,109,111,118,101,11,111,100,95,99,97,110, + 102,108,111,97,116,10,111,100,95,99,97,110,100,111,99,107,15,111,100,95, + 112,114,111,112,111,114,116,105,111,110,97,108,11,111,100,95,112,114,111,112, + 115,105,122,101,14,111,100,95,99,97,112,116,105,111,110,104,105,110,116,13, + 111,100,95,99,104,105,108,100,105,99,111,110,115,0,7,111,112,116,105,111, + 110,115,11,10,102,111,95,115,97,118,101,112,111,115,12,102,111,95,115,97, + 118,101,115,116,97,116,101,0,8,115,116,97,116,102,105,108,101,7,22,109, + 97,105,110,102,111,46,112,114,111,106,101,99,116,115,116,97,116,102,105,108, + 101,7,99,97,112,116,105,111,110,6,7,87,97,116,99,104,101,115,21,105, + 99,111,110,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,12,105,99,111,110,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,0,10,105,99,111,110,46,105,109,97, + 103,101,10,96,3,0,0,0,0,0,0,2,0,0,0,24,0,0,0,24, + 0,0,0,204,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,208, + 208,208,96,124,124,124,25,217,217,217,22,255,255,255,1,124,124,124,1,217, + 217,217,3,200,200,200,1,161,161,161,1,217,217,217,5,166,166,166,1,194, + 194,194,1,217,217,217,4,210,210,210,1,154,154,154,1,217,217,217,4,255, + 255,255,1,124,124,124,1,217,217,217,2,78,78,78,1,13,13,13,1,24, + 24,24,2,150,150,150,1,217,217,217,1,184,184,184,1,30,30,30,1,22, + 22,22,1,14,14,14,1,54,54,54,1,217,217,217,2,106,106,106,1,15, + 15,15,1,28,28,28,1,17,17,17,1,119,119,119,1,217,217,217,2,255, + 255,255,1,124,124,124,1,217,217,217,1,182,182,182,1,8,8,8,1,191, + 191,191,1,217,217,217,1,82,82,82,1,48,48,48,1,217,217,217,1,79, + 79,79,1,57,57,57,1,217,217,217,1,204,204,204,1,18,18,18,1,138, + 138,138,1,210,210,210,1,14,14,14,1,151,151,151,1,217,217,217,1,121, + 121,121,1,23,23,23,1,217,217,217,2,255,255,255,1,124,124,124,1,217, + 217,217,1,156,156,156,1,105,105,105,1,217,217,217,2,159,159,159,1,14, + 14,14,1,217,217,217,1,99,99,99,1,161,161,161,1,217,217,217,2,60, + 60,60,1,81,81,81,1,181,181,181,1,86,86,86,1,217,217,217,2,210, + 210,210,1,2,2,2,1,194,194,194,1,217,217,217,1,255,255,255,1,124, + 124,124,1,217,217,217,5,51,51,51,1,60,60,60,1,217,217,217,4,171, + 171,171,1,11,11,11,1,150,150,150,1,217,217,217,4,83,83,83,1,31, + 31,31,1,217,217,217,2,255,255,255,1,124,124,124,1,217,217,217,4,78, + 78,78,1,26,26,26,1,204,204,204,1,217,217,217,3,194,194,194,1,19, + 19,19,1,94,94,94,1,217,217,217,4,113,113,113,1,14,14,14,1,180, + 180,180,1,217,217,217,2,255,255,255,1,124,124,124,1,217,217,217,3,185, + 185,185,1,9,9,9,1,185,185,185,1,217,217,217,4,79,79,79,1,56, + 56,56,1,217,217,217,5,13,13,13,1,149,149,149,1,217,217,217,3,255, + 255,255,1,124,124,124,1,217,217,217,3,139,139,139,1,39,39,39,1,217, + 217,217,5,53,53,53,1,117,117,117,1,217,217,217,4,188,188,188,1,16, + 16,16,1,217,217,217,4,255,255,255,1,124,124,124,1,217,217,217,3,210, + 210,210,1,197,197,197,1,217,217,217,5,199,199,199,1,207,207,207,1,217, + 217,217,4,213,213,213,1,194,194,194,1,217,217,217,4,255,255,255,1,124, + 124,124,1,217,217,217,3,111,111,111,1,20,20,20,1,217,217,217,5,31, + 31,31,1,93,93,93,1,217,217,217,4,156,156,156,1,0,0,0,1,213, + 213,213,1,217,217,217,3,255,255,255,1,124,124,124,1,217,217,217,3,185, + 185,185,1,146,146,146,1,217,217,217,5,153,153,153,1,178,178,178,1,217, + 217,217,4,200,200,200,1,134,134,134,1,217,217,217,4,255,255,255,1,124, + 124,124,1,217,217,217,22,255,255,255,1,124,124,124,1,217,217,217,22,255, + 255,255,1,124,124,124,1,255,255,255,23,208,208,208,96,0,0,0,0,0, + 0,0,0,0,0,0,0,0,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,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,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,15,109,111,100,117,108,101,99,108, + 97,115,115,110,97,109,101,6,9,116,100,111,99,107,102,111,114,109,0,11, + 116,119,105,100,103,101,116,103,114,105,100,4,103,114,105,100,13,111,112,116, + 105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101, + 102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119, + 95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119, + 102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117, + 115,111,117,116,17,111,119,95,102,111,99,117,115,98,97,99,107,111,110,101, + 115,99,13,111,119,95,109,111,117,115,101,119,104,101,101,108,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,9,111,119,95,104,105, + 110,116,111,110,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,15,102,114,108,95,111,112,116,105,111,110,115,115,107,105,110,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 8,116,97,98,111,114,100,101,114,2,1,9,112,111,112,117,112,109,101,110, + 117,7,8,103,114,105,112,111,112,117,112,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,2,24,9,98,111,117,110,100,115, + 95,99,120,3,44,1,9,98,111,117,110,100,115,95,99,121,3,221,0,7, + 97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,9,97,110,95,98, + 111,116,116,111,109,0,11,111,112,116,105,111,110,115,103,114,105,100,11,12, + 111,103,95,99,111,108,115,105,122,105,110,103,12,111,103,95,114,111,119,109, + 111,118,105,110,103,15,111,103,95,107,101,121,114,111,119,109,111,118,105,110, + 103,15,111,103,95,114,111,119,105,110,115,101,114,116,105,110,103,14,111,103, + 95,114,111,119,100,101,108,101,116,105,110,103,19,111,103,95,102,111,99,117, + 115,99,101,108,108,111,110,101,110,116,101,114,15,111,103,95,97,117,116,111, + 102,105,114,115,116,114,111,119,13,111,103,95,97,117,116,111,97,112,112,101, + 110,100,10,111,103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116, + 111,112,111,112,117,112,0,13,102,105,120,99,111,108,115,46,99,111,117,110, + 116,2,1,13,102,105,120,99,111,108,115,46,105,116,101,109,115,14,1,5, + 119,105,100,116,104,2,20,8,110,117,109,115,116,97,114,116,2,1,7,110, + 117,109,115,116,101,112,2,1,0,0,13,102,105,120,114,111,119,115,46,99, + 111,117,110,116,2,1,13,102,105,120,114,111,119,115,46,105,116,101,109,115, + 14,1,6,104,101,105,103,104,116,2,16,14,99,97,112,116,105,111,110,115, + 46,99,111,117,110,116,2,6,14,99,97,112,116,105,111,110,115,46,105,116, + 101,109,115,14,1,7,99,97,112,116,105,111,110,6,1,65,4,104,105,110, + 116,6,6,65,99,116,105,118,101,0,1,7,99,97,112,116,105,111,110,6, + 10,69,120,112,114,101,115,115,105,111,110,4,104,105,110,116,6,55,69,120, + 112,114,101,115,115,105,111,110,115,32,115,116,97,114,116,105,110,103,32,119, + 105,116,104,32,35,32,97,114,101,32,116,114,101,97,116,101,100,32,97,115, + 32,103,100,98,32,99,111,109,109,97,110,100,115,0,1,7,99,97,112,116, + 105,111,110,6,6,82,101,115,117,108,116,0,1,7,99,97,112,116,105,111, + 110,6,1,70,4,104,105,110,116,6,73,68,105,115,112,108,97,121,32,102, + 111,114,109,97,116,10,66,32,61,32,66,105,110,97,114,121,10,68,32,61, + 32,68,101,99,105,109,97,108,32,115,105,103,110,101,100,10,85,32,61,32, + 68,101,99,105,109,97,108,32,117,110,115,105,103,110,101,100,10,72,32,61, + 32,72,101,120,0,1,0,1,0,0,0,0,14,114,111,119,102,111,110,116, + 115,46,99,111,117,110,116,2,1,14,114,111,119,102,111,110,116,115,46,105, + 116,101,109,115,14,1,5,99,111,108,111,114,4,7,0,0,160,4,110,97, + 109,101,6,11,115,116,102,95,100,101,102,97,117,108,116,6,120,115,99,97, + 108,101,2,1,10,108,111,99,97,108,112,114,111,112,115,11,9,102,108,112, + 95,99,111,108,111,114,10,102,108,112,95,120,115,99,97,108,101,0,0,0, + 14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,5,14,100,97, + 116,97,99,111,108,115,46,105,116,101,109,115,14,7,7,119,97,116,99,104, + 111,110,1,5,119,105,100,116,104,2,13,7,111,112,116,105,111,110,115,11, + 12,99,111,95,100,114,97,119,102,111,99,117,115,11,99,111,95,102,105,120, + 119,105,100,116,104,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99, + 111,95,115,97,118,101,115,116,97,116,101,0,10,119,105,100,103,101,116,110, + 97,109,101,6,7,119,97,116,99,104,111,110,9,100,97,116,97,99,108,97, + 115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97, + 108,105,115,116,0,7,10,101,120,112,114,101,115,115,105,111,110,1,5,119, + 105,100,116,104,3,152,0,7,111,112,116,105,111,110,115,11,12,99,111,95, + 115,97,118,101,118,97,108,117,101,12,99,111,95,115,97,118,101,115,116,97, + 116,101,0,8,111,112,116,105,111,110,115,49,11,12,99,111,49,95,114,111, + 119,99,111,108,111,114,14,99,111,49,95,122,101,98,114,97,99,111,108,111, + 114,0,10,119,105,100,103,101,116,110,97,109,101,6,10,101,120,112,114,101, + 115,115,105,111,110,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114, + 105,100,109,115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0, + 7,9,101,120,112,114,101,115,117,108,116,1,5,119,105,100,116,104,2,80, + 7,111,112,116,105,111,110,115,11,7,99,111,95,102,105,108,108,0,8,119, + 105,100,116,104,109,105,110,2,50,11,111,110,99,101,108,108,101,118,101,110, + 116,7,15,114,101,115,117,108,116,99,101,108,108,101,118,101,110,116,10,119, + 105,100,103,101,116,110,97,109,101,6,9,101,120,112,114,101,115,117,108,116, + 9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101, + 115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,10,102,111,114, + 109,97,116,99,111,100,101,1,5,99,111,108,111,114,4,2,0,0,128,11, + 99,111,108,111,114,97,99,116,105,118,101,4,7,0,0,144,5,119,105,100, + 116,104,2,12,7,111,112,116,105,111,110,115,11,11,99,111,95,102,105,120, + 119,105,100,116,104,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99, + 111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109,111,117,115,101, + 115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109, + 101,6,10,102,111,114,109,97,116,99,111,100,101,9,100,97,116,97,99,108, + 97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116, + 97,108,105,115,116,0,7,8,115,105,122,101,99,111,100,101,1,5,119,105, + 100,116,104,2,13,7,111,112,116,105,111,110,115,11,12,99,111,95,105,110, + 118,105,115,105,98,108,101,12,99,111,95,115,97,118,101,118,97,108,117,101, + 12,99,111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109,111,117, + 115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110, + 97,109,101,6,8,115,105,122,101,99,111,100,101,9,100,97,116,97,99,108, + 97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116, + 97,108,105,115,116,0,0,13,100,97,116,97,114,111,119,104,101,105,103,104, + 116,2,16,8,115,116,97,116,102,105,108,101,7,22,109,97,105,110,102,111, + 46,112,114,111,106,101,99,116,115,116,97,116,102,105,108,101,13,114,101,102, + 102,111,110,116,104,101,105,103,104,116,2,14,0,12,116,98,111,111,108,101, + 97,110,101,100,105,116,7,119,97,116,99,104,111,110,11,111,112,116,105,111, + 110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116, + 116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,1,8, + 98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,121,2,16,8,115,116,97,116,102,105, + 108,101,7,22,109,97,105,110,102,111,46,112,114,111,106,101,99,116,115,116, + 97,116,102,105,108,101,11,111,112,116,105,111,110,115,101,100,105,116,11,12, + 111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115, + 101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110, + 99,101,108,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95, + 114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101, + 95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,97,117,116, + 111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99, + 116,111,110,102,105,114,115,116,99,108,105,99,107,0,12,111,112,116,105,111, + 110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112,111,112, + 117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99,117,116, + 101,13,111,101,49,95,115,97,118,101,118,97,108,117,101,13,111,101,49,95, + 115,97,118,101,115,116,97,116,101,0,13,111,110,100,97,116,97,101,110,116, + 101,114,101,100,7,23,101,120,112,114,101,115,115,105,111,110,111,110,100,97, + 116,97,101,110,116,101,114,101,100,7,118,105,115,105,98,108,101,8,5,118, + 97,108,117,101,9,12,118,97,108,117,101,100,101,102,97,117,108,116,9,0, + 0,11,116,115,116,114,105,110,103,101,100,105,116,10,101,120,112,114,101,115, + 115,105,111,110,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13, + 111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98, + 102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15, + 111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97, + 114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116, + 114,111,121,119,105,100,103,101,116,115,0,11,111,112,116,105,111,110,115,115, + 107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110, + 111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,2,7,118,105,115, + 105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,14,8,98,111,117, + 110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,152,0, + 9,98,111,117,110,100,115,95,99,121,2,16,8,115,116,97,116,102,105,108, + 101,7,22,109,97,105,110,102,111,46,112,114,111,106,101,99,116,115,116,97, + 116,102,105,108,101,12,111,112,116,105,111,110,115,101,100,105,116,49,11,13, + 111,101,49,95,115,97,118,101,118,97,108,117,101,0,11,111,112,116,105,111, + 110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99, + 13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104, + 101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105,102,116, + 114,101,116,117,114,110,24,111,101,95,102,111,114,99,101,114,101,116,117,114, + 110,99,104,101,99,107,118,97,108,117,101,12,111,101,95,101,97,116,114,101, + 116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111, + 110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111, + 114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97, + 117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108, + 101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,18,111,101,95,104, + 105,110,116,99,108,105,112,112,101,100,116,101,120,116,0,13,111,110,100,97, + 116,97,101,110,116,101,114,101,100,7,23,101,120,112,114,101,115,115,105,111, + 110,111,110,100,97,116,97,101,110,116,101,114,101,100,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,14,0,0,11,116,115,116,114,105,110,103, + 101,100,105,116,9,101,120,112,114,101,115,117,108,116,14,111,112,116,105,111, + 110,115,119,105,100,103,101,116,49,11,13,111,119,49,95,97,117,116,111,115, + 99,97,108,101,0,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,11,111,112,116,105,111,110,115, + 115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111, + 110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,3,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,167,0,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2, + 80,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110, + 115,101,100,105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105,116, + 11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108, + 111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99, + 97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110, + 12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115, + 101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120, + 105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101, + 110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111, + 101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99, + 108,105,99,107,18,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116, + 101,120,116,0,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121, + 99,101,110,116,101,114,101,100,11,116,102,95,110,111,115,101,108,101,99,116, + 15,116,102,95,101,108,108,105,112,115,101,114,105,103,104,116,0,10,111,110, + 115,101,116,118,97,108,117,101,7,19,101,120,112,114,101,115,117,108,116,111, + 110,115,101,116,118,97,108,117,101,0,0,11,116,100,97,116,97,98,117,116, + 116,111,110,10,102,111,114,109,97,116,99,111,100,101,8,116,97,98,111,114, + 100,101,114,2,4,8,98,111,117,110,100,115,95,120,3,248,0,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,12, + 9,98,111,117,110,100,115,95,99,121,2,16,13,111,110,100,97,116,97,101, + 110,116,101,114,101,100,7,9,102,111,114,109,97,116,101,110,116,5,115,116, + 97,116,101,11,12,97,115,95,105,110,118,105,115,105,98,108,101,17,97,115, + 95,108,111,99,97,108,105,109,97,103,101,108,105,115,116,0,9,105,109,97, + 103,101,108,105,115,116,7,11,116,105,109,97,103,101,108,105,115,116,49,13, + 102,111,99,117,115,114,101,99,116,100,105,115,116,2,0,15,105,109,97,103, + 101,110,117,109,115,46,99,111,117,110,116,2,5,15,105,109,97,103,101,110, + 117,109,115,46,105,116,101,109,115,1,2,255,2,0,2,1,2,2,2,3, + 0,5,118,97,108,117,101,2,0,12,118,97,108,117,101,100,101,102,97,117, + 108,116,2,0,3,109,105,110,2,0,3,109,97,120,2,4,0,0,12,116, + 105,110,116,101,103,101,114,101,100,105,116,8,115,105,122,101,99,111,100,101, + 14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49, + 95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,11,111,112, + 116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101, + 98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101, + 118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108, + 105,101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,10,102, + 114,108,95,108,101,118,101,108,105,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,5,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,5,1,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2, + 13,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110, + 115,101,100,105,116,49,11,13,111,101,49,95,115,97,118,101,118,97,108,117, + 101,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0, + 0,12,116,98,111,111,108,101,97,110,101,100,105,116,9,119,97,116,99,104, + 101,115,111,110,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,11, + 87,97,116,99,104,101,115,32,38,111,110,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,1,2,77,2,2,0,8,98,111, + 117,110,100,115,95,120,2,8,8,98,111,117,110,100,115,95,121,2,4,9, + 98,111,117,110,100,115,95,99,120,2,90,9,98,111,117,110,100,115,95,99, + 121,2,16,8,115,116,97,116,102,105,108,101,7,22,109,97,105,110,102,111, + 46,112,114,111,106,101,99,116,115,116,97,116,102,105,108,101,11,111,112,116, + 105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101, + 115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95, + 99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101,97,116, + 114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99, + 116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114, + 115,111,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101, + 95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108, + 105,99,107,0,8,111,110,99,104,97,110,103,101,7,17,119,97,116,99,104, + 101,115,111,110,111,110,99,104,97,110,103,101,10,111,110,115,101,116,118,97, + 108,117,101,7,19,119,97,116,99,104,101,115,111,110,111,110,115,101,116,118, + 97,108,117,101,5,118,97,108,117,101,9,0,0,10,116,112,111,112,117,112, + 109,101,110,117,8,103,114,105,112,111,112,117,112,8,111,110,117,112,100,97, + 116,101,7,9,112,111,112,117,112,100,97,116,101,18,109,101,110,117,46,115, + 117,98,109,101,110,117,46,99,111,117,110,116,2,21,18,109,101,110,117,46, + 115,117,98,109,101,110,117,46,105,116,101,109,115,14,1,7,99,97,112,116, + 105,111,110,6,10,68,101,108,101,116,101,32,97,108,108,5,115,116,97,116, + 101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97, + 115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110, + 101,120,101,99,117,116,101,7,15,100,101,108,101,116,97,108,108,101,120,101, + 99,117,116,101,0,1,7,111,112,116,105,111,110,115,11,13,109,97,111,95, + 115,101,112,97,114,97,116,111,114,19,109,97,111,95,115,104,111,114,116,99, + 117,116,99,97,112,116,105,111,110,0,0,1,7,99,97,112,116,105,111,110, + 6,14,65,100,100,32,87,97,116,99,104,112,111,105,110,116,5,115,116,97, + 116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17, + 97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111, + 110,101,120,101,99,117,116,101,7,13,97,100,100,119,97,116,99,104,112,111, + 105,110,116,0,1,7,99,97,112,116,105,111,110,6,20,65,100,100,114,101, + 115,115,32,87,97,116,99,104,112,111,105,110,116,32,56,5,115,116,97,116, + 101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97, + 115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110, + 101,120,101,99,117,116,101,7,12,97,100,100,114,101,115,115,119,97,116,99, + 104,0,1,7,99,97,112,116,105,111,110,6,21,65,100,100,114,101,115,115, + 32,87,97,116,99,104,112,111,105,110,116,32,49,54,5,115,116,97,116,101, + 11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,11,97,115, + 95,108,111,99,97,108,116,97,103,17,97,115,95,108,111,99,97,108,111,110, + 101,120,101,99,117,116,101,0,3,116,97,103,2,1,9,111,110,101,120,101, + 99,117,116,101,7,12,97,100,100,114,101,115,115,119,97,116,99,104,0,1, + 7,99,97,112,116,105,111,110,6,21,65,100,100,114,101,115,115,32,87,97, + 116,99,104,112,111,105,110,116,32,51,50,5,115,116,97,116,101,11,15,97, + 115,95,108,111,99,97,108,99,97,112,116,105,111,110,11,97,115,95,108,111, + 99,97,108,116,97,103,17,97,115,95,108,111,99,97,108,111,110,101,120,101, + 99,117,116,101,0,3,116,97,103,2,2,9,111,110,101,120,101,99,117,116, + 101,7,12,97,100,100,114,101,115,115,119,97,116,99,104,0,1,7,99,97, + 112,116,105,111,110,6,21,65,100,100,114,101,115,115,32,87,97,116,99,104, + 112,111,105,110,116,32,54,52,5,115,116,97,116,101,11,15,97,115,95,108, + 111,99,97,108,99,97,112,116,105,111,110,11,97,115,95,108,111,99,97,108, + 116,97,103,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116, + 101,0,3,116,97,103,2,3,9,111,110,101,120,101,99,117,116,101,7,12, + 97,100,100,114,101,115,115,119,97,116,99,104,0,1,7,111,112,116,105,111, + 110,115,11,13,109,97,111,95,115,101,112,97,114,97,116,111,114,19,109,97, + 111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111,110,0,0,1, + 7,99,97,112,116,105,111,110,6,15,38,70,111,114,109,97,116,32,100,101, + 102,97,117,108,116,4,110,97,109,101,6,6,102,111,114,109,97,116,5,115, + 116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,104,101,99,107,101, + 100,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115, + 95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,7,111,112,116, + 105,111,110,115,11,15,109,97,111,95,114,97,100,105,111,98,117,116,116,111, + 110,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111, + 110,0,9,111,110,101,120,101,99,117,116,101,7,13,102,111,114,109,97,116, + 101,120,101,99,117,116,101,0,1,7,99,97,112,116,105,111,110,6,7,38, + 66,105,110,97,114,121,5,115,116,97,116,101,11,15,97,115,95,108,111,99, + 97,108,99,97,112,116,105,111,110,11,97,115,95,108,111,99,97,108,116,97, + 103,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0, + 7,111,112,116,105,111,110,115,11,15,109,97,111,95,114,97,100,105,111,98, + 117,116,116,111,110,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97, + 112,116,105,111,110,0,3,116,97,103,2,1,9,111,110,101,120,101,99,117, + 116,101,7,13,102,111,114,109,97,116,101,120,101,99,117,116,101,0,1,7, + 99,97,112,116,105,111,110,6,15,68,38,101,99,105,109,97,108,32,115,105, + 103,110,101,100,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,11,97,115,95,108,111,99,97,108,116,97,103,17, + 97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,7,111, + 112,116,105,111,110,115,11,15,109,97,111,95,114,97,100,105,111,98,117,116, + 116,111,110,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116, + 105,111,110,0,3,116,97,103,2,2,9,111,110,101,120,101,99,117,116,101, + 7,13,102,111,114,109,97,116,101,120,101,99,117,116,101,0,1,7,99,97, + 112,116,105,111,110,6,17,68,101,99,105,109,97,108,32,38,117,110,115,105, + 103,110,101,100,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,11,97,115,95,108,111,99,97,108,116,97,103,17, + 97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,7,111, + 112,116,105,111,110,115,11,15,109,97,111,95,114,97,100,105,111,98,117,116, + 116,111,110,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116, + 105,111,110,0,3,116,97,103,2,3,9,111,110,101,120,101,99,117,116,101, + 7,13,102,111,114,109,97,116,101,120,101,99,117,116,101,0,1,7,99,97, + 112,116,105,111,110,6,4,38,72,101,120,5,115,116,97,116,101,11,15,97, + 115,95,108,111,99,97,108,99,97,112,116,105,111,110,11,97,115,95,108,111, + 99,97,108,116,97,103,17,97,115,95,108,111,99,97,108,111,110,101,120,101, + 99,117,116,101,0,7,111,112,116,105,111,110,115,11,15,109,97,111,95,114, + 97,100,105,111,98,117,116,116,111,110,19,109,97,111,95,115,104,111,114,116, + 99,117,116,99,97,112,116,105,111,110,0,3,116,97,103,2,4,9,111,110, + 101,120,101,99,117,116,101,7,13,102,111,114,109,97,116,101,120,101,99,117, + 116,101,0,1,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,11,97,115,95,108,111,99,97,108,116,97,103,17, + 97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,7,111, + 112,116,105,111,110,115,11,13,109,97,111,95,115,101,112,97,114,97,116,111, + 114,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111, + 110,0,3,116,97,103,2,4,0,1,7,99,97,112,116,105,111,110,6,13, + 38,83,105,122,101,32,100,101,102,97,117,108,116,4,110,97,109,101,6,4, + 115,105,122,101,5,115,116,97,116,101,11,10,97,115,95,99,104,101,99,107, + 101,100,15,97,115,95,108,111,99,97,108,99,104,101,99,107,101,100,15,97, + 115,95,108,111,99,97,108,99,97,112,116,105,111,110,13,97,115,95,108,111, + 99,97,108,103,114,111,117,112,17,97,115,95,108,111,99,97,108,111,110,101, + 120,101,99,117,116,101,0,7,111,112,116,105,111,110,115,11,15,109,97,111, + 95,114,97,100,105,111,98,117,116,116,111,110,19,109,97,111,95,115,104,111, + 114,116,99,117,116,99,97,112,116,105,111,110,0,5,103,114,111,117,112,2, + 1,9,111,110,101,120,101,99,117,116,101,7,11,115,105,122,101,101,120,101, + 99,117,116,101,0,1,7,99,97,112,116,105,111,110,6,6,38,56,32,66, + 105,116,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97, + 112,116,105,111,110,11,97,115,95,108,111,99,97,108,116,97,103,13,97,115, + 95,108,111,99,97,108,103,114,111,117,112,17,97,115,95,108,111,99,97,108, + 111,110,101,120,101,99,117,116,101,0,7,111,112,116,105,111,110,115,11,15, + 109,97,111,95,114,97,100,105,111,98,117,116,116,111,110,19,109,97,111,95, + 115,104,111,114,116,99,117,116,99,97,112,116,105,111,110,0,3,116,97,103, + 2,1,5,103,114,111,117,112,2,1,9,111,110,101,120,101,99,117,116,101, + 7,11,115,105,122,101,101,120,101,99,117,116,101,0,1,7,99,97,112,116, + 105,111,110,6,7,38,49,54,32,66,105,116,5,115,116,97,116,101,11,15, + 97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,11,97,115,95,108, + 111,99,97,108,116,97,103,13,97,115,95,108,111,99,97,108,103,114,111,117, + 112,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0, + 7,111,112,116,105,111,110,115,11,15,109,97,111,95,114,97,100,105,111,98, + 117,116,116,111,110,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97, + 112,116,105,111,110,0,3,116,97,103,2,2,5,103,114,111,117,112,2,1, + 9,111,110,101,120,101,99,117,116,101,7,11,115,105,122,101,101,120,101,99, + 117,116,101,0,1,7,99,97,112,116,105,111,110,6,7,38,51,50,32,66, + 105,116,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97, + 112,116,105,111,110,11,97,115,95,108,111,99,97,108,116,97,103,13,97,115, + 95,108,111,99,97,108,103,114,111,117,112,17,97,115,95,108,111,99,97,108, + 111,110,101,120,101,99,117,116,101,0,7,111,112,116,105,111,110,115,11,15, + 109,97,111,95,114,97,100,105,111,98,117,116,116,111,110,19,109,97,111,95, + 115,104,111,114,116,99,117,116,99,97,112,116,105,111,110,0,3,116,97,103, + 2,3,5,103,114,111,117,112,2,1,9,111,110,101,120,101,99,117,116,101, + 7,11,115,105,122,101,101,120,101,99,117,116,101,0,1,7,99,97,112,116, + 105,111,110,6,7,38,54,52,32,66,105,116,4,110,97,109,101,6,7,38, + 54,52,32,66,105,116,5,115,116,97,116,101,11,15,97,115,95,108,111,99, + 97,108,99,97,112,116,105,111,110,11,97,115,95,108,111,99,97,108,116,97, + 103,13,97,115,95,108,111,99,97,108,103,114,111,117,112,17,97,115,95,108, + 111,99,97,108,111,110,101,120,101,99,117,116,101,0,7,111,112,116,105,111, + 110,115,11,15,109,97,111,95,114,97,100,105,111,98,117,116,116,111,110,19, + 109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105,111,110,0, + 3,116,97,103,2,4,5,103,114,111,117,112,2,1,9,111,110,101,120,101, + 99,117,116,101,7,11,115,105,122,101,101,120,101,99,117,116,101,0,1,7, + 111,112,116,105,111,110,115,11,13,109,97,111,95,115,101,112,97,114,97,116, + 111,114,19,109,97,111,95,115,104,111,114,116,99,117,116,99,97,112,116,105, + 111,110,0,0,1,7,99,97,112,116,105,111,110,6,14,38,82,101,115,101, + 116,32,70,111,114,109,97,116,115,5,115,116,97,116,101,11,15,97,115,95, + 108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97, + 108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116, + 101,7,12,114,101,115,101,116,102,111,114,109,97,116,115,0,0,9,109,101, + 110,117,46,110,97,109,101,6,9,103,114,105,100,112,111,112,117,112,10,109, + 101,110,117,46,115,116,97,116,101,11,17,97,115,95,108,111,99,97,108,111, + 110,101,120,101,99,117,116,101,0,14,109,101,110,117,46,111,110,101,120,101, + 99,117,116,101,7,15,100,101,108,101,116,97,108,108,101,120,101,99,117,116, + 101,4,108,101,102,116,2,96,3,116,111,112,2,112,0,0,10,116,105,109, + 97,103,101,108,105,115,116,11,116,105,109,97,103,101,108,105,115,116,49,5, + 119,105,100,116,104,2,10,6,104,101,105,103,104,116,2,18,5,99,111,117, + 110,116,2,4,4,108,101,102,116,2,96,3,116,111,112,3,152,0,5,105, + 109,97,103,101,10,144,2,0,0,0,0,0,0,2,0,0,0,20,0,0, + 0,36,0,0,0,204,1,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,255,255,255,103,0,0,0,3,255,255,255,7,0,0,0,3,255,255,255, + 7,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,6,0,0,0, + 1,255,255,255,2,0,0,0,1,255,255,255,6,0,0,0,1,255,255,255, + 2,0,0,0,1,255,255,255,6,0,0,0,1,255,255,255,2,0,0,0, + 1,255,255,255,6,0,0,0,3,255,255,255,7,0,0,0,1,255,255,255, + 2,0,0,0,1,255,255,255,6,0,0,0,1,255,255,255,2,0,0,0, + 1,255,255,255,6,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255, + 6,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,6,0,0,0, + 1,255,255,255,2,0,0,0,1,255,255,255,6,0,0,0,1,255,255,255, + 2,0,0,0,1,255,255,255,6,0,0,0,1,255,255,255,2,0,0,0, + 1,255,255,255,6,0,0,0,3,255,255,255,7,0,0,0,3,255,255,255, + 207,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,6,0,0,0, + 1,255,255,255,2,0,0,0,1,255,255,255,6,0,0,0,1,255,255,255, + 2,0,0,0,1,255,255,255,6,0,0,0,1,255,255,255,2,0,0,0, + 1,255,255,255,6,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255, + 6,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,6,0,0,0, + 1,255,255,255,2,0,0,0,1,255,255,255,6,0,0,0,1,255,255,255, + 2,0,0,0,1,255,255,255,6,0,0,0,1,255,255,255,2,0,0,0, + 1,255,255,255,6,0,0,0,4,255,255,255,6,0,0,0,1,255,255,255, + 2,0,0,0,1,255,255,255,6,0,0,0,1,255,255,255,2,0,0,0, + 1,255,255,255,6,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255, + 6,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,7,0,0,0, + 2,255,255,255,7,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255, + 103,0,0,16,8,0,0,208,191,0,0,144,8,0,0,0,0,0,0,144, + 8,56,224,128,5,72,32,1,192,72,32,1,0,56,32,145,8,72,32,1, + 0,72,32,209,191,72,32,17,8,56,224,144,8,0,0,32,8,0,0,208, + 191,0,0,0,8,0,0,0,0,0,0,144,8,0,0,128,5,0,0,0, + 192,0,0,0,0,0,0,144,8,0,0,0,0,72,32,17,8,72,32,145, + 8,72,32,145,8,72,32,209,191,72,224,1,8,72,32,1,0,72,32,129, + 5,48,32,1,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,16,116,115,116,114,105,110,103,99,111,110,116,97, + 105,110,101,114,1,99,12,115,116,114,105,110,103,115,46,100,97,116,97,1, + 6,34,68,111,32,121,111,117,32,119,105,115,104,32,116,111,32,100,101,108, + 101,116,101,32,97,108,108,32,119,97,116,99,104,101,115,63,6,12,67,111, + 110,102,105,114,109,97,116,105,111,110,6,10,60,100,105,115,97,98,108,101, + 100,62,0,4,108,101,102,116,2,96,3,116,111,112,2,80,0,0,0) + ); + +initialization + registerobjectdata(@objdata,twatchfo,''); +end. diff --git a/mseide-msegui/apps/ide/watchpointsform.mfm b/mseide-msegui/apps/ide/watchpointsform.mfm new file mode 100644 index 0000000..6d1036a --- /dev/null +++ b/mseide-msegui/apps/ide/watchpointsform.mfm @@ -0,0 +1,353 @@ +object watchpointsfo: twatchpointsfo + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_floatbutton, go_topbutton, go_backgroundbutton, go_nolockbutton, go_buttonhints] + visible = False + bounds_x = 120 + bounds_y = 368 + bounds_cx = 483 + bounds_cy = 210 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 473 + 210 + ) + dragdock.caption = 'Watchpoints' + dragdock.optionsdock = [od_savepos, od_canmove, od_canfloat, od_candock, od_propsize, od_captionhint] + options = [fo_savepos, fo_savestate] + statfile = mainfo.projectstatfile + caption = 'Watchpoints' + icon.transparentcolor = -2147483642 + icon.image = { + 0000000000000000180000001800000078070000000000000000000000000000 + 0000000000000000000000000000000000000000F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501 + E3E3E301E2E2E201E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01D6D6D6016868680137373701 + 16161601181818013939390165656501CACACA01DBDBDB01DADADA01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01EDEDED01EBEBEB019F9F9F010F0F0F01000000060D0D0D01 + 8B8B8B01DADADA01D8D8D801D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001 + F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01EDEDED01C5C5C5010A0A0A01 + 000000011B1B1C017D7D9E018181E0017F7FDD017C7C9D011C1C1D0100000001 + 04040401AAAAAA01D8D8D801D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001 + F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01EDEDED014141410100000001 + 06060C010606DD010000FF040606EA010A0A1601000000012A2A2A01D8D8D801 + D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001EEEEEE01E5E5E5010606070100000001000077010000FF0600008D01 + 0000000101010201CCCCCC01D7D7D701D5D5D501D3D3D301D2D2D201D0D0D001 + F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01C5C5CB010B0B460100002A01 + 0000C5010000FF060000B10100000002A8A8AE01D6D6D601D5D5D501D3D3D301 + D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE017373F601 + 0000FF0900007A0100000001000016013636B801C9C9C901D4D4D401D3D3D301 + D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001E9E9EE010707FE01 + 0000FF080000C70100000B010000000100005F010303FA0186868B01D2D2D201 + D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001C0C0F101 + 0000FF080000D1010000110100000001000031010000F1010000FF0151518201 + B0B0B001D2D2D202D0D0D001F5F5F501F3F3F301F2F2F201F0F0F0019090F501 + 0000FF070000CC010000120100000001000022010000E8010000FF023C3CA101 + 91919101D1D1D101D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001 + 9090F5010000FF060000E20100000F010000000100001C010000DC010000FF03 + 3B3BA0017A7A7A01D1D1D101D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001C0C0F1010000FF060000560100000001000018010000DB010000FF04 + 4E4E7F016A6A6A01D0D0D001D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201 + F0F0F001E9E9EE010707FE010000FF040000FC01000007010000000100009601 + 0000FF040303FA01606065017A7A7A01D1D1D101D2D2D201D0D0D001F5F5F501 + F3F3F301F2F2F201F0F0F001EEEEEE017272F5010000FF040000D80100000002 + 0000D5010000FF042F2FB2016363630191919101D1D1D101D2D2D201D0D0D001 + F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01E6E6EC012121F4010000FF03 + 0000BE01000008020000ED010000FF031111E4015F5F650164646401B0B0B001 + D2D2D202D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01EDEDED01 + C2C2EB011A1AED010000FF081111E40152527B016363630189898901D2D2D201 + D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01 + EDEDED01EAEAEA01D5D5DB013A3ABD010303FA010000FF040303FA013131B401 + 616167016464640170707001C9C9C901D4D4D401D3D3D301D2D2D201D0D0D001 + F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01EDEDED01EBEBEB01E9E9E901 + D9D9D9018F8F940134345201020205010202040139395B016363680165656502 + 8A8A8A01CACACA01D6D6D601D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501 + F3F3F301F2F2F201F0F0F001EEEEEE01EDEDED01EBEBEB01EAEAEA01E7E7E701 + E3E3E30170707001000000024D4D4D018080800196969601B5B5B501D7D7D703 + D5D5D501D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001 + EEEEEE01EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E6019E9E9E0138383801 + 37373701A9A9A901DCDCDC01DBDBDB01DADADA02D8D8D801D7D7D701D5D5D501 + D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01 + EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501E3E3E301E2E2E201 + E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801D7D7D701D5D5D501 + D3D3D301D2D2D201D0D0D001F5F5F501F3F3F301F2F2F201F0F0F001EEEEEE01 + EDEDED01EBEBEB01EAEAEA01E8E8E801E6E6E601E5E5E501E3E3E301E2E2E201 + E0E0E001DFDFDF01DDDDDD01DBDBDB01DADADA01D8D8D801D7D7D701D5D5D501 + D3D3D301D2D2D201D0D0D001 + } + onshow = watchpointsonshow + moduleclassname = 'tdockform' + object grid: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + frame.localprops = [] + frame.localprops1 = [] + popupmenu = gripopup + bounds_x = 0 + bounds_y = 0 + bounds_cx = 473 + bounds_cy = 210 + anchors = [an_top, an_bottom] + optionsgrid = [og_colsizing, og_rowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixcols.count = 1 + fixcols.items = < + item + width = 20 + numstart = 1 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 7 + captions.items = < + item + caption = 'on' + end + item + caption = 'Kind' + end + item + caption = 'Expression' + end + item + end + item + caption = 'Count' + end + item + caption = 'Ignore' + end + item + caption = 'Condition' + end> + end> + datacols.count = 7 + datacols.items = < + item[wpton] + width = 16 + options = [co_drawfocus, co_fixwidth, co_savestate] + widgetname = 'wpton' + dataclass = tgridintegerdatalist + end + item[wptkind] + width = 33 + options = [co_savevalue, co_savestate] + widgetname = 'wptkind' + dataclass = tgridenumdatalist + end + item[wptexpression] + width = 149 + options = [co_proportional, co_savevalue, co_savestate] + widgetname = 'wptexpression' + dataclass = tgridmsestringdatalist + end + item[wptno] + width = 9 + options = [co_invisible] + widgetname = 'wptno' + dataclass = tgridintegerdatalist + end + item[wptcount] + color = -1879048185 + width = 34 + options = [co_readonly, co_nofocus, co_savestate] + widgetname = 'wptcount' + dataclass = tgridintegerdatalist + end + item[wptignore] + width = 38 + options = [co_savevalue, co_savestate] + widgetname = 'wptignore' + dataclass = tgridintegerdatalist + end + item[wptcondition] + width = 162 + options = [co_fill, co_savevalue, co_savestate] + widgetname = 'wptcondition' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + statfile = mainfo.projectstatfile + onrowsdeleting = deleterow + reffontheight = 14 + object wpton: tbooleanedit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 16 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + onsetvalue = wptononsetvalue + end + object wptkind: tenumedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.button.color = -2147483646 + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + end> + taborder = 2 + visible = False + bounds_x = 17 + bounds_y = 0 + bounds_cx = 33 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + textflags = [tf_xcentered, tf_ycentered, tf_noselect] + ondataentered = wptondataentered + dropdown.cols.count = 1 + dropdown.cols.items = < + item + data = ( + 'W' + 'R/W' + 'R' + ) + end> + value = 0 + valuedefault = 0 + valuemin = 0 + valuemax = 2 + reffontheight = 14 + end + object wptexpression: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 3 + visible = False + bounds_x = 51 + bounds_y = 0 + bounds_cx = 149 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + ondataentered = wptondataentered + reffontheight = 14 + end + object wptno: tintegeredit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 4 + visible = False + bounds_x = 201 + bounds_y = 0 + bounds_cx = 9 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + object wptcount: tintegeredit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 5 + visible = False + bounds_x = 211 + bounds_y = 0 + bounds_cx = 34 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + object wptignore: tintegeredit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 6 + visible = False + bounds_x = 246 + bounds_y = 0 + bounds_cx = 38 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_forcereturncheckvalue, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + ondataentered = wptondataentered + reffontheight = 14 + end + object wptcondition: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 7 + visible = False + bounds_x = 285 + bounds_y = 0 + bounds_cx = 162 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + ondataentered = wptondataentered + reffontheight = 14 + end + end + object gripopup: tpopupmenu + menu.submenu.count = 1 + menu.submenu.items = < + item + caption = 'Delete all' + state = [as_localcaption, as_localonexecute] + onexecute = deleteallonexecute + end> + menu.name = 'gridpopup' + left = 112 + top = 88 + end + object c: tstringcontainer + strings.data = ( + 'Watchpoint error.' + 'WATCHPOINT ERROR' + 'Program not loaded.' + 'Do you wish to delete all watchpoints?' + 'Confirmation' + ) + left = 216 + top = 88 + end +end diff --git a/mseide-msegui/apps/ide/watchpointsform.pas b/mseide-msegui/apps/ide/watchpointsform.pas new file mode 100644 index 0000000..4adcc91 --- /dev/null +++ b/mseide-msegui/apps/ide/watchpointsform.pas @@ -0,0 +1,210 @@ +{ MSEide Copyright (c) 1999-2014 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit watchpointsform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msetypes,msegui,mseclasses,mseforms,msedataedits,msegraphedits,msewidgetgrid, + msestat, + msegdbutils,msesimplewidgets,msemenus,msestrings,msegrids,msestringcontainer; + +type + twatchpointsfo = class(tdockform) + gripopup: tpopupmenu; + wptkind: tenumedit; + wptno: tintegeredit; + wptcondition: tstringedit; + wptignore: tintegeredit; + wptcount: tintegeredit; + wptexpression: tstringedit; + wpton: tbooleanedit; + grid: twidgetgrid; + c: tstringcontainer; + procedure wptondataentered(const sender: TObject); + procedure wptononsetvalue(const sender: TObject; var avalue: Boolean; + var accept: Boolean); + procedure watchpointsonshow(const sender: TObject); + procedure deleteallonexecute(const sender: TObject); + procedure deleterow(const sender: tcustomgrid; var aindex: Integer; + var acount: Integer); + private + procedure changed; + function watchpointerror(const error: gdbresultty): boolean; + public + gdb: tgdbmi; + procedure refresh(const breakpoints: breakpointinfoarty); + procedure clear(const all: boolean = false); + procedure addwatch(const expression: msestring); + end; + +var + watchpointsfo: twatchpointsfo; + +implementation + +uses + watchpointsform_mfm,projectoptionsform,msewidgets,breakpointsform; +type + stringconstants = ( + watcherror, //0 Watchpoint error. + watcherror2, //1 WATCHPOINT ERROR + programnotloaded, //2 Program not loaded. + deleteall, //3 Do you wish to delete all watchpoints? + confirmation //4 Confirmation + ); + +{ twatchpointsfo } + +procedure twatchpointsfo.refresh(const breakpoints: breakpointinfoarty); +var + int1,int2: integer; +begin + for int1:= 0 to grid.rowhigh do begin + wptcount[int1]:= 0; + for int2:= 0 to high(breakpoints) do begin + with breakpoints[int2] do begin + if bkptno = wptno[int1] then begin + wptcount[int1]:= passcount; + end; + end; + end; + end; +end; + +procedure twatchpointsfo.clear(const all: boolean); +begin + if all then begin + grid.clear; + end + else begin + wpton.fillcol(false); + end; +end; + +procedure twatchpointsfo.changed; +begin + with projectoptions do begin + modified:= true; +// watchpointexpressions:= wptexpression.gridvalues; +// watchpointignore:= wptignore.gridvalues; +// watchpointconditions:= wptcondition.gridvalues; +// watchpointkinds:= wptkind.gridvalues; + end; +end; + +function twatchpointsfo.watchpointerror(const error: gdbresultty): boolean; +var + str1: msestring; +begin + result:= error <> gdb_ok; + if result then begin + if error in [gdb_message,gdb_timeout] then begin + str1:= msestring(gdb.errormessage); + end + else begin + str1:= c[ord(watcherror)]; + end; + showmessage(str1,c[ord(watcherror2)]); + end; +end; + +procedure twatchpointsfo.wptondataentered(const sender: TObject); +begin + changed; + wpton.value:= false; + if gdb.started then begin + wpton.checkvalue; + end; +end; + +procedure twatchpointsfo.watchpointsonshow(const sender: TObject); +begin + breakpointsfo.refresh; +end; + +procedure twatchpointsfo.wptononsetvalue(const sender: TObject; + var avalue: Boolean; var accept: Boolean); +var + info: watchpointinfoty; +begin + if gdb.started then begin + if avalue then begin + with info do begin + kind:= watchpointkindty(wptkind.value); + expression:= ansistring(wptexpression.value); + ignore:= wptignore.value; + condition:= ansistring(wptcondition.value); + end; + if watchpointerror(gdb.watchinsert(info)) then begin + avalue:= false; + wptno.value:= 0; + end + else begin + wptno.value:= info.wptno; + end; + end + else begin + if wptno.value <> 0 then begin + gdb.breakdelete(wptno.value); + wptno.value:= 0; + end; + end; + end + else begin + showerror(c[ord(programnotloaded)]); + end; +end; + +procedure twatchpointsfo.deleteallonexecute(const sender: TObject); +var + int1,int2: integer; +begin + if askok(c[ord(deleteall)],c[ord(confirmation)]) then begin + int1:= 0; + int2:= grid.rowcount; + deleterow(nil,int1,int2); + grid.clear; + end; +end; + +procedure twatchpointsfo.addwatch(const expression: msestring); +begin + grid.show; + grid.setfocus(false); + if not grid.datacols.rowempty(grid.row) then begin + grid.row:= grid.appendrow; + end; + wptexpression.value:= expression; + wpton.value:= true; + wpton.checkvalue; +end; + +procedure twatchpointsfo.deleterow(const sender: tcustomgrid; + var aindex: Integer; var acount: Integer); +var + int1: integer; +begin + for int1:= aindex to aindex + acount - 1 do begin + if wptno[int1] <> 0 then begin + gdb.breakdelete(wptno[int1]); + end; + end; +end; + +end. diff --git a/mseide-msegui/apps/ide/watchpointsform_mfm.pas b/mseide-msegui/apps/ide/watchpointsform_mfm.pas new file mode 100644 index 0000000..e424ee4 --- /dev/null +++ b/mseide-msegui/apps/ide/watchpointsform_mfm.pas @@ -0,0 +1,440 @@ +unit watchpointsform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,watchpointsform; + +const + objdata: record size: integer; data: array[0..8448] of byte end = + (size: 8449; data: ( + 84,80,70,48,14,116,119,97,116,99,104,112,111,105,110,116,115,102,111,13, + 119,97,116,99,104,112,111,105,110,116,115,102,111,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,15,102,114,97,109,101,46,103, + 114,105,112,95,115,105,122,101,2,10,18,102,114,97,109,101,46,103,114,105, + 112,95,111,112,116,105,111,110,115,11,14,103,111,95,99,108,111,115,101,98, + 117,116,116,111,110,16,103,111,95,102,105,120,115,105,122,101,98,117,116,116, + 111,110,14,103,111,95,102,108,111,97,116,98,117,116,116,111,110,12,103,111, + 95,116,111,112,98,117,116,116,111,110,19,103,111,95,98,97,99,107,103,114, + 111,117,110,100,98,117,116,116,111,110,15,103,111,95,110,111,108,111,99,107, + 98,117,116,116,111,110,14,103,111,95,98,117,116,116,111,110,104,105,110,116, + 115,0,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120, + 2,120,8,98,111,117,110,100,115,95,121,3,112,1,9,98,111,117,110,100, + 115,95,99,120,3,227,1,9,98,111,117,110,100,115,95,99,121,3,210,0, + 26,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,0,27,99,111,110,116,97,105,110,101,114,46, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16, + 99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2,0,2, + 0,3,217,1,3,210,0,0,16,100,114,97,103,100,111,99,107,46,99,97, + 112,116,105,111,110,6,11,87,97,116,99,104,112,111,105,110,116,115,20,100, + 114,97,103,100,111,99,107,46,111,112,116,105,111,110,115,100,111,99,107,11, + 10,111,100,95,115,97,118,101,112,111,115,10,111,100,95,99,97,110,109,111, + 118,101,11,111,100,95,99,97,110,102,108,111,97,116,10,111,100,95,99,97, + 110,100,111,99,107,11,111,100,95,112,114,111,112,115,105,122,101,14,111,100, + 95,99,97,112,116,105,111,110,104,105,110,116,0,7,111,112,116,105,111,110, + 115,11,10,102,111,95,115,97,118,101,112,111,115,12,102,111,95,115,97,118, + 101,115,116,97,116,101,0,8,115,116,97,116,102,105,108,101,7,22,109,97, + 105,110,102,111,46,112,114,111,106,101,99,116,115,116,97,116,102,105,108,101, + 7,99,97,112,116,105,111,110,6,11,87,97,116,99,104,112,111,105,110,116, + 115,21,105,99,111,110,46,116,114,97,110,115,112,97,114,101,110,116,99,111, + 108,111,114,4,6,0,0,128,10,105,99,111,110,46,105,109,97,103,101,10, + 172,7,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0,0,0, + 120,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,245,245,245,1, + 243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1, + 235,235,235,1,234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1, + 227,227,227,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1, + 219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1, + 211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1, + 242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1,235,235,235,1, + 234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1,227,227,227,1, + 226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219,219,1, + 218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1, + 210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1, + 240,240,240,1,238,238,238,1,237,237,237,1,235,235,235,1,234,234,234,1, + 214,214,214,1,104,104,104,1,55,55,55,1,22,22,22,1,24,24,24,1, + 57,57,57,1,101,101,101,1,202,202,202,1,219,219,219,1,218,218,218,1, + 216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1,210,210,210,1, + 208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1, + 238,238,238,1,237,237,237,1,235,235,235,1,159,159,159,1,15,15,15,1, + 0,0,0,6,13,13,13,1,139,139,139,1,218,218,218,1,216,216,216,1, + 215,215,215,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1, + 245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1, + 237,237,237,1,197,197,197,1,10,10,10,1,0,0,0,1,27,27,28,1, + 125,125,158,1,129,129,224,1,127,127,221,1,124,124,157,1,28,28,29,1, + 0,0,0,1,4,4,4,1,170,170,170,1,216,216,216,1,215,215,215,1, + 213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1, + 243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1, + 65,65,65,1,0,0,0,1,6,6,12,1,6,6,221,1,0,0,255,4, + 6,6,234,1,10,10,22,1,0,0,0,1,42,42,42,1,216,216,216,1, + 215,215,215,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1, + 245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1, + 229,229,229,1,6,6,7,1,0,0,0,1,0,0,119,1,0,0,255,6, + 0,0,141,1,0,0,0,1,1,1,2,1,204,204,204,1,215,215,215,1, + 213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1, + 243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1,197,197,203,1, + 11,11,70,1,0,0,42,1,0,0,197,1,0,0,255,6,0,0,177,1, + 0,0,0,2,168,168,174,1,214,214,214,1,213,213,213,1,211,211,211,1, + 210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1, + 240,240,240,1,238,238,238,1,115,115,246,1,0,0,255,9,0,0,122,1, + 0,0,0,1,0,0,22,1,54,54,184,1,201,201,201,1,212,212,212,1, + 211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1, + 242,242,242,1,240,240,240,1,233,233,238,1,7,7,254,1,0,0,255,8, + 0,0,199,1,0,0,11,1,0,0,0,1,0,0,95,1,3,3,250,1, + 134,134,139,1,210,210,210,1,211,211,211,1,210,210,210,1,208,208,208,1, + 245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1,192,192,241,1, + 0,0,255,8,0,0,209,1,0,0,17,1,0,0,0,1,0,0,49,1, + 0,0,241,1,0,0,255,1,81,81,130,1,176,176,176,1,210,210,210,2, + 208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1, + 144,144,245,1,0,0,255,7,0,0,204,1,0,0,18,1,0,0,0,1, + 0,0,34,1,0,0,232,1,0,0,255,2,60,60,161,1,145,145,145,1, + 209,209,209,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1, + 242,242,242,1,240,240,240,1,144,144,245,1,0,0,255,6,0,0,226,1, + 0,0,15,1,0,0,0,1,0,0,28,1,0,0,220,1,0,0,255,3, + 59,59,160,1,122,122,122,1,209,209,209,1,210,210,210,1,208,208,208,1, + 245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1,192,192,241,1, + 0,0,255,6,0,0,86,1,0,0,0,1,0,0,24,1,0,0,219,1, + 0,0,255,4,78,78,127,1,106,106,106,1,208,208,208,1,210,210,210,1, + 208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1, + 233,233,238,1,7,7,254,1,0,0,255,4,0,0,252,1,0,0,7,1, + 0,0,0,1,0,0,150,1,0,0,255,4,3,3,250,1,96,96,101,1, + 122,122,122,1,209,209,209,1,210,210,210,1,208,208,208,1,245,245,245,1, + 243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1,114,114,245,1, + 0,0,255,4,0,0,216,1,0,0,0,2,0,0,213,1,0,0,255,4, + 47,47,178,1,99,99,99,1,145,145,145,1,209,209,209,1,210,210,210,1, + 208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1, + 238,238,238,1,230,230,236,1,33,33,244,1,0,0,255,3,0,0,190,1, + 0,0,8,2,0,0,237,1,0,0,255,3,17,17,228,1,95,95,101,1, + 100,100,100,1,176,176,176,1,210,210,210,2,208,208,208,1,245,245,245,1, + 243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1, + 194,194,235,1,26,26,237,1,0,0,255,8,17,17,228,1,82,82,123,1, + 99,99,99,1,137,137,137,1,210,210,210,1,211,211,211,1,210,210,210,1, + 208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1, + 238,238,238,1,237,237,237,1,234,234,234,1,213,213,219,1,58,58,189,1, + 3,3,250,1,0,0,255,4,3,3,250,1,49,49,180,1,97,97,103,1, + 100,100,100,1,112,112,112,1,201,201,201,1,212,212,212,1,211,211,211,1, + 210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1, + 240,240,240,1,238,238,238,1,237,237,237,1,235,235,235,1,233,233,233,1, + 217,217,217,1,143,143,148,1,52,52,82,1,2,2,5,1,2,2,4,1, + 57,57,91,1,99,99,104,1,101,101,101,2,138,138,138,1,202,202,202,1, + 214,214,214,1,213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1, + 245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1, + 237,237,237,1,235,235,235,1,234,234,234,1,231,231,231,1,227,227,227,1, + 112,112,112,1,0,0,0,2,77,77,77,1,128,128,128,1,150,150,150,1, + 181,181,181,1,215,215,215,3,213,213,213,1,211,211,211,1,210,210,210,1, + 208,208,208,1,245,245,245,1,243,243,243,1,242,242,242,1,240,240,240,1, + 238,238,238,1,237,237,237,1,235,235,235,1,234,234,234,1,232,232,232,1, + 230,230,230,1,158,158,158,1,56,56,56,1,55,55,55,1,169,169,169,1, + 220,220,220,1,219,219,219,1,218,218,218,2,216,216,216,1,215,215,215,1, + 213,213,213,1,211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1, + 243,243,243,1,242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1, + 235,235,235,1,234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1, + 227,227,227,1,226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1, + 219,219,219,1,218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1, + 211,211,211,1,210,210,210,1,208,208,208,1,245,245,245,1,243,243,243,1, + 242,242,242,1,240,240,240,1,238,238,238,1,237,237,237,1,235,235,235,1, + 234,234,234,1,232,232,232,1,230,230,230,1,229,229,229,1,227,227,227,1, + 226,226,226,1,224,224,224,1,223,223,223,1,221,221,221,1,219,219,219,1, + 218,218,218,1,216,216,216,1,215,215,215,1,213,213,213,1,211,211,211,1, + 210,210,210,1,208,208,208,1,6,111,110,115,104,111,119,7,17,119,97,116, + 99,104,112,111,105,110,116,115,111,110,115,104,111,119,15,109,111,100,117,108, + 101,99,108,97,115,115,110,97,109,101,6,9,116,100,111,99,107,102,111,114, + 109,0,11,116,119,105,100,103,101,116,103,114,105,100,4,103,114,105,100,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111, + 117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114, + 114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102, + 111,99,117,115,111,117,116,17,111,119,95,102,111,99,117,115,98,97,99,107, + 111,110,101,115,99,13,111,119,95,109,111,117,115,101,119,104,101,101,108,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,9,112,111, + 112,117,112,109,101,110,117,7,8,103,114,105,112,111,112,117,112,8,98,111, + 117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,120,3,217,1,9,98,111,117,110,100,115,95, + 99,121,3,210,0,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111, + 112,9,97,110,95,98,111,116,116,111,109,0,11,111,112,116,105,111,110,115, + 103,114,105,100,11,12,111,103,95,99,111,108,115,105,122,105,110,103,12,111, + 103,95,114,111,119,109,111,118,105,110,103,15,111,103,95,114,111,119,105,110, + 115,101,114,116,105,110,103,14,111,103,95,114,111,119,100,101,108,101,116,105, + 110,103,19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116, + 101,114,15,111,103,95,97,117,116,111,102,105,114,115,116,114,111,119,13,111, + 103,95,97,117,116,111,97,112,112,101,110,100,20,111,103,95,99,111,108,99, + 104,97,110,103,101,111,110,116,97,98,107,101,121,10,111,103,95,119,114,97, + 112,99,111,108,12,111,103,95,97,117,116,111,112,111,112,117,112,17,111,103, + 95,109,111,117,115,101,115,99,114,111,108,108,99,111,108,0,13,102,105,120, + 99,111,108,115,46,99,111,117,110,116,2,1,13,102,105,120,99,111,108,115, + 46,105,116,101,109,115,14,1,5,119,105,100,116,104,2,20,8,110,117,109, + 115,116,97,114,116,2,1,7,110,117,109,115,116,101,112,2,1,0,0,13, + 102,105,120,114,111,119,115,46,99,111,117,110,116,2,1,13,102,105,120,114, + 111,119,115,46,105,116,101,109,115,14,1,6,104,101,105,103,104,116,2,16, + 14,99,97,112,116,105,111,110,115,46,99,111,117,110,116,2,7,14,99,97, + 112,116,105,111,110,115,46,105,116,101,109,115,14,1,7,99,97,112,116,105, + 111,110,6,2,111,110,0,1,7,99,97,112,116,105,111,110,6,4,75,105, + 110,100,0,1,7,99,97,112,116,105,111,110,6,10,69,120,112,114,101,115, + 115,105,111,110,0,1,0,1,7,99,97,112,116,105,111,110,6,5,67,111, + 117,110,116,0,1,7,99,97,112,116,105,111,110,6,6,73,103,110,111,114, + 101,0,1,7,99,97,112,116,105,111,110,6,9,67,111,110,100,105,116,105, + 111,110,0,0,0,0,14,100,97,116,97,99,111,108,115,46,99,111,117,110, + 116,2,7,14,100,97,116,97,99,111,108,115,46,105,116,101,109,115,14,7, + 5,119,112,116,111,110,1,5,119,105,100,116,104,2,16,7,111,112,116,105, + 111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117,115,11,99,111, + 95,102,105,120,119,105,100,116,104,12,99,111,95,115,97,118,101,115,116,97, + 116,101,0,10,119,105,100,103,101,116,110,97,109,101,6,5,119,112,116,111, + 110,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100,105,110, + 116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,7,119,112,116,107, + 105,110,100,1,5,119,105,100,116,104,2,33,7,111,112,116,105,111,110,115, + 11,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111,95,115,97, + 118,101,115,116,97,116,101,0,10,119,105,100,103,101,116,110,97,109,101,6, + 7,119,112,116,107,105,110,100,9,100,97,116,97,99,108,97,115,115,7,17, + 116,103,114,105,100,101,110,117,109,100,97,116,97,108,105,115,116,0,7,13, + 119,112,116,101,120,112,114,101,115,115,105,111,110,1,5,119,105,100,116,104, + 3,149,0,7,111,112,116,105,111,110,115,11,15,99,111,95,112,114,111,112, + 111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,118,97,108,117, + 101,12,99,111,95,115,97,118,101,115,116,97,116,101,0,10,119,105,100,103, + 101,116,110,97,109,101,6,13,119,112,116,101,120,112,114,101,115,115,105,111, + 110,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115, + 101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,5,119,112, + 116,110,111,1,5,119,105,100,116,104,2,9,7,111,112,116,105,111,110,115, + 11,12,99,111,95,105,110,118,105,115,105,98,108,101,0,10,119,105,100,103, + 101,116,110,97,109,101,6,5,119,112,116,110,111,9,100,97,116,97,99,108, + 97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116, + 97,108,105,115,116,0,7,8,119,112,116,99,111,117,110,116,1,5,99,111, + 108,111,114,4,7,0,0,144,5,119,105,100,116,104,2,34,7,111,112,116, + 105,111,110,115,11,11,99,111,95,114,101,97,100,111,110,108,121,10,99,111, + 95,110,111,102,111,99,117,115,12,99,111,95,115,97,118,101,115,116,97,116, + 101,0,10,119,105,100,103,101,116,110,97,109,101,6,8,119,112,116,99,111, + 117,110,116,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100, + 105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,9,119,112, + 116,105,103,110,111,114,101,1,5,119,105,100,116,104,2,38,7,111,112,116, + 105,111,110,115,11,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99, + 111,95,115,97,118,101,115,116,97,116,101,0,10,119,105,100,103,101,116,110, + 97,109,101,6,9,119,112,116,105,103,110,111,114,101,9,100,97,116,97,99, + 108,97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97, + 116,97,108,105,115,116,0,7,12,119,112,116,99,111,110,100,105,116,105,111, + 110,1,5,119,105,100,116,104,3,162,0,7,111,112,116,105,111,110,115,11, + 7,99,111,95,102,105,108,108,12,99,111,95,115,97,118,101,118,97,108,117, + 101,12,99,111,95,115,97,118,101,115,116,97,116,101,0,10,119,105,100,103, + 101,116,110,97,109,101,6,12,119,112,116,99,111,110,100,105,116,105,111,110, + 9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101, + 115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,0,13,100,97,116, + 97,114,111,119,104,101,105,103,104,116,2,16,8,115,116,97,116,102,105,108, + 101,7,22,109,97,105,110,102,111,46,112,114,111,106,101,99,116,115,116,97, + 116,102,105,108,101,14,111,110,114,111,119,115,100,101,108,101,116,105,110,103, + 7,9,100,101,108,101,116,101,114,111,119,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,12,116,98,111,111,108,101,97,110,101,100,105, + 116,5,119,112,116,111,110,11,111,112,116,105,111,110,115,115,107,105,110,11, + 19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121, + 0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97, + 109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117, + 110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,120,2,16,9,98,111,117,110,100,115,95,99,121, + 2,16,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117, + 110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101, + 114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12, + 111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101, + 116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105, + 116,111,110,99,117,114,115,111,114,13,111,101,95,97,117,116,111,115,101,108, + 101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102, + 105,114,115,116,99,108,105,99,107,0,12,111,112,116,105,111,110,115,101,100, + 105,116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101, + 110,117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101, + 49,95,115,97,118,101,115,116,97,116,101,0,7,118,105,115,105,98,108,101, + 8,10,111,110,115,101,116,118,97,108,117,101,7,15,119,112,116,111,110,111, + 110,115,101,116,118,97,108,117,101,0,0,9,116,101,110,117,109,101,100,105, + 116,7,119,112,116,107,105,110,100,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111, + 119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102, + 111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110, + 16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119, + 95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,11,111,112,116, + 105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98, + 117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114, + 108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,18,102,114,97,109,101, + 46,98,117,116,116,111,110,46,99,111,108,111,114,4,2,0,0,128,19,102, + 114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1, + 19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115, + 14,1,5,99,111,108,111,114,4,2,0,0,128,0,0,8,116,97,98,111, + 114,100,101,114,2,2,7,118,105,115,105,98,108,101,8,8,98,111,117,110, + 100,115,95,120,2,17,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,120,2,33,9,98,111,117,110,100,115,95,99,121,2, + 16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,13,111,101,49,95, + 115,97,118,101,118,97,108,117,101,0,9,116,101,120,116,102,108,97,103,115, + 11,12,116,102,95,120,99,101,110,116,101,114,101,100,12,116,102,95,121,99, + 101,110,116,101,114,101,100,11,116,102,95,110,111,115,101,108,101,99,116,0, + 13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,16,119,112,116,111, + 110,100,97,116,97,101,110,116,101,114,101,100,19,100,114,111,112,100,111,119, + 110,46,99,111,108,115,46,99,111,117,110,116,2,1,19,100,114,111,112,100, + 111,119,110,46,99,111,108,115,46,105,116,101,109,115,14,1,4,100,97,116, + 97,1,6,1,87,6,3,82,47,87,6,1,82,0,0,0,5,118,97,108, + 117,101,2,0,12,118,97,108,117,101,100,101,102,97,117,108,116,2,0,8, + 118,97,108,117,101,109,105,110,2,0,8,118,97,108,117,101,109,97,120,2, + 2,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,11, + 116,115,116,114,105,110,103,101,100,105,116,13,119,112,116,101,120,112,114,101, + 115,115,105,111,110,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49, + 11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104, + 116,0,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119, + 95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111, + 99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119, + 95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114, + 111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111, + 121,119,105,100,103,101,116,115,0,11,111,112,116,105,111,110,115,115,107,105, + 110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110, + 108,121,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102, + 114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,3,0,0, + 128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,3,7,118, + 105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,51,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3, + 149,0,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111, + 110,115,101,100,105,116,49,11,13,111,101,49,95,115,97,118,101,118,97,108, + 117,101,0,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,16,119, + 112,116,111,110,100,97,116,97,101,110,116,101,114,101,100,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,12,116,105,110,116,101,103, + 101,114,101,100,105,116,5,119,112,116,110,111,14,111,112,116,105,111,110,115, + 119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121, + 112,104,104,101,105,103,104,116,0,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111, + 119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102, + 111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110, + 16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119, + 95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,11,111,112,116, + 105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98, + 117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114, + 108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114, + 100,101,114,2,4,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100, + 115,95,120,3,201,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,120,2,9,9,98,111,117,110,100,115,95,99,121,2, + 16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,0,11,111,112,116, + 105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101, + 115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95, + 99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101,97,116, + 114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99, + 116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114, + 115,111,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101, + 95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108, + 105,99,107,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,8,119,112,116,99, + 111,117,110,116,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11, + 19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116, + 0,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95, + 97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111, + 119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121, + 119,105,100,103,101,116,115,0,11,111,112,116,105,111,110,115,115,107,105,110, + 11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108, + 121,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,5,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,211,0,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2, + 34,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110, + 115,101,100,105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105,116, + 11,11,111,101,95,114,101,97,100,111,110,108,121,12,111,101,95,117,110,100, + 111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121, + 16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101, + 95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115, + 101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111, + 110,99,117,114,115,111,114,13,111,101,95,97,117,116,111,115,101,108,101,99, + 116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114, + 115,116,99,108,105,99,107,0,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,14,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,9, + 119,112,116,105,103,110,111,114,101,14,111,112,116,105,111,110,115,119,105,100, + 103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104, + 101,105,103,104,116,0,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119, + 95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,0,11,111,112,116,105,111,110, + 115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116, + 111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101,118,101,108,111, + 2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116, + 4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99, + 111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114, + 2,6,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120, + 3,246,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100, + 115,95,99,120,2,38,9,98,111,117,110,100,115,95,99,121,2,16,12,111, + 112,116,105,111,110,115,101,100,105,116,49,11,13,111,101,49,95,115,97,118, + 101,118,97,108,117,101,0,11,111,112,116,105,111,110,115,101,100,105,116,11, + 12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111, + 115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97, + 110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,24, + 111,101,95,102,111,114,99,101,114,101,116,117,114,110,99,104,101,99,107,118, + 97,108,117,101,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101, + 95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111, + 101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110, + 100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101, + 99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105, + 114,115,116,99,108,105,99,107,0,13,111,110,100,97,116,97,101,110,116,101, + 114,101,100,7,16,119,112,116,111,110,100,97,116,97,101,110,116,101,114,101, + 100,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,11, + 116,115,116,114,105,110,103,101,100,105,116,12,119,112,116,99,111,110,100,105, + 116,105,111,110,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11, + 19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116, + 0,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95, + 97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111, + 119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121, + 119,105,100,103,101,116,115,0,11,111,112,116,105,111,110,115,115,107,105,110, + 11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108, + 121,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114, + 97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102, + 114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,7,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,29,1,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3, + 162,0,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111, + 110,115,101,100,105,116,49,11,13,111,101,49,95,115,97,118,101,118,97,108, + 117,101,0,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,16,119, + 112,116,111,110,100,97,116,97,101,110,116,101,114,101,100,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,0,10,116,112,111,112,117, + 112,109,101,110,117,8,103,114,105,112,111,112,117,112,18,109,101,110,117,46, + 115,117,98,109,101,110,117,46,99,111,117,110,116,2,1,18,109,101,110,117, + 46,115,117,98,109,101,110,117,46,105,116,101,109,115,14,1,7,99,97,112, + 116,105,111,110,6,10,68,101,108,101,116,101,32,97,108,108,5,115,116,97, + 116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17, + 97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111, + 110,101,120,101,99,117,116,101,7,18,100,101,108,101,116,101,97,108,108,111, + 110,101,120,101,99,117,116,101,0,0,9,109,101,110,117,46,110,97,109,101, + 6,9,103,114,105,100,112,111,112,117,112,4,108,101,102,116,2,112,3,116, + 111,112,2,88,0,0,16,116,115,116,114,105,110,103,99,111,110,116,97,105, + 110,101,114,1,99,12,115,116,114,105,110,103,115,46,100,97,116,97,1,6, + 17,87,97,116,99,104,112,111,105,110,116,32,101,114,114,111,114,46,6,16, + 87,65,84,67,72,80,79,73,78,84,32,69,82,82,79,82,6,19,80,114, + 111,103,114,97,109,32,110,111,116,32,108,111,97,100,101,100,46,6,38,68, + 111,32,121,111,117,32,119,105,115,104,32,116,111,32,100,101,108,101,116,101, + 32,97,108,108,32,119,97,116,99,104,112,111,105,110,116,115,63,6,12,67, + 111,110,102,105,114,109,97,116,105,111,110,0,4,108,101,102,116,3,216,0, + 3,116,111,112,2,88,0,0,0) + ); + +initialization + registerobjectdata(@objdata,twatchpointsfo,''); +end. diff --git a/mseide-msegui/apps/myide/mybutton.pas b/mseide-msegui/apps/myide/mybutton.pas new file mode 100644 index 0000000..261fa71 --- /dev/null +++ b/mseide-msegui/apps/myide/mybutton.pas @@ -0,0 +1,80 @@ +unit mybutton; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msesimplewidgets,mseevent,msegraphics,classes,mclasses,msegraphutils,mseact, + mseguiglob; + +const + defaultcolorclicked = cl_red; + +type + tmybutton = class(tbutton) + private + fcolorclicked: colorty; + procedure setcolorclicked(const avalue: colorty); + protected + procedure checkcolor; + procedure clientmouseevent(var info: mouseeventinfoty); override; + procedure dokeydown(var info: keyeventinfoty); override; + procedure dokeyup(var info: keyeventinfoty); override; + public + constructor create(aowner: tcomponent); override; + published + property colorclicked: colorty read fcolorclicked + write setcolorclicked default defaultcolorclicked; + end; + +implementation +uses + mseshapes; + +{ tmybutton } + +constructor tmybutton.create(aowner: tcomponent); +begin + fcolorclicked:= defaultcolorclicked; + inherited; +end; + +procedure tmybutton.checkcolor; +begin + with finfo do begin + if shs_clicked in state then begin + color:= fcolorclicked; + end + else begin + color:= self.color; + end; + end; +end; + +procedure tmybutton.clientmouseevent(var info: mouseeventinfoty); +begin + inherited; + checkcolor; +end; + +procedure tmybutton.dokeydown(var info: keyeventinfoty); +begin + inherited; + checkcolor; +end; + +procedure tmybutton.dokeyup(var info: keyeventinfoty); +begin + inherited; + checkcolor; +end; + +procedure tmybutton.setcolorclicked(const avalue: colorty); +begin + if fcolorclicked <> avalue then begin + fcolorclicked:= avalue; + checkcolor; + invalidate; + end; +end; + +end. diff --git a/mseide-msegui/apps/myide/mymseide.prj b/mseide-msegui/apps/myide/mymseide.prj new file mode 100644 index 0000000..a2a7780 --- /dev/null +++ b/mseide-msegui/apps/myide/mymseide.prj @@ -0,0 +1,1010 @@ +[componentpalette] +order0=0 +order1=0 +order2=0 +order3=0 +order4=0 +order5=0 +order6=0 +order7=0 +order8=0 +order9=0 +order10=0 +order11=0 +order12=0 +order13=0 +order14=0 +order15=0 +order16=0 +order17=0 +order18=0 +[projectoptions] +projectdir=/home/mse/packs/standard/git/mseide-msegui/apps/myide +projectfilename=/home/mse/packs/standard/git/mseide-msegui/apps/myide/mymseide.prj +mainfile=../ide/mseide.pas +targetfile=mymseide${EXEEXT} +messageoutputfile= +makecommand=${COMPILER} +makedir= +unitdirs=5 + ${MSEDIR}lib/addon/*/ + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}kernel/ + ${MSELIBDIR}*/ + ../ide/ +unitpref=-Fu +incpref=-Fi +libpref=-Fl +objpref=-Fo +targpref=-o +befcommand=0 +aftcommand=0 +makeoptions=4 + -Xg -l -Mobjfpc -Sh -Fcutf8 -FE../myide -FU. -dmorecomponents + -gl -O- + -B + -O2 -XX -Xs -CX +codetemplatedirs=1 + ${TEMPLATEDIR} +toolmenus=0 +toolfiles=0 +toolparams=0 +fontnames=0 +scriptbeforecopy= +scriptaftercopy= +newprojectfiles=4 + ${TEMPLATEDIR}default/project.pas + ${TEMPLATEDIR}default/main.pas + ${TEMPLATEDIR}default/main.mfm + ${TEMPLATEDIR}default/main_mfm.pas +newprojectfilesdest=4 + ${%PROJECTNAME%}.pas + + + +newfinames=3 + Program + Unit + Textfile +newfifilters=3 + "*.pas" "*.pp" + "*.pas" "*.pp" + +newfiexts=3 + pas + pas + +newfisources=3 + ${TEMPLATEDIR}default/program.pas + ${TEMPLATEDIR}default/unit.pas + +newfonames=11 + Mainform + Simple Form + Docking Form + Datamodule + Subform + Scrollboxform + Tabform + Dockpanel + Report + Scriptform + Inherited Form +newfonamebases=11 + form + form + form + module + form + form + form + form + report + script + form +newfosources=11 + ${TEMPLATEDIR}default/mainform.pas + ${TEMPLATEDIR}default/simpleform.pas + ${TEMPLATEDIR}default/dockingform.pas + ${TEMPLATEDIR}default/datamodule.pas + ${TEMPLATEDIR}default/subform.pas + ${TEMPLATEDIR}default/scrollboxform.pas + ${TEMPLATEDIR}default/tabform.pas + ${TEMPLATEDIR}default/dockpanelform.pas + ${TEMPLATEDIR}default/report.pas + ${TEMPLATEDIR}default/pascform.pas + ${TEMPLATEDIR}default/inheritedform.pas +newfoforms=11 + ${TEMPLATEDIR}default/mainform.mfm + ${TEMPLATEDIR}default/simpleform.mfm + ${TEMPLATEDIR}default/dockingform.mfm + ${TEMPLATEDIR}default/datamodule.mfm + ${TEMPLATEDIR}default/subform.mfm + ${TEMPLATEDIR}default/scrollboxform.mfm + ${TEMPLATEDIR}default/tabform.mfm + ${TEMPLATEDIR}default/dockpanelform.mfm + ${TEMPLATEDIR}default/report.mfm + ${TEMPLATEDIR}default/pascform.mfm + ${TEMPLATEDIR}default/inheritedform.mfm +forcezorder=0 +stripmessageesc=0 +copymessages=0 +closemessages=1 +checkmethods=1 +colorerror=-1610612712 +colorwarning=-1610612717 +colornote=-1610612716 +usercolors=30 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +usercolorcomment=30 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +formatmacronames=0 +formatmacrovalues=0 +settingsfile= +settingseditor=0 +settingsdebugger=0 +settingsstorage=0 +settingsprojecttree=0 +settingsautoload=0 +settingsautosave=0 +modulenames=0 +moduletypes=0 +modulefiles=0 +befcommandon=0 +makeoptionson=4 + 63 + 31 + 34 + 32 +aftcommandon=0 +unitdirson=5 + 196671 + 65599 + 196671 + 65599 + 196671 +macroon=0 +macronames=0 +macrovalues=0 +macrogroup=0 +groupcomments=6 + + + + + + +toolsave=0 +toolhide=0 +toolparse=0 +toolmessages=0 +toolshortcuts=0 +fontalias=0 +fontancestors=0 +fontheights=0 +fontwidths=0 +fontoptions=0 +fontxscales=0 +expandprojectfilemacros=4 + 1 + 1 + 1 + 0 +loadprojectfile=4 + 1 + 1 + 1 + 0 +newinheritedforms=11 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 +uid=0 +sourcefilemasks=3 + "*.pas" "*.dpr" "*.lpr" "*.pp" "*.inc" + "*.c" "*.cc" "*.h" + "*.mfm" +syntaxdeffiles=3 + ${SYNTAXDEFDIR}pascal.sdef + ${SYNTAXDEFDIR}cpp.sdef + ${SYNTAXDEFDIR}objecttext.sdef +filemasknames=3 + Source + Forms + All Files +filemasks=3 + "*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + *.mfm + * +showgrid=1 +snaptogrid=1 +moveonfirstclick=1 +noformdesignerdocking=0 +gridsizex=8 +gridsizey=8 +autoindent=1 +blockindent=1 +linenumberson=0 +rightmarginon=1 +rightmarginchars=80 +scrollheight=0 +tabstops=4 +spacetabs=0 +showtabs=0 +tabindent=0 +editfontname=mseide_source +editfontheight=0 +editfontwidth=0 +editfontextraspace=0 +editfontcolor=-1879048183 +editbkcolor=-1879048186 +statementcolor=14745599 +editfontantialiased=1 +editmarkbrackets=1 +backupfilecount=2 +encoding=1 +codetemplatedirs=1 + ${TEMPLATEDIR} +debugcommand=${DEBUGGER} +debugoptions= +debugtarget= +runcommand= +xtermcommand=xterm -S${PTSN}/${PTSH} +remoteconnection= +uploadcommand= +gdbprocessor=auto +gdbservercommand= +gdbservercommandattach= +beforeconnect= +afterconnect= +beforeload= +afterload= +beforerun= +sourcebase= +sourcedirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ + ./ +defines=0 +progparameters= +progworkingdirectory= +envvarnames=0 +envvarvalues=0 +defineson=0 +stoponexception=0 +valuehints=1 +activateonbreak=1 +raiseonbreak=1 +showconsole=0 +externalconsole=0 +settty=1 +gdbdownload=0 +downloadalways=0 +startupbkpt=0 +startupbkpton=0 +gdbsimulator=0 +gdbserverstartonce=0 +gdbloadtimeout= +gdbserverwait=0 +nogdbserverexit=0 +gdbservertty=0 +exceptclassnames=1 + EconvertError +exceptignore=1 + 0 +nodebugbeginend=0 +sigsettings=27 + 1,1,T,F + 3,3,T,F + 4,4,T,F + 6,6,T,F + 7,7,T,F + 8,8,T,F + 9,9,T,F + 10,10,T,F + 11,11,T,F + 12,12,T,F + 13,13,T,F + 15,15,T,F + 16,16,T,F + 17,17,F,F + 18,18,T,F + 19,19,T,F + 20,20,T,F + 21,21,T,F + 22,22,T,F + 23,23,T,F + 24,24,T,F + 25,25,T,F + 26,26,T,F + 27,27,T,F + 28,28,T,F + 29,29,T,F + 30,30,T,F +defaultmake=1 +[breakpoints] +on=0 +path=0 +line=0 +address=0 +addbkpt=0 +ignore=0 +condition=0 +panels=2 + panel1 + panel2 +units= + ( + a=0,4132,6,Pascal Units + ) +cmodules= + ( + a=0,4132,6,C Modules + ) +files= + ( + a=0,4132,6,Text Files + ) +[componentstore] +storedir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ +filename= +[components] +[selecteditpage] +colwidth=100 +x=0 +y=0 +cx=0 +cy=0 +[progparams] +progparamhistory=0 +workdirparamhistory=0 +envvarons=0 +[edit] +hintwidth=0 +hintheight=0 +finddtext= +findhistory=0 +findoptions=1 +editpos=3 + 0,0 + 0,-1073741823 + 0,-1073741823 +bookmarks0=0 +bookmarks1=0 +bookmarks2=0 +sourcefiles=3 + /home/mse/packs/standard/git/mseide-msegui/apps/myide/mybutton.pas + /home/mse/packs/standard/git/mseide-msegui/apps/myide/regcomponents.inc + /home/mse/packs/standard/git/mseide-msegui/apps/myide/regmycomps.pas +relpaths=3 + mybutton.pas + regcomponents.inc + regmycomps.pas +ismoduletexts=3 + 0 + 0 + 0 +modules=0 +moduleoptions=0 +visiblemodules=0 +nomenumodules=0 +[sourcefo.tabwidget] +tabsize=121 +firsttab=0 +index=0 +[layout] +windowlayout=544 + [mainfo.openform] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.projectfiledia] + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + [mainfo.openfile] + filenames=0 + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter="*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + [mainfo.basedock] + splitdir=2 + useroptions=146560 + [mainfo] + splitdir=0 + useroptions=33554555 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=25 + cx=323 + cy=64 + rcx=0 + rcy=0 + wsize=0 + active=1 + visible=1 + [targetconsolefo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=209 + y=385 + cx=368 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [threadsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=37 + y=270 + cx=349 + cy=276 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo] + splitdir=0 + useroptions=16507 + stackedunder=cpui386fo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=100 + y=100 + cx=453 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo.add] + value=0 + [memoryfo.memon] + value=0 + [memoryfo.bitwidth] + value=0 + [memoryfo.cnt] + value=0 + [disassfo] + splitdir=0 + useroptions=16491 + stackedunder=findinfilefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=162 + y=502 + cx=564 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [findinfilefo] + splitdir=0 + useroptions=16491 + stackedunder=componentpalettefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=548 + y=115 + cx=369 + cy=198 + rcx=0 + rcy=0 + [projecttreefo] + splitdir=0 + useroptions=16491 + stackedunder=memoryfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=263 + y=431 + cx=286 + cy=201 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [projecttreefo.grid] + propcolwidthref=135 + width0=141 + sortdescend0=0 + width1=129 + sortdescend1=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=16 + [stackfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=295 + rcx=0 + rcy=0 + [watchpointsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=120 + y=368 + cx=483 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [watchpointsfo.grid] + propcolwidthref=352 + sortdescend0=0 + values1=0 + values1_ci=-1 + width1=33 + sortdescend1=0 + values2=0 + width2=158 + sortdescend2=0 + width4=34 + sortdescend4=0 + values5=0 + values5_ci=-1 + width5=38 + sortdescend5=0 + values6=0 + width6=184 + sortdescend6=0 + [breakpointsfo] + splitdir=0 + useroptions=16491 + stackedunder=projecttreefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=107 + y=404 + cx=636 + cy=128 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [breakpointsfo.bkptson] + value=1 + [objectinspectorfo] + splitdir=0 + useroptions=16491 + stackedunder=mainfo.panel2 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=724 + y=157 + cx=296 + cy=566 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [objectinspectorfo.grid] + propcolwidthref=286 + width0=105 + sortdescend0=0 + width1=175 + sortdescend1=0 + [symbolfo] + splitdir=0 + useroptions=16507 + stackedunder=disassfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=142 + y=257 + cx=361 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [symbolfo.grid] + propcolwidthref=222 + values0=14 + + + + + + + + + + + + + + + width0=111 + sortdescend0=0 + width1=135 + sortdescend1=0 + [symbolfo.symbol] + [watchfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=298 + cx=313 + cy=236 + rcx=0 + rcy=0 + [watchfo.grid] + propcolwidthref=118 + values0=0 + values0_ci=-1 + sortdescend0=0 + values1=0 + width1=152 + sortdescend1=0 + values3=0 + values3_ci=-1 + sortdescend3=0 + values4=0 + values4_ci=-1 + width4=13 + sortdescend4=0 + [watchfo.watchon] + [watchfo.expression] + [watchfo.watcheson] + value=1 + [messagefo] + splitdir=0 + useroptions=49259 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=510 + cx=675 + cy=95 + rcx=0 + rcy=0 + [componentstorefo] + splitdir=0 + useroptions=24699 + stackedunder=symbolfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=305 + y=101 + cx=445 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentstorefo.grid] + propcolwidthref=435 + width0=111 + sortdescend0=0 + sortdescend1=0 + width2=112 + sortdescend2=0 + width3=185 + sortdescend3=0 + [componentstorefo.storefiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.groupfiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.compfiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentpalettefo] + splitdir=0 + useroptions=24683 + stackedunder=objectinspectorfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=25 + cx=685 + cy=103 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [componentpalettefo.componentpages] + activetab=0 + [debuggerfo] + splitdir=0 + useroptions=24683 + parent=mainfo.basedock + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=28 + rcx=0 + rcy=0 + [sourcefo] + splitdir=0 + useroptions=16489 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=675 + cy=507 + rcx=0 + rcy=0 + [actionsmo.watchesonact] + checked=1 + [actionsmo.bluedotsonact] + checked=1 + [cpui386fo] + irqoff=0 + splitdir=0 + useroptions=16491 + stackedunder=componentstorefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=337 + y=295 + cx=273 + cy=207 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [mainfo.panel1] + splitdir=2 + useroptions=33586667 + stackedunder=mainfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=118 + cx=685 + cy=605 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel2] + splitdir=2 + useroptions=33586667 + stackedunder=mainfo.panel1 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=189 + cx=323 + cy=534 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 +[targetconsole] +finddtext= +findhistory=0 +findoptions=1 diff --git a/mseide-msegui/apps/myide/regcomponents.inc b/mseide-msegui/apps/myide/regcomponents.inc new file mode 100644 index 0000000..b8778a1 --- /dev/null +++ b/mseide-msegui/apps/myide/regcomponents.inc @@ -0,0 +1 @@ +regmycomps, diff --git a/mseide-msegui/apps/myide/regmycomps.pas b/mseide-msegui/apps/myide/regmycomps.pas new file mode 100644 index 0000000..6be4cc3 --- /dev/null +++ b/mseide-msegui/apps/myide/regmycomps.pas @@ -0,0 +1,17 @@ +unit regmycomps; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + msedesignintf,mybutton; + +procedure register; +begin + registercomponents('My',[tmybutton]); +end; + +initialization + register; +end. diff --git a/mseide-msegui/contributed/README.TXT b/mseide-msegui/contributed/README.TXT new file mode 100644 index 0000000..d001c97 --- /dev/null +++ b/mseide-msegui/contributed/README.TXT @@ -0,0 +1,4 @@ +2007-11-15 mse + +Contributed has been moved to +https://gitlab.com/mseuniverse/mseuniverse/tree/master/attic/msedocumenting/mse/trunk/contributed diff --git a/mseide-msegui/help/README.TXT b/mseide-msegui/help/README.TXT new file mode 100644 index 0000000..458522c --- /dev/null +++ b/mseide-msegui/help/README.TXT @@ -0,0 +1,4 @@ +2007-11-15 mse + +Help has been moved to +https://gitlab.com/mseide-msegui/mseuniverse/tree/master/attic/msedocumenting/mse/trunk/help \ No newline at end of file diff --git a/mseide-msegui/icons/buttons/breakpoint.png b/mseide-msegui/icons/buttons/breakpoint.png new file mode 100644 index 0000000000000000000000000000000000000000..4aab1b85876b20d288759556c1c393827e8512c9 GIT binary patch literal 481 zcmV<70UrK|P)RRMm9S=d0X@LJB$F6(M*?rEb%S#B({9E4cwr4y7V+?c4GI=$)0E4l5 zZ@XQd@;j88&BdY*VC)K@QK}DiyGGlx%;QcNV`%HT+5Gr;9~}+`fX=BJj&lG2WmPQ| zMX?%_q%gc*%=de + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/buttons/continue.png b/mseide-msegui/icons/buttons/continue.png new file mode 100644 index 0000000000000000000000000000000000000000..8a8c92ab0f784a7e9c988f5e2aa009a7e25aa772 GIT binary patch literal 582 zcmV-M0=fN(P)Z8T_Am}2&RLmq!GI8ZHW=3c5 ztndAPaL&10ftg`uSxilTR-o#Ds-^RCHxUV@08tfIq>1j7aoaMrQj*~S00?%Qm|CAx zXK#P8MV~0cZ~y=jlWhsv4R1;^o71-|#;8PZ%QOu+!D>ZuePwQTQ{L*!&g5o2h~_P_ z2o{vq)MgYk7EL>P?V5+LdreErq|~y;>W-XI#|#n0z5l3p;4CEZ?You_`IEUD)J>w{ z006vlytcNre3YE;3t1YXEW?5OQbVd3TtdvjCq6d#^zyH=@^#_QiOVyB5N4Sy#oNgFtZZttZsm}zhD2GI@-9JzUc?B#?0zN=QRUrR0VHt`aFG}h1+#y z5Wrrnw&(^Tih}*spBLUP@0@y!5df!J!ZiWmKrnK?a(w1@-HgGH2>?E=;ci3l#X|o`5U-3&0{XhxLX7fDrG~Cn7;lOLPNIEz>{!JGQZ@ U4Z?7b_5c6?07*qoM6N<$g0(sRt^fc4 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/buttons/continue.svg b/mseide-msegui/icons/buttons/continue.svg new file mode 100644 index 0000000..e648de7 --- /dev/null +++ b/mseide-msegui/icons/buttons/continue.svg @@ -0,0 +1,283 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/buttons/continuedisab.png b/mseide-msegui/icons/buttons/continuedisab.png new file mode 100644 index 0000000000000000000000000000000000000000..3b20480d8fdaf47a6fee4a3995387bb134ecd95a GIT binary patch literal 489 zcmV!ZiA4bO}6DfJVej>JkRfQ4re(=yWK`- znOf8T9B8##2U-EcFrJ3P;kh;dh`X+P=XqXT7r=BnrQ7XZE2WyYZ5vw$=B1Q6ZZ?~* zuIuh;0RVj8KOB$8Zm-wd*8%_pK@bmu;H}^9A87#qMx)WLQtHw7{YxzXz+^HpJDpC$ z^Sp)@U|y+Is%G2v)o=ZsO@qVXFy(TYWHLEhG`A5DjYg?ftHfflPvA^M9<~M~5(z4m z3Xw?U12_?pmqqhy0qJy_QmI5J6nX|uMMN#zSsBP?v*h!6fP3IVL`JLZEd@-|q*yGH z$z%ZPz>SD3eAsn>f#W!F%d)Ma|i4R + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/buttons/execline.png b/mseide-msegui/icons/buttons/execline.png new file mode 100644 index 0000000000000000000000000000000000000000..c93651a8bf16763ec7b085922c0cd64fe135d65e GIT binary patch literal 527 zcmV+q0`UEbP)wK2dr(xfYI+i^cIRC15E5u{eaIpsI?Z63cGrC%Yp9CZ@;+gZM%b zSY5Y06oJ_wOilwRibg7<>-xe-0KdwLItBp^=AyO-G*HLD?{{)o3;|n%G+dk9eT7aN z%qEmB?U>oLW8K#;sq-TNtQJ=dgYAF@ZOe`|pP*rY)w0ihDs?vvuQAQnsxsZ{D$1kb zK%e2^LsCkMLJ7DVB;eYEBXNDvlhwR&FXc@cZpvWXgOs*-hlBGM4r@ShkcQ_T0BqK28PBYrG|IQtd=z!}9YJ{x)m6onACZgoQgMz!DnoBjhl?HzB`idI%N Rq)7k(002ovPDHLkV1jI&;U541 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/buttons/execline.svg b/mseide-msegui/icons/buttons/execline.svg new file mode 100644 index 0000000..6e73c0d --- /dev/null +++ b/mseide-msegui/icons/buttons/execline.svg @@ -0,0 +1,285 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/buttons/finish.png b/mseide-msegui/icons/buttons/finish.png new file mode 100644 index 0000000000000000000000000000000000000000..3a8d5767f1ce40970d03d28a5f3487803f1c55e8 GIT binary patch literal 1199 zcmV;g1W@~lP)8e-|cS<+?fEuBtP*89qL~O~}Qbi&4D1w3^Q8Uq*B;z>E z%$PSHZ@PHTIMFm!Je&8y<^Mb9f9^e3i3k8%>v|E%KK}l^;i-DxptW8F6akOc+9x7M zo)@4VR`4*i*3DI56X*g2s0YG8Qbf{^3zfBg({|QVBNAJz0surL<$^Z5q9q^%EC-t0 z?mH!p z{pS^tlfdOA5&%d5WVCK+G))s=&az5#P6Cw$03hyWWB`Hx5q=a}cZb^BziD2*dKp0a z!GoL)*(U%Zl2!u)QC~3lnI{lvF?a6{qtsFs0ub1;CD<5=Gu^ucM{Rw5El-_&Ran_9=ZA(8pQh78IBt~Z0rtj?Yr^Z+?P-ffTLA9eyjf1% zzMZ#=#R{g0QVIYCN|~n9J*7}esa!r^n4X=@j%6}apJy_^%{qM(5h>0C>cZiJt-Zai z0Dql4IejD^kByYe@hCK3fW$Od9#94-(|KZm@_?EK%Z3N8Et9|noE|U_F#Y~kWf=5M-8csN#BF28tq5SpYC zjvcJnx$`ja;dbYQhHy^#i>@{Qxt*1Wa8>Kb>(S_imo{x$29Ql8?1^*da&3F}HU!tN z$MkwBPfd|Jb&83jNB2`@m)5!$cp0bz{svwJZUDB3hym~(j9(icKX7$;I90K2>f73k zrmn6AE0G|7>lXQVoRVP>7#N^w+qT1iu1azoI1l`evk^|=?5ON~4@9J*wf^q?+1ZJA zlgY1|gTWUXa=E5ZM~6>^LYRI(s!}0)=@LH-4aEjw`)P=|fIeU~&TuTacHINgTI;?A z7mn82i_^sZ58$mYH*enOUAYoNDXg(E2G5?24Z`Il9B{qw0IrLOt+ieTq^h^*d<73f zL<(B#IFQ^0xw&L=U$Io8GBd+3*RI6|L6Y!2@D4DGGrC8Cf{4s4*5t)*G#ju=T3goL zyBNtNCsL`{AjoNv{qC~si-|oIpgJn)G$-J3@n?#q#<3LP?dK5(_!r!8u(z-d7+L@T N002ovPDHLkV1lTq8Z7_- literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/buttons/finish.svg b/mseide-msegui/icons/buttons/finish.svg new file mode 100644 index 0000000..70f2c70 --- /dev/null +++ b/mseide-msegui/icons/buttons/finish.svg @@ -0,0 +1,449 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + begin int1:= 2; caption:= 'A';end; + begin int1:= 2; caption:= 'A';end; + + + + + + diff --git a/mseide-msegui/icons/buttons/finishdisab.png b/mseide-msegui/icons/buttons/finishdisab.png new file mode 100644 index 0000000000000000000000000000000000000000..77a81ddc1cf0e52e3a23a33309c4769388b88ae5 GIT binary patch literal 870 zcmV-s1DX7ZP)O{rJ4IiqosLWg`RBFho z|3?;xZIRe^1L98rA+hKxo2(Kc1Y*ewsZk`_oRJq)s`{a(h&ISgBO0jFjEBX{1ZUj1 zX?iv@@9DjB&b{xx`5dXcn%cJtRm^_*A;MC1R2ci^pLOz z-T?%h0_wmcNn3d$NhLFTJ}!c6VJ{WBl#=cN6Tn-*WIEo;?eV~FYPN4?l|u!F@CQ%@ zP5_;h^bxRYW*-1Mz=y!C#l^*Y*(UFOIS7JhVHj3kCQt=hz#G7QpbR_%O297A2c7_r zQxgCb3I%|8Bmy(*0B@#qCnWsv{0NDAek0PrAnR7hPP36fgC zuY_{BOub&G(P&_1IOo0xzRgGQRYpEBF~Qv29F0Z;?~k0J$0P;u8}MZqhJ(Do#cX1J zex9kRso!^Yc0ONOS@~)B(i{f`Nsgr60jSsO0G}=|FaHXZ!!V2w+k6xh%`BF52Y4S~ zb90ksv)RoS#Bofw+l@P&jsq~WHveC&I`9v0UDALTppbs|PknWDm9@3C&zy57v$-gW z=ytnVB!83irWWuvFc{()fs=%!v)=pLQ52199eD4_BFSK80dNjD3ETkA1Gj*IBo)#{ z_iMG< + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + begin int1:= 2; caption:= 'A';end; + begin int1:= 2; caption:= 'A';end; + + + + + + diff --git a/mseide-msegui/icons/buttons/finishi.png b/mseide-msegui/icons/buttons/finishi.png new file mode 100644 index 0000000000000000000000000000000000000000..8bd8a4273a64c841dabb3273cf13599677151f9f GIT binary patch literal 1183 zcmV;Q1YrA#P)c)tQj8c( zATdVci*LU8qA>;@crnH&1JURc#1}QuNQ^P@&Bka*RM;35c>oUrh6q@`3jNw{zh-x5 zcV?~+Gc4OuD}<9wa_(gE|DF3kcg|HJ0)W=KSw!X*<_{W9L;j@JdL2*$9IbUqL=HbF zK;7QK?a*3xG=Obj4In@>&<2c(NO7Uiz*)UB{+{1AOMbB(03afT81zgm>I1F7Dxf`H z-vuza%-6Na6ap*p>~TywImg6)^Jvz>T;f3uyWu;d*Sppx2XK_F<6AIb!>L~aCiK>y$U8^cx2ulhZaxK$_x*3C)@V@%X4 z6|11I>NzN-DEU>Z;Ln+>{#f;}|06DEB15EB2dK3Dp5N2b1(5h3lx@H#T>1i3Vtv@C-+jy>}>n2 zGFyBr_?0hfpEJGCmhet$;$;BTM8wPkpsXeUHQ`ml)8-%GxV44uwvH8eO)c*icVF|I z-5fcwNv7_%HxVERO8{X{Cgr>|vo$I3*(CVgL(3Rf1sxgGtz!{`6zXcbzv(g>+L}iuRsXde^U^ckPBlz$^AH6wz$z z1y;w_{O562BEt6X_1fTx>`8w^dk(;wsf5mzDYtKHUrR@K7nZH4xD|#kU*YokbNk_r zU0UnMfk%K0a2nVITm(W95evY3n<4vR`GE81WC09eHf4pmOiO9nW3EubEmpu-boH*H zXZ6E}0NqgJ5O4zc377`HBRWxY^&W_b(OQ3OzfilL*yFup+ME?u+HWu6r5vk-owQNP zP%PZy+NW3Z{va=MjC>5(25cZ2j@8(%Nua2;-Zt;T(OM^gl|Y~KJiEI0uHTnwT8?Fh zxNd=4Uk&B`LC%;-4#eK~02f3g)LQ3&LgNvw@8EWbNL6cn0~mFl#Vt*H`~31OzL{p~ z+nafR5HXW{0z3!I5{>RlKvhI07HjfiH(CgIJI-sbJX^*~%;Dt=d4CZ3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + begin int1:= 2; caption:= 'A';end; + + begin int1:= 2; caption:= 'A';end; + + + + diff --git a/mseide-msegui/icons/buttons/interrupt.png b/mseide-msegui/icons/buttons/interrupt.png new file mode 100644 index 0000000000000000000000000000000000000000..a7d9be48589d1268961bfa81dcb1e445bf0c7bec GIT binary patch literal 489 zcmVFowps?U($%ot>FGm1P-rd7_=B{|P~56F58X zJ~U6_7yxGXx;D9kf0GQr!b#nF8D9hPc!BHo&!*S9Zj+0)!x!h0F)5{{S z=)ovy4@OD5e!ST8xmW=)uzIlo0K)(fsh@CBz}n^k%*p~P;BUDgj-fWn ze*&YwHoc6C0%B96<$M8HeBMs^i&mre=Q+Rt;(&_+93J#>+qeL<1<3k1yP0* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/buttons/interruptdisab.png b/mseide-msegui/icons/buttons/interruptdisab.png new file mode 100644 index 0000000000000000000000000000000000000000..f6073c8499a88a9d33875945ee25df8049a12107 GIT binary patch literal 213 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ zFuwp{#;w&s*+4QnYLHZm$}ell>_!vE##*Z-51?Y}%uxY88J z?WQZSHNhaFVY8iqfkDENa2Mf8?Tp7Rdd(MLVDNVpNtIjuR|IG}gQu&X%Q~loCIC7F BLm2=7 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/buttons/interruptdisab.svg b/mseide-msegui/icons/buttons/interruptdisab.svg new file mode 100644 index 0000000..1f27137 --- /dev/null +++ b/mseide-msegui/icons/buttons/interruptdisab.svg @@ -0,0 +1,265 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/buttons/next.png b/mseide-msegui/icons/buttons/next.png new file mode 100644 index 0000000000000000000000000000000000000000..f16771c12caad1fe72de2b4b65f6636f9198489d GIT binary patch literal 947 zcmV;k15EshP)e<$apO-7QYAF?%RX}c+-(%NT~Om2Sy_mY)V8r0ZUa=|2MZOKqK-zQg^oP!EF(9c<GMTBUT@F=qjpX? zoAvz}kG~pG{iz{e=-ufb&UAzN1pjZOC3QlF?v2Cc${6!!LR7K=BAPV$|$aPhXTL7)$ z@VKwD({id+7Gkl#-ppoy9D!>eLrWX{It8oSOW#}`Rh@COHr&`B?%20gf$8&g0c7so ztNyUIb`!Yr0eB;k$d%;%`)|#`g?82dKz0JwjEms5spB}?H|r+AV~xn?0Afa2QPH!Jb@x?!4(4i5Hw z7Y=`F!T`}I*3b~$)6)!}I@J_p>!>JBPX01_^5ip?-%mN8XGwKEboz8_$Kk`6EiF{i zX_hZv=J)gG-`xYBZSIL|08Q5~3MANQ;}YQC`k^w(t((rUmlFtDz1Fr*50#k0RABg_zuzOylGy-&)Ro`i7i8du7CUEo>m^yp>_?bO@eHey8J|5@u z`T2&-VTTJxRja_yDG{rfN}X{k71kd-;LBL7Ve=gUoAQ8DTwbP_O7ZQ=N>k=_0RW{; zhVP+i^SS^Fv;;4F1=F*xxrpoo_PJBqRCT^-fZOMDvoKc^4goD}^nH031w8sY`5)fI VU+#RR>7oDt002ovPDHLkV1lO|!NC9k literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/buttons/next.svg b/mseide-msegui/icons/buttons/next.svg new file mode 100644 index 0000000..f79bf6f --- /dev/null +++ b/mseide-msegui/icons/buttons/next.svg @@ -0,0 +1,399 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + begin int1:= 2; caption:= 'A';end; + + + + + + diff --git a/mseide-msegui/icons/buttons/nextdisab.png b/mseide-msegui/icons/buttons/nextdisab.png new file mode 100644 index 0000000000000000000000000000000000000000..fb4abd5cca29251c1f2bd7e4166a2c717da9ca5c GIT binary patch literal 655 zcmV;A0&x9_P)jg^*G zLLh~e2$tf{u(FjYwGh`|u%-xv4dh(VW(w2T*d#8jkWn^kk&Mj7n3+WPt>&J&=Y8g! zxgVCQl2js+Rn?>U=VfvdyH9mXM6Loq0Y^kORQ1KO1Z$NFLW#%)z){t&adX!KtfJJJ zx-<6=+U<5Gm&-k~Eb9(X2eua_wOXw$W6Zae0R4XdT0WnD4cttSHv+6AfD}Nt+f7@R z^){jTDTzo{L>v*>io`C4&kjH)lX(nW2e56MMx#NgR3e+r0vyIL?g2UASVRthB5+AW z_Eq(B*rNO4?0UUUtyVh%o&tNunBg*aRedx2YD-m5fKRjW#_tM%8(~7ZTn2b^7>~!7;}YgKnTTux_H0-LzA)V*KY;TofNHgR90bALLZR?I4zQq- zUEm?`2&ge#k-IGjWLPZ^~Y)Ix~>B}0d9Mq z_uya57XqS+uI+WqA>nbou6ZIrv)NqR9AaAJx^4;xj4^2d5!nHDX0HpX`XLUm^wKxR pOn`JGlxMojZKfB0tj_#S{sl%F%wEgbYs>%u002ovPDHLkV1hMWA3y*A literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/buttons/nextdisab.svg b/mseide-msegui/icons/buttons/nextdisab.svg new file mode 100644 index 0000000..035a312 --- /dev/null +++ b/mseide-msegui/icons/buttons/nextdisab.svg @@ -0,0 +1,359 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + begin int1:= 2; caption:= 'A';end; + + + + + + diff --git a/mseide-msegui/icons/buttons/nexti.png b/mseide-msegui/icons/buttons/nexti.png new file mode 100644 index 0000000000000000000000000000000000000000..6c53ffb1433775db173d96f6731f08e3783159fe GIT binary patch literal 929 zcmV;S177@zP)O^V3fKpk*J#5cyg z)$Rw?Nd_&6$N=CPW0wDKZdZU#L%ot;L1&}MEQ@xp~aANQ{N}*~o z&W%c_)}j!L#ac+PSa9OH8*?)&5y=4okT=Hs-Hh!s#$4Y5_+IMe+IaslltN!!+i+&q zeu_ViF2{?kV+n{zh_NJCA`%j|ul!LU55yw!6)*zq7m;aW%z_ILXT38vlX9^ZZ8ny| z*P~C|Bb2;XN%<*e%V$~LnR;t`j4>CQt5(g}_sy|?vj*DP1K|7>#PLjh9=Pbff|p4Z zE(Z10=L_$1e)?YXAIPnM+r|Mj+f*fXXR+o13dKSC`$pfaB|LrR8!5B{+)fQZlq>@z zMPKU&y$L`AAq_xK|4{!~t)UdLYmO z9O(+Obyb|4Klw%d#NJcZ)u>vGUMkm4+;cR&XWt->b_g~DmahH6wYl$JOgp^Ss)>jc zS{c*mphX&O90HlGgBGrYkEBY=Uq<&098UVuIvL2OE9HRobQSG6xSnQkbeL*&{oLZ* zua|+=Nqztr1G2zxz%gJASODCAU3PL>ite-Sd1ur;N|EB&$f10`P{j2#sD#y(KUjF@ z$LV;AujfkUg^spp3nHR{N%wIc8+zvOOFcb(C~c{1u5kT>pF1+YC7`8K-^xST^j)QN zI!oP_DNp_0u{pGR(Hv~Bxk)Y9Ae>(5%Dg=Qs7Do;t$yCEd0T)VVFJJMaQG2Vw9G|h z2pDQk=`+U6bPZ_s`6WtR+7|8wQZ)L$zKaCz{G0p_BzsunkE27o00000NkvXXu0mjf DrbE38 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/buttons/nexti.svg b/mseide-msegui/icons/buttons/nexti.svg new file mode 100644 index 0000000..df211d9 --- /dev/null +++ b/mseide-msegui/icons/buttons/nexti.svg @@ -0,0 +1,399 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + begin int1:= 2; caption:= 'A';end; + + + + + + diff --git a/mseide-msegui/icons/buttons/nextidisab.png b/mseide-msegui/icons/buttons/nextidisab.png new file mode 100644 index 0000000000000000000000000000000000000000..5a334d995295f789538c6e5dae889a4092d388a0 GIT binary patch literal 601 zcmV-f0;c_mP)*f z?>$$#-7Y6t?nK@H3&7b)0##iSkvtFsIWsfw{o8*A05;7m=bS45yJq%zTJw>BR;yKr zqUhT2TAHQ+JKp;*GXYjtSI>uG_!3wKWQ_g^urd=M48zC3ZQvQO4*VLS-vMYgn~VK^ z{~S=vWHMVxlFY|(yqL{qx69>na0E~)l|)sSfi>^_gGsv@39C=yUiIE@P6CfA2T-Y0wt2$I| z5WE2HF#Z++yaC<;mqjE2egdhP1qbRWAV7Is6VrCQ#LjwOZ}l z!QBse%^v}b5eC40@BOQZ;-Q+RRRG+a^%hM`psGcn2;iK{SF6>H;{c{fkOStNb7#^t n?H|V+rbzI&b^3p_(+~I!FLK8&mu*mY00000NkvXXu0mjfra20K literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/buttons/nextidisab.svg b/mseide-msegui/icons/buttons/nextidisab.svg new file mode 100644 index 0000000..e729708 --- /dev/null +++ b/mseide-msegui/icons/buttons/nextidisab.svg @@ -0,0 +1,339 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + begin int1:= 2; caption:= 'A';end; + + + + + diff --git a/mseide-msegui/icons/buttons/path3846.png b/mseide-msegui/icons/buttons/path3846.png new file mode 100644 index 0000000000000000000000000000000000000000..92c58c209f0e2ad9d2533e19527f6a22b7e9a498 GIT binary patch literal 735 zcmV<50wDc~P)F^(iC&BeM!n&w zCodlKqWB|R{4>yS(1y}9bwi1=)i1{iXjG%x{tSMcx_#1>!)hybSnJ1DCl zBKhr*EwD?rePpCsod?{{B99h~=>sN2q`aGPCn-OX@Mm2&b0(L&w(9$%BI5oFU<=Gk zBwPhn-t(5iO1-j`T2_By^nCw^3o_%nlU6EK0Z>!z?a3~!pGB35{!ccJ?|->bEM6RP zoSzD?lHu^#Q=!m6uhv}}ti1qDpgOgVpVYcDqEz@pwfgpQK7Un-2*wzT#vpb8hX^ia zFXrP|?8@zEbTI9@i^rFj?`mUA4~^kdz<$65CV|zxXvs)q9T;p@N&_7l_)TM~TYxqi z6CDb&YZj4`F-8NeB9hw-JJ{d<3&2(?1lU?cvOsntz!-B5xDG4=bz@8wmUR6Tob+Zv~uSy$0gO7!T+MmOi$%xqY^crIZDPc7mM%jsaaj0jLEf z&jahgHy{p_FRZK-y0t!>cHNsmO#v|)-$*^^*{Fy(#+cCNl6I3ZM$ve~^*@7e<%iWK RD_Z~n002ovPDHLkV1ks9Ga3K@ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/buttons/reset.png b/mseide-msegui/icons/buttons/reset.png new file mode 100644 index 0000000000000000000000000000000000000000..c76f21cced80fd91131ae0a0838fbd4715888993 GIT binary patch literal 1318 zcmV+>1=;$EP)M zu$NNysvdShi}oUdAc7*e9(I?CNB2}=p`eR+5kIha2v`*q3uDV_ETxN@4U;x)Y?I07 zB-z88MyuV`ivuq+!~49?|M~d8&)=r&I$!dUzNmM=@hO7`nzq9S18&&vfiA$7g@g%H z3AlX*CV+~r>$SDc+y1LW4>e6yU{r(MA!zn|u%827L;f*L+=4^bVOH1m%4Y#gYT8f; zPV_fUTA3% z08LHcsKZ(oluD4#^WyE>{2#g8@5AsjkX->;)#QhoriS1|5BPGxWru^5qJXMGXD0-M z5DJNRFvy(W&t-kRC8JwQxs%1eSK!10)GU#;v0)#Y8v#$bpplLfa*u7HofwnfnvP`U4 zB=Y<@Mr*5Z9t>jmd_=~^h%GGu-8j0lOZxTh9S!sl0;;5lvpZ7xTAyUks~M@H-e%-dpkYBpuE%J*b8g| z>H~g2K7q>vJ5VlSRM~*M+ectLAEFgGpQ6a^Yd&81c;tKjjF1`uBk}`)!Ymo z4*{2}74QSn`!u%!f`U$`IMmc697vL&Ys1n89*@|oR^QRp8bWouQC%*gr%n;>>?D>*5V>%HxpW#T6(|&#jmL|R3WaH44yZN&&cMWDn6QdP zC=|GnOcKjv2>X0Q_wPrQWhfLNmqT?ph#o&qI1nI~OmcH_5=;|oX^FcpU&jA}e}E)l zz2D@@EjXmW{eII_545yEZ!ZH|x8g6AAe(*HP)S0y+ZjK4lp9l19O&+bbefy@?=KE7 zE!_d$0Iyb+NZ0k+b(nnymtJHtdC&4Phg~lGrU|JO%+0~V0xT~Juxu8^vN*hXGoEys z7n764Yl+0uc@h0MkkNI$wrU#dx?a&V?c!3c*0v{=`mtY<6bFd<7K_5M%k^%WmdjYC z$;~HE7Oxq`(?3h42fz~`zM>6lDOzC|&V5^{Jp9`*e%)u9n|ktj*^|o&?#nXR?c_=& zX6NRLcVE4V4`(uW>XAQ2C|sd&W!4fLP19_MksI0t2Y1?RdpA3sovPF6t4R{cN+ml} zE+-$A%hUCSzNwcb&Zh+D10Xx#MGUS0;`%G~?G%EF$$CRGpDmedWMfB^Q>uRhRDddA c@js&fFQ0+?y7S}1F#rGn07*qoM6N<$f?!KwssI20 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/buttons/reset.svg b/mseide-msegui/icons/buttons/reset.svg new file mode 100644 index 0000000..11d44c7 --- /dev/null +++ b/mseide-msegui/icons/buttons/reset.svg @@ -0,0 +1,327 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/buttons/resetdisab.png b/mseide-msegui/icons/buttons/resetdisab.png new file mode 100644 index 0000000000000000000000000000000000000000..d3edb10c13cfd6a5048c58432da6976fa0511559 GIT binary patch literal 978 zcmV;@111Y=;14Wm)Cge}0)s~^2;>D9LEyrL zUDzy(>wxXX^(I9ibs!0Z{0}KzY_X)UOS`rsKM_c=U?U-ck);_~l9^$onU`WUie@#k z17Qyg%y8$ObMJZgzNg&W-0&r#eo=N{?zy08nsc>UZO8Mx*NUQS02`ywwUqK&Rn@C( zHhY#xB!;s%lvx&4Diz)Hyx)P>&m|Fy#XhR4`gVPN{jae2ltqO?K@mc{^E~g*m&gGe z$60e6M^vlTp9_V8@?r%-h<8%TUtb~)LoS#5P%4$)2q9!>1(ixgms0)+Af@E#=?TyC zW)ixtOTXVo%1?aNYIVO}um3dp&se}T&AE~1Ujg)bJsut&Fin$aG#W~Ne}7M_)na*h znP@bM>$;T7EjgtJQXx@O*J`k%ff?dcEG1h)+Hk3`i!E?C$Q8%jEzt3`1=+ z8t)5*!rbQ;ZA`oqi9|@J)5PO(TCEm_VGxVOrpONu4;c&wRIAnT+HSYI2JFDZ97rjr zI>vQfQmGUG?RFa}CH;OsK<>IO=jZ3xwmn|gYPI}?|Ck)KKm|UA!y%fcA*IAH3;+^| zM1b6~tiYOfyNz%6vy<$@ahw2&qA2wHeJ(FAr^r7~cybS}!~XI;cN~X!JWeW=!Y~X@ zPfusIu%>C__pyMYC|9${eb0}Nk2yFvK+`l#)1=vKGCw~*B{15zYY18ts35FcT-W8| z;(~ZQ4*a|E>2x|^)u@82Kn2-s_AC~Qee}OA%L?rl%d&7?cWhUu(;<_|u(Y%^CeLIt z%)3)tJ+qS<}6a~-ouq=ymxg6+oA5u!X-7cL@hr7Ewip3(UtE)D!BZO!MD)6zt zzyEzMm-`TjMDRS1+uPevav#Itkb1pNu~;OZ&jb7*g!tQ!PYDPiWT{kov$eJLOEQ_9 zeUy%%X&QTbd*t(Z8~7IZZ8ARdMg!1w{Z*sUc>nnLxYlmB{Ru_WG&D^kl}eGxWPH!R znaun@2>^^vMgOD?+{>fq3OEx&gx + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/buttons/step.png b/mseide-msegui/icons/buttons/step.png new file mode 100644 index 0000000000000000000000000000000000000000..d97c569ddf10fdf553c2496a98cd864d2355ed69 GIT binary patch literal 1171 zcmV;E1Z?|>P)``X)S4Tt;w3rR%+dvh~^6DMdrcI;)2lO+*r^+W(IPrEs{(>G!|y@OneGhK7TAn~j3sk3ASHlT=stO`bW! z5S;a^CPd@_umJc(f^CYWk zPDH-{d~xw4&;cBvJl7TFgbkzajVo7996x#Tpueffalg;kLpt37Tn5&+o89x2`&|N7 zfN|i5N(3XNl5svB|G53ywTpLz!?krD&uzf%z>l!a>{RtV01;^eegz%`x_}fA1D1ex zU_@1yH=Y|8nKlZAEP&VTcDf;uwv_MKV^y87CLv?3>p&hT06D<9HUBPHC6~)#Nza$9 z!?;Po4&kNjF?H5{$pT*&kviZIunK%TnM^uXW@jlbFPnJ_d{+VyaZ|Q}84J{){BbcT zTk*20E{n*Vb + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + begin int1:= 2; caption:= 'A';end; + begin int1:= 2; caption:= 'A';end; + + + + + + diff --git a/mseide-msegui/icons/buttons/stepdisab.png b/mseide-msegui/icons/buttons/stepdisab.png new file mode 100644 index 0000000000000000000000000000000000000000..70b7aebe62a5a0052eda2392b5e98681f4a19908 GIT binary patch literal 856 zcmV-e1E>6nP)EhUH`Xj_O)Mc{cDDa|5(P!XkLgX8Gf%xf|C$@qNZw8$?! zxcA(9zTb21kMpikRgM!il?LYL=j&B<=hy@+>J}Cj+~X9WP$=LR5s^qxI|$)_iNX^Z z7#J|tbWKEBflZ)BL^f6RX^^ie-(*#d1NVTlKtB*FpBxH>C=)?MdVn856lk^qe*=m@ z9Qd>^psH7a$97^x_(iPH6`%q52o!)kFbKR0Tk>w;3D8uHd~9qCV8?Ns`m&*vjlKzJ zvsruv!rmr7@W>;P2qPmSjE;_0BH#6q12h7sC@srxy9x#jo@Oh-q@m+kHC zN#I2gxrkf@YVG$^Rg;yn4y&rM$^f*tw*y?CnVFe2#$b#Iiu^OMYqKs^A_oYIh^wk= zo=7^Krmd~*jUC?|A0Mv+3gye9s;ftlmc!eFx1M2cZjNL!Ic|(G6B83r8~H!ommnBb zMO9B5W0qXkt$MQqumL#02jISl9H?J403woVX=%9=3WWmvtD+US0NjejVoqmgXX7CO zfbQ<@=|m!NHy)1{qR}YE7(Y=}tgo;4EiW%8hlYmsc@L~@PfyPy*L9x(w=@C14Bq1*Cx?;JvD5JinEd74KM+%jE#X>j$11Rb5n77ud1iD)5I= zA=?A|r6TV&ip3(pNv~h+d`Il$m~E#md0s?fz!@Oh)z$TCYHF(7ul7g*5ox4U3RWzs zq4aYxHrkA;W<=yWVAj^wYI}Qo8xn~`&Qk0j!LX0`rft>(&sBBtsPt5I(`P#2IL= + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + begin int1:= 2; caption:= 'A';end; + begin int1:= 2; caption:= 'A';end; + + + + + + diff --git a/mseide-msegui/icons/buttons/stepi.png b/mseide-msegui/icons/buttons/stepi.png new file mode 100644 index 0000000000000000000000000000000000000000..fb22f4f3a4b461532c1dd73540910a4bc3c24761 GIT binary patch literal 1140 zcmV-)1dIELP)ECHs7EUD_J|41-;=H9_5=e!p?cE8b)-fox%*$pZ3g$%humQ>Ce`>ixh z_G6Auj_8tz3;~ycf{5Ii;LQUOunqWmm0-{81J6VoJKpjKyN56h?D;aavP&gh$8t<; z$70jgE!3-(vH5dz3KUg!Hc8XtKo*z=HUl0o2wb)k&v!(9o$vSqg?<3T4KT0N8+96K z+pJ+b78nsri+^zb*jzCf=V?w-ydn6riT8P6V-m&hfNcXr`P31=zpEd>nOeBYDYq2O zhF5Bb8;6XrhGE6jYKvU@WVRTLGkyA`zPx_BfIgrDxCnFtbs%gKWSo9X1H%pAlw0zT zhM%QgqEat64u$Rte!R@`=ku%JBC;27lD43#lQ$EJJzA0!Te>;{tc%rZcq04>_|_D9 z>y;X=vw~M#T<`g>KqE;>bTe=OdvZj*`xhQr1_=A}d3%3(I64wuGO`o`cZIlEF9zdG z$A9w5^+l?Bz8&Zq0syn-Um%Wm#TgqOOyBKXt3Mje#1qzV{V{i(gDrA?%Vwx5dnR@d zha+9z1v?725yx2bRoAR~i03zbp`-~^e1J2uVm({}tE01ZktyKU~ zcPbri$){u6#9XNR)<;)A^pA$G0Toq^S5LC4`Xcf@UwH?B-M|n{U0ZEE-$}3YV&w^c z-=^)+#;jxAxhqfO~)`RV`m%x91Bv7ZEoA$XgjQ^x-xmZ<%9Nok^77 zCha^B03qN5nKfw|q)Ht7&94|ja?sRY+xvj#9`pgdN&i{`?uke*a34?wzDb=39CO*l z2m*_MRT;J<5Rn|sQZSc*8Z<8#gJvl%t7=(9E+zjm=Goe_=KHmSQ9zcMO3MgD + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + begin int1:= 2; caption:= 'A';end; + begin int1:= 2; caption:= 'A';end; + + + + + + diff --git a/mseide-msegui/icons/buttons/stepidisab.png b/mseide-msegui/icons/buttons/stepidisab.png new file mode 100644 index 0000000000000000000000000000000000000000..eb61795895efd2730081ac12f1d5abdb02f0ef81 GIT binary patch literal 840 zcmV-O1GoH%P)w#0K~zYI&6PoDR96&+zjH@kXEcO15sA1k3tcoyixkv_F4K1N zX3n;{bEUZHqN@^+l7$qy=%yf2>dy6eZGw!`#P}Pks z4Q6I$cC}iqbHMSObHD}Qq?w&o)j!Q_kBA%ty!XE8oZH`Sx0}Gha=H8fSRH6!W@Eq% za2RL;18X-jGP1h7yu1huJLf(EQs>-WU~zqYeV>`_5|Ja$xqqT4df46MGr(aH`BGKK za{~{22TZE!5tJS^-XfzrhPfbnzH9b9j!puGgo&isy zC|XI=^i$xLs`k&qbD+|1Fz|m6$MM4a{Coh`^XCDuk)~7cwxjof8uioe)A3SdmTqn`M~*srP2%7f`tu;Io;fhHuk&NMR4UcuI9}K;VG;BsP}Lv1%m&r@KjS5X%`&wn SrH|eK0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + begin int1:= 2; caption:= 'A';end; + + + begin int1:= 2; caption:= 'A';end; + + + diff --git a/mseide-msegui/icons/buttons/watches.png b/mseide-msegui/icons/buttons/watches.png new file mode 100644 index 0000000000000000000000000000000000000000..3b9cc1f985910ba9cf50c770c3b0f4a0a57c7fd3 GIT binary patch literal 565 zcmV-50?Pe~P)b?N@KLDMxiKUbtyo-otO<#?vh?uPDOR*9kBcfG(*QlO@Qc52# z;5~Y9E}xg+78+QN5gdw$W+`O={TRbC9K_o;s1CS|JD5(hGuVS(Y{G-oPvQ!$;Vuqi z9d@7#2QVHHt@;d(;}ag?D!yS`LN8+?jfc^l8Slk@_yxSgx+N;V%_r-^OqjFYy9TF`3zK&z22jt48nz9a-5CtieOf{068% zcH#-fF%%Ka)cbK0YcUuRUsK_)hdv{M*Z~93HV#_@Bd8~0Dp|{A77;RZ8_$-00000NkvXXu0mjf Df1vX5 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/buttons/watches.svg b/mseide-msegui/icons/buttons/watches.svg new file mode 100644 index 0000000..c8bea8c --- /dev/null +++ b/mseide-msegui/icons/buttons/watches.svg @@ -0,0 +1,299 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + ??? + + + + + ??? + + diff --git a/mseide-msegui/icons/components/123.png b/mseide-msegui/icons/components/123.png new file mode 100644 index 0000000000000000000000000000000000000000..b8490706ecb694e398f3e49de20e98c361ae8470 GIT binary patch literal 349 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*O%l>?NMQuIx9sQL70(Y)*O%l>?NMQuIx9s<#@Ol*rH4}0)-??Tq8=H^K)}k z^GX<;i&7IyQd1PlGfOfQ+&z5*!W;R-fr|P)T^vI^j=#O2$mJ9$;Py~IiuI_{3|+S7 zv$7pWmw6Wm<{e;-xYObr)AONAK}&41<7t~666@7=va|h@WaBgb!|fX~G2P;Em+G}0 z?rV!!qxUFT+AOTb)#|h`;KT#o4Yso9l@pG40-eU->FVdQ&MBb@0KXY!A^-pY literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/123ss.png b/mseide-msegui/icons/components/123ss.png new file mode 100644 index 0000000000000000000000000000000000000000..89cb326b7bac8841be8fd5a1d5c560adb86dba12 GIT binary patch literal 308 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*O%l>?NMQuIx9s<#_mH%FNgP0t!i%xJHyX=jZ08 z=9Mrw7o{eaq^2m8XO?6rxO@5rgg5eu0~Pgqx;Tb-9DjR3k;^Gi!0n-a6zfr?8Mb4WlKzJy&t{u1ZIb);LS^&6s`ci s=hP|ga9NivwOLq=tJP^?z=;RE8*F9ID<>T91Uiku)78&qol`;+0JG9&Q2+n{ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/1_2.png b/mseide-msegui/icons/components/1_2.png new file mode 100644 index 0000000000000000000000000000000000000000..eb4549882ab124b23ee1723766fa779f9e52bc77 GIT binary patch literal 303 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*O%l>?NMQuIx9sTq8=H^K)}k z^GX<;i&7IyQd1PlGfOfQ+&z5*!W;R-fr`33T^vI^j=#NZ$aTm;!0n;F#F1-GYc5qV zJAM!|D|?h`6DFlNb+4INQ)?^x2ZoKFf-XYBSF+-acmFxPCoz%3E~O*ddEX&M_cgoC z;ve;FdgvR-Yj}9?>V$^C?u6*8oN~4MSLU2tek1ui_dyx;oC!7F6Rw@J++^oFS^VJc n-xA?5SvQr$^f{Uy%(r1|3KIT%Q9JiH&{Yhcu6{1-oD!MQL70(Y)*O%l>?NMQuIx9s<#<@ca(LI|0fi(>Tq8=H^K)}k z^GX<;i&7IyQd1PlGfOfQ+&z5*!W;R-fr{RHx;Tb-9DjRB+xu{!1lx!C+ZQ^zI2O9` z@*T+$?DiBt;-3&Nxca`M$i@5wVV*Wt!ObUkEpQcB!`JNmA?V&gN3$D()Bo6iIP~!0 z&N-ipG(O}Tbky2BmMxvKJH!0L#OMv}?m5Z4<~!ajSiPWg{hSYt9P8EY@NBDlp;p-6 ze5dK9!Icj!=5vy@F7iC)I{vY1P18|>JBhNZcN}$HWO>NctuEL=zU^sC^dWV%4bAOO zTyL^IPSjA1(cHm0=jhJMbG}4f>bSaPW0Tl11M%&7=hIrk4Q^*2%v-Zi>i?d`%X+uo rh#nN+``9&|L;mmSCMH&{FM{`Du96<>!(u|!C+HaApIz)}bSM$)8|gaLRW$@~_+GhENb;6oJ$<76(}C+2L3-nj2L WHtRm*c1P&PxMGa;%U`_S>-!DJnkCu* literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/TComponent.png b/mseide-msegui/icons/components/TComponent.png new file mode 100644 index 0000000000000000000000000000000000000000..fad0f80d8885bd93f07ba610a3e6ef9201462db8 GIT binary patch literal 897 zcmV-{1AhF8P)7kdPpn{B`UW3S|-g>j%!VoEpBBBdYA}Ayk!+4#^GxwQu=3G_}=RZ2A zgJ+7M1wZ!xzxQT+_u6ai%}x>FzqD-b&-mH(E1Ko4A2crAdo0RZ#%qIXf0;Pbb>QO< z7q3ex6;euRp@1|SLF2CncVr!_K22$94+#~bOk7Z@o+}^yw!UxY)6<7gjRl0=0*vms zC1UN#l&$GuISQB{28jXUPm@!FV|$;Q-u30z^&cam(k>u_W^?7+DO=YgZ6s|b-A%fa zbUUesw9=Brg=KHPTHKHBlv1HxKnH}bhggXJG5|(0#jlH$axCcX+YCD1~ zb#9_aDp4rp*d^#B74vlzbgxdgwpO9oZUh-L8q=qlCdOz?QLACNwaBPo1~nHhMmZ;6 zuBJvxkBp@BXiBMb-Yu$D%inhthwc+4RJ4*jnr~AXW0-K_RCAy;pb1jyOdKeYt!Gb4 z>2yR?uZiIBS0~@AR{G20cj8p8(?maUo)|JVZt|7at4A?_8q|3$cTEB0 zC7pe9sBib=xraw$WOu~Ko`~VcB8Im`lzU^eziZ<8XNsTTCESKA=xs6;L=aV~J9!pe z5n)zWJ}5r9Yw-i$9bSKA;6&e<%7xx)|MBJLzc^U>VMA~BK3>Eo6eB{N&u5*_>Nr1R z3p%d{NO^U1V>_P03wgUe?=K=Xc;ag3v)a!)ST!FY~-o3%Z_>6FtUciX09vsTXHxh@?9a#G=wd0&&hUVlG@j6 zAnddD9L_3Rav1df#Yy!$;g&on-S%-X`u+lskS%bY9-Cw~)o?e&nK4=P>K~2Iabp|>IO(6H0AQmNZh-0Wb$XkdhKHl}< n9uPs@K+QpO$iv?u?i4r$UVvxd5|{z^z(cXa`}XTN@d|?v(X!l?znuM5p^nd;<$NZ$ipg)vIxO}2UP{atbX#}#CX=`*e=qr9 zRWj@Me9M3HDXLmEJ&TFf0iQ?B!{fNKZMjtIa%`Ti7DKoA)4lvScF42MbKw6{)%1n; zoU@Cu$L3OglTOy=`Pcj459rJ@L<8uCgg*!{M~|U^NCbo^0ZOeOZ6h<|R0_mH;s7YQ zx>6>>VFF=Q!Qha9Y`P_$ijx$UN#`>%V~M-K+o8LK&G+VUEv-{5GQ-4O-_az+W0rQK p4=Gork5XP-P~r4m@R;NbD#5`xL)E63aI{j2tZ{~^hfne$_y-=tS>6Bu literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/TZConnection.bmp b/mseide-msegui/icons/components/TZConnection.bmp new file mode 100644 index 0000000000000000000000000000000000000000..c59e54106356d29bb567e475f1849ca9355ab19f GIT binary patch literal 1654 zcmeH{-Ahw(7{|Z9G>_BNxwNUJHCs+or>o7EReMQSZkcUst!yV9MkpEx#w_d> ztdy~Ulyss{MS)_uCK~vV#1#ud2VOz~_$jGK&di1&TMS`NF4A)IkS-}86E0*FmY|}# z0(rU`NURdXXzY+y8BuAhgt$?R;yN1)CIiInVw9NcA-B+oH9L`iD<3WwP})<9qP`+H z8XS-h%ApuifOq8%1XpiE=}|)6>O{Gx9A&;T7zPZ8YaIhcO66BUHKIa%`(spH?}K(! zi)v>-I&OAA{X`A@xE{7K8*~#o@VlSGI&KC1fJWWmD24`yU8^Rm`odVSRl){Bvyg+Z*_A8=ypts7(@y91h182H{&?Kp&!=_9PHYWISg-&T*McttC8(wsWfD;t}GR zg3AoIa_>d%FOyZDB=ecOcQx3tBQ84h;DpzlVYx7^k&9p*!t1zsA@)b`a`VMY7i{_? u!Z1qm4d+kkh)kzTB6%%C8I?uw3gnhDv^WFG@EuZ>S=@fIjz-{rJNW}%MYiz( literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/TZSequence.bmp b/mseide-msegui/icons/components/TZSequence.bmp new file mode 100644 index 0000000000000000000000000000000000000000..d0efe30031e4d35a51e51873fc60766290180d6c GIT binary patch literal 1234 zcmZ9L?@wD*7{@<_3I*MiD`V(bU2(XAk`A_l78Gc;uH9gxrDKzJfQ*d_GUV5VvO))x zQChkIu5&JiEWVf%4OSc)V~mOMrCCPA7shCq%ij1$;JIwj#c%S>IrsB??{lA=++(g@ zQL~}hB+!dp_9Ls%Z176K|4o1BtAZ$2q*AF!PEJOxR+EyFLTYL%8jXguv@|qn=}6l& zWMpKpD|0)USy{q6$;!?qTUfhChfb#xT>|Xgr^jG0u>W8QyIs2}tEi;B%1oXsj|#H| z(_s@;)9lSR*ENzX>2`9^O-h`AtT1H5pSE9l1K@s zz3r4nOKE9;AJZih_MjcpjES<@GP*ju=sMTM&A}s7#j0rU?dJ>sQ9Akt=;`aHXRwE! zfk7&6RNx!%iRU4@edn>xTj?9};}`Dr2dMw39`omB1_EQa=3RKMdx!;P{Noc`xH!q= z#H3h5j7^3JZLCu`<4z(|5j+bXLg5I(NR;WwG*PimL@(2}(8lcLS;8}ObS!ody>gXH z!n4;tX71W`Vq%rQmZ|-<7T;|ju}|h1{brQW??!34+d}aBApW2H+_?D}!#@w>UGWnB zA@-QQMO zS^b?q|N5J?wKdl6-DB;a``mx3sdD6^=bzmnSL6t&6dpB_o{;7Iq9)fNwG!UyBc%lWvMj%M&L#4X^_SGM z7u7j(j@py)*gWEYEmN!Ol0Qs3nv%NNSQ1pZGjB@bMr=W`;oaBm`}5eFU`KX|98|k| zLQXinS$Kixs!mqY{K1Rc4tMM5*yOzJ=xjH`vC^Hd*1{&1a5y@9Ew9ns)p+&=IalyZt<`4LW^VA- ziRox0Jn)X-2CdB&v)Qx;kv~7>>k}FqK92OH)uxSUZPup+A5o~H79?!qcw;e}=-9>^ o^$M*i=9EMtFL@7&355=dBPdMtS7u5mF;9YR>>Bi1eS;+Z2jIpmO#lD@ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/TZSqlMetadata.bmp b/mseide-msegui/icons/components/TZSqlMetadata.bmp new file mode 100644 index 0000000000000000000000000000000000000000..831596834ea03a489d4bb32bc6bbe938b404c157 GIT binary patch literal 1654 zcmeH{-Ahwp9LK-fvSnpvsY^}QYQCM8+ti)4xzuU1d@0SQSx(K@L3%}<)=kt8e@Au<(;L+yQ z_<@sx2gH({z#Bf`b3Dx#cpKme4tST4kPrw20)&NyK`0bLAQ3<;79%P?ia44P$Y>!= zkRnKyg&;YJXK@{i@{ zz0-@fXKiR0Zb0LkMpRB#BIU+3>@VzaymCNucMk8|H=(&VhoLyk`neTl?ytxh{DzvBGZ+{jK+W(B+>>s&r`(treT|{1A)Fuij!UDn_%!hz_OTyW zSXfy4%l_~GPvDzYYAbnksJ{2`G9w_M4z9? zBY1Q0CNKoj13n*>$4d(LksC)F5gfb?)Xe4Kohdz5oJRech*)3ZU(CP3Xf~|l@@qVW zxil;Lp^g1fIeXQ6ywmX9bO7-Nt>&1VTxDYLeJWU%jVF8!0(VNIx5LXB9AQ~n7;zGn zGDf(_`2iJdd;m!UiA0sLgfpwMsQnjDmlM%?ey8b5x$Xe*dqe=k*(uL0h!KW|g>2z` z)JsM9VdDP{R~#)johsWeTj9?;k)26Yba40bJclTyN?OLFAWEQg*H#ET6}@Yuzo$k2 K9n0|Fz5E2_w#>-@ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/TZSqlMonitor.bmp b/mseide-msegui/icons/components/TZSqlMonitor.bmp new file mode 100644 index 0000000000000000000000000000000000000000..89983a90979f9b15195a174421adb84b9cbbdfd9 GIT binary patch literal 1654 zcmdUv`BRj29LHaaAS8liJ!p5SAfCW(AV`25k|0QcctneGgdl|ABBsf;+`=M@93~66 zNQ$E2svxU^2jESlq>N43HCfiw50;osGxqF)lTLp@pPBdP^ZmX)$M-wWGtc7_oG})o zxtM~zxSBjF2^L1azyx}&M`Q$}P9l*YF_B_9Be#AKGy+92S;3G4g|YS z!_C!=rJnXI^P0g5@0oadcoOM53%TEHq882})Ylc;2wMXEyog!k!2HGYi3@Nb;w?AU z1UZo)Dlu5fip3rTED9iLiHzhB8Ieo8Sr_U|YM3+f5MN?Ky$K8rBsR>4xNtwFr%q?t z(g-})c(QW&N^){Q9w{eYz8uBs5S+4{h+Y*;#K*&VT{C899` zO<^jUqBNRI)}h_1pt!J@7L|hXl43MvIfU!Nk+;gJQz@x0SE4FYQC?O~g{qug>OvA) z6HsqcQ&CYtWkn^2Yqn6Uu3&#nK26o7B)28gS(k&Zu82-eKKlB6j@1`%q9Koshc^=1 zABtwDhOS)&9BnM+P-8h=+CnzBZ>GDcSX2q8b{C^k(>dB&~wTi@RiS!+)qW3^Gr6)`2J6KE4 z!5y@=w4&-((W`4DdmtNipBkM`$EEfrE_O7L|3yCiCtK0$^;|vO#*H2wm(S{H8)##o zSI^M7c5a^UKzB{Y&;>oZ>pD8FcktcN6>i-exf4Vkj%Ix?-EiG02KwU^UgnIbq!jpd>{ zfa%z$o__vW36>MR1Utt^To9JMiusI)gt%yD(>F)x%IPET%Vfbjx#gd8xk%| z3tszn;Gzjr-zz98*}nhO&Uu~&&hn_d55ofd#xLD{_GDdE<;Ta~pKRn&QF&WM&g$OF z=ep{vN)8wE7+*-zrE6C%bk(U^3MHdltqBWQXuayhz^DD^IxBXhP8#Kn`@#bJZJcU) zKD*j~ac{n>?u&ajJUJz1jz!`K-*vR1 xRJ69{CCp{aiz|#&tlwjx22&XCH;RRgEM8-v?~1?FN6Z*M@ELhNK3PxTe*o6!$X@^e literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/TZSqlProcessor.bmp b/mseide-msegui/icons/components/TZSqlProcessor.bmp new file mode 100644 index 0000000000000000000000000000000000000000..a6b15c5c597ba8aed9e1b10378842ba1bc1108ea GIT binary patch literal 1654 zcmeH{YfPI}7{~uWX<;y!`nat+FVi^}@0V>}hSK4tbGi+|Ejpbz-PKKH#nJ+8DQq3< z1gh&;H!cB^fyUXfQi6#ZV~mN3BqPC&AT9K=(yp|NAz@=1A^5z#FcQD`%`ZO5?>*=I zo^zga^5%U{&W2(!BC%2gEaTq77zs#;cv&LwYetlah&_@L6Cf5PL6V$=RIv!D5)sl; zl98S&M#dZg2{O|pn3pcWBAN@DzW~dZN_n*oYqGPjDq9AbOopu0IVj9qf!s~GSf87R zt@-P)F)trF9k69v0Sb2R#`ax%uw(B&>{qBzq$q|`p@dSYgj%IQk*WkG$`Z&`rI44Z zp(xWpqb`G5t%g>kfmW-9v7!hn-9c1VRzh>=F!Xvobowe(R2g7kYL3=GUtNn@##B=c zqtS>uQyq+TW|)tgaqLt*Os5)fg4=HzYthiqfTsE;G&VNE(qck$Q!`qcTF~0u3TsZ z%!ETBgu)?&!(se&IfSvXF^rFoJ>~(OyK&pYq);n1|}ybF*P-X>FMd&pWgrd z|M(4LN`=V$M@XgoM@Xex-`f1frZ+d|zP|p|=oI$C0wg4fC8EUSlni<%l3*t!_Pj!r zz3n9;dSo6yC{msi4fH;dRxp&tHj{m%{=*L~Bf5|1VBAN~bMjnx-)SFLi zA$si?Q4!IcNF8Bw;S~~nqCQOYDN%adv%QV|yHrW^+0FUO@#I~1-?4ybqcNY4vo19@ zAGrVV7vFghd}VxTG=A|h)(W+``u?nibMJX!J`6`|Yd$x8gqLF;58QdnqNRZTi2l%# zs@+%<^{b$G{;3s@;<1YIa$R}(F077v;h66+suE3Eaj9wto{Ra&`8OOW+$)#M3lDsN zr)T`}eK%t}ZeJNMWH!w5PjF2{GQuS`6NbglzWrg;FUhGl8RB6o*eSd9-e{#I!qQn0 K)A9ZPP5U?Jmz28z literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/TZStoredProc.bmp b/mseide-msegui/icons/components/TZStoredProc.bmp new file mode 100644 index 0000000000000000000000000000000000000000..937532fb1d2349e50816ceaa3f87d4468bd61f2c GIT binary patch literal 1654 zcmeHHOHUI~6#n|KFh1bY7gIW1plCrWS_&;%snVLjLfjZ(4GY6UW4bV74GUY0L~RB& zB~45uD8VSWGI49tg(fUy=@t`02;#!{3+kDfJ3-Nni90#Tch21JJFmHmo4KgEU|7Nl zbkdhBU_-6J57>eCbtVi#I2%QW-3Gtk4_THGY4L(Lb8ybl)#f8L4;IP5-8}?%j1V6} za5M-$#*w`gN9bw@BbP@Iz8OY74N|>LWK}=i0Vp&6ODTiKd6+I6> zVtjH7Q_E9Gls;i;;W_%}HjrBUg47Gb%Wb4y5ta$Bw=wo+9T(nyh5Bw2YGo6*K77Od zl`RxkzoS~MiksLAdpGcZ-GJoPP5RBe-gG+slhDr06ylA7R>s<;Fk`GmBFFSLx}dPb zbkG^yQ;D8T0&JZov%?$xWqb3lyt$7o*D`iQ?_lLi5_ljGkQs|ff98)`$yA~nPSX3u z_c7KXMQEK4b06YOGjeu0>^fV=f5aaaP{}a zd)gdk0ir&S$8Y|`!0Eo;Zn2$$%&Ei)rx-wj=&u|~olPES+!<``qtw9F JWYK>We*p1rdZhpW literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/TZUpdateSql.bmp b/mseide-msegui/icons/components/TZUpdateSql.bmp new file mode 100644 index 0000000000000000000000000000000000000000..99a7b602137da81ca1c6d33a969ece182b38f1f1 GIT binary patch literal 1654 zcmeH_`8Ql=7{|XvA|wp8l)h-RO%rXJv_YhlS(q_nVo8D)u~q0Q_90av8ZlxlgBfET z#LnRMXwGRv?fY&fZO&?$6#x13ENYa;85&N)7-`uc6N5Kx3`CzqYd27 zS;OI?0~{_n($!^f_I8Goj}u&cUE%KI4i7&MobmI7_hoPR`uHL+Fc3U04_+x=$iCr= zsE8;8+zvo=bTndOVh|S>hq5w2kQt2R% zq=?nV()=3IG-;3yhNGgQ0vdTS5_%Kya8Qhvs(WaVKftYlBqXs6Q-)H|R#T4j{&Xab zB%!0W95v&SNF7f_?&CaYm6gcQWuUpfmQshz;XBCIWg}-S2e}iuXj3;Mhhgs;$i@qi zKbcP{KwoW0ub*8tUA6DB8gcrwXgYU(Lv3e(fmn3MGXO*08?5j*X2CY;JC1cWWJ6TbqO|MUOw1vs8;aQ+pZo(#jhG?79~CDa=i+$Q8xP9h;BnnMS|wqYmo$!COo!5Wf5 zlR{&AIsr3tLM#ZeG+rmZrQX=Tf4G2x&L#^)pG(7UykYXD zK8iDr=>dU!=3YcZl-+yAeHArIrCQ^X_Hj0SN9OymYhKPKuc)hQQd`}>%*6RK-wDMM z$w}59^+BaC<9+1^E|(EY!1~nG*iSB=d*@h1aATQ|M z*V+2N!%3d>K_=tlbM=-j)i1)${lS;P-+UAk|CZYe$!2a2ykgl`AvUjQI^${$YuA4k Hzw-1K9RrZk literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/_sta.png b/mseide-msegui/icons/components/_sta.png new file mode 100644 index 0000000000000000000000000000000000000000..90a30ebfc1dfbe61215c120951f6d0941b8baeb1 GIT binary patch literal 333 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*O%l>?NMQuIx9s<+zP?>^%?X0)-??Tq8=H^K)}k z^GX<;i&7IyQd1PlGfOfQ+&z5*!W;R-fr?gmx;Tb-9DjS+kk8Rkpy8pu)ZAHqN_vXx z8diw*Jroj}>-CtcMDGDt30J4vW5t%Hw0I?_PxD;1*Bj41lk)G(8@-7K#R#mmU?~_^*41U8j)uxu)JjR=Y>-JuXTU>p!x*3|0BD UY);f7pqm*yUHx3vIVCg!04Y9t00000 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/a01.png b/mseide-msegui/icons/components/a01.png new file mode 100644 index 0000000000000000000000000000000000000000..082722cf61d670a275cff254d0a4ad3e4ae2e025 GIT binary patch literal 348 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*O%l>?NMQuIx9so8$)GRThgn#rPhse7G#*fQ{6C zg~R1**0z0?e;>+NT4Hd{^w%NI?SfTWpLd4(d=wGh{-L3CkILayZ&-CNo_ksD^QfzA jhyLb8E=m(U{;=QL70(Y)*O%l>?NMQuIx9s<%Gm^j`(($0)-??Tq8=H^K)}k z^GX<;i&7IyQd1PlGfOfQ+&z5*!W;R-fr|1yT^vI^j=#OIk@t{+0P6+uBXW)+GnJVq zux@e_OX6(f6fKoFWRiZeHfCYgKMaI4VowKgYD05dZ)H literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/ab.png b/mseide-msegui/icons/components/ab.png new file mode 100644 index 0000000000000000000000000000000000000000..b57e2a62d898cd6dc4dcba2b0f5d37e289acf4c0 GIT binary patch literal 330 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*O%l>?NMQuIx9s<+u$EBb0W3olGmoV0h(QongZdyUiAeQL70(Y)*O%l>?NMQuIx9svV>J;_}%58A4EdC~IzasB<$b5~qcdkFunl4{>F7bf(>xaDLu6RwC z+MbKcXQbp=xQmO{JY-Y-^0AjcX8HMP9x6h=(|Ao=luk?)QL70(Y)*O%l>?NMQuIx9s<#_l^OTq8=H^K)}k z^GX<;i&7IyQd1PlGfOfQ+&z5*!W;R-fr?&wx;Tb-9DjRdy%$TN49kc9{|+ubheX#) z=y8}$KFR)}>1v8`hvyr1GkFJtA3}>xK62(*bTQ$AO4o^n@1{mZ_;l|mIN|s6+=dUb z`;6_U{cp+@nW@TE^H^zDbMcyj&)r*5oTmio^*$23*pbo;~InibFWc~|{meEo8TVDoyfi@h#iI`Sr~ kzJI>Ic$sUr*yCQoz4L8cCNV@80X@y&>FVdQ&MBb@0Ot{!!TQL70(Y)*O%l>?NMQuIx9s<#+^{9Fyj;1BE0@Tq8=H^K)}k z^GX<;i&7IyQd1PlGfOfQ+&z5*!W;R-fr@r{x;Tb-9DjS!(979Tp#9_gPNxYIyefJ_ zyTUnM7B$Ey>}&|%AX0ts95csGw+pA#+69{A6jvTm5PNj%%%Q_s8+m@48q0GVpQ*PL z(VMs^O{ngJ#Jz-8|2;`jMmxky8`aPJ-(zmk`HxY0&O@_39mzR{$MkICCltv4YrI(h zXl7~K(hqwQI%zQld+g4_LL?9aIO6^hsO mmFmQL70(Y)*O%l>?NMQuIx9sl2MS4+xJHyX=jZ08 z=9Mrw7o{eaq^2m8XO?6rxO@5rgg5eu0~Iasba4#vIR5ssBA1h+NbAG*oo62~@wjy# zOfib);qPJFJR_$0sA-23w3N9YdG@?P1tlW+FkRM>Xnk;tLyp5*2)Yl@EimQT8^vWQFg zPLa~8jXWFmmYu8?{QL70(Y)*O%l>?NMQuIx9s<#@z}xcW7p0)-??Tq8=H^K)}k z^GX<;i&7IyQd1PlGfOfQ+&z5*!W;R-fr@H9T^vI^j=#OIk(bGl$K@hBQ)k1RIS*bf zU|7d^YeCED73^J&LJF!14mu~-ZBZ(1`!o6DiAiq_{~uypnzi^rb8*UtJ+C^rzuEug zop$lH_>Sam_piE+2Q_ykT<6ukx}7!KX0g6h;gL02|CfozU1Txm*(z7?R%nl*=Oh)+ bNec0g3dAmZam{}XbO?i|tDnm{r-UW|2aaWx literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/breakpoint.png b/mseide-msegui/icons/components/breakpoint.png new file mode 100644 index 0000000000000000000000000000000000000000..616e6c494eea90ba56a9721258f18dfa64363148 GIT binary patch literal 382 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ zFuwp{#;w&s*+4QViWrU%3^udOgE`<_-Hi0+d^7OD^avZ+p>~ zEOX`QwRH;w4_V4xJQikoi}i1>fL=YThV}j*dV0#Y7k(BvRA_YI`L>W_DJkr8S_I01 z8P7`Hmz$ljlu7JrnN~tXc;%trHv9Q5=xVGw)AVRoy3b^W#}e%8MJF^pYWt^~|3Z~f zq5tEXuFHax=R}^%Ir3z}ZsmCe^2s$TPn{S0TX1UijZdWug1QL70(Y)*O%l>?NMQuIx9s5`Z?Hl3309lF6v<=t$|1OCp|jtQqUBQL70(Y)*O%l>?NMQuIx9s<+x3?8VU~H0}4r&xJHyX=jZ08 z=9Mrw7o{eaq^2m8XO?6rxO@5rgg5eu0~Iazba4#vIR5scA=e=Xf!2rmhGk0M%EFRX zns4}`H|^e`Q^66@9qa;YboMqp5Omqt>D%Jkp&}?fdH>DUnYHiF>hQ9@Oz742lVIDL zdT#cXo`YP*Dl?Mf9ac;^$oluqyab_+C5;hXv7*iFQLK}eNrW0&unU)L_>mwm)v#l8 zakJsAnLoa)T_0WgUBBwaqc&wW$F~jD=S+C(4_ud*{BM;QqEs1jUexqTgL;#`^0V!# S^ELpT%;4$j=d#Wzp$Pyf!*>J# literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/d_t.png b/mseide-msegui/icons/components/d_t.png new file mode 100644 index 0000000000000000000000000000000000000000..d3e1f5ac4a87cfd706304be0073d13bb7de039d3 GIT binary patch literal 242 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*O%l>?NMQuIx9sQL70(Y)*O%l>?NMQuIx9s=@>_MVfQ z8W^*F=<7VQL70(Y)*O%l>?NMQuIx9s<#-sR%Pxps2MS4+xJHyX=jZ08 z=9Mrw7o{eaq^2m8XO?6rxO@5rgg5eu0~J+!x;Tb-9DjRhBkv&t5!Z{%hf_F2)I6rj zMzjjv(2uPW@a=M#>~W$6F)RxOArP7d|;_ zZsAem$)ctolxG^<6Jn=G(a;%HLf$oj#Q X5o?@2Hz=eA=nMu=S3j3^P6QL70(Y)*O%l>?NMQuIx9s<%D>-PZWM_0SZZ$xJHyX=jZ08 z=9Mrw7o{eaq^2m8XO?6rxO@5rgg5eu0~Psux;Tb-98XS=(0gDn@;@mdfx|_3`7BnR zfW!5Pg8$DSIIy8vO6)<>|MY}}3yZe0_B@d|({hYIB_ZL5Z;SE@xs(4T-41F0tu;ilzopr0FaQL70(Y)*O%l>?NMQuIx9s<#@EsTx;Tb-9Dh4;A#Z~NkE{GV(TEn^8w~A9 zDq_w`Ga3~1CM0PExbIvd@yo}zK5jODy<D49GnvO#PHue`^} z-^bP0l+XkK DnOjow literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/enum.png b/mseide-msegui/icons/components/enum.png new file mode 100644 index 0000000000000000000000000000000000000000..2e5521af1c33d93a59c660dd5d5036d0c0fe19bf GIT binary patch literal 286 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*O%l>?NMQuIx9s<@j|hXB=-l0u+)gag8W(&d<$F z%`0JWE=o--Nlj5G&n(GMaQE~L2yf&Q2P&%cba4#vIR5sMAs3S)kK4oii)ja?E10TEgF{9%U5ll-m>Qf5`5Ksr>3X^95h?WUmxXF0J6w@0}}s?q}>|70*fW6--^c W3Qt`u_8$W}g2B_(&t;ucLK6VRzGF-P literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/file.png b/mseide-msegui/icons/components/file.png new file mode 100644 index 0000000000000000000000000000000000000000..6d3b9b427c12da3406044d266e55cc391878e101 GIT binary patch literal 264 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*O%l>?NMQuIx9s<+#m_7HV08%$F>2jVN)>&&^HE zD`9XhN=+eBQ-Ln2Z}dbSStiiK>< z1`{(^Xfrb(HrCjtXxbss!Ldl1hlghy5QhPAx+bSmjMyK?q6_&^5e4E>Ca0#j8R>D? tNJvP;IUMclOFI;3z~y#OV}U6H!>MP=b&9QL70(Y)*O%l>?NMQuIx9svFJj6R78Qel*y?nZbo|C tH4+jMaSliO`qB;s8gRKC)L3B3z;NoBa-CxD#0;Qy44$rjF6*2UngEALNZ0@X literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/finishi.svg b/mseide-msegui/icons/components/finishi.svg new file mode 100644 index 0000000..556ad5d --- /dev/null +++ b/mseide-msegui/icons/components/finishi.svg @@ -0,0 +1,450 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + begin int1:= 2; caption:= 'A';end; + begin int1:= 2; caption:= 'A';end; + + + + + + diff --git a/mseide-msegui/icons/components/fix.png b/mseide-msegui/icons/components/fix.png new file mode 100644 index 0000000000000000000000000000000000000000..fb35a7cec7c7efbc72a2322e76677e9e4f0b9512 GIT binary patch literal 293 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*O%l>?NMQuIx9s<#-qj*Jj^g1PV!(xJHyX=jZ08 z=9Mrw7o{eaq^2m8XO?6rxO@5rgg5eu0~IxRx;Tb-9DjRxBPWxiK%YvGx#)Jc?Vnb{nfb{F z7}IsK*bfMWuUTd`Z?EKK^|Bp_|4;KB`=k3y;;d%L)&@559H;fp=3AL|J!%q}e&s2< e&m@(f?EHVUWz2pb{S^Xq3xlVtpUXO@geCw@{$+ar literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/gdi.png b/mseide-msegui/icons/components/gdi.png new file mode 100644 index 0000000000000000000000000000000000000000..4654d2542e005ce4c1700e821484217de4e38931 GIT binary patch literal 287 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*O%l>?NMQuIx9s<+#l>jY1AD2MS4+xJHyX=jZ08 z=9Mrw7o{eaq^2m8XO?6rxO@5rgg5eu0~J+yx;Tb-9Dh4$H&=rJk88i*y1EHFcD}y< zTe0biqMqiIOVjMG$!IjH-7(qDxVTZc-~hKwpx+mZwcW*`kNS_v?r79i6uM?=+7Z8v z$=mIS|E((yLS-I~E?LrNr1mE?aqjq{m;U_v=Y#idPdb0MUZ86B?I{a&jd%_lxcy*! Yt*O=Y|Mm+ZpeqQL70(Y)*O%l>?NMQuIx9s<#<`m{C8cy02Goeag8W(&d<$F z%`0JWE=o--Nlj5G&n(GMaQE~L2yf&Q2P*3Dba4#vIR5ssBA1h+K>J5|wdSKr5ql;c z7vO1P|0vh>KvbvcVvhJhous;Hf=^nH2j5eB-psqZzO8>|qGwc)>7CVWyJE$g{)v~` zmm3^rHP?AuD|&O++68rXo7vqY9!D%{7XCIPIl{@{fQa-QZ;p90j&!`+y5@Rof*|+4 mV~6g`Y&aV~PvzwO&rCa376N9I#pUXO@geCwNn`(Ig literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/key.png b/mseide-msegui/icons/components/key.png new file mode 100644 index 0000000000000000000000000000000000000000..d6dd0e772ea77453cb23237854977116b3e795f1 GIT binary patch literal 348 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*O%l>?NMQuIx9s<#@Q%u7q#&0SZZ$xJHyX=jZ08 z=9Mrw7o{eaq^2m8XO?6rxO@5rgg5eu0~Kxeba4#vIR5ssV)h|NiQ^yrg;Lh=@vIIz zJSQ^I5%)4dzM_E@o?!Q+-n^-B@+`E57Rg>AoY*C%3QsPXF%ezUYTj zuGspV;>t+u^O9ub|KXy0N4w1M*28@ldVX=vR$}Dl5&quH7dNT5YKE(=<9?3=4BjS( zWDn0T;0Qk|)?c{k_oDoO<5J~6eAlU^_J}UKUKS`WUvXIepP|>Y*BkeRhI!jR-hIY? i^YPt2YLidKSTO7Rs`>m4z4R351qM%7KbLh*2~7Yy{Cuzg literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/lips.svg b/mseide-msegui/icons/components/lips.svg new file mode 100644 index 0000000..1a44622 --- /dev/null +++ b/mseide-msegui/icons/components/lips.svg @@ -0,0 +1,102 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/loc.png b/mseide-msegui/icons/components/loc.png new file mode 100644 index 0000000000000000000000000000000000000000..ccfd58599495adf1c151e065807c7117fc53c14d GIT binary patch literal 353 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*O%l>?NMQuIx7%**RGatF$cl0fi(>Tq8=H^K)}k z^GX<;i&7IyQd1PlGfOfQ+&z5*!W;R-fr|Ecx;Tb-9DjRhqgPX)#IcX@D|r<&Cp$(5 z7vFVE4p+SK>PD|cC1;-NN7lD%d+#~~gj911z4*lSUP0@A*c^MAipu}(pAQ^LGmgz&ZpHZi#gRLQvy1XA`gV4Hwqo3W zqjP6tWYOjuxhdtnzkAkApIfi`y>aoAb+1|OJmC5*@xW}S^_+#G{qZ@$fp&}jYt;p| p=Iy$FlzCaju}-Ij0UCc&#Uf&qw{qIpGXwp>;OXk;vd$@?2>^tFh-?4= literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/logo_mysql_sun_a.gif b/mseide-msegui/icons/components/logo_mysql_sun_a.gif new file mode 100644 index 0000000000000000000000000000000000000000..ff6da3b046139a474cf3f634afb7dd3f799a6de4 GIT binary patch literal 913 zcmV;C18)3BNk%w1VR8UO0LB0S|NsA3gP#CskLHgWP$-~mz+vMt7g`w`W zW$?RonzY6FS z^Y-}D(=whk+{m%WQ?XFe4c8Msce#}z1ZS1g{AAGM6JWn@bvfUp+D)H zGXDGcma)S9`0;_Fx3$RB?XFq*`~2qc^vmGrZj`JNbC>-6{od^H{`~r?z|Q^t{`dO( zexJ1!beQLn9{>LQr@qa@+vWcM|Nj2|?5R)h_4tUUx@eE6$JXDHuEGBP|5=2f{QdqI zcAD1U=d8}#pSQ?Qm$D{*pg@kRS)I1*^!H$)xeaiYUWcLqX^-!@aA%IFHi)O~uwL=N zevrM+qsiBgtiN5KxSz(=%Glxm|Nf@R*l()9>hJUT-@fanNcGU4EC2ui0CE6C000O6 zfB=GngoTEOh>41ejE#*GaRf0Gu0xf%cBpt!ei!CgK21&56IV8~Ag$}ueOC1hs83J&{ z+}t7pw1-O)umnax8VE@D5f`DfK+U z18^ooiyV&n<(P97v?Mbj0MuwPMgX0uYQhLeBF{A>!v@x%4q@++gE9-z`EK+|z#aeu zqCAIGrQgcsg|8oJ;Wp9>0d}xUI)dg`q$;q*MRvK!DguSiPeY-4&70Enp2C zG;{Q2pC+}n;njelz>|Y=2zrv401~v;U?+Oi@YqKaaxzB^Yhak+CL-iu(ubTlP!oxr njELfjEVk(4i!jD0QL70(Y)*O%l>?NMQuIx9s<+v?)o?o`g0}4r&xJHyX=jZ08 z=9Mrw7o{eaq^2m8XO?6rxO@5rgg5eu0~O8kba4#vIR5ssAz!1TK-)ugA-@M4eGbYQ z7k0APmR~GXVC{_4cA3NYF?-pB-lq90zWJJ2e}0>`f2QZOGqXizsNK@}vVMil(Y;UB z{O&$ApSLf=?am>^oz_P*!E@KfxVyy5~g` z@3V;g6)EzvCWrn!=1XX@KGw;nJjXfuY5(+-DMtUFFz$VzIP;dA(juTM89ZJ6T-G@y GGywqj26Wi~ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/mem.png b/mseide-msegui/icons/components/mem.png new file mode 100644 index 0000000000000000000000000000000000000000..e2c6a46cbec4941b94c13787a294b6e0fab62ea2 GIT binary patch literal 318 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*O%l>?NMQuIx9s<#?F%Q-hix0EHw=Tq8=H^K)}k z^GX<;i&7IyQd1PlGfOfQ+&z5*!W;R-fr@5&x;Tb-9Dh5>mg}$qPwW0!4%6e5ofR+K zQTS3PXQL70(Y)*O%l>?NMQuIx9sp7}0{f`I|tx?G*}59#^&DZP^o_I;Oi?q2r%IaBxg ziJ5vmV*M?-UG~p@1F7fQ&o26;WmiZ~IUvrrQSPtNxsQ^6P5KI()<9Ei0VzvHZp%U9}C7&pzH!+IWzC znbE!u`;5m-(xn&L^fT6S+{~P_){%X!_@WJ6o9kE}7&Tox`Q!PMcO3IpMSTgs@NVOj r8{aRyXWP%3tM_rgblJ5PADi=QV;%DfL+88!`klek)z4*}Q$iB}m`|Gl literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/mes.png b/mseide-msegui/icons/components/mes.png new file mode 100644 index 0000000000000000000000000000000000000000..4bfa4ffd49f869ae6fab3ce0c9b226a01c460e5e GIT binary patch literal 326 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*O%l>?NMQuIx9s<%C#8dKVN`0)-??Tq8=H^K)}k z^GX<;i&7IyQd1PlGfOfQ+&z5*!W;R-fr=J-x;Tb-9DjS+kk8Rk;Mhm`KySGy+qw5t zO-%eA@Nt=6SYZ;S_kc;ry?|}vgpQz(Cch`?irDC1d}Dv}%y#3GHM=Lr3dv7M7JU0$ zF`VE+qiHy=@Z!94HfWmTchBlZ=HVSF+sKi+Jb19U8d Mr>mdKI;Vst0NEpSE&u=k literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/nil.png b/mseide-msegui/icons/components/nil.png new file mode 100644 index 0000000000000000000000000000000000000000..80f13a799a1a2f91e6ece9f869ccd04e19a29752 GIT binary patch literal 254 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*O%l>?NMQuIx9s<+zPR_yW8(0fi(>Tq8=H^K)}k z^GX<;i&7IyQd1PlGfOfQ+&z5*!W;R-fr=tMT^vI^j=#OMm$M;&$Mqq9w|V1Y%l4_O zcl0)AJXgE5$0_b1{|r5Lr@U3n(@=IRZ#!{ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/par_env.png b/mseide-msegui/icons/components/par_env.png new file mode 100644 index 0000000000000000000000000000000000000000..18ab47e59bbff666cb089cc2b9095ca7f45b4bc2 GIT binary patch literal 470 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*O%l>?NMQuIx9s<+x464>IrR0}4r&xJHyX=jZ08 z=9Mrw7o{eaq^2m8XO?6rxO@5rgg5eu1FbUjba4#vIR5sEueNKT1nYzLPlk&2jysiI z?@ko*{517_eS!vaaPWTz!{jI89%@F$1}PdmF5lJEK813X`reD)eOYw-I?k}U=kC3) z`yTbS_L|k7$Nr02eD5Uct@K~mk*<^e>-#Fv8AnylO|BBYb+NJCr~Y|(%hEG@3_0Q_ z|1v2nj9j>X-7VpsL?(65zkeUjL7iwUdR+HKg?4ihd;d-q2DR`lu3K0b4h9nRn8FG@4%srE2k~#YOqlQkWduEc% zB(Ofu{+@X%)zxpk_13T6s;;iC?qDv;1^>k$fnRC^ev$YuYl+~$tR;f~vX%&lOI5JY z)`bNf-|qb3yQ4q$G&a{-Pg^^vREPcgd+xsD@uz5+8S~2=Ue~zv9>s{sBNRHFY1Hxs zR}*R>0Qd;?r7|A7nAcFDt?TErwO@bp@!|3<9=A{??*;&sEHJe=%V0=X%6z2Z3IIsc zPwCK=qAa4;=IS$B0KnCJ?B|*$XG^oICl%`oQYplk2@}Q_U1u_tb*ob@S``p325UlF z*DJ66x#Gx{tvg(~a$bJ1^qSdI4CyktB7+pT0YC)xGWi(3Tm}G`VmuHzOh1zN_fgKH z01$9{Jnj>I$O3@+^WNrj9E1OWIU%VV#oIOVCRw&#tTzijEfgjzUE^bI|0+cs_f$4h?%faz0( zD;H;{kzFC44gh+|0!WxICYam-K-2N<03d>TUg&&_D`nUB4P%N%PhE7sPgI;tDN!+G ztVx2lU0)q~;?Z?}w|CB5^_;STJYzdLC05R+d*U!Pz9eWv^x2MY1OQ&>JOETRX!h^^ zY0~URr_Eb7wB-&BYrb~>{VSK&Rvo%}CVBnJoHViv08nRSj$Fe!+%R3Q>G*c!bO6xe zO4)bBwffrM2rNT3-VFh3AHVR&jT>IlXR23Ur@FG3j}k*XoqFuO0K@2Cv4H%JavnW( z^h?x!0C4O?s2z;g-Eo9(p6l=bA|N8r`|FL}Uip8nd%*~@+Ol6#k zX|97yIuS+OH67m$j>BSk2mo4KDHW$Yi|0OyoX#2wC9FJg*6I#c-g)C90JwK;`W2%^ z$g;=~HvIi@fROn2H67pXu~(R7O#sk^tB#!rY4YX}mU*w1TkEKv#MCCp+Mf5{f8wDB zM&?WJzNM%rqq+-M0RWl3^pd+67m}cjYXA4CqhHFf9<{VB+z~qB%)?UEw$Zn}`QrL& zfhhr*awx@*c0ATZK z_txvLTf3nd&qzSwpjks>|D3t%JC_)gcuTib8yWcjQz=8Bi8IL^YH1q)*u2_0x00UF zMZGe_N*^3+&pf(r=er->vQoF8Os~XSa52xvAN`+C83K#Aa7V}yPCHZIGvlW9gPjQv zg0=N`-~7$%pD({%vSMD&FUZSSkofoQeCx4E*>*bRr?aXVH?0r4j5eNXfJz3+8XC)1 zEKWs~0YH$-mrcKKIPO=58(iX!IP(T|?=>LS4t=)c;XBsQV;KN+OSR;P-(jje_z$~c z4g`{*jj~tm`sAscECH&HBb){R8MEITU|srO0e4he?|$r8lMArhXK7Fw03cS*##DJe zLj8-Q3;=wD8dK$EWzRfQADOQy@s_Zsr|IyEeU_wRqkmspF)0uC@c#O=Qcc=%r$4L^ zx%4a3^KOG*pqDWr3EK8-U1!8v>3Z2*D*f0wIJvst0j{6t2CqH$Olza<`QMGwQq5ry z0RUe$DgCnPN%D2*vmO8U)rZFqACSqrvn|u|^K==8tgPItj278NYY88rp1SD%&!4?- zR)IgP5CMRiw6`ALVO&_MC;C~Ki|1?T24K}p@zVK5)F3u_wxRHG)Hf40m!2dqDJ1E{ zQx2-T)pxiCHx&q1+_*Y7XZ7%{DKa6b{(SGYS0|3E$DMuv2rESG?r~X5UP_QPNzgX6 zV6rh2{&;JKmTE>CiL6xu%i1I>^Xt2Az^vasa_el2YDAima+^y903N4w|IhOJ_JaU0 zqvUo=$>QO5z;_-VGw<@q_yYiKm_chQ5>5C`oI+#v(0{%0so(9r?fy}8#T?DNMYSRv9<&6Y{fh8a9gX}j&6kN@zu+V)O`Mn0qD z_L2oF{CWddq0rWq%wwv%9@+TCD-X{qi1?b;+1yqK#<6Eaw(eL1Ty$S^R9lzKEWT^8 zdeyWZq$}jimy}M!G}k5H?3;f3kleikX+~(n40PLYff)RuroN@Mn@S7*ep+APGrQ zCbV?{fStnZE(hl60*ELVmOhw?=LMYmT253k`z#GD)vP7KQUn1gs&A;OJNU+5wmy#> zaCGrv9bfat8~?cB{%3PD6$uZ8OIN-B_On+OPwP#=t)Ek4)RGugj>4Lw+WOD!yFYj! z+hUBkVE~GxuK_ z?G4B!TvdEHWHEvaQ;r!U1^{cFr1s=z|65}xuv%#dlC zKUgDt?f&V7h3RtL+iR7Vjmof))qJ-jV7|bVyH}F$_URQ6u@(2JjD611;8{vD4TS&@ zaC^dTTbi5nJE{~EP}u-3&}He8p$q^7mdQ@&Y;|ffaUV+2Qq3(Vs<{G1tBs3znP9?vBW#KfyCYvf%C`)P-Z$Rn~u?FX*)a!@4QwQHh4VsMF^@)YtCc zyLHdvBA^{D=qX4Wvz)u5AU^J1Gv6eK2Ulao=1#ii^iai(&@w2(5%8vTVcXNgN_}Z~=KcO`EqyjVF zeF&vE^*bg+)LtMdE@4`i39npizCR)mFE0w&TTkv0J|efE!EDe~@^dE=BJT&MC8 zYGtn4+3vQ5nldl=65s7>4cAKSRYKlGJB880eOPR-jZvSPBzFe7e$d+#MTk{gB>y?8d0`|$M=Q@ zm5VMke#n&9%bU%L)RTXEdVq^!1A(PvvCY%d7|x_i#9WkwI^R=gXO_~-TKT&l8`V8} zc{7r3kQs5F36l#Fu<5B6zCT0hTipg$RcSQHj9pl93l@2*7K<9zSymhXcrL3vWVe3z z_n{&#ofHCq&+Dh{0f0=r5oC zwXpQ2M-XvzVhfhhg%x*X%?M}TV;s9iP%=@o;M#EZJuO&9gUlGGx6%<*2f8wti%O%K z(x@hX<&Qlz`-g-$icq@4p>B7WWkz%Dc0w(bXhi52xf;|~R#F;#j5H&SiVPDCGNaKb zO{{Dmp$1)P=}l1e$qVidRc`Qj7gnrUFp;k)#^eGtkLe-QlAsMNU??fGezL8_`)wN4 z1OTzz6F4N&xJ+{5=Px#nzJGFJ)-u5-I{=^sQgVDH5-9IY_l7BZ60ZP4h7%annCQ@z=C6G-w|GI5qQn7&z_PYOSIV4T(G#xB*-!0n_MF7Dz+q${ zz+99(WQRisl6N;Bp;nJs#&?4xSk5{XaC+%@gtY_Z71MPp06+~608-wFBrS*(FmZYM zf|v9qH^ymzZgooj{EgL>A-c^HK*Nc*63)wnl5h8l^H`RoQB8!SUewy$JFW?BUA|zm zj0#2ihz9@wmj*DoAV~|5H~IC3p4@&`BeF9BwXROWBcKh48ge5jOrx5>5uof?UNT?Tsypc)f7;t)%@1%kh7r29jM?h=FWT1C90YK1YL_G!vfbTweS0?XNQYo|% z?Ot<|We*mwZ+KD-!Bm`2bA+g&If~_gOj-#?eeyS?JzXRK1Z6$Uf^3)>9049ygJf_3 zIA3=PS&Wj9sL)h+(H^qxdH?+%%l8&&`rO{pT(EmUU-VMu5p*={N#56v?AVL6F%vaX ztI&6zs;v~CFZZ?k2>@_5e9q0xlPDxX+prRcUJ&}ty5;AOwB0mCIkP~frmP8TQ&ZL; zEJ)rYdvkr4Ax|US%WN&m1Asxu=j_&%O3>ZAx2Bub&cltmgO!KNKmYij?}c36t49j- z*J~$aq#ChCmKf%yD0#e90H%NqGm~*d2L>$Y@Boz~ZEW|NHSStw>1xW_>8O$hZ9YOx z0D#Rc2a6xIbH9crgVfV?FTb_%y|>=Q+QVsB5<)&_=g@UeN452} zSDyX)(=T)7`kQjdiPw@ENfRak&c7MCgdkefouF&k#?3Ll&l`r$XD zbe$Rr!Sx=@O@R`Ewr(HKPXItmFs#6FjjI+ev>Vky4b`~jsJ6cN%tL#(?zzm8e%AzP zLAFRE5oCGl;KHb(g@})HL&QteM3z9OERa5CDSB@-VF+zqKbG$uGeMftMKDWY$`ERy zgb?+vd9;&}n*k)((Xb~O3lO$#+Pq|Dv3>W6JLkxsnI)N7pePF0WqBF^fZ39CJWBI& z(wWtueT^r}z{VwY{|5j+?km?(sRh|8ZNN%vW){@tjEuaIivUmBp>eg-`LzM7uh|%I zi6K!lgto55bBoR&X`4DhymF#iBME1DYJfRkBFfeI z+zQngwL%-PLfknQ7x8IgqK$9v8I>6tc}pje)EmjWzB&|gd8b}3W|F`H)j^?gt+$7= zq>)4d#n&CITr#sbJC=!-MVMtEa`YTsRReB z&cJaNN`?c6);KauuALsTN2k{<9iRN%X#IWH1Hd&oBGPSR`WLs&Qq{b$)fZV`lZ+&R z(L<3O0EE4Qo|^pwH|zBcPiobY=_Z}oeVR!Jix;FEIQ_9-8M-nKPzF>={i0h3`>d9W zZJRdl-MZ)Mk%9>rg<6_x65UP!fSV;0DVo=+FY~i z*peb1>F!5@fbxY)ftDqddyl!Aw6lEc0V-~eT6hB087kvwIOELnZU1aWbuq~Dfy zfD!;5p6@#E6~${_YArh5Q_)Fjdi@6PahZ ziLt~SpbQuaQdezA@_RApZJjGeWUaQS3h@SHGs|EW6)w3NOsVLpC=LLAy+KQjsdV&E zP7G5}bOy?a$uW1}$Orv)(z=6{Z8qOjy@Z(;Q&4mq{g?(Z&(ej`iE+eq({E4mesj~IUno?Y~q=+)%K8V(YtfC#D3{&}3w%D&XM8-7$$elb60GtX1T|L^$(_f$Ice;DH z{Bx~ZB36iKM`Ho0VuDL6I*b!KK*=9F4l7G)k@?#X-hJ}M`>v8@-ZMjD!hH&-Ggdn> zQvg6JwTCE14+Vhi;%Uw2J#I>lDJUd_GAo=;aj=4@J09QNj_lZ5ayiH`chrVrS^#}} zA6-^d8CJ*(6^Q1p9^g33h0xaZ>iuh*QghYIAW9&b1D=HjK}wx279|Av~_Lz?L#*$EX$;LYiFiq7=$KQ-Jmo8fSZzs zm7~$1);q2Nz?``^bTtumq=}m+4{JU3$;LSDCZ})!a4HmowPxT@IGw4T#-5re4~AmF zQElC}Y4f6j(Ys!H_ttdrotDr%{M>jq`{~3$kgDe4=HAWxz0<2Jm#=+o+k0jw4p^V9 zQRu9w;V8dmC!d@cXCziQove(k$iUA=4YlMCRqvk0+KIg4IUPm$QJ0#9wl3?jANC(R zdhnC)&sxtYNZHjR1*K9c0OVn2yJg;E0m zYK5Q;JK=HWy6S5^b{_!bs8o4+|Lk0`Sxf;45nrsmZ(JjLOJRT_vChXdoc-1yb=zsgJNlNqVbcePZWNz;G(1^-(1%b`9(ZMm$FYB-%IX=80?jJny8 zWf?a;mOL_pBC))DsG{@$A#2Au0BH0DGCK%>n)IAhY^*dJLw7}zJgk+)6stt8k=)(@ z0C@faOkL(zr_f!r&kc~F?5fb;`BjuY-`&F1l?Sayw|qFZun0!7{Y|fzowb>&C_Eop zxV4S7g>N9~tQykw6gd?ml&A6}P(|q%xE)j)7BL&|GQ`;#QH94 z_j%u-Tb+_yIQuMxSIX14Rl-~pf&JX}=ELYcGA5KG3iw{2I|8$ktVX8e{ci1xBZj#s z3w{!rl<#gqDRhLz4p&bcGq_$UR)~TVrp0?p0|2J~`msiD2C{&Qe0NKG#cBJ$Ut?<*4ths!pZOXMzur)~Z2ERW7fX@Isc8T54dU=_ z=DcY{e*WpRRsg_U7yARetP+RT0I@<8T)2q2BbPm2qmjGpdMuTw36EylL5CLnWLlG` za^u5r=m70;e!ZbRT`6)ZC^E>+GVm}?B&rwyP-HOHAvbRvom|OEd763dqZFa!&Tpcy z=GPl6<0hRV-F9zw)D}=l&!#nrzWkppOphzb@zncys8nQn0wG-lH-!miF4n22+E{0! z3bR50&QJMp%U$`whhZ82vaHc3 z1@@@I!-S|Uk>q8xCOkTC$_?B(8WZup?&Q}S?)mM;NXUq7t*2({{=EmWS|Me!lVQ#+eW zVhLMaKkN*eMqtVd4^>fp;)MMQ3_MI8Bw=$&&d5d<-0-`gssERH`v3k~w>o9UpZ|I? zqvM1}ZR2GE0Lxr8xB#HNuAS#NzwU->&UAD}#1Oc3qaB2aSYljK1|k_JC5AChV|vbw z*9B(H9mop%fCf&#-f+!7zxeXjxv5QjHSH;Vt-Ug=+;Z!v&qr zjr1$b4WkN2RenG@Dt}&?;NG>kClFHVn4jzD7lURELDbrOYVFlj1(hE5D?KjSXd93% zvr0y-|Gn)m_aFVJ_VR8Y^DG?#up`{c4_qwjALM6 zqX=d0TR)}DpK=ZtIb^+ERShoc`vbh=Roa_hsFTRz)HYIlw6kH);KZ1RtSnr2vjJI` zVY1x4GIaaB3GcE=(AN-zwl4n1Z+!Lq=F7W%YH)=;fEaWd(?`7dHh$#LS5G`gpJIY` z2k6U49Dz9T0Y=aO5|}0^eBkYlqI>{whee51JSo-yKxpeC>T19G{c{<|E9u^P0@qt^ zxHe_+QqPuu?fqg0x1X}AO(PlZxL{GXTWe^}S2{{cj-+M)K&vQ0${=~x06-G7g{?l= z`tQouwosj&1`!Sb2ZfS3fBREtY~DAwKWx}{V64a!t8POM7LN`Yc@7t~sWp}Q)LlkN zwZK$QM){E7pfCiiA)sq()%s_t?+>Jh{QzK9rWJkk4(9QFcgKC2hWd+190GDNt1_)< z`8>Gxy3Ua%l%8@4UR`o3BrkQqd{OQ}ttcV)`rrJ)Q(Vso*9V7ORApud`oBItsPF0AQp&ya9e zA&>z;z+x8W8uM2yr?N+el)B;mkD|lNT2#>7weR|&<6LBcS;83`;TjX*!^NEnR0{}9^ApmH^ zc>utZidAB%5<=dLbV4gDm|RGia*$ggZ5R39)m}2zXwcgp(CZ+WC$g4_9WDm|YC`0R zBqfso0PRpoela~sTzb|J=z)(JqEp=TOUM_(e+p~AEc`$E-;;WcUgcf@00004nJ zFuwp{#;w&s*+4;`J{rhn)n8ZFRjbx zy?ncJyVs&Amkvs8R^d0j_gieT%5|>TH-#QX>)GWWG6nZ&zcFz69RA^;u)D;A9@VJ& wn1?NO$|sjjF*?N7tMXm{`mGmGTZ2$lO literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/path3889.png b/mseide-msegui/icons/components/path3889.png new file mode 100644 index 0000000000000000000000000000000000000000..a2cbc42a9df25865d90176afe2abab0449033e51 GIT binary patch literal 259 zcmeAS@N?(olHy`uVBq!ia0vp@K+MX)1|;Y0ND~B7EX7WqAsj$Z!;#Vf4nJ zFuwp{#;w&s*+4FKHT+>_VR^oxgu#773A5tbrP3Y>%1_L;B_)4f6La93 zVyFC_PX}@*tym?vZ-Zaa_n=VT!XsKI*B%tPZ=rf~PZQsrq}J4C`7;;)^OsaT5Kr5Y z)ZTA?`*Ba9{>i1Q>nYCAdGXv7yU z^|oz;c%#_2Ku}+lQkp_Ru~XByU+j*cZ>`A2%Hx9itKB zQdlqJPbL_DWh7>}IVaik(g**__~$b%oSZxy8OOFf3)@DHM~ov^)94=p4jDFG8R9v?fx z=3KoY*R6>PwdyR8S;P4C7mqQpp&sd|%K4cer7rr>t)W^S$}pr=$Do2wF8&Q%A>#q3c)+ry&|{u z9AEpl=&pJ)I#{`$Nem>9N+1c$1Gm!CyN>l;N$gxhk~faM0H`&LQ>l&g^tLrH25P@8 zJ}X&iKxtrz`Pt7yhSzcp750tgfSk=(Db>Z*#VcIDuCki3=})AjF8WTG&taD96E;JO z=~-ZatQ6LIA5dsuZX2jvudHTkF7Pyc179fD3!+>r*XvZSSJqnBfb(=`hO8V9)7pBj zA=eg;6~-5)W`SQgHT69pEXIF@Osl|GF_cn|0DD>Kz1y|c6V3Jw z4h}kTj&;#5g>09ARG4E2xC*qd%5}TeI`X3FKd+T*Id&|zB})rSujINAEGtNammoAS e9ceLRO8)?w-|+7$ERWUz00008YJm$#}?28n;!qyX(QZOum=Q zhdcaVjweTv+gV1ziI12H4r;^ly#@a0bAWXD0x>dVOY}`v$;tzG$3|-wGK& zzL4Y6Drh^7?ZMb`$8v|mG29DQ{2Rx4X3k!D$z08&b!imYLKaGme^V=3iM zD`sD8UTN|w1~h|VOdt${Va=1H+XTV@Au!_b_@-l}6y#OdW*alcm=N;HkXIVeOy`7v5MK3aTL|6A~*6oTt`!g+7k-1?P7hr%Jz;}D?M%K-H`4jpUwPl3dE9U?J002ov JPDHLkV1h_C8$AF3 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/path4444.png b/mseide-msegui/icons/components/path4444.png new file mode 100644 index 0000000000000000000000000000000000000000..09990d28daf08f2866627176c8400196c6395a96 GIT binary patch literal 309 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CN!3HF~3v%Lt6icy_X9x!n)NrJ90QsB+9+AZi z49qV;m~m@$P&QCdvcxr_Bsf2(yEr+qAXP8FD1G)j8!4coO`a}} zAsQ2VCvIGM*g%9q|NUZ4l_y~j1mE}tOPB<(2~`N{KREOuiuXP5KHQ5xb+0QL70(Y)*O%l>?NMQuIx9s<%DEq%hH2dfI^Zbt`Q~9`MJ5N zc_j?aMX8A;sVNHOnI#zt?w-B@;f;LaKt*poT^vI^j=#NZ?bTu^!ulZJWy|Ib14nBe&{^RRlD_|QrxC@kL1d4Xqbpwx~=t0;A~#Aeq(Rkr-^B)llYj9N7g6seXh_q znH$x7v#Fe`uKR0~`Q5)x7Yn~G{`z4;{)Vdyb{@GM^3>{I)_tGDcLe8s<~moD*Rl0U zb;Y5VOVlHeg>SU;scZKAl5M5mT01Ab>XCa-YL2_$zo`cqcHfXsE@++W6Mm&`%K^@~ oLW5%qx{qIJ71NFSW517a!FAsY_sV&G13k{*>FVdQ&MBb@0AnAYbpQYW literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/portss.png b/mseide-msegui/icons/components/portss.png new file mode 100644 index 0000000000000000000000000000000000000000..bb4d08b61595ea7d906acfe102366fd0ae0d03ce GIT binary patch literal 306 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*O%l>?NMQuIx9s<%DE))OQB$0}4r&xJHyX=jZ08 z=9Mrw7o{eaq^2m8XO?6rxO@5rgg5eu0~Pgpx;Tb-9DjRJk;}QL70(Y)*O%l>?NMQuIx9s<+x4Ef91|`0}4r&xJHyX=jZ08 z=9Mrw7o{eaq^2m8XO?6rxO@5rgg5eu0~LMtba4#vIR5ssuU?CzNb5s)VY8$|LNgR6 zE>o>C-Gy)FSq&zxHLxa!!0VLZY;r5Qh0<$C2d9Pa>KDC2!_lt*%PE0?{zd>}a<2B3vy{mUfnJ36`SLlA4`5`|t zeM+g@#O+z@EMDp8MYkR1H8axx{JP?hpjfuL#j)DL{hFWmM#wLk{WSK@BgK0wt6c3D zofBDL@A}DZ-o|$4Jt863J^U;(Uz)SMN#K0{@HcCT>7?MAtDEjiT*zE#{(qn8r0lT1^>bP0l+XkK9J`zs literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/ps.png b/mseide-msegui/icons/components/ps.png new file mode 100644 index 0000000000000000000000000000000000000000..8b28b7463dbc23be48a2a45c945a9af4c9f1a711 GIT binary patch literal 317 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*O%l>?NMQuIx9s<+#nHdRrE41PV!(xJHyX=jZ08 z=9Mrw7o{eaq^2m8XO?6rxO@5rgg5eu0~O8iba4#vIR5tXMlQ!d35Eyyu8C&SKJyMN zSRyes$Bh4Rr%lVj6DM3epKyv?FS;t3x9hs@<)5#3{{MVE=l_4}c8%pKvHCF^If{g3 zJ{%Bhj@SS3;-TCT^Pa%NBFB~3!;K!X%{zFHRrbn8r`=~dgytCX7wPJ3JSg>dlk%@+ zv&BAq?$|WPz*+Px)6pmI5;|gkb$ydK>M!mZ_$5F8XtC_yxE>!Cpc@%HUHx3vIVCg! E0Byl^qyPW_ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/rec.png b/mseide-msegui/icons/components/rec.png new file mode 100644 index 0000000000000000000000000000000000000000..380d170cf54c2c60555905b58091f12d0930e26a GIT binary patch literal 337 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*O%l>?NMQuIx9s<+$~v_~%=_018Q#xJHyX=jZ08 z=9Mrw7o{eaq^2m8XO?6rxO@5rgg5eu0~M|Dba4#vIR5ssZB|pDK_UVBwqjk literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/rect9378.png b/mseide-msegui/icons/components/rect9378.png new file mode 100644 index 0000000000000000000000000000000000000000..1a45bfb438a6ff09bff98474668b4a82ad1c1280 GIT binary patch literal 144 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx1|;Q0k8}blmSQK*5Dp-y;YjHK@;M7UB8wRq zm|uV}_UVBwqjk literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/sdf.png b/mseide-msegui/icons/components/sdf.png new file mode 100644 index 0000000000000000000000000000000000000000..cdcce694209c5193c8b63d8c31a41f379bc64e0e GIT binary patch literal 308 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*O%l>?NMQuIx9s<#-rb9v#+91`0`*xJHyX=jZ08 z=9Mrw7o{eaq^2m8XO?6rxO@5rgg5eu0~Pgqx;Tb-9DjRhAs3UQz_E|<7qdPozA210b{6oQR_Q47_-!8G;Pftae$#kn%7i{}`cuC^EnfYlNDVvUp@@DBo?-W?QL70(Y)*O%l>?NMQuIx9s<#_a2=N%Tf2^5knag8W(&d<$F z%`0JWE=o--Nlj5G&n(GMaQE~L2yf&Q2P&H6>EamTas2HCL#{&(BCZ#O9b;Pb4h6Y* zuWc!5N_d_W)7*XO)S+u`TMQFc3(VHqtM<7W^_Agaq9QMn z1tuM1t$reZlV!QZ;$2O8W;YV0ZZanGY+S2daj|;!3qkp5JHkb`Jlf~-Up8f;Y;rTt w+g+3Ooq`f1Z|ZE@nRqwEwbMmu;t$VxW)I}%Uw&!U0dyUMr>mdKI;Vst03o<-tN;K2 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/sigbase.svg b/mseide-msegui/icons/components/sigbase.svg new file mode 100644 index 0000000..32b2773 --- /dev/null +++ b/mseide-msegui/icons/components/sigbase.svg @@ -0,0 +1,221 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + SIG + + diff --git a/mseide-msegui/icons/components/sigedit.svg b/mseide-msegui/icons/components/sigedit.svg new file mode 100644 index 0000000..89e5bbc --- /dev/null +++ b/mseide-msegui/icons/components/sigedit.svg @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/sql.png b/mseide-msegui/icons/components/sql.png new file mode 100644 index 0000000000000000000000000000000000000000..b101d41f9bd5a623de786f7faf2126bc409d0747 GIT binary patch literal 363 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*O%l>?NMQuIx9s<+!a4r%Y4b0~C@hag8W(&d<$F z%`0JWE=o--Nlj5G&n(GMaQE~L2yf&Q2P!(|>EamTas2J&jb6@<0<91G8_YCydd>^H zX%%VW*f@n{{-N{@f{WLRRZ3<{bDxgTV&T0d!4jRHJWH^x+g0rL-^7G;zBiI-Wh>X5 zG@N%ap{;pI?gOd$g64t0pQg(;^UEX(C+|^vDQL70(Y)*O%l>?NMQuIx9s<+!c6gJ%8V0}4r&xJHyX=jZ08 z=9Mrw7o{eaq^2m8XO?6rxO@5rgg5eu0~KBNba4#vIR5tXMlWVZfny)#*>6QetT?am ztx?2DV2ggb#ga`Z9qb=mNB))L7?%b*m|jVJylCZyZn$e%HD zX`-v&#~vo?9LkesaZqiSg!(O3wi}1|&K1th4p`LxR`r&*%^ahX zrZ>7*$rbb;c3B;uQrWmZrg;jp&*VR%y9@J@<@XGpKi-&g4aQL70(Y)*O%l>?NMQuIx9s<+!aZz67p`1PV!(xJHyX=jZ08 z=9Mrw7o{eaq^2m8XO?6rxO@5rgg5eu0~KBKba4#vIR5tXUN2`yfwqV3%(o&UR$N#3 z=EUX5qU(Axw1PMD$b2)gos!wo+^3iHD0q6z@;Gqq@{zQbrxTQB3+UL$^SpV({+rKu z^OdNe=@sssdVa$B+_`6z<~@2B{yCK)I3_{*x`f(2-FF+BZMS@w!TsV9+ivbX{S_8h zHN*=9LiautRqqU6g zAQn3H#p6AjTxDw>8b|#IVhl;nHGMUIZ$`uC(6G%nN?J`H$mayE-G80`qmt1%hQ6I| Qfj(sLboFyt=akR{0BPNijsO4v literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/sql_qqq.png b/mseide-msegui/icons/components/sql_qqq.png new file mode 100644 index 0000000000000000000000000000000000000000..4950cf6db89626e5ecaa07c1fd7e9b1a3b0c7054 GIT binary patch literal 425 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*O%l>?NMQuIx9s<+!c*eco_}0fi(>Tq8=H^K)}k z^GX<;i&7IyQd1PlGfOfQ+&z5*!W;R-fmX42x;Tb-9DjS|ympJD%<+%m(t4YO{;_Qg z-^#9fH1J7&K|$HAm?y`lHrF3>J$3Y8;ZzY-Grc7-TWqG6N}A5I`RcP;DT+t9i#kW} z`ubkoe?k0gw&i=?={xIJ_QZ9u^%-1R8t1Y5LA=-1`u=nLFKz!Z$Tz$UaQfJxdH@(` N44$rjF6*2Ung9T#sd4}S literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/symbols.svg b/mseide-msegui/icons/components/symbols.svg new file mode 100644 index 0000000..70d0f2b --- /dev/null +++ b/mseide-msegui/icons/components/symbols.svg @@ -0,0 +1,427 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + SYM + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tacecomp.bmp b/mseide-msegui/icons/components/tacecomp.bmp new file mode 100755 index 0000000000000000000000000000000000000000..796a3b1663dcb9b465470462894b8df920883506 GIT binary patch literal 406 zcmZXPu?+(u3`KoXiW?zi%FK~I>!fx`fhaQ%16ZDe0%ZmA?IUm~2LA*5-;;Sf-y3Fw<3OjPM+BINv0tpDL`2S+jnWdOR7UVri^cy6xCZ595?2pF8@Hr7 nxFq`CeRG*_%uO(Sj@!CCEy84qpVZgEH}U$0%f5=a>jQZLAn*WX literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/taction.png b/mseide-msegui/icons/components/taction.png new file mode 100644 index 0000000000000000000000000000000000000000..62ff6dcb9420f5c9bfd85d73a19faf6a934b8c1c GIT binary patch literal 829 zcmV-D1H$}?P)g*X}6%8$^^|JGpzQab0? zbAO-T^YOmFH%ckRa)x0shc%Januuvx0GfzKY;2ouG&)2iYDoc_$U!nQn{Yb!jOOR> zZh#H5L89lGI2MDUE@-pujI!Iaf3&u~AL!^9z7H0l56~A3&_vQnNNA+0Dld?n9OJ33 zes#<3es~l*fNmhT;0`pAeQe%*42L6stiAo?=lc5I3SGa}4WED>U_vPsm^VNZF%TVH z6RfD%7qnW_hEJY+eR*i;UJY~sAAoN_Kq)n2^;ND?Mf6UUF|`MSEi?;MV2CAxll zFjR35Fc~g!Sb!#CB|F<0EGx?xX>R^{erV`!9lZThwO1+i-!dZxXd)S;rd|r>ocr(e(JE0K;iWJpfJ% zSdGv>0jGK+Q1P4q08J#p4O15IT?K0aoHaw50osgkF5GS+Yc)Rp$U2j0yHaW@30|#% zcM~vB2`_-Sa5kM&6`II;ii;2Tdc9+rB5n;XOu_X;I0qOBX<`u_?Iav|| zjy^aP1CM}lz%$pQ3k%R}wjGp~?k6n`%hs*dKzjN{3po6+_b0^7Cb-BuC@MNZR@Q1d zJHh2*yuaV}NuH+Er zn*I=p-W6KnCg3OV9T+9_u>=7YY*T_;36M`O6i1&1}Qb00000NkvXX Hu0mjfw}D>@ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/taction.svg b/mseide-msegui/icons/components/taction.svg new file mode 100644 index 0000000..2fc93e4 --- /dev/null +++ b/mseide-msegui/icons/components/taction.svg @@ -0,0 +1,306 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + GUI + + diff --git a/mseide-msegui/icons/components/tactivator.bmp b/mseide-msegui/icons/components/tactivator.bmp new file mode 100644 index 0000000000000000000000000000000000000000..8078d194df35a68f4930c6e755feab847de82d4a GIT binary patch literal 1782 zcmeH_F%Ez*2u17SpqrCN@B|*f-Ne&6dkjzFWP&fP0~)n8sk+$E1}OZ%ho+rUV^7Un zam)24Rx@VczsTLSfjsh`PZ^kH?xpXf%OpckFmc{0YLt;&BaCw+IQa^MB663$Gee-L z{IC)YMS!IqP)LFy<}5gP^LgWA+by$)K?a1&F(LGT+dC*SYn+;h$) zP1Eq3^8Bj%KfsNo?*d{J^Huq($C*ctFvwwwy@+ku2BQ$QZilTnOMCd*uT3boK(k zxhsHt>6tH@#jIO%)5za#%x6N-rOs0$2g?XpM2)MXIWj(yerchTG#x$lp=h zsstEGD4d!4&GF5}L3}@D8m9hXej?gOj(`#bKqY`)y!Uyj70>Zr^FsgyyJhz+zyh-F j8g6G?HsGiF`%mT@L#?1QckhXL00000NkvXXu0mjf-dF_m literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tactivator.svg b/mseide-msegui/icons/components/tactivator.svg new file mode 100644 index 0000000..e217ae9 --- /dev/null +++ b/mseide-msegui/icons/components/tactivator.svg @@ -0,0 +1,491 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tanimitemcomp.png b/mseide-msegui/icons/components/tanimitemcomp.png new file mode 100644 index 0000000000000000000000000000000000000000..1012594c29f254ab7522a993327f2b76af11810c GIT binary patch literal 401 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ zFuwp{#;w&s*+4Ia;vq+A^aR#3WqBENLT2@T3He2Ar)G2Ai7OUZ~yxNR+ zBG2>PD(Uy{M{e7HzHVAh_jfy^^k*U!?~{$iYoyIngO=|S+QF=H`S04abXTVIZz;aT zJtu12K20@Ko9^LUp>Ql)fvJS~ao4#8h3{m4v^)&*5j%49k}uW`6uXB8Sfh3t*m+K+(z2>4>1O8KJI6_r1+cO#S^FgADQ{H znN@I_<5yk_+2-e)f&-ZDYihLib7dW1XWjZB($TlVKS27P_=FVdQ&MBb@067esyZ`_I literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tanimitemcomp.svg b/mseide-msegui/icons/components/tanimitemcomp.svg new file mode 100644 index 0000000..4be96df --- /dev/null +++ b/mseide-msegui/icons/components/tanimitemcomp.svg @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tanimtimer.png b/mseide-msegui/icons/components/tanimtimer.png new file mode 100644 index 0000000000000000000000000000000000000000..5c2a78360c017d710de9ce88b6a7d64e3e022ef1 GIT binary patch literal 1694 zcmV;P24VS$P)RZVHGlupq1m zDC`CIzWaS&|JcPwFf)1oIcMga^E~hSoaa4r1ioS@m6a+Yk+0!!1cbV}fv{rHh5LXXBO6V6kT8 zJZmDG2=ci$}gU7Rwv9W@e|9DSIZf?<$Z{70+1Bu*&_!JK3aG= zx_Xa-GEFX<66h`}u3VnBIE(EVKzx*-7{e}8< zK$ECW5tkGe*t3ZDfVv0NnM6W5YW}uu>_AoL$p>$$9w^snel&DnVZ;`R=vDdoOFkCG z$j$b4?T=+Ss#g>(Kzvef*#)uB$egXS>U0!|CR1vW#gZZ-^@7xc&u?OX)vrg6?QZ+H zJgj}Jv-BZd{o{{|vdyZ|8VqO*2DAo)_*pDQ^tapP4ULU=xieL+$3n9YQqb83;s_R1hMu zxEzV0sC?dF)9{Gb-+Ad;XxA&X?Jw-^Il5ZV7Pl>4tm`Z;7VhTl0;iL`zu1Vy?Z#`f zap*gxa!?TB07IQOTTWM@Zrw(@+fCSJX0(0-t4my{bRw6|T#tRw z+kY-cr3$bAG`yv$Epi5sCbNtI-9UdPY;Mf3>nAgg$HZ$*V-wX+bE8F^oee{Bz>4XdJVWaNuU5xAS!?)D9UX~qLRRg4`J zKuR}quy!Yh#qT1GnG&u7kQ45i06m}rBp^6VX9fB*Mn*%BFwWfT!yMVO2a|UKuO*F* zyLQuWorgvi6TrzZc67wYz&90d8bJh3=ME0)451MDJ|8El_c7Dw!)-S6(-&T(KR53V zU;wS#&5Y(|u^Fxcw*Yx^ZJLjt17B37I<~&W@q?)gf(b91I{2O#fH zf0p{x>aGcx00xqB-@O8WN2Af2?DqC2jEcgz$;6uN+i_-RPs*!Hs*74)v-NE2l z5(JKf5MNS(0!4*pvB9V)s*r&4>fE{VfWl`fCJ=IKiI15O|SD8d)O?Xp_k0n8*lowiNmzMmh9S6{fqWjpv5 z!iqG=mO*_Jyv^X8fPgs_e{21M-yoOg^z>|Z{ot2WND`j|BP1T#|3^4e^-|nskevIU zRNjA`R-ghX17-s@pa56|Jd_;s0o%pX_L^9DNICa+dt}pE_5lw9CP2934!RE+PI>Bg zMh8{3-s-nG3xokz^71@DKX4H^pB%3Op2n8Zo!44cxMn}FMzC4A7nnt&;e@HLrK;hu z<>}9xyvCicFa)@hU}Jp2+jj}!UvH+C4!g}|o1eShAxVq?oxtc+0)a#aX8~zR;4vUX o@|W;s1b_~h0i-AQyMXBb02w)%o7sf(!~g&Q07*qoM6N<$f>G);vj6}9 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tanimtimer.svg b/mseide-msegui/icons/components/tanimtimer.svg new file mode 100644 index 0000000..b7a74ed --- /dev/null +++ b/mseide-msegui/icons/components/tanimtimer.svg @@ -0,0 +1,623 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tasciicommport.bmp b/mseide-msegui/icons/components/tasciicommport.bmp new file mode 100755 index 0000000000000000000000000000000000000000..c0a96fc49745e1d2ee66d8aecba988bf4be3c4b5 GIT binary patch literal 406 zcmb7;xe)>}3`PIWkUHOxkUGd|huBq6k4sPks>M7>-hhE%(fM`j{&;OldSY+rzI4+i z^Ve0+;KOtYQSarjK(uR&L1Ct7&Oj&}DU6>XHCHo7+}u(MSNM&yr$wH@m^Iuvk{u%~ cC&*PexE{buu8556R!WW=c_dl8&>S(dwszr` zhH{E?rB;-iT}a$$kz`ZycbryE5jru-h2-L0q~&a*St}QeCPT-ci|^;hci)_Kc5&36 z`t#!HEVRiF8-q)jb z0)whrhH-3Z_C>fEYjFr$tLj2LggfyRwzu%{fd6}B}-D@FlT zHMS^#syZLX5WIxjs%m3ZZB8=R7+ixnT-(d>*2w_+HJHGjByTprNqm9ns#=cg@iE@R zwyHXU>+tEK7~m(o-Ls#>uee`V{I8QdljINFg)4RK`)E7Ad!WJCX+J9dsXtCa@A$ z<3s#_7xBHW`_}2|a$uBncttZwUdHpfmYl-9NoKGW543ZKlDwN_XJheglHKhC-$=4| zA%OF$YBe_DGhB?XAj!|YE4{p`wp7)9ZExNJGMq)P;5*%{IapQ4lKj=%Key>sxDo4d z!$Qgbi@~NO8vCN8BU;l!zQmvX9H;+FUUGoH0UToE7#BeX`~Uy|07*qo IM6N<$g04he&;S4c literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tasciicommport.svg b/mseide-msegui/icons/components/tasciicommport.svg new file mode 100644 index 0000000..b423e7f --- /dev/null +++ b/mseide-msegui/icons/components/tasciicommport.svg @@ -0,0 +1,205 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + ASCIIPORT + + diff --git a/mseide-msegui/icons/components/tasciiproptport.png b/mseide-msegui/icons/components/tasciiproptport.png new file mode 100644 index 0000000000000000000000000000000000000000..1cef8fda7b8fc3a25897d7c742ff7d82609be41f GIT binary patch literal 729 zcmV;~0w(>5P)xK~zYI)zwX?R%H|g;OB;f`I8huStLb+C@|L``Z1C)ZgLUL zfs-at-6+Tg(M)pEC~zhiNE$^{SR!<@g52%vAV_QCYggj zntuwvU_tXQ!|(XBPtZT2acrxqx3C2(Tl`UMXkQAd>NsvnGJ(7CH5Mkh?ra2~;y?p9 zg`F6~AvjAir~^DORxr?=u~?Ms_N&VBfUP!x+IUa+_Vwa7ust$hL@}AaFP>MH7uTm?Rh0u zU=?m31%9Ru)>PF*RlU*t=_FS`Ti=(o`2MPT8awdtYzX?c9h;LZ#&dYRm*0j*+76qM z;7j~AoUE!{x~bTW6WFTTIe*{FNxYy_GkoTseT8#S^7-2T|EK>K?M=w<-{-g400000 LNkvXXu0mjf7baC} literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tasciiprotport.png b/mseide-msegui/icons/components/tasciiprotport.png new file mode 100644 index 0000000000000000000000000000000000000000..1cef8fda7b8fc3a25897d7c742ff7d82609be41f GIT binary patch literal 729 zcmV;~0w(>5P)xK~zYI)zwX?R%H|g;OB;f`I8huStLb+C@|L``Z1C)ZgLUL zfs-at-6+Tg(M)pEC~zhiNE$^{SR!<@g52%vAV_QCYggj zntuwvU_tXQ!|(XBPtZT2acrxqx3C2(Tl`UMXkQAd>NsvnGJ(7CH5Mkh?ra2~;y?p9 zg`F6~AvjAir~^DORxr?=u~?Ms_N&VBfUP!x+IUa+_Vwa7ust$hL@}AaFP>MH7uTm?Rh0u zU=?m31%9Ru)>PF*RlU*t=_FS`Ti=(o`2MPT8awdtYzX?c9h;LZ#&dYRm*0j*+76qM z;7j~AoUE!{x~bTW6WFTTIe*{FNxYy_GkoTseT8#S^7-2T|EK>K?M=w<-{-g400000 LNkvXXu0mjf7baC} literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tasciiprotport.svg b/mseide-msegui/icons/components/tasciiprotport.svg new file mode 100644 index 0000000..2875619 --- /dev/null +++ b/mseide-msegui/icons/components/tasciiprotport.svg @@ -0,0 +1,205 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + AprotPORT + + diff --git a/mseide-msegui/icons/components/tassistivehandler.png b/mseide-msegui/icons/components/tassistivehandler.png new file mode 100644 index 0000000000000000000000000000000000000000..f09eba19432e7ed7ac58f4c05df1448ef7c6cfe4 GIT binary patch literal 890 zcmV-=1BLvFP)jey!3Hsim5qtXW=q_i+3Q1g%s81f zzU+ZBT>k&u|J-wD?wJc9fe`SDZkwLMLcnngzSDv)v*5KBd|(Pw03Bd7nX_mHwE=jN z=>!NM2o$6XxSG9j{8-U{je#Ma(^Sx-^1P#L;=4OS);Bi zEpivu`0(TbG|AST37Kpgsq{Mr(23q&r@x!9s`KoJH2QPgzz-+pNY>&}IYK?(YDDr( zEP=5~AUnPoZ6=gkC~^-03)3XHD4fuBOe>h;9d=K{JF2@-^Vw|zkO)4==H*-CSI#*| zMSCQe$H>5B_lPS2yk%CQ^dpF)w=^m(Wyj+WUfSdi3Sa{8qDy?txIrTSs2@*>DdV(i zr>b;}=AaU(IAzpdAa%e@J_`6JF|c$P{kD4$$z<0lB!Thz7y30Xu7n3wj}TF9$%=fa zGX&Br5E{TwqII>rsWfBU=HMBh?@v*N&d?^hX zE)>ng+KHWPNOtbAgdGsT8DIs#L?(LXxC?4?QD<7kI;Gy&uEeU_WUN7xYIcs|E!Sk$ zB7qPV@#}B&oAWP%VVTYAyFmb(fx~v@l5cfQ9|8+{TYVeRM`vRvN^D#6#}r_% z6Y-YFCa-V@^M#*ut_g4aJK@dg#G#j7bW7W?bOZ%wTqr%Z5}+{|tSpNj+5L|KA1gpb zI(Bxr`utZJDt8I@*E}T~(^Vxa^i6c^=tUf0oMSJtTNQKtGqmBwIU+j{5%I)h`MG{e z$2rF)X|s&~(Q*MUXF5wJ%gBeWYm4=&5l*?a^_E)jY71Uz!IxO@+bK-{4biOs8DvfS Q0RR9107*qoM6N<$f-=dH1^@s6 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tassistivehandler.svg b/mseide-msegui/icons/components/tassistivehandler.svg new file mode 100644 index 0000000..564f7f3 --- /dev/null +++ b/mseide-msegui/icons/components/tassistivehandler.svg @@ -0,0 +1,130 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tassistivewidgetitem.png b/mseide-msegui/icons/components/tassistivewidgetitem.png new file mode 100644 index 0000000000000000000000000000000000000000..b161358d40781d85d75822d6605a2f188cb27cca GIT binary patch literal 592 zcmV-W0;5J$mv{8yAD{^7M zgqtv0L?dMeftzfg7D)s(LLl8rg6I#3AcCk6GH4+L5rR#N7A^XrzA=4`^WJHZ6FN3C zwRnrj@9v)SJ?Fzc=W@kb8xWyfz&FO2D4Kho_t6DNrBadH!dilRrE9*MNudo`WKK;br07_EJocHce=U6h1Zo zJOj}AD3QJ#_vbF{X2h=w$gr!i=*D*vXy4ev>Z$e$O-fn z6ecq~E3N>{Q`aIvFbHfy0q_ug>V({_qvd&qOjz>vvoEOxM-lB5FepidGlC3#qy9ax z5-`Z)2gBMmhO5IOatK%tbQ7annD}y&t~Uw=pc&XwHjR6+h5D1nxt*^#B7hUz|4fm? zPZFn(DP)1Qi>VDjYq=ko2RYT|U%&O6T;(P2@w0bw>n^?kuA#K^Yp2UJ>V(>xoEsRg z)Tin*ZOWgY0QPIcjV8p|1|-pN4ax^X9hcdjx7F%v0!osZbPmY + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tasymciphercryptohandler.png b/mseide-msegui/icons/components/tasymciphercryptohandler.png new file mode 100644 index 0000000000000000000000000000000000000000..57a7db5dd37c6fed1861dd2df87660477c388888 GIT binary patch literal 858 zcmV-g1Eu_lP)3I>#J`88(ZZjYe(Q9Uk zyvXOK(kyA6gE^Hx2iIb0(HAQvDEbo2#|SzVehKBt4Hgu`Nq8Su6nzjsW#(F}zpFlu?jMC45#4b%$z8G2Qe8D9n8WnQ#Ec%D*djt{U${FEa-Z_hLlM#;=)qV44gL_3p+FUYRDc@&8I($(klJ zR~`Yuw9?EZIac;zO=fP1h+*7;+1e&Qtevh4unZq)=l{OU+y@cyI5uN7zAF9)v@3qc z)Ga-nfbVcxSymfx9Y(Pai!g)-@L2IVA0L+Un0Cr$l_2)xxMFL6Jn(wGS&MNL+bexO zzQ$Z^$Mw|(msWnS;Rft%a2MXel8ERlsb3utt4oG|Oi^ZjTZq@=47^m;`^@t0(HPe5 zr&Bwb`Ajiv!nTO`5esoUEo`>cfVEmO%buIlyhTdb|XTkif&W6XrNkR&z7f_ zete1N|AueS?x*q0JXo*=O+>s{dsXEBkchY&TX9=vPFAKae#p$9D{`4RG3}~25{ZZ* k+9_IGO~5z)$G + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + ASYM + cryp + + diff --git a/mseide-msegui/icons/components/tasynsercommchannel.png b/mseide-msegui/icons/components/tasynsercommchannel.png new file mode 100644 index 0000000000000000000000000000000000000000..5f2377ff80aaea656a6dcc3f7eb85f6650250a9f GIT binary patch literal 1124 zcmV-q1e^PbP)l5%OU zNISI+9yOhG$dSEj;K9d*BmfW=Zo_h~yzf1w@P>f1y#}AS?6BKkPKPd>Fa^s1RXUF` zKK#9SVA&cmw&h8=EHZM{y8BxAWZhyeLrv;`#nWQ^>uuSfr8Gj z&})jX?kO5#Ja9u5jCt_mY~idqL~jp|m(@SuN%!p115LZd?2FAxXtG9D zy&^pU0J;L|jzz2r0HJbXMuu(n(dVVul_8rwf6Nq`H~69zHH0ssSjh6o@!eA?uSD;T4)j?oTxX;NcYkf+wmv&b|+(FE>Po%d08O#`dcG_XoR zh_(QrcdsUi0m^1Pl-svY_fOYh9-w3{F-Ff@*S_0#Hl}83ibG35+G-37a${JKXU=AH z066udDUL@SX5fe+44pFhe*~zzn^TW}r%S_UOzw1#!C&Y%d9Rr7tz!X(=F+WO3r1VF z7K~Qcdz3Rj8+nkt889BWYdZpCozJ97hzIVvH~eD&P*KZhxih7=6Fq*(X75_&P35#D q&AdD^U~#n#*XIY^vM>3+j6VS|OQ{+>^6N+d0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + ASYNCHA + + diff --git a/mseide-msegui/icons/components/taudioout.png b/mseide-msegui/icons/components/taudioout.png new file mode 100644 index 0000000000000000000000000000000000000000..0e686b953ba234a3ae82a1f1aaeea895c382c020 GIT binary patch literal 731 zcmV<10wn#3P)c)nOhB|=kRM-$7i_p-#EZqOG&Po;rUAJ!57$qt#}@nHPd#E z1b5EnZT%iRm!zyVm2WuwvS5OOqW1=V4JYxbzS6t%)=%_@Kf%Vl zTXb8J>+mriJ&$`CcO9^bBY4a9352&2a*6;I2ks7k*80Vt@|ouk_T`8gWUE zc6f1~dXiuCeSK;>^{JWiXK+a~erYN`wb33k^q|ECI)z;gKYIJBYQ4jgBXjP>m(BQl ztPGV*pPu!R_17;Yd3^?PXt=Jc`l<#=&Q{eyd{tGS;7;rv+r_LDy`VqbSFkV1Nu0*B zgOd+%JKn`=lCg%jV*y8!JTMl;f3XgCUo7#e+D`w}*xgj(kN(GJ%-?r~2!>XUiD>`; N002ovPDHLkV1n{pUXcI* literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/taudioout.svg b/mseide-msegui/icons/components/taudioout.svg new file mode 100644 index 0000000..b5ff4fd --- /dev/null +++ b/mseide-msegui/icons/components/taudioout.svg @@ -0,0 +1,243 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + AUDIO + + + + + + + diff --git a/mseide-msegui/icons/components/tbandarea.bmp b/mseide-msegui/icons/components/tbandarea.bmp new file mode 100644 index 0000000000000000000000000000000000000000..b4223873f27736bda41f892fc63ef77d564d04df GIT binary patch literal 1782 zcmd6ju?@p83GqcOPX&(qyu{?Tv<6ci_%G4nAf=cVbaOs%F@Z=a!k4U%t$-s24+A~1BfM{m=VlkU^oDj7vhFsutFg5pW*)~8V!Nb5WpS+z{~*#|G|JX zHd4+4Wi+w?NFxo*A-s24+A~1BfM{m=VlkU^oDj7vhFsutFg5pW*)~8V!Nb5WpS+z{~*#|G|JX zHd4+4Wi+w?NFxo*A4nJ zFuwp{#;w&s*+464*YGo@{{AgLrX%sB*za!&9^zZYxI_E*my!-Wn=G~ zTW1b!dSlhJX2OQ`mE~#g_8i`mIOB*}uG{*nuf8)dJXz?wGnebGN&H#gT_@`IyUH$L zE@}AB^WwH&lb`+@e{a)Em*%B4EaBY1SH-2HayF~R`GKs2cNNpLNpb5f4>H^kEzMcq za9rv>#|^f>JbM`V0~_Aj7H}P2KcPOmX8r*~p8AG0=frnE;rA?lAn-A_LHxn)T@#Mj p)q2|Aj%2y;qMIqN_uBn~l82u}Z&XqZc@6X=gQu&X%Q~loCICf$jk5p% literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tbarcode.svg b/mseide-msegui/icons/components/tbarcode.svg new file mode 100644 index 0000000..5d3d029 --- /dev/null +++ b/mseide-msegui/icons/components/tbarcode.svg @@ -0,0 +1,398 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + 10 + 10 + + + + diff --git a/mseide-msegui/icons/components/tbase64cryptohandler.png b/mseide-msegui/icons/components/tbase64cryptohandler.png new file mode 100644 index 0000000000000000000000000000000000000000..efcc38bc7ac0cc5b7cf7135587512fa71db419f2 GIT binary patch literal 852 zcmV-a1FQUrP)>_IM84S6)xHp zE$o5iLK@WQ0nw_4glZ9k6*NIAH9}|&AvLWcrDzcak!YNv!3rw~Bq@rqB2%JiaesgM zNmB?m2QK%X@9*66KIdMTDc7f&DKp`^3g24ck5u?w75+|z4;E|zW;z(o%zfs8B4VbQ zFXe^4>|~~h=*KF|;;YO&c(NKIVmYQWbGGmeF3-#Z&_u)+7{pUpjmd~ueUi$b#|U1i z;5B%lmYc!(c&-#@F?N>c^KdK9Df}hHiG^5(#|wUEx%XfSTMB81DUx37b0;{H@$choADOD!Qspt5J2;!QeZB%Ku^$)X(abyq5%DaxVm-bs^2fC+{-dsyZWsNC zD@rG9!fjZGLs+WaS5M-ZB6AHsF3%roC%C^j@jcEhXYI!Wd%CSvwcI-Fs`$nD4rgH( zZm$fis^oU#4(x645Z=SGi0G8iZ;pudCBmcKP&4y~qIgt0sZ&+HmzQ^YF^p+k){~hp zm4k7-8WF$XY}|tz=P2CMI9O`;XN9jR%W^5kGIKg2^id;%gkf{xhhVTB4UuXi!QA? e;IRMkH|8&&EMvMq7)Kuf0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Bas64 + cryp + + diff --git a/mseide-msegui/icons/components/tbase64handler.png b/mseide-msegui/icons/components/tbase64handler.png new file mode 100644 index 0000000000000000000000000000000000000000..efcc38bc7ac0cc5b7cf7135587512fa71db419f2 GIT binary patch literal 852 zcmV-a1FQUrP)>_IM84S6)xHp zE$o5iLK@WQ0nw_4glZ9k6*NIAH9}|&AvLWcrDzcak!YNv!3rw~Bq@rqB2%JiaesgM zNmB?m2QK%X@9*66KIdMTDc7f&DKp`^3g24ck5u?w75+|z4;E|zW;z(o%zfs8B4VbQ zFXe^4>|~~h=*KF|;;YO&c(NKIVmYQWbGGmeF3-#Z&_u)+7{pUpjmd~ueUi$b#|U1i z;5B%lmYc!(c&-#@F?N>c^KdK9Df}hHiG^5(#|wUEx%XfSTMB81DUx37b0;{H@$choADOD!Qspt5J2;!QeZB%Ku^$)X(abyq5%DaxVm-bs^2fC+{-dsyZWsNC zD@rG9!fjZGLs+WaS5M-ZB6AHsF3%roC%C^j@jcEhXYI!Wd%CSvwcI-Fs`$nD4rgH( zZm$fis^oU#4(x645Z=SGi0G8iZ;pudCBmcKP&4y~qIgt0sZ&+HmzQ^YF^p+k){~hp zm4k7-8WF$XY}|tz=P2CMI9O`;XN9jR%W^5kGIKg2^id;%gkf{xhhVTB4UuXi!QA? e;IRMkH|8&&EMvMq7)Kuf0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Bas64 + cryp + + diff --git a/mseide-msegui/icons/components/tbitmapcomp.bmp b/mseide-msegui/icons/components/tbitmapcomp.bmp new file mode 100755 index 0000000000000000000000000000000000000000..0cc772269a2f6de498ede84736d53cafd0d5e78d GIT binary patch literal 406 zcmY+9Jr2S!424~Z!AD?3nK%bK*8xUv^$B{JN+{~gDY_!%3gOxLX?Tg<&-Rm}-tNmp zt_SiJajr4Z$@`Z&_u?-J5iW_84>AxT6l267`=y+X5IELC(m|rsj|_dqt|DfgKUK`q zcw=q61=i*Xq5Ffe%n90!;WtjsS{Q}-y$@IOqu$;Bef!Avr*$oC{*k+V-vz#(zJ$sz0VBxKscD literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tbitmapcomp.png b/mseide-msegui/icons/components/tbitmapcomp.png new file mode 100644 index 0000000000000000000000000000000000000000..fc3a36f24e928e3f4a7a707c4274141cbd28f51c GIT binary patch literal 892 zcmV-?1B3jDP)6q0rIu_OGFS6fbAClt;K(C@w+Yl7mM$$aRHE5 zz%~*2lji_qOkStrlarIlYKjjJ4=dnbZIkQX`=V`u$8~f2%s~J|%LI$~7u4e8!&~Ed&rQ3XYY46pYnEsS&jHo&1 zr}*preCbarV#NJo%>7ctTwy7i*>*RiU)4lw!VwJ< zh{$OT904W(bf3ZxAd{&YbY`G4P^iU(u%M_Epi}_A!*?_PoZ3)Y`+hDNxZ9ni!cl8P zj=hOuh?3S-yWqK?9q^p$KF}N8tiLm S>6K3a0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tbitmapcontainer.bmp b/mseide-msegui/icons/components/tbitmapcontainer.bmp new file mode 100755 index 0000000000000000000000000000000000000000..ba0ef1ca096c738e43340141f64714bee412ad43 GIT binary patch literal 406 zcmZ?royN!j24z4}1BfM{n2~`6EUo~R2Xjz}1_lNoVrXc9P(TvM1mXsU0|yQOCH{jE z!~g#v77zm=NC-&WMFJOqa!|l~0U^$N;m#Q-IE#a=ix5{run!^Fhm=6 z2Y?d)!HD7ie-I0Zfe<7FB<@lIfCfOp-MbYX9St2I(2vgM=->cJfyHsN8<5lh*$f;| g^~mBK91wE~7#M&C0euLu3v4aO{Bk&;#8)VK0hDpwpa1{> literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tbooleandisp.png b/mseide-msegui/icons/components/tbooleandisp.png new file mode 100644 index 0000000000000000000000000000000000000000..644163c0896528696ea7087032bc2c67afda5aab GIT binary patch literal 525 zcmV+o0`mQdP)g>XL%?EEu3|IRGS#%#lxx(RaNWb3?7nslI z09-B?YPA}x)ykK+-|s1x%LpL=ST2{O)9IIEa!2IAS$jEv&1OTh+4RMOIiUj1sl011 z2Vj~egTcV%r_(9PWDlG;_sZ`44>h(IBrU9U7T4*ou)bD>NQvu7D82H7DTZcDo(bYSs0F@i2QjqHH$H@pyE7 zDJ6zskVqt4&bIBBqjB(X$ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + T/F + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tbooleanedit.bmp b/mseide-msegui/icons/components/tbooleanedit.bmp new file mode 100755 index 0000000000000000000000000000000000000000..7f9ca65d89cc7c4ea1f68c44e9f4a31e6433a5b2 GIT binary patch literal 406 zcmZ?royN!j24z4}1BfM{n2~`6EUo~R2Xjz}1_lNoVrXc9P(TvM1mXsU0|yQOCH{jE z!~g#v77zm=NC-&Wr3l;y8UX}Od#7uifCyMVp}0*JlkU{HIPA^-q_g7Jj_ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tbooleaneditradio.bmp b/mseide-msegui/icons/components/tbooleaneditradio.bmp new file mode 100755 index 0000000000000000000000000000000000000000..a015c580795e7e82ed78f4d3e11106b4401035bd GIT binary patch literal 406 zcmZ?royN!j24z4}1BfM{n2~`6EUo~R2Xjz}1_lNoVrXc9P(TvM1mXsU0|yQOCH{jE z!~g#v77zm=NC-&Wr3l;y8UX}n3@j^4E)&GAZNnF W|0Ct<8 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tbutton.png b/mseide-msegui/icons/components/tbutton.png new file mode 100644 index 0000000000000000000000000000000000000000..d2981da1407cbfda4615abac61b27252bffc520a GIT binary patch literal 592 zcmV-W08x{gdHgUx0GDdkgDEEYek1GuhBlJq=}g+hVNW|OvUv)k=5olev9JT@8) zMx#-xs>)KSL;$Q-tBl2B?DzWw5R~V6^gNHIY2JGe0mpF|iA1>FZs|DAPiwJQP*D^D zpk-Mc3Y???Xz7!{LBrGKtx2hVgg|+qUs|yK=c4 zNaA!l!T0@ulZUJty^=ktum<9vUArx1eabegKFQV2mI zL|~EPx-K!5f50000 + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + Capt + + + + diff --git a/mseide-msegui/icons/components/tbytestringdisp.bmp b/mseide-msegui/icons/components/tbytestringdisp.bmp new file mode 100644 index 0000000000000000000000000000000000000000..fae2784f08faf81e1a3eab5b07e98c71f2cf96de GIT binary patch literal 406 zcmbtPF%E+;5HnJTNL^5;j*Pscd%sf{J>JH~d-9RIC3P+lP^3;c=ZnvmT$I;)?cn$* zkK(hj!_ECc{l~qsms40lKmoFD%90`xV^kx1Am^e)tzs#qE6{+3lxAyKPC8gHn6dcM dROuSn_0d0S(sZ8inZdR>f8LrlT=~_{-7k}Z-5>w} literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tbytestringdisp.png b/mseide-msegui/icons/components/tbytestringdisp.png new file mode 100644 index 0000000000000000000000000000000000000000..939552e598694a804fa6e5bc3a86c0b3d510b7ca GIT binary patch literal 684 zcmV;d0#p5oP)o(ft)i2Ihk5Ph!TxSQRpP<e{XfBXVn)|>(@_F|jg1XQny;*^{I*C4VOzuDkhizD30w%lcs!np z3n3VdMktD6?cvWmkWyN!+wBsI#V8aCHvIYdneFXulF1~itE=4H+}QH>_xHr(ab8|t zENm))rfF<#ZBZ_l`JBt=^DHkfb9#Ep-rgR&ySoS>kW!-SI_Y#8!!T^UEP@Y7rfH(< zI;m8Og@pyq&(E#g#l;2d>+1+12#3QwK0fmF^n?(C>+5TZ#Uit_vo^~n6x8c=0)YU2 zzn?@R!SV62%{rgYhm?}Jxj7aW7wPx=NGUluI3O4dTK<2j;N;|lKp;S+QbAQ!s?{pJ zUJoGzudlBdhGEqzih`=DlM{cXU@#a^uh;Q-JX~E}aeI5q($bQp!sqjGcXx-BlK1y_ zI-L%|U~t0ozxOjAteU0~iA31n-?z?jtyW`aXNPPyOEem#(P$8h#kjn@Boqqa^?E1H z{^#j!3QDCCo12@q3ButpE|-h5vokW845QJAwY4>Jxg3Xwhql^(Dv(mrXf&pNjm>7$ zdOkWjVmuz>cDtw6K0G{3V3tMSjrsZcZ`T4SrfE8R*|pnk#Yuvn|HJwD1it`s=C<*2 SexK|B0000 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tbytestringdisp.svg b/mseide-msegui/icons/components/tbytestringdisp.svg new file mode 100644 index 0000000..f0a156b --- /dev/null +++ b/mseide-msegui/icons/components/tbytestringdisp.svg @@ -0,0 +1,428 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + A01 + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tbytestringlist.png b/mseide-msegui/icons/components/tbytestringlist.png new file mode 100644 index 0000000000000000000000000000000000000000..939552e598694a804fa6e5bc3a86c0b3d510b7ca GIT binary patch literal 684 zcmV;d0#p5oP)o(ft)i2Ihk5Ph!TxSQRpP<e{XfBXVn)|>(@_F|jg1XQny;*^{I*C4VOzuDkhizD30w%lcs!np z3n3VdMktD6?cvWmkWyN!+wBsI#V8aCHvIYdneFXulF1~itE=4H+}QH>_xHr(ab8|t zENm))rfF<#ZBZ_l`JBt=^DHkfb9#Ep-rgR&ySoS>kW!-SI_Y#8!!T^UEP@Y7rfH(< zI;m8Og@pyq&(E#g#l;2d>+1+12#3QwK0fmF^n?(C>+5TZ#Uit_vo^~n6x8c=0)YU2 zzn?@R!SV62%{rgYhm?}Jxj7aW7wPx=NGUluI3O4dTK<2j;N;|lKp;S+QbAQ!s?{pJ zUJoGzudlBdhGEqzih`=DlM{cXU@#a^uh;Q-JX~E}aeI5q($bQp!sqjGcXx-BlK1y_ zI-L%|U~t0ozxOjAteU0~iA31n-?z?jtyW`aXNPPyOEem#(P$8h#kjn@Boqqa^?E1H z{^#j!3QDCCo12@q3ButpE|-h5vokW845QJAwY4>Jxg3Xwhql^(Dv(mrXf&pNjm>7$ zdOkWjVmuz>cDtw6K0G{3V3tMSjrsZcZ`T4SrfE8R*|pnk#Yuvn|HJwD1it`s=C<*2 SexK|B0000 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tcalendardatetimeedit.bmp b/mseide-msegui/icons/components/tcalendardatetimeedit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..dff71a6145ee4b71e54a6f652f3b468058e60ea1 GIT binary patch literal 1782 zcmeH`F%H5o3`N7j!p6iAH~|M>=T13Nj?h!F(x-g-6}gp)(lWu9(%6pu>RRdj@jRxg z8_z52@?M8(r8IDUK55lN9>ac`ko~)Qq5ic&{wQ%wE2W6KYA7Lax;qLS_w%`-c?8bC zA10s~{?vR{Z!cqU&bQ|Se~a|L=bXDQvkJ{|Gm7Ib8jka7i_Df23g@mNE~FfqU2Nyb o2=1H-ft*DSaikI#w!!ukf)x5`%NK1yT9ncP2e(@Qr|x#xM@UY-4FCWD literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tcalendardatetimeedit.png b/mseide-msegui/icons/components/tcalendardatetimeedit.png new file mode 100644 index 0000000000000000000000000000000000000000..e02bbf5b1e1fd602a00372071f27bfdd3dadbcb9 GIT binary patch literal 539 zcmV+$0_6RPP)jZ$6(hnM`Q?WHcI$IG@j6 zk!LX+4x43h)8H>ytybRmZi6&U34-9i#V(f%yWI|evMg_!Sa>rK5rQCKI-PpCdopde zTLyyxo6UwW42k3T?vIFhMdV*VsBQN)e8Fo@c?BZ!Z^&7ek!9J_v4|idH!&jhvQ26N zA7Jn`5N7r9cnsHzHMOe4#^Gd~%8P9oO{j~rzss;cVsi}uI~E?kM8W$<|y z+2N@wMNtq%5&eE2sM*;wNs^Ex3E;m`%jJ^AV!?jDuj}&5=epDB0B|@QynGmjv|25W d$0OJ4m2XH42WuR364n3!002ovPDHLkV1g4M;hz8i literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tcalendardatetimeedit.svg b/mseide-msegui/icons/components/tcalendardatetimeedit.svg new file mode 100644 index 0000000..5a3588f --- /dev/null +++ b/mseide-msegui/icons/components/tcalendardatetimeedit.svg @@ -0,0 +1,567 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tcaption.png b/mseide-msegui/icons/components/tcaption.png new file mode 100644 index 0000000000000000000000000000000000000000..5278500b1d61144bbac56067fa58d720f69e642b GIT binary patch literal 416 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ zFuwp{#;w&s*+4PBBc1%^XeL0*>Ln z?UzbCqcW4ZRqvOy|E{%vXW3qS^l4F|&)%L{|5$h~s+|8ExZ8$tLvHny0>vZJ3=3AR zYHwSAJ-dP5;d&`Q>z>!|8E?OxwrgGHtTv4H)Y%wYf$lw&=Hep`)KPBD6%F@ zo8jAU+xEka>t0*P_0L$=38ed)mu1dp{Hs=5CEDfhI~s+qHdSQwo+Ht8hW&EI@8=R>XhWfRN!=ga>#&w5jN@9UdgdJKsY zai^0aubpSuZZg-8y|OOd=dp#Hs*D4}Vm<4Re~kXyKM;+4P#DU~?E4%Tnhc(-s24+A~1BfM{m=VlkU^oDjf6WEKV1+>9Kf`~jq5l*Euwxn;8YprS&=u4+ zhoXQ&au2o40eX;pqmbM)2+bkiNvQrpHixvZ!eI`?5M-l}*+A>i5r#PsCt)=QpHVo> zfm?@WAdm|Yfh&MAu$hCb2BHg1FB%u5o{%{}HCS|E3KC%svh$GHDCSdO4vJGLGY4T5 Z#pXbbqJ}x3K%;>AZ)Q7v_j)wAb3&)sb8R8y6B~dxO1?%*o#uDF{lYHxT&?{p}TP# zEj3p6^6qcu9p;_iGc&uwwr$OSd>R1K>2m;$mX-I1hT2lT|GfaDEi3Q4u9+y8zm+U2 zp8%LmODR|E*m0^bIM{zyYkgVRwylE+DnLpI3R;s2HBbhOprA&e^gHc&AF%DUR}Ev) ziA|dhie0<9=T?7Q_ll%oQ!syOafqNs4e9<89&snYbG2gST@^N?GN+Y+vD{!*uTGH-RS7>YtJig z2a+H@U%2pQv1R4MA`*_1(Nhe}`WZ+muK??S&A>C@l~Stfce&FTxUN~P*l{v`L{~kR zQmz1TsJC})H?R-bvSEXDHOi!x!MyOLT>e%H;(Ne|=&yhg3_81W=jr9i-1t+V z_1Lk;ZzBEF#&7~%D#aH7q*C!TPzgOxrQ(f1rK4kh6L4s3>_tn^FO*Wnu-~%s0w9RG zREozS*hPQBAn;x*rOwQj8$MA6zU!K4DP=P7yvjsMx$Vf2OBy%~^woMigRU|REiwv) zPw#=(*ROYa#o`Ee?p*mIr5tW*TK}Y_Wg{0azFVS{`Y@B%HPHyzRVS$Q^sG4wJRcnF z&-M3jWnkdUP2l*WM>mCKon+6RLe%5gVkKbnlYx|S0Jx!)x*??$N~t-2C#nn{K5X%Y z5EgLXbhvDa)6p8hC z{|kc#fR``toda%%OAM3epaXl&sTJgM<2~1|>Dbh2rk{fuJg)y71a}bsnt{+-|JUD^ YA3>-dHYS+brT_o{07*qoM6N<$f)tOVs{jB1 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tchart.svg b/mseide-msegui/icons/components/tchart.svg new file mode 100644 index 0000000..f01d610 --- /dev/null +++ b/mseide-msegui/icons/components/tchart.svg @@ -0,0 +1,303 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tchartrecorder.bmp b/mseide-msegui/icons/components/tchartrecorder.bmp new file mode 100644 index 0000000000000000000000000000000000000000..5ddb4c265d46da4ebd8588903379c84011cf728a GIT binary patch literal 1782 zcmb`Gν26vsca8JUd`Zjy!7%tBdBBAY2mxk=a&5-C!Wu(@3;;aW(MlocD1g{?B# zk@y4r0T#2L)h+YwJ=f#p;cB|x=Y5~fJ?DEq_nha)uk_!qB+pOH-}R*m-QErIe&90_Ty(4^amk9CIAYJZFZP2OeULdBzy4rB;hsNo5^% zE39~>=TuO!$DWS{J4a501s1m1);!3detMMWR8u|8bjS_HC6^s^w9$6MjXCeRA7;3o z`hE7z<2h35z2-U)%$Q|XjqI@F{Q(|xv_3V|9CGOOS6nsI+)n!~x85&%l~r}OtAWaS z*)I{)S|5FP+*yhm8DdD{d5!3xo^o16RS!K!9C?nEEwq$V-cSEI=j*Ju(kjRgjR;~M z>B}fn7q2*q4ls}+rCvl3N3{1K=AU3^VA$|NCSznUE5g Hr5pbMeAkDe literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tchartrecorder.png b/mseide-msegui/icons/components/tchartrecorder.png new file mode 100644 index 0000000000000000000000000000000000000000..84552a26d2edf5d818f6f83b89cc8c5351fe83f2 GIT binary patch literal 1225 zcmV;)1UCDLP)}hDX)i}X}4=D2jxvR+5gP5&%FQnJX-RsZC2yQ>^yv*FN~w>5_gh-7)a=?7Dc;ev9d>q(s`mDEL%=7q#7{cFW$+%b*0ybcwZI)u zmwrm`|69CLN@*oCU4xW{lF|rCX*kj7 z8d_Se)PQ!rqhloJF_@SD?*Um|4}?uKl{L*&7-0AA>T*zxiNwbH$z(f;#QHR-#=> z>ctEw>VtSZcP*EDSW{kJ`6Hxetg2#d+je(X*P_V0dEuYHbr2382FLiy6i3(Ta25Vc#kwoR;Dx%vo9 zmFcuT7#X=mCNth22vl4;apF(kvSlXud}d(Vwh!h@X*ga|uMa%EV}~_A5?T2B^5yG% z$B*ARJ~6>R83-ZfE?&I)@x6O@-nMP~Gq~GcS^2KIaN*FWqocP^nr3QN2Cc1MbpWR} zY&fvbV^9WA1Qg)t&6_`bT}WP7ZnEcqUxg4GZQGv4%pKhu0TXz|G*j=m6z~{idV1=@ zLWme>`;Hy^<25ObP%)EuJeLFZ0B0^=uARo9t80-0J_p`%&xcH3Un~SuuPFHFQFchv ze5vi*JF2Rx=0o8;@cIDYemtI=bN1|;wHGfQAs9TRaO?ikr8es8cSf6<&U8yz7>tEk z2edEE&lXX8U_2jR%wiT~RiR1GH^oEAXzL?altzSMLiPVnt_I`0VpLZ&O4E7u*mOcOtUOYS(bHxLZ>Ed+kWa9EreL;zLM2IFR;h9?c1es zu~ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tcoloredit.bmp b/mseide-msegui/icons/components/tcoloredit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..64d011ef040a85bbf25af4eea03afb11dd61ac66 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDj7vhFsutFg5pW*)~qF)I7rvMhJ0+k09fXXra2ii=wIY8@x=0Gf^#2lb=frfzGN|}2` h&A}h4nJ zFuwp{#;w&s*+4A?BbKKY(B7Q{@Vws$xKTWH@I-E+iU)J)<4GktTxgid#{#+ zG?@I=iMt@NI5o2Gq~w(6mIsgM>oPle9oQ1}Wp)EQzn!hd4UHx3vIVCg! E0DSm#82|tP literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tcoloredit.svg b/mseide-msegui/icons/components/tcoloredit.svg new file mode 100644 index 0000000..431fb1c --- /dev/null +++ b/mseide-msegui/icons/components/tcoloredit.svg @@ -0,0 +1,261 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tcommport.bmp b/mseide-msegui/icons/components/tcommport.bmp new file mode 100755 index 0000000000000000000000000000000000000000..b88f0958cda32b5104f9b174e62cead20e36ccf7 GIT binary patch literal 406 zcma)0xed1rHSC&UN$9#yc%wdl7F dv)R)d7wN7`#W6p)Jzu!~2bK@*u&bZ_li$z^)T00Z literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tcommport.png b/mseide-msegui/icons/components/tcommport.png new file mode 100644 index 0000000000000000000000000000000000000000..299882f06cac34203caa589dbc3dc97d2ba88d28 GIT binary patch literal 776 zcmV+j1NZ!iP)6s=sLWK$CBFfPuWoWdHyr1z4wJZ4-FCJn=mhl}6$zy0=aD=v=W zbMyUv-=C-7=kYg^#B9>&tXls!9B3(;i%D$5iiVBh5$wbr4O@VhlMM8hVlz%}y2mtp z5w;{b7{Q}>3|C-7RUL=h@G~yPL{(jl6R^Ch7B;<=I16)7Skmwnm=B{>HIDsBwkP?f z8J>eHaetB@a5vUAUXiLNR0H~^wcAarJo!rh}T7*mSZjb*vMyhHtcJ&?X!Q!6a!&S8i2de7S z=JXtV*OU1i*Wk6GkN5!V55rs4H{vc_t91!3!kfBU?7%WzA#c|ecSn<()TQ|WT!7sJ zyx&Fl;7go=tD58O&Dav$n&cgPh1YcjeW>ZafW3I7rR=^QZsb3|D#iwvs=6E(>bhrJ zlIezDhSiu#GF?>@xU;E!kF7XGH>3mlILYSW2v+JkYB%n!s)bdx3L7wu^;LB#CUCB< zQ}*I%U55pi;C;Qh8cxwvl4tOwZfI`CjY+0(9d2rJdy>4AWK)acizJin1D{Xw>d_pW zR8?nUjjki+;zMXtJxJ-Lky#_e^h^#~s>7ZzZ`!x2muICk}>b6E;@WJUoakL;S~aLscF7cN~0# zU;E4?TXkLWBKGP28^1YJm;HDG=QovIdYhF0!z9nTgTDaGk@RGl2>$v20000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + COMMPORT + + diff --git a/mseide-msegui/icons/components/tcommselector.bmp b/mseide-msegui/icons/components/tcommselector.bmp new file mode 100755 index 0000000000000000000000000000000000000000..8460a086fc31f4fb7b53556a1e123a82d229fc47 GIT binary patch literal 406 zcmbtPF%AMT4D(4yOsFd(qpJTjEZh!>zT3E>?_u lx_${CZLW8-@A`r79bo(48#8mxuhxeGh183QHNRT)z5xJ`_4oh) literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tcomponent.svg b/mseide-msegui/icons/components/tcomponent.svg new file mode 100644 index 0000000..294a19a --- /dev/null +++ b/mseide-msegui/icons/components/tcomponent.svg @@ -0,0 +1,256 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tconnectedifidatasource.png b/mseide-msegui/icons/components/tconnectedifidatasource.png new file mode 100644 index 0000000000000000000000000000000000000000..ff62f7f0c50d1569b0956a9455ea57194a0443e8 GIT binary patch literal 968 zcmV;(12_DMP)!X8qFq58QkBa}UpXe$R8x6`Ioi)09*T3Kzsai+&N1NPg}aUUGC- zPb0vx_0EVlv_B}3eART&ed+YD8({11hG6qY??x1o?apmYH^wI%0LMm7eZAEA+}-%? zxO|~#?fc@b6U~RqeqX$Uv_!@;Q`!A&Uc0Y7p(+|GqcPtk#onip8ACmIkNK{!-0L!V z4}Uk{`+;h2jb&|DpzD@q2|kYskN?yy3W^KrGm4qS44O@|_?bAS6G@a! znLGj1>kU2?zmq5ccv5#{MfAMBa!y1W^=ix7?>fF+s^!^LJU4*g%YB{oqSFYp#e9?A zTp()qwI|YUE)We|4*#NEIUiXx|8Qn?=xiV)lszxrs_(Vstcy}sE)aQYcW%%eD;?M8 zAI_|X`-j$uP9xBE+kexWnO-&&+5G>#ivSAsl5~2DM*pVH)k<*0Ppslu3y#fV6a7ZW zg2R5}Usjb?@!P}zM#)o1Br$d8jCRIze03`BvLnOPxmp2u-KA4@WYDy)&0-S(Rbqq5 z&mX1Wlue0AEkv>y^)MyrOa@08f$d1W|NFrG$Rx@J!n)Wt6 z^GZ~6dtU0ZY;B%2b#tmnZRw~V1+4i$q&iWPo~LRMHiqU5l6m~7@CVVD{Rge^_oizA z@V#-~6y!%^5cy#4to){Y5LH8@${e@pmF#1 qpvM@ANF;AKYnr0tQO9&Lx${0|SvcG;5>=1@0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdatabutton.bmp b/mseide-msegui/icons/components/tdatabutton.bmp new file mode 100644 index 0000000000000000000000000000000000000000..f7bad63f1393ca83e3b685c3c30574ada734116d GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDj7vhFsutFg5pW*)~8j2wRi$Kz7WS=%PH2nYn zA4rk`kW&s&JJ6g1qywNvtmZg5Iq~rD07;0EEG#VgFaQw=3=A|jHda$p>+0$Pir_K_ zD5b2d4ABB4tE;PBTwHeS*Z~)TFg9)41T+fBCej?B$_W!D03EPp%NAs#+S}W;w6sVv z2dKEGrw8aNxH*P~hDJt4ix)2@)tueCcPl6;z|8?N=Fgw6tE-F09H6YIs3=^Er>7^- zYE4be^73+sU_d|s&^^-9(#6Hac+7#DKqLb#oIz=lY=BXG0SzYuAm@uw_7DmI05`!h A#sB~S literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdatabutton.png b/mseide-msegui/icons/components/tdatabutton.png new file mode 100644 index 0000000000000000000000000000000000000000..7c9e1bc80fe253173f9ae83abb65c918add19069 GIT binary patch literal 472 zcmV;}0Vn>6P)}pXIk)%Ent^Ni) zB7MDHC)#BlAfL}CQe4xt698bh+r6}Suh#?k28hT@0bh!nEFu?czu!|Xmk|*rlL^IQ zkwT$Bzu%|TYGD`#hGEd@bgpvG4|~&r<2Y=$TSSC*yUk!QAe~NQ+cvA!ie|IPVzHoJ zuhVEWe(%6>oH#z8&ncBk9FND?)o3)LR;y91R_{890ZOThl}e>9;+xF|&-3toAEgwQ zWig#j8IQ+Txk{;@ujo7;1OZ_f((QK1<#L#&$#6I%o6VBRWbO{gLjc!xIUEjDDiz=~ zf|g~W>pHIM{vEJfE)fxCv)R?&dF&|%&q@d4iAh2lkmzHly}!)=5BLNks^_$L{YNhV O0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdataedit.bmp b/mseide-msegui/icons/components/tdataedit.bmp new file mode 100755 index 0000000000000000000000000000000000000000..a857b7fbcee1f07b4b291e2e3c9209cd9946cd23 GIT binary patch literal 406 zcmZ?royN!j24z4}1BfM{n2~`6EUo~R2Xjz}1_lNoVrXc9P(TvM1mXsU0|yQOCH{jE z!~g#v77zm=NC-&Wr33&CfP%YsD>|T{|L)xam@tC<;RAyGpPzg-iaGy5<^Vke2K;yL Mmcs!hzCzIp0C~~=+5i9m literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdataicon.bmp b/mseide-msegui/icons/components/tdataicon.bmp new file mode 100755 index 0000000000000000000000000000000000000000..f2cfdfe2192e17c0ada824b3e9bed4c60a691b23 GIT binary patch literal 406 zcmZXQu?+(u3`KoXhDez*bEMBYx#}dQh(vT5AWT6Ui9Wi*vyg8v(m&k?n}-2oxZR(V zG(F(2u(R7Frxw5XdYkNA5J8s^`T!4v1<5&Mp|&oy8o|&k1gAgU67<$Z!5UMF>Z}ns z7-T$?Y=76%&hD7b#!^Pktw4U)YW(f_Ij*!H1s!YPd#Rk6;|HcZ^hSRB%l_fx^^8CH E1FKN+F8}}l literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdataicon.png b/mseide-msegui/icons/components/tdataicon.png new file mode 100644 index 0000000000000000000000000000000000000000..df304256cf5d880ed36f6000217f729ef6f0f677 GIT binary patch literal 546 zcmV+-0^R+IP)!2RaAt2B+X3Hna<7Jaa`D7^9?2HCNCT=+;e%K zb1s~FwQ9ABVHklBLSu^RdWNQHI!rUb{|9L0ayj^$09^>78HN#*N~Nh9S1J{R5Sl*j zkY&S#8Bn);%xlG!rLa4SkQSha0ur$hPqR@n=?J5SXehwEhU4!6jh4c36^`rQuDxNq ziv0t{V)OyUw`o>$3zGq7P5AK1!|s|&g>$2@b};6{2hOo<~$nf(Fw=d_;5dOpZRc`Ee=vdhXy#pF})N>S2VnCox{-mr2CK!)!(ax{A%~6!J+5`Q*4` kWA*QzirJ4g1KeA`0Lzgyl3%O33IG5A07*qoM6N<$f<2P+?f?J) literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdataicon.svg b/mseide-msegui/icons/components/tdataicon.svg new file mode 100644 index 0000000..99473f0 --- /dev/null +++ b/mseide-msegui/icons/components/tdataicon.svg @@ -0,0 +1,253 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdataimage.bmp b/mseide-msegui/icons/components/tdataimage.bmp new file mode 100644 index 0000000000000000000000000000000000000000..56a0e702e07e79807ad17183621191b7f6840f01 GIT binary patch literal 1782 zcmchWy%ED8429*!MJDhFnZN_2&rXcyecY!d4-_j{wg?6;9B|_2eMkZx&(}z?%;@iE z)29v5B3iJ%-nhk$=sbB;=NubXdnHuEa+(NXbSZo^P(H+Xxkh2gObdq`HF7}U+QJb? zwLdAr^hc6q7)QvtKZg8!8Mw|ZEn=MHr+~vufmHh=z6q+upOp5K!!J}MmXYUd&pf2e uBJliwI5?|IT=`hi)qGs(&b-~717MfJzX7P?Z?Owh3DvNisf21+!FdBS@Y7lV literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdataimage.png b/mseide-msegui/icons/components/tdataimage.png new file mode 100644 index 0000000000000000000000000000000000000000..2fd5cfd9c3851c09b96e251ac81644a13af6ec04 GIT binary patch literal 842 zcmV-Q1GW5#P)?>2K~zYIy_P#`6j2z4pL6EStcl4Q-58CR#KIslX>0|--s=yr zu}Fjz78aTm;-(4#t000XR+1*I7qk*VK@e@SLcjzsvC!R^)t%k!&hD9Gu``>!M950? zgO`Ch%=?`8`wlZB=H})|rBcRqUBMPseIV#;1{L7*l@75w7z-dzC`vz+VAmJz${gAzJPSH4K2Tj}eGo2D%>OShS^9 zfP%Dt7AyD)m3aV6`7P3{knvCBC~C4dp_Ufe7L?5)J{K-Az&L@}jW8KL<}ah!SDR70 z)i48q1@AVW)+R_ePso(cPzw4RB5$VBYs;0$yI}^A0uGY)M=_$mt-dRvxw~-X`^9%d zKU)(h+OGN|zp(m7CzmcPFDE_>qJb|>fWPf=wwPvS@ml7oHLEIn%7gds)MS6@TyH!wgt)(*rAjqP!>4b4l72y7Wbq(J)TrFk)ClT*4O1sehCOrs=02vp(DtL9Z$ zl*X)%3-SDh6q(Lab9)*9&8?{i)*IU4?yG64&l+!3h}X9q`E^&m`LxxB?57QD6_5_# zK;S^d0pF<};X)q#0_eOz6eL!`;N-zBMq55DSl!<#j*fV`_e)pg`~N=r|LV8pH<*-1 Uar1dFK>z>%07*qoM6N<$f`L?qz5oCK literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdataimage.svg b/mseide-msegui/icons/components/tdataimage.svg new file mode 100644 index 0000000..6c138cf --- /dev/null +++ b/mseide-msegui/icons/components/tdataimage.svg @@ -0,0 +1,317 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdatasource.bmp b/mseide-msegui/icons/components/tdatasource.bmp new file mode 100644 index 0000000000000000000000000000000000000000..65d5ed12fb69ee2a043efdf85636d1d736236d13 GIT binary patch literal 1782 zcmdUt%}(1u5XaLCm)?5njccEv572vGh{m65uh%y4JS9rvZ>OON(5k?d2SA{L2_$j6 z{o6*-5@A;=Qq@|sqyO&C{ARqnA3n~uI@R|c{vF2K$MLFCosN(FH?Qka1;X(T|6go- z`{L!T0#e&cP-{pNN(}gIAq2O?tWhm7_10hDtV^s#OIJ-XP3ujlXXBq;Y$E*Gx+beO zWmF^kwrlCe9<>cgwN(NmI})w5YdS<$Nmpqpv1_{zclSImc)?*oe^`nY=XvGl`Qx=i_LPS`?IdA`Ri^i!vczHZXg4G>O_za4z;L5$Kbmsi)*;}b6kgDCdH z2rZ40gfEu+%-;Afu^*iCeKrFDhLbrvJzvb1OLSA+V1Zt+RcTXEH#p){{v-2Eq54-s24+A~1BfM{m=VlkU^oDjf6WEKV1+>9Kg0h~M86RDPXR!RsfLDz17rb^ z^|UkxlB_VD1{B8>1d8Bt4@5m&7bXMEH2mfO6~j${Xhh?}O{23paA&|7aF;+B_}zo4 r3sZ!kIcQpdTx39`d(e~-l@I^`5V?km literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdatetimedisp.png b/mseide-msegui/icons/components/tdatetimedisp.png new file mode 100644 index 0000000000000000000000000000000000000000..d147a4987803c4a97f52b92cac30b451fa249b54 GIT binary patch literal 558 zcmV+}0@3}6P)Od4mS7wexF=_1VOd*0oD#6Y&y`3qn6|wON zd=B#nR|yC0BE&ZsT8+u`_n)OK@>%t&u7%VX_{m*nZ(4~?Z)+b{Sp^KP$(2)u@3+# zCHwsz$8jhYi$qbx<#M4`t1%jlD3{Bzq}gnS=Xn5}PA3e*Ae+sS&*zy=r^yCVN({qb zu~uXqpy_#p)>n6;L#4*|yDYw?j%vx7(#!t;Y6M@%KC_<lBdL{Ws}I0zv)91fVKNiLU*b*W7L zNDzi0mStgC7L7)OAPAUDCg{43l#))T!*aR&LhviPCxMibQmMr8cued<>Gcy literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdatetimedisp.svg b/mseide-msegui/icons/components/tdatetimedisp.svg new file mode 100644 index 0000000..6504f65 --- /dev/null +++ b/mseide-msegui/icons/components/tdatetimedisp.svg @@ -0,0 +1,371 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + D:T + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdatetimedisplb.svg b/mseide-msegui/icons/components/tdatetimedisplb.svg new file mode 100644 index 0000000..9efbc2e --- /dev/null +++ b/mseide-msegui/icons/components/tdatetimedisplb.svg @@ -0,0 +1,375 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + D:T + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdatetimeedit.bmp b/mseide-msegui/icons/components/tdatetimeedit.bmp new file mode 100755 index 0000000000000000000000000000000000000000..05c92d7e8394edbdfdf01568dedf1b208cfaaf29 GIT binary patch literal 406 zcmbtPF%AMT4D(5B3_(ncjJ$)Lzc2w~M>aOz(~sm2`GIlMa)88kZk<|=8!5-rb3)>x zdJuPm6ISW()!(i=H*y*~3ZRQp`lBi-7SvkRU|x_-i8{?v@g>lJ0r%T|;NgCL+f9d& k!HCpB3(`{4AWUHUQFPD<_wg3PC literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdatetimeedit.png b/mseide-msegui/icons/components/tdatetimeedit.png new file mode 100644 index 0000000000000000000000000000000000000000..686b4a5b8144028edcacd9db0cac5dbfb485e8ab GIT binary patch literal 328 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ zFuwp{#;w&s*+4ss|%!%kcGqJh4BStV|wF&PkrLUeG8xHdSQSM%KNof1B zYyVlQA1uqvl1gPa=t~xUylR)wjb}b*KJ$ne3QRoyVppF;a;c$xvhww(#jXsm{X?b- zFda4sVOgeseVh2i-Z!aYUu(~A(z*KD?&v!cTdBqOMWcEI-~YYNvQA{i`n}&<1k64u z=iL(6V;t~m-rTM39UPjf51vRod6`|npt;oj>0I86$8^s!9@olHUw6M?oqqxQ_X`n^ UEWgd31@sVur>mdKI;Vst0075 + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbbarcode.png b/mseide-msegui/icons/components/tdbbarcode.png new file mode 100644 index 0000000000000000000000000000000000000000..b21aac08e64f3212252d9526377f33b30185fd5e GIT binary patch literal 422 zcmV;X0a^ZuP)C#WMgb>ycXRg2iGPERfBfU>G_8>GUChJFc&0nnxrO2LL3KafA>% zdA>`|r?zDiv39TF|GzUQ2h8zu^U5)1Nf= + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + 10 + 10 + + + + diff --git a/mseide-msegui/icons/components/tdbbooleandisp.bmp b/mseide-msegui/icons/components/tdbbooleandisp.bmp new file mode 100644 index 0000000000000000000000000000000000000000..4f00f6f8c1da55e862975ebee315b7340e4b184a GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDj7vhFsutFg5pW*)~qF)I7rvMD^>uGEbvNMp`K*ykQfg*U^gRB^tJs8YEa|4?5i1!z!IY6Tz04PO?IS}n| xlE`p|s0TU#je*A;n0pa4Trsja2x+k4c-#ZmP7DLn9AMTU4-MqJz+XJD2}CKhC-5awSDk z*rjwkt^N%Vj5@zug=#8htaJ3S`-=o<$;OSS%(0tX9*?Tup#lO(7gUojZ%i zFSd6Fv-tF~cBOB(+tPa5=Gy-cXa4~|K+a>uCeG6300000NkvXXu0mjf;MdA% literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbbooleanedit.bmp b/mseide-msegui/icons/components/tdbbooleanedit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..ccc9db22fbe2faca38c783a2c4fbb0a0fd3bf7eb GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDj7vhFsutFg5pW*)~8h{Y^Pc*-s24+A~1BfM{m=VlkU^oDj7vhFsutFg5pW*)~8h{Y^Pc*n+a literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbbooleantextedit.bmp b/mseide-msegui/icons/components/tdbbooleantextedit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..ad4039585a91ee2b7bc046e0679f60ea6c0f33c1 GIT binary patch literal 1782 zcmb`FF%H8Z3`ObEp$lt|&`PYS7SctIn(;s>KOO^qgai8G@X1 zo5p(i;f*SOrfK43YaRB3PEwz>l;U`FU1O1h3KbJ8gDsrRa|!+QIv4xN?<@Q}gVtJN ziLWW=R4Q4SN;s%_i|CkO&fd$P+@6pFtJsAiIuN#I;Zw+oA;h6XM9>;Ju-An{mUj8c S>+`KqP{P6IVSz{9y2KAGf#~-D literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbbooleantextedit.png b/mseide-msegui/icons/components/tdbbooleantextedit.png new file mode 100644 index 0000000000000000000000000000000000000000..cb30579ab390ad0ebaeff4bf5f21a654debea9e2 GIT binary patch literal 684 zcmV;d0#p5oP)~ztPSZ40t5w+ELvV;# zEGCZ12q9hwgb+uQmynLfW5i-H=(-L~(*W$Nh@=c?wuKN#r_<6lHqvZ1;dZ;x z?RG5$M*W-b!9L~-%(l^=&*#!M<^zEMN23wL;jqPD*LB(UZye8-X*3!=8ry6(NTpJ+ z+wF3!R;!(i@mB=~6h)DJzu(XGdd)-3W;5<~JLYdYw+Elf`23 zh{S-ABC!v0E>my9VVaEFZ8^k46{i#(!br<>I+cA(iVhc-N+o)|UOF5O=JR>!)9dx9 zC#4=tkm$6tZ&}y{+0F_Dwkw^sbcpRFhK~+`x4gvq+x&8wa9)NQM S8&$FZ0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbcalendardatetimeedit.bmp b/mseide-msegui/icons/components/tdbcalendardatetimeedit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..1dd7f940a679b239e9ab62957f75a866ce61d4b5 GIT binary patch literal 1782 zcmeH`y$!-J5QRfSLr293Ouzv2?39r*0m@Xg=93>hS!YX$@>9W6?A+ORU(P4z{&*d` ztQ+%{arulxwz_U)|9sNOflT9e`XZOVRSWrPg?uP+OdEzl)Ja1DfwQ=xz;QkE4fP{% z{`JrS_3)?qGkJSyi(~fg5BxRK|K9igGo|@Yee=z6F{0r%4XwlB(-v;Y35m69xD!c- sW*6HrGJ+eJN+hPqVI3*OiRGeqT|mt#)0?&+n&DXCT)2w`lft&r8z^Y4i~s-t literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbcalendardatetimeedit.png b/mseide-msegui/icons/components/tdbcalendardatetimeedit.png new file mode 100644 index 0000000000000000000000000000000000000000..2f340763fc29aa0f5612fbf34fa01cea261a7772 GIT binary patch literal 559 zcmV+~0?_@5P)cE4L&uh-4m za=BzSn=v?MbbtSu*VjL-CYNG5oi<_78SoLTR;$+cG}B=x3^z;diqHad?AXWlLrx1?bW72ZM)v!0rW*eME+fJ zk|ZQaa&ayqh)5?#qz*fzCU6A?eW4j}jM-9Uu%tj4|YS-jeIxE^?)CQB@VH+Q@Qh&oP7RN#r`= zoTIEnRaL$JM?2>P7p_E?GPu5r?By9_D2jqG44F(OK+VqXiQ||!j)C?Ym1P-enzGq! x>c0Hvb3Gc30N8G~t$Gjy3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbcoloredit.bmp b/mseide-msegui/icons/components/tdbcoloredit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..88f7e1f8b34a386c5c48968f2680ea6bcb93b310 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDj7vhFsutFg5pW*)~qF)I7rvM4nJ zFuwp{#;w&s*+4d1A-K*06BhlBp5SCTR1f@|16NZnhocj9a(^E}%YC(pcvs|zQ3>2PtGbvMbk zO_2O#fB28$qE$ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbdatabutton.bmp b/mseide-msegui/icons/components/tdbdatabutton.bmp new file mode 100644 index 0000000000000000000000000000000000000000..fa300b31fb32e187be971e744c833bd0731658b2 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjf6WEKV1+>9Kg0h~G!#Ps7J;PE$UbdoX!!sC zKaeB?Ag3IlcAz;2NC!ZTSk2k@|33sljD&N63^Wl47neCeS-2Ls#vMC$K-kD6L>cks zV44g!AIKod95kaKo`sl3k~zC~??&@1++0@?kEP)Y7q6_kikP}GNmh?|2JDYnoqqC+PU zL{M-LMG*v-3_{+Z4uztH(3T?DKM@^T>>vmt1O-uX(bXlP~rBa?w*$-eCh9~Aqsrvu`ZjPVT+?-zr$P36m ztA7s8kR_w>>MBh`a~DX4KkJ)R8}F#BdrRzFoax9%LN%R)YC17zV=gU{aT1crq=<-! zmC!gm)FXh1m5}DDvl=Z+BDO+Rk<*imvou3hzS>pHd1Sp$<{tix# zKJja1+oeU>Ia_DQKBuTp$!2ABkJYt(;y*_Thf8Q|8f7;zL%1qHd3ms~Rtv~$OM|kQ zoch7#cNB + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbdataicon.bmp b/mseide-msegui/icons/components/tdbdataicon.bmp new file mode 100644 index 0000000000000000000000000000000000000000..349d7fcba7416e855919a23a5ef606335629f989 GIT binary patch literal 1782 zcmcJPK@P$o5Jhq0#+@sV;0Zi{d+)@_jHhyozkE9R1v15?5SaW9e_ki0?eq0LhddsL zcdT1kr>sKwVE=mI%0`3~5@(FjbWSg!Ggm*%T4J?TvLF zqa5f%hVemrr}WoEiItm}%F*ZCwmQ-e37ccj=dQF}4j@WUjV(j@90x+6p?nT*=b#J% z+b)NwiiS&t402#IT1(*WNI!J?aRvv>Lxz4ArUwNYXr0|;Ytu}(q?_bPF)D$&TT&$p fVe?7w{Ve};psJD z)?4xF*{jBrhyDpqUh)&XdGaK|vJ|QkytNz;bman;dvNl z-Wem6N@3e}D1%N5Pw$`v@TntKA~k z8|05OLdJcGQ|RH!weSLsX%w+cNj&N?GwCuhR-{!EH5E98A-r_msoeRE3s z_%*qFSOaV+Q@8bK1d=O_N8Qk96Qc!IKOXUF*dg~ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbdataimage.bmp b/mseide-msegui/icons/components/tdbdataimage.bmp new file mode 100644 index 0000000000000000000000000000000000000000..ba9e28a3cd06efddbd89de4eb375ba7768a8b68d GIT binary patch literal 1782 zcmd6n!41MN3`Na_0~0U;6EFaGcFJUkeYkTqKXz+b4md5T5Rqd!a{T(^M7>;}dy;X6 zKVcrHxs!zPV!rGY;4iy^YfS@+Q zG04|?JmHg`8*^?gF!mL|2MCm!g6j zL7ClvvvA?c$1DVUT#P8V(v{#!QLynJa3zY0Z$z^gn4O9^X-(UyB%Mm?ezT}bC7sTU z#%brmp^BpF{O&nbb*p50dYW>%tYH`mOE|ioGBq`&OKChf+%OEKTrTU0Q>&NM`0Q`9 zgkdOd?~tGGiLD^daN}=9XFePZ0Nh=&h0|3DXe>)`apz{gI_ah!*yuX8l*yvj8AjEM0yCU3L&@KSsUnU`mYo z2ELw~>2$ppRFun1K(G%n8wRTRcUkLl^v>nKez^Jbr$q_+Z_JmE-Xiey{U6Cs4^F@N zbL{OTW4$vLy$7R?N@JGePcO_|Z{Bj-BZ@xR_JwkP&C_f&GlC`f_bbbH7kN&s%ZTTB6T{mcYCGr;l0000 Cxp+MQ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbdataimage.svg b/mseide-msegui/icons/components/tdbdataimage.svg new file mode 100644 index 0000000..7ac811c --- /dev/null +++ b/mseide-msegui/icons/components/tdbdataimage.svg @@ -0,0 +1,317 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbdatetimedisp.bmp b/mseide-msegui/icons/components/tdbdatetimedisp.bmp new file mode 100644 index 0000000000000000000000000000000000000000..124eb324d65ace71222d803b8ffce03c6a20299f GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjf6WEKV1+>9Kg0h~M86RDPXR!RsfLDzegFTH zfk4*N(i}*#!gLr=98(Y|g3CP+^>AI73^dd5n*&q~Hvys%jSDx8&gQ_K0cXHn0%72H t52h|m5rXERX#sMP0g>)OQ$~=B%U=XFqA9>M2beX;1IYPels!~J004FJ*Q z&EljqN7MfSKane$Oe#kK0K2>M4#h9N0RSwkiD{Mr&@_SH--Fxj`qEaZ)OmWUwbeCE z5D55NYVQffqRGg}IzvMPG@A<3EHgbl#_{n66BBxiDUrA)7CQ&v?(Tv9{%*WpH@&?+ z^7)fi=*LN4pARYH6bfh5Y8Nam&9bs`K)wFbVv0sXNEt`UI8#%joStqXWxOrC4e(jp z+p9Dh7OB(?0FlT(S6B9Ke#c`vGc!&;F9F!vT4r)mw*~mRiytI}K!~^T!a~qiICR*7 zQVPSkB^VsG9o!M{_*i9cFM(xQgu` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + D:T + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbdatetimedisplb.bmp b/mseide-msegui/icons/components/tdbdatetimedisplb.bmp new file mode 100644 index 0000000000000000000000000000000000000000..02920f6acd4bcd39c4bde560bec715cca64f3793 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKg9Kg0h~M86RDPXR!RsfLDzef$2C zfk4)yne(4|<^atG15Aejg)s$zBG}ynHU}sP*M-SIGY!8v$VNdl!VM(H9AJpS0*yj* zK-$5kk!KEEJH!yEH(_o=_8Ok>K{Eu%MFz-*0NJ?AfjfWz1D0qhH3t?2nC1Yp26+HE LUyQPcN(cY|CSSj4 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbdatetimedisplb.png b/mseide-msegui/icons/components/tdbdatetimedisplb.png new file mode 100644 index 0000000000000000000000000000000000000000..a7d2852f42f944d969b7a8784eb307e3c1a5bf64 GIT binary patch literal 584 zcmV-O0=NB%P)B609a5|hWB!!BLGZiX zargavf86ixL^_?uO)0LrKLDDMCy_`GIFt8`yIhl1Bx0YE-)(AzsnPtQ{-6^UV(3=Q?Mwl>A!V9;T- zxtU~n`5OSo$ES35`e=Kk(V_XsZf!Z%IwJc0?c{P_ug5DZamL0zqw8PLw7;ohu?VqP z1f(Dwnqhw86CZ}dHLI=LMRRlGl*=~T+j{_vj4ZLc`{(8tyzs*hR|?p7do*m*P^h15 zHV44$>?m(uyn>&8_~nDk#$8_f6mLiffe?VD5)KT*Ny9A;)r}yfMBhJPAkbe;ZMJ4! z7jSlR!QxCD+k)uZ_W&Ff3RtDmzXMFOh^9r+9!Ckj{D{7Hz|QI_9#sV(GCj>sD%BF; zy5?Z;8PZ6?VcVUDr*CZBn)|-K-UPt(RIj$Bwv?_J2`Qz!k6k8{5pDwR|A%w`0lxuW WScO-E)dw~J0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + D:T + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbdatetimeedit.bmp b/mseide-msegui/icons/components/tdbdatetimeedit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..c1cc4ed56bd3fbc86b743036f69913640bf6a9b2 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKg9Kg0h~M86RDPXR!RsfLDz17rb^ z^{D0m)4;y}|4BkXn{k-~NmiJqA=?6B14;bm01bib!el_KfQS<`2iYiOjSx0mmj32Y z=r6c-G>@Qh@%szS5Fi&Bzyk*;h{qhbjl?i;nS*REk!;L#2+SJf0pxr!${s2q007-{ BX^H>< literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbdatetimeedit.png b/mseide-msegui/icons/components/tdbdatetimeedit.png new file mode 100644 index 0000000000000000000000000000000000000000..31a987916849604728c932fa50425ea1c6105c59 GIT binary patch literal 347 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ zFuwp{#;w&s*+4Q`T4h0F8KQwrJ7>g2YIC9>JAdeu}|!?yf(*VWWr*B9Tn zHCbx1gh%IAPs72xTcmkkB*pwV7#$ maeXEe!&4E9f9=IJjpD{jLZp&*-eCs%k-^i|&t;ucLK6VdUxJ$e literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbdatetimeedit.svg b/mseide-msegui/icons/components/tdbdatetimeedit.svg new file mode 100644 index 0000000..97dc7b7 --- /dev/null +++ b/mseide-msegui/icons/components/tdbdatetimeedit.svg @@ -0,0 +1,243 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbdatetimelookup64db.png b/mseide-msegui/icons/components/tdbdatetimelookup64db.png new file mode 100644 index 0000000000000000000000000000000000000000..cae63dd778bef8fe71a28ec8bdfa909816f9b19b GIT binary patch literal 843 zcmV-R1GM~!P)nK`W_FcYI>71R@f*~d*37-lME zA4C+9UIa#6MnUc>!a%%;5#1#A0ewJ9RHjB@Aw*xVkyr$E)+EWS*i2`dJ6&w%%AIXU z{;$sa{-5XnJJ0!eHK)^QFom)LIGxTZ2{#NQ2na5k`1x~$@85p}$yN(#X*01{5+XKx zy#x6D!{Zwxe&}o_vFje`$r|p07vmF*sj2B1yLO#o-n=w^{TijO&qqIVH0o@Z><$XB-IJov=4B&=?({>pJf6-JZB_Fs3xaFsAmf>*(mv%uEr{ zfSF3EeiMI=QmQW+Ao58TY~BgH1s;mXZ4sIFk6#G9ixzGQ5Rr7?46sotwF>wE><;ti z0;d7f>BnUDqiqG6fo~$RSSeNckAEIG3Div%kOj;KUIJf5WC$ozN_`cP3W5_oh!qaz z?;sgi3M^AftpQ#GdqiXrP!1fACp;RU2Y9HI8VRl2fDOPQAO}#uQy@h|-b@B?4_GH6 zsiAc-@EkY+k)|zXAI_ V>gs%Zl~Moz002ovPDHLkV1h8bZJ_`F literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbdatetimelookup64db.svg b/mseide-msegui/icons/components/tdbdatetimelookup64db.svg new file mode 100644 index 0000000..c5e4897 --- /dev/null +++ b/mseide-msegui/icons/components/tdbdatetimelookup64db.svg @@ -0,0 +1,396 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + D:T + 64 + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbdatetimelookup64lb.png b/mseide-msegui/icons/components/tdbdatetimelookup64lb.png new file mode 100644 index 0000000000000000000000000000000000000000..482dc0a64fcf817719e49bf751b694ea69dc7511 GIT binary patch literal 788 zcmV+v1MB>WP)S(fwf5`LaFE|LPlhFOi4`>XS8wrn-*7Tbi6Zz zA0s)+Q|292|_>Tkh{q4A6C*zyikQ$Vj=ll%z$Y(S!Zj4G#}%W~PW} zK$cP}Wa8&5rREX=Our%#X#&0geIoKwMC`l#THtG=#f16a$}tc@bFwE-9tvMZ|+K(VJx9V15Rf zKqXM6l&S_sfh!_%6u1uDNhLfH;3v?hl-mBS4FEO34WJZIz + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + D:T + 64 + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbdatetimelookupdb.png b/mseide-msegui/icons/components/tdbdatetimelookupdb.png new file mode 100644 index 0000000000000000000000000000000000000000..38b8b3a12f0f646b3e0676df59fc900dac3c17c0 GIT binary patch literal 632 zcmV-;0*C#HP)l4zfC!T}+~5urN#M z4?;u{=`F!y(82fA!Gr7&qg!DnWI>almKs5YAce6&JOuT=Z6r-W-r2UC`aT`ra+5hX zqTTkrJwLv`@8|b>cz7gLRRtB40-&mDMZ$#;7Qi}0SX*0XW#y+uR%G1ny~wg{$7aJw zk;!Cph4l=~PvTg3Nqwz^9+=B*@K=$@2YPyL)6n2%V`G!$3fkk- zXty?T+9hU3FQR>a!ua%EaO~OgDFvN*vfC9xp?+MhbLe^kpU=Y~|8=H^PvDJDS*D|1 zpo~H5*=@mP0RZaiocR5Xe41Opmv~Jukfi?WB(!zIku!fn$BOos1dvT5{YoOex&tkC z0+%o31(#NFKsF80XBabKzQha;pF9s8m&y(<4iF~1e*_;V_>nXjm~wNfqnU%2TT|0jVzH%v*x-IIUHibC zy|(Keo92sxS}HZMJ3!Mk^!(~#*#nl8B!sB!XBUk|rAh*J{>iF5- literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbdatetimelookupdb.svg b/mseide-msegui/icons/components/tdbdatetimelookupdb.svg new file mode 100644 index 0000000..128679f --- /dev/null +++ b/mseide-msegui/icons/components/tdbdatetimelookupdb.svg @@ -0,0 +1,385 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + D:T + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbdatetimelookuplb.png b/mseide-msegui/icons/components/tdbdatetimelookuplb.png new file mode 100644 index 0000000000000000000000000000000000000000..f390ab9f61aeea3866b63f2e91c7f24dd13db252 GIT binary patch literal 571 zcmV-B0>u4^P)RR0F=lsQAm(nV5q=%NLOtcpkkmjpo<HVQ%q`23069odsoaszUrDm2;`R2Rs$Gv37Yf&u%eM{l-4z#o zHv^dNm(r(xF_GA3em;WF=cQV$ad}x}dU}LdY>~mi-Umj@%ir19*ahJ9^cVi2epFOG z1mE!^5&^f|*AOoh3Lr$BOlFl*X&qhfCLE47B#lNF5F(C9uc14g?0s87tpAkeb$Y!2 zzj8P zl|MX#|4C64l(I}b;U9xLJ5^FGJ1Ar-oE&Evb`0A}Y#&h6$nD&+@cAo~p;6xW{Q#KR zEY(`=>45F+162wnikwAlMQp% zTU*TmLI}(}@^QFrhqEQcvaI%gcBxcKX(yoNHSGX8fDYjK`U9MJipYX(5y}7n002ov JPDHLkV1jar^OXPq literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbdatetimelookuplb.svg b/mseide-msegui/icons/components/tdbdatetimelookuplb.svg new file mode 100644 index 0000000..f9441b8 --- /dev/null +++ b/mseide-msegui/icons/components/tdbdatetimelookuplb.svg @@ -0,0 +1,384 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + D:T + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbdatetimelookupstrdb.png b/mseide-msegui/icons/components/tdbdatetimelookupstrdb.png new file mode 100644 index 0000000000000000000000000000000000000000..68fe918d8bc9b585123168a6d50ddde79f94d895 GIT binary patch literal 798 zcmV+(1L6FMP)v+y#o{O$`O zLW%SyGP)=Tx^NH`d11Q<>820-f~;r~)lw_Sh@`NyK)i@*Ym)d8GHseu_jWPUiF@4^ z?0@$@=Xw6W^FO@jXe<_sLJXw?uvjcHF;^5N00?~8nVXwua`Jb8tkYsLZ9=P!3pwoZ zc$uB`trX^GVX&L{p%)}4YH$?|tR(m+yZs|oRaZ$%GqJF+$i&1HrKNjlZazb5s&N&d zp`jI2Arr~I7jF>#h^DbWmsyl6rQGtdeo0~5e$zyy>4g+ho?;1J*iYJh4fr9G6FT7nC}9Vz8D z;2KaYrR)Ws0#~GzJ-`;g4D1H_qDla~0&WN)@&MZsB$OUWDcx%3stKf&?Z95(D{vW5 zyGg&+Ggk!&AsT^QQp)Q<6;QCWGzV-5XBsTEBWeY13n9(|nZWs_`g_1Cgz!fS&`2qx c*-+H_3yinb`a_%)8UO$Q07*qoM6N<$f@;lRRsaA1 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbdatetimelookupstrdb.svg b/mseide-msegui/icons/components/tdbdatetimelookupstrdb.svg new file mode 100644 index 0000000..7de2af2 --- /dev/null +++ b/mseide-msegui/icons/components/tdbdatetimelookupstrdb.svg @@ -0,0 +1,396 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + D:T + str + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbdatetimelookupstrlb.png b/mseide-msegui/icons/components/tdbdatetimelookupstrlb.png new file mode 100644 index 0000000000000000000000000000000000000000..a76b9447d8aae242a0b64074ea71967681b2a9b4 GIT binary patch literal 746 zcmV4eRc;ml+@ce*%(CfnK0 zf<1TV`_B9Pp7;CCdlbLluTeu;0sMY{P0Te-(*gQJgiL0eRO+`*wpwsH8?jjSlq_Cb z+hB8Zt7yG0Q;+LUGqHv?-KTIf68T17Ux3zDC)w-{D=TTby3P>_-Jzvr-!7w}p<%|x zz5=kY@C*0B16Z(dw*3Te0|98z-z$pe^?Fd%F!A^Z>+7R99CZu~1dEaegM+AQ7c;D~O69xnz(|Uspls@iFS#$kwwWqj6+2jqXPBQ$&|&K^mDoHW zZ6*0-i@}@Ex$N!asM`%dERi6)v-AIesj2VO+qI+)&;S4c literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbdatetimelookupstrlb.svg b/mseide-msegui/icons/components/tdbdatetimelookupstrlb.svg new file mode 100644 index 0000000..218fca5 --- /dev/null +++ b/mseide-msegui/icons/components/tdbdatetimelookupstrlb.svg @@ -0,0 +1,395 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + D:T + str + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbdbenumedit.bmp b/mseide-msegui/icons/components/tdbdbenumedit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..4925a6574f4c5223fa8eb393c6a1bab6f673bfa2 GIT binary patch literal 1782 zcmb`DF%rTs3hUZ{Vh^!t-ix`%L6;uLO-b>0~`9tJ!Pbo-%D<>MTA zs5$UA!|iC7-xxK==bIwV#|=s}YvTbp*l^%eJt8<3n^INGShH0GTagoQ{I21s(B&52 z3yWPiZVFNOvGXWQaFR^)Q*&I>6ynInASatzmV#s3eL{1F+3Y1Auo;WU!3l?>AJ=+I z8MVXh3Vv&jP$pOiWsVA2L4D$EqG}GAnnRL^1pSWq$;gH2r?|r7)u3Wu>&Uu3=6Gl$ F;sp&SM)Cjv literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbdialogstringedit.bmp b/mseide-msegui/icons/components/tdbdialogstringedit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0ffe1302c09f9a3c7d51ceaff9afc33ae5574839 GIT binary patch literal 1782 zcmeH_OA3TA3_$B5|T_f0@9h`A~6{ahs>{g%THOd=&EQ7&XIaV$+&402dAkzKuD zk8>1)ui$7IwwO8&f2o2ZP)|JsG?M&1eWe1ljP!VRKDMI-fmz2qJgKsS7jh`}sKj`9M&;S4c literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbdialogstringedit.png b/mseide-msegui/icons/components/tdbdialogstringedit.png new file mode 100644 index 0000000000000000000000000000000000000000..c2d1b72c0eb0eb1a81371d62f8a1ee62157ce90b GIT binary patch literal 569 zcmV-90>=G`P))%%Cs34iVV0(L>o0}r9uOG7)5ekI|3?t}D(5Zqi0oiPU@$nF& zqeJ9!cXlg$z9}Xrw^&=7aRI{NFj{Me{VcmhrP328Cs*|JOaTxK4!ob + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbdropdownlistedit.bmp b/mseide-msegui/icons/components/tdbdropdownlistedit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..c394bb9d06e2d2e584bb886ee2133901cd3b67c3 GIT binary patch literal 1782 zcmb`D!41MN5Cp@A2Nh5P6;J?wdZIEEiJthHRTf64b7UDOCt}v;+sQh&`};U8b=7*& zbN)VuMNQMJ^ViAGGN@(VuYSn!e`k@u{8^7sT*{o31~7d(5_}BtG%%b;M%%Y@oT283 zzgk?!r)({1P8w)$9fr?>XuIlD#h{cka^j_Ij2(2%Oq_b4(QyD`AR3m{BQ7P8@{l|V zAT-?}PtC#7Bg7F|>qZXmN*rR3313spXDR(Z!XV%%1{`Y#bCZs@vg_59wuuwxqn6!U tI5uh(EpnJ-UINW&v@}D-M;hBLG%|tDGzr zJAvOnhIstcafn>*J500q;&5aFy}ffF699lzDkaCt$_fBL5?EFdM@Kp~Ha_9-@CPjG z$zgZ*EJjB9Yer*qbW{!-k|3E(!!YjQ@q9o&{|m`vS{fA!``Fx!*Cfz&-SKn~#9}AV zw0V#TXxh9ZOplKynw#G^oE3|IaCi5!wEz1BiH*i5f>XrfUjP7sz*|gBea70_M*x7^ z{SKkftmDIM)waki&BAM80_fiAW6>5%rG1d^Wouv>+92Lqh|@;V?-uo6T}!VuDRgO&l5;Vmh6!7%n?RqC`+t z-v8ivnC$A7tR+cQ6ot`fv}%v9cEKchets_Jju6=dBpHoHsVE9ba%*dgZEbDb+1Ys& zk!4xW5B!p#{JpQQkH^Qy^m@IoQt>=ZYZACzE_uFnhdQ_G Yzvh7kub1_5XaE2J07*qoM6N<$f=394NB{r; literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbdropdownlistedit.svg b/mseide-msegui/icons/components/tdbdropdownlistedit.svg new file mode 100644 index 0000000..8ba47f7 --- /dev/null +++ b/mseide-msegui/icons/components/tdbdropdownlistedit.svg @@ -0,0 +1,458 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbdropdownlisteditdb.png b/mseide-msegui/icons/components/tdbdropdownlisteditdb.png new file mode 100644 index 0000000000000000000000000000000000000000..4f58194a24d92e95483f7ddc730c1f375319aa0f GIT binary patch literal 952 zcmV;p14sOcP)KN`jG5(r@L_jCH>$sbMHNKzWbdy=Un4Bj#y1Njw8vHga8c?wj4^6$ z-DB5E_vYrV3ea*0m6DB*-=?*752@6hz#-=6e9|vlr?(# zbd*b%QdJ2&&kH;Q1mokkNhZ6IT$0J|K$xCC&#`XZYXN74!V4ZhezLUxcNs|$H7^P7 zkV<_6KwI0p96o%CbLYMSpuYZ7`ugI54`*jHG&Fq9!-wBfTicG~I2BbHNvoQs23S>s z8o;L6f5V}&6=Mv6Iv5_lg)uD*58o;=Y9SQ*khZo{0L;%np}pN<{rYwq8;@}J?w{7y z_kD~pmFoajR%ksv7l}mPB%A#O$N7w&o{QG5nE$1903gX#E_Y3vH@~j?_rKGoO&gTU zU9;@~(DCD+NODzISF44EU(4EtBzc}^$5M}zP1DjsE6xuddEgl_1GgZ|}!SCc7oMN+!E?>{zE&kjeb4jT<*ea@E=Sp8ER}diLx$ zoj-q6d-q1Hf^<5qd_FJF^R$%yvIIMKZrAkmpd?q*(}UWzYr7>_vnHhe{)8k~v$H?y zz=3A1T^rW!-EV1X>RU@tieiY&62Y?aR*pkuVR9UY0D&FJGsw?jx>TnRq2ZG#UjU5{U%nHI8mfCQjCuN zPB^?MZtK=Jn3?&3eExb>f=U-oS%{2ju|FB0uP;tx;}H^x_Zb}gdRgbi400UDh6nzK acKr`6n+aa;t+M_A0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbdropdownlisteditlb.png b/mseide-msegui/icons/components/tdbdropdownlisteditlb.png new file mode 100644 index 0000000000000000000000000000000000000000..0c82be4462d37ef61502d33774b5f4bfc78bde6c GIT binary patch literal 986 zcmV<0110>4P)Y3jmO-I|);_e<23KTCf)7cD(4{ZZ zlC;ncakdXuA%zu+5DP_=aTW3snuq0~u!rIHU}y0`X#!0Y!O}pzA|n^#N?$5Wq?Jfz zlR}v{o;}oj<}T6n#r@%M@ArNGd;Z@!_nhz3bX^w?61uL7NJ>OfGB$Q!02v#*ujT;J zG))2lubL}ed-LWu0c0;YO2rb1c>)11$)sW1#M;_8TU&*)&55Kqd9n+U6ac1aDjOai z20#f|R)N{sEb;jF%*_0bW$ijVe!LU6yP;|}JRXm-B9uTTvqV1s7cN&1>+64$$t)?- z=H?_1A112`WV2b@(Rsc5V=BU4XndsfSI2^k{7q++gV|ketmrJFj5=0C`!Z&V6tglbRFeKL3 zC;c~XiWr6fl251Qi=#(H3`4%Xcu|IWd*%JJXYyk>EMK>@h!}>5h~#oPu`Eln*{tl8 zzbJvmQ>WzB#Ds`p$g7D7`SSE>CGeTUAw#{rB8DL=iG+O9+A6g*HS*Qjv$8Zkt^`W4 za}9{LBd}+9pA4_JEKRzuV-wJPJ^&6moji_2xaRkNvVXI-7Ps3?E|;UZxf#6r+wBIRsj0~}c2*)^^ZQlZM@C1Pj>ow*GQzE3 zaQ`SwQ@u}3O#zfg@L#Ov^R$IRyk1?cM&19yDaGX69EY4AgFA8T7=J!_g7xA>Re?$u zPFadHpHKZ{fPwCA&UJLq)!xp}LqmHyFIJGQ>nc6)KOEQp0+d$XmNj160000007*qo IM6N<$f(cW^l>h($ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbdropdownlisteditlb.svg b/mseide-msegui/icons/components/tdbdropdownlisteditlb.svg new file mode 100644 index 0000000..0da17cb --- /dev/null +++ b/mseide-msegui/icons/components/tdbdropdownlisteditlb.svg @@ -0,0 +1,465 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbenum64editdb.bmp b/mseide-msegui/icons/components/tdbenum64editdb.bmp new file mode 100644 index 0000000000000000000000000000000000000000..873a626acfb5046f0094708f102e6c07271a5519 GIT binary patch literal 1782 zcmb`GF%H5o5ClU*Lr29EcmWTf=TE#0hDF?8YckQ~&%V6hEr?l=;n)wiRQDCDR6Fs(U4nP4H5Iq`e7IE$#7Lk1eIB8Maq37Yo!$;j#7Do$|(1{{SS MU)l}<)7RB6K2Rw{HUIzs literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbenum64editdb.png b/mseide-msegui/icons/components/tdbenum64editdb.png new file mode 100644 index 0000000000000000000000000000000000000000..29d1881f3ce6cc79ac6ac3e5ad2f236348608969 GIT binary patch literal 1033 zcmV+k1or!hP)FH@zUEROmPhH*XB$FvNY*-J# zz`#$`*B_#(>8*LyaJgJ6vQPviCB->E-@7+ON5@&to%Cw zIRtZY{`}AQd;taq4pC82Mpe~z9z6J+6)PMpU0Mo2DwSq(G7iAZ%+oxQEEW|a*t@rv z>FEScXA=OIE*ZF7pJKD=1cUnkn3#A(Rn>Ox-08z^--=-v1-sHjWI@MN0~VBE5r9be zC6sE&%V?Tb_>%uGEXzXEG%U-av$GTU*A%7G!jU6`tXlOU#l`QjWy@h6K8zJCHZt-n zy8doXE<67P-vNN%f00wCejpI=apg)EGc!-wv*$!!@$vBqJf1Gn>D=oxO;be{YD`6h zB{s)bXU(($C4#$ptr}9}z3PD7|GBtHU0O{#zlQnC~ zrKF@-wrzV;rl-GAzVqza_p*8O8{+f5FVSdljt^zLXl!gulF6i)rYX! zTQ6iDWnQ$lHY!<0M@N-)1EM`A0ASs^-2{XC*toG8fJkJVO`F<@$G;^We?lVhmpaw$ z+mpE6hlxgmEL*mOl`A~}q*5t#J)?%EX}Mvj-&YfpHNh!v48*9?Aq0U-Cm5{ zUe4;(<$3L|U0bQvmSw4RC=|-Q1Aw-+t=zr)8y-&=x?Y6W`!?O(9~acM5avFxth?q& z^kQhhvMgLK7p7?v3WYEX + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbenum64editlb.bmp b/mseide-msegui/icons/components/tdbenum64editlb.bmp new file mode 100644 index 0000000000000000000000000000000000000000..cfe0ea3da9e899b1eb0274c59c3969cdec6aff53 GIT binary patch literal 1782 zcmb`F!4bkB5Jls~gB4hU6ylxlnAmBbGmmduMB z?___BRql*9vb2&zZ6TOZ>p3zL9Y#NHP=TFuy5m*=2OAb8>anO*BZ5Sfx5d7QTbxK} zab&b_#tmslK?cXB{U1qXPK)Fw>+r0d7*<@1gl z{D6wCO!g;bsOM;lWz7-F1P4Ny6MwH3XAxC%$UwtYpkZVuKwT&Un?Gq literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbenum64editlb.png b/mseide-msegui/icons/components/tdbenum64editlb.png new file mode 100644 index 0000000000000000000000000000000000000000..de0fc40f76c1d72099a2af8599ce41c82b223c18 GIT binary patch literal 1034 zcmV+l1oiugP)lV7;Iww zq3VUUyL)=E*{|8`ZZB$m;V@?oGw=JI^PO`v!!U%+gkcyW5|qWoVJRwdiAYd}hg-$v za?1AYdE)ccOLOyk;&g5mr*o?q#`_`?6p^3+GB@X!!oqw>2PJUq*gFDW9Z{QT$Cdt4;ui&&PWEXFIcC7wxVXT8em!GnH0o>vHmBkbApIsgL$ zKTuwNnwpw7(^kXnb}NfR31nwyC47AU{v2n{^m6G^3jnpX<=npAO@IIOv;vl8B|H-Z zp2pzdI1LS53=Ev6urQzE;-fr#I8Q-=lWp5_0ffj?XhPhwEM;-1HWd-R z9vY&nrGLj0ey+lR$^5n^sCoL%{LDzLkOG{NoszjL?F}JU+ zja@r;0`OgHE4z*y;g8i-0yl2({jFR4)Z44ReHQ7;Bx0JfJU%XftWQj+wAUvl1dv}Y zUzXa63L!R>NmgH7t;!M#h1BW>M0+9tz-xyN(R21JZNr@QcMYKnEhYyH)+KCZEtJZlK=n!07*qoM6N<$ Eg1MXI;Q#;t literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbenum64editlb.svg b/mseide-msegui/icons/components/tdbenum64editlb.svg new file mode 100644 index 0000000..884116c --- /dev/null +++ b/mseide-msegui/icons/components/tdbenum64editlb.svg @@ -0,0 +1,452 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbenumedit.bmp b/mseide-msegui/icons/components/tdbenumedit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..3e2c2d4d070e256183f2686f668cd21bd51ded68 GIT binary patch literal 1782 zcmb`DF%rTs3u>ou#8YQb+JW8VSgYzhW zkaPw=nM27pLL8Ab4|2Gx;$XW^_?cqfmgV~oGlIa$QYmnK?#5Ko|wb qg_=eC#92jUjxw2}q#_c$9Pv|-PbOb=1?_dC;=5>Chk!%VM#KYg$!?AS literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbenumedit.png b/mseide-msegui/icons/components/tdbenumedit.png new file mode 100644 index 0000000000000000000000000000000000000000..c71d8794e094527dbe84de8b28eb2f5521e406ed GIT binary patch literal 960 zcmV;x13&zUP)5`b;7bNNh|vNd0wGVK+=ll=i>?le7bYzTRnUB zNW;VZ^7(4y^VP_*ew4H#X+?nc_vaK0)~OO)f`<=(5Flwqp-@0?-i#}gnUL38?IwKv z`WMyJ)w+9!4UNePXd`UcUSpfcy8mdHZ&PnVH`!5~S1Vl79)oc_fp6^7!$u z%+5X~7_6hQ@c|z`9N_o+xP99TK(Y8QA3y#Dz?U!oTq1FBqa4ALClh@7^f!UP006IE zS+uuDG0iGoy!Z)#y}dk*jSqPD?l*4T>cg_EvZ@S8*V?8AaIFM40Io}fVHl-FP9~EW zhCwo!EDiE_=m?G2u)ew7o0FI81XlQ6)Y-|jV=S+05 zSY&&9o3^$#*OGFOBn=G>DUnD>k`jr8hKGk;1^Ikl_4W0Vr2hVX#p7`uA0KOcd|VwJ z9j=1S%}v?1t#mqlUi}F{I2=|so0TMGvspDaH@iVqRaJ_|&mMP%Fd#RFd^IKK{sLRwo}Q#c&{Dis&o^hyGc$Kw|IDmWGcE;C|SYb38b1Zu4S0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbenumeditdb.bmp b/mseide-msegui/icons/components/tdbenumeditdb.bmp new file mode 100644 index 0000000000000000000000000000000000000000..4925a6574f4c5223fa8eb393c6a1bab6f673bfa2 GIT binary patch literal 1782 zcmb`DF%rTs3hUZ{Vh^!t-ix`%L6;uLO-b>0~`9tJ!Pbo-%D<>MTA zs5$UA!|iC7-xxK==bIwV#|=s}YvTbp*l^%eJt8<3n^INGShH0GTagoQ{I21s(B&52 z3yWPiZVFNOvGXWQaFR^)Q*&I>6ynInASatzmV#s3eL{1F+3Y1Auo;WU!3l?>AJ=+I z8MVXh3Vv&jP$pOiWsVA2L4D$EqG}GAnnRL^1pSWq$;gH2r?|r7)u3Wu>&Uu3=6Gl$ F;sp&SM)Cjv literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbenumeditdb.png b/mseide-msegui/icons/components/tdbenumeditdb.png new file mode 100644 index 0000000000000000000000000000000000000000..3764f26806b12e396fbef0eabb879977ca6be531 GIT binary patch literal 1024 zcmV+b1poVqP)tPg>wd2Lc`Vzu#d^ZFZAp$EJQ!3#fnSoN!NFGf{XT8j z@S-|9kE*%3Rz6>re7-E%_Ir{XNsa)`&kraN$W<~Jf+pJ?G%X29d3YoE-SMtP^oH=vUsG6ScrL3%oNF+*m`6~eQ_y0si#R>NB ze?4h6N=r-4h`|t~r@xR8eCN(QEiFCt^?eG!fdds>zurY}?~h3dLZMK?H-R7?!QdFj zj(tgg{|N$tTnY;ha`)~cd3io^axwvkMxQb}`w)O9PySp%5<}{01dWYd+`s<^e*b;| zMn`Q*OB?WdQ#g0-V*qAm7APz{$nD!-laW!4ZQHA=vLvmmO)X$u2~q(h=RZhQx#Evy zS&4@n431%0RRn`$aY0phJa4gY-$?-G<{naAZIhWD8-~EG#UsdGiNmy=Tv> z06cm$On!bHr%!)~$77kDMWau-abud2l9x?MR)Zu*O-*mBz5R$JNA2xL)ZAQa6f7)! zr;QtPBsr?BeNC;cb$a}GR2>~3Y3I&jqhey>S4AS16bgmn)h`ol*|JGfQ{9prO-*%c z>()&sC?&nj%H^1w0n1n($c)zw(TWNPJU%d6pvVmtY-vCf9~|Io6n9NvrJ3`*uH%Z*UdL>T5-1z4V{$Nn<~lC*|Uwx%1T#H zPxC6yNpz7UMIw>EADeg=#iORCoNzb-z^PN;aQX7*)YrFDU;pMBDqJ%k85seRT-Wiq zcW;qhyPCLl>-ROw^sf(2JcfsV#_L@c7YO7sJ>5$r^23@0t35a?N@Q78=8yqeTHd9o u=rDD4Z_wTSNz&vo2idl5$^-wyb^RAat7PW7P7+)I0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbenumeditlb.bmp b/mseide-msegui/icons/components/tdbenumeditlb.bmp new file mode 100644 index 0000000000000000000000000000000000000000..ad648668e8a3ee850280b54a2f23f60837693320 GIT binary patch literal 1782 zcmchU!41MN3`NU@0~0U;6EFaGc4D%s`*7!)KJwwqN(!wKgq5U@6TkSom+NCcWIMB- zn8(-LWp5ZJ&hH1!e351PoxPFmU)4hXIHv6*rF08sQQ{QU80)wraNG=dTxhO`M5Xt0 zR71^yzi5`DQ?}7+j_Xb$tu0>JGiV^!96~IXdwmw literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbenumeditlb.png b/mseide-msegui/icons/components/tdbenumeditlb.png new file mode 100644 index 0000000000000000000000000000000000000000..d1056c4d97ab797a8d35eb4eb5c13fd89ba823d9 GIT binary patch literal 1043 zcmV+u1nm2XP)0+%)O-4iW4^_!H1-);8Gu4 z%cRg29jyb~fG-y7(6S=t;abRxtPhoTGRknnDisB76>1#aY%8=^e7Lt{D}9+%E411w zYz)elc=n+A)y%{ehWo;g`}$XeLU{IV+ zhvekEBbP6qk(QR@;&AK`hhvB6`WGTHCL&`3$ihOu3SnWi~t>k6LjlKvq^pg7K3l3$(U&bM4w!0Myo2@bF<5Jw3Nm0!-6PcqRbW ztFP~88XLc%xA#1`x!L69)$#P{3wG~zuxpncfLLsWXU~=ac=hV94Uo9fk^#=1?c(Lj z-*Gx?0Jw2O$Kz=rJ$)NjuYL)@+}t90d3DUp{J{3@N6>XWX;hksY-yQlz?K5i0K_o< zyC<)A!z)eG5-+(g97gl`=nIEm8~J?L_V1^vxfy`xOG_L%cMf}bIfd2LOh0<0Y%R+| z(=;s0qP@Kx_*WH;+`GqTWo3*`P9}WG^INz0I~oO`p`(MMy?c2vK8{{rPeVtCvWwS$ z(*GbDi*b8;n$DIMew>;j8jC5T_YNJxT~GkP_=5+uoj#2{D~l7Al}vSaD?8IP)rw1% z>7-?`xV%jMv197&FD(V&kBJH1KYW;u#zt(m*FnctR`_*hhLZezm6Bu^Z5WsPfMde6ym7g|JMGk%uL*FH<3t$;^JZ~ z%fjRFY;1O781#oieBRauz_&v~?DYHjespwGfZOc`ps1)Q;hePD9rgQF-G{on8Sm`m z)P)P2s;b&N3d>Ua;o)H*MY~?F`Nc)b>g)M!e*R6Sn-84z8k(3OJ#96(+?*U{Z{8$& z|Na{R$p+4b6lp%6x@3UXx;hH0t2t3w$#=nEO6Tzk(sf;>2mXh4{SPxh{Fe3i6=VPa N002ovPDHLkV1mRb^9%q0 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbenumeditlb.svg b/mseide-msegui/icons/components/tdbenumeditlb.svg new file mode 100644 index 0000000..4d5ee50 --- /dev/null +++ b/mseide-msegui/icons/components/tdbenumeditlb.svg @@ -0,0 +1,445 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbevent.bmp b/mseide-msegui/icons/components/tdbevent.bmp new file mode 100644 index 0000000000000000000000000000000000000000..eb7504d2ce41118364659bfd2569093ce703afcd GIT binary patch literal 1782 zcmd7PF$%*l35{EekB}4e0Ns1#(o=PHe*A+lm62qVkOo@_54Ov4EZw$p`xGV<6L%NSB^ho3PUs!Zu7;>eV7 T*e<7zCpen{=SR>^ZJygNBs68v literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbevent.png b/mseide-msegui/icons/components/tdbevent.png new file mode 100644 index 0000000000000000000000000000000000000000..19ef663b40f1fb884ecb29d1919271d52a68410d GIT binary patch literal 677 zcmV;W0$TlvP)+lnm+^Avt zGNLs!ePu{~r>K-(;u;C1$ zDa8Ize}|*1m@zJ^gOln!gNN@pQO%@zJiNiSnM^9l`qt?Iwax6Rq-Zjyj&plEdHuV5 za8m!5C>-L*Qligk`^Az2RKD&uAdq$zMQYi5lZMX}hbb$iV34lNqVxbkVmTbUOT|6f zW2~Fa`nd#hdkK)VfBD6pE8Kd?@WGU=U}88UAiGiV^#^@}>|M_3E#&oM<$iXb%NUv+ z;BbVhhQvNx$cPZ(p{$+L3xIdcylN-0PcTh)OaEho;;zhKJipzaRPy?0I8qp z)fzqy + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + GUI + + diff --git a/mseide-msegui/icons/components/tdbf.bmp b/mseide-msegui/icons/components/tdbf.bmp new file mode 100644 index 0000000000000000000000000000000000000000..baaa3de4b00e4189b55e2f1a82cbf1eb67f3aea9 GIT binary patch literal 1782 zcmcIjJ5Iwu5M3k-twf55iX)H2ie>6fRP1;bwXB@z`Dm zkWg5SC-Z$XyP0`@Nw<#A6Zj*(2mNkXa_$5E`#bqK5G?=0dE0tJg)AhNrD~B&p};W& z2<8&O)FsF?cq$i(h582^AXpnBn_8ev?Iw%xow`Ioq>DgfSi>ICa%?Ybl8w+o;B#{{7iS`V2shRz?VY8jS+N&akVK zAcMm`ucD;~Ea!dL2Qf-fEuB)_2Z}l;kQxPwb4wh)k@kZyP}gO?S!@`Gvql_vFX7;Y zwVz&#YD&(>Ht=-_RE*$Mh`aiwpA$EOqJ2Kfy?{cGGgcur=Os=!@cT?6scz13SA+9G zV#?iV>?$Qp#^9x2s2z+eHlh$-m6PC#4dF;`PUw(as$T9VIvxfqw|U(FAxv=0^#cy| zBSR%`_(_jLIK%&5f}F{#DJ0UtbLsm)K|1cmAkb)@p^}|B%>#ScSiUp%Wu?o7RT5Ht zSS6&O`WobE??k=O59Ya|EelOJwh?0ts&_RkaUapu`vDZNCYa2+4N&VwSAe?Z<14Ko Tbw)mK26o$Y6qPezT<7--A-&NM literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbfilenameedit.bmp b/mseide-msegui/icons/components/tdbfilenameedit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..2a9c73c31cc2aea392898d29fa9beead6feb8502 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDj7vhFsutFg5pW*)~qF)I7rvMQ7>(YXoQnj%eI9$=9#1CEoK9cod9{O- ziZR9j9iK&&xm| + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbimage.bmp b/mseide-msegui/icons/components/tdbimage.bmp new file mode 100644 index 0000000000000000000000000000000000000000..789c6b5f70ed3c839511843241afea27f80728c3 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDj7vhFsutFg5pW*)?L@?KpLnC{qp`qbF$d4o= zw2&ds9EJvv`zdh`$OH(Yz#N1jK%>Yq2gL*&?%DVMKYoP85Nz(jZwN#di%}TCNbI$YJbKW-wUIo2HpCNCbWhIW~5a z;^L*2Tr_H6vt^N$^^heWkIyhYd7DQr1|aAIApFvA0Cx>$qpj^2e*XY||9${su{d6D z8==tO7)FemnhFja*b2ar50CQIr^lF?x`n6I#>WTivAJqtgt-P26A||8`I7GLKHTn= zseD)0&qN|og27KPj2JFgBd^u0#Xfq5L;HIe+*?TQx-C>R_7fN{<&~VgRIg>$^XG?H zw#-g@`)c|U9WTNb_7k+EWMTqJRT<= zj}yOtz*4ko)pD4gg0o$m?);Vuga6RkQV%cGVb96K=lhkNJCCqoLmAc8ZcDHAw9+9d zOota=$59%-iF5qqL5enRf#fPGE6X``s)egpZ*utX@dX;p#8biqeRPhMv-@N|r+eF2 zyS^NN8#g8y8XCoJFF>S}rlwcv>FJ-xV0sEJ_Q91u5?5|bEk8JRvG424{L+62r*nC# zbaeDORaNg`7%>0>fq^+IvRQ;fClaEU4OmhP4Ie>H9(yaBxpe6YB_$21@|KpjXl|}! z`}UV{yLXYDZKJHr!Hyl(76VP!byL@M%+HGwnKiZW?55Oy7lK$UPBdzepP!q`g~QL_ za5xeZ3=a^gZv#&O3OEZa5s|?MF$e(9i%4NIt^v*g?*S`;3ZM#@ zOnzsCrj$xch)5&Q1Vn&gV6#%{&MdwV2rH$QrWKga;QzwEn;9^J406W<00000NkvXX Hu0mjfi|MsF literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbintegerdisp.bmp b/mseide-msegui/icons/components/tdbintegerdisp.bmp new file mode 100644 index 0000000000000000000000000000000000000000..f74d1456e517a7362fa58fee70b47cf182685e6c GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDj7vhFsutFg5pW*)~qF)I7rvMp%^f@u!KQe^d*Y)lcX=0J>sy8&)8nsy);E`rM(WJ8Ey)6N`V P)*ufc=ZjJHPzeD5r=PSU literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbintegerdisp.png b/mseide-msegui/icons/components/tdbintegerdisp.png new file mode 100644 index 0000000000000000000000000000000000000000..0f38cb36b585d84aa1491e026fb316d224915981 GIT binary patch literal 634 zcmV-=0)_pFP)Sc+h27pX$02nBIE3L+?6O9RoV zW2YE`WVp7Jv_k&i;2;u0q(u}1NtZ5#Y*H(N5Kt*KiOt|rS{xiAl?&-vW5nwq93FQD zrM*GucYD9zd%q9w`{VbXP%IX)Qx03J{|8(~&Rj01*$M!N#YCIRKeV=}T2-mn8>YCb z9$A*D)qY=yFaZt@YV`MqC=|Zwv8AQYh@#BEzzc?k!g_9R?GX59w%!m3JSG~=0uYP6!{-xOUr&-q1PF!RngGu8i{<4n zWV0`k+UjC(@IC*OEBmKpuODy6OWb&GKLi6OVJAd^as{sy?JFA_J47NG0Nm~t6y*bxlTQf-Q>4=$0hpZ~ zr>(8Ua9)VVqaIQb#4_V)+ UhRp$D$^ZZW07*qoM6N<$f;Sl%SpWb4 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbintegerdisp.svg b/mseide-msegui/icons/components/tdbintegerdisp.svg new file mode 100644 index 0000000..6da09d9 --- /dev/null +++ b/mseide-msegui/icons/components/tdbintegerdisp.svg @@ -0,0 +1,371 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + 123 + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbintegerdisplb.bmp b/mseide-msegui/icons/components/tdbintegerdisplb.bmp new file mode 100644 index 0000000000000000000000000000000000000000..4d5a820347c42b577a2fcf7a42df8a495db0fd8a GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjf6WEKV1+>9Kg0h~M86RDPXR!RsfLDzef$2C zfk4)yne!iH4lpIaO@k#3C=C&Z3qrWq%>kN?WDc6KXk3U&eC7Zh26h|V0T2cnNvt`9 zj3U7tB!?mU7s!TlG5rOSf`ku5J1Pm+2=^UC1k)UdArR9*;e%=>!WLNaz+(=YUbx9< nh6A}E5wL++-2-t3Q6$V&l$ryJ0!(v&S%W-)oG(V%LnQ-THN}|btcwtnh@wzO%T{zPhzO!VAe3a&$-HX@Ng{1c=h$+6>et0=^s!MB z+=b9{bq^E|x&&Jm`kr^zNXS!Mq(kO{N{0|QD{1ppilaeG-~IWWH)ich9bQ8*kW z9+y+>(dcSgzDVRpViDKCoDqEa5Y_@|Y7h!VC@ZUHYRaFq4G(`n6eTJuY*bdZBz+4D z->Is)h54MFV@It_yq<@kUd5*p7#*EL6eR+I<)m$6LqU>yaJg>c@jSt5Jx_bP8vuvn z71gIt@$Tt!9@O8U{(g5#blN{RBO@PiyPJ`uo}^8d*XZk$C@DDvKvB_tW@bJ^P|w5b z&FI$kuqF^%SwRqlzYBDA)ubFS7<8CS#{r1PW!mj8sk?L;=8PCMi5!?48W{I_8FxBU z?q@s)(SXc_Gj}*>JV48pt16$fwUtLU8`U-&u~l^={97QdA?yY7*;Y;*Ddt&Q8yZdG zn$Pd&rz~^0u#g&yg?$ADOw7(^D6meVmuK>^T(fi0WTLyVQI+R={r$Wc8UooaC*?!+W2P+r7O2?9%I59vkCsZ7p@3owx=E0eIZh zM6SW0q7yngI+Wxj2lenZH!(0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + 123 + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbintegeredit.bmp b/mseide-msegui/icons/components/tdbintegeredit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..27a82aefe5758d286ecb7ebfc2e9b1230726e365 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDj7vhFsutFg5pW*)~qF)I7rvM0LDP=Rg&0MQIY3>QE`b|Gk~w&cBGnvR zMiDdzr~sk{LXvF`vPQ6x=#d3i0F=ca&Ont!B3$M`96%C@nGS(jgFJwoFGkrzB?JJX Cs(VfV literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbintegeredit.png b/mseide-msegui/icons/components/tdbintegeredit.png new file mode 100644 index 0000000000000000000000000000000000000000..388687a111a99f6a1c268662c08ecee81422a5af GIT binary patch literal 586 zcmV-Q0=4~#P)i+?EF)NqL`C4TQKx^%bxQH|XO~+}gc%||TxTOXsC#S^Y zY1dz0FEThdLwENyg~Cq&HaANQ3}oo(dC%(V)xnfXdPV@W*3!(zkz#RKy1E{_zKA13 zL(iqr_#x%;XNkq4BI3yCXuljCeUobSt3)CX+*lFE-D`{y5fM)YeSJ^a-CglyG&S{_ zV9+8Gc}Ttf2Y|)JcZ9bb)X5RwP+xvuk z{yT|8mf6|V-2t~*sZ?foc%I40Bw9CXb9nfhOy&(+TgxmgeEB!P+}s))8y}gNc!5$1 zfUz;n+1WYq_#*;=))H2$#agY-_VzDQsSobl&dw)n`xS{qmgD0F`TX?X11@_a8Vz%B zP`I&f+auWa$c=fWl887cmBbhWwD~Q%JlOT7wE&DUR4VO6U6~S}zcdR_egf|Qhjae{ Y7poMwfN8X9K>z>%07*qoM6N<$f|%(8tpET3 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbintegeredit.svg b/mseide-msegui/icons/components/tdbintegeredit.svg new file mode 100644 index 0000000..cb2eb30 --- /dev/null +++ b/mseide-msegui/icons/components/tdbintegeredit.svg @@ -0,0 +1,244 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbintegerlookup64db.png b/mseide-msegui/icons/components/tdbintegerlookup64db.png new file mode 100644 index 0000000000000000000000000000000000000000..25b19e11059849556162b67e32b749fcb82761c3 GIT binary patch literal 985 zcmV;~119{5P)CNbI$YJbKW-wUIo2HpCNCbWhIW~5a z;^L*2Tr_H6vt^N$^^heWkIyhYd7DQr1|aAIApFvA0Cx>$qpj^2e*XY||9${su{d6D z8==tO7)FemnhFja*b2ar50CQIr^lF?x`n6I#>WTivAJqtgt-P26A||8`I7GLKHTn= zseD)0&qN|og27KPj2JFgBd^u0#Xfq5L;HIe+*?TQx-C>R_7fN{<&~VgRIg>$^XG?H zw#-g@`)c|U9WTNb_7k+EWMTqJRT<= zj}yOtz*4ko)pD4gg0o$m?);Vuga6RkQV%cGVb96K=lhkNJCCqoLmAc8ZcDHAw9+9d zOota=$59%-iF5qqL5enRf#fPGE6X``s)egpZ*utX@dX;p#8biqeRPhMv-@N|r+eF2 zyS^NN8#g8y8XCoJFF>S}rlwcv>FJ-xV0sEJ_Q91u5?5|bEk8JRvG424{L+62r*nC# zbaeDORaNg`7%>0>fq^+IvRQ;fClaEU4OmhP4Ie>H9(yaBxpe6YB_$21@|KpjXl|}! z`}UV{yLXYDZKJHr!Hyl(76VP!byL@M%+HGwnKiZW?55Oy7lK$UPBdzepP!q`g~QL_ za5xeZ3=a^gZv#&O3OEZa5s|?MF$e(9i%4NIt^v*g?*S`;3ZM#@ zOnzsCrj$xch)5&Q1Vn&gV6#%{&MdwV2rH$QrWKga;QzwEn;9^J406W<00000NkvXX Hu0mjfi|MsF literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbintegerlookup64db.svg b/mseide-msegui/icons/components/tdbintegerlookup64db.svg new file mode 100644 index 0000000..853095e --- /dev/null +++ b/mseide-msegui/icons/components/tdbintegerlookup64db.svg @@ -0,0 +1,396 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + 123 + 64 + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbintegerlookup64lb.png b/mseide-msegui/icons/components/tdbintegerlookup64lb.png new file mode 100644 index 0000000000000000000000000000000000000000..4c9b9d723ccc95f71f976606eb8bb959ccb22f30 GIT binary patch literal 952 zcmV;p14sOcP)4kf;ku1+R(0G%1Br zp3A7?^v{z32RQ=JIQXVOY!}bO6IJW<}hxtc*b>xac77-yf!+ zV1Xl-NTks99CC8zIP&TAILV}m&o>uFbhzs!mRkgXvoed8mb2{K8L?y2OcM%yOij)E ztXQ#|=H^p2ckEaPRaIeDS2xjE{~6{_xe)i*ygpGl9v@@x-d0YZ?xwmrXy@D8uP`>2 zAR0YEDrHhx8D`U_R|o|1`Q)QB^nLR+-eev%yLQpp)5Du}b#|{~f?K!xDJ%@o*0#qn zQDx;)B9R6FJRY6Ji=XG_^%!M|WkgSXi8q-?dVHLRqoZh==IC`8)YevD7(4KK=Q@hY z%Zn*4E&$+CM=!V4Z>$f#0dWrjzn_loZi?2eV|iH_Yin!W4W`71PREHTp@s1e0B61dk%fdrQ^q0RbCFjgLs_&d-n+V{YWrK zQ++*Wy1J%mU}|tDANu@!|AXQ{TN_tTo}{9*)GqmBXoxl8Fe%dnptGmvnNQ@{BKyRH zJ{Z;Qb=%+C%CCcilx^H-mmO?uy3X0|NuZ9ss%7XNLG|lALB)*6dz(y}iAf8z~|h zkgt@AyYMe4r6xPL4c9FakuAW_z-19RFCx!9#jgc^nM&N%KtvV-5#V*DR29$=6@H5U9M}hZF;jyVfg&IZ42j4iV6#$cNJQQtGf|gI zuLExXAP=YjUQ$ZE4BQ5`iO5o*0cf6%_*4eJ1DBOjschU0yawzBN&yAj0Q@4-Hxq+S zpiV^QXXCelAAt{nAW#FW0shIpyFyb+O-hJJ7-#~ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + 123 + 64 + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbintegerlookupdb.png b/mseide-msegui/icons/components/tdbintegerlookupdb.png new file mode 100644 index 0000000000000000000000000000000000000000..95109be6f4c67058b0ae585662dc3c32c207579b GIT binary patch literal 755 zcmV0^N|JB#B5G%K{NiccWuk{>`zSb39#4mIni+ z@XqJ%d(QhlKi>Cz=Ln)Gs_dh50HP@FOSr14VL%;(gkh@0Nx9q0sa8C%Wm(-=^Vr9Yy?1-6|7b}9?y3qNv5bMm!_s$0JPuh z<=LZtHaAwVr0ICjT#C+A4D;*+tgQv8uYXEU&j@Do$%xK| zgWmU%*2X?28jccs<_5V{qqu&gaVaJ)(yN(ue0+xFWIY`nwVH`crW3TZSOJJuLmW?# z`0`jJ)&B-}&vjyNcc7TAv9cOK5Cl!HW&(@Fh{a;W=^WD(rKhJrXahcVGu-u(uM@xM zvX#QQ67(@~I2<3StZXMQFN4BDv!+-3w*IEAU^=ZhI(sR5p)fGmOyc<)u(gW({7i<1 zY%DA+)7CbyN5G~M3C8W9%b!W@U_8Tb?c|)z1Yl`totYUQdVK;}S!vYNT%oUTbQeHq z113jc?pyfEWf$|>P|e-v)4U&T#b`{4l=^%>DJZyuB*_4{Tw^;{q|*d@UWG%aB{-4< zW%nT_j)wd?rl#gdO)ZO*+iW+ft1F?r{32#^HPO*JGBONQR1|6ef+&irD2k|062ne* zF`T{}+3#K?%L>7uM0|W~#PfPjVK5lN6U@%e;@#dczvpa?78iGVf~u + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + 123 + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbintegerlookuplb.png b/mseide-msegui/icons/components/tdbintegerlookuplb.png new file mode 100644 index 0000000000000000000000000000000000000000..cef7009ee264a1730939faac4895f44d92de9553 GIT binary patch literal 726 zcmV;{0xA88P)k}kyZ2To!r=bcqs{_-BZ0d*|ChdGV!x zCV2A;&*As|eV^a=`91ueM-oD)>?33VA;i8ES5m9AIc@9GAUfF zEP33&JIwU+Cm2(?)U>uT5{Yo3wpQD#>tJ$n2CLOVFxa8%$mu+W-`@s+!5~vuc$AMH z;@FbMi4H!(n93!yxykDKI+7&m_Ua7W?s9~oWrglg=sykC zWSGk1arb*VZa-kOx0jO+2LQ{71TzZ@Sj=Wl*zL48H8DIkwo3y=f~h>1HuL(;1UG|0 z-u3rWURtV2zAY_r*5@OwC;*H^BEMXbZi=)M&zWFd*2e9|zyM$7=CCz1XtG;gFV~x! zxm;h5%j3Zy%T$z=ab<@FKoUZzLI~8=S1@nX&G2raWHKaEDRNCFjf-2Yl$4Zgbuc?S zOMDr~*EE)wWB2diz~I2(z+lh#37oCOvYQ*BPyhe`07*qo IM6N<$f?pd(6951J literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbintegerlookuplb.svg b/mseide-msegui/icons/components/tdbintegerlookuplb.svg new file mode 100644 index 0000000..1f74eac --- /dev/null +++ b/mseide-msegui/icons/components/tdbintegerlookuplb.svg @@ -0,0 +1,384 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + 123 + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbintegerlookupstrdb.png b/mseide-msegui/icons/components/tdbintegerlookupstrdb.png new file mode 100644 index 0000000000000000000000000000000000000000..bc5e85f1ae36a5054516086450fb319205105f2c GIT binary patch literal 933 zcmV;W16urvP)M%5<2)V}qcM!Iut_@J z=Nn|;*AJpv>cQmzpksLxz~6x3sHnJs)7gmASqgyH>mxtE0=N4Es_G>xD~-d4w*qkT z_%$w`y}@ALckBs9PM596Xw8OCj12hsv!DI@FHl?i7@KWgfUl`}M1Q{rm+K6w>cwg; zWKC8ormp9dm)6l-JcY=Gxug{~Q2#Z7l@ZZ_SzXuHuiKb0!$f7}UR@)rbuLGa5S+XRF%uJhZR)1Q-Fl0fqUjBz=r?oMX!ofz&ttRQt!G6223zi4ag!ep9^5DDzr zvzofPhEW0r`k>`8biVa}aw*x|H}B@q<@Y>kD92)%9guc)^{{N&0aVosKz)7Vh%GYe zjNP~WrtejVjf1>X5D`srMiH&8oy5oI1>_|qTPP~ZVf*$K*lfEA4>yvOWM;>XOkIFM zQ4~#46twfx{7gzVELauT-?6~!_2KcT#Kc4fxQ>qbn9XK?gZB1zI)+bt8nd?!U%rgw z44S4*>}BV6yA7ku{vV_N2g4wQNESluoUj03F)(jb)i4CTO@$CsfU7_v&<7j@UI6=m zC?P~EpaBWMM&Ou~@@O!xPz^Q#ol?p2(cO1C8azMtOR0#nScj~ z3^p^a0KfsH3n88Y?|@5E$~K@0SSN%CdZ58zkW!9kLF2|BJR2Yw&#Fe(00000NkvXX Hu0mjfOK+YP literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbintegerlookupstrdb.svg b/mseide-msegui/icons/components/tdbintegerlookupstrdb.svg new file mode 100644 index 0000000..4cee91a --- /dev/null +++ b/mseide-msegui/icons/components/tdbintegerlookupstrdb.svg @@ -0,0 +1,396 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + 123 + str + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbintegerlookupstrlb.png b/mseide-msegui/icons/components/tdbintegerlookupstrlb.png new file mode 100644 index 0000000000000000000000000000000000000000..18b0c8c05d7ff8f05c791e9786f7be63372f7ce1 GIT binary patch literal 903 zcmV;219<$2P)(6j2<;f0MJZt8TRw8YGHZ3oAt@O){;Xf}o<3 zA|XqbkTNjJ2p@cDj0j>a>>?2=1yNx{wY^kyBZ=C2$YWOa5U5EK-MlO&yUsd27=uH* zUIIUuhx7k`=ljk#^Pi(=nr1MKPysYen-+1yFh&hV7xyjAZ{PYzN}6M-g+jxqY8-KK zGc5H;WQ1^7$KjX>11fy6(-ofrfR*_dwY9e?De;+WU60`Po+2;r5X+YBr>g3b**kmI zPfkubD{~K0R&)XVeLMthW?vmE91IRoS=qpi8_neAy3Kl1(=&#KLbSBhF+8l3on6kh zZL4v)5;Ie&zpe#usgFA+eaxLT%WSP(zMOltwS4dE z<4jZ26b%McXiwzYnHN-?ILE{D=UL(L0MHu@($Uj{%jrb8-5e|`;?~orlQhs3XitQX zP98sz9BXXkd3`-u>FFlr>(8I8D=%kQ*8zAC2>kPkEK_8jxZ44PsyS}e4Gnzi?k1zK z(4-wNE8|FUF?+XeCD-f4rm8H-%w*pf4uGO*nxSbLM*k!DVz6!V!h~ zYdrCo211D4zyT@cMPMV~1Qq}xz&?@aga&{gSR;gZ348#qNGUsjH^2@dMAQ!&4T_X< dDhHY}{s6gR{vY+tQQrUn002ovPDHLkV1k6(f&u^l literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbintegerlookupstrlb.svg b/mseide-msegui/icons/components/tdbintegerlookupstrlb.svg new file mode 100644 index 0000000..fb5f0d7 --- /dev/null +++ b/mseide-msegui/icons/components/tdbintegerlookupstrlb.svg @@ -0,0 +1,395 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + 123 + str + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbkeystringedit.bmp b/mseide-msegui/icons/components/tdbkeystringedit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..fd7db2ae7f2a86ca71200ea34123460613e9893b GIT binary patch literal 1782 zcmb`EF=~WB7=<@Yiku*xz%&*%!A?jaY_SMp-@^`eIL8iG#!t}s;Z!E+r}a)NfI$ai{Sl0X!qlJ z-Z+jy5C{bQbct78K@670ab4GOoT4b`((=@GZCTdka$$oAjf1y$T^Gl3-}lm>=9%Xi zQJba-!*E%aAI>GNVHlz)YTFhlHBXwRd7fjjEXyp*cqj-hk7T%VWFB*l#4zMAw#EV6 zq~w@jzO3u@KZc8*0uV!JYanycQ!!A>D)bFKo*vWnfYVN8W?1F|= gzj9Q&%B1mIj_MLkuLw@TVQG1IX*&d%ye@O`4u;l_AOHXW literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbkeystringedit.png b/mseide-msegui/icons/components/tdbkeystringedit.png new file mode 100644 index 0000000000000000000000000000000000000000..b713ebc6f5e23c5170bfc2d68fd2c2a3d0a34d07 GIT binary patch literal 803 zcmV+;1Kj+HP)l7o6t2pE!{de|Hm#fwHXQOXAOuqO|KBr23Pg3@gI_0a6-cDGn<^TA_x z-^{#k=G*t)2vt>yRzg)(k~&G9nanH!Fq4^;J^&O#Fd7||zK3I%mme7jyyTzI_K-}| z4iJrwBA+ihHc_qSP_H*!nK(SWKEtx^ z1N!|jgu~sBsxdGyAkBs(C=^a{b@dfJJ#k!Le?y^gDks%ypRl}~f0V#549C+!plJt4 zCKDiaB$Ek;Om}y6w70)-1Zy;Ypi=qL9RKbjv7y`(6p_z=004}SM=&w*9!pDa0RUZH zuQ5L#b1XbRze0ES8=Re`(b4e=s;YXPN|0=6nhF3dB~SpMRfiBlpzZN#e~)sx3?YPf z9sCd2`R`c=LI~+xUth=c^z@Sn48xFSL-~DDsZ_$o#s+j%nT!u2&bl|q|cV+`1n|UyCkxaPNz9JIY~{^7zhOD^Z7V8Hz&tU( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbkeystringeditdb.bmp b/mseide-msegui/icons/components/tdbkeystringeditdb.bmp new file mode 100644 index 0000000000000000000000000000000000000000..d85b0c7a96863342d3f69a22b5870c50cfbf562a GIT binary patch literal 1782 zcmb`Fv1)`s5Qa^YB2N&Xz%&*%!A?jaToDAZ@;&S<@=jV-2b^8?2H*SJ}gIgv%$gb<2YtnHcgYh zomg1y`#wpMd7l4xm%QTrbV}3ocs!z9`zeZ|sw!+YO;eU79|d9f;k_4y?z25dY*=#G zWP<~^P4L^k*b|*VGZf^&3^PTGJ=x@rEK!cfXQ~*i%%t=XT1Ob literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbkeystringeditdb.png b/mseide-msegui/icons/components/tdbkeystringeditdb.png new file mode 100644 index 0000000000000000000000000000000000000000..9c95136f6ae38edd821b5016d113f7a6faaa3f66 GIT binary patch literal 849 zcmV-X1FrmuP)R8bf`&xX*23tc!4M4*=DA{2kdO&N(~q_zlQ zl3+q4rA;6RDu})bYUKnOh?@}%CvBxLvv?^+=m_Hv@gC}8KyWc2{z2FnNWST`n3?Om zW>U1~z{k6sd*40x9=`8>k}S(aDj~}{VUgu{^va&m0g-W~@4XqqO%;cx%|gn+JxF*~bb zaPT>1X1+q#Pd3cSv7w|S?@TvJOG`z>AOw8Ab?ogOprD`y`}^PF^R0_Tq0l6ThP-DA zsH$rC8U#EZKb+1skP4j6HiJz^N5@D{ziikn9R7vv?QhZfp9vx{m`(&1;q|@*05mjI zp|Pq{5YzcPuNr z7JdB4wY4?sx=vM98BKp01gfiVvbVQcyp}~pS2#B}z=ef3Vk4KUgDoxhNGfb=d%)r0 z7eXK&(KbMXMNLh&Fh2eTO-;8^Qj(92jV)AHcSgK4T>=0!H{V5H-+Kgud+>PtqS{Zh zN!)-`7znsnUVfd2hf~bYw+L(Eqod;ytEz6WwY5%gFB0$ta|*kDn7HQVjAu-j_^Ks1wh931>Waq(4H ztwjc2(=;)jnwkP|!9uI4=|X@1lLY?MhI1Z-LX)uB?j-QZ8jggB_ZQJIz~S&GaI!3? b{<;1QeNPv@DH!DA00000NkvXXu0mjfER=6I literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbkeystringeditdb.svg b/mseide-msegui/icons/components/tdbkeystringeditdb.svg new file mode 100644 index 0000000..2be942a --- /dev/null +++ b/mseide-msegui/icons/components/tdbkeystringeditdb.svg @@ -0,0 +1,449 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbkeystringeditlb.bmp b/mseide-msegui/icons/components/tdbkeystringeditlb.bmp new file mode 100644 index 0000000000000000000000000000000000000000..2a020553402d3c80a24f787b76ac34d1e7d031ed GIT binary patch literal 1782 zcmb`Gy=sI|5QR;XB2N&Xz%&*%!A?jaSOh_=d=EQ|yptAI%R;~x5M0n|LECgmV_{Bq z*2Co{B;w8B&$&PId1kmiJ%8L< z$6r61S{JlQ@NDC7ZNF%Sf*hD3N3__JNzTX+=_rSRp~g}7s~YJtB!}k*G?l}h+z&y` lRh5HP(6(^Ybd^a1KXTM8(aaUWAvg@p4~Dw~Ot#Bhd;&|fK>7dx literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbkeystringeditlb.png b/mseide-msegui/icons/components/tdbkeystringeditlb.png new file mode 100644 index 0000000000000000000000000000000000000000..2557e55dc6a58c3bbede5def3fe35490bfacc809 GIT binary patch literal 857 zcmV-f1E&0mP)1;04j>Y+FGmR!sqt)-!LQN z4*!OPa51-g6ScKgcs#q#7 z<4>`+_63GL1^O*WmLo*_B;mZ{kJ`7Z!vbR{6*@jM3r)YVm@ zzJ3s+qfY<;nVFB!-|sLj^!pExm)DBDy?LahG(c6=sHaj$#`T&i0OBf;1OOBwR$gpa ztr3)>C`gEsdSmFi4nA9T1EsQ3lCy3%x<*E>Eud+dj1ZFkO!~O9gI6mn z@Q#gLt9ZzgXds0k00zBYJ}fEWx8-G02(C^{Fe^QsS?TF~KRrzf!3V{~{4_U53c=6w z^SoDBND4uc+}_@%VHngjjhEM-CV{Go3J$clUn~%Ug*iEVH#Nl%Gc&T#%Ygy5)zy(g zu(Pp|FZ%kVKsYX+0h%move~e>x{4;74P^xd`0Dqgs;le5%fv(gKyytE2B)Ur4+i1( z`7qkk6VoPn0t&%hmy7p{ig>cI!MoYn(wgvi*4)g>(o#NdXpmgUmaVNVlBA|-krsuL z=ZA*aVz<-nbTT6?jki-%+1J`C=XYH$0-%_ky%N5JVHk33vM9WpTkLkU*zEv-z{*O* zk&jMJP@J0!YiX&8*L7WvmzI_Q+_2GX-Q5`K=!oF|`QTg!#~T}PR98pv(H + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdblabel.bmp b/mseide-msegui/icons/components/tdblabel.bmp new file mode 100644 index 0000000000000000000000000000000000000000..ee160864beb3061db831db862e52e1b60d6bc64a GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjf6WEKV1+>9Kg0h~G~_~H-~az)BV^CQ4S^*G z20S8gDF_3rIY23(QD`bLMUWNH+8l_J;2y;97@%TY?tz#CcR3~Iz>Okk2!8ia(Hyu@ fKn8w4nJ zFuwp{#;w&s*+4fzX729Eie}el9z5vS|M2Z?f1dPncNWcKovwE`eMjMA!^6M7$4i*y*_>OjdbP(E z{f25ea4&Pc + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + A + + + + + + + diff --git a/mseide-msegui/icons/components/tdblookupbuffer.bmp b/mseide-msegui/icons/components/tdblookupbuffer.bmp new file mode 100644 index 0000000000000000000000000000000000000000..3ee2e1db357506549443d69a7f6177b297c839cf GIT binary patch literal 1782 zcmb`HOA-Ph3`B9`!V`D|Pv8OEdu7Th@8lLk2NEX3PZL#vF`%zbo|! zQ{GQCHO_8I4=!mz#3iGFm5G?N+VE!sU-L&%?Rt^6sE4Y7{~tY4d>T4A)WfObRddJ{ H{3HGXB}i$a literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdblookupbuffer.png b/mseide-msegui/icons/components/tdblookupbuffer.png new file mode 100644 index 0000000000000000000000000000000000000000..c436aed92f7076de832e9dd1805101ab64bd4be0 GIT binary patch literal 321 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjY)RhkE)4%caKYZ?lYt_f1s;*b z3=CX{L734*Q)M+!kiEpy*OmPNHxIu7^Qu<)|3IO0o-U3d9>@1i^X6+d;BlERD88CM zug@%Y%9JG`0+%m1>a_XKd3aQbVZm1osTaHsg165a+wPiwzxN9&X`HM7?&`uMf9 zB~8zx%Q-&#P~7~NA@6*fimuhki=I|3V0YDWlyA=ZHp6_Py`;&}T@pK-kA%52`pwwF z$&>v5T)At>+C}9DMVdRjS7&6%zv243n7@c;)7%*24OyC6NeN9;58hm0Z@feQ;3GTKCNbI$YJbKW-wUIo2HpCNCbWhIW~5a z;^L*2Tr_H6vt^N$^^heWkIyhYd7DQr1|aAIApFvA0Cx>$qpj^2e*XY||9${su{d6D z8==tO7)FemnhFja*b2ar50CQIr^lF?x`n6I#>WTivAJqtgt-P26A||8`I7GLKHTn= zseD)0&qN|og27KPj2JFgBd^u0#Xfq5L;HIe+*?TQx-C>R_7fN{<&~VgRIg>$^XG?H zw#-g@`)c|U9WTNb_7k+EWMTqJRT<= zj}yOtz*4ko)pD4gg0o$m?);Vuga6RkQV%cGVb96K=lhkNJCCqoLmAc8ZcDHAw9+9d zOota=$59%-iF5qqL5enRf#fPGE6X``s)egpZ*utX@dX;p#8biqeRPhMv-@N|r+eF2 zyS^NN8#g8y8XCoJFF>S}rlwcv>FJ-xV0sEJ_Q91u5?5|bEk8JRvG424{L+62r*nC# zbaeDORaNg`7%>0>fq^+IvRQ;fClaEU4OmhP4Ie>H9(yaBxpe6YB_$21@|KpjXl|}! z`}UV{yLXYDZKJHr!Hyl(76VP!byL@M%+HGwnKiZW?55Oy7lK$UPBdzepP!q`g~QL_ za5xeZ3=a^gZv#&O3OEZa5s|?MF$e(9i%4NIt^v*g?*S`;3ZM#@ zOnzsCrj$xch)5&Q1Vn&gV6#%{&MdwV2rH$QrWKga;QzwEn;9^J406W<00000NkvXX Hu0mjfi|MsF literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdblookupinteger64lb.png b/mseide-msegui/icons/components/tdblookupinteger64lb.png new file mode 100644 index 0000000000000000000000000000000000000000..4c9b9d723ccc95f71f976606eb8bb959ccb22f30 GIT binary patch literal 952 zcmV;p14sOcP)4kf;ku1+R(0G%1Br zp3A7?^v{z32RQ=JIQXVOY!}bO6IJW<}hxtc*b>xac77-yf!+ zV1Xl-NTks99CC8zIP&TAILV}m&o>uFbhzs!mRkgXvoed8mb2{K8L?y2OcM%yOij)E ztXQ#|=H^p2ckEaPRaIeDS2xjE{~6{_xe)i*ygpGl9v@@x-d0YZ?xwmrXy@D8uP`>2 zAR0YEDrHhx8D`U_R|o|1`Q)QB^nLR+-eev%yLQpp)5Du}b#|{~f?K!xDJ%@o*0#qn zQDx;)B9R6FJRY6Ji=XG_^%!M|WkgSXi8q-?dVHLRqoZh==IC`8)YevD7(4KK=Q@hY z%Zn*4E&$+CM=!V4Z>$f#0dWrjzn_loZi?2eV|iH_Yin!W4W`71PREHTp@s1e0B61dk%fdrQ^q0RbCFjgLs_&d-n+V{YWrK zQ++*Wy1J%mU}|tDANu@!|AXQ{TN_tTo}{9*)GqmBXoxl8Fe%dnptGmvnNQ@{BKyRH zJ{Z;Qb=%+C%CCcilx^H-mmO?uy3X0|NuZ9ss%7XNLG|lALB)*6dz(y}iAf8z~|h zkgt@AyYMe4r6xPL4c9FakuAW_z-19RFCx!9#jgc^nM&N%KtvV-5#V*DR29$=6@H5U9M}hZF;jyVfg&IZ42j4iV6#$cNJQQtGf|gI zuLExXAP=YjUQ$ZE4BQ5`iO5o*0cf6%_*4eJ1DBOjschU0yawzBN&yAj0Q@4-Hxq+S zpiV^QXXCelAAt{nAW#FW0shIpyFyb+O-hJJ7-#~k}kyZ2To!r=bcqs{_-BZ0d*|ChdGV!x zCV2A;&*As|eV^a=`91ueM-oD)>?33VA;i8ES5m9AIc@9GAUfF zEP33&JIwU+Cm2(?)U>uT5{Yo3wpQD#>tJ$n2CLOVFxa8%$mu+W-`@s+!5~vuc$AMH z;@FbMi4H!(n93!yxykDKI+7&m_Ua7W?s9~oWrglg=sykC zWSGk1arb*VZa-kOx0jO+2LQ{71TzZ@Sj=Wl*zL48H8DIkwo3y=f~h>1HuL(;1UG|0 z-u3rWURtV2zAY_r*5@OwC;*H^BEMXbZi=)M&zWFd*2e9|zyM$7=CCz1XtG;gFV~x! zxm;h5%j3Zy%T$z=ab<@FKoUZzLI~8=S1@nX&G2raWHKaEDRNCFjf-2Yl$4Zgbuc?S zOMDr~*EE)wWB2diz~I2(z+lh#37oCOvYQ*BPyhe`07*qo IM6N<$f?pd(6951J literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdblookupintegerstrlb.png b/mseide-msegui/icons/components/tdblookupintegerstrlb.png new file mode 100644 index 0000000000000000000000000000000000000000..18b0c8c05d7ff8f05c791e9786f7be63372f7ce1 GIT binary patch literal 903 zcmV;219<$2P)(6j2<;f0MJZt8TRw8YGHZ3oAt@O){;Xf}o<3 zA|XqbkTNjJ2p@cDj0j>a>>?2=1yNx{wY^kyBZ=C2$YWOa5U5EK-MlO&yUsd27=uH* zUIIUuhx7k`=ljk#^Pi(=nr1MKPysYen-+1yFh&hV7xyjAZ{PYzN}6M-g+jxqY8-KK zGc5H;WQ1^7$KjX>11fy6(-ofrfR*_dwY9e?De;+WU60`Po+2;r5X+YBr>g3b**kmI zPfkubD{~K0R&)XVeLMthW?vmE91IRoS=qpi8_neAy3Kl1(=&#KLbSBhF+8l3on6kh zZL4v)5;Ie&zpe#usgFA+eaxLT%WSP(zMOltwS4dE z<4jZ26b%McXiwzYnHN-?ILE{D=UL(L0MHu@($Uj{%jrb8-5e|`;?~orlQhs3XitQX zP98sz9BXXkd3`-u>FFlr>(8I8D=%kQ*8zAC2>kPkEK_8jxZ44PsyS}e4Gnzi?k1zK z(4-wNE8|FUF?+XeCD-f4rm8H-%w*pf4uGO*nxSbLM*k!DVz6!V!h~ zYdrCo211D4zyT@cMPMV~1Qq}xz&?@aga&{gSR;gZ348#qNGUsjH^2@dMAQ!&4T_X< dDhHY}{s6gR{vY+tQQrUn002ovPDHLkV1k6(f&u^l literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdblookupstring64lb.png b/mseide-msegui/icons/components/tdblookupstring64lb.png new file mode 100644 index 0000000000000000000000000000000000000000..13e1264d838e156403e2219f4d3cd2a26f1df031 GIT binary patch literal 921 zcmV;K17`e*P)*TUHk-O$K6FdGx$$ zp0|r*{(p~Q`Mr9d_xt1f;dy?44AV4iR!~U*rfIH7xNX~UK)kr-xNu~|!nSSF(o&aB zeU$|LDfD^$05gC@I)DCmqS0|o^ZO-(8BUJZUfvy$Q1gT5$u+yUckc!;@R|$t7Gc**L_R4k^kZrAn;bh7Ri}>sIZ9ez=Da^}beJ}{XwXydb`*+REc)-J_lNr-<_PE`|VliHgjIb(o=41_zjxuUlivz~SCTML9bLmn& z2M&D2(?`z%c>RwT#$4R!>f&W2!l-3&wY{Bf8#l5gHB|#rMGD zNv6Jj58I26lHpA!+vmrhnaO_x0{~?CeC$4UjKLQ#s1AiF&Cds*p{k1QwY7ZYa`8nl z$hRdWa{z{Enzm`0*e`EDe+tpT7=~ex;&v~XXDk-u_2eY(3@Ab zAAvw1-a&6~FMUJAFUMyKa^FjaZQCpR*mZYz8&0N(7(kk;4m{iuhB2q)VqraC52j@Ll1#AFvRW%>D4^)cCT3{b={9VEm z0saTtRCQviZU;($gFrT*Ko{__i1aK6a2+TVk@TrL1cZSGU>&d(*a1YQz8z(#>Y|2- v)B!&NQJ@#7P*rP|pAPh?>L<$rd?>vEMhy`2RiV@g00000NkvXXu0mjflLMmO literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbmemoblookupbuffer.bmp b/mseide-msegui/icons/components/tdbmemoblookupbuffer.bmp new file mode 100644 index 0000000000000000000000000000000000000000..e09d4de3d94d1ed60f045e180f2d460b5966f2af GIT binary patch literal 1782 zcmb`GF-rq67>3WqL2&6HP8A11N|!E9PA*Oz`UB*^r9VI%ONai8LYGbsB96Kog8!mh zr&8!_yTv!(mrK4}a_M0$NqDcxJ$duyySx6+aYnxzjMwPrrXP{YvMM$`T@_{ji zlq2u&^1-tuC-SjX)W{EQVlxSah9JFIKGuwxt;xq@9+rtkqH=q2^fH$ojh4C`_R)mAOGAxkznE2Ty(bXE0&+66uv)R=aB6N zf5pBm`;=7(6V9IlcTR*$A^mfu4l|v^7^fzCm;dBo#xbQ`3zbWp6-^-o4TT`+_i}iV ztqOwhCudul5Vj$I3`bL_D>kqS@zL++D+jmiVvfVH$t6t)d?!cz133CQEUFMfR?`oX zl?I_u!k#*FF&|!n7a3XzbQ>qL7e0YLN2PhOxt|h;Se^QFv3jL<=Bgwxt;A91^}DNbYjw z%4O(xIo{8E_j#7@b3&G7lQxbYK$hjUl$)km1Jn+APs??^7XY89tu|u;1OgMpFFFxOOH{MS8Q#~Gc}cU1o-X3{{H)1 zTzu#9@+Zf~8iRum>UX7*PCC6)KUXRShVhGz4%;ew0Knv=L^8R`*x18{yr<_bYirNw z>kCpY|6qGN-?H2h5Q{}wSlA((O*G`2n{y + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbmemolookupbuffer.bmp b/mseide-msegui/icons/components/tdbmemolookupbuffer.bmp new file mode 100644 index 0000000000000000000000000000000000000000..e09d4de3d94d1ed60f045e180f2d460b5966f2af GIT binary patch literal 1782 zcmb`GF-rq67>3WqL2&6HP8A11N|!E9PA*Oz`UB*^r9VI%ONai8LYGbsB96Kog8!mh zr&8!_yTv!(mrK4}a_M0$NqDcxJ$duyySx6+aYnxzjMwPrrXP{YvMM$`T@_{ji zlq2u&^1-tuC-SjX)W{EQVlxSah9JFIKGuwxt;xq@9+rBvf=`V`EEui3QPw znBZR+3pv>JfZHRG_%2hty}Qi3doz0r0J^+l9FQ9T6PeB|mPfEpPQ(!HqWKt03fm1!kdXoQo;3W(4z*-Pl zCs9FDJn9dY*10HK6q=*=A-Y2>w$4vQAL81 zMA0Wv^g+3N&V2sObo#zQ!E)DAkyV7E*Q?U+KLIctj_G#q5+3AS1#yI;(YR(Zd1E&F zVl;ZCUccHt2U#kQQ7oR)YE`II?y1!-DHKk&??nj@VxE$?)463Zc&6RH**ymd1%Zl6 zr85?b@s@se=3t*L3To$L|1xtN89DDXaA+vXv5qS-{{fbC)jl^!Tu1-_002ovPDHLk FV1l=Fx-|d* literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbnavigator.bmp b/mseide-msegui/icons/components/tdbnavigator.bmp new file mode 100644 index 0000000000000000000000000000000000000000..882e6125a78be09335b5381b52afd878f1d88b84 GIT binary patch literal 1782 zcmeHFu?>JQ3@Zx@8xtpR0SB=26Q^+%YjEqzs=`Jq7Kmu%IEfY7tlQa#WDER^Gv(7I z6vBc0IPj!GI1BcFZ`^>{-ogx4{bU%Vp^mml023158Kug<;5=$k7XYyU+eK1@A+U5< zuQG<}b-W8p9kl?ISb~mJ8G+_;JiFvwmh+ILZ~I=Q@-v+0i91wfQKx#De}ymKzy+OX BDfR#W literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbprogressbar.bmp b/mseide-msegui/icons/components/tdbprogressbar.bmp new file mode 100644 index 0000000000000000000000000000000000000000..b8d48829ed83a4d44fe939813c11c04cfc266c38 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjf6WEKV1+>9Kg0h~H1tB?KLr3O#v2+M4v+;v z)}xvOPD{Y#gdOes{~r?pZ5}lT5@MKv0~8r5;R7p6NT4y}9hel!1IX!cls(cy005oQ BNqqnS literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbprogressbar.png b/mseide-msegui/icons/components/tdbprogressbar.png new file mode 100644 index 0000000000000000000000000000000000000000..1a8c59de1852ca87032c40fec96b2b50d4b48893 GIT binary patch literal 270 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ zFuwp{#;w&s*+4mG_!gSt3V7Gpk3}g@atn9GdhNwCD@eq(|#FVC` z^;i5(XW6;H?Q0khM0q!MpU}I}{V%YBgO_1WQ(@L-hh=h;{yH1zN7l@+x@*sxJ@0|m zQQ;cT1NR(L`~`M@u@&ds^PQvdP`l74@5>A#!5{v$f37>o*0xD=u1AFc2hdpzp00i_ I>zopr0C|92RR910 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbprogressbar.svg b/mseide-msegui/icons/components/tdbprogressbar.svg new file mode 100644 index 0000000..ee8095b --- /dev/null +++ b/mseide-msegui/icons/components/tdbprogressbar.svg @@ -0,0 +1,228 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbrealdisp.bmp b/mseide-msegui/icons/components/tdbrealdisp.bmp new file mode 100644 index 0000000000000000000000000000000000000000..f728f556c81044e1c650d9eb45727c812391d5df GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDj7vhFsutFg5pW*)~qF)I7rvMsyRRdu^L5&IarM%&m2snFwKED8>{2t zp+t;15H(oMK^8=21GQkf2VyCjGKe7D3QSpC=D;-)$-p!Rm^H`)$oXQFJyb#f04agm AY5)KL literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbrealdisp.png b/mseide-msegui/icons/components/tdbrealdisp.png new file mode 100644 index 0000000000000000000000000000000000000000..9affd09c6d2f1c4d880573769ec0b21886ce4bd0 GIT binary patch literal 526 zcmV+p0`dKcP)2w-B)un6tKcF2MBaw*E6#%faW7R2sO8tuR`6A`=Tg%pBv83tca!O_AIgz+!V#1Bhw!!%L8nM_-lOK;~7#?0$2V7sLuv*uUWd$vHJYn4K8Is8(0)Zvg z*Mk7m>jIze9GA;awOUgLM59SgPu&a-4rl^4H)oih9s|H)=_8wcpj4`$C@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + 1.21 + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbrealdisplb.bmp b/mseide-msegui/icons/components/tdbrealdisplb.bmp new file mode 100644 index 0000000000000000000000000000000000000000..b0d1b23b79f7865e8854608e74177c2fbccea5ea GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKg9Kg0h~M86RDPXR!RsfLDzef$2C zfk4)yne(4|<^auRU_f>igbPb+P#ReQcK1Nc0XhuBZD{7hjUsFgaYhkk4u-=pT}6U9 zsHUMAg=r2*0dn|2w4;&x&?5rV9Ec$h(?H>jgpdUZx(A{WSqqv`Kq-VQEYV_h53)w0 X*g!=${2qZe!Inr(pZ&2auw=@F@_ zhOQeGJv43i_@ZuuO*`AKO;BZ^#2%zlzi>G25Q%J*G+tl-N^h@^o*pkc z2a}UG%Nif*iqi?7o3S(-{+S1O+-{nLph*ZG4G)t@r^^E>>hNT!GG;Ev_51hOPN#V> zF;OwCIzYEU{1hYw0DFePwUH4NStc|+jZl=o1eoM2{wYYLGBgT<7Q3C>f)}@Ect + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + 1.21 + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbrealedit.bmp b/mseide-msegui/icons/components/tdbrealedit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..e066c5fba63f9fc5d909a35a4ebfbfa92457560c GIT binary patch literal 1782 zcmeH`OAde_3`B9`#+@sV;0Zi{d+)@_jHhy2N5(W5{MN+8#0fMb!Yfv2yD@h`4PuR6 zEjDF+jvc>nbAAhCw}q!6Nx>#UnOHG7=-lWrA literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbrealedit.png b/mseide-msegui/icons/components/tdbrealedit.png new file mode 100644 index 0000000000000000000000000000000000000000..ee66fc2e6eb38820a0db839d7583a57e30236b58 GIT binary patch literal 471 zcmV;|0Vw{7P)LmY|%X#{Po?aS&Ibp#wojm*5Uugg^&}5aTt7*;OYe+zmp%>fnLK1Lc=Qwp z$mdUq#Z=<)J!Z4_jeCK04*(P;f}+GWCSoU<2>-S&D zQ*3pEgh*rCHW2V%v?}C#fhvG)+c-{;sI>_h@<>ww5hh^w2hQ#TJ^^})Z3j9k?RWqH N002ovPDHLkV1kEfz*ztQ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbrealedit.svg b/mseide-msegui/icons/components/tdbrealedit.svg new file mode 100644 index 0000000..142295d --- /dev/null +++ b/mseide-msegui/icons/components/tdbrealedit.svg @@ -0,0 +1,244 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbreallookup64db.png b/mseide-msegui/icons/components/tdbreallookup64db.png new file mode 100644 index 0000000000000000000000000000000000000000..bed69a5d5135aac1b17f246c4c7d281ea404e35a GIT binary patch literal 865 zcmV-n1D^beP)aNqpuD|W9 zVfkLoH}9PHIp24f8Iz`II&-KH08P{8BwW{ZAHcV;jT>(FH)3O#8WwuJqj)@C!on6z z+#DVN$5RGhKf&XLz6?9S1Yk_X#g*7>&Dd<00*0SGTS84u3%ah8n!295H%}1q?m5`2 z@Qy;pqlFwewvWC3=jV+T_V*8xmv@VzqH@E|8ynkcXn0F&>m3|TH*j^lqw>^ouvgI$ zmCp8u%V_@a142T_YsLX>ZC%90MNwLM$`BAAA4A!LeCD@4#`G|kgb+7xJgXtQgcq*m zoIZ1i%*-8AYQ~Q!EzLq&ngyG!IdJ;$0A_bB*sB0=L~f_D^Ck5U3L!Lt!omyyYHJ;V z0fzDqZ!DP28N3==$H61lDJeZoVq$#Ia$`V%U^ZE)Yy3o3)-}q@&yk*l)S7m$6t9W(A*E9|NUi6fsAT;8yIy6#u_j=4`v+szU zPAA=yUDrQlPmxL2^|}4nIUEj?ktrf3AW|vSZ{Wu$rM?CO%ri1XbJiO3TFdOy$tTmaSrTY%lbPye-{OiHPMhKLjZCxJo0 r2^>~R{hH)20lJk^#y{_1fd8f65A*_7PPq_k00000NkvXXu0mjfAD( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + 1.21 + 64 + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbreallookup64lb.png b/mseide-msegui/icons/components/tdbreallookup64lb.png new file mode 100644 index 0000000000000000000000000000000000000000..593be837372371829ab771067f9182b42b15b9cb GIT binary patch literal 824 zcmV-81IPS{P)^e0Oa~!dOb{OvLK#Cufe>U6 zp{3|57orsvx=6?yE(+X;5n(7Ofr~b-0?j~EkR+YXq&7wiN5Ui-wVX=9nQn`jCjahC zn7(k~e!S; zPtT|!z-mo{Wiz6)gYe|x!M zDgIY8>FHRl*5DF(JRWA2fP~Pqi!$lDzPCR+m&;``GDXA$Br2tR27ZcC${Pu=b(8-# z7Xu%F0TFpFB5|AibHK+);f4SaIS4cXXOvRMfN9|JIzJV702t2xkBq*9^S}#WQABc; zQZ<|WC%|2xW2b;D;1KW@SP+p_;F3~mK}0GE&Zs|HI2iB2KEMVXQA(WvCV)~AISgC{ z?)*!5B)}Xnpp;q*)q}ukpbE$V6z~Q}5|OE$0D6IwB9a`ci-0kp9>@cZ180Hnp?5=> zlv3LoB2oj~09F7GP^^?%UFRnQGfFAr%R3TaxAYsL-tXGvPf9cZ0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + 1.21 + 64 + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbreallookupdb.png b/mseide-msegui/icons/components/tdbreallookupdb.png new file mode 100644 index 0000000000000000000000000000000000000000..4dfdead6b9a9e1847c0c34ef1b1fb94e7dc0ff26 GIT binary patch literal 651 zcmV;60(AX}P)Oen8HRNj1DG2eA^CI1EFTh*V-l#qy#gBq7oc4-PghCCi%@^ zc=LaI-{<}Re-F@!Hmf(jg0k93I$ma_oNiihpcHQvNQ9pBY?@<&5o2`e(_phN{ehG;%rA=@> zJ-~%4=Q+3azO7=+<<=P*dcfFNP_^@DbcKb5kHq7TkQeWfSzRVHd=(O5Ry!Q@Pah@r z={IO~RZkVLwDg6}&JF^BVO4<1bcCr%5BuWJ&`jUJtj+SF*ad@r<}=3_xp|3!fwMK9 z>WJ)iD|WjTNs84^FXXXgBajFKARp`}lzh#bNiXOOc)czFA`!VhKvi4Is|0h(#oLYJ zT)cc2e_({}Zqu%IbwHh9PC9uN{fyf^K`?j=hoiS)fByoC8}REJOkD@yPp^}V@eJlJ zGs)yv-0lfxXYXLOnj410jwMsb!{Q9g`yiJscRc84#bD#a>GI;o$7fhu`%Yh<2ff~j zUhl-?dAKV;BZN?d5GYR$*Ng(4;lDamQ###)#bPOsD3wZ)-dWA;DZ54*MNyjj*~zl3 lX(php@sk#y1!w{Gs=t&nxNm^A%E15t002ovPDHLkV1jLFAEW>P literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbreallookupdb.svg b/mseide-msegui/icons/components/tdbreallookupdb.svg new file mode 100644 index 0000000..f45757c --- /dev/null +++ b/mseide-msegui/icons/components/tdbreallookupdb.svg @@ -0,0 +1,385 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + 1.21 + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbreallookuplb.png b/mseide-msegui/icons/components/tdbreallookuplb.png new file mode 100644 index 0000000000000000000000000000000000000000..25ca30dd870b452e9012f62a886c9e974e805398 GIT binary patch literal 613 zcmV-r0-F7aP)#5{Tf$w}Z2%gVqE|RP{6;u@)z|1azp-tH?r!;9 z?c|Gt{YmEN#w`H4{(g|l6-cFKe8VRv7g5zTLqiW4AJ1XiPNPr{;%xVD@9r~RzAAa| zJ%DAMFflPlHk`9R$bSIi3P$lOiDa4$!)Wq&fUT_xk;pZc zmLB^8qS5OtFFz#^=t8n&2704>e18CzOsQPvNixZU;o&BaH-mUQMm!#)SlsXhC`uUW zK`=t-nn|Iw%Id-b0FOpS0C>B(c`=}+>OnXNfhAMk+2Q`w6pPc--0biFr>!;MOfbMZ zO=B#RA)n21M^#(e{Q;-Jzm6rUwHgC`ee9VgW0?%EXJ?5G4z>)33)YmM0r(Mwy + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + 1.21 + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbreallookupstrdb.png b/mseide-msegui/icons/components/tdbreallookupstrdb.png new file mode 100644 index 0000000000000000000000000000000000000000..a8e9e7cf15a078f6ba436569eec5109b237243e2 GIT binary patch literal 823 zcmV-71IYY|P)y3hIN8hfAuGnYxp@i;A5d1-tlN1{&j{V!pKv;>arIR)GdfIb@dX%YV>Bv@%*H+R zfBpr=&{fYWU}$K9*w`rQ>x*>(@$u0#)Y{qRe1f6zG6_aEgWe=4sH1Zxj*@G+A_$G3sK^RHSC>m0psVHOtpsz} z%7=yhoIZPpy8055ljAqF>jN}`Ih4ceo^fop3Ywd*la-Yku)n_n-Uayi4H_;1@H;h! znV1X`k`fpj`-;t0L3{gc%;toE;jnJWEP9}?1v;x>&h78GppKDk2p2+( z11gXNIKaK$Dbm0&oIngb + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + 1.21 + str + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbreallookupstrlb.png b/mseide-msegui/icons/components/tdbreallookupstrlb.png new file mode 100644 index 0000000000000000000000000000000000000000..45a12b5630a52b66911901681ded1461530a7c96 GIT binary patch literal 787 zcmV+u1MK{XP)NW>sRZ@k!%U36iE7!rblA{ayCG!JCx3%@-bT(66-9lqyH}QBPS=cd=SSaF3Z70J| z$5Q<%KrFULQ_~~-{t?6Q$;l-qCKk}NUV_2Ltgmk|Ix+>JV}t@ZwFV}ex+#LP@DE^@8Co&Jsv&XkuQ zY0C`wBN*VVrqST@G2-`g$?42!HwNqn|J+tsk4C8|EoC_pp~2_lWls-|%F2x4kmj1Q zn-AYjuxy2xnWb=;^Y!%r+#4EVEgHq?^;DetGtGMb!V0_qZW;6iq?8e(aKj0tlp5dwUISiWP6$z$rgiJ6a6^C)q5)`; zQuYCt0V_}n`~WPOLNfw@=YU%X@g7(LhNYBYKm%?FA<`abIw?}hY!;NYegi|`-*4^X R8qNR!002ovPDHLkV1g@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + 1.21 + str + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbrealspinedit.bmp b/mseide-msegui/icons/components/tdbrealspinedit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..07b4592003562dde069ccc5282a7f902af2ee114 GIT binary patch literal 1782 zcmeH`F%E+;3`Nt0g|Q1q-~>GYd+(H!Ax_oR{N^Le1(C)eAtA*|tRLb$TfrILpC%-G z!S|TmG9O8WFk%1Ma;88y2~x*(Hy|g>{HYk@bjZHxe>v!ZQN%TnIm01PJp|3Bz!xk_ zI6TF8OMqUu=<9-d^y~_y5C|8C1t``EFUO(^>tUEC#gbYDnGAE)vm#q;o}@P)@$8oJ4!n@gbJA_O`(gc#Rgg?e`-(hWjyd%ySiety6Ac)u5N z9ETt+9H{y~U>y_HYBkU<3xGR*mf69%P|~-73Rwae#sN~^`-%f( zv&TfEf>>;a$>hybbkP@!0YwR;DA6AQ>GTo9;Rw^brdT`$KuYPGFMK0D)^5L$$=pyb zpJAGZzviz6n9bf1LII#udZ5|7LRI&^<6h0}^?JaXlN^bh05BR&u%AYb{UT?&r3)t(RJMg`_sS3tJwnP_3HOG7ycYtPYXE#uQUOKf&^^; c!r6Yn2XrfKe$nNHL;wH)07*qoM6N<$f_m@H3;+NC literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbrealspinedit.svg b/mseide-msegui/icons/components/tdbrealspinedit.svg new file mode 100644 index 0000000..ccd39bd --- /dev/null +++ b/mseide-msegui/icons/components/tdbrealspinedit.svg @@ -0,0 +1,246 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbslider.bmp b/mseide-msegui/icons/components/tdbslider.bmp new file mode 100644 index 0000000000000000000000000000000000000000..78b76deb70b1f1db392473008dafd69e26e07e2d GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDj7v_dwutFg5pW*)~8hRn{p8|js;|&cB2gm{- z>ru@Crlo!V|6?McLZB@WfTjj$GfCz^TnaR5)EungOs((%MG839hzw_-GExD^0@U;a QOCu!H$mWc)M_LE~0OT)}g8%>k literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbslider.png b/mseide-msegui/icons/components/tdbslider.png new file mode 100644 index 0000000000000000000000000000000000000000..6a690ace0919d1a9602fa9f4aca93a201e690288 GIT binary patch literal 540 zcmV+%0^|LOP)#p5dqh$jNfzIy@;9Ud%cs4K^nrAOG_-t3zu!-QopVaaBYYx<)_vWj^>x(i^(0A|Lymww-~pHiPJuPx1(*YF02q(QIfrMU2|NMo zhSN+@GX(p#xM)q=z&)^H;5z_}Mx)e|TVNA7v2_oATtpBVi3dG01!urA(EXtxuiW={ zfhEE)EK+b}J2?b)ZA@Fhttl%aShKoq+sr<2K^(_L3U&=VTkK^&{uohW_onb1SOBhp z#w-P1rr&u)o}@^@jw#$T@KxYymVzwF;Z%$Oh~qf*#Ju8c{|1#x0v+ZRbZw>)(BS)5 zJp~#>QN(02A#Y71@i8I!{9FJaaL%b-uczhJYPA4l_V*wNkd(%()oL{YmHecIKu{*Z e-+yraKEW4|u{jTxqyGv30000gVU literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbslider.svg b/mseide-msegui/icons/components/tdbslider.svg new file mode 100644 index 0000000..a2b29ac --- /dev/null +++ b/mseide-msegui/icons/components/tdbslider.svg @@ -0,0 +1,813 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbstingdisp.png b/mseide-msegui/icons/components/tdbstingdisp.png new file mode 100644 index 0000000000000000000000000000000000000000..e40048a93b4969c06e25fb8026e84f9d840df2c1 GIT binary patch literal 630 zcmV-+0*U>JP)jK~y-6wUa?eQ*j)}Kkqr+!|mWY30|Z{!6TN)z-$bL#NMTY z2Qe^ELXjkc@M1b;?_kiacd&vEnO%00CwTK99eS~g(+zsWO2W{C7>+E*X0Cq+>yd2( zsrEhn`SbgKKfm9P|5ws=T~I^00OIk>HL}-`PgAzDllyDLsQ|651GNSGiyVLug6Zjb zRCSn^mK$hVjNRSOPN89#sOm7G&=}e5HUI|)1^W6P;P>A|(_*ZzZ&U}YuD-*vY|`n+ zY;L|lQR+z~UOI()dtb<8p3vQWg`uH`0E~`4!sqj1+fSL8xX$?avoe6|*C7}@Pa<&- z(|pa^+6LL|Htp@_0FWdY8M%hbRmb3(ozxt+x|#2I*AY`bL*_AzyB(|z4wVm zCn*#T2?Wlvwe<-Ak4GVye2Zb2G&i4NZf*>K+1cAnP0iEUc^4tTFm549(g}d1>$>4>?cu^tA)y#p4=0FwmV@cxArTu690PUTn!p69t Q3;+NC07*qoM6N<$f&+OSkN^Mx literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbstingdisplb.png b/mseide-msegui/icons/components/tdbstingdisplb.png new file mode 100644 index 0000000000000000000000000000000000000000..aa0553e171c7e40b7f1a4408f84c6727decceeb4 GIT binary patch literal 687 zcmV;g0#N;lP){^ijF_lmbwl zL1SazzX>@h-?3(fxLWk3RM%Ps2noKa@YR?%DT6`+Ap~CUORUyG8X9iX)%A#-om7G7 z_lK}r2eI2d#9~_zS4qFG;g;(OC!E*m8XDq5ELPcIY3UQ;aFmsmXKZdxV=&YZ2+S3T ziNqe7_MB^1E;4X)0@h939e;|&Y$h5E^1$Wd-sEIu1Dow6fxvx2p?7$_)5Kz1B$Imp zND|y}T}4@|qrd$I3)(6N*(`4t7a4Fm(W@$#T3dNDF;Uqd9A3p{bE9b+bab4;Znq)? za3CW~GId+WAf=$_bjY%d0Cv-9Oh#itY&(&tY%nvkOm}w&V`F`EcAjB*X^mV$2F=Wm z+)qMt`Ek9Po#kv(69!e~TuTeD=jQ>4ZfxLiyAh)JZVOw~+k2Uwo^c$Ghh%nhoIc*n zm-X);Buqvl3y}!^V34Er^}HAv0bp`?n8#C7wD8+kQMlx|O7de4 zi~dMSRDeu2i$PUO-uE*ZY7K_cg0{Bb2~tY_Q1*3L^kuaH%8CQ!#s4G_e-G`D@e3fS Vz2TGl#)kj^002ovPDHLkV1i0VFG&CZ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbstringdisp.bmp b/mseide-msegui/icons/components/tdbstringdisp.bmp new file mode 100644 index 0000000000000000000000000000000000000000..58fe00bce0f6d99628f033f0730170ce0cf07d44 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDj7vhFsutFg5pW*)~qF)I7rvMfwf96#)ujH3y;? z;uwetl;v2}P0&!i(vY?O@QY?_dQTGP~>~-@uy(>Cj>q=e|KBRuYCD#BgLeHg&xntdDFP z4QmIX|LNuBdH=und3gW4QZkvOmXd4g{vS|{EYWCG)D!>^3SF*|y;|Lfwzje-MpOl8 zZ5^mB;BRCCgb++m&*O3p)6#MSRSmMe{n;$kG#!^~7_WDXOlA{+y}dkreGhOtZ=$L} zlF7BofR&YZ#A0a-<1y>&FHn?vB9WJ7;m*z%QmH3&cVA&>=pg{3qmOVn?4;9AnV7iF z`1rFDfaT}H<2g?xat~d9&FbnJnan2b?dJfHBp4aFhQ(6H;Gjw{_?$xFfaPU_Xf%Y? zT94oF#_xAm?jRO>gU54+RO$mh-$lG$7ve`kWLc)E$$oSrOC7Q-A%tLeH;2upm}cc( zn+aH2O3>5eV`gT6uC7ZY67M-YECNt0enZz|04yxLqOHw|qBPLaae>9fH~{JNM*@LK zggBmCb4309SLyA&ParT!KEIFKeU^=lPXO3#3i0?`G) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + abc + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbstringdisplb.bmp b/mseide-msegui/icons/components/tdbstringdisplb.bmp new file mode 100644 index 0000000000000000000000000000000000000000..34eb2dd12ea34b383531631f50b32ee4c5b60cf6 GIT binary patch literal 1782 zcmeH`!41MN3`N6*0~0U;6EFaGcFJTG`*7##e*4F6Xj6m&LPDyQxNZ`^{5Z6AJ}anoFv)W?8jA!BQ;bXALVJ^}OAr5F)ptD{#axl{5 x)OyxvM1cT9yvAXAcwKDrChz5y8e-ltRs=;zqQw z5igE-SB7O1ESMpo07c$GRaNJ|3o=r+W6cavb1Mnx-lz~2RR2q2%OH> zSS&qMR^Fwh0DtfwvDE}abhoymS5>am)$wj*q_BYB zzlhb^i>9s6*mwq;&4LiXu8b_nl&zhBgo2{eA+*LH5+5B-}+7}MXABC|3H2HZwCn_8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + abc + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbstringedit.bmp b/mseide-msegui/icons/components/tdbstringedit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..89202537501e81ebcc1eec6bbf8aa1882302cd8b GIT binary patch literal 1782 zcmeH`Jr08~3`WD!g{>1u=m~m&?!8k^R&lDX?js+v0u@mcB&14MiS>oV&(05z=lc?p z-SId2F!wI05Ju*&y?R=RvtVaC?gVUyWj7UL9Gh%PzvS=+US?H|%v+qCCXJVQ3WjKW zEk|dkaM93wEOS`nro3&O@A`%H?+!25VG+b4@{z44*&oF literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbstringedit.png b/mseide-msegui/icons/components/tdbstringedit.png new file mode 100644 index 0000000000000000000000000000000000000000..20469d883c9f2ed41bf04ee906ca5c46f4c023ea GIT binary patch literal 589 zcmV-T0-_iF9LGJLK~=eSL2q2LyvJiO0X;^R-ecT@Z~L0O-1gY4!pTjT#&sl~5Fg zNTeHp!9nxCV{`0aZ0swU%qLb?r|Il`bsw)(ZrI;10I<7zKu^zW!r=h#pHv`q09k4s6?|SZpNfuY~mYrD=fh643k) br}+W5kFt=(@0Gl#00000NkvXXu0mjfe)9PZ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbstringedit.svg b/mseide-msegui/icons/components/tdbstringedit.svg new file mode 100644 index 0000000..11dc1ca --- /dev/null +++ b/mseide-msegui/icons/components/tdbstringedit.svg @@ -0,0 +1,244 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbstringgrid.bmp b/mseide-msegui/icons/components/tdbstringgrid.bmp new file mode 100644 index 0000000000000000000000000000000000000000..6128b7618dc22f480c6df32124c50f9fbf8a1a5a GIT binary patch literal 1782 zcmeH{F%rTc6hyJHv9t0Bp1=dxdnZrka4K7T$&#HvL{XE*LMHqy%V$|WnVc{8Z5rE& zc%&a{-;5}w%=~_*J|+@MD*xwg1+FVv6i23%LcH-Bik}3CIcG8EA@u~lUY2#FAQ55d z#I+Uy3=4-FulF8xrZ1wp`b?+wV<+;=aIwx)KMkqv!ns;Mu8%WaXBd+Puj-=&9SRQ& zr2~#6e9ZLKyUt38v8hj-0#AP0b1~&oXo>xpH|XnVx#N02?28&YM0+sMMxArniGXw( x(!-99cYNx{3IZLSCi7cAC@*XNcmOEqzrpVF#?+h?Gb{{$_+?JCD(d_WegJ7gKJNek literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbstringgrid.png b/mseide-msegui/icons/components/tdbstringgrid.png new file mode 100644 index 0000000000000000000000000000000000000000..518c424dfe25411f47cc6e7410d715450da9d7f6 GIT binary patch literal 1333 zcmV-51sg77$cuGMv$Zk{F_{VVUvi!|@B2Q_`+cvdudlawfsg@eYij|xaN)wzxuKzfjT<-O zcDqTXQrx|JmmNEHP*ha(6t}CZi&QFw&*#H13j?tHEc zKA#WMG?8T)S(dTe?Mwf}i}awbuI_0M>gu-B-24kUIhlAoIjE|W%uENRrG+bkj~xq9 zSGOI2xw!;wZQYcW6*DpMn1O*Y4jtMHu?f%x5x!S zc6KJKR^`#%Jw#EFoBVtihOq$r<$gb?&TaFAiQczJbdDR^v3CK650gKPs=mWj7e zUy*QX*2cg?J9gQk!mEKfPcRrvci{K?Q51!%9ryXXF^eoG+&D3VcWv5(&yJ@!eQ|+o zCzuNmPr|F^2JL6v05rCy_~=v;NwUyVf;`ov^GwFF2WdT_^_HC?k07bR&B1)e#vU;` z8X=KLQQ)%ZYtra%N^t6M1|9t}(=!V^j97g9wMOs_g|5>Yzczwp2^w3hWe)%h)8bOM z%!ltO-0s&n{e#Z_lLe@%lk98*O*d%?Ihl{^T)L%G`I3nzSE8v+C!tw-2Mez)(Byr@7gNs)*eBL;bh@H8(!Z%GOx*;(&Yw%iy#ntO! zZr+vwJJHEUbatkzwk(TSEXJE}Zb(bCY11aI^|}xOjx=O(@?!cX-uT^#-(O5|aTcpQ z5~D3H#(&JE_gj@~zsZcoJiPAD1t4Y5$Kx?kRgH5U66BUHcQ7%%!1X&C?^f&V-JL@? z{DhzGD13jz#>`y0s+4XK>N7D6=(uM9;IPA6eudQq8eg8(`1Bn+!w+RnoXezQ1Ir1% zyOKbX;J~gVfn6RFiCnh$G}>-LQ(Jl*r=k|G9GpjyLCqA@`gQj2Qn5+Ua@@&*FOnSi zDuaSN!6$na4!+H^@43`F+4m>AfTcsLpU76tX(_Bwrv)h zHz&!?e!%+mF#-XVKtNsM1_CNoRVKRLM}Gb|syfQVL?^*udZHu%UDwfdooF-)BpDz7 zgMtEu=H|EnLu>2LKoUqUaUsd{^dyl;7)41jJ3ED<=om(P*@MNlEXx8c z_Uze)+pXgD7IOdoI736@)YMd97$%Ev%pw=S=PSkMOHa*~E$ddu_5bXHP-p;vHETRb zl7ynzC@gfX2>$y%Sj74B?GzWgX>af6@ZlivoRt}k&Y@{K(dZoUxJG~fC`XUJ|F0FV rTeljAL&57U#Ih`e0AZ!Yd|~(#=G*+s$~qcC00000NkvXXu0mjfnC@_J literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbstringgrid.svg b/mseide-msegui/icons/components/tdbstringgrid.svg new file mode 100644 index 0000000..a64d968 --- /dev/null +++ b/mseide-msegui/icons/components/tdbstringgrid.svg @@ -0,0 +1,564 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Algfu + Oef + Riiz + Zsxvtz + Oi + Pkghj + Ugx + 123 + 78 + 00 + 233 + 15 + + + + + + + + + + + + + + + ABC + + + diff --git a/mseide-msegui/icons/components/tdbstringlookup64db.png b/mseide-msegui/icons/components/tdbstringlookup64db.png new file mode 100644 index 0000000000000000000000000000000000000000..cc9f37ee6e2558382f8402779d77f95b17c41cac GIT binary patch literal 970 zcmV;*12z1KP)J`d4O4t4{G}fLC8xukAm_LZNhTHA# z=B@km$IWZ!{LV4l2fpzAJn!duzn;(M`+OgVWm(D+#xelQvX;bLRg-{Z60n^(IT=G$ z$<58Oce@*b{-2=F4?w8q4}kvx^F@36k3^$)v8>$>HRjnj;296xX5oN^>^NoY%1)c+ zoSh5|T&KEvKc%J3tY5!}j*hb_ZD?qi#>T@GuiMR`eFvb^3w?f0-Vx-hJStkw^U=pY z%-zV$DN@ydHZ@i2i4zA^HJ}$SeyRESxvCmapRZZhJW-(6PBrMQPgm)NLZ|-nb*)~x z+^(xv=jq_!QH{q>YfVk1_Vj$NssRlKgQ}{U)}rIbKjgxNL5>{p)7yKMv9WNn6*mU( zY@DRzuXFIyn|Ox*=G@H{Y`Aods;Y7}Z(avLAaHn20ckC&tF!R=zQ^TS#=Fh#4 zZVi(E05pr^tr`AtQM2SSE9t@b8iqqBA%eNh^yjK}!_`6R4 zn6B_ZWj#Ot8RJe=iA1LG`+sBm_NUplt&HyO0m9)Z0ABAGoH=tT4UlS4rX$Y&U0ZN( z-Ah4^lafs(tX(t8jmO=P@he3|g)}rAVq|2TmX;c7YqtW>*7i1T_XlKTI4LVDqQ3sc zG=RghEVV2P{iXnbX!+|nDqdrG-pV=sOeB=)>3?y#(oeUl5{t#j%5tT~LZLE>i;I&L z1cO0BvsaAGJdYq8s=Bn7U4MVS!%h?t2as!wnXu6xGscX}2XNX6BGL$40lG!xw1{Nh zr@snZozL7BAR-08XTZzGm`dO}&@@Xg1bl#P_4mT=vhx64z&|2VYK&>UPd^GA1UeTB zC<4|3eZZ)Q#DE54%&3UGL$adt4>Je*Z;%6&16zzSF94T;og%Uk@B#-GVm=?>HqdR1 ziO=Lczz$#^Py!g>cVLBx3@rw57N`=Dd%trX& + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + abc + 64 + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbstringlookup64lb.png b/mseide-msegui/icons/components/tdbstringlookup64lb.png new file mode 100644 index 0000000000000000000000000000000000000000..13e1264d838e156403e2219f4d3cd2a26f1df031 GIT binary patch literal 921 zcmV;K17`e*P)*TUHk-O$K6FdGx$$ zp0|r*{(p~Q`Mr9d_xt1f;dy?44AV4iR!~U*rfIH7xNX~UK)kr-xNu~|!nSSF(o&aB zeU$|LDfD^$05gC@I)DCmqS0|o^ZO-(8BUJZUfvy$Q1gT5$u+yUckc!;@R|$t7Gc**L_R4k^kZrAn;bh7Ri}>sIZ9ez=Da^}beJ}{XwXydb`*+REc)-J_lNr-<_PE`|VliHgjIb(o=41_zjxuUlivz~SCTML9bLmn& z2M&D2(?`z%c>RwT#$4R!>f&W2!l-3&wY{Bf8#l5gHB|#rMGD zNv6Jj58I26lHpA!+vmrhnaO_x0{~?CeC$4UjKLQ#s1AiF&Cds*p{k1QwY7ZYa`8nl z$hRdWa{z{Enzm`0*e`EDe+tpT7=~ex;&v~XXDk-u_2eY(3@Ab zAAvw1-a&6~FMUJAFUMyKa^FjaZQCpR*mZYz8&0N(7(kk;4m{iuhB2q)VqraC52j@Ll1#AFvRW%>D4^)cCT3{b={9VEm z0saTtRCQviZU;($gFrT*Ko{__i1aK6a2+TVk@TrL1cZSGU>&d(*a1YQz8z(#>Y|2- v)B!&NQJ@#7P*rP|pAPh?>L<$rd?>vEMhy`2RiV@g00000NkvXXu0mjflLMmO literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbstringlookup64lb.svg b/mseide-msegui/icons/components/tdbstringlookup64lb.svg new file mode 100644 index 0000000..c183b97 --- /dev/null +++ b/mseide-msegui/icons/components/tdbstringlookup64lb.svg @@ -0,0 +1,395 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + abc + 64 + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbstringlookupdb.png b/mseide-msegui/icons/components/tdbstringlookupdb.png new file mode 100644 index 0000000000000000000000000000000000000000..50d9b7d862bae85bdafdcd4d2354145af415c501 GIT binary patch literal 746 zcmV$gI?cpsWQK+phQ@9tltw6K zBq2Jepj#<2;!kLd2qLkdNDv|~3ak~$k}~tcP%zo3VFb3J8Id7=?Zeql7n9{MQz-8| z@Ls&eUupV0{L|W&oUq zcL2Wuf3w!sr?}kJsVfyeuLX z85p=J@$s=DViA+6PLg*d$mo+wnYgx1GLqEt>UODoeBUaGiE(1L-xZ(lxfl%j(${xg zL@eTPI7CDwM52z43-tHfX=yPtH1vt7skwj@<2K56&y)VG2M!&hZ0tKdU$&4jI7(4b z4%ykM09Y)|D+UOWsJvXkWO|536VB;6eZbjngb6$GyRxA69vnDMM07NMzn_^I7cnuB z!Ti}-H!hd=&j7F2M|bxS_uI~KCV!5x2Uh`D%q@fb3SNHjFzpsxE-z;DTZ)VKQdp>? zx7WtpoEre6@djO8gCT&RL=h?<4JY@YFQ_FUMooHFIy;kpFuq+6VQ)xDNusi{iOIgx@ZmKFfe*mwfH{ybq}YIM33Dk=_!091;ih@vRSodf{fIY&_C9wstw>k2*neqnL( zCmK!Yc8drekB_J*P0;6b>d + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + abc + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbstringlookuplb.png b/mseide-msegui/icons/components/tdbstringlookuplb.png new file mode 100644 index 0000000000000000000000000000000000000000..01a7c05c261d039b456a5edc33ed674d53ee11c7 GIT binary patch literal 707 zcmV;!0zCbRP)gjn)EVhLZk4`jZ!x)b({6FAW9W*{5!{5Q|>`#h{ykurR#^tJ_ukU>#H#fIH zMMWD`+SE0`#R|8ctt~l2ahM8@$qkzm91hgca*hTJ3^Wl4e4)F0kYMl! zD=XnduDmp#4DAYR7%49(Z)ph)c+-^Z<=WA3oh1%NNdox}# zadFq0n6pV$(RH2mNQCpLdz-ZpjS|(gqXCF@VaS9gbn@4o@q`D}qr10xd? ztcAlwHI2d1QEukuaw98?k5f~GV=(}pw6*ar5IFh{OeP~ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + abc + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbstringlookupstrdb.png b/mseide-msegui/icons/components/tdbstringlookupstrdb.png new file mode 100644 index 0000000000000000000000000000000000000000..d08ec48bdea3acd7d2c77b6c4fca4921ebbdab1a GIT binary patch literal 935 zcmV;Y16cftP)# z9nwpI4qrMILp zUHA0?;buJq^_=ooa~)6?>`J(jd0J#uOkX|GL__uFO3 zl2maze-NMVf>czL$jzH=B4QVp%OxTrArYNDdx%@NoSZmeqqp}l!^7i&C|)?IT0TME zU)}K0W~v7Nru&Z+@_U|AR#rq|VKxAEd&?{XArVzq8??6mgvGLez4g|>W>+H&IZ1nO z73?_$8@8}8F%iGt&*-R|q@?&@|JaxZx7!s>);9C<@AU%?BX@Cc`kq zFbt$49RN?!$C!#Y5udtfR-S&pFg5ir7E9>q77->VeIz7Uf_no41?1%91RS_rE(T_H z48M8)2be@8wwGOhf4?b~0_M3(rlFKtqm9~=_z&VBI+aVfA-n(p002ov JPDHLkV1gW3oaO)k literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbstringlookupstrdb.svg b/mseide-msegui/icons/components/tdbstringlookupstrdb.svg new file mode 100644 index 0000000..c35c728 --- /dev/null +++ b/mseide-msegui/icons/components/tdbstringlookupstrdb.svg @@ -0,0 +1,396 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + abc + str + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbstringlookupstrlb.png b/mseide-msegui/icons/components/tdbstringlookupstrlb.png new file mode 100644 index 0000000000000000000000000000000000000000..593c215898fa0e6e0b0b8fda19fe327e131b0588 GIT binary patch literal 882 zcmV-&1C9KNP)#A&vVXujz&=wl^`kvKv9&Sn5(Ml0eFH|zln2mE>u+|JUlG0>vRZ=7#K2| z0la{XbocIaoX!Ol<$OS6Wl-93t(4fG&Q|k85kSR-0IMpfsd-FsaTZxw$#islB_pGP{QP48 zynp|RwzfJ9i$+q9UL!f;Am+$OE>~C6*4RjFR1_ylN@$akR3Ur=9zHCiy}h6M`WCvo zzcVp0yE1n2STfPBJunl>$&^&ybafG9Hj|Q&K%CVIKd+df=(AgLBVlv zk4N?FSdLifvtFme?RGOgH^XJz5(;|i@bW(O>=W8g@u_6e;Ws2>9Y~$ zwY=`^WNLO6hs#CFyLTK;Oyp2}Ja2n?m~}bKcNEJeS0Q!MuDdiy017r&!d~T>OX{3~!S6)i17M}?*IS*07*qo IM6N<$f){^z&Hw-a literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbstringlookupstrlb.svg b/mseide-msegui/icons/components/tdbstringlookupstrlb.svg new file mode 100644 index 0000000..591a6e9 --- /dev/null +++ b/mseide-msegui/icons/components/tdbstringlookupstrlb.svg @@ -0,0 +1,395 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + abc + str + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdbwidgetgrid.bmp b/mseide-msegui/icons/components/tdbwidgetgrid.bmp new file mode 100644 index 0000000000000000000000000000000000000000..8b02ab10356a49753c0882f5113e8de525e669b6 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDj7vhFsutFg5pW*)~A{YV<6aZwyfyNv-Z~#c| z`~M#e0macokhwrDv^EEpA{Zd{4o>%=IT9X3^b8-M8-Vsg!Uygih~R*@2RXiw-2-O> z6%2;(fw%|a+5vYDJf>*v9-vRj16cDrFx6p#|KQY!DGn3?T8(B7d5%Fd2ieSlWdi^> CqkAL( literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdbwidgetgrid.png b/mseide-msegui/icons/components/tdbwidgetgrid.png new file mode 100644 index 0000000000000000000000000000000000000000..dcfb9eb10904ceb5bb2ec630c7fe561ac40f2ffb GIT binary patch literal 898 zcmV-|1AY97P)^^ zH=RyXtyYP}Vwk2$Hk)O1bd;f?AzV(X>+9>Ns!A@GBcIQ+y}gYnilkC0N0;St8Phab zTwFxcH2i*l;|u;9kw}C{Bm%(N+8Tl&Fg`xsv<xOM9irfE^DSrm&UEbIG` zB8kKxiNqiP=g0MGx!-# zpS}bjlljPl2X}xbE!x^DaQX5-JbpY+C?s?G^eJ|C_X&qP(RBk!5*;0Ty>3DwnY}%u zo^uqCWgnZH1rmut!r@K?LBO)UQ!JL)*(p+~)Eot_Tp0#nV4$a-I~fK`OYivdWuJk8 zD80QQ$Kqe-;AhOtyr5J%z_xAf-n|MmnS-63B0ir7P22b_#~x2BqUb^pgnG`A!NrSl z3WcvI${)WaaP8X2q1?$Zn4Mih6kP;^exgx@Qt5!z)eTftAs&wcjSN12-erD1Lpa*WkYyh| zJzczizez5)Ng^@WbSK5*(fZ5Io%^fd>|_|EQW^l=-2q%K7cDI!iqg?g>@){Yo-7aw z$t*0aFgbY>Xwo8GH>gx<=(<6 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Algfu + Oef + Riiz + Zsxvtz + Oi + Pkghj + Ugx + 123 + 78 + 00 + 233 + 15 + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdial.bmp b/mseide-msegui/icons/components/tdial.bmp new file mode 100644 index 0000000000000000000000000000000000000000..07ed8426822626eaeed7ded67f62fbe7d09a43fd GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDj7vhFsutFg5pW*)~8d@O$kF`+-Fye+#Ai$Fu V+|8pR$T3J^Xu!3PGDc1a000q&_h_dn%2;9fxeDQoSV1#f@U@iUMHjAFn!rK8n2V%|_JPW3|ezD^K9 z@KlFooQlcNK?=d+kgeZo MxufsJAAh9-D=rXk2mk;8 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdialogstringedit.png b/mseide-msegui/icons/components/tdialogstringedit.png new file mode 100644 index 0000000000000000000000000000000000000000..19f259ada39d3be11591098a5feb55778b50a752 GIT binary patch literal 537 zcmV+!0_OdRP)I6Sa?4eil%Dn>tFQ@EvibKO2pdz zKj0muT-S~Dlv4n$Rx6g~s`?jjU;I=-5PX?C91g(48K^487zTp@03w3pI24OTj4^b( zT|^|z0a$CFo_4z(_Dp>Stk-Mu`8>nnkZQFGz-qMuV87p!&1O+mL`*>JnvBF?tkEykFq2Cp1^30N+dlu9KEg+jP<5h0OCP%f8gG#XEUTrP*T zHWEK89Fgz)jK^b=$s_=oOeWmDs-8td`FxJVmkvD7qu1-9svM6;X0usX zBqA7NB4fL2GMQkljl`D@Mxzn^ejk93j}Ox6Gysm{psHAF>2x|zfXA6XDg;cY(@0`I zpTB(J{soB$r_+h+_4*#*UEP03RmFAPZ|hS4yWI}o_kYTwR;ztmBO3FSmI5SB!0*3s bem~$3ti8^z6WD%-00000NkvXXu0mjfF!$Yl literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdialogstringedit.svg b/mseide-msegui/icons/components/tdialogstringedit.svg new file mode 100644 index 0000000..9b61509 --- /dev/null +++ b/mseide-msegui/icons/components/tdialogstringedit.svg @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AB + + diff --git a/mseide-msegui/icons/components/tdigesthandler.png b/mseide-msegui/icons/components/tdigesthandler.png new file mode 100644 index 0000000000000000000000000000000000000000..d0471b8811c8840f0502dede27da5fabe159b944 GIT binary patch literal 868 zcmV-q1DpJbP)5fw$89=?5I zcbuWDT=22i`tNnwd+oIrA9Tw1WoF7uSXAL#D*W*ZUs>TFRQO=Q2GD6?I5T%S4HOZb z_UUq7=$lr#P960O%*U@do|(U#s@I5UW#%NbBjW3x{j;zR3vlVbaDF>(sIgA0Brr?D94;s7?_Lwt(uUE_A; zs6R6g;=7&zhsye6S?A*(O;3zt8xG@RP5;!iwH*;x6=8owT#TU}rHP1`rFkFtT=Pcj zG$~w)Q7pk7IMF?LX0GqUN0^Q0@h*1u1lWu>HD$X8@8AW@#0b8^E9k=$m@GEebRE=H zG|=TM?9Q^@iq#c9qvG3`S;_rn-PFQpX09>~MZ|q24Rf$OGxtxYJB4lMq)whj@oXIK zcIT-C==&#%nR)2%wWg$1Ev(JVtr0Pd2Q;H%kEYHS;W{kD7n;$rAv5=t6K=*9ticaO z|CnaPf7XrC!G)S;87e8;sOiqt*oR9nh^O#u(YY483;zjT$Bc4_aa_<%e+Mh^{uC9o z8e^3_7eC<~jNz^-z~V}8yJj-%Y~x|wecD1#;(NT&gKyMKfg@Ep&ud4-TeVi@{3MEq$24>2-po8+ZSBQGX8xsDGV^Fl uGb(0J=k&i&L=4hY(dAVI{Oo`HjrjwQU2slt+df4A0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + digest + cryp + + diff --git a/mseide-msegui/icons/components/tdintegerblookup64db.png b/mseide-msegui/icons/components/tdintegerblookup64db.png new file mode 100644 index 0000000000000000000000000000000000000000..25b19e11059849556162b67e32b749fcb82761c3 GIT binary patch literal 985 zcmV;~119{5P)CNbI$YJbKW-wUIo2HpCNCbWhIW~5a z;^L*2Tr_H6vt^N$^^heWkIyhYd7DQr1|aAIApFvA0Cx>$qpj^2e*XY||9${su{d6D z8==tO7)FemnhFja*b2ar50CQIr^lF?x`n6I#>WTivAJqtgt-P26A||8`I7GLKHTn= zseD)0&qN|og27KPj2JFgBd^u0#Xfq5L;HIe+*?TQx-C>R_7fN{<&~VgRIg>$^XG?H zw#-g@`)c|U9WTNb_7k+EWMTqJRT<= zj}yOtz*4ko)pD4gg0o$m?);Vuga6RkQV%cGVb96K=lhkNJCCqoLmAc8ZcDHAw9+9d zOota=$59%-iF5qqL5enRf#fPGE6X``s)egpZ*utX@dX;p#8biqeRPhMv-@N|r+eF2 zyS^NN8#g8y8XCoJFF>S}rlwcv>FJ-xV0sEJ_Q91u5?5|bEk8JRvG424{L+62r*nC# zbaeDORaNg`7%>0>fq^+IvRQ;fClaEU4OmhP4Ie>H9(yaBxpe6YB_$21@|KpjXl|}! z`}UV{yLXYDZKJHr!Hyl(76VP!byL@M%+HGwnKiZW?55Oy7lK$UPBdzepP!q`g~QL_ za5xeZ3=a^gZv#&O3OEZa5s|?MF$e(9i%4NIt^v*g?*S`;3ZM#@ zOnzsCrj$xch)5&Q1Vn&gV6#%{&MdwV2rH$QrWKga;QzwEn;9^J406W<00000NkvXX Hu0mjfi|MsF literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdirdropdownedit.bmp b/mseide-msegui/icons/components/tdirdropdownedit.bmp new file mode 100755 index 0000000000000000000000000000000000000000..8c1a2d875ccfed4482e38b1736a0b3c965d88afd GIT binary patch literal 406 zcmZ`!F%H5o5OXC4B!q&*!pO)w*!d0_FJoW8d-4RHk}=!iyCjtY!i_Jk&(|jR$7_M( z$$BF%oeOsEU)et&8c%eL4GG{vN^N7MBolJZY^X1&nj-m_#q#ER$1%|8D6^KoerUlt zFER$)NAd9zhO7FM55ZGk{`l>j9|yL5OHho@#~4MRezclakwCCtu{Uj(*8+HkQtQf$ Ji4M+h_yDWX=FtEE literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdirdropdownedit.png b/mseide-msegui/icons/components/tdirdropdownedit.png new file mode 100644 index 0000000000000000000000000000000000000000..fd104ed04c7251503cdf9c44af7410aa816246b9 GIT binary patch literal 714 zcmV;*0yX`KP)<5>dxA$7 zs;UYopq6Fn)zy_60J;ojZPlJ!l1x=;wOX8d;oFq8ArG)F5hC*ALDE1~B@9FE z?(WFv^VI8g!Z2hw9O8K%j^nVqyUXL_BehzM?d|R5B;WCVE{vH6g8|pq*OW>nY}+Q6 z%dxSsK^(^v3I*QY-iYIv&CN}YkB@&>u&Bau9FC5TP*p6;VrOTEFbr{Bm(gg1=XqRS zUUGVRy1Gn8fg$)yKSYF7FIwDShCv+1+}zxts;DZH$%J07$NT$xCP}J9iw(@Y16*8O zu(h?ta5&`k^_A!6XG*0KQ5502F0SjQ2r?BUl_ax&d3m8)tx~B}sMqU6QAD|1#&MkG z?S=pJ;N#V#pZoUk@Ss5uq|Rq5ST>)ZpHnOriQ|}dyG^6f zpx^IPE|(Dzo}QlYJP+HpX*Qebd+?hFhlhtVQ}_1v@H`I@VLF|%zrRnRP+&5d%$=Dl w(W-L&3#QYl-rnBocs$N7(O*ME*59tb0OxKh+s+BvuK)l507*qoM6N<$f(z|U?EnA( literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdirdropdownedit.svg b/mseide-msegui/icons/components/tdirdropdownedit.svg new file mode 100644 index 0000000..9894ef6 --- /dev/null +++ b/mseide-msegui/icons/components/tdirdropdownedit.svg @@ -0,0 +1,385 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + ilbitrop + + + + + + zfrpti + efkwlfg + + + + + + diff --git a/mseide-msegui/icons/components/tdirtreeview.png b/mseide-msegui/icons/components/tdirtreeview.png new file mode 100644 index 0000000000000000000000000000000000000000..641ac8825b8d9328e614012ebf6262dd29a63006 GIT binary patch literal 516 zcmV+f0{i`mP)akO10w^W#Xx%jqJnxRn7NI2S_TJtxWSz-JC8a)ocfD$DW!xT#0#L5 z`jO!x@-FZvaFXqI3xM0vsZaP7_zwiU&yuB5i9jF#KsKAD-|rI+hXE*;%gpC<4u=En zcAH=@h{xk08jUg-3`i!Ee-Hb3$?}M%X>z$-+3)wSt>`oHc%0pCXUm(W zNw?eOdcCq-E*XtRww{+Rd9&FNi^XjDP$)#N*Q3+va6X@@)oR}pxZQ4y$75Ej6^%y2 zR`>aQBoYZKl?v5rmEmw`>v_5&UDv7C>i`rA1s02iKh$wVL^ + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + DIR + + + + + + diff --git a/mseide-msegui/icons/components/tdirtreeview2.svg b/mseide-msegui/icons/components/tdirtreeview2.svg new file mode 100644 index 0000000..e166d06 --- /dev/null +++ b/mseide-msegui/icons/components/tdirtreeview2.svg @@ -0,0 +1,243 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + dirfil.efil2 + + + + + diff --git a/mseide-msegui/icons/components/tdispwidget.bmp b/mseide-msegui/icons/components/tdispwidget.bmp new file mode 100755 index 0000000000000000000000000000000000000000..fc450e1140a795698e0c194f4ba5bc079dc08ef4 GIT binary patch literal 406 zcmZ?royN!j24z4}1BfM{n2~`6EUo~R2Xjz}1_lNoVrXc9P(TvM1mXsU0|yQOCH{jE n!~g#v77zm=NC-&Wr33&CfP%YsD>|T{f8f~Va6pN#Q1k)-dA8?X literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdmdatetimedisp.png b/mseide-msegui/icons/components/tdmdatetimedisp.png new file mode 100644 index 0000000000000000000000000000000000000000..99c9d093a705671f0ab0c78cbda85b6bb5078401 GIT binary patch literal 530 zcmV+t0`2{YP)Q z&EljqN7MfSKane$Oe#kK0K2>M4#h9N0RSwkiD{Mr&@_SH--Fxj`qEaZ)OmWUwbeCE z5D55NYVQffqRGg}IzvMPG@A<3EHgbl#_{n66BBxiDUrA)7CQ&v?(Tv9{%*WpH@&?+ z^7)fi=*LN4pARYH6bfh5Y8Nam&9bs`K)wFbVv0sXNEt`UI8#%joStqXWxOrC4e(jp z+p9Dh7OB(?0FlT(S6B9Ke#c`vGc!&;F9F!vT4r)mw*~mRiytI}K!~^T!a~qiICR*7 zQVPSkB^VsG9o!M{_*i9cFM(xQgu`3WqL2&6HP8A11N|!E9PA*Oz`UB*^r9VI%ONai8LYGbsB96Kog8!mh zr&8!_yTv!(mrK4}a_M0$NqDcxJ$duyySx6+aYnxzjMwPrrXP{YvMM$`T@_{ji zlq2u&^1-tuC-SjX)W{EQVlxSah9JFIKGuwxt;xq@9+r4Hh{M_a^%X;o4fIAuKipg875!(R;CurTo1>y17#L9S J1L5_K4ggyAwTl1% literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdockformwidget.png b/mseide-msegui/icons/components/tdockformwidget.png new file mode 100644 index 0000000000000000000000000000000000000000..9aad4d25adc2a709a9be355e801759b8160203da GIT binary patch literal 434 zcmV;j0ZsmiP)Z(G%j*-?N7Ar1Nw$m z`416oTeXwf1ufmUGujMc6tC4FlVrI{(A&b0BoiZtAm+g1J-EDkxbHr=nurJyk^nfp z=uvS)>P?edl?I@3bwnnYC!N`3Ib{N{W^VD)xhHEm6G`?q&Zj0oNRL&Xip zK@lNm6&VcrJhm>;jU+dX6T;w{{#)-$vU0hMQVM`lsWd((0P0N>Tz|BGu)TXg)^g}} z?pRs1czu2#U)-nr)M6=_n)`_~5fN?uZ0-xwI6iF876d_ni2QgBhr^k1&+|q-SOkV) zVB0peS`Ei>@H`J-af0uNM4)L}w1UsXg1-^OO^yY>=YRd8g$*2C*C`YV_`W|ea1zyO cHPQ;+0fy1jP)R_Si~s-t07*qoM6N<$f=rCC1^@s6 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdockformwidget.svg b/mseide-msegui/icons/components/tdockformwidget.svg new file mode 100644 index 0000000..f1d4ae5 --- /dev/null +++ b/mseide-msegui/icons/components/tdockformwidget.svg @@ -0,0 +1,371 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + Plioe + + + + + diff --git a/mseide-msegui/icons/components/tdockhandle.bmp b/mseide-msegui/icons/components/tdockhandle.bmp new file mode 100755 index 0000000000000000000000000000000000000000..6b2da973ccd42235a28724f6eb1854639418db32 GIT binary patch literal 406 zcmZ?royN!j24z4}1BfM{n2~`6EUo~R2Xjz}1_lNoVrXc9P(TvM1mXsU0|yQOCH{jE z!~g#v77zm=NC-&W#RKkFeDAM?$$#&!_zq)}Cjrxa7ibim4KxbQ21+2<_YrFD-bGS# K_dY@m9asPtvk0gF literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdockpanel.bmp b/mseide-msegui/icons/components/tdockpanel.bmp new file mode 100755 index 0000000000000000000000000000000000000000..4dba15173a964ee23d5674a600074a6b94d80cb4 GIT binary patch literal 406 zcmZ?royN!j24z4}1BfM{n2~`6EUo~R2Xjz}1_lNoVrXc9P(TvM1mXsU0|yQOCH{jE v!~g#v77zm=NC-&W#RY(pP;mEdElkmUIQxEm{g7tgy$ke9IUK+|h(QAY)HnI- literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdockpanel.png b/mseide-msegui/icons/components/tdockpanel.png new file mode 100644 index 0000000000000000000000000000000000000000..88302ec54aba70beff8e4a12de08791ec7095a83 GIT binary patch literal 231 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ zFuwp{#;w&s*+4-6+J!qecYOX)-Z0JS;Jr@@%VqY-JkDDC=(t})5Z5HT z^HHx$<&&S>s9gJf-Zd#jma6v*)s4$}3=S|b1Br&{V!xtuJ%%2dj1N@){@NDvcV4jO TpB{gZ2N*nE{an^LB{Ts5hNx0( literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdockpanel.svg b/mseide-msegui/icons/components/tdockpanel.svg new file mode 100644 index 0000000..e47eeb4 --- /dev/null +++ b/mseide-msegui/icons/components/tdockpanel.svg @@ -0,0 +1,315 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdockpanelformcontroller.png b/mseide-msegui/icons/components/tdockpanelformcontroller.png new file mode 100644 index 0000000000000000000000000000000000000000..6ab3c1461a5fe6c23bbbf24fba882f5a3d88498c GIT binary patch literal 814 zcmV+}1JV46P)wnZd@ zQYvy6i;H~#@YEVYX<-0^<0@ERwSnahL9S3EL4FK`l|in^#9Gh=Me0cq!Xe7pBQLNQ z9*+kqr7}pOLTO2&EePG}mdEeaJBb5Ol@h!SvU*Apc zc64ZBZNxAPcAo%n+hABEZyb(_SPcN|dB}joBg!i(xdzSmzT4AJw0fjo{rgPC-W{>JUEsO zziVoG;_dAfd^Vd99~T#?gvX7IzrQgW&1i6BL|An?h3cxR?Qcw- s!O*=nKQDZDxrE%TEH|Z8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + Plioe + + + + + diff --git a/mseide-msegui/icons/components/tdrawgrid.bmp b/mseide-msegui/icons/components/tdrawgrid.bmp new file mode 100755 index 0000000000000000000000000000000000000000..2252e5e0f7c4da7fda21e4b159b3c31fd79d1387 GIT binary patch literal 406 zcmb7AF%H5o47^J0Ss5952Rq-P3`ogFMkWMbVBrgSKqX#~KXfDQVlHv1iYNn)&$*l} z+sbBpu25{pxF(hZDlCe=8uI1w5gb5=b9yn75)L5*CZsq-G9!4h#1Q|rdbAj=Z6x)# zyFAGc&105NYb;D^IXBl^k;Dy@Uuh?!yd!_>pv;Z6zRR-K0GAdpUwweN{^QCu=kC4t Mi8#hM)qniM3vFQP(EtDd literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdrawgrid.png b/mseide-msegui/icons/components/tdrawgrid.png new file mode 100644 index 0000000000000000000000000000000000000000..0fd363d8b398ec50a2d6459f41f889562a6e7125 GIT binary patch literal 1075 zcmV-31kC%1P)0M z2QJVy<zt!Z0Nvf)0L;zJrQWBerl_f@!Dh3e zsw#fJpSHF(N=r*m`L3?6qN*xxw;N5<*xcNtwY8PHx;n&6S%bkKE|-g~tu1zUciGw5 zAuB73m6er@RmS6SG)-e^X^B7}Kw)8F`U(Cor_+hk=>%YVdmBLzXm4*fY=hhF=IH1M zlgWh1WWsDVr`Ck?WFX7(X$G<^Gd(>`ettf0R{lwO@o$(-I|yPnT<8Py#{f)BOd!iL z0MTfag@pwqNg^B$69@zt8X5w~%wT_iAFF8@sq7&Zb1j1S9_WP-`-&%9H%|HI=H_Cz z+gV**rKF^UqM{-+O#=)V^z`(QFHVA33*tr46-XvQ2x3lt%l-SOd3e2Eyk0K=4Gj$` zyCH*-FCJsL@IHu*pdUc;7f9YE8vUJ5KEFtFb29)1kqD83f=nTd8LX|Xu^+iXndKoQ zW1uHMe++tgyvGi($1|kt7M1%aw|ik%7%-BN#FhJ^UJF z_Zwcz-{;w1c6`h4@FHQMv$K;Qu3v|nHvy=>caOWbZt>ye%K+5Y)}GDaM5?M13WbQr z<5;a$91aI&vzd?P=Xra5J>~afaWTH$UUG7B&StQ@yiBk6T?9cu5QMaZkNyT8JV2kE zOtW`9e~$m@Q(kXxN7r=*1_l5F277yZXfH)xssd_)v}a^w1g>61(9;ht=sF+xd>kGg zrWKWuK}$=EVaqg4gWI?H^wK3HNlIT71gfo8`uqF;H5oCO8kaLBc%!+6j*bqJ$)sTs zqIldGLk6?6vxb|SnwpShIc*k&LLq!UALZrcBoYbM*VkV?ixfpMOkm_6i^a&x%R^Pw zvu9CPR~MhXfWg5*6h%Q%6e=q#357y{^OV2G~?$F=KnG{(ag*YWo2b7E-o@WJPa7LNKq6Li3EzG5Rb>%*w|onbo9)M ttE;QASS(ajRG{nn@kP~j{ak-r{sG^gk-sjDGK>HK002ovPDHLkV1o4h-bw%f literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdrawgrid.svg b/mseide-msegui/icons/components/tdrawgrid.svg new file mode 100644 index 0000000..dc35fac --- /dev/null +++ b/mseide-msegui/icons/components/tdrawgrid.svg @@ -0,0 +1,613 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Algfu + Oef + Riiz + Zsxvtz + Oi + Pkghj + Ugx + 123 + 78 + 00 + 233 + 15 + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdropdownitemedit.bmp b/mseide-msegui/icons/components/tdropdownitemedit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..a6d18920aa917a4c56af6373ea5e3fd3ec6ef63d GIT binary patch literal 406 zcmZ?royN!j24z4}1BfM{n2~`6EUo~QKg&IP4#a$rT_DTB>Va4nJ zFuwp{#;w&s*+4#Y0*~u{|46k@OgZd16J;m0b=e6oNfeRN*r64;M8Qwy$-0yIJRJYqH?W$V zH=a}6Ig?X%YxTaWSI3t+##L4P<{RElgr)LGdk}%)?a@V?}mBt6E`LlHy4n$S&+>~b; zF- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdropdownlistedit.bmp b/mseide-msegui/icons/components/tdropdownlistedit.bmp new file mode 100755 index 0000000000000000000000000000000000000000..77b8d4ce9aacb97d7d0bd74f5d62844974d42e40 GIT binary patch literal 406 zcmZ`#F%kkH49v|~(51Ds^d0toN7{7of_o27N_TW|1DxPE?vb#!Swe=#bKj`pg?vX` zM{IOy`fb$P&sP#6EE4G(GAKf*l!Ah_MP|+r_*_ED3vlE_5EL6?45IKV>^V(c7VbJc z#NPLqo}4G|eb{a2JM~{rzwF;#-v6AED5NnawwhQ~joD(XiAdShXC6AZfGbbEorT|y Ln&Jm_d6N7Fd}GZ> literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdropdownlistedit.png b/mseide-msegui/icons/components/tdropdownlistedit.png new file mode 100644 index 0000000000000000000000000000000000000000..082730aa23a6a9deb0ff969cd00664bb4d3513dd GIT binary patch literal 843 zcmV-R1GM~!P)f1dwB6@ry>>>#vn1qXlsQ%Xk+ESK&i1H zp;%kv6;cozV+Dx~nm|YFptCrlkWd&CDbPS;jETt|d0&CMatOh%;3b>8y`7u4Gdpiq zNGXX?LP|-6bUIA{OsCWO8vqI+7>PvK3jl018U*lbO~L3U%jI&2L?X!N^PWw-y}iM4 zoL`$GiN(c5bhvV!rF0bryAV*oI!AcPR`=pd8HKnQ_MCgU|S3`C<*03A*2?d@S|Y6_uH2>18*+O}LS zLkQ7d2f*Ki7K_EOwzh^=s|6_~VzHREQ}y4i1K?Zcj^l8Cex6THPn?^ZqvJTb9RT3* z@i9qqW@d)(@9%xvf^FM+eD^r&GVKR$D zNk5Pz4-XG%Sr$psvMe4Q9q9;~%_e7OXGxO#`}<5J68!x9J(_}WA9oXXs9WY5gJUr;RCq;^YB(vEpP17VvUR+#odU~2yS66=` za$UD~!@mi--+}yx4O#r~c!UA4i zUOYG4AoRO%#(Ir}5HL*>*VoqofOtHPP$-0hg9BV%UJi7wDo9F++uPe8e;9GQ{s#gO V3A9M+#jXGV002ovPDHLkV1k50a8LjM literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdropdownlistedit.svg b/mseide-msegui/icons/components/tdropdownlistedit.svg new file mode 100644 index 0000000..0af45a3 --- /dev/null +++ b/mseide-msegui/icons/components/tdropdownlistedit.svg @@ -0,0 +1,458 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdropdownlisteditdb.png b/mseide-msegui/icons/components/tdropdownlisteditdb.png new file mode 100644 index 0000000000000000000000000000000000000000..fc73e15bfc73e3a0412b565c9d5e73c497043b64 GIT binary patch literal 964 zcmV;#13UbQP)BFEy5!Sa=e2A2B`=Aff`(TlRgEC=Dw{Ea@B+A87d|~} zf>5|OJ9~)tBe#jhhjo8A-1~j^-19%@eCM1`8HOS3Ck(?752;j207<1%dJhn#l*Hq4 z*$Y6nwzdRl_~s!{PnJ%niO1t)G8vx}#bOc1aT=Tx5xTp(sd0gA+ghflrvcCeuIsY8 zy2|YAEGsK3xUQ=Wb#-+SjYeB$BNmHk@t_H^*({|}iEubfxm+fj&1$7erNZ3YTuXvn zF6Vpt2-4{^rfDJ~n5OAV)9&sr?d|P8W7TSv?d@&-eJ_cJwt523Xd;ndaBz^BnHc~= zp%BSr()VMbP@t!$hmDO5IyyQq45MjOO1u-=Cn#WF3EBWetpC8&#fBZF6uv%KSa^g| z11u~&s#6*u5cq^d;u`>p#lIOEGB|W-h~C~yJbwI_*0pULrBw4i07$3*ARhmKOy*CY zC&l7VI8GISiHSQzBJWTx|AJwB!NkNJt>@K$eIEdbh$W75UydDnOP)UcPL3WuERJ(u zL@c3pMsn@i=OSWBXJ?1(?EESs)*cbb<#JkH&N$I!n$50JD(w&sf2r3OF1!ywrLsgQ zG{&u4mk9)v_N-d{hbK=q>F<9}r=%G~#FEL$&%`vZh=?Voc}1>X9nle#Npw$30YsC7ZFR=*XQNbsS}#u zz=42FO^u0&C56Hda{he396T75)2H8+wY6_GK|Q<_sh0$=4DZcxu^~-{Vc;WBY5;&> zu#LsV>kJQ{ePi>s9U>ZylF#Sq>+8d|ZDO&Qzf7Ulbc>7E86CX|z}>qK=4899zKiX)b4{DH-6;d!<&qcn~aZt+#(8Fzb`K@12jgk7tf!UId^W7 zXV11;slNWgsmIdN?*xOj;Eo@Eo6XJdaoqsK20D#$PlogVlf#`V8R8w_L1(|g_k0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdropdownlisteditlb.png b/mseide-msegui/icons/components/tdropdownlisteditlb.png new file mode 100644 index 0000000000000000000000000000000000000000..0c40fb6b77efdc8e736f0a514d7656d197566079 GIT binary patch literal 967 zcmV;&133JNP)o8)+2Bf0IpXEDMD$xO!-*4Q`QD5M!Bo>QF zEdbfv+!Ubhn+spHm|+;iVlfsL7Cf6Ml}haG?bU5gL}+VkV_yqw+g4+8auNU~;5ZJ; z%gbak8J3ooa2!V&YH4X96bc<0jc_=uh6^Q-&*v$Z%LIc#wzs#*=ktoRv$MnW^z@+u zmSuUK9s$EJNT<_?2^oC$5^FOVQXtkeXkX9;jb2OjmG0~1_lP0nwkQj zwY8P8u`$n&>+9>Zx3^O)7HMv7M%VR*UTNZ<&=Elcj#R)8Ag1}{mU?^ZmNZSnQwI-o zIkZTGhq>GbQY3=!!Uf`q1OTNsZ}{c@eNJ4w$oauR)?U3*T-&zMG_7$R02t4o6YJ|^ zp(;fIN>87%cTg91Qz<&no@IM+5q)@=yQ!4ox%uC)4xCDb<+U|3qoXXXuHsZGiqvxX zGNFzR02W`qWcM~RU9j8yr>)BZm)0Eev$+gleVUDxpl zXpsm2$NYXCCzD)_MnBuW-PA-V6rxZl(ACw2ZQF#yVQ-qke$hQnCi!iA9DqOO=J+-m z<*%9^Q49Av@9gaK%>9kXSEEst_sN+V7Bd-cKX}0Hc>L2|*tU9~pPvV)_n;OVqPXsZ;#-Z p{5di4QR8j~>AJ4M17G2~{vWT_;hRXDm=*v4002ovPDHLkV1hHM#qIzA literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tdropdownlisteditlb.svg b/mseide-msegui/icons/components/tdropdownlisteditlb.svg new file mode 100644 index 0000000..710410b --- /dev/null +++ b/mseide-msegui/icons/components/tdropdownlisteditlb.svg @@ -0,0 +1,465 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tdummycryptohandler.png b/mseide-msegui/icons/components/tdummycryptohandler.png new file mode 100644 index 0000000000000000000000000000000000000000..a4f8a03ac76880a65d62db10624921c72dff61b7 GIT binary patch literal 812 zcmV+{1JnG8P)7jD9vcb2GeVn}A zOI-i3*?a%Lwbx_swH6=rYwXQTnF%+x_#G|&(H6g|#lO?yM~a(=eg|Wj`H3@ti0F6E zl=8wCoeD=pEW|SWi7zvA|7=+3M#R2aUyCQO65|oEW;P5!zoJ-y&9y!kAJ+Q%nlHve zT!kf?XggS5^U~I%Usv<(J^V6kF*A=u#CH*~2v6cJ+=hMFh{Fi%!CZ{uhKTqHlURd? zv8$JvmrfDc_c;GF{5jZ+2kP;!qmfYy5hcx zh*vdLIvw`nWSi({vS`8S~xkGCZD{2OuJz!w#&+w>7#JA#ZtkvZDC`RxUo-LWB_^j3+;YFNXP8`HVgGSoND!e)9C9R&a z7Q0*fMVbmf54*9lWne{1?hV|7JzYGA_i#l-bSm^aB4T|-c%N!N z**O@)1Qz!)^ZEL)9WO`3Z@3WmYkJEtp21i3c7L__dn00bUFWvUoQQ~jvM4jRm!Wx? zIa%}zHQJbqukq3lzg5#+k7eednlI=^#CTh(rTky0O5KHZnfXWS(*%Ca%%d&kGIMf9 qt>XV8B1UMk=<-$u{9qP;WBvxC$xKx + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Dumy + cryp + + diff --git a/mseide-msegui/icons/components/tedit.bmp b/mseide-msegui/icons/components/tedit.bmp new file mode 100755 index 0000000000000000000000000000000000000000..a857b7fbcee1f07b4b291e2e3c9209cd9946cd23 GIT binary patch literal 406 zcmZ?royN!j24z4}1BfM{n2~`6EUo~R2Xjz}1_lNoVrXc9P(TvM1mXsU0|yQOCH{jE z!~g#v77zm=NC-&Wr33&CfP%YsD>|T{|L)xam@tC<;RAyGpPzg-iaGy5<^Vke2K;yL Mmcs!hzCzIp0C~~=+5i9m literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tedit.png b/mseide-msegui/icons/components/tedit.png new file mode 100644 index 0000000000000000000000000000000000000000..3873b790ccf00cb1c6ebdf5fbe3413b9eb41a6d5 GIT binary patch literal 243 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ zFuwp{#;w&s*+4uprz{67B&3}FVtm!%YYnRT`G0}{e<1L`VoEGZkq!OL+UA4kVYiWz0C8NVR z%OyLPIA0K(H$#%)x#Wa5t9CmGd6X?TtoNDzAllJ8Aj9XqsKxxQsMn>R_bhDMzlEjY haIF3eZP))IZ@P|Zh&G + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tenum64editdb.bmp b/mseide-msegui/icons/components/tenum64editdb.bmp new file mode 100644 index 0000000000000000000000000000000000000000..dc686b442f72bfc0d4e02ee40b65fe5b769f028c GIT binary patch literal 1782 zcmb`EF%H5o5ClU*Lr29EcmWTf=TE#0@hVy~%97Q}P9SnP5odkAo9vnE?X@4qxUimi zPM>Ets$qC?emv+I3t683iwW8PmKXXTrL6yzQtlBRs)OUpfH%t_sc7wyR}w#P*s{)Y zTuFUuwL2q@EUo0wTLsLF^&FW=hv~-yO4vDHw_Xx(u;HLZGgiGCM36+eEayTmagwma zkpbJV$of{3Ns~Y4a=k|ovm(Q>A8x6gE4#jEan!z%14>bGfNu$n33I}CzLSF=DCx>j zA34LP9VAd^- MzO)Vj(Dt^AH)^?6IRF3v literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tenum64editdb.png b/mseide-msegui/icons/components/tenum64editdb.png new file mode 100644 index 0000000000000000000000000000000000000000..472ad295e52196eca3f101a88266356553476f02 GIT binary patch literal 1000 zcmV>P)K~zYIwUkdtTvrsvf6s9wBgKh-hRGiWI=ciBhc3EG2`xt3 zSldk&7B|6|YKbFljEgQp$4%VSGzKH2lTZW|OKmfPtwOSL(R5OT_fXVDh{6b&TAU%K zt=i~(UFbaWI%5}2^1R+S7?DUsyh=nO5lK=il~N!OkR*+bjmhWpsjRF_ z{r&yw?Cg}+>y_8*Rd&B50a{&MmEZ5zey|0ao0|nlk^+H%;_PQrX5*cTVP{j!?9VCW@ctoQ&S^J8X6i>VPT~@ z)+(7y+PV4pc}GS0DgYc66y)p6$jAucaG2rYVf=nS!C;V;l@%%~Dkv!_0bplmhh#Dd zz~<(rebzKh2UlS}fsT$2*4EbW`FsG3kB<`yg>bvwM59pv5{U%CV34JyB|IJvkw_%( zBQo~Nd}T1$ZOSV{A%HaX5~%8OGKOK0x5@t(mStfW29{;f-Q5k~6v$-6l`EqhKKv0y zMelR^^kp7DPUR(=octA+>pe#<6bd=MIRbrscer`;Ck6(>+`HGq=H}nDwqDO6UtCPk z*w{lR<7}U4ns#JiKT}CuyB1?$pq={qHvt$O{ha&v7aSz%^dB@dd_hagyIj5cgPqS> zk`I!mw7UAO0NuFJuA@iGb>Kje&YXEmYir+0nvyi7XU~4rsZ(z#9R5%X3sGgy?uIls zH>d6GZJDNN|K+wtsnk;dZrz$>aIlNJcY8=Aey647EBhvwE=9>?GW7PI&wJC#%1T@= z7uD6(c15;DZnq17!ND%7s$K`+_U+H8s%qoOlRt^Yer94K&VvWnal7*lfPHO}G^O?R zI|8(|HDQ;%wKX9?4Gb!c(@$An|I5DBqen^V>o2pg5ar;(*En>j5!fAqF4wLbhG95|U0Yi{XU~2~ zU*9Jb6c}8*_%-Lw)#33J;qjDn + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tenum64editlb.bmp b/mseide-msegui/icons/components/tenum64editlb.bmp new file mode 100644 index 0000000000000000000000000000000000000000..51f2010737ee663a2645cfca948b1fac65723463 GIT binary patch literal 1782 zcmb`EK@x&65Crk!#hWLe;0t_!cmL$eC|>0iyBL|8Nx0#Li$LrWlabvym zTt3fXQe8K2em?1$3R#B##f)r!%M1N|KW_hxKI!r$vP{Pjny7iiXgAE5Qnz88BAc7>yWjPmmjgy2m zjttm_Mb_7vOq%>Tm+L)(m<1V*{cub5T-o(Si=+0P98ija1AI?tOqesi@tqv}KuK4I z`p6kR?I2lmgmS%wP~PVMMRJitzUZnmG*ZKgtK^U*vR+#L2Gw0WI6uV0)c=G!;ocJDl9CtlSfBKRa{)` zB-lM8Nv3JqE5mCGtgo*-k|k+kVnUUbm6D{Mo*sET9@W>^?)7Hl6iV6VwySn&ga?(Mvyt>M#t*u-=dzNqe`s{e7 zB)K3Nh87+_7NGC1U)TFSpWZrrShXilYH@g2G7QNu^!NCq^x2g9)#voBwAwX4g%$yd=RX^C&HUCVjXva&MV zZa3xS<+dZcM0uW_?fs4pjvqS)z)$V%9KU>-zt+}BJblW~&z|w?-Me<~o7k&Nl3{4& z$rAzE92>K3Z;p)#(C-f(=t_09V_LqxzNoFW%Q87R=@@*jT>$_-ym*oB8#nlEc+iEJ!0M8eqvfG^LVCpkaQrJFZ# zyWL!=uHLhux$yb}%S=~CiS~tX7|XH + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tenumedit.bmp b/mseide-msegui/icons/components/tenumedit.bmp new file mode 100755 index 0000000000000000000000000000000000000000..18720d927c127c091104ce5f8f7e6504af140b13 GIT binary patch literal 406 zcmZ{gI}*Y$3`CU~3U_WPDLDr{*TJni`vjaPM{*Z;;>r0q41*%co7G0%$>aH+q{oYX zr>=BeDgVz&w z9*soby9`Y!1Fw6c%h)^kU(I^izq@?@?ouS=%_c|7wPGPgO9^bzth#5%08+u?gM-Hl NdRtmfN3_!~DIe7t&PM$BBGF#^9`D(sVVvmJ@80gIPac! z?tL#;(siAvCv;sWNj^P2QPVV%@9(Lq zDr-RqOioS`07+8QG@hKC(6TIsLLosuJUnDuTbnn)=NghUO;Zdvt`K;8d-IS<^6c!4 zLqkI($&HN-27^IPO-fok&2%?*c#hgmEZ#kX88=W*oc0D#9qz^^WbVPJZC z8k?J&P*oMtXcTvMcZftHXl-o;08}a!6pKXw!2A2VSZkW5Csxo;U}k0pkB^T~6a@gV zx3`BxA^};JvAVhn04Nj+h(@EhzP?6NQxkMu_dP_?r_H)S!bef+h9Cgc%Y-CJ@D$lF z3`mj$!!W$0KmenoqX2+Xsf4kyF@!=P#N%Wm%9U36^DHVPOFPyaN0C`xqG+ z!NI|SXD6jn3ASwm0FuchdU|^B@bCa#*O5#n1uv0Ec%CjulD2JAQ50TXT`>}g(6(*Q z<(ZqCBT2TjwD9@)nSQ9g$p9#h>Cw><%H=Y;y1K-CaBvU+@bdD4&dyFOE-oSv_%dCo zRFKQ%(AU=|QsM`a8}ETKtL4wH@GRrXTt&D-w$?n zb|A|#06f?`kR%DREMseH3ji=bKaY4kj){p0tgWrp4DOyF kUDvU@yZaRnb^cxd1H0Lry0lt&CIA2c07*qoM6N<$g6_DI(*OVf literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tenumedit.svg b/mseide-msegui/icons/components/tenumedit.svg new file mode 100644 index 0000000..2a1cb6d --- /dev/null +++ b/mseide-msegui/icons/components/tenumedit.svg @@ -0,0 +1,438 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tenumeditdb.bmp b/mseide-msegui/icons/components/tenumeditdb.bmp new file mode 100644 index 0000000000000000000000000000000000000000..1cd7341f0d3d85d932972063e1d9cb7ecc2eb3dd GIT binary patch literal 1782 zcmb`DyAi@L5JXKvLPkUhR6qgb^h9Nht0EN-E$rN!JQgE!gT(4S&nsPT&;3;6!hU9* zK5JLiG|kkH2d&!3Hvcca$nk%9Vg6Cd@4r&YJ%leMPI6vIe#%MY2?~3?7zMw>RHa5V)h6A6vBZ9VgDNV(UHKi1kA}4-vUBl6!$1TBoqC#9FKH`II^*kQ%$|M#Ifx$p?8L9{+NgyoB)Y_%yh{aKJ6gc za)fffg-||fkR2MyMGpBi)n*u^r{$0&V!w`L6zM1fEr(`zBCI1MB~?oI@}mt1fVQ_? FyZ|S+SM>k@ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tenumeditdb.png b/mseide-msegui/icons/components/tenumeditdb.png new file mode 100644 index 0000000000000000000000000000000000000000..6420648f0cb2bd550740b83e1c202a8275326b25 GIT binary patch literal 1004 zcmVQjrF#)7nZ^@`oW^1SFIS5$3@tSV$B#bo^T+ z1cjOD*M-i*amJcO?FWbV?&aL`-S3=x&owN|5{C)PvLs3C>+1>x0+OWR;bHlFK9!c1 zs<*dSot>TXdcE>`y~_AY5}@VfW%>Pn?FWb8%9SeuBuRllKob)avTa+1g@umu`1rU= zN=mW=?5vTbSS;pPCay!Uxw)C;EJ>4-ld7(+mLv@f49M+vtEHu7Ujo3f9D=>hb8~a5 zsi{#Sk#Odwr>CD;DRAYhOC%DZt*wp0!9o0fKfz#-#l=O+%E~A%E(Rc-PLoI^ z0NC2va@NLTv8-6`d<5<7?X0b>;q&qipa9FV z@*W~%N9LiyV7n-X1~-5d{SQK2%$YF^gRCM)B2O`lS|X9ByPRrqxjyFdIw~rz^8EQ9j<0Ro7>0pu+jMt#17s6CcILw{7lo#`eq<0s$}w!d_J#Uy!cLKWyMM+A4!Tj7w7u*&m=`vR8*ji zjb9{1_gL;t2IL&mXV0csS=r#ki7%Y-g$wTi@cQ)#<>gJ>x$`A1m*MOzo&KBY>3OQE z-gQ!v50awl==fAUJ=Y{f)zfoLot+Jif|Zq@bnIBMq^KGiK2TRzlis`;)7`sY>CBms zqaYrSE0szq7K`m}9oqyaPafCIOuwY4W@h?z>eO+E;K&h|y1JSqMYXUnp!4Uebo8i4 zr%%75si|)rg5AiZ$k-v+SKiy>VosVY%OZ=wFlqttc-#yP-K4($>|2Mo?Q+85F!6Yt z%F0S?+r~6aa+;kKWoYOojg7YfxOeX{MMa-*|NgK4N)Qf*0SJXcS>wFTuD<>($z%$E zTep7T$&=eOH}}xo{Luj_Z0CP;bQB<0!Ct(2waU439lU(`=RvNRrs-G)c?m{Fe#7J0 z7U%buFhBo2snp{G2{LcN?l&PPMTSx96dB;gjYcXeuF}->A^rVd?;AXGf-K8&(gXiP ayZ#3P^Pg#qqx0(k0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tenumeditedit.png b/mseide-msegui/icons/components/tenumeditedit.png new file mode 100644 index 0000000000000000000000000000000000000000..7e04ad8eeab33ec14dcf0242154dd47c0059a0cc GIT binary patch literal 910 zcmV;919AL`P)$BBGF#^9`D(sVVvmJ@80gIPac! z?tL#;(siAvCv;sWNj^P2QPVV%@9(Lq zDr-RqOioS`07+8QG@hKC(6TIsLLosuJUnDuTbnn)=NghUO;Zdvt`K;8d-IS<^6c!4 zLqkI($&HN-27^IPO-fok&2%?*c#hgmEZ#kX88=W*oc0D#9qz^^WbVPJZC z8k?J&P*oMtXcTvMcZftHXl-o;08}a!6pKXw!2A2VSZkW5Csxo;U}k0pkB^T~6a@gV zx3`BxA^};JvAVhn04Nj+h(@EhzP?6NQxkMu_dP_?r_H)S!bef+h9Cgc%Y-CJ@D$lF z3`mj$!!W$0KmenoqX2+Xsf4kyF@!=P#N%Wm%9U36^DHVPOFPyaN0C`xqG+ z!NI|SXD6jn3ASwm0FuchdU|^B@bCa#*O5#n1uv0Ec%CjulD2JAQ50TXT`>}g(6(*Q z<(ZqCBT2TjwD9@)nSQ9g$p9#h>Cw><%H=Y;y1K-CaBvU+@bdD4&dyFOE-oSv_%dCo zRFKQ%(AU=|QsM`a8}ETKtL4wH@GRrXTt&D-w$?n zb|A|#06f?`kR%DREMseH3ji=bKaY4kj){p0tgWrp4DOyF kUDvU@yZaRnb^cxd1H0Lry0lt&CIA2c07*qoM6N<$g6_DI(*OVf literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tenumeditlb.bmp b/mseide-msegui/icons/components/tenumeditlb.bmp new file mode 100644 index 0000000000000000000000000000000000000000..82a6a53723035100c010cb5e4ca38e6ab82688c2 GIT binary patch literal 1782 zcmchTF%AMT30U(}Mp;-{&WS?_!Xjbg*mK@oZ;$;{K9}il!kZt*0ypjF?nuY#(F5mx3DfbXIB~F^gSm&LAVoTBe}{U qpSs!%jnuRpl0>Z6k&Gf8H9*Uu*p&$D2uVp@C0~BD4gt{Pjf*GhqA*zi literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tenumeditlb.png b/mseide-msegui/icons/components/tenumeditlb.png new file mode 100644 index 0000000000000000000000000000000000000000..5867181b85f3c128b08c6a9b4c042342cd03e43c GIT binary patch literal 1016 zcmV;Jd@vnCmx6?r z$)FuF+CH=mh){?^(wCtR*Fs(beVF(%WVi2hC}36WhXYAN<^V4&V8|`VL$}+_ zp`jth<8iuNF1lPUmiQzIfLmKz^m@HK3`!spi4Xuu(&zJ02tg?&old7BFDxvuwzk%q z;9w0&nx?6ulvfGt?(SO1B)PJ(!uIxdlH};@YmcNjIJ)+N+uOg*LBO&B2Xw6@!Rq;2IF!3y0nBsv8YI&UATZiLjwR{?&(wX z-Mk6s@#DA>4r6I#MDa}1R8fLDri)Ty`{hg2U%sryp_Uc^z^nOre17pFlF=w^wl}7W zuU}&|n?-Ydz1osWAcbJ;>Q&zD?Infa-QHftuU#XBAOLQs(>&pFkwWmh^XJ(giSX}7 zkN9IO#;=;2Ng+s*nM{U-LV>1fzTG_?xq}-W9q)G`rFx&5ngW1w2k&BYdmC+CUHD^j^FvhV zx~`&xiUO1K^KjVr&3WB!{Q2Mk3QwMVP@r_dDqge_v|vyb832B`ejR5zJ8>l(#?Srz mhbAwbAj2@!_5lAwyZ#qxu5_@~;NHmq0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tenumtypeedit.bmp b/mseide-msegui/icons/components/tenumtypeedit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..d03e8f8a081cdc890258b05b2a0eed6c5f45a996 GIT binary patch literal 406 zcmYjNITFG!3{++)GD9JTijtCd(DNPKy0c%vd;BDKaVJ(soNTd(8|C~0Dxeo6fU$7#-V literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tenumtypeedit.png b/mseide-msegui/icons/components/tenumtypeedit.png new file mode 100644 index 0000000000000000000000000000000000000000..9b934dc0aba7383478cd639b33a07d4affbe0a96 GIT binary patch literal 673 zcmV;S0$%-zP)p(=1PNx9?;c)oR4lT=4>)~*STCH|-006ySPi=|_a=9E%rxQAz4nzbbU2{I4$9B7g zrfKkaJm_}2h(sdFhG7_LK>%u0t5pKve!nLGl6*Sb`^V!^=}prl0Gg&r!!SsaDuUa& z8ybxUG);4be>famvc2!~`CNL_G+nZCkjZ2K0J^R}reGU=cj)F zf?MuC1~1^w|2rWf@VwKYWmymrSeB*kLI8UqS9-5}H-EO~( z(y6zHeaSy|@_xTZHk*AJr475$oDKI-MSsP!Ml%fK^Uw7^^#w3QLnVLL00000NkvXX Hu0mjf=QSrD literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tenumtypeedit.svg b/mseide-msegui/icons/components/tenumtypeedit.svg new file mode 100644 index 0000000..ee82e09 --- /dev/null +++ b/mseide-msegui/icons/components/tenumtypeedit.svg @@ -0,0 +1,462 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tenvelopeedit.png b/mseide-msegui/icons/components/tenvelopeedit.png new file mode 100644 index 0000000000000000000000000000000000000000..50736d595116895a79aa63f50acffab1d0b39494 GIT binary patch literal 613 zcmV-r0-F7aP);|i85>$rlop`~RuJjBf`WoO zaiy*VQ7Zm|ajSb*+8Uwj8pNHHZb}8~qPy0QG9qevhcrz|rbS`K#f%@#G)db@4h$FW zJ=|yB^PYQW#J25#9)D4)yK7=lUCPbs4A?N~{NNi0P zqV*_uy#j#NOno==hMS}3*sRyPq9O*UD#e!PQF=bnBY>;8a^n`Sij!i7Ki)#I6roQQgJd7z-XSRx{7Sx1mODJ zamKG+Ch&a(5W?0J!d4YPqEQpLeg8pc1@&5ubS49U)!)yRpcydS8v=LCkBW3w7k>-pjQ9Zf3IN`3aD}! z-}l=9T$il5KY)l(7#QHIB~SoinLdA5ZVgy>U2^9BJop3nxU}7e9Temf00v`5 z$Ga$rf}sv2sw$PpgQLfe^JQhFHK10hkV#M?Bb6d=9ijZ=`@gyW6J9JVqHD3+V^8sV zZl083K=jEp0362weucMK5ItQA34)-fzb(H3r=*@J7OARx00000NkvXXu0mjfnV$(7 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tenvelopeedit.svg b/mseide-msegui/icons/components/tenvelopeedit.svg new file mode 100644 index 0000000..d7dca31 --- /dev/null +++ b/mseide-msegui/icons/components/tenvelopeedit.svg @@ -0,0 +1,281 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/test.bmp b/mseide-msegui/icons/components/test.bmp new file mode 100644 index 0000000000000000000000000000000000000000..dadd96fc221aa44162e95fe896d5a798d601c587 GIT binary patch literal 1782 zcmd6nKS&!<9LJ-ALha;GGB~7LCZ&r)>kt&TS}~j~=XEO!wc}WGk0z8UBuTnsy+T!?QiU*yDd{%;j<(kB2@NB9qAwO&Knm2m1F~ z`s?01tk9>tMb~w=+iE8dY`?94Uamd|M=KAD&%KWWy^)K}Elo~fB9UMMMC-X0|J)_c zb)w)3zqx`i2^9*3m;-NQsgEHLCvsrFyLcH{A}X0oGUw`4mk1&KFI4x}9drs7NTB z>3DXK17c%YCXj%Iy)4%21?GV8x-zX8L+sV`TM~q}uph zdR4jKI6RO!nLm;!L6R!8kJI< cTR^17O8vpMSYLUtb=#Rs7P!REai){y4@VWicmMzZ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/test.pnm b/mseide-msegui/icons/components/test.pnm new file mode 100644 index 0000000000000000000000000000000000000000..5b065c933ea8a64eabb862a9ea264455352ec2f5 GIT binary patch literal 1786 zcmWGA<5E^|4svx2@ei_62+2rQaQE~LP%l;p@bgu0%giZBEm8keGvG2Z zQ7|&$GBP#gIxw;U149E4Q62`Qn$v&*ASM7wARxm%KwWSXC~*v$AwVt}jsa=`YNVEv zFwG&)Rmffgnh9|vkw!uELV^O>93UHF6oiB*z(oSp!1cn}a0XBcmqs*kh^26&APk@y yxKU{833AaiqHzgo$E5(`FraC;6c8g0aSVlq04;($hC-u|gPj=nkE)?*2mk;=p@^;k literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/test.svg b/mseide-msegui/icons/components/test.svg new file mode 100644 index 0000000..e4d64df --- /dev/null +++ b/mseide-msegui/icons/components/test.svg @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + ABC + + diff --git a/mseide-msegui/icons/components/teventwidget.bmp b/mseide-msegui/icons/components/teventwidget.bmp new file mode 100755 index 0000000000000000000000000000000000000000..4a55d7d76181ac9e73db99a56dfeb5e45acdda98 GIT binary patch literal 406 zcmZWjF%AMT49iJuEQpDbk$1539hi{%3ZxGGOMihnM7#tQCk`#*+&bqtZhPm;V-d#{ z^#mS*i)`FKV!q#!J2*xniC{}g{GdXDNouVabl=juDGYS}{U5Z*m%>!$#W#m;oHbzTG=KN%)|#W z1ExVlMbpBCwXiXeiV&#m0<^42p|@V1@Z|N)p8(c8}oD1d67&o-^@f+C@FbLadC31 zb$J0q^*qt&2!n$sX>L9ws*!AKLpchU5DebNvW}5R2on<@n4bOuq_+(a)oRMhhUw`! zOhrYI-rgx3XV^C8^;U7dN+hc7)YUy=WTcISg>NL2PjH-5UgDk(L^Vh#bc3$0cAA>@ zGBEHK*S%#M^WINlTRITc2;uM~snl84*MHI9KZfhZa}m$#Kva)VUq47^XEmdvpK;xr zwlSY_5zYz_)%{df-lw4+`NW`GW06sY5`n@ghV`|k2Q2evW4ZDSq+7Vr+}0bYt~ zeL(;KqFM&5+s0f2P6I2zq^Mpm2!PVk%Y?%RH%4CpXQO}Y73z5xiRwPu+AgxT=7_2b z+yf?UWBUB$=Ix-dv7eTfYF1ZI0DZtY+n8s5#61CGSx4#UI73wx)YP;SjUE7!qS`I0 zySELXwe>2swdKsrz}y@xF75(~fB@j@Ezi0KVp*Le5)sD6?lL?3k>%wn+n8lPqP_qu sExoYg@#n + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/texpandingwidget.png b/mseide-msegui/icons/components/texpandingwidget.png new file mode 100644 index 0000000000000000000000000000000000000000..667f90aa6c9c5d68e5197749b92babcbc6bcb306 GIT binary patch literal 821 zcmV-51Iqk~P)^Ox@cDefKrWYi>$>h6fLtzzBuPyV8is+UX-)mE>oPex2|#yu_eH5xniH-P zBuS#HtE=HE6bcxIL7`A+%DGzH;^JZ+2nrh;8&ABnol2#yeZ4|hSy@rrku1x?wrv1x z+s3l2wt){04(T_=f+qQ|tVht0`&dweK2)eF6uNe))@D#XNBEv9l`GjmX z8>wwHO(UI7Bg^uCC6HyAbUJJoHa|J078swx8m1NGHTT>#N&^fP$8Xz_Tw<-QTd$H%_| z2vbv2uiB9nMXCRIS(fWF_X6SM>0II4UjgF3<0VI>jXXSGF zF2M5g^2dBWe+=NOR;&1Yz929M1UuHoCC>f;HKR7is;9lJ00000NkvXXu0mjf^ + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/text3429.png b/mseide-msegui/icons/components/text3429.png new file mode 100644 index 0000000000000000000000000000000000000000..a7a92d52755d1ad2a24ddc4ec9c1a4f2f3b3e26d GIT binary patch literal 569 zcmV-90>=G`P)ZOCz3)2&E%iR@^Lak-XoJB( z_$KkkM}8a~@pgL3YWwE!%s!}+PgKgUY0ApqFSEXA+W-8hbubxxde}xBsq?NB?%78Q4J9}h;!qxN?BF2Joa~y;x4dD_ScW*1 z=TOgM;3&Oz)LzK*9eJo1=TSM)bYR55i6lCEDUTk8{g`&D$U}a#UJI1RJ(W}PP_Gp7 zv>E*vH~>;F+)L$1v_Cz2nrGq1O!MMiG3upq^2C`q_Kws31V&OyFXZWiA8_jThd7+a z8Y9o}<6Jmt7I`MJ9z!1T+?NOc^=&vwRTdC=D!7&fdV(wWlb7+4ClEk4r z;7H+fe$3mPXSHmLmF!9$net5LJk%@Wdyx(d^Ssz|s80%UuX;ZU=ae|eBlc$|@1CUn zAwOq032;OnZSIO^^iuqwR}sC)&-=Wx&%)2}Q4qb5r(bwRFMWShPR+7jXz!1$VNE|V*c-OgJrmdRg5BK_^`T+-i;92aU@T~ihI&a4@ z_j=D;*q@3Oy;Kf*5$D~phkMbyhEnjuo)e*a#OXTQOY8tGr1~d$*|Twr{^k4^7LCiU literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tfacecomp.png b/mseide-msegui/icons/components/tfacecomp.png new file mode 100644 index 0000000000000000000000000000000000000000..ddd4b66f92ddb975f59209360b802ac9b3bf47bb GIT binary patch literal 380 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ zFuwp{#;w&s*+48>!e8bI8Zz6sBH25_T;q_c103jNc{%_JMv#dCXlFj=hra@%YFx-X}_>Q{Z)cAc+b9iyMu^?e(< zeH%?T=zX~S{QtStO!s%kyl*^vZPm`7QEf}YYd#9P6|2m3OWS9y$jB4(Y-Xk4flI6m za!!{P3O0P5*tna`LN9jrkICPD@ZWR$tk$q|Gs|ny)Mq9QGbb8ydL}C$xaa!##F@_1 zv6pljR&q1^)2rfpaO#8wm*;o4hP~Zv6KD48m3yvcI2YS+CMVH4i)XdqlgYMyhWk5M X=3Tyj`O`aKATW5k`njxgN@xNA43C-= literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tfacecomp.svg b/mseide-msegui/icons/components/tfacecomp.svg new file mode 100644 index 0000000..1f80b96 --- /dev/null +++ b/mseide-msegui/icons/components/tfacecomp.svg @@ -0,0 +1,269 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tfacelist.bmp b/mseide-msegui/icons/components/tfacelist.bmp new file mode 100644 index 0000000000000000000000000000000000000000..e046aee090e4be8906dff3e6c29f8f185f490e69 GIT binary patch literal 1782 zcmb`HX-^YT6oy;6(H2T+=|-pD{RRF2zxz)V5HTRAKtMni!3BdmE)m5IFlfZ6hzd&F ziK4ioiFDuSKJCe3D3};d`T& z-sFd{WF^`E^~xdt`hA^1OG}IND<^xOQNCnVPg3gp3GHO8^mVg&00Y?J47BlkKtZFt@{4k-t6EC?L)r~~-!{Ks)gFYVc5&Cgdt>;L8WMv1Y&vPLf=GeshP{+CqJtIS%e0aW3hvY|&Ci{w}S2o+^Hnq&|7h(IEJk zJAJ^hHM;F}z`=<-s&Tc8_m9AtXOS}%*N(?ZMejwKphd%Qu z74gwd#B`&PvJ0!_r$WZTfaxIkc&)A8$|kpc7w=QJf3Tm=85wfe;+doxd?wI`atwn( zQ$PAxT0J(xVQSDPH+RwgK@KNhNGs-9)l5n~l|atbNZCc|6Rha>o4UL?j*B+KRIl$D z9vGY92sn_AKNw%Is>ez7y@d7_SVh4~e>w!|zzV0<>a{gt+dQX+f8GVo29)40 z!u}BsM*a+euD)=x1u{FZg08^oT2zNtVZ*T?9M|RpK5LuDwg-+`7qiyqAFciXuF6Dj literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tfacelist.png b/mseide-msegui/icons/components/tfacelist.png new file mode 100644 index 0000000000000000000000000000000000000000..27744c424ff331a7369fda09b7338720cb5ce6fe GIT binary patch literal 287 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ zFuwp{#;w&s*+4^*L2 z#s*95yIdj~-h5(xZGEy_kDo=|=Ir4wjHa>k6xg>;4%2g=wy5)TVne5mx-h?+uEf@a zD@}piZChDi_A5zBNEC$3yuuI}8QH_bWAcIV%u@r0QuzZheA^%V`1qLTct3l@I+Waa<> literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tfacelist.svg b/mseide-msegui/icons/components/tfacelist.svg new file mode 100644 index 0000000..1c56313 --- /dev/null +++ b/mseide-msegui/icons/components/tfacelist.svg @@ -0,0 +1,346 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tfb3connection.png b/mseide-msegui/icons/components/tfb3connection.png new file mode 100644 index 0000000000000000000000000000000000000000..e77897a1ba1a6a3904705552c7ecc102f1d4e07e GIT binary patch literal 1350 zcmV-M1-bf(P)C{Bg{#(sE4W3 zD%H{EjQ~>M+DESC!OqXC%Db2mlL#JwU7)5dO4lDHF}tNR|vP>xVfh z+f-HSPyIZTUE>%NUb3SmytKk+8hdl%OVpv3{ZW>Sz~$S!Rdw?3ml0L0_TMAuEWbX{y89(Fro6`a?bxW=yp^jg|!zS$sM zI}i4JvM~^-6)@QBJi+{)=@W{AHD~>%W(eqv53l30evK36x(Ix2@>diD=FzDI+H=G1 zr0D_LD&ugBHQhAp6Tr$OLlR#<)1C2UAoL<|zk+tDVwW|OX(5|rDX2CmbT49Ra1v!P zrRuLXU*v@yDvmsfCv3($yqeW^JWg}i60^Kn{~$tm?kzlnY?8wlEL_-UjfX0xL(^cHJ+mPfvvDdAiiwKqTh zwrd(N3YZ1tcZ0TJQcUgQ5|tBMYV#O4WjJ2dOn3YhXo~PvRqGY0;t5hy6O_-_A%5ps zy3}$KqMCTX94qPRX{x@y0XTLmST;UpC3+arRF*+39(uG8H*SRP*ozq{6UhlbC8j@}XV$*a87*ZZPN#OZY6va+#&I2;BcWy38lJf1ZCes9FM*j>!rp7+SJQXzF<=}qs;D;J=-2&l zhlfYZ=h5i(grrBKMb**;WXPO|bF{vad@B>{R;RbeIsGct_F{G3*Aao|<;7B&9jyZYZE@QJD8DfAzv$ec^tEl-UK^S7$u=95hDNoYsF(zcidO z)FpqlWVnto!dyU>IhFR#&!|^*_y)xTVk6(2-!B#I4`A{;djNXxqLH4*7#1ogQJgeu zwba;(nHfAlBDT97GpNpLS5m}+_#3=i}0t?{N&(LHpQ`cK-`qJt)k50CGBQa7; zkdqkdI?2{6Xma;ag;WQf+Sl~h*DJ5LEBevE|74FR6D8{jhDxy;>o8<3N;2;>sunD* z65(T2-*|i=)?Icnij$t6hG{NDWGIkG@1}bZIi#AJuHUWpA0)#7qw8{G?EnA(07*qo IM6N<$g3Xk3TmS$7 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tfb3connection.svg b/mseide-msegui/icons/components/tfb3connection.svg new file mode 100644 index 0000000..9905800 --- /dev/null +++ b/mseide-msegui/icons/components/tfb3connection.svg @@ -0,0 +1,448 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + 3 + + diff --git a/mseide-msegui/icons/components/tfb3service.png b/mseide-msegui/icons/components/tfb3service.png new file mode 100644 index 0000000000000000000000000000000000000000..a823178a42b7181b72e3040df5278ba554aafc87 GIT binary patch literal 1628 zcmV-i2BZ0jP)(nW+Ln$!U7Bmi8Fr^hE&uKZ)Wxw3B1(zj%LermiM+&2Ys66pDC*Ge8vu9Vlk zL-L4!o6PoReA(Fu7_u_y8TqZROIG`LoCYVb92f`IOafm5x2*QRAvK8+xi9J2FC+eJ zyjbjcCO<=2E&~&=fX6TIr2#di8G75-7wEFR)Ke2*Zw2;xlzMw{wtk_1O;S~^OKbBe zwIBF1un$O{qTx8d%)hzyFK&6hJmD-5xh%47dA74k4kV5ZJm}vC9E=zIO9Fvx$;`}< zoxXukom=M4)FigkHz3dX-e14a)%a*}LS6H>yubdA(|O(GacxSjl}3-0Wg2IIF3k;% zEvC7=dapfT)|!t2-vr2XtGtGF;nriTM*jV=E0&scO9Wd4img<9%-0=uenA06F9)MP zdOI3z0&*0X9Al?>2^qr9S8z@ntw_zOej&mA>fg=o%(n1ffo}kqg7IFr>3TmH^|ziv zLWkXGN^#$l<1G3^*!M}$c0Ck!KQ!mK^Ll}!z(+up^FXk)=$nymc=(|B0o>ApK=Gq zz}>+8@2yU3v5$I0miadt-L^e@?Kaao+8*@*CB(fO6?Dgz;mRCccU`co83SGZj}X98 zT$`&Xyh>wl-`I_knVF$_dU}E8cv3OT*nn+9hRQXbsBoJ9xS)?zp9n7j27wjvj<%L~ z^>3GC8AU06J;Qjw%wK=TfhK?rn;vm;=rtLlr>AeKT_rg=nG`z@8*t+@h$+YI^K?%v z5O_uP_jgVLSELTJG`5lgJMHq?s+sXWiw)U+#rM4le^Nx`iU(1l9;MJu#Rde?7*->A z#Y2&O$0T`CQUMj_bIg)7Y{j&B&^Shu@zfRFU+W8Sv-Kbv6PTDpjj}f{<-C^Wq99AY z2D}11^|%!)O*>^}&+gN>tK8t7f0}IG6T_dVa3{ddJ3Q?h--y1n{o?S4z-a&nbWpAp zvdFp)JFeKNo!3e|#;HAZCgfU64Glus3>|MsgI>iC<~iB0%sKmDg?ID9H2tCl0Jz$AY<;~cw&_UFay>uaGly2=SGJ$^IF&vlO{1+l27MEw z#$A0t(c#x^UE7u|GnkQhCQymLt}6kfCljDaHMiqdvvVKYv5GmpsYE;Zq>mh zC=s2JFzjxKar&IihQnhdhJhdqgoLIRi>4Nf=Ck&Mz)AfSZT2b!0ucWuY=oBIBqjQ@ z99)B`rJufJRe#l|FG{yHV@1G0eXq^YZi|ProRqsAXk!o@ht?sXbx7z72{#WWd`PE# zuj&X*zNafjrhraf>eD!7HRIG_sEhdRb!g(?iz22*2y1T + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + SERVICE + 3 + + diff --git a/mseide-msegui/icons/components/tfbconnection.png b/mseide-msegui/icons/components/tfbconnection.png new file mode 100644 index 0000000000000000000000000000000000000000..8f616947749499a0fa2bc2977de0d0e228cdbd29 GIT binary patch literal 1469 zcmV;u1w#6XP)%-KNu7I@5*ST8p;wY>-XCr9orG zl}%9aMNH!p1xtml z_a6UX7+VF5e|VDn&%NK}obx+5zYBkI$nicX6wn-;$!KQ+aT!aSu~jy8-43AV24AGc z4O7Gy{Lg$vKJ5JD4;kp};5CeQmf+VazBM=Ufv%L+#OH%B6N7)@^z2+b#x(pS*ddR| zhWKkIEJs1~y1+7huCz<9_pi{CODj%DIKr`XZrL5W+}EZp{*?-z;{iR|;$Nd1ylK6< z?5^Jv{tbUtaIUT`jqBfio3+jt{w-iZV70#Ib@jU7ib3zIsv>&5|3zKwe^RduEY{kp z$Z<{P1@F<;64if{y|1H26+!L{^z!og+}QU7uUYF^otPt_02&TgW10^4rgkOkvLRog zzz(yMeSAgQJV=r*lEhgr4@y^8Lc!wBz`I5 zzzck3Mj7MOaaMSWLA`SkadG%ao*vZDEqV*jd){KXXAQTOoa%eJ@HsLZF;HMqwuTA% zABn}H0`^gw?Ag;tw{#FvlS+G{ML_F_N*8@4yP-3$FRh8)+RDX5B3|j}=+RhUJ1Myq z?|>vmIb*c4vO?P14-GzUF>nMbWT-_UVKRozfde+bj&sV#b5eG?M#}1$=uD+JSHaPU zN|g5Yj)4>n1Of!zVYomsJ_}nsgfvJvTtO@r%>!qJT9}r(k6O1JAk_y2Hdtm3-~!*7 zn~n}eKAPl4M!TV0E7c$&J(Ow*4elj*@rJTmnzDEI57+X4t+J`QB1O%d6yZx#oUtIy z+AR*eVYRZ&`uCvh>wICxIe*0fTmf4%25~t^3aHWx^T-Bs0jIguH$BwPQyXpGyuX;A zUiH$s-plOsEUvnvk3}zJmdTEep1gQ%Z6W6x&oIe74L4U|)YxOtrr!_;hC0nUCUh16 z0Ub^P#*Hvoy|9qRhye*Ox?%oA3rAtazI1*a==ew@O|gwMJJaX}62Om=Wv^$e#eQoI zyY+7b)yD{ZP`id*KyQz5NLV&yuy|y-;8>{F@Yj#7@ldQ+VydG zz;gcB{7}9;^pPds#I|Ww@NGsrS2EN&n`G}Q+NF&Fv+>Wj`g!~_n?#=yE)mwvE2e&= zP6g)|(7;(rAtuL+?Z!H`#%Bnq32;{|wf9cTTa8C2AyP)1ZQ3us?aAy&?G?&w!AwKY5t<_w z5A4j~q~Wrl1t|tU-<$vC|L#ob?oR_)dDmT?ORz&j2|2UyFkgN$9+`76J!MFdA@7{& z#mcpJSFcObR_aXyItKJyfe!OiI-PlPpgX@323?s7Cc{FvQ=l#M^TF$OHnSwrd#$6$ z + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + 3 + + diff --git a/mseide-msegui/icons/components/tfbservice.png b/mseide-msegui/icons/components/tfbservice.png new file mode 100644 index 0000000000000000000000000000000000000000..22de8aff97029095e0ac59df7e14883e7fd694ac GIT binary patch literal 1568 zcmV+*2H*LKP) zB=?fsoBKFt`Qbt&W5n@8_ssgT*INJofA78aUK{?;Lw%J)z)5ZBW+quz(ywOFrR`Bo zeGdT0+|b_`Z%1%*koWYrRP&jA--tkd61tTdYZU<*L%Y6>z4C%;iMNi3xhgb`Z{-%^ z(B=~$&im?FwY7iqMVBL>q-%K|S5I7SV8 z20XGX@K@RDOUa^wHD3q(C88gP7Rn}nzuaT)lu9#lp|2F!aZRy)>^n8OY`oU{HsAs} zfWLc{YW#MI-eLVF@RuT&>hvnr2s8q30^SiMw}l>;7O%+af`3bSx%>S5Bfl8us*`QL zp^imnBe3}#!C{F+N+cRBmY2=m#9oh7j#DD_X0JSI?!M!4=aKuWT|4FW;A0XB1%|il zk>DO_^@=PFJ_De+prtLHyLHPZ=?S&Sa^QymrCv4uz}E!m@IHMIe1ju;CsVCTu8GW{ z?mBlagBvR^Q6l@j()y}f7R=E_9tt*( zdf-nM9F+ZDkskzB8^_Z!@ppBZ+^&-uA8<8r3Lq^w9qZ%kN_E}cVOf_Bbq5b2YB83g zdZLccouet4o-Wa7v5Lh`kEBo!*p*U;AExxxB<$pt_cuo%bzFHQ67-=8+d zs0s!2VztD&bmbuj*m;PxzjU&%LHdZrx<{xF27`p`GHk$uX^>Tp1=WT(yCw3X>gnnH zqOQZe%+Ic(!Y<6u*eowIh6&1x6yW zf_b?|883y{icxL5(L$SX{|NP!W`vp65;XELS;-iezjpSLrcw{lF>)iY0eE_?o}G|r zwo0x~>fBJR^X9G`e`?GU@GHV5Y^e2}{8@earG{9%8E6M^LOXM{8C-2$c7By~YA3WB zkMaIn@8n>tRhz5|%?7^r>uP5@bymnGpzDP2`!_N)J?LS}YBv)KHP$s`5)HATPl4UQ zEmBkTWO{jU7PZ!V5@nuruBZOoGC1q5$xid1p6rVb*jJEI21y0|(7fN~ z#)$^*zWl?xa+Z_S6g7FA=3TSllXUT#YR}vQW0R96T&BF?-U}Y*|LD!?(CK%K+doTe zztYruI{s%z|1p@UdVPxT6fyN4sl1X@Qt;&zoU0Wt3a`QusgSD%Pr&wp479^Sr-N|G zIf4`x|79b90Z=OXhWZ29l?Qt)cil|yRE`?!#mzm$l~(T1_*Yj3y7S2gyDiQP3D}C+ zMLKJ*aDSote8Ik}ZK1XQ6#xz3?SafwfA}P0-4t@5U@Xd-+~2Lbh{J4$&d1$0o8HZG z+S)BXJZk3&4(W$EZZB0J0Qx!3tP+krZ~8rjhE$T%iVhE0 zo9CH&O`)wBH%A=o?y_h*ZL^}(#Z0Gxo>ue@3CH^K7C$RY?{)2`)BdUYG%H+bbaowX<1P&O z6-r9J9H{!SwLJ*yRjhaCXjotQs~CY3jTU2BKSE?2;3r?{orr8zXU?3uSnlUq)n!!V S11*>U0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + SERVICE + + diff --git a/mseide-msegui/icons/components/tfft.png b/mseide-msegui/icons/components/tfft.png new file mode 100644 index 0000000000000000000000000000000000000000..fcd87198bd80efd3918c4870c1e041f3e617bf0e GIT binary patch literal 499 zcmVC*eym;kX<&2VPTt?3GgM?;rv3Z>FCD;4;hvi&=RHQ*e0ND>Z# z`7pUm^c!FzE;$G|L4uGyCaoP4&_A-EPwtr@~os08L;K24)cK)(Ofj&tc z!T;I*8~lT$!QlUGU%!(30+Lp0U^mkjfydxG!1v%&z*z7mu++`~n5}J3XW~rWqQL4a zEozJW2fR0?D@n7Zs@vXe04>{HZKL0aqAikiTmcIOJq9Y + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + FFT + + + diff --git a/mseide-msegui/icons/components/tffttableedit.png b/mseide-msegui/icons/components/tffttableedit.png new file mode 100644 index 0000000000000000000000000000000000000000..cd930edc261506023706e601cc9e1766aaf1f3f2 GIT binary patch literal 331 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ zFuwp{#;w&s*+4z`ug^-msYR5U+N5RlfHHjACF zZhC;wFHYZf0b_2F*9;8CtM|mX$T2X?IVY~7AfcqfVlTvVu%D&**Upv)&;Q=KEy|D( zvh80G>x{l%yBgf;AGkN3+_0Sc$Qr={jiT5GD|lOSipyI+>oA+5| zacR1Z8)`59xx9tx(6yV-5C7x3!BT(u(%DB$iL1@qeb4AzyEWt7W)ojWrA1Y_JDJ~q W)y$UPFYpuSCk9VfKbLh*2~7aG5`i%Q literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tffttableedit.svg b/mseide-msegui/icons/components/tffttableedit.svg new file mode 100644 index 0000000..9eda11f --- /dev/null +++ b/mseide-msegui/icons/components/tffttableedit.svg @@ -0,0 +1,274 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tfieldfieldlink.bmp b/mseide-msegui/icons/components/tfieldfieldlink.bmp new file mode 100644 index 0000000000000000000000000000000000000000..9a38e2cdcce866f1d489656215869173d95461a8 GIT binary patch literal 1782 zcmd6m%MHRX5Jb%-2P&WhDo6p`>5y6wRdIC&PrO=Y9mxqu$;#jLZE%BEEq$j)#5H|lH1+iYq7{?%jTFapaKqPkLL^JSae(dw8&cCcf uW;Y`hacdkoUAkwH*>;Iz0xl?%q~99H>Y|fvemuFk?(qXnPiyl3o16ec9>0?S literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tfieldfieldlink.png b/mseide-msegui/icons/components/tfieldfieldlink.png new file mode 100644 index 0000000000000000000000000000000000000000..f117fa871b267362a1516d91428505b005b52d66 GIT binary patch literal 551 zcmV+?0@(eDP)t(kYSbchfJq;v#3Y4jRrj2OR@(n;*? z=`VRa4gfm{X&#qa?{nSuC*ZN96TmfKbx%ZcEtU(+OR5E4 z+U`2&-T-sWmDg@A@QOdvbVzp`2DaORZPWBem&(=I-vG)sPSF;~@LbYv<=4aTk)$D` p=eTOSb)@W1qh;8yM*EKhegnUG;LQ91e82zz002ovPDHLkV1i>v>s0^% literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tfieldfieldlink.svg b/mseide-msegui/icons/components/tfieldfieldlink.svg new file mode 100644 index 0000000..958c8d6 --- /dev/null +++ b/mseide-msegui/icons/components/tfieldfieldlink.svg @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + Fi + + + + + + FLD + + + + + + + diff --git a/mseide-msegui/icons/components/tfieldlink.bmp b/mseide-msegui/icons/components/tfieldlink.bmp new file mode 100644 index 0000000000000000000000000000000000000000..965e29974363e9366b976f680c4037532f354c8c GIT binary patch literal 1782 zcmd^8!41MN5DOn3Ouz_CzySOir~7p(zF^|iI@vq`A*jTuNt`>|xkT#eeA%`hN6ZI| z{TQ2$TANXyb{w6E>AKd)-j~MGFM3;<;qmfGg!hu0XHLBjI;m% literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tfieldlink.png b/mseide-msegui/icons/components/tfieldlink.png new file mode 100644 index 0000000000000000000000000000000000000000..8641570decef4b88eb1d9bba1cde85f8e1e3437a GIT binary patch literal 645 zcmV;00($+4P)XH*sErmPqNs?a zwMY_@MoA+!miAhywS{OT7K&CX7(oKth!GS5n}Aj-#7JB;*<+D;IJ@hbY_Wx27~Y+8 z=gygTe`aKxPD<$L?*9*gq%lcdIVdSe8j1Q2Nu#Ngq_MULfW5$}1U~`{MtvL@mDHcu zFKzf2VioNN?%U4iw}By`0L%a~e2v;1! zSBEg?5bhcdwIa9x3D!=f_K54^Em%Rxycpa`r2A8mi& zx3MW4c@Bnv>%h~*Hp^N+90ZmU{3h@&p0Ffo&h{_>w(3Z1uC=5NV*uuvF5P0l*hnc6Eh=^gRMEz461j`Nk)JbZn*nZH)# + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + VALFLD + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tfieldparamlink.bmp b/mseide-msegui/icons/components/tfieldparamlink.bmp new file mode 100644 index 0000000000000000000000000000000000000000..334c1546278ad6b784d3e6217d1b66f633a62a84 GIT binary patch literal 1782 zcmd5)!41MN5DOn3Ouz_CzySPN86mL~-{9sN%iJX>RFUA6w2td@eN`{l=RTD><9fnA zu6tKdN_RYe9BdaMF8MFZ1?wGqJZEwO@X8PqIKgKhbg@i{qXTpxKhi=C4WkbkY7FoQ zK@Z1X6;Jfh0Qw4tH4j>>NJep$EO(X7#kZUXm%cY9g2_m!3?{a;(FAd1$Iyo+&gxqq z%K#HsKlF)Vkd1kk-=b7a{uUiFei=8B9qHqq!crNNDdTX@rzvx!9_h1ARY%*FN1dB^ NWG-k%R?~kj`2xq|t@8i? literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tfieldparamlink.png b/mseide-msegui/icons/components/tfieldparamlink.png new file mode 100644 index 0000000000000000000000000000000000000000..4bfc26e184d2fed7ea07de43acf3b3a886c8f07b GIT binary patch literal 619 zcmV-x0+juUP)DbPy|eMJr=IgZ z-(N>|!_>ll)zQxC89l6-3?u-Owo7W1XhhPDx(>^T6|e^Q2%Ij+J_FbL4UiQ0pSD{C zGH|=!09k=QENOG(8@4Y3D+d|izU_&A9hQ;wR_TE>JxiK?Ax+#}4Xjt^w@I3y^Wz%>PDaN~;1O_H(lXoMfgwqEqTLAa&i3mCnU`8b zEVT{10QT6P1&#wdfhk}Ga5U=91LuKTz*^u6e?wJ^;@djl2{0UK6qqTu2-q8w%Bl|U zUu${{xM#Z^=@l?9X-6r+X*vTxQ{`l74y}NtI<)^Nz;7cWG*db<1uFmm002ovPDHLk FV1goI|7rjL literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tfieldparamlink.svg b/mseide-msegui/icons/components/tfieldparamlink.svg new file mode 100644 index 0000000..bd7940e --- /dev/null +++ b/mseide-msegui/icons/components/tfieldparamlink.svg @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + Fi + + + + + + PAR + + + + + + + diff --git a/mseide-msegui/icons/components/tfilechangenotifier.png b/mseide-msegui/icons/components/tfilechangenotifier.png new file mode 100644 index 0000000000000000000000000000000000000000..a41697c3baef733675da0cd456911b0c8469e9e5 GIT binary patch literal 934 zcmV;X16lluP)Vv7@PkVr(w)NM_iHja@B7Sq-ZMv2O7VY=o{U(cCAktU$xR9%B55Kr?LY4$Wm8iu z&)04%b-9S7h{%i^>9s^#BqDjh8DKY13AkCtNxXM`nC~53KHoRDcuzy9HFD&;7g*Q5 z9tZ-dN~z-mP4Fxb0t$e=3^mHMA$RY2s;IK^lj`>$Zt48_ho;SqX?)pT3*-U&fC<+c zxEug0fN?-Kqg}1(@8rB)6L@9#J()xGH|iFD-~LzE7aZ!{0&E9jz&@qau4@gP5)1*N ze3ZFAt6CL*0BI_noa4QB?UN6d_r6}YI3;eL4=R7; zk6ST^emamyV1j|M+Ke+C-HxM~AG7dGt!hy=fQWnrv?-;QI00_hf%4TKHs6Xpj@w)c zwuxyhXH8bUGzJPTFRAC!$+@)z*QE&u2jPk@!PcI`)(l+MM$!kbP!H|uyDfmLplC@h z@jF&w*#UI^M6(tsUqjeQH=x^8a!S)#aQ1}qhiBqqIvRc0dPo`rTjWWb4$_gJFxwUmi6=+YR>y>KKfn!d(E0eH;ioRJBtMba{=4575IQV{lZsvWU z+we7gC^SaDBC*#~1+7qkt;KEZz=W5rM{iBCvUfZH_}0SIX$IjS(wa{vGU07*qo IM6N<$f_CAsQUCw| literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tfilechangenotifier.svg b/mseide-msegui/icons/components/tfilechangenotifier.svg new file mode 100644 index 0000000..d9a5d1b --- /dev/null +++ b/mseide-msegui/icons/components/tfilechangenotifier.svg @@ -0,0 +1,275 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + *.* + + diff --git a/mseide-msegui/icons/components/tfilechangenotifyer.bmp b/mseide-msegui/icons/components/tfilechangenotifyer.bmp new file mode 100755 index 0000000000000000000000000000000000000000..45dba18dadb094f3d00f0df7713be37fc587b3ad GIT binary patch literal 406 zcmZ`zF%rTs3{&q|7_u`m@(y;s!<;8{;*P<8$rG}A@LPiHlxt|IW6QFnA@|2?Le!IZ z<6M@Ra0>mp_;LI|2H42CFCr-?qm)9UMWZ!m96px_wyjYa`8Kz^Q>7GO28cssYI=*+ pKN5uJn567fJU(J%8Y!*OUFg>*IkQ#0lF)*4bFegHX{`f&gN literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tfilechangenotifyer.png b/mseide-msegui/icons/components/tfilechangenotifyer.png new file mode 100644 index 0000000000000000000000000000000000000000..80fc30dd584b5707febd5f04415e796480173135 GIT binary patch literal 1018 zcmVPF1~ zdDZeL_xcA#mqIH9_f75}_vW1M=lovhDpE?WrqsD?7A?7{q9r%=ssO~vg8O6j_`_y> z-VPyz^1lH@y->x;{GCe^(zaF z+ng;})dPS(wEhC{EieW+COxH;|3(082O5AqfEy?$J+{I0r2W&!vew<0z2vr}XZLQo zaOtbgdiD(+1KNQ~paxhB>;hIxDgT_d22#o(kPDcB*U)(Gnn&i>eO&Tp_F!Pp^wfvX z|9I)Gw%6G=v?p}hKSHUr1DkR0^z4vdufOYelGvfl05yh^vsEBY`;sLJ$Q|*Uf zgER-ah%wp;>TNU+A7%TLR-YX}=&KgxShF6VpO@TClBtG`wrWtmq_Q`kdjA(p%uYl_ zr2{PMcW+*`ByX|*;r^R_xBC5zD)&*|?E{9H!CXX*VC6_rPVo(eB`Mb?;kKuW>lY?# zEYP2z-f=I#+O0Dgx~PCVZFw(dT$gTd`S}}K&wtPFofi|ijFT?ifj1Zv?N2tTh$*^f z-kLS*;~sRq^Lh3DbFDvh4SM^}&^qb^x`7@huJ->_#5NUuLgQ{MKpM~o^fGb(8=;4p oq$pwpGC>9fVi5RYHiqH)8zQ< + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + *.* + + diff --git a/mseide-msegui/icons/components/tfiledialog.bmp b/mseide-msegui/icons/components/tfiledialog.bmp new file mode 100755 index 0000000000000000000000000000000000000000..8a9a30f208f70622b7312c61c571a363fc779d5c GIT binary patch literal 406 zcmb_WyA^;S3_RYmrMI+n4tv*;Ql@Yo2C!fO=CJWSJOT>VdXVID`MgZ?rXX18M_OM@ zp%Z;5bxB^%0{pNx2YOPPg>#ODC?7EwIr)jY6H_oGx%>^yH%p3p! literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tfiledialog.png b/mseide-msegui/icons/components/tfiledialog.png new file mode 100644 index 0000000000000000000000000000000000000000..3fa95843bed7950f96b6d3510df8e241fa227980 GIT binary patch literal 531 zcmV+u0_^>XP)VK~zYI?UcVu0%077A5RPVg;dIs=qV@`<)G#)`Zu(ObEB(G zIh>nYL~AbL<`y(I*mltpVHnpf5_V)Y73AAc9Eyi&;pPL!y}Tdp`@HY>?p}uwLNGyG z07s{9q?2tfG%vUM5&)Oy`?yylEV&it7Q6r~d)Ij}o2p2 zP14D>6$&9(m1BH$zM*Dkz3Te zgI?4R8^%~t^O|PZP9NShCwcu1HkEY z4&=6iaq#(klu9K$9uI!Me_&Dn78D8v^7%ZbX%dgesZ=U``SdKB3jU9)SS(Id@CAX- V5%I$DaU=i$002ovPDHLkV1hJ= + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + Plioe + + + + + + + + diff --git a/mseide-msegui/icons/components/tfilelistview.bmp b/mseide-msegui/icons/components/tfilelistview.bmp new file mode 100755 index 0000000000000000000000000000000000000000..af26c65772a4f260892a53912d21889f1e194ea0 GIT binary patch literal 406 zcmbtQI}U>|41Gv!9YA8~*pYLv_c~=l$|-uD+@e#|EBFG)JljCndC9Y%o m?QtzkRr~(%`6Bbt2?uIVowfPs2iOwYlH=Yx=M&52OUeep;2nwp literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tfilelistview.png b/mseide-msegui/icons/components/tfilelistview.png new file mode 100644 index 0000000000000000000000000000000000000000..cdb546997e073e71d7a8408b7e329089d17b8dbb GIT binary patch literal 345 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ zFuwp{#;w&s*+4G*q>s_^t;m01%ah{fHJoD2_ zyL*dNJTI8=&MBU;Omm+@u&F9uXwmEOu_jp;Oea*?~2d=Y< mFnp=~|HFB4^UO~FBeK^YFST2|v1>cfhYX&selF{r5}E*W-isRm literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tfilelistview.svg b/mseide-msegui/icons/components/tfilelistview.svg new file mode 100644 index 0000000..746babb --- /dev/null +++ b/mseide-msegui/icons/components/tfilelistview.svg @@ -0,0 +1,211 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + File + + + + + + + diff --git a/mseide-msegui/icons/components/tfilenameedit.bmp b/mseide-msegui/icons/components/tfilenameedit.bmp new file mode 100755 index 0000000000000000000000000000000000000000..a9cba3e5280ac18554fea74233d63ca259265696 GIT binary patch literal 406 zcmbtPITFG!4BX7nyQQS$9rXN#Dp0zlOUHZs5&dC*psaQB?xOXM$^^}|)ffgjpUhl+W_894|>7*BO=pJp_ eQ-dT%UIRZpUPe!$tMtEL2L+1RbHkCVcC#yGt@oAy literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tfilenameedit.png b/mseide-msegui/icons/components/tfilenameedit.png new file mode 100644 index 0000000000000000000000000000000000000000..bc9c98078286943915d43cd700864124355bf6cc GIT binary patch literal 379 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ zFuwp{#;w&s*+4e3dBuT4Q`W*j(pKOMtG2*~1&>SAB3|xG zIVsowPrf=WM^(wDbG`e`|E%vE!b87iOfz+eoYp^~`-FEwWXlnYz5|NvUMuh3xOM)S zyH0iV{Ou~;C#<$@vlbAX5@h{9IZzmM%RXG zMm&elGwt`>R@|p^I?m-+FV~Oc#YYQ$u9sRopYhysk3;Nr5m(1aDoZk}UTwC%e)Vfi zXvn8mc(|*_PA7&i95BA1e>zhom`Li_h!LIMj4?f$^IWPW$&2vf0 Vc0&{UpTIC+@O1TaS?83{1OPwam;L|% literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tfilenameedit.svg b/mseide-msegui/icons/components/tfilenameedit.svg new file mode 100644 index 0000000..196aafd --- /dev/null +++ b/mseide-msegui/icons/components/tfilenameedit.svg @@ -0,0 +1,245 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tfoldedit.png b/mseide-msegui/icons/components/tfoldedit.png new file mode 100644 index 0000000000000000000000000000000000000000..fad8b543d5136425a004e844cbe1240c901e7d6a GIT binary patch literal 761 zcmVpPCz~MN~p^#gtw$q#^W7Dv}I>V1iS1 zkb+$lr_w5Ku%erZr#9}e>`TTRkFuo|IZ0%QwZQCRg2__~c zTHvFjqg-EK128i)!}$0(BO@a%HN(Th)M_<$cXwG>Sg7T4Ily7ax~>xl1V|(jTwY!h z2n5iyn?8!gA|isOY4r8=Q79BxU0tPIF4NW3MQ3Lx7Z(@ky8h#i=Xi^zrl#21+G1#E zh-$TZ??V0t4i66rg+lj!cXu~# zw;P|&M<$bDX=#aIFv#NKBBp6RE}+q9P_Ng?WHRWwPQ6~I*=+u?F%$}Me0&VR$;k;G zkH;~fWyoHymt-6FzrPQFVHj*|Y~1^$Qi;92Jz}vK>2%s}7{*P2hztO}^YinjuIp7N=wlR# zM2JKp00e` + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + ab + + + + + diff --git a/mseide-msegui/icons/components/tfontcomp.png b/mseide-msegui/icons/components/tfontcomp.png new file mode 100644 index 0000000000000000000000000000000000000000..b69d3c91e522bbbb73e2fc1769e3ebc9ab2a43b1 GIT binary patch literal 787 zcmV+u1MK{XP) zR|PWK$FgY?f>~nw*(f1FML{2!AS7hbU?nX?5FA?^TZCpoP83EMFJUmCS&Qcm++N>& zv&jRO`+v^;Kj++Y?mdSKy)wSaOqmJmD*bDf{-sJkUg-~4`lUs;2)z#0X6Bc!gG5BH zJ7+v18Z7MNT*}N#^YHOaQ+;f~PsnOKf2|fHVrN7wfXuwFiHOtH`rgdEvl_drA4mHP zEhzIyg}ZnfBXhhimJQj_DBi`Ah**rbGxL3X5D}+vE7nKEIBvtucmv}R@hF@vr~VXv z#i?p^upO@!&SIRw4LFD$MgJuB6nq*B3+{C@b9rBi{+9QMScyX=r?V09J=T=vqhM8sr+sq109 z$V8Kwn~S%xh`4_~)*@nizm579ZNwwT|ci=s31EZ~zGX)>PiGmMn&*v6wEa&(M zzO5tc;6P?R{x5e8B4Pt3GIP@~Zlk>w*D5pG#y4yuOKG1PE2}5SIsfA`<}ck~6y0;t R%7_2}002ovPDHLkV1hg&Xzl<2 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tfontcomp.svg b/mseide-msegui/icons/components/tfontcomp.svg new file mode 100644 index 0000000..96874cb --- /dev/null +++ b/mseide-msegui/icons/components/tfontcomp.svg @@ -0,0 +1,216 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Fonttmpl + + diff --git a/mseide-msegui/icons/components/tformlink.bmp b/mseide-msegui/icons/components/tformlink.bmp new file mode 100644 index 0000000000000000000000000000000000000000..ee7b24e75e596d30715cc891904b88dff2fdb5b2 GIT binary patch literal 1782 zcmeH{!3}^g2u1PY#iJKTZ~_PL?oO`Z4i3>>+`()8={HS7Vq$5JC52#=ClKhm-Ms`^ zU}xy`Y8N~ahxg+^4Ijd|dIH*Uoj7D0eC854Bp56?4BSnE*w`F$y!W}S!k<$P>oRkI zO8ZmJsa01kPV0{vur@!cA?i`}C(fZ^;~A^=%ZvOv;by?}G9RGK9Nsx!bz$Xm1<84Hh!1@>+*{=p{b!)yd;=1jqoN-e7*Oy7;q{IV00CaM AnE(I) literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tframecomp.bmp b/mseide-msegui/icons/components/tframecomp.bmp new file mode 100755 index 0000000000000000000000000000000000000000..686846d75ee7fa9d813e1924635bbdb4234213eb GIT binary patch literal 406 zcmcIfI}U@wQRM{soX9PVC68N1ny>?9H+&R=HF33{*Yf%ZWm!*0Y8!Ayjx8Mx z%1>>shZisrf|zRoqD3;LlrYE|lym8j@InE^7z=f0!^^QZ3tl2_sRhq5R28c2<>8_4 Vn&0*2t=B#rzxKbp{i6N5$0s$T#A literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tframecomp.png b/mseide-msegui/icons/components/tframecomp.png new file mode 100644 index 0000000000000000000000000000000000000000..b298e37940dbe5cb41089e27da8bd5ada9fecec6 GIT binary patch literal 394 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ zFuwp{#;w&s*+4?q=T-p}mdqNq+Lk(t^YUG@hSyq4LSyV~7MsXh?ExO`hY zr-rBV-qz=Ht|uS*y>ER(|1O@{%Org-Y}4I#KFjm{w*Kz!Eb)SKm9cgvjF)2@{!d-f z%~Ipa+0dTyTOq)qtA+Wy=Os^(yWet|<}GFs_~SZBj5C7O>evcfMi{WGJmq`t;9gYWX+RG#IA^kx~EW5$8l-buN$>qlPS)SdN`g=DM+wI?rFEe@y l|A;l^>lS@7S@8M{dCj_do;OGJa)IH-;OXk;vd$@?2><|Ln%n>Y literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tframecomp.svg b/mseide-msegui/icons/components/tframecomp.svg new file mode 100644 index 0000000..10f893b --- /dev/null +++ b/mseide-msegui/icons/components/tframecomp.svg @@ -0,0 +1,258 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tfunctableedit.png b/mseide-msegui/icons/components/tfunctableedit.png new file mode 100644 index 0000000000000000000000000000000000000000..3d871031f4e44ed7998f259621568df52f56b5f9 GIT binary patch literal 548 zcmV+<0^9wGP)_|HH?z{0@5z|hdpKoi6N|NjrMfPsO5Vf}-r z49pCS3`~rS49tuSP@0i}iID+HGcqtS;Fe=%WPr*;)qZ%3@Bt;@;oUn7r71}aPai&n zi(P#56wapDg6^7XhNRql2H%hnxDSv46D5Wp+qakD^XE?tUcn(a)sXFjKfix7^w!ld zv`?RjR~^|tST%1BgTAR5gQlK7UUg*o;KRGO49jNDU|6zy4?(qL`CvwS8$(2DI)jji zDD^G4ef28C`4h((B2rR`Qcto4eKnN~`3+4BEUc{5w_yL4O$=Pz+zeLEE=21gI+B0= z{K+u0y@jE7@p4k!M7$4{O`F1C>+Z=Qr>snp1w{Ga_48*8+gC1USg`v5Nrp2p5b1*% zEzJyZ`9%!eyu8%6;Od#v43F>KW$=oKB-wC+7X1JJpJ7UU4MSdYD+421DM=LzcCK2% zAfu?npkrc6mf;KxXpx+3Wy0|Ucv mh{%5^rV?QM|NlQtn=JsyiE*(V?eL5M0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tfuncttableedit.png b/mseide-msegui/icons/components/tfuncttableedit.png new file mode 100644 index 0000000000000000000000000000000000000000..d99016b708a7cf0718df8e5a2f1fed116339adca GIT binary patch literal 556 zcmV+{0@MA8P)_|HH?z{0@5z|hdpKoi6N|NjrMfPsO5Vf}-r z49pCS3`~rS49tuSP@0i}iID+HGcqtS;Fe=%WPr*;)qZ%3@Bt;@;oUn7r71}aPai&n zi(P#56wapDg0AW+hUB~g2A|+yxDSv46D5Wp*|VGB%a_j#omfRlzkmJ8FsHkdValqtq_~NAA1s>K&)^ae$RMqtK#~PS`QX`u2Ml{Ru4h=h?=VS* zGcXY8gDDMl3@K$544mBD)VJWw!2=8*-o9aQ4GJOIa0UhfLG<^}ABJg-bqrM#CNnUi zm6F5)ygt~lU><{}p)rHHz5!W=Gccg}AVODz0ok2$Dk=;u^B0kAIEDo)F5kdfWm0Ux ug9i^77#My-ME*lDl>p=a|Nm*)YykkQi*hHqxPKG?0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tgdbmi.bmp b/mseide-msegui/icons/components/tgdbmi.bmp new file mode 100755 index 0000000000000000000000000000000000000000..3c90773557faf480231a3505d853f895a9761634 GIT binary patch literal 406 zcmchS!4ZHU3zYWEy({2lbfOoc=Tv)l*(=(-r6)Y4Sb&bI`h2C Jz%lcKzg##(^@{)i literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tgdiprinter.bmp b/mseide-msegui/icons/components/tgdiprinter.bmp new file mode 100644 index 0000000000000000000000000000000000000000..d623004b9eaf9f303edbaaec946163a7678c36f5 GIT binary patch literal 1782 zcmcJMJ1<0G5QblkLZVlzG+NihhC<_3OI#Ag{)J5>PJvbwL?j~FMDH(9NR)m7jgD5< zqF8Tc%sA|KIf9cpUnVp2J@d|dGYhR=$Tz}si2uOH-y!Iz@4lLE|`Dz%!vopMW*2??gUFWjU&fnCHXoi>2k0;dwt9 zv<(vzUh=m%RYepjsuHAvq^cZ81y#v(RZ)L6no1(A+e&&`z#1?KOal#D@*prJ@wP>3 zKtI4UHpLcjWZBWL&MB~C5nlIf5H$|G0uR!QsGsZg-3 zw9q!CaD8AG+frDGzvSe6Ip24_-}!ytmqRF}5Jj=QySw`)!!TQYeSK~9_4PmDF$6)7 z0DxuL4YS$YVKf?tQhk(Cf_=b~{L4upT2QdAb5F*9>B@I5>_&ZEZDT z@r|?|x^qpoT)B0naNDiA3O@`Yjp?{CO+&?h~7A zwF=BLm8b0*-5Yg9MLLv~l^_y{qUPjLtgM8fP%sEb)=_RK#%h^0B{N|IKEN?o6VL=h(sb0$XcRY@dfi40DwpY z$5E5!^Lo8^-EQ}X4Gj&se-)WnCfn=Er|IWTr}M9_uCCes{{B~i|Dj;(>eX$dxq0Wz z$~;qW+sA9fK0gF$|NejdSK5L&Gk1qB7*I1UW6Ei|&mPwM7&v6_S3Psu^Wt%F7VK}?p?sU0a4*`5l vDNXLgXMPoeAm{ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + GDI + + + + + + + + + + Poi Li + Poi oL + + + Poi + + + + diff --git a/mseide-msegui/icons/components/tgroupbox.bmp b/mseide-msegui/icons/components/tgroupbox.bmp new file mode 100755 index 0000000000000000000000000000000000000000..31f2b0ebe0a0bdcb1fbb490a38daebb9492a4d88 GIT binary patch literal 406 zcmZ?royN!j24z4}1BfM{n2~`6EUo~R2Xjz}1_lNoVrXc9P(TvM1mXsU0|yQOCH{jE z!~g#v77zm=NC-&WMFRJM0#NYxIzoI1u^BG#@`4@y_j)bEg}c1h%YmTw?p@vsci}#T KC_s1*KMMeFwFu$> literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tgroupbox.png b/mseide-msegui/icons/components/tgroupbox.png new file mode 100644 index 0000000000000000000000000000000000000000..c1ec68e30f483709a462d30eb23bf5812608552a GIT binary patch literal 354 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ zFuwp{#;w&s*+4q<<&qGPm_2)futZ6djN|i&>z3|Sr8^y89dtL45EWzG zDd5qn)~n=GFtPMumOKy7={I#gTN^t*NGG3B-oVPI^r^IPpWsAWbCn;=dzkVM7=PfC zX%zjyQp3!z^ywkfnbVuDY`o7n|A3H1f4^RXxB|Y}Rg u@|V(&82Kv>Fw1>75ZmAo``_XCABG#DMVG?vS3d!ImBG{1&t;ucLK6V;=!q}@ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tgroupbox.svg b/mseide-msegui/icons/components/tgroupbox.svg new file mode 100644 index 0000000..d2e5e0c --- /dev/null +++ b/mseide-msegui/icons/components/tgroupbox.svg @@ -0,0 +1,315 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + Ruio + + + diff --git a/mseide-msegui/icons/components/tguiprocess.png b/mseide-msegui/icons/components/tguiprocess.png new file mode 100644 index 0000000000000000000000000000000000000000..8456c4af839c3861f30425c27b39924a03eef662 GIT binary patch literal 1013 zcmVU(fe>o_Uw^$2@^swP|A=9opA*bxo?G z=&GXVg_}3`gsxrFLf5Zr`-+P@6Zl6pH7%2YfHpZes5x!65mi-nRaNz#j*c&2 z1A)(FA)-=aUEL46w{3e@5&}t=I4`*BLA+b$sv+db-^fs6ZQ3OW$?_IuYgbPjE{4FejZ5(Qd3fR z&T2*aA4HVI=6GWx*%k{=TP*w;3^F}C%P*%-V=|lnGx=-VxBKOnoldvSYTerE^YOmh zjeF-#-YhDjdtiX5t^+U@4%6A)jXgJ)#l=NhFI}R4XozR6R?KEIk|YrdhdF!xJi$;1 zr`?W_W!x^;PvX5(r>a-$KmvR>ZcwXfOioP^i^bUQ^%4q)iO1uVc|6R_&Jw(Pm%Y{1 zq^?~{PawddW5*t~2;lqXW-`~UV|-$Q2eBA?cI=?3wUu{VF1(eMboKX>o|3``RaHnr z@K-2AYkND>Gc%Nzl~L|;Aqm0H=gtA}R#nv-$_qBzFpv*WTu{I!yPfr!nPg{XK8y-L zmSq5@?%m^=oSfx`)@NrEjzn0{bsRR^GG0|t0YK-~t6Rly4Gq604(uB?@RGwpRz}8S zEz5U0>AiWASUe8E?|wh|d3n5;mq+iw0048*D97vTA8*mWRj$=ad1)!T4;&yVDT(Jd zZlt8Bh$W!S=VPD8!~MBAK0J63fX|K`X_hLAi!XlR^_DzIn#Pxwh{fYPm7KgHO&4^X zB$EkQRUf{Uq)$c5<;$->$u9sDS;lNKJ%XD|CWKg-pN6LCrhPN&pPD=uTf>gD5?G*lmFiK$f_U&YZ5Ye+IPkuXk;es~W)~1=( ztcj|MqFd6_CxSko7QAvr`{wA;m5*y{Tc(DGwdq^8 jG^gD@qN=Jc3laSX>FP9~n}d{m00000NkvXXu0mjfbM4ry literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tguiprocess.svg b/mseide-msegui/icons/components/tguiprocess.svg new file mode 100644 index 0000000..897ffa6 --- /dev/null +++ b/mseide-msegui/icons/components/tguiprocess.svg @@ -0,0 +1,228 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Proc + + diff --git a/mseide-msegui/icons/components/tguirttistat.png b/mseide-msegui/icons/components/tguirttistat.png new file mode 100644 index 0000000000000000000000000000000000000000..288341743556b9334e53193c021bbd62396a9e51 GIT binary patch literal 1259 zcmV)Ylv`{XWYg?LtGV^Eg=4yD=1W)IRMh2sLsDX}G8I`%sAWi-JrA6q89Rmq0E4R5 z=kxK=XO%dem+T4XejL+*1OK`Byo`(*EyiYB_;h@H z%DUoWzOVj+)4w&4l&BbO>jBz>MWz*S`s ztE{B4sR@tQ3&1b6wRXK^<;w4XRDhDIu|fXs@+c(=#pvj_*j2cQ^DRG+yKEU}?)>w* z^aAO?`p!;XPe`C}#0dO;f4Kjii}rzI@}O1&PzSsQEvAW$v02bgUU@9Ph zc;MWQ9aNajOc*~NfSsE*?UhS6Zk&04kx9T9ibv?|Zl`kRPKtd#MgsZ37W!{QW7a89}be`q)-%^Mv~2Te~SLk zRAeNC3jd%eLgV9-li!uga&pRt0x}fqak(sVc}`B_qXIDK`oPeBkRjTQ3m4Xl31h}w zI<;j>{G<4jg{Bqi9k*`91e6Ltt4@~-G!3a~46|AR81VaXyWI#WF`7)6&1L}l`uph{ z7(hsg*pqyBP=sID7tlv<`ID)YtExk&@C0keZ)g;12|JYgANseM!kifP+Vm zjxX4{H6I`)DXFev`}Q(`cM1w-9XoYu7QlP?`Cos!e0c-F^tp2vU%h@k)*lGG@;CjO Voniz*Xt4kQ002ovPDHLkV1jQ6QX>EW literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tguirttistat.svg b/mseide-msegui/icons/components/tguirttistat.svg new file mode 100644 index 0000000..a7b7b90 --- /dev/null +++ b/mseide-msegui/icons/components/tguirttistat.svg @@ -0,0 +1,329 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + *.sta + + diff --git a/mseide-msegui/icons/components/tguithreadcomp.bmp b/mseide-msegui/icons/components/tguithreadcomp.bmp new file mode 100644 index 0000000000000000000000000000000000000000..ccfd2933ce2ce31f35208a8ce9a8c3132ac928a3 GIT binary patch literal 406 zcmaKmF$w}P5JhJ}u#kXYV`=F*?7fSXsTOkz&y&t(1L({L@@H7~ zbiNN_x}qN8{o+AZmLD+RZQNTVv@40=N=n{PfpC(XGX~ABv_^t)7@_DNiPlhkUNwZ; zxpsakBIcti*>duz!W^A!GLD6sF3i`?ksKe?^vk|;r32u?tqT%Z@mGu0`|KA literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tguithreadcomp.png b/mseide-msegui/icons/components/tguithreadcomp.png new file mode 100644 index 0000000000000000000000000000000000000000..b92b2a0545a41d30678c8cb678fdd5c25f9ce219 GIT binary patch literal 616 zcmV-u0+;=XP)CBd2;E%j zcQzK602B#u-)Ph)h=iIBg-1TxvXqxAcrS{TXYR#bE^1;{W)RVHq(?g)#?8QAUEnzRw_11)rq2)j&1iY0vMe@i2J~8N~JH-G*>SI5aYfg zX_~7D@fxLe(6lGc=H`#{0>-`r$FdrP;S#WgQd`nApUHALe;&Zt1Schzm#?GLD_{ww z9y^xR_#=QUd{k)q11DOkjRc)ho1A&OM$UNW#P`I>=hGF<-30WioVAQmfK#=-2avNH z1~WIR!@IvL4Ja&t&sZ!vKmt%KS1B$U6c$qBQhPACG>?W3LahPF zYuhT*=S;|5W+3vw*YOFGz@ytaq~AXp9?UmY_ zecIvA8o-sib&=(rrdvzSNRV2z=+h(B>$d!SPG2mVbw71uga)6V8lB_Ao#UgnQM~hJ z{Gug+N7C}wCmjx;-Fo4-gYWATCHUL=_kWpF2mAsfxDg*iUJ~E{0000 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tguithreadcomp.svg b/mseide-msegui/icons/components/tguithreadcomp.svg new file mode 100644 index 0000000..f72e64f --- /dev/null +++ b/mseide-msegui/icons/components/tguithreadcomp.svg @@ -0,0 +1,491 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/thelpcontroller.png b/mseide-msegui/icons/components/thelpcontroller.png new file mode 100644 index 0000000000000000000000000000000000000000..97801b9c479fa338f89a15ba60cf4593e2366731 GIT binary patch literal 994 zcmV<810DQ{P)*md~6Lz~c+0mhWRbGBkN~udJ z^^BC1d+wVzHTSJsT0wU9FRGNfDy3d-v0VLYU_hH29Ms~XqsRUHjZ2pr<{v)PriO>> z07Ln{qT)iP*=$jy1R+qQL|J|YzvJhF$N!D_=PZw3j*j+;%)NVO2otuOOl}db#Q}zU zdYVOCVWBmgB4W|wi3r!?_2gv7Q-b_SzVnkMw*+y1@P*6NWyAdFqS-?=ZXXl zIn!q2cegtbaL>(=UR=E9wnfZBgj~xTx`t95F zIUF>!v^;aAuJ8rGJ85YEyq%hgR$mXmPhDMRwd2egyIsmFe0;`ozEEfKL@`RM6BwjO_{FSvvky7fe)>gTma$R7xQfaf1yl2mfa*Yr* zFQl4&R#rw-(7yYTn4VrJj$~zZuUFu$gajftZ3^Khr>0&Nr%Fot*DJ6V!g}F2dVA|d zUPVRdKlg%Q+O};;42_S+hD%^-dU_*(@ncO*!$f<#Het7G{&r>SmMyc>*RE-Qba!jt zoH+4s8)G)#`}58nZMLsZJDi&vXk$J-di3g}krD0D=%}_kHg;Tz>% literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/thelpcontroller.svg b/mseide-msegui/icons/components/thelpcontroller.svg new file mode 100644 index 0000000..852af5a --- /dev/null +++ b/mseide-msegui/icons/components/thelpcontroller.svg @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + Help + + diff --git a/mseide-msegui/icons/components/thexstringedit.bmp b/mseide-msegui/icons/components/thexstringedit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..54b094536d0d5b7d6ce296cf312d185f9c071d7d GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDj7vhFsutFg5pW*)~qF)I7rvMx=L%0wUk2ydE5CHNw%%`{*c+7!>5JV#`?Qkn- zZ4SgDxHHhWKykPfgn`RF5Kj>#A%*}+3eACAgv%VD6{G@?nW*U*m^H`)$mWc)he`+l E0Q#_cp8x;= literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/thexstringedit.png b/mseide-msegui/icons/components/thexstringedit.png new file mode 100644 index 0000000000000000000000000000000000000000..d1610503ca1fb605219cfacb21763f413e528a9c GIT binary patch literal 513 zcmV+c0{;DpP)4+xK(FN>LPPx7#V5PD_$br;`qc!&3$yp2+h&DwPU_LV?w4MHEHYwvBDu zgkcDPX__PwiKnu#?u#G@m`o;^rU^hMlfiKu_WM1T%LT`Ao)W$1p@Y$AM8Drh5@8rJ zoldD%t9YJ==Xum>wND#7bTA%|84LyhIF3UynWWur)9G{o==FM^Huw + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/thistoryedit.bmp b/mseide-msegui/icons/components/thistoryedit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..9e8b20095ac2820707701d854e532467fdc3b478 GIT binary patch literal 406 zcmZ`#yAHxI47^GVl^Bee7#aBvc7BJh-jXlid-6%%n$4V(ly>2ob57@1)aUCnq2bN= zAa8>cPR+kFe?50z=ma|y;DKtt7%53bDTN7d2kxOreqk}>1K6@*Rwf&kW!E|FS`RvW za}l_?uU)&C=iIf?k2wYri5l-dJ7m<*9W|We)cOc@Z`)Q#fmYT*w1hLaj5PSl)Q!wvgV;4)o zfLK`Ar?3!2?ZnOpNYGwH2>x{z28_%tu37T;U4^R$hV1U_&e=Vgon?|F5xxmYlE{Lh zC3Y3lFc`cfP*v6Obr8&EGsvhx;Hv~d;BUHp z1B@~Jyq@+xG))6z%>N#I0#^R}-UG&%W3s*P_SsRZ)p%P~Rc;o7ev90=-EP17#^W&n za7p~Y3zxf)+1tb6kdnzH34%bqUXO@~n$0EwAW;;Fh-kCfkZGEvsw!XSAaI+VAR3L* z@pvR%*Qr=6`fkLI=QBV-*HL)et$QYufhdZo*Xy2YYvDJU-je8gz0!0#rADJc*=*J` z&yr=mUh}?3qJI%YA`#l{cBJb%#bPms@9}u>zG<2c-& + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/thread.bmp b/mseide-msegui/icons/components/thread.bmp new file mode 100644 index 0000000000000000000000000000000000000000..ba644d81bad07de488fc307e91e60c43a5820e1a GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDj7vhFsutFg5U=$D+0?m!h#3@9m!m0(UAVLo| z7FI1lL9F7~3;>DYQjbfVJad4iF&rrd>cv9>r9jFU7=R?EEpRD3CP2)Gm;+Rg%N&Rl z)H;Zz*hu=DLrnPm|NkGCzaUan2_MYx#}t8Bgg=}yb)kts3;_z_F$YZxCKql9L<(2< iU}{7bK{Es>h1DEnEtqUfLon446d7iQ5cDrC6aWCs1Xu(B literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/ticon.png b/mseide-msegui/icons/components/ticon.png new file mode 100644 index 0000000000000000000000000000000000000000..6566d83283bb30b888e1ffd8c1e4c537bcee9482 GIT binary patch literal 489 zcmVh^(o`}1l`o& z`Wl26CV@Mg8Q}-z)2noDtVM4gEJb&YyG$Pjg3NVTI f`(MQj@DBi=k?U5RJqO?=00000NkvXXu0mjfV#3By literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/ticon.svg b/mseide-msegui/icons/components/ticon.svg new file mode 100644 index 0000000..dcc4099 --- /dev/null +++ b/mseide-msegui/icons/components/ticon.svg @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tifiactionendpoint.png b/mseide-msegui/icons/components/tifiactionendpoint.png new file mode 100644 index 0000000000000000000000000000000000000000..53c61bd0b00b2925ca0022b5422aaf9ff42297d5 GIT binary patch literal 857 zcmV-f1E&0mP)2}?4IyYxSDHmg51Qj5!ir2oN|QE4 z^fJOCB!rM)N+?L$v@k-X+EgNhJt(5kG$JZ1GYq>15vGV@Sn8Nl49z&7-+V1*DyeZk zOFM9P=lmasd(XMHv*raa|1lf@S#22!e_JRb2M@uFb8xXusc+G89=Tq4?f88!yjcq4JOR*}&!mr(M(RAx+atgTcZys1%VlrIh)5zLkRoW6yoa`xGDF z@}anRxbE=bfYUJajnL2zBjaJkbfA>_>A)pYz>*~gaJw^n_4OT>Z{7N=8Aknmr~!I` z&|ecofTyEr<>vP7tI5nv87wPnz1H1bR}D?Td*CBrL~D;FflDNX#KcO|?Orj`+B(!x zQu1VLFj&(8T@i4ap?1 z)oN4fc~eWvwywvIUpftA?kgzsL*~DLMDv~-S1OQ5@ z(L!iUhAqud@dZ-j;O0^hw;?iZ(gYEbkWwnJ0WKE6rgnJbhuzEJ-eQrplP35PCd4NYRuKkd$=hBxp)0qXdj(nAZc<3Ghlp;$oFrkBXd}b>!vko!!`Y zeVNEC2W%ODJ!#-4eDujVShMCN+1ZYbx_(3lhYj}455EZy;Iq2Av1d_n@m>lGv+(&? zv~uP8(Li8U(BoMJG{-^BMBc@?4qW;9PI7aPF*3sFg9rZpXV2Q-csyOVp=UF^1>$3E zGHVASS-RJI=W12el~bLa9i89 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tifiactionlinkcomp.png b/mseide-msegui/icons/components/tifiactionlinkcomp.png new file mode 100644 index 0000000000000000000000000000000000000000..54fa488e2c0fb1a0e11c165152f1137078d800a0 GIT binary patch literal 894 zcmV-^1A+XBP)06jh}|)(+f!i?ebQMGac{TCw7g|W zFMWR)VJ|{KN$5?uLDE|gVnV&tjUcQWffUmh5tf=2imieOQ$z`-)Dg$-(2O3>ock~n zMIC1>Yr%e6=lp-`zu0TG)ss&710vOaxLT{);FPa3 z9tYi{kwxTp;4aYNls8054`gKI_QEX@S(VU%gZMANO<)pG6EpHDQo!SKyWOr($Tb2s z;1iKqsv7uG%h7?V4g!0C0iXcz0^V1!GL)WPKX~|X|3GEsfB$4=wxz%apgjKVS21df zRP{En9ayWX5gWG7n?L_l+Ue7)Ex$j|Sz6jy{O;Y$2pk120#PR&#}<7CsWU{HSh}>@ z-nQ)zva@IQRaCTI>FT<92%3P`z+1plRr{L(hR94ZGOF#evc*HKt^MsKB@Z_b57)Fq zXIwn2s*aT>1sEdhF^n?1uy9tes;cYEn>RQ9hSs=nZ=$Lb0t^v19?vm**RFiaG^4M| z%kSrzW^E625vx3stmQQTp_G)gSs&6UIe%1h^!np;A7a3eg_5w{yGag{P2DP zoS!37{6hdtpML5%Oi)#;1gse_ts5?Sp+!Ve6aAWSk^zjoyj5)2us5^5{@;ZnlRdDh z7xv7BFtKHh&%ufn$H~q0tTW9cCU{)1@7LH&1b|Sot(*8PI(Tp|MMXJ;Ld;&aZ1qSa zGI=-<_zifH3N>Syi%}gI1qBny&p*o05F_{Qg?kzs+g=0$owd-t5ncl6BH~I07~O$L zju{MIzkK1sr4t<;?Hv#zcBupyV|x+;Tt44ze7+`NN?dr5PnU{4)?>r + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tifibooleanendpoint.png b/mseide-msegui/icons/components/tifibooleanendpoint.png new file mode 100644 index 0000000000000000000000000000000000000000..9b3fc2e6a65b3c0f6628b3695c84fd5c2ee89f6b GIT binary patch literal 473 zcmV;~0Ve*5P)P2F@b^wr>G-ySbw?C+-FOVx4djkUu;x>xcDX+2x{lLNtm|0)1O5OY17xd(T9SY7Aj*CM($Ho*>MxB# P00000NkvXXu0mjfE_A+i literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tifibooleanendpoint.svg b/mseide-msegui/icons/components/tifibooleanendpoint.svg new file mode 100644 index 0000000..23091a9 --- /dev/null +++ b/mseide-msegui/icons/components/tifibooleanendpoint.svg @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + T/F + + diff --git a/mseide-msegui/icons/components/tifibooleanlinkcomp.png b/mseide-msegui/icons/components/tifibooleanlinkcomp.png new file mode 100644 index 0000000000000000000000000000000000000000..df83265ba80c3237167b37bd9164e0879c917971 GIT binary patch literal 518 zcmV+h0{Q)kP)a!pR$%)Qm;tVV55UXBHyeB=W66^h1jweOX<*#; z_n42Qp^$thl_v=ZkQUG?&{vD%qX0>LKqKONX!}4?4HyE>fWZ!*J=-UR0H6lE592Aa zPPzhq0tdi5pb~uQz)0*k;f@WuA$$RZ0XNSdSy@WS?K zb_W@d^eV_Vwhy}k00NwwPXMD~d<-mf3m7LmlRI0xZ;O&oMZy}u?=k@o21t5Nw$JS{ zfcq}maBg}7%;mJDt^pmeHd&vSva)AT+MWRa0iX)m-~X`yw=SN3s$nM+U;qFB07*qo IM6N<$f~2L + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + T/F + + diff --git a/mseide-msegui/icons/components/tifidatetimeendpoint.png b/mseide-msegui/icons/components/tifidatetimeendpoint.png new file mode 100644 index 0000000000000000000000000000000000000000..2f18dcb49dab32b176e07dca34dc798e3cf15933 GIT binary patch literal 419 zcmV;U0bKrxP)m@!zhpT?E?}{Q?RWFyr49oM+B|o_kK1!d7GZQ!mv8 zUzz58>Tlp?h&oL~@pS*AQdUb-T7QN>f1A*NE~n#3FCvYL~hAf|CF;VfqA2C$Q2 z$^w)zga#h)(N-^FtiyY+cuoPVVFdS>z$rFc>U~%U_lvm13ocRtaD@Hfsp1;vn!A6D z_23)TJg%EgP4cz~YB<15fK7!2NlG2^I|c%*lG>cK1Td`aY*Uqzpp0eA{{#?Auz_0~ zVikAcgC70D3@SRGbxm`9>n+cwV}R5dw5pzO=??HM{R930pwR2zmM^0{ICl}ClH>pY N002ovPDHLkV1j%MsZ0O> literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tifidatetimeendpoint.svg b/mseide-msegui/icons/components/tifidatetimeendpoint.svg new file mode 100644 index 0000000..f8b9bb0 --- /dev/null +++ b/mseide-msegui/icons/components/tifidatetimeendpoint.svg @@ -0,0 +1,219 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + D:T + + + + diff --git a/mseide-msegui/icons/components/tifidatetimelinkcomp.png b/mseide-msegui/icons/components/tifidatetimelinkcomp.png new file mode 100644 index 0000000000000000000000000000000000000000..556e700f3b60416e79018127e083e773077767ae GIT binary patch literal 454 zcmV;%0XhDOP)j|}`+dIO^E}V{)@fQVZ+!So zG%)DLa>{-VqiNdBDak`PMj?fBhCNKi2(6LzcASLgc8D0-u!CN_)^5fsc*iW>Fo&*4 zR5;W1#M2DmJP3^7BNBa>LOv!EYf%LkA!1l-kRLVZMkmU+m$ac8%^0kc_l(CZ21}Bm z6)=n=tXA!}U?#lJ;tEf=%xVA!*b1CHu5l_kl80Ccya8{`n@hnj&G@I wZ9L5&>kO(h($07*qoM6N<$f`aS2TL1t6 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tifidatetimelinkcomp.svg b/mseide-msegui/icons/components/tifidatetimelinkcomp.svg new file mode 100644 index 0000000..bab8357 --- /dev/null +++ b/mseide-msegui/icons/components/tifidatetimelinkcomp.svg @@ -0,0 +1,231 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + D:T + + + + + diff --git a/mseide-msegui/icons/components/tifidialog.png b/mseide-msegui/icons/components/tifidialog.png new file mode 100644 index 0000000000000000000000000000000000000000..4293f3c778484ea0a9942688e3618b0cb52c4b8f GIT binary patch literal 761 zcmV$MHcjVVefuz)u7)Vs zm-2r;oaZ@*=lpp7hjV0=QkA4Y?q>w}U0uq$0yzQvWvu}I7r=10h1ZR}yld`b+&=Ez z{Mh-yZ;|L0mj-AmY2f8;GtX*UC`~`ZKwCeOB+*`P_FHsnSJ9#YieG`Ld=Hv%4d42# z+{wK~ep4Z-rcD6Y21j_`K7b+BNQ6GZ=YZ*{Y1D!0dASR9U=X5PM4|Na&?1ddI7b{v zl0^O4I!1@>Ts~BZ&0^#9jv~bAIeTh~uTy9`!O6XaxF%h6wRUkN{V>G`3&`J>H)qlB zQmR!Td1ARzLH3OtHk-B(x;hkx?K=Q&mz&Wqb}AY!kd%>3S4$^1OKQ0E=n7dyM{$ff zd@cGzGS4Ks++578U`;|SZkHQL@{s$?Z-_DI0WfSZ@}jW~(Ji70)1V8}5xgqce+QlS zJBTz!dGn5k?d&|ho9yZwBuQdMoB<%(py%_zFaSgS7PJvsLbM@F{g}c!WM#rR;oHIa zv~wVVR?9vaVvTdyYyi;Iumd(1dFk8yTazpo&+IJ1D(ZL3C^k1)2G% z1Ob(x@))t0?|RlXi$bPAPzlHhV6f*Caf$1ZBd7OCH|yf#(1vLldTT+e(;_GZ%5%#o ztu0&N4(3TID3K%g=CO%uy>Zgk6z|^C2hB`6Cb15FC2f0#uSLtD{douIZS5gQ9Yn&$ r#N`LbWHOS|Q+&GpM}E^4z(V>7wPf4tjX-Od00000NkvXXu0mjf>@rl6 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tifidialog.svg b/mseide-msegui/icons/components/tifidialog.svg new file mode 100644 index 0000000..9c6acba --- /dev/null +++ b/mseide-msegui/icons/components/tifidialog.svg @@ -0,0 +1,402 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Dialog + + + + diff --git a/mseide-msegui/icons/components/tifidialogendpoint.png b/mseide-msegui/icons/components/tifidialogendpoint.png new file mode 100644 index 0000000000000000000000000000000000000000..c0698be9482fc224c40ec1361adededcba7e8d23 GIT binary patch literal 698 zcmV;r0!96aP)_soqtUb5lt+^OFYWVXT`rd zGw)Ad6cN3d`DVrhIEYD9SQ8O@a2q@D4gr3}=9v(5_TWHf{(zl0oS7BQm5Tc#Vpl}; zcTqF9+c+Y6LAlANu{1MfCfq{ld-gMa8Lm!F)SaT2 zg#g}QZ&C9XJ}(vaVOeHw!Bu>%z13TB6pMNPDXPl552x_3*i*!7@wnJ`wR_T=nd2Cb zh!=FZ2N5xZ-#c8}Fr1nDO7f|q9%E&(zr+(fi-`FVu>uRGE4UsJ4g863JN#q#DI#`j zZ`~5e%%>6YMMNCKp!VVTqo|!MPn#e!zpL4%oki6ks?2;{#s|u}T@kUdC>)Q7&#*_k zZ$C~~P>al*oHl;YVPEbDZO20NV-!1TzeTgeaa_cS%sj;m70eXna$f87{nrZK!T$sw gL=Wx1|HmTu2hei4O@5farvLx|07*qoM6N<$f)Ip08vp + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Dialog + + + + diff --git a/mseide-msegui/icons/components/tifidialoglinkcomp.png b/mseide-msegui/icons/components/tifidialoglinkcomp.png new file mode 100644 index 0000000000000000000000000000000000000000..85489993508a29b662db564820e10b89c6d7258f GIT binary patch literal 701 zcmV;u0z&V7L4_DQdH33xBpGkJL;D@T} zlL?7z#|i8o4Gy>UrBzjn*n!7-+#biSs`_l4v9|^d4gjBG`&s~oYjC)#4qy-7sHy=zZW+%e z*_&i`44d`i)=6eSo8$#NP*ti5zQvTTgC4}^coje44xDLzZ{jpgVFRAg)$4tHI6pYP zJgJMWHUPMWR~nl?a9_)C9X40h3%G!7x~txSx3G!+E*iA=I-JB0O2L6;EN-;>;*gx8+D1(VoRVyRw?}zmBL#7vXAIDjo!S3E~(SMM)aTf1Z)k)UKV6D=Ib8&d@|7LKV j+yc0vOw;}SZx+BmWl72flcyp200000NkvXXu0mjf(p5n% literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tifidialoglinkcomp.svg b/mseide-msegui/icons/components/tifidialoglinkcomp.svg new file mode 100644 index 0000000..967b8d0 --- /dev/null +++ b/mseide-msegui/icons/components/tifidialoglinkcomp.svg @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Dialog + + + + + diff --git a/mseide-msegui/icons/components/tifidropdownendpoint.png b/mseide-msegui/icons/components/tifidropdownendpoint.png new file mode 100644 index 0000000000000000000000000000000000000000..2ca811136d1944a0548243c5a1625673ed7a94da GIT binary patch literal 1202 zcmV;j1Wo&iP)+LAN%J5d|(gAbfdCeke1)Ggf+w3k|n*We)n%Qhi8@8Z9f3)db18u{XIkVUh8XH~ig*Ye> zan8A?KR6dJaQTPL?{>E5*ZV%t^L@|ro}(Ob8Vv3sJOCpH20}nO5S`&wS%gPf%%n3q zd!cRHifNiCih|ecRWwbT;ddNoFsb@JzbDSNJ`f0mgb+J`v-;Kzhu-{t_ihKfv|4%R zC%{pY)Ygxzlf?jEJW}=eSoqFsYLYTg^=?&uZEdZvENc{CWMl-t-=BVzFYz!JFDE5? zepXcFeFap7q(*>`2R=2w+4`80W^&dJrqLyu{9<>6vQ1@U>GI030&itBK{CltO*$!;t7__&y zFFSMQ3|U!O6c!dLGtM9m1;7J9w{6;-t311B+sU$Zu5T$20%}Nr%F4=+&*xjSdGltj zUAyMQ?CNZKfNCkF0#si))wcHe&ZiH#J})p4*KIzq78tIms7UMV>>SU_%eyo&F>%Q> zP2Y?T%FD}d`2GIF$B!R>rLnQ`7hTuax3#q`D=seHqU-wo0II5n%gV~G>$-j#;Of<@ zOS`+feVV4(V`F35^5x5?*(fL|kZy96BTj>HV%@Qe zd$&;cs`vxQlu`oh032Y4loHqGFg4}PuKpu14*Ur`;W$n(5D4_Aq@+0M>FG{gUELrM zI^r}KiRR!aum-pygg7Uqv|P6W{O-y-rIfd0>kPvvI(YEl4coS(0IjX9OJcrx=O9kM z=*n~EKnRfptlPhTf7s{qWmuN=x29=}P1F1rm~#ejcMd)mLR0}oaS7t*-~%DVC%`UX zdwqTVu5dV<>o^X!ZLe->YWmt`BH^GlyK=Lu#}EP+XTD-WDE}v zpGZiNlrk$$?gFx1S(z30Y`osz-#^sV)pfD2ukYbdDAb>wooxW?6H$Z^B6g3Mz&0u6 zh1oH)p{gnyH*UKp(DfTyICeTia&!Qg+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tifidropdownlistlinkcomp.png b/mseide-msegui/icons/components/tifidropdownlistlinkcomp.png new file mode 100644 index 0000000000000000000000000000000000000000..8429b03a9a5c9ed1999a638fa6e50f4076bce0d0 GIT binary patch literal 570 zcmV-A0>%A_P)V?B^4{a$kBVq{0GxKtVKZ@zhd|u{1+xM!mu8JHHNAVCZYZ82c zdl7N6YC&(s=6$%2t#}*}H4HEr5j!(;;kN*p`86U=;{ncP=2S%@M{pM-Wt&4~i86B< zr!ZKP`2h@P=F_SLr6*{C%wVR*AFGRR14OgX{a8i=bD8VHjgG-o=h!Z7A_2EV_zKYHpuo)x2oS@Lnm4-&d0Hz{hcV;d{L_ZGV zLs=1tbhglpetfAEaI-7heB7R_lW~Rf%{53o({@nSFnA;JtSd8a!q1EgeU!G`G zy{4Uth)tQf*nMSFwXbQJRt<807*qo IM6N<$g2yQHNB{r; literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tifidropdownlistlinkcomp.svg b/mseide-msegui/icons/components/tifidropdownlistlinkcomp.svg new file mode 100644 index 0000000..b740ac1 --- /dev/null +++ b/mseide-msegui/icons/components/tifidropdownlistlinkcomp.svg @@ -0,0 +1,224 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + DdLi + + diff --git a/mseide-msegui/icons/components/tifienumendpoint.png b/mseide-msegui/icons/components/tifienumendpoint.png new file mode 100644 index 0000000000000000000000000000000000000000..ce6ef46933a65c72fbdac11b17530af06d007918 GIT binary patch literal 528 zcmV+r0`L8aP)7Wsbk`6sjL@XwQwHl$3@(kLfo_8Oun)ojFp7Xu;eD2M=?^qk| zW{zJ}7$EKpwELMUJ3R=D#hrnbT8gLabS`W%kL|M&7j|7<<`Q-`5>#l)=`EN%U%;V# z-qwh_XF;n)Xul2P{<4e*@CA%J{r5-q>6C@F5AJ;2i6y=wnABi0hMm}n#p{F%J+&4G z!wt$Bat1R%rfvWc2?3)%>rPcQ|6>5q1RMa{p8OS17XZM6sxEqyBGLuCmO~(^s?Q?Q z2VAIXK}4cJL{)Es0AUf4inyq%m%t=210;cNU>cYO)=T+YU<`-?Ye9f!V7VgB0}G}3 zovN;iNDGkl+57plKDoTAP8-%crSS;}Rpc#GJ>!2+g&u*<(pY zJ0g+0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + Enu + + diff --git a/mseide-msegui/icons/components/tifienumlinkcomp.png b/mseide-msegui/icons/components/tifienumlinkcomp.png new file mode 100644 index 0000000000000000000000000000000000000000..f28be41396a809048d312cf8385a50d6aff7546b GIT binary patch literal 544 zcmV+*0^j|KP)opVSO$2iuMc9R%mR6fB5SEh2(L!6guv zF48|xaH&w73I#`3J5+2b)JZTPQ6gq=@U@iU(y4=!kOt9EL>&?#Cf~hA(8-?VyZ1fk zp6A@}-g8s)=L==-(9!@e_J$rMIVBAPW431l{&zsp_C}JwkSUcPgvgR!0xQ5)q`*z! zi=^>TKsu1T2lxs+0oEi%7yv9w>bHH^7QpsjNw0u!z-!y9fkH-rB_NlS93c3MY!`tE z;8~>dL15DMdMF@q2Mv%NU?<}L5L@2@kkkQ;Cd6&qu3VSwS^&@mdA!$m0RSA? ze$y;UdJ3FfPJz7bf0CX9KWtYe^#Pr>f5!l6UA>p5wtrGP@Eni_27oLu1$?aQe}FNd z515Mqx`CO7c?FoRj}L6Wm-G + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + Enu + + diff --git a/mseide-msegui/icons/components/tififormlinkcomp.png b/mseide-msegui/icons/components/tififormlinkcomp.png new file mode 100644 index 0000000000000000000000000000000000000000..ff671e0b141e6d01205423bd838be93c41a2560a GIT binary patch literal 609 zcmV-n0-pVeP)RA)N8&-0$= zob#UZwhUD(Ggi=A;n3@S8|r}(u^&e>^I`*h5EGd>Ru6yH^?YVkBjt$b!9z?oNpKwZ zBI0->LTiKIZMct3coGp!G{D`6*q)hRmL!mwvk}pY2k6htM-39`#t8cA1&4+$%FGFz zz^*2l@5ZUjeA=GTa5!RpMM1H~p^#ib%pC)zU;&SMkM1yRrv+F_M{E zBjO + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Form + + + + + diff --git a/mseide-msegui/icons/components/tifigridlinkcomp.png b/mseide-msegui/icons/components/tifigridlinkcomp.png new file mode 100644 index 0000000000000000000000000000000000000000..228bd2c7d6620db90cbddc21f8be107d9424e93f GIT binary patch literal 1575 zcmV+?2H5$DP)_e|P@udUowP_Eu|?-PpAq+Z(Uxx^`1T z>bNOY%1adyK$QrN;GqE}DS}qCPoSujf(WHlAP8y-kpKxrlp>_&p-5H>gixsv%W`bl zaZJ3%-E7ugueWQ@{+YRRd9b~aTat3G=FYiuzI)F--#2GQXoj|?8M+Z@2;@(vUOuCv z^N({ETYhum+!288eX)sCqu;%tqw|xaFAZIK?cxx?=bwK3!V@oib;3YrB=&`)>Ew+F z!0*O>|I^Oc?)B39CH<432c8mNI{(Bg1E1S_OcX&!N822Ys;zIcZXq^i2HG~Sj)qlJ zgK7Baw-RNe@9}|Dd7?;ZbPZpFA3Q*Tu4{k*KvX-Mj)dV6~b27@#=H&?NlOomda zL{Co-p67A-pO@JcYvHZrU(aga4nOlGw`ue9^VqhHZQCp^E@GM{3kwTey?S*U&UIa+ zl#GpykxV9OiZ)k$MyXJ)1yD+{x zgR@>iRwRLjU=;y^{a=0v9eqRO@8w>4x%}s~Q+}VHM+Xivm7k_ksj%B>=i0SvXqrYm z9%pH3iQ(a4EX%5%^~#kiq*5tv-n>a)UmwY2lBuaFoQi|)(*e-7(h@?TX&SnwqiZ^v zrqR*Sfl`WWHp|@H97?He+-sVKVHmWwwlX<6NhlN|5{a;uF90y~>HY7DV{e@Nd6%!_ zxbHtY`|sP&qWvC@>+-3@f!k?cZ3_zvx= zA9&ACtUX4>tDuyk&ZVx;j=?RtN@zNGUN*llAp=9LK?RU9Mlh&dA6J6HEbc z@-xRDF(Qe`EYMr6S|LDyZQCfNa2$t1p+KQfz;PS^R##UE1OoVcK7hV8 zTZR|k{M%mR8-IWHbw=G@P#Y;b63_E6O_O*$en$;*xg4(RvUBH7lu`^14wB7gA#@94 zY#GW`WHK3C<)V~gt~mFR8aR%Fl#*hxh~qdcFE5kHWVrW>_W|(r=b!q6ZfEUhdSX4D zH6=d-iGHNzVOS=et(~l`tx;1`Lt|qjZEbCY!{Ke0X_}a(S*3D)eVxOH50haD4UK_) z1FviEoV)bMwqtF+>aObo;CUX!V)2et>AHT~OpUEwmFH0|m#I`Lc+x`%K{Ohz0&Uy= z(Be|5M7dlh8jYfqqOGlsY&MI$OQM@P54R2FH_8UIpcO6w>eC z@zen2av9fkNvG3DDJc{RWm$wmA%=&CX=!Ppwzjrf7wL4GuC6Yo#wTx4q)_-Cu+Vx1 z7k9o}{qdb&{v*>nrU`xQZhkTLDyC_&e0_ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + Algfu + Oef + Riiz + Zsxvtz + Oi + Pkghj + 123 + 78 + 00 + 233 + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tifigtidlinkcomp.png b/mseide-msegui/icons/components/tifigtidlinkcomp.png new file mode 100644 index 0000000000000000000000000000000000000000..e8e07e9f7ae3c7d3fa78548324bad476d3dabb82 GIT binary patch literal 1592 zcmV-82FLk{P)`e{<)tJ8Q2uyM8wHJCC(vI}T1%C?%2I zBt;@pg!q736c7rcAf-YeMJ-joAU6^f;bs8p2-B}A%JwWNhcaw<1=o5iTu z@n&P}W*=Vfx}M#g*X4ulO-xD3xth^E=l*r(od20Ka{#2!gd1)N=bx41iQmW<65ksC z&N-n8S7@p`Fg7&xvV1l1iu_Ar^u&X2tD5Snn(BV-sT1ellz&USB`+m<_Vmne+JArf z#k12gnYdhW9-w=bM}e(31XN!CE!SOS5DirCQZY`b;8T{F!f!9b9``hchH`O;vv z`d%6Poiau&0G2#Xbds}N~np3ue06so9-3&!*g3bxOW{TAvv8SJ`l&y4HOg#?h2M~ zQT1)^8~f}!bsJ6_Mq&Vr|MYh|l|VT7@sD2oah;cP&`llJa*>Y2jG8rGVT1eI+$bp6 zYgIhkqb^!kLjZjK>jyDZeZ9zu($9Wbxv=^~zzA@3{}GbQ|G@EFdW~3JWSKX^E?WL0);|>p+`Q0u4<^LXEa4o5C{ThfOtGk zu9Cy|C4KF2rl+TAYilDI3}RUp;c%GcpE*|YpAMm4d{k!^l zO*hEM-VwZjhZfT5-_eg{S=86p)7;!lXJ;oZEiGFvUDwfd9m6nc^*Da~I9ZWLpfGa( z{`2C}b8nB`9@XZXUMiJnXlS5ZE>kQP@0y9Ks^s%|Ow;^CuiT=@_o-AWI8_^8N&)<7Bg0mY0|D8az~8aJXmm8`}Mk9{j5(y(1N? z!pzJJwr_)k;^NBx)d#NY5(zVh?0PCC9z6`PKZ z4!np@C2TV|ILQ3`JlC#WqrJVINF+kBSR@n*(c0R|=;$b2U0sC3VIq+T;cysT*Ew+D z01G!3Zc!wW7@so{Rl(o4zgzolzI5}C%x?RTXmgaalh2{+I=T5QyCZSbvdUtA1~slC z;u@FVnIsyEGB-bqQm<3EQ2^l0)LXw$I`8YAIX&@YpUT#y{g(eQA z4ezd&O?L$xvHn@^oQ q|E|1}cu&5c*s*8FysD`#ApZj@XN2wcK<*j<0000LdfnqYQ3TL>UN!EKI^5 zpe|h&69XoHz%AThHHkWxLG(ceo03J;QHC=d!~L!rS ze^tZ$03P5ZUR2e#McR5i!r^`%eF3~bj zc)DZ&HeeG*&3AGE$Es>8E@Ql9-U58X9IhpKgF85l>zM6858-T8?dxUIbBmJ9Rn>Fs z#7pePdrX=im(KY?pSNhO=_OpLsx4TH<4L|Qh*fn2?~;645+KQ2oU5vJNxpZ{#~KAT v*L1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + 64 + + + + diff --git a/mseide-msegui/icons/components/tifiint64linkcomp.png b/mseide-msegui/icons/components/tifiint64linkcomp.png new file mode 100644 index 0000000000000000000000000000000000000000..a5ae19b3ca20b22ec544369fa07c8390c3f79e11 GIT binary patch literal 552 zcmV+@0@wYCP)qB-Y_kDMVE(@gO3$Waiht0GT-(5hp71bD8<15ab~4<4iYmSW$|V znJpZ{?jGs)Vl*?SN)5$3s32{$d+0ZMt*-?@L=0dL-el(7Z`u%kWag*R`r;8)2K(?B zC-E{OHZRiFVhTrkdGrL}Caz@WI4)plk#-x!c;dUE=R;htj6)ooLvwjVg&Cq^YfAbnfVT55wRvSzjx8cYXa7e>4MQ8 q=KWS*fWN8#fPVncp!54L7vL8w?S{;61~BOW00002liM1 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tifiint64linkcomp.svg b/mseide-msegui/icons/components/tifiint64linkcomp.svg new file mode 100644 index 0000000..ba1cd35 --- /dev/null +++ b/mseide-msegui/icons/components/tifiint64linkcomp.svg @@ -0,0 +1,224 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + 64 + + + + + diff --git a/mseide-msegui/icons/components/tifiintegerendpoint.png b/mseide-msegui/icons/components/tifiintegerendpoint.png new file mode 100644 index 0000000000000000000000000000000000000000..40b77b25f6aac901ce7a87ccb42945c76981bb8b GIT binary patch literal 545 zcmV++0^a?JP);#7Wn4PGp^i;z=kMqCx z&6_ukTR-Ppc2G??xqfWqcLO5gCYCbub*Hy7{<77q5imSp$ts>i#JS9T(P<6@pw1RH zu^15tGxN)~0GU}iK}5{p4$gLl*8{7%OSNH~ zz;tF_!YfSSFcvcNGA?4S&IF%}?#|!j)>&~a5Xc(*8&t{Z#}P~(P!ywMC|ExO|Xr3P^Et1e+^Kj j|A2o0(4_tM-zmT^2~~~L;Oo)300000NkvXXu0mjf&Z_CF literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tifiintegerendpoint.svg b/mseide-msegui/icons/components/tifiintegerendpoint.svg new file mode 100644 index 0000000..663809f --- /dev/null +++ b/mseide-msegui/icons/components/tifiintegerendpoint.svg @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + 123 + + + + diff --git a/mseide-msegui/icons/components/tifiintegerlinkcomp.png b/mseide-msegui/icons/components/tifiintegerlinkcomp.png new file mode 100644 index 0000000000000000000000000000000000000000..dad22a937f8a9aa4fda2be741da3087f78b54bda GIT binary patch literal 593 zcmV-X0^ zmhDBL7bs=8KL_;Neitis!=0g{@47Tezvu@<1+_UA;bKy{Muwl{JC zB%KE4fCb<|h}{D^felF$z(rse_yBwax+P88ewOT2vja)(z%sCvh}8p^s6OvIz$c&# zbO6(~?*g}hkvtRp3hw%VHUQh30dSxaFmHPmSd~-)MuC?{0&G`;>l(78I^Zd=e(2u^BBg_pPTBsQmdw3_EXA7tH9(gB1O5R( f5vqUx;{xmh!eF9hboT+B00000NkvXXu0mjfJ{ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + 123 + + + + + diff --git a/mseide-msegui/icons/components/tifiitemlinkcomp.png b/mseide-msegui/icons/components/tifiitemlinkcomp.png new file mode 100644 index 0000000000000000000000000000000000000000..fd7186ab479ba25b61fc0f130ccdb1c0afe14a6d GIT binary patch literal 483 zcmV<90UZ8`P)eg?qL8LiqYy{XkwBiu4j$oK%0$}m z8U47bFEqjprtt%B5*)n5PZaCP(*)oYvlvMDW(2RWA6HCTq8iS^XoU5o!Ep}q=*=LU z32_3WSV9i(TOm+G0Sg!o--~!1=0kXfcj&Fq7yUK<3;Y8DxmN$S Z+yki}MlZMAOB?_I002ovPDHLkV1j8{zx4nB literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tifiitemlinkcomp.svg b/mseide-msegui/icons/components/tifiitemlinkcomp.svg new file mode 100644 index 0000000..e17917e --- /dev/null +++ b/mseide-msegui/icons/components/tifiitemlinkcomp.svg @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Item + + + + + diff --git a/mseide-msegui/icons/components/tifilinkcomp.png b/mseide-msegui/icons/components/tifilinkcomp.png new file mode 100644 index 0000000000000000000000000000000000000000..998432f9135cb91b794f0d770c1184892f92b311 GIT binary patch literal 928 zcmV;R17G}!P)6jvCAAI{9OSSv}s_4s$vg(@US?#nur;SP(-T6wdx^Q53tGuS24_qn%WYoI) zd~a&Tq%{h?OGW9o-mQrN_kC(fHAG5A>H|!wgv5k@gjwMLCp%A7iY>7P-{~XncMpKT^+YsK6M!#ZS4T4Zw7o-Fqg((8^}Ab9yO|; z4Zw}o4oaFzv0ALG7_)@HqW}PRJMVI&{189y`-SoDWbzm0rHjPRoY&u)@{XD?&4p^| zg~tvb%JZka53$x;L*Vhh470@naJs%_iYPc=So?ngYP998dd`kqRu_K5kGVS{+Iwvk zLJ=%lyO>}g$g!%Ud|$k&MhQL)Zgyu(O#0ZJ$VV;*F(1S*ZhA5!oHj(1ASKO>ePlfL zkqJ0mPHYYvGRv0w%>uxCenoFq)6JGYMCr8R1!e)_9q}(j zm;cr{vjF$++_wVAjTg4=E|YsSkMwE1C6m%8Uu}?0 zTBB^yW@mjJ8Dmx#t*N^x{hD94YDp + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + IfIlnk + + diff --git a/mseide-msegui/icons/components/tifipointerendpoint.png b/mseide-msegui/icons/components/tifipointerendpoint.png new file mode 100644 index 0000000000000000000000000000000000000000..df0e1d3ca5b273e5048a0009e4b549cdc6c88518 GIT binary patch literal 421 zcmV;W0b2fvP)qh%4#ymqGU1HWHXuU zvJk~!wJD1jq&q5`O}eGT#Jv|WFr2HT-uHFybtisx>YVdF{l4e-JkM})YwsIn%~S(` zB}}Hg+Y%=E$XNjg=*DiSCl)dP6OHeO}zDWL;TRdcvOZ@mfLaQ^LGS(c(7R~W}d zy?~Gwu#a1G$~LWLKm|R4vjT=?GkT1DNxfV2si^sH0FwF#`~g6&*}p9xvY9==3KUPF P00000NkvXXu0mjf`uVEH literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tifipointerendpoint.svg b/mseide-msegui/icons/components/tifipointerendpoint.svg new file mode 100644 index 0000000..2ded721 --- /dev/null +++ b/mseide-msegui/icons/components/tifipointerendpoint.svg @@ -0,0 +1,219 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Po + + + + diff --git a/mseide-msegui/icons/components/tifipointerlinkcomp.png b/mseide-msegui/icons/components/tifipointerlinkcomp.png new file mode 100644 index 0000000000000000000000000000000000000000..8c1984a2b3e8c579e40e117d6369b18af61ee110 GIT binary patch literal 460 zcmV;-0Wd^J%`!7!O1gnX}_#piK zFvhSUwB@tNE729cW$#Tm!aOd}FLcfhe#Zn-8KjuOxKOfHp%JQ*mq8Irs7EIjag7PI z;SML5#C|OXw^+u#P@XG%#7!m+$M{rh1`qgIF;)_?XvZJ);#aK(F}`9Q|IjRS+OrL= z(HfaM5DvqlaI8eBwTsFm#b3f8mv@6VU{HANYs({hX-n3HnTA3D0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Po + + + + + diff --git a/mseide-msegui/icons/components/tifirealendpoint.png b/mseide-msegui/icons/components/tifirealendpoint.png new file mode 100644 index 0000000000000000000000000000000000000000..3efbfa30237a51a9c9f03b44593a91409eb0ee91 GIT binary patch literal 547 zcmV+;0^I$HP)sdTEtH;@0B zbLO1JRCl^#1FZ??+T){ZNsfp~%x30XnZI>(zO!i^n}b()5)tRC0-A%eBVuV4kP$qM zh<%y)Whelm#(x@*aILI(Eg&-ob`TLqa5*z)s$%Lo7-*S!r!J-x5D~}lCNsa6_%`Dt z-e%_KK7AJs;B|lAiYbbSvzWt<65md=aTPBk;zXfe!81&tRcvAZ?akvzaneQ_5M@4bi-B;)X zwinuBW_J7Z-^V-bOJ3HyNH~O#g|nCebgP0NZ`>FfQj lYwbVa9{@Dz&Fe-1egcEsi$!Hg + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + 1.00 + + + + diff --git a/mseide-msegui/icons/components/tifireallinkcomp.png b/mseide-msegui/icons/components/tifireallinkcomp.png new file mode 100644 index 0000000000000000000000000000000000000000..d88b13bac321c9e7de45188b9c1c77b787707a1b GIT binary patch literal 598 zcmV-c0;&CpP)fyIwVG}0r4G)*L8AYF72 z=~j!>V3de~9YY7Ae*i-n#Ku6bq@j^Yb2>;25{*HmNUlf>1~uFVS9_nQt)vs*>6_2_ z@jl;k&hxYl&yLhB<7tN@Q$3w!4iV9dW0`rm#C{25nfYX{t=2tWZ?B?9#8Hf5Fe28J zxIM+4h&Y{@4_dyUB>6_%MF;Lx6@rx*jfm};`Dsyr%={b?{YCOKnR&mYkmI<8fw{?H zMO9guIfg#$sc_qi{>*&b%2+vr0y2S#3j4LH_?Cc(*oT*y`K^U*6%OK6W`1naH)AJW zG{?z0fkHophZsVwC}KV!BF^FpW=dXs9=9{|94_Eupjdz8%BO==7=!*wL#OmVu4Eu|F4<jSGJV5wR8H z*oGUp9uYN-_Vg8QL%50c8f#kn8Q(TMJ5sOuo0dS=X6Dz0^ji0LeW^15t&*4Ne+5{| k`49L90PQsPb-4gP0Fz{*96HsJf&c&j07*qoM6N<$g71R|g#Z8m literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tifireallinkcomp.svg b/mseide-msegui/icons/components/tifireallinkcomp.svg new file mode 100644 index 0000000..761ef2d --- /dev/null +++ b/mseide-msegui/icons/components/tifireallinkcomp.svg @@ -0,0 +1,224 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + 1.00 + + + + + diff --git a/mseide-msegui/icons/components/tifisqlresult.png b/mseide-msegui/icons/components/tifisqlresult.png new file mode 100644 index 0000000000000000000000000000000000000000..c2c898ef57f6d441e594885e033174a75515ffe5 GIT binary patch literal 832 zcmV-G1Hb%_^U!qlnwp)gum`oSb?y7j5$aFVMm z`kznlbAFtM_nh~~5wdLgHVM(m<>r*S!X-r980GnUf`+>#x?K}^`Fay^Y&}QnQrLAVj+~8W z?4fa!RP=Q90MJrr;!Rrz{3STumt< zZKIx;)ZHTz2;Ym=Ue!iv{8h}Rw~U|WOHAG#=C2GyL<9>I>k6nWsz7p=@SEj_)ttVds-=D#!s+sC2R`gE-Q&4~JhK6B+1r6{@C@gg`4&o9>A*uh zmvP^0M3!ZTWBSWI`0YR1c43oKzD5Xh$`=cZobrFSgFiL@zu+6iRqNu_?LE2x0000< KMNUMnLSTYz!G8Pz literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tifisqlresult.svg b/mseide-msegui/icons/components/tifisqlresult.svg new file mode 100644 index 0000000..dae8e87 --- /dev/null +++ b/mseide-msegui/icons/components/tifisqlresult.svg @@ -0,0 +1,398 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tifistringendpoint.png b/mseide-msegui/icons/components/tifistringendpoint.png new file mode 100644 index 0000000000000000000000000000000000000000..be47f22cf99cb1c9f4a883f8e4e65e637fb7b5ac GIT binary patch literal 620 zcmV-y0+aoTP)&bn z=lz}Yob#T-SarO@8mb7e|7GWv)hw2D9(Zc|NmhPpcezr`X|OSeQ3mcvI&S-ZRzY0= zupIjufm@Px*#5jCfbF^`kkkd-0FGug&jl<)dx1XN&;L~LR{+~r@@jqqNZJK7*?twp zI)H6J75E6ew*4c@7l967JMh@{LYiyHfKC9{Bo(6AW#AOh3!DX}C2bAOTY+g{80Z9E zNb1Q1NNNYZ0dv5C8t|y?A=`bxEU+)cZvq!>AG3W1=mAC~HD+1V58MVmgdIPMa_y29 zfmUE=*y$#q&Gx;t$oAWGb5oRmoj_7ku;4E60N5j`6afwcr-4DB05k(7;0tvWThtvE zJp*P)252D4U$A||b~kVpI0wuFEs{3GO(hLW+FT1b3G~~RZ2<>?fz-t06zhNm!y{IBF^Oi0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + ABC + + + + diff --git a/mseide-msegui/icons/components/tifistringlinkcomp.png b/mseide-msegui/icons/components/tifistringlinkcomp.png new file mode 100644 index 0000000000000000000000000000000000000000..99386323f4190537c3ac575838f66275ab77fce6 GIT binary patch literal 662 zcmV;H0%`q;P)!)8RV$; zaIby#T6^ttPGO`vT452R2(a^M>#D2*N!x)o+b1*dVPMMkgCsV&b-Gf_W0$lG7y}MU zTAESz2pE^tYx_>>1R2d&0@r~Rz^yzXKs_)fX}#@_3nH-nNm6HMK4ANHhLAnLWuPb7 z9H1^wmhCBEFR(eMYzxq7dm;_Y-9aEJ1LYk2T;BO#2qbL;8f-s{KoxioJh%Nl zh8KYrU>z`Fdp5$-EV>9>kyMD~&H_h(F5oy&mb5xFZweC*0|&r`GXOsshq&~5t*gdK#N zAmCn9X#0hvH^9D-x+>{gu;(q%8}dWIB}p^D9PokK{s1V9R7Wd$zv)6lQXSA3e*?e$ wP5&fQ?zH2?qr literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tifistringlinkcomp.svg b/mseide-msegui/icons/components/tifistringlinkcomp.svg new file mode 100644 index 0000000..a995169 --- /dev/null +++ b/mseide-msegui/icons/components/tifistringlinkcomp.svg @@ -0,0 +1,208 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + ABC + + diff --git a/mseide-msegui/icons/components/tifitreeitemlinkcomp.png b/mseide-msegui/icons/components/tifitreeitemlinkcomp.png new file mode 100644 index 0000000000000000000000000000000000000000..90192e212e6d4bc1b0ffd5d0fd557ccccda59e2c GIT binary patch literal 504 zcmV!$*wc@3tkql0Dp3tv!O}3B620a4wTv3u46tHJJICd@rV0UvRMNtE#!9hgEz)Xt~S=#p!AhS8AF z5)QBs$mek>By+1(fuAU%UDUP}e8O!}?{DB8?k5BDbP*hf?={@SbZovS=D%%KpoSfM z!4q7^H&GK5aitz#-V)XDHCP!X(H*?Rd(m@pH5rg~f_t&?aBTb(mvI>UCDEJp8z;>O uWZ^L3|4Q4~Y>Ar2e}R8Mpm5&5Eq?(^B}(;A?2*a<0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Tree + + + + + diff --git a/mseide-msegui/icons/components/timage.bmp b/mseide-msegui/icons/components/timage.bmp new file mode 100755 index 0000000000000000000000000000000000000000..bbb38dfa4db88b46bfb88b8244e61e55a59cc859 GIT binary patch literal 406 zcmZ?royN!j24z4}1BfM{n2~`6EUo~R2Xjz}1_lNoVrXc9P(TvM1mXsU0|yQOCH{jE z!~g#v77zm=NC-&W#RY)spy2M^nln&v0Ew-DU@IZmhY;*TN+5RKI}lJpVn0G+zk7sG q15^c957Yu-?*?ms05a$G?tLH*2Kyb78n9}p8tm+HIKbs|6mbA-2k&VB literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/timage.png b/mseide-msegui/icons/components/timage.png new file mode 100644 index 0000000000000000000000000000000000000000..679850cd4e91f4f20a4147780164a0ad577916da GIT binary patch literal 809 zcmV+^1J?YBP)ogoqx9AQgq}${wr!gD`Z_ zN`h9kk6c91!bKD;?6jCbksEb!H@Ic z-0$c6JLlZX6$1kUnr#dVAb;V`wus-l2*$Q3r@{ho%*{Xeulu?R;F=4ZXdR@pWr$LA zgb&4=%q;b68JYmB+Qg~0K|0%>VrBbrRe?)xA4^deOHunjdfuRdj^-h(Y(K&|mrR7y zbnF`8!@~Xl0Hi7?$478gVR@|NEWSQgw`TKzR0T7?Z*to1gK!!pXHjyAS-*En7oi47 zxtoi6cvtM=U}l7}I!3|o#WZuQtKZ;sBN+g0<7*nz&KEz~bJJjb@f9&u9A~ufc>eA8 zQ5767?Os*EM$XoX$)969`~JY6Fkc$dRjuTc`7OU_)tFwG;K}SgIi7i;p+0j*D3Bu=E-K&fJGOkMsldGz&OLgCa2$CZ8> zaP_vLX}=)nK$8PG2Xb!Gw@uB0CneHjFF>@e+#OnZ-x2XZdHrGzVljx7bS>tP4DSfzW0~#cvk^7_t(BT=F z8qSKjor^007Jw`!w>%K=#{t6y;ec`>av*ddh#>F;u_wS2n4W>_Y3y=U>a1zJ8FIt( n*A{ioZzf1Ih1Pmoe_Q?nfsr-jjFOo)00000NkvXXu0mjfCTVhw literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/timage.svg b/mseide-msegui/icons/components/timage.svg new file mode 100644 index 0000000..39ae161 --- /dev/null +++ b/mseide-msegui/icons/components/timage.svg @@ -0,0 +1,264 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/timagelist.bmp b/mseide-msegui/icons/components/timagelist.bmp new file mode 100755 index 0000000000000000000000000000000000000000..a063f1e0540802dbb5d754e9d547c40db1deef02 GIT binary patch literal 406 zcmZ9HF%H8Z3`HHOhv_7%00>v27*mcvs3n8$igp>!p(KF?oUR7~mN4@S{ zY`l8s$o#7Z$5cdK*copFm+e=Ft9vkFyy!T~>}Pq(<-ja&R*$mU3p3ld#Q(>06LTI+ QIko!C_)B{S)8O9t0&*1LL;wH) literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/timagelist.png b/mseide-msegui/icons/components/timagelist.png new file mode 100644 index 0000000000000000000000000000000000000000..88bf1053077d1c5fa760456bd3366608c23f29cd GIT binary patch literal 886 zcmV-+1Bv{JP)k^R96(nf9JmY-b^yu#E4b#57MfLRsvlKLaAb; zAhZh|lxnfyMsybxaig&rLm=yfF!XRr;d}%Oy0e> zi}&W`&AcIukPi-*_h-J}cg}eurBaEsMn}gQ;Cz-yI&()vR`0ursO+Ooa*I5hzJ0+Y zE~8^(4P2Cb`p(F!#q6NDo^zmK}>veL$%|9*JFxKLD+I&0nlGnpi@ z;S{ssW&%yu)dW~)xHoWfBa+&|UoX$FBKQF2A7RZ?oSk8+emqIkogA0O-*2XK`_xfNe9YTD1wog& zU(}!S*`uQjxwjKzjI?&3nxk0kL+_xQkFWF1%rMpd3PZ#IfRGfxO98snc)7%vlc)JD ze;+&GpcW-=Cdak`Jg>V3LOahVf1Ki0{s!}_=WsQN%-fP<7e*w3UI4T!4K&Vhvh*Pj zwvIs~Wo%N(P3!NqwaD3Pj-J4=EPz4|3IXIi$4u2QQ?=1KYk6L2@MN$ITiT3GHhBU7 zoL(gaJwiSQy?I!kgV*u`FCC`hs8@v93U~z%{pVNc{zHV@#&Kb697-m6Qz~j5jLn|D z*P--U!k<1x9uK6tXiY8%=N=BDP$~kXOl=C{dxG{PbE^8gxF63WQz=NRtnd3h#bQww z03FJYO*5qgS3VB+E)z_wNdV%6bH5CuoJ#)xda)7Z{b(#Y9*D~CW&i*H literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/timagelist.svg b/mseide-msegui/icons/components/timagelist.svg new file mode 100644 index 0000000..5e2d417 --- /dev/null +++ b/mseide-msegui/icons/components/timagelist.svg @@ -0,0 +1,498 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tint64disp.png b/mseide-msegui/icons/components/tint64disp.png new file mode 100644 index 0000000000000000000000000000000000000000..0ca8f38a3f18b22335d8e9c926aaada3b88b2b4f GIT binary patch literal 602 zcmV-g0;TO@|4Ht#dtr(E<8NQM4=X>Y-{R}sJ>iewM^!oAa`54}BYOz?r zOc7JB|2Oy-eT+tKfoipi!C-)5v4~!;_v}#= zg?haXilTIP9|b@k(Q38A?RG;b6vBGFMlP2_KA(T~JDm=~;V?8!10m!sVqHXq{a>48M!sGFP5Q1PZ2uYGKnM|OnDg;45EEdCdyM-VKP!#2R2?But zuGcG6RfW&z!+1Of&+|wolZZy6&$&b*0Z|m;_xlY~=o(n9R~oH$X*e7XSS%JpL>~`CUloZ&AW0GqhXXi{(_Nm==Z1&hCU}+8>HO=FccSk1 oySb0ua=E0;H2C=+&d)da1iavk>iRaOO#lD@07*qoM6N<$f^eG*LI3~& literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tint64disp.svg b/mseide-msegui/icons/components/tint64disp.svg new file mode 100644 index 0000000..5cfadb8 --- /dev/null +++ b/mseide-msegui/icons/components/tint64disp.svg @@ -0,0 +1,381 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + 64 + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tint64edit.png b/mseide-msegui/icons/components/tint64edit.png new file mode 100644 index 0000000000000000000000000000000000000000..15f76f94521782d31529875c8b6e03e53feebf88 GIT binary patch literal 578 zcmV-I0=@l-P)q)^%a z3w#23Fc^f|Wf=f;T@Qtvh+bDjM83FOE`j?*1jlh8gm|0hoCA2%gT-QjTrLMyRZ*!_ za6BG8`PFKLbUKaG>EzjGjCs~T0U-o5O~ZIRhGki(*XuA00njDQrF&qw|sw!f!7-U(-bUKBiC{PsTWnGdG zi9|fp^q3&V*vr{>2mcBl2b^>4_xnF;-lt$h;eKf{0QTFezrfG`aDKkPF9?KX&hZ&D QtpET307*qoM6N<$f}+9utN;K2 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tint64edit.svg b/mseide-msegui/icons/components/tint64edit.svg new file mode 100644 index 0000000..ca09dac --- /dev/null +++ b/mseide-msegui/icons/components/tint64edit.svg @@ -0,0 +1,254 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + 64 + + diff --git a/mseide-msegui/icons/components/tintegerdisp.bmp b/mseide-msegui/icons/components/tintegerdisp.bmp new file mode 100755 index 0000000000000000000000000000000000000000..a7e150bd805382cfd4c16a4cc41353dbf5853324 GIT binary patch literal 406 zcmbu4y%oYR41_Q5QFsJOO6H(v7b>7ssV*J!coENHJ}ZJGb#9!e# zIq4MfOXlOTb0%RjTP{2jnrf{idYF123UWpW*N%VziPqkpn9=5}ca=qZaRRB0vY#fg cYDz}^BMLIE(YW@i&vwo0POGYuSGl@4*y<}5W-TLrlIS)jemW8wQ)iSUS3{4 z<>5~TQcANHivp;#l_{)QmIssQgVBH%g)XY)oPV&HcO#Uuo*av6#=x{ zZLY7cDHICkn7XcWadE-c))oMPK!B&GCxj5>^LZQ&2SNy*pPwzOv4m{6<#IUy6h$#7 zaJ$`XZ*K$e_Vz}(Tt-z@q?CBQUI3!eDE)q)YPD)=Sqwh9t_E*F(=?LFB!0i2)6-K+ zuT(10Y&JPQKBm!V;C8$J>U<2@*t;=-loCzTh(@D?LLqK$Zg4uCNGTbQ$GpG46AT7X zRTZDl$HT*eJ>*ZX*UC8_kF&eG%h}l(Qc9DrR4UYJHG~jMCKIO9DUnFTqGQRx!0H68 zR*P=8%V03z>goyrm&?UyG$ND9kWQz$ySoG6^70ao$79txKR;ilQYl*o-@$x7XJcc- z#&2$JejW06;Pd&u>?zCTa=nk;{r$bNPJ^HS;rx7qU!?-7%1-X+j{pDw07*qoM6N<$ Ef=(JKeE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + 123 + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tintegeredit.bmp b/mseide-msegui/icons/components/tintegeredit.bmp new file mode 100755 index 0000000000000000000000000000000000000000..737efa8b8ee00946d5741e93055fd40bba1f3503 GIT binary patch literal 406 zcmbtPF%pC@2*jD|X)P`99rpgkN-a~`U3c%vNB9Fjz=fcrwHuaf*gz)Z^zSIJAb-I= z+0iHJL;7)eq(X$CQrd+Jp7@E(XE`+cOR7z?TimqX hw7HRWb0f4eU)or4C+B!4;B)Yy0E?^_-u&v(djQ$Q@<9Lq literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tintegeredit.png b/mseide-msegui/icons/components/tintegeredit.png new file mode 100644 index 0000000000000000000000000000000000000000..7a8ce5fe030b36aabd267a76a5032f8e15ebbc17 GIT binary patch literal 516 zcmV+f0{i`mP)hbtrQN29}1YiyE=gFcFSlqqEssRbK~)ta=A< + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/titemedit.bmp b/mseide-msegui/icons/components/titemedit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..4f7ebec227b1a95f0ad15c854dd1b34d4bdc76ce GIT binary patch literal 406 zcmZ?royN!j24z4}1BfM{n2~`6EUo~Qf6WEK0zeTEhJXeJ1|VW+Xn;^a637JN28II% z4ge+ogAv33{~#6+10hHVNL;@Q1K00Ti(QTct^+NBfbVx<><=Fh?En04nJ zFuwp{#;w&s*+4uo=z`=6&()}MNj(mS&yDz=kD^p>4QV`d + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tkeystringcontainer.png b/mseide-msegui/icons/components/tkeystringcontainer.png new file mode 100644 index 0000000000000000000000000000000000000000..4cdcab8f1c03b2d9bc10ce0560223c5eb45cb3a4 GIT binary patch literal 1524 zcmV^CWANPiinfDI(OMikMFi8W+rYim<(Q{ z$>^OLb4$&aC%?4sbA4@(o%2wI(PZ=*O-65gVtjFs${fz z^e}?X_D(jv>ll%|@lX>_JsPKvYri|-P~)e>zqr-8RR{Ovmvf}~2q{}qP!t7^%Y(Dp z$+!vQuuZv%x_$MuHMeo<_$fRmJ)nWbItJG<7i&^8u||XsSyc4*_J`>!R@AaPcQ;En zEk&x5pcdrKxl8eMd04l6JqIceaN2d6?z7$WboY?<+DbOR@1U`^iKyr(3is^5VjZKC zZ_L^htr|^6FJKDz0u*N#BZQ#yXeSf@IgvmhKwnQESC7A%mAR=H4Mwct;kZw_nQ-F- zdb)erTCxhW*{m1&_x4U|#^YjJ%eG7aMJOzBEa8Rp=XpPIEdhT3)u57;`37bG{*3t# zETHAk&_*y@%!G!8j#v*pMY+iXNniDqZ^PWpQKsH>_cHFpKevXiOU^?#%k z1hv5~QWWKq_znV^$#OB<37Wug=NF=gH_)UH+vp)XU9>PSES>^&e>Yu%17^RCoM0P(P4vE zg{RAd78u-F`{AExIn;s{(D3{Gc)bH?nnup*jjY?AMgHzQ3b*fMz&pT_<*yg3xyiZH z5>_PuaQw&PWG&9ZzRiv`(h9&^amg4A20D*+VBeTRNqz}+`|GK#s%6uA4hFmf+%szi zt2bw0v5pzMUfdphem~E>{A`B#_0v)!2>V&}!~ z0gwjC4O4Gm))O=Fobs^$v;Fk<_A@^ES_*0kxNGKJe3Y4oq5$XL11W#&^3vimsy^Sx zhVAQ7)xpzrxw{F_g*4rSq^@mpZu&He4Ld}bwxE(@4kib$Oyjqs)nYT zCjEckIUi|BZxdz?V?|OLZ@!XDm&*-+QuK3?T?mnKxb85vTWz|MfBdeU%Px<=8g9i| z?Zg^x!FIC^iKMlu6^qqM-`O4}-8>2ZIX_J`PQ-Zy3q|49X;VRCr4ltM>f6=jt8IVB zn=FwlL`Pf4gkh@ri>&R3!=b9?*Zj@SCMKKXPo807Km=PV8c0;<_!K3n80%z+@K zJIbzIo3!>xfGKxOc5eJnb}2zv`do6%|4R180K~sIzjV>^MNWc2?w>a6sgCxJvHpPn a`CkF|C?^5Fh?q720000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Kstr1Kstr2 + + diff --git a/mseide-msegui/icons/components/tkeystringedit.bmp b/mseide-msegui/icons/components/tkeystringedit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..42765c7e07575cd5ba47effac5ccdcc9bbecd24d GIT binary patch literal 1782 zcmb`EJ!*$Q5XDWCA}5F^FpY&xuoF@U7C{gz?_p<=J85D0hkzFlEVR`|tSkazkvyE_ zv1~#<+zjmcoSpgkc6@kzxwekD$9{)(`@XIYWmy-TKi|kY3b9@OFFugxpW+4muYZgu zC3vY591a6KLyokYbHtJ%hvWRr34#Ep>$*l!)HDsW<2XnnvMiHEXc3$bgf<`F_m^b} z!%!foXP5M<8Q5TG9MAJy*R86GU7DY^ZEf2ghJghlG!DK#j$@jp(=SxHb)YEzaK9zF93jkzb~y=ECK)|foYn!y1GKST*l?)B}~(lf&6|yVzJmvHRAEO zGz*fT-EQOU?G2Gg1n=+fXt&#P(r`G$(b3UN0$tZ_PaA=zX(*LSAc<0`WRqz$8ew^P z*%oXvnMi3yqmhHeg7Tff3c9tmg-j-c!^1-WKrk4@{{Fsg;nUL-R#sN<`1lBq#{*SW zT~8&Z*|0DO01G8hfUk601cVS+nmz6B(eL*mgmABe{{buiUF$#yA)S><1%*OkZUSA` zrCCsZPU?2Ms8*|JHk)$=w$0&uJUq}eP3pQXW7-HdH#d23a3B{%qfuU8U$fKc$Uvv3r`+D&CQ0V= zd7hk{xOUO$H9#>XfDi)ZavAk{9mmJVh{a-16a|yXnM$R&v$G?8mMr)8_ww5zk%hCf zGv;zRYMRDCAV8nb$GyEhIc^vR0r2+r) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tkeystringeditdb.bmp b/mseide-msegui/icons/components/tkeystringeditdb.bmp new file mode 100644 index 0000000000000000000000000000000000000000..a9484bb6e695ad4009abac19e21a0c8e9d4eb740 GIT binary patch literal 1782 zcmb`FF=~Wh5QR;XA}5F^FpY&xuoF@U7C{gz?_p<=J85AR76M*Ca6zjDZPV?x=HW|* zpV^QE{|xKD&vEAS&EV7X<<{Ba5$6N0`_JoUQ;u`M^S3)*TOp3a|HT(_|3AH;|8-se z{#)1e#RwT{2S=6xo+XFv_8eNWHpUDrW-o`)o&C<;D;hCs-EAk==s zFgza5aU2tZdUlbZIItn1I6)BjzTY&BG%7!R-@C3mO%o@QQ*rS2d7kq;UzWvuyI^5; z7=|=Wf1Zm|oKEjqmW|_xcGFK;mUUet*|u#}RWcNW@+0s4RhWM4IkaKPktHh*;5H%O zw($1};lK5H#>D$1GEtOhsmmnoE|pLzwo&=Wg)<&8dBt literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tkeystringeditdb.png b/mseide-msegui/icons/components/tkeystringeditdb.png new file mode 100644 index 0000000000000000000000000000000000000000..23d7198409f03f0cf84472f326e3febe3d8bdf3c GIT binary patch literal 839 zcmV-N1GxN&P)nu~K~zYIwN*<<8&MQJ(`KOy7j=;sCM8)wKTdZ z0g*yLq`E5zLKQ?Oi*}V1nu55AU@^732FAryu@sHqZ!v>z0)mTxBhdALg$%r zLPaqLE;HPB-#zah-hEe+Wtk`@WLc((SS&^WjKyNY2Y`|!(dYB=G5~OYf1fUw%eH3X zPCl8UDDe4wn46ok93qp+;N;}Qb~uu7I-N+T(*OWn*M$XxK>&atFbo5Wi;IXvB3M{h zfMFOSk<;mf$K$zDjr#g}VI~AYB9Xws!2znPt8sXEh(sbGg0k5xCMG7XB+xX?^0g2s zih^)B43Y?k!xouxxg1JLN-W7vPfvw3xm?ahV#1M6U?%PC>_k^r7eb*B0HC6x0wW_M zmW`=Y3YC?W*xlVlX=y2BSuR+WbbcF(1_?k>2^;`Gs<)7;!{(7B33m!a-Wa;BLz1Mz zeQ+Bv?|;EQkfc|_IW_eQ0|Sw36KI+y%!K1|(E553Gc&)TsvobF+?1pcNU8+DOy&oh zn`^kY_noB5`T0+DyUXczmvebJOj2c2Qw=vZA|zFAZhmD$!$XoPNpgF8n}%Uf(=_oI zS_r(}CmbE^Ip3hNw)Q@kmO@-v`79Deql4`2eMwSffB$PvPQDie`8Xc~v`FOlKgI0q zANc*x;PF&pXJ-#y@6ef+j=KPWo}L#N8~cV->Hvzeicsj?l`@G6NR`QCl#Pv#czhgZ zRh3&vlW&8AZ`j)Un0EiJVczpm@zKOT<* zxM8EUwSB<&_* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tkeystringeditlb.bmp b/mseide-msegui/icons/components/tkeystringeditlb.bmp new file mode 100644 index 0000000000000000000000000000000000000000..2f9421cd664edc3bdf6e7bfc676eed377bfe9aea GIT binary patch literal 1782 zcmb`GF=~WR5Qa^YA}5F^FpY&xuoF@U7C{gz?_p<=J85CHECjrO;DS~Q+NMid^T%0- zVKyY;y$tKy-*M*ipJDgu`Qz5v;t}TquKUY%vnj_p;`!?xU0WfJ>`7O(`aU9Vu{gh={*EN!D+g4S@LqRA%{N7)M^kdH<8W`a2|Lj)4?L|)w@gK;=;D>*2pphjp24s}b7I6*^=I3 lb5MXhg1cCAh9MAS;9HI?Q<|8HOf_mQUYdcB_SmPf_yni_R{sD1 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tkeystringeditlb.png b/mseide-msegui/icons/components/tkeystringeditlb.png new file mode 100644 index 0000000000000000000000000000000000000000..c89393aa8d9fd858e88bbf66ae72ca5a873bfa9d GIT binary patch literal 839 zcmV-N1GxN&P)nu~K~zYIwN*VxTTvALo;s+|MM9!Ds1@-igW4b690EEdQ5=Ng zqSQ(S7wM)T^<{EN1{I`HDhdr9vItL!C_-q{;kF&#Lmh;IL!cz;QsNNs$=5;OZJr4g zZS%q5Jh7G;Yh;ibRv~X0RRlckQN98005G}G)?U9?_+Us5qo=k zFile?ayp%8Z*RX-jgF2EX%-|wB9Xw^*%=xe8*zSqjzl6MgEE;6mY0|BB+zx;_O%gc znubs)1d<4aLN=MQ*(}P-%WcW7uCAms*=#nC#6npvftA$n_oKhRAHiS{08m|BjhUGl z+s0%viH3#-oSdAXqM`z-surwDxw#ERg94za1Z4m~A^ts6S67}(Q52LE2z@XN!+@eF zh5O)tz`Fkh`#|aLmd-Uz!^Hgjy$N((mu8{tcF@ z2OoELG34=}y{QR5l1cPTOk8VOS_%Ld?(4(ba2UyS8d@TO;MCNeGRX=k1dpRpK5c2? zMLf>OwY5^3TzfM-%x<@vuLcIB&ywZf;D98l>w3OKR`AB$97nufYM~HaRaJacS;^_q zQMrB`jS>LG+S(uD83+-@H6dNJbl0svC6SYFA$E-uhoUym-g+vYb6L;i1W zZUT56dAnA RoRa_m002ovPDHLkV1l&1Y?1%~ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tkeystringeditlb.svg b/mseide-msegui/icons/components/tkeystringeditlb.svg new file mode 100644 index 0000000..ff9b967 --- /dev/null +++ b/mseide-msegui/icons/components/tkeystringeditlb.svg @@ -0,0 +1,449 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tlabel.bmp b/mseide-msegui/icons/components/tlabel.bmp new file mode 100755 index 0000000000000000000000000000000000000000..936d204c6757f84fcabe36bd6d53a0f9c98f2d71 GIT binary patch literal 406 zcmcIbu?@f=3^P(!_KqEUNB6$dIal-^PT+yuLQOzXdH_yrOyXSkn_zgTC%I21Y&JjU z-abDOfDMuHP-#g)DTRw>jn=v&S$#y&C8$vLL{?=FL|@?%tt?0OI4^?_kr?;873Kq( Ca0IUa literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tlabel.png b/mseide-msegui/icons/components/tlabel.png new file mode 100644 index 0000000000000000000000000000000000000000..3317d21f5094edf117441f8c730ad893fae41abc GIT binary patch literal 471 zcmV;|0Vw{7P)e12f>F@UMt@4d3@@OnK42XSNltYESj5jAKqJp_0Qde1 zkmNKj;ayd2>{7kLcic^KsLjWp8tpcE*iQ1~H{B*q;EMji?+uV-0=Jswyy3TIsSVIp zqB)$z8fFHJS#05AlC#5{w3TS5TbHY9bC5xjmw2R~#lw*^NOByPn+V^w1hL%AH + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + A + + + + + diff --git a/mseide-msegui/icons/components/tlayouter.bmp b/mseide-msegui/icons/components/tlayouter.bmp new file mode 100644 index 0000000000000000000000000000000000000000..7f1fb49f54a6787faa497ae8e19ff59ba5ead01b GIT binary patch literal 1782 zcmds$F%H5o5Cly_la7if@B$t{&!2e}EgU{FI{7Y^FQ&qht;u?K?L^A${ydgCuCiWa zp1<=@sg#H8pBA0fD9h{DLyNUF%cN#5#Y+ME+9u=v(8)sLfInhHAr6eByoWg8JtGQn zKvI@FCDsNj$f~0gXKVF-eg|RI5gQ-{GzK2&5okoRAy~7p?eQEocw5-h$!=}^eb3g5 cXLUYQHmH8$z+}(9c$ktaajO(tbJ&~}-wfHizyJUM literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tlayouter.png b/mseide-msegui/icons/components/tlayouter.png new file mode 100644 index 0000000000000000000000000000000000000000..9f8af9d610e3ceff87f5779d89ce78e611dc9eda GIT binary patch literal 816 zcmV-01JC@4P)UF96=O^zgvY3A-gdrLSUC*kg!b(K|%By!O}{U zJ2*(QSE{g$C>GJeDp%wrWw=4Gx*~{;M?gq(+UOyuA(*5Xf?|mIJDZTZB5Vq?VvKrY ze(;*NzxQU|?8l?2sp-3Enzdvy`B6$aE2W&x=kvle&6;VNwZ6W-jW|CvG_)G$M@L7W z#d**3UdQ?6<>kkJ^8Ha1kuXiOwzs!uqM`l$eO%YovEq4Ny;iGTGg@0)Kj{=GrO0G5 zD5bOx07xVfEynu#`coaV5Q2k)1B4J-&6CMw9mpCwW~CIxViAC1v8Xl0)YQ~Vpv72R zT)f-JEQBBoLjb}s)Sd#sn46o+G&0$?O%MbC1VMmp+YK9UZ*SiOu0~ONdplA}9V?#a z{i@gN4~^d5-Yu<)|CF(?u<-nJLMcU|P|$v7Aq0g&;h!Jh+1dF4;Dn;MaVnKMw*WZz zc`mBUX0ylU!NI{7l}aUY947)U3@PPFT;_8eC#qB`(fs`UIxualuCDgFu1mRGCI|v7 z%L0yRky4(-*-7Gv>9Q<~AP6Xz%ebz~($bO(=TM}SLI{Cv+xWi!SL5?25<;Mq!uS2Z z@Qo>I9vd552Ga3|)6DDW>?O|17#|;hrQPic8Xg{g3#TZ$OfiapHo`qUJ)Z%Lfq{Vs zjm$BM@c~y_**dF2DMc!kA`C+;%VKS9t>HfE@9+O6rF^9IM7C{{%jE#b<#Jlf?(p#N z27s}$vhqad5a0K49H${QXJvGBbo|gU+O|!pRMNUV!1VO=7C`gP&d$cj$VeS%YHMrz zIWaM@3s9|AZ0000 + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tlistview.bmp b/mseide-msegui/icons/components/tlistview.bmp new file mode 100755 index 0000000000000000000000000000000000000000..8d666b1eb0533878fa25096a4fb94629732e8d91 GIT binary patch literal 406 zcmZ?royN!j24z4}1BfM{n2~`6EUo~R2Xjz}1_lNoVrXc9P(TvM1mXsU0|yQOCH{jE z!~g#v77zm=NC-&W#R0AZC86N&b%Yu`>N#iM2}%p{VO(4c?&IOP)K!O)TjV@5%?Y&^Vm(C*Cx_5wV5I{Av91i}1Ww8(dp4b4Z literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tlistview.png b/mseide-msegui/icons/components/tlistview.png new file mode 100644 index 0000000000000000000000000000000000000000..eea0d7c0772bab27498275e5ff769e81e1d817d6 GIT binary patch literal 1376 zcmV-m1)utfP)tQK~zYIwU$dzQ&$*(zk72Zd5}Oz1O#~qMT;Vc*0E~qgR!)Z z?Jy%V?M##CdX>b9+YOm*x+rz5tGj8uUZDqwg+AcR0jLK1H7J+}+w z5u;20%{}MdbN=sto^z$kmoMAAL{R`f>C{nlHwXd3+IZSF2n$A|)v645EL852d7@%j8HvYH3Z2W-rRF!?ndA?VO}Q}t{c zwCTa7ga-a#e7XpaK96Ara6A9yU~>x|PvC_im|0Kpb0*B&ZKtu;ExHH$IO8nI4-tS6 zCUUTgMe{so8%F3Is|8mY;rRZA%CE=9`75`?8x5`KiUtCv6eo8Ri=5Cr`2bl~C@l)p zq23}e9H!kJLaE<{NM!*%PqDCVzMkwQlwCpAbu7TCYFxSV1Ft!X=t->5T&hzB$axu; z(zy4zaZD~yJkW=coyMs-3oMrfc`4T2eAwJhESKZ+JqPj18@A^G zyu|@B(H>@x!R$#5)tEz3T?K%ZT$V4Mbfd@)#+Ra)LNFFv;HROxWQ5IEGXvYkYz~%e zgWG0|?x3IR6)vvsw)nOvOAoOEfM0cTW#2grA!yxGN6_P=v9yx2wXGlomjbohQP~{a zGGZ*-X(We0atLJ7jEe+!i1V4$NC)Lxo06u%M?*IW6#EDuVHyU>RFc(nhG@p(%c;L< zF7fb<$ZZ2YP%F6hTMrF2L5?)nfe;Lj&r!Ln39nlNEW(Sc><)VIDjGi?dXL%VIP;Md z=J4-KMj|vGKEdmIstMH8lUYro%IeNCwHXP`lUp}fO{CErGPB_&w3b>z6Km}9yXhO6 z;oUO_wmj+UpQCqhhJ$4WK8GMMks@8>qN>VC_u~cXd8W}?4ph_GahPj29$;I7b;Bey z86}r9c^nFpNgH{&FieY%la1W(pQNd-mgQuQnMjhk$ZBB@6h)@cVyq!{?f*Bv7L|G!}brOv(=K}!NS7WS=Kf+EdfTSR~{kW)NU%ljQAUcC^IeA0tkfKquBS@R-{B+1!f^!>-53kXH3 z84W+7JfKolUBSJ3Hp8PPU9W7f$vcar#4<`%D_U7IO37Z#_ylq?h7eYMNA3{Wp%aZm zG``5AfnwY)DgXP{Kvs};)gf{jgptBpTf|yVfKx-39WPK{D1L8#A>p`MjQ zDobbUBeFS_fw=|-rrf;W9wq1+1Jpu5Z{HXf&$sf+jR)wO1BWD$&939pRTLS{9BV+` z;qRXhC%E|Le&*)q2}*NRS`n%}KKe)3SWBoWSSNXxX`Ou1e + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Oeps- + Lukip + + + Poli-ui + Wio-l + + diff --git a/mseide-msegui/icons/components/tlocaldataset.png b/mseide-msegui/icons/components/tlocaldataset.png new file mode 100644 index 0000000000000000000000000000000000000000..289cc4a6eff410187eb4f57ad12c421d42792d69 GIT binary patch literal 561 zcmV-10?z%3P)>16?}QNifvt(y@yq{z1v& zlu4>~c2R_v2ST9_0(K}J;!t#{)gtaqsZi)3B2F%L=@QKFUTlbM4IGEas}gBQAwwYt zesDSG-urP6TtiwF1gK6Mf7UnW-~Be4tXlxXSghILx@AU3Gjw!3V`3u1`T2#Pl}bOE znQ`dsOfoPq$H~d}zXR^l($WXU$D?@OYm&(kR#vwBY8RE3kzectvzoXaCY{Ca5w}&Pfr*5yys_yLXk+M z8vxS`5R3IU4(RI(Q!4!es-5@t-uJUeq?>%+z0NLhocE0brl%j1&F)h!|7LytGgDK; zel|Hd!r|dJE-x!M&NjK+QSAlNs-zc^UJAH1(i?f+D64^=Nnd3A_aDu)?Fvw79st0y?s3W literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tlocaldataset.svg b/mseide-msegui/icons/components/tlocaldataset.svg new file mode 100644 index 0000000..78eacc0 --- /dev/null +++ b/mseide-msegui/icons/components/tlocaldataset.svg @@ -0,0 +1,447 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tlookupbuffer.bmp b/mseide-msegui/icons/components/tlookupbuffer.bmp new file mode 100644 index 0000000000000000000000000000000000000000..599e3430ff624fd10fe03502d99e0ff01095d296 GIT binary patch literal 1782 zcmb`HOA-Ph3`B9`!V`D|Pv8OEd*vysypvlD-I-J-Fn}LwhH3+8UV?hNzm5sxD)U9& zv%UwYlpeDFJn_ZGGUZi?_)RZM?mu}n2+%i?)!|@C|MAI5eAXTnT|Z+U^tMh6ktv@P zd2nqTs<99138(X;xLJJ4XQw}(`Rw;6_}E1V8?}eD?~iS>T7r+ysx{Ls*Nfm|2N_R{ zpg-P$I{4HKK2qwM^NFWRo*UMmUwLp$Z6XoY#aT|Sc^Dy7(cQYr@}>e;jFZ^a{%sP8 zKA4p#uqh9Cn{_cb%Y#GuKC&7ZNJbLn+3$}x_bE-??~hqYu674aH*H|W2me2o(iBYw OA5`aZw<<~aMf?ry?3>p43lwTr;BkqU(N|+X zzBsquYj&41W9qWkA2w=no>tRfcu^~AbAs2wvR;1MhTMnYXU|NVf97N7{K6;y?3}cj zCzPDD731M{^{8$C~@4T|S`8w-;tf}t82bRB|Dw%gN&DD7QnZd3z zD%9jzWAMj4><8^uy#BfVSHhCXd)c3P1@6nr(~1yG%4fIL`f!kYy-+3pGfjh@o+^Jf~~wvk0O7S!QJN8lM+_lkJ7o4uD$nqs2{k0ZB=>F?N2~|F?hQA KxvX3XOD literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmainmenu.bmp b/mseide-msegui/icons/components/tmainmenu.bmp new file mode 100755 index 0000000000000000000000000000000000000000..e57b7c0306489c6267d68b60f4d8bd6a003e7703 GIT binary patch literal 406 zcmZWkF%AMD5Zp^FObm&+%F@zz*!vx!xr7d0;Cpxi-BlZ&;dM9*$PpbFm<+=N?vK|* z1y8Iu@X|QZq4-yv&!@^W9ASke!X#_!h7}UD6hgp3E|YQ=1!9PWg$G2YJ|eHWV3EM; z3l>(RM#iI#JTjtN<}WW1WYn1X>EDL_t#wNN>q~#voHU*eXstN8`cC7Z(PE^@aZHwu WMw&!-9~s!W# literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmainmenu.png b/mseide-msegui/icons/components/tmainmenu.png new file mode 100644 index 0000000000000000000000000000000000000000..008fdd3eb0388ae0685c933df85247521e684a1f GIT binary patch literal 1051 zcmV+$1mydPP)j3KU1j`xm*sv-%qJjqQAc%0Mj%{Bob6A6#!IK1)x%? zu(`QOG#Vw9N@26vaJ$`fc6L6F@s9>z7zR$KlT<22GMU6~w=+FG4M4eEW@%}OiHQje z!@%Ki5Dtf}>@%4R0P%PnyWLKuQlV5TF*`epl=5>;2ywKrv4Pj?C7n*w*49Q_Tbq@F zuIu>yevXcgaJ${y-Q8K$0rd3r;PH5HI2^RMx1*}6RWX1DJWr?7Y;A2ZH#bLbZ?EM* zQ4~f-Ml9n8r;4IjTy;W;Mx*uS;0pyflTyB@H%T^|jrH~QdR+iaO-(iIs|F}&3kwT> z#bU9#0p{oD85|sJ>ZBGsJ3DM|Z(D6m)9lJaiS;l%JZ$Q^-qP{)^)($G9mHZW78VwM z0=|<{mW2?Dsu1GSX5xH4&&tXQ@pzn@n;Q~|1jS+z!!RtH<>h4#4-X%j>cfwe@>>n~ z4RALKV7J@p>gvMd@n9GRx~@|!7P-B>rLV8AWp!#RgVWPfoK7b;n~lrMOG2R#UauFI z%VpWj&dw4Fg+9^>Ar>{@ZL2u8Kip%AqP$)1tIoU}1S`|XPc}kG6 zu`wc%2;JS?=(>)kX=Jlma=Dy!d_0Df@~s9e0>3nK9u9}C|41Z4BocW_PQVj}==k`U z)z#G}JFJBe;&%=Bx|xw-7z_*y5C{agxVWIFrw7wCNvG2v?Soh>_E;X!q?Erl3y{fV zI5;@q>go!B^Ye4=?(Rq?lZ=jza&>iu&*vi$2-MZL+-PurgXQyiOw(k4f8RPLve_&r zCnu!S=| + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + File + Aitt + View + + + Zuio + + + + + Przio + Iklaba + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tmainmenuwidget.bmp b/mseide-msegui/icons/components/tmainmenuwidget.bmp new file mode 100644 index 0000000000000000000000000000000000000000..b2206f60c6791f6aca80de03d5abc21f5c05c9f7 GIT binary patch literal 406 zcmah^F%E+;5Idv}NL{K<9U1$M?tG`of^-|afcNAVOcBq3EwwMGN~=^g@x^i+i#+@Qx0uwarKl#zpA~h|#R4tYc4Onr|p@NRVu{gN6 zbo0OX@>TA1{|!Z)6goIKR_LIE&;*5wNK{C~{(=@P($eG(_cm9rtKsMYQ5ZRY3a{Ybnx zJw2sZEWUoUBd>qlhO6tkFY)v9Gh<_86pKZ6c6Po4|CP(-K7i;4ZZ@0j@9$G8m3Vo1 z!7vQk?KYNWc{O``dt6;z4bnH9GCmOsg_xL_AQp>ZSr)pk({8uvcDqbZPy4#_b#Qlg zMj*!RF?sZi?(gsEcDqz670%AiP!t7G6j2m~R;$I@+S*90?+ga9yu6I2 zX-rN|qU$=cEK{%7X*3$%@$uIVve~S6uW1^ZrhT?Ae}S8u8x9T*K27*#0n4(Oo0}t@ zPV@NqNIV|LbzN-Rezy;XojSe()oPW?%S&pt8UPOu5A=FHDwPULOH0&hHIm6B>2!K1 z{!>GC9EWDJiR-#tTwHj^M7>_;_VyOrwnt)p9jK~`s;XYTva<5#f1qjFoBT@x{eJ&j up-}kWuZfT1LjhTqzX3tMuwMY@b@BtBC?%S{kuu=`0000 + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + File + Aitt + View + + + Zuio + + + + + Przio + Iklaba + + + + + + + + + diff --git a/mseide-msegui/icons/components/tmbdropdownitemedit.bmp b/mseide-msegui/icons/components/tmbdropdownitemedit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..3ecf11efe223b46f63e57c065a0d5df62636d0ef GIT binary patch literal 406 zcmb_XI}XAy41JZ5kSZY<85w&HcCJI$Y;^0!d2)noo_qq9Y@LvKiK*yP!N7~3^Wsku zpD*_Y6<7L>JiggrQ{yM*AFcDiNTDMDG=$(AJtY|sV`Rdr!K^5ftAyx8XNdkw_X~*G v$m2w+w5R8Nsye9*8|({z4QHi%WUF^rPl_>O&4G5f0_3M)=Bdh literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmbdropdownitemedit.png b/mseide-msegui/icons/components/tmbdropdownitemedit.png new file mode 100644 index 0000000000000000000000000000000000000000..62e4cc1fbf728decc0e5c400a21263244ff52c09 GIT binary patch literal 347 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ zFuwp{#;w&s*+4e;4+kRY~VT}&Z2bY3#zA@KL zH|gA#5OHN(Dza-Gch+UjYme^SNtS54JNMX@1P2bKB2Q+!H;YVs&6C%4o@nxCH}Mso z`@MGmgUgIcOvyY92P8J{5VN2ES!Q`wKZY*Ok=zF}*(TAI@BKUmn?RR?D nqTJ6m#@mUW@BhXUb4+^M-|lB`Hsx;x`jNrY)z4*}Q$iB}g#3r8 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmbdropdownitemedit.svg b/mseide-msegui/icons/components/tmbdropdownitemedit.svg new file mode 100644 index 0000000..1e8fd54 --- /dev/null +++ b/mseide-msegui/icons/components/tmbdropdownitemedit.svg @@ -0,0 +1,327 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tmemodialogedit.png b/mseide-msegui/icons/components/tmemodialogedit.png new file mode 100644 index 0000000000000000000000000000000000000000..6cbcf533b76681d9400bba7647a74cb8f1a7348c GIT binary patch literal 510 zcmV2#viY8e7r>t79w zHf=N-c%H{>HltpzNBnR&q}S`QSS*;&=Y~MJTt;hc#6$zzwwX?+c%FxC+Y!H7t*BP3 zD5V&W$FWsjE*B#v8Waiz_WM1@zrUh%g$B41vjHg4WuI_b_SzP^na6 z-P7%M>2x{()M_`@J3-+}A8eCJA~QuOY_4pK^SKA*YWZqFG!i_la=a2)4hz6G$| zZrSa2uX@pLw;$#xN%=^#fcXF55Aps7&ifmD0yJ8$poN5+ivR!s07*qoM6N<$f*Z=^ Am;e9( literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmemodialogedit.svg b/mseide-msegui/icons/components/tmemodialogedit.svg new file mode 100644 index 0000000..b91e7fa --- /dev/null +++ b/mseide-msegui/icons/components/tmemodialogedit.svg @@ -0,0 +1,319 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tmemodialogstringedit.svg b/mseide-msegui/icons/components/tmemodialogstringedit.svg new file mode 100644 index 0000000..ffc04c5 --- /dev/null +++ b/mseide-msegui/icons/components/tmemodialogstringedit.svg @@ -0,0 +1,290 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AB + + diff --git a/mseide-msegui/icons/components/tmemoedit.bmp b/mseide-msegui/icons/components/tmemoedit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..5870f7bbb26ec7faeb11f33df45d3d6a0518bbc6 GIT binary patch literal 406 zcmZvYu?+$-3`Kns9fc7U<(14q&n{FznUd~0=E)-7!5f%wJ3&U`Uw-c8$FikduJ46H zckE~QG`!F*@)h^TefogJooYl_)LQ5DbYtUqhS7ZN|=O z#!9M_*_eZs`7g7g-m(UaUcuQj`_%rGa~9j2g>y1y{VX+iQmNo}yJ0?`$2O0(h$MaAr!33SQNz0H zx@@=GGz^1{MuUsRBGIB3Kw1g`|4+~)NqSmi0e>4bl8_|n<(u|#&<=+Kgb>hm9YP2k z4u?eW$3bg0o7`@z-?c0QjWga81vS}j~Im&60aPElOYN~IF^ z`+a0zu~_`vA~HT`wrx|>H0rueAp{-ANwg@npoKlcHT9tJdp!Bam}UUL^StOEnz~4u d|LjkKegTBQvuTTJk=g(N002ovPDHLkV1gq1{|W#A literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmemoedit.svg b/mseide-msegui/icons/components/tmemoedit.svg new file mode 100644 index 0000000..05894d7 --- /dev/null +++ b/mseide-msegui/icons/components/tmemoedit.svg @@ -0,0 +1,261 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tmidisource.png b/mseide-msegui/icons/components/tmidisource.png new file mode 100644 index 0000000000000000000000000000000000000000..242e559e8a3719a2786a3484bd033ac10b589412 GIT binary patch literal 555 zcmV+`0@VG9P)A^f(I9CL7|&J;T3Uku@3K5!o|`my$=L#z9i?# zIX4M`e$!rMrp$z+6~9sOs};Xc@r8v=7(zD z2`u6!j5RxH5udTGIzUrcMPLLg4Zn=UE!@RxT&w1N!Ek0OcwA+)gi}?20x#Fdem*m& zGjj^#xEK)!+k;B0e;?w`*e(%+GEL)KW^U+=M8ufE|7vGESt4Sl1)t#n9;_4h zQba68#9Q1pxV}Ht12S{2hkj;m-^fb;M}I5PrYRzx7hLJkV_(V4I~^KyTOy41Fq@eZ tT{#q->?(Lfj4*g=?5%FX_crkv^9yn|yHiMntmFUy002ovPDHLkV1jQI + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + MIDI + + + diff --git a/mseide-msegui/icons/components/tmodulelink.bmp b/mseide-msegui/icons/components/tmodulelink.bmp new file mode 100644 index 0000000000000000000000000000000000000000..f767639a6fa05cfaf710b35df8d6883a8fa5ba21 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDj7v_dwutFelfO-IE+RVpmfCyqX8ElAK;O0O~ zAcKUMLxx6VE%3mB3zF(Dh(@?Me{eXN$R+$em Hhbklh*aA%X literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmseautoincfield.bmp b/mseide-msegui/icons/components/tmseautoincfield.bmp new file mode 100644 index 0000000000000000000000000000000000000000..7f6124adaefb21813846601859abe681989ca42f GIT binary patch literal 1782 zcmeHFK@Nl<5W~wJe1T8!1^a-#`(@*QynDrl!Ddp8K{0!B0;B_NnGF1fBHOi;8Hz%Id{r^yyOH+f55b`i#)~-QWjuoW*@z~XO?5Br(7t^ R*GC#6sqYVP%@F6BbOmd>4aEQe literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmseautoincfield.png b/mseide-msegui/icons/components/tmseautoincfield.png new file mode 100644 index 0000000000000000000000000000000000000000..48f5f16d90ca85a59ca7461e94ccff7c74727907 GIT binary patch literal 476 zcmV<20VDp2P)&9wMn%QcFz$Z~}}*^*OK; z^H+g6FL+YYEwBe%N;;5~{SFXUPSSXiAt?u}03&8L4Da!r}p(^uXf+wA@UNea?Fw!8zP + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + INC + + + + + diff --git a/mseide-msegui/icons/components/tmsebcdfield.bmp b/mseide-msegui/icons/components/tmsebcdfield.bmp new file mode 100644 index 0000000000000000000000000000000000000000..a2e93cfd7baf63d07a5663a95c6a45f8165bae64 GIT binary patch literal 1782 zcmeHFu?>JQ3@Zx*7jOa>Z~!|mBP4!eEmi}T6$A(h8&O-_Bz8j7uAj@0ti{=2*Xu44 z3SmTis%)o39PvFHV$59D3q*2^bb@DUq!au)IsuLaV0%sLSJN~Ezq`WYbR5^NV9{@Q z@43`bic{0;M>?oZ+y9g{KnwuNQ9lU1t7GL@-Sk<7QP&R=XyjV5`iTK7O?8xb7ymlv P6Z>L5(9Buq4d03`-<$G* literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmsebcdfield.png b/mseide-msegui/icons/components/tmsebcdfield.png new file mode 100644 index 0000000000000000000000000000000000000000..11ca8574de9b7e9ccad59868b639ee0c542ad2b0 GIT binary patch literal 564 zcmV-40?Yl0P)viv~KF&CFHn8xgxPn3yg5$ai(K~~P*nv~{n3-Sj64xT484*Lcj<=b) zxPrG0SMfeGr&o0l5%X1RbC|&03c7%Cywe@wQ(UQ0A4fz7^LU1HOF*NPcG>849T9_Q zX6C|1&bL}KWo5|gR%ZVCoAdk+m))kpAFI*t- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + BCD + + + + + diff --git a/mseide-msegui/icons/components/tmsebinaryfield.bmp b/mseide-msegui/icons/components/tmsebinaryfield.bmp new file mode 100644 index 0000000000000000000000000000000000000000..2f020fe78df275caad46dce3846754a174330c00 GIT binary patch literal 1782 zcmeH_OAf*?3`E0*MNhyHH~|M>&y^APVb3;3U$=~*}c}}axa2pjO&PXG_E6dPMiQ^v6z0S@#{*0xDcF@+jFRq zP?=ps3|c#t;h3;BM|{kW>faJ0Dwg}>T`n-H*F-WLAT-wZqZ*869Eq;=HxAjQ;-jCX U*Qwt*jAB;A`ABEhEPq|_4JZ!s(EtDd literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmsebinaryfield.png b/mseide-msegui/icons/components/tmsebinaryfield.png new file mode 100644 index 0000000000000000000000000000000000000000..7fc347c0319379561acf05cc8127b778a2a755dd GIT binary patch literal 451 zcmV;!0X+VRP)}mI&`|f%7-uE6a3ZWG!5fy-T zyBd{|yjFV&V`U^xVkGeQ0+pm8X&RV_&93eD6h8~R+3riK0bb!1| z*ar@PW?WGwDjB|ANt?hVumr3XY~Tpk0QP{xtbnWvZh5jt9KOpj8XQ z3bbvvY~R>!0N=n$UJ14zfqkG!Mn?)~AW6U+gIN^e80Z13!w6hT`jpgVaBS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + BIN + + + + + diff --git a/mseide-msegui/icons/components/tmseblobfield.bmp b/mseide-msegui/icons/components/tmseblobfield.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0fd3db8aed3f715219223e88b478acec881ff8e4 GIT binary patch literal 1782 zcmcK0!EM4o5QSmq!XXu;1S+5a?r9kzr6;b=*o!|sWe^fFS$WOxdGilzpTBR1XugK~zYI?bbbOR6!KR@!y6;Nn;c(1Q85&g5+SKHi@k$7Fvjn zFJHjcLcz+y%EHD3K_rEpg;x0j@eRQf1W^RBTr7Mg#x;^_v9oa9Y*sB65%M&1=lo~R zx$|7+a2r)MR~e$3u&}VbF^uFB6Rm1w7>VmzFYxaRG`kNGF^aJ={hFDdYiz8yv zB1Ui#C-E9rGV@u%$0K3}A8{%(Tm1?gi->WIVlNK#@N+nXN$kN4_7^r@)?dKYvUZh4 z&oPY~xQ}Z+d=j&n`6)9Wq8Sl83!BZ%Htt}myP@|4Z!>eQ*l`c{xYXUysH(Z@Z`*abl4|SF-vOO=J; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + Blob + + + + + diff --git a/mseide-msegui/icons/components/tmsebooleanfield.bmp b/mseide-msegui/icons/components/tmsebooleanfield.bmp new file mode 100644 index 0000000000000000000000000000000000000000..81d3d232ed2b6119aee6898d3ec91be5065fa1d0 GIT binary patch literal 1782 zcmd6kF%H5o3`Nt0ffMuyoPYzcb7j=~u(O7*7(H30LyQ?}HPLJG|But&?yplDb=7>) zSU+PK)Y_)~=h?;(YU=;1NAJbQdQnKFumiuPVFwPLGx;~U4iN5D%<*>5Iwic?xwHY; zx)*ysLQd!*v^RgR?;J&0S%_vn3t(H4p%M63&uFj%yE#5;CP$i3oTzn<@ETjB4FF>b iumdSOV(b80DZmb-?1-@gY^4A@kg_AjE+{@^*5M74TsNBl literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmsebooleanfield.png b/mseide-msegui/icons/components/tmsebooleanfield.png new file mode 100644 index 0000000000000000000000000000000000000000..c088ce03a95433e085563229295bf5097aae5da3 GIT binary patch literal 413 zcmV;O0b>4%P)LO0{5nSZ&A})esMMMz=07(O25E@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + T/F + + + + + diff --git a/mseide-msegui/icons/components/tmsebytesfield.bmp b/mseide-msegui/icons/components/tmsebytesfield.bmp new file mode 100644 index 0000000000000000000000000000000000000000..fb3b0844ce787e74182d6d0ce927b8d4d33b5a1b GIT binary patch literal 1782 zcmeH_F%H5o3`NVrzzH}4C*T0=Tp1y8C)Qx)m!~gBqNHJ9Xq33Wj{Rb%y^2>c2!N&J@y|5tr{4n{BGPz8JwymAR~ix#5x-3i2vt&^Fe6`(e~BLdH+rG6JX+K zJ9a&uGD5WRLXpTT5IiFsL1Y&>6q$sI#3l~@l%+=K!e6BmN0EdLYRw1jtBQ@uctTH<2R1qMyvgPLXXTAzS{Ewf$ZRu literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmsebytesfield.png b/mseide-msegui/icons/components/tmsebytesfield.png new file mode 100644 index 0000000000000000000000000000000000000000..9e580000634e203eba5c6b379430310f836d2c5b GIT binary patch literal 591 zcmV-V0yOLllH# z4MAHFRAV$XMMEJ}lGM;3LFCjFDA;fW2_guC5Ua%~#0vc z&=CSW_wxbgx=&h>Z zs;*!Z57CZpT#JaY%p8k|Dk7pN{*alI5wW+Hdl)k~SMX;XTH2zQnK@k6k0N3}j^HM4 z<5Y>iyG%zzVhX31JqHo73q5#UT=xpufua(=U}IU2U=JQ=<`52ICw`j2SIl7+ zZ*gg{@1@T}xKqPjcwf}D<9?}n1P{>oF@wzPL*H_0YSxPWMNsC@iMGs~$H|D;f^V5Q zw-7bG;%8cKS2r$WYi2&Hzst-D^EEuXG=EJ33uj^wPuCIqi>*nJnIA3m|F`Vlzpk53 d(9-PRmhY + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + Byte + + + + + diff --git a/mseide-msegui/icons/components/tmsecurrencyfield.bmp b/mseide-msegui/icons/components/tmsecurrencyfield.bmp new file mode 100644 index 0000000000000000000000000000000000000000..1a6506d0a1d6b40e5d539b763ee3d3aedb288eda GIT binary patch literal 1782 zcmd6ku?+$-5CorufC?yq3Mhb_mJ$7slbXW|qZ2Ev)0+V6?VrEhJ=^-z`MzEHIL3O2 zxqr<~r)9Z@e%onwV=V1=vXqq9VlnL!*_*Nr&vpMAzZ(N(Sk=w9y3_jQ#x5FQ5E zsL* z*T{zvzm?}3l{kPIk3;Stl{nz3N`*L3Nx6qO;GRl_I8aHshdAJ#N`*L3Nx6r3z~tl2 GS63bq6&Abz literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmsecurrencyfield.png b/mseide-msegui/icons/components/tmsecurrencyfield.png new file mode 100644 index 0000000000000000000000000000000000000000..23328bcb1db0bd4e61318d996ddf8c020a8f8b5a GIT binary patch literal 525 zcmV+o0`mQdP)h zGV^LJuyES?rJK*pRrkuDj_cP3>Rv<1q*D|BjiDL*4Xj-_|A#?q+|QO@Zw!D+adE9} P00000NkvXXu0mjfBO&0C literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmsecurrencyfield.svg b/mseide-msegui/icons/components/tmsecurrencyfield.svg new file mode 100644 index 0000000..2969aac --- /dev/null +++ b/mseide-msegui/icons/components/tmsecurrencyfield.svg @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + $.$ + + + + + diff --git a/mseide-msegui/icons/components/tmsedatasource.png b/mseide-msegui/icons/components/tmsedatasource.png new file mode 100644 index 0000000000000000000000000000000000000000..f9b0dc66fd12094baa261f7167799f5d54febdbf GIT binary patch literal 392 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ zFuwp{#;w&s*+44<%I^UKo8_eF+vEef#OqS#=_e}LhHPMllhzoawC2jbm%J=TOyoYt8f(SF1Xs))sfVe2txZNrgRDSX**tW0>N3h7_hK_C4AYpNLJL zxcZFFK9?Hd?#Bm8Z5`tFE^tk@`(AUt_ve+*wmVP%_PWx@JGsnM_1EjhcaxniYhBRK z-|NlgZO`DaT}*rW^p(H6^2{RdDS6s=)+#1`me%+5KQeobeB3ABqQVyklVo?qbe5zR h&Ykzi{+q + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tmsedatefield.bmp b/mseide-msegui/icons/components/tmsedatefield.bmp new file mode 100644 index 0000000000000000000000000000000000000000..cbfe62e008ba2ba70fe97cb543c12e1f3b7e9e47 GIT binary patch literal 1782 zcmeH_F%H5o5Coluf*0foynqML^JT<;($kv72cwlE&3rLjwvM_V zwCCrZ8kKTYzU*VSLfz``)}_|LE51cdMix5oT{m=K>*Et(EP$ut*Dv;Xc99>^0Z*e3 zZ$7j_2e1Mwgd4iNoMpLfI21Q-jjo{#icUF1h}z|%aV19{gg(E(5Mj1J^ouS5qt S%`-ZXcfAr_FnD>}LB0bbz-?s! literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmsedatefield.png b/mseide-msegui/icons/components/tmsedatefield.png new file mode 100644 index 0000000000000000000000000000000000000000..9f51f3364622b96b9e662dc5a5c4a9748514aa93 GIT binary patch literal 334 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ zFuwp{#;w&s*+4lD5PeZDo;Le>!j~kL^$r^%dfgt^&+_z9;z$x=Eo5uI zagI}3>KuDB?>5^%&AqDU*2)M5vw2)j6H5ME_y2{Lq1it_#y@fz>An*}7_;hrFq}*K zc82@O$^?!#4ZIVW!aa*UzXmWIxOHY%+BLRSd$i}bvDg`Iwl-jMnePrIJ)V)!TRkyIZY Z_ivGPyw0}Ij6iQOc)I$ztaD0e0syi%e!~C& literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmsedatefield.svg b/mseide-msegui/icons/components/tmsedatefield.svg new file mode 100644 index 0000000..a8147ce --- /dev/null +++ b/mseide-msegui/icons/components/tmsedatefield.svg @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + D + + + + + diff --git a/mseide-msegui/icons/components/tmsedatetimefield.bmp b/mseide-msegui/icons/components/tmsedatetimefield.bmp new file mode 100644 index 0000000000000000000000000000000000000000..2fb428c3fecfcad4ac4d9e424863e4ac68d35c27 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjf6WEKV1+>9KlQ-A|NkjO5Vrsgp#;FS!x`k6 z2GXf!ZMeO&6RClSj}%DKvB7ib-XRnu9;YXc0a@Gbus%9ZZre0CK=Uk^lez literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmsedatetimefield.png b/mseide-msegui/icons/components/tmsedatetimefield.png new file mode 100644 index 0000000000000000000000000000000000000000..c9fb46b0082b363b0538aec3efa9d6f89dfeeeb5 GIT binary patch literal 425 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ zFuwp{#;w&s*+4?qN?zn4+)NVKZPv@j>WeVqxZiOHHya)=W^A86S?R&nTg59x82dt{{_J%$ z)l)gk@Hx|x;a*OCYVMRR96sq=er>zoel(*=_JLRiW4MF+rIkx|@>~eCDrdA=`dX~O z!pw11@$K7zi;NdAzB%f=t$guJy$yN4i$$iT3OH9y`qo(OS(>0_`*hjccmCDwvnoz* zlW!DH0ER&617&_0HI)vLhJ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + D:T + + + + + diff --git a/mseide-msegui/icons/components/tmsedbf.bmp b/mseide-msegui/icons/components/tmsedbf.bmp new file mode 100644 index 0000000000000000000000000000000000000000..2a1c96a9951188610d4f09353cb3a8e631603cc6 GIT binary patch literal 1782 zcmc&zJ8Hx*5LLhg5w_SeN620v2S}eoq}+Su2x+|pgSIfp-Ckjf1YB&P!j1Cgk;w+-@Se}tU33N_~)H`oX8^oeL0u0ZN0wuQio|C(M!`Z zp1nSn%3iR6%D8%2R$mL^UBLMd_bkid;M z$kh{$_hBEzX&t5>rWE&q;7$o!`3Mww!Q>ksu9{* z=%v<*LmRjp0yV07*N=RTOa_#Oe2}_;Ld}_OA#({QbljgJllqf$+|`i0a4_ZmII&6z zlYvmtXV=5I;{T3|&{aN!oY)YKmYKkiLTWDaiH?WCuG?%kKnMkng)ZO_AI8xheo%7= zXZ-JTkP}7a$W)he+8@Ml9Ca}WEShJSlU+E2U&m_;uz;7>| MO5lZx1?MXA3mJJwOaK4? literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmsedbf.png b/mseide-msegui/icons/components/tmsedbf.png new file mode 100644 index 0000000000000000000000000000000000000000..6d421731df56825b5b21c5995d52d556738318c4 GIT binary patch literal 469 zcmV;`0V@89P)l2u>g?tqb%{$65-3^Ps;_IivDN8vafY + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tmsefixdataset.png b/mseide-msegui/icons/components/tmsefixdataset.png new file mode 100644 index 0000000000000000000000000000000000000000..4b6cfac912c813c9f4e783cabb984c290cc8a2fb GIT binary patch literal 435 zcmV;k0ZjghP)s$5e$Kfc=f7N`byGu;MHN_{ zSL^qFft-~H5aJ9WP7%UIh@%z%@aOEhU4q~VfFO9pb^Szukw(_K!*b=geBY*CzreC~ z84T_j4&`QmER{+{dc6~BHN|Mu#59wyN_~Uxh}LO3eZ@2lCX<)co>YL=9kjkl9Sp-6 z-R>RZ@j3neh%kKH46sg7^oea>({9_Cra`N9jBQ^MMIV0y@Vr|bXP;`d3_zt)#&Hht zysKER`1c>pP-+g$^8)}#xkJ**O1&ec74ui4Q0f^e_hSBH{vrQ}M5EErc>=Z(WojEy drnV7f>I*bCcZ)m84A=kw002ovPDHLkV1lEfw*3GA literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmsefixedataset.png b/mseide-msegui/icons/components/tmsefixedataset.png new file mode 100644 index 0000000000000000000000000000000000000000..4b6cfac912c813c9f4e783cabb984c290cc8a2fb GIT binary patch literal 435 zcmV;k0ZjghP)s$5e$Kfc=f7N`byGu;MHN_{ zSL^qFft-~H5aJ9WP7%UIh@%z%@aOEhU4q~VfFO9pb^Szukw(_K!*b=geBY*CzreC~ z84T_j4&`QmER{+{dc6~BHN|Mu#59wyN_~Uxh}LO3eZ@2lCX<)co>YL=9kjkl9Sp-6 z-R>RZ@j3neh%kKH46sg7^oea>({9_Cra`N9jBQ^MMIV0y@Vr|bXP;`d3_zt)#&Hht zysKER`1c>pP-+g$^8)}#xkJ**O1&ec74ui4Q0f^e_hSBH{vrQ}M5EErc>=Z(WojEy drnV7f>I*bCcZ)m84A=kw002ovPDHLkV1lEfw*3GA literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmsefixedformatdataset.bmp b/mseide-msegui/icons/components/tmsefixedformatdataset.bmp new file mode 100644 index 0000000000000000000000000000000000000000..73c6334dd67f590855b018c8206a07840053b3f1 GIT binary patch literal 1782 zcmb_bJ8r`;3{?T6FwhJ^r;Z()3-kcpdxRdK_v`AQFrW+ulr2}t(7{6n4PM+wKAE;` z11XRSG(++8_zCs)9`Bu=SMV2nPwBf;$+>UXA0POsqq6??<6IAt^YNUa@j6wS2EtU< zuq!x*Z-6G`rVPgtnUChmO8pBCqprpp6b0p3J*zkqXR#ZI$x9q)NV$)M;}BuyLuD_2 z7U=e4INYYPEN!jI!r@}HWxkF~B6Xby{GIltUAe68Zs0J;W1$kf%6( z7pW8rdLvH7^w!qC)A3=jv^{l6R&H1dF+oa z!)!i&ios$5e$Kfc=f7N`byGu;MHN_{ zSL^qFft-~H5aJ9WP7%UIh@%z%@aOEhU4q~VfFO9pb^Szukw(_K!*b=geBY*CzreC~ z84T_j4&`QmER{+{dc6~BHN|Mu#59wyN_~Uxh}LO3eZ@2lCX<)co>YL=9kjkl9Sp-6 z-R>RZ@j3neh%kKH46sg7^oea>({9_Cra`N9jBQ^MMIV0y@Vr|bXP;`d3_zt)#&Hht zysKER`1c>pP-+g$^8)}#xkJ**O1&ec74ui4Q0f^e_hSBH{vrQ}M5EErc>=Z(WojEy drnV7f>I*bCcZ)m84A=kw002ovPDHLkV1lEfw*3GA literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmsefixedformatdataset.svg b/mseide-msegui/icons/components/tmsefixedformatdataset.svg new file mode 100644 index 0000000..b42b4a8 --- /dev/null +++ b/mseide-msegui/icons/components/tmsefixedformatdataset.svg @@ -0,0 +1,440 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tmsefixedfornatdataset.png b/mseide-msegui/icons/components/tmsefixedfornatdataset.png new file mode 100644 index 0000000000000000000000000000000000000000..4b6cfac912c813c9f4e783cabb984c290cc8a2fb GIT binary patch literal 435 zcmV;k0ZjghP)s$5e$Kfc=f7N`byGu;MHN_{ zSL^qFft-~H5aJ9WP7%UIh@%z%@aOEhU4q~VfFO9pb^Szukw(_K!*b=geBY*CzreC~ z84T_j4&`QmER{+{dc6~BHN|Mu#59wyN_~Uxh}LO3eZ@2lCX<)co>YL=9kjkl9Sp-6 z-R>RZ@j3neh%kKH46sg7^oea>({9_Cra`N9jBQ^MMIV0y@Vr|bXP;`d3_zt)#&Hht zysKER`1c>pP-+g$^8)}#xkJ**O1&ec74ui4Q0f^e_hSBH{vrQ}M5EErc>=Z(WojEy drnV7f>I*bCcZ)m84A=kw002ovPDHLkV1lEfw*3GA literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmsefloatfield.bmp b/mseide-msegui/icons/components/tmsefloatfield.bmp new file mode 100644 index 0000000000000000000000000000000000000000..e018ad161c9fd9368a301d6226340891d14990d1 GIT binary patch literal 1782 zcmeH_!41MN3`N6*LnmMaCSZWxyK==o+_?r5w@=oO1QzL$s0q)+?>7p}%kx~?xY>HO zdD-TvQ7L!Ze@s4Gqb>EgvDP~H_*pDuWS|4TrJ)1=oOlCV3t+qZ-|GG8%@O)t>p=%Z z^fInw#xK!4nJ zFuwp{#;w&s*+4sPV`>+M#}J;hMUT){Mp*{qynj>{3L4g7QXE<3W{ zV2op9=xdz)?}una;PZd8q+F*87BVcDw#@xV?)}M(?gvs`YQmU8rdsjFFz6<%K4EO+ zFqd&%gM5Oq(!Q=5=ex{XSL%IPo_>IRL#!Cz;qn4Ln-$j&=zZXQ^YmPnrP94mtdU-K lO)A%^H+*DEDXovLW9$p|*vFolpal##22WQ%mvv4FO#tW9lzadH literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmsefloatfield.svg b/mseide-msegui/icons/components/tmsefloatfield.svg new file mode 100644 index 0000000..e95d0f4 --- /dev/null +++ b/mseide-msegui/icons/components/tmsefloatfield.svg @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + 1.2 + + + + + diff --git a/mseide-msegui/icons/components/tmseflotfield.png b/mseide-msegui/icons/components/tmseflotfield.png new file mode 100644 index 0000000000000000000000000000000000000000..77eeacd64444ae133ff72e051cdd54e5b9728bff GIT binary patch literal 395 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ zFuwp{#;w&s*+4sPV`>+M#}J;hMUT){Mp*{qynj>{3L4g7QXE<3W{ zV2op9=xdz)?}una;PZd8q+F*87BVcDw#@xV?)}M(?gvs`YQmU8rdsjFFz6<%K4EO+ zFqd&%gM5Oq(!Q=5=ex{XSL%IPo_>IRL#!Cz;qn4Ln-$j&=zZXQ^YmPnrP94mtdU-K lO)A%^H+*DEDXovLW9$p|*vFolpal##22WQ%mvv4FO#tW9lzadH literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmseformwidget.bmp b/mseide-msegui/icons/components/tmseformwidget.bmp new file mode 100755 index 0000000000000000000000000000000000000000..e6b9c7434cccb02670b156ab2b3a0fab84aaae6b GIT binary patch literal 406 zcmZ?royN!j24z4}1BfM{n2~`6EUo~R2Xjz}1_lNoVrXc9P(TvM1mXsU0|yQOCH{jE z!~g#v77zm=NC-%DAc6LBIH>4Hh!1@>+*{=p{b!)yd;=1jqoN-e7*Oy7;q{IV00CaM AnE(I) literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmseformwidget.png b/mseide-msegui/icons/components/tmseformwidget.png new file mode 100644 index 0000000000000000000000000000000000000000..9dc6d418bb756349856907f6dfc12db24c044673 GIT binary patch literal 386 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ zFuwp{#;w&s*+4x^y1~u`h2*GM+KRQvcyA<{vzM&t$y{ON-8`S(LpDD->L* zab43RYE9Xu3o`A~nj*YpH{F%zdw$^jPkW2wLV}9!HyPf}He5LW(o0L5mqrYCcXMlP zWqW$cE?SknA@+I0`G?%0SO16>Z7Sbu5|i!AsPH8?rqt!da_(T46`IpumK=)yKkbm) z#P+;ylbz|GZ2t+1u`otuGuWJuK4a#v{CUHFi`T`na`OX2eccYHZz~sxmtSvkC)lmo zZuZejx70VexUBhg^%nQ(lFEPkq$a3vDt&r?YE#Zq`Qsnouvea9;5h(B3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + Plioe + + + + + diff --git a/mseide-msegui/icons/components/tmsegraphicfield.bmp b/mseide-msegui/icons/components/tmsegraphicfield.bmp new file mode 100644 index 0000000000000000000000000000000000000000..d210dbfa5a91071cf050c040509912a4c7ddd3f7 GIT binary patch literal 1782 zcmd6m!3}^Q3`Ozc!3i9}2^_$?J2{zgAMalAOG#5j(X__c6w*X^{C=eCm(qo3F*g`> z97U*{oA7EX>GZVYeJ|oYrUO^%wuOuT=ooT;O!$0B!pQDMrnV z7y6i5>e@Cm0a)dYvrPlEH9f`3_Ts8(uDCrcMeQs_E&u3wlL}h*4q|0{5zfVABb=ml z&tt|H?*0cLRY56k##Pg6Yb9s!^~s87whl;DFtyyrIlBkKNtB#H$t7m|?rmL!G9cw{ zF6!cap`D|d$CT7bru}YAGslMdHBL8@LG20vVp{m-Cp|X}HWptO6NL{9Pd}P}H#@9? zQ!n;cRj`?}dNKCv70+hx`yb6wL%OPwJoPKsN=z<%b`L z0BmMHlmU0X-q0^|&!gZ_$QgM%K=#{t6y;ec`>av*ddh#>F;u_wS2n4W>_Y3$Of)CJRcJLra&t}p7G hzn37<6g&Of@)ycBI0!3|&wl^_002ovPDHLkV1nHMWFP + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tmseguidfield.png b/mseide-msegui/icons/components/tmseguidfield.png new file mode 100644 index 0000000000000000000000000000000000000000..baa50bef4e903694eec5d26ed1f6d09d8b7137d0 GIT binary patch literal 551 zcmV+?0@(eDP)cwI!$3EDNHd@KY$8iz{*DuAz>|Uk6ey3HXaCOU}5L6|NqSF zvb&8^TEzfm2T1X_53hikQ<%5ltO<`+D{Vn2d89D~f9$;^W|*X8ey9ql0)#?QKT z3Ex-JF0GQ8v|IEZN2)%8+jv^_1#GJ06As}zrf>o;wOc-p<;+w{Yvr=b%sE`a{fPLW zeN=bjat(QmdF|G{?M^>4XEBR6xQ2HfU!#;(>AkKaVlx(d&wsUl%gnxSNJNZg=8ulv pY%Y|(1b<7`--G{zpfTug%P)DDk$65<^=|+G002ovPDHLkV1na_>}3D| literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmseguidfield.svg b/mseide-msegui/icons/components/tmseguidfield.svg new file mode 100644 index 0000000..527346b --- /dev/null +++ b/mseide-msegui/icons/components/tmseguidfield.svg @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + Guid + + + + + diff --git a/mseide-msegui/icons/components/tmseibconnection.bmp b/mseide-msegui/icons/components/tmseibconnection.bmp new file mode 100644 index 0000000000000000000000000000000000000000..986531b642f9e1c3337f0baf787ac7da194f5111 GIT binary patch literal 1782 zcmb`HQA@)x5Xb*XuAO#O*UrsN6a^6kLG~cBz4+j}%qQ_FtUciX09vsTXHxh@?9a#G=wd0&&hUVlG@j6 zAnddD9L_3Rav1df#Yy!$;g&on-S%-X`u+lskS%bY9-Cw~)o?e&nK4=P>K~2Iabp|>IO(6H0AQmNZh-0Wb$XkdhKHl}< n9uPs@K+QpO$iv?u?i4r$UVvxd5|{z^z(cXa`}XTN@d|?>N>BTg(4xW={u}ZTlJP^Z#O-<*^>P^e?3PQbElANk?UJRP3Jm;Pe+)xAr5BaRbVJ$VrY;ZFz}``P4w(si5`h~2^TND=eH zv)SM;i6yseJC&!xYw^>{X<0{&vDMw_T)bJpeQWOq>*Jh&vmuH%F# z^SwyA&SZYaV}wKzuv}WUEqTa$mo_3)8_QkC(E!#*Ih$D5c9QjN<)MBaDcRQuwP?un zQs|@aB@v6^Y6j!Hr9c{h>o^@8m*ogxgqI5-$xt>Ey&Qfr%G{FRpV6NClgQoL&rnU0 zGHBl2m!y6Ylz?n6g#>(*n{!yxCjzbj9Rmq`;}!C1}2$|R8wgalAyVs!kD2R zG?pRob4i57Nm-mc-g|?2;Q;!^=5iw$G>Jm@{mMCAcCoeMg5^BYNTyC9O;3~z))pN= zvuNo8{5*KZU9@io-<$K@^+AWT@>f~`730H{ZP|88m)m69CMHQJV6YlulAu%ZdboPe z1uXLPENg4deJu3y@QdrjopxTHavi7nrnFR&NkR$mVVblHMZ1V6Uzt0N=OY^#tx}`G zSaJ=V5&Pp3r$!1$R|zN}B$_0xD0~{mc~hh0v-8riy<$eG>)mzd-8gpfoT$#C5_?_t^#T5i70Zo%4e*X-eumgUMJ5{Ef>4rR7Ce?&CMIc1aAvt)b+e; zK(n|Y`AZxlBp^*sv=#&=129;RH#bNVNvLo-28(ADT-%e{09!KR5C>rR;XwuXOQgz=hm`ZbpyJGK5 z(=DwyVio4@ATu(LA>IU<#3s(lDjMS#A7ci?Rd$z1EWSZr;Fw$qosV6ETuFapG6U3| zBrBU=%&+-Pba1Qo_omXVX`n`KcE1Ro0FVG~S;aZd$&EAv5uHdMoy7@b4;Kah*$izp%|1IC9!@PqO^$h4dE{NChi2!|Wnr&~DUo;#-@>$n$+B?H>U#2xZumrze zPFNhkppHcK8a_RsSMsp9OpDw`i+m~eH|tgaZhZJc&qj-Kq|QRB50Gj^eAVI-O7235 z58XW#HF4)X33MYk2(1IaU1*(*5Fy|ULhN%Lr=hppe*mwJ`FqhhJDC6g002ovPDHLk FV1ng;WBdRB literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmseibconnection.svg b/mseide-msegui/icons/components/tmseibconnection.svg new file mode 100644 index 0000000..3725773 --- /dev/null +++ b/mseide-msegui/icons/components/tmseibconnection.svg @@ -0,0 +1,432 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tmselargeintfield.bmp b/mseide-msegui/icons/components/tmselargeintfield.bmp new file mode 100644 index 0000000000000000000000000000000000000000..069f373c66dc918aace54d09c395c3b9b5089df5 GIT binary patch literal 1782 zcmeH_!3}^Q3`Ozc!3i9}2^_$?D;xLm?iGKiejAJ=6ur?v^TThS*f7m|>q3mk19pGz zCMf4t_**AC6e9WWV)4Fk$z1>`3AR(%Xl$pb96bS!Ma1=>?ickuVY_~K5eGHeeba){ zu7QJg9m2G64EN!ur570|1`gY`5EOy1(*K15T^ymb6>(rmBwA>pk~-q>JXcgsdSZXf M2h5U{zHpX%0QZ(6umAu6 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmselargeintfield.png b/mseide-msegui/icons/components/tmselargeintfield.png new file mode 100644 index 0000000000000000000000000000000000000000..55c1a60c116d7efeffdf11314b990964edfbd2d2 GIT binary patch literal 479 zcmV<50U-W~P)}&*xp|5EW*6s-)oi@VLYxQz&{E|ayH4aiMG?zOp^4H{PiYITfr{Q4TG;G`GR*z zHj^w*m|wzo^yUGKg1dNudsTG>Z}DKP{{)_6>SOKB0$?3qv6JLtRXv^Pe~edHn`Y2< z$SXLG!m}h>N!Et5zlrlz^?H^;8{i}^<7!piz#BYF(!&$nZ;5XO{J>UK{T$Xm;5zQ& z0ydNE;tW0|S(z8`5vxg7hxI%7jF&^e`mhXe3*ROUW*%}??I(GJ_eu8g3%9H400*OS zNg52Q>TuGd(=;1RTe?oNgi}>Dm^E%v{r+Clc1=esIrL{6=GK3j?2Z8A>MZ)(@*8Pt VWRir;grNWc002ovPDHLkV1l1P$}#`| literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmselargeintfield.svg b/mseide-msegui/icons/components/tmselargeintfield.svg new file mode 100644 index 0000000..5cf59ab --- /dev/null +++ b/mseide-msegui/icons/components/tmselargeintfield.svg @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + I64 + + + + + diff --git a/mseide-msegui/icons/components/tmselongintfield.bmp b/mseide-msegui/icons/components/tmselongintfield.bmp new file mode 100644 index 0000000000000000000000000000000000000000..eba265d0aa65d660a106cb4ca59f217eed922144 GIT binary patch literal 1782 zcmeH_!3}^Q3`Ozc!3i9}2^_$?D;xLm?iCw~KTTsuv3i40(iZyoG%V}chcsqdC$ceH zm%I>m+CK)ibdZ+#-PmGuPS!#Y&p|3TzpD zR#oOm<&v+ipwP(Sw@9o)SvZdnWoiWe PV}JCAn4Vb{T(x@vg-;@| literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmselongintfield.png b/mseide-msegui/icons/components/tmselongintfield.png new file mode 100644 index 0000000000000000000000000000000000000000..b42e093f8cdc5b0629c976b9da08c9624ce9f92e GIT binary patch literal 501 zcmVN&;|Q(} zTR1X7k{Qfa)qAWbxrc|inPfK}V-x4AYGatjb_r&%)K`jU@w9C}!Wu4aB@UgYS!@Ph z(h literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmselongintfield.svg b/mseide-msegui/icons/components/tmselongintfield.svg new file mode 100644 index 0000000..4363401 --- /dev/null +++ b/mseide-msegui/icons/components/tmselongintfield.svg @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + I32 + + + + + diff --git a/mseide-msegui/icons/components/tmsememdataset.bmp b/mseide-msegui/icons/components/tmsememdataset.bmp new file mode 100644 index 0000000000000000000000000000000000000000..624f2aa57980edf250247a1c9b47fcaf9554e187 GIT binary patch literal 1782 zcmcIjJ5B>J5H->Ytwf55ih=`>3vd8>4#NFtH$p2pMI@(7OPPXVixe)lF>l^DWA7#c ziH|kwjOX*_&BT6sj@ORs5&HwayZl{IbM6iP+Z+8D$SwVTIhP<<05mk!OC7q-11z5D zU*Sw6=Y^);f5EYiNL4zsqBED-RY9P}O3rBxrqsdo3#=(qZ^1FU;b@8-X90GEVti`j z4|K!P(rw!shqiGzm@L`#^8Q`v!JAVWZMO6kc0ps(NJcTr&zQnCr~=(^7$IH&La+Ix zF{)8w6ok=!-9<&l4*Rro;DFtCy8>hJwVf@q%}ZkjzJ+SY?jG_A?)ZL53l* zv(OWVSp^5)OE{Qt<}*g)qqX*1&vpb9I0cHVzTtBq85AAUUi$)y3`bhaP@Lg8j^A-U z6(5;TN@3lx0|62l4mA{R1{~F#-4LT&h*9cds!YNu^n!!BNKX+A#g!@1PH(wC9`}cr zLFc18Vtj?8ObVY%IKqcG@@GLlWH^Fznhz+|D;>qFDWxyx@_gV!I{G3API8}d6gzkQ z$2I1h58lfnKQ25am3%%uB_Y$eC8U*ir^gF?aGx88SLS=a-v(S`NVo1_37Y^`uRDmx kGr`U5wjRf>&riVmYMWd^>y&*;26lVtD5?t`E6$(npCc9t!2kdN literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmsememdataset.png b/mseide-msegui/icons/components/tmsememdataset.png new file mode 100644 index 0000000000000000000000000000000000000000..dfb89bfe9f9386c068c2d56702372873258feb12 GIT binary patch literal 539 zcmV+$0_6RPP)JW0mgKKK~YG8V&O+2Xd95==~*PvtS3Z-6ha0TmYIDs%!3u* zU-O}j$_epxuRnj!hiGzy07MqC?E|e~+xv*jQK`?M)GA7)P-+FGmME8BtF;Mid-EH+ zfyf8|MlE@I`he%XV;F6C-aEP6od%tpEE7~wW3TbNw<`NaE_bDG01%7ykjdNtkj>r@ zjhesK5Q~M$WG<@g1<`1KaDZhEkWQZiu(x+cA~C2n5t&A03Xw^=y5_Z-WsQC~F|{w_c1sj%G?i}#dDFXZ#LL?S)G4Mc?T@m`Y2 zL*nsXM5M7BjU6VL+#((y)L5hbp=AwVn(Gt_OMxazt=8HBu)V!NUtf0}JBn$}QYh@` z!~gw9GhEjLyygu6aGZ92TG@4#rBZ$~2ecG5jFzH? d(NfefJ^&MCo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tmsememofield.bmp b/mseide-msegui/icons/components/tmsememofield.bmp new file mode 100644 index 0000000000000000000000000000000000000000..630d0ff8352469dbd18968c93161d3294d5d742e GIT binary patch literal 1782 zcmds#K@P$&3-b)~My1?Ue;i`9Ms0PyxYas%#kqW>&@n pE98LMsAkTYXhsfvJ&s#9k0coZa=@$089A_A>z&92gO}S5@(YFw#r^;Q literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmsememofield.png b/mseide-msegui/icons/components/tmsememofield.png new file mode 100644 index 0000000000000000000000000000000000000000..19f8702680c04a131902a4e5265fd29794640ba0 GIT binary patch literal 627 zcmV-(0*w8MP)_gDnsbeHTqAJx>T|vI2tGD;t9fiWXOa_14s^8Fl6;gE@C!C3**I(k@I#yJjjFoe zr(eQURRufoDgNmm9vJ{|rp@sEj{Xh4Nb}ZEEgGbtNHGl=Y zoaD(q?H&9zXmD0;)1UAbzEAQj=5ZU6JY})>C-5sKt7^I%V3<)cf$#c!N3jjNa28Wb z1y~7i0pqRxZVP<4#&N2u?&53g?!3;G0aZ1RYf0X~rmC9hbB|)K-M7#_KQU|t+N?jr z`Hub@-h(8s + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + MeMo + + + + + diff --git a/mseide-msegui/icons/components/tmsemysql40connection.bmp b/mseide-msegui/icons/components/tmsemysql40connection.bmp new file mode 100644 index 0000000000000000000000000000000000000000..e1e00dbd49efbf246351065a9e2ddd70b36bafaa GIT binary patch literal 1782 zcmbtU2}~0~6#WR4upDA(RV-S97u9%CW4sV-;t@kr<4q*N+on=NN&51FrEfP|1rguXt)PI2;ijOU~ciG6SE8m`_xcfqU)Je~@GuDoR# z0B*xz03|@9*)R5VG+rEFywKm6(x>61-`=q9mL~AaZpSkXAel>F4Y1`8Pgm!r>l2%< z1sPLix*h(u1;;%f0x%3f27r5k0VbyaaO;0^I0s;;4G*Tu2-fXtc`#-_H%9?%(D#PT=3A)!zp2_i>M28c5w;LS?U{a@H1V7B8PE$NAyPk;k{r z3X=D=aJG?aw>2`LJC(hPdbpl?vYC3et?=^Nq}_9$r$^F-u@6(Dl#1bY@$D?PEgC~T ziK23M&@cAUc?aqIqo^njy-q|WXCr0=wUcPK6)g9oa(B`%qv=4IalJ{}b(p^|gR zkQOmB#9XFUa~n4emiyB$577BX=t4EEPe5|WEy>j9Fz=r-AM@DHdiJY< zZG6Z6taBrX);!|_`;})!)5VE&NeVJ(Q2A98`%YMpdz7(@xOWDS% zNs6FBveqxHSw2`=lYNNh?vfU}UMdmq+q96W&SL8BGYyY7teCIW#4%q=*l!i=kD5se z{@=-_L{3hQVxb3To}z9ZSS{h|BKG!D?~i0Y$`O10fDo# U8{vviad8n~&{4dNw$29s2ARl)!vFvP literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmsemysql41connection.bmp b/mseide-msegui/icons/components/tmsemysql41connection.bmp new file mode 100644 index 0000000000000000000000000000000000000000..71230f63e519479241a98fa52f15477265da9fe9 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDj7vhFsutFfg#m@L>iZqz_pMimV1T^Q#G-)9o zCJK!Lnsd8f>dpiyc@Y*Mk`rbo+f|~xOy3vDLeP;0aZMREHEAw+X(1U&A(G5QHs||d z`4@APH#Ztgt_x2Hu|qQFJ_7?k5*HYf=pv$g%-@%(eP62jeUaRYSqd$YVz5X+4t8{1 zSj^#P{jt&U$9miE%Qbh^E1?EBFwS)u81xw!G#MCxaRFq&4M#Uw6k-n0s15eJ8bJvL zNpS@OLkXCRt_#yW;sR_S_kfVYu4bU^$maZIVDMmIScRzzo5=rp1)4uLIQ-b;bY-S> zq@xUydw{-p$H1V+z_0}=oUbr2L@_WNLK1;`R$7$n-U|PpTikzc^WD&7h3X`rnoA4} z@<_UXj-1E9AdVygHAh5{r!?N;=XU>}J43H7@J;biM|BcV*$M^*0aU^B3=F^w1vLTA z(30o-xhw4Fo|vEelCCU?NDBZ46kHA1fe0>K91BB9lBX@z=-2*~Ux%`O9m&7EA~`+S z7^pwS*JM&vh^?_QlCfB{Bg>j-i2XX0{p)DquM_3JPSsvslRvj9{LHG--hwR?=l;35_|NT?@xcy|V8S4=c+=ik>G!#g-xvFSU!MH?>dZek=Ks01 z^v~T@f9`L%x^LFL)&2X{PTseE`o4{G_HA0QZ_ASX+g5OKaU#0}&d!Um|9xfZpKG&$ ze))5I`JcOM{@ma6=h2S8Pxt+Oe&p|~lYifw|M%|dzYn+neSY}w>oaaHF1TJe!^TME z-k!GK*XR7cx#-XB6@Tun`}1JS-^aWDJU#ID`LTbmPXBv*@$dWV|32LL_xX{lldYB} zW=i{StS$fKQ1@@JUsg^jl$RE5Eld3Sc+cNw2mih}UYr@dWyQ3=?{EJ5c>mv*C$3J& zr4vdJv9K_U3h{ywpNJqY(2-o6?4rT~liN%GzCIrx;lFahJmMiMrrF1l=L44X6YIc3XS zrdtuC!^!YL@rg)$bmZz7Zca9lL1nD+5CMssqC;1D@41(qp4#ix5yRZce@?#hKfeDz z|9>pjzja{iReFx1d%&aJiy`0wwd=$En>o^h3+>gEWn{N5;Q58}G-n(25xxH>73Fbn zA9Q`kAd?}O%8=-w=dOy6?Cr@L?3c2Q{o`YFaYoK$)W;0e|0hl@k7vKBEoa!NO=Ilq z=f5#$GN1r!fmmQ9kOH(a<~o4RU^HL_I@DZzRFLOToaf*OPu`HWJwvxF>=zgUZTlfM zGU`kT(}8&`Y6g(Yz`MYQk9l4Q={z~5^F*R2Ki;{4rlw0B+_%7)!1XF%0z`n${UKA9 z0WSrtUA&)%QWYjSH~Bt{YI+h>0`!Np01*Mb8!!ZLSN}dbUp+oac7F8YlRTwBD$ovi zfknVFpc$Zl&|fg+;RD#G`Fdr1XJK+@k)?X~#D!C0G$t3zI2}j;ma^wi!r(xAzXx8? zICmL&uHIqu7Ekk@wia%FO;ZwWFRlE())}CE-p4e{f%RIGp>IS++Ia67oA=yYSFUyO zOgd$M<@B5e!~riep@mURBQTN8-3C0+c=|#TOi^CvJa0*=S4giuuwdyd+9;KZ75Mn7 z>bn8410yn*j1|u>7E70lWh<&2Z@ryjrtzuPabK>TlV~2Mq3tGIYaKVLpIG{icyX0@ z=>zfdx~iiq_HLg4^WhAsD(hnY8mncD*7@0ZUHSy^(i*XRgY?T*sp38#u$$hXSm+ds*FRw#E}%00KzaYK378qRTQtO_QL9bR9O zDb?giwRyztAoa&dW3hbGNm?$*w|-D=mn(NF<@Oro-gTv;X{seLAzu5_9zD=J+SFXS zO=52;$XaDG@>}13Q@&Xuw|*zL{kVGBqGCt3++M5PZ%`gIPqj=|vp)rbgM)Z|B$FsZ z-$-iZ!b17zKK73@*qgg^jbrkdQf$v2+)k3G>;NsR*^3^lFBFby4 zxI#-Sb9;;PcK`sX_;G>B=;)1psAN)z5-Gm@bqG70PoZmH9p_370`}@kX0Wy~x3?&N zKsxm!rUU-IIAAjrp!01PF1)rG0ASK6alQU!Y~X{S)$5(mnJ(oGAfJb_$@sNVnGxO_ zy;!N&U`?^<-$sR0f~$L7sE7`VtfYJ$`{1kH`8fc9c;s_UGCY54JesrFQlP?-x=Kzd z<>XLk4l%b^k{5t{o;gwAlbMGI_S87Ao<(Gwt;z|t?xXx10N_B`1@YnIe)fIHI>*pIYeBAUo4{BqYO zl*LAg*`IN-56?F}HXz0GiFi6Ap6MDuuw)(Tn%e@oghg64_BxB0mWfKac|{}hG{5v% zfNU~;+0S$0#ove0EIya;D^^&)=;(>(5+C07ERNP_IjdT3Rog0BS<}~NncJ(lw}&nL z518AlR2s~kX_dZ=!jos9)a=r!RmJ`T+YMHoI_EL;Pessh`8K*^TqZp`(IZA?ULl_+ zl+ywEJUl-)`yx#RchiY?K0##K6`PNa?Ks!Q=Ug2?rL_=EFFXxLCM;#fl{L_rt}wS( zo)fSLNz&>49gB5{;*m`wq3E5~KLTL@_dS!wtKE3LJ&0k6K|n^B0pkiFkvb%707*qoM6N<$f|3{Wo&W#< literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmsemysqlconnection.svg b/mseide-msegui/icons/components/tmsemysqlconnection.svg new file mode 100644 index 0000000..dbd518a --- /dev/null +++ b/mseide-msegui/icons/components/tmsemysqlconnection.svg @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tmseodbcconnection.bmp b/mseide-msegui/icons/components/tmseodbcconnection.bmp new file mode 100644 index 0000000000000000000000000000000000000000..8ef254184f70d66d613a4acc3b3218450623f70b GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDj7vhFsutG5LpMhZ%4XzN--6H})ltc~C1o;{v zf<~1|UxcH0(V0L5=K>iJLm=iTUls=k~u*0k&Oa61I-+W zrwF{oV}CbxmL8B3ImuZ+v9=Z4~!16nwePCL?p=4K_oxlOrdnsjFs2M`qP8&4br zdJWaTKBGY}sCZ;Py;5=l5Lv~6>WKNaa@wo}YJm5K>aVdi`0e5nP`wmk0Jlm1p^=$Q zDNrHMVW@uZB7>GTWv76X8T6tEdVyC!6qr6f9CthAqCwdJTv=ey+N$K4k~>%*%M^m6 zqigVn9_pJzkM!-UJQVI4PXtS2GT)|{Lx$=vf!Q&Q + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tmsepqconnection.bmp b/mseide-msegui/icons/components/tmsepqconnection.bmp new file mode 100644 index 0000000000000000000000000000000000000000..83e1f6bf0100c76a6cfc0ed35674dd0b9957e75c GIT binary patch literal 1782 zcmb`HT}xs?7{|>tSC8nbkm73D&H92;7opJ$*-8;@YDsjV8>Xy?hy_tn!fNl`RFtr+ zg|;l3!mGJ|Ti70t z_XG1vhPVSQCk}b&k{G2ncnLY@y~mEd$+f@FQ%DHrf4*Jetv$#K2E1o zAP_WL@riN2-+y>`NFZpBkB_^$x}MNCn;IG#dKFH8fB*k*gn|~E)nd2XA90e&q}S`6 zU>}7-(JYG2&Q7^pE@c?qJM|s=#9}e7pWfbHGLE*rz5Q3KtQd=i6Nv==UR+!(EG&fQ=f0PVWVT+f z`+UCX>FG!$vcA4PIy%bbpg!q}mzS3ahj1{M$zuCK3=XK(;47K`u`kH>4Z8WCW;udfeq!YLFAG&H?dzOk{v<-iXLAQTGW zNWv--OJ~6`7!0Ti(2zRtv8}`p!-(LPD&Yq^rO{}tRx3V16xcpGo6qL~7mLLbiNsd3 z?Xj`3lamwd4*pUI>0Di1A#j_`mdT_c00#v4!KH+3aK$i>G@@*{PN?AE-~g-Ow36hn zt*tQ<5lN9&tKHwd@EKd#MH)X Gb$$UM|H3N( literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmseprocess.png b/mseide-msegui/icons/components/tmseprocess.png new file mode 100644 index 0000000000000000000000000000000000000000..96dc6c159f39edf3f1b5de460cda5d691f29bdc9 GIT binary patch literal 1032 zcmV+j1o!)iP)6E28weG3qh7ZHfdAG{V=3UkdQ zH`|Q<$Ym}^)0t~Uk-SB+7C)2>XW$HRhO3-tfy9uOQe>Jd6%Ax91iSW`NP)o0c}-|F&j%X*`s?bkom8yzER_=?CLDGi#G2JNf5mdftlF}0)9x({$F z1w}`z6O+?lkwQTT1tA~oZri0x1tFMoCWL~N|A>9K!b45dA|WY#7@Z^_FmOodl^o#W zrH&f$Vy5{uJwb%sKIN%b@~Te`u276d?};x?wR`LK$e-7?e+-~$4(xUt4u>75)A_$u zVQ?wguW!WeurY6*2M&iFFE4N2eeV#I`a*eT38LMAIBhOpGxzGwr@SK0Z1pq0KhM6#Nff4(ms zo<^)z3x#>x&@?-1(lSU%P3KU>2l)D$5JF*hZV8Vr523p101XYb`1=PE9c^ZJZt?6E z0h~NhfzJY8hKB|i9vW#?AwD4mMNt5FJEsUC6waM%P7r(d*VVf!Fq@M}OiCkg zS;(w*N%^2qAta$;k=z;V2cWa_1_1#<#F*o-Si0Tu2g*yhckk}p7X2I9l)06{f}K46 z#A?nqeMx@7UVMBO5E~mue(o+zriJwN^A~1S+ z%_5AZ+4;lLMPziWn`pMbCb`!36S1-JEMC0CO|-tg9>(t9B|ahfA=xNZq?Fp}GhI>- zCJRBSuD@w&O3W6qZvE!-dI4Am29}Df?R&231puIHi!NQhc~IoM`P@dm0Q~&}Y@+*C zdxTy9gM(HN0B2cwePu&auiDsrTXl^ketwHa&bRif-(46`^9st{V@yKglWo6T8&a=c zA6B2;klE@QSGMoSZuqV1zS`A2szyXa^+;*Z0O#L7Fh=;Cn~XaE0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + Proc + + diff --git a/mseide-msegui/icons/components/tmsesdfdataset.bmp b/mseide-msegui/icons/components/tmsesdfdataset.bmp new file mode 100644 index 0000000000000000000000000000000000000000..f895f0ecee166ff295f1ca18e8aa4e6013867851 GIT binary patch literal 1782 zcmb`Gu}&jF42B0OLMuTLU3JAh!0`e+06h=F`(3*ciZm%AO}ey{6ci~arr2iqY)`zC z-Ee?lR=&SND2T7+pC`mj(_7QS z=1Pk*NqNtlgWzd#EMSt3(>(6~3{D&Dy5pd@bAs0L@fc5R8T#o2!ORv155XR9`rLF+ z3pl}PkG`Zkj@_oN>-<`Ei-6&>B(x#SX-!#(zr{(r#F5Y#WGgw#K9sagrl4E1V%i!C zfT%4_8L~Mg#6UDSuKH}q?D$WsSm_a`>*6Mw^XB2kg~YUpg7=z{%EzFz$`nUCs(c7T z4u_(hrM2Q{)`-LDIUFWj`3%{~pb)#?Mr}tx4ToI{DXS0oJS!QB4rOnBfg;1HtqGLQ zaE=pqI-ePzwCc430TMYpkF0X$W^mBVIUI0a>;Fz6rm9KAq_yB!Zpko|qiPDmDNYEH z`=gg(GN0JsIFtY22p`3%GklTZu$aI694R?ec@?LnjC~28dVeIHz7&K=xzCs^I%3&B zZZY$|crVxWaq*N)s(pM)jDqS*q?31N<{3WR=SAR^#dX|o6W18&S3RDzNwE62Ln6kiZAg z(h^er1J9S%R1G0DhSl;~UPBN>H3$yXR!~DY1UlIg7(o`dK`LMViohZ8z=eCy_xrtv zbGTQOiYstYT5Wvq%h%ueHku5Fz|qky0|P5~Jc|qst&&RJf7L{05Yh2?bZq<5afwI} zkpLooM8<0i%+4OLy*)*tu*ULo5MAGKG%K}-Wkm>w6WI2}kJ>RxouJfNZ2_;hi%jN` zmzP&2CkJ_WSgo+EX(R0K&l3u5)Ck21hrsFS9NFv>e*YFe-#Y1Zrs|NUjZ!SWJGjq? zexkkn(9_dNEEXUZ3vzdtXJTTLTyCvm$hI$WyIl@Wsbfknr;dZZzBsmhL$UbI^Yber zQswe1!r=s#wN%wzT?f0n(?lYNghEOB`@2adXB^EUI&QZM%UVFw#(pIr|Nf)3o8}wv z);s|K!|0%zWz)=K7`+vIc@(C3jbRK|@TK|l=0_yaXjC;*pcPR=v?6MVRzwZ)0qoD4 UaT0Q)HUIzs07*qoM6N<$f+fl0W&i*H literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmsesdfdataset.svg b/mseide-msegui/icons/components/tmsesdfdataset.svg new file mode 100644 index 0000000..4918245 --- /dev/null +++ b/mseide-msegui/icons/components/tmsesdfdataset.svg @@ -0,0 +1,410 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + SDF + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tmsesmallintfield.bmp b/mseide-msegui/icons/components/tmsesmallintfield.bmp new file mode 100644 index 0000000000000000000000000000000000000000..f9d7df10fc54190045185931bfc1de5dec198126 GIT binary patch literal 1782 zcmeH_u?>JA5Jj=EZ~{kg0tc{nW#c~fw)n&8%S93s#lpf1kO#;Az=dI4>yV(?$*Py_jMwY<3r!lmv3%nHzH8_wf~=EWq)n_D{vse=`=bLJlb9CD&7S zA_uO8r|d_3UayayX+c>4t@CPQKQ&dpf*i>2oU3ww4nJ zFuwp{#;w&s*+4- zLp(a)PTT0k>?q=TK5Ijyfat^{hoV-;XbXBfN*~qY`o;N+Gil*ed4(U`+r*@JBBJj# zIQ?PTx@r1@hz7){Im!i|w@9!EP=IQrz%3$*fVO?-{omy(k_1EVUm-IY{a6TZ< z>M?7g$*hk-o|%4ce;i;~z&l=rtYgeAF^-uVHe01ylT-K41L`!dl=py;B9!zXP~+=jN?Gr^z-3cITbP`U)-uYb*=9Cr0SOpJ0@)5 zKf`2Q>FUXG_QUK#-ONkhvhPJHKHe4nWBR|B8>E?%R8#At?HJt821^Iac$Wjilfl!~ K&t;ucLK6UFSfow> literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmsesmallintfield.svg b/mseide-msegui/icons/components/tmsesmallintfield.svg new file mode 100644 index 0000000..90e03b3 --- /dev/null +++ b/mseide-msegui/icons/components/tmsesmallintfield.svg @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + I16 + + + + + diff --git a/mseide-msegui/icons/components/tmsesqlite3dataset.bmp b/mseide-msegui/icons/components/tmsesqlite3dataset.bmp new file mode 100644 index 0000000000000000000000000000000000000000..3122366bd28a3014ae4af68c726f0bc37e0319e4 GIT binary patch literal 1782 zcmb`H%Wm3G5Qgcdi#|agp-<2U=)SMihv=${E~Bba6&0~SNoWMLC5Cbh;f}#vObFm` z3BktL(0(vg)fF|ONA~FWoSAR_IcMP2YxAjZH(p|2@IL?jKH1HDz6krHXY%eGG2w9d z=l>Y~;K@xTemp67@#)>kn~It_5*3OB;PBjyy2qe0*<_`Wg_FpJj^Pm7Xct9Nt(iLp zwb^WnwInDdeLghwwq9#?N+l{#y6D+1}>s)uq&Iy8Djokc!emtrXF z^y)%8NDt1Avx;XfB(|>QL0Q&WUis}U3yVDBQA42;l3IUYk zx(@zmxQv}LY3o%2$J1f@CYmjLvu$fXhY}>6a9Vn`u3bkIKa0%SHLXW<@)^&BP`-yo zQn@byF3dTESTeXpbt?<=L8_MBJsh^kYmEE3;&+_2PI)pLmFg)ud8+0%Q7d=qg=Vjo ziR>2+_IA)p<-=6O$q+~zkZ5UJ^gLas5tM{ASU87ZS uT!(Om$fLWwbMTZXY&0IAuL{)!w?+fg;niCCAe1=&0V;{8s;Zi%vHlCrktqiN literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmsesqlquery.bmp b/mseide-msegui/icons/components/tmsesqlquery.bmp new file mode 100644 index 0000000000000000000000000000000000000000..b556ba79d46cb566b384fccb512570ec89322b6b GIT binary patch literal 1782 zcmd6myA8rX5JXKvLPkUhR6qgbv_L|mR6&5KgA_&{>uKZ@YXJ_tx;xFy&d%QXb38rQ zT^|Rnd(GW2S3T;wtMc28XD`(9D8s5!GM$vk<$l(fY*%~D<)bdkyw{(Pi03n-&oZrk z_>la@z3NgP-}*>TZGuT3_eECtSc5YE2$8SbFpvqfVVQUVMVc5>Vu4rm30w}-T8SZ> zZi%xBagsJ6#d$_dTVf@=^^}vXecZhjtLjq8Is Y7zg9rN|R!?t(8(_jdPoN_#|h+Z}Y({mH+?% literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmsesqlquery.png b/mseide-msegui/icons/components/tmsesqlquery.png new file mode 100644 index 0000000000000000000000000000000000000000..4a2f9cb6a9ae546c45447c793d40975366934783 GIT binary patch literal 609 zcmV-n0-pVeP)pR4tUCf3SLhNR$j8z=;qLck0ztq3hx zC&w-6zl|o#2CT1tN7H8M?2IumFiWAZZJR8s zN-XvkReg@CPBJ~cf@M|hb47XR449aBM<(-_a`_dB!~@30a<(a*{)pS%&HnxZo11fZ zJUt{5@9TSk&v%2JonIUsS&WVb+1pFnrsd@#Q&abFxw=qQH#0Mj$mPD&2gv6qDV6>* zJe(mMo~KycwN0hcZ~FRN_WtZlI5_xIAHeH%kxY(YnlH#^pAv~=ZIj=Blf%O@0H(Rk z*47UK0e^jf{{EM&t$o9?s#Ge+D2ig6#>c}fE`Fj?ImR$niA3f}rJh^~fJjP2(z3Df zOoBn5bab?frg*DeB$l%~@85+7HBC8_uL4cYPDTqi> zltu^5G->vDN v-~ZhFzetJ4d75SAJE00000NkvXXu0mjf-#igE literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmsesqlquery.svg b/mseide-msegui/icons/components/tmsesqlquery.svg new file mode 100644 index 0000000..1f431b4 --- /dev/null +++ b/mseide-msegui/icons/components/tmsesqlquery.svg @@ -0,0 +1,433 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tmsesqlscript.bmp b/mseide-msegui/icons/components/tmsesqlscript.bmp new file mode 100644 index 0000000000000000000000000000000000000000..5b04f5a9d88897276982c70164d9195fb9ad1f68 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKg9Kg0jQhW7pcPa%T%2yTe3tu34l zXAmQZX3oZU@8H_u3}OV)%!#V3glmU0h!I3H$1XS+t{u)GMi9*$C0$*(b~u9=K{Rvt zMMU7*;S6E~(ahl!7KUqwGl&tSkvVWTkjg-F4?*pnJ9g~-_YYGU+?-kG&l@^9$!lpT z>gZVc`K^5X7^1j-^=cIZ17&@ERU;!~7niV-lAS+(0A+z0oP(Pif`ADgV$QZNUxcNk zI<{|z>xJZnj&0l2O-$Ckdewj6fSR$fg0^RxW3*oNa@a7FW zCnu1rXJ zfBgzEAD4T8DkmR3s%~n^#LNuzNNPt1L_4NAT)ezM#dypSmXu8I>O#xfKz~g-as=+4 zo;`aE93AnSBQ7sL`@#i?miYR5pR_a}8yL4nJ zFuwp{#;w&s*+43^PJAcV-0m;IXBDaI$qs4x6ya&49EM6n;%|SXyu{O6FT$ZX_UBg@J4axoP$m~ z7Jbu;7^1oWMQ?`K`AQP4bgyx{x8=(hLvb;dt-zcRG3xyBQ| zCE==I+Z~s1wmiKuwnRs{wo`W)+FDohO-MU9?`S5Ee_TyULHFEa39@&N7koKmyJM01 z`TNEkpNbFv{QvK7dd1IQ%$Z^xT!qFa;*|z-?gSh$SZ>^F!oS7W4|FhBI_xAOY`|5rlJ#gX#N4SW5(piJddwFf^@7Ecb zd|R8$;r%*2L$hDy6q8$on{~k}M(4Q4YHiZx@rD{FxD0*rJ5vg_T}({jkB0|GN(hSQZt3I{Ep##F<{xjOmll z_J(u@nSXF)T^ys;q$}H;;N2E*oXP9p3RV`zn?D<}Or@5t%y>}ipegZ7jDg|J(MiQq T|AnLjW1Yd%)z4*}Q$iB}?34J- literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmsesqlscript.svg b/mseide-msegui/icons/components/tmsesqlscript.svg new file mode 100644 index 0000000..3c2ab28 --- /dev/null +++ b/mseide-msegui/icons/components/tmsesqlscript.svg @@ -0,0 +1,397 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tmsesqltransaction.bmp b/mseide-msegui/icons/components/tmsesqltransaction.bmp new file mode 100644 index 0000000000000000000000000000000000000000..8ac1d604a47549bceaf670ea96a5ebbcba07d1ef GIT binary patch literal 1782 zcmb`Ev26n}6hqHV8h5TTLMF%n?z3cO@Bp47Rpv+);6jPI2S(BXm%xHf=I7_<|B|n7 zUr$S2uR34!J-6>v(X!l?znuM5p^nd;<$NZ$ipg)vIxO}2UP{atbX#}#CX=`*e=qr9 zRWj@Me9M3HDXLmEJ&TFf0iQ?B!{fNKZMjtIa%`Ti7DKoA)4lvScF42MbKw6{)%1n; zoU@Cu$L3OglTOy=`Pcj459rJ@L<8uCgg*!{M~|U^NCbo^0ZOeOZ6h<|R0_mH;s7YQ zx>6>>VFF=Q!Qha9Y`P_$ijx$UN#`>%V~M-K+o8LK&G+VUEv-{5GQ-4O-_az+W0rQK p4=Gork5XP-P~r4m@R;NbD#5`xL)E63aI{j2tZ{~^hfne$_y-=tS>6Bu literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmsesqltransaction.png b/mseide-msegui/icons/components/tmsesqltransaction.png new file mode 100644 index 0000000000000000000000000000000000000000..c41b8b30beada77ca578a39780b38b4bac0eb494 GIT binary patch literal 1002 zcmV9D ziK&9ZAh1E#+0txtwID4WUU<xI#-qgc zZKTDv;eF38WUq#8m=@fD1JCn6|L6QU=XuVfL?Qw@Ph8{a`dQyRuJMA+7MPq|z~ebh zSy?xG_nu~U_O?wb6im9iCvZAH!RZXq)iq9`VA^q|4n1F>wKYyG_AblIX9$N6(%d{| zlluFwP+3{dg9l%6^X33GHC2Se-)*b{x4W99rQdk`xWM7V4cx!qXOl)p=Qw`+Z7M2W z!s)E!OKU}`FaVf@Md{V^IF&oVc6$0ixZ?`+>*Vec(V$Y%f8n1IVwL0{hi zQmGRR4ZTk=IAoJ*YhU5fqh$b6soUJTm7%V#c4Gp&c74vJOFvO4n5?X${M}B7YPQ>5{bN5k^mwR5$Tud>5rtL!7W?1=;HCXWNNBYM7|c0Z)JV`8|mzP zN49O-Dm67#;`6;G`}Wm~$VCzPL4bd_$gGIWiQ4R-rBZkBdh4Fc-}In)y`GYI4gkx7 zWU@dyZIa7bh-^+&DTT|mmHK)Ye*bPX4U}m{WMssms!HMWmEm@mq3fIbi%e6I$*gki znn6Cl&e5Z9qGo2olFdReSYC3XQt)^@&CZ?GXz8@z^XVwngHqinbpoY2QR>rYN^e7{ z4^gU_9Xr~I#jX~$CXtv&sQ`(@bsO{fUL~E*qUCae+pQt;1tMPpATo$Zv?z(lC?ew| z5}$GERJKl2vZo;|g+wY^1G*Ej$Z6G@ty z-aup$kpv=FX=?Iv;lebgX`z%tbGa0mj8$qOw6yrSapM=}=a+~^6LfSOEQ)t@93dM0 zo=j#Lm#gA`m;=9GBcF$Od=0}eOK#V{nQ2-WMxJ>5XY% + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tmsestringfield.bmp b/mseide-msegui/icons/components/tmsestringfield.bmp new file mode 100644 index 0000000000000000000000000000000000000000..178f1eec5072c6931958e296480a1e10cf6a42c4 GIT binary patch literal 1782 zcmeHF!3~5k3@e{|FaaYl!41Hll@a^!=UYMzmPJ596nIg!spUFOh-ljJ7t;D$tnF0G zDG~~yxA&pMNkR+pzSYH;xzUT6y=^o;Q&p + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + abc + + + + + diff --git a/mseide-msegui/icons/components/tmsetimefield.bmp b/mseide-msegui/icons/components/tmsetimefield.bmp new file mode 100644 index 0000000000000000000000000000000000000000..6779a595d9cb4cbabf3ab4e0eb3c3a6a581e6866 GIT binary patch literal 1782 zcmeH_!3lsc3`Oh3gA+J{6F7i(R~EsYyw*_V5%?g%dhlRq$|LUOk*a7eL{P*$OQ2xk% vYzz&Zmd_2SCQ`u;L|m%D4yYzl!45=Rs=*GZCQ`u;L|m%DZcur&`Qyp~(Yk*F literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmsetimefield.png b/mseide-msegui/icons/components/tmsetimefield.png new file mode 100644 index 0000000000000000000000000000000000000000..288710612c34cf7117d2e05d10fcd7e6e179a134 GIT binary patch literal 274 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ zFuwp{#;w&s*+4o7ki-5d>mHTzI_e@ZD^gC!qAkb+H Mp00i_>zopr09O!T*8l(j literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmsetimefield.svg b/mseide-msegui/icons/components/tmsetimefield.svg new file mode 100644 index 0000000..a5b6176 --- /dev/null +++ b/mseide-msegui/icons/components/tmsetimefield.svg @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + T + + + + + diff --git a/mseide-msegui/icons/components/tmsevarbytesfield.bmp b/mseide-msegui/icons/components/tmsevarbytesfield.bmp new file mode 100644 index 0000000000000000000000000000000000000000..bcba00a8695e44c54fc30c6e7e9a00f1d545dc11 GIT binary patch literal 1782 zcmeH^u?+$-5Cly^Kn0XQ1r$I|%ZPr+NzKZOMk|mWV?%(%>HXTjyB(kXhvRi!TI}`S zX>IRo)l?~G)h`>b)~HwgT%2m1d_0RFGl3m3M#GNyT~7XJj)Ukw*Go<|2&>NwHc}GJ z7zkIhC$+J*D^CeK!X+Bgh#f&2c0?x!f(3R9syT*|84Q!6lVb~TVIMMM93Y6~TdILte3djHe literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmsevarbytesfield.png b/mseide-msegui/icons/components/tmsevarbytesfield.png new file mode 100644 index 0000000000000000000000000000000000000000..5f5419c812338f93285426832a52825f33172210 GIT binary patch literal 568 zcmV-80>}M{P)VMK(qa*TQpo=M^ToNjaXn` zeR>-0_GDWZtqC(TD;wQNJ~Z^a-P4W4Rr?S4`+z1yL?4!B=9{V*5lt+|Ypf{CZL~6T zeldVf2OBXP5xq5i55}+-PjL%((29tQ5z)UWKxW>?D{QIh`!HI*-(}{i%pAl3`muMh z9VnIV>NpXx8f$Q+zNw7oNr@YXi0Oz}QvAM%xZasY6>t{AYV5GKo55Kz7doY!mkADjI z9gBz~*ogym?T-L(6%(0xw=00myzwLL-@mTA4rp}y+431+;*b)~)z5eU0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + VBy + + + + + diff --git a/mseide-msegui/icons/components/tmsevarfield.svg b/mseide-msegui/icons/components/tmsevarfield.svg new file mode 100644 index 0000000..0a9f45f --- /dev/null +++ b/mseide-msegui/icons/components/tmsevarfield.svg @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + I32 + + + + + diff --git a/mseide-msegui/icons/components/tmsevariantfield.png b/mseide-msegui/icons/components/tmsevariantfield.png new file mode 100644 index 0000000000000000000000000000000000000000..19004effe7828bc38e92214c286fe8f19e39fa55 GIT binary patch literal 553 zcmV+^0@nSBP)!B@fRtjwUpA84#C*i z2rS@C*WxMMD`W?>w)0a;X|gNsT|}hfdvOdmQ%a-!?!gSs*3@stN!%|}7x55txa{xt z5?`?il&4|lT1a9eUQO#y>K{-7*he!3Z9}ydv_2*_! r;|*>=m2)HapX)xs|4mT!`nTm5ejmWJ-??dH00000NkvXXu0mjf+FbF~ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmsevariantfield.svg b/mseide-msegui/icons/components/tmsevariantfield.svg new file mode 100644 index 0000000..b253652 --- /dev/null +++ b/mseide-msegui/icons/components/tmsevariantfield.svg @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + VAR + + + + + diff --git a/mseide-msegui/icons/components/tmsewordfield.bmp b/mseide-msegui/icons/components/tmsewordfield.bmp new file mode 100644 index 0000000000000000000000000000000000000000..91d34762e1641b41e42ba0d1d8dbaec603860210 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjf6WEKV1+>9KlQ-A|NkjO5Vrsgp#;FS!x`k6 z2GK~zYI?bf|&RACf_;b-DRkqDxQgg}Z2TG(U>T38CHOhhED zot@wv2wsGppsf(CV;UO;Ee2r+D=Se1ZDOI=1msvaBQwV_N#THCR=F2@z5Dy&JEzk$ z8;uF73!9s>ok@f*E`DmJCJ{WWeZW5iNOCmE%&?i{P?BTqrX(lF)TWXg`6B>#akJ$w z<8do!882G38+e1~N!F75%H8u8CFv%)gZoBTK9AeDSXJk+jVlAcyH@~aaRMt?8>+A3 z5w??@s;cY5O?w7Z)d$>4ve2^TaT+~*NwS62s`|$07JbKoR`YbfzLRFKfU{L~0b95> zFoyweG1qE7k9WHOKH_Or4F-9JOXC1NTum|uNzULhUhV=|$5N8R{oAvGSHA(O>Iv?l zm*jnalJ%;3uv2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + U16 + + + + + diff --git a/mseide-msegui/icons/components/tmsezquery.bmp b/mseide-msegui/icons/components/tmsezquery.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0ad67ac83524856d2c13d56724f028ea801c23ac GIT binary patch literal 1654 zcmeH^`%_F|7{|Yxt=(!{TA@58MN;HelH9e22%CtadTZU4!=aHDq3@ z#jUp*JiT`V1$S>V-9gcV0;WQ|c$^RIBQ5UUt3t)o`zU^_MftOQR4`Q*Kfs%k0=#}+ zgwoqCEkKL!Q{FgQ4fp`jrR4-aExWCWw5qZk_-!}$2P?Uw(){-40a6Hs_tLop$|y|c2i z{wORUv4wGA!y=;jia;Wor(lV!Hr7H21rRN<5?ag_D+GI1fW(ey5|M-O*e_*V@IQ1k zl;{A_L825Q#>IIO5>^t09wFLKbVlR~q;VXlCYrM$f@nR_Y9jeEHWacnJLC2e1=BvF zJw(S?e~7@hYj*DrBMLvUijA}OIFVG~Rv+f%r&e=nl}gRl5c?yyMMuZRbIHkPQ&p<; z^o&d!-@H|$*%iknC7nK-dM+*PVur{?AI{I}HeI#xw-2`|Dk?gLi;q8ia^Y0ZE$1)T zd^j#Laz`{58=IJXYMp9kTKWVZchz#0`>%O|g8b+D`pll?Gw(Pi-g(Glfg$(j-qB7SdM%#6Nz!a2Ra z@A>_{zt6en(%v(XhsEuIFigLBtbV@=IbXuaTm!WB8m#}i4#}yp zE{yJT<&g5jSokmr|Jyq60(t2(N#37y-eLBOqr8QzpVCLsS(9iUl*zb?p(%}gVX`He z7bTA$v)8&|v-2#WdF-4@UrZc1R0@i=2J9zYxgjJFua7{g524s>h*Z^VG@ zu0L?w{tb*cWHdXMGI*Dvv*G1ZxXsWF0Je+WVP)jha`cg}tbOF9iJ z>+xa&I3EFyW&5LZ6lmmS_p>1hERF=Ez6dr_A?8m*2J^|6%JE%?MqhqFB+ldyt|9+q zDJoNGnCNd&FTlF{@h}7Gmt0CX$xnZnR`}Zj3s>D`yXtk^Hul2k>}ARq*x&OpOfQ_l z^|~~Ic`>|V?86a!fP1(^U!J#@Jfq}4NB%R6@e6HDfRj9F_BXE3*MyBaz{>A^gDh5N zSw3OEi+rf$R5%$!k2f8Re+H7|V?Q{f^tlS8#xuCa$xaqGq6z(2W;$-N7whsa^O-#s zCQYd2VeU<`AAf)B=!A{0GtIpi`(Joz83s%4ACD!x9o|1MzRHC@@7`H~q1J?*SU=w6 z3-MAe<4kw3o<5G>fxcSe@R@YL4^_av&&WjH{1^t;ig5Cx2dQO#KPRSPK45~~%G){5 zeDZYlMqwYF!PeMu#2mo=(+S*g7!aDcis{qzA2FlvH9JznTilP~L3Jh@D+vpobVy_UA(1(+MMH%}lP2<6YI4DGK zW<7X_ddA;Z`J5019$^&X32q&dvphZ@<-PmGu3paOXnjgmRU!6RpAq8mjQ;`V%cv-5 zbNhriDvtl1-<;9g+T3oN5H`JssMY<8blprFj&6N%x%3s;d{t>v+-}udSz7OMnax#= zIbBh7C)MZm)|ZyHn$0==pFTPqGX52+swj$Eb-TUZ$LflYna#WY+-Or&pS!Z&`>gBv z)|}p|BV>7sU4^dVU7ntv>cfW(oesXpuqN H|9SicFmhQq literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tmseztable.bmp b/mseide-msegui/icons/components/tmseztable.bmp new file mode 100644 index 0000000000000000000000000000000000000000..8733886b71fe5e621a42edd278857080ec6a4809 GIT binary patch literal 1654 zcmeH^yKj%zbYn_Np#>KcAlMW^w z-24Y1-0#qEDbNz2p@cgnG^BIo13GAlU7Spx7z_q{{GrF^pD(caZ4+DHw_q}vU^bg!u~=ZWT4A%I8ktN6*=!d3`}@e{ayU3RKt7*Gp-@1vSVXB*Lb+TQHOuU)-DyF7GhaDYPT?(f4#$$a|g%(wn?@C&wT!fOBk literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tnoguiaction.bmp b/mseide-msegui/icons/components/tnoguiaction.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0503a42608c521f773447d2d3f2ae0cc19d98ddf GIT binary patch literal 406 zcmZ?royN!j24z4}1BfM{n2~`6EUo~Q7vhFs0iXy7LqG!q0}wGZG(adI31k9s1H*v> z2Y?d)!HD7ie-I0Zfe<7FB<@lKX3j-upLug8oHG}}ynFL5Leb5;HxZn>Kq(}Eqy~k$CNsf$D%Q7l4#7D^icq!E@x4cZnsHOhLhID36kf-T-$Cw=FEdw~AI08yX)L)xdQ z-;^%i?5w(3{p5U8xmWwKtAhLf7Qh4erIbd*0C9amjLB>qUz@RdYQ~i5iJMN9{@wno z=OUH9YT!Q5C8g9t#Rv)zjoF{uEY=g{1*MKRF!u>yW#nXs-B;L2Y_$5tV04sgDW>VZtRh~)SSNWE4RfAo_SqF zi@ynI2L{8*`h6*ZtU_FKWvZAC=^9Cx=m%{NJulsInG857p%idAWbQ9F^(!wj=o>7< z(7`a35gT78YFy4p0Rby`Cn1DFp)HOSwTx)fN)$yw)!iu3JEg0-cf^4AKq@7csaT`- zGg`?+wVGQ+q|n=Lsi@uoMNB%BpnO@ z-J!l|*a~KLd{LY;ZT7?-pMN<~%1*kKWo-5yrUNhVO3Kiq8xoM;S1@bIl=-WZ9f_ok zbBc-9WHT{*$65O#+HA4mEL})IZuD2h(-Ko`jrVTR`s6PEJZ-bnp^fF?U=n-#?V + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/topenglcanvaswidget.png b/mseide-msegui/icons/components/topenglcanvaswidget.png new file mode 100644 index 0000000000000000000000000000000000000000..a2ae8ca9fc0b1a8383ffb74ee70ac5d1ba301319 GIT binary patch literal 949 zcmV;m14{gfP)pjABaMTk)ShP6Y-Kb4I1Of;w~&xD^cTp`=GKl?9zw|$TlTWAl4g#YptcFwDjf& z!y7B@S|t3xo%8&2e(!nC$@{*d%F0R)Bd8F7$Vt0Kr1+PGAP!`*S`6sB+VFVXUU^H; z3*2s3KuCzcgZ5Spmrs-<36T;yDiT9?2g^P`$aK{j01j+YvSIIS#>!HM4(NQ;!nq&T z@OpCIo!)0r|Y52F^2L{+EdKQFAWZ0Hg(Z!)(gc4^zQE8s;^;rK^1Pd zlb_Wag9jM8I~W}`&Zl`m&!7BDuUU^GEe`-|uaUCSpech*y~UBllEXT6rdZwCMcWwm^>?;~D3zt6a&Dct|(DxHs7C@52N zx9JkGaTAcIWC?zGN*0NV=`{X%oV-Ql|K9;XT*8M`>}w`op3XDf9j4Cugv|$Ak%mSf z2?=HCXM + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + GLCA + + + diff --git a/mseide-msegui/icons/components/topenglwidget.bmp b/mseide-msegui/icons/components/topenglwidget.bmp new file mode 100644 index 0000000000000000000000000000000000000000..e89b20e6cd754e2c77f75f13275a865ae05892e4 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjf6WEKV1+>9Kf`~jq5l*Euwxn;8vd8pl8=C{ z7&Qk^0AdTDQ*p^|ib_0eZ0yX;rjk-~JbfVHe?Bo4mQtW}zq1=OYB0>XkeCKEq0_kA{eOd z0jdG|`c+(V2xchhr#x;_<_1I_tbR3XmI4M7llA#NkaoJ&dR zKy&_<)gT;<6i39Hb1x$o?jB5|h&Ko5W)2pX)A1>oh5$u~HwUOVP)(!I)SPm2E+?h) zvaxkLy1dLS`dnCkC^~+*Ul7DtlH3E-0`wO!J@c`%voSO4h>A^cb|=pqtezquh?))w XC`L*H=qd-XIlv;C54nJ zFuwp{#;w&s*+4jR@`bT4A^(^iA509TxKwf1lFoSor_HafC&>fknmi16O_57^fzrq_lkQzO8TE z;juz!TSH@Gqoa>kv*Oko^~3w?>m}>{{Wx>rq-ujwy!~6%Ks$vQlV{GDVaTJ-%2N|* mlErvdH{s9!|MtGKbr~LVmbuw|Fy8=-Tn0~9KbLh*2~7Z9KImrv literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/topenglwidget.svg b/mseide-msegui/icons/components/topenglwidget.svg new file mode 100644 index 0000000..20655a4 --- /dev/null +++ b/mseide-msegui/icons/components/topenglwidget.svg @@ -0,0 +1,288 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + GL + + + diff --git a/mseide-msegui/icons/components/topensslcryptohandler.png b/mseide-msegui/icons/components/topensslcryptohandler.png new file mode 100644 index 0000000000000000000000000000000000000000..349a8279526052a0e7326ab39c4657411fc719c0 GIT binary patch literal 841 zcmV-P1GfB$P)(*1K~zYIwbo6jmQ@f3@ZbA(GwlP)L`!vCW4i%Y#FJy?lm~TQ&n|7KB%fo$4QT>x_bo2I@r6| z+@gCg$?DGJgLtE=Ud7%dw>Eq{AKUs#<_xtY>+mdY!KYQVyQ-!)^F4S6D{-`{HdNKf zcmX6?o9GFc2!jm8}L|FZNl6nTd}pB%Wm900sqE+RV{4FA6Q>ii`#Ba;};x9 zAFou^6`i@q+c>KvSqr0`8+ju>M{pQBaZ$59h;MKZM+_>ehr94AzUqucL(X1va7Hy$ z)g|~d$?s#MYG-mR$*Bp_qpF_oVOx?F6HWdj*PT?usW>DH|lWZD#8EsWkcpuZS9Cx&6R$)dX zT!7243-j0l!Hc#K%P`xZv%*~b(7sQ1e9Y@7*#b!p<3v?$Hpu@c z-Dr~hjgRqTlHVFUy{g{CYt1?QRaH+8*Nu!JSyNS0I*-iKF}t3I%^m$Ctj5XKS|qu- zs-`sitR8kIxz7YrRqJtHl3^OJ#L6VkjJNJTTg7BaRn27Zt8q=I;eBrse`EduZ(C7O Tz7CU300000NkvXXu0mjfEZc>{ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/topensslcryptohandler.svg b/mseide-msegui/icons/components/topensslcryptohandler.svg new file mode 100644 index 0000000..bf65da6 --- /dev/null +++ b/mseide-msegui/icons/components/topensslcryptohandler.svg @@ -0,0 +1,219 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + SSL + crypt + + diff --git a/mseide-msegui/icons/components/tpageorientationselector.png b/mseide-msegui/icons/components/tpageorientationselector.png new file mode 100644 index 0000000000000000000000000000000000000000..7639bb84a3ec28608db150150b3484101875b94c GIT binary patch literal 778 zcmV+l1NHogP)0D@288w80>B}A**kEE*t12?9$aHlZ%{T4RUTpi0_&)$Ism{lO=y~iXf%pe zs|5fMLg47=2to)~ClZNZFc<&;+U>TxDwWEz2k-Ci+}heANhT5rnx@HSv&lpv;mUNo zU3c&Odc6Wb$FAgos;W3WJp};tdOhs#@8jU$0B>(^u1qSGS{ZK3vZOBn1iS+COUx0E z$8mpu@9rIV!}Id;0sxpyCfL~6STepu;6<%g!^On~6h(3K;zc^0MlzX1uh+xo<|Yio z@UFGxq2fuE#MOc?X}r6;b7c+>52bovB!#CBmI!{+Xp0^=%OQ};R8>{v^LYSYjYe{C9#` zw%cvaW-~WL;#29HN?sp}VRE{AWzyEcqTciKGs&-#^(814i`?GcW+)V5CX*pa27^I9 zK0cBpFE1~-v$Ml&HoHV%+qOjhtp~5KuM|SK|AWCG$$0_X-rlm&Xh?c~W$H`NXf$|o za>7_FCJh#69|#0EolZHKOuijB0OWz=Ae+r1pUU47Yf;`CSe2b#T{GjDosQvd(}07*qo IM6N<$f)F`b + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tpagesizeselector.png b/mseide-msegui/icons/components/tpagesizeselector.png new file mode 100644 index 0000000000000000000000000000000000000000..b0b4986b44eda3644c461e5eeb8192726ff4bc4e GIT binary patch literal 707 zcmV;!0zCbRP)QERx_eq+#bi%S~3>|QBV|7P=0DnU_r?PXy zACQsGBy}})=)l;9E)1j?7ou*2goM)b2JN*i2$-kuBsWcO``vTDbMN^+VObXOo3Jd4 zDSEvg0kGHWsktbM2!NXafG;mEtW+u+zmw#jEScjtXfztQzrR;=kB^UEZjK}j!@zVp z1pov=phm0J0sxfKpW`^j!@~mxg8}OGI^sA+sZ`oZP{jH9c~%(!fXcx0JiNZX;`HG~llmM)y|5Fe`Am;I&9m9Wm(WP z4Y#+qduOp)t#EK~0N}Ggk|dYQC6A7dI3AB#E|#D%{d``nKb`oUcQ-ZDi;Q06$)9DmK2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tpaintbox.bmp b/mseide-msegui/icons/components/tpaintbox.bmp new file mode 100755 index 0000000000000000000000000000000000000000..8fb707f59aab44b9d1261b63da0cbd9475952457 GIT binary patch literal 406 zcmY+8u@1r@5QeXb58>$O-o?bt-Ph5T!~vMxjD(>N;UXLF)P;@yccnlN?)vfF1$w)G z29kK7o{`6r10BSlN?#7UqKL3bsr7>jL@J6gqLF1&&P+%wRw$+m4N)TL=99L@xvvQJ z)_FO|j0=Gq!lkjYpZ?8Ckp@5-)pi_&e*`f$!{F0X)<=3f}Hhg~irPijtSev)`9XPXh@Q2+@C}1dAmgrnB zZBqi7Jl{f@|17Q=yL)S~PdlzAiXxCQC_wZQ2n!|@m>Qa9k?6njog0DrcVE3VtNTus zjc6B1G#{qA@hD3R_Ll=u?Sz`yv_KvVhGss7qH{}4%vCkK`I&f|s0p-~!Wbwg^C3xw zd%5cK?_iR>dvt}JBXPbs+J#xydgNRG=WOMVOuV9^q+5#&XLFV3zk>-}=-?cip*HrI zK+kPT&6G3U)ZRGe>v~j`zJIPTfk74n(Cyg%X%dg}0N?OkN=j$l+uY{m!UQ@dy08TX z;IYHy9%cW0FSV6VavpPjK?-vfzU#MOC8j91P8TLHFfoAi3bY>ZSm0p>FDJFMI$oGy zk~Z`|yS88-DZGTVj5?IBJf}c*2i@r62Ft60IXpb2juy>Q<9VAS-+y2@y3nn04v6P? zmj^jSOgpB|ZUnp`f%fp-&HsU|H-u$bTl#GI1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tparamconnector.png b/mseide-msegui/icons/components/tparamconnector.png new file mode 100644 index 0000000000000000000000000000000000000000..16a6da999c151b8206b3c7adefd67d73425a3d68 GIT binary patch literal 525 zcmV+o0`mQdP)eN%nC^Tyav6}=1 zp_`MF=+MEzRS;YhUJ$`e+&U;uZbbr~NwBDcE@DI!1Vt%v$QyYHiMRwEa;AHq^YOpu ze$|Si=$W9^q1kNKCQ-c8>GWnMQMhVTz`qC72ZM;%iG$^I8=o?ByW+3oKxTF;+HUMG zr@b=gXBANGpoKTsLrsx)HGv5qm}f;7MjKWabeZ$67?3 zEPZX<#krxJjm(V93^cG8tK$H_Ei*sjE%rskAYfK&ubM%tk~DJ8%kz z@eCL7Ff(68#E*zr%FO3w&SFGdLk&l90++{ia12**3A0$q%%1-Ce2s`zydLV}8{T6M zi)dx$mvJ3zX6Biy5E1iO(BIz%x@bqlV3k{$dAp3ggIib|2N-2%aW6C1E6^pZjEKF0 zt%z98%%}X_Lu=!~kapjQ!_LglSjWwXn1NbR6us$pJq7&VfI9u_G%3I@UP6Fb+VsI) P00000NkvXXu0mjfauee{ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tparamconnector.svg b/mseide-msegui/icons/components/tparamconnector.svg new file mode 100644 index 0000000..0d677d8 --- /dev/null +++ b/mseide-msegui/icons/components/tparamconnector.svg @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + PAR + + + + + diff --git a/mseide-msegui/icons/components/tparamlink.svg b/mseide-msegui/icons/components/tparamlink.svg new file mode 100644 index 0000000..911d769 --- /dev/null +++ b/mseide-msegui/icons/components/tparamlink.svg @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + PAR + + + + + diff --git a/mseide-msegui/icons/components/tpickwidget.png b/mseide-msegui/icons/components/tpickwidget.png new file mode 100644 index 0000000000000000000000000000000000000000..84284b618b3e8a5750449924e16df8da9254e2ac GIT binary patch literal 1135 zcmV-#1d#iQP)dYgw>(EueSCC2|*Y>FfT4oh`9;=F0v z(UB%Zv899PvZM5G*e8R%5iPeo*F61=@9Iy$kz;rK>GegO8VsyAYS2$ij>MYkJO z?EpG%_cpl5$e5?HaveQA8-MNUYIy<%A{i|O*cxfj6p6**_zIaO^~dmajz|Cz=?pX9LRQx2 zw6r|WxpNn&t^JDe@g0_G*McMlII!#lz@rPs4x*zEP*%1Dk0*`&`+Jy}c+XNj9j3nt zoOuvHxhdizDXE2;noSH3U!ktfM=;o6ss0l#R@ESIaM=JGGRe+|Fp$b<`gS{KCA zk7WS>uE7rL%$b*feLw*C*c53uMUofma&vR(@9%dM7Z-0#Pfy?N@pztD7C=?6ETriJ zwgIg`)(*@{BV!FvYl`f&A>p=ec6Qe1^ZCfh$)U2cGA1o8 z?X-x*+&@84(HpE^pGaRH3=hM|h!cnc4B*bUe0qBNBg?Xab8~YfBqU%MhATEUb`LCl zi!i<3?Nn5_@cEh<8am6=)JaQqDw0-JCyR@VubQTr5)1~f&dkibHaIwV0%%$iz@kFo8U+)w}j002ovPDHLkV1hPv B50L-> literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tpickwidget.svg b/mseide-msegui/icons/components/tpickwidget.svg new file mode 100644 index 0000000..bc7b1b6 --- /dev/null +++ b/mseide-msegui/icons/components/tpickwidget.svg @@ -0,0 +1,288 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tpipeiochannel.bmp b/mseide-msegui/icons/components/tpipeiochannel.bmp new file mode 100644 index 0000000000000000000000000000000000000000..a52465638d0f325f26ca086d36a9dc10a2ce83ef GIT binary patch literal 1782 zcmeHGF;c@o3^WZ*N*bQP3wS_!9$-Jj{zqK#0K4K5X(=eMXKZ@@KxM}4YR}^4;xI#! zf&y8$mUO4hSyHwSAJ>`5J@5|eHmobNvTTq2n~jzo1ne&-kMB=ss_t?o3DW<0ey-u4 ztxu8Xc~KNvKzW7?<_v@rJi`N+VgFeFuF|9``2@3EO!x|h?FtOjG|ltuRL;}3Z9}!E z0n#v`4KZX4xkDtPa-MGNx}hhI{p;9w1KjTU?FB))jB^W$MA9vq@Zg@S@)@G`2G|?9 z{L-ovN&LU4>s^gSFw+cq9@=p~#K7PrF^^aNG{ftobp6WGXlw9c(=DPi!sI?6K{3=# zH9Cwy+IQ9F8)F`jM9m!F9_u@YAq*ds-I*zDx83cwO#y>#ZIR0c9w3Mi z`T!V>_Q6D>h#GuoVxl|{j3Fe%KoouQL4%S=q6Q5KAVG``h7_Y~nyL(%w1qaMwKsO# z-QH$qx4W}5K6G2!6+-Zm_$4R#&L#if`F|(p9FMN+{FfojC42X_6&*c#S^2jC62QKF zSA8$PxZzSb6sr62irF=uG&^p^lN}@Rp^JwOt?&KEfX2qE{Y_2lwkV2(Wl(M!Y&8w& z?@zpY<#OW2R5I0>n40X2C5NK+%#AAt4>o1)3*hrDtsfblK~Zf~MZjMw5-b-9h0A;m zM%h}+WUXaDGMRR7_KggDea7sXHm5spj`Vh%{^I!)x_-^Q8^ELMI_J-)eptJz<`G2| zQB@H|6;YMjxhM!&CYT0TCiL|sxY*Lh#6(dhosQoSF?Jt0w&~iP00O}Dq+2~Wm}YQb zwhaxW7#zIaMn}`QWGO3m2v=o^wqK>xUqeNxS}reLx7rc?Cl4IBq}{bdiP4NDl48z* zs)#IdGoK6S*SaY$tHyO@EHj6t=8(O$>xRb6SAh5L2pAhn$1>@3L!p?eiYUs$F_GTh zBoEiG#2xu5jN<$BLSq+*_dU_P$YX6)m|+)6Gas%l0Y)QpRJIDKf?%#IdQaBLU;n%d1Xe3fEHa9o3 zYgfJV&9|+mMcHG3T?uOW9B6g}F6p#`VYrk8(rj4&0R9pYSr%{vkw4-IdWK>%0ozR1 zR8=+BR#%t#HBA{#By4F;q_y>M4md7Jn%+?N(yJx@jT>d@p^63172qL}$Pga^b%_V9 zSmMDac3^IA7}R2ksmbY~@<8BN(C;s6X>V_vvaI*&qR}(+0A1JJ zNFQKbea}A_iaq<3P9LI1Sf(P9?7QeAzZWxqGwY zT8{<-suPR###_ESa?W(J*}R?ymk07*qoM6N<$g8Y_2U;qFB literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tpipereader.svg b/mseide-msegui/icons/components/tpipereader.svg new file mode 100644 index 0000000..a3f3d28 --- /dev/null +++ b/mseide-msegui/icons/components/tpipereader.svg @@ -0,0 +1,473 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tpipereadercomp.bmp b/mseide-msegui/icons/components/tpipereadercomp.bmp new file mode 100755 index 0000000000000000000000000000000000000000..ce3f51ec073c812e4749262e848a734a468d32d2 GIT binary patch literal 406 zcmZ?royN!j24z4}1BfM{n2~`6EUo~R2Xjz}1_lNoVrXc9P(TvM1mXsU0|yQOCH{jE z!~g#v77zm=NC-&WB@bM-Md-V13}Rnk0GVYBX0vm2@S?MAflA5?IvPOYKt*8og}av# yY~IVv#%%CS2W*j!oCDYp-eA zEI*pdU6RYiKbn@bc8vK0eBgn5?vC&4`8*HLokLYs{>vuJU-b76x(*yTE&tnq2ypoD zacRruji-Xa`i{$&Q&*FT)RoBO^p$b#_Q^eaHsAQiKzDcO#opd^8zo63Yg+YY)_UAD zEXK#9Z(aUv=2~)AAC4!I!_jCwtZ9)S_wC!ByC*<)S9eZDGDxzBEQ@$N75J*%_-gKx z+S{ADP1EYmW-XEly*M(e-TFB^eKk3&58oUayV8H;h4)o;sCXy9p{goBoQ|G-u&ZN( zTmod-xq!*Ch|}r7G%d2GMK)VtY%I#jlNU%P#hh+TUn>?9&+OgXH?$le0HkN_=1EOQ z({wZ~ji%{Lmb#|t%*>b+3Q$$;##d9p*`F@q^R1@7uBD=(uKS@1XW*klhfaC#xJ0*a zn;EB&MlPFmd4lpp7cX67MW6+W5{6-67#1#9`xsH!ajnEC9K5jAkRgtFN?mrdjnMFIhN4v;M} zhJ|6|sjTt_%Zk@{-0r==%X0^YlY z|NIqJ-8k29nk+lR4aOCz9;M z?Y3!cuc9^}AsZHk$715cgKWsfSf87z9gdG(xcS71Q$fFftIzAL2`fscbNBAu^!9ez z17H2}rKi$L7qJ>0$o2COK%r11YZlP;0@XDJJw2^dRaM|}3D|;@vFR9pj7PG*e8y~V zYTB~8xjEqTdSxvZv&8u#XU^;|07u+zullgE>-j*SXRTLmYbb}nK_X$0h#N?<3rP}b z+qRX=lbiYUlW(t2zqD&R#p0R!gTa-y{*NUPD zfDF_ET|k>4hz*Le{jsLtx{%k?(I{4=>D$)E%9TMRc@CJ2Oy^I$zW?C53*YQ?3c{-$ z;qbsh=B57wMNu5gop4VX)Gi1@T`1JIwz+9TXjN-n)6+XP;c|)O^A=wmJv#FJ2d}*` zYUhsuF;!I;zD-M)h|)3alJ!7?`aYb9HoxD_2Z z_TI5sJD)Gra{vp#UlJ^Br9@7^3j|AvT0!u6z11FFPo#he;5_g6qXkMTfn_G;qI^e&w)PyAHVwwS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tpointeredit.bmp b/mseide-msegui/icons/components/tpointeredit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..b4a00e7d472f549c5552045d56c10c6fd64ca52b GIT binary patch literal 406 zcmbtPF%Ez*2*kwAp~lJ4(RaA}7bkV>=;r2o`Vs!%5AdL9;;IKnFA%O_7>|MsGindE z&VowocbGR-W{r+ABN8Dg#{8f{f{{{67>Ff_r~(n%Lg7DvfrEM796R$QCnB8kO;dPw Y&E9=f-=6-h`r{x&U|t^lx$3oh0rEBaga7~l literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tpointeredit.png b/mseide-msegui/icons/components/tpointeredit.png new file mode 100644 index 0000000000000000000000000000000000000000..0728fe90713451887757ddd36ca7b22912919f8d GIT binary patch literal 362 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ zFuwp{#;w&s*+48^DiMFQWP6V#kP z8Pz$rs3g4-E&Xo)pey8hX<%#^!-B1Sn=DVVKA1FN)-uk9=Zzf+GRJ-YX@9%^`|I43 zzLyi`J&#_l#wmESrdM`>1{cra0`3BhwWi`0oDJ8a(jwim-&(!Ta^I*QZhUNlO1bQk z%&t|dE^N!4z;@+gO6>I$pKUlEd{9&OY})tUU%cx?S`1UouJ~zB)xIa!Tdep!+0S~1 zHv2D|9wvt5GgY6Ryd{2m1~crl7I8RVUoelqf|)sVriSFQNl`#AGkCiCxvX + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + NIL + + diff --git a/mseide-msegui/icons/components/tpolygon.bmp b/mseide-msegui/icons/components/tpolygon.bmp new file mode 100644 index 0000000000000000000000000000000000000000..b1921425fdc562948e4d4d8245dd9e94a10857fe GIT binary patch literal 406 zcmYk1tqQ|16oqeLVlXq9nVg&))D-IG`#PHqROCj@jfRRoM9u2@PBn4a$xoA<Yau4q`l$y!G+mWxohkVFt= zWX_FLto7gn6ch9W@jEJn^@T`@yFJgw>dG_Z4=+e1SR)# f&P(R@5$16d2QFv!|KNUhccR+H$aj+2V|V@mu#m2R literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tpolygon.png b/mseide-msegui/icons/components/tpolygon.png new file mode 100644 index 0000000000000000000000000000000000000000..793b0d19007c7146114cef145ec8832b59ed9380 GIT binary patch literal 728 zcmV;}0w?{6P)hC)C4^Y zs9>rorWSU;Vt|abG*D1;0(V)udwcSpeo%|93P4IlfM~-X6bz^^)HTc`;id8yT+_v@ zX4A#%qlWKjL63fhX#EaKYxglVk-j+))(>gP6$9jUB{1?O5FVSVW2|K7+uzZ5(K3I7 zCCt}_BtOSUa(B7<>^m4_%Vt9*zbC@?oF-va?BDgH<6EluS29vmlzUYVb*Gjq&wd62 zxG})hJ3@K;6a1|=$+P0FL|s#DukXs^lEnR!&HyGUOu$I{`u;(@>H~b;x5>>L^{n$) z=bQlyEDVtbn1DC!ZqHY$$J;0`ezxqGvjgH-v*H{70%m-OLi?CAfQf|(BxXb_0j~{S zMyTS5p3wT70S0NrnA^1tTZvOeKu>C2*~%BpZ}CUR1`Fr|UI0)Hd;}$HfAavDkBvOF z=LQk`0NX@_-P4`yrCmR)jb>F{3Xo~~!}r(zM{F?@wr#KJZ_6KG!Oy9+`|^?i0000< KMNUMnLSTY6l1Qll literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tpolygon.svg b/mseide-msegui/icons/components/tpolygon.svg new file mode 100644 index 0000000..a34b863 --- /dev/null +++ b/mseide-msegui/icons/components/tpolygon.svg @@ -0,0 +1,289 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tpopupmenu.bmp b/mseide-msegui/icons/components/tpopupmenu.bmp new file mode 100755 index 0000000000000000000000000000000000000000..2b057c866a98a5992caf5fa11bcf42078c90a511 GIT binary patch literal 406 zcmYjMF%H5o40I)=Rzi^x6C)$6qd-8;Ao&1Mxu$hY!QeSe;>2gu*`{O;3 zVMe`ym&Sn(=3jAtK31OK6jnqcY>KfSsE}Z!loBq~HmMc`VigNT9I{Yf+4-_QD@1~< zi{S;GcP(D;87g`FNYg0X^OUvcnK$|8SwqWD3#;}#>$c}LAYa?TQ{=za4+qosR~afd Te>9Crfsgg?W^pt6*_|yv(#6I- literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tpopupmenu.png b/mseide-msegui/icons/components/tpopupmenu.png new file mode 100644 index 0000000000000000000000000000000000000000..5c7ac5debf0f9876a0c73741c29f731b0ff654d5 GIT binary patch literal 1046 zcmV+x1nK*UP) zcveJi@;``D%JGQE&91I4FOWM)u#Jt4uL^}iumb+k<1+H8RLc8+8Tx=bB665WBy>0& zzURA$T(p2qt#udRSeDfcyafpGEzk*U0jGfg&;aZL--}35Db-G?E(1eDLxpfSY*i*< z1Ls`!0q`@B2bzH%;3Cj%?5B*+rHUBUc6h}Ges^K*z@E`2APJ;R);|DW0vF5<0e%7A z5s||x9C43`oCmxBi;IgZOG`@xgF%A9V70{Viq;w^6}Xy@B_f!=$N{h{s||P>NQp?= zY_%TP6OsIJK@y3C2B@roQfkx!I$!p0^BkBD{w|c5@zuWBJ%b92%uD; zZ;nao1~3m~%x(bcfyb0mrvUtZ|6*@%?`KLW&oS%o%8`#EGVe048@)%AQg%yAOR=r3 z?e$bDbvc{OQdd`ZBzXCV;#%u>0cUG#Yc?K_zk0un0E)#TlarHdZf+8b#TXkKqobpP z;o;%R8aRjuT5GS?`ZmxAbeLgv-aI|P6Xn5Xu!mY(TMOFA+S;1#?(Wu&jg3j*QJ3El zg6Dv%z{^JafmeVJf#-oYDD{fhO`x^bxm-^7^z`W3+S)&XPD60TR!Y5BaRTM;wtyFb zCxIfR#%njWZCREsFIZh&B^V5{v$Nyaw*3LH0U#o?9$*x>W`Gr7#dU`BBBEWkB_diW zbsAu5YKoDO5j{9KXgQ9Khzh1d_K?k_&9+; z0KeZ)Q&STI0|P`Nk^OW!{kVwyVG{bz14L4()FE)Wa@g(%!zwBFe z)INx0v)PX)CMLAc=OY@8+CHCeR4LUAoU@fupP!Tk}0HxGfC{58;SNCQ3Z`YW&kGsbF4Lj(}Ug_a# Qwg3PC07*qoM6N<$g4`e8bN~PV literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tpopupmenu.svg b/mseide-msegui/icons/components/tpopupmenu.svg new file mode 100644 index 0000000..ad3b5fa --- /dev/null +++ b/mseide-msegui/icons/components/tpopupmenu.svg @@ -0,0 +1,290 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + Zuioilo + + + + + Przio + Iklaba + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tpostscriptprinter.bmp b/mseide-msegui/icons/components/tpostscriptprinter.bmp new file mode 100644 index 0000000000000000000000000000000000000000..d4950bf5f8b2e4ff6154da1c8faa3f51dae2c1a4 GIT binary patch literal 1782 zcmcJND@#N{6vuxSgP*``vKT~s-~%7Q;wy?^+FxV>^Z3{-`_X>rjKwP9Q2Y iP7_9b;Rw9=cW9S<*j&SK?rYCr!VP=kJxNG+621U7KHv8M literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tpostscriptprinter.png b/mseide-msegui/icons/components/tpostscriptprinter.png new file mode 100644 index 0000000000000000000000000000000000000000..bc3d2dad9a9eb4f9717fb44af37eadf5030c7ddd GIT binary patch literal 1210 zcmV;r1V#IaP)^Lgi<`z`^%0RSO{%g@hW(`Yo;o12>l0KjB2UF_-U z`P}32RLJFWTUS@t`*n47CS)K2fMZ#f0Kn|*?5Vc4HvRbccp(5ZH8rhjwc0moYimst z6B93Kwc1-FBO?`=0I0YTi^Zr&B$7?j^lscIl}bG>m+R>E_O?)^QVnOCJW)YX!iSxm zotbVPJ^YMLYk0@C}fu!QzloLx!s~8=#;`W^>06;JphG!)J{Rj&tTXlRVQgmCV zQzr8A4h_gDk*dyJLP3ET4}M!lwI~~)3Xm%S-n&|vh#QX0`Hm=tVi^H+Iwg?7Ek7;RXnN3@PQmG{UH=Dm{c&_mo-=7>#DsnM5 zZ^u?B0_+kn^cLK19|VFd+#UZGb@iV<+o&$H&CJXM+-~H^ao{)(zusj54&cBc8jS+H=z#f>*W|dqn zzou5JUl0lfj6(4>2%!KF5JG{F_)G!+*Z{%C`c_!4*RRWDvJyi6{clqM27_ThDwUp% zL?XLWQ&S#_+DrH(aU92ZyP0cDwz9`uh6AKNb76O7_OJ zk5c_stMy?=N5^7cU*CD)e^d~=abwSDY)tqZ4#%V3-d_F2#>OOoA0Gqw{eJ$^(h~fB zKg41&a&vRRFbpVauh8TkkSkXbcEI6)*Xs@S_xJzgcDrW)46!WBJq8E{gZ71mg^^Gw zRLXH&4#O~@X*%U59dxTGiefAli`8bc%>wv}W!Y#Ve*aUUR4SzaYBD~vJx#JKyPoX$ Y8ze=os#j5Mvj6}907*qoM6N<$g1Vz600000 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tpostscriptprinter.svg b/mseide-msegui/icons/components/tpostscriptprinter.svg new file mode 100644 index 0000000..2b46435 --- /dev/null +++ b/mseide-msegui/icons/components/tpostscriptprinter.svg @@ -0,0 +1,354 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + Poi Li + Poi oL + + + Poi + + + + diff --git a/mseide-msegui/icons/components/tprinter.bmp b/mseide-msegui/icons/components/tprinter.bmp new file mode 100644 index 0000000000000000000000000000000000000000..1e11648305bcd2e9c995749dba6feed91f94a034 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDj7vhFsutFg5WE9Xn1kN8n0t^s<*D{@x8nFQF&St&^r7H2A4U0bqqiRF@N3S1q6-4We&rC1|Wi)vtV*R z&?r1k0-6J~jvxY>14MYt0m|YJ9EdDIbAYh`F$x%xSP{@W5CuRIk9#1o2~-1A{~rf{ z8%59@h^v6ce4o;^-#>D;t`D393PM7d7(?K$!r>y2Q4lr6kU-zzaS|~mz|}yE!s;qA WoJ6@fK!*XHgcXtG9=HcbG6Mi`v~R8e literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tprocessmonitor.bmp b/mseide-msegui/icons/components/tprocessmonitor.bmp new file mode 100644 index 0000000000000000000000000000000000000000..1ecf478207ec1e4996a0e487667d955e68dbb030 GIT binary patch literal 1782 zcmeH^F%AMT5CcO)LrKFEc)>k@o6eOf!8ZY4dO;omnMq$%E5SaWa(Pt{HpMS#dH$9wY;u Y2JjGJs?q?s}${88sjmRS9vKi1lE1Bu3!m^c;_=@xNz8z7FEt;on*WLtvUU{#7t zfyK!9YVYeG+Y~Jfm7Sl@J?A-j&-*;@We6d-pJ4xwSm@bq5PG&7?u&uYU9?jnC3@tN z(zYCr``3+63M@3bcQZ7bc3AVPv(MkWG$V8tWst&-p?Li02?Rl)Hk<8ZlgTvM)zwuQ zTd%9D^8$d-Y~G8b?2OWO_l-S#`BVPUtCzq2p>qPmbDPV`%7&||s;>C`{-+l?5JK?R zMN@~vvCHLh?MzEc8;Y&BwY5DChjtsgPCmQuqZcP${j6b%duYup9J(4p2n+_pRfof| ztEHtSH#If&Mnp>pSsankXgp0RWrD%r#@KpQz*>~OK5O5V$qR~w3~sQw|M*Dw*ZF6N zxw8cT0)arf(P%s^m&@nd+uJwAjR*jGdwUCfK3|buufGle!nu+J0I1zsy}zNjHks9N zb0?0UIOAM%Sn`5 z0CevKYp=}ppc}6wJg3!a$9bL~6GgE!q7_B4l;`=NTCM)Av9Yl{HX}S literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tprocessmonitor.svg b/mseide-msegui/icons/components/tprocessmonitor.svg new file mode 100644 index 0000000..1bd0626 --- /dev/null +++ b/mseide-msegui/icons/components/tprocessmonitor.svg @@ -0,0 +1,279 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + procmon + + diff --git a/mseide-msegui/icons/components/tprogressbar.bmp b/mseide-msegui/icons/components/tprogressbar.bmp new file mode 100644 index 0000000000000000000000000000000000000000..de0fde362df16dc0585e3bf5eb787d874bafed01 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDj7vhFsutFg5pW*)~8hRn{p8|js;|&cB2gm{- u>ru@CrzK!=B8U(gfi{ntgArmwFMMES2?;c2yaSUWc>p;bj4nJ zFuwp{#;w&s*+4>AJaKbzN`nqe+3HOB}nX8p>84j`@0Qy##+xqj7^>KQ7lbD5&sTH+I?WzK2`Oe U`Y#z*p!*m+UHx3vIVCg!05POz@&Et; literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tprogressbar.svg b/mseide-msegui/icons/components/tprogressbar.svg new file mode 100644 index 0000000..ce84ecc --- /dev/null +++ b/mseide-msegui/icons/components/tprogressbar.svg @@ -0,0 +1,228 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tpsprinter.png b/mseide-msegui/icons/components/tpsprinter.png new file mode 100644 index 0000000000000000000000000000000000000000..bc3d2dad9a9eb4f9717fb44af37eadf5030c7ddd GIT binary patch literal 1210 zcmV;r1V#IaP)^Lgi<`z`^%0RSO{%g@hW(`Yo;o12>l0KjB2UF_-U z`P}32RLJFWTUS@t`*n47CS)K2fMZ#f0Kn|*?5Vc4HvRbccp(5ZH8rhjwc0moYimst z6B93Kwc1-FBO?`=0I0YTi^Zr&B$7?j^lscIl}bG>m+R>E_O?)^QVnOCJW)YX!iSxm zotbVPJ^YMLYk0@C}fu!QzloLx!s~8=#;`W^>06;JphG!)J{Rj&tTXlRVQgmCV zQzr8A4h_gDk*dyJLP3ET4}M!lwI~~)3Xm%S-n&|vh#QX0`Hm=tVi^H+Iwg?7Ek7;RXnN3@PQmG{UH=Dm{c&_mo-=7>#DsnM5 zZ^u?B0_+kn^cLK19|VFd+#UZGb@iV<+o&$H&CJXM+-~H^ao{)(zusj54&cBc8jS+H=z#f>*W|dqn zzou5JUl0lfj6(4>2%!KF5JG{F_)G!+*Z{%C`c_!4*RRWDvJyi6{clqM27_ThDwUp% zL?XLWQ&S#_+DrH(aU92ZyP0cDwz9`uh6AKNb76O7_OJ zk5c_stMy?=N5^7cU*CD)e^d~=abwSDY)tqZ4#%V3-d_F2#>OOoA0Gqw{eJ$^(h~fB zKg41&a&vRRFbpVauh8TkkSkXbcEI6)*Xs@S_xJzgcDrW)46!WBJq8E{gZ71mg^^Gw zRLXH&4#O~@X*%U59dxTGiefAli`8bc%>wv}W!Y#Ve*aUUR4SzaYBD~vJx#JKyPoX$ Y8ze=os#j5Mvj6}907*qoM6N<$g1Vz600000 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tpsprinter.svg b/mseide-msegui/icons/components/tpsprinter.svg new file mode 100644 index 0000000..387d00e --- /dev/null +++ b/mseide-msegui/icons/components/tpsprinter.svg @@ -0,0 +1,354 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + Poi Li + Poi oL + + + Poi + + + + diff --git a/mseide-msegui/icons/components/tpythonscript.png b/mseide-msegui/icons/components/tpythonscript.png new file mode 100644 index 0000000000000000000000000000000000000000..2fbc7937fcf3716546e98ef155d99395cbf363f2 GIT binary patch literal 863 zcmV-l1EBngP)_U@dixXoLh<+97X6qP?J(LzI_tmcd; z)50!b)D$zy?v`Cnp=HaGqKq<8ib5SiH!)jwGqLhgVp86kBSrF3N{}`~`e7QvHeImi z*UR@j-}^k@cMj*gAfkSTVU12suH8i?2EJHl;P)NM$YvPU$S|yN{(_*YvWgDA{7nbH zLK#syvaXKXudS`?;p^&qc!k2Zg=JYI%d*CjlB#nphCaTozAc4F*e^JclzDA&h$@yy z03rc|1dP-q6hJsq)7W|}2a}wSm+K$}1&4LOM&LME7ul*g0K9(tF^jfD&)aQF6B-!! z>1eCwSy`8T1P%`3A9;lz#I}0K%$Sh#NgmBkU#)uXBT*SPPh6Lj3qMV zWCG^;`9mz0LjU;_7>0o+JqJYWgqnveSyoBamCra!qUeqBh)+0*^o-jW8XCf@G98K@ z=8y6<)fLd|n@#S`&DH8C?R4Ds3B~yfk;o3WZeBsFz6k(uCN&9+P-s?f@rnT8#`Uvs z6id+F)(Wv$g206#P^qGzdwdTLt2aO-5@G5zg~`1!F;UAIgM%Or*98#$Z z^7FE>Qn}XR4gB|~LKPkfj`IM=O*X4JoP4T)u4X0&niFK@=pdgm!z9<+`wgn_NQ)uV z>YdH>RHqG{SmuAwq$S~r?*6z2zy#hRQ;6BR3vTZ2u(z|bs9O{`TTRNa&5x`#;AC>J ztY} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Py + + diff --git a/mseide-msegui/icons/components/tra.png b/mseide-msegui/icons/components/tra.png new file mode 100644 index 0000000000000000000000000000000000000000..1b205e2137397c12840f81be04e43efc015b302c GIT binary patch literal 322 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*O%l>?NMQuIx9s<#-rad+uv&0SZZ$xJHyX=jZ08 z=9Mrw7o{eaq^2m8XO?6rxO@5rgg5eu0~O8nba4#vIR5ssA=e=Xf!2rq8$8}}ZrO6Z zqHWGWr)d5O&Kdc-Pq?a>xgGNts0%cOUr=+3XkwXMR4*}OrupgHkr7I|mF6y!za3Ju zm>n8*?b?g*{6?b-{x=@qXg?@(KFanWv-2Ipf7c&Kt4=e`ZQpaMIA?c`!BNS@tNgSM ze_-;Qt{(L`;BE|KDR7oLvuwvPf5}c4rP|Mo5gB?0?=RPaJjmeb>gTe~ HDWM4fJa%(w literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/trealdisp.bmp b/mseide-msegui/icons/components/trealdisp.bmp new file mode 100755 index 0000000000000000000000000000000000000000..21954ecf8c3b07d3cd891aa484e9f1ac958f6113 GIT binary patch literal 406 zcmbu4F%rTs3)>3%KS3=dDs<`*fLu`R1lkLtu%UW^&W&-5mDL^@xV}PFCTjUvAGwic;v8$zwG6Q eX>2(Sc#c`FXRf4`BR7JWkBJcc+;rrxc6S#LY2ju7 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/trealdisp.png b/mseide-msegui/icons/components/trealdisp.png new file mode 100644 index 0000000000000000000000000000000000000000..dc30389801271653317d42f63ccb8ae374cefe21 GIT binary patch literal 585 zcmV-P0=E5$P)Oc@ZyGao80kN^Pwzm+{*(!*Yg@{<$ilU8` zl?Ya1A%rx7m4%HTpdeb9O0g6>C0ZCkV$3Zhxf_g^_u!?t@D2>@%x=!inOQbuy9LIgP$Z_WLIhxHTbX^Cf z)Qz*~cDpDRi;!g*nx>)AXkap#;Q4%FFc?5pRalnge(Pz`Y&Ju?-9|JT{V2awDnXWI zP)ZSrM6loQVVWik!@%KifTAdHINuc1>vaGCA>^ZiL?QtIux%TiP6w$}3Zf`N6h*XJ zE$F%qmXl|*v2ZH(gJoH$R4O=~PU!dho^$SS{S-L(Nr7paD3{CNc^- z;V@V(-)rh%I-PoaRaM>f@pyb|8w*L2u-$H5|KpJV6^L!y!9I4HrjZ~M{Qe)#?@#ar X + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + 1.21 + + + + + + + + + + diff --git a/mseide-msegui/icons/components/trealedit.bmp b/mseide-msegui/icons/components/trealedit.bmp new file mode 100755 index 0000000000000000000000000000000000000000..cf147aa7715ec93177f606ba7916d44034545186 GIT binary patch literal 406 zcmbu4u@S>C2u1N-dRmt*Ge`RDlFCV`GF`gNqea+38;~cAd~xkBKp(yY$L;=|B(M^% z_?$k;CF)D+ksLx1!K9S!B0}*ZwN?ZV6Zg(=PA?Jc3}}!rd%Y7Mv&Se0S7lUd8+S$1 i@hc!`8hM0nL9=jW#XgM=>G(dzz&DQQoC#c z(ljk4xTF(7F1!+})e5-MgTvuK7=||;$Kx^0W|Jt27>!03I%CYm3qYEt0whV(=~VT4 z{VZQYtJTtezgL!Js?}=0^trEdPLgy{L8H-Nxm*^O-tYIRR4N2Pz;3rIv<1F;0N{BZ zp63-hbh};F>ouKDha^ev5MQ*>1NtgBfFxgfRx^9Pr}5C{N^jf)>Czciy~L o!>HtwW&v~8>JNDTgY*6bp94&&XTJqnfB*mh07*qoM6N<$f@z?*#Q*>R literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/trealedit.svg b/mseide-msegui/icons/components/trealedit.svg new file mode 100644 index 0000000..fde650d --- /dev/null +++ b/mseide-msegui/icons/components/trealedit.svg @@ -0,0 +1,243 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/trealspinedit.bmp b/mseide-msegui/icons/components/trealspinedit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..9af3f65c61c44a160551325f210ee9cc7352565f GIT binary patch literal 406 zcmbtPxe>xZ43uZc2*eDDLxsTB(mlG*pMe5T zWD?={N? z0C=9)3pvS$fOOtP6h*B*%d!9{a!?cn#^Z4(Sr7!6&1RTPCfMzEPh->Rw7tOdJOUs| z?)Q7zwq5xuIF7?S&v`nXI2w&el0paqs7wgKIF3n@PXc9GGRv|b1-9EQN%DHVaxfS? zNNVKLq<~RBjjrp^b-g>-0M_d@E|&{ds})?=1po*kI_Lko4#F_Rd_Ko!vw7|I)k7rF z^zZk3)m|(XJfF|4`At)Xs0*fPf+TLY8xDs9mdj-|c03*-gm}6^^^hqAnl&N);c$pF zO_iIFBF%jK>06{qwgCWf93x4Rw~1xds-UswFU + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/trecordband.bmp b/mseide-msegui/icons/components/trecordband.bmp new file mode 100644 index 0000000000000000000000000000000000000000..5b5b001c7b63c05de0200e29e518ad51e72abb6a GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjf6WEKV1+>9Kg0h~G#Ub wfdGU{3>&Qk198a$Xy%Y*222xji3$@Vhek4oTK)o>12>8!Hb@tedj=01030@_cmMzZ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/trecordfieldedit.png b/mseide-msegui/icons/components/trecordfieldedit.png new file mode 100644 index 0000000000000000000000000000000000000000..4bfda3afee426687b55c0f1bf5c9a675590e2c7f GIT binary patch literal 522 zcmV+l0`>igP) zPav`J8N>&$5N#CGXc-iYt@sWWv&G_Qc5^R#FYa#R4?{RVbN+wMIYUOwW;4PtR8mU8 z3vt&>y;3v@Z-f7DAUw}gf72i>r4(Tps=;9JQsLonNbH&lA@s^-vrHzFFN+ExVqf@W z21+TEQq1Rb`u+Zw4U|#{AyDek^~52kQYj3>(D7oiz%)%v(`2*RXnwU?Q7V;?QnKA{ z6HU|4!M(IxE{E^?ns;57>2!)=7`U#>e!mBx+wC$MjmYQov|26B=kw z+qN|yMG@6%^=Cr*k#ahnsMTs@GMPkiNN7>HT*h%6dcB_J3WWme^_nP(xZQ4=FBXd| zmrH^mz_P4AGXQ9}+Z>NacDo$_zVFj)HnA*=N~NOrjmKjg$Dz?^#9I0cUGMYcg%AWm zpyPVI&h>izE!nnhE|*Iz?|zd!&-=K7@8W*Q*kS+Kuj2ipy$!yNA0hga09Y01D*ylh M07*qoM6N<$g8Dz?f&c&j literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/trecordfieldedit.svg b/mseide-msegui/icons/components/trecordfieldedit.svg new file mode 100644 index 0000000..c074329 --- /dev/null +++ b/mseide-msegui/icons/components/trecordfieldedit.svg @@ -0,0 +1,258 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/treportpage.png b/mseide-msegui/icons/components/treportpage.png new file mode 100644 index 0000000000000000000000000000000000000000..f7afbd3b299b406b32e1fc3a325160bcd37e7f43 GIT binary patch literal 1194 zcmV;b1XcTqP)Y|_wW-_D%K^e2qM0A20OUIegdG5kH z-*v9HySezlS-j7Azw^B3J?A_hPNy?#7>3Hq%9O*<(2xwnkYN}K1Og`C*4Ae7Jv}`p zUsF?K@(T+KlB9GxEyFNGEEfBrErMYfvPen-23vq5M~;vukV>WK=;#2zYPGU!*Dh*n zYuUMTCof*SV0d^qZ-HPi$eTBB7#<$RVzJ=koy&i9|@HQtaEe&m1fSpMF4K|uk9g@x4B z)e#DX^5$&++^*ejr?|M7;^JavW@ZQk0z7>95PJCn&M8jUI%jq2^&w@M@u=CjXcvx>!H|7r;vUcKV%*|Quze3+7w5@7x1pE`Al$;nBU zmzTM9>lO}&g98T+01ys`K~gfOI5RV&%F0T!f_OZxs;VkUQbR+7`uh5G?%X+ZzNMu_ zy}i9=ytK5W=H_NIjzl7&qoX6WQQ**_LmD3+*T~3-T3T9k{rYu%|NdPS6%~>suh*;j z`FTlFd3m|Mefws%cWG%!i;IhSZNlkvW;Y7B-EK8BG$gm&`T3K1qy?giM_xsh^ z*(tx@uTUr?N!q`EzrKF`DoMI|^QKOoJSoF4luRanFR-yiIaF3w>ha^p>hJH@lP6E) z@p!bhwx;IhX5GJkKQGto^_l`+uUEF)w{NF`!rxuBiHQl*26E`?>SAzkkZ?H6>C>l) z#bT6}mh$rDOG-*ga5x;my07IOayp&XyLa#MDw>;{)2C0L^0?XASxrq%Nm{?YV`F1_ z^yrbv<*?;{v`i+0wZ6XIu@#F0?AWnmYrQCuNUVENJRbiEWPps@?Uu{sqO7b;Ic{iZ z=$Fgo!sT*t@#4j`93KjWR&#uJclWOxUsF?)b-7&Z-Mg1R0k(*0KGEl&?f?J)07*qo IM6N<$f|1@#JOBUy literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/treportpage.svg b/mseide-msegui/icons/components/treportpage.svg new file mode 100644 index 0000000..0611b0c --- /dev/null +++ b/mseide-msegui/icons/components/treportpage.svg @@ -0,0 +1,247 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + REPPAG + + + + + diff --git a/mseide-msegui/icons/components/treppagenumdisp.bmp b/mseide-msegui/icons/components/treppagenumdisp.bmp new file mode 100644 index 0000000000000000000000000000000000000000..c5e022f200208b387d1da0150ef60a02df7c9075 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjf6WEKV1+>9Kg0h~G;%}WKLr3e<$#U3e*HQ# zGc#5br%s)^Zr!@Ockia9rJ*Yz#heEZ9wa9x15I#oaUt6rb}(RKVgk}Y2eYxU0T~F> zu(=1AQ-EqXI5?D*m0Ma`{{H<7S05Z4{Q2|eS+i!XT)7f12x4F}2NFI&?UycHGBPr% zudjz|sjaO&apJ`BfnMP25xg8%J%KsCnF;R*Ro>8irKSg1DzBS5&{>zGc)tnty^o?t_3D1ggAyd2q}_S$mWc)he!wj09yIc A4*&oF literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/trepprintdatedisp.bmp b/mseide-msegui/icons/components/trepprintdatedisp.bmp new file mode 100644 index 0000000000000000000000000000000000000000..d3206751c1f1b127b9717b1eef4c4f55629f6468 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjf6WEKV1+>9Kg0h~G;%}WKLr3e<$#U3e*HQy zMKLoov$C?v$;oAAX1;p$3fTgn0(N$GWDyV>n>j#3fHHso{=IYOPIh*-s;cV8k00S0 zNi_$qF+M)Nw6qk?CEJ|cyLYRos8DXsrAwE1cz7r`XUC2mN=izUn-dus35+$e%>l;O z&6_vV)6*p-C7(ZkPKG(a^uxl!0!%;B($WbD2@f7TfEWTy4-f!JU=TLce2nx1x0f^q LvN@ydArb-rh!)&! literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/treppsdisp.png b/mseide-msegui/icons/components/treppsdisp.png new file mode 100644 index 0000000000000000000000000000000000000000..64d43b84d4d768dd1a66208f56b5ae669c824b76 GIT binary patch literal 584 zcmV-O0=NB%P)q;!qHVf0IRGB>|O0f}lb04FV~w1=04BGPRX? z0!R6gA|8)p zFc|z4{?SEvG$0~!U6%mRVzHn{6h)y{t3|urjsVbpzYor~+b!`tPlv-Hh~0JnxCT7W z!*LuWlSw2J33R(%+-^4jKsKAj>2!i12)`G2&R{$q(`K`w^?FV1cAGek3$n6poAUWQ z34%a|VbE%|qGw(jNRmXkT#gEb0#zy%n$2dv2zZ`H)9I9ST_=v?sL^QroxyVr?i`QD z(2M8uIWY|LZ#B4M+ct{DA}*Ip5X)pT@O?k1$s?gTcty2ZMX%R`s;ba54GhDe-|yq? z?G2J7h3<#u!1sNarU_lwkxHfBH6bEQCKFhe1(s!@C<@BuG9Fw1J_ldl^?zXS`S}ja W@@lY5ogG2|0000sQ2># literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/treppsdisp.svg b/mseide-msegui/icons/components/treppsdisp.svg new file mode 100644 index 0000000..938d817 --- /dev/null +++ b/mseide-msegui/icons/components/treppsdisp.svg @@ -0,0 +1,243 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + PS + + + diff --git a/mseide-msegui/icons/components/trepspacer.bmp b/mseide-msegui/icons/components/trepspacer.bmp new file mode 100644 index 0000000000000000000000000000000000000000..85599b932da4690d97f49d40196fb65d5a804e84 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjf6WEKV1+>9Kg0jQi2hRmkbOjfF(|=8ZF4{& zPY9r^!R9Y?HQ3BVS2NViL3TebHpt(&{RPwo0r22~34me&$cBr97&y#mm literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/trepvaluedisp.bmp b/mseide-msegui/icons/components/trepvaluedisp.bmp new file mode 100644 index 0000000000000000000000000000000000000000..32ddc1e0133d88b12168bb47bbdedf485583a1db GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKg9Kg0h~G;%}WKLr3e-s24+A~1BfM{m=VlkU^oDj7v_dwutFg5pW*)~8j2wRi$Kz7WS=%PH2nYn zA4rk`kW&s&JJ1}4NBfbIrz}+L!gx6mW|1;hG2l5xx z9FV`bH-F_@^99I&gfl37y511*7towL|3Kjk^w;s9K)qZ$zXQ$TUGo_jUqG(V3}86F z6@{2ni#xs`?g5(v^4Gy1T)Vz=1LGYSU%>F04-V&v??C3Xyp{x-Q-&VzpfpJ~z$m`R QNX(!FjA72G$dCvD0P7bEW&i*H literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/trichbutton.png b/mseide-msegui/icons/components/trichbutton.png new file mode 100644 index 0000000000000000000000000000000000000000..f04359f150516d8d77e215f33c701a301ae2c402 GIT binary patch literal 662 zcmV;H0%`q;P)VqhW z2!d7-VMtI&M(v`3B#I`8TGY-zAPg7P#-Jc*9YsV^HYlN!p7(HgpYuM?`A{N4Jz>?g`YOTSK&R8`y1J|Z;_-N0iYuim1OQC8RH83n03+bd z$EEU;fcrZx90NWir5E@Y9#l_w9;6=5^7%`dU2U4nXCg$ETCq^JC}eX1+hXB8FY2JX zH_x7(n*LOb#FhqbJ)Q%=HNxo2OV+S2D z!pXx9Cpv7tefR0PQ>0_B&A@BJ+fVqAb?>0_7qD(Q>3;>i%foSyNRx=d0IADOlAY_UTGvVAv}L$ z=zn3zbF;;x^NrYLL6wBWIvDD1#PODqC?r=^+qMSX@F(v)VB=^)o;eLHf(A$? wlfcDVTuY-FlAl&yrhvLWc53y@{Qn7l0rpeW;(BwXApigX07*qoM6N<$g0)g2qW}N^ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/trichbutton.svg b/mseide-msegui/icons/components/trichbutton.svg new file mode 100644 index 0000000..3a0e623 --- /dev/null +++ b/mseide-msegui/icons/components/trichbutton.svg @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + Capt + + diff --git a/mseide-msegui/icons/components/trichstockglyphbutton.bmp b/mseide-msegui/icons/components/trichstockglyphbutton.bmp new file mode 100644 index 0000000..472ed74 --- /dev/null +++ b/mseide-msegui/icons/components/trichstockglyphbutton.bmp @@ -0,0 +1,66 @@ + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/mseide-msegui/icons/components/trichstockglyphbutton.png b/mseide-msegui/icons/components/trichstockglyphbutton.png new file mode 100644 index 0000000000000000000000000000000000000000..7e9cd08cb3093d51451f8a2034ef27f53592628e GIT binary patch literal 470 zcmV;{0V)28P)}MSWI^jIyiL6J2>Sj#3D!$ z9K^VlZhehReTOU^L<-{Gf^HTeH3bbl4k-mm+FYX@3jWK5!_E2l?|<%%5)oFZ!b-dU z19W7h6$gVsuH>uLs?q|?Hvg!(Qi`;RTnGSQv=5=cgm?`FCIasQfxtLk-SOqZ7Frn$ zU#7|0YqFLLFnpd;ci!+HqIu1Kim2a=8IH0cnEch2;Xg(=tq`wK!rIL~ zfaMv?WS?x{wM|Yh0uZ5ly^VcXj5GMHgKrW65|g-8S`PgCPn>2zw`IbI;M~6Boo``R zikaVPh3qr}ytav5Gq8^hysHvUC)5f#(}7hf(DTYzWfk88z& + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/trichstringdisp.png b/mseide-msegui/icons/components/trichstringdisp.png new file mode 100644 index 0000000000000000000000000000000000000000..d0fec2d6a2f5d80241b76368f173623e50ca32db GIT binary patch literal 666 zcmV;L0%iS)P)2#WGHcPYFWOjCz-Q8VORRutKdEwK^3D%n%zOAp*T3!Yr060HC=j!ST zhr>ZM8pZ8)4_j0!l{h*&B9TatN~Ne)t7NlT6LsR^0@>|iOil467DK(gMM}xp*%{Z@ z*Bl-mvbea&{{H^^7R}Agk;!DJR4SCqWm>HkjYh+y`!PSy_njR?yN#O5F_FvB@pwok zlVma(TrL-ZKmec5H(;enP%IW%Sy|!o@)AwcOw9fyOim)DM5rpp_&8&Cchu{30H&v> zky6s_cF{C#fI#*M^7%ZgtE(Iw9N_o+snu%qdOdTR4}}71K9BA66#4v2$K%22bfPE< zx~?OoBpeP?C=^f>#XM(P6bgliMx#U`5!&rGZnv9t$(aX<&;)JRUb07*qoM6N<$f`|$! A!~g&Q literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/trichstringdisp.svg b/mseide-msegui/icons/components/trichstringdisp.svg new file mode 100644 index 0000000..2d5985d --- /dev/null +++ b/mseide-msegui/icons/components/trichstringdisp.svg @@ -0,0 +1,388 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + abc + + + + + + + + + + diff --git a/mseide-msegui/icons/components/trttistat.png b/mseide-msegui/icons/components/trttistat.png new file mode 100644 index 0000000000000000000000000000000000000000..0968de5440b29a373a342f1e808a0366680f9511 GIT binary patch literal 1226 zcmV;*1U37KP)3kK~zYIwU%jYR85V4$%bmbQdxQ@YH| z^TRBnQo?-jd^zu)`_B2_d+xpea{w$6@y5l+HI+1!7<=7&j3sLp7m0{hM7-nE#-BZW z^Eczzts};atm%ivCSI|Lcm9&x-4)GejPtiE42Ltx6|(R8bw@#6%N3)_UHJ)Msl3g3 zg{kSOuL&Bh1W_76&`Kjp&;+z79k3Dl7P|8hrO{|c^iA^Vl&LAV=vJ)mryfFvBn-Z3 z`?pcyBgtOQAgSdM>l$r9qkk-JD+|yO0i3KnzC~w`&VDmw(8|xmm=iecUG&n!(egOG zbWcXge#YoL6uyXeVe4$~j0p{r?U(5zgFqz!7FhLx3ClyQs$dA)xNg1p(80f4_mx9O z#YDA-41=XT5L_pLc7PfJ^aIr!=s`b@M6~*4`77t>Emd3A2bW1t-Tpv_81-jF0C3N# zb#{1pXXydj+OE*mQ3d{*V2YZ-@&I>fw}yrt>#x;QSGo?lzkVG=GGfAD4!rSRN^liM&H^8;YPq0FS zR!C_b#{eQVFFv?OC-8 zZ~~NW9fnp4jYb7EmPP!ag)HB=5ZA>rmSinr>TORrcq@<&n2pUmH);gtzybJue?Q27 zP{n8Oj=N`60h|No0@*y9o5S>3gNbWxBL?UN90ev3xQY(o>e@mM^o?Waq6GltFZ*z( zF8ru4<-S({0qjBd?c8aqr`-6O;w~?b0y#iD&;oo9`~XySbg<3oU{rD<01Mw*P#eBQ zf@V&_ocm(|OV`yfdsZE`E(;x`W3d8h6jXq^gPMT@LNsswhfNlVd19a~4+|&OT07P0rB9uQa{Ju^(#yKvUdrhaH z@pjs~t;x}Lh0UfSs>!0nw7Jf?l0%45(SAgMpwJ3LDKtT?G@v5d!S#mg(EygY&n(zk zzr!eLC^16qN}u>XO{F&u8i#I_8F_0z2(&Ra@usFtI9uLy(m2yxZp?f>BizQk@!spZ oYwuJUE>EqI>`ZovO}v2h7sn-k9x_Ofp8x;=07*qoM6N<$g0D(D{r~^~ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/trttistat.svg b/mseide-msegui/icons/components/trttistat.svg new file mode 100644 index 0000000..5af1b3e --- /dev/null +++ b/mseide-msegui/icons/components/trttistat.svg @@ -0,0 +1,299 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + *.sta + + diff --git a/mseide-msegui/icons/components/true_false.png b/mseide-msegui/icons/components/true_false.png new file mode 100644 index 0000000000000000000000000000000000000000..01fcc9d40da076d40eeb424b71989260245471c5 GIT binary patch literal 382 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*O%l>?NMQuIx9s<%IQhPIKpgjFBvHjVN)>&&^HE zD`9XhN=+gVM=Fj~3 zKkk?k`cC$4`pOSM|h=;8Wn#r@_r3uM2>w1<{%+xli1r{Bh|s(BatU$yGauB&O) zYYWspEa|r6&b3XN30+pRI1`%G_q5$%xf+}Ip@TJw^8w%chho38Z#MJ&%Kyc<^}A0> USCO1Ld`eP$Z{_}0)pcpNTG824E3@Z7}bA|PX4aejRzPjJLCn(@Ep^Wg=2SY;9uBo6c> z5G9El!wC`xh7gQPNbB1%e($@Uz2n1aVywpH?VD_E zf%h~3;Hh|w?>+2PMc_M6OdeWtp7C=KBYgz8x=Jj1E2(Ea*1Fb-ar?9dzyLsqZyf`3 zJ#fS6%!BHTqt>%~uO-|!zu>WJdL-ArTks^3PU?Xek+fIe1tWMgRnFu3Z|alPSyLIi ztdBJx!(cXR_ufqRg}extiis*wvZlwI&{T3?vLeJO9#OK;lik;(C-5+-0Q7?Zq}C%E zvwmiM5+2>p$q}|-#ya;8{+ErFbR|j=X51ftrRlUVC8kAn!@yCl2mM@3f0=9CzVm2f w%&M+n@vVodU61MTo1inR&S6_M@rtR(7BPe5nb)Nl*wOQG909*e*#5YF0eRT1f&c&j literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/trxwidgetgrid.bmp b/mseide-msegui/icons/components/trxwidgetgrid.bmp new file mode 100644 index 0000000000000000000000000000000000000000..bef2801737f790de8162bdffa431b0c0783ea566 GIT binary patch literal 1782 zcmeH`u@S;B3`I>tLrKF3Ouzv2?8F*OkcJ_=3p>z;M?U%IQ;gxlaWv>;pCidn-%heW zT$gFE9rKp4d5p!dN-2|HuQY~2ratw5e|ZDP53GcP$vHEhF6ZFHL!^9U%eOh*XzDvp z4 z(0s~$eZ0gG;gWNAfx?20y!U9ZUSbvp;z$HJ8$<*dDU{sW>Qngk%uSxEkFomH4nJ zFuwp{#;w&s*+4caBgcEV1V*SmtQn;N>U zT6K!w;8=kSyOI-!qP;>(gCSe!-n_tTauL~#8MnWEy8B;D^nSCu*UA^SKQTq#tG1Pq SE7k$}hr!d;&t;ucLK6TpAAfWJ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tscrollbox.svg b/mseide-msegui/icons/components/tscrollbox.svg new file mode 100644 index 0000000..9ae5e6a --- /dev/null +++ b/mseide-msegui/icons/components/tscrollbox.svg @@ -0,0 +1,413 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tselector.bmp b/mseide-msegui/icons/components/tselector.bmp new file mode 100644 index 0000000000000000000000000000000000000000..519ba003b7ffba599527e8a681eec661e146016c GIT binary patch literal 406 zcmYjNITFG!3{++)GD9JTijtCd(DNPKsGz4dP^l8>`m|9wl5ImeRWYL1~C emr~6lTqgQ#di1F|mfZ9xV?NfJ(}6lXN%;fM=FpG; literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tselector.png b/mseide-msegui/icons/components/tselector.png new file mode 100644 index 0000000000000000000000000000000000000000..92b110ccda49d20261664eaeb1ff098c7088b207 GIT binary patch literal 704 zcmV;x0zdtUP)jOgItpb-CyV&Y%n-=JIF z?ZV*3MC#x~QWhY_L~2~y=xE{~10Wkq6Rvq2K6{~3KfZi{Uvg=Cy}r-g)Azj-wrvyJ z#I|iFxUNe8bX`~X0iY0qmSyoL063jaSuU4X-X-iTi+P?0%d*hzc2kp>OeR|lz``Xa2y9D;W$pprYMS#%jHtR;yBjUL{YRN zl3*+gBtaXE22M{;aeaLa05DAxmzS5R4?jLWP_0(+{{D{L-CfwWow+LUoef(<0NAR4 z0sKj~Z6Jie&iY~hP8fy|LS)y$CP?x>vkm~D)oP(sD#0{O+}+*%8b}C{*&hUfZh9;L zok+!E5f2X!h@uE*XJIMxznW&(B$_)!6IxNRkH!2Yh^d-G9y1(x|f2AHxaVKf@y z#lIT0vsV%gc*? zUa{!*_Lfpg777Kn+ijAh=Xorb%gpEVytuenYmrhaHIYn<{+BQe^?j$)fo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tsequencelink.bmp b/mseide-msegui/icons/components/tsequencelink.bmp new file mode 100644 index 0000000000000000000000000000000000000000..b3d7bc598ffd82a10b11c092e7f38bf5dd1a12c3 GIT binary patch literal 1782 zcmd^+y=sI&5P(k(QfR4QtZXhSDA=VFG?h*4e1dE4IqndxuTE>_JA@QgR)Vh}h=r(4 zy3-6AmSs;5@2ouG~5M zWN#pNT-V;^90VaybN1`EaLeSo2!%)9)+afTGH1U{`|IA%zF)b<4gh40p!8AM?RMMk zR+eR87Dd6bEP}hP%k%tr?YhqMyq7@~MLC^L1P5|aFwRNSl;b$$3WC5ejH;>tTbAYF za9GH39LM*4#1RA`%QEy;P?m6#B#|U3&-0PfG!4TrIAkHmw(T$sQORxF(lmW9CyrxP zRWFwd;s8Mu#e3_rEGvp4$i+G5^Vu}bx~{l{9i~ih;0h>B)1YrK W_v7(Ma3J6@!8xF>S&w~SGV2G65$fRp literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tsequencelink.png b/mseide-msegui/icons/components/tsequencelink.png new file mode 100644 index 0000000000000000000000000000000000000000..a6f77320b3993cf12c210aeb5c8dfd6f3e8b1f47 GIT binary patch literal 466 zcmV;@0WJQCP)vpI1-pCOQ9r$>tAGgLr}{2o{sUU>8iL z<1mZSV6h0ME1rKs1e3)kh{>eod<`=vPLo_6cq=fr5CGd(gtBeM z)B`Xt>3h7SLrDvz08t0Pb_Biym%zECMM?X>Rs{c0tv?ZU7Gno^il(oUb_g2}&;l9} z`UtGs{>(Vp#=dcgqkMvAvV!s4W`$ox-WM6W*zF$D_cxn7*gTCR1@xQdKn9(nV(OJ; zNQtt5bQZmK(Y?q~wnY7A70mMiscA)X7 + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + INC + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tsercommchannel.png b/mseide-msegui/icons/components/tsercommchannel.png new file mode 100644 index 0000000000000000000000000000000000000000..d4daf5553c5fb689a25e471cfc847e591fb2428d GIT binary patch literal 1062 zcmV+>1ljwEP)(EqYl{x8@ zGAJlkw@*{S)s1ahU;06z2tvmwB4bbo!k~hF{Wv0G~(--$5)jW88 z^IUyTe{k~qFLmGOupw=IRhmE9r>)r8BhLbW=p)Yg0o|8RyKLJ_-pu8%i{AdjTIk^5 zitCF36%sj4=_`1N^Y|`rrgevyE;kLuSThu3O<#bq0f2I)c@MXF@{R?vB#9UXc;qP| zyQ|^WeJ$I?^qvFC&BQMjf9|C2pB%G10I;o7ngf8L6NSLUB~wgXvxF_rikWJFswO|* zEhqa%LKB>aIEVJ8>j0o}GoSD1Rc1PRm6;7K`~m>1j&p^39^wj=BktDMq|}lC*MBmF zk9%_AP>eNSIi%by7D{t!Y8k7(iPP(wI9(2wBwDwD>f1V{RJ4H>2ahfImn2c_UTO?~ zR`3VzV$AHkLxT~<1c0flmgm%m3jqKK)v@NCYj$+|X7@dvTKmLqZ-q?k&K`LW0RHxt zSb_((2>Fr0qD&ZI?*Zi&<>4l-*}OXEP<76slp}7#gPb0SFjnnK*77QhM{K%hOJ;XU`cF8?h+ z@9s=Y4iH-jGWL5ft1AKEY`uR?51bs4GV&jwcoOkK5v^&9y@dHlkDISBx>Q?_upQ;h<^_;-c` zAUS!(62hxkV@)H~FAV5%YrCi}?pGm^X}E-8;V#aLK4Qn4c`e?|YyJ>x0lTx)@%|fXl=8&wcvndP!0I@?{WFO+&|+%F<~Fqn*>bMs8Bx74ZVB<`Kl}s! g4>y?t$S)`0cU+Eb?~16K@Bjb+07*qoM6N<$f+WrW&;S4c literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tsercommchannel.svg b/mseide-msegui/icons/components/tsercommchannel.svg new file mode 100644 index 0000000..e1c20cf --- /dev/null +++ b/mseide-msegui/icons/components/tsercommchannel.svg @@ -0,0 +1,215 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + SERCHA + + diff --git a/mseide-msegui/icons/components/tsercommcomp.png b/mseide-msegui/icons/components/tsercommcomp.png new file mode 100644 index 0000000000000000000000000000000000000000..deb6f1811f29790bc2e16b99758759cf191c08fd GIT binary patch literal 1300 zcmV+v1?&2WP)2&CHqiLW5Qb2qBB@h%9W5A6D*BD$AX;9E0(1@DU5QVBNwg!+*P_!rkg&+u6TA)y-v(LA${urkY zia#;Y_v^iL-@E57?_6THJ>(c}+|tM!=o|p>?-KO)n9TB-iK_fLo3N;7rp9X?9uXb3 z`y8f!)tYP*0MM~s^qoJUbJr#4>QFqfK9e1|Xfgn> zX@wA+w!oQa*%SEf)3?M>k)JRVS1kJc37ykqn>e&p@!mX%6VDvc`0Z;&KLErpTa28w z$?FmvKcKqrd4eDKc8lTx09mlfq5x?I!j#dx!F$orLCk%@9o@7-DD7w!{Y?v936cbA z8yM-}XNu3zb6H%sM79mcf=x}F?aUn8t9k%n_EJ8!W=Xo@>Bjg_DPxlkp0IA3z{=UA zMIG)`z0)6ZB>{k<346j!M|#Hw$@h;0r@Ay}qTgcLUdonsAJ<)mW)tOgwAOYmbo#DE zuGreg(~;FPeyK??#Le6s(72W`;&hyLE)OS%pKddMl3DFs0A;39t8kJ zw29&4Ss4I=6_g(BHJN*#b;qvun9SLux@*od_dsPmt^Lt2q9{O`p(;uT07J7;+rTKC zldwx7lv+EQQF$+E0WgXG$EeU%n`mDtl&pIy9lp|?`zZkMRhv}2@_|(3$DOJh0HPO6 z=Kbd~p}hU_IfLEYB9x?}7S-CEF3aPwOD4VXwQO*ZptU&@P7hdg-B?CyS&*y*fSn&o z#htBE$t_J>W^;>BdiXphI&sL8~}XZp?LOv zEc*d~Hgucl{l##+xj)bi0E%E!@jjFOVx1U#Wvjm@SV8FxjhwW4QL6mD=iSljk&JY7 zkIFYKbfqqyHaLGc*XWv2IlO8Ft)4xqyUJ=P6#&RfznX0INLtRPH)AoM2$WNXuGmDd zBKO!AA`L~#&6oPySnP22m2Bv>hKvzOhsP#7U={uuK!gkzFc(>5RdCy-D^( zhSA!T`Od_A>>qJEJ6LiO z0G7N{botBo#K5XWsmT4Wdah73?Ac4*@!}9^ET5UE4iBZ&8H@P@Uqo7=DoP(WjT0Ig z*(?B5*3*iEC#

S{u{IiVc(5EJeevtfv(K`0p#32B6(Q|Jv_{$`I{(KY+>r0000< KMNUMnLSTY>e0GTd literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tsercommcomp.svg b/mseide-msegui/icons/components/tsercommcomp.svg new file mode 100644 index 0000000..6fc1441 --- /dev/null +++ b/mseide-msegui/icons/components/tsercommcomp.svg @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + ASYNCOMM + + diff --git a/mseide-msegui/icons/components/tshortcut.bmp b/mseide-msegui/icons/components/tshortcut.bmp new file mode 100644 index 0000000000000000000000000000000000000000..c7a36fbeb59dcd0ffb05aecc1b14aa1212778fce GIT binary patch literal 1782 zcmb`{+fEZf90u^OoCV5FjW!VOeF7iAdtLz! zGM9c(ZkdByRx`GN%iYUc);W-9$%8qRGro%N%A+4jya=K10(9A|;Z6r5Ycbz)pORpJc&sTXI!Z|U>eI===TW9IWL z63>W7#67}sc58=Jp2h(`+V8cU{AQh!pDFJw5zk#`!sJno4Zm4GkV2 z+Ask9y~FOToVZAt6uK2%1yM9dv8iCFLH=5_g3d;O77%j^TlCN}&;pt{g}DfcBh8#B zMsq)hsTw?pUgSu3u}fDtnyuHZE#0$piHeGtY8q-$e#A2{D~C4_=s&W)mq|MbKTHKV AF#rGn literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tshortcutcontroller.png b/mseide-msegui/icons/components/tshortcutcontroller.png new file mode 100644 index 0000000000000000000000000000000000000000..15c9bc1d3fa992b137443fc9a5c0dfa9ad5227ff GIT binary patch literal 867 zcmV-p1DyPcP)9&ilOYc@O6WL&!es=VuoR1m8Ce2JP11ptf19e$DcDc9zGpC&*;8mWc_i zWpYxRsZ@@+{N;IheKwOx`(trYD;9~qvMg(7S=K%~GSaZOwx-=$UVg?9vQM?E)tzZ_ zc_BpzK+~WI0d=yT-oxcTZF4zJOi*a(FFGwQZVNs_aA2U7_LVpQe4d_uMN9MZOMIDx zJ~%w&bDal=hbXG8g(x)@2`Uv<*Vo-#bxX^cLjGZ4|M*^Zbckt|$Fp;Zx}F|nDHK>W z7?6{m4t0IKn``Us^}70}jg5EdPu<-wxWv%Z6v9G6zz~Am^mNpemI45R<#GT(P*fBE zAV4O=z2f3?lbrd;*4o=jiL>H34%F4%^4X{u zsIBeys+|9XPe(EdwZJXhzJQq(*Q*sU-e`?y@$(x+U9bcnCQsJep)v^uJE=Z z*GIbyeA=R$F)@WqZc54sfQ<7F3X_uDc2I0A0KhsocVU8Ut2K~$lAZnGq6C(S34jm? z6B4jvGy;TNDDHw!TlCFjYM@gpE3>=}a1A?eah1<^(yJRAA(t-AOMEe#uQ1M|Bggxd zl}@=-Y6AdqW~RpBbTa;Y{_dh)-wpt8hKH|LHa9;2fGDYS>1|uv5CA-?s){#^j>ZE( tiApt8U0%Kf01*ns!}ZP0Yfguw_z!su>mEaZSy})9002ovPDHLkV1h$^d^7+6 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tshortcutcontroller.svg b/mseide-msegui/icons/components/tshortcutcontroller.svg new file mode 100644 index 0000000..e6dd5b1 --- /dev/null +++ b/mseide-msegui/icons/components/tshortcutcontroller.svg @@ -0,0 +1,224 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + Ctrl + + + diff --git a/mseide-msegui/icons/components/tsigadd.png b/mseide-msegui/icons/components/tsigadd.png new file mode 100644 index 0000000000000000000000000000000000000000..dfba5ad5cd360fbdc349b1989572c48dd68fb67b GIT binary patch literal 735 zcmV<50wDc~P)vV1PN+3NRhZc=Mi$(wdOR*RhBN1rPXi6j`gE75x%+HdE zeCb#v+;89fm#8QV15?v0id=KFvY%LX6%JqTapor@h(#Ch=jSg_LU3evA#OZw$M%Aq zkSRrun!D;0$xYoax&h=TYtfjMy_^I9rtEB(RTWZVy_%&pMH@D5f}*gL@#h<^bdi#( z6V95eO?D9%O(LX`x}J5~(&-{y6Z)F&*|E(*ORG-46h$x_4x8!m%MC-K2mrxHG~^F7 z(+g##6`}|-jmF<}(mRnSiopAI+yF_EwZ@L;Z9Rc0-Wv$=H3oyGFs83l*N6HhL) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tsigconnector.png b/mseide-msegui/icons/components/tsigconnector.png new file mode 100644 index 0000000000000000000000000000000000000000..7f9bfb055e5de95b2bd0e59067433c54773e2f72 GIT binary patch literal 774 zcmV+h1Nr=kP)gxvmpd(x=N!T_{~7B$#y( z8bPUOV;5$nQAGK1EW5HW9adA5rWY161nHu{gy>@KD?c*R)U{xn%;iTl>GdM)W(f@g z2fYUl59d4&&yVwb93BXQ7>Z#`+NM+n`aORB;>#Sbyw}tj%a|0)n553icD(V=^S5(B ze*AR7z@PilD^-@^;36OUy2N*>RI`jRi7_Uw%Rl(I*MCP8#Sp19K5EN4aZ*nS zAb@}p0)Zeb2`E8W5>WhGClG}7VOs+1QSMl!NAmLhkZC0*B`r|7oCAPuVzQlTV+e~(~*e>a=icmWKHtXoE!&r4Gt(H6_&Qg7?3gF%mRdvuUPX&O`%7ySj8Lif2U0UKH(jQ~wjorM6yc${8|O~tuWlHk4-PvT40_a>I&dI8W78pW4Ovl9 zT!dD0H?%q(uGQ39Xh+>GO{C%E@H8itf+kZ305Dv-JWXO4lb%hw znH-%g5K=E|qh;(((bL@XB`@UyEChpzwCHBdh+F_b=D%pf?P;Xf^K%R30>s6~|DxWR z>14S8GoPju5Ckz)-_zUD=kf7=kDqT*C_=G}N!yh>0|VXwAM^$Iji%=HF-DV>?XU+H zxNClq=M@yLk1>X-tCp$7Z+vFyJ5N^ao@Ib%7 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tsigconnector.svg b/mseide-msegui/icons/components/tsigconnector.svg new file mode 100644 index 0000000..fe01046 --- /dev/null +++ b/mseide-msegui/icons/components/tsigconnector.svg @@ -0,0 +1,268 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tsigcontroller.png b/mseide-msegui/icons/components/tsigcontroller.png new file mode 100644 index 0000000000000000000000000000000000000000..174aff3dcd951dcb725273ba102c74503117ee59 GIT binary patch literal 955 zcmV;s14R6ZP)y#uyVAW5V5NZGI!vEgbY#4JPCn~qUK=xBltoepX1 z;^04jKCV?iLY3Zt!paA*+wIsEyBapzfT(wIR8%dktI{Z?0#5BsgKzLWB&Q$4ER_lX z;2RVSKJN@LIEa_^&qTeKif&ZWQ%Q*lVgkF(2JQ0(tcu?ZLdXct%g-O>PwNp99xk;% z>55vL8ezBD;Nk5p`4KT}S-*A(oijH;CnjKH#sC0p1L8ePp<1H}qsL3jOT`2petzKO za=dBN|CTQ;xC(tsi)4soMI0wbkU9(%g$4Nb_3H@k@q_!wNKHYzPAlr)bLemhy?ErH zS}J5;b{^VVnsIE`PH3ANVd?9`?c$p_xo;1GLqid{JVw-;n7pf%R^7ZFB^5Bk-5n?L z3t`Y{k+3upQNAjqCnq5=Bm_CvionU`Qg(2XtOEg|p}2If64u^c^qI|Yb9cvB7Z*?> z?OPDwzm+cAwE2!RApkIb;v~%W@*4iTMuWM#dn%1TaHzrAfWN^n6>XHy{JruIE}S7W zv>P&sXJAlsR>j@9|Km=U5ptAv>RVNRadM}i*J)iLlW~@#Ma8+d3|)Mg!N|L~x>^*B z2~(6aOqxy;U)5#e_n*!ge#WRH7S%p6nfba8J$y{un&D?mVrp86wx^fZf9m5^KE7>? dF@fVa%Xe#OB&6akY~BC>002ovPDHLkV1jq%xkUf~ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tsigcontroller.svg b/mseide-msegui/icons/components/tsigcontroller.svg new file mode 100644 index 0000000..ac58162 --- /dev/null +++ b/mseide-msegui/icons/components/tsigcontroller.svg @@ -0,0 +1,226 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + C + + + diff --git a/mseide-msegui/icons/components/tsigdelay.png b/mseide-msegui/icons/components/tsigdelay.png new file mode 100644 index 0000000000000000000000000000000000000000..db381b0289371ba9ddcdb3e47ddff959e23b7489 GIT binary patch literal 822 zcmV-61Ihe}P)bBbg?3ky>Gb@l8vLMWzv!R&-|vHBt$aWtiTmSyRHMsV$n*IZxH3KT_yMjY{Xz z_TIek9-impdk?(edBNsFsklKVv(y{StnuS0%ehi|S3;>Mp;X+djP7bRkF&N>D~n4? z)-BqPoyx6!W1V8X6Voh6E+3+lij-3ES;s5w@XS~C)?_Xg1i?mfu2)nl_p8(#0eBE_ zgn%bl&;%U8f+pawvX3WN@Gry?AVjw5JGVO_(F`Yvr@Q zWIjI2`UHE49}Mp>IW`KO5D-E@0QmX)BUllFuC|xxXnlc0>MU&b^<6f9&)&UVLU)T! z79P8A*?@uG9vEJCFM+o=H$ipqFtYOt5FQY+AAEF4AA_%?#fe?gWrP>u0g>%}g4j0+sE?UdF<_Xa_ zb(=@Ro-+-;4|W#8 z;6T3{cwVq+svngs=i_T + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Z + -1 + + diff --git a/mseide-msegui/icons/components/tsigdelayn.png b/mseide-msegui/icons/components/tsigdelayn.png new file mode 100644 index 0000000000000000000000000000000000000000..676fdf8db6d200480781396770ee60fe9455f57d GIT binary patch literal 861 zcmV-j1ETziP)al1mHoy z5dxlI(Gze4i=KeP@)%FBh%d$xz)iaO8@DGkObrv6jjin@XDV_4XzJ`L=Mp@3oHeBg z_jPX0YCQz{*;%|%y#xU0v|9A_bQ`eJqCy#GPN}#aff=0+Eae=A1_m&uR->b})qu%! zvLm=VZJpQFBLD!A@h4E4pNAg{3x8q4N{ItqA2B&L3Z4)ULO=l6J2=3_)eX&!uh67= zfdhv^A=x0ok(gNAEh~ZFzWs*$y+J|ELQ8{E>J@nKp8`D{?dWQ4F_6EmuS0lDERxeR z;N>3x?|=Y|4GjSRJbZlcOi}w={;i7p&xskO;=QhZy4s-CS3W>xc^S%TpFkp!7&T}- zAz3Sa(UNtyx8dg1D=2=f0JX3%CItYH5PdX|bK36Svr^EsRtuJ#gv=You(RK4G&umM zlu9oyx4O1^xqyZFd1ReVM0D~Q?DXFKU*t=+;;JagW^k0bB0MgBP2?9cFISP^xOhcU zc5djOMgA^|2zPbH7Dp!t!mm9z#V3;L{zheeMD zM_A3Enn^4z_2!g{o1}Ic<*eE#o>C8X09cV@{==ujUJ%thwfM=2ErLD2sM{ow(hVS|k400000NkvXXu0mjfgE5PG literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tsigdelayn.svg b/mseide-msegui/icons/components/tsigdelayn.svg new file mode 100644 index 0000000..bb53e57 --- /dev/null +++ b/mseide-msegui/icons/components/tsigdelayn.svg @@ -0,0 +1,233 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Z + -N + + diff --git a/mseide-msegui/icons/components/tsigdelayvar.png b/mseide-msegui/icons/components/tsigdelayvar.png new file mode 100644 index 0000000000000000000000000000000000000000..1a35109f8b4099fc62668389d3cc235930cd00a3 GIT binary patch literal 884 zcmV-)1B?8LP)-$ zw4|(1)S`ZrQB+`E6{Ii{ld>$TKV_s#ni3W(F(I%OnMh5YHbZA?&a5WAkwJgvqCj1Z zoj(WeIrn)k=REgtAW5>rhjV3aNQhNuwuq*IVR86e#dTlK6<^Mk6`Ev2tL39;8@7oJ zTQl^N=Q)Q8wXbZWqI2Yvh*GQjIOhuITzT03qP&0XtLPfEl*+Q~pu<(wHJVN7d5i!F z1V#jj;PeDWaC!p6)G>+Rj5~7)hz$w;&Q_;ww!ljkq*B?Lx4;3Q{f+S|%UuRe z+xYk_PXKIID>`4k000=fx?s22T(K(`D%H%FbHx(^RcI*cZr*^&XhcKpZ3L-Qu2^|# z$yTcC9~6w}v?nSWvyWg$>N@D!o?*`H*?*`=p6+$;jBjE8Fbs(ZL<9m579Ni1m{=Iv zo}#_A1v~Q!pl{S++pcUhY3s2oC)ag9B{kI`EnXI%85X@bft)%fCp!_r(DE3s+MeQl zp9$|xy|{I$3bO2j1Whs)MMNSgWi8A--544eKtW+4nj0E0f8hcIt5hHYwrtC|K|Y)- zcZ~gfrV>4>zl-{-HK=KP0Dpgfw?3LgR6K2oCawE*2d$|Sutjcz13;@@pTNrQHQt*l;pfBziudIqYySZ(PfYqJ@JX9? zR9r3*h)~BMJ$ui8fgde8rKJtodz$h~%F_OB@()EpdQ21+MnpoEf46Gonl(64e%|dS zyRD-C8P^g~u~(;QV%(BEwlRBev$qKBHd_$eeX^*-TLi!iD)Q7i`pxC+*yfFy-XfS4 z82FP7ntG$XMPTab4uB-dj^f(73k~KWp)*^Ae?Wl4mvd!aNT^jmXcbR}tm1e@rE85@ zrAanCx7x+akE0?jBh$6U6cirOc8`7*rcYl)v^u7bbFRp;?Dz#?B?W+=V-?5%0000< KMNUMnLSTXw>5FFo literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tsigdelayvar.svg b/mseide-msegui/icons/components/tsigdelayvar.svg new file mode 100644 index 0000000..4670601 --- /dev/null +++ b/mseide-msegui/icons/components/tsigdelayvar.svg @@ -0,0 +1,233 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Z + -X + + diff --git a/mseide-msegui/icons/components/tsigenvelope.png b/mseide-msegui/icons/components/tsigenvelope.png new file mode 100644 index 0000000000000000000000000000000000000000..5a8545b1a859a6a07538b1d58ea47cb058de78c6 GIT binary patch literal 955 zcmV;s14R6ZP)l#Eik$Nx-i_D;4Gb9MgEYsRDEsS(eXV9=8ox$w{EL{;txpe{R2{_-Ts<$9^#ybZa;YBd^7k-de-Yb$QTQfvZ_;O@)s7Z zrvwl{Kna0Bpp68SKpP1t{%jKnG`qHz0F$g~U+ByQi@eYf35W4%a1e=t*Fqs8ctA^WcG{w5H8-9Ec|PgQ~(j&W2TGJJ5XNI^K16 z=_ZLMIp9-}Y#Iw@Fd*4v!pcosajJ5^u8+?yENo$|O>XP-Idh@PGSV_K;>Ja5)}ir2 z4Ng|<#Tb(b1OP#_z6k(A2ne9b1Vqzs-nk1@5C8z@YwPaNBO6MK0ia*@!eSdC5Ez5& z`b{LKr2O?CcRYR!=TBa<*hH0Om~FNnjL9Yw)^0EV>rTFZ_b#fdT=D%SD_6{+6LKcM zig}Rsod^E|hbY3+(H@tZ-R|l1(A67PV;)#C#_J+Tvsl3dhWB#(^ckrlRrbO>&i31l z{{ly@h!^c00D$s+74`Jo{ylks7NQJ&Ap(FLF*hEj(#>1CXw&6Og^`HXWa;Vp338|Y zkOv9?1B!w%si_c{K|g^g;(7a10KkmNj`ei@>UFnNS=L=aF=S@j;eW4SC>Vt5_nYaO z-TT_2@z+;DF$jWyY=;A$j%cDO01WzlzciU1O!*ZiGNcCGG9*$^xQiPoiKj8UX;^uR4<;2rO7xd&PCFr%!6=@k*nTl7dFg zL#ftu#oen&O?`^A>)46-GbS&;pyi>WO0B+tv|!ot_%o(-+xGg-zz3;&;G>jfpZJ<{ d9%76IzX5SLG9JJW+*SYp002ovPDHLkV1f(hzQh0k literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tsigenvelope.svg b/mseide-msegui/icons/components/tsigenvelope.svg new file mode 100644 index 0000000..5901301 --- /dev/null +++ b/mseide-msegui/icons/components/tsigenvelope.svg @@ -0,0 +1,256 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tsigfft.png b/mseide-msegui/icons/components/tsigfft.png new file mode 100644 index 0000000000000000000000000000000000000000..3b458b30d85dbae05a6e24e81632f4a775c33200 GIT binary patch literal 850 zcmV-Y1FigtP)p`#rJlaXT?`D zRx$Zlx?#Q z%MrkXz!8BbIA#JzaLfb_e~uHD@KPX3s|5fYNKEV%`a29tZ9)0Db{g6KFMk`5pJV-GGB6+jykgCm()PCej>s+=SO zfEkk!D?h%21Hnt7fVZD70ASAY5vK7m@C3NYWC+|Iw5k3%S(yn!$nJOkEPcX*p cf*{y_1L<7rrySU}#{d8T07*qoM6N<$g49}i+W-In literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tsigfft.svg b/mseide-msegui/icons/components/tsigfft.svg new file mode 100644 index 0000000..ede89af --- /dev/null +++ b/mseide-msegui/icons/components/tsigfft.svg @@ -0,0 +1,233 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + FFT + + + diff --git a/mseide-msegui/icons/components/tsigfilter.png b/mseide-msegui/icons/components/tsigfilter.png new file mode 100644 index 0000000000000000000000000000000000000000..7a059f0b1ac39a2d9df747af7944eaee68fc7313 GIT binary patch literal 922 zcmV;L17-Y)P)1s#F@QbOzy0XOEC}D)*8-W1>A{VrWEUL!F^lc-+$` ztX!9%{%PNly1)EY-=OfOe@O6FsoEK1B4bQ^@a#pl_LEt7*JU`t^Sp(m6`U)KShac= zB>)EkN(eZD(UpJ_jIIO}fA?_&qyEuY0?bpoeWgoc;|!RBh6egkQ*|3=lWCk!;qE>_ zr;@zx{yoGk4#%~kLL|kn8RviYzWD-83R|%Ef0EbUt;X@RR1}t1;?k{Zm`x@$)IS*) zN52dYJO69)%XzuT&dfkTX&C|+hJaFvohd1}eD=(kxbyjWD&jO_#;20kA7)N8Tr6p zqPjvZ004OVsnF5hChcWykqzL7jy4%Znv?%LPnA`xZ#@6-ZeJL7Rd!sB`R)FuX z3V`Wok?PkB76;DXMPs&Zzb_}i%hwnB&Q4gZRt)s@Dd@J$BTaGw92^`mOW}rYy&k|c zvMsA+;jR}j0Y + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tsigfilterbank.png b/mseide-msegui/icons/components/tsigfilterbank.png new file mode 100644 index 0000000000000000000000000000000000000000..8a21bae7bcc891fe1a797ab6a1fbc44041e657d7 GIT binary patch literal 1621 zcmV-b2CDgqP)bc*FK2$=IrsbD?|;rc=b}`qqB)`%->TOK+kAfeyORO?%dfxj z7quwH)uI^RQ&a1>>JQnk1?KFHCr);6#7}+ie2a4~V!u7VV7Knr@v$h1aZwcGoi}b? znE2$b-96)fO{G#r6)*qxcYmn)@>6F71t?JQ8%?Xzg@sQCe|hE<=bDZ& ze&-GVuQtEH>4u|t?%W2zb>lkUYOwL+?=%B2c)g!zZAUoY{O!*O+!!ADqtLvs>fA

E77GzK5`E7mD6Xq(%J&Rwa#`SFO=lSN--0V;B zr<<^{yj-vW6T@z{KU_uAb6?|X+hxYxZgy5Z!tt+uo%b$Z;{N^n3_G3FHa)??qxE#Z z(}vqQ$dM<$L~Xr|j<)}1CI9_fZ|)G(q8Q%@M1nzdrDc>?Q~=-|`3QYk8J3Fe0EGOr z%m*b5Wo3M^wvO8l2O&wqSZ3ltT^%mRK$gIT*M4zAxab=G%|;+B1t>Nc0Wg@&OpSTa zrrBsV6PTW6E)YOxETz<9!9P7kDBwq5T8hbHVPhEnHFg?Eczr8&Z=N~Vgg+{ zVUAi&L17_9TeiwvtSv$EXMI-L7DXh9;Uh}>fBsdUq_)(q%1R;Sc%0b*6HK~N|h?h zbIUd>Q@+g#vMh>7lI%CYLNG**T1_Cm^#r97wJ4%gZoct)GRaCTmR*5wvw|PI@@k9l zr=R_FAHaMdfHtH2ImwTvpb&qCr%FLdGO;FeY&pi_LPTb>)ykB2LguqCeRoXg`PV;e z0Fj_1`wgibwMDCC*1IW?NUX6Ojmo^Vu)v%oWm}Z723Zz`W~R}Z%H@IJ^fcC84{_^y z9{}-Kj6@=V$DKN5S7I@iqftr>20TMU02G&$P@>Z_GUNte|L$F9gr;x2&;j6aI@$S! zJ+i=vbC9~Hp2pSN%i7v1Bez`ae7K6iz7!9;oa}m}ipP&NaU}k6<0Euz&qq-*WO0~NG1}DyWKomTSrA@C9b|c?l=b6bKoG`cULml+skdo0DJaV z^LS$;?{{{}0!JI0=;>_FwrHTM6YK6u^72zBcYjw06_u4}3JR#Mx6yZ{i|$LU95`y@ z(6I)tb#>C-@*fV>+t|Cm8sGRB3*j&T`>GExF*Zgd9L6=_yCD4V$);yI{(g}YFUt20 z@BZx~&z*Y-fNEO<{oPl{)o9pzsD_$j4SaB=i#&~n$7*U(s#H|h9mdhu3#7h{Lx+!W zqxS;}3Ja5p98rw__2w-xzpzlg^zSX-rJ%4#zS!5|an=(F3X2{+zy0sGF8OBdZ9cy}FF!x37R7k6-Vp4b3EF#RgZ3Z2 z@uvJ6v#+MsF%S&fKMY0e$4@>Z|Hhm>|NWNH$fA9GVafiv9Xmf3MKP{YsiOY_xGH6j Tr^H)`00000NkvXXu0mjfVb&Ci literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tsigfilterbank.svg b/mseide-msegui/icons/components/tsigfilterbank.svg new file mode 100644 index 0000000..6d77dbb --- /dev/null +++ b/mseide-msegui/icons/components/tsigfilterbank.svg @@ -0,0 +1,320 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tsigfir.png b/mseide-msegui/icons/components/tsigfir.png new file mode 100644 index 0000000000000000000000000000000000000000..4099147f87cf44c7a72bfdafe8b4715e7dd9a006 GIT binary patch literal 895 zcmV-_1AzRAP)?|q;5!V8w=oL-a)3Z>HgsN2Lp`S_X7x^$(?n^M7>Qekm)OkIu1!oU7( z<=1RT*8R$-AIh$JXSMPAFLpjqt$t4_6)2^`v$yqmU5-J%xyN*t<2WbDx_bRa^xAbh z83M2%U8{OPGwv zh<#E*m~SqZT&m*5g#~IN^YL-qYHFJ<*(R4aw&qK<0s!FtOnhi-fx}_};SSjkWL9Z8kHgCmpjRq_s7#rr5@4!a zhPi(8#(BPdbz!i-A3uiOXsWHnY+ogOX3P+IGB$0D;{rm%Isq*BU3gwuf!Y^35CQ}* zh(KC)&Nx8P`Ew|j%VB6~MM6>%${su%=c&=@qPX+bkE{O#Y&mpT)S`(Z=iCJ>*J#k8 zZ$j4gRO~-?d_v!(pNg=Bi;%i|50320#OUa#NIQ~ys){K+eKK;gkgeL?aJz?byR<}< z*B&@%AYPOT742PAikr+5az@hEbZOZ9olJb{j;B%q`mEMj%(fG`jZy)C|8R=_6^&ip zdCbwo_!OxC@@dmXm>#1cNGgD_vqJ`!<(y~k+$+4_-OE4fHt|zrGN(7C!c65Hv#!U? zzw9;h$F3BNePbe{W9n+neSCw(#wR4FjD2IY*@vq-Z2i2^KEMa5gWpq11&-sKKLLVW V5Br3GDCGbE002ovPDHLkV1jX-nfw3% literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tsigfir.svg b/mseide-msegui/icons/components/tsigfir.svg new file mode 100644 index 0000000..f8a739f --- /dev/null +++ b/mseide-msegui/icons/components/tsigfir.svg @@ -0,0 +1,233 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + FIR + + + diff --git a/mseide-msegui/icons/components/tsigfunctable.png b/mseide-msegui/icons/components/tsigfunctable.png new file mode 100644 index 0000000000000000000000000000000000000000..aefe450fbd456c399ad2f1c5e38d96ef2530125a GIT binary patch literal 902 zcmV;119|+3P)QcnSdd%%>)ca##jOyZsQVQj%1pZTkgMJi*XK<(TMB}B?$hQ5CTM=ltb+9 z-o=bp+-kLA>uO*0n!1NzWwmt~L?{w<-m0t?JDVcqr3=v1*CYA%ogpb=2~lvre*ScG zHu~?HX5^}}P*74jEUrvRmJ(N?u>0=EFO!`)!QtSI@b;A<h zMwhMwI}V18%Hy07?=zc`bUF?fGgV-@ktJ5hWED(hky_%Yf%4*cEL-V|1xuEW%FD{h zdqZ3(wdB@msJ(Zfsr`(IEt~ML^c_TE@u&}tB}C!SI~W`s#HAC*aY%j&Q$*r1`TMtR zS;fqp=h_1UO0=CynGNs?2QR_r|8BR z1=eiX45^ow-Qv;lr}LT2gt$dx5vwc8QC?h(12M67ivvJd#F0j(=zgwjG}1tSKaygj z5w1wYL^sE)%9trCP-Q~oE`e`Apu^%zJ?DmUe!D_m0vL98=Z|(|rzRu)*$aoo0ia8- z7c;x%@l_)c(i7qlxMweBc+7Ij0Qj#K + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tsigfuncttable.png b/mseide-msegui/icons/components/tsigfuncttable.png new file mode 100644 index 0000000000000000000000000000000000000000..aefe450fbd456c399ad2f1c5e38d96ef2530125a GIT binary patch literal 902 zcmV;119|+3P)QcnSdd%%>)ca##jOyZsQVQj%1pZTkgMJi*XK<(TMB}B?$hQ5CTM=ltb+9 z-o=bp+-kLA>uO*0n!1NzWwmt~L?{w<-m0t?JDVcqr3=v1*CYA%ogpb=2~lvre*ScG zHu~?HX5^}}P*74jEUrvRmJ(N?u>0=EFO!`)!QtSI@b;A<h zMwhMwI}V18%Hy07?=zc`bUF?fGgV-@ktJ5hWED(hky_%Yf%4*cEL-V|1xuEW%FD{h zdqZ3(wdB@msJ(Zfsr`(IEt~ML^c_TE@u&}tB}C!SI~W`s#HAC*aY%j&Q$*r1`TMtR zS;fqp=h_1UO0=CynGNs?2QR_r|8BR z1=eiX45^ow-Qv;lr}LT2gt$dx5vwc8QC?h(12M67ivvJd#F0j(=zgwjG}1tSKaygj z5w1wYL^sE)%9trCP-Q~oE`e`Apu^%zJ?DmUe!D_m0vL98=Z|(|rzRu)*$aoo0ia8- z7c;x%@l_)c(i7qlxMweBc+7Ij0Qj#K + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tsigiir.png b/mseide-msegui/icons/components/tsigiir.png new file mode 100644 index 0000000000000000000000000000000000000000..7374eb4c318dc112ec2368cec146ea8e2b001ef8 GIT binary patch literal 813 zcmV+|1JeA7P)iuKc;Pbmqs(p7?T)d(wCO@eBg#kWM`A%*3g&GySdt|0qyzwfzNrx<_i~~C z+JyGT20Y5mK}=`}Y}3;Y0k6v5)`|s}6XVMJjO%XMKTwP0+gYo3kP&|o4YfL)ij8&X z-|#o)*k|9Sz9HPtZo8eke7h0@y_ zxsOYr_SxgmTd&g{qIs1cD>u?XXhbARKiA+xs~&_9n8rr`>EHCI*y84foF`9_cRd}Z zu`!39^vtXZ`tr^#?PejneSLBEQWAJ-ibFl|O3EN{VoWOUGcq}TvOq|-tkd+cpKk&U zKX;*8E`Zfy@ucT(W_HL00RH0@ttUE+Bl$EVGCW!?fSbGfZ#q6SsFn*bG|;brAc*$t zvUkPrM<#gHh>5!@6n1CEr0ps%vu@nX>n6 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + IIR + + + diff --git a/mseide-msegui/icons/components/tsigin.png b/mseide-msegui/icons/components/tsigin.png new file mode 100644 index 0000000000000000000000000000000000000000..6b7856d487025b3794e7748fa12e36c8048b054a GIT binary patch literal 846 zcmV-U1F`&xP)ps{=xldomxOECeA0b2_gb1%%-WTFm zh#5jpPE2@-Wv(eNQ&65hKI8X4eqJuxknfo~uZy(<0Ql=6JEx}5*8CO#FwFDl?r2}Y z_nEseVz)2AcE-dQ>DETQd_GvCtw4v-;1V$Ta{_tClmLL{hSx}qkAv0nWsZNK)uOHC z-GViDsvbAcB^j#J`C!nNZ757vqTSfC + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + IN + + + + + + + diff --git a/mseide-msegui/icons/components/tsigkeyboard.png b/mseide-msegui/icons/components/tsigkeyboard.png new file mode 100644 index 0000000000000000000000000000000000000000..71a5e5fc6d7d35d4910f9cbde6bbe1647f14c688 GIT binary patch literal 955 zcmV;s14R6ZP)*%D%dWPuvv%l&^j$@xF${GL2H$#ZbIlys30=JkGm>gY&P|NNJ;`nEl72i!uK zZXwLOgQ5ON@|$e30r-Tru5W@VjZ=f~t+k}4X zbaJPnC~0Zi+wbiUu3ocQmcWICEJ?T|@=-#T$VUm8zxG@bc|U(vf;;^s8Rh;}4<&zy z^>Uq1SYEx1c$Y!E%OGP}XsX7NP>8-RgG)J!8m*c>BT8?VLDsU-G?n1erSwFjWG$Oz z)fzGq-O(tQa#IwSmX0X^$6`H{2sc~m*3do>=bhcJa3TRfV^cE#F~h(Do@?HLl&`gc7k0D&&>f9(Z!pMEVx-kI5dP}j+Q-(H zTG*I53o~a?GH)I>HbovUnVf}Z&Kzzmn~&S$BWv5tEi1zYW_W!}*)}(oEx^WRmd}S} z!z~Nuvm_Maj=;iiq#_~AgC`QgiBJFM;gfrCxs>!P?Vs%XbmWYFbR?D9 dn2MsL{{Sj4FR^0QLZAQu002ovPDHLkV1hhM$cF#` literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tsigkeyboard.svg b/mseide-msegui/icons/components/tsigkeyboard.svg new file mode 100644 index 0000000..db6fbec --- /dev/null +++ b/mseide-msegui/icons/components/tsigkeyboard.svg @@ -0,0 +1,348 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tsigmidiconnector.png b/mseide-msegui/icons/components/tsigmidiconnector.png new file mode 100644 index 0000000000000000000000000000000000000000..8bf3f7973a3fba0b7ab852e933aa6c51c101fb7d GIT binary patch literal 1173 zcmV;G1Zw+zGegSJ#maeOV1 ziEN7j;-YCYLx#zM1Ls1rCBA6bAC@>!HyK9J{n#=FC?jznFh=-cp{+0?9mrQvC?FKj zmQg_He%RKcY{NvJf%%C ziqR$*TWk-x*0D)0?NC;u7k~ew!kUiBX|8K(hLg%<1C&x1rPTFHo2hhg*1_E!v7P1d zcurDq{_AhF8JW2&PnN(V1OWkjumoTT0ZRy;EG|GmDOiTV^5PN%ln<<|z`eW-hQOC& z3BbU6XAuGcMT971f!TN9pbY@HBZqN3c|ZKa)Y6Rf@a-6|bYo^}3OW1Y002K;y@E7_ z965;zcuN(7tfc*DZEE!0+Z!pv{QTe8x^0`C@h4bT1s%f+IR5Hg@iVwYjHX{?Q4fOzkrNu>z-M^3RyJTw$_(zmN zfjF%eEx-NxLXMfAn-h8u%A^#Snw#KuyJ2i@f+jiTf62WOu_qc2tV64?it;iU!>82c z1^5C1r1CxJxno94{Y@mj{qDL2X6$xs2?<$+m7YCwh^gwdeCZD+WMrbLrW%gfS%}2q zb&XbK+5C7E-$qp$t356K8bVDqaLMRl%+GBxa$4*d6(bv@lg-Qkc_&7#~ z20;k0DKHSyT`~j*zvlBnM_U_|nm7coY%vL-)b)MOAY}-^f_Mz}%xDaOXD1$lwR8SP zW1i)TnSbfPD~V%=b5fX{QSy8KU|r=UbQ{}Wn(XSu3osjQufkdy8`aF`wLjJRgAuRC zq9iXDca3c?C7@8MkgwOl^qdHreWEat5RyndJrs#0kjE-fl9vm4tP-IT2^c~^2m!&< z-V#rriRV2CArOa25TjBfU#~-qS`Ben7y<=?ACPub*HAMw>IU%2R*YKhwmx#WA3Sz) zYfe#*sU0PGxj0>M848VN-BZ+IFyMqDe14Al$rpnHlNt3*RV#{(HSaU|F8C_`B-zI_oG` zZ?$oOK|xMFrLHZa(22&83GVmN39jf|neQ8;(k2+&C+wX0;WT$3E8F*t`JnJ*P4Dz0 nu7Bn+7cSd9Kq+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + MIDI + + + diff --git a/mseide-msegui/icons/components/tsigmidimulticonnector.png b/mseide-msegui/icons/components/tsigmidimulticonnector.png new file mode 100644 index 0000000000000000000000000000000000000000..05647098b8fe07e0b5a6fd9f470f263048a762eb GIT binary patch literal 1231 zcmV;=1Tg!FP)gd3e3yPU*DG}YHx_bGivSXlTAo40H+GPZ;)%cA#>HtV{f<|l0R^1_Sk?PJGL zeYY96TiS3jzYtkx(lKT**u`kNx=WZusrW++po)q{)2&(nz|!I(Mjt-Jww zu^4id3XQ-0y3WTe%+Cuf3rT1=bPe?|o6XQR)I$*#{-5L)^VuDMKlOulSaCtVh~ZOe zvH*N%X9)dwqx)V98f$A1`qn!RCzv)GvB}-t4$IBHc!Viy>$+qMhD1f9zN!+lGc)k; z^mK^aw6K8N)i)6m9cHx$k)#< z=8cF5Ey*k`yDAHRGiB(0C%m=`u|XifP**2Bg+d4f0_eND;I(}RD5dCaZ--bag>h^Q zBZC7V1lZu>0^v>(+}vKX&Oxh21BpToCzj13PL!IicMnj804xY6<`Sg zL$LNIYXtucp{=jtY9aPWq>u*%ug0$WvY6+O?z3kva*~tKq18B4e~XDFQluutL#MuL z#S)Lkg)=++{2$l``pe`vUsQt6Pb8tE+3_S2r4j{Y<@hN6eQT1&x;hyu2Zp(-!4Wfn zSM~+UWM=*2Su>^7WK~hMegrI5>)EYqMow}PJ}WMTSfOyJ2P^?v)oPqdh{wm-IRJo+ zPd=?;pG+CgNuc4lk{6a&Ko%4X zLI9akd6T*G<8`~~xKVTk$4;doK&EiG{s8c8!6lr`I0vaR$PQnpqIZ)|;`{u(msU|? z>S + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MIDI + + + diff --git a/mseide-msegui/icons/components/tsigmidisource.png b/mseide-msegui/icons/components/tsigmidisource.png new file mode 100644 index 0000000000000000000000000000000000000000..e8eaa626b79073a4326046344ef40f8f3dc6ebd1 GIT binary patch literal 947 zcmV;k15EshP)Wz) zd{BwT@SuX=8436kBQXIF)M!*R#uzjjki(0BRSrSHqo6553zn-;Dpavbfx!9#jRlQ9 z_|MBE-^|XpGqXDxh(uzu9iSevY=RzX`+ZDZ`~?M3A? zC4QLA7#QfsyNYrEKu23E%9T%1u6&BOFDuYx?6f&oQBsVdp&=|=y}AlVGHzVV`qake zE(%~$nT+K$G_%Le?W~}sgB?!4zyPpog-Vw9zLvR9@?bAJKC=TSPBO2#^Vp{CQA`mL z$)?G@Sj^D`R@eQNX-z$Bf=tG0I}EI)$INr5c1Q0RVfL6Y6ROe@>rF}@=0iSj{%=!X zynF=`(oQ4g(q&{86e9obU8rkn{#+se2vV#^Nq#N>pvPpw;NTD@xVrwe&Qd2QEM2)0 zRWHhH@SR&Wui~c8@va{My!{tKQ?0^4e?Q6|JwR}%;;+F+#B<727&{F%SaDI2KbMl7 zpKV15flu&qyne34izkl}xGvp?;wFh>iAE=HEJ~q za&xgJe7y~RFfl2M%Q%+c_bWKd#}`fYbqH42I**o|%v;zHun-}>K1hn)i?pj5a30mK z=$Kdyv7^*-=VK!k;wOs;NfvaPF7lqei(9)j>WNSUT}Gn|x9w=6N+<&0H?Qb_imFkU z${h+@8z~flgH$@mwQ4ofg(A?_*GV7}iOtEk@147^Yvc2DdVZWlVz#H$;_T*bC~7tE z$~FUklzaszdx(4`zxUJaB|i&!i+{{-LI VL&Gcs5LW;I002ovPDHLkV1h#KsJs9G literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tsigmidisource.svg b/mseide-msegui/icons/components/tsigmidisource.svg new file mode 100644 index 0000000..d5d0e87 --- /dev/null +++ b/mseide-msegui/icons/components/tsigmidisource.svg @@ -0,0 +1,233 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + MIDI + + + diff --git a/mseide-msegui/icons/components/tsigmult.png b/mseide-msegui/icons/components/tsigmult.png new file mode 100644 index 0000000000000000000000000000000000000000..79ddc887318a95b72cb394ced2e51bf9df282aa4 GIT binary patch literal 786 zcmV+t1MU2YP)(oer0bh&nU5{5@M9W{l`$qU#-w+{U#n(UH~6^SQ6Y+=n-teSZ%RzNlt&35fPfML zfxxE;D1lECQ0#6K2z+)QmH<)e@J)JFo9=*2qExAts9eDTV0d!MKywpf3*{uCzdfEH zxq>&=)oO?$BxJQ^^!s7in%r!ed@5H40C1otf9UT+UuVa@@#mA1&2(hYq~5QC>9rBY zmgapEylCqfpige+=j;V?+U+ptE3x31!x5ztVJa0?78lXdP!IFRA-^P|KfvhcPiTEs zht`IAgocM>d&>)LTnx6oUSt>C!kMIVyZYu{&ALc5aq(k%WACZGrfAdS!SH|y<%I?K zv$KODT?Nv!t{_aQ^gl(F-EX@6Wg&D1D^I#`+qXsvrCHyIc0Ki=<><@4Z=Gsr9#L)`@XM#l%7&fOT>Lk2E(Z};>YW9tOxd@hAE+xJ8pv)o{0dT-ubWpL(+N$Wi z^wdnb2!euxcc^{lXM|h?Ge4#k5CqY!YkO5^w9WAzn}Z)xDBOXJNnz@vPLtiq2j`sp zeogKFZ%jgBlKG2siH|HSb8SZE|8Gow$(^q0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + * + + diff --git a/mseide-msegui/icons/components/tsignoise.png b/mseide-msegui/icons/components/tsignoise.png new file mode 100644 index 0000000000000000000000000000000000000000..fb38616827654366c678254480547e2bb251b346 GIT binary patch literal 1321 zcmV+^1=jkBP)N=D@DH6Zpgp4kwfR+(u;{KrO& zvMgpZem<}lElo|MK>+~GdOfOjIw+LNZaS8N^T!L&)76E>x;tYc$T@lhtq&idqVC>N zx@vaNx|ac;m`r$Pv!NjKFhZi{p|Q4h)aFn6`%#$p3))%-jiFEb``;W++GN=dG)odT zf4&44iwdFe@a`psJqw}6FfYi{dBRtz&|h$jkV72L6&8dUoJyTT%0|Yo&Vb+wU{ZhKsM`V?j7&f#ruZzxq>4mA$%K(<=J@eZyzteK(VsJ?z3wbfNP zc3>Y2_wNG$u3o%=uT~@>a)H(Xzbf&w82V1Y^m<1H+)D|3G#U&HSa7?t5`w_+dtNSp z!IusIQ43-m@K;Jo=FqgFKa1=HviwQ~01zA&j!VUVAR%cv&K914&1QqeY=*|qA0c63 zBk&_EqV(ko1_>h2)7^zxp<(dy_Ca;U->{g?h>VGWiy$~)H|_ZDB>gdU+w67Gkudf4 zLbeWo<6liMD?A(kpj4~zerzl*ojDD&*$m-@<^Yhg{_6%>db~jEHhw&eO$NwT865X& zi!@WGLAxjclQq7Gj*Um@*)y=1B?zvrPVp1~CizZ5t3eN0wt|jw2ZRu$Wo1LDR>LnK z0F+SNtkgMG5IX(cHT0w9E6-2T_`+x~V8CJ-;p1p)L3}*QOG_azHX_&E*{Pr_w(h8z z};DHcV8!9zpQjPhyzq + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tsigout.png b/mseide-msegui/icons/components/tsigout.png new file mode 100644 index 0000000000000000000000000000000000000000..aa6ef4223cae2f360f8b74704692b4ea3058e3ac GIT binary patch literal 1056 zcmV+*1mF9KP)swpucEqw?Nk$*tI zxacWxfZDc>kHkG@(<`2IBHnem^qvAgd-6o2;O*n%C~a={_1GhS+|>4gr!oN0EIg=_ zleGMFoe*O<;Zf@W__d>huty@0wKB6aGxTbGzH>G0Tp238DjK-=TvGw<3+7!?Ef_$Rm9>+_s=dRPm>382@rJo-^fBzkq z&YWg$c8=*Ol^C;`i>E&1uemvb*Q`Mh;MwOhE{ezY;>3cAs}%sNL&NB9ZFU>9-)JPn7=hl`mr0isfU(;)48A^#z;2E^Xtz7)v` z%{2mog2>B%4_HtlbIN8aKP%(j^fY5O8(qy!M44g;4iBfbt`2~v+8RRE8kfwZv8I~+ z*;$+_`Gh!&h1aZam5b-!K4J!lwj{7RG>ijjn|Wi~R(2dbjF-VcYUXyXUMl6qqy)bH z^fJ$7?^@D9b7KR=C8e0-Edb=adZ1faAU0Rg;^@5e%m1=AZCJloOx?Nb+hyN;KpGz%^%t}9tWBPB01LXv6V%k( zS17)oo|@??2YQ2HRvhT*Ub?aWC-ro7dLv01=h4fbpZub4P`T1Kq&(#9?bOP$>K7O^ zTsbhT{4hAIyjgU@y~damlj`e+$CbtryONfX>0V=Uau1hx+9#BrJAWv~$aS}5SynX~ ajq`7hbVUAH=J + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + OUT + + + + + + + diff --git a/mseide-msegui/icons/components/tsigoutaudio.png b/mseide-msegui/icons/components/tsigoutaudio.png new file mode 100644 index 0000000000000000000000000000000000000000..b5532623b86d84db39b055eb07ab085c0e314597 GIT binary patch literal 1284 zcmV+f1^fDmP))d)HKr&oX@%E+8s z%WBG0!$P@QBZNjp7cba%?LU}PuNf7ZM(zr3?(SWL5Cb8^P*`1iQaLs*H215H^E|I- z4y1hZUGSDS6Ice|z<^~Ka17>01}ua5kpTcr^?1u2IDwvV>#sfpPTMTyo(S!}5Vfel1y2T)m5_W20V(DU_wzLGB!nZ;@GzgQ)^jN{u z&Yp2+C4?9jgKhP7Sofk2JbZj{TVDHE2~HkA7R6p_X!-gWkdPWyUQ+D%Adr{dgx{u@0RSw=!RhH$=vOKc5fh6YugI`%V<4j6jR(iy zzrKs9DX6Wg6!i<2uiRj)2r*=}DapTWG&(m6fI>>FA8NGvsw(W;8Hd!2OuQ5n1dd^n z&Gv!Wnp#;wA|Z=1zrY}*q-P*8E(SG~m5AT|_G`SWhi3*}RN-FK)g>9-$Y0Eu;?4&eYr2kA_7?(S~6yZPt#_*3mKA zKB}Wx*9xhFlM~G@xK0TnhDA&CRqj<>s;GufunhT`8TYeK4YI-IDf`ag2(q}pB`J+et&DA?J`W@6&l#9B$uNO;fY_Q7J4FC`o8;8oW zn<8(N*CHi71O9tsoyB6~d#piQkyr u2S3PZAJqwpyMGF+-Jk0sgcx|9*Z&1?64A~#s4yM?0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + AUDIO + + + + + + + diff --git a/mseide-msegui/icons/components/tsigsampler.png b/mseide-msegui/icons/components/tsigsampler.png new file mode 100644 index 0000000000000000000000000000000000000000..f31928d7b2630e54810c157512ab6f95557e04dc GIT binary patch literal 1439 zcmV;Q1z`G#P)H z6-RB|P!wxj>QcJcYM)E(AKFm0t#z#iw`y5LQU%dUvj zj`5y)wyZ)O5o5@1#b+;BmVBw=zIvsyTJ`bsD^e82q9}?bGxz+4;+i`3_dCY5vMkq& zrCYXc4;vdbR}!E>APIp+U|j{0z`6<~{@te$SpC+s0$y_K{78Cz%s3;@$#h-1R7tIy zyTwJUjho5aL&8`&b1H?GFSR+GpL2$VG0{A3Y_wsSsVPhwIgAQZxeaS>Zf4fR2^>yJ zBKKOs4k<1qXd%G*xL8I_oz7P$e`4~2#jKb%1xrJNEih%zZk%4|#OaJ7m)|*xcNVrNNAoiwm;cfx!NusJr&^n}4G)Vx);vzP@6AyrQZ+{H)7ZNc(hO2qMasARo z6nlFHL`LEl7>FTm4q2(GJbdPUhDSw{m7dOzDJhII7;O09$jE&8!s%?ckcddC%FEgM z$w%}X5iefobP^>(UNsfPO$~no~zt0Vx zljUS*_mkJB97_T80C^{~D7bhY0cf>aUi9%{NK`cTc6J=uv7M0<4Y<0x+7g)S>e&5d zB0_+m<&%UUe(@4?x|Va&vy7L{Ey(ZXUelrilluqvW!vZLtf~ltUJW63;Uc>C@Z`NYv#o8~ zQvLg@R6<@0<#KW92H_JBcx_`wrvLMpWQ`E3r8~E7_WUpM{2#k@qtF43My_9d@W|%W z(z|MUsZq6eaH!WRipABft10`ANj-hnq<)yV$@Yv12^*N7XR1;!+`F%iF-)>OW9BVe to?LkUfqJXDR_*E6t4L84i!96ae*$;q(xTBRfq?)3002ovPDHLkV1n!=s=xpM literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tsigsampler.svg b/mseide-msegui/icons/components/tsigsampler.svg new file mode 100644 index 0000000..fe7360a --- /dev/null +++ b/mseide-msegui/icons/components/tsigsampler.svg @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + SAMPLE + + + diff --git a/mseide-msegui/icons/components/tsigsamplerfft.png b/mseide-msegui/icons/components/tsigsamplerfft.png new file mode 100644 index 0000000000000000000000000000000000000000..c046f012e2fc9f6e7160a40d96e8b953f92cacae GIT binary patch literal 1385 zcmV-v1(y1WP)v`L zKv$i7fDxu_V|+27jVo{dT+HxE)2gRQ;2KD|<>&A3~m-MTaBpqZi=%oN2i*>7fH zuC7j-S5vQ@AEwEEguk*SI{8}teeI2gChb@^w=zXh42q%{GV?DdmjCfk`&*T6hb+s@ zV(XrL`~4ONMM(lw2qYm;35=^i5*Sy3#J|T>0%P2mD`33+@OJ6BMN4!%C9@kbqEUL} zRF{{rBQl)zv;Bw-UrFipYyFZ7b1$(eESS!Y4ilD{n!>6DbE((Yny}v9Ue>-8%Bf?= z$S*GWQi_~9aT7p7WCSm+T+OFH{K)dxH?w`!3Jk5SrVmpNAH;fy4LKQSO<28N&%KHY zveM6(u&V|6TrJ3_Mpq4h)Yj5s)!W;Pp|u5TTU%s#5b9~ZXb&8rtE&@$ruuqxcPm-D zEr!%1hx+Yo&celHok=tK8Oh%Z)U@s7x?Ofcx>$K zuo_|mKvwc;0)sQ&?&fAu5fdjr3qazI_%PKsH_Ob0 z5dIEMP6S0n;_W+wCVefR#cs#PKLFd|cI=GV#$YQeN^jhtp{9nq8XbOtb1AxVnXZlw zCQO>d?c!qE4F*(_gq5{5ZEdX-{_=CT1fVM~BXQ$809-sg(QMd6Ku8!x1;29h+Eo+_ z3uXic;-*%kiF}o;)KuCYo6o$UV6xKFIiHfk5{<@$&k77Il&|Du+fNM$q_MV^eeb@5 z&+GsmG&WFhF`M@fALr!WT?DTQXXb*1CLLs-Nh32Q*;Hu6NC(UmGwxQDG0x4Mg1kHc z4xIS*qAEZ0`((`}(%7A?0ie;0;h$^*a~7K865<@sC_RJ(;^Sg#90V*oOl`2yBK9#piiHE}cJz5SU_; z5Cm(M;iXmsAV1!*p{9mwdAVrTZ$ua=ad^g&?w)SajvV66k3T^Yea$TgTViWB3=eN_ zy1P1wi{47Yp1nu{hS>D!Cnom2WHEnrc*eT;ghi5o(!xSgKHp2+p`-nH?&<18Gi4GP zMJ4|@gU*h2{5{8Wx#C{G8K{JalXFg;3|tqVVA@4pbrt81A4M`!F*hU>a|?6Y4F=MV z9yZbd(`WhP?CLt;9OS@owR0q?DYXN|A$GBJC@egID2?LnIt6CQ>XoV z5g{>U`iv*=>*bY+V(bKU@y?7)&!?eel@M`K)t%b|ABF#DcW#whqEgAtaVJjiPOYrg zrdR5;7M7OHW{P4MW + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + SAMFFT + + + diff --git a/mseide-msegui/icons/components/tsigscope.png b/mseide-msegui/icons/components/tsigscope.png new file mode 100644 index 0000000000000000000000000000000000000000..f292f6a4b866f4996394cfb65a679259daafc360 GIT binary patch literal 1153 zcmV-{1b+L8P){GsMaU>Dsb%>3)g$J-{EpB>gXH z5kYIM4coSLPfw2#^-U?21bzbU1kM1nz|A5uTgqppR10td=l~Y{v#Yh%i?P5nl}ayr zT5Xwp^u;V?Wv4{sG*ddxmWPtS-GS#SmG;8qrj=k@-vsckh-5@$mK$45pe=;#udGU? zP0-UgBXM@VdXGw_D?n#y>xi-LhEG*0eFStCs8Ff21}Z^kaYo8G_U#)gm3{}v(yrGhTqi+u3+(CNmoWSe#C28}G#feK0&ogI=Egkr-1fVG{ecF;E6D@5)B+h1xe&g4 z>!qgv1%3xAmDb9%mJfAyZJ?>yWJ>=Xdi>q=H$Y=41|(}N?&zv3qW-~W2Z3Z*0D!p8 z0?_;T3Dj*ysN;H`+WK-T5)DeJRmAmtgaJIW`v^C!j|Ez#(i$@fn>P1G3ux+%YXEq@ z??cwNFNTwuH!6w6a^$=zpq{)@8884~-^+(+ZdnYpxQ;=UsTurwI4mHp6O*yA0sspO zZM?brz7YQ0nCBOp1X?0`dFAu*fwb24O|9-dg>&#K#wnXSDz_Z)ifR3owN~t6l|GJ1-O%Vgb$dNEBqYM)M{k|0# zEt-p!A`?KPQmQJl-vrE*h!65b82nzo8hDh3>yH=Bh2OS_ECN3QD#D;07{7!`z%)_J z;OFt*fN6%$4gr@j@Sg*0>l=*dZr=Z-w?tfpKQDfPlS6s>ADIJQi+Eqez<<8Y;X~*7 z@-Q^SdVo#rc&w>+W{t4BNJ~ZQCyZ<05jLD=ekdW?(0<5!fmsL;n_QS(aYzAX9jq zDLo9~x8^bi!EX`yicH~NAQdG4e+=UK96;n7REoh$vP@y=KlVcghSvJ3{%!dOm-RUE TTQAEG00000NkvXXu0mjff=UxM literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tsigscope.svg b/mseide-msegui/icons/components/tsigscope.svg new file mode 100644 index 0000000..8cc7830 --- /dev/null +++ b/mseide-msegui/icons/components/tsigscope.svg @@ -0,0 +1,342 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tsigscopefft.png b/mseide-msegui/icons/components/tsigscopefft.png new file mode 100644 index 0000000000000000000000000000000000000000..af30ac5c79410267699eb32345d0bb56e96732d9 GIT binary patch literal 739 zcmV<90v!E`P)0Y^yBG z9QPP)fb8`?K-Uzxm4|7_lDh;VQ{+~{G@#=KrpN<;c?=+N;!KgNG)-N*QEVV_5`sGi zbb|+gmN;=hcRn-lMMe%fNqN%o*HGfbdX_K^Bu;Ft?;Q5~T{GEx0KoH? z-|x=@fRn?`|LK9svdnF7Zz}*1u|Q;uxz_UEMw+H>>Oq*69en;4%7e$&^S^pfOGL+& z9z1(-&XY*04mz8#BXGDV+TCOiXyBgJew2wqjZ`HiYy7Hzj;Gg%Y_EoO6-dgF_{N)HXm%Gj5GkIKj zQx-5q9#mSE@nbv&5E0$v+2eI=v_6VREn#!Nc^(W!q~x+-UqsrT>$vIB;vRVItK8%4 zYSLW4)uTW0z-xb77Lh(1txj`&)&oBW=nvT0L#*{Cv-M0Xj=GC*HF+|oBxmuVzZUhSDoV(ZGmfz=v V# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tsigwavetable.png b/mseide-msegui/icons/components/tsigwavetable.png new file mode 100644 index 0000000000000000000000000000000000000000..c67ba4b2138477721ac52aca1314ed6ec0e0b1d1 GIT binary patch literal 1180 zcmV;N1Y`S&P){`EA3Da6E?7sKpfv- zX*DyzoE8?1;fH3ME=!g<-Q7(5gNxH8?!#@tVIrVFXbV$l3%F$nw1bEk0b7eg8S*tI zWVHmkAGU?UE%Im2pOf>v&$;h=o^$Rw2Q14?i70ihmPm%Rb_cKTAL0+4JoU4fQm2?w zXKZ3pd$Z#K|J%?ApSd&F;N|yzc(}4-WSqY-I>Emtms=^NPD-isYOA@}_V+{n=78fk z$8l5S&^O=ykeH+1&k%qG0YeB_0#8f85O`Vw27zNNfhX?K5+G9Y(jz88sd69y3{{t* zyYNe(upnk!E}Z!62;6QrfaxaGu`zB`MNAqSNCyFe*jQG!3NHKW7a20{p0Z{0q} z?2FrUP)ImBG=z!KQOGyOpt)AJ;u&1g)*wrz_Vt;6r>CD461JHP*qo9Im8KBd(v{gX zJ39;GuXV^&Z3h5+f9ABD5mV|EPGE#0B^3#onYeGW;-2-+6BAfkS`Zo*hOl+(0070u zzud``bl&=Uv2e!aLRV`G-b~sGjuRm(H-AO5sMl+erQYtxF+#$w>n)INjKMQOK>z^N zZVj$puE31T74YM3w;K(59Wrv}{ok6F*3MW=2FYS^oAI&#UWA5+BO)pqO||-f3A+BY zAn3X0A(hL0+)o$Fjm%dEiuNuRw>KKGIVIhXQ|~E2O=(HM1ob){GSuoN{1S@>Z8pr! z&0(!f=Eo;xXT#pti~azM-JsX`c8?ePcIBrs;TxiQ{i-+l+v9~uBt~}LJE#%(vwOR{ z0RWNF(SCfh!4S`!sM1v}B+ZRR#HXYQR;k`yfVzruxLl9?c!OSt^c4EoI5)-g{VGX z;_KhDS@Cdk5;3uFEYTLd|3M#PswngMVKx~8+T+DrN+oPPJ?OVu0X()REk^}Hh@jrj zB1@AAaRLjx5F(Kn+w$^JU3%V=K#%lAyT=Pf)cXBQmgc=H0ATCBiJ%u&BP8^dWfK6v zjy(m?mzQC{eiwfY+()cJA*dT083|?zK0VqA02Y(+iPd}Ys!RrHWF(FqJb>hEB^XBV z!~w9tB1@wYamma3zYuS03enMe9ce1z?Fj&#HhVE^Hq@WZcvlk={PG&aD7JuQSug}3 zp1YNJ?qEU)2#7BhE|Vc#8iC}j?D;Vu^I8HtMQI}uQR*zaZKMCkrGK}t_as=BoBHD7 zr8Cv`L0)Tj@K3K=H6^Ch`J!aauwh`BHw_N+pPV}Fd&a~iCbhQ>kMWiV + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tsimplewidget.bmp b/mseide-msegui/icons/components/tsimplewidget.bmp new file mode 100644 index 0000000000000000000000000000000000000000..41f7694e07bb38f32bf4075da64a9b2f5403f7b7 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDj7v_dwutFelU{C^x>mGsuscd8qK};ZnL<<=* zOn_)XGY7~e+bCpzQOg{%9fRgCYMDbVe^JXEYWa&==1|LD)G~)!{-TyS)bba#%%PUQ TsAUe&UvRIH%0@1K1`itmvouNm literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tsimplewidget.png b/mseide-msegui/icons/components/tsimplewidget.png new file mode 100644 index 0000000000000000000000000000000000000000..2227dd3e9ec3dd16f2397495f8250e2e9cc49370 GIT binary patch literal 632 zcmV-;0*C#HP)fA8r%-4ZxNC;n@#nqY z|MBtogw~p+N^6Z}S!1QtB$LV9dY*USdEP;*)q1a#nkc0v#bVK2_~ml>)55RSYR3zI zeSQ6E;h&tGyz@NorPdmuwZ?VbL)*6B2q92P0T4wIK@b3tNF+!mlK{-;bHXqLz_Ki) zlmG-lKoms)q*5t--~X_+we?zPtx2cT)6r;@GC7$-p%6}|)4DVX{fAa0fNk5qO_Q_P z>;%vfpx^Hwn+|9+8ef5M*&{*%bi3W0Y4F9x#R?#n{fplIpAi*{#V@A8+uPeefk*Pc5ZifcYT1PqodsA<>e}X z<2Y9v8ygP*^ZEQ4#3K?yWPw+}Dj + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tsimplewidgt.bmp b/mseide-msegui/icons/components/tsimplewidgt.bmp new file mode 100644 index 0000000000000000000000000000000000000000..6776551b60cb4050216cb58e6638597b62d6e841 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDj7v_dwutFelU{HdG6aZuoQDDr&QFHKz-e~xY Vh7bM_z%M(Reui%NAjjRnvH>a6t}p-q literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tskincontroller.bmp b/mseide-msegui/icons/components/tskincontroller.bmp new file mode 100644 index 0000000000000000000000000000000000000000..c7a36fbeb59dcd0ffb05aecc1b14aa1212778fce GIT binary patch literal 1782 zcmb`{+fEZf90u^OoCV5FjW!VOeF7iAdtLz! zGM9c(ZkdByRx`GN%iYUc);W-9$%8qRGro%N%A+4jya=K10(9A|;Z6r5Ycbz)pORpJc&sTXI!Z|U>eI===TW9IWL z63>W7#67}sc58=Jp2h(`+V8cU{AQh!pDFJw5zk#`!sJno4nJ zFuwp{#;w&s*+4i~k;d?zWI|hMM+o{~0$u8SM5j9LSxpM!cdxOwMv>?I?Ht>O%S>MsT}oRgKTcD&T9+|b*0*@XAPk}vb0 zrIo3_G)Xm=cD|&=Y~^|TgTe~ HDWM4f-+G{^ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tskincontroller.svg b/mseide-msegui/icons/components/tskincontroller.svg new file mode 100644 index 0000000..4c1fe9e --- /dev/null +++ b/mseide-msegui/icons/components/tskincontroller.svg @@ -0,0 +1,289 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tskinextender.png b/mseide-msegui/icons/components/tskinextender.png new file mode 100644 index 0000000000000000000000000000000000000000..1a63ef751bae740066d17f054d51f812d822d523 GIT binary patch literal 422 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ zFuwp{#;w&s*+40Z-fnM1%`qbMbBDDD&)Bu%2v^`(N$8eP-Gu#*AHGRX9Bvc6ZiIe4*Z1H{(Tlr`?M!q6;(| zay|PkT4tK2^2_(S<@)`ovD0suZX~*T)v2_A>!y>+yo{@-ZMkWG};D!VKNF_K9h~87n>;F|2D|V(QM^q%O0ACvDqP*XbouOy3V^IrMy# zc@*h4`M%u?FKz8RXO^iNFn1V!yF1-j&GC|jaf#-h)fqBpavr%(H{m{Tb{U^@I zF%>*{u~ASZ)>3Lm_{9wjc`C9MmMjV9x%1MPe@L2Mn=JTbYESYR^MyaA1a4pnc?Jwq N22WQ%mvv4FO#qi{p}+tD literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tskinextender.svg b/mseide-msegui/icons/components/tskinextender.svg new file mode 100644 index 0000000..204d831 --- /dev/null +++ b/mseide-msegui/icons/components/tskinextender.svg @@ -0,0 +1,290 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tslider.bmp b/mseide-msegui/icons/components/tslider.bmp new file mode 100755 index 0000000000000000000000000000000000000000..e5c99b94b5caf4a426d50b4cc94bed05e025245d GIT binary patch literal 406 zcmZ?royN!j24z4}1BfM{n2~`6EUo~Q7v_dw0iXy7LqG!q0}wGZG(adI31k9s1H*v> z2Y?d)!HD7ie-I0Zfe<7FB<@lR01bnJyLT%(prHTm-GY7~C@=W&<3Eu714wm%M4;jw YB#Qrsst0-k4EXQfEr$bY`2@ur0Qgw+T>t<8 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tslider.png b/mseide-msegui/icons/components/tslider.png new file mode 100644 index 0000000000000000000000000000000000000000..eaae37501cac63f5c464912e2f09d4a7eb17da94 GIT binary patch literal 626 zcmV-&0*(ENP)<1iG3zqDRJchFKyYDdQ2QkUXFpSn6pwGun& zU+5m{2D_YjDABki4D*tQfw^!IGP>v7?^>XlBu*J;CsqG%@Hdg%-QAt^FDC$XU7ti; z((e&jYmtPtmfddmWB>X2iE|D~2WhQk97md_VHgIiwG6|+cDwx+uIpOgW|DJGyWLL9 zbg$DFi4W#-``_CJUpoH`*?1(T1k=~A0PGh_9jV+1kO3ivShQ_aD9DE z2!Sli*lxF6U0u<29RPjb|Hzk@7mA|b`T3bF%W%$76h$0UG^nZy=NxI8^7{IUF^0`% z!_CbN>-8FA3;-V=A2B7dSS$!3V2p|4P1772IOnLUDvEmV$+CYM{$ z9LJbIB%anU77NbKzNM2XLDMwxs^xheuWAT^JkPnmzvt`gi)j=^f%iVHdy|Wc3jk(y zUF-JtHWr+ppC5?)>HBOpLsDF)ad~;kOecQQ5@2>pgMa_Q`S%Te0cR4e(FDserT_o{ M07*qoM6N<$f>0tIvj6}9 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tslider.svg b/mseide-msegui/icons/components/tslider.svg new file mode 100644 index 0000000..2a859dc --- /dev/null +++ b/mseide-msegui/icons/components/tslider.svg @@ -0,0 +1,813 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tsocketclient.bmp b/mseide-msegui/icons/components/tsocketclient.bmp new file mode 100644 index 0000000000000000000000000000000000000000..c9c63644c61889424974540ea5546cf5a21de0cb GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDj7v_dwutFelU=)moz-S1Jh5*e%AQ=WIu>oiX zL_3^8hH1!pVdWo)CekRFKR`5G3o;unh@U|%bKtfhyMYXU!Oa0O;6}k2$g(7{;oc-k H7paN?LSgB5 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tsocketclientiochannel.bmp b/mseide-msegui/icons/components/tsocketclientiochannel.bmp new file mode 100644 index 0000000000000000000000000000000000000000..c3de89677cf749035b23209a8f27541c38696300 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDj7v_dwutFelfO=r&<24i_h+8N$1gL$~9Qlahuf@B$t{pI7kFyows(!^@5BVQ^rmq8TSA>F#XHm-)6&InMDt z#X3IME~Au|=pQDnOpMR6#UCe7rv4f`PvEU?v3pEs2BDi$bVB6@N1&ThY<;4oz&28+ zc`7WXW9QQif;a-;imbX+t+pbQqH=RLX)zMDsAm1~J_MiCy816H`XmKXp01-s24+A~1BfM{m=VlkU^oDj7v_dwutFelU=)moz-S1Jh5%hcAQ=WIu?=Vj zTstxwE=UXmt`S}a!bOPD4p)Pz3sVHH7!Lze7p4dv?Qki$E(-kxG!SkS8XImG@eH6* L5J0>ZB2@wa(pvjd literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tsocketserveriochannel.bmp b/mseide-msegui/icons/components/tsocketserveriochannel.bmp new file mode 100644 index 0000000000000000000000000000000000000000..d034f79fe7d1817015ee88b7bcec03d507c17f6b GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDj7v_dwutFelfO=r&<24i_h+8N$1gL$~9QJRRm@mt>RQRE3PNIPq&qo|?Y8Ot@jAC&GwvJC z^>a=gwYFe>nRvPo*K*V!H?VGfTf2UNkA~#%HC+k8uodZokR}bmuoaneFk&edt;@V6 zrqZ$NHHCm00^uMgPgnK^v0Ax2+(R;!g`?1B{lWMKo@+VzEk=ecjzw00jQWFODt2kI gD>D-Bfb7c5j$I?Ue*7*3Dk@+-s}2yws#}W6H*tc0lK=n! literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tsocketstdio.bmp b/mseide-msegui/icons/components/tsocketstdio.bmp new file mode 100644 index 0000000000000000000000000000000000000000..1c8fd56fb0e4bc054dd4911430f9e7571c79c7f0 GIT binary patch literal 1782 zcmeH^F%rTs5Ccs^lahuf@Pa&mKCj3}^D1gI7FINOmjVhJ@QgD$Y44KQ_vLYJea(2@ zu&=Lu>Z-L3`DNnnARgO)eendwsqe?GEAXf^%g=NYKv~LkAWRcOQI<0E97J3ii_$SK zsY$waUMT=F6w(2v&#v4XV3q3f;XWj5wJ-{0=6}#x$IAack~K%c0ZB(ffIF@QNO&5q zSdnf}j<>_)a#I=tsh3C27_-BnF_h&Ty~yDY{!4TGEk2WgJFdOmH5e{8HR>qJ@LSFk D#}rx_ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tsocketstdiochannel.bmp b/mseide-msegui/icons/components/tsocketstdiochannel.bmp new file mode 100644 index 0000000000000000000000000000000000000000..f7de9b4c047c38a59be34028b46c955db121bc07 GIT binary patch literal 1782 zcmdUsu@S;B6hlozLrKF3Ouzv2Op&SBfg!RBJ5ZyG$UB|mz+FNCzSt*Avi!euzC5;N z7$>bq&BJSM22@HfeZTV@j9U8djqClk@^dXKLv;LSbH-OM^eDzSr6$?zE1fblw~!d7 z?}NvnxrLnONb->6Pg`t&iiD>g8=PR3Sc6PRvoSfK7x4=b|b{9)=~YVzM4>kqlt45rVWV gCj+^3L0{wuP?A9MDN(I2t!!**69!O86u%xk0nZFNApigX literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tsourceedit.png b/mseide-msegui/icons/components/tsourceedit.png new file mode 100644 index 0000000000000000000000000000000000000000..9e77c5457a33e31aa837493a03302eeac2700df7 GIT binary patch literal 1100 zcmV-S1he~zP)~yu3UB!r?Gpub1}rc6>e`TCJAc+*~4&2qu$>;o)Jbs;W>F1-ILs zC6pzgC<+x76+|KtLZJ}V)zv79f?lh|u)K`LY$lONFfcHH!{MNypa6|VLn@VGbaa%3 zg@yeE8XFsNxm<+9VQR|CDDUh z6DW$ZGpo&0BtFOT^XKA^;$krYdtTAUCuSq{3ox&W|U zy-M!Kj{r#Z^~7v8{>sba=*$ed$B)r1EwLVrGSb}4>dl*kLLpjPTd`OyI}BtAB$G*2 zK78QY@$n7vBS-k{!UYzWmM|C$tQ(DdV=__J(E-4rmoItp>={m{b7wTW3D|5l)K)7h zwHhJIi1+XLac++M^XE|)7jJAjdzO^nk7O{QG8p*Da2Un!$NAq$ zyBl%wBB{c{t^NADcPUJ#X=rHJdeM?3?Hy4(9!LA?712kJC`zY!Qd7hF@#FOO_tVnS zf;|}ImxczaZrvh1I0!g&VU+>8(cNs@NVv@C&~oE$v)`K;Wz1Ay`MYi3TJ!t3>J zWn5HJ!iq+NcC$xGCU=cy*NAFsYbic=4mNEbnw-S`-~kOKC46_{1ZyKBIQ#n0zId_O zts?i#nSBMa9Q5|~;_-NpT3QgBE>giDv0xB%I#^rFYBn}CZGRvC#DQL~Cm0M;bp1N- znwnTQ8n=s|ldIJfT)Kqi-o1UvcR28PJjCO14x3C=b#!1d7 + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + Past fret fejgz Okfrevlfgay OvfrdWios Tzjly Abcs + + + S + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tspacer.bmp b/mseide-msegui/icons/components/tspacer.bmp new file mode 100644 index 0000000000000000000000000000000000000000..bd1572e869f021ba2f67e785701646283a8fcd6e GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDj7vhFsutFg5e-sQv2oMwUqiP^AgB%XH*tp^l zq8>;>09+YN0F?fLY`8cs23$RU1}^Pzafn@TLy*NGf*BL N4le(WiVuq zS1 zxC|upc9;V!EG)bNLi*a;+P!v#0O-rh%eMdEI8M_>)xF2Z$2Wn>E$Zp%K}y+FKy|Na zn!n2B@)JE4iybw2>4wl(S65$LRxFiDIF5tsx)r)@+wAS_)iv(x>-z{$bBlcA;o)H% z$DvdzRn+(Q_nDlWtQ(X_BqRW%qoXgSluAme0JXETqau-r0vbL-2n8tLM@p$yR#x&r zQqSdbv44}J(J0&7+Xx}(?CbjhPl$z(1yu124ooqgT#+gD(G zeEc0$ZBeb;HcEA`Wm#VU^pTN~$L$F4(a+A#B2By2A)QV?fJ=U~R&aiPegiB zt`Gpdx3~94JB*XbjgYybcN07*qoM6N<$g7ytokN^Mx literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tspacer.svg b/mseide-msegui/icons/components/tspacer.svg new file mode 100644 index 0000000..3d3d176 --- /dev/null +++ b/mseide-msegui/icons/components/tspacer.svg @@ -0,0 +1,190 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tsplitter.bmp b/mseide-msegui/icons/components/tsplitter.bmp new file mode 100755 index 0000000000000000000000000000000000000000..b72f899cef215db1b6588ee54c13459e9a463fda GIT binary patch literal 406 zcmbtOu?>JQ409#+tc;A@!OlC(xq^FoQa%Vys8pDcN?N;4(zM?8vmoOjuf*I?FlBvd z{Y+k@05??cgG@;%YOQQ|Zn%dcxS|yKNQm{RaV^f-_7X(Q(u~odB*h=S?*6>b?1zW$ G{!?ANmljFKZ6ZSJ8cieIf(tIsE49tZ@w zKvJEAIY2g>eGB;2QmOP{QcVEVt*tF%l)~-p?VflQhlhu^fzh{UZf*`K$+z`!l4*Xtw_iAx)K#)(9N zdcEG4PbQNRfR&Y%H3Sr)c!W141PzE-Q<1(;e}TdM%^ z^GVCHh8hoRGz>MJPQM%3Z49E(=tmf`MT5v>GClDsbY1@jpe`>jKbb@W5B22a + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tsqlite3connection.bmp b/mseide-msegui/icons/components/tsqlite3connection.bmp new file mode 100644 index 0000000000000000000000000000000000000000..3bd6a1e384c341c18c9ccd7246dcd47bbbd9450c GIT binary patch literal 1782 zcmb`H%Wm3G5Qgcdi#|agp-<2U=)SMihv=${E~BbaRTZ&7Noa&gN`Z1QA>1*TiwWTp zE+N<$8`=-1s=A^^^vE6^pEL8#Kj#d*dTl=S?Z!*&3*P6y-zU47&!@0|^-SKKBPJXU z|NI}rA3V7!$B!ok&p*98c~jOhN1{SX01nUHuyYJ5qbAFB6;4789m65E-YSTsY9o6L zYO~oCs!33>^x0r!w2W$_T@*6*AhK!AbEOzj-&3c}PFWzGTkTK|Ne81YQK!m>>tYmz z?QTtI2kF7taaQrnxy07=94O0L&=0bL^#WY4U8y3SQ^K(?L{Xi#Y9*t`jJ? literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tsqllookupbuffer.bmp b/mseide-msegui/icons/components/tsqllookupbuffer.bmp new file mode 100644 index 0000000000000000000000000000000000000000..5cc0ee3d0cac9cf6bc9c1e736ea346a409c7fa40 GIT binary patch literal 1782 zcmbu7v5EpQ5Qf*r!Y8m1geyD{v=ijO;u@QkeFWdYC-5;W#YV)!$`@GfA?yUV60W+^ zHaD3`CSx{c7kAl&*~#Y1KY!+X@n|RbOkn-Shudv5n=wabbX_X!ZJBfa{p$?| zlEayxKU9w7tTr1^(jN}j$0KpPOnrZ(jB?EWI7{tyOFiX{UZ%c3q#R}-m?}hbvOi7r zAi4~J4Ao_-vl^rxsY=Jud)Ld*kfMZO9Px)F5eH{F-}wXI%#8R$#n#n>hXnm$jt)Zp nuo$!Y!k;I2Gk+W^q{sM09fdvR{WJJaA@@l0C_r9(c);JYWVy>LiswBcAvQ2!!yRW{4!M zBAc+22O_;z(V%q@B>G=<&<6y{>^-w>ZMeR_!{lU!gQHU{A0^5Y6sl{9FVl^m-RsUf z4ku@LdbstvyF85ZXE;)Ox%!o zKEJ_gb%p(}BFfu32o$s^DvI4;@J3#t*5qUly6k9UuIoTWY>VM|c9F&tXzP1&=A8zH ghC;EeqW}N^ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tsqlresult.bmp b/mseide-msegui/icons/components/tsqlresult.bmp new file mode 100644 index 0000000000000000000000000000000000000000..a85ab5ab836bd29c655e8831096786589bb7ffe9 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjKg9Kg0jQhW7pcPa%T%2yTe3tu34l zXAmQZX3oZU@8H_u3}OV)%&`j&hHHm2h!I3H$I!`X#iK`X6Cey?1kub{a_5e!q2ZiM zmynGjMi9*$p!P+#ZmFA^BAY{uAhJ2zzI*{{S^e~>sEiEU93lmg%}Hu*21c=hwsz&> z#c*?o6ht-$u9pl3spfR<*s=HDKTM0@=FB>O9vHv!T3U)aI#zyuD<40GD6U_v9I z4;)Z4HUGg>dl=Z{DzTass(}c6JjF9Rf18eEPKO z*RS5ad$lYqfLvVWz)b)~dijC{Krh$^1px&)d3bhw{|=Yk{`D)wd_3k%K6(_G{Fs=T zfgVZi=zwU)G>40q7r%RiB_-3ly3n#V&|i~|9D%#1XU`r3M@RhTh|9~*zHkAeCBDAi zCoK)g28OeSnHeygfo!0cfw2aRcl_o|J9!dlJ1~lY@$M8E2@Gn8nUHt~3IYvjShEHq Qh$nm?3dklQ@jj?X0JjqLjQ{`u literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tsqlresult.png b/mseide-msegui/icons/components/tsqlresult.png new file mode 100644 index 0000000000000000000000000000000000000000..c9ace6f3c0a4f95e5946ae7d58f22090cbaaf30a GIT binary patch literal 827 zcmV-B1H}A^P)SP(_1U_AtxQ)ZA+v`|Pi2oVA}O<1fd*16;cHoWzuTq7t*1G-nsr?^Zh|(~@N8 zog_YK9q~ySWaSoPn$pROf%AS2NY5$Zux~Lf&vvstYc4A{`5jaKfy;P3(Y(30kII{c z^pESs_QF#=+rf~5y?I&tk@gOgg|jA7dpplD9WS}bhBdSB#6}a}&&!q#i}06}^$bv2 zoIzc~XJ)TFMDpT7Zr!hOOm+3m^y}ks`bycn|M012fB|tH@-pX8elC-uf)y-VU*wn) z2KS}uQwsp)71dO|s%Pxzgq{ILOy9}bD~~ZPNo!jWA%tUEy(F3a$F9=a79h9q49hb1 z;>$_a(EnveQC^?J^_S|DIq(r1pld9xLi78Mh(H`GAKK{ z1B8wklo~d%-E`wy?sqG>yrPC_Q^)rsr48s}I5it4E(iR3WLOQyJVd%KOUz$?iR`v9nFXS@a(NT;~ z9ER892BDz~9hXZ(svuHIG~I{{=p43fBLu|8M1|-D2QN~3;|b^eo5TE?reRtVSEnIe z0ssO*3%5JevTe_48Xg{{Pp7W~pd(hzE7t%3002ovPDHLk FV1hT|Z*Kqq literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tsqlresult.svg b/mseide-msegui/icons/components/tsqlresult.svg new file mode 100644 index 0000000..460dd08 --- /dev/null +++ b/mseide-msegui/icons/components/tsqlresult.svg @@ -0,0 +1,407 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tsqlresultconnector.png b/mseide-msegui/icons/components/tsqlresultconnector.png new file mode 100644 index 0000000000000000000000000000000000000000..ae2ebdfe2fc3f09477cd6a49ce4e4bff331cc790 GIT binary patch literal 534 zcmV+x0_pvUP)zY%jYIg5ncG@8A`W6BGrv@} z8O&zp*WvT+A?K_3h*i9ch>I1s5D{jz;U*4e<~$zYVaa$bYVrbB{-l|ieJtY}77a?amYG|Hzl;5tpH$#DvL-Wgz0~>$ zUXAcy$B9V=HZe2i+!lV0u>UIDL;{JZ$%t5qh;!wpCr9|7D%@DqZF(PT5%DB5`w#(TWLV#UqjF+SmQ+3zddd4p1IR_k=r z>o%>X*KLN!bwupV%#BeODxa#!%pZR%4TEvL?I**y;D!6XQ{Wo^|FGK?*byBD?KCZc Y-#^WlLWY9` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + COL + + + + + diff --git a/mseide-msegui/icons/components/tsqlstatement.bmp b/mseide-msegui/icons/components/tsqlstatement.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0ff9971df1b1075003e5bae49c07abb428a3a823 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjpTh;gV1+>9Kg0jQhW7pcPa%T%2)`k^wzl{c z0A-0WXXCqfR52&2vXUz1*aZhu#T+GFU8TU^nz_r5Kx4ZhiAw4?{L}eU%x`k$79aqqes40q z7icUVbA%-&)4RIRvNq6Pla3sLyQgQ*9s@^5{N{+u%g?@W0iq?ozTPJ-4af$Dvxb=& zFr0yGpqGKM28?(7=1eZUl0XklaP2H GR3re$wkE6q literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tsqlstatement.png b/mseide-msegui/icons/components/tsqlstatement.png new file mode 100644 index 0000000000000000000000000000000000000000..4f5a22c96c50fb1abc034e83342b7115a73cf3aa GIT binary patch literal 577 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ zFuwp{#;w&s*+43^PJAcV-0m;IXBDaI$qs4x6ya&49EM6n;%|SXyu{O6FT$ZX_UBg@J4axoP$m~ z7Jbu;7^1oWMQ?`K`AQP4bgyx{x8=(hLvb;dt-zcRG3xyBQ| zCE==I+Z~s1wmiKuwnRs{wo`W)+FDohO-MU9?`S5Ee_TyULHFEa39@&N7koKmyJM01 z`TNEkpNbFv{QvK7dd1IQ%$Z^xT!qFa;*|z-?gSh$SZ>^F!oS7W4|FhBI_xAOY`|5rlJ#gX#N4SW5(piJddwFf^@7Ecb zd|R8$;r%*2L$hDy6q8$on{~k}M(4Q4YHiZx@rD{FxD0*rJ5vg_T}({jkB0|GN(hSQZt3I{Ep##F<{xjOmll z_J(u@neXW0a(gLpE6RaSVr#=Lu|M^@TDFN@uo1m@hy6*z!hA-CjJ18%efOr71EZV4 M)78&qol`;+0A2R?vH$=8 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tsqlstatement.svg b/mseide-msegui/icons/components/tsqlstatement.svg new file mode 100644 index 0000000..c6bbeb5 --- /dev/null +++ b/mseide-msegui/icons/components/tsqlstatement.svg @@ -0,0 +1,397 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tssl.bmp b/mseide-msegui/icons/components/tssl.bmp new file mode 100644 index 0000000000000000000000000000000000000000..2ca5d5b8f3c77499f25d43b0e22d9650c414fed6 GIT binary patch literal 1782 zcmb`CF%rTs3LrKFEcmWTf=g)Z+H8;6r=f(+z6KTep^+`I*@6Y$z=6ESTbso#P z%+%VX`u*lJH!4kaft$T;Jj$BFr*5?)PE~8*102~VW~zL`@(6C%km5+YRcnYS0*TH5 zSCoY0?37Me&ngV483u6p2fLk!fXBP5UzFJCR#Hs%R2p{GESbr>ovK>TDh$w;fO7|$ na-_a$4N(d#=&o5B;wm2=tuj36b8@`=J6l6-$daRs+e!EVUXW4o literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tstatfile.bmp b/mseide-msegui/icons/components/tstatfile.bmp new file mode 100755 index 0000000000000000000000000000000000000000..659fd5164f67c04ed433476f9d0cd9548b34ccb6 GIT binary patch literal 406 zcmcJJu@S>C3t5mIp=! zBoc}S4FW>ZpeX{HqCv2bX^MbgF;fJzb-l<1y@3DK!(FsvmiR~ckAtHSZE!FWu9^dY z?t`|1C?twxE=9=9^o)?J=4Cf-dk_I5V7U^=yK?;)sd`^k!j%93SRc7kQwh0u94ay^ zR#jM}wtcP;X|Rs;wDvdxz&6P?u)kQidAY4h;NHz@o1D9~cb=2N(}f8DU^1AHU!RA` ziOFTej;2loZw^7IixfHMa^WNL0|4w=?+pNW(cF#$o(Cb`v>Rn5&~|E<)TgOa>!@&fctcW7;t?*~lz?QBw%RtStr7iCaO$SMp8FF?L|jBO zR|4NBj1D9=Blay<0szM&>ig1LKvWT`6I=-h?SvLG`e}4^?)DEcG&r<|H*cAr>wh&+ zE(wsB06^v;OSQ~dc*1qU9}o2pN&%p$=9zPms`wNDNc<#yWsh$)0zmqi%YiNRErAq( u_~iJ;RCP)p0EF(9#*B`PZLwJ9&i)30xbRN}v?5Xf0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + *.sta + + diff --git a/mseide-msegui/icons/components/tstepbox.bmp b/mseide-msegui/icons/components/tstepbox.bmp new file mode 100755 index 0000000000000000000000000000000000000000..f9998e251b4ed28e528a20ca6ff468506a63b142 GIT binary patch literal 406 zcmZ?royN!j24z4}1BfM{n2~`6EUo~R2Xjz}1_lNoVrXc9P(TvM1mXsU0|yQOCH{jE z!~g#v77zm=NC-&WMFRJM0#NYxIzoKNv3W1tg}M0x?*(2Mn}PQN1C)IM#O8(i5h7j= Q1_kT|?0;ci2byyi0D=<%b^rhX literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tstepbox.png b/mseide-msegui/icons/components/tstepbox.png new file mode 100644 index 0000000000000000000000000000000000000000..197d82600e735b5a0755df62864f913b8cd80e72 GIT binary patch literal 286 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ zFuwp{#;w&s*+4tPfOkT zW@5;;MV0gFuQ_oz9PBbHI@i8i;_ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tstingdisp.png b/mseide-msegui/icons/components/tstingdisp.png new file mode 100644 index 0000000000000000000000000000000000000000..4d6273c92156f9209326e674f2c99af94b68f26b GIT binary patch literal 681 zcmV;a0#^NrP)rOiFwY?&uv!;09IF5T>+0oBA)~z-z)X<^1|fgL$FgrWT@$oU$YL$Au&ePKqGcz+zcN-fUjEs!1zP`@U(Gk5~ zkK5Z@PEJnn`FzA;F=DaUaEVlvySqD33NIg0)fELmFsr9c)i|%`1|`i ze!qVpJ~cHpc#|h4CWe9oLqPz>#>W17#@M#)?qgT0)r^}2zyHJe{RDpiaPOzaDb?60 P00000NkvXXu0mjfS(`Ms literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tstockglyphbutton.bmp b/mseide-msegui/icons/components/tstockglyphbutton.bmp new file mode 100755 index 0000000000000000000000000000000000000000..5ab95b607c48dfd085143aa56fd2304eeb28fc33 GIT binary patch literal 406 zcmZ?royN!j24z4}1BfM{n2~`6EUo~R2Xjz}1_lNoVrXc9P(TvM1mXsU0|yQOCH{jE z!~g#v77zm=NC-&Wr6K?t&A<*3wxOhhc2X;1+8Wg<< UGw%ca@&7N>A0T^cp=@eU04-$l(f|Me literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tstockglyphbutton.png b/mseide-msegui/icons/components/tstockglyphbutton.png new file mode 100644 index 0000000000000000000000000000000000000000..5322820a888c8906b1fcf4fe73ea301538f5411a GIT binary patch literal 431 zcmV;g0Z{&lP)>)~-Q8Ul8I;a*yUcUPRY*JX3E^b^ix!(fd@es;XU?KcCNH z6X1LCugrxIOjYD80HAH#P3CbN&(1C8z!-xuhPtkY@lO$0D>SOiXvRsT?MQrxoH~0FhpyOloBZ=T5G~Eq-mPtIj}5?q9{0> zPJ@}0lAl`iBr=SF`K7?nkqm1pK95|H65F Zz!$oxy4g9D1H=FT002ovPDHLkV1nAou!H~r literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tstockglyphbutton.svg b/mseide-msegui/icons/components/tstockglyphbutton.svg new file mode 100644 index 0000000..9838b92 --- /dev/null +++ b/mseide-msegui/icons/components/tstockglyphbutton.svg @@ -0,0 +1,203 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tstockglyphdatabutton.bmp b/mseide-msegui/icons/components/tstockglyphdatabutton.bmp new file mode 100644 index 0000000000000000000000000000000000000000..87a3aba062408bdbc6085142be35add47531a93d GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDj7vhFsutFg5pW*)~8j2wRi$Kz7WS=%PH2nYn zA4rk`kW&s&JJ6g1qywNvtmZg5Iq~rD07)W^#AOapyRxz}k%j=35pND8(1BVo83SSt vem~;!m#(g^sHiA@y~wh-%t2N|3>(cHP?{tgU=&|K!^r^1`C^nkghBuSJ0#Ou)zgb2sg7^fc0YNMln=c>?Hp?_0zy~ns zFipi~8?k8;LD47BVzwAXFo~FjbKM}0F7B}F;w_6mxNx`}ejn!#_ZsK(8J+sj>i!1& zM&@R-(K=-lAel^RF*gk30sz?W_b)Z?bUFYxfQY;la8)qm!{IBo+W-~^k5lX4RAS`}p(Y0?P!elaGI-SyLwMZlqDyAMgpgSk&wH3%C3L0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tstringcontainer.png b/mseide-msegui/icons/components/tstringcontainer.png new file mode 100644 index 0000000000000000000000000000000000000000..878c39e4a6d4088664c74fe4183fe27ffe4c508d GIT binary patch literal 1481 zcmV;)1vdJLP)NL7(0Jy7NP;{_BNCCs%}wN<(?3Eg zE*)mt@1MQ*xAywZ+UuO}Y-Cxk(%I=OPA#2^58XXvN-R2J3fmC2LuaS6=eu zr;AUUQcBL4hK?C>Qg5fX=gW8#GzSrP~Y?Oi(72>*}# z@9`AYCsxu@(nvm-Okr*z&qLER{tZ_zq}gyTZ@H9;XA9M;5;-=K#9c?p%gST=pKY|IBSHMn*%vhUk?#&-RbgxCZmA>kY7OXr@Q@p#t*fT>|qSp3aGge-9N zFut<-)yvk7R(59Y+yE@ezmbn535HJ_&ZudlC@*L^1lBrhLy{y(uO%Khuz#v@Dd|#6pFuu&2YQozIft43 zKF7h?fvWOK#?2Xzqq8Hfo!p37z6ImIwBu!ni{F+c>Fjit_*?OI&l~M=*<&1?9UB=9 ztA;FObh7TXjV2>6RbKXFgOkCAla+dbH^J0TrwtIs&c>V1lTT`&P*z;_MnbBpzLfvt zWO6TM)!|jY09^rgNAD&%A(>WfTT)tF#=H&Tc=z=tKRchCj2woH9&97Ba{elAW!*wk zH712jSL0sNiM+sV7s}c`*(}QpiouC3?mxemu8_^gq)n$}2*(s%WZ)q$t$X z)RJ~SjjD<&;tp@eTw!MH;BgEYHW*o{Z)HT(yaZ)?$q0Ym%Z z>E+4hUB=NAcoVX*~= + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Str1Str2 + + diff --git a/mseide-msegui/icons/components/tstringdisp.bmp b/mseide-msegui/icons/components/tstringdisp.bmp new file mode 100755 index 0000000000000000000000000000000000000000..62ee6e3c191666df0a46e970098e9d029792e57b GIT binary patch literal 406 zcmbu4F%|+L3`A$&vq)!aY3Vua_d04hC7qq;;Ub)cox!-ewmT%@GeCG;=huXxo9ab* z%A9Z*{yF!@Vp9kxK)xqcp^~VzYNL-p?&EtR%MYLIH}QBu!8W<;P6_JhKRax@zh d_K7dcT+dMSxvTc!C$j%9+qQpSwdYrxy9+_M)@}d* literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tstringdisp.png b/mseide-msegui/icons/components/tstringdisp.png new file mode 100644 index 0000000000000000000000000000000000000000..4d6273c92156f9209326e674f2c99af94b68f26b GIT binary patch literal 681 zcmV;a0#^NrP)rOiFwY?&uv!;09IF5T>+0oBA)~z-z)X<^1|fgL$FgrWT@$oU$YL$Au&ePKqGcz+zcN-fUjEs!1zP`@U(Gk5~ zkK5Z@PEJnn`FzA;F=DaUaEVlvySqD33NIg0)fELmFsr9c)i|%`1|`i ze!qVpJ~cHpc#|h4CWe9oLqPz>#>W17#@M#)?qgT0)r^}2zyHJe{RDpiaPOzaDb?60 P00000NkvXXu0mjfS(`Ms literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tstringdisp.svg b/mseide-msegui/icons/components/tstringdisp.svg new file mode 100644 index 0000000..22e05ae --- /dev/null +++ b/mseide-msegui/icons/components/tstringdisp.svg @@ -0,0 +1,380 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + abc + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tstringedit.bmp b/mseide-msegui/icons/components/tstringedit.bmp new file mode 100755 index 0000000000000000000000000000000000000000..ed48b0105636146e059ad31cbddde80314dc32d0 GIT binary patch literal 406 zcmbtPF%rWd3=?{%FcXaPxI;9yIvt{dh_=x|&4;2}lAY6aP~iHU2V e9@_7OPu+bJ`D+ICoO3=uGfjhstyxjn`=kq`S literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tstringedit.png b/mseide-msegui/icons/components/tstringedit.png new file mode 100644 index 0000000000000000000000000000000000000000..420957b584f550604ee2e1f601df34ae35a166c8 GIT binary patch literal 534 zcmV+x0_pvUP)PaBK`@9xlOR(pV-N(3U=(>b$jS=)vBGLt_}+3jm&^Oyd(OQaLlW;);H~ce z0naGdYPH_lV77OWibV-u$`;w&KS6CvEpxJB^iA31% z_gIz%fN7ePN+kd+%VN9T5(osy=kowmtJQy&?V&`CMuX94#Bewyolf7^FP96;lNW*tShFnIx0Ra5x+Qh{a-byIqdQBcV`;!C=7Y zbfR9bW11$>XcX6Vf9}C=_2~oLd+_pS`ZeB5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tstringgrid.bmp b/mseide-msegui/icons/components/tstringgrid.bmp new file mode 100755 index 0000000000000000000000000000000000000000..e408e989f704933c6071da44b8184df2fc821c15 GIT binary patch literal 406 zcmb7=u?@m75Ji6^N~E-ul*~cTI)oyU-H{2H#{(S70(b{HTtqs)FGoZQ3eNuL@8@qT z%JFn-V0C6cP&-$Hjq$yo+h)}wz=;^=g`Jj)NGb6^Z9=s=ilZX7{BLzjWt>+}p1=%!ue|H|AgLs2?VX^?yQ(!4&@vC0UvZQt(0(}Mp0C_J W^Ujw~?)c_q7=}V!bN=Q({=*xmitEAv literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tstringgrid.png b/mseide-msegui/icons/components/tstringgrid.png new file mode 100644 index 0000000000000000000000000000000000000000..ad10f3f03856dd9f4dc4a320da5a312c657f146a GIT binary patch literal 1319 zcmV+?1=#wDP)W()3d3{P$-0^X>@jWGCVv?R#w)=3jT?bk`hWvN&uLcm_P`@{{8!(*#<>X zh{a+^l7u8l7>&mDZ{m4+;PH5#_Q2!u(9+UEMn(qN+1Xeu7ShtvC@n4B5Pas$89W{j z0L#nEw70iYR#t}3=VN$yn3E?@0wg^ULLh_yU}0eazu(WmzyQHua8q>&E`Zr=CO&R3JS={$wAXJ;BOCPSw;wf)oKOc=+UFZVlgyLBNz;BxGaGLHvy;9iPPx>pr)oK zDWsvHL01%o)YMdj5DflqVvA8{`_||>$vY?E55(VtlmgcD81_7MLxQ=b6o#ja7$u!b zdjw)DxZUn}1rCP;S(drgImTyA>7=I$?w*se7w2HHSorj;kBirrFsBM)YYr#2rgG3A3?ine_mRODGbdO}=^?I3{oFp6$lWP?` zYPK@eoWX_qB07g8<`*@l{3;)P^#|@Zt@K{ZdSFCg-oG0&w@&92^b@g@uLWXUj~s zzQXhmFEjW}Ik$h2m<+ze8;O%1B5l9Lmk8=udI+wD%yfvT#gs!AXb0APB0n%vx6 zT3TA@>guAuzn|6BRodFx)>S6B0Q2+n`2BulS!QWz30amm{)-Z2>3aN`9X@;*o6UyZ zZf9(4jM33ioKEL@P=cR;q9`be0zh?j^@eu+Kl>oD8jFgGFc=KTvP@oH-iF{O_dx5DJAD8XDsC>C^wJc-yvZm`o<@c00PR$9IhW dWHX-w{sPqH>qkGcQ@Q{E002ovPDHLkV1jiBbT9w_ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tstringgrid.svg b/mseide-msegui/icons/components/tstringgrid.svg new file mode 100644 index 0000000..f1133b0 --- /dev/null +++ b/mseide-msegui/icons/components/tstringgrid.svg @@ -0,0 +1,564 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Algfu + Oef + Riiz + Zsxvtz + Oi + Pkghj + Ugx + 123 + 78 + 00 + 233 + 15 + + + + + + + + + + + + + + + ABC + + + diff --git a/mseide-msegui/icons/components/tsymciphercryptohandler.png b/mseide-msegui/icons/components/tsymciphercryptohandler.png new file mode 100644 index 0000000000000000000000000000000000000000..0fbfcfdf6e3d6de9807e35b9bfe5923cc026d067 GIT binary patch literal 849 zcmV-X1FrmuP)RGl@klazuopq%Zn9)L>W>Owq2W z7FnSSA%u{jMH@{Lax;h&G!Q7QqA1L%gc`ykiKL)r(mG^Q77|p5eMv7(Xj*BD=e}{9 z8N$WPA0Bw_|D5|j=bn4-c^+t&=d;X|nJ`fC+bjODieFvv?^JwW;d;^TLVsrNHxG!2 zc5A-G3%*`ZMeD(>Sd9Idc{n0^F^IjH`FG`e6TZVz^kn8o({ygfcxJAEuh5MT@G^#R z5JRPwyRo6F_YF9Nb1{Y~EUN7H;tU4LSQ{&`uX4Hwd&+wszQ+|MkpsB7*v3j?4^(q^ z;$zK0xf8xE*&M>NxDDN%31!m#co!QmT=8Rg1iQ<45%%Jh5}@76%!@Pgcie(6@dS=W z#89WMnK_DMScNUqHu6&}kBIYdH(sxet+FxKV@YO?Wac2Q!^VhMTKT?>_cHTOGw}xQ zDG7{L{Ek*cT#HNaOhha!hAAA!AG3(fhEc55l=jCCnVFkfc)w&YjxQo&qAYtjGk-lB z^~^koWttQBA9SIenHO}3h`2B_e>uy{{}&OlwS_mQWiuz@1?yXxxn>RpXP`Bo;#kv# z^_jUNBKk3eh4>uXG?!(C=B6LOay*`yM<61e#&)dJ^riuv(zN*TPL#H$H5|iLB|{{7%&=12+Do0%sI{d{?9^xzx3IE~+o z37p8xGlg5yiilThuS$FdB4Q(6!b6$)S7n;SZ<%?#5|^1LXS9mBL`3w_oTAIB6YzsM b{EhhsA+mK-#|NZ`00000NkvXXu0mjfe_M+^ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tsymciphercryptohandler.svg b/mseide-msegui/icons/components/tsymciphercryptohandler.svg new file mode 100644 index 0000000..1c7b848 --- /dev/null +++ b/mseide-msegui/icons/components/tsymciphercryptohandler.svg @@ -0,0 +1,218 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + SYM + cryp + + diff --git a/mseide-msegui/icons/components/tsyntaxedit.bmp b/mseide-msegui/icons/components/tsyntaxedit.bmp new file mode 100755 index 0000000000000000000000000000000000000000..c2d4e483784f72033478c36694c16c2df9b5a684 GIT binary patch literal 406 zcma)1u?+$-4D?HsFS(_pWDa_Ep#sX3bac#<0g#x$J9q#~=In&PQ~kx~oX?jchvQ?S z#2I}LZaXL1q`&L?92Tt*p{SI0p+ka&YOPp!7P*H4al%5AH9)XK~yu3UB!r?Gpub1}rc6>e`TCJAc+*~4&2qu$>;o)Jbs;W>F1-ILs zC6pzgC<+x76+|KtLZJ}V)zv79f?lh|u)K`LY$lONFfcHH!{MNypa6|VLn@VGbaa%3 zg@yeE8XFsNxm<+9VQR|CDDUh z6DW$ZGpo&0BtFOT^XKA^;$krYdtTAUCuSq{3ox&W|U zy-M!Kj{r#Z^~7v8{>sba=*$ed$B)r1EwLVrGSb}4>dl*kLLpjPTd`OyI}BtAB$G*2 zK78QY@$n7vBS-k{!UYzWmM|C$tQ(DdV=__J(E-4rmoItp>={m{b7wTW3D|5l)K)7h zwHhJIi1+XLac++M^XE|)7jJAjdzO^nk7O{QG8p*Da2Un!$NAq$ zyBl%wBB{c{t^NADcPUJ#X=rHJdeM?3?Hy4(9!LA?712kJC`zY!Qd7hF@#FOO_tVnS zf;|}ImxczaZrvh1I0!g&VU+>8(cNs@NVv@C&~oE$v)`K;Wz1Ay`MYi3TJ!t3>J zWn5HJ!iq+NcC$xGCU=cy*NAFsYbic=4mNEbnw-S`-~kOKC46_{1ZyKBIQ#n0zId_O zts?i#nSBMa9Q5|~;_-NpT3QgBE>giDv0xB%I#^rFYBn}CZGRvC#DQL~Cm0M;bp1N- znwnTQ8n=s|ldIJfT)Kqi-o1UvcR28PJjCO14x3C=b#!1d7 + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + Past fret fejgz Okfrevlfgay OvfrdWios Tzjly Abcs + + + S + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tsyntaxpainter.bmp b/mseide-msegui/icons/components/tsyntaxpainter.bmp new file mode 100755 index 0000000000000000000000000000000000000000..2f44b98c5a8c7e0e38888c14c39be4501d135dff GIT binary patch literal 406 zcmah^u?@p83}b+<+%tCU9o_RzW?zwed_V>bS#^s`J2o1p1}cjZB^ea-UbYFvR>hYv zS4?=6{sATEAsLn9L@gUuLCu@kYh1@gw*B*7aBH+)EUU literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tsysenvmanager.png b/mseide-msegui/icons/components/tsysenvmanager.png new file mode 100644 index 0000000000000000000000000000000000000000..a3250c85c7ae08b5874916b522431f5482e77791 GIT binary patch literal 1154 zcmV-|1bzF7P)e!ycW_V)1rZ2KvP|sSfTur_ zgA>|X9iQ#H_x*mJ=ll7*&v$#C7d+43vyg}eYnw-JDeG@2>QuvugYV^>lSo8^L?RkI zz5F^_zy49t);_LyDJWDm%ST1;ujuN&tn(>r#Q z7leCU;-UN^zh~roc*cP-4vhc%Y244g^Bfq%f*4~Qc>bZ>2WzeC@;}*TfB6`e2)4`Z zCfHJm1Aw}{ub4%=Q4LgY`PwWZF;Uu|u`)*uh~Z*syX=kkpFQ|oN7 zCn|JN6ZXgbNz26oKE5&}rR1UT^szb4=UEh&)Zk)y6H3mWFv(9!PG6u=SeWN3NF<_R zo7`Ch0A>A+d15kf3>Y6DnJZcS6{@RBac!Uvlas%jh`FqJVu8W&th85!($BOfI1Yz- z#+d{)nl=#4z+sh>kyE7Z!;zz>!1EjqB6i%u0s=d@ln>9I_V$s*&hLYuKu4&WM*epnFoq*6D`Vg8fAu;45sUUg z{gs<$5s%*ehKxD8tnXKUQ;+Szk3+uYF+_%KhEA(Ci$Qa<%A0+ZQ+X*nGY)a_nE-&d z6Ebiz=a5+pfCpFP=C%pdm(K$LtZnR2a-rFn(Am*~ZNVORMeYu5SG$q-bhkr7d>Fhv zS3=cT3jo*=5`bR44gjFnYhi6|dmlma@Y?dq?QVFEx>sTGAq>?c*z2wiCzrPYpW zD8HbJ&J@?s+I1VK{o7mAsriWjP<}xfeSGo)34#Un_1_^yS}uj}jG^m8cWGDTUOJYZ ztAvGxXsA*SQcc|u0ic571_EF-V2mdK1b}#6Ffq{RekPrMf&fro{~h{HJ3{vMD@oTg zN-I`4P*3kjCIf(|2w!Ns+5iA!qeBpcx&E`aUxiZzmr-7!##Qy)*Z>xGuT*LYe}5U? zPl|`nMnAmx!p3lfY>%!=PAwu^TYCaP%a%zgE&aT)f{d(B$;QTx0MG_EZ<7kTx^J6Q z@Wa5bRB`D`0zenblq8Cxfvcb{Ap?qXtaab?BF|FUpK4j zJXl&XF|*uhbL(z!%Cg z$DHh>Hvz!S{ps#AMHNZ_NJ) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + -par$env + + diff --git a/mseide-msegui/icons/components/ttabbar.bmp b/mseide-msegui/icons/components/ttabbar.bmp new file mode 100755 index 0000000000000000000000000000000000000000..788e0360520c4ead3db012dfb22e91ac93d6f193 GIT binary patch literal 406 zcmcJHyA8u25QfiEq*U}SQ)Z6zUdJ_4WFAJKqe4uA$agP68w*11*ChRF9?Vw}&||KX*Cjhf6~!*ZNl__tOtsPYiqj literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/ttabbar.png b/mseide-msegui/icons/components/ttabbar.png new file mode 100644 index 0000000000000000000000000000000000000000..fca5e09d5a5a91ad8fc11fd1c90a5ea344b6b6ad GIT binary patch literal 463 zcmV;=0WkiFP)!13w_C>JF<}^Tzu%E0iF&=x zYPCvX!!T$x8qDW&`u#rp{hrh5gsQ4sE|+2fz;rsrG)+v?%mod@NPEk&av9sUGi&J_ z2q6l?0hY@pnx?VYYzmpYDmw?IUQw^t%L=LwrxN^s!4D>*h7L{}YUTg{002ovPDHLk FV1o6Nzv=)0 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/ttabbar.svg b/mseide-msegui/icons/components/ttabbar.svg new file mode 100644 index 0000000..97b4c41 --- /dev/null +++ b/mseide-msegui/icons/components/ttabbar.svg @@ -0,0 +1,440 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + Ode + Pziuo + + diff --git a/mseide-msegui/icons/components/ttabpage.bmp b/mseide-msegui/icons/components/ttabpage.bmp new file mode 100755 index 0000000000000000000000000000000000000000..63209bfb8a035bea620deba5296c6eb93c11a2bd GIT binary patch literal 406 zcmZ`!xem5$g->yS+`>ljh(o#r>6%Q zRiB@`E+2>@EQ#?RL{fH?loAh3OIo`an|VnD{6!9yUq`St1D>1QPw(-(_u1|}p4+{j b-s8Ez5~wKrYtyIX6)4K7y_~}9(c=v#y3qkr literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/ttabpage.png b/mseide-msegui/icons/components/ttabpage.png new file mode 100644 index 0000000000000000000000000000000000000000..a8fa3b52e8019a992f6a11b745e1b70a87c7382b GIT binary patch literal 775 zcmV+i1Ni)jP)gvx|2Bv9BQBd_JF>T&vZP&1Nw(GlQwADcs%NArJ^a zlB73HWdH~UgOtnV&}cM3L{Jn3<#HJ#BO`90Wm$N5ctELCLZMJVUtb@B!5|bx!SnMo z9v>e&8;p&OwE}?vWLf^BBEvA;`QqXtLZJ}0x3@7nJB!=fTh!}yjE;`t{{FtR0RX6~ z3Qg0nv9aM9I5#&3+qU8J`H;zEJY#fS_cX92NfJ2cPhLp_0|N>G;o#r^Yin!R-QC5~ z(vo+zvMhwd;r@k%1(yj#)CADA2d}TMe>jfg*~)EAOiVOHQT*@<4i68T00;nSn#QlL zu2`i~Vaa5Yx4EjSyj(7`v$HdnNF-bykH>kbRANU*M=TbLxjY(;@_ateOw)`A0LZc| z5RvC-wOSq5x{b}v&3!SIO6_;Mo`2Qe-rlmfv$Ml{WdQue+byYf@j$nR%UbifZRjXB|X&T4xA2FFs^2^Ihc5!jR zR8@6(B9Y*yr>E@XE8-n8r@ta|_e002ovPDHLk FV1h-$XG{P9 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/ttabpage.svg b/mseide-msegui/icons/components/ttabpage.svg new file mode 100644 index 0000000..0cac5e3 --- /dev/null +++ b/mseide-msegui/icons/components/ttabpage.svg @@ -0,0 +1,467 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + Ode + Pziuo + + diff --git a/mseide-msegui/icons/components/ttabwidget.bmp b/mseide-msegui/icons/components/ttabwidget.bmp new file mode 100755 index 0000000000000000000000000000000000000000..41fa7860daf3c3708b8d7f4da49ef28592cc95cf GIT binary patch literal 406 zcmdTJQ3`-@BU}WSDcHV(CS8z|h$P{r&Rh+bn#J~Z#vFkWlvh7!)zyV#sd9ctF z`7-9wyo8BR#N0n9EXX7x7_=yA%^is65yU>AXTt8>(O-J2rnuE%?yH%`NeI#-=nFAP Fc>rzg4FCWD literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/ttabwidget.png b/mseide-msegui/icons/components/ttabwidget.png new file mode 100644 index 0000000000000000000000000000000000000000..398274fd0313140f5e64ee495fcd00ea85db623b GIT binary patch literal 582 zcmV-M0=fN(P)YoBi)*bEUl z0A3Iv&-1`>TxY#reVY~bTp zxvu+THk*CB_xNjJ7zU!zC~~1< zX_~NY8;ivPnM?+PAl#a5+s0rpKt7*GHk-wEyM-i4;5hCflm`G=mdP*-91aH%5kyhM zd_G4!9=`=G%ff!Y$8TCGnQFEAQYw{h9z#TD0H5yQYPI_5d7keo zUzJX$4=l@mx%U_%BFnNsM1OoPm&?QZUa$B0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Ode + Pziuo + + diff --git a/mseide-msegui/icons/components/tterminal.bmp b/mseide-msegui/icons/components/tterminal.bmp new file mode 100755 index 0000000000000000000000000000000000000000..9f4e859ea5429fd62756581b57a4aeca54c44f90 GIT binary patch literal 406 zcmb_UISzm@3^NidJ0m0SVCOq9A@vo!r%%YnRPhp2+@xF!5)x_bI(FKwp9^RW0WbcEP)`2)8;} z27jl~o(8`rs~{mnH3nIEek{`(0HkS}|DmNrQkK#LU+@Cpl&1S@P_)DV0000 + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + ~> + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/ttextedit.bmp b/mseide-msegui/icons/components/ttextedit.bmp new file mode 100755 index 0000000000000000000000000000000000000000..bf316c5e72950735be1eb2d724d166c1b2b71256 GIT binary patch literal 406 zcma)1F%rTs40G?;vvy?U9o_j06J^ZE)~)Z!NBjr>z{qk4SEeelt4MNsS?>EJ#1s97 zntM%hp?>W?4~JGou%*`gpo5~SwANrax3~vGVTFXIXMkXb>g(OHsXo5)KQ}M5LboDj sIA%s@jr`E_rqpBBjI+ksLfzb8B#*$4k9^*e|H4CwqPh;8dF>(d0SP@^Iuf^yI( zBKiRh`U6e;15Fw?j)p>m2#SmhClc)tf^uMm674c8qEgxG9h~aTqjiFF&NW%A&E~mz z?sczcNr6B>@DDKn1OkD7Qd|h}Q{Zj$H#s{y1NdJ6U}Hyu2*>R?tB(7z7}f%hA@>20&wDBhhG-$HzyK$t1B@j94s2eSJN$EMqpC zi9{kSEG$q{Q&ZHykB^(j$44$NFNsE@D2jsJZYLZLqiGrdS65fm)zwj3TZ^iyJUl$G zwY5cab91pZr7YUt-xrZcq@aCW*FUxID@t0lv9ZDI>@2BNitFoZEEWqkn~kTZCsL^t z=jZ3-^LYjb2f4YqAs7rYF)=|ln?=(!Mn^}B8YmF(`FyCVN;aECk|ds=pSiiYVRm+w zqoX6Hr>9w4TO%9}BS{j9qM&IS`Fx&-hli356`X<7=|tCcve_(Fs}+yOLseB3b#-<4 z{eITh*YS8fG&MCbJUooo>&4}Akgp;fP|!g-o#y4`g@J(q3&Fg7-ZBuNM%-q(@>nx=7gcSk4`!r^dmaBx6*c{w{f zJIv3|)7ja{@$oSxlZnN}MSMOVQ&Us$GbKgEi!3skOw7#8P+eV()oP`(vJzRA85tRQ z_tlpAEEc-EyNd=}DGDqy8jY;1tYEQN*x%pBZnu+4rKqT= zAQTGG($YdQndIW);`i3PQgjbAO~YcbFg7-Z&1U1|r z)9> + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + Past fret fejgz Okfrevlfgay OvfrdWios Tzjly Abcs + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/tthreadcomp.bmp b/mseide-msegui/icons/components/tthreadcomp.bmp new file mode 100755 index 0000000000000000000000000000000000000000..2cd5ac0bb9ff5604366c21a9ce7daa823a6e0f0f GIT binary patch literal 406 zcmbu1F%E+;3`LDpi7PO6>^a!EOQ&Xvnp1F|Y%FAE!RP3he%lxYb?i^R{rqDXr@155 z3-tjHhda7yem~xIxRgYMODS1H1;UAP&UmPLsa7EvMR$SDdio%Mu^sGH z;$7mDqNtA~EDR*K*XHxZKLQxx7ZOFivDvt`>R0f)*o@HA44S^O*}5+FKJSevat=_l z#>`9I4=@^=Rsb+&)^$Q>vcuX@c>&=V2t`LFn=Gd!z_0E$W%t?H{C$uH0MYYVqH&#Y zEEq7Dngdi2N(R6<{ze9RB%UE0|5+OVu&pZHP7}xJ4-e*U2D+op((BpSR@DRWY_e@t zQ0gYyR0x1C@7Du8bo3-{uSvgK14g^>0aT%3q8%9m%$?_fK70Bq&i58hw+^9EfG46( ztxBu$l~%(XzTr+W&~2-Nz59_)%^Q*L3|e)QcKzEbz_BYi5#*iS%BpQud}rWUw8pDj zve&Jd)0!HOUe1}G3Lgz#-_<*AbIa|w_2{K1;}^}gs@OGidB2wfC>I`>ZR^AGzB>5Z f`uBgC69@bNyGaQCF0MJB00000NkvXXu0mjfK2RG~ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tthreadcomp.svg b/mseide-msegui/icons/components/tthreadcomp.svg new file mode 100644 index 0000000..7b9c317 --- /dev/null +++ b/mseide-msegui/icons/components/tthreadcomp.svg @@ -0,0 +1,491 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/ttilearea.bmp b/mseide-msegui/icons/components/ttilearea.bmp new file mode 100644 index 0000000000000000000000000000000000000000..f0b40f00071cfbedbd57c5cf361ca7fd6caa34dc GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjf6WEKV1+>9Kg0jQh=7g)ga2Sa8XMV15dApF z{{DU(G7wu4Ap;61+yIX`AdN`wp_Vzg-2#%q;~tPSl6xSEf$B*GXy#DMU(_-O9YeBQWi+f2&s@LG6_QY9lm-Y&+<7ND87rq=I(q3 z?vFT;#tZd^y!4#tr24h@l^jYS!ln?~feMHWv@8o6yKdTdK}al-Q25W-Qu+*QbmrM{ z@`%((6x~Ny(8n#GOVMHbXak}XoDG{_cW7OD)V@^)WTN&vvMsp iudM&H8Mwe{Vg44*xnVgo_$;z$5N6xjV7ywXhxh^g>)h%9 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/ttimer.png b/mseide-msegui/icons/components/ttimer.png new file mode 100644 index 0000000000000000000000000000000000000000..6a7a84f22ac3c67e75a14f72d9882ddaf5b3ea43 GIT binary patch literal 1697 zcmV;S244AzP)awUujgU6kGEG;+eMX^B$RuepJN`vjjIw#l>S6`WeTp<;#Al5GG#0A8=> z>H4}4N;;08{djRsj*+x9@OYlUq>{*5)s2zfvd zB4b1%5}zEc8hQ6XJ@+_pFh7aC*(|w?-{cnZ+SYH%`joyR= zzuV;$WJyWiCNuNr8=OwnSdH^&?TWhB#yp)huWa5lM_ASC$L4Cxz#>7f*W?(D zdL5xIP;@gEh^J=%8-1VdYi-yhsn!oJw8S0Swp9qFr5Ti3Eh>!$rB;g}5MV`F`OEni zFTGIT@t?8@-_0GbZvK`f-k_CDJ+DU4>&TP~fC~#`Yn_t&;78u>IB?}eqrd+B4@#7eT1>YN z?o$>P6cni4leV|^dVVWOZM{x+crM@*0JfD5tp}{Y{Ffj)nvmch*Xxx^K&OmyY*iN@ z_h!*Jk_o_L8ZWC;Zm=}o$sCoJ3qcEZV@k;C_F3EDa^)XKD*zKR=#gvUP-)dn7fIjJ61f2bQ#@Zn{@~X~pgm!9RHO6x zW-$*-O2SdutbLVxh`7E!;TqfpJV5v>3D%3EB+2E6Hhfwect~~+Mc%e;!T-u+q68C6 zy?yX22>@;dgQfF(dR)uSoQXc{d^)m^96^8n+{7_SYK%qS#gv}F1OJ12D7|3b69_K2 zEiXACSgv#=o!+)p71Yj<1g*V9$VFO$3M$v@rxdXd*;3Og+pxm=+j)ozdKhK3ZEq1Exd@XcSYJ6h6K zyE(FR$M_4SdvP#j`M^U7RLazHo%NW}aWvVz{|Nn^p-_Vcc75IDD#~`b7DYkU2zTu; z5Q1Pr10%!TmCNTo`MY`EjyKl;O+cT`W|KrwjLaa2^V;U?_0KQsYTSj>AL{Sy!4C`u zptA+8w15ss0t|o`7#j64?w1A@TMK`@weQ+~^Oj=gQ-_aZ2gU*a43TAWbxtT@m0{r4 zzR~JWXa + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/ttimestampfieldlink.bmp b/mseide-msegui/icons/components/ttimestampfieldlink.bmp new file mode 100644 index 0000000000000000000000000000000000000000..36fc0d4d3e12b739739f6705caf21d36cda2c3cd GIT binary patch literal 1782 zcmds0!41MN3=AJ0Ouz_CzySOir~7p(zHp5j>v~5JLWovajpJO-XFF0a*W12SJHwx_ zj`P~psFV@+!y#5B!rixO-dk&V-qE-tKFw1dp$SKhL3VI;1Pz33w!_cfxs5gLPzcXb zOz>M~{yzT7F9nhKvVR^qK?&q3QiP?L^G=*4Ai~DEz~vas4#+Z^*hyK|p2{smyn)v` j`7)|vgQQLdUdu&duC;uIwh-h_5T8(0U&8Na0W2&19)wFvKT1o0 zgm9e@<_Te%5Jr%W_9{`;>1_Lx?S;yq7;g~cATgdqdP$Z&qR}{)yBoc7B%KG|tp;A) z1u&n+6n%Z4iSZ`zxD0Ss(taQSbHJqpHVoXe{eE45D=TlwvKCT?9aYOy5yAp7ZpU7% zi)fpGWdPYmQa{iv1&slFfC<|%H%e*({lIVFo9(asb#|2_zk>t7ZQxbGHwiqXO~7Io z4bvv%GSHMXZTlhswmLv;<>WaA+$oa;7zehLY;SkNxz%ES0pU~dx4+8 zXjO9FrUSq>+aEie(m`Nz!88W!0tRTe>8$PQhcE}IQ~v#b@*gji|4f*-(Zm1%002ov JPDHLkV1kY;1 + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + D:TFLD + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/ttoolbar.bmp b/mseide-msegui/icons/components/ttoolbar.bmp new file mode 100755 index 0000000000000000000000000000000000000000..5f37f30e414ccda4fb42eaf8ee8e29510408f6ee GIT binary patch literal 406 zcmZ?royN!j24z4}1BfM{n2~`6EUo~R2Xjz}1_lNoVrXc9P(TvM1mXsU0|yQOCH{jE z!~g#v77zm=NC-&Wr7^f)4hOaOJ387sAOMx!wX(evC_ba(MeY608SR}jJLa6|TTy$z WYX(St4^ReGJ<#D$@R!EUzY75N%J)0~ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/ttoolbar.png b/mseide-msegui/icons/components/ttoolbar.png new file mode 100644 index 0000000000000000000000000000000000000000..ab922d5d633032c13d01e5db932b4603b873bbd4 GIT binary patch literal 513 zcmV+c0{;DpP)Y8#t>~oYksHaCCQ!LvU~q+9UUHL7{bPff$BC zrBXrDH0t%bsV04N{uzFqOwyKR!ifZzO`Yw)CIOd^Rd<9!vqWfm!D6B)3SO_5Y&MJE z?Tuuc$8B>J5LET&R@!TjVL+50mB6F$xxS8T~KTX4Bt zrdF#FjYjc!JpH_Bg0?KvmSxky*z6iNk7ZU)H}H(RS(*vicC9E1@p#+>hxd2zn``>? z^32qj%eL0*^$ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/ttraywidget.png b/mseide-msegui/icons/components/ttraywidget.png new file mode 100644 index 0000000000000000000000000000000000000000..777fe9e413b21e398a5451d856cd5dc28f2e6a7e GIT binary patch literal 901 zcmV;01A6?4P)tsg6;CA0&+_;M2 z>c%8sMD{ReP93$io5{;tW<*kls!bXtu^XrJ3|{YA%E}Cljn8RrehY;DS-^;7GI{bj z4jfocTAGvc@`w2S=PcEx;rbFfA|p~jcJ>wO>O8!8^PY-|>-hcKM`sEn<)8!fU0hZILQJY*|3wGoLY*DGr4&2HNoHsOSN+}#Dg8g23(}4Ut-CUR8F4! zlpG382tx@X_klcMEpP;w1O$OnAO)yV)oqbM7XnqbZU6m}!|)TozmSH8M}$JIG+4a| zGJw^H-;355o!&<$M5~k*tG`A<2aPOgf0Wim%-C~NT>gaq8?ZT z+=~YO*dkSZ4a^)An`d%!kCU97qAe{?jL3>0oSgv~4mfD324c#?K%=Vuh$|2eMr1Y~ z&pvv4{YE4RT$l;hEY+K_bs};Z*Z}0m#z#J)rAsT>xG|HSo_ydaP&$}Af;)gmReiC+ zVI3H+cNP2hmynSG^XC`v`SUY;z6vAK2{c)%-=eju`XC<1@D4U@I!0F36k1!My&ZhM z@qml|)lBGLKBNQV^%hfBmP&p7dD_}u(B1veQteKJG$8>3fjd@F(QS%~M$7pJ9JX!$ b*K5l!_+00000NkvXXu0mjfL+^|g literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/ttraywidget.svg b/mseide-msegui/icons/components/ttraywidget.svg new file mode 100644 index 0000000..82a3411 --- /dev/null +++ b/mseide-msegui/icons/components/ttraywidget.svg @@ -0,0 +1,285 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + Tray + + diff --git a/mseide-msegui/icons/components/ttreeitemedit.bmp b/mseide-msegui/icons/components/ttreeitemedit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..3ac2d76704ebb3ece99c7fb5c77f8f1dc69d6756 GIT binary patch literal 406 zcmb`CF%pCz3`OINorR8-rKRVv-|MU`r`Ypw3o7oA&hq;q>kzvw_QMZv5{88R_35PQ z&A8Fa*PZk=zp_3L=82hNQxM^n5bR(i(m`U3ETC=y3ej98#gOu?l>fztQ(_a-nQvBY ijFGHmD5^4`jmO3+jp6eCzI(@-;?WCdcB37?{PzMfm;*on literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/ttreeitemedit.png b/mseide-msegui/icons/components/ttreeitemedit.png new file mode 100644 index 0000000000000000000000000000000000000000..d67ca7b38aac5ed8df85c1ce5771983b2c26fab4 GIT binary patch literal 279 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ zFuwp{#;w&s*+4s0uRex^<6iW8mm?u|N0|t&Y}|&G(M`ze`{_@V85MkAxb#ZbkYQe()0dH zRxW3)kZ%a;`YSxa!zonvxlC3}w&)~}+nx!3M9w^GWD+p`-5Z;^|AO(X#_hkqJyV*j zG~duxS^UCTWd*$j?Uhr$pKj177F>QJaA!GVxu5N>Wr=H(LbgATI{NFP*n>^`%A!3@ Ua?3Wk0Nuyn>FVdQ&MBb@03nfSQ2+n{ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/ttreeitemedit.svg b/mseide-msegui/icons/components/ttreeitemedit.svg new file mode 100644 index 0000000..145a690 --- /dev/null +++ b/mseide-msegui/icons/components/ttreeitemedit.svg @@ -0,0 +1,231 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/ttreeitemitemedit.png b/mseide-msegui/icons/components/ttreeitemitemedit.png new file mode 100644 index 0000000000000000000000000000000000000000..125564f1b15f679aa62e83bf2003e1d08481dca7 GIT binary patch literal 279 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ zFuwp{#;w&s*+4d1FQfy4FZAg}SL-d+Q6|y*Kl!wVw5xvFd$h)u@Qp U*2{i(0q8ykPgg&ebxsLQ0Q`t&pa1{> literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/ttrigconnector.png b/mseide-msegui/icons/components/ttrigconnector.png new file mode 100644 index 0000000000000000000000000000000000000000..41a164247ed4744493410b6f4f656a568fe12218 GIT binary patch literal 1429 zcmV;G1#0?BCMzyj{B^60WYkw;e^T0tRg z1+7hd)ubv>Q5#=q`=hC~E^TenYDy5TMNN&E)>fq&w5boQMU2Z!@d-Wl85aBxrYJm& zpq1}KlB9t#zkmQ6_g{fYPY;4NZh-HZV$e~e@U-NQfgt5IH+OSOUW;7yvfzTng5k@S z!dn#JG4EYGuBk!C`BFHY&H*3Z-qq#xGT`2&B?vCq2icTlIP7*b?bwcssc*nJems17 zdLZ%?`FY!PM6OV@6hF`q}0?(8a^&^t~xB-K>B!02*Huv z-$9aG2vTc62r%rxkI{o;I%6Te-M1g_&79Fq=dN9!ObAIHT!Y%G3T$4HiB0)?5E&Qu41nVx$i2`r zH3j!$4d5?T!T;z{$f~R1h=~Qfy>O|l3~MqLVMoD!Oh`z8r-#Qu+VRl#VeFKYh`|BQ z|9T9wmMur*gm{oXO_2UulX4IP17V*r6ITBKc%3;7|HB7?UMGqg%vii?H4F)fAOtYP z$NxeE#vDK0tY_{jneTlHUy})slac{QAWeTlKYcoy6BE((#g~w&RG=K!zb@Ntq4itP z!Ji>8h6i>#RM)N``0KCGv@;)Otp+|k57{8!xX~js`L`BioB%M>9dN;BL(rYuu*Jl{ zH#Y~~grIK!53oC(2$IVn3gQsz+N@STZsErpFT1;Y&8ZU*9W%CO z>+zGL{;kNPj~#`~{siVbb+GjIqIviTw1tL3;jKWhMgz4*4T17Q-egKhHs4rxC(NA_ zn4@BGqoV^|+7P_r>kEIS5;~<49*lvf6qI{DJ$1Kl$w4XKnSJ2Uwj<^yW0Bcn^pwjx zMaCRTRbWeTV~g?krWWHzIk^MhnAnMvs!Wy#*_HQOv(x9y9r(s9U;jbjt%vQ#x + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/ttxdatagrid.bmp b/mseide-msegui/icons/components/ttxdatagrid.bmp new file mode 100644 index 0000000000000000000000000000000000000000..f1931b0f0849ee315d2ae5de38a36318f9350bbd GIT binary patch literal 1782 zcmeH`!3_c-5JmCg#iJKXumTJ4Zcnyh1zs$IUbY9X_`-K5BM?kjjTa|C;4}N?!|onW z_jSl|VBFJp&%VmD5F-2Aje1UGNFn{(+Z#A92oDDnV`RKcx1ymJieK``w>j52RCkFV zJ}Wa1$1kOu(m5A)NMrPVq)0Rf2^|i*K2zuNil28l=10}VG0{T?{OF7Yq|dR^dbajM zf}+o1*Vp~*{Xm{wyu8ikJ(FBF{CImhtSLlyAz=_b~rxGIE84-nu9VH Z&HtTK)R9uEMJbdnIAdlCj%WUM{s69{PXhn| literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/ttxdataset.bmp b/mseide-msegui/icons/components/ttxdataset.bmp new file mode 100644 index 0000000000000000000000000000000000000000..d1d77c445bfd39f89d6e4d2bed217a55f589db8b GIT binary patch literal 1782 zcmcgrF;2uV5HwPREOA9dMZp8O5AXnb9>SCO1Ld`eP$Z{_*QdrC*?sprb+AB zz12MKn;-DlLwXo%=vF+5q@#KuhLQ$#FM#0DR5_39zsOIPXH8}7`rWO0A4jv9!Nhzs zzZc@-xGagJLwdXkMaB2xh=We?P{~S9DAeWMP0$l~Bq$x!1096cErMA+OMVg_UC+r9 zreMan=)r&4ScWT+iePcR|4Q>}VM>@qc0l{w;&OcGigD#)Ek*=Ufpw({Y_flgN z%rlLHUu#U}fS_I%sK>OZ=wA9YZ4C}l1@QaMsk`-4Hi$TALmdJ`*?WzzZ zj;`aJs1*RhQO-eKN6J%FoZ~2Q=vO<1J5_0*^iv4$bv?>aBlBp>fB9BAa&&~Qf`cOt kcDXJ%IPyw-9}yrpofZSLA`Z6nW0jc|Z7D{##xh;Bz0EFW`&xMUZ}jf<-}C2yHLUDxUA z>LQg&vAn!YFc?JFb*xq^cDtRnwl-8%Wp#BGzu!-Db2DbMnL?q!+S(e2hllk6!^6V_ z0s-E&wed@_h%C$GpFiigu@Qj&{(d|j5294!yLrb4 z1OSjee85~z&gF76x3;pevBAK=0E>%@{CN8|8~gjnfB+gyCL)mtySuyf0kgBS09+RW zsT}L*=-~JDb@KT<+uPeDlS%%J#|c-ho1dTOSHGY3_V)UKd_Iq+Xotzj%yk2jO@P&ZR&Q4@mMv^2bx9#ZYC}yYAut*e(Y*hIpBO{jsEG#TA zK0a#h^VTHrfC#Q<>Grqsl=Smo^j{nNBTQD&^3)84i9lY zeOj5f-nvy6U})1=EJi34qBuGV)6<};h)TA7)d z!Ex;xe>{1D>h~LxtHmuhZs2+I26LTTTyug@C`2Zc!QpUl=l*@ZdGv_CUcW}9)3|au z_P4e$b#-A21o-ymO_1gP(ml8GpDaGt&NR-(bUH1B5aJSBxSXA}=fB(343JKzD}U%0 hHz7pyv+GmG{sH0@_QlOJ0*n9v002ovPDHLkV1kF7-+ll9 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/twavetableedit.png b/mseide-msegui/icons/components/twavetableedit.png new file mode 100644 index 0000000000000000000000000000000000000000..c9f43955503793be5b0eb500648f0260538b45a9 GIT binary patch literal 815 zcmV+~1JL}5P)!;o%jGMx)3YngYORG_FZ#as*_8fLtKB3djV4tALEidvbx` zeo*^;3IJKO3feDSl)+Z~`ojis0){U5w13WOB(ACvR0|p!pN;O)JG&a$9r;GXdUy{iueO}&= zk5P7@JO+T%PMNlf4ayX9R4SfYdn5riiv@MH4!L5v^I-v=cjEwT&CCM8aJB_gXNM%< zp{YBhJrMx|P6wrxRZD(OfeOFhk9))wG5IHt2k+M}YH2XzTO@Y zV7qTdTT_c52+;w)iO+oV`PiA49}+)Qqi1w*fJv`6ETGS9;;^A^ReTj-$Z4mjLX98` z-HK00psL|GmM|mxVQh@KxjA;_=1KzwoeoM?^na!48&A{Qb$ivw+RP@ZYYkz~gaCd{ zPxEoy&EC?ou;NWAsqD^I@%XQiwOPzm8)5*wdeYCn{pBd);=+mnjyAV&uVeXRzj3)p zOiE(gj!bF5pwmvVMjJ6Xz@EY)78VwG8ys1ixf^YS_JjcDW@m8^50PJfFe(6`p}Cd2 zo$Unte)_FFROw>?j6Q!xR$c+?5|bnWnpy*{moKoJO{Au$la`So4H)isQY6uyKNg>m zfbQ4{E?;Ov8>RXX06<}dIwk->ebX7XXJ@0X(MQ!SU3=%QUPF!$O&em#X=&WFIgty| t&nN&q9uF|T7!iZde= + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/twidgetgrid.bmp b/mseide-msegui/icons/components/twidgetgrid.bmp new file mode 100755 index 0000000000000000000000000000000000000000..a8d34e90238ffa6c4b1dbd56bdf29fe603a2995d GIT binary patch literal 406 zcmb7Axeb6Y3_K+Iw3L+0LC-osM>;YA^JEe4Ku0=r1cZ1(f#bW_XUnltH&cdaEx96! z0~zwDmq$G&H?ja7*6tUXAz|UYXF;Pwb&Cj|O(Mx(>rNBt2i3qSx;$f;PkrXQ?|y_C eCZQYZK)N3$t-t1(8jg8Uf7WMxA9#vJz=kpYcMV_9X5JizxD&?AGyB0+C& zFJ7+~S(fp5JgBPr$$4vQi+DT^K($)s@bHk~;b97e0@-Yq)zwu1cLwEhnPRa>CX?aq z?d{u4dwP2C`Fy0)X$A%c@Or&imIbt6u)MsCWm&wxzf-AHuxAiA!j>pB3Flao#T zcNkn;T#(D<&@_!;Fi5pprLV7#^Ye2&9uMQ=<7{tlHyM1`!NCClnM{U_jSZkhi3)`R zb8~a-?(Px@1nBPW=H=yuP$-097)X+<8y=5`Kp?>D>uXbUJ*g-PkB^V&x=tt*LJ$OO z+on>fP%4!$P17~N{QNusu~@9B{SJe(vooHbpNYj{3=IvrI{&{9J}i+)P^;B&9EX*a z6`(~Qlu9LJStgs!{!_+XU0sNxh#&|}&6UB_)D-1%8K2MhPXQJd7QSe|!yuVVB8nn@ zzn@4XLakQg=H>=fRnasJ_{`wp;eq4hV?v=2rfG6@b@lgIWEcjjs*+45Nu^R;US1*y z0!K$ju9+H!L9JFpmSq}^#`m*mad8nvQ5YN?n&%JrfJQaO-xLD+WQ>_ zAHT+6Fi2Zl8}04wU%n`}KG@saBM=C1a&p4j+8WTJM22BtnkI%}P_NgyzP@ICef`^v uM@B~I?Cc~GiQqU6f*>F`j`O3>mj3|1`%CBwQ8W(#0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Algfu + Oef + Riiz + Zsxvtz + Oi + Pkghj + Ugx + 123 + 78 + 00 + 233 + 15 + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/twindowwidget.bmp b/mseide-msegui/icons/components/twindowwidget.bmp new file mode 100644 index 0000000000000000000000000000000000000000..f4ffc461ce3b99933f29e37193d47385d2b697d9 GIT binary patch literal 1782 zcmZ?r{l>-s24+A~1BfM{m=VlkU^oDjf6WEKV1+>9Kf`~jq5l*Euwxn;8vd8pl8=C{ z7&Qk^0AhqskE5#;5AQ#)79a^^PjGgJg#Y=(R8S&;nTEo}Felg86sY)2dG%{N zyU5gn40HTd)h(rE>aFd7dh4w1tYu__)iud5$532izL%eoxFk?7kiE#q-&9hH40D7z zIqzrWstO97h)vQE7I~1FC&tB%Y|itXLI~Ou5rYUW)bROQQ~{LwQBqZ4Vh(gtiJ2vk z&B(y;y|@x+6eM89xw#<-Xd^CjuBBuOa&Q2(?2U*8syP@H4`d5*aNbPKf|~NnQcX92W(}Ii5ZwnNwqB8?B{_W=^cO z9xwrrWKNupUa=W8)xk|GGq;M@(I?3qxL%SOsNqAhc39j2jTyA%7_f+@1W>KUVfYUK DXVL~G literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/twindowwidget.png b/mseide-msegui/icons/components/twindowwidget.png new file mode 100644 index 0000000000000000000000000000000000000000..40e6353bc6a49229a1bf7456ecaae66cd2667d74 GIT binary patch literal 597 zcmV-b0;>IqP)4gNDO%b#v!(@w1R)Ml`}5XA zPZ2~t)>}c3T>{^F3?zae2&^8Io+j)`V=Df`<&tf#O*3I>hPJux-QB#t#KFr=*~`F( zec?QO&-tD2=bXdga3oolb&4n}fX(@=DB(};fTbwOyHo-kFu+#o7x`RP_?)Ja+DsZI zs7eY|Nuy;mD49*e*!Fgw^qn!VIJuaI1xBdcx^50Bt(=@In{ zAwPY+Ug5Ru-~9oSB;h>Q$zpVrNYF=9>oqKvL!5SBWhpk!x9~7+-Up(-w&4;tZubhm zvA)d5*Y^zo(=~N@x>$;h5e@mpYTYe8e2Y`{TYnx3w_%Gn= z^e2v%RbV@ITmWXr-cwcW#CrIMDP%vH0QRbS@_CK37p{xG$`cLbG{tcKg-ViTSuZ`; jCBVT3NV={U_1m%oJLaQhvHjvE00000NkvXXu0mjfA#n^6 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/twindowwidget.svg b/mseide-msegui/icons/components/twindowwidget.svg new file mode 100644 index 0000000..5b84dcb --- /dev/null +++ b/mseide-msegui/icons/components/twindowwidget.svg @@ -0,0 +1,289 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + WH + + + diff --git a/mseide-msegui/icons/components/twmfprinter.png b/mseide-msegui/icons/components/twmfprinter.png new file mode 100644 index 0000000000000000000000000000000000000000..83bc421da059c326ae37233c70c5d3962e307321 GIT binary patch literal 1346 zcmV-I1-<%-P)0zcH;Ahho zEsTOxN&~fL7ucp$9hm)-C+9hzzwRWHA%vj6 zzh6^cUVe`d0s!>n$&;TDLXfuh_V!i)G~EY4vyBh})@U>i3W8t;0FTFG+_h`h6|dK8 z1OTVg*;rRsH-M)a9UV0xOK!Kj0XZUsFlhq-)?hFU3W8t(0H4oiICSXHPacoQ2mpd0 zSd2#Fwe)6{N)<}OJswY8X=!ON7mzE~Xf$4Pxm@Pum_{5 z%bXp7$z-xyt=6LeV6|G0HZ(NYa}VTsp7K0TGXRZ7b2phxat?=MUu9*bS0oZ8wOXy; z;czqqKv`K?=9W8m?!4}BIQGrW&6Nxd4K*7KhU+g%Q3e1227_U+x3~B6>gsA20O)i& zXLomZdvSS(&%D@Ecoz;3s{-_p|31pqZQHO`)%o-fjU z0MJ)UaQp9%18v7P%BH4cDwQ&SYV!7%w}1Z8f|0@2fS8?`%2PZGV4i-jHRZha?ite? zpSBilEP_f|h{ul;$jg%f0IarQ>~F5cAHR2w2Or#eZ*TKe@2V87M{-%=mK&~n2n42Z z`RW+@`dt8kSZomw9?rskk$~G^*|C&R_1SEE=3Mc*0eNLg%iaShE-t{GyCLWm8vwQ# z`Gvqo$G2tHolkjYv{mO)F9opKcro+j?TRJ#7PMP7LoP4G!Xksx@(TET6IfhKfa5sm z^;K9*EJw2Ut_x72*mk`3wGT>n*B?MI7(z5Ui-Ljz0CI>#3P`0A#9}e{J=f#2GxyJD z?_KkeZ8n~LMY~5(6uwhiTwDl^rWCPQ95vNjF+DvCk%+~7Yyq3qCFuF(L&1B`bOZpz zVlj94@Zp>P83E7pOxKzHznWe*zdAEVQC*b}kJpcdcmjCBfDE`Q0nqS5!06~`%azNQTf=w0Y6yqMkfIdMksF|tf>MgVh6q3b3W{Vh z35a(|AtFboTZNw+NU z)CU;MKU!F{+wG6kYIPaIWGcmKz@Coo1*pV zd-fXu07DsUN6o6aU@+M4_xnGqudiQ!smRq7vtlQ{UOhfGHa6MT)^_Xc*|To}|09A_ zN5_g|HfP4h$H)Ka?CiA9&(DtlxbO@h8jVT=fdHb>C<+P+ke{Cqj^n_xD}iRe0dw$R z#-AM@Mn79~^$2FAFJdWca5{Xv*r04xAmSs6X z5XO8y-%SABgpg!reQv4Xd0q*i_N8;Sq7g#KqwIly0WpC4ts5$*h5!Hn07*qoM6N<$ Ef^Tke3;+NC literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/twmfprinter.svg b/mseide-msegui/icons/components/twmfprinter.svg new file mode 100644 index 0000000..1c7e49a --- /dev/null +++ b/mseide-msegui/icons/components/twmfprinter.svg @@ -0,0 +1,331 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + WMF + + + + + + + + + + Poi Li + Poi oL + + + Poi + + + + diff --git a/mseide-msegui/icons/components/txserieschartedit.png b/mseide-msegui/icons/components/txserieschartedit.png new file mode 100644 index 0000000000000000000000000000000000000000..243cc17aa5a45f910361cb565e52dd193d45ae94 GIT binary patch literal 300 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEX7WqAsj$Z!;#Vf4nJ zFuwp{#;w&s*+4_)v`PGW5n+>iBkbx1VD zGB$L$)SWw1&cKkhHsRUyJJ8Q`Od|5ZnKDL2 zmPmzT8r)x&PDyE;vsvdtxR)gJnyst9?%q7(c_q&aYop(a3-ZrL*06rr96#-8%z}LG q0GA{8ejCqqKWC|tCboCm9R_aqgu=XPH!Yx}89ZJ6T-G@yGywqm1989r literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/txserieschartedit.svg b/mseide-msegui/icons/components/txserieschartedit.svg new file mode 100644 index 0000000..2f74c8e --- /dev/null +++ b/mseide-msegui/icons/components/txserieschartedit.svg @@ -0,0 +1,274 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/txychartedit.png b/mseide-msegui/icons/components/txychartedit.png new file mode 100644 index 0000000000000000000000000000000000000000..c7a1e67473363b857c7b1b941b199dd901ec8adf GIT binary patch literal 557 zcmV+|0@D47P)QEGgzxY!Ph=PTJV5fz?gPkv+AQ3AYv9qwS zu!uH3Lck&f1S1ixY;1fC16B%RY+_|2lH?YbD>JBfW}Gt%Qk;{``p(+tM^Y5U=NAJx|6pO_V^Pwm8-;(1vsH)0nG`jmIB*9=XpjxexN~OdCT-Rkb zn_*cN^?Lnb%}Xsh91fVK$$UO1o6VwW8sTsl&+}dfxUS1;wZbqAHk%ElQVGK_NF)-s z%k@$M+qRiZCQPSOGMNmrEK?{H2m}KEHU1QEJRa$EI;_`g%H=YqX_8DPKRgXz(L=!X zdPSCH8jS|S;qc3=eWZt{NL5vGxg3>Bg}5;%@Sv)Lq{&kHfW1EkaGr|-#6 v6av_8w_Gllr$v$^AxY9p0Ld5C>?isI9I4>4fchQ-00000NkvXXu0mjfsz&c+ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/txychartedit.svg b/mseide-msegui/icons/components/txychartedit.svg new file mode 100644 index 0000000..12a8db3 --- /dev/null +++ b/mseide-msegui/icons/components/txychartedit.svg @@ -0,0 +1,316 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/components/typ.png b/mseide-msegui/icons/components/typ.png new file mode 100644 index 0000000000000000000000000000000000000000..3838a43461f3aa552f90992a782913bb6df7ed97 GIT binary patch literal 328 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*O%l>?NMQuIx9s<#_a1+ixh&018Q#xJHyX=jZ08 z=9Mrw7o{eaq^2m8XO?6rxO@5rgg5eu0~Iayba4#vIR5sME*Ddv$kC7U7W{?% z+Kq&EjSA@nO~u!gw+pZR|Lo?Yw!~`;Ukd)DUQ+V;FZi?x2=07lQdE@x){!}r73f?B MPgg&ebxsLQ07s{ErvLx| literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/type.png b/mseide-msegui/icons/components/type.png new file mode 100644 index 0000000000000000000000000000000000000000..7705bae540b7269d7f072fc903a3e70a13902c9f GIT binary patch literal 339 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*O%l>?NMQuIx9s<#h z2fy?GJ8vm=wm^KRTwQ~?&7$^lo2R-jl0<%5*0ATE*?6S(NepZ1nt+2=e{{Wm90=cW zKDbTH=#E_So&>3No$NXrTt$!Wk#^91*K46}xTDpsOd{^r%h^4THf#R*^i6A`hlB z92nXT7Ofa9al*0`#Vjj3+D=I1O)CyXIUxty{OOy#ikOl`q+XOYjX8Mk+0*Oyywhyo zy6e8b-|M-q`_FY>_XG2-eVRlPxUt9Y?eUNG_>DdOogP2kxMi3hVJ68(&H}1xetfo^ zH+(s2%b65?4KD3b2XHyQ!xCJG&y)PMScGv^eKDXFZg1@ctilsmjWu{gx6g}WjFppw zB(q8G$BXzdCztv)=34)vs=8^&c~#vygCtO(LF+$@rB$^e$r}?~%#M?+ z8Vb-HznkRHfc_M=VZ)GvsYPbL9QR@UfXQ)ugFkg!Jqi29RdxM<_#~c5a%4as=??o^ zd_2h@$@VF{kMk$!cj1<*+SSGnEzpnQVO^3uFfa)t%qN)?;FM@da88nA1NzP>ym>m# zA<1#wN`|m?oMhAK2KX-+I{h<+O(SegvahOU@F32^XV|4H+iS5-mnp09c#^|VRnKED zw&2@l|A(%`A2<e#9jws>?h! z;_VX;Nbe!pjQzdw3Ve^{*pCgp0PA~pZ{bcH9P4uVJzU+=PF3AjRa@E$|G8*Merk@l z>n>Tp{#@6-U4j{1LA+`z$xBVxgV(C+H(abM6E{ydxaaUyJG=f{aCcR$YumXq$y`;P ztVK!ov_Q*}9BuT=t@W`Khw$nGeg_WXNV^}fa$Hrf_pN%)|Anf06tlQ@!R?*HuStII vIhW+<|0)%yLRC%EWzm(r4EVtr{Ehh=?};GvLlOuI00000NkvXXu0mjft{-ii literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/tzstreamhandler.svg b/mseide-msegui/icons/components/tzstreamhandler.svg new file mode 100644 index 0000000..6e63a90 --- /dev/null +++ b/mseide-msegui/icons/components/tzstreamhandler.svg @@ -0,0 +1,221 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Zlib + cryp + + diff --git a/mseide-msegui/icons/components/watches.bmp b/mseide-msegui/icons/components/watches.bmp new file mode 100644 index 0000000000000000000000000000000000000000..b7dda86458660e50b6098ab9dbb1d92a07ac159e GIT binary patch literal 1782 zcmeH{Jqm+B5QP;ah3QgADr*r-Nn;_TunW187tqpPvC`UBJb{9Rp!ky`q)MASG{_d? zHdcWQJInfJ_G6q8ueaAhnC*gHgP*@H&L=@A5I-FkpA)gU_ve4{JMi9ZU%u-;b{MK4 zIYAI$j&)tLY*Jhjwm3p)=eIzYn6(20bF2XJ>{cIg|iG3r}1u?Z5^4h}fO(t%)DfW^td z#nHuRqN!i*6+_yzfwq(0aBt2%e|~)DkZ^wSHX^=UoMUYLXG`27$`C(Q#O8@Op8n;E zqDTy2&+ZS!iR1W)uRZk~qo=jdDduQwe2Ch3`XR{ZgB~iiW%(%UTa}Wxz7KKC) zT@IXsRH2KO^T;_TL|?*#P=85`eYPAJXB>4aJP7T?!H8~JN%uev;&l1~2hSBp9TUw5 z_0^fP;NZOGsL^zK*S{}hw%`4i1LG1X+qMUBkPKDm0t3MV14_6gs;a6ds;=vzC{~ig zFch4oX;wm;u346;s_OfGp64PbO;gLVz;PUBQ`Nd3<%)tIFiDbR7=~$@FmQ!4Ns{&a cEuOM0gCKBSSJO0EmUUhCJP$gzl>EuiH&&1lG5`Po literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/components/wmf.png b/mseide-msegui/icons/components/wmf.png new file mode 100644 index 0000000000000000000000000000000000000000..48cb2fc3d1b7f9167e265a9fdb21fab391ce062b GIT binary patch literal 392 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*O%l>?NMQuIx9s<+#nPw!Lbq1PV!(xJHyX=jZ08 z=9Mrw7o{eaq^2m8XO?6rxO@5rgg5eu0~I~?ba4#vIR5tXMm?86fny)%AGK?oO;%X8}g62e@{IB*zjBOoRBR4$2&{Z^>uqT$ccv;bZ|)T@X?Q0%~6uYzdTlFzn9g1MXsKuSv=0qt_Y9lOeICnkzx=%Y5W|;^Ki#|4Dvt53Q<6`zW+^JP zjydl-XRY9j1)_y5a_^M(AB|jU`=L>K&SRc%A<7GsNJeT81>FQ`C9*q}X5~-QCS{h5#UnqI>>br<|ZoO;1mM=NAAtQ5pwmKqZ&yI>JBN zG}P7I6H<4rGmE0Q+ZUpq|I9t1Q41t)->gkZ4l|3Qn6%^oDm7>fevyR(ZVA)|8Ht?} zSvY_Mt|3tCWh6$MlBDxO76(X!;2Mz;J&DF>FJzIxHyN>dmP>6Q(HN;f1V5w986hFT zoVz#xe3j=pJy$1^BxzOZ6&4_1!9a0w7PxKTvVqGkA8p_s2bYcdt7`;U)Drz)cma0% zZ^|nh$;vM0=B*csYhz>M(AZFjMx&;x#_S(xecVZYUK$3yj*N_*w6t`1X4=$B z&FRCeS`{*r+t&7;tV|kqp0D5}|iHzDXC!p8s=;<8>pl`rRMEGjo069bA_>`$8$C@4th z_MJC$yzS#`{d0;A8NG76Hd=MnK`b4gd1>y#bghC-5$hG#OG@%)>Iw0&+`n6f$@GMr zz47eZ69w3P0|2Qh@ua3~lfPcdC@sxXoJWM~s6LhR*G^XEFZ)iOxr6!(Jxes)TDf>a dwcNige*pD! + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + 010 + + diff --git a/mseide-msegui/icons/forms/breakpoints.png b/mseide-msegui/icons/forms/breakpoints.png new file mode 100644 index 0000000000000000000000000000000000000000..904088a4a8a02daa21137015bf121cd4993e7ca3 GIT binary patch literal 675 zcmV;U0$lxxP)L!c}%7!pXpTyt9U3Gy90 zdJ5zl^qSm~^qdcnQ)wtjdgvvG5b)+AXyYL@Vo^avblsU=YN=ga*OnamgMndY_&x8; zyu7dI_xnmpiBbwFCBM(T*8H9i@XY%E0YP7DHSxIhetQ(Gz=rjyUpE)*aXnrk8EWs$HfqWL^Q%kqq&XBf23&lzoO0JySfHefj9 z&A|a$xxDZR0KTuT@^E#ZXTy}k^AB7x;!QCCTT5akUEwN=fdm9xFFKupX8sFk^VzC%Pi1`3QAqIuQ(tuApJ4j6HTXy3U7e79j+NVJx@-Ai`k=mzT8H)_j@2&*hN8Ael^tbUM8l0HC(E zXcvoo-rvX8G}peZX?)z<G>U1O1pcV7bBo<%-tBfNUSHF@z2$AQiBgJ( zM1n_M$N6cN$z(81lSm}uszsgvr4)|iFdmPoR4P=fRT_;3olb{XEJiY!#4rrf>GZFN z{Z-Q$O + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/forms/componentstore.png b/mseide-msegui/icons/forms/componentstore.png new file mode 100644 index 0000000000000000000000000000000000000000..f64ede9d6d749de8bdec4c6f70e8ec1424bcc09f GIT binary patch literal 614 zcmV-s0-61ZP)!`3mAj<+~QY0*%!6xfyR~c#K@wuZp_nvdDv9;gtm6Q^t z6jDm!>s#1!_uIVkcy$6{0*Awa(P+eKwF1Dhtf!|^3fs0(NBqA23? z{XGbAnU0gZ76R;xg%8~>rBaFce6A5>GTCZ0ZpZ)l_0I%qIQ)AO2FZ)Jso5A;ZQ72R zlvHvOW{z{qCK7!7^cD*N2rL8^j<$}+&H~7j&6oDKM6yg0IaZ3vv8qgoG7%iqe>OSk zE5GvKYkQHJO&Vs#QwiR-E@dHo)(eGu!Ws#bW@z@6&8HDHIA=mZe|%Qc8j#U@#c4+wHEhH4inX>$+5{Rr2{f zcI=+eDmWgGL{WrNiqq+o>9<8GMJ|`ql95vK3rIj!aQ3eCvH$=807*qoM6N<$f~r{+ A?f?J) literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/forms/componentstore.svg b/mseide-msegui/icons/forms/componentstore.svg new file mode 100644 index 0000000..902651f --- /dev/null +++ b/mseide-msegui/icons/forms/componentstore.svg @@ -0,0 +1,569 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/forms/console.png b/mseide-msegui/icons/forms/console.png new file mode 100644 index 0000000000000000000000000000000000000000..faf9103b4a438127161a0a91bdeb2e5fec280458 GIT binary patch literal 541 zcmV+&0^WZ%B~~e=C>Ay(XHk-cMOj$LGd!h7-XC72cX5sP_xfI+uKVs5vf1pFH%XRdv;gUJ z`dth(Z%h6FK7c>!cs!EHWEhP`?*VAFT2xgf91i32`6!i2>~_270sH-)^ZESCh4cB0 zUazOy?b7S@2!%paDiyq5FNs8gPN#FXdk1JXn>d|LL{Y?Mvk{BMsMTt0w_9ej8L3nX zRaI|(Q54DN^Gqfas?{ojAdpNZ@pwG6+wJeRKLO=(nLr?b!{J~)pEDc|>G%7$xy523 zm&-l0(&=>g{eBLI1Dnl;#bUu~wR!|7ih|v4zq^jXV8C*@#A>w?3>`I2^`g zGTmo9^nF67(+NdUh(@Et<8ee${H^yTfYE4VI-O!L82;*g=^tn`ny12F2K + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + ~> + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/forms/cpu.png b/mseide-msegui/icons/forms/cpu.png new file mode 100644 index 0000000000000000000000000000000000000000..1ce1c023b0973ea5f5372ba54310de6c280fa088 GIT binary patch literal 802 zcmV+-1Ks?IP)>+N(pLZgfZy+b*N^5b%f8jzqEe}Z z|H*W8bVO{;ot+)i{QUe&wYImnN4s3E z7c(<6uiS38|K#L^)C3@eu=VxzC*g2-JDbfWZfbY5)J@BQB;$r=?3(K zD2n%R9PiSHhK3rIO64|yAPBk9XbiSl8&bBaz4_wYIdh zly^8BXZd{Iu(7eRZ8n?h>UtLd0AO}@w$!VsXYBEK#9rO$bXJ{CXI0D7|K}Ru_p8@0 gfbRdF{MP}$0D2MtK67ru#{d8T07*qoM6N<$f{RUNH2?qr literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/forms/cpu.svg b/mseide-msegui/icons/forms/cpu.svg new file mode 100644 index 0000000..fc7c007 --- /dev/null +++ b/mseide-msegui/icons/forms/cpu.svg @@ -0,0 +1,426 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + 010 + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/forms/debugger.png b/mseide-msegui/icons/forms/debugger.png new file mode 100644 index 0000000000000000000000000000000000000000..c35cebde0fbe4d7bcaf1e4e7f5517184088fc2f0 GIT binary patch literal 668 zcmV;N0%QG&P)JpyzK@RYgQ2jm?JE>w%&PoL)Y~*XEa<16sS`Y~?)ntMfYp z2%*J!@I^?{ei92YBjRiEQ+FNjvEIpuGC6o=H@u?@DK%|NKVQT3WX2^ z;s1e8`4#dH-gEfHI3|OMXf(>i!~~)!ZlAaV1Fv5#VO$Uhu8d)|T1g}l1OfpJ2E#w) zeF2@$Cb=h1@jv$As+vzl2U{3wF0J;bPgl&PsH>~=dq z*Yci#jdG37Vv}Rfk0Xf^;YgTREQTaWfBoeK0+f$cJkQ*WEk`h$&BWtzCMPGmu6NIX z+EH%zTZQHfY(^WVy(YX~ujc0IC%*w(%qcBRld)a^0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/forms/findresults.png b/mseide-msegui/icons/forms/findresults.png new file mode 100644 index 0000000000000000000000000000000000000000..76fd20739a496d48e3bafbe6733d52310192141d GIT binary patch literal 1300 zcmV+v1?&2WP)F@c0u``U_6 zB3{5g6cKDI2wsqa#RowJ@lo(iL|W>DP-#Kmv|tDnrP#G5H3^AHOg7sjtDEd4v%A^d znVoNZXtV8R(~IY2X1@96{LcBG`Of!ArBcZeLf|+KLJ01?f6&;Y&X;)vGfk6hHj8PR zk21Z%)cd{2X0y!C&y&mL*xK5vk9#~G+S=Oa>FL4e^F0(G?Ucx}ET*QWn4h1=<#H1W zbrA}N@wWQeH1gzf>#T3AVObS?J|D4I3|-f89A{UF8UU3_h0)Pb48tHAeS)DUpTgtO z0U2R~5MbM2Sv6*6e`ER9Gyp?GL->3?WLbVN;M%ooEH5uJGJK5gNH3bEpvW?|pbii= z_2+at$@t_?6pKY-u^7>46iJeHFY@Z@Dv3mb{e6RUbwyEC8AXx#b8>=@KRL@Y&kpnI zYtQk^uVXmkHY^Z`(%UnF*Xt!7k7F1Hj^i}cpbi)xpP^(*6AcUgG_2`5E zSymAOEYsqh_fF8-x`&rvJlP1brOG^vsbh-hc0_eI9K&@6q2rt5+0U`u^_|e-W zlYevJ+|TH`rvYGDW$sE{XehLLJMsVkxm*TsYq0Kg8&a*BT)KRoA1>dZ-4|k~6^a`G z6pKYPO=~W)&*wu?6f)U#W8`--DV0hbf8`B&qy0_J0SbjQj^kjOCc$8^86Zg#-QC?R zC1%OxGj+%|$Z;f&96m~|W;Ho4mNKmVGgJRj!r?HAqBH^kMn*G5jNVKxD z%$c(%_&2@U;M{QpGjn4&qQ)L;65XW|iA0d)yG^>GRV*wl5RbW?;rfD)gJF6$OcUE5#2f6x-5R8jNl?fnNT%|14xb_v?rh$0R8?hQV1SN}4z6Ck zN;;j!<#M6xo0Q9Cwzjq?m&;Tt6;hg;cJ~^4?|j=9>;oW5g2W$RBZf~mXK=4vl}d%h z#YK|IB&k%2jg1W)#~~01(An8ZBoZOu^N^l6N4TStwjG(w-m2Umuzj^Gi(0LQZQImp zwfZWRWf{kDkR*wcvBApqFA0S^ZbQ65^6N`{Ke}-LJ$c&{MM07zR8>XOv|UdSEp0&} zhu>uN_pbo3g~OHWIg;zOhiCAAjx8l)gT?r_%%v3OZWV||qx=U0n^L@I#)Yf^0000< KMNUMnLSTX@iC$I! literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/forms/findresults.svg b/mseide-msegui/icons/forms/findresults.svg new file mode 100644 index 0000000..88c4750 --- /dev/null +++ b/mseide-msegui/icons/forms/findresults.svg @@ -0,0 +1,462 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + ? + + diff --git a/mseide-msegui/icons/forms/memory.png b/mseide-msegui/icons/forms/memory.png new file mode 100644 index 0000000000000000000000000000000000000000..bb6fd867c64a7291a04402bf44dc67ecab5f48c7 GIT binary patch literal 1084 zcmV-C1jGA@P)Ca~hr<$C6l;^yXf!C7 z%cxeX0DwZFfXmBEq*5tdTwLJp?oO%+27?d;0l8dG;*<4ep->1nH#ZWQAP6uFgR846 zS|Z9Sd_TCySw`9>+4ruuh*1Lr==yhT(0-&beeLz-Ik^s05wah)oS$j_e%oFWb#!! z9&a-k43Cvcg#ds|CPN(@92iTb(nqaUTjV&7A<3GyD2fC@5U5tGM7@V}DxFRzS+gEp zU0n|&BP0K?Ec-x`qzC{im8zoG>pw-KQMJe8vGw%y*p1y5-0s!G~IKsVM=u<<;v02-E@ zOeUL}^E|I02m(&0v!}beJLmCuIzQj;mrA8VxLmG3SeAY8dc9@ z6B8fz_xBA=0{8d#O#%jkp%jTk+F6#(`u+ajEEY=v02qcT#bU8vS(d#&Iy!n|GMPRB zKwn?qLnsu|OioV5_xASQj*X4o0SzvqX}U>3E|-f-OG|&gm^Da}gwyH#>r43D+}z&) zFf}zLeK-C`E_xaHd|tM;w)QR>jlN!4Sz+sVrBWf5mzUp1A`#l>^Sy1X+1}oMb9Q#t z#&KLnFc?$=4NDG(!|?n4D3{9sfWyN>CY??zZ*OmvGMP;JhE%Inf+R^%tJRjW*(}v4 zpwVbb@p%08&d!b{7K^nt38+*mP!t83tY-Jo(b0@br79^DimK6QEYx`lh2puhvop^y zOj)PXJv9oL&E`k7T3sF*8WNOBW$mBoa5%)D8UF%S%N + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + a + 12 + 68 + 15 + c + j + o + 91 + 62 + 11 + 00 + 00 + 00 + 61 + 11 + 14 + + + diff --git a/mseide-msegui/icons/forms/messages.png b/mseide-msegui/icons/forms/messages.png new file mode 100644 index 0000000000000000000000000000000000000000..085a0120803d048ba19e2e00faf476a5fab0a302 GIT binary patch literal 535 zcmV+y0_gpTP)~;y@He&#p0Isx%TSi3BS}>?HUOnqcE2*eKZB z`3Am$SSkurS@{Hlm31Oms8~rbiOp^oHXB73R@jCAgMqnoZ@x1#cgVNlaQK4{X*3!k z0rdO*PciuZG3PJ9KLe0{4Z<*Fv)Pc(=P?W;R_Hhm$Kw&xG`ZbwY`5E_nIuuK*PjDU zrxUhqQ>j!~uh+4{Znw*Bx8ra);JPmDcAHwQ7OPPdg~ej=8~`B8GS}-B$8jhYivaBR zdoGtt!fdr#B~J0X9`>NwY$Ak+;^lIQWmzxH-Ue8f6$1z%5`Z8G==FNBF`Z5mUWqFL zs8*|Zo`>tYgkgxPs%V-Pt4XC&G#ZWAny%~b0RUR97D5Po-^aG?L_VEP)9G}cef}O` zFc=U70YV7w_xnq;KLV7?WjxQrFbq^x<$ONJ^1kmsZ2WjUrcfw6256ebY&MJH$z(z{ zn*~5s)hMUyI`jGb;l^^g-18G;G8s(MjN($M6wPH>j&h2kBpUoo|NqbK3-D4BB%jvb Z)K9S!gMibQ*aH9n002ovPDHLkV1h0i=Dh#_ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/forms/messages.svg b/mseide-msegui/icons/forms/messages.svg new file mode 100644 index 0000000..8a4bfb9 --- /dev/null +++ b/mseide-msegui/icons/forms/messages.svg @@ -0,0 +1,407 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + ME + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/forms/msei18n_24x24.png b/mseide-msegui/icons/forms/msei18n_24x24.png new file mode 100644 index 0000000000000000000000000000000000000000..5b5c3ffdd9b50c455338bf9052cbee42dfcdb5bf GIT binary patch literal 1968 zcmV;h2T%BkP)}Tk02ZR7gKq?HM34I0tfB^U*@X7~LfB2~=5%P)OE$xgp@7k64 zHR)DeLg*0GRE&Ce@8ag>dc%46_N%hHzk3aMR~C{B;J+axr34p}DU8HVpP9UDA|GTX z3q8Bv7z#F^=C1zomCYZ#`AA3iRolm^gCEGrxUQiA&wA-+xn9TCXw%m6(-docsbv8h zd0~ffa`RdeQi3EP7y;_J(|`dGZi9cd%hA5~)<>rY5ysCX+H3uq<2wfm5q@&_@#M{4 zlPer6M8!>D9yxLNR1@7R&TJ~@rB*!a3}1e)*z@CC&EW@c0hfXR1t1|Lh@>)CA-?90 zsheKfk$h_9Volune_TtWYWCjPiTO~e0mk+F_qay(w$ zyLZWOVXE_8L2l{FOY7J5_ZT}LxohE*DiJ8;#Bct&Xqg_>V~;*xD&M}Xo^IdrtUT(z zPYdWC^s+0FjfHU3Eal4zicNvuZieH{c^o{pNGj~Cz4bc}T|9PlV8!+;?#b3YL)o>r z@*Ds#0P^`EslGYb98gWZ)-zRiF#jI*%)N_9NNniT(UI^F`6hHN0bPxuAWR&O85m93 zn6gzGtqCc(W-VVk(K=QsDnEM6{rL1u$IAeq`VsJ(7o!}ww|dn&HqfzgDEGq5hs)o??GLD&oT9tqf78ouZbKE8sFo=_H|1 zTZn_D^*D`A%t{?q(lE>7I8trFsj`V;Gs0X$pynlUXlwyUo0YBEQ14ta(g)Yi9UPUG zIx;Q|$lAclHU8&VOIbZxZ=h{v2U6_}pQM+9+ubmm0TeF-nb6QMB~DjN%<*}U;h{Ef zz@PTfZI8n+N)-8ob?Z;|#R^mR|Mftoq6Q*NtXf|E`Y-QmcYgT#DdD+YELHkEq?^QC zO2a`tK(4g{B8K@!234P7EH6a-3>HVVR6-845r8 zN&2;K|Kju=l|(G9msiTjewG^Z*I@P^1hej9UMh%84KsxRjfkV}a+Ie{s3iqTu@3ia z38P^EpOphY!^LIHZzfFK9eQ&*uZ6y!^p3JdH? zJT1%Wb(gTl6R#-Kkk+IHy%t4vI~KE~V``M?ej2UL2}DR?YVuNusp~N}nM6|O5S22D z%?4UbfCwOjP$LVfV}eBq)t@vcuimW8vE_@1w`G+xk%%7)d@FxJJHz6%0n3`kB+a5u zHku+pEc*(yuDbx`DQL3=I3ffKfZ0-rN;N>;<NLN==>)d^0tDA`#N#V|N`gBk|QYfZ&mqcREh3m}sp4hGyi_2Kgp&phVZ87;$GtT>=$(TPm=Y|hl(b0CvN<;a=w(4)8 zCJ1y2a_i4@`U zCT1_c%)6t3wgn{4)k#MG=d1WPgcv(F@Ya6Nb3;72?^u{UF~Kvs zB27rfgrvZ-)VYh6`ue7o5$?YsJ!0yhhy&+$&*xu>g|Y1F*r}la0000uaEeK(t!!W0OP$rU}%`? z-@w4p9T*ZvPK;sZOrk@h0k0uZ6O0;#D1jTKkQ6j30j(v%t&cvaeeLCdmWKtTI=a7P z=j^ky_U}7;ot3p!B9Rbd3?hOthNbhh*47(uf57cf@+d+A#tOzpt@84uHnO^{yQNRss1+@cg6`;JJHUloe30Uz~ z2I=YPDIK8YJ&*xXAm1PdFqdD;<%gll6C)4^5Rb=~nW$81ZGchRK>h;>fxLv=OOUr9 z(?A4>0*2|Casa~N@PdIe5TNqXrBwk|fUK&+Zf*l6Z)gLV13u=V9|0I0|6~5Ev|cdq zw72631Q4_>@0IlF{*<3=Ho9!0Yt_;Cl23=g<%U z<(DrLtf-*2wzfD$04d$d>(B|3$skAoWCUaaV^Tcm_0w_VC;$x&4Y*t`$mQ75-o9XT zcyf{totB*rrYPrE zo13Y-coB!gvDl05-n8;=LeFm&L8KayLu>$?BE&<2-Ji_=7bv@aeMNJCmVp8OdH$R~ zPo7*%(cN1%o;|dzxS^o!JG1QfrLaUIly!8h9v6#I*4at)$PwIbcX2meP2Jtyyq+H8 z!t5+MkytafWn_eFj~{cYrDgp904+kUs*11Y&M`bZOe_{dL;x0^h54tUA!ZvJO9L3C zh_<#eHa5oXy!p~mFfYt|dwWX*6jW1FLt9(hx^6W6bGzTu{~urlIDIC=-kL8A4h}A> z23V|)GEe9?0B5t*{T1QMmHS0yx4cTqO9p%gbsNib+|0@#00000NkvXXu0mjfpmCWZ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/forms/objectinspector.svg b/mseide-msegui/icons/forms/objectinspector.svg new file mode 100644 index 0000000..5673bee --- /dev/null +++ b/mseide-msegui/icons/forms/objectinspector.svg @@ -0,0 +1,418 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/forms/palette.png b/mseide-msegui/icons/forms/palette.png new file mode 100644 index 0000000000000000000000000000000000000000..86a170a9ca8a9ef4caacc16ed01837e512990e4b GIT binary patch literal 1065 zcmV+^1lIeBP) zsYog1PJruR5{U$wrr~fn5JKQ~yDR!|I80w(UlqmyFg`wxX`1M|j;3kPI1Y!y3=9kq zjYf$?BB-j0%jIHaWrhC!{=W>$0Wd#5k6{=@A`!e^FQ#eI+uQq$aVQj`xw)A_p@3ys zw70kaZPtpEQcg`xkxr-adc8;~$>nmiwY61c@J~fCO;ZXXkWyk6$DEopBSV$a0%2I8DWb!L^*SFyF9Rpi0 z9(NaecDqR>uh#@*GT+k_2oh|14{S$h)Ze0|$w@BvZEb>8<4bgZBd`k;4N$4Cb75w_ zK^O*w%a^MFS@Q-#y%m%Y*j@nq1a%Mj>?jlpD3g=b1dUCnd9o4(@g0;WKt@?erqJr& zrF8y0rE}+yxm*R{^&Md;^$_F?ly8H4#Ij-F^7LXG9>zI12tsTU`2Ah1nkC{3pCPO- zc(Ob}d__f5d$2}FX)G48hK4EtpRb2SV~N$(>mbHRXC{d)D|pnmaa_AbAeX~FHnvFs z@baNaOz{ps+>epWpWwhtwZMB+f~r2)xWl4YB;DD`i;IgWKuT3fpE-l=)TydFUoKln2~r5`hY!;p zkD~yKUN1{$&tmoTtYz@D6t7;zZx|@+`#`aX7#gao?OHbL@S8WOOQkCI4cRQN3m1U( zx9H$2KY`^!N{NEx;=-rsXoOl_6=%XUDNj#h>+a_0@fevul#1@+qmL=zAm6arY%-C+ zcK7ZYfye0~|Lg0O2;S!bp8a>2n%-L}n`299%vC3)XjjGAhx~|h-wY$4Yt>JM)44|Q zZzV$j)wT=j>ek9A1V{-&)INjfDgQZv1HfNj#&%!^fQ<>N>0(<@wwT4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + Aiob + Bloo + + + + + + + + + + diff --git a/mseide-msegui/icons/forms/rect6550.png b/mseide-msegui/icons/forms/rect6550.png new file mode 100644 index 0000000000000000000000000000000000000000..dcc6aa387a860fd48f1d80dffe47ae3d4d6681fe GIT binary patch literal 222 zcmeAS@N?(olHy`uVBq!ia0vp^oIuRV!3HF!2OrA@QY^(zo*^7SP{WbZ0a8%l5n0T@ z!2AM)8MjskffPxWxJHx&=ckpFCl;kLl$V$5W#(lUCnpx9>g5-u&wghk1ymI6>Eal| zF|+sFLf!)kA`BN7|6vjN$tWV7aC2_xg$f?2%X$}<*#12-)AIRQccu%~>MaiEW=6fX zj>_Kn{n?zu63l`Jqr9_wgSf;SRxMh!WJ99$ LS3j3^P6U zTl3GTdEP0UKmV)R*->@VFpQmxLFD2y_f3&iTH{S($M(vbhGDe-?*Jqjl-eaB%LjN4 z$hA30t)>Q9i+GSK8cBEXquqDAF)m22RI{sj&c-mX>D-@@J{0c3WkR# z*|)cYyY~iA6q!{O<>-1Db8{(FRY6haT^w*meTX~lmrJgtwWZ-5B>@Fre(^a-3dfG_ zS!7J1yu6feFaHfZ%;h-`ws9OsNOI^;KnnmCvUJ*_q+|t_Wg$r_M~-}kWB-FtlbFdF zN=r;|XTkIL3s+XDc@-=a{PdacsH=|xGF!LC7#$tsIQ#Ws-o7gEGT_bnWpQ8T_RR7W z03?$pSFhd1va+Pp8M0X$)68I+7TK&rI-SMyf_G*?3SPXJ8t z7~8gOA(5CN9^XVHvIe{i)zu%+y}Rw-Cg-sL;QJqb=lYKap}@8 z?A+CcZQF&2eq(_i=z56e=6ZzC5JG)Z<5=@Lrly`26+Ewk1N%D*_+%~vaN%Nq(b?q> hw>r0cliv4l%WL`DCxKvdoC^Q|002ovPDHLkV1f-%sYw6; literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/forms/source.svg b/mseide-msegui/icons/forms/source.svg new file mode 100644 index 0000000..c7c2900 --- /dev/null +++ b/mseide-msegui/icons/forms/source.svg @@ -0,0 +1,466 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + Abcd ecoe dgrgeeidkl + + diff --git a/mseide-msegui/icons/forms/stack.png b/mseide-msegui/icons/forms/stack.png new file mode 100644 index 0000000000000000000000000000000000000000..fde8360a48875aabd798804d4388ae9a2e6dab25 GIT binary patch literal 884 zcmV-)1B?8LP)=>JXkiyJeR5xmHnp~;0XJen4bIz~-KXYbc?RHy9 zDN#xxrR3-TL2LgvUgIa5NT+#k8-2Tw$!76fx9fYJN4;K0*L6llMrbq|#N%Y*_>rdL0C0JE$;rtHi;Ig$DG9?6r4+vJlh5bLX0x21 zpJSRPxm*q@WfWjMnT&v#Lf|wSWHK3w#UeroVzC%=b8|Er4TKP+QYmI;W*8eABcIRr zl_=J3x0UhX17Q%5Or^RTO~>imwBzGrR#sNHy}iY@ZB|!TQA$y()eu53K0e+P-&Z2f zb>R)w|LpYi6vuIBHk$-NK(pCIDTQs@Y;SKz;v)bp&jY3U76&L43i!T{uIps8S!%T! zQc4yU7Dyx#kskC&^e5(^uS7j^y*Z{q5MbLj>2#X;`FRqFL^sy_@&)tj*REeZI~&g6 z@bIwbn7+Qg5{4m~rlDyXo12?`8GK$|rh0ZZoWa{;>ia&qTn^v&nVg&)mOdQ7vMfra z(!d@JGHu}QJJ{a`xVpOH;NXBtrP8JU_N$aaDaHN${ZN2N4_wzpDMhE#VRv_zt*tHg z_xD*_TO$Ypc6N5y+uI`u0;Z>@DVNJV`Ae3?w~LD?Kr)r$!S|V%n830u48y>29P0Ht z>+9>}ayc~Z2Vq^;F${xDCeu^ASSm#r#D3>R3&Rjy*HKFG&!EZ0000< KMNUMnLSTaUMUl+_ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/forms/stack.svg b/mseide-msegui/icons/forms/stack.svg new file mode 100644 index 0000000..b266226 --- /dev/null +++ b/mseide-msegui/icons/forms/stack.svg @@ -0,0 +1,461 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + asrs fsf fdfwfasda + Psas aiasaaad + + + diff --git a/mseide-msegui/icons/forms/thread.png b/mseide-msegui/icons/forms/thread.png new file mode 100644 index 0000000000000000000000000000000000000000..2632dd24fc16cae6a0231d553be2c48294998e21 GIT binary patch literal 700 zcmV;t0z>_YP)U)<&glTN}W+ z%PO%&2WQ6pEX=!q3t($DMX#Paxqe9|*jHw1I!9Me`KPC-DL@E;p$qQc^e}hF%l?T1 zW0QI8QuWUPKF3l?JGW-qc^7wb;&hhnyR=^ebY!klkVh#=;f5C$=H1NB_z6S|j-SfV z*=-<%z-z_`INq?RAFx<7-!R@%6uZzHine2SiHkRq^bHzZxv&uc37wvGAHg?VmtPN% zhp-6)Zz;;2?hOF!3-kgo8rlTF*p@Jdrj~j6#05Zin}XCn0P>JEz;p!x33v5906mpQ z00hKi07CYs07RV60O3Y)%<> i_(*FN{Qr~xI^YvNJ#ol6Z%2gy0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/forms/watches.png b/mseide-msegui/icons/forms/watches.png new file mode 100644 index 0000000000000000000000000000000000000000..d7dc623ca2dd4cdf673da13e3e670b9123447d4c GIT binary patch literal 826 zcmV-A1I7G_P)+1K zVH|e{dnJRhd-wZ%f6w#%Jo_V!g%4FCWpCnp2VNNzM5 zUx-?CadB}Yo6UAg1>|x$6~i!cA?G-*l_bgAQZX|A!t3=u+S}W+DwWFb0B|)sI~%v# z?M%5`?(ld#E|z8GEX&GGCez1AB=QabV0n4j9F0bwAP7>c)oKcl$3sp{O%)nBuPZ1P zi^_OBevcrCmn2EPve|4O*4Nh`006A6u3EKP?dNnl9ZscEp+cdc+1=f}!*N{e=H@2q z_xoeXWHO55_lDR;!)-HeR;~MbUEP{>-@jup7{2kj=$Yp8c~xIu-zS|;cPZ3pn!bgiXi3N^ifV6bYpaipj4(n? zRKe)zXvJo;y%ll*fM76~R45cbgF@9VB4yz7`BG}NTGTp=#qxDwVd0HTCKJsyk%3O9yOiob z0Km}D(3uohsZ>8O45Os9=8tQD-&3zy1}*>p$$#D87mpeQ!A3}ol>h($07*qoM6N<$ Ef|0U!761SM literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/forms/watches.svg b/mseide-msegui/icons/forms/watches.svg new file mode 100644 index 0000000..48bb5d8 --- /dev/null +++ b/mseide-msegui/icons/forms/watches.svg @@ -0,0 +1,426 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + ??? + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/forms/watchpoints.png b/mseide-msegui/icons/forms/watchpoints.png new file mode 100644 index 0000000000000000000000000000000000000000..75890b11ac3a38791cc7c3b410e58f9ffdd2c72a GIT binary patch literal 873 zcmV-v1D5=WP)Q&AMhf3NQqh-nEe2!@X|tv1oxG!O;|i!Fvh z2VrR9!eqk4!a(9ijP5295?35#Y+^wCAc`@;X!z8`(18H;gQSwwBDBTU-s|AwqrCEp zgM%lzxhLn`^Z(y-?mPEBC6!7^Ap}xNgb*Co&1@%KZ{Z({R%$^akzjaun8n3K*4Ear zSS+~RZv1{feSLj691hcX#jHdV6B7&!46wDeRW#Ucw=*;}M0a=hu_Zc|AR3L*)zw8h zou;v&f!jB3(5Y$Uh2T{_&#lo>K7aXwrfH0gjS&b0{*E9V4l_MHjjgPV_kbsxE!h2L zSs8v!<6An7&*vi&iJbh9cXxMrGcyA~e>Q6X2RNP0axn)fesUbclulloVt6L?d@#?iIE_eqhe&l z1on@-1@7tk6`*r|p4Ts4AcQa{P?wice*QEC{{UPCQa}qZ3|RAdGPAR+uC5kjVIa_! zmQ2Ctfe`Q=@BmMMO5Nw$+$0u@6%dr{p-ht|pmGnwKbl;R3R}+yI^j9_jiJ2cPJkE&;q}=WT+Xhgfk26Qse|0z*Z*E3W6kIM> zi3|XxyqwH~2PEq2_iZ5{qYvj1@cW?(Cw9A?U@(ZqQV41K9ta^wCX-A}PV(~ML&g^tkihk}Htaqhc^%B_^%4vQ zvDs{f=hL(g6h)!3vXbs_n3Y(J+}s=hKWb|5HZ@UOTZ_x(!sGEAWPao>D%og?qM)iO zfk1%v_I9L{^!E1B+S-bgavyMS*M|82{;%RUJV6tP<5AqP00000NkvXXu0mjf$%~6f literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/forms/watchppoints.svg b/mseide-msegui/icons/forms/watchppoints.svg new file mode 100644 index 0000000..5087d82 --- /dev/null +++ b/mseide-msegui/icons/forms/watchppoints.svg @@ -0,0 +1,447 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + ? + + diff --git a/mseide-msegui/icons/frames/demo/0.png b/mseide-msegui/icons/frames/demo/0.png new file mode 100644 index 0000000000000000000000000000000000000000..e3dd0c416693872ae9efcfd99c2e9d1b0e9f23fe GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^%plCc1|-8Yw(bW~oCO|{#S9GG!XV7ZFl&wkP>{XE z)7O>#E+;>ypeWlVZ6=_Qk*AAe2*-6sb%q=N8G(G(s;Mh}tv+;{ff2~~fBVHRhU_3~ n1_sse=KuT8-TD9T-@pGsb|R;}t6!c2s%G$X^>bP0l+XkKC*&(! literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/0.xcf b/mseide-msegui/icons/frames/demo/0.xcf new file mode 100644 index 0000000000000000000000000000000000000000..87c5f6c6121958f16a1f0bb842471b8382f6eef5 GIT binary patch literal 804 zcmb7BO-{l<6rL7E1b=G$S(!K+5?Iv01zd0h6T`ZccAQXJ(n10xCMLar8!q6ATj&Y& z0(uS>CdKdJj9{z_zvS!t=FR)s_g;nU5BS*ixi15c0R=_UN1$QgaSWDP4~!9k6L3rM zOhu|YMg2LVCGc8X_8sBbB9>jG814;LONNuc<4F|AZoORdg&PG?%xkM)$D-r##${uL z9MM!)byzz&R(;R^7GxbK1ILx2;7$E4Bqw=Em9s~o9C8`Dw_Za2$oCU(_}w76f2Y1O zKdrO}1tZl8adYXFmgDwB9F4-&+DuheM5L83!IILn@?E777_FXa2xU;~iqcfSx1skp zY7U|4y&5|Z+OL1N?gdxo6?hM!TSqjnaVDso*`dRNO{>$J=jv0oV6*n@?zQ~_HBaY{ z@9A5%u4dMHaNc*49-03;^#MH8HBD-P)Cr&m&;uc5e&C^-M|pu3Kv22D1s$^OWpVil DKTUTT literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/1.png b/mseide-msegui/icons/frames/demo/1.png new file mode 100644 index 0000000000000000000000000000000000000000..bf89036f980e8d8f024d46624b9d3c5bc9b60e73 GIT binary patch literal 121 zcmeAS@N?(olHy`uVBq!ia0vp^%plCc1SD^IDZKzvoCO|{#S9GG!XV7ZFl&wkP>{XE z)7O>#E+;>yqT&yQmo7jd2~QWt5RU7~2^%zj{{DXc{{H$I5(x|knHc5;u`LXlcEl8@ OhQZU-&t;ucLK6VUryk${ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/1.xcf b/mseide-msegui/icons/frames/demo/1.xcf new file mode 100644 index 0000000000000000000000000000000000000000..f8c6b01feb97af3041aad0aba9230648f073f7da GIT binary patch literal 643 zcmZ`$%TB{E5Oe~9(t-f-IC1bXJp{FP#G#+iKSkZ!t$)zp}hB)ycehWkq9(TZK@yQqgaSxmVH2ml}%{^fL3H3(d*i^4G zRivucD@Y9eh$Xh!mj$<`)T`+@kxH1-)I4z|tyP}!+4IcB0Ga#N6xMve8v6WyLe`z# zWI|Vp&%?JM?uSILrQ1q3Tvy_)u;e#V+M@ZrAi4iaKgzL{_TVG>2n@Bq^vNO<@2WQ2 z%B?N-V`r$e@-JZIIj#J{a}-9arx}Vd5cs6WFMIr|$FITZ+z{s=!5@BixC>hGs~-$k cM~#=qTAb7Sfpwir)*W8D&LwEmwk}!w4Vh(d5C8xG literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/10.png b/mseide-msegui/icons/frames/demo/10.png new file mode 100644 index 0000000000000000000000000000000000000000..6ef0d142d4a0cfca4da115286e83d14204d0945d GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^%plCc1|-8Yw(bW~oCO|{#S9GG!XV7ZFl&wkP>{XE z)7O>#E+;>y1h=mIS`DC(k*AAe2*-6sb%q=N8O40-{ud{t0fiYDm;$Vn80IZl$Z+Js nT?WQCFK@6;+;HjFihVa382AJvjw>z}2dVOO^>bP0l+XkKUBD!+ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/10.xcf b/mseide-msegui/icons/frames/demo/10.xcf new file mode 100644 index 0000000000000000000000000000000000000000..e4675b2e539f972c6635dded6984919e78dd3003 GIT binary patch literal 806 zcmb7BJx{_=6n$+)5&XcYOeVg?2ty700S9w1yi=L@AJEhI2tOo%aTu5QjI{0RSr zKY+!=ox#Lz+)fG*6tZ20tet4 zxDFPTrn*DaA0ZY5UTe#?BRpHgvWXPKy}?RJcMy0yi2~Uy=SseCqaccTX&&rYG#p+z ztIV-NRMk}(*2W5}zUO}nvi6gXV@;QnW~IdO)F2qtkSgdO{EbSt)6NKIZ*4o(p0~- zq_>x9cA@FL8XFMWuYb4h1y|-dcmttZM>H>RCa9d*pu?;<9{Z>Dx8cdGKAGIrhp!Kp zv+L>f@%H)UX|$+jg~i~!?IbNS|99#gc&KZdv;a~kfF3{(gp~P?hia6{Em{CU<*Z{m KWYUjJ%F<6F@pt?H literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/11.png b/mseide-msegui/icons/frames/demo/11.png new file mode 100644 index 0000000000000000000000000000000000000000..2921c401bfeff6d5c7a89c6a8ce0bbae304d2d65 GIT binary patch literal 127 zcmeAS@N?(olHy`uVBq!ia0vp^%plCc1SD^IDZKzvoCO|{#S9GG!XV7ZFl&wkP>{XE z)7O>#E+;=Hqx9+(A|XH_IZqeI5RU7~Z(@G8G=jm?gQ0pH-4hQkV>!gckdVwW!R|wB Q3Q#43r>mdKI;Vst0B5-%XaE2J literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/11.xcf b/mseide-msegui/icons/frames/demo/11.xcf new file mode 100644 index 0000000000000000000000000000000000000000..cdd07a3522bac8ee27a83a8256e5979fff190353 GIT binary patch literal 628 zcmZ`$K~BRk5OfvJ{fd}hLAd2v~0tWMUAsDDJa0u}5jn_PPjrm*fg~73j zU8Y7Qrm_oI0{uwDb+av$tX*LjlVPk)?h04QxTT~rSt_S@)3$oV%(o_pW5)1m=~00|T#l;ztbC867)eYbWfl3Ma>Th;9dy; literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/12.png b/mseide-msegui/icons/frames/demo/12.png new file mode 100644 index 0000000000000000000000000000000000000000..d80c28281df98a6a6515afc6fed4df98b04aba41 GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^%plCc1|-8Yw(bW~oCO|{#S9GG!XV7ZFl&wkP>{XE z)7O>#E+;>yxPf#}#9^S2k*AAe2*-6sb%q=N89UcL`41Fh=v^?2f#tzfE{1)lr!$1u nsW32z`PTi<=~?ps%a>QI22KKJdn;#WgH(FD`njxgN@xNA@2V%O literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/12.xcf b/mseide-msegui/icons/frames/demo/12.xcf new file mode 100644 index 0000000000000000000000000000000000000000..f17f2b3a62558fac41431f168d7eb988a4f71cdb GIT binary patch literal 803 zcmb7BJx>Bb5Zygg5d6TXR3>gG6ldTMSkTk>502w*UAYf(2MIL9Xe^8t{sv>~zp}Eh zqPbY$8{CyMV&O~P&D+^|cQbQRg#$5mec`LXV?aTZ^d87L9{XUa{m2**H~`nc4X~y) z)g7Y#2(c>hT3dyV^lX`^9#RbVoYm9eB=AHU2ddX7*L~^6L7a&CBG`%SI-+^nTwsN0 z>8l2;-4#}IFa8!}9j61wRgn}e^DQJNtCBirk0Lb`DsnHpl>D*pr{3_pL3002ePw=H zX%8Cw#wf)6(kpGp?aL${MT@mrx{Ov$E1!cUt!d?(S|c!8J=GA(pwShrseUV`w{tbS z(DYt|B82gq-)(xqm30PQL73JNt#h0SI%jq1!0)n}I=QR`Gyalwt~>XghZ%p(rth~; z)91HkHLETM7on5($^74`ci^F}Y0@f4od9M4GZ0eN2Og$*lox0L1f44!)1f$L>z`>u Bb1VP= literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/13.png b/mseide-msegui/icons/frames/demo/13.png new file mode 100644 index 0000000000000000000000000000000000000000..43516d0b55e9f7418c431fcad1b684d41dd7f4f0 GIT binary patch literal 120 zcmeAS@N?(olHy`uVBq!ia0vp^%plCc1SD^IDZKzvoCO|{#S9GG!XV7ZFl&wkP>{XE z)7O>#E+;=HqXE0fTM?j;xTlL_2*>s0H!;6k8XFhxsb>;q=23`Xh&{l(&CGk=RG<KL85rM#?rUP1>_3ZvF^=#ZPe3H@ItP zq?38f!e)qfGUC{F0 g?4Y|ks<%4Uyola;)v~Ih{XE z)7O>#E+;>yxY)_YyLLb!15X#n5RU7~0-x9Zo_}xSga6&?(<3C$+y4J=Z?v{o@rZM4 nW8wL!`Tr#)BqWSxS4%RqZ5KSXr^GJxM@8F&n^6iM%ZhJnW}n62G0Mg;c2 z47dswm8QCV)E^)g1YT>)wj(@S#IlJL!@a>uNp}!)UtG?%d3$pf;j^oNu@T&e6l7nSQm9u-H>~a~p7hXdC$oCVk``sY9 zf2Y1OKdrO}1!Jfc;^NZtHOFmJ7wVA4nR!u8U!K~7>@^z&V7_FXa2su#eywX&^ zv7k2>YPO;2y&7u}+OL1N?gdxoDR>Q`TSqj{a3-jn*`UL;DBhlqFGr)JY5n%)wSGSy zpHHtIp3|Gh$z(XMW`+6SyzL|{GXHn#EqJJFnzR5?Cx9M64}_HYj)!WL$}L&|LFKGN MIvDB4N}5SO0fQfT=>Px# literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/15.png b/mseide-msegui/icons/frames/demo/15.png new file mode 100644 index 0000000000000000000000000000000000000000..3f2062ba460bd6b7e2c87e46ec9ee13a63b52151 GIT binary patch literal 127 zcmeAS@N?(olHy`uVBq!ia0vp^%plCc1SD^IDZKzvoCO|{#S9GG!XV7ZFl&wkP>{XE z)7O>#E+;=Hlh{8KYb~IVoTrOp2*>s0lnt7R31DFJ{f~Xi(NFK*mUD13L^-k9E?NJ> Q3#gL8)78&qol`;+06=;m5dZ)H literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/15.xcf b/mseide-msegui/icons/frames/demo/15.xcf new file mode 100644 index 0000000000000000000000000000000000000000..df7b36cd1f555fb7bb1242d24145352997dcb266 GIT binary patch literal 628 zcmZ`$OHRWu6m%X4N(%zSXT`$HbP?3<5sMz7H%L<3Sfp{4q*A-)0vw1lu;LEffNhx< zY?O-dq{&R?y>YA;W0xzr$+gtBPy%(}!TJ)2B0R2u!R%EC2I?9(1bFz?Yo5Eo{2lnh z;Ml}2Q=<}7*##_tek9_$*%nIHuCR;oFxDn_g{x%TQc{^Lm6Q8PTRmdxTVq7Co@nUH z{{=@k^(xJ6Y2-9~3+A@Z^j@+qZ6j@&KdGAYPU~7VzZc~6U+c%&kMbUTMK3{tyGtL< z()`&}Ze6x(BR_To=9TY&f!Dn96R$ynSI;wCLm=o;N1t}|Sx28k^SPmpAwoX{XE z)7O>#E+;>ym;uxD%qF0afv1aO2*>s0x^Ewtw0EyMd|!OeFWxh6R`J!Jzf*B+!oy{U n4s7{#A-7G#I+e|vSCfsw<|6Oci`9YcK)no}u6{1-oD!Mqs? zn#$hBU!X7%&&3(Rh=nIPd(YgtXZPN_LWXVLbA9g1z+-@=NcsRY3_K3OZ0(LQB5(w5 zfEn;aX{tL${V8HW;I+049pTv`kxir+?hRH-JN>}pX&lIAIal(98wYX1ON(G9qT%q$ zd1Zk$qN=XSur}6M^*#SvkhPb#9alzzSM|4$?5|6zoZXFNhs(&l_EPf4zMp!X?*_^J zJN1?MX{9|V7(=ZPSC^izIc`fNaW`75%~WNyYFham%qmSQ-&Pud(dwy&kOQ^OD^2w~ zD|&aOW*?f~tFZ;4{rY$7UT|ezfHx4jbwu+DXM)O^4LZ!;2F1bUxOo3EdmYtB;iUdB zolPgh$?fCt>3Lbr3d_NH=%g(&|99#=c&KZdv;a~kfF3{(gp~P?hi)F_7A=6Fa@H9g JJ~ro>`6v8~cnJUi literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/17.png b/mseide-msegui/icons/frames/demo/17.png new file mode 100644 index 0000000000000000000000000000000000000000..8963e6fda4c883132a0ecb0056af7a6878c7e20a GIT binary patch literal 121 zcmeAS@N?(olHy`uVBq!ia0vp^%plCc1SD^IDZKzvoCO|{#S9GG!XV7ZFl&wkP>{XE z)7O>#E+;=Hldix0B|e~#gr|#R2*>s0gbkWIOCSGfuD(7~B7xx`6GPWR*3;Dzg^z%0 O7(8A5T-G@yGywpBTpeiu literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/17.xcf b/mseide-msegui/icons/frames/demo/17.xcf new file mode 100644 index 0000000000000000000000000000000000000000..4ff30b32acad31303b001219f189f407d24d3990 GIT binary patch literal 640 zcmZ`$K~BRk5Oe~9(t-d{IC1bXJp{FP#Gy~%2Z`$#i!`p{RBF$BfS+*$aX|bcN0?1) zl&WF1lby`&IMzn#<%(}a#xtEuhB$B_ehCBt9#_C%{>m5uF$N9+8oqIy=B_b+i+Z7O zY^;}wlCdiF0un<%V3Do1x#ZU5dNCPBnGz;9C6AgCmnu#8^lsWj51F~v1lF|2>ihhE zLe`C4B|;a9&-}L_Zu>;1#p^;>To>X=TJoDLv$FcTAi4LYR@t@E9$W-3o}qS^KAI=u zS(Rp8G;0gp*byqN{0A5~PAflg9EH*9X@+75cs}az(+)rD@N;lF*T*r4_xs=N?}AqN e;0FEGQNzbwEllaXW}n|}*7qM@ZPwM>dz-&OlWmIt literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/18.png b/mseide-msegui/icons/frames/demo/18.png new file mode 100644 index 0000000000000000000000000000000000000000..8dfc10ef3b1606dcc2d957664e1b7ab1c94fd1b1 GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^%plCc1|-8Yw(bW~oCO|{#S9GG!XV7ZFl&wkP>{XE z)7O>#E+;>y7>Cx>i!wkVBTpB{5RU7N>I^sjGl==t{oix+`2T0m?)_&9uu@`}xZxth qncHs}7~j0S!8&onrC%%d-DFt5RZL~odVO}FZU#?RKbLh*2~7aWJS>#} literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/18.xcf b/mseide-msegui/icons/frames/demo/18.xcf new file mode 100644 index 0000000000000000000000000000000000000000..ac8c1495a858e26c623db1fdb01ed30db3164f76 GIT binary patch literal 806 zcmb7BJx{_=6n!nC2!3ExCKKOc0z(b_0S9w5LL&lgHdT1a5fm@v3H>gMd|?BZY? z`~yyoBqr_*Cf0NDJ;8{BCpo?6-FHuW@2!yS4)41@_hsNQAfrfn12hagHo;u|f-xen z1ulS#U`c7J+eZBkVo~6=mTcR?vqUVLNHN?StekWQfya|5kj+ZI>|fS^z=i NGP`uhrXSgqrJs1adCmX; literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/19.png b/mseide-msegui/icons/frames/demo/19.png new file mode 100644 index 0000000000000000000000000000000000000000..f6bd55a067ed8bb0f8e55cf9404dc0ef2d14d26f GIT binary patch literal 127 zcmeAS@N?(olHy`uVBq!ia0vp^%plCc1SD^IDZKzvoCO|{#S9GG!XV7ZFl&wkP>{XE z)7O>#E+;=HGuLOmFcqMXoTrOp2*>s0ny;S>nZbaYo!z|U=!t}2rbI@D;1cEz)d|_Y PK$Q%hu6{1-oD!M$eix0AMd#MHOOh-N*}(3k%U zj&9s4%}u4{G<*x@w$JolvaU=cO_e_sj`LP2S2VvDvK1t9keb61f&^tBX9?oB# literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/2.png b/mseide-msegui/icons/frames/demo/2.png new file mode 100644 index 0000000000000000000000000000000000000000..10edecafee2548200673034b917e237978603d38 GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^%plCc1|-8Yw(bW~oCO|{#S9GG!XV7ZFl&wkP>{XE z)7O>#E+;>ylsLD>I^sjGl==t{ojB5)c;5Kul;9CYhUpH$*a!{ qk+zBqjBj4vV4b+((ytZ!ZZe!~5IeQ~)%1Bl-3*?telF{r5}E)G?k^tz literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/2.xcf b/mseide-msegui/icons/frames/demo/2.xcf new file mode 100644 index 0000000000000000000000000000000000000000..2692d8c5f6adc2ad2349c0e7fd98ba16840ba05e GIT binary patch literal 806 zcmb7BJxjw-6n#mp*4B@T+DY&&LOVp-Kj6?&aB*=?)8zSRn$)C)c2I;4T?HpM!Og+R z-BIudh@0RhxOWhY=hpXZ#X5N4v-IgzRQ4=BIy;-Fz{FfGu1Q3 zh`<^+1I~g4rKxTm^&5zJf!A8HX$#j9k*p)daBr|;-0t}X_(->I+6Pb=*~!RTv+IJxv()pi;p3Om7QZKf)tRny87FrzfBd|qh;Mysb9LKf6I zr!>_sOz6dlnq_Euuf`mN_UqrRd%=~t1D-LqxnYnn6{XE z)7O>#E+;>yC<_PQxi3H=BTpB{5RU7N>I^sjGoHG9>;JFcKNy1Q*Dx>vB^kO`o@5BI nQ(<5b^R4@z)3fCNmoKka(@zV&6nE&n22$YZ>gTe~DWM4fKN2Z6 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/20.xcf b/mseide-msegui/icons/frames/demo/20.xcf new file mode 100644 index 0000000000000000000000000000000000000000..543cee5f87dc1ae5ea699acf9130c27c19849e1a GIT binary patch literal 803 zcmb7BJx{_=6n!l!2!7P4OeVe&h8p+-4(!Cle^5&Md{SD{mIwsI8{>b+eFa2(i+`m&_ znV(kLgMx9V72@jB3pK}Wi8$(pi?x}mj8;u6pMyE2Y318WBQRP$)e!Qa)&-@herHAR zuGH*9(|a|t5ZbSQx9$a3<~eu^p<72ZFL5TQoY|nmZ1hqbU0fG~>1_O3AK%>9htt{Q zZ7_L!8a%%*tC_VNoVT5%Mdtrby$26{XE z)7O>#E+;=Hv)s!sO_4w$aZeY=5RU7~HQ&D2F*7%Z{0LEFlW^F;kf^}Cjm2BZ9jJuC M)78&qol`;+08}0t#{d8T literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/21.xcf b/mseide-msegui/icons/frames/demo/21.xcf new file mode 100644 index 0000000000000000000000000000000000000000..c187908239704e888111e1d96d32eb0e9156bcef GIT binary patch literal 640 zcmZ`$!A^rf5Zy(iwbiJxdh)PGdcd@IKLE_R;2&~=f8eBVaM#dC zC-a!cn|aG-Pp5}${yAl*C3dQ_o-o*e}*wzfzXu#_F;xr-a z-fY8IXG$#Gw;&#dM5_h6OqW7u@q1#(pG#?y^6!G={xAJ1$5z^d4gTpEYJcgIWf*^` zBHv}*+B`dUfl4d?21b_C%C9U(VYGUhp%?>>PkQ{i$8UQ47M#v?aS7u5?svPppyj>U fL3edjZ*{DB5xw)KWlclL>-M#-DS6eFRYmy&A_i-u literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/22.png b/mseide-msegui/icons/frames/demo/22.png new file mode 100644 index 0000000000000000000000000000000000000000..7af40f4ef02ba8322408050bf8abf97d0144320b GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^%plCc1|-8Yw(bW~oCO|{#S9GG!XV7ZFl&wkP>{XE z)7O>#E+;>yh=Q(|bP7<&$kW9!gyTA+I>U|s3}U`@|I<4b{D1M}5-a1z?c4v)*m;}5 pNL8GHNlQVTA;DFfVb!5q47u9{TrND-5d!LF@O1TaS?83{1OU|ECLaI* literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/22.xcf b/mseide-msegui/icons/frames/demo/22.xcf new file mode 100644 index 0000000000000000000000000000000000000000..84eecadbdb98f8637732d7d83c6cc07ffd09ad03 GIT binary patch literal 806 zcmb7BJx{_=6n$+`5&XcYOeVg?1cn;;0}gBsE-uccw9gkxOIk=ECdP!t(U`cqGCCM0 z|AK>ygR6u8fWgFiF1{xiaquLk_q_Y=Y45!iveo82*XOJG2$S0FCl;A`-#{2 zZjju+Q(u{%R@#GtG0+NecIo+=<2FScb;HTpOjSm!rj@5)R%u%KveF2QR!=pA9H@0( zX{ukD(W^5x>(KOGjU@=}*S}l$f-Ca?ynxWHBbvuJ6I9Nu(_vf`Z+C}hFT=g@(dFx? zee-;OGCse38eI<`9|qHER+tXXTTap>^M9vagNM4NNedu#0_XwsKuDSIc&J9H+@b{# PRL{XE z)7O>#E+;=H3;Usad*XmXa-J@ZAsp9}Q#NQOCV;`7if0NfM-QDn%$~@|U@yvS)w6L9 Q&?E*1Pgg&ebxsLQ09|DtzyJUM literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/23.xcf b/mseide-msegui/icons/frames/demo/23.xcf new file mode 100644 index 0000000000000000000000000000000000000000..daa42512508974164a5b06854ec9baa5a1995f4c GIT binary patch literal 628 zcmZ`$%TB{E5OfvJ$wG?~flj$>`KS+3+JS5ld>5U4#5*5^PJ;c)>BX3s(}P?x|yz{A&G^V}8YZ@_07 z$0lZ(>LSs#S-=wLM@>Jd}l8Y7zZL_=Tx zFF3k!t28&2mecSpnA<+nd&#;ojWkvMP&m$8rCibcUXas&tsiGM%6sq?Jp~2sE`2mh z^G99Vb=9to{MZ4QSN;VIyylf3c?}Z0dY<7L0zr>D`naP{I{Flv&kc155%S@8hr6If d_kJ*39Zd6Gk1~EILGScQcl1gh)X)pPeFG7)UiSb1 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/24.png b/mseide-msegui/icons/frames/demo/24.png new file mode 100644 index 0000000000000000000000000000000000000000..cd186f3e750056676bb19e00333d0e4b32915e66 GIT binary patch literal 145 zcmeAS@N?(olHy`uVBq!ia0vp^%plCc1|-8Yw(bW~oCO|{#S9GG!XV7ZFl&wkP>{XE z)7O>#E+;>yu&&Irk8(gE15X#n5RU7~brqjkUWaSG-Y?J6D?MYsSLFYz6B3eUOniUh nz?ScKlG|LY<=F0ppO$3s72p?McUlOjm4U(2)z4*}Q$iB}QT-_K literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/24.xcf b/mseide-msegui/icons/frames/demo/24.xcf new file mode 100644 index 0000000000000000000000000000000000000000..6f95972b1d08ef7ef950f1577c2704ed9c8905ce GIT binary patch literal 804 zcmb7B%TB^T6rC1D1Roe5D-$QIU{M1<;DS#u{6HzwaYAWH3kmEDChSc70*D{rf4F96 z;>MjTU9!-K=i-cD#Dyn0y=U&+)82b4RjbW=p3i+12nM7yN$-J{g~vXasopR~1P;J8 zFby7QO?8K;KSs<;yw*`IR|-eQs(}>4y~T=2rymHOM1g9QvPEBdQ4qzvI1f%N>n<;! zmgiU@D*CDfYkh^)-1EN$S$j#_^;9T%#e56N{;H(TIo(ioxC*@sk&r*~{X}%W8zlGd z)K})GmG+=vT^WVAy!2ev^_nt{y5W3nwl1Sp)5>RHMr&I6rq&3IR!=pAENFC2YpUN` z(%VZlyU_GrgAEAdH^1BTf-CzByo4~VBiiRU6Lik5(_#7~3gY^;@bW%=7}kcP=i1|B zdOseFZzqGh{-T=Y7lZSbn>5M%->G-tp{{AtJV>1YW&kq~QuZ4jrg@a7XaNMBOP$c+ JV||vMeFDn~c_jb< literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/25.png b/mseide-msegui/icons/frames/demo/25.png new file mode 100644 index 0000000000000000000000000000000000000000..c41386c083a821c79b1044a7be64328eb3cef8ef GIT binary patch literal 121 zcmeAS@N?(olHy`uVBq!ia0vp^%plCc1SD^IDZKzvoCO|{#S9GG!XV7ZFl&wkP>{XE z)7O>#E+;=Hi$*4YBRfz?!qdeugyVX0$_CA!+auoIfBxHt$DkpBk)f`O)i=6@-yNui N!PC{xWt~$(698oC91{Ql literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/25.xcf b/mseide-msegui/icons/frames/demo/25.xcf new file mode 100644 index 0000000000000000000000000000000000000000..a36e191e2755b244815397940eab20e9d4c3b70b GIT binary patch literal 640 zcmZ`$OHRWu5Oo5A(t-f-S+VdkT?Dmz#G*&&4HDNj7HM21sno2w0BerL1vo}F2zZm& zC>3EeFZ1$do?}h4S#S7GD6UK<8REc!_$3eocw7Oa#Vcb3#5HgT(D1F}G(X2q_nV^EqK(HxX@|BXZN!<2FTpCrm&_1R^R9U z6SD5gO(IOL`P_dCVm%}}E#Bs);wBeQvLwG%s+8651Xdye?ZHLx;u&gx>61kw zo^@fjdAqjIjUA!V%D;h;R fk8aRk9W`9;Yhg<74g31+vU&J;@3N`h>Mnl(OTTP` literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/26.png b/mseide-msegui/icons/frames/demo/26.png new file mode 100644 index 0000000000000000000000000000000000000000..17c32613dc63be01c65424b357fabc99e0c0ec3d GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^%plCc1|-8Yw(bW~oCO|{#S9GG!XV7ZFl&wkP>{XE z)7O>#E+;>ykV)dSjQKzzBTpB{5RU7N>I^sjGm7}s{=c1hhJo|%a|R|SeHn(S7d05( qKE1%e_~zve*1AQfe(gBPc|%)E*-3AMntd;7P=LnkMVoG^t4oEh31D7cbt#t3N^T zzxW3{2!h87g7Hnc3v_w5whLkeaGXT^j!vI6iF|EhJnX2n5$niMg&UW z6gUm8Dou4Os9!@Y3cS{mZCkjOh-4EfhI@mRt|@p2lhNHlC- z-K?gVAZqHW0&8P}Rp0Z!1zG!X$97~Ocuju`$-$(g%2~ZYcDW3k12-mr=y|c*{ce!l zzf)hCpH|v~f^n`D;`q`Fb=zr)DC`C4+DuhOtEQDFU`}aT`K;0ij8;!IggmHqL20U= z8`JY+HH*;nUX2+D?bp9s_kt^P3p|C;ts|PdI1^OPY|vp?dVSl!czQY9816jWA79=) zU+oP~wyU>C?D6hwRLzQ`!Fk(`TV($4)C=%X*EDGnq)q@mfF1}b^BoV}Jjye)0D{V8 N*6ENGYcdGyZ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/27.png b/mseide-msegui/icons/frames/demo/27.png new file mode 100644 index 0000000000000000000000000000000000000000..e38a5e5521a7d860824f7241cafcf1a66ca22a80 GIT binary patch literal 127 zcmeAS@N?(olHy`uVBq!ia0vp^%plCc1SD^IDZKzvoCO|{#S9GG!XV7ZFl&wkP>{XE z)7O>#E+;=HE34`0H^x9AIZqeI5RU7~e>UE1Xas|&ZzppLh$%Pwa<;HCWS(U;p1!I1 Q98e{Lr>mdKI;Vst0Bp}7S^xk5 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/27.xcf b/mseide-msegui/icons/frames/demo/27.xcf new file mode 100644 index 0000000000000000000000000000000000000000..3bba2ad3753ea003160a35442b0b10743b038077 GIT binary patch literal 628 zcmZ{hO-{ow5QUuqL1{sN_*t>=GF=3vd&Htg=nWD#F&1fD#i`V;xd1y3!kM@OJ9rap zl!`FY%Y2!c=U5YMR%^Lcr7TTV2*iOG^Cc8Tcw9lF`Ku5t#5HsX@$ju@p1Z;P9rA_7 zv58q_x=3_mmM97IBN4lHR~6FP$}FejxYWv4wvlm{l1As5Oz+b!24Ln}Q&{r>Yv{}W zfvsD&&XlROoP}?pxEm_^TC%B4D^0DQ3deq1mab@jFUan{rJu^amG|HydI^NwU;1R8 zsb}5TP2H`H{MZpPulx%ddFGX$ct#SudY<7JLxCqfKJD>YkI%t;Zir(*@Q2?W?t&IQ b`oVB@WLoUkDCc+jqz@AGPH*%;DX9Gh6Et0I literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/28.png b/mseide-msegui/icons/frames/demo/28.png new file mode 100644 index 0000000000000000000000000000000000000000..1a426b202f99429c17b222e233b518496ccb413e GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^%plCc1|-8Yw(bW~oCO|{#S9GG!XV7ZFl&wkP>{XE z)7O>#E+;>yl(vfd`y`-{k*AAe2*-6sb%q=N8Gmdt`2UqzoI!oM83W_f=?wqpz0GI1 p{ZEg9LByx_e`3r0|37|wU=0lunqT#Ll>ksTgQu&X%Q~loCIC7oDU|>K literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/28.xcf b/mseide-msegui/icons/frames/demo/28.xcf new file mode 100644 index 0000000000000000000000000000000000000000..b33ecdb96f209a670cbee17e5ddcd6ca45f3f49e GIT binary patch literal 803 zcmb7BO;5r=5Zx9P1V1oVPbTgW4mITuc;MoNlRv_oI(?p!!4 z9mOvFdyNw;<~%?Yo|g1aIhXAvw-Vs+>KHT?%5I2`zX}VrlB=Im>t<6+rv}#)U5-cfAE8kTbfzj%zhEN8zt|(3QdmDOx zqvjBr-m6iB(0={9buYLwFTpzq-8!OqjWa>z%r+ge#hdjyy|LUy_WaU%nBBK#i_E#2 zu=sKE^uDfU)%D=K=cZjU|99#Gc&KZdv{XE z)7O>#E+;=Ht4igfKe<35aZeY=5RU7~e>NVS(b(9z`0%_=Mm7N*2KN-EZS!`RmjIP8 Nc)I$ztaD0e0sxV_9dQ5v literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/29.xcf b/mseide-msegui/icons/frames/demo/29.xcf new file mode 100644 index 0000000000000000000000000000000000000000..7d56dd7a7e492e987db722945e27a4c7d617486d GIT binary patch literal 640 zcmZ`$%TB{E5VQk=(t-f-IC1bXJp{Ev+)xkw1pXj#V`GuVRgy~WnIGU|@^7Rkm`!bz zim=+rPG)x;YopC_B{otCWwMkZjvR_m0!t9p)cUuQZO0 z%re$#qzkiv#L(v~EURsniqd9gF&>6WOPkq3gl&lmoy21DIBBDYOkHaXYtm!&eepjb z>!w`A(&So9{kI@)`$VTj>)cero$#0b^)9UwvD47I!T(L9## zy0GiKU0dMBPEcv(-@w3eTKSpdD2!H5GZaI>^HGPNclbqzUxL%QK2AZr-~VoZ7qo(z g8}wI44PFnmAfb2O>{!!K@_P4D*OXsR&(%JE01q=~;{X5v literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/3.png b/mseide-msegui/icons/frames/demo/3.png new file mode 100644 index 0000000000000000000000000000000000000000..fc3c696126f24e7c11f87d23e90fb2f42b4011f2 GIT binary patch literal 127 zcmeAS@N?(olHy`uVBq!ia0vp^%plCc1SD^IDZKzvoCO|{#S9GG!XV7ZFl&wkP>{XE z)7O>#E+;>SrHt~#aBHBDoTrOp2*>s0nu_;Y%wTZ(y1%@FjvL!-Ar5YaMn*Ozq3Rb# PK$Q%hu6{1-oD!MZN-9$p0=4JC`W%QNJT8F2>{$o~>Jr!oc=+0Dp1Z>Q4fsss z*u*STT_n0T3s?gENW`w$mW6b-G>h>tRywz(t!3O&QtK?0liNvKJ!0xxV??u_Xz0uT z1xGh-mFA|>avHt`bK7TnFIiWnk*3NY3deb?lq;Iw3v&9e_2cYDc@Ms#r=Y;yrH^K5 z{-|rauG+PcA3Ff^%D;et*Szv0uR(%W&of*@Am~v?A9wUgN1sCTxuFgrLO%TNa2K@b c-VcVWgK56&QO57|N$(`+gI?*5-spvzZyGLN6#xJL literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/30.png b/mseide-msegui/icons/frames/demo/30.png new file mode 100644 index 0000000000000000000000000000000000000000..8924e031459183a59f1bb930534d72e83882f460 GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^%plCc1|-8Yw(bW~oCO|{#S9GG!XV7ZFl&wkP>{XE z)7O>#E+;>y5QBr#94(-bk*AAe2*-6sb%q=N8AW_*|2rGVF!UrFvoZd7d-?y=jprC{ pJpa$Y#PW0*L!uoI!`}0c7#y+$PU_w``W~p8!PC{xWt~$(69CR=C%FIs literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/30.xcf b/mseide-msegui/icons/frames/demo/30.xcf new file mode 100644 index 0000000000000000000000000000000000000000..6cebc4f0202468e41fc873a15739039030f0818a GIT binary patch literal 806 zcmb7BJxc>Y5Z${Z8WTSvMk~R^Dk)BqKVXsCN(Af6{*4jo;Jl`a{CSojn@OIwL&bynP6|&XlJ;&po^j!v|6iF|GhJj@T%+@X#BLYP* z4bFmVN>kk`>emqq0-v>H%NDLBBH2KS;oM-QxYPGt9*4eclyfCdIH4a#yfh3}B}1zCG>+je9icvb%k$^NvY%30k&cDM|j12-mr=y|c*`EHQh zzf+^kPb%B42su#eywX%Z zKcN>UYL=ksyBhSg+OMBm_ktsH8$5>4ts|Pd*b`LFtkY&t+<$&McRyY?2RnyPFIQ*x zk9&io%e#l0>;CP@xSAEl7w0WIZj$-Gw_b#Yx~7{JKk$h&7bn*qO?0N?P literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/31.png b/mseide-msegui/icons/frames/demo/31.png new file mode 100644 index 0000000000000000000000000000000000000000..8fc4a7d37931af8682f2180065dfd1593adb89c2 GIT binary patch literal 127 zcmeAS@N?(olHy`uVBq!ia0vp^%plCc1SD^IDZKzvoCO|{#S9GG!XV7ZFl&wkP>{XE z)7O>#E+;=HtNCALm+r{P;Lw|%Dfl67etY0Lac)tq-)*Q)uwAgBLYKhA!X_uwmf2@2d@`e>Hs z&!%$gvRxbbu_G|Ad{XE z)7O>#E+;>yq*+eRg$kgMk*AAe2*-6sb%q=N8E;=d`~UW{4-5$t4l=M@d+?HB`u1B4 qA$BSZ3}U`@|8shl{QvUh73<1sk*)2IKAr^XX7F_Nb6Mw<&;$VS;VrHJ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/4.xcf b/mseide-msegui/icons/frames/demo/4.xcf new file mode 100644 index 0000000000000000000000000000000000000000..98f9936a460e5d43a6d3aba129438b1ac944c26b GIT binary patch literal 803 zcmb7By-vbV6uxa$5d6WYOeWqDh8lPQ2PPL5-=Hn+^-5_;3kfX5#8C&H!T16$IPnP1 z4!(giNe2h~4&EymaqvsNp6{M}zV@6`Av;|@@B$vl&}V?9NcsRY3_K3Od}GWQ5jX-j zz%8(>G}RrW{sgfk@LF4T9O2s{ku9Vc?hRH+d&AJ@X&lN{wNMF!7l(1eD~n(!!gYA< zthT@!QCC-0Slu;Neb4_EWF4ek$CHuZb^R?QhwG9mXZIu7<1+HD{FMB05Tt(ZyFqgQ zPJLy5T4@go#;sO}t4l979Iq{sxF0RnW~wq;HLZLO=9Q+EZ!3+!X!TS>D1cfQm8SZg z6}`Jsvky)0)yP3;zy9627hIX=;0=Us9nrkRnV@o}ONZ=jQhvI)E{C)1b=rK6?wa?r z>}5Kdj2}ji@5^ddS`N-TPTD5(f2ZDqhq|UoOCWUu=mGRVNSPma=;l#w(E{XE z)7O>#E+;>SrHPoz|ARmw2~QWt5RU7~HJ@Hwn}2`5$RlwB!vhRWtPHESvu(>+xJ3-8 OhQZU-&t;ucLK6VEeI9iH literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/5.xcf b/mseide-msegui/icons/frames/demo/5.xcf new file mode 100644 index 0000000000000000000000000000000000000000..41da66a7151df290f9153ce07baa47079649613e GIT binary patch literal 640 zcmZ`$K~BRk5Oe~9(t-d{IC1bXJp{FP#Gy~%2Z`$#i!`p{RBF$BfX8t{LPCf?pvpWaQI=pi%Ln!uX&Sbd-W zPsqBlt3>ER@tOY?#BHDGw0K?Uit9o=NlSi{WmZ;y7bN$-)GE7H+JlSW#WU3I(ns?| zJgd^Ii)L-18#_X!mHz+($7$s!j-xPIJ{XE z)7O>#E+;>ygjLPKwL(B4BTpB{5RU7N>I^sjGl==t{ZH>$@c+e=ORS7n@4xupFmD%w qnglxo!@qxj|L;F{`@d><^Z!K!Vj4RKK&p{{At0!W{XE z)7O>#E+;=HgZkV%k&}QzvYsxEAsp9}YYLvLFoS_|voGhAumAtob8s_cU1T$ph?a5y PDrE3<^>bP0l+XkK&{P}l literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/7.xcf b/mseide-msegui/icons/frames/demo/7.xcf new file mode 100644 index 0000000000000000000000000000000000000000..3da65d0aa04578c8d75673bb121c58d90ee08111 GIT binary patch literal 628 zcmZ`$OHRWu5OoFwr3C@vvtr?8x(I6bh((Xk8zgRQEYhTkQ>k5Z0j|XzSa6f@CfFzy zVWj7Ic{9%*O^jV{nA)x&3DhGIyJlbH(p80BO~&|UbWlJOH;Vp>!A<=8ewzQ43rFzL7`zx(o-uw>8?!VHHa%kl}_=w&DL+&qqvPjjd zsjF?-t&M!!2{Ny|1xB9p%FjGU61;lu;TQvfPkQ{k$1i&P5}fZ1aS9Ur;dh5wP@-qw Z7)D2?<)KCyf72HUYUz`naDGrj?Kc_iUzh*@ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/8.png b/mseide-msegui/icons/frames/demo/8.png new file mode 100644 index 0000000000000000000000000000000000000000..b4867e79c56ee46ff94f07e8bb06f77788b93d6b GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^%plCc1|-8Yw(bW~oCO|{#S9GG!XV7ZFl&wkP>{XE z)7O>#E+;>yq{vR5iF1HLMxHK?Asp8k)fsO5XMXnZ0xP?!!`~OY`VGt=#@Zcs8CFcK jW?)baZ~njM$~Q0$KPMtx=CX7$P&b38tDnm{r-UW|U~4M+ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/8.xcf b/mseide-msegui/icons/frames/demo/8.xcf new file mode 100644 index 0000000000000000000000000000000000000000..8ee78ea9c00c59ca20f6999272457a699b4b6880 GIT binary patch literal 807 zcmb7BJ8r^25M7&u5Xgsos}!q9C{Q?p3#6b=lZM(Dd$YpW$OZ{$QF?mBS zOm!Eizd|kwTx-dWEnG`PvIU9Z++gLnH}qW|hrVo8@?}prp&v%Pyh&Chnl`WARyVPQ z)YMT0*5($gKIeZEvJT>|?Z`mzn*J8V;WkleRzHwEE(7P$jmaN+UhMY18YK5`=~MY> zr9G%H#+o6gmtLsbPFqA_KiI6zRApIYT6qHG6sMK%D~`ly^;AQV2Q)7zPW1;VeweB` z2B&*{XE z)7O>#E+;=HBV*X9w|YP!2~QWt5RU7~2^%zTmi~Ob?)3c`5(x|knHV}2v+g>&WafOJ O8U{~SKbLh*2~7aK*B@E{ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/demo/9.xcf b/mseide-msegui/icons/frames/demo/9.xcf new file mode 100644 index 0000000000000000000000000000000000000000..589e1ac564948ed05b073c81442fccb3c6a18d58 GIT binary patch literal 642 zcmZ`$OHRWu5Oo5A(t-f-S+VdkT?Dmz#G*&&4HDNe7HLw&sno8y0O!dyau%RFc;nhA z6=5_l^YUh%V@;G^uJ}e|Jkz;kh$9E$*FX^9aRUry?~D-;x4rm)w-OUW|uPrbL;S6_0F*E0rdE@;I^4L#D1ZhBfW6`ab`k zkac5LiO_}OQ~xc9+dk20@w(78*M)eIhWurg8Cm~cklcTzy>e)!J-7(oJVWg+eKbqN ztE$R%Vb>PAu@h8U`8P0doK}A3I0~cH(+tHB@O;$a=N*30;g{fau8&g?@Atpk-vzDk h*$w)uqlWWCEllZs$C}0_Yj#gEK^~dKve*p0nZCU^T literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/frames.png b/mseide-msegui/icons/frames/frames.png new file mode 100644 index 0000000000000000000000000000000000000000..790b81c0704d2ce637a4a830caf8f887dac4bfc4 GIT binary patch literal 1160 zcmeAS@N?(olHy`uVBq!ia0vp^DIm2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR4yZDpVi3WMyWH@$!`9X35Q_l7Mzo%VN6ih!L|MiFPjyJpBtvbHrpK*3; zh-CBuL-51jBEJ|r+(!5!FR)byn z^qpLj2kjXF?i%j({Ck`-SD(LW?lk#XxyWah8;ORUY6rGVDYD$MWvgClZ$RBWx0MU; zo|R!-|GIR(DT~TOpuZZ{M_ieB)%xH;?#$Io?)sh$?3%UkR$}4$crQ!$tw~%mi)U@@ zd=*m1uCyoEoRed|Bx|7-uPW&X$6^;$4X z+19b}`~?fPramtksIb@MioJA a^^CuIWiqPT8r*@U27{-opUXO@geCwpMex@E literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/frames.svg b/mseide-msegui/icons/frames/frames.svg new file mode 100644 index 0000000..86b81b0 --- /dev/null +++ b/mseide-msegui/icons/frames/frames.svg @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/mseide-msegui/icons/frames/frames.xcf b/mseide-msegui/icons/frames/frames.xcf new file mode 100644 index 0000000000000000000000000000000000000000..84e1289053a7175ec68380f0800812dc28cfced9 GIT binary patch literal 5422 zcmeHL&2Jl35P!S&Zu}8@-PAFNG_9LfC6%4fB=yFnG$p-&DmX-?IYosuv0aNKj=Wpb zNCqDe5=y_)9*{thLb`5Tku*WTkwds~M1lk2uK>wOTSUFg?7m5zc8yf2$^m7f$(x<` z-oE#Ko|!kZne60r^vYN|n$Aw77|=Lpl=lD&0{q(x>^bxOKO!>7VPH3K2{^)K9M=lt z_dy%Vz-zm*lcSkbS0mao{9W7!!YG%=L&dshctR6k|FvhC__yre|=742-{t35?@VM)CrajK2-ZzB<`oCpXv0fjU_M8Q&`bqYX3x z)4RwXa4skDeJ;?xVXUZa*NLCvbIoL@>i(@WQ4T~7#(G6hBsO?Hm6IdtNO5j{u{kz! zt+KjOi3}Di-!5J)9y~v{wm5U{bZmV7{`L1dTYIM#?|t%S1aY7>5v#pVVHG{pgRAZ& zTnM!jTnH~G*9|Vv)&VZpo$Wf;cldnT`dd$E#@&xjghW+0jLWKGwfb|k@FrTy8Kqua zY$s7V4C^_e6vU0#9G187of3$w+5Wn#+}Ig%JD-kQH-nc#3LXPaakA)%F>LF>b{(L0cwz{6=T+9T17 z8i9vi%Srl+3v>hkPeyM>;yM{3IGI?@B}!r~q)19FsY+_Cpi86ku=Y~6qvkPmL;$Wn*yjr<75)0g!zf~MbMC4p*crX_6h`sTHk$`NO1TE-n zItg5IC$YjaI{6#k`kXvyR!FpUFd0wMR*}y0Ha_#HBq|t>boII0P_j@qG{k_Gaz+Vl zZbwmSbk()sMr`t)mv&KwR(XYzv~bOkQ{^4%WlI{-Si@ zM4MOqX0xpBLFd{0Q=v&yX^R3~tZDz7sOXzO>v6eTQjmPCBj7Kx7TYcPr z5~EcM#4YB6(c_#E3ICHc0G@UX0bC2o$BdCTCiGt9|9too4@duRy%HIK>>=K|< ze!$C?gxan?Oz=3aunj6>@|xbJZ)$mp>;bkZP-$ZvFdk5(XU#B&YMrvN�D{DEbS` z&o?&E2)!GkLKO!)z&2caPg&VekoQp)f_);t%ayu5tW2yvo*(S?QHHdOOC1uH zo!J@Wi^T;WJm0cx@E9r;EsqIN_HX$FcpDXvNpSjVl4=6* zCm-98sH(L5v_OS|1U_69snRT$jW$ClZ&LXnLNCSzyZ(f@ut^1l0D)nX3Q`SRe^a9x zg9Ul?iT7gkd61x@BUBft9tHg#Nfh8)o**2CAO;sBD|wk&$Im`XA+z*^G2g%%*!na8 zE#+6rxzt2zOwZ<~qVJAsAL1~`Uo4_b6TcK&*WG1Hkjh literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/frames0.png b/mseide-msegui/icons/frames/frames0.png new file mode 100644 index 0000000000000000000000000000000000000000..bc8863a3aa6cc7ddcd748a0835c1f53b9f3a3e4f GIT binary patch literal 240 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqY)RhkE)4%caKYZ?lYt_f1s;*b zKpodXn9)gNb_Gz7y~NYkmHjTW9EY4H?$jZc6EQ~Qw-sLCbQ1&grb?xkAzc(D|&Cc|2V?^c>hD0bF9kuDjr0)tat0Q dlyduHkb9$FJZ#rf8IVI5JYD@<);T3K0RUR{Q+faZ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/frames1.png b/mseide-msegui/icons/frames/frames1.png new file mode 100644 index 0000000000000000000000000000000000000000..7a966de42cf1bcec0e41bf70197d04371d953114 GIT binary patch literal 177 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqY)RhkE)4%caKYZ?lYt_f1s;*b zKpodXn9)gNb_Gz7y~NYkmHjTW9EZHBY8_5 P&?E*=S3j3^P6X~Lcz{pU&*D)}bfdUj#o|Le+B%Ah`;wbo zGjji*mT)VQJtlSe#&$_&5sCIfA)Dh?zkR#?AIRQON-a^eDLgJJZjupny)?+H_Uw!G ctDJtaPI8ixTFP$n6zC2HPgg&ebxsLQ0GUitt^fc4 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/frames3.png b/mseide-msegui/icons/frames/frames3.png new file mode 100644 index 0000000000000000000000000000000000000000..4571f5c9121faba301eb9b312cd1da73a3000bb3 GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqY)RhkE)4%caKYZ?lYt_f1s;*b zKpodXn9)gNb_Gz7y~NYkmHjTW9H*3qeDt(tppdPni(`ny<<_%`LI)HCSPt&vnpVHy zQPSu7liduHPc(-r@5*8pUzWo9l|||p-yZdXdRyZO|NbvfHWH{POJLmJ#J+FS&spby P1~GWL`njxgN@xNA-x)T! literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/frames4.png b/mseide-msegui/icons/frames/frames4.png new file mode 100644 index 0000000000000000000000000000000000000000..e7b36617c6b83b8b600484fca68ab5d5d1aa0aad GIT binary patch literal 242 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqY)RhkE)4%caKYZ?lYt_f1s;*b zKpodXn9)gNb_Gz7y~NYkmHjTW9ES?0u<7^dK%sh17sn8Z%ckcy3LPvEIPy^cD}9TqWOv+*!nzRbq+%z6QfI1aPR{t`JS zq^&b?@j>3)t{X}ZWb|VK7kgfuX~0==P*QZ4NbUIzopr05V2YmH+?% literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/frames5.png b/mseide-msegui/icons/frames/frames5.png new file mode 100644 index 0000000000000000000000000000000000000000..6b7c9df3b441e7d783f4bba74675d0aea26a3a0d GIT binary patch literal 163 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqY)RhkE)4%caKYZ?lYt_f1s;*b zKpodXn9)gNb_Gz7y~NYkmHjTW9EY;l#hRR@Kp_K97sn8Z%U4e=WMmK!VYv9bytu>6 zU=Od)7uH>GE^&totjLgf;m2)k^D9f^dLeJ;9l2>NUN&!cy94zyc)I$ztaD0e0st`3 BFdhH^ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/frames/frames6.png b/mseide-msegui/icons/frames/frames6.png new file mode 100644 index 0000000000000000000000000000000000000000..78a32134aaf2f504e99127aa8513abcb92485fd3 GIT binary patch literal 251 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqY)RhkE)4%caKYZ?lYt_f1s;*b zKpodXn9)gNb_Gz7y~NYkmHjTW94C(oS80AdP^iPx#W6(UvhF$WET%w_mWS_)tdq3& zvE6KcWb*rd3$r7~ij2jc8)}!XXZCmW?V7*JD`LUX{2yKEnoFCx;w_Tf^WS`&9JFhC z&@L|T7^aBiR^C}tF0DPpkbLHlbIPB^CudY=cX0mN@vvpTjAM74$<-Z;4{9ENEhaxB qsYSidBE=?Y{ju~vFPLuZW8nIvv*p*i)eb;6F?hQAxvXTn^uFA(ZZrBLId$S5R)^}BxV-l zCO3f)RO6~uigL=CtZB#LN)8#=T|qG%u|H6b^Hy?L*N&SPvU z9`u9DJ)HYHALrhCG^G^(BOM@@%X$AYnWpDdDqcF9&CV*Nwt4khFmk0GG~FGU2-)TwM{>JX6_oREi;y59I0UuDUx?CNZ!ZHo6U7rMC;?^UEhbI7d{A7-WVu=S2 z-!NZXsg(&I@ac1z1JOP7ojStu${GN@Cy&zFx*vdi{vGEBlMJ5gB>&=z-=PoC^$_75 z767)jxp#CN@{OjcV_7=3t>e{=k`LIox0zCDnbp-FxSreaknwmMuU;>bpZiGr;hl{D zfJ+z7FnNEP8>2&hE}c#RFmN`>hs83Hh)wtL7XN(PH^w>-5{tEMj_{WH`%{2}Wf=@z zOhI)Cs^vz&_?`KNw*RhXKhl&^NGSy{_WP9r$o&Px#+8@%&sKZ@0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + 010 + + diff --git a/mseide-msegui/icons/menus/breakpoints.png b/mseide-msegui/icons/menus/breakpoints.png new file mode 100644 index 0000000000000000000000000000000000000000..2a5168a5c4ec31178b34499b5835152999d9465b GIT binary patch literal 467 zcmV;^0WAKBP)UqK~y-6rIS5t!cY{3UyDghVnR{t&{|0m>{c&CM<*Q$6}q|$ z{v0PK!L@&(wV(*jfh!JfMGU%06eM3n>{6kaLe+mg|HN z#V1%2!g2e3G7LWCR+f1Qs0MCuX?8%?C%C87aUzk`IoQ~2Y!mPTH?V>3!gcL1Sf9<@ z-g-R&Fb@<6n%0?G*0*k&t`F9A_e;}$+NL=MFg(lyAJU*$Y~@+De#`SbqEQ&0XZN<- zN!xM806r!;e*v61cWUsi%Q*l5002ov JPDHLkV1i^;yvqOp literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/menus/breakpoints.svg b/mseide-msegui/icons/menus/breakpoints.svg new file mode 100644 index 0000000..4a1fc38 --- /dev/null +++ b/mseide-msegui/icons/menus/breakpoints.svg @@ -0,0 +1,426 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/menus/componentstore.png b/mseide-msegui/icons/menus/componentstore.png new file mode 100644 index 0000000000000000000000000000000000000000..cb6890c034180683a18350faa0627eb7fde33d6b GIT binary patch literal 429 zcmV;e0aE^nP)*-)3hot*9u0lmQzHNh&MJ@3FMHHccwa zh=0K@q!b}yBZLsQ6#_}QL46& zz(8yH=lb&EW({CG!Dj#TU>JYlL2~{$so4ndy*W5x6~d4ckY@3;6OKdkmu{M7Afnrk z4L0dMAB}*vZC|1&x>8EnWLZ{M)$zWu`-?c|uSt@mN~t?3<-h>!0XUipSn5ei`2YZK XI4EKm1uVcD00000NkvXXu0mjfUV^H! literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/menus/componentstore.svg b/mseide-msegui/icons/menus/componentstore.svg new file mode 100644 index 0000000..219d04b --- /dev/null +++ b/mseide-msegui/icons/menus/componentstore.svg @@ -0,0 +1,536 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/menus/console.png b/mseide-msegui/icons/menus/console.png new file mode 100644 index 0000000000000000000000000000000000000000..1956b41f9b21c57a92233a72677cd5c534dea78b GIT binary patch literal 381 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf4nJ zFuwp{#;w&s*+4L zZQ!f*uR}1!Xr|f0ueWBG->W_usj-yDxY$N+BjYBW*{2W8vi)h zl*_#>)TUTD&zR@%`g?2!#};f|wn}T;ZQVkd$Gh}u?@w0YeExZ6q0G)0y(O7l?|)~k zUCur4y!!RmQx89M5MY_(r~d7??dq#pw^DBFO!w9~eQ1W~+}5B|dp&rxMmJ0m(tNuAFMG!qJ+lS@CH8&K81^yt YGWtvkc(7&;FccU(UHx3vIVCg!0HCaws{jB1 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/menus/console.svg b/mseide-msegui/icons/menus/console.svg new file mode 100644 index 0000000..565b79b --- /dev/null +++ b/mseide-msegui/icons/menus/console.svg @@ -0,0 +1,407 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + ~> + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/menus/cpu.png b/mseide-msegui/icons/menus/cpu.png new file mode 100644 index 0000000000000000000000000000000000000000..c99e62cfa76a6bffcc4561d389f11ae8c851c864 GIT binary patch literal 434 zcmV;j0ZsmiP)2ykxB%grG<-+N7A_xMm*DJT% zjV#Luf`I4q2|${rbh}-`FeHj1s;a61=kuAtU;seB-=`=FY};nD*~m&oQ7{}10WeLI z`~6-6bX}(`O8|rrsH%#lX&+wO?Y68cgpj%dFdB_G9*+PV4hJmD`ZX-aame$W*XzaO z@j%!08lY(!oGq0{NSMMa_4>q%=u2wd02bzKQ=tyZh5=^72gc;A6x7>xh` ct^fZ_KX{vOU88=pUH||907*qoM6N<$f_~1nGXMYp literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/menus/cpu.svg b/mseide-msegui/icons/menus/cpu.svg new file mode 100644 index 0000000..21cb124 --- /dev/null +++ b/mseide-msegui/icons/menus/cpu.svg @@ -0,0 +1,407 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + 010 + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/menus/debugger.png b/mseide-msegui/icons/menus/debugger.png new file mode 100644 index 0000000000000000000000000000000000000000..d9c1ca712dac18afe63099257816e15d31346365 GIT binary patch literal 486 zcmV@P)}BX9x{w> z%tdBgT#%JZ1^__Yt8X<;Ogr?d!7DDv_DBW*K;5QcX3b0Hv98I${G;6{832G5xe|+( zCCPe3a1EZliR;lz5{jRH=H$XD%NRUj3O@tM + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/menus/findresults.png b/mseide-msegui/icons/menus/findresults.png new file mode 100644 index 0000000000000000000000000000000000000000..c87cf71a6899152b875ecc30a6ceea42757e47d6 GIT binary patch literal 809 zcmV+^1J?YBP)YFn)HM_}FnzNcZb?5BgOIt2| ziGGhi_k{zZY(|`yi#{B*UmG2vm?2xtCJqvDIqr-3<22Q6liQ~8? zLf8{|=3+xehLI==5S;&p$*IxRg@wQiO6h64-5%Q1K%>#NrlkqT%1SGBNd^wG3@9?d zZ^=bYwnaPQd3n@3Hqkiq5x3^P!z!L_v7mIOK>zj`Ey~c1}YU{0hkhxz^LB`gMoNBssOKDuW;tnMeu3H zI3TnbKq#~n-0%t!W$o$Y)Y#5+ew!u+$uk$n)nha5_eOlau}J_k2?pVC_}1Lq*ZI$1 zd~t(NXc5cHOY!jRoDbiFpOhTNqf6q{?*Nd5k2EkaU;!n4f{@SUZ?~#-+7tjlc;zQP zd>o7f=BKEwBw4c>7=>rp`Q}E;$nj_0{WD~J7aAHG1e>kAGdCx5)v2j)u#X|tBf*@4Lvb;4A2!sL5@G06+vq^t* z$8H=*&la%<*jF12w{0ksBuNy2OBBVy_4}UQL3*XWy80}o-9;8^<+H@7ce+O=|5|6q nwK{{P$aHULA`-pd)$jQQNuU?|dix_800000NkvXXu0mjfQ!8mk literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/menus/findresults.svg b/mseide-msegui/icons/menus/findresults.svg new file mode 100644 index 0000000..88bf419 --- /dev/null +++ b/mseide-msegui/icons/menus/findresults.svg @@ -0,0 +1,456 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + ? + + diff --git a/mseide-msegui/icons/menus/memory.png b/mseide-msegui/icons/menus/memory.png new file mode 100644 index 0000000000000000000000000000000000000000..60d5524bcbe248468cb1c611cd6ac55175f65060 GIT binary patch literal 717 zcmV;;0y6!HP)yen1vrFd!sQKoLWt8-neG#14u-Iv}9HRMclX($#a%ecu~1 z3?t%=+1lD70kFEd3V;v-RaJ2u2jBORBnerT@jMS91cgF@TrP*>IQ08{fct{|{e808 zEUKy!1Oe@K8-U5lN!sl;LI`Zzrcfy0`#x7!S42_tR4_L;M>?HmFc^?dr^)B@42MGi zN~IE|Qt8n!l}fR&u<+a<3_}Kk!Q&wSS(cyiLtb(MV0wCb6o#QJgkW)T@pr4$O5Wby z%D(S^tW+vLo6Tm*ahyb_)7jK@ef#9(B%4eo17I@_aCv!2v)Kfo-|tI@hle>uQ9^)P ztu}FXcJ{u}XuJa`7K_6m2x6}5CjK@EJkOKw?(Qg;%iVIh+y&U(-DPEErE_s{k+CdG zwrv}LwY9bO!xLhLVMLmy{loU3vazvoZ=kBGt0+oF2!XEa+c!5i^7Zw#V%zqom%OyJ z^sCqFC2ZT4fz1R!tJPw5b{2qxgM;yUy*?I(A@lR|uh=xrv7@7-iK(e6uUf6%8%UD$ z_?;`2ilu2<&$29~(P+G4UDs_*(|X-*SN?x9n3$=kE>1lRvZ?Cwsvjc` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + a + 12 + 68 + 15 + c + j + o + 91 + 62 + 11 + 00 + 00 + 00 + 61 + 11 + 14 + + + + + + + diff --git a/mseide-msegui/icons/menus/messages.png b/mseide-msegui/icons/menus/messages.png new file mode 100644 index 0000000000000000000000000000000000000000..88b3f7a554720e7c46e2b4b7282a307fc0de6d02 GIT binary patch literal 405 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf4nJ zFuwp{#;w&s*+4}$X-kR$hA;F^;TQ`j}9M}jQ^I$!xTFGXfOblmchZ<1Dm z;w0T^HXMz*DT(C?2@=o#&ycLs^}Vdlt$cdZX(i>~cCQ+wZ>hqV$16nNypVfeIbU3JKit;$a)FHd)2yw(Y!bKMPK*?D6e!q#f1?h!A`8R1*FwiP3biJ7Jg>a} w!NhmI_uP!z-|P)8y|=iy?Jajf9Mcb`m}sBld+n5W0fUgi)78&qol`;+0K?^-0{{R3 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/menus/messages.svg b/mseide-msegui/icons/menus/messages.svg new file mode 100644 index 0000000..be36d47 --- /dev/null +++ b/mseide-msegui/icons/menus/messages.svg @@ -0,0 +1,407 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + ME + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/menus/objectinspector.png b/mseide-msegui/icons/menus/objectinspector.png new file mode 100644 index 0000000000000000000000000000000000000000..413cb0a1b92efc9a329023af9082c1abb68b0b94 GIT binary patch literal 542 zcmV+(0^$9MP)ugK~y-6rI9^In^72rpL@R>M5v$^3Mxr#@MmbtcNJPh6hU!w ztzy>>3JMMmB5k)04jBvLSg1&$gR2M?RQv&vo8V8Wv=$961x0N|!QAU$5;A-?!5%o= z;cy=A`@X^$L%#e-yGR@?If|6b6{D|v{peT{@%++{^d0LKC~yVt z+cWI?=aYlhSVd%IqVNwycpUKryiSm(@-Zzwbo6=j1UeAE6YV0(3Kmrr6m>& zaEFVyZAgCwy8>E)<$^O1Z38mD&Lw8e?t&wKx~#Ou5-9W%B`6 zDK{YH+kyZf?v$F(FK4~&dB1=f^{*QPBsMm>wblbbeL&n(5Rlo^)LogpD=1d~4Nw5H gCLy%e@%sR70GU_5wKNqh?EnA(07*qoM6N<$f`?(=5dZ)H literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/menus/objectinspector.svg b/mseide-msegui/icons/menus/objectinspector.svg new file mode 100644 index 0000000..23c1843 --- /dev/null +++ b/mseide-msegui/icons/menus/objectinspector.svg @@ -0,0 +1,396 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/menus/palette.png b/mseide-msegui/icons/menus/palette.png new file mode 100644 index 0000000000000000000000000000000000000000..3215e16a2839b8ebd0faec844d48341ac6866e83 GIT binary patch literal 733 zcmV<30wVp1P)7Yw zG*U_&4hMli0K+htn3!N_Xoz$=O*|ea5D1`Y8rf`?{{H^M20FmX$_lkw4a>5~<#L2V zp??LsPAC+jSS%uhz;3rUO(^pDyvpbE$3_nZga7^ip+KorQsr_AUH2h`8_Tj#N;Snw zWffibqm*`x>Fd89V-w4m)hZ6pL(a6^YwD2Me1_AOVy{xe>5bqpZZvTz)lV*6jL;pt zOS$k4097aeV4CZA99vxOh;X$lOu01Hc(u;~q)n5+c@Q3;+~5NPDAU9=Q@9Kdh)$pd z)Gh$^!9mz<+~r=mPO + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + Aiob + Blo + + + + + + + + + diff --git a/mseide-msegui/icons/menus/pastedpic_11162008_154602.png b/mseide-msegui/icons/menus/pastedpic_11162008_154602.png new file mode 100644 index 0000000000000000000000000000000000000000..a598609847c75ba000918d91f1a6fce0989c5b2f GIT binary patch literal 798 zcmV+(1L6FMP)O7X)EtWrYxu$z)iT)imw!@UX_B>O~^~WU~Fux!8l8$(!s%jX`111`0VV=>-BOR$8nt3>tz@w91f>asrmW&?(Xiv!ND5q zhl{nfH2`RCZjMAEA0Hn+pN|j%05nbOy3Vq!X__xDFM&XSqNq?P)L@*qx3^16OBmzf z;o+yJr(&@f2m}Bio6Y+D{+^y5S(Y)zJkNVPp2nf}_xC3f3BTX}@bDmtVpmsJGMNMb zm&+wd5+S5qE+-O+*49>p(9qCO1BvPBX#mLQ^L>4Not>SEq7;ioRaFND25xR{78Vv{ zS)QGp_4$1DE`E$N7K_DVF;NuL>Gb90CC1q0a*3jdF&-HiNvG3=LgD1(w1m#!v!H^XJ_Z`?oL(JXf$eB zmZB)TyStWUMWazwRSm;fUtjqobp-#QFL8=H}-0^|h|+`}_O0Z6kybLa(o{$z)R3^-87E+uOUh zx3{se(Ku9|=a-k4bGe+`?LIv{<#~Q)W(ELKsno^Ag>Bmm!yF$Ue|>#5H8s^(Kic_k c_&#wIaFLcmA5EZPTRJgH5T9H;GjcIPgYC>{v@0WwEBqdi0zHm4{ z4)1x+dtOD?b^b?TfO5I)|H~AK_>O7%7fYp5Mc4HqZ+LgOdE+D~>d5uz;oGn_?ma0M zi`S);4+bG&_MvDrN`7`mfOlUA5tCBh+l34Pp1r7&NF=Zw&@>GZictS*fbW8Gg#7FU zf#ToUfh_2{?hgUl?Vqfzx3C?bRH}!y?GcNO5mrpFmq0y3e&)Oog85KLiAyPO4*{-R zE{yEpY2`WP$`UB=L5bmPcSJTjbqjbL*g>Pwre*x1{k@BpOyb%Gj%9HA)EKy%)K-%K zmqZX?YpcUXqlIldbh|y8%^!TJxA)paV1it38Z{E*XeN#4+2Br~iWIi}4RzqzK)~Xw zDlMbK%f)3(vri@+=i}-M2M<_WyP6ILIF3tLRXLH%q8S~k@75?3B(3Hr@@J1Tez*rX zqXDnqtYBImJ|Su!>P%;+n43FCJRag$Mg?~h+~%Ksw}e5!`sXJ7zJ+Z&OioVV`#wS_ zLBAYMuyA)7I7EHJ2dtgbKDAn9#I@w#Nzrv3DWw4B_a@qhyx%zW!gC_>3qAk<002ov JPDHLkV1l3p4;=si literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/menus/source.svg b/mseide-msegui/icons/menus/source.svg new file mode 100644 index 0000000..08190dc --- /dev/null +++ b/mseide-msegui/icons/menus/source.svg @@ -0,0 +1,462 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + Abcd ecoe dgrgeeidkl + + diff --git a/mseide-msegui/icons/menus/stack.png b/mseide-msegui/icons/menus/stack.png new file mode 100644 index 0000000000000000000000000000000000000000..a548f4aabfb535eb69919f3f1a14e3c7ca9758fe GIT binary patch literal 449 zcmV;y0Y3hTP)JE42%sF??RGA5S5%pCL3V{Go>1`82!hbJ67BbYG2ld|t8=5anrfg*baUHrjDv2&f7eVSoUB*0sI zK!q8smz(=-wY`XXEJ0?T;p_$SAxyny(E_WF*C2mDrgO58H?D) z4)(EzT}=}8B4&q%*nYmu{PKd*9}%%s>W6lt8hoZ=;WI8Z@$M9b?{SR#nnNQPeTA=@ r{QoVzN)x0$?nWd3Ou=i>{`&s_0j71IkP#mG00000NkvXXu0mjf+atJn literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/menus/stack.svg b/mseide-msegui/icons/menus/stack.svg new file mode 100644 index 0000000..555a077 --- /dev/null +++ b/mseide-msegui/icons/menus/stack.svg @@ -0,0 +1,431 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + asrs fsf fdfwfasda + Psas aiasaaad + + + diff --git a/mseide-msegui/icons/menus/symbols.png b/mseide-msegui/icons/menus/symbols.png new file mode 100644 index 0000000000000000000000000000000000000000..fbbd915a96a9b7536e48bbf744286a832d0a5eb7 GIT binary patch literal 889 zcmV-<1BU#GP)vv}2m~8x zKrup4M5IWygCr>E;E##o zV;F`O1VI7-i9~{o#bQ+MOe&RuqXlYkM^^ zGUBq?Y%h+Ej!IaTm3MV@^@u5D4f2faAFGNF-9_@pwJ}06`E!Fc?&d zIiXNUEtN{IZUMsKa9L$#WlF2nW=N9E4h;>lRaI3N05CW>xHCUL{}ceGrluO5PUkz4 zB(ngZ)oSBAJ39|^DxykCO1|C#n9b&Mp65%uySv*qHZ~rZ&F1s5v9b36;B-3UBuRdo zot-u8?d?4p9vFMd`?d|QXczOV!X*!cmrzt@YB%7O?>ZYcq*qs0XuvjdqrKP3im6er% zMx*&OIy!0>y`G+)k20C;%I$V@$dg8+NiYmUvn;D}I2?Ba=H})ePfkuY0Dw-XOZ)x) z;Njun{oLW=;^OZznJkMuSuB?L_V%_algUtOwff7QfSQ^betmttA(>3d0Dxf_S}vDg z9Uzkj$R7FL_ zmBC<$*=)81MNwImN_DK$>Cy^?qFLhgdawWJTlBj{h@?URB>(^9zYh2Tb95tbSubue P00000NkvXXu0mjfH9eyg literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/menus/thread.png b/mseide-msegui/icons/menus/thread.png new file mode 100644 index 0000000000000000000000000000000000000000..68038c28478d6283516412db9dea16585bf7fe03 GIT binary patch literal 569 zcmV-90>=G`P)42Q*UrQj&02YE?@%pC*^+^s2?vBqEPeucN_mGI@DSNoI@?E{I*JQ zc3Ge=0-|nR_-LF~a7=3jr~z2|2ZQrh>gbCIDhr?q14O-c!%_ezxxK~EZTe5Pw|EXf z#jK;729*WGerXPv0d1xVV9kD2xzx=n6_fqa93<^^wfpUv8g0B%S5ZnSmCI3lH4k+yIgp898 zh2p`zv?m|`$8(qF*~=2fzY~rW2E9%L;PRdKS{`LLXvp|LLHqRPrpkspQL$JyFW!C^ zopuW+lYMz)>}AQ?cr-ACj6(*!XldGEfb#XHk&HK&WE}DbSXvWA;uawh00000NkvXX Hu0mjf^LO&z literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/menus/thread.svg b/mseide-msegui/icons/menus/thread.svg new file mode 100644 index 0000000..0a770d7 --- /dev/null +++ b/mseide-msegui/icons/menus/thread.svg @@ -0,0 +1,486 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/menus/threads.svg b/mseide-msegui/icons/menus/threads.svg new file mode 100644 index 0000000..ee48c52 --- /dev/null +++ b/mseide-msegui/icons/menus/threads.svg @@ -0,0 +1,439 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + asrs fsf fdfwfasda + Psas aiasaaad + + + diff --git a/mseide-msegui/icons/menus/watches.png b/mseide-msegui/icons/menus/watches.png new file mode 100644 index 0000000000000000000000000000000000000000..35df49d505ac82d43a6c59d32fe735962373e4a2 GIT binary patch literal 438 zcmV;n0ZIOeP)d0yh(?{fp?_wR`g#aXeLP_ zUJdqrpC-U;HhZ1Hm*ToEk|ZI7AP54|G$qS2?)N*>>6F1>z+$nW)9KLb^{S!`fb;o` zVHgBKK)2f^&vQ9EQUo z08tcS+cuVE0kGTcP!xrByIpSqV7Xiph9R;n1F+q0>G%7LMk4@(5Ukg0Hk-}Q832sO zV^meGu&(Qvrdi>~ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + ??? + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/menus/watchpoints.png b/mseide-msegui/icons/menus/watchpoints.png new file mode 100644 index 0000000000000000000000000000000000000000..9629b8d22d6c4ea805e9477644af51db73030511 GIT binary patch literal 572 zcmV-C0>k}@P)@UeACPL)T3mL?S4q>SA5-JR+`ZP4xGV11}ps;i_#v>UA9Zx?A1b*`p)g?d~#`NH7|Y z-`83v!g?@Jd-MG9F=Hz$40LqxYH*Mnz8?cJVSuX2o}O|yo8^{LydN5(#c?i<;$eWV z!Ns#;5zn%iOQ-QY4}jdsNinFY29(QB&H3N}uvsc`I~wI$#cYf*lWS{BoX + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + ? + + diff --git a/mseide-msegui/icons/msegui/edelweiss.svg b/mseide-msegui/icons/msegui/edelweiss.svg new file mode 100644 index 0000000..b1d5b2b --- /dev/null +++ b/mseide-msegui/icons/msegui/edelweiss.svg @@ -0,0 +1,245 @@ + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/msegui/edelweiss2_16.png b/mseide-msegui/icons/msegui/edelweiss2_16.png new file mode 100644 index 0000000000000000000000000000000000000000..cb8f1dac7bca69762069d43173781daa88bc5727 GIT binary patch literal 1029 zcmV+g1p51lP)j;uxO@WazSwD9e?jUIK1ob zfct;<>qW^}_1V5}e*5n8>iYu`;os5kA6Rc}v=pztq3|d9|8)iU2W{o;ryYUND49#* zGKsA5t#U@B4x{_Ov#ha)K1tI1K3hi zs!;XZ3N-$1UB;CYxoA8&6Nv}h$3=!UH#o7(#4vXd>@9S$j|BtPMBjljRetwpSvC23 zHt)lZS)6XxVe+**&7H#BqfUJHMGmH1VeETvlDRh~;dx`IfFUBJyy$&LNUoEH zXE}Ky3?KnKmvs?5qeh0h2;Y7)3H^2tUMMO@``3@)@g@;tIbR^6Y39!U_DbHqUEIYB ztvdOUH!@ILslv=$7&=uK#)nE#Y)peta2=&3W}LfPj8h+IapFiOluF`l4?RkO>-*=2 zGxykg7u?Rh2lvPUVqm)FL)%d&24O`savB4755pO+$J*2wT0V8cw?z2E76&U%?`HwP zy^uQG)g8gx#~z~RmLEF|QgoR+;gj!zeJT?IjTC2EpMa@-GYYp$;dCUCjI#j420=s+ z8N79Zt)uSuznmeDKSr-LS&4|~7fXQh%0{U5tb;1w9jAG3l!%DVUvpD-#h71Y@Yel3 zBoW3Ms-)b}gK8Z6d>VCC=}0DlGnd@pj!uk@%ky~EsDOxPF*=$={{Ukj7*V!`Z%Xg5 z06^xFxxxDz4*7%1j!+zb79OzShwdme8UbvMD6Zb{g9wl-SWt@4&PmeFb7GkZ02m@# zc?|JOv5Z70us0cADoaGe+fvs=HH!fTEDM}Eu1Z|EzBoBFu4w1PGE?YBq3b__$MD8b z0mZ`k$#^Ual$3yBgF5ZfI+s^=IcQe(t?vE>+ia`iHiE126oEP)u(M#^%InE84OiBy&(bv63FRs5xp)Qu{aO)+S0OetIBKZG9en9=zZ0N3WL_4u?f4g@~Y(LMcUXGD&{`JWe|zij4FWS#Aq&wpz+8 z<_#8ZXv`uv%ixD!3@&w>Jigw;;ZLR!W#eAIB4?RSNxp-!2jaNwYO#jC_;d~^zU&Y_ zZHsZ`>O8wPt)TRN8@g_C@=yVZxX$sGB&WW0F%dP0OsjteX5$)z0gYXob2;7UW8E4j z2b)8@Uw=16t8KU(I)8>NtfWcH#d+Gg9klhh5Lp;#@6qY(QPjLXf;Y#Y<((pihE0yQ z-ehbv$_sCHFgayWxY|ZzeJ(ZI^00}9rhzdtuhG?)BzR+n4Uc-Lsvlxsm6r#LTQFiF zYPQVc_m40hIl&iA#RSIVRMiD2@j00@b&SA-#$X_Ul@JF1h?AU$!ykE5Yfl z;9y;V!gW9L(YZ{TJ_{4M1!+!=;7tRgKVVW&WO3|`VhZzJ05lvOW0gHf*Y_1{C^x9A z?BLYFf^e~n<=wcN?atuxfU8=`t^4kB>&>nM%2A-dWJh$r8p z^XI*UQqPm^N$|?sA)>QFDy4H^w*x&p1D3hdIQNxBP3;XXbxc!U=ApIy1kvRixjvGQ z;q}nm;NwhFG39IBjE$vOk!6tSRxmOek$nvlVlU~HSDQxVujzz5xqm=JM1Hy!lakGS z^45nT+4l0FOio!MB69LVSa!blyIkq)6~mJzJanIp7oW{!|86e_js$sbM=nai(a$GI z%ZA!LtN5<-7HfC>Mn;yM!U6~RD-|xgy2C-KKf%mwii$ngx!P+|>UZ;0?J$-J{(I7C zZkgnX$8s=S22)c81uG5qZcL%;3n2NtHeTB9p=whOZjX)f>S4}bu*l1^GZZp8b8#9G z@E1AQxy8xWa+7rD9h9|y+jx6UxZI=B-Iro0m|$wgL?vuwWokV0w1@uT7}b?2T=wLW yjoSa|e0xp^Oz1>oEa@DH#aZJM(w*`jo&N@<8LI(33OnNf00003$b!q3c(a8 zcD>rjkzzEYjfk{htF=j6HH{b(8>_K29!cX7>rwwGDry@n5a~fFtcxuRF53cyC9qq{ z0=xU(zVQ!2)7nll$xJfy%}ger0TJPT{!mS?>CPPaof7gp`TNy!L<9if)^|lAcFIZL zZSiZ11?@9(?NAABJ&(5riHqhhj6DCTp6NiQ#TXvT4e2`j+*);YjHKILEtbAuo+y8|BoLqPO+iNGRgL1Fc`cwI__Vh>q>baih@jpc$yj?i zzkhhadwt5QnwqUtyyFTH5mmoAOnpOcx;EvZ==B4n&HS7AEZc8oO(PwqHwOQ@Yn_0C z`HJ$q>Cb*>Nr~YZhx(RLq{K_G+CAWT;MS4?>vaz}m0@$yDs0;nMRhF`C)y7uS26(5 z7Rd>!Z?0@|+8a}~Zv?6eh=Phm=V4s#8OP453M`Fx;Nheo{L#7wuh;5PyML5B(=9o) zMREcI09E!FRiAfVT$F&3YaXntv|!A79u0NJks9X4sh>=kvBw}XOoPxM9`*0qakfK- z>RZZIWsi|Vey3QNq5pYxBr8leh?=xS2?o809nHfK9ZsA$8IRucK*1Ab_~>XIE{;6| zgI+>hv<9>Diqd8FpA;mKMaM>RDbJUNYs&Lh0RWDCGliG79z#y%0QPKeg)C3wY}YI3 z8_PiQBLYftL(%)s0?b1mVbT#e%MlSYk4+yCl<9*xMhzk(I4Ck;A9P@C`Y0aH`V-|( zc3|f_r*ZU<0bib)!6(OOVH@F~hy)=t>L3FEj`1#!hj*GSGIBCPP@El#;?e|s_+Ayh z{k;h<)_)4OA|pu4&{!RdGhd~mc%uL?=HwXfS{4yRTUdl}V_#zg8mnT_-g6W0?@C5k zumD~Xk(KuVOvO5EZWzL`A03#SmGQ;fN!YM~ffGcV004}a223Sfe0V62+Wr6H!Q?*!-tLgLm7aS-PY940Heh002ovPDHLkV1llX`Dy?F literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/msegui/edelweiss2_17bi.png b/mseide-msegui/icons/msegui/edelweiss2_17bi.png new file mode 100644 index 0000000000000000000000000000000000000000..782f7ef0c838b1faf98f8b6e3d329fa589c72a4d GIT binary patch literal 1051 zcmV+$1mydPP)9v^2;Ir7`dgj6Bg03vCO4FR>JMWGHbGDv|La3~D3 z+`0GqfYfULr~l!clXL$3=NCL4kFM)Fnx>&?8k_v<%VE+I%mhL@Mp+{+IzoD47y+IC z*US8arJE|2Xc%?M43B99^a$OT{49B7OlFagz*=hG_pz<9yc| zA9SpcnrPz1N;}SJKlf!p%jtU<{Z*m;8-Z_!qR@2Ew2j_dn|PLu94NI?y<4X4tr@xp zR_Jfbrt67iYLDE-%tDB{xd;;zYb^Q9xV%PmAxuq~is12h^pOdH4?9DwD{J(eyBA3m zIQix@+tSQTOoxzVSP3Xxp9v!9A_q#XJojW0A6;-!Ss2_nXJkz0($Fftn<~|>I?*&R zNh<5!ce(PTo4Trf1ZD@w&4{6|C7aX7QmHxXBCu-M(8RqcGCr-aw5;GrlKB0P5CzX% zV|IL)+7q9W74N5~>kwX-gT#0PmKceXZ@B2~594&}%qjfXyXo2iZ6Iol$ z+?{IVrFtjk`DH%;DwUBTc(|;B_giZio~>l7BML{7OjuPh%j?LVl?awNfoJz5uy>ag zfcHA)dErPag*!%RJl;l#1qOepc0ED;Eb zTpd$rJY~ly3%IrzX*yBF;p6#y(OZR-pb`@$QdgbA;qnBYZ=NPb7O-1X#4X7h*_j5? z(k0H+*{Q2a;o@ZnasEsO*Cqpad${$(>bbt-p-~QS^UzZpj(-?O} zm|Kjn>Q}JD7_iwR>??`Izp~2i2P6N9f;)z6@|gtzk59OjCw7a<)D1sHIno_@@;6FW VzZ~R0Wb*(3002ovPDHLkV1j4U-(vs( literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/msegui/edelweiss2_18.png b/mseide-msegui/icons/msegui/edelweiss2_18.png new file mode 100644 index 0000000000000000000000000000000000000000..18edcf32cdf0c03f89bd8f21ec0e6bbe89d15b7b GIT binary patch literal 1204 zcmV;l1WWsgP)&% zuCNuxNGx#EiseI6GAJ8LZPm;zGp0k$X^~5yiJ$^XY6OM^LL-q!!ABlW;XLklKkj~? z{wN$hy|>RlpMCb)=bzUbM1=pE$kfK!UWs*qQ+J5JDE{BQfWN{P*6UHfz(oYjkf=!+ zD+7+GZivz|Ltld+SwihmYnPi>=oa^G=EbnG@fuFWlsp1G8LdlCNbA`+FT-8#e&|1D zx5HeRV=*_icJ8`)%fohW3Klt@;oFn<*OFih(J%Ho@4TRIc|@9gEofz3#Hl*l==FZ5 z=f!tB9Wz(8l5K2)YMVxB$%b|!BFf#@Pl#$G7Squw%)7NWe&hASN!h=hAR=&+z%fUx z@ld&KBs@gNm40e9IWJFs{AOaQ>eD|YZcz?VB7$9Jbkkn~muW?5wT`wOs` zM9i7v2x#q+x=B)K^vT(vfLjJrzCcIt=$Gt3eWmJOozmoY>|N;qCMf(8XXq(*BBCw=E`8Mp|wc-pe1v{1|VTO(K4% zdH?_j4CLVv2%5x?@UnLWFZrGsui?~3(z-60F35`<1m>2@&e>Bs+sTj97zT!2Xt}Cl zco;a_@Bl_{4y2R11lhZiH~5rHipz*-Y8ybm*g4nZaxB$UXPh?SiYA%}fkrYI=S*C} zi8F#l&(U&Y0k8YJ{r>_@x~Hj1EV)%HX>JpUWH6@4devj}nXuh=SdRa*kNyCFei6$_ S7b0c=0000=c$vxsGXzPDN{p8U)J3x_26Va^FI*;J!3AL#sROstF*X^~*>%$H z*6TUP50e4%e0kmv@ALccKL7V8jE#+{s;Z(W3Rk+KDD(`(m+ zT=+ww?;JR@6+W+ZQe5HT(umByU1^8{YMrknh?>8jfmcY!j}6MtmY?&I!~v`^d}C z)AH_oUfJlNvUY%_3lk6}g}$L6?*0(VOF^3u!Dv=_syqv=M!E{>?1lF3AjeP4uwnao z0M?e-7#Z~QM2!o4XE@keO;>jay&%#0aUT1&W>fRwFh*_M>>CB91l)r%uHGPzK4c^q zl3BCagH{sw_LFitP88AIc@y`Q9p%$6o}uZTd=m5$+vuV+KV8$@hYkqu>_ z8TQ7IH50hL$tTmHo7=+L=Xxl)^AsnJl<@Z@ffV~?N=tvCzGa-MigZ4!%_SIC*xNkH zNw*&{(Wt@i(^0W~kiAW#Oa)~&?H**n?PF14KSKip1SWUj4@^^8{XJPuCwmWgS@pDs z!Uy_jIW)tq`EiIw10-AZv>lh(ymg%09_html5pgv@xsm@@y=UDYSt(^dziZ2P8#3N zrG94)f(Aza1glxXpjQx6tqPeb5}G&>dz#9dTQVqFX2zBz@%6quUfPtw`YrDhHQmLQ zw}zOUky(%x&*8cPHm*+~DN)5?iJ>tYRTgAR+)|{as@%rvl0;TN@8N@2od6u~nnW@y zeDu1L{fB(4diET78G5W%iJS}_?Y~{dWRPcbv}_S1B}Z|2g50yYpO~zY>4>Ag#mlkI z2@2-xIdH^B)q@UFlj3ODAEM#Q5T5=Bl`F4FcDhaBu~I9O0WBTfDuwxa*43P+`VB8j z3lm65iKDqS06?-`!fKN!Tdrfp%`({z`T9?L#}Y6ZwCJ=(+D}i=(V-wm1ul+7aGj0f z^Qjy@>Bnx>^6=dv#YHlUb3!PyazOaMkA}U_)i;~=i=#5*{uq)VV4f$EWDk>U)lgO> zL4(E^ zgB_Eq@ltOc(^N5vAc-simUd7twf!WhGYj1+#M1wh%^8Oj44?_IRYHG-C70SU6HC zUR#w20BC6saCB73Q^Wpe)lgtQjRfYJpXy#&@be3&CNFPZ3IJe?jSq1~F#nmd4mbPO zC}r%IRX5pVt1mKHp={VMv%FOo?k=;!wQa0mO&d#^cagz$iDfQnz4PW?x9?Qbu4Tq4ZMA@2LM0_ux(=sECvCaw%>p+s3PcRSon)hl)vAN-T@g& zHXa5&!?&W3i=8C*0(awLaJ;YVdDl3sQ24i43M$4jRu6rL+z zV#zD5u!L^n-B;%$majx`kYL15aiVH6K6oP?7L$M_1WG{RFN{6 z5^+5~O)$T-*p4k#x6siw3WJWvjGVuqVsjM^?0p`xA|N55A9IS%;gj>F__WG3evq;q zH_-5f!ZWHksUT(OXUi7_0APx2XR4G!71{aE4jJ42*o%OlV%G;l&~U)&CmDi4J+8D( zg~|8?Ufq}vw}(eicBA@8G}bMO$F3uNs5$C~9OOZ@QW~d9DNK>=gfRx=tnLz7MQD-5mIrJkF8;!XhoY;oR-j^T^}Di^xDH|yrbf0 zi73c60|0g(>BH}L^rP{Uc`%!USY7-crsiLQXpErh{gtp6N|4nU_!Jq|C=Ika4qa{u zH*NxyOgJeRCVV7}wWDF!5s z+RJnC@vdU%v>Yy78%4=)Z=kVOK}6=EY5-0T1%xQv7y#!dg!ch}Z$Ln2yNW59M%3-j zMzl$TMeCEWb7v8vT@I{YQHcff_Mj)=fJPtyfZTKg8V+P((?&CFY3jEe;(dg0{xKeK zyqEBNKX{=}XHl_sRTOrYJMmskA1o#Tm77zLn`Xo-FC^et^W&J5p9iCf;E5O7;2n_x z06a%fxiJMhUr$6*8Ulpp`@!+vu?z&wZNh82^-*kK$#X_*-{gR-FdX{Ki>)sujbHeo zlU_)S!j)=3ZFLq>?Rpfw*p3yyx{BZIbK`Gkhme_~$L19leSEy%Mg+}m0RTd$H6C$> z;(5A|Bv)^7qV;+Z?;Pv}&l5~_nE(K%&V7S3=Y2@eBWP(0Lf{EL+?tN!(#tsfp$w{x zfNF;jW#s}BqJ^tNfvCTS>NTEmJy6JiGDAr|)@-)P|hnmpW6Icioy; z9SoWq98L~Jc@ywtNju)C97HGtlq{Zv_=y6#t}*=KNFM-TN~Qs-sDknUCmI@fQU4E4 zqi?<|KKJNBxWUlKiN?=)ov}6;)^^O<&>1;h&kzi881VzOEh9KyKLSPK@zIGPsFWci zSqF$1;dG{xyv|t5iN?>v4Ti?MG0FFdzHa7dK9xh$s1$ybDG?V{WG7T5KF%(q|27YR zgGNX3>#`W?Ocb%AeE6?CA5+I^^v&N5eqR7!OdpsW$)Spr!Bi=QscIZ!Y7`g*5GaK3 zzN~EDW0S1J($Hcp1p<1sDgKEhjQXwu7ox#;E!3uYwTHPq}aeoa~X#*e>61 a|Gxl-cn#}F>2t3D0000)mItDfB)s~H*jy7eIX&a*_s$gQXy(PpzYL( zwvIv(T*p)e#t;-324Py;sg4xK0u!N7O{jy#HV{kOfl5j&GN1v99g{SqDP$obxgqx^ zX1Pi3e>;8%1pzajne*YibI$vmcbWHjq);d%gb-Mkg%IM7ZCMtYZULakw{8FH-fT9N z|Fd@ed6Mv$U~#Son_@%PEffVNrghGDL|E~ljk3V(@9zNkuv=p)YEqixpg%0r-YpZE zR;b;c&EuQf5mO#aL!hCtuu!FHWjY6s4Kg+5AUj1T(XZbFApiH_Z0i)kF(*H(8RgXm zjd#wOboLoIY%;rklEKIQqny4l&Sy&P?A@G2%hgFf_)yT$1n+%dqqWO%4}h{|%a&&W zgb;wh>2R@Wbvmux5zaP`(0W-XD?{ZAWj=&#($O2?56@-eaVqRR8syYpbp}EfQ&Abi zQWzQ+ymdjxvIOaI(wz~=l83s+Fg8_U%ePZGf3S$PtNr}?P(Ow#sCYbq*jR}7*#PLe zrcquFUZ2L9ixHYSB1~CsRzEfmOWc*B{*cVSIs`qvGQT<84}c`W3zZr8+$!sLb}<$) ziHr-rzNv$4dwUod(n(KIaJvNGTjk=!?mQ}=Os4wvezKD6cLKCulW4tS(Ahgp_2EH| zG=^_QW*8RNKRUbN%m0@f$eD`5NB;w+u z)(7xFnB6=?e>iw))p2WWTAa!qyqem2a`V9s`c5aNQNTEQ1>F$z4r(mQk!B)z?eq<5x8-nuru&{g9_ZI;Y^Y$)oC#`n9VK(Vos)0Md}UP} zVu4IJY~zWq`FMWKJODIZaO_N&!wn$}^JWcJK9o$wbJw`f2T%VXmGZ(E0QT1hxzc8k zk~T<8OoWcMX5OxAresl+t(&%z_J)Q#HkP*uzJ0=rYDvsa_58_E}WxG!*X7WraS zd=4)s-WlZ|O`YWDshF09EQ6Y8P`;>+wCqtVO{MDRF9UF@{ZU@uw+yFUruoVw>weM2 z`BMf_UBR@0s(_;0Y*VibVmvb)J2s@!(PmPT@1b#jA%3ronwnb=ebfZ~9gGqv}#zA}cCY?B$E5+0|R0r1B_yk90E-j35}Qt_QR?BABfZ|j2i zyed03WKf*#VdGQD9J}~A5*L@^@k%Uts+I8Q%z#s5i5-<0?Ae}5ZUMylV6MlSNl|hf zq$Me&q)L<&dDyu=6WtITc{j{U+veXY_>sSa(S$|8d^a`E1o-~5S6TYQHi~oIR3BvHH&ZCdcVjxn z5thQI7dj~|kSNSDNb>6laTlYN3^+L3?Bq*T9kjQ|$d-&IOisN&%A40D$WG{Ir#G%iAiom0lnCCa?{Gn?|beaTYsIKa_8ffH8oe#-vJRe2th#z zr*a@6JF9)t{K=__>;BewrM9u(3@XVr!BVC1$6|L;Ab$M8p>dit_iCO0S-WFwL|8^H zw~XF`nVEJ)QgbrwSpINY`qQs9&TFpM>j6+mmXg;moO9rf0k#-T!nzNeVtFJ`BqXKU zUZh?mvU)DKSMq-!0oo;7RT{HkO4__z3%ivi$DP__ncmyD5gf%Mfui;Rw*kOIcRA^p zLN!g6`~|`Y56;R8ij$%e|BsW60*o#fq4H0PYSRYqj z33Bk`n3pe-G;Y?Bi0H-ep z;b{_yEE2qxMS`PwBs78>q2b&J720nzGRc@PZ%P?|c=itx(9~h=2g?24u)%TXuta)d z)1a8mFJ!nzjNtKB1bF6;)c^pyjpDtPIdJu6cz8l;$NtZcwIkvqAeOw#-VGdzN`ZqS~Wm|SPv+MKYM^c&3qDz!Giu%AJ)Kp~z}aFKq&wisjO##&ZY7w)9aQ`6Hha-akEF0F(w$Pf&3a4xX$l`5=y_bT?6 zx1+&rA+NWF?#U_uf&2m!@2}2|{nv*6_M9Ge-21C@-rB~*^<9oYFE*XrGI|Tk=))}| zr}~_t-nsZRJYKUCiIIci;JG4U*n{O*_WBjHRY~Y$-;NmZ92UQD2;OQ5$I3!DSl*5o z7p0+m^Ub)uFaZECchv>!>k9b*Gg3^w*mMHlx`v!tJp?l|g=O^89f7>8EC!!npm=@- z4!<)Hb{oaXivhgyRt;WTvL1lI^4~1LjJrzl>Z&yWfc!p}Fl)tH%$uHyrL!`isow~^ zac2WQE)B3?Ya*jIGm|r`2cR^{9cRx>mtbZ(XI4ghqNVToLq6L47VcVn8iS^vz+20D zWBmsWn19c^cwoj306=SV0xnhc=m24s1VtBJz$-2VvEq$dcYV&;_I zxb2Qlv0?p8giL{{&z!~1SMxv!(B`)=dC6HcomW99AeiM6j5)zss^Ba|zNUY?;4DFK zs~c59DbDT!mI?R+46bAaLnf-obZYqQP%A#zJ|1@2!k2r8VcqNL7(SB2Ie-6jqPY8}5q44=);BW+S;zS;7y~5bNVIcZs*gIkb z!VKF#_h93WCZncN)XK;>MT8L0ZuQ^JdELD3DS^8S^XxIJ7i1x~$2S`p7kKKmOW3;6 zi<*kD(K#kzVA4K}7=0YsH(kc@f9KfaOhA3ZFMpP2p9#p3=mcO zTGAYQBwNhxXb}=(03=KZ2@58n`LYC06>#!s9rQ$o?r9QszS$RZR-Q-cks&z#`VgqG z0x>>Mhe~HFdclzjOc|RTt&4aCe_xY_UHe<`_}a^;sZ;=qUV|fHfP_JaL8BAYPbl?+ zNInplAOHk`o**!DauSZcHwaa=A=ES(*tot2%6AMv<+i~PDcx{S$=g`8U^%8g^fD|k zgbm)Qb|#EY!im2Q!i0$`;#~%!@g*Oj)K3WYM=4RsOQ_UFsMG=~djtXEG7K!3m4a6n z^@KzTo?c&#LAf!QGBz0wy95Au?$HdCHRobqeKDpjNm4a3?w=Tk6%R*WxgB44(As8U&Eo7% zf$bWFkOgAxGJf}DPi+5fE+P?N*z9ubKGF))>TLH`&(Ff_NpV_yiZ2aRY9dr}%K#AE zEBUn|rJhJits^0V@kP2=|5Pt>edF>sYvAgpqHpFmH-mHFm+P(|s2gbaN3U){KL_@| zlaGnNsKksVmtcuU%ViUq-9N-{Fi&u=5s3g}g+0Ta$5q-C= z%q6Wp3&+m+@&0Z%n%oSVR%Ug|X6gFNX!SD8nc59ocedbERRH3aS|=iJW>^u{kaR-}()MrAlM^#I}N_R6V~ax*kU)x(*OO>sg9VC~jgtlQFnhBGR9 z4kmbPa(C3aBcO!hV3{9bgF{m(CByYOay3=7lT@*trn0S)$m+T4n4Jhj4kWbL zi_J0)q7Wfu3Lq{q9Gm5`CEhZ(3}-5Upj!hG1e7vR3Y1?6A{YQ#-4fPrsl&1dGXMa( zPQS@q(M}RYJ3$m%IZ#5DCh7dsh=8X7nAfsgx5{`iQ z?|WOb&_1==UQA3uXoy?X>u!!YFUdwPPOJ>UESKO`a{X0V8S}^)xa%cw8qK5rDrN6| z+Dzw8a1z53A<3riC$f5h%C<_P*ebpY{(}UrE1{QAAE8nUr*fl^l$xlMVNStW5(JBF zxGFRNl&Ii@kg#FsfeqUlM$Mhzj0r@TpQ`!+D*t$AbmP5Y)HAxSIhh2(xdRZ|_1+L5 zVM3`tDY>~IE-p0A=U4yi4fI|6-+IFvBG5skggLI+w|F7Aqf2*8sQ=ot?*5^SzdQZ| X{z%^DvPSWb+ceP+V6P ziB*$0Yz9`%{LuaH9UA|I<#a(fuJGhbNsgb)anU*DXsUuI*s+*CZ z!SHCF@|q&Zmp@a*bFU}Z{cMgxMx|j+ju#&4pv0*%63&qt7wkJ!AY7x8ND0O>7TRi| z(xbnRfb!mnwptehfh^BG*ulE1{Paem91X+?oXQai!@<4@0G`~?M(Z2{1%q?iom6?P z02~=i6AVc99n5mzs808BgTs9aM}{nf;u?KHgBRY`KbSx)sgTLpIMACRn>V?5k%zZ` z-O1BGXkhV2Omtmx=TCdIlvzxAXK1ktxtiFYxl(FXnOQ4V4_~O|$RlH~=*j zR%~{d+v1#h_oX)yR5$5-bQ$=n^8`;7IB_b)P$J8gTU*)q)w8JfDpQF$MPTrh!oa9W z?{I;5MC0DaN9Z5TPWwIUSJkqlvxLvzag0>jAe}Wa3vl!1el|TZ!rtyAp-6!_tq%M? z3m}=hAkVgY8hPo*b7`x0u=;z)`Q&{26s88nIuC>e!$Ha5h)&;77HL?yWZe;7fBbBG zWtOQ8OFBzER9%;{`r->k&Fvy~AU7wXpS>AU9q91lN3V7Xa}{ z83TRwQ%(v66|0l?IX^s*X2YWaLPK`yJOg^%^p|$;vx=*u7;o zLO^1?z!l#*M!468R3JVki6>!fLLsLMw26!$H6clko5YhkicP1|FVS@vpD^)PXw1LD zMuXqR3$Mm`X2+#C)B=0|x{!w+tzpp;gXrm5T)1Ek&+WaO%Bm=LZCuYMZ#J0K=w!#s zQA9zdsYA!2flvz^9Tm7stjuXp(Xx5T$#9NCqY;{C3U2$@46az}qq+J_roL;-j;FCz zgz)<#jK@ltdv>vyeHC#2`3dUkPXTcLtb=TO>eKYkO|X2akDIUbGq?Fnsh$kyxbD6l z-s~~a3I@D=BFX%j4mPiCnwIhZYN@or@X0iT(_ zsgw)1JI#Ruv#~a3c=3^WwAMMMFeb7FJNLwR>iH0+0UeE2MAzY{+|wo5@z*#bu_Wit zcCl$~1MT%^HX5d6{f`Iu-Q!~nA6{CVGgLau_ptC|U9`*@r0cB?dWUN%o0}v~CHVrF zia|rQjn+B`gQv0#26PfJ!Gc+CK004v(d;au`&d-IvR|_2tvoNkmLxHjV@9n>OQXt- zE2^mRS-IuGelkf3rr{f8t1Wt!SJf;#I(1`a*ZrK;aQEuX| zQP}m^OxAp_mzQ6k&;FmCgS7-)so2z4>N(Pay8>1$^%e7?%)%cw&*qPNV|;zfASZh) zNJGJ47dUJJo24jX6qiF%;(}7Qf~Qmi0aAcO;PgmVFZa;(R44s`EGNTxe(^{>-Mi*- zY{z_LMFpR|XdAcOd^cCGd4Pg2$>z;zxpUctUJg9n$z_*YDD&qjbt|}?;C2=zoMN*` z%1gjoCh(Q3D4IYDD6P%0cD0WO*EORmf;+Yj(b?u;#Zn(`hYG-VzgEvXk#_b3mvQw? zUNULPd8-c)h~%e{C~>On*f@(Dukxb0vXqxXnajjxk;Thsh6gIWg6bI-sw*wHEAxC| zc^Mnl6i>Nbe~S_yGuXVYc^a_8CNMQgi9_Q@w>7czN3+P~Vc~V%y!d8(O0>Rfo7OgR z$%Sr4$I^I93}Esysw|h(R4CL|srafSOWK@lUEeab@$N^5sjjdvv*Ao-m?nJt;UO~4 zJY%V1=`NV*V(+#NF8}5+R^2g((*bs;!08Z_mZ-GW*=h7!=^ji|;3;kM;2N+x5O(u7TZlhIh3=vbbGYr2UgOhQ3PHl@W9sUH}4-JZm55XaC_ew_jhwvh&LL-5(NcdNROo?rERIvSV>dOckUesqt&HHmJ;L zR+!f+nAdVfl1&j%6Vpr6%+*=4h3`4`RrB;?Trep^(M`J9YshcdzR^{xXLRzyG0b^c+ef+Uy5g^LIR$MkHqL5L zX>U|$Z!~GE)$zCsQ_kN<0HE4uBBel81U9P$sk*uSCnF>yHqzrJrYb=~YTTrEB*Wd0 z4U>wiNK;|kt}x$RRfEl*#+J*J8i)# z0wIH7L?@OoNhAwQqy(Q>dz4hvLRpywr$a&Lf~Q}MaQ&yNkeHl1Thi#4G*!Jn@((2d z;4L*-FjG?DQSo~PLBC2krVtw|YKKftqU$cGE4F41o510a{OZ|Ik$^Or-)>B{X7U4_ ze<%ScCT2^uL5;7d8zTvbrv#}9l}ye=FBE0hyUnTF37#Pfi@(yvWs9veRTZ=S-#G^m c|L^wvpPs(q)9wL?y#N3J07*qoM6N<$g8r*4R{#J2 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/msegui/edelweiss2_48.png b/mseide-msegui/icons/msegui/edelweiss2_48.png new file mode 100644 index 0000000000000000000000000000000000000000..eac35684a4f7c9b1c792b5d1a0730db4f1b30247 GIT binary patch literal 5112 zcmVxP)MK~!jg)mnLURn@uw?Y+-%&&ka^hd@GrkOTtAAR4L&Viggs zmRDb`6H>Kmt=4LthpNlgS*x`UXsy!LI*YbcpMVOh8bOdb3?UO4$ef#d&%I~b-}~bx zflGq6+V$3Yd#$Xjb@o2{`~B|T`}@BA`wk-_{C{rBe_|3g@1s27jwVej@`=a*NgaR+ zkO05{5Wsu@E*Q5NV^J_3u~zfwx3>LlR=_-28b0gEQ`w%+d@0j)p>2v;Wp@)%0H8Pl z0s|W)z+A>y3`{ycuV0|6_V`#V_@t(nRew`5-)IHQll>q`KbxeVNocxs?y;$<@BF4* zo%Q1{r|qn*yHdvTHpB@)0TBaZ1i%BBOQNg92=<*dbG#AA%}7>PeH!J`v+pzJi7v)P zhqYRS|6>Fg10%xF5}6C6M!uIv(#wPIXOZ->C8wg<6+vAQ3@h)i&?le2`P8u0Yr@wf zARO943_cI^7o?_#r@nMssaRB%fyZBK#y>u_bIFZO0#`anh-_n?(#C|+W_`$=Z$*I3 z`zSBCKwF=3DjNIyy=#m>RWnJifPAlDfJ8P)KU;E<+|=&)0L17V9V_lERepHK?h~!{ z^cF}a2w)5#XtrV|N3z#HHI?QXu>>?T~mTFg&ZPa zgZqG)7Q>C_kHYlQV1kKlwGmD> zWt>*M>YmHToO;#S`3wL$`&``pLX&)MWg8<$x9uJ^0AE1M@5O<)k41KxI`r=TmKdg7 zunEzYAVh8m?e86jwBVr~DVdCa0b{B_t2l4?ZIbRsVaW^^Af)Q^_lFt3o`?$g%Jev zA`q^EyI*KZc)z3|fM;)-fTTPN=|MFCe4Jnu8W-R`1Cs!JKZ`u4lstO^dCqw0xh2wb zi#@+#iLP(@C_h90gQ{xjXoU`;f0BHD+KPr~t&Q${4wZ~4eM<1+}KE**0TJ)fS)2`crjW0~YghFE&ft~dhd>;_|lX2f4 zn(^X$?a0qj5$jZN;858eW=snR1ie^km zZNa)Xmkk+T*7Q0~`p%zGHFsMAcmO#4w2$$?YZu_*UyQ@jMY$txNdUO~{#rC1kns9V z!BsyKzL!Z{NoUf}Ao4Q+-h61iq)Z{{r;_y3Kz=$&KLb8eRUwd~oalqn=-8UT2GI)41? zy?AYHCmwyJ1+GVsx(ivCjK^PSNA~HTL5V5YziVs)fbQ;8Z1{94Lfx5IIQNgZ>*i~* zWBUZW_4;@5_`^#Yb)Nb?imJtXT60hAF4&H*#x8bX(lPtNXGGjWC}??#XMOW zjEG>)_p+oLtCX%?Dcx8ldG=)K#wwXlNsI_0H3lQ-BW4p+g+nM3u9Q$X2bUaPtpOt@ zu;MS*VcvpI@#Pm4xbBL(aqAt0IAtMW`&Qt^|aohN`-Sfuy+G%TCo$QEXync@UN3OjHz`D9q6jiul;Ds~3622 zu#=9-#IY4Y%$S&rlq50YKFv;3F*ZMds~*}1SSn`C+6GODN7LM##IdRhRLvnwm{>pb zjB|ZMMYX@p=h!&OW2aL(K;Od4w@%;C7iw%0|1cP?+7vv$+&a?dTB zKj?*2O>aH-wBwT|K7aExo@|Z`c%-&wQ!gmS@$6G~;(JRz002Du*!fuX#?Rt$VPGo9 z2G+h0oN!8FUe(o=3Z*cHlV%2S&AA0QWmY=)QBq7zWf(uo!0buM;)Bn7(ipfhFq8z~ zRCM=yG8`Q-?Kx_D;oXDCQ@V!01Hfh1u7DlghdZtncz-3w+ploUo2sC3Kg0TuW(|$o zyL&8t_uC6Wg0OUPE>4|&bnrXtEnITnUdlhSTHgP1`#$Lw-N2Y8<7eQcSf#YB=|XS( z2~(o8mYkHyFFPxb&8ZwYZ5V9bArIr0Y(Q1=KD_nDPZRq7@Wc;s&$YjRAYjIcn=xiW zBera+z|NiHQ8r~C(nodR)BO|SngWgsP?C$2W~Ab(CHWX%Xdo2vv3-98?^pNYqfNc& zi}-LOfv|K_H*k@(k*k3%TnlU+BrsXJu_@BEr%1Q|SgwX<8Yxb4lF4xC;yhfuC>JFK zi7D|bA9mo%2lpY?t|Hhi@Wp5Uh1~p(q5hjLzYY6qigEvQcVld6BLKjT>6laT7Me{H zc1{#OIyDF1ot=hlwHAK=W-F{d2B8APB{*Y{jzGAF1D*m&0!%0^Yydb{^{reTB4C%t z3B)R;8=Fe5T}hr>#JLAO#RVA-%8E=ZTbzSQV@+KD+j{J-i-B=MUY3ToZU=dt4t{dM z8%R&@$NCRvW7S*p@r&D^!Ow18oJX3yN%n+kei_;fCqr2 zfWY#b$K!&9+4%31^WJb6e*v1rn`{9vza0Mb@++v(Z80TRy-VY}Fi2-1M)LrPK`|;|% z6NkV9z;i1PLP&w1{h$Cx#*UOEflJTKgIgFylV>1%hQM_)vDBOCy%)jZ0$2!ZhsnCN4ihZyI*06>}pvmk=M zJv<4Ej#&C9UTc9(9o3qNKx?VGgC2Vx}lkwozs9gPR2#ZTFnm=q&N>TF8UZ3yk$`R)=bdG;KQo*N8(9@J)>uknFA2<&IUv(q%B2)GBgQu*xvs9dYV&WS*{w39VMdzC@(fpQV>9XmWJGP6|P5^`_rvH^Cv7&^z7<{8=1A5M~!)+3tZ`7 z+|M>Lx~DBYBbSc^{;4-xvAM>=aN;Lu_3APr14KB%-QZaRXuN_Nj8LTHHTtpcc z9VA3Hp{=aAfM-5@_1Gad(b4PT!;QUocYQbB{HPNu1n&It$g<_*ueM@8*DKBE7`LqT>?} zb$gGCdtYqAv+uM)aNxZMr(jI3j}#~8m;RBGA!}PE6up}+=2w1lye|GSw)ZPfuuMD zUQrvEP@Cc;lmi1KT9{DU4#ztzd9^;|j^LA)drtZ73W`?<%3jTpvV{q?o+)Yr2??pX zShhH>Ce$=on0d*Uxc;#Q#2SL|I!pvo374LANNq554w4*RNX1>xHy&vcML9a8Dvt!; zz!a^XD{3QC)B{W?&5SE8M^L7dr4QEQn{>jv!A z4`EQ$#*r#EN0ry3Yt&XIv<9YVbzD*FxuWi8infm_dVNQqBNtq=jc$9o307+m($WuQ zj+_v)fL-KGv^`AG_cBG>#}#!ySJe7} z`anZ;joLaA&ZAdo07TcSO-yKYOwnqYqSbOm+sj#Sb0lQ!{P=UfG18t<3#RtQ!2^T; zV-W=_-tRzjhl6GJ?M1Xl8%l{|JsO^Ty#=Ajp_^aKks$C+u4;R@qV461ws+7b6Ixw# zt=e=nj9*)3jjmOjjQQ~rDZpdk+>&lyh@$F>J zXEt#jA)kkdi4bwoLsIF4?`1Ob)8nF(OeQIlKx9}QnhN;3L!6iZfeqyFj76hi#vgmN zrR;|D3IzZ(x7!{Q%03Q#&w#sZVfSzeS10~P zpBfxqsgDc7gL0ot0!ic0rv^|!#KD-vK&5`*A`&I_V1;4!T|9GQkT&kNnq2Fcg-jC% z|J_RcxBgZlu4>1%N{}=`WPJU%5-bYFEsyq3kQB}4QhU|==hWtJg5g^cIFbxVCjDQ3 at@6JL)uJS^IepUr0000Y literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/msegui/edelweiss2_48bi.png b/mseide-msegui/icons/msegui/edelweiss2_48bi.png new file mode 100644 index 0000000000000000000000000000000000000000..fea52280a287bc4986b0b4620dc485649636e428 GIT binary patch literal 5097 zcmV_cVT&&i zq97>B9$91&^FS0ZPeAYp4@B07hD`)i2uLJ|3dSIaLLdnkhD?@8GBcTddU|@_?o#iM zP9`)nLBMy;`<*kV=Tz0L`hKf^RrOm+L?RKTlmb90#fSg@xU#Y8YzJ}$Fio%>f$bFQ z1PVupNmeBzY6^1%+jU;}qKnQ6%6pz|bTfH+Wq( zeviWEw*Rg1KNA7lf#IYimJ$pl9KL;jH}QIHm^65?D6ac5$Yp6lfB39bCG^ z<5FyB%P|luaN5y6W;W}T`7NaQ^jO5FRiQ{+GL#TR6EK`my!hrYN>e=l;~5-%=|9nN z(_9t6c0f7%Mp5XRz|a-_@htCk#F#eTOLf>Fku*8~#1P@2A{?-(2wMMlDzvv9P*j!v zVaebyMB*?MgW&{p588b3xDdJ~c>cB-9D4pHVnY(Q=K9bIfUZH@OcOWLJig)}mdvl< z-eYkr7mdEc_nl0H{jkfCL6&7GJxyhsH{s%a&FW^m^!vLVr{- z7*#}K4$-(nA_-js1pvm?xOw6S(>VLaZDjj{C{@%6fk5+`cq=o!xpFo$Ci(#A9WqI# z1UtJFv7{hgE=gqtnJm;+ID`Y{XD5)(I;64=OBU4d&3pDRwb94CDPhcl&OpRwaM&gi zwTZ+WI{Wh@-z{BG!FeZF^UF0+a{Yb)9L>g4o?+envqr!JY;DgFkHfA#Hi@JpnGs~N zf=o`MU8x_uDe`_qk9xi$qEznUQ3&l3YPxS`yRJ zaFn7hY#oq*JWxd>u5skFAWyyAPtd1v>%|k;_1rv8JvPYBcpuS14BIgg1)ZLu0)w&r zGvzV_Fa6|T+!Z;5ZeeOUt~#@!q<_bOJ&_!$An6-0+1XK`qsykF$D*@O(LEsO9@OZG z==2ZkwC=IFZB>pZ*A@OXfk<4^6A{ds7~-B)y(8sSWd`?MJ(*q4&f}U3stGlv@zV(;q7;*uKDmPiHJjKl7(JRRLOdwOlU`V~Ec z@XE$KSN$x(b&utlJ-vhltn3r?mm+}Jr=ur zOn$#%h_|+9xZ}#n>|Avu7c8#9alp{_Ul^kZ^bZUAhXs8Rhn@k4km2K}&-9G7P`C`i z)n9AmXWyHQKyc=YR${4AeHDPi=o_lFJwrC@FmqPivFmgchJJgdU*NGVV-|&XiO3S7o1$f z^0OK+bCL^h-7!*LuoMD_#0$Lew;?{*ox$9@{Oem%NL{ev!g0)-9-wb1j}VGLW11<` z9bSKM7I$3HjN2$eeEbjny!=*_vySzbPSC!a*mht?mt=dVLtCe!t;1wTM}Zx?b7b-b zytQf8-g^i~&kT)8BAKzNS@IUTt#QLe4SfHC@%-*@LoEBRo!B`I-B37gn~Y_#U{)FH zw9mbh8o53%i?8{B4UZkh)F$sJ0$bWM*p5Qq738+Zx_SJiLF%gw z@*I!i6wP!csb(d;&XMdhA-_XjO z<}gy}3@0th{Tda)qN;v~0K}3-`z9K9h(v7$A|{3}kFUZaW13`!3>IF#nSVZc1l8q6 z3HTGPYT@uu9~a#GOS-#i`O_OmvZ1AkI+5e)rZ5&k6F++BLe%&)m!4M7 zjmyRn4vxN(@}|QVuKoZIK0KP6cuJ5+OX6usMUedjQdvPV1F@uHIN>lHw;7Jx*tU%p z%<$apGpP+5oN+@dz5O-|zPXt-cg$e=gyOAw$5Y)*4fXQ3)fbHne$k#fj$iN_<}chl z0)C&IviLRbSalwEeP=Sumeh`^k^tZQ?>0L3*o5#COE|<+8i}+Zos*<<5}(^HZsJrH zk{LlVtw^LD;t8AKxCM^D&@}2Q3}#LC^X?Oe)6}4|XSc)LW$*EWhdW4SY*wusFTH*gUtIxzTREFUC;L$fe*4!5SN>!tx&FOIpXMN>BAzu# zWhL3XAe$HD3j#+8L}&MqYHf!tyA>a_nY_0(Lu*G8Q<-@DHW|~Ty3F9fGw*%=`Su~4yhQToGy5+!(}a^2=$x?l3BG^J z{Qx+Qqwu4%MgSD2B5HP#Xu}iRmfmkqlXI?d6?Ez zKsQY&m=H@@ywTcEPc*|ZN0o8>oJx+I5n#@=AR)gtrk+-p8#LE@xbn_6M8;t5k(+U8 z7D5SXYE?;F!+`no6;r3}9x0R3;hZo2nU}tO3=cjL!B?&b1SD5pSjU$aR&q$QucVKH zsc6}q=9XXV;ie~t`NcJUblVYFw&L~8QD#kb^Y#rh3HrtcJeI866hq}DD<8ax)4uXD z01w}DE`NM(IkpYj-mVIHc=Z**=NFaQRYTD-^rjrg&GEDRtVR~i3nLF;BfAX2ltwS} zru$j9A&PBFq@#+aZF_&3Sjr-m{d7@+$6oBGUK<(#4{*tUK1CtBgPWG?ys}2}yQd|` zAFk7}Tkytf^G4e3*xthxvgvRzLr(lDfz5`#QH? zeJw&L<{tAds|QHk1C|YHI5TN9wn2natc{-sSd(Z=w01P5|;b zHw$L2rX^KRAzIEkXIJrs&xLt^XNCuV+r#VY)BJr?8%jDzAy5U4WL!g;UZl{ep6bHu zmPlE|ECuMAROlMT$eAYa7#h0eBh}?5Ep6_4WRN?5)y4D)UM^Z%%OTA^uD!3FZM$;_ z2@O*OebF2zEPjm3&-*Rq;RJ82J&HfBK7sGt`129)0B%p7Q_on--Rl>z_1ANlP*?O5 z&NvRfdrl+E@7~Qbe;y>?&%+f)F6U?Go(6s_XlH71C`e+y=M} z@Og^hy`JJuQUC&!0GV@<@ADuW$^4^yY<+qzr_Qh7_9yp{Nr5&w%cYl=v+>EpNUxjE z*^6s<^wq_@{+FYG;+g;B8?WN69n&~ve)xdU zr{*x@AdQS3$KwH?N8$5;&s~h%Nq~SCf<8siF9`W1Wg(4lnGOORcOGv;nwRc6geCJU zN(Q+9*&gy(EI+GpOaP0IF2@zNaSX*5jx6Vg7f;~rM-QXC65iOD zoi`tv&7sr1yx$!yPO{heC;>jxLQI3x*|X@tu(q{qQmn`PbovsidoSxLvQzZWN! zbvS)t6*XaF^vJ+Ft!d1hMA#Z1>@1qj(mT%VN&5clpudd)V5MA#aWy z5B0hwfB4D4G}XFzr!9%!X@b)7|F!S6^xGjxM+fvM% z5iDtY>ijS_uIxlfa0Do&fvFHmV_cb=@wJlXCdq_)#l$+B3AH9}V}BU4#FMTnbBLt` zZ*7gS;Lsq~|E!%|J$YJors(X??ir?Qk zoAI@7rjPfr`TaaE{UbJtz@!E*8Oti(HxiUkC(JS2)9E(Rq@a5si({BvbZRl0u(cz@IX7=(`|bj{ zo&eI+@lQ%|$!Yte4PKW7M`9%mZho|rdzP0v`4ehA40YNFN77JZ&{(I@RIAZg4Rw`@ z`bvkIu#Mm2l+6B^1fZx&1yf+z0>>#XlGvLjLbLEyxC#0+?p@Wx_kZ3_Vc3I81rZAN zHpg-HkJQ$kLn#Au*u%pw^l{^|@l=HN4?Sa|hxc1Dj0?M|trpbRXf##}>Z=qDRSvab zYb22MFIQln)K@wvBuar00!`B}G_bJQHV|Xc@)p*=pC;QE09!*yg;D|mf|aGo!OeauDzi*z(5S5}s!eg`Z5pa9YQxs3ncpV| zOmF}+R62~WRWvsUCN@YWkJFev)yueWkoHb!3RF{9?ZxBMaQ2$Lj#T858c+RcknX_( z7yWn#*2n5r=_D#q73G*#Olo1OXC75MN<=$gQ# z3%qWD&npS~Do2uh!*QEL(jl30NM{|gIftAnY2B4z-0ACa*N0z8lJCGX|A`4eaZh+$0V;JCZOA1ba2cGL0A<#EeU}A$tbA9os+?Qtk zSKvP}0VtkMevd=QCn*mKDni9PaV#lFWi(P5Nj49eoFrdRdlTJzyZ=z4+v^s1-9Dau zGtOT&#yH`Ka&~rSIeu1%=K9h^_a~80{nVhU%%MD>s0d18Wr9Sy7*|baA(Mk#L1I~a zqoFJFy6Fl~C zMjm@?>&h`OY;yc;7v%x@|MOZU;8g^?>N7pJsVO&5O8-eSi4U+t>ed)F>vX8iwL)c=W(gytJRnEhb(0j!u| z0W1KBLCp+6h6oNoE{JRpr4wsJ`ty{HJ`W8D&1W*QBiruX`y)UIL4iG%7{8gpelS~L zs0;ye&}$kX1A+@8hd^nNutAh05(y9`K%zIXhCWk)KT`ri^Nk+{Kd0)nn1}`YScJg52DCfE54*9w2~;3;-7( zmq4yoZO2M0dX^lw@!f8POA(E4m?M^xq}o-y$G1pCydWW25t! zbsmh#WuvnJJKtp!oH!;30J!6d3VgITffv^uxXjpcH5p$Lp86lO20%kVBhYdhQ>x;U z`6amb+A5S6`S91bI(1uz8PBd=1tEKwMU;%m4$YNa5V9+=hV zz+$!D0iQ_HWjb~JFZ?w9VUoTaHg3Tn67tyS+zbiXQjpu$H9$ZpAh7y@qiOmTn}gkM z$5a!|?md_Q4)^+%l?wgs{$qxKPdf%F+X$gWHXEmsh3+PnQLu?Hn=r8nfjJbK%Lfu` zRr_a7fD}}D!zJZ7sxnAFczEwkj;Pw&Cm3$;W2nwr`Dr%1(mFfDAy)P?02VT3C(?=M)Zm=i{0LhyZp_ zWVBPku2aFTQ$Q#15&OI2iVBP$6NJi5Kp24hX+SW3xN!7{?YGw? z;1de$x_$ju7~KclJqWy0#>OdS?Ua5R5{^hfXg*7U$h*7hld8Ve8&M?*w|#32cK=}( z{pgaiV17Zm8j-eRDXXgrDxFIPptObdZU;MR6T|xSS%hcroCK{La4-${H0ICBLwS*J zL>ad2>xGjNAOpadT=u~C)eLy2jEz&q+AU@6j$-4EV(pHi)80Nwp0@tkz}&a?(Cl@0 z|H}lhaf=mI*D57ae}AuQ$g`@_0PelE3eBrdpyw7Jg_+0t3E45I;vPV0C?WB{?;A(# zcjlxl+psmG@1dIbZO0l;{3&!1xr^ z@JnAAvNDfIKxjToHo73Q&lj@Mh0s0{9IU@>SslCj$o|76^NaA@U6VkTK~Jy2mG|r( zPCy?6@J4#1@^MYC*ETzab7tpa{bSSc_$}iB00j1?gfKpt-8Du8;}wgpst}u2%n(zn z!~K1%|F9c>exqI3E^Zwr!-!usIxl0~6nOi*Tf|xyaU#-M*PO=fPt+cf003Apw+Q!N zKNcXyD;v77Y-RJ1=Xwy4t(`WSJ8U$xrIE4+v~=6P1pGq6H3mzrtHP;MvmuB;83GVU zLl$)7sA@lbuwn-8ys`pH4iH<@oWfUsx?NjRy%qGG`1-*z4)X>>^NpWfZ!c%q0sx?fGj@lzrIfIq$7j)iyZ1Y@WS zSpkVF&Mv`~XP4j`i+5qqZWpfK#-gh#u&XYK|6Y3lNcf?A3}ZRC^U4a(wipB)0J`HY zW?j9-)VH`zFypTiBC?B=RX^B)8m<9G=Q3v;9HaBV{o3G7g`_WplpmKa-iey#)Da2r zTLM40s0=c|;F!XhH*Le(4?O!|>)u}Yp%ALeL#RFv)vkl%vf5GQZ^e^;Zo|y0Hsh0q zBxI+zaNqsg20XvE3z8K$n8wVher#Aieb}f205kB7pMAo0Eq2shnSf| zOySUc3Y2UZU>MmepA2_fQO68L__mUzZ*Sd3WVmmg+@D7?AleV zol4K@va2%YXC+iBm;4S?&;<+uV3ZUoyuEB1#uN`HVekGFj=y>{;+=$(3+wU4*&9Is z)~q`o@6}cT0RyWogr|OWC(b+nwPEjneZeDG``!%b@?O}|!9{b5aL;!tF@AJ#Slhwn zZ*O8leS2{ojAwIr?D#2Oli$bd~4Y_gb578{cV))CLOH4!#C8^RzGl6d{mskr^}G1#zt zI<7jW1e!FOT3t-Ld=uW>(%s)(Z%X5-ms)X5apN%X0C2~m$B>sDM>=t63$V4-bBu~| ztxp9$nKt<9t=nNI1vnN08=cK;A}}TgtRrkZeDG=*7`zBFhuD}fmT^NImt#M%jSzrPiCF0VsZ%*6|Db|95z%&Mv#QP@Brg_7cS zbazJZ)0=OB)^b>zXMcA-ge%a{mcs7F<&AbY+Q4N4Eeupg5cfUZi1PC{ z;M)85z)JW~zkAGx!Zy^GVt-v3h=He{xCm#Q`V3aDoC9WWHNX8QH{+duegXc@AUGj$ z?k(HVn>w_M|J&8AcF{g%q9e6)_~03KaO2{tkL#3cAc^8 z+T)D2$Fl2G!I&J+4%d)HaX366h-EC8ga8=mR;`e}8dAP}q^uetefvoHYDii8L}vK? zVB=%vK<0NK^E(JOA!2}}0hEUBu^=4l!0B4gq@cJ z1mlKl7oldarwQv{KOSHI(v!I4(gG}9W-w=-!R*r+x8KG1c)=HdoOb!w$jgR*B!WahG5;DMWj6rFE z59LLE2m*)*+Awz2ClE_$5CN9-H5;eomr@nKE~IZ?#t>o!W(#n_S~Q;~Bk?a9t^HLc z0X}7FE{>a=h2xHjV8+BO1pP-2A`t=SoRW_l9^MOKJi9#{Orfo*7{owU7DfaQ02g0o z&`{qp1Uvvpsd3)ixA4xAsdz7*0t}OC*>c~t*&cHW6SP19{j`p z;j7H^CTv3~!h*SlxbA|| zAra(5mC8|mRF3lFD<|g5Pp@u6 zIL>(PrJGPv>ctQ&pM!^%FT$SfRao)ZSlo2`&{ciy-w97H6_|d)@Gu$xy!ww*;FQL3 z`B}wy_y^U<4iDct4^`qxji+C3#e>i7H}$P)!<_Rf6pKDzKp5&7B>?;3KQ{TR%Y)*w zGmHO6zyaWcU2)X5rm$ef)_(APB@|BK`XB!eH(zlVx>|v%@r+0=@aigomsSy&7;nEh z6C2*1j^j_>0swGbi6!@Z7pqs!fg0b9EuZuvme8MyfZdHr{OT{wc=E5!Y&$T<4Qv%$ z`DZ2b-UA?rnGu|0k7d`c*1C7Hp{C1O#Ai;e4)b@;FQtp;6(K+SUpqm&ZCNcIdZr0K znYS9Z-}UIQ=joImCsn?L=z$yvCKzJmkLtvz(QT-$8I7KJ7+E=SOgsK#ga|LizTQ^6ec$fN||{?Ap}^v6-y8X9$(fBf)g`N%^?)Y;TbnyxJdJ;z^C4JXV8W zzt{}_fe>cpx8Sw6FCEs-u`Qff@iG#zAkM$!@3{Q?f57BvUc{)gJr@_9`8am%sD>R$ z!!AoA8BQbYmzX*}j9v9fbjBQ5S^|pU!l1GwfJDk5o^+8&8wdd?ZNW}RKwE(8?zq3UW%m;U4b9`@TvZG%!EgmT#1g3T&#HUCd@s1{g8h0 z3#0ha9Z%qz%kD#LViYqcMR3QJ<8jW(`5^K_XKUV%;zy6{!;ZQnMBI4HI=Hl5`4j@<`!R!g2VD{-7kxp57Z{196 z**FDcfOR{*hRSin!{*Uw1QRF!9X;c_(6Z`86z2^;-_VA!Y-J06`s*5`k^mnFf>M4k z0W26sAoCl5lo z?rYwUw5f+rTTt494mh~w($V<&)m5lzPT@~$J75AX-q|_@Z?=pDa$PvkaA&q5+!V&H zZR1BI;N5kzU}vW>xgsAy7>&td1~X8I+U>y!q%PVP9@xNZ8=ulF#)%Ja}1K@3EXkl_u#riSMpdajAf5p0u(qn=hP#| z91C(REc@{UtXgt3!UYyk{(uQ`#|q*3eVp!7muy0fm@jE{CC zQCy->_xy3gyf*;&$NOD4I1CR`W6In<01`}&U8brxVMpiPDk(KbWvqZ9Q)Y0c=mc-!8ak1u?#|#6% zac3MKd=iIN8n<3HdPML5@TKGOFm+rQ=}`%=0Fo18C_GAI!PjzOmDv!kz`D)dIOE2x zhm8XqT%;h}eN7eq`)8A(!Zt*9-0xxXGR-phk|0VZ)`;{#mR28F61_ws2|>Le5hoIH zZ$Shg7@{bKtXzYCJ~j=rr{xS2;K@}j@R2|yq;S>QqYf+V4GYVW%1MF=u%(N8zgvZ; zZl8#cp7{c*DlG^iyt_4y)2{yrd-oqX1V6Z3G^Y^%_~kJOMjXG4v`>OGc7}*vknmFP zFgPSelprB`K?A^vL@$Jhfkcc2LlnkPP)K<9iRqXzF>BaI6DfmdUulIQ;Co*$MJRB1 z)s+HJg1`ds(LhGY*wO$tET4hXzmN?UjIBG9IOdz1@c4_(hwbm+a{BZfyz}@p%FQ)7 z6lnP(NW?+Zo56W70b&5S5OI)dvGtlbi-Dx{UD0EmNbkx zOy`+$Y;_o`A2?bV*p*uDKhe`@5eJE0V9>!xVhwRteHo`iy&NH8WJC{y?13@eEOa-^WRQIE(xo?!KkP}&oy%*nw=o3`#*GWh z4+}o+7+n90y|B_2oPrb#GpwEfK4};^@_Y5Uqj18M2rl^Pb~Nl~_?q&-mWHtm8loEY zHA(z4&}0upOPIy6^wGm9vM$N?N9e4Vo| znp@1*T~K;RFX*kUJ-Gk(jS!B)%qan!Fy+uh0l*Cp@AERh0>FiH3egjHv1WZ7tx*T< z-3|(KhFgEfR)=xVwNfH%wJg4P8PM3))I+2#_;Uq>2y(5!f<-838;|iiB(@q1s8P4id71r0jr@9VBEY z3E6dUZt=*G4k5dU{dLla_QzgmE_v*QX10_}O9q-#<^AT1+~D=jhrzz})8_|e5x z!;YyBL>(;sQxhKfa}#=#8XOIPa#L9R?W%r9C*booBR8h-)Jv^cbXDbuPLR(cl;r!+ z+O0vhH2_`!AlM{TD@oPnRe6AEoelFRf-zp26~| zRuZa>ggih(9ynAY^)Ttf za$P6T5drlEhN!BS*fsP!buB3f0qFN4(A+UJW$xE6G()8PVDh5EZnq!LzS4%;5mIo*migfr4M^GMfwwZXPbSrz zk+Zc=_QT;jVz@W4hIDAYYRM=Z0A%ttNuw`#VpQzrU)AKKZ9_-})94L)=3>T!?2jWb z07qi;Cvo)jdSUI|jY+({tq16hfcl0b?T17P|M5&Cmi>7A5P3=qd@#%)DVs=Gtt3J~H}lyPpU%z~+8Q{VS9 ze=}NOHTA7ei8bVm0B1<~)B*p*8gfGORa3?_&RlB~DG;TgMM4^X8$;(q>Rcw%4I%rI z6SDfx;~5q}P{xOg@7w_bK|2CYXJq(L*nWpNrIxL1p`Twfa8lJDUQnu$U^S7H9ht4J zorF99>8bsvy)W=Dop^YiTFs%ki zkOYP@(ONHnDbhmcP)ASGnJd?K^hcgH?u@~2$!_NGE)uefgzW4i;d8q)G$IMF$#`gf ze}p9lA$q+0LXl0vWV4Z3#3qY{34%F9UebjhU>}$j9qQJY7rM5+0H!}B$v=MSpPI&g z?es#y3_SlvyLOG-rj%7jB)drbd$-0ulZ%tX?+xnA+~;tA&XIR@*3Zn=NcRRY_}-uw zx=w>AZA8adLv1&maY8O4AxY1_(cu!6eATC_HhvcO20yo(qwv!0!d~JP2fZo4zJKNB zC}q|dml}^E(eX1SM046zj|O}*pZ=_Fj(%=;hrMhp4h<}T#`pjH-Qh!(|C?`*|8Kp| Vbe`VmBdGuY002ovPDHLkV1f`^TH62s literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/msegui/edelweiss2_64bi.ico b/mseide-msegui/icons/msegui/edelweiss2_64bi.ico new file mode 100644 index 0000000000000000000000000000000000000000..6a22884dd6b91d5c818266f5e1ad0e2be2e841c9 GIT binary patch literal 12862 zcmeHO2UJwox&~%wYNAGk*rQkg6$J|@L$hH+jZuR&V(-ydqsE3M_HxA-6Qjh64HY$3 zM5gx{hUt|V7#IdL8l#EzeP@myCj)YG-%IXYZ@qVNWbJeIp1r^SKY!mlUS8h#FEP;z ze?RmJjq>se^78Tu#Xr3AT8n?g`*&Rx6%|g`RsQC3xUMqSRr=<#yRH(~RqVQKZ!W9r zDso*Gv$@EqFVd=t)QTcyfkh$1ZN{yXn^X#;R&CI~zI3ij`{vTPF171Yxi00KtI%~R zTvx%HOYXX4GTC2%zsO?Kscj0WP0F_k@{75-#mwurysNg{%eLGc+}7JU);m{<@~&E# zH!R#cCIQPN5f~IQomTS(zV<(YzgVxa7fMS+EIa#VNp6n)`q`44<0Ti4*v}m*&N@(% z^-b}~4BR%{r@pbBK4?96$a>*N>y=YQH?l2vuBeah6bC3{zv>|S27YZ>lh+(M>h?F*O;AH^2~RI5fZ6a7?IvNWXhsMUX~{FEBBb|7cpEW3HW^kQb&sr~lD z+e(2MXtypb**Ld&%~ac}NwzO1SeK5mE=eVBG?tGqS~1bKdWtQ5wsrG-+m0oo(e34P z5?;N0`Rc_B>Ey1$X|V>*9j!zNBK{`)r500Zp~S(yKtoR_}?iI)7V~&&i%D&rF3fb5& zy98Wa@Cku=V!Zj&?xqo)4MV~V$!&D~TFMgYN#pBk5}N3GH`n!TiI@7pp~jCROryKW z1~=ynZuIi`GZOzj-cR|lUgmGp&8H8VuAbKCUDJyAe;Iyzi9=mLu>Iya$GPtuhqn?u z-#Dju*;w1$l%ljmz&56Y>-&AAjSJTFsHg4{sOmuH^`bKq{aJ|toLFB)xL0AQmol7& zE)38xg4hZEmV>KE@c8?nfDQbnjk7KL*O`y*F=l5PZeG-K^Oc1PQ1L(Fzs>4UO3T?d z%degU+a2Ggmu+2WT|BCAbhu`8XVWK<#sO^sTix}&!f+peENt(MTM_2XjP&wf&D z5R7iaVfYrdBi@s@xU&~Cj{cj&_7=aK3H-)|pA@CfF50uwd}yor%=h}MXSM7*ssj0c z8^5E(<|q`GGq08B9CaMs<@m=+`}!Fri$4`4H()0P0HHWGP}$j^f=z&I=Tq3$N7Big z8Ap5m=m8Kuw&@`1(hlCrwnSH9dmlE#SGQ$41s;w2;#>khbY%X=mQ`t%tzVeG-Do=b zjp52^E$g;YE(Hnyvi~Z!l`AFX`9GCk%q-8`UbbtQea#fxyrGr}40d8b$=QFDT|UH0 z^yl`X%R>p+fTwIjBX2>Zw`58;3ZZ;fEU!CV8A9|*I{GlM&~g13Fe_YL9EP7ZeInIG zHmpZBaN_;d-RtW5wK9(CYMR#Hykv}d!(4O5T9BXz39MX2fgB{f2_Fh-jvt)bLMP{z z^YSr*^8ml{GwaL&=F#2seOf>V*>S#xo%6`0pFeq|TJZ@ykto8au(hwU6>;+;eU!_F zQXn6=#9I;KD+#AzBqWOJA{*LGlX)@p!uDRO&H>t_X8I9bj8poU7pD>=>|bX*u^+mi zX6OA${N+Yn+3oZ8lY1SRI~=>06P%wl&^$6qm)KO<5vzC$yLdB`0-ybIpMqgK_B9*U zCXO!ZL{ql%7j&lahc|uk^fz+Aec?@rcVTNkR-B)1^Aze=R6{4~goW6DV0~(6@H;~2GE9gWc z3`jd~MLQoBgJwIvl>&gq)BEKxiR^xLnGCuxf(CiEo!CYWsAONpY{HIocJEqG?>XFm zMYj1v8{_j43Qm#`P9sPd(FKBJS~kwSWufW&E&6kZHMg%6iiIQz?~)&N zzkRkd?_A00J*JE$%4I3+zIA{BlEd%n4ILCj`tVYMDF;MBdj9wq>(R}u1b=RKA9kPG zBwF}c{Fd7@0CQ3!sm9BvzeA{`;V#`LNPvwZz5)cvFfz(CbD(+UB=fE>jhVajIVV-j z+cn^KT8x#VeCO2@ifOTekDEib->&lF`9mcSiYA*G3+v78L5Ec=zj=}x;NEatI|{(8 zSh{pt45SE50O3po47q3Ahmq|^h5`(hw{_`0EZCc`09}AO8^*+#<_$Nmn`zp&#&Gf* z?X~kt0T(1x!+(dPLM5%t%c(g1jeXk!cAr|BwPUL;hc^!jSWJdDJDMg*>ssvqywq=< z0YPFh=<2UVBgo`-Bj|nlv$N{>@>{1sn(`w*Lib^#-jd)2i=-XYMx7d^ni8*=(_g-D zuw=>bf)g39(aYuT`HRzRs1W2;z~&tKx@_}2eOfQ9Xg|Nd>WX+{+P{p+pn-4rDAf)C z+l8Y-xZQjq8yF^t@a3g^Sal?rFBlcV>E#FQmbD`cl(4gpAj+HD(-#&MRu{h|Zy0UN zz#G;SkA-)imN@=ztHx-NuPnA#2`s8^>}?Iqvb<6p;G z!Z3e+M_*wFKl$u;ykRW%u%Z4KkiC7}2s|UXt$XsYQp^mt8#q*NhFPTDIfk;R^+iX9?PyAhLK^# z(S9#4uG&k!Q7s+HjR{aUtjp^jpx-u=8us$VbN$Y_z|8IDlh5!enBVul==N`=7UTld zn5qqMk{M5vFB_%3o~;mYK>{T|m3mbr`+CLMgU*bvN@4J)^hRKY*hUfRjR*lB?s1XE zW5O3ter5Hp1)FdFc7;b5^#}$s<9s#s>vI?Z#V2==?-3UjF6al^!FB|w_Uvz{@ijCc zY1|>f!jU1yL)&zhPAHkVZ}FEqDhoxGx6V6{?JnQGsN{=Lh!b@29}M{QQNqh7c9Sr*JscT3mM)nT1=*AXO{VdCOpZOQHkdRx355hV3_f%UvAwt+GQ2TxZND+T{bM1!D0E64pA9e{o*WEr- zKdIVq=AMSk3wzf!PEIl|pJ3Xx!fkAv`$Ji^lwGP z^Y9~xDiN5qrYk@4<#(gQ2vA8Mxe!b!JI0qkv?)Z|W9fT>8=y|vsGhb?LuI4-qR>EI zWS}tIpULo5%F}!1%*G;TN*6Ml;k6>SG3w_IBhuT1aqYGh(17;s|d@GO{+fW8>Um zru5mygPU~cjwtWmB=9?(gz(=y=lpSpW6J_q9?Qr`ZFK#&!sEiPYU!tH;jd~IC=T^w zG5o-AN|vNkqd75t+~@!R6Q+h*f86A__M`cm<*@wMyLPGn?AP~S{Z8JEA68`bAH<0X zH0@vd4%Dw-SF$c~lItSamWRHMDB#QV!#WzLC!1DJGwxfXJ9Q8$Ad^Zf%IuXgZsoO8 z&L6foHq0uXJqXDxf@A_enUX+wTKUS``XVZ0G5i6N+tZKR9gfM{l(7_!0H%qZ6ew;N zs0^wn>`;pvTMOciVUpIhhhEH~z>|$(moAFh2a3jozYG7xjaYwRsbv z^}u$9$-PZqPBiXbsXwt_edD5BEUYZCLU}8pyx(msT|3n_t)FRNJ0#$w@GIKU5E+6G zm=KQAa%c^LVa4Zt@yH>3D~&feSd%^xtd_T^bEeOLrRf`2u2`MTNY(}hYyBIC8+9J| zo8EUQn!HcM5>*0GNW1-f2D{(;uxZjzm&Af~&^{vT^hWxx>(|;aG2XaztZCLuA2o}I0EuVH?yk7ROp2nkWYdi4s( z@A0mQ#&rN6_)#=bC%U);T@p^0h0zP!&|gP%pU!Pl`{%HyRyhs z$;++0c-XmrHH?pbOq3|04zz|DPggD*R*`?<<+G>m$f-6$WyHhaq^Nzsm7Z}PI2-)_ zND$nyuy*V1Qx|rX%gEjq6{T0B7~0y66v1`*T>=T_^rqNtmE53-yP0XmYX?TvjDwX5Q_}3qLsaEGzgl z3_q8A)&<}3*@H?7Y7GtZfiKyy{wr6n_Q2oh$wN_4N4^^m%`@cD?)N*Jech+s0CK%a@kl4gP*^rM6 z^M=8M8VLNS6dWdrzx41X?tuDmvM?Rg&;LvVa)p^Q(nfpWA9M7ip59C|ZPqL6g2y`RXNgtFGPB1-H#i8AS~v z8ySvPERF9>1#j5mdt? zz(4jxrnF5UG#9ID){RFkvF7E_3!^Qb z7{Q+qN$Bqz`&oWqojNUsodm5RG)TQ}T=D7MnC+iBdSq2FdN4tV6QsedAmO@zU|plO z9^mn)I-7khs+R};S^M|MTh`)7(s@xd(ol=Wv`6m$t65o<5X9IpDe^h-`3ZFChUu`M z9{$TVGg&#Hxu^%7+mp_UBhm`kBGH&o&6-qHxe@$e+CNyNmoJeBK=y>80owN(s^1T0 zg>)iFsMT0mQQ<*?W>~7cQS+e34=57qKYx65WFIgeX|*&h64?aeRpkEU(!8OKQOA=` z?ID{MEuGR0Tp}z|tT%6HGxgpTr2ncpeo(ZhNjlI3aA7^@>^L}IZ;~S6sMeCSZo<(a zoaFjg5lNQngZg(mMRqV~fUR%tZSjX~)L(6I$FDk`w=I|o z%(_i!B&$(VLYlye_vQ8QlZDbnu3Qr7BtOba7~>~PZmb?3ZCI7|hxh>-cs0gv^7b@1 zL>J*+u-M22_?>Ae<_J6bio*PO5p;2=zcToJO}+XFoVyfbqZBfBNC)-wx$0ZFs=T}E z)#=)x7NX{DE-?}`bw9vhPP?|M;P+Uue##{&90)GLng;a{@*$V0HVY`b`~!F;>)~2tR0#~-I(xJGy+_W8k_ZtQqVf|g%?&^*Z z?Vu+Qge_VLTekLikH^txj*G(lQNf_lR&BuUiN=LL*YfNk<}mLjjNzi=^8Z zVW$UpEQd6lll%d=m^*tE{a7tVN)kU45dL5o_P7{Z{T zK=;_Dr!adoD%m+mG~@%CnPvk$;sivM`V~<^=@LLBGQ_SB4OKE! z#jC9aVNvX5a0dtRdicYtpxT44#vkz!{Ggz-AE$lmF{d)?y?6pDpu$TxuP$gEC~fPn zZcS;-)P4f*0H|x)5s_s@-fBR$ouoxw*PrK{l8{-pz z1mY9)dk@tQ5B|76qVmj+^W%3zMWr6i`9&*spOa|6e5qVAgx&W&{gwqp<>BgCC7Bu}$xfLJD>~#Sw(p!>9C|+3gwH4R^`uPD6b7P{}8Ih|-74Z|>xJ+MHjOAUMEUSyeDmXIML(?bsLVh6uel3y9Ak}pPTTK&wlgN4)KK2U-sBW@04v?ie-~V1=hvK~W{R!C% zknDKkLy*E>dhsAAMY@V=1LhG===ex4qvk;apPn_pyGis;>?}Z*Z)cU#a5?`SCM<6{8R>{sA$PZuoUpzQF*k> zZ=S#yPP7l~;qR4Y?!9o?B>sEctM2d7hC@deA{_VNgxWt+$2XQGHvtKvi4l(sa_YCL zRioISw5kC=L4;9PA-wDS=~Vf#-LkQr#N#`VSvEBZ)j&lQUJ@xPuPfmu5ZO{)WCKgP z@Oz_>>(Pan2XUIDBkE(cg7!28!FkX9JKdbY{FEjTCuHI%q+xMK1wfs>$&u^r`R-+PVEkC@Cf3L@D6nC#@8{V`(Tu&At4-wf3*cGgyq=E zbd?u~Afej*Q&Ywo#hTB!quLT5YkUXrpV_-sfmm2Geur!S+LE~yzj8PD*f&SQ&K=l* z2*RU%q#cPGmpqJ!k$yF++>xV=)EGum+=0gL3cVQM(Thjq6ucfZlI^h4sIb+re=WUq zjQ7P5&ZrQq396nH!l2zMMXFWPKZ{>IY^^y7P0dw$O}t*>}+69^J^ zKuC4w4R5NLKM=?*rw;tB=l7`d!ye}+OHb_M^sQZ-wF~%(K$qd8pEt0k^ONgmsb=@Z zmLI!!01BJ=@pRROX_lN5#+w)a?(>r%;r03FKb~Ke&+ErZ@^?7}FV&)yKXZN+3@=zT zOpqGJPYpBO%r< zK&#+?BfSw4q|lg##*`ZPaG$@kYbO7qrZm_Ufm0DwJ*c?g`6C4Q8l^@d0$L*_h!FxT z6D&g!G9hFsA|ZwN7s>gd6Hsylc12RK6?Z+6M=O}x7-C*q6xRpe7r356BX-aLkOB-T zFbs`lK**AWEltRhL_&&aND~b!Vqx{6%KM=Zpfwb2NxrNp+LE#ZH~wXaRci|*A_hZw zm*WmhbHLmbz5>@1!7|X>=hcv48YAB(ge;8!o>`k`W48lnuKh|QbqPT{tVl#Z93nn2 z0YzJqEo$;5L7^-ulr@DCJh!gIb?46HTPL=0%^jUw_3KW&szq}ug71UpYetu)5CL#0 zHI^v}necXRkr&^|Qt>ojKB|%1AL-@M)eeU(juDUeB;%4q#Q(rV{L=(DRYA5W$QC8J zBIJsid`VL(!*EekvOVTaivn=@8Pi#_sl>z2_Ob8OW-P-*Yfx&G0F9IaLxN%YytQqZ zo?MwPAJxRQ=gg$7F~p<)$k5gAvu#k2h#C}aO-)RYiu=?=eIg;f3u!+f0iLgUc1?-J zv!m1|B>9pgQxFUnV7LI;0_2O3D?*{9D3*gYJdkzA#<=6M`5g4MS9yKwAZfE<+%6!c zKuWL-Nyg3M;PC7(7IE;xzlMM>T-n9y zbv9DKX-Cy_%3+NZY{=wcI1j^lMZTyR&MOKfO`)W)3`zg+b^>A%$zOl+5%xLbRl0{W z_}RpS=ZLt25wm&xzdkY!e8pARj!&To-Tj(k0+P0%WDD#H*cC~|71X&^URKg*R?y)f;6_`D80$Gejn*$>bEnc}1?^lP@TWC5`sQI068sHHCS2 z`2r68#v6#R19oKl#YhFBHuqk=C(D-9j=Qg;w*o*uFX%B8#j>DegY5{auAou{*8|tp z_{yZd#>bHFZArW*0@@lw6v{qdIkttv_N(QD%h$2|j~y(TUB~pgT88sJ!#R&!UX#sx z%-IK6e0$dMfPYLtP>p1{sO^LAjSNm}NZ@aka zHyx}sb3{c9Q4N#ND;!57G$0KA_odvVV_ts7bpG`BK{mN1^gs{GH$Y{$cPBo$YV7*_(%2c;xh2UcD>xqD5JySk_}4CN(@_DJwndzsF@ zU`9$oPR8S%Q16n2&F{=!k;| zc^t8S9c_)FN#$6(rHofG5DF@`rgy-lr{AM@z^89e(Lbc=&u9iRFpw1t<|IQogG|BT z^(`LXyS>Em*A%(wA?N)OFqD%FW(Cc)F=7#ezpWk~cYS7Sglo^4NzX$c<=(6JWXZxX zI#s}E%7NiwN`oK&u4~ebK`y6(35DCWeQF@ypb1f-G^6xvoHUCbR*Q3@XH3bKibEG&kRlajFS#;#8Zl@ z_E<1;asqs%+0^YIy+8wmPzZu$R&f-)10H>YJ_AFFfnmj#9+zAHHo!eAvn-gEWaW(u zS$p>qzH~$*b~Ug$c1wU$6=VDSP);+Lh52oDtZOfG-%|rS;|zd(=OwuP(z)Do<(`PB zi}Xy+{Lx1GGSvxvN4F~tG}TS6{_k`-xV}Og3ZpfPpU$Gv!|29g(BQk8{z0FCjK{jJ z0)Jc6N4n17mD~5_f$J7<*nYu|^7|(TnAt1|ndA4!NeRdnAzKs-27|JT#ia|Oa zOPVu(^!7vocG$3eHTjrtZYco*nRGbz<8?gqi^be> z@f<)SM6etbK7;-+eRhE>&X~^2zuAvPv*Tl9Jo9>v`<@!){Le%tj6Z>ZLOC#RGx-2~ zCZ`$BDKc4~sEX6xSK+c1?Ykua;KXH(Tz}py5Q@iN7-q$TJ>#zXI}q8IsnRo4Wov&0 zr@Gy~U%REK{n)=KP$}3zuuQC&YX^EY$tY0kHhCL zdyA#>!W^{ML;}WbgIYtrEJkd5LADSWIGLPJChL>Sf#<~d@$b4gbe|N*9$dd$629?; zR(^7C7yUho3;ugE`_4^pz=9e8)_2+n1RBj(uiLI6iKxjLM>lciG0oijL_dDnfUwU! zPxP~)!{!ew2N8A%SziLH$`xnM;L_8kjROvlD|&qT!Zk!glCwWuN51S43y+s?oCXxe zz-w{^MXnHlAI^DXvL4yIhp2=Rl`yAVwVo|K6StLjx3DGo<_S|UA{t$^IO@W+tb92O zz?w}Z!kEN6>WFvNF~@T`ATh)qp+0W?(*R4(dXPiY_Ny#zB^&6)F1v?<2P}by2qc*-Gn^O$u-LWl5 zRkPFQ{_xID9(z8+ z$M;O5e1k$+Q4=#LI*RxXD`AX)k|QYE0r=vGLsKYea(SOz!4E7vs|pbp8TCL3`UgA? zIrnv*Td|mFO%qAj)a`J{Ij>V1795=J;1i#F2`S)zR(+Hg*3Cpmd_se9mfw6ipZV7O=CVs};gwhRX65RA@um;s8XhMsYve~?o57r^(VYSZ`0H~SuKaZ;ZHXjd8Kz`I z*%lOSP02ARSNyTa(ij0{M^JX4ScZI=F|V#rROE^-!m6T^MLw}lEk`V^<&RGd^46vj zz5N~^`}*rV`^$+W-0=G@N(If`mtW6kk6k(T|LyJGQsGY)-mjJ%$@5tMLxasSgpI90{|GukH=HWG1YZXO~xoaEArzJu=@6Z-u2uFoNS$=1FK zZ+F?dCE&cDZenAngUZAaN>CmFU#r@0zRp3-5PE~Fvpi&h$6&)}%(%H5(Wk*r6 z{a|$0#PmX3eDfAIblR-lT;k7vAH?-Eo>nMBVGYK(?yfG{KD(N8u78J6Da6*dr%fts zS7$5T9jyojcdj^rPkrnj9(i!tSfKQ>?_R_|p52egPz+r*IPT&%DLMX5!QcK!A9p<3 zhsq?t3&<=xDo}ZQJ2s~p#1N`(K!6w=9Mszep|elY(W~g#rs(K)Y47&v=&sP)UqvX8 zN`T>EG#07qQ9%TjGErrT@FfBezCc+XM%5xb9KomG9bCu#*X@Pzu8_}5>x&$6 z?(2BjFtQj!3s6#{B{Zc?rnZ<&YZ0_H3#K+}rZo7prCl0RE>df#dV)$-<5V=&s>Z28 z)zwrgfzu%X3bq~crWT*a16 zfhIir)B$|)$Xhx2lzMJlq4?zCibFr4x$J7i&wlBX8?NEa*XMKP4{l=Z+efi>!>4)U z<v?yB-ud!C+*4Tg&_eO#q5q+ssUDErJyu=gHO z_L>o6ubDCCPK{#i;AChGcRtp~`8RCB>kg6VPGSf}Q{xbQ+Zr*1U`?k>eZxdmKIL-; z|My&lwH-$iiEcNveBa=>FWtyfy)!xJBQ=yOnm67lp_E2cO^iq&V{1c*w#HCkE(?LL zG#fk1@+7T%}x+hF&sA77)!1D#3r*W#9S2tyNqdkLN^_ej(!Xb-lS-MvZ zOZTi{-+2k5;a!Fhf`uXA*hA{M;J-H^dLz-CZ?Bi6QiVy!tgX$VErp6#F%7|q%hG)P_||a|sk8MS9x(mmD7)mA%pllI91I{8;1GbX;ZoWygfb;cz`<}?I&J@-`)2u4m$J| z0IZP94YysvygfH_`^^(IY31XBTW^vi5);E{08c!52yRP}(~oXq;E@Bl`-=JR2|Pg2 z_PO~l+gNbwORVoKbMW3_v;tG>ARsYRaIq}O&;GcL*=tlUamc?@toc-ArzI1pa^~v{lf_CYOc5b+P8{a+rQ7*gsrU}<8PMCvd zJVtgP1%Q@N-#kRiw0_z*Pa{{1QBzxF@zOV`OJ{kzvyGQF&&G?opn$q6p(tE>`ZP{G zs%e}FzO}!?s@HNn{aTJEU(B+l$02H&G$&##-Xp;tZIWrting>zTZ4<(+%crvd!VBa zwsb4nyFJ!!F0yf34qMp>0mmFv&zZ+GbM!&=5ow^#`x^Xf8+G??`5w=K|CNcRLcpUx`hoJW>Za6skWA}<5l7j$)eeD zHguNB6g({708`;<&5V`^<%*(cdz2j&9JMPG*EYekXlsZveTqR_vt(L}U}}@k)O27A zm_mY-qv!L%Clw9T7_Mc@)-b|yd1O_A2cOMQn~Eg+khOsIpD&mt)SsZm>E%!V=K&&&#$L4P2&`-Wd#kN?zYJXmPc>z+v z({CNmj9C-I=GklwbNBumg*}GpefU6{>L$LBeWh9PU@zbM56uK^-wRS9fn+D#B>d|*ikG2 zK7k=ee+TI}(lQvy$q7gZTS1&Z95#rI8a<=Se&kzJEzE2j**0ZpD$$j zd3zAD1gBrK0pAwrx+>YZLrh-?-#@2~-+X^Amz+8cdrFDRfA9@FZ~U9QP>8eQ=chnj zm17Uxeax{TWwGKrb9rd_-ozVyWNQv>dSkMNLxNC92AHgoiI&@wu}mQ#WNN}8NhB-? zg#?jMaC{XG2ip>w@kvS}hYM~)882aT+ELB?{6A(>6AQpR@xm~x*A~^K#iPgibe?7#B|8@&sJO6jIP48iA#}t10pI_t6clN;EbATiEAAd@`t9INW z^{l;XKTfz}JukkMN9AJZYM5|X5V8VHmIdJugscFw5F_5;P)^X<2kkwY&R$K&HjmD3 zmyT^!I=URRPw*a4BQZe*I$cD@U4D1fe7^9>@h7_bpYQ~=>+c$;D25m z=2I80rFLTjrfuR!J)8y`q8_SZpz0kC-M5y%{&>NAGQUTguQXTwx`S))>Owdnrlx9{ z+H5eTSunL(Ftth3miCy^;E{^EK|CNF(nP|7Xc%H)h(!d^s2~=R#G}UcSr>o=-CQ7) z@_6!RADICDrS(N#-dMypeJ(j|>ZITSj$B&DqFHe&EoHO>dv>1mo<1jjp$=_m?R!Ig10K5r9w33Nz^Ky{ly{> zSQ80pBB3DnaEt&c0(RojVD@8CK|Cf�_d<2H~&(sgda-4QavizuJd==S@s;DLaaL z9`8p9%{RW#N-VN#)iorTBimL;7-JbFd$dM);kJGG#FARHRIJ%(^N~|u=9UL~b~)a= z+b8x(@!Tzo!SH!{eJ0R?h$b4+W9O1%62>B$SOgL=NXDQhE~tr1Y7&xE!a~-TNH<7U z-?|U;r%xWp{Nu_2Dy~KY=N&&~w*vml&L>U??a$MXm88>+BrwjP{@h!N*r&=`l z#!uhj$P3o6^5rZYy_K;nvt6}?v*SE`{ob_qJG`*5IHK*_ZyYo7;}K0Fs;P-d5^)0X zaYZU=(2>a@T$hKI@B9#?>T3S;?yaEVgk=poO?DVX-kKg)fQoPTZHM&;T=8^n(8cSVg^h1 zs^Q8rr*qBiot*edV_dfBI4`Fr3NITZ?Uyo6Y8l)n;yzk zY|Z&}wmUo_zlNpHsEwa$J{KC+3g zAK$uDK>xQU&-K6SM!J$E3!;2SxZuAx)6wHVMDWGK(&S4XPp&G`mvI@)xujDQ zt-pn{LNq`>Nq9YMW zeXT({C22`pw4?>i4Vsn)MRT1`YrTgM{S4P2 zt8@)iSl?;$)XQ0lwvQzZyt0X?#KH1tY8E>czG(aW{LkCC>b6c~)gqi!Jh*&s!j`11 zF@&ppBFf^aSF$@DWB&9QQV6uApc;T5wNDI7kghkVOG)ZdlG>!8E(x_Yn%aaW759lp zCfXB|MmlN}Ff}b{Oj`Wn{vLkuKre}iLBurB%D}9~G4c|xDo1<{ji@d2?Jv!ka7;ar zb-D4rZQOKUHzix4^ASYK;i|999CLIcps;`}de-zLK&1jup} z&#iFjigs?hWbUK_&u)v*+vSX#`Nn#K#(IN>I!QyVAYChHNGa+@X1^|>2wU%i0Dx3N zGjFOvGHTG90gcA@w*)=U$c?>R}DcvicyRpv_KK~ z=u74&2wU5Yq)`pfLZgOa-2O-(-#v9Ib0;|lpEoVS^RL=?BWpfAGV={}lEykoLkj9s zn);-szD7}(@TrOUlV-Q=k^q2)l*01`z7qI8XgzYCCQJ+&L|H6Tu+`BlniHJfuJ0&w z{H5!7XR8C5B%)%DtW{tn0Q+uXI(i+X6lg#=VGJC8c*j=m{QkTNGR>M2#Rv@%Pa4$M z2A_sn5qwgRu7h++(~wluCw=N_cAY`KO9G^ThNMDixkGNh9GUSAOttH7x$e)C8l z=l$dz{HlSUsX-_ME!kciB!WLZL*sLZfB8T!(y`D;klX&e7jqiz!Sz*Fx`* z*z6V}{N}HHTz=|QnjH+~VTF_jl$F{oBxBY0r#O`MPeG@SH@Wxt2$P`3ILT7=CDXEER z5-~ASG82F=+G->@K~r@#)vCgE!BzF-s%5m+#LXy1iySMNF-=Vh8(LX(WCe{IRkyIV4@#^P+zup}OVL^N=vOJzyE9Assc>>%xCH0Qwe z0u2Z%#!{0OO_^p8l#PU7ica$I%XuDrW@s$(^wRnQ>6FQ=R;Y=oaYa+_b=E&H0T38V z&2^f1WYm=wB;$b(k+KCPTjNv=O3tY22M4g8uXkHE7esG0;gG?G-WWIiX&ayaL>jH( zfmIpiw^>X{`(tHu`kz5Q(!_^RJFJwRP&iq#N3*hYP&!*3t?3EMTY|#Lu@QGDoYZ55 zlOYqf^x53_KtG>4pq50;;Gt)SxclM;7R}nezkU$;KNJFX{2ncxEsfOkI2BFB4N`D+ zUOKC{AI*)G&N5OutJ%DFxq@IN&p{H@$~z9{{Q#t paVdg#LoB>~nS8MF`G1X^{|^&ILeth)ONRge002ovPDHLkV1i8y@_+yU literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/msegui/edelweiss_bi.svg b/mseide-msegui/icons/msegui/edelweiss_bi.svg new file mode 100644 index 0000000..e55856c --- /dev/null +++ b/mseide-msegui/icons/msegui/edelweiss_bi.svg @@ -0,0 +1,342 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/msegui/edelweiss_biround.svg b/mseide-msegui/icons/msegui/edelweiss_biround.svg new file mode 100644 index 0000000..e2c1ccd --- /dev/null +++ b/mseide-msegui/icons/msegui/edelweiss_biround.svg @@ -0,0 +1,344 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/msegui/edelweissgreen_24bi.png b/mseide-msegui/icons/msegui/edelweissgreen_24bi.png new file mode 100644 index 0000000000000000000000000000000000000000..ccf50980377ef8b44bd1fb5137d0910dab972aef GIT binary patch literal 1754 zcmV<01||84P)zxlM)j% zjTx1WZK~rqYHdt9HdE7fnp!3?2{wTwj!hadLEDa|qtzOuF={kk(L)q9K)Az!0~`*V z%RYOr{$NI9(5{*9$C|ZfJwM)WeeWx|TrMGm;JalQ20{pedXWAh1+QNr5Rxzq1G8cf zW;Tcl3yrz|-BNkL8uCdrxfJ#`zl~pV5o@eRB_1IpEV6>2mD}2Gmc*=LPD(0vvvJ>d z?g7;IeT6UN$F9x9*)6!~F$gLqs-E1%qN>d_YMTHBhw%lA$2aqQ_8MM4-ibeu!Q^O} zjQGG9fc)*vsm?RBXWi)9(zRQ_l?S6$z5 zQIDaf-{54s%B2?T{|7iivxv1Nuzy7vi>KTs!c*V%gkH#!ssNAmdFwf|z0P5fr=S}v`AlXaO9 zyn22QAtS_^>C1?gdx*2g0?_1jQ)J#vlJXJf=;T7M0$;R~75UF#2>mW#$S2|K7F_WL z`P`GuYv(@%Ktkfr3w}j}J%J51f5a0Q!XqS>{c9`RPQFUV$N&@U23A@qO+LoqXJ2GP z(Q4j0bAX)ixpzfw?2)+X(W%$`gk&G(b!SN%7sv7`j{*=hMrgM8vi$f1V#TH4$evXcCxfYw21^lLNuT;^1g%q=!a3#Q;X-UkUm5KQKs7V5Yk*o z3Ru1EOgp!cv``}g9@<1?5Xoyrr_ zzNV|~I51}vkRC6X&^<(;@#p|0K9SG z177>;0xMFB>GlnB&h5q*@?leLJQSV?9R?Ul8CpaJtUK z50W#%(4azyJ5Qp0(Dy-dD7>wMi)@f2;%jz7qy?B?Jjm zVkT4bsv>cy61T&`q1j(+|HZEHXS5zu5R52nzPOPK(Njzv@Xu({k7=joH6d}T;L!z_ zIuCL~Mh+7KLvd*GPilWHfMvs#R+WY@G<8{=i5=s=X07FKcl;AYX)loM0}z;24Xw#_ z%&)kMS5I%mkz7l@H_5Pk2an%6nM*y(Id8l|13_AoIh+Ze1z=Oj;id_IMQ&6xIPd|Y2%{W z&1u`9I$?3LBgC2uYj~$^Kd)Wgg^k@Gz_Q_DP;j9`BII$ zFsT(5mTLtwb}r`F{2gSw{e1?L3P!Uh6leVAnN(z#(2_BR>E$t;t~Xis$p^H0#?cx6 z3~#uef1mIui^trDAaxIyy!`{T?io1KhtXrkacI4PC>Rkmb=ou<7FX;ZT-Li3tNVyp zf+^d+$Hxoaz^%DC6Fkf6Q@eO!h7Q8TQ>O=V-;gW3ID8iXBeREb{~NGm)Ks3DuoRc( z>H}Y2wT%PUV4Uk#TH-eCof?5mBL&bJgJ43^Y??G~m{hGo%is)V{#0-2!o zn1YT3gbYc$ZD9$E7X419Zhw$WmlvTrxR^G9+51`R&~E`V!u{XCneZI1%RVJ&)0p_9L()9k!&ygovTgV+uq~T}U3Tl^kv{ zIMm%rbMhE@$|rbe#;t33be(`VmqFbrlzG z`Z@WIC@YRn;=(02?FtbXh zux#w#Ga_erpU$;t0}J*nWnkMJw4?(Aue=$+Zg-`9_vuGh1*LQGW{yUWVOZqgr%r5@>^S!)U^*YkXVPyJE zh!f}A<@Co?u9JS)ZXLEtVgAhTnEZX`i*JcT6Ft=4rm=sb{Db z;?rmem!f_Of}at)-i9d^q!FeleITWoH&7pGq&{X4wk9%8yPa>Pd$~D3fjC{$E)QRp zyx(SUC>|vwE|O>MX0W@PB^7s5;K^m#!Jp8D0;#6x>m@L@#I?wATPAFNEW3?~zXgNZ)L_&@^9r3+jdxP>51D1_8O zw74FnMU8Os%FU1zcohm`Dg(NX@Hcray!4$H`wV~d z!Se(>nGDSy(l=&Hn-xcXjumSq>Pdy;v4ILcn!BBuyB9I{-Iqz@KXEG-9#tjX;iS}8 zNKr;Er@OY}OPdU6DFCM~Da-&z@FE4?_t-XbGaZQzPBd4sCKh|$GD-Qh| z?eQp!huy)}+TU|FSk1`X5#)Jt*;e^Hx9nL>gL@GqHAw1|bZL0I!nh;t{Nv!&_?&wG zw7fXirs>@O($?L|&Fk+aluYBg989-kB<0#!W|T|?pfT3OBm1A>M0+z&jbFr+qDgGM zQpdBOyuy~s=TlmlML4atUgsJGmQJanGu)lejs6^NEQ~{MM$`wOD)8jkrBpR6AsHaGZ96d~!YS^8(ic^Mj`EP<2)aG-Y!YLY>U(#JA!(;TXeadf8r zD+n7^I8lVc>0mY8b{-wdDAs=Z3Qtc;ZIwq=DKlM^C@Mpo3PXH0W!WZ~o@Af%F984q zvTURjs6yaWbg;k8Q}4b^M0)vxfH5p<&kwn)fJ#*u)ga1JbCkCoT`&_ z)j^R|8SGLi@mZ8*o8+eVcm9*9m} O0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/icons/resources/dir.png b/mseide-msegui/icons/resources/dir.png new file mode 100644 index 0000000000000000000000000000000000000000..7a640f58604fd4dc8133a942207288b721d45945 GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|I14-?iy0XB zjsWp%#&&bFGN2%PiKnkC`)x)6c2y0=*s$L~p?FUh#}JM4XD2!G9Z=w4DfjuWYrlND z+rovuzWPFk8!dFY9~G^2xt#QeVU2W>%G5IC5HIqD`9Vmi?(S ynq4k`%}xC{ZHoL%sT(eedk;@PyXpROYewBQW|F2$d^3PnF?hQAxvXe#t`LoJ! ziX4PI4O2g?#^|Oi)B3w szemlkd$rFZ@rV~mj5nBH04nJ z@Erl-*NpAvW@SLZDo+>35R2ZslTY$BCrer53XA1bKAR0Totpe1G<92)78&q Iol`;+0OI0ETL1t6 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/resources/diropen.png b/mseide-msegui/icons/resources/diropen.png new file mode 100644 index 0000000000000000000000000000000000000000..51a176811230b46e52c76cf61ad93e5b10ee41e4 GIT binary patch literal 226 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|I14-?iy0XB zjsWp%#&&bFGN2%PiKnkC`)x)6c2%Q4_UjvgLM5Iqjv*T7&rWjWJFLLNlK%VS2jh8W zmJ0+Ng|B>>BKj$leY2Th9dlRs@o3o z28x-j|=>ZaUGp UQ7!)S7NGqMp00i_>zopr0Of;GzW@LL literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/resources/diropengreen.png b/mseide-msegui/icons/resources/diropengreen.png new file mode 100644 index 0000000000000000000000000000000000000000..df9128380cf549fa167096e0f21991e05cbde889 GIT binary patch literal 230 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|I14-?iy0XB zjsWp%#&&bFGN2%PiKnkC`)w{RE@Qb#my>ybLKU7ajv*T7&rWjWJFLLNlD_z#^`D;Q zzWggpR9Q@IuR7U9Y+lpbd1CI39g_RGPQ^L>(yZPowB)QnQ-@;Gq}4a&glDbrlrq%V z9#?x=pLbE44~uf`iDdt?8}DzgQ~G#W(J^c7<(i@fQ{A<_>;5*0@mEJ|v(tMw-|oI} X;J2#dIxLGpK4S26^>bP0l+XkK+1XCV literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/resources/diropengreenwarn.png b/mseide-msegui/icons/resources/diropengreenwarn.png new file mode 100644 index 0000000000000000000000000000000000000000..c11fdd89761727396861ca350ea5d27a9d3af3d6 GIT binary patch literal 247 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf4nJ z@Erl-*NpAvW@SLZnVv3=Ar`$$Cp!wYDDbdYi~XNA|KpaM%*R-p*6j#(3C5nfjEZXywIb{--OC_vAg@^MB0|6&6tkg$Fm1+-@&ic}dl$b#3N(oi}eB z8)gfL9CkV&BKPML$3mw4s#Wb3OCk<#)LeR}YPOQYJC3PAd3X0uzaaU6ZCb#8KDmrN qUaL)Y&N(^%x8*)Lxgq@VA4b3HlXqPxtg8k(lEKr}&t;ucLK6U6W?TIL literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/resources/diropenred.png b/mseide-msegui/icons/resources/diropenred.png new file mode 100644 index 0000000000000000000000000000000000000000..81feec1fe064957487be76c5ae80161f0e0b09af GIT binary patch literal 213 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|I14-?iy0XB zjsWp%#&&bFGN2%PiKnkC`)x)6b}hCjVfWuap>$6d#}JM4XD0=6H5l+X3$K5BylS(o zZk@>L#bL|irwJW95gjGL`p{RmA~K#a+s)wCtf?&u@y-#dJCD`orIZ^y7Z*0zm4E3} z%LOKn$syeQoOLhu#=qh?vy(sJl5Pi|K#fGL{=fI1bJKY)8~7`2`U|v@!PC{xWt~$( F69CoGL~#HB literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/resources/diropenredgreen.png b/mseide-msegui/icons/resources/diropenredgreen.png new file mode 100644 index 0000000000000000000000000000000000000000..169b50a2f7c7c5d3a3a7dbd4792819f80005765f GIT binary patch literal 245 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|I14-?iy0XB zjsWp%#&&bFGN2%PiKnkC`)zJEc74XSLuUVhLhYU|jv*T7&rb5@Yc}9k{aS{rW?f=c)c?1^bNiH7g@M}3ngv7lJ1(d)~N1T@6xd7thMd4@^Zd% n#BVryRZeg1d-3o7^WU?o$4yD%%4nJ z@Erl-*NpAvW@SLZ#hxyXAr`$$Cp&Vr7znUrABlgy!2a~*EdDGR^HZyC3q-X@UDg#| zlw-7G>5YjW1%LcqIN_n>&FmY?&VF`bX*WK9`TXn_B^`#Q1HU|2b}kI=oo>J_vvS_% z#I?}ysSG-vN{?HCzrnt4A*)4A#bX0fJ^Z`1T!PC{xWt~$(69C38 BV>|!= literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/resources/diropenredwarn.png b/mseide-msegui/icons/resources/diropenredwarn.png new file mode 100644 index 0000000000000000000000000000000000000000..7f7148fd349f5462f2ba8bf97170308546543b42 GIT binary patch literal 228 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf4nJ z@Erl-*NpAvW@SLZHcuDF5R2ZWlfC&G6nI?Xd$*S?D2ApEbuwlXK>A9SLC} zJEK|0{7&CV-D8)M^s4w?dQp^@c3Oy6=3hT0MNUSc?j^;C>%=?Fi#ZFAHn10aFFMci zw2x7Lqq42qhvIXVcghbm>}2Yhp_;E1y85}Sb4q9e0Bzw*BLDyZ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/resources/diropenwhite.png b/mseide-msegui/icons/resources/diropenwhite.png new file mode 100644 index 0000000000000000000000000000000000000000..2f754c56075bc01d50959561683ed6727a230105 GIT binary patch literal 220 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|I14-?iy0XB zjsWp%#&&bFGN2%PiKnkC`)w{RE)xZr&o2^yLV2Dpjv*T7&rS;DI-tPgEd24_w=_B3 z-vVp2SD&d}+p$7r+j=iYi_WIQKe9HYu{__9HnXw0alsP<6=O3lu2(N5yC1BHd{yas zqKqeYvsYgGhfiJs-mmuBpNp7ztZu!S%8A(@+;mUePh{Rz*7^T;jd*NC#jb-TA3*MB N@O1TaS?83{1OQ?5P^tg` literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/resources/dirplus.png b/mseide-msegui/icons/resources/dirplus.png new file mode 100644 index 0000000000000000000000000000000000000000..56082e732a9343aa97ca066bfcfbfdd68cb507fd GIT binary patch literal 224 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|I14-?iy0XB zjsWp%#&&bFGN2%PiKnkC`)w{RZf2H^rpGn`g^D~~978nDpPl5$$D}C0vbyJgT-`l6 zlhY1vkB@Z=A8PdBz02EHurx1bjeJ8P&&Qa@61opwI{GjjbEBi?VF#TYm!gPGy3eb1 z%p3BK8MXY;id&SoNAM>{&Ss{bV(G&{2iGPQ+iO0ty(9bV{fCrIf8KwVU1}7<8KWaQ Q6KFYur>mdKI;Vst0DnA89smFU literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/resources/dirplusred.png b/mseide-msegui/icons/resources/dirplusred.png new file mode 100644 index 0000000000000000000000000000000000000000..93e8011b60ebc6298f9fe8654e28f05be5a843d5 GIT binary patch literal 209 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|I14-?iy0XB zjsWp%#&&bFGN2%PiKnkC`)x)6c3sw<=!Q0+P_n0sV~EE2vq6r04F(+9f48-N{9L7w zm$2>SB6iQitXxYQn>GkZi#=vN*d@4TLsD&<0y~4}p?8+klwPc5Q8!v-=o=(ce=;-X zvaprfCj&c$&(RtF?hQAxvXmdKI;Vst0KD8n AjQ{`u literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/resources/dirred.png b/mseide-msegui/icons/resources/dirred.png new file mode 100644 index 0000000000000000000000000000000000000000..5932ce3af5fa43b4b372a4f65152c557be573635 GIT binary patch literal 202 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|I14-?iy0XB zjsWp%#&&bFGN2%PiKnkC`)x)6c1}DUnC!^1|JRPo>q~`)vC>e7Bj?>Q^s-b}@Lm`njxgN@xNAR(nQx literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/resources/dirredgreenwarn.png b/mseide-msegui/icons/resources/dirredgreenwarn.png new file mode 100644 index 0000000000000000000000000000000000000000..e9712c71342734f9414ec746962796ea43040e64 GIT binary patch literal 229 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf4nJ z@Erl-*NpAvW@SLZc25__5R2ZclTQk@CxTFw&f+tMPO-MfcstXM?5HhKnq8#8nIn+Er}FgOB90diO}`{1MwE1? zJ4@T(67H@QWBzmJR9B=jNJ`hBPN We}?ZJJas@PF?hQAxvX4nJ z@Erl-*NpAvW@SLZdQTU}5R2ZclfC&4C~&yQFWdgkDc>$Or1#76ZL22<1V~DlCOa`X z9NRE6OKRD{rFO}OWIp9AoI5Y*2+woPqkO^(A5AE}CiVJWZ!}v{^Ld4zr518sUk&H6 zS^nbvy1Qb}r2GqvyLX*t+n*A!|Kr>6TjvskxOsnV7Mpg7QzAT7`8jWopr%0KtNR5& Pr!aWB`njxgN@xNA;7U(? literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/resources/dirwhite.png b/mseide-msegui/icons/resources/dirwhite.png new file mode 100644 index 0000000000000000000000000000000000000000..72ddfedea333ca419ae918fa7b35a0fd81a32725 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|I14-?iy0XB zjsWp%#&&bFGN2%PiKnkC`)w{RE<>gMu3Ao@P@t!aV~EE2vy%>T9Z=wL{@nII_rJ~V zo>vEZI~CgIG4-1*jJVdL=bOdYA=NQwg(1rc9**5l8QVU}iGM6~^Pl$Y*Vc7)x6e)M iWAqYZ|HEkU{%0P4hNPU4nRztOa0X9TKbLh*2~7Y=JUvYS literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/resources/file.png b/mseide-msegui/icons/resources/file.png new file mode 100644 index 0000000000000000000000000000000000000000..6869d76c4b6d38036c33951bcdc6a793f8b934fe GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|I14-?iy0XB zjsWp%#&&bFGN2%PiKnkC`)x)6c2&I>cAw7yg(5v&978nD-wis=cff$7=@@_f{yBFe z%%rW$Wz>ZavU@qcNLbKW;PPQ&v{}Ejvv{-0!8I%0CQZ4WS9W5S#toId^U|eVbD0m= rJado!uh6lye?3dno7mDh@2cm|IIJS?(qa7vXbFR-tDnm{r-UW|FNi`6 literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/resources/filedialogres.png b/mseide-msegui/icons/resources/filedialogres.png new file mode 100644 index 0000000000000000000000000000000000000000..e32b496fab296eefa2ea8ce28bbc821b2c146834 GIT binary patch literal 488 zcmeAS@N?(olHy`uVBq!ia0vp^`+!)Hg9%8!P-}|;Qk(@Ik;M!Qd`E!zHDkNESs4QZ z<19}X$B>FSZ)XPfH5>4_9A9l4QEfD5^2OPe_M2L^T+rGWWa;tQZqce$s~Rg?SQ0L- z$SP?mmUv@quW*F*s-oWtzCx$c4&hbKa{^=^wY(Bg4{5j9xy@>omgp*}xf$+!F6vS~ ztF4NsO$jn;p83>psmR}x#{VWsoS1Od{ciH~j+|j~jt$tfrA}3+0@2i}8t>dc}d0X{|_?-%w z(w6iVXy9+7%5#&xC5t)QE{a;wruOG~>RsWgS^eqI=5yOb*$deH+^Rme?XoKkzq#bxH-|;{F513*w`hUPUYXT*#NONuEz3RU zDL*;qU7Q5aRlMC_3?Ft++!!!df0K@PNsE5bTl42C0w{sD(CP>$N_hTZT*&MAd$yeX RCt%buc)I$ztaD0e0sz#T()<7b literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/resources/filegreen.png b/mseide-msegui/icons/resources/filegreen.png new file mode 100644 index 0000000000000000000000000000000000000000..1594712a8815c4351ff4155f681a476b23685322 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|I14-?iy0XB zjsWp%#&&bFGN2%PiKnkC`)w{RE=#5w+v_KRLSddRjv*T7lmDFmFuzgcz!3+fgvQMh zk`fo6Y=}D7vW%s1gQVjL&;J`=C_Z85v8^yQFme!4ew}zI*=$q2l(f`Io@);mG_u;t obYA~3|DnCjn-52MSDut+n2{o?V#gVC2xtR?r>mdKI;Vst0Ifwo)&Kwi literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/resources/filegreenminusred.png b/mseide-msegui/icons/resources/filegreenminusred.png new file mode 100644 index 0000000000000000000000000000000000000000..c2303ad97f30fe8939da7363cec7895a6ee78e02 GIT binary patch literal 237 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85sDE0P$`sf9VSU$eU%$_MR`D>Tu&Fr5RLO| zgBC+oF bzpiCUYgd<-4yslKTFl_->gTe~DWM4fx5QI< literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/resources/filegreenred.png b/mseide-msegui/icons/resources/filegreenred.png new file mode 100644 index 0000000000000000000000000000000000000000..30ddc026ce854c2fb8865870ddaca842b5adb51e GIT binary patch literal 202 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|I14-?iy0XB zjsWp%#&&bFGN2%PiKnkC`)zJUE4nJ z@Erl-*NpAvW@SLZW=|K#5R2ZelLPq4nJ z@Erl-*NpAvW@SLZdQTU}5R2ZelVkZB6nL7W5C6279Mj2tjonrDL_Cjg1>?7^r;WIT zCb{r*`ghLOI@7y?d%^+HbJ~yHB_7tPHLl38tN5js@_H$&Uxse1=!7}d0^xC66PM&J zzwH!a!p`7y<2a-3TIMH@=de8qj+l0!(P+29E1m^+SWot4O!$~Tmw(E9vyG=5y5xaQ OVeoYIb6Mw<&;$Tio=aT- literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/resources/fileminusred.png b/mseide-msegui/icons/resources/fileminusred.png new file mode 100644 index 0000000000000000000000000000000000000000..c40c13ba65d13336ead942981ad8a4f3e6c6f0a1 GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|I14-?iy0XB zjsWp%#&&bFGN2%PiKnkC`)zJfE*Y!NYZp%fg%Uko978nDuMLXkJD|YB^!VWOlQ-q7 zuUs*mtS`K9=@yX|E~%~;b%Hg2eP@4XcNT9}Ik@7aj%Qb{xUq|`{|yz}d3(1m*~XY4 z^SFG?H^J)Ms5@KkUAw&F`43Np6E{;&ublUt^W+x|#ZB*Pm4TKqc)I$ztaD0e0suW3 BN(uk~ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/resources/fileplusgreen.png b/mseide-msegui/icons/resources/fileplusgreen.png new file mode 100644 index 0000000000000000000000000000000000000000..dccf727b34cbeee11f17577db1928060150284bb GIT binary patch literal 215 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|I14-?iy0XB zjsWp%#&&bFGN2%PiKnkC`)w|1HgndwsmrQ>LYbZ}jv*T7*9JNA9Z=xN7MHV&zbAVp zLgctpjK9h@5iOAxECL9|E9ZS@b-$#c>A!|A0B9+Lr>mdK II;Vst0Q2HW@Bjb+ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/resources/filered.png b/mseide-msegui/icons/resources/filered.png new file mode 100644 index 0000000000000000000000000000000000000000..58dcb7be0f3f6bfba3e08609268379b5f48ddb18 GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|I14-?iy0XB zjsWp%#&&bFGN2%PiKnkC`)x)6b}f0kiucw)p?FUh#}JM4cPCl%9WdZG+&jcto&R+UCdI zy9ZgHC+npN@kwa5GO;Ee<%j_cG`@-a5W?7mqPcK$ch;bW>ROy`?i Q16t1D>FVdQ&MBb@05#Z4U;qFB literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/resources/fileredwarn.png b/mseide-msegui/icons/resources/fileredwarn.png new file mode 100644 index 0000000000000000000000000000000000000000..cfef49423a8ac8d5e25128f3af1692452a58877f GIT binary patch literal 230 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf4nJ z@Erl-*NpAvW@SLZ4o?@y5R2Zelkf62DDbqbZ)=Tdnb>0>)NOI;r-FvPlEfj^Jq&-V zrZ01vz_Dn7_opc<;#(_~7qYVyvP~c!G|MP$T z^)Q=`SvNeL9lx>MzV>uVbOHmjd-SA?T;@|jU%n^YE=xGqz+B%x@GqaKu4LA(EMU zPUy|!2FWL#Oc(bVfP%tbHDz){JgvT{f1e)5)L-~YODJ7n~|xdrR9Rl zg*%-`+sZu_tY6=M%de@0lT+&6-s{XE z)7O>#9y2?SxM0M-6Vre~vY8S|xv6<2KrRD=b5UwyNotBhd1gt5g1e`0K#E=} zJ5XHR)5S4F<9xD@w|DXZww~VJja|lu6FA&V1(+iWTEE}iobK-2StrHt`yk8Pm-k#l PL1uZn`njxgN@xNABo8ki literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/resources/mergepending.png b/mseide-msegui/icons/resources/mergepending.png new file mode 100644 index 0000000000000000000000000000000000000000..d84dcd813e82147aca64524f6e67595840976fcb GIT binary patch literal 190 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|I14-?iy0XB zjsWp%#&&bFGN2%PiKnkC`)w|ME?tIh=ZQ@~p#V=8#}JM4SA!h67!){eFZo}8lTUEz z)Q4-!0#k&|mpDyqROn=9T`Jo2*~DYf8J&`^^_qn{XQj(OlHFaW9kAl&35_txgP+ft iEt~!9*Pb)`%2^j&5S5bn?hpwyo59o7&t;ucLK6Ut`8})v literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/resources/mergependingred.png b/mseide-msegui/icons/resources/mergependingred.png new file mode 100644 index 0000000000000000000000000000000000000000..3b3575ab2aa64a8793e61bd34f816b1ba00c2f2a GIT binary patch literal 192 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|I14-?iy0XB zjsWp%#&&bFGN2%PiKnkC`)w{sP6mTtExxybLP4G`jv*T7lmDFmFuzgcz!3)}i595{ z1rcRt9@}_;i}5AnCN8aAP@*sUQX%*@Z1D};Al~ifp5|C#Ihg| z4M<)}T*EEnDAV1G;Ognch^HytJi!_(9=g4S6U(!-uFyb$O)zFxt3%_bO-K+!)K;q? zX2UWwGpO<_OacBEVcS*bf(IcgqIldxD_ROpd~9GwlhDP3S#^S-2#-*@^_%K}-8;9f zxMe|+hxu>b+gCnqqS;SD1F09T)}u|>%eK1RffBhj?~)z?t5WAmUqbgP@E?b(eLp#6 zGbg$X%pMwwGl~XOdIY(4Q1_Ij@fSlWZN)S@EG!ppAx>np6;^S>+?LZ!iMJ>(?N*5lyJc_H}6EW8y7j*3j z#==6LWhM2hj+E3hMO=9)CgWtnnS|Smqkt*)ILn=2%}FkgO}-AM>($f*#(Cf?i3UD5 z#@6X8=JVgLQiaQa-yC$#dk-R2&3ZQ&}O_fcVwYz z6oPXeVUs(eh?v~{s;V)vKKY(K16BOwm=+cL*O>L>P+i8W^|L5#*ZjgfD$0C`(}4uZ zpd+*7BM>MkROhsRi@R7Xf5ZtJ&n@KY6 zS0#rRdG(al^|GBmc??-USGqHWa@861roW^|q)@ALP{te~oD_GBo5`MS6blzNuOR5s zA2rzrOVmt|hmn!iniQAzE8J z!7^QHXK1doV4ZlU!+jX-Z7kUtSe7O(_`M)OXck_c=!P1Hozc z15<|%nO)n$gC(zC$H2^!gWu@nmp142lWT%qi=)Zis6m7bPUOB(djZe!aB{l}5bFp;nR1_X3Q z?xjrOf6}}P3rEGhz9{oBzupIdZcRo_Dqx6@&}sj56+5x3B=w4*Iou>Zor%v*Hzx7B z%_UT&92&0Ka#7xADEdNm?`vEB+J}clSD2g`@vqPAM~3aqQJ&bm3*Ggdp%$g4fYsM& z22=*ereQHx_qj+rgmO36*kbt1c_NyeS>8U9oQ^VyNZ6bS>Kv&-8E#TC@WT!#%}IL8 zM0Ibb+7`H_G>T7lzitlq3j?m~#d#{U_R37Hcm>kr0yBmqG zo70`jrhemYe|aoFpYr7~7d1vn0Ui|Py)O$A>u~IHf>8U9E7swaFQyuTL4KK`7$z}_ z0X@g zM5Vllv@kavNqQ4BOq3HB7CR}BMCFfmZfh~a#YLE&Cq9+?`>Un*z6Mica+~gYN5k$9 z+%qCuEC;3D4Q*S$w`x(3;>MhMFSHMFiBU@R(!zpB*fz{cb*_9|*OpxQYH8z+{g<(t{ zCccpAVQY1Tw2RoTg^FmzP%-X=AZ8RVVpI=$2_qhAq(&2_zx~f2V-X{%Z?-;Dzvtdy zN;~>gE)vj;BHTsEK+9@aQZ$l^Ll__&T5`Hv#+E9~OXRGKwQBvVJF6HY zddY$O1KVz{BNJPe=MlUQ>xO+xNY9^-k|4tuqeg_Eob*$lJ2L4TX}bqE+RrdRAqubo zQ7wNIZQD-u$@^TRdS#L&4kEiBJ!{*TOs74$tOJ$bGb$xl&q$Uh>Dztn<|6}w%$G8! z-Qbp;r{g!TAocwsbJktKb-FqgMC2qh==>-1y?$`J#VKKDS21;6Wb<&5UoN{Ep2KgK zQJQeR&7pkrHiZKjSwG{J=Hr9bk~<8}c8HDW^Bh&yAFp1PQR;=M+Km}rOXVJ%%Xf!$ zI>L54bbig%nScMDz3I~?Ywr!oeA`dj0gvj(lh-lucJbos9Uar;xZ(AIS-)pR{b{pW zSbgF3sBAe&k4jjycr!i0%Y88sMv7r)>*lnaJVwV1wUNxHy(0ly*WrigV@DSvRumQtkN1Kd@Rfn|u*5E52j7`F3{s)kqN)S@QjPaesCETM&yf zuk>~@ekJwlLSxJON%6A5o`mY5i}VqC`tCK%iRNb8Jc{D8_^v>GYvk?|RAXxG=hs@f zLyE{qZ8qqy4}!umCL}r%^f+YcQ72qrozrVXg1P26T|3-zp~lF;UYK79N2r zi4yvzdD~4z`EzAO*sE&R>x6rT=ezZqFEitXa4c&}%G|F4JBp}o*ymh{qIfm(&Tk8$ zQo)|Z?Tm!eev3#A289;=l(HhX$N)4FK7DS9@SiVt&(KUh1eZ!*MxnS--St6!o5{TN z`UJTia0-qZlw{BnqKd!Om4drhvnfA&e_v}<;`5>FX_Hy?OT{H2yhNHejLB8j0I zXg8=|0Pn&CnlCJId$A*BbPF)3eLn_-2~fGJ9Qd{Lm7KYaNC$=J#wMDJdqHBS#*y^T zx&8`xRpJ?#c2&GgsTltnEM8f>@W@s9B9!dyLiG_QO;hbE09s4WWa_ZzY{(3&igYU?y{Gdo5m(CEb95mafXvV>N-hksD?cj@!E_T%We=nSi&?b)S8(vv-F* zPZIMe?K-4wAfvNxwD}*}#}Bf#!!A~Y7_CQJUXZ7sz*~X1wmdt^~Fp^Z<_mZ?Srhxd<{#?1^?(X zAL}GX#}n}Qm@rWnU4O6cgbmQk+0{#z~GoBLyr;D9Y+ zy|@W0%Q5hijd2$p&I%Zl=%WC;Nt}eI!v=~n9B3-pKw>y)(s+sU?~pe^(zJ8G+g^Ft zu?Rt3zkq%l6vug6yS;*FZgWD_`7ZT4_Qvx9-6lbKSCc_us|VT0VF6|?4FX>`>@-ND zf_A+kq|bPWC#$m1r`k|j#|s@eBLiyZamRl%0W($v$>fy%ePg9K+NF6kz^nU_q*KTx zl#!i6%QGsE`g|8Mn*ZbWmA>ZeT5;KFP)RAFwH%2AB^rR6u^B&ITJ!?bHY6^YlsZK& zp1z2T9`QM(o!+hi?pVO+9BZ!K7xC4-w-F<-ZKhmgxPM`#!l`wm|o(fF@xjOA3Yo|>j<|MUiK)+`d>uM`Pc<7U}|J@xS<=uF!~ zf&wdb7#~PN{Dnm@t#uekvQWD8g4?u8IbO|-q2|!?pJ&ncy0;*{+zneiZa!e$LKBdl zn%r5Fn_`UMyQ-qg+AR=I=_U6R34c zD?$X#1*vezrg8b25Tb^$B70sp$5iYo8?zI&A6Y@wRml08B+o?TpG--R*Uv1WA<_Xc z_6S5JOnU2ZA)k!VA~iCY+6;l(%;2VCzED7=K5E~mK7ZT%*F2Sdb_mZw8Z#CM4Gggz zUgOSbLLx=zQuB(IwGl?~WX3Tmm+Zx)_#os^p$Czen*5Ox#yMe?IA^o6v;s?ZLm2?b^)jMAg-9AP{cYRs;$<@W9!>_2wl?f3~RdA7IlhAI91;zXn zDudp`pbGxL{MtVvP6CXk5k(LofBK~9LYnP!Z>e}0C}GL7wY6ou+Uo6-y<1NLXMFD@ z+7=>_tLi1urSaeB=9qq0Re~p^4>ra7uhYD>M1~noOiq5Raz`)FoNscqi>y=0{C{Wt zUo`)#f&YytZ6~)Ns4DtcrYTRlO+p$?q;!U&BAKE=kcwh7(A5T6)xxQM0SQ>%+>u~~ zPF1^3)!L3*gCIW%3`Kwn`UU>+U4GLXXO5|Lp8$m*D&`P!>J&1rgE0ve`%vJn8c-#o32SYXboq)8o6t;% zmX;O;R%l(3tO0FiBKRa2gK(ZPg}I#<tqo<(bw2s@S2Q!EYza~s3(%bV`lVq<`!v~*vG&pwsAN-I9&k8| z8@_(Wok64UA*;VoAa4V39kmEvGb1k4=dY7M;z3;+EcJl ztX#;vEf;|Gy{4z9M`?L5r=N&h5Ku|n4j0UN1hed_<1-K7_Vk5G>aGifpis;A%zaP= zrv)wAehh4Vs$xVUt(*%|jav(1NWl-yZ7nXL`1uE$^qWPnBc-HYRhi#K{CG;~uy~IJ zjjpbsocyqagF-U5tj2q5y)rpGR(YpZinzB+w4)r~Qfb$QLO=x?QT`zjj@bB^3PNXM(n=Y1`vj~Lw)!19{H$+qUO6Xoql>65U#AgU;GZv{Sd}!0jc)XDakv zK|hv(^H)HW)<3Pme#9SqRPqGW>l7j$+|Vmg8KV_GBtkO`=x(N9Sfrw4Z=tox9XfxX zze#OR!H(_PRa4%QG@)RQlCd6)nYeT-M)EHWYcEK$heYhSkqsrk&zzo9MDxDDz>tN2 zm*2XW?H=#v=XDwB3M;HZdy3TW=^fc05vB~m_f_?zg(L{=`7veUpOdGMk9gixQFYX(U<5;;7k?r4Eomkp%rI>a(_iV$s zdpstVPzFJ|u9DqQ!?OXTedRPIz@9>qC-a$7ilrNj?TVnZhOM&KUODbpUU7_DVUQEg zLJ6DL?5$)6S%#7Bb;0mk0{G)O>gE=DRdw@A8%umu@PYC162&Wu#9;rx#K4Q^$C(7K z;@^3CCNgx8EOrLodIrHf(m-fAnQ?GMOr`Dby9JybfDW>(uK5k!L zeLRk0;GbeW?;lN|MllSfKX0~`)j(C1jNO|f7O=g{v?5mp54zp1Q@kQg3#OIqWkY1P z=P+zzi=Yg9tF+D*l$6cnD&5npk*ptP38NqUvR#4c3rgkW55QId6_=BF9|lmd_99bx zzeRCX9+F8ZD=N-qW^;rHyXR@4vJz#k9F&-{$HgiZ3uY(Nv!cIk*6=bsi(o5Tsk^oP z)}9*^)fz0W(nPe`AE(=JSoS+rr0c>4?UxA}FI+tGc`e0<+6qbLy?&G@`Qsw395p4& zi^}E0R))&BUTVfZr+oy9H}|&4qDLR1R7Ac7HoY*Bhs%E;Ml7eJi;mU!N|Q|xa=`Mp z-%)Hrht4wAh?BY8xVA1Kh?O|qt3i@oE@ZcZ;TnFm2phUxI9|_JXsK+mS8t@B1654GISO0d5dq& zBYeCbVqsZr>UI2^;&Er5A`jzD^N3gMtc%o{yPip*p1>iXElsUuL*2pBb7UzA^qlNb?Hz!Ytc#thOg;#`1s}Y4ue8$+r`ZQ0@XjLAZ zoBQoxoRRjhAfcveCp47nr-q|cHoUnvWY?XhhzaTyI!+y!Q}8~#vZ7+_g4VS8LQ0UE zJs$_wtSX6@+;*2=-W<0Tq36yxAXtlhCx0yKpuizJg_mP$m9ZzdDeT$~Jr#Pv)JP_K zQbSc(NF;%y;o>LO{bmLif--sv<M!IwYYAHvK~NQJBbbP%3k}v zJlQVW10rdDd2rFfUB~Dj%YOJ3(zsIzVj#Fob_hQ6UCtmlUf`*d0Zo(?W!_NCk zBLjoKqMD7XURJtw7qPyRU{*lq+3t*|-euFjVid7&TG1BL$bBEjr4Y0|bcJeD7_P_R zY8^ozaT6IVZKWPVk1i^l;Gb%dFA6U%n@&g%V*hwnrP_b?F8>xh0B$iU4c>)=8nYjV zP#37jO6bI^4^S!&-+3L;qkn^D=r=p~$6X)dX5Q-a=AxJLoBNH|i|$!Wn*RCNMiu-8 zL$ilzgelm@u(DCG!q!!iWC$(_#Y$n zX!TTw`3a+oo?_`0D6+{!4lbHUXKV6EN7?yD^a4BiU9%cZzTmkP6U?a!Ib~156=OT}ySC6r4VWpAu)LgDg_2le*U7e>A zBy3q4Vh+mgoJCA3Q%(vJVa40=&pTm0LU{soB-7-3YuxwOD40hQQA1i~QtR^);r(&} z>RYjhv>v1Qz3k*Z9|hd>J7vfFw6Th`?2~q3dNx+U1>Kbrn3eZ`Fl!~Ym2t(&%Vbuc zb8-#B{#kLaGfi1bHPo{^1a2`)VTahFMJh7i?-i9=!FUd!%D)v4?BD%vNIMLRZ@t{N zzWjwvwh&E{(sG83jxp-q`9T*hl;N#>M_-DCW?iK%77>;)=?IT4%R|nCgQyXFV$*l6 zPl<2cRw-ns?j>pO2L8fzOOts&1O~X!%YgbHw$!gGH1st!2XJ|*9~_kUxs*E0*lkC- z(bgs3Q@F&2Hu)&oO**_Y8kt?{@ST|%3ndoi=Q4^5~fJinuv%%UG9b$S=Sv<5ca@q<(82g(d$o#UYy@fIld+c z+@+^zNo~i_e*3ecV{ha2{=;I{>fRzQvw+Rz5x?-!ASoQpNj2ueU3OM+v9c?Hq3kb` zsnaV?A_^T0reEE~O2HS~erZUAnDtXa)iT3RZ+&0?fIC~4S@oElJnn9=zOo|7Y8$&O zE^hmsUx>;uz|@mu07Kby3EURsj&gPDmL9p=qDy)oIZ4q-qa=r_0o!Bql72zVw`@iIL> zRE^g!U)Gdlj4K|uy+r?I;ing@tUmUNGm&~Q@8b?~4CX`Y<7=f_7f>r3sLEQJ>^b%8 z!JioXa$mR|eLl}O!Rv~;8}?-~tW8R35XE~d>{TCHwQrEigjt7c4T3bU%&O1i1ZR(q z+ufUU*OQLF%KZGOQY`EziTvU;4CB1&iSe6=2cvld1=e=OnHo0y= z>{Jk|s0=5hC|17HhW+p98xsc#6dwn=(`Wg7yEaS96kxdpzkm0WjZqI62+1QdXh@)K zOqAvgN`IG3EG}ct7#f0|LFy~A(Aj6XcauKlmL}dq6$j!;9r_Y9)mwJYs%#W0J&>54 zovV_ao^kE^NJ>Y}&DHU${QIW|We_277+)_?#a-M|@zH+5bIZCI{R9EFe}B z4Tma8Pv>tLoOf_7oy9_K z6unxdSg^$9^9ZiLHssY{-ifSKzhxW>3?z>#5H}98S1dP9TwPE_S7EhsKs^xF&Y)K? zNJ-d&J^sq{Tao}anZ$MvgpB}PUJuF4h! zF(J1M@Qeg*VbxFqELIFfG!qLmxbO^q^iJ(Rw`Y(22$cXifaLu@Er|6o4+TJOomDg{B2KD_7=T*arLaFD zEpZbphAldqeH5D0k80&?4v5+eAvJ@$6OYwr^<%Pi;~X8p@lE0;U6h3~D5=Nmf8fwB zE9Cz&tGUMXbG&{^!bH1fxX;l zZJnny3+KJt3vH~2W)ebWd@*72V9!EDCN&kDbxsK^5_ol`;TNTL?2R5b=#L93X6=*D zP^T&`)==<%$6!J&-(Y3JVc8bE?vJciMdbFJl+~~&$$kz+pVj!4r_gCQ>Jn9>4j!~f zaa5Pzq85&*O|NI(g~jirSp9iFohDc25jDe?DH>rHR%nfXl5p~6IfL7TGD`7QR-A~O zI2CPY<9CUuBPe_dqkF7`md^E1>knzBIQy1GNHJocI$(_n%Qzt~MZ880ZD{TRtdM9V zzEdZ8d;J_{pb#RLwj29u)SsFZ*~@ErZ_$>lkVJZmS}3IUBRaRIQix08fvjfI+ir38 z9gA0|k&bevS%vD>D@S@JY`V?SW+@eKoB4D1Ha|L9X=*Lui}x@GM5xIe*V&{dfF->D z#Hk8vHZaj!)z$22j{cLVV}hC=#tdDbADS0)n0FMr?RBKz}Lb*)cHO*#6;jm1SG z658db-5U(SJMOejVP(}x)U+28{4h18Z=F3$9l%)Bj?k3j ze`uxQhfO<}c-q}p0QU-LM6qspzaUgK7O<2QT5%S>IXz)x*UTj0bdi(3-Cukn_-&RW zRY_nTfm$N!N7pRv!wC;^2ltHO4hEZO^VD}|yDP8XC+?%fw1 z8le{0Ozld`#-Zt5s+L6_-%H~CKIvk!Qs0f?=3+anRciYv`+M4;LcM$Nk9p-l$-#Q} zJfx9oY|L46y!KCT+LNy-i$8#^V(Y(PSD|1^e7@0eo}F|nOOqX3N)(vmB2Io>B>(R3 z6K#{GzA?pGR2*PKP^1q%hr~1MC*v;|lQ}4wpS2U^pEOjeg70bUZfwm97+5g)-Vi6A z+zb(hcTweCpsg2sHLE$F8vR5~C(A=$g*TZFW?N-i>3u`7G~{OdYut6gt&qe!w%%8? z3guGvbN!SIZsG4di#Ah%z_rxwO|OQ6EXappMg$g#_iE@^%nouA{d!FqflZ*bIx_E+ zVK~Bktn=$5SuKZn8a`o8=7vm2Oky}pfKu5;M>3SVmSWtqj1%{sO%8K?KvHYgg=(4$ zq0B~RRo79xr!cTN5G9U>6@dk;HV6;flPuGzQo~bbl~gl8cp;;krkFV8G1nZ$);t%X z=43(rK$J!F@(OCpe-BH;XO+ohU%aMVNq0ziyLtiMDSUU?A!nd@QW2t2;Sj1xy)~N= zOfRIZCQlfgvvH&sOfGLYcltQ!Ew+3kvnuT<*;AO%+!Y$fV=C|=k5Ya z`M^v%YcEt0k5aAKh{N}C-KRBZpbEk%Je0qoo_}Hp73cH75^IfZGj(smiy+i;Uyn*nrlIS<;w~{%axipl)M09SJn7fuoU}yHO946- z^DA0`N}XwR!A`p$l>&}CC++*rGOI~-aD-;~{X#wziW4YSL=H9GMLR*oWdnnKEZf0U zN6l)uRe0AALVxYg5vclJOfEAmJ_79*|4$D$^g@EM#}d z_<@r4AkO!kc?nU&i1(heM!1k9U2dglQfH!#Yo3tN^n<fD_QaZI=9F}FiJ_64|MVLof>U=1zI_0nlLNy;wlLQ=c=HDD z=mjAf-af@J8!Kt@Xpq5e_u-R1!{NrapyQQ@G*pIW!ot>@6_A z^h@0yxd3FVs8%ZiK|naCq73Vfu^@F>P<-8`)j{TiTAy}d@qGr3@|nHSQ~RdkeWt{u zL=Oo~a+XjiyDUTe5v_vuR65TAnr1EXlV(}Lk z=c)>rXY8P;7-xwstx)*h*{w^PR#uHv^BWzL&-0_pnsNB}N!A1f&@@!?aptYl&@!p( z$+c6+SW(q1NWD0u_D7hF@|jH(6YH6S-%3t0Q8sUwfYU@5v`T=VlF$iRKkYMX*G`G{ z`I#st@lRxS#?(d^>9bJh6YCZ;B5P5ihfn!$P_t{to~xWCS|Q2Du%$tTKb4^hjxweV zMFgxYT>4k|G1H=?Pi4#;Xh4e;Xy=6163&8!=#;YeG|u}pwf);BXd_&J)WV4WXb>%! z%QtL-RSP+b{yBn$LzK|GLc#8CYzw`NTu2lY~>miHra@C{drh3NopQ;N4|9=M_`%Wql zh>VHuBnl8sV^&QwM7-Z!A1%(}dFQGw@V-?l_@Azi{+COjwB~n9KeK(v`h7?gl$Bxo zKW@hl7oRO=K13^~aAK8Pujf`yX@jd$H0g_4tRZeUq=mJ z6$b9w;%~yt8budVVNP5NCW5AgPwu~M#7N|mXz!jYH$sF_QNkJ*Y}N;pzrNa^M9Iy~C3)w>>~g$R zG(XcDO%C?Dg*M+GlyEE`<H z2=YMz=Jua&JTk7inyI{BiHO*B{3a$o{K*i+cibHzynZ^1@$GJQzfjfC2uinYMDu;V z$mU(tYjy)`mFoCQM-tUS%L60*!ol=i{;sPnQRfcC&-b&6Bm&&=ZcE7=`)*HHk^Ua@ zM6|-flqK5by)8E@7$9aYuD;C}Q5e{)*LXZny0EYi2X^sn*Z`$%eR=i-iHVDgr$6Kz z%~zvTe;y84w(WboyI_2ovgm_RHoQDP;8IdX%Tl=`KHQvW+b{tGbEaUZ2wxHCBujgE zylZ{F{~ARpM0Bw`Dr;$31pWKZDb{n`uPEOU+$=d_yPT|WSbpgW!6Xs&f%L{u#|)?Q zZ#JE@c5MwL{FAd@YETonZudt><@tj3&(#A7Oq&;@q9~xrHZ^S4$d^)V(|3NM$(1V$ zxc+>+8}*ejFrd^b(+>y2YoVgGoW4t>4(xcI_oC4GdfdKQxGUq$aRKd1jmSn z>tnrbPl}OGxO~EElkLHz&g-5?VzaZ2p1I$SOjKT{;=o<1+`>DzQ<~P>4UEU@`nH~r zb}hkA4>xAOTHWrpQ!3rgOxGJ26_breG6d(E-Fb*O^}|G;_EkW}jh;l@;DsZ0eNGk9 z*48XZ9g^SsY}yA1SMeN!fLm}$_w8?feXKVSoGas6F;*rDSCO z4adyPj8lhA&i6{lCT^T|0eDZ$6t5& z9keNOw}r2i1tA53KlPn6>)_xZDD@-@NhxZ!?6+|>Kn#t=A)1~(7UQ)+t*or<+}zkO z6;H(qMPOuP>~=hEIuZH1+(dk{>}pg3u%PV)D401pdlzcIRvLG}n|NAVm#S)(m6yx9 zxiuIa0g0t+vC2jO(rNV)92^>|gsw{{rE-Nt^_7(3N z0|Ekqwb{03UMk;5`vLb2&+k3>DiFB(#b{EV&!{XR#615Iv7&7h7dy@}Qb9=AkTE17 z7Y)Q>%PvwO7xvbt>yJ}YQ)@tU_w9}62YYLk5CSd&3cgpsxf!ZiqGhr>l4)a0rjsq= zt*WZ(cYp8U1w>N+pjF2AxTK_D-mfz`#l`3+%@q3D)6@(e6?u4t|5^#B zZq<3#;P(Eo+@w|y7ayPA{=Kh&{RZM29v-m87|qu9HrnE_%RfIYEe-XL90z@!?Oj{( z#6KNmBM$QJ5NX<}?4#-eawj?*pJ@Zg(FBJ3gxBvokLp)p{{q)-Bb*5b4=;cz+Y7I} z`8>j37z+Y;si!j-V?0+9rPQ#63^;R$u7@*)h~3@Y!=j^m?ynBdN{pTc%j**2O8H&>r$~UnOC5X@k5Ryc}(^(o1?ruh=VmF8&g4CjpWdCMb zj|hMj>|s2!3S#0vSS_tbk*_1;p1(FE2OF+lqj0RL{$J#ZoWmcT8HXMd06+m>)7&I( zF83#+kKqdla}R$^*h3=Za|HjBJ&`V7QJU^?FvS9#{3!IYuj0j)!VJYIs#GXArSq_oiC1P$sCq4rKG1vT2B5jnf&p-zrVk|(fKgU#)9%^J*FS$bfJuDq}qu` zCV((K7+lSM@$q;|?z@?8YyK$kGoi-1{LWAJR}D|si@0QD5&M%r6`yG+1)w0F&ws?s z%^8k=?^02S`ee+7%-DM@qE3B?wu$>s+hQn%LWGVR5L}ulBZ)XVvxGh0F4_z>7ES(C z=?liln#Kf@DilZ!!~+}T#I!WBQr&9ge3@vxIzmFij`h=05H&GzD6oaNqtowzRr~7~ zSN_7CGQIrLqRa*4#U4#vBlBP$+hG-39O zbv8c;%z!iR{NmzlLXpel?tHuRy0DPhBvb9@WOxPl`2^elJa7FzVm$lm-DtLGOcI;+#!cHxOIh8M0e{jb-6$$y;Lj3Id;qh?q5ji~Buo$d^Y6U(pD0h6g zJ_0VRL(dkzmeanSdU^3F__C}4`Uk=y_j~kFq&z}FInT({6GnYLB!r(zv>ftbvT>f+)Obl`T}t|S_uBG`twT$axItXp9WN9D1X`?;A%!IPn| zXK%EzC@CpP?*03o2tqb)-)FCEn};Ub;uHiFEaR8wCxCU;hGqr6ueL4jS{Jjo2hWrl zL?U4j?O82GW;v_F#aujZbNO~eaAKu}x*r8N=~Qek;{-@l@(w3NNgP!=%e1t{FspaR^`wf4^~ObQQ- zg(XEEv+oU>TsQ!`X)_@1cxJs(xad3{>F|1lVo`9OC~UX>JVIMSw*&`~Kex3y_EadG76(|B?IlA1^QBZ)$Ki z!ukS6Bccy5f+xyQ?YkAT*m_B~QB;`|XT)*Lwu1v@t^vy34L3O9C4^)M+sTkT*py}# d9Dn!n)nMI4GPZ>r_^%;IURqhIOu{(e{{Ww$)dc_m literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/resources/pushconflict.png b/mseide-msegui/icons/resources/pushconflict.png new file mode 100644 index 0000000000000000000000000000000000000000..0256ff697f1fb4a5544dde7f38379c3b072a7b70 GIT binary patch literal 214 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|I14-?iy0XB zjsWp%#&&bFGN2%PiKnkC`)w|MUJ2E7%ZcBBLK&Vejv*T7w+0ys9Z=x#{_}tSWyfs8 ztwlUfC2Uk08AMvTOht6r1#}oVvW{-ZHkc)OrCH{n*rYc1cRy}>-rhL>>~G-@a@)6u zNUYYp=T@_3nf^+J6JLB8_uTz1P}cIf^r)@I**L8~rEA3xYp95y^bzO>+R5PQ>gTe~ HDWM4fwUI|~ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/resources/pushmergeconflictpending.png b/mseide-msegui/icons/resources/pushmergeconflictpending.png new file mode 100644 index 0000000000000000000000000000000000000000..a95d432d8f0557a2c4723b1dfc460cc6196e6996 GIT binary patch literal 214 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|I14-?iy0XB zjsWp%#&&bFGN2%PiKnkC`)w{sPA&m!*4CLop$tzK#}JM4TZ0_=4j6DS{r{g{R^T1I z>uSY}j~4_SHwFn<31+zYD%?;IXc6PP+;|5t$(F(;telz&82^e$0vl&_gDTsW&4Ty>%TJXS5pyBzUJ!+w3ETp)z4*} HQ$iB}EPYBG literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/resources/pushmergepending.png b/mseide-msegui/icons/resources/pushmergepending.png new file mode 100644 index 0000000000000000000000000000000000000000..7308179ac8e9f19675537d921fdfb30ce254ddb9 GIT binary patch literal 215 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|I14-?iy0XB zjsWp%#&&bFGN2%PiKnkC`)w|MUTO3FYd6;dg)%)|978nDZw<2KJ7B=E`RD)ncNHh@ zxFzE(=*%LqftmH;F`nt$*ah}52($>bH9KcMcC;*E(GBzE-t>U#GlrpPskUn^l)v_OJWOxKl$#{ELiEH_%cBPgg&e IbxsLQ0AvVAqyPW_ literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/resources/pushpending.png b/mseide-msegui/icons/resources/pushpending.png new file mode 100644 index 0000000000000000000000000000000000000000..69909c98e893e5d5bea8b8f754fba8ce662ed7ce GIT binary patch literal 185 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|I14-?iy0XB zjsWp%#&&bFGN2%PiKnkC`)w|ME^RT*v(2GEA#YC?#}JM4XD4}bF(~jbs~`Pezf*3{ zjs;6Q68uzC7A%?iI3-0zl-Y^XfkR$``?ACNh&gEqZ}wcU%5U8I?wQSsuVNYxZ>BwN cj^D+qbv2(?RraIUMWC?^p00i_>zopr0R163U;qFB literal 0 HcmV?d00001 diff --git a/mseide-msegui/icons/resources/stg_checkboxparentnotchecked.png b/mseide-msegui/icons/resources/stg_checkboxparentnotchecked.png new file mode 100644 index 0000000000000000000000000000000000000000..4302d63af87d6027c66052717f414b41f1620954 GIT binary patch literal 166 zcmeAS@N?(olHy`uVBq!ia0vp^{2{XE)7O>#9;XDSDEH;p=iUN^j6Gc(LpZJ{|M=hkkU`p+S@`fD zf1b(qhCY9e7(5m}JV&Xm(v9bHtHd*ZrcUP6#;kw;nHd)F3I3O|j$;C9XYh3Ob6Mw< G&;$UtE6S55 zZ#;fuJAO8HS?X1i>DMTl3dDtjLY6=PkZ(2{d@lh>`3mSid<&oxUumlxT6qsH=EMxpo!h;JI+R&I*ugR5Y{l*U(e6> z_+XEp?{OZC>-y+{c)x!H{w$bMnJe@^gtMr(LruMNJd}Y@a)9S0MIT`P<`e0*Y%&nIQ>x(*}SKFcJAq@J7ohH2dj6V|=mmS10U=Y0i}*BVEu>u0Zr0G-L;>FVdQ I&MBb@0FP>4#Q*>R literal 0 HcmV?d00001 diff --git a/mseide-msegui/lib/common/COPYING.LGPL b/mseide-msegui/lib/common/COPYING.LGPL new file mode 100644 index 0000000..b1e3f5a --- /dev/null +++ b/mseide-msegui/lib/common/COPYING.LGPL @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/mseide-msegui/lib/common/COPYING.MSE b/mseide-msegui/lib/common/COPYING.MSE new file mode 100644 index 0000000..e2eff9b --- /dev/null +++ b/mseide-msegui/lib/common/COPYING.MSE @@ -0,0 +1,23 @@ +This is the file COPYING.MSE, it applies to the MSEgui Library. + +The source code of the MSEgui Library is +distributed under the Library GNU General Public License +(see the file COPYING) with the following modification: + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent modules, +and to copy and distribute the resulting executable under terms of your choice, +provided that you also meet, for each linked independent module, the terms +and conditions of the license of that module. An independent module is a module +which is not derived from or based on this library. If you modify this +library, you may extend this exception to your version of the library, but you are +not obligated to do so. If you do not wish to do so, delete this exception +statement from your version. + +If you didn't receive a copy of the file COPYING, contact: + Free Software Foundation + 675 Mass Ave + Cambridge, MA 02139 + USA + diff --git a/mseide-msegui/lib/common/assistive/mseassistivehandler.pas b/mseide-msegui/lib/common/assistive/mseassistivehandler.pas new file mode 100644 index 0000000..853681c --- /dev/null +++ b/mseide-msegui/lib/common/assistive/mseassistivehandler.pas @@ -0,0 +1,2596 @@ +{ MSEgui Copyright (c) 2017-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +// +// under construction +// +unit mseassistivehandler; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,mseclasses,mseassistiveserver,mseevent,mselist, + mseguiglob,mseglob,msestrings,mseinterfaces,mseact,mseshapes, + mseassistiveclient,msemenuwidgets,msegrids,msespeak,msetypes, + msestockobjects,msegraphutils,msegui,msehash,mdb,msestat,msestatfile; + +type + assistivehandlerstatety = + (ahs_active,ahs_speaklocked, + ahs_activated, //set by dowindowactivated() and doapplicationactivated(), + //reset by doapplicationdeactivated() + ahs_applicationactivated, //set by doapplicationactivated(), + //consumed by dowindowactivated() + ahs_nocut, + ahs_windowactivated,ahs_menuactivated,ahs_menuactivatepending, + ahs_dropdownlistclosed,ahs_editcharenter,ahs_editchardelete, + ahs_locatepending,ahs_dropdownpending,ahs_cellwidgetpending, + ahs_dbchangepending, + ahs_textblock,ahs_textblock1); + assistivehandlerstatesty = set of assistivehandlerstatety; + +const + internalstates = [ahs_active,ahs_speaklocked,ahs_activated, + ahs_applicationactivated]; + volumemin = 0.2; + volumemax = 2; + ratemin = 0.2; + ratemax = 5; + +type + tassistivespeak = class(tcustomespeakng) + public + constructor create(aowner: tcomponent); override; + published + property datapath; + property options; + property device; + property bufferlength; + property voicedefault; + property voices; + property language; + property identifier; + property voicename; + property variant; + property gender; + property age; + property variantnum; + property volume; + property rate; + property pitch; + property range; + property wordgap; + property punctuationlist; + property onbeforeconnect; + end; + + tassistivehandler = class; + tassistivewidgetitem = class; + + assistiveeventty = + procedure(const sender: tassistivewidgetitem; + const handler: tassistivehandler; const intf: iassistiveclient; + var handled: boolean) of object; + assistivemouseeventty = + procedure(const sender: tassistivewidgetitem; + const handler: tassistivehandler; const intf: iassistiveclient; + const info: mouseeventinfoty; var handled: boolean) of object; + assistivefocuschangedeventty = + procedure(const sender: tassistivewidgetitem; + const handler: tassistivehandler; const intf: iassistiveclient; + const oldwidget,newwidget: iassistiveclient; + var handled: boolean) of object; + assistivekeyeventty = + procedure(const sender: tassistivewidgetitem; + const handler: tassistivehandler; const intf: iassistiveclient; + const info: keyeventinfoty; var handled: boolean) of object; + assistivedataeventty = + procedure(const sender: tassistivewidgetitem; + const handler: tassistivehandler; const intf: iassistiveclientdata; + var handled: boolean) of object; + assistivecelleventty = + procedure(const sender: tassistivewidgetitem; + const handler: tassistivehandler; const intf: iassistiveclientgrid; + const info: celleventinfoty; var handled: boolean) of object; + assistiveediteventty = + procedure(const sender: tassistivewidgetitem; + const handler: tassistivehandler; const intf: iassistiveclientedit; + var handled: boolean) of object; + assistiveeditstringeventty = + procedure(const sender: tassistivewidgetitem; + const handler: tassistivehandler; const intf: iassistiveclientedit; + const atext: msestring; var handled: boolean) of object; + assistiveeditindexeventty = + procedure(const sender: tassistivewidgetitem; + const handler: tassistivehandler; const intf: iassistiveclientedit; + const index: int32; var handled: boolean) of object; + assistiveeditinputmodeeventty = + procedure(const sender: tassistivewidgetitem; + const handler: tassistivehandler; const intf: iassistiveclientedit; + const amode: editinputmodety; var handled: boolean) of object; + assistiveedittextblockeventty = + procedure(const sender: tassistivewidgetitem; + const handler: tassistivehandler; const intf: iassistiveclientedit; + const amode: edittextblockmodety; const atext: msestring; + var handled: boolean) of object; + assistivedirectioneventty = + procedure(const sender: tassistivewidgetitem; + const handler: tassistivehandler; const intf: iassistiveclient; + const adirection: graphicdirectionty; + var handled: boolean) of object; + assistivebooleaneventty = + procedure(const sender: tassistivewidgetitem; + const handler: tassistivehandler; const intf: iassistiveclient; + const avalue: boolean; + var handled: boolean) of object; + assistivedirectiongrideventty = + procedure(const sender: tassistivewidgetitem; + const handler: tassistivehandler; + const intf: iassistiveclientgrid; + const adirection: graphicdirectionty; + var handled: boolean) of object; + assistivestringeventty = + procedure(const sender: tassistivewidgetitem; + const handler: tassistivehandler; + const intf: iassistiveclient; var atext: msestring) of object; + assistivedataseteventty = + procedure(const sender: tassistivewidgetitem; + const handler: tassistivehandler; const intf: iassistiveclient; + const akind: assistivedbeventkindty; const adataset: tdataset; + var handled: boolean) of object; + + tassistivewidgetitem = class(tmsecomponent) + private + fhandler: tassistivehandler; + fwidget: twidget; + fonwindowactivated: assistiveeventty; + fonwindowdeactivated: assistiveeventty; + fonwindowclosed: assistiveeventty; + fonenter: assistiveeventty; + fonactivate: assistiveeventty; + fondeactivate: assistiveeventty; + fonclientmouseevent: assistivemouseeventty; + fonkeydown: assistivekeyeventty; + fonchange: assistiveeventty; + fondataentered: assistivedataeventty; + foncellevent: assistivecelleventty; + foneditcharenter: assistiveeditstringeventty; + foneditchardelete: assistiveeditstringeventty; + foneditwithdrawn: assistiveediteventty; + foneditindexmoved: assistiveeditindexeventty; + foneditinputmodeset: assistiveeditinputmodeeventty; + fonedittextblock: assistiveedittextblockeventty; + fonnavigbordertouched: assistivedirectioneventty; + fontabordertouched: assistivebooleaneventty; + fongetcaption: assistivestringeventty; + fcaption: msestring; + fongettext: assistivestringeventty; + fongethint: assistivestringeventty; + ftext: msestring; + fhint: msestring; + fondbvaluechanged: assistivedataeventty; + fondatasetevent: assistivedataseteventty; + fongridbordertouched: assistivedirectiongrideventty; + procedure sethandler(const avalue:tassistivehandler); + procedure setwidget(const avalue: twidget); + protected + procedure linkhandler(); + procedure unlinkhandler(); + procedure objectevent(const sender: tobject; + const event: objecteventty) override; + procedure dowindowactivated(const sender:tassistivehandler; + const aintf: iassistiveclient; var handled: boolean); + procedure dowindowdeactivated(const sender:tassistivehandler; + const aintf: iassistiveclient; var handled: boolean); + procedure dowindowclosed(const sender:tassistivehandler; + const aintf: iassistiveclient; var handled: boolean); + procedure doenter(const sender:tassistivehandler; + const aintf: iassistiveclient; var handled: boolean); + procedure doactivate(const sender:tassistivehandler; + const aintf: iassistiveclient; var handled: boolean); + procedure dodeactivate(const sender:tassistivehandler; + const aintf: iassistiveclient; var handled: boolean); + procedure doclientmouseevent(const sender:tassistivehandler; + const aintf: iassistiveclient; const info: mouseeventinfoty; + var handled: boolean); + procedure dokeydown(const sender:tassistivehandler; + const aintf: iassistiveclient; const info: keyeventinfoty; + var handled: boolean); + procedure dochange(const sender:tassistivehandler; + const aintf: iassistiveclient; var handled: boolean); + procedure dodbvaluechanged(const sender:tassistivehandler; + const aintf: iassistiveclientdata; var handled: boolean); + procedure dodataentered(const sender:tassistivehandler; + const aintf: iassistiveclientdata; var handled: boolean); + procedure docellevent(const sender:tassistivehandler; + const aintf: iassistiveclientgrid; const info: celleventinfoty; + var handled: boolean); + procedure dogridbordertouched(const sender:tassistivehandler; + const aintf: iassistiveclientgrid; + const adirection: graphicdirectionty; + var handled: boolean); + procedure doeditcharenter(const sender:tassistivehandler; + const aintf: iassistiveclientedit; const achar: msestring; + var handled: boolean); + procedure doeditchardelete(const sender:tassistivehandler; + const aintf: iassistiveclientedit; const achar: msestring; + var handled: boolean); + procedure doeditindexmoved(const sender:tassistivehandler; + const aintf: iassistiveclientedit; const aindex: int32; + var handled: boolean); + procedure doeditwithdrawn(const sender:tassistivehandler; + const aintf: iassistiveclientedit; var handled: boolean); + procedure doedittextblock(const sender:tassistivehandler; + const aintf: iassistiveclientedit; + const amode: edittextblockmodety; const atext: msestring; + var handled: boolean); + procedure doeditinputmodeset(const sender:tassistivehandler; + const aintf: iassistiveclientedit; const amode: editinputmodety; + var handled: boolean); + procedure donavigbordertouched(const sender:tassistivehandler; + const aintf: iassistiveclient; + const adirection: graphicdirectionty; + var handled: boolean); + procedure dotabordertouched(const sender:tassistivehandler; + const aintf: iassistiveclient; + const adown: boolean; + var handled: boolean); + procedure dodatasetevent(const sender:tassistivehandler; + const aintf: iassistiveclient; const akind: assistivedbeventkindty; + const adataset: tdataset; var handled: boolean); + function getcaption(const sender: tassistivehandler; + const aintf: iassistiveclient): msestring; + function gettext(const sender: tassistivehandler; + const aintf: iassistiveclient): msestring; + function gethint(const sender: tassistivehandler; + const aintf: iassistiveclient): msestring; + public + destructor destroy(); override; + published + property handler: tassistivehandler read fhandler write sethandler; + property widget: twidget read fwidget write setwidget; + property caption: msestring read fcaption write fcaption; + property text: msestring read ftext write ftext; + property hint: msestring read fhint write fhint; + property onwindowactivated: assistiveeventty read fonwindowactivated + write fonwindowactivated; + property onwindowdeactivated: assistiveeventty read fonwindowdeactivated + write fonwindowdeactivated; + property onwindowclosed: assistiveeventty read fonwindowclosed + write fonwindowclosed; + property onenter: assistiveeventty read fonenter write fonenter; + property onactivate: assistiveeventty read fonactivate write fonactivate; + property ondeactivate: assistiveeventty read fondeactivate + write fondeactivate; + property onclientmouseevent: assistivemouseeventty read fonclientmouseevent + write fonclientmouseevent; + property onkeydown: assistivekeyeventty read fonkeydown write fonkeydown; + property onchange: assistiveeventty read fonchange write fonchange; + property ondataentered: assistivedataeventty read fondataentered + write fondataentered; + property ondbvaluechanged: assistivedataeventty read fondbvaluechanged + write fondbvaluechanged; + property oncellevent: assistivecelleventty read foncellevent + write foncellevent; + property ongridbordertouched: assistivedirectiongrideventty + read fongridbordertouched write fongridbordertouched; + property oneditcharenter: assistiveeditstringeventty read foneditcharenter + write foneditcharenter; + property oneditchardelete: assistiveeditstringeventty read foneditchardelete + write foneditchardelete; + property oneditwithdrawn: assistiveediteventty read foneditwithdrawn + write foneditwithdrawn; + property oneditindexmoved: assistiveeditindexeventty read foneditindexmoved + write foneditindexmoved; + property oneditinputmodeset: assistiveeditinputmodeeventty + read foneditinputmodeset write foneditinputmodeset; + property onedittextblock: assistiveedittextblockeventty + read fonedittextblock write fonedittextblock; + property onnavigbordertouched: assistivedirectioneventty + read fonnavigbordertouched write fonnavigbordertouched; + property ontabordertouched: assistivebooleaneventty + read fontabordertouched write fontabordertouched; + property ondatasetevent: assistivedataseteventty + read fondatasetevent write fondatasetevent; + property ongetcaption: assistivestringeventty read fongetcaption + write fongetcaption; + property ongettext: assistivestringeventty read fongettext + write fongettext; + property ongethint: assistivestringeventty read fongethint + write fongethint; + end; + + assistivewidgetdataty = record + item: tassistivewidgetitem; + end; + + assistivewidgethashdataty = record + header: pointerhashdataty; //datapointer = interface + data: assistivewidgetdataty; + end; + passistivewidgethashdataty = ^assistivewidgethashdataty; + + tassistivewidgetitemlist = class(tpointerhashdatalist) + protected + function getrecordsize(): int32 override; + end; + + assistiveservereventty = + procedure(const sender:tassistivehandler; var handled: boolean) of object; + assistiveserverclienteventty = + procedure(const sender:tassistivehandler; + const intf: iassistiveclient; var handled: boolean) of object; + assistiveserverkeyeventty = + procedure(const sender:tassistivehandler; + const intf: iassistiveclient; const info: keyeventinfoty; + var handled: boolean) of object; + assistiveservermouseeventty = + procedure(const sender:tassistivehandler; + const intf: iassistiveclient; const info: mouseeventinfoty; + var handled: boolean) of object; + assistiveserverdataeventty = + procedure(const sender:tassistivehandler; + const intf: iassistiveclientdata; var handled: boolean) of object; + assistiveservercelleventty = + procedure(const sender:tassistivehandler; + const intf: iassistiveclientgrid; const info: celleventinfoty; + var handled: boolean) of object; + assistiveservereditstringeventty = + procedure(const sender:tassistivehandler; + const intf: iassistiveclientedit; const achar: msestring; + var handled: boolean) of object; + assistiveserverediteventty = + procedure(const sender:tassistivehandler; + const intf: iassistiveclientedit; var handled: boolean) of object; + assistiveservereditindexeventty = + procedure(const sender:tassistivehandler; + const intf: iassistiveclientedit; const index: int32; + var handled: boolean) of object; + assistiveservereditinputmodeeventty = + procedure(const sender:tassistivehandler; + const intf: iassistiveclientedit; const amode: editinputmodety; + var handled: boolean) of object; + assistiveserveredittextblockeventty = + procedure(const sender:tassistivehandler; + const intf: iassistiveclientedit; + const amode: edittextblockmodety; const atext: msestring; + var handled: boolean) of object; + assistiveserverdirectioneventty = + procedure(const sender:tassistivehandler; + const intf: iassistiveclient; + const adirection: graphicdirectionty; + var handled: boolean) of object; + assistiveserverbooleaneventty = + procedure(const sender:tassistivehandler; + const intf: iassistiveclient; + const avalue: boolean; + var handled: boolean) of object; + assistiveservergriddirectioneventty = + procedure(const sender:tassistivehandler; + const intf: iassistiveclientgrid; + const adirection: graphicdirectionty; + var handled: boolean) of object; + + assistiveserverfocuschangedeventty = + procedure(const sender:tassistivehandler; + const oldwidget,newwidget: iassistiveclient; + var handled: boolean) of object; + assistiveserveractioneventty = + procedure (const sender: tassistivehandler; + const intf: iassistiveclient; //intf can be nil + const actionobj: tobject; const info: actioninfoty; + var handled: boolean) of object; + assistiveserveritemeventty = + procedure (const sender:tassistivehandler; + const intf: iassistiveclient; //intf can be nil + const items: shapeinfoarty; const aindex: integer; + var handled: boolean) of object; + assistiveservermenueventty = + procedure (const sender:tassistivehandler; + const intf: iassistiveclientmenu; + var handled: boolean) of object; + assistiveservermenuitemeventty = + procedure (const sender:tassistivehandler; + const intf: iassistiveclientmenu;//intf can be nil + const items: menucellinfoarty; const aindex: integer; + var handled: boolean) of object; + assistiveserverdataseteventty = + procedure(const handler: tassistivehandler; const intf: iassistiveclient; + const akind: assistivedbeventkindty; const adataset: tdataset; + var handled: boolean) of object; + speakoptionty = (spo_addtext,spo_hint,spo_columncaption,spo_parent,spo_path, + spo_notext, + spo_maincaption); + speakoptionsty = set of speakoptionty; + + tassistivehandler = class(tmsecomponent,iassistiveserver,istatfile) + private + factive: boolean; + fspeaker: tassistivespeak; + fvoicefixed: int32; + fvoicecaption: int32; + fvoicetext: int32; + fonwindowactivated: assistiveserverclienteventty; + fonwindowdeactivated: assistiveserverclienteventty; + fonwindowclosed: assistiveserverclienteventty; + fonenter: assistiveserverclienteventty; + fonactivate: assistiveserverclienteventty; + fondeactivate: assistiveserverclienteventty; + fonclientmouseevent: assistiveservermouseeventty; + fonfocuschanged: assistiveserverfocuschangedeventty; + fonkeydown: assistiveserverkeyeventty; + fonchange: assistiveserverclienteventty; + fondataentered: assistiveserverdataeventty; + foncellevent: assistiveservercelleventty; + foneditcharenter: assistiveservereditstringeventty; + foneditchardelete: assistiveservereditstringeventty; + foneditwithdrawn: assistiveserverediteventty; + foneditindexmoved: assistiveservereditindexeventty; + foneditinputmodeset: assistiveservereditinputmodeeventty; + fonedittextblock: assistiveserveredittextblockeventty; + fonnavigbordertouched: assistiveserverdirectioneventty; + fontabordertouched: assistiveserverbooleaneventty; + fonitementer: assistiveserveritemeventty; + fonmenuitementer: assistiveservermenuitemeventty; + fonactionexecute: assistiveserveractioneventty; + foptions: assistiveoptionsty; + fonapplicationactivated: assistiveservereventty; + fonapplicationdeactivated: assistiveservereventty; + fonmenuactivated: assistiveservermenueventty; + fondbvaluechanged: assistiveserverdataeventty; + fondatasetevent: assistiveserverdataseteventty; + fongridbordertouched: assistiveservergriddirectioneventty; + fvoicetextmessage: int32; + fvoicetextdisp: int32; + fvoicetextedit: int32; + fvoicetexteditreadonly: int32; + fstatfile: tstatfile; + fstatvarname: msestring; + fstatpriority: int32; + fmaincaption: msestring; + procedure setactive(const avalue: boolean); + procedure setspeaker(const avalue: tassistivespeak); + procedure setoptions(const avalue: assistiveoptionsty); + procedure setstatfile(const avalue: tstatfile); + protected + fstate: assistivehandlerstatesty; + fspeaklock: int32; + fdataenteredkeyserial: card32; + fitems: tassistivewidgetitemlist; + fgridintf: iassistiveclientgrid; + fnewcell: gridcoordty; + fnewcol: boolean; + {$ifdef mse_debugassistive} + procedure debug(const text: string; + const intf: iassistiveclient); + {$endif} + procedure activate(); + procedure deactivate(); + + procedure loaded() override; + + function canspeak(): boolean; + procedure startspeak(); + + procedure registeritem(const aintf: iassistiveclient; + const aitem: tassistivewidgetitem); + procedure unregisteritem(const aintf: iassistiveclient); + function finditem(aintf: iassistiveclient; + out aitem: tassistivewidgetitem): boolean; + procedure doshortcut(const sender: twidget; var info: keyeventinfoty); + procedure dospeakagain(const sender: twidget); + procedure dospeakpath(const sender: twidget); + procedure checklocatepending(const sender: iassistiveclient); + function gettextvoice(const aflags: assistiveflagsty): int32; + + //iassistiveserver + procedure doapplicationactivated(); + procedure doapplicationdeactivated(); + procedure dowindowactivated(const sender: iassistiveclient); + procedure dowindowdeactivated(const sender: iassistiveclient); + procedure dowindowclosed(const sender: iassistiveclient); + procedure doenter(const sender: iassistiveclient); + procedure doactivate(const sender: iassistiveclient); + procedure dodeactivate(const sender: iassistiveclient); + procedure doclientmouseevent(const sender: iassistiveclient; + const info: mouseeventinfoty); + procedure dokeydown(const sender: iassistiveclient; + const info: keyeventinfoty); + procedure dochange(const sender: iassistiveclient); + procedure dodataentered(const sender: iassistiveclientdata); + procedure dodbvaluechanged(const sender: iassistiveclientdata); + procedure docellevent(const sender: iassistiveclientgrid; + const info: celleventinfoty); + procedure dogridbordertouched(const sender: iassistiveclientgrid; + const adirection: graphicdirectionty); + + procedure doeditcharenter(const sender: iassistiveclientedit; + const achar: msestring); + procedure doeditchardelete(const sender: iassistiveclientedit; + const achar: msestring); + procedure doeditindexmoved(const sender: iassistiveclientedit; + const aindex: int32); + procedure doeditwithdrawn(const sender: iassistiveclientedit); + procedure doedittextblock(const sender: iassistiveclientedit; + const amode: edittextblockmodety; const atext: msestring); + procedure doeditinputmodeset(const sender: iassistiveclientedit; + const amode: editinputmodety); + procedure donavigbordertouched(const sender: iassistiveclient; + const adirection: graphicdirectionty); + procedure dotabordertouched(const sender: iassistiveclient; + const adown: boolean); + procedure dofocuschanged(const sender: iassistiveclient; + const oldwidget,newwidget: iassistiveclient); + procedure doactionexecute(const sender: iassistiveclient;//sender can be nil + const senderobj: tobject; const info: actioninfoty); + procedure doitementer(const sender: iassistiveclient; //sender can be nil + const items: shapeinfoarty; const aindex: integer); + procedure domenuactivated(const sender: iassistiveclientmenu); + procedure doitementer(const sender: iassistiveclientmenu;//sender can be nil + const items: menucellinfoarty; const aindex: integer); + procedure dodatasetevent(const sender: iassistiveclient; + const akind: assistivedbeventkindty; + const adataset: pointer); //tdataset + //istatfile + procedure dostatread(const reader: tstatreader) virtual; + procedure dostatwrite(const writer: tstatwriter) virtual; + procedure statreading(); + procedure statread(); + function getstatvarname(): msestring; + function getstatpriority(): integer; + public + constructor create(aowner: tcomponent); override; + destructor destroy(); override; + procedure initnewcomponent(const ascale: real) override; + + procedure setstate(const astate: assistivehandlerstatesty); + procedure resetstate(const astate: assistivehandlerstatesty); + procedure speakstop(const acancel: boolean = false); + procedure speakcontinue(); + procedure wait(); + procedure cancel(); + procedure speaktext(const atext: msestring; const avoice: int32 = 0; + const nocut: boolean = false); + procedure speaktext1(const atext: msestring; const avoice: int32 = 0; + const nocut: boolean = false); + //with cancel + procedure speaktext(const atext: stockcaptionty; const avoice: int32 = 0; + const nocut: boolean = false); + procedure speaktext1(const atext: stockcaptionty; const avoice: int32 = 0; + const nocut: boolean = false); + //with cancel + procedure speakcharacter(const achar: char32; const avoice: int32 = 0; + const nocut: boolean = false); + procedure speakall(const sender: iassistiveclient; aoptions: speakoptionsty); + procedure speakall(const sender: twidget; aoptions: speakoptionsty); + procedure speakgridcell(const sender: iassistiveclientgrid; + const acell: gridcoordty; const acaption: boolean); + procedure speakinput(const sender: iassistiveclientdata); + procedure speakmenustart(const sender: iassistiveclient); + procedure speakallmenu(const sender: iassistiveclientmenu; + const ahint: boolean); + function getcaptiontext(const acaption: msestring): msestring; + function getcaptiontext(const sender: iassistiveclient): msestring; + function gettexttext(const sender: iassistiveclient): msestring; + function gethinttext(const sender: iassistiveclient): msestring; + procedure focusfirstelement(const awidget: twidget); + procedure focuslastelement(const awidget: twidget); + property state: assistivehandlerstatesty read fstate; + published + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read fstatvarname write fstatvarname; + property statpriority: int32 read fstatpriority + write fstatpriority default 0; + property active: boolean read factive write setactive default false; + property options: assistiveoptionsty read foptions + write setoptions default defaultassistiveoptions; + property speaker: tassistivespeak read fspeaker write setspeaker; + property voicefixed: int32 read fvoicefixed + write fvoicefixed default 0; + property maincaption: msestring read fmaincaption write fmaincaption; + property voicecaption: int32 read fvoicecaption + write fvoicecaption default 0; + property voicetextmessage: int32 read fvoicetextmessage + write fvoicetextmessage default 0; + property voicetext: int32 read fvoicetext + write fvoicetext default 0; + property voicetextdisp: int32 read fvoicetextdisp + write fvoicetextdisp default 0; + property voicetextedit: int32 read fvoicetextedit + write fvoicetextedit default 0; + property voicetexteditreadonly: int32 read fvoicetexteditreadonly + write fvoicetexteditreadonly default 0; + property onapplicationactivated: assistiveservereventty + read fonapplicationactivated write fonapplicationactivated; + property onapplicationdeactivated: assistiveservereventty + read fonapplicationdeactivated write fonapplicationdeactivated; + property onwindowactivated: assistiveserverclienteventty + read fonwindowactivated write fonwindowactivated; + property onwindowdeactivated: assistiveserverclienteventty + read fonwindowdeactivated write fonwindowdeactivated; + property onwindowclosed: assistiveserverclienteventty read fonwindowclosed + write fonwindowclosed; + property onenter: assistiveserverclienteventty read fonenter write fonenter; + property onactivate: assistiveserverclienteventty read fonactivate + write fonactivate; + property ondeactivate: assistiveserverclienteventty read fondeactivate + write fondeactivate; + property onclientmouseevent: assistiveservermouseeventty + read fonclientmouseevent write fonclientmouseevent; + property onfocuschanged: assistiveserverfocuschangedeventty + read fonfocuschanged write fonfocuschanged; + property onkeydown: assistiveserverkeyeventty read fonkeydown + write fonkeydown; + property onchange: assistiveserverclienteventty read fonchange + write fonchange; + property ondataentered: assistiveserverdataeventty read fondataentered + write fondataentered; + property ondbvaluechanged: assistiveserverdataeventty read fondbvaluechanged + write fondbvaluechanged; + property oncellevent: assistiveservercelleventty read foncellevent + write foncellevent; + property ongridbordertouched: assistiveservergriddirectioneventty + read fongridbordertouched write fongridbordertouched; + property oneditcharenter: assistiveservereditstringeventty + read foneditcharenter write foneditcharenter; + property oneditchardelete: assistiveservereditstringeventty + read foneditchardelete write foneditchardelete; + property oneditwithdrawn: assistiveserverediteventty read foneditwithdrawn + write foneditwithdrawn; + property oneditindexmoved: assistiveservereditindexeventty + read foneditindexmoved write foneditindexmoved; + property oneditinputmodeset: assistiveservereditinputmodeeventty + read foneditinputmodeset write foneditinputmodeset; + property onedittextblock: assistiveserveredittextblockeventty + read fonedittextblock write fonedittextblock; + property onnavigbordertouched: assistiveserverdirectioneventty + read fonnavigbordertouched write fonnavigbordertouched; + property ontabordertouched: assistiveserverbooleaneventty + read fontabordertouched write fontabordertouched; + property onactionexecute: assistiveserveractioneventty read fonactionexecute + write fonactionexecute; + property onitementer: assistiveserveritemeventty read fonitementer + write fonitementer; + property onmenuactivated: assistiveservermenueventty + read fonmenuactivated write fonmenuactivated; + property onmenuitementer: assistiveservermenuitemeventty + read fonmenuitementer write fonmenuitementer; + property ondatasetevent: assistiveserverdataseteventty + read fondatasetevent write fondatasetevent; + end; + +implementation +uses + msekeyboard,sysutils,msesysutils,mserichstring,msemenus,mseactions, + msegridsglob,mseeditglob,typinfo; + +type + twidget1 = class(twidget); + tpopupmenuwidget1 = class(tpopupmenuwidget); + tmenuitem1 = class(tmenuitem); + +{ tassistivespeak } + +constructor tassistivespeak.create(aowner: tcomponent); +begin + inherited; + setsubcomponent(true); +end; + +{ tassistivewidgetitem } + +destructor tassistivewidgetitem.destroy(); +begin + handler:= nil; + inherited; +end; + +procedure tassistivewidgetitem.sethandler(const avalue:tassistivehandler); +begin + unlinkhandler(); + setlinkedvar(avalue,tmsecomponent(fhandler)); + linkhandler(); +end; + +procedure tassistivewidgetitem.setwidget(const avalue: twidget); +begin + unlinkhandler(); + setlinkedvar(avalue,tmsecomponent(fwidget)); + linkhandler(); +end; + +procedure tassistivewidgetitem.linkhandler(); +begin + if (fwidget <> nil) and (fhandler <> nil) and + not (csdesigning in componentstate) then begin + fhandler.registeritem(twidget1(fwidget).getiassistiveclient,self); + end; +end; + +procedure tassistivewidgetitem.unlinkhandler(); +begin + if (fhandler <> nil) and (fwidget <> nil) and + not (csdesigning in componentstate) then begin + fhandler.unregisteritem(twidget1(fwidget).getiassistiveclient()); + end; +end; + +procedure tassistivewidgetitem.objectevent(const sender: tobject; + const event: objecteventty); +begin + if (event = oe_destroyed) and (sender = fwidget) then begin + unlinkhandler(); + end; + inherited; +end; + +procedure tassistivewidgetitem.dowindowactivated(const sender:tassistivehandler; + const aintf: iassistiveclient; var handled: boolean); +begin + if canevent(tmethod(fonwindowactivated)) then begin + fonwindowactivated(self,sender,aintf,handled); + end; +end; + +procedure tassistivewidgetitem.dowindowdeactivated( + const sender:tassistivehandler; const aintf: iassistiveclient; + var handled: boolean); +begin + if canevent(tmethod(fonwindowdeactivated)) then begin + fonwindowdeactivated(self,sender,aintf,handled); + end; +end; + +procedure tassistivewidgetitem.dowindowclosed(const sender:tassistivehandler; + const aintf: iassistiveclient; var handled: boolean); +begin + if canevent(tmethod(fonwindowclosed)) then begin + fonwindowclosed(self,sender,aintf,handled); + end; +end; + +procedure tassistivewidgetitem.doenter(const sender:tassistivehandler; + const aintf: iassistiveclient; var handled: boolean); +begin + if canevent(tmethod(fonenter)) then begin + fonenter(self,sender,aintf,handled); + end; +end; + +procedure tassistivewidgetitem.doactivate(const sender:tassistivehandler; + const aintf: iassistiveclient; var handled: boolean); +begin + if canevent(tmethod(fonactivate)) then begin + fonactivate(self,sender,aintf,handled); + end; +end; + +procedure tassistivewidgetitem.dodeactivate(const sender: tassistivehandler; + const aintf: iassistiveclient; var handled: boolean); +begin + if canevent(tmethod(fondeactivate)) then begin + fondeactivate(self,sender,aintf,handled); + end; +end; + +procedure tassistivewidgetitem.doclientmouseevent( + const sender:tassistivehandler; const aintf: iassistiveclient; + const info: mouseeventinfoty; var handled: boolean); +begin + if canevent(tmethod(fonclientmouseevent)) then begin + fonclientmouseevent(self,sender,aintf,info,handled); + end; +end; + +procedure tassistivewidgetitem.dokeydown(const sender:tassistivehandler; + const aintf: iassistiveclient; const info: keyeventinfoty; + var handled: boolean); +begin + if canevent(tmethod(fonkeydown)) then begin + fonkeydown(self,sender,aintf,info,handled); + end; +end; + +procedure tassistivewidgetitem.dochange(const sender:tassistivehandler; + const aintf: iassistiveclient; var handled: boolean); +begin + if canevent(tmethod(fonchange)) then begin + fonchange(self,sender,aintf,handled); + end; +end; + +procedure tassistivewidgetitem.dodbvaluechanged(const sender: tassistivehandler; + const aintf: iassistiveclientdata; var handled: boolean); +begin + if canevent(tmethod(fondbvaluechanged)) then begin + fondbvaluechanged(self,sender,aintf,handled); + end; +end; + +procedure tassistivewidgetitem.dodataentered(const sender:tassistivehandler; + const aintf: iassistiveclientdata; var handled: boolean); +begin + if canevent(tmethod(fondataentered)) then begin + fondataentered(self,sender,aintf,handled); + end; +end; + +procedure tassistivewidgetitem.docellevent(const sender:tassistivehandler; + const aintf: iassistiveclientgrid; const info: celleventinfoty; + var handled: boolean); +begin + if canevent(tmethod(foncellevent)) then begin + foncellevent(self,sender,aintf,info,handled); + end; +end; + +procedure tassistivewidgetitem.dogridbordertouched( + const sender: tassistivehandler; + const aintf: iassistiveclientgrid; + const adirection: graphicdirectionty; var handled: boolean); +begin + if canevent(tmethod(fongridbordertouched)) then begin + fongridbordertouched(self,sender,aintf,adirection,handled); + end; +end; + +procedure tassistivewidgetitem.doeditcharenter(const sender:tassistivehandler; + const aintf: iassistiveclientedit; const achar: msestring; + var handled: boolean); +begin + if canevent(tmethod(foneditcharenter)) then begin + foneditcharenter(self,sender,aintf,achar,handled); + end; +end; + +procedure tassistivewidgetitem.doeditchardelete(const sender:tassistivehandler; + const aintf: iassistiveclientedit; const achar: msestring; + var handled: boolean); +begin + if canevent(tmethod(foneditchardelete)) then begin + foneditchardelete(self,sender,aintf,achar,handled); + end; +end; + +procedure tassistivewidgetitem.doeditindexmoved(const sender:tassistivehandler; + const aintf: iassistiveclientedit; const aindex: int32; + var handled: boolean); +begin + if canevent(tmethod(foneditindexmoved)) then begin + foneditindexmoved(self,sender,aintf,aindex,handled); + end; +end; + +procedure tassistivewidgetitem.doeditwithdrawn(const sender:tassistivehandler; + const aintf: iassistiveclientedit; var handled: boolean); +begin + if canevent(tmethod(foneditwithdrawn)) then begin + foneditwithdrawn(self,sender,aintf,handled); + end; +end; + +procedure tassistivewidgetitem.doedittextblock(const sender:tassistivehandler; + const aintf: iassistiveclientedit; + const amode: edittextblockmodety; const atext: msestring; + var handled: boolean); +begin + if canevent(tmethod(fonedittextblock)) then begin + fonedittextblock(self,sender,aintf,amode,atext,handled); + end; +end; + +procedure tassistivewidgetitem.doeditinputmodeset( + const sender:tassistivehandler; const aintf: iassistiveclientedit; + const amode: editinputmodety; var handled: boolean); +begin + if canevent(tmethod(foneditinputmodeset)) then begin + foneditinputmodeset(self,sender,aintf,amode,handled); + end; +end; + +procedure tassistivewidgetitem.donavigbordertouched( + const sender:tassistivehandler; const aintf: iassistiveclient; + const adirection: graphicdirectionty; var handled: boolean); +begin + if canevent(tmethod(fonnavigbordertouched)) then begin + fonnavigbordertouched(self,sender,aintf,adirection,handled); + end; +end; + +procedure tassistivewidgetitem.dotabordertouched( + const sender: tassistivehandler; const aintf: iassistiveclient; + const adown: boolean; var handled: boolean); +begin + if canevent(tmethod(fontabordertouched)) then begin + fontabordertouched(self,sender,aintf,adown,handled); + end; +end; + +procedure tassistivewidgetitem.dodatasetevent(const sender: tassistivehandler; + const aintf: iassistiveclient; + const akind: assistivedbeventkindty; const adataset: tdataset; + var handled: boolean); +begin + if canevent(tmethod(fondatasetevent)) then begin + fondatasetevent(self,sender,aintf,akind,adataset,handled); + end; +end; + +function tassistivewidgetitem.getcaption(const sender: tassistivehandler; + const aintf: iassistiveclient): msestring; +begin + result:= fcaption; + if canevent(tmethod(fongetcaption)) then begin + fongetcaption(self,sender,aintf,result); + end; +end; + +function tassistivewidgetitem.gettext(const sender: tassistivehandler; + const aintf: iassistiveclient): msestring; +begin + result:= ftext; + if canevent(tmethod(fongettext)) then begin + fongettext(self,sender,aintf,result); + end; +end; + +function tassistivewidgetitem.gethint(const sender: tassistivehandler; + const aintf: iassistiveclient): msestring; +begin + result:= fhint; + if canevent(tmethod(fongethint)) then begin + fongethint(self,sender,aintf,result); + end; +end; + +{ tassistivewidgetitemlist } + +function tassistivewidgetitemlist.getrecordsize(): int32; +begin + result:= sizeof(assistivewidgethashdataty); +end; + +{tassistivehandler } + +constructor tassistivehandler.create(aowner: tcomponent); +begin + foptions:= defaultassistiveoptions; + fspeaker:= tassistivespeak.create(nil); + fitems:= tassistivewidgetitemlist.create(); + inherited; +end; + +destructor tassistivehandler.destroy(); +begin + inherited; + fspeaker.free(); + fitems.free(); +end; + +procedure tassistivehandler.initnewcomponent(const ascale: real); +begin + fvoicetext:= 1; + fvoicetextmessage:= 1; + fvoicetextdisp:= 2; + fvoicetextedit:= 2; + fvoicetexteditreadonly:= 2; + fspeaker.voices.count:= 3; + with fspeaker.voices[0] do begin + gender:= gen_male; + end; + with fspeaker.voices[1] do begin + gender:= gen_female; + end; + with fspeaker.voices[2] do begin + gender:= gen_female; + punctuation:= pu_all; + end; +end; + +procedure tassistivehandler.setactive(const avalue: boolean); +begin + if factive <> avalue then begin + factive:= avalue; + if not (csloading in componentstate) then begin + if avalue then begin + activate(); + end + else begin + deactivate(); + end; + end; + end; +end; + +procedure tassistivehandler.activate(); +begin + if not (csdesigning in componentstate) then begin + fspeaklock:= 0; + application.registeronshortcut(@doshortcut); + fspeaker.active:= true; + assistiveserver:= iassistiveserver(self); + assistiveoptions:= options; + fstate:= [ahs_active]; +// include(fstate,ahs_active); + application.invalidate(); + end; +end; + +procedure tassistivehandler.deactivate(); +begin + if not (csdesigning in componentstate) then begin + application.unregisteronshortcut(@doshortcut); + assistiveserver:= nil; + assistiveoptions:= []; + fspeaker.active:= false; + exclude(fstate,ahs_active); + application.invalidate(); + end; +end; + +procedure tassistivehandler.setspeaker(const avalue: tassistivespeak); +begin + fspeaker.assign(avalue); +end; + +procedure tassistivehandler.setoptions(const avalue: assistiveoptionsty); +begin + foptions:= avalue; + if ahs_active in fstate then begin + assistiveoptions:= foptions; + end; +end; + +procedure tassistivehandler.setstatfile(const avalue: tstatfile); +begin + setstatfilevar(istatfile(self),avalue,fstatfile); +end; + +procedure tassistivehandler.loaded(); +begin + inherited; + if factive then begin + factive:= false; + active:= true; + end; +end; + +procedure tassistivehandler.wait(); +begin + fspeaker.wait(); +end; + +procedure tassistivehandler.cancel(); +begin + if (fspeaklock <= 0) then begin + if not (ahs_nocut in fstate) then begin + fspeaker.cancel(); + end; + exclude(fstate,ahs_nocut); + end; +end; + +function tassistivehandler.getcaptiontext(const acaption: msestring): msestring; +var + capt1: richstringty; +begin + captiontorichstring(acaption,capt1); + result:= capt1.text; +end; + +function tassistivehandler.getcaptiontext( + const sender: iassistiveclient): msestring; +var + item1: tassistivewidgetitem; +begin + result:= ''; + if finditem(sender,item1) then begin + result:= item1.getcaption(self,sender); + end; + if result = '' then begin + result:= getcaptiontext(sender.getassistivecaption()); + end; +end; + +function tassistivehandler.gettexttext( + const sender: iassistiveclient): msestring; +var + item1: tassistivewidgetitem; +begin + result:= ''; + if finditem(sender,item1) then begin + result:= item1.gettext(self,sender); + end; + if result = '' then begin + result:= sender.getassistivetext(); + end; +end; + +function tassistivehandler.gethinttext( + const sender: iassistiveclient): msestring; +var + item1: tassistivewidgetitem; +begin + result:= ''; + if finditem(sender,item1) then begin + result:= item1.gethint(self,sender); + end; + if result = '' then begin + result:= sender.getassistivehint(); + end; +end; + +procedure tassistivehandler.focusfirstelement(const awidget: twidget); +var + w1: twidget; +begin + if awidget <> nil then begin + w1:= awidget.window.firstfocuswidget(); + if w1 <> nil then begin + w1.activate(); + end; + end; +end; + +procedure tassistivehandler.focuslastelement(const awidget: twidget); +var + w1: twidget; +begin + if awidget <> nil then begin + w1:= awidget.window.lastfocuswidget(); + if w1 <> nil then begin + w1.activate(); + end; + end; +end; + +function tassistivehandler.canspeak(): boolean; +begin + result:= fstate * [ahs_active,ahs_speaklocked,ahs_activated] = + [ahs_active,ahs_activated]; +end; + +procedure tassistivehandler.speaktext(const atext: msestring; + const avoice: int32 = 0; const nocut: boolean = false); +begin + if canspeak() then begin + if nocut then begin + include(fstate,ahs_nocut); + end; + fspeaker.speak(atext,[so_endpause],avoice); + end; +end; + +procedure tassistivehandler.speaktext1(const atext: msestring; + const avoice: int32 = 0; const nocut: boolean = false); +begin + cancel(); + speaktext(atext,avoice,nocut); +end; + +procedure tassistivehandler.speaktext(const atext: stockcaptionty; + const avoice: int32 = 0; const nocut: boolean = false); +begin + speaktext(stockobjects.captions[atext],avoice,nocut); +end; + +procedure tassistivehandler.speaktext1(const atext: stockcaptionty; + const avoice: int32 = 0; const nocut: boolean = false); +begin + cancel(); + speaktext(atext,avoice,nocut); +end; + +procedure tassistivehandler.speakcharacter(const achar: char32; + const avoice: int32 = 0; const nocut: boolean = false); +begin + if canspeak() then begin + if nocut then begin + include(fstate,ahs_nocut); + end; + fspeaker.speakcharacter(achar,[so_endpause],avoice); + end; +end; + +procedure tassistivehandler.speakall(const sender: iassistiveclient; + aoptions: speakoptionsty); +var + fla1: assistiveflagsty; + s1,s2,s3: msestring; + w1: tpopupmenuwidget1; + intf2: iassistiveclient; + i1: int32; + b1: boolean; +begin + fla1:= sender.getassistiveflags(); + intf2:= sender.getassistiveparent(); + if spo_path in aoptions then begin + exclude(aoptions,spo_parent); + aoptions:= aoptions + [spo_columncaption]; + if intf2 <> nil then begin + exclude(fla1,asf_toplevel); + speakall(intf2,aoptions+[spo_notext]); + include(aoptions,spo_addtext); + exclude(aoptions,spo_maincaption); + intf2:= nil; + end; + end + else begin + if not (spo_parent in aoptions) then begin + intf2:= nil; + end; + end; + i1:= gettextvoice(fla1); + if asf_async in fla1 then begin + include(aoptions,spo_addtext); + end; + pointer(w1):= sender.getinstance(); + if not (spo_addtext in aoptions) then begin + startspeak(); + end; +// s1:= ''; + if asf_menu in fla1 then begin + if w1 is tpopupmenuwidget then begin + speakallmenu(tmenuitem1(w1.flayout.menu).getiassistiveclient(), + spo_hint in aoptions); + exit; + end; + end; + if (intf2 <> nil) and (asf_message in intf2.getassistiveflags()) then begin + speakall(intf2,aoptions - [spo_addtext,spo_parent,spo_maincaption]); + end; + if fla1 * [asf_grid,asf_popup] = [asf_grid,asf_popup] then begin + b1:= aoptions * [spo_parent,spo_path] <> []; + if b1 and not(aso_textfirst in foptions) then begin + speaktext(sc_selection,fvoicefixed); + end; + with iassistiveclientgrid(sender) do begin + speaktext(getassistivecellcaption(mgc(getassistivefocusedcell().col,-1)), + fvoicecaption); + speaktext(getassistivecelltext(getassistivefocusedcell(),fla1),i1); + end; + if b1 and (aso_textfirst in foptions) then begin + speaktext(sc_selection,fvoicefixed); + end; + exit; + end; + s2:= ''; + if asf_button in fla1 then begin + if asf_disabled in fla1 then begin + s2:= stockobjects.captions[sc_disabledbutton] + ' '; + end + else begin + s2:= stockobjects.captions[sc_button] + ' '; + end; + end; + if asf_toplevel in fla1 then begin + if s2 <> '' then begin + s2:= sc(sc_area)+' '+s2; + end + else begin + s2:= sc(sc_area); + end; + end; +// speaktext(s1,fvoicefixed); + s1:= ''; + if (spo_columncaption in aoptions) and (asf_gridwidget in fla1) then begin + s1:= s1+iassistiveclientgridwidget(sender).getassistivecolumncaption(); + end; + s3:= getcaptiontext(sender); + if (spo_maincaption in aoptions) and (maincaption <> '') then begin + if not (asf_mainwindow in fla1) then begin + s3:= maincaption+' '+s3; + end; + end; + if s3 <> '' then begin + if s1 <> '' then begin + s1:= s1 + ' '; + end; +{ + if asf_toplevel in fla1 then begin + s1:= s1 + sc(sc_window) + ' '; + end; +} + s1:= s1 + s3; + end; + if asf_message in fla1 then begin + exclude(aoptions,spo_notext); + end; + if aso_textfirst in foptions then begin + if not (spo_notext in aoptions) then begin + speaktext(gettexttext(sender),i1); + end; + speaktext(s1,fvoicecaption); + speaktext(s2,fvoicefixed); + end + else begin + speaktext(s2,fvoicefixed); + speaktext(s1,fvoicecaption); + if not (spo_notext in aoptions) then begin + speaktext(gettexttext(sender),i1); + end; + end; + if spo_hint in aoptions then begin + speaktext(gethinttext(sender),fvoicecaption); + end; +end; + +procedure tassistivehandler.speakall(const sender: twidget; + aoptions: speakoptionsty); +begin + if sender <> nil then begin + speakall(twidget1(sender).getiassistiveclient(),aoptions); + end; +end; + +procedure tassistivehandler.speakgridcell(const sender: iassistiveclientgrid; + const acell: gridcoordty; const acaption: boolean); +var + i1: int32; + s1: msestring; + f1: assistiveflagsty; +begin + s1:= sender.getassistivecelltext(acell,f1); + i1:= gettextvoice(f1); + if aso_textfirst in foptions then begin + speaktext(s1,i1); + end; + if acaption then begin + speaktext(sender.getassistivecellcaption( + mgc(acell.col,-1)),fvoicecaption); + end; + if not (aso_textfirst in foptions) then begin + speaktext(s1,i1); + end; +end; + +procedure tassistivehandler.speakinput(const sender: iassistiveclientdata); +var + i1: int32; +begin + startspeak(); + i1:= gettextvoice(sender.getassistiveflags); + if aso_textfirst in foptions then begin + speaktext(gettexttext(sender),i1); + end; + speaktext(sc_input,fvoicefixed); + speaktext(getcaptiontext(iassistiveclient(sender)),fvoicecaption); + if not (aso_textfirst in foptions) then begin + speaktext(gettexttext(sender),i1); + end; +end; + +procedure tassistivehandler.speakmenustart(const sender: iassistiveclient); +begin + speaktext(sc_menu,fvoicefixed); +end; + +procedure tassistivehandler.setstate(const astate: assistivehandlerstatesty); +begin + fstate:= fstate + (astate-internalstates); +end; + +procedure tassistivehandler.resetstate(const astate: assistivehandlerstatesty); +begin + fstate:= fstate - (astate-internalstates); +end; + +procedure tassistivehandler.speakstop(const acancel: boolean = false); +begin + if acancel then begin + cancel; + end; + inc(fspeaklock); + if fspeaklock > 0 then begin + include(fstate,ahs_speaklocked); + end; +end; + +procedure tassistivehandler.speakcontinue(); +begin + dec(fspeaklock); + if fspeaklock <= 0 then begin + exclude(fstate,ahs_speaklocked); + end; +end; + +procedure tassistivehandler.startspeak(); +begin + cancel(); +end; + +procedure tassistivehandler.registeritem(const aintf: iassistiveclient; + const aitem: tassistivewidgetitem); +begin + with passistivewidgethashdataty(fitems.add(aintf))^ do begin + data.item:= aitem; + end; +end; + +procedure tassistivehandler.unregisteritem(const aintf: iassistiveclient); +begin + fitems.delete(aintf,true); +end; + +function tassistivehandler.finditem(aintf: iassistiveclient; + out aitem: tassistivewidgetitem): boolean; +var + p1: passistivewidgethashdataty; +begin + result:= false; + aitem:= nil; + p1:= pointer(fitems.find(aintf)); + if p1 <> nil then begin + aitem:= p1^ .data.item; + result:= true; + end; +end; + +function checkassistiveshortcut(const akind: assistiveshortcutty; + var info: keyeventinfoty): boolean; +begin + result:= false; + if not (es_processed in info.eventstate) then begin + if checkactionshortcut(assistiveshortcuts[akind],info) then begin + result:= true; + end + else begin + if not (es_processed in info.eventstate) then begin + if checkactionshortcut(assistiveshortcuts1[akind],info) then begin + result:= true; + end; + end; + end; + end; +end; + +procedure tassistivehandler.doshortcut(const sender: twidget; + var info: keyeventinfoty); +var + sho1: assistiveshortcutty; + f1: flo64; +begin + for sho1:= low(sho1) to high(sho1) do begin + if es_processed in info.eventstate then begin + break; + end; + if checkassistiveshortcut(sho1,info) then begin + case sho1 of + shoa_speakagain: begin + dospeakagain(sender); + end; + shoa_speakpath: begin + dospeakpath(sender); + end; + shoa_firstelement: begin + focusfirstelement(sender); + end; + shoa_lastelement: begin + focuslastelement(sender); + end; + shoa_cancelspeech: begin + cancel(); + end; + shoa_slower: begin + f1:= fspeaker.rate/1.1; + if f1 < ratemin then begin + f1:= ratemin; + end; + fspeaker.rate:= f1; + startspeak(); + speaktext(sc_slower,voicetext); + end; + shoa_faster: begin + f1:= fspeaker.rate*1.1; + if f1 > ratemax then begin + f1:= ratemax; + end; + fspeaker.rate:= f1; + startspeak(); + speaktext(sc_faster,voicetext); + end; + shoa_volumedown: begin + f1:= fspeaker.volume/1.1; + if f1 < volumemin then begin + f1:= volumemin; + end; + fspeaker.volume:= f1; + startspeak(); + speaktext(sc_volumedown,voicetext); + end; + shoa_volumeup: begin + f1:= fspeaker.volume*1.1; + if f1 > volumemax then begin + f1:= volumemax; + end; + fspeaker.volume:= f1; + startspeak(); + speaktext(sc_volumeup,voicetext); + end; + end; + end; + end; +end; + +procedure tassistivehandler.dospeakagain(const sender: twidget); +begin + cancel(); + speakall(twidget1(sender).getiassistiveclient(),[spo_hint,spo_parent, + spo_columncaption]); +end; + +procedure tassistivehandler.dospeakpath(const sender: twidget); +begin + cancel(); + speakall(twidget1(sender).getiassistiveclient(), + [spo_hint,spo_path,spo_maincaption]); +end; + +procedure tassistivehandler.checklocatepending(const sender: iassistiveclient); +begin + if asf_hasdropdown in sender.getassistiveflags then begin + setstate([ahs_locatepending]); + end; +end; + +function tassistivehandler.gettextvoice(const aflags: assistiveflagsty): int32; +begin + result:= fvoicetext; + if aflags * [asf_popup,asf_grid] = [asf_popup,asf_grid] then begin + result:= fvoicetexteditreadonly; + end; + if asf_message in aflags then begin + result:= fvoicetextmessage; + end; + if asf_dispwidget in aflags then begin + result:= fvoicetextdisp; + end; + if [asf_inplaceedit,asf_textedit] * aflags <> [] then begin + if asf_readonly in aflags then begin + result:= fvoicetexteditreadonly; + end + else begin + result:= fvoicetextedit; + end; + end; +end; + +{$ifdef mse_debugassistive} +procedure tassistivehandler.debug(const text: string; + const intf: iassistiveclient); +var + wi1: twidget; +begin + debugwrite('*'+text+':'+ + settostring(ptypeinfo(typeinfo(assistivehandlerstatesty)), + int32(fstate),true)); + if intf <> nil then begin + pointer(wi1):= intf.getassistivewidget(); + if wi1 <> nil then begin + debugwriteln(':'+wi1.name); + end + else begin + debugwriteln(':NIL'); + end; + debugwrite(' '+settostring(ptypeinfo(typeinfo(assistiveflagsty)), + int32(intf.getassistiveflags()),true)); + end; + debugwriteln(''); +end; +{$endif} + +procedure tassistivehandler.doapplicationactivated(); +var + b1: boolean; +begin + fstate:= fstate + [ahs_activated,ahs_applicationactivated]; +{$ifdef mse_debugassistive} + debug('applicationactivated',nil); +{$endif} + b1:= false; + if canevent(tmethod(fonapplicationactivated)) then begin + fonapplicationactivated(self,b1); + end; +end; + +procedure tassistivehandler.doapplicationdeactivated(); +var + b1: boolean; +begin + fstate:= fstate - [ahs_activated,ahs_applicationactivated, + ahs_dropdownlistclosed,ahs_dropdownpending]; +{$ifdef mse_debugassistive} + debug('applicationdeactivated',nil); +{$endif} + b1:= false; + if canevent(tmethod(fonapplicationdeactivated)) then begin + fonapplicationdeactivated(self,b1); + end; + if not b1 then begin + cancel(); + end; +end; + +procedure tassistivehandler.dowindowactivated(const sender: iassistiveclient); +var + b1: boolean; + item1: tassistivewidgetitem; + fla1: assistiveflagsty; + i1: int32; + s1: msestring; +begin +{$ifdef mse_debugassistive} + debug('windowactivated',sender); +{$endif} + include(fstate,ahs_activated); + setstate([ahs_windowactivated]); + b1:= false; + if finditem(sender,item1) then begin + item1.dowindowactivated(self,sender,b1); + end; + if not b1 then begin + if canevent(tmethod(fonwindowactivated)) then begin + fonwindowactivated(self,sender,b1); + end; + if not b1 then begin + fla1:= sender.getassistiveflags(); + if asf_menu in fla1 then begin + { + setstate([ass_menuactivated]); + if not (ass_menuactivatepending in fstate) then begin + startspeak(); + speakmenustart(sender); + end; + } + end + else begin + if fstate*[ahs_dropdownlistclosed,ahs_dropdownpending] = [] then begin + if fla1 * [asf_async,asf_message] <> [asf_async] then begin + startspeak(); + end; + i1:= gettextvoice(fla1); + s1:= getcaptiontext(sender); + if (ahs_applicationactivated in fstate) and (fmaincaption <> '') and + (not (asf_mainwindow in fla1) or (s1 = '')) then begin + s1:= fmaincaption + ' ' + s1; + end; + exclude(fstate,ahs_applicationactivated); + if aso_textfirst in foptions then begin + speaktext(gettexttext(sender),i1); + speaktext(s1,fvoicecaption); + speaktext(sc(sc_areaactivated),fvoicefixed); + end + else begin + speaktext(s1,fvoicecaption); + speaktext(sc(sc_areaactivated),fvoicefixed); + speaktext(gettexttext(sender),i1); + end; + end; + end; + end; + end; + resetstate([ahs_menuactivatepending,ahs_dropdownpending]); +end; + +procedure tassistivehandler.dowindowdeactivated(const sender: iassistiveclient); +var + b1: boolean; + item1: tassistivewidgetitem; +begin +{$ifdef mse_debugassistive} + debug('windowdeactivated',sender); +{$endif} + if sender.getassistiveflags() * [asf_popup,asf_grid] = + [asf_popup,asf_grid] then begin + setstate([ahs_dropdownlistclosed]); + end; + b1:= false; + if finditem(sender,item1) then begin + item1.dowindowdeactivated(self,sender,b1); + end; + if not b1 then begin + if canevent(tmethod(fonwindowdeactivated)) then begin + fonwindowdeactivated(self,sender,b1); + end; + if not b1 then begin + end; + end; + resetstate([ahs_windowactivated]); +end; + +procedure tassistivehandler.dowindowclosed(const sender: iassistiveclient); +var + b1: boolean; + item1: tassistivewidgetitem; +begin +{$ifdef mse_debugassistive} + debug('windowclosed',sender); +{$endif} + b1:= false; + if finditem(sender,item1) then begin + item1.dowindowclosed(self,sender,b1); + end; + if not b1 then begin + if canevent(tmethod(fonwindowclosed)) then begin + fonwindowclosed(self,sender,b1); + end; + end; +end; + +procedure tassistivehandler.doenter(const sender: iassistiveclient); +var + b1: boolean; + item1: tassistivewidgetitem; +begin +{$ifdef mse_debugassistive} + debug('enter',sender); +{$endif} + resetstate([ahs_dropdownpending]); + if (ahs_editcharenter in fstate) and + (sender.getassistiveflags*[asf_popup,asf_grid] = + [asf_popup,asf_grid]) then begin + setstate([ahs_dropdownpending]); + end; + b1:= false; + if finditem(sender,item1) then begin + item1.doenter(self,sender,b1); + end; + if not b1 then begin + if canevent(tmethod(fonenter)) then begin + fonenter(self,sender,b1); + end; + end; + resetstate([ahs_editcharenter]); +end; + +procedure tassistivehandler.doactivate(const sender: iassistiveclient); +var + b1: boolean; + item1: tassistivewidgetitem; + fla1: assistiveflagsty; + opt1: speakoptionsty; +begin +{$ifdef mse_debugassistive} + debug('activate',sender); +{$endif} + b1:= false; + if finditem(sender,item1) then begin + item1.doactivate(self,sender,b1); + end; + if not b1 then begin + if canevent(tmethod(fonactivate)) then begin + fonactivate(self,sender,b1); + end; + if twidget(sender.getassistivewidget).focused then begin + if not b1{ and not (ahs_cellwidgetpending in fstate)} then begin + fla1:= sender.getassistiveflags(); + if not (asf_dummy in fla1) then begin + if asf_menu in fla1 then begin + end + else begin + if fla1*[asf_grid,asf_popup] = [asf_grid,asf_popup] then begin + if not (aso_textfirst in foptions) then begin + speaktext(sc_selection,fvoicefixed); + end; + speakgridcell(iassistiveclientgrid(sender), + tcustomgrid(sender.getassistivewidget()).focusedcell,true); + if aso_textfirst in foptions then begin + speaktext(sc_selection,fvoicefixed); + end; + end + else begin + if not (ahs_dropdownlistclosed in fstate) and + not (asf_scrolllimit in fla1) then begin + opt1:= []; + if asf_gridwidget in fla1 then begin + setstate([ahs_dbchangepending]); + if ahs_windowactivated in fstate then begin + include(opt1,spo_columncaption); + end; + end; + if fstate * [ahs_windowactivated,ahs_cellwidgetpending] <> [] then begin + include(opt1,spo_addtext); + end; + speakall(sender,opt1); + if (aso_textfirst in foptions) and + (ahs_cellwidgetpending in fstate) then begin + speakgridcell(fgridintf,fnewcell,fnewcol); + end; + end; + end; + end; + end; + end; + end; + end; + fla1:= sender.getassistiveflags(); + if not (asf_dummy in fla1) then begin + resetstate([ahs_cellwidgetpending]); + if asf_focused in fla1 then begin + resetstate([ahs_windowactivated,ahs_dropdownlistclosed]); + end; + end; +end; + +procedure tassistivehandler.dodeactivate(const sender: iassistiveclient); +var + item1: tassistivewidgetitem; + b1: boolean; +begin +{$ifdef mse_debugassistive} + debug('deactivate',sender); +{$endif} + b1:= false; + if finditem(sender,item1) then begin + item1.dodeactivate(self,sender,b1); + end; + if not b1 then begin + if canevent(tmethod(fondeactivate)) then begin + fonactivate(self,sender,b1); + end; + end; + resetstate([ahs_dbchangepending]); +end; + +procedure tassistivehandler.doclientmouseevent(const sender: iassistiveclient; + const info: mouseeventinfoty); +var + b1: boolean; + item1: tassistivewidgetitem; +begin +{$ifdef mse_debugassistive} + debug('clientmouseevent',sender); +{$endif} + b1:= false; + if finditem(sender,item1) then begin + item1.doclientmouseevent(self,sender,info,b1); + end; + if not b1 then begin + if canevent(tmethod(fonclientmouseevent)) then begin + fonclientmouseevent(self,sender,info,b1); + end; + end; +end; + +procedure tassistivehandler.dofocuschanged(const sender: iassistiveclient; + const oldwidget: iassistiveclient; const newwidget: iassistiveclient); +var + b1: boolean; +begin +{$ifdef mse_debugassistive} + debug('focuschanged',sender); +{$endif} + b1:= false; + if canevent(tmethod(fonfocuschanged)) then begin + fonfocuschanged(self,oldwidget,newwidget,b1); + end; +end; + +procedure tassistivehandler.dokeydown(const sender: iassistiveclient; + const info: keyeventinfoty); +//var +// fla1: assistiveflagsty; +begin +{$ifdef mse_debugassistive} + debug('keydown',sender); +{$endif} + if not (es_child in info.eventstate) then begin + { + if (info.key = key_return) and + (info.shiftstate*keyshiftstatesmask = []) then begin + if info.serial <> fdataenteredkeyserial then begin + speakall(sender,false,true); + end; + end; + } + fdataenteredkeyserial:= 0; + end; +end; + +procedure tassistivehandler.doactionexecute(const sender: iassistiveclient; + const senderobj: tobject; const info: actioninfoty); +var + b1: boolean; +begin +{$ifdef mse_debugassistive} + debug('actionexecute',sender); +{$endif} + b1:= false; + if canevent(tmethod(fonactionexecute)) then begin + fonactionexecute(self,sender,senderobj,info,b1); + end; +end; + +procedure tassistivehandler.dochange(const sender: iassistiveclient); +var + b1: boolean; + item1: tassistivewidgetitem; +begin +{$ifdef mse_debugassistive} + debug('change',sender); +{$endif} + b1:= false; + if finditem(sender,item1) then begin + item1.dochange(self,sender,b1); + end; + if not b1 then begin + if canevent(tmethod(fonchange)) then begin + fonchange(self,sender,b1); + end; + end; +end; + +procedure tassistivehandler.dodataentered(const sender: iassistiveclientdata); +var + b1: boolean; + item1: tassistivewidgetitem; +begin +{$ifdef mse_debugassistive} + debug('dataentered',sender); +{$endif} + fdataenteredkeyserial:= 0; + if application.keyeventinfo <> nil then begin + fdataenteredkeyserial:= application.keyeventinfo^.serial; + end; + b1:= false; + if finditem(sender,item1) then begin + item1.doenter(self,sender,b1); + end; + if not b1 then begin + if canevent(tmethod(fonenter)) then begin + fonenter(self,sender,b1); + end; + if not b1 then begin + speakinput(sender); + end; + end; +end; + +procedure tassistivehandler.dodbvaluechanged(const sender: iassistiveclientdata); +var + b1: boolean; + item1: tassistivewidgetitem; +begin +{$ifdef mse_debugassistive} + debug('dbvaluechanged',sender); +{$endif} + b1:= false; + if finditem(sender,item1) then begin + item1.dodbvaluechanged(self,sender,b1); + end; + if not b1 then begin + if canevent(tmethod(fondbvaluechanged)) then begin + fondbvaluechanged(self,sender,b1); + end; + if not b1 and not (ahs_dbchangepending in fstate) then begin + startspeak(); + speaktext(gettexttext(sender),gettextvoice(sender.getassistiveflags())); + end; + end; + resetstate([ahs_dbchangepending]); +end; + +procedure tassistivehandler.docellevent(const sender: iassistiveclientgrid; + const info: celleventinfoty); +var + b1: boolean; + item1: tassistivewidgetitem; + f1: assistiveflagsty; +begin +{$ifdef mse_debugassistive} + debug('cellevent '+ + getenumname(typeinfo(celleventkindty),int32(info.eventkind)),sender); +{$endif} + b1:= false; + if finditem(sender,item1) then begin + item1.docellevent(self,sender,info,b1); + end; + if not b1 then begin + if canevent(tmethod(foncellevent)) then begin + foncellevent(self,sender,info,b1); + end; + if {not b1 and} twidget(sender.getassistivewidget()).active then begin + with info do begin + case eventkind of + cek_enter: begin + f1:= sender.getassistiveflags(); + if not b1 and ((cellbefore.col <> cell.col) or + (cellbefore.row <> cell.row)) and + not (asf_scrolllimit in f1) then begin + if not (ahs_locatepending in fstate) then begin + startspeak(); + end; + b1:= cellbefore.col <> cell.col; + if b1 and (asf_widgetcell in f1) then begin + if not (aso_textfirst in foptions) then begin + speakgridcell(sender,cell,b1); + end; + fgridintf:= sender; + fnewcol:= b1; + fnewcell:= cell; + setstate([ahs_cellwidgetpending]); + end + else begin + speakgridcell(sender,cell,b1); + end; + end; + resetstate([ahs_locatepending]); + end; + end; + end; + end; + end; +end; + +procedure tassistivehandler.dogridbordertouched( + const sender: iassistiveclientgrid; + const adirection: graphicdirectionty); +var + b1: boolean; + item1: tassistivewidgetitem; + ca1: stockcaptionty; +begin +{$ifdef mse_debugassistive} + debug('gridbordertouched',sender); +{$endif} + b1:= false; + if finditem(sender,item1) then begin + item1.dogridbordertouched(self,sender,adirection,b1); + end; + if not b1 then begin + if canevent(tmethod(fongridbordertouched)) then begin + fongridbordertouched(self,sender,adirection,b1); + end; + if not b1 and twidget(sender.getassistivewidget()).active then begin + case adirection of + gd_left: begin + ca1:= sc_firstcol; + end; + gd_up: begin + if asf_db in sender.getassistiveflags then begin + ca1:= sc_bof; + end + else begin + ca1:= sc_firstrow; + end; + end; + gd_right: begin + ca1:= sc_lastcol; + end; + gd_down: begin + if asf_db in sender.getassistiveflags then begin + ca1:= sc_eof; + end + else begin + ca1:= sc_lastrow; + end; + end; + else begin + exit; + end; + end; + startspeak(); + speaktext(ca1,fvoicefixed); + end; + end; +end; + +procedure tassistivehandler.doeditcharenter(const sender: iassistiveclientedit; + const achar: msestring); +var + b1: boolean; + item1: tassistivewidgetitem; +begin +{$ifdef mse_debugassistive} + debug('editcharenter',sender); +{$endif} + setstate([ahs_editcharenter]); + b1:= false; + if finditem(sender,item1) then begin + item1.doeditcharenter(self,sender,achar,b1); + end; + if not b1 then begin + if canevent(tmethod(foneditcharenter)) then begin + foneditcharenter(self,sender,achar,b1); + end; + if not b1 then begin + if not (ahs_textblock1 in fstate) then begin + startspeak(); + end + else begin +// if not(aso_textfirst in foptions) then begin +// speaktext(sc_input,fvoicefixed); +// end; + end; + if length(achar) = 1 then begin + speakcharacter(getucs4char(achar,1),fvoicetextedit); + end + else begin + speaktext(achar,fvoicetextedit); + end; +// if (aso_textfirst in foptions) and (ahs_textblock1 in fstate) then begin +// speaktext(sc_input,fvoicefixed); +// end; + exclude(fstate,ahs_textblock1); + end; + end; + checklocatepending(sender); +end; + +procedure tassistivehandler.doeditchardelete(const sender: iassistiveclientedit; + const achar: msestring); +var + b1: boolean; + item1: tassistivewidgetitem; +begin +{$ifdef mse_debugassistive} + debug('editchardelete',sender); +{$endif} + setstate([ahs_textblock,ahs_editchardelete]); + b1:= false; + if finditem(sender,item1) then begin + item1.dochange(self,sender,b1); + end; + if not b1 then begin + if canevent(tmethod(fonchange)) then begin + fonchange(self,sender,b1); + end; + end; + if not b1 then begin + startspeak(); + if not(aso_textfirst in foptions) then begin + speaktext(sc_deleted,fvoicefixed); + end; + if length(achar) = 1 then begin + speakcharacter(getucs4char(achar,1),fvoicetextedit); + end + else begin + speaktext(achar,fvoicetextedit); + end; + if aso_textfirst in foptions then begin + speaktext(sc_deleted,fvoicefixed); + end; + end; + checklocatepending(sender); +end; + +procedure tassistivehandler.doeditindexmoved(const sender: iassistiveclientedit; + const aindex: int32); +var + b1: boolean; + item1: tassistivewidgetitem; + s1: msestring; + i1: int32; + f1: assistiveflagsty; +begin +{$ifdef mse_debugassistive} + debug('editindexmoved',sender); +{$endif} + b1:= false; + if finditem(sender,item1) then begin + item1.doeditindexmoved(self,sender,aindex,b1); + end; + if not b1 then begin + if canevent(tmethod(foneditindexmoved)) then begin + foneditindexmoved(self,sender,aindex,b1); + end; + if not b1 then begin + if not (ahs_textblock in fstate) then begin + startspeak(); + end; + s1:= sender.getassistivetext(); + f1:= sender.getassistiveflags(); + i1:= gettextvoice(f1); + if aindex < length(s1) then begin + if aindex = 0 then begin + speaktext(sc_beginoftext,fvoicefixed); + end; + speakcharacter(getucs4char(s1,aindex+1),i1); + end + else begin + speaktext(sc_endoftext,fvoicefixed); + end; + end; + end; + exclude(fstate,ahs_textblock); +end; + +procedure tassistivehandler.doeditwithdrawn(const sender: iassistiveclientedit); +var + b1: boolean; + item1: tassistivewidgetitem; +begin +{$ifdef mse_debugassistive} + debug('editwithdrawn',sender); +{$endif} + include(fstate,ahs_textblock); + b1:= false; + if finditem(sender,item1) then begin + item1.doeditwithdrawn(self,sender,b1); + end; + if not b1 then begin + if canevent(tmethod(foneditwithdrawn)) then begin + foneditwithdrawn(self,sender,b1); + end; + if not b1 then begin + startspeak(); + if not(aso_textfirst in foptions) then begin + speaktext(sc_withdrawn,fvoicefixed); + end; + speaktext(sender.getassistivetext(), + gettextvoice(sender.getassistiveflags())); + if aso_textfirst in foptions then begin + speaktext(sc_withdrawn,fvoicefixed); + end; + end; + end; +end; + +procedure tassistivehandler.doedittextblock(const sender: iassistiveclientedit; + const amode: edittextblockmodety; const atext: msestring); +var + b1: boolean; + item1: tassistivewidgetitem; + sc1: stockcaptionty; + f1: assistiveflagsty; + i1: int32; +begin +{$ifdef mse_debugassistive} + debug('edittextblock',sender); +{$endif} + fstate:= fstate + [ahs_textblock,ahs_textblock1]; + b1:= false; + if finditem(sender,item1) then begin + item1.doedittextblock(self,sender,amode,atext,b1); + end; + if not b1 then begin + if canevent(tmethod(fonedittextblock)) then begin + fonedittextblock(self,sender,amode,atext,b1); + end; + if not b1 then begin + case amode of + etbm_delete: begin + sc1:= sc_deleted; + end; + etbm_cut: begin + sc1:= sc_cut; + end; + etbm_copy: begin + sc1:= sc_copied; + end; + etbm_insert: begin + sc1:= sc_inserted; + end; + etbm_paste: begin + sc1:= sc_pasted; + end; + else begin + exit; + end; + end; + startspeak(); + f1:= sender.getassistiveflags(); + if not(aso_textfirst in foptions) then begin + speaktext(sc1,fvoicefixed); + end; + i1:= gettextvoice(f1); + speaktext(atext,i1); + if aso_textfirst in foptions then begin + speaktext(sc1,fvoicefixed); + end; + end; + end; +end; + +procedure tassistivehandler.doeditinputmodeset( + const sender: iassistiveclientedit; const amode: editinputmodety); +var + b1: boolean; + item1: tassistivewidgetitem; +begin +{$ifdef mse_debugassistive} + debug('editinputmodeset',sender); +{$endif} + b1:= false; + if finditem(sender,item1) then begin + item1.doeditinputmodeset(self,sender,amode,b1); + end; + if not b1 then begin + if canevent(tmethod(foneditinputmodeset)) then begin + foneditinputmodeset(self,sender,amode,b1); + end; + if not b1 then begin + startspeak(); + if not(aso_textfirst in foptions) then begin + speaktext(sc_inputmode,fvoicefixed); + end; + case amode of + eim_insert: begin + speaktext(sc_insert,fvoicetexteditreadonly); + end; + eim_overwrite: begin + speaktext(sc_overwrite,fvoicetexteditreadonly); + end; + end; + if aso_textfirst in foptions then begin + speaktext(sc_inputmode,fvoicefixed); + end; + end; + end; +end; + +procedure tassistivehandler.donavigbordertouched(const sender: iassistiveclient; + const adirection: graphicdirectionty); +var + b1: boolean; + item1: tassistivewidgetitem; + ca1: stockcaptionty; +begin +{$ifdef mse_debugassistive} + debug('navigbordertouched',sender); +{$endif} + b1:= false; + if finditem(sender,item1) then begin + item1.donavigbordertouched(self,sender,adirection,b1); + end; + if not b1 then begin + if canevent(tmethod(fonnavigbordertouched)) then begin + fonnavigbordertouched(self,sender,adirection,b1); + end; + if not b1 then begin + case adirection of + gd_left: begin + ca1:= sc_leftborder; + end; + gd_up: begin + ca1:= sc_topborder; + end; + gd_right: begin + ca1:= sc_rightborder; + end; + gd_down: begin + ca1:= sc_bottomborder; + end; + else begin + exit; + end; + end; + startspeak(); + speaktext(ca1,fvoicefixed); + end; + end; +end; + +procedure tassistivehandler.dotabordertouched(const sender: iassistiveclient; + const adown: boolean); +var + b1: boolean; + item1: tassistivewidgetitem; + ca1: stockcaptionty; +begin +{$ifdef mse_debugassistive} + debug('tabordertouched',sender); +{$endif} + b1:= false; + if finditem(sender,item1) then begin + item1.dotabordertouched(self,sender,adown,b1); + end; + if not b1 then begin + if canevent(tmethod(fonnavigbordertouched)) then begin + fontabordertouched(self,sender,adown,b1); + end; + if not b1 then begin + if adown then begin + ca1:= sc_firstfield; + end + else begin + ca1:= sc_lastfield; + end; + startspeak(); + speaktext(ca1,fvoicefixed); + end; + end; +end; + +procedure tassistivehandler.doitementer(const sender: iassistiveclient; + const items: shapeinfoarty; const aindex: integer); +var + b1: boolean; +begin +{$ifdef mse_debugassistive} + debug('shapeitementer',sender); +{$endif} + b1:= false; + if canevent(tmethod(fonitementer)) then begin + fonitementer(self,sender,items,aindex,b1); + end; + if not b1 then begin + //todo + end; +end; + +procedure tassistivehandler.speakallmenu(const sender: iassistiveclientmenu; + const ahint: boolean); +begin + startspeak(); + speakmenustart(sender); + speaktext(getcaptiontext(sender.getassistiveselfcaption()),fvoicecaption); + speaktext(getcaptiontext(sender.getassistivecaption()),fvoicetext); + if ahint then begin + speaktext(sender.getassistivehint(),fvoicecaption); + end; +end; + +procedure tassistivehandler.domenuactivated(const sender: iassistiveclientmenu); +var + b1: boolean; +begin +{$ifdef mse_debugassistive} + debug('menuactivated',sender); +{$endif} + setstate([ahs_menuactivated]); + b1:= false; + if canevent(tmethod(fonmenuactivated)) then begin + fonmenuactivated(self,sender,b1); + end; + if not b1 then begin + speakallmenu(sender,false); + end; +end; + +procedure tassistivehandler.doitementer(const sender: iassistiveclientmenu; + const items: menucellinfoarty; const aindex: integer); +var + b1: boolean; +begin +{$ifdef mse_debugassistive} + debug('menuitementer',sender); +{$endif} + b1:= false; + if canevent(tmethod(fonmenuitementer)) then begin + fonmenuitementer(self,sender,items,aindex,b1); + end; + if not b1 then begin + if not (ahs_menuactivated in fstate) then begin + startspeak(); + speaktext(getcaptiontext(iassistiveclient(sender)),fvoicetext); + end; + end; + resetstate([ahs_menuactivated]); +end; + +procedure tassistivehandler.dodatasetevent(const sender: iassistiveclient; + const akind: assistivedbeventkindty; const adataset: pointer); +var + b1: boolean; + item1: tassistivewidgetitem; + sc1: stockcaptionty; +begin +{$ifdef mse_debugassistive} + debug('datasetevent',sender); +{$endif} + b1:= false; + if finditem(sender,item1) then begin + item1.dodatasetevent(self,sender,akind,tdataset(adataset),b1); + end; + if not b1 then begin + if canevent(tmethod(fondatasetevent)) then begin + fondatasetevent(self,sender,akind,tdataset(adataset),b1); + end; + if not b1 then begin + case akind of + adek_bof: begin + sc1:= sc_bof; + end; + adek_eof: begin + sc1:= sc_eof; + end; + else begin + sc1:= sc_none; + end; + end; + if sc1 <> sc_none then begin + startspeak(); + speaktext(sc1,fvoicefixed); + end; + end; + end; +end; + +procedure tassistivehandler.dostatread(const reader: tstatreader); +begin + if reader.canstate then begin + with fspeaker do begin + if aso_savelanguage in foptions then begin + language:= reader.readmsestring('language',language); + end; + if aso_savegender in foptions then begin + gender:= genderty(reader.readinteger('gender',ord(gender),ord(low(gender)), + ord(high(gender)))); + end; + if aso_saveage in foptions then begin + age:= reader.readinteger('age',age,0,100); + end; + if aso_savevolume in foptions then begin + volume:= reader.readreal('volume',volume,0,2); + end; + if aso_saverate in foptions then begin + rate:= reader.readreal('rate',rate,0.1,10); + end; + if aso_savepitch in foptions then begin + pitch:= reader.readreal('pitch',pitch,0.2,5); + end; + if aso_saverange in foptions then begin + range:= reader.readreal('range',pitch,0.2,5); + end; + if aso_savecapitals in foptions then begin + capitals:= reader.readinteger('capitals',capitals,0,300); + end; + if aso_savewordgap in foptions then begin + wordgap:= reader.readinteger('wordgap',wordgap,0,100); + end; + end; + end; +end; + +procedure tassistivehandler.dostatwrite(const writer: tstatwriter); +begin + if writer.canstate then begin + with fspeaker do begin + if aso_savelanguage in foptions then begin + writer.writemsestring('language',msestring(language)); + end; + if aso_savegender in foptions then begin + writer.writeinteger('gender',ord(gender)); + end; + if aso_saveage in foptions then begin + writer.writeinteger('age',age); + end; + if aso_savevolume in foptions then begin + writer.writereal('volume',volume); + end; + if aso_saverate in foptions then begin + writer.writereal('rate',rate); + end; + if aso_savepitch in foptions then begin + writer.writereal('pitch',pitch); + end; + if aso_saverange in foptions then begin + writer.writereal('range',pitch); + end; + if aso_savecapitals in foptions then begin + writer.writeinteger('capitals',capitals); + end; + if aso_savewordgap in foptions then begin + writer.writeinteger('wordgap',wordgap); + end; + end; + end; +end; + +procedure tassistivehandler.statreading(); +begin + //dummy +end; + +procedure tassistivehandler.statread(); +begin + //dummy +end; + +function tassistivehandler.getstatvarname(): msestring; +begin + result:= fstatvarname; +end; + +function tassistivehandler.getstatpriority(): integer; +begin + result:= fstatpriority; +end; + +end. diff --git a/mseide-msegui/lib/common/audio/mseaudio.pas b/mseide-msegui/lib/common/audio/mseaudio.pas new file mode 100644 index 0000000..4386c74 --- /dev/null +++ b/mseide-msegui/lib/common/audio/mseaudio.pas @@ -0,0 +1,357 @@ +{ MSEgui Copyright (c) 2010-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseaudio; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,mseclasses,msethread,msetypes,msepulseglob,msepulsesimple, + msesys,msestrings; + +type + + sampleformatty = (sfm_u8,sfm_8alaw,sfm_8ulaw, + sfm_s16,sfm_s24,sfm_s32,sfm_f32,smf_s2432, + sfm_s16le,sfm_s24le,sfm_s32le,sfm_f32le,smf_s2432le, + sfm_s16be,sfm_s24be,sfm_s32be,sfm_f32be,smf_s2432be); +const + defaultsampleformat = sfm_s16; + defaultsamplechannels = 1; + defaultsamplerate = 44100; + defaultlatency = 0.1; + +{$ifdef endian_little} + pulsesampleformatmatrix: array[sampleformatty] of pa_sample_format_t = + //sfm_u8, sfm_8alaw, sfm_8ulaw, + (PA_SAMPLE_U8,PA_SAMPLE_ALAW,PA_SAMPLE_ULAW, + //sfm_s16, sfm_s24, sfm_s32, + PA_SAMPLE_S16LE,PA_SAMPLE_S24LE,PA_SAMPLE_S32LE, + //sfm_f32, smf_s2432, + PA_SAMPLE_FLOAT32LE,PA_SAMPLE_S24_32LE, + //sfm_s16le, sfm_s24le, sfm_s32le, + PA_SAMPLE_S16LE,PA_SAMPLE_S24LE,PA_SAMPLE_S32LE, + //sfm_f32le, smf_s2432le, + PA_SAMPLE_FLOAT32LE,PA_SAMPLE_S24_32LE, + //sfm_s16be, sfm_s24be, sfm_s32be, + PA_SAMPLE_S16BE,PA_SAMPLE_S24BE,PA_SAMPLE_S32BE, + //sfm_f32be, smf_s2432be); + PA_SAMPLE_FLOAT32BE,PA_SAMPLE_S24_32BE); +{$else} + pulsesampleformatmatrix: array[sampleformatty] of pa_sample_format_t = + //sfm_u8, sfm_8alaw, sfm_8ulaw, + (PA_SAMPLE_U8,PA_SAMPLE_ALAW,PA_SAMPLE_ULAW, + //sfm_s16, sfm_s24, sfm_s32, + PA_SAMPLE_S16BE,PA_SAMPLE_S24BE,PA_SAMPLE_S32BE, + //sfm_f32, smf_s2432, + PA_SAMPLE_FLOAT32BE,PA_SAMPLE_S24_32BE, + //sfm_s16le, sfm_s24le, sfm_s32le, + PA_SAMPLE_S16LE,PA_SAMPLE_S24LE,PA_SAMPLE_S32LE, + //sfm_f32le, smf_s2432le, + PA_SAMPLE_FLOAT32LE,PA_SAMPLE_S24_32LE, + //sfm_s16be, sfm_s24be, sfm_s32be, + PA_SAMPLE_S16BE,PA_SAMPLE_S24BE,PA_SAMPLE_S32BE, + //sfm_f32be, smf_s2432be); + PA_SAMPLE_FLOAT32BE,PA_SAMPLE_S24_32BE); +{$endif} + + samplesizematrix: array[sampleformatty] of integer = + //sfm_u8, sfm_8alaw, sfm_8ulaw, + (1, 1, 1, + //sfm_s16, sfm_s24, sfm_s32, + 2, 1, 4, + //sfm_f32, smf_s2432, + 4, 4, + //sfm_s16le, sfm_s24le, sfm_s32le, + 2, 1, 4, + //sfm_f32le, smf_s2432le, + 4, 4, + //sfm_s16be, sfm_s24be, sfm_s32be, + 2, 1, 4, + //sfm_f32be, smf_s2432be); + 4, 4); + + samplebuffersizematrix: array[sampleformatty] of integer = + //sfm_u8, sfm_8alaw, sfm_8ulaw, + (1, 1, 1, + //sfm_s16, sfm_s24, sfm_s32, + 2, 3, 4, + //sfm_f32, smf_s2432, + 4, 4, + //sfm_s16le, sfm_s24le, sfm_s32le, + 2, 3, 4, + //sfm_f32le, smf_s2432le, + 4, 4, + //sfm_s16be, sfm_s24be, sfm_s32be, + 2, 3, 4, + //sfm_f32be, smf_s2432be); + 4, 4); + +type + + toutstreamthread = class(tmsethread) + end; + + sendeventty = procedure(var data: pointer) of object; + //data = + //bytearty (sfm_u8,sfm_8alaw,sfm_8ulaw, + // sfm_s24,sfm_s24le,sfm_s24be) + //smallintarty (sfm_s16,sfm_s16le,sfm_s16be) + //integerarty (sfm_s32,smf_s2432,sfm_s32le,smf_s2432le, + // sfm_s32be,smf_s2432be) + //or singlearty (sfm_f32,sfm_f32le,sfm_f32be) + + erroreventty = procedure(const sender: tobject; const errorcode: integer; + const errortext: msestring) of object; + + tcustomaudioout = class(tmsecomponent) + private + fthread: toutstreamthread; + fstacksizekb: integer; + fonsend: sendeventty; + fonerror: erroreventty; + fserver: msestring; + fdev: msestring; + fchannels: integer; + frate: integer; + flatency: real; + procedure setactive(const avalue: boolean); + protected + factive: boolean; + fformat: sampleformatty; + fappname: msestring; + fstreamname: msestring; + fpulsestream: ppa_simple; + procedure initnames; virtual; + procedure loaded; override; + procedure run; virtual; + procedure stop; virtual; + function threadproc(sender: tmsethread): integer; virtual; + procedure raiseerror(const aerror: integer); + procedure doerror(const aerror: integer); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; +// function lock: boolean; +// procedure unlock; + procedure flush(); + procedure drain(); + + property active: boolean read factive write setactive default false; + property server: msestring read fserver write fserver; + property dev: msestring read fdev write fdev; + property appname: msestring read fappname write fappname; + property streamname: msestring read fstreamname write fstreamname; + property channels: integer read fchannels write fchannels + default defaultsamplechannels; + property format: sampleformatty read fformat write fformat + default defaultsampleformat; + property rate: integer read frate write frate default defaultsamplerate; + property stacksizekb: integer read fstacksizekb write fstacksizekb default 0; + property latency: real read flatency write flatency; + //seconds, 0 -> server default + property onsend: sendeventty read fonsend write fonsend; + property onerror: erroreventty read fonerror write fonerror; + end; + + taudioout = class(tcustomaudioout) + published + property active; + property server; + property dev; + property appname; + property streamname; + property channels; + property format; + property rate; + property latency; + property stacksizekb; + property onsend; + property onerror; + end; + +implementation +uses + sysutils,msesysintf,mseapplication,msepulse; + +{ tcustomaudioout } + +constructor tcustomaudioout.create(aowner: tcomponent); +begin +// syserror(sys_mutexcreate(fmutex),self); + fchannels:= defaultsamplechannels; + fformat:= defaultsampleformat; + frate:= defaultsamplerate; + flatency:= defaultlatency; + inherited; +end; + +destructor tcustomaudioout.destroy; +begin + active:= false; + inherited; +// sys_mutexdestroy(fmutex); +end; + +procedure tcustomaudioout.flush(); +begin + if fpulsestream <> nil then begin + pa_simple_flush(fpulsestream,nil); + end; +end; + +procedure tcustomaudioout.drain(); +begin + if fpulsestream <> nil then begin + pa_simple_drain(fpulsestream,nil); + end; +end; + +procedure tcustomaudioout.setactive(const avalue: boolean); +begin + if factive <> avalue then begin + if componentstate * [csloading,csdesigning] = [] then begin + if not avalue then begin + stop; + end + else begin + run; + end; + end + else begin + factive:= avalue; + end; + end; +end; + +procedure tcustomaudioout.stop; +begin + if fthread <> nil then begin + fthread.terminate; + application.waitforthread(fthread); + freeandnil(fthread); + pa_simple_free(fpulsestream); + releasepulsesimple; + end; + factive:= false; +end; + +procedure tcustomaudioout.run; +var + ss: pa_sample_spec; + int1: integer; + buattr: pa_buffer_attr; +begin + initializepulsesimple([]); + fillchar(ss,sizeof(ss),0); + fillchar(buattr,sizeof(buattr),0); + with buattr do begin + maxlength:= longword(-1); + tlength:= longword(-1); + prebuf:= longword(-1); + minreq:= longword(-1); + fragsize:= longword(-1); + end; + if flatency > 0 then begin + int1:= round(flatency*frate*samplebuffersizematrix[fformat]*fchannels); + buattr.tlength:= int1; + end; + ss.format:= pulsesampleformatmatrix[fformat]; + ss.rate:= frate; + ss.channels:= fchannels; + fpulsestream:= pa_simple_new(pointer(string(fserver)), + pointer(string(fappname)), + pa_stream_playback,pointer(string(fdev)), + pointer(string(fstreamname)), + @ss,nil,@buattr,@int1); + if fpulsestream = nil then begin + raiseerror(int1); + end; + fthread:= toutstreamthread.create({$ifdef FPC}@{$endif}threadproc,false, + fstacksizekb); + factive:= true; +end; + +procedure tcustomaudioout.initnames; +begin + if fappname = '' then begin + fappname:= application.applicationname; + end; + if fstreamname = '' then begin + fstreamname:= msestring(name); + end; +end; + +procedure tcustomaudioout.loaded; +begin + inherited; + if not (csdesigning in componentstate) then begin + initnames; + if factive and (fthread = nil) then begin + run; + end; + end; +end; +{ +function tcustomaudioout.lock: boolean; +begin + result:= sys_mutexlock(fmutex) = sye_ok; +end; + +procedure tcustomaudioout.unlock; +begin + sys_mutexunlock(fmutex); +end; +} +function tcustomaudioout.threadproc(sender: tmsethread): integer; +var + data: pointer; + int1: integer; + datasize: integer; +begin + result:= 0; + if canevent(tmethod(fonsend)) then begin + factive:= true; + datasize:= samplesizematrix[fformat]; + while not sender.terminated do begin + data:= nil; +// lock; +// try + fonsend(data); +// finally +// unlock; +// end; + if data <> nil then begin + if pa_simple_write(fpulsestream,data,length(bytearty(data))*datasize, + @int1) <> 0 then begin + doerror(int1); + break; + end; + end; + end; + end; +end; + +procedure tcustomaudioout.raiseerror(const aerror: integer); +begin + raise exception.create(pa_strerror(aerror)); +end; + +procedure tcustomaudioout.doerror(const aerror: integer); +begin + application.lock; + try + if canevent(tmethod(fonerror)) then begin + fonerror(self,aerror,pa_strerror(aerror)); + end; + finally + application.unlock; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/audio/mseespeakng.pas b/mseide-msegui/lib/common/audio/mseespeakng.pas new file mode 100644 index 0000000..3ac3893 --- /dev/null +++ b/mseide-msegui/lib/common/audio/mseespeakng.pas @@ -0,0 +1,465 @@ +{/* eSpeak NG API. + * + * Copyright (C) 2015-2017 Reece H. Dunn + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */} + +unit mseespeakng; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msectypes,msetypes,sysutils,msestrings; + {$packrecords c} + +const +{$ifdef mswindows} +// {$define wincall} + espeaknglib: array[0..0] of filenamety = ( + 'libespeak-ngwo.dll'); +{$else} + espeaknglib: array[0..1] of filenamety = + ('libespeak-ngsync.so.1','libespeak-ngsync.so'); +{$endif} + + ENS_GROUP_MASK = $70000000; + ENS_GROUP_ERRNO = $00000000; //* Values 0-255 map to errno error codes. */ + ENS_GROUP_ESPEAK_NG = $10000000; //* eSpeak NG error codes. */ + +//* eSpeak NG 1.49.0 */ + ENS_OK = 0; + ENS_COMPILE_ERROR = $100001FF; + ENS_VERSION_MISMATCH = $100002FF; + ENS_FIFO_BUFFER_FULL = $100003FF; + ENS_NOT_INITIALIZED = $100004FF; + ENS_AUDIO_ERROR = $100005FF; + ENS_VOICE_NOT_FOUND = $100006FF; + ENS_MBROLA_NOT_FOUND = $100007FF; + ENS_MBROLA_VOICE_NOT_FOUND = $100008FF; + ENS_EVENT_BUFFER_FULL = $100009FF; + ENS_NOT_SUPPORTED = $10000AFF; + ENS_UNSUPPORTED_PHON_FORMAT = $10000BFF; + ENS_NO_SPECT_FRAMES = $10000CFF; + ENS_EMPTY_PHONEME_MANIFEST = $10000DFF; + ENS_SPEECH_STOPPED = $10000EFF; + +//* eSpeak NG 1.49.2 */ + ENS_UNKNOWN_PHONEME_FEATURE = $10000FFF; + ENS_UNKNOWN_TEXT_ENCODING = $100010FF; + + espeakCHARS_AUTO = 0; + espeakCHARS_UTF8 = 1; + espeakCHARS_8BIT = 2; + espeakCHARS_WCHAR = 3; + espeakCHARS_16BIT = 4; + espeakSSML = $10; + espeakPHONEMES = $100; + espeakENDPAUSE = $1000; + espeakKEEP_NAMEDATA = $2000; + + ENOUTPUT_MODE_SYNCHRONOUS = $0001; + ENOUTPUT_MODE_SPEAK_AUDIO = $0002; + +// values for 'value' in espeak_SetParameter(espeakRATE, value, 0), nominally in words-per-minute + espeakRATE_MINIMUM = 80; + espeakRATE_MAXIMUM = 450; + espeakRATE_NORMAL = 175; + +type + espeak_ng_OUTPUT_MODE = cint32; + + espeak_PARAMETER = ( + espeakSILENCE=0, //* internal use */ + espeakRATE=1, + espeakVOLUME=2, + espeakPITCH=3, + espeakRANGE=4, + espeakPUNCTUATION=5, + espeakCAPITALS=6, + espeakWORDGAP=7, + espeakOPTIONS=8, // reserved for misc. options. not yet used + espeakINTONATION=9, + + espeakRESERVED1=10, + espeakRESERVED2=11, + espeakEMPHASIS, //* internal use */ + espeakLINELENGTH, //* internal use */ + espeakVOICETYPE, // internal, 1=mbrola + N_SPEECH_PARAM //* last enum */ + ); + + espeak_POSITION_TYPE = ( + POS_CHARACTER = 1, + POS_WORD, + POS_SENTENCE + ); + + espeak_VOICE = record + name: pcchar; // a given name for this voice. UTF8 string. + languages: pcchar; // list of pairs of (byte) priority + + //(string) language (and dialect qualifier) + identifier: pcchar; // the filename for this voice within + //espeak-ng-data/voices + gender: cuchar; // 0=none 1=male, 2=female, + age: cuchar; // 0=not specified, or age in years + variant: cuchar; // only used when passed as a parameter to + //espeak_SetVoiceByProperties + xx1: cuchar; // for internal use + score: cint; // for internal use + spare: pointer; // for internal use + end; + pespeak_VOICE = ^ espeak_VOICE; + + + espeak_ng_STATUS = cuint; + { + espeak_ng_OUTPUT_MODE = ( + ENOUTPUT_MODE_SYNCHRONOUS = $0001, + ENOUTPUT_MODE_SPEAK_AUDIO = $0002 + ); +} + espeak_ng_CONTEXT_TYPE = ( + ERROR_CONTEXT_FILE, + ERROR_CONTEXT_VERSION + ); + + espeak_ng_ERROR_CONTEXT_ = record + _type: espeak_ng_CONTEXT_TYPE; + name: pchar; + version: cint; + expected_version: cint; + end; + espeak_ng_ERROR_CONTEXT = ^espeak_ng_ERROR_CONTEXT_; + + tespeakerror = class(exception) + public + constructor create(const err: espeak_ng_STATUS; const atext: string=''); + end; + +var + espeak_ng_ClearErrorContext: + procedure(context: espeak_ng_ERROR_CONTEXT) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + espeak_ng_GetStatusCodeMessage: + procedure(status: espeak_ng_STATUS; buffer: pcchar; length: size_t) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{ +ESPEAK_NG_API void +espeak_ng_PrintStatusCodeMessage(espeak_ng_STATUS status, + FILE *out, + espeak_ng_ERROR_CONTEXT context); +} + espeak_ng_InitializePath: + procedure(path: pcchar){$ifdef wincall}stdcall{$else}cdecl{$endif}; + espeak_ng_Initialize: + function(context: espeak_ng_ERROR_CONTEXT): espeak_ng_STATUS + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + espeak_ng_InitializeOutput: + function(output_mode: espeak_ng_OUTPUT_MODE; buffer_length: cint; + device: pcchar): espeak_ng_STATUS + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + espeak_ng_GetSampleRate: + function(): cint {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + espeak_ng_SetParameter: + function(parameter: espeak_PARAMETER; value: cint; + relative: cint): espeak_ng_STATUS + {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{from espeak_SetParameter(): +/* Sets the value of the specified parameter. + relative=0 Sets the absolute value of the parameter. + relative=1 Sets a relative value of the parameter. + + parameter: + espeakRATE: speaking speed in word per minute. Values 80 to 450. + + espeakVOLUME: volume in range 0-200 or more. + 0=silence, 100=normal full volume, greater values may produce amplitude compression or distortion + + espeakPITCH: base pitch, range 0-100. 50=normal + + espeakRANGE: pitch range, range 0-100. 0-monotone, 50=normal + + espeakPUNCTUATION: which punctuation characters to announce: + value in espeak_PUNCT_TYPE (none, all, some), + see espeak_GetParameter() to specify which characters are announced. + + espeakCAPITALS: announce capital letters by: + 0=none, + 1=sound icon, + 2=spelling, + 3 or higher, by raising pitch. This values gives the amount in Hz by which the pitch + of a word raised to indicate it has a capital letter. + + espeakWORDGAP: pause between words, units of 10mS (at the default speed) + + Return: EE_OK: operation achieved + EE_BUFFER_FULL: the command can not be buffered; + you may try after a while to call the function again. + EE_INTERNAL_ERROR. +*/} + espeak_ng_SetPunctuationList: + function(punctlist: pwchar_t): espeak_ng_STATUS + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + espeak_ng_SetVoiceByName: + function(name: pcchar): espeak_ng_STATUS + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + espeak_ng_SetVoiceByProperties: + function(voice_selector: pespeak_VOICE): espeak_ng_STATUS + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + espeak_GetCurrentVoice: function(): pespeak_VOICE + {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{/* Returns the espeak_VOICE data for the currently selected voice. + This is not affected by temporary voice changes caused by + SSML elements such as and +*/} + + espeak_ng_Synthesize: + function(text: pointer; size: size_t; + position: cuint; + position_type: espeak_POSITION_TYPE; + end_position: cuint; + flags: cuint; + unique_identifier: pcuint; + user_data: pointer): espeak_ng_STATUS + {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{from espeak_Synthesize(): +/* Synthesize speech for the specified text. + The speech sound data is passed to the calling + program in buffers by means of the callback function specified by + espeak_SetSynthCallback(). The command is asynchronous: + it is internally buffered and returns as soon as possible. + If espeak_Initialize was previously called with AUDIO_OUTPUT_PLAYBACK + as argument, the sound data are played by eSpeak. + +text: The text to be spoken, terminated by a zero character. + It may be either 8-bit characters, + wide characters (wchar_t), or UTF8 encoding. Which of these is determined + by the "flags" parameter. + +size: Equal to (or greatrer than) the size of the text data, in bytes. + This is used in order + to allocate internal storage space for the text. This value is not used for + AUDIO_OUTPUT_SYNCHRONOUS mode. + +position: The position in the text where speaking starts. Zero indicates + speak from the + start of the text. + +position_type: Determines whether "position" is a number of characters, words, + or sentences. + Values: + +end_position: If set, this gives a character position at which speaking + will stop. A value of zero indicates no end position. + +flags: These may be OR'd together: + Type of character codes, one of: + espeakCHARS_UTF8 UTF8 encoding + espeakCHARS_8BIT The 8 bit ISO-8859 character set for + the particular language. + espeakCHARS_AUTO 8 bit or UTF8 (this is the default) + espeakCHARS_WCHAR Wide characters (wchar_t) + espeakCHARS_16BIT 16 bit characters. + + espeakSSML Elements within < > are treated as SSML elements, + or if not recognised are ignored. + + espeakPHONEMES Text within [[ ]] is treated as phonemes codes + (in espeak's Hirshenbaum encoding). + + espeakENDPAUSE If set then a sentence pause is added at the end of the + text. If not set then this pause is suppressed. + +unique_identifier: This must be either NULL, or point to an integer variable to + which eSpeak writes a message identifier number. + eSpeak includes this number in espeak_EVENT messages which are the result of + this call of espeak_Synth(). + +user_data: a pointer (or NULL) which will be passed to the callback function in + espeak_EVENT messages. + +Return: EE_OK: operation achieved + EE_BUFFER_FULL: the command can not be buffered; + you may try after a while to call the function again. + EE_INTERNAL_ERROR. +} + espeak_ng_SynthesizeMark: + function(text: pointer; size: size_t; + index_mark: pcchar; + end_position: cuint; + flags: cuint; + unique_identifier: pcuint; + user_data: pointer): espeak_ng_STATUS + {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{from espeak_SynthesizeMark(): +/* Synthesize speech for the specified text. + Similar to espeak_Synth() but the start position is + specified by the name of a element in the text. + + index_mark: The "name" attribute of a element within the + text which specified the point at which synthesis starts. UTF8 string. + + For the other parameters, see espeak_Synth() + + Return: EE_OK: operation achieved + EE_BUFFER_FULL: the command can not be buffered; + you may try after a while to call the function again. + EE_INTERNAL_ERROR. +*/ +} + espeak_ng_SpeakKeyName: + function(key_name: pchar): espeak_ng_STATUS + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + espeak_ng_SpeakCharacter: + function(character: wchar_t): espeak_ng_STATUS + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + espeak_IsPlaying: + function(): cint {$ifdef wincall}stdcall{$else}cdecl{$endif}; + //* Returns 1 if audio is played, 0 otherwise. + + espeak_ng_Cancel: + function(): espeak_ng_STATUS {$ifdef wincall}stdcall{$else}cdecl{$endif}; + espeak_ng_SetCancelState: + function(canceled: cint): espeak_ng_STATUS + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + espeak_ng_Synchronize: + function(): espeak_ng_STATUS {$ifdef wincall}stdcall{$else}cdecl{$endif}; + espeak_ng_Terminate: + function(): espeak_ng_STATUS {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{ +ESPEAK_NG_API espeak_ng_STATUS +espeak_ng_CompileDictionary(const char *dsource, + const char *dict_name, + FILE *log, + int flags, + espeak_ng_ERROR_CONTEXT *context); + +ESPEAK_NG_API espeak_ng_STATUS +espeak_ng_CompileMbrolaVoice(const char *path, + FILE *log, + espeak_ng_ERROR_CONTEXT *context); + +ESPEAK_NG_API espeak_ng_STATUS +espeak_ng_CompilePhonemeData(long rate, + FILE *log, + espeak_ng_ERROR_CONTEXT *context); + +ESPEAK_NG_API espeak_ng_STATUS +espeak_ng_CompileIntonation(FILE *log, + espeak_ng_ERROR_CONTEXT *context); + +/* eSpeak NG 1.49.1 */ + +ESPEAK_NG_API espeak_ng_STATUS +espeak_ng_CompilePhonemeDataPath(long rate, + const char *source_path, + const char *destination_path, + FILE *log, + espeak_ng_ERROR_CONTEXT *context); +} + +function espeakngerrormessage(const err: espeak_ng_STATUS): string; + +procedure initializeespeakng(const sonames: array of filenamety; + const espeakdatapath: string = ''); //[],'' = default +procedure releaseespeakng(); + +implementation +uses + msedynload; +var + libinfo: dynlibinfoty; + err: espeak_ng_ERROR_CONTEXT_; + +function espeakngerrormessage(const err: espeak_ng_STATUS): string; +var + buf: array[0..500] of char; +begin + espeak_ng_GetStatusCodeMessage(err,@buf,sizeof(buf)); + result:= string(pchar(@buf)) +end; + +procedure checkerror(const astate: espeak_ng_status; const atext: string); +begin + if astate <> 0 then begin + raise tespeakerror.create(astate,atext); + end; +end; + +procedure ini(const data: pointer); +begin + espeak_ng_InitializePath(data); + checkerror(espeak_ng_Initialize(@err), + lineend+'espeak-ng-data directory not found'+lineend+ + string(pchar(data))); +end; + +procedure fini(const data: pointer); +begin + espeak_ng_terminate(); +end; + +procedure initializeespeakng(const sonames: array of filenamety; + const espeakdatapath: string = ''); + +const + funcs: array[0..19] of funcinfoty = ( + (n: 'espeak_ng_ClearErrorContext'; d: @espeak_ng_ClearErrorContext), + (n: 'espeak_ng_GetStatusCodeMessage'; d: @espeak_ng_GetStatusCodeMessage), + (n: 'espeak_ng_InitializePath'; d: @ espeak_ng_InitializePath), + (n: 'espeak_ng_Initialize'; d: @espeak_ng_Initialize), + (n: 'espeak_ng_InitializeOutput'; d: @espeak_ng_InitializeOutput), + (n: 'espeak_ng_GetSampleRate'; d: @espeak_ng_GetSampleRate), + (n: 'espeak_ng_SetParameter'; d: @espeak_ng_SetParameter), + (n: 'espeak_ng_SetPunctuationList'; d: @espeak_ng_SetPunctuationList), + (n: 'espeak_ng_SetVoiceByName'; d: @espeak_ng_SetVoiceByName), + (n: 'espeak_ng_SetVoiceByProperties'; d: @espeak_ng_SetVoiceByProperties), + (n: 'espeak_GetCurrentVoice'; d: @espeak_GetCurrentVoice), + (n: 'espeak_ng_Synthesize'; d: @espeak_ng_Synthesize), + (n: 'espeak_ng_SynthesizeMark'; d: @espeak_ng_SynthesizeMark), + (n: 'espeak_ng_SpeakKeyName'; d: @espeak_ng_SpeakKeyName), + (n: 'espeak_ng_SpeakCharacter'; d: @espeak_ng_SpeakCharacter), + (n: 'espeak_IsPlaying'; d: @espeak_IsPlaying), + (n: 'espeak_ng_Cancel'; d: @espeak_ng_Cancel), + (n: 'espeak_ng_SetCancelState'; d: @espeak_ng_SetCancelState), + (n: 'espeak_ng_Synchronize'; d: @espeak_ng_Synchronize), + (n: 'espeak_ng_Terminate'; d: @espeak_ng_Terminate) + ); + errormessage = 'Can not load eSpeakNG library. '; +begin + if not initializedynlib(libinfo,sonames,espeaknglib,funcs,[], + errormessage,@ini,false,pointer(espeakdatapath)) then begin + espeak_ng_InitializePath(pointer(espeakdatapath)); //ini not called + end;; +end; + +procedure releaseespeakng(); +begin + releasedynlib(libinfo,@fini); +end; + +{ tespeakerror } + +constructor tespeakerror.create(const err: espeak_ng_STATUS; + const atext: string=''); +begin + inherited create('eSpeak error:'+atext+lineend+espeakngerrormessage(err)); +end; + +initialization + initializelibinfo(libinfo); +finalization + finalizelibinfo(libinfo); +end. diff --git a/mseide-msegui/lib/common/audio/msemidi.pas b/mseide-msegui/lib/common/audio/msemidi.pas new file mode 100644 index 0000000..be40cfd --- /dev/null +++ b/mseide-msegui/lib/common/audio/msemidi.pas @@ -0,0 +1,833 @@ +{ MSEgui Copyright (c) 2010-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msemidi; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + msestream,classes,mclasses,mseclasses,sysutils,msestrings,msetimer,msetypes; + +const + defaultmidimaxdatasize = 1000000; +// defaulttimescaleus = 1000000*60/(120*120); + defaulttempo = 120; //beats per minute + defaultticksperbeat = 120; + + mc_endoftrack = 47; + mc_keysig = 89; + mc_timesig = 88; + mc_tempo = 81; + mc_trackname = 3; + mc_instrumentname = 4; + +type + midierrorty = (em_ok,em_nostream,em_fileformat,em_notrack,em_trackdata); + + emidiexception = class(exception); + + midichannelty = (mic_0,mic_1,mic_2,mic_3,mic_4,mic_5,mic_6,mic_7, + mic_8,mic_9,mic_10,mic_11,mic_12,mic_13,mic_14,mic_15); + midichannelsty = set of midichannelty; + + idstringty = array[0..3] of char; + midichunkheaderty = record + id: idstringty; + size: longword; + end; + + midichunkty = record + header: midichunkheaderty; + data: record //variable + end; + end; + + midifileheaderty = record + formattype: word; + numberoftracks: word; + timedivision: word; + end; + + midimessagekindty = (mmk_none,mmk_noteoff,mmk_noteon,mmk_notepressure, + mmk_controller,mmk_programchange,mmk_channelpressure, + mmk_pitchbend,mmk_system); +const + midichannelmessages = [mmk_noteoff,mmk_noteon,mmk_notepressure, + mmk_controller,mmk_programchange,mmk_channelpressure]; +type + midieventinfoty = record + track: integer; + kind: midimessagekindty; + channel: byte; + par1: byte; + par2: byte; + end; + trackeventinfoty = record + delta: longword; + event: midieventinfoty; + end; + ptrackeventinfoty = ^trackeventinfoty; + + tmidistream = class(tbufstream) + private + ftrackcount: integer; + ftimedivision: longword; + ftracksize: longword; + fmetadata: string; + fstatus: byte; + fmaxdatasize: longword; + ftracknum: integer; + protected + function readtrackbyte(out adata: byte): boolean; + function readtrackdatabyte(out adata: byte): boolean; //check bit 7 + function readtrackword(out adata: word): boolean; + function readtracklongword(out adata: word): boolean; + function readtrackdata(out adata; const acount: integer): boolean; overload; + function readtrackvarlength(out adata: longword): boolean; + + function readbyte(out adata: byte): boolean; + function readword(out adata: word): boolean; + function readlongword(out adata: word): boolean; + function readchunkheader(out adata: midichunkheaderty): boolean; + + function checkchunkheader(const aid: idstringty; + const asize: integer): boolean; + function readfileheader(out adata: midifileheaderty): boolean; + function skip(const adist: longword): boolean; + public + constructor create(ahandle: integer); override; + function initfile: boolean; + function starttrack: boolean; + function skiptrack: boolean; + function readtrackdata(out adata: trackeventinfoty): boolean; overload; + function getmetadata(const alen: integer; out avalue: longword): boolean; + property timedivision: longword read ftimedivision; + property metadata: string read fmetadata; + property maxdatasize: longword read fmaxdatasize write fmaxdatasize + default defaultmidimaxdatasize; + end; + + trackeventty = procedure(const sender: tobject; + var ainfo: midieventinfoty) of object; + + midisourcestatety = (mss_inited,mss_tracksloaded,mss_eventsmerged, + mss_endoftrack); + midisourcestatesty = set of midisourcestatety; + +const + loadstates = [mss_inited,mss_tracksloaded,mss_eventsmerged]; +type + trackinfoty = record + disabled: boolean; + trackname: string; + instrumentname: string; + keysig: byte; + tempo: longword; //micro seconds per quarter note + timesig: longword; + channels: midichannelsty; + end; + trackinfoarty = array of trackinfoty; + + trackbufferarty = array of trackeventinfoty; + trackbufferararty = array of trackbufferarty; + + tmidisource = class(tmsecomponent) + private + fstream: tmidistream; + factive: boolean; + fontrackevent: trackeventty; + fstarttime: longword; + feventtime: longword; + ftimer: tsimpletimer; + ftracks: trackinfoarty; + ftrackbuffer: trackbufferararty; + feventbuffer: trackbufferarty; + feventindex: integer; + ftimescale: real; //miditicks to us + ftempo: real; + ftimesum: real; + procedure setstream(const avalue: tmidistream); + procedure setactive(const avalue: boolean); + procedure settempo(const avalue: real); + protected + fstate: midisourcestatesty; + ftrackevent: trackeventinfoty; + function ticksperbeat: integer; + procedure error(const aerror: midierrorty); + procedure clear; + procedure initstream; + procedure mergeevents; + procedure checkdata; + procedure start; + procedure stop; + function checkresult(const aresult: boolean; + const aerror: midierrorty): boolean; {$ifdef FPC}inline;{$endif} + procedure processevent; + procedure dotrackevent; virtual; + procedure dotimer(const sender: tobject); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure loadtracks; + property active: boolean read factive write setactive; + property stream: tmidistream read fstream write setstream; + //owns the stream + property tracks: trackinfoarty read ftracks; + property tempo: real read ftempo write settempo; //beats per minute + published + property ontrackevent: trackeventty read fontrackevent write fontrackevent; + end; + +const + midimessagetable: array[0..7] of midimessagekindty = ( + mmk_noteoff, //8c + mmk_noteon, //9c + mmk_notepressure, //ac + mmk_controller, //bc + mmk_programchange, //cc + mmk_channelpressure, //dc + mmk_pitchbend, //ec + mmk_system); //fx + + midiparcount: array[midimessagekindty] of integer = ( + // mmk_none,mmk_noteoff,mmk_noteon,mmk_notepressure, + 0, 2, 2, 2, + // mmk_controller,mmk_programchange,mmk_channelpressure, + 2, 1, 1, + // mmk_pitchbend,mmk_system + 2, 0); + +implementation +uses + msesysutils,msedatalist,msearrayutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + errormessages: array[midierrorty] of msestring = ( + '', + 'No midi stream', + 'No midi file.', + 'No track found.', + 'Invalid track data.' + ); + +function swap(const avalue: word): word; {$ifdef FPC}inline;{$endif} + overload; +begin + result:= (avalue shl 8) or (avalue shr 8); +end; + +procedure swap1(var avalue: word); {$ifdef FPC}inline;{$endif} + overload; +begin + avalue:= (avalue shl 8) or (avalue shr 8); +end; + +function swap(const avalue: longword): longword; {$ifdef FPC}inline;{$endif} + overload; +begin + result:= (swap(word(avalue)) shl 16) or swap(word(avalue shr 16)); +end; + +procedure swap1(var avalue: longword); {$ifdef FPC}inline;{$endif} overload; +begin + avalue:= (swap(word(avalue)) shl 16) or swap(word(avalue shr 16)); +end; + +{ tmidistream } + +constructor tmidistream.create(ahandle: integer); +begin + fmaxdatasize:= defaultmidimaxdatasize; +// ftimescaleus:= defaulttimescaleus; + inherited; +end; + +function tmidistream.readbyte(out adata: byte): boolean; +begin + result:= read(adata,sizeof(adata)) = sizeof(adata); +end; + +function tmidistream.readword(out adata: word): boolean; +begin + result:= read(adata,sizeof(adata)) = sizeof(adata); + swap1(adata); +end; + +function tmidistream.readlongword(out adata: word): boolean; +begin + result:= read(adata,sizeof(adata)) = sizeof(adata); + swap1(adata); +end; + +function tmidistream.readtrackbyte(out adata: byte): boolean; +var + int1: integer; +begin + result:= ftrackcount >= sizeof(adata); + if result then begin + int1:= read(adata,sizeof(adata)); + ftrackcount:= ftrackcount - int1; + result:= int1 = sizeof(adata); + end; +end; + +function tmidistream.readtrackdatabyte(out adata: byte): boolean; +begin + result:= readtrackbyte(adata); + if result and (adata and $80 <> 0) then begin + result:= false; + fstatus:= adata; //try to resync + end; +end; + +function tmidistream.readtrackword(out adata: word): boolean; +var + int1: integer; +begin + result:= ftrackcount >= sizeof(adata); + if result then begin + int1:= read(adata,sizeof(adata)); + ftrackcount:= ftrackcount - int1; + result:= int1 = sizeof(adata); + if result then begin + swap1(adata); + end; + end; +end; + +function tmidistream.readtracklongword(out adata: word): boolean; +var + int1: integer; +begin + result:= ftrackcount >= sizeof(adata); + if result then begin + int1:= read(adata,sizeof(adata)); + ftrackcount:= ftrackcount - int1; + result:= int1 = sizeof(adata); + if result then begin + swap1(adata); + end; + end; +end; + +function tmidistream.readtrackdata(out adata; const acount: integer): boolean; +var + int1: integer; +begin + result:= ftrackcount >= acount; + if result then begin + int1:= read(adata,acount); + ftrackcount:= ftrackcount - int1; + result:= int1 = acount; + end; +end; + +function tmidistream.readchunkheader(out adata: midichunkheaderty): boolean; +begin + result:= read(adata,sizeof(adata)) = sizeof(adata); + swap1(adata.size); +end; + +function tmidistream.checkchunkheader(const aid: idstringty; + const asize: integer): boolean; +var + header1: midichunkheaderty; +begin + result:= readchunkheader(header1) and (header1.size = asize) and + (header1.id = aid); +end; + +function tmidistream.readfileheader(out adata: midifileheaderty): boolean; +begin + result:= checkchunkheader('MThd',6); + if result then begin + result:= read(adata,sizeof(adata)) = sizeof(adata); + if result then begin + with adata do begin + swap1(formattype); + swap1(numberoftracks); + swap1(timedivision); + end; + end; + end; +end; + +function tmidistream.initfile: boolean; +var + header: midifileheaderty; +begin + ftracknum:= -1; + result:= readfileheader(header); + if result then begin + with header do begin + ftrackcount:= numberoftracks; + ftimedivision:= timedivision; + end; + result:= ftimedivision > 0; + end; +end; + +function tmidistream.starttrack: boolean; +var + header: midichunkheaderty; +begin + repeat + result:= readchunkheader(header); + if result then begin + with header do begin + ftracksize:= header.size; + if id = 'MTrk' then begin + ftrackcount:= ftracksize; + inc(ftracknum); + break; + end; + result:= skip(ftracksize); + end; + end; + until not result; +end; + +function tmidistream.skiptrack: boolean; +var + header: midichunkheaderty; +begin + repeat + result:= readchunkheader(header); + if result then begin + with header do begin + ftracksize:= header.size; + if id = 'MTrk' then begin + result:= skip(ftracksize); + inc(ftracknum); + break; + end; + result:= skip(ftracksize); + end; + end; + until not result; +end; + + +function tmidistream.skip(const adist: longword): boolean; +var + lint1: int64; +begin + lint1:= position; + result:= seek(adist,socurrent)-lint1 = adist; +end; + +function tmidistream.readtrackvarlength(out adata: longword): boolean; +var + by1: byte; +begin + result:= true; + adata:= 0; + while result and (ftrackcount > 0) do begin + dec(ftrackcount); + result:= read(by1,1) = 1; + adata:= (adata shl 7) or by1 and $7f; + if by1 and $80 = 0 then begin + break; + end; + end; +end; +{ +function tmidistream.readtrackevent(out adata: trackeventinfoty): boolean; +var + stat1: byte; + lwo1: longword; + rea1: real; +begin + fillchar(adata,sizeof(adata),0); + result:= readtrackvarlength(adata.delta); + if not result then exit; + + if adata.delta <> 0 then begin + ftimesum:= ftimesum + adata.delta*ftimescaleus; + adata.delta:= round(ftimesum); + ftimesum:= ftimesum - adata.delta; + end; + + result:= readtrackbyte(stat1); + if not result then exit; + if (stat1 and $80) <> 0 then begin + fstatus:= stat1; + result:= readtrackdatabyte(adata.event.par1); + if not result then exit; + end + else begin + adata.event.par1:= stat1; + stat1:= fstatus; + end; + adata.event.kind:= messagetable[(stat1 shr 4) and $7]; + if adata.event.kind = mmk_system then begin + result:= readtrackvarlength(lwo1) and (lwo1 <= fmaxdatasize); + if not result then exit; + setlength(fmetadata,lwo1); + if lwo1 > 0 then begin + result:= readtrackdata(pointer(fmetadata)^,lwo1); + end; + end + else begin + adata.event.channel:= stat1 and $0f; + if parcount[adata.event.kind] > 1 then begin + result:= readtrackdatabyte(adata.event.par2); + end; + end; +end; +} +function tmidistream.readtrackdata(out adata: trackeventinfoty): boolean; +var + stat1: byte; + lwo1: longword; +// rea1: real; +begin + fillchar(adata,sizeof(adata),0); + adata.event.track:= ftracknum; + fmetadata:= ''; + result:= readtrackvarlength(adata.delta); + if not result then exit; + result:= readtrackbyte(stat1); + if not result then exit; + if (stat1 and $80) <> 0 then begin + fstatus:= stat1; + result:= readtrackdatabyte(adata.event.par1); + if not result then exit; + end + else begin + adata.event.par1:= stat1; + stat1:= fstatus; + end; + adata.event.kind:= midimessagetable[(stat1 shr 4) and $7]; + if adata.event.kind = mmk_system then begin + result:= readtrackvarlength(lwo1) and (lwo1 <= fmaxdatasize); + if not result then exit; + setlength(fmetadata,lwo1); + if lwo1 > 0 then begin + result:= readtrackdata(pointer(fmetadata)^,lwo1); + end; + end + else begin + adata.event.channel:= stat1 and $0f; + if midiparcount[adata.event.kind] > 1 then begin + result:= readtrackdatabyte(adata.event.par2); + end; + end; +end; + +function tmidistream.getmetadata(const alen: integer; + out avalue: longword): boolean; +var + int1: integer; +begin + result:= length(fmetadata) = alen; + if result then begin + avalue:= 0; + for int1:= 1 to alen do begin + avalue:= (avalue shl 8) or byte(fmetadata[int1]); + end; + end; +end; + +{ tmidisource } + +constructor tmidisource.create(aowner: tcomponent); +begin + tempo:= defaulttempo; + inherited; + ftimer:= tsimpletimer.create(0,{$ifdef FPC}@{$endif}dotimer,false, + [to_single,to_absolute,to_autostart]); +end; + +destructor tmidisource.destroy; +begin + stream:= nil; + ftimer.free; + inherited; +end; + +function tmidisource.checkresult(const aresult: boolean; + const aerror: midierrorty): boolean; +begin + result:= aresult; + if not aresult then begin + error(aerror); + end; +end; + +procedure tmidisource.clear; +begin + fstate:= fstate - loadstates; + ftracks:= nil; + ftrackbuffer:= nil; + feventbuffer:= nil; + ftempo:= defaulttempo; + feventindex:= 0; + ftimesum:= 0; +end; + +procedure tmidisource.setstream(const avalue: tmidistream); +begin + active:= false; + fstream.free; + fstream:= avalue; + clear; +end; + +procedure tmidisource.setactive(const avalue: boolean); +begin + if factive <> avalue then begin + factive:= avalue; + if avalue then begin + start; + end + else begin + stop; + end; + end; +end; + +procedure tmidisource.error(const aerror: midierrorty); +begin + raise emidiexception.create(self.name+': '+ansistring(errormessages[aerror])); +end; + +procedure tmidisource.dotrackevent; +begin + if assigned(fontrackevent) then begin + fontrackevent(self,ftrackevent.event); + end; +end; + +procedure tmidisource.dotimer(const sender: tobject); +begin + dotrackevent; + processevent; +end; + +procedure tmidisource.processevent; +var + lwo1: longword; +begin + while feventindex <= high(feventbuffer) do begin + ftrackevent:= feventbuffer[feventindex]; + inc(feventindex); + with ftrackevent do begin + if delta = 0 then begin + dotrackevent; + end + else begin + ftimesum:= ftimesum +delta*ftimescale; + lwo1:= round(ftimesum); + ftimesum:= ftimesum - lwo1; + feventtime:= feventtime + lwo1; + ftimer.interval:= feventtime; + break; + end; + end; + end; +end; + +procedure tmidisource.initstream; +begin + if not (mss_inited in fstate) then begin + if fstream = nil then begin + error(em_nostream); + end; + checkresult(fstream.initfile,em_fileformat); + tempo:= tempo; //update timescale + include(fstate,mss_inited); + end; +end; + +procedure tmidisource.loadtracks; +var + int1,int2,int3: integer; + trackdata: trackeventinfoty; +begin + initstream; + if not (mss_tracksloaded in fstate) then begin + setlength(ftracks,fstream.ftrackcount); + setlength(ftrackbuffer,length(ftracks)); + for int1:= 0 to high(ftracks) do begin + checkresult(fstream.starttrack,em_notrack); + with ftracks[int1] do begin + int2:= 0; + while true do begin + checkresult(fstream.readtrackdata(trackdata),em_trackdata); + with trackdata.event do begin + case kind of + mmk_noteoff,mmk_noteon,mmk_notepressure, + mmk_controller,mmk_programchange,mmk_channelpressure, + mmk_pitchbend: begin + int3:= additemindex(ftrackbuffer[int1],typeinfo(trackbufferarty),int2); + ftrackbuffer[int1][int3]:= trackdata; + include(channels,midichannelty(trackdata.event.channel and $0f)); + end; + mmk_system: begin + case par1 of + mc_keysig: begin + keysig:= par2; + end; + mc_tempo: begin + checkresult(fstream.getmetadata(3,tempo),em_trackdata); + end; + mc_timesig: begin + checkresult(fstream.getmetadata(4,timesig),em_trackdata); + end; + mc_trackname: begin + trackname:= fstream.metadata; + end; + mc_instrumentname: begin + instrumentname:= fstream.metadata; + end; + mc_endoftrack: begin + break; + end; + end; + end; + end; + end; + end; + setlength(ftrackbuffer[int1],int2); + end; + end; + if (ftracks <> nil) and (ftracks[0].tempo > 0) then begin + tempo:= 60000000/ftracks[0].tempo; + end; + include(fstate,mss_tracksloaded); + end; +end; + +type + trackmergeinfoty = record + po: ptrackeventinfoty; + time: longword; + end; + trackmergeinfoarty = array of trackmergeinfoty; + +procedure tmidisource.mergeevents; //todo: optimize +var + int1,int2,int3,int4,int5,int6: integer; + ar1: trackmergeinfoarty; + lwo1: longword; +begin + loadtracks; + if high(ftracks) < 0 then begin + exit; + end; + if not (mss_eventsmerged in fstate) then begin + int2:= 0; + int3:= 0; + setlength(ar1,length(ftracks)); + for int1:= 0 to high(ftracks) do begin + if not ftracks[int1].disabled and (ftrackbuffer[int1] <> nil) then begin + int4:= length(ftrackbuffer[int1]); + int2:= int2 + int4; + setlength(ftrackbuffer[int1],int4+1); + ftrackbuffer[int1][int4].delta:= bigint; //endmarker + ar1[int3].po:= pointer(ftrackbuffer[int1]); + inc(int3); + end; + end; + setlength(ar1,int3); + setlength(feventbuffer,int2); + { + for int3:= 0 to high(ar1) do begin + with ar1[int3] do begin + time:= time + po^.delta; //init + end; + end; + } + lwo1:= 0; + for int1:= 0 to int2 - 1 do begin + with ar1[0] do begin + int4:= time+po^.delta-lwo1; + end; + int5:= 0; + for int3:= 1 to high(ar1) do begin + with ar1[int3] do begin + int6:= time+po^.delta-lwo1; + if int6 < int4 then begin + int4:= int6; + int5:= int3; + end; + end; + end; + with ar1[int5] do begin + feventbuffer[int1]:= po^; + time:= time + po^.delta; + with feventbuffer[int1] do begin + delta:= time-lwo1; + end; + lwo1:= time; + inc(po); + end; + end; + ftrackbuffer:= nil; + include(fstate,mss_eventsmerged); + end; +end; + +{ + fstarttime:= timestamp; + feventtime:= fstarttime; + processevent; +} +procedure tmidisource.checkdata; +begin + mergeevents; +end; + +procedure tmidisource.start; +begin + checkdata; + fstarttime:= timestamp; + feventtime:= fstarttime; + processevent; +end; + +procedure tmidisource.stop; +begin + ftimer.enabled:= false; +end; + +procedure tmidisource.settempo(const avalue: real); +begin + if avalue > 0 then begin + ftempo:= avalue; + ftimescale:= (60000000)/(ticksperbeat*avalue); + end; +end; + +function tmidisource.ticksperbeat: integer; +begin + result:= defaultticksperbeat; + if fstream <> nil then begin + result:= fstream.timedivision; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/audio/msepulse.pas b/mseide-msegui/lib/common/audio/msepulse.pas new file mode 100644 index 0000000..480dc55 --- /dev/null +++ b/mseide-msegui/lib/common/audio/msepulse.pas @@ -0,0 +1,58 @@ +{ MSEgui Copyright (c) 2010 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msepulse; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes{msestrings},msepulseglob,msectypes; + +const +{$ifdef mswindows} + pulsesimplelib: array[0..0] of filenamety = ('libpulse-0.dll'); +{$else} + pulsesimplelib: array[0..1] of filenamety = + ('libpulse.so.0','libpulse.so'); +{$endif} + +var +//** Return a human readable error message for the specified numeric error code */ + pa_strerror: function(error: cint): pchar; cdecl; + +procedure initializepulse(const sonames: array of filenamety); + //[] = default +procedure releasepulse; + +implementation +uses + msedynload,sysutils,msesys; + +var + libinfo: dynlibinfoty; + +procedure initializepulse(const sonames: array of filenamety); //[] = default +const + funcs: array[0..0] of funcinfoty = ( + (n: 'pa_strerror'; d: {$ifndef FPC}@{$endif}@pa_strerror) //0 + ); + errormessage = 'Can not load Pulseaudio simple library. '; +begin + initializedynlib(libinfo,sonames,pulsesimplelib,funcs,[],errormessage); +end; + +procedure releasepulse; +begin + releasedynlib(libinfo); +end; + +initialization + initializelibinfo(libinfo); +finalization + finalizelibinfo(libinfo); +end. diff --git a/mseide-msegui/lib/common/audio/msepulseglob.pas b/mseide-msegui/lib/common/audio/msepulseglob.pas new file mode 100644 index 0000000..be685d2 --- /dev/null +++ b/mseide-msegui/lib/common/audio/msepulseglob.pas @@ -0,0 +1,333 @@ +{ MSEgui Copyright (c) 2010 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +{ +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + Copyright 2006 Pierre Ossman for Cendio AB + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ +} +{ +/** \mainpage + * + * \section intro_sec Introduction + * + * This document describes the client API for the PulseAudio sound + * server. The API comes in two flavours to accommodate different styles + * of applications and different needs in complexity: + * + * \li The complete but somewhat complicated to use asynchronous API + * \li The simplified, easy to use, but limited synchronous API + * + * All strings in PulseAudio are in the UTF-8 encoding, regardless of current + * locale. Some functions will filter invalid sequences from the string, some + * will simply fail. To ensure reliable behaviour, make sure everything you + * pass to the API is already in UTF-8. + + * \section simple_sec Simple API + * + * Use this if you develop your program in synchronous style and just + * need a way to play or record data on the sound server. See + * \subpage simple for more details. + * + * \section async_sec Asynchronous API + * + * Use this if you develop your programs in asynchronous, event loop + * based style or if you want to use the advanced features of the + * PulseAudio API. A guide can be found in \subpage async. + * + * By using the built-in threaded main loop, it is possible to acheive a + * pseudo-synchronous API, which can be useful in synchronous applications + * where the simple API is insufficient. See the \ref async page for + * details. + * + * \section thread_sec Threads + * + * The PulseAudio client libraries are not designed to be directly + * thread-safe. They are however designed to be reentrant and + * threads-aware. + * + * To use the libraries in a threaded environment, you must assure that + * all objects are only used in one thread at a time. Normally, this means + * that all objects belonging to a single context must be accessed from the + * same thread. + * + * The included main loop implementation is also not thread safe. Take care + * to make sure event objects are not manipulated when any other code is + * using the main loop. + * + * \section pkgconfig pkg-config + * + * The PulseAudio libraries provide pkg-config snippets for the different + * modules: + * + * \li libpulse - The asynchronous API and the internal main loop implementation. + * \li libpulse-mainloop-glib - GLIB 2.x main loop bindings. + * \li libpulse-simple - The simple PulseAudio API. + */ +} +unit msepulseglob; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes; +{$ifdef FPC} + {$packrecords c} +{$else} + {$ALIGN 4} + {$MINENUMSIZE 4} +{$endif} +const + PA_CHANNELS_MAX = 32; //** Maximum number of allowed channels */ + PA_RATE_MAX = (48000*4);//** Maximum allowed sample rate */ + +type + uint32_t = longword; + uint8_t = byte; + size_t = ptruint; + pa_usec_t = uint64; + +//** The direction of a pa_stream object */ + pa_stream_direction_t = ( + PA_STREAM_NODIRECTION, //**< Invalid direction */ + PA_STREAM_PLAYBACK, //**< Playback stream */ + PA_STREAM_RECORD, //**< Record stream */ + PA_STREAM_UPLOAD //**< Sample upload stream */ + ); + +//** Sample format */ + pa_sample_format_t = ( + PA_SAMPLE_INVALID = -1,//**< An invalid value */ + PA_SAMPLE_U8 = 0, //**< Unsigned 8 Bit PCM */ + PA_SAMPLE_ALAW, //**< 8 Bit a-Law */ + PA_SAMPLE_ULAW, //**< 8 Bit mu-Law */ + PA_SAMPLE_S16LE,//**< Signed 16 Bit PCM, little endian (PC) */ + PA_SAMPLE_S16BE,//**< Signed 16 Bit PCM, big endian */ + PA_SAMPLE_FLOAT32LE,//**< 32 Bit IEEE floating point, little endian (PC), range -1.0 to 1.0 */ + PA_SAMPLE_FLOAT32BE,//**< 32 Bit IEEE floating point, big endian, range -1.0 to 1.0 */ + PA_SAMPLE_S32LE,//**< Signed 32 Bit PCM, little endian (PC) */ + PA_SAMPLE_S32BE,//**< Signed 32 Bit PCM, big endian */ + PA_SAMPLE_S24LE,//**< Signed 24 Bit PCM packed, little endian (PC). \since 0.9.15 */ + PA_SAMPLE_S24BE,//**< Signed 24 Bit PCM packed, big endian. \since 0.9.15 */ + PA_SAMPLE_S24_32LE,//**< Signed 24 Bit PCM in LSB of 32 Bit words, little endian (PC). \since 0.9.15 */ + PA_SAMPLE_S24_32BE,//**< Signed 24 Bit PCM in LSB of 32 Bit words, big endian. \since 0.9.15 */ + PA_SAMPLE_MAX//**< Upper limit of valid sample types */ + ); + +const +{$ifdef endian_big} + PA_SAMPLE_S16NE = PA_SAMPLE_S16BE; + PA_SAMPLE_FLOAT32NE = PA_SAMPLE_FLOAT32BE; + PA_SAMPLE_S32NE = PA_SAMPLE_S32BE; + PA_SAMPLE_S24NE = PA_SAMPLE_S24BE; + PA_SAMPLE_S24_32NE = PA_SAMPLE_S24_32BE; + PA_SAMPLE_S16RE = PA_SAMPLE_S16LE; + PA_SAMPLE_FLOAT32RE = PA_SAMPLE_FLOAT32LE; + PA_SAMPLE_S32RE = PA_SAMPLE_S32LE; + PA_SAMPLE_S24RE = PA_SAMPLE_S24LE; + PA_SAMPLE_S24_32RE = PA_SAMPLE_S24_32LE; +{$else} + PA_SAMPLE_S16NE = PA_SAMPLE_S16LE; + PA_SAMPLE_FLOAT32NE = PA_SAMPLE_FLOAT32LE; + PA_SAMPLE_S32NE = PA_SAMPLE_S32LE; + PA_SAMPLE_S24NE = PA_SAMPLE_S24LE; + PA_SAMPLE_S24_32NE = PA_SAMPLE_S24_32LE; + PA_SAMPLE_S16RE = PA_SAMPLE_S16BE; + PA_SAMPLE_FLOAT32RE = PA_SAMPLE_FLOAT32BE; + PA_SAMPLE_S32RE = PA_SAMPLE_S32BE; + PA_SAMPLE_S24RE = PA_SAMPLE_S24BE; + PA_SAMPLE_S24_32RE = PA_SAMPLE_S24_32BE; +{$endif} + +type + +//** A sample format and attribute specification */ + pa_sample_spec = record + format: pa_sample_format_t; //**< The sample format */ + rate: uint32_t; //**< The sample rate. (e.g. 44100) */ + channels: uint8_t; //**< Audio channels. (1 for mono, 2 for stereo, ...) */ + end; + ppa_sample_spec = ^pa_sample_spec; + +//** A list of channel mapping definitions for pa_channel_map_init_auto() */ + pa_channel_map_def = ( + PA_CHANNEL_MAP_AIFF, //**< The mapping from RFC3551, which is based on AIFF-C */ + PA_CHANNEL_MAP_ALSA, //**< The default mapping used by ALSA. This mapping is probably + //* not too useful since ALSA's default channel mapping depends on + //* the device string used. */ + PA_CHANNEL_MAP_AUX, //**< Only aux channels */ + PA_CHANNEL_MAP_WAVEEX,//**< Microsoft's WAVEFORMATEXTENSIBLE mapping. This mapping works + //* as if all LSBs of dwChannelMask are set. */ + PA_CHANNEL_MAP_OSS, //**< The default channel mapping used by OSS as defined in the OSS + //* 4.0 API specs. This mapping is probably not too useful since + //* the OSS API has changed in this respect and no longer knows a + //* default channel mapping based on the number of channels. */ + + //**< Upper limit of valid channel mapping definitions */ + PA_CHANNEL_MAP_DEF_MAX + ); + ppa_channel_map_def = ^pa_channel_map_def; + +const + PA_CHANNEL_MAP_DEFAULT = PA_CHANNEL_MAP_AIFF; //**< The default channel map */ + +type + +//** A list of channel labels */ + pa_channel_position_t = ( + PA_CHANNEL_POSITION_INVALID = -1, + PA_CHANNEL_POSITION_MONO = 0, + PA_CHANNEL_POSITION_FRONT_LEFT, //* Apple, Dolby call this 'Left' */ + PA_CHANNEL_POSITION_FRONT_RIGHT, //* Apple, Dolby call this 'Right' */ + PA_CHANNEL_POSITION_FRONT_CENTER, //* Apple, Dolby call this 'Center' */ + PA_CHANNEL_POSITION_REAR_CENTER, //* Microsoft calls this 'Back Center', Apple calls this 'Center Surround', Dolby calls this 'Surround Rear Center' */ + PA_CHANNEL_POSITION_REAR_LEFT, //* Microsoft calls this 'Back Left', Apple calls this 'Left Surround' (!), Dolby calls this 'Surround Rear Left' */ + PA_CHANNEL_POSITION_REAR_RIGHT, //* Microsoft calls this 'Back Right', Apple calls this 'Right Surround' (!), Dolby calls this 'Surround Rear Right' */ + PA_CHANNEL_POSITION_LFE, //* Microsoft calls this 'Low Frequency', Apple calls this 'LFEScreen' */ + PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER, //* Apple, Dolby call this 'Left Center' */ + PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER, //* Apple, Dolby call this 'Right Center */ + PA_CHANNEL_POSITION_SIDE_LEFT, //* Apple calls this 'Left Surround Direct', Dolby calls this 'Surround Left' (!) */ + PA_CHANNEL_POSITION_SIDE_RIGHT, //* Apple calls this 'Right Surround Direct', Dolby calls this 'Surround Right' (!) */ + PA_CHANNEL_POSITION_AUX0, + PA_CHANNEL_POSITION_AUX1, + PA_CHANNEL_POSITION_AUX2, + PA_CHANNEL_POSITION_AUX3, + PA_CHANNEL_POSITION_AUX4, + PA_CHANNEL_POSITION_AUX5, + PA_CHANNEL_POSITION_AUX6, + PA_CHANNEL_POSITION_AUX7, + PA_CHANNEL_POSITION_AUX8, + PA_CHANNEL_POSITION_AUX9, + PA_CHANNEL_POSITION_AUX10, + PA_CHANNEL_POSITION_AUX11, + PA_CHANNEL_POSITION_AUX12, + PA_CHANNEL_POSITION_AUX13, + PA_CHANNEL_POSITION_AUX14, + PA_CHANNEL_POSITION_AUX15, + PA_CHANNEL_POSITION_AUX16, + PA_CHANNEL_POSITION_AUX17, + PA_CHANNEL_POSITION_AUX18, + PA_CHANNEL_POSITION_AUX19, + PA_CHANNEL_POSITION_AUX20, + PA_CHANNEL_POSITION_AUX21, + PA_CHANNEL_POSITION_AUX22, + PA_CHANNEL_POSITION_AUX23, + PA_CHANNEL_POSITION_AUX24, + PA_CHANNEL_POSITION_AUX25, + PA_CHANNEL_POSITION_AUX26, + PA_CHANNEL_POSITION_AUX27, + PA_CHANNEL_POSITION_AUX28, + PA_CHANNEL_POSITION_AUX29, + PA_CHANNEL_POSITION_AUX30, + PA_CHANNEL_POSITION_AUX31, + PA_CHANNEL_POSITION_TOP_CENTER, //* Apple calls this 'Top Center Surround' */ + PA_CHANNEL_POSITION_TOP_FRONT_LEFT, //* Apple calls this 'Vertical Height Left' */ + PA_CHANNEL_POSITION_TOP_FRONT_RIGHT, //* Apple calls this 'Vertical Height Right' */ + PA_CHANNEL_POSITION_TOP_FRONT_CENTER, //* Apple calls this 'Vertical Height Center' */ + PA_CHANNEL_POSITION_TOP_REAR_LEFT, //* Microsoft and Apple call this 'Top Back Left' */ + PA_CHANNEL_POSITION_TOP_REAR_RIGHT, //* Microsoft and Apple call this 'Top Back Right' */ + PA_CHANNEL_POSITION_TOP_REAR_CENTER, //* Microsoft and Apple call this 'Top Back Center' */ + PA_CHANNEL_POSITION_MAX + ); + +const + PA_CHANNEL_POSITION_LEFT = PA_CHANNEL_POSITION_FRONT_LEFT; + PA_CHANNEL_POSITION_RIGHT = PA_CHANNEL_POSITION_FRONT_RIGHT; + PA_CHANNEL_POSITION_CENTER = PA_CHANNEL_POSITION_FRONT_CENTER; + PA_CHANNEL_POSITION_SUBWOOFER = PA_CHANNEL_POSITION_LFE; + +type + pa_channel_position_aty = array[0..PA_CHANNELS_MAX-1] of pa_channel_position_t; + +//** A channel map which can be used to attach labels to specific +// * channels of a stream. These values are relevant for conversion and +// * mixing of streams */ + pa_channel_map = record + chsnnels: uint8_t; //**< Number of channels */ + map: pa_channel_position_aty; //**< Channel labels */ + end; + ppa_channel_map = ^pa_channel_map; + +//** Playback and record buffer metrics */ + pa_buffer_attr = record + maxlength: uint32_t; + //**< Maximum length of the buffer. Setting this to (uint32_t) -1 + //* will initialize this to the maximum value supported by server, + //* which is recommended. */ + tlength: uint32_t; + //**< Playback only: target length of the buffer. The server tries + //* to assure that at least tlength bytes are always available in + //* the per-stream server-side playback buffer. It is recommended + //* to set this to (uint32_t) -1, which will initialize this to a + //* value that is deemed sensible by the server. However, this + //* value will default to something like 2s, i.e. for applications + //* that have specific latency requirements this value should be + //* set to the maximum latency that the application can deal + //* with. When PA_STREAM_ADJUST_LATENCY is not set this value will + //* influence only the per-stream playback buffer size. When + //* PA_STREAM_ADJUST_LATENCY is set the overall latency of the sink + //* plus the playback buffer size is configured to this value. Set + //* PA_STREAM_ADJUST_LATENCY if you are interested in adjusting the + //* overall latency. Don't set it if you are interested in + //* configuring the server-side per-stream playback buffer + //* size. */ + prebuf: uint32_t; + //**< Playback only: pre-buffering. The server does not start with + //* playback before at least prebuf bytes are available in the + //* buffer. It is recommended to set this to (uint32_t) -1, which + //* will initialize this to the same value as tlength, whatever + //* that may be. Initialize to 0 to enable manual start/stop + //* control of the stream. This means that playback will not stop + //* on underrun and playback will not start automatically. Instead + //* pa_stream_corked() needs to be called explicitly. If you set + //* this value to 0 you should also set PA_STREAM_START_CORKED. */ + minreq: uint32_t; + //**< Playback only: minimum request. The server does not request + //* less than minreq bytes from the client, instead waits until the + //* buffer is free enough to request more bytes at once. It is + //* recommended to set this to (uint32_t) -1, which will initialize + //* this to a value that is deemed sensible by the server. This + //* should be set to a value that gives PulseAudio enough time to + //* move the data from the per-stream playback buffer into the + //* hardware playback buffer. */ + fragsize: uint32_t; + //**< Recording only: fragment size. The server sends data in + //* blocks of fragsize bytes size. Large values diminish + //* interactivity with other operations on the connection context + //* but decrease control overhead. It is recommended to set this to + //* (uint32_t) -1, which will initialize this to a value that is + //* deemed sensible by the server. However, this value will default + //* to something like 2s, i.e. for applications that have specific + //* latency requirements this value should be set to the maximum + //* latency that the application can deal with. If + //* PA_STREAM_ADJUST_LATENCY is set the overall source latency will + //* be adjusted according to this value. If it is not set the + //* source latency is left unmodified. */ + end; + ppa_buffer_attr = ^pa_buffer_attr; + +implementation +end. diff --git a/mseide-msegui/lib/common/audio/msepulsesimple.pas b/mseide-msegui/lib/common/audio/msepulsesimple.pas new file mode 100644 index 0000000..644ff70 --- /dev/null +++ b/mseide-msegui/lib/common/audio/msepulsesimple.pas @@ -0,0 +1,201 @@ +{ MSEgui Copyright (c) 2010-2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +{ +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + Copyright 2006 Pierre Ossman for Cendio AB + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ +} +{ +/** \page simple Simple API + * + * \section overv_sec Overview + * + * The simple API is designed for applications with very basic sound + * playback or capture needs. It can only support a single stream per + * connection and has no handling of complex features like events, channel + * mappings and volume control. It is, however, very simple to use and + * quite sufficent for many programs. + * + * \section conn_sec Connecting + * + * The first step before using the sound system is to connect to the + * server. This is normally done this way: + * + * \code + * pa_simple *s; + * pa_sample_spec ss; + * + * ss.format = PA_SAMPLE_S16NE; + * ss.channels = 2; + * ss.rate = 44100; + * + * s = pa_simple_new(NULL, // Use the default server. + * "Fooapp", // Our application's name. + * PA_STREAM_PLAYBACK, + * NULL, // Use the default device. + * "Music", // Description of our stream. + * &ss, // Our sample format. + * NULL, // Use default channel map + * NULL, // Use default buffering attributes. + * NULL, // Ignore error code. + * ); + * \endcode + * + * At this point a connected object is returned, or NULL if there was a + * problem connecting. + * + * \section transfer_sec Transferring data + * + * Once the connection is established to the server, data can start flowing. + * Using the connection is very similar to the normal read() and write() + * system calls. The main difference is that they're call pa_simple_read() + * and pa_simple_write(). Note that these operations always block. + * + * \section ctrl_sec Buffer control + * + * If a playback stream is used then a few other operations are available: + * + * \li pa_simple_drain() - Will wait for all sent data to finish playing. + * \li pa_simple_flush() - Will throw away all data currently in buffers. + * \li pa_simple_get_playback_latency() - Will return the total latency of + * the playback pipeline. + * + * \section cleanup_sec Cleanup + * + * Once playback or capture is complete, the connection should be closed + * and resources freed. This is done through: + * + * \code + * pa_simple_free(s); + * \endcode + */ + +/** \file + * A simple but limited synchronous playback and recording + * API. This is a synchronous, simplified wrapper around the standard + * asynchronous API. */ + +/** \example pacat-simple.c + * A simple playback tool using the simple API */ + +/** \example parec-simple.c + * A simple recording tool using the simple API */ +} +unit msepulsesimple; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msetypes{msestrings},msepulseglob,msectypes; + +const +{$ifdef mswindows} + pulsesimplelib: array[0..0] of filenamety = ('libpulse-simple-0.dll'); +{$else} + pulsesimplelib: array[0..1] of filenamety = + ('libpulse-simple.so.0','libpulse-simple.so'); +{$endif} +type + pa_simple = record //opaque connection object + end; + ppa_simple = ^pa_simple; + +var + pa_simple_new: function( + const server: pchar; //**< Server name, or NULL for default */ + const name: pchar; //**< A descriptive name for this client + //(application name, ...) */ + dir: pa_stream_direction_t; //**< Open this stream for recording or playback? */ + const dev: pchar; //**< Sink (resp. source) name, or NULL for default */ + const stream_name: pchar; //**< A descriptive name for this client (application name, song title, ...) */ + const ss: ppa_sample_spec; //**< The sample type to use */ + const map: ppa_channel_map; //**< The channel map to use, or NULL for default */ + const attr: ppa_buffer_attr; //**< Buffering attributes, or NULL for default */ + error: pcint //**< A pointer where the error code is stored + //when the routine returns NULL. + //It is OK to pass NULL here. */ + ): ppa_simple; cdecl; +//** Close and free the connection to the server. The connection objects becomes invalid when this is called. */ + pa_simple_free: procedure(s: ppa_simple); cdecl; + +//** Write some data to the server */ + pa_simple_write: function(s: ppa_simple; const data: pointer; + bytes: size_t; error: pcint): cint; cdecl; + +//** Wait until all data already written is played by the daemon */ + pa_simple_drain: function(s: ppa_simple; error: pcint): cint; cdecl; + +//** Read some data from the server */ + pa_simple_read: function(s: ppa_simple; data: pointer; bytes: size_t; + error: pcint): cint; cdecl; +//** Return the playback latency. */ + pa_simple_get_latency: function(s: ppa_simple; + error: pcint): pa_usec_t; cdecl; + +//** Flush the playback buffer. */ + pa_simple_flush: function(s: ppa_simple; error: pcint): cint; cdecl; + +procedure initializepulsesimple(const sonames: array of filenamety); + //[] = default +procedure releasepulsesimple; + +implementation +uses + msedynload,sysutils,msesys,msepulse; + +var + libinfo: dynlibinfoty; + +procedure initializepulsesimple(const sonames: array of filenamety); //[] = default +const + funcs: array[0..6] of funcinfoty = ( + (n: 'pa_simple_new'; d: {$ifndef FPC}@{$endif}@pa_simple_new), //0 + (n: 'pa_simple_free'; d: {$ifndef FPC}@{$endif}@pa_simple_free), //1 + (n: 'pa_simple_write'; d: {$ifndef FPC}@{$endif}@pa_simple_write), //2 + (n: 'pa_simple_drain'; d: {$ifndef FPC}@{$endif}@pa_simple_drain), //3 + (n: 'pa_simple_read'; d: {$ifndef FPC}@{$endif}@pa_simple_read), //4 + (n: 'pa_simple_get_latency'; d: {$ifndef FPC}@{$endif}@pa_simple_get_latency), //5 + (n: 'pa_simple_flush'; d: {$ifndef FPC}@{$endif}@pa_simple_flush) //6 + ); + errormessage = 'Can not load Pulseaudio simple library. '; +begin + initializedynlib(libinfo,sonames,pulsesimplelib,funcs,[],errormessage); + initializepulse([]); +end; + +procedure releasepulsesimple; +begin + releasedynlib(libinfo); + releasepulse; +end; + +initialization + initializelibinfo(libinfo); +finalization + finalizelibinfo(libinfo); +end. diff --git a/mseide-msegui/lib/common/audio/msespeak.pas b/mseide-msegui/lib/common/audio/msespeak.pas new file mode 100644 index 0000000..8fb9db0 --- /dev/null +++ b/mseide-msegui/lib/common/audio/msespeak.pas @@ -0,0 +1,1244 @@ +{ MSEgui Copyright (c) 2017-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +// +// under construction +// +unit msespeak; +{$ifdef FPC}{$mode objfpc}{$h+}{$goto on}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,mseclasses,msetypes,mseespeakng,msearrayprops, + msethread,mseevent,msesystypes,mselist; +type + espeakoptionty = (eso_nospeakaudio,eso_speakonidle); + espeakoptionsty = set of espeakoptionty; +const + defaultespeakoptions = [eso_speakonidle]; +type + speakoptionty = (so_cancel,so_wait,so_ssml,so_phonemes,so_endpause); + + speakoptionsty = set of speakoptionty; + + tcustomespeakng = class; + + genderty = (gen_none,gen_male,gen_female); + punctuationty = (pu_none,pu_all,pu_some); + tvoice = class(townedpersistent) + private + fgender: genderty; + fpitch: int32; + frate: int32; + fvolume: int32; + frange: int32; + fpunctuation: punctuationty; + fcapitals: int32; + fwordgap: int32; + flanguage: msestring; + fvoicename: msestring; + fidentifier: msestring; + fvariant: msestring; + fage: card8; + fvariantnum: card8; + fpunctuationlist: msestring; + procedure setgender(const avalue: genderty); + procedure setpitch(const avalue: int32); + procedure setrate(const avalue: int32); + procedure setvolume(const avalue: int32); + procedure setrange(const avalue: int32); + procedure setpunctuation(const avalue: punctuationty); + procedure setcapitals(const avalue: int32); + procedure setwordgap(const avalue: int32); + procedure setlanguage(const avalue: msestring); + procedure setidentifier(const avalue: msestring); + procedure setvoicename(const avalue: msestring); + procedure setvariant(const avalue: msestring); + procedure setage(const avalue: card8); + procedure setvariantnum(const avalue: card8); + procedure setpunctuationlist(const avalue: msestring); + protected + fid: string; + procedure change(); + public + constructor create(aowner: tobject); override; + published + property identifier: msestring read fidentifier write setidentifier; + //voice selection 1. priority + // the filename for this voice within + //espeak-ng-data/voices + property voicename: msestring read fvoicename write setvoicename; + //voice selection used if identifier = '', example: de + property variant: msestring read fvariant write setvariant; + //appended to identifier or voicename, example: f3 + + + //values below used for voice selection if identifier and voicename = '' + property language: msestring read flanguage write setlanguage; + //example: en-uk + property variantnum: card8 read fvariantnum write setvariantnum default 0; + property gender: genderty read fgender write setgender default gen_none; + property age: card8 read fage write setage default 0; + + //voice independent parameters + property rate: int32 read frate write setrate default espeakRATE_NORMAL; + {espeakRATE: speaking speed in word per minute. Values 80 to 450.} + property volume: int32 read fvolume write setvolume default 100; + {espeakVOLUME: volume in range 0-200 or more. + 0=silence, 100=normal full volume, greater values may + produce amplitude compression or distortion} + property pitch: int32 read fpitch write setpitch default 50; + {espeakPITCH: base pitch, range 0-100. 50=normal} + property range: int32 read frange write setrange default 50; + {espeakRANGE: pitch range, range 0-100. 0-monotone, 50=normal} + property punctuationlist: msestring read fpunctuationlist + write setpunctuationlist; + property punctuation: punctuationty read fpunctuation + write setpunctuation default pu_none; + {espeakPUNCTUATION: which punctuation characters to announce: + value in espeak_PUNCT_TYPE (none, all, some), + see espeak_GetParameter() to specify which characters are announced.} + property capitals: int32 read fcapitals write setcapitals default -1; + {espeakCAPITALS: announce capital letters by: + 0=none, + 1=sound icon, + 2=spelling, + 3 or higher, by raising pitch. + This values gives the amount in Hz by which the pitch + of a word raised to indicate it has a capital letter.} + property wordgap: int32 read fwordgap write setwordgap default -1; + //-1 = default + {espeakWORDGAP: pause between words, units of 10mS (at the default speed)} + end; + + tvoices = class(townedpersistentarrayprop) + private + function getitems(const index: int32): tvoice; + procedure setitems(const index: int32; const avalue: tvoice); + protected + procedure setcount1(acount: integer; doinit: boolean); override; + public + constructor create(const aowner: tcustomespeakng); reintroduce; + class function getitemclasstype: persistentclassty; override; + property items[const index: int32]: tvoice read getitems + write setitems; default; + end; + + speakmodety = (smo_text,smo_char,smo_key); + tspeakevent = class(tmseevent) + protected + fmode: speakmodety; + fvoice: int32; + foptions: speakoptionsty; + ftext: msestring; + fchar: char32; + public + constructor create(const text: msestring; const options: speakoptionsty; + const voice: int32); + constructor create(const achar: char32; const options: speakoptionsty; + const voice: int32); + constructor createkey(const key: msestring; const options: speakoptionsty; + const voice: int32); + end; +{ + tspeakthread = class(teventthread) + protected + fidlecond: condty; + public + constructor create(const athreadproc: threadprocty; + const afreeonterminate: boolean = false; + const astacksizekb: integer = 0); overload; override; + destructor destroy(); override; + procedure clearevents() override; + end; +} + speakstatety = (ss_voicevalid,ss_connected,ss_disconnected, + ss_connecting,ss_espeaknginitialized, + ss_canceled,ss_idle); + speakstatesty = set of speakstatety; + + espeakngeventty = procedure(const sender: tcustomespeakng) of object; + + tcustomespeakng = class(tmsecomponent) + private + factive: boolean; + fdatapath: filenamety; + foptions: espeakoptionsty; + fdevice: msestring; + fbufferlength: int32; + fvoicedefault: int32; + fvoices: tvoices; + fpunctuationlist: msestring; + fvolume: flo64; + frate: flo64; + fpitch: flo64; + frange: flo64; + fwordgap: int32; + flanguage: msestring; + fidentifier: msestring; + fvariant: msestring; + fgender: genderty; + fage: card8; + fvariantnum: card8; + fcapitals: int32; + fvoicename: msestring; + fonbeforeconnect: espeakngeventty; + procedure setactive(const avalue: boolean); + procedure setvoicedefault(avalue: int32); + procedure setvoices(const avalue: tvoices); + procedure setpunctuationlist(const avalue: msestring); + procedure setvolume(const avalue: flo64); + procedure setrate(const avalue: flo64); + procedure setpitch(const avalue: flo64); + procedure setrange(const avalue: flo64); + procedure setwordgap(const avalue: int32); + procedure setlanguage(const avalue: msestring); + procedure setidentifier(const avalue: msestring); + procedure setvariant(const avalue: msestring); + procedure setgender(const avalue: genderty); + procedure setage(const avalue: card8); + procedure setvariantnum(const avalue: card8); + procedure setcapitals(const avalue: int32); + procedure setvoicename(const avalue: msestring); + protected + fstate: speakstatesty; + flastvoice: int32; + fspeakqueue: tcustomeventqueue; + fspeakthread: teventthread; + fidlecond: condty; + procedure doasyncevent(var atag: int32) override; + function speakexe(athread: tmsethread): int32; + procedure loaded() override; + procedure connect(); + procedure disconnect(); + procedure doidle(var again: boolean); + procedure checkerror(const astate: espeak_ng_status); + procedure voicechanged(); + procedure checkvoice(avoice: int32); + procedure internalspeak(const atext: msestring; + const aoptions: speakoptionsty; + const avoice: int32); + procedure internalspeakcharacter(const achar: char32; + const aoptions: speakoptionsty; + const avoice: int32); + procedure internalspeakkeyname(const akey: msestring; + const aoptions: speakoptionsty; + const avoice: int32); + procedure lock(); + procedure unlock(); + procedure beginchange(); + procedure endchange(); + + procedure postidle(); + procedure postevent(const aevent: tspeakevent); + public + constructor create(aowner: tcomponent); override; + destructor destroy(); override; + procedure speak(const atext: msestring; const aoptions: speakoptionsty = []; + const avoice: int32 = -1); //-1 -> default + procedure speakcharacter(const achar: char32; + const aoptions: speakoptionsty = []; + const avoice: int32 = -1); //-1 -> default + procedure speakkeyname(const akey: msestring; + const aoptions: speakoptionsty = []; + const avoice: int32 = -1); //-1 -> default + procedure wait(); + procedure cancel(); + property active: boolean read factive write setactive default false; + property datapath: filenamety read fdatapath write fdatapath; + property options: espeakoptionsty read foptions write foptions + default defaultespeakoptions; + property device: msestring read fdevice write fdevice; + property bufferlength: int32 read fbufferlength + write fbufferlength default 0; + //ms, 0 -> 60ms + property voicedefault: int32 read fvoicedefault + write setvoicedefault default 0; + property voices: tvoices read fvoices write setvoices; + property identifier: msestring read fidentifier write setidentifier; + property voicename: msestring read fvoicename write setvoicename; + property variant: msestring read fvariant write setvariant; + + property language: msestring read flanguage write setlanguage; + property gender: genderty read fgender write setgender default gen_none; + property age: card8 read fage write setage default 0; + property variantnum: card8 read fvariantnum write setvariantnum default 0; + + property volume: flo64 read fvolume write setvolume; //default 1.0 + property rate: flo64 read frate write setrate; //default 1.0 + property pitch: flo64 read fpitch write setpitch; //default 1.0 + property range: flo64 read frange write setrange; //default 1.0 + property capitals: int32 read fcapitals write setcapitals default 0; + property wordgap: int32 read fwordgap write setwordgap default 0; + //n*10ms + property punctuationlist: msestring read fpunctuationlist + write setpunctuationlist; + //for voice.punctuation pu_some + property onbeforeconnect: espeakngeventty read fonbeforeconnect + write fonbeforeconnect; + end; + + tespeakng = class(tcustomespeakng) + published + property active; + property datapath; + property options; + property device; + property bufferlength; + property voicedefault; + property voices; + property language; + property identifier; + property voicename; + property variant; + property gender; + property age; + property variantnum; + property volume; + property rate; + property pitch; + property range; + property wordgap; + property punctuationlist; + property onbeforeconnect; + end; + +implementation +uses + msestrings,msefileutils,msectypes,mseapplication,msesysintf1, + sysutils,msesysutils{$ifdef mswindows},activex{$endif}; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +const + disconnecttag = 5936727; + +{ tspeakevent } + +constructor tspeakevent.create(const text: msestring; + const options: speakoptionsty; const voice: int32); +begin + fmode:= smo_text; + foptions:= options; + fvoice:= voice; + ftext:= text; +end; + +constructor tspeakevent.create(const achar: char32; + const options: speakoptionsty; const voice: int32); +begin + fmode:= smo_char; + foptions:= options; + fvoice:= voice; + fchar:= achar; +end; + +constructor tspeakevent.createkey(const key: msestring; + const options: speakoptionsty; const voice: int32); +begin + fmode:= smo_key; + foptions:= options; + fvoice:= voice; + ftext:= key; +end; + +{ tvoices } + +function tvoices.getitems(const index: int32): tvoice; +begin + checkindex(index); + result:= tvoice(fitems[index]); +end; + +procedure tvoices.setitems(const index: int32; const avalue: tvoice); +begin + checkindex(index); + fitems[index].assign(avalue); +end; + +constructor tvoices.create(const aowner: tcustomespeakng); +begin + inherited create(aowner,tvoice); + count:= 1; +end; + +procedure tvoices.setcount1(acount: integer; doinit: boolean); +begin + tcustomespeakng(fowner).lock(); + if (acount < 1) and not (aps_destroying in fstate) then begin + acount:= 1; + end; + inherited; + tcustomespeakng(fowner).unlock(); +end; + +class function tvoices.getitemclasstype: persistentclassty; +begin + result:= tvoice; +end; + +{ tcustomespeakng } + +constructor tcustomespeakng.create(aowner: tcomponent); +begin + fvolume:= 1; + frate:= 1; + fpitch:= 1; + frange:= 1; + foptions:= defaultespeakoptions; + inherited; + fspeakqueue:= tcustomeventqueue.create(true); + fvoices:= tvoices.create(self); +end; + +destructor tcustomespeakng.destroy(); +begin + active:= false; + fvoices.free(); + fspeakqueue.free(); + inherited; +end; + +procedure tcustomespeakng.setactive(const avalue: boolean); +begin + if avalue <> factive then begin + if not(csloading in componentstate) then begin + if avalue then begin + try + connect(); + except + disconnect(); + raise; + end; + end + else begin + disconnect(); + end; + end; + factive:= avalue; + end; +end; + +procedure tcustomespeakng.setvoicedefault(avalue: int32); +begin + if (avalue < 0) or (avalue >= fvoices.count) then begin + avalue:= 0; + end; + fvoicedefault:= avalue; +end; + +procedure tcustomespeakng.setvoices(const avalue: tvoices); +begin + fvoices.assign(avalue); +end; + +procedure tcustomespeakng.setpunctuationlist(const avalue: msestring); +begin + if fpunctuationlist <> avalue then begin + beginchange(); + fpunctuationlist:= avalue; + endchange(); + end; +end; + +procedure tcustomespeakng.setvolume(const avalue: flo64); +begin + if fvolume <> avalue then begin + beginchange(); + fvolume:= avalue; + endchange(); + end; +end; + +procedure tcustomespeakng.setrate(const avalue: flo64); +begin + if frate <> avalue then begin + beginchange(); + frate:= avalue; + endchange(); + end; +end; + +procedure tcustomespeakng.setpitch(const avalue: flo64); +begin + if fpitch <> avalue then begin + beginchange(); + fpitch:= avalue; + endchange(); + end; +end; + +procedure tcustomespeakng.setrange(const avalue: flo64); +begin + if frange <> avalue then begin + beginchange(); + frange:= avalue; + endchange(); + end; +end; + +procedure tcustomespeakng.setwordgap(const avalue: int32); +begin + if fwordgap <> avalue then begin + beginchange(); + fwordgap:= avalue; + endchange(); + end; +end; + +procedure tcustomespeakng.setlanguage(const avalue: msestring); +begin + if flanguage <> avalue then begin + beginchange(); + flanguage:= avalue; + endchange(); + end; +end; + +procedure tcustomespeakng.setidentifier(const avalue: msestring); +begin + if fidentifier <> avalue then begin + beginchange(); + fidentifier:= avalue; + endchange(); + end; +end; + +procedure tcustomespeakng.setvariant(const avalue: msestring); +begin + if fvariant <> avalue then begin + beginchange(); + fvariant:= avalue; + endchange(); + end; +end; + +procedure tcustomespeakng.setvoicename(const avalue: msestring); +begin + if fvoicename <> avalue then begin + beginchange(); + fvoicename:= avalue; + endchange(); + end; +end; + +procedure tcustomespeakng.doasyncevent(var atag: int32); +begin + if atag = disconnecttag then begin + active:= false; + end + else begin + inherited; + end; +end; + +procedure tcustomespeakng.setgender(const avalue: genderty); +begin + if fgender <> avalue then begin + beginchange(); + fgender:= avalue; + endchange(); + end; +end; + +procedure tcustomespeakng.setage(const avalue: card8); +begin + if fage <> avalue then begin + beginchange(); + fage:= avalue; + endchange(); + end; +end; + +procedure tcustomespeakng.setvariantnum(const avalue: card8); +begin + if fvariantnum <> avalue then begin + beginchange(); + fvariantnum:= avalue; + endchange(); + end; +end; + +procedure tcustomespeakng.setcapitals(const avalue: int32); +begin + if fcapitals <> avalue then begin + beginchange(); + fcapitals:= avalue; + endchange(); + end; +end; + +function tcustomespeakng.speakexe(athread: tmsethread): int32; +var + ev1: tspeakevent; + b1: boolean; +begin +{$ifdef mswindows} + coinitialize(nil); +{$endif} + with teventthread(athread) do begin + while not terminated do begin + pointer(ev1):= waitevent(); + if ev1 is tspeakevent then begin + lock(); + b1:= ss_disconnected in fstate; + checkerror(espeak_ng_setcancelstate(0)); + unlock(); + if not b1 then begin + try + case ev1.fmode of + smo_text: begin + internalspeak(ev1.ftext,ev1.foptions,ev1.fvoice); + end; + smo_char: begin + internalspeakcharacter(ev1.fchar,ev1.foptions,ev1.fvoice); + end; + smo_key: begin + internalspeakkeyname(ev1.ftext,ev1.foptions,ev1.fvoice); + end; + end; + except + application.handleexception(); + end; + end; + end; + ev1.free(); + eventlist.lock(); + if eventlist.count = 0 then begin + postidle(); + end; + eventlist.unlock(); + end; + postidle(); + end; +{$ifdef mswindows} + couninitialize(); +{$endif} + result:= 0; +end; + +procedure tcustomespeakng.loaded(); +begin + inherited; + if factive then begin + factive:= false; + active:= true; + end; +end; + +procedure tcustomespeakng.connect(); +var + m1: espeak_ng_OUTPUT_MODE; + s1: string; +begin + if not (csdesigning in componentstate) then begin + if assigned(fonbeforeconnect) then begin + fonbeforeconnect(self); + end; + include(fstate,ss_connecting); + application.registeronidle(@doidle); + exclude(fstate,ss_disconnected); + include(fstate,ss_idle); + sys_condcreate(fidlecond); + voicechanged(); + s1:= stringtoutf8ansi(tosysfilepath(fdatapath)); + initializeespeakng([],s1); + include(fstate,ss_espeaknginitialized); + + m1:= ENOUTPUT_MODE_SYNCHRONOUS; +// m1:= 0;//ENOUTPUT_MODE_SYNCHRONOUS; + //espeak_ng_cancel() does not work in synchronous mode + if not (eso_nospeakaudio in foptions) then begin + m1:= m1 or ENOUTPUT_MODE_SPEAK_AUDIO; + end; + checkerror(espeak_ng_InitializeOutput(m1,fbufferlength,nil)); + include(fstate,ss_connected); + fspeakthread:= teventthread.create(@speakexe); + end; +end; + +procedure tcustomespeakng.disconnect(); +begin + if not (csdesigning in componentstate) and + (ss_connecting in fstate) then begin + application.unregisteronidle(@doidle); + cancel(); + freeandnil(fspeakthread); + sys_conddestroy(fidlecond); + exclude(fstate,ss_connected); + if ss_espeaknginitialized in fstate then begin + releaseespeakng(); + exclude(fstate,ss_espeaknginitialized); + end; + exclude(fstate,ss_connecting); + end; +end; + +procedure tcustomespeakng.checkerror(const astate: espeak_ng_status); +begin + if (astate <> 0) and (astate <> ENS_SPEECH_STOPPED) then begin + componentexception(self,utf8tostring(espeakngerrormessage(astate))); + end; +end; + +procedure tcustomespeakng.voicechanged(); +begin + exclude(fstate,ss_voicevalid); +end; + +procedure tcustomespeakng.checkvoice(avoice: int32); +var + info1: espeak_voice; + name1,lang1,ident1,variant1: string; + s1: string; + ms1: msestring; + ar1: card32arty; + i1: int32; + err1: espeak_ng_STATUS; +{$ifdef mse_debugassistive} + p1: pespeak_voice; +{$endif} +begin + lock(); + try + if avoice < 0 then begin + avoice:= fvoicedefault; + end; + if (avoice >= fvoices.count) then begin + avoice:= 0; + end; + if not (ss_voicevalid in fstate) or (flastvoice <> avoice) then begin + include(fstate,ss_voicevalid); + flastvoice:= avoice; + fillchar(info1,sizeof(info1),0); + with voices[avoice] do begin + if language <> '' then begin + lang1:= stringtoutf8(language); + end + else begin + lang1:= stringtoutf8(self.flanguage); + end; + info1.languages:= pointer(lang1); + if identifier <> '' then begin + ident1:= stringtoutf8(tosysfilepath(identifier)); + end + else begin + ident1:= stringtoutf8(tosysfilepath(self.identifier)); + end; + info1.identifier:= pointer(ident1); + if voicename <> '' then begin + name1:= stringtoutf8(tosysfilepath(voicename)); + end + else begin + name1:= stringtoutf8(tosysfilepath(self.voicename)); + end; + info1.name:= pointer(name1); + if variant <> '' then begin + variant1:= stringtoutf8(tosysfilepath(variant)); + end + else begin + variant1:= stringtoutf8(tosysfilepath(self.variant)); + end; + info1.name:= pointer(name1); + if gender <> gen_none then begin + info1.gender:= ord(gender); + end + else begin + info1.gender:= ord(self.gender); + end; + if age > 0 then begin + info1.age:= age; + end + else begin + info1.age:= self.age; + end; + if variantnum > 0 then begin + info1.variant:= variantnum; + end + else begin + info1.variant:= self.variantnum; + end; + if punctuationlist <> '' then begin + ms1:= punctuationlist; + end + else begin + ms1:= self.punctuationlist; + end; + setlength(ar1,length(ms1)+1); //terminating #0 + for i1:= 0 to high(ar1)-1 do begin + ar1[i1]:= ord(ms1[i1+1]); + end; + checkerror(espeak_ng_setpunctuationlist(pointer(ar1))); + if fid <> '' then begin + err1:= espeak_ng_setvoicebyname(pchar(fid)); + end + else begin + s1:= ''; + if ident1 <> '' then begin + s1:= ident1; + end + else begin + if name1 <> '' then begin + s1:= name1; + end; + end; + if s1 <> '' then begin + if variant1 <> '' then begin + s1:= s1+'+'+variant1; + end; + err1:= espeak_ng_setvoicebyname(pchar(s1)); + end + else begin + err1:= espeak_ng_setvoicebyproperties(@info1); + end; + if err1 = ENS_OK then begin + fid:= espeak_getcurrentvoice()^.identifier; + end; + end; + {$ifdef mse_debugassistive} + p1:= espeak_getcurrentvoice(); + debugwriteln(inttostr(avoice)+':'+p1^.identifier+':'+p1^.name); + {$endif} + if err1 <> ENS_OK then begin + include(fstate,ss_disconnected); + asyncevent(disconnecttag,[peo_local,peo_first]); + checkerror(err1); + end; + checkerror(espeak_ng_setparameter(espeakRATE,round(rate*self.rate),0)); + checkerror(espeak_ng_setparameter(espeakVOLUME, + round(volume*self.volume),0)); + checkerror(espeak_ng_setparameter(espeakPITCH,round(pitch*self.pitch),0)); + checkerror(espeak_ng_setparameter(espeakRANGE,round(range*self.range),0)); + checkerror(espeak_ng_setparameter(espeakPUNCTUATION, + ord(punctuation),0)); + if capitals < 0 then begin + i1:= self.capitals; + end + else begin + i1:= capitals; + end; + checkerror(espeak_ng_setparameter(espeakCAPITALS,i1,0)); + if wordgap < 0 then begin + i1:= self.wordgap; + end + else begin + i1:= wordgap; + end; + checkerror(espeak_ng_setparameter(espeakWORDGAP,i1,0)); + end; + end; + finally + unlock(); + end; +end; + +procedure tcustomespeakng.wait(); +var + b1: boolean; +begin + if not (ss_connected in fstate) then begin + exit; + end; + doidle(b1); + with fspeakthread do begin + sys_condlock(fidlecond); + while true do begin + if ss_idle in fstate then begin + sys_condunlock(fidlecond); + break; + end + else begin + sys_condwait(fidlecond,0); + end; + end; + end; +// checkerror(espeak_ng_synchronize()); +end; + +procedure tcustomespeakng.cancel(); +begin + if not (ss_connected in fstate) then begin + exit; + end; +{$ifdef mse_debugassistive} + debugwriteln('---cancel'); +{$endif} + fspeakqueue.clear(); + fspeakthread.clearevents(); + include(fstate,ss_canceled); +// fspeakthread.lock(); + checkerror(espeak_ng_setcancelstate(1)); +// fspeakthread.unlock(); +// postidle(); +end; + +procedure tcustomespeakng.internalspeak(const atext: msestring; + const aoptions: speakoptionsty; const avoice: int32); +var + s1: string; + f1: cuint; +begin + checkvoice(avoice); + f1:= espeakCHARS_UTF8; + if so_ssml in aoptions then begin + f1:= f1 or espeakSSML; + end; + if so_phonemes in aoptions then begin + f1:= f1 or espeakPHONEMES; + end; + if so_endpause in aoptions then begin + f1:= f1 or espeakENDPAUSE; + end; + s1:= stringtoutf8(atext); + replacechar1(s1,c_tab,' '); +// {$ifdef mse_debugassistive} +// debugwriteln(inttostr(length(s1))+':'+s1); +// {$endif} + checkerror(espeak_ng_synthesize(pchar(s1),length(s1)+1, //terminating #0 + 0,pos_character,0,f1,nil,nil)); +end; + +procedure tcustomespeakng.lock(); +begin + if ss_connected in fstate then begin + fspeakthread.lock(); + end; +end; + +procedure tcustomespeakng.unlock(); +begin + if ss_connected in fstate then begin + fspeakthread.unlock(); + end; +end; + +procedure tcustomespeakng.beginchange(); +begin + lock(); +end; + +procedure tcustomespeakng.endchange(); +begin + voicechanged(); + unlock(); +end; + +procedure tcustomespeakng.postidle(); +begin + sys_condlock(fidlecond); + include(fstate,ss_idle); + sys_condbroadcast(fidlecond); + sys_condunlock(fidlecond); +end; + +procedure tcustomespeakng.doidle(var again: boolean); +begin + if fspeakqueue.count > 0 then begin + fspeakthread.eventlist.lock(); + sys_condlock(fidlecond); + exclude(fstate,ss_idle); + fspeakthread.eventlist.post(fspeakqueue); + sys_condunlock(fidlecond); + fspeakthread.eventlist.unlock(); + end; +end; + +procedure tcustomespeakng.postevent(const aevent: tspeakevent); +begin + if ss_canceled in fstate then begin + wait(); + exclude(fstate,ss_canceled); + end; + if eso_speakonidle in foptions then begin + fspeakqueue.add(aevent); + end + else begin + fspeakthread.eventlist.lock(); + sys_condlock(fidlecond); + exclude(fstate,ss_idle); + fspeakthread.postevent(aevent); + sys_condunlock(fidlecond); + fspeakthread.eventlist.unlock(); + end; +end; + +procedure tcustomespeakng.speak(const atext: msestring; + const aoptions: speakoptionsty = []; const avoice: int32 = -1); +var + c1: char16; +begin + if not (ss_connected in fstate) then begin + exit; + end; + if so_cancel in aoptions then begin + cancel(); + end; +{$ifdef mse_debugassistive} + debugwriteln('**'+inttostr(avoice)+' '+string(atext)); +{$endif} + if atext <> '' then begin + c1:= atext[length(atext)]; + if (c1 in ['.',',',':',';','?','!']) then begin + postevent(tspeakevent.create(atext+' ',aoptions,avoice)); + //last punctuation not spoken, espeak bug? + end + else begin + postevent(tspeakevent.create(atext,aoptions,avoice)); + end; + end; + if so_wait in aoptions then begin + wait(); + end; +end; + +procedure tcustomespeakng.internalspeakcharacter(const achar: char32; + const aoptions: speakoptionsty; const avoice: int32); +begin + checkvoice(avoice); + checkerror(espeak_ng_speakcharacter(ord(achar))); +end; + +procedure tcustomespeakng.speakcharacter(const achar: char32; + const aoptions: speakoptionsty = []; const avoice: int32 = -1); +begin + if not (ss_connected in fstate) then begin + exit; + end; + if so_cancel in aoptions then begin + cancel(); + end; +{$ifdef mse_debugassistive} + debugwriteln('***'+inttostr(avoice)+' '+string(unicodechar(achar))); +{$endif} + postevent(tspeakevent.create(achar,aoptions,avoice)); + if so_wait in aoptions then begin + wait(); + end; +end; + +procedure tcustomespeakng.internalspeakkeyname(const akey: msestring; + const aoptions: speakoptionsty; const avoice: int32); +begin + checkvoice(avoice); + checkerror(espeak_ng_speakkeyname(pchar(stringtoutf8(akey)))); +end; + +procedure tcustomespeakng.speakkeyname(const akey: msestring; + const aoptions: speakoptionsty = []; const avoice: int32 = -1); +begin + if not (ss_connected in fstate) then begin + exit; + end; + if so_cancel in aoptions then begin + cancel(); + end; +{$ifdef mse_debugassistive} + debugwriteln('****'+inttostr(avoice)+' '+string(akey)); +{$endif} + if akey <> '' then begin + postevent(tspeakevent.createkey(akey,aoptions,avoice)); + end; + if so_wait in aoptions then begin + wait(); + end; +end; + +{ tvoice } + +constructor tvoice.create(aowner: tobject); +begin + fpitch:= 50; + frate:= espeakRATE_NORMAL; + fvolume:= 100; + frange:= 50; + fcapitals:= -1; + fwordgap:= -1; + inherited; +end; +{ +procedure tvoice.beginchange(); +begin + tcustomespeakng(fowner).lock(); +end; + +procedure tvoice.endchange(); +begin + tcustomespeakng(fowner).voicechanged(); + tcustomespeakng(fowner).unlock(); +end; +} +procedure tvoice.setgender(const avalue: genderty); +begin + if avalue <> fgender then begin + change(); + tcustomespeakng(fowner).beginchange(); + fgender:= avalue; + tcustomespeakng(fowner).endchange(); + end; +end; + +procedure tvoice.setpitch(const avalue: int32); +begin + if avalue <> fpitch then begin + change(); + tcustomespeakng(fowner).beginchange(); + fpitch:= avalue; + tcustomespeakng(fowner).endchange(); + end; +end; + +procedure tvoice.setrate(const avalue: int32); +begin + if avalue <> frate then begin + change(); + tcustomespeakng(fowner).beginchange(); + frate:= avalue; + tcustomespeakng(fowner).endchange(); + end; +end; + +procedure tvoice.setvolume(const avalue: int32); +begin + if avalue <> fvolume then begin + change(); + tcustomespeakng(fowner).beginchange(); + fvolume:= avalue; + tcustomespeakng(fowner).endchange(); + end; +end; + +procedure tvoice.setrange(const avalue: int32); +begin + if avalue <> frange then begin + change(); + tcustomespeakng(fowner).beginchange(); + frange:= avalue; + tcustomespeakng(fowner).endchange(); + end; +end; + +procedure tvoice.setpunctuation(const avalue: punctuationty); +begin + if avalue <> fpunctuation then begin + change(); + tcustomespeakng(fowner).beginchange(); + fpunctuation:= avalue; + tcustomespeakng(fowner).endchange(); + end; +end; + +procedure tvoice.setcapitals(const avalue: int32); +begin + if avalue <> fcapitals then begin + change(); + tcustomespeakng(fowner).beginchange(); + fcapitals:= avalue; + tcustomespeakng(fowner).endchange(); + end; +end; + +procedure tvoice.setwordgap(const avalue: int32); +begin + if avalue <> fwordgap then begin + change(); + tcustomespeakng(fowner).beginchange(); + fwordgap:= avalue; + tcustomespeakng(fowner).endchange(); + end; +end; + +procedure tvoice.setvoicename(const avalue: msestring); +begin + if avalue <> fvoicename then begin + change(); + tcustomespeakng(fowner).beginchange(); + fvoicename:= avalue; + tcustomespeakng(fowner).endchange(); + end; +end; + +procedure tvoice.setvariant(const avalue: msestring); +begin + if avalue <> fvariant then begin + change(); + tcustomespeakng(fowner).beginchange(); + fvariant:= avalue; + tcustomespeakng(fowner).endchange(); + end; +end; + +procedure tvoice.setlanguage(const avalue: msestring); +begin + if avalue <> flanguage then begin + change(); + tcustomespeakng(fowner).beginchange(); + flanguage:= avalue; + tcustomespeakng(fowner).endchange(); + end; +end; + +procedure tvoice.setidentifier(const avalue: msestring); +begin + if avalue <> fidentifier then begin + change(); + tcustomespeakng(fowner).beginchange(); + fidentifier:= avalue; + tcustomespeakng(fowner).endchange(); + end; +end; + +procedure tvoice.setage(const avalue: card8); +begin + if avalue <> fage then begin + change(); + tcustomespeakng(fowner).beginchange(); + fage:= avalue; + tcustomespeakng(fowner).endchange(); + end; +end; + +procedure tvoice.setvariantnum(const avalue: card8); +begin + if avalue <> fvariantnum then begin + change(); + tcustomespeakng(fowner).beginchange(); + fvariantnum:= avalue; + tcustomespeakng(fowner).endchange(); + end; +end; + +procedure tvoice.setpunctuationlist(const avalue: msestring); +begin + if avalue <> fpunctuationlist then begin + change(); + tcustomespeakng(fowner).beginchange(); + fpunctuationlist:= avalue; + tcustomespeakng(fowner).endchange(); + end; +end; + +procedure tvoice.change(); +begin + fid:= ''; +end; + +end. diff --git a/mseide-msegui/lib/common/container/msedatalist.pas b/mseide-msegui/lib/common/container/msedatalist.pas new file mode 100644 index 0000000..7c07bc1 --- /dev/null +++ b/mseide-msegui/lib/common/container/msedatalist.pas @@ -0,0 +1,7128 @@ +{ MSEgui Copyright (c) 1999-2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msedatalist; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$goto on}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{$ifndef FPC} + {$ifdef mswindows} + {$define msestringsarenotrefcounted} + {$endif} +{$endif} + +uses + sysutils,classes,mclasses,msestrings,typinfo,msereal,msetypes,msestream, + mseclasses,mselist,mseglob,msearrayutils; + +type + + dataprocty = procedure(var data) of object; +{ + internallistoptionty = (ilo_needsfree,ilo_needscopy,ilo_needsinit, + ilo_nostreaming,ilo_nogridstreaming, + ilo_propertystreaming); + internallistoptionsty = set of internallistoptionty; +} + tdatalist = class; + tintegerdatalist = class; + + indexeventty = procedure(const sender: tdatalist; const index: integer) of object; +// listlineeventty = procedure (sender: tdatalist; index: integer) of object; + + blockcopymodety = (bcm_none,bcm_copy,bcm_init,bcm_rotate); +{ + idatalist = interface(inullinterface) + procedure listdestroyed(const sender: idatalist); + getlist: tdatalist; + end; + idatalistarty = array of idatalist; +} + copyprocty = procedure(const source,dest:pointer); + copy2procty = procedure(const source1,source2,dest:pointer); + + datalistarty = array of tdatalist; + + listlinkinfoty = record + name: string; //case sensitive + dirtystart,dirtystop: integer; + source: tdatalist; + end; + plistlinkinfoty = ^listlinkinfoty; + + idatalistclient = interface(iobjectlink) + function getobjectlinker: tobjectlinker; + procedure itemchanged(const sender: tdatalist; const aindex: integer); + end; + + dataliststatety = ( + dls_needsfree,dls_needscopy,dls_needsinit, + dls_nostreaming,dls_nogridstreaming, + dls_propertystreaming,dls_selectsetting, + dls_sorted,dls_sortio, + dls_forcenew, //used in tundolist + dls_remote, //used in ificomp datalist + dls_remotelock, + dls_rowdeleting, //used in treeitemeditlist + dls_facultative,dls_binarydata + ); + dataliststatesty = set of dataliststatety; + + tdatalist = class(tlinkedpersistent) + private + fbytelength: integer; //pufferlaenge + Fcapacity: integer; + fnochange: integer; + fonchange: notifyeventty; + fonitemchange: indexeventty; + fmaxcount: integer; + fringpointer: integer; + fcheckeditem: integer; + procedure setcapacity(value: integer); + procedure internalsetcount(value: integer; nochangeandinit: boolean); + procedure checkcapacity; //ev. reduktion des memory + procedure setmaxcount(const Value: integer); + procedure internalfreedata(index,anzahl: integer); //gibt daten frei falls notwendig + procedure internalcopyinstance(index,anzahl: integer); + function getsorted: boolean; + procedure setsorted(const Value: boolean); //datenkopieren + procedure internalcleardata(const index: integer); + procedure remoteitemchange(const alink: pointer); + procedure setcheckeditem(const avalue: integer); + function getfacultative: boolean; + procedure setfacultative(const avalue: boolean); + protected + fdeleting: integer; + fdatapo: pchar; + fsize: integer; + fcount: integer; + fscrolled: integer; + flinkdest: datalistarty; + fstate: dataliststatesty; + fintparam: integer; + frearanged: boolean; //set by rearange + fgridsortdescend: boolean; //set by tdatacols before sorting + function checkassigncompatibility(const source: tpersistent): boolean; virtual; + procedure checkindex1(const index: integer); + function assigndata(const source: tpersistent): boolean; + //false if not possible + procedure assigntodata(const dest: tdatalist); + procedure newbuffer(const acount: integer; const noinit: boolean; + const fillnull: boolean); + procedure clearbuffer; virtual; //buffer release + procedure setcount(const value: integer); virtual; + property nochange: integer read fnochange; + procedure internalgetasarray(const adatapo: pointer; const asize: integer); + procedure internalsetasarray(const source: pointer; const asize: integer; + const acount: integer); + procedure writedata(writer: twriter); + procedure readdata(reader: treader); + procedure readitem(const reader: treader; var value); virtual; + procedure writeitem(const writer: twriter; var value); virtual; + + procedure internalgetdata(index: integer; out ziel); + procedure internalsetdata(index: integer; const quelle); + procedure internalfill(const anzahl: integer; const wert); + procedure getdefaultdata(var dest); //out is not possible because of + //FPC bug 20962 + procedure getgriddefaultdata(var dest); virtual; + procedure getdata(index: integer; var dest); + procedure getgriddata(index: integer; var dest); virtual; + procedure setdata(index: integer; const source); + procedure setgriddata(index: integer; const source); virtual; + function getstatdata(const index: integer): msestring; virtual; + procedure setstatdata(const index: integer; const value: msestring); virtual; + procedure writestate(const writer; const name: msestring); virtual; + //typeless because of recursive interface + procedure readstate(const reader; const acount: integer; + const name: msestring); virtual; + procedure writeappendix(const writer; const aname: msestring); virtual; + procedure readappendix(const reader; const aname: msestring); virtual; + + function poptopdata(var ziel): boolean; //top of stack, false if empty + function popbottomdata(var ziel): boolean; //bottom of stack, false if empty + procedure pushdata(const quelle); + procedure checkbuffersize(increment: integer); //fuer ringpuffer + procedure internalinsertdata(index: integer; const quelle; + const docopy: boolean); + procedure insertdata(const index: integer; const quelle); + procedure defineproperties(const propname: string; + const filer: tfiler); + procedure defineproperties(filer: tfiler); override; + procedure freedata(var data); virtual; //gibt daten frei + procedure beforecopy(var data); virtual; + procedure aftercopy(var data); virtual; + procedure initinstance(var data); virtual; //fuer neue zeilen aufgerufen + function internaladddata(const quelle; docopy: boolean): integer; + function adddata(const quelle): integer; + function compare(const l,r): integer; virtual; + function comparecaseinsensitive(const l,r): integer; virtual; + function getdefault: pointer; virtual; //nil fuer null + procedure normalizering; //macht ringpointer = null + procedure blockcopymovedata(fromindex,toindex: integer; + const acount: integer; const mode: blockcopymodety); + procedure initdata1(const afree: boolean; index: integer; + const acount: integer); + //initialisiert mit defaultwert + procedure forall(startindex: integer; const count: integer; + const proc: dataprocty); + procedure doitemchange(const index: integer); virtual; + procedure dochange; virtual; + procedure internaldeletedata(index: integer; dofree: boolean); + + function getlinkdatatypes(const atag: integer): listdatatypesty; virtual; + procedure initsource(var asource: listlinkinfoty); + procedure removesource(var asource: listlinkinfoty); + procedure checklistdestroyed(var ainfo: listlinkinfoty; + const sender: tdatalist); + procedure unlinksource(var alink: listlinkinfoty); + function internallinksource(const source: tdatalist; + const atag: integer; var variable: tdatalist): boolean; + function sourceischanged(const asource: listlinkinfoty): boolean; + function checksourcechange(var ainfo: listlinkinfoty; + const sender: tdatalist; const aindex: integer): boolean; + function checksourcecopy(var ainfo: listlinkinfoty; + const copyproc: copyprocty): boolean; + function checksourcecopy2(var ainfo: listlinkinfoty; + const source2: tdatalist; const copyproc: copy2procty): boolean; + procedure internalrearange(arangelist: pinteger; const acount: integer); + function islinked(const asource: tdatalist): boolean; + procedure datadeleted(const aindex: integer; const acount: integer); + procedure datainserted(const aindex: integer; const acount: integer); + procedure datamoved(const fromindex: integer; const toindex: integer; + const acount: integer); virtual; + procedure setitemselected(const row: integer; const value: boolean); virtual; + //iificlient + function getifidatatype(): listdatatypety virtual; + public + constructor create; override; + destructor destroy; override; + + //idatalist + procedure listdestroyed(const sender: tdatalist); virtual; + procedure sourcechange(const sender: tdatalist; + const aindex: integer); virtual; + + procedure linkclient(const aclient: idatalistclient); + procedure unlinkclient(const aclient: idatalistclient); + + function getsourcecount: integer; virtual; + function getsourceinfo(const atag: integer): plistlinkinfoty; virtual; + function getsourcename(const atag: integer): string; + procedure linksource(const source: tdatalist; const atag: integer); virtual; + function canlink(const asource: tdatalist; + const atag: integer): boolean; virtual; + + property size: integer read fsize; + property state: dataliststatesty read fstate; + function datapo: pointer; //calls normalizering, + //do not use in copyinstance,initinstance,freedata + function datahighpo: pointer; //points to last item + function getitempo(index: integer): pointer; + //invalid after capacity change + function getastext(const index: integer): msestring; virtual; + procedure setastext(const index: integer; const avalue: msestring); virtual; + + procedure assign(sender: tpersistent); override; + procedure assignb(const source: tdatalist); virtual; + //assign with second value if possible, exception otherwise + procedure assigntob(const dest: tdatalist); virtual; + //assignto with second value if possible, exception otherwise + function getdatablock(const source: pointer; const destsize: integer): integer; + //returns size of datablock + function setdatablock(const dest: pointer; const sourcesize: integer; + const acount: integer): integer; + //returns size of datablock + procedure change(const index: integer); virtual; + //index -1 -> undefined + class function datatype: listdatatypety; virtual; + procedure checkindexrange(const aindex: integer; const acount: integer = 1); + procedure checkindex(var index: integer); + //bringt absolute zeilennummer in ringpuffer + procedure beginupdate; virtual; + procedure endupdate; virtual; + procedure incupdate; + procedure decupdate; + function updating: boolean; + procedure clear; virtual;//loescht daten + procedure initdata(const index,anzahl: integer); + //anzahl -> count, initialisiert mit defaultwert + procedure cleardata(index: integer); + function deleting: boolean; + function checkwritedata(const filer: tfiler): boolean; virtual; + + procedure rearange(const arangelist: tintegerdatalist); overload; + procedure rearange(const arangelist: integerarty); overload; + procedure movedata(const fromindex,toindex: integer); + procedure blockmovedata(const fromindex,toindex,count: integer); + procedure blockcopydata(const fromindex,toindex,count: integer); + procedure deletedata(const index: integer); + procedure deleteitems(index,acount: integer); virtual; + procedure insertitems(index,acount: integer); virtual; + function empty(const index: integer): boolean; virtual; //true wenn leer + + function sort(const comparefunc: sortcomparemethodty; + out arangelist: integerarty; + const dorearange: boolean): boolean; + function sort(out arangelist: integerarty; + const dorearange: boolean): boolean; + function sort(const compareproc: sortcomparemethodty): boolean; + function sort: boolean; //true if changed + function sortcaseinsensitive: boolean; //true if changed + function sortcaseinsensitive(out arangelist: integerarty; + const dorearange: boolean): boolean; + + procedure clean(const start,stop: integer); virtual; + procedure clearmemberitem(const subitem: integer; + const index: integer); virtual; + procedure setmemberitem(const subitem: integer; + const index: integer; const avalue: integer); virtual; + + + property count: integer read Fcount write Setcount; //anzahl zeilen + property capacity: integer read Fcapacity write Setcapacity; + property onchange: notifyeventty read fonchange write fonchange; + property onitemchange: indexeventty read fonitemchange write fonitemchange; + + property maxcount: integer read fmaxcount + write setmaxcount default bigint; //for ring buffer + property sorted: boolean read getsorted write setsorted; + property checkeditem: integer read fcheckeditem write setcheckeditem; + //-1 if none + property facultative: boolean read getfacultative + write setfacultative default false; + //used by objecttovalues() + end; + + pdatalist = ^tdatalist; + + tnonedatalist = class(tdatalist) + public + class function datatype: listdatatypety; override; + end; + + subdatainfoty = record + list: tdatalist; + subindex: integer; //0 = main + end; + subdatainfoarty = array of subdatainfoty; + + tintegerdatalist = class(tdatalist) + private + function Getitems(const index: integer): integer; + procedure Setitems(const index: integer; const Value: integer); + procedure setasarray(const avalue: integerarty); + function getasarray: integerarty; + procedure setasbooleanarray(const avalue: booleanarty); + function getasbooleanarray: booleanarty; + protected + function checkassigncompatibility( + const source: tpersistent): boolean; override; + procedure readitem(const reader: treader; var value); override; + procedure writeitem(const writer: twriter; var value); override; + function compare(const l,r): integer; override; + procedure setstatdata(const index: integer; const value: msestring); override; + function getstatdata(const index: integer): msestring; override; + procedure writeappendix(const writer; const aname: msestring); override; + procedure readappendix(const reader; const aname: msestring); override; + public + min: integer; + max: integer; + notcheckedvalue: integer; //used for statread + constructor create; override; + class function datatype: listdatatypety; override; + function empty(const index: integer): boolean; override; //true wenn leer + function add(const value: integer): integer; + procedure insert(const index: integer; const item: integer); + procedure number(const start,step: integer); //numeriert daten + function find(value: integer): integer; //bringt index, -1 wenn nicht gefunden + procedure fill(acount: integer; const defaultvalue: integer); overload; + procedure fill(const defaultvalue: integer); overload; + function getastext(const index: integer): msestring; override; + procedure setastext(const index: integer; const avalue: msestring); override; + + property asarray: integerarty read getasarray write setasarray; + property asbooleanarray: booleanarty read getasbooleanarray write setasbooleanarray; + property items[const index: integer]: integer read Getitems write Setitems; default; + end; + + tbooleandatalist = class(tintegerdatalist) + private + procedure setasarray(const avalue: longboolarty); + function getasarray: longboolarty; + function getitems(const index: integer): boolean; + procedure setitems(const index: integer; const avalue: boolean); + public + procedure fill(acount: integer; const defaultvalue: boolean); overload; + procedure fill(const defaultvalue: boolean); overload; + property asarray: longboolarty read getasarray + write setasarray; + property items[const index: integer]: boolean read Getitems write Setitems; default; + end; + + tint64datalist = class(tdatalist) + private + function Getitems(index: integer): int64; + procedure Setitems(index: integer; const avalue: int64); + procedure setasarray(const value: int64arty); + function getasarray: int64arty; + protected + function checkassigncompatibility( + const source: tpersistent): boolean; override; + procedure readitem(const reader: treader; var value); override; + procedure writeitem(const writer: twriter; var value); override; + function compare(const l,r): integer; override; + procedure setstatdata(const index: integer; const value: msestring); override; + function getstatdata(const index: integer): msestring; override; + public + constructor create; override; + class function datatype: listdatatypety; override; +// procedure assign(source: tpersistent); override; + function empty(const index: integer): boolean; override; //true wenn leer + function add(const avalue: int64): integer; + procedure insert(const index: integer; const avalue: int64); + function find(const avalue: int64): integer; //bringt index, -1 wenn nicht gefunden + procedure fill(const acount: integer; const defaultvalue: int64); overload; + procedure fill(const defaultvalue: int64); overload; + function getastext(const index: integer): msestring; override; + procedure setastext(const index: integer; const avalue: msestring); override; + + property asarray: int64arty read getasarray write setasarray; + property items[index: integer]: int64 read Getitems write Setitems; default; + end; + + tcurrencydatalist = class(tdatalist) + private + function Getitems(index: integer): currency; + procedure Setitems(index: integer; const avalue: currency); + procedure setasarray(const value: currencyarty); + function getasarray: currencyarty; + protected + function checkassigncompatibility( + const source: tpersistent): boolean; override; + procedure readitem(const reader: treader; var value); override; + procedure writeitem(const writer: twriter; var value); override; + function compare(const l,r): integer; override; + procedure setstatdata(const index: integer; const value: msestring); override; + function getstatdata(const index: integer): msestring; override; + public + constructor create; override; + class function datatype: listdatatypety; override; +// procedure assign(source: tpersistent); override; + function empty(const index: integer): boolean; override; //true wenn leer + function add(const avalue: currency): integer; + procedure insert(const index: integer; const avalue: currency); + function find(const avalue: currency): integer; //bringt index, -1 wenn nicht gefunden + procedure fill(const acount: integer; const defaultvalue: currency); overload; + procedure fill(const defaultvalue: currency); overload; + function getastext(const index: integer): msestring; override; + procedure setastext(const index: integer; const avalue: msestring); override; + + property asarray: currencyarty read getasarray write setasarray; + property items[index: integer]: currency read Getitems write Setitems; default; + end; + + tenumdatalist = class(tintegerdatalist) + private + fgetdefault: getintegereventty; + fdefaultval: integer; + protected + function getdefault: pointer; override; + public + constructor create(agetdefault: getintegereventty); reintroduce; + function empty(const index: integer): boolean; override; //true wenn leer + end; + + tenum64datalist = class(tint64datalist) + private + fgetdefault: getint64eventty; + fdefaultval: int64; + protected + function getdefault: pointer; override; + public + constructor create(agetdefault: getint64eventty); reintroduce; + function empty(const index: integer): boolean; override; //true wenn leer + end; + + tcomplexdatalist = class; + + trealdatalist = class(tdatalist) + private + fdefaultzero: boolean; + fdefaultval: realty; + facceptempty: boolean; + function Getitems(index: integer): realty; + procedure Setitems(index: integer; const Value: realty); + function getasarray: realarty; + procedure setasarray(const data: realarty); + protected + function checkassigncompatibility( + const source: tpersistent): boolean; override; + procedure readitem(const reader: treader; var value); override; + procedure writeitem(const writer: twriter; var value); override; + function getdefault: pointer; override; + function compare(const l,r): integer; override; + procedure setstatdata(const index: integer; const value: msestring); override; + function getstatdata(const index: integer): msestring; override; + procedure copytocomplex(dest: pcomplexty); + public + min: realty; + max: realty; + constructor create; override; + class function datatype: listdatatypety; override; + procedure assignre(const source: tcomplexdatalist); overload; + procedure assignim(const source: tcomplexdatalist); overload; + procedure assignre(const source: complexarty); overload; + procedure assignim(const source: complexarty); overload; + procedure assigntore(const dest: tcomplexdatalist); overload; + procedure assigntoim(const dest: tcomplexdatalist); overload; + procedure assigntore(var dest: complexarty); overload; + procedure assigntoim(var dest: complexarty); overload; + function empty(const index: integer): boolean; override; + function add(const value: real): integer; + procedure insert(index: integer; const item: realty); + procedure number(start,step: real); + procedure fill(acount: integer; const defaultvalue: realty); overload; + procedure fill(const defaultvalue: realty); overload; + procedure minmax(out minval,maxval: realty); + function getastext(const index: integer): msestring; override; + procedure setastext(const index: integer; const avalue: msestring); override; + + property asarray: realarty read getasarray write setasarray; + property items[index: integer]: realty read Getitems write Setitems; default; + property defaultzero: boolean read fdefaultzero + write fdefaultzero default false; + property acceptempty: boolean read facceptempty + write facceptempty default false; + end; + + tdatetimedatalist = class(trealdatalist) + protected + function getdefault: pointer; override; + public + class function datatype: listdatatypety; override; + function empty(const index: integer): boolean; override; //true wenn leer + procedure fill(acount: integer; const defaultvalue: tdatetime); overload; + procedure fill(const defaultvalue: tdatetime); overload; + end; + + tcomplexdatalist = class(tdatalist) + private + fdefaultzero: boolean; + fdefaultval: complexty; + function Getitems(const index: integer): complexty; + procedure Setitems(const index: integer; const Value: complexty); + procedure setasarray(const data: complexarty); + function getasarray: complexarty; + function getasarrayre: realarty; + procedure setasarrayre(const avalue: realarty); + function getasarrayim: realarty; + procedure setasarrayim(const avalue: realarty); + protected + function checkassigncompatibility( + const source: tpersistent): boolean; override; + procedure readitem(const reader: treader; var value); override; + procedure writeitem(const writer: twriter; var value); override; + function getdefault: pointer; override; + procedure assignto(dest: tpersistent); override; + public + min: realty; //for property editor + max: realty; + + constructor create; override; + class function datatype: listdatatypety; override; + procedure assign(source: tpersistent); override; + procedure assignb(const source: tdatalist); override; + procedure assignre(const source: trealdatalist); + procedure assignim(const source: trealdatalist); + procedure assigntoa(const dest: tdatalist); + procedure assigntob(const dest: tdatalist); override; + function add(const value: complexty): integer; + procedure insert(const index: integer; const item: complexty); + function empty(const index: integer): boolean; override; //true wenn leer + procedure fill(const acount: integer; const defaultvalue: complexty); overload; + procedure fill(const defaultvalue: complexty); overload; + + property asarray: complexarty read getasarray write setasarray; + property asarrayre: realarty read getasarrayre write setasarrayre; + property asarrayim: realarty read getasarrayim write setasarrayim; + property items[const index: integer]: complexty read Getitems write Setitems; default; + property defaultzero: boolean read fdefaultzero + write fdefaultzero default false; + end; + + realintty = record + rea: realty; + int: integer; + end; + prealintty = ^realintty; + realintarty = array of realintty; + realintaty = array[0..0] of realintty; + + trealintdatalist = class(trealdatalist) + private + fdefaultval1: realintty; + function Getdoubleitems(index: integer): realintty; + procedure Setdoubleitems(index: integer; const Value: realintty); + function Getitemsb(index: integer): integer; + procedure Setitemsb(index: integer; const Value: integer); + function getasarray: realintarty; + procedure setasarray(const data: realintarty); + function getasarraya: realarty; + procedure setasarraya(const data: realarty); + function getasarrayb: integerarty; + procedure setasarrayb(const data: integerarty); + protected + procedure readitem(const reader: treader; var value); override; + procedure writeitem(const writer: twriter; var value); override; + function compare(const l,r): integer; override; + procedure setstatdata(const index: integer; const value: msestring); override; + function getstatdata(const index: integer): msestring; override; + function getdefault: pointer; override; + public + constructor create; override; +// procedure assign(source: tpersistent); override; + procedure assignb(const source: tdatalist); override; + procedure assigntob(const dest: tdatalist); override; + + class function datatype: listdatatypety; override; + function add(const valuea: realty; const valueb: integer = 0): integer; overload; + function add(const value: realintty): integer; overload; + procedure insert(const index: integer; const item: realty; + const itemint: integer); + procedure fill(const acount: integer; const defaultvalue: realty; + const defaultint: integer); overload; + procedure fill(const defaultvalue: realty; + const defaultint: integer); overload; + + property asarray: realintarty read getasarray write setasarray; + property asarraya: realarty read getasarraya write setasarraya; + property asarrayb: integerarty read getasarrayb write setasarrayb; + property itemsb[index: integer]: integer read Getitemsb write Setitemsb; + property doubleitems[index: integer]: realintty read Getdoubleitems + write Setdoubleitems; default; + end; + + tpointerdatalist = class(tdatalist) + private + function Getitems(index: integer): pointer; + procedure Setitems(index: integer; const Value: pointer); + function getasarray: pointerarty; + procedure setasarray(const data: pointerarty); + protected + function checkassigncompatibility( + const source: tpersistent): boolean; override; + procedure readitem(const reader: treader; var value); override; + procedure writeitem(const writer: twriter; var value); override; + public + constructor create; override; + property items[index: integer]: pointer read Getitems write Setitems; default; + property asarray: pointerarty read getasarray write setasarray; + end; + + tdynamicdatalist = class(tdatalist) + protected + public + constructor create; override; + end; + + tdynamicpointerdatalist = class(tdynamicdatalist) + public + constructor create; override; + end; + + tansistringdatalist = class(tdynamicpointerdatalist) + private + function Getitems(index: integer): ansistring; + procedure Setitems(index: integer; const Value: ansistring); + function getasarray: stringarty; + procedure setasarray(const avalue: stringarty); + function getasmsestringarray: msestringarty; + procedure setasmsestringarray(const avalue: msestringarty); + protected + function checkassigncompatibility( + const source: tpersistent): boolean; override; + procedure readitem(const reader: treader; var value); override; + procedure writeitem(const writer: twriter; var value); override; + procedure freedata(var data); override; //gibt daten frei + procedure beforecopy(var data); override; + procedure assignto(dest: tpersistent); override; + function compare(const l,r): integer; override; + function comparecaseinsensitive(const l,r): integer; override; + procedure setstatdata(const index: integer; const value: msestring); override; + function getstatdata(const index: integer): msestring; override; + function textlength: integer; + public + class function datatype: listdatatypety; override; + procedure assign(source: tpersistent); override; + procedure assignopenarray(const data: array of ansistring); +// procedure assignarray(const data: stringarty); overload; +/// procedure assignarray(const data: msestringarty); overload; + procedure insert(index: integer; const item: ansistring); + function add(const value: ansistring): integer; overload; + function addtext(const value: ansistring): integer; + //returns added linecount + function empty(const index: integer): boolean; override; //true wenn leer + procedure fill(acount: integer; const defaultvalue: ansistring); + function getastext(const index: integer): msestring; override; + procedure setastext(const index: integer; const avalue: msestring); override; + + function gettext: ansistring; + procedure settext(const avalue: ansistring); + + property items[index: integer]: ansistring read Getitems write + setitems; default; + property asarray: stringarty read getasarray write setasarray; + property asmsestringarray: msestringarty read getasmsestringarray + write setasmsestringarray; + end; + + tmsestringdatalist = class; + + addcharoptionty = (aco_processeditchars,aco_stripescsequence, + aco_multilinepara); //breaks lines by maxchars in a + //single list row + addcharoptionsty = set of addcharoptionty; + + tpoorstringdatalist = class(tdynamicpointerdatalist) + private + function Getitems(index: integer): msestring; + procedure Setitems(index: integer; const Value: msestring); + function getasarray: msestringarty; + procedure setasarray(const data: msestringarty); + function getasstringarray: stringarty; + procedure setasstringarray(const data: stringarty); + protected + function checkassigncompatibility( + const source: tpersistent): boolean; override; + procedure readitem(const reader: treader; var value); override; + procedure writeitem(const writer: twriter; var value); override; + procedure freedata(var data); override; //gibt daten frei +{$ifdef msestringsarenotrefcounted} + procedure aftercopy(var data); override; +{$else} + procedure beforecopy(var data); override; +{$endif} + procedure assignto(dest: tpersistent); override; + procedure setstatdata(const index: integer; const value: msestring); override; + function getstatdata(const index: integer): msestring; override; + function getnoparagraphs(index: integer): boolean; virtual; + function textlength: integer; + public + feditcharindex: integer; + procedure assign(source: tpersistent); override; + procedure assignopenarray(const data: array of msestring); overload; +// procedure assignarray(const data: stringarty); overload; +// procedure assignarray(const data: msestringarty); overload; + procedure insert(const index: integer; const item: msestring); virtual; abstract; + function add(const value: tmsestringdatalist): integer; overload; + function add(const value: msestring): integer; overload; virtual; abstract; + function add(const avalue: msestring; const anoparagraph: boolean): integer; + overload; virtual; + function addchars(const value: msestring; + const aoptions: addcharoptionsty = [aco_processeditchars]; + const maxchars: integer = 0): integer; + //adds characters to last row, returns index + //maxchars = 0 -> no limitation, inserts line breaks otherwise + function getastext(const index: integer): msestring; override; + procedure setastext(const index: integer; + const avalue: msestring); override; + + function gettext: msestring; + procedure settext(const avalue: msestring); + + function indexof(const value: msestring): integer; + function empty(const index: integer): boolean; override; //true wenn leer + function concatstring(const delim: msestring = ''; + const separator: msestring = ''; + const separatornoparagraph: msestring = ''): msestring; + procedure loadfromfile(const filename: filenamety; + const aencoding: charencodingty = ce_locale); + procedure loadfromstream(const stream: ttextstream); + procedure savetofile(const filename: filenamety; + const aencoding: charencodingty = ce_locale); + procedure savetostream(const stream: ttextstream); + function dataastextstream: ttextstream; + //chars truncated to 8bit, not null terminated + + property asarray: msestringarty read getasarray write setasarray; + property asstringarray:stringarty read getasstringarray write setasstringarray; + property items[index: integer]: msestring read Getitems write Setitems; default; + end; + + stringdatalistoptionty = (sdo_naturalsort); + stringdatalistoptionsty = set of stringdatalistoptionty; + + tmsestringdatalist = class(tpoorstringdatalist) + private + foptions: stringdatalistoptionsty; + protected + function compare(const l,r): integer; override; + function comparecaseinsensitive(const l,r): integer; override; + public + class function datatype: listdatatypety; override; + function add(const value: msestring): integer; override; + procedure insert(const index: integer; const item: msestring); override; + procedure fill(acount: integer; const defaultvalue: msestring); + published + property options: stringdatalistoptionsty read foptions + write foptions default []; + end; + + tdoublemsestringdatalist = class(tpoorstringdatalist) + private + function Getdoubleitems(index: integer): doublemsestringty; + procedure Setdoubleitems(index: integer; const Value: doublemsestringty); + function Getitemsb(index: integer): msestring; + procedure Setitemsb(index: integer; const Value: msestring); + function getasarray: doublemsestringarty; + procedure setasarray(const data: doublemsestringarty); + function getasarraya: msestringarty; + procedure setasarraya(const data: msestringarty); + function getasarrayb: msestringarty; + procedure setasarrayb(const data: msestringarty); + protected + procedure readitem(const reader: treader; var value); override; + procedure writeitem(const writer: twriter; var value); override; + function compare(const l,r): integer; override; + function comparecaseinsensitive(const l,r): integer; override; + procedure freedata(var data); override; //gibt daten frei +{$ifdef msestringsarenotrefcounted} + procedure aftercopy(var data); override; +{$else} + procedure beforecopy(var data); override; +{$endif} + public + constructor create; override; +// procedure assign(source: tpersistent); override; + procedure assignb(const source: tdatalist); override; + procedure assigntob(const dest: tdatalist); override; + + class function datatype: listdatatypety; override; + function add(const value: msestring): integer; overload; override; + function add(const valuea: msestring; const valueb: msestring = ''): integer; overload; + function add(const value: doublemsestringty): integer; overload; + procedure insert(const index: integer; const item: msestring); override; + procedure fill(const acount: integer; const defaultvalue: msestring); + + property asarray: doublemsestringarty read getasarray write setasarray; + property asarraya: msestringarty read getasarraya write setasarraya; + property asarrayb: msestringarty read getasarrayb write setasarrayb; + property itemsb[index: integer]: msestring read Getitemsb write Setitemsb; + property doubleitems[index: integer]: doublemsestringty read Getdoubleitems + write Setdoubleitems; default; + end; + + msestringintty = record + mstr: msestring; + int: integer; + end; + pmsestringintty = ^msestringintty; + msestringintarty = array of msestringintty; + msestringintaty = array[0..0] of msestringintty; + pmsestringintaty = ^msestringintaty; + + tmsestringintdatalist = class(tpoorstringdatalist) + private + function Getdoubleitems(index: integer): msestringintty; + procedure Setdoubleitems(index: integer; const Value: msestringintty); + function Getitemsb(index: integer): integer; + procedure Setitemsb(index: integer; const Value: integer); + function getasarray: msestringintarty; + procedure setasarray(const data: msestringintarty); + function getasarraya: msestringarty; + procedure setasarraya(const data: msestringarty); + function getasarrayb: integerarty; + procedure setasarrayb(const data: integerarty); + protected + procedure readitem(const reader: treader; var value); override; + procedure writeitem(const writer: twriter; var value); override; + function compare(const l,r): integer; override; + function comparecaseinsensitive(const l,r): integer; override; +// procedure freedata(var data); override; +// procedure copyinstance(var data); override; + procedure setstatdata(const index: integer; const value: msestring); override; + function getstatdata(const index: integer): msestring; override; + public + constructor create; override; +// procedure assign(source: tpersistent); override; + procedure assignb(const source: tdatalist); override; + procedure assigntob(const dest: tdatalist); override; + + class function datatype: listdatatypety; override; + function add(const value: msestring): integer; override; + function add(const valuea: msestring; const valueb: integer): integer; overload; + function add(const value: msestringintty): integer; overload; + procedure insert(const index: integer; const item: msestring); + overload; override; + procedure insert(const index: integer; const item: msestring; + const itemint: integer); reintroduce; overload; + procedure fill(const acount: integer; const defaultvalue: msestring; + const defaultint: integer); + + property asarray: msestringintarty read getasarray write setasarray; + property asarraya: msestringarty read getasarraya write setasarraya; + property asarrayb: integerarty read getasarrayb write setasarrayb; + property itemsb[index: integer]: integer read Getitemsb write Setitemsb; + property doubleitems[index: integer]: msestringintty read Getdoubleitems + write Setdoubleitems; default; + end; + +const + foldhiddenbit = 7; + foldhiddenmask = 1 shl foldhiddenbit; + currentfoldhiddenbit = 6; + currentfoldhiddenmask = 1 shl currentfoldhiddenbit; + foldlevelmask = byte(not (foldhiddenmask or currentfoldhiddenmask)); + foldissumbit = 0; + foldissummask = $01; + rowstatemask = $7f; + + selectedcolmax = 30; //32 bitset, bit31 -> whole row + wholerowselectedmask = $80000000; + mergedcolmax = 32; + mergedcolall = $ffffffff; + +type + rowstatenumty = -1..126; //msb = row readonly flag for rowfontstate, + //reserved for rowcolorstate (used in tcustomstringgrid) +const + rowstatenummask = $7f; +type + + rowinfolevelty = (ril_normal,ril_colmerge,ril_rowheight); + rowstatety = packed record + selected: longword; //bitset lsb = col 0, msb-1 = col 30, msb = whole row + //adressed by fcreateindex + color: byte; //index in rowcolors, 0 = none, 1 = rowcolors[0] + font: byte; //index in rowfonts, 0 = none, 1 = rowfonts[0] + fold: byte; // hc nnnnnn h = hidden c = current hidden, + // nnnnnn = fold level, 0 -> top + flags: byte; // 0000000s s = issum + end; + prowstatety = ^rowstatety; + rowstateaty = array[0..0] of rowstatety; + prowstateaty = ^rowstateaty; + + colmergety = packed record + merged: longword; //bitset lsb = col 1, msb = col32, + // $ffffffff = first col fills whole row + //addressed by column index + end; + rowstatecolmergety = packed record + normal: rowstatety; + colmerge: colmergety; + end; + prowstatecolmergety = ^rowstatecolmergety; + rowstatecolmergeaty = array[0..0] of rowstatecolmergety; + prowstatecolmergeaty = ^rowstatecolmergeaty; + + rowheightty = packed record + height: integer; + ypos: integer; + linewidth: byte; //0 -> default, 1 -> 0, 2 -> 1... + linecolor: byte; //index in rowcolors, 0 = none, 1 = rowcolors[0] + linecolorfix: byte; //index in rowcolors, 0 = none, 1 = rowcolors[0] + end; + rowstaterowheightty = packed record + normal: rowstatety; + colmerge: colmergety; + rowheight: rowheightty; + end; + prowstaterowheightty = ^rowstaterowheightty; + rowstaterowheightaty = array[0..0] of rowstaterowheightty; + prowstaterowheightaty = ^rowstaterowheightaty; + + rowstatememberty = (rsm_select,rsm_color,rsm_font,rsm_readonly, + rsm_foldlevel,rsm_foldissum, + rsm_hidden,rsm_merged,rsm_height); + +const + rowinfosizes: array[rowinfolevelty] of integer = + (sizeof(rowstatety),sizeof(rowstatecolmergety), + sizeof(rowstaterowheightty)); +type + rowlinewidthty = -1..254; //-1 = default + tcustomrowstatelist = class(tdatalist) + private + function getrowstate(const index: integer): rowstatety; + procedure setrowstate(const index: integer; const Value: rowstatety); + function getrowstatecolmerge(const index: integer): rowstatecolmergety; + procedure setrowstatecolmerge(const index: integer; + const Value: rowstatecolmergety); + function getrowstaterowheight(const index: integer): rowstaterowheightty; + procedure setrowstaterowheight(const index: integer; + const Value: rowstaterowheightty); + function getfoldinfoar: bytearty; + function getcolor(const index: integer): rowstatenumty; + procedure setcolor(const index: integer; const avalue: rowstatenumty); + function getfont(const index: integer): rowstatenumty; + procedure setfont(const index: integer; const avalue: rowstatenumty); + function getreadonly(const index: integer): boolean; + procedure setreadonly(const index: integer; const avalue: boolean); + function getflag1(const index: integer): boolean; + procedure setflag1(const index: integer; const avalue: boolean); + function getselected(const index: integer): longword; + procedure setselected(const index: integer; const avalue: longword); + function getmerged(const index: integer): longword; + procedure setmerged(const index: integer; const avalue: longword); + function getlinecolor(const index: integer): rowstatenumty; + procedure setlinecolor(const index: integer; const avalue: rowstatenumty); + function getlinecolorfix(const index: integer): rowstatenumty; + procedure setlinecolorfix(const index: integer; const avalue: rowstatenumty); + function getcolorar: integerarty; + procedure setcolorar(const avalue: integerarty); + function getfontar: integerarty; + procedure setfontar(const avalue: integerarty); + function getfoldlevelar: integerarty; + procedure setfoldlevelar(const avalue: integerarty); + procedure setfoldlevel(const index: integer; const avalue: byte); + function gethiddenar: longboolarty; + procedure sethiddenar(const avalue: longboolarty); + function getfoldissumar: longboolarty; + procedure setfoldissumar(const avalue: longboolarty); + protected + finfolevel: rowinfolevelty; + procedure sethidden(const index: integer; const avalue: boolean); virtual; + procedure setfoldissum(const index: integer; const avalue: boolean); virtual; + procedure checkdirty(const arow: integer); virtual; + function gethidden(const index: integer): boolean; + function getfoldlevel(const index: integer): byte; + function getfoldissum(const index: integer): boolean; + function getheight(const index: integer): integer; + function getlinewidth(const index: integer): rowlinewidthty; + procedure checkinfolevel(const wantedlevel: rowinfolevelty); + procedure initdirty; virtual; + procedure recalchidden; virtual; + function checkassigncompatibility(const source: tpersistent): boolean; override; + procedure readstate(const reader; const acount: integer; + const name: msestring); override; + property flag1[const index: integer]: boolean read getflag1 + write setflag1; + public + constructor create; overload; override; + constructor create(const ainfolevel: rowinfolevelty); reintroduce; overload; + function checkwritedata(const filer: tfiler): boolean; override; + procedure change(const aindex: integer); override; + procedure assign(source: tpersistent); override; + property infolevel: rowinfolevelty read finfolevel; + class function datatype: listdatatypety; override; + function datapocolmerge: pointer; + function dataporowheight: pointer; + function getitempo(const index: integer): prowstatety; + function getitempocolmerge(const index: integer): prowstatecolmergety; + function getitemporowheight(const index: integer): prowstaterowheightty; + property items[const index: integer]: rowstatety read getrowstate + write setrowstate; default; + property itemscolmerge[const index: integer]: rowstatecolmergety + read getrowstatecolmerge write setrowstatecolmerge; + property itemsrowheight[const index: integer]: rowstaterowheightty + read getrowstaterowheight write setrowstaterowheight; + + function mergecols(const arow: integer; const astart: longword; + const acount: longword): boolean; + function unmergecols(const arow: integer): boolean; + + property color[const index: integer]: rowstatenumty read getcolor + write setcolor; + property colorar: integerarty read getcolorar write setcolorar; + property font[const index: integer]: rowstatenumty read getfont + write setfont; + property fontar: integerarty read getfontar write setfontar; + property readonly[const index: integer]: boolean read getreadonly + write setreadonly; + property selected[const index: integer]: longword read getselected + write setselected; + property hidden[const index: integer]: boolean read gethidden write sethidden; + property hiddenar: longboolarty read gethiddenar write sethiddenar; + property foldlevel[const index: integer]: byte read getfoldlevel + write setfoldlevel; //0..64 + property foldlevelar: integerarty read getfoldlevelar write setfoldlevelar; + property foldissum[const index: integer]: boolean read getfoldissum + write setfoldissum; + property foldissumar: longboolarty read getfoldissumar write setfoldissumar; + + property height[const index: integer]: integer read getheight; + property merged[const index: integer]: longword read getmerged + write setmerged; + property linewidth[const index: integer]: rowlinewidthty + read getlinewidth{ write setlineheight}; + property linecolorfix[const index: integer]: rowstatenumty + read getlinecolorfix write setlinecolorfix; + property linecolor[const index: integer]: rowstatenumty + read getlinecolor write setlinecolor; + property foldinfoar: bytearty read getfoldinfoar; + end; + + createobjecteventty = procedure(const sender: tobject; var obj: tobject) of object; + + tobjectdatalist = class(tdynamicpointerdatalist) + private + foncreateobject: createobjecteventty; + function Getitems(index: integer): tobject; + procedure setitems(index: integer; const Value: tobject); + protected + fitemclass: tclass; + function checkassigncompatibility( + const source: tpersistent): boolean; override; + procedure checkitemclass(const aitem: tobject); + procedure freedata(var data); override; +// procedure copyinstance(var data); override; + procedure initinstance(var data); override; + procedure docreateobject(var instance: tobject); virtual; + public + constructor create; overload; override; + function add(const aitem: tobject): integer; + function extract(const index: integer): tobject; //no finalize + property oncreateobject: createobjecteventty read foncreateobject write foncreateobject; + property items[index: integer]: tobject read Getitems write setitems; default; + end; + + datalistclassty = class of tdatalist; + +// +// array util functions moved to lib/kernel/msearrayutils.pas +// +type + getintegeritemfuncty = function(const index: integer): integer of object; + +function datalisttocomplexar(const re,im: trealdatalist): complexarty; + +function newidentnum(const count: integer; + getfunc: getintegeritemfuncty): integer; + //returns lowest not used value +function getdatalistclass(const adatatype: listdatatypety): datalistclassty; +procedure registerdatalistclass(const adatatype: listdatatypety; + const aclass: datalistclassty); + +procedure setremotedatalist(const aintf: idatalistclient; + const source: tdatalist; var dest: tdatalist); + +implementation +uses + rtlconsts,msestreaming,msesys,msestat,msebits,msefloattostr,mseformatstr; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +var + datalistclasses: array[listdatatypety] of datalistclassty = +//dl_none,dl_integer, dl_int64, dl_currency, + (nil,tintegerdatalist,tint64datalist,tcurrencydatalist, +//dl_real, dl_realint, dl_realsum + trealdatalist,trealintdatalist,nil, +//dl_datetime, + trealdatalist, +//dl_pointer, + tpointerdatalist, +//dl_ansistring, dl_msestring, dl_doublemsestring, + tansistringdatalist,tmsestringdatalist,tdoublemsestringdatalist, +//dl_msestringint + tmsestringintdatalist, +//dl_complex, dl_rowstate + tcomplexdatalist,tcustomrowstatelist, +//dl_custom + nil); + +procedure setremotedatalist(const aintf: idatalistclient; + const source: tdatalist; var dest: tdatalist); +begin + aintf.getobjectlinker.setlinkedvar(aintf,source,tlinkedpersistent(dest), + typeinfo(idatalistclient)); + if dest <> nil then begin + include(dest.fstate,dls_remote); + aintf.itemchanged(dest,-1); + end; +end; + +function getdatalistclass(const adatatype: listdatatypety): datalistclassty; +begin + if adatatype <= high(datalistclasses) then begin + result:= datalistclasses[adatatype]; + end + else begin + result:= nil; + end; +end; + +procedure registerdatalistclass(const adatatype: listdatatypety; + const aclass: datalistclassty); +begin + if adatatype > high(datalistclasses) then begin + raise exception.create('Invalid datalist class.'); + end; + datalistclasses[adatatype]:= aclass; +end; + +function datalisttocomplexar(const re,im: trealdatalist): complexarty; +var + int1: integer; + pre,pim: preal; + pres: pcomplexty; + intre,intim: integer; +begin + int1:= re.count; + if im.count < int1 then begin + int1:= im.count; + end; + setlength(result,int1); + pre:= re.datapo; + intre:= re.size; + pim:= im.datapo; + intim:= im.size; + pres:= pointer(result); + for int1:= high(result) downto 0 do begin + pres^.re:= pre^; + pres^.im:= pim^; + inc(pchar(pre),intre); + inc(pchar(pim),intim); + inc(pchar(pres),sizeof(complexty)); + end; +end; + +function newidentnum(const count: integer; getfunc: getintegeritemfuncty): integer; +var + list1: tintegerdatalist; + int1: integer; +begin + list1:= tintegerdatalist.create; + try + list1.count:= count; + for int1:= 0 to count - 1 do begin + list1[int1]:= getfunc(int1); + end; + list1.sort; + for int1:= 0 to count -1 do begin + if list1[int1] > int1 then begin + result:= int1; + exit; + end; + end; + result:= count; + finally + list1.Free; + end; +end; + +procedure variantsnotsupported; +begin + raise exception.create('Variants not supported'); +end; + +{ tdatalist } + +constructor tdatalist.create; +begin + fsize:= 1; + fmaxcount:= bigint; +// fsourcedirtystop:= maxint; +end; + +destructor tdatalist.destroy; +var + int1: integer; +begin + for int1:= 0 to high(flinkdest) do begin + flinkdest[int1].listdestroyed(self); + end; + flinkdest:= nil; + clearbuffer; + inherited; +end; + +procedure tdatalist.listdestroyed(const sender: tdatalist); +begin + removeitems(pointerarty(flinkdest),sender); +end; + +function tdatalist.sourceischanged(const asource: listlinkinfoty): boolean; +begin + with asource do begin + result:= (source <> nil) and (dirtystart >= dirtystop); + end; +end; + +function tdatalist.checksourcechange(var ainfo: listlinkinfoty; + const sender: tdatalist; const aindex: integer): boolean; +begin + with ainfo do begin + result:= (source = sender) and (sender <> nil); + if result then begin + if aindex < 0 then begin + dirtystart:= 0; + dirtystop:= sender.count-1; + end + else begin + if aindex < dirtystart then begin + dirtystart:= aindex; + end; + if aindex > ainfo.dirtystop then begin + dirtystop:= aindex; + end; + end; + end; + end; +end; + +procedure tdatalist.sourcechange(const sender: tdatalist; const aindex: integer); +begin + //dummy +// checksourcechange(flinksource,sender,index,fsourcedirtystart,fsourcedirtystop); +end; + +function tdatalist.islinked(const asource: tdatalist): boolean; +var + int1: integer; + po1: plistlinkinfoty; +begin + result:= asource = self; + if not result then begin + for int1:= 0 to getsourcecount - 1 do begin + po1:= getsourceinfo(int1); + if (po1 <> nil) and (po1^.source <> nil) then begin + result:= po1^.source.islinked(asource); + if result then begin + break; + end; + end; + end; + end; +end; + +function tdatalist.canlink(const asource: tdatalist; + const atag: integer): boolean; +begin + result:= (asource <> nil) and (asource.datatype in getlinkdatatypes(atag)) and + not asource.islinked(self); +end; + +function tdatalist.checksourcecopy(var ainfo: listlinkinfoty; + const copyproc: copyprocty): boolean; +var + int1: integer; + int2,int3: ptruint; + po1,po2: pchar; //delphi needs pchar for pointer arithmetic +begin + with ainfo do begin + result:= (source <> nil) and (dirtystop >= dirtystart); + if result then begin + if dirtystop >= source.count then begin + dirtystop:= source.count - 1; + end; + if dirtystop >= count then begin + dirtystop:= count - 1; + end; + int2:= source.size; + po1:= pchar(source.datapo) + int2 * dirtystart; + int3:= size; + po2:= pchar(datapo) + int3 * dirtystart; + for int1:= dirtystop - dirtystart downto 0 do begin + copyproc(po1,po2); + inc(po1,int2); + inc(po2,int3); + end; + dirtystart:= maxint; + dirtystop:= -1; + end; + end; +end; + +function tdatalist.checksourcecopy2(var ainfo: listlinkinfoty; + const source2: tdatalist; const copyproc: copy2procty): boolean; +var + int1: integer; + int2,int3,int4: ptruint; + po1,po2,po3: pchar; //delphi needs pchar for pointer arithmetic +begin + with ainfo do begin + result:= (source <> nil) and (source2 <> nil) and (dirtystop >= dirtystart); + if result then begin + if dirtystop >= source.count then begin + dirtystop:= source.count - 1; + end; + if dirtystop >= source2.count then begin + dirtystop:= source2.count - 1; + end; + if dirtystop >= count then begin + dirtystop:= count - 1; + end; + int2:= source.size; + po1:= pchar(source.datapo) + int2 * dirtystart; + int3:= source2.size; + po2:= pchar(source2.datapo) + int3 * dirtystart; + int4:= size; + po3:= pchar(datapo) + int4 * dirtystart; + for int1:= dirtystop - dirtystart downto 0 do begin + copyproc(po1,po2,po3); + inc(po1,int2); + inc(po2,int3); + inc(po3,int4); + end; + dirtystart:= maxint; + dirtystop:= -1; + end; + end; +end; + +{ +procedure tdatalist.linkdest(const dest: tdatalist); +begin + if dest.flinksource <> nil then begin + dest.flinksource.unlinkdest(dest); + end; + if dest.canlink(self) then begin + dest.flinksource:= self; + additem(pointerarty(flinkdest),dest); + dest.sourcechange(self,-1); + end; +end; + +procedure tdatalist.unlinkdest(const dest: tdatalist); +begin + removeitems(pointerarty(flinkdest),dest); + dest.flinksource:= nil; +end; +} + +procedure tdatalist.unlinksource(var alink: listlinkinfoty); +begin + if alink.source <> nil then begin + removeitem(pointerarty(alink.source.flinkdest),self); + alink.source:= nil; + end; +end; + +function tdatalist.internallinksource(const source: tdatalist; + const atag: integer; var variable: tdatalist): boolean; +begin + if variable <> nil then begin + removeitem(pointerarty(variable.flinkdest),self); + end; + result:= (source <> nil) and canlink(source,atag); + if result then begin + variable:= source; + additem(pointerarty(source.flinkdest),self); + sourcechange(source,-1); + end; +end; + +procedure tdatalist.linksource(const source: tdatalist; const atag: integer); +begin + //dummy +end; + +procedure tdatalist.clearbuffer; +begin + internalfreedata(0,fcount); + if fdatapo <> nil then begin + freemem(fdatapo); + end; + fdatapo:= nil; + fbytelength:= 0; + fcapacity:= 0; + fcount:= 0; + fringpointer:= 0; +end; + +function tdatalist.sort(const comparefunc: sortcomparemethodty; + out arangelist: integerarty; const dorearange: boolean): boolean; +var + int1: integer; +begin + result:= false; + if fcount > 0 then begin + mergesort(pointer(datapo),fsize,fcount,comparefunc,arangelist); + for int1:= high(arangelist) downto 0 do begin + if arangelist[int1] <> int1 then begin + result:= true; + break; + end; + end; + if result and dorearange then begin + include(fstate,dls_sortio); + rearange(arangelist); + end; + end + else begin + include(fstate,dls_sortio); + end; +end; + +(* +function tdatalist.sort(const compareproc: compareprocty; + const arangelist: tintegerdatalist; dorearange: boolean): boolean; + //true wenn bewegt, refrow erhaelt neue indexpos + + procedure QuickSort(var arangelist: integeraty; L, R: Integer); + var + I, J: Integer; + P, T: integer; + int1: integer; + pp: pointer; + begin + if r >= l then begin + repeat + I := L; + J := R; + P := arangelist[(L + R) shr 1]; + pp:= fdatapo+p*fsize; + repeat + repeat + int1:= 0; + compareproc((fdatapo+arangeList[I]*fsize)^, pp^,int1); + if int1 = 0 then begin + int1:= arangelist[i] - p; + end; + if int1 >= 0 then break; + inc(i); + until false; + repeat + int1:= 0; + compareproc((fdatapo+arangeList[J]*fsize)^, pp^,int1); + if int1 = 0 then begin + int1:= arangelist[j] - p; + end; + if int1 <= 0 then break; + dec(j); + until false; + if I <= J then + begin + if i <> j then begin + result:= true; + T := arangeList[I]; + arangeList[I] := arangeList[J]; + arangeList[J] := T; + end; + Inc(I); + Dec(J); + end; + until I > J; + if L < J then QuickSort(arangelist,L, J); + L := I; + until I >= R; + end; + end; + +begin + arangelist.count:= fcount; + result:= false; + if fcount > 0 then begin + arangelist.number(0,1); + quicksort(pintegeraty(arangelist.datapo)^,0,arangelist.count-1); + if result and dorearange then begin + include(fstate,dls_sortio); + rearange(arangelist); + end; + end + else begin + include(fstate,dls_sortio); + end; +end; +*) + +function tdatalist.sort(out arangelist: integerarty; + const dorearange: boolean): boolean; +begin + result:= sort({$ifdef FPC}@{$endif}compare,arangelist,dorearange); +end; + +function tdatalist.sortcaseinsensitive(out arangelist: integerarty; + const dorearange: boolean): boolean; +begin + result:= sort({$ifdef FPC}@{$endif}comparecaseinsensitive, + arangelist,dorearange); +end; + +function tdatalist.sort(const compareproc: sortcomparemethodty): boolean; +var + ar1: integerarty; +begin + result:= sort(compareproc,ar1,true); +end; + +function tdatalist.sort: boolean; +begin + result:= sort({$ifdef FPC}@{$endif}compare); +end; + +function tdatalist.sortcaseinsensitive: boolean; +begin + result:= sort({$ifdef FPC}@{$endif}comparecaseinsensitive); +end; + +procedure tdatalist.checkindexrange(const aindex: integer; + const acount: integer = 1); +begin + if (aindex < 0) or (aindex >= fcount) then begin + tlist.error(slistindexerror, aindex); + end; + if (aindex+acount > fcount) then begin + tlist.error(slistindexerror, aindex); + end; +end; + +procedure tdatalist.checkindex(var index: integer); +begin + if (Index < 0) or (Index >= FCount) then begin + tlist.Error(SListIndexError, Index); + end; + index:= index + fringpointer; + if index >= fmaxcount then begin + index:= index - fmaxcount; + end; +end; + +procedure tdatalist.checkindex1(const index: integer); +begin + if (Index < 0) or (Index >= FCount) then begin + tlist.Error(SListIndexError, Index); + end; +end; + +function tdatalist.internaladddata(const quelle; docopy: boolean): integer; +var + int1: integer; + po1: pointer; +begin + beginupdate; + try + internalsetcount(fcount + 1,true); + int1:= fcount - 1 + fringpointer; + if int1 >= fmaxcount then begin + dec(int1,fmaxcount); + end; + po1:= fdatapo + int1*fsize; + move(quelle,po1^,fsize); + if docopy and (dls_needscopy in fstate) then begin + beforecopy(po1^); + aftercopy(po1^); + end; + finally + endupdate; + end; + result:= fcount-1; +end; + +function tdatalist.adddata(const quelle): integer; +begin + result:= internaladddata(quelle,true); +end; + +procedure tdatalist.internaldeletedata(index: integer; dofree: boolean); +var + int1: integer; +begin + checkindex(index); + if dofree then begin + internalcleardata(index); + end; + int1:= (index+1)*fsize; + if fringpointer = 0 then begin + move((fdatapo+int1)^,(fdatapo+int1-fsize)^,fcount*fsize-int1); + end + else begin + if index < fringpointer then begin //im unteren bereich + move((fdatapo+int1)^,(fdatapo+int1-fsize)^, + (fcount+fringpointer-fmaxcount)*fsize-int1); + end + else begin //im oberen bereich + move((fdatapo+int1)^,(fdatapo+int1-fsize)^,fmaxcount*fsize-int1); //start + move(fdatapo^,(fdatapo+(fmaxcount-1)*fsize)^,fsize); //ueberlauf + move((fdatapo+fsize)^,fdatapo^,(fcount+fringpointer-fmaxcount-1)*fsize); + //rest + end; + end; + fcount:= fcount-1; + datadeleted(index,1); + change(-1); +end; + +procedure tdatalist.deletedata(const index: integer); +begin + internaldeletedata(index,true); +end; + +procedure tdatalist.deleteitems(index,acount: integer); +begin + if index + acount > fcount then begin + acount:= fcount - index; + end; + if acount > 0 then begin + inc(fdeleting); + try + internalfreedata(index,acount); + blockcopymovedata(index+acount,index,fcount-index-acount,bcm_none); + fcount:= fcount-acount; + checkcapacity; + datadeleted(index,acount); + change(-1); + finally + dec(fdeleting); + end; + end; +end; + +procedure tdatalist.clear; +begin +// beginupdate; + inc(fdeleting); + try + clearbuffer; + change(-1); + finally + dec(fdeleting); +// endupdate; + end; +end; + +procedure tdatalist.insertitems(index,acount: integer); +var + countbefore: integer; +begin + if acount > 0 then begin + countbefore:= fcount; + internalsetcount(fcount + acount,true); + dec(index,acount+countbefore-fcount); //adjust for maxcount + blockcopymovedata(index,index+acount,fcount-index-acount,bcm_none); + initdata1(false,index,acount); + datainserted(index,acount); + change(-1); + end; +end; + +function tdatalist.checkassigncompatibility(const source: tpersistent): boolean; +begin + result:= false; +end; + +function tdatalist.assigndata(const source: tpersistent): boolean; +begin + if source = self then begin + result:= true; + exit; + end; + result:= checkassigncompatibility(source); +// result:= (datatype < dl_custom) and (source is tdatalist) and +// (tdatalist(source).datatype = datatype) or +// source.inheritsfrom(classtype) or +// inheritsfrom(source.classtype); + if result then begin + tdatalist(source).assigntodata(self); + end; +end; + +procedure tdatalist.assigntodata(const dest: tdatalist); +var + int1: integer; + po1,po2: pointer; + s0,s1,s2: integer; +begin + with dest do begin + newbuffer(self.count,true,size < self.size); + if size = self.size then begin + move(self.datapo^,fdatapo^,fcount*fsize); + end + else begin + po1:= self.datapo; + po2:= fdatapo; + s1:= self.size; + s2:= size; + s0:= s1; + if s0 > s2 then begin + s0:= s2; + end; + for int1:= 0 to fcount-1 do begin + move(po1^,po2^,s0); + inc(pchar(po1),s1); + inc(pchar(po2),s2); + end; + end; + internalcopyinstance(0,fcount); + change(-1); + end; +end; + +procedure tdatalist.internalgetasarray(const adatapo: pointer; + const asize: integer); +var + int1: integer; + po1,po2: pointer; + s1,s2: integer; +begin + if fcount > 0 then begin + normalizering; + if asize < size then begin + po1:= fdatapo; + po2:= adatapo; + s1:= size; + s2:= asize; + for int1:= 0 to count - 1 do begin + move(po1^,po2^,s2); + inc(pchar(po1),s1); + inc(pchar(po2),s2); + end; + end + else begin + move(fdatapo^,adatapo^,fcount*fsize); + end; + if dls_needscopy in fstate then begin + po1:= adatapo; + s1:= asize; + for int1:= 0 to fcount - 1 do begin + beforecopy(po1^); + aftercopy(po1^); + inc(pchar(po1),s1); + end; + end; + end; +end; + +procedure tdatalist.internalsetasarray(const source: pointer; + const asize: integer; const acount: integer); +var + int1: integer; + po1,po2: pointer; + s1,s2,s3: integer; +begin + newbuffer(acount,true,size > asize); + if fcount > 0 then begin + if size <> asize then begin + po1:= fdatapo; + po2:= source; + s1:= size; + s2:= asize; + s3:= size; + if s3 > asize then begin + s3:= asize; + end; + for int1:= 0 to fcount - 1 do begin + move(po2^,po1^,s3); + inc(pchar(po1),s1); + inc(pchar(po2),s2); + end; + end + else begin + move(source^,fdatapo^,fcount*fsize); + end; + internalcopyinstance(0,fcount); + end; + change(-1); +end; + +function tdatalist.getdatablock(const source: pointer; const destsize: integer): integer; + //returns size of datablock +begin + internalgetasarray(source,destsize); + result:= count * destsize; +end; + +function tdatalist.setdatablock(const dest: pointer; const sourcesize: integer; + const acount: integer): integer; + //returns size of datablock +begin + internalsetasarray(dest,sourcesize,acount); + result:= acount * sourcesize; +end; + +procedure tdatalist.internalgetdata(index: integer; out ziel); +begin + checkindex(index); + move((fdatapo+index*fsize)^,ziel,fsize); +end; + +procedure tdatalist.getdata(index: integer; var dest); +var + po1: pointer; +begin + checkindex(index); + po1:= fdatapo+index*fsize; + if dls_needscopy in fstate then begin + beforecopy(po1^); + end; + if dls_needsfree in fstate then begin + freedata(dest); + end; + move(po1^,dest,fsize); + if dls_needscopy in fstate then begin + aftercopy(dest); + end; +end; + +procedure tdatalist.getgriddata(index: integer; var dest); +begin + getdata(index,dest); +end; + +procedure tdatalist.internalsetdata(index: integer; const quelle); +var + po1: pointer; + int1: integer; +begin + int1:= index; + checkindex(index); + if dls_needscopy in fstate then begin + beforecopy((@quelle)^); + end; + po1:= fdatapo+index*fsize; + if dls_needsfree in fstate then begin + freedata(po1^); + end; + move(quelle,po1^,fsize); + if dls_needscopy in fstate then begin + aftercopy(po1^); + end; + change(int1); +end; + +procedure tdatalist.setdata(index: integer; const source); +begin + internalsetdata(index,source); +end; + +procedure tdatalist.setgriddata(index: integer; const source); +begin + internalsetdata(index,source); +end; + +function tdatalist.getstatdata(const index: integer): msestring; +begin + result:= ''; //dummy +end; + +procedure tdatalist.setstatdata(const index: integer; const value: msestring); +begin + //dummy +end; + +procedure tdatalist.writestate(const writer; const name: msestring); +var + int1: integer; +begin + with tstatwriter(writer) do begin + writeinteger(name,fcount); + for int1:= 0 to count - 1 do begin + writelistitem(getstatdata(int1)); + end; + end; +end; + +procedure tdatalist.readstate(const reader; const acount: integer; + const name: msestring); +var + int1: integer; + str1: msestring; +begin + with tstatreader(reader) do begin + try + beginupdate; + count:= acount; + for int1:= 0 to acount - 1 do begin + str1:= readlistitem; + setstatdata(int1,str1); + end; + finally + endupdate; + end; + end; +end; + +procedure tdatalist.writeappendix(const writer; const aname: msestring); +begin + //dummy +end; + +procedure tdatalist.readappendix(const reader; const aname: msestring); +begin + //dummy +end; + +function tdatalist.popbottomdata(var ziel): boolean; +begin + result:= fcount > 0; + if result then begin + checkbuffersize(0); + if @ziel <> nil then begin + getdata(0,ziel); + end; + cleardata(0); + inc(fringpointer); + if fringpointer >= fmaxcount then begin + dec(fringpointer,fmaxcount); + end; + dec(fcount); + end; +end; + +function tdatalist.poptopdata(var ziel): boolean; +begin + result:= fcount > 0; + if result then begin + if @ziel <> nil then begin + getdata(fcount-1,ziel); + end; + count:= fcount-1; + end; +end; + +procedure tdatalist.pushdata(const quelle); +begin + checkbuffersize(1); + adddata(quelle); +end; + +procedure tdatalist.internalinsertdata(index: integer; const quelle; + const docopy: boolean); +var + po1: pchar; +begin + if index = fcount then begin + internaladddata(quelle,docopy); + end + else begin + beginupdate; + try + checkindex(index); + internalsetcount(fcount+1,true); + po1:= fdatapo+index*fsize; + move(po1^,(po1+fsize)^,(fcount-index-1)*fsize); + if @quelle = nil then begin + initdata1(false,index,1); + end + else begin + move(quelle,po1^,fsize); + if (dls_needscopy in fstate) and docopy then begin + beforecopy(po1^); + aftercopy(po1^); + end; + end; + finally + endupdate; + end; + end; +end; + +procedure tdatalist.insertdata(const index: integer; const quelle); +begin + internalinsertdata(index,quelle,true); +end; + +procedure tdatalist.Setcapacity(Value: integer); +begin + if value < fcount then begin + value:= fcount; + end; + if value < fmaxcount then begin + normalizering; + end; + fbytelength:= value*fsize; + reallocmem(fdatapo,fbytelength); + fcapacity:= value; +end; + +procedure tdatalist.initdata1(const afree: boolean; index: integer; + const acount: integer); + //initialisiert mit defaultwert +var + int1,int2: integer; + default,po,po1: pchar; +begin + if acount <= 0 then begin + exit; + end; + if afree then begin + internalfreedata(index,acount); + end; + int1:= index+acount-1; + checkindex(index); + checkindex(int1); + default:= getdefault; + if default = nil then begin + if int1 >= index then begin + fillchar((fdatapo+index*fsize)^,acount*fsize,0); + if dls_needsinit in fstate then begin + for int2:= index to index + acount - 1 do begin + initinstance((fdatapo+int2*fsize)^); + end; + end; + end + else begin + fillchar((fdatapo)^,int1*fsize,0); + fillchar((fdatapo+index*fsize)^,(fmaxcount-index)*fsize,0); + if dls_needsinit in fstate then begin + for int2:= 0 to int1 - 1 do begin + initinstance((fdatapo+int2*fsize)^); + end; + for int2:= index to fmaxcount-index - 1 do begin + initinstance((fdatapo+int2*fsize)^); + end; + end; + end; + end + else begin + po:= fdatapo; + inc(po,index*fsize); + if int1 >= index then begin //one piece + for int1:= 0 to acount-1 do begin + move(default^,po^,fsize); + inc(po,fsize); + end; + if dls_needscopy in fstate then begin + for int2:= index to index + acount - 1 do begin + po1:= fdatapo+int2*fsize; + beforecopy(po1^); + aftercopy(po1^); + end; + end; + end + else begin + for int1:= 0 to fmaxcount - acount - 1 do begin + move(default^,po^,fsize); + inc(po,fsize); + end; + po:= fdatapo; + for int2:= 0 to int1 do begin + move(default^,po^,fsize); + inc(po,fsize); + end; + if dls_needscopy in fstate then begin + for int2:= 0 to int1 - 1 do begin + po1:= fdatapo+int2*fsize; + beforecopy(po1^); + aftercopy(po1^); + end; + for int2:= index to fmaxcount-index - 1 do begin + po1:= fdatapo+int2*fsize; + beforecopy(po1^); + aftercopy(po1^); + end; + end; + end; + end; +end; + +procedure tdatalist.getdefaultdata(var dest); +var + po: pointer; +begin + po:= getdefault; + if po = nil then begin + fillchar(dest,fsize,0); + end + else begin + if dls_needscopy in fstate then begin + beforecopy(po^); + end; + if dls_needsfree in fstate then begin + freedata(dest); + end; + move(po^,dest,fsize); + if dls_needscopy in fstate then begin + aftercopy(dest); + end; + end; +end; + +procedure tdatalist.getgriddefaultdata(var dest); +begin + getdefaultdata(dest); +end; + +procedure tdatalist.internalcleardata(const index: integer); +var + default,po1: pointer; +begin + po1:= fdatapo+index*fsize; + if dls_needsfree in fstate then begin + freedata(po1^); + end; + default:= getdefault; + if default <> nil then begin + move(default^,po1^,fsize); + end + else begin + fillchar(po1^,fsize,0); + end; +end; + +procedure tdatalist.cleardata(index: integer); +begin + checkindex(index); + internalcleardata(index); +end; + + +function tdatalist.deleting: boolean; +begin + result:= fdeleting > 0; +end; + +procedure tdatalist.checkcapacity; +var + int1: integer; +begin +// int1:= ((fcount*12) div 10) + 5; + int1:= fcount*2 + 32; + if fcapacity > int1 then begin + capacity:= fcount; + end; +end; + +procedure tdatalist.internalsetcount(value: integer; nochangeandinit: boolean); +var + int1: integer; + countvorher: integer; +begin + if value < 0 then begin + tlist.Error(SListCountError, value); + end; + + countvorher:= fcount; + if value > fmaxcount then begin + int1:= value-fmaxcount; //last item to init + if int1 > fcount then begin + int1:= fcount; + end; + fscrolled:= fscrolled+int1; + value:= fmaxcount; + if value > fcapacity then begin + capacity:= value; + end; + fcount:= value; + if not nochangeandinit then begin + initdata1(true,0,int1); //free lost oldbuffer + initdata1(false,countvorher,value-countvorher); //init newbuffer + end + else begin + internalfreedata(0,int1); + end; + fringpointer:= fringpointer + int1; + if fringpointer >= fmaxcount then begin + fringpointer:= fringpointer - fmaxcount; + end; + if not nochangeandinit then begin + change(-1); + end; + end + else begin + if value > fcapacity then begin + capacity:= value*2 + 32; +// capacity:= ((value*12) div 10) + 5; //in 20% schritten + end; + if value > countvorher then begin + Fcount:= Value; + // fillchar(datapoty(fdatapo)^[countvorher*fsize],(value-countvorher)*fsize,0); + if not nochangeandinit then begin + initdata1(false,countvorher,value-countvorher); //mit defaultdaten fuellen + end; + end + else begin + if value < countvorher then begin + internalfreedata(value,countvorher-value); + Fcount := Value; + checkcapacity; + end; + end; + if countvorher > value then begin + datadeleted(count,countvorher-count); + end; + if not nochangeandinit and (countvorher <> value) then begin + change(-2); + end; + end; +end; + +procedure tdatalist.newbuffer(const acount: integer; const noinit: boolean; + const fillnull: boolean); +begin + clearbuffer; + fcount:= acount; + if fcount > fmaxcount then begin + fcount:= fmaxcount; + end; + setcapacity(fcount); + if not noinit then begin + initdata1(false,0,fcount); + end + else begin + fillchar(fdatapo^,fcount*fsize,0); + end; +end; + +procedure tdatalist.Setcount(const Value: integer); +begin + internalsetcount(value,false); +end; + +procedure tdatalist.checkbuffersize(increment: integer); +var + int1: integer; +begin + increment:= fcount + increment; + int1:= 2*increment; + if increment > fmaxcount then begin + maxcount:= int1; + end + else begin + if fmaxcount > int1 + increment + 40 then begin + maxcount:= int1; + end + end; + if fcapacity < fmaxcount then begin + capacity:= fmaxcount; + end; +end; + +procedure tdatalist.internalfill(const anzahl: integer; const wert); + //initialisiert mit wert +var + int1: integer; + po1: pchar; +begin + beginupdate; + try + count:= anzahl; + normalizering; + po1:= fdatapo; + if (@wert <> nil) and (dls_needscopy in fstate) then begin + for int1:= 0 to fcount - 1 do begin + beforecopy((@wert)^); + end; + end; + if dls_needsfree in fstate then begin + for int1:= 0 to fcount - 1 do begin + freedata(po1^); + inc(po1,fsize); + end; + end; + if @wert = nil then begin + fillchar(fdatapo^,anzahl*fsize,0); + end + else begin + po1:= fdatapo; + if dls_needscopy in fstate then begin + for int1:= 0 to fcount - 1 do begin + move(wert,po1^,fsize); + aftercopy(po1^); + inc(po1,fsize); + end; + end + else begin + for int1:= 0 to fcount - 1 do begin + move(wert,po1^,fsize); + inc(po1,fsize); + end; + end; + end; + finally + endupdate; + end; +end; + +procedure tdatalist.movedata(const fromindex, toindex: integer); +var + po1: pointer; +begin + if fromindex <> toindex then begin + normalizering; + checkindex1(toindex); + beginupdate; + getmem(po1,fsize); + try + internalgetdata(fromindex,po1^); + if fromindex > toindex then begin + move((fdatapo+toindex*fsize)^,(fdatapo+toindex*fsize+fsize)^, + (fromindex-toindex)*fsize); + end + else begin + move((fdatapo+fromindex*fsize+fsize)^,(fdatapo+fromindex*fsize)^, + (toindex-fromindex)*fsize); + end; + move(po1^,(fdatapo+toindex*fsize)^,fsize); +// internaldeletedata(fromindex,false); +// internalinsertdata(toindex,po1^,false); + datamoved(fromindex,toindex,1); + finally + freemem(po1); + endupdate; + end; + end; +// change(-1); +end; + +procedure tdatalist.blockcopymovedata(fromindex, toindex: integer; + const acount: integer; const mode: blockcopymodety); +var + ueberlappung,freestart,freecount,initstart: integer; + int1,int2: integer; +begin + if (acount > 0) and (fromindex <> toindex) then begin + normalizering; + checkindex(fromindex); + checkindex(toindex); + int1:= fromindex+acount-1; + checkindex(int1); +// if (mode <> bcm_rotate) then begin + int2:= toindex+acount-1; + checkindex(int2); +// end; + if fromindex > toindex then begin + ueberlappung:= toindex+acount-fromindex; + if ueberlappung < 0 then begin + ueberlappung:= 0; + end; + freestart:= toindex; + initstart:= fromindex + ueberlappung; + end + else begin + ueberlappung:= fromindex+acount-toindex; + if ueberlappung < 0 then begin + ueberlappung:= 0; + end; + freestart:= toindex+ueberlappung; + initstart:= fromindex; + end; + freecount:= acount-ueberlappung; + if mode = bcm_rotate then begin + if toindex < fromindex then begin + internalsetcount(fcount + freecount,true); + move((fdatapo+toindex*fsize)^, + (fdatapo+(fcount-freecount)*fsize)^,freecount*fsize); + move((fdatapo+fromindex*fsize)^, + (fdatapo+toindex*fsize)^,acount*fsize); + if ueberlappung = 0 then begin + move((fdatapo+(toindex+acount)*fsize)^, + (fdatapo+(toindex+acount+acount)*fsize)^, + (fromindex-toindex-acount)*fsize); + end; + move((fdatapo+(fcount-freecount)*fsize)^, + (fdatapo+(toindex+acount)*fsize)^, + freecount*fsize); + end + else begin + if ueberlappung = 0 then begin + internalsetcount(fcount + freecount,true); + move((fdatapo+fromindex*fsize)^, + (fdatapo+(fcount-freecount)*fsize)^,freecount*fsize); + move((fdatapo+(fromindex+freecount)*fsize)^, + (fdatapo+fromindex*fsize)^,(toindex-fromindex{-acount+1})*fsize); + move((fdatapo+(fcount-freecount)*fsize)^, + (fdatapo+(toindex{-freecount+1})*fsize)^, + freecount*fsize); + end + else begin + if toindex + acount > fcount then begin + toindex:= fcount-acount; + end; + freecount:= toindex-fromindex; + internalsetcount(fcount + freecount,true); + move((fdatapo+(fromindex+acount)*fsize)^, + (fdatapo+(fcount-freecount)*fsize)^,freecount*fsize); + move((fdatapo+(fromindex)*fsize)^, + (fdatapo+toindex*fsize)^,acount*fsize); + move((fdatapo+(fcount-freecount)*fsize)^, + (fdatapo+fromindex*fsize)^, + freecount*fsize); + end; + end; + fcount:= fcount-freecount; //no free + checkcapacity; + end + else begin + if mode <> bcm_none then begin + internalfreedata(freestart,freecount); + end; + move((fdatapo+fromindex*fsize)^, + (fdatapo+toindex*fsize)^,acount*fsize); + if mode = bcm_copy then begin + internalcopyinstance(initstart,freecount); + end + else begin + if mode = bcm_init then begin + initdata1(false,initstart,freecount); + end + end; + end; + end; +end; + +procedure tdatalist.blockmovedata(const fromindex, toindex, count: integer); +begin + if fromindex <> toindex then begin + if count = 1 then begin + movedata(fromindex,toindex); + end + else begin + blockcopymovedata(fromindex,toindex,count,bcm_rotate); + datamoved(fromindex,toindex,count); + change(-1); + end; + end; +end; + +procedure tdatalist.blockcopydata(const fromindex, toindex, count: integer); +begin + blockcopymovedata(fromindex,toindex,count,bcm_copy); + change(-1); +end; + +procedure tdatalist.readdata(reader: treader); +begin + beginupdate; + try + clear; + reader.readlistbegin; + while not reader.EndOfList do begin + internalsetcount(fcount + 1,false); + readitem(reader,(fdatapo+(fcount-1)*fsize)^); + end; + reader.ReadListEnd; + finally + endupdate; + end; +end; + +procedure tdatalist.writedata(writer: twriter); +var + int1: integer; + po1: pchar; +begin + writer.WriteListBegin; + normalizering; + po1:= fdatapo; + for int1:= 0 to count-1 do begin + writeitem(writer,po1^); + inc(po1,fsize); + end; + writer.writelistend; +end; + +procedure tdatalist.readitem(const reader: treader; var value); +begin + //dummy +end; + +procedure tdatalist.writeitem(const writer: twriter; var value); +begin + //dummy +end; + +function tdatalist.checkwritedata(const filer: tfiler): boolean; +var + int1,int2: integer; + po1: pointer; +begin + if filer.ancestor = nil then begin + result:= (fcount <> 0); + end + else begin + result:= tdatalist(filer.ancestor).fcount <> fcount; + if not result and (filer is twriter) then begin + datapo; //normalize ring + po1:= tdatalist(filer.ancestor).datapo; + for int1:= 0 to fcount-1 do begin + int2:= compare((fdatapo+int1*fsize)^,(pchar(po1)+int1*fsize)^); + if int2 <> 0 then begin + result:= true; + break; + end; + end; + end; + end; +end; + +procedure tdatalist.defineproperties(const propname: string; + const filer: tfiler); +begin + filer.defineproperty(propname, + {$ifdef FPC}@{$endif}readdata,{$ifdef FPC}@{$endif}writedata, + not (dls_nostreaming in fstate) and checkwritedata(filer)); +end; + +procedure tdatalist.defineproperties(filer: tfiler); +begin + inherited; + defineproperties('data',filer); +end; +procedure tdatalist.freedata(var data); +begin + //dummy +end; + +procedure tdatalist.internalfreedata(index, anzahl: integer); +begin + if dls_needsfree in fstate then begin + forall(index,anzahl,{$ifdef FPC}@{$endif}freedata); + end; +end; + +procedure tdatalist.beforecopy(var data); +begin + //dumy +end; + +procedure tdatalist.aftercopy(var data); +begin + //dumy +end; + +procedure tdatalist.initinstance(var data); +begin + //dummy +end; + +procedure tdatalist.internalcopyinstance(index, anzahl: integer); +begin + if dls_needscopy in fstate then begin + forall(index,anzahl,{$ifdef FPC}@{$endif}beforecopy); + forall(index,anzahl,{$ifdef FPC}@{$endif}aftercopy); + end; +end; + +procedure tdatalist.remoteitemchange(const alink: pointer); +begin + with idatalistclient(alink) do begin + itemchanged(self,fintparam); + end; +end; + +procedure tdatalist.doitemchange(const index: integer); +begin + if assigned(fonitemchange) then begin + fonitemchange(self,index); + end; + fintparam:= index; + if (dls_remote in fstate) and (fobjectlinker <> nil) then begin + fobjectlinker.forall({$ifdef FPC}@{$endif}remoteitemchange, + typeinfo(idatalistclient)); + end; +end; + +procedure tdatalist.dochange; +begin + if assigned(fonchange) then begin + fonchange(self); + end; +end; + +procedure tdatalist.change(const index: integer); +var + int1: integer; +begin + exclude(fstate,dls_sortio); + if fcount = 0 then begin + frearanged:= false; + end; + if fnochange = 0 then begin + doitemchange(index); + if sorted then begin + sort; + end; + dochange; + if flinkdest <> nil then begin + for int1:= 0 to high(flinkdest) do begin + flinkdest[int1].sourcechange(self,index); + end; + end; + end; +end; + +procedure tdatalist.beginupdate; +begin + inc(fnochange); +end; + +procedure tdatalist.endupdate; +begin + dec(fnochange); + if fnochange = 0 then begin + change(-1); + end; +end; + +procedure tdatalist.incupdate; +begin + inc(fnochange); +end; + +procedure tdatalist.decupdate; +begin + dec(fnochange); +end; +{ +procedure tdatalist.resetupdate; +begin + fnochange:= 0; +end; +} +function tdatalist.updating: boolean; +begin + result:= fnochange > 0; +end; + +procedure tdatalist.internalrearange(arangelist: pinteger; + const acount: integer); +var + datapo1: pchar; + int1: integer; +begin + frearanged:= true; + normalizering; + getmem(datapo1,fbytelength); + try + for int1:= 0 to acount -1 do begin + move((fdatapo+arangelist^*fsize)^,(datapo1+int1*fsize)^,fsize); + inc(arangelist); + end; + move((fdatapo+acount*fsize)^, + (datapo1+acount*fsize)^, + (fcount-acount)*fsize); //rest kopieren + finally + freemem(fdatapo); + fdatapo:= datapo1; + end; + change(-1); +end; + +procedure tdatalist.rearange(const arangelist: tintegerdatalist); +begin + internalrearange(arangelist.datapo,arangelist.count); +end; + +procedure tdatalist.rearange(const arangelist: integerarty); +begin + internalrearange(pointer(arangelist),length(arangelist)); +end; + +function tdatalist.empty(const index: integer): boolean; +var + int1: integer; + po1: pbyte; +begin + po1:= getitempo(index); + for int1:= 0 to fsize-1 do begin + if po1^ <> 0 then begin + result:= false; + exit; + end; + inc(po1); + end; + result:= true; +end; + +class function tdatalist.datatype: listdatatypety; +begin + result:= dl_custom; +end; + +function tdatalist.compare(const l,r): integer; +begin + result:= 0; +end; + +function tdatalist.comparecaseinsensitive(const l,r): integer; +begin + result:= compare(l,r); +end; + +procedure tdatalist.setmaxcount(const Value: integer); +begin + if fmaxcount <> value then begin + normalizering; + if fcount > value then begin + count:= value; + end; + fmaxcount := Value; + end; +end; + +function tdatalist.getdefault: pointer; +begin + result:= nil; +end; + +procedure tdatalist.normalizering; +var + po: pbyte; + int1,int2,int3: integer; +begin + if fringpointer <> 0 then begin + int1:= fringpointer*fsize; + int2:= fringpointer + fcount; + if int2 > fmaxcount then begin //2 pieces + int2:= (int2 - fmaxcount) * fsize; + getmem(po,int2); + move(fdatapo^,po^,int2); + int3:= fmaxcount * fsize-int1; + move((fdatapo+int1)^,fdatapo^,int3); + move(po^,(fdatapo+int3)^,int2); + freemem(po); + end + else begin + move((fdatapo+int1)^,fdatapo^,int1); + end; + fringpointer:= 0; + end; +end; + +procedure tdatalist.initdata(const index, anzahl: integer); +begin + initdata1(true,index,anzahl); +end; + +procedure tdatalist.forall(startindex: integer; const count: integer; + const proc: dataprocty); +var + int1: integer; + po1: pchar; +begin if count > 0 then begin + int1:= startindex+count-1; + checkindex(startindex); + checkindex(int1); + po1:= fdatapo; + if (fringpointer = 0) or (int1 >= startindex) then begin //ein stueck + inc(po1,startindex*fsize); + for int1:= startindex to int1 do begin + proc(po1^); + inc(po1,fsize); + end; + end + else begin + for int1:= 0 to int1 do begin + proc(po1^); + inc(po1,fsize); + end; + po1:= fdatapo; + inc(po1,startindex*fsize); + for int1:= startindex to fmaxcount-1 do begin + proc(po1^); + inc(po1,fsize); + end; + end; + end; +end; + +function tdatalist.getsorted: boolean; +begin + result:= dls_sorted in fstate; +end; + +procedure tdatalist.setsorted(const Value: boolean); +begin + if sorted <> value then begin + if value then begin + include(fstate,dls_sorted); + sort; + end + else begin + exclude(fstate,dls_sorted); + end; + end; +end; +{ +function tdatalist.Getasvarrec(index: integer): tvarrec; +begin + result.VType:= vtpointer; //dummy + result.VPointer:= nil; +end; + +procedure tdatalist.Setasvarrec(index: integer; const Value: tvarrec); +begin + //dummy +end; +} +{ +procedure tdatalist.invalidateline(index: integer); +begin + if assigned(foninvalidateline) then begin + foninvalidateline(self,index); + end; +end; +} + +procedure tdatalist.assignb(const source: tdatalist); +begin + source.assigntob(self); +end; + +procedure tdatalist.assigntob(const dest: tdatalist); +begin + raise exception.Create('Can not assigntob.'); +end; + +function tdatalist.datapo: pointer; +begin + normalizering; + result:= fdatapo; +end; + +function tdatalist.datahighpo: pointer; +begin + result:= nil; + if fcount > 0 then begin + result:= pchar(datapo) + (fcount-1)*fsize; + end; +end; + +function tdatalist.getitempo(index: integer): pointer; +begin + checkindex(index); + result:= fdatapo + index*fsize; +end; + +procedure tdatalist.assign(sender: tpersistent); +begin + if not assigndata(sender) then begin + inherited; + end; +end; + +procedure tdatalist.clean(const start,stop: integer); +begin + //dummy +end; + +function tdatalist.getsourcecount: integer; +begin + result:= 0; +end; + +function tdatalist.getsourceinfo(const atag: integer): plistlinkinfoty; +begin + result:= nil; +end; + +function tdatalist.getsourcename(const atag: integer): string; +var + po1: plistlinkinfoty; +begin + po1:= getsourceinfo(atag); + if po1 <> nil then begin + result:= po1^.name; + end + else begin + result:= ''; + end; +end; + +function tdatalist.getlinkdatatypes(const atag: integer): listdatatypesty; +begin + result:= [datatype]; +end; + +procedure tdatalist.initsource(var asource: listlinkinfoty); +begin + fillchar(asource,sizeof(asource),0); + with asource do begin + dirtystop:= maxint; + end; +end; + +procedure tdatalist.removesource(var asource: listlinkinfoty); +begin + with asource do begin + if source <> nil then begin + source.listdestroyed(self); + source:= nil; + end; + end; +end; + +procedure tdatalist.checklistdestroyed(var ainfo: listlinkinfoty; + const sender: tdatalist); +begin + if sender = ainfo.source then begin + ainfo.source:= nil; + end; +end; + +procedure tdatalist.clearmemberitem(const subitem: integer; + const index: integer); +begin + //dummy +end; + +procedure tdatalist.setmemberitem(const subitem: integer; + const index: integer; const avalue: integer); +begin + //dummy +end; + +procedure tdatalist.setcheckeditem(const avalue: integer); +begin + if (avalue < 0) or (avalue > fcount) then begin + fcheckeditem:= -1; + end + else begin + fcheckeditem:= avalue; + end; +end; + +function tdatalist.getfacultative: boolean; +begin + result:= dls_facultative in fstate; +end; + +procedure tdatalist.setfacultative(const avalue: boolean); +begin + if avalue then begin + fstate:= fstate+[dls_facultative,dls_propertystreaming]; + end + else begin + exclude(fstate,dls_facultative); + end; +end; + +procedure tdatalist.datadeleted(const aindex: integer; const acount: integer); +begin + if fcheckeditem >= 0 then begin + if fcheckeditem >= aindex then begin + if fcheckeditem < aindex + acount then begin + fcheckeditem:= -1; + end + else begin + fcheckeditem:= fcheckeditem - acount; + if fcheckeditem < 0 then begin + fcheckeditem:= -1; + end; + end; + end; + end; +end; + +procedure tdatalist.datainserted(const aindex: integer; const acount: integer); +begin + if (fcheckeditem >= 0) and (fcheckeditem >= aindex) then begin + fcheckeditem:= fcheckeditem + acount; + if fcheckeditem >= fcount then begin + fcheckeditem:= -1; + end; + end; +end; + +procedure tdatalist.datamoved(const fromindex: integer; const toindex: integer; + const acount: integer); +begin + if (fcheckeditem >= 0) and (fcheckeditem >= fromindex) and + (fcheckeditem < fromindex+acount) then begin + fcheckeditem:= fcheckeditem + toindex - fromindex; + if (fcheckeditem < 0) or (fcheckeditem >= fcount) then begin + fcheckeditem:= -1; + end; + end; +end; + +procedure tdatalist.linkclient(const aclient: idatalistclient); +begin + aclient.getobjectlinker.link(aclient,iobjectlink(self),nil, + typeinfo(idatalistclient)); + include(fstate,dls_remote); + aclient.itemchanged(self,-1); +end; + +procedure tdatalist.unlinkclient(const aclient: idatalistclient); +begin + aclient.getobjectlinker.unlink(aclient,iobjectlink(self),nil); +end; + +function tdatalist.getastext(const index: integer): msestring; +begin + result:= ''; +end; + +procedure tdatalist.setastext(const index: integer; const avalue: msestring); +begin + //dummy +end; + +procedure tdatalist.setitemselected(const row: integer; const value: boolean); +begin + //dummy +end; + +function tdatalist.getifidatatype(): listdatatypety; +begin + result:= datatype; +end; + +{ tintegerdatalist } + +constructor tintegerdatalist.create; +begin + inherited; + fsize:= sizeof(integer); + min:= minint; + max:= maxint; + fcheckeditem:= -1; +end; + +procedure tintegerdatalist.number(const start,step: integer); +var + int1,int2: integer; +begin + int2:= start; + beginupdate; + try + for int1:= 0 to count-1 do begin + internalsetdata(int1,int2); + int2:= int2 + step; + end; + finally + endupdate; + end; +end; + +function tintegerdatalist.add(const value: integer): integer; +begin + result:= adddata(value); +end; +{ +procedure tintegerdatalist.assign(source: tpersistent); +begin + if not assigndata(source) then begin + inherited; + end; +end; +} +function tintegerdatalist.Getitems(const index: integer): integer; +begin + internalgetdata(index,result); +end; + +procedure tintegerdatalist.insert(const index: integer; const item: integer); +begin + insertdata(index,item); +end; + +procedure tintegerdatalist.Setitems(const index: integer; const Value: integer); +begin + internalsetdata(index,value); +end; + +class function tintegerdatalist.datatype: listdatatypety; +begin + result:= dl_integer; +end; + +function tintegerdatalist.empty(const index: integer): boolean; +var + po1: pointer; +begin + po1:= getdefault; + if po1 = nil then begin + result:= pinteger(getitempo(index))^ = 0; + end + else begin + result:= pinteger(getitempo(index))^ = pinteger(po1)^; + end; +end; + +function tintegerdatalist.compare(const l,r): integer; +begin + result:= integer(l)-integer(r); +end; + +function tintegerdatalist.find(value: integer): integer; +var + int1: integer; +begin + result:= -1; + for int1:= 0 to fcount-1 do begin + if integer(pointer(fdatapo+int1*fsize)^) = value then begin + result:= int1; + break; + end; + end; +end; + +procedure tintegerdatalist.fill(acount: integer; const defaultvalue: integer); +begin + internalfill(count,defaultvalue); +end; + +function tintegerdatalist.getasarray: integerarty; +begin + setlength(result,fcount); + internalgetasarray(pointer(result),sizeof(integer)); +end; + +procedure tintegerdatalist.setasarray(const avalue: integerarty); +begin + internalsetasarray(pointer(avalue),sizeof(integer),length(avalue)); +end; + +function tintegerdatalist.getasbooleanarray: booleanarty; +var + po1: pinteger; + int1: integer; +begin + setlength(result,fcount); + po1:= datapo; + for int1:= 0 to high(result) do begin + result[int1]:= po1^ <> 0; + inc(pchar(po1),fsize); + end; +end; + +procedure tintegerdatalist.setasbooleanarray(const avalue: booleanarty); +var + int1: integer; + po1: plongbool; +begin + newbuffer(length(avalue),true,size > sizeof(integer)); + po1:= pointer(fdatapo); + for int1:= 0 to high(avalue) do begin + po1^:= avalue[int1]; + inc(pchar(po1),fsize); + end; + change(-1); +end; + +function tintegerdatalist.getstatdata(const index: integer): msestring; +begin + result:= inttostrmse(items[index]); +end; + +procedure tintegerdatalist.setstatdata(const index: integer; + const value: msestring); +var + int1: integer; +begin + int1:= strtoint(value); + if int1 < min then begin + int1:= min; + end + else begin + if int1 > max then begin + int1:= max; + end; + end; + setdata(index,int1); +end; + +procedure tintegerdatalist.writeappendix(const writer; const aname: msestring); +begin + with tstatwriter(writer) do begin + writeinteger(aname+'_ci',fcheckeditem); + end; +end; + +procedure tintegerdatalist.readappendix(const reader; const aname: msestring); +var +// po1: plongboolaty; + po1,pe,pchecked: pinteger; +// int1: integer; +begin + with tstatreader(reader) do begin + fcheckeditem:= readinteger(aname+'_ci',fcheckeditem,-1,count-1); + if fcheckeditem >= 0 then begin + po1:= datapo; + pe:= pointer(po1)+fcount*fsize; + pchecked:= pointer(po1) + fcheckeditem*fsize; + while po1 < pe do begin + if po1 <> pchecked then begin + po1^:= notcheckedvalue; + end; + po1:= pointer(po1) + fsize; + end; + { + for int1:= 0 to fcount-1 do begin //fix wrong data + if po1^[int1] <> (int1 = fcheckeditem) then begin + items[int1]:= integer(longbool((int1 = fcheckeditem))); + end; + end; + } + end; + end; +end; + +procedure tintegerdatalist.readitem(const reader: treader; var value); +begin + integer(value):= reader.ReadInteger; +end; + +procedure tintegerdatalist.writeitem(const writer: twriter; var value); +begin + writer.writeinteger(integer(value)) +end; + +function tintegerdatalist.checkassigncompatibility(const source: tpersistent): boolean; +begin + result:= source.inheritsfrom(tintegerdatalist); +end; + +function tintegerdatalist.getastext(const index: integer): msestring; +begin + result:= inttostrmse(items[index]); +end; + +procedure tintegerdatalist.setastext(const index: integer; + const avalue: msestring); +var + int1: integer; +begin + if trystrtoint(avalue,int1) then begin + items[index]:= int1; + end; +end; + +procedure tintegerdatalist.fill(const defaultvalue: integer); +begin + fill(count,defaultvalue); +end; + +{ tbooleandatalist } + +procedure tbooleandatalist.setasarray(const avalue: longboolarty); +begin + inherited asarray:= integerarty(avalue); +end; + +function tbooleandatalist.getasarray: longboolarty; +begin + result:= longboolarty(inherited asarray); +end; + +function tbooleandatalist.getitems(const index: integer): boolean; +begin + result:= inherited items[index] <> 0; +end; + +procedure tbooleandatalist.setitems(const index: integer; + const avalue: boolean); +begin + inherited items[index]:= longint(longbool(avalue)); +end; + +procedure tbooleandatalist.fill(acount: integer; const defaultvalue: boolean); +begin + inherited fill(acount,ord(longbool(defaultvalue))); +end; + +procedure tbooleandatalist.fill(const defaultvalue: boolean); +begin + fill(count,defaultvalue); +end; + +{ tint64datalist } + +constructor tint64datalist.create; +begin + inherited; + fsize:= sizeof(int64); +// min:= minint; +// max:= maxint; +end; + +class function tint64datalist.datatype: listdatatypety; +begin + result:= dl_int64; +end; +{ +procedure tint64datalist.assign(source: tpersistent); +begin + if not assigndata(source) then begin + inherited; + end; +end; +} +function tint64datalist.Getitems(index: integer): int64; +begin + internalgetdata(index,result); +end; + +procedure tint64datalist.Setitems(index: integer; const avalue: int64); +begin + internalsetdata(index,avalue); +end; + +procedure tint64datalist.setasarray(const value: int64arty); +begin + internalsetasarray(pointer(value),sizeof(int64),length(value)); +end; + +function tint64datalist.getasarray: int64arty; +begin + setlength(result,fcount); + internalgetasarray(pointer(result),sizeof(int64)); +end; + +procedure tint64datalist.readitem(const reader: treader; var value); +begin + int64(value):= reader.ReadInt64; +end; + +procedure tint64datalist.writeitem(const writer: twriter; var value); +begin + writer.writeinteger(int64(value)) +end; + +function tint64datalist.compare(const l,r): integer; +begin + result:= int64(l)-int64(r); +end; + +procedure tint64datalist.setstatdata(const index: integer; + const value: msestring); +var + int1: int64; +begin + int1:= strtoint64(value); + setdata(index,int1); +end; + +function tint64datalist.getstatdata(const index: integer): msestring; +begin + result:= inttostrmse(items[index]); +end; + +function tint64datalist.empty(const index: integer): boolean; +var + po1: pointer; +begin + po1:= getdefault; + if po1 = nil then begin + result:= pint64(getitempo(index))^ = 0; + end + else begin + result:= pint64(getitempo(index))^ = pinteger(po1)^; + end; +end; + +function tint64datalist.add(const avalue: int64): integer; +begin + result:= adddata(avalue); +end; + +procedure tint64datalist.insert(const index: integer; const avalue: int64); +begin + insertdata(index,avalue); +end; + +function tint64datalist.find(const avalue: int64): integer; +var + int1: integer; +begin + result:= -1; + for int1:= 0 to fcount-1 do begin + if int64(pointer(fdatapo+int1*fsize)^) = avalue then begin + result:= int1; + break; + end; + end; +end; + +procedure tint64datalist.fill(const acount: integer; const defaultvalue: int64); +begin + internalfill(count,defaultvalue); +end; + +function tint64datalist.checkassigncompatibility(const source: tpersistent): boolean; +begin + result:= source.inheritsfrom(tint64datalist); +end; + +function tint64datalist.getastext(const index: integer): msestring; +begin + result:= inttostrmse(items[index]); +end; + +procedure tint64datalist.setastext(const index: integer; + const avalue: msestring); +var + int1: int64; +begin + if trystrtoint64(avalue,int1) then begin + items[index]:= int1; + end; +end; + +procedure tint64datalist.fill(const defaultvalue: int64); +begin + fill(count,defaultvalue); +end; + +{ tcurrencydatalist } + +constructor tcurrencydatalist.create; +begin + inherited; + fsize:= sizeof(currency); +// min:= minint; +// max:= maxint; +end; + +class function tcurrencydatalist.datatype: listdatatypety; +begin + result:= dl_currency; +end; +{ +procedure tcurrencydatalist.assign(source: tpersistent); +begin + if not assigndata(source) then begin + inherited; + end; +end; +} +function tcurrencydatalist.Getitems(index: integer): currency; +begin + internalgetdata(index,result); +end; + +procedure tcurrencydatalist.Setitems(index: integer; const avalue: currency); +begin + internalsetdata(index,avalue); +end; + +procedure tcurrencydatalist.setasarray(const value: currencyarty); +begin + internalsetasarray(pointer(value),sizeof(currency),length(value)); +end; + +function tcurrencydatalist.getasarray: currencyarty; +begin + setlength(result,fcount); + internalgetasarray(pointer(result),sizeof(currency)); +end; + +procedure tcurrencydatalist.readitem(const reader: treader; var value); +begin + currency(value):= reader.Readcurrency; +end; + +procedure tcurrencydatalist.writeitem(const writer: twriter; var value); +begin + writer.writecurrency(currency(value)) +end; + +function tcurrencydatalist.compare(const l,r): integer; +var + cur1: currency; +begin + result:= 0; + cur1:= currency(l)-currency(r); + if cur1 < 0 then begin + result:= -1; + end + else begin + if cur1 > 0 then begin + result:= 1; + end; + end; +end; + +procedure tcurrencydatalist.setstatdata(const index: integer; + const value: msestring); +var + int1: currency; +begin + int1:= strtocurr(ansistring(value)); + setdata(index,int1); +end; + +function tcurrencydatalist.getstatdata(const index: integer): msestring; +begin + result:= msestring(currtostr(items[index])); +end; + +function tcurrencydatalist.empty(const index: integer): boolean; +var + po1: pointer; +begin + po1:= getdefault; + if po1 = nil then begin + result:= pcurrency(getitempo(index))^ = 0; + end + else begin + result:= pcurrency(getitempo(index))^ = pinteger(po1)^; + end; +end; + +function tcurrencydatalist.add(const avalue: currency): integer; +begin + result:= adddata(avalue); +end; + +procedure tcurrencydatalist.insert(const index: integer; const avalue: currency); +begin + insertdata(index,avalue); +end; + +function tcurrencydatalist.find(const avalue: currency): integer; +var + int1: integer; +begin + result:= -1; + for int1:= 0 to fcount-1 do begin + if currency(pointer(fdatapo+int1*fsize)^) = avalue then begin + result:= int1; + break; + end; + end; +end; + +procedure tcurrencydatalist.fill(const acount: integer; const defaultvalue: currency); +begin + internalfill(count,defaultvalue); +end; + +function tcurrencydatalist.checkassigncompatibility(const source: tpersistent): boolean; +begin + result:= source.inheritsfrom(tcurrencydatalist); +end; + +function tcurrencydatalist.getastext(const index: integer): msestring; +begin + result:= msestring(currtostr(items[index])); +end; + +procedure tcurrencydatalist.setastext(const index: integer; + const avalue: msestring); +var + cu1: currency; +begin + if trystrtocurr(ansistring(avalue),cu1) then begin + items[index]:= cu1; + end; +end; + +procedure tcurrencydatalist.fill(const defaultvalue: currency); +begin + fill(count,defaultvalue); +end; + +{ tenumdatalist } + +constructor tenumdatalist.create(agetdefault: getintegereventty); +begin + inherited create; + fgetdefault:= agetdefault; +end; + +function tenumdatalist.empty(const index: integer): boolean; +begin + result:= integer(getitempo(index)^) = fgetdefault(); +end; + +function tenumdatalist.getdefault: pointer; +begin + fdefaultval:= fgetdefault(); + result:= @fdefaultval; +end; + +{ tenum64datalist } + +constructor tenum64datalist.create(agetdefault: getint64eventty); +begin + inherited create; + fgetdefault:= agetdefault; +end; + +function tenum64datalist.empty(const index: integer): boolean; +begin + result:= int64(getitempo(index)^) = fgetdefault(); +end; + +function tenum64datalist.getdefault: pointer; +begin + fdefaultval:= fgetdefault(); + result:= @fdefaultval; +end; + +{ trealdatalist } + +constructor trealdatalist.create; +begin + inherited; + fsize:= sizeof(real); + min:= emptyreal; + max:= bigreal; + fdefaultval:= emptyreal; +end; + +function trealdatalist.getdefault: pointer; +begin + if fdefaultzero then begin + result:= nil; + end + else begin + result:= @fdefaultval; + end; +end; + +procedure trealdatalist.number(start,step: real); +var + int1: integer; + rea1: real; +begin + beginupdate; + try + for int1:= 0 to count-1 do begin + rea1:= start+int1*step; + internalsetdata(int1,rea1); + end; + finally + endupdate; + end; +end; + +function trealdatalist.add(const value: real): integer; +begin + result:= adddata(value); +end; +{ +procedure trealdatalist.assign(source: tpersistent); +begin + if not assigndata(source) then begin + inherited; + end; +end; +} +procedure trealdatalist.assignre(const source: tcomplexdatalist); +begin + source.assigntodata(self); +end; + +procedure trealdatalist.assignim(const source: tcomplexdatalist); +begin + source.assigntob(self); +end; + +procedure trealdatalist.assignre(const source: complexarty); +var + pod,poe: preal; + pos: pcomplexty; +begin + beginupdate; + count:= length(source); + if count > 0 then begin + pod:= datapo; + poe:= pod + fcount; + pos:= pointer(source); + repeat + pod^:= pos^.re; + inc(pos); + inc(pod); + until pod = poe; + end; + endupdate; +end; + +procedure trealdatalist.assignim(const source: complexarty); +var + pod,poe: preal; + pos: pcomplexty; +begin + beginupdate; + count:= length(source); + if count > 0 then begin + pod:= datapo; + poe:= pod + fcount; + pos:= pointer(source); + repeat + pod^:= pos^.im; + inc(pos); + inc(pod); + until pod = poe; + end; + endupdate; +end; + +procedure trealdatalist.copytocomplex(dest: pcomplexty); +var + ps,pe: preal; +begin + if count > 0 then begin + ps:= datapo; + pe:= ps+count; + repeat + dest^.re:= ps^; //dest possibly shifted to im + inc(dest); + inc(ps); + until ps = pe; + end; +end; + +procedure trealdatalist.assigntore(const dest: tcomplexdatalist); +begin + dest.beginupdate; + dest.count:= count; + copytocomplex(dest.datapo); + dest.endupdate; +end; + +procedure trealdatalist.assigntoim(const dest: tcomplexdatalist); +begin + dest.beginupdate; + dest.count:= count; + copytocomplex(pointer(preal(dest.datapo)+1)); + dest.endupdate; +end; + +procedure trealdatalist.assigntore(var dest: complexarty); +begin + setlength(dest,count); + copytocomplex(pointer(dest)); +end; + +procedure trealdatalist.assigntoim(var dest: complexarty); +begin + setlength(dest,count); + copytocomplex(pointer(preal(pointer(dest))+1)); +end; + +procedure trealdatalist.insert(index: integer; const item: realty); +begin + insertdata(index,item); +end; + +function trealdatalist.Getitems(index: integer): realty; +begin + checkindex(index); + result:= prealty(pointer(fdatapo+index*fsize))^; +// internalgetdata(index,result); +end; + +procedure trealdatalist.Setitems(index: integer; const Value: realty); +var + int1: integer; +begin + int1:= index; + checkindex(index); + prealty(pointer(fdatapo+index*fsize))^:= value; + change(int1); +// internalsetdata(index,value); +end; + +function trealdatalist.getasarray: realarty; +begin + setlength(result,fcount); + internalgetasarray(pointer(result),sizeof(realty)); +end; + +procedure trealdatalist.setasarray(const data: realarty); +begin + internalsetasarray(pointer(data),sizeof(realty),length(data)); +end; + +class function trealdatalist.datatype: listdatatypety; +begin + result:= dl_real; +end; + +function trealdatalist.empty(const index: integer): boolean; +var + po1: preal; +begin + po1:= preal(getitempo(index)); + result:= po1^ = emptyreal; + if fdefaultzero then begin + result:= result or (po1^ = 0); + end; +end; + +function trealdatalist.compare(const l,r): integer; +begin + result:= cmprealty(real(l),real(r)); +end; + +procedure trealdatalist.fill(acount: integer; const defaultvalue: realty); +begin + internalfill(count,defaultvalue); +end; + +procedure trealdatalist.minmax(out minval,maxval: realty); +var + int1: integer; + po1: prealty; + min1,max1: realty; +begin + min1:= bigreal; + max1:= emptyreal; + po1:= datapo; + for int1:= count-1 downto 0 do begin + if po1^ = emptyreal then begin + min1:= po1^; + end + else begin + if (max1 = emptyreal) or (po1^ > max1) then begin + max1:= po1^; + end; + if not (min1 = emptyreal) and (min1 > po1^) then begin + min1:= po1^; + end; + end; + inc(pchar(po1),fsize); + end; + minval:= min1; + maxval:= max1; +end; + +function trealdatalist.getstatdata(const index: integer): msestring; +begin + result:= realtytostrdotmse(items[index]); +// result:= realtytostrdot(items[index]); +end; + +procedure trealdatalist.setstatdata(const index: integer; const value: msestring); +var + rea1: realty; +begin + if (value = '') and facceptempty then begin + rea1:= emptyreal; + end + else begin + rea1:= strtorealtydot(value); + if cmprealty(rea1,min) < 0 then begin + rea1:= min; + end + else begin + if cmprealty(rea1,max) > 0 then begin + rea1:= max; + end; + end; + end; + items[index]:= rea1; +end; + +procedure trealdatalist.readitem(const reader: treader; var value); +begin + realty(value):= readrealty(reader); +end; + +procedure trealdatalist.writeitem(const writer: twriter; var value); +begin + writer.writefloat(double(value)); +// writerealty(writer,realty(value)); +end; + +function trealdatalist.checkassigncompatibility(const source: tpersistent): boolean; +begin + result:= source.inheritsfrom(trealdatalist); +end; + +function trealdatalist.getastext(const index: integer): msestring; +var + rea1: realty; +begin + result:= ''; + rea1:= items[index]; + if not (rea1 = emptyreal) then begin + result:= doubletostring(rea1,0,fsm_default, + defaultformatsettingsmse.decimalseparator); + end; +end; + +procedure trealdatalist.setastext(const index: integer; + const avalue: msestring); +var + rea1: realty; +begin + if avalue = '' then begin + items[index]:= emptyreal; + end + else begin + if trystrtodouble(avalue,double(rea1)) then begin + items[index]:= rea1; + end; + end; +end; + +procedure trealdatalist.fill(const defaultvalue: realty); +begin + fill(count,defaultvalue); +end; + +{ tdatetimedatalist } + +class function tdatetimedatalist.datatype: listdatatypety; +begin + result:= dl_datetime; +end; + +function tdatetimedatalist.empty(const index: integer): boolean; +begin + result:= preal(getitempo(index))^ = 0; +end; + +procedure tdatetimedatalist.fill(acount: integer; + const defaultvalue: tdatetime); +begin + internalfill(count,defaultvalue); +end; + +function tdatetimedatalist.getdefault: pointer; +begin + result:= nil; //-> 0.0 +end; + +procedure tdatetimedatalist.fill(const defaultvalue: tdatetime); +begin + fill(count,defaultvalue); +end; + +{ tcomplexdatalist } + +constructor tcomplexdatalist.create; +begin + min:= emptyreal; + max:= bigreal; + fdefaultval.re:= emptyreal; + fdefaultval.im:= emptyreal; + inherited; + fsize:= sizeof(complexty); +end; + +function tcomplexdatalist.add(const value: complexty): integer; +begin + result:= adddata(value); +end; + +procedure tcomplexdatalist.assign(source: tpersistent); +begin + if not assigndata(source) then begin + if source is trealdatalist then begin + assignre(trealdatalist(source)); + end + else begin + inherited; + end; + end; +end; + +procedure tcomplexdatalist.assignb(const source: tdatalist); +var + int1: integer; + po1,po2: pcomplexty; + s1,s2: integer; +begin + if source = self then begin + exit; + end; + if source is tcomplexdatalist then begin + beginupdate; + count:= source.count; + po1:= datapo; + po2:= source.datapo; + s1:= size; + s2:= source.size; + for int1:= 0 to fcount-1 do begin + po1^.im:= po2^.im; + inc(pchar(po1),s1); + inc(pchar(po2),s2); + end; + endupdate; + end + else begin + if source is trealdatalist then begin + assignim(trealdatalist(source)); + end + else begin + inherited; + end; + end; +end; + +procedure tcomplexdatalist.assignre(const source: trealdatalist); +begin + source.assigntodata(self); +end; + +procedure tcomplexdatalist.assignim(const source: trealdatalist); +var + int1: integer; + po1: pcomplexty; + po2: prealty; + s1,s2: integer; +begin + beginupdate; + count:= source.count; + po1:= datapo; + po2:= source.datapo; + s1:= size; + s2:= source.size; + for int1:= 0 to fcount-1 do begin + po1^.im:= po2^; + inc(pchar(po1),s1); + inc(pchar(po2),s2); + end; + endupdate; +end; + +procedure tcomplexdatalist.assigntoa(const dest: tdatalist); +begin + dest.assign(self); +end; + +procedure tcomplexdatalist.assigntob(const dest: tdatalist); +var + int1: integer; + po1: pcomplexty; + po2: prealty; + s1,s2: integer; +begin + if dest is trealdatalist then begin + with trealdatalist(dest) do begin + newbuffer(count,true,dest.size > sizeof(real)); + po1:= self.datapo; + po2:= pointer(fdatapo); + s1:= self.size; + s2:= size; + for int1:= 0 to fcount-1 do begin + po2^:= po1^.im; + inc(pchar(po1),s1); + inc(pchar(po2),s2); + end; + change(-1); + end; + end + else begin + inherited; + end; +end; + +procedure tcomplexdatalist.assignto(dest: tpersistent); +begin + if dest is trealdatalist then begin + assigntodata(trealdatalist(dest)); + end + else begin + inherited; + end; +end; + +function tcomplexdatalist.Getitems(const index: integer): complexty; +begin + internalgetdata(index,result); +end; + +procedure tcomplexdatalist.insert(const index: integer; const item: complexty); +begin + insertdata(index,item); +end; + +procedure tcomplexdatalist.Setitems(const index: integer; const Value: complexty); +begin + internalsetdata(index,value); +end; + +class function tcomplexdatalist.datatype: listdatatypety; +begin + result:= dl_complex; +end; + +function tcomplexdatalist.empty(const index: integer): boolean; +var + po1: pcomplexty; +begin + po1:= getitempo(index); + result:= (po1^.re = emptyreal) and (po1^.im = emptyreal); + if fdefaultzero then begin + result:= result or (po1^.re = 0) and (po1^.im = 0); + end; +end; + +function tcomplexdatalist.getdefault: pointer; +begin + if fdefaultzero then begin + result:= nil; + end + else begin +// fdefaultval.re:= emptyreal; +// fdefaultval.im:= emptyreal; + result:= @fdefaultval; + end; +end; + +function tcomplexdatalist.getasarray: complexarty; +begin + setlength(result,fcount); + internalgetasarray(pointer(result),sizeof(complexty)); +end; + +procedure tcomplexdatalist.setasarray(const data: complexarty); +begin + internalsetasarray(pointer(data),sizeof(complexty),length(data)); +end; + +function tcomplexdatalist.getasarrayre: realarty; +var + int1: integer; + po1: pcomplexty; +begin + setlength(result,count); + po1:= datapo; + for int1:= 0 to high(result) do begin + result[int1]:= po1^.re; + inc(po1); + end; +end; + +procedure tcomplexdatalist.setasarrayre(const avalue: realarty); +var + int1: integer; + po1: pcomplexty; +begin + beginupdate; + count:= length(avalue); + po1:= datapo; + for int1:= 0 to high(avalue) do begin + po1^.re:= avalue[int1]; + inc(po1); + end; + endupdate; +end; + +function tcomplexdatalist.getasarrayim: realarty; +var + int1: integer; + po1: pcomplexty; +begin + setlength(result,count); + po1:= datapo; + for int1:= 0 to high(result) do begin + result[int1]:= po1^.im; + inc(po1); + end; +end; + +procedure tcomplexdatalist.setasarrayim(const avalue: realarty); +var + int1: integer; + po1: pcomplexty; +begin + beginupdate; + count:= length(avalue); + po1:= datapo; + for int1:= 0 to high(avalue) do begin + po1^.im:= avalue[int1]; + inc(po1); + end; + endupdate; +end; + + +procedure tcomplexdatalist.fill(const acount: integer; + const defaultvalue: complexty); +begin + internalfill(count,defaultvalue); +end; + +procedure tcomplexdatalist.readitem(const reader: treader; var value); +begin + reader.ReadListBegin; + complexty(value).re:= readrealty(reader); + complexty(value).im:= readrealty(reader); + reader.readlistend; +end; + +procedure tcomplexdatalist.writeitem(const writer: twriter; var value); +begin + with writer do begin + writelistbegin; + writer.writefloat(complexty(value).re); + writer.writefloat(complexty(value).im); +// writerealty(writer,complexty(value).re); +// writerealty(writer,complexty(value).im); + writelistend; + end; +end; + +function tcomplexdatalist.checkassigncompatibility(const source: tpersistent): boolean; +begin + result:= source.inheritsfrom(tcomplexdatalist); +end; + +procedure tcomplexdatalist.fill(const defaultvalue: complexty); +begin + fill(count,defaultvalue); +end; + +{ tpointerdatalist } + +constructor tpointerdatalist.create; +begin + inherited; + fsize:= sizeof(pointer); +end; + +function tpointerdatalist.Getitems(index: integer): pointer; +begin + internalgetdata(index,result); +end; + +procedure tpointerdatalist.Setitems(index: integer; const Value: pointer); +begin + internalsetdata(index,value); +end; + +function tpointerdatalist.getasarray: pointerarty; +begin + setlength(result,fcount); + internalgetasarray(pointer(result),sizeof(pointer)); +end; + +procedure tpointerdatalist.setasarray(const data: pointerarty); +begin + internalsetasarray(pointer(data),sizeof(pointer),length(data)); +end; + +function tpointerdatalist.checkassigncompatibility( + const source: tpersistent): boolean; +begin + result:= source.inheritsfrom(tpointerdatalist); +end; + +procedure tpointerdatalist.readitem(const reader: treader; var value); +begin + ptrint(value):= reader.ReadInt64; +end; + +procedure tpointerdatalist.writeitem(const writer: twriter; var value); +begin + writer.writeinteger(ptrint(value)); +end; + +{ tdynamicdatalist } + +constructor tdynamicdatalist.create; +begin + inherited; + fstate:= fstate + [dls_needsfree,dls_needscopy]; +end; +{ +destructor tdynamicdatalistmse.destroy; +begin + clear; + inherited; +end; +} + +{ tdynamicpointerdatalist } + +constructor tdynamicpointerdatalist.create; +begin + inherited; + fsize:= sizeof(pointer); +end; + +{ tansistringdatalist } + +function tansistringdatalist.add(const value: ansistring): integer; +begin + result:= adddata(value); +end; + +function tansistringdatalist.addtext(const value: ansistring): integer; + //returns added linecount +var + ar1: stringarty; + int1,int2: integer; +begin + ar1:= nil; //compiler warning + if value <> '' then begin + beginupdate; + ar1:= breaklines(value); + int1:= count; + if int1 = 0 then begin + result:= length(ar1); + end + else begin + result:= high(ar1); + end; + count:= count + result; + items[int1]:= items[int1] + ar1[0]; + for int2:= 1 to high(ar1) do begin + items[int1+int2]:= ar1[int2]; + end; + endupdate; + end + else begin + result:= 0; + end; +end; + +procedure tansistringdatalist.assign(source: tpersistent); +var + int1: integer; + po1{,po2}: pansistring; + s1{,s2}: integer; +begin + if not assigndata(source) then begin + if source is tstringlist then begin + with tstringlist(source) do begin + self.newbuffer(count,false,true); + po1:= self.datapo; + s1:= self.size; + for int1:= 0 to self.fcount - 1 do begin + po1^:= strings[int1]; + inc(pchar(po1),s1); + end; + end; + change(-1); + end + else begin + inherited; + end; + end; +end; + +procedure tansistringdatalist.assignopenarray(const data: array of ansistring); +var + po1: pstring; + int1: integer; + s1: integer; +begin + newbuffer(length(data),true,true); + po1:= pointer(fdatapo); + s1:= size; + for int1:= 0 to fcount - 1 do begin + po1^:= data[int1]; + inc(pchar(po1),s1); + end; + change(-1); +end; +{ +procedure tansistringdatalist.assignarray(const data: stringarty); +var + int1: integer; + po1: pansistring; + s1: integer; +begin + beginupdate; + try + count:= 0; + count:= length(data); + po1:= pointer(fdatapo); + s1:= size; + for int1:= 0 to length(data)-1 do begin + po1^:= data[int1]; + inc(pchar(po1),s1); + end; + finally + endupdate; + end; +end; + +procedure tansistringdatalist.assignarray(const data: msestringarty); +var + int1: integer; + po1: pansistring; + s1: integer; +begin + beginupdate; + try + count:= 0; + count:= length(data); + po1:= datapo; + s1:= size; + for int1:= 0 to length(data)-1 do begin + po1^:= ansistring(data[int1]); + inc(pchar(po1),s1); + end; + finally + endupdate; + end; +end; +} +function tansistringdatalist.Getitems(index: integer): ansistring; +begin + result:= pansistring(getitempo(index))^; +end; + +procedure tansistringdatalist.insert(index: integer; const item: ansistring); +begin + insertdata(index,item); +end; + +procedure tansistringdatalist.Setitems(index: integer; const Value: ansistring); +begin + pansistring(getitempo(index))^:= value; + change(index); +end; + +class function tansistringdatalist.datatype: listdatatypety; +begin + result:= dl_ansistring; +end; + +function tansistringdatalist.empty(const index: integer): boolean; +begin + result:= pansistring(getitempo(index))^ = ''; +end; + +procedure tansistringdatalist.freedata(var data); +begin + ansistring(data):= ''; +end; + +procedure tansistringdatalist.beforecopy(var data); +begin + stringaddref(ansistring(data)); +end; + +procedure tansistringdatalist.assignto(dest: tpersistent); +var + int1: integer; + po1: pansistring; + s1: integer; +begin + if dest is tstringlist then begin + po1:= datapo; + s1:= size; + with tstringlist(dest) do begin + clear; + capacity:= self.count; + for int1:= 0 to self.count-1 do begin + add(po1^); + inc(pchar(po1),s1); + end; + end; + end + else begin + inherited; + end; +end; + +function tansistringdatalist.compare(const l,r): integer; +begin + result:= comparestr(ansistring(l),ansistring(r)); +end; + +function tansistringdatalist.comparecaseinsensitive(const l,r): integer; +begin + result:= comparetext(ansistring(l),ansistring(r)); +end; + +procedure tansistringdatalist.readitem(const reader: treader; var value); +begin + string(value):= reader.ReadString; +end; + +procedure tansistringdatalist.writeitem(const writer: twriter; var value); +begin + writer.WriteString(string(value)); +end; + +procedure tansistringdatalist.fill(acount: integer; + const defaultvalue: ansistring); +begin + internalfill(count,defaultvalue); +end; + +function tansistringdatalist.getstatdata(const index: integer): msestring; +begin + if dls_binarydata in fstate then begin + result:= msestring(encodebase64(items[index])); + end + else begin + result:= msestring(items[index]); + end; +end; + +procedure tansistringdatalist.setstatdata(const index: integer; + const value: msestring); +begin + if dls_binarydata in fstate then begin + items[index]:= decodebase64(ansistring(value)); + end + else begin + items[index]:= ansistring(value); + end; +end; + +function tansistringdatalist.getasarray: stringarty; +begin + result:= nil; + allocuninitedarray(fcount,sizeof(result[0]),result); +// setlength(result,fcount); + internalgetasarray(pointer(result),sizeof(string)); +end; + +procedure tansistringdatalist.setasarray(const avalue: stringarty); +begin + internalsetasarray(pointer(avalue),sizeof(string),length(avalue)); +end; + +function tansistringdatalist.getasmsestringarray: msestringarty; +var + po1: pstring; + int1: integer; + s1: integer; +begin + setlength(result,fcount); + po1:= datapo; + s1:= size; + for int1:= 0 to fcount - 1 do begin + result[int1]:= msestring(po1^); + inc(pchar(pointer(po1)),s1); + end; +end; + +procedure tansistringdatalist.setasmsestringarray(const avalue: msestringarty); +var + po1: pstring; + s1: integer; + int1: integer; +begin + newbuffer(length(avalue),true,true); + po1:= pointer(fdatapo); + s1:= size; + for int1:= 0 to high(avalue) do begin + po1^:= ansistring(avalue[int1]); + inc(pchar(po1),s1); + end; + change(-1); +end; + +function tansistringdatalist.checkassigncompatibility(const source: tpersistent): boolean; +begin + result:= source.inheritsfrom(tansistringdatalist); +end; + +function tansistringdatalist.getastext(const index: integer): msestring; +begin + result:= msestring(items[index]); +end; + +procedure tansistringdatalist.setastext(const index: integer; + const avalue: msestring); +begin + items[index]:= ansistring(avalue); +end; + +function tansistringdatalist.textlength: integer; +var + int1,int2: integer; + po1: pchar; +begin + po1:= datapo; + int2:= 0; + for int1:= 0 to fcount - 1 do begin + inc(int2,length(ansistring(pointer(po1)^))); + inc(po1,fsize); + end; + result:= int2; +end; + +function tansistringdatalist.gettext: ansistring; +var + po1: pansistring; + po2: pansichar; + int1: integer; + int2: integer; + ch1,ch2: ansichar; +begin + if count = 0 then begin + result:=''; + exit; + end; + int2:= textlength; + int2:= int2 + count * length(lineend); + setlength(result,int2); + ch1:= string(lineend)[1]; +{$warnings off} + if length(lineend) > 1 then begin + ch2:= string(lineend)[2]; + end; +{$warnings on} + po1:= datapo; + po2:= pointer(result); + for int1:= count-1 downto 0 do begin + int2:= length(po1^); + if int2 <> 0 then begin + move(pointer(po1^)^,po2^,int2*sizeof(ansichar)); + inc(po2,int2); + end; + po2^:= ch1; + inc(po2); +{$warnings off} + if length(lineend) > 1 then begin + po2^:= ch2; + inc(po2); + end; +{$warnings on} + inc(pchar(po1),fsize); + end; + setlength(result,length(result)-length(lineend)); //remove last lineend +end; + +procedure tansistringdatalist.settext(const avalue: ansistring); +begin + asarray:= breaklines(avalue); +end; + +{ tpoorstringdatalist } + +function tpoorstringdatalist.add(const value: tmsestringdatalist): integer; +var + int1,int2: integer; +begin + result:= fcount; + beginupdate; + with value do begin + self.count:= fcount+self.fcount; + int2:= self.fcount-fcount; + int1:= 0; + if int2 < 0 then begin + int1:= int1-int2; + int2:= 0; + end; + for int1:= int1 to fcount - 1 do begin + self.items[int2]:= items[int1]; + inc(int2); + end; + end; + endupdate; +end; + +function tpoorstringdatalist.add(const avalue: msestring; + const anoparagraph: boolean): integer; +begin + result:= add(avalue); +end; + +function tpoorstringdatalist.addchars(const value: msestring; + const aoptions: addcharoptionsty = [aco_processeditchars]; +// const processeditchars: boolean = true; + const maxchars: integer = 0): integer; +var + int1,int2,int3,int4: integer; + ar1,ar2: msestringarty; + ar3,ar4: booleanarty; + first: pmsestring; + mstr1: msestring; + bo1: boolean; +begin + result:= 0; + ar1:= nil; //compilerwarning + if value <> '' then begin + if aco_stripescsequence in aoptions then begin + ar1:= breaklines(stripescapesequences(value)); + end + else begin + ar1:= breaklines(value); + end; + if fcount = 0 then begin + count:= 1; + inc(result); + end; + int1:= fcount - 1; + int2:= int1; + checkindex(int1); + first:= pmsestring(fdatapo+int1*fsize); +// if processeditchars then begin + if aco_processeditchars in aoptions then begin + mstr1:= first^; + addeditchars(ar1[0],mstr1,feditcharindex); + ar1[0]:= mstr1; + for int1:= 1 to high(ar1) do begin + mstr1:= ''; + feditcharindex:= 0; + addeditchars(ar1[int1],mstr1,feditcharindex); + ar1[int1]:= mstr1; + end; + end + else begin + ar1[0]:= first^ + ar1[0]; +// for int1:= 1 to high(ar1) do begin +// add(ar1[int1]); +// inc(result); +// end; + end; + if maxchars <> 0 then begin + int2:= 0; + for int1:= 0 to high(ar1) do begin //calc new linecount + if ar1[int1] = '' then begin + inc(int2); + end + else begin + int2:= int2 + (length(ar1[int1])-1) div maxchars + 1; + end; + end; + if int2 <> length(ar1) then begin //break lines + setlength(ar2,int2); + setlength(ar4,int2); + setlength(ar3,int2+1); + int2:= 0; + bo1:= aco_multilinepara in aoptions; + for int1:= 0 to high(ar1) do begin + ar4[int2]:= true; //paragraph start + int3:= length(ar1[int1]); + if int3 > maxchars then begin + int4:= 1; + while int4 <= int3 do begin //todo: handle surrogate pairs + if bo1 then begin + ar2[int2]:= ar2[int2]+copy(ar1[int1],int4,maxchars)+lineend; + end + else begin + ar2[int2]:= copy(ar1[int1],int4,maxchars); + end; + int4:= int4 + maxchars; + if not bo1 then begin + ar3[int2]:= true; //appended line + inc(int2); + end; + end; + if bo1 then begin + setlength(ar2[int2],length(ar2[int2])-length(lineend)); + inc(int2); + end; + end + else begin + ar2[int2]:= ar1[int1]; + inc(int2); + end; + end; + ar1:= ar2; + end; + end; + setlength(ar3,length(ar1)); + setlength(ar4,length(ar1)); + first^:= ar1[0]; + if high(ar1) > 0 then begin + beginupdate; + result:= result + high(ar1); + for int1:= 1 to high(ar1) do begin + add(ar1[int1],ar3[int1] and not ar4[int1]); + end; + endupdate; + end + else begin + change(fcount-1); + end; + end; +end; + +{ +function tpoorstringdatalist.addchars(const value: msestring; + const processeditchars: boolean = true; + const maxchars: integer = 0): integer; +var + int1,int2: integer; + ar1: msestringarty; + first: pmsestring; + mstr1: msestring; +begin + ar1:= nil; //compilerwarning + if value <> '' then begin + ar1:= breaklines(value); + if high(ar1) > 0 then begin + beginupdate; + end; + if fcount = 0 then begin + count:= 1; + end; + int1:= fcount - 1; + int2:= int1; + checkindex(int1); + first:= pmsestring(fdatapo+int1*fsize); + if processeditchars then begin + addeditchars(ar1[0],first^,feditcharindex); + for int1:= 1 to high(ar1) do begin + mstr1:= ''; + feditcharindex:= 0; + addeditchars(ar1[int1],mstr1,feditcharindex); + add(mstr1); + end; + end + else begin + first^:= first^ + ar1[0]; + for int1:= 1 to high(ar1) do begin + add(ar1[int1]); + end; + end; + if high(ar1) > 0 then begin + endupdate; + end + else begin + change(int2); + end; + end; + result:= fcount-1; +end; +} + +(* +function tpoorstringdatalist.addchars(const value: msestring; + const processeditchars: boolean = true): integer; +var + int1,int2: integer; + po1: pmsestring; + ar1: msestringarty; + backdelete: integer; +begin + ar1:= nil; //compilerwarning + if value <> '' then begin + ar1:= breaklines(value); + backdelete:= 0; + if processeditchars then begin + for int1:= 0 to high(ar1) do begin + int2:= msestrings.processeditchars(ar1[int1],false); + if int1 = 0 then begin + backdelete:= int2; + end; + end; + end; + if high(ar1) > 0 then begin + beginupdate; + end; + for int2:= 0 to high(ar1) do begin + if (fcount = 0) or (int2 > 0) then begin + add(ar1[int2]); + end + else begin + int1:= fcount - 1; + checkindex(int1); + po1:= pointer(fdatapo+int1*fsize); + po1^:= copy(po1^,1,length(po1^)+backdelete) + ar1[int2]; + change(int1); +// doitemchange(int1); + end; + end; + if high(ar1) > 0 then begin + endupdate; + end; + end; + result:= fcount-1; +end; +*) +procedure tpoorstringdatalist.assign(source: tpersistent); +var + int1: integer; + po1{,po2}: pmsestring; + po3: pstring; + s1,s2: integer; +begin + if not assigndata(source) then begin + if source is tansistringdatalist then begin + with tansistringdatalist(source) do begin + self.newbuffer(count,true,true); + po3:= datapo; + po1:= self.datapo; + s1:= self.size; + s2:= size; + for int1:= 0 to count - 1 do begin + po1^:= msestring(po3^); + inc(pchar(po1),s1); + inc(pchar(po3),s2); + end; + end; + change(-1); + end + else begin + inherited; + end; + end; +end; + +function tpoorstringdatalist.Getitems(index: integer): msestring; +var + po1: pmsestring; +begin + checkindex(index); + po1:= pointer(fdatapo+index*fsize); + result:= po1^; +end; + +procedure tpoorstringdatalist.Setitems(index: integer; const Value: msestring); +var + po1: pmsestring; + int1: integer; +begin + int1:= index; + checkindex(index); + po1:= pointer(fdatapo+index*fsize); + po1^:= value; + change(int1); +end; + +function tpoorstringdatalist.empty(const index: integer): boolean; +begin + result:= pmsestring(getitempo(index))^ = ''; +end; +{ +function tpoorstringdatalist.empty(const index: integer): boolean; +var + po1: pmsestring; +begin + checkindex(index); + po1:= pointer(fdatapo+index*fsize); + result:= po1^ = ''; +end; +} +procedure tpoorstringdatalist.freedata(var data); +begin + msestring(data):= ''; +end; + +{$ifdef msestringsarenotrefcounted} +procedure tpoorstringdatalist.aftercopy(var data); +begin + stringaddref(msestring(data)); +end; +{$else} +procedure tpoorstringdatalist.beforecopy(var data); +begin + stringaddref(msestring(data)); +end; +{$endif} + +procedure tpoorstringdatalist.assignto(dest: tpersistent); +var + int1: integer; + po1: pmsestring; +// s1: integer; +begin + if dest is tstringlist then begin + normalizering; +// s1:= size; + with tstringlist(dest) do begin + clear; + capacity:= self.fcount; + po1:= pointer(fdatapo); + for int1:= 0 to self.count-1 do begin + add(ansistring(po1^)); + inc(pchar(po1),fsize); + end; + end; + end + else begin + inherited; + end; +end; + +procedure tpoorstringdatalist.readitem(const reader: treader; var value); +begin +{$ifdef fpcbug4519read} + msestring(value):= readwidestring4519(reader); +{$else} + msestring(value):= treader_readmsestring(reader); +// {$ifdef mse_unicodestring} +// msestring(value):= reader.ReadunicodeString; +// {$else} +// msestring(value):= reader.ReadwideString; +// {$endif} +{$endif} +end; + +procedure tpoorstringdatalist.writeitem(const writer: twriter; var value); +begin +// {$ifdef fpcbug4519} +// writewidestring4519(writer,msestring(value)); +// {$else} + twriter_writemsestring(writer,msestring(value)); +// {$ifdef mse_unicodestring} +// writer.writeunicodestring(msestring(value)); +// {$else} +// writer.WritewideString(msestring(value)); +// {$endif} +// {$endif} +end; + +procedure tpoorstringdatalist.loadfromstream(const stream: ttextstream); +var + mstr1: msestring; + first: boolean; +begin + beginupdate; + try + clear; + first:= true; + while stream.readln(mstr1) do begin + add(mstr1); + first:= false; + end; + if not first or (mstr1 <> '') then begin + add(mstr1); + end; + finally + endupdate; + end; +end; + +procedure tpoorstringdatalist.loadfromfile(const filename: filenamety; + const aencoding: charencodingty = ce_locale); +var + stream: ttextstream; +begin + stream:= ttextstream.Create(filename,fm_read); + stream.encoding:= aencoding; + try + loadfromstream(stream); + finally + stream.Free; + end; +end; + +procedure tpoorstringdatalist.savetofile(const filename: filenamety; + const aencoding: charencodingty = ce_locale); +var + stream: ttextstream; +begin + stream:= ttextstream.Create(filename,fm_create); + stream.encoding:= aencoding; + try + savetostream(stream); + finally + stream.Free; + end; +end; + +procedure tpoorstringdatalist.savetostream(const stream: ttextstream); +var + int1: integer; + po1: pmsestring; + si1: int64; +begin + if fcount > 0 then begin + po1:= datapo; + if stream.ismemorystream then begin + si1:= 0; + for int1:= count - 2 downto 0 do begin + si1:= si1 + length(po1^); + inc(pchar(po1),fsize); + end; + stream.capacity:= stream.capacity + si1 + count*2; + //space for return-linefeed + po1:= datapo; + end; + for int1:= count - 2 downto 0 do begin + stream.writeln(po1^); + inc(pchar(po1),fsize); + end; + stream.write(po1^); + end; +end; + +function tpoorstringdatalist.textlength: integer; +var + int1,int2: integer; + po1: pchar; +begin + po1:= datapo; + int2:= 0; + for int1:= 0 to fcount - 1 do begin + inc(int2,length(msestring(pointer(po1)^))); + inc(po1,fsize); + end; + result:= int2; +end; + +function tpoorstringdatalist.dataastextstream: ttextstream; + //chars truncated to 8bit +var + len: integer; + int1,int2,int3,int4: integer; + po1,po2: pchar; + bo1: boolean; + ch1,ch2: char; + wch1: widechar; +begin + result:= ttextstream.create; //memorystream + int2:= textlength; + if int2 > 0 then begin + len:= int2+(fcount-1)*length(lineend); + result.setsize(len+sizeof(lineend)); +// getmem(result,len+sizeof(lineend)); + po2:= result.memory; + po1:= datapo; + bo1:= length(lineend) > 1; + ch1:= string(lineend)[1]; + if bo1 then begin + ch2:= string(lineend)[2]; + end + else begin + ch2:= ' '; //compiler warning + end; + for int1:= 0 to fcount - 1 do begin + int4:= length(msestring(pointer(po1)^)); + for int3:= int4 - 1 downto 0 do begin + wch1:= msecharaty(pointer(pointer(po1)^)^)[int3]; + if wch1 > #$ff then begin + wch1:= #$ff; + end; + (po2 + int3)^:= char(byte(wch1)); + end; + inc(po2,int4); + po2^:= ch1; + if bo1 then begin + (po2 + 1)^:= ch2; + inc(po2,2); + end + else begin + inc(po2,1); + end; + inc(po1,fsize); + end; + result.setsize(len+sizeof(lineend)); //remove last newline + end; +end; + +function tpoorstringdatalist.getasarray: msestringarty; +begin + result:= nil; + allocuninitedarray(fcount,sizeof(result[0]),result); +// setlength(result,fcount); //possible memory leak in FPC 3.0 + internalgetasarray(pointer(result),sizeof(msestring)); +end; + +procedure tpoorstringdatalist.setasarray(const data: msestringarty); +begin + internalsetasarray(pointer(data),sizeof(msestring),length(data)); +end; + +function tpoorstringdatalist.getasstringarray: stringarty; +var + int1: integer; + po1: pmsestring; +begin + setlength(result,count); + po1:= datapo; + for int1:= 0 to count - 1 do begin + result[int1]:= ansistring(po1^); + pchar(po1):= pchar(po1)+fsize; + end; +end; + +procedure tpoorstringdatalist.setasstringarray(const data: stringarty); +var + po1: pmsestring; + int1: integer; + s1: integer; +begin + newbuffer(length(data),true,true); + po1:= pointer(fdatapo); + s1:= size; + for int1:= 0 to high(data) do begin + po1^:= msestring(data[int1]); + inc(pchar(po1),s1); + end; + change(-1); +end; + +procedure tpoorstringdatalist.assignopenarray(const data: array of msestring); +var + po1: pmsestring; + s1: integer; + int1: integer; +begin + newbuffer(length(data),true,true); + po1:= datapo; + s1:= size; + for int1:= 0 to high(data) do begin + po1^:= data[int1]; + inc(pchar(po1),s1); + end; + change(-1); +end; +{ +procedure tpoorstringdatalist.assignarray(const data: stringarty); +var + int1: integer; + po1: pmsestring; +begin + beginupdate; + try + count:= 0; + count:= length(data); + po1:= pointer(fdatapo); + for int1:= 0 to length(data)-1 do begin + po1^:= msestring(data[int1]); + inc(pchar(po1),fsize); + end; + finally + endupdate; + end; +end; + +procedure tpoorstringdatalist.assignarray(const data: msestringarty); +var + int1: integer; + po1: pmsestring; +begin + beginupdate; + try + count:= 0; + count:= length(data); + po1:= pointer(fdatapo); + for int1:= 0 to high(data) do begin + po1^:= data[int1]; + inc(pchar(po1),fsize); + end; + finally + endupdate; + end; +end; +} +function tpoorstringdatalist.indexof(const value: msestring): integer; +var + int1: integer; + po1: pmsestring; +begin + result:= -1; + normalizering; + po1:= pointer(fdatapo); + for int1:= 0 to fcount -1 do begin + if po1^ = value then begin + result:= int1; + break; + end; + inc(pchar(po1),fsize); + end; +end; + +function tpoorstringdatalist.concatstring(const delim: msestring = ''; + const separator: msestring = ''; + const separatornoparagraph: msestring = ''): msestring; +var + int1: integer; + po1: pmsestring; +begin + if fcount > 0 then begin + normalizering; + result:= delim + pmsestring(fdatapo)^ + delim; + for int1:= 1 to fcount-1 do begin + po1:= @separator; + if getnoparagraphs(int1) then begin + po1:= @separatornoparagraph; + end; + result:= result + po1^ + delim + pmsestring(fdatapo+int1*fsize)^ + delim; + end; + end + else begin + result:= ''; + end; +end; + +function tpoorstringdatalist.getstatdata(const index: integer): msestring; +begin + result:= items[index]; +end; + +procedure tpoorstringdatalist.setstatdata(const index: integer; + const value: msestring); +begin + items[index]:= value; +end; + +function tpoorstringdatalist.checkassigncompatibility( + const source: tpersistent): boolean; +begin + result:= source.inheritsfrom(tpoorstringdatalist); +end; + +function tpoorstringdatalist.getnoparagraphs(index: integer): boolean; +begin + result:= false; +end; + +function tpoorstringdatalist.getastext(const index: integer): msestring; +begin + result:= items[index]; +end; + +procedure tpoorstringdatalist.setastext(const index: integer; + const avalue: msestring); +begin + items[index]:= avalue; +end; + +function tpoorstringdatalist.gettext: msestring; +var + po1: pmsestring; + po2: pmsechar; + int1: integer; + int2: integer; + ch1,ch2: msechar; +begin + if count = 0 then begin + result:=''; + exit; + end; + int2:= textlength; + int2:= int2 + count * length(lineend); + setlength(result,int2); + ch1:= msechar(byte(string(lineend)[1])); +{$warnings off} + if length(lineend) > 1 then begin + ch2:= msechar(byte(string(lineend)[2])); + end; +{$warnings on} + po1:= datapo; + po2:= pointer(result); + for int1:= count-1 downto 0 do begin + int2:= length(po1^); + if int2 <> 0 then begin + move(pointer(po1^)^,po2^,int2*sizeof(msechar)); + inc(po2,int2); + end; + po2^:= ch1; + inc(po2); +{$warnings off} + if length(lineend) > 1 then begin + po2^:= ch2; + inc(po2); + end; +{$warnings on} + inc(pchar(po1),fsize); + end; + setlength(result,length(result)-length(lineend)); //remove last lineend +end; + +procedure tpoorstringdatalist.settext(const avalue: msestring); +begin + asarray:= breaklines(avalue); +end; + +{ tmsestringdatalist } + +class function tmsestringdatalist.datatype: listdatatypety; +begin + result:= dl_msestring; +end; + +function tmsestringdatalist.add(const value: msestring): integer; +begin + result:= adddata(value); +end; + +procedure tmsestringdatalist.insert(const index: integer; const item: msestring); +begin + insertdata(index,item); +end; + +function tmsestringdatalist.compare(const l,r): integer; +begin + if sdo_naturalsort in foptions then begin + result:= msecomparestrnatural(msestring(l),msestring(r)); + end + else begin + result:= msecomparestr(msestring(l),msestring(r)); + end; +end; + +function tmsestringdatalist.comparecaseinsensitive(const l,r): integer; +begin + if sdo_naturalsort in foptions then begin + result:= msecomparetextnatural(msestring(l),msestring(r)); + end + else begin + result:= msecomparetext(msestring(l),msestring(r)); + end; +end; + +procedure tmsestringdatalist.fill(acount: integer; const defaultvalue: msestring); +begin + internalfill(count,defaultvalue); +end; + +{ tdoublemsestringdatalist } + +function tdoublemsestringdatalist.add(const value: msestring): integer; +begin + result:= add(value,''); +end; + +function tdoublemsestringdatalist.add(const valuea: msestring; + const valueb: msestring = ''): integer; +var + dstr1: doublemsestringty; +begin + dstr1.a:= valuea; + dstr1.b:= valueb; + result:= adddata(dstr1); +end; + +function tdoublemsestringdatalist.add(const value: doublemsestringty): integer; +begin + result:= adddata(value); +end; + +{$ifdef msestringsarenotrefcounted} +procedure tdoublemsestringdatalist.aftercopy(var data); +begin + inherited; + stringaddref(doublemsestringty(data).b); +end; +{$else} +procedure tdoublemsestringdatalist.beforecopy(var data); +begin + inherited; + stringaddref(doublemsestringty(data).b); +end; +{$endif} + +constructor tdoublemsestringdatalist.create; +begin + inherited; + fsize:= sizeof(doublemsestringty); +end; + +class function tdoublemsestringdatalist.datatype: listdatatypety; +begin + result:= dl_doublemsestring; +end; + +procedure tdoublemsestringdatalist.fill(const acount: integer; + const defaultvalue: msestring); +var + dstr1: doublemsestringty; +begin + dstr1.a:= defaultvalue; + dstr1.b:= ''; + internalfill(count,dstr1); +end; + +procedure tdoublemsestringdatalist.freedata(var data); +begin + inherited; + doublemsestringty(data).b:= ''; +end; + +function tdoublemsestringdatalist.Getitemsb(index: integer): msestring; +begin + result:= pdoublemsestringty(getitempo(index))^.b; +end; + +procedure tdoublemsestringdatalist.Setitemsb(index: integer; + const Value: msestring); +begin + pdoublemsestringty(getitempo(index))^.b:= value; +end; + +function tdoublemsestringdatalist.Getdoubleitems(index: integer): doublemsestringty; +begin + result:= pdoublemsestringty(getitempo(index))^; +end; + +procedure tdoublemsestringdatalist.Setdoubleitems(index: integer; + const Value: doublemsestringty); +begin + pdoublemsestringty(getitempo(index))^:= value; +end; + +procedure tdoublemsestringdatalist.insert(const index: integer; + const item: msestring); +var + dstr1: doublemsestringty; +begin + dstr1.a:= item; + dstr1.b:= ''; + insertdata(index,dstr1); +end; + +function tdoublemsestringdatalist.compare(const l,r): integer; +begin + result:= msecomparestr(doublemsestringty(l).a,doublemsestringty(r).a); +end; + +function tdoublemsestringdatalist.comparecaseinsensitive(const l,r): integer; +begin + result:= msecomparetext(doublemsestringty(l).a,doublemsestringty(r).a); +end; + +{ +procedure tdoublemsestringdatalist.assign(source: tpersistent); +var + int1: integer; + po1,po2: pdoublemsestringty; + s1,s2: integer; +begin + if source = self then begin + exit; + end; + if source is tdoublemsestringdatalist then begin + beginupdate; + with tdoublemsestringdatalist(source) do begin + po2:= datapo; + self.clear; + self.count:= count; + po1:= self.datapo; + s1:= self.size; + s2:= size; + for int1:= 0 to count - 1 do begin + po1^:= po2^; + inc(pchar(po1),s1); + inc(pchar(po2),s2); + end; + end; + endupdate; + end + else begin + inherited; + end; +end; +} +procedure tdoublemsestringdatalist.assignb(const source: tdatalist); +var + int1: integer; + po1,po2: pdoublemsestringty; + po3: pmsestring; + s1,s2: integer; +begin + if source is tdoublemsestringdatalist then begin + beginupdate; + with tdoublemsestringdatalist(source) do begin + self.count:= fcount; + po1:= self.datapo; + po2:= datapo; + s1:= self.size; + s2:= size; + for int1:= 0 to fcount-1 do begin + po1^.b:= po2^.b; + inc(pchar(po1),s1); + inc(pchar(po2),s2); + end; + end; + endupdate; + end + else begin + if source is tmsestringdatalist then begin + beginupdate; + with tmsestringdatalist(source) do begin + self.count:= fcount; + po1:= self.datapo; + po3:= datapo; + s1:= self.size; + s2:= size; + for int1:= 0 to fcount-1 do begin + po1^.b:= po3^; + inc(pchar(po1),s1); + inc(pchar(po3),s2); + end; + end; + endupdate; + end + else begin + inherited; + end; + end; +end; + +procedure tdoublemsestringdatalist.assigntob(const dest: tdatalist); +var + int1: integer; + po1: pdoublemsestringty; + po2: pmsestring; + s1,s2: integer; +begin + if dest is tmsestringdatalist then begin + with tmsestringdatalist(dest) do begin + beginupdate; + clear; + count:= self.fcount; + po1:= self.datapo; + po2:= datapo; + s1:= self.size; + s2:= size; + for int1:= 0 to fcount-1 do begin + po2^:= po1^.b; + inc(pchar(po1),s1); + inc(pchar(po2),s2); + end; + endupdate; + end + end + else begin + inherited; + end; +end; + +procedure tdoublemsestringdatalist.setasarray(const data: doublemsestringarty); +begin + internalsetasarray(pointer(data),sizeof(doublemsestringty),length(data)); +end; + +function tdoublemsestringdatalist.getasarray: doublemsestringarty; +begin + result:= nil; + allocuninitedarray(fcount,sizeof(result[0]),result); +// setlength(result,fcount); + internalgetasarray(pointer(result),sizeof(doublemsestringty)); +end; + +function tdoublemsestringdatalist.getasarraya: msestringarty; +var + int1: integer; + po1: pdoublemsestringty; + s1: integer; +begin + setlength(result,fcount); + po1:= datapo; + s1:= size; + for int1:= 0 to fcount - 1 do begin + result[int1]:= po1^.a; + inc(pchar(po1),s1); + end; +end; + +procedure tdoublemsestringdatalist.setasarraya(const data: msestringarty); +var + int1: integer; + po1: pdoublemsestringty; + s1: integer; +begin + beginupdate; + count:= length(data); + po1:= datapo; + s1:= size; + for int1:= 0 to fcount - 1 do begin + po1^.a:= data[int1]; + inc(pchar(po1),s1); + end; + endupdate; +end; + +procedure tdoublemsestringdatalist.setasarrayb(const data: msestringarty); +var + int1: integer; + po1: pdoublemsestringty; + s1: integer; +begin + beginupdate; + count:= length(data); + po1:= datapo; + s1:= size; + for int1:= 0 to fcount - 1 do begin + po1^.b:= data[int1]; + inc(pchar(po1),s1); + end; + endupdate; +end; + +function tdoublemsestringdatalist.getasarrayb: msestringarty; +var + int1: integer; + po1: pdoublemsestringty; + s1: integer; +begin + setlength(result,fcount); + po1:= datapo; + s1:= size; + for int1:= 0 to fcount - 1 do begin + result[int1]:= po1^.b; + inc(pchar(po1),s1); + end; +end; + +procedure tdoublemsestringdatalist.readitem(const reader: treader; var value); +begin + with reader do begin + readlistbegin; + {$ifdef fpcbug4519read} + doublemsestringty(value).a:= readwidestring4519(reader); + doublemsestringty(value).b:= readwidestring4519(reader); + {$else} + doublemsestringty(value).a:= treader_readmsestring(reader); + doublemsestringty(value).b:= treader_readmsestring(reader); +// {$ifdef mse_unicodestring} +// doublemsestringty(value).a:= readunicodestring; +// doublemsestringty(value).b:= readunicodestring; +// {$else} +// doublemsestringty(value).a:= readwidestring; +// doublemsestringty(value).b:= readwidestring; +// {$endif} + {$endif} + readlistend; + end; +end; + +procedure tdoublemsestringdatalist.writeitem(const writer: twriter; var value); +begin + with writer do begin + writelistbegin; +// {$ifdef fpcbug4519} +// writewidestring4519(writer,doublemsestringty(value).a); +// writewidestring4519(writer,doublemsestringty(value).b); +// {$else} + twriter_writemsestring(writer,doublemsestringty(value).a); + twriter_writemsestring(writer,doublemsestringty(value).b); +// {$ifdef mse_unicodestring} +// writeunicodestring(doublemsestringty(value).a); +// writeunicodestring(doublemsestringty(value).b); +// {$else} +// writewidestring(doublemsestringty(value).a); +// writewidestring(doublemsestringty(value).b); +// {$endif} +// {$endif} + writelistend; + end; +end; + +{ tmsestringintdatalist } + +constructor tmsestringintdatalist.create; +begin + inherited; + fsize:= sizeof(msestringintty); +end; + +class function tmsestringintdatalist.datatype: listdatatypety; +begin + result:= dl_msestringint; +end; + +function tmsestringintdatalist.add(const value: msestring): integer; +begin + result:= add(value,0); +end; + +function tmsestringintdatalist.add(const valuea: msestring; + const valueb: integer): integer; +var + dstr1: msestringintty; +begin + dstr1.mstr:= valuea; + dstr1.int:= valueb; + result:= adddata(dstr1); +end; + +function tmsestringintdatalist.add(const value: msestringintty): integer; +begin + result:= adddata(value); +end; + +procedure tmsestringintdatalist.fill(const acount: integer; + const defaultvalue: msestring; const defaultint: integer); +var + dstr1: msestringintty; +begin + dstr1.mstr:= defaultvalue; + dstr1.int:= defaultint; + internalfill(count,dstr1); +end; + +function tmsestringintdatalist.Getitemsb(index: integer): integer; +begin + result:= pmsestringintty(getitempo(index))^.int; +end; + +procedure tmsestringintdatalist.Setitemsb(index: integer; + const Value: integer); +begin + pmsestringintty(getitempo(index))^.int:= value; + change(index); +end; + +function tmsestringintdatalist.Getdoubleitems(index: integer): msestringintty; +begin + result:= pmsestringintty(getitempo(index))^; +end; + +procedure tmsestringintdatalist.Setdoubleitems(index: integer; + const Value: msestringintty); +begin + pmsestringintty(getitempo(index))^:= value; + change(index); +end; + +procedure tmsestringintdatalist.insert(const index: integer; + const item: msestring); +begin + insert(index,item,0); +end; + +procedure tmsestringintdatalist.insert(const index: integer; + const item: msestring; const itemint: integer); +var + dstr1: msestringintty; +begin + dstr1.mstr:= item; + dstr1.int:= itemint; + insertdata(index,dstr1); +end; + +function tmsestringintdatalist.compare(const l,r): integer; +begin + result:= msecomparestr(msestringintty(l).mstr,msestringintty(r).mstr); +end; + +function tmsestringintdatalist.comparecaseinsensitive(const l,r): integer; +begin + result:= msecomparetext(msestringintty(l).mstr,msestringintty(r).mstr); +end; + +{ +procedure tmsestringintdatalist.assign(source: tpersistent); +begin + if not assigndata(source) then begin + inherited; + end; +end; +} +procedure tmsestringintdatalist.assignb(const source: tdatalist); +var + int1: integer; + po1,po2: pmsestringintty; + po3: pinteger; + s1,s2: integer; +begin + if source is tmsestringintdatalist then begin + beginupdate; + count:= source.count; + with tmsestringintdatalist(source) do begin + po1:= self.datapo; + po2:= datapo; + s1:= self.size; + s2:= size; + for int1:= 0 to self.fcount-1 do begin + po1^.int:= po2^.int; + inc(pchar(po1),s1); + inc(pchar(po2),s2); + end; + end; + endupdate; + end + else begin + if source is tintegerdatalist then begin + beginupdate; + count:= source.count; + with tintegerdatalist(source) do begin + po1:= self.datapo; + po3:= datapo; + s1:= self.size; + s2:= size; + for int1:= 0 to fcount-1 do begin + po1^.int:= po3^; + inc(pchar(po1),s1); + inc(pchar(po3),s2); + end; + end; + endupdate; + end + else begin + inherited; + end; + end; +end; + +procedure tmsestringintdatalist.assigntob(const dest: tdatalist); +var + int1: integer; + po1: pmsestringintty; + po2: pinteger; + s1,s2: integer; +begin + if dest is tintegerdatalist then begin + with tintegerdatalist(dest) do begin + newbuffer(self.count,true,dest.size > sizeof(integer)); + po1:= self.datapo; + po2:= pointer(fdatapo); + s1:= self.size; + s2:= size; + for int1:= 0 to fcount-1 do begin + po2^:= po1^.int; + inc(pchar(po1),s1); + inc(pchar(po2),s2); + end; + change(-1); + end + end + else begin + inherited; + end; +end; + +procedure tmsestringintdatalist.setasarray(const data: msestringintarty); +begin + internalsetasarray(pointer(data),sizeof(msestringintty),length(data)); +end; + +function tmsestringintdatalist.getasarray: msestringintarty; +begin + result:= nil; + allocuninitedarray(fcount,sizeof(result[0]),result); +// setlength(result,fcount); + internalgetasarray(pointer(result),sizeof(msestringintty)); +end; + +function tmsestringintdatalist.getasarraya: msestringarty; +var + int1: integer; + po1: pmsestringintty; + s1: integer; +begin + setlength(result,fcount); + po1:= datapo; + s1:= size; + for int1:= 0 to fcount - 1 do begin + result[int1]:= po1^.mstr; + inc(pchar(po1),s1); + end; +end; + +procedure tmsestringintdatalist.setasarraya(const data: msestringarty); +var + int1: integer; + po1: pmsestringintty; + s1: integer; +begin + beginupdate; + count:= length(data); + po1:= datapo; + s1:= size; + for int1:= 0 to fcount - 1 do begin + po1^.mstr:= data[int1]; + inc(pchar(po1),s1); + end; + endupdate; +end; + +procedure tmsestringintdatalist.setasarrayb(const data: integerarty); +var + int1: integer; + po1: pmsestringintty; + s1: integer; +begin + beginupdate; + count:= length(data); + po1:= datapo; + s1:= size; + for int1:= 0 to fcount - 1 do begin + po1^.int:= data[int1]; + inc(pchar(po1),s1); + end; + endupdate; +end; + +function tmsestringintdatalist.getasarrayb: integerarty; +var + int1: integer; + po1: pmsestringintty; + s1: integer; +begin + setlength(result,fcount); + po1:= datapo; + s1:= size; + for int1:= 0 to fcount - 1 do begin + result[int1]:= po1^.int; + inc(pchar(po1),s1); + end; +end; + +procedure tmsestringintdatalist.readitem(const reader: treader; var value); +begin + with reader do begin + readlistbegin; + {$ifdef fpcbug4519read} + msestringintty(value).mstr:= readwidestring4519(reader); + {$else} + msestringintty(value).mstr:= treader_readmsestring(reader); +// {$ifdef mse_unicodestring} +// msestringintty(value).mstr:= readunicodestring; +// {$else} +// msestringintty(value).mstr:= readwidestring; +// {$endif} + {$endif} + msestringintty(value).int:= readinteger; + readlistend; + end; +end; + +procedure tmsestringintdatalist.writeitem(const writer: twriter; var value); +begin + with writer do begin + writelistbegin; +// {$ifdef fpcbug4519} +// writewidestring4519(writer,doublemsestringty(value).a); +// writewidestring4519(writer,doublemsestringty(value).b); +// {$else} + twriter_writemsestring(writer,msestringintty(value).mstr); +// {$ifdef mse_unicodestring} +// writeunicodestring(msestringintty(value).mstr); +// {$else} +// writewidestring(msestringintty(value).mstr); +// {$endif} + writeinteger(msestringintty(value).int); +// {$endif} + writelistend; + end; +end; + +procedure tmsestringintdatalist.setstatdata(const index: integer; + const value: msestring); +var + strint1: msestringintty; + int1: integer; +begin + int1:= findchar(value,','); + if int1 > 0 then begin + strint1.int:= strtoint(copy(value,1,int1-1)); + strint1.mstr:= copy(value,int1+1,bigint); + setdata(index,strint1); + end; +end; + +function tmsestringintdatalist.getstatdata(const index: integer): msestring; +begin + with pmsestringintty(getitempo(index))^ do begin + result:= inttostrmse(int)+','+mstr; + end; +end; + +{ trealintdatalist } + +constructor trealintdatalist.create; +begin + fdefaultval1.rea:= emptyreal; + inherited; + fsize:= sizeof(realintty); +end; + +class function trealintdatalist.datatype: listdatatypety; +begin + result:= dl_realint; +end; + +function trealintdatalist.add(const valuea: realty; + const valueb: integer = 0): integer; +var + d1: realintty; +begin + d1.rea:= valuea; + d1.int:= valueb; + result:= adddata(d1); +end; + +function trealintdatalist.add(const value: realintty): integer; +begin + result:= adddata(value); +end; + +procedure trealintdatalist.fill(const acount: integer; + const defaultvalue: realty; const defaultint: integer); +var + d1: realintty; +begin + d1.rea:= defaultvalue; + d1.int:= defaultint; + internalfill(count,d1); +end; + +function trealintdatalist.Getitemsb(index: integer): integer; +begin + result:= prealintty(getitempo(index))^.int; +end; + +procedure trealintdatalist.Setitemsb(index: integer; + const Value: integer); +begin + prealintty(getitempo(index))^.int:= value; + change(index); +end; + +function trealintdatalist.Getdoubleitems(index: integer): realintty; +begin + result:= prealintty(getitempo(index))^; +end; + +procedure trealintdatalist.Setdoubleitems(index: integer; + const Value: realintty); +begin + prealintty(getitempo(index))^:= value; + change(index); +end; + +procedure trealintdatalist.insert(const index: integer; + const item: realty; const itemint: integer); +var + d1: realintty; +begin + d1.rea:= item; + d1.int:= itemint; + insertdata(index,d1); +end; + +function trealintdatalist.compare(const l,r): integer; +begin + result:= cmprealty(realintty(l).rea,realintty(r).rea); +end; +{ +procedure trealintdatalist.assign(source: tpersistent); +begin + if not assigndata(source) then begin + inherited; + end; +end; +} +procedure trealintdatalist.assignb(const source: tdatalist); +var + int1: integer; + po1,po2: prealintty; + po3: pinteger; + s1,s2: integer; +begin + if source is trealintdatalist then begin + beginupdate; + count:= source.count; + with trealintdatalist(source) do begin + po1:= self.datapo; + po2:= datapo; + s1:= self.size; + s2:= size; + for int1:= 0 to self.fcount-1 do begin + po1^.int:= po2^.int; + inc(pchar(po1),s1); + inc(pchar(po2),s2); + end; + end; + endupdate; + end + else begin + if source is tintegerdatalist then begin + beginupdate; + count:= source.count; + with tintegerdatalist(source) do begin + po1:= self.datapo; + po3:= datapo; + s1:= self.size; + s2:= size; + for int1:= 0 to fcount-1 do begin + po1^.int:= po3^; + inc(pchar(po1),s1); + inc(pchar(po3),s2); + end; + end; + endupdate; + end + else begin + inherited; + end; + end; +end; + +procedure trealintdatalist.assigntob(const dest: tdatalist); +var + int1: integer; + po1: prealintty; + po2: pinteger; + s1,s2: integer; +begin + if dest is tintegerdatalist then begin + with tintegerdatalist(dest) do begin + newbuffer(self.count,true,dest.size > sizeof(integer)); + po1:= self.datapo; + po2:= pointer(fdatapo); + s1:= self.size; + s2:= size; + for int1:= 0 to fcount-1 do begin + po2^:= po1^.int; + inc(pchar(po1),s1); + inc(pchar(po2),s2); + end; + change(-1); + end + end + else begin + inherited; + end; +end; + +procedure trealintdatalist.setasarray(const data: realintarty); +begin + internalsetasarray(pointer(data),sizeof(realintty),length(data)); +end; + +function trealintdatalist.getasarray: realintarty; +begin + setlength(result,fcount); + internalgetasarray(pointer(result),sizeof(realintty)); +end; + +function trealintdatalist.getasarraya: realarty; +var + int1: integer; + po1: prealintty; + s1: integer; +begin + setlength(result,fcount); + po1:= datapo; + s1:= size; + for int1:= 0 to fcount - 1 do begin + result[int1]:= po1^.rea; + inc(pchar(po1),s1); + end; +end; + +procedure trealintdatalist.setasarraya(const data: realarty); +var + int1: integer; + po1: prealintty; + s1: integer; +begin + beginupdate; + count:= length(data); + po1:= pointer(fdatapo); + s1:= size; + for int1:= 0 to fcount - 1 do begin + po1^.rea:= data[int1]; + inc(pchar(po1),s1); + end; + endupdate; +end; + +procedure trealintdatalist.setasarrayb(const data: integerarty); +var + int1: integer; + po1: prealintty; + s1: integer; +begin + beginupdate; + count:= length(data); + po1:= pointer(fdatapo); + s1:= size; + for int1:= 0 to fcount - 1 do begin + po1^.int:= data[int1]; + inc(pchar(po1),s1); + end; + endupdate; +end; + +function trealintdatalist.getasarrayb: integerarty; +var + int1: integer; + po1: prealintty; + s1: integer; +begin + setlength(result,fcount); + po1:= datapo; + s1:= size; + for int1:= 0 to fcount - 1 do begin + result[int1]:= po1^.int; + inc(pchar(po1),s1); + end; +end; + +procedure trealintdatalist.readitem(const reader: treader; var value); +begin + with reader do begin + readlistbegin; + realintty(value).rea:= readrealty(reader); + realintty(value).int:= readinteger; + readlistend; + end; +end; + +procedure trealintdatalist.writeitem(const writer: twriter; var value); +begin + with writer do begin + writelistbegin; + writer.writefloat(realintty(value).rea); +// writerealty(writer,realintty(value).rea); + writeinteger(realintty(value).int); + writelistend; + end; +end; + +procedure trealintdatalist.setstatdata(const index: integer; + const value: msestring); +var + d1: realintty; + int1: integer; +begin + int1:= findchar(value,','); + if int1 > 0 then begin + d1.rea:= strtorealtydot(copy(value,1,int1-1)); + if cmprealty(d1.rea,min) < 0 then begin + d1.rea:= min; + end + else begin + if cmprealty(d1.rea,max) > 0 then begin + d1.rea:= max; + end; + end; + d1.int:= strtoint(copy(value,int1+1,bigint)); + setdata(index,d1); + end; +end; + +function trealintdatalist.getstatdata(const index: integer): msestring; +begin + with prealintty(getitempo(index))^ do begin + result:= realtytostrdotmse(rea)+','+inttostrmse(int); + end; +end; + +function trealintdatalist.getdefault: pointer; +begin + if fdefaultzero then begin + result:= nil; + end + else begin + result:= @fdefaultval1; + end; +end; + +procedure trealintdatalist.fill(const defaultvalue: realty; + const defaultint: integer); +begin + fill(count,defaultvalue,defaultint); +end; + +{ tcustomrowstatelist } + +constructor tcustomrowstatelist.create; +begin + inherited; + fsize:= sizeof(rowstatety); +end; + +constructor tcustomrowstatelist.create(const ainfolevel: rowinfolevelty); +begin + finfolevel:= ainfolevel; + inherited create; + case finfolevel of + ril_colmerge: begin + fsize:= sizeof(rowstatecolmergety); + end; + ril_rowheight: begin + fsize:= sizeof(rowstaterowheightty); + end; + else begin + fsize:= sizeof(rowstatety); + end; + end; +end; + +class function tcustomrowstatelist.datatype: listdatatypety; +begin + result:= dl_rowstate; +end; + +function tcustomrowstatelist.getitempo(const index: integer): prowstatety; +begin + result:= prowstatety(inherited getitempo(index)); +end; + +function tcustomrowstatelist.getrowstate(const index: integer): rowstatety; +begin + getdata(index,result); +end; + +procedure tcustomrowstatelist.setrowstate(const index: integer; + const Value: rowstatety); +begin + setdata(index,value); +end; + +function tcustomrowstatelist.getrowstatecolmerge(const index: integer): rowstatecolmergety; +begin + checkinfolevel(ril_colmerge); + getdata(index,result); +end; + +procedure tcustomrowstatelist.setrowstatecolmerge(const index: integer; + const Value: rowstatecolmergety); +begin + checkinfolevel(ril_colmerge); + setdata(index,value); +end; + +function tcustomrowstatelist.getrowstaterowheight(const index: integer): rowstaterowheightty; +begin + checkinfolevel(ril_rowheight); + getdata(index,result); +end; + +procedure tcustomrowstatelist.setrowstaterowheight(const index: integer; + const Value: rowstaterowheightty); +begin + checkinfolevel(ril_rowheight); + setdata(index,value); +end; + +function tcustomrowstatelist.mergecols(const arow: integer; const astart: longword; + const acount: longword): boolean; +var + ca1,ca2: longword; +begin + result:= false; + if (astart < mergedcolmax - 1) and (acount > 0) then begin + with getitempocolmerge(arow)^ do begin + if (astart = 0) and (acount > mergedcolmax) then begin + ca2:= mergedcolall; + end + else begin + ca1:= acount; + if ca1 + astart > mergedcolmax then begin + ca1:= mergedcolmax - astart; + end; + ca2:= colmerge.merged or (bitmask[ca1] shl astart); + end; + if colmerge.merged <> ca2 then begin + colmerge.merged:= ca2; + result:= true; + end; + end; + end; +end; + +function tcustomrowstatelist.unmergecols(const arow: integer): boolean; +var + int1: integer; + po1: prowstatecolmergeaty; +begin + result:= false; + if arow = invalidaxis then begin + po1:= datapocolmerge; + for int1:= 0 to count - 1 do begin + if po1^[int1].colmerge.merged <> 0 then begin + result:= true; + po1^[int1].colmerge.merged:= 0; + end; + end; + end + else begin + with getitempocolmerge(arow)^ do begin + if colmerge.merged <> 0 then begin + result:= true; + colmerge.merged:= 0; + end; + end; + end; +end; + +function tcustomrowstatelist.gethidden(const index: integer): boolean; +begin + result:= getitempo(index)^.fold and foldhiddenmask <> 0; +end; + +function tcustomrowstatelist.getfoldinfoar: bytearty; +var + int1: integer; + po1: prowstatety; +begin + setlength(result,count); + po1:= datapo; + inc(po1,count); + for int1:= high(result) downto 0 do begin + dec(po1); + result[int1]:= po1^.fold; + end; +end; + +function tcustomrowstatelist.getfoldlevel(const index: integer): byte; +begin + result:= getitempo(index)^.fold and foldlevelmask; +end; + +procedure tcustomrowstatelist.setfoldlevel(const index: integer; + const avalue: byte); +begin + with getitempo(index)^ do begin + fold:= replacebits(avalue,fold,foldlevelmask); + end; + checkdirty(index); +end; + +procedure tcustomrowstatelist.sethidden(const index: integer; + const avalue: boolean); +begin + with getitempo(index)^ do begin + updatebit(fold,foldhiddenbit,avalue); + end; + checkdirty(index); +end; + +procedure tcustomrowstatelist.setfoldissum(const index: integer; + const avalue: boolean); +begin + with getitempo(index)^ do begin + updatebit(fold,foldissumbit,avalue); + end; + checkdirty(index); +end; + +function tcustomrowstatelist.getfoldissum(const index: integer): boolean; +begin + result:= getitempo(index)^.flags and foldissummask <> 0; +end; + +{ +procedure tcustomrowstatelist.assign(source: tpersistent); +begin + if source is tcustomrowstatelist then begin + with tcustomrowstatelist(source) do begin + self.beginupdate; + self.count:= count; + move(datapo^,self.datapo^,count*sizeof(rowstatety)); + self.endupdate; + end; + end + else begin + inherited; + end; +end; +} +function tcustomrowstatelist.getcolor(const index: integer): rowstatenumty; +begin + result:= (getitempo(index)^.color and rowstatemask) - 1; +end; + +procedure tcustomrowstatelist.setcolor(const index: integer; + const avalue: rowstatenumty); +begin + with getitempo(index)^ do begin + color:= replacebits(avalue + 1,color,rowstatemask); + end; +end; + +function tcustomrowstatelist.getlinecolor(const index: integer): rowstatenumty; +begin + result:= (getitemporowheight(index)^.rowheight.linecolor and rowstatemask) - 1; +end; + +procedure tcustomrowstatelist.setlinecolor(const index: integer; + const avalue: rowstatenumty); +begin + with getitemporowheight(index)^.rowheight do begin + linecolor:= replacebits(avalue + 1,linecolor,rowstatemask); + end; +end; + +function tcustomrowstatelist.getlinecolorfix(const index: integer): rowstatenumty; +begin + result:= (getitemporowheight(index)^.rowheight.linecolorfix and + rowstatemask) - 1; +end; + +procedure tcustomrowstatelist.setlinecolorfix(const index: integer; + const avalue: rowstatenumty); +begin + with getitemporowheight(index)^.rowheight do begin + linecolorfix:= replacebits(avalue + 1,linecolorfix,rowstatemask); + end; +end; + +function tcustomrowstatelist.getfont(const index: integer): rowstatenumty; +begin + result:= (getitempo(index)^.font and rowstatemask) - 1; +end; + +procedure tcustomrowstatelist.setfont(const index: integer; + const avalue: rowstatenumty); +begin + with getitempo(index)^ do begin + font:= replacebits(avalue + 1,font,rowstatemask); + end; +end; + +function tcustomrowstatelist.getreadonly(const index: integer): boolean; +begin + result:= getitempo(index)^.font and $80 <> 0; +end; + +procedure tcustomrowstatelist.setreadonly(const index: integer; + const avalue: boolean); +begin + with getitempo(index)^ do begin + if avalue then begin + font:= font or $80; + end + else begin + font:= font and not $80; + end; + end; +end; + +function tcustomrowstatelist.getflag1(const index: integer): boolean; +begin + result:= getitempo(index)^.color and $80 <> 0; +end; + +procedure tcustomrowstatelist.setflag1(const index: integer; + const avalue: boolean); +begin + with getitempo(index)^ do begin + if avalue then begin + color:= color or $80; + end + else begin + color:= color and not $80; + end; + end; +end; + +function tcustomrowstatelist.getselected(const index: integer): longword; +begin + result:= getitempo(index)^.selected; +end; + +procedure tcustomrowstatelist.setselected(const index: integer; + const avalue: longword); +begin + getitempo(index)^.selected:= avalue; +end; + +function tcustomrowstatelist.getmerged(const index: integer): longword; +begin + result:= getitempocolmerge(index)^.colmerge.merged; +end; + +procedure tcustomrowstatelist.setmerged(const index: integer; + const avalue: longword); +begin + getitempocolmerge(index)^.colmerge.merged:= avalue; +end; + +function tcustomrowstatelist.getheight(const index: integer): integer; +begin + result:= getitemporowheight(index)^.rowheight.height; + if result < 0 then begin + result:= 0; + end; +end; + +function tcustomrowstatelist.getlinewidth(const index: integer): rowlinewidthty; +begin + result:= getitemporowheight(index)^.rowheight.linewidth-1; +end; + +procedure tcustomrowstatelist.checkinfolevel(const wantedlevel: rowinfolevelty); +begin + if wantedlevel > finfolevel then begin + raise exception.create('Wrong rowinfolevel.'); + end; +end; + +function tcustomrowstatelist.datapocolmerge: pointer; +begin + checkinfolevel(ril_colmerge); + result:= datapo; +end; + +function tcustomrowstatelist.dataporowheight: pointer; +begin + checkinfolevel(ril_rowheight); + result:= datapo; +end; + +function tcustomrowstatelist.getitempocolmerge(const index: integer): prowstatecolmergety; +begin + checkinfolevel(ril_colmerge); + result:= prowstatecolmergety(inherited getitempo(index)); +end; + +function tcustomrowstatelist.getitemporowheight(const index: integer): prowstaterowheightty; +begin + checkinfolevel(ril_rowheight); + result:= prowstaterowheightty(inherited getitempo(index)); +end; + +procedure tcustomrowstatelist.initdirty; +begin + //dummy +end; + +procedure tcustomrowstatelist.recalchidden; +begin + //dummy +end; + +function tcustomrowstatelist.checkassigncompatibility( + const source: tpersistent): boolean; +begin + result:= source.inheritsfrom(tcustomrowstatelist); +end; + +procedure tcustomrowstatelist.change(const aindex: integer); +begin + if (aindex < 0) and (aindex <> -2) then begin //no count change + initdirty; + end; + inherited; +end; + +procedure tcustomrowstatelist.readstate(const reader; const acount: integer; + const name: msestring); +begin + initdirty; + inherited; + recalchidden; +end; + +procedure tcustomrowstatelist.assign(source: tpersistent); +begin + inherited; + recalchidden; +end; + +function tcustomrowstatelist.checkwritedata(const filer: tfiler): boolean; +begin + result:= false; +end; + +function tcustomrowstatelist.getcolorar: integerarty; +var + po1: prowstatety; + int1: integer; +begin + setlength(result,count); + po1:= datapo; + for int1:= 0 to high(result) do begin + result[int1]:= (po1^.color and rowstatemask) - 1; + inc(pchar(po1),fsize); + end; +end; + +procedure tcustomrowstatelist.setcolorar(const avalue: integerarty); +var + po1: prowstatety; + int1: integer; +begin +// beginupdate; + count:= length(avalue); + po1:= datapo; + for int1:= 0 to high(avalue) do begin + po1^.color:= replacebits(avalue[int1] + 1,po1^.color,rowstatemask); + inc(pchar(po1),fsize); + end; +// endupdate; +end; + +function tcustomrowstatelist.getfontar: integerarty; +var + po1: prowstatety; + int1: integer; +begin + setlength(result,count); + po1:= datapo; + for int1:= 0 to high(result) do begin + result[int1]:= (po1^.font and rowstatemask) - 1; + inc(pchar(po1),fsize); + end; +end; + +procedure tcustomrowstatelist.setfontar(const avalue: integerarty); +var + po1: prowstatety; + int1: integer; +begin +// beginupdate; + count:= length(avalue); + po1:= datapo; + for int1:= 0 to high(avalue) do begin + po1^.font:= replacebits(avalue[int1] + 1,po1^.font,rowstatemask); + inc(pchar(po1),fsize); + end; +// endupdate; +end; + +function tcustomrowstatelist.getfoldlevelar: integerarty; +var + po1: prowstatety; + int1: integer; +begin + setlength(result,count); + po1:= datapo; + for int1:= 0 to high(result) do begin + result[int1]:= (po1^.fold and foldlevelmask); + inc(pchar(po1),fsize); + end; +end; + +procedure tcustomrowstatelist.setfoldlevelar(const avalue: integerarty); +var + po1: prowstatety; + int1: integer; +begin +// beginupdate; + count:= length(avalue); + po1:= datapo; + for int1:= 0 to high(avalue) do begin + po1^.fold:= replacebits(avalue[int1] + 1,po1^.fold,foldlevelmask); + inc(pchar(po1),fsize); + end; + if avalue <> nil then begin + checkdirty(0); + end; +// endupdate; +end; + +function tcustomrowstatelist.gethiddenar: longboolarty; +var + po1: prowstatety; + int1: integer; +begin + setlength(result,count); + po1:= datapo; + for int1:= 0 to high(result) do begin + result[int1]:= (po1^.fold and foldhiddenmask) <> 0; + inc(pchar(po1),fsize); + end; +end; + +procedure tcustomrowstatelist.sethiddenar(const avalue: longboolarty); +var + po1: prowstatety; + int1: integer; +begin +// beginupdate; + count:= length(avalue); + po1:= datapo; + for int1:= 0 to high(avalue) do begin + updatebit(po1^.fold,foldhiddenbit,avalue[int1]); + inc(pchar(po1),fsize); + end; + if avalue <> nil then begin + checkdirty(0); + end; +// endupdate; +end; + +function tcustomrowstatelist.getfoldissumar: longboolarty; +var + po1: prowstatety; + int1: integer; +begin + setlength(result,count); + po1:= datapo; + for int1:= 0 to high(result) do begin + result[int1]:= (po1^.fold and foldissummask) <> 0; + inc(pchar(po1),fsize); + end; +end; + +procedure tcustomrowstatelist.setfoldissumar(const avalue: longboolarty); +var + po1: prowstatety; + int1: integer; +begin +// beginupdate; + count:= length(avalue); + po1:= datapo; + for int1:= 0 to high(avalue) do begin + updatebit(po1^.fold,foldissumbit,avalue[int1]); + inc(pchar(po1),fsize); + end; + if avalue <> nil then begin + checkdirty(0); + end; +// endupdate; +end; + +procedure tcustomrowstatelist.checkdirty(const arow: integer); +begin + //dummy +end; +(* +{ tlinindexmse } + +function tlinindexmse.find(key: pointer; nearest : boolean): integer; +var + l,r,p: integer; + int1: integer; +begin + l:= 0; + r:= count-1; + result:= -1; + if assigned(fcomparefunc) and (r > 0) then begin + p:= 0; int1:= 0; //compilerwarnungen verhindern + while true do begin + p:= (l+r) shr 1; + int1:= fcomparefunc(list^[p],key); + if l = r then begin + break; + end; + if int1 < 0 then begin + l:= p+1; + end + else begin + r:= p; + end; + end; + if int1 < 0 then begin + inc(p); + end; + if nearest or (int1 = 0) then begin + result:= p; + end; + end; +end; + +function tlinindexmse.insert(value: pointer): integer; +var + int1: integer; +begin + int1:= find(value,true); + if int1 < 0 then begin + int1:= 0; + end; + insert(int1,value); + result:= int1; +end; + +procedure tlinindexmse.QuickSort(L, R: Integer); +var + I, J: Integer; + P,T: Pointer; + pivotnum,pivotsortnum: integer; + int1: integer; +begin + repeat + I := L; + J := R; + pivotnum:= (L + R) shr 1; + pivotsortnum:= fsortnums[pivotnum]; + P := self.list^[pivotnum]; + repeat + while true do begin + int1:= fcomparefunc(self.list^[I], P); + if int1 = 0 then begin + int1:= fsortnums[I]-pivotsortnum; + end; + if int1 >= 0 then begin + break; + end; + Inc(I); + end; + while true do begin + int1:= fcomparefunc(self.list^[J], P); + if int1 = 0 then begin + int1:= fsortnums[J]-pivotsortnum; + end; + if int1 <= 0 then begin + break; + end; + Dec(J); + end; + if I <= J then begin + T := self.list^[I]; + self.list^[I] := self.list^[J]; + self.list^[J] := T; + int1:= fsortnums[I]; + fsortnums[I]:= fsortnums[J]; + fsortnums[J]:= int1; + Inc(I); + Dec(J); + end; + until I > J; + if L < J then + QuickSort(L, J); + L := I; + until I >= R; +end; + +procedure tlinindexmse.reindex; +var + int1: integer; +begin + if assigned(fcomparefunc) and (self.list <> nil) then begin + setlength(fsortnums,count); + for int1:= 0 to count-1 do begin + fsortnums[int1]:= int1; + end; + quicksort(0,count-1); + setlength(fsortnums,0); + end; +end; + +procedure tlinindexmse.Setcomparefunc(const Value: indexcomparety); +begin + if @fcomparefunc <> @value then begin + Fcomparefunc:= Value; + fsortvalid:= false; + end; +end; +*) + +{ tobjectdatalist } + +constructor tobjectdatalist.create; +begin + inherited; + fstate:= (fstate - [dls_needscopy]) + [dls_needsinit]; +end; + +procedure tobjectdatalist.checkitemclass(const aitem: tobject); +begin + if (fitemclass <> nil) and not (aitem is fitemclass) then begin + raise exception.create('Item must be "'+fitemclass.classname+'".'); + end; +end; + +function tobjectdatalist.add(const aitem: tobject): integer; +begin + checkitemclass(aitem); + result:= adddata(aitem); +end; + +function tobjectdatalist.extract(const index: integer): tobject; //no finalize +begin + result:= self[index]; + internaldeletedata(index,false); +end; +{ +procedure tobjectdatalist.copyinstance(var data); +begin + tobject(data):= nil; + initinstance(data); +end; +} +procedure tobjectdatalist.freedata(var data); +begin + freeandnil(tobject(data)); +end; + +procedure tobjectdatalist.docreateobject(var instance: tobject); +begin + if instance = nil then begin + if assigned(foncreateobject) then begin + foncreateobject(self,instance); + end; + end; +end; + +procedure tobjectdatalist.initinstance(var data); +begin + docreateobject(tobject(data)); +end; + +function tobjectdatalist.Getitems(index: integer): tobject; +begin + internalgetdata(index,result); +end; + + +procedure tobjectdatalist.setitems(index: integer; const Value: tobject); +var + po1: pobject; +begin + po1:= getitempo(index); + freedata(po1^); + po1^:= value; +end; + +function tobjectdatalist.checkassigncompatibility(const source: tpersistent): boolean; +begin + result:= source.inheritsfrom(tobjectdatalist); +end; + +{ tnonedatalist } + +class function tnonedatalist.datatype: listdatatypety; +begin + result:= dl_none; +end; + +end. diff --git a/mseide-msegui/lib/common/container/msehash.pas b/mseide-msegui/lib/common/container/msehash.pas new file mode 100644 index 0000000..41331f7 --- /dev/null +++ b/mseide-msegui/lib/common/container/msehash.pas @@ -0,0 +1,3280 @@ +{ MSEgui Copyright (c) 1999-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msehash; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface +uses + msestrings,msetypes; +// +//todo: use objects instead of records +// +type + identty = card32; + pidentty = ^identty; + hashvaluety = card32; + phashvaluety = ^hashvaluety; + hashoffsetty = int32;//ptruint; + phashoffsetty = ^hashoffsetty; + hashoffsetarty = array of hashoffsetty; + + hashheaderty = record + prevhash: hashoffsetty; //offset from liststart + nexthash: hashoffsetty; //offset from liststart + prevlist: hashoffsetty; //memory offset to previous item + nextlist: hashoffsetty; //memory offset to next item + hash: hashvaluety; +//dummy: card32; + end; + phashheaderty = ^hashheaderty; +{ + hashdatadataty = record + end; + phashdatadataty = ^hashdatadataty; +} + hashdataty = record + header: hashheaderty; +// data: hashdatadataty; + end; + phashdataty = ^hashdataty; + + hashiteratorprocty = procedure(const aitem: phashdataty) of object; + internalhashiteratorprocty = procedure(const aitem: phashdataty) of object; + keyhashiteratorprocty = procedure(const aitem: phashdataty) of object; + findcheckprocty = procedure(const aitem: phashdataty; + var accept: boolean) of object; + + hashliststatety = (hls_needsnull,hls_needsinit,hls_needsfinalize, + hls_destroying); + hashliststatesty = set of hashliststatety; + + thashdatalist = class + private +// fdatasize: integer; + frecsize: int32; + fcapacity: int32; + fcount: int32; + fassignedfirst: hashoffsetty; //offset to fdata + fassignedlast: hashoffsetty; //offset to fdata + fdeletedroot: hashoffsetty; //offset to fdata + fcurrentitem: hashoffsetty; //offset to fdata.data + fdestpo: phashdataty; + procedure setcapacity(const avalue: integer); + procedure moveitem(const aitem: phashdataty); + function getdatasize: int32; + protected + fdata: pointer; //first record is a dummy + fmask: hashvaluety; + fhashtable: hashoffsetarty;//ptruintarty; + fstate: hashliststatesty; + {$ifdef mse_debug_hash} + procedure checkhash; + procedure checkexists(const aitem: phashdataty); + procedure checknotexists(const aitem: phashdataty); + {$endif} + property data: pointer read fdata; + property assignedfirst: hashoffsetty read fassignedfirst; + property assignedlast: hashoffsetty read fassignedlast; + function getdatapoornil(const aoffset: hashoffsetty): pointer; inline; + function getdatapo(const aoffset: hashoffsetty): pointer; inline; + function getdataoffs(const adata: pointer): hashoffsetty; inline; + function internaladd(const akey): phashdataty; + function internaladdhash(hash1: hashvaluety): phashdataty; + procedure inserthash(ahash: hashvaluety; const adata: phashdataty); + procedure removehash(aitem: phashdataty); // does not delete ithem + procedure internaldeleteitem(const aitem: phashdataty); overload; +// procedure internaldeleteitem(const aitem: phashdatadataty); overload; + procedure internaldelete(const aoffset: hashoffsetty); + function internaldelete(const akey; const all: boolean): boolean; + function internalfind(const akey): phashdataty; overload; + function internalfind(const akey; + hash1: hashvaluety): phashdataty; overload; + function internalfind(const akey; out acount: integer): phashdataty; overload; + function internalfind(const akey; + const acheckproc: findcheckprocty): phashdataty; overload; + function internalfind(const akey; + const acheckproc: findcheckprocty; + out acount: integer): phashdataty; overload; + function internalfindexact(const akey): phashdataty; overload; + function internalfindexact(const akey; + out acount: integer): phashdataty; overload; + procedure checkexact(const aitem: phashdataty; var accept: boolean) virtual; + function hashkey(const akey): hashvaluety; virtual; abstract; + function checkkey(const akey; + const aitem: phashdataty): boolean; virtual; abstract; + function getrecordsize(): int32 virtual abstract; + procedure rehash; + procedure grow; + procedure inititem(const aitem: phashdataty) virtual; + procedure finalizeitem(const aitem: phashdataty) virtual; + procedure internaliterate( + const aiterator: internalhashiteratorprocty); overload; + procedure iterate(const akey; + const aiterator: keyhashiteratorprocty); overload; + function internalfirstx: phashdataty; + function internallastx: phashdataty; + function internalnextx: phashdataty; + function internalprevx: phashdataty; + public + constructor create(); + destructor destroy; override; + procedure clear; virtual; + procedure reset; //next next() will return first, next prev() will return last + property datasize: int32 read getdatasize; + property capacity: integer read fcapacity write setcapacity; + property count: integer read fcount; + procedure mark(out ref: hashoffsetty); + procedure release(const ref: hashoffsetty); + function absdata(const ref: ptrint): pointer; + //returns pointer to hashdataty.data from mark(ref) + property recsize: int32 read frecsize; + procedure iterate(const aiterator: hashiteratorprocty); overload; + end; + + integerdataty = record + key: integer; +// data: record end; + end; + pintegerdataty = ^integerdataty; + integerhashdataty = record + header: hashheaderty; + data: integerdataty; + end; + pintegerhashdataty = ^integerhashdataty; + + tintegerhashdatalist = class(thashdatalist) + private + protected + function hashkey(const akey): hashvaluety; override; + function checkkey(const akey; const aitem: phashdataty): boolean; override; + function getrecordsize(): int32 override; + public +// constructor create(); + function add(const akey: integer): pintegerhashdataty; + function addunique(const akey: integer): pintegerhashdataty; + function addunique(const akey: integer; + out adata: pintegerhashdataty): boolean; + //true if new + function find(const akey: integer): pintegerhashdataty; + function delete(const akey: integer; + const all: boolean = false): boolean; overload; + //true if found + function first: pintegerhashdataty; + function next: pintegerhashdataty; //wraps to first after last + function last: pintegerhashdataty; + function prev: pintegerhashdataty; //wraps to last after first + end; + + doubleintegerty = record + a: integer; + b: integer; + end; + doubleintegerdataty = record + key: doubleintegerty; +// data: record end; + end; + pdoubleintegerdataty = ^doubleintegerdataty; + doubleintegerhashdataty = record + header: hashheaderty; + data: doubleintegerdataty; + end; + pdoubleintegerhashdataty = ^doubleintegerhashdataty; + + tdoubleintegerhashdatalist = class(thashdatalist) + private + protected + function hashkey(const akey): hashvaluety; override; + function checkkey(const akey; const aitem: phashdataty): boolean; override; + function getrecordsize(): int32 override; + public +// constructor create(const datasize: integer); + function add(const akeya,akeyb: integer): pdoubleintegerhashdataty; + function addunique(const akeya,akeyb: integer): pdoubleintegerhashdataty; + function addunique(const akeya,akeyb: integer; + out adata: pdoubleintegerhashdataty): boolean; + //true if new + function find(const akeya,akeyb: integer): pdoubleintegerhashdataty; + function delete(const akeya,akeyb: integer; + const all: boolean = false): boolean; overload; + //true if found + function first: pdoubleintegerhashdataty; + function next: pdoubleintegerhashdataty; //wraps to first after last + function last: pdoubleintegerhashdataty; + function prev: pdoubleintegerhashdataty; //wraps to last after first + end; + + tripleintegerty = record + a: int32; + b: int32; + c: int32; + end; + tripleintegerdataty = record + key: tripleintegerty; +// data: record end; + end; + ptripleintegerdataty = ^tripleintegerdataty; + tripleintegerhashdataty = record + header: hashheaderty; + data: tripleintegerdataty; + end; + ptripleintegerhashdataty = ^tripleintegerhashdataty; + + ttripleintegerhashdatalist = class(thashdatalist) + private + protected + function hashkey(const akey): hashvaluety; override; + function checkkey(const akey; const aitem: phashdataty): boolean; override; + function getrecordsize(): int32 override; + public +// constructor create(const datasize: integer); + function add(const akeya,akeyb,akeyc: int32): ptripleintegerhashdataty; + function addunique(const akeya,akeyb,akeyc: int32): ptripleintegerhashdataty; + function addunique(const akeya,akeyb,akeyc: int32; + out adata: ptripleintegerhashdataty): boolean; + //true if new + function find(const akeya,akeyb,akeyc: int32): ptripleintegerhashdataty; + function delete(const akeya,akeyb,akeyc: int32; + const all: boolean = false): boolean; overload; + //true if found + function first: ptripleintegerhashdataty; + function next: ptripleintegerhashdataty; //wraps to first after last + function last: ptripleintegerhashdataty; + function prev: ptripleintegerhashdataty; //wraps to last after first + end; + + int32int32dataty = record + key: int32; + data: int32; + end; + pint32int32dataty = ^int32int32dataty; + int32int32hashdataty = record + header: hashheaderty; + data: int32int32dataty; + end; + pint32int32hashdataty = ^int32int32hashdataty; + + int32int32iteratorprocty = + procedure(const aitem: pint32int32hashdataty) of object; + + tint32int32hashdatalist = class(tintegerhashdatalist) + protected + function getrecordsize(): int32 override; + public + procedure add(const akey: int32; const avalue: int32); + function addunique(const akey: int32; const avalue: int32): boolean; + //true if found + function find(const akey: int32): int32; overload; + function find(const akey: int32; out avalue: int32): boolean; overload; + function first: pint32int32hashdataty; + function next: pint32int32hashdataty; //wraps to first after last + function last: pint32int32hashdataty; + function prev: pint32int32hashdataty; //wraps to last after first + end; + + pointerdataty = record + key: pointer; +// data: record end; + end; + ppointerdataty = ^pointerdataty; + pointerhashdataty = record + header: hashheaderty; + data: pointerdataty; + end; + ppointerhashdataty = ^pointerhashdataty; + + tpointerhashdatalist = class(thashdatalist) + private + protected + function hashkey(const akey): hashvaluety; override; + function checkkey(const akey; const aitem: phashdataty): boolean; override; + function getrecordsize(): int32 override; + public +// constructor create(const datasize: integer); + function add(const akey: pointer): ppointerhashdataty; + function addunique(const akey: pointer): ppointerhashdataty; + function find(const akey: pointer): ppointerhashdataty; + function delete(const akey: pointer; + const all: boolean = false): boolean; overload; + //true if found + function first: ppointerhashdataty; + function next: ppointerhashdataty; //wraps to first after last + function last: ppointerhashdataty; + function prev: ppointerhashdataty; //wraps to last after first + end; + + pointerint32dataty = record + key: pointer; + data: int32; + end; + ppointerint32dataty = ^pointerint32dataty; + pointerint32hashdataty = record + header: hashheaderty; + data: pointerint32dataty; + end; + ppointerint32hashdataty = ^pointerint32hashdataty; + + pointerint32iteratorprocty = + procedure(const aitem: ppointerint32hashdataty) of object; + + tpointerint32hashdatalist = class(tpointerhashdatalist) + protected + function getrecordsize(): int32 override; + public + procedure add(const akey: pointer; const avalue: int32); + function addunique(const akey: pointer; const avalue: int32): boolean; + //true if found + function find(const akey: pointer): int32; overload; + function find(const akey: pointer; out avalue: int32): boolean; overload; + function first: ppointerint32hashdataty; + function next: ppointerint32hashdataty; //wraps to first after last + function last: ppointerint32hashdataty; + function prev: ppointerint32hashdataty; //wraps to last after first + end; + + ptruintdataty = record + key: ptruint; +// data: record end; + end; + pptruintdataty = ^ptruintdataty; + ptruinthashdataty = record + header: hashheaderty; + data: ptruintdataty; + end; + pptruinthashdataty = ^ptruinthashdataty; + + tptruinthashdatalist = class(thashdatalist) + private + protected + function hashkey(const akey): hashvaluety; override; + function checkkey(const akey; const aitem: phashdataty): boolean; override; + function getrecordsize(): int32 override; + public +// constructor create(const datasize: integer); + function add(const akey: ptruint): pptruinthashdataty; + function addunique(const akey: ptruint): pptruinthashdataty; + function find(const akey: ptruint): pptruinthashdataty; + function delete(const akey: ptruint; + const all: boolean = false): boolean; overload; + //true if found + function first: pptruinthashdataty; + function next: pptruinthashdataty; //wraps to first after last + function last: pptruinthashdataty; + function prev: pptruinthashdataty; //wraps to last after first + end; + + pointerptruintdataty = record + key: ptruint; + data: pointer; + end; + ppointerptruintdataty = ^pointerptruintdataty; + pointerptruinthashdataty = record + header: hashheaderty; + data: pointerptruintdataty; + end; + ppointerptruinthashdataty = ^pointerptruinthashdataty; + + pointerptruintiteratorprocty = + procedure(const aitem: pointerptruinthashdataty) of object; + + tpointerptruinthashdatalist = class(tptruinthashdatalist) + private + fpointerparam: pointer; + protected + procedure checkexact(const aitem: phashdataty; + var accept: boolean); override; + function getrecordsize(): int32 override; + public +// constructor create; + procedure add(const akey: ptruint; const avalue: pointer); + function addunique(const akey: ptruint; const avalue: pointer): boolean; + //true if found + procedure delete(const akey: ptruint; const avalue: pointer); overload; + function find(const akey: ptruint): pointer; overload; + function find(const akey: ptruint; out avalue: pointer): boolean; overload; + function first: ppointerptruinthashdataty; + function next: ppointerptruinthashdataty; //wraps to first after last + function last: ppointerptruinthashdataty; + function prev: ppointerptruinthashdataty; //wraps to last after first + procedure iterate(const akey: ptruint; + const aiterator: pointerptruintiteratorprocty); overload; + end; + + ansistringptruintdataty = record + key: ptruint; + data: ansistring; + end; + pansistringptruintdataty = ^ansistringptruintdataty; + ansistringptruinthashdataty = record + header: hashheaderty; + data: ansistringptruintdataty; + end; + pansistringptruinthashdataty = ^ansistringptruinthashdataty; + + ansistringptruintiteratorprocty = + procedure(const aitem: pansistringptruinthashdataty) of object; + + tansistringptruinthashdatalist = class(tptruinthashdatalist) + private + fansistringparam: ansistring; + protected + procedure checkexact(const aitem: phashdataty; var accept: boolean) override; + procedure finalizeitem(const aitem: phashdataty) override; + function getrecordsize(): int32 override; + public + constructor create; + procedure add(const akey: ptruint; const avalue: ansistring); + function addunique(const akey: ptruint; const avalue: ansistring): boolean; + //true if found + procedure delete(const akey: ptruint; const avalue: ansistring) overload; + function find(const akey: ptruint): ansistring overload; + function find(const akey: ptruint; out avalue: ansistring): boolean overload; + function first: pansistringptruinthashdataty; + function next: pansistringptruinthashdataty; //wraps to first after last + function last: pansistringptruinthashdataty; + function prev: pansistringptruinthashdataty; //wraps to last after first + procedure iterate(const akey: ptruint; + const aiterator: ansistringptruintiteratorprocty) overload; + function setdata(const akey: ptruint; const avalue: ansistring): boolean; + //false if not found + end; + + msestringptruintdataty = record + key: ptruint; + data: msestring; + end; + pmsestringptruintdataty = ^msestringptruintdataty; + msestringptruinthashdataty = record + header: hashheaderty; + data: msestringptruintdataty; + end; + pmsestringptruinthashdataty = ^msestringptruinthashdataty; + + msestringptruintiteratorprocty = + procedure(const aitem: pmsestringptruinthashdataty) of object; + + tmsestringptruinthashdatalist = class(tptruinthashdatalist) + private + fmsestringparam: msestring; + protected + procedure checkexact(const aitem: phashdataty; + var accept: boolean); override; + procedure finalizeitem(const aitem: phashdataty); override; + function getrecordsize(): int32 override; + public + constructor create; + procedure add(const akey: ptruint; const avalue: msestring); + function addunique(const akey: ptruint; const avalue: msestring): boolean; + //true if found + procedure delete(const akey: ptruint; const avalue: msestring); overload; + function find(const akey: ptruint): msestring; overload; + function find(const akey: ptruint; out avalue: msestring): boolean; overload; + function first: pmsestringptruinthashdataty; + function next: pmsestringptruinthashdataty; //wraps to first after last + function last: pmsestringptruinthashdataty; + function prev: pmsestringptruinthashdataty; //wraps to last after first + procedure iterate(const akey: ptruint; + const aiterator: msestringptruintiteratorprocty); overload; + function setdata(const akey: ptruint; const avalue: msestring): boolean; + //false if not found + end; + + ansistringdataty = record + key: ansistring; +// data: record end; + end; + pansistringdataty = ^ansistringdataty; + ansistringhashdataty = record + header: hashheaderty; + data: ansistringdataty; + end; + pansistringhashdataty = ^ansistringhashdataty; + + ansistringhashiteratorprocty = + procedure(const aitem: pansistringhashdataty) of object; + + tansistringhashdatalist = class(thashdatalist) + private + protected + function hashkey(const akey): hashvaluety; override; + function checkkey(const akey; const aitem: phashdataty): boolean; override; + function hashlkey(const akey: lstringty): hashvaluety; + function checklkey(const akey: lstringty; + const aitemdata: ansistringdataty): boolean; + procedure finalizeitem(const aitem: phashdataty) override; + function getrecordsize(): int32 override; + public + constructor create(); + function add(const akey: ansistring): pansistringhashdataty; + function addunique(const akey: ansistring): pansistringhashdataty; + function find(const akey: ansistring): pansistringhashdataty; overload; + function find(const akey: lstringty): pansistringhashdataty; overload; + function delete(const akey: ansistring; + const all: boolean = false): boolean; overload; + //true if found + function delete(const akey: lstringty; + const all: boolean = false): boolean; overload; + //true if found + function first: pansistringhashdataty; + function next: pansistringhashdataty; //wraps to first after last + function last: pansistringhashdataty; + function prev: pansistringhashdataty; //wraps to last after first + procedure iterate(const akey: ansistring; + const aiterator: ansistringhashiteratorprocty); overload; + end; + + pointeransistringdataty = record + key: ansistring; + data: pointer; + end; + ppointeransistringdataty = ^pointeransistringdataty; + pointeransistringhashdataty = record + header: hashheaderty; + data: pointeransistringdataty; + end; + ppointeransistringhashdataty = ^pointeransistringhashdataty; + + pointeransistringiteratorprocty = + procedure(const aitem: ppointeransistringhashdataty) of object; + + tpointeransistringhashdatalist = class(tansistringhashdatalist) + private + fpointerparam: pointer; + protected + procedure checkexact(const aitem: phashdataty; var accept: boolean) override; + function getrecordsize(): int32 override; + public +// constructor create; + procedure add(const akey: ansistring; const avalue: pointer); overload; + procedure add(const keys: array of string; + startindex: pointer = pointer($00000001)); overload; + //data = arrayindex + startindex + function addunique(const akey: ansistring; const avalue: pointer): boolean; + //true if found + procedure delete(const akey: ansistring; const avalue: pointer) overload; + function find(const akey: ansistring): pointer; overload; + function find(const akey: ansistring; out avalue: pointer): boolean overload; + function find(const akey: lstringty): pointer; overload; + function first: ppointeransistringhashdataty; + function next: ppointeransistringhashdataty; //wraps to first after last + function last: ppointeransistringhashdataty; + function prev: ppointeransistringhashdataty; //wraps to last after first + procedure iterate(const akey: ansistring; + const aiterator: pointeransistringiteratorprocty) overload; + end; + + msestringdataty = record + key: msestring; +// data: record end; + end; + pmsestringdataty = ^msestringdataty; + msestringhashdataty = record + header: hashheaderty; + data: msestringdataty; + end; + pmsestringhashdataty = ^msestringhashdataty; + + msestringiteratorprocty = + procedure(const aitem: pmsestringhashdataty) of object; + + tmsestringhashdatalist = class(thashdatalist) + private + protected + function hashkey(const akey): hashvaluety; override; + function checkkey(const akey; const aitem: phashdataty): boolean; override; + function hashlkey(const akey: lmsestringty): hashvaluety; + function checklkey(const akey: lmsestringty; + const aitemdata: msestringdataty): boolean; + procedure finalizeitem(const aitem: phashdataty) override; + function getrecordsize(): int32 override; + public + constructor create(); + function add(const akey: msestring): pmsestringhashdataty; + function addunique(const akey: msestring): pmsestringhashdataty; + function find(const akey: msestring): pmsestringhashdataty; overload; + function find(const akey: lmsestringty): pmsestringhashdataty; overload; + function find(const akey: msestring; + out acount: integer): pmsestringhashdataty; overload; + function delete(const akey: msestring; + const all: boolean = false): boolean; overload; + //true if found + function delete(const akey: lmsestringty; + const all: boolean = false): boolean; overload; + //true if found + function first: pmsestringhashdataty; + function next: pmsestringhashdataty; //wraps to first after last + function last: pmsestringhashdataty; + function prev: pmsestringhashdataty; //wraps to last after first + procedure iterate(const akey: msestring; + const aiterator: msestringiteratorprocty); overload; + end; + + pointermsestringdataty = record + key: msestring; + data: pointer; + end; + ppointermsestringdataty = ^pointermsestringdataty; + pointermsestringhashdataty = record + header: hashheaderty; + data: pointermsestringdataty; + end; + ppointermsestringhashdataty = ^pointermsestringhashdataty; + + pointermsestringiteratorprocty = + procedure(const aitem: ppointermsestringhashdataty) of object; + + tpointermsestringhashdatalist = class(tmsestringhashdatalist) + private + fpointerparam: pointer; + protected + procedure checkexact(const aitem: phashdataty; var accept: boolean) override; + function getrecordsize(): int32 override; + public +// constructor create; + procedure add(const akey: msestring; const avalue: pointer); + function addunique(const akey: msestring; const avalue: pointer): boolean; + //true if found + procedure delete(const akey: msestring; const avalue: pointer); + function find(const akey: msestring): pointer; overload; + function find(const akey: msestring; out avalue: pointer): boolean; overload; + function find(const akey: msestring; out avalue: pointer; + out acount: integer): boolean; overload; + function find(const akey: lmsestringty): pointer; overload; + function first: ppointermsestringhashdataty; + function next: ppointermsestringhashdataty; //wraps to first after last + function last: ppointermsestringhashdataty; + function prev: ppointermsestringhashdataty; //wraps to last after first + procedure iterate(const akey: msestring; + const aiterator: pointermsestringiteratorprocty); overload; + end; + + integermsestringdataty = record + key: msestring; + data: integer; + end; + pintegermsestringdataty = ^integermsestringdataty; + integermsestringhashdataty = record + header: hashheaderty; + data: integermsestringdataty; + end; + pintegermsestringhashdataty = ^integermsestringhashdataty; + + integermsestringiteratorprocty = + procedure(const aitem: pintegermsestringhashdataty) of object; + + tintegermsestringhashdatalist = class(tmsestringhashdatalist) + private + fintegerparam: integer; + protected + procedure checkexact(const aitem: phashdataty; var accept: boolean) override; + function getrecordsize(): int32 override; + public +// constructor create; + procedure add(const akey: msestring; const avalue: integer); + function addunique(const akey: msestring; const avalue: integer): boolean; + //true if found + procedure delete(const akey: msestring; const avalue: integer); + function find(const akey: msestring): integer; overload; //-1 if not found + function find(const akey: msestring; out avalue: integer): boolean; overload; + function find(const akey: msestring; out avalue: integer; + out acount: integer): boolean; overload; + function find(const akey: lmsestringty): integer; overload; //-1 if not found + function first: pintegermsestringhashdataty; + function next: pintegermsestringhashdataty; //wraps to first after last + function last: pintegermsestringhashdataty; + function prev: pintegermsestringhashdataty; //wraps to last after first + procedure iterate(const akey: msestring; + const aiterator: integermsestringiteratorprocty); overload; + end; + + objectmsestringdataty = record + key: msestring; + data: tobject; + end; + pobjectmsestringdataty = ^objectmsestringdataty; + objectmsestringhashdataty = record + header: hashheaderty; + data: objectmsestringdataty; + end; + pobjectmsestringhashdataty = ^objectmsestringhashdataty; + + objectmsestringiteratorprocty = + procedure(const aitem: pobjectmsestringhashdataty) of object; + + tobjectmsestringhashdatalist = class(tpointermsestringhashdatalist) + protected + fownsobjects: boolean; + procedure finalizeitem(const aitem: phashdataty) override; + public + constructor create(const aownsobjects: boolean = true); + procedure add(const akey: msestring; const avalue: tobject); + function addunique(const akey: msestring; const avalue: tobject): boolean; + //true if found + procedure delete(const akey: msestring; const avalue: tobject); + function find(const akey: msestring): tobject; overload; + function find(const akey: msestring; out avalue: tobject): boolean; overload; + function find(const akey: msestring; out avalue: tobject; + out acount: integer): boolean; overload; + function first: pobjectmsestringhashdataty; + function next: pobjectmsestringhashdataty; //wraps to first after last + function last: pobjectmsestringhashdataty; + function prev: pobjectmsestringhashdataty; //wraps to last after first + procedure iterate(const akey: msestring; + const aiterator: objectmsestringiteratorprocty); overload; + end; + +function scramble(const avalue: hashvaluety): hashvaluety; inline; +function datahash(const data; len: integer): longword; //simple +function datahash2(const data; len: integer): longword; +function stringhash(const key: string): longword; overload; +function stringhash(const key: lstringty): longword; overload; +function stringhash(const key: msestring): longword; overload; +function stringhash(const key: lmsestringty): longword; overload; +function pointerhash(const key: pointer): longword; inline; + +procedure addoffs(var dest: hashoffsetarty; const value: hashoffsetty); + +implementation +uses + sysutils,msebits; + +function scramble(const avalue: hashvaluety): hashvaluety; +begin + result:= ((avalue xor (avalue shr 8)) xor (avalue shr 16)) xor (avalue shr 24); +end; + +function datahash(const data; len: integer): longword; +var + po1: pbyte; + int1: integer; + ca1: longword; +begin + ca1:= 0; + po1:= @data; + for int1:= len - 1 downto 0 do begin + inc(ca1,po1^); + inc(po1); + end; + result:= ca1; +end; + +function datahash2(const data; len: integer): longword; +var + po1: pbyte; + int1: integer; + ca1: longword; +begin + ca1:= 0; + po1:= @data; + for int1:= len - 1 downto 0 do begin + ca1:= ((ca1 shl 2) or (ca1 shr (sizeof(ca1) * 8 - 2))) xor po1^; + inc(po1); + end; + result:= ca1; +end; + +function stringhash(const key: string): longword; overload; +var + int1: integer; +begin + result := 0; + for int1 := 1 to length(key) do begin + result := ((result shl 2) or (result shr (sizeof(result) * 8 - 2))) xor + ord(key[int1]); + end; +end; + +function stringhash(const key: lstringty): longword; overload; +var + int1: integer; + po: pcharaty; +begin + result := 0; + po:= pointer(key.po); + for int1:= 0 to key.len - 1 do begin; + result:= ((result shl 2) or (result shr (sizeof(result) * 8 - 2))) xor + ord(po^[int1]); + end; +end; + +function stringhash(const key: msestring): longword; overload; +var + int1: integer; +begin + result:= 0; + for int1 := 1 to length(key) do begin + result := ((result shl 2) or (result shr (sizeof(result) * 8 - 2))) xor + ord(key[int1]); + end; +end; + +function stringhash(const key: lmsestringty): longword; overload; +var + int1: integer; + po: pmsecharaty; +begin + result:= 0; + po:= pointer(key.po); + for int1:= 0 to key.len - 1 do begin + result := ((result shl 2) or (result shr (sizeof(result) * 8 - 2))) xor + ord(po^[int1]); + end; +end; + +function pointerhash(const key: pointer): longword; inline; +begin +{$ifdef cpu64} + result:= scramble((ptruint(key) xor (ptruint(key) shr 32)) xor + (ptruint(key) shr 2)); +{$else} + result:= scramble(ptruint(key) xor (ptruint(key) shr 2)); +{$endif} +end; + +procedure addoffs(var dest: hashoffsetarty; const value: hashoffsetty); +var + i1: int32; +begin + i1:= length(dest); + setlength(dest,i1+1); + dest[i1]:= value; +end; + +{ thashdatalist } + +constructor thashdatalist.create(); +begin +// fdatasize:= datasize; +// frecsize:= (sizeof(hashheaderty) + datasize + 3) and not 3; + frecsize:= (getrecordsize() + 3) and not 3; + inherited create; +end; + +destructor thashdatalist.destroy; +begin + include(fstate,hls_destroying); + clear; + inherited; +end; + +procedure thashdatalist.moveitem(const aitem: phashdataty); +begin + move((pointer(aitem)+sizeof(hashheaderty))^, + (pointer(fdestpo)+sizeof(hashheaderty))^, + frecsize-sizeof(hashheaderty)); + with fdestpo^.header do begin + nextlist:= frecsize; + prevlist:= -frecsize; + hash:= aitem^.header.hash; + end; + inc(pchar(fdestpo),frecsize); +end; + +function thashdatalist.getdatasize: int32; +begin + result:= fcount * frecsize; +end; + +function thashdatalist.getdatapoornil(const aoffset: hashoffsetty): pointer; +begin + result:= nil; + if aoffset <> 0 then begin + result:= fdata+aoffset; + end; +end; + +procedure thashdatalist.setcapacity(const avalue: int32); +var + int1,int2: integer; + po1: pointer; + puint1: hashoffsetty; +begin + if avalue <> fcapacity then begin +{$ifdef mse_debug_hash} + checkhash; +{$endif} + if avalue < fcount then begin + raise exception.create('Capacity < count.'); + end; + if avalue >= {high(ptruint)} maxint div frecsize then begin + raise exception.create('Capacity too big.'); + end; + + if (avalue < fcapacity) and (fdeletedroot <> 0) and + (fcount > 0) then begin //packing necessary + getmem(po1,(avalue+1)*frecsize); + if po1 = nil then begin + raise exception.create('Out of memory.'); + end; + puint1:= frecsize*fcount; + if fcount > 0 then begin + fdestpo:= pointer(pchar(po1) + frecsize); + internaliterate({$ifdef FPC}@{$endif}moveitem); + fassignedlast:= puint1; + fassignedfirst:= frecsize; + end + else begin + fassignedlast:= 0; + fassignedfirst:= 0; + end; + freemem(fdata); + fdata:= po1; + phashdataty(fdata+frecsize)^.header.prevlist:= 0; //end marker + phashdataty(fdata+puint1)^.header.nextlist:= 0; //end marker + if (hls_needsnull in fstate) and (avalue > fcount) then begin + fillchar((pchar(fdata)+puint1+frecsize)^,(avalue-fcount)*frecsize,0); + end; + fdeletedroot:= 0; + end + else begin + {$ifdef FPC} + if reallocmem(fdata,(avalue+1)*frecsize) = nil then begin + raise exception.create('Out of memory.'); + end; + {$else} + reallocmem(fdata,(avalue+1)*frecsize); + {$endif} + if (hls_needsnull in fstate) and (avalue > fcapacity) then begin + fillchar((pchar(fdata)+fcapacity*frecsize+frecsize)^, + (avalue-fcapacity)*frecsize,0); + end; + end; +// phashdataty(fdata)^.header.prevlist:= 0; //end marker +// phashdataty(fdata)^.header.nextlist:= 0; //end marker + //first record is a dummy so offset = 0 -> not assigned + fcapacity:= avalue; + int2:= highestbit(avalue); + int1:= bits[int2]; + if int1 < avalue then begin + int1:= int1 * 2; + inc(int2); + end; + if int1 <> length(fhashtable) then begin + if fhashtable <> nil then begin + fillchar(pointer(fhashtable)^,length(fhashtable)*sizeof(fhashtable[0]),0); + end; + setlength(fhashtable,int1); //additional length nulled by setlength + fmask:= int1 - 1; +// fhashshift:= sizeof(hashvaluety)*8 - int2; + rehash; + end; +{$ifdef mse_debug_hash} + checkhash; +{$endif} + end; +end; + +procedure thashdatalist.rehash; +var + puint2: hashoffsetty; + po1: phashdataty; + po2: phashoffsetty; +begin + if fassignedfirst <> 0 then begin + po1:= pointer(pchar(fdata) + fassignedfirst); + while true do begin + if po1^.header.prevhash >= 0 then begin //hash removed otherwise + po2:= phashoffsetty(pchar(fhashtable) + + (po1^.header.hash and fmask)*sizeof(hashoffsetty)); + puint2:= po2^; + po1^.header.nexthash:= puint2; + po1^.header.prevhash:= 0; + po2^:= pchar(po1) - fdata; + phashdataty(pchar(fdata)+puint2)^.header.prevhash:= po2^; + end; + if po1^.header.nextlist = 0 then begin + break; + end; + inc(pchar(po1),po1^.header.nextlist); + end; + end; +{$ifdef mse_debug_hash} + checkhash; +{$endif} +end; + +procedure thashdatalist.grow; +begin + capacity:= 2*capacity + 256; +end; + +function thashdatalist.internaladdhash(hash1: hashvaluety): phashdataty; +var + puint1,puint2: hashoffsetty;//ptruint; +// hash1: hashvaluety; +begin +{$ifdef mse_debug_hash} + checkhash; +{$endif} + if count = capacity then begin + grow; + end; + if fdeletedroot <> 0 then begin + result:= phashdataty(pchar(fdata)+fdeletedroot); + inc(fdeletedroot,result^.header.nextlist); + if result^.header.nextlist = 0 then begin + fdeletedroot:= 0; + end; + if hls_needsnull in fstate then begin + fillchar((pointer(result)+sizeof(hashheaderty))^, + frecsize-sizeof(hashheaderty),0); + end; + end + else begin + result:= phashdataty(pchar(fdata) + count * frecsize + frecsize); + end; +{$ifdef mse_debug_hash} + checknotexists(result); +{$endif} + result^.header.prevhash:= 0; + result^.header.hash:= hash1; + hash1:= hash1 and fmask; + puint2:= fhashtable[hash1]; + result^.header.nexthash:= puint2; + puint1:= pchar(result) - fdata; + fhashtable[hash1]:= puint1; + phashdataty(pchar(fdata)+puint2)^.header.prevhash:= puint1; + //[0] is dummy + if fcount = 0 then begin + result^.header.prevlist:= 0; + fassignedfirst:= puint1; + end + else begin + result^.header.prevlist:= fassignedlast-puint1; + //memory offset to next item + phashdataty(pchar(fdata)+fassignedlast)^.header.nextlist:= + -result^.header.prevlist; + //memory offset to previous item + end; + result^.header.nextlist:= 0; + fassignedlast:= puint1; //new item is last + inc(fcount); + if hls_needsinit in fstate then begin + inititem(result); + end; +{$ifdef mse_debug_hash} + checkhash; +{$endif} +end; + +function thashdatalist.internaladd(const akey): phashdataty; +begin + result:= internaladdhash(hashkey(akey)); +end; + +procedure thashdatalist.inserthash(ahash: hashvaluety; + const adata: phashdataty); +var + puint1,puint2: hashoffsetty;//ptruint; +begin + adata^.header.prevhash:= 0; + adata^.header.hash:= ahash; + ahash:= ahash and fmask; + puint2:= fhashtable[ahash]; + adata^.header.nexthash:= puint2; + puint1:= pointer(adata) - fdata; + fhashtable[ahash]:= puint1; + phashdataty(fdata+puint2)^.header.prevhash:= puint1; + //[0] is dummy +end; + +procedure thashdatalist.removehash(aitem: phashdataty); +begin + with aitem^.header do begin + if nexthash <> 0 then begin + phashdataty(pchar(fdata)+nexthash)^.header.prevhash:= prevhash; + end; + if prevhash <> 0 then begin + phashdataty(pchar(fdata)+prevhash)^.header.nexthash:= nexthash; + end + else begin + fhashtable[hash and fmask]:= nexthash; + end; + prevhash:= -1; //nothashed mrker + end; +end; + +procedure thashdatalist.internaldeleteitem(const aitem: phashdataty); +var + puint1: hashoffsetty; + bo1: boolean; +begin + if aitem <> nil then begin +{$ifdef mse_debug_hash} + checkexists(aitem); +{$endif} + if pointer(aitem) = pointer(pchar(fdata) + fcurrentitem) then begin + fcurrentitem:= 0; + end; + if hls_needsfinalize in fstate then begin + finalizeitem(aitem); + end; + puint1:= pchar(aitem) - fdata; + with aitem^.header do begin +{$ifdef mse_debug_hash} + if nexthash <> 0 then begin + checkexists(phashdataty(pchar(fdata)+nexthash)); + end; + if prevhash <> 0 then begin + checkexists(phashdataty(pchar(fdata)+prevhash)); + end; +{$endif} + if nexthash <> 0 then begin + phashdataty(pchar(fdata)+nexthash)^.header.prevhash:= prevhash; + end; + if prevhash <> 0 then begin + phashdataty(pchar(fdata)+prevhash)^.header.nexthash:= nexthash; + end + else begin + fhashtable[hash and fmask]:= nexthash; + end; + bo1:= false; + if puint1 <> fassignedfirst then begin //not first + inc(phashdataty(pchar(aitem)+prevlist)^.header.nextlist,nextlist); + end + else begin + bo1:= true; + inc(fassignedfirst,nextlist); + phashdataty(fdata+fassignedfirst)^.header.prevlist:= 0; + end; + if puint1 <> fassignedlast then begin //not last + if not bo1 then begin + inc(phashdataty(pchar(aitem)+nextlist)^.header.prevlist,prevlist); + end; + end + else begin + inc(fassignedlast,prevlist); + phashdataty(fdata+fassignedlast)^.header.nextlist:= 0; + end; + + if fdeletedroot = 0 then begin + nextlist:= 0; + end + else begin + nextlist:= fdeletedroot - puint1; + //memory offset to next deleted item + end; + end; + fdeletedroot:= puint1; + dec(fcount); + if fcount = 0 then begin + fassignedfirst:= 0; + fassignedlast:= 0; + end; +{$ifdef mse_debug_hash} + checkhash; +{$endif} + end; +end; + +procedure thashdatalist.internaldelete(const aoffset: hashoffsetty); +begin + internaldeleteitem(fdata+aoffset); +end; + +procedure thashdatalist.mark(out ref: hashoffsetty); +begin + ref:= fassignedlast; +end; + +procedure thashdatalist.release(const ref: hashoffsetty); +var + po1,pend: phashdataty; +begin + if fassignedlast <> 0 then begin + pend:= pointer(pchar(fdata)+ref); + po1:= pointer(pchar(fdata)+fassignedlast); + while po1 <> pend do begin + internaldeleteitem(po1); + if po1^.header.prevlist = 0 then begin + break; + end; + inc(pchar(po1),po1^.header.prevlist); + end; + end; +end; + +function thashdatalist.absdata(const ref: ptrint): pointer; + //returns pointer to hashdataty.data from mark(ref) +begin + result:= fdata + ref + sizeof(hashheaderty); +end; +{ +procedure thashdatalist.internaldeleteitem(const aitem: phashdatadataty); +begin + if aitem <> nil then begin + internaldeleteitem(phashdataty(pchar(aitem)-sizeof(hashheaderty))); + end; +end; +} +function thashdatalist.internaldelete(const akey; const all: boolean): boolean; +var + po1: phashdataty; +begin + result:= false; + while true do begin + po1:= internalfind(akey); + if po1 = nil then begin + break; + end; + internaldeleteitem(po1); + result:= true; + if not all then begin + break; + end; + end; +end; + +procedure thashdatalist.clear; +begin + if fdata <> nil then begin + if hls_needsfinalize in fstate then begin + iterate({$ifdef FPC}@{$endif}finalizeitem); + end; + freemem(fdata); + fdata:= nil; + fhashtable:= nil; + fcount:= 0; + fcapacity:= 0; + fassignedfirst:= 0; //dummy item + fassignedlast:= 0; //dummy item + fdeletedroot:= 0; //dummy item + end; +end; + +procedure thashdatalist.reset; +begin + fcurrentitem:= 0; +end; + +procedure thashdatalist.iterate(const aiterator: hashiteratorprocty); +var + puint1: hashoffsetty; + po1: phashdataty; +begin + if fcount > 0 then begin + po1:= pointer(pchar(fdata) + fassignedfirst); + while true do begin + puint1:= phashheaderty(po1)^.nextlist; + aiterator(po1); + if puint1 = 0 then begin + break; + end; + inc(pchar(po1),puint1); + end; + end; +end; + +procedure thashdatalist.iterate(const akey; + const aiterator: keyhashiteratorprocty); +var + ha1: hashvaluety; + uint1: hashoffsetty; + po1: phashdataty; +begin + po1:= nil; + if count > 0 then begin + ha1:= hashkey(akey); + uint1:= fhashtable[ha1 and fmask]; + if uint1 <> 0 then begin + po1:= phashdataty(pchar(fdata) + uint1); + while true do begin + if (po1^.header.hash = ha1) and checkkey(akey,po1) then begin + aiterator(po1); + end; + if po1^.header.nexthash = 0 then begin + break; + end; + po1:= phashdataty(pchar(fdata) + po1^.header.nexthash); + end; + end; + end; +end; + +procedure thashdatalist.internaliterate( + const aiterator: internalhashiteratorprocty); +var + po1: phashdataty; +begin + if fcount > 0 then begin + po1:= pointer(pchar(fdata) + fassignedfirst); + while true do begin + aiterator(po1); + if phashheaderty(po1)^.nextlist = 0 then begin + break; + end; + inc(pchar(po1),phashheaderty(po1)^.nextlist); + end; + end; +end; + +procedure thashdatalist.inititem(const aitem: phashdataty); +begin + //dummy +end; + +procedure thashdatalist.finalizeitem(const aitem: phashdataty); +begin + //dummy +end; + +function thashdatalist.internalfind(const akey; + hash1: hashvaluety): phashdataty; +var +// ha1: hashvaluety; + uint1: hashoffsetty; + po1: phashdataty; +begin +{$ifdef mse_debug_hash} + checkhash; +{$endif} + po1:= nil; + if count > 0 then begin +// ha1:= hashkey(akey); + uint1:= fhashtable[hash1 and fmask]; + if uint1 <> 0 then begin + po1:= phashdataty(pchar(fdata) + uint1); + while true do begin + if (po1^.header.hash = hash1) and checkkey(akey,po1) then begin + break; + end; + if po1^.header.nexthash = 0 then begin + po1:= nil; + break; + end; + po1:= phashdataty(pchar(fdata) + po1^.header.nexthash); + end; + end; + end; + result:= po1; +end; + +function thashdatalist.internalfind(const akey): phashdataty; +begin + result:= internalfind(akey,hashkey(akey)); +end; + +function thashdatalist.internalfind(const akey; out acount: integer): phashdataty; +var + ha1: hashvaluety; + uint1: hashoffsetty; + po1: phashdataty; +begin + result:= nil; + acount:= 0; + if count > 0 then begin + ha1:= hashkey(akey); + uint1:= fhashtable[ha1 and fmask]; + if uint1 <> 0 then begin + po1:= phashdataty(pchar(fdata) + uint1); + while true do begin + if (po1^.header.hash = ha1) and checkkey(akey,po1) then begin + if result = nil then begin + result:= po1; + end; + inc(acount); + end + else begin + if result <> nil then begin + break; + end; + end; + if po1^.header.nexthash = 0 then begin + break; + end; + po1:= phashdataty(pchar(fdata) + po1^.header.nexthash); + end; + end; + end; +end; + +function thashdatalist.internalfind(const akey; + const acheckproc: findcheckprocty): phashdataty; +var + ha1: hashvaluety; + uint1: hashoffsetty; + po1: phashdataty; + bo1: boolean; +begin + po1:= nil; + if count > 0 then begin + ha1:= hashkey(akey); + uint1:= fhashtable[ha1 and fmask]; + if uint1 <> 0 then begin + po1:= phashdataty(pchar(fdata) + uint1); + bo1:= false; + while true do begin + if (po1^.header.hash = ha1) and checkkey(akey,po1) then begin + acheckproc(po1,bo1); + if bo1 then begin + break; + end; + end; + if po1^.header.nexthash = 0 then begin + po1:= nil; + break; + end; + po1:= phashdataty(pchar(fdata) + po1^.header.nexthash); + end; + end; + end; + result:= po1; +end; + +function thashdatalist.internalfind(const akey; + const acheckproc: findcheckprocty; + out acount: integer): phashdataty; +var + ha1: hashvaluety; + uint1: hashoffsetty; + po1: phashdataty; + bo1: boolean; +begin + result:= nil; + acount:= 0; + if count > 0 then begin + ha1:= hashkey(akey); + uint1:= fhashtable[ha1 and fmask]; + if uint1 <> 0 then begin + po1:= phashdataty(pchar(fdata) + uint1); + bo1:= false; + while true do begin + if (po1^.header.hash = ha1) and checkkey(akey,po1) then begin + acheckproc(po1,bo1); + if bo1 then begin + if result = nil then begin + result:= po1; + end; + inc(acount); + end + else begin + if result <> nil then begin + break; + end; + end; + end; + if po1^.header.nexthash = 0 then begin + break; + end; + po1:= phashdataty(pchar(fdata) + po1^.header.nexthash); + end; + end; + end; +end; + +function thashdatalist.internalfindexact(const akey): phashdataty; +begin + result:= internalfind(akey,{$ifdef FPC}@{$endif}checkexact); +end; + +function thashdatalist.internalfindexact(const akey; + out acount: integer): phashdataty; +begin + result:= internalfind(akey,{$ifdef FPC}@{$endif}checkexact,acount); +end; + +function thashdatalist.internalfirstx: phashdataty; +begin + result:= nil; + if count > 0 then begin + fcurrentitem:= fassignedfirst; + result:= fdata + fcurrentitem; + end; +end; + +function thashdatalist.internallastx: phashdataty; +begin + result:= nil; + if count > 0 then begin + fcurrentitem:= fassignedlast; + result:= fdata + fcurrentitem; + end; +end; + +function thashdatalist.internalnextx: phashdataty; +var + po1: phashdataty; +begin + result:= nil; + if count > 0 then begin + po1:= phashdataty(fdata + fcurrentitem); + if (fcurrentitem = 0) or (po1^.header.nextlist = 0) then begin + fcurrentitem:= fassignedfirst; + end + else begin + fcurrentitem:= fcurrentitem + po1^.header.nextlist; + end; + result:= fdata + fcurrentitem; + end; +end; + +function thashdatalist.internalprevx: phashdataty; +var + po1: phashdataty; +begin + result:= nil; + if count > 0 then begin + po1:= phashdataty(fdata + fcurrentitem); + if (fcurrentitem = 0) or (po1^.header.prevlist = 0) then begin + fcurrentitem:= fassignedlast; + end + else begin + fcurrentitem:= fcurrentitem + po1^.header.prevlist; + end; + result:= fdata + fcurrentitem; + end; +end; + +procedure thashdatalist.checkexact(const aitem: phashdataty; + var accept: boolean); +begin + accept:= false; //dummy +end; + +function thashdatalist.getdatapo(const aoffset: hashoffsetty): pointer; inline; +begin + result:= pchar(fdata)+aoffset; +end; + +function thashdatalist.getdataoffs(const adata: pointer): hashoffsetty; inline; +begin + result:= pchar(adata)-pchar(fdata); +end; + +{$ifdef mse_debug_hash} +procedure thashdatalist.checkhash; +var + int1,int2,int3: integer; + po1,po2: phashdataty; + uint1: hashoffsetty; +begin + if (fmask <> 0) and (fhashtable <> nil) then begin + int3:= 0; + for int1:= 0 to fmask do begin + uint1:= fhashtable[int1]; + if uint1 <> 0 then begin + inc(int3); + po1:= phashdataty(pchar(fdata) + uint1); + if po1^.header.prevhash <> 0 then begin + raise exception.create('prevhash is not 0.'); + end; + int2:= 0; + while po1^.header.nexthash <> 0 do begin + po2:= po1; + po1:= phashdataty(pchar(fdata) + po1^.header.nexthash); + if phashdataty(pchar(fdata)+po1^.header.prevhash) <> po2 then begin + raise exception.create('Wrong hash backlink.'); + end; + inc(int2); + inc(int3); + if int2 > count then begin + raise exception.create('Hash loop.'); + end; + end; + end; + end; + if int3 <> count then begin + raise exception.create('Wrong hash count.'); + end; + end; + if (fassignedfirst <> 0) or (fassignedlast <> 0) then begin + if (fassignedfirst = 0) then begin + raise exception.create('fassignedfirst 0.'); + end; + if (fassignedlast = 0) then begin + raise exception.create('fassignedlast 0.'); + end; + + int1:= 0; + po1:= fdata + fassignedfirst; + if po1^.header.prevlist <> 0 then begin + raise exception.create('fprevlist not 0.'); + end; + while true do begin + inc(int1); + if int1 > fcount then begin + raise exception.create('Forward List loop.'); + end; + if po1^.header.nextlist = 0 then begin + break; + end; + po1:= pointer(po1) + po1^.header.nextlist; + end; + if int1 <> count then begin + raise exception.create('Wrong forward list count.'); + end; + int1:= 0; + po1:= fdata + fassignedlast; + if po1^.header.nextlist <> 0 then begin + raise exception.create('fnextlist not 0.'); + end; + while true do begin + inc(int1); + if int1 > fcount then begin + raise exception.create('Backward List loop.'); + end; + if po1^.header.prevlist = 0 then begin + break; + end; + po1:= pointer(po1) + po1^.header.prevlist; + end; + if int1 <> count then begin + raise exception.create('Wrong backward list count.'); + end; + end + else begin + if fcount <> 0 then begin + raise exception.create('Wrong count.'); + end; + end; + int1:= 0; + if fdeletedroot <> 0 then begin + po1:= fdata + fdeletedroot; + while true do begin + inc(int1); + if int1 > fcapacity-fcount then begin + raise exception.create('Deleted List loop.'); + end; + if po1^.header.nextlist = 0 then begin + break; + end; + po1:= pointer(po1) + po1^.header.nextlist; + end; + end; +end; + +procedure thashdatalist.checkexists(const aitem: phashdataty); +var + int1: integer; + po1: phashdataty; + uint1: hashoffsetty; +begin + checkhash; + if fmask <> 0 then begin + for int1:= 0 to fmask do begin + uint1:= fhashtable[int1]; + if uint1 <> 0 then begin + po1:= phashdataty(pchar(fdata) + uint1); + if po1 = aitem then begin + exit; + end; + while po1^.header.nexthash <> 0 do begin + po1:= phashdataty(pchar(fdata) + po1^.header.nexthash); + if po1 = aitem then begin + exit; + end; + end; + end; + end; + raise exception.create('Hash item does not exist.'); + end; +end; + +procedure thashdatalist.checknotexists(const aitem: phashdataty); +var + int1: integer; + po1: phashdataty; + uint1: hashoffsetty; +begin + checkhash; + if fmask <> 0 then begin + for int1:= 0 to fmask do begin + uint1:= fhashtable[int1]; + if uint1 <> 0 then begin + po1:= phashdataty(pchar(fdata) + uint1); + if po1 = aitem then begin + raise exception.create('Hash item does exist.'); + end; + while po1^.header.nexthash <> 0 do begin + po1:= phashdataty(pchar(fdata) + po1^.header.nexthash); + if po1 = aitem then begin + raise exception.create('Hash item does exist.'); + end; + end; + end; + end; + end; +end; + +{$endif} + +{ tintegerhasdatalist } +{ +constructor tintegerhashdatalist.create(); +begin + inherited create(datasize + sizeof(integerhashdataty)-sizeof(hashdataty)); +end; +} +function tintegerhashdatalist.hashkey(const akey): hashvaluety; +// todo: optimize +begin + result:= scramble((integer(akey) xor (integer(akey) shr 2))); +end; + +function tintegerhashdatalist.add(const akey: integer): pintegerhashdataty; +begin + result:= pintegerhashdataty(internaladd(akey)); + result^.data.key:= akey; +end; + +function tintegerhashdatalist.find(const akey: integer): pintegerhashdataty; +begin + result:= pintegerhashdataty(internalfind(akey)); +end; + +function tintegerhashdatalist.addunique(const akey: integer): pintegerhashdataty; +begin + result:= find(akey); + if result = nil then begin + result:= add(akey); + end; +end; + +function tintegerhashdatalist.addunique(const akey: integer; + out adata: pintegerhashdataty): boolean; + //true if new +begin + adata:= find(akey); + result:= false; + if adata = nil then begin + adata:= add(akey); + result:= true; + end; +end; + +function tintegerhashdatalist.checkkey(const akey; + const aitem: phashdataty): boolean; +begin + result:= integer(akey) = pintegerhashdataty(aitem)^.data.key; +end; + +function tintegerhashdatalist.getrecordsize(): int32; +begin + result:= sizeof(integerhashdataty); +end; + +function tintegerhashdatalist.first: pintegerhashdataty; +begin + result:= pintegerhashdataty(internalfirstx); +end; + +function tintegerhashdatalist.next: pintegerhashdataty; +begin + result:= pintegerhashdataty(internalnextx); +end; + +function tintegerhashdatalist.last: pintegerhashdataty; +begin + result:= pintegerhashdataty(internallastx); +end; + +function tintegerhashdatalist.prev: pintegerhashdataty; +begin + result:= pintegerhashdataty(internalprevx); +end; + +function tintegerhashdatalist.delete(const akey: integer; + const all: boolean = false): boolean; +begin + result:= internaldelete(akey,all); +end; + +{ tdoubleintegerhashdatalist } + +function mdikey(a,b: integer): doubleintegerty; inline; +begin + result.a:= a; + result.b:= b; +end; + +function tdoubleintegerhashdatalist.hashkey(const akey): hashvaluety; +var + i1: int32; +begin + with doubleintegerty(akey) do begin + i1:= a + b; + end; + result:= scramble((integer(i1) xor (integer(i1) shr 2))); +end; + +function tdoubleintegerhashdatalist.checkkey(const akey; + const aitem: phashdataty): boolean; +begin + with doubleintegerty(akey) do begin + result:= (a = pdoubleintegerhashdataty(aitem)^.data.key.a) and + (b = pdoubleintegerhashdataty(aitem)^.data.key.b); + end; +end; + +function tdoubleintegerhashdatalist.getrecordsize(): int32; +begin + result:= sizeof(doubleintegerhashdataty); +end; + +function tdoubleintegerhashdatalist.add( + const akeya,akeyb: integer): pdoubleintegerhashdataty; +var + k1: doubleintegerty; +begin + k1.a:= akeya; + k1.b:= akeyb; + result:= pdoubleintegerhashdataty(internaladd(k1)); + result^.data.key:= k1; +end; + +function tdoubleintegerhashdatalist.find( + const akeya,akeyb: integer): pdoubleintegerhashdataty; +begin + result:= pdoubleintegerhashdataty(internalfind(mdikey(akeya,akeyb))); +end; + +function tdoubleintegerhashdatalist.addunique( + const akeya,akeyb: integer): pdoubleintegerhashdataty; +begin + result:= find(akeya,akeyb); + if result = nil then begin + result:= add(akeya,akeyb); + end; +end; + +function tdoubleintegerhashdatalist.addunique(const akeya,akeyb: integer; + out adata: pdoubleintegerhashdataty): boolean; +begin + adata:= find(akeya,akeyb); + result:= false; + if adata = nil then begin + adata:= add(akeya,akeyb); + result:= true; + end; +end; + +function tdoubleintegerhashdatalist.first: pdoubleintegerhashdataty; +begin + result:= pdoubleintegerhashdataty(internalfirstx); +end; + +function tdoubleintegerhashdatalist.next: pdoubleintegerhashdataty; +begin + result:= pdoubleintegerhashdataty(internalnextx); +end; + +function tdoubleintegerhashdatalist.last: pdoubleintegerhashdataty; +begin + result:= pdoubleintegerhashdataty(internallastx); +end; + +function tdoubleintegerhashdatalist.prev: pdoubleintegerhashdataty; +begin + result:= pdoubleintegerhashdataty(internalprevx); +end; + +function tdoubleintegerhashdatalist.delete(const akeya,akeyb: integer; + const all: boolean = false): boolean; +begin + result:= internaldelete(mdikey(akeya,akeyb),all); +end; + +{ ttripleintegerhashdatalist } + +function mtikey(a,b,c: int32): tripleintegerty; inline; +begin + result.a:= a; + result.b:= b; + result.c:= c; +end; + +function ttripleintegerhashdatalist.hashkey(const akey): hashvaluety; +var + i1: int32; +begin + with tripleintegerty(akey) do begin + i1:= a + b + c; + end; + result:= scramble((integer(i1) xor (integer(i1) shr 2))); +end; + +function ttripleintegerhashdatalist.checkkey(const akey; + const aitem: phashdataty): boolean; +begin + with tripleintegerty(akey) do begin + result:= (a = ptripleintegerhashdataty(aitem)^.data.key.a) and + (b = ptripleintegerhashdataty(aitem)^.data.key.b) and + (c = ptripleintegerhashdataty(aitem)^.data.key.c); + end; +end; + +function ttripleintegerhashdatalist.getrecordsize(): int32; +begin + result:= sizeof(tripleintegerhashdataty); +end; + +function ttripleintegerhashdatalist.add( + const akeya,akeyb,akeyc: integer): ptripleintegerhashdataty; +var + k1: tripleintegerty; +begin + k1.a:= akeya; + k1.b:= akeyb; + k1.c:= akeyc; + result:= ptripleintegerhashdataty(internaladd(k1)); + result^.data.key:= k1; +end; + +function ttripleintegerhashdatalist.find( + const akeya,akeyb,akeyc: integer): ptripleintegerhashdataty; +begin + result:= ptripleintegerhashdataty(internalfind(mtikey(akeya,akeyb,akeyc))); +end; + +function ttripleintegerhashdatalist.addunique( + const akeya,akeyb,akeyc: integer): ptripleintegerhashdataty; +begin + result:= find(akeya,akeyb,akeyc); + if result = nil then begin + result:= add(akeya,akeyb,akeyc); + end; +end; + +function ttripleintegerhashdatalist.addunique(const akeya,akeyb,akeyc: integer; + out adata: ptripleintegerhashdataty): boolean; +begin + adata:= find(akeya,akeyb,akeyc); + result:= false; + if adata = nil then begin + adata:= add(akeya,akeyb,akeyc); + result:= true; + end; +end; + +function ttripleintegerhashdatalist.first: ptripleintegerhashdataty; +begin + result:= ptripleintegerhashdataty(internalfirstx); +end; + +function ttripleintegerhashdatalist.next: ptripleintegerhashdataty; +begin + result:= ptripleintegerhashdataty(internalnextx); +end; + +function ttripleintegerhashdatalist.last: ptripleintegerhashdataty; +begin + result:= ptripleintegerhashdataty(internallastx); +end; + +function ttripleintegerhashdatalist.prev: ptripleintegerhashdataty; +begin + result:= ptripleintegerhashdataty(internalprevx); +end; + +function ttripleintegerhashdatalist.delete(const akeya,akeyb,akeyc: integer; + const all: boolean = false): boolean; +begin + result:= internaldelete(mtikey(akeya,akeyb,akeyc),all); +end; + +{ tint32int32hashdatalist } + +procedure tint32int32hashdatalist.add(const akey: int32; + const avalue: int32); +begin + pint32int32hashdataty(inherited add(akey))^.data.data:= avalue; +end; + +function tint32int32hashdatalist.find(const akey: int32; + out avalue: int32): boolean; +var + po1: pint32int32hashdataty; +begin + po1:= pint32int32hashdataty(inherited find(akey)); + result:= po1 <> nil; + if result then begin + avalue:= po1^.data.data; + end + else begin + avalue:= 0; + end; +end; + +function tint32int32hashdatalist.addunique(const akey: int32; + const avalue: int32): boolean; +var + po1: pint32int32hashdataty; +begin + result:= true; + po1:= pint32int32hashdataty(inherited find(akey)); + if po1 = nil then begin + result:= false; + po1:= pint32int32hashdataty(inherited add(akey)); + po1^.data.data:= avalue; + end; +end; + +function tint32int32hashdatalist.getrecordsize(): int32; +begin + result:= sizeof(int32int32hashdataty); +end; + +function tint32int32hashdatalist.find(const akey: int32): int32; +begin + find(akey,result); +end; + +function tint32int32hashdatalist.first: pint32int32hashdataty; +begin + result:= pint32int32hashdataty(internalfirstx); +end; + +function tint32int32hashdatalist.next: pint32int32hashdataty; +begin + result:= pint32int32hashdataty(internalnextx); +end; + +function tint32int32hashdatalist.last: pint32int32hashdataty; +begin + result:= pint32int32hashdataty(internallastx); +end; + +function tint32int32hashdatalist.prev: pint32int32hashdataty; +begin + result:= pint32int32hashdataty(internalprevx); +end; + +{ tpointerhashdatalist } + +function tpointerhashdatalist.hashkey(const akey): hashvaluety; +begin + result:= pointerhash(pointer(akey)); +end; + +function tpointerhashdatalist.checkkey(const akey; + const aitem: phashdataty): boolean; +begin + result:= pointer(akey) = ppointerhashdataty(aitem)^.data.key; +end; + +function tpointerhashdatalist.getrecordsize(): int32; +begin + result:= sizeof(pointerhashdataty); +end; + +function tpointerhashdatalist.add(const akey: pointer): ppointerhashdataty; +begin + result:= ppointerhashdataty(internaladd(akey)); + result^.data.key:= akey; +end; + +function tpointerhashdatalist.addunique( + const akey: pointer): ppointerhashdataty; +begin + result:= find(akey); + if result = nil then begin + result:= add(akey); + end; +end; + +function tpointerhashdatalist.find(const akey: pointer): ppointerhashdataty; +begin + result:= ppointerhashdataty(internalfind(akey)); +end; + +function tpointerhashdatalist.delete(const akey: pointer; + const all: boolean = false): boolean; +begin + result:= internaldelete(akey,all); +end; + +function tpointerhashdatalist.first: ppointerhashdataty; +begin + result:= ppointerhashdataty(internalfirstx); +end; + +function tpointerhashdatalist.next: ppointerhashdataty; +begin + result:= ppointerhashdataty(internalnextx); +end; + +function tpointerhashdatalist.last: ppointerhashdataty; +begin + result:= ppointerhashdataty(internallastx); +end; + +function tpointerhashdatalist.prev: ppointerhashdataty; +begin + result:= ppointerhashdataty(internalprevx); +end; + +{ tpointerint32hashdatalist } + +procedure tpointerint32hashdatalist.add(const akey: pointer; + const avalue: int32); +begin + ppointerint32hashdataty(inherited add(akey))^.data.data:= avalue; +end; + +function tpointerint32hashdatalist.find(const akey: pointer; + out avalue: int32): boolean; +var + po1: ppointerint32hashdataty; +begin + po1:= ppointerint32hashdataty(inherited find(akey)); + result:= po1 <> nil; + if result then begin + avalue:= po1^.data.data; + end + else begin + avalue:= 0; + end; +end; + +function tpointerint32hashdatalist.addunique(const akey: pointer; + const avalue: int32): boolean; +var + po1: ppointerint32hashdataty; +begin + result:= true; + po1:= ppointerint32hashdataty(inherited find(akey)); + if po1 = nil then begin + result:= false; + po1:= ppointerint32hashdataty(inherited add(akey)); + po1^.data.data:= avalue; + end; +end; + +function tpointerint32hashdatalist.getrecordsize(): int32; +begin + result:= sizeof(pointerint32hashdataty); +end; + +function tpointerint32hashdatalist.find(const akey: pointer): int32; +begin + find(akey,result); +end; + +function tpointerint32hashdatalist.first: ppointerint32hashdataty; +begin + result:= ppointerint32hashdataty(internalfirstx); +end; + +function tpointerint32hashdatalist.next: ppointerint32hashdataty; +begin + result:= ppointerint32hashdataty(internalnextx); +end; + +function tpointerint32hashdatalist.last: ppointerint32hashdataty; +begin + result:= ppointerint32hashdataty(internallastx); +end; + +function tpointerint32hashdatalist.prev: ppointerint32hashdataty; +begin + result:= ppointerint32hashdataty(internalprevx); +end; + +{ tptruinthasdatalist } +{ +constructor tptruinthashdatalist.create(const datasize: integer); +begin + inherited create(datasize + sizeof(ptruintdataty)); +end; +} +function tptruinthashdatalist.hashkey(const akey): hashvaluety; +// todo: optimize +begin + result:= pointerhash(pointer(akey)); +// result:= scramble(ptruint(akey) xor (ptruint(akey) shr 2)); +end; + +function tptruinthashdatalist.add(const akey: ptruint): pptruinthashdataty; +begin + result:= pptruinthashdataty(internaladd(akey)); + result^.data.key:= akey; +end; + +function tptruinthashdatalist.find(const akey: ptruint): pptruinthashdataty; +begin + result:= pptruinthashdataty(internalfind(akey)); +end; + +function tptruinthashdatalist.addunique( + const akey: ptruint): pptruinthashdataty; +begin + result:= find(akey); + if result = nil then begin + result:= add(akey); + end; +end; + +function tptruinthashdatalist.checkkey(const akey; + const aitem: phashdataty): boolean; +begin + result:= ptruint(akey) = pptruinthashdataty(aitem)^.data.key; +end; + +function tptruinthashdatalist.getrecordsize(): int32; +begin + result:= sizeof(ptruinthashdataty); +end; + +function tptruinthashdatalist.first: pptruinthashdataty; +begin + result:= pptruinthashdataty(internalfirstx); +end; + +function tptruinthashdatalist.next: pptruinthashdataty; +begin + result:= pptruinthashdataty(internalnextx); +end; + +function tptruinthashdatalist.last: pptruinthashdataty; +begin + result:= pptruinthashdataty(internallastx); +end; + +function tptruinthashdatalist.prev: pptruinthashdataty; +begin + result:= pptruinthashdataty(internalprevx); +end; + +function tptruinthashdatalist.delete(const akey: ptruint; + const all: boolean = false): boolean; +begin + result:= internaldelete(akey,all); +end; + +{ tpointerptruinthashdatalist } + +procedure tpointerptruinthashdatalist.add(const akey: ptruint; + const avalue: pointer); +begin + ppointerptruinthashdataty(inherited add(akey))^.data.data:= avalue; +end; + +function tpointerptruinthashdatalist.find(const akey: ptruint; + out avalue: pointer): boolean; +var + po1: ppointerptruinthashdataty; +begin + po1:= ppointerptruinthashdataty(inherited find(akey)); + result:= po1 <> nil; + if result then begin + avalue:= po1^.data.data; + end + else begin + avalue:= nil; + end; +end; + +function tpointerptruinthashdatalist.addunique(const akey: ptruint; + const avalue: pointer): boolean; +var + po1: ppointerptruinthashdataty; +begin + result:= true; + po1:= ppointerptruinthashdataty(inherited find(akey)); + if po1 = nil then begin + result:= false; + po1:= ppointerptruinthashdataty(inherited add(akey)); + po1^.data.data:= avalue; + end; +end; + +procedure tpointerptruinthashdatalist.checkexact( + const aitem: phashdataty; var accept: boolean); +begin + accept:= ppointerptruinthashdataty(aitem)^.data.data = fpointerparam; +end; + +function tpointerptruinthashdatalist.getrecordsize(): int32; +begin + result:= sizeof(pointerptruinthashdataty); +end; + +procedure tpointerptruinthashdatalist.delete(const akey: ptruint; + const avalue: pointer); +//var +// po1: phashdataty; +begin + fpointerparam:= avalue; + internaldeleteitem(internalfindexact(akey)); +end; + +function tpointerptruinthashdatalist.find(const akey: ptruint): pointer; +begin + find(akey,result); +end; + +function tpointerptruinthashdatalist.first: ppointerptruinthashdataty; +begin + result:= ppointerptruinthashdataty(internalfirstx); +end; + +function tpointerptruinthashdatalist.next: ppointerptruinthashdataty; +begin + result:= ppointerptruinthashdataty(internalnextx); +end; + +function tpointerptruinthashdatalist.last: ppointerptruinthashdataty; +begin + result:= ppointerptruinthashdataty(internallastx); +end; + +function tpointerptruinthashdatalist.prev: ppointerptruinthashdataty; +begin + result:= ppointerptruinthashdataty(internalprevx); +end; + +procedure tpointerptruinthashdatalist.iterate(const akey: ptruint; + const aiterator: pointerptruintiteratorprocty); +begin + iterate(akey,keyhashiteratorprocty(aiterator)); +end; + +{ tansistringptruinthashdatalist } + +constructor tansistringptruinthashdatalist.create; +begin + inherited create(); + fstate:= fstate + [hls_needsnull,hls_needsfinalize]; +end; + +procedure tansistringptruinthashdatalist.add(const akey: ptruint; + const avalue: ansistring); +begin + pansistringptruinthashdataty(inherited add(akey))^.data.data:= avalue; +end; + +function tansistringptruinthashdatalist.find(const akey: ptruint; + out avalue: ansistring): boolean; +var + po1: pansistringptruinthashdataty; +begin + po1:= pansistringptruinthashdataty(inherited find(akey)); + result:= po1 <> nil; + if result then begin + avalue:= po1^.data.data; + end + else begin + avalue:= ''; + end; +end; + +function tansistringptruinthashdatalist.addunique(const akey: ptruint; + const avalue: ansistring): boolean; +var + po1: pansistringptruinthashdataty; +begin + result:= true; + po1:= pansistringptruinthashdataty(inherited find(akey)); + if po1 = nil then begin + result:= false; + po1:= pansistringptruinthashdataty(inherited add(akey)); + po1^.data.data:= avalue; + end; +end; + +procedure tansistringptruinthashdatalist.checkexact( + const aitem: phashdataty; var accept: boolean); +begin + accept:= pansistringptruinthashdataty(aitem)^.data.data = fansistringparam; +end; + +procedure tansistringptruinthashdatalist.delete(const akey: ptruint; + const avalue: ansistring); +//var +// po1: phashdataty; +begin + fansistringparam:= avalue; + internaldeleteitem(internalfindexact(akey)); +end; + +function tansistringptruinthashdatalist.find(const akey: ptruint): ansistring; +begin + find(akey,result); +end; + +function tansistringptruinthashdatalist.first: pansistringptruinthashdataty; +begin + result:= pansistringptruinthashdataty(internalfirstx); +end; + +function tansistringptruinthashdatalist.next: pansistringptruinthashdataty; +begin + result:= pansistringptruinthashdataty(internalnextx); +end; + +function tansistringptruinthashdatalist.last: pansistringptruinthashdataty; +begin + result:= pansistringptruinthashdataty(internallastx); +end; + +function tansistringptruinthashdatalist.prev: pansistringptruinthashdataty; +begin + result:= pansistringptruinthashdataty(internalprevx); +end; + +procedure tansistringptruinthashdatalist.iterate(const akey: ptruint; + const aiterator: ansistringptruintiteratorprocty); +begin + iterate(akey,keyhashiteratorprocty(aiterator)); +end; + +procedure tansistringptruinthashdatalist.finalizeitem(const aitem: phashdataty); +begin + finalize(pansistringptruinthashdataty(aitem)^.data); +end; + +function tansistringptruinthashdatalist.getrecordsize(): int32; +begin + result:= sizeof(ansistringptruinthashdataty); +end; + +function tansistringptruinthashdatalist.setdata(const akey: ptruint; + const avalue: ansistring): boolean; +var + po1: pansistringptruinthashdataty; +begin + po1:= pansistringptruinthashdataty(inherited find(akey)); + result:= po1 <> nil; + if result then begin + po1^.data.data:= avalue; + end; +end; + +{ tmsestringptruinthashdatalist } + +constructor tmsestringptruinthashdatalist.create; +begin + inherited create(); + fstate:= fstate + [hls_needsnull,hls_needsfinalize]; +end; + +procedure tmsestringptruinthashdatalist.add(const akey: ptruint; + const avalue: msestring); +begin + pmsestringptruinthashdataty(inherited add(akey))^.data.data:= avalue; +end; + +function tmsestringptruinthashdatalist.find(const akey: ptruint; + out avalue: msestring): boolean; +var + po1: pmsestringptruinthashdataty; +begin + po1:= pmsestringptruinthashdataty(inherited find(akey)); + result:= po1 <> nil; + if result then begin + avalue:= po1^.data.data; + end + else begin + avalue:= ''; + end; +end; + +function tmsestringptruinthashdatalist.addunique(const akey: ptruint; + const avalue: msestring): boolean; +var + po1: pmsestringptruinthashdataty; +begin + result:= true; + po1:= pmsestringptruinthashdataty(inherited find(akey)); + if po1 = nil then begin + result:= false; + po1:= pmsestringptruinthashdataty(inherited add(akey)); + po1^.data.data:= avalue; + end; +end; + +procedure tmsestringptruinthashdatalist.checkexact(const aitem: phashdataty; + var accept: boolean); +begin + accept:= pmsestringptruinthashdataty(aitem)^.data.data = fmsestringparam; +end; + +procedure tmsestringptruinthashdatalist.delete(const akey: ptruint; + const avalue: msestring); +//var +// po1: phashdataty; +begin + fmsestringparam:= avalue; + internaldeleteitem(internalfindexact(akey)); +end; + +function tmsestringptruinthashdatalist.find(const akey: ptruint): msestring; +begin + find(akey,result); +end; + +function tmsestringptruinthashdatalist.first: pmsestringptruinthashdataty; +begin + result:= pmsestringptruinthashdataty(internalfirstx); +end; + +function tmsestringptruinthashdatalist.next: pmsestringptruinthashdataty; +begin + result:= pmsestringptruinthashdataty(internalnextx); +end; + +function tmsestringptruinthashdatalist.last: pmsestringptruinthashdataty; +begin + result:= pmsestringptruinthashdataty(internallastx); +end; + +function tmsestringptruinthashdatalist.prev: pmsestringptruinthashdataty; +begin + result:= pmsestringptruinthashdataty(internalprevx); +end; + +procedure tmsestringptruinthashdatalist.iterate(const akey: ptruint; + const aiterator: msestringptruintiteratorprocty); +begin + iterate(akey,keyhashiteratorprocty(aiterator)); +end; + +procedure tmsestringptruinthashdatalist.finalizeitem(const aitem: phashdataty); +begin + finalize(pmsestringptruinthashdataty(aitem)^.data); +end; + +function tmsestringptruinthashdatalist.getrecordsize(): int32; +begin + result:= sizeof(msestringptruinthashdataty); +end; + +function tmsestringptruinthashdatalist.setdata(const akey: ptruint; + const avalue: msestring): boolean; +var + po1: pmsestringptruinthashdataty; +begin + po1:= pmsestringptruinthashdataty(inherited find(akey)); + result:= po1 <> nil; + if result then begin + po1^.data.data:= avalue; + end; +end; + +{ tansistringhashdatalist } + +constructor tansistringhashdatalist.create(); +begin + inherited create(); + fstate:= fstate + [hls_needsnull,hls_needsfinalize]; +end; + +procedure tansistringhashdatalist.finalizeitem(const aitem: phashdataty); +begin + finalize(pansistringhashdataty(aitem)^.data); +end; + +function tansistringhashdatalist.getrecordsize(): int32; +begin + result:= sizeof(ansistringhashdataty); +end; + +function tansistringhashdatalist.add( + const akey: ansistring): pansistringhashdataty; +begin + result:= pansistringhashdataty(internaladd(akey)); + result^.data.key:= akey; +end; + +function tansistringhashdatalist.find( + const akey: ansistring): pansistringhashdataty; +begin + result:= pansistringhashdataty(internalfind(akey)); +end; + +function tansistringhashdatalist.find( + const akey: lstringty): pansistringhashdataty; +var + ha1: hashvaluety; + uint1: hashoffsetty; + po1: phashdataty; +begin + po1:= nil; + if count > 0 then begin + ha1:= hashlkey(akey); + uint1:= fhashtable[ha1 and fmask]; + if uint1 <> 0 then begin + po1:= phashdataty(pchar(fdata) + uint1); + while true do begin + if (po1^.header.hash = ha1) and checklkey(akey, + pansistringhashdataty(po1)^.data) then begin + break; + end; + if po1^.header.nexthash = 0 then begin + po1:= nil; + break; + end; + po1:= phashdataty(pchar(fdata) + po1^.header.nexthash); + end; + end; + end; + result:= pansistringhashdataty(po1); +end; + +function tansistringhashdatalist.addunique( + const akey: ansistring): pansistringhashdataty; +begin + result:= find(akey); + if result = nil then begin + result:= add(akey); + end; +end; + +function tansistringhashdatalist.hashkey(const akey): hashvaluety; +begin + result:= stringhash(ansistring(akey)); +end; + +function tansistringhashdatalist.hashlkey(const akey: lstringty): hashvaluety; +begin + result:= stringhash(akey); +end; + +function tansistringhashdatalist.checkkey(const akey; + const aitem: phashdataty): boolean; +var + int1: integer; +begin + result:= pointer(akey) = pointer(pansistringhashdataty(aitem)^.data.key); + if not result then begin + int1:= length(ansistring(akey)); + result:= (int1 = length(pansistringhashdataty(aitem)^.data.key)) and + comparemem(pointer(akey), + pointer(pansistringhashdataty(aitem)^.data.key),int1); + end; +end; + +function tansistringhashdatalist.checklkey(const akey: lstringty; + const aitemdata: ansistringdataty): boolean; +begin + result:= (akey.len = length(aitemdata.key)) and + comparemem(akey.po,pointer(aitemdata.key),akey.len); +end; + +function tansistringhashdatalist.delete(const akey: ansistring; + const all: boolean = false): boolean; +begin + result:= internaldelete(akey,all); +end; + +function tansistringhashdatalist.delete(const akey: lstringty; + const all: boolean = false): boolean; +var + str1: string; +begin + str1:= lstringtostring(akey); + result:= internaldelete(str1,all); +end; + +function tansistringhashdatalist.first: pansistringhashdataty; +begin + result:= pansistringhashdataty(internalfirstx); +end; + +function tansistringhashdatalist.next: pansistringhashdataty; +begin + result:= pansistringhashdataty(internalnextx); +end; + +function tansistringhashdatalist.last: pansistringhashdataty; +begin + result:= pansistringhashdataty(internallastx); +end; + +function tansistringhashdatalist.prev: pansistringhashdataty; +begin + result:= pansistringhashdataty(internalprevx); +end; + +procedure tansistringhashdatalist.iterate(const akey: ansistring; + const aiterator: ansistringhashiteratorprocty); +begin + iterate(akey,keyhashiteratorprocty(aiterator)); +end; + +{ tpointeransistringhashdatalist } +{ +constructor tpointeransistringhashdatalist.create; +begin + inherited create(sizeof(pointer)); +end; +} +procedure tpointeransistringhashdatalist.add(const akey: ansistring; + const avalue: pointer); +begin + ppointeransistringhashdataty(inherited add(akey))^.data.data:= avalue; +end; + +procedure tpointeransistringhashdatalist.add(const keys: array of string; + startindex: pointer = pointer($00000001)); +var + ca1: longword; +begin + for ca1:= 0 to high(keys) do begin + add(keys[ca1],pointer(ca1+ptruint(startindex))); + end; +end; + +function tpointeransistringhashdatalist.find(const akey: ansistring; + out avalue: pointer): boolean; +var + po1: ppointeransistringhashdataty; +begin + po1:= ppointeransistringhashdataty(inherited find(akey)); + result:= po1 <> nil; + if result then begin + avalue:= po1^.data.data; + end + else begin + avalue:= nil; + end; +end; + +function tpointeransistringhashdatalist.find(const akey: lstringty): pointer; +begin + result:= inherited find(akey); + if result <> nil then begin + result:= ppointeransistringhashdataty(result)^.data.data; + end; +end; + +function tpointeransistringhashdatalist.addunique(const akey: ansistring; + const avalue: pointer): boolean; +var + po1: ppointeransistringhashdataty; +begin + result:= true; + po1:= ppointeransistringhashdataty(inherited find(akey)); + if po1 = nil then begin + result:= false; + po1:= ppointeransistringhashdataty(inherited add(akey)); + po1^.data.data:= avalue; + end; +end; + +procedure tpointeransistringhashdatalist.checkexact(const aitem: phashdataty; + var accept: boolean); +begin + accept:= ppointeransistringhashdataty(aitem)^.data.data = fpointerparam; +end; + +function tpointeransistringhashdatalist.getrecordsize(): int32; +begin + result:= sizeof(pointeransistringhashdataty); +end; + +procedure tpointeransistringhashdatalist.delete(const akey: ansistring; + const avalue: pointer); +//var +// po1: phashdataty; +begin + fpointerparam:= avalue; + internaldeleteitem(internalfindexact(akey)); +end; + +function tpointeransistringhashdatalist.find(const akey: ansistring): pointer; +begin + find(akey,result); +end; + +function tpointeransistringhashdatalist.first: ppointeransistringhashdataty; +begin + result:= ppointeransistringhashdataty(internalfirstx); +end; + +function tpointeransistringhashdatalist.next: ppointeransistringhashdataty; +begin + result:= ppointeransistringhashdataty(internalnextx); +end; + +function tpointeransistringhashdatalist.last: ppointeransistringhashdataty; +begin + result:= ppointeransistringhashdataty(internallastx); +end; + +function tpointeransistringhashdatalist.prev: ppointeransistringhashdataty; +begin + result:= ppointeransistringhashdataty(internalprevx); +end; + +procedure tpointeransistringhashdatalist.iterate(const akey: ansistring; + const aiterator: pointeransistringiteratorprocty); +begin + iterate(akey,keyhashiteratorprocty(aiterator)); +end; + +{ tmsestringhashdatalist } + +constructor tmsestringhashdatalist.create(); +begin + inherited create(); + fstate:= fstate + [hls_needsnull,hls_needsfinalize]; +end; + +procedure tmsestringhashdatalist.finalizeitem( + const aitem: phashdataty); +begin + finalize(pmsestringhashdataty(aitem)^.data); +end; + +function tmsestringhashdatalist.getrecordsize(): int32; +begin + result:= sizeof(msestringhashdataty); +end; + +function tmsestringhashdatalist.add( + const akey: msestring): pmsestringhashdataty; +begin + result:= pmsestringhashdataty(internaladd(akey)); + result^.data.key:= akey; +end; + +function tmsestringhashdatalist.find( + const akey: msestring): pmsestringhashdataty; +begin + result:= pmsestringhashdataty(internalfind(akey)); +end; + +function tmsestringhashdatalist.find( + const akey: lmsestringty): pmsestringhashdataty; +var + ha1: hashvaluety; + uint1: hashoffsetty; + po1: phashdataty; +begin + po1:= nil; + if count > 0 then begin + ha1:= hashlkey(akey); + uint1:= fhashtable[ha1 and fmask]; + if uint1 <> 0 then begin + po1:= phashdataty(pchar(fdata) + uint1); + while true do begin + if (po1^.header.hash = ha1) and checklkey(akey, + pmsestringhashdataty(po1)^.data) then begin + break; + end; + if po1^.header.nexthash = 0 then begin + po1:= nil; + break; + end; + po1:= phashdataty(pchar(fdata) + po1^.header.nexthash); + end; + end; + end; + result:= pmsestringhashdataty(po1); +end; + +function tmsestringhashdatalist.find(const akey: msestring; + out acount: integer): pmsestringhashdataty; +begin + result:= pmsestringhashdataty(internalfind(akey,acount)); +end; + +function tmsestringhashdatalist.addunique( + const akey: msestring): pmsestringhashdataty; +begin + result:= find(akey); + if result = nil then begin + result:= add(akey); + end; +end; + +function tmsestringhashdatalist.hashkey(const akey): hashvaluety; +begin + result:= stringhash(msestring(akey)); +end; + +function tmsestringhashdatalist.hashlkey(const akey: lmsestringty): hashvaluety; +begin + result:= stringhash(akey); +end; + +function tmsestringhashdatalist.checklkey(const akey: lmsestringty; + const aitemdata: msestringdataty): boolean; +begin + result:= (akey.len = length(aitemdata.key)) and + comparemem(akey.po,pointer(aitemdata.key), + akey.len*sizeof(msechar)); +end; + +function tmsestringhashdatalist.checkkey(const akey; + const aitem: phashdataty): boolean; +var + int1: integer; +begin + result:= pointer(akey) = pointer(pmsestringhashdataty(aitem)^.data.key); + if not result then begin + int1:= length(msestring(akey)); + result:= (int1 = length(pmsestringhashdataty(aitem)^.data.key)) and + comparemem(pointer(akey),pointer(pmsestringhashdataty(aitem)^.data.key), + int1*sizeof(msechar)); + end; +// result:= msestring(akey) = msestringdataty(aitemdata).key; +end; + +function tmsestringhashdatalist.delete(const akey: msestring; + const all: boolean = false): boolean; +begin + result:= internaldelete(akey,all); +end; + +function tmsestringhashdatalist.delete(const akey: lmsestringty; + const all: boolean = false): boolean; +var + mstr1: msestring; +begin + mstr1:= lstringtostring(akey); + result:= internaldelete(mstr1,all); +end; + +function tmsestringhashdatalist.first: pmsestringhashdataty; +begin + result:= pmsestringhashdataty(internalfirstx); +end; + +function tmsestringhashdatalist.next: pmsestringhashdataty; +begin + result:= pmsestringhashdataty(internalnextx); +end; + +function tmsestringhashdatalist.last: pmsestringhashdataty; +begin + result:= pmsestringhashdataty(internallastx); +end; + +function tmsestringhashdatalist.prev: pmsestringhashdataty; +begin + result:= pmsestringhashdataty(internalprevx); +end; + +procedure tmsestringhashdatalist.iterate(const akey: msestring; + const aiterator: msestringiteratorprocty); +begin + iterate(akey,keyhashiteratorprocty(aiterator)); +end; + +{ tpointermsestringhashdatalist } +{ +constructor tpointermsestringhashdatalist.create; +begin + inherited create(sizeof(pointermsestringhashdataty) - + sizeof(msestringhashdataty)); +end; +} +procedure tpointermsestringhashdatalist.add(const akey: msestring; + const avalue: pointer); +begin + ppointermsestringhashdataty(inherited add(akey))^.data.data:= avalue; +end; + +function tpointermsestringhashdatalist.find(const akey: msestring; + out avalue: pointer): boolean; +var + po1: ppointermsestringhashdataty; +begin + po1:= ppointermsestringhashdataty(inherited find(akey)); + result:= po1 <> nil; + if result then begin + avalue:= po1^.data.data; + end + else begin + avalue:= nil; + end; +end; + +function tpointermsestringhashdatalist.find(const akey: msestring; + out avalue: pointer; out acount: integer): boolean; +var + po1: ppointermsestringhashdataty; +begin + po1:= ppointermsestringhashdataty(internalfind(akey,acount)); + result:= po1 <> nil; + if result then begin + avalue:= po1^.data.data; + end + else begin + avalue:= nil; + end; +end; + +function tpointermsestringhashdatalist.find(const akey: lmsestringty): pointer; +begin + result:= inherited find(akey); + if result <> nil then begin + result:= ppointermsestringhashdataty(result)^.data.data; + end; +end; + +function tpointermsestringhashdatalist.find(const akey: msestring): pointer; +begin + find(akey,result); +end; + +procedure tpointermsestringhashdatalist.delete(const akey: msestring; + const avalue: pointer); +//var +// po1: phashdataty; +begin + fpointerparam:= avalue; + internaldeleteitem(internalfindexact(akey)); +end; + +function tpointermsestringhashdatalist.addunique(const akey: msestring; + const avalue: pointer): boolean; +var + po1: ppointermsestringhashdataty; +begin + result:= true; + po1:= ppointermsestringhashdataty(inherited find(akey)); + if po1 = nil then begin + result:= false; + po1:= ppointermsestringhashdataty(inherited add(akey)); + po1^.data.data:= avalue; + end; +end; + +procedure tpointermsestringhashdatalist.checkexact( + const aitem: phashdataty; var accept: boolean); +begin + accept:= ppointermsestringhashdataty(aitem)^.data.data = fpointerparam; +end; + +function tpointermsestringhashdatalist.getrecordsize(): int32; +begin + result:= sizeof(pointermsestringhashdataty); +end; + +function tpointermsestringhashdatalist.first: ppointermsestringhashdataty; +begin + result:= ppointermsestringhashdataty(internalfirstx); +end; + +function tpointermsestringhashdatalist.next: ppointermsestringhashdataty; +begin + result:= ppointermsestringhashdataty(internalnextx); +end; + +function tpointermsestringhashdatalist.last: ppointermsestringhashdataty; +begin + result:= ppointermsestringhashdataty(internallastx); +end; + +function tpointermsestringhashdatalist.prev: ppointermsestringhashdataty; +begin + result:= ppointermsestringhashdataty(internalprevx); +end; + +procedure tpointermsestringhashdatalist.iterate(const akey: msestring; + const aiterator: pointermsestringiteratorprocty); +begin + iterate(akey,keyhashiteratorprocty(aiterator)); +end; + +{ tintegermsestringhashdatalist } +{ +constructor tintegermsestringhashdatalist.create; +begin + inherited create(sizeof(integer)); +end; +} +procedure tintegermsestringhashdatalist.add(const akey: msestring; + const avalue: integer); +begin + pintegermsestringhashdataty(inherited add(akey))^.data.data:= avalue; +end; + +function tintegermsestringhashdatalist.find(const akey: msestring; + out avalue: integer): boolean; +var + po1: pintegermsestringhashdataty; +begin + po1:= pintegermsestringhashdataty(inherited find(akey)); + result:= po1 <> nil; + if result then begin + avalue:= po1^.data.data; + end + else begin + avalue:= -1; + end; +end; + +function tintegermsestringhashdatalist.find(const akey: msestring; + out avalue: integer; out acount: integer): boolean; +var + po1: pintegermsestringhashdataty; +begin + po1:= pintegermsestringhashdataty(inherited find(akey,acount)); + result:= po1 <> nil; + if result then begin + avalue:= po1^.data.data; + end + else begin + avalue:= -1; + end; +end; + +function tintegermsestringhashdatalist.find(const akey: lmsestringty): integer; +var + po1: pintegermsestringhashdataty; +begin + po1:= pintegermsestringhashdataty(inherited find(akey)); + if po1 <> nil then begin + result:= po1^.data.data; + end + else begin + result:= -1; + end; +end; + +function tintegermsestringhashdatalist.find(const akey: msestring): integer; +begin + find(akey,result); +end; + +procedure tintegermsestringhashdatalist.delete(const akey: msestring; + const avalue: integer); +//var +// po1: phashdataty; +begin + fintegerparam:= avalue; + internaldeleteitem(internalfindexact(akey)); +end; + +function tintegermsestringhashdatalist.addunique(const akey: msestring; + const avalue: integer): boolean; +var + po1: pintegermsestringhashdataty; +begin + result:= true; + po1:= pintegermsestringhashdataty(inherited find(akey)); + if po1 = nil then begin + result:= false; + po1:= pintegermsestringhashdataty(inherited add(akey)); + po1^.data.data:= avalue; + end; +end; + +procedure tintegermsestringhashdatalist.checkexact(const aitem: phashdataty; + var accept: boolean); +begin + accept:= pintegermsestringhashdataty(aitem)^.data.data = fintegerparam; +end; + +function tintegermsestringhashdatalist.getrecordsize(): int32; +begin + result:= sizeof(integermsestringhashdataty); +end; + +function tintegermsestringhashdatalist.first: pintegermsestringhashdataty; +begin + result:= pintegermsestringhashdataty(internalfirstx); +end; + +function tintegermsestringhashdatalist.next: pintegermsestringhashdataty; +begin + result:= pintegermsestringhashdataty(internalnextx); +end; + +function tintegermsestringhashdatalist.last: pintegermsestringhashdataty; +begin + result:= pintegermsestringhashdataty(internallastx); +end; + +function tintegermsestringhashdatalist.prev: pintegermsestringhashdataty; +begin + result:= pintegermsestringhashdataty(internalprevx); +end; + +procedure tintegermsestringhashdatalist.iterate(const akey: msestring; + const aiterator: integermsestringiteratorprocty); +begin + iterate(akey,keyhashiteratorprocty(aiterator)); +end; + +{ tobjectmsestringhashdatalist } + +constructor tobjectmsestringhashdatalist.create(const aownsobjects: boolean = true); +begin + fownsobjects:= aownsobjects; + inherited create; +end; + +procedure tobjectmsestringhashdatalist.add(const akey: msestring; + const avalue: tobject); +begin + inherited add(akey,avalue); +end; + +function tobjectmsestringhashdatalist.addunique(const akey: msestring; + const avalue: tobject): boolean; +begin + result:= inherited addunique(akey,avalue); +end; + +procedure tobjectmsestringhashdatalist.delete(const akey: msestring; + const avalue: tobject); +begin + inherited delete(akey,avalue); +end; + +function tobjectmsestringhashdatalist.find(const akey: msestring): tobject; +begin + result:= tobject(inherited find(akey)); +end; + +function tobjectmsestringhashdatalist.find(const akey: msestring; + out avalue: tobject): boolean; +begin + result:= inherited find(akey,pointer(avalue)); +end; + +function tobjectmsestringhashdatalist.find(const akey: msestring; + out avalue: tobject; out acount: integer): boolean; +begin + result:= inherited find(akey,pointer(avalue),acount); +end; + +function tobjectmsestringhashdatalist.first: pobjectmsestringhashdataty; +begin + result:= pobjectmsestringhashdataty(internalfirstx); +end; + +function tobjectmsestringhashdatalist.next: pobjectmsestringhashdataty; +begin + result:= pobjectmsestringhashdataty(internalnextx); +end; + +function tobjectmsestringhashdatalist.last: pobjectmsestringhashdataty; +begin + result:= pobjectmsestringhashdataty(internallastx); +end; + +function tobjectmsestringhashdatalist.prev: pobjectmsestringhashdataty; +begin + result:= pobjectmsestringhashdataty(internalprevx); +end; + +procedure tobjectmsestringhashdatalist.iterate(const akey: msestring; + const aiterator: objectmsestringiteratorprocty); +begin + inherited iterate(akey,pointermsestringiteratorprocty(aiterator)); +end; + +procedure tobjectmsestringhashdatalist.finalizeitem(const aitem: phashdataty); +begin + inherited; + if fownsobjects then begin + with pobjectmsestringhashdataty(aitem)^.data do begin + data.free; + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/container/msehashstore.pas b/mseide-msegui/lib/common/container/msehashstore.pas new file mode 100644 index 0000000..7351a96 --- /dev/null +++ b/mseide-msegui/lib/common/container/msehashstore.pas @@ -0,0 +1,423 @@ +{ MSEgui Copyright (c) 2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msehashstore; +{$ifdef FPC}{$mode objfpc}{$h+}{$goto on}{$endif} +interface +uses + msehash,msetypes; + +const + maxidentvector = 200; + +type + identarty = card32arty; + identvecty = record + high: integer; + d: array[0..maxidentvector] of identty; + end; + + elementheaderty = record + path: identty; //key, sum of names to root + name: identty; + parent: hashoffsetty; //offset in data array + parentlevel: int32; //max = maxidentvector-1 + refcount: int32; + end; + + elementdataty = record + header: elementheaderty; + // data: record + // end; + end; + pelementdataty = ^elementdataty; + elementhashdataty = record + header: hashheaderty; + data: elementdataty; + end; + pelementhashdataty = ^elementhashdataty; + + thashstore = class(thashdatalist) + private + fcurparent: hashoffsetty; + protected + function hashkey(const akey): hashvaluety override; + function checkkey(const akey; const aitem: phashdataty): boolean override; + function find(const aele: elementdataty): pelementhashdataty; +// function internalfind(const idents: identvecty): pelementhashdataty; + function find(const idents: identvecty): pelementhashdataty; +// function internaladd(const idents: identvecty; +// out aelement: pelementhashdataty): hashoffsetty; + function add(const idents: identvecty; + out aelement: pelementhashdataty): hashoffsetty; + function getrecordsize(): int32 override; +// procedure inititem(const aitem: phashdataty) override; + public +// constructor create(); + function datapo(const aoffs: hashoffsetty): pelementhashdataty; + procedure delete(const idents: identvecty); + procedure delete(const item: hashoffsetty); //offset of datapo + end; + + treeelementheaderty = record + element: elementheaderty; + children: hashoffsetty; //offset in data array + prevsibling: hashoffsetty; //offset in data array + nextsibling: hashoffsetty; //offset in data array + end; + + treeelementdataty = record + header: treeelementheaderty; +// data: record +// end; + end; + ptreeelementdataty = ^treeelementdataty; + treeelementhashdataty = record + header: hashheaderty; + data: treeelementdataty; + end; + ptreeelementhashdataty = ^treeelementhashdataty; + + treehashelementiteratorprocty = procedure(const aitem : ptreeelementhashdataty; + const adata: pointer) of object; + thashtree = class(thashstore) + protected + function add(const idents: identvecty; + out aelement: ptreeelementhashdataty): hashoffsetty; + function find(const idents: identvecty): ptreeelementhashdataty; + function find(const idents: identvecty; + out aoffs: hashoffsetty): ptreeelementhashdataty; +// function find(const aele: elementdataty): ptreeelementhashdataty; +// function add(const idents: identvecty; +// out aelement: pointer): hashoffsetty; +// function find(const idents: identvecty): pointer; + function getrecordsize(): int32 override; + procedure inititem(const aitem: phashdataty) override; + public + constructor create(); + function datapo(const aoffs: hashoffsetty): ptreeelementhashdataty; + function root(const aoffs: hashoffsetty): ptreeelementhashdataty; + function root(const aitem: ptreeelementhashdataty): ptreeelementhashdataty; + procedure iteratechildren(const aitem: ptreeelementhashdataty; + const aiterator: treehashelementiteratorprocty; + const adata: pointer); + end; + +implementation + +{ thashstore } +{ +constructor thashstore.create(); +begin + include(fstate,hls_needsinit); + inherited; +end; +} +function thashstore.add(const idents: identvecty; + out aelement: pelementhashdataty): hashoffsetty; +var + p1,pe: pidentty; + ele: elementdataty; + p2: pelementhashdataty; +// off1: hashoffsetty; +begin + if idents.high >= 0 then begin + ele.header.path:= 0; + ele.header.parent:= 0; + ele.header.parentlevel:= 0; + ele.header.refcount:= 0; + p1:= @idents.d; + pe:= p1+idents.high; + fcurparent:= 0; + while p1 <= pe do begin + ele.header.path:= ele.header.path+p1^; + ele.header.name:= p1^; + if (p1 = pe) then begin + p2:= nil; + end + else begin + p2:= find(ele); + end; + if (p2 = nil) then begin + p2:= pointer(internaladdhash(ele.header.path)); + p2^.data.header:= ele.header; + if fcurparent <> 0 then begin + inc(pelementhashdataty(fdata+fcurparent)^.data.header.refcount); + end; + end; + inc(ele.header.parentlevel); + ele.header.parent:= getdataoffs(p2); + fcurparent:= p2-fdata; + inc(p1); + end; + inc(p2^.data.header.refcount); +// adata:= @p2^.data.data; + aelement:= p2; + result:= pointer(p2)-fdata; + end + else begin + result:= 0; + aelement:= nil; + end; +end; + +function thashstore.find(const aele: elementdataty): pelementhashdataty; +var + p1: pelementhashdataty; + uint1: ptruint; +begin + result:= nil; + p1:= fdata; + if count > 0 then begin + uint1:= fhashtable[aele.header.path and fmask]; + while uint1 <> 0 do begin + p1:= pelementhashdataty(fdata + uint1); + with p1^ do begin + if (data.header.path = aele.header.path) and + (data.header.parent = aele.header.parent) then begin + result:= p1; + break; + end; + end; + uint1:= p1^.header.nexthash; + end; + end; +end; + +function thashstore.hashkey(const akey): hashvaluety; +begin + result:= elementdataty(akey).header.path; +end; + +function thashstore.checkkey(const akey; const aitem: phashdataty): boolean; +begin + result:= elementdataty(akey).header.path = + pelementhashdataty(aitem)^.data.header.path; +end; + +function thashstore.find(const idents: identvecty): pelementhashdataty; +var + c1: card32; + p1,p2,pe,ps: pidentty; + ph1,ph2: pelementhashdataty; + uint1: ptruint; +label + nextlab; +begin + result:= nil; + if (count > 0) and (idents.high >= 0) then begin + ps:= @idents.d; + p1:= ps; + pe:= p1+idents.high; + c1:= 0; + while p1 <= pe do begin + c1:= c1 + p1^; + inc(p1); + end; + uint1:= fhashtable[c1 and fmask]; + while uint1 <> 0 do begin + ph1:= pelementhashdataty(fdata + uint1); + with ph1^ do begin + if (data.header.path = c1) and + (data.header.parentlevel = idents.high) then begin + ph2:= ph1; + p2:= pe; + while p2 >= ps do begin + if p2^ <> ph2^.data.header.name then begin + goto nextlab; + end; + ph2:= fdata+ph2^.data.header.parent; + dec(p2); + end; + result:= ph1;//@ph1^.data.data; + exit; + end; + end; +nextlab: + uint1:= ph1^.header.nexthash; + end; + end; +end; +{ +function thashstore.add(const idents: identvecty; + out adata: pointer): hashoffsetty; +begin + result:= internaladd(idents,adata); + adata:= adata+sizeof(elementhashdataty); +end; +} +function thashstore.datapo(const aoffs: hashoffsetty): pelementhashdataty; +begin + result:= fdata+aoffs; +end; + +function thashstore.getrecordsize(): int32; +begin + result:= sizeof(elementhashdataty); +end; + +{ +function thashstore.find(const idents: identvecty): pointer; +begin + result:= internalfind(idents); + if result <> nil then begin + result:= result + sizeof(elementhashdataty); + end; +end; +} +procedure thashstore.delete(const item: hashoffsetty); +var + p1: pelementhashdataty; +begin + p1:= getdatapo(item{-sizeof(elementhashdataty)}); + while true do begin + dec(p1^.data.header.refcount); + if p1^.data.header.refcount > 0 then begin + break; + end; + internaldeleteitem(phashdataty(pointer(p1))); //memory still valid + if p1^.data.header.parent = 0 then begin + break; + end; + p1:= fdata+p1^.data.header.parent; + end; +end; + +procedure thashstore.delete(const idents: identvecty); +var + p1: pelementhashdataty; +begin + p1:= find(idents); + if p1 <> nil then begin + delete(getdataoffs(p1)); + end; +end; + +{ thashtree } + +const + treeheaderext = sizeof(treeelementhashdataty) - sizeof(elementhashdataty); + +constructor thashtree.create(); +begin + include(fstate,hls_needsinit); + inherited create(); +end; + +procedure thashtree.inititem(const aitem: phashdataty); +var + p1,p2: ptreeelementhashdataty; + o1,o2: hashoffsetty; +begin + with ptreeelementhashdataty(aitem)^.data.header do begin + children:= 0; + prevsibling:= 0; + nextsibling:= 0; + p1:= getdatapoornil(fcurparent); + if p1 <> nil then begin + o1:= p1^.data.header.children; + o2:= getdataoffs(aitem); + if o1 <> 0 then begin + p2:= datapo(o1); + p2^.data.header.nextsibling:= o2; + prevsibling:= o1; + end; + p1^.data.header.children:= o2; + end; + end; +end; + +function thashtree.add(const idents: identvecty; + out aelement: ptreeelementhashdataty): hashoffsetty; +{ +var + p1,p2: ptreeelementhashdataty; + o1: hashoffsetty; +} +begin + result:= inherited add(idents,pelementhashdataty(aelement)); +{ + with aelement^ do begin + p1:= getdatapoornil(data.header.element.parent); + if p1 <> nil then begin + o1:= p1^.data.header.children; + if o1 <> 0 then begin + p2:= datapo(o1); + p2^.data.header.nextsibling:= result-o1; + data.header.prevsibling:= pointer(p2) - pointer(aelement); + end; + p1^.data.header.children:= result; + end; + end; +} +// adata:= adata+sizeof(treeelementhashdataty); +end; + +procedure thashtree.iteratechildren(const aitem: ptreeelementhashdataty; + const aiterator: treehashelementiteratorprocty; + const adata: pointer); +var + o1: hashoffsetty; +begin + o1:= aitem^.data.header.children; + while o1 <> 0 do begin + aiterator(datapo(o1),adata); + o1:= datapo(o1)^.data.header.prevsibling; + end; +end; + +function thashtree.find(const idents: identvecty): ptreeelementhashdataty; +begin + result:= ptreeelementhashdataty(inherited find(idents)); +end; + +function thashtree.find(const idents: identvecty; + out aoffs: hashoffsetty): ptreeelementhashdataty; +begin + result:= ptreeelementhashdataty(inherited find(idents)); + if result = nil then begin + aoffs:= 0; + end + else begin + aoffs:= pointer(result)-fdata; + end; +end; + +function thashtree.datapo(const aoffs: hashoffsetty): ptreeelementhashdataty; +begin + result:= fdata+aoffs; +end; + +function thashtree.root(const aoffs: hashoffsetty): ptreeelementhashdataty; +var + o1: hashoffsetty; +begin + result:= nil; + o1:= aoffs; + while o1 <> 0 do begin + result:= fdata+o1; + o1:= result^.data.header.element.parent + end; +end; + +function thashtree.root( + const aitem: ptreeelementhashdataty): ptreeelementhashdataty; +begin + result:= aitem; + if aitem <> nil then begin + result:= root(getdataoffs(aitem)); + end; +end; + +function thashtree.getrecordsize(): int32; +begin + result:= sizeof(treeelementhashdataty); +end; + +end. diff --git a/mseide-msegui/lib/common/container/mselinklist.pas b/mseide-msegui/lib/common/container/mselinklist.pas new file mode 100644 index 0000000..ea4ca96 --- /dev/null +++ b/mseide-msegui/lib/common/container/mselinklist.pas @@ -0,0 +1,437 @@ +{ MSEgui Copyright (c) 2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mselinklist; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes; + +type + + linkheaderty = record + next: ptruint; //offset in data + end; + plinkheaderty = ^linkheaderty; + linkinfoty = record + header: linkheaderty; + data: record + end; + end; + + doublelinkheaderty = record + lh: linkheaderty; + prev: ptruint; //offset in data + end; + pdoublelinkheaderty = ^doublelinkheaderty; + doublelinkinfoty = record + header: doublelinkheaderty; + data: record + end; + end; + + tlinklist = class(tobject) + private + fcapacity: ptruint; + flast: ptruint; + fdeleted: ptruint; + fcount: integer; + function getcapacity: integer; + procedure setcapacity(const avalue: integer); + protected + fdata: pointer; //dummy item at 0 + fheadersize: integer; + fitemsize: integer; + function getheadersize: integer; virtual; + procedure grow; + function add(out aoffset: ptruint): pointer; + procedure delete(const aoffset: ptruint); + public + constructor create(const adatasize: integer); + destructor destroy; override; + procedure clear; + property count: integer read fcount; + property capacity: integer read getcapacity write setcapacity; + //grow only + end; + + tsinglelinklist = class(tlinklist) + protected + public + end; + + tdoublelinklist = class(tlinklist) + protected + function getheadersize: integer; override; + procedure delete(const aoffset: ptruint); + public + end; + + listadty = card32; + linklistheaderty = record + next: listadty; //offset from list + end; + plinklistheaderty = ^linkheaderty; + linkdataty = record + header: linkheaderty; + data: record + end; + end; + plinkdataty = ^linkdataty; + + linklistty = record + itemsize: integer; + mincapacity: integer; + list: pointer; + current: listadty; //offset from list + capacity: listadty; //offset from list + deleted: listadty; + end; + + resolvehandlerty = procedure(var item); + resolvehandlerdataty = procedure(var item; var data); + checkresolvehandlerty = procedure(var item; var data; var resolved: boolean); + +procedure clearlist(var alist: linklistty; const aitemsize: integer; + const amincapacity: integer); +procedure freelist(var alist: linklistty); +function addlistitem(var alist: linklistty; var aitem: listadty): pointer; +function getlistitem(const alist: linklistty; const aitem: listadty): pointer; +function getnextlistitem(const alist: linklistty; + const aitem: listadty): pointer; +procedure deletelistitem(var alist: linklistty; var achain: listadty); +procedure deletelistchain(var alist: linklistty; var achain: listadty); +procedure invertlist(const alist: linklistty; var achain: listadty); +procedure resolvelist(var alist: linklistty; const handler: resolvehandlerty; + var achain: listadty); +procedure checkresolve(var alist: linklistty; + const handler: checkresolvehandlerty; var achain: listadty; + const data: pointer); +procedure foralllistitems(var alist: linklistty; + const handler: resolvehandlerty; const achain: listadty); +procedure foralllistitemsdata(var alist: linklistty; + const handler: resolvehandlerdataty; const achain: listadty; + const data: pointer); + +implementation + +procedure clearlist(var alist: linklistty; const aitemsize: integer; + const amincapacity: integer); +begin + with alist do begin + itemsize:= aitemsize; + mincapacity:= amincapacity*aitemsize; + if list <> nil then begin + freemem(list); + end; + list:= nil; + current:= 0; + capacity:= 0; + deleted:= 0; + end; +end; + +procedure freelist(var alist: linklistty); +begin + with alist do begin + if list <> nil then begin + freemem(list); + end; + fillchar(alist,sizeof(alist),0); + end; +end; + +function addlistitem(var alist: linklistty; var aitem: listadty): pointer; +var + li1: listadty; +begin + with alist do begin + li1:= deleted; + if li1 = 0 then begin + current:= current + itemsize; + if current >= capacity then begin + capacity:= 2*capacity + mincapacity; + reallocmem(list,capacity); + end; + li1:= current; + result:= list+li1; + end + else begin + result:= list+li1; + deleted:= plinkheaderty(result)^.next; + end; + plinkheaderty(result)^.next:= aitem; + aitem:= li1; + end; +end; + +function getlistitem(const alist: linklistty; const aitem: listadty): pointer; +begin + result:= alist.list+aitem; +end; + +function getnextlistitem(const alist: linklistty; + const aitem: listadty): pointer; +var + i1: listadty; +begin + result:= alist.list+aitem; + i1:= plinkdataty(result)^.header.next; + if i1 = 0 then begin + result:= nil; + end + else begin + result:= alist.list+i1; + end; +end; + +procedure deletelistitem(var alist: linklistty; var achain: listadty); +var + next1: listadty; +begin + if achain <> 0 then begin + with alist do begin + next1:= plinkheaderty(list+achain)^.next; + plinkheaderty(list+achain)^.next:= deleted; + deleted:= achain; + end; + achain:= next1; + end; +end; + +procedure deletelistchain(var alist: linklistty; var achain: listadty); +var + ad1: listadty; + po1: plinkheaderty; +begin + if achain <> 0 then begin + with alist do begin + ad1:= achain; + repeat + po1:= alist.list+ad1; + ad1:= po1^.next; + until ad1 = 0; + po1^.next:= deleted; + deleted:= achain; + end; + achain:= 0; + end; +end; + +procedure invertlist(const alist: linklistty; var achain: listadty); +var + s,s1,d: listadty; +begin + if achain <> 0 then begin + d:= 0; + s:= achain; + repeat + with plinkheaderty(alist.list+s)^ do begin + s1:= next; + next:= d; + end; + d:= s; + s:= s1; + until s = 0; + achain:= d; + end; +end; + +procedure resolvelist(var alist: linklistty; const handler: resolvehandlerty; + var achain: listadty); +var + ad1: listadty; + po1: plinkheaderty; +begin + if achain <> 0 then begin + ad1:= achain; + with alist do begin + while ad1 <> 0 do begin + po1:= alist.list+ad1; + handler(po1^); + ad1:= po1^.next; + end; + plinkheaderty(list+achain)^.next:= deleted; + deleted:= achain; + achain:= 0; + end; + end; +end; + +procedure checkresolve(var alist: linklistty; + const handler: checkresolvehandlerty; var achain: listadty; + const data: pointer); +var + ad1: listadty; + po2: pointer; + po1,po3: plinkheaderty; + bo1: boolean; +begin + if achain <> 0 then begin + po3:= nil; + ad1:= achain; + po2:= alist.list; + while ad1 <> 0 do begin + po1:= po2+ad1; + bo1:= false; + handler(po1^,data^,bo1); + if bo1 then begin + if po3 <> nil then begin + po3^.next:= po1^.next; + end + else begin + achain:= po1^.next; + end; + if alist.deleted <> 0 then begin + plinkheaderty(alist.list+alist.deleted)^.next:= ad1; + end; + alist.deleted:= ad1; + ad1:= po1^.next; + po1^.next:= 0; + end + else begin + ad1:= po1^.next; + end; + po3:= po1; + end; + end; +end; + +procedure foralllistitems(var alist: linklistty; + const handler: resolvehandlerty; const achain: listadty); +var + ad1: listadty; + po2: pointer; + po1: plinkheaderty; +begin + if achain <> 0 then begin + ad1:= achain; + po2:= alist.list; + while ad1 <> 0 do begin + po1:= po2+ad1; + handler(po1^); + ad1:= po1^.next; + end; + end; +end; + +procedure foralllistitemsdata(var alist: linklistty; + const handler: resolvehandlerdataty; const achain: listadty; + const data: pointer); +var + ad1: listadty; + po2: pointer; + po1: plinkheaderty; +begin + if achain <> 0 then begin + ad1:= achain; + po2:= alist.list; + while ad1 <> 0 do begin + po1:= po2+ad1; + handler(po1^,data^); + ad1:= po1^.next; + end; + end; +end; + +{ tlinklist } + +constructor tlinklist.create(const adatasize: integer); +begin + fheadersize:= getheadersize; + fitemsize:= adatasize + fheadersize; +end; + +destructor tlinklist.destroy; +begin + clear; + inherited; +end; + +function tlinklist.getheadersize: integer; +begin + result:= sizeof(linkheaderty); +end; + +function tlinklist.getcapacity: integer; +begin + result:= fcapacity div fitemsize +end; + +procedure tlinklist.setcapacity(const avalue: integer); +var + ca1: ptruint; +begin + ca1:= avalue * fitemsize; + if ca1 > fcapacity then begin + reallocmem(fdata,ca1+fitemsize); + fcapacity:= ca1; + end; +end; + +procedure tlinklist.grow; +begin + capacity:= 2*count+256; +end; + +function tlinklist.add(out aoffset: ptruint): pointer; +begin + if fdeleted = 0 then begin + flast:= flast+fitemsize; + if flast >= fcapacity then begin + grow; + end; + aoffset:= flast; + end + else begin + aoffset:= fdeleted; + fdeleted:= plinkheaderty(fdata + fdeleted)^.next; + end; + inc(fcount); + result:= fdata+aoffset; +end; + +procedure tlinklist.delete(const aoffset: ptruint); +begin + plinkheaderty(fdata+aoffset)^.next:= fdeleted; + fdeleted:= aoffset; + dec(fcount); +end; + +procedure tlinklist.clear; +begin + if fdata <> nil then begin + freemem(fdata); + fdata:= nil; + end; + fcount:= 0; + fdeleted:= 0; + fcapacity:= 0; +end; + +{ tsinglelinklist } + + +{ tdoublelinklist } + +function tdoublelinklist.getheadersize: integer; +begin + result:= sizeof(doublelinkheaderty); +end; + +procedure tdoublelinklist.delete(const aoffset: ptruint); +begin + with pdoublelinkheaderty(fdata+aoffset)^ do begin + pdoublelinkheaderty(fdata+prev)^.lh.next:= lh.next; + pdoublelinkheaderty(fdata+lh.next)^.prev:= prev; + end; + inherited; +end; + +end. diff --git a/mseide-msegui/lib/common/container/mselist.pas b/mseide-msegui/lib/common/container/mselist.pas new file mode 100644 index 0000000..c988c67 --- /dev/null +++ b/mseide-msegui/lib/common/container/mselist.pas @@ -0,0 +1,1861 @@ +{ MSEgui Copyright (c) 1999-2015 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mselist; +{$ifdef FPC}{$mode objfpc}{$h+}{$GOTO ON}{$interfaces corba}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + msetypes,msestrings,mseglob,Classes,sysutils,msesystypes,msearrayutils; + +type +// compareprocty = procedure (const l,r; var result: integer) of object; + + recordliststatety = (rels_needsinitialize,rels_needsfinalize,rels_needscopy, + rels_destroying); + recordliststatesty = set of recordliststatety; + + trecordlist = class(tnullinterfacedobject) + private + fcapacity: integer; + procedure checkindex(const index: integer); + procedure checkcapacity; + procedure setcapacity(Value: integer); + protected + frecordsize: integer; + fcount: integer; + fdata: pchar; + fstate: recordliststatesty; + procedure inccount; + procedure setcount(const Value: integer); + procedure setitem(const index: integer; const source); + procedure getitem(const index: integer; out dest); + function add(const source): integer; //returns index of new record + function add(): pointer; //returns pointer of new record + procedure insert(const source; const index: integer); + function getitempo(const index: integer): pointer; + //nil if index < 0 + //will be invalid after capacity change! + function isempty(var item): boolean; virtual; + procedure finalizerecord(var item); virtual; + procedure initializerecord(var item); virtual; + procedure copyrecord(var item); virtual; + procedure change; virtual; + property recordsize: integer read frecordsize; + public + constructor create(const arecordsize: integer; + const aoptions: recordliststatesty = []); + destructor destroy; override; + procedure assign(const source: trecordlist); + function invalidindex(const aindex: int32): boolean; inline; + function validindex(const aindex: int32): boolean; inline; + function datapo: pointer; + function dataend: pointer; //after datablock + function newitem: pointer; virtual; + function newitems(const acount: integer): pointer; virtual; + procedure deletelast; + procedure pack; + procedure clear; virtual; + procedure delete(const index: integer); //indexes < 0 are ignored + property count: integer read fcount write setcount; + property capacity: integer read fcapacity write setcapacity; + end; + + torderedrecordlist = class(trecordlist) + private + fsorted: boolean; + procedure setsorted(const avalue: boolean); +// procedure quicksort(var arangelist: integerarty; L, R: Integer); + procedure sort; + protected + fcomparefunc: sortcomparemethodty; + function internalfind(const item; out index: integer): boolean; + //true if exact else next bigger + //for comp: l is item, r are tablevalues + function add(const source): integer; + function indexof(const item): integer; + function deleteitem(const item): integer; + function getcomparefunc: sortcomparemethodty; virtual; abstract; + public + function newitem: pointer; override; + function newitems(const acount: integer): pointer; override; + property sorted: boolean read fsorted write setsorted; + end; + + trecordmap = class(trecordlist) + private + procedure setorder(const avalue: integer); + protected + fcomparefuncs: sortcomparemethodarty; + findexes: pointerararty; + fhasindex: boolean; + forder: integer; + procedure setitem(const index: integer; const source); + procedure getitem(const index: integer; out dest); + function internalgetitempo(const aorder: integer; + const index: integer): pointer; + function getitempo(const index: integer): pointer; + //nil if index < 0 + //will be invalid after capacity change! + procedure sort(const aindexnum: integer); + function internalfind(const aindexnum: integer; const item; + out aindex: integer; out adata: pointer): boolean; + //true if exact else next bigger + //for comp: l is item, r are tablevalues + procedure change; override; + procedure setcomparefuncs(const afuncs: array of sortcomparemethodty); + public + constructor create(const arecordsize: integer; + const aoptions: recordliststatesty = []); + property order: integer read forder write setorder default -1; + end; + + tpointerlist = class(tnullinterfacedobject) + private + fringpointer: integer; //for queue + function getcapacity: integer; + procedure inccount; + protected + fitems: pointerarty; + fcount: integer; + procedure normalizering; + procedure setitems(index: integer; const Value: pointer); + function getitems(index: integer): pointer; + procedure checkindex(var index: integer); virtual; + procedure setcapacity(Value: integer); virtual; + public + destructor destroy; override; + procedure clear; virtual; + function datapo: ppointeraty; + function add(const value: pointer): integer; + procedure add(const values: ppointer; const acount: int32); + function remove(const item: pointer): integer; + function delete(index: integer): pointer; virtual; + procedure insert(index: integer; const value: pointer); virtual; + function indexof(const item: pointer): integer; + function extract(const item: pointer): pointer; + + procedure order(const sourceorderlist: integerarty); + procedure reorder(const destorderlist: integerarty); + procedure sort(compare: arraysortcomparety); overload; + procedure sort(compare: arraysortcomparety; out indexlist: integerarty); overload; + + property items[index: integer]: pointer read getitems write setitems; default; + property count: integer read fcount; + property capacity: integer read getcapacity write setcapacity; + end; + + tpointerqueue = class(tpointerlist) + private + fmaxcount: integer; + procedure setmaxcount(const Value: integer); + protected + fnofinalize: integer; + procedure checkindex(var index: integer); override; + procedure setcapacity(value: integer); override; + procedure finalizeitem(var item: pointer); virtual; + public + function datapo: ppointeraty; virtual; + procedure clear; override; + function delete(index: integer): pointer; override; + function add(const value: pointer): integer; + function indexof(const item: pointer): integer; + //-1 if not found + procedure insert(index: integer; const value: pointer); override; + function getfirst: pointer; + function getlast: pointer; + property maxcount: integer read fmaxcount write setmaxcount; + end; + + tmethodlist = class(trecordlist) + private + function getitems(index: integer): tmethod; + procedure setitems(index: integer; const avalue: tmethod); + protected + factitem: integer; + public + constructor create; + function indexof(const value: tmethod): integer; + function add(const value: tmethod): integer; + //creates no duplicates + function remove(const value: tmethod): integer; + property items[index: integer]: tmethod read getitems + write setitems; default; + end; + + tobjectqueue = class(tpointerqueue) + private + protected + function getitems(index: integer): tobject; + procedure setitems(index: integer; const Value: tobject); + procedure finalizeitem(var item: pointer); override; + public + ownsobjects: boolean; + constructor create(aownsobjects: boolean); + procedure add(value: tobject); + procedure insert(const index: integer; const value: tobject); reintroduce; + function getfirst: tobject; + function getlast: tobject; + property items[index: integer]: tobject read getitems write setitems; + end; + + tlockedobjectqueue = class(tobjectqueue) + private + fmutex: mutexty; + function getitems(index: integer): tobject; + procedure setitems(index: integer; const Value: tobject); + protected + procedure lock; + procedure unlock; + procedure setcapacity(Value: integer); override; + public + constructor create(aownsobjects: boolean); + destructor destroy; override; + //items below are thread safe + procedure add(value: tobject); + procedure insert(const index: integer; const value: tobject); reintroduce; + function getfirst: tobject; + function getlast: tobject; + property items[index: integer]: tobject read getitems write setitems; + end; + + nameidty = integer; + + indexednameinfoty = record + name: string; + id: nameidty + end; + pindexednameinfoty = ^indexednameinfoty; + indexednameinfoaty = array[0..0] of indexednameinfoty; + pindexednameinfoaty = ^indexednameinfoaty; + + tindexednamelist = class(torderedrecordlist) + private + fidnames: stringarty; + function comp(const l,r): integer; + protected + procedure finalizerecord(var item); override; + procedure copyrecord(var item); override; + function getcomparefunc: sortcomparemethodty; override; + public + constructor create; + function add(const avalue: string): integer; + //returns id + function find(const avalue: string): integer; + //returns id, -1 if not found + function getname(const id: integer): string; + end; + + mseindexednameinfoty = record + name: msestring; + id: nameidty + end; + pmseindexednameinfoty = ^mseindexednameinfoty; + mseindexednameinfoaty = array[0..0] of mseindexednameinfoty; + pmseindexednameinfoaty = ^mseindexednameinfoaty; + + tmseindexednamelist = class(torderedrecordlist) + private + fidnames: msestringarty; + function comp(const l,r): integer; + protected + procedure finalizerecord(var item); override; + procedure copyrecord(var item); override; + function getcomparefunc: sortcomparemethodty; override; + public + constructor create; + function add(const avalue: msestring): integer; virtual; + //returns id + function find(const avalue: msestring): integer; virtual; + //returns id, -1 if not found + function getname(const id: integer): msestring; + end; + + tindexedfilenamelist = class(tmseindexednamelist) + public + function add(const avalue: msestring): integer; override; + //returns id + function find(const avalue: msestring): integer; override; + //returns id, -1 if not found + end; + + bufferoffsetty = ptrint; + + bufferheaderty = record + size: bufferoffsetty; + data: record + end; + end; + pbufferheaderty = ^bufferheaderty; + + bufferdataliststatety = (bdls_destroying); + bufferdataliststatesty = set of bufferdataliststatety; + tbufferdatalist = class + private + fbuffer: pointer; + fbuffersize: bufferoffsetty; + fbuffercapacity: bufferoffsetty; + fnextitem: bufferoffsetty; + protected + fstate: bufferdataliststatesty; + function adddata(asize: int32): pointer; virtual; + function adddata(const asize: int32; out aoffset: bufferoffsetty): pointer; + public + constructor create(); + destructor destroy(); override; + procedure checkcapacity(const asize: int32); + procedure clear(); virtual; + procedure mark(out ref: bufferoffsetty); + procedure release(const ref: bufferoffsetty); + function absdata(const aoffset: bufferoffsetty): pointer; inline; + function firstdata: pointer; //nil if none + function nextdata: pointer; //nil if none + end; + + tindexbufferdatalist = class(tbufferdatalist) + private + findex: ptrintarty; + fcapacity: int32; + function getitems(index: integer): pointer; + protected + fcount: int32; + function adddata(asize: int32): pointer; override; + public + procedure clear(); override; + property items[index: integer]: pointer read getitems; + property count: int32 read fcount; + end; + +implementation +uses + rtlconsts,msebits,msedatalist,msesysintf1,msesysintf; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +const + growstep = 32; + +{ +procedure QuickSort1(var indexlist: array of integer; SortList: PPointerList; L, R: Integer; + SCompare: TListSortCompare); + //bei compareresult = 0 wird urspruengliche ordnung beibehalten +var + I, J: Integer; + P, T: Pointer; + pivotindex: integer; + pivotoffset: integer; + int1: integer; +label + 1,2; +begin + repeat + I := L; + J := R; + pivotindex:= (L + R) shr 1; + pivotoffset:= indexlist[pivotindex]; + P := SortList^[pivotindex]; + repeat +1: + int1:= SCompare(SortList^[I], P); + if int1 = 0 then begin + int1:= indexlist[i]-pivotoffset; + end; + if int1 < 0 then begin + inc(i); + goto 1; + end; + +// while SCompare(SortList^[I], P) < 0 do +// Inc(I); +2: + int1:= SCompare(SortList^[J], P); + if int1 = 0 then begin + int1:= indexlist[j]-pivotoffset; + end; + if int1 > 0 then begin + dec(j); + goto 2; + end; +// while SCompare(SortList^[J], P) > 0 do +// Dec(J); + if I <= J then + begin + T := SortList^[I]; + int1:= indexlist[i]; + SortList^[I] := SortList^[J]; + indexlist[I] := indexList[J]; + SortList^[J] := T; + indexlist[J] := int1; + Inc(I); + Dec(J); + end; + until I > J; + if L < J then + QuickSort1(indexlist,SortList, L, J, SCompare); + L := I; + until I >= R; +end; + +procedure QuickSortmse(SortList: PPointerList; count: integer; + SCompare: TListSortCompare; out indexlist: integerarty); + //on compareresult = 0 order remains unchanged +var + int1: integer; +begin + setlength(indexlist,count); + if count > 0 then begin + for int1:= 0 to count -1 do begin + indexlist[int1]:= int1; + end; + quicksort1(indexlist,sortlist,0,count-1,scompare); + end; +end; +} +{ tlistmse } +{ +procedure tlistmse.Sort(Compare: TListSortCompare); +var + indexlist: integerarty; +begin + sort(compare,indexlist) +end; + +procedure tlistmse.Sort(Compare: TListSortCompare; out indexlist: integerarty); +begin + if (List <> nil) and (Count > 0) then begin + QuickSortmse(List, Count, Compare,indexlist); + end; +end; +} + +{ trecordlist } + +constructor trecordlist.create(const arecordsize: integer; + const aoptions: recordliststatesty = []); +begin + frecordsize:= arecordsize; + fstate:= aoptions; +end; + +destructor trecordlist.destroy; +begin + clear; + if fdata <> nil then begin + freemem(fdata); + end; + inherited; +end; + +procedure trecordlist.assign(const source: trecordlist); +var + int1: integer; + po1: pchar; +begin + if (rels_needsinitialize in fstate) or (source.ClassType <> self.ClassType) then begin + raise exception.Create('Can not assign'); + end; + clear; + count:= source.count; + move(source.datapo^,fdata^,count*frecordsize); + if rels_needscopy in fstate then begin + po1:= fdata; + for int1:= 0 to fcount - 1 do begin + copyrecord(po1^); + inc(po1,frecordsize); + end; + end; +end; + +function trecordlist.datapo: pointer; +begin + result:= fdata; +end; + +function trecordlist.dataend: pointer; +begin + result:= fdata+fcount*frecordsize; +end; + +function trecordlist.newitem: pointer; +begin + inccount; + result:= getitempo(fcount - 1); +end; + +function trecordlist.newitems(const acount: integer): pointer; +var + int1: integer; +begin + if acount > 0 then begin + int1:= fcount; + count:= count + acount; + result:= fdata + int1 * frecordsize; + end + else begin + result:= nil; + end; +end; + +procedure trecordlist.deletelast; +begin + delete(fcount - 1); +end; + +procedure trecordlist.setcapacity(Value: integer); +begin + if value < fcount then begin + value:= fcount; + end; + if fcapacity <> value then begin + fcapacity := Value; + reallocmem(fdata,value*frecordsize); + end; +end; + +procedure trecordlist.checkcapacity; +begin + if fcapacity > fcount + fcount div 4 + 2*growstep then begin + capacity:= fcount + fcount div 8 + growstep; + end; +end; + +procedure trecordlist.setcount(const Value: integer); +var + int1: integer; + po1: pchar; +begin + if value <> fcount then begin + if value > fcount then begin + if fcapacity < value then begin + capacity:= value + value div 8 + growstep; + end; + fillchar((fdata+fcount*frecordsize)^,(value-fcount)*frecordsize,0); + if rels_needsinitialize in fstate then begin + po1:= fdata + fcount * frecordsize; + for int1:= fcount to value - 1 do begin + initializerecord(po1^); + inc(po1,frecordsize); + end; + end; + fcount:= value; + end + else begin + if rels_needsfinalize in fstate then begin + po1:= fdata + value * frecordsize; + for int1:= value to fcount - 1 do begin + finalizerecord(po1^); + inc(po1,frecordsize); + end; + end; + fcount:= value; + checkcapacity; + end; + change; + end; +end; + +procedure trecordlist.inccount; +begin + count:= fcount + 1; + { + inc(fcount); + if fcapacity < fcount then begin + capacity:= fcount + fcount div 8 + growstep; + end; +} +end; + +function trecordlist.add(const source): integer; +var + po1: pointer; +begin + result:= fcount; + inccount; + po1:= fdata + result * frecordsize; + move(source,po1^,frecordsize); + if rels_needscopy in fstate then begin + copyrecord(po1^); + end; +end; + +function trecordlist.add: pointer; +begin + inccount(); + result:= pointer(fdata) + (fcount - 1) * frecordsize; +end; + + +procedure trecordlist.insert(const source; const index: integer); +var + po1: pchar; +begin + inccount; + po1:= fdata+index*frecordsize; + move(po1^,(po1+frecordsize)^,(count-index-1)*frecordsize); + move(source,po1^,frecordsize); + if rels_needscopy in fstate then begin + copyrecord(po1^); + end; +end; + +procedure trecordlist.checkindex(const index: integer); +begin + if (index < 0) or (index >= fcount) then begin + tlist.error(slistindexerror,index); + end; +end; + +procedure trecordlist.getitem(const index: integer; out dest); +var + po1: pchar; +begin + checkindex(index); + po1:= fdata+index*frecordsize; + move(po1^,dest,frecordsize); + if rels_needscopy in fstate then begin + copyrecord(po1^); + end; +end; + +function trecordlist.getitempo(const index: integer): pointer; +//var +// int1: integer; +begin + if index < 0 then begin + result:= nil; + end + else begin +// int1:= index; + checkindex(index); + result:= fdata + index * frecordsize; + end; +end; + +procedure trecordlist.setitem(const index: integer; const source); +var + po1: pchar; +begin + checkindex(index); + po1:= fdata+index*frecordsize; + if rels_needsfinalize in fstate then begin + finalizerecord(po1^); + end; + move(source,(po1)^,frecordsize); + if rels_needscopy in fstate then begin + copyrecord(po1^); + end; + change; +end; + +procedure trecordlist.clear; +begin + count:= 0; +end; + +procedure trecordlist.delete(const index: integer); +begin + if index >= 0 then begin + checkindex(index); + if rels_needsfinalize in fstate then begin + finalizerecord((fdata+index*frecordsize)^); + end; + if index < count-1 then begin + move((fdata+(index+1)*frecordsize)^,(fdata+index*frecordsize)^, + (fcount-index-1)*frecordsize); + end; + fcount:= fcount-1; + checkcapacity; + end; +end; + +function trecordlist.isempty(var item): boolean; +begin + result:= iszero(@item,frecordsize); +end; + +procedure trecordlist.pack; +var + po1,po2,po3: pchar; + int1,int2: integer; +begin + if fcount <> 0 then begin + getmem(po1,fcount*frecordsize); + po3:= po1; + po2:= fdata; + int2:= 0; + for int1:= 0 to fcount -1 do begin + if not isempty(po2^) then begin + move(po2^,po3^,frecordsize); + inc(int2); + inc(po3,frecordsize); + end; + inc(po2,frecordsize); + end; + freemem(fdata); + fdata:= po1; + fcount:= int2; + fcapacity:= fcount; + if fcount > 0 then begin + reallocmem(fdata,fcount*frecordsize); + end + else begin + freemem(fdata); + fdata:= nil; + end; + change; + end; +end; + +procedure trecordlist.initializerecord(var item); +begin + //dummy +end; + +procedure trecordlist.finalizerecord(var item); +begin + //dummy +end; + +procedure trecordlist.copyrecord(var item); +begin + //dummy +end; + +procedure trecordlist.change; +begin + //dummy +end; + +function trecordlist.invalidindex(const aindex: int32): boolean; +begin + result:= (aindex < 0) or (aindex >= fcount); +end; + +function trecordlist.validindex(const aindex: int32): boolean; +begin + result:= (aindex >= 0) and (aindex < fcount); +end; + +{ torderedrecordlist } + +function torderedrecordlist.add(const source): integer; +begin + if fsorted then begin + internalfind(source,result); + insert(source,result); + end + else begin + result:= inherited add(source); + end; +end; + +procedure torderedrecordlist.setsorted(const avalue: boolean); +begin + if avalue <> fsorted then begin + if avalue then begin + sort; + end; + fsorted:= avalue; + end; +end; +(* +procedure torderedrecordlist.quicksort(var arangelist: integerarty; L, R: Integer); +var + I, J: Integer; + P, T: integer; + int1: integer; + pp: pointer; +begin + if r >= l then begin + repeat + I := L; + J := R; + P := arangelist[(L + R) shr 1]; + pp:= fdata+p*frecordsize; + repeat + repeat + int1:= fcomparefunc((fdata+arangeList[I]*frecordsize)^, pp^); + if int1 = 0 then begin + int1:= arangelist[i] - p; + end; + if int1 >= 0 then break; + inc(i); + until false; + repeat + int1:= fcomparefunc((fdata+arangeList[J]*frecordsize)^, pp^); + if int1 = 0 then begin + int1:= arangelist[j] - p; + end; + if int1 <= 0 then break; + dec(j); + until false; +// while (sortfunc(List.items[I], P,self) < 0) do Inc(I); +// while (sortfunc(List.items[J], P,self) > 0) do Dec(J); + if I <= J then + begin + if i <> j then begin + T := arangeList[I]; + arangeList[I] := arangeList[J]; + arangeList[J] := T; + end; + Inc(I); + Dec(J); + end; + until I > J; + if L < J then QuickSort(arangelist,L, J); + L := I; + until I >= R; + end; +end; +*) +procedure torderedrecordlist.sort; + + +var + arangelist: integerarty; + int1: integer; + po1,po2: pchar; +begin + fcomparefunc:= getcomparefunc(); + if fcount > 0 then begin +// setlength(arangelist,fcount); +// for int1:= 0 to high(arangelist) do begin +// arangelist[int1]:= int1; +// end; +// quicksort(arangelist,0,fcount-1); + mergesort(fdata,frecordsize,fcount,fcomparefunc,arangelist); + getmem(po1,fcount*frecordsize); + po2:= po1; + for int1:= 0 to high(arangelist) do begin + move((fdata+arangelist[int1]*frecordsize)^,po2^,frecordsize); + inc(po2,frecordsize); + end; + freemem(fdata); + fdata:= po1; + fcapacity:= fcount; + end; +end; + +function torderedrecordlist.internalfind(const item; out index: integer): boolean; +var + ilo,ihi:integer; + int1,int2: integer; +// bo1: boolean; +begin + sorted:= true; + index:= fcount; + result:= false; + if fcount > 0 then begin + ilo:= 0; + ihi:= fcount - 1; +// bo1:= false; + while true do begin + int1:= (ilo + ihi) div 2; + int2:= fcomparefunc(item,(fdata+int1*frecordsize)^); +// if int2 = 0 then begin +// index:= int1; +// result:= true; +// break; +// end +// else begin + if int2 >= 0 then begin //item <= pivot + if int2 = 0 then begin + result:= true; //found + end; + if ihi = ilo then begin + index:= ihi + 1; + break; + end; + if ilo = int1 then begin + inc(ilo); + end + else begin + ilo:= int1; + end; + end + else begin //item > pivot + if ihi = ilo then begin + index:= ihi; + break; + end; + ihi:= int1; +// end; + end; + end; + if result then begin + dec(index); + end; + end; +end; + +function torderedrecordlist.indexof(const item): integer; +begin + if not internalfind(item,result) then begin + result:= -1; + end; +end; + +function torderedrecordlist.deleteitem(const item): integer; +begin + result:= indexof(item); + if result >= 0 then begin + delete(result); + end; +end; + +function torderedrecordlist.newitem: pointer; +begin + fsorted:= false; + result:= inherited newitem; +end; + +function torderedrecordlist.newitems(const acount: integer): pointer; +begin + fsorted:= false; + result:= inherited newitems(acount); +end; + +{ tpointerlist } + +destructor tpointerlist.destroy; +begin + clear; + inherited; +end; +function tpointerlist.getcapacity: integer; +begin + result:= length(fitems); +end; + +procedure tpointerlist.setcapacity(Value: integer); +begin + if value < fcount then begin + value:= fcount; + end; + setlength(fitems,value); +end; + +procedure tpointerlist.checkindex(var index: integer); +begin + if (index < 0) or (index >= fcount) then begin + tlist.error(slistindexerror,index); + end; +end; + +procedure tpointerlist.setitems(index: integer; const Value: pointer); +begin + checkindex(index); + fitems[index]:= value; +end; + +function tpointerlist.getitems(index: integer): pointer; +begin + checkindex(index); + result:= fitems[index]; +end; + +procedure tpointerlist.normalizering; +var + ar1: pointerarty; + int1: integer; +begin + if fringpointer <> 0 then begin + if fringpointer + fcount > length(fitems) then begin //2 pieces + setlength(ar1,count); + int1:= length(fitems)-fringpointer; + move(fitems[fringpointer],ar1[0], + int1*sizeof(pointer)); + move(fitems[0],ar1[int1], + (fcount-int1)*sizeof(pointer)); + fitems:= ar1; + end + else begin + move(fitems[fringpointer],fitems[0],fcount*sizeof(pointer)); + end; + fringpointer:= 0; + end; +end; + +procedure tpointerlist.inccount; +begin + if fcount >= length(fitems) then begin + capacity:= fcount + fcount div 4 + 32; + end; + inc(fcount); +end; + +function tpointerlist.add(const value: pointer): integer; +begin + inccount; + result:= fcount - 1; + setitems(result,value); +end; + +procedure tpointerlist.add(const values: ppointer; const acount: int32); +var + i1: int32; +begin + normalizering(); + i1:= fcount; + fcount:= fcount + acount; + if fcount >= length(fitems) then begin + capacity:= fcount + fcount div 4 + 32; + end; + move(values^,fitems[i1],acount * sizeof(pointer)); +end; + +procedure tpointerlist.clear; +begin + fcount:= 0; +end; + +function tpointerlist.indexof(const item: pointer): integer; +var + int1: integer; +begin + result:= -1; + for int1:= 0 to fcount - 1 do begin + if fitems[int1] = item then begin + result:= int1; + exit; + end; + end; +end; + +function tpointerlist.delete(index: integer): pointer; +begin + checkindex(index); + result:= fitems[index]; + move(fitems[index+1],fitems[index],(fcount-index-1)*sizeof(pointer)); + dec(fcount); +end; + +function tpointerlist.remove(const item: pointer): integer; +begin + result:= indexof(item); + if result >= 0 then begin + delete(result); + end; +end; + +procedure tpointerlist.insert(index: integer; const value: pointer); +begin + if index = fcount then begin + add(value); + end + else begin + checkindex(index); + inccount; + move(fitems[index],fitems[index+1],(fcount-index-1)*sizeof(pointer)); + fitems[index]:= value; + end; +end; + +function tpointerlist.extract(const item: pointer): pointer; +var + int1: integer; +begin + int1:= indexof(item); + if int1 >= 0 then begin + result:= fitems[int1]; + delete(int1); + end + else begin + result:= nil; + end; +end; + +procedure tpointerlist.order(const sourceorderlist: integerarty); +var + int1: integer; + ar1: pointerarty; +begin + normalizering; + allocuninitedarray(length(fitems),sizeof(pointer),ar1); + for int1:= 0 to fcount - 1 do begin + ar1[int1]:= fitems[sourceorderlist[int1]]; + end; + fitems:= ar1; +end; + +procedure tpointerlist.reorder(const destorderlist: integerarty); +var + int1: integer; + ar1: pointerarty; +begin + normalizering; + allocuninitedarray(length(fitems),sizeof(pointer),ar1); + for int1:= 0 to fcount - 1 do begin + ar1[destorderlist[int1]]:= fitems[int1]; + end; + fitems:= ar1; +end; + +procedure tpointerlist.sort(compare: arraysortcomparety; + out indexlist: integerarty); +begin + mergesortarray(fitems,sizeof(pointer),fcount,compare,indexlist,false); + order(indexlist); +end; + +procedure tpointerlist.sort(compare: arraysortcomparety); +var + indexlist: integerarty; +begin + sort(compare,indexlist); +end; + +function tpointerlist.datapo: ppointeraty; +begin + result:= ppointeraty(pointer(fitems)); +end; + +{ tpointerqueue } + +procedure tpointerqueue.checkindex(var index: integer); +begin + inherited; + inc(index,fringpointer); + if index >= length(fitems) then begin + dec(index,length(fitems)); + end; +end; + +function tpointerqueue.delete(index: integer): pointer; +begin + normalizering; + result:= inherited delete(index); + if fnofinalize = 0 then begin + finalizeitem(result); + end; +end; + +procedure tpointerqueue.clear; +var + int1: integer; +begin + normalizering; + if fnofinalize = 0 then begin + for int1:= 0 to fcount - 1 do begin + finalizeitem(fitems[int1]); + end; + end; + inherited; +end; + +procedure tpointerqueue.insert(index: integer; const value: pointer); +begin + normalizering; + inherited; +end; + +function tpointerqueue.getfirst: pointer; +begin + if fcount = 0 then begin + result:= nil; + end + else begin + result:= fitems[fringpointer]; + dec(fcount); + inc(fringpointer); + if fringpointer >= length(fitems) then begin + dec(fringpointer,length(fitems)); + end; + end; +end; + +function tpointerqueue.getlast: pointer; +begin + if fcount = 0 then begin + result:= nil; + end + else begin + result:= items[fcount-1]; + dec(fcount); + end; +end; + +function tpointerqueue.indexof(const item: pointer): integer; +var + int1: integer; +begin + result:= -1; + for int1:= fringpointer to fcount - 1 do begin + if int1 >= length(fitems) then begin + break; + end; + if fitems[int1] = item then begin + result:= int1; + exit; + end; + end; + for int1:= 0 to count - (length(fitems) - fringpointer) - 1 do begin + if fitems[int1] = item then begin + result:= int1; + exit; + end; + end; +end; + +procedure tpointerqueue.setcapacity(Value: integer); +begin + normalizering; + inherited; +end; + +function tpointerqueue.add(const value: pointer): integer; +begin + if (fmaxcount <> 0) and (fcount >= fmaxcount) then begin + finalizeitem(fitems[fringpointer]); + getfirst; + end; + result:= inherited add(value); +end; + +procedure tpointerqueue.setmaxcount(const Value: integer); +var + int1: integer; +begin + fmaxcount := Value; + if (fmaxcount <> 0) and (fcount > fmaxcount) then begin + normalizering; + for int1:= 0 to fcount-fmaxcount-1 do begin + finalizeitem(fitems[int1]); + end; + fringpointer:= fcount-fmaxcount; + fcount:= fmaxcount; + capacity:= fmaxcount; + end; +end; + +procedure tpointerqueue.finalizeitem(var item: pointer); +begin + //dummy +end; + +function tpointerqueue.datapo: ppointeraty; +begin + normalizering; + result:= inherited datapo; +end; + +{ tobjectqueue } + +procedure tobjectqueue.finalizeitem(var item: pointer); +begin + if ownsobjects then begin + tobject(item).Free; + item:= nil; + end; +end; + +function tobjectqueue.getitems(index: integer): tobject; +begin + result:= tobject(inherited getitems(index)); +end; + +procedure tobjectqueue.setitems(index: integer; const Value: tobject); +begin + inherited setitems(index,value); +end; + +function tobjectqueue.getfirst: tobject; +begin + result:= tobject(inherited getfirst); +end; + +function tobjectqueue.getlast: tobject; +begin + result:= tobject(inherited getlast); +end; + +procedure tobjectqueue.add(value: tobject); +begin + inherited add(value); +end; + +procedure tobjectqueue.insert(const index: integer; const value: tobject); +begin + inherited insert(index,value); +end; + +constructor tobjectqueue.create(aownsobjects: boolean); +begin + ownsobjects:= aownsobjects; + inherited create; +end; + +{ tmethodlist } + +function tmethodlist.add(const value: tmethod): integer; +begin + result:= indexof(value); + if result < 0 then begin + result:= inherited add(value); + end; +end; + +constructor tmethodlist.create; +begin + inherited create(sizeof(tmethod)); +end; + +function tmethodlist.indexof(const value: tmethod): integer; +var + po1: pmethod; + int1: integer; + +begin + result:= -1; + po1:= pmethod(fdata); + for int1:= 0 to fcount - 1 do begin + if issamemethod(value,po1^) then begin + result:= int1; + break; + end; + inc(po1); + end; +end; + +function tmethodlist.remove(const value: tmethod): integer; +begin + result:= indexof(value); + if result >= 0 then begin + delete(result); + if result <= factitem then begin + dec(factitem); + end; + end; +end; + +function tmethodlist.getitems(index: integer): tmethod; +begin + checkindex(index); + result:= pmethod(fdata+index*sizeof(tmethod))^; +end; + +procedure tmethodlist.setitems(index: integer; const avalue: tmethod); +begin + checkindex(index); + pmethod(fdata+index*sizeof(tmethod))^:= avalue; +end; + +{ tindexednamelist } + +constructor tindexednamelist.create; +begin + inherited create(sizeof(indexednameinfoty),[rels_needsfinalize,rels_needscopy]); +end; + +function tindexednamelist.add(const avalue: string): integer; +var + info: indexednameinfoty; +begin + info.name:= avalue; + result:= find(avalue); + if result < 0 then begin + additem(fidnames,avalue); + info.id:= high(fidnames); + result:= info.id; + inherited add(info); + end; +end; + +procedure tindexednamelist.finalizerecord(var item); +begin + finalize(indexednameinfoty(item)); +end; + +procedure tindexednamelist.copyrecord(var item); +begin + with mseindexednameinfoty(item) do begin + stringaddref(name); + end; +end; + +function tindexednamelist.comp(const l,r): integer; +var + int1: integer; +begin + result:= (length(indexednameinfoty(l).name) - + length(indexednameinfoty(r).name)) shl 16; + if result = 0 then begin + for int1:= length(indexednameinfoty(l).name) - 1 downto 0 do begin + result:= integer(pcharaty(indexednameinfoty(l).name)^[int1]) - + integer(pcharaty(indexednameinfoty(r).name)^[int1]); + if result <> 0 then begin + break; + end; + end; + end; +end; + +function tindexednamelist.getcomparefunc: sortcomparemethodty; +begin + result:= {$ifdef FPC}@{$endif}comp; +end; + +function tindexednamelist.find(const avalue: string): integer; +var + info: indexednameinfoty; + int1: integer; +begin + info.name:= avalue; + if internalfind(info,int1) then begin + result:= pindexednameinfoaty(datapo)^[int1].id; + end + else begin + result:= -1; + end; +end; + +function tindexednamelist.getname(const id: integer): string; +begin + if (id < 0) or (id > high(fidnames)) then begin + result:= ''; + end + else begin + result:= fidnames[id]; + end; +end; + + +{ tmseindexednamelist } + +constructor tmseindexednamelist.create; +begin + inherited create(sizeof(mseindexednameinfoty),[rels_needsfinalize,rels_needscopy]); +end; + +function tmseindexednamelist.add(const avalue: msestring): integer; +var + info: mseindexednameinfoty; +begin + info.name:= avalue; + result:= find(avalue); + if result < 0 then begin + additem(fidnames,avalue); + info.id:= high(fidnames); + result:= info.id; + inherited add(info); + end; +end; + +procedure tmseindexednamelist.finalizerecord(var item); +begin + finalize(mseindexednameinfoty(item)); +end; + +procedure tmseindexednamelist.copyrecord(var item); +begin + with mseindexednameinfoty(item) do begin + stringaddref(name); + end; +end; + +function tmseindexednamelist.comp(const l,r): integer; +var + int1: integer; +begin + result:= (length(mseindexednameinfoty(l).name) - + length(mseindexednameinfoty(r).name)) shl 16; + if result = 0 then begin + for int1:= length(mseindexednameinfoty(l).name) - 1 downto 0 do begin + result:= integer(pmsecharaty(mseindexednameinfoty(l).name)^[int1]) - + integer(pmsecharaty(mseindexednameinfoty(r).name)^[int1]); + if result <> 0 then begin + break; + end; + end; + end; +end; + +function tmseindexednamelist.getcomparefunc: sortcomparemethodty; +begin + result:= {$ifdef FPC}@{$endif}comp; +end; + +function tmseindexednamelist.find(const avalue: msestring): integer; +var + info: mseindexednameinfoty; + int1: integer; +begin + info.name:= avalue; + if internalfind(info,int1) then begin + result:= pmseindexednameinfoaty(datapo)^[int1].id; + end + else begin + result:= -1; + end; +end; + +function tmseindexednamelist.getname(const id: integer): msestring; +begin + if (id < 0) or (id > high(fidnames)) then begin + result:= ''; + end + else begin + result:= fidnames[id]; + end; +end; + +{ tindexedfilenamelist } + +function tindexedfilenamelist.add(const avalue: msestring): integer; +begin + if sys_filesystemiscaseinsensitive then begin + result:= inherited add(mselowercase(avalue)); + end + else begin + result:= inherited add(avalue); + end; +end; + +function tindexedfilenamelist.find(const avalue: msestring): integer; +begin + if sys_filesystemiscaseinsensitive then begin + result:= inherited find(mselowercase(avalue)); + end + else begin + result:= inherited find(avalue); + end; +end; + +{ tlockedobjectqueue } + +constructor tlockedobjectqueue.create(aownsobjects: boolean); +begin + sys_mutexcreate(fmutex); + inherited; +end; + +destructor tlockedobjectqueue.destroy; +begin + inherited; + sys_mutexdestroy(fmutex); +end; + +function tlockedobjectqueue.getitems(index: integer): tobject; +begin + lock; + result:= inherited getitems(index); + unlock; +end; + +procedure tlockedobjectqueue.setitems(index: integer; const Value: tobject); +begin + lock; + inherited setitems(index,value); + unlock; +end; + +procedure tlockedobjectqueue.lock; +begin + sys_mutexlock(fmutex); +end; + +procedure tlockedobjectqueue.unlock; +begin + sys_mutexunlock(fmutex); +end; + +procedure tlockedobjectqueue.setcapacity(Value: integer); +begin + lock; + inherited; + unlock; +end; + +procedure tlockedobjectqueue.add(value: tobject); +begin + lock; + inherited add(value); + unlock; +end; + +procedure tlockedobjectqueue.insert(const index: integer; const value: tobject); +begin + lock; + inherited insert(index,value); + unlock; +end; + +function tlockedobjectqueue.getfirst: tobject; +begin + lock; + result:= inherited getfirst; + unlock; +end; + +function tlockedobjectqueue.getlast: tobject; +begin + lock; + result:= inherited getlast; + unlock; +end; + +{ trecordmap } + +constructor trecordmap.create(const arecordsize: integer; + const aoptions: recordliststatesty = []); +begin + forder:= -1; + inherited; +end; + +procedure trecordmap.change; +var + int1: integer; +begin + if fhasindex then begin + for int1:= 0 to high(findexes) do begin + findexes[int1]:= nil; + end; + fhasindex:= false; + end; +end; + +procedure trecordmap.setcomparefuncs(const afuncs: array of sortcomparemethodty); +var + int1: integer; +begin + if forder > high(afuncs) then begin + forder:= -1; + end; + change; + setlength(findexes,length(afuncs)); + setlength(fcomparefuncs,length(afuncs)); + for int1:= 0 to high(fcomparefuncs) do begin + fcomparefuncs[int1]:= afuncs[int1]; + end; +end; + +procedure trecordmap.sort(const aindexnum: integer); +begin + mergesortpointer(fdata,frecordsize,fcount,fcomparefuncs[aindexnum], + findexes[aindexnum]); + fhasindex:= true; +end; + +function trecordmap.internalfind(const aindexnum: integer; const item; + out aindex: integer; out adata: pointer): boolean; +begin + result:= false; + aindex:= -1; + adata:= nil; + if fcount > 0 then begin + if findexes[aindexnum] = nil then begin + sort(aindexnum); + end; + result:= findarrayitem(item,findexes[aindexnum], + fcomparefuncs[aindexnum],aindex); + if aindex < fcount then begin + adata:= findexes[aindexnum][aindex]; + end; + end; +end; + +function trecordmap.internalgetitempo(const aorder: integer; + const index: integer): pointer; +begin + checkindex(index); + if aorder >= 0 then begin + if findexes[aorder] = nil then begin + sort(aorder); + end; + result:= findexes[aorder][index]; + end + else begin + result:= fdata + index * frecordsize; + end; +end; + +procedure trecordmap.setitem(const index: integer; const source); +var + po1: pointer; +begin + po1:= internalgetitempo(forder,index); + if rels_needsfinalize in fstate then begin + finalizerecord(po1^); + end; + move(source,(po1)^,frecordsize); + if rels_needscopy in fstate then begin + copyrecord(po1^); + end; + change; +end; + +procedure trecordmap.getitem(const index: integer; out dest); +var + po1: pointer; +begin + po1:= internalgetitempo(forder,index); + move(po1^,dest,frecordsize); + if rels_needscopy in fstate then begin + copyrecord(po1^); + end; +end; + +function trecordmap.getitempo(const index: integer): pointer; +begin + result:= nil; + if index >= 0 then begin + result:= internalgetitempo(forder,index); + end; +end; + +procedure trecordmap.setorder(const avalue: integer); +begin + if (avalue < -1) or (avalue > high(findexes)) then begin + raise exception.create('Invalid order index '+inttostr(avalue)+'.'); + end; + forder:= avalue; +end; + +{ tbufferdatalist } + +constructor tbufferdatalist.create; +begin +end; + +destructor tbufferdatalist.destroy(); +begin + include(fstate,bdls_destroying); + clear(); +end; + +procedure tbufferdatalist.clear; +begin + if fbuffer <> nil then begin + freemem(fbuffer); + fbuffer:= nil; + fbuffersize:= 0; + fbuffercapacity:= 0; + end; +end; + +procedure tbufferdatalist.mark(out ref: bufferoffsetty); +begin + ref:= fbuffersize; +end; + +procedure tbufferdatalist.release(const ref: bufferoffsetty); +begin + fbuffersize:= ref; +end; + +function tbufferdatalist.absdata(const aoffset: bufferoffsetty): pointer; +begin + result:= fbuffer + aoffset; +end; + +procedure tbufferdatalist.checkcapacity(const asize: int32); +begin + fbuffersize:= fbuffersize + ((asize+3) and not 3); //4 byte align + if fbuffersize > fbuffercapacity then begin + fbuffercapacity:= fbuffersize*2 + 1024; + reallocmem(fbuffer,fbuffercapacity); + end; +end; +{ +procedure tbufferdatalist.add(const asize: int32); +begin + checkcapacity(asize); + fbuffersize:= fbuffersize + asize; +end; +} + +function tbufferdatalist.adddata(asize: int32): pointer; +var + i1: bufferoffsetty; +begin + asize:= asize + sizeof(bufferheaderty); + i1:= fbuffersize; + checkcapacity(asize); + result:= fbuffer + i1; + pbufferheaderty(result)^.size:= fbuffersize-i1; + inc(result,sizeof(bufferheaderty)); +end; + +function tbufferdatalist.adddata(const asize: int32; + out aoffset: bufferoffsetty): pointer; +begin + aoffset:= fbuffersize; + result:= adddata(asize); +end; + +function tbufferdatalist.firstdata: pointer; +begin + result:= nil; + if fbuffersize > 0 then begin + result:= fbuffer; + fnextitem:= pbufferheaderty(result)^.size; + inc(result,sizeof(bufferheaderty)); + end; +end; + +function tbufferdatalist.nextdata: pointer; +begin + result:= nil; + if fnextitem < fbuffersize then begin + result:= fbuffer + fnextitem; + inc(fnextitem,pbufferheaderty(result)^.size); + inc(result,sizeof(bufferheaderty)); + end; +end; + +{ tindexbufferdatalist } + +procedure tindexbufferdatalist.clear; +begin + inherited; + findex:= nil; + fcount:= 0; + fcapacity:= 0; +end; + +function tindexbufferdatalist.adddata(asize: int32): pointer; +begin + result:= inherited adddata(asize); + if fcount >= fcapacity then begin + fcapacity:= 2*fcount + 1024; + reallocuninitedarray(fcapacity,sizeof(findex[0]),findex); + end; + findex[fcount]:= result-fbuffer; + inc(fcount); +end; + +function tindexbufferdatalist.getitems(index: integer): pointer; +begin + if (index < 0) or (index >= fcount) then begin + tlist.error(slistindexerror,index); + end; + result:= fbuffer + findex[index]{ + sizeof(bufferheaderty)}; +end; + +end. + + + + + diff --git a/mseide-msegui/lib/common/container/msestringident.pas b/mseide-msegui/lib/common/container/msestringident.pas new file mode 100644 index 0000000..02f29ce --- /dev/null +++ b/mseide-msegui/lib/common/container/msestringident.pas @@ -0,0 +1,573 @@ +{ MSEgui Copyright (c) 2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msestringident; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + {globtypes,}msehash,msestrings,msetypes; + +//{$define caseinsensitive} +const + firstident = 256; + stridstart = $12345678; //not used + strid0 = $2468ACF1; + strid1 = $48D159E3; + strid2 = $91A2B3C6; + strid3 = $2345678C; + strid4 = $468ACF19; + strid5 = $8D159E33; + strid6 = $1A2B3C66; + strid7 = $345678CD; + strid8 = $68ACF19B; + strid9 = $D159E337; + +type +// keywordty = identty; + + identnamety = record + offset: int32; //relative to data block + end; + + identheaderty = record + ident: identty; + end; + + pidentheaderty = ^identheaderty; + identoffsetty = int32; + + identdataty = record + header:identheaderty; + keyname: identoffsetty; // +// keylen: integer; + end; + identhashdataty = record + header: hashheaderty; + data: identdataty; + end; + pidenthashdataty = ^identhashdataty; + + tidenthashdatalist = class(thashdatalist) + protected + function hashkey(const akey): hashvaluety; override; + function checkkey(const akey; const aitem: phashdataty): boolean; override; + function getrecordsize(): int32 override; + public +// constructor create(const asize: int32); + //total datasize including identheaderty + function adduniquedata(const akey: identty; + out adata: pidenthashdataty): boolean; + //false if duplicate + end; + + tstringidents = class; +// tidenthashdatalist = class; + + indexidentdataty = record + key: identnamety; //index of null terminated string + data: identty; + end; + pindexidentdataty = ^indexidentdataty; + indexidenthashdataty = record + header: hashheaderty; + data: indexidentdataty; + end; + pindexidenthashdataty = ^indexidenthashdataty; + + tindexidenthashdatalist = class(thashdatalist) +// {$ifdef mse_debugparser} + private + fidents: tidenthashdatalist; +// {$endif} + protected + fowner: tstringidents; + function hashkey(const akey): hashvaluety; override; + function checkkey(const akey; const aitem: phashdataty): boolean; override; + function getrecordsize(): int32 override; + public + constructor create(const aowner: tstringidents); + destructor destroy; override; + procedure clear; override; + function identname(const aident: identty; out aname: lstringty): boolean; + function identname(const aident: identty; out aname: identnamety): boolean; + function getident(const aname: lstringty): pindexidenthashdataty; + end; + + tstringidents = class + protected + fstringident: identty; + fidentlist: tindexidenthashdatalist; + fstringindex,fstringlen: identoffsetty; + fstringdata: pointer; + procedure nextident(); + function storestring(const astr: lstringty): identnamety; + public + constructor create(); + destructor destroy(); override; + function getident(): identty; + function getident(const astart,astop: pchar): identty; + function getident(const aname: lstringty): identty; + function getident(const aname: pchar; const alen: integer): identty; + function getident(const aname: string): identty; + + function getidentname(const aident: identty; out name: identnamety): boolean; + //true if found + function getidentname(const aident: identty; out name: lstringty): boolean; + //true if found + function getidentname(const aname: string): identnamety; + function getidentname(const aident: identty): string; + function getidentnamel(const aident: identty): lstringty; + function getidentnamep(const aident: identty): pchar; +// function getidentnamel(const aeledata: pointer): lstringty; + function getidentname2(const aident: identty): identnamety; +// function getidentname2(const aeledata: pointer): identnamety; + + function nametolstring(const aname: identnamety): lstringty; inline; + + procedure clear(); +// procedure init(); + end; + +implementation +uses + mselfsr; + +const + mindatasize = 1024; + +type + identbufferheaderty = record + len: int32; + end; + identbufferty = record + header: identbufferheaderty; + data: record //null terminated array of char + end; + end; + pidentbufferty = ^identbufferty; + +procedure tstringidents.nextident; +begin + repeat + lfsr321(fstringident); + until fstringident >= firstident; +end; + +function tstringidents.getident(): identty; +begin + result:= fstringident; + nextident; +end; + +function tstringidents.getident(const aname: lstringty): identty; +begin + result:= fidentlist.getident(aname)^.data.data; +end; + +function tstringidents.getident(const aname: pchar; + const alen: integer): identty; +var + lstr1: lstringty; +begin + lstr1.po:= aname; + lstr1.len:= alen; + result:= fidentlist.getident(lstr1)^.data.data; +end; + +function tstringidents.getident(const astart,astop: pchar): identty; +var + lstr1: lstringty; +begin + lstr1.po:= astart; + lstr1.len:= astop-astart; + result:= fidentlist.getident(lstr1)^.data.data; +end; + +function tstringidents.getident(const aname: string): identty; +var + lstr1: lstringty; +begin + lstr1.po:= pointer(aname); + lstr1.len:= length(aname); + result:= fidentlist.getident(lstr1)^.data.data; +end; + +function tstringidents.nametolstring(const aname: identnamety): lstringty; +var + po1: pidentbufferty; +begin + po1:= pointer(fstringdata) + aname.offset; + result.len:= po1^.header.len; + result.po:= @po1^.data; +end; + +function tstringidents.getidentname(const aident: identty; + out name: lstringty): boolean; + //true if found +begin + result:= fidentlist.identname(aident,name); +end; + +function tstringidents.getidentname(const aname: string): identnamety; +begin + result:= fidentlist.getident(stringtolstring(aname))^.data.key; +end; + +function tstringidents.getidentname(const aident: identty; + out name: identnamety): boolean; + //true if found +begin + result:= fidentlist.identname(aident,name); +end; + +function tstringidents.getidentname(const aident: identty): string; +var + lstr1: lstringty; +begin + if getidentname(aident,lstr1) then begin + result:= lstringtostring(lstr1); + end + else begin + result:= '°'; + end; +end; + +function tstringidents.getidentnamel(const aident: identty): lstringty; +begin +{$ifdef mse_checkinternalerror} + if not +{$endif} + getidentname(aident,result) +{$ifdef mse_checkinternalerror} then begin + internalerror(ie_parser,'20151111A'); + end; +{$else} + ; +{$endif} +end; + +(* +function tstringidents.getidentnamel(const aeledata: pointer): lstringty; +begin +{$ifdef mse_checkinternalerror} + if not +{$endif} + getidentname(datatoele(aeledata)^.header.name,result) +{$ifdef mse_checkinternalerror} then begin + internalerror(ie_parser,'20151124A'); + end; +{$else} + ; +{$endif} +end; +*) +function tstringidents.getidentname2(const aident: identty): identnamety; +begin +{$ifdef mse_checkinternalerror} + if not +{$endif} + getidentname(aident,result) +{$ifdef mse_checkinternalerror} then begin + internalerror(ie_parser,'20151111B'); + end; +{$else} + ; +{$endif} +end; + +function tstringidents.getidentnamep(const aident: identty): pchar; +begin + result:= getidentnamel(aident).po; +end; + +(* +function tstringidents.getidentname2(const aeledata: pointer): identnamety; +begin +{$ifdef mse_checkinternalerror} + if not +{$endif} + getidentname(datatoele(aeledata)^.header.name,result) +{$ifdef mse_checkinternalerror} then begin + internalerror(ie_parser,'20151111C'); + end; +{$else} + ; +{$endif} +end; +*) +const + hashmask: array[0..7] of longword = + (%10101010101010100101010101010101, + %01010101010101011010101010101010, + %11001100110011000011001100110011, + %00110011001100111100110011001100, + %01100110011001111001100110011000, + %10011001100110000110011001100111, + %11100110011001100001100110011001, + %00011001100110011110011001100110 + ); + +function hashkey1(const akey: lstringty): hashvaluety; +var + int1: integer; + wo1: word; + by1: byte; + po1: pchar; +begin + result:= 0; + if akey.len > 0 then begin + wo1:= hashmask[0]; + po1:= akey.po; + for int1:= 0 to akey.len-1 do begin + {$ifdef caseinsensitive} + by1:= byte(lowerchars[po1[int1]]); + {$else} + by1:= byte(po1[int1]); + {$endif} + wo1:= ((wo1 + by1) xor by1); + end; + wo1:= (wo1 xor wo1 shl 7); + result:= (wo1 or (longword(wo1) shl 16)) xor hashmask[akey.len and $7]; + end; +end; + +function tstringidents.storestring(const astr: lstringty): identnamety; + //offset from stringdata +var + int1,int2: integer; + po1: pidentbufferty; +begin + int1:= fstringindex; + int2:= astr.len; + fstringindex:= (fstringindex + int2 + 1 + sizeof(identbufferheaderty) + 3) + and not 3; //align 4 + if fstringindex >= fstringlen then begin + fstringlen:= fstringindex*2+mindatasize; + reallocmem(fstringdata,fstringlen); + fillchar((pchar(pointer(fstringdata))+int1)^,fstringlen-int1,0); + //for terminating 0 + end; + po1:= fstringdata + int1; + po1^.header.len:= int2; + move(astr.po^,po1^.data,int2); + result.offset:= int1; + nextident(); +end; + +constructor tstringidents.create(); +begin + fidentlist:= tindexidenthashdatalist.create(self); + clear(); +end; + +destructor tstringidents.destroy(); +begin + clear(); + fidentlist.free(); +end; + +procedure tstringidents.clear(); +begin + fidentlist.clear; + if fstringdata <> nil then begin + freemem(fstringdata); + fstringdata:= nil; + end; + fstringindex:= 0; + fstringlen:= 0; + fstringident:= strid9; + nextident(); +end; +{ +procedure tstringidents.init(); +begin + fstringident:= idstart; //invalid + nextident(); +end; +} +{ tidenthashdatalist } +{ +constructor tidenthashdatalist.create(const asize: int32); +begin + inherited create(asize); +end; +} +function tidenthashdatalist.hashkey(const akey): hashvaluety; +begin + result:= identty(akey); +end; + +function tidenthashdatalist.checkkey(const akey; + const aitem: phashdataty): boolean; +begin + result:= identty(akey) = pidenthashdataty(aitem)^.data.header.ident; +end; + +function tidenthashdatalist.getrecordsize(): int32; +begin + result:= sizeof(identhashdataty); +end; + +function tidenthashdatalist.adduniquedata(const akey: identty; + out adata: pidenthashdataty): boolean; +begin + adata:= pidenthashdataty(internalfind(akey)); + result:= adata = nil; + if result then begin + adata:= pidenthashdataty(internaladd(akey)); + adata^.data.header.ident:= akey; +// end +// else begin +// inc(adata,sizeof(hashheaderty)); + end; +end; + +{ tindexidenthashdatalist } + +constructor tindexidenthashdatalist.create(const aowner: tstringidents); +begin + fowner:= aowner; + inherited create(); + fidents:= tidenthashdatalist.create(); +end; + +destructor tindexidenthashdatalist.destroy; +begin + inherited; + fidents.free; +end; + +function tindexidenthashdatalist.getrecordsize(): int32; +begin + result:= sizeof(indexidenthashdataty); +end; + +procedure tindexidenthashdatalist.clear; +begin + inherited; + fidents.clear; +end; + +function tindexidenthashdatalist.identname(const aident: identty; + out aname: lstringty): boolean; +var + po1: pidenthashdataty; + po2: pidentbufferty; +begin + po1:= pidenthashdataty(fidents.internalfind(aident,aident)); + if po1 <> nil then begin + result:= true; + po2:= pointer(fowner.fstringdata)+po1^.data.keyname; + aname.len:= po2^.header.len; + aname.po:= @po2^.data; + end + else begin + result:= false; + aname.po:= nil; + aname.len:= 0; + end; +end; + +function tindexidenthashdatalist.identname(const aident: identty; + out aname: identnamety): boolean; +var + po1: pidenthashdataty; +begin + po1:= pidenthashdataty(fidents.internalfind(aident,aident)); + if po1 <> nil then begin + result:= true; + aname.offset:= po1^.data.keyname; + end + else begin + result:= false; + aname.offset:= -1; + end; +end; + +function tindexidenthashdatalist.getident(const aname: lstringty): + pindexidenthashdataty; +var + po1: pindexidenthashdataty; + ha1: hashvaluety; +begin +{ + if aname.len > maxidentlen then begin + errormessage(err_identtoolong,[lstringtostring(aname)]); + result:= nil; + exit; + end; +} + ha1:= hashkey1(aname); + po1:= pointer(internalfind(aname,ha1)); + if po1 = nil then begin + po1:= pointer(internaladdhash(ha1)); + with po1^.data do begin + data:= fowner.fstringident; + key:= fowner.storestring(aname); + with pidenthashdataty(fidents.internaladdhash(data))^.data do begin + header.ident:= data; + keyname:= key.offset; + end; + end; + end; + result:= po1; +// result:= po1^.data.data; +end; + +function tindexidenthashdatalist.hashkey(const akey): hashvaluety; +var + po1,po2: pchar; + wo1: word; + by1: byte; +begin + with indexidentdataty(akey) do begin + po1:= fowner.fstringdata + key.offset + sizeof(identbufferheaderty); + po2:= po1; + wo1:= hashmask[0]; + while true do begin + {$ifdef caseinsensitive} + by1:= byte(lowerchars[po1^]); + {$else} + by1:= byte(po1^); + {$endif} + if by1 = 0 then begin + break; + end; + wo1:= ((wo1 + by1) xor by1); + end; + wo1:= (wo1 xor wo1 shl 7); + result:= (wo1 or (longword(wo1) shl 16)) xor hashmask[(po1-po2) and $7]; + end; +end; + +function tindexidenthashdatalist.checkkey(const akey; + const aitem: phashdataty): boolean; +var + po1,po2: pchar; + int1: integer; +begin + result:= false; + with lstringty(akey) do begin + po1:= po; + po2:= fowner.fstringdata + pindexidenthashdataty(aitem)^.data.key.offset + + sizeof(identbufferty); + for int1:= 0 to len-1 do begin + {$ifdef caseinsensitive} + if lowerchars[po1[int1]] <> lowerchars[po2[int1]] then begin + {$else} + if po1[int1] <> po2[int1] then begin + {$endif} + exit; + end; + end; + result:= po2[len] = #0; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/container/msesumlist.pas b/mseide-msegui/lib/common/container/msesumlist.pas new file mode 100644 index 0000000..19290f7 --- /dev/null +++ b/mseide-msegui/lib/common/container/msesumlist.pas @@ -0,0 +1,606 @@ +unit msesumlist; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msedatalist,msetypes,msearrayprops,mseclasses,mseglob; + +//todo: optimize!!! + +const +// foldlevelsumname = '#foldlevel'; + sumleveltag = 1; + sumissumtag = 2; + +type + + realsumty = record + data: realintty; + sumup: realty; + sumdown: realty; + issum: boolean; + end; + prealsumty = ^realsumty; + + tsumprop = class(tindexpersistent) + protected + fsum: realty; + fsumindex: integer; + published + end; + psumprop = ^tsumprop; + + optionsumty = (osu_sumsonly,osu_valuesonly, + osu_foldsum{,osu_foldsumdown,osu_folddefaultsum}); + optionssumty = set of optionsumty; + + + tsumarrayprop = class(tindexpersistentarrayprop) + private + protected + function newsum(const alevel: integer; const asum: realty; + const aindex: integer): realty; + public + constructor create(const aowner: tdatalist); reintroduce; + end; + + tsumuparrayprop = class(tsumarrayprop) + end; + + tsumdownarrayprop = class(tsumarrayprop) + end; + + trealsumlist = class(trealintdatalist) + private + fsumsup: tsumuparrayprop; + fsumsdown: tsumdownarrayprop; + fdefaultval: realsumty; + function getsumlevel(index: integer): integer; + procedure setsumlevel(index: integer; const avalue: integer); + function getisfoldsum(index: integer): boolean; + procedure setisfoldsum(index: integer; const avalue: boolean); + procedure setsumsup(const avalue: tsumuparrayprop); + procedure setsumsdown(const avalue: tsumdownarrayprop); + protected + fdirtyup: integer; + fdirtydown: integer; + flinkvalue: listlinkinfoty; + flinklevel: listlinkinfoty; + flinkissum: listlinkinfoty; + foptions: optionssumty; + procedure setoptions(const avalue: optionssumty); virtual; + procedure setsourcevalue(const avalue: string); virtual; + procedure setsourcelevel(const avalue: string); virtual; + procedure setsourceissum(const avalue: string); virtual; + procedure getgriddefaultdata(var dest); override; + procedure getgriddata(index: integer; var dest); override; + procedure setgriddata(index: integer; const source); override; + function getdefault: pointer; override; + function getlinkdatatypes(const atag: integer): listdatatypesty; override; + public + constructor create; override; + destructor destroy; override; + procedure listdestroyed(const sender: tdatalist); override; + procedure clean(const start,stop: integer); override; + procedure change(const index: integer); override; + class function datatype: listdatatypety; override; + procedure sourcechange(const sender: tdatalist; + const index: integer); override; + function getsourcecount: integer; override; + function getsourceinfo(const atag: integer): plistlinkinfoty; override; + procedure linksource(const source: tdatalist; const atag: integer); override; + + procedure clearmemberitem(const subitem: integer; + const index: integer); override; + procedure setmemberitem(const subitem: integer; + const index: integer; const avalue: integer); override; + property sumlevel[index: integer]: integer read getsumlevel + write setsumlevel; + //0 -> no sum > 0 top down, < 0 bottom up, not used for osu_foldsum + property isfoldsum[index: integer]: boolean read getisfoldsum + write setisfoldsum; + //for osu_foldsum only + property sourcevalue: string read flinkvalue.name + write setsourcevalue; + property sourcelevel: string read flinklevel.name + write setsourcelevel; + property sourceissum: string read flinkissum.name + write setsourceissum; + //for osu_foldsum only + published + property sumsup: tsumuparrayprop read fsumsup write setsumsup; + property sumsdown: tsumdownarrayprop read fsumsdown write setsumsdown; + property options: optionssumty read foptions write setoptions + default []; +end; + +implementation +uses + msereal,msebits; + +{ trealsumlist } + +constructor trealsumlist.create; +begin + initsource(flinkvalue); + initsource(flinklevel); + initsource(flinkissum); + inherited; + fsize:= sizeof(realsumty); +{$warnings off} + fsumsup:= tsumuparrayprop.create(self); +{$warnings on} +{$warnings off} + fsumsdown:= tsumdownarrayprop.create(self); +{$warnings on} + fillchar(fdefaultval,sizeof(fdefaultval),0); + fdefaultval.data.rea:= emptyreal; +end; + +destructor trealsumlist.destroy; +begin + removesource(flinkvalue); + removesource(flinklevel); + removesource(flinkissum); + fsumsup.free; + fsumsdown.free; + inherited; +end; + +procedure trealsumlist.listdestroyed(const sender: tdatalist); +begin + inherited; + checklistdestroyed(flinkvalue,sender); + checklistdestroyed(flinklevel,sender); + checklistdestroyed(flinkissum,sender); +end; + +class function trealsumlist.datatype: listdatatypety; +begin + result:= dl_realsum; +end; + +procedure trealsumlist.getgriddefaultdata(var dest); +begin + realty(dest):= emptyreal; +end; + +procedure trealsumlist.getgriddata(index: integer; var dest); +//var +// po1: prealsumty; +begin + clean(index,index); + checkindex(index); + realty(dest):= prealsumty(fdatapo+index*fsize)^.data.rea; +end; + +procedure trealsumlist.setgriddata(index: integer; const source); +var + int1: integer; +begin + int1:= index; + checkindex(index); + with prealsumty(fdatapo+index*fsize)^ do begin + if data.int = 0 then begin + data.rea:= realty(source); + change(int1); + end; + end; +end; + +function trealsumlist.getsumlevel(index: integer): integer; +begin + checkindex(index); + result:= prealsumty(fdatapo+index*fsize)^.data.int; +end; + +procedure trealsumlist.setsumlevel(index: integer; + const avalue: integer); +var + int1: integer; +begin + int1:= index; + checkindex(index); + with prealsumty(fdatapo+index*fsize)^ do begin + if data.int <> avalue then begin + data.int:= avalue; + if not (osu_foldsum in foptions) then begin + if avalue = 0 then begin + if defaultzero then begin + data.rea:= 0; + end + else begin + data.rea:= emptyreal; + end; + end; + sourcechange(flinkvalue.source,int1); //restore value + change(-1); + end; + end; + end; +end; + +function trealsumlist.getisfoldsum(index: integer): boolean; +begin + checkindex(index); + result:= prealsumty(fdatapo+index*fsize)^.issum; +end; + +procedure trealsumlist.setisfoldsum(index: integer; + const avalue: boolean); +var + int1: integer; +begin + int1:= index; + checkindex(index); + with prealsumty(fdatapo+index*fsize)^ do begin + if issum <> avalue then begin + issum:= avalue; + if (osu_foldsum in foptions) then begin + if not avalue then begin + if defaultzero then begin + data.rea:= 0; + end + else begin + data.rea:= emptyreal; + end; + end; + end; + sourcechange(flinklevel.source,int1); //restore sumlevel + sourcechange(flinkvalue.source,int1); //restore value + change(-1); + end; + end; +end; + +procedure copyvalue(const source,dest: pointer); +begin + prealsumty(dest)^.data.rea:= preal(source)^; +end; + +procedure copylevel(const source,dest: pointer); +begin + prealsumty(dest)^.data.int:= pinteger(source)^; +end; + +procedure copylevelrowstate(const source,dest: pointer); +begin + with prowstatety(source)^ do begin + prealsumty(dest)^.issum:= flags and foldissummask <> 0; + if prealsumty(dest)^.issum then begin + prealsumty(dest)^.data.int:= -(fold + 1); + end + else begin + prealsumty(dest)^.data.int:= 0 + end; + end; +end; + +procedure copylevelrowstateissum(const source1,source2,dest: pointer); +begin + with prealsumty(dest)^ do begin + if pinteger(source2)^ <> 0 then begin + data.int:= -(prowstatety(source1)^.fold + 1); + issum:= true; + end + else begin + data.int:= 0; + issum:= false; + end; + end; +end; + +procedure trealsumlist.clean(const start,stop: integer); +var + po1: prealsumty; +// po2: prowstatety; +// po3: pinteger; + int1,int2: integer; + rea1: realty; +begin + checksourcecopy(flinkvalue,@copyvalue); + if flinklevel.source is tcustomrowstatelist then begin + if flinkissum.source <> nil then begin + checksourcecopy2(flinklevel,flinkissum.source,@copylevelrowstateissum); + end + else begin + checksourcecopy(flinklevel,@copylevelrowstate); + end; + end + else begin + checksourcecopy(flinklevel,@copylevel); + end; + if fsumsup.count > 0 then begin + if stop >= fdirtyup then begin + if fdirtyup > 0 then begin + po1:= datapo; + inc(po1,fdirtyup-1); + rea1:= po1^.sumup; + end + else begin + with fsumsup do begin + for int1:= 0 to high(fitems) do begin + with tsumprop(fitems[int1]) do begin + fsum:= emptyreal; + fsumindex:= -1; + end; + end; + end; + rea1:= emptyreal; + end; + po1:= datapo; + inc(po1,fdirtyup); + for int1:= fdirtyup to stop do begin + int2:= po1^.data.int; + if int2 = 0 then begin + rea1:= addrealty(rea1,po1^.data.rea); + end + else begin + if int2 > 0 then begin + if int2 <= high(fsumsup.fitems) then begin + po1^.data.rea:= fsumsup.newsum(int2-1,rea1,int1); + end + else begin + po1^.data.rea:= rea1; + end; + end; + end; + po1^.sumup:= rea1; + inc(po1); + end; + fdirtyup:= stop+1; + end; + end; + if fsumsdown.count > 0 then begin + if start <= fdirtydown then begin + if fdirtydown < count - 1 then begin + po1:= datapo; + inc(po1,fdirtydown+1); + rea1:= po1^.sumdown; + end + else begin + with fsumsdown do begin + for int1:= 0 to high(fitems) do begin + with tsumprop(fitems[int1]) do begin + fsum:= emptyreal; + fsumindex:= maxint; + end; + end; + end; + rea1:= emptyreal; + end; + po1:= datapo; + inc(po1,fdirtydown); + for int1:= fdirtydown downto start do begin + int2:= -po1^.data.int; + if int2 = 0 then begin + rea1:= addrealty(rea1,po1^.data.rea); + end + else begin + if int2 > 0 then begin + if int2 <= high(fsumsdown.fitems) then begin + po1^.data.rea:= fsumsdown.newsum(int2-1,rea1,int1); + end + else begin + po1^.data.rea:= rea1; + end; + end; + end; + po1^.sumdown:= rea1; + dec(po1); + end; + fdirtydown:= start-1; + end; + end; +end; + +procedure trealsumlist.change(const index: integer); +begin + if index < 0 then begin + fdirtyup:= 0; + fdirtydown:= count-1; + end + else begin + with fsumsup do begin + if (fitems <> nil) and + (tsumprop(fitems[high(fitems)]).fsumindex <= index) then begin + fdirtyup:= 0; + end; + end; + with fsumsdown do begin + if (fitems <> nil) and + (tsumprop(fitems[high(fitems)]).fsumindex >= index) then begin + fdirtydown:= self.count-1; + end; + end; + end; + inherited change(-1); //sum invalid +end; + +procedure trealsumlist.setsumsup(const avalue: tsumuparrayprop); +begin + fsumsup.assign(avalue); +end; + +procedure trealsumlist.setsumsdown(const avalue: tsumdownarrayprop); +begin + fsumsdown.assign(avalue); +end; + +function trealsumlist.getdefault: pointer; +begin + if defaultzero then begin + result:= nil; + end + else begin + result:= @fdefaultval; + end; +end; + +procedure trealsumlist.sourcechange(const sender: tdatalist; + const index: integer); +begin + inherited; + if sender <> nil then begin + if sender = flinkvalue.source then begin + checksourcechange(flinkvalue,flinkvalue.source,index); //restore value + change(index); + end + else begin + if (sender = flinkissum.source) then begin + checksourcechange(flinklevel,flinklevel.source,index); //invalid + checksourcechange(flinkvalue,flinkvalue.source,index); //restore value + change(-1); + end + else begin + if checksourcechange(flinklevel,sender,index) then begin + checksourcechange(flinkvalue,flinkvalue.source,index); //restore value + change(-1); + end; + end; + end; + end; +end; + +function trealsumlist.getlinkdatatypes(const atag: integer): listdatatypesty; +begin + result:= inherited getlinkdatatypes(atag); + case atag of + 0: begin + result:= result + [dl_real]; + end; + sumleveltag: begin + if osu_foldsum in foptions then begin + result:= [dl_rowstate]; + end + else begin + result:= [dl_integer]; + end; + end; + sumissumtag: begin + result:= [dl_integer]; + end; + end; +end; + +procedure trealsumlist.setoptions(const avalue: optionssumty); +const + mask1: optionssumty = [osu_sumsonly,osu_valuesonly]; +begin + if foptions <> avalue then begin + foptions:= optionssumty( + setsinglebit({$ifdef FPC}longword{$else}byte{$endif}(avalue), + {$ifdef FPC}longword{$else}byte{$endif}(foptions), + {$ifdef FPC}longword{$else}byte{$endif}(mask1))); + change(-1); + end; +end; + +procedure trealsumlist.setsourcevalue(const avalue: string); +begin + flinkvalue.name:= avalue; +end; + +procedure trealsumlist.setsourcelevel(const avalue: string); +begin + flinklevel.name:= avalue; +end; + +procedure trealsumlist.setsourceissum(const avalue: string); +begin + flinkissum.name:= avalue; +end; + +procedure trealsumlist.linksource(const source: tdatalist; const atag: integer); +begin + case atag of + 0: begin + internallinksource(source,atag,flinkvalue.source); + end; + sumleveltag: begin + internallinksource(source,atag,flinklevel.source); + end; + sumissumtag: begin + if internallinksource(source,atag,flinkissum.source) and + (flinklevel.source <> nil)then begin + sourcechange(flinklevel.source,-1); //sum level invalid + end; + end; + end; +end; + +function trealsumlist.getsourcecount: integer; +begin + result:= 3; +end; + +function trealsumlist.getsourceinfo(const atag: integer): plistlinkinfoty; +begin + case atag of + 0: begin + result:= @flinkvalue; + end; + sumleveltag: begin + result:= @flinklevel; + end; + sumissumtag: begin + result:= @flinkissum; + end + else begin + result:= nil; + end; + end; +end; + +procedure trealsumlist.clearmemberitem(const subitem: integer; + const index: integer); +begin + if subitem = 1 then begin + if osu_foldsum in foptions then begin + isfoldsum[index]:= false; + end + else begin + sumlevel[index]:= 0; + end; + end; +end; + +procedure trealsumlist.setmemberitem(const subitem: integer; + const index: integer; const avalue: integer); +begin + if subitem = 1 then begin + if osu_foldsum in foptions then begin + isfoldsum[index]:= avalue <> 0; + end + else begin + sumlevel[index]:= avalue; + end; + end; +end; + +{ tsumprop } + +{ tsumarrayprop } + +constructor tsumarrayprop.create(const aowner: tdatalist); +begin + inherited create(aowner,tsumprop); +end; + +function tsumarrayprop.newsum(const alevel: integer; + const asum: realty; const aindex: integer): realty; +var + po1: psumprop; + int1: integer; +begin + po1:= psumprop(@fitems[alevel]); + result:= subrealty(asum,po1^.fsum); + for int1:= alevel to high(fitems) do begin + po1^.fsum:= asum; + po1^.findex:= aindex; + inc(po1); + end; +end; + +initialization + registerdatalistclass(dl_realsum,trealsumlist); +end. diff --git a/mseide-msegui/lib/common/crypto/msecrc.pas b/mseide-msegui/lib/common/crypto/msecrc.pas new file mode 100644 index 0000000..f770a29 --- /dev/null +++ b/mseide-msegui/lib/common/crypto/msecrc.pas @@ -0,0 +1,111 @@ +{ MSEgui Copyright (c) 2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msecrc; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface + +function crc32(const data: pbyte; const length: integer): longword; overload; +procedure crc32(const data: pbyte; const length: integer; var crc: longword); + + +implementation + +const + crc32table: array[byte] of longword = ( + $00000000,$77073096,$EE0E612C,$990951BA, + $076DC419,$706AF48F,$E963A535,$9E6495A3, + $0EDB8832,$79DCB8A4,$E0D5E91E,$97D2D988, + $09B64C2B,$7EB17CBD,$E7B82D07,$90BF1D91, + $1DB71064,$6AB020F2,$F3B97148,$84BE41DE, + $1ADAD47D,$6DDDE4EB,$F4D4B551,$83D385C7, + $136C9856,$646BA8C0,$FD62F97A,$8A65C9EC, + $14015C4F,$63066CD9,$FA0F3D63,$8D080DF5, + $3B6E20C8,$4C69105E,$D56041E4,$A2677172, + $3C03E4D1,$4B04D447,$D20D85FD,$A50AB56B, + $35B5A8FA,$42B2986C,$DBBBC9D6,$ACBCF940, + $32D86CE3,$45DF5C75,$DCD60DCF,$ABD13D59, + $26D930AC,$51DE003A,$C8D75180,$BFD06116, + $21B4F4B5,$56B3C423,$CFBA9599,$B8BDA50F, + $2802B89E,$5F058808,$C60CD9B2,$B10BE924, + $2F6F7C87,$58684C11,$C1611DAB,$B6662D3D, + $76DC4190,$01DB7106,$98D220BC,$EFD5102A, + $71B18589,$06B6B51F,$9FBFE4A5,$E8B8D433, + $7807C9A2,$0F00F934,$9609A88E,$E10E9818, + $7F6A0DBB,$086D3D2D,$91646C97,$E6635C01, + $6B6B51F4,$1C6C6162,$856530D8,$F262004E, + $6C0695ED,$1B01A57B,$8208F4C1,$F50FC457, + $65B0D9C6,$12B7E950,$8BBEB8EA,$FCB9887C, + $62DD1DDF,$15DA2D49,$8CD37CF3,$FBD44C65, + $4DB26158,$3AB551CE,$A3BC0074,$D4BB30E2, + $4ADFA541,$3DD895D7,$A4D1C46D,$D3D6F4FB, + $4369E96A,$346ED9FC,$AD678846,$DA60B8D0, + $44042D73,$33031DE5,$AA0A4C5F,$DD0D7CC9, + $5005713C,$270241AA,$BE0B1010,$C90C2086, + $5768B525,$206F85B3,$B966D409,$CE61E49F, + $5EDEF90E,$29D9C998,$B0D09822,$C7D7A8B4, + $59B33D17,$2EB40D81,$B7BD5C3B,$C0BA6CAD, + $EDB88320,$9ABFB3B6,$03B6E20C,$74B1D29A, + $EAD54739,$9DD277AF,$04DB2615,$73DC1683, + $E3630B12,$94643B84,$0D6D6A3E,$7A6A5AA8, + $E40ECF0B,$9309FF9D,$0A00AE27,$7D079EB1, + $F00F9344,$8708A3D2,$1E01F268,$6906C2FE, + $F762575D,$806567CB,$196C3671,$6E6B06E7, + $FED41B76,$89D32BE0,$10DA7A5A,$67DD4ACC, + $F9B9DF6F,$8EBEEFF9,$17B7BE43,$60B08ED5, + $D6D6A3E8,$A1D1937E,$38D8C2C4,$4FDFF252, + $D1BB67F1,$A6BC5767,$3FB506DD,$48B2364B, + $D80D2BDA,$AF0A1B4C,$36034AF6,$41047A60, + $DF60EFC3,$A867DF55,$316E8EEF,$4669BE79, + $CB61B38C,$BC66831A,$256FD2A0,$5268E236, + $CC0C7795,$BB0B4703,$220216B9,$5505262F, + $C5BA3BBE,$B2BD0B28,$2BB45A92,$5CB36A04, + $C2D7FFA7,$B5D0CF31,$2CD99E8B,$5BDEAE1D, + $9B64C2B0,$EC63F226,$756AA39C,$026D930A, + $9C0906A9,$EB0E363F,$72076785,$05005713, + $95BF4A82,$E2B87A14,$7BB12BAE,$0CB61B38, + $92D28E9B,$E5D5BE0D,$7CDCEFB7,$0BDBDF21, + $86D3D2D4,$F1D4E242,$68DDB3F8,$1FDA836E, + $81BE16CD,$F6B9265B,$6FB077E1,$18B74777, + $88085AE6,$FF0F6A70,$66063BCA,$11010B5C, + $8F659EFF,$F862AE69,$616BFFD3,$166CCF45, + $A00AE278,$D70DD2EE,$4E048354,$3903B3C2, + $A7672661,$D06016F7,$4969474D,$3E6E77DB, + $AED16A4A,$D9D65ADC,$40DF0B66,$37D83BF0, + $A9BCAE53,$DEBB9EC5,$47B2CF7F,$30B5FFE9, + $BDBDF21C,$CABAC28A,$53B39330,$24B4A3A6, + $BAD03605,$CDD70693,$54DE5729,$23D967BF, + $B3667A2E,$C4614AB8,$5D681B02,$2A6F2B94, + $B40BBE37,$C30C8EA1,$5A05DF1B,$2D02EF8D + ); + +procedure crc32(const data: pbyte; const length: integer; var crc: longword); +var + po1,po2: pbyte; + lwo1: longword; +begin + if length > 0 then begin + lwo1:= not crc; //startvector + po1:= data; + po2:= data+length; + while po1 < po2 do begin + lwo1:= (lwo1 shr 8) xor crc32table[byte(lwo1) xor po1^]; + inc(po1) + end; + crc:= not lwo1; + end; +end; + +function crc32(const data: pbyte; const length: integer): longword; +begin + result:= 0; + crc32(data,length,result); +end; + +end. diff --git a/mseide-msegui/lib/common/crypto/msecryptio.pas b/mseide-msegui/lib/common/crypto/msecryptio.pas new file mode 100644 index 0000000..3e51fce --- /dev/null +++ b/mseide-msegui/lib/common/crypto/msecryptio.pas @@ -0,0 +1,147 @@ +{ MSEgui Copyright (c) 2007 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msecryptio; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseclasses,sysutils; + +type + + ecryptoio = class(exception) + end; + + tcryptoio = class; + cryptoioclassty = class of tcryptoio; + cryptoiokindty = (cyk_none,cyk_server,cyk_client); + + cryptodataty = array[0..17] of pointer; + cryptoioinfoty = record +// handler: tcryptio; + kind: cryptoiokindty; + classtype: cryptoioclassty; + rxfd: integer; + txfd: integer; + cryptodata: cryptodataty; + end; + pcryptoioinfoty = ^cryptoioinfoty; + + connectionkindty = (cok_server,cok_client); + + tcryptoio = class(tmsecomponent) + protected + class procedure internalunlink(var ainfo: cryptoioinfoty); virtual; + class procedure internalthreadterminate; virtual; + class procedure connect(var ainfo: cryptoioinfoty; + const atimeoutms: integer); virtual; abstract; + class procedure accept(var ainfo: cryptoioinfoty; + const atimeoutms: integer); virtual; abstract; + class function write(var ainfo: cryptoioinfoty; const buffer: pointer; + const count: integer; + const atimeoutms: integer): integer; virtual; abstract; + class function read(var ainfo: cryptoioinfoty; const buffer: pointer; + const count: integer; + const atimeoutms: integer): integer; virtual; abstract; + //atimeoutms < 0 -> nonblocked + public + procedure link(const atxfd,arxfd: integer; + out ainfo: cryptoioinfoty); virtual; + { + class procedure unlink(var ainfo: cryptioinfoty); + class procedure threadterminate(var ainfo: cryptioinfoty); + } + end; + +procedure cryptoconnect(var ainfo: cryptoioinfoty; const atimeoutms: integer); +procedure cryptoaccept(var ainfo: cryptoioinfoty; const atimeoutms: integer); +function cryptowrite(var ainfo: cryptoioinfoty; const buffer: pointer; + const count: integer; const atimeoutms: integer): integer; +function cryptoread(var ainfo: cryptoioinfoty; const buffer: pointer; + const count: integer; const atimeoutms: integer): integer; + //atimeoutms < 0 -> nonblocked +procedure cryptounlink(var ainfo: cryptoioinfoty); +procedure cryptothreadterminate(var ainfo: cryptoioinfoty); + +implementation +uses + msesystypes; + +procedure cryptoconnect(var ainfo: cryptoioinfoty; const atimeoutms: integer); +begin + if ainfo.classtype <> nil then begin + ainfo.classtype.connect(ainfo,atimeoutms); + end; +end; + +procedure cryptoaccept(var ainfo: cryptoioinfoty; const atimeoutms: integer); +begin + if ainfo.classtype <> nil then begin + ainfo.classtype.accept(ainfo,atimeoutms); + end; +end; + +function cryptowrite(var ainfo: cryptoioinfoty; const buffer: pointer; + const count: integer; const atimeoutms: integer): integer; +begin + result:= 0; + if ainfo.classtype <> nil then begin + result:= ainfo.classtype.write(ainfo,buffer,count,atimeoutms); + end; +end; + +function cryptoread(var ainfo: cryptoioinfoty; const buffer: pointer; + const count: integer; const atimeoutms: integer): integer; +begin + result:= 0; + if ainfo.classtype <> nil then begin + result:= ainfo.classtype.read(ainfo,buffer,count,atimeoutms); + end; +end; + +procedure cryptounlink(var ainfo: cryptoioinfoty); +begin + if ainfo.classtype <> nil then begin + ainfo.classtype.internalunlink(ainfo); + end; +end; + +procedure cryptothreadterminate(var ainfo: cryptoioinfoty); +begin + if ainfo.classtype <> nil then begin + ainfo.classtype.internalthreadterminate; + end; +end; + +{ tcryptoio } + +class procedure tcryptoio.internalunlink(var ainfo: cryptoioinfoty); +begin + with ainfo do begin +// handler:= nil; + classtype:= nil; + txfd:= invalidfilehandle; + rxfd:= invalidfilehandle; + end; +end; + +class procedure tcryptoio.internalthreadterminate; +begin + //dummy +end; + +procedure tcryptoio.link(const atxfd,arxfd: integer; + out ainfo: cryptoioinfoty); +begin +// ainfo.handler:= self; + ainfo.classtype:= cryptoioclassty(classtype); + ainfo.rxfd:= arxfd; + ainfo.txfd:= atxfd; +end; +end. diff --git a/mseide-msegui/lib/common/crypto/msecryptohandler.pas b/mseide-msegui/lib/common/crypto/msecryptohandler.pas new file mode 100644 index 0000000..313a73e --- /dev/null +++ b/mseide-msegui/lib/common/crypto/msecryptohandler.pas @@ -0,0 +1,930 @@ +{ MSEgui Copyright (c) 2012-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msecryptohandler; +{$ifdef FPC}{$mode objfpc}{$h+}{$goto on}{$endif} +interface +uses + msestream,classes,mclasses,sysutils,msetypes{msestrings},mseformatstr,mseglob; + +type + cryptoerrorty = (cerr_error,cerr_ciphernotfound,cerr_notseekable, + cerr_cipherinit,cerr_invalidopenmode,cerr_digestnotfound, + cerr_cannotwrite,cerr_invalidblocksize, + cerr_invalidkeylength,cerr_invaliddatalength, + cerr_readheader,cerr_writeheader,cerr_nobio, + cerr_nopubkey,cerr_encrypt,cerr_norsakey, + cerr_noprivkey,cerr_decrypt,cerr_nokey, + cerr_cannotrestart,cerr_notactive,cerr_wrongdatadirection); + + ecryptohandler = class(exception) + end; + + tbasecryptohandler = class(tcustomcryptohandler) + protected + procedure error(const err: cryptoerrorty); + procedure checkerror(const err: cryptoerrorty = cerr_error); virtual; + function checknullerror(const avalue: integer; + const err: cryptoerrorty = cerr_error): integer; + {$ifdef FPC} inline;{$endif} + function checknilerror(const avalue: pointer; + const err: cryptoerrorty = cerr_error): pointer; + {$ifdef FPC} inline;{$endif} + end; + + tdummycryptohandler = class(tbasecryptohandler) + end; + + sslhandlerstatety = (sslhs_hasfirstblock,sslhs_eofflag,sslhs_finalized, + sslhs_fileeof); + sslhandlerstatesty = set of sslhandlerstatety; + + padbufty = array[0..0] of byte; //variable + + paddedhandlerdatadty = record + mode: integer; + headersize: integer; + blocksize: integer; //-1 -> variable + bufsize: integer; + padindex: integer; + padcount: integer; + seekoffset: integer; + padbuf: ^padbufty; + blockbuf: pbyte; + state: sslhandlerstatesty; + end; + ppaddedhandlerdatadty = ^paddedhandlerdatadty; + {$if sizeof(paddedhandlerdatadty) > sizeof(cryptohandlerdataty)} + {$error 'buffer overflow'} + {$ifend} + paddedhandlerdataty = record + case integer of + 0: (d: paddedhandlerdatadty;); + 1: (_bufferspace: cryptohandlerdataty;); + end; + + tpaddedcryptohandler = class(tbasecryptohandler) + private + protected + procedure cipherupdate(var aclient: cryptoclientinfoty; + const source: pbyte; const sourcelen: integer; + const dest: pbyte; out destlen: integer); virtual; abstract; + procedure cipherfinal(var aclient: cryptoclientinfoty; + const dest: pbyte; out destlen: integer); virtual; abstract; + function calcwritebuffersize(var aclient: cryptoclientinfoty; + const acount: integer): integer; virtual; + function readdata(var aclient: cryptoclientinfoty; var buffer; + const acount: integer): integer; virtual; + //for variable block size + + function read(var aclient: cryptoclientinfoty; + var buffer; count: longint): longint; override; + function write(var aclient: cryptoclientinfoty; + const buffer; count: longint): longint; override; + function seek(var aclient: cryptoclientinfoty; + const offset: int64; origin: tseekorigin): int64; override; + function internalread(var aclient: cryptoclientinfoty; + var buffer; count: longint): longint; + function internalwrite(var aclient: cryptoclientinfoty; + const buffer; count: longint): longint; + function internalseek(var aclient: cryptoclientinfoty; + const offset: int64; origin: tseekorigin): int64; + function getsize(var aclient: cryptoclientinfoty): int64; override; + procedure restartcipher(var aclient: cryptoclientinfoty); virtual; + procedure open(var aclient: cryptoclientinfoty); override; + procedure close(var aclient: cryptoclientinfoty); override; + procedure initializedata(var aclient: cryptoclientinfoty); virtual; + procedure finalizedata(var aclient: cryptoclientinfoty); virtual; + function padbufsize: integer; virtual; + end; + + base64handlerdatadty = record + p: paddedhandlerdatadty; + linestep: integer; + buf: array[0..2] of byte; + bufindex: integer; + lineindex: integer; + readbuffer: pbyte; + readindex: integer; + readbuffersize: integer; + readbufferlength: integer; + end; + pbase64handlerdatadty = ^base64handlerdatadty; + {$if sizeof(base64handlerdatadty) > sizeof(cryptohandlerdataty)} + {$error 'buffer overflow'} + {$ifend} + base64handlerdataty = record + case integer of + 0: (d: base64handlerdatadty;); + 1: (_bufferspace: cryptohandlerdataty;); + end; + + tbase64handler = class(tpaddedcryptohandler) + private + fmaxlinelength: integer; + protected + procedure initpointers(var aclient: cryptoclientinfoty); + function padbufsize: integer; override; + procedure cipherupdate(var aclient: cryptoclientinfoty; + const source: pbyte; const sourcelen: integer; + const dest: pbyte; out destlen: integer); override; + procedure cipherfinal(var aclient: cryptoclientinfoty; + const dest: pbyte; out destlen: integer); override; + function readdata(var aclient: cryptoclientinfoty; var buffer; + const acount: integer): integer; override; + function calcwritebuffersize(var aclient: cryptoclientinfoty; + const acount: integer): integer; override; + procedure initializedata(var aclient: cryptoclientinfoty); override; + procedure finalizedata(var aclient: cryptoclientinfoty); override; + procedure restartcipher(var aclient: cryptoclientinfoty); override; + public + constructor create(aowner: tcomponent); override; + published + property maxlinelength: integer read fmaxlinelength write fmaxlinelength + default defaultbase64linelength; + end; + +const + cryptoerrormessages: array[cryptoerrorty] of msestring =( + 'OpenSSL error.', + 'Cipher not found.', + 'Stream not seekable.', + 'Can not cipher init.', + 'Invalid open mode.', + 'Digest not found.', + 'Can not write.', + 'Invalid block size.', + 'Invalid key length.', + 'Invalid data length.', + 'Can not read header.', + 'Can not write header.', + 'Can not create BIO.', + 'No public key.', + 'Can not encrypt.', + 'No RSA key.', + 'No private key.', + 'Can not decrypt.', + 'No key.', + 'Can not restart.', + 'Not active.', + 'Wrong data direction.' + ); + +implementation +uses + msebits,msesystypes,msesys; + +{ tbasecryptohandler } + +procedure tbasecryptohandler.checkerror(const err: cryptoerrorty); +begin + //dummy +end; + +function tbasecryptohandler.checknullerror(const avalue: integer; + const err: cryptoerrorty): integer; +begin + result:= avalue; + if avalue = 0 then begin + error(err); + end; +end; + +function tbasecryptohandler.checknilerror(const avalue: pointer; + const err: cryptoerrorty): pointer; +begin + result:= avalue; + if avalue = nil then begin + error(err); + end; +end; + +procedure tbasecryptohandler.error(const err: cryptoerrorty); +begin + checkerror(err); + raise ecryptohandler.create(ansistring(cryptoerrormessages[err])); + //there was no queued error +end; + +{ tpaddedcryptohandler } + +function tpaddedcryptohandler.read(var aclient: cryptoclientinfoty; + var buffer; count: longint): longint; +var + ps,pd: pbyte; +// blocksize: integer; + + procedure checkpadding; + var + int1,int2: integer; + begin + with paddedhandlerdataty(aclient.handlerdata).d do begin + int2:= padcount - padindex; + if int2 > 0 then begin + int1:= count; + if int1 > int2 then begin + int1:= int2; + end; + move(padbuf^[padindex],pd^,int1); + padindex:= padindex + int1; + result:= result + int1; + count:= count - int1; + seekoffset:= seekoffset + int1; + inc(pd,int1); + end; + end; + end; //checkpadding + +var + int1,int2,int3,int4: integer; + pb,po1: pbyte; + +begin + if count > 0 then begin + with paddedhandlerdataty(aclient.handlerdata).d do begin + pd:= @buffer; + result:= 0; + if blocksize <> 1 then begin + checkpadding; + end; + if count > 0 then begin + int1:= count; + if blocksize > 1 then begin + if sslhs_eofflag in state then begin + exit; + end; + int1:= ((count+blocksize-1) div blocksize) * blocksize; //whole blocks + if not (sslhs_hasfirstblock in state) then begin + int1:= int1+blocksize; + include(state,sslhs_hasfirstblock); + end; + getmem(po1,int1); + ps:= po1; + try + int2:= inherited read(aclient,(ps)^,int1); + updatebit1({$ifdef FPC}longword{$else}byte{$endif}(state), + ord(sslhs_eofflag),int2 < int1); + seekoffset:= seekoffset + ((count div blocksize) * blocksize - int2); + //set to zero later if eofflag + pb:= pointer(padbuf); + padindex:= 0; + padcount:= 0; + int4:= (int2 div blocksize - 1) * blocksize; + if int4 > count then begin + int4:= (count div blocksize) * blocksize; + end; + if int4 > 0 then begin + cipherupdate(aclient,ps,int4,pd,int3); +// checknullerror(evp_cipherupdate(ctx,pointer(pd),int3,pointer(ps),int4)); + inc(result,int3); + inc(pd,int3); + dec(count,int3); + inc(ps,int4); + end + else begin + int4:= 0; + end; + int4:= int2-int4; + if int4 > 0 then begin + cipherupdate(aclient,ps,int4,pb,padcount); +// checknullerror(evp_cipherupdate(ctx,pointer(pb),padcount, +// pointer(ps),int4)); + inc(pb,padcount); + end; + if sslhs_eofflag in state then begin + cipherfinal(aclient,pb,int3); +// checknullerror(evp_cipherfinal(ctx,pointer(pb),int3)); + include(state,sslhs_finalized); + padcount:= padcount + int3; + end; + checkpadding; + if sslhs_eofflag in state then begin + seekoffset:= 0; + end; + finally + freemem(po1); + end; + end + else begin + if blocksize < 0 then begin //variable + result:= result + readdata(aclient,pd^,int1); + end + else begin + getmem(ps,int1); + try + int2:= inherited read(aclient,ps^,int1); + if int2 > 0 then begin + cipherupdate(aclient,ps,int2,@buffer,result); + // checknullerror(evp_cipherupdate(ctx,@buffer,result,pointer(ps),int2)); + end; + finally + freemem(ps); + end; + end; + end; + end; + end; + end + else begin + result:= inherited read(aclient,buffer,count); + end; +end; + +function tpaddedcryptohandler.calcwritebuffersize( + var aclient: cryptoclientinfoty; const acount: integer): integer; +begin + with paddedhandlerdataty(aclient.handlerdata).d do begin + result:= acount + blocksize; + end; +end; + +function tpaddedcryptohandler.write(var aclient: cryptoclientinfoty; + const buffer; count: longint): longint; +var + po1: pointer; + int1: integer; +begin + if count > 0 then begin + with paddedhandlerdataty(aclient.handlerdata).d do begin + getmem(po1,calcwritebuffersize(aclient,count)); + try + cipherupdate(aclient,@buffer,count,po1,int1); + if int1 > 0 then begin + result:= inherited write(aclient,po1^,int1); + if result = int1 then begin + result:= count; + seekoffset:= seekoffset + count - int1; + end + else begin + error(cerr_cannotwrite); + end; + end + else begin + result:= count; + seekoffset:= seekoffset + count; + end; + finally + freemem(po1); + end; + end; + end + else begin + result:= inherited write(aclient,buffer,count); + end; +end; + +function tpaddedcryptohandler.seek(var aclient: cryptoclientinfoty; + const offset: int64; origin: tseekorigin): int64; +begin + if (offset <> 0) or (origin = soend) then begin + result:= 0; //compiler warning + error(cerr_notseekable); + end + else begin + result:= internalseek(aclient,offset,origin); + with paddedhandlerdataty(aclient.handlerdata).d do begin + case origin of + socurrent: begin + result:= result + seekoffset; + end; + sobeginning: begin + restartcipher(aclient); + end; + soend: begin + error(cerr_notseekable); + end; + end; + end; + end; +end; + +function tpaddedcryptohandler.getsize(var aclient: cryptoclientinfoty): int64; +var + lint1: int64; +begin + with aclient do begin + if stream.handle <> invalidfilehandle then begin + lint1:= fileseek(stream.handle,int64(0),ord(socurrent)); + result:= fileseek(stream.handle,int64(0),ord(soend)); + fileseek(stream.handle,lint1,ord(sobeginning)); + end + else begin + result:= inherited getsize(aclient); + end; + end; +end; + +function tpaddedcryptohandler.internalseek(var aclient: cryptoclientinfoty; + const offset: int64; origin: tseekorigin): int64; +begin + result:= inherited seek(aclient,offset,origin); +end; + +function tpaddedcryptohandler.internalread(var aclient: cryptoclientinfoty; + var buffer; count: longint): longint; +begin + result:= inherited read(aclient,buffer,count); +end; + +function tpaddedcryptohandler.internalwrite(var aclient: cryptoclientinfoty; + const buffer; count: longint): longint; +begin + result:= inherited write(aclient,buffer,count); +end; + +procedure tpaddedcryptohandler.restartcipher( + var aclient: cryptoclientinfoty); +var + int1: integer; +begin + with paddedhandlerdataty(aclient.handlerdata).d do begin + if not (sslhs_finalized in state) and + (aclient.stream.openmode in [fm_write,fm_create])then begin + cipherfinal(aclient,blockbuf,int1); +// checknullerror(evp_cipherfinal(ctx,@buffer,int1)); + if int1 > 0 then begin + if inherited write(aclient,blockbuf^,int1) <> int1 then begin + error(cerr_cannotwrite); + end; + end; + end; +// checknullerror(evp_cipherinit_ex(ctx,nil,nil,pointer(keybuf), +// pointer(ivbuf),mode),cerr_cipherinit); +// ctx^.iv:= ctx^.iov; + padindex:= 0; + padcount:= 0; + seekoffset:= 0; + state:= []; + if headersize > 0 then begin + internalseek(aclient,int64(headersize),sobeginning); + end; + end; +end; + +procedure tpaddedcryptohandler.open(var aclient: cryptoclientinfoty); +//var +// int1: integer; +begin + inherited; + with paddedhandlerdataty(aclient.handlerdata).d do begin + case aclient.stream.openmode of + fm_read: begin + mode:= 0; //decrypt + end; + fm_create,fm_write: begin + mode:= 1; //encrypt + end; + else begin + error(cerr_invalidopenmode); //todo: allow append + end; + end; + state:= []; + padcount:= 0; + padindex:= 0; + initializedata(aclient); + end; +end; + +procedure tpaddedcryptohandler.close(var aclient: cryptoclientinfoty); +var + int1: integer; +begin + try + with paddedhandlerdataty(aclient.handlerdata).d do begin + if (aclient.stream.openmode in [fm_write,fm_create]) {and + (cipher <> nil)} then begin + if not (sslhs_finalized in state) then begin + cipherfinal(aclient,blockbuf,int1); + include(state,sslhs_finalized); + if int1 > 0 then begin + if inherited write(aclient,blockbuf^,int1) <> int1 then begin + error(cerr_cannotwrite); + end; + end; + end; + end; + end; + finally + finalizedata(aclient); + inherited; + end; +end; + +procedure tpaddedcryptohandler.initializedata(var aclient: cryptoclientinfoty); +begin + with paddedhandlerdataty(aclient.handlerdata).d do begin + bufsize:= padbufsize; + getmem(padbuf,bufsize); + getmem(blockbuf,bufsize); + end; +end; + +procedure tpaddedcryptohandler.finalizedata(var aclient: cryptoclientinfoty); +begin + with paddedhandlerdataty(aclient.handlerdata).d do begin + if padbuf <> nil then begin + fillchar(padbuf^,bufsize,0); + freemem(padbuf); + end; + if blockbuf <> nil then begin + fillchar(blockbuf^,bufsize,0); + freemem(blockbuf); + end; + end; +end; + +function tpaddedcryptohandler.padbufsize: integer; +begin + result:= 1; //dummy +end; + +function tpaddedcryptohandler.readdata(var aclient: cryptoclientinfoty; + var buffer; const acount: integer): integer; +begin + result:= inherited read(aclient,buffer,acount); +end; + +{ tbase64handler } + +constructor tbase64handler.create(aowner: tcomponent); +begin + fmaxlinelength:= defaultbase64linelength; + inherited; +end; + +function tbase64handler.padbufsize: integer; +begin + result:= 6; //4+return linefeed +end; + +type + putinfoty = record + pb: pbyte; + pc: pchar; + pline: pchar; + linest: integer; + end; + +procedure putgroup(var info: putinfoty); +var + by1: byte; +begin + with info do begin + if pc >= pline then begin + pc^:= c_return; + inc(pc); + pc^:= c_linefeed; + inc(pc); + pline:= pc+linest; + end; + by1:= pb^; //s0 + pc^:= base64encoding[by1 shr 2]; //d0 + inc(pb); //s1 + inc(pc); //d1 + pc^:= base64encoding[((by1 shl 4) or (pb^ shr 4)) and base64mask]; + by1:= pb^ shl 2; + inc(pb); //s2 + inc(pc); //d2 + pc^:= base64encoding[(by1 or (pb^ shr 6)) and base64mask]; + inc(pc); //d3 + pc^:= base64encoding[pb^ and base64mask]; + inc(pb); + inc(pc); //d0 + end; +end; + +procedure tbase64handler.cipherupdate(var aclient: cryptoclientinfoty; + const source: pbyte; const sourcelen: integer; const dest: pbyte; + out destlen: integer); +var + po1: pbyte; + pbend: pbyte; + info: putinfoty; + int1: integer; + scount: integer; + +begin + with base64handlerdataty(aclient.handlerdata).d,info do begin + destlen:= 0; + if p.mode <> 0 then begin + linest:= linestep; + pb:= source; + scount:= sourcelen; + while bufindex < 3 do begin + buf[bufindex]:= pb^; + inc(pb); + inc(bufindex); + dec(scount); + if scount = 0 then begin + break; + end; + end; + if bufindex < 3 then begin + exit; + end; + bufindex:= 0; + pc:= pointer(dest); + if linestep > 0 then begin + pline:= pc + linestep - lineindex; + end + else begin + pline:= pointer(ptrint(-1)); + end; + po1:= pb; + pb:= @buf; + putgroup(info); + pb:= po1; + + bufindex:= scount mod 3; //tail + pbend:= pbyte(pchar(source) + sourcelen - bufindex); + while pchar(pb) < pchar(pbend) do begin + putgroup(info); + end; + destlen:= pc - pointer(dest); + for int1:= 0 to bufindex - 1 do begin //store tail + buf[int1]:= pb^; + inc(pb); + end; + if linestep > 0 then begin + lineindex:= pc - pline + linestep; + end; + end; + end; +end; + +procedure tbase64handler.cipherfinal(var aclient: cryptoclientinfoty; + const dest: pbyte; out destlen: integer); +var + pb: pbyte; + pc: pchar; + by1: byte; +begin + with base64handlerdataty(aclient.handlerdata).d do begin + destlen:= 0; + if p.mode <> 0 then begin + if bufindex > 0 then begin + pc:= pointer(dest); + if (linestep > 0) and (lineindex >= linestep) then begin + pc^:= c_return; + inc(pc); + pc^:= c_linefeed; + inc(pc); + end; + pb:= @buf; + by1:= pb^; //s0 + pc^:= base64encoding[by1 shr 2]; //d0 + inc(pc); //d1 + pc^:= base64encoding[(by1 shl 4) and base64mask]; + if bufindex > 1 then begin + inc(pb); //s1 + pc^:= base64encoding[((by1 shl 4) or (pb^ shr 4)) and base64mask]; + inc(pc); //d2 + pc^:= base64encoding[(pb^ shl 2) and base64mask]; + end + else begin + inc(pc); //d2 + pc^:= '='; + end; + inc(pc); //d3 + pc^:= '='; + destlen:= pc-pointer(dest)+1; + end; + end; + end; +end; + +function tbase64handler.calcwritebuffersize(var aclient: cryptoclientinfoty; + const acount: integer): integer; +begin + with base64handlerdataty(aclient.handlerdata).d do begin + result:= ((acount+2) div 3)*4; + if linestep > 0 then begin + result:= result + 2*(result div linestep + 1); //return-linefeed, max + end; + end; +end; + +procedure tbase64handler.initpointers(var aclient: cryptoclientinfoty); +begin + with base64handlerdataty(aclient.handlerdata).d do begin + bufindex:= 0; + lineindex:= 0; + if readbuffer <> nil then begin + freemem(readbuffer); + readbuffer:= nil; + end; + readindex:= 0; + readbufferlength:= 0; + readbuffersize:= 0; + end; +end; + +procedure tbase64handler.initializedata(var aclient: cryptoclientinfoty); +begin + inherited; + initpointers(aclient); + with base64handlerdataty(aclient.handlerdata).d do begin + p.blocksize:= -1; //variable + linestep:= 0; + if fmaxlinelength > 0 then begin + linestep:= fmaxlinelength and $fffffffc; //do not cut 4 char boundary + if fmaxlinelength > 0 then begin + if linestep = 0 then begin + linestep:= 4; + end; + end; + end; + end; +end; + +procedure tbase64handler.restartcipher(var aclient: cryptoclientinfoty); +begin + inherited; + initpointers(aclient); +end; + +{$optimization off} //internal compiler error 200409241 + +function tbase64handler.readdata(var aclient: cryptoclientinfoty; var buffer; + const acount: integer): integer; +var + ps: pbyte; + psend: pbyte; + pd: pbyte; + pdend: pbyte; + psgroup,pdgroup: pbyte; + + function decode: boolean; //true by data end + var + by1: byte; + begin + result:= true; + while (pchar(ps) < pchar(psend)) and (pchar(pd) < pchar(pdend)) do begin + psgroup:= ps; + pdgroup:= pd; + by1:= base64decoding[ord(ps^)]; //s0 + while shortint(by1) < 0 do begin + inc(ps); + if (pchar(ps) >= pchar(psend)) or (char(by1) = '=') then begin + exit; + end; + by1:= base64decoding[ord(ps^)]; + end; + pd^:= by1 shl 2; //d0 + inc(ps); + by1:= base64decoding[ord(ps^)]; //s1 + while shortint(by1) < 0 do begin + inc(ps); + if (pchar(ps) >= pchar(psend)) or (char(by1) = '=') then begin + exit; + end; + by1:= base64decoding[ord(ps^)]; + end; + pd^:= pd^ or (by1 shr 4); + inc(pd); //d1 + pd^:= by1 shl 4; + inc(ps); + by1:= base64decoding[ord(ps^)]; //s2 + while shortint(by1) < 0 do begin + inc(ps); + if (pchar(ps) >= pchar(psend)) or (char(by1) = '=') then begin + exit; + end; + by1:= base64decoding[ord(ps^)]; + end; + pd^:= pd^ or by1 shr 2; + inc(pd); //d2 + pd^:= by1 shl 6; + inc(ps); + by1:= base64decoding[ord(ps^)]; //s3 + while shortint(by1) < 0 do begin + inc(ps); + if (pchar(ps) >= pchar(psend)) or (char(by1) = '=') then begin + exit; + end; + by1:= base64decoding[ord(ps^)]; + end; + pd^:= pd^ or by1; + inc(pd); + inc(ps); //s0 + end; + if pd = pdend then begin + result:= false; + end; + end; + + procedure fillbuffer(const aoffset: integer); + begin + with base64handlerdataty(aclient.handlerdata).d do begin + readbufferlength:= aoffset + + inherited readdata(aclient,(pchar(readbuffer)+aoffset)^, + readbuffersize-aoffset); + if readbufferlength < readbuffersize then begin + include(p.state,sslhs_fileeof); + end; + psend:= pbyte(pchar(readbuffer) + readbufferlength); + end; + end; + + procedure getdata; + var + int1: integer; + newbufsize: integer; + po1: pointer; + begin + with base64handlerdataty(aclient.handlerdata).d do begin + newbufsize:= 2*acount+256; + if readbuffer = nil then begin + readbuffersize:= newbufsize; + getmem(readbuffer,readbuffersize); + readindex:= 0; + fillbuffer(0); + end; + ps:= pbyte(pchar(readbuffer) + readindex); + psend:= pbyte(pchar(readbuffer) + readbufferlength); + while true do begin + if decode then begin + if (pchar(ps) >= pchar(psend)) and (pchar(pd) < pchar(pdend)) then begin + //text end, try to get more + if (sslhs_fileeof in p.state) or ((pchar(ps)-1)^ = '=') then begin + include(p.state,sslhs_eofflag); + break; + end; + int1:= pchar(ps)-pchar(psgroup); + if newbufsize > readbuffersize then begin //need a bigger buffer + po1:= readbuffer; + getmem(readbuffer,readbuffersize); + move(psgroup^,readbuffer^,int1); + freemem(po1); + end + else begin + move(psgroup^,readbuffer^,int1); + end; + readindex:= 0; + fillbuffer(int1); + pd:= pdgroup; + ps:= readbuffer; + continue; + end; + end + else begin + break; + end; + end; + readindex:= pchar(ps) - pchar(readbuffer); + end; + end; + +var + int1: integer; +// by1: byte; + tail: integer; + po1: pbyte; + +begin + with base64handlerdataty(aclient.handlerdata).d do begin + result:= 0; + pd:= @buffer; + tail:= acount mod 3; + if (acount > tail) then begin + pdend:= pbyte(pchar(pd) + acount - tail); + getdata; + result:= pchar(pd) - @buffer; + end; + if not (sslhs_eofflag in p.state) then begin + po1:= pd; + pd:= pointer(p.padbuf); + pdend:= pbyte(pchar(pd) + 3); + getdata; + p.padcount:= pchar(pd) - pchar(pointer(p.padbuf)); + if tail > 0 then begin + int1:= tail; + if int1 > p.padcount then begin + int1:= p.padcount; + end; + move(p.padbuf^,po1^,int1); + result:= result + int1; + p.padindex:= int1; + end; + end; + if pchar(ps) >= pchar(psend) then begin + freemem(readbuffer); + readbuffer:= nil; + readbufferlength:= 0; + end; + end; +end; + +procedure tbase64handler.finalizedata(var aclient: cryptoclientinfoty); +begin + initpointers(aclient); + inherited; +end; + +end. diff --git a/mseide-msegui/lib/common/crypto/msecryptstream.pas b/mseide-msegui/lib/common/crypto/msecryptstream.pas new file mode 100644 index 0000000..e865b1d --- /dev/null +++ b/mseide-msegui/lib/common/crypto/msecryptstream.pas @@ -0,0 +1,21 @@ +{ MSEgui Copyright (c) 2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msecryptstream; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msecryptio; + +type + tblockcipher = class(tcryptio) + end; + +implementation +end. diff --git a/mseide-msegui/lib/common/crypto/mseopenssl.pas b/mseide-msegui/lib/common/crypto/mseopenssl.pas new file mode 100644 index 0000000..4792b5b --- /dev/null +++ b/mseide-msegui/lib/common/crypto/mseopenssl.pas @@ -0,0 +1,529 @@ +{ MSEgui Copyright (c) 2007-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseopenssl; +{$ifdef FPC} +{$MODE OBJFPC}{$H+} +{$endif} +interface + +uses + msedynload,msetypes{msestrings},msectypes; +const +{$ifdef mswindows} + openssllib: array[0..1] of filenamety = ('libssl32.dll','ssleay32.dll'); + opensslutillib: array[0..0] of filenamety = ('libeay32.dll'); +{$else} + openssllib: array[0..4] of filenamety = ( + 'libssl.so.1.0.0','libssl.so.0.9.8','libssl.so.0.9.7','libssl.so.0.9.6', + 'libssl.so'); + opensslutillib: array[0..4] of filenamety = ( + 'libcrypto.so.1.0.0','libcrypto.so.0.9.8','libcrypto.so.0.9.7', + 'libcrypto.so.0.9.6','libcrypto.so'); +{$endif} + +const + SHA_DIGEST_LENGTH = 20; + BN_CTX_NUM = 16; + BN_CTX_NUM_POS = 12; + + SSL_CTRL_OPTIONS = 32; // ssl/ssl.h + CRYPTO_LOCK = 1; // ssl/crypto.h + CRYPTO_UNLOCK = 2; + CRYPTO_READ = 4; + CRYPTO_WRITE = 8; + + EVP_MAX_MD_SIZE = 16 + 20; + + SSL_ERROR_NONE = 0; + SSL_ERROR_SSL = 1; + SSL_ERROR_WANT_READ = 2; + SSL_ERROR_WANT_WRITE = 3; + SSL_ERROR_WANT_X509_LOOKUP = 4; + SSL_ERROR_SYSCALL = 5; //look at error stack/return value/errno + SSL_ERROR_ZERO_RETURN = 6; + SSL_ERROR_WANT_CONNECT = 7; + SSL_ERROR_WANT_ACCEPT = 8; + + SSL_OP_NO_SSLv2 = $01000000; + SSL_OP_NO_SSLv3 = $02000000; + SSL_OP_NO_TLSv1 = $04000000; + SSL_OP_ALL = $000FFFFF; + SSL_VERIFY_NONE = $00; + SSL_VERIFY_PEER = $01; + + OPENSSL_DES_DECRYPT = 0; + OPENSSL_DES_ENCRYPT = 1; + + SSL_FILETYPE_ASN1 = 2; + SSL_FILETYPE_PEM = 1; + EVP_PKEY_RSA = 6; + +type + sslsize_t = culong; + SslPtr = Pointer; + pSslPtr = ^SslPtr; + pSSL_CTX = SslPtr; + pSSL = SslPtr; + pSSL_METHOD = SslPtr; + pBIO_METHOD = SslPtr; + pBIO = SslPtr; + pX509 = SslPtr; + ppX509 = ^pX509; + pX509_NAME = SslPtr; + pEVP_MD = SslPtr; +// PInteger = ^Integer; +// EVP_PKEY = SslPtr; + pEVP_CIPHER = SslPtr; + pEVP_PKEY = SslPtr; + ppEVP_PKEY = ^pEVP_PKEY; + pX509_REQ = SslPtr; + ppX509_REQ = ^pX509_REQ; + pX509_CRL = SslPtr; + ppX509_CRL = pX509_CRL; + pPKCS7 = SslPtr; + pASN1_cint = SslPtr; + pSTACK_OFX509 = SslPtr; + pX509_SIG = SslPtr; + pBIGNUM = SslPtr; + pBN_MONT_CTX = SslPtr; + pBN_BLINDING = SslPtr; + pRSA = SslPtr; + ppRSA = ^pRSA; + pDSA = SslPtr; + ppDSA = ^pDSA; + pASN1_UTCTIME = SslPtr; + pASN1_INTEGER = SslPtr; + pASN1_ENUMERATED = SslPtr; + pASN1_OCTET_STRING = SslPtr; + pPasswdCb = SslPtr; + pDH = SslPtr; + pBUF_MEM = SslPtr; + pEC_KEY = SslPtr; + pSTACK = SslPtr; + pPKCS7_SIGNER_INFO = SslPtr; + pAES_KEY = SslPtr; + pENGINE = SslPtr; + pRAND_METHOD = SslPtr; + + pFunction = procedure; cdecl; + pCharacter = PChar; + + CRYPTO_EX_DATA = record + sk: pointer; + dummy: cint; + end; + + TProgressCallbackFunction = procedure(status: cint; progress: cint; + data: pointer); + + // Password ask callback for I/O function prototipe + // It must fill buffer with password and return password length + TPWCallbackFunction = function(buffer: pcuchar; length: cint; + verify: cint; data: pointer): cint; cdecl; + + +var + SSL_new: function(ctx: PSSL_CTX):PSSL; cdecl; + SSL_free: procedure(ssl: PSSL); cdecl; + SSL_ctrl: function(ssl: PSSL; cmd: cint; larg: cint; + parg: pointer): cint; cdecl; + SSL_get_error: function(s: PSSL; ret_code: cint):cint; cdecl; + SSL_library_init: function():cint; cdecl; + SSL_load_error_strings: procedure; cdecl; + SSL_set_cipher_list: function(arg0: PSSL_CTX; str: PChar):cint; cdecl; + + SSL_CTX_set_cipher_list: function(arg0: PSSL_CTX; str: PChar):cint; cdecl; +// SSL_CTX_set_cipher_list: function(arg0: PSSL_CTX; +// var str: String):cint; cdecl; + SSL_CTX_new: function(meth: PSSL_METHOD):PSSL_CTX; cdecl; + SSL_CTX_free: procedure(arg0: PSSL_CTX); cdecl; + SSL_CTX_use_PrivateKey: function(ctx: PSSL_CTX; pkey: SslPtr):cint; cdecl; + SSL_CTX_use_PrivateKey_ASN1: function(pk: cint; ctx: PSSL_CTX; d: pbyte; + len: cint):cint; cdecl; + SSL_CTX_use_PrivateKey_file: function(ctx: PSSL_CTX; _file: PChar; + _type: cint):cint; cdecl; +// SSL_CTX_use_PrivateKey_file: function(ctx: PSSL_CTX; +// const _file: String; _type: cint):cint; cdecl; + SSL_CTX_use_RSAPrivateKey_file: function(ctx: PSSL_CTX; _file: pchar; + _type: cint):cint; cdecl; + SSL_CTX_use_certificate: function(ctx: PSSL_CTX; x: SslPtr):cint; cdecl; + SSL_CTX_use_certificate_ASN1: function(ctx: PSSL_CTX; len: cint; + d: pbyte):cint; cdecl; + SSL_CTX_use_certificate_file: function(ctx: PSSL_CTX; + _file: pchar; _type: cint):cint; cdecl; + SSL_CTX_use_certificate_chain_file: function(ctx: PSSL_CTX; + _file: PChar):cint; cdecl; +// SSL_CTX_use_certificate_chain_file: function(ctx: PSSL_CTX; +// const _file: String):cint; cdecl; + SSL_CTX_check_private_key: function(ctx: PSSL_CTX):cint; cdecl; + SSL_CTX_set_default_passwd_cb: procedure(ctx: PSSL_CTX; cb: PPasswdCb); cdecl; + SSL_CTX_set_default_passwd_cb_userdata: procedure( + ctx: PSSL_CTX; u: SslPtr); cdecl; +// function SSL_CTX_LoadVerifyLocations(ctx: PSSL_CTX; +// const CAfile: PChar; const CApath: PChar):cint; cdecl; + SSL_CTX_load_verify_locations: function(ctx: PSSL_CTX; CAfile: pchar; + CApath: pchar):cint; cdecl; + SSL_CTX_set_verify: procedure(ctx: PSSL_CTX; mode: cint; + arg2: PFunction); cdecl; + +// SSLv2_method: function():PSSL_METHOD; cdecl; + SSLv3_method: function():PSSL_METHOD; cdecl; + TLSv1_method: function():PSSL_METHOD; cdecl; + SSLv23_method: function():PSSL_METHOD; cdecl; + SSL_use_certificate_file: function(ssl: PSSL; + _file: pchar; _type: cint):cint; cdecl; + SSL_use_PrivateKey_file: function(ssl: PSSL; _file: PChar; + _type: cint):cint; cdecl; + + SSL_set_fd: function(s: PSSL; fd: cint):cint; cdecl; + SSL_set_rfd: function(s: PSSL; fd: cint):cint; cdecl; + SSL_set_wfd: function(s: PSSL; fd: cint):cint; cdecl; + SSL_accept: function(ssl: PSSL):cint; cdecl; + SSL_connect: function(ssl: PSSL):cint; cdecl; + SSL_shutdown: function(ssl: PSSL):cint; cdecl; + SSL_read: function(ssl: PSSL; buf: SslPtr; num: cint):cint; cdecl; + SSL_peek: function(ssl: PSSL; buf: SslPtr; num: cint):cint; cdecl; + SSL_write: function(ssl: PSSL; buf: SslPtr; num: cint):cint; cdecl; + SSL_pending: function(ssl: PSSL):cint; cdecl; + SSL_get_version: function(ssl: PSSL): pchar; cdecl; + SSL_get_peer_certificate: function(ssl: PSSL): PX509; cdecl; + SSL_get_current_cipher: function(s: PSSL):SslPtr; cdecl; + SSL_CIPHER_get_name: function(c: SslPtr): pchar; cdecl; + SSL_CIPHER_get_bits: function(c: SslPtr; var alg_bits: cint):cint; cdecl; + SSL_get_verify_result: function(ssl: PSSL):cint; cdecl; + +{$ifndef mswindows} + SSLeay: function: cardinal; cdecl; + OpenSSL_add_all_ciphers: procedure; cdecl; + OpenSSL_add_all_digests: procedure; cdecl; + ERR_load_crypto_strings: procedure; cdecl; + ERR_peek_error: function: cardinal; cdecl; + ERR_peek_last_error: function: cardinal; cdecl; + CRYPTO_malloc: function (length: clong; const f: PCharacter; + line: cint): pointer; cdecl; + CRYPTO_realloc: function(str: PCharacter; length: clong; + const f: PCharacter; line: cint): pointer; cdecl; + CRYPTO_remalloc: function(a: pointer; length: clong; + const f: PCharacter; line: cint): pointer; cdecl; + CRYPTO_free: procedure(str: pointer); cdecl; +{$endif} + // Low level debugable memory management function +//util + SSLeay_version: function(t: cint): pchar; cdecl; + ERR_error_string_n: procedure(e: cint; buf: PChar; len: cint); cdecl; + ERR_get_error: function(): cint; cdecl; + ERR_clear_error: procedure; cdecl; + ERR_free_strings: procedure; cdecl; + ERR_remove_state: procedure(pid: cint); cdecl; + OPENSSL_add_all_algorithms_noconf: procedure; cdecl; + CRYPTO_cleanup_all_ex_data: procedure; cdecl; +// RAND_screen: procedure; cdecl; + i2d_X509_bio: function(b: PBIO; x: PX509): cint; cdecl; + i2d_PrivateKey_Bio: function(b: PBIO; pkey: pEVP_PKEY): cint; cdecl; + + CRYPTO_num_locks: function: cint; cdecl; + CRYPTO_set_locking_callback: procedure(cb: Sslptr); cdecl; + CRYPTO_set_id_callback: procedure(func: pointer); cdecl; + + +// OBJ functions + OBJ_obj2nid: function(asn1_object: pointer): cint; cdecl; + OBJ_txt2nid: function(s: PCharacter): cint; cdecl; + OBJ_txt2obj: function(s: PCharacter; no_name: cint): cint; cdecl; + // safestack functions + sk_new_null: function: pointer; cdecl; + sk_free: procedure(st: pointer); cdecl; + sk_push: function(st: pointer; val: pointer): cint; cdecl; + sk_num: function(st: pointer): cint; cdecl; + sk_value: function(st: pointer; i: cint): pointer; cdecl; + // Internal to DER and DER to internal conversion functions + + +// Helper: convert standard Delphi integer in big-endian integer +function int2bin(n: cint): cint; +// High level memory management function +{$ifndef mswindows} +function OPENSSL_malloc(length: clong): pointer; +function OPENSSL_realloc(address: PCharacter; length: clong): pointer; +function OPENSSL_remalloc(var address: pointer; length: clong): pointer; +procedure OPENSSL_free(address: pointer); // cdecl; ? +{$endif} +function SSL_set_options(ssl: PSSL; options: cint): cint; +//function IsSSLloaded: Boolean; + +procedure initsslinterface; //calls initializeopenssl once +procedure initializeopenssl(const sonames: array of filenamety; + const sonamesutil: array of filenamety); + //[] = default +procedure releaseopenssl; +procedure regopensslinit(const initproc: dynlibprocty); +procedure regopenssldeinit(const deinitproc: dynlibprocty); + +implementation +uses + msesystypes,{$ifdef FPC}dynlibs,{$endif}msesysintf1,msesysintf + {$ifndef FPC},classes_del{$endif}; +var + libinfo,libinfoutil: dynlibinfoty; + +var +// ssllibhandle: integer; +// sslutillibhandle: integer; +// sslloaded: boolean = false; + RAND_screen: procedure; cdecl; + +function SSL_set_options(ssl: PSSL; options: cint): cint; +begin + result:= ssl_ctrl(ssl,ssl_ctrl_options,options,nil); +end; + +function int2bin(n: cint): cint; +begin + result := ((cardinal(n) shr 24) and $000000FF) or + ((cardinal(n) shr 8) and $0000FF00) or + ((cardinal(n) shl 8) and $00FF0000) or + ((cardinal(n) shl 24) and $FF000000); +end; +{$ifndef mswindows} +function OPENSSL_malloc(length: clong): pointer; +begin + OPENSSL_malloc := CRYPTO_malloc(length, nil, 0); +end; + +function OPENSSL_realloc(address: PCharacter; length: clong): pointer; +begin + OPENSSL_realloc := CRYPTO_realloc(address, length, nil, 0); +end; + +function OPENSSL_remalloc(var address: pointer; length: clong): pointer; +begin + OPENSSL_remalloc := CRYPTO_remalloc(address, length, nil, 0); +end; + +procedure OPENSSL_free(address: pointer); +begin + CRYPTO_free(address); +end; +{$endif} +{ +procedure dounload; +begin + if ssllibhandle <> 0 then begin + freelibrary(ssllibhandle); + ssllibhandle:= 0; + end; + if sslutillibhandle <> 0 then begin + freelibrary(sslutillibhandle); + sslutillibhandle:= 0; + end; +end; +} +type + mutexarty = array of mutexty; +var + locks: mutexarty; + +procedure lockingcallback(mode: cint; n: cint; afile: pchar; + line: cint); cdecl; +begin + if mode and crypto_lock <> 0 then begin + sys_mutexlock(locks[n]); + end + else begin + sys_mutexunlock(locks[n]); + end; +end; + +function idcallback: cint; cdecl; +begin + result:= sys_getcurrentthread; +end; + +procedure initssllib(const data: pointer); +var + int1: cint; +begin + //init library + Ssl_Library_Init; + Ssl_Load_Error_Strings; + OPENSSL_add_all_algorithms_noconf; + pointer({$ifndef FPC}@{$endif}rand_screen):= getprocedureaddress( + libinfoutil.libhandle,'RAND_screen'); + if assigned(rand_screen) then begin + Rand_Screen; //windows, todo: better random + end; + setlength(locks,crypto_num_locks()); + for int1:= 0 to high(locks) do begin + sys_mutexcreate(locks[int1]); + end; + crypto_set_locking_callback(@lockingcallback); + crypto_set_id_callback(@idcallback); +end; + +procedure initializeopenssl(const sonames: array of filenamety; + const sonamesutil: array of filenamety); + //[] = default +const + funcs: array[0..{$ifndef mswindows}53{$else}43{$endif}] of funcinfoty = ( + (n: 'SSL_get_error'; d: {$ifndef FPC}@{$endif}@SSL_get_error), + (n: 'SSL_library_init'; d: {$ifndef FPC}@{$endif}@SSL_library_init), + (n: 'SSL_load_error_strings'; d: {$ifndef FPC}@{$endif}@SSL_load_error_strings), + (n: 'SSL_CTX_set_cipher_list'; d: {$ifndef FPC}@{$endif}@SSL_CTX_set_cipher_list), + (n: 'SSL_CTX_new'; d: {$ifndef FPC}@{$endif}@SSL_CTX_new), + (n: 'SSL_CTX_free'; d: {$ifndef FPC}@{$endif}@SSL_CTX_free), + (n: 'SSL_set_fd'; d: {$ifndef FPC}@{$endif}@SSL_set_fd), + (n: 'SSL_set_rfd'; d: {$ifndef FPC}@{$endif}@SSL_set_rfd), + (n: 'SSL_set_wfd'; d: {$ifndef FPC}@{$endif}@SSL_set_wfd), + (n: 'SSL_set_cipher_list'; d: {$ifndef FPC}@{$endif}@SSL_set_cipher_list), +// (n: 'SSLv2_method'; d: {$ifndef FPC}@{$endif}@SSLv2_method), + (n: 'SSLv3_method'; d: {$ifndef FPC}@{$endif}@SSLv3_method), + (n: 'TLSv1_method'; d: {$ifndef FPC}@{$endif}@TLSv1_method), + (n: 'SSLv23_method'; d: {$ifndef FPC}@{$endif}@SSLv23_method), + (n: 'SSL_CTX_use_PrivateKey'; d: {$ifndef FPC}@{$endif}@SSL_CTX_use_PrivateKey), + (n: 'SSL_CTX_use_PrivateKey_ASN1'; d: {$ifndef FPC}@{$endif}@SSL_CTX_use_PrivateKey_ASN1), + (n: 'SSL_CTX_use_PrivateKey_file'; d: {$ifndef FPC}@{$endif}@SSL_CTX_use_PrivateKey_file), + (n: 'SSL_CTX_use_RSAPrivateKey_file'; d: {$ifndef FPC}@{$endif}@SSL_CTX_use_RSAPrivateKey_file), + (n: 'SSL_CTX_use_certificate'; d: {$ifndef FPC}@{$endif}@SSL_CTX_use_certificate), + (n: 'SSL_CTX_use_certificate_ASN1'; d: {$ifndef FPC}@{$endif}@SSL_CTX_use_certificate_ASN1), + (n: 'SSL_CTX_use_certificate_file'; d: {$ifndef FPC}@{$endif}@SSL_CTX_use_certificate_file), + (n: 'SSL_CTX_use_certificate_chain_file'; d: {$ifndef FPC}@{$endif}@SSL_CTX_use_certificate_chain_file), + (n: 'SSL_CTX_check_private_key'; d: {$ifndef FPC}@{$endif}@SSL_CTX_check_private_key), + (n: 'SSL_CTX_set_default_passwd_cb'; d: {$ifndef FPC}@{$endif}@SSL_CTX_set_default_passwd_cb), + (n: 'SSL_CTX_set_default_passwd_cb_userdata'; d: {$ifndef FPC}@{$endif}@SSL_CTX_set_default_passwd_cb_userdata), + (n: 'SSL_CTX_load_verify_locations'; d: {$ifndef FPC}@{$endif}@SSL_CTX_load_verify_locations), + (n: 'SSL_new'; d: {$ifndef FPC}@{$endif}@SSL_new), + (n: 'SSL_free'; d: {$ifndef FPC}@{$endif}@SSL_free), + (n: 'SSL_ctrl'; d: {$ifndef FPC}@{$endif}@SSL_ctrl), + (n: 'SSL_use_certificate_file'; d: {$ifndef FPC}@{$endif}@SSL_use_certificate_file), + (n: 'SSL_use_PrivateKey_file'; d: {$ifndef FPC}@{$endif}@SSL_use_PrivateKey_file), + (n: 'SSL_accept'; d: {$ifndef FPC}@{$endif}@SSL_accept), + (n: 'SSL_connect'; d: {$ifndef FPC}@{$endif}@SSL_connect), + (n: 'SSL_shutdown'; d: {$ifndef FPC}@{$endif}@SSL_shutdown), + (n: 'SSL_read'; d: {$ifndef FPC}@{$endif}@SSL_read), + (n: 'SSL_peek'; d: {$ifndef FPC}@{$endif}@SSL_peek), + (n: 'SSL_write'; d: {$ifndef FPC}@{$endif}@SSL_write), + (n: 'SSL_pending'; d: {$ifndef FPC}@{$endif}@SSL_pending), + (n: 'SSL_get_peer_certificate'; d: {$ifndef FPC}@{$endif}@SSL_get_peer_certificate), + (n: 'SSL_get_version'; d: {$ifndef FPC}@{$endif}@SSL_get_version), + (n: 'SSL_CTX_set_verify'; d: {$ifndef FPC}@{$endif}@SSL_CTX_set_verify), + (n: 'SSL_get_current_cipher'; d: {$ifndef FPC}@{$endif}@SSL_get_current_cipher), + (n: 'SSL_CIPHER_get_name'; d: {$ifndef FPC}@{$endif}@SSL_CIPHER_get_name), + (n: 'SSL_CIPHER_get_bits'; d: {$ifndef FPC}@{$endif}@SSL_CIPHER_get_bits), + (n: 'SSL_get_verify_result'; d: {$ifndef FPC}@{$endif}@SSL_get_verify_result) + {$ifndef mswindows} + , + (n: 'SSLeay'; d: {$ifndef FPC}@{$endif}@SSLeay), + (n: 'OpenSSL_add_all_ciphers'; d: {$ifndef FPC}@{$endif}@OpenSSL_add_all_ciphers), + (n: 'OpenSSL_add_all_digests'; d: {$ifndef FPC}@{$endif}@OpenSSL_add_all_digests), + (n: 'ERR_load_crypto_strings'; d: {$ifndef FPC}@{$endif}@ERR_load_crypto_strings), + (n: 'ERR_peek_error'; d: {$ifndef FPC}@{$endif}@ERR_peek_error), + (n: 'ERR_peek_last_error'; d: {$ifndef FPC}@{$endif}@ERR_peek_last_error), + (n: 'CRYPTO_malloc'; d: {$ifndef FPC}@{$endif}@CRYPTO_malloc), + (n: 'CRYPTO_realloc'; d: {$ifndef FPC}@{$endif}@CRYPTO_realloc), + (n: 'CRYPTO_remalloc'; d: {$ifndef FPC}@{$endif}@CRYPTO_remalloc), + (n: 'CRYPTO_free'; d: {$ifndef FPC}@{$endif}@CRYPTO_free) + {$endif} + ); + funcsutil: array[0..20] of funcinfoty = ( + (n: 'SSLeay_version'; d: {$ifndef FPC}@{$endif}@SSLeay_version), + (n: 'ERR_error_string_n'; d: {$ifndef FPC}@{$endif}@ERR_error_string_n), + (n: 'ERR_get_error'; d: {$ifndef FPC}@{$endif}@ERR_get_error), + (n: 'ERR_clear_error'; d: {$ifndef FPC}@{$endif}@ERR_clear_error), + (n: 'ERR_free_strings'; d: {$ifndef FPC}@{$endif}@ERR_free_strings), + (n: 'ERR_remove_state'; d: {$ifndef FPC}@{$endif}@ERR_remove_state), + (n: 'OPENSSL_add_all_algorithms_noconf'; d: {$ifndef FPC}@{$endif}@OPENSSL_add_all_algorithms_noconf), + (n: 'CRYPTO_cleanup_all_ex_data'; d: {$ifndef FPC}@{$endif}@CRYPTO_cleanup_all_ex_data), +// 'RAND_screen', + (n: 'i2d_X509_bio'; d: {$ifndef FPC}@{$endif}@i2d_X509_bio), + (n: 'i2d_PrivateKey_bio'; d: {$ifndef FPC}@{$endif}@i2d_PrivateKey_bio), + // 3DES functions + // + (n: 'CRYPTO_num_locks'; d: {$ifndef FPC}@{$endif}@CRYPTO_num_locks), + (n: 'CRYPTO_set_locking_callback'; d: {$ifndef FPC}@{$endif}@CRYPTO_set_locking_callback), + (n: 'CRYPTO_set_id_callback'; d: {$ifndef FPC}@{$endif}@CRYPTO_set_id_callback), + + (n: 'OBJ_obj2nid'; d: {$ifndef FPC}@{$endif}@OBJ_obj2nid), + (n: 'OBJ_txt2nid'; d: {$ifndef FPC}@{$endif}@OBJ_txt2nid), + (n: 'OBJ_txt2obj'; d: {$ifndef FPC}@{$endif}@OBJ_txt2obj), + (n: 'sk_new_null'; d: {$ifndef FPC}@{$endif}@sk_new_null), + (n: 'sk_free'; d: {$ifndef FPC}@{$endif}@sk_free), + (n: 'sk_push'; d: {$ifndef FPC}@{$endif}@sk_push), + (n: 'sk_num'; d: {$ifndef FPC}@{$endif}@sk_num), + (n: 'sk_value'; d: {$ifndef FPC}@{$endif}@sk_value) + + ); + + errormessage = 'Can not load OpenSSL library, '; +begin + initializedynlib(libinfo,sonames,openssllib,funcs,[],errormessage); + initializedynlib(libinfoutil,sonamesutil,opensslutillib, + funcsutil,[],errormessage,@initssllib); +end; + +var + libloaded: boolean; + +procedure initsslinterface; //calls initializeopenssl once +begin + if not libloaded then begin + initializeopenssl([],[]); + libloaded:= true; + end; +end; + +procedure deinitssllib(const data: pointer); +var + int1: cint; +begin + crypto_cleanup_all_ex_data; + err_remove_state(0); + for int1:= 0 to high(locks) do begin + sys_mutexdestroy(locks[int1]); + end; + locks:= nil; +end; + +procedure releaseopenssl; +begin + releasedynlib(libinfoutil); + releasedynlib(libinfo,@deinitssllib); +end; + +procedure regopensslinit(const initproc: dynlibprocty); +begin + regdynlibinit(libinfoutil,initproc); +end; + +procedure regopenssldeinit(const deinitproc: dynlibprocty); +begin + regdynlibdeinit(libinfoutil,deinitproc); +end; + +{ +function issslloaded: boolean; +begin + result:= sslloaded; +end; +} + +{ +finalization + destroysslinterface; +} +initialization + initializelibinfo(libinfo); + initializelibinfo(libinfoutil); +finalization + if libloaded then begin + releaseopenssl; + end; + finalizelibinfo(libinfo); + finalizelibinfo(libinfoutil); +end. diff --git a/mseide-msegui/lib/common/crypto/mseopensslaes.pas b/mseide-msegui/lib/common/crypto/mseopensslaes.pas new file mode 100644 index 0000000..f4a4686 --- /dev/null +++ b/mseide-msegui/lib/common/crypto/mseopensslaes.pas @@ -0,0 +1,38 @@ +{ MSEgui Copyright (c) 2007-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseopensslaes; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseopenssl,msectypes; + +var + AES_set_decrypt_key: function(userKey: PCharacter; bits: cint; + key: pAES_KEY): cint; cdecl; + AES_cbc_encrypt: procedure(buffer: PCharacter; u: PCharacter; length: clong; + key: pAES_KEY; ivec: pointer; enc: cint); cdecl; + +implementation +uses + msedynload; + +procedure init(const info: dynlibinfoty); +const + funcs: array[0..1] of funcinfoty = ( + (n: 'AES_set_decrypt_key'; d: @AES_set_decrypt_key), + (n: 'AES_cbc_encrypt'; d: @AES_cbc_encrypt) + ); +begin + getprocaddresses(info,funcs); +end; + +initialization + regopensslinit(@init); +end. diff --git a/mseide-msegui/lib/common/crypto/mseopensslasn.pas b/mseide-msegui/lib/common/crypto/mseopensslasn.pas new file mode 100644 index 0000000..f2ad7d7 --- /dev/null +++ b/mseide-msegui/lib/common/crypto/mseopensslasn.pas @@ -0,0 +1,75 @@ +{ MSEgui Copyright (c) 2007-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseopensslasn; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseopenssl,msectypes; +type +// ASN1 types + pASN1_OBJECT = pointer; + pASN1_STRING = ^ASN1_STRING; + ASN1_STRING = record + length: cint; + asn1_type: cint; + data: pointer; + flags: clong; + end; + pASN1_IA5STRING = pASN1_STRING; + pASN1_ENUMERATED = pASN1_STRING; + pASN1_TIME = pASN1_STRING; + pASN1_OCTET_STRING = pASN1_STRING; + +var + // ASN.1 functions + ASN1_UTCTIME_New: function(): PASN1_UTCTIME; cdecl; + ASN1_UTCTIME_Free: procedure(a: PASN1_UTCTIME); cdecl; + ASN1_INTEGER_Set: function(a: PASN1_INTEGER; v: cint): cint; cdecl; + ASN1_IA5STRING_new: function: pASN1_IA5STRING; cdecl; + ASN1_INTEGER_free: procedure(x: pASN1_IA5STRING); cdecl; + ASN1_INTEGER_get: function(a: pointer): clong; cdecl; + ASN1_STRING_set_default_mask: procedure(mask: cardinal); cdecl; + ASN1_STRING_get_default_mask: function: cardinal; cdecl; + ASN1_TIME_print: function(fp: pBIO; a: pASN1_TIME): cint; cdecl; + i2d_ASN1_TIME: function(a: pASN1_TIME; pp: PCharacter): cint; cdecl; + d2i_ASN1_TIME: function(var a: pASN1_TIME; pp: PCharacter; + length: clong): pASN1_TIME; cdecl; + // Internal to ASN.1 and ASN.1 to internal conversion functions + i2a_ASN1_INTEGER: function(bp: pBIO; a: pASN1_INTEGER): cint; cdecl; + a2i_ASN1_INTEGER: function(bp: pBIO; bs: pASN1_INTEGER; buf: PCharacter; + size: cint): cint; cdecl; +implementation +uses + msedynload; + +procedure init(const info: dynlibinfoty); +const + funcs: array[0..12] of funcinfoty = ( + (n: 'ASN1_UTCTIME_new'; d: @ASN1_UTCTIME_new), + (n: 'ASN1_UTCTIME_free'; d: @ASN1_UTCTIME_free), + (n: 'ASN1_INTEGER_set'; d: @ASN1_INTEGER_set), + (n: 'ASN1_IA5STRING_new'; d: @ASN1_IA5STRING_new), + (n: 'ASN1_INTEGER_free'; d: @ASN1_INTEGER_free), + (n: 'ASN1_INTEGER_get'; d: @ASN1_INTEGER_get), + (n: 'ASN1_STRING_set_default_mask'; d: @ASN1_STRING_set_default_mask), + (n: 'ASN1_STRING_get_default_mask'; d: @ASN1_STRING_get_default_mask), + (n: 'ASN1_TIME_print'; d: @ASN1_TIME_print), + (n: 'i2d_ASN1_TIME'; d: @i2d_ASN1_TIME), + (n: 'd2i_ASN1_TIME'; d: @d2i_ASN1_TIME), + (n: 'i2a_ASN1_INTEGER'; d: @i2a_ASN1_INTEGER), + (n: 'a2i_ASN1_INTEGER'; d: @a2i_ASN1_INTEGER) + ); +begin + getprocaddresses(info,funcs); +end; + +initialization + regopensslinit(@init); +end. diff --git a/mseide-msegui/lib/common/crypto/mseopensslbignum.pas b/mseide-msegui/lib/common/crypto/mseopensslbignum.pas new file mode 100644 index 0000000..8a8e24e --- /dev/null +++ b/mseide-msegui/lib/common/crypto/mseopensslbignum.pas @@ -0,0 +1,379 @@ +{ MSEgui Copyright (c) 2007-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseopensslbignum; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseopenssl,msectypes; + +type + pBN_ULONG = ^BN_ULONG; + BN_ULONG = culong; // system dependent, consider it as a opaque pointer + + pBIGNUM = ^BIGNUM; + BIGNUM = record + d: pBN_ULONG; // Pointer to an array of 'BN_BITS2' bit chunks. + top: cint; // Index of last used d +1. + // The next are internal book keeping for bn_expand. + dmax: cint; // Size of the d array. + neg: cint; // one if the number is negative + flags: cint; + end; + + pBN_CTX = ^BN_CTX; + BN_CTX = record + tos: cint; + bn: array [0..BN_CTX_NUM-1] of BIGNUM; + flags: cint; + depth: cint; + pos: array [0..BN_CTX_NUM_POS-1] of cint; + too_many: cint; + end; + + pBN_BLINDING = ^BN_BLINDING; + BN_BLINDING = record + init: cint; + A: pBIGNUM; + Ai: pBIGNUM; + _mod: pBIGNUM; // just a reference (original name: mod) + end; + + // Used for montgomery multiplication + pBN_MONT_CTX = ^BN_MONT_CTX; + BN_MONT_CTX = record + ri: cint; // number of bits in R + RR: BIGNUM; // used to convert to montgomery form + N: BIGNUM; // The modulus + Ni: BIGNUM; // R*(1/R mod N) - N*Ni = 1 + // (Ni is only stored for bignum algorithm) + n0: BN_ULONG; // least significant word of Ni + flags: cint; + end; + + // Used for reciprocal division/mod functions + // It cannot be shared between threads + pBN_RECP_CTX = ^BN_RECP_CTX; + BN_RECP_CTX = record + N: BIGNUM; // the divisor + Nr: BIGNUM; // the reciprocal + num_bits: cint; + shift: cint; + flags: cint; + end; + +var + // Big number function + BN_new:function: pBIGNUM; cdecl; + BN_init: procedure(bn: pBIGNUM); cdecl; + BN_clear: procedure(bn: pBIGNUM); cdecl; + BN_free: procedure(bn: pBIGNUM); cdecl; + BN_clear_free: procedure(bn: pBIGNUM); cdecl; + BN_set_params: procedure (mul, high, low, mont: cint); cdecl; + BN_get_params: function(which: cint): cint; cdecl; + BN_options:function: PCharacter; cdecl; + BN_CTX_new: function: pBN_CTX; cdecl; + BN_CTX_init: procedure(ctx: pBN_CTX); cdecl; + BN_CTX_start: procedure(ctx: pBN_CTX); cdecl; + BN_CTX_get: function(ctx: pBN_CTX): pBIGNUM; cdecl; + BN_CTX_end: procedure(ctx: pBN_CTX); cdecl; + BN_CTX_free: procedure(ctx: pBN_CTX); cdecl; + BN_MONT_CTX_new: function: pBN_MONT_CTX; cdecl; + BN_MONT_CTX_init: procedure(m_ctx: pBN_MONT_CTX); cdecl; + BN_MONT_CTX_set: function(m_ctx: pBN_MONT_CTX;const modulus: pBIGNUM; + ctx: pBN_CTX): cint; cdecl; + BN_MONT_CTX_copy: function(_to: pBN_MONT_CTX; + from: pBN_MONT_CTX): pBN_MONT_CTX; cdecl; + BN_MONT_CTX_free: procedure(m_ctx: pBN_MONT_CTX); cdecl; + BN_mod_mul_montgomery: function(r, a, b: pBIGNUM; m_ctx: pBN_MONT_CTX; + ctx: pBN_CTX): cint; cdecl; + BN_from_montgomery: function(r, a: pBIGNUM; m_ctx: pBN_MONT_CTX; + ctx: pBN_CTX): cint; cdecl; + BN_RECP_CTX_init: procedure(recp: pBN_RECP_CTX); cdecl; + BN_RECP_CTX_set: function(recp: pBN_RECP_CTX; const rdiv: pBIGNUM; + ctx: pBN_CTX): cint; cdecl; + BN_RECP_CTX_new: function: pBN_RECP_CTX; cdecl; + BN_RECP_CTX_free: procedure(recp: pBN_RECP_CTX); cdecl; + BN_div_recp: function(dv, rem, a: pBIGNUM; recp: pBN_RECP_CTX; + ctx: pBN_CTX): cint; cdecl; + BN_mod_mul_reciprocal: function(r, a, b: pBIGNUM; recp: pBN_RECP_CTX; + ctx: pBN_CTX): cint; cdecl; + BN_BLINDING_new: function(a: pBIGNUM; Ai: pBIGNUM; + _mod: pBIGNUM): pBN_BLINDING; cdecl; + BN_BLINDING_update: function(b: pBN_BLINDING; + ctx: pBN_CTX): pBN_BLINDING; cdecl; + BN_BLINDING_free: procedure(b: pBN_BLINDING); cdecl; + BN_BLINDING_convert: function(n: pBIGNUM; r: pBN_BLINDING; + ctx: pBN_CTX): cint; cdecl; + BN_BLINDING_invert: function(n: pBIGNUM; b: pBN_BLINDING; + ctx: pBN_CTX): cint; cdecl; + BN_copy: function(_to: pBIGNUM; const from: pBIGNUM): pBIGNUM; cdecl; + BN_dup: function(const from: pBIGNUM): pBIGNUM; cdecl; + BN_bn2bin: function(const n: pBIGNUM; _to: pointer): cint; cdecl; + BN_bin2bn: function(const _from: pointer; len: cint; + ret: pBIGNUM): pBIGNUM; cdecl; + BN_bn2hex: function(const n: pBIGNUM): PCharacter; cdecl; + BN_bn2dec: function(const n: pBIGNUM): PCharacter; cdecl; + BN_hex2bn: function(var n: pBIGNUM; const str: PCharacter): cint; cdecl; + BN_dec2bn: function(var n: pBIGNUM; const str: PCharacter): cint; cdecl; + BN_bn2mpi: function(const a: pBIGNUM; _to: pointer): cint; cdecl; + BN_mpi2bn: function(s: pointer; len: cint; ret: pBIGNUM): pBIGNUM; cdecl; + BN_print: function(fp: pBIO; const a: pointer): cint; cdecl; + // BN_print_fp: function(FILE *fp, const BIGNUM *a): cint; cdecl; + BN_value_one: function: pBIGNUM; cdecl; + BN_set_word: function(n: pBIGNUM; w: cardinal): cint; cdecl; + BN_get_word: function(n: pBIGNUM): cardinal; cdecl; + BN_cmp: function(a: pBIGNUM; b: pBIGNUM): cint; cdecl; + BN_ucmp: function(a: pBIGNUM; b: pBIGNUM): cint; cdecl; + BN_num_bits: function(const a: pBIGNUM): cint; cdecl; + BN_num_bits_word: function(w: BN_ULONG): cint; cdecl; + BN_add: function(r: pBIGNUM; const a, b: pBIGNUM): cint; cdecl; + BN_sub: function(r: pBIGNUM; const a, b: pBIGNUM): cint; cdecl; + BN_uadd: function(r: pBIGNUM; const a, b: pBIGNUM): cint; cdecl; + BN_usub: function(r: pBIGNUM; const a, b: pBIGNUM): cint; cdecl; + BN_mul: function(r: pBIGNUM; a: pBIGNUM; b: pBIGNUM; + ctx: pBN_CTX): cint; cdecl; + BN_sqr: function(r: pBIGNUM; a: pBIGNUM; ctx: pBN_CTX): cint; cdecl; + BN_div: function(dv: pBIGNUM; rem: pBIGNUM; const a, d: pBIGNUM; + ctx: pBN_CTX): cint; cdecl; + BN_exp: function(r: pBIGNUM; a: pBIGNUM; p: pBIGNUM; + ctx: pBN_CTX): cint; cdecl; + BN_mod_exp: function(r, a: pBIGNUM; const p, m: pBIGNUM; + ctx: pBN_CTX): cint; cdecl; + BN_gcd: function(r: pBIGNUM; a: pBIGNUM; b: pBIGNUM; + ctx: pBN_CTX): cint; cdecl; + // BN_nnmod requires OpenSSL >= 0.9.7 + BN_nnmod: function(rem: pBIGNUM; const a: pBIGNUM; + const m: pBIGNUM; ctx: pBN_CTX): cint; cdecl; + // BN_mod_add requires OpenSSL >= 0.9.7 + BN_mod_add: function(r: pBIGNUM; a: pBIGNUM; b: pBIGNUM; + const m: pBIGNUM; ctx: pBN_CTX): cint;cdecl; + // BN_mod_sub requires OpenSSL >= 0.9.7 + BN_mod_sub: function(r: pBIGNUM; a: pBIGNUM; b: pBIGNUM; + const m: pBIGNUM; ctx: pBN_CTX): cint; cdecl; + // BN_mod_mul requires OpenSSL >= 0.9.7 + BN_mod_mul: function(ret, a, b: pBIGNUM; const m: pBIGNUM; + ctx: pBN_CTX): cint; cdecl; + // BN_mod_sqr requires OpenSSL >= 0.9.7 + BN_mod_sqr: function(r: pBIGNUM; a: pBIGNUM; + const m: pBIGNUM; ctx: pBN_CTX): cint; cdecl; + BN_reciprocal: function(r, m: pBIGNUM; ctx: pBN_CTX): cint; cdecl; + BN_mod_exp2_mont: function(r, a1, p1, a2, p2, m: pBIGNUM; + ctx: pBN_CTX; m_ctx: pBN_MONT_CTX): cint; cdecl; + BN_mod_exp_mont: function(r, a: pBIGNUM; const p, m: pBIGNUM; + ctx: pBN_CTX; m_ctx: pBN_MONT_CTX): cint; cdecl; + BN_mod_exp_mont_word: function(r: pBIGNUM; a: BN_ULONG; + const p, m: pBIGNUM; ctx: pBN_CTX; m_ctx: pBN_MONT_CTX): cint; cdecl; + BN_mod_exp_simple: function(r, a, p, m: pBIGNUM; + ctx: pBN_CTX): cint; cdecl; + BN_mod_exp_recp: function(r: pBIGNUM; const a, p, m: pBIGNUM; + ctx: pBN_CTX): cint; cdecl; + BN_mod_inverse: function(ret, a: pBIGNUM; const n: pBIGNUM; + ctx: pBN_CTX): pBIGNUM; cdecl; + BN_add_word: function (a: pBIGNUM; w: BN_ULONG): cint; cdecl; + // Adds w to a ("a+=w"). + BN_sub_word: function(a: pBIGNUM; w: BN_ULONG): cint; cdecl; + // Subtracts w from a ("a-=w"). + BN_mul_word: function(a: pBIGNUM; w: BN_ULONG): cint; cdecl; + // Multiplies a and w ("a*=b"). + BN_div_word: function(a: pBIGNUM; w: BN_ULONG): BN_ULONG; cdecl; + // Divides a by w ("a/=w") and returns the remainder. + BN_mod_word: function(const a: pBIGNUM; w: BN_ULONG): BN_ULONG; cdecl; + // Returns the remainder of a divided by w ("a%m"). + bn_mul_words: function(rp, ap: pBN_ULONG; num: cint; + w: BN_ULONG): BN_ULONG; cdecl; + bn_mul_add_words: function(rp, ap: pBN_ULONG; num: cint; + w: BN_ULONG): BN_ULONG; cdecl; + bn_sqr_words: procedure(rp, ap: pBN_ULONG; num: cint); cdecl; + bn_div_words: function(h, l, d: BN_ULONG): BN_ULONG; cdecl; + bn_add_words: function(rp, ap, bp: pBN_ULONG; num: cint): BN_ULONG; cdecl; + bn_sub_words: function(rp, ap, bp: pBN_ULONG; num: cint): BN_ULONG; cdecl; + bn_expand2: function(a: pBIGNUM; n: cint): pBIGNUM; cdecl; + BN_set_bit: function(a: pBIGNUM; n: cint): cint; cdecl; + BN_clear_bit: function(a: pBIGNUM; n: cint): cint; cdecl; + BN_is_bit_set: function(const a: pBIGNUM; n: cint): cint; cdecl; + BN_mask_bits: function(a: pBIGNUM; n: cint): cint; cdecl; + BN_lshift: function(r: pBIGNUM; const a: pBIGNUM; n: cint): cint; cdecl; + BN_lshift1: function(r: pBIGNUM; a: pBIGNUM): cint; cdecl; + BN_rshift: function(r: pBIGNUM; const a: pBIGNUM; n: cint): cint; cdecl; + BN_rshift1: function(r: pBIGNUM; a: pBIGNUM): cint; cdecl; + BN_generate_prime: function (ret: pBIGNUM; num, safe: cint; + add, rem: pBIGNUM; + progress: TProgressCallbackFunction; + cb_arg: pointer): pBIGNUM; cdecl; + BN_is_prime: function(const a: pBIGNUM; checks: cint; + progress: TProgressCallbackFunction; ctx: pBN_CTX; + cb_arg: pointer): cint; cdecl; + BN_is_prime_fasttest: function(const a: pBIGNUM; checks: cint; + progress: TProgressCallbackFunction; ctx: pBN_CTX; + cb_arg: pointer; do_trial_division: cint): cint; cdecl; + BN_rand: function(rnd: pBIGNUM; bits, top, bottom: cint): cint; cdecl; + BN_pseudo_rand: function(rnd: pBIGNUM; + bits, top, bottom: cint): cint; cdecl; + BN_rand_range: function(rnd, range: pBIGNUM): cint; cdecl; + // BN_pseudo_rand_range requires OpenSSL >= 0.9.6c + BN_pseudo_rand_range: function(rnd, range: pBIGNUM): cint; cdecl; + BN_bntest_rand: function(rnd: pBIGNUM; + bits, top, bottom: cint): cint; cdecl; + BN_to_ASN1_INTEGER: function(bn: pBIGNUM; + ai: pASN1_INTEGER): pASN1_INTEGER; cdecl; + BN_to_ASN1_ENUMERATED: function(bn: pBIGNUM; + ai: pASN1_ENUMERATED): pASN1_ENUMERATED; cdecl; + +function BN_to_montgomery(r, a: pBIGNUM; m_ctx: pBN_MONT_CTX; + ctx: pBN_CTX): cint; +function BN_zero(n: pBIGNUM): cint; +function BN_one(n: pBIGNUM): cint; +function BN_num_bytes(const a: pBIGNUM): cint; +// BN_mod redefined as BN_div in some DLL version +function BN_mod(rem: pBIGNUM; const a, m: pBIGNUM; ctx: pBN_CTX): cint; + +implementation +uses + msedynload; + +function BN_to_montgomery(r, a: pBIGNUM; m_ctx: pBN_MONT_CTX; + ctx: pBN_CTX): cint; +begin + result := BN_mod_mul_montgomery(r, a, @(m_ctx^.RR), m_ctx, ctx); +end; + +function BN_zero(n: pBIGNUM): cint; +begin + result := BN_set_word(n, 0) +end; + +function BN_one(n: pBIGNUM): cint; +begin + result := BN_set_word(n, 1) +end; + +function BN_num_bytes(const a: pBIGNUM): cint; +begin + result := (BN_num_bits(a) + 7) div 8; +end; + +function BN_mod(rem: pBIGNUM; const a, m: pBIGNUM; ctx: pBN_CTX): cint; +begin + result := BN_div(nil, rem, a, m, ctx); +end; + +procedure init(const info: dynlibinfoty); +const + funcs: array[0..101] of funcinfoty = ( + (n: 'BN_new'; d: @BN_new), + (n: 'BN_init'; d: @BN_init), + (n: 'BN_clear'; d: @BN_clear), + (n: 'BN_free'; d: @BN_free), + (n: 'BN_clear_free'; d: @BN_clear_free), + (n: 'BN_set_params'; d: @BN_set_params), + (n: 'BN_get_params'; d: @BN_get_params), + (n: 'BN_options'; d: @BN_options), + (n: 'BN_CTX_new'; d: @BN_CTX_new), + (n: 'BN_CTX_init'; d: @BN_CTX_init), + (n: 'BN_CTX_start'; d: @BN_CTX_start), + (n: 'BN_CTX_get'; d: @BN_CTX_get), + (n: 'BN_CTX_end'; d: @BN_CTX_end), + (n: 'BN_CTX_free'; d: @BN_CTX_free), + (n: 'BN_MONT_CTX_new'; d: @BN_MONT_CTX_new), + (n: 'BN_MONT_CTX_init'; d: @BN_MONT_CTX_init), + (n: 'BN_MONT_CTX_set'; d: @BN_MONT_CTX_set), + (n: 'BN_MONT_CTX_copy'; d: @BN_MONT_CTX_copy), + (n: 'BN_MONT_CTX_free'; d: @BN_MONT_CTX_free), + (n: 'BN_mod_mul_montgomery'; d: @BN_mod_mul_montgomery), + (n: 'BN_from_montgomery'; d: @BN_from_montgomery), + (n: 'BN_RECP_CTX_init'; d: @BN_RECP_CTX_init), + (n: 'BN_RECP_CTX_set'; d: @BN_RECP_CTX_set), + (n: 'BN_RECP_CTX_new'; d: @BN_RECP_CTX_new), + (n: 'BN_RECP_CTX_free'; d: @BN_RECP_CTX_free), + (n: 'BN_div_recp'; d: @BN_div_recp), + (n: 'BN_mod_mul_reciprocal'; d: @BN_mod_mul_reciprocal), + (n: 'BN_BLINDING_new'; d: @BN_BLINDING_new), + (n: 'BN_BLINDING_update'; d: @BN_BLINDING_update), + (n: 'BN_BLINDING_free'; d: @BN_BLINDING_free), + (n: 'BN_BLINDING_convert'; d: @BN_BLINDING_convert), + (n: 'BN_BLINDING_invert'; d: @BN_BLINDING_invert), + (n: 'BN_copy'; d: @BN_copy), + (n: 'BN_dup'; d: @BN_dup), + (n: 'BN_bn2bin'; d: @BN_bn2bin), + (n: 'BN_bin2bn'; d: @BN_bin2bn), + (n: 'BN_bn2hex'; d: @BN_bn2hex), + (n: 'BN_bn2dec'; d: @BN_bn2dec), + (n: 'BN_hex2bn'; d: @BN_hex2bn), + (n: 'BN_dec2bn'; d: @BN_dec2bn), + (n: 'BN_bn2mpi'; d: @BN_bn2mpi), + (n: 'BN_mpi2bn'; d: @BN_mpi2bn), + (n: 'BN_print'; d: @BN_print), + (n: 'BN_value_one'; d: @BN_value_one), + (n: 'BN_set_word'; d: @BN_set_word), + (n: 'BN_get_word'; d: @BN_get_word), + (n: 'BN_cmp'; d: @BN_cmp), + (n: 'BN_ucmp'; d: @BN_ucmp), + (n: 'BN_num_bits'; d: @BN_num_bits), + (n: 'BN_num_bits_word'; d: @BN_num_bits_word), + (n: 'BN_add'; d: @BN_add), + (n: 'BN_sub'; d: @BN_sub), + (n: 'BN_uadd'; d: @BN_uadd), + (n: 'BN_usub'; d: @BN_usub), + (n: 'BN_mul'; d: @BN_mul), + (n: 'BN_sqr'; d: @BN_sqr), + (n: 'BN_div'; d: @BN_div), + (n: 'BN_exp'; d: @BN_exp), + (n: 'BN_mod_exp'; d: @BN_mod_exp), + (n: 'BN_gcd'; d: @BN_gcd), + (n: 'BN_nnmod'; d: @BN_nnmod), + (n: 'BN_mod_add'; d: @BN_mod_add), + (n: 'BN_mod_sub'; d: @BN_mod_sub), + (n: 'BN_mod_mul'; d: @BN_mod_mul), + (n: 'BN_mod_sqr'; d: @BN_mod_sqr), + (n: 'BN_reciprocal'; d: @BN_reciprocal), + (n: 'BN_mod_exp2_mont'; d: @BN_mod_exp2_mont), + (n: 'BN_mod_exp_mont'; d: @BN_mod_exp_mont), + (n: 'BN_mod_exp_mont_word'; d: @BN_mod_exp_mont_word), + (n: 'BN_mod_exp_simple'; d: @BN_mod_exp_simple), + (n: 'BN_mod_exp_recp'; d: @BN_mod_exp_recp), + (n: 'BN_mod_inverse'; d: @BN_mod_inverse), + (n: 'BN_add_word'; d: @BN_add_word), + (n: 'BN_sub_word'; d: @BN_sub_word), + (n: 'BN_mul_word'; d: @BN_mul_word), + (n: 'BN_div_word'; d: @BN_div_word), + (n: 'BN_mod_word'; d: @BN_mod_word), + (n: 'bn_mul_words'; d: @bn_mul_words), + (n: 'bn_mul_add_words'; d: @bn_mul_add_words), + (n: 'bn_sqr_words'; d: @bn_sqr_words), + (n: 'bn_div_words'; d: @bn_div_words), + (n: 'bn_add_words'; d: @bn_add_words), + (n: 'bn_sub_words'; d: @bn_sub_words), + (n: 'bn_expand2'; d: @bn_expand2), + (n: 'BN_set_bit'; d: @BN_set_bit), + (n: 'BN_clear_bit'; d: @BN_clear_bit), + (n: 'BN_is_bit_set'; d: @BN_is_bit_set), + (n: 'BN_mask_bits'; d: @BN_mask_bits), + (n: 'BN_lshift'; d: @BN_lshift), + (n: 'BN_lshift1'; d: @BN_lshift1), + (n: 'BN_rshift'; d: @BN_rshift), + (n: 'BN_rshift1'; d: @BN_rshift1), + (n: 'BN_generate_prime'; d: @BN_generate_prime), + (n: 'BN_is_prime'; d: @BN_is_prime), + (n: 'BN_is_prime_fasttest'; d: @BN_is_prime_fasttest), + (n: 'BN_rand'; d: @BN_rand), + (n: 'BN_pseudo_rand'; d: @BN_pseudo_rand), + (n: 'BN_rand_range'; d: @BN_rand_range), + (n: 'BN_pseudo_rand_range'; d: @BN_pseudo_rand_range), + (n: 'BN_bntest_rand'; d: @BN_bntest_rand), + (n: 'BN_to_ASN1_INTEGER'; d: @BN_to_ASN1_INTEGER), + (n: 'BN_to_ASN1_ENUMERATED'; d: @BN_to_ASN1_ENUMERATED) + ); +begin + getprocaddresses(info,funcs); +end; + +initialization + regopensslinit(@init); +end. diff --git a/mseide-msegui/lib/common/crypto/mseopensslbio.pas b/mseide-msegui/lib/common/crypto/mseopensslbio.pas new file mode 100644 index 0000000..f2236bc --- /dev/null +++ b/mseide-msegui/lib/common/crypto/mseopensslbio.pas @@ -0,0 +1,248 @@ +{ MSEgui Copyright (c) 2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseopensslbio; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseopenssl,msectypes; + +const + // These are the 'types' of BIOs + BIO_TYPE_NONE = $0000; + BIO_TYPE_MEM = $0001 or $0400; + BIO_TYPE_FILE = $0002 or $0400; + + BIO_TYPE_FD = $0004 or $0400 or $0100; + BIO_TYPE_SOCKET = $0005 or $0400 or $0100; + BIO_TYPE_NULL = $0006 or $0400; + BIO_TYPE_SSL = $0007 or $0200; + BIO_TYPE_MD = $0008 or $0200; // passive filter + BIO_TYPE_BUFFER = $0009 or $0200; // filter + BIO_TYPE_CIPHER = $00010 or $0200; // filter + BIO_TYPE_BASE64 = $00011 or $0200; // filter + BIO_TYPE_CONNECT = $00012 or $0400 or $0100; // socket - connect + BIO_TYPE_ACCEPT = $00013 or $0400 or $0100; // socket for accept + BIO_TYPE_PROXY_CLIENT = $00014 or $0200; // client proxy BIO + BIO_TYPE_PROXY_SERVER = $00015 or $0200; // server proxy BIO + BIO_TYPE_NBIO_TEST = $00016 or $0200; // server proxy BIO + BIO_TYPE_NULL_FILTER = $00017 or $0200; + BIO_TYPE_BER = $00018 or $0200; // BER -> bin filter + BIO_TYPE_BIO = $00019 or $0400; // (half a; BIO pair + BIO_TYPE_LINEBUFFER = $00020 or $0200; // filter + + BIO_TYPE_DESCRIPTOR = $0100; // socket, fd, connect or accept + BIO_TYPE_FILTER= $0200; + BIO_TYPE_SOURCE_SINK = $0400; + + // BIO ops constants + // BIO_FILENAME_READ|BIO_CLOSE to open or close on free. + // BIO_set_fp(in,stdin,BIO_NOCLOSE); + BIO_NOCLOSE = $00; + BIO_CLOSE = $01; + BIO_FP_READ = $02; + BIO_FP_WRITE = $04; + BIO_FP_APPEND = $08; + BIO_FP_TEXT = $10; + + BIO_C_SET_FD = 104; + BIO_C_GET_FD = 105; + BIO_C_SET_FILENAME = 108; + BIO_CTRL_RESET = 1; // opt - rewind/zero etc + BIO_CTRL_EOF = 2; // opt - are we at the eof + BIO_CTRL_INFO = 3; // opt - extra tit-bits + BIO_CTRL_SET = 4; // man - set the 'IO' type + BIO_CTRL_GET = 5; // man - get the 'IO' type + BIO_CTRL_PUSH = 6; // opt - internal, used to signify change + BIO_CTRL_POP = 7; // opt - internal, used to signify change + BIO_CTRL_GET_CLOSE = 8; // man - set the 'close' on free + BIO_CTRL_SET_CLOSE = 9; // man - set the 'close' on free + BIO_CTRL_PENDING_C = 10; // opt - is their more data buffered + BIO_CTRL_FLUSH = 11; // opt - 'flush' buffered output + BIO_CTRL_DUP = 12; // man - extra stuff for 'duped' BIO + BIO_CTRL_WPENDING = 13; // opt - number of bytes still to write + + BIO_C_GET_MD_CTX = 120; +{ +type + PBIO_METHOD = SslPtr; + PBIO = SslPtr; +} +var + // BIO functions + BIO_new: function(b: PBIO_METHOD): PBIO; cdecl; + BIO_new_fd: function(fd: cint; close_flag: cint): PBIO; cdecl; + BIO_new_file: function(const filename: PCharacter; + const mode: PCharacter): pBIO; cdecl; + BIO_free_all: procedure(b: PBIO); cdecl; + BIO_s_mem: function(): PBIO_METHOD; cdecl; + BIO_s_fd: function: pBIO_METHOD; cdecl; + BIO_s_file: function: pBIO_METHOD; cdecl; + BIO_ctrl_pending: function(b: PBIO): cint; cdecl; + BIO_read: function(b: PBIO; Buf: pbyte; Len: cint): cint; cdecl; + BIO_write: function(b: PBIO; Buf: pbyte; Len: cint): cint; cdecl; + d2i_PKCS12_bio: function(b:PBIO; Pkcs12: SslPtr): SslPtr; cdecl; + BIO_set: function(a: pBIO; _type: pBIO_METHOD): cint; cdecl; + BIO_free: function(a: pBIO): cint; cdecl; + BIO_vfree: procedure(a: pBIO); cdecl; + BIO_push: function(b: pBIO; append: pBIO): pBIO; cdecl; + BIO_pop: function(b: pBIO): pBIO; cdecl; + BIO_ctrl: function(bp: pBIO; cmd: cint; larg: clong; + parg: Pointer): clong; cdecl; + BIO_int_ctrl: function(bp: pBIO; cmd: cint; larg: clong; + iarg: cint): clong; cdecl; + BIO_gets: function(b: pBIO; buf: PCharacter; size: cint): cint; cdecl; + BIO_puts: function(b: pBIO; const buf: PCharacter): cint; cdecl; + BIO_f_base64: function: pBIO_METHOD; cdecl; + +//optional todo: these are probably macros + BIO_set_mem_eof_return: procedure(b: pBIO; v: cint); cdecl; + BIO_set_mem_buf: procedure(b: pBIO; bm: pBUF_MEM; c: cint); cdecl; + BIO_get_mem_ptr: procedure(b: pBIO; var pp: pBUF_MEM); cdecl; + BIO_new_mem_buf: function(buf: pointer; len: cint): pBIO; cdecl; + +function BIO_flush(b: pBIO): cint; +function BIO_get_mem_data(b: pBIO; var pp: PCharacter): clong; +function BIO_get_md_ctx(bp: pBIO; mdcp: Pointer): clong; +function BIO_reset(bp: pBIO): cint; +function BIO_eof(bp: pBIO): cint; +function BIO_set_close(bp: pBIO; c: cint): cint; +function BIO_get_close(bp: pBIO): cint; +function BIO_pending(bp: pBIO): cint; +function BIO_wpending(bp: pBIO): cint; +function BIO_read_filename(bp: pBIO; filename: PCharacter): cint; +function BIO_write_filename(bp: pBIO; filename: PCharacter): cint; +function BIO_append_filename(bp: pBIO; filename: PCharacter): cint; +function BIO_rw_filename(bp: pBIO; filename: PCharacter): cint; +function BIO_set_fd(bp: pBIO; fd: cint; c: cint): clong; +function BIO_get_fd(bp: pBIO; var c: cint): cint; + + +implementation +uses + {$ifdef FPC}dynlibs,{$endif}msedynload; + +function BIO_flush(b: pBIO): cint; +begin + result := BIO_ctrl(b, BIO_CTRL_FLUSH, 0, nil); +end; + +function BIO_get_mem_data(b: pBIO; var pp: PCharacter): clong; +begin + result := BIO_ctrl(b, BIO_CTRL_INFO, 0, @pp); +end; + +function BIO_get_md_ctx(bp: pBIO; mdcp: Pointer): clong; +begin + result := BIO_ctrl(bp, BIO_C_GET_MD_CTX, 0, mdcp); +end; + +function BIO_reset(bp: pBIO): cint; +begin + result := BIO_ctrl(bp, BIO_CTRL_RESET, 0, nil); +end; + +function BIO_eof(bp: pBIO): cint; +begin + result := BIO_ctrl(bp, BIO_CTRL_EOF, 0, nil); +end; + +function BIO_set_close(bp: pBIO; c: cint): cint; +begin + result := BIO_ctrl(bp, BIO_CTRL_SET_CLOSE, c, nil); +end; + +function BIO_get_close(bp: pBIO): cint; +begin + result := BIO_ctrl(bp, BIO_CTRL_GET_CLOSE, 0, nil); +end; + +function BIO_pending(bp: pBIO): cint; +begin + result := BIO_ctrl(bp, BIO_CTRL_PENDING_C, 0, nil); +end; + +function BIO_wpending(bp: pBIO): cint; +begin + result := BIO_ctrl(bp, BIO_CTRL_WPENDING, 0, nil); +end; + +function BIO_read_filename(bp: pBIO; filename: PCharacter): cint; +begin + result := BIO_ctrl(bp, BIO_C_SET_FILENAME, BIO_CLOSE or + BIO_FP_READ, filename); +end; + +function BIO_write_filename(bp: pBIO; filename: PCharacter): cint; +begin + result := BIO_ctrl(bp, BIO_C_SET_FILENAME, BIO_CLOSE or + BIO_FP_WRITE, filename); +end; + +function BIO_append_filename(bp: pBIO; filename: PCharacter): cint; +begin + result := BIO_ctrl(bp, BIO_C_SET_FILENAME, BIO_CLOSE or + BIO_FP_APPEND, filename); +end; + +function BIO_rw_filename(bp: pBIO; filename: PCharacter): cint; +begin + result := BIO_ctrl(bp, BIO_C_SET_FILENAME, BIO_CLOSE or BIO_FP_READ or + BIO_FP_WRITE, filename); +end; + +function BIO_set_fd(bp: pBIO; fd: cint; c: cint): clong; +begin + result:= bio_int_ctrl(bp,bio_c_set_fd,c,fd); +end; + +function BIO_get_fd(bp: pBIO; var c: cint): cint; +begin + result:= bio_ctrl(bp,bio_c_get_fd,0,@c); +end; + +procedure init(const info: dynlibinfoty); +const + funcs: array[0..19] of funcinfoty = ( + (n: 'BIO_new'; d: {$ifndef FPC}@{$endif}@BIO_new), + (n: 'BIO_new_fd'; d: {$ifndef FPC}@{$endif}@BIO_new_fd), + (n: 'BIO_free_all'; d: {$ifndef FPC}@{$endif}@BIO_free_all), + (n: 'BIO_s_mem'; d: {$ifndef FPC}@{$endif}@BIO_s_mem), + (n: 'BIO_ctrl_pending'; d: {$ifndef FPC}@{$endif}@BIO_ctrl_pending), + (n: 'BIO_read'; d: {$ifndef FPC}@{$endif}@BIO_read), + (n: 'BIO_write'; d: {$ifndef FPC}@{$endif}@BIO_write), + (n: 'd2i_PKCS12_bio'; d: {$ifndef FPC}@{$endif}@d2i_PKCS12_bio), + (n: 'BIO_new_file'; d: {$ifndef FPC}@{$endif}@BIO_new_file), + (n: 'BIO_set'; d: {$ifndef FPC}@{$endif}@BIO_set), + (n: 'BIO_free'; d: {$ifndef FPC}@{$endif}@BIO_free), + (n: 'BIO_vfree'; d: {$ifndef FPC}@{$endif}@BIO_vfree), + (n: 'BIO_push'; d: {$ifndef FPC}@{$endif}@BIO_push), + (n: 'BIO_pop'; d: {$ifndef FPC}@{$endif}@BIO_pop), + (n: 'BIO_ctrl'; d: {$ifndef FPC}@{$endif}@BIO_ctrl), + (n: 'BIO_gets'; d: {$ifndef FPC}@{$endif}@BIO_gets), + (n: 'BIO_puts'; d: {$ifndef FPC}@{$endif}@BIO_puts), + (n: 'BIO_f_base64'; d: {$ifndef FPC}@{$endif}@BIO_f_base64), + (n: 'BIO_s_fd'; d: {$ifndef FPC}@{$endif}@BIO_s_fd), + (n: 'BIO_s_file'; d: {$ifndef FPC}@{$endif}@BIO_s_file) + ); + funcsopt: array[0..3] of funcinfoty = ( + (n: 'BIO_set_mem_eof_return'; d: {$ifndef FPC}@{$endif}@BIO_set_mem_eof_return), + (n: 'BIO_set_mem_buf'; d: {$ifndef FPC}@{$endif}@BIO_set_mem_buf), + (n: 'BIO_get_mem_ptr'; d: {$ifndef FPC}@{$endif}@BIO_get_mem_ptr), + (n: 'BIO_new_mem_buf'; d: {$ifndef FPC}@{$endif}@BIO_new_mem_buf) + ); + +begin + getprocaddresses(info,funcs); + getprocaddresses(info,funcsopt,true); +end; + +initialization + regopensslinit(@init); +end. diff --git a/mseide-msegui/lib/common/crypto/mseopenssldes.pas b/mseide-msegui/lib/common/crypto/mseopenssldes.pas new file mode 100644 index 0000000..554dd12 --- /dev/null +++ b/mseide-msegui/lib/common/crypto/mseopenssldes.pas @@ -0,0 +1,49 @@ +{ MSEgui Copyright (c) 2007-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseopenssldes; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseopenssl,msectypes; + +type + DES_cblock = array[0..7] of Byte; + PDES_cblock = ^DES_cblock; + des_ks_struct = packed record + ks: DES_cblock; + weak_key: cint; + end; + des_key_schedule = array[0..15] of des_ks_struct; + +var + DES_set_odd_parity: procedure(Key: des_cblock); cdecl; + DES_set_key_checked: function(key: des_cblock; + schedule: des_key_schedule): cint; cdecl; + DES_ecb_encrypt: procedure(Input: des_cblock; output: des_cblock; + ks: des_key_schedule; enc: cint); cdecl; + +implementation +uses + msedynload; + +procedure init(const info: dynlibinfoty); +const + funcs: array[0..2] of funcinfoty = ( + (n: 'DES_set_odd_parity'; d: {$ifndef FPC}@{$endif}@DES_set_odd_parity), + (n: 'DES_set_key_checked'; d: {$ifndef FPC}@{$endif}@DES_set_key_checked), + (n: 'DES_ecb_encrypt'; d: {$ifndef FPC}@{$endif}@DES_ecb_encrypt) + ); +begin + getprocaddresses(info,funcs); +end; + +initialization + regopensslinit(@init); +end. diff --git a/mseide-msegui/lib/common/crypto/mseopenssldsa.pas b/mseide-msegui/lib/common/crypto/mseopenssldsa.pas new file mode 100644 index 0000000..9b02abd --- /dev/null +++ b/mseide-msegui/lib/common/crypto/mseopenssldsa.pas @@ -0,0 +1,71 @@ +{ MSEgui Copyright (c) 2007-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseopenssldsa; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseopenssl,msectypes; +type + pDSA = ^DSA; + DSA = record + // This first variable is used to pick up errors where + // a DSA is passed instead of of a EVP_PKEY + pad: cint; + version: cint; + write_params: cint; + p: pointer; + q: pointer; // = 20 + g: pointer; + pub_key: pointer; // y public key + priv_key: pointer; // x private key + kinv: pointer; // Signing pre-calc + r: pointer; // Signing pre-calc + flags: cint; + // Normally used to cache montgomery values + method_mont_p: PCharacter; + references: cint; + ex_data: record + sk: pointer; + dummy: cint; + end; + meth: pointer; + end; + +var + DSA_new: function: pDSA; cdecl; + DSA_free: procedure(r: pDSA); cdecl; + DSA_generate_parameters: function(bits: cint; seed: pointer; + seed_len: cint;var counter_ret: cint; var h_ret: culong; + progress: TProgressCallbackFunction; cb_arg: Pointer): pDSA; cdecl; + DSA_generate_key: function(a: pDSA): cint; cdecl; + d2i_DSAPrivateKey_bio: function(bp: pBIO; dsa: pDSA): pDSA; cdecl; + i2d_DSAPrivateKey_bio: function(bp: pBIO; dsa: pDSA): cint; cdecl; + +implementation +uses + msedynload; + +procedure init(const info: dynlibinfoty); +const + funcs: array[0..5] of funcinfoty = ( + (n: 'DSA_new'; d: @DSA_new), + (n: 'DSA_free'; d: @DSA_free), + (n: 'DSA_generate_parameters'; d: @DSA_generate_parameters), + (n: 'DSA_generate_key'; d: @DSA_generate_key), + (n: 'd2i_DSAPrivateKey_bio'; d: @d2i_DSAPrivateKey_bio), + (n: 'i2d_DSAPrivateKey_bio'; d: @i2d_DSAPrivateKey_bio) + ); +begin + getprocaddresses(info,funcs); +end; + +initialization + regopensslinit(@init); +end. diff --git a/mseide-msegui/lib/common/crypto/mseopensslevp.pas b/mseide-msegui/lib/common/crypto/mseopensslevp.pas new file mode 100644 index 0000000..ee80bdd --- /dev/null +++ b/mseide-msegui/lib/common/crypto/mseopensslevp.pas @@ -0,0 +1,564 @@ +{ MSEgui Copyright (c) 2007-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseopensslevp; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseopenssl,msectypes,mseopenssldes; +const + EVP_MAX_MD_SIZE = 64; //* longest known is SHA512 */ + EVP_MAX_KEY_LENGTH = 32; + EVP_MAX_IV_LENGTH = 16; + EVP_MAX_BLOCK_LENGTH = 32; + + PKCS5_SALT_LEN = 8; + PKCS5_DEFAULT_ITER = 2048; //* Default PKCS#5 iteration count */ + +//* Values for cipher flags */ + +//* Modes for ciphers */ + + EVP_CIPH_STREAM_CIPHER = $0; + EVP_CIPH_ECB_MODE = $1; + EVP_CIPH_CBC_MODE = $2; + EVP_CIPH_CFB_MODE = $3; + EVP_CIPH_OFB_MODE = $4; + EVP_CIPH_MODE = $7; +//* Set if variable length cipher */ + EVP_CIPH_VARIABLE_LENGTH = $8; +//* Set if the iv handling should be done by the cipher itself */ + EVP_CIPH_CUSTOM_IV = $10; +//* Set if the cipher's init() function should be called if key is NULL */ + EVP_CIPH_ALWAYS_CALL_INIT = $20; +//* Call ctrl() to init cipher parameters */ + EVP_CIPH_CTRL_INIT = $40; +//* Don't use standard key length function */ + EVP_CIPH_CUSTOM_KEY_LENGTH = $80; +//* Don't use standard block padding */ + EVP_CIPH_NO_PADDING = $100; +//* cipher handles random key generation */ + EVP_CIPH_RAND_KEY = $200; + +//* ctrl() values */ + + EVP_CTRL_INIT = $0; + EVP_CTRL_SET_KEY_LENGTH = $1; + EVP_CTRL_GET_RC2_KEY_BITS = $2; + EVP_CTRL_SET_RC2_KEY_BITS = $3; + EVP_CTRL_GET_RC5_ROUNDS = $4; + EVP_CTRL_SET_RC5_ROUNDS = $5; + EVP_CTRL_RAND_KEY = $6; + + +type + MD2_CTX = record + num: cint; + data: array [0..15] of byte; + cksm: array [0..15] of cardinal; + state: array [0..15] of cardinal; + end; + + MD4_CTX = record + A, B, C, D: cardinal; + Nl, Nh: cardinal; + data: array [0..15] of cardinal; + num: cint; + end; + + MD5_CTX = record + A, B, C, D: cardinal; + Nl, Nh: cardinal; + data: array [0..15] of cardinal; + num: cint; + end; + + RIPEMD160_CTX = record + A, B, C, D, E: cardinal; + Nl, Nh: cardinal; + data: array [0..15] of cardinal; + num: cint; + end; + + SHA_CTX = record + h0, h1, h2, h3, h4: cardinal; + Nl, Nh: cardinal; + data: array [0..16] of cardinal; + num: cint; + end; + + MDC2_CTX = record + num: cint; + data: array [0..7] of byte; + h, hh: des_cblock; + pad_type: cint; // either 1 or 2, default 1 + end; + + // Superfluo? No, in EVP_MD ci sono le dimensioni del risultato + pEVP_MD_CTX = ^EVP_MD_CTX; + EVP_MD_CTX = record + digest: pEVP_MD; + case integer of + 0: (base: array [0..3] of byte); + 1: (md2: MD2_CTX); + 8: (md4: MD4_CTX); + 2: (md5: MD5_CTX); + 16: (ripemd160: RIPEMD160_CTX); + 4: (sha: SHA_CTX); + 32: (mdc2: MDC2_CTX); + end; + + pEVP_PKEY = ^EVP_PKEY; + EVP_PKEY_PKEY = record + case integer of + 0: (ptr: pcuchar); + 1: (rsa: pRSA); // ^rsa_st + 2: (dsa: pDSA); // ^dsa_st + 3: (dh: pDH); // ^dh_st + end; + ppEVP_PKEY = ^pEVP_PKEY; + pSTACK_OFX509 = SslPtr; //todo + EVP_PKEY = record //for version 1.0 + _type: cint; + save_type: cint; + references: cint; + ameth: SslPtr; + engine: pENGINE; + pkey: EVP_PKEY_PKEY; + save_parameters: cint; + attributes: pSTACK_OFX509; + end; + + ASN1_TYPE = record //todo + end; + pASN1_TYPE = ^ASN1_TYPE; + + pEVP_CIPHER_CTX = ^EVP_CIPHER_CTX; + EVP_CIPHER = record + nid: cint; + block_size: cint; + key_len: cint; //* Default value for variable length ciphers */ + iv_len: cint; + flags: culong; //* Various flags */ + init: function(ctx: pEVP_CIPHER_CTX; key: pcuchar; iv: pcuchar; + enc: cint): cint; +// int (*init)(EVP_CIPHER_CTX *ctx, const unsigned char *key, +// const unsigned char *iv, int enc); /* init key */ + do_cipher: function (ctx: pEVP_CIPHER_CTX; _out: pcuchar; _in: pcuchar; + inl: cint): cint; //* encrypt/decrypt data */ +// int (*do_cipher)(EVP_CIPHER_CTX *ctx, unsigned char *out, +// const unsigned char *in, unsigned int inl);/* encrypt/decrypt data */ + cleanup: function(ctx: pEVP_CIPHER_CTX): cint; //* cleanup ctx */ +// int (*cleanup)(EVP_CIPHER_CTX *); /* cleanup ctx */ + ctx_size: cint; //* how big ctx->cipher_data needs to be */ + set_asn1_parameters: function (ctx: pEVP_CIPHER_CTX; _type: pASN1_TYPE): cint; + //* Populate a ASN1_TYPE with parameters */ +// int (*set_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Populate a ASN1_TYPE with parameters */ + get_asn1_parameters: function(ctx: pEVP_CIPHER_CTX; _type: pASN1_TYPE): cint; + //* Get parameters from a ASN1_TYPE */ +// int (*get_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Get parameters from a ASN1_TYPE */ + ctrl: function(ctx: pEVP_CIPHER_CTX; _type: cint; arg: cint; + ptr: pointer): cint; //* Miscellaneous operations */ +// int (*ctrl)(EVP_CIPHER_CTX *, int type, int arg, void *ptr); /* Miscellaneous operations */ + app_data: pointer; //* Application data */ + end; + pEVP_CIPHER = ^EVP_CIPHER; + + pEVP_MD = ^EVP_MD; + EVP_MD = record + _type: cint; + pkey_type: cint; + md_size: cint; + init: pointer; + update: pointer; + final: pointer; + sign: pointer; + verify: pointer; + required_pkey_type: array [0..4] of cint; + block_size: cint; + ctx_size: cint; + end; + ivty = array[0..EVP_MAX_IV_LENGTH-1] of byte; + pENGINE = SslPtr; + EVP_CIPHER_CTX = record + cipher: pEVP_CIPHER; + engine: pENGINE; //* functional reference if 'cipher' is ENGINE-provided */ + encrypt: cint; //* encrypt or decrypt */ + buf_len: cint; //* number we have left */ + + iov: ivty; //* original iv */ + iv: ivty; //* working iv */ + buf: array[0..EVP_MAX_BLOCK_LENGTH-1] of byte; //* saved partial block */ + num: cint; //* used by cfb/ofb mode */ + + app_data: pointer; //* application stuff */ + key_len: cint; //* May change for variable length cipher */ + flags: culong; //* Various flags */ + cipher_data: pointer; //* per EVP data */ + final_used: cint; + block_mask: cint; + final: array[0..EVP_MAX_BLOCK_LENGTH-1] of byte; + //* possible final block */ + end; +// pEVP_CIPHER_CTX = ^EVP_CIPHER_CTX; + +var + EVP_cleanup: procedure; cdecl; + EVP_CIPHER_CTX_init: procedure(ctx: pEVP_CIPHER_CTX); cdecl; + EVP_CIPHER_CTX_cleanup: function(ctx: pEVP_CIPHER_CTX): cint; cdecl; + EVP_CIPHER_CTX_set_padding: function(ctx: pEVP_CIPHER_CTX; + padding: cint): cint; cdecl; + EVP_CIPHER_CTX_set_key_length: function(ctx: pEVP_CIPHER_CTX; + keylen: cint): cint; cdecl; + EVP_get_digestbyname: function(Name: pcchar): pEVP_MD; cdecl; + EVP_get_cipherbyname: function(name: pcchar): pEVP_CIPHER; cdecl; + + EVP_CipherInit: function(ctc: pEVP_CIPHER_CTX; cipher: pEVP_CIPHER; + key: pcuchar; iv: pcuchar; enc: cint): cint; cdecl; + EVP_CipherInit_ex: function(ctx: pEVP_CIPHER_CTX; cipher: pEVP_CIPHER; + impl: pENGINE; key: pcuchar; iv: pcuchar; enc: cint): cint; cdecl; + EVP_CipherUpdate: function(ctx: pEVP_CIPHER_CTX; _out: pcuchar; + var outl: cint; _in: pcuchar; inl: cint): cint; cdecl; + EVP_CipherFinal: function(ctx: pEVP_CIPHER_CTX; outm: pcuchar; + var outl: cint): cint; cdecl; + EVP_CipherFinal_ex: function(ctx: pEVP_CIPHER_CTX; outm: pcuchar; + var outl: cint): cint; cdecl; + + EVP_EncryptInit: function(ctx: pEVP_CIPHER_CTX; _type: pEVP_CIPHER; + key: pcuchar; iv: pcuchar): cint; cdecl; + EVP_EncryptInit_ex: function(ctx: pEVP_CIPHER_CTX; _type: pEVP_CIPHER; + impl: pENGINE; key: pcuchar; iv: pcuchar): cint; cdecl; + EVP_EncryptUpdate: function(ctx: pEVP_CIPHER_CTX;_out: pcuchar; + var outl: cint; _in: pcuchar; inl: cint): cint; cdecl; + EVP_EncryptFinal: function(ctx: pEVP_CIPHER_CTX; _out: pcuchar; + var outl: cint): cint; cdecl; + EVP_EncryptFinal_ex: function(ctx: pEVP_CIPHER_CTX; _out: pcuchar; + var outl: cint): cint; cdecl; + + EVP_DecryptInit: function(ctx: pEVP_CIPHER_CTX; cipher: pEVP_CIPHER; + key: pcuchar; iv: pcuchar): cint; cdecl; + EVP_DecryptInit_ex: function(ctx: pEVP_CIPHER_CTX; cipher: pEVP_CIPHER; + impl: pENGINE; key: pcuchar; iv: pcuchar): cint; cdecl; + EVP_DecryptUpdate: function(ctx: pEVP_CIPHER_CTX; _out: pcuchar; + var outl: cint; _in: pcuchar; inl: cint): cint; cdecl; + EVP_DecryptFinal: function(ctx: pEVP_CIPHER_CTX; outm: pcuchar; + var outl: cint): cint; cdecl; + EVP_DecryptFinal_ex: function(ctx: pEVP_CIPHER_CTX; outm: pcuchar; + var outl: cint): cint; cdecl; + + EVP_DigestInit: function(ctx: pEVP_MD_CTX; const _type: pEVP_MD): cint; cdecl; + EVP_DigestInit_ex: function(ctx: pEVP_MD_CTX; const _type: pEVP_MD; + impl: pENGINE): cint; cdecl; + EVP_DigestUpdate: function(ctx: pEVP_MD_CTX; const d: Pointer; + cnt: sslsize_t): cint; cdecl; + EVP_DigestFinal: function(ctx: pEVP_MD_CTX; md: pcuchar; + var s: cuint): cint; cdecl; + EVP_DigestFinal_ex: function(ctx: pEVP_MD_CTX; md: pcuchar; + var s: cuint): cint; cdecl; + EVP_SignFinal: function(ctx: pEVP_MD_CTX; sig: pointer; + var s: cuint; key: pEVP_PKEY): cint; cdecl; + EVP_VerifyFinal: function(ctx: pEVP_MD_CTX; sigbuf: pointer; + siglen: cuint; pkey: pEVP_PKEY): cint; cdecl; + + EVP_MD_CTX_copy: function(_out: pEVP_MD_CTX; _in: pEVP_MD_CTX): cint; cdecl; + EVP_CIPHER_CTX_rand_key: function(ctx: pEVP_CIPHER_CTX; + key: pcuchar): cint; cdecl; + + // Hash functions + EVP_md_null: function: pEVP_MD; cdecl; + EVP_md2: function: pEVP_MD; cdecl; //optional! + EVP_md5: function: pEVP_MD; cdecl; + EVP_sha: function: pEVP_MD; cdecl; + EVP_sha1: function: pEVP_MD; cdecl; + EVP_dss: function: pEVP_MD; cdecl; + EVP_dss1: function: pEVP_MD; cdecl; + EVP_mdc2: function: pEVP_MD; cdecl; + EVP_ripemd160: function: pEVP_MD; cdecl; + // Crypt functions + EVP_enc_null: function: pEVP_CIPHER; cdecl; + EVP_des_ecb: function: pEVP_CIPHER; cdecl; + EVP_des_ede: function: pEVP_CIPHER; cdecl; + EVP_des_ede3: function: pEVP_CIPHER; cdecl; + {$ifndef mswindows} + EVP_des_cfb: function: pEVP_CIPHER; cdecl; + EVP_des_ede_cfb: function: pEVP_CIPHER; cdecl; + EVP_des_ede3_cfb: function: pEVP_CIPHER; cdecl; + EVP_des_ofb: function: pEVP_CIPHER; cdecl; + EVP_des_ede_ofb: function: pEVP_CIPHER; cdecl; + EVP_des_ede3_ofb: function: pEVP_CIPHER; cdecl; + EVP_des_cbc: function: pEVP_CIPHER; cdecl; + EVP_des_ede_cbc: function: pEVP_CIPHER; cdecl; + EVP_des_ede3_cbc: function: pEVP_CIPHER; cdecl; + {$endif} + EVP_desx_cbc: function: pEVP_CIPHER; cdecl; + EVP_idea_cbc: function: pEVP_CIPHER; cdecl; + EVP_idea_cfb: function: pEVP_CIPHER; cdecl; + EVP_idea_ecb: function: pEVP_CIPHER; cdecl; + EVP_idea_ofb: function: pEVP_CIPHER; cdecl; + + // EVP Key functions + EVP_PKEY_New: function(): pEVP_PKEY; cdecl; + EVP_PKEY_Free: procedure(pk: pEVP_PKEY); cdecl; + EVP_PKEY_Assign: function(pkey: pEVP_PKEY; _type: cint; + key: pRSA): cint; cdecl; + EVP_PKEY_type: function(keytype: cint): cint; cdecl; + EVP_PKEY_assign_RSA: function(key: pEVP_PKEY; rsa: pRSA): cint; cdecl; + EVP_PKEY_assign_DSA: function(key: pEVP_PKEY; dsa: pDSA): cint; cdecl; + EVP_PKEY_assign_DH: function(key: pEVP_PKEY; dh: pDH): cint; cdecl; + EVP_PKEY_assign_EC_KEY: function(key: pEVP_PKEY; ec: pEC_KEY): cint; cdecl; + EVP_PKEY_set1_RSA: function(key: pEVP_PKEY; rsa: pRSA): cint; cdecl; + EVP_PKEY_set1_DSA: function(key: pEVP_PKEY; dsa: pDSA): cint; cdecl; + EVP_PKEY_set1_DH: function(key: pEVP_PKEY; dh: pDH): cint; cdecl; + EVP_PKEY_set1_EC_KEY: function(key: pEVP_PKEY; ec: pEC_KEY): cint; cdecl; + EVP_PKEY_size: function(key: pEVP_PKEY): cint; cdecl; + EVP_PKEY_get1_RSA: function(key: pEVP_PKEY): pRSA; cdecl; + EVP_PKEY_get1_DSA: function(key: pEVP_PKEY): pDSA; cdecl; + EVP_PKEY_get1_DH: function(key: pEVP_PKEY): pDH; cdecl; + EVP_PKEY_get1_EC_KEY: function(key: pEVP_PKEY): pEC_KEY; cdecl; + // Password prompt for callback function + EVP_set_pw_prompt: procedure(prompt: pcchar);cdecl; + EVP_get_pw_prompt: function: pcchar;cdecl; + // Default callback password function: replace if you want + EVP_read_pw_string: function(buf: pcchar; len: cint; + const prompt: pcchar; verify: cint): cint; cdecl; + EVP_read_pw_string_min: function(buf: pcchar; minlen: cint; maxlen: cint; + prompt: pcchar; verify: cint): cint; cdecl; //openssl 1.0+ + d2i_PrivateKey_bio: function(bp: pBIO; var a: pEVP_PKEY): pEVP_PKEY; cdecl; + d2i_PUBKEY_bio: function(bp: pBIO; var a: pEVP_PKEY): pEVP_PKEY; cdecl; + i2d_PUBKEY_bio: function(bp: pBIO; pkey: pEVP_PKEY): cint; cdecl; + + EVP_MD_type: function(const md: pEVP_MD): cint; cdecl; + EVP_MD_pkey_type: function(const md: pEVP_MD): cint; cdecl; + EVP_MD_block_size: function(const md: pEVP_MD): cint; cdecl; + EVP_MD_flags: function(const md: pEVP_MD): cardinal; cdecl; //openssl 1.0 + + EVP_MD_CTX_md: function(const ctx: pEVP_MD_CTX): pEVP_MD;cdecl; + + EVP_MD_CTX_init: procedure(ctx: pEVP_MD_CTX);cdecl; + EVP_MD_CTX_cleanup: function(ctx: pEVP_MD_CTX): cint;cdecl; + EVP_MD_CTX_create: function: pEVP_MD_CTX;cdecl; + EVP_MD_CTX_destroy: procedure(ctx: pEVP_MD_CTX);cdecl; + + EVP_BytesToKey: function(const _type: pEVP_CIPHER; const md: pEVP_MD; + salt: pcuchar; const data: pcuchar; datalen: cint; + count: cint; key: pcuchar; iv: pcuchar): cint; cdecl; + EVP_SealInit: function(ctx: pEVP_CIPHER_CTX; _type: pEVP_CIPHER; + ek: ppcuchar; ekl: pcint; iv: pcuchar; + pubkey: ppEVP_PKEY; npubk: cint): cint; cdecl; + EVP_SealFinal: function(ctx: pEVP_CIPHER_CTX; _out: pcuchar; + var outl: cint): cint; cdecl; + EVP_OpenInit: function(ctx: pEVP_CIPHER_CTX;_type: pEVP_CIPHER; + ek: pcuchar; ekl: cint; iv: pcuchar; + priv: pEVP_PKEY): cint; cdecl; + EVP_OpenFinal: function(ctx: pEVP_CIPHER_CTX; _out: pcuchar; + var outl: cint): cint; cdecl; + +function EVP_SealUpdate(ctx: pEVP_CIPHER_CTX; _out: pcuchar; + var outl: cint; _in: pcuchar; inl: cint): cint; +function EVP_OpenUpdate(ctx: pEVP_CIPHER_CTX; _out: pcuchar; + var outl: cint; _in: pcuchar; inl: cint): cint; +function EVP_SignInit(ctx: pEVP_MD_CTX; const _type: pEVP_MD): cint; +function EVP_SignUpdate(ctx: pEVP_MD_CTX; const d: Pointer; cnt: cuint): cint; +function EVP_VerifyInit(ctx: pEVP_MD_CTX; const _type: pEVP_MD): cint; +function EVP_VerifyUpdate(ctx: pEVP_MD_CTX; const d: Pointer; cnt: cuint): cint; +function EVP_MD_size(e: pEVP_MD): cint; +function EVP_MD_CTX_size(e: pEVP_MD_CTX): cint; + +function encryptsymkeyrsa(ek: pcuchar; key: pcuchar; key_len: integer; + pubk: pEVP_PKEY): integer; + //like EVP_PKEY_encrypt_old(), -2 if no rsa key, -1 on error +function decryptsymkeyrsa(key: pcuchar; ek: pcuchar; ekl: integer; + priv: pEVP_PKEY): integer; + //like EVP_PKEY_decrypt_old(), -2 if no rsa key, -1 on error + +implementation +uses + msedynload,mseopensslrsa; + +function encryptsymkeyrsa(ek: pcuchar; key: pcuchar; key_len: cint; + pubk: pEVP_PKEY): cint; +begin + result:= -2; + if pubk^._type = EVP_PKEY_RSA then begin + result:= RSA_public_encrypt(key_len,key,ek,EVP_PKEY_get1_RSA(pubk), + RSA_PKCS1_OAEP_PADDING{RSA_PKCS1_PADDING}); + end; +end; + +function decryptsymkeyrsa(key: pcuchar; ek: pcuchar; ekl: integer; + priv: pEVP_PKEY): integer; +begin + result:= -2; + if priv^._type = EVP_PKEY_RSA then begin + result:= RSA_private_decrypt(ekl,ek,key,EVP_PKEY_get1_RSA(priv), + RSA_PKCS1_OAEP_PADDING{RSA_PKCS1_PADDING}); + end; +end; + +function EVP_SealUpdate(ctx: pEVP_CIPHER_CTX; _out: pcuchar; + var outl: cint; _in: pcuchar; inl: cint): cint; +begin + result:= evp_encryptupdate(ctx,_out,outl,_in,inl); +end; + +function EVP_OpenUpdate(ctx: pEVP_CIPHER_CTX; _out: pcuchar; + var outl: cint; _in: pcuchar; inl: cint): cint; +begin + result:= evp_decryptupdate(ctx,_out,outl,_in,inl); +end; + +function EVP_SignInit(ctx: pEVP_MD_CTX; const _type: pEVP_MD): cint; +begin + result:= EVP_DigestInit(ctx, _type); +end; + +function EVP_SignUpdate(ctx: pEVP_MD_CTX; const d: Pointer; cnt: cardinal): cint; +begin + result:= EVP_DigestUpdate(ctx, d, cnt); +end; + +function EVP_VerifyInit(ctx: pEVP_MD_CTX; const _type: pEVP_MD): cint; +begin + result:= EVP_DigestInit(ctx, _type); +end; + +function EVP_VerifyUpdate(ctx: pEVP_MD_CTX; const d: Pointer; cnt: cardinal): cint; +begin + result:= EVP_DigestUpdate(ctx, d, cnt); +end; + +function EVP_MD_size(e: pEVP_MD): cint; +begin + result := e^.md_size; +end; + +function EVP_MD_CTX_size(e: pEVP_MD_CTX): cint; +begin + result := EVP_MD_size(e^.digest); +end; + +procedure init(const info: dynlibinfoty); +const + funcs: array[0.. {$ifndef mswindows}83{$else}74{$endif}] of funcinfoty = ( + (n: 'EVP_PKEY_new'; d: {$ifndef FPC}@{$endif}@EVP_PKEY_new), + (n: 'EVP_PKEY_free'; d: {$ifndef FPC}@{$endif}@EVP_PKEY_free), + (n: 'EVP_PKEY_assign'; d: {$ifndef FPC}@{$endif}@EVP_PKEY_assign), + (n: 'EVP_CIPHER_CTX_init'; d: {$ifndef FPC}@{$endif}@EVP_CIPHER_CTX_init), + (n: 'EVP_CIPHER_CTX_cleanup'; d: {$ifndef FPC}@{$endif}@EVP_CIPHER_CTX_cleanup), + (n: 'EVP_CIPHER_CTX_set_padding'; d: {$ifndef FPC}@{$endif}@EVP_CIPHER_CTX_set_padding), + (n: 'EVP_CIPHER_CTX_set_key_length'; d: {$ifndef FPC}@{$endif}@EVP_CIPHER_CTX_set_key_length), + (n: 'EVP_cleanup'; d: {$ifndef FPC}@{$endif}@EVP_cleanup), + (n: 'EVP_get_digestbyname'; d: {$ifndef FPC}@{$endif}@EVP_get_digestbyname), + (n: 'EVP_md_null'; d: {$ifndef FPC}@{$endif}@EVP_md_null), + (n: 'EVP_md5'; d: {$ifndef FPC}@{$endif}@EVP_md5), + (n: 'EVP_sha'; d: {$ifndef FPC}@{$endif}@EVP_sha), + (n: 'EVP_sha1'; d: {$ifndef FPC}@{$endif}@EVP_sha1), + (n: 'EVP_dss'; d: {$ifndef FPC}@{$endif}@EVP_dss), + (n: 'EVP_dss1'; d: {$ifndef FPC}@{$endif}@EVP_dss1), + (n: 'EVP_ripemd160'; d: {$ifndef FPC}@{$endif}@EVP_ripemd160), + (n: 'EVP_CipherInit'; d: {$ifndef FPC}@{$endif}@EVP_CipherInit), + (n: 'EVP_CipherInit_ex'; d: {$ifndef FPC}@{$endif}@EVP_CipherInit_ex), + (n: 'EVP_CipherUpdate'; d: {$ifndef FPC}@{$endif}@EVP_CipherUpdate), + (n: 'EVP_CipherFinal'; d: {$ifndef FPC}@{$endif}@EVP_CipherFinal), + (n: 'EVP_CipherFinal_ex'; d: {$ifndef FPC}@{$endif}@EVP_CipherFinal_ex), + (n: 'EVP_EncryptInit'; d: {$ifndef FPC}@{$endif}@EVP_EncryptInit), + (n: 'EVP_EncryptInit_ex'; d: {$ifndef FPC}@{$endif}@EVP_EncryptInit_ex), + (n: 'EVP_EncryptUpdate'; d: {$ifndef FPC}@{$endif}@EVP_EncryptUpdate), + (n: 'EVP_EncryptFinal'; d: {$ifndef FPC}@{$endif}@EVP_EncryptFinal), + (n: 'EVP_EncryptFinal_ex'; d: {$ifndef FPC}@{$endif}@EVP_EncryptFinal_ex), + (n: 'EVP_DecryptInit'; d: {$ifndef FPC}@{$endif}@EVP_DecryptInit), + (n: 'EVP_DecryptInit_ex'; d: {$ifndef FPC}@{$endif}@EVP_DecryptInit_ex), + (n: 'EVP_DecryptUpdate'; d: {$ifndef FPC}@{$endif}@EVP_DecryptUpdate), + (n: 'EVP_DecryptFinal'; d: {$ifndef FPC}@{$endif}@EVP_DecryptFinal), + (n: 'EVP_DecryptFinal_ex'; d: {$ifndef FPC}@{$endif}@EVP_DecryptFinal_ex), + (n: 'EVP_DigestInit'; d: {$ifndef FPC}@{$endif}@EVP_DigestInit), + (n: 'EVP_DigestInit_ex'; d: {$ifndef FPC}@{$endif}@EVP_DigestInit_ex), + (n: 'EVP_DigestUpdate'; d: {$ifndef FPC}@{$endif}@EVP_DigestUpdate), + (n: 'EVP_DigestFinal'; d: {$ifndef FPC}@{$endif}@EVP_DigestFinal), + (n: 'EVP_DigestFinal_ex'; d: {$ifndef FPC}@{$endif}@EVP_DigestFinal_ex), + (n: 'EVP_SignFinal'; d: {$ifndef FPC}@{$endif}@EVP_SignFinal), + (n: 'EVP_VerifyFinal'; d: {$ifndef FPC}@{$endif}@EVP_VerifyFinal), + (n: 'EVP_MD_CTX_copy'; d: {$ifndef FPC}@{$endif}@EVP_MD_CTX_copy), + (n: 'EVP_enc_null'; d: {$ifndef FPC}@{$endif}@EVP_enc_null), + (n: 'EVP_des_ecb'; d: {$ifndef FPC}@{$endif}@EVP_des_ecb), + (n: 'EVP_des_ede'; d: {$ifndef FPC}@{$endif}@EVP_des_ede), + (n: 'EVP_des_ede3'; d: {$ifndef FPC}@{$endif}@EVP_des_ede3), + {$ifndef mswindows} + (n: 'EVP_des_cfb'; d: {$ifndef FPC}@{$endif}@EVP_des_cfb), + (n: 'EVP_des_ede_cfb'; d: {$ifndef FPC}@{$endif}@EVP_des_ede_cfb), + (n: 'EVP_des_ede3_cfb'; d: {$ifndef FPC}@{$endif}@EVP_des_ede3_cfb), + (n: 'EVP_des_ofb'; d: {$ifndef FPC}@{$endif}@EVP_des_ofb), + (n: 'EVP_des_ede_ofb'; d: {$ifndef FPC}@{$endif}@EVP_des_ede_ofb), + (n: 'EVP_des_ede3_ofb'; d: {$ifndef FPC}@{$endif}@EVP_des_ede3_ofb), + (n: 'EVP_des_cbc'; d: {$ifndef FPC}@{$endif}@EVP_des_cbc), + (n: 'EVP_des_ede_cbc'; d: {$ifndef FPC}@{$endif}@EVP_des_ede_cbc), + (n: 'EVP_des_ede3_cbc'; d: {$ifndef FPC}@{$endif}@EVP_des_ede3_cbc), + {$endif} + (n: 'EVP_desx_cbc'; d: {$ifndef FPC}@{$endif}@EVP_desx_cbc), + (n: 'EVP_get_cipherbyname'; d: {$ifndef FPC}@{$endif}@EVP_get_cipherbyname), + (n: 'EVP_PKEY_type'; d: {$ifndef FPC}@{$endif}@EVP_PKEY_type), + (n: 'EVP_PKEY_set1_RSA'; d: {$ifndef FPC}@{$endif}@EVP_PKEY_set1_RSA), + (n: 'EVP_PKEY_set1_DSA'; d: {$ifndef FPC}@{$endif}@EVP_PKEY_set1_DSA), + (n: 'EVP_PKEY_set1_DH'; d: {$ifndef FPC}@{$endif}@EVP_PKEY_set1_DH), + (n: 'EVP_PKEY_set1_EC_KEY'; d: {$ifndef FPC}@{$endif}@EVP_PKEY_set1_EC_KEY), + (n: 'EVP_PKEY_size'; d: {$ifndef FPC}@{$endif}@EVP_PKEY_size), + (n: 'EVP_PKEY_get1_RSA'; d: {$ifndef FPC}@{$endif}@EVP_PKEY_get1_RSA), + (n: 'EVP_PKEY_get1_DSA'; d: {$ifndef FPC}@{$endif}@EVP_PKEY_get1_DSA), + (n: 'EVP_PKEY_get1_DH'; d: {$ifndef FPC}@{$endif}@EVP_PKEY_get1_DH), + (n: 'EVP_PKEY_get1_EC_KEY'; d: {$ifndef FPC}@{$endif}@EVP_PKEY_get1_EC_KEY), + (n: 'EVP_set_pw_prompt'; d: {$ifndef FPC}@{$endif}@EVP_set_pw_prompt), + (n: 'EVP_get_pw_prompt'; d: {$ifndef FPC}@{$endif}@EVP_get_pw_prompt), + (n: 'EVP_read_pw_string'; d: {$ifndef FPC}@{$endif}@EVP_read_pw_string), + (n: 'd2i_PrivateKey_bio'; d: {$ifndef FPC}@{$endif}@d2i_PrivateKey_bio), + (n: 'd2i_PUBKEY_bio'; d: {$ifndef FPC}@{$endif}@d2i_PUBKEY_bio), + (n: 'i2d_PUBKEY_bio'; d: {$ifndef FPC}@{$endif}@i2d_PUBKEY_bio), + (n: 'EVP_MD_type'; d: {$ifndef FPC}@{$endif}@EVP_MD_type), + (n: 'EVP_MD_pkey_type'; d: {$ifndef FPC}@{$endif}@EVP_MD_pkey_type), + (n: 'EVP_MD_block_size'; d: {$ifndef FPC}@{$endif}@EVP_MD_block_size), + (n: 'EVP_MD_CTX_md'; d: {$ifndef FPC}@{$endif}@EVP_MD_CTX_md), + (n: 'EVP_MD_CTX_init'; d: {$ifndef FPC}@{$endif}@EVP_MD_CTX_init), + (n: 'EVP_MD_CTX_cleanup'; d: {$ifndef FPC}@{$endif}@EVP_MD_CTX_cleanup), + (n: 'EVP_MD_CTX_create'; d: {$ifndef FPC}@{$endif}@EVP_MD_CTX_create), + (n: 'EVP_MD_CTX_destroy'; d: {$ifndef FPC}@{$endif}@EVP_MD_CTX_destroy), + (n: 'EVP_BytesToKey'; d: {$ifndef FPC}@{$endif}@EVP_BytesToKey), + (n: 'EVP_SealInit'; d: {$ifndef FPC}@{$endif}@EVP_SealInit), +// (n: 'EVP_SealUpdate'; d: {$ifndef FPC}@{$endif}@EVP_SealUpdate), //macro + (n: 'EVP_SealFinal'; d: {$ifndef FPC}@{$endif}@EVP_SealFinal), + (n: 'EVP_OpenInit'; d: {$ifndef FPC}@{$endif}@EVP_OpenInit), + (n: 'EVP_OpenFinal'; d: {$ifndef FPC}@{$endif}@EVP_OpenFinal), + (n: 'EVP_CIPHER_CTX_rand_key'; d: {$ifndef FPC}@{$endif}@EVP_CIPHER_CTX_rand_key) +// (n: 'EVP_PKEY_encrypt_old'; d: {$ifndef FPC}@{$endif}@EVP_PKEY_encrypt_old) //version dependent + ); + funcsopt: array[0..10] of funcinfoty = ( + (n: 'EVP_MD_flags'; d: {$ifndef FPC}@{$endif}@EVP_MD_flags), + (n: 'EVP_read_pw_string_min'; d: {$ifndef FPC}@{$endif}@EVP_read_pw_string_min), + (n: 'EVP_md2'; d: {$ifndef FPC}@{$endif}@EVP_md2), + (n: 'EVP_mdc2'; d: {$ifndef FPC}@{$endif}@EVP_mdc2), + (n: 'EVP_idea_cbc'; d: {$ifndef FPC}@{$endif}@EVP_idea_cbc), + (n: 'EVP_idea_ecb'; d: {$ifndef FPC}@{$endif}@EVP_idea_ecb), + (n: 'EVP_idea_ofb'; d: {$ifndef FPC}@{$endif}@EVP_idea_ofb), + (n: 'EVP_PKEY_assign_RSA'; d: {$ifndef FPC}@{$endif}@EVP_PKEY_assign_RSA), //todo: macros + (n: 'EVP_PKEY_assign_DSA'; d: {$ifndef FPC}@{$endif}@EVP_PKEY_assign_DSA), + (n: 'EVP_PKEY_assign_DH'; d: {$ifndef FPC}@{$endif}@EVP_PKEY_assign_DH), + (n: 'EVP_PKEY_assign_EC_KEY'; d: {$ifndef FPC}@{$endif}@EVP_PKEY_assign_EC_KEY) + ); + +begin + getprocaddresses(info,funcs); + getprocaddresses(info,funcsopt,true); +end; + +procedure deinit(const info: dynlibinfoty); +begin + evp_cleanup; +end; + +initialization + regopensslinit(@init); + regopenssldeinit(@deinit); +end. diff --git a/mseide-msegui/lib/common/crypto/mseopensslpem.pas b/mseide-msegui/lib/common/crypto/mseopensslpem.pas new file mode 100644 index 0000000..a258249 --- /dev/null +++ b/mseide-msegui/lib/common/crypto/mseopensslpem.pas @@ -0,0 +1,85 @@ +{ MSEgui Copyright (c) 2007-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseopensslpem; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseopenssl,msectypes; +var +// PEM functions + PEM_read_bio_RSAPrivateKey: function(bp: pBIO; + x: ppRSA;cb: TPWCallbackFunction; u: pointer): pRSA; cdecl; + PEM_write_bio_RSAPrivateKey: function(bp: pBIO; x: pRSA; + const enc: pEVP_CIPHER; kstr: PCharacter; klen: cint; + cb: TPWCallbackFunction; u: pointer): cint; cdecl; + PEM_read_bio_RSAPublicKey: function(bp: pBIO; x: ppRSA; + cb: TPWCallbackFunction; u: pointer): pRSA; cdecl; + PEM_write_bio_RSAPublicKey: function(bp: pBIO; x: pRSA): cint; cdecl; + PEM_read_bio_DSAPrivateKey: function(bp: pBIO; dsa: ppDSA; + cb: TPWCallbackFunction; data: pointer): pDSA; cdecl; + PEM_write_bio_DSAPrivateKey: function(bp: pBIO; dsa: pDSA; + const enc: pEVP_CIPHER; kstr: PCharacter; klen: cint; + cb: TPWCallbackFunction; data: pointer): cint; cdecl; + PEM_read_bio_PUBKEY: function(bp: pBIO; x: ppEVP_PKEY; + cb: TPWCallbackFunction; u: pointer): pEVP_PKEY; cdecl; + PEM_write_bio_PUBKEY: function(bp: pBIO; x: pEVP_PKEY): cint; cdecl; + PEM_read_bio_X509: function(bp: pBIO; x: ppX509; cb: TPWCallbackFunction; + u: pointer): pX509; cdecl; + PEM_write_bio_X509: function(bp: pBIO; x: pX509): cint; cdecl; + PEM_read_bio_X509_AUX: function(bp: pBIO; x: ppX509; + cb: TPWCallbackFunction; u: pointer): pX509; cdecl; + PEM_write_bio_X509_AUX: function(bp: pBIO; x: pX509): cint; cdecl; + PEM_read_bio_X509_REQ: function(bp: pBIO; x: ppX509_REQ; + cb: TPWCallbackFunction; u: pointer): pX509_REQ; cdecl; + PEM_write_bio_X509_REQ: function(bp: pBIO; x: pX509_REQ): cint; cdecl; + PEM_read_bio_X509_CRL: function(bp: pBIO; x: ppX509_CRL; + cb: TPWCallbackFunction; u: pointer): pX509_CRL; cdecl; + PEM_write_bio_X509_CRL: function(bp: pBIO; x: pX509_CRL): cint; cdecl; + PEM_read_bio_PrivateKey: function(bp: pBIO; x: ppEVP_PKEY; + cb: TPWCallbackFunction; u: pointer): pEVP_PKEY; cdecl; + PEM_write_bio_PrivateKey: function(bp: pBIO; x: pEVP_PKEY; + const enc: pEVP_CIPHER; kstr: PCharacter; klen: cint; + cb: TPWCallbackFunction; u: pointer): cint; cdecl; + PEM_write_bio_PKCS7: function(bp: pBIO; x: pPKCS7): cint; cdecl; + +implementation +uses + msedynload; + +procedure init(const info: dynlibinfoty); +const + funcs: array[0..18] of funcinfoty = ( + (n: 'PEM_read_bio_RSAPrivateKey'; d: {$ifndef FPC}@{$endif}@PEM_read_bio_RSAPrivateKey), + (n: 'PEM_write_bio_RSAPrivateKey'; d: {$ifndef FPC}@{$endif}@PEM_write_bio_RSAPrivateKey), + (n: 'PEM_read_bio_RSAPublicKey'; d: {$ifndef FPC}@{$endif}@PEM_read_bio_RSAPublicKey), + (n: 'PEM_write_bio_RSAPublicKey'; d: {$ifndef FPC}@{$endif}@PEM_write_bio_RSAPublicKey), + (n: 'PEM_read_bio_DSAPrivateKey'; d: {$ifndef FPC}@{$endif}@PEM_read_bio_DSAPrivateKey), + (n: 'PEM_write_bio_DSAPrivateKey'; d: {$ifndef FPC}@{$endif}@PEM_write_bio_DSAPrivateKey), + (n: 'PEM_read_bio_PUBKEY'; d: {$ifndef FPC}@{$endif}@PEM_read_bio_PUBKEY), + (n: 'PEM_write_bio_PUBKEY'; d: {$ifndef FPC}@{$endif}@PEM_write_bio_PUBKEY), + (n: 'PEM_read_bio_X509'; d: {$ifndef FPC}@{$endif}@PEM_read_bio_X509), + (n: 'PEM_write_bio_X509'; d: {$ifndef FPC}@{$endif}@PEM_write_bio_X509), + (n: 'PEM_read_bio_X509_AUX'; d: {$ifndef FPC}@{$endif}@PEM_read_bio_X509_AUX), + (n: 'PEM_write_bio_X509_AUX'; d: {$ifndef FPC}@{$endif}@PEM_write_bio_X509_AUX), + (n: 'PEM_read_bio_X509_REQ'; d: {$ifndef FPC}@{$endif}@PEM_read_bio_X509_REQ), + (n: 'PEM_write_bio_X509_REQ'; d: {$ifndef FPC}@{$endif}@PEM_write_bio_X509_REQ), + (n: 'PEM_read_bio_X509_CRL'; d: {$ifndef FPC}@{$endif}@PEM_read_bio_X509_CRL), + (n: 'PEM_write_bio_X509_CRL'; d: {$ifndef FPC}@{$endif}@PEM_write_bio_X509_CRL), + (n: 'PEM_read_bio_PrivateKey'; d: {$ifndef FPC}@{$endif}@PEM_read_bio_PrivateKey), + (n: 'PEM_write_bio_PrivateKey'; d: {$ifndef FPC}@{$endif}@PEM_write_bio_PrivateKey), + (n: 'PEM_write_bio_PKCS7'; d: {$ifndef FPC}@{$endif}@PEM_write_bio_PKCS7) + ); +begin + getprocaddresses(info,funcs); +end; + +initialization + regopensslinit(@init); +end. diff --git a/mseide-msegui/lib/common/crypto/mseopensslpkcs.pas b/mseide-msegui/lib/common/crypto/mseopensslpkcs.pas new file mode 100644 index 0000000..c6963f3 --- /dev/null +++ b/mseide-msegui/lib/common/crypto/mseopensslpkcs.pas @@ -0,0 +1,173 @@ +{ MSEgui Copyright (c) 2007-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseopensslpkcs; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseopenssl,msectypes; + +type + + pSTACK_OFPKCS7_SIGNER_INFO = pointer; + + pPKCS7_signed = ^PKCS7_signed; + PKCS7_signed = record + version: pASN1_cint; + md_algs: pointer; // ^STACK_OF(X509_ALGOR) + cert: pointer; // ^STACK_OF(X509) + crl: pointer; // ^STACK_OF(X509_CRL) + signer_info: pSTACK_OFPKCS7_SIGNER_INFO; + contents: pointer; // ^struct pkcs7_st + end; + + pPKCS7_signedandenveloped = ^PKCS7_signedandenveloped; + PKCS7_signedandenveloped = record + version: pASN1_cint; + md_algs: pointer; // ^STACK_OF(X509_ALGOR) + cert: pointer; // ^STACK_OF(X509) + crl: pointer; // ^STACK_OF(X509_CRL) + signer_info: pSTACK_OFPKCS7_SIGNER_INFO; + enc_data: pointer; // ^PKCS7_ENC_CONTENT + recipientinfo: pointer; // ^STACK_OF(PKCS7_RECIP_INFO) + end; + + pPKCS7 = ^PKCS7; + PKCS7 = record + asn1: PCharacter; + length: cint; + state: cint; + detached: cint; + asn1_type: pointer; // ^ASN1_OBJECT + case integer of + 0: (ptr: pASN1_OCTET_STRING); + 1: (data: pointer); // ^PKCS7_SIGNED + 2: (sign: pPKCS7_signed); // ^PKCS7_SIGNED + 3: (enveloped: pointer); // ^PKCS7_ENVELOPE + 4: (signed_and_enveloped: pPKCS7_signedandenveloped); + 5: (digest: pointer); // ^PKCS7_DIGEST + 6: (encrypted: pointer); // ^PKCS7_ENCRYPT + 7: (other: pointer); // ^ASN1_TYPE + end; + + pPKCS12 = ^PKCS12; + PKCS12 = record + version: pointer; + mac: pointer; + authsafes: pPKCS7; + end; + + pPKCS8_Priv_Key_Info = ^PKCS8_Priv_Key_Info; + PKCS8_Priv_Key_Info = record + broken: cint; // Flag for various broken formats */ + version: pASN1_INTEGER; + pkeyalg: Pointer; // X509_ALGOR *pkeyalg; + pkey: Pointer; // ASN1_TYPE *pkey; /* Should be OCTET STRING but some are broken */ + attributes: Pointer; // STACK_OF(X509_ATTRIBUTE) *attributes; + end; + +var +// PKCS#5 functions + PKCS5_PBKDF2_HMAC_SHA1: function(pass: PCharacter; passlen: cint; + salt: pointer; saltlen: cint; iter: cint; + keylen: cint; u: pointer): cint; cdecl; +// PKCS#7 functions + PKCS7_sign: function(signcert: pX509; pkey: pEVP_PKEY; certs: pointer; + data: pBIO; flags: cint): pPKCS7; cdecl; + PKCS7_get_signer_info: function(p7: pPKCS7): pSTACK_OFPKCS7_SIGNER_INFO; cdecl; + PKCS7_verify: function(p7: pPKCS7; certs: pointer; store: pSTACK_OFX509; + indata: pBIO; _out: pBIO; flags: cint): cint; cdecl; + PKCS7_get0_signers: function(p7: pPKCS7; certs: pSTACK_OFX509; + flags: cint): pSTACK_OFX509; cdecl; + PKCS7_signatureVerify: function(bio: pBIO; p7: pPKCS7; si: pPKCS7_SIGNER_INFO; + x509: pX509): cint; cdecl; + PKCS7_encrypt: function(certs: pSTACK_OFX509; _in: pBIO; + cipher: pEVP_CIPHER; flags: cint): pPKCS7; cdecl; + PKCS7_decrypt: function(p7: pPKCS7; pkey: pEVP_PKEY; cert: pX509; + data: pBIO; flags: cint): cint; cdecl; + PKCS7_free: procedure(p7: pPKCS7); cdecl; + PKCS7_ctrl: function(p7: pPKCS7; cmd: cint; larg: clong; + parg: PCharacter): clong; cdecl; + PKCS7_dataInit: function(p7: pPKCS7; bio: pBIO): pBIO; cdecl; +// PKCS#7 DER/PEM to internal conversion function +{ + d2i_PKCS7_DIGEST @737 + d2i_PKCS7_ENCRYPT @738 + d2i_PKCS7_ENC_CONTENT @739 + d2i_PKCS7_ENVELOPE @740 + d2i_PKCS7_ISSUER_AND_SERIAL @741 + d2i_PKCS7_RECIP_INFO @742 + d2i_PKCS7_SIGNED @743 + d2i_PKCS7_SIGNER_INFO @744 + d2i_PKCS7_SIGN_ENVELOPE @745 } + EVP_PKCS82PKEY: function(p8 : pPKCS8_Priv_Key_Info) : pEVP_PKEY; cdecl; + PKCS8_decrypt: function(p8: pX509_SIG; + Pass: PCharacter; PassLen: cint): pPKCS8_Priv_Key_Info; cdecl; + PKCS8_PRIV_KEY_INFO_free: procedure(var a: pPKCS8_Priv_Key_Info); cdecl; + PKCS12_new: function: pPKCS12; cdecl; + PEM_read_bio_PKCS7: function(bp: pBIO; data: pointer; + cb: TPWCallbackFunction; u: pointer): pPKCS7; cdecl; + PKCS12_parse: function(p12: SslPtr; pass: pchar; pkey, + cert, ca: pSslPtr): cint; cdecl; + PKCS12_free: procedure(p12: SslPtr); cdecl; + i2d_PKCS12_bio: function(bp: pBIO; pkcs12: pPKCS12): cint; cdecl; + d2i_PKCS7: function(var a: pPKCS7; pp: pointer; + length: clong): pPKCS7; cdecl; + d2i_PKCS7_bio: function(bp: pBIO; p7: pPKCS7): pPKCS7; cdecl; + i2d_PKCS7_bio: function(bp: pBIO; p7: pPKCS7): cint; cdecl; + d2i_PKCS8_bio: function(bp: pBIO; p8: pX509_SIG): pX509_SIG; cdecl; + d2i_PKCS8_PRIV_KEY_INFO: function(var a: pPKCS8_Priv_Key_Info; pp: PCharacter; + Length: clong): pPKCS8_Priv_Key_Info; cdecl; + +function PKCS7_get_detached(p7: pPKCS7): pointer; + +implementation +uses + msedynload; + +function PKCS7_get_detached(p7: pPKCS7): pointer; +begin + result := pointer(PKCS7_ctrl(p7, 2, 0, nil)); +end; + +procedure init(const info: dynlibinfoty); +const + funcs: array[0..23] of funcinfoty = ( + (n: 'PKCS5_PBKDF2_HMAC_SHA1'; d: @PKCS5_PBKDF2_HMAC_SHA1), + (n: 'PKCS7_sign'; d: @PKCS7_sign), + (n: 'PKCS7_get_signer_info'; d: @PKCS7_get_signer_info), + (n: 'PKCS7_verify'; d: @PKCS7_verify), + (n: 'PKCS7_get0_signers'; d: @PKCS7_get0_signers), + (n: 'PKCS7_signatureVerify'; d: @PKCS7_signatureVerify), + (n: 'PKCS7_encrypt'; d: @PKCS7_encrypt), + (n: 'PKCS7_decrypt'; d: @PKCS7_decrypt), + (n: 'PKCS7_free'; d: @PKCS7_free), + (n: 'PKCS7_ctrl'; d: @PKCS7_ctrl), + (n: 'PKCS7_dataInit'; d: @PKCS7_dataInit), + (n: 'EVP_PKCS82PKEY'; d: @EVP_PKCS82PKEY), + (n: 'PKCS8_decrypt'; d: @PKCS8_decrypt), + (n: 'PKCS8_PRIV_KEY_INFO_free'; d: @PKCS8_PRIV_KEY_INFO_free), + (n: 'PKCS12_new'; d: @PKCS12_new), + (n: 'PEM_read_bio_PKCS7'; d: @PEM_read_bio_PKCS7), + (n: 'PKCS12_parse'; d: @PKCS12_parse), + (n: 'PKCS12_free'; d: @PKCS12_free), + (n: 'i2d_PKCS12_bio'; d: @i2d_PKCS12_bio), + (n: 'd2i_PKCS7'; d: @d2i_PKCS7), + (n: 'd2i_PKCS7_bio'; d: @d2i_PKCS7_bio), + (n: 'i2d_PKCS7_bio'; d: @i2d_PKCS7_bio), + (n: 'd2i_PKCS8_bio'; d: @d2i_PKCS8_bio), + (n: 'd2i_PKCS8_PRIV_KEY_INFO'; d: @d2i_PKCS8_PRIV_KEY_INFO) + ); +begin + getprocaddresses(info,funcs); +end; + +initialization + regopensslinit(@init); +end. diff --git a/mseide-msegui/lib/common/crypto/mseopensslrand.pas b/mseide-msegui/lib/common/crypto/mseopensslrand.pas new file mode 100644 index 0000000..b7ce1fe --- /dev/null +++ b/mseide-msegui/lib/common/crypto/mseopensslrand.pas @@ -0,0 +1,67 @@ +{ MSEgui Copyright (c) 2007-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseopensslrand; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseopenssl,msectypes; + +var + // pseudo-random number generator (PRNG) functions + RAND_seed: procedure(const buf: pointer; num: cint); cdecl; + RAND_add: procedure(const buf: pointer; num: cint; entropy: double); cdecl; + RAND_status: function: cint; cdecl; + // RAND_event: function(UINT iMsg, WPARAM wParam, LPARAM lParam): cint; cdecl; + RAND_file_name: function(buf: PCharacter; size_t: cardinal): PCharacter; cdecl; + RAND_load_file: function(const filename: PCharacter; max_bytes: clong): cint; cdecl; + RAND_write_file: function(const filename: PCharacter): cint; cdecl; + + RAND_set_rand_engine: function(engine: pENGINE): cint; cdecl; + + RAND_bytes: function(buf: pbyte; num: cint): cint; cdecl; + RAND_pseudo_bytes: function(buf: pbyte; num: cint): cint; cdecl; + + RAND_egd: function(path: pchar): cint; cdecl; + + RAND_set_rand_method: procedure(meth: pRAND_METHOD); cdecl; + RAND_get_rand_method: function(): pRAND_METHOD; cdecl; + RAND_SSLeay: function(): pRAND_METHOD; cdecl; + + RAND_cleanup: procedure(); cdecl; + +implementation +uses + msedynload; + +procedure init(const info: dynlibinfoty); +const + funcs: array[0..13] of funcinfoty = ( + (n: 'RAND_seed'; d: {$ifndef FPC}@{$endif}@RAND_seed), + (n: 'RAND_add'; d: {$ifndef FPC}@{$endif}@RAND_add), + (n: 'RAND_status'; d: {$ifndef FPC}@{$endif}@RAND_status), + (n: 'RAND_file_name'; d: {$ifndef FPC}@{$endif}@RAND_file_name), + (n: 'RAND_load_file'; d: {$ifndef FPC}@{$endif}@RAND_load_file), + (n: 'RAND_write_file'; d: {$ifndef FPC}@{$endif}@RAND_write_file), + (n: 'RAND_set_rand_engine'; d: {$ifndef FPC}@{$endif}@RAND_set_rand_engine), + (n: 'RAND_bytes'; d: {$ifndef FPC}@{$endif}@RAND_bytes), + (n: 'RAND_pseudo_bytes'; d: {$ifndef FPC}@{$endif}@RAND_pseudo_bytes), + (n: 'RAND_egd'; d: {$ifndef FPC}@{$endif}@RAND_egd), + (n: 'RAND_set_rand_method'; d: {$ifndef FPC}@{$endif}@RAND_set_rand_method), + (n: 'RAND_get_rand_method'; d: {$ifndef FPC}@{$endif}@RAND_get_rand_method), + (n: 'RAND_SSLeay'; d: {$ifndef FPC}@{$endif}@RAND_SSLeay), + (n: 'RAND_cleanup'; d: {$ifndef FPC}@{$endif}@RAND_cleanup) + ); +begin + getprocaddresses(info,funcs); +end; + +initialization + regopensslinit(@init); +end. diff --git a/mseide-msegui/lib/common/crypto/mseopensslrsa.pas b/mseide-msegui/lib/common/crypto/mseopensslrsa.pas new file mode 100644 index 0000000..d0ae420 --- /dev/null +++ b/mseide-msegui/lib/common/crypto/mseopensslrsa.pas @@ -0,0 +1,120 @@ +{ MSEgui Copyright (c) 2007-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseopensslrsa; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseopenssl,msectypes; + +const + RSA_PKCS1_PADDING = 1; + RSA_SSLV23_PADDING = 2; + RSA_NO_PADDING = 3; + RSA_PKCS1_OAEP_PADDING = 4; + RSA_X931_PADDING = 5; +//* EVP_PKEY_ only */ + RSA_PKCS1_PSS_PADDING = 6; + + RSA_PKCS1_PADDING_SIZE = 11; + +type + pRSA_METHOD = pointer; + RSA = record + // The first parameter is used to pickup errors where + // this is passed instead of aEVP_PKEY, it is set to 0 + pad: cint; + version: cint; + meth: pRSA_METHOD; + n: pBIGNUM; + e: pBIGNUM; + d: pBIGNUM; + p: pBIGNUM; + q: pBIGNUM; + dmp1: pBIGNUM; + dmq1: pBIGNUM; + iqmp: pBIGNUM; + // be careful using this if the RSA structure is shared + ex_data: CRYPTO_EX_DATA; + references: cint; + flags: cint; + // Used to cache montgomery values + _method_mod_n: pBN_MONT_CTX; + _method_mod_p: pBN_MONT_CTX; + _method_mod_q: pBN_MONT_CTX; + // all BIGNUM values are actually in the following data, if it is not + // NULL + bignum_data: ^byte; + blinding: pBN_BLINDING; + end; + pRSA = ^RSA; + +var + // RSA function + RSA_new: function: pRSA; cdecl; + RSA_free: procedure(r: pRSA); cdecl; + RSA_new_method: function(method: pRSA_METHOD): pRSA; cdecl; + RSA_size: function(pkey: pRSA): cint; cdecl; + RSA_check_key: function(arg0: pRSA): cint; cdecl; + RSA_public_encrypt: function(flen: cint; from: pcuchar; _to: pcuchar; + rsa: pRSA; padding: cint): cint; cdecl; + RSA_private_encrypt: function(flen: cint; from: pcuchar; _to: pcuchar; + rsa: pRSA; padding: cint): cint; cdecl; + RSA_public_decrypt: function(flen: cint; from: pcuchar; _to: pcuchar; + rsa: pRSA; padding: cint): cint; cdecl; + RSA_private_decrypt: function(flen: cint; from: pcuchar; _to: pcuchar; + rsa: pRSA; padding: cint): cint; cdecl; + RSA_flags: function(r: pRSA): cint; cdecl; + RSA_set_default_method: procedure(meth: pRSA_METHOD); cdecl; + RSA_get_default_method: function: pRSA_METHOD; cdecl; + RSA_get_method: function(rsa: pRSA): pRSA_METHOD; cdecl; + RSA_set_method: function(rsa: pRSA; meth: pRSA_METHOD): pRSA_METHOD; cdecl; + RSA_memory_lock: function(r: pRSA):cint; cdecl; + RSA_PKCS1_SSLeay: function: pRSA_METHOD; cdecl; + ERR_load_RSA_strings: procedure;cdecl; + RSA_generate_key: function(bits, e: cint; + callback: PFunction; cb_arg: SslPtr): PRSA; cdecl; + d2i_RSAPrivateKey_bio: function(bp: pBIO; rsa: pRSA): pRSA; cdecl; + i2d_RSAPrivateKey_bio: function(bp: pBIO; rsa: pRSA): cint; cdecl; + +implementation +uses + msedynload; + +procedure init(const info: dynlibinfoty); +const + funcs: array[0..19] of funcinfoty = ( + (n: 'RSA_new'; d: {$ifndef FPC}@{$endif}@RSA_new), + (n: 'RSA_free'; d: {$ifndef FPC}@{$endif}@RSA_free), + (n: 'RSA_new_method'; d: {$ifndef FPC}@{$endif}@RSA_new_method), + (n: 'RSA_size'; d: {$ifndef FPC}@{$endif}@RSA_size), + (n: 'RSA_check_key'; d: {$ifndef FPC}@{$endif}@RSA_check_key), + (n: 'RSA_public_encrypt'; d: {$ifndef FPC}@{$endif}@RSA_public_encrypt), + (n: 'RSA_private_encrypt'; d: {$ifndef FPC}@{$endif}@RSA_private_encrypt), + (n: 'RSA_public_decrypt'; d: {$ifndef FPC}@{$endif}@RSA_public_decrypt), + (n: 'RSA_private_decrypt'; d: {$ifndef FPC}@{$endif}@RSA_private_decrypt), + (n: 'RSA_flags'; d: {$ifndef FPC}@{$endif}@RSA_flags), + (n: 'RSA_set_default_method'; d: {$ifndef FPC}@{$endif}@RSA_set_default_method), + (n: 'RSA_get_default_method'; d: {$ifndef FPC}@{$endif}@RSA_get_default_method), + (n: 'RSA_get_method'; d: {$ifndef FPC}@{$endif}@RSA_get_method), + (n: 'RSA_set_method'; d: {$ifndef FPC}@{$endif}@RSA_set_method), + (n: 'RSA_memory_lock'; d: {$ifndef FPC}@{$endif}@RSA_memory_lock), + (n: 'RSA_PKCS1_SSLeay'; d: {$ifndef FPC}@{$endif}@RSA_PKCS1_SSLeay), + (n: 'ERR_load_RSA_strings'; d: {$ifndef FPC}@{$endif}@ERR_load_RSA_strings), + (n: 'RSA_generate_key'; d: {$ifndef FPC}@{$endif}@RSA_generate_key), + (n: 'd2i_RSAPrivateKey_bio'; d: {$ifndef FPC}@{$endif}@d2i_RSAPrivateKey_bio), + (n: 'i2d_RSAPrivateKey_bio'; d: {$ifndef FPC}@{$endif}@i2d_RSAPrivateKey_bio) + ); +begin + getprocaddresses(info,funcs); +end; + +initialization + regopensslinit(@init); +end. diff --git a/mseide-msegui/lib/common/crypto/mseopensslsmime.pas b/mseide-msegui/lib/common/crypto/mseopensslsmime.pas new file mode 100644 index 0000000..e97232a --- /dev/null +++ b/mseide-msegui/lib/common/crypto/mseopensslsmime.pas @@ -0,0 +1,38 @@ +{ MSEgui Copyright (c) 2007-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseopensslsmime; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseopenssl,msectypes; + +var +// SMIME function + SMIME_write_PKCS7: function(bp: pBIO; p7: pPKCS7; + data: pBIO; flags: cint): cint; cdecl; + SMIME_read_PKCS7: function(bp: pBIO; var bcont: pBIO): pPKCS7; cdecl; + +implementation +uses + msedynload; + +procedure init(const info: dynlibinfoty); +const + funcs: array[0..1] of funcinfoty = ( + (n: 'SMIME_write_PKCS7'; d: @SMIME_write_PKCS7), + (n: 'SMIME_read_PKCS7'; d: @SMIME_read_PKCS7) + ); +begin + getprocaddresses(info,funcs); +end; + +initialization + regopensslinit(@init); +end. \ No newline at end of file diff --git a/mseide-msegui/lib/common/crypto/mseopensslx509.pas b/mseide-msegui/lib/common/crypto/mseopensslx509.pas new file mode 100644 index 0000000..6097b9a --- /dev/null +++ b/mseide-msegui/lib/common/crypto/mseopensslx509.pas @@ -0,0 +1,386 @@ +{ MSEgui Copyright (c) 2007-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseopensslx509; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseopenssl,msectypes; + +type + pEVP_PKEY = SslPtr; //todo + pASN1_OBJECT = SslPtr; + pASN1_STRING = SslPtr; + pASN1_TIME = SslPtr; + +const + X509_V_OK = 0; + X509_V_ILLEGAL = 1; + X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT = 2; + X509_V_ERR_UNABLE_TO_GET_CRL = 3; + X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE = 4; + X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE = 5; + X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY = 6; + X509_V_ERR_CERT_SIGNATURE_FAILURE = 7; + X509_V_ERR_CRL_SIGNATURE_FAILURE = 8; + X509_V_ERR_CERT_NOT_YET_VALID = 9; + X509_V_ERR_CERT_HAS_EXPIRED = 10; + X509_V_ERR_CRL_NOT_YET_VALID = 11; + X509_V_ERR_CRL_HAS_EXPIRED = 12; + X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD = 13; + X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD = 14; + X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD = 15; + X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD = 16; + X509_V_ERR_OUT_OF_MEM = 17; + X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT = 18; + X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN = 19; + X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY = 20; + X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE = 21; + X509_V_ERR_CERT_CHAIN_TOO_LONG = 22; + X509_V_ERR_CERT_REVOKED = 23; + X509_V_ERR_INVALID_CA = 24; + X509_V_ERR_PATH_LENGTH_EXCEEDED = 25; + X509_V_ERR_INVALID_PURPOSE = 26; + X509_V_ERR_CERT_UNTRUSTED = 27; + X509_V_ERR_CERT_REJECTED = 28; + //These are 'informational' when looking for issuer cert + X509_V_ERR_SUBJECT_ISSUER_MISMATCH = 29; + X509_V_ERR_AKID_SKID_MISMATCH = 30; + X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH = 31; + X509_V_ERR_KEYUSAGE_NO_CERTSIGN = 32; + X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER = 33; + X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION = 34; + //The application is not happy + X509_V_ERR_APPLICATION_VERIFICATION = 50; + +type + pX509_NAME_ENTRY = ^X509_NAME_ENTRY; + X509_NAME_ENTRY = record + obj: pASN1_OBJECT; + value: pASN1_STRING; + _set: cint; + size: cint; // temp variable + end; + + pX509_NAME = ^X509_NAME; + pDN = ^X509_NAME; + X509_NAME = record + entries: pointer; + modified: cint; + bytes: pointer; + hash: cardinal; + end; + + pX509_VAL = ^X509_VAL; + X509_VAL = record + notBefore: pASN1_TIME; + notAfter: pASN1_TIME; + end; + + pX509_CINF = ^X509_CINF; + X509_CINF = record + version: pointer; + serialNumber: pointer; + signature: pointer; + issuer: pointer; + validity: pX509_VAL; + subject: pointer; + key: pointer; + issuerUID: pointer; + subjectUID: pointer; + extensions: pointer; + end; + + pX509 = ^X509; + X509 = record + cert_info: pX509_CINF; + sig_alg: pointer; // ^X509_ALGOR + signature: pointer; // ^ASN1_BIT_STRING + valid: cint; + references: cint; + name: PCharacter; + ex_data: CRYPTO_EX_DATA; + ex_pathlen: cint; + ex_flags: cint; + ex_kusage: cint; + ex_xkusage: cint; + ex_nscert: cint; + skid: pASN1_OCTET_STRING; + akid: pointer; // ? + sha1_hash: array [0..SHA_DIGEST_LENGTH-1] of char; + aux: pointer; // ^X509_CERT_AUX + end; + + pX509V3_CTX = pointer; + + pX509_REQ = ^X509_REQ; + pX509_REQ_INFO = ^X509_REQ_INFO; + X509_REQ_INFO = record + asn1: pointer; + length: cint; + version: pointer; + subject: pX509_NAME; + pubkey: pointer; + attributes: pointer; + req_kludge: cint; + end; + X509_REQ = record + req_info: pX509_REQ_INFO; + sig_alg: pointer; + signature: pointer; + references: cint; + end; + + pX509_EXTENSION = ^X509_EXTENSION; + X509_EXTENSION = record + obj: pASN1_OBJECT; + critical: Smallint; + netscape_hack: Smallint; + value: pASN1_OCTET_STRING; + method: pointer; // struct v3_ext_method *: V3 method to use + ext_val: pointer; // extension value + end; + pSTACK_OFX509_EXTENSION = pointer; + + pX509_CRL = pointer; + + pX509_SIG = ^X509_SIG; + X509_SIG = record + algor: Pointer; // X509_ALGOR *algor; + digest: pASN1_OCTET_STRING; + end; + + pX509_STORE_CTX = pointer; + // Certificate verification callback + TCertificateVerifyFunction = function(ok: cint; ctx: pX509_STORE_CTX): cint; cdecl; + + pSTACK_OFX509 = pointer; + pX509_STORE = ^X509_STORE; + pX509_LOOKUP = pointer; + pSTACK_OF509LOOKUP = pointer; + pX509_LOOKUP_METHOD = pointer; + X509_STORE = record + cache: cint; + objs: pSTACK_OFX509; + get_cert_methods: pSTACK_OF509LOOKUP; + verify: pointer; // function called to verify a certificate + verify_cb: TCertificateVerifyFunction; + ex_data: pointer; + references: cint; + depth: cint; + end; + +var + X509_new: function(): PX509; cdecl; + X509_free: procedure(x: PX509); cdecl; + X509_NAME_oneline: function(a: PX509_NAME; + buf: pchar; size: cint): pchar; cdecl; + X509_Get_Subject_Name: function(a: PX509):PX509_NAME; cdecl; + X509_Get_Issuer_Name: function(a: PX509):PX509_NAME; cdecl; + X509_NAME_hash: function(x: PX509_NAME):longword; cdecl; +// function SSL_X509Digest(data: PX509; _type: PEVP_MD; md: PChar; +// len: Pcint):cint; cdecl; + X509_digest: function(data: PX509; _type: PEVP_MD; md: pchar; + len: pcint):cint; cdecl; + X509_print: function(b: PBIO; a: PX509): cint; cdecl; + X509_set_version: function(x: PX509; version: cint): cint; cdecl; + X509_set_pubkey: function(x: PX509; pkey: pEVP_PKEY): cint; cdecl; + X509_set_issuer_name: function(x: PX509; name: PX509_NAME): cint; cdecl; + X509_NAME_add_entry_by_txt: function(name: PX509_NAME; field: pchar; + _type: cint; bytes: pbyte; len, loc, _set: cint): cint; cdecl; + X509_sign: function(x: PX509; pkey: pEVP_PKEY; const md: PEVP_MD): cint; cdecl; + X509_gmtime_adj: function(s: PASN1_UTCTIME; adj: cint): PASN1_UTCTIME; cdecl; + X509_set_NotBefore: function(x: PX509; tm: PASN1_UTCTIME): cint; cdecl; + X509_set_NotAfter: function(x: PX509; tm: PASN1_UTCTIME): cint; cdecl; + X509_get_serialNumber: function(x: PX509): PASN1_INTEGER; cdecl; + +// X.509 names (DN) + X509_NAME_new: function: pX509_NAME; cdecl; + X509_NAME_free: procedure(x:pX509_NAME) cdecl; + X509_NAME_get_entry: function(name: pX509_NAME; + loc: cint): pX509_NAME_ENTRY; cdecl; + X509_NAME_get_text_by_NID: function(name: pX509_NAME; nid: cint; + buf: PCharacter; len: cint): cint; cdecl; +// X.509 function + X509_load_cert_file: function(ctx: pX509_LOOKUP; + const filename: PCharacter; _type: cint): cint; cdecl; + X509_get1_email: function(x: pX509): pSTACK; cdecl; + X509_get_pubkey: function(a: pX509): pEVP_PKEY; cdecl; + X509_check_private_key: function(x509: pX509; pkey: pEVP_PKEY): cint; cdecl; + X509_check_purpose: function(x: pX509; id: cint; ca: cint): cint; cdecl; + X509_issuer_and_serial_cmp: function(a: pX509; b: pX509): cint; cdecl; + X509_issuer_and_serial_hash: function(a: pX509): cardinal; cdecl; + X509_verify_cert: function(ctx: pX509_STORE_CTX): cint; cdecl; + X509_verify_cert_error_string: function(n: clong): PCharacter; cdecl; + X509_email_free: procedure(sk: pSTACK); cdecl; + X509_get_ext: function(x: pX509; loc: cint): pX509_EXTENSION; cdecl; + X509_get_ext_by_NID: function(x: pX509; nid, lastpos: cint): cint; cdecl; + X509_get_ext_d2i: function(x: pX509; nid: cint; + var crit, idx: cint): pointer; cdecl; + X509V3_EXT_d2i: function(ext: pX509_EXTENSION): pointer; cdecl; + X509V3_EXT_i2d: function(ext_nid: cint; crit: cint; ext_struc: pointer): + pX509_EXTENSION; cdecl; + X509V3_EXT_conf_nid: function(conf: pointer; ctx: pointer; + ext_nid: cint; value: PCharacter): pX509_EXTENSION; cdecl; + X509_set_subject_name: function(x: pX509; name: pX509_NAME): cint; cdecl; + X509V3_set_ctx: procedure(ctx: pX509V3_CTX; issuer: pX509; + subject: pX509; req: pX509_REQ; crl: pX509_CRL; flags: cint); + X509_SIG_free: procedure(a: pX509_SIG); cdecl; + X509_PUBKEY_get: function(key: pointer): pEVP_PKEY; cdecl; + X509_REQ_new: function: pX509_REQ; cdecl; + X509_REQ_free: procedure(req: pX509_REQ); cdecl; + X509_REQ_set_version: function(req: pX509_REQ; version: clong): cint; cdecl; + X509_REQ_set_subject_name: function(req: pX509_REQ; + name: pX509_NAME): cint; cdecl; + X509_REQ_add1_attr_by_txt: function(req: pX509_REQ; attrname: PCharacter; + asn1_type: cint; bytes: pointer; len: cint): cint; cdecl; + X509_REQ_add_extensions: function(req: pX509_REQ; + exts: pSTACK_OFX509_EXTENSION): cint; cdecl; + X509_REQ_set_pubkey: function(req: pX509_REQ; pkey: pEVP_PKEY): cint; cdecl; + X509_REQ_get_pubkey: function(req: pX509_REQ): pEVP_PKEY; cdecl; + X509_REQ_sign: function(req: pX509_REQ; pkey: pEVP_PKEY; + const md: pEVP_MD): cint; cdecl; +// X.509 collections + X509_STORE_new: function: pX509_STORE; cdecl; + X509_STORE_free: procedure(v: pX509_STORE); cdecl; + X509_STORE_add_cert: function(ctx: pX509_STORE; x: pX509): cint; cdecl; + X509_STORE_add_lookup: function(v: pX509_STORE; + m: pX509_LOOKUP_METHOD): pX509_LOOKUP; cdecl; + X509_STORE_CTX_new: function: pX509_STORE_CTX; cdecl; + X509_STORE_CTX_free: procedure(ctx: pX509_STORE); cdecl; + X509_STORE_CTX_init: procedure(ctx: pX509_STORE_CTX; + store: pX509_STORE; x509: pX509; chain: pSTACK_OFX509); cdecl; + X509_STORE_CTX_get_current_cert: function(ctx: pX509_STORE_CTX): pX509; cdecl; + X509_STORE_CTX_get_error: function(ctx: pX509_STORE_CTX): cint; cdecl; + X509_STORE_CTX_get_error_depth: function(ctx: pX509_STORE_CTX): cint; cdecl; + X509_LOOKUP_new: function(method: pX509_LOOKUP_METHOD): pX509_LOOKUP; cdecl; + X509_LOOKUP_init: function(ctx: pX509_LOOKUP): cint; cdecl; + X509_LOOKUP_free: procedure(ctx: pX509_LOOKUP); cdecl; + X509_LOOKUP_ctrl: function(ctx: pX509_LOOKUP; cmd: cint; + const argc: PCharacter; argl: clong; ret: pointer): cint; cdecl; + X509_LOOKUP_file: function: pX509_LOOKUP_METHOD; cdecl; + d2i_X509_REQ_bio: function(bp: pBIO; req: pX509_REQ): pX509_REQ; cdecl; + i2d_X509_REQ_bio: function(bp: pBIO; req: pX509_REQ): cint; cdecl; + d2i_X509_bio: function(bp: pBIO; x509: pX509): pX509; cdecl; + +function X509_get_version(x: pX509): cint; +function X509_get_notBefore(a: pX509): pASN1_TIME; +function X509_get_notAfter(a: pX509): pASN1_TIME; +function X509_REQ_get_version(req: pX509_REQ): cint; +function X509_REQ_get_subject_name(req: pX509_REQ): pX509_NAME; + +implementation +uses + msedynload,mseopensslasn; + +function X509_get_version(x: pX509): cint; +begin + result := ASN1_INTEGER_get(x^.cert_info^.version); +end; + +function X509_get_notBefore(a: pX509): pASN1_TIME; +begin + result := a^.cert_info^.validity^.notBefore; +end; + +function X509_get_notAfter(a: pX509): pASN1_TIME; +begin + result := a^.cert_info^.validity^.notAfter; +end; + +function X509_REQ_get_version(req: pX509_REQ): cint; +begin + result := ASN1_INTEGER_get(req^.req_info^.version); +end; + +function X509_REQ_get_subject_name(req: pX509_REQ): pX509_NAME; +begin + result := req^.req_info^.subject; +end; + +procedure init(const info: dynlibinfoty); +const + funcs: array[0..67] of funcinfoty = ( + (n: 'X509_new'; d: @X509_new), + (n: 'X509_free'; d: @X509_free), + (n: 'X509_NAME_oneline'; d: @X509_NAME_oneline), + (n: 'X509_get_subject_name'; d: @X509_get_subject_name), + (n: 'X509_get_issuer_name'; d: @X509_get_issuer_name), + (n: 'X509_NAME_hash'; d: @X509_NAME_hash), + (n: 'X509_digest'; d: @X509_digest), + (n: 'X509_print'; d: @X509_print), + (n: 'X509_set_version'; d: @X509_set_version), + (n: 'X509_set_pubkey'; d: @X509_set_pubkey), + (n: 'X509_set_issuer_name'; d: @X509_set_issuer_name), + (n: 'X509_NAME_add_entry_by_txt'; d: @X509_NAME_add_entry_by_txt), + (n: 'X509_sign'; d: @X509_sign), + (n: 'X509_gmtime_adj'; d: @X509_gmtime_adj), + (n: 'X509_set_notBefore'; d: @X509_set_notBefore), + (n: 'X509_set_notAfter'; d: @X509_set_notAfter), + (n: 'X509_get_serialNumber'; d: @X509_set_notAfter), + (n: 'X509_NAME_new'; d: @X509_NAME_new), + (n: 'X509_NAME_free'; d: @X509_NAME_free), + (n: 'X509_NAME_get_entry'; d: @X509_NAME_get_entry), + (n: 'X509_NAME_get_text_by_NID'; d: @X509_NAME_get_text_by_NID), + (n: 'X509_load_cert_file'; d: @X509_load_cert_file), + (n: 'X509_get1_email'; d: @X509_get1_email), + (n: 'X509_get_pubkey'; d: @X509_get_pubkey), + (n: 'X509_check_private_key'; d: @X509_check_private_key), + (n: 'X509_check_purpose'; d: @X509_check_purpose), + (n: 'X509_issuer_and_serial_cmp'; d: @X509_issuer_and_serial_cmp), + (n: 'X509_issuer_and_serial_hash'; d: @X509_issuer_and_serial_hash), + (n: 'X509_verify_cert'; d: @X509_verify_cert), + (n: 'X509_verify_cert_error_string'; d: @X509_verify_cert_error_string), + (n: 'X509_email_free'; d: @X509_email_free), + (n: 'X509_get_ext'; d: @X509_get_ext), + (n: 'X509_get_ext_by_NID'; d: @X509_get_ext_by_NID), + (n: 'X509_get_ext_d2i'; d: @X509_get_ext_d2i), + (n: 'X509V3_EXT_d2i'; d: @X509V3_EXT_d2i), + (n: 'X509V3_EXT_i2d'; d: @X509V3_EXT_i2d), + (n: 'X509V3_EXT_conf_nid'; d: @X509V3_EXT_conf_nid), + (n: 'X509_set_subject_name'; d: @X509_set_subject_name), + (n: 'X509V3_set_ctx'; d: @X509V3_set_ctx), + (n: 'X509_SIG_free'; d: @X509_SIG_free), + (n: 'X509_PUBKEY_get'; d: @X509_PUBKEY_get), + (n: 'X509_REQ_new'; d: @X509_REQ_new), + (n: 'X509_REQ_free'; d: @X509_REQ_free), + (n: 'X509_REQ_set_version'; d: @X509_REQ_set_version), + (n: 'X509_REQ_set_subject_name'; d: @X509_REQ_set_subject_name), + (n: 'X509_REQ_add1_attr_by_txt'; d: @X509_REQ_add1_attr_by_txt), + (n: 'X509_REQ_add_extensions'; d: @X509_REQ_add_extensions), + (n: 'X509_REQ_set_pubkey'; d: @X509_REQ_set_pubkey), + (n: 'X509_REQ_get_pubkey'; d: @X509_REQ_get_pubkey), + (n: 'X509_REQ_sign'; d: @X509_REQ_sign), + (n: 'X509_STORE_new'; d: @X509_STORE_new), + (n: 'X509_STORE_free'; d: @X509_STORE_free), + (n: 'X509_STORE_add_cert'; d: @X509_STORE_add_cert), + (n: 'X509_STORE_add_lookup'; d: @X509_STORE_add_lookup), + (n: 'X509_STORE_CTX_new'; d: @X509_STORE_CTX_new), + (n: 'X509_STORE_CTX_free'; d: @X509_STORE_CTX_free), + (n: 'X509_STORE_CTX_init'; d: @X509_STORE_CTX_init), + (n: 'X509_STORE_CTX_get_current_cert'; d: @X509_STORE_CTX_get_current_cert), + (n: 'X509_STORE_CTX_get_error'; d: @X509_STORE_CTX_get_error), + (n: 'X509_STORE_CTX_get_error_depth'; d: @X509_STORE_CTX_get_error_depth), + (n: 'X509_LOOKUP_new'; d: @X509_LOOKUP_new), + (n: 'X509_LOOKUP_init'; d: @X509_LOOKUP_init), + (n: 'X509_LOOKUP_free'; d: @X509_LOOKUP_free), + (n: 'X509_LOOKUP_ctrl'; d: @X509_LOOKUP_ctrl), + (n: 'X509_LOOKUP_file'; d: @X509_LOOKUP_file), + (n: 'd2i_X509_REQ_bio'; d: @d2i_X509_REQ_bio), + (n: 'i2d_X509_REQ_bio'; d: @i2d_X509_REQ_bio), + (n: 'd2i_X509_bio'; d: @d2i_X509_bio) + ); + +begin + getprocaddresses(info,funcs); +end; + +initialization + regopensslinit(@init); +end. diff --git a/mseide-msegui/lib/common/crypto/msessl.pas b/mseide-msegui/lib/common/crypto/msessl.pas new file mode 100644 index 0000000..2f3e117 --- /dev/null +++ b/mseide-msegui/lib/common/crypto/msessl.pas @@ -0,0 +1,1076 @@ +{ MSEgui Copyright (c) 2007-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msessl; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses,msecryptio,mseopenssl,mseopensslevp,mseopensslrand, + msestrings,msesystypes,msecryptohandler,msetypes,msesys, + msestream; + +type + essl = class(ecryptoio) + end; + + ssldataty = record + ssl: pssl; + mutex: mutexty; + end; + + sslinfoty = record + case integer of + 0: (d: ssldataty); + 1: (_bufferspace: cryptodataty); + end; + {$if sizeof(ssldataty) > sizeof(cryptodataty)} + {$error 'buffer overflow'} + {$ifend} + + sslprotocolty = (ssp_sslv2,ssp_sslv3,ssp_tlsv1); + sslprotocolsty = set of sslprotocolty; +const + defaultsslprotocols = [ssp_sslv2,ssp_sslv3,ssp_tlsv1]; + defaultcipherlist = 'DEFAULT'; + defaultkeygeniterationcount = 1{5}; //same as openssl enc + +type + + tssl = class(tcryptoio) + private + fctx: pssl_ctx; + fprotocols: sslprotocolsty; + fcipherlist: tstringlist; + fcertfile: filenamety; + fprivkeyfile: filenamety; + procedure ctxchanged; + procedure setcipherlist(const avalue: tstringlist); + protected + class procedure internalunlink(var ainfo: cryptoioinfoty); override; + class procedure internalthreadterminate; override; + class procedure connect(var ainfo: cryptoioinfoty; + const atimeoutms: integer); override; + class procedure accept(var ainfo: cryptoioinfoty; const atimeoutms: integer); override; + class function write(var ainfo: cryptoioinfoty; const buffer: pointer; + const count: integer; const atimeoutms: integer): integer; override; + class function read(var ainfo: cryptoioinfoty; const buffer: pointer; + const count: integer; const atimeoutms: integer): integer; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure link(const arxfd,atxfd: integer; + out ainfo: cryptoioinfoty); override; + published + property protocols: sslprotocolsty read fprotocols write fprotocols + default defaultsslprotocols; + property cipherlist: tstringlist read fcipherlist write setcipherlist; + property certfile: filenamety read fcertfile write fcertfile; + property privkeyfile: filenamety read fprivkeyfile write fprivkeyfile; + end; + + digeststatety = (ds_inited{,ds_final}); + digeststatesty = set of digeststatety; + + digesthandlerdatadty = record + ctx: pevp_md_ctx; + md: pevp_md; + state: digeststatesty; +// digest: pointer; //string + end; + pdigesthandlerdatadty = ^digesthandlerdatadty; + {$if sizeof(digesthandlerdatadty) > sizeof(cryptohandlerdataty)} + {$error 'buffer overflow'} + {$ifend} + digesthandlerdataty = record + case integer of + 0: (d: digesthandlerdatadty;); + 1: (_bufferspace: cryptohandlerdataty;); + end; + + tdigesthandler = class; + +// digesteventty = procedure(const sender: tdigesthandler; +// const astream: tmsefilestream; const adigest: string) of object; + + tdigesthandler = class(tbasecryptohandler) + private + fdigestname: string; +// fondigest: digesteventty; + protected +// procedure finalizeclient(var aclient: cryptoclientinfoty); override; +// procedure dofinal(var aclient: cryptoclientinfoty); + procedure checkerror(const err: cryptoerrorty = cerr_error); override; + procedure open(var aclient: cryptoclientinfoty); override; + procedure close(var aclient: cryptoclientinfoty); override; + function read(var aclient: cryptoclientinfoty; + var buffer; count: longint): longint; override; + function write(var aclient: cryptoclientinfoty; + const buffer; count: longint): longint; override; + function seek(var aclient: cryptoclientinfoty; + const offset: int64; origin: tseekorigin): int64; override; + procedure restartdigest(var aclient: cryptoclientinfoty); + public + function digest(const astream: tmsefilestream): string; + published + property digestname: string read fdigestname write fdigestname; +// property ondigest: digesteventty read fondigest write fondigest; + end; + + cipherkindty = (ckt_stream, + ckt_ecb, //electronic codebook + ctk_cbc, //cipher-block chaining + ctk_cfb, //cipher feedback + ctk_ofb);//output feedback + +// padbufty = array[0..3*evp_max_block_length-1] of byte; + keybufty = array[0..evp_max_key_length-1] of byte; + ivbufty = array[0..evp_max_iv_length-1] of byte; +// blockbufty = array[0..evp_max_block_length-1] of byte; + + sslhandlerdatadty = record + p: paddedhandlerdatadty; + ctx: pevp_cipher_ctx; + cipher: pevp_cipher; + digest: pevp_md; + keybuf: ^keybufty; + ivbuf: ^ivbufty; + end; + psslhandlerdatadty = ^sslhandlerdatadty; + {$if sizeof(sslhandlerdatadty) > sizeof(cryptohandlerdataty)} + {$error 'buffer overflow'} + {$ifend} + sslhandlerdataty = record + case integer of + 0: (d: sslhandlerdatadty;); + 1: (_bufferspace: cryptohandlerdataty;); + end; + + getkeyeventty = procedure(const sender: tobject; + var akey,asalt: string) of object; + + opensslcryptooptionty = (sslco_salt,sslco_canrestart); + //stores key and iv for seek(0) + opensslcryptooptionsty = set of opensslcryptooptionty; +const + defaultopensslcryptooptions = [sslco_salt]; + +type + tcustomopensslcryptohandler = class(tpaddedcryptohandler) + private + fciphername: string; + fkey: string; + fsalt: string; + fkeyphrase: msestring; + fongetkey: getkeyeventty; + fkeylength: integer; + foptions: opensslcryptooptionsty; + procedure setkeyphrase(const avalue: msestring); + protected + procedure clearerror; {$ifdef FPC}inline;{$endif} + procedure checkerror(const err: cryptoerrorty = cerr_error); override; + procedure cipherupdate(var aclient: cryptoclientinfoty; + const source: pbyte; const sourcelen: integer; + const dest: pbyte; out destlen: integer); override; + procedure cipherfinal(var aclient: cryptoclientinfoty; + const dest: pbyte; out destlen: integer); override; + procedure initcipher(var aclient: cryptoclientinfoty); virtual; abstract; + procedure restartcipher(var aclient: cryptoclientinfoty); override; + procedure getkey(out akey: string; out asalt: string); virtual; + procedure initializedata(var aclient: cryptoclientinfoty); override; + procedure finalizedata(var aclient: cryptoclientinfoty); override; + function padbufsize: integer; override; + public + constructor create(aowner: tcomponent); override; + property key: string read fkey write fkey; + property options: opensslcryptooptionsty read foptions + write foptions default defaultopensslcryptooptions; + property ciphername: string read fciphername write fciphername; + property keyphrase: msestring read fkeyphrase write setkeyphrase; + property keylength: integer read fkeylength write fkeylength default 0; + //bits, 0 -> use cipher default + property ongetkey: getkeyeventty read fongetkey write fongetkey; + end; +{ + asymkeyfileheader = record + symkeylen: integer; + symkey: array[0..0] of byte; //encrypted, variable length + iv: array[0..0] of byte; //variable length, cipher dependent + end; +} + tsymciphercryptohandler = class(tcustomopensslcryptohandler) + private + fkeydigestname: string; + fkeygeniterationcount: integer; + protected + procedure initcipher(var aclient: cryptoclientinfoty); override; + published + constructor create(aowner: tcomponent); override; + property salt: string read fsalt write fsalt; + property keydigestname: string read fkeydigestname write fkeydigestname; + //default md5 + property keygeniterationcount: integer read fkeygeniterationcount + write fkeygeniterationcount default defaultkeygeniterationcount; + property options; + property ciphername; +// property keydigestname; +// property keygeniterationcount; + property keyphrase; + property keylength; + property ongetkey; + end; + + tasymciphercryptohandler = class(tcustomopensslcryptohandler) + private + fprivkeyfile: filenamety; + fpubkeyfile: filenamety; + protected + procedure initcipher(var aclient: cryptoclientinfoty); override; + published + property privkeyfile: filenamety read fprivkeyfile write fprivkeyfile; + property pubkeyfile: filenamety read fpubkeyfile write fpubkeyfile; + //use '"first" "second" "third"' for multiple + property options; + property ciphername; +// property keydigestname; +// property keygeniterationcount; + property keyphrase; + property keylength; + property ongetkey; + end; + +getkeydataeventty = procedure(out akey: string; out asalt: string) of object; + +function waitforio(const aerror: integer; var ainfo: cryptoioinfoty; + const atimeoutms: integer; + const resultpo: pinteger = nil): boolean; +function filebio(const aname: filenamety; + const aopenmode: fileopenmodety): pbio; +procedure closebio(const abio: pbio); +function readpubkey(const aname: filenamety): pevp_pkey; +function readprivkey(const aname: filenamety; + const getkey: getkeydataeventty): pevp_pkey; +procedure freekey(const akey: pevp_pkey); +function messagedigest(const adata: string; const digestname: string): string; + +implementation +uses + sysutils,msesysintf1,msefileutils,msesocketintf,mseopensslbio,mseopensslpem, + mseopensslrsa,msebits, + msesysintf,msectypes; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +procedure raisesslerror(const err: cryptoerrorty); +const + buffersize = 200; +var + int1: integer; + str1,str2: string; +begin + str1:= ''; + setlength(str2,buffersize); + while true do begin + int1:= err_get_error(); + if int1 = 0 then begin + break; + end; + err_error_string_n(int1,pointer(str2),buffersize); + if str1 <> '' then begin + str1:= str1 + lineend; + end; + str1:= str1 + pchar(str2); + end; + if str1 <> '' then begin + raise essl.create(ansistring(cryptoerrormessages[err])+lineend+str1); + end; +end; + +procedure raiseerror(errco : integer; const amessage: string = ''); +var + buf: array [0..255] of char; + str1: string; +begin + if amessage = '' then begin + str1:= 'SSL error.'; + end + else begin + str1:= amessage; + end; + repeat + err_error_string_n(errco,@buf,sizeof(buf)); + str1:= str1 + lineend + buf; + errco:= err_get_error(); + until errco = 0; + raise essl.create(str1); +end; + +procedure sslerror(const aerror: integer); +begin + if aerror <> 1 then begin + raiseerror(err_get_error()); + end; +end; + +procedure cryptoerror(const aerror: cryptoerrorty); +var + int1: integer; +begin + int1:= err_get_error(); + if int1 <> 0 then begin + raiseerror(int1,ansistring(cryptoerrormessages[aerror])); + end; +end; + +function filebio(const aname: filenamety; + const aopenmode: fileopenmodety): pbio; +var + str1,str2: string; +begin + str1:= stringtoutf8ansi(tosysfilepath(filepath(aname))); + case aopenmode of + fm_write: begin + str2:= 'a+'; //-> append, not supported + end; + fm_readwrite: begin + str2:= 'r+'; + end; + fm_create: begin + str2:= 'w+'; + end; + fm_append: begin + str2:= 'a+'; //sets write filepointer to end! + end + else begin + str2:= 'r'; //fm_read, fm none + end; + end; + result:= bio_new_file(pchar(str1),pchar(str2)); + if result = nil then begin + cryptoerror(cerr_nobio); + end; +end; +{ +function filebio(const aname: filenamety; + const aopenmode: fileopenmodety): pbio; +var + fd: integer; +begin + syserror(sys_openfile(aname,aopenmode,[],[],fd)); + result:= bio_new_fd(fd,1); + if result = nil then begin + cryptoerror(cerr_nobio); + end; +end; +} +{ +function streambio(const aname: filenamety; + const aopenmode: fileopenmodety): pbio; +var + fd: integer; + file1: pfile; + str1: string; +begin + syserror(sys_openfile(aname,aopenmode,[],[],fd)); + file1:= fdopen(fd,pchar(str1); + if file1 = nil then begin + syserror(syelasterror); + end; + bio_new(bio_s_file); + if bio_set +end; +} +procedure closebio(const abio: pbio); +begin + bio_free_all(abio); +end; + +function readpubkey(const aname: filenamety): pevp_pkey; +var + bio: pbio; +begin + bio:= filebio(aname,fm_read); + result:= pem_read_bio_pubkey(bio,nil,nil,nil); + closebio(bio); + if result = nil then begin + cryptoerror(cerr_nopubkey); + end; +end; + +function cb(buf: pcuchar; size: cint; rwflag: cint; u: pointer): cint; cdecl; +var + key,iv: string; +begin + getkeydataeventty(u^)(key,iv); + if length(key) > size then begin + setlength(key,size); + end; + result:= length(key); + move(key[1],buf^,result); +end; + +function readprivkey(const aname: filenamety; + const getkey: getkeydataeventty): pevp_pkey; +var + bio: pbio; +begin + bio:= filebio(aname,fm_read); + result:= pem_read_bio_privatekey(bio,nil,@cb,@getkey); + closebio(bio); + if result = nil then begin + cryptoerror(cerr_noprivkey); + end; +end; + +procedure freekey(const akey: pevp_pkey); +begin + if akey <> nil then begin + evp_pkey_free(akey); + end; +end; + +function checknilerror(const avalue: pointer; + const err: cryptoerrorty = cerr_error): pointer; + {$ifdef FPC} inline;{$endif} +begin + result:= avalue; + if avalue = nil then begin + raisesslerror(err); + end; +end; + +function checknullerror(const avalue: integer; + const err: cryptoerrorty = cerr_error): integer; + {$ifdef FPC} inline;{$endif} +begin + result:= avalue; + if avalue = 0 then begin + raisesslerror(err); + end; +end; + +function messagedigest(const adata: string; const digestname: string): string; +var + ctx: pevp_md_ctx; + md: pevp_md; + int1: integer; + str1: string; +begin + initsslinterface; + ctx:= checknilerror(evp_md_ctx_create()); + try + md:= checknilerror(evp_get_digestbyname(pointer(pchar(digestname)))); + checknullerror(evp_digestinit_ex(ctx,md,nil)); + checknullerror(evp_digestupdate(ctx,pointer(adata),length(adata))); + setlength(str1,evp_max_md_size); + checknullerror(evp_digestfinal_ex(ctx,pointer(str1),cardinal(int1))); + setlength(str1,int1); + result:= str1; + finally + evp_md_ctx_destroy(ctx); + end; +end; + +{ tssl } + +constructor tssl.create(aowner: tcomponent); +begin + fprotocols:= defaultsslprotocols; + fcipherlist:= tstringlist.create; + fcipherlist.text:= defaultcipherlist; + inherited; +end; + +destructor tssl.destroy; +begin + inherited; + if fctx <> nil then begin + ssl_ctx_free(fctx); + fctx:= nil; + end; + fcipherlist.free; +end; + +procedure tssl.ctxchanged; +begin + if fctx <> nil then begin + + end; +end; + +procedure tssl.link(const arxfd,atxfd: integer; out ainfo: cryptoioinfoty); +var + int1: integer; + str1: string; +begin + inherited; + if fctx = nil then begin + initsslinterface; + fctx:= ssl_ctx_new(sslv23_method()); + if fctx = nil then begin + sslerror(0); + end; + ctxchanged; + end; + with ainfo,sslinfoty(cryptodata).d do begin + ssl:= ssl_new(fctx); + if ssl = nil then begin + sslerror(0); + end; + sys_mutexcreate(mutex); + int1:= 0; + if not (ssp_sslv2 in fprotocols) then begin + int1:= int1 or ssl_op_no_sslv2; + end; + if not (ssp_sslv3 in fprotocols) then begin + int1:= int1 or ssl_op_no_sslv3; + end; + if not (ssp_tlsv1 in fprotocols) then begin + int1:= int1 or ssl_op_no_tlsv1; + end; + if int1 <> 0 then begin + ssl_set_options(ssl,int1); + end; + str1:= ''; + for int1:= 0 to fcipherlist.count - 1 do begin + str1:= str1 + fcipherlist[int1] + ':'; + end; + setlength(str1,length(str1)-1); + sslerror(ssl_set_cipher_list(ssl,pchar(str1))); + if fcertfile <> '' then begin + str1:= ansistring(tosysfilepath(filepath(fcertfile))); + sslerror(ssl_use_certificate_file(ssl,pchar(str1),ssl_filetype_pem)); + end; + if fprivkeyfile <> '' then begin + str1:= ansistring(tosysfilepath(filepath(fprivkeyfile))); + sslerror(ssl_use_privatekey_file(ssl,pchar(str1),ssl_filetype_pem)); + end; + sslerror(ssl_set_rfd(ssl,rxfd)); + sslerror(ssl_set_wfd(ssl,txfd)); + end; +end; + +class procedure tssl.internalunlink(var ainfo: cryptoioinfoty); +begin //todo: shutdown + with ainfo,sslinfoty(cryptodata).d do begin + if ssl <> nil then begin + ssl_free(ssl); + end; + sys_mutexdestroy(mutex); + end; + inherited; +end; + +class procedure tssl.internalthreadterminate; +begin + err_remove_state(0); + inherited; +end; + +function {tssl.}waitforio(const aerror: integer; var ainfo: cryptoioinfoty; + const atimeoutms: integer; const resultpo: pinteger = nil): boolean; +var + int1: integer; + err1: syserrorty; + pollres: pollkindsty; +begin + with ainfo,sslinfoty(cryptodata).d do begin + sys_mutexunlock(mutex); + result:= (aerror > 0); + if not result then begin + if aerror < 0 then begin + err1:= sye_ok; + int1:= ssl_get_error(ssl,aerror); + if (int1 = ssl_error_want_read) then begin + if atimeoutms >= 0 then begin + err1:= soc_poll(rxfd,[poka_read],atimeoutms,pollres); + end; + end + else begin + if (int1 = ssl_error_want_write) then begin + if atimeoutms >= 0 then begin + err1:= soc_poll(txfd,[poka_write],atimeoutms,pollres); + end; + end + else begin + raiseerror(int1); + end; + end; + if err1 <> sye_ok then begin + syserror(err1); + end; + end + else begin + sslerror(aerror); + end; + end; + end; + if resultpo <> nil then begin + if (atimeoutms < 0) and (aerror < 0) then begin + resultpo^:= 0; + end + else begin + resultpo^:= aerror; + end; + end; +end; + +class procedure tssl.connect(var ainfo: cryptoioinfoty; + const atimeoutms: integer); +//var +// int1,int2: integer; +// err1: syserrorty; +begin + with ainfo,sslinfoty(cryptodata).d do begin + repeat + sys_mutexlock(mutex); + until waitforio(ssl_connect(ssl),ainfo,atimeoutms); + end; +end; + +class procedure tssl.accept(var ainfo: cryptoioinfoty; + const atimeoutms: integer); +//var +// int1{,int2}: integer; +// err1: syserrorty; +begin + with ainfo,sslinfoty(cryptodata).d do begin + repeat + sys_mutexlock(mutex); + until waitforio(ssl_accept(ssl),ainfo,atimeoutms); + end; +end; + +procedure tssl.setcipherlist(const avalue: tstringlist); +begin + fcipherlist.assign(avalue); +end; + +class function tssl.write(var ainfo: cryptoioinfoty; const buffer: pointer; + const count: integer; const atimeoutms: integer): integer; +begin + with ainfo,sslinfoty(cryptodata).d do begin + try + repeat + sys_mutexlock(mutex); + until waitforio(ssl_write(ssl,buffer,count),ainfo,atimeoutms,@result); + except + result:= -1; + end; + end; +end; + +class function tssl.read(var ainfo: cryptoioinfoty; const buffer: pointer; + const count: integer; const atimeoutms: integer): integer; +var + pollres: pollkindsty; +begin + result:= 0; + with ainfo,sslinfoty(cryptodata).d do begin + try + if (atimeoutms < 0) or + (soc_poll(ainfo.rxfd,[poka_read],atimeoutms,pollres) = sye_ok) then begin + repeat + sys_mutexlock(mutex); + until waitforio(ssl_read(ssl,buffer,count),ainfo,atimeoutms,@result) or + (atimeoutms < 0); + end; + except + result:= -1; + end; + end; +end; + +{ tcustomopensslcryptohandler } + +constructor tcustomopensslcryptohandler.create(aowner: tcomponent); +begin + foptions:= defaultopensslcryptooptions; + inherited; +end; + +procedure tcustomopensslcryptohandler.clearerror; +begin + err_clear_error(); +end; + +procedure tcustomopensslcryptohandler.checkerror(const err: cryptoerrorty); +begin + raisesslerror(err); +end; + +procedure tcustomopensslcryptohandler.initializedata( + var aclient: cryptoclientinfoty); +var + int1: integer; +begin + inherited; + initsslinterface; + with sslhandlerdataty(aclient.handlerdata).d do begin + getmem(ctx,sizeof(ctx^)); + evp_cipher_ctx_init(ctx); + getmem(keybuf,sizeof(keybuf^)); + getmem(ivbuf,sizeof(ivbuf^)); + + cipher:= checknilerror(evp_get_cipherbyname(pcchar(pchar(fciphername))), + cerr_ciphernotfound); + checknullerror(evp_cipherinit_ex(ctx,cipher,nil,nil,nil,p.mode), + cerr_cipherinit); + if fkeylength <> 0 then begin + int1:= fkeylength div 8; + if int1 > evp_max_key_length then begin + error(cerr_invalidkeylength); + end; + checknullerror(evp_cipher_ctx_set_key_length(ctx,int1)); + if (ctx^.key_len * 8 <> fkeylength) then begin + error(cerr_invalidkeylength); + end; + end; +{ if (mode = 0) and (cipher^.block_size > 1) then begin + finalizedata(sslhandlerdataty(aclient.handlerdata).d); + error(cerr_invalidblocksize); //todo: implement block ciphers + end; +} + initcipher(aclient); + p.blocksize:= ctx^.cipher^.block_size; + if not (sslco_canrestart in foptions) then begin + fillchar(keybuf^,sizeof(keybuf^),0); + fillchar(ivbuf^,sizeof(ivbuf^),0); + end; + end; +end; + +procedure tcustomopensslcryptohandler.finalizedata( + var aclient: cryptoclientinfoty); +var + data1: psslhandlerdatadty; +begin + inherited; + data1:= @sslhandlerdataty(aclient.handlerdata).d; + with data1^ do begin + if ctx <> nil then begin + evp_cipher_ctx_cleanup(ctx); + freemem(ctx); + end; + if keybuf <> nil then begin + fillchar(keybuf^,sizeof(keybuf^),0); + freemem(keybuf); + end; + if ivbuf <> nil then begin + fillchar(ivbuf^,sizeof(ivbuf^),0); + freemem(ivbuf); + end; + end; + fillchar(data1^,sizeof(data1^),0); +end; + +procedure tcustomopensslcryptohandler.restartcipher( + var aclient: cryptoclientinfoty); +begin + if not (sslco_canrestart in foptions) then begin + error(cerr_cannotrestart); + end; + inherited; + with sslhandlerdataty(aclient.handlerdata).d do begin + checknullerror(evp_cipherinit_ex(ctx,nil,nil,pointer(keybuf), + pointer(ivbuf),p.mode),cerr_cipherinit); + ctx^.iv:= ctx^.iov; + end; +end; + +procedure tcustomopensslcryptohandler.setkeyphrase(const avalue: msestring); +begin + fkey:= stringtoutf8ansi(avalue); + fkeyphrase:= avalue; +end; + +procedure tcustomopensslcryptohandler.getkey(out akey: string; out asalt: string); +begin + akey:= fkey; + asalt:= fsalt; + if canevent(tmethod(fongetkey)) then begin + fongetkey(self,akey,asalt); + end; +end; + +procedure tcustomopensslcryptohandler.cipherupdate( + var aclient: cryptoclientinfoty;const source: pbyte; + const sourcelen: integer; const dest: pbyte; + out destlen: integer); +begin + with sslhandlerdataty(aclient.handlerdata).d do begin + checknullerror(evp_cipherupdate(ctx,pointer(dest),destlen, + pointer(source),sourcelen)); + end; +end; + +procedure tcustomopensslcryptohandler.cipherfinal( + var aclient: cryptoclientinfoty; + const dest: pbyte; out destlen: integer); +begin + with sslhandlerdataty(aclient.handlerdata).d do begin + checknullerror(evp_cipherfinal(ctx,pcuchar(dest),destlen)); + end; +end; + +function tcustomopensslcryptohandler.padbufsize: integer; +begin + result:= 3*evp_max_block_length; +end; + +{ tsymciphercryptohandler} + +constructor tsymciphercryptohandler.create(aowner: tcomponent); +begin + fkeydigestname:= 'md5'; + fkeygeniterationcount:= defaultkeygeniterationcount; + inherited; +end; + +procedure tsymciphercryptohandler.initcipher(var aclient: cryptoclientinfoty); +const + salttag = 'Salted__'; + taglength = length(salttag); + saltlength = 8; + headerlength = taglength + saltlength; +var +// keydata: keybufty; +// ivdata: ivbufty; + key1,salt1: string; +begin + with sslhandlerdataty(aclient.handlerdata).d do begin + digest:= checknilerror(evp_get_digestbyname(pcchar(pchar(fkeydigestname))), + cerr_digestnotfound); + getkey(key1,salt1); + if key1 = '' then begin + error(cerr_nokey); + end; + if salt1 <> '' then begin + salt1:= salt1 + nullstring(8-length(salt1)); + end; + if sslco_salt in foptions then begin + if p.mode = 0 then begin + setlength(salt1,headerlength); + if (internalread(aclient,pointer(salt1)^,headerlength) <> headerlength) or + (pos(salttag,salt1) <> 1) then begin + error(cerr_readheader); + end; + end + else begin + if salt1 = '' then begin + setlength(salt1,saltlength); + checknullerror(rand_bytes(pbyte(pointer(salt1)),saltlength)); + end; + salt1:= salttag+salt1; + if internalwrite(aclient,pointer(salt1)^,length(salt1)) <> + length(salt1) then begin + error(cerr_writeheader); + end; + end; + end; + if sslco_salt in foptions then begin + p.headersize:= headerlength; + end; + checknullerror(evp_bytestokey(cipher,digest, + pointer(pchar(pointer(salt1))+taglength),pointer(key1), + length(key1),fkeygeniterationcount, + pointer(keybuf),pointer(ivbuf))); + checknullerror(evp_cipherinit_ex(ctx,nil,nil,pointer(keybuf),pointer(ivbuf), + p.mode),cerr_cipherinit); + end; +end; + +{ tasymciphercryptohandler } + +procedure tasymciphercryptohandler.initcipher(var aclient: cryptoclientinfoty); +var + asymkey: pevp_pkey; + keybuf1: string; + keydata: string; +// ivdata: ivbufty; + int1,int2: integer; +begin + with sslhandlerdataty(aclient.handlerdata).d do begin + asymkey:= nil; + try + if p.mode = 1 then begin //encrypt + if fpubkeyfile = '' then begin + error(cerr_nopubkey); + end; + asymkey:= readpubkey(fpubkeyfile); +// setlength(keydata,evp_max_key_length); + checknullerror(evp_cipher_ctx_rand_key(ctx,pointer(keybuf))); + if cipher^.iv_len > 0 then begin + checknullerror(rand_bytes(pointer(ivbuf),cipher^.iv_len)); + end; + setlength(keybuf1,evp_pkey_size(asymkey)); + int1:= encryptsymkeyrsa(pointer(keybuf1),pointer(keybuf),ctx^.key_len, + asymkey); + if int1 < -1 then begin + error(cerr_norsakey); + end; + if int1 < 0 then begin + error(cerr_encrypt); + end; + if internalwrite(aclient,pointer(keybuf1)^,int1) <> int1 then begin + error(cerr_writeheader); + end; + if cipher^.iv_len > 0 then begin + if internalwrite(aclient,ivbuf^,cipher^.iv_len) <> + cipher^.iv_len then begin + error(cerr_writeheader); + end; + end; + end + else begin + if fprivkeyfile = '' then begin + error(cerr_nopubkey); + end; + asymkey:= readprivkey(fprivkeyfile,{$ifdef FPC}@{$endif}getkey); + if asymkey^._type <> EVP_PKEY_RSA then begin + error(cerr_norsakey); + end; + int1:= evp_pkey_size(asymkey); + setlength(keybuf1,int1); + if internalread(aclient,pointer(keybuf1)^,int1) <> int1 then begin + error(cerr_readheader); + end; + setlength(keydata,rsa_size(EVP_PKEY_get1_RSA(asymkey))+2); + int2:= decryptsymkeyrsa(pointer(keydata),pointer(keybuf1),length(keybuf1), + asymkey); + if (int2 < 0) or (int2 > sizeof(keybuf^)) then begin + error(cerr_decrypt); + end; + checknullerror(evp_cipher_ctx_set_key_length(ctx,int2)); + move(pointer(keydata)^,keybuf^,int2); + if cipher^.iv_len > 0 then begin + if internalread(aclient,ivbuf^,cipher^.iv_len) <> + cipher^.iv_len then begin + error(cerr_readheader); + end; + end; + end; + p.headersize:= int1 + cipher^.iv_len; + finally + freekey(asymkey); + end; + checknullerror(evp_cipherinit_ex(ctx,nil,nil,pointer(keybuf), + pointer(ivbuf),p.mode),cerr_cipherinit); + end; +end; + +{ tdigesthandler } + +procedure tdigesthandler.open(var aclient: cryptoclientinfoty); +begin + inherited; + initsslinterface; + with digesthandlerdataty(aclient.handlerdata).d do begin + ctx:= checknilerror(evp_md_ctx_create()); + md:= checknilerror(evp_get_digestbyname(pointer(pchar(fdigestname)))); + checknullerror(evp_digestinit_ex(ctx,md,nil)); + include(state,ds_inited); + end; +end; + +procedure tdigesthandler.close(var aclient: cryptoclientinfoty); +begin + inherited; + with digesthandlerdataty(aclient.handlerdata).d do begin + if ctx <> nil then begin + evp_md_ctx_destroy(ctx); + ctx:= nil; + state:= []; + end; + end; +end; + +function tdigesthandler.read(var aclient: cryptoclientinfoty; var buffer; + count: longint): longint; +begin + result:= inherited read(aclient,buffer,count); + with digesthandlerdataty(aclient.handlerdata).d do begin + checknullerror(evp_digestupdate(ctx,@buffer,result)); + end; +end; + +function tdigesthandler.write(var aclient: cryptoclientinfoty; const buffer; + count: longint): longint; +begin + with digesthandlerdataty(aclient.handlerdata).d do begin + checknullerror(evp_digestupdate(ctx,@buffer,count)); + end; + result:= inherited write(aclient,buffer,count); +end; + +function tdigesthandler.seek(var aclient: cryptoclientinfoty; + const offset: int64; origin: tseekorigin): int64; +begin + if (offset <> 0) then begin + error(cerr_notseekable); + end; + result:= inherited seek(aclient,offset,origin); + if origin = sobeginning then begin + restartdigest(aclient); + end; +end; + +procedure tdigesthandler.restartdigest(var aclient: cryptoclientinfoty); +begin + with digesthandlerdataty(aclient.handlerdata).d do begin + checknullerror(evp_digestinit_ex(ctx,md,nil)); +// exclude(state,ds_final); + end; +end; + +procedure tdigesthandler.checkerror(const err: cryptoerrorty = cerr_error); +begin + raisesslerror(err); +end; + +function tdigesthandler.digest(const astream: tmsefilestream): string; +var + str1: string; + int1: integer; +begin + with digesthandlerdataty(getclient(astream)^.handlerdata).d do begin + if not (ds_inited in state) then begin + error(cerr_notactive); + end; + setlength(str1,evp_max_md_size); + checknullerror(evp_digestfinal_ex(ctx,pcuchar(pointer(str1)),cardinal(int1))); + setlength(str1,int1); + result:= str1; + checknullerror(evp_digestinit_ex(ctx,md,nil)); + end; +end; + +{ +procedure tdigesthandler.finalizeclient(var aclient: cryptoclientinfoty); +begin + inherited; + with digesthandlerdataty(aclient.handlerdata).d do begin + string(digest):= ''; + end; +end; +} +end. diff --git a/mseide-msegui/lib/common/crypto/msezlib.pas b/mseide-msegui/lib/common/crypto/msezlib.pas new file mode 100644 index 0000000..25db2eb --- /dev/null +++ b/mseide-msegui/lib/common/crypto/msezlib.pas @@ -0,0 +1,743 @@ +{ MSEgui Copyright (c) 2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msezlib; +{/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.2.7, May 2nd, 2012 + + Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 + (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). +*/} +{/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed data. + This version of the library supports only one compression method (deflation) + but other algorithms will be added later and will have the same stream + interface. + + Compression can be done in a single step if the buffers are large enough, + or can be done by repeated calls of the compression function. In the latter + case, the application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip streams in memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never crash + even in case of corrupted input. +*/} + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +uses + msedynload,msetypes{msestrings},msectypes; +const +{$ifdef mswindows} + zliblib: array[0..0] of filenamety = ('zli1.dll'); +{$else} + zliblib: array[0..1] of filenamety = ('libz.so.1','libz.so'); +{$endif} + +const + ZLIB_VERSION = '1.2.7'; + ZLIB_VERNUM = $1270; + ZLIB_VER_MAJOR = 1; + ZLIB_VER_MINOR = 2; + ZLIB_VER_REVISION = 7; + ZLIB_VER_SUBREVISION = 0; + +{$ifdef FPC} + {$packrecords c} +{$else} + {$ALIGN 4} + {$MINENUMSIZE 4} +{$endif} + +type + int = cint; + uInt = cuint; + uIntf = uInt; + puIntf = ^uIntf; + + uLong = culong; + uLongf = uLong; + puLongf = ^uLongf; + + Bytef = cchar; + pBytef = ^Bytef; + + alloc_func = function(opaque: pointer; + items: uInt; size: uInt): pointer; cdecl; + free_func = procedure(opaque: pointer; address: pointer); cdecl; + + internal_state = record //opaque + end; + pinternal_state = ^internal_state; + + z_stream = record + next_in: pBytef; {/* next input byte */} + avail_in: uInt; {/* number of bytes available at next_in */} + total_in: uLong; {/* total number of input bytes read so far */} + + next_out: pBytef; {/* next output byte should be put there */} + avail_out: uInt; {/* remaining free space at next_out */} + total_out: uLong; {/* total number of bytes output so far */} + + msg: pchar; {/* last error message, NULL if no error */} + internal_state: pinternal_state; + {/* not visible by applications */} + + zalloc: alloc_func; {/* used to allocate the internal state */} + zfree: free_func; {/* used to free the internal state */} + opaque: pointer; {/* private data object passed to zalloc and zfree */} + + data_type: int; {/* best guess about the data type: binary or text */} + adler: uLong; {/* adler32 value of the uncompressed data */} + reserved: uLong; {/* reserved for future use */} + end; + pz_stream = ^z_stream; + +{/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/} + gz_header = record + text: int; {/* true if compressed data believed to be text */} + time: uLong; {/* modification time */} + xflags: int; {/* extra flags (not used when writing a gzip file) */} + os: int; {/* operating system */} + extra: pBytef; {/* pointer to extra field or Z_NULL if none */} + extra_len: uInt; {/* extra field length (valid if extra != Z_NULL) */} + extra_max: uInt; {/* space at extra (only when reading header) */} + name: pBytef; {/* pointer to zero-terminated file name or Z_NULL */} + name_max: uInt; {/* space at name (only when reading header) */} + comment: pBytef; {/* pointer to zero-terminated comment or Z_NULL */} + comm_max: uInt; {/* space at comment (only when reading header) */} + hcrc: int; {/* true if there was or will be a header crc */} + done: int; {/* true when done reading gzip header (not used + when writing a gzip file) */} + end; + pgz_header = ^gz_header; + +{/* + The application must update next_in and avail_in when avail_in has dropped + to zero. It must update next_out and avail_out when avail_out has dropped + to zero. The application must initialize zalloc, zfree and opaque before + calling the init function. All other fields are set by the compression + library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this if + the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers + returned by zalloc for objects of exactly 65536 bytes *must* have their + offset normalized to zero. The default allocation function provided by this + library ensures this (see zutil.c). To reduce memory requirements and avoid + any allocation of 64K objects, at the expense of compression ratio, compile + the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or progress + reports. After compression, total_in holds the total size of the + uncompressed data and may be saved for use in the decompressor (particularly + if the decompressor wants to decompress everything in a single step). +*/} + + {/* constants */} +const + Z_NO_FLUSH = 0; + Z_PARTIAL_FLUSH = 1; + Z_SYNC_FLUSH = 2; + Z_FULL_FLUSH = 3; + Z_FINISH = 4; + Z_BLOCK = 5; + Z_TREES = 6; +{/* Allowed flush values; see deflate() and inflate() below for details */} + + Z_OK = 0; + Z_STREAM_END = 1; + Z_NEED_DICT = 2; + Z_ERRNO = (-1); + Z_STREAM_ERROR = (-2); + Z_DATA_ERROR = (-3); + Z_MEM_ERROR = (-4); + Z_BUF_ERROR = (-5); + Z_VERSION_ERROR = (-6); +{/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */} + + Z_NO_COMPRESSION = 0; + Z_BEST_SPEED = 1; + Z_BEST_COMPRESSION = 9; + Z_DEFAULT_COMPRESSION = (-1); +{/* compression levels */} + + Z_FILTERED = 1; + Z_HUFFMAN_ONLY = 2; + Z_RLE = 3; + Z_FIXED = 4; + Z_DEFAULT_STRATEGY = 0; +{/* compression strategy; see deflateInit2() below for details */} + + Z_BINARY = 0; + Z_TEXT = 1; + Z_ASCII = Z_TEXT; {/* for compatibility with 1.2.2 and earlier */} + Z_UNKNOWN = 2; +{/* Possible values of the data_type field (though see inflate()) */} + + Z_DEFLATED = 8; +{/* The deflate compression method (the only one supported in this version) */} + + Z_NULL = 0; {/* for initializing zalloc, zfree, opaque */} + +//#define zlib_version zlibVersion() +///* for compatibility with versions < 1.0.2 */ + + + {/* basic functions */} + +function deflateInit(strm: pz_stream; level: int): int; +function deflateInit2(strm: pz_stream; level: int; method: int; + windowBits: int; memLevel: int; strategy: int): int; +function inflateInit(strm: pz_stream): int; +function inflateInit2 (strm: pz_stream; windowBits: int): int; + +var + zlibVersion: function(): pchar; cdecl; +{/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is not + compatible with the zlib.h header file used by the application. This check + is automatically made by deflateInit and inflateInit. + */} + + deflateInit_: function (strm: pz_stream; level: int; version: pchar; + stream_size: cint): cint; cdecl; +{/* + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. If + zalloc and zfree are set to Z_NULL, deflateInit updates them to use default + allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at all + (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION + requests a default compromise between speed and compression (currently + equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if level is not a valid compression level, or + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). msg is set to null + if there is no error message. deflateInit does not perform any compression: + this will be done by deflate(). +*/} + + deflateInit2_: function(strm: pz_stream; level: int; method: int; + windowBits: int; memLevel: int; strategy: int; + version: pchar; stream_size: int): int; cdecl; +{/* + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by the + caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute an adler32 check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), no + header crc, and the operating system will be set to 255 (unknown). If a + gzip stream is being written, strm->adler is a crc32 instead of an adler32. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but is + slow and reduces compression ratio; memLevel=9 uses maximum memory for + optimal speed. The default value is 8. See zconf.h for total memory usage + as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as + fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The + strategy parameter only affects the compression ratio but not the + correctness of the compressed output even if it is not set appropriately. + Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler + decoder for special applications. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid + method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is + incompatible with the version assumed by the caller (ZLIB_VERSION). msg is + set to null if there is no error message. deflateInit2 does not perform any + compression: this will be done by deflate(). +*/} + + + deflate: function(strm: pz_stream; flush: int): int; cdecl; +{/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). Some + output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating avail_in or avail_out accordingly; avail_out should + never be zero before the call. The application can consume the compressed + output when it wants, for example when the output buffer is full (avail_out + == 0), or after each call of deflate(). If deflate returns Z_OK and with + zero avail_out, it must be called again after making room in the output + buffer because there might be more output pending. + + Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to + decide how much data to accumulate before producing output, in order to + maximize compression. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In + particular avail_in is zero after the call if enough output space has been + provided before the call.) Flushing may degrade compression for some + compression algorithms and so it should be used only when necessary. This + completes the current deflate block and follows it with an empty stored block + that is three bits plus filler bits to the next byte, followed by four bytes + (00 00 ff ff). + + If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the + output buffer, but the output is not aligned to a byte boundary. All of the + input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. + This completes the current deflate block and follows it with an empty fixed + codes block that is 10 bits long. This assures that enough bytes are output + in order for the decompressor to finish the block before the empty fixed code + block. + + If flush is set to Z_BLOCK, a deflate block is completed and emitted, as + for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to + seven bits of the current block are held to be written as the next byte after + the next deflate block is completed. In this case, the decompressor may not + be provided enough bits at this point in order to complete decompression of + the data provided so far to the compressor. It may need to wait for the next + block to be emitted. This is for advanced applications that need to control + the emission of deflate blocks. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six to avoid repeated flush markers due to + avail_out == 0 on return. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there was + enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the stream + are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least the + value returned by deflateBound (see below). Then deflate is guaranteed to + return Z_STREAM_END. If not enough output space is provided, deflate will + not return Z_STREAM_END, and it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so far (that is, total_in bytes). + + deflate() may update strm->data_type if it can make a good guess about + the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered + binary. This field is only for information purposes and does not affect the + compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not + fatal, and deflate() can be called again with more input and more output + space to continue compressing. +*/} + + + deflateEnd: function(strm: pz_stream): int; cdecl; +{/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, msg + may be set but then points to a static string (which must not be + deallocated). +*/} + + inflateInit_: function(strm: pz_stream; version: pchar; + stream_size: int): int; cdecl; +{/* + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the + exact value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit() does not process any header information -- that is deferred + until inflate() is called. +*/} + + inflateInit2_: function(strm: pz_stream; windowBits: int; + version: pchar; stream_size: int): int; cdecl; +{/* + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be zero to request that inflate use the window size in + the zlib header of the compressed stream. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an adler32 or a crc32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a + crc32 instead of an adler32. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit2 does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit2() does not process any header information -- that is + deferred until inflate() is called. +*/} + + inflate: function(strm: pz_stream; flush: int): int; cdecl; +{/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing will + resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there is + no more input data or no more space in the output buffer (see below about + the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating the next_* and avail_* values accordingly. The + application can consume the uncompressed output when it wants, for example + when the output buffer is full (avail_out == 0), or after each call of + inflate(). If inflate returns Z_OK and with zero avail_out, it must be + called again after making room in the output buffer because there might be + more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, + Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() + stop if and when it gets to the next deflate block boundary. When decoding + the zlib or gzip format, this will cause inflate() to return immediately + after the header and before the first block. When doing a raw inflate, + inflate() will go ahead and process the first block, and will return when it + gets to the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + Also to assist in this, on return inflate() will set strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 if + inflate() is currently decoding the last block in the deflate stream, plus + 128 if inflate() returned immediately after decoding an end-of-block code or + decoding the complete header up to just before the first byte of the deflate + stream. The end-of-block will not be indicated until all of the uncompressed + data from that block has been written to strm->next_out. The number of + unused bits may in general be greater than seven, except when bit 7 of + data_type is set, in which case the number of unused bits will be less than + eight. data_type is set as noted here every time inflate() returns for all + flush options, and so can be used to determine the amount of currently + consumed input in bits. + + The Z_TREES option behaves as Z_BLOCK does, but it also returns when the + end of each deflate block header is reached, before any actual data in that + block is decoded. This allows the caller to determine the length of the + deflate block header for later use in random access within a deflate block. + 256 is added to the value of strm->data_type when inflate() returns + immediately after reaching the end of the deflate block header. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step (a + single call of inflate), the parameter flush should be set to Z_FINISH. In + this case all pending input is processed and all pending output is flushed; + avail_out must be large enough to hold all of the uncompressed data for the + operation to complete. (The size of the uncompressed data may have been + saved by the compressor for this purpose.) The use of Z_FINISH is not + required to perform an inflation in one step. However it may be used to + inform inflate that a faster approach can be used for the single inflate() + call. Z_FINISH also informs inflate to not maintain a sliding window if the + stream completes, which reduces inflate's memory footprint. If the stream + does not complete, either because not all of the stream is provided or not + enough output space is provided, then a sliding window will be allocated and + inflate() can be called again to continue the operation as if Z_NO_FLUSH had + been used. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the effects of the flush parameter in this implementation are + on the return value of inflate() as noted below, when inflate() returns early + when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of + memory for a sliding window when Z_FINISH is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the Adler-32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the Adler-32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed adler32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() can decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically, if requested when + initializing with inflateInit2(). Any information contained in the gzip + header is not retained, so applications that need that information should + instead use raw inflate, see inflateInit2() below, or inflateBack() and + perform their own processing of the gzip header and trailer. When processing + gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output + producted so far. The CRC-32 is checked against the gzip trailer. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value), Z_STREAM_ERROR if the stream structure was inconsistent (for example + next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory, + Z_BUF_ERROR if no progress is possible or if there was not enough room in the + output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may + then call inflateSync() to look for a good compression block if a partial + recovery of the data is desired. +*/} + + inflateEnd: function(strm: pz_stream): int; cdecl; +{/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/} + +procedure initializezlib(const sonames: array of filenamety); + //[] = default +procedure initzlib; //calls initializezlib once +procedure releasezlib; + +implementation +uses + msesystypes,{$ifdef FPC}dynlibs,{$endif}msesysintf1,msesysintf; +var + libinfo: dynlibinfoty; + +function deflateInit(strm: pz_stream; level: int): int; +begin + result:= deflateInit_(strm,level,ZLIB_VERSION, sizeof(z_stream)); +end; + +function deflateInit2(strm: pz_stream; level: int; method: int; + windowBits: int; memLevel: int; strategy: int): int; +begin + result:= deflateInit2_(strm,level,method,windowBits,memLevel,strategy, + ZLIB_VERSION, sizeof(z_stream)); +end; + +function inflateInit(strm: pz_stream): int; +begin + result:= inflateInit_(strm,ZLIB_VERSION, sizeof(z_stream)); +end; + +function inflateInit2 (strm: pz_stream; windowBits: int): int; +begin + result:= inflateInit2_(strm,windowBits,ZLIB_VERSION, sizeof(z_stream)); +end; + +procedure initializezlib(const sonames: array of filenamety); + //[] = default +const + errormessage = 'Can not load OpenSSL library, '; + funcs: array[0..8] of funcinfoty = ( + (n: 'zlibVersion'; d: {$ifndef FPC}@{$endif}@zlibVersion), + (n: 'deflateInit_'; d: {$ifndef FPC}@{$endif}@deflateInit_), + (n: 'deflateInit2_'; d: {$ifndef FPC}@{$endif}@deflateInit2_), + (n: 'deflate'; d: {$ifndef FPC}@{$endif}@deflate), + (n: 'deflateEnd'; d: {$ifndef FPC}@{$endif}@deflateEnd), + (n: 'inflateInit_'; d: {$ifndef FPC}@{$endif}@inflateInit_), + (n: 'inflateInit2_'; d: {$ifndef FPC}@{$endif}@inflateInit2_), + (n: 'inflate'; d: {$ifndef FPC}@{$endif}@inflate), + (n: 'inflateEnd'; d: {$ifndef FPC}@{$endif}@inflateEnd) + ); + +begin + initializedynlib(libinfo,sonames,zliblib,funcs,[],errormessage); +end; + +procedure releasezlib; +begin + releasedynlib(libinfo); +end; + +var + libloaded: boolean; + +procedure initzlib; //calls initializezlib once +begin + if not libloaded then begin + initializezlib([]); + libloaded:= true; + end; +end; + +initialization + initializelibinfo(libinfo); +finalization + if libloaded then begin + releasezlib; + end; + finalizelibinfo(libinfo); +end. diff --git a/mseide-msegui/lib/common/crypto/msezstream.pas b/mseide-msegui/lib/common/crypto/msezstream.pas new file mode 100644 index 0000000..892b378 --- /dev/null +++ b/mseide-msegui/lib/common/crypto/msezstream.pas @@ -0,0 +1,309 @@ +{ MSEgui Copyright (c) 2012-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msezstream; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,msezlib,msecryptohandler,msestream,mseclasses, + msetypes{msestrings}; + +const + defaultzstreambuffersize = 16384; + minzstreambuffersize = 256; + +type + zstreamstatety = (zs_inflate,zs_inited,zs_fileeof); + zstreamstatesty = set of zstreamstatety; + + zstreamhandlerdatadty = record + strm: pz_stream; + buf: pbyte; + bufsize: integer; + state: zstreamstatesty; + end; + pzstreamhandlerdatadty = ^zstreamhandlerdatadty; + {$if sizeof(zstreamhandlerdatadty) > sizeof(cryptohandlerdataty)} + {$error 'buffer overflow'} + {$ifend} + zstreamhandlerdataty = record + case integer of + 0: (d: zstreamhandlerdatadty;); + 1: (_bufferspace: cryptohandlerdataty;); + end; + + tzstreamhandler = class(tbasecryptohandler) + private + fcompressionlevel: integer; + fbuffersize: integer; + procedure setbuffersize(avalue: integer); + protected + procedure internalflush(var aclient: cryptoclientinfoty; + const mode: integer); + procedure flush(var aclient: cryptoclientinfoty); override; + procedure checkinflate(var aclient: cryptoclientinfoty); + {$ifdef FPC}inline;{$endif} + procedure checknoinflate(var aclient: cryptoclientinfoty); + {$ifdef FPC}inline;{$endif} + function writedeflate(var aclient: cryptoclientinfoty; + const aflush: integer): boolean; + procedure open(var aclient: cryptoclientinfoty); override; + procedure close(var aclient: cryptoclientinfoty); override; + procedure checkerror(const aclient: cryptoclientinfoty; + const aerror: integer); reintroduce; + function read(var aclient: cryptoclientinfoty; + var buffer; count: longint): longint; override; + function write(var aclient: cryptoclientinfoty; + const buffer; count: longint): longint; override; + function seek(var aclient: cryptoclientinfoty; + const offset: int64; origin: tseekorigin): int64; override; + public + constructor create(aowner: tcomponent); override; + procedure flush(const astream: tmsefilestream; + const mode: integer = Z_SYNC_FLUSH); overload; + published + property compressionlevel: integer read fcompressionlevel + write fcompressionlevel default Z_DEFAULT_COMPRESSION; + property buffersize: integer read fbuffersize write setbuffersize + default defaultzstreambuffersize; + + end; + +implementation +uses + msesys,mseapplication; + +{ tzstreamhandler } + +constructor tzstreamhandler.create(aowner: tcomponent); +begin + fcompressionlevel:= Z_DEFAULT_COMPRESSION; + fbuffersize:= defaultzstreambuffersize; + inherited; +end; + +procedure tzstreamhandler.checkinflate(var aclient: cryptoclientinfoty); +begin + with zstreamhandlerdataty(aclient.handlerdata).d do begin + if not (zs_inflate in state) then begin + error(cerr_wrongdatadirection); + end; + end; +end; + +procedure tzstreamhandler.checknoinflate(var aclient: cryptoclientinfoty); +begin + with zstreamhandlerdataty(aclient.handlerdata).d do begin + if (zs_inflate in state) then begin + error(cerr_wrongdatadirection); + end; + end; +end; + +procedure tzstreamhandler.open(var aclient: cryptoclientinfoty); +begin + if not (aclient.stream.openmode in [fm_read,fm_create,fm_write]) then begin + error(cerr_invalidopenmode); + end; + initzlib; + inherited; + with zstreamhandlerdataty(aclient.handlerdata).d do begin + getmem(strm,sizeof(z_stream)); + getmem(buf,fbuffersize); + bufsize:= fbuffersize; + if aclient.stream.openmode in [fm_read] then begin + include(state,zs_inflate); + end; + with strm^ do begin + zalloc:= nil; + zfree:= nil; + opaque:= nil; + end; + if zs_inflate in state then begin + inflateinit(strm); + include(state,zs_inited); + strm^.next_in:= nil; + strm^.avail_in:= 0; + end + else begin + deflateinit(strm,fcompressionlevel); + include(state,zs_inited); + end; + end; +end; + +procedure tzstreamhandler.close(var aclient: cryptoclientinfoty); +begin + with zstreamhandlerdataty(aclient.handlerdata).d do begin + if strm <> nil then begin + if zs_inited in state then begin + if zs_inflate in state then begin + inflateend(strm); + end + else begin + strm^.next_in:= nil; + strm^.avail_in:= 0; + try + if not writedeflate(aclient,Z_FINISH) then begin + writeerror(aclient); + end; + except + application.handleexception; + end; + deflateend(strm); + end; + end; + freemem(strm); + strm:= nil; + end; + if buf <> nil then begin + freemem(buf); + buf:= nil; + end; + state:= []; + end; + inherited; +end; + +procedure tzstreamhandler.checkerror(const aclient: cryptoclientinfoty; + const aerror: integer); +begin + if aerror < 0 then begin + with zstreamhandlerdataty(aclient.handlerdata).d do begin + componentexception(self,msestring(string(strm^.msg))); + end; + end; +end; + +function tzstreamhandler.read(var aclient: cryptoclientinfoty; var buffer; + count: longint): longint; +var + po1: pbyte; + int1: integer; +begin + checkinflate(aclient); + result:= 0; + po1:= @buffer; + with zstreamhandlerdataty(aclient.handlerdata).d do begin + while true do begin + if not (zs_fileeof in state) and (strm^.avail_in = 0) then begin + strm^.next_in:= pointer(buf); + strm^.avail_in:= inherited read(aclient,buf^,bufsize); + if strm^.avail_in < bufsize then begin + include(state,zs_fileeof); + end; + end; + strm^.avail_out:= count-result; + if strm^.avail_out <= 0 then begin + break; + end; + strm^.next_out:= pointer(po1); + checkerror(aclient,inflate(strm,z_no_flush)); + int1:= pchar(pointer(strm^.next_out)) - pchar(po1); + if (int1 = 0) and (zs_fileeof in state) and (strm^.avail_in = 0) then begin + break; + end; + result:= result + int1; + po1:= pointer(strm^.next_out); + end; + end; +end; + +function tzstreamhandler.writedeflate(var aclient: cryptoclientinfoty; + const aflush: integer): boolean; +var + int1: integer; +begin + result:= true; + with zstreamhandlerdataty(aclient.handlerdata).d do begin + while true do begin + strm^.next_out:= pointer(buf); + strm^.avail_out:= bufsize; + deflate(strm,aflush); + int1:= pchar(pointer(strm^.next_out)) - pchar(buf); + if int1 = 0 then begin + break; + end; + if result then begin + if inherited write(aclient,buf^,int1) <> int1 then begin + result:= false; //can not write + end; + end; + end; + end; +end; + +function tzstreamhandler.write(var aclient: cryptoclientinfoty; const buffer; + count: longint): longint; +//var +// int1: integer; +begin + checknoinflate(aclient); + result:= count; + with zstreamhandlerdataty(aclient.handlerdata).d do begin + if count > 0 then begin + with strm^ do begin + next_in:= @buffer; + avail_in:= count; + if not writedeflate(aclient,z_no_flush) then begin + result:= 0; //can not write + end; + end; + end; + end; +end; + +procedure tzstreamhandler.internalflush(var aclient: cryptoclientinfoty; + const mode: integer); +begin + with zstreamhandlerdataty(aclient.handlerdata).d do begin + if not (zs_inflate in state) then begin + strm^.next_in:= nil; + strm^.avail_in:= 0; + if not writedeflate(aclient,mode) then begin + writeerror(aclient); + end; + end; + end; +end; + +procedure tzstreamhandler.flush(var aclient: cryptoclientinfoty); +begin + internalflush(aclient,Z_SYNC_FLUSH); +end; + +procedure tzstreamhandler.flush(const astream: tmsefilestream; + const mode: integer = Z_SYNC_FLUSH); +var + po1: pcryptoclientinfoty; +begin + po1:= getclient(astream); + if ccs_open in po1^.state then begin + internalflush(po1^,mode); + end; +end; + +procedure tzstreamhandler.setbuffersize(avalue: integer); +begin + if avalue < minzstreambuffersize then begin + avalue:= minzstreambuffersize; + end; + fbuffersize:= avalue; +end; + +function tzstreamhandler.seek(var aclient: cryptoclientinfoty; + const offset: int64; origin: tseekorigin): int64; +begin + if (origin <> socurrent) or (offset <> 0) then begin + error(cerr_notseekable); + end; + result:= inherited seek(aclient,offset,origin); +end; + +end. diff --git a/mseide-msegui/lib/common/db/firebird.pas b/mseide-msegui/lib/common/db/firebird.pas new file mode 100644 index 0000000..68bdc87 --- /dev/null +++ b/mseide-msegui/lib/common/db/firebird.pas @@ -0,0 +1,12993 @@ +{ This file was autogenerated by cloop - Cross Language Object Oriented Programming } +{$ifdef fpc} {$mode delphi} {$endif} +unit firebird; + +interface + +uses classes, sysUtils; + +type +{$IFNDEF FPC} + QWord = UInt64; +{$ENDIF} + + IVersioned = class; + IReferenceCounted = class; + IDisposable = class; + IStatus = class; + IMaster = class; + IPluginBase = class; + IPluginSet = class; + IConfigEntry = class; + IConfig = class; + IFirebirdConf = class; + IPluginConfig = class; + IPluginFactory = class; + IPluginModule = class; + IPluginManager = class; + ICryptKey = class; + IConfigManager = class; + IEventCallback = class; + IBlob = class; + ITransaction = class; + IMessageMetadata = class; + IMetadataBuilder = class; + IResultSet = class; + IStatement = class; + IRequest = class; + IEvents = class; + IAttachment = class; + IService = class; + IProvider = class; + IDtcStart = class; + IDtc = class; + IAuth = class; + IWriter = class; + IServerBlock = class; + IClientBlock = class; + IServer = class; + IClient = class; + IUserField = class; + ICharUserField = class; + IIntUserField = class; + IUser = class; + IListUsers = class; + ILogonInfo = class; + IManagement = class; + IWireCryptPlugin = class; + ICryptKeyCallback = class; + IKeyHolderPlugin = class; + IDbCryptPlugin = class; + IExternalContext = class; + IExternalResultSet = class; + IExternalFunction = class; + IExternalProcedure = class; + IExternalTrigger = class; + IRoutineMetadata = class; + IExternalEngine = class; + ITimer = class; + ITimerControl = class; + IVersionCallback = class; + IUtil = class; + IOffsetsCallback = class; + IXpbBuilder = class; + ITraceConnection = class; + ITraceDatabaseConnection = class; + ITraceTransaction = class; + ITraceParams = class; + ITraceStatement = class; + ITraceSQLStatement = class; + ITraceBLRStatement = class; + ITraceDYNRequest = class; + ITraceContextVariable = class; + ITraceProcedure = class; + ITraceFunction = class; + ITraceTrigger = class; + ITraceServiceConnection = class; + ITraceStatusVector = class; + ITraceSweepInfo = class; + ITraceLogWriter = class; + ITraceInitInfo = class; + ITracePlugin = class; + ITraceFactory = class; + IUdrFunctionFactory = class; + IUdrProcedureFactory = class; + IUdrTriggerFactory = class; + IUdrPlugin = class; + + FbException = class(Exception) + public + constructor create(status: IStatus); virtual; + destructor Destroy(); override; + + function getStatus: IStatus; + + class procedure checkException(status: IStatus); + class procedure catchException(status: IStatus; e: Exception); + + private + status: IStatus; + end; + + ISC_DATE = Integer; + ISC_TIME = Integer; + ISC_QUAD = array [1..2] of Integer; + + ntrace_relation_t = Integer; + TraceCounts = Record + trc_relation_id : ntrace_relation_t; + trc_relation_name : PAnsiChar; + trc_counters : ^Int64; + end; + TraceCountsPtr = ^TraceCounts; + PerformanceInfo = Record + pin_time : Int64; + pin_counters : ^Int64; + pin_count : NativeUInt; + pin_tables : TraceCountsPtr; + pin_records_fetched : Int64; + end; + + Dsc = Record + dsc_dtype, dsc_scale: Byte; + dsc_length, dsc_sub_type, dsc_flags: Int16; + dsc_address: ^Byte; + end; + BooleanPtr = ^Boolean; + BytePtr = ^Byte; + CardinalPtr = ^Cardinal; + IKeyHolderPluginPtr = ^IKeyHolderPlugin; + ISC_QUADPtr = ^ISC_QUAD; + Int64Ptr = ^Int64; + NativeIntPtr = ^NativeInt; + PerformanceInfoPtr = ^PerformanceInfo; + dscPtr = ^dsc; + + IReferenceCounted_addRefPtr = procedure(this: IReferenceCounted); cdecl; + IReferenceCounted_releasePtr = function(this: IReferenceCounted): Integer; cdecl; + IDisposable_disposePtr = procedure(this: IDisposable); cdecl; + IStatus_initPtr = procedure(this: IStatus); cdecl; + IStatus_getStatePtr = function(this: IStatus): Cardinal; cdecl; + IStatus_setErrors2Ptr = procedure(this: IStatus; length: Cardinal; value: NativeIntPtr); cdecl; + IStatus_setWarnings2Ptr = procedure(this: IStatus; length: Cardinal; value: NativeIntPtr); cdecl; + IStatus_setErrorsPtr = procedure(this: IStatus; value: NativeIntPtr); cdecl; + IStatus_setWarningsPtr = procedure(this: IStatus; value: NativeIntPtr); cdecl; + IStatus_getErrorsPtr = function(this: IStatus): NativeIntPtr; cdecl; + IStatus_getWarningsPtr = function(this: IStatus): NativeIntPtr; cdecl; + IStatus_clonePtr = function(this: IStatus): IStatus; cdecl; + IMaster_getStatusPtr = function(this: IMaster): IStatus; cdecl; + IMaster_getDispatcherPtr = function(this: IMaster): IProvider; cdecl; + IMaster_getPluginManagerPtr = function(this: IMaster): IPluginManager; cdecl; + IMaster_getTimerControlPtr = function(this: IMaster): ITimerControl; cdecl; + IMaster_getDtcPtr = function(this: IMaster): IDtc; cdecl; + IMaster_registerAttachmentPtr = function(this: IMaster; provider: IProvider; attachment: IAttachment): IAttachment; cdecl; + IMaster_registerTransactionPtr = function(this: IMaster; attachment: IAttachment; transaction: ITransaction): ITransaction; cdecl; + IMaster_getMetadataBuilderPtr = function(this: IMaster; status: IStatus; fieldCount: Cardinal): IMetadataBuilder; cdecl; + IMaster_serverModePtr = function(this: IMaster; mode: Integer): Integer; cdecl; + IMaster_getUtilInterfacePtr = function(this: IMaster): IUtil; cdecl; + IMaster_getConfigManagerPtr = function(this: IMaster): IConfigManager; cdecl; + IMaster_getProcessExitingPtr = function(this: IMaster): Boolean; cdecl; + IPluginBase_setOwnerPtr = procedure(this: IPluginBase; r: IReferenceCounted); cdecl; + IPluginBase_getOwnerPtr = function(this: IPluginBase): IReferenceCounted; cdecl; + IPluginSet_getNamePtr = function(this: IPluginSet): PAnsiChar; cdecl; + IPluginSet_getModuleNamePtr = function(this: IPluginSet): PAnsiChar; cdecl; + IPluginSet_getPluginPtr = function(this: IPluginSet; status: IStatus): IPluginBase; cdecl; + IPluginSet_nextPtr = procedure(this: IPluginSet; status: IStatus); cdecl; + IPluginSet_set_Ptr = procedure(this: IPluginSet; status: IStatus; s: PAnsiChar); cdecl; + IConfigEntry_getNamePtr = function(this: IConfigEntry): PAnsiChar; cdecl; + IConfigEntry_getValuePtr = function(this: IConfigEntry): PAnsiChar; cdecl; + IConfigEntry_getIntValuePtr = function(this: IConfigEntry): Int64; cdecl; + IConfigEntry_getBoolValuePtr = function(this: IConfigEntry): Boolean; cdecl; + IConfigEntry_getSubConfigPtr = function(this: IConfigEntry; status: IStatus): IConfig; cdecl; + IConfig_findPtr = function(this: IConfig; status: IStatus; name: PAnsiChar): IConfigEntry; cdecl; + IConfig_findValuePtr = function(this: IConfig; status: IStatus; name: PAnsiChar; value: PAnsiChar): IConfigEntry; cdecl; + IConfig_findPosPtr = function(this: IConfig; status: IStatus; name: PAnsiChar; pos: Cardinal): IConfigEntry; cdecl; + IFirebirdConf_getKeyPtr = function(this: IFirebirdConf; name: PAnsiChar): Cardinal; cdecl; + IFirebirdConf_asIntegerPtr = function(this: IFirebirdConf; key: Cardinal): Int64; cdecl; + IFirebirdConf_asStringPtr = function(this: IFirebirdConf; key: Cardinal): PAnsiChar; cdecl; + IFirebirdConf_asBooleanPtr = function(this: IFirebirdConf; key: Cardinal): Boolean; cdecl; + IPluginConfig_getConfigFileNamePtr = function(this: IPluginConfig): PAnsiChar; cdecl; + IPluginConfig_getDefaultConfigPtr = function(this: IPluginConfig; status: IStatus): IConfig; cdecl; + IPluginConfig_getFirebirdConfPtr = function(this: IPluginConfig; status: IStatus): IFirebirdConf; cdecl; + IPluginConfig_setReleaseDelayPtr = procedure(this: IPluginConfig; status: IStatus; microSeconds: QWord); cdecl; + IPluginFactory_createPluginPtr = function(this: IPluginFactory; status: IStatus; factoryParameter: IPluginConfig): IPluginBase; cdecl; + IPluginModule_doCleanPtr = procedure(this: IPluginModule); cdecl; + IPluginManager_registerPluginFactoryPtr = procedure(this: IPluginManager; pluginType: Cardinal; defaultName: PAnsiChar; factory: IPluginFactory); cdecl; + IPluginManager_registerModulePtr = procedure(this: IPluginManager; cleanup: IPluginModule); cdecl; + IPluginManager_unregisterModulePtr = procedure(this: IPluginManager; cleanup: IPluginModule); cdecl; + IPluginManager_getPluginsPtr = function(this: IPluginManager; status: IStatus; pluginType: Cardinal; namesList: PAnsiChar; firebirdConf: IFirebirdConf): IPluginSet; cdecl; + IPluginManager_getConfigPtr = function(this: IPluginManager; status: IStatus; filename: PAnsiChar): IConfig; cdecl; + IPluginManager_releasePluginPtr = procedure(this: IPluginManager; plugin: IPluginBase); cdecl; + ICryptKey_setSymmetricPtr = procedure(this: ICryptKey; status: IStatus; type_: PAnsiChar; keyLength: Cardinal; key: Pointer); cdecl; + ICryptKey_setAsymmetricPtr = procedure(this: ICryptKey; status: IStatus; type_: PAnsiChar; encryptKeyLength: Cardinal; encryptKey: Pointer; decryptKeyLength: Cardinal; decryptKey: Pointer); cdecl; + ICryptKey_getEncryptKeyPtr = function(this: ICryptKey; length: CardinalPtr): Pointer; cdecl; + ICryptKey_getDecryptKeyPtr = function(this: ICryptKey; length: CardinalPtr): Pointer; cdecl; + IConfigManager_getDirectoryPtr = function(this: IConfigManager; code: Cardinal): PAnsiChar; cdecl; + IConfigManager_getFirebirdConfPtr = function(this: IConfigManager): IFirebirdConf; cdecl; + IConfigManager_getDatabaseConfPtr = function(this: IConfigManager; dbName: PAnsiChar): IFirebirdConf; cdecl; + IConfigManager_getPluginConfigPtr = function(this: IConfigManager; configuredPlugin: PAnsiChar): IConfig; cdecl; + IConfigManager_getInstallDirectoryPtr = function(this: IConfigManager): PAnsiChar; cdecl; + IConfigManager_getRootDirectoryPtr = function(this: IConfigManager): PAnsiChar; cdecl; + IEventCallback_eventCallbackFunctionPtr = procedure(this: IEventCallback; length: Cardinal; events: BytePtr); cdecl; + IBlob_getInfoPtr = procedure(this: IBlob; status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); cdecl; + IBlob_getSegmentPtr = function(this: IBlob; status: IStatus; bufferLength: Cardinal; buffer: Pointer; segmentLength: CardinalPtr): Integer; cdecl; + IBlob_putSegmentPtr = procedure(this: IBlob; status: IStatus; length: Cardinal; buffer: Pointer); cdecl; + IBlob_cancelPtr = procedure(this: IBlob; status: IStatus); cdecl; + IBlob_closePtr = procedure(this: IBlob; status: IStatus); cdecl; + IBlob_seekPtr = function(this: IBlob; status: IStatus; mode: Integer; offset: Integer): Integer; cdecl; + ITransaction_getInfoPtr = procedure(this: ITransaction; status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); cdecl; + ITransaction_preparePtr = procedure(this: ITransaction; status: IStatus; msgLength: Cardinal; message: BytePtr); cdecl; + ITransaction_commitPtr = procedure(this: ITransaction; status: IStatus); cdecl; + ITransaction_commitRetainingPtr = procedure(this: ITransaction; status: IStatus); cdecl; + ITransaction_rollbackPtr = procedure(this: ITransaction; status: IStatus); cdecl; + ITransaction_rollbackRetainingPtr = procedure(this: ITransaction; status: IStatus); cdecl; + ITransaction_disconnectPtr = procedure(this: ITransaction; status: IStatus); cdecl; + ITransaction_joinPtr = function(this: ITransaction; status: IStatus; transaction: ITransaction): ITransaction; cdecl; + ITransaction_validatePtr = function(this: ITransaction; status: IStatus; attachment: IAttachment): ITransaction; cdecl; + ITransaction_enterDtcPtr = function(this: ITransaction; status: IStatus): ITransaction; cdecl; + IMessageMetadata_getCountPtr = function(this: IMessageMetadata; status: IStatus): Cardinal; cdecl; + IMessageMetadata_getFieldPtr = function(this: IMessageMetadata; status: IStatus; index: Cardinal): PAnsiChar; cdecl; + IMessageMetadata_getRelationPtr = function(this: IMessageMetadata; status: IStatus; index: Cardinal): PAnsiChar; cdecl; + IMessageMetadata_getOwnerPtr = function(this: IMessageMetadata; status: IStatus; index: Cardinal): PAnsiChar; cdecl; + IMessageMetadata_getAliasPtr = function(this: IMessageMetadata; status: IStatus; index: Cardinal): PAnsiChar; cdecl; + IMessageMetadata_getTypePtr = function(this: IMessageMetadata; status: IStatus; index: Cardinal): Cardinal; cdecl; + IMessageMetadata_isNullablePtr = function(this: IMessageMetadata; status: IStatus; index: Cardinal): Boolean; cdecl; + IMessageMetadata_getSubTypePtr = function(this: IMessageMetadata; status: IStatus; index: Cardinal): Integer; cdecl; + IMessageMetadata_getLengthPtr = function(this: IMessageMetadata; status: IStatus; index: Cardinal): Cardinal; cdecl; + IMessageMetadata_getScalePtr = function(this: IMessageMetadata; status: IStatus; index: Cardinal): Integer; cdecl; + IMessageMetadata_getCharSetPtr = function(this: IMessageMetadata; status: IStatus; index: Cardinal): Cardinal; cdecl; + IMessageMetadata_getOffsetPtr = function(this: IMessageMetadata; status: IStatus; index: Cardinal): Cardinal; cdecl; + IMessageMetadata_getNullOffsetPtr = function(this: IMessageMetadata; status: IStatus; index: Cardinal): Cardinal; cdecl; + IMessageMetadata_getBuilderPtr = function(this: IMessageMetadata; status: IStatus): IMetadataBuilder; cdecl; + IMessageMetadata_getMessageLengthPtr = function(this: IMessageMetadata; status: IStatus): Cardinal; cdecl; + IMetadataBuilder_setTypePtr = procedure(this: IMetadataBuilder; status: IStatus; index: Cardinal; type_: Cardinal); cdecl; + IMetadataBuilder_setSubTypePtr = procedure(this: IMetadataBuilder; status: IStatus; index: Cardinal; subType: Integer); cdecl; + IMetadataBuilder_setLengthPtr = procedure(this: IMetadataBuilder; status: IStatus; index: Cardinal; length: Cardinal); cdecl; + IMetadataBuilder_setCharSetPtr = procedure(this: IMetadataBuilder; status: IStatus; index: Cardinal; charSet: Cardinal); cdecl; + IMetadataBuilder_setScalePtr = procedure(this: IMetadataBuilder; status: IStatus; index: Cardinal; scale: Cardinal); cdecl; + IMetadataBuilder_truncatePtr = procedure(this: IMetadataBuilder; status: IStatus; count: Cardinal); cdecl; + IMetadataBuilder_moveNameToIndexPtr = procedure(this: IMetadataBuilder; status: IStatus; name: PAnsiChar; index: Cardinal); cdecl; + IMetadataBuilder_removePtr = procedure(this: IMetadataBuilder; status: IStatus; index: Cardinal); cdecl; + IMetadataBuilder_addFieldPtr = function(this: IMetadataBuilder; status: IStatus): Cardinal; cdecl; + IMetadataBuilder_getMetadataPtr = function(this: IMetadataBuilder; status: IStatus): IMessageMetadata; cdecl; + IResultSet_fetchNextPtr = function(this: IResultSet; status: IStatus; message: Pointer): Integer; cdecl; + IResultSet_fetchPriorPtr = function(this: IResultSet; status: IStatus; message: Pointer): Integer; cdecl; + IResultSet_fetchFirstPtr = function(this: IResultSet; status: IStatus; message: Pointer): Integer; cdecl; + IResultSet_fetchLastPtr = function(this: IResultSet; status: IStatus; message: Pointer): Integer; cdecl; + IResultSet_fetchAbsolutePtr = function(this: IResultSet; status: IStatus; position: Integer; message: Pointer): Integer; cdecl; + IResultSet_fetchRelativePtr = function(this: IResultSet; status: IStatus; offset: Integer; message: Pointer): Integer; cdecl; + IResultSet_isEofPtr = function(this: IResultSet; status: IStatus): Boolean; cdecl; + IResultSet_isBofPtr = function(this: IResultSet; status: IStatus): Boolean; cdecl; + IResultSet_getMetadataPtr = function(this: IResultSet; status: IStatus): IMessageMetadata; cdecl; + IResultSet_closePtr = procedure(this: IResultSet; status: IStatus); cdecl; + IResultSet_setDelayedOutputFormatPtr = procedure(this: IResultSet; status: IStatus; format: IMessageMetadata); cdecl; + IStatement_getInfoPtr = procedure(this: IStatement; status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); cdecl; + IStatement_getTypePtr = function(this: IStatement; status: IStatus): Cardinal; cdecl; + IStatement_getPlanPtr = function(this: IStatement; status: IStatus; detailed: Boolean): PAnsiChar; cdecl; + IStatement_getAffectedRecordsPtr = function(this: IStatement; status: IStatus): QWord; cdecl; + IStatement_getInputMetadataPtr = function(this: IStatement; status: IStatus): IMessageMetadata; cdecl; + IStatement_getOutputMetadataPtr = function(this: IStatement; status: IStatus): IMessageMetadata; cdecl; + IStatement_executePtr = function(this: IStatement; status: IStatus; transaction: ITransaction; inMetadata: IMessageMetadata; inBuffer: Pointer; outMetadata: IMessageMetadata; outBuffer: Pointer): ITransaction; cdecl; + IStatement_openCursorPtr = function(this: IStatement; status: IStatus; transaction: ITransaction; inMetadata: IMessageMetadata; inBuffer: Pointer; outMetadata: IMessageMetadata; flags: Cardinal): IResultSet; cdecl; + IStatement_setCursorNamePtr = procedure(this: IStatement; status: IStatus; name: PAnsiChar); cdecl; + IStatement_freePtr = procedure(this: IStatement; status: IStatus); cdecl; + IStatement_getFlagsPtr = function(this: IStatement; status: IStatus): Cardinal; cdecl; + IRequest_receivePtr = procedure(this: IRequest; status: IStatus; level: Integer; msgType: Cardinal; length: Cardinal; message: BytePtr); cdecl; + IRequest_sendPtr = procedure(this: IRequest; status: IStatus; level: Integer; msgType: Cardinal; length: Cardinal; message: BytePtr); cdecl; + IRequest_getInfoPtr = procedure(this: IRequest; status: IStatus; level: Integer; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); cdecl; + IRequest_startPtr = procedure(this: IRequest; status: IStatus; tra: ITransaction; level: Integer); cdecl; + IRequest_startAndSendPtr = procedure(this: IRequest; status: IStatus; tra: ITransaction; level: Integer; msgType: Cardinal; length: Cardinal; message: BytePtr); cdecl; + IRequest_unwindPtr = procedure(this: IRequest; status: IStatus; level: Integer); cdecl; + IRequest_freePtr = procedure(this: IRequest; status: IStatus); cdecl; + IEvents_cancelPtr = procedure(this: IEvents; status: IStatus); cdecl; + IAttachment_getInfoPtr = procedure(this: IAttachment; status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); cdecl; + IAttachment_startTransactionPtr = function(this: IAttachment; status: IStatus; tpbLength: Cardinal; tpb: BytePtr): ITransaction; cdecl; + IAttachment_reconnectTransactionPtr = function(this: IAttachment; status: IStatus; length: Cardinal; id: BytePtr): ITransaction; cdecl; + IAttachment_compileRequestPtr = function(this: IAttachment; status: IStatus; blrLength: Cardinal; blr: BytePtr): IRequest; cdecl; + IAttachment_transactRequestPtr = procedure(this: IAttachment; status: IStatus; transaction: ITransaction; blrLength: Cardinal; blr: BytePtr; inMsgLength: Cardinal; inMsg: BytePtr; outMsgLength: Cardinal; outMsg: BytePtr); cdecl; + IAttachment_createBlobPtr = function(this: IAttachment; status: IStatus; transaction: ITransaction; id: ISC_QUADPtr; bpbLength: Cardinal; bpb: BytePtr): IBlob; cdecl; + IAttachment_openBlobPtr = function(this: IAttachment; status: IStatus; transaction: ITransaction; id: ISC_QUADPtr; bpbLength: Cardinal; bpb: BytePtr): IBlob; cdecl; + IAttachment_getSlicePtr = function(this: IAttachment; status: IStatus; transaction: ITransaction; id: ISC_QUADPtr; sdlLength: Cardinal; sdl: BytePtr; paramLength: Cardinal; param: BytePtr; sliceLength: Integer; slice: BytePtr): Integer; cdecl; + IAttachment_putSlicePtr = procedure(this: IAttachment; status: IStatus; transaction: ITransaction; id: ISC_QUADPtr; sdlLength: Cardinal; sdl: BytePtr; paramLength: Cardinal; param: BytePtr; sliceLength: Integer; slice: BytePtr); cdecl; + IAttachment_executeDynPtr = procedure(this: IAttachment; status: IStatus; transaction: ITransaction; length: Cardinal; dyn: BytePtr); cdecl; + IAttachment_preparePtr = function(this: IAttachment; status: IStatus; tra: ITransaction; stmtLength: Cardinal; sqlStmt: PAnsiChar; dialect: Cardinal; flags: Cardinal): IStatement; cdecl; + IAttachment_executePtr = function(this: IAttachment; status: IStatus; transaction: ITransaction; stmtLength: Cardinal; sqlStmt: PAnsiChar; dialect: Cardinal; inMetadata: IMessageMetadata; inBuffer: Pointer; outMetadata: IMessageMetadata; outBuffer: Pointer): ITransaction; cdecl; + IAttachment_openCursorPtr = function(this: IAttachment; status: IStatus; transaction: ITransaction; stmtLength: Cardinal; sqlStmt: PAnsiChar; dialect: Cardinal; inMetadata: IMessageMetadata; inBuffer: Pointer; outMetadata: IMessageMetadata; cursorName: PAnsiChar; cursorFlags: Cardinal): IResultSet; cdecl; + IAttachment_queEventsPtr = function(this: IAttachment; status: IStatus; callback: IEventCallback; length: Cardinal; events: BytePtr): IEvents; cdecl; + IAttachment_cancelOperationPtr = procedure(this: IAttachment; status: IStatus; option: Integer); cdecl; + IAttachment_pingPtr = procedure(this: IAttachment; status: IStatus); cdecl; + IAttachment_detachPtr = procedure(this: IAttachment; status: IStatus); cdecl; + IAttachment_dropDatabasePtr = procedure(this: IAttachment; status: IStatus); cdecl; + IService_detachPtr = procedure(this: IService; status: IStatus); cdecl; + IService_queryPtr = procedure(this: IService; status: IStatus; sendLength: Cardinal; sendItems: BytePtr; receiveLength: Cardinal; receiveItems: BytePtr; bufferLength: Cardinal; buffer: BytePtr); cdecl; + IService_startPtr = procedure(this: IService; status: IStatus; spbLength: Cardinal; spb: BytePtr); cdecl; + IProvider_attachDatabasePtr = function(this: IProvider; status: IStatus; fileName: PAnsiChar; dpbLength: Cardinal; dpb: BytePtr): IAttachment; cdecl; + IProvider_createDatabasePtr = function(this: IProvider; status: IStatus; fileName: PAnsiChar; dpbLength: Cardinal; dpb: BytePtr): IAttachment; cdecl; + IProvider_attachServiceManagerPtr = function(this: IProvider; status: IStatus; service: PAnsiChar; spbLength: Cardinal; spb: BytePtr): IService; cdecl; + IProvider_shutdownPtr = procedure(this: IProvider; status: IStatus; timeout: Cardinal; reason: Integer); cdecl; + IProvider_setDbCryptCallbackPtr = procedure(this: IProvider; status: IStatus; cryptCallback: ICryptKeyCallback); cdecl; + IDtcStart_addAttachmentPtr = procedure(this: IDtcStart; status: IStatus; att: IAttachment); cdecl; + IDtcStart_addWithTpbPtr = procedure(this: IDtcStart; status: IStatus; att: IAttachment; length: Cardinal; tpb: BytePtr); cdecl; + IDtcStart_startPtr = function(this: IDtcStart; status: IStatus): ITransaction; cdecl; + IDtc_joinPtr = function(this: IDtc; status: IStatus; one: ITransaction; two: ITransaction): ITransaction; cdecl; + IDtc_startBuilderPtr = function(this: IDtc; status: IStatus): IDtcStart; cdecl; + IWriter_resetPtr = procedure(this: IWriter); cdecl; + IWriter_addPtr = procedure(this: IWriter; status: IStatus; name: PAnsiChar); cdecl; + IWriter_setTypePtr = procedure(this: IWriter; status: IStatus; value: PAnsiChar); cdecl; + IWriter_setDbPtr = procedure(this: IWriter; status: IStatus; value: PAnsiChar); cdecl; + IServerBlock_getLoginPtr = function(this: IServerBlock): PAnsiChar; cdecl; + IServerBlock_getDataPtr = function(this: IServerBlock; length: CardinalPtr): BytePtr; cdecl; + IServerBlock_putDataPtr = procedure(this: IServerBlock; status: IStatus; length: Cardinal; data: Pointer); cdecl; + IServerBlock_newKeyPtr = function(this: IServerBlock; status: IStatus): ICryptKey; cdecl; + IClientBlock_getLoginPtr = function(this: IClientBlock): PAnsiChar; cdecl; + IClientBlock_getPasswordPtr = function(this: IClientBlock): PAnsiChar; cdecl; + IClientBlock_getDataPtr = function(this: IClientBlock; length: CardinalPtr): BytePtr; cdecl; + IClientBlock_putDataPtr = procedure(this: IClientBlock; status: IStatus; length: Cardinal; data: Pointer); cdecl; + IClientBlock_newKeyPtr = function(this: IClientBlock; status: IStatus): ICryptKey; cdecl; + IServer_authenticatePtr = function(this: IServer; status: IStatus; sBlock: IServerBlock; writerInterface: IWriter): Integer; cdecl; + IClient_authenticatePtr = function(this: IClient; status: IStatus; cBlock: IClientBlock): Integer; cdecl; + IUserField_enteredPtr = function(this: IUserField): Integer; cdecl; + IUserField_specifiedPtr = function(this: IUserField): Integer; cdecl; + IUserField_setEnteredPtr = procedure(this: IUserField; status: IStatus; newValue: Integer); cdecl; + ICharUserField_getPtr = function(this: ICharUserField): PAnsiChar; cdecl; + ICharUserField_set_Ptr = procedure(this: ICharUserField; status: IStatus; newValue: PAnsiChar); cdecl; + IIntUserField_getPtr = function(this: IIntUserField): Integer; cdecl; + IIntUserField_set_Ptr = procedure(this: IIntUserField; status: IStatus; newValue: Integer); cdecl; + IUser_operationPtr = function(this: IUser): Cardinal; cdecl; + IUser_userNamePtr = function(this: IUser): ICharUserField; cdecl; + IUser_passwordPtr = function(this: IUser): ICharUserField; cdecl; + IUser_firstNamePtr = function(this: IUser): ICharUserField; cdecl; + IUser_lastNamePtr = function(this: IUser): ICharUserField; cdecl; + IUser_middleNamePtr = function(this: IUser): ICharUserField; cdecl; + IUser_commentPtr = function(this: IUser): ICharUserField; cdecl; + IUser_attributesPtr = function(this: IUser): ICharUserField; cdecl; + IUser_activePtr = function(this: IUser): IIntUserField; cdecl; + IUser_adminPtr = function(this: IUser): IIntUserField; cdecl; + IUser_clearPtr = procedure(this: IUser; status: IStatus); cdecl; + IListUsers_listPtr = procedure(this: IListUsers; status: IStatus; user: IUser); cdecl; + ILogonInfo_namePtr = function(this: ILogonInfo): PAnsiChar; cdecl; + ILogonInfo_rolePtr = function(this: ILogonInfo): PAnsiChar; cdecl; + ILogonInfo_networkProtocolPtr = function(this: ILogonInfo): PAnsiChar; cdecl; + ILogonInfo_remoteAddressPtr = function(this: ILogonInfo): PAnsiChar; cdecl; + ILogonInfo_authBlockPtr = function(this: ILogonInfo; length: CardinalPtr): BytePtr; cdecl; + IManagement_startPtr = procedure(this: IManagement; status: IStatus; logonInfo: ILogonInfo); cdecl; + IManagement_executePtr = function(this: IManagement; status: IStatus; user: IUser; callback: IListUsers): Integer; cdecl; + IManagement_commitPtr = procedure(this: IManagement; status: IStatus); cdecl; + IManagement_rollbackPtr = procedure(this: IManagement; status: IStatus); cdecl; + IWireCryptPlugin_getKnownTypesPtr = function(this: IWireCryptPlugin; status: IStatus): PAnsiChar; cdecl; + IWireCryptPlugin_setKeyPtr = procedure(this: IWireCryptPlugin; status: IStatus; key: ICryptKey); cdecl; + IWireCryptPlugin_encryptPtr = procedure(this: IWireCryptPlugin; status: IStatus; length: Cardinal; from: Pointer; to_: Pointer); cdecl; + IWireCryptPlugin_decryptPtr = procedure(this: IWireCryptPlugin; status: IStatus; length: Cardinal; from: Pointer; to_: Pointer); cdecl; + ICryptKeyCallback_callbackPtr = function(this: ICryptKeyCallback; dataLength: Cardinal; data: Pointer; bufferLength: Cardinal; buffer: Pointer): Cardinal; cdecl; + IKeyHolderPlugin_keyCallbackPtr = function(this: IKeyHolderPlugin; status: IStatus; callback: ICryptKeyCallback): Integer; cdecl; + IKeyHolderPlugin_keyHandlePtr = function(this: IKeyHolderPlugin; status: IStatus; keyName: PAnsiChar): ICryptKeyCallback; cdecl; + IDbCryptPlugin_setKeyPtr = procedure(this: IDbCryptPlugin; status: IStatus; length: Cardinal; sources: IKeyHolderPluginPtr; keyName: PAnsiChar); cdecl; + IDbCryptPlugin_encryptPtr = procedure(this: IDbCryptPlugin; status: IStatus; length: Cardinal; from: Pointer; to_: Pointer); cdecl; + IDbCryptPlugin_decryptPtr = procedure(this: IDbCryptPlugin; status: IStatus; length: Cardinal; from: Pointer; to_: Pointer); cdecl; + IExternalContext_getMasterPtr = function(this: IExternalContext): IMaster; cdecl; + IExternalContext_getEnginePtr = function(this: IExternalContext; status: IStatus): IExternalEngine; cdecl; + IExternalContext_getAttachmentPtr = function(this: IExternalContext; status: IStatus): IAttachment; cdecl; + IExternalContext_getTransactionPtr = function(this: IExternalContext; status: IStatus): ITransaction; cdecl; + IExternalContext_getUserNamePtr = function(this: IExternalContext): PAnsiChar; cdecl; + IExternalContext_getDatabaseNamePtr = function(this: IExternalContext): PAnsiChar; cdecl; + IExternalContext_getClientCharSetPtr = function(this: IExternalContext): PAnsiChar; cdecl; + IExternalContext_obtainInfoCodePtr = function(this: IExternalContext): Integer; cdecl; + IExternalContext_getInfoPtr = function(this: IExternalContext; code: Integer): Pointer; cdecl; + IExternalContext_setInfoPtr = function(this: IExternalContext; code: Integer; value: Pointer): Pointer; cdecl; + IExternalResultSet_fetchPtr = function(this: IExternalResultSet; status: IStatus): Boolean; cdecl; + IExternalFunction_getCharSetPtr = procedure(this: IExternalFunction; status: IStatus; context: IExternalContext; name: PAnsiChar; nameSize: Cardinal); cdecl; + IExternalFunction_executePtr = procedure(this: IExternalFunction; status: IStatus; context: IExternalContext; inMsg: Pointer; outMsg: Pointer); cdecl; + IExternalProcedure_getCharSetPtr = procedure(this: IExternalProcedure; status: IStatus; context: IExternalContext; name: PAnsiChar; nameSize: Cardinal); cdecl; + IExternalProcedure_openPtr = function(this: IExternalProcedure; status: IStatus; context: IExternalContext; inMsg: Pointer; outMsg: Pointer): IExternalResultSet; cdecl; + IExternalTrigger_getCharSetPtr = procedure(this: IExternalTrigger; status: IStatus; context: IExternalContext; name: PAnsiChar; nameSize: Cardinal); cdecl; + IExternalTrigger_executePtr = procedure(this: IExternalTrigger; status: IStatus; context: IExternalContext; action: Cardinal; oldMsg: Pointer; newMsg: Pointer); cdecl; + IRoutineMetadata_getPackagePtr = function(this: IRoutineMetadata; status: IStatus): PAnsiChar; cdecl; + IRoutineMetadata_getNamePtr = function(this: IRoutineMetadata; status: IStatus): PAnsiChar; cdecl; + IRoutineMetadata_getEntryPointPtr = function(this: IRoutineMetadata; status: IStatus): PAnsiChar; cdecl; + IRoutineMetadata_getBodyPtr = function(this: IRoutineMetadata; status: IStatus): PAnsiChar; cdecl; + IRoutineMetadata_getInputMetadataPtr = function(this: IRoutineMetadata; status: IStatus): IMessageMetadata; cdecl; + IRoutineMetadata_getOutputMetadataPtr = function(this: IRoutineMetadata; status: IStatus): IMessageMetadata; cdecl; + IRoutineMetadata_getTriggerMetadataPtr = function(this: IRoutineMetadata; status: IStatus): IMessageMetadata; cdecl; + IRoutineMetadata_getTriggerTablePtr = function(this: IRoutineMetadata; status: IStatus): PAnsiChar; cdecl; + IRoutineMetadata_getTriggerTypePtr = function(this: IRoutineMetadata; status: IStatus): Cardinal; cdecl; + IExternalEngine_openPtr = procedure(this: IExternalEngine; status: IStatus; context: IExternalContext; charSet: PAnsiChar; charSetSize: Cardinal); cdecl; + IExternalEngine_openAttachmentPtr = procedure(this: IExternalEngine; status: IStatus; context: IExternalContext); cdecl; + IExternalEngine_closeAttachmentPtr = procedure(this: IExternalEngine; status: IStatus; context: IExternalContext); cdecl; + IExternalEngine_makeFunctionPtr = function(this: IExternalEngine; status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder): IExternalFunction; cdecl; + IExternalEngine_makeProcedurePtr = function(this: IExternalEngine; status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder): IExternalProcedure; cdecl; + IExternalEngine_makeTriggerPtr = function(this: IExternalEngine; status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; fieldsBuilder: IMetadataBuilder): IExternalTrigger; cdecl; + ITimer_handlerPtr = procedure(this: ITimer); cdecl; + ITimerControl_startPtr = procedure(this: ITimerControl; status: IStatus; timer: ITimer; microSeconds: QWord); cdecl; + ITimerControl_stopPtr = procedure(this: ITimerControl; status: IStatus; timer: ITimer); cdecl; + IVersionCallback_callbackPtr = procedure(this: IVersionCallback; status: IStatus; text: PAnsiChar); cdecl; + IUtil_getFbVersionPtr = procedure(this: IUtil; status: IStatus; att: IAttachment; callback: IVersionCallback); cdecl; + IUtil_loadBlobPtr = procedure(this: IUtil; status: IStatus; blobId: ISC_QUADPtr; att: IAttachment; tra: ITransaction; file_: PAnsiChar; txt: Boolean); cdecl; + IUtil_dumpBlobPtr = procedure(this: IUtil; status: IStatus; blobId: ISC_QUADPtr; att: IAttachment; tra: ITransaction; file_: PAnsiChar; txt: Boolean); cdecl; + IUtil_getPerfCountersPtr = procedure(this: IUtil; status: IStatus; att: IAttachment; countersSet: PAnsiChar; counters: Int64Ptr); cdecl; + IUtil_executeCreateDatabasePtr = function(this: IUtil; status: IStatus; stmtLength: Cardinal; creatDBstatement: PAnsiChar; dialect: Cardinal; stmtIsCreateDb: BooleanPtr): IAttachment; cdecl; + IUtil_decodeDatePtr = procedure(this: IUtil; date: ISC_DATE; year: CardinalPtr; month: CardinalPtr; day: CardinalPtr); cdecl; + IUtil_decodeTimePtr = procedure(this: IUtil; time: ISC_TIME; hours: CardinalPtr; minutes: CardinalPtr; seconds: CardinalPtr; fractions: CardinalPtr); cdecl; + IUtil_encodeDatePtr = function(this: IUtil; year: Cardinal; month: Cardinal; day: Cardinal): ISC_DATE; cdecl; + IUtil_encodeTimePtr = function(this: IUtil; hours: Cardinal; minutes: Cardinal; seconds: Cardinal; fractions: Cardinal): ISC_TIME; cdecl; + IUtil_formatStatusPtr = function(this: IUtil; buffer: PAnsiChar; bufferSize: Cardinal; status: IStatus): Cardinal; cdecl; + IUtil_getClientVersionPtr = function(this: IUtil): Cardinal; cdecl; + IUtil_getXpbBuilderPtr = function(this: IUtil; status: IStatus; kind: Cardinal; buf: BytePtr; len: Cardinal): IXpbBuilder; cdecl; + IUtil_setOffsetsPtr = function(this: IUtil; status: IStatus; metadata: IMessageMetadata; callback: IOffsetsCallback): Cardinal; cdecl; + IOffsetsCallback_setOffsetPtr = procedure(this: IOffsetsCallback; status: IStatus; index: Cardinal; offset: Cardinal; nullOffset: Cardinal); cdecl; + IXpbBuilder_clearPtr = procedure(this: IXpbBuilder; status: IStatus); cdecl; + IXpbBuilder_removeCurrentPtr = procedure(this: IXpbBuilder; status: IStatus); cdecl; + IXpbBuilder_insertIntPtr = procedure(this: IXpbBuilder; status: IStatus; tag: Byte; value: Integer); cdecl; + IXpbBuilder_insertBigIntPtr = procedure(this: IXpbBuilder; status: IStatus; tag: Byte; value: Int64); cdecl; + IXpbBuilder_insertBytesPtr = procedure(this: IXpbBuilder; status: IStatus; tag: Byte; bytes: Pointer; length: Cardinal); cdecl; + IXpbBuilder_insertStringPtr = procedure(this: IXpbBuilder; status: IStatus; tag: Byte; str: PAnsiChar); cdecl; + IXpbBuilder_insertTagPtr = procedure(this: IXpbBuilder; status: IStatus; tag: Byte); cdecl; + IXpbBuilder_isEofPtr = function(this: IXpbBuilder; status: IStatus): Boolean; cdecl; + IXpbBuilder_moveNextPtr = procedure(this: IXpbBuilder; status: IStatus); cdecl; + IXpbBuilder_rewindPtr = procedure(this: IXpbBuilder; status: IStatus); cdecl; + IXpbBuilder_findFirstPtr = function(this: IXpbBuilder; status: IStatus; tag: Byte): Boolean; cdecl; + IXpbBuilder_findNextPtr = function(this: IXpbBuilder; status: IStatus): Boolean; cdecl; + IXpbBuilder_getTagPtr = function(this: IXpbBuilder; status: IStatus): Byte; cdecl; + IXpbBuilder_getLengthPtr = function(this: IXpbBuilder; status: IStatus): Cardinal; cdecl; + IXpbBuilder_getIntPtr = function(this: IXpbBuilder; status: IStatus): Integer; cdecl; + IXpbBuilder_getBigIntPtr = function(this: IXpbBuilder; status: IStatus): Int64; cdecl; + IXpbBuilder_getStringPtr = function(this: IXpbBuilder; status: IStatus): PAnsiChar; cdecl; + IXpbBuilder_getBytesPtr = function(this: IXpbBuilder; status: IStatus): BytePtr; cdecl; + IXpbBuilder_getBufferLengthPtr = function(this: IXpbBuilder; status: IStatus): Cardinal; cdecl; + IXpbBuilder_getBufferPtr = function(this: IXpbBuilder; status: IStatus): BytePtr; cdecl; + ITraceConnection_getKindPtr = function(this: ITraceConnection): Cardinal; cdecl; + ITraceConnection_getProcessIDPtr = function(this: ITraceConnection): Integer; cdecl; + ITraceConnection_getUserNamePtr = function(this: ITraceConnection): PAnsiChar; cdecl; + ITraceConnection_getRoleNamePtr = function(this: ITraceConnection): PAnsiChar; cdecl; + ITraceConnection_getCharSetPtr = function(this: ITraceConnection): PAnsiChar; cdecl; + ITraceConnection_getRemoteProtocolPtr = function(this: ITraceConnection): PAnsiChar; cdecl; + ITraceConnection_getRemoteAddressPtr = function(this: ITraceConnection): PAnsiChar; cdecl; + ITraceConnection_getRemoteProcessIDPtr = function(this: ITraceConnection): Integer; cdecl; + ITraceConnection_getRemoteProcessNamePtr = function(this: ITraceConnection): PAnsiChar; cdecl; + ITraceDatabaseConnection_getConnectionIDPtr = function(this: ITraceDatabaseConnection): Int64; cdecl; + ITraceDatabaseConnection_getDatabaseNamePtr = function(this: ITraceDatabaseConnection): PAnsiChar; cdecl; + ITraceTransaction_getTransactionIDPtr = function(this: ITraceTransaction): Int64; cdecl; + ITraceTransaction_getReadOnlyPtr = function(this: ITraceTransaction): Boolean; cdecl; + ITraceTransaction_getWaitPtr = function(this: ITraceTransaction): Integer; cdecl; + ITraceTransaction_getIsolationPtr = function(this: ITraceTransaction): Cardinal; cdecl; + ITraceTransaction_getPerfPtr = function(this: ITraceTransaction): PerformanceInfoPtr; cdecl; + ITraceParams_getCountPtr = function(this: ITraceParams): Cardinal; cdecl; + ITraceParams_getParamPtr = function(this: ITraceParams; idx: Cardinal): dscPtr; cdecl; + ITraceStatement_getStmtIDPtr = function(this: ITraceStatement): Int64; cdecl; + ITraceStatement_getPerfPtr = function(this: ITraceStatement): PerformanceInfoPtr; cdecl; + ITraceSQLStatement_getTextPtr = function(this: ITraceSQLStatement): PAnsiChar; cdecl; + ITraceSQLStatement_getPlanPtr = function(this: ITraceSQLStatement): PAnsiChar; cdecl; + ITraceSQLStatement_getInputsPtr = function(this: ITraceSQLStatement): ITraceParams; cdecl; + ITraceSQLStatement_getTextUTF8Ptr = function(this: ITraceSQLStatement): PAnsiChar; cdecl; + ITraceSQLStatement_getExplainedPlanPtr = function(this: ITraceSQLStatement): PAnsiChar; cdecl; + ITraceBLRStatement_getDataPtr = function(this: ITraceBLRStatement): BytePtr; cdecl; + ITraceBLRStatement_getDataLengthPtr = function(this: ITraceBLRStatement): Cardinal; cdecl; + ITraceBLRStatement_getTextPtr = function(this: ITraceBLRStatement): PAnsiChar; cdecl; + ITraceDYNRequest_getDataPtr = function(this: ITraceDYNRequest): BytePtr; cdecl; + ITraceDYNRequest_getDataLengthPtr = function(this: ITraceDYNRequest): Cardinal; cdecl; + ITraceDYNRequest_getTextPtr = function(this: ITraceDYNRequest): PAnsiChar; cdecl; + ITraceContextVariable_getNameSpacePtr = function(this: ITraceContextVariable): PAnsiChar; cdecl; + ITraceContextVariable_getVarNamePtr = function(this: ITraceContextVariable): PAnsiChar; cdecl; + ITraceContextVariable_getVarValuePtr = function(this: ITraceContextVariable): PAnsiChar; cdecl; + ITraceProcedure_getProcNamePtr = function(this: ITraceProcedure): PAnsiChar; cdecl; + ITraceProcedure_getInputsPtr = function(this: ITraceProcedure): ITraceParams; cdecl; + ITraceProcedure_getPerfPtr = function(this: ITraceProcedure): PerformanceInfoPtr; cdecl; + ITraceFunction_getFuncNamePtr = function(this: ITraceFunction): PAnsiChar; cdecl; + ITraceFunction_getInputsPtr = function(this: ITraceFunction): ITraceParams; cdecl; + ITraceFunction_getResultPtr = function(this: ITraceFunction): ITraceParams; cdecl; + ITraceFunction_getPerfPtr = function(this: ITraceFunction): PerformanceInfoPtr; cdecl; + ITraceTrigger_getTriggerNamePtr = function(this: ITraceTrigger): PAnsiChar; cdecl; + ITraceTrigger_getRelationNamePtr = function(this: ITraceTrigger): PAnsiChar; cdecl; + ITraceTrigger_getActionPtr = function(this: ITraceTrigger): Integer; cdecl; + ITraceTrigger_getWhichPtr = function(this: ITraceTrigger): Integer; cdecl; + ITraceTrigger_getPerfPtr = function(this: ITraceTrigger): PerformanceInfoPtr; cdecl; + ITraceServiceConnection_getServiceIDPtr = function(this: ITraceServiceConnection): Pointer; cdecl; + ITraceServiceConnection_getServiceMgrPtr = function(this: ITraceServiceConnection): PAnsiChar; cdecl; + ITraceServiceConnection_getServiceNamePtr = function(this: ITraceServiceConnection): PAnsiChar; cdecl; + ITraceStatusVector_hasErrorPtr = function(this: ITraceStatusVector): Boolean; cdecl; + ITraceStatusVector_hasWarningPtr = function(this: ITraceStatusVector): Boolean; cdecl; + ITraceStatusVector_getStatusPtr = function(this: ITraceStatusVector): IStatus; cdecl; + ITraceStatusVector_getTextPtr = function(this: ITraceStatusVector): PAnsiChar; cdecl; + ITraceSweepInfo_getOITPtr = function(this: ITraceSweepInfo): Int64; cdecl; + ITraceSweepInfo_getOSTPtr = function(this: ITraceSweepInfo): Int64; cdecl; + ITraceSweepInfo_getOATPtr = function(this: ITraceSweepInfo): Int64; cdecl; + ITraceSweepInfo_getNextPtr = function(this: ITraceSweepInfo): Int64; cdecl; + ITraceSweepInfo_getPerfPtr = function(this: ITraceSweepInfo): PerformanceInfoPtr; cdecl; + ITraceLogWriter_writePtr = function(this: ITraceLogWriter; buf: Pointer; size: Cardinal): Cardinal; cdecl; + ITraceInitInfo_getConfigTextPtr = function(this: ITraceInitInfo): PAnsiChar; cdecl; + ITraceInitInfo_getTraceSessionIDPtr = function(this: ITraceInitInfo): Integer; cdecl; + ITraceInitInfo_getTraceSessionNamePtr = function(this: ITraceInitInfo): PAnsiChar; cdecl; + ITraceInitInfo_getFirebirdRootDirectoryPtr = function(this: ITraceInitInfo): PAnsiChar; cdecl; + ITraceInitInfo_getDatabaseNamePtr = function(this: ITraceInitInfo): PAnsiChar; cdecl; + ITraceInitInfo_getConnectionPtr = function(this: ITraceInitInfo): ITraceDatabaseConnection; cdecl; + ITraceInitInfo_getLogWriterPtr = function(this: ITraceInitInfo): ITraceLogWriter; cdecl; + ITracePlugin_trace_get_errorPtr = function(this: ITracePlugin): PAnsiChar; cdecl; + ITracePlugin_trace_attachPtr = function(this: ITracePlugin; connection: ITraceDatabaseConnection; create_db: Boolean; att_result: Cardinal): Boolean; cdecl; + ITracePlugin_trace_detachPtr = function(this: ITracePlugin; connection: ITraceDatabaseConnection; drop_db: Boolean): Boolean; cdecl; + ITracePlugin_trace_transaction_startPtr = function(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; tpb_length: Cardinal; tpb: BytePtr; tra_result: Cardinal): Boolean; cdecl; + ITracePlugin_trace_transaction_endPtr = function(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; commit: Boolean; retain_context: Boolean; tra_result: Cardinal): Boolean; cdecl; + ITracePlugin_trace_proc_executePtr = function(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; procedure_: ITraceProcedure; started: Boolean; proc_result: Cardinal): Boolean; cdecl; + ITracePlugin_trace_trigger_executePtr = function(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; trigger: ITraceTrigger; started: Boolean; trig_result: Cardinal): Boolean; cdecl; + ITracePlugin_trace_set_contextPtr = function(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; variable: ITraceContextVariable): Boolean; cdecl; + ITracePlugin_trace_dsql_preparePtr = function(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceSQLStatement; time_millis: Int64; req_result: Cardinal): Boolean; cdecl; + ITracePlugin_trace_dsql_freePtr = function(this: ITracePlugin; connection: ITraceDatabaseConnection; statement: ITraceSQLStatement; option: Cardinal): Boolean; cdecl; + ITracePlugin_trace_dsql_executePtr = function(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceSQLStatement; started: Boolean; req_result: Cardinal): Boolean; cdecl; + ITracePlugin_trace_blr_compilePtr = function(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceBLRStatement; time_millis: Int64; req_result: Cardinal): Boolean; cdecl; + ITracePlugin_trace_blr_executePtr = function(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceBLRStatement; req_result: Cardinal): Boolean; cdecl; + ITracePlugin_trace_dyn_executePtr = function(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; request: ITraceDYNRequest; time_millis: Int64; req_result: Cardinal): Boolean; cdecl; + ITracePlugin_trace_service_attachPtr = function(this: ITracePlugin; service: ITraceServiceConnection; att_result: Cardinal): Boolean; cdecl; + ITracePlugin_trace_service_startPtr = function(this: ITracePlugin; service: ITraceServiceConnection; switches_length: Cardinal; switches: PAnsiChar; start_result: Cardinal): Boolean; cdecl; + ITracePlugin_trace_service_queryPtr = function(this: ITracePlugin; service: ITraceServiceConnection; send_item_length: Cardinal; send_items: BytePtr; recv_item_length: Cardinal; recv_items: BytePtr; query_result: Cardinal): Boolean; cdecl; + ITracePlugin_trace_service_detachPtr = function(this: ITracePlugin; service: ITraceServiceConnection; detach_result: Cardinal): Boolean; cdecl; + ITracePlugin_trace_event_errorPtr = function(this: ITracePlugin; connection: ITraceConnection; status: ITraceStatusVector; function_: PAnsiChar): Boolean; cdecl; + ITracePlugin_trace_event_sweepPtr = function(this: ITracePlugin; connection: ITraceDatabaseConnection; sweep: ITraceSweepInfo; sweep_state: Cardinal): Boolean; cdecl; + ITracePlugin_trace_func_executePtr = function(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; function_: ITraceFunction; started: Boolean; func_result: Cardinal): Boolean; cdecl; + ITraceFactory_trace_needsPtr = function(this: ITraceFactory): QWord; cdecl; + ITraceFactory_trace_createPtr = function(this: ITraceFactory; status: IStatus; init_info: ITraceInitInfo): ITracePlugin; cdecl; + IUdrFunctionFactory_setupPtr = procedure(this: IUdrFunctionFactory; status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder); cdecl; + IUdrFunctionFactory_newItemPtr = function(this: IUdrFunctionFactory; status: IStatus; context: IExternalContext; metadata: IRoutineMetadata): IExternalFunction; cdecl; + IUdrProcedureFactory_setupPtr = procedure(this: IUdrProcedureFactory; status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder); cdecl; + IUdrProcedureFactory_newItemPtr = function(this: IUdrProcedureFactory; status: IStatus; context: IExternalContext; metadata: IRoutineMetadata): IExternalProcedure; cdecl; + IUdrTriggerFactory_setupPtr = procedure(this: IUdrTriggerFactory; status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; fieldsBuilder: IMetadataBuilder); cdecl; + IUdrTriggerFactory_newItemPtr = function(this: IUdrTriggerFactory; status: IStatus; context: IExternalContext; metadata: IRoutineMetadata): IExternalTrigger; cdecl; + IUdrPlugin_getMasterPtr = function(this: IUdrPlugin): IMaster; cdecl; + IUdrPlugin_registerFunctionPtr = procedure(this: IUdrPlugin; status: IStatus; name: PAnsiChar; factory: IUdrFunctionFactory); cdecl; + IUdrPlugin_registerProcedurePtr = procedure(this: IUdrPlugin; status: IStatus; name: PAnsiChar; factory: IUdrProcedureFactory); cdecl; + IUdrPlugin_registerTriggerPtr = procedure(this: IUdrPlugin; status: IStatus; name: PAnsiChar; factory: IUdrTriggerFactory); cdecl; + + VersionedVTable = class + version: NativeInt; + end; + + IVersioned = class + vTable: VersionedVTable; + + const VERSION = 0; + + end; + + IVersionedImpl = class(IVersioned) + constructor create; + + end; + + ReferenceCountedVTable = class(VersionedVTable) + addRef: IReferenceCounted_addRefPtr; + release: IReferenceCounted_releasePtr; + end; + + IReferenceCounted = class(IVersioned) + const VERSION = 2; + + procedure addRef(); + function release(): Integer; + end; + + IReferenceCountedImpl = class(IReferenceCounted) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + end; + + DisposableVTable = class(VersionedVTable) + dispose: IDisposable_disposePtr; + end; + + IDisposable = class(IVersioned) + const VERSION = 1; + + procedure dispose(); + end; + + IDisposableImpl = class(IDisposable) + constructor create; + + procedure dispose(); virtual; abstract; + end; + + StatusVTable = class(DisposableVTable) + init: IStatus_initPtr; + getState: IStatus_getStatePtr; + setErrors2: IStatus_setErrors2Ptr; + setWarnings2: IStatus_setWarnings2Ptr; + setErrors: IStatus_setErrorsPtr; + setWarnings: IStatus_setWarningsPtr; + getErrors: IStatus_getErrorsPtr; + getWarnings: IStatus_getWarningsPtr; + clone: IStatus_clonePtr; + end; + + IStatus = class(IDisposable) + const VERSION = 10; + const STATE_WARNINGS = Cardinal(1); + const STATE_ERRORS = Cardinal(2); + const RESULT_ERROR = Integer(-1); + const RESULT_OK = Integer(0); + const RESULT_NO_DATA = Integer(1); + const RESULT_SEGMENT = Integer(2); + + procedure init(); + function getState(): Cardinal; + procedure setErrors2(length: Cardinal; value: NativeIntPtr); + procedure setWarnings2(length: Cardinal; value: NativeIntPtr); + procedure setErrors(value: NativeIntPtr); + procedure setWarnings(value: NativeIntPtr); + function getErrors(): NativeIntPtr; + function getWarnings(): NativeIntPtr; + function clone(): IStatus; + end; + + IStatusImpl = class(IStatus) + constructor create; + + procedure dispose(); virtual; abstract; + procedure init(); virtual; abstract; + function getState(): Cardinal; virtual; abstract; + procedure setErrors2(length: Cardinal; value: NativeIntPtr); virtual; abstract; + procedure setWarnings2(length: Cardinal; value: NativeIntPtr); virtual; abstract; + procedure setErrors(value: NativeIntPtr); virtual; abstract; + procedure setWarnings(value: NativeIntPtr); virtual; abstract; + function getErrors(): NativeIntPtr; virtual; abstract; + function getWarnings(): NativeIntPtr; virtual; abstract; + function clone(): IStatus; virtual; abstract; + end; + + MasterVTable = class(VersionedVTable) + getStatus: IMaster_getStatusPtr; + getDispatcher: IMaster_getDispatcherPtr; + getPluginManager: IMaster_getPluginManagerPtr; + getTimerControl: IMaster_getTimerControlPtr; + getDtc: IMaster_getDtcPtr; + registerAttachment: IMaster_registerAttachmentPtr; + registerTransaction: IMaster_registerTransactionPtr; + getMetadataBuilder: IMaster_getMetadataBuilderPtr; + serverMode: IMaster_serverModePtr; + getUtilInterface: IMaster_getUtilInterfacePtr; + getConfigManager: IMaster_getConfigManagerPtr; + getProcessExiting: IMaster_getProcessExitingPtr; + end; + + IMaster = class(IVersioned) + const VERSION = 12; + + function getStatus(): IStatus; + function getDispatcher(): IProvider; + function getPluginManager(): IPluginManager; + function getTimerControl(): ITimerControl; + function getDtc(): IDtc; + function registerAttachment(provider: IProvider; attachment: IAttachment): IAttachment; + function registerTransaction(attachment: IAttachment; transaction: ITransaction): ITransaction; + function getMetadataBuilder(status: IStatus; fieldCount: Cardinal): IMetadataBuilder; + function serverMode(mode: Integer): Integer; + function getUtilInterface(): IUtil; + function getConfigManager(): IConfigManager; + function getProcessExiting(): Boolean; + end; + + IMasterImpl = class(IMaster) + constructor create; + + function getStatus(): IStatus; virtual; abstract; + function getDispatcher(): IProvider; virtual; abstract; + function getPluginManager(): IPluginManager; virtual; abstract; + function getTimerControl(): ITimerControl; virtual; abstract; + function getDtc(): IDtc; virtual; abstract; + function registerAttachment(provider: IProvider; attachment: IAttachment): IAttachment; virtual; abstract; + function registerTransaction(attachment: IAttachment; transaction: ITransaction): ITransaction; virtual; abstract; + function getMetadataBuilder(status: IStatus; fieldCount: Cardinal): IMetadataBuilder; virtual; abstract; + function serverMode(mode: Integer): Integer; virtual; abstract; + function getUtilInterface(): IUtil; virtual; abstract; + function getConfigManager(): IConfigManager; virtual; abstract; + function getProcessExiting(): Boolean; virtual; abstract; + end; + + PluginBaseVTable = class(ReferenceCountedVTable) + setOwner: IPluginBase_setOwnerPtr; + getOwner: IPluginBase_getOwnerPtr; + end; + + IPluginBase = class(IReferenceCounted) + const VERSION = 4; + + procedure setOwner(r: IReferenceCounted); + function getOwner(): IReferenceCounted; + end; + + IPluginBaseImpl = class(IPluginBase) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure setOwner(r: IReferenceCounted); virtual; abstract; + function getOwner(): IReferenceCounted; virtual; abstract; + end; + + PluginSetVTable = class(ReferenceCountedVTable) + getName: IPluginSet_getNamePtr; + getModuleName: IPluginSet_getModuleNamePtr; + getPlugin: IPluginSet_getPluginPtr; + next: IPluginSet_nextPtr; + set_: IPluginSet_set_Ptr; + end; + + IPluginSet = class(IReferenceCounted) + const VERSION = 7; + + function getName(): PAnsiChar; + function getModuleName(): PAnsiChar; + function getPlugin(status: IStatus): IPluginBase; + procedure next(status: IStatus); + procedure set_(status: IStatus; s: PAnsiChar); + end; + + IPluginSetImpl = class(IPluginSet) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + function getName(): PAnsiChar; virtual; abstract; + function getModuleName(): PAnsiChar; virtual; abstract; + function getPlugin(status: IStatus): IPluginBase; virtual; abstract; + procedure next(status: IStatus); virtual; abstract; + procedure set_(status: IStatus; s: PAnsiChar); virtual; abstract; + end; + + ConfigEntryVTable = class(ReferenceCountedVTable) + getName: IConfigEntry_getNamePtr; + getValue: IConfigEntry_getValuePtr; + getIntValue: IConfigEntry_getIntValuePtr; + getBoolValue: IConfigEntry_getBoolValuePtr; + getSubConfig: IConfigEntry_getSubConfigPtr; + end; + + IConfigEntry = class(IReferenceCounted) + const VERSION = 7; + + function getName(): PAnsiChar; + function getValue(): PAnsiChar; + function getIntValue(): Int64; + function getBoolValue(): Boolean; + function getSubConfig(status: IStatus): IConfig; + end; + + IConfigEntryImpl = class(IConfigEntry) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + function getName(): PAnsiChar; virtual; abstract; + function getValue(): PAnsiChar; virtual; abstract; + function getIntValue(): Int64; virtual; abstract; + function getBoolValue(): Boolean; virtual; abstract; + function getSubConfig(status: IStatus): IConfig; virtual; abstract; + end; + + ConfigVTable = class(ReferenceCountedVTable) + find: IConfig_findPtr; + findValue: IConfig_findValuePtr; + findPos: IConfig_findPosPtr; + end; + + IConfig = class(IReferenceCounted) + const VERSION = 5; + + function find(status: IStatus; name: PAnsiChar): IConfigEntry; + function findValue(status: IStatus; name: PAnsiChar; value: PAnsiChar): IConfigEntry; + function findPos(status: IStatus; name: PAnsiChar; pos: Cardinal): IConfigEntry; + end; + + IConfigImpl = class(IConfig) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + function find(status: IStatus; name: PAnsiChar): IConfigEntry; virtual; abstract; + function findValue(status: IStatus; name: PAnsiChar; value: PAnsiChar): IConfigEntry; virtual; abstract; + function findPos(status: IStatus; name: PAnsiChar; pos: Cardinal): IConfigEntry; virtual; abstract; + end; + + FirebirdConfVTable = class(ReferenceCountedVTable) + getKey: IFirebirdConf_getKeyPtr; + asInteger: IFirebirdConf_asIntegerPtr; + asString: IFirebirdConf_asStringPtr; + asBoolean: IFirebirdConf_asBooleanPtr; + end; + + IFirebirdConf = class(IReferenceCounted) + const VERSION = 6; + + function getKey(name: PAnsiChar): Cardinal; + function asInteger(key: Cardinal): Int64; + function asString(key: Cardinal): PAnsiChar; + function asBoolean(key: Cardinal): Boolean; + end; + + IFirebirdConfImpl = class(IFirebirdConf) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + function getKey(name: PAnsiChar): Cardinal; virtual; abstract; + function asInteger(key: Cardinal): Int64; virtual; abstract; + function asString(key: Cardinal): PAnsiChar; virtual; abstract; + function asBoolean(key: Cardinal): Boolean; virtual; abstract; + end; + + PluginConfigVTable = class(ReferenceCountedVTable) + getConfigFileName: IPluginConfig_getConfigFileNamePtr; + getDefaultConfig: IPluginConfig_getDefaultConfigPtr; + getFirebirdConf: IPluginConfig_getFirebirdConfPtr; + setReleaseDelay: IPluginConfig_setReleaseDelayPtr; + end; + + IPluginConfig = class(IReferenceCounted) + const VERSION = 6; + + function getConfigFileName(): PAnsiChar; + function getDefaultConfig(status: IStatus): IConfig; + function getFirebirdConf(status: IStatus): IFirebirdConf; + procedure setReleaseDelay(status: IStatus; microSeconds: QWord); + end; + + IPluginConfigImpl = class(IPluginConfig) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + function getConfigFileName(): PAnsiChar; virtual; abstract; + function getDefaultConfig(status: IStatus): IConfig; virtual; abstract; + function getFirebirdConf(status: IStatus): IFirebirdConf; virtual; abstract; + procedure setReleaseDelay(status: IStatus; microSeconds: QWord); virtual; abstract; + end; + + PluginFactoryVTable = class(VersionedVTable) + createPlugin: IPluginFactory_createPluginPtr; + end; + + IPluginFactory = class(IVersioned) + const VERSION = 1; + + function createPlugin(status: IStatus; factoryParameter: IPluginConfig): IPluginBase; + end; + + IPluginFactoryImpl = class(IPluginFactory) + constructor create; + + function createPlugin(status: IStatus; factoryParameter: IPluginConfig): IPluginBase; virtual; abstract; + end; + + PluginModuleVTable = class(VersionedVTable) + doClean: IPluginModule_doCleanPtr; + end; + + IPluginModule = class(IVersioned) + const VERSION = 1; + + procedure doClean(); + end; + + IPluginModuleImpl = class(IPluginModule) + constructor create; + + procedure doClean(); virtual; abstract; + end; + + PluginManagerVTable = class(VersionedVTable) + registerPluginFactory: IPluginManager_registerPluginFactoryPtr; + registerModule: IPluginManager_registerModulePtr; + unregisterModule: IPluginManager_unregisterModulePtr; + getPlugins: IPluginManager_getPluginsPtr; + getConfig: IPluginManager_getConfigPtr; + releasePlugin: IPluginManager_releasePluginPtr; + end; + + IPluginManager = class(IVersioned) + const VERSION = 6; + const TYPE_PROVIDER = Cardinal(1); + const TYPE_FIRST_NON_LIB = Cardinal(2); + const TYPE_AUTH_SERVER = Cardinal(3); + const TYPE_AUTH_CLIENT = Cardinal(4); + const TYPE_AUTH_USER_MANAGEMENT = Cardinal(5); + const TYPE_EXTERNAL_ENGINE = Cardinal(6); + const TYPE_TRACE = Cardinal(7); + const TYPE_WIRE_CRYPT = Cardinal(8); + const TYPE_DB_CRYPT = Cardinal(9); + const TYPE_KEY_HOLDER = Cardinal(10); + const TYPE_COUNT = Cardinal(11); + + procedure registerPluginFactory(pluginType: Cardinal; defaultName: PAnsiChar; factory: IPluginFactory); + procedure registerModule(cleanup: IPluginModule); + procedure unregisterModule(cleanup: IPluginModule); + function getPlugins(status: IStatus; pluginType: Cardinal; namesList: PAnsiChar; firebirdConf: IFirebirdConf): IPluginSet; + function getConfig(status: IStatus; filename: PAnsiChar): IConfig; + procedure releasePlugin(plugin: IPluginBase); + end; + + IPluginManagerImpl = class(IPluginManager) + constructor create; + + procedure registerPluginFactory(pluginType: Cardinal; defaultName: PAnsiChar; factory: IPluginFactory); virtual; abstract; + procedure registerModule(cleanup: IPluginModule); virtual; abstract; + procedure unregisterModule(cleanup: IPluginModule); virtual; abstract; + function getPlugins(status: IStatus; pluginType: Cardinal; namesList: PAnsiChar; firebirdConf: IFirebirdConf): IPluginSet; virtual; abstract; + function getConfig(status: IStatus; filename: PAnsiChar): IConfig; virtual; abstract; + procedure releasePlugin(plugin: IPluginBase); virtual; abstract; + end; + + CryptKeyVTable = class(VersionedVTable) + setSymmetric: ICryptKey_setSymmetricPtr; + setAsymmetric: ICryptKey_setAsymmetricPtr; + getEncryptKey: ICryptKey_getEncryptKeyPtr; + getDecryptKey: ICryptKey_getDecryptKeyPtr; + end; + + ICryptKey = class(IVersioned) + const VERSION = 4; + + procedure setSymmetric(status: IStatus; type_: PAnsiChar; keyLength: Cardinal; key: Pointer); + procedure setAsymmetric(status: IStatus; type_: PAnsiChar; encryptKeyLength: Cardinal; encryptKey: Pointer; decryptKeyLength: Cardinal; decryptKey: Pointer); + function getEncryptKey(length: CardinalPtr): Pointer; + function getDecryptKey(length: CardinalPtr): Pointer; + end; + + ICryptKeyImpl = class(ICryptKey) + constructor create; + + procedure setSymmetric(status: IStatus; type_: PAnsiChar; keyLength: Cardinal; key: Pointer); virtual; abstract; + procedure setAsymmetric(status: IStatus; type_: PAnsiChar; encryptKeyLength: Cardinal; encryptKey: Pointer; decryptKeyLength: Cardinal; decryptKey: Pointer); virtual; abstract; + function getEncryptKey(length: CardinalPtr): Pointer; virtual; abstract; + function getDecryptKey(length: CardinalPtr): Pointer; virtual; abstract; + end; + + ConfigManagerVTable = class(VersionedVTable) + getDirectory: IConfigManager_getDirectoryPtr; + getFirebirdConf: IConfigManager_getFirebirdConfPtr; + getDatabaseConf: IConfigManager_getDatabaseConfPtr; + getPluginConfig: IConfigManager_getPluginConfigPtr; + getInstallDirectory: IConfigManager_getInstallDirectoryPtr; + getRootDirectory: IConfigManager_getRootDirectoryPtr; + end; + + IConfigManager = class(IVersioned) + const VERSION = 6; + const DIR_BIN = Cardinal(0); + const DIR_SBIN = Cardinal(1); + const DIR_CONF = Cardinal(2); + const DIR_LIB = Cardinal(3); + const DIR_INC = Cardinal(4); + const DIR_DOC = Cardinal(5); + const DIR_UDF = Cardinal(6); + const DIR_SAMPLE = Cardinal(7); + const DIR_SAMPLEDB = Cardinal(8); + const DIR_HELP = Cardinal(9); + const DIR_INTL = Cardinal(10); + const DIR_MISC = Cardinal(11); + const DIR_SECDB = Cardinal(12); + const DIR_MSG = Cardinal(13); + const DIR_LOG = Cardinal(14); + const DIR_GUARD = Cardinal(15); + const DIR_PLUGINS = Cardinal(16); + const DIR_COUNT = Cardinal(17); + + function getDirectory(code: Cardinal): PAnsiChar; + function getFirebirdConf(): IFirebirdConf; + function getDatabaseConf(dbName: PAnsiChar): IFirebirdConf; + function getPluginConfig(configuredPlugin: PAnsiChar): IConfig; + function getInstallDirectory(): PAnsiChar; + function getRootDirectory(): PAnsiChar; + end; + + IConfigManagerImpl = class(IConfigManager) + constructor create; + + function getDirectory(code: Cardinal): PAnsiChar; virtual; abstract; + function getFirebirdConf(): IFirebirdConf; virtual; abstract; + function getDatabaseConf(dbName: PAnsiChar): IFirebirdConf; virtual; abstract; + function getPluginConfig(configuredPlugin: PAnsiChar): IConfig; virtual; abstract; + function getInstallDirectory(): PAnsiChar; virtual; abstract; + function getRootDirectory(): PAnsiChar; virtual; abstract; + end; + + EventCallbackVTable = class(ReferenceCountedVTable) + eventCallbackFunction: IEventCallback_eventCallbackFunctionPtr; + end; + + IEventCallback = class(IReferenceCounted) + const VERSION = 3; + + procedure eventCallbackFunction(length: Cardinal; events: BytePtr); + end; + + IEventCallbackImpl = class(IEventCallback) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure eventCallbackFunction(length: Cardinal; events: BytePtr); virtual; abstract; + end; + + BlobVTable = class(ReferenceCountedVTable) + getInfo: IBlob_getInfoPtr; + getSegment: IBlob_getSegmentPtr; + putSegment: IBlob_putSegmentPtr; + cancel: IBlob_cancelPtr; + close: IBlob_closePtr; + seek: IBlob_seekPtr; + end; + + IBlob = class(IReferenceCounted) + const VERSION = 8; + + procedure getInfo(status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); + function getSegment(status: IStatus; bufferLength: Cardinal; buffer: Pointer; segmentLength: CardinalPtr): Integer; + procedure putSegment(status: IStatus; length: Cardinal; buffer: Pointer); + procedure cancel(status: IStatus); + procedure close(status: IStatus); + function seek(status: IStatus; mode: Integer; offset: Integer): Integer; + end; + + IBlobImpl = class(IBlob) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure getInfo(status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); virtual; abstract; + function getSegment(status: IStatus; bufferLength: Cardinal; buffer: Pointer; segmentLength: CardinalPtr): Integer; virtual; abstract; + procedure putSegment(status: IStatus; length: Cardinal; buffer: Pointer); virtual; abstract; + procedure cancel(status: IStatus); virtual; abstract; + procedure close(status: IStatus); virtual; abstract; + function seek(status: IStatus; mode: Integer; offset: Integer): Integer; virtual; abstract; + end; + + TransactionVTable = class(ReferenceCountedVTable) + getInfo: ITransaction_getInfoPtr; + prepare: ITransaction_preparePtr; + commit: ITransaction_commitPtr; + commitRetaining: ITransaction_commitRetainingPtr; + rollback: ITransaction_rollbackPtr; + rollbackRetaining: ITransaction_rollbackRetainingPtr; + disconnect: ITransaction_disconnectPtr; + join: ITransaction_joinPtr; + validate: ITransaction_validatePtr; + enterDtc: ITransaction_enterDtcPtr; + end; + + ITransaction = class(IReferenceCounted) + const VERSION = 12; + + procedure getInfo(status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); + procedure prepare(status: IStatus; msgLength: Cardinal; message: BytePtr); + procedure commit(status: IStatus); + procedure commitRetaining(status: IStatus); + procedure rollback(status: IStatus); + procedure rollbackRetaining(status: IStatus); + procedure disconnect(status: IStatus); + function join(status: IStatus; transaction: ITransaction): ITransaction; + function validate(status: IStatus; attachment: IAttachment): ITransaction; + function enterDtc(status: IStatus): ITransaction; + end; + + ITransactionImpl = class(ITransaction) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure getInfo(status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); virtual; abstract; + procedure prepare(status: IStatus; msgLength: Cardinal; message: BytePtr); virtual; abstract; + procedure commit(status: IStatus); virtual; abstract; + procedure commitRetaining(status: IStatus); virtual; abstract; + procedure rollback(status: IStatus); virtual; abstract; + procedure rollbackRetaining(status: IStatus); virtual; abstract; + procedure disconnect(status: IStatus); virtual; abstract; + function join(status: IStatus; transaction: ITransaction): ITransaction; virtual; abstract; + function validate(status: IStatus; attachment: IAttachment): ITransaction; virtual; abstract; + function enterDtc(status: IStatus): ITransaction; virtual; abstract; + end; + + MessageMetadataVTable = class(ReferenceCountedVTable) + getCount: IMessageMetadata_getCountPtr; + getField: IMessageMetadata_getFieldPtr; + getRelation: IMessageMetadata_getRelationPtr; + getOwner: IMessageMetadata_getOwnerPtr; + getAlias: IMessageMetadata_getAliasPtr; + getType: IMessageMetadata_getTypePtr; + isNullable: IMessageMetadata_isNullablePtr; + getSubType: IMessageMetadata_getSubTypePtr; + getLength: IMessageMetadata_getLengthPtr; + getScale: IMessageMetadata_getScalePtr; + getCharSet: IMessageMetadata_getCharSetPtr; + getOffset: IMessageMetadata_getOffsetPtr; + getNullOffset: IMessageMetadata_getNullOffsetPtr; + getBuilder: IMessageMetadata_getBuilderPtr; + getMessageLength: IMessageMetadata_getMessageLengthPtr; + end; + + IMessageMetadata = class(IReferenceCounted) + const VERSION = 17; + + function getCount(status: IStatus): Cardinal; + function getField(status: IStatus; index: Cardinal): PAnsiChar; + function getRelation(status: IStatus; index: Cardinal): PAnsiChar; + function getOwner(status: IStatus; index: Cardinal): PAnsiChar; + function getAlias(status: IStatus; index: Cardinal): PAnsiChar; + function getType(status: IStatus; index: Cardinal): Cardinal; + function isNullable(status: IStatus; index: Cardinal): Boolean; + function getSubType(status: IStatus; index: Cardinal): Integer; + function getLength(status: IStatus; index: Cardinal): Cardinal; + function getScale(status: IStatus; index: Cardinal): Integer; + function getCharSet(status: IStatus; index: Cardinal): Cardinal; + function getOffset(status: IStatus; index: Cardinal): Cardinal; + function getNullOffset(status: IStatus; index: Cardinal): Cardinal; + function getBuilder(status: IStatus): IMetadataBuilder; + function getMessageLength(status: IStatus): Cardinal; + end; + + IMessageMetadataImpl = class(IMessageMetadata) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + function getCount(status: IStatus): Cardinal; virtual; abstract; + function getField(status: IStatus; index: Cardinal): PAnsiChar; virtual; abstract; + function getRelation(status: IStatus; index: Cardinal): PAnsiChar; virtual; abstract; + function getOwner(status: IStatus; index: Cardinal): PAnsiChar; virtual; abstract; + function getAlias(status: IStatus; index: Cardinal): PAnsiChar; virtual; abstract; + function getType(status: IStatus; index: Cardinal): Cardinal; virtual; abstract; + function isNullable(status: IStatus; index: Cardinal): Boolean; virtual; abstract; + function getSubType(status: IStatus; index: Cardinal): Integer; virtual; abstract; + function getLength(status: IStatus; index: Cardinal): Cardinal; virtual; abstract; + function getScale(status: IStatus; index: Cardinal): Integer; virtual; abstract; + function getCharSet(status: IStatus; index: Cardinal): Cardinal; virtual; abstract; + function getOffset(status: IStatus; index: Cardinal): Cardinal; virtual; abstract; + function getNullOffset(status: IStatus; index: Cardinal): Cardinal; virtual; abstract; + function getBuilder(status: IStatus): IMetadataBuilder; virtual; abstract; + function getMessageLength(status: IStatus): Cardinal; virtual; abstract; + end; + + MetadataBuilderVTable = class(ReferenceCountedVTable) + setType: IMetadataBuilder_setTypePtr; + setSubType: IMetadataBuilder_setSubTypePtr; + setLength: IMetadataBuilder_setLengthPtr; + setCharSet: IMetadataBuilder_setCharSetPtr; + setScale: IMetadataBuilder_setScalePtr; + truncate: IMetadataBuilder_truncatePtr; + moveNameToIndex: IMetadataBuilder_moveNameToIndexPtr; + remove: IMetadataBuilder_removePtr; + addField: IMetadataBuilder_addFieldPtr; + getMetadata: IMetadataBuilder_getMetadataPtr; + end; + + IMetadataBuilder = class(IReferenceCounted) + const VERSION = 12; + + procedure setType(status: IStatus; index: Cardinal; type_: Cardinal); + procedure setSubType(status: IStatus; index: Cardinal; subType: Integer); + procedure setLength(status: IStatus; index: Cardinal; length: Cardinal); + procedure setCharSet(status: IStatus; index: Cardinal; charSet: Cardinal); + procedure setScale(status: IStatus; index: Cardinal; scale: Cardinal); + procedure truncate(status: IStatus; count: Cardinal); + procedure moveNameToIndex(status: IStatus; name: PAnsiChar; index: Cardinal); + procedure remove(status: IStatus; index: Cardinal); + function addField(status: IStatus): Cardinal; + function getMetadata(status: IStatus): IMessageMetadata; + end; + + IMetadataBuilderImpl = class(IMetadataBuilder) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure setType(status: IStatus; index: Cardinal; type_: Cardinal); virtual; abstract; + procedure setSubType(status: IStatus; index: Cardinal; subType: Integer); virtual; abstract; + procedure setLength(status: IStatus; index: Cardinal; length: Cardinal); virtual; abstract; + procedure setCharSet(status: IStatus; index: Cardinal; charSet: Cardinal); virtual; abstract; + procedure setScale(status: IStatus; index: Cardinal; scale: Cardinal); virtual; abstract; + procedure truncate(status: IStatus; count: Cardinal); virtual; abstract; + procedure moveNameToIndex(status: IStatus; name: PAnsiChar; index: Cardinal); virtual; abstract; + procedure remove(status: IStatus; index: Cardinal); virtual; abstract; + function addField(status: IStatus): Cardinal; virtual; abstract; + function getMetadata(status: IStatus): IMessageMetadata; virtual; abstract; + end; + + ResultSetVTable = class(ReferenceCountedVTable) + fetchNext: IResultSet_fetchNextPtr; + fetchPrior: IResultSet_fetchPriorPtr; + fetchFirst: IResultSet_fetchFirstPtr; + fetchLast: IResultSet_fetchLastPtr; + fetchAbsolute: IResultSet_fetchAbsolutePtr; + fetchRelative: IResultSet_fetchRelativePtr; + isEof: IResultSet_isEofPtr; + isBof: IResultSet_isBofPtr; + getMetadata: IResultSet_getMetadataPtr; + close: IResultSet_closePtr; + setDelayedOutputFormat: IResultSet_setDelayedOutputFormatPtr; + end; + + IResultSet = class(IReferenceCounted) + const VERSION = 13; + + function fetchNext(status: IStatus; message: Pointer): Integer; + function fetchPrior(status: IStatus; message: Pointer): Integer; + function fetchFirst(status: IStatus; message: Pointer): Integer; + function fetchLast(status: IStatus; message: Pointer): Integer; + function fetchAbsolute(status: IStatus; position: Integer; message: Pointer): Integer; + function fetchRelative(status: IStatus; offset: Integer; message: Pointer): Integer; + function isEof(status: IStatus): Boolean; + function isBof(status: IStatus): Boolean; + function getMetadata(status: IStatus): IMessageMetadata; + procedure close(status: IStatus); + procedure setDelayedOutputFormat(status: IStatus; format: IMessageMetadata); + end; + + IResultSetImpl = class(IResultSet) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + function fetchNext(status: IStatus; message: Pointer): Integer; virtual; abstract; + function fetchPrior(status: IStatus; message: Pointer): Integer; virtual; abstract; + function fetchFirst(status: IStatus; message: Pointer): Integer; virtual; abstract; + function fetchLast(status: IStatus; message: Pointer): Integer; virtual; abstract; + function fetchAbsolute(status: IStatus; position: Integer; message: Pointer): Integer; virtual; abstract; + function fetchRelative(status: IStatus; offset: Integer; message: Pointer): Integer; virtual; abstract; + function isEof(status: IStatus): Boolean; virtual; abstract; + function isBof(status: IStatus): Boolean; virtual; abstract; + function getMetadata(status: IStatus): IMessageMetadata; virtual; abstract; + procedure close(status: IStatus); virtual; abstract; + procedure setDelayedOutputFormat(status: IStatus; format: IMessageMetadata); virtual; abstract; + end; + + StatementVTable = class(ReferenceCountedVTable) + getInfo: IStatement_getInfoPtr; + getType: IStatement_getTypePtr; + getPlan: IStatement_getPlanPtr; + getAffectedRecords: IStatement_getAffectedRecordsPtr; + getInputMetadata: IStatement_getInputMetadataPtr; + getOutputMetadata: IStatement_getOutputMetadataPtr; + execute: IStatement_executePtr; + openCursor: IStatement_openCursorPtr; + setCursorName: IStatement_setCursorNamePtr; + free: IStatement_freePtr; + getFlags: IStatement_getFlagsPtr; + end; + + IStatement = class(IReferenceCounted) + const VERSION = 13; + const PREPARE_PREFETCH_NONE = Cardinal(0); + const PREPARE_PREFETCH_TYPE = Cardinal(1); + const PREPARE_PREFETCH_INPUT_PARAMETERS = Cardinal(2); + const PREPARE_PREFETCH_OUTPUT_PARAMETERS = Cardinal(4); + const PREPARE_PREFETCH_LEGACY_PLAN = Cardinal(8); + const PREPARE_PREFETCH_DETAILED_PLAN = Cardinal(16); + const PREPARE_PREFETCH_AFFECTED_RECORDS = Cardinal(32); + const PREPARE_PREFETCH_FLAGS = Cardinal(64); + const PREPARE_PREFETCH_METADATA = Cardinal(IStatement.PREPARE_PREFETCH_TYPE or IStatement.PREPARE_PREFETCH_FLAGS or IStatement.PREPARE_PREFETCH_INPUT_PARAMETERS or IStatement.PREPARE_PREFETCH_OUTPUT_PARAMETERS); + const PREPARE_PREFETCH_ALL = Cardinal(IStatement.PREPARE_PREFETCH_METADATA or IStatement.PREPARE_PREFETCH_LEGACY_PLAN or IStatement.PREPARE_PREFETCH_DETAILED_PLAN or IStatement.PREPARE_PREFETCH_AFFECTED_RECORDS); + const FLAG_HAS_CURSOR = Cardinal(1); + const FLAG_REPEAT_EXECUTE = Cardinal(2); + const CURSOR_TYPE_SCROLLABLE = Cardinal(1); + + procedure getInfo(status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); + function getType(status: IStatus): Cardinal; + function getPlan(status: IStatus; detailed: Boolean): PAnsiChar; + function getAffectedRecords(status: IStatus): QWord; + function getInputMetadata(status: IStatus): IMessageMetadata; + function getOutputMetadata(status: IStatus): IMessageMetadata; + function execute(status: IStatus; transaction: ITransaction; inMetadata: IMessageMetadata; inBuffer: Pointer; outMetadata: IMessageMetadata; outBuffer: Pointer): ITransaction; + function openCursor(status: IStatus; transaction: ITransaction; inMetadata: IMessageMetadata; inBuffer: Pointer; outMetadata: IMessageMetadata; flags: Cardinal): IResultSet; + procedure setCursorName(status: IStatus; name: PAnsiChar); + procedure free(status: IStatus); + function getFlags(status: IStatus): Cardinal; + end; + + IStatementImpl = class(IStatement) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure getInfo(status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); virtual; abstract; + function getType(status: IStatus): Cardinal; virtual; abstract; + function getPlan(status: IStatus; detailed: Boolean): PAnsiChar; virtual; abstract; + function getAffectedRecords(status: IStatus): QWord; virtual; abstract; + function getInputMetadata(status: IStatus): IMessageMetadata; virtual; abstract; + function getOutputMetadata(status: IStatus): IMessageMetadata; virtual; abstract; + function execute(status: IStatus; transaction: ITransaction; inMetadata: IMessageMetadata; inBuffer: Pointer; outMetadata: IMessageMetadata; outBuffer: Pointer): ITransaction; virtual; abstract; + function openCursor(status: IStatus; transaction: ITransaction; inMetadata: IMessageMetadata; inBuffer: Pointer; outMetadata: IMessageMetadata; flags: Cardinal): IResultSet; virtual; abstract; + procedure setCursorName(status: IStatus; name: PAnsiChar); virtual; abstract; + procedure free(status: IStatus); virtual; abstract; + function getFlags(status: IStatus): Cardinal; virtual; abstract; + end; + + RequestVTable = class(ReferenceCountedVTable) + receive: IRequest_receivePtr; + send: IRequest_sendPtr; + getInfo: IRequest_getInfoPtr; + start: IRequest_startPtr; + startAndSend: IRequest_startAndSendPtr; + unwind: IRequest_unwindPtr; + free: IRequest_freePtr; + end; + + IRequest = class(IReferenceCounted) + const VERSION = 9; + + procedure receive(status: IStatus; level: Integer; msgType: Cardinal; length: Cardinal; message: BytePtr); + procedure send(status: IStatus; level: Integer; msgType: Cardinal; length: Cardinal; message: BytePtr); + procedure getInfo(status: IStatus; level: Integer; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); + procedure start(status: IStatus; tra: ITransaction; level: Integer); + procedure startAndSend(status: IStatus; tra: ITransaction; level: Integer; msgType: Cardinal; length: Cardinal; message: BytePtr); + procedure unwind(status: IStatus; level: Integer); + procedure free(status: IStatus); + end; + + IRequestImpl = class(IRequest) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure receive(status: IStatus; level: Integer; msgType: Cardinal; length: Cardinal; message: BytePtr); virtual; abstract; + procedure send(status: IStatus; level: Integer; msgType: Cardinal; length: Cardinal; message: BytePtr); virtual; abstract; + procedure getInfo(status: IStatus; level: Integer; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); virtual; abstract; + procedure start(status: IStatus; tra: ITransaction; level: Integer); virtual; abstract; + procedure startAndSend(status: IStatus; tra: ITransaction; level: Integer; msgType: Cardinal; length: Cardinal; message: BytePtr); virtual; abstract; + procedure unwind(status: IStatus; level: Integer); virtual; abstract; + procedure free(status: IStatus); virtual; abstract; + end; + + EventsVTable = class(ReferenceCountedVTable) + cancel: IEvents_cancelPtr; + end; + + IEvents = class(IReferenceCounted) + const VERSION = 3; + + procedure cancel(status: IStatus); + end; + + IEventsImpl = class(IEvents) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure cancel(status: IStatus); virtual; abstract; + end; + + AttachmentVTable = class(ReferenceCountedVTable) + getInfo: IAttachment_getInfoPtr; + startTransaction: IAttachment_startTransactionPtr; + reconnectTransaction: IAttachment_reconnectTransactionPtr; + compileRequest: IAttachment_compileRequestPtr; + transactRequest: IAttachment_transactRequestPtr; + createBlob: IAttachment_createBlobPtr; + openBlob: IAttachment_openBlobPtr; + getSlice: IAttachment_getSlicePtr; + putSlice: IAttachment_putSlicePtr; + executeDyn: IAttachment_executeDynPtr; + prepare: IAttachment_preparePtr; + execute: IAttachment_executePtr; + openCursor: IAttachment_openCursorPtr; + queEvents: IAttachment_queEventsPtr; + cancelOperation: IAttachment_cancelOperationPtr; + ping: IAttachment_pingPtr; + detach: IAttachment_detachPtr; + dropDatabase: IAttachment_dropDatabasePtr; + end; + + IAttachment = class(IReferenceCounted) + const VERSION = 20; + + procedure getInfo(status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); + function startTransaction(status: IStatus; tpbLength: Cardinal; tpb: BytePtr): ITransaction; + function reconnectTransaction(status: IStatus; length: Cardinal; id: BytePtr): ITransaction; + function compileRequest(status: IStatus; blrLength: Cardinal; blr: BytePtr): IRequest; + procedure transactRequest(status: IStatus; transaction: ITransaction; blrLength: Cardinal; blr: BytePtr; inMsgLength: Cardinal; inMsg: BytePtr; outMsgLength: Cardinal; outMsg: BytePtr); + function createBlob(status: IStatus; transaction: ITransaction; id: ISC_QUADPtr; bpbLength: Cardinal; bpb: BytePtr): IBlob; + function openBlob(status: IStatus; transaction: ITransaction; id: ISC_QUADPtr; bpbLength: Cardinal; bpb: BytePtr): IBlob; + function getSlice(status: IStatus; transaction: ITransaction; id: ISC_QUADPtr; sdlLength: Cardinal; sdl: BytePtr; paramLength: Cardinal; param: BytePtr; sliceLength: Integer; slice: BytePtr): Integer; + procedure putSlice(status: IStatus; transaction: ITransaction; id: ISC_QUADPtr; sdlLength: Cardinal; sdl: BytePtr; paramLength: Cardinal; param: BytePtr; sliceLength: Integer; slice: BytePtr); + procedure executeDyn(status: IStatus; transaction: ITransaction; length: Cardinal; dyn: BytePtr); + function prepare(status: IStatus; tra: ITransaction; stmtLength: Cardinal; sqlStmt: PAnsiChar; dialect: Cardinal; flags: Cardinal): IStatement; + function execute(status: IStatus; transaction: ITransaction; stmtLength: Cardinal; sqlStmt: PAnsiChar; dialect: Cardinal; inMetadata: IMessageMetadata; inBuffer: Pointer; outMetadata: IMessageMetadata; outBuffer: Pointer): ITransaction; + function openCursor(status: IStatus; transaction: ITransaction; stmtLength: Cardinal; sqlStmt: PAnsiChar; dialect: Cardinal; inMetadata: IMessageMetadata; inBuffer: Pointer; outMetadata: IMessageMetadata; cursorName: PAnsiChar; cursorFlags: Cardinal): IResultSet; + function queEvents(status: IStatus; callback: IEventCallback; length: Cardinal; events: BytePtr): IEvents; + procedure cancelOperation(status: IStatus; option: Integer); + procedure ping(status: IStatus); + procedure detach(status: IStatus); + procedure dropDatabase(status: IStatus); + end; + + IAttachmentImpl = class(IAttachment) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure getInfo(status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); virtual; abstract; + function startTransaction(status: IStatus; tpbLength: Cardinal; tpb: BytePtr): ITransaction; virtual; abstract; + function reconnectTransaction(status: IStatus; length: Cardinal; id: BytePtr): ITransaction; virtual; abstract; + function compileRequest(status: IStatus; blrLength: Cardinal; blr: BytePtr): IRequest; virtual; abstract; + procedure transactRequest(status: IStatus; transaction: ITransaction; blrLength: Cardinal; blr: BytePtr; inMsgLength: Cardinal; inMsg: BytePtr; outMsgLength: Cardinal; outMsg: BytePtr); virtual; abstract; + function createBlob(status: IStatus; transaction: ITransaction; id: ISC_QUADPtr; bpbLength: Cardinal; bpb: BytePtr): IBlob; virtual; abstract; + function openBlob(status: IStatus; transaction: ITransaction; id: ISC_QUADPtr; bpbLength: Cardinal; bpb: BytePtr): IBlob; virtual; abstract; + function getSlice(status: IStatus; transaction: ITransaction; id: ISC_QUADPtr; sdlLength: Cardinal; sdl: BytePtr; paramLength: Cardinal; param: BytePtr; sliceLength: Integer; slice: BytePtr): Integer; virtual; abstract; + procedure putSlice(status: IStatus; transaction: ITransaction; id: ISC_QUADPtr; sdlLength: Cardinal; sdl: BytePtr; paramLength: Cardinal; param: BytePtr; sliceLength: Integer; slice: BytePtr); virtual; abstract; + procedure executeDyn(status: IStatus; transaction: ITransaction; length: Cardinal; dyn: BytePtr); virtual; abstract; + function prepare(status: IStatus; tra: ITransaction; stmtLength: Cardinal; sqlStmt: PAnsiChar; dialect: Cardinal; flags: Cardinal): IStatement; virtual; abstract; + function execute(status: IStatus; transaction: ITransaction; stmtLength: Cardinal; sqlStmt: PAnsiChar; dialect: Cardinal; inMetadata: IMessageMetadata; inBuffer: Pointer; outMetadata: IMessageMetadata; outBuffer: Pointer): ITransaction; virtual; abstract; + function openCursor(status: IStatus; transaction: ITransaction; stmtLength: Cardinal; sqlStmt: PAnsiChar; dialect: Cardinal; inMetadata: IMessageMetadata; inBuffer: Pointer; outMetadata: IMessageMetadata; cursorName: PAnsiChar; cursorFlags: Cardinal): IResultSet; virtual; abstract; + function queEvents(status: IStatus; callback: IEventCallback; length: Cardinal; events: BytePtr): IEvents; virtual; abstract; + procedure cancelOperation(status: IStatus; option: Integer); virtual; abstract; + procedure ping(status: IStatus); virtual; abstract; + procedure detach(status: IStatus); virtual; abstract; + procedure dropDatabase(status: IStatus); virtual; abstract; + end; + + ServiceVTable = class(ReferenceCountedVTable) + detach: IService_detachPtr; + query: IService_queryPtr; + start: IService_startPtr; + end; + + IService = class(IReferenceCounted) + const VERSION = 5; + + procedure detach(status: IStatus); + procedure query(status: IStatus; sendLength: Cardinal; sendItems: BytePtr; receiveLength: Cardinal; receiveItems: BytePtr; bufferLength: Cardinal; buffer: BytePtr); + procedure start(status: IStatus; spbLength: Cardinal; spb: BytePtr); + end; + + IServiceImpl = class(IService) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure detach(status: IStatus); virtual; abstract; + procedure query(status: IStatus; sendLength: Cardinal; sendItems: BytePtr; receiveLength: Cardinal; receiveItems: BytePtr; bufferLength: Cardinal; buffer: BytePtr); virtual; abstract; + procedure start(status: IStatus; spbLength: Cardinal; spb: BytePtr); virtual; abstract; + end; + + ProviderVTable = class(PluginBaseVTable) + attachDatabase: IProvider_attachDatabasePtr; + createDatabase: IProvider_createDatabasePtr; + attachServiceManager: IProvider_attachServiceManagerPtr; + shutdown: IProvider_shutdownPtr; + setDbCryptCallback: IProvider_setDbCryptCallbackPtr; + end; + + IProvider = class(IPluginBase) + const VERSION = 9; + + function attachDatabase(status: IStatus; fileName: PAnsiChar; dpbLength: Cardinal; dpb: BytePtr): IAttachment; + function createDatabase(status: IStatus; fileName: PAnsiChar; dpbLength: Cardinal; dpb: BytePtr): IAttachment; + function attachServiceManager(status: IStatus; service: PAnsiChar; spbLength: Cardinal; spb: BytePtr): IService; + procedure shutdown(status: IStatus; timeout: Cardinal; reason: Integer); + procedure setDbCryptCallback(status: IStatus; cryptCallback: ICryptKeyCallback); + end; + + IProviderImpl = class(IProvider) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure setOwner(r: IReferenceCounted); virtual; abstract; + function getOwner(): IReferenceCounted; virtual; abstract; + function attachDatabase(status: IStatus; fileName: PAnsiChar; dpbLength: Cardinal; dpb: BytePtr): IAttachment; virtual; abstract; + function createDatabase(status: IStatus; fileName: PAnsiChar; dpbLength: Cardinal; dpb: BytePtr): IAttachment; virtual; abstract; + function attachServiceManager(status: IStatus; service: PAnsiChar; spbLength: Cardinal; spb: BytePtr): IService; virtual; abstract; + procedure shutdown(status: IStatus; timeout: Cardinal; reason: Integer); virtual; abstract; + procedure setDbCryptCallback(status: IStatus; cryptCallback: ICryptKeyCallback); virtual; abstract; + end; + + DtcStartVTable = class(DisposableVTable) + addAttachment: IDtcStart_addAttachmentPtr; + addWithTpb: IDtcStart_addWithTpbPtr; + start: IDtcStart_startPtr; + end; + + IDtcStart = class(IDisposable) + const VERSION = 4; + + procedure addAttachment(status: IStatus; att: IAttachment); + procedure addWithTpb(status: IStatus; att: IAttachment; length: Cardinal; tpb: BytePtr); + function start(status: IStatus): ITransaction; + end; + + IDtcStartImpl = class(IDtcStart) + constructor create; + + procedure dispose(); virtual; abstract; + procedure addAttachment(status: IStatus; att: IAttachment); virtual; abstract; + procedure addWithTpb(status: IStatus; att: IAttachment; length: Cardinal; tpb: BytePtr); virtual; abstract; + function start(status: IStatus): ITransaction; virtual; abstract; + end; + + DtcVTable = class(VersionedVTable) + join: IDtc_joinPtr; + startBuilder: IDtc_startBuilderPtr; + end; + + IDtc = class(IVersioned) + const VERSION = 2; + + function join(status: IStatus; one: ITransaction; two: ITransaction): ITransaction; + function startBuilder(status: IStatus): IDtcStart; + end; + + IDtcImpl = class(IDtc) + constructor create; + + function join(status: IStatus; one: ITransaction; two: ITransaction): ITransaction; virtual; abstract; + function startBuilder(status: IStatus): IDtcStart; virtual; abstract; + end; + + AuthVTable = class(PluginBaseVTable) + end; + + IAuth = class(IPluginBase) + const VERSION = 4; + const AUTH_FAILED = Integer(-1); + const AUTH_SUCCESS = Integer(0); + const AUTH_MORE_DATA = Integer(1); + const AUTH_CONTINUE = Integer(2); + + end; + + IAuthImpl = class(IAuth) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure setOwner(r: IReferenceCounted); virtual; abstract; + function getOwner(): IReferenceCounted; virtual; abstract; + end; + + WriterVTable = class(VersionedVTable) + reset: IWriter_resetPtr; + add: IWriter_addPtr; + setType: IWriter_setTypePtr; + setDb: IWriter_setDbPtr; + end; + + IWriter = class(IVersioned) + const VERSION = 4; + + procedure reset(); + procedure add(status: IStatus; name: PAnsiChar); + procedure setType(status: IStatus; value: PAnsiChar); + procedure setDb(status: IStatus; value: PAnsiChar); + end; + + IWriterImpl = class(IWriter) + constructor create; + + procedure reset(); virtual; abstract; + procedure add(status: IStatus; name: PAnsiChar); virtual; abstract; + procedure setType(status: IStatus; value: PAnsiChar); virtual; abstract; + procedure setDb(status: IStatus; value: PAnsiChar); virtual; abstract; + end; + + ServerBlockVTable = class(VersionedVTable) + getLogin: IServerBlock_getLoginPtr; + getData: IServerBlock_getDataPtr; + putData: IServerBlock_putDataPtr; + newKey: IServerBlock_newKeyPtr; + end; + + IServerBlock = class(IVersioned) + const VERSION = 4; + + function getLogin(): PAnsiChar; + function getData(length: CardinalPtr): BytePtr; + procedure putData(status: IStatus; length: Cardinal; data: Pointer); + function newKey(status: IStatus): ICryptKey; + end; + + IServerBlockImpl = class(IServerBlock) + constructor create; + + function getLogin(): PAnsiChar; virtual; abstract; + function getData(length: CardinalPtr): BytePtr; virtual; abstract; + procedure putData(status: IStatus; length: Cardinal; data: Pointer); virtual; abstract; + function newKey(status: IStatus): ICryptKey; virtual; abstract; + end; + + ClientBlockVTable = class(ReferenceCountedVTable) + getLogin: IClientBlock_getLoginPtr; + getPassword: IClientBlock_getPasswordPtr; + getData: IClientBlock_getDataPtr; + putData: IClientBlock_putDataPtr; + newKey: IClientBlock_newKeyPtr; + end; + + IClientBlock = class(IReferenceCounted) + const VERSION = 7; + + function getLogin(): PAnsiChar; + function getPassword(): PAnsiChar; + function getData(length: CardinalPtr): BytePtr; + procedure putData(status: IStatus; length: Cardinal; data: Pointer); + function newKey(status: IStatus): ICryptKey; + end; + + IClientBlockImpl = class(IClientBlock) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + function getLogin(): PAnsiChar; virtual; abstract; + function getPassword(): PAnsiChar; virtual; abstract; + function getData(length: CardinalPtr): BytePtr; virtual; abstract; + procedure putData(status: IStatus; length: Cardinal; data: Pointer); virtual; abstract; + function newKey(status: IStatus): ICryptKey; virtual; abstract; + end; + + ServerVTable = class(AuthVTable) + authenticate: IServer_authenticatePtr; + end; + + IServer = class(IAuth) + const VERSION = 5; + + function authenticate(status: IStatus; sBlock: IServerBlock; writerInterface: IWriter): Integer; + end; + + IServerImpl = class(IServer) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure setOwner(r: IReferenceCounted); virtual; abstract; + function getOwner(): IReferenceCounted; virtual; abstract; + function authenticate(status: IStatus; sBlock: IServerBlock; writerInterface: IWriter): Integer; virtual; abstract; + end; + + ClientVTable = class(AuthVTable) + authenticate: IClient_authenticatePtr; + end; + + IClient = class(IAuth) + const VERSION = 5; + + function authenticate(status: IStatus; cBlock: IClientBlock): Integer; + end; + + IClientImpl = class(IClient) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure setOwner(r: IReferenceCounted); virtual; abstract; + function getOwner(): IReferenceCounted; virtual; abstract; + function authenticate(status: IStatus; cBlock: IClientBlock): Integer; virtual; abstract; + end; + + UserFieldVTable = class(VersionedVTable) + entered: IUserField_enteredPtr; + specified: IUserField_specifiedPtr; + setEntered: IUserField_setEnteredPtr; + end; + + IUserField = class(IVersioned) + const VERSION = 3; + + function entered(): Integer; + function specified(): Integer; + procedure setEntered(status: IStatus; newValue: Integer); + end; + + IUserFieldImpl = class(IUserField) + constructor create; + + function entered(): Integer; virtual; abstract; + function specified(): Integer; virtual; abstract; + procedure setEntered(status: IStatus; newValue: Integer); virtual; abstract; + end; + + CharUserFieldVTable = class(UserFieldVTable) + get: ICharUserField_getPtr; + set_: ICharUserField_set_Ptr; + end; + + ICharUserField = class(IUserField) + const VERSION = 5; + + function get(): PAnsiChar; + procedure set_(status: IStatus; newValue: PAnsiChar); + end; + + ICharUserFieldImpl = class(ICharUserField) + constructor create; + + function entered(): Integer; virtual; abstract; + function specified(): Integer; virtual; abstract; + procedure setEntered(status: IStatus; newValue: Integer); virtual; abstract; + function get(): PAnsiChar; virtual; abstract; + procedure set_(status: IStatus; newValue: PAnsiChar); virtual; abstract; + end; + + IntUserFieldVTable = class(UserFieldVTable) + get: IIntUserField_getPtr; + set_: IIntUserField_set_Ptr; + end; + + IIntUserField = class(IUserField) + const VERSION = 5; + + function get(): Integer; + procedure set_(status: IStatus; newValue: Integer); + end; + + IIntUserFieldImpl = class(IIntUserField) + constructor create; + + function entered(): Integer; virtual; abstract; + function specified(): Integer; virtual; abstract; + procedure setEntered(status: IStatus; newValue: Integer); virtual; abstract; + function get(): Integer; virtual; abstract; + procedure set_(status: IStatus; newValue: Integer); virtual; abstract; + end; + + UserVTable = class(VersionedVTable) + operation: IUser_operationPtr; + userName: IUser_userNamePtr; + password: IUser_passwordPtr; + firstName: IUser_firstNamePtr; + lastName: IUser_lastNamePtr; + middleName: IUser_middleNamePtr; + comment: IUser_commentPtr; + attributes: IUser_attributesPtr; + active: IUser_activePtr; + admin: IUser_adminPtr; + clear: IUser_clearPtr; + end; + + IUser = class(IVersioned) + const VERSION = 11; + const OP_USER_ADD = Cardinal(1); + const OP_USER_MODIFY = Cardinal(2); + const OP_USER_DELETE = Cardinal(3); + const OP_USER_DISPLAY = Cardinal(4); + const OP_USER_SET_MAP = Cardinal(5); + const OP_USER_DROP_MAP = Cardinal(6); + + function operation(): Cardinal; + function userName(): ICharUserField; + function password(): ICharUserField; + function firstName(): ICharUserField; + function lastName(): ICharUserField; + function middleName(): ICharUserField; + function comment(): ICharUserField; + function attributes(): ICharUserField; + function active(): IIntUserField; + function admin(): IIntUserField; + procedure clear(status: IStatus); + end; + + IUserImpl = class(IUser) + constructor create; + + function operation(): Cardinal; virtual; abstract; + function userName(): ICharUserField; virtual; abstract; + function password(): ICharUserField; virtual; abstract; + function firstName(): ICharUserField; virtual; abstract; + function lastName(): ICharUserField; virtual; abstract; + function middleName(): ICharUserField; virtual; abstract; + function comment(): ICharUserField; virtual; abstract; + function attributes(): ICharUserField; virtual; abstract; + function active(): IIntUserField; virtual; abstract; + function admin(): IIntUserField; virtual; abstract; + procedure clear(status: IStatus); virtual; abstract; + end; + + ListUsersVTable = class(VersionedVTable) + list: IListUsers_listPtr; + end; + + IListUsers = class(IVersioned) + const VERSION = 1; + + procedure list(status: IStatus; user: IUser); + end; + + IListUsersImpl = class(IListUsers) + constructor create; + + procedure list(status: IStatus; user: IUser); virtual; abstract; + end; + + LogonInfoVTable = class(VersionedVTable) + name: ILogonInfo_namePtr; + role: ILogonInfo_rolePtr; + networkProtocol: ILogonInfo_networkProtocolPtr; + remoteAddress: ILogonInfo_remoteAddressPtr; + authBlock: ILogonInfo_authBlockPtr; + end; + + ILogonInfo = class(IVersioned) + const VERSION = 5; + + function name(): PAnsiChar; + function role(): PAnsiChar; + function networkProtocol(): PAnsiChar; + function remoteAddress(): PAnsiChar; + function authBlock(length: CardinalPtr): BytePtr; + end; + + ILogonInfoImpl = class(ILogonInfo) + constructor create; + + function name(): PAnsiChar; virtual; abstract; + function role(): PAnsiChar; virtual; abstract; + function networkProtocol(): PAnsiChar; virtual; abstract; + function remoteAddress(): PAnsiChar; virtual; abstract; + function authBlock(length: CardinalPtr): BytePtr; virtual; abstract; + end; + + ManagementVTable = class(PluginBaseVTable) + start: IManagement_startPtr; + execute: IManagement_executePtr; + commit: IManagement_commitPtr; + rollback: IManagement_rollbackPtr; + end; + + IManagement = class(IPluginBase) + const VERSION = 8; + + procedure start(status: IStatus; logonInfo: ILogonInfo); + function execute(status: IStatus; user: IUser; callback: IListUsers): Integer; + procedure commit(status: IStatus); + procedure rollback(status: IStatus); + end; + + IManagementImpl = class(IManagement) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure setOwner(r: IReferenceCounted); virtual; abstract; + function getOwner(): IReferenceCounted; virtual; abstract; + procedure start(status: IStatus; logonInfo: ILogonInfo); virtual; abstract; + function execute(status: IStatus; user: IUser; callback: IListUsers): Integer; virtual; abstract; + procedure commit(status: IStatus); virtual; abstract; + procedure rollback(status: IStatus); virtual; abstract; + end; + + WireCryptPluginVTable = class(PluginBaseVTable) + getKnownTypes: IWireCryptPlugin_getKnownTypesPtr; + setKey: IWireCryptPlugin_setKeyPtr; + encrypt: IWireCryptPlugin_encryptPtr; + decrypt: IWireCryptPlugin_decryptPtr; + end; + + IWireCryptPlugin = class(IPluginBase) + const VERSION = 8; + + function getKnownTypes(status: IStatus): PAnsiChar; + procedure setKey(status: IStatus; key: ICryptKey); + procedure encrypt(status: IStatus; length: Cardinal; from: Pointer; to_: Pointer); + procedure decrypt(status: IStatus; length: Cardinal; from: Pointer; to_: Pointer); + end; + + IWireCryptPluginImpl = class(IWireCryptPlugin) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure setOwner(r: IReferenceCounted); virtual; abstract; + function getOwner(): IReferenceCounted; virtual; abstract; + function getKnownTypes(status: IStatus): PAnsiChar; virtual; abstract; + procedure setKey(status: IStatus; key: ICryptKey); virtual; abstract; + procedure encrypt(status: IStatus; length: Cardinal; from: Pointer; to_: Pointer); virtual; abstract; + procedure decrypt(status: IStatus; length: Cardinal; from: Pointer; to_: Pointer); virtual; abstract; + end; + + CryptKeyCallbackVTable = class(VersionedVTable) + callback: ICryptKeyCallback_callbackPtr; + end; + + ICryptKeyCallback = class(IVersioned) + const VERSION = 1; + + function callback(dataLength: Cardinal; data: Pointer; bufferLength: Cardinal; buffer: Pointer): Cardinal; + end; + + ICryptKeyCallbackImpl = class(ICryptKeyCallback) + constructor create; + + function callback(dataLength: Cardinal; data: Pointer; bufferLength: Cardinal; buffer: Pointer): Cardinal; virtual; abstract; + end; + + KeyHolderPluginVTable = class(PluginBaseVTable) + keyCallback: IKeyHolderPlugin_keyCallbackPtr; + keyHandle: IKeyHolderPlugin_keyHandlePtr; + end; + + IKeyHolderPlugin = class(IPluginBase) + const VERSION = 6; + + function keyCallback(status: IStatus; callback: ICryptKeyCallback): Integer; + function keyHandle(status: IStatus; keyName: PAnsiChar): ICryptKeyCallback; + end; + + IKeyHolderPluginImpl = class(IKeyHolderPlugin) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure setOwner(r: IReferenceCounted); virtual; abstract; + function getOwner(): IReferenceCounted; virtual; abstract; + function keyCallback(status: IStatus; callback: ICryptKeyCallback): Integer; virtual; abstract; + function keyHandle(status: IStatus; keyName: PAnsiChar): ICryptKeyCallback; virtual; abstract; + end; + + DbCryptPluginVTable = class(PluginBaseVTable) + setKey: IDbCryptPlugin_setKeyPtr; + encrypt: IDbCryptPlugin_encryptPtr; + decrypt: IDbCryptPlugin_decryptPtr; + end; + + IDbCryptPlugin = class(IPluginBase) + const VERSION = 7; + + procedure setKey(status: IStatus; length: Cardinal; sources: IKeyHolderPluginPtr; keyName: PAnsiChar); + procedure encrypt(status: IStatus; length: Cardinal; from: Pointer; to_: Pointer); + procedure decrypt(status: IStatus; length: Cardinal; from: Pointer; to_: Pointer); + end; + + IDbCryptPluginImpl = class(IDbCryptPlugin) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure setOwner(r: IReferenceCounted); virtual; abstract; + function getOwner(): IReferenceCounted; virtual; abstract; + procedure setKey(status: IStatus; length: Cardinal; sources: IKeyHolderPluginPtr; keyName: PAnsiChar); virtual; abstract; + procedure encrypt(status: IStatus; length: Cardinal; from: Pointer; to_: Pointer); virtual; abstract; + procedure decrypt(status: IStatus; length: Cardinal; from: Pointer; to_: Pointer); virtual; abstract; + end; + + ExternalContextVTable = class(VersionedVTable) + getMaster: IExternalContext_getMasterPtr; + getEngine: IExternalContext_getEnginePtr; + getAttachment: IExternalContext_getAttachmentPtr; + getTransaction: IExternalContext_getTransactionPtr; + getUserName: IExternalContext_getUserNamePtr; + getDatabaseName: IExternalContext_getDatabaseNamePtr; + getClientCharSet: IExternalContext_getClientCharSetPtr; + obtainInfoCode: IExternalContext_obtainInfoCodePtr; + getInfo: IExternalContext_getInfoPtr; + setInfo: IExternalContext_setInfoPtr; + end; + + IExternalContext = class(IVersioned) + const VERSION = 10; + + function getMaster(): IMaster; + function getEngine(status: IStatus): IExternalEngine; + function getAttachment(status: IStatus): IAttachment; + function getTransaction(status: IStatus): ITransaction; + function getUserName(): PAnsiChar; + function getDatabaseName(): PAnsiChar; + function getClientCharSet(): PAnsiChar; + function obtainInfoCode(): Integer; + function getInfo(code: Integer): Pointer; + function setInfo(code: Integer; value: Pointer): Pointer; + end; + + IExternalContextImpl = class(IExternalContext) + constructor create; + + function getMaster(): IMaster; virtual; abstract; + function getEngine(status: IStatus): IExternalEngine; virtual; abstract; + function getAttachment(status: IStatus): IAttachment; virtual; abstract; + function getTransaction(status: IStatus): ITransaction; virtual; abstract; + function getUserName(): PAnsiChar; virtual; abstract; + function getDatabaseName(): PAnsiChar; virtual; abstract; + function getClientCharSet(): PAnsiChar; virtual; abstract; + function obtainInfoCode(): Integer; virtual; abstract; + function getInfo(code: Integer): Pointer; virtual; abstract; + function setInfo(code: Integer; value: Pointer): Pointer; virtual; abstract; + end; + + ExternalResultSetVTable = class(DisposableVTable) + fetch: IExternalResultSet_fetchPtr; + end; + + IExternalResultSet = class(IDisposable) + const VERSION = 2; + + function fetch(status: IStatus): Boolean; + end; + + IExternalResultSetImpl = class(IExternalResultSet) + constructor create; + + procedure dispose(); virtual; abstract; + function fetch(status: IStatus): Boolean; virtual; abstract; + end; + + ExternalFunctionVTable = class(DisposableVTable) + getCharSet: IExternalFunction_getCharSetPtr; + execute: IExternalFunction_executePtr; + end; + + IExternalFunction = class(IDisposable) + const VERSION = 3; + + procedure getCharSet(status: IStatus; context: IExternalContext; name: PAnsiChar; nameSize: Cardinal); + procedure execute(status: IStatus; context: IExternalContext; inMsg: Pointer; outMsg: Pointer); + end; + + IExternalFunctionImpl = class(IExternalFunction) + constructor create; + + procedure dispose(); virtual; abstract; + procedure getCharSet(status: IStatus; context: IExternalContext; name: PAnsiChar; nameSize: Cardinal); virtual; abstract; + procedure execute(status: IStatus; context: IExternalContext; inMsg: Pointer; outMsg: Pointer); virtual; abstract; + end; + + ExternalProcedureVTable = class(DisposableVTable) + getCharSet: IExternalProcedure_getCharSetPtr; + open: IExternalProcedure_openPtr; + end; + + IExternalProcedure = class(IDisposable) + const VERSION = 3; + + procedure getCharSet(status: IStatus; context: IExternalContext; name: PAnsiChar; nameSize: Cardinal); + function open(status: IStatus; context: IExternalContext; inMsg: Pointer; outMsg: Pointer): IExternalResultSet; + end; + + IExternalProcedureImpl = class(IExternalProcedure) + constructor create; + + procedure dispose(); virtual; abstract; + procedure getCharSet(status: IStatus; context: IExternalContext; name: PAnsiChar; nameSize: Cardinal); virtual; abstract; + function open(status: IStatus; context: IExternalContext; inMsg: Pointer; outMsg: Pointer): IExternalResultSet; virtual; abstract; + end; + + ExternalTriggerVTable = class(DisposableVTable) + getCharSet: IExternalTrigger_getCharSetPtr; + execute: IExternalTrigger_executePtr; + end; + + IExternalTrigger = class(IDisposable) + const VERSION = 3; + const TYPE_BEFORE = Cardinal(1); + const TYPE_AFTER = Cardinal(2); + const TYPE_DATABASE = Cardinal(3); + const ACTION_INSERT = Cardinal(1); + const ACTION_UPDATE = Cardinal(2); + const ACTION_DELETE = Cardinal(3); + const ACTION_CONNECT = Cardinal(4); + const ACTION_DISCONNECT = Cardinal(5); + const ACTION_TRANS_START = Cardinal(6); + const ACTION_TRANS_COMMIT = Cardinal(7); + const ACTION_TRANS_ROLLBACK = Cardinal(8); + const ACTION_DDL = Cardinal(9); + + procedure getCharSet(status: IStatus; context: IExternalContext; name: PAnsiChar; nameSize: Cardinal); + procedure execute(status: IStatus; context: IExternalContext; action: Cardinal; oldMsg: Pointer; newMsg: Pointer); + end; + + IExternalTriggerImpl = class(IExternalTrigger) + constructor create; + + procedure dispose(); virtual; abstract; + procedure getCharSet(status: IStatus; context: IExternalContext; name: PAnsiChar; nameSize: Cardinal); virtual; abstract; + procedure execute(status: IStatus; context: IExternalContext; action: Cardinal; oldMsg: Pointer; newMsg: Pointer); virtual; abstract; + end; + + RoutineMetadataVTable = class(VersionedVTable) + getPackage: IRoutineMetadata_getPackagePtr; + getName: IRoutineMetadata_getNamePtr; + getEntryPoint: IRoutineMetadata_getEntryPointPtr; + getBody: IRoutineMetadata_getBodyPtr; + getInputMetadata: IRoutineMetadata_getInputMetadataPtr; + getOutputMetadata: IRoutineMetadata_getOutputMetadataPtr; + getTriggerMetadata: IRoutineMetadata_getTriggerMetadataPtr; + getTriggerTable: IRoutineMetadata_getTriggerTablePtr; + getTriggerType: IRoutineMetadata_getTriggerTypePtr; + end; + + IRoutineMetadata = class(IVersioned) + const VERSION = 9; + + function getPackage(status: IStatus): PAnsiChar; + function getName(status: IStatus): PAnsiChar; + function getEntryPoint(status: IStatus): PAnsiChar; + function getBody(status: IStatus): PAnsiChar; + function getInputMetadata(status: IStatus): IMessageMetadata; + function getOutputMetadata(status: IStatus): IMessageMetadata; + function getTriggerMetadata(status: IStatus): IMessageMetadata; + function getTriggerTable(status: IStatus): PAnsiChar; + function getTriggerType(status: IStatus): Cardinal; + end; + + IRoutineMetadataImpl = class(IRoutineMetadata) + constructor create; + + function getPackage(status: IStatus): PAnsiChar; virtual; abstract; + function getName(status: IStatus): PAnsiChar; virtual; abstract; + function getEntryPoint(status: IStatus): PAnsiChar; virtual; abstract; + function getBody(status: IStatus): PAnsiChar; virtual; abstract; + function getInputMetadata(status: IStatus): IMessageMetadata; virtual; abstract; + function getOutputMetadata(status: IStatus): IMessageMetadata; virtual; abstract; + function getTriggerMetadata(status: IStatus): IMessageMetadata; virtual; abstract; + function getTriggerTable(status: IStatus): PAnsiChar; virtual; abstract; + function getTriggerType(status: IStatus): Cardinal; virtual; abstract; + end; + + ExternalEngineVTable = class(PluginBaseVTable) + open: IExternalEngine_openPtr; + openAttachment: IExternalEngine_openAttachmentPtr; + closeAttachment: IExternalEngine_closeAttachmentPtr; + makeFunction: IExternalEngine_makeFunctionPtr; + makeProcedure: IExternalEngine_makeProcedurePtr; + makeTrigger: IExternalEngine_makeTriggerPtr; + end; + + IExternalEngine = class(IPluginBase) + const VERSION = 10; + + procedure open(status: IStatus; context: IExternalContext; charSet: PAnsiChar; charSetSize: Cardinal); + procedure openAttachment(status: IStatus; context: IExternalContext); + procedure closeAttachment(status: IStatus; context: IExternalContext); + function makeFunction(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder): IExternalFunction; + function makeProcedure(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder): IExternalProcedure; + function makeTrigger(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; fieldsBuilder: IMetadataBuilder): IExternalTrigger; + end; + + IExternalEngineImpl = class(IExternalEngine) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure setOwner(r: IReferenceCounted); virtual; abstract; + function getOwner(): IReferenceCounted; virtual; abstract; + procedure open(status: IStatus; context: IExternalContext; charSet: PAnsiChar; charSetSize: Cardinal); virtual; abstract; + procedure openAttachment(status: IStatus; context: IExternalContext); virtual; abstract; + procedure closeAttachment(status: IStatus; context: IExternalContext); virtual; abstract; + function makeFunction(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder): IExternalFunction; virtual; abstract; + function makeProcedure(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder): IExternalProcedure; virtual; abstract; + function makeTrigger(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; fieldsBuilder: IMetadataBuilder): IExternalTrigger; virtual; abstract; + end; + + TimerVTable = class(ReferenceCountedVTable) + handler: ITimer_handlerPtr; + end; + + ITimer = class(IReferenceCounted) + const VERSION = 3; + + procedure handler(); + end; + + ITimerImpl = class(ITimer) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure handler(); virtual; abstract; + end; + + TimerControlVTable = class(VersionedVTable) + start: ITimerControl_startPtr; + stop: ITimerControl_stopPtr; + end; + + ITimerControl = class(IVersioned) + const VERSION = 2; + + procedure start(status: IStatus; timer: ITimer; microSeconds: QWord); + procedure stop(status: IStatus; timer: ITimer); + end; + + ITimerControlImpl = class(ITimerControl) + constructor create; + + procedure start(status: IStatus; timer: ITimer; microSeconds: QWord); virtual; abstract; + procedure stop(status: IStatus; timer: ITimer); virtual; abstract; + end; + + VersionCallbackVTable = class(VersionedVTable) + callback: IVersionCallback_callbackPtr; + end; + + IVersionCallback = class(IVersioned) + const VERSION = 1; + + procedure callback(status: IStatus; text: PAnsiChar); + end; + + IVersionCallbackImpl = class(IVersionCallback) + constructor create; + + procedure callback(status: IStatus; text: PAnsiChar); virtual; abstract; + end; + + UtilVTable = class(VersionedVTable) + getFbVersion: IUtil_getFbVersionPtr; + loadBlob: IUtil_loadBlobPtr; + dumpBlob: IUtil_dumpBlobPtr; + getPerfCounters: IUtil_getPerfCountersPtr; + executeCreateDatabase: IUtil_executeCreateDatabasePtr; + decodeDate: IUtil_decodeDatePtr; + decodeTime: IUtil_decodeTimePtr; + encodeDate: IUtil_encodeDatePtr; + encodeTime: IUtil_encodeTimePtr; + formatStatus: IUtil_formatStatusPtr; + getClientVersion: IUtil_getClientVersionPtr; + getXpbBuilder: IUtil_getXpbBuilderPtr; + setOffsets: IUtil_setOffsetsPtr; + end; + + IUtil = class(IVersioned) + const VERSION = 13; + + procedure getFbVersion(status: IStatus; att: IAttachment; callback: IVersionCallback); + procedure loadBlob(status: IStatus; blobId: ISC_QUADPtr; att: IAttachment; tra: ITransaction; file_: PAnsiChar; txt: Boolean); + procedure dumpBlob(status: IStatus; blobId: ISC_QUADPtr; att: IAttachment; tra: ITransaction; file_: PAnsiChar; txt: Boolean); + procedure getPerfCounters(status: IStatus; att: IAttachment; countersSet: PAnsiChar; counters: Int64Ptr); + function executeCreateDatabase(status: IStatus; stmtLength: Cardinal; creatDBstatement: PAnsiChar; dialect: Cardinal; stmtIsCreateDb: BooleanPtr): IAttachment; + procedure decodeDate(date: ISC_DATE; year: CardinalPtr; month: CardinalPtr; day: CardinalPtr); + procedure decodeTime(time: ISC_TIME; hours: CardinalPtr; minutes: CardinalPtr; seconds: CardinalPtr; fractions: CardinalPtr); + function encodeDate(year: Cardinal; month: Cardinal; day: Cardinal): ISC_DATE; + function encodeTime(hours: Cardinal; minutes: Cardinal; seconds: Cardinal; fractions: Cardinal): ISC_TIME; + function formatStatus(buffer: PAnsiChar; bufferSize: Cardinal; status: IStatus): Cardinal; + function getClientVersion(): Cardinal; + function getXpbBuilder(status: IStatus; kind: Cardinal; buf: BytePtr; len: Cardinal): IXpbBuilder; + function setOffsets(status: IStatus; metadata: IMessageMetadata; callback: IOffsetsCallback): Cardinal; + end; + + IUtilImpl = class(IUtil) + constructor create; + + procedure getFbVersion(status: IStatus; att: IAttachment; callback: IVersionCallback); virtual; abstract; + procedure loadBlob(status: IStatus; blobId: ISC_QUADPtr; att: IAttachment; tra: ITransaction; file_: PAnsiChar; txt: Boolean); virtual; abstract; + procedure dumpBlob(status: IStatus; blobId: ISC_QUADPtr; att: IAttachment; tra: ITransaction; file_: PAnsiChar; txt: Boolean); virtual; abstract; + procedure getPerfCounters(status: IStatus; att: IAttachment; countersSet: PAnsiChar; counters: Int64Ptr); virtual; abstract; + function executeCreateDatabase(status: IStatus; stmtLength: Cardinal; creatDBstatement: PAnsiChar; dialect: Cardinal; stmtIsCreateDb: BooleanPtr): IAttachment; virtual; abstract; + procedure decodeDate(date: ISC_DATE; year: CardinalPtr; month: CardinalPtr; day: CardinalPtr); virtual; abstract; + procedure decodeTime(time: ISC_TIME; hours: CardinalPtr; minutes: CardinalPtr; seconds: CardinalPtr; fractions: CardinalPtr); virtual; abstract; + function encodeDate(year: Cardinal; month: Cardinal; day: Cardinal): ISC_DATE; virtual; abstract; + function encodeTime(hours: Cardinal; minutes: Cardinal; seconds: Cardinal; fractions: Cardinal): ISC_TIME; virtual; abstract; + function formatStatus(buffer: PAnsiChar; bufferSize: Cardinal; status: IStatus): Cardinal; virtual; abstract; + function getClientVersion(): Cardinal; virtual; abstract; + function getXpbBuilder(status: IStatus; kind: Cardinal; buf: BytePtr; len: Cardinal): IXpbBuilder; virtual; abstract; + function setOffsets(status: IStatus; metadata: IMessageMetadata; callback: IOffsetsCallback): Cardinal; virtual; abstract; + end; + + OffsetsCallbackVTable = class(VersionedVTable) + setOffset: IOffsetsCallback_setOffsetPtr; + end; + + IOffsetsCallback = class(IVersioned) + const VERSION = 1; + + procedure setOffset(status: IStatus; index: Cardinal; offset: Cardinal; nullOffset: Cardinal); + end; + + IOffsetsCallbackImpl = class(IOffsetsCallback) + constructor create; + + procedure setOffset(status: IStatus; index: Cardinal; offset: Cardinal; nullOffset: Cardinal); virtual; abstract; + end; + + XpbBuilderVTable = class(DisposableVTable) + clear: IXpbBuilder_clearPtr; + removeCurrent: IXpbBuilder_removeCurrentPtr; + insertInt: IXpbBuilder_insertIntPtr; + insertBigInt: IXpbBuilder_insertBigIntPtr; + insertBytes: IXpbBuilder_insertBytesPtr; + insertString: IXpbBuilder_insertStringPtr; + insertTag: IXpbBuilder_insertTagPtr; + isEof: IXpbBuilder_isEofPtr; + moveNext: IXpbBuilder_moveNextPtr; + rewind: IXpbBuilder_rewindPtr; + findFirst: IXpbBuilder_findFirstPtr; + findNext: IXpbBuilder_findNextPtr; + getTag: IXpbBuilder_getTagPtr; + getLength: IXpbBuilder_getLengthPtr; + getInt: IXpbBuilder_getIntPtr; + getBigInt: IXpbBuilder_getBigIntPtr; + getString: IXpbBuilder_getStringPtr; + getBytes: IXpbBuilder_getBytesPtr; + getBufferLength: IXpbBuilder_getBufferLengthPtr; + getBuffer: IXpbBuilder_getBufferPtr; + end; + + IXpbBuilder = class(IDisposable) + const VERSION = 21; + const DPB = Cardinal(1); + const SPB_ATTACH = Cardinal(2); + const SPB_START = Cardinal(3); + const TPB = Cardinal(4); + + procedure clear(status: IStatus); + procedure removeCurrent(status: IStatus); + procedure insertInt(status: IStatus; tag: Byte; value: Integer); + procedure insertBigInt(status: IStatus; tag: Byte; value: Int64); + procedure insertBytes(status: IStatus; tag: Byte; bytes: Pointer; length: Cardinal); + procedure insertString(status: IStatus; tag: Byte; str: PAnsiChar); + procedure insertTag(status: IStatus; tag: Byte); + function isEof(status: IStatus): Boolean; + procedure moveNext(status: IStatus); + procedure rewind(status: IStatus); + function findFirst(status: IStatus; tag: Byte): Boolean; + function findNext(status: IStatus): Boolean; + function getTag(status: IStatus): Byte; + function getLength(status: IStatus): Cardinal; + function getInt(status: IStatus): Integer; + function getBigInt(status: IStatus): Int64; + function getString(status: IStatus): PAnsiChar; + function getBytes(status: IStatus): BytePtr; + function getBufferLength(status: IStatus): Cardinal; + function getBuffer(status: IStatus): BytePtr; + end; + + IXpbBuilderImpl = class(IXpbBuilder) + constructor create; + + procedure dispose(); virtual; abstract; + procedure clear(status: IStatus); virtual; abstract; + procedure removeCurrent(status: IStatus); virtual; abstract; + procedure insertInt(status: IStatus; tag: Byte; value: Integer); virtual; abstract; + procedure insertBigInt(status: IStatus; tag: Byte; value: Int64); virtual; abstract; + procedure insertBytes(status: IStatus; tag: Byte; bytes: Pointer; length: Cardinal); virtual; abstract; + procedure insertString(status: IStatus; tag: Byte; str: PAnsiChar); virtual; abstract; + procedure insertTag(status: IStatus; tag: Byte); virtual; abstract; + function isEof(status: IStatus): Boolean; virtual; abstract; + procedure moveNext(status: IStatus); virtual; abstract; + procedure rewind(status: IStatus); virtual; abstract; + function findFirst(status: IStatus; tag: Byte): Boolean; virtual; abstract; + function findNext(status: IStatus): Boolean; virtual; abstract; + function getTag(status: IStatus): Byte; virtual; abstract; + function getLength(status: IStatus): Cardinal; virtual; abstract; + function getInt(status: IStatus): Integer; virtual; abstract; + function getBigInt(status: IStatus): Int64; virtual; abstract; + function getString(status: IStatus): PAnsiChar; virtual; abstract; + function getBytes(status: IStatus): BytePtr; virtual; abstract; + function getBufferLength(status: IStatus): Cardinal; virtual; abstract; + function getBuffer(status: IStatus): BytePtr; virtual; abstract; + end; + + TraceConnectionVTable = class(VersionedVTable) + getKind: ITraceConnection_getKindPtr; + getProcessID: ITraceConnection_getProcessIDPtr; + getUserName: ITraceConnection_getUserNamePtr; + getRoleName: ITraceConnection_getRoleNamePtr; + getCharSet: ITraceConnection_getCharSetPtr; + getRemoteProtocol: ITraceConnection_getRemoteProtocolPtr; + getRemoteAddress: ITraceConnection_getRemoteAddressPtr; + getRemoteProcessID: ITraceConnection_getRemoteProcessIDPtr; + getRemoteProcessName: ITraceConnection_getRemoteProcessNamePtr; + end; + + ITraceConnection = class(IVersioned) + const VERSION = 9; + const KIND_DATABASE = Cardinal(1); + const KIND_SERVICE = Cardinal(2); + + function getKind(): Cardinal; + function getProcessID(): Integer; + function getUserName(): PAnsiChar; + function getRoleName(): PAnsiChar; + function getCharSet(): PAnsiChar; + function getRemoteProtocol(): PAnsiChar; + function getRemoteAddress(): PAnsiChar; + function getRemoteProcessID(): Integer; + function getRemoteProcessName(): PAnsiChar; + end; + + ITraceConnectionImpl = class(ITraceConnection) + constructor create; + + function getKind(): Cardinal; virtual; abstract; + function getProcessID(): Integer; virtual; abstract; + function getUserName(): PAnsiChar; virtual; abstract; + function getRoleName(): PAnsiChar; virtual; abstract; + function getCharSet(): PAnsiChar; virtual; abstract; + function getRemoteProtocol(): PAnsiChar; virtual; abstract; + function getRemoteAddress(): PAnsiChar; virtual; abstract; + function getRemoteProcessID(): Integer; virtual; abstract; + function getRemoteProcessName(): PAnsiChar; virtual; abstract; + end; + + TraceDatabaseConnectionVTable = class(TraceConnectionVTable) + getConnectionID: ITraceDatabaseConnection_getConnectionIDPtr; + getDatabaseName: ITraceDatabaseConnection_getDatabaseNamePtr; + end; + + ITraceDatabaseConnection = class(ITraceConnection) + const VERSION = 11; + + function getConnectionID(): Int64; + function getDatabaseName(): PAnsiChar; + end; + + ITraceDatabaseConnectionImpl = class(ITraceDatabaseConnection) + constructor create; + + function getKind(): Cardinal; virtual; abstract; + function getProcessID(): Integer; virtual; abstract; + function getUserName(): PAnsiChar; virtual; abstract; + function getRoleName(): PAnsiChar; virtual; abstract; + function getCharSet(): PAnsiChar; virtual; abstract; + function getRemoteProtocol(): PAnsiChar; virtual; abstract; + function getRemoteAddress(): PAnsiChar; virtual; abstract; + function getRemoteProcessID(): Integer; virtual; abstract; + function getRemoteProcessName(): PAnsiChar; virtual; abstract; + function getConnectionID(): Int64; virtual; abstract; + function getDatabaseName(): PAnsiChar; virtual; abstract; + end; + + TraceTransactionVTable = class(VersionedVTable) + getTransactionID: ITraceTransaction_getTransactionIDPtr; + getReadOnly: ITraceTransaction_getReadOnlyPtr; + getWait: ITraceTransaction_getWaitPtr; + getIsolation: ITraceTransaction_getIsolationPtr; + getPerf: ITraceTransaction_getPerfPtr; + end; + + ITraceTransaction = class(IVersioned) + const VERSION = 5; + const ISOLATION_CONSISTENCY = Cardinal(1); + const ISOLATION_CONCURRENCY = Cardinal(2); + const ISOLATION_READ_COMMITTED_RECVER = Cardinal(3); + const ISOLATION_READ_COMMITTED_NORECVER = Cardinal(4); + + function getTransactionID(): Int64; + function getReadOnly(): Boolean; + function getWait(): Integer; + function getIsolation(): Cardinal; + function getPerf(): PerformanceInfoPtr; + end; + + ITraceTransactionImpl = class(ITraceTransaction) + constructor create; + + function getTransactionID(): Int64; virtual; abstract; + function getReadOnly(): Boolean; virtual; abstract; + function getWait(): Integer; virtual; abstract; + function getIsolation(): Cardinal; virtual; abstract; + function getPerf(): PerformanceInfoPtr; virtual; abstract; + end; + + TraceParamsVTable = class(VersionedVTable) + getCount: ITraceParams_getCountPtr; + getParam: ITraceParams_getParamPtr; + end; + + ITraceParams = class(IVersioned) + const VERSION = 2; + + function getCount(): Cardinal; + function getParam(idx: Cardinal): dscPtr; + end; + + ITraceParamsImpl = class(ITraceParams) + constructor create; + + function getCount(): Cardinal; virtual; abstract; + function getParam(idx: Cardinal): dscPtr; virtual; abstract; + end; + + TraceStatementVTable = class(VersionedVTable) + getStmtID: ITraceStatement_getStmtIDPtr; + getPerf: ITraceStatement_getPerfPtr; + end; + + ITraceStatement = class(IVersioned) + const VERSION = 2; + + function getStmtID(): Int64; + function getPerf(): PerformanceInfoPtr; + end; + + ITraceStatementImpl = class(ITraceStatement) + constructor create; + + function getStmtID(): Int64; virtual; abstract; + function getPerf(): PerformanceInfoPtr; virtual; abstract; + end; + + TraceSQLStatementVTable = class(TraceStatementVTable) + getText: ITraceSQLStatement_getTextPtr; + getPlan: ITraceSQLStatement_getPlanPtr; + getInputs: ITraceSQLStatement_getInputsPtr; + getTextUTF8: ITraceSQLStatement_getTextUTF8Ptr; + getExplainedPlan: ITraceSQLStatement_getExplainedPlanPtr; + end; + + ITraceSQLStatement = class(ITraceStatement) + const VERSION = 7; + + function getText(): PAnsiChar; + function getPlan(): PAnsiChar; + function getInputs(): ITraceParams; + function getTextUTF8(): PAnsiChar; + function getExplainedPlan(): PAnsiChar; + end; + + ITraceSQLStatementImpl = class(ITraceSQLStatement) + constructor create; + + function getStmtID(): Int64; virtual; abstract; + function getPerf(): PerformanceInfoPtr; virtual; abstract; + function getText(): PAnsiChar; virtual; abstract; + function getPlan(): PAnsiChar; virtual; abstract; + function getInputs(): ITraceParams; virtual; abstract; + function getTextUTF8(): PAnsiChar; virtual; abstract; + function getExplainedPlan(): PAnsiChar; virtual; abstract; + end; + + TraceBLRStatementVTable = class(TraceStatementVTable) + getData: ITraceBLRStatement_getDataPtr; + getDataLength: ITraceBLRStatement_getDataLengthPtr; + getText: ITraceBLRStatement_getTextPtr; + end; + + ITraceBLRStatement = class(ITraceStatement) + const VERSION = 5; + + function getData(): BytePtr; + function getDataLength(): Cardinal; + function getText(): PAnsiChar; + end; + + ITraceBLRStatementImpl = class(ITraceBLRStatement) + constructor create; + + function getStmtID(): Int64; virtual; abstract; + function getPerf(): PerformanceInfoPtr; virtual; abstract; + function getData(): BytePtr; virtual; abstract; + function getDataLength(): Cardinal; virtual; abstract; + function getText(): PAnsiChar; virtual; abstract; + end; + + TraceDYNRequestVTable = class(VersionedVTable) + getData: ITraceDYNRequest_getDataPtr; + getDataLength: ITraceDYNRequest_getDataLengthPtr; + getText: ITraceDYNRequest_getTextPtr; + end; + + ITraceDYNRequest = class(IVersioned) + const VERSION = 3; + + function getData(): BytePtr; + function getDataLength(): Cardinal; + function getText(): PAnsiChar; + end; + + ITraceDYNRequestImpl = class(ITraceDYNRequest) + constructor create; + + function getData(): BytePtr; virtual; abstract; + function getDataLength(): Cardinal; virtual; abstract; + function getText(): PAnsiChar; virtual; abstract; + end; + + TraceContextVariableVTable = class(VersionedVTable) + getNameSpace: ITraceContextVariable_getNameSpacePtr; + getVarName: ITraceContextVariable_getVarNamePtr; + getVarValue: ITraceContextVariable_getVarValuePtr; + end; + + ITraceContextVariable = class(IVersioned) + const VERSION = 3; + + function getNameSpace(): PAnsiChar; + function getVarName(): PAnsiChar; + function getVarValue(): PAnsiChar; + end; + + ITraceContextVariableImpl = class(ITraceContextVariable) + constructor create; + + function getNameSpace(): PAnsiChar; virtual; abstract; + function getVarName(): PAnsiChar; virtual; abstract; + function getVarValue(): PAnsiChar; virtual; abstract; + end; + + TraceProcedureVTable = class(VersionedVTable) + getProcName: ITraceProcedure_getProcNamePtr; + getInputs: ITraceProcedure_getInputsPtr; + getPerf: ITraceProcedure_getPerfPtr; + end; + + ITraceProcedure = class(IVersioned) + const VERSION = 3; + + function getProcName(): PAnsiChar; + function getInputs(): ITraceParams; + function getPerf(): PerformanceInfoPtr; + end; + + ITraceProcedureImpl = class(ITraceProcedure) + constructor create; + + function getProcName(): PAnsiChar; virtual; abstract; + function getInputs(): ITraceParams; virtual; abstract; + function getPerf(): PerformanceInfoPtr; virtual; abstract; + end; + + TraceFunctionVTable = class(VersionedVTable) + getFuncName: ITraceFunction_getFuncNamePtr; + getInputs: ITraceFunction_getInputsPtr; + getResult: ITraceFunction_getResultPtr; + getPerf: ITraceFunction_getPerfPtr; + end; + + ITraceFunction = class(IVersioned) + const VERSION = 4; + + function getFuncName(): PAnsiChar; + function getInputs(): ITraceParams; + function getResult(): ITraceParams; + function getPerf(): PerformanceInfoPtr; + end; + + ITraceFunctionImpl = class(ITraceFunction) + constructor create; + + function getFuncName(): PAnsiChar; virtual; abstract; + function getInputs(): ITraceParams; virtual; abstract; + function getResult(): ITraceParams; virtual; abstract; + function getPerf(): PerformanceInfoPtr; virtual; abstract; + end; + + TraceTriggerVTable = class(VersionedVTable) + getTriggerName: ITraceTrigger_getTriggerNamePtr; + getRelationName: ITraceTrigger_getRelationNamePtr; + getAction: ITraceTrigger_getActionPtr; + getWhich: ITraceTrigger_getWhichPtr; + getPerf: ITraceTrigger_getPerfPtr; + end; + + ITraceTrigger = class(IVersioned) + const VERSION = 5; + const TYPE_ALL = Cardinal(0); + const TYPE_BEFORE = Cardinal(1); + const TYPE_AFTER = Cardinal(2); + + function getTriggerName(): PAnsiChar; + function getRelationName(): PAnsiChar; + function getAction(): Integer; + function getWhich(): Integer; + function getPerf(): PerformanceInfoPtr; + end; + + ITraceTriggerImpl = class(ITraceTrigger) + constructor create; + + function getTriggerName(): PAnsiChar; virtual; abstract; + function getRelationName(): PAnsiChar; virtual; abstract; + function getAction(): Integer; virtual; abstract; + function getWhich(): Integer; virtual; abstract; + function getPerf(): PerformanceInfoPtr; virtual; abstract; + end; + + TraceServiceConnectionVTable = class(TraceConnectionVTable) + getServiceID: ITraceServiceConnection_getServiceIDPtr; + getServiceMgr: ITraceServiceConnection_getServiceMgrPtr; + getServiceName: ITraceServiceConnection_getServiceNamePtr; + end; + + ITraceServiceConnection = class(ITraceConnection) + const VERSION = 12; + + function getServiceID(): Pointer; + function getServiceMgr(): PAnsiChar; + function getServiceName(): PAnsiChar; + end; + + ITraceServiceConnectionImpl = class(ITraceServiceConnection) + constructor create; + + function getKind(): Cardinal; virtual; abstract; + function getProcessID(): Integer; virtual; abstract; + function getUserName(): PAnsiChar; virtual; abstract; + function getRoleName(): PAnsiChar; virtual; abstract; + function getCharSet(): PAnsiChar; virtual; abstract; + function getRemoteProtocol(): PAnsiChar; virtual; abstract; + function getRemoteAddress(): PAnsiChar; virtual; abstract; + function getRemoteProcessID(): Integer; virtual; abstract; + function getRemoteProcessName(): PAnsiChar; virtual; abstract; + function getServiceID(): Pointer; virtual; abstract; + function getServiceMgr(): PAnsiChar; virtual; abstract; + function getServiceName(): PAnsiChar; virtual; abstract; + end; + + TraceStatusVectorVTable = class(VersionedVTable) + hasError: ITraceStatusVector_hasErrorPtr; + hasWarning: ITraceStatusVector_hasWarningPtr; + getStatus: ITraceStatusVector_getStatusPtr; + getText: ITraceStatusVector_getTextPtr; + end; + + ITraceStatusVector = class(IVersioned) + const VERSION = 4; + + function hasError(): Boolean; + function hasWarning(): Boolean; + function getStatus(): IStatus; + function getText(): PAnsiChar; + end; + + ITraceStatusVectorImpl = class(ITraceStatusVector) + constructor create; + + function hasError(): Boolean; virtual; abstract; + function hasWarning(): Boolean; virtual; abstract; + function getStatus(): IStatus; virtual; abstract; + function getText(): PAnsiChar; virtual; abstract; + end; + + TraceSweepInfoVTable = class(VersionedVTable) + getOIT: ITraceSweepInfo_getOITPtr; + getOST: ITraceSweepInfo_getOSTPtr; + getOAT: ITraceSweepInfo_getOATPtr; + getNext: ITraceSweepInfo_getNextPtr; + getPerf: ITraceSweepInfo_getPerfPtr; + end; + + ITraceSweepInfo = class(IVersioned) + const VERSION = 5; + + function getOIT(): Int64; + function getOST(): Int64; + function getOAT(): Int64; + function getNext(): Int64; + function getPerf(): PerformanceInfoPtr; + end; + + ITraceSweepInfoImpl = class(ITraceSweepInfo) + constructor create; + + function getOIT(): Int64; virtual; abstract; + function getOST(): Int64; virtual; abstract; + function getOAT(): Int64; virtual; abstract; + function getNext(): Int64; virtual; abstract; + function getPerf(): PerformanceInfoPtr; virtual; abstract; + end; + + TraceLogWriterVTable = class(ReferenceCountedVTable) + write: ITraceLogWriter_writePtr; + end; + + ITraceLogWriter = class(IReferenceCounted) + const VERSION = 3; + + function write(buf: Pointer; size: Cardinal): Cardinal; + end; + + ITraceLogWriterImpl = class(ITraceLogWriter) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + function write(buf: Pointer; size: Cardinal): Cardinal; virtual; abstract; + end; + + TraceInitInfoVTable = class(VersionedVTable) + getConfigText: ITraceInitInfo_getConfigTextPtr; + getTraceSessionID: ITraceInitInfo_getTraceSessionIDPtr; + getTraceSessionName: ITraceInitInfo_getTraceSessionNamePtr; + getFirebirdRootDirectory: ITraceInitInfo_getFirebirdRootDirectoryPtr; + getDatabaseName: ITraceInitInfo_getDatabaseNamePtr; + getConnection: ITraceInitInfo_getConnectionPtr; + getLogWriter: ITraceInitInfo_getLogWriterPtr; + end; + + ITraceInitInfo = class(IVersioned) + const VERSION = 7; + + function getConfigText(): PAnsiChar; + function getTraceSessionID(): Integer; + function getTraceSessionName(): PAnsiChar; + function getFirebirdRootDirectory(): PAnsiChar; + function getDatabaseName(): PAnsiChar; + function getConnection(): ITraceDatabaseConnection; + function getLogWriter(): ITraceLogWriter; + end; + + ITraceInitInfoImpl = class(ITraceInitInfo) + constructor create; + + function getConfigText(): PAnsiChar; virtual; abstract; + function getTraceSessionID(): Integer; virtual; abstract; + function getTraceSessionName(): PAnsiChar; virtual; abstract; + function getFirebirdRootDirectory(): PAnsiChar; virtual; abstract; + function getDatabaseName(): PAnsiChar; virtual; abstract; + function getConnection(): ITraceDatabaseConnection; virtual; abstract; + function getLogWriter(): ITraceLogWriter; virtual; abstract; + end; + + TracePluginVTable = class(ReferenceCountedVTable) + trace_get_error: ITracePlugin_trace_get_errorPtr; + trace_attach: ITracePlugin_trace_attachPtr; + trace_detach: ITracePlugin_trace_detachPtr; + trace_transaction_start: ITracePlugin_trace_transaction_startPtr; + trace_transaction_end: ITracePlugin_trace_transaction_endPtr; + trace_proc_execute: ITracePlugin_trace_proc_executePtr; + trace_trigger_execute: ITracePlugin_trace_trigger_executePtr; + trace_set_context: ITracePlugin_trace_set_contextPtr; + trace_dsql_prepare: ITracePlugin_trace_dsql_preparePtr; + trace_dsql_free: ITracePlugin_trace_dsql_freePtr; + trace_dsql_execute: ITracePlugin_trace_dsql_executePtr; + trace_blr_compile: ITracePlugin_trace_blr_compilePtr; + trace_blr_execute: ITracePlugin_trace_blr_executePtr; + trace_dyn_execute: ITracePlugin_trace_dyn_executePtr; + trace_service_attach: ITracePlugin_trace_service_attachPtr; + trace_service_start: ITracePlugin_trace_service_startPtr; + trace_service_query: ITracePlugin_trace_service_queryPtr; + trace_service_detach: ITracePlugin_trace_service_detachPtr; + trace_event_error: ITracePlugin_trace_event_errorPtr; + trace_event_sweep: ITracePlugin_trace_event_sweepPtr; + trace_func_execute: ITracePlugin_trace_func_executePtr; + end; + + ITracePlugin = class(IReferenceCounted) + const VERSION = 23; + const RESULT_SUCCESS = Cardinal(0); + const RESULT_FAILED = Cardinal(1); + const RESULT_UNAUTHORIZED = Cardinal(2); + const SWEEP_STATE_STARTED = Cardinal(1); + const SWEEP_STATE_FINISHED = Cardinal(2); + const SWEEP_STATE_FAILED = Cardinal(3); + const SWEEP_STATE_PROGRESS = Cardinal(4); + + function trace_get_error(): PAnsiChar; + function trace_attach(connection: ITraceDatabaseConnection; create_db: Boolean; att_result: Cardinal): Boolean; + function trace_detach(connection: ITraceDatabaseConnection; drop_db: Boolean): Boolean; + function trace_transaction_start(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; tpb_length: Cardinal; tpb: BytePtr; tra_result: Cardinal): Boolean; + function trace_transaction_end(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; commit: Boolean; retain_context: Boolean; tra_result: Cardinal): Boolean; + function trace_proc_execute(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; procedure_: ITraceProcedure; started: Boolean; proc_result: Cardinal): Boolean; + function trace_trigger_execute(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; trigger: ITraceTrigger; started: Boolean; trig_result: Cardinal): Boolean; + function trace_set_context(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; variable: ITraceContextVariable): Boolean; + function trace_dsql_prepare(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceSQLStatement; time_millis: Int64; req_result: Cardinal): Boolean; + function trace_dsql_free(connection: ITraceDatabaseConnection; statement: ITraceSQLStatement; option: Cardinal): Boolean; + function trace_dsql_execute(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceSQLStatement; started: Boolean; req_result: Cardinal): Boolean; + function trace_blr_compile(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceBLRStatement; time_millis: Int64; req_result: Cardinal): Boolean; + function trace_blr_execute(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceBLRStatement; req_result: Cardinal): Boolean; + function trace_dyn_execute(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; request: ITraceDYNRequest; time_millis: Int64; req_result: Cardinal): Boolean; + function trace_service_attach(service: ITraceServiceConnection; att_result: Cardinal): Boolean; + function trace_service_start(service: ITraceServiceConnection; switches_length: Cardinal; switches: PAnsiChar; start_result: Cardinal): Boolean; + function trace_service_query(service: ITraceServiceConnection; send_item_length: Cardinal; send_items: BytePtr; recv_item_length: Cardinal; recv_items: BytePtr; query_result: Cardinal): Boolean; + function trace_service_detach(service: ITraceServiceConnection; detach_result: Cardinal): Boolean; + function trace_event_error(connection: ITraceConnection; status: ITraceStatusVector; function_: PAnsiChar): Boolean; + function trace_event_sweep(connection: ITraceDatabaseConnection; sweep: ITraceSweepInfo; sweep_state: Cardinal): Boolean; + function trace_func_execute(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; function_: ITraceFunction; started: Boolean; func_result: Cardinal): Boolean; + end; + + ITracePluginImpl = class(ITracePlugin) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + function trace_get_error(): PAnsiChar; virtual; abstract; + function trace_attach(connection: ITraceDatabaseConnection; create_db: Boolean; att_result: Cardinal): Boolean; virtual; abstract; + function trace_detach(connection: ITraceDatabaseConnection; drop_db: Boolean): Boolean; virtual; abstract; + function trace_transaction_start(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; tpb_length: Cardinal; tpb: BytePtr; tra_result: Cardinal): Boolean; virtual; abstract; + function trace_transaction_end(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; commit: Boolean; retain_context: Boolean; tra_result: Cardinal): Boolean; virtual; abstract; + function trace_proc_execute(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; procedure_: ITraceProcedure; started: Boolean; proc_result: Cardinal): Boolean; virtual; abstract; + function trace_trigger_execute(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; trigger: ITraceTrigger; started: Boolean; trig_result: Cardinal): Boolean; virtual; abstract; + function trace_set_context(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; variable: ITraceContextVariable): Boolean; virtual; abstract; + function trace_dsql_prepare(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceSQLStatement; time_millis: Int64; req_result: Cardinal): Boolean; virtual; abstract; + function trace_dsql_free(connection: ITraceDatabaseConnection; statement: ITraceSQLStatement; option: Cardinal): Boolean; virtual; abstract; + function trace_dsql_execute(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceSQLStatement; started: Boolean; req_result: Cardinal): Boolean; virtual; abstract; + function trace_blr_compile(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceBLRStatement; time_millis: Int64; req_result: Cardinal): Boolean; virtual; abstract; + function trace_blr_execute(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceBLRStatement; req_result: Cardinal): Boolean; virtual; abstract; + function trace_dyn_execute(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; request: ITraceDYNRequest; time_millis: Int64; req_result: Cardinal): Boolean; virtual; abstract; + function trace_service_attach(service: ITraceServiceConnection; att_result: Cardinal): Boolean; virtual; abstract; + function trace_service_start(service: ITraceServiceConnection; switches_length: Cardinal; switches: PAnsiChar; start_result: Cardinal): Boolean; virtual; abstract; + function trace_service_query(service: ITraceServiceConnection; send_item_length: Cardinal; send_items: BytePtr; recv_item_length: Cardinal; recv_items: BytePtr; query_result: Cardinal): Boolean; virtual; abstract; + function trace_service_detach(service: ITraceServiceConnection; detach_result: Cardinal): Boolean; virtual; abstract; + function trace_event_error(connection: ITraceConnection; status: ITraceStatusVector; function_: PAnsiChar): Boolean; virtual; abstract; + function trace_event_sweep(connection: ITraceDatabaseConnection; sweep: ITraceSweepInfo; sweep_state: Cardinal): Boolean; virtual; abstract; + function trace_func_execute(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; function_: ITraceFunction; started: Boolean; func_result: Cardinal): Boolean; virtual; abstract; + end; + + TraceFactoryVTable = class(PluginBaseVTable) + trace_needs: ITraceFactory_trace_needsPtr; + trace_create: ITraceFactory_trace_createPtr; + end; + + ITraceFactory = class(IPluginBase) + const VERSION = 6; + const TRACE_EVENT_ATTACH = Cardinal(0); + const TRACE_EVENT_DETACH = Cardinal(1); + const TRACE_EVENT_TRANSACTION_START = Cardinal(2); + const TRACE_EVENT_TRANSACTION_END = Cardinal(3); + const TRACE_EVENT_SET_CONTEXT = Cardinal(4); + const TRACE_EVENT_PROC_EXECUTE = Cardinal(5); + const TRACE_EVENT_TRIGGER_EXECUTE = Cardinal(6); + const TRACE_EVENT_DSQL_PREPARE = Cardinal(7); + const TRACE_EVENT_DSQL_FREE = Cardinal(8); + const TRACE_EVENT_DSQL_EXECUTE = Cardinal(9); + const TRACE_EVENT_BLR_COMPILE = Cardinal(10); + const TRACE_EVENT_BLR_EXECUTE = Cardinal(11); + const TRACE_EVENT_DYN_EXECUTE = Cardinal(12); + const TRACE_EVENT_SERVICE_ATTACH = Cardinal(13); + const TRACE_EVENT_SERVICE_START = Cardinal(14); + const TRACE_EVENT_SERVICE_QUERY = Cardinal(15); + const TRACE_EVENT_SERVICE_DETACH = Cardinal(16); + const TRACE_EVENT_ERROR = Cardinal(17); + const TRACE_EVENT_SWEEP = Cardinal(18); + const TRACE_EVENT_FUNC_EXECUTE = Cardinal(19); + const TRACE_EVENT_MAX = Cardinal(20); + + function trace_needs(): QWord; + function trace_create(status: IStatus; init_info: ITraceInitInfo): ITracePlugin; + end; + + ITraceFactoryImpl = class(ITraceFactory) + constructor create; + + procedure addRef(); virtual; abstract; + function release(): Integer; virtual; abstract; + procedure setOwner(r: IReferenceCounted); virtual; abstract; + function getOwner(): IReferenceCounted; virtual; abstract; + function trace_needs(): QWord; virtual; abstract; + function trace_create(status: IStatus; init_info: ITraceInitInfo): ITracePlugin; virtual; abstract; + end; + + UdrFunctionFactoryVTable = class(DisposableVTable) + setup: IUdrFunctionFactory_setupPtr; + newItem: IUdrFunctionFactory_newItemPtr; + end; + + IUdrFunctionFactory = class(IDisposable) + const VERSION = 3; + + procedure setup(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder); + function newItem(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata): IExternalFunction; + end; + + IUdrFunctionFactoryImpl = class(IUdrFunctionFactory) + constructor create; + + procedure dispose(); virtual; abstract; + procedure setup(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder); virtual; abstract; + function newItem(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata): IExternalFunction; virtual; abstract; + end; + + UdrProcedureFactoryVTable = class(DisposableVTable) + setup: IUdrProcedureFactory_setupPtr; + newItem: IUdrProcedureFactory_newItemPtr; + end; + + IUdrProcedureFactory = class(IDisposable) + const VERSION = 3; + + procedure setup(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder); + function newItem(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata): IExternalProcedure; + end; + + IUdrProcedureFactoryImpl = class(IUdrProcedureFactory) + constructor create; + + procedure dispose(); virtual; abstract; + procedure setup(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder); virtual; abstract; + function newItem(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata): IExternalProcedure; virtual; abstract; + end; + + UdrTriggerFactoryVTable = class(DisposableVTable) + setup: IUdrTriggerFactory_setupPtr; + newItem: IUdrTriggerFactory_newItemPtr; + end; + + IUdrTriggerFactory = class(IDisposable) + const VERSION = 3; + + procedure setup(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; fieldsBuilder: IMetadataBuilder); + function newItem(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata): IExternalTrigger; + end; + + IUdrTriggerFactoryImpl = class(IUdrTriggerFactory) + constructor create; + + procedure dispose(); virtual; abstract; + procedure setup(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; fieldsBuilder: IMetadataBuilder); virtual; abstract; + function newItem(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata): IExternalTrigger; virtual; abstract; + end; + + UdrPluginVTable = class(VersionedVTable) + getMaster: IUdrPlugin_getMasterPtr; + registerFunction: IUdrPlugin_registerFunctionPtr; + registerProcedure: IUdrPlugin_registerProcedurePtr; + registerTrigger: IUdrPlugin_registerTriggerPtr; + end; + + IUdrPlugin = class(IVersioned) + const VERSION = 4; + + function getMaster(): IMaster; + procedure registerFunction(status: IStatus; name: PAnsiChar; factory: IUdrFunctionFactory); + procedure registerProcedure(status: IStatus; name: PAnsiChar; factory: IUdrProcedureFactory); + procedure registerTrigger(status: IStatus; name: PAnsiChar; factory: IUdrTriggerFactory); + end; + + IUdrPluginImpl = class(IUdrPlugin) + constructor create; + + function getMaster(): IMaster; virtual; abstract; + procedure registerFunction(status: IStatus; name: PAnsiChar; factory: IUdrFunctionFactory); virtual; abstract; + procedure registerProcedure(status: IStatus; name: PAnsiChar; factory: IUdrProcedureFactory); virtual; abstract; + procedure registerTrigger(status: IStatus; name: PAnsiChar; factory: IUdrTriggerFactory); virtual; abstract; + end; + +// function fb_get_master_interface : IMaster; cdecl; external 'fbclient'; + +const + isc_dpb_version1 = byte(1); + isc_dpb_version2 = byte(2); + isc_dpb_cdd_pathname = byte(1); + isc_dpb_allocation = byte(2); + isc_dpb_journal = byte(3); + isc_dpb_page_size = byte(4); + isc_dpb_num_buffers = byte(5); + isc_dpb_buffer_length = byte(6); + isc_dpb_debug = byte(7); + isc_dpb_garbage_collect = byte(8); + isc_dpb_verify = byte(9); + isc_dpb_sweep = byte(10); + isc_dpb_enable_journal = byte(11); + isc_dpb_disable_journal = byte(12); + isc_dpb_dbkey_scope = byte(13); + isc_dpb_number_of_users = byte(14); + isc_dpb_trace = byte(15); + isc_dpb_no_garbage_collect = byte(16); + isc_dpb_damaged = byte(17); + isc_dpb_license = byte(18); + isc_dpb_sys_user_name = byte(19); + isc_dpb_encrypt_key = byte(20); + isc_dpb_activate_shadow = byte(21); + isc_dpb_sweep_interval = byte(22); + isc_dpb_delete_shadow = byte(23); + isc_dpb_force_write = byte(24); + isc_dpb_begin_log = byte(25); + isc_dpb_quit_log = byte(26); + isc_dpb_no_reserve = byte(27); + isc_dpb_user_name = byte(28); + isc_dpb_password = byte(29); + isc_dpb_password_enc = byte(30); + isc_dpb_sys_user_name_enc = byte(31); + isc_dpb_interp = byte(32); + isc_dpb_online_dump = byte(33); + isc_dpb_old_file_size = byte(34); + isc_dpb_old_num_files = byte(35); + isc_dpb_old_file = byte(36); + isc_dpb_old_start_page = byte(37); + isc_dpb_old_start_seqno = byte(38); + isc_dpb_old_start_file = byte(39); + isc_dpb_drop_walfile = byte(40); + isc_dpb_old_dump_id = byte(41); + isc_dpb_wal_backup_dir = byte(42); + isc_dpb_wal_chkptlen = byte(43); + isc_dpb_wal_numbufs = byte(44); + isc_dpb_wal_bufsize = byte(45); + isc_dpb_wal_grp_cmt_wait = byte(46); + isc_dpb_lc_messages = byte(47); + isc_dpb_lc_ctype = byte(48); + isc_dpb_cache_manager = byte(49); + isc_dpb_shutdown = byte(50); + isc_dpb_online = byte(51); + isc_dpb_shutdown_delay = byte(52); + isc_dpb_reserved = byte(53); + isc_dpb_overwrite = byte(54); + isc_dpb_sec_attach = byte(55); + isc_dpb_disable_wal = byte(56); + isc_dpb_connect_timeout = byte(57); + isc_dpb_dummy_packet_interval = byte(58); + isc_dpb_gbak_attach = byte(59); + isc_dpb_sql_role_name = byte(60); + isc_dpb_set_page_buffers = byte(61); + isc_dpb_working_directory = byte(62); + isc_dpb_sql_dialect = byte(63); + isc_dpb_set_db_readonly = byte(64); + isc_dpb_set_db_sql_dialect = byte(65); + isc_dpb_gfix_attach = byte(66); + isc_dpb_gstat_attach = byte(67); + isc_dpb_set_db_charset = byte(68); + isc_dpb_gsec_attach = byte(69); + isc_dpb_address_path = byte(70); + isc_dpb_process_id = byte(71); + isc_dpb_no_db_triggers = byte(72); + isc_dpb_trusted_auth = byte(73); + isc_dpb_process_name = byte(74); + isc_dpb_trusted_role = byte(75); + isc_dpb_org_filename = byte(76); + isc_dpb_utf8_filename = byte(77); + isc_dpb_ext_call_depth = byte(78); + isc_dpb_auth_block = byte(79); + isc_dpb_client_version = byte(80); + isc_dpb_remote_protocol = byte(81); + isc_dpb_host_name = byte(82); + isc_dpb_os_user = byte(83); + isc_dpb_specific_auth_data = byte(84); + isc_dpb_auth_plugin_list = byte(85); + isc_dpb_auth_plugin_name = byte(86); + isc_dpb_config = byte(87); + isc_dpb_nolinger = byte(88); + isc_dpb_reset_icu = byte(89); + isc_dpb_map_attach = byte(90); + isc_dpb_address = byte(1); + isc_dpb_addr_protocol = byte(1); + isc_dpb_addr_endpoint = byte(2); + isc_dpb_pages = byte(1); + isc_dpb_records = byte(2); + isc_dpb_indices = byte(4); + isc_dpb_transactions = byte(8); + isc_dpb_no_update = byte(16); + isc_dpb_repair = byte(32); + isc_dpb_ignore = byte(64); + isc_dpb_shut_cache = $1; + isc_dpb_shut_attachment = $2; + isc_dpb_shut_transaction = $4; + isc_dpb_shut_force = $8; + isc_dpb_shut_mode_mask = $70; + isc_dpb_shut_default = $0; + isc_dpb_shut_normal = $10; + isc_dpb_shut_multi = $20; + isc_dpb_shut_single = $30; + isc_dpb_shut_full = $40; + RDB_system = byte(1); + RDB_id_assigned = byte(2); + isc_tpb_version1 = byte(1); + isc_tpb_version3 = byte(3); + isc_tpb_consistency = byte(1); + isc_tpb_concurrency = byte(2); + isc_tpb_shared = byte(3); + isc_tpb_protected = byte(4); + isc_tpb_exclusive = byte(5); + isc_tpb_wait = byte(6); + isc_tpb_nowait = byte(7); + isc_tpb_read = byte(8); + isc_tpb_write = byte(9); + isc_tpb_lock_read = byte(10); + isc_tpb_lock_write = byte(11); + isc_tpb_verb_time = byte(12); + isc_tpb_commit_time = byte(13); + isc_tpb_ignore_limbo = byte(14); + isc_tpb_read_committed = byte(15); + isc_tpb_autocommit = byte(16); + isc_tpb_rec_version = byte(17); + isc_tpb_no_rec_version = byte(18); + isc_tpb_restart_requests = byte(19); + isc_tpb_no_auto_undo = byte(20); + isc_tpb_lock_timeout = byte(21); + isc_bpb_version1 = byte(1); + isc_bpb_source_type = byte(1); + isc_bpb_target_type = byte(2); + isc_bpb_type = byte(3); + isc_bpb_source_interp = byte(4); + isc_bpb_target_interp = byte(5); + isc_bpb_filter_parameter = byte(6); + isc_bpb_storage = byte(7); + isc_bpb_type_segmented = $0; + isc_bpb_type_stream = $1; + isc_bpb_storage_main = $0; + isc_bpb_storage_temp = $2; + isc_spb_version1 = byte(1); + isc_spb_current_version = byte(2); + isc_spb_version3 = byte(3); + isc_spb_command_line = byte(105); + isc_spb_dbname = byte(106); + isc_spb_verbose = byte(107); + isc_spb_options = byte(108); + isc_spb_address_path = byte(109); + isc_spb_process_id = byte(110); + isc_spb_trusted_auth = byte(111); + isc_spb_process_name = byte(112); + isc_spb_trusted_role = byte(113); + isc_spb_verbint = byte(114); + isc_spb_auth_block = byte(115); + isc_spb_auth_plugin_name = byte(116); + isc_spb_auth_plugin_list = byte(117); + isc_spb_utf8_filename = byte(118); + isc_spb_client_version = byte(119); + isc_spb_remote_protocol = byte(120); + isc_spb_host_name = byte(121); + isc_spb_os_user = byte(122); + isc_spb_config = byte(123); + isc_spb_expected_db = byte(124); + isc_action_svc_backup = byte(1); + isc_action_svc_restore = byte(2); + isc_action_svc_repair = byte(3); + isc_action_svc_add_user = byte(4); + isc_action_svc_delete_user = byte(5); + isc_action_svc_modify_user = byte(6); + isc_action_svc_display_user = byte(7); + isc_action_svc_properties = byte(8); + isc_action_svc_add_license = byte(9); + isc_action_svc_remove_license = byte(10); + isc_action_svc_db_stats = byte(11); + isc_action_svc_get_ib_log = byte(12); + isc_action_svc_get_fb_log = byte(12); + isc_action_svc_nbak = byte(20); + isc_action_svc_nrest = byte(21); + isc_action_svc_trace_start = byte(22); + isc_action_svc_trace_stop = byte(23); + isc_action_svc_trace_suspend = byte(24); + isc_action_svc_trace_resume = byte(25); + isc_action_svc_trace_list = byte(26); + isc_action_svc_set_mapping = byte(27); + isc_action_svc_drop_mapping = byte(28); + isc_action_svc_display_user_adm = byte(29); + isc_action_svc_validate = byte(30); + isc_action_svc_last = byte(31); + isc_info_svc_svr_db_info = byte(50); + isc_info_svc_get_license = byte(51); + isc_info_svc_get_license_mask = byte(52); + isc_info_svc_get_config = byte(53); + isc_info_svc_version = byte(54); + isc_info_svc_server_version = byte(55); + isc_info_svc_implementation = byte(56); + isc_info_svc_capabilities = byte(57); + isc_info_svc_user_dbpath = byte(58); + isc_info_svc_get_env = byte(59); + isc_info_svc_get_env_lock = byte(60); + isc_info_svc_get_env_msg = byte(61); + isc_info_svc_line = byte(62); + isc_info_svc_to_eof = byte(63); + isc_info_svc_timeout = byte(64); + isc_info_svc_get_licensed_users = byte(65); + isc_info_svc_limbo_trans = byte(66); + isc_info_svc_running = byte(67); + isc_info_svc_get_users = byte(68); + isc_info_svc_auth_block = byte(69); + isc_info_svc_stdin = byte(78); + isc_spb_sec_userid = byte(5); + isc_spb_sec_groupid = byte(6); + isc_spb_sec_username = byte(7); + isc_spb_sec_password = byte(8); + isc_spb_sec_groupname = byte(9); + isc_spb_sec_firstname = byte(10); + isc_spb_sec_middlename = byte(11); + isc_spb_sec_lastname = byte(12); + isc_spb_sec_admin = byte(13); + isc_spb_lic_key = byte(5); + isc_spb_lic_id = byte(6); + isc_spb_lic_desc = byte(7); + isc_spb_bkp_file = byte(5); + isc_spb_bkp_factor = byte(6); + isc_spb_bkp_length = byte(7); + isc_spb_bkp_skip_data = byte(8); + isc_spb_bkp_stat = byte(15); + isc_spb_bkp_ignore_checksums = $01; + isc_spb_bkp_ignore_limbo = $02; + isc_spb_bkp_metadata_only = $04; + isc_spb_bkp_no_garbage_collect = $08; + isc_spb_bkp_old_descriptions = $10; + isc_spb_bkp_non_transportable = $20; + isc_spb_bkp_convert = $40; + isc_spb_bkp_expand = $80; + isc_spb_bkp_no_triggers = $8000; + isc_spb_prp_page_buffers = byte(5); + isc_spb_prp_sweep_interval = byte(6); + isc_spb_prp_shutdown_db = byte(7); + isc_spb_prp_deny_new_attachments = byte(9); + isc_spb_prp_deny_new_transactions = byte(10); + isc_spb_prp_reserve_space = byte(11); + isc_spb_prp_write_mode = byte(12); + isc_spb_prp_access_mode = byte(13); + isc_spb_prp_set_sql_dialect = byte(14); + isc_spb_prp_activate = $0100; + isc_spb_prp_db_online = $0200; + isc_spb_prp_nolinger = $0400; + isc_spb_prp_force_shutdown = byte(41); + isc_spb_prp_attachments_shutdown = byte(42); + isc_spb_prp_transactions_shutdown = byte(43); + isc_spb_prp_shutdown_mode = byte(44); + isc_spb_prp_online_mode = byte(45); + isc_spb_prp_sm_normal = byte(0); + isc_spb_prp_sm_multi = byte(1); + isc_spb_prp_sm_single = byte(2); + isc_spb_prp_sm_full = byte(3); + isc_spb_prp_res_use_full = byte(35); + isc_spb_prp_res = byte(36); + isc_spb_prp_wm_async = byte(37); + isc_spb_prp_wm_sync = byte(38); + isc_spb_prp_am_readonly = byte(39); + isc_spb_prp_am_readwrite = byte(40); + isc_spb_rpr_commit_trans = byte(15); + isc_spb_rpr_rollback_trans = byte(34); + isc_spb_rpr_recover_two_phase = byte(17); + isc_spb_tra_id = byte(18); + isc_spb_single_tra_id = byte(19); + isc_spb_multi_tra_id = byte(20); + isc_spb_tra_state = byte(21); + isc_spb_tra_state_limbo = byte(22); + isc_spb_tra_state_commit = byte(23); + isc_spb_tra_state_rollback = byte(24); + isc_spb_tra_state_unknown = byte(25); + isc_spb_tra_host_site = byte(26); + isc_spb_tra_remote_site = byte(27); + isc_spb_tra_db_path = byte(28); + isc_spb_tra_advise = byte(29); + isc_spb_tra_advise_commit = byte(30); + isc_spb_tra_advise_rollback = byte(31); + isc_spb_tra_advise_unknown = byte(33); + isc_spb_tra_id_64 = byte(46); + isc_spb_single_tra_id_64 = byte(47); + isc_spb_multi_tra_id_64 = byte(48); + isc_spb_rpr_commit_trans_64 = byte(49); + isc_spb_rpr_rollback_trans_64 = byte(50); + isc_spb_rpr_recover_two_phase_64 = byte(51); + isc_spb_rpr_validate_db = $01; + isc_spb_rpr_sweep_db = $02; + isc_spb_rpr_mend_db = $04; + isc_spb_rpr_list_limbo_trans = $08; + isc_spb_rpr_check_db = $10; + isc_spb_rpr_ignore_checksum = $20; + isc_spb_rpr_kill_shadows = $40; + isc_spb_rpr_full = $80; + isc_spb_rpr_icu = $0800; + isc_spb_res_buffers = byte(9); + isc_spb_res_page_size = byte(10); + isc_spb_res_length = byte(11); + isc_spb_res_access_mode = byte(12); + isc_spb_res_fix_fss_data = byte(13); + isc_spb_res_fix_fss_metadata = byte(14); + isc_spb_res_deactivate_idx = $0100; + isc_spb_res_no_shadow = $0200; + isc_spb_res_no_validity = $0400; + isc_spb_res_one_at_a_time = $0800; + isc_spb_res_replace = $1000; + isc_spb_res_create = $2000; + isc_spb_res_use_all_space = $4000; + isc_spb_val_tab_incl = byte(1); + isc_spb_val_tab_excl = byte(2); + isc_spb_val_idx_incl = byte(3); + isc_spb_val_idx_excl = byte(4); + isc_spb_val_lock_timeout = byte(5); + isc_spb_num_att = byte(5); + isc_spb_num_db = byte(6); + isc_spb_sts_table = byte(64); + isc_spb_sts_data_pages = $01; + isc_spb_sts_db_log = $02; + isc_spb_sts_hdr_pages = $04; + isc_spb_sts_idx_pages = $08; + isc_spb_sts_sys_relations = $10; + isc_spb_sts_record_versions = $20; + isc_spb_sts_nocreation = $80; + isc_spb_sts_encryption = $100; + isc_spb_nbk_level = byte(5); + isc_spb_nbk_file = byte(6); + isc_spb_nbk_direct = byte(7); + isc_spb_nbk_no_triggers = $01; + isc_spb_trc_id = byte(1); + isc_spb_trc_name = byte(2); + isc_spb_trc_cfg = byte(3); + isc_sdl_version1 = byte(1); + isc_sdl_eoc = byte(255); + isc_sdl_relation = byte(2); + isc_sdl_rid = byte(3); + isc_sdl_field = byte(4); + isc_sdl_fid = byte(5); + isc_sdl_struct = byte(6); + isc_sdl_variable = byte(7); + isc_sdl_scalar = byte(8); + isc_sdl_tiny_integer = byte(9); + isc_sdl_short_integer = byte(10); + isc_sdl_long_integer = byte(11); + isc_sdl_add = byte(13); + isc_sdl_subtract = byte(14); + isc_sdl_multiply = byte(15); + isc_sdl_divide = byte(16); + isc_sdl_negate = byte(17); + isc_sdl_begin = byte(31); + isc_sdl_end = byte(32); + isc_sdl_do3 = byte(33); + isc_sdl_do2 = byte(34); + isc_sdl_do1 = byte(35); + isc_sdl_element = byte(36); + isc_blob_untyped = byte(0); + isc_blob_text = byte(1); + isc_blob_blr = byte(2); + isc_blob_acl = byte(3); + isc_blob_ranges = byte(4); + isc_blob_summary = byte(5); + isc_blob_format = byte(6); + isc_blob_tra = byte(7); + isc_blob_extfile = byte(8); + isc_blob_debug_info = byte(9); + isc_blob_max_predefined_subtype = byte(10); + fb_shut_confirmation = byte(1); + fb_shut_preproviders = byte(2); + fb_shut_postproviders = byte(4); + fb_shut_finish = byte(8); + fb_shut_exit = byte(16); + fb_cancel_disable = byte(1); + fb_cancel_enable = byte(2); + fb_cancel_raise = byte(3); + fb_cancel_abort = byte(4); + fb_dbg_version = byte(1); + fb_dbg_end = byte(255); + fb_dbg_map_src2blr = byte(2); + fb_dbg_map_varname = byte(3); + fb_dbg_map_argument = byte(4); + fb_dbg_subproc = byte(5); + fb_dbg_subfunc = byte(6); + fb_dbg_map_curname = byte(7); + fb_dbg_arg_input = byte(0); + fb_dbg_arg_output = byte(1); + isc_facility = 20; + isc_err_base = 335544320; + isc_err_factor = 1; + isc_arg_end = 0; (* end of argument list *) + isc_arg_gds = 1; (* generic DSRI status value *) + isc_arg_string = 2; (* string argument *) + isc_arg_cstring = 3; (* count & string argument *) + isc_arg_number = 4; (* numeric argument (long) *) + isc_arg_interpreted = 5; (* interpreted status code (string) *) + isc_arg_vms = 6; (* VAX/VMS status code (long) *) + isc_arg_unix = 7; (* UNIX error code *) + isc_arg_domain = 8; (* Apollo/Domain error code *) + isc_arg_dos = 9; (* MSDOS/OS2 error code *) + isc_arith_except = 335544321; + isc_bad_dbkey = 335544322; + isc_bad_db_format = 335544323; + isc_bad_db_handle = 335544324; + isc_bad_dpb_content = 335544325; + isc_bad_dpb_form = 335544326; + isc_bad_req_handle = 335544327; + isc_bad_segstr_handle = 335544328; + isc_bad_segstr_id = 335544329; + isc_bad_tpb_content = 335544330; + isc_bad_tpb_form = 335544331; + isc_bad_trans_handle = 335544332; + isc_bug_check = 335544333; + isc_convert_error = 335544334; + isc_db_corrupt = 335544335; + isc_deadlock = 335544336; + isc_excess_trans = 335544337; + isc_from_no_match = 335544338; + isc_infinap = 335544339; + isc_infona = 335544340; + isc_infunk = 335544341; + isc_integ_fail = 335544342; + isc_invalid_blr = 335544343; + isc_io_error = 335544344; + isc_lock_conflict = 335544345; + isc_metadata_corrupt = 335544346; + isc_not_valid = 335544347; + isc_no_cur_rec = 335544348; + isc_no_dup = 335544349; + isc_no_finish = 335544350; + isc_no_meta_update = 335544351; + isc_no_priv = 335544352; + isc_no_recon = 335544353; + isc_no_record = 335544354; + isc_no_segstr_close = 335544355; + isc_obsolete_metadata = 335544356; + isc_open_trans = 335544357; + isc_port_len = 335544358; + isc_read_only_field = 335544359; + isc_read_only_rel = 335544360; + isc_read_only_trans = 335544361; + isc_read_only_view = 335544362; + isc_req_no_trans = 335544363; + isc_req_sync = 335544364; + isc_req_wrong_db = 335544365; + isc_segment = 335544366; + isc_segstr_eof = 335544367; + isc_segstr_no_op = 335544368; + isc_segstr_no_read = 335544369; + isc_segstr_no_trans = 335544370; + isc_segstr_no_write = 335544371; + isc_segstr_wrong_db = 335544372; + isc_sys_request = 335544373; + isc_stream_eof = 335544374; + isc_unavailable = 335544375; + isc_unres_rel = 335544376; + isc_uns_ext = 335544377; + isc_wish_list = 335544378; + isc_wrong_ods = 335544379; + isc_wronumarg = 335544380; + isc_imp_exc = 335544381; + isc_random = 335544382; + isc_fatal_conflict = 335544383; + isc_badblk = 335544384; + isc_invpoolcl = 335544385; + isc_nopoolids = 335544386; + isc_relbadblk = 335544387; + isc_blktoobig = 335544388; + isc_bufexh = 335544389; + isc_syntaxerr = 335544390; + isc_bufinuse = 335544391; + isc_bdbincon = 335544392; + isc_reqinuse = 335544393; + isc_badodsver = 335544394; + isc_relnotdef = 335544395; + isc_fldnotdef = 335544396; + isc_dirtypage = 335544397; + isc_waifortra = 335544398; + isc_doubleloc = 335544399; + isc_nodnotfnd = 335544400; + isc_dupnodfnd = 335544401; + isc_locnotmar = 335544402; + isc_badpagtyp = 335544403; + isc_corrupt = 335544404; + isc_badpage = 335544405; + isc_badindex = 335544406; + isc_dbbnotzer = 335544407; + isc_tranotzer = 335544408; + isc_trareqmis = 335544409; + isc_badhndcnt = 335544410; + isc_wrotpbver = 335544411; + isc_wroblrver = 335544412; + isc_wrodpbver = 335544413; + isc_blobnotsup = 335544414; + isc_badrelation = 335544415; + isc_nodetach = 335544416; + isc_notremote = 335544417; + isc_trainlim = 335544418; + isc_notinlim = 335544419; + isc_traoutsta = 335544420; + isc_connect_reject = 335544421; + isc_dbfile = 335544422; + isc_orphan = 335544423; + isc_no_lock_mgr = 335544424; + isc_ctxinuse = 335544425; + isc_ctxnotdef = 335544426; + isc_datnotsup = 335544427; + isc_badmsgnum = 335544428; + isc_badparnum = 335544429; + isc_virmemexh = 335544430; + isc_blocking_signal = 335544431; + isc_lockmanerr = 335544432; + isc_journerr = 335544433; + isc_keytoobig = 335544434; + isc_nullsegkey = 335544435; + isc_sqlerr = 335544436; + isc_wrodynver = 335544437; + isc_funnotdef = 335544438; + isc_funmismat = 335544439; + isc_bad_msg_vec = 335544440; + isc_bad_detach = 335544441; + isc_noargacc_read = 335544442; + isc_noargacc_write = 335544443; + isc_read_only = 335544444; + isc_ext_err = 335544445; + isc_non_updatable = 335544446; + isc_no_rollback = 335544447; + isc_bad_sec_info = 335544448; + isc_invalid_sec_info = 335544449; + isc_misc_interpreted = 335544450; + isc_update_conflict = 335544451; + isc_unlicensed = 335544452; + isc_obj_in_use = 335544453; + isc_nofilter = 335544454; + isc_shadow_accessed = 335544455; + isc_invalid_sdl = 335544456; + isc_out_of_bounds = 335544457; + isc_invalid_dimension = 335544458; + isc_rec_in_limbo = 335544459; + isc_shadow_missing = 335544460; + isc_cant_validate = 335544461; + isc_cant_start_journal = 335544462; + isc_gennotdef = 335544463; + isc_cant_start_logging = 335544464; + isc_bad_segstr_type = 335544465; + isc_foreign_key = 335544466; + isc_high_minor = 335544467; + isc_tra_state = 335544468; + isc_trans_invalid = 335544469; + isc_buf_invalid = 335544470; + isc_indexnotdefined = 335544471; + isc_login = 335544472; + isc_invalid_bookmark = 335544473; + isc_bad_lock_level = 335544474; + isc_relation_lock = 335544475; + isc_record_lock = 335544476; + isc_max_idx = 335544477; + isc_jrn_enable = 335544478; + isc_old_failure = 335544479; + isc_old_in_progress = 335544480; + isc_old_no_space = 335544481; + isc_no_wal_no_jrn = 335544482; + isc_num_old_files = 335544483; + isc_wal_file_open = 335544484; + isc_bad_stmt_handle = 335544485; + isc_wal_failure = 335544486; + isc_walw_err = 335544487; + isc_logh_small = 335544488; + isc_logh_inv_version = 335544489; + isc_logh_open_flag = 335544490; + isc_logh_open_flag2 = 335544491; + isc_logh_diff_dbname = 335544492; + isc_logf_unexpected_eof = 335544493; + isc_logr_incomplete = 335544494; + isc_logr_header_small = 335544495; + isc_logb_small = 335544496; + isc_wal_illegal_attach = 335544497; + isc_wal_invalid_wpb = 335544498; + isc_wal_err_rollover = 335544499; + isc_no_wal = 335544500; + isc_drop_wal = 335544501; + isc_stream_not_defined = 335544502; + isc_wal_subsys_error = 335544503; + isc_wal_subsys_corrupt = 335544504; + isc_no_archive = 335544505; + isc_shutinprog = 335544506; + isc_range_in_use = 335544507; + isc_range_not_found = 335544508; + isc_charset_not_found = 335544509; + isc_lock_timeout = 335544510; + isc_prcnotdef = 335544511; + isc_prcmismat = 335544512; + isc_wal_bugcheck = 335544513; + isc_wal_cant_expand = 335544514; + isc_codnotdef = 335544515; + isc_xcpnotdef = 335544516; + isc_except = 335544517; + isc_cache_restart = 335544518; + isc_bad_lock_handle = 335544519; + isc_jrn_present = 335544520; + isc_wal_err_rollover2 = 335544521; + isc_wal_err_logwrite = 335544522; + isc_wal_err_jrn_comm = 335544523; + isc_wal_err_expansion = 335544524; + isc_wal_err_setup = 335544525; + isc_wal_err_ww_sync = 335544526; + isc_wal_err_ww_start = 335544527; + isc_shutdown = 335544528; + isc_existing_priv_mod = 335544529; + isc_primary_key_ref = 335544530; + isc_primary_key_notnull = 335544531; + isc_ref_cnstrnt_notfound = 335544532; + isc_foreign_key_notfound = 335544533; + isc_ref_cnstrnt_update = 335544534; + isc_check_cnstrnt_update = 335544535; + isc_check_cnstrnt_del = 335544536; + isc_integ_index_seg_del = 335544537; + isc_integ_index_seg_mod = 335544538; + isc_integ_index_del = 335544539; + isc_integ_index_mod = 335544540; + isc_check_trig_del = 335544541; + isc_check_trig_update = 335544542; + isc_cnstrnt_fld_del = 335544543; + isc_cnstrnt_fld_rename = 335544544; + isc_rel_cnstrnt_update = 335544545; + isc_constaint_on_view = 335544546; + isc_invld_cnstrnt_type = 335544547; + isc_primary_key_exists = 335544548; + isc_systrig_update = 335544549; + isc_not_rel_owner = 335544550; + isc_grant_obj_notfound = 335544551; + isc_grant_fld_notfound = 335544552; + isc_grant_nopriv = 335544553; + isc_nonsql_security_rel = 335544554; + isc_nonsql_security_fld = 335544555; + isc_wal_cache_err = 335544556; + isc_shutfail = 335544557; + isc_check_constraint = 335544558; + isc_bad_svc_handle = 335544559; + isc_shutwarn = 335544560; + isc_wrospbver = 335544561; + isc_bad_spb_form = 335544562; + isc_svcnotdef = 335544563; + isc_no_jrn = 335544564; + isc_transliteration_failed = 335544565; + isc_start_cm_for_wal = 335544566; + isc_wal_ovflow_log_required = 335544567; + isc_text_subtype = 335544568; + isc_dsql_error = 335544569; + isc_dsql_command_err = 335544570; + isc_dsql_constant_err = 335544571; + isc_dsql_cursor_err = 335544572; + isc_dsql_datatype_err = 335544573; + isc_dsql_decl_err = 335544574; + isc_dsql_cursor_update_err = 335544575; + isc_dsql_cursor_open_err = 335544576; + isc_dsql_cursor_close_err = 335544577; + isc_dsql_field_err = 335544578; + isc_dsql_internal_err = 335544579; + isc_dsql_relation_err = 335544580; + isc_dsql_procedure_err = 335544581; + isc_dsql_request_err = 335544582; + isc_dsql_sqlda_err = 335544583; + isc_dsql_var_count_err = 335544584; + isc_dsql_stmt_handle = 335544585; + isc_dsql_function_err = 335544586; + isc_dsql_blob_err = 335544587; + isc_collation_not_found = 335544588; + isc_collation_not_for_charset = 335544589; + isc_dsql_dup_option = 335544590; + isc_dsql_tran_err = 335544591; + isc_dsql_invalid_array = 335544592; + isc_dsql_max_arr_dim_exceeded = 335544593; + isc_dsql_arr_range_error = 335544594; + isc_dsql_trigger_err = 335544595; + isc_dsql_subselect_err = 335544596; + isc_dsql_crdb_prepare_err = 335544597; + isc_specify_field_err = 335544598; + isc_num_field_err = 335544599; + isc_col_name_err = 335544600; + isc_where_err = 335544601; + isc_table_view_err = 335544602; + isc_distinct_err = 335544603; + isc_key_field_count_err = 335544604; + isc_subquery_err = 335544605; + isc_expression_eval_err = 335544606; + isc_node_err = 335544607; + isc_command_end_err = 335544608; + isc_index_name = 335544609; + isc_exception_name = 335544610; + isc_field_name = 335544611; + isc_token_err = 335544612; + isc_union_err = 335544613; + isc_dsql_construct_err = 335544614; + isc_field_aggregate_err = 335544615; + isc_field_ref_err = 335544616; + isc_order_by_err = 335544617; + isc_return_mode_err = 335544618; + isc_extern_func_err = 335544619; + isc_alias_conflict_err = 335544620; + isc_procedure_conflict_error = 335544621; + isc_relation_conflict_err = 335544622; + isc_dsql_domain_err = 335544623; + isc_idx_seg_err = 335544624; + isc_node_name_err = 335544625; + isc_table_name = 335544626; + isc_proc_name = 335544627; + isc_idx_create_err = 335544628; + isc_wal_shadow_err = 335544629; + isc_dependency = 335544630; + isc_idx_key_err = 335544631; + isc_dsql_file_length_err = 335544632; + isc_dsql_shadow_number_err = 335544633; + isc_dsql_token_unk_err = 335544634; + isc_dsql_no_relation_alias = 335544635; + isc_indexname = 335544636; + isc_no_stream_plan = 335544637; + isc_stream_twice = 335544638; + isc_stream_not_found = 335544639; + isc_collation_requires_text = 335544640; + isc_dsql_domain_not_found = 335544641; + isc_index_unused = 335544642; + isc_dsql_self_join = 335544643; + isc_stream_bof = 335544644; + isc_stream_crack = 335544645; + isc_db_or_file_exists = 335544646; + isc_invalid_operator = 335544647; + isc_conn_lost = 335544648; + isc_bad_checksum = 335544649; + isc_page_type_err = 335544650; + isc_ext_readonly_err = 335544651; + isc_sing_select_err = 335544652; + isc_psw_attach = 335544653; + isc_psw_start_trans = 335544654; + isc_invalid_direction = 335544655; + isc_dsql_var_conflict = 335544656; + isc_dsql_no_blob_array = 335544657; + isc_dsql_base_table = 335544658; + isc_duplicate_base_table = 335544659; + isc_view_alias = 335544660; + isc_index_root_page_full = 335544661; + isc_dsql_blob_type_unknown = 335544662; + isc_req_max_clones_exceeded = 335544663; + isc_dsql_duplicate_spec = 335544664; + isc_unique_key_violation = 335544665; + isc_srvr_version_too_old = 335544666; + isc_drdb_completed_with_errs = 335544667; + isc_dsql_procedure_use_err = 335544668; + isc_dsql_count_mismatch = 335544669; + isc_blob_idx_err = 335544670; + isc_array_idx_err = 335544671; + isc_key_field_err = 335544672; + isc_no_delete = 335544673; + isc_del_last_field = 335544674; + isc_sort_err = 335544675; + isc_sort_mem_err = 335544676; + isc_version_err = 335544677; + isc_inval_key_posn = 335544678; + isc_no_segments_err = 335544679; + isc_crrp_data_err = 335544680; + isc_rec_size_err = 335544681; + isc_dsql_field_ref = 335544682; + isc_req_depth_exceeded = 335544683; + isc_no_field_access = 335544684; + isc_no_dbkey = 335544685; + isc_jrn_format_err = 335544686; + isc_jrn_file_full = 335544687; + isc_dsql_open_cursor_request = 335544688; + isc_ib_error = 335544689; + isc_cache_redef = 335544690; + isc_cache_too_small = 335544691; + isc_log_redef = 335544692; + isc_log_too_small = 335544693; + isc_partition_too_small = 335544694; + isc_partition_not_supp = 335544695; + isc_log_length_spec = 335544696; + isc_precision_err = 335544697; + isc_scale_nogt = 335544698; + isc_expec_short = 335544699; + isc_expec_long = 335544700; + isc_expec_ushort = 335544701; + isc_escape_invalid = 335544702; + isc_svcnoexe = 335544703; + isc_net_lookup_err = 335544704; + isc_service_unknown = 335544705; + isc_host_unknown = 335544706; + isc_grant_nopriv_on_base = 335544707; + isc_dyn_fld_ambiguous = 335544708; + isc_dsql_agg_ref_err = 335544709; + isc_complex_view = 335544710; + isc_unprepared_stmt = 335544711; + isc_expec_positive = 335544712; + isc_dsql_sqlda_value_err = 335544713; + isc_invalid_array_id = 335544714; + isc_extfile_uns_op = 335544715; + isc_svc_in_use = 335544716; + isc_err_stack_limit = 335544717; + isc_invalid_key = 335544718; + isc_net_init_error = 335544719; + isc_loadlib_failure = 335544720; + isc_network_error = 335544721; + isc_net_connect_err = 335544722; + isc_net_connect_listen_err = 335544723; + isc_net_event_connect_err = 335544724; + isc_net_event_listen_err = 335544725; + isc_net_read_err = 335544726; + isc_net_write_err = 335544727; + isc_integ_index_deactivate = 335544728; + isc_integ_deactivate_primary = 335544729; + isc_cse_not_supported = 335544730; + isc_tra_must_sweep = 335544731; + isc_unsupported_network_drive = 335544732; + isc_io_create_err = 335544733; + isc_io_open_err = 335544734; + isc_io_close_err = 335544735; + isc_io_read_err = 335544736; + isc_io_write_err = 335544737; + isc_io_delete_err = 335544738; + isc_io_access_err = 335544739; + isc_udf_exception = 335544740; + isc_lost_db_connection = 335544741; + isc_no_write_user_priv = 335544742; + isc_token_too_long = 335544743; + isc_max_att_exceeded = 335544744; + isc_login_same_as_role_name = 335544745; + isc_reftable_requires_pk = 335544746; + isc_usrname_too_long = 335544747; + isc_password_too_long = 335544748; + isc_usrname_required = 335544749; + isc_password_required = 335544750; + isc_bad_protocol = 335544751; + isc_dup_usrname_found = 335544752; + isc_usrname_not_found = 335544753; + isc_error_adding_sec_record = 335544754; + isc_error_modifying_sec_record = 335544755; + isc_error_deleting_sec_record = 335544756; + isc_error_updating_sec_db = 335544757; + isc_sort_rec_size_err = 335544758; + isc_bad_default_value = 335544759; + isc_invalid_clause = 335544760; + isc_too_many_handles = 335544761; + isc_optimizer_blk_exc = 335544762; + isc_invalid_string_constant = 335544763; + isc_transitional_date = 335544764; + isc_read_only_database = 335544765; + isc_must_be_dialect_2_and_up = 335544766; + isc_blob_filter_exception = 335544767; + isc_exception_access_violation = 335544768; + isc_exception_datatype_missalignment = 335544769; + isc_exception_array_bounds_exceeded = 335544770; + isc_exception_float_denormal_operand = 335544771; + isc_exception_float_divide_by_zero = 335544772; + isc_exception_float_inexact_result = 335544773; + isc_exception_float_invalid_operand = 335544774; + isc_exception_float_overflow = 335544775; + isc_exception_float_stack_check = 335544776; + isc_exception_float_underflow = 335544777; + isc_exception_integer_divide_by_zero = 335544778; + isc_exception_integer_overflow = 335544779; + isc_exception_unknown = 335544780; + isc_exception_stack_overflow = 335544781; + isc_exception_sigsegv = 335544782; + isc_exception_sigill = 335544783; + isc_exception_sigbus = 335544784; + isc_exception_sigfpe = 335544785; + isc_ext_file_delete = 335544786; + isc_ext_file_modify = 335544787; + isc_adm_task_denied = 335544788; + isc_extract_input_mismatch = 335544789; + isc_insufficient_svc_privileges = 335544790; + isc_file_in_use = 335544791; + isc_service_att_err = 335544792; + isc_ddl_not_allowed_by_db_sql_dial = 335544793; + isc_cancelled = 335544794; + isc_unexp_spb_form = 335544795; + isc_sql_dialect_datatype_unsupport = 335544796; + isc_svcnouser = 335544797; + isc_depend_on_uncommitted_rel = 335544798; + isc_svc_name_missing = 335544799; + isc_too_many_contexts = 335544800; + isc_datype_notsup = 335544801; + isc_dialect_reset_warning = 335544802; + isc_dialect_not_changed = 335544803; + isc_database_create_failed = 335544804; + isc_inv_dialect_specified = 335544805; + isc_valid_db_dialects = 335544806; + isc_sqlwarn = 335544807; + isc_dtype_renamed = 335544808; + isc_extern_func_dir_error = 335544809; + isc_date_range_exceeded = 335544810; + isc_inv_client_dialect_specified = 335544811; + isc_valid_client_dialects = 335544812; + isc_optimizer_between_err = 335544813; + isc_service_not_supported = 335544814; + isc_generator_name = 335544815; + isc_udf_name = 335544816; + isc_bad_limit_param = 335544817; + isc_bad_skip_param = 335544818; + isc_io_32bit_exceeded_err = 335544819; + isc_invalid_savepoint = 335544820; + isc_dsql_column_pos_err = 335544821; + isc_dsql_agg_where_err = 335544822; + isc_dsql_agg_group_err = 335544823; + isc_dsql_agg_column_err = 335544824; + isc_dsql_agg_having_err = 335544825; + isc_dsql_agg_nested_err = 335544826; + isc_exec_sql_invalid_arg = 335544827; + isc_exec_sql_invalid_req = 335544828; + isc_exec_sql_invalid_var = 335544829; + isc_exec_sql_max_call_exceeded = 335544830; + isc_conf_access_denied = 335544831; + isc_wrong_backup_state = 335544832; + isc_wal_backup_err = 335544833; + isc_cursor_not_open = 335544834; + isc_bad_shutdown_mode = 335544835; + isc_concat_overflow = 335544836; + isc_bad_substring_offset = 335544837; + isc_foreign_key_target_doesnt_exist = 335544838; + isc_foreign_key_references_present = 335544839; + isc_no_update = 335544840; + isc_cursor_already_open = 335544841; + isc_stack_trace = 335544842; + isc_ctx_var_not_found = 335544843; + isc_ctx_namespace_invalid = 335544844; + isc_ctx_too_big = 335544845; + isc_ctx_bad_argument = 335544846; + isc_identifier_too_long = 335544847; + isc_except2 = 335544848; + isc_malformed_string = 335544849; + isc_prc_out_param_mismatch = 335544850; + isc_command_end_err2 = 335544851; + isc_partner_idx_incompat_type = 335544852; + isc_bad_substring_length = 335544853; + isc_charset_not_installed = 335544854; + isc_collation_not_installed = 335544855; + isc_att_shutdown = 335544856; + isc_blobtoobig = 335544857; + isc_must_have_phys_field = 335544858; + isc_invalid_time_precision = 335544859; + isc_blob_convert_error = 335544860; + isc_array_convert_error = 335544861; + isc_record_lock_not_supp = 335544862; + isc_partner_idx_not_found = 335544863; + isc_tra_num_exc = 335544864; + isc_field_disappeared = 335544865; + isc_met_wrong_gtt_scope = 335544866; + isc_subtype_for_internal_use = 335544867; + isc_illegal_prc_type = 335544868; + isc_invalid_sort_datatype = 335544869; + isc_collation_name = 335544870; + isc_domain_name = 335544871; + isc_domnotdef = 335544872; + isc_array_max_dimensions = 335544873; + isc_max_db_per_trans_allowed = 335544874; + isc_bad_debug_format = 335544875; + isc_bad_proc_BLR = 335544876; + isc_key_too_big = 335544877; + isc_concurrent_transaction = 335544878; + isc_not_valid_for_var = 335544879; + isc_not_valid_for = 335544880; + isc_need_difference = 335544881; + isc_long_login = 335544882; + isc_fldnotdef2 = 335544883; + isc_invalid_similar_pattern = 335544884; + isc_bad_teb_form = 335544885; + isc_tpb_multiple_txn_isolation = 335544886; + isc_tpb_reserv_before_table = 335544887; + isc_tpb_multiple_spec = 335544888; + isc_tpb_option_without_rc = 335544889; + isc_tpb_conflicting_options = 335544890; + isc_tpb_reserv_missing_tlen = 335544891; + isc_tpb_reserv_long_tlen = 335544892; + isc_tpb_reserv_missing_tname = 335544893; + isc_tpb_reserv_corrup_tlen = 335544894; + isc_tpb_reserv_null_tlen = 335544895; + isc_tpb_reserv_relnotfound = 335544896; + isc_tpb_reserv_baserelnotfound = 335544897; + isc_tpb_missing_len = 335544898; + isc_tpb_missing_value = 335544899; + isc_tpb_corrupt_len = 335544900; + isc_tpb_null_len = 335544901; + isc_tpb_overflow_len = 335544902; + isc_tpb_invalid_value = 335544903; + isc_tpb_reserv_stronger_wng = 335544904; + isc_tpb_reserv_stronger = 335544905; + isc_tpb_reserv_max_recursion = 335544906; + isc_tpb_reserv_virtualtbl = 335544907; + isc_tpb_reserv_systbl = 335544908; + isc_tpb_reserv_temptbl = 335544909; + isc_tpb_readtxn_after_writelock = 335544910; + isc_tpb_writelock_after_readtxn = 335544911; + isc_time_range_exceeded = 335544912; + isc_datetime_range_exceeded = 335544913; + isc_string_truncation = 335544914; + isc_blob_truncation = 335544915; + isc_numeric_out_of_range = 335544916; + isc_shutdown_timeout = 335544917; + isc_att_handle_busy = 335544918; + isc_bad_udf_freeit = 335544919; + isc_eds_provider_not_found = 335544920; + isc_eds_connection = 335544921; + isc_eds_preprocess = 335544922; + isc_eds_stmt_expected = 335544923; + isc_eds_prm_name_expected = 335544924; + isc_eds_unclosed_comment = 335544925; + isc_eds_statement = 335544926; + isc_eds_input_prm_mismatch = 335544927; + isc_eds_output_prm_mismatch = 335544928; + isc_eds_input_prm_not_set = 335544929; + isc_too_big_blr = 335544930; + isc_montabexh = 335544931; + isc_modnotfound = 335544932; + isc_nothing_to_cancel = 335544933; + isc_ibutil_not_loaded = 335544934; + isc_circular_computed = 335544935; + isc_psw_db_error = 335544936; + isc_invalid_type_datetime_op = 335544937; + isc_onlycan_add_timetodate = 335544938; + isc_onlycan_add_datetotime = 335544939; + isc_onlycansub_tstampfromtstamp = 335544940; + isc_onlyoneop_mustbe_tstamp = 335544941; + isc_invalid_extractpart_time = 335544942; + isc_invalid_extractpart_date = 335544943; + isc_invalidarg_extract = 335544944; + isc_sysf_argmustbe_exact = 335544945; + isc_sysf_argmustbe_exact_or_fp = 335544946; + isc_sysf_argviolates_uuidtype = 335544947; + isc_sysf_argviolates_uuidlen = 335544948; + isc_sysf_argviolates_uuidfmt = 335544949; + isc_sysf_argviolates_guidigits = 335544950; + isc_sysf_invalid_addpart_time = 335544951; + isc_sysf_invalid_add_datetime = 335544952; + isc_sysf_invalid_addpart_dtime = 335544953; + isc_sysf_invalid_add_dtime_rc = 335544954; + isc_sysf_invalid_diff_dtime = 335544955; + isc_sysf_invalid_timediff = 335544956; + isc_sysf_invalid_tstamptimediff = 335544957; + isc_sysf_invalid_datetimediff = 335544958; + isc_sysf_invalid_diffpart = 335544959; + isc_sysf_argmustbe_positive = 335544960; + isc_sysf_basemustbe_positive = 335544961; + isc_sysf_argnmustbe_nonneg = 335544962; + isc_sysf_argnmustbe_positive = 335544963; + isc_sysf_invalid_zeropowneg = 335544964; + isc_sysf_invalid_negpowfp = 335544965; + isc_sysf_invalid_scale = 335544966; + isc_sysf_argmustbe_nonneg = 335544967; + isc_sysf_binuuid_mustbe_str = 335544968; + isc_sysf_binuuid_wrongsize = 335544969; + isc_missing_required_spb = 335544970; + isc_net_server_shutdown = 335544971; + isc_bad_conn_str = 335544972; + isc_bad_epb_form = 335544973; + isc_no_threads = 335544974; + isc_net_event_connect_timeout = 335544975; + isc_sysf_argmustbe_nonzero = 335544976; + isc_sysf_argmustbe_range_inc1_1 = 335544977; + isc_sysf_argmustbe_gteq_one = 335544978; + isc_sysf_argmustbe_range_exc1_1 = 335544979; + isc_internal_rejected_params = 335544980; + isc_sysf_fp_overflow = 335544981; + isc_udf_fp_overflow = 335544982; + isc_udf_fp_nan = 335544983; + isc_instance_conflict = 335544984; + isc_out_of_temp_space = 335544985; + isc_eds_expl_tran_ctrl = 335544986; + isc_no_trusted_spb = 335544987; + isc_package_name = 335544988; + isc_cannot_make_not_null = 335544989; + isc_feature_removed = 335544990; + isc_view_name = 335544991; + isc_lock_dir_access = 335544992; + isc_invalid_fetch_option = 335544993; + isc_bad_fun_BLR = 335544994; + isc_func_pack_not_implemented = 335544995; + isc_proc_pack_not_implemented = 335544996; + isc_eem_func_not_returned = 335544997; + isc_eem_proc_not_returned = 335544998; + isc_eem_trig_not_returned = 335544999; + isc_eem_bad_plugin_ver = 335545000; + isc_eem_engine_notfound = 335545001; + isc_attachment_in_use = 335545002; + isc_transaction_in_use = 335545003; + isc_pman_cannot_load_plugin = 335545004; + isc_pman_module_notfound = 335545005; + isc_pman_entrypoint_notfound = 335545006; + isc_pman_module_bad = 335545007; + isc_pman_plugin_notfound = 335545008; + isc_sysf_invalid_trig_namespace = 335545009; + isc_unexpected_null = 335545010; + isc_type_notcompat_blob = 335545011; + isc_invalid_date_val = 335545012; + isc_invalid_time_val = 335545013; + isc_invalid_timestamp_val = 335545014; + isc_invalid_index_val = 335545015; + isc_formatted_exception = 335545016; + isc_async_active = 335545017; + isc_private_function = 335545018; + isc_private_procedure = 335545019; + isc_request_outdated = 335545020; + isc_bad_events_handle = 335545021; + isc_cannot_copy_stmt = 335545022; + isc_invalid_boolean_usage = 335545023; + isc_sysf_argscant_both_be_zero = 335545024; + isc_spb_no_id = 335545025; + isc_ee_blr_mismatch_null = 335545026; + isc_ee_blr_mismatch_length = 335545027; + isc_ss_out_of_bounds = 335545028; + isc_missing_data_structures = 335545029; + isc_protect_sys_tab = 335545030; + isc_libtommath_generic = 335545031; + isc_wroblrver2 = 335545032; + isc_trunc_limits = 335545033; + isc_info_access = 335545034; + isc_svc_no_stdin = 335545035; + isc_svc_start_failed = 335545036; + isc_svc_no_switches = 335545037; + isc_svc_bad_size = 335545038; + isc_no_crypt_plugin = 335545039; + isc_cp_name_too_long = 335545040; + isc_cp_process_active = 335545041; + isc_cp_already_crypted = 335545042; + isc_decrypt_error = 335545043; + isc_no_providers = 335545044; + isc_null_spb = 335545045; + isc_max_args_exceeded = 335545046; + isc_ee_blr_mismatch_names_count = 335545047; + isc_ee_blr_mismatch_name_not_found = 335545048; + isc_bad_result_set = 335545049; + isc_wrong_message_length = 335545050; + isc_no_output_format = 335545051; + isc_item_finish = 335545052; + isc_miss_config = 335545053; + isc_conf_line = 335545054; + isc_conf_include = 335545055; + isc_include_depth = 335545056; + isc_include_miss = 335545057; + isc_protect_ownership = 335545058; + isc_badvarnum = 335545059; + isc_sec_context = 335545060; + isc_multi_segment = 335545061; + isc_login_changed = 335545062; + isc_auth_handshake_limit = 335545063; + isc_wirecrypt_incompatible = 335545064; + isc_miss_wirecrypt = 335545065; + isc_wirecrypt_key = 335545066; + isc_wirecrypt_plugin = 335545067; + isc_secdb_name = 335545068; + isc_auth_data = 335545069; + isc_auth_datalength = 335545070; + isc_info_unprepared_stmt = 335545071; + isc_idx_key_value = 335545072; + isc_forupdate_virtualtbl = 335545073; + isc_forupdate_systbl = 335545074; + isc_forupdate_temptbl = 335545075; + isc_cant_modify_sysobj = 335545076; + isc_server_misconfigured = 335545077; + isc_alter_role = 335545078; + isc_map_already_exists = 335545079; + isc_map_not_exists = 335545080; + isc_map_load = 335545081; + isc_map_aster = 335545082; + isc_map_multi = 335545083; + isc_map_undefined = 335545084; + isc_baddpb_damaged_mode = 335545085; + isc_baddpb_buffers_range = 335545086; + isc_baddpb_temp_buffers = 335545087; + isc_map_nodb = 335545088; + isc_map_notable = 335545089; + isc_miss_trusted_role = 335545090; + isc_set_invalid_role = 335545091; + isc_cursor_not_positioned = 335545092; + isc_dup_attribute = 335545093; + isc_dyn_no_priv = 335545094; + isc_dsql_cant_grant_option = 335545095; + isc_read_conflict = 335545096; + isc_crdb_load = 335545097; + isc_crdb_nodb = 335545098; + isc_crdb_notable = 335545099; + isc_interface_version_too_old = 335545100; + isc_fun_param_mismatch = 335545101; + isc_savepoint_backout_err = 335545102; + isc_domain_primary_key_notnull = 335545103; + isc_invalid_attachment_charset = 335545104; + isc_map_down = 335545105; + isc_login_error = 335545106; + isc_already_opened = 335545107; + isc_bad_crypt_key = 335545108; + isc_encrypt_error = 335545109; + isc_gfix_db_name = 335740929; + isc_gfix_invalid_sw = 335740930; + isc_gfix_incmp_sw = 335740932; + isc_gfix_replay_req = 335740933; + isc_gfix_pgbuf_req = 335740934; + isc_gfix_val_req = 335740935; + isc_gfix_pval_req = 335740936; + isc_gfix_trn_req = 335740937; + isc_gfix_full_req = 335740940; + isc_gfix_usrname_req = 335740941; + isc_gfix_pass_req = 335740942; + isc_gfix_subs_name = 335740943; + isc_gfix_wal_req = 335740944; + isc_gfix_sec_req = 335740945; + isc_gfix_nval_req = 335740946; + isc_gfix_type_shut = 335740947; + isc_gfix_retry = 335740948; + isc_gfix_retry_db = 335740951; + isc_gfix_exceed_max = 335740991; + isc_gfix_corrupt_pool = 335740992; + isc_gfix_mem_exhausted = 335740993; + isc_gfix_bad_pool = 335740994; + isc_gfix_trn_not_valid = 335740995; + isc_gfix_unexp_eoi = 335741012; + isc_gfix_recon_fail = 335741018; + isc_gfix_trn_unknown = 335741036; + isc_gfix_mode_req = 335741038; + isc_gfix_pzval_req = 335741042; + isc_dsql_dbkey_from_non_table = 336003074; + isc_dsql_transitional_numeric = 336003075; + isc_dsql_dialect_warning_expr = 336003076; + isc_sql_db_dialect_dtype_unsupport = 336003077; + isc_sql_dialect_conflict_num = 336003079; + isc_dsql_warning_number_ambiguous = 336003080; + isc_dsql_warning_number_ambiguous1 = 336003081; + isc_dsql_warn_precision_ambiguous = 336003082; + isc_dsql_warn_precision_ambiguous1 = 336003083; + isc_dsql_warn_precision_ambiguous2 = 336003084; + isc_dsql_ambiguous_field_name = 336003085; + isc_dsql_udf_return_pos_err = 336003086; + isc_dsql_invalid_label = 336003087; + isc_dsql_datatypes_not_comparable = 336003088; + isc_dsql_cursor_invalid = 336003089; + isc_dsql_cursor_redefined = 336003090; + isc_dsql_cursor_not_found = 336003091; + isc_dsql_cursor_exists = 336003092; + isc_dsql_cursor_rel_ambiguous = 336003093; + isc_dsql_cursor_rel_not_found = 336003094; + isc_dsql_cursor_not_open = 336003095; + isc_dsql_type_not_supp_ext_tab = 336003096; + isc_dsql_feature_not_supported_ods = 336003097; + isc_primary_key_required = 336003098; + isc_upd_ins_doesnt_match_pk = 336003099; + isc_upd_ins_doesnt_match_matching = 336003100; + isc_upd_ins_with_complex_view = 336003101; + isc_dsql_incompatible_trigger_type = 336003102; + isc_dsql_db_trigger_type_cant_change = 336003103; + isc_dsql_record_version_table = 336003104; + isc_dsql_invalid_sqlda_version = 336003105; + isc_dsql_sqlvar_index = 336003106; + isc_dsql_no_sqlind = 336003107; + isc_dsql_no_sqldata = 336003108; + isc_dsql_no_input_sqlda = 336003109; + isc_dsql_no_output_sqlda = 336003110; + isc_dsql_wrong_param_num = 336003111; + isc_dyn_filter_not_found = 336068645; + isc_dyn_func_not_found = 336068649; + isc_dyn_index_not_found = 336068656; + isc_dyn_view_not_found = 336068662; + isc_dyn_domain_not_found = 336068697; + isc_dyn_cant_modify_auto_trig = 336068717; + isc_dyn_dup_table = 336068740; + isc_dyn_proc_not_found = 336068748; + isc_dyn_exception_not_found = 336068752; + isc_dyn_proc_param_not_found = 336068754; + isc_dyn_trig_not_found = 336068755; + isc_dyn_charset_not_found = 336068759; + isc_dyn_collation_not_found = 336068760; + isc_dyn_role_not_found = 336068763; + isc_dyn_name_longer = 336068767; + isc_dyn_column_does_not_exist = 336068784; + isc_dyn_role_does_not_exist = 336068796; + isc_dyn_no_grant_admin_opt = 336068797; + isc_dyn_user_not_role_member = 336068798; + isc_dyn_delete_role_failed = 336068799; + isc_dyn_grant_role_to_user = 336068800; + isc_dyn_inv_sql_role_name = 336068801; + isc_dyn_dup_sql_role = 336068802; + isc_dyn_kywd_spec_for_role = 336068803; + isc_dyn_roles_not_supported = 336068804; + isc_dyn_domain_name_exists = 336068812; + isc_dyn_field_name_exists = 336068813; + isc_dyn_dependency_exists = 336068814; + isc_dyn_dtype_invalid = 336068815; + isc_dyn_char_fld_too_small = 336068816; + isc_dyn_invalid_dtype_conversion = 336068817; + isc_dyn_dtype_conv_invalid = 336068818; + isc_dyn_zero_len_id = 336068820; + isc_dyn_gen_not_found = 336068822; + isc_max_coll_per_charset = 336068829; + isc_invalid_coll_attr = 336068830; + isc_dyn_wrong_gtt_scope = 336068840; + isc_dyn_coll_used_table = 336068843; + isc_dyn_coll_used_domain = 336068844; + isc_dyn_cannot_del_syscoll = 336068845; + isc_dyn_cannot_del_def_coll = 336068846; + isc_dyn_table_not_found = 336068849; + isc_dyn_coll_used_procedure = 336068851; + isc_dyn_scale_too_big = 336068852; + isc_dyn_precision_too_small = 336068853; + isc_dyn_miss_priv_warning = 336068855; + isc_dyn_ods_not_supp_feature = 336068856; + isc_dyn_cannot_addrem_computed = 336068857; + isc_dyn_no_empty_pw = 336068858; + isc_dyn_dup_index = 336068859; + isc_dyn_package_not_found = 336068864; + isc_dyn_schema_not_found = 336068865; + isc_dyn_cannot_mod_sysproc = 336068866; + isc_dyn_cannot_mod_systrig = 336068867; + isc_dyn_cannot_mod_sysfunc = 336068868; + isc_dyn_invalid_ddl_proc = 336068869; + isc_dyn_invalid_ddl_trig = 336068870; + isc_dyn_funcnotdef_package = 336068871; + isc_dyn_procnotdef_package = 336068872; + isc_dyn_funcsignat_package = 336068873; + isc_dyn_procsignat_package = 336068874; + isc_dyn_defvaldecl_package_proc = 336068875; + isc_dyn_package_body_exists = 336068877; + isc_dyn_invalid_ddl_func = 336068878; + isc_dyn_newfc_oldsyntax = 336068879; + isc_dyn_func_param_not_found = 336068886; + isc_dyn_routine_param_not_found = 336068887; + isc_dyn_routine_param_ambiguous = 336068888; + isc_dyn_coll_used_function = 336068889; + isc_dyn_domain_used_function = 336068890; + isc_dyn_alter_user_no_clause = 336068891; + isc_dyn_duplicate_package_item = 336068894; + isc_dyn_cant_modify_sysobj = 336068895; + isc_dyn_cant_use_zero_increment = 336068896; + isc_dyn_cant_use_in_foreignkey = 336068897; + isc_dyn_defvaldecl_package_func = 336068898; + isc_gbak_unknown_switch = 336330753; + isc_gbak_page_size_missing = 336330754; + isc_gbak_page_size_toobig = 336330755; + isc_gbak_redir_ouput_missing = 336330756; + isc_gbak_switches_conflict = 336330757; + isc_gbak_unknown_device = 336330758; + isc_gbak_no_protection = 336330759; + isc_gbak_page_size_not_allowed = 336330760; + isc_gbak_multi_source_dest = 336330761; + isc_gbak_filename_missing = 336330762; + isc_gbak_dup_inout_names = 336330763; + isc_gbak_inv_page_size = 336330764; + isc_gbak_db_specified = 336330765; + isc_gbak_db_exists = 336330766; + isc_gbak_unk_device = 336330767; + isc_gbak_blob_info_failed = 336330772; + isc_gbak_unk_blob_item = 336330773; + isc_gbak_get_seg_failed = 336330774; + isc_gbak_close_blob_failed = 336330775; + isc_gbak_open_blob_failed = 336330776; + isc_gbak_put_blr_gen_id_failed = 336330777; + isc_gbak_unk_type = 336330778; + isc_gbak_comp_req_failed = 336330779; + isc_gbak_start_req_failed = 336330780; + isc_gbak_rec_failed = 336330781; + isc_gbak_rel_req_failed = 336330782; + isc_gbak_db_info_failed = 336330783; + isc_gbak_no_db_desc = 336330784; + isc_gbak_db_create_failed = 336330785; + isc_gbak_decomp_len_error = 336330786; + isc_gbak_tbl_missing = 336330787; + isc_gbak_blob_col_missing = 336330788; + isc_gbak_create_blob_failed = 336330789; + isc_gbak_put_seg_failed = 336330790; + isc_gbak_rec_len_exp = 336330791; + isc_gbak_inv_rec_len = 336330792; + isc_gbak_exp_data_type = 336330793; + isc_gbak_gen_id_failed = 336330794; + isc_gbak_unk_rec_type = 336330795; + isc_gbak_inv_bkup_ver = 336330796; + isc_gbak_missing_bkup_desc = 336330797; + isc_gbak_string_trunc = 336330798; + isc_gbak_cant_rest_record = 336330799; + isc_gbak_send_failed = 336330800; + isc_gbak_no_tbl_name = 336330801; + isc_gbak_unexp_eof = 336330802; + isc_gbak_db_format_too_old = 336330803; + isc_gbak_inv_array_dim = 336330804; + isc_gbak_xdr_len_expected = 336330807; + isc_gbak_open_bkup_error = 336330817; + isc_gbak_open_error = 336330818; + isc_gbak_missing_block_fac = 336330934; + isc_gbak_inv_block_fac = 336330935; + isc_gbak_block_fac_specified = 336330936; + isc_gbak_missing_username = 336330940; + isc_gbak_missing_password = 336330941; + isc_gbak_missing_skipped_bytes = 336330952; + isc_gbak_inv_skipped_bytes = 336330953; + isc_gbak_err_restore_charset = 336330965; + isc_gbak_err_restore_collation = 336330967; + isc_gbak_read_error = 336330972; + isc_gbak_write_error = 336330973; + isc_gbak_db_in_use = 336330985; + isc_gbak_sysmemex = 336330990; + isc_gbak_restore_role_failed = 336331002; + isc_gbak_role_op_missing = 336331005; + isc_gbak_page_buffers_missing = 336331010; + isc_gbak_page_buffers_wrong_param = 336331011; + isc_gbak_page_buffers_restore = 336331012; + isc_gbak_inv_size = 336331014; + isc_gbak_file_outof_sequence = 336331015; + isc_gbak_join_file_missing = 336331016; + isc_gbak_stdin_not_supptd = 336331017; + isc_gbak_stdout_not_supptd = 336331018; + isc_gbak_bkup_corrupt = 336331019; + isc_gbak_unk_db_file_spec = 336331020; + isc_gbak_hdr_write_failed = 336331021; + isc_gbak_disk_space_ex = 336331022; + isc_gbak_size_lt_min = 336331023; + isc_gbak_svc_name_missing = 336331025; + isc_gbak_not_ownr = 336331026; + isc_gbak_mode_req = 336331031; + isc_gbak_just_data = 336331033; + isc_gbak_data_only = 336331034; + isc_gbak_missing_interval = 336331078; + isc_gbak_wrong_interval = 336331079; + isc_gbak_verify_verbint = 336331081; + isc_gbak_option_only_restore = 336331082; + isc_gbak_option_only_backup = 336331083; + isc_gbak_option_conflict = 336331084; + isc_gbak_param_conflict = 336331085; + isc_gbak_option_repeated = 336331086; + isc_gbak_max_dbkey_recursion = 336331091; + isc_gbak_max_dbkey_length = 336331092; + isc_gbak_invalid_metadata = 336331093; + isc_gbak_invalid_data = 336331094; + isc_gbak_inv_bkup_ver2 = 336331096; + isc_gbak_db_format_too_old2 = 336331100; + isc_dsql_too_old_ods = 336397205; + isc_dsql_table_not_found = 336397206; + isc_dsql_view_not_found = 336397207; + isc_dsql_line_col_error = 336397208; + isc_dsql_unknown_pos = 336397209; + isc_dsql_no_dup_name = 336397210; + isc_dsql_too_many_values = 336397211; + isc_dsql_no_array_computed = 336397212; + isc_dsql_implicit_domain_name = 336397213; + isc_dsql_only_can_subscript_array = 336397214; + isc_dsql_max_sort_items = 336397215; + isc_dsql_max_group_items = 336397216; + isc_dsql_conflicting_sort_field = 336397217; + isc_dsql_derived_table_more_columns = 336397218; + isc_dsql_derived_table_less_columns = 336397219; + isc_dsql_derived_field_unnamed = 336397220; + isc_dsql_derived_field_dup_name = 336397221; + isc_dsql_derived_alias_select = 336397222; + isc_dsql_derived_alias_field = 336397223; + isc_dsql_auto_field_bad_pos = 336397224; + isc_dsql_cte_wrong_reference = 336397225; + isc_dsql_cte_cycle = 336397226; + isc_dsql_cte_outer_join = 336397227; + isc_dsql_cte_mult_references = 336397228; + isc_dsql_cte_not_a_union = 336397229; + isc_dsql_cte_nonrecurs_after_recurs = 336397230; + isc_dsql_cte_wrong_clause = 336397231; + isc_dsql_cte_union_all = 336397232; + isc_dsql_cte_miss_nonrecursive = 336397233; + isc_dsql_cte_nested_with = 336397234; + isc_dsql_col_more_than_once_using = 336397235; + isc_dsql_unsupp_feature_dialect = 336397236; + isc_dsql_cte_not_used = 336397237; + isc_dsql_col_more_than_once_view = 336397238; + isc_dsql_unsupported_in_auto_trans = 336397239; + isc_dsql_eval_unknode = 336397240; + isc_dsql_agg_wrongarg = 336397241; + isc_dsql_agg2_wrongarg = 336397242; + isc_dsql_nodateortime_pm_string = 336397243; + isc_dsql_invalid_datetime_subtract = 336397244; + isc_dsql_invalid_dateortime_add = 336397245; + isc_dsql_invalid_type_minus_date = 336397246; + isc_dsql_nostring_addsub_dial3 = 336397247; + isc_dsql_invalid_type_addsub_dial3 = 336397248; + isc_dsql_invalid_type_multip_dial1 = 336397249; + isc_dsql_nostring_multip_dial3 = 336397250; + isc_dsql_invalid_type_multip_dial3 = 336397251; + isc_dsql_mustuse_numeric_div_dial1 = 336397252; + isc_dsql_nostring_div_dial3 = 336397253; + isc_dsql_invalid_type_div_dial3 = 336397254; + isc_dsql_nostring_neg_dial3 = 336397255; + isc_dsql_invalid_type_neg = 336397256; + isc_dsql_max_distinct_items = 336397257; + isc_dsql_alter_charset_failed = 336397258; + isc_dsql_comment_on_failed = 336397259; + isc_dsql_create_func_failed = 336397260; + isc_dsql_alter_func_failed = 336397261; + isc_dsql_create_alter_func_failed = 336397262; + isc_dsql_drop_func_failed = 336397263; + isc_dsql_recreate_func_failed = 336397264; + isc_dsql_create_proc_failed = 336397265; + isc_dsql_alter_proc_failed = 336397266; + isc_dsql_create_alter_proc_failed = 336397267; + isc_dsql_drop_proc_failed = 336397268; + isc_dsql_recreate_proc_failed = 336397269; + isc_dsql_create_trigger_failed = 336397270; + isc_dsql_alter_trigger_failed = 336397271; + isc_dsql_create_alter_trigger_failed = 336397272; + isc_dsql_drop_trigger_failed = 336397273; + isc_dsql_recreate_trigger_failed = 336397274; + isc_dsql_create_collation_failed = 336397275; + isc_dsql_drop_collation_failed = 336397276; + isc_dsql_create_domain_failed = 336397277; + isc_dsql_alter_domain_failed = 336397278; + isc_dsql_drop_domain_failed = 336397279; + isc_dsql_create_except_failed = 336397280; + isc_dsql_alter_except_failed = 336397281; + isc_dsql_create_alter_except_failed = 336397282; + isc_dsql_recreate_except_failed = 336397283; + isc_dsql_drop_except_failed = 336397284; + isc_dsql_create_sequence_failed = 336397285; + isc_dsql_create_table_failed = 336397286; + isc_dsql_alter_table_failed = 336397287; + isc_dsql_drop_table_failed = 336397288; + isc_dsql_recreate_table_failed = 336397289; + isc_dsql_create_pack_failed = 336397290; + isc_dsql_alter_pack_failed = 336397291; + isc_dsql_create_alter_pack_failed = 336397292; + isc_dsql_drop_pack_failed = 336397293; + isc_dsql_recreate_pack_failed = 336397294; + isc_dsql_create_pack_body_failed = 336397295; + isc_dsql_drop_pack_body_failed = 336397296; + isc_dsql_recreate_pack_body_failed = 336397297; + isc_dsql_create_view_failed = 336397298; + isc_dsql_alter_view_failed = 336397299; + isc_dsql_create_alter_view_failed = 336397300; + isc_dsql_recreate_view_failed = 336397301; + isc_dsql_drop_view_failed = 336397302; + isc_dsql_drop_sequence_failed = 336397303; + isc_dsql_recreate_sequence_failed = 336397304; + isc_dsql_drop_index_failed = 336397305; + isc_dsql_drop_filter_failed = 336397306; + isc_dsql_drop_shadow_failed = 336397307; + isc_dsql_drop_role_failed = 336397308; + isc_dsql_drop_user_failed = 336397309; + isc_dsql_create_role_failed = 336397310; + isc_dsql_alter_role_failed = 336397311; + isc_dsql_alter_index_failed = 336397312; + isc_dsql_alter_database_failed = 336397313; + isc_dsql_create_shadow_failed = 336397314; + isc_dsql_create_filter_failed = 336397315; + isc_dsql_create_index_failed = 336397316; + isc_dsql_create_user_failed = 336397317; + isc_dsql_alter_user_failed = 336397318; + isc_dsql_grant_failed = 336397319; + isc_dsql_revoke_failed = 336397320; + isc_dsql_cte_recursive_aggregate = 336397321; + isc_dsql_mapping_failed = 336397322; + isc_dsql_alter_sequence_failed = 336397323; + isc_dsql_create_generator_failed = 336397324; + isc_dsql_set_generator_failed = 336397325; + isc_dsql_wlock_simple = 336397326; + isc_dsql_firstskip_rows = 336397327; + isc_dsql_wlock_aggregates = 336397328; + isc_dsql_wlock_conflict = 336397329; + isc_dsql_max_exception_arguments = 336397330; + isc_dsql_string_byte_length = 336397331; + isc_dsql_string_char_length = 336397332; + isc_dsql_max_nesting = 336397333; + isc_gsec_cant_open_db = 336723983; + isc_gsec_switches_error = 336723984; + isc_gsec_no_op_spec = 336723985; + isc_gsec_no_usr_name = 336723986; + isc_gsec_err_add = 336723987; + isc_gsec_err_modify = 336723988; + isc_gsec_err_find_mod = 336723989; + isc_gsec_err_rec_not_found = 336723990; + isc_gsec_err_delete = 336723991; + isc_gsec_err_find_del = 336723992; + isc_gsec_err_find_disp = 336723996; + isc_gsec_inv_param = 336723997; + isc_gsec_op_specified = 336723998; + isc_gsec_pw_specified = 336723999; + isc_gsec_uid_specified = 336724000; + isc_gsec_gid_specified = 336724001; + isc_gsec_proj_specified = 336724002; + isc_gsec_org_specified = 336724003; + isc_gsec_fname_specified = 336724004; + isc_gsec_mname_specified = 336724005; + isc_gsec_lname_specified = 336724006; + isc_gsec_inv_switch = 336724008; + isc_gsec_amb_switch = 336724009; + isc_gsec_no_op_specified = 336724010; + isc_gsec_params_not_allowed = 336724011; + isc_gsec_incompat_switch = 336724012; + isc_gsec_inv_username = 336724044; + isc_gsec_inv_pw_length = 336724045; + isc_gsec_db_specified = 336724046; + isc_gsec_db_admin_specified = 336724047; + isc_gsec_db_admin_pw_specified = 336724048; + isc_gsec_sql_role_specified = 336724049; + isc_gstat_unknown_switch = 336920577; + isc_gstat_retry = 336920578; + isc_gstat_wrong_ods = 336920579; + isc_gstat_unexpected_eof = 336920580; + isc_gstat_open_err = 336920605; + isc_gstat_read_err = 336920606; + isc_gstat_sysmemex = 336920607; + isc_fbsvcmgr_bad_am = 336986113; + isc_fbsvcmgr_bad_wm = 336986114; + isc_fbsvcmgr_bad_rs = 336986115; + isc_fbsvcmgr_info_err = 336986116; + isc_fbsvcmgr_query_err = 336986117; + isc_fbsvcmgr_switch_unknown = 336986118; + isc_fbsvcmgr_bad_sm = 336986159; + isc_fbsvcmgr_fp_open = 336986160; + isc_fbsvcmgr_fp_read = 336986161; + isc_fbsvcmgr_fp_empty = 336986162; + isc_fbsvcmgr_bad_arg = 336986164; + isc_utl_trusted_switch = 337051649; + isc_nbackup_missing_param = 337117213; + isc_nbackup_allowed_switches = 337117214; + isc_nbackup_unknown_param = 337117215; + isc_nbackup_unknown_switch = 337117216; + isc_nbackup_nofetchpw_svc = 337117217; + isc_nbackup_pwfile_error = 337117218; + isc_nbackup_size_with_lock = 337117219; + isc_nbackup_no_switch = 337117220; + isc_nbackup_err_read = 337117223; + isc_nbackup_err_write = 337117224; + isc_nbackup_err_seek = 337117225; + isc_nbackup_err_opendb = 337117226; + isc_nbackup_err_fadvice = 337117227; + isc_nbackup_err_createdb = 337117228; + isc_nbackup_err_openbk = 337117229; + isc_nbackup_err_createbk = 337117230; + isc_nbackup_err_eofdb = 337117231; + isc_nbackup_fixup_wrongstate = 337117232; + isc_nbackup_err_db = 337117233; + isc_nbackup_userpw_toolong = 337117234; + isc_nbackup_lostrec_db = 337117235; + isc_nbackup_lostguid_db = 337117236; + isc_nbackup_err_eofhdrdb = 337117237; + isc_nbackup_db_notlock = 337117238; + isc_nbackup_lostguid_bk = 337117239; + isc_nbackup_page_changed = 337117240; + isc_nbackup_dbsize_inconsistent = 337117241; + isc_nbackup_failed_lzbk = 337117242; + isc_nbackup_err_eofhdrbk = 337117243; + isc_nbackup_invalid_incbk = 337117244; + isc_nbackup_unsupvers_incbk = 337117245; + isc_nbackup_invlevel_incbk = 337117246; + isc_nbackup_wrong_orderbk = 337117247; + isc_nbackup_err_eofbk = 337117248; + isc_nbackup_err_copy = 337117249; + isc_nbackup_err_eofhdr_restdb = 337117250; + isc_nbackup_lostguid_l0bk = 337117251; + isc_nbackup_switchd_parameter = 337117255; + isc_nbackup_user_stop = 337117257; + isc_nbackup_deco_parse = 337117259; + isc_trace_conflict_acts = 337182750; + isc_trace_act_notfound = 337182751; + isc_trace_switch_once = 337182752; + isc_trace_param_val_miss = 337182753; + isc_trace_param_invalid = 337182754; + isc_trace_switch_unknown = 337182755; + isc_trace_switch_svc_only = 337182756; + isc_trace_switch_user_only = 337182757; + isc_trace_switch_param_miss = 337182758; + isc_trace_param_act_notcompat = 337182759; + isc_trace_mandatory_switch_miss = 337182760; +implementation + +procedure IReferenceCounted.addRef(); +begin + ReferenceCountedVTable(vTable).addRef(Self); +end; + +function IReferenceCounted.release(): Integer; +begin + Result := ReferenceCountedVTable(vTable).release(Self); +end; + +procedure IDisposable.dispose(); +begin + DisposableVTable(vTable).dispose(Self); +end; + +procedure IStatus.init(); +begin + StatusVTable(vTable).init(Self); +end; + +function IStatus.getState(): Cardinal; +begin + Result := StatusVTable(vTable).getState(Self); +end; + +procedure IStatus.setErrors2(length: Cardinal; value: NativeIntPtr); +begin + StatusVTable(vTable).setErrors2(Self, length, value); +end; + +procedure IStatus.setWarnings2(length: Cardinal; value: NativeIntPtr); +begin + StatusVTable(vTable).setWarnings2(Self, length, value); +end; + +procedure IStatus.setErrors(value: NativeIntPtr); +begin + StatusVTable(vTable).setErrors(Self, value); +end; + +procedure IStatus.setWarnings(value: NativeIntPtr); +begin + StatusVTable(vTable).setWarnings(Self, value); +end; + +function IStatus.getErrors(): NativeIntPtr; +begin + Result := StatusVTable(vTable).getErrors(Self); +end; + +function IStatus.getWarnings(): NativeIntPtr; +begin + Result := StatusVTable(vTable).getWarnings(Self); +end; + +function IStatus.clone(): IStatus; +begin + Result := StatusVTable(vTable).clone(Self); +end; + +function IMaster.getStatus(): IStatus; +begin + Result := MasterVTable(vTable).getStatus(Self); +end; + +function IMaster.getDispatcher(): IProvider; +begin + Result := MasterVTable(vTable).getDispatcher(Self); +end; + +function IMaster.getPluginManager(): IPluginManager; +begin + Result := MasterVTable(vTable).getPluginManager(Self); +end; + +function IMaster.getTimerControl(): ITimerControl; +begin + Result := MasterVTable(vTable).getTimerControl(Self); +end; + +function IMaster.getDtc(): IDtc; +begin + Result := MasterVTable(vTable).getDtc(Self); +end; + +function IMaster.registerAttachment(provider: IProvider; attachment: IAttachment): IAttachment; +begin + Result := MasterVTable(vTable).registerAttachment(Self, provider, attachment); +end; + +function IMaster.registerTransaction(attachment: IAttachment; transaction: ITransaction): ITransaction; +begin + Result := MasterVTable(vTable).registerTransaction(Self, attachment, transaction); +end; + +function IMaster.getMetadataBuilder(status: IStatus; fieldCount: Cardinal): IMetadataBuilder; +begin + Result := MasterVTable(vTable).getMetadataBuilder(Self, status, fieldCount); +// FbException.checkException(status); +end; + +function IMaster.serverMode(mode: Integer): Integer; +begin + Result := MasterVTable(vTable).serverMode(Self, mode); +end; + +function IMaster.getUtilInterface(): IUtil; +begin + Result := MasterVTable(vTable).getUtilInterface(Self); +end; + +function IMaster.getConfigManager(): IConfigManager; +begin + Result := MasterVTable(vTable).getConfigManager(Self); +end; + +function IMaster.getProcessExiting(): Boolean; +begin + Result := MasterVTable(vTable).getProcessExiting(Self); +end; + +procedure IPluginBase.setOwner(r: IReferenceCounted); +begin + PluginBaseVTable(vTable).setOwner(Self, r); +end; + +function IPluginBase.getOwner(): IReferenceCounted; +begin + Result := PluginBaseVTable(vTable).getOwner(Self); +end; + +function IPluginSet.getName(): PAnsiChar; +begin + Result := PluginSetVTable(vTable).getName(Self); +end; + +function IPluginSet.getModuleName(): PAnsiChar; +begin + Result := PluginSetVTable(vTable).getModuleName(Self); +end; + +function IPluginSet.getPlugin(status: IStatus): IPluginBase; +begin + Result := PluginSetVTable(vTable).getPlugin(Self, status); +// FbException.checkException(status); +end; + +procedure IPluginSet.next(status: IStatus); +begin + PluginSetVTable(vTable).next(Self, status); +// FbException.checkException(status); +end; + +procedure IPluginSet.set_(status: IStatus; s: PAnsiChar); +begin + PluginSetVTable(vTable).set_(Self, status, s); +// FbException.checkException(status); +end; + +function IConfigEntry.getName(): PAnsiChar; +begin + Result := ConfigEntryVTable(vTable).getName(Self); +end; + +function IConfigEntry.getValue(): PAnsiChar; +begin + Result := ConfigEntryVTable(vTable).getValue(Self); +end; + +function IConfigEntry.getIntValue(): Int64; +begin + Result := ConfigEntryVTable(vTable).getIntValue(Self); +end; + +function IConfigEntry.getBoolValue(): Boolean; +begin + Result := ConfigEntryVTable(vTable).getBoolValue(Self); +end; + +function IConfigEntry.getSubConfig(status: IStatus): IConfig; +begin + Result := ConfigEntryVTable(vTable).getSubConfig(Self, status); +// FbException.checkException(status); +end; + +function IConfig.find(status: IStatus; name: PAnsiChar): IConfigEntry; +begin + Result := ConfigVTable(vTable).find(Self, status, name); +// FbException.checkException(status); +end; + +function IConfig.findValue(status: IStatus; name: PAnsiChar; value: PAnsiChar): IConfigEntry; +begin + Result := ConfigVTable(vTable).findValue(Self, status, name, value); +// FbException.checkException(status); +end; + +function IConfig.findPos(status: IStatus; name: PAnsiChar; pos: Cardinal): IConfigEntry; +begin + Result := ConfigVTable(vTable).findPos(Self, status, name, pos); +// FbException.checkException(status); +end; + +function IFirebirdConf.getKey(name: PAnsiChar): Cardinal; +begin + Result := FirebirdConfVTable(vTable).getKey(Self, name); +end; + +function IFirebirdConf.asInteger(key: Cardinal): Int64; +begin + Result := FirebirdConfVTable(vTable).asInteger(Self, key); +end; + +function IFirebirdConf.asString(key: Cardinal): PAnsiChar; +begin + Result := FirebirdConfVTable(vTable).asString(Self, key); +end; + +function IFirebirdConf.asBoolean(key: Cardinal): Boolean; +begin + Result := FirebirdConfVTable(vTable).asBoolean(Self, key); +end; + +function IPluginConfig.getConfigFileName(): PAnsiChar; +begin + Result := PluginConfigVTable(vTable).getConfigFileName(Self); +end; + +function IPluginConfig.getDefaultConfig(status: IStatus): IConfig; +begin + Result := PluginConfigVTable(vTable).getDefaultConfig(Self, status); +// FbException.checkException(status); +end; + +function IPluginConfig.getFirebirdConf(status: IStatus): IFirebirdConf; +begin + Result := PluginConfigVTable(vTable).getFirebirdConf(Self, status); +// FbException.checkException(status); +end; + +procedure IPluginConfig.setReleaseDelay(status: IStatus; microSeconds: QWord); +begin + PluginConfigVTable(vTable).setReleaseDelay(Self, status, microSeconds); +// FbException.checkException(status); +end; + +function IPluginFactory.createPlugin(status: IStatus; factoryParameter: IPluginConfig): IPluginBase; +begin + Result := PluginFactoryVTable(vTable).createPlugin(Self, status, factoryParameter); +// FbException.checkException(status); +end; + +procedure IPluginModule.doClean(); +begin + PluginModuleVTable(vTable).doClean(Self); +end; + +procedure IPluginManager.registerPluginFactory(pluginType: Cardinal; defaultName: PAnsiChar; factory: IPluginFactory); +begin + PluginManagerVTable(vTable).registerPluginFactory(Self, pluginType, defaultName, factory); +end; + +procedure IPluginManager.registerModule(cleanup: IPluginModule); +begin + PluginManagerVTable(vTable).registerModule(Self, cleanup); +end; + +procedure IPluginManager.unregisterModule(cleanup: IPluginModule); +begin + PluginManagerVTable(vTable).unregisterModule(Self, cleanup); +end; + +function IPluginManager.getPlugins(status: IStatus; pluginType: Cardinal; namesList: PAnsiChar; firebirdConf: IFirebirdConf): IPluginSet; +begin + Result := PluginManagerVTable(vTable).getPlugins(Self, status, pluginType, namesList, firebirdConf); +// FbException.checkException(status); +end; + +function IPluginManager.getConfig(status: IStatus; filename: PAnsiChar): IConfig; +begin + Result := PluginManagerVTable(vTable).getConfig(Self, status, filename); +// FbException.checkException(status); +end; + +procedure IPluginManager.releasePlugin(plugin: IPluginBase); +begin + PluginManagerVTable(vTable).releasePlugin(Self, plugin); +end; + +procedure ICryptKey.setSymmetric(status: IStatus; type_: PAnsiChar; keyLength: Cardinal; key: Pointer); +begin + CryptKeyVTable(vTable).setSymmetric(Self, status, type_, keyLength, key); +// FbException.checkException(status); +end; + +procedure ICryptKey.setAsymmetric(status: IStatus; type_: PAnsiChar; encryptKeyLength: Cardinal; encryptKey: Pointer; decryptKeyLength: Cardinal; decryptKey: Pointer); +begin + CryptKeyVTable(vTable).setAsymmetric(Self, status, type_, encryptKeyLength, encryptKey, decryptKeyLength, decryptKey); +// FbException.checkException(status); +end; + +function ICryptKey.getEncryptKey(length: CardinalPtr): Pointer; +begin + Result := CryptKeyVTable(vTable).getEncryptKey(Self, length); +end; + +function ICryptKey.getDecryptKey(length: CardinalPtr): Pointer; +begin + Result := CryptKeyVTable(vTable).getDecryptKey(Self, length); +end; + +function IConfigManager.getDirectory(code: Cardinal): PAnsiChar; +begin + Result := ConfigManagerVTable(vTable).getDirectory(Self, code); +end; + +function IConfigManager.getFirebirdConf(): IFirebirdConf; +begin + Result := ConfigManagerVTable(vTable).getFirebirdConf(Self); +end; + +function IConfigManager.getDatabaseConf(dbName: PAnsiChar): IFirebirdConf; +begin + Result := ConfigManagerVTable(vTable).getDatabaseConf(Self, dbName); +end; + +function IConfigManager.getPluginConfig(configuredPlugin: PAnsiChar): IConfig; +begin + Result := ConfigManagerVTable(vTable).getPluginConfig(Self, configuredPlugin); +end; + +function IConfigManager.getInstallDirectory(): PAnsiChar; +begin + Result := ConfigManagerVTable(vTable).getInstallDirectory(Self); +end; + +function IConfigManager.getRootDirectory(): PAnsiChar; +begin + Result := ConfigManagerVTable(vTable).getRootDirectory(Self); +end; + +procedure IEventCallback.eventCallbackFunction(length: Cardinal; events: BytePtr); +begin + EventCallbackVTable(vTable).eventCallbackFunction(Self, length, events); +end; + +procedure IBlob.getInfo(status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); +begin + BlobVTable(vTable).getInfo(Self, status, itemsLength, items, bufferLength, buffer); +// FbException.checkException(status); +end; + +function IBlob.getSegment(status: IStatus; bufferLength: Cardinal; buffer: Pointer; segmentLength: CardinalPtr): Integer; +begin + Result := BlobVTable(vTable).getSegment(Self, status, bufferLength, buffer, segmentLength); +// FbException.checkException(status); +end; + +procedure IBlob.putSegment(status: IStatus; length: Cardinal; buffer: Pointer); +begin + BlobVTable(vTable).putSegment(Self, status, length, buffer); +// FbException.checkException(status); +end; + +procedure IBlob.cancel(status: IStatus); +begin + BlobVTable(vTable).cancel(Self, status); +// FbException.checkException(status); +end; + +procedure IBlob.close(status: IStatus); +begin + BlobVTable(vTable).close(Self, status); +// FbException.checkException(status); +end; + +function IBlob.seek(status: IStatus; mode: Integer; offset: Integer): Integer; +begin + Result := BlobVTable(vTable).seek(Self, status, mode, offset); +// FbException.checkException(status); +end; + +procedure ITransaction.getInfo(status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); +begin + TransactionVTable(vTable).getInfo(Self, status, itemsLength, items, bufferLength, buffer); +// FbException.checkException(status); +end; + +procedure ITransaction.prepare(status: IStatus; msgLength: Cardinal; message: BytePtr); +begin + TransactionVTable(vTable).prepare(Self, status, msgLength, message); +// FbException.checkException(status); +end; + +procedure ITransaction.commit(status: IStatus); +begin + TransactionVTable(vTable).commit(Self, status); +// FbException.checkException(status); +end; + +procedure ITransaction.commitRetaining(status: IStatus); +begin + TransactionVTable(vTable).commitRetaining(Self, status); +// FbException.checkException(status); +end; + +procedure ITransaction.rollback(status: IStatus); +begin + TransactionVTable(vTable).rollback(Self, status); +// FbException.checkException(status); +end; + +procedure ITransaction.rollbackRetaining(status: IStatus); +begin + TransactionVTable(vTable).rollbackRetaining(Self, status); +// FbException.checkException(status); +end; + +procedure ITransaction.disconnect(status: IStatus); +begin + TransactionVTable(vTable).disconnect(Self, status); +// FbException.checkException(status); +end; + +function ITransaction.join(status: IStatus; transaction: ITransaction): ITransaction; +begin + Result := TransactionVTable(vTable).join(Self, status, transaction); +// FbException.checkException(status); +end; + +function ITransaction.validate(status: IStatus; attachment: IAttachment): ITransaction; +begin + Result := TransactionVTable(vTable).validate(Self, status, attachment); +// FbException.checkException(status); +end; + +function ITransaction.enterDtc(status: IStatus): ITransaction; +begin + Result := TransactionVTable(vTable).enterDtc(Self, status); +// FbException.checkException(status); +end; + +function IMessageMetadata.getCount(status: IStatus): Cardinal; +begin + Result := MessageMetadataVTable(vTable).getCount(Self, status); +// FbException.checkException(status); +end; + +function IMessageMetadata.getField(status: IStatus; index: Cardinal): PAnsiChar; +begin + Result := MessageMetadataVTable(vTable).getField(Self, status, index); +// FbException.checkException(status); +end; + +function IMessageMetadata.getRelation(status: IStatus; index: Cardinal): PAnsiChar; +begin + Result := MessageMetadataVTable(vTable).getRelation(Self, status, index); +// FbException.checkException(status); +end; + +function IMessageMetadata.getOwner(status: IStatus; index: Cardinal): PAnsiChar; +begin + Result := MessageMetadataVTable(vTable).getOwner(Self, status, index); +// FbException.checkException(status); +end; + +function IMessageMetadata.getAlias(status: IStatus; index: Cardinal): PAnsiChar; +begin + Result := MessageMetadataVTable(vTable).getAlias(Self, status, index); +// FbException.checkException(status); +end; + +function IMessageMetadata.getType(status: IStatus; index: Cardinal): Cardinal; +begin + Result := MessageMetadataVTable(vTable).getType(Self, status, index); +// FbException.checkException(status); +end; + +function IMessageMetadata.isNullable(status: IStatus; index: Cardinal): Boolean; +begin + Result := MessageMetadataVTable(vTable).isNullable(Self, status, index); +// FbException.checkException(status); +end; + +function IMessageMetadata.getSubType(status: IStatus; index: Cardinal): Integer; +begin + Result := MessageMetadataVTable(vTable).getSubType(Self, status, index); +// FbException.checkException(status); +end; + +function IMessageMetadata.getLength(status: IStatus; index: Cardinal): Cardinal; +begin + Result := MessageMetadataVTable(vTable).getLength(Self, status, index); +// FbException.checkException(status); +end; + +function IMessageMetadata.getScale(status: IStatus; index: Cardinal): Integer; +begin + Result := MessageMetadataVTable(vTable).getScale(Self, status, index); +// FbException.checkException(status); +end; + +function IMessageMetadata.getCharSet(status: IStatus; index: Cardinal): Cardinal; +begin + Result := MessageMetadataVTable(vTable).getCharSet(Self, status, index); +// FbException.checkException(status); +end; + +function IMessageMetadata.getOffset(status: IStatus; index: Cardinal): Cardinal; +begin + Result := MessageMetadataVTable(vTable).getOffset(Self, status, index); +// FbException.checkException(status); +end; + +function IMessageMetadata.getNullOffset(status: IStatus; index: Cardinal): Cardinal; +begin + Result := MessageMetadataVTable(vTable).getNullOffset(Self, status, index); +// FbException.checkException(status); +end; + +function IMessageMetadata.getBuilder(status: IStatus): IMetadataBuilder; +begin + Result := MessageMetadataVTable(vTable).getBuilder(Self, status); +// FbException.checkException(status); +end; + +function IMessageMetadata.getMessageLength(status: IStatus): Cardinal; +begin + Result := MessageMetadataVTable(vTable).getMessageLength(Self, status); +// FbException.checkException(status); +end; + +procedure IMetadataBuilder.setType(status: IStatus; index: Cardinal; type_: Cardinal); +begin + MetadataBuilderVTable(vTable).setType(Self, status, index, type_); +// FbException.checkException(status); +end; + +procedure IMetadataBuilder.setSubType(status: IStatus; index: Cardinal; subType: Integer); +begin + MetadataBuilderVTable(vTable).setSubType(Self, status, index, subType); +// FbException.checkException(status); +end; + +procedure IMetadataBuilder.setLength(status: IStatus; index: Cardinal; length: Cardinal); +begin + MetadataBuilderVTable(vTable).setLength(Self, status, index, length); +// FbException.checkException(status); +end; + +procedure IMetadataBuilder.setCharSet(status: IStatus; index: Cardinal; charSet: Cardinal); +begin + MetadataBuilderVTable(vTable).setCharSet(Self, status, index, charSet); +// FbException.checkException(status); +end; + +procedure IMetadataBuilder.setScale(status: IStatus; index: Cardinal; scale: Cardinal); +begin + MetadataBuilderVTable(vTable).setScale(Self, status, index, scale); +// FbException.checkException(status); +end; + +procedure IMetadataBuilder.truncate(status: IStatus; count: Cardinal); +begin + MetadataBuilderVTable(vTable).truncate(Self, status, count); +// FbException.checkException(status); +end; + +procedure IMetadataBuilder.moveNameToIndex(status: IStatus; name: PAnsiChar; index: Cardinal); +begin + MetadataBuilderVTable(vTable).moveNameToIndex(Self, status, name, index); +// FbException.checkException(status); +end; + +procedure IMetadataBuilder.remove(status: IStatus; index: Cardinal); +begin + MetadataBuilderVTable(vTable).remove(Self, status, index); +// FbException.checkException(status); +end; + +function IMetadataBuilder.addField(status: IStatus): Cardinal; +begin + Result := MetadataBuilderVTable(vTable).addField(Self, status); +// FbException.checkException(status); +end; + +function IMetadataBuilder.getMetadata(status: IStatus): IMessageMetadata; +begin + Result := MetadataBuilderVTable(vTable).getMetadata(Self, status); +// FbException.checkException(status); +end; + +function IResultSet.fetchNext(status: IStatus; message: Pointer): Integer; +begin + Result := ResultSetVTable(vTable).fetchNext(Self, status, message); +// FbException.checkException(status); +end; + +function IResultSet.fetchPrior(status: IStatus; message: Pointer): Integer; +begin + Result := ResultSetVTable(vTable).fetchPrior(Self, status, message); +// FbException.checkException(status); +end; + +function IResultSet.fetchFirst(status: IStatus; message: Pointer): Integer; +begin + Result := ResultSetVTable(vTable).fetchFirst(Self, status, message); +// FbException.checkException(status); +end; + +function IResultSet.fetchLast(status: IStatus; message: Pointer): Integer; +begin + Result := ResultSetVTable(vTable).fetchLast(Self, status, message); +// FbException.checkException(status); +end; + +function IResultSet.fetchAbsolute(status: IStatus; position: Integer; message: Pointer): Integer; +begin + Result := ResultSetVTable(vTable).fetchAbsolute(Self, status, position, message); +// FbException.checkException(status); +end; + +function IResultSet.fetchRelative(status: IStatus; offset: Integer; message: Pointer): Integer; +begin + Result := ResultSetVTable(vTable).fetchRelative(Self, status, offset, message); +// FbException.checkException(status); +end; + +function IResultSet.isEof(status: IStatus): Boolean; +begin + Result := ResultSetVTable(vTable).isEof(Self, status); +// FbException.checkException(status); +end; + +function IResultSet.isBof(status: IStatus): Boolean; +begin + Result := ResultSetVTable(vTable).isBof(Self, status); +// FbException.checkException(status); +end; + +function IResultSet.getMetadata(status: IStatus): IMessageMetadata; +begin + Result := ResultSetVTable(vTable).getMetadata(Self, status); +// FbException.checkException(status); +end; + +procedure IResultSet.close(status: IStatus); +begin + ResultSetVTable(vTable).close(Self, status); +// FbException.checkException(status); +end; + +procedure IResultSet.setDelayedOutputFormat(status: IStatus; format: IMessageMetadata); +begin + ResultSetVTable(vTable).setDelayedOutputFormat(Self, status, format); +// FbException.checkException(status); +end; + +procedure IStatement.getInfo(status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); +begin + StatementVTable(vTable).getInfo(Self, status, itemsLength, items, bufferLength, buffer); +// FbException.checkException(status); +end; + +function IStatement.getType(status: IStatus): Cardinal; +begin + Result := StatementVTable(vTable).getType(Self, status); +// FbException.checkException(status); +end; + +function IStatement.getPlan(status: IStatus; detailed: Boolean): PAnsiChar; +begin + Result := StatementVTable(vTable).getPlan(Self, status, detailed); +// FbException.checkException(status); +end; + +function IStatement.getAffectedRecords(status: IStatus): QWord; +begin + Result := StatementVTable(vTable).getAffectedRecords(Self, status); +// FbException.checkException(status); +end; + +function IStatement.getInputMetadata(status: IStatus): IMessageMetadata; +begin + Result := StatementVTable(vTable).getInputMetadata(Self, status); +// FbException.checkException(status); +end; + +function IStatement.getOutputMetadata(status: IStatus): IMessageMetadata; +begin + Result := StatementVTable(vTable).getOutputMetadata(Self, status); +// FbException.checkException(status); +end; + +function IStatement.execute(status: IStatus; transaction: ITransaction; inMetadata: IMessageMetadata; inBuffer: Pointer; outMetadata: IMessageMetadata; outBuffer: Pointer): ITransaction; +begin + Result := StatementVTable(vTable).execute(Self, status, transaction, inMetadata, inBuffer, outMetadata, outBuffer); +// FbException.checkException(status); +end; + +function IStatement.openCursor(status: IStatus; transaction: ITransaction; inMetadata: IMessageMetadata; inBuffer: Pointer; outMetadata: IMessageMetadata; flags: Cardinal): IResultSet; +begin + Result := StatementVTable(vTable).openCursor(Self, status, transaction, inMetadata, inBuffer, outMetadata, flags); +// FbException.checkException(status); +end; + +procedure IStatement.setCursorName(status: IStatus; name: PAnsiChar); +begin + StatementVTable(vTable).setCursorName(Self, status, name); +// FbException.checkException(status); +end; + +procedure IStatement.free(status: IStatus); +begin + StatementVTable(vTable).free(Self, status); +// FbException.checkException(status); +end; + +function IStatement.getFlags(status: IStatus): Cardinal; +begin + Result := StatementVTable(vTable).getFlags(Self, status); +// FbException.checkException(status); +end; + +procedure IRequest.receive(status: IStatus; level: Integer; msgType: Cardinal; length: Cardinal; message: BytePtr); +begin + RequestVTable(vTable).receive(Self, status, level, msgType, length, message); +// FbException.checkException(status); +end; + +procedure IRequest.send(status: IStatus; level: Integer; msgType: Cardinal; length: Cardinal; message: BytePtr); +begin + RequestVTable(vTable).send(Self, status, level, msgType, length, message); +// FbException.checkException(status); +end; + +procedure IRequest.getInfo(status: IStatus; level: Integer; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); +begin + RequestVTable(vTable).getInfo(Self, status, level, itemsLength, items, bufferLength, buffer); +// FbException.checkException(status); +end; + +procedure IRequest.start(status: IStatus; tra: ITransaction; level: Integer); +begin + RequestVTable(vTable).start(Self, status, tra, level); +// FbException.checkException(status); +end; + +procedure IRequest.startAndSend(status: IStatus; tra: ITransaction; level: Integer; msgType: Cardinal; length: Cardinal; message: BytePtr); +begin + RequestVTable(vTable).startAndSend(Self, status, tra, level, msgType, length, message); +// FbException.checkException(status); +end; + +procedure IRequest.unwind(status: IStatus; level: Integer); +begin + RequestVTable(vTable).unwind(Self, status, level); +// FbException.checkException(status); +end; + +procedure IRequest.free(status: IStatus); +begin + RequestVTable(vTable).free(Self, status); +// FbException.checkException(status); +end; + +procedure IEvents.cancel(status: IStatus); +begin + EventsVTable(vTable).cancel(Self, status); +// FbException.checkException(status); +end; + +procedure IAttachment.getInfo(status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); +begin + AttachmentVTable(vTable).getInfo(Self, status, itemsLength, items, bufferLength, buffer); +// FbException.checkException(status); +end; + +function IAttachment.startTransaction(status: IStatus; tpbLength: Cardinal; tpb: BytePtr): ITransaction; +begin + Result := AttachmentVTable(vTable).startTransaction(Self, status, tpbLength, tpb); +// FbException.checkException(status); +end; + +function IAttachment.reconnectTransaction(status: IStatus; length: Cardinal; id: BytePtr): ITransaction; +begin + Result := AttachmentVTable(vTable).reconnectTransaction(Self, status, length, id); +// FbException.checkException(status); +end; + +function IAttachment.compileRequest(status: IStatus; blrLength: Cardinal; blr: BytePtr): IRequest; +begin + Result := AttachmentVTable(vTable).compileRequest(Self, status, blrLength, blr); +// FbException.checkException(status); +end; + +procedure IAttachment.transactRequest(status: IStatus; transaction: ITransaction; blrLength: Cardinal; blr: BytePtr; inMsgLength: Cardinal; inMsg: BytePtr; outMsgLength: Cardinal; outMsg: BytePtr); +begin + AttachmentVTable(vTable).transactRequest(Self, status, transaction, blrLength, blr, inMsgLength, inMsg, outMsgLength, outMsg); +// FbException.checkException(status); +end; + +function IAttachment.createBlob(status: IStatus; transaction: ITransaction; id: ISC_QUADPtr; bpbLength: Cardinal; bpb: BytePtr): IBlob; +begin + Result := AttachmentVTable(vTable).createBlob(Self, status, transaction, id, bpbLength, bpb); +// FbException.checkException(status); +end; + +function IAttachment.openBlob(status: IStatus; transaction: ITransaction; id: ISC_QUADPtr; bpbLength: Cardinal; bpb: BytePtr): IBlob; +begin + Result := AttachmentVTable(vTable).openBlob(Self, status, transaction, id, bpbLength, bpb); +// FbException.checkException(status); +end; + +function IAttachment.getSlice(status: IStatus; transaction: ITransaction; id: ISC_QUADPtr; sdlLength: Cardinal; sdl: BytePtr; paramLength: Cardinal; param: BytePtr; sliceLength: Integer; slice: BytePtr): Integer; +begin + Result := AttachmentVTable(vTable).getSlice(Self, status, transaction, id, sdlLength, sdl, paramLength, param, sliceLength, slice); +// FbException.checkException(status); +end; + +procedure IAttachment.putSlice(status: IStatus; transaction: ITransaction; id: ISC_QUADPtr; sdlLength: Cardinal; sdl: BytePtr; paramLength: Cardinal; param: BytePtr; sliceLength: Integer; slice: BytePtr); +begin + AttachmentVTable(vTable).putSlice(Self, status, transaction, id, sdlLength, sdl, paramLength, param, sliceLength, slice); +// FbException.checkException(status); +end; + +procedure IAttachment.executeDyn(status: IStatus; transaction: ITransaction; length: Cardinal; dyn: BytePtr); +begin + AttachmentVTable(vTable).executeDyn(Self, status, transaction, length, dyn); +// FbException.checkException(status); +end; + +function IAttachment.prepare(status: IStatus; tra: ITransaction; stmtLength: Cardinal; sqlStmt: PAnsiChar; dialect: Cardinal; flags: Cardinal): IStatement; +begin + Result := AttachmentVTable(vTable).prepare(Self, status, tra, stmtLength, sqlStmt, dialect, flags); +// FbException.checkException(status); +end; + +function IAttachment.execute(status: IStatus; transaction: ITransaction; stmtLength: Cardinal; sqlStmt: PAnsiChar; dialect: Cardinal; inMetadata: IMessageMetadata; inBuffer: Pointer; outMetadata: IMessageMetadata; outBuffer: Pointer): ITransaction; +begin + Result := AttachmentVTable(vTable).execute(Self, status, transaction, stmtLength, sqlStmt, dialect, inMetadata, inBuffer, outMetadata, outBuffer); +// FbException.checkException(status); +end; + +function IAttachment.openCursor(status: IStatus; transaction: ITransaction; stmtLength: Cardinal; sqlStmt: PAnsiChar; dialect: Cardinal; inMetadata: IMessageMetadata; inBuffer: Pointer; outMetadata: IMessageMetadata; cursorName: PAnsiChar; cursorFlags: Cardinal): IResultSet; +begin + Result := AttachmentVTable(vTable).openCursor(Self, status, transaction, stmtLength, sqlStmt, dialect, inMetadata, inBuffer, outMetadata, cursorName, cursorFlags); +// FbException.checkException(status); +end; + +function IAttachment.queEvents(status: IStatus; callback: IEventCallback; length: Cardinal; events: BytePtr): IEvents; +begin + Result := AttachmentVTable(vTable).queEvents(Self, status, callback, length, events); +// FbException.checkException(status); +end; + +procedure IAttachment.cancelOperation(status: IStatus; option: Integer); +begin + AttachmentVTable(vTable).cancelOperation(Self, status, option); +// FbException.checkException(status); +end; + +procedure IAttachment.ping(status: IStatus); +begin + AttachmentVTable(vTable).ping(Self, status); +// FbException.checkException(status); +end; + +procedure IAttachment.detach(status: IStatus); +begin + AttachmentVTable(vTable).detach(Self, status); +// FbException.checkException(status); +end; + +procedure IAttachment.dropDatabase(status: IStatus); +begin + AttachmentVTable(vTable).dropDatabase(Self, status); +// FbException.checkException(status); +end; + +procedure IService.detach(status: IStatus); +begin + ServiceVTable(vTable).detach(Self, status); +// FbException.checkException(status); +end; + +procedure IService.query(status: IStatus; sendLength: Cardinal; sendItems: BytePtr; receiveLength: Cardinal; receiveItems: BytePtr; bufferLength: Cardinal; buffer: BytePtr); +begin + ServiceVTable(vTable).query(Self, status, sendLength, sendItems, receiveLength, receiveItems, bufferLength, buffer); +// FbException.checkException(status); +end; + +procedure IService.start(status: IStatus; spbLength: Cardinal; spb: BytePtr); +begin + ServiceVTable(vTable).start(Self, status, spbLength, spb); +// FbException.checkException(status); +end; + +function IProvider.attachDatabase(status: IStatus; fileName: PAnsiChar; dpbLength: Cardinal; dpb: BytePtr): IAttachment; +begin + Result := ProviderVTable(vTable).attachDatabase(Self, status, fileName, dpbLength, dpb); +// FbException.checkException(status); +end; + +function IProvider.createDatabase(status: IStatus; fileName: PAnsiChar; dpbLength: Cardinal; dpb: BytePtr): IAttachment; +begin + Result := ProviderVTable(vTable).createDatabase(Self, status, fileName, dpbLength, dpb); +// FbException.checkException(status); +end; + +function IProvider.attachServiceManager(status: IStatus; service: PAnsiChar; spbLength: Cardinal; spb: BytePtr): IService; +begin + Result := ProviderVTable(vTable).attachServiceManager(Self, status, service, spbLength, spb); +// FbException.checkException(status); +end; + +procedure IProvider.shutdown(status: IStatus; timeout: Cardinal; reason: Integer); +begin + ProviderVTable(vTable).shutdown(Self, status, timeout, reason); +// FbException.checkException(status); +end; + +procedure IProvider.setDbCryptCallback(status: IStatus; cryptCallback: ICryptKeyCallback); +begin + ProviderVTable(vTable).setDbCryptCallback(Self, status, cryptCallback); +// FbException.checkException(status); +end; + +procedure IDtcStart.addAttachment(status: IStatus; att: IAttachment); +begin + DtcStartVTable(vTable).addAttachment(Self, status, att); +// FbException.checkException(status); +end; + +procedure IDtcStart.addWithTpb(status: IStatus; att: IAttachment; length: Cardinal; tpb: BytePtr); +begin + DtcStartVTable(vTable).addWithTpb(Self, status, att, length, tpb); +// FbException.checkException(status); +end; + +function IDtcStart.start(status: IStatus): ITransaction; +begin + Result := DtcStartVTable(vTable).start(Self, status); +// FbException.checkException(status); +end; + +function IDtc.join(status: IStatus; one: ITransaction; two: ITransaction): ITransaction; +begin + Result := DtcVTable(vTable).join(Self, status, one, two); +// FbException.checkException(status); +end; + +function IDtc.startBuilder(status: IStatus): IDtcStart; +begin + Result := DtcVTable(vTable).startBuilder(Self, status); +// FbException.checkException(status); +end; + +procedure IWriter.reset(); +begin + WriterVTable(vTable).reset(Self); +end; + +procedure IWriter.add(status: IStatus; name: PAnsiChar); +begin + WriterVTable(vTable).add(Self, status, name); +// FbException.checkException(status); +end; + +procedure IWriter.setType(status: IStatus; value: PAnsiChar); +begin + WriterVTable(vTable).setType(Self, status, value); +// FbException.checkException(status); +end; + +procedure IWriter.setDb(status: IStatus; value: PAnsiChar); +begin + WriterVTable(vTable).setDb(Self, status, value); +// FbException.checkException(status); +end; + +function IServerBlock.getLogin(): PAnsiChar; +begin + Result := ServerBlockVTable(vTable).getLogin(Self); +end; + +function IServerBlock.getData(length: CardinalPtr): BytePtr; +begin + Result := ServerBlockVTable(vTable).getData(Self, length); +end; + +procedure IServerBlock.putData(status: IStatus; length: Cardinal; data: Pointer); +begin + ServerBlockVTable(vTable).putData(Self, status, length, data); +// FbException.checkException(status); +end; + +function IServerBlock.newKey(status: IStatus): ICryptKey; +begin + Result := ServerBlockVTable(vTable).newKey(Self, status); +// FbException.checkException(status); +end; + +function IClientBlock.getLogin(): PAnsiChar; +begin + Result := ClientBlockVTable(vTable).getLogin(Self); +end; + +function IClientBlock.getPassword(): PAnsiChar; +begin + Result := ClientBlockVTable(vTable).getPassword(Self); +end; + +function IClientBlock.getData(length: CardinalPtr): BytePtr; +begin + Result := ClientBlockVTable(vTable).getData(Self, length); +end; + +procedure IClientBlock.putData(status: IStatus; length: Cardinal; data: Pointer); +begin + ClientBlockVTable(vTable).putData(Self, status, length, data); +// FbException.checkException(status); +end; + +function IClientBlock.newKey(status: IStatus): ICryptKey; +begin + Result := ClientBlockVTable(vTable).newKey(Self, status); +// FbException.checkException(status); +end; + +function IServer.authenticate(status: IStatus; sBlock: IServerBlock; writerInterface: IWriter): Integer; +begin + Result := ServerVTable(vTable).authenticate(Self, status, sBlock, writerInterface); +// FbException.checkException(status); +end; + +function IClient.authenticate(status: IStatus; cBlock: IClientBlock): Integer; +begin + Result := ClientVTable(vTable).authenticate(Self, status, cBlock); +// FbException.checkException(status); +end; + +function IUserField.entered(): Integer; +begin + Result := UserFieldVTable(vTable).entered(Self); +end; + +function IUserField.specified(): Integer; +begin + Result := UserFieldVTable(vTable).specified(Self); +end; + +procedure IUserField.setEntered(status: IStatus; newValue: Integer); +begin + UserFieldVTable(vTable).setEntered(Self, status, newValue); +// FbException.checkException(status); +end; + +function ICharUserField.get(): PAnsiChar; +begin + Result := CharUserFieldVTable(vTable).get(Self); +end; + +procedure ICharUserField.set_(status: IStatus; newValue: PAnsiChar); +begin + CharUserFieldVTable(vTable).set_(Self, status, newValue); +// FbException.checkException(status); +end; + +function IIntUserField.get(): Integer; +begin + Result := IntUserFieldVTable(vTable).get(Self); +end; + +procedure IIntUserField.set_(status: IStatus; newValue: Integer); +begin + IntUserFieldVTable(vTable).set_(Self, status, newValue); +// FbException.checkException(status); +end; + +function IUser.operation(): Cardinal; +begin + Result := UserVTable(vTable).operation(Self); +end; + +function IUser.userName(): ICharUserField; +begin + Result := UserVTable(vTable).userName(Self); +end; + +function IUser.password(): ICharUserField; +begin + Result := UserVTable(vTable).password(Self); +end; + +function IUser.firstName(): ICharUserField; +begin + Result := UserVTable(vTable).firstName(Self); +end; + +function IUser.lastName(): ICharUserField; +begin + Result := UserVTable(vTable).lastName(Self); +end; + +function IUser.middleName(): ICharUserField; +begin + Result := UserVTable(vTable).middleName(Self); +end; + +function IUser.comment(): ICharUserField; +begin + Result := UserVTable(vTable).comment(Self); +end; + +function IUser.attributes(): ICharUserField; +begin + Result := UserVTable(vTable).attributes(Self); +end; + +function IUser.active(): IIntUserField; +begin + Result := UserVTable(vTable).active(Self); +end; + +function IUser.admin(): IIntUserField; +begin + Result := UserVTable(vTable).admin(Self); +end; + +procedure IUser.clear(status: IStatus); +begin + UserVTable(vTable).clear(Self, status); +// FbException.checkException(status); +end; + +procedure IListUsers.list(status: IStatus; user: IUser); +begin + ListUsersVTable(vTable).list(Self, status, user); +// FbException.checkException(status); +end; + +function ILogonInfo.name(): PAnsiChar; +begin + Result := LogonInfoVTable(vTable).name(Self); +end; + +function ILogonInfo.role(): PAnsiChar; +begin + Result := LogonInfoVTable(vTable).role(Self); +end; + +function ILogonInfo.networkProtocol(): PAnsiChar; +begin + Result := LogonInfoVTable(vTable).networkProtocol(Self); +end; + +function ILogonInfo.remoteAddress(): PAnsiChar; +begin + Result := LogonInfoVTable(vTable).remoteAddress(Self); +end; + +function ILogonInfo.authBlock(length: CardinalPtr): BytePtr; +begin + Result := LogonInfoVTable(vTable).authBlock(Self, length); +end; + +procedure IManagement.start(status: IStatus; logonInfo: ILogonInfo); +begin + ManagementVTable(vTable).start(Self, status, logonInfo); +// FbException.checkException(status); +end; + +function IManagement.execute(status: IStatus; user: IUser; callback: IListUsers): Integer; +begin + Result := ManagementVTable(vTable).execute(Self, status, user, callback); +// FbException.checkException(status); +end; + +procedure IManagement.commit(status: IStatus); +begin + ManagementVTable(vTable).commit(Self, status); +// FbException.checkException(status); +end; + +procedure IManagement.rollback(status: IStatus); +begin + ManagementVTable(vTable).rollback(Self, status); +// FbException.checkException(status); +end; + +function IWireCryptPlugin.getKnownTypes(status: IStatus): PAnsiChar; +begin + Result := WireCryptPluginVTable(vTable).getKnownTypes(Self, status); +// FbException.checkException(status); +end; + +procedure IWireCryptPlugin.setKey(status: IStatus; key: ICryptKey); +begin + WireCryptPluginVTable(vTable).setKey(Self, status, key); +// FbException.checkException(status); +end; + +procedure IWireCryptPlugin.encrypt(status: IStatus; length: Cardinal; from: Pointer; to_: Pointer); +begin + WireCryptPluginVTable(vTable).encrypt(Self, status, length, from, to_); +// FbException.checkException(status); +end; + +procedure IWireCryptPlugin.decrypt(status: IStatus; length: Cardinal; from: Pointer; to_: Pointer); +begin + WireCryptPluginVTable(vTable).decrypt(Self, status, length, from, to_); +// FbException.checkException(status); +end; + +function ICryptKeyCallback.callback(dataLength: Cardinal; data: Pointer; bufferLength: Cardinal; buffer: Pointer): Cardinal; +begin + Result := CryptKeyCallbackVTable(vTable).callback(Self, dataLength, data, bufferLength, buffer); +end; + +function IKeyHolderPlugin.keyCallback(status: IStatus; callback: ICryptKeyCallback): Integer; +begin + Result := KeyHolderPluginVTable(vTable).keyCallback(Self, status, callback); +// FbException.checkException(status); +end; + +function IKeyHolderPlugin.keyHandle(status: IStatus; keyName: PAnsiChar): ICryptKeyCallback; +begin + Result := KeyHolderPluginVTable(vTable).keyHandle(Self, status, keyName); +// FbException.checkException(status); +end; + +procedure IDbCryptPlugin.setKey(status: IStatus; length: Cardinal; sources: IKeyHolderPluginPtr; keyName: PAnsiChar); +begin + DbCryptPluginVTable(vTable).setKey(Self, status, length, sources, keyName); +// FbException.checkException(status); +end; + +procedure IDbCryptPlugin.encrypt(status: IStatus; length: Cardinal; from: Pointer; to_: Pointer); +begin + DbCryptPluginVTable(vTable).encrypt(Self, status, length, from, to_); +// FbException.checkException(status); +end; + +procedure IDbCryptPlugin.decrypt(status: IStatus; length: Cardinal; from: Pointer; to_: Pointer); +begin + DbCryptPluginVTable(vTable).decrypt(Self, status, length, from, to_); +// FbException.checkException(status); +end; + +function IExternalContext.getMaster(): IMaster; +begin + Result := ExternalContextVTable(vTable).getMaster(Self); +end; + +function IExternalContext.getEngine(status: IStatus): IExternalEngine; +begin + Result := ExternalContextVTable(vTable).getEngine(Self, status); +// FbException.checkException(status); +end; + +function IExternalContext.getAttachment(status: IStatus): IAttachment; +begin + Result := ExternalContextVTable(vTable).getAttachment(Self, status); +// FbException.checkException(status); +end; + +function IExternalContext.getTransaction(status: IStatus): ITransaction; +begin + Result := ExternalContextVTable(vTable).getTransaction(Self, status); +// FbException.checkException(status); +end; + +function IExternalContext.getUserName(): PAnsiChar; +begin + Result := ExternalContextVTable(vTable).getUserName(Self); +end; + +function IExternalContext.getDatabaseName(): PAnsiChar; +begin + Result := ExternalContextVTable(vTable).getDatabaseName(Self); +end; + +function IExternalContext.getClientCharSet(): PAnsiChar; +begin + Result := ExternalContextVTable(vTable).getClientCharSet(Self); +end; + +function IExternalContext.obtainInfoCode(): Integer; +begin + Result := ExternalContextVTable(vTable).obtainInfoCode(Self); +end; + +function IExternalContext.getInfo(code: Integer): Pointer; +begin + Result := ExternalContextVTable(vTable).getInfo(Self, code); +end; + +function IExternalContext.setInfo(code: Integer; value: Pointer): Pointer; +begin + Result := ExternalContextVTable(vTable).setInfo(Self, code, value); +end; + +function IExternalResultSet.fetch(status: IStatus): Boolean; +begin + Result := ExternalResultSetVTable(vTable).fetch(Self, status); +// FbException.checkException(status); +end; + +procedure IExternalFunction.getCharSet(status: IStatus; context: IExternalContext; name: PAnsiChar; nameSize: Cardinal); +begin + ExternalFunctionVTable(vTable).getCharSet(Self, status, context, name, nameSize); +// FbException.checkException(status); +end; + +procedure IExternalFunction.execute(status: IStatus; context: IExternalContext; inMsg: Pointer; outMsg: Pointer); +begin + ExternalFunctionVTable(vTable).execute(Self, status, context, inMsg, outMsg); +// FbException.checkException(status); +end; + +procedure IExternalProcedure.getCharSet(status: IStatus; context: IExternalContext; name: PAnsiChar; nameSize: Cardinal); +begin + ExternalProcedureVTable(vTable).getCharSet(Self, status, context, name, nameSize); +// FbException.checkException(status); +end; + +function IExternalProcedure.open(status: IStatus; context: IExternalContext; inMsg: Pointer; outMsg: Pointer): IExternalResultSet; +begin + Result := ExternalProcedureVTable(vTable).open(Self, status, context, inMsg, outMsg); +// FbException.checkException(status); +end; + +procedure IExternalTrigger.getCharSet(status: IStatus; context: IExternalContext; name: PAnsiChar; nameSize: Cardinal); +begin + ExternalTriggerVTable(vTable).getCharSet(Self, status, context, name, nameSize); +// FbException.checkException(status); +end; + +procedure IExternalTrigger.execute(status: IStatus; context: IExternalContext; action: Cardinal; oldMsg: Pointer; newMsg: Pointer); +begin + ExternalTriggerVTable(vTable).execute(Self, status, context, action, oldMsg, newMsg); +// FbException.checkException(status); +end; + +function IRoutineMetadata.getPackage(status: IStatus): PAnsiChar; +begin + Result := RoutineMetadataVTable(vTable).getPackage(Self, status); +// FbException.checkException(status); +end; + +function IRoutineMetadata.getName(status: IStatus): PAnsiChar; +begin + Result := RoutineMetadataVTable(vTable).getName(Self, status); +// FbException.checkException(status); +end; + +function IRoutineMetadata.getEntryPoint(status: IStatus): PAnsiChar; +begin + Result := RoutineMetadataVTable(vTable).getEntryPoint(Self, status); +// FbException.checkException(status); +end; + +function IRoutineMetadata.getBody(status: IStatus): PAnsiChar; +begin + Result := RoutineMetadataVTable(vTable).getBody(Self, status); +// FbException.checkException(status); +end; + +function IRoutineMetadata.getInputMetadata(status: IStatus): IMessageMetadata; +begin + Result := RoutineMetadataVTable(vTable).getInputMetadata(Self, status); +// FbException.checkException(status); +end; + +function IRoutineMetadata.getOutputMetadata(status: IStatus): IMessageMetadata; +begin + Result := RoutineMetadataVTable(vTable).getOutputMetadata(Self, status); +// FbException.checkException(status); +end; + +function IRoutineMetadata.getTriggerMetadata(status: IStatus): IMessageMetadata; +begin + Result := RoutineMetadataVTable(vTable).getTriggerMetadata(Self, status); +// FbException.checkException(status); +end; + +function IRoutineMetadata.getTriggerTable(status: IStatus): PAnsiChar; +begin + Result := RoutineMetadataVTable(vTable).getTriggerTable(Self, status); +// FbException.checkException(status); +end; + +function IRoutineMetadata.getTriggerType(status: IStatus): Cardinal; +begin + Result := RoutineMetadataVTable(vTable).getTriggerType(Self, status); +// FbException.checkException(status); +end; + +procedure IExternalEngine.open(status: IStatus; context: IExternalContext; charSet: PAnsiChar; charSetSize: Cardinal); +begin + ExternalEngineVTable(vTable).open(Self, status, context, charSet, charSetSize); +// FbException.checkException(status); +end; + +procedure IExternalEngine.openAttachment(status: IStatus; context: IExternalContext); +begin + ExternalEngineVTable(vTable).openAttachment(Self, status, context); +// FbException.checkException(status); +end; + +procedure IExternalEngine.closeAttachment(status: IStatus; context: IExternalContext); +begin + ExternalEngineVTable(vTable).closeAttachment(Self, status, context); +// FbException.checkException(status); +end; + +function IExternalEngine.makeFunction(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder): IExternalFunction; +begin + Result := ExternalEngineVTable(vTable).makeFunction(Self, status, context, metadata, inBuilder, outBuilder); +// FbException.checkException(status); +end; + +function IExternalEngine.makeProcedure(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder): IExternalProcedure; +begin + Result := ExternalEngineVTable(vTable).makeProcedure(Self, status, context, metadata, inBuilder, outBuilder); +// FbException.checkException(status); +end; + +function IExternalEngine.makeTrigger(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; fieldsBuilder: IMetadataBuilder): IExternalTrigger; +begin + Result := ExternalEngineVTable(vTable).makeTrigger(Self, status, context, metadata, fieldsBuilder); +// FbException.checkException(status); +end; + +procedure ITimer.handler(); +begin + TimerVTable(vTable).handler(Self); +end; + +procedure ITimerControl.start(status: IStatus; timer: ITimer; microSeconds: QWord); +begin + TimerControlVTable(vTable).start(Self, status, timer, microSeconds); +// FbException.checkException(status); +end; + +procedure ITimerControl.stop(status: IStatus; timer: ITimer); +begin + TimerControlVTable(vTable).stop(Self, status, timer); +// FbException.checkException(status); +end; + +procedure IVersionCallback.callback(status: IStatus; text: PAnsiChar); +begin + VersionCallbackVTable(vTable).callback(Self, status, text); +// FbException.checkException(status); +end; + +procedure IUtil.getFbVersion(status: IStatus; att: IAttachment; callback: IVersionCallback); +begin + UtilVTable(vTable).getFbVersion(Self, status, att, callback); +// FbException.checkException(status); +end; + +procedure IUtil.loadBlob(status: IStatus; blobId: ISC_QUADPtr; att: IAttachment; tra: ITransaction; file_: PAnsiChar; txt: Boolean); +begin + UtilVTable(vTable).loadBlob(Self, status, blobId, att, tra, file_, txt); +// FbException.checkException(status); +end; + +procedure IUtil.dumpBlob(status: IStatus; blobId: ISC_QUADPtr; att: IAttachment; tra: ITransaction; file_: PAnsiChar; txt: Boolean); +begin + UtilVTable(vTable).dumpBlob(Self, status, blobId, att, tra, file_, txt); +// FbException.checkException(status); +end; + +procedure IUtil.getPerfCounters(status: IStatus; att: IAttachment; countersSet: PAnsiChar; counters: Int64Ptr); +begin + UtilVTable(vTable).getPerfCounters(Self, status, att, countersSet, counters); +// FbException.checkException(status); +end; + +function IUtil.executeCreateDatabase(status: IStatus; stmtLength: Cardinal; creatDBstatement: PAnsiChar; dialect: Cardinal; stmtIsCreateDb: BooleanPtr): IAttachment; +begin + Result := UtilVTable(vTable).executeCreateDatabase(Self, status, stmtLength, creatDBstatement, dialect, stmtIsCreateDb); +// FbException.checkException(status); +end; + +procedure IUtil.decodeDate(date: ISC_DATE; year: CardinalPtr; month: CardinalPtr; day: CardinalPtr); +begin + UtilVTable(vTable).decodeDate(Self, date, year, month, day); +end; + +procedure IUtil.decodeTime(time: ISC_TIME; hours: CardinalPtr; minutes: CardinalPtr; seconds: CardinalPtr; fractions: CardinalPtr); +begin + UtilVTable(vTable).decodeTime(Self, time, hours, minutes, seconds, fractions); +end; + +function IUtil.encodeDate(year: Cardinal; month: Cardinal; day: Cardinal): ISC_DATE; +begin + Result := UtilVTable(vTable).encodeDate(Self, year, month, day); +end; + +function IUtil.encodeTime(hours: Cardinal; minutes: Cardinal; seconds: Cardinal; fractions: Cardinal): ISC_TIME; +begin + Result := UtilVTable(vTable).encodeTime(Self, hours, minutes, seconds, fractions); +end; + +function IUtil.formatStatus(buffer: PAnsiChar; bufferSize: Cardinal; status: IStatus): Cardinal; +begin + Result := UtilVTable(vTable).formatStatus(Self, buffer, bufferSize, status); +end; + +function IUtil.getClientVersion(): Cardinal; +begin + Result := UtilVTable(vTable).getClientVersion(Self); +end; + +function IUtil.getXpbBuilder(status: IStatus; kind: Cardinal; buf: BytePtr; len: Cardinal): IXpbBuilder; +begin + Result := UtilVTable(vTable).getXpbBuilder(Self, status, kind, buf, len); +// FbException.checkException(status); +end; + +function IUtil.setOffsets(status: IStatus; metadata: IMessageMetadata; callback: IOffsetsCallback): Cardinal; +begin + Result := UtilVTable(vTable).setOffsets(Self, status, metadata, callback); +// FbException.checkException(status); +end; + +procedure IOffsetsCallback.setOffset(status: IStatus; index: Cardinal; offset: Cardinal; nullOffset: Cardinal); +begin + OffsetsCallbackVTable(vTable).setOffset(Self, status, index, offset, nullOffset); +// FbException.checkException(status); +end; + +procedure IXpbBuilder.clear(status: IStatus); +begin + XpbBuilderVTable(vTable).clear(Self, status); +// FbException.checkException(status); +end; + +procedure IXpbBuilder.removeCurrent(status: IStatus); +begin + XpbBuilderVTable(vTable).removeCurrent(Self, status); +// FbException.checkException(status); +end; + +procedure IXpbBuilder.insertInt(status: IStatus; tag: Byte; value: Integer); +begin + XpbBuilderVTable(vTable).insertInt(Self, status, tag, value); +// FbException.checkException(status); +end; + +procedure IXpbBuilder.insertBigInt(status: IStatus; tag: Byte; value: Int64); +begin + XpbBuilderVTable(vTable).insertBigInt(Self, status, tag, value); +// FbException.checkException(status); +end; + +procedure IXpbBuilder.insertBytes(status: IStatus; tag: Byte; bytes: Pointer; length: Cardinal); +begin + XpbBuilderVTable(vTable).insertBytes(Self, status, tag, bytes, length); +// FbException.checkException(status); +end; + +procedure IXpbBuilder.insertString(status: IStatus; tag: Byte; str: PAnsiChar); +begin + XpbBuilderVTable(vTable).insertString(Self, status, tag, str); +// FbException.checkException(status); +end; + +procedure IXpbBuilder.insertTag(status: IStatus; tag: Byte); +begin + XpbBuilderVTable(vTable).insertTag(Self, status, tag); +// FbException.checkException(status); +end; + +function IXpbBuilder.isEof(status: IStatus): Boolean; +begin + Result := XpbBuilderVTable(vTable).isEof(Self, status); +// FbException.checkException(status); +end; + +procedure IXpbBuilder.moveNext(status: IStatus); +begin + XpbBuilderVTable(vTable).moveNext(Self, status); +// FbException.checkException(status); +end; + +procedure IXpbBuilder.rewind(status: IStatus); +begin + XpbBuilderVTable(vTable).rewind(Self, status); +// FbException.checkException(status); +end; + +function IXpbBuilder.findFirst(status: IStatus; tag: Byte): Boolean; +begin + Result := XpbBuilderVTable(vTable).findFirst(Self, status, tag); +// FbException.checkException(status); +end; + +function IXpbBuilder.findNext(status: IStatus): Boolean; +begin + Result := XpbBuilderVTable(vTable).findNext(Self, status); +// FbException.checkException(status); +end; + +function IXpbBuilder.getTag(status: IStatus): Byte; +begin + Result := XpbBuilderVTable(vTable).getTag(Self, status); +// FbException.checkException(status); +end; + +function IXpbBuilder.getLength(status: IStatus): Cardinal; +begin + Result := XpbBuilderVTable(vTable).getLength(Self, status); +// FbException.checkException(status); +end; + +function IXpbBuilder.getInt(status: IStatus): Integer; +begin + Result := XpbBuilderVTable(vTable).getInt(Self, status); +// FbException.checkException(status); +end; + +function IXpbBuilder.getBigInt(status: IStatus): Int64; +begin + Result := XpbBuilderVTable(vTable).getBigInt(Self, status); +// FbException.checkException(status); +end; + +function IXpbBuilder.getString(status: IStatus): PAnsiChar; +begin + Result := XpbBuilderVTable(vTable).getString(Self, status); +// FbException.checkException(status); +end; + +function IXpbBuilder.getBytes(status: IStatus): BytePtr; +begin + Result := XpbBuilderVTable(vTable).getBytes(Self, status); +// FbException.checkException(status); +end; + +function IXpbBuilder.getBufferLength(status: IStatus): Cardinal; +begin + Result := XpbBuilderVTable(vTable).getBufferLength(Self, status); +// FbException.checkException(status); +end; + +function IXpbBuilder.getBuffer(status: IStatus): BytePtr; +begin + Result := XpbBuilderVTable(vTable).getBuffer(Self, status); +// FbException.checkException(status); +end; + +function ITraceConnection.getKind(): Cardinal; +begin + Result := TraceConnectionVTable(vTable).getKind(Self); +end; + +function ITraceConnection.getProcessID(): Integer; +begin + Result := TraceConnectionVTable(vTable).getProcessID(Self); +end; + +function ITraceConnection.getUserName(): PAnsiChar; +begin + Result := TraceConnectionVTable(vTable).getUserName(Self); +end; + +function ITraceConnection.getRoleName(): PAnsiChar; +begin + Result := TraceConnectionVTable(vTable).getRoleName(Self); +end; + +function ITraceConnection.getCharSet(): PAnsiChar; +begin + Result := TraceConnectionVTable(vTable).getCharSet(Self); +end; + +function ITraceConnection.getRemoteProtocol(): PAnsiChar; +begin + Result := TraceConnectionVTable(vTable).getRemoteProtocol(Self); +end; + +function ITraceConnection.getRemoteAddress(): PAnsiChar; +begin + Result := TraceConnectionVTable(vTable).getRemoteAddress(Self); +end; + +function ITraceConnection.getRemoteProcessID(): Integer; +begin + Result := TraceConnectionVTable(vTable).getRemoteProcessID(Self); +end; + +function ITraceConnection.getRemoteProcessName(): PAnsiChar; +begin + Result := TraceConnectionVTable(vTable).getRemoteProcessName(Self); +end; + +function ITraceDatabaseConnection.getConnectionID(): Int64; +begin + Result := TraceDatabaseConnectionVTable(vTable).getConnectionID(Self); +end; + +function ITraceDatabaseConnection.getDatabaseName(): PAnsiChar; +begin + Result := TraceDatabaseConnectionVTable(vTable).getDatabaseName(Self); +end; + +function ITraceTransaction.getTransactionID(): Int64; +begin + Result := TraceTransactionVTable(vTable).getTransactionID(Self); +end; + +function ITraceTransaction.getReadOnly(): Boolean; +begin + Result := TraceTransactionVTable(vTable).getReadOnly(Self); +end; + +function ITraceTransaction.getWait(): Integer; +begin + Result := TraceTransactionVTable(vTable).getWait(Self); +end; + +function ITraceTransaction.getIsolation(): Cardinal; +begin + Result := TraceTransactionVTable(vTable).getIsolation(Self); +end; + +function ITraceTransaction.getPerf(): PerformanceInfoPtr; +begin + Result := TraceTransactionVTable(vTable).getPerf(Self); +end; + +function ITraceParams.getCount(): Cardinal; +begin + Result := TraceParamsVTable(vTable).getCount(Self); +end; + +function ITraceParams.getParam(idx: Cardinal): dscPtr; +begin + Result := TraceParamsVTable(vTable).getParam(Self, idx); +end; + +function ITraceStatement.getStmtID(): Int64; +begin + Result := TraceStatementVTable(vTable).getStmtID(Self); +end; + +function ITraceStatement.getPerf(): PerformanceInfoPtr; +begin + Result := TraceStatementVTable(vTable).getPerf(Self); +end; + +function ITraceSQLStatement.getText(): PAnsiChar; +begin + Result := TraceSQLStatementVTable(vTable).getText(Self); +end; + +function ITraceSQLStatement.getPlan(): PAnsiChar; +begin + Result := TraceSQLStatementVTable(vTable).getPlan(Self); +end; + +function ITraceSQLStatement.getInputs(): ITraceParams; +begin + Result := TraceSQLStatementVTable(vTable).getInputs(Self); +end; + +function ITraceSQLStatement.getTextUTF8(): PAnsiChar; +begin + Result := TraceSQLStatementVTable(vTable).getTextUTF8(Self); +end; + +function ITraceSQLStatement.getExplainedPlan(): PAnsiChar; +begin + Result := TraceSQLStatementVTable(vTable).getExplainedPlan(Self); +end; + +function ITraceBLRStatement.getData(): BytePtr; +begin + Result := TraceBLRStatementVTable(vTable).getData(Self); +end; + +function ITraceBLRStatement.getDataLength(): Cardinal; +begin + Result := TraceBLRStatementVTable(vTable).getDataLength(Self); +end; + +function ITraceBLRStatement.getText(): PAnsiChar; +begin + Result := TraceBLRStatementVTable(vTable).getText(Self); +end; + +function ITraceDYNRequest.getData(): BytePtr; +begin + Result := TraceDYNRequestVTable(vTable).getData(Self); +end; + +function ITraceDYNRequest.getDataLength(): Cardinal; +begin + Result := TraceDYNRequestVTable(vTable).getDataLength(Self); +end; + +function ITraceDYNRequest.getText(): PAnsiChar; +begin + Result := TraceDYNRequestVTable(vTable).getText(Self); +end; + +function ITraceContextVariable.getNameSpace(): PAnsiChar; +begin + Result := TraceContextVariableVTable(vTable).getNameSpace(Self); +end; + +function ITraceContextVariable.getVarName(): PAnsiChar; +begin + Result := TraceContextVariableVTable(vTable).getVarName(Self); +end; + +function ITraceContextVariable.getVarValue(): PAnsiChar; +begin + Result := TraceContextVariableVTable(vTable).getVarValue(Self); +end; + +function ITraceProcedure.getProcName(): PAnsiChar; +begin + Result := TraceProcedureVTable(vTable).getProcName(Self); +end; + +function ITraceProcedure.getInputs(): ITraceParams; +begin + Result := TraceProcedureVTable(vTable).getInputs(Self); +end; + +function ITraceProcedure.getPerf(): PerformanceInfoPtr; +begin + Result := TraceProcedureVTable(vTable).getPerf(Self); +end; + +function ITraceFunction.getFuncName(): PAnsiChar; +begin + Result := TraceFunctionVTable(vTable).getFuncName(Self); +end; + +function ITraceFunction.getInputs(): ITraceParams; +begin + Result := TraceFunctionVTable(vTable).getInputs(Self); +end; + +function ITraceFunction.getResult(): ITraceParams; +begin + Result := TraceFunctionVTable(vTable).getResult(Self); +end; + +function ITraceFunction.getPerf(): PerformanceInfoPtr; +begin + Result := TraceFunctionVTable(vTable).getPerf(Self); +end; + +function ITraceTrigger.getTriggerName(): PAnsiChar; +begin + Result := TraceTriggerVTable(vTable).getTriggerName(Self); +end; + +function ITraceTrigger.getRelationName(): PAnsiChar; +begin + Result := TraceTriggerVTable(vTable).getRelationName(Self); +end; + +function ITraceTrigger.getAction(): Integer; +begin + Result := TraceTriggerVTable(vTable).getAction(Self); +end; + +function ITraceTrigger.getWhich(): Integer; +begin + Result := TraceTriggerVTable(vTable).getWhich(Self); +end; + +function ITraceTrigger.getPerf(): PerformanceInfoPtr; +begin + Result := TraceTriggerVTable(vTable).getPerf(Self); +end; + +function ITraceServiceConnection.getServiceID(): Pointer; +begin + Result := TraceServiceConnectionVTable(vTable).getServiceID(Self); +end; + +function ITraceServiceConnection.getServiceMgr(): PAnsiChar; +begin + Result := TraceServiceConnectionVTable(vTable).getServiceMgr(Self); +end; + +function ITraceServiceConnection.getServiceName(): PAnsiChar; +begin + Result := TraceServiceConnectionVTable(vTable).getServiceName(Self); +end; + +function ITraceStatusVector.hasError(): Boolean; +begin + Result := TraceStatusVectorVTable(vTable).hasError(Self); +end; + +function ITraceStatusVector.hasWarning(): Boolean; +begin + Result := TraceStatusVectorVTable(vTable).hasWarning(Self); +end; + +function ITraceStatusVector.getStatus(): IStatus; +begin + Result := TraceStatusVectorVTable(vTable).getStatus(Self); +end; + +function ITraceStatusVector.getText(): PAnsiChar; +begin + Result := TraceStatusVectorVTable(vTable).getText(Self); +end; + +function ITraceSweepInfo.getOIT(): Int64; +begin + Result := TraceSweepInfoVTable(vTable).getOIT(Self); +end; + +function ITraceSweepInfo.getOST(): Int64; +begin + Result := TraceSweepInfoVTable(vTable).getOST(Self); +end; + +function ITraceSweepInfo.getOAT(): Int64; +begin + Result := TraceSweepInfoVTable(vTable).getOAT(Self); +end; + +function ITraceSweepInfo.getNext(): Int64; +begin + Result := TraceSweepInfoVTable(vTable).getNext(Self); +end; + +function ITraceSweepInfo.getPerf(): PerformanceInfoPtr; +begin + Result := TraceSweepInfoVTable(vTable).getPerf(Self); +end; + +function ITraceLogWriter.write(buf: Pointer; size: Cardinal): Cardinal; +begin + Result := TraceLogWriterVTable(vTable).write(Self, buf, size); +end; + +function ITraceInitInfo.getConfigText(): PAnsiChar; +begin + Result := TraceInitInfoVTable(vTable).getConfigText(Self); +end; + +function ITraceInitInfo.getTraceSessionID(): Integer; +begin + Result := TraceInitInfoVTable(vTable).getTraceSessionID(Self); +end; + +function ITraceInitInfo.getTraceSessionName(): PAnsiChar; +begin + Result := TraceInitInfoVTable(vTable).getTraceSessionName(Self); +end; + +function ITraceInitInfo.getFirebirdRootDirectory(): PAnsiChar; +begin + Result := TraceInitInfoVTable(vTable).getFirebirdRootDirectory(Self); +end; + +function ITraceInitInfo.getDatabaseName(): PAnsiChar; +begin + Result := TraceInitInfoVTable(vTable).getDatabaseName(Self); +end; + +function ITraceInitInfo.getConnection(): ITraceDatabaseConnection; +begin + Result := TraceInitInfoVTable(vTable).getConnection(Self); +end; + +function ITraceInitInfo.getLogWriter(): ITraceLogWriter; +begin + Result := TraceInitInfoVTable(vTable).getLogWriter(Self); +end; + +function ITracePlugin.trace_get_error(): PAnsiChar; +begin + Result := TracePluginVTable(vTable).trace_get_error(Self); +end; + +function ITracePlugin.trace_attach(connection: ITraceDatabaseConnection; create_db: Boolean; att_result: Cardinal): Boolean; +begin + Result := TracePluginVTable(vTable).trace_attach(Self, connection, create_db, att_result); +end; + +function ITracePlugin.trace_detach(connection: ITraceDatabaseConnection; drop_db: Boolean): Boolean; +begin + Result := TracePluginVTable(vTable).trace_detach(Self, connection, drop_db); +end; + +function ITracePlugin.trace_transaction_start(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; tpb_length: Cardinal; tpb: BytePtr; tra_result: Cardinal): Boolean; +begin + Result := TracePluginVTable(vTable).trace_transaction_start(Self, connection, transaction, tpb_length, tpb, tra_result); +end; + +function ITracePlugin.trace_transaction_end(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; commit: Boolean; retain_context: Boolean; tra_result: Cardinal): Boolean; +begin + Result := TracePluginVTable(vTable).trace_transaction_end(Self, connection, transaction, commit, retain_context, tra_result); +end; + +function ITracePlugin.trace_proc_execute(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; procedure_: ITraceProcedure; started: Boolean; proc_result: Cardinal): Boolean; +begin + Result := TracePluginVTable(vTable).trace_proc_execute(Self, connection, transaction, procedure_, started, proc_result); +end; + +function ITracePlugin.trace_trigger_execute(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; trigger: ITraceTrigger; started: Boolean; trig_result: Cardinal): Boolean; +begin + Result := TracePluginVTable(vTable).trace_trigger_execute(Self, connection, transaction, trigger, started, trig_result); +end; + +function ITracePlugin.trace_set_context(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; variable: ITraceContextVariable): Boolean; +begin + Result := TracePluginVTable(vTable).trace_set_context(Self, connection, transaction, variable); +end; + +function ITracePlugin.trace_dsql_prepare(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceSQLStatement; time_millis: Int64; req_result: Cardinal): Boolean; +begin + Result := TracePluginVTable(vTable).trace_dsql_prepare(Self, connection, transaction, statement, time_millis, req_result); +end; + +function ITracePlugin.trace_dsql_free(connection: ITraceDatabaseConnection; statement: ITraceSQLStatement; option: Cardinal): Boolean; +begin + Result := TracePluginVTable(vTable).trace_dsql_free(Self, connection, statement, option); +end; + +function ITracePlugin.trace_dsql_execute(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceSQLStatement; started: Boolean; req_result: Cardinal): Boolean; +begin + Result := TracePluginVTable(vTable).trace_dsql_execute(Self, connection, transaction, statement, started, req_result); +end; + +function ITracePlugin.trace_blr_compile(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceBLRStatement; time_millis: Int64; req_result: Cardinal): Boolean; +begin + Result := TracePluginVTable(vTable).trace_blr_compile(Self, connection, transaction, statement, time_millis, req_result); +end; + +function ITracePlugin.trace_blr_execute(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceBLRStatement; req_result: Cardinal): Boolean; +begin + Result := TracePluginVTable(vTable).trace_blr_execute(Self, connection, transaction, statement, req_result); +end; + +function ITracePlugin.trace_dyn_execute(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; request: ITraceDYNRequest; time_millis: Int64; req_result: Cardinal): Boolean; +begin + Result := TracePluginVTable(vTable).trace_dyn_execute(Self, connection, transaction, request, time_millis, req_result); +end; + +function ITracePlugin.trace_service_attach(service: ITraceServiceConnection; att_result: Cardinal): Boolean; +begin + Result := TracePluginVTable(vTable).trace_service_attach(Self, service, att_result); +end; + +function ITracePlugin.trace_service_start(service: ITraceServiceConnection; switches_length: Cardinal; switches: PAnsiChar; start_result: Cardinal): Boolean; +begin + Result := TracePluginVTable(vTable).trace_service_start(Self, service, switches_length, switches, start_result); +end; + +function ITracePlugin.trace_service_query(service: ITraceServiceConnection; send_item_length: Cardinal; send_items: BytePtr; recv_item_length: Cardinal; recv_items: BytePtr; query_result: Cardinal): Boolean; +begin + Result := TracePluginVTable(vTable).trace_service_query(Self, service, send_item_length, send_items, recv_item_length, recv_items, query_result); +end; + +function ITracePlugin.trace_service_detach(service: ITraceServiceConnection; detach_result: Cardinal): Boolean; +begin + Result := TracePluginVTable(vTable).trace_service_detach(Self, service, detach_result); +end; + +function ITracePlugin.trace_event_error(connection: ITraceConnection; status: ITraceStatusVector; function_: PAnsiChar): Boolean; +begin + Result := TracePluginVTable(vTable).trace_event_error(Self, connection, status, function_); +end; + +function ITracePlugin.trace_event_sweep(connection: ITraceDatabaseConnection; sweep: ITraceSweepInfo; sweep_state: Cardinal): Boolean; +begin + Result := TracePluginVTable(vTable).trace_event_sweep(Self, connection, sweep, sweep_state); +end; + +function ITracePlugin.trace_func_execute(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; function_: ITraceFunction; started: Boolean; func_result: Cardinal): Boolean; +begin + Result := TracePluginVTable(vTable).trace_func_execute(Self, connection, transaction, function_, started, func_result); +end; + +function ITraceFactory.trace_needs(): QWord; +begin + Result := TraceFactoryVTable(vTable).trace_needs(Self); +end; + +function ITraceFactory.trace_create(status: IStatus; init_info: ITraceInitInfo): ITracePlugin; +begin + Result := TraceFactoryVTable(vTable).trace_create(Self, status, init_info); +// FbException.checkException(status); +end; + +procedure IUdrFunctionFactory.setup(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder); +begin + UdrFunctionFactoryVTable(vTable).setup(Self, status, context, metadata, inBuilder, outBuilder); +// FbException.checkException(status); +end; + +function IUdrFunctionFactory.newItem(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata): IExternalFunction; +begin + Result := UdrFunctionFactoryVTable(vTable).newItem(Self, status, context, metadata); +// FbException.checkException(status); +end; + +procedure IUdrProcedureFactory.setup(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder); +begin + UdrProcedureFactoryVTable(vTable).setup(Self, status, context, metadata, inBuilder, outBuilder); +// FbException.checkException(status); +end; + +function IUdrProcedureFactory.newItem(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata): IExternalProcedure; +begin + Result := UdrProcedureFactoryVTable(vTable).newItem(Self, status, context, metadata); +// FbException.checkException(status); +end; + +procedure IUdrTriggerFactory.setup(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; fieldsBuilder: IMetadataBuilder); +begin + UdrTriggerFactoryVTable(vTable).setup(Self, status, context, metadata, fieldsBuilder); +// FbException.checkException(status); +end; + +function IUdrTriggerFactory.newItem(status: IStatus; context: IExternalContext; metadata: IRoutineMetadata): IExternalTrigger; +begin + Result := UdrTriggerFactoryVTable(vTable).newItem(Self, status, context, metadata); +// FbException.checkException(status); +end; + +function IUdrPlugin.getMaster(): IMaster; +begin + Result := UdrPluginVTable(vTable).getMaster(Self); +end; + +procedure IUdrPlugin.registerFunction(status: IStatus; name: PAnsiChar; factory: IUdrFunctionFactory); +begin + UdrPluginVTable(vTable).registerFunction(Self, status, name, factory); +// FbException.checkException(status); +end; + +procedure IUdrPlugin.registerProcedure(status: IStatus; name: PAnsiChar; factory: IUdrProcedureFactory); +begin + UdrPluginVTable(vTable).registerProcedure(Self, status, name, factory); +// FbException.checkException(status); +end; + +procedure IUdrPlugin.registerTrigger(status: IStatus; name: PAnsiChar; factory: IUdrTriggerFactory); +begin + UdrPluginVTable(vTable).registerTrigger(Self, status, name, factory); +// FbException.checkException(status); +end; + +var + IVersionedImpl_vTable: VersionedVTable; + +constructor IVersionedImpl.create; +begin + vTable := IVersionedImpl_vTable; +end; + +procedure IReferenceCountedImpl_addRefDispatcher(this: IReferenceCounted); cdecl; +begin + //try + IReferenceCountedImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IReferenceCountedImpl_releaseDispatcher(this: IReferenceCounted): Integer; cdecl; +begin + //try + Result := IReferenceCountedImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + IReferenceCountedImpl_vTable: ReferenceCountedVTable; + +constructor IReferenceCountedImpl.create; +begin + vTable := IReferenceCountedImpl_vTable; +end; + +procedure IDisposableImpl_disposeDispatcher(this: IDisposable); cdecl; +begin + //try + IDisposableImpl(this).dispose(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + IDisposableImpl_vTable: DisposableVTable; + +constructor IDisposableImpl.create; +begin + vTable := IDisposableImpl_vTable; +end; + +procedure IStatusImpl_disposeDispatcher(this: IStatus); cdecl; +begin + //try + IStatusImpl(this).dispose(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IStatusImpl_initDispatcher(this: IStatus); cdecl; +begin + //try + IStatusImpl(this).init(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IStatusImpl_getStateDispatcher(this: IStatus): Cardinal; cdecl; +begin + //try + Result := IStatusImpl(this).getState(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IStatusImpl_setErrors2Dispatcher(this: IStatus; length: Cardinal; value: NativeIntPtr); cdecl; +begin + //try + IStatusImpl(this).setErrors2(length, value); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IStatusImpl_setWarnings2Dispatcher(this: IStatus; length: Cardinal; value: NativeIntPtr); cdecl; +begin + //try + IStatusImpl(this).setWarnings2(length, value); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IStatusImpl_setErrorsDispatcher(this: IStatus; value: NativeIntPtr); cdecl; +begin + //try + IStatusImpl(this).setErrors(value); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IStatusImpl_setWarningsDispatcher(this: IStatus; value: NativeIntPtr); cdecl; +begin + //try + IStatusImpl(this).setWarnings(value); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IStatusImpl_getErrorsDispatcher(this: IStatus): NativeIntPtr; cdecl; +begin + //try + Result := IStatusImpl(this).getErrors(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IStatusImpl_getWarningsDispatcher(this: IStatus): NativeIntPtr; cdecl; +begin + //try + Result := IStatusImpl(this).getWarnings(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IStatusImpl_cloneDispatcher(this: IStatus): IStatus; cdecl; +begin + //try + Result := IStatusImpl(this).clone(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + IStatusImpl_vTable: StatusVTable; + +constructor IStatusImpl.create; +begin + vTable := IStatusImpl_vTable; +end; + +function IMasterImpl_getStatusDispatcher(this: IMaster): IStatus; cdecl; +begin + //try + Result := IMasterImpl(this).getStatus(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IMasterImpl_getDispatcherDispatcher(this: IMaster): IProvider; cdecl; +begin + //try + Result := IMasterImpl(this).getDispatcher(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IMasterImpl_getPluginManagerDispatcher(this: IMaster): IPluginManager; cdecl; +begin + //try + Result := IMasterImpl(this).getPluginManager(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IMasterImpl_getTimerControlDispatcher(this: IMaster): ITimerControl; cdecl; +begin + //try + Result := IMasterImpl(this).getTimerControl(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IMasterImpl_getDtcDispatcher(this: IMaster): IDtc; cdecl; +begin + //try + Result := IMasterImpl(this).getDtc(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IMasterImpl_registerAttachmentDispatcher(this: IMaster; provider: IProvider; attachment: IAttachment): IAttachment; cdecl; +begin + //try + Result := IMasterImpl(this).registerAttachment(provider, attachment); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IMasterImpl_registerTransactionDispatcher(this: IMaster; attachment: IAttachment; transaction: ITransaction): ITransaction; cdecl; +begin + //try + Result := IMasterImpl(this).registerTransaction(attachment, transaction); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IMasterImpl_getMetadataBuilderDispatcher(this: IMaster; status: IStatus; fieldCount: Cardinal): IMetadataBuilder; cdecl; +begin + //try + Result := IMasterImpl(this).getMetadataBuilder(status, fieldCount); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IMasterImpl_serverModeDispatcher(this: IMaster; mode: Integer): Integer; cdecl; +begin + //try + Result := IMasterImpl(this).serverMode(mode); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IMasterImpl_getUtilInterfaceDispatcher(this: IMaster): IUtil; cdecl; +begin + //try + Result := IMasterImpl(this).getUtilInterface(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IMasterImpl_getConfigManagerDispatcher(this: IMaster): IConfigManager; cdecl; +begin + //try + Result := IMasterImpl(this).getConfigManager(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IMasterImpl_getProcessExitingDispatcher(this: IMaster): Boolean; cdecl; +begin + //try + Result := IMasterImpl(this).getProcessExiting(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + IMasterImpl_vTable: MasterVTable; + +constructor IMasterImpl.create; +begin + vTable := IMasterImpl_vTable; +end; + +procedure IPluginBaseImpl_addRefDispatcher(this: IPluginBase); cdecl; +begin + //try + IPluginBaseImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IPluginBaseImpl_releaseDispatcher(this: IPluginBase): Integer; cdecl; +begin + //try + Result := IPluginBaseImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IPluginBaseImpl_setOwnerDispatcher(this: IPluginBase; r: IReferenceCounted); cdecl; +begin + //try + IPluginBaseImpl(this).setOwner(r); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IPluginBaseImpl_getOwnerDispatcher(this: IPluginBase): IReferenceCounted; cdecl; +begin + //try + Result := IPluginBaseImpl(this).getOwner(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + IPluginBaseImpl_vTable: PluginBaseVTable; + +constructor IPluginBaseImpl.create; +begin + vTable := IPluginBaseImpl_vTable; +end; + +procedure IPluginSetImpl_addRefDispatcher(this: IPluginSet); cdecl; +begin + //try + IPluginSetImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IPluginSetImpl_releaseDispatcher(this: IPluginSet): Integer; cdecl; +begin + //try + Result := IPluginSetImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IPluginSetImpl_getNameDispatcher(this: IPluginSet): PAnsiChar; cdecl; +begin + //try + Result := IPluginSetImpl(this).getName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IPluginSetImpl_getModuleNameDispatcher(this: IPluginSet): PAnsiChar; cdecl; +begin + //try + Result := IPluginSetImpl(this).getModuleName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IPluginSetImpl_getPluginDispatcher(this: IPluginSet; status: IStatus): IPluginBase; cdecl; +begin + //try + Result := IPluginSetImpl(this).getPlugin(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IPluginSetImpl_nextDispatcher(this: IPluginSet; status: IStatus); cdecl; +begin + //try + IPluginSetImpl(this).next(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IPluginSetImpl_set_Dispatcher(this: IPluginSet; status: IStatus; s: PAnsiChar); cdecl; +begin + //try + IPluginSetImpl(this).set_(status, s); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IPluginSetImpl_vTable: PluginSetVTable; + +constructor IPluginSetImpl.create; +begin + vTable := IPluginSetImpl_vTable; +end; + +procedure IConfigEntryImpl_addRefDispatcher(this: IConfigEntry); cdecl; +begin + //try + IConfigEntryImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IConfigEntryImpl_releaseDispatcher(this: IConfigEntry): Integer; cdecl; +begin + //try + Result := IConfigEntryImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IConfigEntryImpl_getNameDispatcher(this: IConfigEntry): PAnsiChar; cdecl; +begin + //try + Result := IConfigEntryImpl(this).getName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IConfigEntryImpl_getValueDispatcher(this: IConfigEntry): PAnsiChar; cdecl; +begin + //try + Result := IConfigEntryImpl(this).getValue(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IConfigEntryImpl_getIntValueDispatcher(this: IConfigEntry): Int64; cdecl; +begin + //try + Result := IConfigEntryImpl(this).getIntValue(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IConfigEntryImpl_getBoolValueDispatcher(this: IConfigEntry): Boolean; cdecl; +begin + //try + Result := IConfigEntryImpl(this).getBoolValue(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IConfigEntryImpl_getSubConfigDispatcher(this: IConfigEntry; status: IStatus): IConfig; cdecl; +begin + //try + Result := IConfigEntryImpl(this).getSubConfig(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IConfigEntryImpl_vTable: ConfigEntryVTable; + +constructor IConfigEntryImpl.create; +begin + vTable := IConfigEntryImpl_vTable; +end; + +procedure IConfigImpl_addRefDispatcher(this: IConfig); cdecl; +begin + //try + IConfigImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IConfigImpl_releaseDispatcher(this: IConfig): Integer; cdecl; +begin + //try + Result := IConfigImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IConfigImpl_findDispatcher(this: IConfig; status: IStatus; name: PAnsiChar): IConfigEntry; cdecl; +begin + //try + Result := IConfigImpl(this).find(status, name); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IConfigImpl_findValueDispatcher(this: IConfig; status: IStatus; name: PAnsiChar; value: PAnsiChar): IConfigEntry; cdecl; +begin + //try + Result := IConfigImpl(this).findValue(status, name, value); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IConfigImpl_findPosDispatcher(this: IConfig; status: IStatus; name: PAnsiChar; pos: Cardinal): IConfigEntry; cdecl; +begin + //try + Result := IConfigImpl(this).findPos(status, name, pos); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IConfigImpl_vTable: ConfigVTable; + +constructor IConfigImpl.create; +begin + vTable := IConfigImpl_vTable; +end; + +procedure IFirebirdConfImpl_addRefDispatcher(this: IFirebirdConf); cdecl; +begin + //try + IFirebirdConfImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IFirebirdConfImpl_releaseDispatcher(this: IFirebirdConf): Integer; cdecl; +begin + //try + Result := IFirebirdConfImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IFirebirdConfImpl_getKeyDispatcher(this: IFirebirdConf; name: PAnsiChar): Cardinal; cdecl; +begin + //try + Result := IFirebirdConfImpl(this).getKey(name); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IFirebirdConfImpl_asIntegerDispatcher(this: IFirebirdConf; key: Cardinal): Int64; cdecl; +begin + //try + Result := IFirebirdConfImpl(this).asInteger(key); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IFirebirdConfImpl_asStringDispatcher(this: IFirebirdConf; key: Cardinal): PAnsiChar; cdecl; +begin + //try + Result := IFirebirdConfImpl(this).asString(key); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IFirebirdConfImpl_asBooleanDispatcher(this: IFirebirdConf; key: Cardinal): Boolean; cdecl; +begin + //try + Result := IFirebirdConfImpl(this).asBoolean(key); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + IFirebirdConfImpl_vTable: FirebirdConfVTable; + +constructor IFirebirdConfImpl.create; +begin + vTable := IFirebirdConfImpl_vTable; +end; + +procedure IPluginConfigImpl_addRefDispatcher(this: IPluginConfig); cdecl; +begin + //try + IPluginConfigImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IPluginConfigImpl_releaseDispatcher(this: IPluginConfig): Integer; cdecl; +begin + //try + Result := IPluginConfigImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IPluginConfigImpl_getConfigFileNameDispatcher(this: IPluginConfig): PAnsiChar; cdecl; +begin + //try + Result := IPluginConfigImpl(this).getConfigFileName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IPluginConfigImpl_getDefaultConfigDispatcher(this: IPluginConfig; status: IStatus): IConfig; cdecl; +begin + //try + Result := IPluginConfigImpl(this).getDefaultConfig(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IPluginConfigImpl_getFirebirdConfDispatcher(this: IPluginConfig; status: IStatus): IFirebirdConf; cdecl; +begin + //try + Result := IPluginConfigImpl(this).getFirebirdConf(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IPluginConfigImpl_setReleaseDelayDispatcher(this: IPluginConfig; status: IStatus; microSeconds: QWord); cdecl; +begin + //try + IPluginConfigImpl(this).setReleaseDelay(status, microSeconds); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IPluginConfigImpl_vTable: PluginConfigVTable; + +constructor IPluginConfigImpl.create; +begin + vTable := IPluginConfigImpl_vTable; +end; + +function IPluginFactoryImpl_createPluginDispatcher(this: IPluginFactory; status: IStatus; factoryParameter: IPluginConfig): IPluginBase; cdecl; +begin + //try + Result := IPluginFactoryImpl(this).createPlugin(status, factoryParameter); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IPluginFactoryImpl_vTable: PluginFactoryVTable; + +constructor IPluginFactoryImpl.create; +begin + vTable := IPluginFactoryImpl_vTable; +end; + +procedure IPluginModuleImpl_doCleanDispatcher(this: IPluginModule); cdecl; +begin + //try + IPluginModuleImpl(this).doClean(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + IPluginModuleImpl_vTable: PluginModuleVTable; + +constructor IPluginModuleImpl.create; +begin + vTable := IPluginModuleImpl_vTable; +end; + +procedure IPluginManagerImpl_registerPluginFactoryDispatcher(this: IPluginManager; pluginType: Cardinal; defaultName: PAnsiChar; factory: IPluginFactory); cdecl; +begin + //try + IPluginManagerImpl(this).registerPluginFactory(pluginType, defaultName, factory); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IPluginManagerImpl_registerModuleDispatcher(this: IPluginManager; cleanup: IPluginModule); cdecl; +begin + //try + IPluginManagerImpl(this).registerModule(cleanup); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IPluginManagerImpl_unregisterModuleDispatcher(this: IPluginManager; cleanup: IPluginModule); cdecl; +begin + //try + IPluginManagerImpl(this).unregisterModule(cleanup); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IPluginManagerImpl_getPluginsDispatcher(this: IPluginManager; status: IStatus; pluginType: Cardinal; namesList: PAnsiChar; firebirdConf: IFirebirdConf): IPluginSet; cdecl; +begin + //try + Result := IPluginManagerImpl(this).getPlugins(status, pluginType, namesList, firebirdConf); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IPluginManagerImpl_getConfigDispatcher(this: IPluginManager; status: IStatus; filename: PAnsiChar): IConfig; cdecl; +begin + //try + Result := IPluginManagerImpl(this).getConfig(status, filename); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IPluginManagerImpl_releasePluginDispatcher(this: IPluginManager; plugin: IPluginBase); cdecl; +begin + //try + IPluginManagerImpl(this).releasePlugin(plugin); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + IPluginManagerImpl_vTable: PluginManagerVTable; + +constructor IPluginManagerImpl.create; +begin + vTable := IPluginManagerImpl_vTable; +end; + +procedure ICryptKeyImpl_setSymmetricDispatcher(this: ICryptKey; status: IStatus; type_: PAnsiChar; keyLength: Cardinal; key: Pointer); cdecl; +begin + //try + ICryptKeyImpl(this).setSymmetric(status, type_, keyLength, key); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure ICryptKeyImpl_setAsymmetricDispatcher(this: ICryptKey; status: IStatus; type_: PAnsiChar; encryptKeyLength: Cardinal; encryptKey: Pointer; decryptKeyLength: Cardinal; decryptKey: Pointer); cdecl; +begin + //try + ICryptKeyImpl(this).setAsymmetric(status, type_, encryptKeyLength, encryptKey, decryptKeyLength, decryptKey); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function ICryptKeyImpl_getEncryptKeyDispatcher(this: ICryptKey; length: CardinalPtr): Pointer; cdecl; +begin + //try + Result := ICryptKeyImpl(this).getEncryptKey(length); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ICryptKeyImpl_getDecryptKeyDispatcher(this: ICryptKey; length: CardinalPtr): Pointer; cdecl; +begin + //try + Result := ICryptKeyImpl(this).getDecryptKey(length); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ICryptKeyImpl_vTable: CryptKeyVTable; + +constructor ICryptKeyImpl.create; +begin + vTable := ICryptKeyImpl_vTable; +end; + +function IConfigManagerImpl_getDirectoryDispatcher(this: IConfigManager; code: Cardinal): PAnsiChar; cdecl; +begin + //try + Result := IConfigManagerImpl(this).getDirectory(code); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IConfigManagerImpl_getFirebirdConfDispatcher(this: IConfigManager): IFirebirdConf; cdecl; +begin + //try + Result := IConfigManagerImpl(this).getFirebirdConf(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IConfigManagerImpl_getDatabaseConfDispatcher(this: IConfigManager; dbName: PAnsiChar): IFirebirdConf; cdecl; +begin + //try + Result := IConfigManagerImpl(this).getDatabaseConf(dbName); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IConfigManagerImpl_getPluginConfigDispatcher(this: IConfigManager; configuredPlugin: PAnsiChar): IConfig; cdecl; +begin + //try + Result := IConfigManagerImpl(this).getPluginConfig(configuredPlugin); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IConfigManagerImpl_getInstallDirectoryDispatcher(this: IConfigManager): PAnsiChar; cdecl; +begin + //try + Result := IConfigManagerImpl(this).getInstallDirectory(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IConfigManagerImpl_getRootDirectoryDispatcher(this: IConfigManager): PAnsiChar; cdecl; +begin + //try + Result := IConfigManagerImpl(this).getRootDirectory(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + IConfigManagerImpl_vTable: ConfigManagerVTable; + +constructor IConfigManagerImpl.create; +begin + vTable := IConfigManagerImpl_vTable; +end; + +procedure IEventCallbackImpl_addRefDispatcher(this: IEventCallback); cdecl; +begin + //try + IEventCallbackImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IEventCallbackImpl_releaseDispatcher(this: IEventCallback): Integer; cdecl; +begin + //try + Result := IEventCallbackImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IEventCallbackImpl_eventCallbackFunctionDispatcher(this: IEventCallback; length: Cardinal; events: BytePtr); cdecl; +begin + //try + IEventCallbackImpl(this).eventCallbackFunction(length, events); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + IEventCallbackImpl_vTable: EventCallbackVTable; + +constructor IEventCallbackImpl.create; +begin + vTable := IEventCallbackImpl_vTable; +end; + +procedure IBlobImpl_addRefDispatcher(this: IBlob); cdecl; +begin + //try + IBlobImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IBlobImpl_releaseDispatcher(this: IBlob): Integer; cdecl; +begin + //try + Result := IBlobImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IBlobImpl_getInfoDispatcher(this: IBlob; status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); cdecl; +begin + //try + IBlobImpl(this).getInfo(status, itemsLength, items, bufferLength, buffer); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IBlobImpl_getSegmentDispatcher(this: IBlob; status: IStatus; bufferLength: Cardinal; buffer: Pointer; segmentLength: CardinalPtr): Integer; cdecl; +begin + //try + Result := IBlobImpl(this).getSegment(status, bufferLength, buffer, segmentLength); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IBlobImpl_putSegmentDispatcher(this: IBlob; status: IStatus; length: Cardinal; buffer: Pointer); cdecl; +begin + //try + IBlobImpl(this).putSegment(status, length, buffer); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IBlobImpl_cancelDispatcher(this: IBlob; status: IStatus); cdecl; +begin + //try + IBlobImpl(this).cancel(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IBlobImpl_closeDispatcher(this: IBlob; status: IStatus); cdecl; +begin + //try + IBlobImpl(this).close(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IBlobImpl_seekDispatcher(this: IBlob; status: IStatus; mode: Integer; offset: Integer): Integer; cdecl; +begin + //try + Result := IBlobImpl(this).seek(status, mode, offset); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IBlobImpl_vTable: BlobVTable; + +constructor IBlobImpl.create; +begin + vTable := IBlobImpl_vTable; +end; + +procedure ITransactionImpl_addRefDispatcher(this: ITransaction); cdecl; +begin + //try + ITransactionImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITransactionImpl_releaseDispatcher(this: ITransaction): Integer; cdecl; +begin + //try + Result := ITransactionImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure ITransactionImpl_getInfoDispatcher(this: ITransaction; status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); cdecl; +begin + //try + ITransactionImpl(this).getInfo(status, itemsLength, items, bufferLength, buffer); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure ITransactionImpl_prepareDispatcher(this: ITransaction; status: IStatus; msgLength: Cardinal; message: BytePtr); cdecl; +begin + //try + ITransactionImpl(this).prepare(status, msgLength, message); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure ITransactionImpl_commitDispatcher(this: ITransaction; status: IStatus); cdecl; +begin + //try + ITransactionImpl(this).commit(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure ITransactionImpl_commitRetainingDispatcher(this: ITransaction; status: IStatus); cdecl; +begin + //try + ITransactionImpl(this).commitRetaining(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure ITransactionImpl_rollbackDispatcher(this: ITransaction; status: IStatus); cdecl; +begin + //try + ITransactionImpl(this).rollback(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure ITransactionImpl_rollbackRetainingDispatcher(this: ITransaction; status: IStatus); cdecl; +begin + //try + ITransactionImpl(this).rollbackRetaining(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure ITransactionImpl_disconnectDispatcher(this: ITransaction; status: IStatus); cdecl; +begin + //try + ITransactionImpl(this).disconnect(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function ITransactionImpl_joinDispatcher(this: ITransaction; status: IStatus; transaction: ITransaction): ITransaction; cdecl; +begin + //try + Result := ITransactionImpl(this).join(status, transaction); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function ITransactionImpl_validateDispatcher(this: ITransaction; status: IStatus; attachment: IAttachment): ITransaction; cdecl; +begin + //try + Result := ITransactionImpl(this).validate(status, attachment); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function ITransactionImpl_enterDtcDispatcher(this: ITransaction; status: IStatus): ITransaction; cdecl; +begin + //try + Result := ITransactionImpl(this).enterDtc(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + ITransactionImpl_vTable: TransactionVTable; + +constructor ITransactionImpl.create; +begin + vTable := ITransactionImpl_vTable; +end; + +procedure IMessageMetadataImpl_addRefDispatcher(this: IMessageMetadata); cdecl; +begin + //try + IMessageMetadataImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IMessageMetadataImpl_releaseDispatcher(this: IMessageMetadata): Integer; cdecl; +begin + //try + Result := IMessageMetadataImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IMessageMetadataImpl_getCountDispatcher(this: IMessageMetadata; status: IStatus): Cardinal; cdecl; +begin + //try + Result := IMessageMetadataImpl(this).getCount(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IMessageMetadataImpl_getFieldDispatcher(this: IMessageMetadata; status: IStatus; index: Cardinal): PAnsiChar; cdecl; +begin + //try + Result := IMessageMetadataImpl(this).getField(status, index); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IMessageMetadataImpl_getRelationDispatcher(this: IMessageMetadata; status: IStatus; index: Cardinal): PAnsiChar; cdecl; +begin + //try + Result := IMessageMetadataImpl(this).getRelation(status, index); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IMessageMetadataImpl_getOwnerDispatcher(this: IMessageMetadata; status: IStatus; index: Cardinal): PAnsiChar; cdecl; +begin + //try + Result := IMessageMetadataImpl(this).getOwner(status, index); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IMessageMetadataImpl_getAliasDispatcher(this: IMessageMetadata; status: IStatus; index: Cardinal): PAnsiChar; cdecl; +begin + //try + Result := IMessageMetadataImpl(this).getAlias(status, index); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IMessageMetadataImpl_getTypeDispatcher(this: IMessageMetadata; status: IStatus; index: Cardinal): Cardinal; cdecl; +begin + //try + Result := IMessageMetadataImpl(this).getType(status, index); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IMessageMetadataImpl_isNullableDispatcher(this: IMessageMetadata; status: IStatus; index: Cardinal): Boolean; cdecl; +begin + //try + Result := IMessageMetadataImpl(this).isNullable(status, index); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IMessageMetadataImpl_getSubTypeDispatcher(this: IMessageMetadata; status: IStatus; index: Cardinal): Integer; cdecl; +begin + //try + Result := IMessageMetadataImpl(this).getSubType(status, index); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IMessageMetadataImpl_getLengthDispatcher(this: IMessageMetadata; status: IStatus; index: Cardinal): Cardinal; cdecl; +begin + //try + Result := IMessageMetadataImpl(this).getLength(status, index); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IMessageMetadataImpl_getScaleDispatcher(this: IMessageMetadata; status: IStatus; index: Cardinal): Integer; cdecl; +begin + //try + Result := IMessageMetadataImpl(this).getScale(status, index); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IMessageMetadataImpl_getCharSetDispatcher(this: IMessageMetadata; status: IStatus; index: Cardinal): Cardinal; cdecl; +begin + //try + Result := IMessageMetadataImpl(this).getCharSet(status, index); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IMessageMetadataImpl_getOffsetDispatcher(this: IMessageMetadata; status: IStatus; index: Cardinal): Cardinal; cdecl; +begin + //try + Result := IMessageMetadataImpl(this).getOffset(status, index); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IMessageMetadataImpl_getNullOffsetDispatcher(this: IMessageMetadata; status: IStatus; index: Cardinal): Cardinal; cdecl; +begin + //try + Result := IMessageMetadataImpl(this).getNullOffset(status, index); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IMessageMetadataImpl_getBuilderDispatcher(this: IMessageMetadata; status: IStatus): IMetadataBuilder; cdecl; +begin + //try + Result := IMessageMetadataImpl(this).getBuilder(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IMessageMetadataImpl_getMessageLengthDispatcher(this: IMessageMetadata; status: IStatus): Cardinal; cdecl; +begin + //try + Result := IMessageMetadataImpl(this).getMessageLength(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IMessageMetadataImpl_vTable: MessageMetadataVTable; + +constructor IMessageMetadataImpl.create; +begin + vTable := IMessageMetadataImpl_vTable; +end; + +procedure IMetadataBuilderImpl_addRefDispatcher(this: IMetadataBuilder); cdecl; +begin + //try + IMetadataBuilderImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IMetadataBuilderImpl_releaseDispatcher(this: IMetadataBuilder): Integer; cdecl; +begin + //try + Result := IMetadataBuilderImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IMetadataBuilderImpl_setTypeDispatcher(this: IMetadataBuilder; status: IStatus; index: Cardinal; type_: Cardinal); cdecl; +begin + //try + IMetadataBuilderImpl(this).setType(status, index, type_); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IMetadataBuilderImpl_setSubTypeDispatcher(this: IMetadataBuilder; status: IStatus; index: Cardinal; subType: Integer); cdecl; +begin + //try + IMetadataBuilderImpl(this).setSubType(status, index, subType); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IMetadataBuilderImpl_setLengthDispatcher(this: IMetadataBuilder; status: IStatus; index: Cardinal; length: Cardinal); cdecl; +begin + //try + IMetadataBuilderImpl(this).setLength(status, index, length); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IMetadataBuilderImpl_setCharSetDispatcher(this: IMetadataBuilder; status: IStatus; index: Cardinal; charSet: Cardinal); cdecl; +begin + //try + IMetadataBuilderImpl(this).setCharSet(status, index, charSet); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IMetadataBuilderImpl_setScaleDispatcher(this: IMetadataBuilder; status: IStatus; index: Cardinal; scale: Cardinal); cdecl; +begin + //try + IMetadataBuilderImpl(this).setScale(status, index, scale); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IMetadataBuilderImpl_truncateDispatcher(this: IMetadataBuilder; status: IStatus; count: Cardinal); cdecl; +begin + //try + IMetadataBuilderImpl(this).truncate(status, count); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IMetadataBuilderImpl_moveNameToIndexDispatcher(this: IMetadataBuilder; status: IStatus; name: PAnsiChar; index: Cardinal); cdecl; +begin + //try + IMetadataBuilderImpl(this).moveNameToIndex(status, name, index); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IMetadataBuilderImpl_removeDispatcher(this: IMetadataBuilder; status: IStatus; index: Cardinal); cdecl; +begin + //try + IMetadataBuilderImpl(this).remove(status, index); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IMetadataBuilderImpl_addFieldDispatcher(this: IMetadataBuilder; status: IStatus): Cardinal; cdecl; +begin + //try + Result := IMetadataBuilderImpl(this).addField(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IMetadataBuilderImpl_getMetadataDispatcher(this: IMetadataBuilder; status: IStatus): IMessageMetadata; cdecl; +begin + //try + Result := IMetadataBuilderImpl(this).getMetadata(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IMetadataBuilderImpl_vTable: MetadataBuilderVTable; + +constructor IMetadataBuilderImpl.create; +begin + vTable := IMetadataBuilderImpl_vTable; +end; + +procedure IResultSetImpl_addRefDispatcher(this: IResultSet); cdecl; +begin + //try + IResultSetImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IResultSetImpl_releaseDispatcher(this: IResultSet): Integer; cdecl; +begin + //try + Result := IResultSetImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IResultSetImpl_fetchNextDispatcher(this: IResultSet; status: IStatus; message: Pointer): Integer; cdecl; +begin + //try + Result := IResultSetImpl(this).fetchNext(status, message); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IResultSetImpl_fetchPriorDispatcher(this: IResultSet; status: IStatus; message: Pointer): Integer; cdecl; +begin + //try + Result := IResultSetImpl(this).fetchPrior(status, message); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IResultSetImpl_fetchFirstDispatcher(this: IResultSet; status: IStatus; message: Pointer): Integer; cdecl; +begin + //try + Result := IResultSetImpl(this).fetchFirst(status, message); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IResultSetImpl_fetchLastDispatcher(this: IResultSet; status: IStatus; message: Pointer): Integer; cdecl; +begin + //try + Result := IResultSetImpl(this).fetchLast(status, message); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IResultSetImpl_fetchAbsoluteDispatcher(this: IResultSet; status: IStatus; position: Integer; message: Pointer): Integer; cdecl; +begin + //try + Result := IResultSetImpl(this).fetchAbsolute(status, position, message); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IResultSetImpl_fetchRelativeDispatcher(this: IResultSet; status: IStatus; offset: Integer; message: Pointer): Integer; cdecl; +begin + //try + Result := IResultSetImpl(this).fetchRelative(status, offset, message); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IResultSetImpl_isEofDispatcher(this: IResultSet; status: IStatus): Boolean; cdecl; +begin + //try + Result := IResultSetImpl(this).isEof(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IResultSetImpl_isBofDispatcher(this: IResultSet; status: IStatus): Boolean; cdecl; +begin + //try + Result := IResultSetImpl(this).isBof(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IResultSetImpl_getMetadataDispatcher(this: IResultSet; status: IStatus): IMessageMetadata; cdecl; +begin + //try + Result := IResultSetImpl(this).getMetadata(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IResultSetImpl_closeDispatcher(this: IResultSet; status: IStatus); cdecl; +begin + //try + IResultSetImpl(this).close(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IResultSetImpl_setDelayedOutputFormatDispatcher(this: IResultSet; status: IStatus; format: IMessageMetadata); cdecl; +begin + //try + IResultSetImpl(this).setDelayedOutputFormat(status, format); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IResultSetImpl_vTable: ResultSetVTable; + +constructor IResultSetImpl.create; +begin + vTable := IResultSetImpl_vTable; +end; + +procedure IStatementImpl_addRefDispatcher(this: IStatement); cdecl; +begin + //try + IStatementImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IStatementImpl_releaseDispatcher(this: IStatement): Integer; cdecl; +begin + //try + Result := IStatementImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IStatementImpl_getInfoDispatcher(this: IStatement; status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); cdecl; +begin + //try + IStatementImpl(this).getInfo(status, itemsLength, items, bufferLength, buffer); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IStatementImpl_getTypeDispatcher(this: IStatement; status: IStatus): Cardinal; cdecl; +begin + //try + Result := IStatementImpl(this).getType(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IStatementImpl_getPlanDispatcher(this: IStatement; status: IStatus; detailed: Boolean): PAnsiChar; cdecl; +begin + //try + Result := IStatementImpl(this).getPlan(status, detailed); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IStatementImpl_getAffectedRecordsDispatcher(this: IStatement; status: IStatus): QWord; cdecl; +begin + //try + Result := IStatementImpl(this).getAffectedRecords(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IStatementImpl_getInputMetadataDispatcher(this: IStatement; status: IStatus): IMessageMetadata; cdecl; +begin + //try + Result := IStatementImpl(this).getInputMetadata(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IStatementImpl_getOutputMetadataDispatcher(this: IStatement; status: IStatus): IMessageMetadata; cdecl; +begin + //try + Result := IStatementImpl(this).getOutputMetadata(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IStatementImpl_executeDispatcher(this: IStatement; status: IStatus; transaction: ITransaction; inMetadata: IMessageMetadata; inBuffer: Pointer; outMetadata: IMessageMetadata; outBuffer: Pointer): ITransaction; cdecl; +begin + //try + Result := IStatementImpl(this).execute(status, transaction, inMetadata, inBuffer, outMetadata, outBuffer); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IStatementImpl_openCursorDispatcher(this: IStatement; status: IStatus; transaction: ITransaction; inMetadata: IMessageMetadata; inBuffer: Pointer; outMetadata: IMessageMetadata; flags: Cardinal): IResultSet; cdecl; +begin + //try + Result := IStatementImpl(this).openCursor(status, transaction, inMetadata, inBuffer, outMetadata, flags); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IStatementImpl_setCursorNameDispatcher(this: IStatement; status: IStatus; name: PAnsiChar); cdecl; +begin + //try + IStatementImpl(this).setCursorName(status, name); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IStatementImpl_freeDispatcher(this: IStatement; status: IStatus); cdecl; +begin + //try + IStatementImpl(this).free(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IStatementImpl_getFlagsDispatcher(this: IStatement; status: IStatus): Cardinal; cdecl; +begin + //try + Result := IStatementImpl(this).getFlags(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IStatementImpl_vTable: StatementVTable; + +constructor IStatementImpl.create; +begin + vTable := IStatementImpl_vTable; +end; + +procedure IRequestImpl_addRefDispatcher(this: IRequest); cdecl; +begin + //try + IRequestImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IRequestImpl_releaseDispatcher(this: IRequest): Integer; cdecl; +begin + //try + Result := IRequestImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IRequestImpl_receiveDispatcher(this: IRequest; status: IStatus; level: Integer; msgType: Cardinal; length: Cardinal; message: BytePtr); cdecl; +begin + //try + IRequestImpl(this).receive(status, level, msgType, length, message); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IRequestImpl_sendDispatcher(this: IRequest; status: IStatus; level: Integer; msgType: Cardinal; length: Cardinal; message: BytePtr); cdecl; +begin + //try + IRequestImpl(this).send(status, level, msgType, length, message); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IRequestImpl_getInfoDispatcher(this: IRequest; status: IStatus; level: Integer; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); cdecl; +begin + //try + IRequestImpl(this).getInfo(status, level, itemsLength, items, bufferLength, buffer); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IRequestImpl_startDispatcher(this: IRequest; status: IStatus; tra: ITransaction; level: Integer); cdecl; +begin + //try + IRequestImpl(this).start(status, tra, level); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IRequestImpl_startAndSendDispatcher(this: IRequest; status: IStatus; tra: ITransaction; level: Integer; msgType: Cardinal; length: Cardinal; message: BytePtr); cdecl; +begin + //try + IRequestImpl(this).startAndSend(status, tra, level, msgType, length, message); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IRequestImpl_unwindDispatcher(this: IRequest; status: IStatus; level: Integer); cdecl; +begin + //try + IRequestImpl(this).unwind(status, level); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IRequestImpl_freeDispatcher(this: IRequest; status: IStatus); cdecl; +begin + //try + IRequestImpl(this).free(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IRequestImpl_vTable: RequestVTable; + +constructor IRequestImpl.create; +begin + vTable := IRequestImpl_vTable; +end; + +procedure IEventsImpl_addRefDispatcher(this: IEvents); cdecl; +begin + //try + IEventsImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IEventsImpl_releaseDispatcher(this: IEvents): Integer; cdecl; +begin + //try + Result := IEventsImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IEventsImpl_cancelDispatcher(this: IEvents; status: IStatus); cdecl; +begin + //try + IEventsImpl(this).cancel(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IEventsImpl_vTable: EventsVTable; + +constructor IEventsImpl.create; +begin + vTable := IEventsImpl_vTable; +end; + +procedure IAttachmentImpl_addRefDispatcher(this: IAttachment); cdecl; +begin + //try + IAttachmentImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IAttachmentImpl_releaseDispatcher(this: IAttachment): Integer; cdecl; +begin + //try + Result := IAttachmentImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IAttachmentImpl_getInfoDispatcher(this: IAttachment; status: IStatus; itemsLength: Cardinal; items: BytePtr; bufferLength: Cardinal; buffer: BytePtr); cdecl; +begin + //try + IAttachmentImpl(this).getInfo(status, itemsLength, items, bufferLength, buffer); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IAttachmentImpl_startTransactionDispatcher(this: IAttachment; status: IStatus; tpbLength: Cardinal; tpb: BytePtr): ITransaction; cdecl; +begin + //try + Result := IAttachmentImpl(this).startTransaction(status, tpbLength, tpb); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IAttachmentImpl_reconnectTransactionDispatcher(this: IAttachment; status: IStatus; length: Cardinal; id: BytePtr): ITransaction; cdecl; +begin + //try + Result := IAttachmentImpl(this).reconnectTransaction(status, length, id); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IAttachmentImpl_compileRequestDispatcher(this: IAttachment; status: IStatus; blrLength: Cardinal; blr: BytePtr): IRequest; cdecl; +begin + //try + Result := IAttachmentImpl(this).compileRequest(status, blrLength, blr); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IAttachmentImpl_transactRequestDispatcher(this: IAttachment; status: IStatus; transaction: ITransaction; blrLength: Cardinal; blr: BytePtr; inMsgLength: Cardinal; inMsg: BytePtr; outMsgLength: Cardinal; outMsg: BytePtr); cdecl; +begin + //try + IAttachmentImpl(this).transactRequest(status, transaction, blrLength, blr, inMsgLength, inMsg, outMsgLength, outMsg); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IAttachmentImpl_createBlobDispatcher(this: IAttachment; status: IStatus; transaction: ITransaction; id: ISC_QUADPtr; bpbLength: Cardinal; bpb: BytePtr): IBlob; cdecl; +begin + //try + Result := IAttachmentImpl(this).createBlob(status, transaction, id, bpbLength, bpb); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IAttachmentImpl_openBlobDispatcher(this: IAttachment; status: IStatus; transaction: ITransaction; id: ISC_QUADPtr; bpbLength: Cardinal; bpb: BytePtr): IBlob; cdecl; +begin + //try + Result := IAttachmentImpl(this).openBlob(status, transaction, id, bpbLength, bpb); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IAttachmentImpl_getSliceDispatcher(this: IAttachment; status: IStatus; transaction: ITransaction; id: ISC_QUADPtr; sdlLength: Cardinal; sdl: BytePtr; paramLength: Cardinal; param: BytePtr; sliceLength: Integer; slice: BytePtr): Integer; cdecl; +begin + //try + Result := IAttachmentImpl(this).getSlice(status, transaction, id, sdlLength, sdl, paramLength, param, sliceLength, slice); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IAttachmentImpl_putSliceDispatcher(this: IAttachment; status: IStatus; transaction: ITransaction; id: ISC_QUADPtr; sdlLength: Cardinal; sdl: BytePtr; paramLength: Cardinal; param: BytePtr; sliceLength: Integer; slice: BytePtr); cdecl; +begin + //try + IAttachmentImpl(this).putSlice(status, transaction, id, sdlLength, sdl, paramLength, param, sliceLength, slice); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IAttachmentImpl_executeDynDispatcher(this: IAttachment; status: IStatus; transaction: ITransaction; length: Cardinal; dyn: BytePtr); cdecl; +begin + //try + IAttachmentImpl(this).executeDyn(status, transaction, length, dyn); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IAttachmentImpl_prepareDispatcher(this: IAttachment; status: IStatus; tra: ITransaction; stmtLength: Cardinal; sqlStmt: PAnsiChar; dialect: Cardinal; flags: Cardinal): IStatement; cdecl; +begin + //try + Result := IAttachmentImpl(this).prepare(status, tra, stmtLength, sqlStmt, dialect, flags); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IAttachmentImpl_executeDispatcher(this: IAttachment; status: IStatus; transaction: ITransaction; stmtLength: Cardinal; sqlStmt: PAnsiChar; dialect: Cardinal; inMetadata: IMessageMetadata; inBuffer: Pointer; outMetadata: IMessageMetadata; outBuffer: Pointer): ITransaction; cdecl; +begin + //try + Result := IAttachmentImpl(this).execute(status, transaction, stmtLength, sqlStmt, dialect, inMetadata, inBuffer, outMetadata, outBuffer); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IAttachmentImpl_openCursorDispatcher(this: IAttachment; status: IStatus; transaction: ITransaction; stmtLength: Cardinal; sqlStmt: PAnsiChar; dialect: Cardinal; inMetadata: IMessageMetadata; inBuffer: Pointer; outMetadata: IMessageMetadata; cursorName: PAnsiChar; cursorFlags: Cardinal): IResultSet; cdecl; +begin + //try + Result := IAttachmentImpl(this).openCursor(status, transaction, stmtLength, sqlStmt, dialect, inMetadata, inBuffer, outMetadata, cursorName, cursorFlags); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IAttachmentImpl_queEventsDispatcher(this: IAttachment; status: IStatus; callback: IEventCallback; length: Cardinal; events: BytePtr): IEvents; cdecl; +begin + //try + Result := IAttachmentImpl(this).queEvents(status, callback, length, events); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IAttachmentImpl_cancelOperationDispatcher(this: IAttachment; status: IStatus; option: Integer); cdecl; +begin + //try + IAttachmentImpl(this).cancelOperation(status, option); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IAttachmentImpl_pingDispatcher(this: IAttachment; status: IStatus); cdecl; +begin + //try + IAttachmentImpl(this).ping(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IAttachmentImpl_detachDispatcher(this: IAttachment; status: IStatus); cdecl; +begin + //try + IAttachmentImpl(this).detach(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IAttachmentImpl_dropDatabaseDispatcher(this: IAttachment; status: IStatus); cdecl; +begin + //try + IAttachmentImpl(this).dropDatabase(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IAttachmentImpl_vTable: AttachmentVTable; + +constructor IAttachmentImpl.create; +begin + vTable := IAttachmentImpl_vTable; +end; + +procedure IServiceImpl_addRefDispatcher(this: IService); cdecl; +begin + //try + IServiceImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IServiceImpl_releaseDispatcher(this: IService): Integer; cdecl; +begin + //try + Result := IServiceImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IServiceImpl_detachDispatcher(this: IService; status: IStatus); cdecl; +begin + //try + IServiceImpl(this).detach(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IServiceImpl_queryDispatcher(this: IService; status: IStatus; sendLength: Cardinal; sendItems: BytePtr; receiveLength: Cardinal; receiveItems: BytePtr; bufferLength: Cardinal; buffer: BytePtr); cdecl; +begin + //try + IServiceImpl(this).query(status, sendLength, sendItems, receiveLength, receiveItems, bufferLength, buffer); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IServiceImpl_startDispatcher(this: IService; status: IStatus; spbLength: Cardinal; spb: BytePtr); cdecl; +begin + //try + IServiceImpl(this).start(status, spbLength, spb); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IServiceImpl_vTable: ServiceVTable; + +constructor IServiceImpl.create; +begin + vTable := IServiceImpl_vTable; +end; + +procedure IProviderImpl_addRefDispatcher(this: IProvider); cdecl; +begin + //try + IProviderImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IProviderImpl_releaseDispatcher(this: IProvider): Integer; cdecl; +begin + //try + Result := IProviderImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IProviderImpl_setOwnerDispatcher(this: IProvider; r: IReferenceCounted); cdecl; +begin + //try + IProviderImpl(this).setOwner(r); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IProviderImpl_getOwnerDispatcher(this: IProvider): IReferenceCounted; cdecl; +begin + //try + Result := IProviderImpl(this).getOwner(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IProviderImpl_attachDatabaseDispatcher(this: IProvider; status: IStatus; fileName: PAnsiChar; dpbLength: Cardinal; dpb: BytePtr): IAttachment; cdecl; +begin + //try + Result := IProviderImpl(this).attachDatabase(status, fileName, dpbLength, dpb); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IProviderImpl_createDatabaseDispatcher(this: IProvider; status: IStatus; fileName: PAnsiChar; dpbLength: Cardinal; dpb: BytePtr): IAttachment; cdecl; +begin + //try + Result := IProviderImpl(this).createDatabase(status, fileName, dpbLength, dpb); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IProviderImpl_attachServiceManagerDispatcher(this: IProvider; status: IStatus; service: PAnsiChar; spbLength: Cardinal; spb: BytePtr): IService; cdecl; +begin + //try + Result := IProviderImpl(this).attachServiceManager(status, service, spbLength, spb); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IProviderImpl_shutdownDispatcher(this: IProvider; status: IStatus; timeout: Cardinal; reason: Integer); cdecl; +begin + //try + IProviderImpl(this).shutdown(status, timeout, reason); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IProviderImpl_setDbCryptCallbackDispatcher(this: IProvider; status: IStatus; cryptCallback: ICryptKeyCallback); cdecl; +begin + //try + IProviderImpl(this).setDbCryptCallback(status, cryptCallback); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IProviderImpl_vTable: ProviderVTable; + +constructor IProviderImpl.create; +begin + vTable := IProviderImpl_vTable; +end; + +procedure IDtcStartImpl_disposeDispatcher(this: IDtcStart); cdecl; +begin + //try + IDtcStartImpl(this).dispose(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IDtcStartImpl_addAttachmentDispatcher(this: IDtcStart; status: IStatus; att: IAttachment); cdecl; +begin + //try + IDtcStartImpl(this).addAttachment(status, att); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IDtcStartImpl_addWithTpbDispatcher(this: IDtcStart; status: IStatus; att: IAttachment; length: Cardinal; tpb: BytePtr); cdecl; +begin + //try + IDtcStartImpl(this).addWithTpb(status, att, length, tpb); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IDtcStartImpl_startDispatcher(this: IDtcStart; status: IStatus): ITransaction; cdecl; +begin + //try + Result := IDtcStartImpl(this).start(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IDtcStartImpl_vTable: DtcStartVTable; + +constructor IDtcStartImpl.create; +begin + vTable := IDtcStartImpl_vTable; +end; + +function IDtcImpl_joinDispatcher(this: IDtc; status: IStatus; one: ITransaction; two: ITransaction): ITransaction; cdecl; +begin + //try + Result := IDtcImpl(this).join(status, one, two); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IDtcImpl_startBuilderDispatcher(this: IDtc; status: IStatus): IDtcStart; cdecl; +begin + //try + Result := IDtcImpl(this).startBuilder(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IDtcImpl_vTable: DtcVTable; + +constructor IDtcImpl.create; +begin + vTable := IDtcImpl_vTable; +end; + +procedure IAuthImpl_addRefDispatcher(this: IAuth); cdecl; +begin + //try + IAuthImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IAuthImpl_releaseDispatcher(this: IAuth): Integer; cdecl; +begin + //try + Result := IAuthImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IAuthImpl_setOwnerDispatcher(this: IAuth; r: IReferenceCounted); cdecl; +begin + //try + IAuthImpl(this).setOwner(r); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IAuthImpl_getOwnerDispatcher(this: IAuth): IReferenceCounted; cdecl; +begin + //try + Result := IAuthImpl(this).getOwner(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + IAuthImpl_vTable: AuthVTable; + +constructor IAuthImpl.create; +begin + vTable := IAuthImpl_vTable; +end; + +procedure IWriterImpl_resetDispatcher(this: IWriter); cdecl; +begin + //try + IWriterImpl(this).reset(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IWriterImpl_addDispatcher(this: IWriter; status: IStatus; name: PAnsiChar); cdecl; +begin + //try + IWriterImpl(this).add(status, name); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IWriterImpl_setTypeDispatcher(this: IWriter; status: IStatus; value: PAnsiChar); cdecl; +begin + //try + IWriterImpl(this).setType(status, value); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IWriterImpl_setDbDispatcher(this: IWriter; status: IStatus; value: PAnsiChar); cdecl; +begin + //try + IWriterImpl(this).setDb(status, value); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IWriterImpl_vTable: WriterVTable; + +constructor IWriterImpl.create; +begin + vTable := IWriterImpl_vTable; +end; + +function IServerBlockImpl_getLoginDispatcher(this: IServerBlock): PAnsiChar; cdecl; +begin + //try + Result := IServerBlockImpl(this).getLogin(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IServerBlockImpl_getDataDispatcher(this: IServerBlock; length: CardinalPtr): BytePtr; cdecl; +begin + //try + Result := IServerBlockImpl(this).getData(length); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IServerBlockImpl_putDataDispatcher(this: IServerBlock; status: IStatus; length: Cardinal; data: Pointer); cdecl; +begin + //try + IServerBlockImpl(this).putData(status, length, data); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IServerBlockImpl_newKeyDispatcher(this: IServerBlock; status: IStatus): ICryptKey; cdecl; +begin + //try + Result := IServerBlockImpl(this).newKey(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IServerBlockImpl_vTable: ServerBlockVTable; + +constructor IServerBlockImpl.create; +begin + vTable := IServerBlockImpl_vTable; +end; + +procedure IClientBlockImpl_addRefDispatcher(this: IClientBlock); cdecl; +begin + //try + IClientBlockImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IClientBlockImpl_releaseDispatcher(this: IClientBlock): Integer; cdecl; +begin + //try + Result := IClientBlockImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IClientBlockImpl_getLoginDispatcher(this: IClientBlock): PAnsiChar; cdecl; +begin + //try + Result := IClientBlockImpl(this).getLogin(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IClientBlockImpl_getPasswordDispatcher(this: IClientBlock): PAnsiChar; cdecl; +begin + //try + Result := IClientBlockImpl(this).getPassword(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IClientBlockImpl_getDataDispatcher(this: IClientBlock; length: CardinalPtr): BytePtr; cdecl; +begin + //try + Result := IClientBlockImpl(this).getData(length); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IClientBlockImpl_putDataDispatcher(this: IClientBlock; status: IStatus; length: Cardinal; data: Pointer); cdecl; +begin + //try + IClientBlockImpl(this).putData(status, length, data); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IClientBlockImpl_newKeyDispatcher(this: IClientBlock; status: IStatus): ICryptKey; cdecl; +begin + //try + Result := IClientBlockImpl(this).newKey(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IClientBlockImpl_vTable: ClientBlockVTable; + +constructor IClientBlockImpl.create; +begin + vTable := IClientBlockImpl_vTable; +end; + +procedure IServerImpl_addRefDispatcher(this: IServer); cdecl; +begin + //try + IServerImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IServerImpl_releaseDispatcher(this: IServer): Integer; cdecl; +begin + //try + Result := IServerImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IServerImpl_setOwnerDispatcher(this: IServer; r: IReferenceCounted); cdecl; +begin + //try + IServerImpl(this).setOwner(r); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IServerImpl_getOwnerDispatcher(this: IServer): IReferenceCounted; cdecl; +begin + //try + Result := IServerImpl(this).getOwner(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IServerImpl_authenticateDispatcher(this: IServer; status: IStatus; sBlock: IServerBlock; writerInterface: IWriter): Integer; cdecl; +begin + //try + Result := IServerImpl(this).authenticate(status, sBlock, writerInterface); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IServerImpl_vTable: ServerVTable; + +constructor IServerImpl.create; +begin + vTable := IServerImpl_vTable; +end; + +procedure IClientImpl_addRefDispatcher(this: IClient); cdecl; +begin + //try + IClientImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IClientImpl_releaseDispatcher(this: IClient): Integer; cdecl; +begin + //try + Result := IClientImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IClientImpl_setOwnerDispatcher(this: IClient; r: IReferenceCounted); cdecl; +begin + //try + IClientImpl(this).setOwner(r); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IClientImpl_getOwnerDispatcher(this: IClient): IReferenceCounted; cdecl; +begin + //try + Result := IClientImpl(this).getOwner(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IClientImpl_authenticateDispatcher(this: IClient; status: IStatus; cBlock: IClientBlock): Integer; cdecl; +begin + //try + Result := IClientImpl(this).authenticate(status, cBlock); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IClientImpl_vTable: ClientVTable; + +constructor IClientImpl.create; +begin + vTable := IClientImpl_vTable; +end; + +function IUserFieldImpl_enteredDispatcher(this: IUserField): Integer; cdecl; +begin + //try + Result := IUserFieldImpl(this).entered(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IUserFieldImpl_specifiedDispatcher(this: IUserField): Integer; cdecl; +begin + //try + Result := IUserFieldImpl(this).specified(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IUserFieldImpl_setEnteredDispatcher(this: IUserField; status: IStatus; newValue: Integer); cdecl; +begin + //try + IUserFieldImpl(this).setEntered(status, newValue); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IUserFieldImpl_vTable: UserFieldVTable; + +constructor IUserFieldImpl.create; +begin + vTable := IUserFieldImpl_vTable; +end; + +function ICharUserFieldImpl_enteredDispatcher(this: ICharUserField): Integer; cdecl; +begin + //try + Result := ICharUserFieldImpl(this).entered(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ICharUserFieldImpl_specifiedDispatcher(this: ICharUserField): Integer; cdecl; +begin + //try + Result := ICharUserFieldImpl(this).specified(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure ICharUserFieldImpl_setEnteredDispatcher(this: ICharUserField; status: IStatus; newValue: Integer); cdecl; +begin + //try + ICharUserFieldImpl(this).setEntered(status, newValue); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function ICharUserFieldImpl_getDispatcher(this: ICharUserField): PAnsiChar; cdecl; +begin + //try + Result := ICharUserFieldImpl(this).get(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure ICharUserFieldImpl_set_Dispatcher(this: ICharUserField; status: IStatus; newValue: PAnsiChar); cdecl; +begin + //try + ICharUserFieldImpl(this).set_(status, newValue); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + ICharUserFieldImpl_vTable: CharUserFieldVTable; + +constructor ICharUserFieldImpl.create; +begin + vTable := ICharUserFieldImpl_vTable; +end; + +function IIntUserFieldImpl_enteredDispatcher(this: IIntUserField): Integer; cdecl; +begin + //try + Result := IIntUserFieldImpl(this).entered(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IIntUserFieldImpl_specifiedDispatcher(this: IIntUserField): Integer; cdecl; +begin + //try + Result := IIntUserFieldImpl(this).specified(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IIntUserFieldImpl_setEnteredDispatcher(this: IIntUserField; status: IStatus; newValue: Integer); cdecl; +begin + //try + IIntUserFieldImpl(this).setEntered(status, newValue); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IIntUserFieldImpl_getDispatcher(this: IIntUserField): Integer; cdecl; +begin + //try + Result := IIntUserFieldImpl(this).get(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IIntUserFieldImpl_set_Dispatcher(this: IIntUserField; status: IStatus; newValue: Integer); cdecl; +begin + //try + IIntUserFieldImpl(this).set_(status, newValue); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IIntUserFieldImpl_vTable: IntUserFieldVTable; + +constructor IIntUserFieldImpl.create; +begin + vTable := IIntUserFieldImpl_vTable; +end; + +function IUserImpl_operationDispatcher(this: IUser): Cardinal; cdecl; +begin + //try + Result := IUserImpl(this).operation(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IUserImpl_userNameDispatcher(this: IUser): ICharUserField; cdecl; +begin + //try + Result := IUserImpl(this).userName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IUserImpl_passwordDispatcher(this: IUser): ICharUserField; cdecl; +begin + //try + Result := IUserImpl(this).password(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IUserImpl_firstNameDispatcher(this: IUser): ICharUserField; cdecl; +begin + //try + Result := IUserImpl(this).firstName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IUserImpl_lastNameDispatcher(this: IUser): ICharUserField; cdecl; +begin + //try + Result := IUserImpl(this).lastName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IUserImpl_middleNameDispatcher(this: IUser): ICharUserField; cdecl; +begin + //try + Result := IUserImpl(this).middleName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IUserImpl_commentDispatcher(this: IUser): ICharUserField; cdecl; +begin + //try + Result := IUserImpl(this).comment(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IUserImpl_attributesDispatcher(this: IUser): ICharUserField; cdecl; +begin + //try + Result := IUserImpl(this).attributes(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IUserImpl_activeDispatcher(this: IUser): IIntUserField; cdecl; +begin + //try + Result := IUserImpl(this).active(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IUserImpl_adminDispatcher(this: IUser): IIntUserField; cdecl; +begin + //try + Result := IUserImpl(this).admin(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IUserImpl_clearDispatcher(this: IUser; status: IStatus); cdecl; +begin + //try + IUserImpl(this).clear(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IUserImpl_vTable: UserVTable; + +constructor IUserImpl.create; +begin + vTable := IUserImpl_vTable; +end; + +procedure IListUsersImpl_listDispatcher(this: IListUsers; status: IStatus; user: IUser); cdecl; +begin + //try + IListUsersImpl(this).list(status, user); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IListUsersImpl_vTable: ListUsersVTable; + +constructor IListUsersImpl.create; +begin + vTable := IListUsersImpl_vTable; +end; + +function ILogonInfoImpl_nameDispatcher(this: ILogonInfo): PAnsiChar; cdecl; +begin + //try + Result := ILogonInfoImpl(this).name(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ILogonInfoImpl_roleDispatcher(this: ILogonInfo): PAnsiChar; cdecl; +begin + //try + Result := ILogonInfoImpl(this).role(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ILogonInfoImpl_networkProtocolDispatcher(this: ILogonInfo): PAnsiChar; cdecl; +begin + //try + Result := ILogonInfoImpl(this).networkProtocol(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ILogonInfoImpl_remoteAddressDispatcher(this: ILogonInfo): PAnsiChar; cdecl; +begin + //try + Result := ILogonInfoImpl(this).remoteAddress(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ILogonInfoImpl_authBlockDispatcher(this: ILogonInfo; length: CardinalPtr): BytePtr; cdecl; +begin + //try + Result := ILogonInfoImpl(this).authBlock(length); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ILogonInfoImpl_vTable: LogonInfoVTable; + +constructor ILogonInfoImpl.create; +begin + vTable := ILogonInfoImpl_vTable; +end; + +procedure IManagementImpl_addRefDispatcher(this: IManagement); cdecl; +begin + //try + IManagementImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IManagementImpl_releaseDispatcher(this: IManagement): Integer; cdecl; +begin + //try + Result := IManagementImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IManagementImpl_setOwnerDispatcher(this: IManagement; r: IReferenceCounted); cdecl; +begin + //try + IManagementImpl(this).setOwner(r); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IManagementImpl_getOwnerDispatcher(this: IManagement): IReferenceCounted; cdecl; +begin + //try + Result := IManagementImpl(this).getOwner(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IManagementImpl_startDispatcher(this: IManagement; status: IStatus; logonInfo: ILogonInfo); cdecl; +begin + //try + IManagementImpl(this).start(status, logonInfo); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IManagementImpl_executeDispatcher(this: IManagement; status: IStatus; user: IUser; callback: IListUsers): Integer; cdecl; +begin + //try + Result := IManagementImpl(this).execute(status, user, callback); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IManagementImpl_commitDispatcher(this: IManagement; status: IStatus); cdecl; +begin + //try + IManagementImpl(this).commit(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IManagementImpl_rollbackDispatcher(this: IManagement; status: IStatus); cdecl; +begin + //try + IManagementImpl(this).rollback(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IManagementImpl_vTable: ManagementVTable; + +constructor IManagementImpl.create; +begin + vTable := IManagementImpl_vTable; +end; + +procedure IWireCryptPluginImpl_addRefDispatcher(this: IWireCryptPlugin); cdecl; +begin + //try + IWireCryptPluginImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IWireCryptPluginImpl_releaseDispatcher(this: IWireCryptPlugin): Integer; cdecl; +begin + //try + Result := IWireCryptPluginImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IWireCryptPluginImpl_setOwnerDispatcher(this: IWireCryptPlugin; r: IReferenceCounted); cdecl; +begin + //try + IWireCryptPluginImpl(this).setOwner(r); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IWireCryptPluginImpl_getOwnerDispatcher(this: IWireCryptPlugin): IReferenceCounted; cdecl; +begin + //try + Result := IWireCryptPluginImpl(this).getOwner(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IWireCryptPluginImpl_getKnownTypesDispatcher(this: IWireCryptPlugin; status: IStatus): PAnsiChar; cdecl; +begin + //try + Result := IWireCryptPluginImpl(this).getKnownTypes(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IWireCryptPluginImpl_setKeyDispatcher(this: IWireCryptPlugin; status: IStatus; key: ICryptKey); cdecl; +begin + //try + IWireCryptPluginImpl(this).setKey(status, key); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IWireCryptPluginImpl_encryptDispatcher(this: IWireCryptPlugin; status: IStatus; length: Cardinal; from: Pointer; to_: Pointer); cdecl; +begin + //try + IWireCryptPluginImpl(this).encrypt(status, length, from, to_); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IWireCryptPluginImpl_decryptDispatcher(this: IWireCryptPlugin; status: IStatus; length: Cardinal; from: Pointer; to_: Pointer); cdecl; +begin + //try + IWireCryptPluginImpl(this).decrypt(status, length, from, to_); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IWireCryptPluginImpl_vTable: WireCryptPluginVTable; + +constructor IWireCryptPluginImpl.create; +begin + vTable := IWireCryptPluginImpl_vTable; +end; + +function ICryptKeyCallbackImpl_callbackDispatcher(this: ICryptKeyCallback; dataLength: Cardinal; data: Pointer; bufferLength: Cardinal; buffer: Pointer): Cardinal; cdecl; +begin + //try + Result := ICryptKeyCallbackImpl(this).callback(dataLength, data, bufferLength, buffer); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ICryptKeyCallbackImpl_vTable: CryptKeyCallbackVTable; + +constructor ICryptKeyCallbackImpl.create; +begin + vTable := ICryptKeyCallbackImpl_vTable; +end; + +procedure IKeyHolderPluginImpl_addRefDispatcher(this: IKeyHolderPlugin); cdecl; +begin + //try + IKeyHolderPluginImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IKeyHolderPluginImpl_releaseDispatcher(this: IKeyHolderPlugin): Integer; cdecl; +begin + //try + Result := IKeyHolderPluginImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IKeyHolderPluginImpl_setOwnerDispatcher(this: IKeyHolderPlugin; r: IReferenceCounted); cdecl; +begin + //try + IKeyHolderPluginImpl(this).setOwner(r); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IKeyHolderPluginImpl_getOwnerDispatcher(this: IKeyHolderPlugin): IReferenceCounted; cdecl; +begin + //try + Result := IKeyHolderPluginImpl(this).getOwner(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IKeyHolderPluginImpl_keyCallbackDispatcher(this: IKeyHolderPlugin; status: IStatus; callback: ICryptKeyCallback): Integer; cdecl; +begin + //try + Result := IKeyHolderPluginImpl(this).keyCallback(status, callback); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IKeyHolderPluginImpl_keyHandleDispatcher(this: IKeyHolderPlugin; status: IStatus; keyName: PAnsiChar): ICryptKeyCallback; cdecl; +begin + //try + Result := IKeyHolderPluginImpl(this).keyHandle(status, keyName); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IKeyHolderPluginImpl_vTable: KeyHolderPluginVTable; + +constructor IKeyHolderPluginImpl.create; +begin + vTable := IKeyHolderPluginImpl_vTable; +end; + +procedure IDbCryptPluginImpl_addRefDispatcher(this: IDbCryptPlugin); cdecl; +begin + //try + IDbCryptPluginImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IDbCryptPluginImpl_releaseDispatcher(this: IDbCryptPlugin): Integer; cdecl; +begin + //try + Result := IDbCryptPluginImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IDbCryptPluginImpl_setOwnerDispatcher(this: IDbCryptPlugin; r: IReferenceCounted); cdecl; +begin + //try + IDbCryptPluginImpl(this).setOwner(r); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IDbCryptPluginImpl_getOwnerDispatcher(this: IDbCryptPlugin): IReferenceCounted; cdecl; +begin + //try + Result := IDbCryptPluginImpl(this).getOwner(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IDbCryptPluginImpl_setKeyDispatcher(this: IDbCryptPlugin; status: IStatus; length: Cardinal; sources: IKeyHolderPluginPtr; keyName: PAnsiChar); cdecl; +begin + //try + IDbCryptPluginImpl(this).setKey(status, length, sources, keyName); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IDbCryptPluginImpl_encryptDispatcher(this: IDbCryptPlugin; status: IStatus; length: Cardinal; from: Pointer; to_: Pointer); cdecl; +begin + //try + IDbCryptPluginImpl(this).encrypt(status, length, from, to_); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IDbCryptPluginImpl_decryptDispatcher(this: IDbCryptPlugin; status: IStatus; length: Cardinal; from: Pointer; to_: Pointer); cdecl; +begin + //try + IDbCryptPluginImpl(this).decrypt(status, length, from, to_); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IDbCryptPluginImpl_vTable: DbCryptPluginVTable; + +constructor IDbCryptPluginImpl.create; +begin + vTable := IDbCryptPluginImpl_vTable; +end; + +function IExternalContextImpl_getMasterDispatcher(this: IExternalContext): IMaster; cdecl; +begin + //try + Result := IExternalContextImpl(this).getMaster(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IExternalContextImpl_getEngineDispatcher(this: IExternalContext; status: IStatus): IExternalEngine; cdecl; +begin + //try + Result := IExternalContextImpl(this).getEngine(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IExternalContextImpl_getAttachmentDispatcher(this: IExternalContext; status: IStatus): IAttachment; cdecl; +begin + //try + Result := IExternalContextImpl(this).getAttachment(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IExternalContextImpl_getTransactionDispatcher(this: IExternalContext; status: IStatus): ITransaction; cdecl; +begin + //try + Result := IExternalContextImpl(this).getTransaction(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IExternalContextImpl_getUserNameDispatcher(this: IExternalContext): PAnsiChar; cdecl; +begin + //try + Result := IExternalContextImpl(this).getUserName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IExternalContextImpl_getDatabaseNameDispatcher(this: IExternalContext): PAnsiChar; cdecl; +begin + //try + Result := IExternalContextImpl(this).getDatabaseName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IExternalContextImpl_getClientCharSetDispatcher(this: IExternalContext): PAnsiChar; cdecl; +begin + //try + Result := IExternalContextImpl(this).getClientCharSet(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IExternalContextImpl_obtainInfoCodeDispatcher(this: IExternalContext): Integer; cdecl; +begin + //try + Result := IExternalContextImpl(this).obtainInfoCode(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IExternalContextImpl_getInfoDispatcher(this: IExternalContext; code: Integer): Pointer; cdecl; +begin + //try + Result := IExternalContextImpl(this).getInfo(code); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IExternalContextImpl_setInfoDispatcher(this: IExternalContext; code: Integer; value: Pointer): Pointer; cdecl; +begin + //try + Result := IExternalContextImpl(this).setInfo(code, value); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + IExternalContextImpl_vTable: ExternalContextVTable; + +constructor IExternalContextImpl.create; +begin + vTable := IExternalContextImpl_vTable; +end; + +procedure IExternalResultSetImpl_disposeDispatcher(this: IExternalResultSet); cdecl; +begin + //try + IExternalResultSetImpl(this).dispose(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IExternalResultSetImpl_fetchDispatcher(this: IExternalResultSet; status: IStatus): Boolean; cdecl; +begin + //try + Result := IExternalResultSetImpl(this).fetch(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IExternalResultSetImpl_vTable: ExternalResultSetVTable; + +constructor IExternalResultSetImpl.create; +begin + vTable := IExternalResultSetImpl_vTable; +end; + +procedure IExternalFunctionImpl_disposeDispatcher(this: IExternalFunction); cdecl; +begin + //try + IExternalFunctionImpl(this).dispose(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IExternalFunctionImpl_getCharSetDispatcher(this: IExternalFunction; status: IStatus; context: IExternalContext; name: PAnsiChar; nameSize: Cardinal); cdecl; +begin + //try + IExternalFunctionImpl(this).getCharSet(status, context, name, nameSize); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IExternalFunctionImpl_executeDispatcher(this: IExternalFunction; status: IStatus; context: IExternalContext; inMsg: Pointer; outMsg: Pointer); cdecl; +begin + //try + IExternalFunctionImpl(this).execute(status, context, inMsg, outMsg); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IExternalFunctionImpl_vTable: ExternalFunctionVTable; + +constructor IExternalFunctionImpl.create; +begin + vTable := IExternalFunctionImpl_vTable; +end; + +procedure IExternalProcedureImpl_disposeDispatcher(this: IExternalProcedure); cdecl; +begin + //try + IExternalProcedureImpl(this).dispose(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IExternalProcedureImpl_getCharSetDispatcher(this: IExternalProcedure; status: IStatus; context: IExternalContext; name: PAnsiChar; nameSize: Cardinal); cdecl; +begin + //try + IExternalProcedureImpl(this).getCharSet(status, context, name, nameSize); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IExternalProcedureImpl_openDispatcher(this: IExternalProcedure; status: IStatus; context: IExternalContext; inMsg: Pointer; outMsg: Pointer): IExternalResultSet; cdecl; +begin + //try + Result := IExternalProcedureImpl(this).open(status, context, inMsg, outMsg); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IExternalProcedureImpl_vTable: ExternalProcedureVTable; + +constructor IExternalProcedureImpl.create; +begin + vTable := IExternalProcedureImpl_vTable; +end; + +procedure IExternalTriggerImpl_disposeDispatcher(this: IExternalTrigger); cdecl; +begin + //try + IExternalTriggerImpl(this).dispose(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IExternalTriggerImpl_getCharSetDispatcher(this: IExternalTrigger; status: IStatus; context: IExternalContext; name: PAnsiChar; nameSize: Cardinal); cdecl; +begin + //try + IExternalTriggerImpl(this).getCharSet(status, context, name, nameSize); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IExternalTriggerImpl_executeDispatcher(this: IExternalTrigger; status: IStatus; context: IExternalContext; action: Cardinal; oldMsg: Pointer; newMsg: Pointer); cdecl; +begin + //try + IExternalTriggerImpl(this).execute(status, context, action, oldMsg, newMsg); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IExternalTriggerImpl_vTable: ExternalTriggerVTable; + +constructor IExternalTriggerImpl.create; +begin + vTable := IExternalTriggerImpl_vTable; +end; + +function IRoutineMetadataImpl_getPackageDispatcher(this: IRoutineMetadata; status: IStatus): PAnsiChar; cdecl; +begin + //try + Result := IRoutineMetadataImpl(this).getPackage(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IRoutineMetadataImpl_getNameDispatcher(this: IRoutineMetadata; status: IStatus): PAnsiChar; cdecl; +begin + //try + Result := IRoutineMetadataImpl(this).getName(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IRoutineMetadataImpl_getEntryPointDispatcher(this: IRoutineMetadata; status: IStatus): PAnsiChar; cdecl; +begin + //try + Result := IRoutineMetadataImpl(this).getEntryPoint(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IRoutineMetadataImpl_getBodyDispatcher(this: IRoutineMetadata; status: IStatus): PAnsiChar; cdecl; +begin + //try + Result := IRoutineMetadataImpl(this).getBody(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IRoutineMetadataImpl_getInputMetadataDispatcher(this: IRoutineMetadata; status: IStatus): IMessageMetadata; cdecl; +begin + //try + Result := IRoutineMetadataImpl(this).getInputMetadata(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IRoutineMetadataImpl_getOutputMetadataDispatcher(this: IRoutineMetadata; status: IStatus): IMessageMetadata; cdecl; +begin + //try + Result := IRoutineMetadataImpl(this).getOutputMetadata(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IRoutineMetadataImpl_getTriggerMetadataDispatcher(this: IRoutineMetadata; status: IStatus): IMessageMetadata; cdecl; +begin + //try + Result := IRoutineMetadataImpl(this).getTriggerMetadata(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IRoutineMetadataImpl_getTriggerTableDispatcher(this: IRoutineMetadata; status: IStatus): PAnsiChar; cdecl; +begin + //try + Result := IRoutineMetadataImpl(this).getTriggerTable(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IRoutineMetadataImpl_getTriggerTypeDispatcher(this: IRoutineMetadata; status: IStatus): Cardinal; cdecl; +begin + //try + Result := IRoutineMetadataImpl(this).getTriggerType(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IRoutineMetadataImpl_vTable: RoutineMetadataVTable; + +constructor IRoutineMetadataImpl.create; +begin + vTable := IRoutineMetadataImpl_vTable; +end; + +procedure IExternalEngineImpl_addRefDispatcher(this: IExternalEngine); cdecl; +begin + //try + IExternalEngineImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IExternalEngineImpl_releaseDispatcher(this: IExternalEngine): Integer; cdecl; +begin + //try + Result := IExternalEngineImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IExternalEngineImpl_setOwnerDispatcher(this: IExternalEngine; r: IReferenceCounted); cdecl; +begin + //try + IExternalEngineImpl(this).setOwner(r); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IExternalEngineImpl_getOwnerDispatcher(this: IExternalEngine): IReferenceCounted; cdecl; +begin + //try + Result := IExternalEngineImpl(this).getOwner(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IExternalEngineImpl_openDispatcher(this: IExternalEngine; status: IStatus; context: IExternalContext; charSet: PAnsiChar; charSetSize: Cardinal); cdecl; +begin + //try + IExternalEngineImpl(this).open(status, context, charSet, charSetSize); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IExternalEngineImpl_openAttachmentDispatcher(this: IExternalEngine; status: IStatus; context: IExternalContext); cdecl; +begin + //try + IExternalEngineImpl(this).openAttachment(status, context); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IExternalEngineImpl_closeAttachmentDispatcher(this: IExternalEngine; status: IStatus; context: IExternalContext); cdecl; +begin + //try + IExternalEngineImpl(this).closeAttachment(status, context); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IExternalEngineImpl_makeFunctionDispatcher(this: IExternalEngine; status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder): IExternalFunction; cdecl; +begin + //try + Result := IExternalEngineImpl(this).makeFunction(status, context, metadata, inBuilder, outBuilder); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IExternalEngineImpl_makeProcedureDispatcher(this: IExternalEngine; status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder): IExternalProcedure; cdecl; +begin + //try + Result := IExternalEngineImpl(this).makeProcedure(status, context, metadata, inBuilder, outBuilder); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IExternalEngineImpl_makeTriggerDispatcher(this: IExternalEngine; status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; fieldsBuilder: IMetadataBuilder): IExternalTrigger; cdecl; +begin + //try + Result := IExternalEngineImpl(this).makeTrigger(status, context, metadata, fieldsBuilder); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IExternalEngineImpl_vTable: ExternalEngineVTable; + +constructor IExternalEngineImpl.create; +begin + vTable := IExternalEngineImpl_vTable; +end; + +procedure ITimerImpl_addRefDispatcher(this: ITimer); cdecl; +begin + //try + ITimerImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITimerImpl_releaseDispatcher(this: ITimer): Integer; cdecl; +begin + //try + Result := ITimerImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure ITimerImpl_handlerDispatcher(this: ITimer); cdecl; +begin + //try + ITimerImpl(this).handler(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ITimerImpl_vTable: TimerVTable; + +constructor ITimerImpl.create; +begin + vTable := ITimerImpl_vTable; +end; + +procedure ITimerControlImpl_startDispatcher(this: ITimerControl; status: IStatus; timer: ITimer; microSeconds: QWord); cdecl; +begin + //try + ITimerControlImpl(this).start(status, timer, microSeconds); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure ITimerControlImpl_stopDispatcher(this: ITimerControl; status: IStatus; timer: ITimer); cdecl; +begin + //try + ITimerControlImpl(this).stop(status, timer); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + ITimerControlImpl_vTable: TimerControlVTable; + +constructor ITimerControlImpl.create; +begin + vTable := ITimerControlImpl_vTable; +end; + +procedure IVersionCallbackImpl_callbackDispatcher(this: IVersionCallback; status: IStatus; text: PAnsiChar); cdecl; +begin + //try + IVersionCallbackImpl(this).callback(status, text); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IVersionCallbackImpl_vTable: VersionCallbackVTable; + +constructor IVersionCallbackImpl.create; +begin + vTable := IVersionCallbackImpl_vTable; +end; + +procedure IUtilImpl_getFbVersionDispatcher(this: IUtil; status: IStatus; att: IAttachment; callback: IVersionCallback); cdecl; +begin + //try + IUtilImpl(this).getFbVersion(status, att, callback); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IUtilImpl_loadBlobDispatcher(this: IUtil; status: IStatus; blobId: ISC_QUADPtr; att: IAttachment; tra: ITransaction; file_: PAnsiChar; txt: Boolean); cdecl; +begin + //try + IUtilImpl(this).loadBlob(status, blobId, att, tra, file_, txt); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IUtilImpl_dumpBlobDispatcher(this: IUtil; status: IStatus; blobId: ISC_QUADPtr; att: IAttachment; tra: ITransaction; file_: PAnsiChar; txt: Boolean); cdecl; +begin + //try + IUtilImpl(this).dumpBlob(status, blobId, att, tra, file_, txt); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IUtilImpl_getPerfCountersDispatcher(this: IUtil; status: IStatus; att: IAttachment; countersSet: PAnsiChar; counters: Int64Ptr); cdecl; +begin + //try + IUtilImpl(this).getPerfCounters(status, att, countersSet, counters); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IUtilImpl_executeCreateDatabaseDispatcher(this: IUtil; status: IStatus; stmtLength: Cardinal; creatDBstatement: PAnsiChar; dialect: Cardinal; stmtIsCreateDb: BooleanPtr): IAttachment; cdecl; +begin + //try + Result := IUtilImpl(this).executeCreateDatabase(status, stmtLength, creatDBstatement, dialect, stmtIsCreateDb); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IUtilImpl_decodeDateDispatcher(this: IUtil; date: ISC_DATE; year: CardinalPtr; month: CardinalPtr; day: CardinalPtr); cdecl; +begin + //try + IUtilImpl(this).decodeDate(date, year, month, day); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IUtilImpl_decodeTimeDispatcher(this: IUtil; time: ISC_TIME; hours: CardinalPtr; minutes: CardinalPtr; seconds: CardinalPtr; fractions: CardinalPtr); cdecl; +begin + //try + IUtilImpl(this).decodeTime(time, hours, minutes, seconds, fractions); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IUtilImpl_encodeDateDispatcher(this: IUtil; year: Cardinal; month: Cardinal; day: Cardinal): ISC_DATE; cdecl; +begin + //try + Result := IUtilImpl(this).encodeDate(year, month, day); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IUtilImpl_encodeTimeDispatcher(this: IUtil; hours: Cardinal; minutes: Cardinal; seconds: Cardinal; fractions: Cardinal): ISC_TIME; cdecl; +begin + //try + Result := IUtilImpl(this).encodeTime(hours, minutes, seconds, fractions); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IUtilImpl_formatStatusDispatcher(this: IUtil; buffer: PAnsiChar; bufferSize: Cardinal; status: IStatus): Cardinal; cdecl; +begin + //try + Result := IUtilImpl(this).formatStatus(buffer, bufferSize, status); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IUtilImpl_getClientVersionDispatcher(this: IUtil): Cardinal; cdecl; +begin + //try + Result := IUtilImpl(this).getClientVersion(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function IUtilImpl_getXpbBuilderDispatcher(this: IUtil; status: IStatus; kind: Cardinal; buf: BytePtr; len: Cardinal): IXpbBuilder; cdecl; +begin + //try + Result := IUtilImpl(this).getXpbBuilder(status, kind, buf, len); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IUtilImpl_setOffsetsDispatcher(this: IUtil; status: IStatus; metadata: IMessageMetadata; callback: IOffsetsCallback): Cardinal; cdecl; +begin + //try + Result := IUtilImpl(this).setOffsets(status, metadata, callback); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IUtilImpl_vTable: UtilVTable; + +constructor IUtilImpl.create; +begin + vTable := IUtilImpl_vTable; +end; + +procedure IOffsetsCallbackImpl_setOffsetDispatcher(this: IOffsetsCallback; status: IStatus; index: Cardinal; offset: Cardinal; nullOffset: Cardinal); cdecl; +begin + //try + IOffsetsCallbackImpl(this).setOffset(status, index, offset, nullOffset); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IOffsetsCallbackImpl_vTable: OffsetsCallbackVTable; + +constructor IOffsetsCallbackImpl.create; +begin + vTable := IOffsetsCallbackImpl_vTable; +end; + +procedure IXpbBuilderImpl_disposeDispatcher(this: IXpbBuilder); cdecl; +begin + //try + IXpbBuilderImpl(this).dispose(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IXpbBuilderImpl_clearDispatcher(this: IXpbBuilder; status: IStatus); cdecl; +begin + //try + IXpbBuilderImpl(this).clear(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IXpbBuilderImpl_removeCurrentDispatcher(this: IXpbBuilder; status: IStatus); cdecl; +begin + //try + IXpbBuilderImpl(this).removeCurrent(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IXpbBuilderImpl_insertIntDispatcher(this: IXpbBuilder; status: IStatus; tag: Byte; value: Integer); cdecl; +begin + //try + IXpbBuilderImpl(this).insertInt(status, tag, value); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IXpbBuilderImpl_insertBigIntDispatcher(this: IXpbBuilder; status: IStatus; tag: Byte; value: Int64); cdecl; +begin + //try + IXpbBuilderImpl(this).insertBigInt(status, tag, value); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IXpbBuilderImpl_insertBytesDispatcher(this: IXpbBuilder; status: IStatus; tag: Byte; bytes: Pointer; length: Cardinal); cdecl; +begin + //try + IXpbBuilderImpl(this).insertBytes(status, tag, bytes, length); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IXpbBuilderImpl_insertStringDispatcher(this: IXpbBuilder; status: IStatus; tag: Byte; str: PAnsiChar); cdecl; +begin + //try + IXpbBuilderImpl(this).insertString(status, tag, str); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IXpbBuilderImpl_insertTagDispatcher(this: IXpbBuilder; status: IStatus; tag: Byte); cdecl; +begin + //try + IXpbBuilderImpl(this).insertTag(status, tag); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IXpbBuilderImpl_isEofDispatcher(this: IXpbBuilder; status: IStatus): Boolean; cdecl; +begin + //try + Result := IXpbBuilderImpl(this).isEof(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IXpbBuilderImpl_moveNextDispatcher(this: IXpbBuilder; status: IStatus); cdecl; +begin + //try + IXpbBuilderImpl(this).moveNext(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IXpbBuilderImpl_rewindDispatcher(this: IXpbBuilder; status: IStatus); cdecl; +begin + //try + IXpbBuilderImpl(this).rewind(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IXpbBuilderImpl_findFirstDispatcher(this: IXpbBuilder; status: IStatus; tag: Byte): Boolean; cdecl; +begin + //try + Result := IXpbBuilderImpl(this).findFirst(status, tag); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IXpbBuilderImpl_findNextDispatcher(this: IXpbBuilder; status: IStatus): Boolean; cdecl; +begin + //try + Result := IXpbBuilderImpl(this).findNext(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IXpbBuilderImpl_getTagDispatcher(this: IXpbBuilder; status: IStatus): Byte; cdecl; +begin + //try + Result := IXpbBuilderImpl(this).getTag(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IXpbBuilderImpl_getLengthDispatcher(this: IXpbBuilder; status: IStatus): Cardinal; cdecl; +begin + //try + Result := IXpbBuilderImpl(this).getLength(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IXpbBuilderImpl_getIntDispatcher(this: IXpbBuilder; status: IStatus): Integer; cdecl; +begin + //try + Result := IXpbBuilderImpl(this).getInt(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IXpbBuilderImpl_getBigIntDispatcher(this: IXpbBuilder; status: IStatus): Int64; cdecl; +begin + //try + Result := IXpbBuilderImpl(this).getBigInt(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IXpbBuilderImpl_getStringDispatcher(this: IXpbBuilder; status: IStatus): PAnsiChar; cdecl; +begin + //try + Result := IXpbBuilderImpl(this).getString(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IXpbBuilderImpl_getBytesDispatcher(this: IXpbBuilder; status: IStatus): BytePtr; cdecl; +begin + //try + Result := IXpbBuilderImpl(this).getBytes(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IXpbBuilderImpl_getBufferLengthDispatcher(this: IXpbBuilder; status: IStatus): Cardinal; cdecl; +begin + //try + Result := IXpbBuilderImpl(this).getBufferLength(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IXpbBuilderImpl_getBufferDispatcher(this: IXpbBuilder; status: IStatus): BytePtr; cdecl; +begin + //try + Result := IXpbBuilderImpl(this).getBuffer(status); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IXpbBuilderImpl_vTable: XpbBuilderVTable; + +constructor IXpbBuilderImpl.create; +begin + vTable := IXpbBuilderImpl_vTable; +end; + +function ITraceConnectionImpl_getKindDispatcher(this: ITraceConnection): Cardinal; cdecl; +begin + //try + Result := ITraceConnectionImpl(this).getKind(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceConnectionImpl_getProcessIDDispatcher(this: ITraceConnection): Integer; cdecl; +begin + //try + Result := ITraceConnectionImpl(this).getProcessID(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceConnectionImpl_getUserNameDispatcher(this: ITraceConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceConnectionImpl(this).getUserName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceConnectionImpl_getRoleNameDispatcher(this: ITraceConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceConnectionImpl(this).getRoleName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceConnectionImpl_getCharSetDispatcher(this: ITraceConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceConnectionImpl(this).getCharSet(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceConnectionImpl_getRemoteProtocolDispatcher(this: ITraceConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceConnectionImpl(this).getRemoteProtocol(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceConnectionImpl_getRemoteAddressDispatcher(this: ITraceConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceConnectionImpl(this).getRemoteAddress(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceConnectionImpl_getRemoteProcessIDDispatcher(this: ITraceConnection): Integer; cdecl; +begin + //try + Result := ITraceConnectionImpl(this).getRemoteProcessID(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceConnectionImpl_getRemoteProcessNameDispatcher(this: ITraceConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceConnectionImpl(this).getRemoteProcessName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ITraceConnectionImpl_vTable: TraceConnectionVTable; + +constructor ITraceConnectionImpl.create; +begin + vTable := ITraceConnectionImpl_vTable; +end; + +function ITraceDatabaseConnectionImpl_getKindDispatcher(this: ITraceDatabaseConnection): Cardinal; cdecl; +begin + //try + Result := ITraceDatabaseConnectionImpl(this).getKind(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceDatabaseConnectionImpl_getProcessIDDispatcher(this: ITraceDatabaseConnection): Integer; cdecl; +begin + //try + Result := ITraceDatabaseConnectionImpl(this).getProcessID(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceDatabaseConnectionImpl_getUserNameDispatcher(this: ITraceDatabaseConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceDatabaseConnectionImpl(this).getUserName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceDatabaseConnectionImpl_getRoleNameDispatcher(this: ITraceDatabaseConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceDatabaseConnectionImpl(this).getRoleName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceDatabaseConnectionImpl_getCharSetDispatcher(this: ITraceDatabaseConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceDatabaseConnectionImpl(this).getCharSet(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceDatabaseConnectionImpl_getRemoteProtocolDispatcher(this: ITraceDatabaseConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceDatabaseConnectionImpl(this).getRemoteProtocol(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceDatabaseConnectionImpl_getRemoteAddressDispatcher(this: ITraceDatabaseConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceDatabaseConnectionImpl(this).getRemoteAddress(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceDatabaseConnectionImpl_getRemoteProcessIDDispatcher(this: ITraceDatabaseConnection): Integer; cdecl; +begin + //try + Result := ITraceDatabaseConnectionImpl(this).getRemoteProcessID(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceDatabaseConnectionImpl_getRemoteProcessNameDispatcher(this: ITraceDatabaseConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceDatabaseConnectionImpl(this).getRemoteProcessName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceDatabaseConnectionImpl_getConnectionIDDispatcher(this: ITraceDatabaseConnection): Int64; cdecl; +begin + //try + Result := ITraceDatabaseConnectionImpl(this).getConnectionID(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceDatabaseConnectionImpl_getDatabaseNameDispatcher(this: ITraceDatabaseConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceDatabaseConnectionImpl(this).getDatabaseName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ITraceDatabaseConnectionImpl_vTable: TraceDatabaseConnectionVTable; + +constructor ITraceDatabaseConnectionImpl.create; +begin + vTable := ITraceDatabaseConnectionImpl_vTable; +end; + +function ITraceTransactionImpl_getTransactionIDDispatcher(this: ITraceTransaction): Int64; cdecl; +begin + //try + Result := ITraceTransactionImpl(this).getTransactionID(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceTransactionImpl_getReadOnlyDispatcher(this: ITraceTransaction): Boolean; cdecl; +begin + //try + Result := ITraceTransactionImpl(this).getReadOnly(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceTransactionImpl_getWaitDispatcher(this: ITraceTransaction): Integer; cdecl; +begin + //try + Result := ITraceTransactionImpl(this).getWait(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceTransactionImpl_getIsolationDispatcher(this: ITraceTransaction): Cardinal; cdecl; +begin + //try + Result := ITraceTransactionImpl(this).getIsolation(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceTransactionImpl_getPerfDispatcher(this: ITraceTransaction): PerformanceInfoPtr; cdecl; +begin + //try + Result := ITraceTransactionImpl(this).getPerf(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ITraceTransactionImpl_vTable: TraceTransactionVTable; + +constructor ITraceTransactionImpl.create; +begin + vTable := ITraceTransactionImpl_vTable; +end; + +function ITraceParamsImpl_getCountDispatcher(this: ITraceParams): Cardinal; cdecl; +begin + //try + Result := ITraceParamsImpl(this).getCount(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceParamsImpl_getParamDispatcher(this: ITraceParams; idx: Cardinal): dscPtr; cdecl; +begin + //try + Result := ITraceParamsImpl(this).getParam(idx); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ITraceParamsImpl_vTable: TraceParamsVTable; + +constructor ITraceParamsImpl.create; +begin + vTable := ITraceParamsImpl_vTable; +end; + +function ITraceStatementImpl_getStmtIDDispatcher(this: ITraceStatement): Int64; cdecl; +begin + //try + Result := ITraceStatementImpl(this).getStmtID(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceStatementImpl_getPerfDispatcher(this: ITraceStatement): PerformanceInfoPtr; cdecl; +begin + //try + Result := ITraceStatementImpl(this).getPerf(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ITraceStatementImpl_vTable: TraceStatementVTable; + +constructor ITraceStatementImpl.create; +begin + vTable := ITraceStatementImpl_vTable; +end; + +function ITraceSQLStatementImpl_getStmtIDDispatcher(this: ITraceSQLStatement): Int64; cdecl; +begin + //try + Result := ITraceSQLStatementImpl(this).getStmtID(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceSQLStatementImpl_getPerfDispatcher(this: ITraceSQLStatement): PerformanceInfoPtr; cdecl; +begin + //try + Result := ITraceSQLStatementImpl(this).getPerf(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceSQLStatementImpl_getTextDispatcher(this: ITraceSQLStatement): PAnsiChar; cdecl; +begin + //try + Result := ITraceSQLStatementImpl(this).getText(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceSQLStatementImpl_getPlanDispatcher(this: ITraceSQLStatement): PAnsiChar; cdecl; +begin + //try + Result := ITraceSQLStatementImpl(this).getPlan(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceSQLStatementImpl_getInputsDispatcher(this: ITraceSQLStatement): ITraceParams; cdecl; +begin + //try + Result := ITraceSQLStatementImpl(this).getInputs(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceSQLStatementImpl_getTextUTF8Dispatcher(this: ITraceSQLStatement): PAnsiChar; cdecl; +begin + //try + Result := ITraceSQLStatementImpl(this).getTextUTF8(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceSQLStatementImpl_getExplainedPlanDispatcher(this: ITraceSQLStatement): PAnsiChar; cdecl; +begin + //try + Result := ITraceSQLStatementImpl(this).getExplainedPlan(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ITraceSQLStatementImpl_vTable: TraceSQLStatementVTable; + +constructor ITraceSQLStatementImpl.create; +begin + vTable := ITraceSQLStatementImpl_vTable; +end; + +function ITraceBLRStatementImpl_getStmtIDDispatcher(this: ITraceBLRStatement): Int64; cdecl; +begin + //try + Result := ITraceBLRStatementImpl(this).getStmtID(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceBLRStatementImpl_getPerfDispatcher(this: ITraceBLRStatement): PerformanceInfoPtr; cdecl; +begin + //try + Result := ITraceBLRStatementImpl(this).getPerf(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceBLRStatementImpl_getDataDispatcher(this: ITraceBLRStatement): BytePtr; cdecl; +begin + //try + Result := ITraceBLRStatementImpl(this).getData(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceBLRStatementImpl_getDataLengthDispatcher(this: ITraceBLRStatement): Cardinal; cdecl; +begin + //try + Result := ITraceBLRStatementImpl(this).getDataLength(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceBLRStatementImpl_getTextDispatcher(this: ITraceBLRStatement): PAnsiChar; cdecl; +begin + //try + Result := ITraceBLRStatementImpl(this).getText(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ITraceBLRStatementImpl_vTable: TraceBLRStatementVTable; + +constructor ITraceBLRStatementImpl.create; +begin + vTable := ITraceBLRStatementImpl_vTable; +end; + +function ITraceDYNRequestImpl_getDataDispatcher(this: ITraceDYNRequest): BytePtr; cdecl; +begin + //try + Result := ITraceDYNRequestImpl(this).getData(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceDYNRequestImpl_getDataLengthDispatcher(this: ITraceDYNRequest): Cardinal; cdecl; +begin + //try + Result := ITraceDYNRequestImpl(this).getDataLength(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceDYNRequestImpl_getTextDispatcher(this: ITraceDYNRequest): PAnsiChar; cdecl; +begin + //try + Result := ITraceDYNRequestImpl(this).getText(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ITraceDYNRequestImpl_vTable: TraceDYNRequestVTable; + +constructor ITraceDYNRequestImpl.create; +begin + vTable := ITraceDYNRequestImpl_vTable; +end; + +function ITraceContextVariableImpl_getNameSpaceDispatcher(this: ITraceContextVariable): PAnsiChar; cdecl; +begin + //try + Result := ITraceContextVariableImpl(this).getNameSpace(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceContextVariableImpl_getVarNameDispatcher(this: ITraceContextVariable): PAnsiChar; cdecl; +begin + //try + Result := ITraceContextVariableImpl(this).getVarName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceContextVariableImpl_getVarValueDispatcher(this: ITraceContextVariable): PAnsiChar; cdecl; +begin + //try + Result := ITraceContextVariableImpl(this).getVarValue(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ITraceContextVariableImpl_vTable: TraceContextVariableVTable; + +constructor ITraceContextVariableImpl.create; +begin + vTable := ITraceContextVariableImpl_vTable; +end; + +function ITraceProcedureImpl_getProcNameDispatcher(this: ITraceProcedure): PAnsiChar; cdecl; +begin + //try + Result := ITraceProcedureImpl(this).getProcName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceProcedureImpl_getInputsDispatcher(this: ITraceProcedure): ITraceParams; cdecl; +begin + //try + Result := ITraceProcedureImpl(this).getInputs(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceProcedureImpl_getPerfDispatcher(this: ITraceProcedure): PerformanceInfoPtr; cdecl; +begin + //try + Result := ITraceProcedureImpl(this).getPerf(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ITraceProcedureImpl_vTable: TraceProcedureVTable; + +constructor ITraceProcedureImpl.create; +begin + vTable := ITraceProcedureImpl_vTable; +end; + +function ITraceFunctionImpl_getFuncNameDispatcher(this: ITraceFunction): PAnsiChar; cdecl; +begin + //try + Result := ITraceFunctionImpl(this).getFuncName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceFunctionImpl_getInputsDispatcher(this: ITraceFunction): ITraceParams; cdecl; +begin + //try + Result := ITraceFunctionImpl(this).getInputs(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceFunctionImpl_getResultDispatcher(this: ITraceFunction): ITraceParams; cdecl; +begin + //try + Result := ITraceFunctionImpl(this).getResult(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceFunctionImpl_getPerfDispatcher(this: ITraceFunction): PerformanceInfoPtr; cdecl; +begin + //try + Result := ITraceFunctionImpl(this).getPerf(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ITraceFunctionImpl_vTable: TraceFunctionVTable; + +constructor ITraceFunctionImpl.create; +begin + vTable := ITraceFunctionImpl_vTable; +end; + +function ITraceTriggerImpl_getTriggerNameDispatcher(this: ITraceTrigger): PAnsiChar; cdecl; +begin + //try + Result := ITraceTriggerImpl(this).getTriggerName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceTriggerImpl_getRelationNameDispatcher(this: ITraceTrigger): PAnsiChar; cdecl; +begin + //try + Result := ITraceTriggerImpl(this).getRelationName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceTriggerImpl_getActionDispatcher(this: ITraceTrigger): Integer; cdecl; +begin + //try + Result := ITraceTriggerImpl(this).getAction(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceTriggerImpl_getWhichDispatcher(this: ITraceTrigger): Integer; cdecl; +begin + //try + Result := ITraceTriggerImpl(this).getWhich(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceTriggerImpl_getPerfDispatcher(this: ITraceTrigger): PerformanceInfoPtr; cdecl; +begin + //try + Result := ITraceTriggerImpl(this).getPerf(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ITraceTriggerImpl_vTable: TraceTriggerVTable; + +constructor ITraceTriggerImpl.create; +begin + vTable := ITraceTriggerImpl_vTable; +end; + +function ITraceServiceConnectionImpl_getKindDispatcher(this: ITraceServiceConnection): Cardinal; cdecl; +begin + //try + Result := ITraceServiceConnectionImpl(this).getKind(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceServiceConnectionImpl_getProcessIDDispatcher(this: ITraceServiceConnection): Integer; cdecl; +begin + //try + Result := ITraceServiceConnectionImpl(this).getProcessID(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceServiceConnectionImpl_getUserNameDispatcher(this: ITraceServiceConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceServiceConnectionImpl(this).getUserName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceServiceConnectionImpl_getRoleNameDispatcher(this: ITraceServiceConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceServiceConnectionImpl(this).getRoleName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceServiceConnectionImpl_getCharSetDispatcher(this: ITraceServiceConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceServiceConnectionImpl(this).getCharSet(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceServiceConnectionImpl_getRemoteProtocolDispatcher(this: ITraceServiceConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceServiceConnectionImpl(this).getRemoteProtocol(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceServiceConnectionImpl_getRemoteAddressDispatcher(this: ITraceServiceConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceServiceConnectionImpl(this).getRemoteAddress(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceServiceConnectionImpl_getRemoteProcessIDDispatcher(this: ITraceServiceConnection): Integer; cdecl; +begin + //try + Result := ITraceServiceConnectionImpl(this).getRemoteProcessID(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceServiceConnectionImpl_getRemoteProcessNameDispatcher(this: ITraceServiceConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceServiceConnectionImpl(this).getRemoteProcessName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceServiceConnectionImpl_getServiceIDDispatcher(this: ITraceServiceConnection): Pointer; cdecl; +begin + //try + Result := ITraceServiceConnectionImpl(this).getServiceID(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceServiceConnectionImpl_getServiceMgrDispatcher(this: ITraceServiceConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceServiceConnectionImpl(this).getServiceMgr(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceServiceConnectionImpl_getServiceNameDispatcher(this: ITraceServiceConnection): PAnsiChar; cdecl; +begin + //try + Result := ITraceServiceConnectionImpl(this).getServiceName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ITraceServiceConnectionImpl_vTable: TraceServiceConnectionVTable; + +constructor ITraceServiceConnectionImpl.create; +begin + vTable := ITraceServiceConnectionImpl_vTable; +end; + +function ITraceStatusVectorImpl_hasErrorDispatcher(this: ITraceStatusVector): Boolean; cdecl; +begin + //try + Result := ITraceStatusVectorImpl(this).hasError(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceStatusVectorImpl_hasWarningDispatcher(this: ITraceStatusVector): Boolean; cdecl; +begin + //try + Result := ITraceStatusVectorImpl(this).hasWarning(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceStatusVectorImpl_getStatusDispatcher(this: ITraceStatusVector): IStatus; cdecl; +begin + //try + Result := ITraceStatusVectorImpl(this).getStatus(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceStatusVectorImpl_getTextDispatcher(this: ITraceStatusVector): PAnsiChar; cdecl; +begin + //try + Result := ITraceStatusVectorImpl(this).getText(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ITraceStatusVectorImpl_vTable: TraceStatusVectorVTable; + +constructor ITraceStatusVectorImpl.create; +begin + vTable := ITraceStatusVectorImpl_vTable; +end; + +function ITraceSweepInfoImpl_getOITDispatcher(this: ITraceSweepInfo): Int64; cdecl; +begin + //try + Result := ITraceSweepInfoImpl(this).getOIT(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceSweepInfoImpl_getOSTDispatcher(this: ITraceSweepInfo): Int64; cdecl; +begin + //try + Result := ITraceSweepInfoImpl(this).getOST(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceSweepInfoImpl_getOATDispatcher(this: ITraceSweepInfo): Int64; cdecl; +begin + //try + Result := ITraceSweepInfoImpl(this).getOAT(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceSweepInfoImpl_getNextDispatcher(this: ITraceSweepInfo): Int64; cdecl; +begin + //try + Result := ITraceSweepInfoImpl(this).getNext(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceSweepInfoImpl_getPerfDispatcher(this: ITraceSweepInfo): PerformanceInfoPtr; cdecl; +begin + //try + Result := ITraceSweepInfoImpl(this).getPerf(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ITraceSweepInfoImpl_vTable: TraceSweepInfoVTable; + +constructor ITraceSweepInfoImpl.create; +begin + vTable := ITraceSweepInfoImpl_vTable; +end; + +procedure ITraceLogWriterImpl_addRefDispatcher(this: ITraceLogWriter); cdecl; +begin + //try + ITraceLogWriterImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceLogWriterImpl_releaseDispatcher(this: ITraceLogWriter): Integer; cdecl; +begin + //try + Result := ITraceLogWriterImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceLogWriterImpl_writeDispatcher(this: ITraceLogWriter; buf: Pointer; size: Cardinal): Cardinal; cdecl; +begin + //try + Result := ITraceLogWriterImpl(this).write(buf, size); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ITraceLogWriterImpl_vTable: TraceLogWriterVTable; + +constructor ITraceLogWriterImpl.create; +begin + vTable := ITraceLogWriterImpl_vTable; +end; + +function ITraceInitInfoImpl_getConfigTextDispatcher(this: ITraceInitInfo): PAnsiChar; cdecl; +begin + //try + Result := ITraceInitInfoImpl(this).getConfigText(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceInitInfoImpl_getTraceSessionIDDispatcher(this: ITraceInitInfo): Integer; cdecl; +begin + //try + Result := ITraceInitInfoImpl(this).getTraceSessionID(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceInitInfoImpl_getTraceSessionNameDispatcher(this: ITraceInitInfo): PAnsiChar; cdecl; +begin + //try + Result := ITraceInitInfoImpl(this).getTraceSessionName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceInitInfoImpl_getFirebirdRootDirectoryDispatcher(this: ITraceInitInfo): PAnsiChar; cdecl; +begin + //try + Result := ITraceInitInfoImpl(this).getFirebirdRootDirectory(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceInitInfoImpl_getDatabaseNameDispatcher(this: ITraceInitInfo): PAnsiChar; cdecl; +begin + //try + Result := ITraceInitInfoImpl(this).getDatabaseName(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceInitInfoImpl_getConnectionDispatcher(this: ITraceInitInfo): ITraceDatabaseConnection; cdecl; +begin + //try + Result := ITraceInitInfoImpl(this).getConnection(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceInitInfoImpl_getLogWriterDispatcher(this: ITraceInitInfo): ITraceLogWriter; cdecl; +begin + //try + Result := ITraceInitInfoImpl(this).getLogWriter(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ITraceInitInfoImpl_vTable: TraceInitInfoVTable; + +constructor ITraceInitInfoImpl.create; +begin + vTable := ITraceInitInfoImpl_vTable; +end; + +procedure ITracePluginImpl_addRefDispatcher(this: ITracePlugin); cdecl; +begin + //try + ITracePluginImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_releaseDispatcher(this: ITracePlugin): Integer; cdecl; +begin + //try + Result := ITracePluginImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_get_errorDispatcher(this: ITracePlugin): PAnsiChar; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_get_error(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_attachDispatcher(this: ITracePlugin; connection: ITraceDatabaseConnection; create_db: Boolean; att_result: Cardinal): Boolean; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_attach(connection, create_db, att_result); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_detachDispatcher(this: ITracePlugin; connection: ITraceDatabaseConnection; drop_db: Boolean): Boolean; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_detach(connection, drop_db); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_transaction_startDispatcher(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; tpb_length: Cardinal; tpb: BytePtr; tra_result: Cardinal): Boolean; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_transaction_start(connection, transaction, tpb_length, tpb, tra_result); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_transaction_endDispatcher(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; commit: Boolean; retain_context: Boolean; tra_result: Cardinal): Boolean; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_transaction_end(connection, transaction, commit, retain_context, tra_result); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_proc_executeDispatcher(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; procedure_: ITraceProcedure; started: Boolean; proc_result: Cardinal): Boolean; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_proc_execute(connection, transaction, procedure_, started, proc_result); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_trigger_executeDispatcher(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; trigger: ITraceTrigger; started: Boolean; trig_result: Cardinal): Boolean; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_trigger_execute(connection, transaction, trigger, started, trig_result); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_set_contextDispatcher(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; variable: ITraceContextVariable): Boolean; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_set_context(connection, transaction, variable); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_dsql_prepareDispatcher(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceSQLStatement; time_millis: Int64; req_result: Cardinal): Boolean; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_dsql_prepare(connection, transaction, statement, time_millis, req_result); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_dsql_freeDispatcher(this: ITracePlugin; connection: ITraceDatabaseConnection; statement: ITraceSQLStatement; option: Cardinal): Boolean; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_dsql_free(connection, statement, option); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_dsql_executeDispatcher(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceSQLStatement; started: Boolean; req_result: Cardinal): Boolean; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_dsql_execute(connection, transaction, statement, started, req_result); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_blr_compileDispatcher(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceBLRStatement; time_millis: Int64; req_result: Cardinal): Boolean; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_blr_compile(connection, transaction, statement, time_millis, req_result); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_blr_executeDispatcher(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceBLRStatement; req_result: Cardinal): Boolean; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_blr_execute(connection, transaction, statement, req_result); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_dyn_executeDispatcher(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; request: ITraceDYNRequest; time_millis: Int64; req_result: Cardinal): Boolean; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_dyn_execute(connection, transaction, request, time_millis, req_result); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_service_attachDispatcher(this: ITracePlugin; service: ITraceServiceConnection; att_result: Cardinal): Boolean; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_service_attach(service, att_result); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_service_startDispatcher(this: ITracePlugin; service: ITraceServiceConnection; switches_length: Cardinal; switches: PAnsiChar; start_result: Cardinal): Boolean; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_service_start(service, switches_length, switches, start_result); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_service_queryDispatcher(this: ITracePlugin; service: ITraceServiceConnection; send_item_length: Cardinal; send_items: BytePtr; recv_item_length: Cardinal; recv_items: BytePtr; query_result: Cardinal): Boolean; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_service_query(service, send_item_length, send_items, recv_item_length, recv_items, query_result); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_service_detachDispatcher(this: ITracePlugin; service: ITraceServiceConnection; detach_result: Cardinal): Boolean; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_service_detach(service, detach_result); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_event_errorDispatcher(this: ITracePlugin; connection: ITraceConnection; status: ITraceStatusVector; function_: PAnsiChar): Boolean; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_event_error(connection, status, function_); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_event_sweepDispatcher(this: ITracePlugin; connection: ITraceDatabaseConnection; sweep: ITraceSweepInfo; sweep_state: Cardinal): Boolean; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_event_sweep(connection, sweep, sweep_state); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITracePluginImpl_trace_func_executeDispatcher(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; function_: ITraceFunction; started: Boolean; func_result: Cardinal): Boolean; cdecl; +begin + //try + Result := ITracePluginImpl(this).trace_func_execute(connection, transaction, function_, started, func_result); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +var + ITracePluginImpl_vTable: TracePluginVTable; + +constructor ITracePluginImpl.create; +begin + vTable := ITracePluginImpl_vTable; +end; + +procedure ITraceFactoryImpl_addRefDispatcher(this: ITraceFactory); cdecl; +begin + //try + ITraceFactoryImpl(this).addRef(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceFactoryImpl_releaseDispatcher(this: ITraceFactory): Integer; cdecl; +begin + //try + Result := ITraceFactoryImpl(this).release(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure ITraceFactoryImpl_setOwnerDispatcher(this: ITraceFactory; r: IReferenceCounted); cdecl; +begin + //try + ITraceFactoryImpl(this).setOwner(r); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceFactoryImpl_getOwnerDispatcher(this: ITraceFactory): IReferenceCounted; cdecl; +begin + //try + Result := ITraceFactoryImpl(this).getOwner(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceFactoryImpl_trace_needsDispatcher(this: ITraceFactory): QWord; cdecl; +begin + //try + Result := ITraceFactoryImpl(this).trace_needs(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +function ITraceFactoryImpl_trace_createDispatcher(this: ITraceFactory; status: IStatus; init_info: ITraceInitInfo): ITracePlugin; cdecl; +begin + //try + Result := ITraceFactoryImpl(this).trace_create(status, init_info); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + ITraceFactoryImpl_vTable: TraceFactoryVTable; + +constructor ITraceFactoryImpl.create; +begin + vTable := ITraceFactoryImpl_vTable; +end; + +procedure IUdrFunctionFactoryImpl_disposeDispatcher(this: IUdrFunctionFactory); cdecl; +begin + //try + IUdrFunctionFactoryImpl(this).dispose(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IUdrFunctionFactoryImpl_setupDispatcher(this: IUdrFunctionFactory; status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder); cdecl; +begin + //try + IUdrFunctionFactoryImpl(this).setup(status, context, metadata, inBuilder, outBuilder); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IUdrFunctionFactoryImpl_newItemDispatcher(this: IUdrFunctionFactory; status: IStatus; context: IExternalContext; metadata: IRoutineMetadata): IExternalFunction; cdecl; +begin + //try + Result := IUdrFunctionFactoryImpl(this).newItem(status, context, metadata); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IUdrFunctionFactoryImpl_vTable: UdrFunctionFactoryVTable; + +constructor IUdrFunctionFactoryImpl.create; +begin + vTable := IUdrFunctionFactoryImpl_vTable; +end; + +procedure IUdrProcedureFactoryImpl_disposeDispatcher(this: IUdrProcedureFactory); cdecl; +begin + //try + IUdrProcedureFactoryImpl(this).dispose(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IUdrProcedureFactoryImpl_setupDispatcher(this: IUdrProcedureFactory; status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder); cdecl; +begin + //try + IUdrProcedureFactoryImpl(this).setup(status, context, metadata, inBuilder, outBuilder); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IUdrProcedureFactoryImpl_newItemDispatcher(this: IUdrProcedureFactory; status: IStatus; context: IExternalContext; metadata: IRoutineMetadata): IExternalProcedure; cdecl; +begin + //try + Result := IUdrProcedureFactoryImpl(this).newItem(status, context, metadata); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IUdrProcedureFactoryImpl_vTable: UdrProcedureFactoryVTable; + +constructor IUdrProcedureFactoryImpl.create; +begin + vTable := IUdrProcedureFactoryImpl_vTable; +end; + +procedure IUdrTriggerFactoryImpl_disposeDispatcher(this: IUdrTriggerFactory); cdecl; +begin + //try + IUdrTriggerFactoryImpl(this).dispose(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IUdrTriggerFactoryImpl_setupDispatcher(this: IUdrTriggerFactory; status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; fieldsBuilder: IMetadataBuilder); cdecl; +begin + //try + IUdrTriggerFactoryImpl(this).setup(status, context, metadata, fieldsBuilder); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +function IUdrTriggerFactoryImpl_newItemDispatcher(this: IUdrTriggerFactory; status: IStatus; context: IExternalContext; metadata: IRoutineMetadata): IExternalTrigger; cdecl; +begin + //try + Result := IUdrTriggerFactoryImpl(this).newItem(status, context, metadata); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IUdrTriggerFactoryImpl_vTable: UdrTriggerFactoryVTable; + +constructor IUdrTriggerFactoryImpl.create; +begin + vTable := IUdrTriggerFactoryImpl_vTable; +end; + +function IUdrPluginImpl_getMasterDispatcher(this: IUdrPlugin): IMaster; cdecl; +begin + //try + Result := IUdrPluginImpl(this).getMaster(); + //except + //on e: Exception do FbException.catchException(nil, e); + //end +end; + +procedure IUdrPluginImpl_registerFunctionDispatcher(this: IUdrPlugin; status: IStatus; name: PAnsiChar; factory: IUdrFunctionFactory); cdecl; +begin + //try + IUdrPluginImpl(this).registerFunction(status, name, factory); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IUdrPluginImpl_registerProcedureDispatcher(this: IUdrPlugin; status: IStatus; name: PAnsiChar; factory: IUdrProcedureFactory); cdecl; +begin + //try + IUdrPluginImpl(this).registerProcedure(status, name, factory); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +procedure IUdrPluginImpl_registerTriggerDispatcher(this: IUdrPlugin; status: IStatus; name: PAnsiChar; factory: IUdrTriggerFactory); cdecl; +begin + //try + IUdrPluginImpl(this).registerTrigger(status, name, factory); + //except + //on e: Exception do FbException.catchException(status, e); + //end +end; + +var + IUdrPluginImpl_vTable: UdrPluginVTable; + +constructor IUdrPluginImpl.create; +begin + vTable := IUdrPluginImpl_vTable; +end; + +constructor FbException.create(status: IStatus); +begin + inherited Create('FbException'); + self.status := status.clone; +end; + +destructor FbException.Destroy(); +begin + status.dispose; + inherited Destroy; +end; + +function FbException.getStatus: IStatus; +begin + Result := status; +end; + +class procedure FbException.checkException(status: IStatus); +begin + if ((status.getState and status.STATE_ERRORS) <> 0) then + raise FbException.create(status); +end; + +class procedure FbException.catchException(status: IStatus; e: Exception); +var + statusVector: array[0..4] of NativeIntPtr; + msg: AnsiString; +begin + if (e.inheritsFrom(FbException)) then + status.setErrors(FbException(e).getStatus.getErrors) + else + begin + msg := e.message; + + statusVector[0] := NativeIntPtr(isc_arg_gds); + statusVector[1] := NativeIntPtr(isc_random); + statusVector[2] := NativeIntPtr(isc_arg_string); + statusVector[3] := NativeIntPtr(PAnsiChar(msg)); + statusVector[4] := NativeIntPtr(isc_arg_end); + + status.setErrors(@statusVector); + end +end; +initialization + IVersionedImpl_vTable := VersionedVTable.create; + IVersionedImpl_vTable.version := 0; + + IReferenceCountedImpl_vTable := ReferenceCountedVTable.create; + IReferenceCountedImpl_vTable.version := 2; + IReferenceCountedImpl_vTable.addRef := @IReferenceCountedImpl_addRefDispatcher; + IReferenceCountedImpl_vTable.release := @IReferenceCountedImpl_releaseDispatcher; + + IDisposableImpl_vTable := DisposableVTable.create; + IDisposableImpl_vTable.version := 1; + IDisposableImpl_vTable.dispose := @IDisposableImpl_disposeDispatcher; + + IStatusImpl_vTable := StatusVTable.create; + IStatusImpl_vTable.version := 10; + IStatusImpl_vTable.dispose := @IStatusImpl_disposeDispatcher; + IStatusImpl_vTable.init := @IStatusImpl_initDispatcher; + IStatusImpl_vTable.getState := @IStatusImpl_getStateDispatcher; + IStatusImpl_vTable.setErrors2 := @IStatusImpl_setErrors2Dispatcher; + IStatusImpl_vTable.setWarnings2 := @IStatusImpl_setWarnings2Dispatcher; + IStatusImpl_vTable.setErrors := @IStatusImpl_setErrorsDispatcher; + IStatusImpl_vTable.setWarnings := @IStatusImpl_setWarningsDispatcher; + IStatusImpl_vTable.getErrors := @IStatusImpl_getErrorsDispatcher; + IStatusImpl_vTable.getWarnings := @IStatusImpl_getWarningsDispatcher; + IStatusImpl_vTable.clone := @IStatusImpl_cloneDispatcher; + + IMasterImpl_vTable := MasterVTable.create; + IMasterImpl_vTable.version := 12; + IMasterImpl_vTable.getStatus := @IMasterImpl_getStatusDispatcher; + IMasterImpl_vTable.getDispatcher := @IMasterImpl_getDispatcherDispatcher; + IMasterImpl_vTable.getPluginManager := @IMasterImpl_getPluginManagerDispatcher; + IMasterImpl_vTable.getTimerControl := @IMasterImpl_getTimerControlDispatcher; + IMasterImpl_vTable.getDtc := @IMasterImpl_getDtcDispatcher; + IMasterImpl_vTable.registerAttachment := @IMasterImpl_registerAttachmentDispatcher; + IMasterImpl_vTable.registerTransaction := @IMasterImpl_registerTransactionDispatcher; + IMasterImpl_vTable.getMetadataBuilder := @IMasterImpl_getMetadataBuilderDispatcher; + IMasterImpl_vTable.serverMode := @IMasterImpl_serverModeDispatcher; + IMasterImpl_vTable.getUtilInterface := @IMasterImpl_getUtilInterfaceDispatcher; + IMasterImpl_vTable.getConfigManager := @IMasterImpl_getConfigManagerDispatcher; + IMasterImpl_vTable.getProcessExiting := @IMasterImpl_getProcessExitingDispatcher; + + IPluginBaseImpl_vTable := PluginBaseVTable.create; + IPluginBaseImpl_vTable.version := 4; + IPluginBaseImpl_vTable.addRef := @IPluginBaseImpl_addRefDispatcher; + IPluginBaseImpl_vTable.release := @IPluginBaseImpl_releaseDispatcher; + IPluginBaseImpl_vTable.setOwner := @IPluginBaseImpl_setOwnerDispatcher; + IPluginBaseImpl_vTable.getOwner := @IPluginBaseImpl_getOwnerDispatcher; + + IPluginSetImpl_vTable := PluginSetVTable.create; + IPluginSetImpl_vTable.version := 7; + IPluginSetImpl_vTable.addRef := @IPluginSetImpl_addRefDispatcher; + IPluginSetImpl_vTable.release := @IPluginSetImpl_releaseDispatcher; + IPluginSetImpl_vTable.getName := @IPluginSetImpl_getNameDispatcher; + IPluginSetImpl_vTable.getModuleName := @IPluginSetImpl_getModuleNameDispatcher; + IPluginSetImpl_vTable.getPlugin := @IPluginSetImpl_getPluginDispatcher; + IPluginSetImpl_vTable.next := @IPluginSetImpl_nextDispatcher; + IPluginSetImpl_vTable.set_ := @IPluginSetImpl_set_Dispatcher; + + IConfigEntryImpl_vTable := ConfigEntryVTable.create; + IConfigEntryImpl_vTable.version := 7; + IConfigEntryImpl_vTable.addRef := @IConfigEntryImpl_addRefDispatcher; + IConfigEntryImpl_vTable.release := @IConfigEntryImpl_releaseDispatcher; + IConfigEntryImpl_vTable.getName := @IConfigEntryImpl_getNameDispatcher; + IConfigEntryImpl_vTable.getValue := @IConfigEntryImpl_getValueDispatcher; + IConfigEntryImpl_vTable.getIntValue := @IConfigEntryImpl_getIntValueDispatcher; + IConfigEntryImpl_vTable.getBoolValue := @IConfigEntryImpl_getBoolValueDispatcher; + IConfigEntryImpl_vTable.getSubConfig := @IConfigEntryImpl_getSubConfigDispatcher; + + IConfigImpl_vTable := ConfigVTable.create; + IConfigImpl_vTable.version := 5; + IConfigImpl_vTable.addRef := @IConfigImpl_addRefDispatcher; + IConfigImpl_vTable.release := @IConfigImpl_releaseDispatcher; + IConfigImpl_vTable.find := @IConfigImpl_findDispatcher; + IConfigImpl_vTable.findValue := @IConfigImpl_findValueDispatcher; + IConfigImpl_vTable.findPos := @IConfigImpl_findPosDispatcher; + + IFirebirdConfImpl_vTable := FirebirdConfVTable.create; + IFirebirdConfImpl_vTable.version := 6; + IFirebirdConfImpl_vTable.addRef := @IFirebirdConfImpl_addRefDispatcher; + IFirebirdConfImpl_vTable.release := @IFirebirdConfImpl_releaseDispatcher; + IFirebirdConfImpl_vTable.getKey := @IFirebirdConfImpl_getKeyDispatcher; + IFirebirdConfImpl_vTable.asInteger := @IFirebirdConfImpl_asIntegerDispatcher; + IFirebirdConfImpl_vTable.asString := @IFirebirdConfImpl_asStringDispatcher; + IFirebirdConfImpl_vTable.asBoolean := @IFirebirdConfImpl_asBooleanDispatcher; + + IPluginConfigImpl_vTable := PluginConfigVTable.create; + IPluginConfigImpl_vTable.version := 6; + IPluginConfigImpl_vTable.addRef := @IPluginConfigImpl_addRefDispatcher; + IPluginConfigImpl_vTable.release := @IPluginConfigImpl_releaseDispatcher; + IPluginConfigImpl_vTable.getConfigFileName := @IPluginConfigImpl_getConfigFileNameDispatcher; + IPluginConfigImpl_vTable.getDefaultConfig := @IPluginConfigImpl_getDefaultConfigDispatcher; + IPluginConfigImpl_vTable.getFirebirdConf := @IPluginConfigImpl_getFirebirdConfDispatcher; + IPluginConfigImpl_vTable.setReleaseDelay := @IPluginConfigImpl_setReleaseDelayDispatcher; + + IPluginFactoryImpl_vTable := PluginFactoryVTable.create; + IPluginFactoryImpl_vTable.version := 1; + IPluginFactoryImpl_vTable.createPlugin := @IPluginFactoryImpl_createPluginDispatcher; + + IPluginModuleImpl_vTable := PluginModuleVTable.create; + IPluginModuleImpl_vTable.version := 1; + IPluginModuleImpl_vTable.doClean := @IPluginModuleImpl_doCleanDispatcher; + + IPluginManagerImpl_vTable := PluginManagerVTable.create; + IPluginManagerImpl_vTable.version := 6; + IPluginManagerImpl_vTable.registerPluginFactory := @IPluginManagerImpl_registerPluginFactoryDispatcher; + IPluginManagerImpl_vTable.registerModule := @IPluginManagerImpl_registerModuleDispatcher; + IPluginManagerImpl_vTable.unregisterModule := @IPluginManagerImpl_unregisterModuleDispatcher; + IPluginManagerImpl_vTable.getPlugins := @IPluginManagerImpl_getPluginsDispatcher; + IPluginManagerImpl_vTable.getConfig := @IPluginManagerImpl_getConfigDispatcher; + IPluginManagerImpl_vTable.releasePlugin := @IPluginManagerImpl_releasePluginDispatcher; + + ICryptKeyImpl_vTable := CryptKeyVTable.create; + ICryptKeyImpl_vTable.version := 4; + ICryptKeyImpl_vTable.setSymmetric := @ICryptKeyImpl_setSymmetricDispatcher; + ICryptKeyImpl_vTable.setAsymmetric := @ICryptKeyImpl_setAsymmetricDispatcher; + ICryptKeyImpl_vTable.getEncryptKey := @ICryptKeyImpl_getEncryptKeyDispatcher; + ICryptKeyImpl_vTable.getDecryptKey := @ICryptKeyImpl_getDecryptKeyDispatcher; + + IConfigManagerImpl_vTable := ConfigManagerVTable.create; + IConfigManagerImpl_vTable.version := 6; + IConfigManagerImpl_vTable.getDirectory := @IConfigManagerImpl_getDirectoryDispatcher; + IConfigManagerImpl_vTable.getFirebirdConf := @IConfigManagerImpl_getFirebirdConfDispatcher; + IConfigManagerImpl_vTable.getDatabaseConf := @IConfigManagerImpl_getDatabaseConfDispatcher; + IConfigManagerImpl_vTable.getPluginConfig := @IConfigManagerImpl_getPluginConfigDispatcher; + IConfigManagerImpl_vTable.getInstallDirectory := @IConfigManagerImpl_getInstallDirectoryDispatcher; + IConfigManagerImpl_vTable.getRootDirectory := @IConfigManagerImpl_getRootDirectoryDispatcher; + + IEventCallbackImpl_vTable := EventCallbackVTable.create; + IEventCallbackImpl_vTable.version := 3; + IEventCallbackImpl_vTable.addRef := @IEventCallbackImpl_addRefDispatcher; + IEventCallbackImpl_vTable.release := @IEventCallbackImpl_releaseDispatcher; + IEventCallbackImpl_vTable.eventCallbackFunction := @IEventCallbackImpl_eventCallbackFunctionDispatcher; + + IBlobImpl_vTable := BlobVTable.create; + IBlobImpl_vTable.version := 8; + IBlobImpl_vTable.addRef := @IBlobImpl_addRefDispatcher; + IBlobImpl_vTable.release := @IBlobImpl_releaseDispatcher; + IBlobImpl_vTable.getInfo := @IBlobImpl_getInfoDispatcher; + IBlobImpl_vTable.getSegment := @IBlobImpl_getSegmentDispatcher; + IBlobImpl_vTable.putSegment := @IBlobImpl_putSegmentDispatcher; + IBlobImpl_vTable.cancel := @IBlobImpl_cancelDispatcher; + IBlobImpl_vTable.close := @IBlobImpl_closeDispatcher; + IBlobImpl_vTable.seek := @IBlobImpl_seekDispatcher; + + ITransactionImpl_vTable := TransactionVTable.create; + ITransactionImpl_vTable.version := 12; + ITransactionImpl_vTable.addRef := @ITransactionImpl_addRefDispatcher; + ITransactionImpl_vTable.release := @ITransactionImpl_releaseDispatcher; + ITransactionImpl_vTable.getInfo := @ITransactionImpl_getInfoDispatcher; + ITransactionImpl_vTable.prepare := @ITransactionImpl_prepareDispatcher; + ITransactionImpl_vTable.commit := @ITransactionImpl_commitDispatcher; + ITransactionImpl_vTable.commitRetaining := @ITransactionImpl_commitRetainingDispatcher; + ITransactionImpl_vTable.rollback := @ITransactionImpl_rollbackDispatcher; + ITransactionImpl_vTable.rollbackRetaining := @ITransactionImpl_rollbackRetainingDispatcher; + ITransactionImpl_vTable.disconnect := @ITransactionImpl_disconnectDispatcher; + ITransactionImpl_vTable.join := @ITransactionImpl_joinDispatcher; + ITransactionImpl_vTable.validate := @ITransactionImpl_validateDispatcher; + ITransactionImpl_vTable.enterDtc := @ITransactionImpl_enterDtcDispatcher; + + IMessageMetadataImpl_vTable := MessageMetadataVTable.create; + IMessageMetadataImpl_vTable.version := 17; + IMessageMetadataImpl_vTable.addRef := @IMessageMetadataImpl_addRefDispatcher; + IMessageMetadataImpl_vTable.release := @IMessageMetadataImpl_releaseDispatcher; + IMessageMetadataImpl_vTable.getCount := @IMessageMetadataImpl_getCountDispatcher; + IMessageMetadataImpl_vTable.getField := @IMessageMetadataImpl_getFieldDispatcher; + IMessageMetadataImpl_vTable.getRelation := @IMessageMetadataImpl_getRelationDispatcher; + IMessageMetadataImpl_vTable.getOwner := @IMessageMetadataImpl_getOwnerDispatcher; + IMessageMetadataImpl_vTable.getAlias := @IMessageMetadataImpl_getAliasDispatcher; + IMessageMetadataImpl_vTable.getType := @IMessageMetadataImpl_getTypeDispatcher; + IMessageMetadataImpl_vTable.isNullable := @IMessageMetadataImpl_isNullableDispatcher; + IMessageMetadataImpl_vTable.getSubType := @IMessageMetadataImpl_getSubTypeDispatcher; + IMessageMetadataImpl_vTable.getLength := @IMessageMetadataImpl_getLengthDispatcher; + IMessageMetadataImpl_vTable.getScale := @IMessageMetadataImpl_getScaleDispatcher; + IMessageMetadataImpl_vTable.getCharSet := @IMessageMetadataImpl_getCharSetDispatcher; + IMessageMetadataImpl_vTable.getOffset := @IMessageMetadataImpl_getOffsetDispatcher; + IMessageMetadataImpl_vTable.getNullOffset := @IMessageMetadataImpl_getNullOffsetDispatcher; + IMessageMetadataImpl_vTable.getBuilder := @IMessageMetadataImpl_getBuilderDispatcher; + IMessageMetadataImpl_vTable.getMessageLength := @IMessageMetadataImpl_getMessageLengthDispatcher; + + IMetadataBuilderImpl_vTable := MetadataBuilderVTable.create; + IMetadataBuilderImpl_vTable.version := 12; + IMetadataBuilderImpl_vTable.addRef := @IMetadataBuilderImpl_addRefDispatcher; + IMetadataBuilderImpl_vTable.release := @IMetadataBuilderImpl_releaseDispatcher; + IMetadataBuilderImpl_vTable.setType := @IMetadataBuilderImpl_setTypeDispatcher; + IMetadataBuilderImpl_vTable.setSubType := @IMetadataBuilderImpl_setSubTypeDispatcher; + IMetadataBuilderImpl_vTable.setLength := @IMetadataBuilderImpl_setLengthDispatcher; + IMetadataBuilderImpl_vTable.setCharSet := @IMetadataBuilderImpl_setCharSetDispatcher; + IMetadataBuilderImpl_vTable.setScale := @IMetadataBuilderImpl_setScaleDispatcher; + IMetadataBuilderImpl_vTable.truncate := @IMetadataBuilderImpl_truncateDispatcher; + IMetadataBuilderImpl_vTable.moveNameToIndex := @IMetadataBuilderImpl_moveNameToIndexDispatcher; + IMetadataBuilderImpl_vTable.remove := @IMetadataBuilderImpl_removeDispatcher; + IMetadataBuilderImpl_vTable.addField := @IMetadataBuilderImpl_addFieldDispatcher; + IMetadataBuilderImpl_vTable.getMetadata := @IMetadataBuilderImpl_getMetadataDispatcher; + + IResultSetImpl_vTable := ResultSetVTable.create; + IResultSetImpl_vTable.version := 13; + IResultSetImpl_vTable.addRef := @IResultSetImpl_addRefDispatcher; + IResultSetImpl_vTable.release := @IResultSetImpl_releaseDispatcher; + IResultSetImpl_vTable.fetchNext := @IResultSetImpl_fetchNextDispatcher; + IResultSetImpl_vTable.fetchPrior := @IResultSetImpl_fetchPriorDispatcher; + IResultSetImpl_vTable.fetchFirst := @IResultSetImpl_fetchFirstDispatcher; + IResultSetImpl_vTable.fetchLast := @IResultSetImpl_fetchLastDispatcher; + IResultSetImpl_vTable.fetchAbsolute := @IResultSetImpl_fetchAbsoluteDispatcher; + IResultSetImpl_vTable.fetchRelative := @IResultSetImpl_fetchRelativeDispatcher; + IResultSetImpl_vTable.isEof := @IResultSetImpl_isEofDispatcher; + IResultSetImpl_vTable.isBof := @IResultSetImpl_isBofDispatcher; + IResultSetImpl_vTable.getMetadata := @IResultSetImpl_getMetadataDispatcher; + IResultSetImpl_vTable.close := @IResultSetImpl_closeDispatcher; + IResultSetImpl_vTable.setDelayedOutputFormat := @IResultSetImpl_setDelayedOutputFormatDispatcher; + + IStatementImpl_vTable := StatementVTable.create; + IStatementImpl_vTable.version := 13; + IStatementImpl_vTable.addRef := @IStatementImpl_addRefDispatcher; + IStatementImpl_vTable.release := @IStatementImpl_releaseDispatcher; + IStatementImpl_vTable.getInfo := @IStatementImpl_getInfoDispatcher; + IStatementImpl_vTable.getType := @IStatementImpl_getTypeDispatcher; + IStatementImpl_vTable.getPlan := @IStatementImpl_getPlanDispatcher; + IStatementImpl_vTable.getAffectedRecords := @IStatementImpl_getAffectedRecordsDispatcher; + IStatementImpl_vTable.getInputMetadata := @IStatementImpl_getInputMetadataDispatcher; + IStatementImpl_vTable.getOutputMetadata := @IStatementImpl_getOutputMetadataDispatcher; + IStatementImpl_vTable.execute := @IStatementImpl_executeDispatcher; + IStatementImpl_vTable.openCursor := @IStatementImpl_openCursorDispatcher; + IStatementImpl_vTable.setCursorName := @IStatementImpl_setCursorNameDispatcher; + IStatementImpl_vTable.free := @IStatementImpl_freeDispatcher; + IStatementImpl_vTable.getFlags := @IStatementImpl_getFlagsDispatcher; + + IRequestImpl_vTable := RequestVTable.create; + IRequestImpl_vTable.version := 9; + IRequestImpl_vTable.addRef := @IRequestImpl_addRefDispatcher; + IRequestImpl_vTable.release := @IRequestImpl_releaseDispatcher; + IRequestImpl_vTable.receive := @IRequestImpl_receiveDispatcher; + IRequestImpl_vTable.send := @IRequestImpl_sendDispatcher; + IRequestImpl_vTable.getInfo := @IRequestImpl_getInfoDispatcher; + IRequestImpl_vTable.start := @IRequestImpl_startDispatcher; + IRequestImpl_vTable.startAndSend := @IRequestImpl_startAndSendDispatcher; + IRequestImpl_vTable.unwind := @IRequestImpl_unwindDispatcher; + IRequestImpl_vTable.free := @IRequestImpl_freeDispatcher; + + IEventsImpl_vTable := EventsVTable.create; + IEventsImpl_vTable.version := 3; + IEventsImpl_vTable.addRef := @IEventsImpl_addRefDispatcher; + IEventsImpl_vTable.release := @IEventsImpl_releaseDispatcher; + IEventsImpl_vTable.cancel := @IEventsImpl_cancelDispatcher; + + IAttachmentImpl_vTable := AttachmentVTable.create; + IAttachmentImpl_vTable.version := 20; + IAttachmentImpl_vTable.addRef := @IAttachmentImpl_addRefDispatcher; + IAttachmentImpl_vTable.release := @IAttachmentImpl_releaseDispatcher; + IAttachmentImpl_vTable.getInfo := @IAttachmentImpl_getInfoDispatcher; + IAttachmentImpl_vTable.startTransaction := @IAttachmentImpl_startTransactionDispatcher; + IAttachmentImpl_vTable.reconnectTransaction := @IAttachmentImpl_reconnectTransactionDispatcher; + IAttachmentImpl_vTable.compileRequest := @IAttachmentImpl_compileRequestDispatcher; + IAttachmentImpl_vTable.transactRequest := @IAttachmentImpl_transactRequestDispatcher; + IAttachmentImpl_vTable.createBlob := @IAttachmentImpl_createBlobDispatcher; + IAttachmentImpl_vTable.openBlob := @IAttachmentImpl_openBlobDispatcher; + IAttachmentImpl_vTable.getSlice := @IAttachmentImpl_getSliceDispatcher; + IAttachmentImpl_vTable.putSlice := @IAttachmentImpl_putSliceDispatcher; + IAttachmentImpl_vTable.executeDyn := @IAttachmentImpl_executeDynDispatcher; + IAttachmentImpl_vTable.prepare := @IAttachmentImpl_prepareDispatcher; + IAttachmentImpl_vTable.execute := @IAttachmentImpl_executeDispatcher; + IAttachmentImpl_vTable.openCursor := @IAttachmentImpl_openCursorDispatcher; + IAttachmentImpl_vTable.queEvents := @IAttachmentImpl_queEventsDispatcher; + IAttachmentImpl_vTable.cancelOperation := @IAttachmentImpl_cancelOperationDispatcher; + IAttachmentImpl_vTable.ping := @IAttachmentImpl_pingDispatcher; + IAttachmentImpl_vTable.detach := @IAttachmentImpl_detachDispatcher; + IAttachmentImpl_vTable.dropDatabase := @IAttachmentImpl_dropDatabaseDispatcher; + + IServiceImpl_vTable := ServiceVTable.create; + IServiceImpl_vTable.version := 5; + IServiceImpl_vTable.addRef := @IServiceImpl_addRefDispatcher; + IServiceImpl_vTable.release := @IServiceImpl_releaseDispatcher; + IServiceImpl_vTable.detach := @IServiceImpl_detachDispatcher; + IServiceImpl_vTable.query := @IServiceImpl_queryDispatcher; + IServiceImpl_vTable.start := @IServiceImpl_startDispatcher; + + IProviderImpl_vTable := ProviderVTable.create; + IProviderImpl_vTable.version := 9; + IProviderImpl_vTable.addRef := @IProviderImpl_addRefDispatcher; + IProviderImpl_vTable.release := @IProviderImpl_releaseDispatcher; + IProviderImpl_vTable.setOwner := @IProviderImpl_setOwnerDispatcher; + IProviderImpl_vTable.getOwner := @IProviderImpl_getOwnerDispatcher; + IProviderImpl_vTable.attachDatabase := @IProviderImpl_attachDatabaseDispatcher; + IProviderImpl_vTable.createDatabase := @IProviderImpl_createDatabaseDispatcher; + IProviderImpl_vTable.attachServiceManager := @IProviderImpl_attachServiceManagerDispatcher; + IProviderImpl_vTable.shutdown := @IProviderImpl_shutdownDispatcher; + IProviderImpl_vTable.setDbCryptCallback := @IProviderImpl_setDbCryptCallbackDispatcher; + + IDtcStartImpl_vTable := DtcStartVTable.create; + IDtcStartImpl_vTable.version := 4; + IDtcStartImpl_vTable.dispose := @IDtcStartImpl_disposeDispatcher; + IDtcStartImpl_vTable.addAttachment := @IDtcStartImpl_addAttachmentDispatcher; + IDtcStartImpl_vTable.addWithTpb := @IDtcStartImpl_addWithTpbDispatcher; + IDtcStartImpl_vTable.start := @IDtcStartImpl_startDispatcher; + + IDtcImpl_vTable := DtcVTable.create; + IDtcImpl_vTable.version := 2; + IDtcImpl_vTable.join := @IDtcImpl_joinDispatcher; + IDtcImpl_vTable.startBuilder := @IDtcImpl_startBuilderDispatcher; + + IAuthImpl_vTable := AuthVTable.create; + IAuthImpl_vTable.version := 4; + IAuthImpl_vTable.addRef := @IAuthImpl_addRefDispatcher; + IAuthImpl_vTable.release := @IAuthImpl_releaseDispatcher; + IAuthImpl_vTable.setOwner := @IAuthImpl_setOwnerDispatcher; + IAuthImpl_vTable.getOwner := @IAuthImpl_getOwnerDispatcher; + + IWriterImpl_vTable := WriterVTable.create; + IWriterImpl_vTable.version := 4; + IWriterImpl_vTable.reset := @IWriterImpl_resetDispatcher; + IWriterImpl_vTable.add := @IWriterImpl_addDispatcher; + IWriterImpl_vTable.setType := @IWriterImpl_setTypeDispatcher; + IWriterImpl_vTable.setDb := @IWriterImpl_setDbDispatcher; + + IServerBlockImpl_vTable := ServerBlockVTable.create; + IServerBlockImpl_vTable.version := 4; + IServerBlockImpl_vTable.getLogin := @IServerBlockImpl_getLoginDispatcher; + IServerBlockImpl_vTable.getData := @IServerBlockImpl_getDataDispatcher; + IServerBlockImpl_vTable.putData := @IServerBlockImpl_putDataDispatcher; + IServerBlockImpl_vTable.newKey := @IServerBlockImpl_newKeyDispatcher; + + IClientBlockImpl_vTable := ClientBlockVTable.create; + IClientBlockImpl_vTable.version := 7; + IClientBlockImpl_vTable.addRef := @IClientBlockImpl_addRefDispatcher; + IClientBlockImpl_vTable.release := @IClientBlockImpl_releaseDispatcher; + IClientBlockImpl_vTable.getLogin := @IClientBlockImpl_getLoginDispatcher; + IClientBlockImpl_vTable.getPassword := @IClientBlockImpl_getPasswordDispatcher; + IClientBlockImpl_vTable.getData := @IClientBlockImpl_getDataDispatcher; + IClientBlockImpl_vTable.putData := @IClientBlockImpl_putDataDispatcher; + IClientBlockImpl_vTable.newKey := @IClientBlockImpl_newKeyDispatcher; + + IServerImpl_vTable := ServerVTable.create; + IServerImpl_vTable.version := 5; + IServerImpl_vTable.addRef := @IServerImpl_addRefDispatcher; + IServerImpl_vTable.release := @IServerImpl_releaseDispatcher; + IServerImpl_vTable.setOwner := @IServerImpl_setOwnerDispatcher; + IServerImpl_vTable.getOwner := @IServerImpl_getOwnerDispatcher; + IServerImpl_vTable.authenticate := @IServerImpl_authenticateDispatcher; + + IClientImpl_vTable := ClientVTable.create; + IClientImpl_vTable.version := 5; + IClientImpl_vTable.addRef := @IClientImpl_addRefDispatcher; + IClientImpl_vTable.release := @IClientImpl_releaseDispatcher; + IClientImpl_vTable.setOwner := @IClientImpl_setOwnerDispatcher; + IClientImpl_vTable.getOwner := @IClientImpl_getOwnerDispatcher; + IClientImpl_vTable.authenticate := @IClientImpl_authenticateDispatcher; + + IUserFieldImpl_vTable := UserFieldVTable.create; + IUserFieldImpl_vTable.version := 3; + IUserFieldImpl_vTable.entered := @IUserFieldImpl_enteredDispatcher; + IUserFieldImpl_vTable.specified := @IUserFieldImpl_specifiedDispatcher; + IUserFieldImpl_vTable.setEntered := @IUserFieldImpl_setEnteredDispatcher; + + ICharUserFieldImpl_vTable := CharUserFieldVTable.create; + ICharUserFieldImpl_vTable.version := 5; + ICharUserFieldImpl_vTable.entered := @ICharUserFieldImpl_enteredDispatcher; + ICharUserFieldImpl_vTable.specified := @ICharUserFieldImpl_specifiedDispatcher; + ICharUserFieldImpl_vTable.setEntered := @ICharUserFieldImpl_setEnteredDispatcher; + ICharUserFieldImpl_vTable.get := @ICharUserFieldImpl_getDispatcher; + ICharUserFieldImpl_vTable.set_ := @ICharUserFieldImpl_set_Dispatcher; + + IIntUserFieldImpl_vTable := IntUserFieldVTable.create; + IIntUserFieldImpl_vTable.version := 5; + IIntUserFieldImpl_vTable.entered := @IIntUserFieldImpl_enteredDispatcher; + IIntUserFieldImpl_vTable.specified := @IIntUserFieldImpl_specifiedDispatcher; + IIntUserFieldImpl_vTable.setEntered := @IIntUserFieldImpl_setEnteredDispatcher; + IIntUserFieldImpl_vTable.get := @IIntUserFieldImpl_getDispatcher; + IIntUserFieldImpl_vTable.set_ := @IIntUserFieldImpl_set_Dispatcher; + + IUserImpl_vTable := UserVTable.create; + IUserImpl_vTable.version := 11; + IUserImpl_vTable.operation := @IUserImpl_operationDispatcher; + IUserImpl_vTable.userName := @IUserImpl_userNameDispatcher; + IUserImpl_vTable.password := @IUserImpl_passwordDispatcher; + IUserImpl_vTable.firstName := @IUserImpl_firstNameDispatcher; + IUserImpl_vTable.lastName := @IUserImpl_lastNameDispatcher; + IUserImpl_vTable.middleName := @IUserImpl_middleNameDispatcher; + IUserImpl_vTable.comment := @IUserImpl_commentDispatcher; + IUserImpl_vTable.attributes := @IUserImpl_attributesDispatcher; + IUserImpl_vTable.active := @IUserImpl_activeDispatcher; + IUserImpl_vTable.admin := @IUserImpl_adminDispatcher; + IUserImpl_vTable.clear := @IUserImpl_clearDispatcher; + + IListUsersImpl_vTable := ListUsersVTable.create; + IListUsersImpl_vTable.version := 1; + IListUsersImpl_vTable.list := @IListUsersImpl_listDispatcher; + + ILogonInfoImpl_vTable := LogonInfoVTable.create; + ILogonInfoImpl_vTable.version := 5; + ILogonInfoImpl_vTable.name := @ILogonInfoImpl_nameDispatcher; + ILogonInfoImpl_vTable.role := @ILogonInfoImpl_roleDispatcher; + ILogonInfoImpl_vTable.networkProtocol := @ILogonInfoImpl_networkProtocolDispatcher; + ILogonInfoImpl_vTable.remoteAddress := @ILogonInfoImpl_remoteAddressDispatcher; + ILogonInfoImpl_vTable.authBlock := @ILogonInfoImpl_authBlockDispatcher; + + IManagementImpl_vTable := ManagementVTable.create; + IManagementImpl_vTable.version := 8; + IManagementImpl_vTable.addRef := @IManagementImpl_addRefDispatcher; + IManagementImpl_vTable.release := @IManagementImpl_releaseDispatcher; + IManagementImpl_vTable.setOwner := @IManagementImpl_setOwnerDispatcher; + IManagementImpl_vTable.getOwner := @IManagementImpl_getOwnerDispatcher; + IManagementImpl_vTable.start := @IManagementImpl_startDispatcher; + IManagementImpl_vTable.execute := @IManagementImpl_executeDispatcher; + IManagementImpl_vTable.commit := @IManagementImpl_commitDispatcher; + IManagementImpl_vTable.rollback := @IManagementImpl_rollbackDispatcher; + + IWireCryptPluginImpl_vTable := WireCryptPluginVTable.create; + IWireCryptPluginImpl_vTable.version := 8; + IWireCryptPluginImpl_vTable.addRef := @IWireCryptPluginImpl_addRefDispatcher; + IWireCryptPluginImpl_vTable.release := @IWireCryptPluginImpl_releaseDispatcher; + IWireCryptPluginImpl_vTable.setOwner := @IWireCryptPluginImpl_setOwnerDispatcher; + IWireCryptPluginImpl_vTable.getOwner := @IWireCryptPluginImpl_getOwnerDispatcher; + IWireCryptPluginImpl_vTable.getKnownTypes := @IWireCryptPluginImpl_getKnownTypesDispatcher; + IWireCryptPluginImpl_vTable.setKey := @IWireCryptPluginImpl_setKeyDispatcher; + IWireCryptPluginImpl_vTable.encrypt := @IWireCryptPluginImpl_encryptDispatcher; + IWireCryptPluginImpl_vTable.decrypt := @IWireCryptPluginImpl_decryptDispatcher; + + ICryptKeyCallbackImpl_vTable := CryptKeyCallbackVTable.create; + ICryptKeyCallbackImpl_vTable.version := 1; + ICryptKeyCallbackImpl_vTable.callback := @ICryptKeyCallbackImpl_callbackDispatcher; + + IKeyHolderPluginImpl_vTable := KeyHolderPluginVTable.create; + IKeyHolderPluginImpl_vTable.version := 6; + IKeyHolderPluginImpl_vTable.addRef := @IKeyHolderPluginImpl_addRefDispatcher; + IKeyHolderPluginImpl_vTable.release := @IKeyHolderPluginImpl_releaseDispatcher; + IKeyHolderPluginImpl_vTable.setOwner := @IKeyHolderPluginImpl_setOwnerDispatcher; + IKeyHolderPluginImpl_vTable.getOwner := @IKeyHolderPluginImpl_getOwnerDispatcher; + IKeyHolderPluginImpl_vTable.keyCallback := @IKeyHolderPluginImpl_keyCallbackDispatcher; + IKeyHolderPluginImpl_vTable.keyHandle := @IKeyHolderPluginImpl_keyHandleDispatcher; + + IDbCryptPluginImpl_vTable := DbCryptPluginVTable.create; + IDbCryptPluginImpl_vTable.version := 7; + IDbCryptPluginImpl_vTable.addRef := @IDbCryptPluginImpl_addRefDispatcher; + IDbCryptPluginImpl_vTable.release := @IDbCryptPluginImpl_releaseDispatcher; + IDbCryptPluginImpl_vTable.setOwner := @IDbCryptPluginImpl_setOwnerDispatcher; + IDbCryptPluginImpl_vTable.getOwner := @IDbCryptPluginImpl_getOwnerDispatcher; + IDbCryptPluginImpl_vTable.setKey := @IDbCryptPluginImpl_setKeyDispatcher; + IDbCryptPluginImpl_vTable.encrypt := @IDbCryptPluginImpl_encryptDispatcher; + IDbCryptPluginImpl_vTable.decrypt := @IDbCryptPluginImpl_decryptDispatcher; + + IExternalContextImpl_vTable := ExternalContextVTable.create; + IExternalContextImpl_vTable.version := 10; + IExternalContextImpl_vTable.getMaster := @IExternalContextImpl_getMasterDispatcher; + IExternalContextImpl_vTable.getEngine := @IExternalContextImpl_getEngineDispatcher; + IExternalContextImpl_vTable.getAttachment := @IExternalContextImpl_getAttachmentDispatcher; + IExternalContextImpl_vTable.getTransaction := @IExternalContextImpl_getTransactionDispatcher; + IExternalContextImpl_vTable.getUserName := @IExternalContextImpl_getUserNameDispatcher; + IExternalContextImpl_vTable.getDatabaseName := @IExternalContextImpl_getDatabaseNameDispatcher; + IExternalContextImpl_vTable.getClientCharSet := @IExternalContextImpl_getClientCharSetDispatcher; + IExternalContextImpl_vTable.obtainInfoCode := @IExternalContextImpl_obtainInfoCodeDispatcher; + IExternalContextImpl_vTable.getInfo := @IExternalContextImpl_getInfoDispatcher; + IExternalContextImpl_vTable.setInfo := @IExternalContextImpl_setInfoDispatcher; + + IExternalResultSetImpl_vTable := ExternalResultSetVTable.create; + IExternalResultSetImpl_vTable.version := 2; + IExternalResultSetImpl_vTable.dispose := @IExternalResultSetImpl_disposeDispatcher; + IExternalResultSetImpl_vTable.fetch := @IExternalResultSetImpl_fetchDispatcher; + + IExternalFunctionImpl_vTable := ExternalFunctionVTable.create; + IExternalFunctionImpl_vTable.version := 3; + IExternalFunctionImpl_vTable.dispose := @IExternalFunctionImpl_disposeDispatcher; + IExternalFunctionImpl_vTable.getCharSet := @IExternalFunctionImpl_getCharSetDispatcher; + IExternalFunctionImpl_vTable.execute := @IExternalFunctionImpl_executeDispatcher; + + IExternalProcedureImpl_vTable := ExternalProcedureVTable.create; + IExternalProcedureImpl_vTable.version := 3; + IExternalProcedureImpl_vTable.dispose := @IExternalProcedureImpl_disposeDispatcher; + IExternalProcedureImpl_vTable.getCharSet := @IExternalProcedureImpl_getCharSetDispatcher; + IExternalProcedureImpl_vTable.open := @IExternalProcedureImpl_openDispatcher; + + IExternalTriggerImpl_vTable := ExternalTriggerVTable.create; + IExternalTriggerImpl_vTable.version := 3; + IExternalTriggerImpl_vTable.dispose := @IExternalTriggerImpl_disposeDispatcher; + IExternalTriggerImpl_vTable.getCharSet := @IExternalTriggerImpl_getCharSetDispatcher; + IExternalTriggerImpl_vTable.execute := @IExternalTriggerImpl_executeDispatcher; + + IRoutineMetadataImpl_vTable := RoutineMetadataVTable.create; + IRoutineMetadataImpl_vTable.version := 9; + IRoutineMetadataImpl_vTable.getPackage := @IRoutineMetadataImpl_getPackageDispatcher; + IRoutineMetadataImpl_vTable.getName := @IRoutineMetadataImpl_getNameDispatcher; + IRoutineMetadataImpl_vTable.getEntryPoint := @IRoutineMetadataImpl_getEntryPointDispatcher; + IRoutineMetadataImpl_vTable.getBody := @IRoutineMetadataImpl_getBodyDispatcher; + IRoutineMetadataImpl_vTable.getInputMetadata := @IRoutineMetadataImpl_getInputMetadataDispatcher; + IRoutineMetadataImpl_vTable.getOutputMetadata := @IRoutineMetadataImpl_getOutputMetadataDispatcher; + IRoutineMetadataImpl_vTable.getTriggerMetadata := @IRoutineMetadataImpl_getTriggerMetadataDispatcher; + IRoutineMetadataImpl_vTable.getTriggerTable := @IRoutineMetadataImpl_getTriggerTableDispatcher; + IRoutineMetadataImpl_vTable.getTriggerType := @IRoutineMetadataImpl_getTriggerTypeDispatcher; + + IExternalEngineImpl_vTable := ExternalEngineVTable.create; + IExternalEngineImpl_vTable.version := 10; + IExternalEngineImpl_vTable.addRef := @IExternalEngineImpl_addRefDispatcher; + IExternalEngineImpl_vTable.release := @IExternalEngineImpl_releaseDispatcher; + IExternalEngineImpl_vTable.setOwner := @IExternalEngineImpl_setOwnerDispatcher; + IExternalEngineImpl_vTable.getOwner := @IExternalEngineImpl_getOwnerDispatcher; + IExternalEngineImpl_vTable.open := @IExternalEngineImpl_openDispatcher; + IExternalEngineImpl_vTable.openAttachment := @IExternalEngineImpl_openAttachmentDispatcher; + IExternalEngineImpl_vTable.closeAttachment := @IExternalEngineImpl_closeAttachmentDispatcher; + IExternalEngineImpl_vTable.makeFunction := @IExternalEngineImpl_makeFunctionDispatcher; + IExternalEngineImpl_vTable.makeProcedure := @IExternalEngineImpl_makeProcedureDispatcher; + IExternalEngineImpl_vTable.makeTrigger := @IExternalEngineImpl_makeTriggerDispatcher; + + ITimerImpl_vTable := TimerVTable.create; + ITimerImpl_vTable.version := 3; + ITimerImpl_vTable.addRef := @ITimerImpl_addRefDispatcher; + ITimerImpl_vTable.release := @ITimerImpl_releaseDispatcher; + ITimerImpl_vTable.handler := @ITimerImpl_handlerDispatcher; + + ITimerControlImpl_vTable := TimerControlVTable.create; + ITimerControlImpl_vTable.version := 2; + ITimerControlImpl_vTable.start := @ITimerControlImpl_startDispatcher; + ITimerControlImpl_vTable.stop := @ITimerControlImpl_stopDispatcher; + + IVersionCallbackImpl_vTable := VersionCallbackVTable.create; + IVersionCallbackImpl_vTable.version := 1; + IVersionCallbackImpl_vTable.callback := @IVersionCallbackImpl_callbackDispatcher; + + IUtilImpl_vTable := UtilVTable.create; + IUtilImpl_vTable.version := 13; + IUtilImpl_vTable.getFbVersion := @IUtilImpl_getFbVersionDispatcher; + IUtilImpl_vTable.loadBlob := @IUtilImpl_loadBlobDispatcher; + IUtilImpl_vTable.dumpBlob := @IUtilImpl_dumpBlobDispatcher; + IUtilImpl_vTable.getPerfCounters := @IUtilImpl_getPerfCountersDispatcher; + IUtilImpl_vTable.executeCreateDatabase := @IUtilImpl_executeCreateDatabaseDispatcher; + IUtilImpl_vTable.decodeDate := @IUtilImpl_decodeDateDispatcher; + IUtilImpl_vTable.decodeTime := @IUtilImpl_decodeTimeDispatcher; + IUtilImpl_vTable.encodeDate := @IUtilImpl_encodeDateDispatcher; + IUtilImpl_vTable.encodeTime := @IUtilImpl_encodeTimeDispatcher; + IUtilImpl_vTable.formatStatus := @IUtilImpl_formatStatusDispatcher; + IUtilImpl_vTable.getClientVersion := @IUtilImpl_getClientVersionDispatcher; + IUtilImpl_vTable.getXpbBuilder := @IUtilImpl_getXpbBuilderDispatcher; + IUtilImpl_vTable.setOffsets := @IUtilImpl_setOffsetsDispatcher; + + IOffsetsCallbackImpl_vTable := OffsetsCallbackVTable.create; + IOffsetsCallbackImpl_vTable.version := 1; + IOffsetsCallbackImpl_vTable.setOffset := @IOffsetsCallbackImpl_setOffsetDispatcher; + + IXpbBuilderImpl_vTable := XpbBuilderVTable.create; + IXpbBuilderImpl_vTable.version := 21; + IXpbBuilderImpl_vTable.dispose := @IXpbBuilderImpl_disposeDispatcher; + IXpbBuilderImpl_vTable.clear := @IXpbBuilderImpl_clearDispatcher; + IXpbBuilderImpl_vTable.removeCurrent := @IXpbBuilderImpl_removeCurrentDispatcher; + IXpbBuilderImpl_vTable.insertInt := @IXpbBuilderImpl_insertIntDispatcher; + IXpbBuilderImpl_vTable.insertBigInt := @IXpbBuilderImpl_insertBigIntDispatcher; + IXpbBuilderImpl_vTable.insertBytes := @IXpbBuilderImpl_insertBytesDispatcher; + IXpbBuilderImpl_vTable.insertString := @IXpbBuilderImpl_insertStringDispatcher; + IXpbBuilderImpl_vTable.insertTag := @IXpbBuilderImpl_insertTagDispatcher; + IXpbBuilderImpl_vTable.isEof := @IXpbBuilderImpl_isEofDispatcher; + IXpbBuilderImpl_vTable.moveNext := @IXpbBuilderImpl_moveNextDispatcher; + IXpbBuilderImpl_vTable.rewind := @IXpbBuilderImpl_rewindDispatcher; + IXpbBuilderImpl_vTable.findFirst := @IXpbBuilderImpl_findFirstDispatcher; + IXpbBuilderImpl_vTable.findNext := @IXpbBuilderImpl_findNextDispatcher; + IXpbBuilderImpl_vTable.getTag := @IXpbBuilderImpl_getTagDispatcher; + IXpbBuilderImpl_vTable.getLength := @IXpbBuilderImpl_getLengthDispatcher; + IXpbBuilderImpl_vTable.getInt := @IXpbBuilderImpl_getIntDispatcher; + IXpbBuilderImpl_vTable.getBigInt := @IXpbBuilderImpl_getBigIntDispatcher; + IXpbBuilderImpl_vTable.getString := @IXpbBuilderImpl_getStringDispatcher; + IXpbBuilderImpl_vTable.getBytes := @IXpbBuilderImpl_getBytesDispatcher; + IXpbBuilderImpl_vTable.getBufferLength := @IXpbBuilderImpl_getBufferLengthDispatcher; + IXpbBuilderImpl_vTable.getBuffer := @IXpbBuilderImpl_getBufferDispatcher; + + ITraceConnectionImpl_vTable := TraceConnectionVTable.create; + ITraceConnectionImpl_vTable.version := 9; + ITraceConnectionImpl_vTable.getKind := @ITraceConnectionImpl_getKindDispatcher; + ITraceConnectionImpl_vTable.getProcessID := @ITraceConnectionImpl_getProcessIDDispatcher; + ITraceConnectionImpl_vTable.getUserName := @ITraceConnectionImpl_getUserNameDispatcher; + ITraceConnectionImpl_vTable.getRoleName := @ITraceConnectionImpl_getRoleNameDispatcher; + ITraceConnectionImpl_vTable.getCharSet := @ITraceConnectionImpl_getCharSetDispatcher; + ITraceConnectionImpl_vTable.getRemoteProtocol := @ITraceConnectionImpl_getRemoteProtocolDispatcher; + ITraceConnectionImpl_vTable.getRemoteAddress := @ITraceConnectionImpl_getRemoteAddressDispatcher; + ITraceConnectionImpl_vTable.getRemoteProcessID := @ITraceConnectionImpl_getRemoteProcessIDDispatcher; + ITraceConnectionImpl_vTable.getRemoteProcessName := @ITraceConnectionImpl_getRemoteProcessNameDispatcher; + + ITraceDatabaseConnectionImpl_vTable := TraceDatabaseConnectionVTable.create; + ITraceDatabaseConnectionImpl_vTable.version := 11; + ITraceDatabaseConnectionImpl_vTable.getKind := @ITraceDatabaseConnectionImpl_getKindDispatcher; + ITraceDatabaseConnectionImpl_vTable.getProcessID := @ITraceDatabaseConnectionImpl_getProcessIDDispatcher; + ITraceDatabaseConnectionImpl_vTable.getUserName := @ITraceDatabaseConnectionImpl_getUserNameDispatcher; + ITraceDatabaseConnectionImpl_vTable.getRoleName := @ITraceDatabaseConnectionImpl_getRoleNameDispatcher; + ITraceDatabaseConnectionImpl_vTable.getCharSet := @ITraceDatabaseConnectionImpl_getCharSetDispatcher; + ITraceDatabaseConnectionImpl_vTable.getRemoteProtocol := @ITraceDatabaseConnectionImpl_getRemoteProtocolDispatcher; + ITraceDatabaseConnectionImpl_vTable.getRemoteAddress := @ITraceDatabaseConnectionImpl_getRemoteAddressDispatcher; + ITraceDatabaseConnectionImpl_vTable.getRemoteProcessID := @ITraceDatabaseConnectionImpl_getRemoteProcessIDDispatcher; + ITraceDatabaseConnectionImpl_vTable.getRemoteProcessName := @ITraceDatabaseConnectionImpl_getRemoteProcessNameDispatcher; + ITraceDatabaseConnectionImpl_vTable.getConnectionID := @ITraceDatabaseConnectionImpl_getConnectionIDDispatcher; + ITraceDatabaseConnectionImpl_vTable.getDatabaseName := @ITraceDatabaseConnectionImpl_getDatabaseNameDispatcher; + + ITraceTransactionImpl_vTable := TraceTransactionVTable.create; + ITraceTransactionImpl_vTable.version := 5; + ITraceTransactionImpl_vTable.getTransactionID := @ITraceTransactionImpl_getTransactionIDDispatcher; + ITraceTransactionImpl_vTable.getReadOnly := @ITraceTransactionImpl_getReadOnlyDispatcher; + ITraceTransactionImpl_vTable.getWait := @ITraceTransactionImpl_getWaitDispatcher; + ITraceTransactionImpl_vTable.getIsolation := @ITraceTransactionImpl_getIsolationDispatcher; + ITraceTransactionImpl_vTable.getPerf := @ITraceTransactionImpl_getPerfDispatcher; + + ITraceParamsImpl_vTable := TraceParamsVTable.create; + ITraceParamsImpl_vTable.version := 2; + ITraceParamsImpl_vTable.getCount := @ITraceParamsImpl_getCountDispatcher; + ITraceParamsImpl_vTable.getParam := @ITraceParamsImpl_getParamDispatcher; + + ITraceStatementImpl_vTable := TraceStatementVTable.create; + ITraceStatementImpl_vTable.version := 2; + ITraceStatementImpl_vTable.getStmtID := @ITraceStatementImpl_getStmtIDDispatcher; + ITraceStatementImpl_vTable.getPerf := @ITraceStatementImpl_getPerfDispatcher; + + ITraceSQLStatementImpl_vTable := TraceSQLStatementVTable.create; + ITraceSQLStatementImpl_vTable.version := 7; + ITraceSQLStatementImpl_vTable.getStmtID := @ITraceSQLStatementImpl_getStmtIDDispatcher; + ITraceSQLStatementImpl_vTable.getPerf := @ITraceSQLStatementImpl_getPerfDispatcher; + ITraceSQLStatementImpl_vTable.getText := @ITraceSQLStatementImpl_getTextDispatcher; + ITraceSQLStatementImpl_vTable.getPlan := @ITraceSQLStatementImpl_getPlanDispatcher; + ITraceSQLStatementImpl_vTable.getInputs := @ITraceSQLStatementImpl_getInputsDispatcher; + ITraceSQLStatementImpl_vTable.getTextUTF8 := @ITraceSQLStatementImpl_getTextUTF8Dispatcher; + ITraceSQLStatementImpl_vTable.getExplainedPlan := @ITraceSQLStatementImpl_getExplainedPlanDispatcher; + + ITraceBLRStatementImpl_vTable := TraceBLRStatementVTable.create; + ITraceBLRStatementImpl_vTable.version := 5; + ITraceBLRStatementImpl_vTable.getStmtID := @ITraceBLRStatementImpl_getStmtIDDispatcher; + ITraceBLRStatementImpl_vTable.getPerf := @ITraceBLRStatementImpl_getPerfDispatcher; + ITraceBLRStatementImpl_vTable.getData := @ITraceBLRStatementImpl_getDataDispatcher; + ITraceBLRStatementImpl_vTable.getDataLength := @ITraceBLRStatementImpl_getDataLengthDispatcher; + ITraceBLRStatementImpl_vTable.getText := @ITraceBLRStatementImpl_getTextDispatcher; + + ITraceDYNRequestImpl_vTable := TraceDYNRequestVTable.create; + ITraceDYNRequestImpl_vTable.version := 3; + ITraceDYNRequestImpl_vTable.getData := @ITraceDYNRequestImpl_getDataDispatcher; + ITraceDYNRequestImpl_vTable.getDataLength := @ITraceDYNRequestImpl_getDataLengthDispatcher; + ITraceDYNRequestImpl_vTable.getText := @ITraceDYNRequestImpl_getTextDispatcher; + + ITraceContextVariableImpl_vTable := TraceContextVariableVTable.create; + ITraceContextVariableImpl_vTable.version := 3; + ITraceContextVariableImpl_vTable.getNameSpace := @ITraceContextVariableImpl_getNameSpaceDispatcher; + ITraceContextVariableImpl_vTable.getVarName := @ITraceContextVariableImpl_getVarNameDispatcher; + ITraceContextVariableImpl_vTable.getVarValue := @ITraceContextVariableImpl_getVarValueDispatcher; + + ITraceProcedureImpl_vTable := TraceProcedureVTable.create; + ITraceProcedureImpl_vTable.version := 3; + ITraceProcedureImpl_vTable.getProcName := @ITraceProcedureImpl_getProcNameDispatcher; + ITraceProcedureImpl_vTable.getInputs := @ITraceProcedureImpl_getInputsDispatcher; + ITraceProcedureImpl_vTable.getPerf := @ITraceProcedureImpl_getPerfDispatcher; + + ITraceFunctionImpl_vTable := TraceFunctionVTable.create; + ITraceFunctionImpl_vTable.version := 4; + ITraceFunctionImpl_vTable.getFuncName := @ITraceFunctionImpl_getFuncNameDispatcher; + ITraceFunctionImpl_vTable.getInputs := @ITraceFunctionImpl_getInputsDispatcher; + ITraceFunctionImpl_vTable.getResult := @ITraceFunctionImpl_getResultDispatcher; + ITraceFunctionImpl_vTable.getPerf := @ITraceFunctionImpl_getPerfDispatcher; + + ITraceTriggerImpl_vTable := TraceTriggerVTable.create; + ITraceTriggerImpl_vTable.version := 5; + ITraceTriggerImpl_vTable.getTriggerName := @ITraceTriggerImpl_getTriggerNameDispatcher; + ITraceTriggerImpl_vTable.getRelationName := @ITraceTriggerImpl_getRelationNameDispatcher; + ITraceTriggerImpl_vTable.getAction := @ITraceTriggerImpl_getActionDispatcher; + ITraceTriggerImpl_vTable.getWhich := @ITraceTriggerImpl_getWhichDispatcher; + ITraceTriggerImpl_vTable.getPerf := @ITraceTriggerImpl_getPerfDispatcher; + + ITraceServiceConnectionImpl_vTable := TraceServiceConnectionVTable.create; + ITraceServiceConnectionImpl_vTable.version := 12; + ITraceServiceConnectionImpl_vTable.getKind := @ITraceServiceConnectionImpl_getKindDispatcher; + ITraceServiceConnectionImpl_vTable.getProcessID := @ITraceServiceConnectionImpl_getProcessIDDispatcher; + ITraceServiceConnectionImpl_vTable.getUserName := @ITraceServiceConnectionImpl_getUserNameDispatcher; + ITraceServiceConnectionImpl_vTable.getRoleName := @ITraceServiceConnectionImpl_getRoleNameDispatcher; + ITraceServiceConnectionImpl_vTable.getCharSet := @ITraceServiceConnectionImpl_getCharSetDispatcher; + ITraceServiceConnectionImpl_vTable.getRemoteProtocol := @ITraceServiceConnectionImpl_getRemoteProtocolDispatcher; + ITraceServiceConnectionImpl_vTable.getRemoteAddress := @ITraceServiceConnectionImpl_getRemoteAddressDispatcher; + ITraceServiceConnectionImpl_vTable.getRemoteProcessID := @ITraceServiceConnectionImpl_getRemoteProcessIDDispatcher; + ITraceServiceConnectionImpl_vTable.getRemoteProcessName := @ITraceServiceConnectionImpl_getRemoteProcessNameDispatcher; + ITraceServiceConnectionImpl_vTable.getServiceID := @ITraceServiceConnectionImpl_getServiceIDDispatcher; + ITraceServiceConnectionImpl_vTable.getServiceMgr := @ITraceServiceConnectionImpl_getServiceMgrDispatcher; + ITraceServiceConnectionImpl_vTable.getServiceName := @ITraceServiceConnectionImpl_getServiceNameDispatcher; + + ITraceStatusVectorImpl_vTable := TraceStatusVectorVTable.create; + ITraceStatusVectorImpl_vTable.version := 4; + ITraceStatusVectorImpl_vTable.hasError := @ITraceStatusVectorImpl_hasErrorDispatcher; + ITraceStatusVectorImpl_vTable.hasWarning := @ITraceStatusVectorImpl_hasWarningDispatcher; + ITraceStatusVectorImpl_vTable.getStatus := @ITraceStatusVectorImpl_getStatusDispatcher; + ITraceStatusVectorImpl_vTable.getText := @ITraceStatusVectorImpl_getTextDispatcher; + + ITraceSweepInfoImpl_vTable := TraceSweepInfoVTable.create; + ITraceSweepInfoImpl_vTable.version := 5; + ITraceSweepInfoImpl_vTable.getOIT := @ITraceSweepInfoImpl_getOITDispatcher; + ITraceSweepInfoImpl_vTable.getOST := @ITraceSweepInfoImpl_getOSTDispatcher; + ITraceSweepInfoImpl_vTable.getOAT := @ITraceSweepInfoImpl_getOATDispatcher; + ITraceSweepInfoImpl_vTable.getNext := @ITraceSweepInfoImpl_getNextDispatcher; + ITraceSweepInfoImpl_vTable.getPerf := @ITraceSweepInfoImpl_getPerfDispatcher; + + ITraceLogWriterImpl_vTable := TraceLogWriterVTable.create; + ITraceLogWriterImpl_vTable.version := 3; + ITraceLogWriterImpl_vTable.addRef := @ITraceLogWriterImpl_addRefDispatcher; + ITraceLogWriterImpl_vTable.release := @ITraceLogWriterImpl_releaseDispatcher; + ITraceLogWriterImpl_vTable.write := @ITraceLogWriterImpl_writeDispatcher; + + ITraceInitInfoImpl_vTable := TraceInitInfoVTable.create; + ITraceInitInfoImpl_vTable.version := 7; + ITraceInitInfoImpl_vTable.getConfigText := @ITraceInitInfoImpl_getConfigTextDispatcher; + ITraceInitInfoImpl_vTable.getTraceSessionID := @ITraceInitInfoImpl_getTraceSessionIDDispatcher; + ITraceInitInfoImpl_vTable.getTraceSessionName := @ITraceInitInfoImpl_getTraceSessionNameDispatcher; + ITraceInitInfoImpl_vTable.getFirebirdRootDirectory := @ITraceInitInfoImpl_getFirebirdRootDirectoryDispatcher; + ITraceInitInfoImpl_vTable.getDatabaseName := @ITraceInitInfoImpl_getDatabaseNameDispatcher; + ITraceInitInfoImpl_vTable.getConnection := @ITraceInitInfoImpl_getConnectionDispatcher; + ITraceInitInfoImpl_vTable.getLogWriter := @ITraceInitInfoImpl_getLogWriterDispatcher; + + ITracePluginImpl_vTable := TracePluginVTable.create; + ITracePluginImpl_vTable.version := 23; + ITracePluginImpl_vTable.addRef := @ITracePluginImpl_addRefDispatcher; + ITracePluginImpl_vTable.release := @ITracePluginImpl_releaseDispatcher; + ITracePluginImpl_vTable.trace_get_error := @ITracePluginImpl_trace_get_errorDispatcher; + ITracePluginImpl_vTable.trace_attach := @ITracePluginImpl_trace_attachDispatcher; + ITracePluginImpl_vTable.trace_detach := @ITracePluginImpl_trace_detachDispatcher; + ITracePluginImpl_vTable.trace_transaction_start := @ITracePluginImpl_trace_transaction_startDispatcher; + ITracePluginImpl_vTable.trace_transaction_end := @ITracePluginImpl_trace_transaction_endDispatcher; + ITracePluginImpl_vTable.trace_proc_execute := @ITracePluginImpl_trace_proc_executeDispatcher; + ITracePluginImpl_vTable.trace_trigger_execute := @ITracePluginImpl_trace_trigger_executeDispatcher; + ITracePluginImpl_vTable.trace_set_context := @ITracePluginImpl_trace_set_contextDispatcher; + ITracePluginImpl_vTable.trace_dsql_prepare := @ITracePluginImpl_trace_dsql_prepareDispatcher; + ITracePluginImpl_vTable.trace_dsql_free := @ITracePluginImpl_trace_dsql_freeDispatcher; + ITracePluginImpl_vTable.trace_dsql_execute := @ITracePluginImpl_trace_dsql_executeDispatcher; + ITracePluginImpl_vTable.trace_blr_compile := @ITracePluginImpl_trace_blr_compileDispatcher; + ITracePluginImpl_vTable.trace_blr_execute := @ITracePluginImpl_trace_blr_executeDispatcher; + ITracePluginImpl_vTable.trace_dyn_execute := @ITracePluginImpl_trace_dyn_executeDispatcher; + ITracePluginImpl_vTable.trace_service_attach := @ITracePluginImpl_trace_service_attachDispatcher; + ITracePluginImpl_vTable.trace_service_start := @ITracePluginImpl_trace_service_startDispatcher; + ITracePluginImpl_vTable.trace_service_query := @ITracePluginImpl_trace_service_queryDispatcher; + ITracePluginImpl_vTable.trace_service_detach := @ITracePluginImpl_trace_service_detachDispatcher; + ITracePluginImpl_vTable.trace_event_error := @ITracePluginImpl_trace_event_errorDispatcher; + ITracePluginImpl_vTable.trace_event_sweep := @ITracePluginImpl_trace_event_sweepDispatcher; + ITracePluginImpl_vTable.trace_func_execute := @ITracePluginImpl_trace_func_executeDispatcher; + + ITraceFactoryImpl_vTable := TraceFactoryVTable.create; + ITraceFactoryImpl_vTable.version := 6; + ITraceFactoryImpl_vTable.addRef := @ITraceFactoryImpl_addRefDispatcher; + ITraceFactoryImpl_vTable.release := @ITraceFactoryImpl_releaseDispatcher; + ITraceFactoryImpl_vTable.setOwner := @ITraceFactoryImpl_setOwnerDispatcher; + ITraceFactoryImpl_vTable.getOwner := @ITraceFactoryImpl_getOwnerDispatcher; + ITraceFactoryImpl_vTable.trace_needs := @ITraceFactoryImpl_trace_needsDispatcher; + ITraceFactoryImpl_vTable.trace_create := @ITraceFactoryImpl_trace_createDispatcher; + + IUdrFunctionFactoryImpl_vTable := UdrFunctionFactoryVTable.create; + IUdrFunctionFactoryImpl_vTable.version := 3; + IUdrFunctionFactoryImpl_vTable.dispose := @IUdrFunctionFactoryImpl_disposeDispatcher; + IUdrFunctionFactoryImpl_vTable.setup := @IUdrFunctionFactoryImpl_setupDispatcher; + IUdrFunctionFactoryImpl_vTable.newItem := @IUdrFunctionFactoryImpl_newItemDispatcher; + + IUdrProcedureFactoryImpl_vTable := UdrProcedureFactoryVTable.create; + IUdrProcedureFactoryImpl_vTable.version := 3; + IUdrProcedureFactoryImpl_vTable.dispose := @IUdrProcedureFactoryImpl_disposeDispatcher; + IUdrProcedureFactoryImpl_vTable.setup := @IUdrProcedureFactoryImpl_setupDispatcher; + IUdrProcedureFactoryImpl_vTable.newItem := @IUdrProcedureFactoryImpl_newItemDispatcher; + + IUdrTriggerFactoryImpl_vTable := UdrTriggerFactoryVTable.create; + IUdrTriggerFactoryImpl_vTable.version := 3; + IUdrTriggerFactoryImpl_vTable.dispose := @IUdrTriggerFactoryImpl_disposeDispatcher; + IUdrTriggerFactoryImpl_vTable.setup := @IUdrTriggerFactoryImpl_setupDispatcher; + IUdrTriggerFactoryImpl_vTable.newItem := @IUdrTriggerFactoryImpl_newItemDispatcher; + + IUdrPluginImpl_vTable := UdrPluginVTable.create; + IUdrPluginImpl_vTable.version := 4; + IUdrPluginImpl_vTable.getMaster := @IUdrPluginImpl_getMasterDispatcher; + IUdrPluginImpl_vTable.registerFunction := @IUdrPluginImpl_registerFunctionDispatcher; + IUdrPluginImpl_vTable.registerProcedure := @IUdrPluginImpl_registerProcedureDispatcher; + IUdrPluginImpl_vTable.registerTrigger := @IUdrPluginImpl_registerTriggerDispatcher; + +finalization + IVersionedImpl_vTable.destroy; + IReferenceCountedImpl_vTable.destroy; + IDisposableImpl_vTable.destroy; + IStatusImpl_vTable.destroy; + IMasterImpl_vTable.destroy; + IPluginBaseImpl_vTable.destroy; + IPluginSetImpl_vTable.destroy; + IConfigEntryImpl_vTable.destroy; + IConfigImpl_vTable.destroy; + IFirebirdConfImpl_vTable.destroy; + IPluginConfigImpl_vTable.destroy; + IPluginFactoryImpl_vTable.destroy; + IPluginModuleImpl_vTable.destroy; + IPluginManagerImpl_vTable.destroy; + ICryptKeyImpl_vTable.destroy; + IConfigManagerImpl_vTable.destroy; + IEventCallbackImpl_vTable.destroy; + IBlobImpl_vTable.destroy; + ITransactionImpl_vTable.destroy; + IMessageMetadataImpl_vTable.destroy; + IMetadataBuilderImpl_vTable.destroy; + IResultSetImpl_vTable.destroy; + IStatementImpl_vTable.destroy; + IRequestImpl_vTable.destroy; + IEventsImpl_vTable.destroy; + IAttachmentImpl_vTable.destroy; + IServiceImpl_vTable.destroy; + IProviderImpl_vTable.destroy; + IDtcStartImpl_vTable.destroy; + IDtcImpl_vTable.destroy; + IAuthImpl_vTable.destroy; + IWriterImpl_vTable.destroy; + IServerBlockImpl_vTable.destroy; + IClientBlockImpl_vTable.destroy; + IServerImpl_vTable.destroy; + IClientImpl_vTable.destroy; + IUserFieldImpl_vTable.destroy; + ICharUserFieldImpl_vTable.destroy; + IIntUserFieldImpl_vTable.destroy; + IUserImpl_vTable.destroy; + IListUsersImpl_vTable.destroy; + ILogonInfoImpl_vTable.destroy; + IManagementImpl_vTable.destroy; + IWireCryptPluginImpl_vTable.destroy; + ICryptKeyCallbackImpl_vTable.destroy; + IKeyHolderPluginImpl_vTable.destroy; + IDbCryptPluginImpl_vTable.destroy; + IExternalContextImpl_vTable.destroy; + IExternalResultSetImpl_vTable.destroy; + IExternalFunctionImpl_vTable.destroy; + IExternalProcedureImpl_vTable.destroy; + IExternalTriggerImpl_vTable.destroy; + IRoutineMetadataImpl_vTable.destroy; + IExternalEngineImpl_vTable.destroy; + ITimerImpl_vTable.destroy; + ITimerControlImpl_vTable.destroy; + IVersionCallbackImpl_vTable.destroy; + IUtilImpl_vTable.destroy; + IOffsetsCallbackImpl_vTable.destroy; + IXpbBuilderImpl_vTable.destroy; + ITraceConnectionImpl_vTable.destroy; + ITraceDatabaseConnectionImpl_vTable.destroy; + ITraceTransactionImpl_vTable.destroy; + ITraceParamsImpl_vTable.destroy; + ITraceStatementImpl_vTable.destroy; + ITraceSQLStatementImpl_vTable.destroy; + ITraceBLRStatementImpl_vTable.destroy; + ITraceDYNRequestImpl_vTable.destroy; + ITraceContextVariableImpl_vTable.destroy; + ITraceProcedureImpl_vTable.destroy; + ITraceFunctionImpl_vTable.destroy; + ITraceTriggerImpl_vTable.destroy; + ITraceServiceConnectionImpl_vTable.destroy; + ITraceStatusVectorImpl_vTable.destroy; + ITraceSweepInfoImpl_vTable.destroy; + ITraceLogWriterImpl_vTable.destroy; + ITraceInitInfoImpl_vTable.destroy; + ITracePluginImpl_vTable.destroy; + ITraceFactoryImpl_vTable.destroy; + IUdrFunctionFactoryImpl_vTable.destroy; + IUdrProcedureFactoryImpl_vTable.destroy; + IUdrTriggerFactoryImpl_vTable.destroy; + IUdrPluginImpl_vTable.destroy; + +end. diff --git a/mseide-msegui/lib/common/db/ibase60.inc b/mseide-msegui/lib/common/db/ibase60.inc new file mode 100644 index 0000000..38c75cf --- /dev/null +++ b/mseide-msegui/lib/common/db/ibase60.inc @@ -0,0 +1,3241 @@ +{ +} +{$ifdef FPC}{$MODE objfpc}{$MACRO on}{$endif} + +interface + +{$IFDEF LinkDynamically} +uses + {$ifdef FPC}Dynlibs,{$else}{$endif} sysutils, msetypes{msestrings},msectypes; + +const + {$define cvcall} +{$ifdef mswindows} + {$define wincall} + fbembedlib: array[0..0] of filenamety = ('fbembed.dll'); + fbcgdslib: array[0..1] of filenamety = ('fbclient.dll','gds32.dll'); +{$else} + fbembedlib: array[0..4] of filenamety = ( + 'libfbembed.so.2.5','libfbembed.so.2.1','libfbembed.so.2', + 'libfbembed.so.1','libfbembed.so'); + fbcgdslib: array[0..3] of filenamety = ('libfbclient.so.2', + 'libfbclient.so.1','libfbclient.so','libgds.so'); +{$endif} + +var + useembeddedfirebird : boolean = false; + +procedure initializeibase60(const sonames: array of filenamety); + //[] = default +procedure releaseibase60; + +{$ENDIF} +(* +{$DEFINE extdeclvararg:= cdecl} + +{$IFDEF Unix} + {$DEFINE extdecl:=cdecl} +{ + const + gdslib = 'libgds.so'; + fbclib = 'libfbclient.so'; + fbembedlib = 'libfbembed.so'; +} +{$ENDIF} +{$IFDEF Win32} + {$DEFINE extdecl:=stdcall} +{ + const + gdslib = 'gds32.dll'; + fbclib = 'fbclient.dll'; + fbembedlib = 'fbembed.dll'; +} +{$ENDIF} +{$IFDEF Wince} + {$DEFINE extdecl:=stdcall} +{ + const + gdslib = 'gds32.dll'; + fbclib = 'fbclient.dll'; + fbembedlib = 'fbembed.dll'; +} +{$ENDIF} + +*) +type + { Unsigned types } + + UChar = Byte; + UShort = Word; + UInt = DWord; + ULong = DWord; + + { Signed types } + + Int = LongInt; + Long = LongInt; + Short = SmallInt; + Float = Single; + + { Pointers to basic types } + + PInt = ^Int; + PShort = ^Short; + PUShort = ^UShort; + PLong = ^Long; + PULong = ^ULong; + PFloat = ^Float; + PUChar = ^UChar; + PVoid = ^Pointer; + +{$ifdef FPC} + {$PACKRECORDS C} +{$else} + {$ALIGN 4} + {$MINENUMSIZE 4} +{$endif} + + const + ISC_TRUE = 1; + ISC_FALSE = 0; + const + ISC__TRUE = ISC_TRUE; + ISC__FALSE = ISC_FALSE; + +Type + ISC_USHORT = word; + ISC_STATUS = ptrint; //defined as intptr_t in types_pub.h + ISC_INT64 = int64; + ISC_UINT64 = qword; + ISC_LONG = Longint; + + PISC_USHORT = ^ISC_USHORT; + PISC_STATUS = ^ISC_STATUS; + PPISC_STATUS = ^PISC_STATUS; + PISC_INT64 = ^ISC_INT64; + PISC_UINT64 = ^ISC_UINT64; + PISC_LONG = ^ISC_LONG; + + {$IFDEF CPU64} + FB_API_HANDLE = cuint; + {$ELSE} + FB_API_HANDLE = pointer; + {$ENDIF} + + + const + {$IFDEF CPU64} + FB_API_NULLHANDLE = 0; + {$ELSE} + FB_API_NULLHANDLE = nil; + {$ENDIF} + DSQL_close = 1; + DSQL_drop = 2; + + {!!MVC + Removed all ISC_FAR, ISC_EXPORT_VARARG and ISC_EXPORT + macros. + They confuse h2pas... + !!MVC } + { } + { Time & Date Support } + { } +{$ifndef _ISC_TIMESTAMP_} + + type + + ISC_DATE = longint; + ISC_TIME = dword; + ISC_TIMESTAMP = record + timestamp_date : ISC_DATE; + timestamp_time : ISC_TIME; + end; + TISC_DATE = ISC_DATE; + TISC_TIME = ISC_TIME; + TISC_TIMESTAMP = ISC_TIMESTAMP; + PISC_DATE = ^ISC_DATE; + PISC_TIME = ^ISC_TIME; + PISC_TIMESTAMP = ^ISC_TIMESTAMP; + const + _ISC_TIMESTAMP_ = 1; +{$endif} + + const + ISC_TIME_SECONDS_PRECISION = 10000; + ISC_TIME_SECONDS_PRECISION_SCALE = -4; + { } + { Blob id structure } + { } + +Type + + GDS_QUAD = record + gds_quad_high : ISC_LONG; + gds_quad_low : ISC_LONG; + end; + TGDS_QUAD = GDS_QUAD; + PGDS_QUAD = ^GDS_QUAD; + +Type + ISC_QUAD = GDS_QUAD; + TISC_QUAD = ISC_QUAD; + PISC_QUAD = ^ISC_QUAD; + +{ !!field redefinitions !! + isc_quad_high = gds_quad_high; + isc_quad_low = gds_quad_low; +} + +type + + ISC_ARRAY_BOUND = record + array_bound_lower : smallint; + array_bound_upper : smallint; + end; + TISC_ARRAY_BOUND = ISC_ARRAY_BOUND; + PISC_ARRAY_BOUND = ^ISC_ARRAY_BOUND; + + ISC_ARRAY_DESC = record + array_desc_dtype : byte; + array_desc_scale : char; + array_desc_length : word; + array_desc_field_name : array[0..31] of char; + array_desc_relation_name : array[0..31] of char; + array_desc_dimensions : smallint; + array_desc_flags : smallint; + array_desc_bounds : array[0..15] of ISC_ARRAY_BOUND; + end; + TISC_ARRAY_DESC = ISC_ARRAY_DESC; + PISC_ARRAY_DESC = ^ISC_ARRAY_DESC; + + ISC_BLOB_DESC = record + blob_desc_subtype : smallint; + blob_desc_charset : smallint; + blob_desc_segment_size : smallint; + blob_desc_field_name : array[0..31] of byte; + blob_desc_relation_name : array[0..31] of byte; + end; + TISC_BLOB_DESC = ISC_BLOB_DESC; + PISC_BLOB_DESC = ^ISC_BLOB_DESC ; + { } + { Blob control structure } + { } + {!!MVC + !!MVC } + { Source filter } + {!!MVC + !!MVC } + { Argument to pass to source } + { filter } + { Target type } + { Source type } + { Length of buffer } + { Length of current segment } + { Length of blob parameter } + { block } + { Address of blob parameter } + { block } + { Address of segment buffer } + { Length of longest segment } + { Total number of segments } + { Total length of blob } + { Address of status vector } + { Application specific data } + TCTLSourceFunction = function : isc_long; + + PISC_BLOB_CTL = ^ISC_BLOB_CTL ; + ISC_BLOB_CTL = record + ctl_source : TCTLSourceFunction; // was ISC_STATUS ( *ctl_source)(); + ctl_source_handle : pisc_blob_ctl ; // was struct isc_blob_ctl * ctl_source_handle; + ctl_to_sub_type : smallint; + ctl_from_sub_type : smallint; + ctl_buffer_length : word; + ctl_segment_length : word; + ctl_bpb_length : word; + ctl_bpb : Pchar; + ctl_buffer : Pbyte; + ctl_max_segment : ISC_LONG; + ctl_number_segments : ISC_LONG; + ctl_total_length : ISC_LONG; + ctl_status : PISC_STATUS; + ctl_data : array[0..7] of longint; + end; + TISC_BLOB_CTL = ISC_BLOB_CTL; + + { } + { Blob stream definitions } + { } + { Blob handle } + { Address of buffer } + { Next character } + { Length of buffer } + { Characters in buffer } + { (mode) ? OUTPUT : INPUT } + + BSTREAM = record + bstr_blob : pointer; + bstr_buffer : Pchar; + bstr_ptr : Pchar; + bstr_length : smallint; + bstr_cnt : smallint; + bstr_mode : char; + end; + TBSTREAM = BSTREAM; + PBstream = ^BSTREAM; + { } + { Dynamic SQL definitions } + { } + { } + { Declare the extended SQLDA } + { } + { datatype of field } + { scale factor } + { datatype subtype - BLOBs & Text } + { types only } + { length of data area } + { address of data } + { address of indicator variable } + { length of sqlname field } + { name of field, name length + space } + { for NULL } + { length of relation name } + { field's relation name + space for } + { NULL } + { length of owner name } + { relation's owner name + space for } + { NULL } + { length of alias name } + { relation's alias name + space for } + { NULL } + + XSQLVAR = record + sqltype : smallint; + sqlscale : smallint; + sqlsubtype : smallint; + sqllen : smallint; + sqldata : Pchar; + sqlind : Psmallint; + sqlname_length : smallint; + sqlname : array[0..31] of char; + relname_length : smallint; + relname : array[0..31] of char; + ownname_length : smallint; + ownname : array[0..31] of char; + aliasname_length : smallint; + aliasname : array[0..31] of char; + end; + TXSQLVAR = XSQLVAR; + PXSQLVAR =^XSQLVAR; + { version of this XSQLDA } + { XSQLDA name field } + { length in bytes of SQLDA } + { number of fields allocated } + { actual number of fields } + { first field address } + + XSQLDA = record + version : smallint; + sqldaid : array[0..7] of char; + sqldabc : ISC_LONG; + sqln : smallint; + sqld : smallint; + sqlvar : array[0..0] of XSQLVAR; + end; + TXSQLDA = XSQLDA; + PXSQLDA =^XSQLDA; + + function XSQLDA_LENGTH(n: Integer): Integer; + + + const + SQLDA_VERSION1 = 1; + { meaning is same as DIALECT_xsqlda } + SQL_DIALECT_V5 = 1; + { flagging anything that is delimited + by double quotes as an error and + flagging keyword DATE as an error } + SQL_DIALECT_V6_TRANSITION = 2; + { supports SQL delimited identifier, + SQLDATE/DATE, TIME, TIMESTAMP, + CURRENT_DATE, CURRENT_TIME, + CURRENT_TIMESTAMP, and 64-bit exact + numeric type } + SQL_DIALECT_V6 = 3; + { latest IB DIALECT } + SQL_DIALECT_CURRENT = SQL_DIALECT_V6; + { } + { InterBase Handle Definitions } + { } + + type + isc_att_handle = FB_API_HANDLE; + isc_blob_handle = FB_API_HANDLE; + isc_db_handle = FB_API_HANDLE; + isc_form_handle = FB_API_HANDLE; + isc_req_handle = FB_API_HANDLE; + isc_stmt_handle = FB_API_HANDLE; + isc_svc_handle = FB_API_HANDLE; + isc_tr_handle = FB_API_HANDLE; + isc_win_handle = FB_API_HANDLE; + isc_callback = procedure; {$ifdef wincall}cdecl{stdcall}{$else}cdecl{$endif}; + isc_versioncallback = procedure(user_arg: pointer; atext: pchar); + {$ifdef wincall}cdecl{stdcall}{$else}cdecl{$endif}; + isc_resv_handle = ISC_LONG; + tisc_att_handle = isc_att_handle; + tisc_blob_handle = isc_blob_handle; + tisc_db_handle = isc_db_handle; + tisc_form_handle = isc_form_handle; + tisc_req_handle = isc_req_handle; + tisc_stmt_handle = isc_stmt_handle; + tisc_svc_handle = isc_svc_handle; + tisc_tr_handle = isc_tr_handle; + tisc_win_handle = isc_win_handle; + tisc_callback = isc_callback; + tisc_resv_handle = isc_resv_handle; + pisc_att_handle =^isc_att_handle ; + pisc_blob_handle =^isc_blob_handle ; + pisc_db_handle =^isc_db_handle ; + pisc_form_handle =^isc_form_handle ; + pisc_req_handle =^isc_req_handle ; + pisc_stmt_handle =^isc_stmt_handle ; + pisc_svc_handle =^isc_svc_handle ; + pisc_tr_handle =^isc_tr_handle ; + pisc_win_handle =^isc_win_handle ; + pisc_callback = ^isc_callback; + pisc_resv_handle =^isc_resv_handle ; + + + { } + { Security structures } + { } + + const + sec_uid_spec = $01; + sec_gid_spec = $02; + sec_server_spec = $04; + sec_password_spec = $08; + sec_group_name_spec = $10; + sec_first_name_spec = $20; + sec_middle_name_spec = $40; + sec_last_name_spec = $80; + sec_dba_user_name_spec = $100; + sec_dba_password_spec = $200; + sec_protocol_tcpip = 1; + sec_protocol_netbeui = 2; + sec_protocol_spx = 3; + sec_protocol_local = 4; + { which fields are specified } + { the user's id } + { the user's group id } + { protocol to use for connection } + { server to administer } + { the user's name } + { the user's password } + { the group name } + { the user's first name } + { the user's middle name } + { the user's last name } + { the dba user name } + { the dba password } + + type + + USER_SEC_DATA = record + sec_flags : smallint; + uid : longint; + gid : longint; + protocol : longint; + server : Pchar; + user_name : Pchar; + password : Pchar; + group_name : Pchar; + first_name : Pchar; + middle_name : Pchar; + last_name : Pchar; + dba_user_name : Pchar; + dba_password : Pchar; + end; + TUSER_SEC_DATA = USER_SEC_DATA; + PUSER_SEC_DATA = ^USER_SEC_DATA; + + { } + { Actions to pass to the blob filter (ctl_source) } + { } + + const + isc_blob_filter_open = 0; + isc_blob_filter_get_segment = 1; + isc_blob_filter_close = 2; + isc_blob_filter_create = 3; + isc_blob_filter_put_segment = 4; + isc_blob_filter_alloc = 5; + isc_blob_filter_free = 6; + isc_blob_filter_seek = 7; + { } + { Blr definitions } + { } +{$ifndef _JRD_BLR_H_} + + const + blr_text = 14; + blr_text2 = 15; + blr_short = 7; + blr_long = 8; + blr_quad = 9; + blr_int64 = 16; + blr_float = 10; + blr_double = 27; + blr_d_float = 11; + blr_timestamp = 35; + blr_varying = 37; + blr_varying2 = 38; + blr_blob = 261; + blr_cstring = 40; + blr_cstring2 = 41; + blr_blob_id = 45; + blr_sql_date = 12; + blr_sql_time = 13; + { Historical alias for pre V6 applications } + blr_date = blr_timestamp; + blr_inner = 0; + blr_left = 1; + blr_right = 2; + blr_full = 3; + blr_gds_code = 0; + blr_sql_code = 1; + blr_exception = 2; + blr_trigger_code = 3; + blr_default_code = 4; + blr_version4 = 4; + blr_version5 = 5; + blr_eoc = 76; + blr_end = 255; + blr_assignment = 1; + blr_begin = 2; + blr_dcl_variable = 3; + blr_message = 4; + blr_erase = 5; + blr_fetch = 6; + blr_for = 7; + blr_if = 8; + blr_loop = 9; + blr_modify = 10; + blr_handler = 11; + blr_receive = 12; + blr_select = 13; + blr_send = 14; + blr_store = 15; + blr_label = 17; + blr_leave = 18; + blr_store2 = 19; + blr_post = 20; + blr_literal = 21; + blr_dbkey = 22; + blr_field = 23; + blr_fid = 24; + blr_parameter = 25; + blr_variable = 26; + blr_average = 27; + blr_count = 28; + blr_maximum = 29; + blr_minimum = 30; + blr_total = 31; + blr_add = 34; + blr_subtract = 35; + blr_multiply = 36; + blr_divide = 37; + blr_negate = 38; + blr_concatenate = 39; + blr_substring = 40; + blr_parameter2 = 41; + blr_from = 42; + blr_via = 43; + blr_user_name = 44; + blr_null = 45; + blr_eql = 47; + blr_neq = 48; + blr_gtr = 49; + blr_geq = 50; + blr_lss = 51; + blr_leq = 52; + blr_containing = 53; + blr_matching = 54; + blr_starting = 55; + blr_between = 56; + blr_or = 57; + blr_and = 58; + blr_not = 59; + blr_any = 60; + blr_missing = 61; + blr_unique = 62; + blr_like = 63; + blr_stream = 65; + blr_set_index = 66; + blr_rse = 67; + blr_first = 68; + blr_project = 69; + blr_sort = 70; + blr_boolean = 71; + blr_ascending = 72; + blr_descending = 73; + blr_relation = 74; + blr_rid = 75; + blr_union = 76; + blr_map = 77; + blr_group_by = 78; + blr_aggregate = 79; + blr_join_type = 80; + blr_agg_count = 83; + blr_agg_max = 84; + blr_agg_min = 85; + blr_agg_total = 86; + blr_agg_average = 87; + blr_parameter3 = 88; + blr_run_count = 118; + blr_run_max = 89; + blr_run_min = 90; + blr_run_total = 91; + blr_run_average = 92; + blr_agg_count2 = 93; + blr_agg_count_distinct = 94; + blr_agg_total_distinct = 95; + blr_agg_average_distinct = 96; + blr_function = 100; + blr_gen_id = 101; + blr_prot_mask = 102; + blr_upcase = 103; + blr_lock_state = 104; + blr_value_if = 105; + blr_matching2 = 106; + blr_index = 107; + blr_ansi_like = 108; + blr_bookmark = 109; + blr_crack = 110; + blr_force_crack = 111; + blr_seek = 112; + blr_find = 113; + blr_continue = 0; + blr_forward = 1; + blr_backward = 2; + blr_bof_forward = 3; + blr_eof_backward = 4; + blr_lock_relation = 114; + blr_lock_record = 115; + blr_set_bookmark = 116; + blr_get_bookmark = 117; + blr_rs_stream = 119; + blr_exec_proc = 120; + blr_begin_range = 121; + blr_end_range = 122; + blr_delete_range = 123; + blr_procedure = 124; + blr_pid = 125; + blr_exec_pid = 126; + blr_singular = 127; + blr_abort = 128; + blr_block = 129; + blr_error_handler = 130; + blr_cast = 131; + blr_release_lock = 132; + blr_release_locks = 133; + blr_start_savepoint = 134; + blr_end_savepoint = 135; + blr_find_dbkey = 136; + blr_range_relation = 137; + blr_delete_ranges = 138; + blr_plan = 139; + blr_merge = 140; + blr_join = 141; + blr_sequential = 142; + blr_navigational = 143; + blr_indices = 144; + blr_retrieve = 145; + blr_relation2 = 146; + blr_rid2 = 147; + blr_reset_stream = 148; + blr_release_bookmark = 149; + blr_set_generator = 150; + blr_ansi_any = 151; + blr_exists = 152; + blr_cardinality = 153; + { get tid of record } + blr_record_version = 154; + { fake server stall } + blr_stall = 155; + blr_seek_no_warn = 156; + blr_find_dbkey_version = 157; + blr_ansi_all = 158; + blr_extract = 159; + { sub parameters for blr_extract } + blr_extract_year = 0; + blr_extract_month = 1; + blr_extract_day = 2; + blr_extract_hour = 3; + blr_extract_minute = 4; + blr_extract_second = 5; + blr_extract_weekday = 6; + blr_extract_yearday = 7; + blr_current_date = 160; + blr_current_timestamp = 161; + blr_current_time = 162; + { These verbs were added in 6.0, primarily to support 64-bit integers } + blr_add2 = 163; + blr_subtract2 = 164; + blr_multiply2 = 165; + blr_divide2 = 166; + blr_agg_total2 = 167; + blr_agg_total_distinct2 = 168; + blr_agg_average2 = 169; + blr_agg_average_distinct2 = 170; + blr_average2 = 171; + blr_gen_id2 = 172; + blr_set_generator2 = 173; +{$endif} + { _JRD_BLR_H_ } + { } + { Database parameter block stuff } + { } + + const + isc_dpb_version1 = 1; + isc_dpb_cdd_pathname = 1; + isc_dpb_allocation = 2; + isc_dpb_journal = 3; + isc_dpb_page_size = 4; + isc_dpb_num_buffers = 5; + isc_dpb_buffer_length = 6; + isc_dpb_debug = 7; + isc_dpb_garbage_collect = 8; + isc_dpb_verify = 9; + isc_dpb_sweep = 10; + isc_dpb_enable_journal = 11; + isc_dpb_disable_journal = 12; + isc_dpb_dbkey_scope = 13; + isc_dpb_number_of_users = 14; + isc_dpb_trace = 15; + isc_dpb_no_garbage_collect = 16; + isc_dpb_damaged = 17; + isc_dpb_license = 18; + isc_dpb_sys_user_name = 19; + isc_dpb_encrypt_key = 20; + isc_dpb_activate_shadow = 21; + isc_dpb_sweep_interval = 22; + isc_dpb_delete_shadow = 23; + isc_dpb_force_write = 24; + isc_dpb_begin_log = 25; + isc_dpb_quit_log = 26; + isc_dpb_no_reserve = 27; + isc_dpb_user_name = 28; + isc_dpb_password = 29; + isc_dpb_password_enc = 30; + isc_dpb_sys_user_name_enc = 31; + isc_dpb_interp = 32; + isc_dpb_online_dump = 33; + isc_dpb_old_file_size = 34; + isc_dpb_old_num_files = 35; + isc_dpb_old_file = 36; + isc_dpb_old_start_page = 37; + isc_dpb_old_start_seqno = 38; + isc_dpb_old_start_file = 39; + isc_dpb_drop_walfile = 40; + isc_dpb_old_dump_id = 41; + isc_dpb_wal_backup_dir = 42; + isc_dpb_wal_chkptlen = 43; + isc_dpb_wal_numbufs = 44; + isc_dpb_wal_bufsize = 45; + isc_dpb_wal_grp_cmt_wait = 46; + isc_dpb_lc_messages = 47; + isc_dpb_lc_ctype = 48; + isc_dpb_cache_manager = 49; + isc_dpb_shutdown = 50; + isc_dpb_online = 51; + isc_dpb_shutdown_delay = 52; + isc_dpb_reserved = 53; + isc_dpb_overwrite = 54; + isc_dpb_sec_attach = 55; + isc_dpb_disable_wal = 56; + isc_dpb_connect_timeout = 57; + isc_dpb_dummy_packet_interval = 58; + isc_dpb_gbak_attach = 59; + isc_dpb_sql_role_name = 60; + isc_dpb_set_page_buffers = 61; + isc_dpb_working_directory = 62; + isc_dpb_SQL_dialect = 63; + isc_dpb_set_db_readonly = 64; + isc_dpb_set_db_SQL_dialect = 65; + isc_dpb_gfix_attach = 66; + isc_dpb_gstat_attach = 67; + { } + { isc_dpb_verify specific flags } + { } + isc_dpb_pages = 1; + isc_dpb_records = 2; + isc_dpb_indices = 4; + isc_dpb_transactions = 8; + isc_dpb_no_update = 16; + isc_dpb_repair = 32; + isc_dpb_ignore = 64; + { } + { isc_dpb_shutdown specific flags } + { } + isc_dpb_shut_cache = 1; + isc_dpb_shut_attachment = 2; + isc_dpb_shut_transaction = 4; + isc_dpb_shut_force = 8; + { } + { Bit assignments in RDB$SYSTEM_FLAG } + { } + RDB_system = 1; + RDB_id_assigned = 2; + { } + { Transaction parameter block stuff } + { } + isc_tpb_version1 = 1; + isc_tpb_version3 = 3; + isc_tpb_consistency = 1; + isc_tpb_concurrency = 2; + isc_tpb_shared = 3; + isc_tpb_protected = 4; + isc_tpb_exclusive = 5; + isc_tpb_wait = 6; + isc_tpb_nowait = 7; + isc_tpb_read = 8; + isc_tpb_write = 9; + isc_tpb_lock_read = 10; + isc_tpb_lock_write = 11; + isc_tpb_verb_time = 12; + isc_tpb_commit_time = 13; + isc_tpb_ignore_limbo = 14; + isc_tpb_read_committed = 15; + isc_tpb_autocommit = 16; + isc_tpb_rec_version = 17; + isc_tpb_no_rec_version = 18; + isc_tpb_restart_requests = 19; + isc_tpb_no_auto_undo = 20; + isc_tpb_lock_timeout = 21; //TPB = #21,#4, + + { Blob Parameter Block } + { } + isc_bpb_version1 = 1; + isc_bpb_source_type = 1; + isc_bpb_target_type = 2; + isc_bpb_type = 3; + isc_bpb_source_interp = 4; + isc_bpb_target_interp = 5; + isc_bpb_filter_parameter = 6; + isc_bpb_type_segmented = 0; + isc_bpb_type_stream = 1; + + { } + { Service parameter block stuff } + { } + isc_spb_version1 = 1; + isc_spb_current_version = 2; + isc_spb_version = isc_spb_current_version; + isc_spb_user_name = isc_dpb_user_name; //shortstring + isc_spb_sys_user_name = isc_dpb_sys_user_name; + isc_spb_sys_user_name_enc = isc_dpb_sys_user_name_enc; + isc_spb_password = isc_dpb_password; //shortstring + isc_spb_password_enc = isc_dpb_password_enc; + isc_spb_command_line = 105; + isc_spb_dbname = 106; + isc_spb_verbose = 107; + isc_spb_options = 108; + isc_spb_address_path = 109; + isc_spb_process_id = 110; + isc_spb_trusted_auth = 111; + isc_spb_process_name = 112; + isc_spb_trusted_role = 113; + + isc_spb_connect_timeout = isc_dpb_connect_timeout; + isc_spb_dummy_packet_interval = isc_dpb_dummy_packet_interval; + isc_spb_sql_role_name = isc_dpb_sql_role_name; + { + Service action items + } + { Starts database backup process on the server } + isc_action_svc_backup = 1; + { Starts database restore process on the server } + isc_action_svc_restore = 2; + { Starts database repair process on the server } + isc_action_svc_repair = 3; + { Adds a new user to the security database } + isc_action_svc_add_user = 4; + { Deletes a user record from the security database } + isc_action_svc_delete_user = 5; + { Modifies a user record in the security database } + isc_action_svc_modify_user = 6; + { Displays a user record from the security database } + isc_action_svc_display_user = 7; + { Sets database properties } + isc_action_svc_properties = 8; + { Adds a license to the license file } + isc_action_svc_add_license = 9; + { Removes a license from the license file } + isc_action_svc_remove_license = 10; + { Retrieves database statistics } + isc_action_svc_db_stats = 11; + { Retrieves the InterBase log file from the server } + isc_action_svc_get_ib_log = 12; + isc_action_svc_get_fb_log = 12; + //* Retrieves the Firebird log file from the server */ + isc_action_svc_nbak = 20; //* Incremental nbackup */ + isc_action_svc_nrest = 21; //* Incremental database restore */ + isc_action_svc_trace_start = 22; // Start trace session + isc_action_svc_trace_stop = 23; // Stop trace session + isc_action_svc_trace_suspend = 24; // Suspend trace session + isc_action_svc_trace_resume = 25; // Resume trace session + isc_action_svc_trace_list = 26; // List existing sessions + isc_action_svc_set_mapping = 27; + // Set auto admins mapping in security database + isc_action_svc_drop_mapping = 28; + // Drop auto admins mapping in security database + isc_action_svc_display_user_adm = 29; + // Displays user(s) from security database with admin info + isc_action_svc_validate = 30; // Starts database online validation + isc_action_svc_last = 31; // keep it last ! + { + Service information items + } + { Retrieves the number of attachments and databases } + isc_info_svc_svr_db_info = 50; + { Retrieves all license keys and IDs from the license file } + isc_info_svc_get_license = 51; + { Retrieves a bitmask representing licensed options on the server } + isc_info_svc_get_license_mask = 52; + { Retrieves the parameters and values for IB_CONFIG } + isc_info_svc_get_config = 53; //mse: not implemented in fb 2.5.5 + { Retrieves the version of the services manager } + isc_info_svc_version = 54; //card32 + { Retrieves the version of the InterBase server } + isc_info_svc_server_version = 55; //string + { Retrieves the implementation of the InterBase server } + isc_info_svc_implementation = 56; //string + { Retrieves a bitmask representing the server's capabilities } + isc_info_svc_capabilities = 57; //card32 + { Retrieves the path to the security database in use by the server } + isc_info_svc_user_dbpath = 58; //string + { Retrieves the setting of $INTERBASE } + isc_info_svc_get_env = 59; //string + { Retrieves the setting of $INTERBASE_LCK } + isc_info_svc_get_env_lock = 60; //string + { Retrieves the setting of $INTERBASE_MSG } + isc_info_svc_get_env_msg = 61; //string + { Retrieves 1 line of service output per call + mse: up to the size of buffer, remaining text of line in next call + adds a ' ' at end if line, string length 0 -> eof} + isc_info_svc_line = 62; + { Retrieves as much of the server output as will fit in the supplied buffer } + //mse: length 0 -> eof + isc_info_svc_to_eof = 63; + { Sets / signifies a timeout value for reading service information } + isc_info_svc_timeout = 64; + // 4byte 4byte + //mse send params = isc_info_svc_timeout <4> isc_info_end + { Retrieves the number of users licensed for accessing the server } + isc_info_svc_get_licensed_users = 65; + { Retrieve the limbo transactions } + isc_info_svc_limbo_trans = 66; + { Checks to see if a service is running on an attachment } + isc_info_svc_running = 67; + { Returns the user information from isc_action_svc_display_users } + isc_info_svc_get_users = 68; + isc_info_svc_stdin = 78; + //* Returns size of data, needed as stdin for service */ + { + Parameters for isc_action_(add|delete|modify)_user + } + isc_spb_sec_userid = 5; //card32 + isc_spb_sec_groupid = 6; //card32 + isc_spb_sec_username = 7; //string + isc_spb_sec_password = 8; + isc_spb_sec_groupname = 9; + isc_spb_sec_firstname = 10; //string + isc_spb_sec_middlename = 11; + isc_spb_sec_lastname = 12; //string + isc_spb_sec_admin = 13; //card32 + { + Parameters for isc_action_svc_(add|remove)_license, + isc_info_svc_get_license + } + isc_spb_lic_key = 5; + isc_spb_lic_id = 6; + isc_spb_lic_desc = 7; + { + Parameters for isc_action_svc_properties + } + isc_spb_prp_page_buffers = 5; + isc_spb_prp_sweep_interval = 6; + isc_spb_prp_shutdown_db = 7; + isc_spb_prp_deny_new_attachments = 9; + isc_spb_prp_deny_new_transactions = 10; + isc_spb_prp_reserve_space = 11; + isc_spb_prp_write_mode = 12; + isc_spb_prp_access_mode = 13; + isc_spb_prp_set_sql_dialect = 14; + isc_spb_prp_activate = $0100; + isc_spb_prp_db_online = $0200; + isc_spb_prp_force_shutdown = 41; + isc_spb_prp_attachments_shutdown = 42; + isc_spb_prp_transactions_shutdown = 43; + isc_spb_prp_shutdown_mode = 44; + isc_spb_prp_online_mode = 45; +///******************************************** +// * Parameters for isc_spb_prp_shutdown_mode * +// * and isc_spb_prp_online_mode * +// ********************************************/ + isc_spb_prp_sm_normal = 0; + isc_spb_prp_sm_multi = 1; + isc_spb_prp_sm_single = 2; + isc_spb_prp_sm_full = 3; + + { + Parameters for isc_spb_prp_reserve_space + } + isc_spb_prp_res_use_full = 35; + isc_spb_prp_res = 36; + { + Parameters for isc_spb_prp_write_mode + } + isc_spb_prp_wm_async = 37; + isc_spb_prp_wm_sync = 38; + { + Parameters for isc_spb_prp_access_mode + } + isc_spb_prp_am_readonly = 39; + isc_spb_prp_am_readwrite = 40; + { + Parameters for isc_action_svc_backup + } + isc_spb_bkp_file = 5; + isc_spb_bkp_factor = 6; + isc_spb_bkp_length = 7; + isc_spb_bkp_stat = 15; + isc_spb_bkp_ignore_checksums = $01; + isc_spb_bkp_ignore_limbo = $02; + isc_spb_bkp_metadata_only = $04; + isc_spb_bkp_no_garbage_collect = $08; + isc_spb_bkp_old_descriptions = $10; + isc_spb_bkp_non_transportable = $20; + isc_spb_bkp_convert = $40; + isc_spb_bkp_expand = $80; + isc_spb_bkp_no_triggers = $8000; + { + Parameters for isc_action_svc_restore + } + isc_spb_res_buffers = 9; + isc_spb_res_page_size = 10; + isc_spb_res_length = 11; + isc_spb_res_access_mode = 12; + isc_spb_res_fix_fss_data = 13; + isc_spb_res_fix_fss_metadata = 14; + isc_spb_res_stat = isc_spb_bkp_stat; + isc_spb_res_metadata_only = isc_spb_bkp_metadata_only; + isc_spb_res_deactivate_idx = $0100; + isc_spb_res_no_shadow = $0200; + isc_spb_res_no_validity = $0400; + isc_spb_res_one_at_a_time = $0800; + isc_spb_res_replace = $1000; + isc_spb_res_create = $2000; + isc_spb_res_use_all_space = $4000; + +///***************************************** +// * Parameters for isc_action_svc_validate * +// *****************************************/ + isc_spb_val_tab_incl = 1; // include filter based on regular expression + isc_spb_val_tab_excl = 2; // exclude filter based on regular expression + isc_spb_val_idx_incl = 3; // regexp of indices to validate + isc_spb_val_idx_excl = 4; // regexp of indices to NOT validate + isc_spb_val_lock_timeout = 5; // how long to wait for table lock + { + Parameters for isc_action_svc_repair + } + isc_spb_rpr_commit_trans = 15; + isc_spb_rpr_rollback_trans = 34; + isc_spb_rpr_recover_two_phase = 17; + isc_spb_tra_id = 18; + isc_spb_single_tra_id = 19; + isc_spb_multi_tra_id = 20; + isc_spb_tra_state = 21; + isc_spb_tra_state_limbo = 22; + isc_spb_tra_state_commit = 23; + isc_spb_tra_state_rollback = 24; + isc_spb_tra_state_unknown = 25; + isc_spb_tra_host_site = 26; + isc_spb_tra_remote_site = 27; + isc_spb_tra_db_path = 28; + isc_spb_tra_advise = 29; + isc_spb_tra_advise_commit = 30; + isc_spb_tra_advise_rollback = 31; + isc_spb_tra_advise_unknown = 33; + isc_spb_rpr_validate_db = $01; + isc_spb_rpr_sweep_db = $02; + isc_spb_rpr_mend_db = $04; + isc_spb_rpr_list_limbo_trans = $08; + isc_spb_rpr_check_db = $10; + isc_spb_rpr_ignore_checksum = $20; + isc_spb_rpr_kill_shadows = $40; + isc_spb_rpr_full = $80; + { + Parameters for isc_spb_res_access_mode + } + isc_spb_res_am_readonly = isc_spb_prp_am_readonly; + isc_spb_res_am_readwrite = isc_spb_prp_am_readwrite; + { + Parameters for isc_info_svc_svr_db_info + } + isc_spb_num_att = 5; + isc_spb_num_db = 6; + { + Parameters for isc_info_svc_db_stats + } + isc_spb_sts_data_pages = $01; + isc_spb_sts_db_log = $02; + isc_spb_sts_hdr_pages = $04; + isc_spb_sts_idx_pages = $08; + isc_spb_sts_sys_relations = $10; + isc_spb_sts_record_versions = $20; + isc_spb_sts_table = $40; + isc_spb_sts_nocreation = $80; + +//* Not available in Firebird 1.5 */ + +///*************************************** +// * Parameters for isc_action_svc_nbak * +// ***************************************/ + + isc_spb_nbk_level = 5; + isc_spb_nbk_file = 6; + isc_spb_nbk_direct = 7; + isc_spb_nbk_no_triggers = $01; + +///*************************************** +// * Parameters for isc_action_svc_trace * +// ***************************************/ + + isc_spb_trc_id = 1; + isc_spb_trc_name = 2; + isc_spb_trc_cfg = 3; + + + { } + { Information call declarations } + { } + { } + { Common, structural codes } + { } + isc_info_end = 1; + isc_info_truncated = 2; + isc_info_error = 3; + isc_info_data_not_ready = 4; + isc_info_flag_end = 127; + { } + { Database information items } + { } + isc_info_db_id = 4; + isc_info_reads = 5; + isc_info_writes = 6; + isc_info_fetches = 7; + isc_info_marks = 8; + isc_info_implementation = 11; + isc_info_version = 12; + isc_info_base_level = 13; + isc_info_page_size = 14; + isc_info_num_buffers = 15; + isc_info_limbo = 16; + isc_info_current_memory = 17; + isc_info_max_memory = 18; + isc_info_window_turns = 19; + isc_info_license = 20; + isc_info_allocation = 21; + isc_info_attachment_id = 22; + isc_info_read_seq_count = 23; + isc_info_read_idx_count = 24; + isc_info_insert_count = 25; + isc_info_update_count = 26; + isc_info_delete_count = 27; + isc_info_backout_count = 28; + isc_info_purge_count = 29; + isc_info_expunge_count = 30; + isc_info_sweep_interval = 31; + isc_info_ods_version = 32; + isc_info_ods_minor_version = 33; + isc_info_no_reserve = 34; + isc_info_logfile = 35; + isc_info_cur_logfile_name = 36; + isc_info_cur_log_part_offset = 37; + isc_info_num_wal_buffers = 38; + isc_info_wal_buffer_size = 39; + isc_info_wal_ckpt_length = 40; + isc_info_wal_cur_ckpt_interval = 41; + isc_info_wal_prv_ckpt_fname = 42; + isc_info_wal_prv_ckpt_poffset = 43; + isc_info_wal_recv_ckpt_fname = 44; + isc_info_wal_recv_ckpt_poffset = 45; + isc_info_wal_grpc_wait_usecs = 47; + isc_info_wal_num_io = 48; + isc_info_wal_avg_io_size = 49; + isc_info_wal_num_commits = 50; + isc_info_wal_avg_grpc_size = 51; + isc_info_forced_writes = 52; + isc_info_user_names = 53; + isc_info_page_errors = 54; + isc_info_record_errors = 55; + isc_info_bpage_errors = 56; + isc_info_dpage_errors = 57; + isc_info_ipage_errors = 58; + isc_info_ppage_errors = 59; + isc_info_tpage_errors = 60; + isc_info_set_page_buffers = 61; + isc_info_db_SQL_dialect = 62; + isc_info_db_read_only = 63; + isc_info_db_size_in_pages = 64; + { } + { Database information return values } + { } + isc_info_db_impl_rdb_vms = 1; + isc_info_db_impl_rdb_eln = 2; + isc_info_db_impl_rdb_eln_dev = 3; + isc_info_db_impl_rdb_vms_y = 4; + isc_info_db_impl_rdb_eln_y = 5; + isc_info_db_impl_jri = 6; + isc_info_db_impl_jsv = 7; + isc_info_db_impl_isc_a = 25; + isc_info_db_impl_isc_u = 26; + isc_info_db_impl_isc_v = 27; + isc_info_db_impl_isc_s = 28; + isc_info_db_impl_isc_apl_68K = 25; + isc_info_db_impl_isc_vax_ultr = 26; + isc_info_db_impl_isc_vms = 27; + isc_info_db_impl_isc_sun_68k = 28; + isc_info_db_impl_isc_os2 = 29; + isc_info_db_impl_isc_sun4 = 30; + isc_info_db_impl_isc_hp_ux = 31; + isc_info_db_impl_isc_sun_386i = 32; + isc_info_db_impl_isc_vms_orcl = 33; + isc_info_db_impl_isc_mac_aux = 34; + isc_info_db_impl_isc_rt_aix = 35; + isc_info_db_impl_isc_mips_ult = 36; + isc_info_db_impl_isc_xenix = 37; + isc_info_db_impl_isc_dg = 38; + isc_info_db_impl_isc_hp_mpexl = 39; + isc_info_db_impl_isc_hp_ux68K = 40; + isc_info_db_impl_isc_sgi = 41; + isc_info_db_impl_isc_sco_unix = 42; + isc_info_db_impl_isc_cray = 43; + isc_info_db_impl_isc_imp = 44; + isc_info_db_impl_isc_delta = 45; + isc_info_db_impl_isc_next = 46; + isc_info_db_impl_isc_dos = 47; + isc_info_db_impl_isc_winnt = 48; + isc_info_db_impl_isc_epson = 49; + isc_info_db_class_access = 1; + isc_info_db_class_y_valve = 2; + isc_info_db_class_rem_int = 3; + isc_info_db_class_rem_srvr = 4; + isc_info_db_class_pipe_int = 7; + isc_info_db_class_pipe_srvr = 8; + isc_info_db_class_sam_int = 9; + isc_info_db_class_sam_srvr = 10; + isc_info_db_class_gateway = 11; + isc_info_db_class_cache = 12; + { } + { Request information items } + { } + isc_info_number_messages = 4; + isc_info_max_message = 5; + isc_info_max_send = 6; + isc_info_max_receive = 7; + isc_info_state = 8; + isc_info_message_number = 9; + isc_info_message_size = 10; + isc_info_request_cost = 11; + isc_info_access_path = 12; + isc_info_req_select_count = 13; + isc_info_req_insert_count = 14; + isc_info_req_update_count = 15; + isc_info_req_delete_count = 16; + { } + { Access path items } + { } + isc_info_rsb_end = 0; + isc_info_rsb_begin = 1; + isc_info_rsb_type = 2; + isc_info_rsb_relation = 3; + isc_info_rsb_plan = 4; + { } + { Rsb types } + { } + isc_info_rsb_unknown = 1; + isc_info_rsb_indexed = 2; + isc_info_rsb_navigate = 3; + isc_info_rsb_sequential = 4; + isc_info_rsb_cross = 5; + isc_info_rsb_sort = 6; + isc_info_rsb_first = 7; + isc_info_rsb_boolean = 8; + isc_info_rsb_union = 9; + isc_info_rsb_aggregate = 10; + isc_info_rsb_merge = 11; + isc_info_rsb_ext_sequential = 12; + isc_info_rsb_ext_indexed = 13; + isc_info_rsb_ext_dbkey = 14; + isc_info_rsb_left_cross = 15; + isc_info_rsb_select = 16; + isc_info_rsb_sql_join = 17; + isc_info_rsb_simulate = 18; + isc_info_rsb_sim_cross = 19; + isc_info_rsb_once = 20; + isc_info_rsb_procedure = 21; + { } + { Bitmap expressions } + { } + isc_info_rsb_and = 1; + isc_info_rsb_or = 2; + isc_info_rsb_dbkey = 3; + isc_info_rsb_index = 4; + isc_info_req_active = 2; + isc_info_req_inactive = 3; + isc_info_req_send = 4; + isc_info_req_receive = 5; + isc_info_req_select = 6; + isc_info_req_sql_stall = 7; + { } + { Blob information items } + { } + isc_info_blob_num_segments = 4; + isc_info_blob_max_segment = 5; + isc_info_blob_total_length = 6; + isc_info_blob_type = 7; + { } + { Transaction information items } + { } + isc_info_tra_id = 4; + { } + { SQL information items } + { } + isc_info_sql_select = 4; + isc_info_sql_bind = 5; + isc_info_sql_num_variables = 6; + isc_info_sql_describe_vars = 7; + isc_info_sql_describe_end = 8; + isc_info_sql_sqlda_seq = 9; + isc_info_sql_message_seq = 10; + isc_info_sql_type = 11; + isc_info_sql_sub_type = 12; + isc_info_sql_scale = 13; + isc_info_sql_length = 14; + isc_info_sql_null_ind = 15; + isc_info_sql_field = 16; + isc_info_sql_relation = 17; + isc_info_sql_owner = 18; + isc_info_sql_alias = 19; + isc_info_sql_sqlda_start = 20; + isc_info_sql_stmt_type = 21; + isc_info_sql_get_plan = 22; + isc_info_sql_records = 23; + isc_info_sql_batch_fetch = 24; + { } + { SQL information return values } + { } + isc_info_sql_stmt_select = 1; + isc_info_sql_stmt_insert = 2; + isc_info_sql_stmt_update = 3; + isc_info_sql_stmt_delete = 4; + isc_info_sql_stmt_ddl = 5; + isc_info_sql_stmt_get_segment = 6; + isc_info_sql_stmt_put_segment = 7; + isc_info_sql_stmt_exec_procedure = 8; + isc_info_sql_stmt_start_trans = 9; + isc_info_sql_stmt_commit = 10; + isc_info_sql_stmt_rollback = 11; + isc_info_sql_stmt_select_for_upd = 12; + isc_info_sql_stmt_set_generator = 13; + { } + { Server configuration key values } + { } + ISCCFG_LOCKMEM_KEY = 0; + ISCCFG_LOCKSEM_KEY = 1; + ISCCFG_LOCKSIG_KEY = 2; + ISCCFG_EVNTMEM_KEY = 3; + ISCCFG_DBCACHE_KEY = 4; + ISCCFG_PRIORITY_KEY = 5; + ISCCFG_IPCMAP_KEY = 6; + ISCCFG_MEMMIN_KEY = 7; + ISCCFG_MEMMAX_KEY = 8; + ISCCFG_LOCKORDER_KEY = 9; + ISCCFG_ANYLOCKMEM_KEY = 10; + ISCCFG_ANYLOCKSEM_KEY = 11; + ISCCFG_ANYLOCKSIG_KEY = 12; + ISCCFG_ANYEVNTMEM_KEY = 13; + ISCCFG_LOCKHASH_KEY = 14; + ISCCFG_DEADLOCK_KEY = 15; + ISCCFG_LOCKSPIN_KEY = 16; + ISCCFG_CONN_TIMEOUT_KEY = 17; + ISCCFG_DUMMY_INTRVL_KEY = 18; + { Internal Use only } + ISCCFG_TRACE_POOLS_KEY = 19; + ISCCFG_REMOTE_BUFFER_KEY = 20; + { } + { Error codes } + { } + isc_facility = 20; + isc_err_base = 335544320; + isc_err_factor = 1; + isc_arg_end = 0; + isc_arg_gds = 1; + isc_arg_string = 2; + isc_arg_cstring = 3; + isc_arg_number = 4; + isc_arg_interpreted = 5; + isc_arg_vms = 6; + isc_arg_unix = 7; + isc_arg_domain = 8; + isc_arg_dos = 9; + isc_arg_mpexl = 10; + isc_arg_mpexl_ipc = 11; + isc_arg_next_mach = 15; + isc_arg_netware = 16; + isc_arg_win32 = 17; + isc_arg_warning = 18; + + { } + { Dynamic Data Definition Language operators } + { } + { } + { Version number } + { } + + const + isc_dyn_version_1 = 1; + isc_dyn_eoc = 255; + { } + { Operations (may be nested) } + { } + isc_dyn_begin = 2; + isc_dyn_end = 3; + isc_dyn_if = 4; + isc_dyn_def_database = 5; + isc_dyn_def_global_fld = 6; + isc_dyn_def_local_fld = 7; + isc_dyn_def_idx = 8; + isc_dyn_def_rel = 9; + isc_dyn_def_sql_fld = 10; + isc_dyn_def_view = 12; + isc_dyn_def_trigger = 15; + isc_dyn_def_security_class = 120; + isc_dyn_def_dimension = 140; + isc_dyn_def_generator = 24; + isc_dyn_def_function = 25; + isc_dyn_def_filter = 26; + isc_dyn_def_function_arg = 27; + isc_dyn_def_shadow = 34; + isc_dyn_def_trigger_msg = 17; + isc_dyn_def_file = 36; + isc_dyn_mod_database = 39; + isc_dyn_mod_rel = 11; + isc_dyn_mod_global_fld = 13; + isc_dyn_mod_idx = 102; + isc_dyn_mod_local_fld = 14; + isc_dyn_mod_sql_fld = 216; + isc_dyn_mod_view = 16; + isc_dyn_mod_security_class = 122; + isc_dyn_mod_trigger = 113; + isc_dyn_mod_trigger_msg = 28; + isc_dyn_delete_database = 18; + isc_dyn_delete_rel = 19; + isc_dyn_delete_global_fld = 20; + isc_dyn_delete_local_fld = 21; + isc_dyn_delete_idx = 22; + isc_dyn_delete_security_class = 123; + isc_dyn_delete_dimensions = 143; + isc_dyn_delete_trigger = 23; + isc_dyn_delete_trigger_msg = 29; + isc_dyn_delete_filter = 32; + isc_dyn_delete_function = 33; + isc_dyn_delete_shadow = 35; + isc_dyn_grant = 30; + isc_dyn_revoke = 31; + isc_dyn_def_primary_key = 37; + isc_dyn_def_foreign_key = 38; + isc_dyn_def_unique = 40; + isc_dyn_def_procedure = 164; + isc_dyn_delete_procedure = 165; + isc_dyn_def_parameter = 135; + isc_dyn_delete_parameter = 136; + isc_dyn_mod_procedure = 175; + isc_dyn_def_log_file = 176; + isc_dyn_def_cache_file = 180; + isc_dyn_def_exception = 181; + isc_dyn_mod_exception = 182; + isc_dyn_del_exception = 183; + isc_dyn_drop_log = 194; + isc_dyn_drop_cache = 195; + isc_dyn_def_default_log = 202; + { } + { View specific stuff } + { } + isc_dyn_view_blr = 43; + isc_dyn_view_source = 44; + isc_dyn_view_relation = 45; + isc_dyn_view_context = 46; + isc_dyn_view_context_name = 47; + { } + { Generic attributes } + { } + isc_dyn_rel_name = 50; + isc_dyn_fld_name = 51; + isc_dyn_new_fld_name = 215; + isc_dyn_idx_name = 52; + isc_dyn_description = 53; + isc_dyn_security_class = 54; + isc_dyn_system_flag = 55; + isc_dyn_update_flag = 56; + isc_dyn_prc_name = 166; + isc_dyn_prm_name = 137; + isc_dyn_sql_object = 196; + isc_dyn_fld_character_set_name = 174; + { } + { Relation specific attributes } + { } + isc_dyn_rel_dbkey_length = 61; + isc_dyn_rel_store_trig = 62; + isc_dyn_rel_modify_trig = 63; + isc_dyn_rel_erase_trig = 64; + isc_dyn_rel_store_trig_source = 65; + isc_dyn_rel_modify_trig_source = 66; + isc_dyn_rel_erase_trig_source = 67; + isc_dyn_rel_ext_file = 68; + isc_dyn_rel_sql_protection = 69; + isc_dyn_rel_constraint = 162; + isc_dyn_delete_rel_constraint = 163; + { } + { Global field specific attributes } + { } + isc_dyn_fld_type = 70; + isc_dyn_fld_length = 71; + isc_dyn_fld_scale = 72; + isc_dyn_fld_sub_type = 73; + isc_dyn_fld_segment_length = 74; + isc_dyn_fld_query_header = 75; + isc_dyn_fld_edit_string = 76; + isc_dyn_fld_validation_blr = 77; + isc_dyn_fld_validation_source = 78; + isc_dyn_fld_computed_blr = 79; + isc_dyn_fld_computed_source = 80; + isc_dyn_fld_missing_value = 81; + isc_dyn_fld_default_value = 82; + isc_dyn_fld_query_name = 83; + isc_dyn_fld_dimensions = 84; + isc_dyn_fld_not_null = 85; + isc_dyn_fld_precision = 86; + isc_dyn_fld_char_length = 172; + isc_dyn_fld_collation = 173; + isc_dyn_fld_default_source = 193; + isc_dyn_del_default = 197; + isc_dyn_del_validation = 198; + isc_dyn_single_validation = 199; + isc_dyn_fld_character_set = 203; + { } + { Local field specific attributes } + { } + isc_dyn_fld_source = 90; + isc_dyn_fld_base_fld = 91; + isc_dyn_fld_position = 92; + isc_dyn_fld_update_flag = 93; + { } + { Index specific attributes } + { } + isc_dyn_idx_unique = 100; + isc_dyn_idx_inactive = 101; + isc_dyn_idx_type = 103; + isc_dyn_idx_foreign_key = 104; + isc_dyn_idx_ref_column = 105; + isc_dyn_idx_statistic = 204; + { } + { Trigger specific attributes } + { } + isc_dyn_trg_type = 110; + isc_dyn_trg_blr = 111; + isc_dyn_trg_source = 112; + isc_dyn_trg_name = 114; + isc_dyn_trg_sequence = 115; + isc_dyn_trg_inactive = 116; + isc_dyn_trg_msg_number = 117; + isc_dyn_trg_msg = 118; + { } + { Security Class specific attributes } + { } + isc_dyn_scl_acl = 121; + isc_dyn_grant_user = 130; + isc_dyn_grant_proc = 186; + isc_dyn_grant_trig = 187; + isc_dyn_grant_view = 188; + isc_dyn_grant_options = 132; + isc_dyn_grant_user_group = 205; + { } + { Dimension specific information } + { } + isc_dyn_dim_lower = 141; + isc_dyn_dim_upper = 142; + { } + { File specific attributes } + { } + isc_dyn_file_name = 125; + isc_dyn_file_start = 126; + isc_dyn_file_length = 127; + isc_dyn_shadow_number = 128; + isc_dyn_shadow_man_auto = 129; + isc_dyn_shadow_conditional = 130; + { } + { Log file specific attributes } + { } + isc_dyn_log_file_sequence = 177; + isc_dyn_log_file_partitions = 178; + isc_dyn_log_file_serial = 179; + isc_dyn_log_file_overflow = 200; + isc_dyn_log_file_raw = 201; + { } + { Log specific attributes } + { } + isc_dyn_log_group_commit_wait = 189; + isc_dyn_log_buffer_size = 190; + isc_dyn_log_check_point_length = 191; + isc_dyn_log_num_of_buffers = 192; + { } + { Function specific attributes } + { } + isc_dyn_function_name = 145; + isc_dyn_function_type = 146; + isc_dyn_func_module_name = 147; + isc_dyn_func_entry_point = 148; + isc_dyn_func_return_argument = 149; + isc_dyn_func_arg_position = 150; + isc_dyn_func_mechanism = 151; + isc_dyn_filter_in_subtype = 152; + isc_dyn_filter_out_subtype = 153; + isc_dyn_description2 = 154; + isc_dyn_fld_computed_source2 = 155; + isc_dyn_fld_edit_string2 = 156; + isc_dyn_fld_query_header2 = 157; + isc_dyn_fld_validation_source2 = 158; + isc_dyn_trg_msg2 = 159; + isc_dyn_trg_source2 = 160; + isc_dyn_view_source2 = 161; + isc_dyn_xcp_msg2 = 184; + { } + { Generator specific attributes } + { } + isc_dyn_generator_name = 95; + isc_dyn_generator_id = 96; + { } + { Procedure specific attributes } + { } + isc_dyn_prc_inputs = 167; + isc_dyn_prc_outputs = 168; + isc_dyn_prc_source = 169; + isc_dyn_prc_blr = 170; + isc_dyn_prc_source2 = 171; + { } + { Parameter specific attributes } + { } + isc_dyn_prm_number = 138; + isc_dyn_prm_type = 139; + { } + { Relation specific attributes } + { } + isc_dyn_xcp_msg = 185; + { } + { Cascading referential integrity values } + { } + isc_dyn_foreign_key_update = 205; + isc_dyn_foreign_key_delete = 206; + isc_dyn_foreign_key_cascade = 207; + isc_dyn_foreign_key_default = 208; + isc_dyn_foreign_key_null = 209; + isc_dyn_foreign_key_none = 210; + { } + { SQL role values } + { } + isc_dyn_def_sql_role = 211; + isc_dyn_sql_role_name = 212; + isc_dyn_grant_admin_options = 213; + isc_dyn_del_sql_role = 214; + { } + { Last $dyn value assigned } + { } + isc_dyn_last_dyn_value = 216; + { } + { Array slice description language (SDL) } + { } + isc_sdl_version1 = 1; + isc_sdl_eoc = 255; + isc_sdl_relation = 2; + isc_sdl_rid = 3; + isc_sdl_field = 4; + isc_sdl_fid = 5; + isc_sdl_struct = 6; + isc_sdl_variable = 7; + isc_sdl_scalar = 8; + isc_sdl_tiny_integer = 9; + isc_sdl_short_integer = 10; + isc_sdl_long_integer = 11; + isc_sdl_literal = 12; + isc_sdl_add = 13; + isc_sdl_subtract = 14; + isc_sdl_multiply = 15; + isc_sdl_divide = 16; + isc_sdl_negate = 17; + isc_sdl_eql = 18; + isc_sdl_neq = 19; + isc_sdl_gtr = 20; + isc_sdl_geq = 21; + isc_sdl_lss = 22; + isc_sdl_leq = 23; + isc_sdl_and = 24; + isc_sdl_or = 25; + isc_sdl_not = 26; + isc_sdl_while = 27; + isc_sdl_assignment = 28; + isc_sdl_label = 29; + isc_sdl_leave = 30; + isc_sdl_begin = 31; + isc_sdl_end = 32; + isc_sdl_do3 = 33; + isc_sdl_do2 = 34; + isc_sdl_do1 = 35; + isc_sdl_element = 36; + { } + { International text interpretation values } + { } + isc_interp_eng_ascii = 0; + isc_interp_jpn_sjis = 5; + isc_interp_jpn_euc = 6; + { } + { SQL definitions } + { } + SQL_TEXT = 452; + SQL_VARYING = 448; + SQL_SHORT = 500; + SQL_LONG = 496; + SQL_FLOAT = 482; + SQL_DOUBLE = 480; + SQL_D_FLOAT = 530; + SQL_TIMESTAMP = 510; + SQL_BLOB = 520; + SQL_ARRAY = 540; + SQL_QUAD = 550; + SQL_TYPE_TIME = 560; + SQL_TYPE_DATE = 570; + SQL_INT64 = 580; + { Historical alias for pre V6 applications } + SQL_DATE = SQL_TIMESTAMP; + { } + { Blob Subtypes } + { } + { types less than zero are reserved for customer use } + isc_blob_untyped = 0; + { internal subtypes } + isc_blob_text = 1; + isc_blob_blr = 2; + isc_blob_acl = 3; + isc_blob_ranges = 4; + isc_blob_summary = 5; + isc_blob_format = 6; + isc_blob_tra = 7; + isc_blob_extfile = 8; + { the range 20-30 is reserved for dBASE and Paradox types } + isc_blob_formatted_memo = 20; + isc_blob_paradox_ole = 21; + isc_blob_graphic = 22; + isc_blob_dbase_ole = 23; + isc_blob_typed_binary = 24; + +//****************************************/ +//* Shutdown reasons, used by engine */ +//* Users should provide positive values */ +//****************************************/ + + fb_shutrsn_svc_stopped = -1; + fb_shutrsn_no_connection = -2; + fb_shutrsn_app_stopped = -3; + fb_shutrsn_device_removed = -4; + fb_shutrsn_signal = -5; + fb_shutrsn_services = -6; + fb_shutrsn_exit_called = -7; + +{$IFNDEF LinkDynamically} + + { } + { OSRI database functions } + { } + + function isc_attach_database(_para1:PISC_STATUS; _para2:smallint; _para3:Pchar; _para4:Pisc_db_handle; _para5:smallint; + _para6:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_array_gen_sdl(_para1:PISC_STATUS; _para2:PISC_ARRAY_DESC; _para3:Psmallint; _para4:Pchar; _para5:Psmallint):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_array_get_slice(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:PISC_QUAD; _para5:PISC_ARRAY_DESC; + _para6:pointer; _para7:PISC_LONG):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_array_lookup_bounds(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pchar; _para5:Pchar; + _para6:PISC_ARRAY_DESC):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_array_lookup_desc(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pchar; _para5:Pchar; + _para6:PISC_ARRAY_DESC):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_array_set_desc(_para1:PISC_STATUS; _para2:Pchar; _para3:Pchar; _para4:Psmallint; _para5:Psmallint; + _para6:Psmallint; _para7:PISC_ARRAY_DESC):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_array_put_slice(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:PISC_QUAD; _para5:PISC_ARRAY_DESC; + _para6:pointer; _para7:PISC_LONG):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_blob_default_desc(_para1:PISC_BLOB_DESC; _para2:Pbyte; _para3:Pbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_blob_gen_bpb(_para1:PISC_STATUS; _para2:PISC_BLOB_DESC; _para3:PISC_BLOB_DESC; _para4:word; _para5:Pbyte; + _para6:Pword):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_blob_info(_para1:PISC_STATUS; _para2:Pisc_blob_handle; _para3:smallint; _para4:Pchar; _para5:smallint; + _para6:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_blob_lookup_desc(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pbyte; _para5:Pbyte; + _para6:PISC_BLOB_DESC; _para7:Pbyte):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_blob_set_desc(_para1:PISC_STATUS; _para2:Pbyte; _para3:Pbyte; _para4:smallint; _para5:smallint; + _para6:smallint; _para7:PISC_BLOB_DESC):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_cancel_blob(_para1:PISC_STATUS; _para2:Pisc_blob_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_cancel_events(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:PISC_LONG):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_close_blob(_para1:PISC_STATUS; _para2:Pisc_blob_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_commit_retaining(_para1:PISC_STATUS; _para2:Pisc_tr_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_commit_transaction(_para1:PISC_STATUS; _para2:Pisc_tr_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_create_blob(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pisc_blob_handle; _para5:PISC_QUAD):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_create_blob2(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pisc_blob_handle; _para5:PISC_QUAD; + _para6:smallint; _para7:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_create_database(_para1:PISC_STATUS; _para2:smallint; _para3:Pchar; _para4:Pisc_db_handle; _para5:smallint; + _para6:Pchar; _para7:smallint):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_database_info(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:smallint; _para4:Pchar; _para5:smallint; + _para6:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_decode_date(_para1:PISC_QUAD; _para2:pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_decode_sql_date(_para1:PISC_DATE; _para2:pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_decode_sql_time(_para1:PISC_TIME; _para2:pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_decode_timestamp(_para1:PISC_TIMESTAMP; _para2:pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_detach_database(_para1:PISC_STATUS; _para2:Pisc_db_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_drop_database(_para1:PISC_STATUS; _para2:Pisc_db_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_allocate_statement(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_stmt_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_alloc_statement2(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_stmt_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_describe(_para1:PISC_STATUS; _para2:Pisc_stmt_handle; _para3:word; _para4:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_describe_bind(_para1:PISC_STATUS; _para2:Pisc_stmt_handle; _para3:word; _para4:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_exec_immed2(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:word; _para5:Pchar; + _para6:word; _para7:PXSQLDA; _para8:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_execute(_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pisc_stmt_handle; _para4:word; _para5:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_execute2(_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pisc_stmt_handle; _para4:word; _para5:PXSQLDA; + _para6:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_execute_immediate(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:word; _para5:Pchar; + _para6:word; _para7:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_fetch(_para1:PISC_STATUS; _para2:Pisc_stmt_handle; _para3:word; _para4:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_finish(_para1:Pisc_db_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_free_statement(_para1:PISC_STATUS; _para2:Pisc_stmt_handle; _para3:word):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_insert(_para1:PISC_STATUS; _para2:Pisc_stmt_handle; _para3:word; _para4:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_prepare(_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pisc_stmt_handle; _para4:word; _para5:Pchar; + _para6:word; _para7:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_set_cursor_name(_para1:PISC_STATUS; _para2:Pisc_stmt_handle; _para3:Pchar; _para4:word):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_sql_info(_para1:PISC_STATUS; _para2:Pisc_stmt_handle; _para3:smallint; _para4:Pchar; _para5:smallint; + _para6:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_encode_date(_para1:pointer; _para2:PISC_QUAD); {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_encode_sql_date(_para1:pointer; _para2:PISC_DATE); {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_encode_sql_time(_para1:pointer; _para2:PISC_TIME); {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_encode_timestamp(_para1:pointer; _para2:PISC_TIMESTAMP); {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_event_block(_para1:PPchar; _para2:PPchar; _para3:word; + args: array of const):ISC_LONG; {$ifdef cvcall}cdecl{$else}error{$endif}; external gdslib; + procedure isc_event_count(_para1: PISC_STATUS; _para2: short; + _para3: pchar; _para4: pchar); {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + (*!!MVC + void isc_event_counts (unsigned ISC_LONG , + short, + char , + char ); {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + !!MVC *) + procedure isc_expand_dpb(_para1:PPchar; _para2:Psmallint; args:array of const); + {$ifdef cvcall}cdecl{$else}error{$endif}; external gdslib; + + function isc_modify_dpb(_para1:PPchar; _para2:Psmallint; _para3:word; _para4:Pchar; _para5:smallint):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_free(_para1:Pchar):ISC_LONG; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_get_segment(_para1:PISC_STATUS; _para2:Pisc_blob_handle; _para3:Pword; _para4:word; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_get_slice(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:PISC_QUAD; _para5:smallint; + _para6:Pchar; _para7:smallint; _para8:PISC_LONG; _para9:ISC_LONG; _para10:pointer; + _para11:PISC_LONG):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_interprete(_para1:Pchar; _para2:PPISC_STATUS):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_open_blob(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pisc_blob_handle; _para5:PISC_QUAD):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_open_blob2(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pisc_blob_handle; _para5:PISC_QUAD; + _para6:smallint; _para7:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_prepare_transaction2(_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:smallint; _para4:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_print_sqlerror(_para1:smallint; _para2:PISC_STATUS); {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_print_status(_para1:PISC_STATUS):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_put_segment(_para1:PISC_STATUS; _para2:Pisc_blob_handle; _para3:word; _para4:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_put_slice(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:PISC_QUAD; _para5:smallint; + _para6:Pchar; _para7:smallint; _para8:PISC_LONG; _para9:ISC_LONG; _para10:pointer):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_que_events(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:PISC_LONG; _para4:smallint; _para5:Pchar; + _para6:isc_callback; _para7:pointer):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_rollback_retaining(_para1:PISC_STATUS; _para2:Pisc_tr_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_rollback_transaction(_para1:PISC_STATUS; _para2:Pisc_tr_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_start_multiple(_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:smallint; _para4:pointer):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_start_transaction(_para1:PISC_STATUS; _para2:Pisc_tr_handle; + _para3:smallint; args:array of const):ISC_STATUS; {$ifdef cvcall}cdecl{$else}error{$endif}; external gdslib; + + function isc_sqlcode(_para1:PISC_STATUS):ISC_LONG; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_sql_interprete(_para1:smallint; _para2:Pchar; _para3:smallint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_transaction_info(_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:smallint; _para4:Pchar; _para5:smallint; + _para6:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_transact_request(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:word; _para5:Pchar; + _para6:word; _para7:Pchar; _para8:word; _para9:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_vax_integer(_para1:Pchar; _para2:smallint):ISC_LONG; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_portable_integer(_para1:Pbyte; _para2:smallint):ISC_INT64; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + { } + { Security Functions } + { } + + + function isc_add_user(_para1:PISC_STATUS; _para2:PUSER_SEC_DATA):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_delete_user(_para1:PISC_STATUS; _para2:PUSER_SEC_DATA):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_modify_user(_para1:PISC_STATUS; _para2:PUSER_SEC_DATA):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + { } + { Other OSRI functions } + { } + function isc_compile_request(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_req_handle; _para4:smallint; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_compile_request2(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_req_handle; _para4:smallint; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_ddl(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:smallint; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_prepare_transaction(_para1:PISC_STATUS; _para2:Pisc_tr_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_receive(_para1:PISC_STATUS; _para2:Pisc_req_handle; _para3:smallint; _para4:smallint; _para5:pointer; + _para6:smallint):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_reconnect_transaction(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:smallint; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_release_request(_para1:PISC_STATUS; _para2:Pisc_req_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_request_info(_para1:PISC_STATUS; _para2:Pisc_req_handle; _para3:smallint; _para4:smallint; _para5:Pchar; + _para6:smallint; _para7:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_seek_blob(_para1:PISC_STATUS; _para2:Pisc_blob_handle; _para3:smallint; _para4:ISC_LONG; _para5:PISC_LONG):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_send(_para1:PISC_STATUS; _para2:Pisc_req_handle; _para3:smallint; _para4:smallint; _para5:pointer; + _para6:smallint):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_start_and_send(_para1:PISC_STATUS; _para2:Pisc_req_handle; _para3:Pisc_tr_handle; _para4:smallint; _para5:smallint; + _para6:pointer; _para7:smallint):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_start_request(_para1:PISC_STATUS; _para2:Pisc_req_handle; _para3:Pisc_tr_handle; _para4:smallint):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_unwind_request(_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:smallint):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_wait_for_event(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:smallint; _para4:Pchar; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + { } + { Other Sql functions } + { } + function isc_close(_para1:PISC_STATUS; _para2:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_declare(_para1:PISC_STATUS; _para2:Pchar; _para3:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_describe(_para1:PISC_STATUS; _para2:Pchar; _para3:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_describe_bind(_para1:PISC_STATUS; _para2:Pchar; _para3:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_execute(_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pchar; _para4:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_execute_immediate(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Psmallint; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_fetch(_para1:PISC_STATUS; _para2:Pchar; _para3:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_open(_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pchar; _para4:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_prepare(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pchar; _para5:Psmallint; + _para6:Pchar; _para7:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + { } + { Other Dynamic sql functions } + { } + function isc_dsql_execute_m(_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pisc_stmt_handle; _para4:word; _para5:Pchar; + _para6:word; _para7:word; _para8:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_execute2_m(_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pisc_stmt_handle; _para4:word; _para5:Pchar; + _para6:word; _para7:word; _para8:Pchar; _para9:word; _para10:Pchar; + _para11:word; _para12:word; _para13:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_execute_immediate_m(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:word; _para5:Pchar; + _para6:word; _para7:word; _para8:Pchar; _para9:word; _para10:word; + _para11:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_exec_immed3_m(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:word; _para5:Pchar; + _para6:word; _para7:word; _para8:Pchar; _para9:word; _para10:word; + _para11:Pchar; _para12:word; _para13:Pchar; _para14:word; _para15:word; + _para16:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_fetch_m(_para1:PISC_STATUS; _para2:Pisc_stmt_handle; _para3:word; _para4:Pchar; _para5:word; + _para6:word; _para7:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_insert_m(_para1:PISC_STATUS; _para2:Pisc_stmt_handle; _para3:word; _para4:Pchar; _para5:word; + _para6:word; _para7:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_prepare_m(_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pisc_stmt_handle; _para4:word; _para5:Pchar; + _para6:word; _para7:word; _para8:Pchar; _para9:word; _para10:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_dsql_release(_para1:PISC_STATUS; _para2:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_embed_dsql_close(_para1:PISC_STATUS; _para2:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_embed_dsql_declare(_para1:PISC_STATUS; _para2:Pchar; _para3:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_embed_dsql_describe(_para1:PISC_STATUS; _para2:Pchar; _para3:word; _para4:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_embed_dsql_describe_bind(_para1:PISC_STATUS; _para2:Pchar; _para3:word; _para4:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_embed_dsql_execute(_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pchar; _para4:word; _para5:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_embed_dsql_execute2(_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pchar; _para4:word; _para5:PXSQLDA; + _para6:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_embed_dsql_execute_immed(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:word; _para5:Pchar; + _para6:word; _para7:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_embed_dsql_fetch(_para1:PISC_STATUS; _para2:Pchar; _para3:word; _para4:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_embed_dsql_open(_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pchar; _para4:word; _para5:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_embed_dsql_open2(_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pchar; _para4:word; _para5:PXSQLDA; + _para6:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_embed_dsql_insert(_para1:PISC_STATUS; _para2:Pchar; _para3:word; _para4:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_embed_dsql_prepare(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pchar; _para5:word; + _para6:Pchar; _para7:word; _para8:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_embed_dsql_release(_para1:PISC_STATUS; _para2:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + { } + { Other Blob functions } + { } + function BLOB_open(_para1:isc_blob_handle; _para2:Pchar; _para3:longint):PBSTREAM; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function BLOB_put(_para1:char; _para2:PBSTREAM):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function BLOB_close(_para1:PBSTREAM):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function BLOB_get(_para1:PBSTREAM):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function BLOB_display(_para1:PISC_QUAD; _para2:isc_db_handle; _para3:isc_tr_handle; _para4:Pchar):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function BLOB_dump(_para1:PISC_QUAD; _para2:isc_db_handle; _para3:isc_tr_handle; _para4:Pchar):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function BLOB_edit(_para1:PISC_QUAD; _para2:isc_db_handle; _para3:isc_tr_handle; _para4:Pchar):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function BLOB_load(_para1:PISC_QUAD; _para2:isc_db_handle; _para3:isc_tr_handle; _para4:Pchar):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function BLOB_text_dump(_para1:PISC_QUAD; _para2:isc_db_handle; _para3:isc_tr_handle; _para4:Pchar):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function BLOB_text_load(_para1:PISC_QUAD; _para2:isc_db_handle; _para3:isc_tr_handle; _para4:Pchar):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function Bopen(_para1:PISC_QUAD; _para2:isc_db_handle; _para3:isc_tr_handle; _para4:Pchar):PBSTREAM; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + +{$IFDEF Unix} + function Bopen2(_para1:PISC_QUAD; _para2:isc_db_handle; _para3:isc_tr_handle; _para4:Pchar; _para5:word):PBSTREAM; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; +{$ENDIF} + + { } + { Other Misc functions } + { } + function isc_ftof(_para1:Pchar; _para2:word; _para3:Pchar; _para4:word):ISC_LONG; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_print_blr(_para1:Pchar; _para2:isc_callback; _para3:pointer; _para4:smallint):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_set_debug(_para1:longint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_qtoq(_para1:PISC_QUAD; _para2:PISC_QUAD); {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_vtof(_para1:Pchar; _para2:Pchar; _para3:word); {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_vtov(_para1:Pchar; _para2:Pchar; _para3:smallint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_version(_para1:Pisc_db_handle; _para2:isc_versioncallback; _para3:pointer):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_get_client_version(aversion: pchar); {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + function isc_get_client_major_version: integer; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + function isc_get_client_minor_version: integer; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + +{$IFDEF Unix} + function isc_reset_fpe(_para1:word):ISC_LONG; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; +{$ENDIF} + + { } + { Service manager functions } + { } + + function isc_service_attach(status_vector: PISC_STATUS; + service_length: word; service: Pchar; svc_handle: Pisc_svc_handle; + spb_length: word; spb: Pchar): ISC_STATUS; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + function isc_service_detach(status_vector: PISC_STATUS; + svc_handle: Pisc_svc_handle):ISC_STATUS; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + function isc_service_query(status_vector: PISC_STATUS; + svc_handle: Pisc_svc_handle; + reserved: Pisc_resv_handle; + send_spb_length: word; send_sbp: Pchar; + request_spb_length: word; request_spb:Pchar; + buffer_length: word; buffer: Pchar):ISC_STATUS; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + function isc_service_start(status_vector: PISC_STATUS; + svc_handle: Pisc_svc_handle; reserved: Pisc_resv_handle; + spp_length: word; spb: Pchar):ISC_STATUS; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + { } + { Forms functions } + { } +{$IFDEF Unix} + function isc_compile_map(_para1:PISC_STATUS; _para2:Pisc_form_handle; _para3:Pisc_req_handle; _para4:Psmallint; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_compile_menu(_para1:PISC_STATUS; _para2:Pisc_form_handle; _para3:Pisc_req_handle; _para4:Psmallint; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_compile_sub_map(_para1:PISC_STATUS; _para2:Pisc_win_handle; _para3:Pisc_req_handle; _para4:Psmallint; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_create_window(_para1:PISC_STATUS; _para2:Pisc_win_handle; _para3:Psmallint; _para4:Pchar; _para5:Psmallint; + _para6:Psmallint):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_delete_window(_para1:PISC_STATUS; _para2:Pisc_win_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_drive_form(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pisc_win_handle; _para5:Pisc_req_handle; + _para6:Pbyte; _para7:Pbyte):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_drive_menu(_para1:PISC_STATUS; _para2:Pisc_win_handle; _para3:Pisc_req_handle; _para4:Psmallint; _para5:Pchar; + _para6:Psmallint; _para7:Pchar; _para8:Psmallint; _para9:Psmallint; _para10:Pchar; + _para11:PISC_LONG):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_form_delete(_para1:PISC_STATUS; _para2:Pisc_form_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_form_fetch(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pisc_req_handle; _para5:Pbyte):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_form_insert(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pisc_req_handle; _para5:Pbyte):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_get_entree(_para1:PISC_STATUS; _para2:Pisc_req_handle; _para3:Psmallint; _para4:Pchar; _para5:PISC_LONG; + _para6:Psmallint):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_initialize_menu(_para1:PISC_STATUS; _para2:Pisc_req_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_menu(_para1:PISC_STATUS; _para2:Pisc_win_handle; _para3:Pisc_req_handle; _para4:Psmallint; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_load_form(_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pisc_form_handle; _para5:Psmallint; + _para6:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_pop_window(_para1:PISC_STATUS; _para2:Pisc_win_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_put_entree(_para1:PISC_STATUS; _para2:Pisc_req_handle; _para3:Psmallint; _para4:Pchar; _para5:PISC_LONG):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_reset_form(_para1:PISC_STATUS; _para2:Pisc_req_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_suspend_window(_para1:PISC_STATUS; _para2:Pisc_win_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; +{$ENDIF} + + function isc_attach_database:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_array_gen_sdl:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_array_get_slice:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_array_lookup_bounds:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_array_lookup_desc:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_array_set_desc:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_array_put_slice:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_blob_gen_bpb:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_blob_info:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_blob_lookup_desc:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_blob_set_desc:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_cancel_blob:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_cancel_events:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_close_blob:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_commit_retaining:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_commit_transaction:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_compile_request:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_compile_request2:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_create_blob:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_create_blob2:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_create_database:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_database_info:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_ddl:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_decode_date; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_decode_sql_date; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_decode_sql_time; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_decode_timestamp; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_detach_database:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_drop_database:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_encode_date; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_encode_sql_date; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_encode_sql_time; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_encode_timestamp; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_event_block:ISC_LONG; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_event_counts; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_expand_dpb; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_modify_dpb:longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_free:ISC_LONG; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_get_segment:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_get_slice:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_interprete:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_open_blob:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_open_blob2:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_prepare_transaction:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_prepare_transaction2:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_print_sqlerror; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_print_status:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_put_segment:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_put_slice:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_que_events:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_receive:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_reconnect_transaction:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_release_request:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_request_info:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + +{$IFDEF Unix} + function isc_reset_fpe:ISC_LONG; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; +{$ENDIF} + + function isc_rollback_transaction:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_rollback_retaining:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_seek_blob:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_send:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_service_attach:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_service_detach:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_service_query:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_service_start:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_start_and_send:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_start_multiple:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_start_request:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_start_transaction:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_sqlcode:ISC_LONG; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_transaction_info:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_transact_request:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_unwind_request:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_wait_for_event:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_ftof:ISC_LONG; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_print_blr:ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_set_debug; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_qtoq; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_vax_integer:ISC_LONG; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_vtof; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + procedure isc_vtov; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function isc_version:longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + { } + { Blob functions } + { } + + function Bopen:PBSTREAM; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + + function BLOB_open:PBSTREAM; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; + +{$IFDEF Unix} + function Bopen2:PBSTREAM; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external gdslib; +{$ENDIF} + +{$ELSE} // LinkDynamically + +var + +{ } +{ OSRI database functions } +{ } + isc_attach_database : function (_para1:PISC_STATUS; _para2:smallint; _para3:Pchar; _para4:Pisc_db_handle; _para5:smallint;_para6:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_array_gen_sdl : function (_para1:PISC_STATUS; _para2:PISC_ARRAY_DESC; _para3:Psmallint; _para4:Pchar; _para5:Psmallint):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_array_get_slice : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:PISC_QUAD; _para5:PISC_ARRAY_DESC;_para6:pointer; _para7:PISC_LONG):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_array_lookup_bounds : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pchar; _para5:Pchar;_para6:PISC_ARRAY_DESC):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_array_lookup_desc : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pchar; _para5:Pchar;_para6:PISC_ARRAY_DESC):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_array_set_desc : function (_para1:PISC_STATUS; _para2:Pchar; _para3:Pchar; _para4:Psmallint; _para5:Psmallint;_para6:Psmallint; _para7:PISC_ARRAY_DESC):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_array_put_slice : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:PISC_QUAD; _para5:PISC_ARRAY_DESC;_para6:pointer; _para7:PISC_LONG):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_blob_default_desc : procedure (_para1:PISC_BLOB_DESC; _para2:Pbyte; _para3:Pbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_blob_gen_bpb : function (_para1:PISC_STATUS; _para2:PISC_BLOB_DESC; _para3:PISC_BLOB_DESC; _para4:word; _para5:Pbyte;_para6:Pword):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_blob_info : function (_para1:PISC_STATUS; _para2:Pisc_blob_handle; _para3:smallint; _para4:Pchar; _para5:smallint;_para6:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_blob_lookup_desc : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pbyte; _para5:Pbyte;_para6:PISC_BLOB_DESC; _para7:Pbyte):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_blob_set_desc : function (_para1:PISC_STATUS; _para2:Pbyte; _para3:Pbyte; _para4:smallint; _para5:smallint;_para6:smallint; _para7:PISC_BLOB_DESC):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_cancel_blob : function (_para1:PISC_STATUS; _para2:Pisc_blob_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_cancel_events : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:PISC_LONG):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_close_blob : function (_para1:PISC_STATUS; _para2:Pisc_blob_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_commit_retaining : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_commit_transaction : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_create_blob : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pisc_blob_handle; _para5:PISC_QUAD):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_create_blob2 : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pisc_blob_handle; _para5:PISC_QUAD;_para6:smallint; _para7:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_create_database : function (_para1:PISC_STATUS; _para2:smallint; _para3:Pchar; _para4:Pisc_db_handle; _para5:smallint;_para6:Pchar; _para7:smallint):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_database_info : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:smallint; _para4:Pchar; _para5:smallint;_para6:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_decode_date : procedure (_para1:PISC_QUAD; _para2:pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_decode_sql_date : procedure (_para1:PISC_DATE; _para2:pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_decode_sql_time : procedure (_para1:PISC_TIME; _para2:pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_decode_timestamp : procedure (_para1:PISC_TIMESTAMP; _para2:pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_detach_database : function (_para1:PISC_STATUS; _para2:Pisc_db_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_drop_database : function (_para1:PISC_STATUS; _para2:Pisc_db_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_allocate_statement : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_stmt_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_alloc_statement2 : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_stmt_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_describe : function (_para1:PISC_STATUS; _para2:Pisc_stmt_handle; _para3:word; _para4:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_describe_bind : function (_para1:PISC_STATUS; _para2:Pisc_stmt_handle; _para3:word; _para4:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_exec_immed2 : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:word; _para5:Pchar;_para6:word; _para7:PXSQLDA; _para8:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_execute : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pisc_stmt_handle; _para4:word; _para5:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_execute2 : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pisc_stmt_handle; _para4:word; _para5:PXSQLDA;_para6:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_execute_immediate : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:word; _para5:Pchar;_para6:word; _para7:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_fetch : function (_para1:PISC_STATUS; _para2:Pisc_stmt_handle; _para3:word; _para4:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_finish : function (_para1:Pisc_db_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_free_statement : function (_para1:PISC_STATUS; _para2:Pisc_stmt_handle; _para3:word):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_insert : function (_para1:PISC_STATUS; _para2:Pisc_stmt_handle; _para3:word; _para4:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_prepare : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pisc_stmt_handle; _para4:word; _para5:Pchar;_para6:word; _para7:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_set_cursor_name : function (_para1:PISC_STATUS; _para2:Pisc_stmt_handle; _para3:Pchar; _para4:word):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_sql_info : function (_para1:PISC_STATUS; _para2:Pisc_stmt_handle; + _para3:smallint; _para4:Pchar; _para5:smallint; + _para6:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_encode_date : procedure (_para1:pointer; _para2:PISC_QUAD); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_encode_sql_date : procedure (_para1:pointer; _para2:PISC_DATE); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_encode_sql_time : procedure (_para1:pointer; _para2:PISC_TIME); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_encode_timestamp : procedure (_para1:pointer; _para2:PISC_TIMESTAMP); {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{$warnings off} + isc_event_block : function (_para1:PPchar; _para2:PPchar; _para3:word; + args: array of const):ISC_LONG; {$ifdef cvcall}cdecl{$else}error{$endif}; {varargs;} +{$warnings on} + isc_event_counts: procedure (_para1: PISC_STATUS; _para2: short; + _para3: pchar; _para4: pchar); {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{$warnings off} + isc_expand_dpb : procedure (_para1:PPchar; _para2:Psmallint; + args:array of const); {$ifdef cvcall}cdecl{$else}error{$endif}; +{$warnings on} + isc_modify_dpb : function (_para1:PPchar; _para2:Psmallint; _para3:word; _para4:Pchar; _para5:smallint):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_free : function (_para1:Pchar):ISC_LONG; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_get_segment : function (_para1:PISC_STATUS; _para2:Pisc_blob_handle; _para3:Pword; _para4:word; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_get_slice : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:PISC_QUAD; _para5:smallint;_para6:Pchar; _para7:smallint; _para8:PISC_LONG; _para9:ISC_LONG; _para10:pointer;_para11:PISC_LONG):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_interprete : function (_para1:Pchar; _para2:PPISC_STATUS):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_open_blob : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pisc_blob_handle; _para5:PISC_QUAD):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_open_blob2 : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pisc_blob_handle; _para5:PISC_QUAD;_para6:smallint; _para7:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_prepare_transaction2 : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:smallint; _para4:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_print_sqlerror : procedure (_para1:smallint; _para2:PISC_STATUS); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_print_status : function (_para1:PISC_STATUS):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_put_segment : function (_para1:PISC_STATUS; _para2:Pisc_blob_handle; _para3:word; _para4:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_put_slice : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:PISC_QUAD; _para5:smallint;_para6:Pchar; _para7:smallint; _para8:PISC_LONG; _para9:ISC_LONG; _para10:pointer):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_que_events : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:PISC_LONG; _para4:smallint; _para5:Pchar;_para6:isc_callback; _para7:pointer):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_rollback_retaining : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_rollback_transaction : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_start_multiple : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:smallint; _para4:pointer):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{$warnings off} + isc_start_transaction : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle; + _para3:smallint; args:array of const):ISC_STATUS; + {$ifdef cvcall}cdecl{$else}error{$endif}; +{$warnings on} + isc_sqlcode : function (_para1:PISC_STATUS):ISC_LONG; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_sql_interprete : procedure (_para1:smallint; _para2:Pchar; _para3:smallint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_transaction_info : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:smallint; _para4:Pchar; _para5:smallint;_para6:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_transact_request : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:word; _para5:Pchar;_para6:word; _para7:Pchar; _para8:word; _para9:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_vax_integer : function (_para1:Pchar; _para2:smallint):ISC_LONG; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_portable_integer : function (_para1:Pbyte; _para2:smallint):ISC_INT64; {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{ } +{ Security Functions } +{ } + isc_add_user : function (_para1:PISC_STATUS; _para2:PUSER_SEC_DATA):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_delete_user : function (_para1:PISC_STATUS; _para2:PUSER_SEC_DATA):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_modify_user : function (_para1:PISC_STATUS; _para2:PUSER_SEC_DATA):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{ } +{ Other OSRI functions } +{ } + isc_compile_request : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_req_handle; _para4:smallint; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_compile_request2 : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_req_handle; _para4:smallint; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_ddl : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:smallint; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_prepare_transaction : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_receive : function (_para1:PISC_STATUS; _para2:Pisc_req_handle; _para3:smallint; _para4:smallint; _para5:pointer;_para6:smallint):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_reconnect_transaction : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:smallint; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_release_request : function (_para1:PISC_STATUS; _para2:Pisc_req_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_request_info : function (_para1:PISC_STATUS; _para2:Pisc_req_handle; _para3:smallint; _para4:smallint; _para5:Pchar;_para6:smallint; _para7:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_seek_blob : function (_para1:PISC_STATUS; _para2:Pisc_blob_handle; _para3:smallint; _para4:ISC_LONG; _para5:PISC_LONG):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_send : function (_para1:PISC_STATUS; _para2:Pisc_req_handle; _para3:smallint; _para4:smallint; _para5:pointer;_para6:smallint):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_start_and_send : function (_para1:PISC_STATUS; _para2:Pisc_req_handle; _para3:Pisc_tr_handle; _para4:smallint; _para5:smallint;_para6:pointer; _para7:smallint):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_start_request : function (_para1:PISC_STATUS; _para2:Pisc_req_handle; _para3:Pisc_tr_handle; _para4:smallint):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_unwind_request : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:smallint):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_wait_for_event : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:smallint; _para4:Pchar; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{ } +{ Other Sql functions } +{ } + isc_close : function (_para1:PISC_STATUS; _para2:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_declare : function (_para1:PISC_STATUS; _para2:Pchar; _para3:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_describe : function (_para1:PISC_STATUS; _para2:Pchar; _para3:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_describe_bind : function (_para1:PISC_STATUS; _para2:Pchar; _para3:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_execute : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pchar; _para4:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_execute_immediate : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Psmallint; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_fetch : function (_para1:PISC_STATUS; _para2:Pchar; _para3:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_open : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pchar; _para4:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_prepare : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pchar; _para5:Psmallint;_para6:Pchar; _para7:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{ } +{ Other Dynamic sql functions } +{ } + isc_dsql_execute_m : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pisc_stmt_handle; _para4:word; _para5:Pchar;_para6:word; _para7:word; _para8:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_execute2_m : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pisc_stmt_handle; _para4:word; _para5:Pchar;_para6:word; _para7:word; _para8:Pchar; _para9:word; _para10:Pchar;_para11:word; _para12:word; _para13:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_execute_immediate_m : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:word; _para5:Pchar;_para6:word; _para7:word; _para8:Pchar; _para9:word; _para10:word;_para11:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_exec_immed3_m : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:word; _para5:Pchar;_para6:word; _para7:word; _para8:Pchar; _para9:word; _para10:word;_para11:Pchar; _para12:word; _para13:Pchar; _para14:word; _para15:word;_para16:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_fetch_m : function (_para1:PISC_STATUS; _para2:Pisc_stmt_handle; _para3:word; _para4:Pchar; _para5:word;_para6:word; _para7:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_insert_m : function (_para1:PISC_STATUS; _para2:Pisc_stmt_handle; _para3:word; _para4:Pchar; _para5:word;_para6:word; _para7:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_prepare_m : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pisc_stmt_handle; _para4:word; _para5:Pchar;_para6:word; _para7:word; _para8:Pchar; _para9:word; _para10:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_dsql_release : function (_para1:PISC_STATUS; _para2:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_embed_dsql_close : function (_para1:PISC_STATUS; _para2:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_embed_dsql_declare : function (_para1:PISC_STATUS; _para2:Pchar; _para3:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_embed_dsql_describe : function (_para1:PISC_STATUS; _para2:Pchar; _para3:word; _para4:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_embed_dsql_describe_bind : function (_para1:PISC_STATUS; _para2:Pchar; _para3:word; _para4:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_embed_dsql_execute : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pchar; _para4:word; _para5:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_embed_dsql_execute2 : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pchar; _para4:word; _para5:PXSQLDA;_para6:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_embed_dsql_execute_immed : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:word; _para5:Pchar;_para6:word; _para7:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_embed_dsql_fetch : function (_para1:PISC_STATUS; _para2:Pchar; _para3:word; _para4:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_embed_dsql_open : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pchar; _para4:word; _para5:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_embed_dsql_open2 : function (_para1:PISC_STATUS; _para2:Pisc_tr_handle; _para3:Pchar; _para4:word; _para5:PXSQLDA;_para6:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_embed_dsql_insert : function (_para1:PISC_STATUS; _para2:Pchar; _para3:word; _para4:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_embed_dsql_prepare : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pchar; _para5:word;_para6:Pchar; _para7:word; _para8:PXSQLDA):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_embed_dsql_release : function (_para1:PISC_STATUS; _para2:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{ } +{ Other Blob functions } +{ } + BLOB_open : function (_para1:isc_blob_handle; _para2:Pchar; _para3:longint):PBSTREAM; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + BLOB_put : function (_para1:char; _para2:PBSTREAM):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + BLOB_close : function (_para1:PBSTREAM):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + BLOB_get : function (_para1:PBSTREAM):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + BLOB_display : function (_para1:PISC_QUAD; _para2:isc_db_handle; _para3:isc_tr_handle; _para4:Pchar):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + BLOB_dump : function (_para1:PISC_QUAD; _para2:isc_db_handle; _para3:isc_tr_handle; _para4:Pchar):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + BLOB_edit : function (_para1:PISC_QUAD; _para2:isc_db_handle; _para3:isc_tr_handle; _para4:Pchar):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + BLOB_load : function (_para1:PISC_QUAD; _para2:isc_db_handle; _para3:isc_tr_handle; _para4:Pchar):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + BLOB_text_dump : function (_para1:PISC_QUAD; _para2:isc_db_handle; _para3:isc_tr_handle; _para4:Pchar):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + BLOB_text_load : function (_para1:PISC_QUAD; _para2:isc_db_handle; _para3:isc_tr_handle; _para4:Pchar):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + Bopen : function (_para1:PISC_QUAD; _para2:isc_db_handle; _para3:isc_tr_handle; _para4:Pchar):PBSTREAM; {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{$IFDEF Unix} + Bopen2 : function (_para1:PISC_QUAD; _para2:isc_db_handle; _para3:isc_tr_handle; _para4:Pchar; _para5:word):PBSTREAM; {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{$ENDIF} +{ } +{ Other Misc functions } +{ } + isc_ftof : function (_para1:Pchar; _para2:word; _para3:Pchar; _para4:word):ISC_LONG; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_print_blr : function (_para1:Pchar; _para2:isc_callback; _para3:pointer; _para4:smallint):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_set_debug : procedure (_para1:longint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_qtoq : procedure (_para1:PISC_QUAD; _para2:PISC_QUAD); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_vtof : procedure (_para1:Pchar; _para2:Pchar; _para3:word); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_vtov : procedure (_para1:Pchar; _para2:Pchar; _para3:smallint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_version : function (_para1:Pisc_db_handle; _para2:isc_versioncallback; + _para3:pointer):longint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_get_client_version: procedure (aversion: pchar); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_get_client_major_version: function: integer; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_get_client_minor_version: function: integer; {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{$IFDEF Unix} + isc_reset_fpe : function (_para1:word):ISC_LONG; {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{$ENDIF} +{ } +{ Service manager functions } +{ } + isc_service_attach: function (status_vector: PISC_STATUS; + service_length: word; service: Pchar; svc_handle: Pisc_svc_handle; + spb_length: word; spb: Pchar): ISC_STATUS; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_service_detach: function (status_vector: PISC_STATUS; + svc_handle: Pisc_svc_handle):ISC_STATUS; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_service_query: function (status_vector: PISC_STATUS; + svc_handle: Pisc_svc_handle; + reserved: Pisc_resv_handle; + send_spb_length: word; send_sbp: Pchar; + request_spb_length: word; request_spb:Pchar; + buffer_length: word; buffer: Pchar):ISC_STATUS; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_service_start: function (status_vector: PISC_STATUS; + svc_handle: Pisc_svc_handle; reserved: Pisc_resv_handle; + spp_length: word; spb: Pchar):ISC_STATUS; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{ } +{ Forms functions } +{ } +{$IFDEF Unix} + isc_compile_map : function (_para1:PISC_STATUS; _para2:Pisc_form_handle; _para3:Pisc_req_handle; _para4:Psmallint; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_compile_menu : function (_para1:PISC_STATUS; _para2:Pisc_form_handle; _para3:Pisc_req_handle; _para4:Psmallint; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_compile_sub_map : function (_para1:PISC_STATUS; _para2:Pisc_win_handle; _para3:Pisc_req_handle; _para4:Psmallint; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_create_window : function (_para1:PISC_STATUS; _para2:Pisc_win_handle; _para3:Psmallint; _para4:Pchar; _para5:Psmallint;_para6:Psmallint):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_delete_window : function (_para1:PISC_STATUS; _para2:Pisc_win_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_drive_form : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pisc_win_handle; _para5:Pisc_req_handle;_para6:Pbyte; _para7:Pbyte):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_drive_menu : function (_para1:PISC_STATUS; _para2:Pisc_win_handle; _para3:Pisc_req_handle; _para4:Psmallint; _para5:Pchar;_para6:Psmallint; _para7:Pchar; _para8:Psmallint; _para9:Psmallint; _para10:Pchar;_para11:PISC_LONG):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_form_delete : function (_para1:PISC_STATUS; _para2:Pisc_form_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_form_fetch : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pisc_req_handle; _para5:Pbyte):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_form_insert : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pisc_req_handle; _para5:Pbyte):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_get_entree : function (_para1:PISC_STATUS; _para2:Pisc_req_handle; _para3:Psmallint; _para4:Pchar; _para5:PISC_LONG;_para6:Psmallint):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_initialize_menu : function (_para1:PISC_STATUS; _para2:Pisc_req_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_menu : function (_para1:PISC_STATUS; _para2:Pisc_win_handle; _para3:Pisc_req_handle; _para4:Psmallint; _para5:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_load_form : function (_para1:PISC_STATUS; _para2:Pisc_db_handle; _para3:Pisc_tr_handle; _para4:Pisc_form_handle; _para5:Psmallint;_para6:Pchar):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_pop_window : function (_para1:PISC_STATUS; _para2:Pisc_win_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_put_entree : function (_para1:PISC_STATUS; _para2:Pisc_req_handle; _para3:Psmallint; _para4:Pchar; _para5:PISC_LONG):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_reset_form : function (_para1:PISC_STATUS; _para2:Pisc_req_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_suspend_window : function (_para1:PISC_STATUS; _para2:Pisc_win_handle):ISC_STATUS; {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{$ENDIF} + + fb_shutdown: function(timeout: cuint; reason: cint): cint; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +{$ENDIF} + +{$IFDEF LinkDynamically} +//var +// libname: filenamety; +{$endif} + +implementation +uses + msesys,msesonames,msedynload,msesysintf; + +function XSQLDA_LENGTH(n: Integer): Integer; +begin + Result := SizeOf(XSQLDA) + (n - 1) * SizeOf(XSQLVAR); +end; + +{$IFDEF LinkDynamically} + +ResourceString + SErrEmbeddedFailed = 'Can not load embedded Firebird client "%s". Check your installation.'; + SErrDefaultsFailed = 'Can not load default Firebird clients ("%s" or "%s"). Check your installation.'; + SErrLoadFailed = 'Can not load Firebird client library "%s". Check your installation.'; + SErrAlreadyLoaded = 'Firebird interface already initialized from library %s.'; + +var + libinfo: dynlibinfoty; +// RefCount : integer; +// LoadedLibrary : String; +(* +Function TryInitialiseIBase60(Const LibraryNames: array of filenamety) : Boolean; +var + mstr1: filenamety; +begin + Result:=True; + if (RefCount = 0) then begin + try + IBaseLibraryHandle:= LoadLib(LibraryNames,mstr1); + except + IBaseLibraryHandle:= nilhandle + end; + if IBaseLibraryHandle = nilhandle then begin + result:= false; + exit; + end; +// inc(RefCount); + refcount:= 2; //releasing the library is unsafe! + LoadedLibrary:= mstr1; + getprocaddresses(ibaselibraryhandle, + [ + 'isc_attach_database', //1 + 'isc_array_gen_sdl', //2 + 'isc_array_get_slice', //3 + 'isc_array_lookup_bounds', //4 + 'isc_array_lookup_desc', //5 + 'isc_array_set_desc', //6 + 'isc_array_put_slice', //7 + 'isc_blob_default_desc', //8 + 'isc_blob_gen_bpb', //9 + 'isc_blob_info', //10 + 'isc_blob_lookup_desc', //11 + 'isc_blob_set_desc', //12 + 'isc_cancel_blob', //13 + 'isc_cancel_events', //14 + 'isc_close_blob', //15 + 'isc_commit_retaining', //16 + 'isc_commit_transaction', //17 + 'isc_create_blob', //18 + 'isc_create_blob2', //19 + 'isc_create_database', //20 + 'isc_database_info', //21 + 'isc_decode_date', //22 + 'isc_decode_sql_date', //23 + 'isc_decode_sql_time', //24 + 'isc_decode_timestamp', //25 + 'isc_detach_database', //26 + 'isc_drop_database', //27 + 'isc_dsql_allocate_statement', //28 + 'isc_dsql_alloc_statement2', //29 + 'isc_dsql_describe', //30 + 'isc_dsql_describe_bind', //31 + 'isc_dsql_exec_immed2', //32 + 'isc_dsql_execute', //33 + 'isc_dsql_execute2', //34 + 'isc_dsql_execute_immediate', //35 + 'isc_dsql_fetch', //36 + 'isc_dsql_finish', //37 + 'isc_dsql_free_statement', //38 + 'isc_dsql_insert', //39 + 'isc_dsql_prepare', //40 + 'isc_dsql_set_cursor_name', //41 + 'isc_dsql_sql_info', //42 + 'isc_encode_date', //43 + 'isc_encode_sql_date', //44 + 'isc_encode_sql_time', //45 + 'isc_encode_timestamp', //46 + 'isc_event_block', //47 + 'isc_event_counts', //48 + 'isc_expand_dpb', //49 + 'isc_modify_dpb', //50 + 'isc_free', //51 + 'isc_get_segment', //52 + 'isc_get_slice', //53 + 'isc_interprete', //54 + 'isc_open_blob', //55 + 'isc_open_blob2', //56 + 'isc_prepare_transaction2', //57 + 'isc_print_sqlerror', //58 + 'isc_print_status', //69 + 'isc_put_segment', //60 + 'isc_put_slice', //61 + 'isc_que_events', //62 + 'isc_rollback_retaining', //63 + 'isc_rollback_transaction', //64 + 'isc_start_multiple', //65 + 'isc_start_transaction', //66 + 'isc_sqlcode', //67 + 'isc_sql_interprete', //68 + 'isc_transaction_info', //69 + 'isc_transact_request', //70 + 'isc_vax_integer', //71 + 'isc_portable_integer', //72 + 'isc_add_user', //73 + 'isc_delete_user', //74 + 'isc_modify_user', //75 + 'isc_compile_request', //76 + 'isc_compile_request2', //77 + 'isc_ddl', //78 + 'isc_prepare_transaction', //79 + 'isc_receive', //80 + 'isc_reconnect_transaction', //81 + 'isc_release_request', //82 + 'isc_request_info', //83 + 'isc_seek_blob', //84 + 'isc_send', //85 + 'isc_start_and_send', //86 + 'isc_start_request', //87 + 'isc_unwind_request', //88 + 'isc_wait_for_event', //89 + 'isc_close', //90 + 'isc_declare', //91 + 'isc_describe', //92 + 'isc_describe_bind', //93 + 'isc_execute', //94 + 'isc_execute_immediate', //95 + 'isc_fetch', //96 + 'isc_open', //97 + 'isc_prepare', //98 + 'isc_dsql_execute_m', //99 + 'isc_dsql_execute2_m', //100 + 'isc_dsql_execute_immediate_m', //101 + 'isc_dsql_exec_immed3_m', //102 + 'isc_dsql_fetch_m', //103 + 'isc_dsql_insert_m', //104 + 'isc_dsql_prepare_m', //105 + 'isc_dsql_release', //106 + 'isc_embed_dsql_close', //107 + 'isc_embed_dsql_declare', //108 + 'isc_embed_dsql_describe', //109 + 'isc_embed_dsql_describe_bind', //110 + 'isc_embed_dsql_execute', //111 + 'isc_embed_dsql_execute2', //112 + 'isc_embed_dsql_execute_immed', //113 + 'isc_embed_dsql_fetch', //114 + 'isc_embed_dsql_open', //115 + 'isc_embed_dsql_open2', //116 + 'isc_embed_dsql_insert', //117 + 'isc_embed_dsql_prepare', //118 + 'isc_embed_dsql_release', //119 + 'BLOB_open', //120 + 'BLOB_put', //121 + 'BLOB_close', //122 + 'BLOB_get', //123 + 'BLOB_display', //124 + 'BLOB_dump', //125 + 'BLOB_edit', //126 + 'BLOB_load', //127 + 'BLOB_text_dump', //128 + 'BLOB_text_load', //129 + 'Bopen', //130 +{$IFDEF Unix} + 'Bopen2', //131 +{$ENDIF} + 'isc_ftof', //132 + 'isc_print_blr', //133 + 'isc_set_debug', //134 + 'isc_qtoq', //135 + 'isc_vtof', //136 + 'isc_vtov', //137 + 'isc_version', //138 + 'isc_get_client_version', //139 + 'isc_get_client_major_version', //140 + 'isc_get_client_minor_version', //141 +{$IFDEF Unix} + 'isc_reset_fpe', //142 +{$ENDIF} + 'isc_service_attach', //143 + 'isc_service_detach', //144 + 'isc_service_query', //145 + 'isc_service_start' //146 +{$IFDEF Unix} + , + 'isc_compile_map', //147 + 'isc_compile_menu', //148 + 'isc_compile_sub_map', //149 + 'isc_create_window', //150 + 'isc_delete_window', //151 + 'isc_drive_form', //152 + 'isc_drive_menu', //153 + 'isc_form_delete', //154 + 'isc_form_fetch', //155 + 'isc_form_insert', //156 + 'isc_get_entree', //157 + 'isc_initialize_menu', //158 + 'isc_menu', //159 + 'isc_load_form', //160 + 'isc_pop_window', //161 + 'isc_put_entree', //162 + 'isc_reset_form', //163 + 'isc_suspend_window' //164 +{$ENDIF} + ], + [ + @isc_attach_database, //1 + @isc_array_gen_sdl, //2 + @isc_array_get_slice, //3 + @isc_array_lookup_bounds, //4 + @isc_array_lookup_desc, //5 + @isc_array_set_desc, //6 + @isc_array_put_slice, //7 + @isc_blob_default_desc, //8 + @isc_blob_gen_bpb, //9 + @isc_blob_info, //10 + @isc_blob_lookup_desc, //11 + @isc_blob_set_desc, //12 + @isc_cancel_blob, //13 + @isc_cancel_events, //14 + @isc_close_blob, //15 + @isc_commit_retaining, //16 + @isc_commit_transaction, //17 + @isc_create_blob, //18 + @isc_create_blob2, //19 + @isc_create_database, //20 + @isc_database_info, //21 + @isc_decode_date, //22 + @isc_decode_sql_date, //23 + @isc_decode_sql_time, //24 + @isc_decode_timestamp, //25 + @isc_detach_database, //26 + @isc_drop_database, //27 + @isc_dsql_allocate_statement, //28 + @isc_dsql_alloc_statement2, //29 + @isc_dsql_describe, //30 + @isc_dsql_describe_bind, //31 + @isc_dsql_exec_immed2, //32 + @isc_dsql_execute, //33 + @isc_dsql_execute2, //34 + @isc_dsql_execute_immediate, //35 + @isc_dsql_fetch, //36 + @isc_dsql_finish, //37 + @isc_dsql_free_statement, //38 + @isc_dsql_insert, //39 + @isc_dsql_prepare, //40 + @isc_dsql_set_cursor_name, //41 + @isc_dsql_sql_info, //42 + @isc_encode_date, //43 + @isc_encode_sql_date, //44 + @isc_encode_sql_time, //45 + @isc_encode_timestamp, //46 + @isc_event_block, //47 + @isc_event_counts, //48 + @isc_expand_dpb, //49 + @isc_modify_dpb, //50 + @isc_free, //51 + @isc_get_segment, //52 + @isc_get_slice, //53 + @isc_interprete, //54 + @isc_open_blob, //55 + @isc_open_blob2, //56 + @isc_prepare_transaction2, //57 + @isc_print_sqlerror, //58 + @isc_print_status, //59 + @isc_put_segment, //60 + @isc_put_slice, //61 + @isc_que_events, //62 + @isc_rollback_retaining, //63 + @isc_rollback_transaction, //64 + @isc_start_multiple, //65 + @isc_start_transaction, //66 + @isc_sqlcode, //67 + @isc_sql_interprete, //68 + @isc_transaction_info, //69 + @isc_transact_request, //70 + @isc_vax_integer, //71 + @isc_portable_integer, //72 + @isc_add_user, //73 + @isc_delete_user, //74 + @isc_modify_user, //75 + @isc_compile_request, //76 + @isc_compile_request2, //77 + @isc_ddl, //78 + @isc_prepare_transaction, //79 + @isc_receive, //80 + @isc_reconnect_transaction, //81 + @isc_release_request, //82 + @isc_request_info, //83 + @isc_seek_blob, //84 + @isc_send, //85 + @isc_start_and_send, //86 + @isc_start_request, //87 + @isc_unwind_request, //88 + @isc_wait_for_event, //89 + @isc_close, //90 + @isc_declare, //91 + @isc_describe, //92 + @isc_describe_bind, //93 + @isc_execute, //94 + @isc_execute_immediate, //95 + @isc_fetch, //96 + @isc_open, //97 + @isc_prepare, //98 + @isc_dsql_execute_m, //99 + @isc_dsql_execute2_m, //100 + @isc_dsql_execute_immediate_m, //101 + @isc_dsql_exec_immed3_m, //102 + @isc_dsql_fetch_m, //103 + @isc_dsql_insert_m, //104 + @isc_dsql_prepare_m, //105 + @isc_dsql_release, //106 + @isc_embed_dsql_close, //107 + @isc_embed_dsql_declare, //108 + @isc_embed_dsql_describe, //109 + @isc_embed_dsql_describe_bind, //110 + @isc_embed_dsql_execute, //111 + @isc_embed_dsql_execute2, //112 + @isc_embed_dsql_execute_immed, //113 + @isc_embed_dsql_fetch, //114 + @isc_embed_dsql_open, //115 + @isc_embed_dsql_open2, //116 + @isc_embed_dsql_insert, //117 + @isc_embed_dsql_prepare, //118 + @isc_embed_dsql_release, //119 + @BLOB_open, //120 + @BLOB_put, //121 + @BLOB_close, //122 + @BLOB_get, //123 + @BLOB_display, //124 + @BLOB_dump, //125 + @BLOB_edit, //126 + @BLOB_load, //127 + @BLOB_text_dump, //128 + @BLOB_text_load, //129 + @Bopen, //130 +{$IFDEF Unix} + @Bopen2, //131 +{$ENDIF} + @isc_ftof, //132 + @isc_print_blr, //133 + @isc_set_debug, //134 + @isc_qtoq, //135 + @isc_vtof, //136 + @isc_vtov, //137 + @isc_version, //138 + @isc_get_client_version, //139 + @isc_get_client_major_version, //140 + @isc_get_client_minor_version, //141 +{$IFDEF Unix} + @isc_reset_fpe, //142 +{$ENDIF} + @isc_service_attach, //143 + @isc_service_detach, //144 + @isc_service_query, //145 + @isc_service_start //146 +{$IFDEF Unix} + , + @isc_compile_map, //147 + @isc_compile_menu, //148 + @isc_compile_sub_map, //149 + @isc_create_window, //150 + @isc_delete_window, //151 + @isc_drive_form, //152 + @isc_drive_menu, //153 + @isc_form_delete, //154 + @isc_form_fetch, //155 + @isc_form_insert, //156 + @isc_get_entree, //157 + @isc_initialize_menu, //158 + @isc_menu, //159 + @isc_load_form, //160 + @isc_pop_window, //161 + @isc_put_entree, //162 + @isc_reset_form, //163 + @isc_suspend_window //164 +{$ENDIF} + ],true); //accept missing entries + end + else begin +// If (LoadedLibrary<>LibraryName) then +// Raise EInoutError.CreateFmt(SErrAlreadyLoaded,[LoadedLibrary]); + if (loadedlibrary = mstr1) then begin + inc(RefCount); //mse 2006-11-23 + end; + end; +end; + +procedure checkloaded; +begin + if (loadedlibrary <> '') then begin + raise einouterror.createfmt(serralreadyloaded,[loadedlibrary]); + end; +end; +*) + +Procedure InitializeIBase60(const sonames: array of filenamety); +const + funcs: array[0..{$ifdef unix}164{$else}144{$endif}] of funcinfoty = ( + (n: 'isc_attach_database'; d: {$ifndef FPC}@{$endif}@isc_attach_database), + (n: 'isc_array_gen_sdl'; d: {$ifndef FPC}@{$endif}@isc_array_gen_sdl), + (n: 'isc_array_get_slice'; d: {$ifndef FPC}@{$endif}@isc_array_get_slice), + (n: 'isc_array_lookup_bounds'; d: {$ifndef FPC}@{$endif}@isc_array_lookup_bounds), + (n: 'isc_array_lookup_desc'; d: {$ifndef FPC}@{$endif}@isc_array_lookup_desc), + (n: 'isc_array_set_desc'; d: {$ifndef FPC}@{$endif}@isc_array_set_desc), + (n: 'isc_array_put_slice'; d: {$ifndef FPC}@{$endif}@isc_array_put_slice), + (n: 'isc_blob_default_desc'; d: {$ifndef FPC}@{$endif}@isc_blob_default_desc), + (n: 'isc_blob_gen_bpb'; d: {$ifndef FPC}@{$endif}@isc_blob_gen_bpb), + (n: 'isc_blob_info'; d: {$ifndef FPC}@{$endif}@isc_blob_info), + (n: 'isc_blob_lookup_desc'; d: {$ifndef FPC}@{$endif}@isc_blob_lookup_desc), + (n: 'isc_blob_set_desc'; d: {$ifndef FPC}@{$endif}@isc_blob_set_desc), + (n: 'isc_cancel_blob'; d: {$ifndef FPC}@{$endif}@isc_cancel_blob), + (n: 'isc_cancel_events'; d: {$ifndef FPC}@{$endif}@isc_cancel_events), + (n: 'isc_close_blob'; d: {$ifndef FPC}@{$endif}@isc_close_blob), + (n: 'isc_commit_retaining'; d: {$ifndef FPC}@{$endif}@isc_commit_retaining), + (n: 'isc_commit_transaction'; d: {$ifndef FPC}@{$endif}@isc_commit_transaction), + (n: 'isc_create_blob'; d: {$ifndef FPC}@{$endif}@isc_create_blob), + (n: 'isc_create_blob2'; d: {$ifndef FPC}@{$endif}@isc_create_blob2), + (n: 'isc_create_database'; d: {$ifndef FPC}@{$endif}@isc_create_database), + (n: 'isc_database_info'; d: {$ifndef FPC}@{$endif}@isc_database_info), + (n: 'isc_decode_date'; d: {$ifndef FPC}@{$endif}@isc_decode_date), + (n: 'isc_decode_sql_date'; d: {$ifndef FPC}@{$endif}@isc_decode_sql_date), + (n: 'isc_decode_sql_time'; d: {$ifndef FPC}@{$endif}@isc_decode_sql_time), + (n: 'isc_decode_timestamp'; d: {$ifndef FPC}@{$endif}@isc_decode_timestamp), + (n: 'isc_detach_database'; d: {$ifndef FPC}@{$endif}@isc_detach_database), + (n: 'isc_drop_database'; d: {$ifndef FPC}@{$endif}@isc_drop_database), + (n: 'isc_dsql_allocate_statement'; d: {$ifndef FPC}@{$endif}@isc_dsql_allocate_statement), + (n: 'isc_dsql_alloc_statement2'; d: {$ifndef FPC}@{$endif}@isc_dsql_alloc_statement2), + (n: 'isc_dsql_describe'; d: {$ifndef FPC}@{$endif}@isc_dsql_describe), + (n: 'isc_dsql_describe_bind'; d: {$ifndef FPC}@{$endif}@isc_dsql_describe_bind), + (n: 'isc_dsql_exec_immed2'; d: {$ifndef FPC}@{$endif}@isc_dsql_exec_immed2), + (n: 'isc_dsql_execute'; d: {$ifndef FPC}@{$endif}@isc_dsql_execute), + (n: 'isc_dsql_execute2'; d: {$ifndef FPC}@{$endif}@isc_dsql_execute2), + (n: 'isc_dsql_execute_immediate'; d: {$ifndef FPC}@{$endif}@isc_dsql_execute_immediate), + (n: 'isc_dsql_fetch'; d: {$ifndef FPC}@{$endif}@isc_dsql_fetch), + (n: 'isc_dsql_finish'; d: {$ifndef FPC}@{$endif}@isc_dsql_finish), + (n: 'isc_dsql_free_statement'; d: {$ifndef FPC}@{$endif}@isc_dsql_free_statement), + (n: 'isc_dsql_insert'; d: {$ifndef FPC}@{$endif}@isc_dsql_insert), + (n: 'isc_dsql_prepare'; d: {$ifndef FPC}@{$endif}@isc_dsql_prepare), + (n: 'isc_dsql_set_cursor_name'; d: {$ifndef FPC}@{$endif}@isc_dsql_set_cursor_name), + (n: 'isc_dsql_sql_info'; d: {$ifndef FPC}@{$endif}@isc_dsql_sql_info), + (n: 'isc_encode_date'; d: {$ifndef FPC}@{$endif}@isc_encode_date), + (n: 'isc_encode_sql_date'; d: {$ifndef FPC}@{$endif}@isc_encode_sql_date), + (n: 'isc_encode_sql_time'; d: {$ifndef FPC}@{$endif}@isc_encode_sql_time), + (n: 'isc_encode_timestamp'; d: {$ifndef FPC}@{$endif}@isc_encode_timestamp), + (n: 'isc_event_block'; d: {$ifndef FPC}@{$endif}@isc_event_block), + (n: 'isc_event_counts'; d: {$ifndef FPC}@{$endif}@isc_event_counts), + (n: 'isc_expand_dpb'; d: {$ifndef FPC}@{$endif}@isc_expand_dpb), + (n: 'isc_modify_dpb'; d: {$ifndef FPC}@{$endif}@isc_modify_dpb), + (n: 'isc_free'; d: {$ifndef FPC}@{$endif}@isc_free), + (n: 'isc_get_segment'; d: {$ifndef FPC}@{$endif}@isc_get_segment), + (n: 'isc_get_slice'; d: {$ifndef FPC}@{$endif}@isc_get_slice), + (n: 'isc_interprete'; d: {$ifndef FPC}@{$endif}@isc_interprete), + (n: 'isc_open_blob'; d: {$ifndef FPC}@{$endif}@isc_open_blob), + (n: 'isc_open_blob2'; d: {$ifndef FPC}@{$endif}@isc_open_blob2), + (n: 'isc_prepare_transaction2'; d: {$ifndef FPC}@{$endif}@isc_prepare_transaction2), + (n: 'isc_print_sqlerror'; d: {$ifndef FPC}@{$endif}@isc_print_sqlerror), + (n: 'isc_print_status'; d: {$ifndef FPC}@{$endif}@isc_print_status), + (n: 'isc_put_segment'; d: {$ifndef FPC}@{$endif}@isc_put_segment), + (n: 'isc_put_slice'; d: {$ifndef FPC}@{$endif}@isc_put_slice), + (n: 'isc_que_events'; d: {$ifndef FPC}@{$endif}@isc_que_events), + (n: 'isc_rollback_retaining'; d: {$ifndef FPC}@{$endif}@isc_rollback_retaining), + (n: 'isc_rollback_transaction'; d: {$ifndef FPC}@{$endif}@isc_rollback_transaction), + (n: 'isc_start_multiple'; d: {$ifndef FPC}@{$endif}@isc_start_multiple), + (n: 'isc_start_transaction'; d: {$ifndef FPC}@{$endif}@isc_start_transaction), + (n: 'isc_sqlcode'; d: {$ifndef FPC}@{$endif}@isc_sqlcode), + (n: 'isc_sql_interprete'; d: {$ifndef FPC}@{$endif}@isc_sql_interprete), + (n: 'isc_transaction_info'; d: {$ifndef FPC}@{$endif}@isc_transaction_info), + (n: 'isc_transact_request'; d: {$ifndef FPC}@{$endif}@isc_transact_request), + (n: 'isc_vax_integer'; d: {$ifndef FPC}@{$endif}@isc_vax_integer), + (n: 'isc_portable_integer'; d: {$ifndef FPC}@{$endif}@isc_portable_integer), + (n: 'isc_add_user'; d: {$ifndef FPC}@{$endif}@isc_add_user), + (n: 'isc_delete_user'; d: {$ifndef FPC}@{$endif}@isc_delete_user), + (n: 'isc_modify_user'; d: {$ifndef FPC}@{$endif}@isc_modify_user), + (n: 'isc_compile_request'; d: {$ifndef FPC}@{$endif}@isc_compile_request), + (n: 'isc_compile_request2'; d: {$ifndef FPC}@{$endif}@isc_compile_request2), + (n: 'isc_ddl'; d: {$ifndef FPC}@{$endif}@isc_ddl), + (n: 'isc_prepare_transaction'; d: {$ifndef FPC}@{$endif}@isc_prepare_transaction), + (n: 'isc_receive'; d: {$ifndef FPC}@{$endif}@isc_receive), + (n: 'isc_reconnect_transaction'; d: {$ifndef FPC}@{$endif}@isc_reconnect_transaction), + (n: 'isc_release_request'; d: {$ifndef FPC}@{$endif}@isc_release_request), + (n: 'isc_request_info'; d: {$ifndef FPC}@{$endif}@isc_request_info), + (n: 'isc_seek_blob'; d: {$ifndef FPC}@{$endif}@isc_seek_blob), + (n: 'isc_send'; d: {$ifndef FPC}@{$endif}@isc_send), + (n: 'isc_start_and_send'; d: {$ifndef FPC}@{$endif}@isc_start_and_send), + (n: 'isc_start_request'; d: {$ifndef FPC}@{$endif}@isc_start_request), + (n: 'isc_unwind_request'; d: {$ifndef FPC}@{$endif}@isc_unwind_request), + (n: 'isc_wait_for_event'; d: {$ifndef FPC}@{$endif}@isc_wait_for_event), + (n: 'isc_close'; d: {$ifndef FPC}@{$endif}@isc_close), + (n: 'isc_declare'; d: {$ifndef FPC}@{$endif}@isc_declare), + (n: 'isc_describe'; d: {$ifndef FPC}@{$endif}@isc_describe), + (n: 'isc_describe_bind'; d: {$ifndef FPC}@{$endif}@isc_describe_bind), + (n: 'isc_execute'; d: {$ifndef FPC}@{$endif}@isc_execute), + (n: 'isc_execute_immediate'; d: {$ifndef FPC}@{$endif}@isc_execute_immediate), + (n: 'isc_fetch'; d: {$ifndef FPC}@{$endif}@isc_fetch), + (n: 'isc_open'; d: {$ifndef FPC}@{$endif}@isc_open), + (n: 'isc_prepare'; d: {$ifndef FPC}@{$endif}@isc_prepare), + (n: 'isc_dsql_execute_m'; d: {$ifndef FPC}@{$endif}@isc_dsql_execute_m), + (n: 'isc_dsql_execute2_m'; d: {$ifndef FPC}@{$endif}@isc_dsql_execute2_m), + (n: 'isc_dsql_execute_immediate_m'; d: {$ifndef FPC}@{$endif}@isc_dsql_execute_immediate_m), + (n: 'isc_dsql_exec_immed3_m'; d: {$ifndef FPC}@{$endif}@isc_dsql_exec_immed3_m), + (n: 'isc_dsql_fetch_m'; d: {$ifndef FPC}@{$endif}@isc_dsql_fetch_m), + (n: 'isc_dsql_insert_m'; d: {$ifndef FPC}@{$endif}@isc_dsql_insert_m), + (n: 'isc_dsql_prepare_m'; d: {$ifndef FPC}@{$endif}@isc_dsql_prepare_m), + (n: 'isc_dsql_release'; d: {$ifndef FPC}@{$endif}@isc_dsql_release), + (n: 'isc_embed_dsql_close'; d: {$ifndef FPC}@{$endif}@isc_embed_dsql_close), + (n: 'isc_embed_dsql_declare'; d: {$ifndef FPC}@{$endif}@isc_embed_dsql_declare), + (n: 'isc_embed_dsql_describe'; d: {$ifndef FPC}@{$endif}@isc_embed_dsql_describe), + (n: 'isc_embed_dsql_describe_bind'; d: {$ifndef FPC}@{$endif}@isc_embed_dsql_describe_bind), + (n: 'isc_embed_dsql_execute'; d: {$ifndef FPC}@{$endif}@isc_embed_dsql_execute), + (n: 'isc_embed_dsql_execute2'; d: {$ifndef FPC}@{$endif}@isc_embed_dsql_execute2), + (n: 'isc_embed_dsql_execute_immed'; d: {$ifndef FPC}@{$endif}@isc_embed_dsql_execute_immed), + (n: 'isc_embed_dsql_fetch'; d: {$ifndef FPC}@{$endif}@isc_embed_dsql_fetch), + (n: 'isc_embed_dsql_open'; d: {$ifndef FPC}@{$endif}@isc_embed_dsql_open), + (n: 'isc_embed_dsql_open2'; d: {$ifndef FPC}@{$endif}@isc_embed_dsql_open2), + (n: 'isc_embed_dsql_insert'; d: {$ifndef FPC}@{$endif}@isc_embed_dsql_insert), + (n: 'isc_embed_dsql_prepare'; d: {$ifndef FPC}@{$endif}@isc_embed_dsql_prepare), + (n: 'isc_embed_dsql_release'; d: {$ifndef FPC}@{$endif}@isc_embed_dsql_release), + (n: 'BLOB_open'; d: {$ifndef FPC}@{$endif}@BLOB_open), + (n: 'BLOB_put'; d: {$ifndef FPC}@{$endif}@BLOB_put), + (n: 'BLOB_close'; d: {$ifndef FPC}@{$endif}@BLOB_close), + (n: 'BLOB_get'; d: {$ifndef FPC}@{$endif}@BLOB_get), + (n: 'BLOB_display'; d: {$ifndef FPC}@{$endif}@BLOB_display), + (n: 'BLOB_dump'; d: {$ifndef FPC}@{$endif}@BLOB_dump), + (n: 'BLOB_edit'; d: {$ifndef FPC}@{$endif}@BLOB_edit), + (n: 'BLOB_load'; d: {$ifndef FPC}@{$endif}@BLOB_load), + (n: 'BLOB_text_dump'; d: {$ifndef FPC}@{$endif}@BLOB_text_dump), + (n: 'BLOB_text_load'; d: {$ifndef FPC}@{$endif}@BLOB_text_load), + (n: 'Bopen'; d: {$ifndef FPC}@{$endif}@Bopen), + (n: 'isc_ftof'; d: {$ifndef FPC}@{$endif}@isc_ftof), + (n: 'isc_print_blr'; d: {$ifndef FPC}@{$endif}@isc_print_blr), + (n: 'isc_set_debug'; d: {$ifndef FPC}@{$endif}@isc_set_debug), + (n: 'isc_qtoq'; d: {$ifndef FPC}@{$endif}@isc_qtoq), + (n: 'isc_vtof'; d: {$ifndef FPC}@{$endif}@isc_vtof), + (n: 'isc_vtov'; d: {$ifndef FPC}@{$endif}@isc_vtov), + (n: 'isc_version'; d: {$ifndef FPC}@{$endif}@isc_version), + (n: 'isc_get_client_version'; d: {$ifndef FPC}@{$endif}@isc_get_client_version), + (n: 'isc_get_client_major_version'; d: {$ifndef FPC}@{$endif}@isc_get_client_major_version), + (n: 'isc_get_client_minor_version'; d: {$ifndef FPC}@{$endif}@isc_get_client_minor_version), + (n: 'isc_service_attach'; d: {$ifndef FPC}@{$endif}@isc_service_attach), + (n: 'isc_service_detach'; d: {$ifndef FPC}@{$endif}@isc_service_detach), + (n: 'isc_service_query'; d: {$ifndef FPC}@{$endif}@isc_service_query), + (n: 'isc_service_start'; d: {$ifndef FPC}@{$endif}@isc_service_start) + +{$IFDEF Unix} + , + (n: 'Bopen2'; d: {$ifndef FPC}@{$endif}@Bopen2), + (n: 'isc_reset_fpe'; d: {$ifndef FPC}@{$endif}@isc_reset_fpe), + (n: 'isc_compile_map'; d: {$ifndef FPC}@{$endif}@isc_compile_map), + (n: 'isc_compile_menu'; d: {$ifndef FPC}@{$endif}@isc_compile_menu), + (n: 'isc_compile_sub_map'; d: {$ifndef FPC}@{$endif}@isc_compile_sub_map), + (n: 'isc_create_window'; d: {$ifndef FPC}@{$endif}@isc_create_window), + (n: 'isc_delete_window'; d: {$ifndef FPC}@{$endif}@isc_delete_window), + (n: 'isc_drive_form'; d: {$ifndef FPC}@{$endif}@isc_drive_form), + (n: 'isc_drive_menu'; d: {$ifndef FPC}@{$endif}@isc_drive_menu), + (n: 'isc_form_delete'; d: {$ifndef FPC}@{$endif}@isc_form_delete), + (n: 'isc_form_fetch'; d: {$ifndef FPC}@{$endif}@isc_form_fetch), + (n: 'isc_form_insert'; d: {$ifndef FPC}@{$endif}@isc_form_insert), + (n: 'isc_get_entree'; d: {$ifndef FPC}@{$endif}@isc_get_entree), + (n: 'isc_initialize_menu'; d: {$ifndef FPC}@{$endif}@isc_initialize_menu), + (n: 'isc_menu'; d: {$ifndef FPC}@{$endif}@isc_menu), + (n: 'isc_load_form'; d: {$ifndef FPC}@{$endif}@isc_load_form), + (n: 'isc_pop_window'; d: {$ifndef FPC}@{$endif}@isc_pop_window), + (n: 'isc_put_entree'; d: {$ifndef FPC}@{$endif}@isc_put_entree), + (n: 'isc_reset_form'; d: {$ifndef FPC}@{$endif}@isc_reset_form), + (n: 'isc_suspend_window'; d: {$ifndef FPC}@{$endif}@isc_suspend_window) +{$ENDIF} + , + (n: 'fb_shutdown'; d: @fb_shutdown) + ); + + errormessage = 'Can not load Firebird library. '; +begin +// if length(sonames) = 0 then begin + if useembeddedfirebird then begin + initializedynlib(libinfo,sonames,fbembedlib,[],funcs,errormessage); + //accept missing entries + end + else begin + initializedynlib(libinfo,sonames,fbcgdslib,[],funcs,errormessage); + //accept missing entries + end; +// end +// else begin +// initializedynlib(libinfo,sonames,[],[],funcs,errormessage); + //accept missing entries +// end; +end; + +procedure shutdown(const data: pointer); +begin + //FB-embedded crash on Linux exit, probably atexit() call in FB-lib, + //fb_shutdown() call does not help + //workarond: call + // initializeibase60(fbembedlib); + //at program start in order to prevent unloading of FB-lib + if fb_shutdown <> nil then begin + fb_shutdown(100,-fb_shutrsn_app_stopped); + end; +end; + +Procedure ReleaseIBase60; + +begin + releasedynlib(libinfo,@shutdown); +end; + +initialization + initializelibinfo(libinfo); +finalization + if libinfo.refcount > 0 then begin + libinfo.refcount:= 1; + releaseibase60(); + end; + finalizelibinfo(libinfo); +{$ENDIF} + diff --git a/mseide-msegui/lib/common/db/ibase60.pas b/mseide-msegui/lib/common/db/ibase60.pas new file mode 100644 index 0000000..db7a378 --- /dev/null +++ b/mseide-msegui/lib/common/db/ibase60.pas @@ -0,0 +1,9 @@ +{ +} +unit ibase60; + +{$UNDEF LinkDynamically} + +{$i ibase60.inc} + +end. diff --git a/mseide-msegui/lib/common/db/ibase60dyn.pas b/mseide-msegui/lib/common/db/ibase60dyn.pas new file mode 100644 index 0000000..139087b --- /dev/null +++ b/mseide-msegui/lib/common/db/ibase60dyn.pas @@ -0,0 +1,18 @@ +{ + + + Contains the Interbase/Firebird-functions calls + In this stage only the calls needed for IBConnection are implemented + Other calls could be simply implemented, using copy-paste from ibase60 + + Call InitialiseIbase60 before using any of the calls, and call ReleaseIbase60 + when finished. +} + +unit ibase60dyn; + +{$DEFINE LinkDynamically} + +{$i ibase60.inc} + +end. diff --git a/mseide-msegui/lib/common/db/memds.pp b/mseide-msegui/lib/common/db/memds.pp new file mode 100644 index 0000000..633cabd --- /dev/null +++ b/mseide-msegui/lib/common/db/memds.pp @@ -0,0 +1,987 @@ +{ + This file is part of the Free Component Library (FCL) + Copyright (c) 1999-2000 by the Free Pascal development team + Modified 2007 by Martin Schreiber + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + **********************************************************************} +{$mode objfpc} +{$H+} +{ + TMemDataset : In-memory dataset. + - Has possibility to copy Structure/Data from other dataset. + - Can load/save to/from stream. + + Ideas taken from THKMemTab Component by Harri Kasulke - Hamburg/Germany + E-mail: harri.kasulke@okay.net +} + +unit memds; +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + sysutils,classes,mclasses,mdb,msetypes; +const + // Stream Markers. + MarkerSize = SizeOf(Integer); + + smEOF = 0; + smFieldDefs = 1; + smData = 2; + +type + MDSError=class(Exception); + + PRecInfo=^TMTRecInfo; + TMTRecInfo=record + Bookmark: Longint; + BookmarkFlag: TBookmarkFlag; + end; + + PInteger = ^Integer; + PSmallInt = ^SmallInt; + PInt64 = ^Int64; + PFloat = ^Extended; + PBoolean = ^Boolean; + + TMemDataset=class(TDataSet) + private + FOpenStream : TStream; + FFileName : String; + FFileModified : Boolean; + FStream: TMemoryStream; + FRecInfoOffset: integer; + FRecInfoSize: integer; + FRecCount: integer; + FRecSize: integer; + FRecBufferSize: integer; + FCurrRecNo: integer; + FIsOpen: boolean; + FFilterBuffer: PChar; + ffieldoffsets: integerarty; + freadfieldsizes: integerarty; + fwritefieldsizes: integerarty; + procedure calcrecordlayout; + function MDSGetRecordOffset(ARecNo: integer): longint; + function MDSGetFieldOffset(FieldNo: integer): integer; + function MDSGetBufferSize(FieldNo: integer; out fieldsize: integer): integer; + function MDSGetActiveBuffer(var Buffer: PChar): Boolean; + procedure MDSReadRecord(Buffer:PChar;ARecNo:Integer); + procedure MDSWriteRecord(Buffer:PChar;ARecNo:Integer); + procedure MDSAppendRecord(Buffer:PChar); + function MDSFilterRecord(Buffer: PChar): Boolean; + protected + // Mandatory + function AllocRecordBuffer: PChar; override; + procedure FreeRecordBuffer(var Buffer: PChar); override; + procedure GetBookmarkData(Buffer: PChar; Data: Pointer); override; + function GetBookmarkFlag(Buffer: PChar): TBookmarkFlag; override; + function GetRecord(Buffer: PChar; GetMode: TGetMode; DoCheck: Boolean): TGetResult; override; + function GetRecordSize: Word; override; + procedure InternalAddRecord(Buffer: Pointer; DoAppend: Boolean); override; + procedure InternalClose; override; + procedure InternalDelete; override; + procedure InternalFirst; override; + procedure InternalGotoBookmark(ABookmark: Pointer); override; + procedure InternalInitFieldDefs; override; + procedure InternalInitRecord(Buffer: PChar); override; + procedure InternalLast; override; + procedure InternalOpen; override; + procedure InternalPost; override; + procedure InternalSetToRecord(Buffer: PChar); override; + function IsCursorOpen: Boolean; override; + procedure SetBookmarkFlag(Buffer: PChar; Value: TBookmarkFlag); override; + procedure SetBookmarkData(Buffer: PChar; Data: Pointer); override; + + // Optional. + function GetRecordCount: Integer; override; + procedure SetRecNo(Value: Integer); override; + function GetRecNo: Integer; override; + + // Own. + Procedure RaiseError(Fmt : String; Args : Array of const); + Procedure CheckMarker(F : TStream; Marker : Integer); + Procedure WriteMarker(F : TStream; Marker : Integer); + procedure ReadFieldDefsFromStream(F : TStream); + procedure SaveFieldDefsToStream(F : TStream); + // These should be overridden if you want to load more data. + // E.g. index defs. + Procedure LoadDataFromStream(F : TStream); virtual; + // If SaveData=False, a size 0 block should be written. + Procedure SaveDataToStream(F : TStream; SaveData : Boolean); virtual; + + + public + constructor Create(AOwner:tComponent); override; + destructor Destroy; override; + procedure CreateTable; + + Function DataSize : Integer; + + function GetFieldData(Field: TField; Buffer: Pointer): Boolean; override; + procedure SetFieldData(Field: TField; Buffer: Pointer); override; + procedure Clear(ClearDefs : Boolean); + procedure Clear; + Procedure SaveToFile(AFileName : String); + Procedure SaveToFile(AFileName : String; SaveData : Boolean); + Procedure SaveToStream(F : TStream); + Procedure SaveToStream(F : TStream; SaveData : Boolean); + Procedure LoadFromStream(F : TStream); + Procedure LoadFromFile(AFileName : String); + Procedure CopyFromDataset(DataSet : TDataSet); + Procedure CopyFromDataset(DataSet : TDataSet; CopyData : Boolean); + + Property FileModified : Boolean Read FFileModified; + + published + Property FileName : String Read FFileName Write FFileName; + property Filtered; + Property Active default false; + property AutocalcFields default false; + Property FieldDefs; + property BeforeOpen; + property AfterOpen; + property BeforeClose; + property AfterClose; + property BeforeInsert; + property AfterInsert; + property BeforeEdit; + property AfterEdit; + property BeforePost; + property AfterPost; + property BeforeCancel; + property AfterCancel; + property BeforeDelete; + property AfterDelete; + property BeforeScroll; + property AfterScroll; + property OnDeleteError; + property OnEditError; + property OnNewRecord; + property OnPostError; + property onmodified; + property OnFilterRecord; + end; + +implementation +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +ResourceString + SErrFieldTypeNotSupported = 'Fieldtype of Field "%s" not supported.'; + SErrBookMarkNotFound = 'Bookmark %d not found.'; + SErrInvalidDataStream = 'Error in data stream at position %d'; + SErrInvalidMarkerAtPos = 'Wrong data stream marker at position %d. Got %d, expected %d'; + SErrNoFileName = 'Filename must not be empty.'; + +const + ormask: array[0..7] of byte = (%00000001,%00000010,%00000100,%00001000, + %00010000,%00100000,%01000000,%10000000); + andmask: array[0..7] of byte = (%11111110,%11111101,%11111011,%11110111, + %11101111,%11011111,%10111111,%01111111); + +procedure unsetfieldisnull(nullmask: pbyte; const x: integer); +//var +// int1: integer; +begin + inc(nullmask,(x shr 3)); + nullmask^:= nullmask^ or ormask[x and 7]; +end; + +procedure setfieldisnull(nullmask: pbyte; const x: integer); +begin + inc(nullmask,(x shr 3)); + nullmask^:= nullmask^ and andmask[x and 7]; +end; + +function getfieldisnull(nullmask: pbyte; const x: integer): boolean; +begin + inc(nullmask,(x shr 3)); + result:= nullmask^ and ormask[x and 7] = 0; +end; + + +{ --------------------------------------------------------------------- + Stream functions + ---------------------------------------------------------------------} + +Function ReadInteger(S : TStream) : Integer; + +begin + S.ReadBuffer(Result,SizeOf(Result)); +end; + +Function ReadString(S : TStream) : String; + +Var + L : Integer; + +begin + L:=ReadInteger(S); + Setlength(Result,L); + If (L<>0) then + S.ReadBuffer(Result[1],L); +end; + +Procedure WriteInteger(S : TStream; Value : Integer); + +begin + S.WriteBuffer(Value,SizeOf(Value)); +end; + +Procedure WriteString(S : TStream; Value : String); + +Var + L : Integer; + +begin + L:=Length(Value); + WriteInteger(S,Length(Value)); + If (L<>0) then + S.WriteBuffer(Value[1],L); +end; + +{ --------------------------------------------------------------------- + TMemDataset + ---------------------------------------------------------------------} + + +constructor TMemDataset.Create(AOwner:tComponent); + +begin + inherited create(aOwner); + FStream:=TMemoryStream.Create; + FRecInfoSize:=SizeOf(TMTRecInfo); + FRecCount:=0; + FRecSize:=0; + FRecBufferSize:=0; + FRecInfoOffset:=0; + FCurrRecNo:=-1; + FIsOpen:=False; +end; + +Destructor TMemDataset.Destroy; +begin + FStream.Free; + inherited Destroy; +end; + +function TMemDataset.MDSGetRecordOffset(ARecNo: integer): longint; +begin + Result:=FRecSize*ARecNo +end; + +function TMemDataset.MDSGetFieldOffset(FieldNo: integer): integer; +begin + result:= ffieldoffsets[fieldno-1]; +end; + +Procedure TMemDataset.RaiseError(Fmt : String; Args : Array of const); + +begin + Raise MDSError.CreateFmt(Fmt,Args); +end; + +function TMemDataset.MDSGetBufferSize(FieldNo: integer; + out fieldsize: integer): integer; +var + dt1: tfieldtype; +begin + result:= 0; //compiler warning + dt1:= FieldDefs.Items[FieldNo-1].Datatype; + case dt1 of + ftString: result:=FieldDefs.Items[FieldNo-1].Size+1; + ftBoolean: result:=SizeOf(Wordbool{Boolean}); + ftFloat,ftcurrency: result:=SizeOf(Double{Extended}); + ftLargeInt: result:=SizeOf(int64); + ftSmallInt: result:=SizeOf(SmallInt); + ftInteger: result:=SizeOf(Integer); + ftDate: result:=SizeOf(TDateTime); + ftTime: result:=SizeOf(TDateTime); + else + RaiseError(SErrFieldTypeNotSupported,[FieldDefs.Items[FieldNo-1].Name]); + end; + if dt1 = ftstring then begin + fieldsize:= result - 1; + end + else begin + fieldsize:= result; + end; +end; + +function TMemDataset.MDSGetActiveBuffer(var Buffer: PChar): Boolean; + +begin + case State of + dsBrowse: + if IsEmpty then + Buffer:=nil + else + Buffer:=ActiveBuffer; + + dsEdit, + dsInsert: + Buffer:=ActiveBuffer; + dsFilter: + Buffer:=FFilterBuffer; + else + Buffer:=nil; + end; + Result:=(Buffer<>nil); +end; + +procedure TMemDataset.MDSReadRecord(Buffer:PChar;ARecNo:Integer); //Reads a Rec from Stream in Buffer +begin + FStream.Position:=MDSGetRecordOffset(ARecNo); + FStream.ReadBuffer(Buffer^, FRecSize); +end; + +procedure TMemDataset.MDSWriteRecord(Buffer:PChar;ARecNo:Integer); //Writes a Rec from Buffer to Stream +begin + FStream.Position:=MDSGetRecordOffset(ARecNo); + FStream.WriteBuffer(Buffer^, FRecSize); + FFileModified:=True; +end; + +procedure TMemDataset.MDSAppendRecord(Buffer:PChar); //Appends a Rec (from Buffer) to Stream +begin + FStream.Position:=MDSGetRecordOffset(FRecCount); + FStream.WriteBuffer(Buffer^, FRecSize); + FFileModified:=True; +end; + +//Abstract Overrides +function TMemDataset.AllocRecordBuffer: PChar; +begin + GetMem(Result,FRecBufferSize); +end; + +procedure TMemDataset.FreeRecordBuffer (var Buffer: PChar); +begin + FreeMem(Buffer); +end; + +procedure TMemDataset.InternalInitRecord(Buffer: PChar); + +//var +// I : integer; + +begin + fillchar(buffer^,frecsize,0); +end; + +procedure TMemDataset.InternalDelete; + +Var + TS : TMemoryStream; +// OldPos,NewPos,CopySize1,CopySize2 : longword; + +begin + if (FCurrRecNo<0) or (FCurrRecNo>=FRecCount) then + Exit; + // Very inefficient. We should simply move the last part closer to the beginning in + // The FStream. + TS:=TMemoryStream.Create; + Try + if FCurrRecNo>0 then + begin + FStream.Position:=MDSGetRecordOffset(0); //Delete Rec + if FCurrRecNo=FRecCount then FCurrRecNo:=FRecCount-1; + Finally + TS.Free; + end; + FFileModified:=True; +end; + +procedure TMemDataset.InternalInitFieldDefs; + +begin + If (FOpenStream<>Nil) then + ReadFieldDefsFromStream(FOpenStream); +end; + +Procedure TMemDataset.CheckMarker(F : TStream; Marker : Integer); + +Var + I,P : Integer; + +begin + P:=F.Position; + If F.Read(I,MarkerSize)<>MarkerSize then + RaiseError(SErrInvalidDataStream,[P]) + else + if (I<>Marker) then + RaiseError(SErrInvalidMarkerAtPos,[P,I,Marker]); +end; + +procedure TMemDataset.ReadFieldDefsFromStream(F : TStream); + +Var + I,ACount : Integer; + FN : String; + FS : Integer; + B : Boolean; + FT : TFieldType; + +begin + CheckMarker(F,smFieldDefs); + FieldDefs.Clear; + ACount:=ReadInteger(F); + For I:=1 to ACount do + begin + FN:=ReadString(F); + FS:=ReadInteger(F); + FT:=TFieldType(ReadInteger(F)); + B:=ReadInteger(F)<>0; + TFieldDef.Create(FieldDefs,FN,ft,FS,B,I); + end; + CreateTable; +end; + +procedure TMemDataset.InternalFirst; +begin + FCurrRecNo:=-1; +end; + +procedure TMemDataset.InternalLast; +begin + FCurrRecNo:=FRecCount; +end; + +procedure TMemDataset.InternalOpen; + + +begin + If (FFileName<>'') then + FOpenStream:=TFileStream.Create(FFileName,fmOpenRead); + Try + InternalInitFieldDefs; + if DefaultFields then + CreateFields; + BindFields(True); + FCurrRecNo:=-1; + If (FOpenStream<>Nil) then + begin + LoadDataFromStream(FOpenStream); + CheckMarker(FOpenStream,smEOF); + end; + Finally + FreeAndNil(FOpenStream); + end; + FIsOpen:=True; +end; + +Procedure TMemDataSet.LoadDataFromStream(F : TStream); + +Var + Size : Integer; + +begin + CheckMarker(F,smData); + Size:=ReadInteger(F); + FStream.Clear; + FStream.CopyFrom(F,Size); + FRecCount:=Size div FRecSize; + FCurrRecNo:=-1; +end; + +Procedure TMemDataSet.LoadFromStream(F : TStream); + +begin + Close; + ReadFieldDefsFromStream(F); + LoadDataFromStream(F); + CheckMarker(F,smEOF); + FFileModified:=False; +end; + +Procedure TMemDataSet.LoadFromFile(AFileName : String); + +Var + F : TFileStream; + +begin + F:=TFileStream.Create(AFileName,fmOpenRead); + Try + LoadFromStream(F); + Finally + F.Free; + end; +end; + + +Procedure TMemDataset.SaveToFile(AFileName : String); + +begin + SaveToFile(AFileName,True); +end; + +Procedure TMemDataset.SaveToFile(AFileName : String; SaveData : Boolean); + +Var + F : TFileStream; + +begin + If (AFileName='') then + RaiseError(SErrNoFileName,[]); + F:=TFileStream.Create(AFileName,fmCreate); + try + SaveToStream(F,SaveData); + Finally + F.Free; + end; +end; + +Procedure TMemDataset.WriteMarker(F : TStream; Marker : Integer); + +begin + Writeinteger(F,Marker); +end; + +Procedure TMemDataset.SaveToStream(F : TStream); + +begin + SaveToStream(F,True); +end; + +Procedure TMemDataset.SaveToStream(F : TStream; SaveData : Boolean); + +begin + SaveFieldDefsToStream(F); + If SaveData then + SaveDataToStream(F,SaveData); + WriteMarker(F,smEOF); +end; + +Procedure TMemDataset.SaveFieldDefsToStream(F : TStream); + +Var + I{,ACount} : Integer; +// FN : String; +// FS : Integer; +// B : Boolean; +// FT : TFieldType; + FD : TFieldDef; + +begin + WriteMarker(F,smFieldDefs); + WriteInteger(F,FieldDefs.Count); + For I:=1 to FieldDefs.Count do + begin + FD:=FieldDefs[I-1]; + WriteString(F,FD.Name); + WriteInteger(F,FD.Size); + WriteInteger(F,Ord(FD.DataType)); + WriteInteger(F,Ord(FD.Required)); + end; +end; + +Procedure TMemDataset.SaveDataToStream(F : TStream; SaveData : Boolean); + +begin + if SaveData then + begin + WriteMarker(F,smData); + WriteInteger(F,FStream.Size); + FStream.Position:=0; + F.CopyFrom(FStream,FStream.Size); + FFileModified:=False; + end + else + begin + WriteMarker(F,smData); + WriteInteger(F,0); + end; +end; + +procedure TMemDataset.InternalClose; + +begin + if (FFileModified) and (FFileName<>'') then begin + SaveToFile(FFileName,True); + end; + FIsOpen:=False; + FFileModified:=False; + BindFields(False); + if DefaultFields then begin + DestroyFields; + end; + ffieldoffsets:= nil; + freadfieldsizes:= nil; + fwritefieldsizes:= nil; +end; + +procedure TMemDataset.InternalPost; +begin + CheckActive; + if ((State<>dsEdit) and (State<>dsInsert)) then + Exit; + if (State=dsEdit) then + MDSWriteRecord(ActiveBuffer, FCurrRecNo) + else + InternalAddRecord(ActiveBuffer,True); +end; + +function TMemDataset.IsCursorOpen: Boolean; + +begin + Result:=FIsOpen; +end; + +function TMemDataset.GetRecord(Buffer: PChar; GetMode: TGetMode; DoCheck: Boolean): TGetResult; + +var + Accepted: Boolean; + +begin + Result:=grOk; + Accepted:=False; + if (FRecCount<1) then + begin + Result:=grEOF; + exit; + end; + repeat + case GetMode of + gmCurrent: + if (FCurrRecNo>=FRecCount) or (FCurrRecNo<0) then + Result:=grError; + gmNext: + if (FCurrRecNo0) then + Dec(FCurrRecNo) + else + result:=grBOF; + end; + if result=grOK then + begin + MDSReadRecord(Buffer, FCurrRecNo); + PRecInfo(Buffer+FRecInfoOffset)^.Bookmark:=FCurrRecNo; + PRecInfo(Buffer+FRecInfoOffset)^.BookmarkFlag:=bfCurrent; + if (Filtered) then + Accepted:=MDSFilterRecord(Buffer) //Filtering + else + Accepted:=True; + if (GetMode=gmCurrent) and not Accepted then + result:=grError; + end; + until (result<>grOK) or Accepted; +end; + +function TMemDataset.GetFieldData(Field: TField; Buffer: Pointer): Boolean; +var + SrcBuffer: PChar; + int1: integer; +begin + int1:= Field.FieldNo - 1; + result:= (int1 >= 0) and MDSGetActiveBuffer(SrcBuffer) and + not getfieldisnull(pointer(srcbuffer),int1); + if result and (buffer <> nil) then begin + Move((SrcBuffer+ffieldoffsets[int1])^, Buffer^,freadfieldsizes[int1]); + end; +end; + +procedure TMemDataset.SetFieldData(Field: TField; Buffer: Pointer); +var + DestBuffer: PChar; + int1: integer; + +begin + int1:= Field.FieldNo - 1; + if (int1 >= 0) and MDSGetActiveBuffer(DestBuffer) then begin + if buffer = nil then begin + setfieldisnull(pointer(destbuffer),int1); + end + else begin + unsetfieldisnull(pointer(destbuffer),int1); + Move(Buffer^,(DestBuffer+ffieldoffsets[int1])^,fwritefieldsizes[int1]); + dataevent(defieldchange,ptrint(field)); + end; + end; +end; + +function TMemDataset.GetRecordSize: Word; + +begin + Result:= FRecSize; +end; + +procedure TMemDataset.InternalGotoBookmark(ABookmark: Pointer); + +var + ReqBookmark: integer; + +begin + ReqBookmark:=PInteger(ABookmark)^; + if (ReqBookmark>=0) and (ReqBookmarknil then + PInteger(Data)^:=PRecInfo(Buffer+FRecInfoOffset)^.Bookmark; +end; + +procedure TMemDataset.SetBookmarkData(Buffer: PChar; Data: Pointer); + +begin + if Data<>nil then + PRecInfo(Buffer+FRecInfoOffset)^.Bookmark:=PInteger(Data)^ + else + PRecInfo(Buffer+FRecInfoOffset)^.Bookmark:=0; +end; + +function TMemDataset.MDSFilterRecord(Buffer: PChar): Boolean; + +var + SaveState: TDatasetState; + +begin + Result:=True; + if not Assigned(OnFilterRecord) then + Exit; + SaveState:=SetTempState(dsFilter); + FFilterBuffer:=Buffer; + OnFilterRecord(Self,Result); + RestoreState(SaveState); +end; + +Function TMemDataset.DataSize : Integer; + +begin + Result:=FStream.Size; +end; + +procedure TMemDataset.Clear; + +begin + Clear(True); +end; + +procedure TMemDataset.Clear(ClearDefs : Boolean); + +begin + FStream.Clear; + FRecCount:=0; + FCurrRecNo:=-1; + if Active then + Resync([]); + If ClearDefs then + begin + Close; + FieldDefs.Clear; + end; +end; + +procedure tmemdataset.calcrecordlayout; +var + int1: integer; +begin + int1:= fielddefs.count; + setlength(ffieldoffsets,int1); + setlength(freadfieldsizes,int1); + setlength(fwritefieldsizes,int1); + FRecSize:= (int1+7) div 8; //null mask + for int1:= 0 to high(ffieldoffsets) do begin + ffieldoffsets[int1]:= frecsize; + freadfieldsizes[int1]:= MDSGetbufferSize(int1+1,fwritefieldsizes[int1]); + FRecSize:= FRecSize + freadfieldsizes[int1]; + end; +end; + +procedure TMemDataset.CreateTable; + +begin + FStream.Clear; + FRecCount:=0; + FCurrRecNo:=-1; + FIsOpen:=False; + calcrecordlayout; + FRecInfoOffset:=FRecSize; + FRecSize:=FRecSize+FRecInfoSize; + FRecBufferSize:=FRecSize; +end; + +procedure TMemDataset.InternalAddRecord(Buffer: Pointer; DoAppend: Boolean); + +begin + MDSAppendRecord(ActiveBuffer); + InternalLast; + Inc(FRecCount); +end; + +procedure TMemDataset.SetRecNo(Value: Integer); +begin + CheckBrowseMode; + if (Value>=1) and (Value<=FRecCount) then + begin + FCurrRecNo:=Value-1; + Resync([]); + end; +end; + +Function TMemDataset.GetRecNo: Longint; + +begin + UpdateCursorPos; + if (FCurrRecNo<0) then + Result:=1 + else + Result:=FCurrRecNo+1; +end; + +Function TMemDataset.GetRecordCount: Longint; + +begin + CheckActive; + Result:=FRecCount; +end; + +Procedure TMemDataset.CopyFromDataset(DataSet : TDataSet); + +begin + CopyFromDataset(Dataset,True); +end; + +Procedure TMemDataset.CopyFromDataset(DataSet : TDataSet; CopyData : Boolean); + +Var + I : Integer; + F,F1,F2 : TField; + L1,L2 : TList; + N : String; + +begin + Clear(True); + // NOT from fielddefs. The data may not be available in buffers !! + For I:=0 to Dataset.FieldCount-1 do + begin + F:=Dataset.Fields[I]; + TFieldDef.Create(FieldDefs,F.FieldName,F.DataType,F.Size,F.Required,F.FieldNo); + end; + CreateTable; + If CopyData then + begin + Open; + L1:=TList.Create; + Try + L2:=TList.Create; + Try + For I:=0 to FieldDefs.Count-1 do + begin + N:=FieldDefs[I].Name; + F1:=FieldByName(N); + F2:=DataSet.FieldByName(N); + L1.Add(F1); + L2.Add(F2); + end; + Dataset.DisableControls; + Try + Dataset.Open; + While not Dataset.EOF do + begin + Append; + For I:=0 to L1.Count-1 do + begin + F1:=TField(L1[i]); + F2:=TField(L2[I]); + Case F1.DataType of + ftString : F1.AsString:=F2.AsString; + ftBoolean : F1.AsBoolean:=F2.AsBoolean; + ftFloat,ftcurrency : F1.AsFloat:=F2.AsFloat; + ftLargeInt : F1.AsInteger:=F2.AsInteger; + ftSmallInt : F1.AsInteger:=F2.AsInteger; + ftInteger : F1.AsInteger:=F2.AsInteger; + ftDate : F1.AsDateTime:=F2.AsDateTime; + ftTime : F1.AsDateTime:=F2.AsDateTime; + end; + end; + Try + Post; + except + Cancel; + Raise; + end; + Dataset.Next; + end; + Finally + Dataset.EnableControls; + end; + finally + L2.Free; + end; + finally + l1.Free; + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/db/mibconnection.pas b/mseide-msegui/lib/common/db/mibconnection.pas new file mode 100644 index 0000000..5210be2 --- /dev/null +++ b/mseide-msegui/lib/common/db/mibconnection.pas @@ -0,0 +1,1827 @@ +{ + Copyright (c) 2004 by Joost van der Sluis + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Modified 2006-2013 by Martin Schreiber + + **********************************************************************} + +unit mibconnection; +{$ifdef FPC}{$mode objfpc}{$H+}{$macro on}{$endif} +{$ifdef linux}{$define unix}{$endif} + +{$Define LinkDynamically} +{$R-} +(* +{$IFDEF Unix} + {$DEFINE extdecl:=cdecl} +{$else} + {$DEFINE extdecl:=stdcall} +{$endif} +*) +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +//todo: use execute_immediate if possible + +uses + classes,mclasses,SysUtils,msqldb,mdb,math, + {$ifdef FPC}dbconst{$else}dbconst_del{$endif},msebufdataset,msedbevents, + msesystypes,msestrings,msedb,msetypes, +{$IfDef LinkDynamically} + ibase60dyn; +{$Else} + ibase60; +{$EndIf} + +type + tibconnection = class; + statusvectorty = array[0..19] of ISC_STATUS; + + eiberror = class(econnectionerror) + private + fstatus: statusvectorty; + fsqlcode: integer; + public + constructor create(const asender: tibconnection; const amessage: msestring; + const aerror: statusvectorty; const asqlcode: integer); + property status: statusvectorty read fstatus; + property sqlcode: integer read fsqlcode; + end; + + TIBCursor = Class(TSQLCursor) + protected + fconnection: tibconnection; + fopen: boolean; + ffetched: boolean; + fempty: boolean; + Status : statusvectorty; + Statement : pointer; + fibstatementtype: integer; + SQLDA : PXSQLDA; + in_SQLDA : PXSQLDA; + fexecsqlda: pxsqlda; + ParamBinding : tparambinding; + paramtypes: fieldtypearty; + public + constructor create(const aowner: icursorclient; + const aconnection: tibconnection); + procedure close; override; + end; + + TIBTrans = Class(TSQLHandle) + protected + TransactionHandle : pointer; + TPB : string; // Transaction parameter buffer + Status : statusvectorty; + end; + + fbeventbufferty = record + event: tdbevent; + name: string; + length: integer; + eventbuffer: pchar; + resultbuffer: pchar; + id: isc_long; + count: integer; + end; + pfbeventbufferty = ^fbeventbufferty; + + ibconnectionoptionty = (ibo_embedded,ibo_sqlinfo); + ibconnectionoptionsty = set of ibconnectionoptionty; + + fbversionty = record + imp: stringarty; + ods: string; + end; + + TIBConnection = class (TSQLConnection,iblobconnection, + idbevent,idbeventcontroller) + private + FSQLDatabaseHandle : pointer; + FStatus : statusvectorty; //array [0..19] of ISC_STATUS; + FDialect : integer; + feventcontroller: tdbeventcontroller; + feventbuffers: array of pfbeventbufferty; + feventcount: integer; + fmutex: mutexty; + foptions: ibconnectionoptionsty; + flasterror: statusvectorty; + flasterrormessage: msestring; + flastsqlcode: integer; + procedure SetDBDialect; + procedure AllocSQLDA(var aSQLDA : PXSQLDA;Count : integer); + procedure TranslateFldType(SQLType,sqlsubtype,SQLLen,SQLScale: integer; + out TrType: TFieldType; out TrLen: word); + //conversion methods + procedure GetDateTime(CurrBuff, Buffer : pointer; AType : integer); + procedure SetDateTime(CurrBuff: pointer; PTime : TDateTime; AType : integer); + procedure GetFloat(const CurrBuff,Buffer: pointer; + const datalength: integer); + procedure SetFloat(CurrBuff: pointer; Dbl: Double; Size: integer); + procedure CheckError(const ProcName : string; + const Status : statusvectorty); overload; + procedure CheckError(const ProcName : string; + const Status: integer); overload; + function getMaxBlobSize(blobHandle : TIsc_Blob_Handle) : longInt; + procedure SetParameters(cursor : TSQLCursor;AParams : TmseParams); + procedure FreeSQLDABuffer(var aSQLDA : PXSQLDA); + function getblobstream(const acursor: tsqlcursor; const blobid: isc_quad; + const forstring: boolean = false): tmemorystream; + function getblobstring(const acursor: tsqlcursor; + const blobid: isc_quad): string; + protected + procedure freeeventbuffer(var abuffer: pfbeventbufferty); + + procedure DoInternalConnect; override; + procedure DoInternalDisconnect; override; + function GetHandle : pointer; override; + + Function AllocateTransactionHandle : TSQLHandle; override; + + procedure internalExecute(const cursor: TSQLCursor; + const atransaction: tsqltransaction; const AParams : TmseParams; + const autf8: boolean); override; + function fetch1(const cursor: tibcursor) : boolean; + function GetTransactionHandle(trans : TSQLHandle): pointer; override; + function Commit(trans : TSQLHandle) : boolean; override; + function RollBack(trans : TSQLHandle) : boolean; override; + function StartdbTransaction(const trans : TSQLHandle; + const AParams : tstringlist) : boolean; override; + procedure internalCommitRetaining(trans : TSQLHandle); override; + procedure internalRollBackRetaining(trans : TSQLHandle); override; + procedure UpdateIndexDefs(var IndexDefs : TIndexDefs; + const aTableName : string; const acursor: tsqlcursor); override; + function GetSchemaInfoSQL(SchemaType : TSchemaType; SchemaObjectName, + SchemaPattern : msestring) : msestring; override; + function CreateBlobStream(const Field: TField; const Mode: TBlobStreamMode; + const acursor: tsqlcursor): TStream; override; + function getblobdatasize: integer; override; + + procedure writeblobdata(const atransactionhandle: pointer; + const tablename: string; const acursor: tsqlcursor; + const adata: pointer; const alength: integer; + const afield: tfield; const aparam: tparam; out newid: string); + overload; + //iblobconnection + procedure writeblobdata(const atransaction: tsqltransaction; + const tablename: string; const acursor: tsqlcursor; + const adata: pointer; const alength: integer; + const afield: tfield; const aparam: tparam; out newid: string); + overload; + procedure setupblobdata(const afield: tfield; const acursor: tsqlcursor; + const aparam: tparam); +// function blobscached: boolean; + //idbevent + procedure listen(const sender: tdbevent); + procedure unlisten(const sender: tdbevent); + procedure fire(const sender: tdbevent); + //idbeventcontroller + function getdbevent(var aname: string; var aid: int64): boolean; + //false if none + procedure dolisten(const sender: tdbevent); + procedure dounlisten(const sender: tdbevent); + public + constructor Create(AOwner : TComponent); override; + destructor destroy; override; + Function AllocateCursorHandle(const aowner: icursorclient; + const aname: ansistring): TSQLCursor; override; + Procedure DeAllocateCursorHandle(var cursor : TSQLCursor); override; + procedure preparestatement(const cursor: tsqlcursor; + const atransaction : tsqltransaction; + const asql: msestring; const aparams : tmseparams); override; + procedure UnPrepareStatement(cursor : TSQLCursor); override; + procedure FreeFldBuffers(cursor : TSQLCursor); override; + procedure AddFieldDefs(const cursor: TSQLCursor; + const FieldDefs : TfieldDefs); override; + function Fetch(cursor : TSQLCursor) : boolean; override; + function loadfield(const cursor: tsqlcursor; + const datatype: tfieldtype; const fieldnum: integer; //zero based + const buffer: pointer; var bufsize: integer; + const aisutf8: boolean): boolean; override; + //if bufsize < 0 -> buffer was to small, should be -bufsize + function fetchblob(const cursor: tsqlcursor; + const fieldnum: integer): ansistring; override; + //zero based + procedure createdatabase(const asql: ansistring); + function version: fbversionty; + property lasterror: statusvectorty read flasterror; + property lasterrormessage: msestring read flasterrormessage; + property lastsqlcode: integer read flastsqlcode; + published + property Dialect : integer read FDialect write FDialect default 0; + property options: ibconnectionoptionsty read foptions + write foptions default []; + property DatabaseName; + property KeepConnection; + property Params; + property ongetcredentials; + end; + +function clientversion: string; +function clientmajorversion: integer; +function clientminorversion: integer; + //library must be inited before calling + +implementation +uses + strutils,msesysintf1,msebits,msefloattostr,msedatabase,msesqlresult,msefbutils + {$ifndef FPC},classes_del{$ifdef mswindows},windows{$endif}{$endif}; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +function clientversion: string; +var + buf: array[0..255] of char; +begin + result:= ''; + if assigned(isc_get_client_version) then begin + isc_get_client_version(@buf); + result:= buf; + end; +end; + +function clientmajorversion: integer; +begin + if assigned(isc_get_client_major_version) then begin + result:= isc_get_client_major_version(); + end + else begin + result:= -1; + end; +end; + +function clientminorversion: integer; +begin + if assigned(isc_get_client_minor_version) then begin + result:= isc_get_client_minor_version(); + end + else begin + result:= -1; + end; +end; + +type + TTm = packed record + tm_sec : longint; + tm_min : longint; + tm_hour : longint; + tm_mday : longint; + tm_mon : longint; + tm_year : longint; + tm_wday : longint; + tm_yday : longint; + tm_isdst : longint; + __tm_gmtoff : longint; + __tm_zone : Pchar; + end; + +{ TIBCursor } + +procedure TIBCursor.close; +begin + inherited; + if fopen and (fibstatementtype = isc_info_sql_stmt_select) then begin + if isc_dsql_free_statement(@status, @statement, dsql_close) <> 0 then begin + fconnection.checkerror('close cursor', status{,fname}); + end; + end; + fopen:= false; +end; + +constructor TIBCursor.create(const aowner: icursorclient; + const aconnection: tibconnection); +begin + fconnection:= aconnection; + inherited create(aowner,fconnection.name); +end; + +{ tibconnection } + +procedure TIBConnection.CheckError(const ProcName : string; + const Status: statusvectorty); +var + buf: array [0..1024] of char; + p: pointer; + Msg: msestring; +begin + if ((Status[0] = 1) and (Status[1] <> 0)) then begin + p:= @Status; + msg:= msestring(procname); +{$warnings off} + while isc_interprete(Buf, @p) > 0 do begin + Msg := Msg + lineend +' -' + connectionmessage(Buf); + end; + flasterror:= status; + flasterrormessage:= msg; + flastsqlcode:= isc_sqlcode(@status); + raise eiberror.create(self,msg,status,flastsqlcode); + end; +end; +{$warnings on} + +procedure tibconnection.CheckError(const ProcName : string; + const Status: integer); +begin + if status <> 0 then begin + checkerror(procname,fstatus); + end; +end; + +constructor TIBConnection.Create(AOwner : TComponent); + +begin + sys_mutexcreate(fmutex); + feventcontroller:= tdbeventcontroller.create(idbeventcontroller(self)); + feventcontroller.eventinterval:= -1; //event driven + inherited; + FConnOptions := FConnOptions + [sco_SupportParams,sco_nounprepared]; +end; + +destructor TIBConnection.destroy; +begin + inherited; + feventcontroller.free; + sys_mutexdestroy(fmutex); +end; + +function TIBConnection.GetTransactionHandle(trans : TSQLHandle): pointer; +begin + Result:= TIBtrans(trans).TransactionHandle; +end; + +function TIBConnection.Commit(trans : TSQLHandle) : boolean; +begin + result := false; + with (trans as TIBTrans) do + if isc_commit_transaction(@Status, @TransactionHandle) <> 0 then + CheckError('Commit', Status) + else result := true; +end; + +function TIBConnection.RollBack(trans : TSQLHandle) : boolean; +begin + result:= false; + if isc_rollback_transaction(@TIBTrans(trans).Status, + @TIBTrans(trans).TransactionHandle) <> 0 then begin + CheckError('Rollback', TIBTrans(trans).Status); + end + else begin + result := true; + end; +end; + +function TIBConnection.StartDBTransaction( + const trans : TSQLHandle; const AParams : tstringlist) : boolean; +var + DBHandle : pointer; + tr : TIBTrans; + s : string; + int1: integer; + s2: string; + i2: int32; + + procedure paramerror(); + begin + raise econnectionerror.create(self, + 'Invalid transaction parameter "'+s+'"','',0); + end; //paramerror + +begin + result := false; + + DBHandle := GetHandle; + tr := trans as TIBtrans; + with tr do begin + TPB := chr(isc_tpb_version3); + for int1:= 0 to aparams.count - 1 do begin + s:= trim(aparams[int1]); + if s='isc_tpb_write' then TPB := TPB + chr(isc_tpb_write) + else if s='isc_tpb_read' then TPB := TPB + chr(isc_tpb_read) + else if s='isc_tpb_consistency' then TPB := TPB + chr(isc_tpb_consistency) + else if s='isc_tpb_concurrency' then TPB := TPB + chr(isc_tpb_concurrency) + else if s='isc_tpb_read_committed' then TPB := TPB + chr(isc_tpb_read_committed) + else if s='isc_tpb_rec_version' then TPB := TPB + chr(isc_tpb_rec_version) + else if s='isc_tpb_no_rec_version' then TPB := TPB + chr(isc_tpb_no_rec_version) + else if s='isc_tpb_wait' then TPB := TPB + chr(isc_tpb_wait) + else if s='isc_tpb_nowait' then TPB := TPB + chr(isc_tpb_nowait) + else if s='isc_tpb_shared' then TPB := TPB + chr(isc_tpb_shared) + else if s='isc_tpb_protected' then TPB := TPB + chr(isc_tpb_protected) + else if s='isc_tpb_exclusive' then TPB := TPB + chr(isc_tpb_exclusive) + else if s='isc_tpb_lock_read' then TPB := TPB + chr(isc_tpb_lock_read) + else if s='isc_tpb_lock_write' then TPB := TPB + chr(isc_tpb_lock_write) + else if s='isc_tpb_verb_time' then TPB := TPB + chr(isc_tpb_verb_time) + else if s='isc_tpb_commit_time' then TPB := TPB + chr(isc_tpb_commit_time) + else if s='isc_tpb_ignore_limbo' then TPB := TPB + chr(isc_tpb_ignore_limbo) + else if s='isc_tpb_autocommit' then TPB := TPB + chr(isc_tpb_autocommit) + else if s='isc_tpb_restart_requests' then TPB := TPB + chr(isc_tpb_restart_requests) + else if s='isc_tpb_no_auto_undo' then TPB := TPB + chr(isc_tpb_no_auto_undo) + else if pos('isc_tpb_lock_timeout',s) = 1 then begin + i2:= length('isc_tpb_lock_timeout'); + if length(s) > i2 then begin + s2:= trim(copy(s,i2+1,bigint)); + if trystrtoint(s2,i2) then begin + tpb:= tpb + chr(isc_tpb_lock_timeout)+#4+ + chr(i2)+chr(i2 shr 8)+chr(i2 shr 16)+chr(i2 shr 24); + end + else begin + paramerror(); + end; + end + else begin + paramerror(); + end; + end; + end; + TransactionHandle := nil; + if isc_start_transaction(@Status, @TransactionHandle, 1, + [@DBHandle, Length(TPB), @TPB[1]]) <> 0 then begin + CheckError('StartTransaction',Status); + end + else begin + Result:= True; + end; + end; +end; + +procedure TIBConnection.internalCommitRetaining(trans : TSQLHandle); +begin + with trans as TIBtrans do + if isc_commit_retaining(@Status, @TransactionHandle) <> 0 then + CheckError('CommitRetaining', Status); +end; + +procedure TIBConnection.internalRollBackRetaining(trans : TSQLHandle); +begin + with trans as TIBtrans do + if isc_rollback_retaining(@Status, @TransactionHandle) <> 0 then + CheckError('RollBackRetaining', Status); +end; + + +procedure TIBConnection.DoInternalConnect; +const + utf8name = 'UTF8'; +var + DPB : string; + ADatabaseName : String; + u,p: msestring; + u1,p1: string; + s1: string; +begin +{$IfDef LinkDynamically} + useembeddedfirebird:= ibo_embedded in foptions; + InitializeIBase60([]); + try +{$EndIf} + inherited dointernalconnect; + getcredentials(u,p); + DPB:= chr(isc_dpb_version1); + if (u <> '') then begin + u1:= ansistring(u); + DPB := DPB + chr(isc_dpb_user_name) + chr(Length(u1)) + u1; + stringsafefree(u1,false); + if (p <> '') then begin + p1:= ansistring(p); + DPB := DPB + chr(isc_dpb_password) + chr(Length(p1)) + p1; + stringsafefree(p1,false); + end; + end; + freecredentials(u,p); + if (Role <> '') then begin + s1:= ansistring(role); + DPB := DPB + chr(isc_dpb_sql_role_name) + chr(Length(s1)) + s1; + end; + if Length(CharSet) > 0 then begin + s1:= ansistring(charset); + DPB := DPB + Chr(isc_dpb_lc_ctype) + Chr(Length(s1)) + s1; + end + else begin + if dbo_utf8 in fcontroller.options then begin + DPB := DPB + Chr(isc_dpb_lc_ctype) + Chr(Length(utf8name)) + utf8name; + end; + end; + + FSQLDatabaseHandle := nil; + if HostName <> '' then ADatabaseName := ansistring(HostName)+':'+ + ansistring(DatabaseName) + else ADatabaseName := ansistring(DatabaseName); + if isc_attach_database(@FStatus, Length(ADatabaseName), @ADatabaseName[1], + @FSQLDatabaseHandle,Length(DPB), @DPB[1]) <> 0 then + stringsafefree(dpb,false); + CheckError('DoInternalConnect', FStatus); + stringsafefree(dpb,false); + SetDBDialect; +{$IfDef LinkDynamically} + except + releaseIBase60; + raise; + end; +{$EndIf} + feventcontroller.connect; +end; + +procedure TIBConnection.DoInternalDisconnect; +begin + feventcontroller.disconnect; + if not Connected then begin + FSQLDatabaseHandle:= nil; + Exit; + end; + isc_detach_database(@FStatus[0], @FSQLDatabaseHandle); +// CheckError('Close', FStatus); //no exception on close +{$IfDef LinkDynamically} + ReleaseIBase60; +{$EndIf} +end; + +procedure TIBConnection.SetDBDialect; +const + bufferlength = 40; +var + x : integer; + Len : integer; + Buffer : string; + ResBuf : array [0..bufferlength-1] of byte; + by1: byte; +begin + Buffer:= Chr(isc_info_db_sql_dialect) + Chr(isc_info_end); + if isc_database_info(@FStatus, @FSQLDatabaseHandle, Length(Buffer), + @Buffer[1], SizeOf(ResBuf), @ResBuf) <> 0 then begin + CheckError('SetDBDialect', FStatus); + end; + x := 0; + while x < bufferlength do begin + by1:= resbuf[x]; + inc(x); + len:= isc_vax_integer(@ResBuf[x], 2); + inc(x,2); + case by1 of + isc_info_db_sql_dialect: begin + FDialect:= isc_vax_integer(@ResBuf[x], Len); + end; + isc_info_end: begin + Break; + end; + end; + inc(x,len); + end; +end; + +procedure TIBConnection.AllocSQLDA(var aSQLDA : PXSQLDA;Count : integer); +begin + FreeSQLDABuffer(aSQLDA); + + if count > -1 then + begin + reAllocMem(aSQLDA, XSQLDA_Length(Count)); + { Zero out the memory block to avoid problems with exceptions within the + constructor of this class. } + FillChar(aSQLDA^, XSQLDA_Length(Count), 0); + + aSQLDA^.Version := sqlda_version1; + aSQLDA^.SQLN := Count; + end + else + reAllocMem(aSQLDA,0); +end; + +procedure TIBConnection.TranslateFldType(SQLType,sqlsubtype,SQLLen, + SQLScale: integer; + out TrType: TFieldType; out TrLen: word); +begin + TrLen:= SQLLen; + if SQLScale < 0 then begin + TrLen:= -sqlscale; + if (sqlscale < -4) and (dbo_bcdtofloatif in controller.options) then begin + TrType:= ftfloat; + end + else begin + TrType:= ftBCD + end; + end + else begin + case (SQLType and not 1) of + SQL_VARYING: begin + if sqlsubtype and $ff = 1 then begin //octets + trtype:= ftvarbytes; + end + else begin + TrType:= ftString; + end; + end; + SQL_TEXT: begin + if sqlsubtype and $ff = 1 then begin //octets + trtype:= ftbytes; + end + else begin + TrType:= ftString; + end; + end; + SQL_TYPE_DATE: begin + TrType:= ftDate{Time}; + end; + SQL_TYPE_TIME: begin + TrType:= ftTime;//ftDateTime; + end; + SQL_TIMESTAMP: begin + TrType := ftDateTime; + end; + SQL_ARRAY: begin + TrType := ftArray; + end; + SQL_BLOB: begin + if sqlsubtype = isc_blob_text then begin + trtype:= ftmemo; + end + else begin + TrType:= ftBlob; + end; + end; + SQL_SHORT: begin + TrType:= ftsmallint; + end; + SQL_LONG: begin + TrType:= ftInteger; + end; + SQL_INT64: begin + TrType:= ftLargeInt; + end; + SQL_DOUBLE: begin + TrType:= ftFloat; + end; + SQL_FLOAT: begin + TrType:= ftFloat; + end + else begin + TrType := ftUnknown; + end; + end; + end; +end; + +Function TIBConnection.AllocateCursorHandle(const aowner: icursorclient; + const aname: ansistring): TSQLCursor; + +var curs : TIBCursor; + +begin + curs := TIBCursor.create(aowner,self); + curs.sqlda := nil; + curs.statement := nil; + curs.FPrepared := False; + AllocSQLDA(curs.SQLDA,0); + AllocSQLDA(curs.in_SQLDA,0); + result := curs; +end; + +procedure TIBConnection.DeAllocateCursorHandle(var cursor : TSQLCursor); + +begin + if assigned(cursor) then with cursor as TIBCursor do + begin + AllocSQLDA(SQLDA,-1); + AllocSQLDA(in_SQLDA,-1); + end; + FreeAndNil(cursor); +end; + +Function TIBConnection.AllocateTransactionHandle : TSQLHandle; + +begin + result := TIBTrans.create; +end; + +procedure tibconnection.preparestatement(const cursor: tsqlcursor; + const atransaction : tsqltransaction; + const asql: msestring; const aparams : tmseparams); + +var + dh: pointer; + tr: pointer; + x: integer; + TransLen: word; + TransType: TFieldType; + str1: string; + buf1: array[0..15] of byte; + int1: integer; + by1: byte; + +begin + with TIBcursor(cursor) do begin + ffetched:= false; + fempty:= true; + dh := GetHandle; + if isc_dsql_allocate_statement(@Status, @dh, @Statement) <> 0 then begin + CheckError('PrepareStatement', Status); + end; + tr := aTransaction.Handle; + if assigned(AParams) and (AParams.count > 0) then begin + str1:= todbstring(AParams.ParseSQL(asql,false,false,false,psInterbase, + paramBinding)); + end + else begin + str1:= todbstring(asql); + end; + if isc_dsql_prepare(@Status, @tr, @Statement, 0, @str1[1], + Dialect, nil) <> 0 then begin + isc_dsql_free_statement(@fstatus, @statement, dsql_drop); + CheckError('PrepareStatement', Status); + end; + by1:= isc_info_sql_stmt_type; + if isc_dsql_sql_info(@fstatus,@statement,sizeof(by1),@by1, + sizeof(buf1),@buf1[0]) <> 0 then begin + isc_dsql_free_statement(@fstatus, @statement, dsql_drop); + CheckError('PrepareStatement get info', Status); + end; + if buf1[0] = isc_info_sql_stmt_type then begin + int1:= isc_vax_integer(@buf1[1], 2); + fibstatementtype:= isc_vax_integer(@buf1[3],int1); + end; + FPrepared := True; + if assigned(AParams) and (AParams.count > 0) then begin + AllocSQLDA(in_SQLDA,Length(ParamBinding)); + if isc_dsql_describe_bind(@Status, @Statement, 1, in_SQLDA) <> 0 then begin + CheckError('PrepareStatement bind', Status); + end; + if in_SQLDA^.SQLD > in_SQLDA^.SQLN then begin + DatabaseError(SParameterCountIncorrect,self); + end; + setlength(paramtypes,in_SQLDA^.SQLD); + for x := 0 to in_SQLDA^.SQLD - 1 do begin + with in_SQLDA^.SQLVar[x] do begin + TranslateFldType(SQLType,sqlsubtype,SQLLen,SQLScale,TransType,TransLen); + paramtypes[x]:= transtype; + if ((SQLType and not 1) = SQL_VARYING) then begin + SQLData := AllocMem(in_SQLDA^.SQLVar[x].SQLLen+2) + end + else begin + SQLData := AllocMem(in_SQLDA^.SQLVar[x].SQLLen); + end; + sqltype:= sqltype or 1; //always use null flag + New(SQLInd); + end; + end; + end; + fexecsqlda:= nil; + if FStatementType in datareturningtypes then begin + if isc_dsql_describe(@Status, @Statement, 1, SQLDA) <> 0 then begin + CheckError('PrepareSelect', Status); + end; + if SQLDA^.SQLD > SQLDA^.SQLN then begin + AllocSQLDA(SQLDA,SQLDA^.SQLD); + if isc_dsql_describe(@Status, @Statement, 1, SQLDA) <> 0 then begin + CheckError('PrepareSelect', Status); + end; + end; + for x := 0 to SQLDA^.SQLD - 1 do with SQLDA^.SQLVar[x] do begin + if ((SQLType and not 1) = SQL_VARYING) then begin + SQLData := AllocMem(SQLDA^.SQLVar[x].SQLLen+2); + end + else begin + SQLData := AllocMem(SQLDA^.SQLVar[x].SQLLen); + end; + if (SQLType and 1) = 1 then begin //check not null constraint + New(SQLInd); + end; + end; + end; + if fibstatementtype = isc_info_sql_stmt_exec_procedure then begin + fexecsqlda:= sqlda; + end; + end; +end; + +procedure tibconnection.unpreparestatement(cursor: tsqlcursor); +begin + with tibcursor(cursor) do begin + if statement <> nil then begin + if isc_dsql_free_statement(@status, @statement, dsql_drop) <> 0 then begin + checkerror('freestatement', status); + end; + end; + statement:= nil; + fprepared:= false; + fopen:= false; + end; +end; + +procedure TIBConnection.FreeSQLDABuffer(var aSQLDA : PXSQLDA); + +var x : integer; + +begin + if assigned(aSQLDA) then + for x := 0 to aSQLDA^.SQLN - 1 do + begin + reAllocMem(aSQLDA^.SQLVar[x].SQLData,0); + if assigned(aSQLDA^.SQLVar[x].sqlind) then + begin + Dispose(aSQLDA^.SQLVar[x].sqlind); + aSQLDA^.SQLVar[x].sqlind := nil; + end + + end; +end; + +procedure TIBConnection.FreeFldBuffers(cursor : TSQLCursor); + +begin + with cursor as TIBCursor do + begin + FreeSQLDABuffer(SQLDA); + FreeSQLDABuffer(in_SQLDA); + end; +end; + +procedure TIBConnection.internalExecute(const cursor: TSQLCursor; + const atransaction: tsqltransaction; const AParams : TmseParams; + const autf8: boolean); +var + buf1: array[0..127] of byte; + by1: byte; + int1,int2: integer; + datasize: integer; + selectcount: integer; + updatecount: integer; + deletecount: integer; + insertcount: integer; +begin + if Assigned(APArams) and (AParams.count > 0) then begin + SetParameters(cursor, AParams); + end; + with TIBCursor(cursor) do begin + ffetched:= false; + if isc_dsql_execute2(@Status,@cursor.ftrans, + @Statement,1,in_SQLDA,fexecsqlda) <> 0 then begin + CheckError('Execute', Status); + end; + fopen:= true; + fempty:= sqlda^.sqld = 0; + if not fempty and (fexecsqlda = nil) then begin + fempty:= not fetch1(tibcursor(cursor)); //needed for rowsreturned? + end; + frowsaffected:= -1; + frowsreturned:= -1; + if ibo_sqlinfo in foptions then begin + by1:= isc_info_sql_records; + if isc_dsql_sql_info(@fstatus,@statement,sizeof(by1),@by1, + sizeof(buf1),@buf1[0]) <> 0 then begin + CheckError('Execute get records info', Status); + end; + if buf1[0] = isc_info_sql_records then begin + int2:= isc_vax_integer(@buf1[1],2)+3; //record size + if int2 <= sizeof(buf1) then begin + selectcount:= -1; + updatecount:= -1; + deletecount:= -1; + insertcount:= -1; + int1:= 3; + while true do begin + by1:= buf1[int1]; + if (by1 in [isc_info_end,isc_info_truncated]) or + (int1 >= int2-1) then begin + break; + end; + datasize:= isc_vax_integer(@buf1[int1+1],2); + inc(int1,3); + if int1 + datasize > int2 then begin + break; + end; + case by1 of + isc_info_req_select_count: begin + selectcount:= isc_vax_integer(@buf1[int1],datasize); + end; + isc_info_req_update_count: begin + updatecount:= isc_vax_integer(@buf1[int1],datasize); + end; + isc_info_req_delete_count: begin + deletecount:= isc_vax_integer(@buf1[int1],datasize); + end; + isc_info_req_insert_count: begin + insertcount:= isc_vax_integer(@buf1[int1],datasize); + end; + end; + inc(int1,datasize); + end; + if selectcount >= 0 then begin + frowsreturned:= selectcount; + end; + if updatecount > 0 then begin + frowsreturned:= 0; + frowsaffected:= updatecount; + end; + if deletecount > 0 then begin + frowsreturned:= 0; + frowsaffected:= deletecount; + end; + if insertcount > 0 then begin + frowsreturned:= 0; + frowsaffected:= insertcount; + end; + end; + end; + end; + end; +end; + +function sqlvarnametostring(const avalue: pointer): string; +type + sqlnamety = packed record + length: smallint; + name: array[0..31] of char; + end; +begin + with sqlnamety(avalue^) do begin + setlength(result,length); + move(name,result[1],length); + end; +end; + +function sqlsubtypetocharlen(const subtype: smallint; const len: integer): integer; +var + int1: integer; +begin + case subtype and $ff of +// 0,1,2,10,11,12,13,14,19,21,22,39, +// 45,46,47,50,51,52,53,54,55,58: begin +// int1:= 1; + 5,6,{8,}44,56,57{,64}: begin + int1:= 2; + end; + 3: begin + int1:= 3; + end; + 4,59: begin + int1:= 4; + end; + else begin + int1:= 1; + end; + end; + result:= (len) div int1; +end; + +procedure TIBConnection.AddFieldDefs(const cursor: TSQLCursor; + const FieldDefs: TfieldDefs); +var + x: integer; + TransLen: word; + TransType: TFieldType; + FD: TFieldDef; + ar1: fielddefarty; + int1: integer; +begin + ar1:= getfielddefar(fielddefs); + fielddefs.clear; + with tibcursor(cursor) do begin + for x := 0 to SQLDA^.SQLD - 1 do begin + with SQLDA^.SQLVar[x] do begin + TranslateFldType(SQLType,sqlsubtype,SQLLen,SQLScale,TransType,TransLen); + case transtype of + ftstring: begin + translen:= sqlsubtypetocharlen(sqlsubtype,translen); + end; + ftbcd: begin + if translen > 4 then begin + translen:= 4; + end; + end; + ftbytes: begin + if translen = 16 then begin + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + if (datatype = ftguid) and (name = aliasname) then begin + transtype:= ftguid; + end; + end; + end; + end; + end; + end; + if not(transtype in varsizefields) then begin + translen:= 0; + end; + FD:= TFieldDef.Create(nil,AliasName,TransType, + TransLen,False,(x + 1)); + if TransType = ftBCD then begin + case sqllen of + 2: fd.precision:= 4; + 4: fd.precision:= 9; + 8: fd.precision:= 18; + else begin + FD.precision:= SQLLen; + end; + end; + end; +// FD.DisplayName:= AliasName; + fd.collection:= fielddefs; + end; + end; + end; +end; + +function TIBConnection.GetHandle: pointer; +begin + Result := FSQLDatabaseHandle; +end; + +function tibconnection.fetch1(const cursor: tibcursor): boolean; +var + retcode: integer; +begin + with cursor do begin + retcode:= isc_dsql_fetch(@Status,@Statement,1,SQLDA); + if (retcode <> 0) and (retcode <> 100) and (retcode <> 335544364) then begin + //request synchronizing error, FireBird bug? + CheckError('Fetch',Status); + end; + end; + Result:= retcode = 0; +end; + +function TIBConnection.Fetch(cursor : TSQLCursor) : boolean; +begin + with TIBCursor(cursor) do begin + result:= not fempty; + if result then begin + if fibstatementtype = isc_info_sql_stmt_exec_procedure then begin + result:= not ffetched; + end + else begin + result:= not ffetched or fetch1(tibcursor(cursor)); + end; + ffetched:= true; + end; + end; +end; + +procedure TIBConnection.SetParameters(cursor: TSQLCursor; AParams: TmseParams); + //todo: remove not needed move operations +var + ParNr,SQLVarNr: integer; + s,str1: string; + i: integer; + li: LargeInt; + currbuff: pchar; + w: word; + cur1: currency; + id1: tguid; + po1: pxsqlvar; + bo1: boolean; + +begin + with tibcursor(cursor) do begin + for SQLVarNr := 0 to High(ParamBinding) do begin + ParNr:= ParamBinding[SQLVarNr]; + po1:= @in_sqlda^.SQLvar[SQLVarNr]; + with AParams[ParNr] do begin + if IsNull then begin + If Assigned(po1^.SQLInd) then begin + po1^.SQLInd^ := -1; + end; + end + else begin + if assigned(po1^.SQLInd) then begin + po1^.SQLInd^ := 0; + end; + case paramtypes[sqlvarnr] of + ftunknown: begin + //null flag only + end; + ftInteger,ftsmallint : begin + if datatype = ftboolean then begin + i:= 0; + if asboolean then begin + i:= 1; + end; + end + else begin + i:= AsInteger; + end; + Move(i, po1^.SQLData^,po1^.SQLLen); + //todo: byte order? + end; + ftbcd: begin + cur1:= ascurrency; + with po1^ do begin + cur1:= scaleexp10(cur1,-(4+sqlscale)); + move(cur1,sqldata^,po1^.sqllen); + end; + end; + ftString,ftFixedChar,ftwidestring,ftbytes,ftvarbytes: begin + if (datatype = ftguid) and (paramtypes[sqlvarnr] = ftbytes) and + (po1^.sqllen = sizeof(tguid)) then begin + with po1^ do begin + id1:= dbstringtoguid(asstring); + move(id1,sqldata^,po1^.sqllen); + end; + end + else begin + bo1:= paramtypes[sqlvarnr] in [ftbytes,ftvarbytes]; + if bo1 then begin + s:= asstring; + end + else begin + s:= aparams.AsdbString(parnr); + end; + w:= length(s); + with po1^ do begin + if ((SQLType and not 1) = SQL_VARYING) then begin + SQLLen:= w; + ReAllocMem(SQLData,SQLLen+sizeof(w)); + CurrBuff:= SQLData; + move(w,CurrBuff^,sizeof(w)); + inc(CurrBuff,sizeof(w)); + end + else begin + if w > sqllen then begin + w:= sqllen; + end; + CurrBuff:= SQLData; + if w < sqllen then begin + if bo1 then begin + fillchar((currbuff+w)^,sqllen-w,0); + end + else begin + fillchar((currbuff+w)^,sqllen-w,' '); + end; + end; + end; + end; + Move(pointer(s)^,CurrBuff^,w); + end; + end; + ftDate, ftTime, ftDateTime: begin + SetDateTime(po1^.SQLData,AsDateTime, po1^.SQLType); + end; + ftLargeInt: begin + li := AsLargeInt; + Move(li, po1^.SQLData^,po1^.SQLLen); + end; + ftblob,ftmemo: begin + if datatype in [ftblob,ftString,ftFixedChar,ftwidestring, + ftbytes,ftvarbytes] then begin + if paramtypes[sqlvarnr] = ftmemo then begin + s:= aparams.asdbstring(parnr); + end + else begin + s:= asstring; + end; + writeblobdata(cursor.ftrans,'',nil,pointer(s),length(s),nil,nil,str1); + move(str1[1],li,sizeof(li)); //blobid + end + else begin + li := AsLargeInt; + end; + Move(li, po1^.SQLData^,po1^.SQLLen); + end; + ftFloat,ftcurrency: begin + with po1^ do begin + if sqlscale < 0 then begin + {$ifdef FPC} + {$ifdef CPUARM} + int64(ar8ty(cur1)):= round(asfloat * intexp10(-SQLScale)); + {$else} + int64(ar8ty(cur1)):= round(asfloat * intexp10(-SQLScale)); + {$endif} + {$else} + int64(ar8ty(cur1)):= round(asfloat * intexp10(-SQLScale)); + {$endif} + move(cur1,sqldata^,po1^.sqllen); + end + else begin + SetFloat(po1^.SQLData,AsFloat,po1^.SQLLen); + end; + end; + end; + else begin + DatabaseErrorFmt(SUnsupportedParameter, + [Fieldtypenames[AParams[ParNr].DataType]],self); + end; + end; {case} + end; + end; + end; + end; +end; + +function tibconnection.loadfield(const cursor: tsqlcursor; + const datatype: tfieldtype; const fieldnum: integer; //null based + const buffer: pointer; var bufsize: integer; + const aisutf8: boolean): boolean; + //if bufsize < 0 -> buffer was to small, should be -bufsize +var + VarcharLen: word; + CurrBuff: pchar; + po1: pxsqlvar; + + function getint64: int64; + begin + case po1^.sqllen of + 2: begin + int64(result):= psmallint(currbuff)^; //sign extend + end; + 4: begin + int64(result):= pinteger(currbuff)^; //sign extend + end; + else begin + result:= pint64(currbuff)^; + end; + end; + end; + +begin + po1:= @TIBCursor(cursor).SQLDA^.SQLVar[fieldnum]; + with TIBCursor(cursor),po1^ do begin + if assigned(SQLInd) and (SQLInd^ = -1) then begin + result:= false + end + else begin + Result := true; + if buffer = nil then begin + exit; + end; + if ((SQLType and not 1) = SQL_VARYING) then begin + Move(SQLData^,VarcharLen,2); + CurrBuff:= SQLData + 2; + end + else begin + CurrBuff:= SQLData; + VarCharLen:= SQLLen; + end; + case DataType of + ftBCD: begin + pint64(buffer)^:= scaleexp10(getint64,4+SQLScale); + end; + ftInteger,ftsmallint: begin + if datatype = ftsmallint then begin + pinteger(buffer)^:= psmallint(currbuff)^; + end + else begin + pinteger(buffer)^:= pinteger(currbuff)^; + end; + end; + ftLargeint: begin + pint64(buffer)^:= pint64(currbuff)^; + end; + ftDate,ftTime,ftDateTime: begin + GetDateTime(CurrBuff,Buffer,SQLType); + end; + ftguid: begin + pguid(buffer)^:= pguid(currbuff)^; + end; + ftString,ftBytes,ftvarbytes: begin + if datatype = ftvarbytes then begin + currbuff:= currbuff - sizeof(word); + varcharlen:= varcharlen + sizeof(word); + end; + if bufsize < varcharlen then begin + bufsize:= -varcharlen; + end + else begin + bufsize:= varcharlen; + move(currbuff^,buffer^,varcharlen); + end; + end; + ftFloat,ftcurrency: begin + if sqlscale < 0 then begin //numeric/decimal + pdouble(buffer)^:= getint64 / intexp10(-SQLScale); + end + else begin + GetFloat(CurrBuff,Buffer,sqllen); + end; + end; + ftBlob,ftmemo,ftgraphic: begin // load the BlobIb in field's buffer + pint64(buffer)^:= getint64; + if wantblobfetch then begin + addblobcache(pint64(buffer)^,getblobstring(cursor,pisc_quad(buffer)^)); + end; + end; + else begin + result := false; + end; + end; + end; + end; +end; + +procedure TIBConnection.GetDateTime(CurrBuff, Buffer : pointer; AType : integer); +var + CTime : TTm; // C struct time + STime : TSystemTime; // System time +begin + case (AType and not 1) of + SQL_TYPE_DATE : + isc_decode_sql_date(PISC_DATE(CurrBuff), @CTime); + SQL_TYPE_TIME : + isc_decode_sql_time(PISC_TIME(CurrBuff), @CTime); + SQL_TIMESTAMP : + isc_decode_timestamp(PISC_TIMESTAMP(CurrBuff), @CTime); + end; + +{$ifdef FPC} +{$warnings off} + STime.Year := CTime.tm_year + 1900; + STime.Month := CTime.tm_mon + 1; + STime.Day := CTime.tm_mday; + STime.Hour := CTime.tm_hour; + STime.Minute := CTime.tm_min; + STime.Second := CTime.tm_sec; + STime.Millisecond := 0; +{$else} + STime.wYear := CTime.tm_year + 1900; + STime.wMonth := CTime.tm_mon + 1; + STime.wDay := CTime.tm_mday; + STime.wHour := CTime.tm_hour; + STime.wMinute := CTime.tm_min; + STime.wSecond := CTime.tm_sec; + STime.wMilliseconds := 0; +{$endif} + pdatetime(buffer)^:= SystemTimeToDateTime(STime); +end; +{$warnings on} + +procedure TIBConnection.SetDateTime(CurrBuff: pointer; PTime : TDateTime; AType : integer); +var + CTime : TTm; // C struct time + STime : TSystemTime; // System time +begin + DateTimeToSystemTime(PTime,STime); + +{$ifdef FPC} + CTime.tm_year := STime.Year - 1900; + CTime.tm_mon := STime.Month -1; + CTime.tm_mday := STime.Day; + CTime.tm_hour := STime.Hour; + CTime.tm_min := STime.Minute; + CTime.tm_sec := STime.Second; +{$else} + CTime.tm_year := STime.wYear - 1900; + CTime.tm_mon := STime.wMonth -1; + CTime.tm_mday := STime.wDay; + CTime.tm_hour := STime.wHour; + CTime.tm_min := STime.wMinute; + CTime.tm_sec := STime.wSecond; +{$endif} + case (AType and not 1) of + SQL_TYPE_DATE : + isc_encode_sql_date(@CTime, PISC_DATE(CurrBuff)); + SQL_TYPE_TIME : + isc_encode_sql_time(@CTime, PISC_TIME(CurrBuff)); + SQL_TIMESTAMP : + isc_encode_timestamp(@CTime, PISC_TIMESTAMP(CurrBuff)); + end; +end; + +function TIBConnection.GetSchemaInfoSQL(SchemaType : TSchemaType; + SchemaObjectName, SchemaPattern : msestring) : msestring; + +begin + result:= fbgetschemainfosql(self,schematype,schemaobjectname,schemapattern); +end; + +procedure tibconnection.updateindexdefs(var indexdefs : tindexdefs; + const atablename : string; const acursor: tsqlcursor); +begin + fbupdateindexdefs(self,indexdefs,atablename); +end; + +procedure TIBConnection.SetFloat(CurrBuff: pointer; Dbl: Double; Size: integer); + +begin + case Size of + 4: begin + psingle(currbuff)^:= Dbl; + end; + 8: begin + pdouble(currbuff)^:= Dbl; + end; + 10: begin + pextended(currbuff)^:= Dbl; + end; + end; +end; + +procedure tibconnection.GetFloat(const CurrBuff,Buffer: pointer; + const datalength: integer); +begin + case datalength of + 4: begin + pdouble(buffer)^:= psingle(currbuff)^; + end; + 8: begin + pdouble(buffer)^:= pdouble(currbuff)^; + end; + 10: begin + pdouble(buffer)^:= pextended(currbuff)^; + end; + end; +end; + + +function TIBConnection.getMaxBlobSize(blobHandle : TIsc_Blob_Handle) : longInt; +var + iscInfoBlobMaxSegment : byte; + blobInfo : array[0..50] of byte; + +begin + result:= 0; + iscInfoBlobMaxSegment:= isc_info_blob_max_segment; + if isc_blob_info(@Fstatus, @blobHandle, sizeof(iscInfoBlobMaxSegment), + @iscInfoBlobMaxSegment, sizeof(blobInfo) - 2, @blobInfo) <> 0 then + CheckError('isc_blob_info', FStatus); + if blobInfo[0] = isc_info_blob_max_segment then + begin + result := isc_vax_integer(pchar(@blobInfo[3]), + isc_vax_integer(pchar(@blobInfo[1]), 2)); + end + else + CheckError('isc_blob_info', FStatus); +end; + +function tibconnection.getblobstream(const acursor: tsqlcursor; + const blobid: isc_quad; const forstring: boolean = false): tmemorystream; +const + isc_segstr_eof = 335544367; +var + blobHandle : Isc_blob_Handle; + blobSegment : pointer; + blobSegLen : word; + maxBlobSize : longInt; +begin + blobseglen:= 0; + blobHandle:= FB_API_NULLHANDLE; + if isc_open_blob(@FStatus, @FSQLDatabaseHandle, @acursor.ftrans, + @blobHandle, @blobId) <> 0 then begin + CheckError('TIBConnection.CreateBlobStream', FStatus); + end; + maxBlobSize:= getMaxBlobSize(blobHandle); + blobSegment:= AllocMem(maxBlobSize); + if forstring then begin + result:= tmemorystringstream.create; + end + else begin + result:= tmemorystream.create; + end; + while isc_get_segment(@FStatus,@blobHandle,@blobSegLen,maxBlobSize, + blobSegment) = 0 do begin + result.writeBuffer(blobSegment^,blobSegLen); + end; + freemem(blobSegment); + result.seek(0,soFromBeginning); + if FStatus[1] = isc_segstr_eof then begin + if isc_close_blob(@FStatus, @blobHandle) <> 0 then begin + CheckError('TIBConnection.CreateBlobStream isc_close_blob', FStatus); + end; + end + else begin + CheckError('TIBConnection.CreateBlobStream isc_get_segment', FStatus); + end; +end; + +function tibconnection.getblobstring(const acursor: tsqlcursor; + const blobid: isc_quad): string; +begin + tmemorystringstream(getblobstream(acursor,blobid,true)).destroyasstring(result); +end; + +function TIBConnection.fetchblob(const cursor: tsqlcursor; + const fieldnum: integer): ansistring; +var + blobId : ISC_QUAD; + int1: integer; +begin + int1:= sizeof(blobid); + if not loadfield(cursor,ftblob,fieldnum,@blobid,int1,false) then begin + result:= ''; + end + else begin + result:= getblobstring(cursor,blobid); + end; +end; + +function TIBConnection.CreateBlobStream(const Field: TField; + const Mode: TBlobStreamMode; const acursor: tsqlcursor): TStream; +var + blobId : ISC_QUAD; +begin + result := nil; + if mode = bmRead then begin + if not field.getData(@blobId) then begin + exit; + end; + result:= getblobstream(acursor,blobid); + end; +end; + + +procedure TIBConnection.writeblobdata(const atransactionhandle: pointer; + const tablename: string; const acursor: tsqlcursor; + const adata: pointer; const alength: integer; + const afield: tfield; const aparam: tparam; out newid: string); + + procedure check(const ares: isc_status); + begin + if ares <> 0 then begin + CheckError('TIBConnection.writeblob', FStatus); + end; + end; +const + defsegsize = $ffff; +var +// transactionhandle: pointer; + blobhandle: isc_blob_handle; + blobid: isc_quad; + step: word; + po1: pointer; + int1: integer; +begin +// transactionhandle:= atransaction.handle; + blobhandle:= FB_API_NULLHANDLE; + fillchar(blobid,sizeof(blobid),0); + check(isc_create_blob2(@fstatus,@fsqldatabasehandle,@atransactionhandle, + @blobhandle,@blobid,0,nil)); + try + int1:= getmaxblobsize(blobhandle); + if (int1 <= 0) or (int1 > defsegsize) then begin + step:= defsegsize; + end + else begin + step:= int1; + end; + po1:= adata; + int1:= alength; + while int1 > 0 do begin + if int1 < step then begin + step:= int1; + end; + check(isc_put_segment(@fstatus,@blobhandle,step,po1)); + dec(int1,step); + inc(pchar(po1),step); + end; + if aparam = nil then begin + setlength(newid,sizeof(blobid)); + move(blobid,newid[1],sizeof(blobid)); + end + else begin + aparam.aslargeint:= int64(blobid); + newid:= ''; //id no more usable + end; + finally + isc_close_blob(@fstatus,@blobhandle); + end; +end; + +procedure TIBConnection.writeblobdata(const atransaction: tsqltransaction; + const tablename: string; const acursor: tsqlcursor; + const adata: pointer; const alength: integer; + const afield: tfield; const aparam: tparam; out newid: string); +begin + writeblobdata(atransaction.handle,tablename,acursor,adata,alength, + afield,aparam,newid); +end; + +procedure tibconnection.setupblobdata(const afield: tfield; + const acursor: tsqlcursor; const aparam: tparam); +var + blobid: isc_quad; +begin +{ + if afield.isnull then begin + aparam.clear; + end + else begin + } + afield.getdata(@blobid); + aparam.aslargeint:= int64(blobid); +// end; +end; + +function TIBConnection.getblobdatasize: integer; +begin + result:= sizeof(isc_quad); +end; + +procedure TIBConnection.createdatabase(const asql: ansistring); +var + dbha: isc_db_handle; + trha: isc_tr_handle; + bo1: boolean; +begin + dbha:= FB_API_NULLHANDLE; + trha:= FB_API_NULLHANDLE; +{$ifdef linkdynamically} + useembeddedfirebird:= ibo_embedded in foptions; + initializeibase60([]); + try +{$endif} + bo1:= isc_dsql_execute_immediate(@fstatus,@dbha,@trha,length(asql), + pchar(asql),fdialect,nil) <> 0; + if bo1 then begin + checkerror('createdatabase',fstatus); + end + else begin + if dbha <> FB_API_NULLHANDLE then begin + isc_detach_database(@FStatus,@dbha); + end; + end; +{$ifdef linkdynamically} + finally + releaseibase60; + end; +{$endif} +end; +{ +function TIBConnection.blobscached: boolean; +begin + result:= false; +end; +} +procedure TIBConnection.listen(const sender: tdbevent); +begin + feventcontroller.register(sender); + if connected then begin + dolisten(sender); + end; +end; + +procedure TIBConnection.unlisten(const sender: tdbevent); +begin + if connected then begin + dounlisten(sender); + end; + feventcontroller.unregister(sender); +end; + +procedure TIBConnection.fire(const sender: tdbevent); +begin + databaseerror('Event fire not implemented.',self); +end; + +procedure eventcallback(adata: pointer; alength: smallint; aupdated: pchar); + cdecl; +//var +// status: statusvectorty; +begin + with pfbeventbufferty(adata)^,tibconnection(event.database) do begin + sys_mutexlock(fmutex); + inc(count); + inc(feventcount); + move(aupdated^,resultbuffer^,alength); + feventcontroller.eventinterval:= -1; //restart timer + sys_mutexunlock(fmutex); + end; +end; + +function TIBConnection.getdbevent(var aname: string; var aid: int64): boolean; +var + int1: integer; + status: statusvectorty; +begin + result:= false; + if feventcount > 0 then begin + sys_mutexlock(fmutex); + dec(feventcount); + for int1:= 0 to high(feventbuffers) do begin + if feventbuffers[int1] <> nil then begin + with feventbuffers[int1]^ do begin + if count <> 0 then begin + isc_event_counts(@status,length,eventbuffer,resultbuffer); + isc_que_events(@status,@fsqldatabasehandle,@id,length, + eventbuffer,isc_callback(@eventcallback),feventbuffers[int1]); + if count < 0 then begin //first dummy + count:= 0; + end + else begin + dec(count); + aname:= event.eventname; + aid:= id; + result:= true; + end; + break; + end; + end; + end; + end; + sys_mutexunlock(fmutex); + end; +end; + +procedure TIBConnection.dolisten(const sender: tdbevent); +var + int1,int2: integer; +begin + int2:= -1; + for int1:= 0 to high(feventbuffers) do begin + if feventbuffers[int1] = nil then begin + int2:= int1; + break; + end; + end; + if int2 < 0 then begin + int2:= length(feventbuffers); + setlength(feventbuffers,high(feventbuffers)+17); + end; + getmem(feventbuffers[int2],sizeof(fbeventbufferty)); + fillchar(feventbuffers[int2]^,sizeof(fbeventbufferty),0); + with feventbuffers[int2]^ do begin + count:= -2; //remove dummy call + event:= sender; + name:= sender.eventname; + length:= isc_event_block(@eventbuffer,@resultbuffer,1,[pchar(name)]); + checkerror('dolisten',isc_que_events(@fstatus,@fsqldatabasehandle,@id,length, + eventbuffer,isc_callback(@eventcallback),feventbuffers[int2])); + end; +end; + +procedure TIBConnection.dounlisten(const sender: tdbevent); +var + int1: integer; +begin + for int1:= 0 to high(feventbuffers) do begin + if (feventbuffers[int1] <> nil) and + (feventbuffers[int1]^.event = sender) then begin + sys_mutexlock(fmutex); //not save! there can be an event in queue + isc_cancel_events(@fstatus,@fsqldatabasehandle,@feventbuffers[int1]^.id); + freeeventbuffer(feventbuffers[int1]); + sys_mutexunlock(fmutex); + break; + end; + end; +end; + +procedure TIBConnection.freeeventbuffer(var abuffer: pfbeventbufferty); +begin + with abuffer^ do begin + isc_free(eventbuffer); + isc_free(resultbuffer); + end; + finalize(abuffer^); + freemem(abuffer); + abuffer:= nil; +end; + +procedure versioncallback(user_arg: pointer; atext: pchar); +// {$ifdef mswindows}stdcall{$else}cdecl{$endif}; + {$ifdef mswindows}cdecl{$else}cdecl{$endif}; +begin + setlength(stringarty(user_arg^),high(stringarty(user_arg^))+2); + stringarty(user_arg^)[high(stringarty(user_arg^))]:= atext; +end; + +function TIBConnection.version: fbversionty; +var + ar1: stringarty; + int1: integer; +begin + checkconnected; + ar1:= nil; + if isc_version(@fsqldatabasehandle,@versioncallback, + @ar1) <> 0 then begin + raise edatabaseerror(name+': Can not get version info.'); + end; + with result do begin + imp:= nil; + ods:= ''; + if high(ar1) > 0 then begin + setlength(imp,high(ar1)); + for int1:= 0 to high(imp) do begin + imp[int1]:= ar1[int1]; + end; + ods:= ar1[high(ar1)]; + end; + end; +end; + +{ eiberror } + +constructor eiberror.create(const asender: tibconnection; + const amessage: msestring; + const aerror: statusvectorty; const asqlcode: integer); +begin + fstatus:= aerror; + fsqlcode:= asqlcode; + inherited create(asender,ansistring(amessage),amessage,aerror[1]); +end; + +end. \ No newline at end of file diff --git a/mseide-msegui/lib/common/db/mmysql40conn.pas b/mseide-msegui/lib/common/db/mmysql40conn.pas new file mode 100644 index 0000000..307087d --- /dev/null +++ b/mseide-msegui/lib/common/db/mmysql40conn.pas @@ -0,0 +1,26 @@ +{ + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +{ + Contains the TMysqlConnection for MySQL 4.0 +} + +unit mmysql40conn; + +{$UNDEF MYSQL41} + +{$i mmysqlconn.inc} + +end. diff --git a/mseide-msegui/lib/common/db/mmysql41conn.pas b/mseide-msegui/lib/common/db/mmysql41conn.pas new file mode 100644 index 0000000..3ab3b09 --- /dev/null +++ b/mseide-msegui/lib/common/db/mmysql41conn.pas @@ -0,0 +1,26 @@ +{ + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +{ + Contains the TMysqlConnection for MySQL 4.1 +} + +unit mmysql41conn; + +{$DEFINE MYSQL41} + +{$i mmysqlconn.inc} + +end. diff --git a/mseide-msegui/lib/common/db/mmysql4conn.pas b/mseide-msegui/lib/common/db/mmysql4conn.pas new file mode 100644 index 0000000..1d610b7 --- /dev/null +++ b/mseide-msegui/lib/common/db/mmysql4conn.pas @@ -0,0 +1,28 @@ +{ + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +{ + Contains the TMysqlConnection for MySQL 4.0 + + temporary backwards compatibility for Lazarus +} + +unit mmysql4conn; + +{$DEFINE MYSQL4} + +{$i mmysqlconn.inc} + +end. diff --git a/mseide-msegui/lib/common/db/mmysql50conn.pas b/mseide-msegui/lib/common/db/mmysql50conn.pas new file mode 100644 index 0000000..b6d2a00 --- /dev/null +++ b/mseide-msegui/lib/common/db/mmysql50conn.pas @@ -0,0 +1,27 @@ +{ + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +{ + Contains the TMysqlConnection for MySQL 5.0 +} + +unit mmysql50conn; + +{$DEFINE MYSQL50} +{$DEFINE MYSQL41} + +{$i mmysqlconn.inc} + +end. diff --git a/mseide-msegui/lib/common/db/mmysqlconn.inc b/mseide-msegui/lib/common/db/mmysqlconn.inc new file mode 100644 index 0000000..5a8fd86 --- /dev/null +++ b/mseide-msegui/lib/common/db/mmysqlconn.inc @@ -0,0 +1,1136 @@ +{ + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +{Modified 2006-2010 by Martin Schreiber} + +{$ifdef VER2_1_5} {$define mse_FPC_2_2} {$endif} +{$ifdef VER2_2} {$define mse_FPC_2_2} {$endif} +{$ifdef VER2_3} {$define mse_FPC_2_2} {$endif} +{$ifdef VER2_4} {$define mse_FPC_2_2} {$endif} +{$ifdef VER2_5} {$define mse_FPC_2_2} {$endif} +{$if FPC_FULLVERSION >= 20300} {$define mse_FPC_2_2} {$endif} + +{$mode objfpc}{$H+} +{$MACRO on} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,SysUtils,msqldb,mdb,dynlibs,msetypes{msestrings},msedb, +{$IfDef mysql50} + mysql50dyn; + {$DEFINE TConnectionName:=TMySQL50Connection} + {$DEFINE TTransactionName:=TMySQL50Transaction} + {$DEFINE TCursorName:=TMySQL50Cursor} + {$define eerrorname:= emysql50error} +{$ELSE} + {$IfDef mysql41} + mysql41dyn; + {$DEFINE TConnectionName:=TMySQL41Connection} + {$DEFINE TTransactionName:=TMySQL41Transaction} + {$DEFINE TCursorName:=TMySQL41Cursor} + {$define eerrorname:= emysql41error} + {$ELSE} + {$IFDEF mysql4} // temporary backwards compatibility for Lazarus + mysql40dyn; + {$DEFINE TConnectionName:=TMySQLConnection} + {$DEFINE TTransactionName:=TMySQLTransaction} + {$DEFINE TCursorName:=TMySQLCursor} + {$define eerrorname:= emysqlerror} + {$ELSE} + mysql40dyn; + {$DEFINE TConnectionName:=TMySQL40Connection} + {$DEFINE TTransactionName:=TMySQL40Transaction} + {$DEFINE TCursorName:=TMySQL40Cursor} + {$define eerrorname:= emysql40error} + {$EndIf} + {$EndIf} +{$EndIf} + +Type + + tcursorname = class; + + eerrorname = class(econnectionerror) + private + fsqlcode: string; + public + constructor create(const asender: tcustomsqlconnection; const amessage: ansistring; + const aerrormessage: msestring; const aerror: integer; const asqlcode: string); + property sqlcode: string read fsqlcode; + end; + + TTransactionName = Class(TSQLHandle) + protected + end; + + TCursorName = Class(TSQLCursor) + protected +// FQMySQL : PMySQL; + FRes: PMYSQL_RES; { Record pointer } + FNeedData : Boolean; + fstatementm: msestring; + Row : MYSQL_ROW; +// RowsAffected : QWord; + LastInsertID : QWord; + ParamBinding : TParamBinding; + ParamReplaceString : mseString; + MapDSRowToMSQLRow : array of integer; + fprimarykeyfieldname: string; + end; + + TConnectionName = class (TSQLConnection,iblobconnection) + private + FDialect: integer; + FHostInfo: String; + FServerInfo: String; + FMySQL : PMySQL; +{$if fpc_fullversion >= 20401} +{$else} + FDidConnect : Boolean; +{$endif} + fport: longword; + flasterror: integer; + flasterrormessage: msestring; + flastsqlcode: string; + function GetClientInfo: string; + function GetServerStatus: String; + procedure ConnectMySQL(var HMySQL : PMySQL;H,U,P : pchar); + procedure freeresultbuffer(const cursor: tcursorname); + protected + Procedure checkerror(const Msg: String); + +// function stringtosqltext(const afeildtype: tfieldtype; const avalue: string): string; + function StrToStatementType(s : msestring) : TStatementType; override; + Procedure ConnectToServer; virtual; + Procedure SelectDatabase; virtual; +// function MySQLDataType(AType: enum_field_types; ASize, ADecimals: Integer; var NewType: TFieldType; var NewSize: Integer): Boolean; + function MySQLDataType(const afield: mysql_field; var NewType: TFieldType; var NewSize: Integer): Boolean; + function MySQLWriteData(const acursor: tsqlcursor; AType: enum_field_types; + ASize: Integer; + AFieldType: TFieldType;Source, Dest: PChar): Boolean; + // SQLConnection methods + procedure DoInternalConnect; override; + procedure DoInternalDisconnect; override; + function GetHandle : pointer; override; + +// function GetAsSQLText(Field : TField) : string; overload; override; +// function GetAsSQLText(Param : TParam) : string; overload; override; + + + procedure internalExecute(const cursor: TSQLCursor; + const atransaction:tSQLtransaction; const AParams : TmseParams; + const autf8: boolean); override; + function GetTransactionHandle(trans : TSQLHandle): pointer; override; + function Commit(trans : TSQLHandle) : boolean; override; + function RollBack(trans : TSQLHandle) : boolean; override; + function StartdbTransaction(const trans : TSQLHandle; + const AParams: tstringlist) : boolean; override; + procedure internalCommitRetaining(trans : TSQLHandle); override; + procedure internalRollBackRetaining(trans : TSQLHandle); override; + procedure UpdateIndexDefs(var IndexDefs : TIndexDefs; + const aTableName : string; const acursor: tsqlcursor); override; + + function getprimarykeyfield(const atablename: string; + const acursor: tsqlcursor): string; override; + procedure updateprimarykeyfield(const afield: tfield; + const atransaction: tsqltransaction); override; + function CreateBlobStream(const Field: TField; const Mode: TBlobStreamMode; + const acursor: tsqlcursor): TStream; override; + function getblobdatasize: integer; override; +// function getfeatures(): databasefeaturesty override; + //iblobconnection + procedure writeblobdata(const atransaction: tsqltransaction; + const tablename: string; const acursor: tsqlcursor; + const adata: pointer; const alength: integer; + const afield: tfield; const aparam: tparam; + out newid: string); + procedure setupblobdata(const afield: tfield; const acursor: tsqlcursor; + const aparam: tparam); +// function blobscached: boolean; + function identquotechar: msestring; override; + + Public + constructor create(aowner: tcomponent); override; + Function AllocateTransactionHandle : TSQLHandle; override; + Function AllocateCursorHandle(const aowner: icursorclient; + const aname: ansistring): TSQLCursor; override; + Procedure DeAllocateCursorHandle(var cursor : TSQLCursor); override; + procedure preparestatement(const cursor: tsqlcursor; + const atransaction : tsqltransaction; + const asql: msestring; const aparams : tmseparams); override; + procedure UnPrepareStatement(cursor:TSQLCursor); override; + procedure FreeFldBuffers(cursor : TSQLCursor); override; + procedure AddFieldDefs(const cursor: TSQLCursor; + const FieldDefs : TfieldDefs); override; + function Fetch(cursor : TSQLCursor) : boolean; override; + function loadfield(const cursor: tsqlcursor; + const datatype: tfieldtype; const fieldnum: integer; //null based + const buffer: pointer; var bufsize: integer; + const aisutf8: boolean): boolean; override; + //if bufsize < 0 -> buffer was to small, should be -bufsize + function fetchblob(const cursor: tsqlcursor; + const fieldnum: integer): ansistring; override; + //null based + function getinsertid(const atransaction: tsqltransaction): int64; override; + Property ServerInfo : String Read FServerInfo; + Property HostInfo : String Read FHostInfo; + property ClientInfo: string read GetClientInfo; + property ServerStatus : String read GetServerStatus; + property lasterror: integer read flasterror; + property lasterrormessage: msestring read flasterrormessage; + property lastsqlcode: string read flastsqlcode; + published + property Dialect : integer read FDialect write FDialect default 0; + property port: longword read fport write fport default 0; + property DatabaseName; + property HostName; + property KeepConnection; +// property LoginPrompt; + property Params; +// property OnLogin; + end; + +// EMySQLError = Class(Exception); + +implementation +uses + msestrings,dbconst,msebufdataset,msesqlresult; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tmsebufdataset1 = class(tmsebufdataset); + +{ TConnectionName } + +Resourcestring + SErrServerConnectFailed = 'Server connect failed.'; + SErrDatabaseSelectFailed = 'failed to select database: %s'; + SErrDatabaseCreate = 'Failed to create database: %s'; + SErrDatabaseDrop = 'Failed to drop database: %s'; + SErrNoData = 'No data for record'; + SErrExecuting = 'Error executing query: %s'; + SErrFetchingdata = 'Error fetching row data: %s'; + SErrGettingResult = 'Error getting result set: %s'; + SErrNoQueryResult = 'No result from query.'; + SErrNotversion50 = 'TMySQL50Connection can not work with the installed MySQL client version (%s).'; + SErrNotversion41 = 'TMySQL41Connection can not work with the installed MySQL client version (%s).'; + SErrNotversion40 = 'TMySQL40Connection can not work with the installed MySQL client version (%s).'; + +constructor TConnectionName.create(aowner: tcomponent); +begin + inherited; + fconnoptions:= fconnoptions + [sco_supportparams,sco_emulateretaining, + sco_blobscached]; +end; + +Procedure tconnectionname.checkerror(const Msg: String); +var + str1: msestring; +begin + str1:= connectionmessage(mysql_error(fmysql)); + flasterrormessage:= str1; + flasterror:= mysql_errno(fmysql); + flastsqlcode:= strpas(mysql_sqlstate(fmysql)); + raise eerrorname.create(self,format(msg,[str1]),flasterrormessage, + flasterror,flastsqlcode); +end; + +function TConnectionName.StrToStatementType(s : msestring) : TStatementType; + +begin + S:=Lowercase(s); + if s = 'show' then exit(stSelect); + result := inherited StrToStatementType(s); +end; + + +function TConnectionName.GetClientInfo: string; + +{$if fpc_fullversion < 20401} +Var + B : Boolean; +{$endif} + +begin +{$if fpc_fullversion >= 20401} + // To make it possible to call this if there's no connection yet + InitialiseMysql; + Try + Result:=strpas(mysql_get_client_info()); + Finally + ReleaseMysql; + end; +{$else} + // To make it possible to call this if there's no connection yet + B:=(MysqlLibraryHandle=Nilhandle); + If B then + InitialiseMysql; + Try + Result:=strpas(mysql_get_client_info()); + Finally + if B then + ReleaseMysql; + end; +{$endif} +end; + +function TConnectionName.GetServerStatus: String; +begin + CheckConnected; + Result := mysql_stat(FMYSQL); +end; + +procedure TConnectionName.ConnectMySQL(var HMySQL : PMySQL;H,U,P : pchar); + +begin + HMySQL := mysql_init(HMySQL); + HMySQL:=mysql_real_connect(HMySQL,PChar(H),PChar(U),Pchar(P),Nil,fport,Nil,0); + If (HMySQL=Nil) then + databaseerror(SErrServerConnectFailed,Self); +end; +{ +function tconnectionname.stringtosqltext(const afieldtype: tfieldtype; + const avalue: string): string; +var + esc_str : pchar; +begin + Getmem(esc_str,length(avalue)*2+1); + mysql_real_escape_string(FMySQL,esc_str,pchar(str1),length(str1)); + Result := '''' + esc_str + ''''; + Freemem(esc_str); +end; + +function TConnectionName.GetAsSQLText(Field : TField) : string; +var + esc_str : pchar; + str1: string; +begin + if (not assigned(field)) or field.IsNull then begin + Result := 'Null' + end + else begin + if field.DataType in [ftString,ftmemo,ftblob,ftgraphic] then begin + result:= stringtosqltext(field.datatype,field.asstring); + end + else begin + Result := inherited GetAsSqlText(field); + end; + end; +end; + +function TConnectionName.GetAsSQLText(Param: TParam) : string; +var + esc_str : pchar; + str1: string; +begin + if (not assigned(param)) or param.IsNull then begin + Result:= 'Null' + end + else begin + if param.DataType in [ftString,ftmemo,ftblob,ftgraphic] then begin + str1:= param.asstring; + Getmem(esc_str,length(str1)*4+1); + mysql_real_escape_string(FMySQL,esc_str,pchar(str1),length(str1)); + Result:= '''' + esc_str + ''''; + Freemem(esc_str); + end + else begin + Result:= inherited GetAsSqlText(Param); + end; + end; +end; +} + +procedure TConnectionName.ConnectToServer; + +Var + H,U,P : String; + +begin + H:= ansistring(HostName); + U:= ansistring(UserName); + P:= ansistring(Password); + ConnectMySQL(FMySQL,pchar(H),pchar(U),pchar(P)); + FServerInfo := strpas(mysql_get_server_info(FMYSQL)); + FHostInfo := strpas(mysql_get_host_info(FMYSQL)); +end; + +procedure TConnectionName.SelectDatabase; +begin + if mysql_select_db(FMySQL,pchar(ansistring(DatabaseName)))<>0 then + checkerror(SErrDatabaseSelectFailed); +end; + +procedure TConnectionName.DoInternalConnect; +begin +{$if fpc_fullversion >= 20401} +{$else} + FDidConnect:=(MySQLLibraryHandle=NilHandle); + if FDidConnect then +{$endif} + InitialiseMysql; +{$IFDEF mysql50} + if copy(strpas(mysql_get_client_info()),1,3)<>'5.0' then + Raise EInOutError.CreateFmt(SErrNotversion50,[strpas(mysql_get_client_info())]); +{$ELSE} + {$IFDEF mysql41} + if copy(strpas(mysql_get_client_info()),1,3)<>'4.1' then + Raise EInOutError.CreateFmt(SErrNotversion41,[strpas(mysql_get_client_info())]); + {$ELSE} + if copy(strpas(mysql_get_client_info()),1,3)<>'4.0' then + Raise EInOutError.CreateFmt(SErrNotversion40,[strpas(mysql_get_client_info())]); + {$ENDIF} +{$ENDIF} + inherited DoInternalConnect; + ConnectToServer; + SelectDatabase; +end; + +procedure TConnectionName.DoInternalDisconnect; +begin + inherited DoInternalDisconnect; + mysql_close(FMySQL); + FMySQL:=Nil; +{$if fpc_fullversion >= 20401} +{$else} + if FDidConnect then +{$endif} + ReleaseMysql; +end; + +function TConnectionName.GetHandle: pointer; +begin + Result:=FMySQL; +end; + +function TConnectionName.AllocateCursorHandle(const aowner: icursorclient; + const aname: ansistring): TSQLCursor; +begin + Result:=TCursorName.Create(aowner,aname); +end; + +Procedure TConnectionName.DeAllocateCursorHandle(var cursor : TSQLCursor); + +begin + FreeAndNil(cursor); +end; + +function TConnectionName.AllocateTransactionHandle: TSQLHandle; +begin +// Result:=TTransactionName.Create; + Result := nil; +end; + +procedure tconnectionname.preparestatement(const cursor: tsqlcursor; + const atransaction : tsqltransaction; + const asql: msestring; const aparams : tmseparams); +begin + With TCursorName(cursor) do begin + FStatementm:= asql; + if assigned(AParams) and (AParams.count > 0) then begin + FStatementm:= AParams.ParseSQL(FStatementm,false,false,false,psSimulated, + paramBinding,ParamReplaceString); + end; + if FStatementType in datareturningtypes then begin + FNeedData:=True; + end; + fprepared:= true; + end; +end; + +procedure TConnectionName.UnPrepareStatement(cursor: TSQLCursor); +begin + with tcursorname(cursor) do begin + fstatementm:= ''; + fprepared:= false; + end; +end; + +procedure tconnectionname.freeresultbuffer(const cursor: tcursorname); +begin + If (Cursor.FRes<>Nil) then begin + Mysql_free_result(Cursor.FRes); + Cursor.FRes:=Nil; + end; +end; + +procedure TConnectionName.FreeFldBuffers(cursor: TSQLCursor); + +Var + C : TCursorName; + +begin + C:= TCursorName(cursor); + if c.FStatementType in datareturningtypes then + c.FNeedData:=False; + freeresultbuffer(c); + SetLength(c.MapDSRowToMSQLRow,0); +end; + +procedure TConnectionName.internalExecute(const cursor: TSQLCursor; + const atransaction: tSQLtransaction; const AParams : TmseParams; + const autf8: boolean); + +var + C: TCursorName; +// i: integer; + str1: ansistring; +// par1: tparam; + mstr1: msestring; +begin + C:= TCursorName(cursor); + c.frowsaffected:= -1; + c.frowsreturned:= -1; + freeresultbuffer(c); + if Assigned(AParams) and (aparams.count > 0) then begin + mstr1:= aparams.expandvalues(c.fstatementm, + c.parambinding,c.paramreplacestring); + end + else begin + mstr1:= c.fstatementm; + end; + if autf8 then begin + str1:= stringtoutf8ansi(mstr1); + end + else begin + str1:= ansistring(mstr1); + end; + + if mysql_query(FMySQL,Pchar(str1))<>0 then begin + checkerror(Format(SErrExecuting,[ + ansistring(connectionmessage(mysql_error(FMySQL)))])) + end + else begin + C.fRowsAffected := mysql_affected_rows(FMYSQL); + C.LastInsertID := mysql_insert_id(FMYSQL); + if C.FNeedData then begin + C.FRes:= mysql_store_result(FMySQL); + c.frowsreturned:= mysql_num_rows(c.fres); + end + else begin + c.frowsreturned:= 0; + end; + end; +end; + +//function TConnectionName.MySQLDataType(AType: enum_field_types; ASize, ADecimals: Integer; +// var NewType: TFieldType; var NewSize: Integer): Boolean; +function TConnectionName.MySQLDataType(const afield: mysql_field; var NewType: TFieldType; + var NewSize: Integer): Boolean; +begin + Result := True; + NewSize:= 0; + with afield do begin + case ftype of + FIELD_TYPE_TINY,FIELD_TYPE_SHORT,FIELD_TYPE_LONG: begin + NewType:= ftInteger; + end; + FIELD_TYPE_LONGLONG,FIELD_TYPE_INT24: begin + newtype:= ftlargeint; + end; + {$ifdef mysql50} + FIELD_TYPE_NEWDECIMAL, + {$endif} + FIELD_TYPE_DECIMAL: begin + if Decimals < 5 then begin + NewType:= ftBCD; + end + else begin + NewType:= ftFloat; + end; + end; + FIELD_TYPE_FLOAT,FIELD_TYPE_DOUBLE: begin + NewType:= ftFloat; + end; + FIELD_TYPE_TIMESTAMP,FIELD_TYPE_DATETIME: begin + NewType:= ftDateTime; + end; + FIELD_TYPE_DATE: begin + NewType:= ftDate; + end; + FIELD_TYPE_TIME: begin + NewType:= ftTime; + end; + FIELD_TYPE_VAR_STRING,FIELD_TYPE_STRING,FIELD_TYPE_ENUM, + FIELD_TYPE_SET: begin + NewType:= ftString; + NewSize:= length; + end; + {$ifdef mysql41} + field_type_blob: begin + newsize:= sizeof(integer); + if charsetnr = 63 then begin //binary + newtype:= ftblob; + end + else begin + newtype:= ftmemo; + end; + end; + {$endif} + else begin + Result:= False; + end; + end; + end; +end; + +procedure TConnectionName.AddFieldDefs(const cursor: TSQLCursor; + const FieldDefs: TfieldDefs); +var + C: TCursorName; + I,TF,FC: Integer; + field: PMYSQL_FIELD; + DFT: TFieldType; + DFS: Integer; + fd: tfielddef; + str1: ansistring; + +begin + fielddefs.clear; + C:=(Cursor as TCursorName); + If (C.FRes=Nil) then begin + checkerror(SErrNoQueryResult); + end; + FC:=mysql_num_fields(C.FRes); + SetLength(c.MapDSRowToMSQLRow,FC); + + TF := 1; + For I:= 0 to FC-1 do begin + field := mysql_fetch_field_direct(C.FRES, I); + with field^ do begin + if (flags and (pri_key_flag or auto_increment_flag) = + (pri_key_flag or auto_increment_flag)) then begin + c.fprimarykeyfieldname:= name; + end; + end; + if MySQLDataType(field^,DFT,DFS) then begin + if (dft = ftmemo) and (cursor.stringmemo) then begin + dft:= ftstring; + dfs:= 0; + end; + str1:= field^.name; + if not(dft in varsizefields) then begin + dfs:= 0; + end; + fd:= TFieldDef.Create(nil,str1,DFT,DFS,False,TF); + fd.collection:= fielddefs; + + c.MapDSRowToMSQLRow[TF-1] := I; + inc(TF); + end + end; +end; + +function TConnectionName.Fetch(cursor: TSQLCursor): boolean; + +Var + C : TCursorName; + +begin + C:=Cursor as TCursorName; + C.Row:=MySQL_Fetch_row(C.FRes); + Result:=(C.Row<>Nil); +end; + +function tconnectionname.loadfield(const cursor: tsqlcursor; + const datatype: tfieldtype; const fieldnum: integer; //null based + const buffer: pointer; var bufsize: integer; + const aisutf8: boolean): boolean; + //if bufsize < 0 -> buffer was to small, should be -bufsize + +var + field: PMYSQL_FIELD; + row : MYSQL_ROW; + C : TCursorName; + fno: integer; + alen: integer; +begin +// Writeln('LoadFieldsFromBuffer'); + result:= false; + C:= tcursorname(Cursor); + fno:= fieldnum; + if C.Row=nil then + begin + // Writeln('LoadFieldsFromBuffer: row=nil'); + checkerror(SErrFetchingData); + end; + Row:=C.Row; + + inc(Row,c.MapDSRowToMSQLRow[fno]); + if row^ <> nil then begin + if buffer = nil then begin + exit; + end; + field:= mysql_fetch_field_direct(C.FRES,c.MapDSRowToMSQLRow[fno]); + if datatype = ftstring then begin +// alen:= strlen(row^); + alen:= mysql_fetch_lengths(c.fres)[c.MapDSRowToMSQLRow[fno]]; + if bufsize < alen then begin + bufsize:= -alen; + result:= true; + exit; + end + else begin + bufsize:= alen; + end; + end + else begin + if datatype in [ftmemo,ftgraphic,ftblob] then begin + alen:= mysql_fetch_lengths(c.fres)[c.MapDSRowToMSQLRow[fno]]; + end + else begin + alen:= field^.length; + end; + end; + Result:= MySQLWriteData(cursor, field^.ftype,alen, + DataType,Row^,Buffer); + end; +end; + +function TConnectionName.fetchblob(const cursor: tsqlcursor; + const fieldnum: integer): ansistring; +var + int1: integer; + row1: MYSQL_ROW; +begin + result:= ''; + with tcursorname(cursor) do begin + if row <> nil then begin + int1:= MapDSRowToMSQLRow[fieldnum]; + row1:= row; + inc(row1,int1); + setlength(result,mysql_fetch_lengths(fres)[int1]); + if result <> '' then begin + move(row1^^,result[1],length(result)); + end; + end; + end; +end; + +function InternalStrToFloat(S: string): Extended; + +var + I: Integer; + Tmp: string; + +begin + Tmp := ''; + for I := 1 to Length(S) do + begin + if not (S[I] in ['0'..'9', '+', '-', 'E', 'e']) then + Tmp := Tmp + {$ifdef FPC}defaultformatsettings.{$endif}DecimalSeparator + else + Tmp := Tmp + S[I]; + end; + Result := StrToFloat(Tmp); +end; + +function InternalStrToCurrency(S: string): Extended; + +var + I: Integer; + Tmp: string; + +begin + Tmp := ''; + for I := 1 to Length(S) do + begin + if not (S[I] in ['0'..'9', '+', '-', 'E', 'e']) then + Tmp := Tmp + {$ifdef FPC}defaultformatsettings.{$endif}DecimalSeparator + else + Tmp := Tmp + S[I]; + end; + Result := StrToCurr(Tmp); +end; + +function InternalStrToDate(S: string): TDateTime; + +var + EY, EM, ED: Word; + +begin + EY := StrToInt(Copy(S,1,4)); + EM := StrToInt(Copy(S,6,2)); + ED := StrToInt(Copy(S,9,2)); + if (EY = 0) or (EM = 0) or (ED = 0) then + Result:=0 + else + Result:=EncodeDate(EY, EM, ED); +end; + +function InternalStrToDateTime(S: string): TDateTime; + +var + EY, EM, ED: Word; + EH, EN, ES: Word; + +begin + EY := StrToInt(Copy(S, 1, 4)); + EM := StrToInt(Copy(S, 6, 2)); + ED := StrToInt(Copy(S, 9, 2)); + EH := StrToInt(Copy(S, 12, 2)); + EN := StrToInt(Copy(S, 15, 2)); + ES := StrToInt(Copy(S, 18, 2)); + if (EY = 0) or (EM = 0) or (ED = 0) then + Result := 0 + else + Result := EncodeDate(EY, EM, ED); + Result := Result + EncodeTime(EH, EN, ES, 0); +end; + +function InternalStrToTime(S: string): TDateTime; + +var + EH, EM, ES: Word; + +begin + EH := StrToInt(Copy(S, 1, 2)); + EM := StrToInt(Copy(S, 4, 2)); + ES := StrToInt(Copy(S, 7, 2)); + Result := EncodeTime(EH, EM, ES, 0); +end; + +function InternalStrToTimeStamp(S: string): TDateTime; + +var + EY, EM, ED: Word; + EH, EN, ES: Word; + +begin +{$IFNDEF mysql40} + EY := StrToInt(Copy(S, 1, 4)); + EM := StrToInt(Copy(S, 6, 2)); + ED := StrToInt(Copy(S, 9, 2)); + EH := StrToInt(Copy(S, 12, 2)); + EN := StrToInt(Copy(S, 15, 2)); + ES := StrToInt(Copy(S, 18, 2)); +{$ELSE} + EY := StrToInt(Copy(S, 1, 4)); + EM := StrToInt(Copy(S, 5, 2)); + ED := StrToInt(Copy(S, 7, 2)); + EH := StrToInt(Copy(S, 9, 2)); + EN := StrToInt(Copy(S, 11, 2)); + ES := StrToInt(Copy(S, 13, 2)); +{$ENDIF} + if (EY = 0) or (EM = 0) or (ED = 0) then + Result := 0 + else + Result := EncodeDate(EY, EM, ED); + Result := Result + EncodeTime(EH, EN, ES, 0);; +end; + +function TConnectionName.MySQLWriteData(const acursor: tsqlcursor; + AType: enum_field_types;ASize: Integer; + AFieldType: TFieldType;Source, Dest: PChar): Boolean; + +var + VI: Integer; + VL: largeint; + VF: Double; + VC: Currency; + VD: TDateTime; + Src : String; + int1: integer; +begin + Result:= False; + if Source = Nil then begin + exit; + end; + Result:= True; + case afieldtype of + ftstring: begin + Move(Source^, Dest^, ASize) + end; + ftblob,ftmemo: begin + int1:= acursor.addblobdata(source,asize); + move(int1,dest^,sizeof(int1)); + //save id + end; + else begin + Src:=StrPas(Source); + case AType of + FIELD_TYPE_TINY, FIELD_TYPE_SHORT, FIELD_TYPE_LONG, + FIELD_TYPE_INT24: + begin + if (Src<>'') then + VI := StrToInt(Src) + else + VI := 0; + Move(VI, Dest^, SizeOf(Integer)); + end; + FIELD_TYPE_LONGLONG: + begin + if (Src<>'') then + VL := StrToInt64(Src) + else + VL := 0; + Move(VL, Dest^, SizeOf(LargeInt)); + end; +{$ifdef mysql50} + FIELD_TYPE_NEWDECIMAL, +{$endif} + FIELD_TYPE_DECIMAL, FIELD_TYPE_FLOAT, FIELD_TYPE_DOUBLE: + if AFieldType = ftBCD then + begin + VC := InternalStrToCurrency(Src); + Move(VC, Dest^, SizeOf(Currency)); + end + else + begin + if Src <> '' then + VF := InternalStrToFloat(Src) + else + VF := 0; + Move(VF, Dest^, SizeOf(Double)); + end; + FIELD_TYPE_TIMESTAMP: + begin + if Src <> '' then + VD := InternalStrToTimeStamp(Src) + else + VD := 0; + Move(VD, Dest^, SizeOf(TDateTime)); + end; + FIELD_TYPE_DATETIME: + begin + if Src <> '' then + VD := InternalStrToDateTime(Src) + else + VD := 0; + Move(VD, Dest^, SizeOf(TDateTime)); + end; + FIELD_TYPE_DATE: + begin + if Src <> '' then + VD := InternalStrToDate(Src) + else + VD := 0; + Move(VD, Dest^, SizeOf(TDateTime)); + end; + FIELD_TYPE_TIME: + begin + if Src <> '' then + VD := InternalStrToTime(Src) + else + VD := 0; + Move(VD, Dest^, SizeOf(TDateTime)); + end; + FIELD_TYPE_VAR_STRING, FIELD_TYPE_STRING, FIELD_TYPE_ENUM, FIELD_TYPE_SET: + begin +// if Src<> '' then + Move(Source^, Dest^, ASize) +// else +// Dest^ := #0; + end; + field_type_blob: begin + int1:= acursor.addblobdata(source,asize); + move(int1,dest^,sizeof(int1)); + //save id + end; + end; + end; + end; +end; + +procedure TConnectionName.UpdateIndexDefs(var IndexDefs : TIndexDefs; + const aTableName : string; const acursor: tsqlcursor); +var + qry: tsqlresult; + keynamef,{filednamef,}columnnamef,nonuniquef: tdbcol; + str1: string; +begin + if not assigned(Transaction) then begin + DatabaseError(SErrConnTransactionnSet); + end; + qry:= tsqlresult.Create(nil); + try + with qry do begin + database := Self; + sql.text:= 'show index from ' + msestring(aTableName); + active:= true; + keynamef:= datacols.colbyname('Key_name'); + columnnamef:= datacols.colbyname('Column_name'); + nonuniquef:= datacols.colbyname('Non_unique'); + while not eof do begin + with IndexDefs.AddIndexDef do begin + Name:= trim(keynamef.asstring); + if Name = 'PRIMARY' then begin + options:= options + [ixPrimary]; + end; + if nonuniquef.asinteger = 0 then begin + options:= options + [ixUnique]; + end; + str1:= ''; + repeat + str1:= str1 + trim(columnnamef.asstring) + ';'; + next; + until eof or (name <> keynamef.asstring); + setlength(str1,length(str1)-1); //remove last ';' + fields:= str1; + end; + end; + end; + finally + qry.free; + end; +end; + + +function TConnectionName.GetTransactionHandle(trans: TSQLHandle): pointer; +begin + Result:=Nil; +end; + +function TConnectionName.Commit(trans: TSQLHandle): boolean; +begin + result:= true; + // Do nothing. +end; + +function TConnectionName.RollBack(trans: TSQLHandle): boolean; +begin + result:= true; + // Do nothing +end; + +function TConnectionName.StartdbTransaction(const trans: TSQLHandle; + const AParams: tstringlist): boolean; +begin + result:= true; + // Do nothing +end; + +procedure TConnectionName.internalCommitRetaining(trans: TSQLHandle); +begin + // Do nothing +end; + +procedure TConnectionName.internalRollBackRetaining(trans: TSQLHandle); +begin + // Do nothing +end; + +function TConnectionName.CreateBlobStream(const Field: TField; + const Mode: TBlobStreamMode; const acursor: tsqlcursor): TStream; +var + blobid: integer; +// int1,int2: integer; +// str1: string; +// bo1: boolean; +begin + result:= nil; + if mode = bmread then begin + if field.getData(@blobId) then begin + result:= acursor.getcachedblob(blobid); + end; + end; +end; + +function TConnectionName.getblobdatasize: integer; +begin + result:= sizeof(integer); +end; +{ +function TConnectionName.getfeatures(): databasefeaturesty; +begin + result:= inherited getfeatures() + [dbf_blobscached]; +end; +} +procedure TConnectionName.writeblobdata(const atransaction: tsqltransaction; + const tablename: string; const acursor: tsqlcursor; + const adata: pointer; const alength: integer; + const afield: tfield; const aparam: tparam; out newid: string); +var + str1: string; + int1: integer; +begin + setlength(str1,alength); + move(adata^,str1[1],alength); + if afield.datatype = ftmemo then begin + aparam.asmemo:= str1; + end + else begin + aparam.asblob:= str1; + end; + int1:= acursor.addblobdata(str1); + setlength(newid,sizeof(int1)); + move(int1,newid[1],sizeof(int1)); +end; + +procedure TConnectionName.setupblobdata(const afield: tfield; + const acursor: tsqlcursor; const aparam: tparam); +begin + acursor.blobfieldtoparam(afield,aparam,false); +end; +{ +function TConnectionName.blobscached: boolean; +begin + result:= true; +end; +} +function TConnectionName.getprimarykeyfield(const atablename: string; + const acursor: tsqlcursor): string; +begin + result:= tcursorname(acursor).fprimarykeyfieldname; +end; + +function TConnectionName.getinsertid(const atransaction: tsqltransaction): int64; +begin + result:= mysql_insert_id(fmysql); +end; + +procedure TConnectionName.updateprimarykeyfield(const afield: tfield; + const atransaction: tsqltransaction); +begin + afield.aslargeint:= getinsertid(nil); + { + with tmsebufdataset1(afield.dataset) do begin + setcurvalue(afield,getinsertid); + end; + } +end; + +function TConnectionName.identquotechar: msestring; +begin + result:= '`'; //needed for reserved words as fieldnames +end; + +{ eerrorname } + +constructor eerrorname.create(const asender: tcustomsqlconnection; + const amessage: ansistring; const aerrormessage: msestring; + const aerror: integer; const asqlcode: string); +begin + fsqlcode:= asqlcode; + inherited create(asender,amessage,aerrormessage,aerror); +end; + +end. diff --git a/mseide-msegui/lib/common/db/mmysqlconn.pas b/mseide-msegui/lib/common/db/mmysqlconn.pas new file mode 100644 index 0000000..9293c9a --- /dev/null +++ b/mseide-msegui/lib/common/db/mmysqlconn.pas @@ -0,0 +1,1965 @@ +{ + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +{Modified 2006-2013 by Martin Schreiber} + +unit mmysqlconn; + +{$ifdef FPC}{$mode objfpc}{$H+}{$MACRO on}{$endif} + +{$DEFINE mysql51} + +{$ifdef mysql51} + {$define mysql50} +{$endif} +{$ifdef mysql50} + {$define mysql41} +{$endif} + +interface +uses +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + classes,mclasses,SysUtils,msqldb,mdb,{$ifdef FPC}dynlibs,{$endif}msestrings, + msedb,mysqldyn,msetypes,msectypes; + +Type + + tmysqlcursor = class; + + emysqlerror = class(econnectionerror) + private + fsqlcode: string; + public + constructor create(const asender: tcustomsqlconnection; + const amessage: ansistring; const aerrormessage: msestring; + const aerror: integer; const asqlcode: string); + property sqlcode: string read fsqlcode; + end; + + tmysqltrans = class(TSQLHandle) + protected + fconn: pmysql; + public + property conn: pmysql read fconn; + end; + + bindinginfoty = record + length: culong; + buffer: pointer; + isnull: boolean; //-> cchar + isblob: boolean; //-> cchar + end; + pbindinginfoty = ^bindinginfoty; + bindinginfoarty = array of bindinginfoty; + + tmysqlcursor = class(TSQLCursor) + protected +// FQMySQL : PMySQL; + FRes: PMYSQL_RES; { Record pointer } + FNeedData : Boolean; + fstatementm: msestring; + Row : MYSQL_ROW; +// RowsAffected : QWord; + LastInsertID : QWord; + ParamBinding : TParamBinding; + ParamReplaceString : mseString; + MapDSRowToMSQLRow: integerarty; + fprimarykeyfieldname: string; + fconn: pmysql; + fparambinding: tparambinding; + fprepstatement: pmysql_stmt; + fresultmetadata: pmysql_res; + fresultfieldcount: integer; + fresultbindinginfo: bindinginfoarty; + fresultbindings: pointer; + fresultbuf: pointer; + procedure freeprepstatement; + public + end; + + mysqloptionty = (myo_nopreparedstatements,myo_storeresult,myo_ssl); + mysqloptionsty = set of mysqloptionty; + + tmysqlconnection = class (TSQLConnection,iblobconnection) + private + FDialect: integer; + FHostInfo: String; + FServerInfo: String; + FMySQL1 : PMySQL; +// FDidConnect : Boolean; + fport: longword; + flasterror: integer; + foptions: mysqloptionsty; + flasterrormessage: msestring; + flastsqlcode: string; + ftransactionconnectionused: boolean; + fssl_key: filenamety; + fssl_cert: filenamety; + fssl_ca: filenamety; + fssl_capath: filenamety; + fssl_cipher: filenamety; + function GetClientInfo: string; + function GetServerStatus: String; + procedure ConnectMySQL(var HMySQL : PMySQL;H,U,P : pchar); + procedure freeresultbuffer(const cursor: tmysqlcursor); + procedure begintrans(const aconnection: pmysql; const aparams: ansistring); + procedure openconnection(var aconn: pmysql); + procedure closeconnection(var aconnection: pmysql); + protected + Procedure checkerror(const Msg: String; const aconn: pmysql); + Procedure checkstmterror(const Msg: String; const astmt: pmysql_stmt); + +// function stringtosqltext(const afeildtype: tfieldtype; const avalue: string): string; + function StrToStatementType(s : msestring) : TStatementType; override; +// Procedure ConnectToServer; virtual; +// Procedure SelectDatabase; virtual; +// function MySQLDataType(AType: enum_field_types; ASize, ADecimals: Integer; var NewType: TFieldType; var NewSize: Integer): Boolean; + function MySQLDataType(const afield: mysql_field; + const charsetinfo: my_charset_info; out NewType: TFieldType; + out NewSize: Integer; out newprecision: integer): Boolean; + function MySQLWriteData(const acursor: tsqlcursor; AType: enum_field_types; + ASize: Integer; + AFieldType: TFieldType;Source, Dest: PChar): Boolean; + // SQLConnection methods + procedure DoInternalConnect; override; + procedure executeparams; override; + procedure DoInternalDisconnect; override; + function GetHandle : pointer; override; + +// function GetAsSQLText(Field : TField) : string; overload; override; +// function GetAsSQLText(Param : TParam) : string; overload; override; + + Function AllocateTransactionHandle : TSQLHandle; override; + procedure finalizetransaction(const atransaction: tsqlhandle); override; + + procedure doexecuteunprepared(const c: tmysqlcursor; + const atransaction: tsqltransaction; const asql: string); + procedure internalExecute(const cursor: TSQLCursor; + const atransaction:tSQLtransaction; + const AParams: TmseParams; const autf8: boolean); override; + procedure internalexecuteunprepared(const cursor: tsqlcursor; + const atransaction: tsqltransaction; const asql: string; + const origsql: msestring; const aparams: tmseparams); override; + + function GetTransactionHandle(trans : TSQLHandle): pointer; override; + function Commit(trans : TSQLHandle) : boolean; override; + function RollBack(trans : TSQLHandle) : boolean; override; + function StartdbTransaction(const trans : TSQLHandle; + const AParams: tstringlist) : boolean; override; + procedure internalCommitRetaining(trans : TSQLHandle); override; + procedure internalRollBackRetaining(trans : TSQLHandle); override; + procedure UpdateIndexDefs(var IndexDefs : TIndexDefs; + const aTableName : string; const acursor: tsqlcursor); override; + + function getprimarykeyfield(const atablename: string; + const acursor: tsqlcursor): string; override; + procedure updateprimarykeyfield(const afield: tfield; + const atransaction: tsqltransaction); override; + function CreateBlobStream(const Field: TField; const Mode: TBlobStreamMode; + const acursor: tsqlcursor): TStream; override; + function getblobdatasize: integer; override; +// function getfeatures(): databasefeaturesty override; + //iblobconnection + procedure writeblobdata(const atransaction: tsqltransaction; + const tablename: string; const acursor: tsqlcursor; + const adata: pointer; const alength: integer; + const afield: tfield; const aparam: tparam; + out newid: string); + procedure setupblobdata(const afield: tfield; const acursor: tsqlcursor; + const aparam: tparam); +// function blobscached: boolean; + function identquotechar: msestring; override; + + Public + constructor create(aowner: tcomponent); override; + Function AllocateCursorHandle(const aowner: icursorclient; + const aname: ansistring): TSQLCursor; override; + Procedure DeAllocateCursorHandle(var cursor : TSQLCursor); override; + procedure preparestatement(const cursor: tsqlcursor; + const atransaction : tsqltransaction; + const asql: msestring; const aparams : tmseparams); override; + procedure UnPrepareStatement(cursor:TSQLCursor); override; + procedure FreeFldBuffers(cursor : TSQLCursor); override; + procedure AddFieldDefs(const cursor: TSQLCursor; + const FieldDefs : TfieldDefs); override; + function Fetch(cursor : TSQLCursor) : boolean; override; + function loadfield(const cursor: tsqlcursor; + const datatype: tfieldtype; const fieldnum: integer; //null based + const abuffer: pointer; var abufsize: integer; + const aisutf8: boolean): boolean; override; + //if bufsize < 0 -> buffer was to small, should be -bufsize + function fetchblob(const cursor: tsqlcursor; + const fieldnum: integer): ansistring; override; + //null based + function getinsertid(const atransaction: tsqltransaction): int64; override; + procedure createdatabase(const asql: ansistring); + Property ServerInfo : String Read FServerInfo; + Property HostInfo : String Read FHostInfo; + property ClientInfo: string read GetClientInfo; + property ServerStatus : String read GetServerStatus; + property lasterror: integer read flasterror; + property lasterrormessage: msestring read flasterrormessage; + property lastsqlcode: string read flastsqlcode; + published + property options: mysqloptionsty read foptions write foptions default []; + property Dialect : integer read FDialect write FDialect default 0; + property port: longword read fport write fport default 0; + property ssl_key: filenamety read fssl_key write fssl_key; + property ssl_cert: filenamety read fssl_cert write fssl_cert; + property ssl_ca: filenamety read fssl_ca write fssl_ca; + property ssl_capath: filenamety read fssl_capath write fssl_capath; + property ssl_cipher: filenamety read fssl_cipher write fssl_cipher; + property DatabaseName; + property HostName; + property KeepConnection; +// property LoginPrompt; + property Params; + property ongetcredentials; +// property OnLogin; + end; + +// EMySQLError = Class(Exception); + +implementation +uses + {$ifdef FPC}dbconst{$else}dbconst_del,classes_del{$endif}, + msebufdataset,typinfo,dateutils,msefileutils,msedatabase,msedynload, + msesqlresult; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tmsebufdataset1 = class(tmsebufdataset); +var + is51: boolean; +const + maxprecision = 18; + +Resourcestring + SErrServerConnectFailed = 'Server connect failed: %s'; + SErrDatabaseSelectFailed = 'failed to select database: %s'; + SErrDatabaseCreate = 'Failed to create database: %s'; + SErrDatabaseDrop = 'Failed to drop database: %s'; + sbindresult = 'Failed to bind result: %s'; + serrstarttransaction = 'Failed to start transaction: %s'; + serrcommittransaction = 'Failed to commit transaction: %s'; + serrrollbacktransaction = 'Failed to rollback transaction: %s'; + serrprepare = 'Failed to prepare statement: %s'; + SErrNoData = 'No data for record'; + SErrExecuting = 'Error executing query: %s'; + SErrFetchingdata = 'Error fetching row data: %s'; + SErrGettingResult = 'Error getting result set: %s'; + SErrNoQueryResult = 'No result from query.'; + SErrNotversion50 = 'TMySQL50Connection can not work with the installed MySQL client version (%s).'; + SErrNotversion41 = 'TMySQL41Connection can not work with the installed MySQL client version (%s).'; + SErrNotversion40 = 'TMySQL40Connection can not work with the installed MySQL client version (%s).'; + +function datetimetomysql_time(const datatype: tfieldtype; + const avalue: tdatetime): mysql_time; +var + year1,month1,day1,hour1,minute1,second1,millisecond1: word; +begin + fillchar(result,sizeof(result),0); + decodedatetime(avalue,year1,month1,day1,hour1,minute1,second1,millisecond1); + with result do begin + if datatype in [ftdate,ftdatetime] then begin + year:= year1; + month:= month1; + day:= day1; + time_type:= mysql_timestamp_date; + end; + if datatype in [fttime,ftdatetime] then begin + hour:= hour1; + minute:= minute1; + second:= second1; + second_part:= millisecond1 * 1000; + time_type:= mysql_timestamp_time; + end; + if datatype = ftdatetime then begin + time_type:= mysql_timestamp_datetime; + end; + end; +end; + +function mysql_timetodatetime(const avalue: mysql_time): tdatetime; +begin + result:= 0; + with avalue do begin + case time_type of + mysql_timestamp_date: begin + tryencodedate(year,month,day,result); + end; + mysql_timestamp_time: begin + tryencodetime(hour,minute,second,second_part div 1000, + result); + end; + else begin + tryencodedatetime(year,month,day,hour,minute,second,second_part div 1000, + result); + end; + end; + end; +end; + +function createbindings(const acount: integer): pointer; +var + int1: integer; +begin + result:= nil; + if is51 then begin + int1:= acount * sizeof(mysql_bind_51); + end + else begin + int1:= acount * sizeof(mysql_bind_50); + end; + if int1 > 0 then begin + getmem(result,int1); + fillchar(result^,int1,0); + end; +end; + +function getbind(const abindings: pointer; const index: integer): pointer; +begin +{$ifdef FPC} + if is51 then begin + result:= @pmysql_bind_51(abindings)[index]; + end + else begin + result:= @pmysql_bind_50(abindings)[index]; + end; +{$else} + if is51 then begin + result:= pointer(pchar(abindings)+sizeof(mysql_bind_51)*index); + end + else begin + result:= pointer(pchar(abindings)+sizeof(mysql_bind_50)*index); + end; +{$endif} +end; + +procedure freebindings(var abindings: pointer); +begin + if abindings <> nil then begin + freemem(abindings); + abindings:= nil; + end; +end; + +procedure setupresultbinding(const index: integer; const fieldtype: tfieldtype; + const len: integer; //character count + const bindings: pointer; var bindinginfo: bindinginfoarty); +var + bi: pbindinginfoty; + bufsize: integer; + pbuffer_type: penum_field_types; + pbuffer_length: pculong; +begin + bi:= @bindinginfo[index]; + if is51 then begin +{$ifdef FPC} + with pmysql_bind_51(bindings)[index] do begin +{$else} + with pmysql_bind_51(pointer(pchar(bindings)+sizeof(mysql_bind_51)*index))^ do begin +{$endif} + pbuffer_type:= @buffer_type; + pbuffer_length:= @buffer_length; + length:= @bi^.length; + is_null:= @bi^.isnull; + end; + end + else begin + {$ifdef FPC} + with pmysql_bind_50(bindings)[index] do begin + {$else} + with pmysql_bind_50(pointer(pchar(bindings)+sizeof(mysql_bind_50)*index))^ do begin + {$endif} + pbuffer_type:= @buffer_type; + pbuffer_length:= @buffer_length; + length:= @bi^.length; + is_null:= @bi^.isnull; + end; + end; + case fieldtype of + ftinteger: begin + bufsize:= sizeof(longint); + pbuffer_type^:= mysql_type_long; + end; + ftlargeint: begin + bufsize:= sizeof(int64); + pbuffer_type^:= mysql_type_longlong; + end; + ftbcd,ftfloat: begin + bufsize:= sizeof(double); + pbuffer_type^:= mysql_type_double; + end; + ftdate,ftdatetime,fttime: begin + bufsize:= sizeof(mysql_time); + pbuffer_type^:= mysql_type_datetime; + end; + ftstring: begin + bufsize:= len*4; //room for multibyte encodings + pbuffer_type^:= mysql_type_var_string; + end; + ftblob,ftmemo,ftgraphic: begin + bufsize:= 0; + pbuffer_type^:= mysql_type_blob; + end + else begin + bufsize:= 0; //dummy + pbuffer_type^:= mysql_type_null; + end; + end; + pbuffer_length^:= bufsize; + bi^.length:= bufsize; + bi^.isblob:= bufsize = 0; +end; + +procedure setupinputbinding(const index: integer; const fieldtype: tfieldtype; + const bindings: pointer; var bindinginfo: bindinginfoarty; + const abuffer: pointer; const abufsize: integer); +var + bi: pbindinginfoty; + bufsize: integer; + pbuffer_type: penum_field_types; + pbuffer_length: pculong; +begin + bi:= @bindinginfo[index]; + if is51 then begin +{$ifdef FPC} + with pmysql_bind_51(bindings)[index] do begin +{$else} + with pmysql_bind_51(pointer(pchar(bindings)+sizeof(mysql_bind_51)*index))^ do begin +{$endif} + pbuffer_type:= @buffer_type; + pbuffer_length:= @buffer_length; + length:= @bi^.length; + is_null:= @bi^.isnull; + buffer:= abuffer; + end; + end + else begin +{$ifdef FPC} + with pmysql_bind_50(bindings)[index] do begin +{$else} + with pmysql_bind_50(pointer(pchar(bindings)+sizeof(mysql_bind_50)*index))^ do begin +{$endif} + pbuffer_type:= @buffer_type; + pbuffer_length:= @buffer_length; + length:= @bi^.length; + is_null:= @bi^.isnull; + buffer:= abuffer; + end; + end; + case fieldtype of + ftinteger: begin + bufsize:= sizeof(longint); + pbuffer_type^:= mysql_type_long; + end; + ftlargeint: begin + bufsize:= sizeof(int64); + pbuffer_type^:= mysql_type_longlong; + end; + ftbcd,ftfloat: begin + bufsize:= sizeof(double); + pbuffer_type^:= mysql_type_double; + end; + ftdate,ftdatetime,fttime: begin + bufsize:= sizeof(mysql_time); + pbuffer_type^:= mysql_type_datetime; + end; + ftstring: begin + bufsize:= abufsize; + pbuffer_type^:= mysql_type_var_string; + end; + ftblob,ftmemo,ftgraphic: begin + bufsize:= abufsize; + pbuffer_type^:= mysql_type_blob; + end + else begin + bufsize:= 0; //dummy + pbuffer_type^:= mysql_type_null; + end; + end; + bi^.length:= bufsize; + pbuffer_length^:= bufsize; + bi^.isblob:= bufsize = 0; +end; + +function createbindingbuffers(const bindings: pointer; + var bindinfos: bindinginfoarty): pointer; +var + int1: integer; + bufsum: longword; +begin + bufsum:= 0; + for int1:= 0 to high(bindinfos) do begin + bufsum:= bufsum + bindinfos[int1].length; + end; + getmem(result,bufsum); + bufsum:= 0; + for int1:= 0 to high(bindinfos) do begin + with bindinfos[int1] do begin + if length > 0 then begin + buffer:= pchar(result) + bufsum; + if is51 then begin +{$ifdef FPC} + pmysql_bind_51(bindings)[int1].buffer:= buffer; +{$else} + pmysql_bind_51(pointer(pchar(bindings)+ + sizeof(mysql_bind_51)*int1))^.buffer:= buffer; +{$endif} + end + else begin +{$ifdef FPC} + pmysql_bind_50(bindings)[int1].buffer:= buffer; +{$else} + pmysql_bind_50(pointer(pchar(bindings)+ + sizeof(mysql_bind_50)*int1))^.buffer:= buffer; +{$endif} + end; + bufsum:= bufsum + length; + end; + end; + end; +end; + +procedure freebindingbuffers(var abuffer: pointer); +begin + if abuffer <> nil then begin + freemem(abuffer); + abuffer:= nil; + end; +end; + +procedure setbindingbuffer(const bindings: pointer; const index: integer; + const abuffer: pointer; const alength: integer); +begin + if is51 then begin +{$ifdef FPC} + with pmysql_bind_51(bindings)[index] do begin +{$else} + with pmysql_bind_51(pointer(pchar(bindings)+sizeof(mysql_bind_51)*index))^ do begin +{$endif} + buffer:= abuffer; + buffer_length:= alength; + end; + end + else begin +{$ifdef FPC} + with pmysql_bind_50(bindings)[index] do begin +{$else} + with pmysql_bind_50(pointer(pchar(bindings)+sizeof(mysql_bind_50)*index))^ do begin +{$endif} + buffer:= abuffer; + buffer_length:= alength; + end; + end; +end; + +{ tmysqlcursor } + +procedure tmysqlcursor.freeprepstatement; +begin + if fprepstatement <> nil then begin + mysql_stmt_close(fprepstatement); + fprepstatement:= nil; + end; +end; + +{ tmysqlconnection } + +constructor tmysqlconnection.create(aowner: tcomponent); +begin + inherited; + fconnoptions:= fconnoptions + [sco_supportparams,sco_emulateretaining, + sco_blobscached]; +end; + +Procedure tmysqlconnection.checkerror(const Msg: String; const aconn: pmysql); +var + str1: msestring; +begin + str1:= connectionmessage(mysql_error(aconn)); + flasterrormessage:= str1; + flasterror:= mysql_errno(aconn); + flastsqlcode:= strpas(mysql_sqlstate(aconn)); + raise emysqlerror.create(self,format(msg,[str1]),flasterrormessage, + flasterror,flastsqlcode); +end; + +Procedure tmysqlconnection.checkstmterror(const Msg: String; + const astmt: pmysql_stmt); +var + str1: msestring; +begin + str1:= connectionmessage(mysql_stmt_error(astmt)); + flasterrormessage:= str1; + flasterror:= 0; //??? + flastsqlcode:= ''; //??? + raise emysqlerror.create(self,format(msg,[str1]),flasterrormessage, + flasterror,flastsqlcode); +end; + +function tmysqlconnection.StrToStatementType(s : msestring) : TStatementType; + +begin + S:=Lowercase(s); + if s = 'show' then begin + result:= stSelect; + exit; + end; + result := inherited StrToStatementType(s); +end; + +function tmysqlconnection.GetClientInfo: string; + +//Var +// B : Boolean; + +begin + // To make it possible to call this if there's no connection yet +// B:=(MysqlLibraryHandle=Nilhandle); +// If B then + InitializeMysql([]); + Try + Result:=strpas(mysql_get_client_info()); + Finally +// if B then + ReleaseMysql; + end; +end; + +function tmysqlconnection.GetServerStatus: String; +begin + CheckConnected; + Result := mysql_stat(FMYSQL1); +end; + +procedure tmysqlconnection.ConnectMySQL(var HMySQL : PMySQL;H,U,P : pchar); +var + key,cert,ca,capath,cipher: string; + hmysql1: pmysql; + actcipher: pchar; +begin + dynloadlock; + HMySQL := mysql_init(HMySQL); + dynloadunlock; + if myo_ssl in foptions then begin + key:= ansistring(tosysfilepath(fssl_key)); + cert:= ansistring(tosysfilepath(fssl_cert)); + ca:= ansistring(tosysfilepath(fssl_ca)); + capath:= ansistring(tosysfilepath(fssl_capath)); + cipher:= ansistring(fssl_cipher); + mysql_ssl_set(hmysql,pointer(key),pointer(cert),pointer(ca),pointer(capath), + pointer(cipher)); + end; + HMySQL1:=mysql_real_connect(HMySQL,PChar(H),PChar(U),Pchar(P),Nil,fport,Nil,0); + If (HMySQL1=Nil) then begin + checkerror(SErrServerConnectFailed,hmysql); + end; + if (myo_ssl in foptions) and + ({$ifndef FPC}@{$endif}mysql_get_ssl_cipher <> nil) then begin + actcipher:= mysql_get_ssl_cipher(hmysql); + if actcipher = nil then begin + closeconnection(hmysql); + databaseerror('Can not encrypt connection.',self); + end; + end; +end; +{ +function tmysqlconnection.stringtosqltext(const afieldtype: tfieldtype; + const avalue: string): string; +var + esc_str : pchar; +begin + Getmem(esc_str,length(avalue)*2+1); + mysql_real_escape_string(FMySQL,esc_str,pchar(str1),length(str1)); + Result := '''' + esc_str + ''''; + Freemem(esc_str); +end; + +function tmysqlconnection.GetAsSQLText(Field : TField) : string; +var + esc_str : pchar; + str1: string; +begin + if (not assigned(field)) or field.IsNull then begin + Result := 'Null' + end + else begin + if field.DataType in [ftString,ftmemo,ftblob,ftgraphic] then begin + result:= stringtosqltext(field.datatype,field.asstring); + end + else begin + Result := inherited GetAsSqlText(field); + end; + end; +end; + +function tmysqlconnection.GetAsSQLText(Param: TParam) : string; +var + esc_str : pchar; + str1: string; +begin + if (not assigned(param)) or param.IsNull then begin + Result:= 'Null' + end + else begin + if param.DataType in [ftString,ftmemo,ftblob,ftgraphic] then begin + str1:= param.asstring; + Getmem(esc_str,length(str1)*4+1); + mysql_real_escape_string(FMySQL,esc_str,pchar(str1),length(str1)); + Result:= '''' + esc_str + ''''; + Freemem(esc_str); + end + else begin + Result:= inherited GetAsSqlText(Param); + end; + end; +end; +} + +procedure tmysqlconnection.openconnection(var aconn: pmysql); +Var + H: string; + u,p: msestring; + u1,p1: string; + +begin + H:= ansistring(HostName); + getcredentials(u,p); + u1:= ansistring(u); + p1:= ansistring(p); +// U:= UserName; +// P:= Password; + try + ConnectMySQL(aconn,pchar(H),pchar(U1),pchar(P1)); + finally + stringsafefree(u1,false); + stringsafefree(p1,false); + freecredentials(u,p); + end; + if mysql_select_db(aconn,pchar(ansistring(DatabaseName))) <> 0 then begin + checkerror(SErrDatabaseSelectFailed,aconn); + end; +end; + +procedure tmysqlconnection.closeconnection(var aconnection: pmysql); +begin + mysql_close(aconnection); + aconnection:= nil; +end; + +procedure tmysqlconnection.DoInternalConnect; +var + version: integer; +begin + ftransactionconnectionused:= false; + InitializeMysql([]); + version:= mysql_get_client_version() div 100; + if version < 500 then begin + raise exception.create(name+': MySql client version must be >= 5.0.'); + end; + is51:= version >= 501; + inherited DoInternalConnect; + openconnection(fmysql1); + FServerInfo := strpas(mysql_get_server_info(FMYSQL1)); + FHostInfo := strpas(mysql_get_host_info(FMYSQL1)); + if charset <> '' then begin + mysql_set_character_set(fmysql1,pchar(charset)); + end; +end; + +procedure tmysqlconnection.executeparams; +var + int1: integer; + bo1: boolean; +begin + if params.count > 0 then begin + checktransaction(name,transaction); + bo1:= transaction.active; + try + for int1:= 0 to params.count-1 do begin + executedirect(msestring(params[int1])); + end; + if not bo1 then begin + bo1:= true; + transaction.commit; + end; + finally + if not bo1 then begin + transaction.rollback; + end; + end; + end; +end; + +procedure tmysqlconnection.DoInternalDisconnect; +begin + inherited DoInternalDisconnect; + closeconnection(fmysql1); + ReleaseMysql; +end; + +function tmysqlconnection.GetHandle: pointer; +begin + Result:=FMySQL1; +end; + +function tmysqlconnection.AllocateCursorHandle(const aowner: icursorclient; + const aname: ansistring): TSQLCursor; +begin + Result:= tmysqlcursor.Create(aowner,aname); + tmysqlcursor(result).fconn:= fmysql1; //can be overridden by transaction +end; + +Procedure tmysqlconnection.DeAllocateCursorHandle(var cursor : TSQLCursor); + +Var + C : tmysqlcursor; + +begin + if cursor <> nil then begin + C:= tmysqlcursor(cursor); + freeresultbuffer(c); + freebindingbuffers(c.fresultbuf); + FreeAndNil(cursor); + end; +end; + +function tmysqlconnection.AllocateTransactionHandle: TSQLHandle; +begin +// Result:=tmysqltransaction.Create; + Result:= tmysqltrans.create; +end; + +procedure tmysqlconnection.finalizetransaction(const atransaction: tsqlhandle); +begin + with tmysqltrans(atransaction) do begin + if (fconn <> fmysql1) then begin + closeconnection(fconn); + end; + fconn:= nil; + end; +end; + +procedure tmysqlconnection.preparestatement(const cursor: tsqlcursor; + const atransaction : tsqltransaction; + const asql: msestring; const aparams : tmseparams); +var + mstr1: msestring; + str1: ansistring; +// fieldcount: integer; +begin + With tmysqlcursor(cursor) do begin + fconn:= tmysqltrans(atransaction.trans).fconn; + if fconn = nil then begin + fconn:= fmysql1; // dummy transaction + tmysqltrans(atransaction.trans).fconn:= fmysql1; + end; + + if not (myo_nopreparedstatements in foptions) and + (FStatementType in [stInsert,stUpdate,stDelete,stSelect]) then begin + fprepstatement:= mysql_stmt_init(fconn); + if fprepstatement = nil then begin + checkerror(serrprepare,fconn); + end; + if assigned(aparams) then begin + mstr1:= aparams.parsesql(asql,true,false,false,psinterbase,fparambinding); + end + else begin + mstr1:= asql; + end; + mstr1:= trim(mstr1); + if (mstr1 <> '') and (mstr1[length(mstr1)] = ';') then begin + setlength(mstr1,length(mstr1)-1); + end; + str1:= ansistring(mstr1); //utf8? + if mysql_stmt_prepare(fprepstatement,pchar(str1), + length(str1)) <> 0 then begin + try + checkstmterror(serrprepare,fprepstatement); + finally + freeprepstatement; + end; + end; + fresultmetadata:= mysql_stmt_result_metadata(fprepstatement); + if fresultmetadata <> nil then begin + fresultfieldcount:= mysql_num_fields(fresultmetadata); + fresultbindings:= createbindings(fresultfieldcount); + end + else begin + fresultfieldcount:= 0; + end; + end + else begin + FStatementm:= asql; + if assigned(AParams) and (AParams.count > 0) then begin + FStatementm:= AParams.ParseSQL(FStatementm,false,false,false,psSimulated, + paramBinding,ParamReplaceString); + end; + end; + if FStatementType in datareturningtypes then begin + FNeedData:=True; + end; + fprepared:= true; + end; +end; + +procedure tmysqlconnection.UnPrepareStatement(cursor: TSQLCursor); +begin + with tmysqlcursor(cursor) do begin + fstatementm:= ''; + fprepared:= false; + fparambinding:= nil; + freeprepstatement; + freebindings(fresultbindings); + if fresultmetadata <> nil then begin + mysql_free_result(fresultmetadata); + fresultmetadata:= nil; + end; + end; +end; + +procedure tmysqlconnection.freeresultbuffer(const cursor: tmysqlcursor); +begin + if cursor.fres <> nil then begin + mysql_free_result(cursor.fres); + cursor.fres:= nil; + end; + if cursor.fprepstatement <> nil then begin + mysql_stmt_free_result(cursor.fprepstatement); + end; +end; + +procedure tmysqlconnection.FreeFldBuffers(cursor: TSQLCursor); + +Var + C : tmysqlcursor; + +begin + C:= tmysqlcursor(cursor); + if c.FStatementType in datareturningtypes then + c.FNeedData:=False; + freeresultbuffer(c); + c.mapdsrowtomsqlrow:= nil; +// SetLength(c.MapDSRowToMSQLRow,0); + c.fresultbindinginfo:= nil; + freebindingbuffers(c.fresultbuf); +end; + +procedure tmysqlconnection.doexecuteunprepared(const c: tmysqlcursor; + const atransaction: tsqltransaction; const asql: string); +begin + with tmysqltrans(atransaction.trans) do begin + if mysql_query(fconn,Pchar(asql)) <> 0 then begin + checkerror(SErrExecuting,fconn); + end + else begin + C.fRowsAffected := mysql_affected_rows(fconn); + C.LastInsertID := mysql_insert_id(fconn); + if C.FNeedData then begin + if myo_storeresult in foptions then begin + C.FRes:= mysql_store_result(fconn); + end + else begin + C.FRes:= mysql_use_result(fconn); + //needs to call mysql_fetch_row() until all data has been fetched + end; + if myo_storeresult in foptions then begin + c.frowsreturned:= mysql_num_rows(c.fres); + end; + end; + end; + end; +end; + +procedure tmysqlconnection.internalExecute(const cursor: TSQLCursor; + const atransaction: tSQLtransaction; const AParams : TmseParams; + const autf8: boolean); + +var + C: tmysqlcursor; +// i: integer; + str1: ansistring; +// par1: tparam; + int1: integer; + inputparambindings: bindinginfoarty; + paramdata: pointer; + inputbindings: pointer; + strings: stringarty; + dataty1: tfieldtype; + mstr1: msestring; +begin + C:= tmysqlcursor(cursor); + c.frowsaffected:= -1; + c.frowsreturned:= -1; + if not C.FNeedData then begin + c.frowsreturned:= 0; + end; + freeresultbuffer(c); + if c.fprepstatement <> nil then begin + paramdata:= nil; + inputbindings:= nil; + if (aparams <> nil) and (aparams.count > 0) then begin + inputbindings:= createbindings(length(c.fparambinding)); + setlength(inputparambindings,length(c.fparambinding)); + setlength(strings,length(c.fparambinding)); + for int1:= 0 to high(c.fparambinding) do begin + if c.fparambinding[int1] < aparams.count then begin + with aparams[c.fparambinding[int1]] do begin + case datatype of //todo: date and time + ftinteger,ftsmallint,ftword: begin + setupinputbinding(int1,ftinteger,inputbindings, + inputparambindings,nil,sizeof(integer)); + end; + ftlargeint: begin + setupinputbinding(int1,ftlargeint,inputbindings, + inputparambindings,nil,sizeof(int64)); + end; + ftfloat,ftcurrency,ftbcd: begin + setupinputbinding(int1,ftfloat,inputbindings, + inputparambindings,nil,sizeof(double)); + end; + ftdate,ftdatetime,fttime: begin + setupinputbinding(int1,ftdatetime,inputbindings, + inputparambindings,nil,sizeof(mysql_time)); + end; + ftstring,ftwidestring,ftblob,ftmemo,ftfixedchar,ftfixedwidechar: begin + setupinputbinding(int1,ftstring,inputbindings, + inputparambindings,nil,0); + //dummy for NULL, setup later + end; + else begin + freebindings(inputbindings); + databaseerror('Paramtype '+ + getenumname(typeinfo(tfieldtype),ord(datatype))+' not supported.',self); + end; + end; + end; + end; + end; + paramdata:= createbindingbuffers(inputbindings,inputparambindings); + for int1:= 0 to high(c.fparambinding) do begin + if c.fparambinding[int1] < aparams.count then begin + with aparams[c.fparambinding[int1]] do begin + if isnull then begin + inputparambindings[int1].isnull:= true; + end + else begin + case datatype of + ftinteger,ftsmallint,ftword: begin + pinteger(inputparambindings[int1].buffer)^:= asinteger; + end; + ftlargeint: begin + pint64(inputparambindings[int1].buffer)^:= aslargeint; + end; + ftfloat,ftbcd,ftcurrency: begin + pdouble(inputparambindings[int1].buffer)^:= asfloat; + end; + ftdate,ftdatetime,fttime: begin + pmysql_time(inputparambindings[int1].buffer)^:= + datetimetomysql_time(datatype,asdatetime); + end; + ftstring,ftwidestring,ftblob,ftmemo,ftfixedchar,ftfixedwidechar: begin + strings[int1]:= aparams.asdbstring(c.fparambinding[int1]); + dataty1:= datatype; + if dataty1 <> ftblob then begin + dataty1:= ftstring; + end; + setupinputbinding(int1,dataty1,inputbindings, + inputparambindings,pointer(strings[int1]), + length(strings[int1])); + end; + end; + end; + end; + end; + end; + end; + try + if mysql_stmt_bind_param(c.fprepstatement,inputbindings) <> 0 then begin + checkstmterror(serrexecuting,c.fprepstatement); + end; + if mysql_stmt_execute(c.fprepstatement) <> 0 then begin + checkstmterror(serrexecuting,c.fprepstatement); + end; + if myo_storeresult in foptions then begin + if mysql_stmt_store_result(c.fprepstatement) <> 0 then begin + checkstmterror(serrexecuting,c.fprepstatement); + end; + if myo_storeresult in foptions then begin + c.frowsreturned:= mysql_stmt_num_rows(c.fprepstatement); + end; + end; + finally + freebindingbuffers(paramdata); + freebindings(inputbindings); + end; + C.fRowsAffected := mysql_stmt_affected_rows(c.fprepstatement); + C.LastInsertID := mysql_stmt_insert_id(c.fprepstatement); + end + else begin //not prepared + if Assigned(AParams) and (aparams.count > 0) then begin + mstr1:= aparams.expandvalues(c.fstatementm, + c.parambinding,c.paramreplacestring); + end + else begin + mstr1:= c.fstatementm; + end; + if autf8 then begin + str1:= stringtoutf8ansi(mstr1); + end + else begin + str1:= ansistring(mstr1); + end; + doexecuteunprepared(c,atransaction,str1); + end; +// if not C.FNeedData then begin +// c.frowsreturned:= 0; +// end; +end; + +procedure tmysqlconnection.internalexecuteunprepared(const cursor: tsqlcursor; + const atransaction: tsqltransaction; const asql: string; + const origsql: msestring; const aparams: tmseparams); +var + C: tmysqlcursor; +begin + C:= tmysqlcursor(cursor); + c.frowsaffected:= -1; + c.frowsreturned:= -1; + c.fneeddata:= c.FStatementType in datareturningtypes; + if not C.FNeedData then begin + c.frowsreturned:= 0; + end; + freeresultbuffer(c); + doexecuteunprepared(c,atransaction,asql); +end; + +//function tmysqlconnection.MySQLDataType(AType: enum_field_types; ASize, ADecimals: Integer; +// var NewType: TFieldType; var NewSize: Integer): Boolean; +function tmysqlconnection.MySQLDataType(const afield: mysql_field; + const charsetinfo: my_charset_info; + out NewType: TFieldType; out NewSize: Integer; + out newprecision: integer): Boolean; +begin + Result := True; + NewSize:= 0; + newprecision:= 0; + with afield do begin + case ftype of + FIELD_TYPE_TINY,FIELD_TYPE_SHORT,FIELD_TYPE_LONG: begin + NewType:= ftInteger; + end; + FIELD_TYPE_LONGLONG,FIELD_TYPE_INT24: begin + newtype:= ftlargeint; + end; + {$ifdef mysql50} + FIELD_TYPE_NEWDECIMAL, + {$endif} + FIELD_TYPE_DECIMAL: begin + newprecision:= length - 2; + if (Decimals <= 4) or not (dbo_bcdtofloatif in controller.options) then begin + if newprecision > maxprecision then begin + newprecision:= maxprecision; + end; + newsize:= decimals; + if newsize > 4 then begin + newsize:= 4; + end; + NewType:= ftBCD; + end + else begin + NewType:= ftFloat; + end; + end; + FIELD_TYPE_FLOAT,FIELD_TYPE_DOUBLE: begin + NewType:= ftFloat; + end; + FIELD_TYPE_TIMESTAMP,FIELD_TYPE_DATETIME: begin + NewType:= ftDateTime; + end; + FIELD_TYPE_DATE: begin + NewType:= ftDate; + end; + FIELD_TYPE_TIME: begin + NewType:= ftTime; + end; + FIELD_TYPE_VAR_STRING,FIELD_TYPE_STRING,FIELD_TYPE_ENUM, + FIELD_TYPE_SET: begin + NewType:= ftString; + NewSize:= length; + if charsetinfo.mbmaxlen > 0 then begin + newsize:= newsize div charsetinfo.mbmaxlen; + end; + end; + {$ifdef mysql41} + field_type_blob: begin + newsize:= sizeof(integer); + if charsetnr = 63 then begin //binary + newtype:= ftblob; + end + else begin + newtype:= ftmemo; + end; + end; + {$endif} + else begin + Result:= False; + end; + end; + end; +end; + +procedure tmysqlconnection.AddFieldDefs(const cursor: TSQLCursor; + const FieldDefs: TfieldDefs); +var + C: tmysqlcursor; + I,TF,FC: Integer; + field: PMYSQL_FIELD; + DFT: TFieldType; + DFS: Integer; + precision: integer; + fd: tfielddef; + str1: ansistring; + res1: pmysql_res; + charsetinfo: my_charset_info; +begin + fielddefs.clear; + C:= tmysqlcursor(cursor); + mysql_get_character_set_info(c.fconn,@charsetinfo); + if c.fprepstatement <> nil then begin + fc:= c.fresultfieldcount; + c.fresultbindinginfo:= nil; //initialize with zeros + setlength(c.fresultbindinginfo,fc); + res1:= mysql_stmt_result_metadata(c.fprepstatement); + end + else begin + If (C.FRes=Nil) then begin + checkerror(SErrNoQueryResult,c.fconn); + end; + res1:= c.fres; + FC:= mysql_num_fields(res1); + end; + + SetLength(c.MapDSRowToMSQLRow,FC); + TF := 1; + For I:= 0 to FC-1 do begin + field := mysql_fetch_field_direct(res1, I); + with field^ do begin + if (flags and (pri_key_flag or auto_increment_flag) = + (pri_key_flag or auto_increment_flag)) then begin + c.fprimarykeyfieldname:= name; + end; + end; + if MySQLDataType(field^,charsetinfo,DFT,DFS,precision) then begin + if not(dft in varsizefields) then begin + dfs:= 0; + end; + c.MapDSRowToMSQLRow[TF-1] := I; + if c.fprepstatement <> nil then begin + setupresultbinding(i,dft,dfs,c.fresultbindings,c.fresultbindinginfo); + end; + if (dft = ftmemo) and (cursor.stringmemo) then begin + dft:= ftstring; + dfs:= 0; + end; + str1:= field^.name; + + fd:= TFieldDef.Create(nil,str1,DFT,DFS,False,TF); + fd.collection:= fielddefs; + if dft = ftbcd then begin + fd.precision:= precision; + end; + inc(TF); + end + end; + if (c.fprepstatement <> nil) and (res1 <> nil) then begin + freebindingbuffers(c.fresultbuf); //could be refresh operation + c.fresultbuf:= createbindingbuffers(c.fresultbindings,c.fresultbindinginfo); + mysql_free_result(res1); + if mysql_stmt_bind_result(c.fprepstatement,c.fresultbindings) <> 0 then begin + checkstmterror(sbindresult,c.fprepstatement); + end; + end; +end; + +function tmysqlconnection.Fetch(cursor: TSQLCursor): boolean; + +Var + C : tmysqlcursor; + int1: integer; +begin + C:= tmysqlcursor(cursor); + if c.fprepstatement <> nil then begin + int1:= mysql_stmt_fetch(c.fprepstatement); + result:= int1 <> mysql_no_data; + if result and (int1 <> 0) and (int1 <> mysql_data_truncated) then begin + checkstmterror(serrfetchingdata,c.fprepstatement); + end; + end + else begin + C.Row:=MySQL_Fetch_row(C.FRes); + Result:=(C.Row<>Nil); + end; + if not result then begin + freeresultbuffer(c); + end; +end; + +function tmysqlconnection.loadfield(const cursor: tsqlcursor; + const datatype: tfieldtype; const fieldnum: integer; //null based + const abuffer: pointer; var abufsize: integer; + const aisutf8: boolean): boolean; + //if bufsize < 0 -> buffer was to small, should be -bufsize + +var + field: PMYSQL_FIELD; + row : MYSQL_ROW; + C : tmysqlcursor; + fno: integer; + alen: integer; + int1: integer; + str1: ansistring; + index1: integer; + + procedure loadblob; + begin + with c.fresultbindinginfo[index1] do begin + setlength(str1,length); + if length > 0 then begin + setbindingbuffer(c.fresultbindings,index1,pointer(str1),length); + int1:= mysql_stmt_fetch_column(c.fprepstatement, + getbind(c.fresultbindings,index1),index1,0); + setbindingbuffer(c.fresultbindings,index1,nil,0); + if int1 <> 0 then begin + checkstmterror(serrfetchingdata,c.fprepstatement); + end; + end; + end; + end; + +begin + str1:= ''; + result:= false; + C:= tmysqlcursor(Cursor); + fno:= fieldnum; + if c.fprepstatement <> nil then begin + index1:= c.MapDSRowToMSQLRow[fno]; + with c.fresultbindinginfo[index1] do begin + result:= not isnull; + if abuffer = nil then begin + exit; //check null state + end; + if result then begin + case datatype of //todo: blobs + ftinteger,ftsmallint,ftword: begin + pinteger(abuffer)^:= pinteger(buffer)^; + end; + ftlargeint: begin + pint64(abuffer)^:= pint64(buffer)^; + end; + ftfloat: begin + pdouble(abuffer)^:= pdouble(buffer)^; + end; + ftbcd: begin + pcurrency(abuffer)^:= pdouble(buffer)^; + end; + ftdate,fttime,ftdatetime: begin + pdatetime(abuffer)^:= mysql_timetodatetime(pmysql_time(buffer)^); + end; + ftstring: begin + if length > abufsize then begin + abufsize:= -length; + end + else begin + if isblob then begin //stringmemo + loadblob; + move(pointer(str1)^,abuffer^,length); + abufsize:= length; + end + else begin + move(buffer^,abuffer^,length); + abufsize:= length; + end; + end; + end; + ftblob,ftgraphic,ftmemo: begin + loadblob; + int1:= cursor.addblobdata(pchar(str1),system.length(str1)); + pinteger(abuffer)^:= int1; //save id + end; + else begin + result:= false; //not suported + end; + end; + end; + end; + end + else begin + if C.Row=nil then + begin + // Writeln('LoadFieldsFromBuffer: row=nil'); + checkerror(SErrFetchingData,c.fconn); + end; + Row:=C.Row; + + inc(Row,c.MapDSRowToMSQLRow[fno]); +// inc(row,fno); + if row^ <> nil then begin + if abuffer = nil then begin + result:= true; + exit; + end; + field:= mysql_fetch_field_direct(C.FRES,c.MapDSRowToMSQLRow[fno]); + if datatype = ftstring then begin + // alen:= strlen(row^); +{$ifdef FPC} + alen:= mysql_fetch_lengths(c.fres)[c.MapDSRowToMSQLRow[fno]]; +{$else} + alen:= pculongaty(mysql_fetch_lengths(c.fres))^[c.MapDSRowToMSQLRow[fno]]; +{$endif} + if abufsize < alen then begin + abufsize:= -alen; + result:= true; + exit; + end + else begin + abufsize:= alen; + end; + end + else begin + if datatype in [ftmemo,ftgraphic,ftblob] then begin +{$ifdef FPC} + alen:= mysql_fetch_lengths(c.fres)[c.MapDSRowToMSQLRow[fno]]; +{$else} + alen:= pculongaty(mysql_fetch_lengths(c.fres))^[c.MapDSRowToMSQLRow[fno]]; +{$endif} + end + else begin + alen:= field^.length; + end; + end; + Result:= MySQLWriteData(cursor, field^.ftype,alen, + DataType,Row^,aBuffer); + end; + end; +end; + +function tmysqlconnection.fetchblob(const cursor: tsqlcursor; + const fieldnum: integer): ansistring; +var + int1: integer; + row1: MYSQL_ROW; +begin + result:= ''; + with tmysqlcursor(cursor) do begin + if row <> nil then begin + int1:= MapDSRowToMSQLRow[fieldnum]; + row1:= row; + inc(row1,int1); +{$ifdef FPC} + setlength(result,mysql_fetch_lengths(fres)[int1]); +{$else} + setlength(result,pculongaty(mysql_fetch_lengths(fres))^[int1]); +{$endif} + if result <> '' then begin + move(row1^^,result[1],length(result)); + end; + end; + end; +end; + +function InternalStrToFloat(S: string): Extended; + +var + I: Integer; + Tmp: string; + +begin + Tmp := ''; + for I := 1 to Length(S) do + begin + if not (S[I] in ['0'..'9', '+', '-', 'E', 'e']) then + Tmp := Tmp + {$ifdef FPC}defaultformatsettings.{$endif}DecimalSeparator + else + Tmp := Tmp + S[I]; + end; + Result := StrToFloat(Tmp); +end; + +function InternalStrToCurrency(S: string): Extended; + +var + I: Integer; + Tmp: string; + +begin + Tmp := ''; + for I := 1 to Length(S) do + begin + if not (S[I] in ['0'..'9', '+', '-', 'E', 'e']) then + Tmp := Tmp + {$ifdef FPC}defaultformatsettings.{$endif}DecimalSeparator + else + Tmp := Tmp + S[I]; + end; + Result := StrToCurr(Tmp); +end; + +function InternalStrToDate(S: string): TDateTime; + +var + EY, EM, ED: Word; + +begin + EY := StrToInt(Copy(S,1,4)); + EM := StrToInt(Copy(S,6,2)); + ED := StrToInt(Copy(S,9,2)); + if (EY = 0) or (EM = 0) or (ED = 0) then + Result:=0 + else + Result:=EncodeDate(EY, EM, ED); +end; + +function InternalStrToDateTime(S: string): TDateTime; + +var + EY, EM, ED: Word; + EH, EN, ES: Word; + +begin + EY := StrToInt(Copy(S, 1, 4)); + EM := StrToInt(Copy(S, 6, 2)); + ED := StrToInt(Copy(S, 9, 2)); + EH := StrToInt(Copy(S, 12, 2)); + EN := StrToInt(Copy(S, 15, 2)); + ES := StrToInt(Copy(S, 18, 2)); + if (EY = 0) or (EM = 0) or (ED = 0) then + Result := 0 + else + Result := EncodeDate(EY, EM, ED); + Result := Result + EncodeTime(EH, EN, ES, 0); +end; + +function InternalStrToTime(S: string): TDateTime; + +var + EH, EM, ES: Word; + +begin + EH := StrToInt(Copy(S, 1, 2)); + EM := StrToInt(Copy(S, 4, 2)); + ES := StrToInt(Copy(S, 7, 2)); + Result := EncodeTime(EH, EM, ES, 0); +end; + +function InternalStrToTimeStamp(S: string): TDateTime; + +var + EY, EM, ED: Word; + EH, EN, ES: Word; + +begin +{$IFNDEF mysql40} + EY := StrToInt(Copy(S, 1, 4)); + EM := StrToInt(Copy(S, 6, 2)); + ED := StrToInt(Copy(S, 9, 2)); + EH := StrToInt(Copy(S, 12, 2)); + EN := StrToInt(Copy(S, 15, 2)); + ES := StrToInt(Copy(S, 18, 2)); +{$ELSE} + EY := StrToInt(Copy(S, 1, 4)); + EM := StrToInt(Copy(S, 5, 2)); + ED := StrToInt(Copy(S, 7, 2)); + EH := StrToInt(Copy(S, 9, 2)); + EN := StrToInt(Copy(S, 11, 2)); + ES := StrToInt(Copy(S, 13, 2)); +{$ENDIF} + if (EY = 0) or (EM = 0) or (ED = 0) then + Result := 0 + else + Result := EncodeDate(EY, EM, ED); + Result := Result + EncodeTime(EH, EN, ES, 0);; +end; + +function tmysqlconnection.MySQLWriteData(const acursor: tsqlcursor; + AType: enum_field_types;ASize: Integer; + AFieldType: TFieldType;Source, Dest: PChar): Boolean; + +var + VI: Integer; + VL: largeint; + VF: Double; + VC: Currency; + VD: TDateTime; + Src : String; + int1: integer; +begin + Result:= False; + if Source = Nil then begin + exit; + end; + Result:= True; + case afieldtype of + ftstring: begin + Move(Source^, Dest^, ASize) + end; + ftblob,ftmemo: begin + int1:= acursor.addblobdata(source,asize); + move(int1,dest^,sizeof(int1)); + //save id + end; + else begin + Src:=StrPas(Source); + case AType of + FIELD_TYPE_TINY, FIELD_TYPE_SHORT, FIELD_TYPE_LONG, + FIELD_TYPE_INT24: + begin + if (Src<>'') then + VI := StrToInt(Src) + else + VI := 0; + Move(VI, Dest^, SizeOf(Integer)); + end; + FIELD_TYPE_LONGLONG: + begin + if (Src<>'') then + VL := StrToInt64(Src) + else + VL := 0; + Move(VL, Dest^, SizeOf(LargeInt)); + end; +{$ifdef mysql50} + FIELD_TYPE_NEWDECIMAL, +{$endif} + FIELD_TYPE_DECIMAL, FIELD_TYPE_FLOAT, FIELD_TYPE_DOUBLE: + if AFieldType = ftBCD then + begin + VC := InternalStrToCurrency(Src); + Move(VC, Dest^, SizeOf(Currency)); + end + else + begin + if Src <> '' then + VF := InternalStrToFloat(Src) + else + VF := 0; + Move(VF, Dest^, SizeOf(Double)); + end; + FIELD_TYPE_TIMESTAMP: + begin + if Src <> '' then + VD := InternalStrToTimeStamp(Src) + else + VD := 0; + Move(VD, Dest^, SizeOf(TDateTime)); + end; + FIELD_TYPE_DATETIME: + begin + if Src <> '' then + VD := InternalStrToDateTime(Src) + else + VD := 0; + Move(VD, Dest^, SizeOf(TDateTime)); + end; + FIELD_TYPE_DATE: + begin + if Src <> '' then + VD := InternalStrToDate(Src) + else + VD := 0; + Move(VD, Dest^, SizeOf(TDateTime)); + end; + FIELD_TYPE_TIME: + begin + if Src <> '' then + VD := InternalStrToTime(Src) + else + VD := 0; + Move(VD, Dest^, SizeOf(TDateTime)); + end; + FIELD_TYPE_VAR_STRING, FIELD_TYPE_STRING, FIELD_TYPE_ENUM, FIELD_TYPE_SET: + begin +// if Src<> '' then + Move(Source^, Dest^, ASize) +// else +// Dest^ := #0; + end; + field_type_blob: begin + int1:= acursor.addblobdata(source,asize); + move(int1,dest^,sizeof(int1)); + //save id + end; + end; + end; + end; +end; + +procedure tmysqlconnection.UpdateIndexDefs(var IndexDefs : TIndexDefs; + const aTableName : string; const acursor: tsqlcursor); +var + qry: tsqlresult; + keynamef,{filednamef,}columnnamef,nonuniquef: tdbcol; + str1: string; +begin + if not assigned(Transaction) then begin + DatabaseError(SErrConnTransactionnSet); + end; + qry:= tsqlresult.Create(nil); + try + with qry do begin + database:= Self; + sql.text:= 'show index from ' + msestring(aTableName); + active:= true; + keynamef:= datacols.colbyname('Key_name'); + columnnamef:= datacols.colbyname('Column_name'); + nonuniquef:= datacols.colbyname('Non_unique'); + while not eof do begin + with IndexDefs.AddIndexDef do begin + Name:= trim(keynamef.asstring); + if Name = 'PRIMARY' then begin + options:= options + [ixPrimary]; + end; + if nonuniquef.asinteger = 0 then begin + options:= options + [ixUnique]; + end; + str1:= ''; + repeat + str1:= str1 + trim(columnnamef.asstring) + ';'; + qry.next; + until qry.eof or (name <> keynamef.asstring); + setlength(str1,length(str1)-1); //remove last ';' + fields:= str1; + end; + end; + end; + finally + qry.free; + end; +end; + +function tmysqlconnection.GetTransactionHandle(trans: TSQLHandle): pointer; +begin + Result:= trans; +end; + +procedure tmysqlconnection.begintrans(const aconnection: pmysql; + const aparams: ansistring); +var + str1: ansistring; +begin + str1:= 'START TRANSACTION '+aparams; + if mysql_real_query(aconnection,pointer(str1),length(str1)) <> 0 then begin + checkerror(serrstarttransaction,aconnection); + end; +end; + +function tmysqlconnection.Commit(trans: TSQLHandle): boolean; +begin + with tmysqltrans(trans) do begin + if mysql_query(fconn,'COMMIT') <> 0 then begin + checkerror(serrcommittransaction,fconn); + end; + end; + result:= true; +end; + +function tmysqlconnection.RollBack(trans: TSQLHandle): boolean; +begin + with tmysqltrans(trans) do begin + if mysql_query(fconn,'ROLLBACK') <> 0 then begin + checkerror(serrrollbacktransaction,fconn); + end; + end; + result:= true; +end; + +procedure tmysqlconnection.internalCommitRetaining(trans: TSQLHandle); +begin + with tmysqltrans(trans) do begin + if mysql_query(fconn,'COMMIT AND CHAIN') <> 0 then begin + checkerror(serrcommittransaction,fconn); + end; + end; +end; + +procedure tmysqlconnection.internalRollBackRetaining(trans: TSQLHandle); +begin + with tmysqltrans(trans) do begin + if mysql_query(fconn,'ROLLBACK AND CHAIN') <> 0 then begin + checkerror(serrrollbacktransaction,fconn); + end; + end; +end; + +function tmysqlconnection.StartdbTransaction(const trans: TSQLHandle; + const AParams: tstringlist): boolean; +begin + with tmysqltrans(trans) do begin + if fconn = nil then begin + if not ftransactionconnectionused then begin + fconn:= self.fmysql1; + ftransactionconnectionused:= true; + end + else begin + openconnection(fconn); + end; + end; + begintrans(fconn,aparams.text); + end; + result:= true; +end; + +function tmysqlconnection.CreateBlobStream(const Field: TField; + const Mode: TBlobStreamMode; const acursor: tsqlcursor): TStream; +var + blobid: integer; +// int1,int2: integer; +// str1: string; +// bo1: boolean; +begin + result:= nil; + if mode = bmread then begin + if field.getData(@blobId) then begin + result:= acursor.getcachedblob(blobid); + end; + end; +end; + +function tmysqlconnection.getblobdatasize: integer; +begin + result:= sizeof(integer); +end; +{ +function tmysqlconnection.getfeatures(): databasefeaturesty; +begin + result:= inherited getfeatures() + [dbf_blobscached]; +end; +} +procedure tmysqlconnection.writeblobdata(const atransaction: tsqltransaction; + const tablename: string; const acursor: tsqlcursor; + const adata: pointer; const alength: integer; + const afield: tfield; const aparam: tparam; out newid: string); +var + str1: string; + int1: integer; +begin + setlength(str1,alength); + move(adata^,str1[1],alength); + if afield.datatype = ftmemo then begin + aparam.asmemo:= str1; + end + else begin + aparam.asblob:= str1; + end; + int1:= acursor.addblobdata(str1); + setlength(newid,sizeof(int1)); + move(int1,newid[1],sizeof(int1)); +end; + +procedure tmysqlconnection.setupblobdata(const afield: tfield; + const acursor: tsqlcursor; const aparam: tparam); +begin + acursor.blobfieldtoparam(afield,aparam,false); +end; +{ +function tmysqlconnection.blobscached: boolean; +begin + result:= true; +end; +} +function tmysqlconnection.getprimarykeyfield(const atablename: string; + const acursor: tsqlcursor): string; +begin + result:= tmysqlcursor(acursor).fprimarykeyfieldname; +end; + +function tmysqlconnection.getinsertid(const atransaction: tsqltransaction): int64; +begin + result:= mysql_insert_id(tmysqltrans(atransaction.trans).fconn); +end; + +procedure tmysqlconnection.updateprimarykeyfield(const afield: tfield; + const atransaction: tsqltransaction); +begin + if afield.datatype in integerfields then begin + afield.aslargeint:= getinsertid(atransaction); + end; + { + with tmsebufdataset1(afield.dataset) do begin + setcurvalue(afield,getinsertid); + end; + } +end; + +function tmysqlconnection.identquotechar: msestring; +begin + result:= '`'; //needed for reserved words as fieldnames +end; + +procedure tmysqlconnection.createdatabase(const asql: ansistring); +var + bo1: boolean; + po1: pmysql_res; +begin + initializemysql([]); + try + bo1:= fmysql1 = nil; + if bo1 then begin + ConnectMySQL(fmysql1,pchar(hostname),pchar(username),pchar(password)); + end; + try + if mysql_real_query(fmysql1,pointer(asql),length(asql)) <> 0 then begin + checkerror(serrstarttransaction,fmysql1); + end; + po1:= mysql_store_result(fmysql1); + if po1 <> nil then begin + mysql_free_result(po1); + end; + finally + if bo1 then begin + closeconnection(fmysql1); + end; + end; + finally + releasemysql; + end; +end; + +{ emysqlerror } + +constructor emysqlerror.create(const asender: tcustomsqlconnection; + const amessage: ansistring; const aerrormessage: msestring; + const aerror: integer; const asqlcode: string); +begin + fsqlcode:= asqlcode; + inherited create(asender,amessage,aerrormessage,aerror); +end; + +end. diff --git a/mseide-msegui/lib/common/db/modbcconn.pas b/mseide-msegui/lib/common/db/modbcconn.pas new file mode 100644 index 0000000..3e2e89c --- /dev/null +++ b/mseide-msegui/lib/common/db/modbcconn.pas @@ -0,0 +1,1818 @@ +{****************************************************************************** + * * + * (c) 2005 Hexis BV * + * * + * File: odbcconn.pas * + * Author: Bram Kuijvenhoven (bkuijvenhoven@eljakim.nl) * + * Description: ODBC SQLDB unit * + * License: (modified) LGPL * + * * + * Modified 2006-2013 by Martin Schreiber * + ******************************************************************************} + +unit modbcconn; + +{$ifdef FPC}{$mode objfpc}{$H+}{$endif} + +interface + +uses + classes,mclasses,SysUtils, msqldb, mdb, odbcsqldyn,msetypes,msedb,msestrings; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + + // forward declarations + TODBCConnection = class; + + { TODBCCursor } + + TODBCCursor = class(TSQLCursor) + protected + fconnection: todbcconnection; + ffieldnames: stringarty; + FSTMTHandle:SQLHSTMT; // ODBC Statement Handle + FQuery:string; // last prepared query, with :ParamName converted to ? + FParamIndex:TParamBinding; // maps the i-th parameter in the query to the TParams passed to PrepareStatement + FParamBuf:array of pointer; // buffers that can be used to bind the i-th parameter in the query +// FBlobStreams:TList; // list of Blob TMemoryStreams stored in field buffers (we need this currently as we can't hook into the freeing of TBufDataset buffers) + fcurrentblobbuffer: ansistring; + public + constructor Create(const aowner: icursorclient; const aname: ansistring; + const Connection:TODBCConnection); + destructor Destroy; override; + procedure close; override; + end; + + { TODBCHandle } // this name is a bit confusing, but follows the standards for naming classes in sqldb + + TODBCHandle = class(TSQLHandle) + protected + end; + + { TODBCEnvironment } + + TODBCEnvironment = class + private + finitialized: boolean; + protected + FENVHandle:SQLHENV; // ODBC Environment Handle + public + constructor Create; + destructor Destroy; override; + end; + + { TODBCConnection } + + TODBCConnection = class(TSQLConnection,iblobconnection) + private + FDriver: string; + FEnvironment:TODBCEnvironment; + FDBCHandle:SQLHDBC; // ODBC Connection Handle + FFileDSN: string; + + procedure SetParameters(ODBCCursor:TODBCCursor; AParams:TmseParams); + procedure FreeParamBuffers(ODBCCursor:TODBCCursor); + protected + procedure ODBCCheckResult( + LastReturnCode:SQLRETURN; HandleType:SQLSMALLINT; + AHandle: SQLHANDLE; ErrorMsg: string); overload; + + procedure ODBCCheckResult( + LastReturnCode:SQLRETURN; HandleType:SQLSMALLINT; + AHandle: SQLHANDLE; ErrorMsg: string; + const values: array of const); overload; + // Overrides from TSQLConnection + function GetHandle:pointer; override; + // - Connect/disconnect + procedure DoInternalConnect; override; + procedure DoInternalDisconnect; override; + // - Handle (de)allocation + function AllocateTransactionHandle:TSQLHandle; override; + // - Statement handling + + // - Transaction handling + function GetTransactionHandle(trans:TSQLHandle):pointer; override; + function StartDBTransaction(const trans:TSQLHandle; + const AParams: tstringlist):boolean; override; + function Commit(trans:TSQLHandle):boolean; override; + function Rollback(trans:TSQLHandle):boolean; override; + procedure internalCommitRetaining(trans:TSQLHandle); override; + procedure internalRollbackRetaining(trans:TSQLHandle); override; + // - Statement execution + procedure updaterowcount(const acursor: todbccursor); + procedure internalExecute(const cursor:TSQLCursor; + const ATransaction:TSQLTransaction; const AParams:TmseParams; + const autf8: boolean); override; + procedure internalexecuteunprepared(const cursor: tsqlcursor; + const atransaction: tsqltransaction; const asql: string; + const origsql: msestring; const aparams: tmseparams); override; + + + function CreateBlobStream(const Field: TField; const Mode: TBlobStreamMode; + const acursor: tsqlcursor): TStream; override; + // - UpdateIndexDefs + procedure UpdateIndexDefs(var IndexDefs:TIndexDefs; + const aTableName:string; const acursor: tsqlcursor); override; + // - Schema info + function GetSchemaInfoSQL(SchemaType:TSchemaType; + SchemaObjectName, SchemaObjectPattern:msestring):msestring; override; + + // Internal utility functions + function CreateConnectionString:string; + function getblobdatasize: integer; override; +// function getfeatures(): databasefeaturesty override; + + //iblobconnection + procedure writeblobdata(const atransaction: tsqltransaction; + const tablename: string; const acursor: tsqlcursor; + const adata: pointer; const alength: integer; + const afield: tfield; const aparam: tparam; + out newid: string); + procedure setupblobdata(const afield: tfield; const acursor: tsqlcursor; + const aparam: tparam); +// function blobscached: boolean; + public + constructor create(aowner: tcomponent); override; + function AllocateCursorHandle(const aowner: icursorclient; + const aname: ansistring): TSQLCursor; override; + procedure DeAllocateCursorHandle(var cursor:TSQLCursor); override; + procedure preparestatement(const cursor: tsqlcursor; + const atransaction : tsqltransaction; + const asql: msestring; const aparams : tmseparams); override; + procedure UnPrepareStatement(cursor:TSQLCursor); override; + // - Result retrieving + procedure AddFieldDefs(const cursor:TSQLCursor; + const FieldDefs:TFieldDefs); override; + function Fetch(cursor:TSQLCursor):boolean; override; + function loadfield(const cursor: tsqlcursor; + const datatype: tfieldtype; const fieldnum: integer; //null based + const buffer: pointer; var bufsize: integer; + const aisutf8: boolean): boolean; override; + //if bufsize < 0 -> buffer was to small, should be -bufsize + procedure FreeFldBuffers(cursor:TSQLCursor); override; + property Environment:TODBCEnvironment read FEnvironment; + published + property Driver:string read FDriver write FDriver; // will be passed as DRIVER connection parameter + property FileDSN:string read FFileDSN write FFileDSN; // will be passed as FILEDSN parameter + // Redeclare properties from TSQLConnection + property Password; // will be passed as PWD connection parameter + property Transaction; + property UserName; // will be passed as UID connection parameter + property CharSet; + property HostName; // ignored + // Redeclare properties from TmDatabase + property Connected; + property Role; + property DatabaseName; // will be passed as DSN connection parameter + property KeepConnection; +// property LoginPrompt; // if true, ODBC drivers might prompt for more details that are not in the connection string + property Params; // will be added to connection string +// property OnLogin; + property ongetcredentials; + end; + + EODBCException = class(Exception) + // currently empty; perhaps we can add fields here later that describe the error instead of one simple message string + end; + +implementation +uses + Math, {$ifdef FPC}DBConst{$else}dbconst_del{$endif},msedatabase; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{$define ODBCVER3} + +(* odbc type nums +internal enum SQL_TYPE : short + { + BIGINT = (-5), + BINARY = (-2), + BIT = (-7), + CHAR = 1, + DATE = 9, + DECIMAL = 3, + DOUBLE = 8, + GUID = (-11), + INTEGER = 4, + INTERVAL_DAY = (100 + 3), + INTERVAL_DAY_TO_HOUR = (100 + 8), + INTERVAL_DAY_TO_MINUTE = (100 + 9), + INTERVAL_DAY_TO_SECOND = (100 + 10), + INTERVAL_HOUR = (100 + 4), + INTERVAL_HOUR_TO_MINUTE = (100 + 11), + INTERVAL_HOUR_TO_SECOND = (100 + 12), + INTERVAL_MINUTE = (100 + 5), + INTERVAL_MINUTE_TO_SECOND = (100 + 13), + INTERVAL_MONTH = (100 + 2), + INTERVAL_SECOND = (100 + 6), + INTERVAL_YEAR = (100 + 1), + INTERVAL_YEAR_TO_MONTH = (100 + 7), + LONGVARBINARY = (-4), + LONGVARCHAR = (-1), + NUMERIC = 2, + REAL = 7, + SMALLINT = 5, + TIME = 10, + TIMESTAMP = 11, + TINYINT = (-6), + TYPE_DATE = 91, + TYPE_TIME = 92, + TYPE_TIMESTAMP = 93, + VARBINARY = (-3), + VARCHAR = 12, + WCHAR = (-8), + WLONGVARCHAR = (-10), + WVARCHAR = (-9), + UNASSIGNED = Int16.MaxValue + } + + internal enum SQL_C_TYPE : short + { + BINARY = (-2), + BIT = (-7), + BOOKMARK = (4 +(-22)), + CHAR = 1, + DATE = 9, + DEFAULT = 99, + DOUBLE = 8, + FLOAT = 7, + GUID = (-11), + INTERVAL_DAY = (100 + 3), + INTERVAL_DAY_TO_HOUR = (100 + 8), + INTERVAL_DAY_TO_MINUTE = (100 + 9), + INTERVAL_DAY_TO_SECOND = (100 + 10), + INTERVAL_HOUR = (100 + 4), + INTERVAL_HOUR_TO_MINUTE = (100 + 11), + INTERVAL_HOUR_TO_SECOND = (100 + 12), + INTERVAL_MINUTE = (100 + 5), + INTERVAL_MINUTE_TO_SECOND = (100 + 13), + INTERVAL_MONTH = (100 + 2), + INTERVAL_SECOND = (100 + 6), + INTERVAL_YEAR = (100 + 1), + INTERVAL_YEAR_TO_MONTH = (100 + 7), + LONG = 4, + NUMERIC = 2, + SBIGINT = ((-5)+(-20)), + SHORT = 5, + SLONG = (4 +(-20)), + SSHORT = (5 +(-20)), + STINYINT = ((-6)+(-20)), + TCHAR = 1, + TIME = 10, + TIMESTAMP = 11, + TINYINT = (-6), + TYPE_DATE = 91, + TYPE_TIME = 92, + TYPE_TIMESTAMP = 93, + UBIGINT = ((-5)+(-22)), + ULONG = (4 +(-22)), + USHORT = (5 +(-22)), + UTINYINT = ((-6)+(-22)), + WCHAR = (-8), + UNASSIGNED = Int16.MaxValue + } +} +*) + +const + +{$ifdef ODBCVER3} + SQL_C_WCHAR = SQL_WCHAR; +{$endif} + + blobidsize = sizeof(integer); + maxstrlen = 3000; + maxprecision = 18; +var + DefaultEnvironment:TODBCEnvironment = nil; +// ODBCLoadCount:integer = 0; // ODBC is loaded when > 0; modified by TODBCEnvironment.Create/Destroy + +{ Generic ODBC helper functions } + +function ODBCSucces(const Res:SQLRETURN):boolean; +begin + Result:=(Res=SQL_SUCCESS) or (Res=SQL_SUCCESS_WITH_INFO) or + (res = SQL_NO_DATA); +end; + +function ODBCResultToStr(Res:SQLRETURN):string; +begin + case Res of + SQL_SUCCESS: Result:='SQL_SUCCESS'; + SQL_SUCCESS_WITH_INFO:Result:='SQL_SUCCESS_WITH_INFO'; + SQL_ERROR: Result:='SQL_ERROR'; + SQL_INVALID_HANDLE: Result:='SQL_INVALID_HANDLE'; + SQL_NO_DATA: Result:='SQL_NO_DATA'; + SQL_NEED_DATA: Result:='SQL_NEED_DATA'; + SQL_STILL_EXECUTING: Result:='SQL_STILL_EXECUTING'; + else + Result:=''; + end; +end; + +{ todbcconnection } + +constructor TODBCConnection.create(aowner: tcomponent); +begin + inherited; + fconnoptions:= fconnoptions + [sco_supportparams,sco_emulateretaining, + sco_blobscached]; +end; + +procedure todbcconnection.ODBCCheckResult( + LastReturnCode:SQLRETURN; HandleType:SQLSMALLINT; + AHandle: SQLHANDLE; ErrorMsg: string); + + // check return value from SQLGetDiagField/Rec function itself + procedure Check(const Res:SQLRETURN); + begin + case Res of + SQL_INVALID_HANDLE: + raise EODBCException.Create('Invalid handle passed to SQLGetDiagRec/Field'); + SQL_ERROR: + raise EODBCException.Create('An invalid parameter was passed to SQLGetDiagRec/Field'); + SQL_NO_DATA: + raise EODBCException.Create('A too large RecNumber was passed to SQLGetDiagRec/Field'); + end; + end; + +var + NativeError: SQLINTEGER; + reccount: sqlinteger; + TextLength:SQLSMALLINT; + Res:SQLRETURN; + SqlState,MessageText,TotalMessage:string; + RecNumber:SQLSMALLINT; + firstmessage: string; + firsterror: integer; +begin + // check result + if ODBCSucces(LastReturnCode) then begin + Exit; // no error; all is ok + end; + + firstmessage:= ''; + // build TotalMessage for exception to throw + TotalMessage:=Format('%s ODBC error details:',[ErrorMsg]); + // retrieve status records + check(sqlgetdiagfield(handletype,ahandle,0,SQL_DIAG_NUMBER,@reccount, + sizeof(reccount),textlength)); + //unixODBC crashes with too big rec number + + SetLength(SqlState,5); // SqlState buffer + firsterror:= 0; + for RecNumber:=1 to reccount do begin + // dummy call to get correct TextLength + Res:=SQLGetDiagRec(HandleType,AHandle,RecNumber,@(SqlState[1]), + NativeError,nil,0,TextLength); + if Res=SQL_NO_DATA then begin + Break; // no more status records + end; + Check(Res); + if TextLength>0 then begin + // if TextLength=0 we don't need another call; + // also our string buffer would not point to a #0, but be a nil pointer + // allocate large enough buffer + SetLength(MessageText,4*TextLength); + //reserve for multi-byte-encodings, ODBC bug? + // note: ansistrings of Length>0 are always terminated by a #0 character, so this is safe + // actual call + check(SQLGetDiagRec(HandleType,AHandle,RecNumber,@(SqlState[1]), + NativeError,@(MessageText[1]),Length(MessageText)+1,TextLength)); + end + else begin + messagetext:= ''; + end; + if firsterror = 0 then begin + firsterror:= nativeerror; + firstmessage:= strpas(pchar(messagetext)); + end; + // add to TotalMessage + TotalMessage:=TotalMessage + + Format(' Record %d: SqlState: %s; NativeError: %d; Message: %s;', + [RecNumber,SqlState,NativeError, + strpas(pchar(MessageText))]); + //string termination by #0, textlength seems to be unreliable + end; + // raise error +// raise EODBCException.Create(TotalMessage); + raise econnectionerror.create(self, + ansistring(connectionmessage(pchar(totalmessage))), + msestring(firstmessage),firsterror); +end; + +procedure todbcconnection.ODBCCheckResult( + LastReturnCode:SQLRETURN; HandleType:SQLSMALLINT; + AHandle: SQLHANDLE; ErrorMsg: string; + const values: array of const); +begin + if not ODBCSucces(LastReturnCode) then begin + odbccheckresult(lastreturncode,handletype,ahandle,format(errormsg,values)); + end; +end; + + +// Creates a connection string using the current value of the fields +function TODBCConnection.CreateConnectionString: string; + + // encloses a param value with braces if necessary, i.e. when any of the characters []{}(),;?*=!@ is in the value + function EscapeParamValue(const s:string):string; + var + NeedEscape:boolean; + i:integer; + begin + NeedEscape:=false; + for i:=1 to Length(s) do + if s[i] in ['[',']','{','}','(',')',',','*','=','!','@'] then + begin + NeedEscape:=true; + Break; + end; + if NeedEscape then + Result:='{'+s+'}' + else + Result:=s; + end; + +var + i: Integer; + Param: string; + EqualSignPos:integer; + u,p: msestring; + u1,p1: string; +begin + Result:=''; + getcredentials(u,p); + if charset <> '' then begin + result:= result + 'CHARSET='+ ansistring(charset)+';'; + end; + if DatabaseName<>'' then Result:=Result + 'DSN='+ + EscapeParamValue(ansistring(DatabaseName))+';'; + if Driver <>'' then Result:=Result + 'DRIVER='+EscapeParamValue(Driver)+';'; + if U <>'' then begin + u1:= ansistring(u); + p1:= ansistring(p); + Result:=Result + 'UID='+EscapeParamValue(U1)+';PWD='+ + EscapeParamValue(P1)+';'; + stringsafefree(u1,false); + stringsafefree(p1,false); + end; + freecredentials(u,p); + if FileDSN <>'' then Result:=Result + 'FILEDSN='+EscapeParamValue(FileDSN)+''; + for i:=0 to Params.Count-1 do + begin + Param:=Params[i]; + EqualSignPos:=Pos('=',Param); + if EqualSignPos=0 then + raise EODBCException.CreateFmt('Invalid parameter in Params[%d]; can''t find a ''='' in ''%s''',[i, Param]) + else if EqualSignPos=1 then + raise EODBCException.CreateFmt('Invalid parameter in Params[%d]; no identifier before the ''='' in ''%s''',[i, Param]) + else + Result:=Result + EscapeParamValue(Copy(Param,1,EqualSignPos-1))+'='+EscapeParamValue(Copy(Param,EqualSignPos+1,MaxInt))+';'; + end; +end; + +procedure TODBCConnection.writeblobdata(const atransaction: tsqltransaction; + const tablename: string; const acursor: tsqlcursor; + const adata: pointer; const alength: integer; + const afield: tfield; const aparam: tparam; + out newid: string); +var + str1: string; + int1: integer; +begin + setlength(str1,alength); + move(adata^,str1[1],alength); + if afield.datatype = ftmemo then begin + aparam.asmemo:= str1; + end + else begin + aparam.asblob:= str1; + end; + int1:= acursor.addblobdata(str1); + setlength(newid,sizeof(int1)); + move(int1,newid[1],sizeof(int1)); +end; + +procedure TODBCConnection.setupblobdata(const afield: tfield; + const acursor: tsqlcursor; const aparam: tparam); +begin +// acursor.blobfieldtoparam(afield,aparam,afield.datatype = ftmemo); + acursor.blobfieldtoparam(afield,aparam,false); +end; + +function TODBCConnection.getblobdatasize: integer; +begin + result:= sizeof(integer); +end; +{ +function TODBCConnection.getfeatures(): databasefeaturesty; +begin + result:= inherited getfeatures() + [dbf_blobscached]; +end; +} +{ +function TODBCConnection.blobscached: boolean; +begin + result:= true; +end; +} +procedure TODBCConnection.SetParameters(ODBCCursor: TODBCCursor; AParams: TmseParams); + + procedure bindnum(i: integer; valuetype: SQLSMALLINT; parametertype: SQLSMALLINT; + buf: pointer); + begin + ODBCCursor.FParamBuf[i]:=Buf; + ODBCCheckResult( + SQLBindParameter(ODBCCursor.FSTMTHandle, // StatementHandle + i+1, // ParameterNumber + SQL_PARAM_INPUT, // InputOutputType + valuetype, // ValueType + parametertype, // ParameterType + 1, // ColumnSize + 0, // DecimalDigits + Buf, // ParameterValuePtr + 0, // BufferLength + nil), // StrLen_or_IndPtr + SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, 'Could not bind parameter %d',[i] + ); + end; + + procedure bindstr(i: integer; valuetype: SQLSMALLINT; parametertype: SQLSMALLINT; + buf: pointer; strlen: sqlinteger; buflen: sqlinteger + ); + begin + psqlinteger(buf)^:= buflen; + ODBCCursor.FParamBuf[i]:=Buf; + ODBCCheckResult( + SQLBindParameter(ODBCCursor.FSTMTHandle, // StatementHandle + i+1, // ParameterNumber + SQL_PARAM_INPUT, // InputOutputType + valuetype, // ValueType + parametertype, // ParameterType + strlen, // ColumnSize + 0, // DecimalDigits + pchar(buf)+SizeOf(SQLINTEGER), // ParameterValuePtr + buflen, // BufferLength + buf), // StrLen_or_IndPtr + SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, 'Could not bind parameter %d',[i]); + end; + + procedure bindnull(i: integer; valuetype: sqlsmallint; parametertype: sqlsmallint); + var + buf: psqllen; + begin + getmem(buf,sizeof(sqllen)); + ODBCCursor.FParamBuf[i]:= Buf; + buf^:= SQL_NULL_DATA; + ODBCCheckResult( + SQLBindParameter(ODBCCursor.FSTMTHandle, // StatementHandle + i+1, // ParameterNumber + SQL_PARAM_INPUT, // InputOutputType + valuetype, // ValueType + parametertype, // ParameterType + 1, // ColumnSize + 0, // DecimalDigits + nil, // ParameterValuePtr + 0, // BufferLength + buf), // StrLen_or_IndPtr + SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, 'Could not bind parameter %d',[i]); + end; + +var + ParamIndex:integer; + Buf:pointer; + I:integer; +// IntVal:longint; +// largeintval: int64; + StrVal:string; +{$ifdef mswindows} + wideStrVal: msestring; + buflen: SQLINTEGER; +{$endif} +// doubleval: double; + StrLen{,buflen}: SQLINTEGER; +// isnull1: boolean; + datatype1: tfieldtype; + +begin + // Note: it is assumed that AParams is the same as the one passed to PrepareStatement, in the sense that + // the parameters have the same order and names + + if Length(ODBCCursor.FParamIndex)>0 then begin + if not Assigned(AParams) then begin + raise EODBCException.CreateFmt( + 'The query has parameter markers in it, but no actual parameters were passed', + []); + end; + end; + SetLength(ODBCCursor.FParamBuf, Length(ODBCCursor.FParamIndex)); + for i:=0 to High(ODBCCursor.FParamIndex) do begin + ParamIndex:= ODBCCursor.FParamIndex[i]; + if (ParamIndex<0) or (ParamIndex>=AParams.Count) then begin + raise EODBCException.CreateFmt( + 'Parameter %d in query does not have a matching parameter set',[i]); + end; + with AParams[ParamIndex] do begin +// isnull1:= isnull; + datatype1:= datatype; + case datatype1 of + ftInteger,ftboolean,ftword,ftsmallint: begin + if isnull then begin + bindnull(i,SQL_C_LONG,SQL_INTEGER); + end + else begin + GetMem(buf,sizeof(longint)); + plongint(buf)^:= AsInteger; + bindnum(i,SQL_C_LONG,SQL_INTEGER,buf); + end; + end; + ftlargeint: begin + if isnull then begin + bindnull(i,SQL_C_SBIGINT,SQL_BIGINT); + end + else begin + GetMem(buf,sizeof(int64)); + pint64(buf)^:= Aslargeint; + bindnum(i,SQL_C_SBIGINT,SQL_BIGINT,buf); + end; + end; + ftfloat,ftcurrency,ftbcd: begin + if isnull then begin + bindnull(i,SQL_C_CHAR,SQL_CHAR); + end + else begin + GetMem(buf,sizeof(double)); + pdouble(buf)^:= Asfloat; + bindnum(i,SQL_C_DOUBLE,SQL_DOUBLE,buf); + end; + end; + fttime,ftdate,ftdatetime: begin + if isnull then begin + bindnull(i,SQL_C_TYPE_TIMESTAMP,SQL_TYPE_TIMESTAMP); + end + else begin + GetMem(buf,sizeof(sql_timestamp_struct)); + datetime2timestampstruct(psql_timestamp_struct(buf)^,Asdatetime); + bindnum(i,SQL_C_TYPE_TIMESTAMP,SQL_TYPE_TIMESTAMP,buf); + end; + end; + ftguid: begin + if isnull then begin + bindnull(i,SQL_C_GUID,SQL_GUID); + end + else begin + GetMem(buf,sizeof(tguid)); + pguid(buf)^:= dbstringtoguid(asstring); + bindnum(i,SQL_C_guid,SQL_guid,buf); + end; + end; + ftblob,ftmemo: begin + if isnull then begin + bindnull(i,SQL_C_CHAR,SQL_CHAR); + end + else begin + StrVal:= asstring; + StrLen:= Length(StrVal); + GetMem(buf,StrLen+sizeof(sqlinteger)); + Move(StrVal[1],(pchar(buf)+sizeof(sqlinteger))^,StrLen); + if datatype1 = ftmemo then begin + bindstr(i,SQL_C_CHAR,SQL_LONGVARCHAR,buf,strlen,strlen) + end + else begin + bindstr(i,SQL_C_BINARY,SQL_LONGVARBINARY,buf,strlen,strlen) + end; + end; + end; + ftstring,ftfixedchar + {$ifndef mswindows},ftwidestring,ftfixedwidechar{$endif}: begin + if isnull then begin + bindnull(i,SQL_C_CHAR,SQL_CHAR); + end + else begin + StrVal:= AParams.AsdbString(paramindex); + StrLen:= Length(StrVal); + GetMem(buf,StrLen+sizeof(sqlinteger)); + Move(StrVal[1],(pchar(buf)+sizeof(sqlinteger))^,StrLen); + if strlen > maxstrlen then begin + bindstr(i,SQL_C_CHAR,SQL_LONGVARCHAR,buf,strlen,strlen) + end + else begin + bindstr(i,SQL_C_CHAR,SQL_CHAR,buf,strlen,strlen) + end; + end; + end; + ftbytes,ftvarbytes: begin + if isnull then begin + bindnull(i,SQL_C_BINARY,SQL_VARBINARY); + end + else begin + StrVal:= AParams[paramindex].AsString; + StrLen:= Length(StrVal); + GetMem(buf,StrLen+sizeof(sqlinteger)); + Move(StrVal[1],(pchar(buf)+sizeof(sqlinteger))^,StrLen); + if strlen > maxstrlen then begin + bindstr(i,SQL_C_BINARY,SQL_LONGVARBINARY,buf,strlen,strlen) + end + else begin + bindstr(i,SQL_C_BINARY,SQL_VARBINARY,buf,strlen,strlen) + end; + end; + end; + {$ifdef mswindows} + ftwidestring,ftfixedwidechar: begin + if isnull then begin + bindnull(i,SQL_C_WCHAR,SQL_WCHAR); + end + else begin + widestrval:= aparams[paramindex].aswidestring; + strlen:= length(widestrval); + buflen:= strlen*sizeof(msechar); + getmem(buf,buflen+sizeof(sqlinteger)); + move(widestrval[1],(pchar(buf)+sizeof(sqlinteger))^,buflen); + if strlen > maxstrlen then begin + bindstr(i,SQL_C_WCHAR,SQL_WLONGVARCHAR,buf,strlen,buflen); + end + else begin + bindstr(i,SQL_C_WCHAR,SQL_WCHAR,buf,strlen,buflen); + end; + // bindstr(i,SQL_C_WCHAR,SQL_WCHAR,buf,buflen,buflen); + end; + end; + {$endif} + else begin + if isnull then begin + bindnull(i,SQL_C_CHAR,SQL_CHAR); //dummy + end + else begin + raise EDataBaseError.CreateFmt( + 'Parameter %d is of type %s, which not supported yet', + [ParamIndex, Fieldtypenames[AParams[ParamIndex].DataType]]); + end; + end; + end; + end; + end; +end; + +procedure TODBCConnection.FreeParamBuffers(ODBCCursor: TODBCCursor); +var + i:integer; +begin + for i:=0 to High(ODBCCursor.FParamBuf) do begin + FreeMem(ODBCCursor.FParamBuf[i]); + end; + ODBCCursor.FParamBuf:= nil; +end; + +function TODBCConnection.GetHandle: pointer; +begin + // I'm not sure whether this is correct; perhaps we should return nil + // note that FDBHandle is a LongInt, because ODBC handles are integers, not pointers + // I wonder how this will work on 64 bit platforms then (FK) + Result:=pointer(FDBCHandle); +end; + +procedure TODBCConnection.DoInternalConnect; +const + BufferLength = 1024; // should be at least 1024 according to the ODBC specification +var + ConnectionString: string; + OutConnectionString: string; + ActualLength: SQLSMALLINT; +begin + // Do not call the inherited method as it checks for a non-empty DatabaseName, and we don't even use DatabaseName! + // inherited DoInternalConnect; + + // make sure we have an environment + if not Assigned(FEnvironment) then + begin + if DefaultEnvironment = nil then + DefaultEnvironment:= TODBCEnvironment.Create; + FEnvironment:=DefaultEnvironment; + end; + + // allocate connection handle + ODBCCheckResult( + SQLAllocHandle(SQL_HANDLE_DBC,Environment.FENVHandle,FDBCHandle), + SQL_HANDLE_ENV,Environment.FENVHandle,'Could not allocate ODBC Connection handle.' + ); + + // connect + ConnectionString:=CreateConnectionString; + SetLength(OutConnectionString,BufferLength); // allocate completed connection string buffer (using the ansistring #0 trick) + try + ODBCCheckResult( + SQLDriverConnect(FDBCHandle, // the ODBC connection handle + nil, // no parent window (would be required for prompts) + PChar(ConnectionString), // the connection string + Length(ConnectionString), // connection string length + @(OutConnectionString[1]),// buffer for storing the completed connection string + BufferLength, // length of the buffer + ActualLength, // the actual length of the completed connection string + SQL_DRIVER_NOPROMPT), // don't prompt for password etc. + SQL_HANDLE_DBC,FDBCHandle, + 'Could not connect with connection string "%s".',[ConnectionString] + ); + except + stringsafefree(connectionstring,false); + SQLFreeHandle(SQL_HANDLE_DBC, FDBCHandle); + fdbchandle:= nil; + raise; + end; + stringsafefree(connectionstring,false); + +// commented out as the OutConnectionString is not used further at the moment +// if ActualLength 0) then begin + str1:= todbstring(AParams.ParseSQL(asql,false,false,false,psInterbase, + ODBCCursor.FParamIndex)); + end + else begin + str1:= todbstring(asql); + end; + // prepare statement + ODBCCheckResult( + SQLPrepare(ODBCCursor.FSTMTHandle, PChar(str1), Length(str1)), + SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, 'Could not prepare statement.' + ); + + ODBCCursor.FQuery:= str1; + ODBCCursor.fprepared:= true; +end; + +procedure TODBCConnection.UnPrepareStatement(cursor: TSQLCursor); +begin + with todbccursor(cursor) do begin + FQuery:= ''; + fprepared:= false; + end; +end; + +function TODBCConnection.GetTransactionHandle(trans: TSQLHandle): pointer; +begin + result:= nil; + // Tranactions not implemented yet +end; + +function TODBCConnection.StartDBTransaction(const trans: TSQLHandle; + const AParams: tstringlist): boolean; +begin + result:= true; + // Tranactions not implemented yet +end; + +function TODBCConnection.Commit(trans: TSQLHandle): boolean; +begin + result:= true; + // Tranactions not implemented yet +end; + +function TODBCConnection.Rollback(trans: TSQLHandle): boolean; +begin + result:= true; + // Tranactions not implemented yet +end; + +procedure TODBCConnection.internalCommitRetaining(trans: TSQLHandle); +begin + // Tranactions not implemented yet +end; + +procedure TODBCConnection.internalRollbackRetaining(trans: TSQLHandle); +begin + // Tranactions not implemented yet +end; + +procedure todbcconnection.updaterowcount(const acursor: todbccursor); +var + len1: sqllen; + int1: sqlsmallint; +begin + with acursor do begin + if odbcsucces(sqlgetdiagfield(sql_handle_stmt,fstmthandle,0, + sql_diag_cursor_row_count,@len1,0,int1)) then begin + frowsreturned:= len1; + end; + if odbcsucces(sqlgetdiagfield(sql_handle_stmt,fstmthandle,0, + sql_diag_row_count,@len1,0,int1)) then begin + frowsaffected:= len1; + end; + end; +end; + +procedure TODBCConnection.internalExecute(const cursor: TSQLCursor; + const ATransaction: TSQLTransaction; const AParams: TmseParams; + const autf8: boolean); +var + ODBCCursor:TODBCCursor; + Res: SQLRETURN; +begin + ODBCCursor:= TODBCCursor(cursor); + odbccursor.frowsreturned:= -1; + odbccursor.frowsaffected:= -1; + + + // set parameters + if Assigned(APArams) and (AParams.count > 0) then begin + SetParameters(ODBCCursor, AParams); + end; + + // execute the statement + res:= SQLExecute(ODBCCursor.FSTMTHandle); + ODBCCheckResult(res, + SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, 'Could not execute statement.' + ); + updaterowcount(odbccursor); + // free parameter buffers + FreeParamBuffers(ODBCCursor); +end; + +procedure todbcconnection.internalexecuteunprepared(const cursor: tsqlcursor; + const atransaction: tsqltransaction; const asql: string; + const origsql: msestring; const aparams: tmseparams); +var + ODBCCursor:TODBCCursor; + Res: SQLRETURN; +begin + ODBCCursor:= TODBCCursor(cursor); + odbccursor.frowsreturned:= -1; + odbccursor.frowsaffected:= -1; + res:= SQLExecdirect(ODBCCursor.FSTMTHandle,pchar(asql),length(asql)); + ODBCCheckResult(res, + SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, 'Could not execute statement.' + ); + updaterowcount(odbccursor); +end; + +function TODBCConnection.Fetch(cursor: TSQLCursor): boolean; +var + ODBCCursor:TODBCCursor; + Res:SQLRETURN; +begin + ODBCCursor:= TODBCCursor(cursor); + + // fetch new row + Res:=SQLFetch(ODBCCursor.FSTMTHandle); + if Res<>SQL_NO_DATA then + ODBCCheckResult(Res,SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, + 'Could not fetch new row from result set'); + + // result is true iff a new row was available + Result:=Res<>SQL_NO_DATA; +end; + +function todbcconnection.loadfield(const cursor: tsqlcursor; + const datatype: tfieldtype; const fieldnum: integer; //null based + const buffer: pointer; var bufsize: integer; + const aisutf8: boolean): boolean; + //if bufsize < 0 -> buffer was to small, should be -bufsize + +//todo: optimize + +const + DEFAULT_BLOB_BUFFER_SIZE = 1024; +var + ODBCCursor:TODBCCursor; + StrLenOrInd:SQLINTEGER; + ODBCDateStruct:SQL_DATE_STRUCT; + ODBCTimeStruct:SQL_TIME_STRUCT; + ODBCTimeStampStruct:SQL_TIMESTAMP_STRUCT; + DateTime:TDateTime; +// BlobBuffer:pointer; + BlobBufferSize,BytesRead:SQLINTEGER; +// BlobMemoryStream:TMemoryStream; + Res:SQLRETURN; + targettype: sqlsmallint; + fno: integer; + int1: integer; + str1: string; + + buffer1: pointer; + bufsize1: integer; + memolen1: integer; + dummybuf: array [0..31] of byte; + do1: double; + cu1: currency; + +begin + str1:= ''; + ODBCCursor:= TODBCCursor(cursor); + + // load the field using SQLGetData + // Note: optionally we can implement the use of SQLBindCol later for even more speed + // TODO: finish this + + res:= 0; //ok + fno:= fieldnum+1; + bufsize1:= bufsize; + if buffer = nil then begin + buffer1:= @dummybuf; + bufsize1:= 0; + end + else begin + bufsize1:= bufsize; + buffer1:= buffer; + end; + + case DataType of + ftFixedChar,ftString: begin // are both mapped to TStringField + Res:= SQLGetData(ODBCCursor.FSTMTHandle, fno, + SQL_C_CHAR, buffer1, bufsize1{aField.Size}, @StrLenOrInd); + bufsize1:= strlenorind; + if bufsize1 > bufsize then begin + bufsize1:= -bufsize1; + end; + end; + ftwidestring,ftFixedWideChar: begin + Res:= SQLGetData(ODBCCursor.FSTMTHandle, fno, + SQL_C_WCHAR, buffer1, bufsize1{aField.Size}, @StrLenOrInd); + bufsize1:= strlenorind; + if bufsize1 > bufsize then begin + bufsize1:= -bufsize1; + end; + end; + ftSmallint: begin // mapped to TSmallintField + Res:=SQLGetData(ODBCCursor.FSTMTHandle, fno, SQL_C_SSHORT, buffer1, + SizeOf(Smallint), @StrLenOrInd); + end; + ftInteger,ftWord: begin // mapped to TLongintField + Res:=SQLGetData(ODBCCursor.FSTMTHandle, fno, SQL_C_SLONG, buffer1, + SizeOf(Longint), @StrLenOrInd); + end; + ftLargeint: begin // mapped to TLargeintField + Res:=SQLGetData(ODBCCursor.FSTMTHandle, fno, SQL_C_SBIGINT, buffer1, + SizeOf(Largeint), @StrLenOrInd); + end; + ftFloat,ftcurrency: begin // mapped to TFloatField + Res:=SQLGetData(ODBCCursor.FSTMTHandle, fno, SQL_C_DOUBLE, buffer1, + SizeOf(Double), @StrLenOrInd); + end; + ftbcd: begin + Res:=SQLGetData(ODBCCursor.FSTMTHandle, fno, SQL_C_DOUBLE, @do1, + SizeOf(Double), @StrLenOrInd); + if res = 0 then begin + cu1:= do1; + Move(cu1, buffer1^, SizeOf(cu1)); + end; + end; + ftTime: begin // mapped to TTimeField + Res:= SQLGetData(ODBCCursor.FSTMTHandle,fno,SQL_C_TYPE_TIME, + @ODBCTimeStruct, SizeOf(SQL_TIME_STRUCT),@StrLenOrInd); + if StrLenOrInd <> SQL_NULL_DATA then begin + DateTime:= TimeStructToDateTime(@ODBCTimeStruct); + Move(DateTime,buffer1^,SizeOf(TDateTime)); + end; + end; + ftDate: begin // mapped to TDateField + Res:=SQLGetData(ODBCCursor.FSTMTHandle, fno, SQL_C_TYPE_DATE, + @ODBCDateStruct, SizeOf(SQL_DATE_STRUCT), @StrLenOrInd); + if StrLenOrInd<>SQL_NULL_DATA then begin + DateTime:=DateStructToDateTime(@ODBCDateStruct); + Move(DateTime, buffer1^, SizeOf(TDateTime)); + end; + end; + ftDateTime: begin // mapped to TDateTimeField + Res:=SQLGetData(ODBCCursor.FSTMTHandle, fno, SQL_C_TYPE_TIMESTAMP, + @ODBCTimeStampStruct, SizeOf(SQL_TIMESTAMP_STRUCT), @StrLenOrInd); + if StrLenOrInd<>SQL_NULL_DATA then begin + DateTime:=TimeStampStructToDateTime(@ODBCTimeStampStruct); + Move(DateTime, buffer1^, SizeOf(TDateTime)); + end; + end; + ftBoolean: begin // mapped to TBooleanField + Res:=SQLGetData(ODBCCursor.FSTMTHandle, fno, SQL_C_BIT, buffer1, + SizeOf(Wordbool), @StrLenOrInd); + end; + ftBytes: begin // mapped to TBytesField + Res:=SQLGetData(ODBCCursor.FSTMTHandle, fno, SQL_C_BINARY, buffer1, + bufsize1{aField.Size}, @StrLenOrInd); + end; + ftVarBytes: begin // mapped to TVarBytesField + int1:= bufsize1-sizeof(word); + if int1 < 0 then begin + int1:= 0; + end; + Res:=SQLGetData(ODBCCursor.FSTMTHandle, fno, SQL_C_BINARY, + pchar(buffer1)+sizeof(word), + int1{aField.Size}, @StrLenOrInd); + pword(buffer1)^:= strlenorind; + end; + ftguid: begin + Res:=SQLGetData(ODBCCursor.FSTMTHandle, fno, SQL_C_GUID, buffer1, + SizeOf(tguid), @StrLenOrInd); + end; + ftBlob,ftMemo,ftwidememo: begin // BLOBs + // Try to discover BLOB data length + memolen1:= maxint div sizeof(widechar); + if odbccursor.fcurrentblobbuffer = '' then begin + Res:=SQLGetData(ODBCCursor.FSTMTHandle, fno, SQL_C_BINARY, buffer1, 0, + @StrLenOrInd); + ODBCCheckResult(Res, SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, + 'Could not get field data for field ''%s'' (index %d).', + [odbccursor.ffieldNames[fieldnum], fno]); + if StrLenOrInd = 0 then begin + strlenorind:= sql_null_data; //length 0 -> NULL + end; + // Read the data if not NULL + if (StrLenOrInd <> SQL_NULL_DATA) and (buffer <> nil) then begin + // Determine size of buffer to use + if StrLenOrInd <> SQL_NO_TOTAL then begin + memolen1:= strlenorind; + if datatype = ftwidememo then begin + memolen1:= memolen1 * sizeof(widechar); + end; + BlobBufferSize:= StrLenOrInd; + case datatype of + ftmemo: begin + blobbuffersize:= blobbuffersize + sizeof(char); //terminating 0 + end; + ftwidememo: begin + blobbuffersize:= (blobbuffersize+1)*sizeof(widechar); //terminating 0 + end; + end; + end + else begin + BlobBufferSize:= DEFAULT_BLOB_BUFFER_SIZE; + end; + if BlobBufferSize > 0 then begin + int1:= 0; //write index + targettype:= SQL_C_BINARY; + if datatype = ftwidememo then begin + targettype:= SQL_C_WCHAR; + end; + repeat + setlength(str1,int1+blobbuffersize); + Res:= SQLGetData(ODBCCursor.FSTMTHandle, fno, targettype, + pchar(pointer(str1))+int1, BlobBufferSize, @StrLenOrInd); + ODBCCheckResult(Res, SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, + 'Could not get field data for field ''%s'' (index %d).', + [odbccursor.ffieldNames[fieldnum], fno]); + if (StrLenOrInd=SQL_NO_TOTAL) or (StrLenOrInd>BlobBufferSize) then begin + BytesRead:= BlobBufferSize; + end + else begin + BytesRead:= StrLenOrInd; + end; + inc(int1,bytesread); + until Res = SQL_SUCCESS; + case datatype of + ftmemo,ftwidestring: begin + if memolen1 < int1 then begin + int1:= memolen1; //remove terminating 0 + end; + end; + end; + setlength(str1,int1); + end; + if datatype = ftwidememo then begin + bufsize1:= length(str1); + odbccursor.fcurrentblobbuffer:= str1; + bufsize1:= -bufsize1; + end + else begin + int1:= cursor.addblobdata(str1); + move(int1,buffer^,sizeof(int1)); //save id + end; + end; + end + else begin + strlenorind:= sql_null_data; //invalid + if datatype = ftwidememo then begin + bufsize1:= length(odbccursor.fcurrentblobbuffer); + if bufsize1 <= bufsize then begin + strlenorind:= 0; + if buffer <> nil then begin + move(pointer(odbccursor.fcurrentblobbuffer)^,buffer^,bufsize1); + end; + end + else begin + bufsize1:= 0; //data lost + end; + odbccursor.fcurrentblobbuffer:= ''; + end; + end; + end; + else begin // TODO: Loading of other field types + raise EODBCException.CreateFmt('Tried to load field of unsupported field type %s', + [Fieldtypenames[DataType]]); + end; + end; + bufsize:= bufsize1; + ODBCCheckResult(Res, SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, + 'Could not get field data for field ''%s'' (index %d).', + [odbccursor.ffieldNames[fieldnum], fno]); + Result:=StrLenOrInd<>SQL_NULL_DATA; // Result indicates whether the value is non-null +end; + +function TODBCConnection.CreateBlobStream(const Field: TField; const Mode: TBlobStreamMode; + const acursor: tsqlcursor): TStream; +var + blobid: integer; +// int1,int2: integer; +// str1: string; +// bo1: boolean; +begin + result:= nil; + if mode = bmread then begin + if field.getData(@blobId) then begin + result:= acursor.getcachedblob(blobid); + end; + end; +end; + +procedure TODBCConnection.FreeFldBuffers(cursor: TSQLCursor); +var + ODBCCursor:TODBCCursor; +// i: integer; +begin + ODBCCursor:=cursor as TODBCCursor; +{ + // Free TMemoryStreams in cursor.FBlobStreams and clear it + for i:=0 to ODBCCursor.FBlobStreams.Count-1 do + TObject(ODBCCursor.FBlobStreams[i]).Free; + ODBCCursor.FBlobStreams.Clear; +} + ODBCCheckResult( + SQLFreeStmt(ODBCCursor.FSTMTHandle, SQL_CLOSE), + SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, 'Could not close ODBC statement cursor.' + ); +end; + +procedure TODBCConnection.AddFieldDefs(const cursor: TSQLCursor; + const FieldDefs: TFieldDefs); +const + ColNameDefaultLength = 40; // should be > 0, because an ansistring of length 0 is a nil pointer instead of a pointer to a #0 + TypeNameDefaultLength = 80; // idem +var + ODBCCursor:TODBCCursor; + ColumnCount:SQLSMALLINT; + i:integer; + ColNameLength,{TypeNameLength,}DataType,DecimalDigits,Nullable:SQLSMALLINT; + ColumnSize: SQLULEN; + ColName{,TypeName}:string; + FieldType:TFieldType; + FieldSize: integer; + fd: tfielddef; + int1: integer; +begin + fielddefs.clear; + ODBCCursor:=cursor as TODBCCursor; + + // get number of columns in result set + ODBCCheckResult( + SQLNumResultCols(ODBCCursor.FSTMTHandle, ColumnCount), + SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, + 'Could not determine number of columns in result set.' + ); + + setlength(odbccursor.ffieldnames,columncount); + for i:=1 to ColumnCount do + begin + SetLength(ColName,ColNameDefaultLength); // also garantuees uniqueness + + // call with default column name buffer + ODBCCheckResult( + SQLDescribeCol(ODBCCursor.FSTMTHandle, // statement handle + i, // column number, is 1-based (Note: column 0 is the bookmark column in ODBC) + @(ColName[1]), // default buffer + ColNameDefaultLength+1, // and its length; we include the #0 terminating any ansistring of Length > 0 in the buffer + ColNameLength, // actual column name length + DataType, // the SQL datatype for the column + ColumnSize, // column size + DecimalDigits, // number of decimal digits + Nullable), // SQL_NO_NULLS, SQL_NULLABLE or SQL_NULLABLE_UNKNOWN + SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, + 'Could not get column properties for column %d.',[i] + ); + + // truncate buffer or make buffer long enough for entire column name (note: the call is the same for both cases!) + SetLength(ColName,ColNameLength); + // check whether entire column name was returned + if ColNameLength>ColNameDefaultLength then + begin + // request column name with buffer that is long enough + ODBCCheckResult( + SQLColAttribute(ODBCCursor.FSTMTHandle, // statement handle + i, // column number + SQL_DESC_NAME, // the column name or alias + @(ColName[1]), // buffer + ColNameLength+1, // buffer size + @ColNameLength, // actual length + nil), // no numerical output + SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, + 'Could not get column name for column %d.',[i] + ); + end; + + // convert type + // NOTE: I made some guesses here after I found only limited information about TFieldType; please report any problems + case DataType of + SQL_CHAR: begin FieldType:=ftString; FieldSize:=ColumnSize{+1}; end; + SQL_VARCHAR: begin FieldType:=ftString; FieldSize:=ColumnSize{+1}; end; + SQL_LONGVARCHAR: begin FieldType:=ftMemo; FieldSize:= blobidsize; end; + // is a blob + SQL_WCHAR: begin FieldType:=ftWideString; FieldSize:=ColumnSize{+1}; end; + SQL_WVARCHAR: begin FieldType:=ftWideString; FieldSize:=ColumnSize{+1}; end; + SQL_WLONGVARCHAR: begin + FieldType:= ftwidememo; //for tmsestringfield + FieldSize:= 0; + end; // is a blob + SQL_NUMERIC,SQL_DECIMAL: + begin + if (decimaldigits > 4) and + (dbo_bcdtofloatif in controller.options) then begin + FieldType:= ftFloat; + FieldSize:= 0; + end + else begin + FieldType:= ftbcd; + FieldSize:= decimaldigits; + if fieldsize > 4 then begin + fieldsize:= 4; + end; + end; + end; + SQL_SMALLINT: begin FieldType:=ftSmallint; FieldSize:=0; end; + SQL_INTEGER: begin FieldType:=ftInteger; FieldSize:=0; end; + SQL_REAL: begin FieldType:=ftFloat; FieldSize:=0; end; + SQL_FLOAT: begin FieldType:=ftFloat; FieldSize:=0; end; + SQL_DOUBLE: begin FieldType:=ftFloat; FieldSize:=0; end; + SQL_BIT: begin FieldType:=ftBoolean; FieldSize:=0; end; + SQL_TINYINT: begin FieldType:=ftSmallint; FieldSize:=0; end; + SQL_BIGINT: begin FieldType:=ftLargeint; FieldSize:=0; end; + SQL_BINARY: begin FieldType:=ftBytes; FieldSize:=ColumnSize; end; + SQL_VARBINARY: begin FieldType:=ftVarBytes; FieldSize:=ColumnSize; end; + SQL_LONGVARBINARY: begin FieldType:=ftBlob; FieldSize:=blobidsize; end; + // is a blob + SQL_TYPE_DATE: begin FieldType:=ftDate; FieldSize:=0; end; + SQL_TYPE_TIME: begin FieldType:=ftTime; FieldSize:=0; end; + SQL_TYPE_TIMESTAMP:begin FieldType:=ftDateTime; FieldSize:=0; end; +{ SQL_TYPE_UTCDATETIME:FieldType:=ftUnknown;} +{ SQL_TYPE_UTCTIME: FieldType:=ftUnknown;} +{ SQL_INTERVAL_MONTH: FieldType:=ftUnknown;} +{ SQL_INTERVAL_YEAR: FieldType:=ftUnknown;} +{ SQL_INTERVAL_YEAR_TO_MONTH: FieldType:=ftUnknown;} +{ SQL_INTERVAL_DAY: FieldType:=ftUnknown;} +{ SQL_INTERVAL_HOUR: FieldType:=ftUnknown;} +{ SQL_INTERVAL_MINUTE: FieldType:=ftUnknown;} +{ SQL_INTERVAL_SECOND: FieldType:=ftUnknown;} +{ SQL_INTERVAL_DAY_TO_HOUR: FieldType:=ftUnknown;} +{ SQL_INTERVAL_DAY_TO_MINUTE: FieldType:=ftUnknown;} +{ SQL_INTERVAL_DAY_TO_SECOND: FieldType:=ftUnknown;} +{ SQL_INTERVAL_HOUR_TO_MINUTE: FieldType:=ftUnknown;} +{ SQL_INTERVAL_HOUR_TO_SECOND: FieldType:=ftUnknown;} +{ SQL_INTERVAL_MINUTE_TO_SECOND:FieldType:=ftUnknown;} + SQL_GUID: begin FieldType:=ftGuid; FieldSize:=ColumnSize; end; + else + begin FieldType:=ftUnknown; FieldSize:=ColumnSize; end + end; + +// if (FieldType in [ftString,ftFixedChar]) and // field types mapped to TStringField +// (FieldSize >= dsMaxStringSize) then +// begin +// FieldSize:=dsMaxStringSize-1; +// end; +(* + if FieldType=ftUnknown then // if unknown field type encountered, try finding more specific information about the ODBC SQL DataType + begin + SetLength(TypeName,TypeNameDefaultLength); // also garantuees uniqueness + + ODBCCheckResult( + SQLColAttribute(ODBCCursor.FSTMTHandle, // statement handle + i, // column number + SQL_DESC_TYPE_NAME, // FieldIdentifier indicating the datasource dependent data type name (useful for diagnostics) + @(TypeName[1]), // default buffer + TypeNameDefaultLength+1, // and its length; we include the #0 terminating any ansistring of Length > 0 in the buffer + @TypeNameLength, // actual type name length + nil // no need for a pointer to return a numeric attribute at + ), + SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, + 'Could not get datasource dependent type name for column %s.',[ColName] + ); + // truncate buffer or make buffer long enough for entire column name (note: the call is the same for both cases!) + SetLength(TypeName,TypeNameLength); + // check whether entire column name was returned + if TypeNameLength>TypeNameDefaultLength then + begin + // request column name with buffer that is long enough + ODBCCheckResult( + SQLColAttribute(ODBCCursor.FSTMTHandle, // statement handle + i, // column number + SQL_DESC_TYPE_NAME, // FieldIdentifier indicating the datasource dependent data type name (useful for diagnostics) + @(TypeName[1]), // buffer + TypeNameLength+1, // buffer size + @TypeNameLength, // actual length + nil), // no need for a pointer to return a numeric attribute at + SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, + 'Could not get datasource dependent type name for column %s.',[ColName] + ); + end; + DatabaseErrorFmt('Column %s has an unknown or unsupported column type. Datasource dependent type name: %s. ODBC SQL data type code: %d.', [ColName, TypeName, DataType]); + end; +*) + // add FieldDef + if not(fieldtype in varsizefields) then begin + fieldsize:= 0; + end; + fd:= TFieldDef.Create(FieldDefs, ColName, FieldType, FieldSize, False, i); + fd.collection:= fielddefs; + if fieldtype = ftbcd then begin + int1:= columnsize; + if int1 > maxprecision then begin + int1:= maxprecision; + end; + fd.precision:= int1; + end; + odbccursor.ffieldnames[i-1]:= colname; + end; +end; + +procedure TODBCConnection.UpdateIndexDefs(var IndexDefs: TIndexDefs; + const aTableName: string; const acursor: tsqlcursor); +var + StmtHandle:SQLHSTMT; + Res:SQLRETURN; + IndexDef: TIndexDef; + KeyFields, KeyName: String; + // variables for binding + NonUnique :SQLSMALLINT; NonUniqueIndOrLen :SQLINTEGER; + IndexName :string; IndexNameIndOrLen :SQLINTEGER; + _Type :SQLSMALLINT; _TypeIndOrLen :SQLINTEGER; + OrdinalPos:SQLSMALLINT; OrdinalPosIndOrLen:SQLINTEGER; + ColName :string; ColNameIndOrLen :SQLINTEGER; + AscOrDesc :SQLCHAR; AscOrDescIndOrLen :SQLINTEGER; + PKName :string; PKNameIndOrLen :SQLINTEGER; +const + DEFAULT_NAME_LEN = 255; +begin + +// exit; /////////// does not work with MS SQL because of one statement + //per connection limitation + + // allocate statement handle + StmtHandle := SQL_NULL_HANDLE; + ODBCCheckResult( + SQLAllocHandle(SQL_HANDLE_STMT, FDBCHandle, StmtHandle), + SQL_HANDLE_DBC, FDBCHandle, 'Could not allocate ODBC Statement handle.' + ); + + try + // Disabled: only works if we can specify a SchemaName and, if supported by the data source, a CatalogName + // otherwise SQLPrimaryKeys returns error HY0009 (Invalid use of null pointer) + // set the SQL_ATTR_METADATA_ID so parameters to Catalog functions are considered as identifiers (e.g. case-insensitive) + //ODBCCheckResult( + // SQLSetStmtAttr(StmtHandle, SQL_ATTR_METADATA_ID, SQLPOINTER(SQL_TRUE), SQL_IS_UINTEGER), + // SQL_HANDLE_STMT, StmtHandle, 'Could not set SQL_ATTR_METADATA_ID statement attribute to SQL_TRUE.' + //); + + // alloc result column buffers + SetLength(ColName, DEFAULT_NAME_LEN); + SetLength(PKName, DEFAULT_NAME_LEN); + SetLength(IndexName,DEFAULT_NAME_LEN); + + // Fetch primary key info using SQLPrimaryKeys + ODBCCheckResult( + SQLPrimaryKeys( + StmtHandle, + nil, 0, // any catalog + nil, 0, // any schema + PChar(aTableName), Length(aTableName) + ), + SQL_HANDLE_STMT, StmtHandle, + 'Could not retrieve primary key metadata for table %s using SQLPrimaryKeys.', + [aTableName] + ); + + // init key name & fields; we will set the IndexDefs.Option ixPrimary below when there is a match by IndexName=KeyName + KeyName:=''; + KeyFields:=''; + try + // bind result columns; the column numbers are documented in the reference for SQLStatistics + ODBCCheckResult(SQLBindCol(StmtHandle, 4, SQL_C_CHAR , @ColName[1], + Length(ColName)+1, @ColNameIndOrLen), SQL_HANDLE_STMT, StmtHandle, + 'Could not bind primary key metadata column COLUMN_NAME.'); + ODBCCheckResult(SQLBindCol(StmtHandle, 5, SQL_C_SSHORT, @OrdinalPos, 0, + @OrdinalPosIndOrLen), SQL_HANDLE_STMT, StmtHandle, + 'Could not bind primary key metadata column KEY_SEQ.'); + ODBCCheckResult(SQLBindCol(StmtHandle, 6, SQL_C_CHAR , @PKName [1], + Length(PKName )+1, @PKNameIndOrLen ), SQL_HANDLE_STMT, StmtHandle, + 'Could not bind primary key metadata column PK_NAME.'); + + // fetch result + repeat + // go to next row; loads data in bound columns + Res:=SQLFetch(StmtHandle); + // if no more row, break + if Res=SQL_NO_DATA then + Break; + // handle data + if ODBCSucces(Res) then begin + if OrdinalPos=1 then begin + KeyName:=PChar(@PKName[1]); + KeyFields:= PChar(@ColName[1]); + end else begin + KeyFields:=KeyFields+';'+PChar(@ColName[1]); + end; + end else begin + ODBCCheckResult(Res, SQL_HANDLE_STMT, StmtHandle, + 'Could not fetch primary key metadata row.'); + end; + until false; + finally + // unbind columns & close cursor + ODBCCheckResult(SQLFreeStmt(StmtHandle, SQL_UNBIND), SQL_HANDLE_STMT, + StmtHandle, 'Could not unbind columns.'); + ODBCCheckResult(SQLFreeStmt(StmtHandle, SQL_CLOSE), SQL_HANDLE_STMT, + StmtHandle, 'Could not close cursor.'); + end; + + //WriteLn('KeyName: ',KeyName,'; KeyFields: ',KeyFields); + + // use SQLStatistics to get index information + ODBCCheckResult( + SQLStatistics( + StmtHandle, + nil, 0, // catalog unkown; request for all catalogs + nil, 0, // schema unkown; request for all schemas + PChar(aTableName), Length(aTableName), // request information for TableName + SQL_INDEX_ALL, + SQL_QUICK + ), + SQL_HANDLE_STMT, StmtHandle, + 'Could not retrieve index metadata for table %s using SQLStatistics.', + [aTableName] + ); + + try + // bind result columns; the column numbers are documented in the reference for SQLStatistics + ODBCCheckResult(SQLBindCol(StmtHandle, 4, SQL_C_SSHORT, @NonUnique , 0, + @NonUniqueIndOrLen ), SQL_HANDLE_STMT, StmtHandle, + 'Could not bind index metadata column NON_UNIQUE.'); + ODBCCheckResult(SQLBindCol(StmtHandle, 6, SQL_C_CHAR , @IndexName[1], + Length(IndexName)+1, @IndexNameIndOrLen), SQL_HANDLE_STMT, StmtHandle, + 'Could not bind index metadata column INDEX_NAME.'); + ODBCCheckResult(SQLBindCol(StmtHandle, 7, SQL_C_SSHORT, @_Type , 0, + @_TypeIndOrLen ), SQL_HANDLE_STMT, StmtHandle, + 'Could not bind index metadata column TYPE.'); + ODBCCheckResult(SQLBindCol(StmtHandle, 8, SQL_C_SSHORT, @OrdinalPos, 0, + @OrdinalPosIndOrLen), SQL_HANDLE_STMT, StmtHandle, + 'Could not bind index metadata column ORDINAL_POSITION.'); + ODBCCheckResult(SQLBindCol(StmtHandle, 9, SQL_C_CHAR , @ColName [1], + Length(ColName )+1, @ColNameIndOrLen ), SQL_HANDLE_STMT, StmtHandle, + 'Could not bind index metadata column COLUMN_NAME.'); + ODBCCheckResult(SQLBindCol(StmtHandle, 10, SQL_C_CHAR , @AscOrDesc , 1, + @AscOrDescIndOrLen ), SQL_HANDLE_STMT, StmtHandle, + 'Could not bind index metadata column ASC_OR_DESC.'); + + // clear index defs + IndexDef:=nil; + + // fetch result + repeat + // go to next row; loads data in bound columns + Res:=SQLFetch(StmtHandle); + // if no more row, break + if Res=SQL_NO_DATA then + Break; + // handle data + if ODBCSucces(Res) then begin + // note: SQLStatistics not only returns index info, but also statistics; we skip the latter + if _Type<>SQL_TABLE_STAT then begin + if (OrdinalPos=1) or not Assigned(IndexDef) then begin + // create new IndexDef iff OrdinalPos=1 or not Assigned(IndexDef) (the latter should not occur though) + IndexDef:=IndexDefs.AddIndexDef; + IndexDef.Name:=PChar(@IndexName[1]); // treat ansistring as zero terminated string + IndexDef.Fields:=PChar(@ColName[1]); + if NonUnique=SQL_FALSE then + IndexDef.Options:=IndexDef.Options+[ixUnique]; + if (AscOrDescIndOrLen<>SQL_NULL_DATA) and (AscOrDesc='D') then + IndexDef.Options:=IndexDef.Options+[ixDescending]; + if IndexDef.Name=KeyName then + IndexDef.Options:=IndexDef.Options+[ixPrimary]; + // TODO: figure out how we can tell whether COLUMN_NAME is an expression or not + // if it is an expression, we should include ixExpression in Options and set Expression to ColName + end else // NB we re-use the last IndexDef + IndexDef.Fields:=IndexDef.Fields+';'+PChar(@ColName[1]); // NB ; is the separator to be used for IndexDef.Fields + end; + end else begin + ODBCCheckResult(Res, SQL_HANDLE_STMT, StmtHandle, + 'Could not fetch index metadata row.'); + end; + until false; + finally + // unbind columns & close cursor + ODBCCheckResult(SQLFreeStmt(StmtHandle, SQL_UNBIND), SQL_HANDLE_STMT, + StmtHandle, 'Could not unbind columns.'); + ODBCCheckResult(SQLFreeStmt(StmtHandle, SQL_CLOSE), SQL_HANDLE_STMT, + StmtHandle, 'Could not close cursor.'); + end; + + finally + if StmtHandle<>SQL_NULL_HANDLE then begin + // Free the statement handle + Res:=SQLFreeHandle(SQL_HANDLE_STMT, StmtHandle); + if Res=SQL_ERROR then + ODBCCheckResult(Res, SQL_HANDLE_STMT, STMTHandle, + 'Could not free ODBC Statement handle.'); + end; + end; +end; + +function TODBCConnection.GetSchemaInfoSQL(SchemaType: TSchemaType; + SchemaObjectName, SchemaObjectPattern: msestring): msestring; +begin + Result:=inherited GetSchemaInfoSQL( + SchemaType, SchemaObjectName, SchemaObjectPattern); + // TODO: implement this +end; + +{ TODBCEnvironment } + +procedure ODBCCheckResult(LastReturnCode:SQLRETURN; HandleType:SQLSMALLINT; + AHandle: SQLHANDLE; ErrorMsg: string; + const values: array of const); +var + conn: todbcconnection; +begin + if not odbcsucces(lastreturncode) then begin + conn:= todbcconnection.create(nil); + try + conn.odbccheckresult(lastreturncode,handletype,ahandle,errormsg,values); + finally; + conn.free; + end; + end; +end; + +constructor TODBCEnvironment.Create; +var + res: sqlreturn; +begin + // make sure odbc is loaded + initializeodbc([]); + finitialized:= true; + // allocate environment handle + if SQLAllocHandle(SQL_HANDLE_ENV, + SQL_NULL_HANDLE, FENVHandle) = SQL_Error then begin + raise EODBCException.Create('Could not allocate ODBC Environment handle'); + // we can't retrieve any more information, + //because we don't have a handle for the SQLGetDiag* functions + end; + // set odbc version + res:= SQLSetEnvAttr(FENVHandle, SQL_ATTR_ODBC_VERSION, + SQLPOINTER(SQL_OV_ODBC3), 0); + ODBCCheckResult(res, + SQL_HANDLE_ENV, FENVHandle,'Could not set ODBC version to 3.',[]); +end; + +destructor TODBCEnvironment.Destroy; +var + Res:SQLRETURN; +begin + // free environment handle + if FENVHandle <> nil then begin //otherwise exception in create + Res:=SQLFreeHandle(SQL_HANDLE_ENV, FENVHandle); + if Res = SQL_ERROR then + ODBCCheckResult(Res,SQL_HANDLE_ENV, FENVHandle, + 'Could not free ODBC Environment handle.',[]); + + // free odbc if not used by any TODBCEnvironment object anymore + end; +// Dec(ODBCLoadCount); +// if ODBCLoadCount=0 then ReleaseOdbc; + if finitialized then begin + releaseodbc; + end; +end; + +{ TODBCCursor } + +constructor TODBCCursor.Create(const aowner: icursorclient; + const aname: ansistring; const Connection:TODBCConnection); +begin + fconnection:= connection; + inherited create(aowner,aname); + // allocate statement handle + connection.ODBCCheckResult( + SQLAllocHandle(SQL_HANDLE_STMT, Connection.FDBCHandle, FSTMTHandle), + SQL_HANDLE_DBC, Connection.FDBCHandle, + 'Could not allocate ODBC Statement handle.' + ); + + // allocate FBlobStreams +// FBlobStreams:=TList.Create; +end; + +destructor TODBCCursor.Destroy; +var + Res:SQLRETURN; +begin + inherited Destroy; + +// FBlobStreams.Free; + + if pointer(FSTMTHandle) <> pointer(SQL_INVALID_HANDLE) then + begin + // deallocate statement handle + Res:=SQLFreeHandle(SQL_HANDLE_STMT, FSTMTHandle); + if Res=SQL_ERROR then + fconnection.ODBCCheckResult(Res,SQL_HANDLE_STMT, FSTMTHandle, + 'Could not free ODBC Statement handle.'); + end; +end; + +procedure TODBCCursor.close; +begin + sqlclosecursor(fstmthandle); +// ODBCCheckResult(sqlclosecursor(fstmthandle),SQL_HANDLE_STMT, FSTMTHandle, +// 'Could not close Cursor'); + //there is possible no cursor -> no errorcheck + fcurrentblobbuffer:= ''; + inherited; +end; + +{ finalization } + +initialization +finalization + + if Assigned(DefaultEnvironment) then + DefaultEnvironment.Free; + +end. + diff --git a/mseide-msegui/lib/common/db/mpqconnection.pas b/mseide-msegui/lib/common/db/mpqconnection.pas new file mode 100644 index 0000000..562a48e --- /dev/null +++ b/mseide-msegui/lib/common/db/mpqconnection.pas @@ -0,0 +1,1708 @@ +{ + Copyright (c) 2004 by Joost van der Sluis + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Modified 2006-2013 by Martin Schreiber + + **********************************************************************} + +unit mpqconnection; +{$ifdef FPC}{$mode objfpc}{$H+}{$endif} + +{$Define LinkDynamically} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses,SysUtils, msqldb, mdb, + {$ifdef FPC}dbconst{$else}dbconst_del{$endif}, + msedbevents,msetypes{msestrings},msedb, +{$IfDef LinkDynamically} + postgres3dyn; +{$Else} + postgres3; +{$EndIf} + +type + epqerror = class(econnectionerror) + private + fsqlcode: string; + public + constructor create(const asender: tcustomsqlconnection; const amessage: ansistring; + const aerrormessage: msestring; const asqlcode: string); + public + property sqlcode: string read fsqlcode; + end; + + TPQTrans = Class(TSQLHandle) + protected + fconn: PPGConn; + fparams: ansistring; +// ErrorOccured : boolean; + public + property conn: ppgconn read fconn; + end; + + dbarrayinfoty = record + fieldtype: tfieldtype; + vartype: word; + end; + dbarrayinfoarty = array of dbarrayinfoty; + + TPQCursor = Class(TSQLCursor) + protected + Statementm : msestring; + tr : TPQTrans; + res : PPGresult; + CurTuple : integer; + Nr : string; + fopen: boolean; + ParamBinding : TParamBinding; + ParamReplaceString : mseString; + arrayinfo: dbarrayinfoarty; + public + procedure close; override; + end; + + dbeventarty = array of tdbevent; + + TPQConnection = class (TSQLConnection,iblobconnection,idbevent,idbeventcontroller) + private + FCursorCount : integer; + FConnectString : string; + FHandle: ppgconn; + FIntegerDateTimes : boolean; + feventcontroller: tdbeventcontroller; + ftransactionconnectionused: boolean; + flastsqlcode: string; + flasterrormessage: msestring; + function TranslateFldType(Type_Oid: integer; + out isarray: boolean; out vartype: word) : TFieldType; + function geteventinterval: integer; + procedure seteventinterval(const avalue: integer); + procedure closeconnection(var aconnection: ppgconn); + function constructconnectstring: string; + procedure openconnection(const aconnectstring: ansistring; + var aconnection: ppgconn); + procedure begintrans(const aconnection: ppgconn; const aparams: ansistring); + protected + procedure checkerror(const aconnection: ppgconn; var ares: ppgresult; + const amessage: ansistring); + procedure checkexec(const aconnection: ppgconn; const asql: ansistring; + const amessage: ansistring); + procedure finalizetransaction(const atransaction: tsqlhandle); override; + procedure DoInternalConnect; override; + procedure DoInternalDisconnect; override; + function GetHandle : pointer; override; + + Function AllocateTransactionHandle : TSQLHandle; override; + + procedure internalExecute(const cursor: TSQLCursor; const atransaction: tsqltransaction; + const AParams : TmseParams; const autf8: boolean); override; + procedure internalexecuteunprepared(const cursor: tsqlcursor; + const atransaction: tsqltransaction; const asql: string; + const origsql: msestring; const aparams: tmseparams); override; + function GetTransactionHandle(trans : TSQLHandle): pointer; override; + function RollBack(trans : TSQLHandle) : boolean; override; + function Commit(trans : TSQLHandle) : boolean; override; + procedure internalCommitRetaining(trans : TSQLHandle); override; + function StartdbTransaction(const trans : TSQLHandle; + const AParams: tstringlist) : boolean; override; + procedure internalRollBackRetaining(trans : TSQLHandle); override; + procedure UpdateIndexDefs(var IndexDefs : TIndexDefs; + const aTableName : string; const acursor: tsqlcursor); override; + function GetSchemaInfoSQL(SchemaType : TSchemaType; + SchemaObjectName, SchemaPattern : msestring) : msestring; override; + procedure dopqexec(const asql: ansistring); overload; + procedure dopqexec(const asql: ansistring; + const aconnection: ppgconn); overload; + + function CreateBlobStream(const Field: TField; const Mode: TBlobStreamMode; + const acursor: tsqlcursor): TStream; override; + function getblobdatasize: integer; override; + function getnumboolean: boolean; override; + + //iblobconnection + procedure writeblobdata(const atransaction: tsqltransaction; + const tablename: string; const acursor: tsqlcursor; + const adata: pointer; const alength: integer; + const afield: tfield; const aparam: tparam; + out newid: string); + procedure setupblobdata(const afield: tfield; const acursor: tsqlcursor; + const aparam: tparam); +// function getfeatures(): databasefeaturesty override; +// function blobscached: boolean; + + //idbevent + procedure listen(const sender: tdbevent); + procedure unlisten(const sender: tdbevent); + procedure fire(const sender: tdbevent); + //idbeventcontroller + function getdbevent(var aname: string; var aid: int64): boolean; + //false if none + procedure dolisten(const sender: tdbevent); + procedure dounlisten(const sender: tdbevent); + public + constructor Create(AOwner : TComponent); override; + destructor destroy; override; + Function AllocateCursorHandle(const aowner: icursorclient; + const aname: ansistring) : TSQLCursor; override; + Procedure DeAllocateCursorHandle(var cursor : TSQLCursor); override; + procedure preparestatement(const cursor: tsqlcursor; + const atransaction : tsqltransaction; + const asql: msestring; const aparams : tmseparams); override; + procedure FreeFldBuffers(cursor : TSQLCursor); override; + procedure AddFieldDefs(const cursor: TSQLCursor; + const FieldDefs : TfieldDefs); override; + procedure UnPrepareStatement(cursor : TSQLCursor); override; + function Fetch(cursor : TSQLCursor) : boolean; override; + function loadfield(const cursor: tsqlcursor; + const datatype: tfieldtype; const fieldnum: integer; //null based + const buffer: pointer; var bufsize: integer; + const aisutf8: boolean): boolean; override; + //if bufsize < 0 -> buffer was to small, should be -bufsize + function fetchblob(const cursor: tsqlcursor; + const fieldnum: integer): ansistring; override; + //null based + function backendpid: int64; //0 if not connected + procedure createdatabase(const asql: ansistring); + property eventcontroller: tdbeventcontroller read feventcontroller; + property lasterrormessage: msestring read flasterrormessage; + property lastsqlcode: string read flastsqlcode; + published + property DatabaseName; + property KeepConnection; +// property LoginPrompt; + property Params; +// property OnLogin; + property ongetcredentials; + property eventinterval: integer read geteventinterval + write seteventinterval default defaultdbeventinterval; + end; + +implementation +uses + math,msestream,msedatalist,mseformatstr,msedatabase,msectypes,msestrings, + variants,msevariants,msesqlresult{$ifndef FPC},classes_del{$endif}; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +ResourceString + SErrRollbackFailed = 'Rollback transaction failed'; + SErrCommitFailed = 'Commit transaction failed'; + SErrConnectionFailed = 'Connection to database failed'; + SErrTransactionFailed = 'Start of transaction failed'; + SErrClearSelection = 'Clear of selection failed'; + SErrExecuteFailed = 'Execution of query failed'; + SErrFieldDefsFailed = 'Can not extract field information from query'; + SErrFetchFailed = 'Fetch of data failed'; + SErrPrepareFailed = 'Preparation of query failed.'; + +const + Oid_Bool = 16; + Oid_Bool_ar = 1000; + Oid_Text = 25; + Oid_Text_ar = 1009; + Oid_bytea = 17; + Oid_bytea_ar = 1001; + Oid_Oid = 26; + Oid_Oid_ar = 1028; + Oid_Name = 19; + Oid_Name_ar = 1003; + Oid_Int8 = 20; + Oid_Int8_ar = 1016; + Oid_int2 = 21; + Oid_int2_ar = 1005; + Oid_Int4 = 23; + Oid_Int4_ar = 1007; + Oid_Float4 = 700; + Oid_Float4_ar = 1021; + Oid_Float8 = 701; + Oid_Float8_ar = 1022; + Oid_Unknown = 705; + Oid_Unknown_ar = 0; + Oid_bpchar = 1042; + Oid_bpchar_ar = 1014; + Oid_varchar = 1043; + Oid_varchar_ar = 1015; + Oid_timestamp = 1114; + Oid_timestamp_ar = 1115; + oid_date = 1082; + oid_date_ar = 1182; + oid_time = 1083; + oid_time_ar = 1183; + oid_numeric = 1700; + oid_numeric_ar = 1231; + oid_uuid = 2950; + oid_uuid_ar = 2951; + pg_diag_sqlstate = 'C'; + + inv_read = $40000; + inv_write = $20000; + invalidoid = 0; + + varhdrsz = 4; + nbase = 10000; //base for numeric digits + maxprecision = 18; + +type + tdatabase1 = class(tdatabase); + +{ TPQCursor } + +procedure TPQCursor.close; +begin + inherited; + if fopen then begin + arrayinfo:= nil; + fopen:= false; + if res <> nil then begin + pqclear(res); + end; + end; +end; + +{ tpqconnection } + +constructor tpqconnection.create(aowner: tcomponent); +begin + feventcontroller:= tdbeventcontroller.create(idbeventcontroller(self)); + inherited; + fconnoptions:= fconnoptions + [sco_supportparams,sco_emulateretaining, + sco_blobscached]; +end; + +destructor TPQConnection.destroy; +begin + inherited; + feventcontroller.free; +end; + +function TPQConnection.GetTransactionHandle(trans : TSQLHandle): pointer; +begin + Result := trans; +end; + +procedure TPQConnection.checkerror(const aconnection: ppgconn; + var ares: ppgresult; const amessage: ansistring); +var +// err: integer; + res: texecstatustype; +begin + res:= PQresultStatus(ares); + if not(res in [PGRES_COMMAND_OK,PGRES_TUPLES_OK]) then begin + flastsqlcode:= strpas(pqresulterrorfield(ares,ord(pg_diag_sqlstate))); + flasterrormessage:= connectionmessage(pqresulterrormessage(ares)); + PQclear(ares); + ares:= nil; + raise epqerror.create(self,amessage+' (PostgreSQL: '+ + ansistring(flasterrormessage)+ ')', + flasterrormessage,flastsqlcode); + end + else begin + if res <> pgres_tuples_ok then begin + PQclear(ares); + ares:= nil; + end; + end; +end; + +procedure tpqconnection.checkexec(const aconnection: ppgconn; const asql: ansistring; + const amessage: ansistring); +var + res: ppgresult; +begin + res:= pqexec(aconnection,pchar(asql)); + checkerror(aconnection,res,amessage); +end; + +procedure tpqconnection.begintrans(const aconnection: ppgconn; + const aparams: ansistring); +begin + checkexec(aconnection,'BEGIN '+aparams,sErrTransactionFailed); +end; + +function TPQConnection.StartdbTransaction(const trans : TSQLHandle; + const AParams: tstringlist) : boolean; +var + int1: integer; +begin + with tpqtrans(trans) do begin + if fconn = nil then begin + if not ftransactionconnectionused then begin + fconn:= self.fhandle; + ftransactionconnectionused:= true; + end + else begin + openconnection(fconnectstring,fconn); + end; + end; + fparams:= ''; + if aparams <> nil then begin + for int1:= 0 to aparams.count - 1 do begin + fparams:= fparams + aparams[int1] + ',' + end; + if aparams.count > 0 then begin + setlength(fparams,length(fparams)-1); + end; + end; + begintrans(fconn,fparams); + end; + result:= true; +end; + +function TPQConnection.RollBack(trans : TSQLHandle) : boolean; +begin + checkexec(tpqtrans(trans).fconn,'ROLLBACK',SErrRollbackFailed); + result := true; +end; + +function TPQConnection.Commit(trans : TSQLHandle) : boolean; +begin + checkexec(tpqtrans(trans).fconn,'COMMIT',SErrCommitFailed); + result:= true; +end; + +procedure TPQConnection.internalRollBackRetaining(trans : TSQLHandle); +begin + with tpqtrans(trans) do begin + checkexec(fconn,'ROLLBACK',SErrRollbackFailed); + begintrans(fconn,fparams); + end; +end; + +procedure TPQConnection.internalCommitRetaining(trans : TSQLHandle); +begin + with tpqtrans(trans) do begin + checkexec(fconn,'COMMIT',SErrCommitFailed); + begintrans(fconn,fparams); + end; +end; + +procedure TPQConnection.openconnection(const aconnectstring: string; + var aconnection: ppgconn); +var + msg: ansistring; +begin + aconnection:= PQconnectdb(pchar(aConnectString)); + if (PQstatus(aconnection) = CONNECTION_BAD) then begin + msg:= ansistring(connectionmessage(PQerrorMessage(aconnection))); + pqfinish(aconnection); + aconnection:= nil; + DatabaseError(sErrConnectionFailed + ' (PostgreSQL: ' + msg + ')',self); + end; +end; + +function tpqconnection.constructconnectstring: ansistring; +var + u,p: msestring; //how to define encoding of connectionstring? + u1,p1: string; +begin + result:= ''; + getcredentials(u,p); + if (U <> '') then begin + u1:= ansistring(u); + result := result + ' user=''' + U1 + ''''; + stringsafefree(u1,false); + end; + if (P <> '') then begin + p1:= ansistring(p); + result:= result + ' password=''' + P1 + ''''; + stringsafefree(p1,false); + end; + freecredentials(u,p); + if (HostName <> '') then begin + result:= result + ' host=''' + ansistring(HostName) + ''''; + end; + if (DatabaseName <> '') then begin + result:= result + ' dbname=''' + ansistring(DatabaseName) + ''''; + end + else begin + result:= result + ' dbname=''' + 'postgres' + ''''; + end; + if (Params.Text <> '') then begin + result:= result + ' '+Params.Text; + end; +end; + +procedure TPQConnection.DoInternalConnect; +var +// msg: string; + bo1: boolean; +// int1: integer; +begin +{$IfDef LinkDynamically} + InitializePostgres3([]); +{$EndIf} + ftransactionconnectionused:= false; + inherited dointernalconnect; + fconnectstring:= constructconnectstring; + openconnection(fconnectstring,fhandle); +// This does only work for pg>=8.0, so timestamps won't work with earlier versions of pg which are compiled with integer_datetimes on + if {$ifndef FPC}@{$endif}pqparameterstatus <> nil then begin + FIntegerDatetimes := pqparameterstatus(FHandle,'integer_datetimes') = 'on'; + end; + bo1:= fconnected; + fconnected:= true; + feventcontroller.connect; + fconnected:= bo1; +end; + +procedure TPQConnection.DoInternalDisconnect; +//var +// int1: integer; +begin + feventcontroller.disconnect; + inherited; + closeconnection(fhandle); +{$IfDef LinkDynamically} + ReleasePostgres3; +{$EndIf} +end; + +procedure TPQConnection.createdatabase(const asql: ansistring); +var + conn: ppgconn; +begin +{$IfDef LinkDynamically} + InitializePostgres3([]); +{$EndIf} + try + openconnection(constructconnectstring,conn); + dopqexec(asql,conn); + closeconnection(conn); + finally + {$IfDef LinkDynamically} + ReleasePostgres3; + {$EndIf} + end; +end; + +function TPQConnection.TranslateFldType(Type_Oid : integer; + out isarray: boolean; out vartype: word) : TFieldType; + +begin + isarray:= false; + vartype:= 0; + case Type_Oid of + Oid_varchar,Oid_bpchar, + Oid_name: begin + Result:= ftstring; + end; + Oid_varchar_ar,Oid_bpchar_ar, + Oid_name_ar: begin + Result:= ftstring; + isarray:= true; + vartype:= varolestr; + end; + Oid_text: begin + Result:= ftstring; + end; + Oid_text_ar: begin + Result:= ftstring; + isarray:= true; + vartype:= varolestr; + end; + Oid_bytea: begin + result:= ftBlob; + end; + Oid_bytea_ar: begin + result:= ftBlob; + isarray:= true; + end; + Oid_oid: begin + Result:= ftInteger; + end; + Oid_oid_ar: begin + Result:= ftInteger; + isarray:= true; + vartype:= varinteger; + end; + Oid_int8: begin + Result:= ftLargeInt; + end; + Oid_int8_ar: begin + Result:= ftLargeInt; + isarray:= true; + vartype:= varint64; + end; + Oid_int4: begin + Result:= ftInteger; + end; + Oid_int4_ar: begin + Result:= ftInteger; + isarray:= true; + vartype:= varinteger; + end; + Oid_int2: begin + Result:= ftSmallInt; + end; + Oid_int2_ar: begin + Result:= ftSmallInt; + isarray:= true; + vartype:= varinteger; + end; + Oid_Float4,Oid_Float8: begin + Result:= ftFloat; + end; + Oid_Float4_ar,Oid_Float8_ar: begin + Result:= ftFloat; + isarray:= true; + vartype:= vardouble; + end; + Oid_TimeStamp: begin + Result:= ftDateTime; + end; + Oid_TimeStamp_ar: begin + Result:= ftDateTime; + isarray:= true; + vartype:= vardate; + end; + Oid_Date: begin + Result:= ftDate; + end; + Oid_Date_ar: begin + Result:= ftDate; + isarray:= true; + vartype:= vardate; + end; + Oid_Time: begin + Result:= ftTime; + end; + Oid_Time_ar: begin + Result:= ftTime; + isarray:= true; + vartype:= vardate; + end; + Oid_Bool: begin + Result:= ftBoolean; + end; + Oid_Bool_ar: begin + Result:= ftBoolean; + isarray:= true; + vartype:= varboolean; + end; + Oid_Numeric: begin + Result:= ftBCD; + end; + Oid_Numeric_ar: begin + Result:= ftBCD; + isarray:= true; + vartype:= varcurrency; + end; + oid_uuid: begin + result:= ftguid; + end; + oid_uuid_ar: begin + result:= ftguid; + isarray:= true; + vartype:= varstring; + end; + Oid_Unknown: begin + Result:= ftUnknown; + end; + else begin + Result:= ftUnknown; + end; + end; +end; + +Function TPQConnection.AllocateCursorHandle(const aowner: icursorclient; + const aname: ansistring): TSQLCursor; +begin + result:= TPQCursor.create(aowner,aname); +end; + +Procedure TPQConnection.DeAllocateCursorHandle(var cursor : TSQLCursor); + +begin + FreeAndNil(cursor); +end; + +Function TPQConnection.AllocateTransactionHandle : TSQLHandle; + +begin + result:= TPQTrans.create; +end; + +procedure tpqconnection.preparestatement(const cursor: tsqlcursor; + const atransaction : tsqltransaction; + const asql: msestring; const aparams : tmseparams); + +const TypeStrings : array[TFieldType] of string = + ( + 'Unknown', //ftUnknown + 'varchar', //ftString + 'int', //ftSmallint + 'int', //ftInteger + 'int', //ftWord + 'bool', //ftBoolean + 'float', //ftFloat + 'numeric', //ftCurrency + 'numeric', //ftBCD + 'date', //ftDate + 'time', //ftTime + 'timestamp',//ftDateTime + 'Unknown', //ftBytes + 'Unknown', //ftVarBytes + 'Unknown', //ftAutoInc + 'bytea', //ftBlob + 'text', //ftMemo + 'bytea', //ftGraphic + 'Unknown', //ftFmtMemo + 'Unknown', //ftParadoxOle + 'Unknown', //ftDBaseOle + 'Unknown', //ftTypedBinary + 'Unknown', //ftCursor + 'varchar', //ftFixedChar + 'varchar', //ftWideString + 'bigint', //ftLargeint + 'Unknown', //ftADT + 'Unknown', //ftArray + 'Unknown', //ftReference + 'Unknown', //ftDataSet + 'Unknown', //ftOraBlob + 'Unknown', //ftOraClob + 'Unknown', //ftVariant + 'Unknown', //ftInterface + 'Unknown', //ftIDispatch + 'uuid', //ftGuid + 'Unknown', //ftTimeStamp + 'Unknown' //ftFMTBcd + ,'varchar', //ftFixedWideChar + 'Unknown' //ftWideMemo + ); + +const + savepoint = 'mseinternal$prep;'; +var + s: string; + i: integer; + str1: string; + bo1: boolean; + n: integer; +begin + with TPQCursor(cursor) do begin + if tpqtrans(atransaction.trans).fconn = nil then begin + tpqtrans(atransaction.trans).fconn:= fhandle; //fake transaction + end; + FPrepared := False; + // Prior to v8 there is no support for cursors and parameters. + // So that's not supported. + if FStatementType in [stInsert,stUpdate,stDelete,stSelect] then begin + tr:= TPQTrans(aTransaction.Handle); + repeat + n:= interlockedincrement(fcursorcount) and $ffffff; + //limit range 0..167774655 + nr:= inttostr(n); + // Only available for pq 8.0, so don't use it... + // Res := pqprepare(tr,'prepst'+name+nr,pchar(buf),params.Count,pchar('')); + s:= 'prepare prepst'+nr+' '; + if Assigned(AParams) and (AParams.count > 0) then begin + s:= s + '('; + for i := 0 to AParams.count-1 do begin + with AParams[i] do begin + if datatype = ftvariant then begin + s:= s+'unknown,'; + end + else begin + if TypeStrings[DataType] <> 'Unknown' then begin + s:= s + TypeStrings[DataType] + ',' + end + else begin + if DataType = ftUnknown then begin + DatabaseErrorFmt(SUnknownParamFieldType,[Name],self); + end + else begin + DatabaseErrorFmt(SUnsupportedParameter, + [Fieldtypenames[DataType]],self); + end; + end; + end; + end; + end; + s[length(s)]:= ')'; + str1:= todbstring(AParams.ParseSQL(asql,false,false,false,psPostgreSQL)); + end + else begin + str1:= todbstring(asql); + end; + s:= s + ' as ' + str1; + pqexec(tr.fconn,'SAVEPOINT '+savepoint); + res := pqexec(tr.fconn,pchar(s)); + bo1:= (PQresultStatus(res) = PGRES_COMMAND_OK); + if not bo1 then begin + pqexec(tr.fconn,'ROLLBACK TO SAVEPOINT '+savepoint); + end + else begin + pqexec(tr.fconn,'RELEASE SAVEPOINT '+savepoint); + end; + until bo1 or + (strpas(pqresulterrorfield(res,ord(pg_diag_sqlstate))) <> '42P05'); + //no duplicate_prepared_statement + if (PQresultStatus(res) <> PGRES_COMMAND_OK) then begin + s:= ansistring(connectionmessage(pqresulterrormessage(res))); + pqclear(res); + DatabaseError(SErrPrepareFailed + lineend + + ' (PostgreSQL: ' + s + ')',self) + end; + FPrepared := True; + end + else begin + Statementm:= {todbstring(}AParams.ParseSQL(asql,false,false,false,psSimulated, + paramBinding,ParamReplaceString){)}; +// statement := buf; + end; + end; +end; + +procedure TPQConnection.UnPrepareStatement(cursor : TSQLCursor); + +begin + with tpqcursor(cursor) do begin + if FPrepared then begin + close; +// if not tr.ErrorOccured then begin + res := pqexec(tr.fconn,pchar('deallocate prepst'+nr)); + if (PQresultStatus(res) <> PGRES_COMMAND_OK) then begin + pqclear(res); + rollback(tr); + res := pqexec(tr.fconn,pchar('deallocate prepst'+nr)); + { + DatabaseError(SErrPrepareFailed + ' (PostgreSQL: ' + + PQerrorMessage(tr.fconn) + ')',self) + } + end; + //problem with aborted transaction + pqclear(res); +// end; + FPrepared := False; + end; + end; +end; + +procedure TPQConnection.FreeFldBuffers(cursor : TSQLCursor); + +begin +// Do nothing +end; + +procedure TPQConnection.internalExecute(const cursor: TSQLCursor; + const atransaction: tsqltransaction; const AParams : TmseParams; + const autf8: boolean); + +var + ar: array of pointer; + i: integer; + s: string; + lengths,formats: integerarty; + mstr1: msestring; + +begin + with TPQCursor(cursor) do begin + frowsreturned:= -1; + frowsaffected:= -1; + curtuple:= -1; + if FStatementType in [stInsert,stUpdate,stDelete,stSelect] then begin + if Assigned(AParams) and (AParams.count > 0) then begin + setlength(ar,Aparams.count); + setlength(lengths,length(ar)); + setlength(formats,length(ar)); + for i := 0 to AParams.count -1 do begin + with AParams[i] do begin + if not IsNull then begin + case DataType of + ftdatetime: s:= formatdatetime('YYYY-MM-DD hh:nn:ss',AsDateTime); + ftdate: s:= formatdatetime('YYYY-MM-DD',AsDateTime); + fttime: s:= formatdatetime('hh:nn:ss',AsDateTime); + ftfloat,ftcurrency: s:= realtostr(asfloat); + ftbcd: s:= realtostr(ascurrency); + ftvariant: begin + if isutf8 then begin + s:= stringtoutf8ansi(encodesqlvariant(value,true)); + end + else begin + s:= ansistring(encodesqlvariant(value,true)); + end; + end; + else begin + s:= AParams.asdbstring(i); + if datatype = ftblob then begin + formats[i]:= 1; //binary + end; + end; + end; {case} + lengths[i]:= length(s); + GetMem(ar[i],length(s)+1); + StrMove(PChar(ar[i]),Pchar(s),Length(S)+1); + end; + end; + end; + res := PQexecPrepared(tr.fconn,pchar('prepst'+nr),Aparams.count,@Ar[0], + pointer(lengths),pointer(formats),1); + for i := 0 to AParams.count -1 do begin + FreeMem(ar[i]); + end; + end + else begin + res:= PQexecPrepared(tr.fconn,pchar('prepst'+nr),0,nil,nil,nil,1); + end; + end + else begin + tr := TPQTrans(cursor.ftrans); + if aparams <> nil then begin + mstr1:= aparams.expandvalues(statementm,parambinding,paramreplacestring); + end + else begin + mstr1:= statementm; + end; + if autf8 then begin + s:= stringtoutf8ansi(mstr1); + end + else begin + s:= ansistring(mstr1); + end; + res:= pqexec(tr.fconn,pchar(s)); + end; + frowsaffected:= strtointdef(pqcmdtuples(res),-1); + checkerror(tr.fconn,res,'Execution of query failed'); + frowsreturned:= pqntuples(res); + fopen:= true; + end; +end; + +procedure tpqconnection.internalexecuteunprepared(const cursor: tsqlcursor; + const atransaction: tsqltransaction; const asql: string; + const origsql: msestring; const aparams: tmseparams); +begin + with TPQCursor(cursor) do begin + tr := TPQTrans(cursor.ftrans); + frowsreturned:= -1; + frowsaffected:= -1; + curtuple:= -1; +// res:= pqexec(tr.fconn,pchar(asql)); + res:= pqexecparams(tr.fconn,pchar(asql),0,nil,nil,nil,nil,1); + + frowsaffected:= strtointdef(pqcmdtuples(res),-1); + checkerror(tr.fconn,res,'Execution of query failed'); + frowsreturned:= pqntuples(res); + fopen:= true; + end; +end; + +procedure TPQConnection.AddFieldDefs(const cursor: TSQLCursor; + const FieldDefs : TfieldDefs); +var + i: integer; + size: integer; +// st: string; + fieldtype: tfieldtype; + nFields: integer; + fd: tfielddef; + str1: ansistring; + int1: integer; + precision: integer; + isarray: boolean; +begin + precision:= 0; + fielddefs.clear; + with tpqcursor(cursor) do begin + nFields:= PQnfields(Res); + setlength(arrayinfo,nfields); + for i:= 0 to nFields-1 do begin + fieldtype:= TranslateFldType(PQftype(Res,i),isarray,arrayinfo[i].vartype); + arrayinfo[i].fieldtype:= fieldtype; + if isarray then begin + fieldtype:= ftvariant; + size:= 0; + end + else begin + size:= PQfsize(Res,i); + case fieldtype of + ftstring: begin + if size = -1 then begin + size:= pqfmod(res,i)-4; + if size = -5 then begin //text + if stringmemo then begin + size:= 0; + end + else begin + fieldtype:= ftmemo; + size:= blobidsize; + end; + end; + end; + end; + ftdate: begin + size:= sizeof(double); + end; + ftblob,ftmemo: begin + size:= blobidsize; + end; + ftbcd: begin + int1:= PQfmod(Res,i) - varhdrsz; //can be -1 - 4 = -5 + size:= int1 and $ffff; + precision:= int1 and $ffff0000 shr 16; + if (dbo_bcdtofloatif in controller.options) and (size > 4) then begin + //for pqfmod = -1 too + fieldtype:= ftfloat; + end + else begin + if size > 4 then begin + size:= 4; + end; + end; + end; + end; + end; + str1:= PQfname(Res,i); + if not(fieldtype in varsizefields) then begin + size:= 0; + end; + fd:= TFieldDef.Create(nil,str1,fieldtype,size,False,(i+1)); + fd.collection:= fielddefs; + if fieldtype = ftbcd then begin + if precision > maxprecision then begin + precision:= maxprecision; + end; + fd.precision:= precision; + end; + end; + end; +end; + +function TPQConnection.GetHandle: pointer; +begin + Result := FHandle; +end; + +function TPQConnection.Fetch(cursor : TSQLCursor) : boolean; + +//var st : string; + +begin + with cursor as TPQCursor do + begin + inc(CurTuple); + Result := (PQntuples(res)>CurTuple); + end; +end; + +type + arraytypeheaderty = record +// size: integer; // total array size (varlena requirement) + ndim: cint; // # of dimensions + flags: cint; // implementation flags + // flags field is currently unused, always zero. + elemtype: oid; // element type OID + end; + arraytype = record + header: arraytypeheaderty; + data: record + //dim: array[ndim] of cint; + // size of each array axis (C array of int) + //dim_lower: array[ndim] of cint; + // lower boundary of each dimension (C array of int) + // // whatever is the stored data + end; + end; + parraytype = ^arraytype; + + vararrayboundarty = array of tvararraybound; + +type + TNumericRecord = record + Digits : SmallInt; + Weight : SmallInt; + Sign : SmallInt; + Scale : Smallint; + end; + pnumericrecord = ^tnumericrecord; + +function tpqconnection.loadfield(const cursor: tsqlcursor; + const datatype: tfieldtype; const fieldnum: integer; //zero based + const buffer: pointer; var bufsize: integer; + const aisutf8: boolean): boolean; + //if bufsize < 0 -> buffer was to small, should be -bufsize + + +const + numericpos = $0000; + numericneg = $4000; + numericnan = $8000; + numericsigmask = $c000; + +var +// x{,i} : integer; + CurrBuff : pchar; + + function getnumeric(out numericrecord: tnumericrecord): boolean; + begin + NumericRecord.Digits := BEtoN(pNumericRecord(currbuff)^.Digits); + NumericRecord.Scale := BEtoN(pNumericRecord(currbuff)^.Scale); + NumericRecord.Weight := BEtoN(pNumericRecord(currbuff)^.Weight); + numericrecord.sign:= beton(pnumericrecord(currbuff)^.sign); + inc(currbuff,sizeof(TNumericRecord)); + result:= numericrecord.sign and numericnan = 0; +// if (NumericRecord^.Digits = 0) and (NumericRecord^.Scale = 0) then +// = NaN, which is not supported by Currency-type, so we return NULL + //???? 0 in database seems to return digits and scale 0. mse + end; + + function getfloat4: single; + var + si1: single; + begin + {$ifdef FPC} + integer(si1):= beton(pinteger(currbuff)^); + {$else} + integer(ar4ty(si1)):= beton(pinteger(currbuff)^); + {$endif} + result:= si1; + end; + + function getfloat8: double; + begin + {$ifdef FPC} + int64(result):= beton(pint64(currbuff)^); + {$else} + int64(ar8ty(result)):= beton8(pint64(currbuff)^); + {$endif} + end; + + procedure handleitem(const adatatype: tfieldtype;{ const currbuff: pointer;} + const asize: integer; const atype: integer; var buffer: pchar); + var + li : Longint; +// dbl : pdouble; + cur : currency; + lint1: int64; +// sint1: smallint; + wbo1: wordbool; + do1: double; + int1: integer; + tel: byte; + numericrecord: tnumericrecord; + str1: string; + begin + with TPQCursor(cursor) do begin + case aDataType of + ftInteger,ftSmallint,ftword: begin + int1:= 0; + case asize of // postgres returns big-endian numbers + sizeof(integer): begin + int1:= BEtoN(pinteger(CurrBuff)^); + end; + sizeof(smallint): begin + int1:= BEtoN(psmallint(CurrBuff)^); + end; + end; + move(int1,buffer^,sizeof(int1)); + inc(buffer,sizeof(integer)); + inc(currbuff,asize); + end; + ftlargeint: begin + {$ifdef FPC} + lint1:= BEtoN(pint64(CurrBuff)^); + {$else} + lint1:= BEtoN8(pint64(CurrBuff)^); + {$endif} + move(lint1,buffer^,sizeof(lint1)); + inc(buffer,sizeof(int64)); + inc(currbuff,asize); + end; + ftfloat,ftcurrency: begin + if atype = oid_numeric then begin + if getnumeric(numericrecord) then begin + do1:= 0; + for int1 := NumericRecord.Digits - 1 downto 0 do begin + do1:= do1 + beton(pword(currbuff)^) * intpower(nbase,int1); + inc(currbuff,2); + end; + int1:= numericrecord.weight - numericrecord.digits + 1; + if int1 < 0 then begin + do1:= do1 / intpower(nbase,-int1); + end + else begin + do1:= do1 * intpower(nbase,int1); + end; + if NumericRecord.Sign <> 0 then begin + do1:= -do1; + end; + end + else begin + do1:= nan; + end; + end + else begin + if atype = oid_float4 then begin + do1:= getfloat4; + end + else begin + do1:= getfloat8; + end; + end; + Move(do1, Buffer^, sizeof(do1)); + inc(buffer,sizeof(do1)); + inc(currbuff,asize); + end; + ftString: begin + if datatype = ftvariant then begin + setlength(str1,asize); + move(currbuff^,str1[1],asize); + if aisutf8 then begin + pwidestring(buffer)^:= utf8tostringansi(str1); + end + else begin + pwidestring(buffer)^:= msestring(str1); + end; + inc(buffer,sizeof(widestring)); + inc(currbuff,asize); + end + else begin + li:= pqgetlength(res,curtuple,fieldnum); + if bufsize < li then begin + bufsize:= -li; + end + else begin + bufsize:= li; + Move(CurrBuff^,Buffer^,li); + end; + end; + end; + ftblob,ftmemo,ftgraphic: begin + li := pqgetlength(res,curtuple,fieldnum); + int1:= addblobdata(currbuff,li); + move(int1,buffer^,sizeof(int1)); + //save id + end; + ftdate: begin + do1:= BEtoN(plongint(CurrBuff)^) + 36526; + move(do1,buffer^,sizeof(do1)); + inc(buffer,sizeof(do1)); + inc(currbuff,asize); + end; + ftDateTime,fttime: begin + {$ifdef FPC} + do1:= double(BEtoN(pint64(CurrBuff)^)); + {$else} + do1:= double(ar8ty(BEtoN8(pint64(CurrBuff)^))); + {$endif} + if FIntegerDatetimes then begin + do1:= do1/1000000; + end; + do1:= (do1+3.1558464E+009)/86400; // postgres counts seconds elapsed since 1-1-2000 + // Now convert the mathematically-correct datetime to the + // illogical windows/delphi/fpc TDateTime: + if (do1 <= 0) and (frac(do1)<0) then begin + do1:= trunc(do1)-2-frac(do1); + end; + move(do1,buffer^,sizeof(do1)); + inc(buffer,sizeof(do1)); + inc(currbuff,asize); + end; + ftBCD: begin + + case atype of + oid_float4: begin + cur:= getfloat4; + end; + oid_float8: begin + cur:= getfloat8; + end; + else begin + cur := 0; + result:= getnumeric(numericrecord); + if result then begin + for tel := 1 to NumericRecord.Digits do begin + cur := cur + beton(pword(currbuff)^) * intpower(10000,-(tel-1)+ + NumericRecord.weight); + inc(currbuff,2); + end; + if NumericRecord.Sign <> 0 then begin + cur := -cur; + end; + end; + end; + end; + Move(Cur, Buffer^, sizeof(cur)); + inc(buffer,sizeof(cur)); +// inc(currbuff,asize); + end; + ftBoolean: begin + if datatype = ftvariant then begin + pboolean(buffer)^:= CurrBuff[0] <> #0; + inc(buffer,sizeof(boolean)); + end + else begin + wbo1:= CurrBuff[0] <> #0; + move(wbo1,buffer^,sizeof(wbo1)); + inc(buffer,sizeof(wbo1)); + end; + inc(currbuff,asize); + end; + ftguid: begin + {$ifdef FPC} + with pguid(currbuff)^ do begin + pguid(buffer)^.time_low:= beton(time_low); + pguid(buffer)^.time_mid:= beton(time_mid); + pguid(buffer)^.time_hi_and_version:= beton(time_hi_and_version); + pguid(buffer)^.clock_seq_hi_and_reserved:= clock_seq_hi_and_reserved; + pguid(buffer)^.clock_seq_low:= clock_seq_low; + pguid(buffer)^.node:= node; + end; + {$else} + with pguid_fpc(currbuff)^ do begin + pguid_fpc(buffer)^.time_low:= beton(time_low); + pguid_fpc(buffer)^.time_mid:= beton(time_mid); + pguid_fpc(buffer)^.time_hi_and_version:= beton(time_hi_and_version); + pguid_fpc(buffer)^.clock_seq_hi_and_reserved:= clock_seq_hi_and_reserved; + pguid_fpc(buffer)^.clock_seq_low:= clock_seq_low; + pguid_fpc(buffer)^.node:= node; + end; + {$endif} + inc(buffer,sizeof(tguid)); + inc(currbuff,asize); + end; + else begin + result := false; + end; + end; + end; + end; + +var + int1,int2,int3,eltype: integer; + typ1: tfieldtype; + ar1: vararrayboundarty; + po1: pcint; + po2: pointer; + +begin +{$ifdef FPC}{$checkpointer off}{$endif} + with TPQCursor(cursor) do begin + result:= pqgetisnull(res,CurTuple,fieldnum) = 0; + if not result or (buffer = nil) then begin + exit; + end; + CurrBuff := pqgetvalue(res,CurTuple,fieldnum); + if datatype = ftvariant then begin + with parraytype(currbuff)^,header do begin +// int1:= pqgetlength(res,curtuple,fieldnum); + setlength(ar1,beton(ndim)); + if ar1 = nil then begin + result:= false; + exit; + end; + po1:= @data; + int2:= 1; + for int1:= 0 to high(ar1) do begin + int3:= beton(po1^); + ar1[int1].elementcount:= int3; //dim + inc(po1); + ar1[int1].lowbound:= beton(po1^); //dim_lower + int2:= int2*int3; + inc(po1); + end; +// inc(po1,length(ar1)); //skip dim_lower + eltype:= beton(elemtype); + currbuff:= pointer(po1); + typ1:= arrayinfo[fieldnum].fieldtype; + pvariant(buffer)^:= msevararraycreate(pointer(ar1),length(ar1), + arrayinfo[fieldnum].vartype); + po2:= pvardata(buffer)^.varray^.data; + for int1:= 0 to int2-1 do begin + int3:= beton(pinteger(currbuff)^); //alignment? + inc(pinteger(currbuff)); + handleitem(typ1,int3,eltype,pchar(po2)); + end; + end; + end + else begin + po2:= buffer; + handleitem(datatype,{currbuff,}PQfsize(res,fieldnum),pqftype(res,fieldnum), + pchar(po2)); + end; + end; +{$ifdef FPC}{$checkpointer default}{$endif} +end; + +function TPQConnection.fetchblob(const cursor: tsqlcursor; + const fieldnum: integer): ansistring; +begin + result:= ''; +{$ifdef FPC}{$checkpointer off}{$endif} + with TPQCursor(cursor) do begin + if pqgetisnull(res,CurTuple,fieldnum) <> 1 then begin + setlength(result,pqgetlength(res,curtuple,fieldnum)); + if result <> '' then begin + move(pqgetvalue(res,CurTuple,fieldnum)^,result[1],length(result)); + end; + end; + end; +end; + +procedure tpqconnection.updateindexdefs(var indexdefs : tindexdefs; + const atablename : string; const acursor: tsqlcursor); + +var + qry : tsqlresult; +begin + if not assigned(transaction) then + databaseerror(serrconntransactionnset); + + qry:= tsqlresult.create(nil); + try + with qry do begin + database:= self; + sql.text:= 'select '+ + 'ic.relname as indexname, '+ + 'tc.relname as tablename, '+ + 'ia.attname, '+ + 'i.indisprimary, '+ + 'i.indisunique '+ + 'from '+ + 'pg_attribute ta, '+ + 'pg_attribute ia, '+ + 'pg_class tc, '+ + 'pg_class ic, '+ + 'pg_index i '+ + 'where '+ + '(i.indrelid = tc.oid) and '+ + '(ta.attrelid = tc.oid) and '+ + '(ia.attrelid = i.indexrelid) and '+ + '(ic.oid = i.indexrelid) and '+ + '(ta.attnum = i.indkey[ia.attnum-1]) and '+ + '(upper(tc.relname)=''' + + msestring(UpperCase(aTableName)) +''') '+ + 'order by '+ + 'ic.relname;'; + active:= true; + while not eof do begin + with IndexDefs.AddIndexDef do begin + Name:= trim(qry.cols[0].asstring); + Fields:= trim(qry.cols[2].asstring); + If cols[3].asboolean then begin + options:= options + [ixPrimary]; + end; + If cols[4].asboolean then begin + options:= options + [ixUnique]; + end; + next; + while not qry.eof and (name = cols[0].asstring) do begin + fields:= fields + ';' + trim(cols[2].asstring); + next; + end; + end; + end; + end; + finally + qry.free; + end; +end; + +function TPQConnection.GetSchemaInfoSQL(SchemaType: TSchemaType; + SchemaObjectName, SchemaPattern: msestring): msestring; + +var s : msestring; + +begin + s:= ''; + case SchemaType of + stTables : s := 'select '+ + 'relfilenode as recno, '+ + '''' + msestring(DatabaseName) + + ''' as catalog_name, '+ + ''''' as schema_name, '+ + 'relname as table_name, '+ + '0 as table_type '+ + 'from '+ + 'pg_class '+ + 'where '+ + '(relowner > 1) and relkind=''r''' + + 'order by relname'; + + stSysTables : s := 'select '+ + 'relfilenode as recno, '+ + '''' + msestring(DatabaseName) + + ''' as catalog_name, '+ + ''''' as schema_name, '+ + 'relname as table_name, '+ + '0 as table_type '+ + 'from '+ + 'pg_class '+ + 'where '+ + 'relkind=''r''' + + 'order by relname'; + else + DatabaseError(SMetadataUnavailable) + end; {case} + result := s; +end; + +function TPQConnection.CreateBlobStream(const Field: TField; + const Mode: TBlobStreamMode; const acursor: tsqlcursor): TStream; +var + blobid: integer; +// int1,int2: integer; +// str1: string; +// bo1: boolean; +begin + result:= nil; + if mode = bmread then begin + if field.getData(@blobId) then begin + result:= acursor.getcachedblob(blobid); + end; + end; +end; + +procedure TPQConnection.writeblobdata(const atransaction: tsqltransaction; + const tablename: string; const acursor: tsqlcursor; + const adata: pointer; const alength: integer; + const afield: tfield; const aparam: tparam; + out newid: string); +var + str1: string; + int1: integer; +begin + setlength(str1,alength); + move(adata^,str1[1],alength); + if afield.datatype = ftmemo then begin + aparam.asmemo:= str1; + end + else begin + aparam.asblob:= str1; + end; + int1:= acursor.addblobdata(str1); + setlength(newid,sizeof(int1)); + move(int1,newid[1],sizeof(int1)); +end; + +procedure TPQConnection.setupblobdata(const afield: tfield; + const acursor: tsqlcursor; const aparam: tparam); +begin + acursor.blobfieldtoparam(afield,aparam,false); +end; +{ +function TPQConnection.getfeatures(): databasefeaturesty; +begin + result:= inherited getfeatures() + [dbf_blobscached]; +end; +} +function TPQConnection.getblobdatasize: integer; +begin + result:= sizeof(integer); +end; +{ +function TPQConnection.blobscached: boolean; +begin + result:= true; +end; +} +procedure TPQConnection.dolisten(const sender: tdbevent); +begin + dopqexec('LISTEN '+sender.eventname+';'); +end; + +procedure TPQConnection.dounlisten(const sender: tdbevent); +begin + dopqexec('UNLISTEN '+sender.eventname+';'); +end; + +procedure TPQConnection.listen(const sender: tdbevent); +begin + feventcontroller.register(sender); + if connected then begin + dolisten(sender); + end; +end; + +procedure TPQConnection.unlisten(const sender: tdbevent); +begin + if connected then begin + dounlisten(sender); + end; + feventcontroller.unregister(sender); +end; + +procedure TPQConnection.fire(const sender: tdbevent); +begin + dopqexec('NOTIFY '+sender.eventname+';'); +end; + +function TPQConnection.getdbevent(var aname: string; var aid: int64): boolean; +var + info: ppgnotify; +begin + pqconsumeinput(fhandle); + info:= pqnotifies(fhandle); + result:= info <> nil; + if result then begin + aname:= info^.relname; + aid:= info^.be_pid; + pqfreemem(info); + end; +end; + +function TPQConnection.geteventinterval: integer; +begin + result:= feventcontroller.eventinterval; +end; + +procedure TPQConnection.seteventinterval(const avalue: integer); +begin + feventcontroller.eventinterval:= avalue; +end; + +procedure tpqconnection.dopqexec(const asql: ansistring; const aconnection: ppgconn); +var + res: ppgresult; +begin + res:= pqexec(aconnection,pchar(asql)); + if pqresultstatus(res) <> pgres_command_ok then begin + pqclear(res); + databaseerror('PQExecerror'+ ' (postgresql: ' + + ansistring(connectionmessage(pqerrormessage(aconnection))) + + ')',self); + end + else begin + pqclear(res); + end; +end; + +procedure tpqconnection.dopqexec(const asql: ansistring); +begin + dopqexec(asql,fhandle); +end; + +function TPQConnection.backendpid: int64; +begin + if not connected then begin + result:= 0; + end + else begin + result:= pqbackendpid(fhandle); + end; +end; + +function TPQConnection.getnumboolean: boolean; +begin + result:= false; +end; + +procedure TPQConnection.closeconnection(var aconnection: ppgconn); +begin + if aconnection <> nil then begin + PQfinish(aconnection); + aconnection:= nil; + end; +end; + +procedure TPQConnection.finalizetransaction(const atransaction: tsqlhandle); +begin + with tpqtrans(atransaction) do begin + if (fconn <> fhandle) then begin + closeconnection(fconn); + end; + fconn:= nil; + end; +end; + +{ +procedure TPQConnection.writeblobdata(const atransaction: tsqltransaction; + const tablename: string; const adata: pointer; + const alength: integer; const aparam: tparam); + +var + started: boolean; + + procedure endtrans; + var + res: ppgresult; + begin + res:= pqexec(fsqldatabasehandle,'END'); + pqclear(res); + end; + + procedure doerror; + begin + if started then begin + endtrans; + end; + databaseerror('TPQConnection blob write error.'); + end; + + procedure checkerror(const aresult: ppgresult); + begin + if PQresultStatus(aresult) <> PGRES_COMMAND_OK then begin + pqclear(aresult); + doerror; + end; + pqclear(aresult); + end; + +var + blobid: oid; + fd: integer; + int1,int2: integer; +begin + if alength = 0 then begin + aparam.clear; + end + else begin + started:= false; + checkerror(pqexec(fsqldatabasehandle,'BEGIN')); + started:= true; + blobid:= lo_creat(fsqldatabasehandle,inv_read or inv_write); + if blobid = invalidoid then begin + doerror; + end; + fd:= lo_open(fsqldatabasehandle,blobid,inv_write); + if fd = -1 then begin + doerror; + end; + int1:= alength; + while int1 > 0 do begin + int2:= lo_write(fsqldatabasehandle,fd,adata,int1); + if int2 < 0 then begin + doerror; + end; + dec(int1,int2); + end; + lo_close(fsqldatabasehandle,fd); + endtrans; + aparam.asinteger:= blobid; + end; +end; +} + +{ epqerror } + +constructor epqerror.create(const asender: tcustomsqlconnection; + const amessage: ansistring; const aerrormessage: msestring; + const asqlcode: string); +begin + fsqlcode:= asqlcode; + inherited create(asender,amessage,aerrormessage,-1); +end; + +end. diff --git a/mseide-msegui/lib/common/db/msebufdataset.pas b/mseide-msegui/lib/common/db/msebufdataset.pas new file mode 100644 index 0000000..5b03789 --- /dev/null +++ b/mseide-msegui/lib/common/db/msebufdataset.pas @@ -0,0 +1,10892 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 1999-2000 by Michael Van Canneyt, member of the + Free Pascal development team + + + BufDataset implementation + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Rewritten 2006-2018 by Martin Schreiber + + **********************************************************************} + +unit msebufdataset; +{$ifdef FPC} + {$mode objfpc}{$h+}{$GOTO ON}{$interfaces corba} + {$define mse_hasvtunicodestring} +{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + mdb,classes,mclasses,variants,msetypes,msearrayprops,mseclasses,mselist, + msestrings, + msedb,msedatabase,mseglob,msearrayutils,msedatalist,msevariants, + msestream; + +const + defaultpacketrecords = -1; + integerindexfields = [ftsmallint,ftinteger,ftword,ftboolean]; + largeintindexfields = [ftlargeint]; + floatindexfields = [ftfloat,{ftcurrency,}ftdatetime,ftdate,fttime]; + currencyindexfields = [ftcurrency,ftbcd]; + stringindexfields = [ftstring,ftfixedchar]; + guidindexfields = [ftguid]; + indexfieldtypes = integerindexfields+largeintindexfields+floatindexfields+ + currencyindexfields+stringindexfields+guidindexfields; + dsbuffieldkinds = [fkcalculated,fklookup]; + bufferfieldkinds = [fkdata]; + + dscheckfilter = ord(high(tdatasetstate)) + 1; + +const + bufstreambuffersize = 4096; + +type + + fieldinfo_0ty = record //version 0 + offset: integer; //data offset in buffer //// + size: integer; //size in buffer // checked by save/restore + fieldtype: tfieldtype; // + dbfieldsize: integer; //maxsize of dbfield //// + {$ifdef cpu64} + field: card32; + {$else} + field: tfield; //last! + {$endif} + end; + + fieldinfobasety = record + offset: integer; //data offset in buffer //// + size: integer; //size in buffer // checked by save/restore + fieldtype: tfieldtype; // + dbfieldsize: integer; //maxsize of dbfield //// + end; + pfieldinfobasety = ^fieldinfobasety; + + fieldinfoextty = record + basetype: tfieldtype; + field: tfield; + uppername: string; + end; + fieldinfoty = record + base: fieldinfobasety; + ext: fieldinfoextty; + end; + + fieldinfoarty = array of fieldinfoty; + + fielddataty = record + nullmask: array[0..0] of byte; //variable length + //fielddata following + end; + + blobcacheinfoty = record + id: int64; + data: string; + end; + blobcacheinfoarty = array of blobcacheinfoty; + + blobinfoty = record + field: tfield; + data: pointer; + datalength: integer; + new: boolean; + end; + + pblobinfoty = ^blobinfoty; + blobinfoarty = array of blobinfoty; + pblobinfoarty = ^blobinfoarty; + + blobstreamfixinfoty = record + id: int64; + new: boolean; + current: boolean; + end; + blobstreaminfoty = record + info: blobstreamfixinfoty; + data: string; + end; + + recheaderty = record + blobinfo: blobinfoarty; + fielddata: fielddataty; + end; + precheaderty = ^recheaderty; + pprecheaderty = ^precheaderty; + + intheaderty = record + end; + + intrecordty = record + intheader: intheaderty; + header: recheaderty; + end; + pintrecordty = ^intrecordty; + ppintrecordty = ^pintrecordty; + + bookmarkdataty = record + recno: integer; + recordpo: pintrecordty; + end; + pbookmarkdataty = ^bookmarkdataty; + + bufbookmarkty = record + data: bookmarkdataty; + flag : tbookmarkflag; + end; + pbufbookmarkty = ^bufbookmarkty; + + dsheaderty = record + bookmark: bufbookmarkty; + end; + dsrecordty = record + dsheader: dsheaderty; + header: recheaderty; + end; + pdsrecordty = ^dsrecordty; + +const + intheadersize = sizeof(intheaderty); + dsheadersize = sizeof(dsheaderty); + +// structure of internal recordbuffer: +// +------------------+ +// intrecheaderty, |recheaderty,nullflags,fielddata| +// |moved to tdataset buffer header| +// |fieldoffsets are in ffieldinfos[].offset +// | | +// structure of dataset recordbuffer: +// +-----------------------------------+ +// +------------------+ | +// dsrecheaderty, |recheaderty,nullflags,fielddata|nullflags,calcfields| +// |moved to internal buffer header| | +// |<-field offsets are in ffieldinfos[].offset | +// |<-calcfield offsets are in fcalcfieldbufpositions | + +type + indexty = record + ind: pointerarty; + end; + pindexty = ^indexty; + + tmsebufdataset = class; + + logflagty = (lf_end,lf_rec,lf_update,lf_cancel,lf_apply,lf_drop); + reclogheader32ty = record + kind: tupdatekind; + po: card32; + end; +{$packrecords 8} + reclogheaderty = record + kind: tupdatekind; + po: card64; //pointer; + end; +{$packrecords default} + updatekindty = (uk_modify=ord(ukmodify),uk_insert=ord(ukinsert), + uk_delete=ord(ukdelete),uk_modifyinupdate); + updatelogheader32ty = record + logging: boolean; + kind: updatekindty; + po: card32; + deletedrecord: card32; + end; +{$packrecords 8} //64 bit compatible + updatelogheaderty = record + logging: boolean; + kind: updatekindty; + po: card64; //pointer; + deletedrecord: card64; //pintrecordty; + end; +{$packrecords default} + logbufferheader32ty = record + case logflag: logflagty of + lf_rec: ( + rec: reclogheader32ty; + ); + lf_update,lf_cancel,lf_apply,lf_drop: ( + update: updatelogheader32ty; + ); + end; +{$packrecords 8} //64 bit compatible + logbufferheaderty = record + case logflag: logflagty of + lf_rec: ( + rec: reclogheaderty; + ); + lf_update,lf_cancel,lf_apply,lf_drop: ( + update: updatelogheaderty; + ); + end; +{$packrecords default} + + tbufstreamwriter = class + private + fstream: tstream; + fowner: tmsebufdataset; + fbuffer: array [0..bufstreambuffersize-1] of byte; + fbufindex: integer; + procedure flushbuffer; + public + constructor create(const aowner: tmsebufdataset; const astream: tstream); + destructor destroy; override; + procedure write(const buffer; length: integer); + procedure writefielddata(const data: precheaderty; + const aindex: integer); + procedure writestring(const avalue: string); + procedure writemsestring(const avalue: msestring); + procedure writeinteger(const avalue: integer); + procedure writepointer(const avalue: pointer); + procedure writevariant(const avalue: variant); + + procedure writefielddef(const afielddef: tfielddef); + procedure writelogbufferheader(const aheader: logbufferheaderty); + procedure writeendmarker; + end; + + tbufstreamreader = class + private + fstream: tstream; + fowner: tmsebufdataset; + fbuffer: array [0..bufstreambuffersize-1] of byte; + fbuflen: integer; + fbufindex: integer; + protected + f32to64: boolean; + public + constructor create(const aowner: tmsebufdataset; const astream: tstream); + function read(out buffer; length: integer): integer; + procedure readbuffer(out buffer; const length: integer); + procedure readfielddata(const data: precheaderty; const aindex: integer); + function readstring: string; + function readmsestring: msestring; + function readinteger: integer; + function readpointer: pointer; + function readvariant: variant; + procedure readfielddef(const aowner: tfielddefs); + function readlogbufferheader(out aheader: logbufferheaderty): boolean; + //false if eof or lf_end + procedure readrecord(const arecord: pintrecordty); + end; + + resolverresponsety = (rr_abort,rr_quiet,rr_revert,rr_again,rr_applied, + rr_skipped); //for fkinternalcalc only updates + resolverresponsesty = set of resolverresponsety; + + updateerroreventty = procedure( + const sender: tmsebufdataset; + var e: edatabaseerror; const updatekind: tupdatekind; + var response: resolverresponsesty) of object; + + tblobbuffer = class(tmemorystream) + private + fowner: tmsebufdataset; + ffield: tfield; + public + constructor create(const aowner: tmsebufdataset; const afield: tfield); + destructor destroy; override; + end; + + tblobcopy = class(tmemorystream) + public + constructor create(const ablob: blobinfoty); + destructor destroy; override; + end; + + indexfieldoptionty = (ifo_desc,ifo_caseinsensitive,ifo_natural); + indexfieldoptionsty = set of indexfieldoptionty; + + tindexfield = class(townedpersistent) + private + ffieldname: string; + foptions: indexfieldoptionsty; + procedure change; + procedure setfieldname(const avalue: string); + procedure setoptions(const avalue: indexfieldoptionsty); + published + property fieldname: string read ffieldname write setfieldname; + property options: indexfieldoptionsty read foptions + write setoptions default []; + end; + + localindexoptionty = (lio_desc,lio_default, + lio_quicksort); //default is mergesort + + localindexoptionsty = set of localindexoptionty; + + tlocalindex = class; + + tindexfields = class(townedpersistentarrayprop) + private + function getitems(const index: integer): tindexfield; + public + constructor create(const aowner: tlocalindex); reintroduce; + class function getitemclasstype: persistentclassty; override; + property items[const index: integer]: tindexfield read getitems; default; + published + property count default 1; + end; + + intrecordpoaty = array[0..0] of pintrecordty; + pintrecordpoaty = ^intrecordpoaty; + indexfieldinfoty = record + fieldinstance: tfield; + comparefunc: arraysortcomparety; + vtype: integer; + recoffset: integer; + fieldindex: integer; + islookup: boolean; + desc: boolean; + caseinsensitive: boolean; + canpartialstring: boolean; + end; + indexfieldinfoarty = array of indexfieldinfoty; + indexcomparefuncty = function (l,r: pintrecordty; const alastindex: integer; + const apartialstring: boolean): integer of object; + + tlocalindex = class(townedpersistent) + private + ffields: tindexfields; + foptions: localindexoptionsty; + fsortarray: pintrecordpoaty; + findexfieldinfos: indexfieldinfoarty; + finvalid: boolean; + fhaslookup: boolean; + fname: string; + procedure setoptions(const avalue: localindexoptionsty); + procedure setfields(const avalue: tindexfields); + function dolookupcompare(const l,r: pintrecordty; + const ainfo: indexfieldinfoty; + const apartialstring: boolean): integer; + function dolookupcomparea(const lvalue: pointer; r: pintrecordty; + const ainfo: indexfieldinfoty; + const apartialstring: boolean): integer; + //lvalue is compare value, r can be lookup + function compare1(l,r: pintrecordty; const alastindex: integer; + const apartialstring: boolean): integer; + function compare1a(l,r: pintrecordty; const alastindex: integer; + const apartialstring: boolean): integer; + //l is compare value record, r can be lookup + function compare2(l,r: pintrecordty): integer; + {$ifndef FPC} + function compare3(l,r: pointer): integer; + {$endif} + procedure quicksort(l,r: integer); +// procedure mergesort(var adata: pointerarty); + procedure sort(var adata: pointerarty); + function getactive: boolean; + procedure setactive(const avalue: boolean); + procedure bindfields; + function findboundary(const comparefunc: indexcomparefuncty; + const arecord: pintrecordty; + const alastindex: integer; const abigger: boolean): integer; + //returns index of next bigger or lower + function findrecord(const arecord: pintrecordty): integer; + //returns index, -1 if not found + function getdesc: boolean; + procedure setdesc(const avalue: boolean); + function getdefault: boolean; + procedure setdefault(const avalue: boolean); + protected + procedure change; + public + constructor create(aowner: tobject); override; + destructor destroy; override; + function find(const avalues: array of const; + //nil -> NULL field + const aisnull: array of boolean; + //itemcount of avalues and aisnull + //can be smaller than fields count in index + //itemcount of aisnull can be smaller than itemcount of avalues + out abookmark: bookmarkdataty; + const abigger: boolean = false; + const partialstring: boolean = false; + const nocheckbrowsemode: boolean = false; + const filtered: boolean = false): boolean; overload; + //true if found else nearest lower or bigger, + //abookmark = '' if no lower or bigger found + //string values must be msestring + function find(const avalues: array of const; + //nil -> NULL field + const aisnull: array of boolean; + //itemcount of avalues and aisnull + //can be smaller than fields count in index + //itemcount of aisnull can be smaller than itemcount of avalues + out abookmark: bookmarkty; + const abigger: boolean = false; + const partialstring: boolean = false; + const nocheckbrowsemode: boolean = false; + const filtered: boolean = false): boolean; overload; + //true if found else nearest lower or bigger, + //abookmark = '' if no lower or bigger found + //string values must be msestring + function findvariant(const avalue: array of variant; + out abookmark: bookmarkty; + const abigger: boolean = false; + const partialstring: boolean = false; + const nocheckbrowsemode: boolean = false; + const filtered: boolean = false): boolean; overload; + //true if found else nearest lower or bigger, + //abookmark = '' if no lower or bigger found + //string values must be msestring + function find(const avalues: array of tfield; + out abookmark: bookmarkty; + const abigger: boolean = false; + const partialstring: boolean = false; + const nocheckbrowsemode: boolean = false; + const filtered: boolean = false): boolean; overload; + //true if found else nearest lower or bigger, + //abookmark = '' if no lower or bigger found + function find(const avalues: array of tfield; + out abookmark: bookmarkdataty; + const abigger: boolean = false; + const partialstring: boolean = false; + const nocheckbrowsemode: boolean = false; + const filtered: boolean = false): boolean; overload; + //true if found else nearest lower or bigger, + + function find(const avalues: array of const; + //nil -> NULL field + const aisnull: array of boolean; + //itemcount of avalues and aisnull + //can be smaller than fields count in index + //itemcount of aisnull can be smaller than itemcount of avalues + const abigger: boolean = false; + const partialstring: boolean = false; + const nocheckbrowsemode: boolean = false; + const exact: boolean = true; + const filtered: boolean = true): boolean; overload; + //sets dataset cursor if found + function find(const avalues: array of tfield; + const abigger: boolean = false; + const partialstring: boolean = false; + const nocheckbrowsemode: boolean = false; + const exact: boolean = true; + const filtered: boolean = true): boolean; overload; + //sets dataset cursor if found + function findvariant(const avalue: array of variant; + const abigger: boolean = false; + const partialstring: boolean = false; + const nocheckbrowsemode: boolean = false; + const exact: boolean = true; + const filtered: boolean = true): boolean; overload; + //sets dataset cursor if found + + function unique(const avalues: array of const): boolean; + procedure deleteduplicates(); //does not store recupdates, no delete events + function getbookmark(const arecno: integer): bookmarkty; + property desc: boolean read getdesc write setdesc; + property default: boolean read getdefault write setdefault; + published + property fields: tindexfields read ffields write setfields; + property options: localindexoptionsty read foptions + write setoptions default []; + property active: boolean read getactive write setactive default false; + property name: string read fname write fname; + //case sensitive + end; + + bufdataseteventty = procedure(const sender: tmsebufdataset) of object; + + tlocalindexes = class(townedpersistentarrayprop) + private + fonindexchanged: bufdataseteventty; + function getitems(const index: integer): tlocalindex; + procedure bindfields; + function getactiveindex: integer; + procedure setactiveindex(const avalue: integer); + function getdefaultindex: integer; + procedure setdefaultindex(const avalue: integer); + protected + procedure checkinactive; + procedure setcount1(acount: integer; doinit: boolean); override; + procedure doindexchanged; + public + constructor create(const aowner: tmsebufdataset); reintroduce; + class function getitemclasstype: persistentclassty; override; + procedure move(const curindex,newindex: integer); override; + property items[const index: integer]: tlocalindex read getitems; default; + function indexbyname(const aname: string): tlocalindex; //case sensitive + property activeindex: integer read getactiveindex + write setactiveindex; //-1 > none + property defaultindex: integer read getdefaultindex + write setdefaultindex; //-1 > none + function fieldactive(const afield: tfield): boolean; + //true if field in active index + function hasfield(const afield: tfield): boolean; + //true if field in any index + function fieldmodified(const afield: tfield; const delayed: boolean): boolean; + procedure preparefixup; //clear changed indexes + published + property onindexchanged: bufdataseteventty read fonindexchanged + write fonindexchanged; + end; + + recupdateflagty = (ruf_applied,ruf_error,ruf_append,ruf_inupdate); + recupdateflagsty = set of recupdateflagty; + + recupdateinfoty = record + updatekind: tupdatekind; + flags: recupdateflagsty; + bookmark: bookmarkdataty; + end; + recupdateinfoarty = array of recupdateinfoty; + + recupdatebufferty = record + info: recupdateinfoty; + oldvalues: pintrecordty; + end; + precupdatebufferty = ^recupdatebufferty; + + recupdatebufferarty = array of recupdatebufferty; + + + bufdatasetstatety = (bs_opening,bs_loading,bs_fetching, + bs_displaydata,bs_applying,bs_recapplying, + bs_curvaluemodified, + bs_curvalueset,{bs_curindexinvalid,} + bs_connected, + bs_hasindex,bs_fetchall,bs_initinternalcalc, + bs_blobsfetched,bs_blobscached,bs_blobssorted, + bs_hasvalidindex, + bs_editing,bs_append,bs_internalcalc,bs_startedit, + bs_utf8, + bs_hasfilter,bs_visiblerecordcountvalid, + bs_refreshing,bs_restorerecno,bs_idle, + bs_noautoapply, + bs_refreshinsert,bs_refreshupdate, + bs_refreshinsertindex,bs_refreshupdateindex, + bs_inserttoupdate + //used by tsqlquery + ); + bufdatasetstatesty = set of bufdatasetstatety; + + bufdatasetstate1ty = (bs1_needsresync,bs1_inupdatechanged, + bs1_lookupnotifying,bs1_lookupnotifypending,bs1_posting,bs1_recordupdating, + bs1_deferdeleterecupdatebuffer,bs1_restoreupdate, + bs1_onidleregistered); + bufdatasetstates1ty = set of bufdatasetstate1ty; + + internalcalcfieldseventty = procedure(const sender: tmsebufdataset; + const fetching: boolean) of object; + iblobchache = interface(inullinterface) + function blobsarefetched: boolean; + function getblobcache: blobcacheinfoarty; + function addblobcache(const adata: pointer; + const alength: integer): integer; overload; + function addblobcache(const aid: int64; const adata: string): integer; overload; + end; + + ecurrentvalueaccess = class(edatabaseerror) + public + constructor create(const adataset: tdataset; const afield: tfield; + const msg: string); + end; + + eapplyerror = class(edatabaseerror) + private + fresponse: resolverresponsesty; + public + constructor create(const msg: string = ''; + const aresponse: resolverresponsesty = []); + property response: resolverresponsesty read fresponse write fresponse; + end; + + lookupdataty = record //todo: case items? + po: pointer; + int: integer; + lint: int64; + doub: double; + cur: currency; + mstr: msestring; + boo: longbool; + vari: variant; + dt: tdatetime; + guid: tguid; + end; + + getbmvalueeventty = procedure (const afield: tfield; const bm: bookmarkdataty; + var adata: lookupdataty) of object; + lookupfieldinfoty = record + getvalue: getbmvalueeventty; + keyfieldar: fieldarty; + indexnum: integer; + valuefield: tfield; + lookupvaluefield: tfield; + basedatatype: tfieldtype; + hasindex: boolean; + end; + lookupfieldinfoarty = array of lookupfieldinfoty; + + filterediteventty = procedure(const sender: tmsebufdataset; + const akind: filtereditkindty) of object; + bufdatasetarty = array of tmsebufdataset; + + bufdatasetoptionty = (bdo_postsavepoint,bdo_deletesavepoint, + bdo_cancelupdateonerror,bdo_cancelupdatesonerror, + bdo_cancelupdateondeleteerror, + bdo_editonapplyerror, + bdo_restoreupdateonsavepointrollback, + bdo_rollbackonupdateerror, + bdo_noapply,bdo_autoapply,bdo_autoapplyexceptions, + bdo_autocommitret,bdo_autocommit, + bdo_refreshafterapply,bdo_recnoapplyrefresh, + bdo_refreshtransaction, + bdo_notransactionrefresh,bdo_recnotransactionrefresh, + bdo_checkbrowsemodebylookupchange, + bdo_noprepare, + bdo_cacheblobs, + bdo_offline, //disconnect database after open + bdo_local //do not connect database on open + ); + bufdatasetoptionsty = set of bufdatasetoptionty; +const + defaultbufdatasetoptions = []; + oldbdsoptions = [ + bdo_postsavepoint,bdo_deletesavepoint, + bdo_cancelupdateonerror,bdo_cancelupdatesonerror, + bdo_cancelupdateondeleteerror, + bdo_editonapplyerror, + bdo_restoreupdateonsavepointrollback, + bdo_noapply,bdo_autoapply, + bdo_autocommitret,bdo_autocommit, + bdo_refreshafterapply,bdo_recnoapplyrefresh, + bdo_refreshtransaction, + bdo_notransactionrefresh,bdo_recnotransactionrefresh, + bdo_noprepare, + bdo_cacheblobs, + bdo_offline, //disconnect database after open + bdo_local //do not connect database on open + ]; + +type + tmsebufdataset = class(tmdbdataset,iblobchache,idatasetsum,imasterlink, + idbdata,iobjectlink) + private + fpacketrecords: integer; + fopen: boolean; + fupdatebuffer: recupdatebufferarty; + fcurrentupdatebuffer: integer; +// fstatebefore: tdatasetstate; +// fcurrentbufbefore: pintrecordty; + + frecordsize: integer; + fnullmasksize: integer; + fcalcfieldcount: integer; + finternalcalcfieldcount: integer; + fstringpositions: integerarty; + fvarpositions: integerarty; + + fcalcrecordsize: integer; + fcalcnullmasksize: integer; + fcalcfieldbufpositions: integerarty; + fcalcfieldsizes: integerarty; + fcalcstringpositions: integerarty; + fcalcvarpositions: integerarty; + flookupfieldinfos: lookupfieldinfoarty; + flookupclients: bufdatasetarty; + flookupmasters: bufdatasetarty; + fnotifylookupclientcount: integer; + flookupupdate: integer; + + fbuffercountbefore: integer; + fonupdateerror: updateerroreventty; + + femptybuffer: pintrecordty; + ffilterbuffer: array[filtereditkindty] of pdsrecordty; + fcheckfilterbuffer: pdsrecordty; + fnewvaluebuffer: pdsrecordty; //buffer for applyupdates +// flookupbuffer: pdsrecordty; + flookuppo: pintrecordty; + flookupresult: lookupdataty; + fcalcbuffer1: pchar; + + findexlocal: tlocalindexes; + factindex: integer; + foninternalcalcfields: internalcalcfieldseventty; + fvisiblerecordcount: integer; + floadingstream: tstream; + + flogfilename: filenamety; + flogger: tbufstreamwriter; + fbeforeapplyupdate: tdatasetnotifyevent; + fafterapplyupdate: tdatasetnotifyevent; + fbeforebeginfilteredit: filterediteventty; + fafterbeginfilteredit: filterediteventty; + fbeforeendfilteredit: filterediteventty; + fafterendfilteredit: filterediteventty; + ffiltereditkind: filtereditkindty; + + fobjectlinker: tobjectlinker; + fcryptohandler: tcustomcryptohandler; + fdelayedapplycount: integer; + fbeforefilterchanged: bufdataseteventty; + fafterfilterchanged: bufdataseteventty; + procedure calcrecordsize; + function loadbuffer(var buffer: recheaderty): tgetresult; + function getfieldsize(const datatype: tfieldtype; const varsize: integer; + out basetype: tfieldtype) : longint; + function getrecordupdatebuffer: boolean; + procedure setpacketrecords(avalue: integer); + function intallocrecord: pintrecordty; + procedure finalizevalues(var header: recheaderty); + procedure finalizecalcvalues(var header: recheaderty); + procedure addrefvalues(var header: recheaderty); + procedure intfinalizerecord(const buffer: pintrecordty); + procedure intfreerecord(var buffer: pintrecordty); + procedure freeblobcache(const arec: precheaderty; const afield: tfield); + + procedure clearindex; + procedure checkindexsize; + function appendrecord(const arecord: pintrecordty): integer; + //returns new recno + function insertrecord(arecno: integer; const arecord: pintrecordty): integer; + //returns new recno + procedure deleterecord(const arecno: integer); overload; + procedure deleterecord(const arecord: pintrecordty); overload; + procedure getnewupdatebuffer; + procedure dropupdates1(const apply: boolean); + procedure setindexlocal(const avalue: tlocalindexes); + function insertindexrefs(const arecord: pintrecordty): integer; + //returns new recno of active index + procedure removeindexrefs(const arecord: pintrecordty); + function remove0indexref(const arecord: pintrecordty): integer; + //returns index + procedure internalsetrecno(const avalue: integer); + procedure setactindex(const avalue: integer); + procedure checkindex(const aid: integer{; const force: boolean}); + + function getmsestringdata(const sender: tmsestringfield; + out avalue: msestring): boolean; + procedure setmsestringdata(const sender: tmsestringfield; avalue: msestring); + function getvardata(const sender: tmsevariantfield; + out avalue: variant): boolean; + procedure setvardata(const sender: tmsevariantfield; avalue: variant); + procedure setoninternalcalcfields(const avalue: internalcalcfieldseventty); + procedure checkfilterstate; + procedure checklogfile; + procedure initsavepoint; + procedure dointernalopen; + procedure doloadfromstream; + procedure dointernalclose; + procedure logupdatebuffer(const awriter: tbufstreamwriter; + const abuffer: recupdatebufferty; const adeletedrecord: pintrecordty; + const alogging: boolean; const alogmode: logflagty); + procedure logrecbuffer(const awriter: tbufstreamwriter; + const akind: tupdatekind; const abuffer: pintrecordty); + function getlogging: boolean; + procedure checksumfield(const afield: tfield; const fieldtypes: fieldtypesty); + function getcurrentasfloat(const afield: tfield; aindex: integer): double; + procedure setcurrentasfloat(const afield: tfield; aindex: integer; + const avalue: double); + function getcurrentisnull(const afield: tfield; aindex: integer): boolean; + function getcurrentasboolean(const afield: tfield; aindex: integer): boolean; + procedure setcurrentasboolean(const afield: tfield; aindex: integer; + const avalue: boolean); + function getcurrentasinteger(const afield: tfield; aindex: integer): integer; + procedure setcurrentasinteger(const afield: tfield; aindex: integer; + const avalue: integer); + function getcurrentaslargeint(const afield: tfield; aindex: integer): int64; + procedure setcurrentaslargeint(const afield: tfield; aindex: integer; + const avalue: int64); + function getcurrentasdatetime(const afield: tfield; aindex: integer): tdatetime; + procedure setcurrentasdatetime(const afield: tfield; aindex: integer; + const avalue: tdatetime); + function getcurrentascurrency(const afield: tfield; aindex: integer): currency; + procedure setcurrentascurrency(const afield: tfield; aindex: integer; + const avalue: currency); + function getcurrentasmsestring(const afield: tfield; + aindex: integer): msestring; + procedure setcurrentasmsestring(const afield: tfield; aindex: integer; + const avalue: msestring); + function getcurrentasguid(const afield: tfield; aindex: integer): tguid; + procedure setcurrentasguid(const afield: tfield; aindex: integer; + const avalue: tguid); + function getcurrentasid(const afield: tfield; aindex: integer): int64; + procedure setcurrentasid(const afield: tfield; aindex: integer; + const avalue: int64); + procedure setbookmarkdata1(const avalue: bookmarkdataty); + function getcurrentbmisnull(const afield: tfield; + const abm: bookmarkdataty): boolean; + function getcurrentbmasboolean(const afield: tfield; + const abm: bookmarkdataty): boolean; + procedure setcurrentbmasboolean(const afield: tfield; + const abm: bookmarkdataty; + const avalue: boolean); + function getcurrentbmasinteger(const afield: tfield; + const abm: bookmarkdataty): integer; + procedure setcurrentbmasinteger(const afield: tfield; + const abm: bookmarkdataty; + const avalue: integer); + function getcurrentbmaslargeint(const afield: tfield; + const abm: bookmarkdataty): int64; + procedure setcurrentbmaslargeint(const afield: tfield; + const abm: bookmarkdataty; + const avalue: int64); + function getcurrentbmasid(const afield: tfield; + const abm: bookmarkdataty): int64; + procedure setcurrentbmasid(const afield: tfield; + const abm: bookmarkdataty; + const avalue: int64); + function getcurrentbmasfloat(const afield: tfield; + const abm: bookmarkdataty): double; + procedure setcurrentbmasfloat(const afield: tfield; + const abm: bookmarkdataty; + const avalue: double); + function getcurrentbmasdatetime(const afield: tfield; + const abm: bookmarkdataty): tdatetime; + procedure setcurrentbmasdatetime(const afield: tfield; + const abm: bookmarkdataty; + const avalue: tdatetime); + function getcurrentbmascurrency(const afield: tfield; + const abm: bookmarkdataty): currency; + procedure setcurrentbmascurrency(const afield: tfield; + const abm: bookmarkdataty; + const avalue: currency); + function getcurrentbmasmsestring(const afield: tfield; + const abm: bookmarkdataty): msestring; + procedure setcurrentbmasmsestring(const afield: tfield; + const abm: bookmarkdataty; + const avalue: msestring); + function getcurrentbmasguid(const afield: tfield; + const abm: bookmarkdataty): tguid; + procedure setcurrentbmasguid(const afield: tfield; + const abm: bookmarkdataty; + const avalue: tguid); + procedure docurrentassign(const po1: pointer; + const abasetype: tfieldtype; const df: tfield); + procedure lookupdschanged(const sender: tmsebufdataset); + procedure notifylookupclients; + function getcurrentasvariant(const afield: tfield; aindex: integer): variant; + procedure setcurrentasvariant(const afield: tfield; aindex: integer; + const avalue: variant); + function getchangerecords: recupdateinfoarty; + function getapplyerrorrecords: recupdateinfoarty; + function getcurrentbmasvariant(const afield: tfield; + const abm: bookmarkdataty): variant; + procedure setcurrentbmasvariant(const afield: tfield; + const abm: bookmarkdataty; const avalue: variant); + procedure setcryptohandler(const avalue: tcustomcryptohandler); + function getrecnozerobased: int32; + procedure setrecnozerobased(const avalue: int32); + procedure readstreamingversion(reader: treader); + procedure writestreamingversion(writer: twriter); + procedure setdelayedapplycount(const avalue: integer); + procedure registeronidle; + procedure unregisteronidle; + procedure doonidle(var again: boolean); + protected + foldopts: bufdatasetoptionsty; //transferred from tdatasetcontroller + fcontroller: tdscontroller; + foptions: bufdatasetoptionsty; + fbrecordcount: integer; + ffieldinfos: fieldinfoarty; + ffieldorder: integerarty; + factindexpo: pindexty; + fbstate: bufdatasetstatesty; + fbstate1: bufdatasetstates1ty; + fallpacketsfetched : boolean; + fapplyindex: integer; //take care about canceled updates while applying + ffailedcount: integer; + frecno: integer; //zero based + findexes: array of indexty; + fblobcache: blobcacheinfoarty; + fblobcount: integer; + ffreedblobs: integerarty; + ffreedblobcount: integer; + fcurrentbuf: pintrecordty; + fcurrentupdating: integer; +// flastcurrentrec: pintrecordty; + flastcurrentindex: integer; + fsavepointlevel: integer; + fappliedcount: card32; + + procedure doidleapplyupdates() virtual; + procedure setoptions(const avalue: bufdatasetoptionsty) virtual; + function getdefaultoptions: bufdatasetoptionsty virtual; + procedure openlocal; + procedure fixupcurrentset; virtual; + procedure currentcheckbrowsemode; + + function getrestorerecno: boolean; + procedure setrestorerecno(const avalue: boolean); + + procedure dogetcoldata(const afield: tfield; const afieldtype: tfieldtype; + const step: integer; const data: pointer); + function getcurrentlookuppo(const afield: tfield; + const afieldtype: tfieldtype; const arecord: pintrecordty): pointer; + function getcurrentpo(const afield: tfield; + const afieldtype: tfieldtype; const arecord: pintrecordty): pointer; + function beforecurrentget(const afield: tfield; + const afieldtype: tfieldtype; var aindex: integer): pointer; + function beforecurrentbmget(const afield: tfield; + const afieldtype: tfieldtype; const abm: bookmarkdataty): pointer; + function setcurrentpo(const afield: tfield; + const afieldtype: tfieldtype; const arecord: precheaderty; + const aisnull: boolean; out changed: boolean): pointer; + function beforecurrentset(const afield: tfield; + const afieldtype: tfieldtype; var aindex: integer; + const aisnull: boolean; out changed: boolean): pointer; + procedure aftercurrentset(const afield: tfield); virtual; + function beforecurrentbmset(const afield: tfield; + const afieldtype: tfieldtype; const abm: bookmarkdataty; + const aisnull: boolean; out changed: boolean): pointer; + procedure getbminteger(const afield: tfield; const bm: bookmarkdataty; + var adata: lookupdataty); + procedure getbmlargeint(const afield: tfield; const bm: bookmarkdataty; + var adata: lookupdataty); + procedure getbmcurrency(const afield: tfield; const bm: bookmarkdataty; + var adata: lookupdataty); + procedure getbmfloat(const afield: tfield; const bm: bookmarkdataty; + var adata: lookupdataty); + procedure getbmstring(const afield: tfield; const bm: bookmarkdataty; + var adata: lookupdataty); + procedure getbmboolean(const afield: tfield; const bm: bookmarkdataty; + var adata: lookupdataty); + procedure getbmdatetime(const afield: tfield; const bm: bookmarkdataty; + var adata: lookupdataty); + procedure getbmvariant(const afield: tfield; const bm: bookmarkdataty; + var adata: lookupdataty); + procedure getbmguid(const afield: tfield; const bm: bookmarkdataty; + var adata: lookupdataty); + + function getfieldbuffer(const afield: tfield; + out buffer: pointer; out datasize: integer): boolean; overload; + //read, true if not null + function getfieldbuffer(const afield: tfield; + const aisnull: boolean; out datasize: integer): pointer; + overload; virtual; + //write + procedure fieldchanged(const field: tfield); + function getfiltereditkind: filtereditkindty; + function blobsarefetched: boolean; + function getblobcache: blobcacheinfoarty; + function findcachedblob(var info: blobcacheinfoty): boolean; overload; + function findcachedblob(const id: int64; + out info: blobcacheinfoty): boolean; overload; + function addblobcache(const adata: pointer; + const alength: integer): integer; overload; + function addblobcache(const aid: int64; const adata: string): integer; overload; + procedure updatestate; + function getintblobpo: pblobinfoarty; //in currentrecbuf + procedure internalcancel; override; + procedure FreeFieldBuffers; override; + procedure cancelrecupdate(var arec: recupdatebufferty); + procedure setdatastringvalue(const afield: tfield; const avalue: string); +// function getdsoptions: datasetoptionsty; virtual; + procedure resetblobcache; + procedure sortblobcache; + procedure fetchblobs; + procedure fetchallblobs; + procedure getofflineblob(const data: precheaderty; const aindex: integer; + out ainfo: blobstreaminfoty); + procedure setofflineblob(const adata: precheaderty; const aindex: integer; + const ainfo: blobstreaminfoty); + function getblobrecpo: precheaderty; + +// procedure dscontrolleroptionschanged(const aoptions: datasetoptionsty); virtual; + procedure savepointevent(const sender: tmdbtransaction; + const akind: savepointeventkindty; const alevel: integer); override; + procedure packrecupdatebuffer; + procedure restorerecupdatebuffer; + procedure postrecupdatebuffer; + procedure recupdatebufferapplied(const abuf: precupdatebufferty); + procedure recupdatebufferdropped(const abuf: precupdatebufferty); + procedure editapplyerror(const arecupdatenum: integer); + procedure internalapplyupdate(const maxerrors: integer; + const cancelonerror: boolean; + const cancelondeleteerror: boolean; + out response: resolverresponsesty); + procedure afterapply; virtual; + procedure freeblob(const ablob: blobinfoty); + procedure freeblobs(var ablobs: blobinfoarty); + procedure deleteblob(var ablobs: blobinfoarty; const aindex: integer; + const afreeblob: boolean); overload; + procedure deleteblob(var ablobs: blobinfoarty; const afield: tfield; + const adeleteitem: boolean); overload; + procedure addblob(const ablob: tblobbuffer); + + procedure setrecno1(value: longint; const nocheck: boolean); + procedure setrecno(value: longint); override; + function getrecno: longint; override; + function getchangecount: integer; virtual; + function getapplyerrorcount: integer; virtual; + function allocrecordbuffer: pchar; override; + procedure internalinitrecord(buffer: pchar); override; + procedure clearcalcfields(buffer: pchar); override; + procedure freerecordbuffer(var buffer: pchar); override; + function getcanmodify: boolean; override; + function getrecord(buffer: pchar; getmode: tgetmode; + docheck: boolean): tgetresult; override; + function GetNextRecord: Boolean; override; + function GetNextRecords: Longint; override; + function bookmarkdatatobookmark(const abookmark: bookmarkdataty): bookmarkty; + function bookmarktobookmarkdata(const abookmark: bookmarkty): bookmarkdataty; + function findbookmarkindex(const abookmark: bookmarkdataty): integer; + procedure checkrecno(const avalue: integer); + procedure setonfilterrecord(const value: tfilterrecordevent); override; + procedure setfiltered(value: boolean); override; + procedure filterchanged1(const aloaded: boolean); + procedure setactive(value: boolean); override; + + procedure CalculateFields(Buffer: PChar); override; + procedure notification(acomponent: tcomponent; + operation: toperation) override; + procedure loaded override; + procedure defineproperties(filer: tfiler) override; + procedure readstate(reader: treader) override; + procedure OpenCursor(InfoQuery: Boolean); override; + procedure internalopen; override; + procedure internalclose; override; + procedure clearbuffers; override; + procedure internalinsert; override; + procedure internaledit; override; + procedure dataevent(event: tdataevent; info: ptrint); override; + procedure checkconnected; + procedure startlogger; + procedure closelogger; + procedure savestate(const awriter: tbufstreamwriter); + + function getfieldclass(fieldtype: tfieldtype): tfieldclass; override; + function getnextpacket(const all: boolean) : integer; + function getrecordsize: word; override; + procedure saveindex(const oldbuffer,newbuffer: pintrecordty; + var ar1,ar2,ar3: integerarty); + procedure relocateindex(const abuffer: pintrecordty; + const ar1,ar2,ar3: integerarty); + procedure internalpost; override; + procedure internaldelete; override; + procedure internalfirst; override; + procedure internallast; override; + procedure internalsettorecord(buffer: pchar); override; + procedure internalgotobookmark(abookmark: pointer); override; + procedure setbookmarkdata(buffer: pchar; data: pointer); override; + procedure setbookmarkflag(buffer: pchar; value: tbookmarkflag); override; + procedure getbookmarkdata(buffer: pchar; data: pointer); override; + function getbookmarkdata1: bookmarkdataty; + function getbookmarkflag(buffer: pchar): tbookmarkflag; override; + function getfieldblobid(const field: tfield; out aid: blobidty): boolean; + //false if null + function iscursoropen: boolean; override; + function getrecordcount: longint; override; + procedure applyrecupdate(updatekind : tupdatekind); virtual; + procedure setonupdateerror(const avalue: updateerroreventty); + property actindex: integer read factindex write setactindex; + function findrecord(arecordpo: pintrecordty): integer; reintroduce; + //returns index, -1 if not found + procedure dofilterrecord(var acceptable: boolean); virtual; + procedure dobeforeapplyupdate; virtual; + procedure doafterapplyupdate; virtual; + procedure dointernalcalcfields(const fetching: boolean); + + function islocal: boolean; virtual; + function updatesortfield(const afield: tfield; const adescend: boolean): boolean; + function getobjectlinker: tobjectlinker; + procedure objectevent(const sender: tobject; + const event: objecteventty); virtual; + //iobjectlink + procedure link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); + procedure unlink(const source,dest: iobjectlink; valuepo: pointer = nil); virtual; + procedure objevent(const sender: iobjectlink; const event: objecteventty); virtual; + function getinstance: tobject; + function getcomponent: tcomponent; + //idscontroller + procedure begindisplaydata; + procedure enddisplaydata; + function getsavepointoptions(): savepointoptionsty; + //idbdata + function getindex(const afield: tfield): integer; //-1 if none + function gettextindex(const afield: tfield; + const acaseinsensitive: boolean): integer; //-1 if none + function lookuptext(const indexnum: integer; const akey: integer; + const aisnull: boolean; + const valuefield: tmsestringfield): msestring; overload; + function lookuptext(const indexnum: integer; const akey: int64; + const aisnull: boolean; + const valuefield: tmsestringfield): msestring; overload; + function lookuptext(const indexnum: integer; const akey: msestring; + const aisnull: boolean; + const valuefield: tmsestringfield): msestring; overload; + function findtext(const indexnum: integer; const searchtext: msestring; + out arecord: integer): boolean; + function getrowtext(const indexnum: integer; const arecord: integer; + const afield: tfield): msestring; + function getrowinteger(const indexnum: integer; const arecord: integer; + const afield: tfield): integer; + function getrowlargeint(const indexnum: integer; const arecord: integer; + const afield: tfield): int64; + + {abstracts, must be overidden by descendents} + function fetch : boolean; virtual; abstract; + function getblobdatasize: integer; virtual; abstract; + function blobscached: boolean; virtual; abstract; + function loadfield(const afieldno: integer; const afieldtype: tfieldtype{const afield: tfield}; + const buffer: pointer; + var bufsize: integer): boolean; virtual; abstract; + //if bufsize < 0 -> buffer was to small, should be -bufsize + property nullmasksize: integer read fnullmasksize; + function islastrecord: boolean; + procedure checkfreebuffer(const afield: tfield); + function callvalidate(const afield: tfield; const avalue: pointer): boolean; + procedure checkvaluebuffer(const afield: tfield; const asize: integer); + {$ifndef FPC} + function refreshrecordvarar(const sourcedatasets: array of tdataset; + const akeyvalue: array of variant; + const keyindex: integer; + const acancelupdate: boolean; + const restorerecno: boolean; + const noinsert: boolean): bookmarkdataty; + {$endif} + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + + procedure enablecontrols; override; + procedure beginlookupupdate(); //delays notifylookupclient calls + procedure endlookupupdate(); + procedure updaterecord(); override; + procedure post; override; + procedure gotobookmark(const abookmark: bookmarkdataty); overload; + function findbookmark(const abookmark: bookmarkdataty): boolean; + property bookmarkdata: bookmarkdataty read getbookmarkdata1 + write setbookmarkdata1; + function recnobookmark(const arecnozerobased: int32): bookmarkdataty; + + function createblobstream(field: tfield; + mode: tblobstreammode): tstream; override; + function getfielddata(field: tfield; buffer: pointer; + nativeformat: boolean): boolean; override; + function getfielddata(field: tfield; buffer: pointer): boolean; override; + procedure setfielddata(field: tfield; buffer: pointer; + nativeformat: boolean); override; + procedure setfielddata(field: tfield; buffer: pointer); override; + procedure Append; + procedure notifycontrols; //calls enablecontrols/disablecontrols + + //logging works with persistent fields only + procedure recover; + //load from logfile, start logging, + procedure startlogging; + //close logfile, save state with truncated log, open logfile + procedure stoplogging; //close logfile + property logging: boolean read getlogging; + procedure savetostream(const astream: tstream); + procedure loadfromstream(const astream: tstream); + procedure savetofile(afilename: filenamety = ''; //''-> uselogfilename + const acryptohandler: tcustomcryptohandler = nil); + procedure loadfromfile(afilename: filenamety = ''; + //''-> uselogfilename + const acryptohandler: tcustomcryptohandler = nil); + function streamloading: boolean; + + //imasterlink +// function refreshing: boolean; + + function refreshrecord(const akeyfield: array of tfield; + const keyindex: integer = 0; + const acancelupdate: boolean = true; + const restorerecno: boolean = true; + const noinsert: boolean = false): bookmarkdataty; overload; + function refreshrecord(const sourcedatasets: array of tdataset; + const akeyvalue: array of variant; + const keyindex: integer = 0; + const acancelupdate: boolean = true; + const restorerecno: boolean = true; + const noinsert: boolean = false): bookmarkdataty; overload; + function refreshrecord(const asourcefields: array of tfield; + const akeyfield: array of tfield; + const keyindex: integer = 0; + const acancelupdate: boolean = true; + const restorerecno: boolean = true; + const noinsert: boolean = false): bookmarkdataty; overload; + function refreshrecord(const asourcefields: array of tfield; + const adestfields: array of tfield; + const akeyfield: array of tfield; + const keyindex: integer = 0; + const acancelupdate: boolean = true; + const restorerecno: boolean = true; + const noinsert: boolean = false): bookmarkdataty; overload; + function refreshrecord(const asourcefields: array of tfield; + const adestfields: array of tfield; + const akeyvalue: array of variant; + const keyindex: integer = 0; + const acancelupdate: boolean = true; + const restorerecno: boolean = true; + const noinsert: boolean = false): bookmarkdataty; overload; + function refreshrecord(const asourcevalues: array of variant; + const adestfields: array of tfield; + const akeyvalue: array of variant; + const keyindex: integer = 0; + const acancelupdate: boolean = true; + const restorerecno: boolean = true; + const noinsert: boolean = false): bookmarkdataty; overload; + //keyindex must be unique, copies equally named visible fields, + //inserts record if key not found. + + procedure copyfieldvalues(const bm: bookmarkdataty; + const dest: tdataset); overload; + //copies field values with same name + procedure copyfieldvalues(const bm: bookmarkdataty; + const dest: tmsebufdataset; + const acancelupdate: boolean); overload; + //copies field values with same name + + function isutf8: boolean; virtual; + procedure bindfields(const bind: boolean); + function findfields(const anames: string): fieldarty; overload; + function findfields(const anames: string; out afields: fieldarty): boolean; + overload; + //true if all found + procedure fieldtoparam(const source: tfield; const dest: tparam); + procedure oldfieldtoparam(const source: tfield; const dest: tparam); + procedure stringtoparam(const source: msestring; const dest: tparam); + //takes care about utf8 conversion + function recordisnull(): boolean; //all fields null + procedure clearrecord(); + procedure clearfilter(); + property filtereditkind: filtereditkindty read ffiltereditkind + write ffiltereditkind; + procedure beginfilteredit(const akind: filtereditkindty); + procedure endfilteredit; + function beginfiltervalue(const akind: filtereditkindty): tdatasetstate; + procedure endfiltervalue(const astatebefore: tdatasetstate); + procedure filterchanged(); + function fieldfiltervalue(const afield: tfield; + const akind: filtereditkindty = fek_filter): variant; + function fieldfiltervalueisnull(const afield: tfield; + const akind: filtereditkindty = fek_filter): boolean; + function checkfiltervalue(const afield: tfield; + const akind: filtereditkindty = fek_filter; + const acaseinsensitive: boolean = true): boolean; + //returns true if filter value is null or filter condition is fulfilled + function checkfiltervalues(const afield: tfield; + const acaseinsensitive: boolean = true): boolean; + //calls checkfiltervalue() for all filtereditkinds + function checkfiltervalues(const acaseinsensitive: boolean = true): boolean; + //calls checkfiltervalue() for all fields and all filtereditkinds + + function locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; reintroduce; + function locaterecno(const arecno: integer): boolean; + //moves to next valid recno, //returns true if resulting recno = arecno + + function countvisiblerecords: integer; + procedure fetchall; + procedure resetindex; //deactivates all indexes + function createblobbuffer(const afield: tfield): tblobbuffer; + + property changecount: integer read getchangecount; + property changerecords: recupdateinfoarty read getchangerecords; + property applyerrorcount: integer read getapplyerrorcount; + property applyerrorrecords: recupdateinfoarty read getapplyerrorrecords; + property appliedcount: card32 read fappliedcount; + //total successfully applied records since last open + + procedure applyupdates(const maxerrors: integer = 0); overload; virtual; + procedure applyupdates(const maxerrors: integer; + const cancelonerror: boolean; + const cancelondeleteerror: boolean = false; + const editonerror: boolean = false); overload; virtual; + procedure applyupdate(const cancelonerror: boolean; + const cancelondeleteerror: boolean = false; + const editonerror: boolean = false); overload; virtual; + procedure applyupdate; overload; virtual; + //applies current record + function recapplying: boolean; + procedure dropupdates(); //delete update info + procedure cancelupdates; virtual; //revert changes + procedure cancelupdate(const norecordcancel: boolean = false); virtual; + //cancels current record, + //if norecordcancel no restoring of old values + function updatestatus: tupdatestatus; overload; override; + function updatestatus(out aflags: recupdateflagsty): tupdatestatus; overload; + + procedure currentbeginupdate; virtual; + procedure currentendupdate; virtual; + function currentrecordhigh: integer; //calls checkbrowsemode + property recnozerobased: int32 read getrecnozerobased + write setrecnozerobased; + + //calls checkbrowsemode, writing for fkInternalCalc only, + //aindex = -1 -> current record + procedure currentclear(const afield: tfield; aindex: integer); + procedure currentassign(const source: tfield; const dest: tfield; + aindex: integer); + property currentisnull[const afield: tfield; aindex: integer]: boolean read + getcurrentisnull; + property currentasvariant[const afield: tfield; aindex: integer]: variant + read getcurrentasvariant write setcurrentasvariant; + property currentasboolean[const afield: tfield; aindex: integer]: boolean + read getcurrentasboolean write setcurrentasboolean; + property currentasinteger[const afield: tfield; aindex: integer]: integer + read getcurrentasinteger write setcurrentasinteger; + property currentaslargeint[const afield: tfield; aindex: integer]: int64 + read getcurrentaslargeint write setcurrentaslargeint; + property currentasid[const afield: tfield; aindex: integer]: int64 + read getcurrentasid write setcurrentasid; //-1 for null + property currentasfloat[const afield: tfield; aindex: integer]: double + read getcurrentasfloat write setcurrentasfloat; + property currentasdatetime[const afield: tfield; aindex: integer]: tdatetime + read getcurrentasdatetime write setcurrentasdatetime; + property currentascurrency[const afield: tfield; aindex: integer]: currency + read getcurrentascurrency write setcurrentascurrency; + property currentasmsestring[const afield: tfield; aindex: integer]: msestring + read getcurrentasmsestring write setcurrentasmsestring; + property currentasguid[const afield: tfield; aindex: integer]: tguid + read getcurrentasguid write setcurrentasguid; + + procedure currentbmclear(const afield: tfield; const abm: bookmarkdataty); + procedure currentbmassign(const source: tfield; const dest: tfield; + const abm: bookmarkdataty); + property currentbmisnull[const afield: tfield; + const abm: bookmarkdataty]: boolean read getcurrentbmisnull; + property currentbmasvariant[const afield: tfield; + const abm: bookmarkdataty]: variant + read getcurrentbmasvariant write setcurrentbmasvariant; + property currentbmasboolean[const afield: tfield; + const abm: bookmarkdataty]: boolean + read getcurrentbmasboolean write setcurrentbmasboolean; + property currentbmasinteger[const afield: tfield; + const abm: bookmarkdataty]: integer + read getcurrentbmasinteger write setcurrentbmasinteger; + property currentbmaslargeint[const afield: tfield; + const abm: bookmarkdataty]: int64 + read getcurrentbmaslargeint write setcurrentbmaslargeint; + property currentbmasid[const afield: tfield; + const abm: bookmarkdataty]: int64 + read getcurrentbmasid write setcurrentbmasid; //-1 for null + property currentbmasfloat[const afield: tfield; + const abm: bookmarkdataty]: double + read getcurrentbmasfloat write setcurrentbmasfloat; + property currentbmasdatetime[const afield: tfield; + const abm: bookmarkdataty]: tdatetime + read getcurrentbmasdatetime write setcurrentbmasdatetime; + property currentbmascurrency[const afield: tfield; + const abm: bookmarkdataty]: currency + read getcurrentbmascurrency write setcurrentbmascurrency; + property currentbmasmsestring[const afield: tfield; + const abm: bookmarkdataty]: msestring + read getcurrentbmasmsestring write setcurrentbmasmsestring; + property currentbmasguid[const afield: tfield; + const abm: bookmarkdataty]: tguid + read getcurrentbmasguid write setcurrentbmasguid; + + procedure getcoldata(const afield: tfield; const adatalist: tdatalist); + procedure asarray(const afield: tfield; out avalue: int64arty); overload; + procedure asarray(const afield: tfield; out avalue: integerarty); overload; + procedure asarray(const afield: tfield; out avalue: stringarty); overload; + procedure asarray(const afield: tfield; out avalue: msestringarty); overload; + procedure asarray(const afield: tfield; out avalue: currencyarty); overload; + procedure asarray(const afield: tfield; out avalue: realarty); overload; + procedure asarray(const afield: tfield; out avalue: datetimearty); overload; + procedure asarray(const afield: tfield; out avalue: booleanarty); overload; + + function getdata(const afields: array of tfield): variantararty; + //[] -> all + procedure sumfield(const afield: tfield; out asum: double); overload; + procedure sumfield(const afield: tfield; out asum: currency); overload; + procedure sumfield(const afield: tfield; out asum: integer); overload; + procedure sumfield(const afield: tfield; out asum: int64); overload; + function sumfielddouble(const afield: tfield): double; + function sumfieldcurrency(const afield: tfield): currency; + function sumfieldinteger(const afield: tfield): integer; + function sumfieldint64(const afield: tfield): int64; + property delayedapplycount: integer read fdelayedapplycount + write setdelayedapplycount default 0; + //0 -> no autoapply + published + property options: bufdatasetoptionsty read foptions + write setoptions default []; + property logfilename: filenamety read flogfilename write flogfilename; + property cryptohandler: tcustomcryptohandler read fcryptohandler + write setcryptohandler; + property packetrecords : integer read fpacketrecords write setpacketrecords + default defaultpacketrecords; + property indexlocal: tlocalindexes read findexlocal write setindexlocal; + + property onupdateerror: updateerroreventty read fonupdateerror + write setonupdateerror; + property oninternalcalcfields: internalcalcfieldseventty + read foninternalcalcfields write setoninternalcalcfields; + property beforeapplyupdate: tdatasetnotifyevent read fbeforeapplyupdate + write fbeforeapplyupdate; + property afterapplyupdate: tdatasetnotifyevent read fafterapplyupdate + write fafterapplyupdate; + property beforebeginfilteredit: filterediteventty + read fbeforebeginfilteredit write fbeforebeginfilteredit; + property afterbeginfilteredit: filterediteventty + read fafterbeginfilteredit write fafterbeginfilteredit; + property beforeendfilteredit: filterediteventty + read fbeforeendfilteredit write fbeforeendfilteredit; + property afterendfilteredit: filterediteventty + read fafterendfilteredit write fafterendfilteredit; + property beforefilterchanged: bufdataseteventty + read fbeforefilterchanged write fbeforefilterchanged; + property afterfilterchanged: bufdataseteventty + read fafterfilterchanged write fafterfilterchanged; + property Active default false; +// property AutocalcFields default false; + end; + +function getfieldflag(nullmask: pbyte; const x: integer): boolean; +procedure setfieldflag(nullmask: pbyte; const x: integer); +procedure clearfieldflag(nullmask: pbyte; const x: integer); +procedure alignfieldpos(var avalue: integer); + +implementation +uses + rtlconsts,{$ifdef FPC}dbconst{$else}dbconst_del,classes_del{$endif},sysutils, + mseformatstr,msereal,msesys,msefileutils,mseapplication,msesysutils,msebits, + typinfo; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tmsestringfield1 = class(tmsestringfield); + tmseblobfield1 = class(tmseblobfield); + tmsevariantfield1 = class(tmsevariantfield); + tmsebooleanfield1 = class(tmsebooleanfield); + tmsedatetimefield1 = class(tmsedatetimefield); + tfield1 = class(tfield); + +const + fielddatacompatibility: array[tfieldtype] of fieldtypesty = ( + //ftUnknown, ftString, ftSmallint, ftInteger, ftWord, + [ftunknown],stringfcomp,longintfcomp,longintfcomp,longintfcomp, + //ftBoolean, ftFloat, ftCurrency, ftBCD, + booleanfcomp,realfcomp+datetimefcomp,realfcomp+datetimefcomp,[ftbcd], + //ftDate, ftTime, tDateTime, + realfcomp+datetimefcomp,realfcomp+datetimefcomp,realfcomp+datetimefcomp, + //ftBytes, ftVarBytes, ftAutoInc, + [ftbytes],[ftvarbytes],[ftautoinc], + // ftBlob, ftMemo, ftGraphic, ftFmtMemo, + blobfcomp,memofcomp,blobfcomp,memofcomp, + //ftParadoxOle, ftDBaseOle, ftTypedBinary, ftCursor, tFixedChar, + [ftParadoxOle],[ftDBaseOle],[ftTypedBinary],[ftCursor],stringfcomp, + //ftWideString, ftLargeint, ftADT, ftArray, ftReference, + stringfcomp,[ftLargeint],[ftADT],[ftArray],[ftReference], + //ftDataSet, ftOraBlob, ftOraClob, ftVariant, ftInterface, + [ftDataSet],[ftOraBlob],[ftOraClob],[ftVariant],[ftInterface], + //ftIDispatch, ftGuid, ftTimeStamp, ftFMTBcd); + [ftIDispatch],[ftGuid],[ftTimeStamp],[ftFMTBcd], + //ftFixedWideChar,ftWideMemo + stringfcomp, stringfcomp + ); + +function compblobcache(const a,b): integer; +var + lint1: int64; +begin + lint1:= blobcacheinfoty(a).id - blobcacheinfoty(b).id; + result:= 0; + if lint1 < 0 then begin + result:= -1; + end + else begin + if lint1 > 0 then begin + result:= 1; + end; + end; +end; + +function compinteger(const l,r): integer; +begin + result:= integer(l) - integer(r); +end; + +function compint64(const l,r): integer; +begin + if int64(l) > int64(r) then begin + result:= 1; + end + else begin + if int64(l) = int64(r) then begin + result:= 0; + end + else begin + result:= -1; + end; + end; +end; + +function compfloat(const l,r): integer; +begin + result:= 0; + if double(l) > double(r) then begin + inc(result); + end + else begin + if double(l) < double(r) then begin + dec(result); + end; + end; +end; + +function compcurrency(const l,r): integer; +begin + result:= 0; + if currency(l) > currency(r) then begin + inc(result); + end + else begin + if currency(l) < currency(r) then begin + dec(result); + end; + end; +end; + +function compstring(const l,r): integer; +begin + result:= msecomparestr(msestring(l),msestring(r)); +end; + +function compstringi(const l,r): integer; +begin + result:= msecomparetext(msestring(l),msestring(r)); +end; + +function compstringn(const l,r): integer; +begin + result:= msecomparestrnatural(msestring(l),msestring(r)); +end; + +function compstringin(const l,r): integer; +begin + result:= msecomparetextnatural(msestring(l),msestring(r)); +end; + +function compguid(const l,r): integer; +var + int1: integer; +begin + for int1:= 0 to (sizeof(tguid) div sizeof(integer)) - 1 do begin + result:= pintegeraty(@l)^[int1]-pintegeraty(@r)^[int1]; + if result <> 0 then begin + break; + end; + end; +end; + +type + fieldcomparekindty = (fct_integer,fct_largeint,fct_float,fct_currency,fct_text, + fct_guid); + fieldcompareinfoty = record + datatypes: set of tfieldtype; + cvtype: integer; + compfunc: arraysortcomparety; + compfunci: arraysortcomparety; + compfuncn: arraysortcomparety; + compfuncin: arraysortcomparety; + end; + +const + comparefuncs: array[fieldcomparekindty] of fieldcompareinfoty = + ((datatypes: integerindexfields; cvtype: vtinteger; + compfunc: @compinteger; + compfunci: @compinteger; + compfuncn: @compinteger; + compfuncin: @compinteger), + (datatypes: largeintindexfields; cvtype: vtint64; + compfunc: @compint64; + compfunci: @compint64; + compfuncn: @compint64; + compfuncin: @compint64), + (datatypes: floatindexfields; cvtype: vtextended; + compfunc: @compfloat; + compfunci: @compfloat; + compfuncn: @compfloat; + compfuncin: @compfloat), + (datatypes: currencyindexfields; cvtype: vtcurrency; + compfunc: @compcurrency; + compfunci: @compcurrency; + compfuncn: @compcurrency; + compfuncin: @compcurrency), + (datatypes: stringindexfields; + cvtype: {$ifdef mse_hasvtunicodestring}vtunicodestring + {$else}vtwidestring{$endif}; + compfunc: @compstring; + compfunci: @compstringi; + compfuncn: @compstringn; + compfuncin: @compstringin), + (datatypes: guidindexfields; cvtype: mse_vtguid; + compfunc: @compguid; + compfunci: @compguid; + compfuncn: @compguid; + compfuncin: @compguid) +); + +procedure alignfieldpos(var avalue: integer); +const + step = sizeof(pointer); +begin + avalue:= (avalue + step - 1) and -step; //align to pointer +end; + +const +{$ifdef FPC} + ormask: array[0..7] of byte = (%00000001,%00000010,%00000100,%00001000, + %00010000,%00100000,%01000000,%10000000); + andmask: array[0..7] of byte = (%11111110,%11111101,%11111011,%11110111, + %11101111,%11011111,%10111111,%01111111); +{$else} + ormask: array[0..7] of byte = ($01,$02,$04,$08,$10,$20,$40,$80); + andmask: array[0..7] of byte = + (byte(not$01),byte(not$02),byte(not$04),byte(not$08), + byte(not$10),byte(not$20),byte(not$40),byte(not$80)); +{$endif} + +procedure setfieldflag(nullmask: pbyte; const x: integer); +//var +// int1: integer; +begin + inc(nullmask,(x shr 3)); + nullmask^:= nullmask^ or ormask[x and 7]; +end; + +procedure clearfieldflag(nullmask: pbyte; const x: integer); +begin + inc(nullmask,(x shr 3)); + nullmask^:= nullmask^ and andmask[x and 7]; +end; + +function getfieldflag(nullmask: pbyte; const x: integer): boolean; +begin + inc(nullmask,(x shr 3)); + result:= nullmask^ and ormask[x and 7] <> 0; +end; + + +{ tbufstreamwriter } + +constructor tbufstreamwriter.create(const aowner: tmsebufdataset; + const astream: tstream); +begin + fowner:= aowner; + fstream:= astream; +end; + +destructor tbufstreamwriter.destroy; +begin + flushbuffer; + inherited; +end; + +procedure tbufstreamwriter.flushbuffer; +begin + fstream.writebuffer(fbuffer,fbufindex); + fbufindex:= 0; +end; + +procedure tbufstreamwriter.write(const buffer; length: integer); +var + po1: pointer; + int1: integer; +begin + po1:= @buffer; + while length > 0 do begin + int1:= length; + if int1 + fbufindex > bufstreambuffersize then begin + int1:= bufstreambuffersize - fbufindex; + end; + move(po1^,fbuffer[fbufindex],int1); + inc(fbufindex,int1); + if fbufindex >= bufstreambuffersize then begin + flushbuffer; + end; + inc(pchar(po1),int1); + dec(length,int1); + end; +end; + +procedure tbufstreamwriter.writefielddata(const data: precheaderty; + const aindex: integer); +var + fielddata: pointer; + blobinfo: blobstreaminfoty; +begin + with fowner.ffieldinfos[aindex].base do begin + fielddata:= pchar(pointer(data)) + offset; + case fieldtype of + ftstring,ftfixedchar,ftwidestring,ftfixedwidechar: begin + writemsestring(msestring(fielddata^)); + end; + ftmemo,ftblob,ftgraphic: begin + if getfieldflag(@data^.fielddata.nullmask,aindex) then begin + fowner.getofflineblob(data,aindex,blobinfo); + write(blobinfo.info,sizeof(blobinfo.info)); + writestring(blobinfo.data); + end; + end; + ftvariant: begin + writevariant(variant(fielddata^)); + end; + else begin + write(fielddata^,size); + end; + end; + end; +end; + +procedure tbufstreamwriter.writestring(const avalue: string); +begin + writeinteger(length(avalue)); + write(pointer(avalue)^,length(avalue)); +end; + +procedure tbufstreamwriter.writemsestring(const avalue: msestring); +begin + writeinteger(length(avalue)); + write(pointer(avalue)^,length(avalue)*sizeof(msechar)); +end; + +procedure tbufstreamwriter.writeinteger(const avalue: integer); +begin + write(avalue,sizeof(integer)); +end; + +procedure tbufstreamwriter.writefielddef(const afielddef: tfielddef); +begin + with afielddef do begin + writestring(name); + writeinteger(ord(datatype)); + writeinteger(size); + writeinteger(integer(required)); + writeinteger(fieldno); + writeinteger(precision); + end; +end; + +{$ifdef mse_debuglogger} +function logpo(const apo: card64): string; +begin + if apo = 0 then begin + result:= '0'; + end + else begin + result:= hextostr(apo); + end; +end; + +procedure dumplogbufferheader(const aheader: logbufferheaderty); +begin + with aheader do begin + debugwrite('*log '+getenumname(typeinfo(logflag),ord(logflag))); + case aheader.logflag of + lf_end: begin + end; + lf_rec: begin + with rec do begin + debugwriteln(' '+getenumname(typeinfo(kind),ord(kind))+' '+logpo(po)); + end; + end; + else begin + with update do begin + if logging then begin + debugwrite(' logging'); + end; + debugwriteln(' '+getenumname(typeinfo(kind),ord(kind))+' '+ + logpo(po)+' '+logpo(deletedrecord)); + end; + end; + end; + end; +end; +{$endif} + +procedure tbufstreamwriter.writelogbufferheader( + const aheader: logbufferheaderty); +begin +{$ifdef mse_debuglogger} + dumplogbufferheader(aheader); +{$endif} + write(aheader,sizeof(aheader)); +end; + +procedure tbufstreamwriter.writeendmarker; +var + abuffer: logbufferheaderty; +begin + fillchar(abuffer,sizeof(abuffer),0); + abuffer.logflag:= lf_end; + write(abuffer,sizeof(abuffer)); +end; + +procedure tbufstreamwriter.writepointer(const avalue: pointer); +begin + write(avalue,sizeof(pointer)); +end; + +type + pointeraty1 = array[0..1] of pointer; + ppointeraty1 = ^pointeraty1; + +procedure tbufstreamwriter.writevariant(const avalue: variant); +var + int1,int2: integer; +begin + write(avalue,sizeof(variant)); + with tvardata(avalue) do begin + case vtype of + varstring: begin + writestring(ansistring(vstring)); + end; + varolestr: begin + writemsestring(widestring(pointer(volestr))); + end; + end; + if vtype and vararray <> 0 then begin + write(varray^,sizeof(tvararray)); + with varray^ do begin + write(ppointeraty1(varray)^[1],(dimcount-1)*sizeof(tvararrayboundarray)); + //additional dims + int2:= 1; + for int1:= 0 to dimcount-1 do begin + int2:= int2 * bounds[int1].elementcount; + end; + write(data^,elementsize*int2); + case vtype and vartypemask of + varstring: begin + for int1:= 0 to int2 - 1 do begin + writestring(pstringaty(data)^[int1]); + end; + end; + varolestr: begin + for int1:= 0 to int2 - 1 do begin + writemsestring(pwidestringaty(data)^[int1]); + end; + end; + varvariant: begin + for int1:= 0 to int2 - 1 do begin + writevariant(pvariantaty(data)^[int1]); + end; + end; + end; + end; + end; + end; +end; + +{ tbufstreamreader } + +constructor tbufstreamreader.create(const aowner: tmsebufdataset; + const astream: tstream); +begin + fowner:= aowner; + fstream:= astream; +end; + +function tbufstreamreader.read(out buffer; length: integer): integer; +var + po1: pointer; + int1: integer; +begin + po1:= @buffer; + result:= 0; + while length > 0 do begin + int1:= length; + if int1 + fbufindex >= fbuflen then begin + int1:= fbuflen - fbufindex; + end; + move(fbuffer[fbufindex],po1^,int1); + inc(pchar(po1),int1); + inc(result,int1); + dec(length,int1); + inc(fbufindex,int1); + if fbufindex >= fbuflen then begin + fbufindex:= 0; + fbuflen:= fstream.read(fbuffer,bufstreambuffersize); + if fbuflen = 0 then begin + exit; //eof + end; + end; + end; +end; + +procedure tbufstreamreader.readbuffer(out buffer; const length: integer); +begin + if read(buffer,length) < length then begin + raise ereaderror.create(sreaderror); + end; +end; + +procedure tbufstreamreader.readfielddata(const data: precheaderty; + const aindex: integer); +var + fielddata: pointer; + blobinfo: blobstreaminfoty; +begin + with fowner.ffieldinfos[aindex].base do begin + fielddata:= pchar(pointer(data)) + offset; + case fieldtype of + ftstring,ftfixedchar,ftwidestring,ftfixedwidechar: begin + msestring(fielddata^):= readmsestring; + end; + ftmemo,ftblob,ftgraphic: begin + if getfieldflag(@data^.fielddata.nullmask,aindex) then begin + readbuffer(blobinfo.info,sizeof(blobinfo.info)); + blobinfo.data:= readstring; + fowner.setofflineblob(data,aindex,blobinfo); + end; + end; + ftvariant: begin + variant(fielddata^):= readvariant; + end; + else begin + readbuffer(fielddata^,size); + end; + end; + end; +end; + +function tbufstreamreader.readstring: string; +var + int1: integer; +begin + int1:= readinteger; + setlength(result,int1); + readbuffer(pointer(result)^,int1); +end; + +function tbufstreamreader.readmsestring: msestring; +var + int1: integer; +begin + int1:= readinteger; + setlength(result,int1); + readbuffer(pointer(result)^,int1*sizeof(msechar)); +end; + +function tbufstreamreader.readinteger: integer; +begin + readbuffer(result,sizeof(integer)); +end; + +procedure tbufstreamreader.readfielddef(const aowner: tfielddefs); +var + name: string; + datatype: tfieldtype; + size: integer; + required: boolean; + fieldno: integer; + precision: integer; + def1: tfielddef; +begin + name:= readstring; + datatype:= tfieldtype(readinteger); + size:= readinteger; + if datatype in blobfields then begin +// size:= fowner.getblobdatasize; + size:= 0; + end; + required:= boolean(readinteger); + fieldno:= readinteger; + precision:= readinteger; + def1:= tfielddef.create(aowner,name,datatype,size,required,fieldno); + def1.precision:= precision; +end; + +function tbufstreamreader.readlogbufferheader( + out aheader: logbufferheaderty): boolean; +var + rec1: logbufferheader32ty; +begin + if f32to64 then begin + result:= (read(rec1,sizeof(rec1)) = sizeof(rec1)) and + (rec1.logflag <> lf_end); + if result then begin + aheader.logflag:= rec1.logflag; + if rec1.logflag = lf_rec then begin + with aheader.rec do begin + kind:= rec1.rec.kind; + po:= rec1.rec.po; + end; + end + else begin + with aheader.update do begin + logging:= rec1.update.logging; + kind:= rec1.update.kind; + po:= rec1.update.po; + deletedrecord:= rec1.update.deletedrecord; + end; + end; + end; + end + else begin + result:= (read(aheader,sizeof(aheader)) = sizeof(aheader)) and + (aheader.logflag <> lf_end); + end; +{$ifdef mse_debuglogger} + if result then begin + dumplogbufferheader(aheader); + end + else begin + if aheader.logflag = lf_end then begin + debugwriteln('*log lf_end'); + end + else begin + debugwriteln('*log header readerror*'); + end; + end; +{$endif} +end; + +function tbufstreamreader.readpointer: pointer; +begin + readbuffer(result,sizeof(pointer)); +end; + +type + bufdattagty = array[0..15]of char; + tbsfheaderty = packed record + tag: bufdattagty; + byteorder: byte; //bit 0 0 -> little endian, 1 -> big endian + //bit 2 0 -> 32 bit 1 -> 64 bit (version 2) + version: integer; + fieldcount: integer; + fielddefcount: integer; + recordcount: integer; + end; + +procedure tbufstreamreader.readrecord(const arecord: pintrecordty); +var + int1: integer; + datapo: precheaderty; +begin + datapo:= @arecord^.header; + readbuffer(datapo^.fielddata,fowner.fnullmasksize); + for int1:= 0 to high(fowner.ffieldinfos) do begin + readfielddata(datapo,int1); + end; +end; + +function tbufstreamreader.readvariant: variant; +var + int1,int2: integer; +begin + readbuffer(result,sizeof(variant)); + with tvardata(result) do begin + case vtype of + varstring: begin + vtype:= 0; + result:= readstring; + end; + varolestr: begin + vtype:= 0; + result:= readmsestring; + end; + end; + if vtype and vararray <> 0 then begin + getmem(pointer(varray),sizeof(tvararray)); + read(varray^,sizeof(tvararray)); + varray^.lockcount:= 0; + reallocmem(varray,sizeof(tvararray)+ + (varray^.dimcount-1)*sizeof(tvararrayboundarray)); + with varray^ do begin + read(ppointeraty1(varray)^[1],(dimcount-1)*sizeof(tvararrayboundarray)); + int2:= 1; + for int1:= 0 to dimcount-1 do begin + int2:= int2 * bounds[int1].elementcount; + end; + getmem(data,elementsize*int2); + read(data^,elementsize*int2); + case vtype and vartypemask of + varstring: begin + for int1:= 0 to int2 - 1 do begin + ppointeraty(data)^[int1]:= nil; + pansistringaty(data)^[int1]:= readstring; + end; + end; + varolestr: begin + for int1:= 0 to int2 - 1 do begin + ppointeraty(data)^[int1]:= nil; + pwidestringaty(data)^[int1]:= readmsestring; + end; + end; + varvariant: begin + for int1:= 0 to int2 - 1 do begin + pvardataaty(data)^[int1].vtype:= 0; + pvariantaty(data)^[int1]:= readvariant; + end; + end; + end; + end; + end; + end; +end; + +{ tblobbuffer } + +constructor tblobbuffer.create(const aowner: tmsebufdataset; const afield: tfield); +begin + fowner:= aowner; + ffield:= afield; + inherited create; +end; + +destructor tblobbuffer.destroy; +begin + fowner.addblob(self); + setpointer(nil,0); + inherited; +end; + +{ tblobcopy } + +constructor tblobcopy.create(const ablob: blobinfoty); +begin + inherited create; + setpointer(ablob.data,ablob.datalength); +end; + +destructor tblobcopy.destroy; +begin + setpointer(nil,0); + inherited; +end; + +{ eapplyerror } + +constructor eapplyerror.create(const msg: string = ''; + const aresponse: resolverresponsesty = []); +begin + fresponse:= aresponse; + inherited create(msg); +end; + +{ tmsebufdataset } + +constructor tmsebufdataset.Create(AOwner : TComponent); +begin + foptions:= getdefaultoptions(); + frecno:= -1; + findexlocal:= tlocalindexes.create(self); + packetrecords:= defaultpacketrecords; + inherited; + bookmarksize := sizeof(bufbookmarkty); +end; + +destructor tmsebufdataset.destroy; +var + int1: integer; +begin + unregisteronidle(); + inherited destroy; + for int1:= high(flookupclients) downto 0 do begin + removeitem(pointerarty(flookupclients[int1].flookupmasters),pointer(self)); + end; + findexlocal.free; + closelogger; + freeandnil(fobjectlinker); +end; + +procedure tmsebufdataset.setpacketrecords(avalue : integer); +begin + if (avalue = 0) then begin + databaseerror('Packetrecords can not be 0.'{sinvpacketrecordsvalue}); + end; + fpacketrecords:= avalue; + updatestate; +end; + +Function tmsebufdataset.GetCanModify: Boolean; +begin + result:= false; +end; + +function tmsebufdataset.intallocrecord: pintrecordty; +begin + result:= allocmem(frecordsize+intheadersize); + fillchar(result^,frecordsize+intheadersize,0); + { + fillchar(result^,sizeof(intrecordty),0); + for int1:= high(fstringpositions) downto 0 do begin + pointer(pointer(@result^.header)+fstringpositions[int1])^):= nil; + end; + } +end; + +procedure freedbvariant(var avalue: variant); +begin + finalize(avalue); +{ + if avariant <> nil then begin + finalize(avariant^); + freemem(avariant); + avariant:= nil; + end; + } +end; + +procedure addrefdbvariant(var avalue: variant); +var + var1: variant; +begin + move(avalue,var1,sizeof(variant)); + fillchar(avalue,sizeof(variant),0); + avalue:= var1; //deep copy + tvardata(var1).vtype:= 0; +{ + po1:= avariant; + if po1 <> nil then begin + avariant:= getmem(sizeof(variant)); + tvardata(avariant^).vtype:= 0; + avariant^:= po1^; + end; + } +end; + +procedure tmsebufdataset.finalizevalues(var header: recheaderty); +var + int1: integer; +begin + for int1:= high(fstringpositions) downto 0 do begin + pmsestring(pchar(pointer(@header))+fstringpositions[int1])^:= ''; + end; + for int1:= high(fvarpositions) downto 0 do begin + freedbvariant(pvariant(pchar(pointer(@header))+fvarpositions[int1])^); + end; +end; + +procedure tmsebufdataset.finalizecalcvalues(var header: recheaderty); +var + int1: integer; +begin + for int1:= high(fcalcstringpositions) downto 0 do begin + pmsestring(pchar(pointer(@header))+fcalcstringpositions[int1])^:= ''; + end; + for int1:= high(fcalcvarpositions) downto 0 do begin + freedbvariant(pvariant(pchar(pointer(@header))+fcalcvarpositions[int1])^) + end; +end; +{ +procedure tmsebufdataset.finalizechangedvalues(const tocompare: recheaderty; + var tofinalize: recheaderty); +var + int1: integer; +begin + for int1:= high(fstringpositions) downto 0 do begin + if ppointer(pointer(@tocompare)+fstringpositions[int1])^ <> + ppointer(pointer(@tofinalize)+fstringpositions[int1])^ then begin + pmsestring(pointer(@tofinalize)+fstringpositions[int1])^:= ''; + end; + end; + for int1:= high(fvarpositions) downto 0 do begin + if ppointer(pointer(@tocompare)+fvarpositions[int1])^ <> + ppointer(pointer(@tofinalize)+fvarpositions[int1])^ then begin + freedbvariant(ppvariant(pointer(@tofinalize)+fvarpositions[int1])^); + end; + end; +end; +} +procedure tmsebufdataset.addrefvalues(var header: recheaderty); +var + int1: integer; +begin + for int1:= high(fstringpositions) downto 0 do begin + stringaddref(pmsestring(pchar(pointer(@header))+fstringpositions[int1])^); + end; + for int1:= high(fvarpositions) downto 0 do begin + addrefdbvariant(pvariant(pchar(pointer(@header))+fvarpositions[int1])^) + end; +end; + +procedure tmsebufdataset.intfinalizerecord(const buffer: pintrecordty); +begin + freeblobs(buffer^.header.blobinfo); + finalizevalues(buffer^.header); +end; + +procedure tmsebufdataset.intfreerecord(var buffer: pintrecordty); +begin + if buffer <> nil then begin + intfinalizerecord(buffer); + freemem(buffer); + buffer:= nil; + end; +end; + +function tmsebufdataset.allocrecordbuffer: pchar; +var + int1: integer; +begin + int1:= dsheadersize+fcalcrecordsize; + result:= allocmem(int1); + fillchar(result^,int1,0); //init for refcounted calcdata + initrecord(result); +end; + +procedure tmsebufdataset.clearcalcfields(buffer: pchar); +var + int1: integer; +begin + with pdsrecordty(buffer)^ do begin + for int1:= high(fcalcstringpositions) downto 0 do begin + pmsestring(pchar(pointer(@header))+fcalcstringpositions[int1])^:= ''; + end; + for int1:= high(fcalcvarpositions) downto 0 do begin + freedbvariant(pvariant(pchar(pointer(@header))+fcalcvarpositions[int1])^) + end; + fillchar((pchar(pointer(@header))+frecordsize)^,fcalcrecordsize-frecordsize,0); + end; +end; + +procedure tmsebufdataset.internalinitrecord(buffer: pchar); +begin + with pdsrecordty(buffer)^ do begin + finalizecalcvalues(precheaderty(@header)^); + fillchar(header,fcalcrecordsize,#0); //zero the whole buffer + end; +end; +{ +procedure tmsebufdataset.internalinitrecord(buffer: pchar); + +begin + freecalcfields(buffer); +// with pdsrecordty(buffer)^ do begin +// fillchar(header,fcalcrecordsize, #0); +// end; +end; +} +procedure tmsebufdataset.freerecordbuffer(var buffer: pchar); +//var +// int1: integer; +// bo1: boolean; +begin + if buffer <> nil then begin + with pdsrecordty(buffer)^,header do begin +{ there can be copies of invalid buffers + bo1:= false; + for int1:= high(blobinfo) downto 0 do begin + if blobinfo[int1].new then begin + freeblob(blobinfo[int1]); + bo1:= true; + end; + end; + if bo1 then begin + blobinfo:= nil; + end; +} + finalizecalcvalues(header); + end; + reallocmem(buffer,0); + end; +end; + +function tmsebufdataset.getintblobpo: pblobinfoarty; +begin + if bs_recapplying in fbstate then begin + result:= @fnewvaluebuffer^.header.blobinfo; + end + else begin + result:= @fcurrentbuf^.header.blobinfo; + end; +end; + +procedure tmsebufdataset.freeblob(const ablob: blobinfoty); +begin + with ablob do begin + if datalength > 0 then begin + freemem(data); + end; + end; +end; + +function tmsebufdataset.createblobbuffer(const afield: tfield): tblobbuffer; +begin + result:= tblobbuffer.create(self,afield); +end; + +procedure tmsebufdataset.freeblobcache(const arec: precheaderty; + const afield: tfield); +var + fieldindex: integer; + blobid: integer; +begin +//todo: free offline blobs + if bs_blobscached in fbstate then begin + fieldindex:= afield.fieldno-1; + if getfieldflag(@arec^.fielddata.nullmask,fieldindex) then begin + blobid:= pinteger(pchar(arec) + ffieldinfos[fieldindex].base.offset)^; + fblobcache[blobid].data:= ''; + additem(ffreedblobs,blobid,ffreedblobcount{,(high(ffreedblobs)+129)*2}); + end; + end; +end; + +procedure tmsebufdataset.addblob(const ablob: tblobbuffer); +var + int1,int2: integer; + bo1: boolean; + blobfree: boolean; + po2: pointer; + po1: precheaderty; +begin + bo1:= false; + int2:= -1; + if bs_recapplying in fbstate then begin + po1:= @fnewvaluebuffer^.header; + blobfree:= true; + end + else begin + po1:= @pdsrecordty(activebuffer)^.header; + blobfree:= false; + end; + with po1^{pdsrecordty(activebuffer)^.header} do begin + for int1:= high(blobinfo) downto 0 do begin + with blobinfo[int1] do begin + if new then begin + bo1:= true; + end; + if field = ablob.ffield then begin + int2:= int1; + end; + end; + end; + if not bo1 and not (bs_recapplying in fbstate) then begin //copy needed + po2:= pointer(blobinfo); + pointer(blobinfo):= nil; + blobinfo:= copy(blobinfoarty(po2)); + end; + if int2 >= 0 then begin + deleteblob(blobinfo,int2,blobfree); + end + else begin + if blobfree then begin //else necessary for //done in post + //cancelupdate + freeblobcache(po1,ablob.ffield); + end; + end; + setlength(blobinfo,high(blobinfo)+2); + with blobinfo[high(blobinfo)],ablob do begin + data:= memory; + reallocmem(data,size); + datalength:= size; + field:= ffield; + if not (bs_recapplying in fbstate) then begin + new:= true; + end; + if size = 0 then begin + clearfieldflag(@fielddata.nullmask,field.fieldno-1); + end + else begin + setfieldflag(@fielddata.nullmask,field.fieldno-1); + end; + fieldchanged(field); + end; + end; +end; + +procedure tmsebufdataset.freeblobs(var ablobs: blobinfoarty); +var + int1: integer; +begin + for int1:= 0 to high(ablobs) do begin + freeblob(ablobs[int1]); + end; + ablobs:= nil; +end; + +procedure tmsebufdataset.deleteblob(var ablobs: blobinfoarty; + const aindex: integer; const afreeblob: boolean); +begin + if afreeblob then begin + freeblob(ablobs[aindex]); + end; + deleteitem(ablobs,typeinfo(blobinfoarty),aindex); +end; + +procedure tmsebufdataset.deleteblob(var ablobs: blobinfoarty; + const afield: tfield; const adeleteitem: boolean); +var + int1: integer; +begin + for int1:= high(ablobs) downto 0 do begin + if ablobs[int1].field = afield then begin + freeblob(ablobs[int1]); + if adeleteitem then begin + deleteitem(ablobs,typeinfo(blobinfoarty),int1); + end + else begin + ablobs[int1].field:= nil; + end; + exit; + end; + end; + if not adeleteitem then begin //called from post + freeblobcache(@fcurrentbuf^.header,afield); + end; +end; + +procedure tmsebufdataset.initsavepoint; +begin + fsavepointlevel:= -1; + exclude(fbstate1,bs1_deferdeleterecupdatebuffer); +end; + +procedure tmsebufdataset.dointernalopen; +var + int1: integer; + kind1: filtereditkindty; +begin + initsavepoint; + for int1:= 0 to fields.count - 1 do begin + with fields[int1] do begin + if (fieldkind = fkdata) and (fielddefs.indexof(fieldname) < 0) then begin + databaseerrorfmt(sfieldnotfound,[fieldname],self); + end; + end; + end; + include(fbstate,bs_opening); + if bdo_cacheblobs in foptions then begin + include(fbstate,bs_blobsfetched); + end + else begin + exclude(fbstate,bs_blobsfetched); + end; + if isutf8 then begin + include(fbstate,bs_utf8); + end + else begin + exclude(fbstate,bs_utf8); + end; + bindfields(true); //calculate calc fields size + setlength(findexes,1+findexlocal.count); + factindexpo:= @findexes[factindex]; + calcrecordsize; + findexlocal.bindfields; + femptybuffer:= intallocrecord; + for kind1:= low(filtereditkindty) to high(filtereditkindty) do begin + ffilterbuffer[kind1]:= pdsrecordty(allocrecordbuffer); + end; + fnewvaluebuffer:= pdsrecordty(allocrecordbuffer); +// flookupbuffer:= pdsrecordty(allocrecordbuffer); + updatestate; + fallpacketsfetched:= false; + fopen:= true; +end; + +procedure tmsebufdataset.internalopen; +begin + if blobscached then begin + include(fbstate,bs_blobscached); + end + else begin + exclude(fbstate,bs_blobscached); + end; + if streamloading then begin + doloadfromstream; + end + else begin + dointernalopen; + end; + if fdelayedapplycount > 0 then begin + registeronidle; + end; +end; + +procedure tmsebufdataset.openlocal; +var + bo1: boolean; +begin + bo1:= false; + if defaultfields then begin + createfields; + end; + if (floadingstream = nil) and + (flogfilename <> '') and findfile(flogfilename) then begin + floadingstream:= tmsefilestream.create(flogfilename,fm_read); + tmsefilestream(floadingstream).cryptohandler:= fcryptohandler; + bo1:= true; + end; + if floadingstream <> nil then begin + try + doloadfromstream; + finally + if bo1 then begin + freeandnil(floadingstream); + end; + end; + end + else begin + dointernalopen; + fallpacketsfetched:= true; + end; + if (flogfilename <> '') and not (csdesigning in componentstate) then begin + dropupdates1(true); + startlogger; //drop old updates + end; +end; + +procedure tmsebufdataset.dointernalclose; +var + int1: integer; + kind1: filtereditkindty; +begin + unregisteronidle(); + exclude(fbstate,bs_opening); + dropupdates1(false); + closelogger; + frecno:= -1; + resetblobcache; + if fopen then begin + fopen:= false; + with findexes[0] do begin + for int1:= 0 to fbrecordcount - 1 do begin + intfreerecord(pintrecordty(ind[int1])); + end; + end; + intfreerecord(femptybuffer); + for kind1:= low(filtereditkindty) to high(filtereditkindty) do begin + intfinalizerecord(@ffilterbuffer[kind1]^.header); + freerecordbuffer(pchar(ffilterbuffer[kind1])); + end; + freemem(fnewvaluebuffer); //allways copied by move, needs no finalize +// for int1:= 0 to high(fupdatebuffer) do begin +// with fupdatebuffer[int1] do begin +// if bookmark.recordpo <> nil then begin +// intfreerecord(oldvalues); +// end; +// end; +// end; +// fupdatebuffer:= nil; + end; + clearindex; + fbrecordcount:= 0; + + ffieldinfos:= nil; + fstringpositions:= nil; + fvarpositions:= nil; + fcalcfieldbufpositions:= nil; + flookupfieldinfos:= nil; + for int1:= high(flookupmasters) downto 0 do begin + removeitem(pointerarty(flookupmasters[int1].flookupclients),pointer(self)); + end; + flookupmasters:= nil; + fcalcfieldsizes:= nil; + fcalcstringpositions:= nil; + fcalcvarpositions:= nil; + flookupupdate:= 0; + + bindfields(false); +end; + +procedure tmsebufdataset.internalclose; +begin + fappliedcount:= 0; + dointernalclose; +end; + +procedure tmsebufdataset.clearbuffers; +begin + if bs_editing in fbstate then begin + internalcancel; //free data + end; + inherited; +end; + +procedure tmsebufdataset.internalinsert; +begin + include(fbstate,bs_editing); + exclude(fbstate1,bs1_inupdatechanged); + with pdsrecordty(activebuffer)^.dsheader.bookmark.data do begin + recordpo:= nil; + recno:= frecno; + end; + inherited; +end; + +procedure tmsebufdataset.internaledit; +begin + addrefvalues(pdsrecordty(activebuffer)^.header); + fbstate:= fbstate + [bs_startedit,bs_editing]; + exclude(fbstate1,bs1_inupdatechanged); +// include(fbstate,bs_editing); + inherited; +end; + +procedure tmsebufdataset.internalfirst; +begin + internalsetrecno(-1); +end; + +procedure tmsebufdataset.internallast; +begin +{ + repeat + until (getnextpacket < fpacketrecords) or (bs_fetchall in fbstate); +} + getnextpacket(true); + internalsetrecno(fbrecordcount) +end; + +function tmsebufdataset.getrecord(buffer: pchar; getmode: tgetmode; + docheck: boolean): tgetresult; +var + acceptable: boolean; + state1: tdatasetstate; +begin + result:= grok; + acceptable:= true; + fcheckfilterbuffer:= pointer(buffer); + repeat + case getmode of + gmprior: begin + if frecno <= 0 then begin + result := grbof; + end + else begin + internalsetrecno(frecno-1); + end; + end; + gmcurrent: begin + if (frecno < 0) or (frecno >= fbrecordcount) or + (fcurrentbuf = nil) then begin + result := grerror; + end; + end; + gmnext: begin + if frecno >= fbrecordcount - 1 then begin + if getnextpacket(bs_fetchall in fbstate) = 0 then begin + result:= greof; + end + else begin + internalsetrecno(frecno+1); + end; + end + else begin + internalsetrecno(frecno+1); + end; + end; + end; + if result = grok then begin + with pdsrecordty(buffer)^ do begin + with dsheader.bookmark do begin + data.recno:= frecno; + data.recordpo:= fcurrentbuf; + flag:= bfcurrent; + end; + move(fcurrentbuf^.header,header,frecordsize); + getcalcfields(buffer); //get lookup fields + if filtered then begin + state1:= settempstate(tdatasetstate(dscheckfilter)); + try + acceptable:= true; + dofilterrecord(acceptable); + finally + restorestate(state1); + end; + end; + if (getmode = gmcurrent) and not acceptable then begin + result:= grerror; + end; + end; + end; + until acceptable or (result <> grok); + if docheck and (result = grerror) then begin + databaseerror('No record'); + end; +end; + +function tmsebufdataset.getrecordupdatebuffer : boolean; +var + int1: integer; +begin + if bs_recapplying in fbstate then begin + result:= true; //fcurrentupdatebuffer is valid + end + else begin + with pdsrecordty(activebuffer)^.dsheader.bookmark.data do begin + if (fcurrentupdatebuffer >= length(fupdatebuffer)) or + (fupdatebuffer[fcurrentupdatebuffer].info.bookmark.recordpo <> + recordpo) then begin + for int1:= 0 to high(fupdatebuffer) do begin + with fupdatebuffer[int1] do begin + if (info.bookmark.recordpo = recordpo) and + not (ruf_applied in info.flags) then begin + fcurrentupdatebuffer:= int1; + break; + end; + end; + end; + end; + result:= (fcurrentupdatebuffer <= high(fupdatebuffer)) and + (fupdatebuffer[fcurrentupdatebuffer].info.bookmark.recordpo = recordpo) and + (recordpo <> nil); + end; + end; +end; + +procedure tmsebufdataset.internalsettorecord(buffer: pchar); +begin + internalsetrecno(pdsrecordty(buffer)^.dsheader.bookmark.data.recno); +end; + +procedure tmsebufdataset.setbookmarkdata(buffer: pchar; data: pointer); +begin + move(data^,pdsrecordty(buffer)^.dsheader.bookmark,sizeof(bookmarkdataty)); +end; + +procedure tmsebufdataset.setbookmarkflag(buffer: pchar; value: tbookmarkflag); +begin + pdsrecordty(buffer)^.dsheader.bookmark.flag := value; +end; + +procedure tmsebufdataset.GetBookmarkData(Buffer: PChar; Data: Pointer); +begin + move(pdsrecordty(buffer)^.dsheader.bookmark,data^,sizeof(bookmarkdataty)); +end; + +function tmsebufdataset.getbookmarkdata1: bookmarkdataty; +begin + getbookmarkdata(activebuffer,@result); +end; + +function tmsebufdataset.getbookmarkflag(buffer: pchar): tbookmarkflag; +begin + result:= pdsrecordty(buffer)^.dsheader.bookmark.flag; +end; + +function tmsebufdataset.findrecord(arecordpo: pintrecordty): integer; +//-1 if not found +var + int1: integer; + po1: ppointeraty; +begin + if factindex = 0 then begin + result:= -1; + po1:= pointer(findexes[0].ind); + for int1:= fbrecordcount - 1 downto 0 do begin + if po1^[int1] = arecordpo then begin + result:= int1; + break; + end; + end; + end + else begin + result:= findexlocal[factindex-1].findrecord(arecordpo); + end; +end; + +function tmsebufdataset.findbookmarkindex( + const abookmark: bookmarkdataty): integer; +begin + with abookmark do begin + if (recno >= fbrecordcount) or (recno < 0) then begin + databaseerror('Invalid bookmark recno: '+inttostr(recno)+'.'); + end; +// checkindex(false); + checkindex(factindex); + if (factindexpo^.ind[recno] <> recordpo) and (recordpo <> nil) then begin + result:= findrecord(recordpo); + if result < 0 then begin + databaseerror('Invalid bookmarkdata.'); + end; + end + else begin + result:= recno; + end; + end; +end; + +procedure tmsebufdataset.internalgotobookmark(abookmark: pointer); +begin + if abookmark <> nil then begin + internalsetrecno(findbookmarkindex(pbufbookmarkty(abookmark)^.data)); + end; +end; + +function tmsebufdataset.findbookmark(const abookmark: bookmarkdataty): boolean; +var + int1: integer; + bm1: bookmarkdataty; +begin + result:= false; + with abookmark do begin +// checkindex(false); + checkindex(factindex); + if (recno < 0) or (recno >= fbrecordcount) or + (factindexpo^.ind[recno] <> recordpo) and (recordpo <> nil) then begin + int1:= findrecord(recordpo); + end + else begin + int1:= recno; + end; + if int1 >= 0 then begin + bm1:= abookmark; + bm1.recno:= int1; + gotobookmark(@bm1); + result:= true; + end; + end; +end; + +procedure tmsebufdataset.gotobookmark(const abookmark: bookmarkdataty); +begin + gotobookmark(@abookmark); +end; + +function tmsebufdataset.getnextpacket(const all: boolean): integer; +var + state1: tdatasetstate; + int1,int2,int3: integer; + recnobefore: integer; + bufbefore: pointer; + bo1,bo2: boolean; + ar1: fieldarty; + field1: tfield; + {$ifdef mse_debugdataset} + ts: longword; + {$endif} + +begin + result:= 0; + if fallpacketsfetched then begin + exit; + end; + int2:= fbrecordcount; + database.beforeaction; + try +{$ifdef mse_debugdataset} + if all then begin + debugoutstart(ts,self,'getnextpacket all'); + end + else begin + debugoutstart(ts,self,'getnextpacket'); + end; +{$endif} + while ((result < fpacketrecords) or all) and + (loadbuffer(femptybuffer^.header) = grok) do begin + appendrecord(femptybuffer); + femptybuffer:= intallocrecord; + inc(result); + end; + bo1:= checkcanevent(self,tmethod(foninternalcalcfields)); + bo2:= (bs_initinternalcalc in fbstate); + if bo2 then begin + setlength(ar1,fields.count); + int3:= 0; + for int1:= 0 to high(ar1) do begin + field1:= fields[int1]; + with field1 do begin + if (fieldkind = fkinternalcalc) and (defaultexpression <> '') then begin + ar1[int3]:= field1; + inc(int3); + end; + end; + end; + setlength(ar1,int3); + end; + if bo1 or bo2 then begin + state1:= settempstate(dsinternalcalc); + fbstate:= fbstate + [bs_internalcalc,bs_fetching]; + recnobefore:= frecno; + bufbefore:= fcurrentbuf; + try + for int1:= int2 to fbrecordcount-1 do begin + frecno:= int1; + fcurrentbuf:= findexes[0].ind[int1]; + if bo2 then begin + for int3:= 0 to high(ar1) do begin + with ar1[int3] do begin + asstring:= defaultexpression; + end; + end; + end; + if bo1 then begin + foninternalcalcfields(self,true); + end; + end; + finally + frecno:= recnobefore; + fcurrentbuf:= bufbefore; + fbstate:= fbstate - [bs_internalcalc,bs_opening,bs_fetching]; + restorestate(state1); + end; + end; + exclude(fbstate,bs_opening); + {$ifdef mse_debugdataset} + debugoutend(ts,self,'getnextpacket'); + {$endif} + finally + database.afteraction; + end; +end; + +function tmsebufdataset.getfieldsize(const datatype: tfieldtype; + const varsize: integer; out basetype: tfieldtype): longint; +begin + case datatype of + ftstring,ftfixedchar,ftwidestring,ftfixedwidechar,ftwidememo: begin + result:= sizeof(msestring); + basetype:= ftwidestring; + end; + ftbytes: begin + result:= varsize; + basetype:= ftbytes; + end; + ftvarbytes: begin + result:= varsize + sizeof(word); + basetype:= ftvarbytes; + end; + ftguid: begin + result:= sizeof(tguid); + basetype:= ftguid; + end; + ftsmallint,ftinteger,ftword: begin + result:= sizeof(longint); + basetype:= ftinteger; + end; + ftboolean: begin + result:= sizeof(longbool); + basetype:= ftboolean; + end; + ftbcd: begin + result:= sizeof(currency); + basetype:= ftbcd; + end; + ftfloat,ftcurrency: begin + result:= sizeof(double); + basetype:= ftfloat; + end; + ftlargeint: begin + result:= sizeof(largeint); + basetype:= ftlargeint; + end; + fttime,ftdate,ftdatetime: begin + result:= sizeof(tdatetime); + basetype:= ftdatetime; + end; + ftmemo,ftblob: begin + result:= getblobdatasize; + basetype:= ftblob; + end; + ftvariant: begin + result:= sizeof(variant); + basetype:= ftvariant; + end; + else begin + result:= 0; + basetype:= ftunknown; + end; + end; +end; + +function tmsebufdataset.loadbuffer(var buffer: recheaderty): tgetresult; +var + int1,int2: integer; + str1: string; + field1: tfield; + po2: pmsestring; + fno: integer; +begin + if not fetch then begin + result := greof; + fallpacketsfetched := true; + exit; + end; + pointer(buffer.blobinfo):= nil; + fillchar(buffer.fielddata.nullmask,fnullmasksize,$ff); + for int1:= 0 to fields.count-1 do begin + field1:= fields[ffieldorder[int1]]; //ODBC needs ordered loadfield + fno:= field1.fieldno-1; + with ffieldinfos[fno].base do begin + case field1.fieldkind of + fkdata: begin + int2:= dbfieldsize; + if field1.datatype in charfields then begin + int2:= int2*4+4; //room for multibyte encodings + setlength(str1,int2); + if not loadfield(fno,fieldtype,pointer(str1),int2) then begin + clearfieldflag(@buffer.fielddata.nullmask,fno); + end + else begin + if int2 < 0 then begin //buffer to small + int2:= -int2; + setlength(str1,int2); + loadfield(fno,fieldtype,pointer(str1),int2); + end; + setlength(str1,int2); + po2:= pointer(pchar(@buffer) + offset); + if fieldtype in widecharfields then begin + setlength(po2^,int2 div 2); + move(pointer(str1)^,pointer(po2^)^,int2); + end + else begin + try + if bs_utf8 in fbstate then begin + po2^:= utf8tostringansi(str1); + end + else begin + po2^:= msestring(str1); + end; + except + po2^:= converrorstring; + end; + end; + if (dbfieldsize <> 0) and (length(po2^) > dbfieldsize) then begin + setlength(po2^,dbfieldsize); + end; + end; + end + else begin + if not loadfield(fno,fieldtype,pchar(@buffer)+offset,int2) or + (int2 < 0)then begin + clearfieldflag(@buffer.fielddata.nullmask,fno); //buffer too small + end; + end; + end; + fkinternalcalc: begin + clearfieldflag(@buffer.fielddata.nullmask,fno); + end; + end; + end; + end; + result:= grok; +end; + +function tmsebufdataset.getfieldbuffer(const afield: tfield; + out buffer: pointer; out datasize: integer): boolean; + //read buffer + //true if not null +var + int1: integer; + st1: integer; +begin + result:= false; + buffer:= nil; + if not fopen{active} then begin + exit; + end; + int1:= afield.fieldno - 1; + if (flookuppo <> nil) and (int1 >= 0) then begin + buffer:= flookuppo; + result:= getfieldflag(@precheaderty(buffer)^.fielddata.nullmask,int1); + inc(pchar(buffer),ffieldinfos[int1].base.offset{ffieldbufpositions[int1]}); + datasize:= ffieldinfos[int1].base.size{ffieldsizes[int1]}; + exit; + end; + st1:= ord(state); + if bs_displaydata in fbstate then begin + st1:= ord(dsbrowse); + end; + case st1 of + ord(dscalcfields): begin + buffer:= @pdsrecordty(fcalcbuffer1)^.header; + end; + dscheckfilter: begin + buffer:= @fcheckfilterbuffer^.header; + end; + ord(dsfilter): begin + buffer:= @ffilterbuffer[ffiltereditkind]^.header; + end; + ord(dscurvalue): begin + if (buffercount <= 0) or //probably fetchallblobs() + (pdsrecordty(activebuffer)^.dsheader.bookmark.data.recordpo <> + nil) then begin + buffer:= @fcurrentbuf^.header; + end + else begin + buffer:= @pdsrecordty(activebuffer)^.header; //insert + end; + end; + else begin + if fbstate * [bs_internalcalc,bs_displaydata] = [bs_internalcalc] then begin + if int1 < 0 then begin//calc field + buffer:= @pdsrecordty(activebuffer)^.header; + //values invalid! + end + else begin + buffer:= @fcurrentbuf^.header; + end; + end + else begin + if fbstate*[bs_recapplying,bs_displaydata] = [bs_recapplying] then begin + buffer:= @fnewvaluebuffer^.header; + end + else begin + buffer:= @pdsrecordty(activebuffer)^.header; + end; + end; + end; + end; + if int1 >= 0 then begin // data field + result:= false; + if state = dsoldvalue then begin + if getrecordupdatebuffer then begin + buffer:= fupdatebuffer[fcurrentupdatebuffer].oldvalues; + if buffer <> nil then begin + buffer:= @pintrecordty(buffer)^.header; + end; + end + else begin //there is no old value available + if pdsrecordty(activebuffer)^.dsheader.bookmark.data.recordpo <> nil + then begin //dsinsert otherwise + buffer:= @fcurrentbuf^.header + end; + end; + end; + if buffer <> nil then begin + result:= getfieldflag(@precheaderty(buffer)^.fielddata.nullmask,int1); + inc(pchar(buffer),ffieldinfos[int1].base.offset{ffieldbufpositions[int1]}); + datasize:= ffieldinfos[int1].base.size{ffieldsizes[int1]}; + end + else begin + datasize:= 0; + end; + end + else begin + int1:= -2 - int1; + if int1 >= 0 then begin //calc field + result:= getfieldflag(pointer(pchar(buffer)+frecordsize),int1); + inc(pchar(buffer),fcalcfieldbufpositions[int1]); + datasize:= fcalcfieldsizes[int1]; + end + else begin + buffer:= nil; + datasize:= 0; + end; + end; +end; + +function tmsebufdataset.getfieldbuffer(const afield: tfield; + const aisnull: boolean; out datasize: integer): pointer; + //write buffer +var + int1: integer; + state1: tdatasetstate; +begin + if (bs_recapplying in fbstate) and (state = dsbrowse) then begin + state1:= dsedit; //dummy + include(fbstate,bs_curvaluemodified); + end + else begin + if not ((state in dswritemodes - [dsinternalcalc,dscalcfields]) or + (afield.fieldkind = fkinternalcalc) and + (state = dsinternalcalc) or + (afield.fieldkind = fkcalculated) and + (state = dscalcfields) or + (afield.fieldkind = fklookup) + {or + (bs_curvaluesetting in fbstate) and (state = dscurvalue)}) then begin + databaseerrorfmt(snotediting,[name],self); + end; + state1:= state; + end; + int1:= afield.fieldno-1; + case state1 of + dscalcfields: begin + result:= @pdsrecordty(fcalcbuffer1)^.header; + end; + dsfilter: begin + result:= @ffilterbuffer[ffiltereditkind]^.header; + end; + dscurvalue: begin + result:= @fcurrentbuf^.header; + end; + else begin + if bs_internalcalc in fbstate then begin + if int1 < 0 then begin//calc field + result:= @pdsrecordty(activebuffer)^.header; + //values invalid! + end + else begin + result:= @fcurrentbuf^.header; + end; + end + else begin + if bs_recapplying in fbstate then begin + result:= @fnewvaluebuffer^.header; + end + else begin + result:= @pdsrecordty(activebuffer)^.header; + end; + if (int1 >= 0) and // data field + (of_inupdate in afield.optionsfield) then begin + include(fbstate1,bs1_inupdatechanged); + end; + end; + end; + end; + if int1 >= 0 then begin // data field + if aisnull then begin + clearfieldflag(@precheaderty(result)^.fielddata.nullmask,int1); + end + else begin + setfieldflag(@precheaderty(result)^.fielddata.nullmask,int1); + end; + inc(pchar(result),ffieldinfos[int1].base.offset{ffieldbufpositions[int1]}); + datasize:= ffieldinfos[int1].base.size{ffieldsizes[int1]}; + end + else begin + int1:= -2 - int1; + if int1 >= 0 then begin //calc field + if aisnull then begin + clearfieldflag(pbyte(pchar(result)+frecordsize),int1); + end + else begin + setfieldflag(pbyte(pchar(result)+frecordsize),int1); + end; + inc(pchar(result),fcalcfieldbufpositions[int1]); + datasize:= fcalcfieldsizes[int1]; + end + else begin + result:= nil; + datasize:= 0; + end; + end; +end; + +procedure tmsebufdataset.fieldchanged(const field: tfield); +begin + if {(field.fieldno > 0) and} not + (state in [dscalcfields,dsinternalcalc,{dsfilter,}dsnewvalue]) and + not (bs_recapplying in fbstate) then begin + dataevent(defieldchange, ptrint(field)); + end; +end; + +function tmsebufdataset.getfielddata(field: tfield; buffer: pointer): boolean; +var + po1: pointer; + datasize: integer; +begin + result:= getfieldbuffer(field,po1,datasize); + if (buffer <> nil) and result then begin + move(po1^,buffer^,datasize); + end; +end; + +function tmsebufdataset.getfielddata(field: tfield; buffer: pointer; + nativeformat: boolean): boolean; +begin + result:= getfielddata(field,buffer); +end; + +function tmsebufdataset.getmsestringdata(const sender: tmsestringfield; + out avalue: msestring): boolean; +var + po1: pointer; + int1: integer; +begin + {$ifdef FPC}{$warnings off}{$endif} + with tfield1(sender) do begin + {$ifdef FPC}{$warnings on}{$endif} + if fvalidating then begin + result:= (fvaluebuffer <> nil) and (foffset and 1 = 0); + po1:= fvaluebuffer; + end + else begin + result:= getfieldbuffer(sender,po1,int1); + end; + end; + if result then begin + avalue:= msestring(po1^); + end + else begin + avalue:= ''; + end; +end; + +function tmsebufdataset.getvardata(const sender: tmsevariantfield; + out avalue: variant): boolean; +var + po1: pvariant; + int1: integer; +begin + {$ifdef FPC}{$warnings off}{$endif} + with tfield1(sender) do begin + {$ifdef FPC}{$warnings on}{$endif} + if fvalidating then begin + result:= (fvaluebuffer <> nil) and (foffset and 1 = 0); + po1:= fvaluebuffer; + end + else begin + result:= getfieldbuffer(sender,pointer(po1),int1); + end; + end; + if result then begin + avalue:= po1^; + end + else begin + avalue:= null; + end; +end; + +procedure tmsebufdataset.checkfreebuffer(const afield: tfield); +begin + {$ifdef FPC}{$warnings off}{$endif} + with tfield1(afield) do begin + {$ifdef FPC}{$warnings on}{$endif} + if foffset and 2 <> 0 then begin + freemem(fvaluebuffer); + fvaluebuffer:= nil; + end; + end; +end; + +function tmsebufdataset.callvalidate(const afield: tfield; + const avalue: pointer): boolean; + //true if not nulled +begin + {$ifdef FPC}{$warnings off}{$endif} + with tfield1(afield) do begin + {$ifdef FPC}{$warnings on}{$endif} + foffset:= 0; + fvaluebuffer:= avalue; + afield.validate(avalue); + result:= (avalue <> nil) and (foffset and 1 = 0); + end; +end; + +procedure tmsebufdataset.checkvaluebuffer(const afield: tfield; + const asize: integer); +begin + {$ifdef FPC}{$warnings off}{$endif} + with tfield1(afield) do begin + {$ifdef FPC}{$warnings on}{$endif} + foffset:= foffset and not 1; + if fvaluebuffer = nil then begin + getmem(fvaluebuffer,asize); + fillchar(fvaluebuffer^,asize,0); + foffset:= foffset or 2; + end; + end; +end; + +procedure tmsebufdataset.setfielddata(field: tfield; buffer: pointer); + +var + po1: pointer; + datasize1: integer; +begin + {$ifdef FPC}{$warnings off}{$endif} + with tfield1(field) do begin + {$ifdef FPC}{$warnings on}{$endif} + if fvalidating then begin + if buffer = nil then begin + foffset:= foffset or 1; + end + else begin + getfieldbuffer(field,po1,datasize1); //get data size + checkvaluebuffer(field,datasize1); + move(buffer^,fvaluebuffer^,datasize1); + end; + end + else begin + try + if callvalidate(field,buffer) then begin + po1:= getfieldbuffer(field,false,datasize1); + move(fvaluebuffer^,po1^,datasize1); + end + else begin + po1:= getfieldbuffer(field,true,datasize1); + case field.datatype of + ftstring: begin + pmsestring(po1)^:= ''; + end; + ftvariant: begin + freedbvariant(pvariant(po1)^); + end; + else begin + fillchar(po1^,datasize1,0); + end; + end; + end; + finally + checkfreebuffer(field); + end; + fieldchanged(field); + end; + end; +end; + +procedure tmsebufdataset.setfielddata(field: tfield; buffer: pointer; + nativeformat: boolean); +begin + setfielddata(field,buffer); +end; + +procedure tmsebufdataset.setmsestringdata(const sender: tmsestringfield; + avalue: msestring); +var + po1: pmsestring; + int1: integer; +begin + {$ifdef FPC}{$warnings off}{$endif} + with tfield1(sender) do begin + {$ifdef FPC}{$warnings on}{$endif} + if fvalidating then begin + checkvaluebuffer(sender,sizeof(msestring)); + pmsestring(fvaluebuffer)^:= avalue; + end + else begin + try + if callvalidate(sender,@avalue) then begin + po1:= getfieldbuffer(sender,false,int1); + po1^:= pmsestring(fvaluebuffer)^; + if (sender.characterlength > 0) and + (length(avalue) > sender.characterlength) then begin + setlength(msestring(po1^),sender.characterlength); + end; + end + else begin + po1:= getfieldbuffer(sender,true,int1); + po1^:= ''; + end; + finally + pmsestring(fvaluebuffer)^:= ''; + checkfreebuffer(sender); + end; + fieldchanged(sender); + end; + end; +end; + +procedure tmsebufdataset.setvardata(const sender: tmsevariantfield; + avalue: variant); +var + po1: pvariant; + int1: integer; +begin + {$ifdef FPC}{$warnings off}{$endif} + with tfield1(sender) do begin + {$ifdef FPC}{$warnings on}{$endif} + if fvalidating then begin + checkvaluebuffer(sender,sizeof(variant)); + pvariant(fvaluebuffer)^:= avalue; + end + else begin + try + if callvalidate(sender,@avalue) then begin + po1:= getfieldbuffer(sender,false,int1); + po1^:= pvariant(fvaluebuffer)^; + end + else begin + po1:= getfieldbuffer(sender,true,int1); + finalize(po1^); + fillchar(po1^,sizeof(variant),0); + end; + finally + finalize(pvariant(fvaluebuffer)^); + checkfreebuffer(sender); + end; + fieldchanged(sender); + end; + end; +end; + +procedure tmsebufdataset.getnewupdatebuffer; +begin + setlength(fupdatebuffer,high(fupdatebuffer)+2); + fcurrentupdatebuffer:= high(fupdatebuffer); +end; + +procedure tmsebufdataset.internaldelete; +var + po1: pintrecordty; + recnobefore: integer; +begin + if state = dsedit then begin + internalcancel; + end; + po1:= fcurrentbuf; + recnobefore:= frecno; + deleterecord(frecno); + if not (bdo_noapply in foptions) then begin + if not getrecordupdatebuffer then begin + getnewupdatebuffer; + with fupdatebuffer[fcurrentupdatebuffer] do begin + info.bookmark.recno:= recnobefore; + info.bookmark.recordpo:= po1; + oldvalues:= info.bookmark.recordpo; + end; + end + else begin + with fupdatebuffer[fcurrentupdatebuffer] do begin + intfreerecord(info.bookmark.recordpo); + if info.updatekind = ukmodify then begin + info.bookmark.recordpo:= oldvalues; + end + else begin //ukinsert + info.bookmark.recordpo := nil; //this 'disables' the updatebuffer + end; + end; + end; + fupdatebuffer[fcurrentupdatebuffer].info.updatekind := ukdelete; + if flogger <> nil then begin + logupdatebuffer(flogger,fupdatebuffer[fcurrentupdatebuffer],po1,true,lf_update); + flogger.flushbuffer; + end; + end; +end; + +procedure tmsebufdataset.applyrecupdate(updatekind : tupdatekind); +begin + raise edatabaseerror.create(sapplyrecnotsupported); +end; + +procedure tmsebufdataset.cancelrecupdate(var arec: recupdatebufferty); +begin + if (flogger <> nil) and not (bs_loading in fbstate) then begin + logupdatebuffer(flogger,arec,nil,true,lf_cancel); + flogger.flushbuffer; + end; + with arec do begin + if info.bookmark.recordpo <> nil then begin + if info.updatekind = ukmodify then begin + freeblobs(info.bookmark.recordpo^.header.blobinfo); + finalizevalues(info.bookmark.recordpo^.header); + move(oldvalues^.header,info.bookmark.recordpo^.header,frecordsize); + freemem(oldvalues); //no finalize + end + else begin + if info.updatekind = ukdelete then begin + insertrecord(info.bookmark.recno,info.bookmark.recordpo); + end + else begin + if info.updatekind = ukinsert then begin + deleterecord(info.bookmark.recordpo); + if info.bookmark.recordpo = fcurrentbuf then begin + fcurrentbuf:= nil; + if frecno >= 0 then begin + dec(frecno); + end; + end; + intfreerecord(info.bookmark.recordpo); + end; + end; + end; + end; + end; +end; + +procedure tmsebufdataset.cancelupdate(const norecordcancel: boolean = false); +var + int1: integer; +begin + cancel; + checkbrowsemode; + if (fupdatebuffer <> nil) and (frecno >= 0) then begin + for int1:= high(fupdatebuffer) downto 0 do begin + if fupdatebuffer[int1].info.bookmark.recordpo = fcurrentbuf then begin + if not norecordcancel then begin + cancelrecupdate(fupdatebuffer[int1]); + end + else begin + with fupdatebuffer[int1] do begin + intFreeRecord(OldValues); + info.bookmark.recordpo:= nil + end; + end; + deleteitem(fupdatebuffer,typeinfo(recupdatebufferarty),int1); + if int1 <= fapplyindex then begin + dec(fapplyindex); + end; + resync([]); + break; + end; + end; + end; +end; + +procedure tmsebufdataset.cancelupdates; +var + int1: integer; +begin + cancel; + checkbrowsemode; + if high(fupdatebuffer) >= 0 then begin + for int1:= high(fupdatebuffer) downto 0 do begin + cancelrecupdate(fupdatebuffer[int1]); + end; + fupdatebuffer:= nil; + resync([]); + end; +end; + +procedure tmsebufdataset.dropupdates1(const apply: boolean); +var + po1: precupdatebufferty; + i1: int32; +begin + for i1:= 0 to high(fupdatebuffer) do begin + po1:= @fupdatebuffer[i1]; + with po1^ do begin + if info.bookmark.recordpo <> nil then begin + if apply or (ruf_applied in info.flags) then begin + recupdatebufferapplied(po1); + end + else begin + recupdatebufferdropped(po1); + end; + end; + end; + end; + fupdatebuffer:= nil; +end; + +procedure tmsebufdataset.SetOnUpdateError(const AValue: updateerroreventty); + +begin + FOnUpdateError := AValue; +end; + +procedure tmsebufdataset.recupdatebufferapplied(const abuf: precupdatebufferty); +begin + if flogger <> nil then begin + logupdatebuffer(flogger,abuf^,nil,true,lf_apply); + flogger.flushbuffer; + end; + intFreeRecord(abuf^.OldValues); + abuf^.info.bookmark.recordpo:= nil; +end; + +procedure tmsebufdataset.recupdatebufferdropped(const abuf: precupdatebufferty); +begin + if flogger <> nil then begin + logupdatebuffer(flogger,abuf^,nil,true,lf_drop); + flogger.flushbuffer; + end; + with abuf^ do begin + intfreerecord(oldvalues); + end; +end; + +procedure tmsebufdataset.packrecupdatebuffer; +var + int1,int2: integer; +begin + int2:= 0; + for int1:= 0 to high(fupdatebuffer) do begin //pack + with fupdatebuffer[int1] do begin + if (info.bookmark.recordpo <> nil) or (oldvalues <> nil) then begin + fupdatebuffer[int2]:= fupdatebuffer[int1]; + inc(int2); + end; + end; + end; + setlength(fupdatebuffer,int2); +end; + +procedure tmsebufdataset.restorerecupdatebuffer; +var + int1: integer; +begin + for int1:= high(fupdatebuffer) downto 0 do begin + exclude(fupdatebuffer[int1].info.flags,ruf_applied); + end; +end; + +procedure tmsebufdataset.postrecupdatebuffer; +var + po1: precupdatebufferty; + int1,int2: integer; +begin + int2:= 0; + for int1:= high(fupdatebuffer) downto 0 do begin + po1:= @fupdatebuffer[int1]; + with po1^ do begin + if (ruf_applied in info.flags) and (info.bookmark.recordpo <> nil) then begin + inc(int2); + recupdatebufferapplied(po1); + end; + end; + end; + if int2 = length(fupdatebuffer) then begin + fupdatebuffer:= nil; + end + else begin + packrecupdatebuffer; + end; +end; + +procedure tmsebufdataset.internalapplyupdate(const maxerrors: integer; + const cancelonerror: boolean; + const cancelondeleteerror: boolean; + out response: resolverresponsesty); + + procedure checkrevert; + var + po1: precupdatebufferty; + begin + po1:= @fupdatebuffer[fcurrentupdatebuffer]; + if rr_applied in response then begin + if bs1_deferdeleterecupdatebuffer in fbstate1 then begin + include(po1^.info.flags,ruf_applied); + end + else begin + recupdatebufferapplied(po1); + end; + end + else begin + if (cancelonerror or + cancelondeleteerror and (po1^.info.updatekind = ukdelete)) or + (rr_revert in response) then begin + cancelrecupdate(po1^); + po1^.info.bookmark.recordpo:= nil; + exclude(fbstate,bs_curvaluemodified); + end; + end; + end; //checkrevert + +var + by1,by2: boolean; + e1: exception; + ar1,ar2,ar3: integerarty; +// int1: integer; + origpo: pintrecordty; + +begin + include(fbstate,bs_recapplying); + by1:= not islocal; + by2:= false; + response:= []; + with fupdatebuffer[fcurrentupdatebuffer] do begin + origpo:= info.bookmark.recordpo; + move(origpo^.header,fnewvaluebuffer^.header,frecordsize); + addrefvalues(fnewvaluebuffer^.header); + try + if (info.updatekind <> ukmodify) or (ruf_inupdate in info.flags) then begin + repeat + exclude(fbstate,bs_curvaluemodified); + getcalcfields(pchar(fnewvaluebuffer)); + if rr_again in response then begin + dec(ffailedcount); + exclude(info.flags,ruf_error); + end; + Response:= [rr_applied]; + try + try + if by1 then begin + ApplyRecUpdate(info.UpdateKind); + inc(fappliedcount); + end; + except + on E: EDatabaseError do begin + include(info.flags,ruf_error); + e1:= e; + Inc(fFailedCount); + if e is eapplyerror then begin + response:= eapplyerror(e).response; + end + else begin + if longword(ffailedcount) > longword(MaxErrors) then begin + Response:= [rr_abort] + end + else begin + Response:= []; + end; + end; + e.message:= 'An error occured while applying the updates in a record: '+ + e.message; + if checkcanevent(self,tmethod(OnUpdateError)) then begin + OnUpdateError(Self,edatabaseerror(e1),info.UpdateKind,Response); + if rr_applied in response then begin + dec(ffailedcount); + end; + end; + if rr_abort in response then begin + checkrevert; + if not (rr_quiet in response) then begin + if e = e1 then begin + raise; + end + else begin + if e1 <> nil then begin + Raise e1; + end; + end; + end; + end; + end + else begin + raise; + end; + end; + finally + if bs_curvaluemodified in fbstate then begin + by2:= true; + dointernalcalcfields(false); + // if (updatekind = ukmodify) and + // (bs_refreshupdateindex in fbstate) or + // (updatekind = ukinsert) and + // (bs_refreshinsertindex in fbstate) then begin + // int1:= factindex; + // factindex:= -1; //do not use recno + + saveindex(origpo,@fnewvaluebuffer^.header,ar1,ar2,ar3); + relocateindex(origpo,ar1,ar2,ar3); + // factindex:= int1; + // end; + end; + end; + until response <> [rr_again]; + checkrevert; + end + else begin + response:= [rr_applied,rr_skipped]; + checkrevert(); + end; + finally + exclude(fbstate,bs_recapplying); + if by2 and (info.updatekind <> ukdelete) then begin + include(fbstate1,bs1_needsresync); + finalizevalues(origpo^.header); + move(fnewvaluebuffer^.header,origpo^.header,frecordsize); + end + else begin + finalizevalues(fnewvaluebuffer^.header); + end; + finalizecalcvalues(fnewvaluebuffer^.header); + end; + end; +end; + +procedure tmsebufdataset.afterapply; +begin + //dummy +end; + +procedure tmsebufdataset.editapplyerror(const arecupdatenum: integer); +var + po1: pintrecordty; + info1: recupdatebufferty; +begin + disablecontrols; + try + info1:= fupdatebuffer[arecupdatenum]; + with info1 do begin + if (info.updatekind = ukdelete) or findbookmark(info.bookmark) then begin + po1:= nil; + if info.updatekind in [ukinsert,ukmodify] then begin + po1:= intallocrecord; + move(fcurrentbuf^.header,po1^.header,frecordsize); + addrefvalues(po1^.header); + end; + try + cancelrecupdate(info1); + resync([]); + deleteitem(fupdatebuffer,typeinfo(recupdatebufferarty),arecupdatenum); + if info.updatekind = ukdelete then begin + findbookmark(info.bookmark) + end + else begin + if info.updatekind in [ukmodify,ukinsert] then begin + if info.updatekind = ukmodify then begin + edit; + end + else begin + if ruf_append in info.flags then begin + append(); + end + else begin + insert(); + end; + end; + finalizevalues(pdsrecordty(activebuffer)^.header); + finalizecalcvalues(pdsrecordty(activebuffer)^.header); + move(po1^,pdsrecordty(activebuffer)^.header,frecordsize); + freemem(po1); + setmodified(true); + getcalcfields(activebuffer); + end; + end; + except + if po1 <> nil then begin + intfreerecord(po1); + end; + raise; + end; + end; + end; + finally + enablecontrols; + end; +end; + +procedure tmsebufdataset.applyupdate(const cancelonerror: boolean; + const cancelondeleteerror: boolean = false; + const editonerror: boolean = false); + //applies current record +var + response: resolverresponsesty; + canedit1: boolean; + recupdatebuffernum1: integer; +begin + if not (bs_applying in fbstate) then begin + include(fbstate,bs_applying); + try + canedit1:= false; + checkbrowsemode; + dobeforeapplyupdate; + checkbrowsemode; + if getrecordupdatebuffer then begin + canedit1:= editonerror; + if canedit1 then begin + recupdatebuffernum1:= fcurrentupdatebuffer; + end; + ffailedcount:= 0; + exclude(fbstate1,bs1_needsresync); + try + internalapplyupdate(0,cancelonerror,cancelondeleteerror,response); + if rr_applied in response then begin + canedit1:= false; + end; + finally + if (fcurrentupdatebuffer <= high(fupdatebuffer)) and //??? + (FUpdateBuffer[fcurrentupdatebuffer].info.Bookmark.recordpo = nil) then begin + deleteitem(fupdatebuffer,typeinfo(recupdatebufferarty),fcurrentupdatebuffer); + canedit1:= false; + end; + if bs1_needsresync in fbstate1 then begin + resync([]); + end; + end; + if rr_applied in response then begin + dataevent(tdataevent(de_afterapplyupdate),0); + afterapply; //possible commit + end; + end; + doafterapplyupdate; + finally + exclude(fbstate,bs_applying); + if canedit1 then begin + editapplyerror(recupdatebuffernum1); + end; + end; + end; +end; + +procedure tmsebufdataset.ApplyUpdates(const MaxErrors: Integer; + const cancelonerror: boolean; + const cancelondeleteerror: boolean = false; + const editonerror: boolean = false); +var + recnobefore: integer; + response: resolverresponsesty; + bo1: boolean; + canedit1: boolean; + recupdatenum1: integer; + +begin + if not (bs_applying in fbstate) then begin + include(fbstate,bs_applying); + canedit1:= false; + try + CheckBrowseMode; + dobeforeapplyupdate; + CheckBrowseMode; + disablecontrols; + recnobefore:= frecno; + try + fapplyindex := 0; + fFailedCount := 0; + bo1:= false; + response:= []; + while (fapplyindex <= high(FUpdateBuffer)) and not(rr_abort in response) do begin + canedit1:= editonerror; + fcurrentupdatebuffer:= fapplyindex; + recupdatenum1:= fcurrentupdatebuffer; + with fupdatebuffer[fcurrentupdatebuffer] do begin + if (info.bookmark.recordpo <> nil) and not (ruf_applied in info.flags) then begin + internalapplyupdate(maxerrors,cancelonerror, + cancelondeleteerror,response); + bo1:= bo1 or not (rr_applied in response); + if rr_applied in response then begin + canedit1:= false; + end; + end; + end; + inc(fapplyindex); + // if (bs_idle in fbstate) and not application.idle then begin + // break; + // end; + //win98 is not idle after applyupdate ??? + end; + finally + fcurrentupdatebuffer:= bigint; //invalid + if not (bs1_deferdeleterecupdatebuffer in fbstate1) then begin + if (ffailedcount = 0) and (fapplyindex > high(fupdatebuffer)) then begin + fupdatebuffer:= nil; + end + else begin + packrecupdatebuffer; + end; + end; + if active then begin + internalsetrecno(recnobefore); + resync([]); + enablecontrols; + end + else begin + enablecontrols; + end; + end; + if not bo1 then begin + dataevent(tdataevent(de_afterapplyupdate),0); + afterapply; //possible commit + end; + doafterapplyupdate; + finally + exclude(fbstate,bs_applying); + if canedit1 then begin + editapplyerror(recupdatenum1); + end; + end; + end; +end; + +procedure tmsebufdataset.ApplyUpdates(const maxerrors: integer = 0); +begin + applyupdates(maxerrors,false); +end; + +procedure tmsebufdataset.applyupdate; +begin + applyupdate(false); +end; + +procedure tmsebufdataset.saveindex(const oldbuffer,newbuffer: pintrecordty; + var ar1,ar2,ar3: integerarty); +var + int1: integer; + lastind: integer; +begin + if (bs_hasvalidindex in fbstate) then begin + setlength(ar1,findexlocal.count); + setlength(ar2,length(ar1)); + setlength(ar3,length(ar1)); + for int1:= high(ar1) downto 0 do begin + if findexes[int1+1].ind <> nil then begin + with findexlocal[int1] do begin + lastind:= high(findexfieldinfos); + ar2[int1]:= compare1(oldbuffer,newbuffer,lastind,false); + if ar2[int1] <> 0 then begin + if int1 = factindex - 1 then begin + ar1[int1]:= frecno + 1; //for fast find of bufpo + end + else begin + ar1[int1]:= findboundary(@compare1,oldbuffer,lastind,true); //old boundary + end; + ar3[int1]:= findboundary(@compare1,newbuffer,lastind,true); //new boundary + end; + end; + end; + end; + end; +end; + +procedure tmsebufdataset.relocateindex(const abuffer: pintrecordty; + const ar1,ar2,ar3: integerarty); +var + int1,int2,int3: integer; +begin + if bs_hasvalidindex in fbstate then begin +// with pdsrecordty(activebuffer)^ do begin + for int1:= high(ar1) downto 0 do begin + if findexes[int1+1].ind <> nil then begin + if ar2[int1] <> 0 then begin // position changed + include(fbstate1,bs1_needsresync); + int2:= ar3[int1]; //new boundary + with findexes[int1+1] do begin + for int3:= ar1[int1] - 1 downto 0 do begin + if ind[int3] = abuffer then begin //update indexes + move(ind[int3+1],ind[int3],(fbrecordcount-int3-1)*sizeof(pointer)); + if int3 < int2 then begin + dec(int2); + end; + move(ind[int2],ind[int2+1],(fbrecordcount-int2-1)*sizeof(pointer)); + ind[int2]:= abuffer; + if (int1 = factindex - 1) then begin + frecno:= int2; + end; + break; + end; + end; + end; + end; + end; + end; + end + else begin +// if factindex > 0 then begin +// include(fbstate1,bs1_needsresync); +// end; + end; +// end; +end; + +procedure tmsebufdataset.internalpost; +var + po1,po2: pblobinfoarty; + po3: pointer; + int1{,int2,int3}: integer; + bo1: boolean; + ar1,ar2,ar3: integerarty; + newupdatebuffer: boolean; + canapply: boolean; + +begin + checkindex(factindex); + with pdsrecordty(activebuffer)^ do begin + bo1:= false; + if state = dsinsert then begin + fcurrentbuf:= intallocrecord; + end; + newupdatebuffer:= false; + canapply:= not (bdo_noapply in foptions); + if canapply then begin + newupdatebuffer:= not getrecordupdatebuffer; + if newupdatebuffer then begin + getnewupdatebuffer; + with fupdatebuffer[fcurrentupdatebuffer] do begin + info.bookmark.recordpo:= fcurrentbuf; + info.bookmark.recno:= frecno; + if state = dsedit then begin + oldvalues:= intallocrecord; + move(info.bookmark.recordpo^,oldvalues^,frecordsize+intheadersize); + addrefvalues(oldvalues^.header); + po1:= getintblobpo; + if po1^ <> nil then begin + po2:= @oldvalues^.header.blobinfo; + pointer(po2^):= nil; + setlength(po2^,length(po1^)); + for int1:= high(po1^) downto 0 do begin //copy blobs + po2^[int1]:= po1^[int1]; + with po2^[int1] do begin + if datalength > 0 then begin + getmem(po3,datalength); + move(data^,po3^,datalength); + data:= po3; + end + else begin + data:= nil; + end; + end; + end; + end; + info.updatekind := ukmodify; + end + else begin + info.updatekind := ukinsert; + if frecno = frecordcount-1 then begin + include(info.flags,ruf_append); + end + else begin + exclude(info.flags,ruf_append); + end; + end; + end; + end; + if bs1_inupdatechanged in fbstate1 then begin + with fupdatebuffer[fcurrentupdatebuffer] do begin + include(info.flags,ruf_inupdate); + end; + end; + end; + + with header do begin + for int1:= high(blobinfo) downto 0 do begin + with blobinfo[int1] do begin + if new then begin +// deleteblob(fcurrentbuf^.header.blobinfo,field,false); + deleteblob(fcurrentbuf^.header.blobinfo,field,true); + //no reassign of blobinfo + //blobcache data needed for possible cancelupdate + new:= false; + bo1:= true; + end; + end; + end; + end; + + if (state = dsedit) then begin + saveindex(fcurrentbuf,@header,ar1,ar2,ar3); + end; + if bo1 then begin + fcurrentbuf^.header.blobinfo:= nil; //free old array + end; + finalizevalues(fcurrentbuf^.header); + move(header,fcurrentbuf^.header,frecordsize); //get new field values + + if (flogger <> nil) and canapply then begin + logrecbuffer(flogger,fupdatebuffer[fcurrentupdatebuffer].info.updatekind, + fcurrentbuf); + if newupdatebuffer then begin + logupdatebuffer(flogger,fupdatebuffer[fcurrentupdatebuffer],nil,true, + lf_update); + end; + flogger.flushbuffer; + end; + + if state = dsinsert then begin + with dsheader.bookmark do begin + frecno:= insertrecord(frecno,fcurrentbuf); + if factindexpo^.ind = nil then begin + checkindex(factindex); //for first record + end; + fcurrentbuf:= factindexpo^.ind[frecno]; + data.recordpo:= fcurrentbuf; + data.recno:= frecno; + flag := bfinserted; + end; + end + else begin + if (state = dsedit) then begin + relocateindex(fcurrentbuf,ar1,ar2,ar3); + dsheader.bookmark.data.recno:= frecno; + end; + end; + end; + fbstate:= fbstate - [bs_editing,bs_append]; +end; + +procedure tmsebufdataset.internalcancel; +var + int1: integer; + bo1: boolean; +begin + with pdsrecordty(activebuffer)^,header do begin + finalizevalues(header); + bo1:= false; + for int1:= high(blobinfo) downto 0 do begin + if blobinfo[int1].new then begin + deleteblob(blobinfo,int1,true); + bo1:= true; + end; + end; + if bo1 then begin + blobinfo:= nil; //free copy + end; + end; + fbstate:= fbstate - [bs_editing,bs_append]; +end; + +procedure tmsebufdataset.FreeFieldBuffers; +begin + //dummy +end; + +function comparefieldnum(const l,r): integer; +begin + result:= tfield(l).fieldno - tfield(r).fieldno; +end; + +procedure tmsebufdataset.calcrecordsize; + + procedure addfield(const aindex: integer; const datatype: tfieldtype; + const asize: integer; const afield: tfield); + begin + with ffieldinfos[aindex] do begin + base.offset:= frecordsize; + base.size:= getfieldsize(datatype,asize,ext.basetype); + if ext.basetype = ftvariant then begin + additem(fvarpositions,frecordsize); + end; + if ext.basetype = ftwidestring then begin + additem(fstringpositions,frecordsize); + base.dbfieldsize:= asize; //max size + end + else begin + base.dbfieldsize:= base.size; + end; + base.fieldtype:= datatype; //used for savetostream; + ext.field:= afield; + ext.uppername:= uppercase(afield.fieldname); + inc(frecordsize,base.size); + alignfieldpos(frecordsize); + end; + end; //addfield + +var + lookuprecursion: integer; + + function getbasetype(const afield: tfield): tfieldtype; + var + field1: tfield; + begin + inc(lookuprecursion); + if lookuprecursion > 16 then begin + databaseerror(name+': Recursive lookup field "'+afield.fieldname+'".'); + end; + result:= ftunknown; + if afield.dataset is tmsebufdataset then begin + if (afield.fieldkind = fklookup) and + (afield.lookupdataset <> nil) and + (afield.lookupresultfield <> '') then begin + field1:= afield.lookupdataset.findfield(afield.lookupresultfield); + if field1 <> nil then begin + result:= getbasetype(field1); + end; + end + else begin + getfieldsize(afield.datatype,0,result); + end; + end; + end; //getbasetype + +var + int1,int2,int3,int4: integer; + field1: tfield; + ar1: fieldarty; + ar2: stringarty; + bo1: boolean; +begin + fcalcfieldcount:= 0; + finternalcalcfieldcount:= 0; + for int1:= fields.count - 1 downto 0 do begin + with fields[int1] do begin + if fieldkind in dsbuffieldkinds then begin + inc(fcalcfieldcount); + end; + if fieldkind = fkinternalcalc then begin + inc(finternalcalcfieldcount); + end; + end; + end; + int1:= fielddefs.count+finternalcalcfieldcount; + frecordsize:= sizeof(blobinfoarty); + fnullmasksize:= (int1+7) div 8; + inc(frecordsize,fnullmasksize); + alignfieldpos(frecordsize); + + setlength(ffieldinfos,int1); + fstringpositions:= nil; + fvarpositions:= nil; + for int1:= 0 to fielddefs.count - 1 do begin + with fielddefs[int1] do begin + field1:= fields.findfield(name); + if (field1 <> nil) and (field1.fieldkind = fkdata) then begin + if fieldno = 0 then begin +{$warnings off} + tfield1(field1).ffieldno:= int1 + 1; //local mode without connection +{$warnings on} + end; + addfield(int1,datatype,size,field1); + end; + end; + end; + int2:= fielddefs.count; + for int1:= 0 to fields.count -1 do begin + field1:= fields[int1]; + with field1 do begin + if fieldkind = fkinternalcalc then begin + addfield(int2,datatype,size,field1); +{$warnings off} + tfield1(field1).ffieldno:= int2 + 1; +{$warnings on} + inc(int2); + end; + end; + end; + setlength(fcalcfieldbufpositions,fcalcfieldcount); + flookupfieldinfos:= nil; + setlength(flookupfieldinfos,fcalcfieldcount); + setlength(fcalcfieldsizes,fcalcfieldcount); + fcalcstringpositions:= nil; + fcalcvarpositions:= nil; + fcalcrecordsize:= frecordsize; + fcalcnullmasksize:= (fcalcfieldcount+7) div 8; + inc(fcalcrecordsize,fcalcnullmasksize); + alignfieldpos(fcalcrecordsize); + int2:= 0; + setlength(ar1,fields.count); + for int1:= fields.count - 1 downto 0 do begin + field1:= fields[int1]; + ar1[int1]:= field1; + with field1 do begin + if fieldkind in dsbuffieldkinds then begin +{$warnings off} + tfield1(field1).ffieldno:= -1 - int2; +{$warnings on} + fcalcfieldbufpositions[int2]:= fcalcrecordsize; + if field1 is tmsestringfield then begin + additem(fcalcstringpositions,fcalcrecordsize); + end; + if field1 is tmsevariantfield then begin + additem(fcalcvarpositions,fcalcrecordsize); + end; + fcalcfieldsizes[int2]:= datasize; + with flookupfieldinfos[int2] do begin + valuefield:= field1; + indexnum:= -1; + if (fieldkind = fklookup) and not lookupcache and + (lookupdataset is tmsebufdataset) then begin + if findfields(field1.keyfields,keyfieldar) and + (keyfieldar <> nil) then begin + with tmsebufdataset(lookupdataset) do begin + lookupvaluefield:= findfield(field1.lookupresultfield); + if lookupvaluefield <> nil then begin + lookupvaluefield.freenotification(self); + ar2:= splitstring(lookupkeyfields,';',true); + if high(ar2) = high(keyfieldar) then begin + for int3:= 0 to indexlocal.count - 1 do begin + with indexlocal[int3] do begin + if fields.count > high(keyfieldar) then begin + bo1:= true; + for int4:= 0 to high(keyfieldar) do begin + if not sametext(fields[int4].fieldname,ar2[int4]) then begin + bo1:= false; + break; + end; + end; + if not bo1 then begin + continue; + end + else begin + indexnum:= int3; + lookuprecursion:= 0; + basedatatype:= getbasetype(lookupvaluefield); + case basedatatype of + ftwidestring: begin + getvalue:= {$ifdef FPC}@{$endif}getbmstring; + end; + ftguid: begin + getvalue:= {$ifdef FPC}@{$endif}getbmguid; + end; + ftinteger: begin + getvalue:= {$ifdef FPC}@{$endif}getbminteger; + end; + ftboolean: begin + getvalue:= {$ifdef FPC}@{$endif}getbmboolean; + end; + ftbcd: begin + getvalue:= {$ifdef FPC}@{$endif}getbmcurrency; + end; + ftfloat: begin + getvalue:= {$ifdef FPC}@{$endif}getbmfloat; + end; + ftlargeint: begin + getvalue:= {$ifdef FPC}@{$endif}getbmlargeint; + end; + ftdatetime: begin + getvalue:= {$ifdef FPC}@{$endif}getbmdatetime; + end; + ftvariant: begin + getvalue:= {$ifdef FPC}@{$endif}getbmvariant; + end; + else begin + indexnum:= -1; + end; + end; + end; + adduniqueitem(pointerarty(flookupclients),pointer(self)); + adduniqueitem(pointerarty(self.flookupmasters), + pointer(lookupdataset)); + break; + end + end; + end; + end; + end; + end; + end; + if indexnum < 0 then begin + databaseerror(self.name+', '+name+': no loookup index for KeyFields "'+ + keyfields+'" LookupKeyFields "'+lookupkeyfields+'".'); + end; + end; + end; + inc(fcalcrecordsize,fcalcfieldsizes[int2]); + alignfieldpos(fcalcrecordsize); + inc(int2); + end; + end; + end; + mergesortarray(ar1,sizeof(ar1[0]),length(ar1),@comparefieldnum, + ffieldorder,false); + //MS SQL ODBC needs ordered load field +end; + +function tmsebufdataset.getrecordsize : word; +begin + result:= frecordsize; +end; + +function tmsebufdataset.getchangecount: integer; +begin + result:= length(fupdatebuffer); +end; + +function tmsebufdataset.getapplyerrorcount: integer; +var + int1: integer; +begin + result:= 0; + for int1:= 0 to high(fupdatebuffer) do begin + if ruf_error in fupdatebuffer[int1].info.flags then begin + inc(result); + end; + end; +end; + +procedure tmsebufdataset.setrecno1(value: longint; const nocheck: boolean); +var + bm: bufbookmarkty; +begin + checkbrowsemode; + if value > recordcount then begin + repeat + until (getnextpacket(bs_fetchall in fbstate) < fpacketrecords) or + (value <= recordcount) or (bs_fetchall in fbstate); + end; + if nocheck then begin + if value > fbrecordcount then begin + value:= fbrecordcount; + end; + if value < 1 then begin + exit; + end; + end; + checkrecno(value); + bm.data.recordpo:= nil; + bm.data.recno:= value-1; + if nocheck then begin + try + gotobookmark(@bm); + except //catch exception by filter + resync([]); //record not found + end; + end + else begin + gotobookmark(@bm); + end; +end; + +procedure tmsebufdataset.setrecno(value: longint); +begin + setrecno1(value,false); +end; + +procedure tmsebufdataset.setrecnozerobased(const avalue: int32); +begin + setrecno1(avalue + 1,false); +end; + +procedure tmsebufdataset.setoptions(const avalue: bufdatasetoptionsty); +begin + if avalue <> foptions then begin + if bdo_restoreupdateonsavepointrollback in avalue then begin + include(fbstate1,bs1_restoreupdate); + end + else begin + if (bs1_restoreupdate in fbstate1) and active and + not (csloading in componentstate) then begin + postrecupdatebuffer; + end; + exclude(fbstate1,bs1_restoreupdate); + end; + foptions:= bufdatasetoptionsty(setsinglebit(card32(avalue),card32(foptions), + [card32([bdo_autocommitret,bdo_autocommit]), + card32([bdo_editonapplyerror,bdo_cancelupdatesonerror, + bdo_cancelupdateonerror,bdo_cancelupdateondeleteerror])])); + end; +end; + +function tmsebufdataset.getdefaultoptions: bufdatasetoptionsty; +begin + result:= defaultbufdatasetoptions; +end; + +function tmsebufdataset.getrecno: longint; +begin + result:= getrecnozerobased + 1; +end; + +function tmsebufdataset.getrecnozerobased: int32; +begin + if bs_internalcalc in fbstate then begin + result:= frecno; + end + else begin + result:= -1; + if activebuffer <> nil then begin + with pdsrecordty(activebuffer)^.dsheader.bookmark do begin + if state = dsinsert then begin + if (bs_append in fbstate) or (fbrecordcount = 0) then begin + result:= fbrecordcount; + end + else begin + result:= data.recno; + end; + end + else begin + if fbrecordcount > 0 then begin + result:= data.recno; + end; + end; + end; + end; + end; +end; + +function tmsebufdataset.iscursoropen: boolean; +begin + result:= fopen; +end; + +function tmsebufdataset.getrecordcount: longint; +begin + result:= fbrecordcount; +end; + +function tmsebufdataset.updatestatus(out aflags: recupdateflagsty): tupdatestatus; +begin + aflags:= []; + result:= usunmodified; + if getrecordupdatebuffer then begin + with fupdatebuffer[fcurrentupdatebuffer] do begin + aflags:= info.flags; + case info.updatekind of + ukmodify : result := usmodified; + ukinsert : result := usinserted; + ukdelete : result := usdeleted; + end; + end; + end; +end; + +function tmsebufdataset.updatestatus: tupdatestatus; +var + stat1: recupdateflagsty; +begin + result:= updatestatus(stat1); +end; + +{ +Function tmsebufdataset.Locate(const KeyFields: string; const KeyValues: Variant; options: TLocateOptions) : boolean; + + + function CompareText0(substr, astr: pchar; len : integer; options: TLocateOptions): integer; + + var + i : integer; Chr1, Chr2: byte; + begin + result := 0; + i := 0; + chr1 := 1; + while (result=0) and (i 0) do + begin + Chr1 := byte(substr[i]); + Chr2 := byte(astr[i]); + inc(i); + if loCaseInsensitive in options then + begin + if Chr1 in [97..122] then + dec(Chr1,32); + if Chr2 in [97..122] then + dec(Chr2,32); + end; + result := Chr1 - Chr2; + end; + if (result <> 0) and (chr1 = 0) and (loPartialKey in options) then result := 0; + end; + + +var keyfield : TField; // Field to search in + ValueBuffer : pchar; // Pointer to value to search for, in TField' internal format + VBLength : integer; + + FieldBufPos : PtrInt; // Amount to add to the record buffer to get the FieldBuffer + CurrLinkItem: Pbufreclinkitem1; + CurrBuff : pchar; + bm : TBufBookmarkty; + + CheckNull : Boolean; + SaveState : TDataSetState; + +begin +// For now it is only possible to search in one field at the same time + result := False; + + if IsEmpty then exit; + + keyfield := FieldByName(keyfields); + CheckNull := VarIsNull(KeyValues); + + if not CheckNull then + begin + SaveState := State; + SetTempState(dsFilter); + keyfield.Value := KeyValues; + RestoreState(SaveState); + + FieldBufPos := FFieldBufPositions[keyfield.FieldNo-1]; + VBLength := keyfield.DataSize; + ValueBuffer := AllocMem(VBLength); + currbuff := pointer(FLastRecBuf)+sizeof(Tbufreclinkitem1)+FieldBufPos; + move(currbuff^,ValueBuffer^,VBLength); + end; + + CurrLinkItem := FFirstRecBuf; + + if CheckNull then + begin + repeat + currbuff := pointer(CurrLinkItem)+sizeof(Tbufreclinkitem1); + if GetFieldIsnull(pbyte(CurrBuff),keyfield.Fieldno-1) then + begin + result := True; + break; + end; + CurrLinkItem := CurrLinkItem^.next; + if CurrLinkItem = FLastRecBuf then getnextpacket; + until CurrLinkItem = FLastRecBuf; + end + else if keyfield.DataType = ftString then + begin + repeat + currbuff := pointer(CurrLinkItem)+sizeof(Tbufreclinkitem1); + if not GetFieldIsnull(pbyte(CurrBuff),keyfield.Fieldno-1) then + begin + inc(CurrBuff,FieldBufPos); + if CompareText0(ValueBuffer,CurrBuff,VBLength,options) = 0 then + begin + result := True; + break; + end; + end; + CurrLinkItem := CurrLinkItem^.next; + if CurrLinkItem = FLastRecBuf then getnextpacket; + until CurrLinkItem = FLastRecBuf; + end + else + begin + repeat + currbuff := pointer(CurrLinkItem)+sizeof(Tbufreclinkitem1); + if not GetFieldIsnull(pbyte(CurrBuff),keyfield.Fieldno-1) then + begin + inc(CurrBuff,FieldBufPos); + if CompareByte(ValueBuffer^,CurrBuff^,VBLength) = 0 then + begin + result := True; + break; + end; + end; + + CurrLinkItem := CurrLinkItem^.next; + if CurrLinkItem = FLastRecBuf then getnextpacket; + until CurrLinkItem = FLastRecBuf; + end; + + + if Result then + begin + bm.BookmarkData := CurrLinkItem; + bm.BookmarkFlag := bfCurrent; + GotoBookmark(@bm); + end; + + ReAllocmem(ValueBuffer,0); +end; +} +function tmsebufdataset.getblobrecpo: precheaderty; +begin + if state = dsoldvalue then begin + if getrecordupdatebuffer then begin + result:= pointer(fupdatebuffer[fcurrentupdatebuffer].oldvalues); + if result <> nil then begin + result:= @pintrecordty(result)^.header; + end; + end + else begin + result:= @fcurrentbuf^.header //there is no old value available + end; + end + else begin + if state = dscurvalue then begin + result:= @fcurrentbuf^.header; + end + else begin + if bs_recapplying in fbstate then begin + result:= @fnewvaluebuffer^.header; + end + else begin + result:= @pdsrecordty(activebuffer)^.header; + end; + end; + end; +end; + +function tmsebufdataset.createblobstream(field: tfield; + mode: tblobstreammode): tstream; +var + int1: integer; + buffer: pointer; +begin + if (mode <> bmread) and not ((state in dseditmodes) or + (bs_recapplying in fbstate)) then begin + databaseerrorfmt(snotediting,[name],self); + end; + result:= nil; + if mode = bmread then begin + buffer:= getblobrecpo; + with precheaderty(buffer)^ do begin + for int1:= high(blobinfo) downto 0 do begin + if blobinfo[int1].field = field then begin + result:= tblobcopy.create(blobinfo[int1]); + break; + end; + end; + end; + end + else begin + if (mode = bmwrite) and (field.fieldno-1 >= 0) and // data field + (of_inupdate in field.optionsfield) then begin + include(fbstate1,bs1_inupdatechanged); + end; + end; +end; + +function tmsebufdataset.getfieldblobid(const field: tfield; + out aid: blobidty): boolean; +var + po1: precheaderty; + po2: pointer; + int1: integer; +begin + result:= getfieldbuffer(field,po2,int1); + if result then begin + po1:= getblobrecpo; + with po1^ do begin + for int1:= high(blobinfo) downto 0 do begin + if blobinfo[int1].field = field then begin + aid.local:= true; + aid.id:= ptrint(blobinfo[int1].data); + result:= aid.id <> 0; + exit; + end; + end; + aid.local:= false; + aid.id:= 0; + move(po2^,aid.id,getblobdatasize); + end; + end; +end; + +procedure tmsebufdataset.fetchallblobs; +begin + fetchall; + fetchblobs; +end; + +function tmsebufdataset.blobsarefetched: boolean; +begin + result:= (bs_blobsfetched in fbstate) or (bdo_cacheblobs in foptions); +end; + +function tmsebufdataset.getblobcache: blobcacheinfoarty; +begin + result:= fblobcache; +end; + +function tmsebufdataset.findcachedblob(var info: blobcacheinfoty): boolean; +var + int1: integer; +begin + if bs_blobscached in fbstate then begin + info:= fblobcache[integer(info.id)]; + result:= true; + end + else begin + if not (bs_blobssorted in fbstate) then begin + sortblobcache; + end; + result:= findarrayvalue(info,fblobcache,sizeof(blobcacheinfoty), + fblobcount,@compblobcache,int1); + if result then begin + info.data:= fblobcache[int1].data; + end + else begin + info.data:= ''; + end; + end +end; + +procedure tmsebufdataset.sortblobcache; +begin + setlength(fblobcache,fblobcount); + sortarray(fblobcache,sizeof(blobcacheinfoty),@compblobcache); + include(fbstate,bs_blobssorted); +end; + +procedure tmsebufdataset.resetblobcache; +begin + fblobcache:= nil; + fblobcount:= 0; + ffreedblobs:= nil; + ffreedblobcount:= 0; + fbstate:= fbstate - [bs_blobssorted,bs_blobsfetched]; +end; + +procedure tmsebufdataset.fetchblobs; +var + datapobefore: pintrecordty; + statebefore: tdatasetstate; + int1,int2,int3: integer; + ind1: pointerarty; + fieldar1: fieldarty; + ar1: integerarty; + stream1: tmemorystream; +// id: int64; +begin + if not blobscached and not (bs_blobsfetched in fbstate) then begin + setlength(fieldar1,fields.count); + int2:= 0; + for int1:= 0 to high(fieldar1) do begin + fieldar1[int2]:= fields[int1]; + if fieldar1[int2].isblob then begin + inc(int2); + end; + end; + if int2 > 0 then begin + setlength(fieldar1,int2); + setlength(ar1,int2); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= fieldar1[int1].fieldno-1; + end; + datapobefore:= fcurrentbuf; + ind1:= findexes[0].ind; + statebefore:= settempstate(dscurvalue); + resetblobcache; + try + for int1:= 0 to recordcount - 1 do begin + fcurrentbuf:= ind1[int1]; + for int2:= 0 to high(fieldar1) do begin + if getfieldflag(@fcurrentbuf^.header.fielddata.nullmask, + ar1[int2]) then begin + stream1:= tmemorystream(createblobstream(fieldar1[int2],bmread)); + int3:= addblobcache(stream1.memory,stream1.size); + fieldar1[int2].getdata(@fblobcache[int3].id); + stream1.free; + end; + end; + end; + finally + fcurrentbuf:= datapobefore; + restorestate(statebefore); + end; + end; + end + else begin + setlength(fblobcache,fblobcount); + end; + include(fbstate,bs_blobsfetched); +end; + +function tmsebufdataset.findcachedblob(const id: int64; + out info: blobcacheinfoty): boolean; +begin + info.id:= id; + result:= findcachedblob(info); +end; + +procedure tmsebufdataset.getofflineblob(const data: precheaderty; + const aindex: integer; out ainfo: blobstreaminfoty); +var + cacheinfo: blobcacheinfoty; + int1: integer; +begin + with ffieldinfos[aindex],base,ext do begin + cacheinfo.id:= 0; //field size can be 32 bit + move((pchar(data)+offset)^,cacheinfo.id,size); + with data^ do begin + for int1:= high(blobinfo) downto 0 do begin + if blobinfo[int1].field = field then begin + with blobinfo[int1] do begin + ainfo.info.id:= cacheinfo.id; + ainfo.info.new:= new; + ainfo.info.current:= true; + setlength(ainfo.data,datalength); + move(data^,pointer(ainfo.data)^,datalength); + //todo: no move + end; + exit; + end; + end; + end; + findcachedblob(cacheinfo); + {$warnings off} + with ainfo,info do begin + id:= cacheinfo.id; + new:= false; + current:= false; + data:= cacheinfo.data; + end; + end; +end; + {$warnings on} + +procedure tmsebufdataset.setofflineblob(const adata: precheaderty; + const aindex: integer; const ainfo: blobstreaminfoty); +begin + with ainfo,info do begin + with ffieldinfos[aindex],base,ext do begin + move(id,(pchar(adata)+offset)^,size); + if current then begin + with adata^ do begin + setlength(blobinfo,high(blobinfo) + 2); + with blobinfo[high(blobinfo)] do begin + field:= ffieldinfos[aindex].ext.field; + new:= info.new; //?? + datalength:= length(ainfo.data); + getmem(data,datalength); //todo: no move + move(pointer(ainfo.data)^,data^,datalength); + end; + end; + end + else begin + addblobcache(id,data); + end; + end; + end; +end; + +procedure tmsebufdataset.setdatastringvalue(const afield: tfield; + const avalue: string); +var + po1: pbyte; + int1: integer; +begin + if bs_recapplying in fbstate then begin +// po1:= pbyte(@fupdatebuffer[fcurrentupdatebuffer].bookmark.recordpo^.header); + po1:= @fnewvaluebuffer^.header; + include(fbstate,bs_curvaluemodified); + end + else begin + po1:= pbyte(@fcurrentbuf^.header); + end; + int1:= afield.fieldno - 1; + if avalue <> '' then begin + move(avalue[1],(pchar(po1)+ffieldinfos[int1].base.offset)^, + length(avalue)); + setfieldflag(@precheaderty(po1)^.fielddata.nullmask,int1); + end + else begin + clearfieldflag(@precheaderty(po1)^.fielddata.nullmask,int1); + end; +end; + +procedure tmsebufdataset.checkindexsize; +var + int1,int2: integer; +begin + if high(factindexpo^.ind) <= fbrecordcount then begin + int2:= (fbrecordcount+16)*2; + setlength(findexes[0].ind,int2); + if bs_hasvalidindex in fbstate then begin + for int1:= 1 to high(findexes) do begin + if (findexes[int1].ind <> nil) or (int1 = factindex) then begin + //init for first insert/append + setlength(findexes[int1].ind,int2); + end; + end; + end; + end; +end; + +function tmsebufdataset.insertindexrefs(const arecord: pintrecordty): integer; +var + int1,int2: integer; +begin + result:= frecno; + if bs_hasvalidindex in fbstate then begin + for int1:= 1 to high(findexes) do begin + if findexes[int1].ind <> nil then begin + with findexlocal[int1-1] do begin + int2:= findboundary(@compare1,arecord,high(findexfieldinfos),true); + end; + with findexes[int1] do begin + if int2 < fbrecordcount then begin + move(ind[int2],ind[int2+1],(fbrecordcount-int2)*sizeof(pointer)); + end; + ind[int2]:= arecord; + if int1 = factindex then begin + result:= int2; + end; + end; + end; + end; + end; +end; + +procedure tmsebufdataset.removeindexrefs(const arecord: pintrecordty); +var + int1,int2: integer; +begin + if bs_hasvalidindex in fbstate then begin + for int1:= 1 to high(findexes) do begin + if findexes[int1].ind <> nil then begin + if int1 <> factindex then begin + int2:= findexlocal[int1-1].findrecord(arecord); + if int2 < 0 then begin + databaseerror('Internal error: Indexed record not found.'); + end; + with findexes[int1] do begin + move(ind[int2+1],ind[int2],(fbrecordcount-int2-1)*sizeof(pointer)); + end; + end; + end; + end; + end; +end; + +function tmsebufdataset.appendrecord(const arecord: pintrecordty): integer; +begin + checkindexsize; + findexes[0].ind[fbrecordcount]:= arecord; + result:= insertindexrefs(arecord); + if factindex = 0 then begin + result:= fbrecordcount; + end; + inc(fbrecordcount); +end; + +function tmsebufdataset.insertrecord(arecno: integer; + const arecord: pintrecordty): integer; +begin + if arecno < 0 then begin + arecno:= 0; + end; + checkindexsize; + result:= insertindexrefs(arecord); + if factindex <> 0 then begin + findexes[0].ind[fbrecordcount]:= arecord; //append + end + else begin + result:= arecno; + move(findexes[0].ind[arecno],findexes[0].ind[arecno+1], + (fbrecordcount-arecno)*sizeof(pointer)); + findexes[0].ind[arecno]:= arecord; + end; + if (frecno > arecno) then begin + inc(frecno); + end; +// fcurrentbuf:= arecord; + fcurrentbuf:= factindexpo^.ind[frecno]; + inc(fbrecordcount); +end; + +function tmsebufdataset.remove0indexref(const arecord: pintrecordty): integer; +var + po1: pintrecordty; + po2: ppointer; + int1: integer; +begin + result:= -1; + dec(fbrecordcount); + po1:= arecord; + with findexes[0] do begin + po2:= pointer(pchar(pointer(ind)) + fbrecordcount*sizeof(pointer)); + for int1:= fbrecordcount downto 0 do begin + if po2^ = po1 then begin + result:= int1; + break; + end; + dec(po2); + end; + if result >= 0 then begin + move(ind[result+1],ind[result],(fbrecordcount-result)*sizeof(pointer)); + end; + end; +end; + +procedure tmsebufdataset.deleterecord(const arecord: pintrecordty); +var + int1: integer; +begin + if bs_hasvalidindex in fbstate then begin + int1:= factindex; + factindex:= 0; + removeindexrefs(arecord); + factindex:= int1; + end; + remove0indexref(arecord); +end; + +procedure tmsebufdataset.deleterecord(const arecno: integer); +var + po1: pintrecordty; +// int1: integer; +begin + po1:= factindexpo^.ind[arecno]; + if bs_hasvalidindex in fbstate then begin + removeindexrefs(po1); + if factindex <> 0 then begin + move(factindexpo^.ind[arecno+1],factindexpo^.ind[arecno], + (fbrecordcount-arecno-1)*sizeof(pointer)); + end; + end; + if factindex = 0 then begin + dec(fbrecordcount); + with findexes[0] do begin + move(ind[arecno+1],ind[arecno],(fbrecordcount-arecno)*sizeof(pointer)); + end; + end + else begin + remove0indexref(po1); + end; + if (frecno > arecno) or (frecno >= fbrecordcount) then begin + dec(frecno); + end; + if frecno < 0 then begin + fcurrentbuf:= nil; + end + else begin + fcurrentbuf:= factindexpo^.ind[frecno]; + end; +end; + +procedure tmsebufdataset.checkindex(const aid: integer); +var + int2: integer; +begin + if aid > 0 then begin + int2:= length(findexes[0].ind); + if int2 > 0 then begin + with findexes[aid] do begin + if ind = nil then begin + allocuninitedarray(int2,sizeof(pointer),ind); + if fbrecordcount > 0 then begin + move(findexes[0].ind[0],ind[0],fbrecordcount*sizeof(pointer)); + findexlocal.items[aid-1].sort(ind); + end; + end; + end; + end; + include(fbstate,bs_hasvalidindex); + end; +end; + +procedure tmsebufdataset.internalsetrecno(const avalue: integer); +begin + frecno:= avalue; + if (avalue < 0) or (avalue >= fbrecordcount) then begin + fcurrentbuf:= nil; + end + else begin + checkindex(factindex); + fcurrentbuf:= factindexpo^.ind[avalue]; + end; +// tdatasetcracker(self).fbof:= frecno = 0; +end; + +procedure tmsebufdataset.clearindex; +begin + findexes:= nil; + factindexpo:= nil; + exclude(fbstate,bs_hasvalidindex); +end; + +procedure tmsebufdataset.setindexlocal(const avalue: tlocalindexes); +begin + findexlocal.assign(avalue); +end; + +procedure tmsebufdataset.updatestate; +begin + if (fpacketrecords < 0) {or assigned(foninternalcalcfields)} then begin + include(fbstate,bs_fetchall); + end + else begin + exclude(fbstate,bs_fetchall); + end; + if findexlocal.count > 0 then begin + fbstate:= fbstate + [bs_hasindex,bs_fetchall]; + end + else begin + exclude(fbstate,bs_hasindex); + end; +end; + +procedure tmsebufdataset.setactindex(const avalue: integer); +//var +// int1: integer; +begin + if factindex <> avalue then begin + if active then begin + checkbrowsemode; + factindex:= avalue; + factindexpo:= @findexes[avalue]; + internalsetrecno(findrecord(fcurrentbuf)); + resync([]); + findexlocal.doindexchanged; + end + else begin + factindex:= avalue; + factindexpo:= @findexes[avalue]; + end; + end; +end; + +procedure tmsebufdataset.resetindex; +var + int1: integer; +begin + actindex:= 0; + for int1:= 1 to high(findexes) do begin + findexes[int1].ind:= nil; + end; + exclude(fbstate,bs_hasvalidindex); +end; + +function tmsebufdataset.GetFieldClass(FieldType: TFieldType): TFieldClass; +begin + result:= getmsefieldclass(fieldtype); +end; + +procedure tmsebufdataset.fieldtoparam(const source: tfield; const dest: tparam); +var +// int1: integer; + mstr1: msestring; +begin + if source is tmsestringfield then begin + with tmsestringfield(source) do begin + if source.isnull then begin + dest.clear; + if fixedchar then begin + dest.datatype:= ftfixedchar; + end + else begin + dest.datatype:= ftstring; + end; + end + else begin + mstr1:= asmsestring; + if (characterlength <> 0) and (length(mstr1) > characterlength) then begin + setlength(mstr1,characterlength); + end; + dest.aswidestring:= mstr1; + if fixedchar then begin + dest.datatype:= ftfixedwidechar; + end; + end; + end; + end + else begin + dest.assignfieldvalue(source,source.value); + end; +end; + +procedure tmsebufdataset.oldfieldtoparam(const source: tfield; + const dest: tparam); +var + bo1:boolean; + mstr1: msestring; +begin + if source is tmsestringfield then begin + mstr1:= tmsestringfield(source).oldmsestring(bo1); + if bo1 then begin + dest.clear; + if tmsestringfield(source).fixedchar then begin + dest.datatype:= ftfixedchar; + end + else begin + dest.datatype:= ftstring; + end; + end + else begin + { + if bs_utf8 in fbstate then begin + dest.asstring:= stringtoutf8ansi(mstr1); + end + else begin + dest.asstring:= mstr1; + end; + } + dest.aswidestring:= mstr1; + if tmsestringfield(source).fixedchar then begin + dest.datatype:= ftfixedwidechar; + end; + end; + end + else begin + dest.assignfieldvalue(source,source.oldvalue); + end; +end; + +procedure tmsebufdataset.stringtoparam(const source: msestring; + const dest: tparam); +begin + if bs_utf8 in fbstate then begin + dest.asstring:= stringtoutf8ansi(source); + end + else begin + dest.asstring:= ansistring(source); + end; +end; + +procedure tmsebufdataset.bindfields(const bind: boolean); +var + int1: integer; + field1: tfield; + int2: integer; + fielddef1: tfielddef; +begin + fielddef1:= nil; + for int1:= fields.count - 1 downto 0 do begin + field1:= fields[int1]; + if bind then begin + if field1.fieldkind = fkdata then begin + fielddef1:= tfielddef(fielddefs.find(field1.fieldname)); + //needed for FPC 2_2 + if fielddef1 <> nil then begin + field1.fieldname:= fielddef1.name; + //get exact name for quoting in update statements + end; + end + else begin + fielddef1:= nil; + end; + end; + if field1 is tmsestringfield then begin + int2:= 0; + if bind then begin + int2:= field1.size; + if fielddef1 <> nil then begin + int2:= fielddef1.size; + end; + tmsestringfield1(field1).setismsestring({$ifdef FPC}@{$endif}getmsestringdata, + {$ifdef FPC}@{$endif}setmsestringdata,int2,(fielddef1 <> nil) and + (fielddef1.datatype in widestringfields)); + end + else begin + tmsestringfield1(field1).setismsestring(nil,nil,int2,false); + end; + end + else begin + if field1 is tmseblobfield then begin + if bind then begin + tmseblobfield1(field1).fgetblobid:= {$ifdef FPC}@{$endif}getfieldblobid; + end + else begin + tmseblobfield1(field1).fgetblobid:= nil; + end; + end + else begin + if field1 is tmsevariantfield then begin + if bind then begin + tmsevariantfield1(field1).fsetvardata:= {$ifdef FPC}@{$endif}setvardata; + tmsevariantfield1(field1).fgetvardata:= {$ifdef FPC}@{$endif}getvardata; + end + else begin + tmsevariantfield1(field1).fsetvardata:= nil; + tmsevariantfield1(field1).fgetvardata:= nil; + end; + end; + end; + end; + end; + inherited bindfields(bind); +end; + +function tmsebufdataset.findfields(const anames: string): fieldarty; +var + ar1: stringarty; + int1: integer; +begin + ar1:= splitstring(anames,';',true); + setlength(result,length(ar1)); + for int1:= 0 to high(result) do begin + result[int1]:= findfield(ar1[int1]); + end; +end; + +function tmsebufdataset.findfields(const anames: string; out afields: fieldarty): boolean; + //true if all found +var + ar1: stringarty; + int1: integer; +begin + ar1:= splitstring(anames,';',true); + setlength(afields,length(ar1)); + result:= true; + for int1:= 0 to high(afields) do begin + afields[int1]:= findfield(ar1[int1]); + if afields[int1] = nil then begin + result:= false; + end; + end; +end; +{ +function tmsebufdataset.refreshing: boolean; +begin + result:= bs_refreshing in fbstate; +end; +} +function tmsebufdataset.isutf8: boolean; +begin + result:= false; //default +end; + +procedure tmsebufdataset.append; +begin + include(fbstate,bs_append); + inherited; +end; + +procedure tmsebufdataset.setoninternalcalcfields( + const avalue: internalcalcfieldseventty); +begin + foninternalcalcfields:= avalue; + updatestate; +end; + +procedure tmsebufdataset.lookupdschanged(const sender: tmsebufdataset); +var + int1,int2: integer; + bo1: boolean; + bm1: bookmarkdataty; +begin + if active and not (csdestroying in componentstate) then begin + int2:= fnotifylookupclientcount; + bo1:= false; + bm1:= bookmarkdata; + for int1:= 0 to high(flookupfieldinfos) do begin + with flookupfieldinfos[int1] do begin + if hasindex and (lookupvaluefield.dataset = sender) then begin + findexlocal.fieldmodified(valuefield,false); + bo1:= true; + end; + end; + end; + if (state in [dsbrowse]) or (state in [dsedit,dsinsert]) and + (bdo_checkbrowsemodebylookupchange in foptions) then begin + //stop recursion triggered by dscalcfields + if bo1 then begin + if state = dsinsert then begin + checkbrowsemode; + end + else begin + if bm1.recordpo <> nil then begin + bookmarkdata:= bm1; + end; + end; + end + else begin + checkbrowsemode; + resync([]); + end; + if int2 = fnotifylookupclientcount then begin + //already called by post otherwise + notifylookupclients; + end; + end; + end; +end; + +procedure tmsebufdataset.notifylookupclients; +var + int1: integer; +begin + if not (bs1_lookupnotifying in fbstate1) then begin + if (fdisablecontrolscount > 0) or (flookupupdate > 0) then begin + include(fbstate1,bs1_lookupnotifypending); + end + else begin + inc(fnotifylookupclientcount); + include(fbstate1,bs1_lookupnotifying); + try + for int1:= 0 to high(flookupclients) do begin + flookupclients[int1].lookupdschanged(self); + end; + exclude(fbstate1,bs1_lookupnotifypending); + finally + exclude(fbstate1,bs1_lookupnotifying); + end; + end; + end; +end; + +procedure tmsebufdataset.beginlookupupdate(); +begin + inc(flookupupdate); +end; + +procedure tmsebufdataset.endlookupupdate(); +begin + dec(flookupupdate); + if (flookupupdate = 0) and (bs1_lookupnotifypending in fbstate1) then begin + notifylookupclients(); + end; +end; + + +procedure tmsebufdataset.enablecontrols(); +begin + inherited; + if (bs1_lookupnotifypending in fbstate1) and (fdisablecontrolscount = 0) and + (flookupupdate = 0) then begin + notifylookupclients(); + end; +end; + +procedure tmsebufdataset.dointernalcalcfields(const fetching: boolean); +begin + if checkcanevent(self,tmethod(foninternalcalcfields)) then begin + foninternalcalcfields(self,fetching); + end; +end; + +procedure tmsebufdataset.dataevent(event: tdataevent; info: ptrint); +var + int1: integer; + field1: tfield; +begin + if (event = decheckbrowsemode) and (state = dsfilter) then begin + databaseerror('Database is in dsFilter state.',self); + end; + if event in [deupdaterecord,dedatasetchange] then begin + exclude(fbstate,bs_visiblerecordcountvalid); + end; + if (event = deupdatestate) and (state = dsbrowse) then begin + updatecursorpos; //update fcurrentbuf after open + end; + if (bs_startedit in fbstate) and (event = derecordchange) and (info = 0) then begin + exclude(fbstate,bs_startedit); + for int1:= 0 to fields.count - 1 do begin + field1:= fields[int1]; + if field1.fieldkind = fkcalculated then begin + dataevent(defieldchange,ptrint(field1)); + end; + exit; + end; + end; + if not ((bs_recapplying in fbstate) and (event = dedatasetchange)) then begin + inherited; + end; + case ord(event) of + ord(deupdaterecord): begin + dointernalcalcfields(false); + end; + de_modified: begin + notifylookupclients(); + end; + end; +end; + +procedure tmsebufdataset.updaterecord(); +var + bo1: boolean; +begin + bo1:= bs1_recordupdating in fbstate1; + include(fbstate1,bs1_recordupdating); + try + inherited; + finally + if not bo1 then begin + exclude(fbstate1,bs1_recordupdating); + end; + end; +end; + +function tmsebufdataset.bookmarkdatatobookmark( + const abookmark: bookmarkdataty): bookmarkty; +begin + if abookmark.recordpo = nil then begin + result:= ''; + end + else begin + setlength(result,sizeof(abookmark)); + move(abookmark,pointer(result)^,sizeof(abookmark)); + end; +end; + +function tmsebufdataset.bookmarktobookmarkdata( + const abookmark: bookmarkty): bookmarkdataty; +begin + if abookmark = '' then begin + result.recordpo:= nil; + result.recno:= -1; + end + else begin + move(pointer(abookmark)^,result,sizeof(result)); + end; +end; + +procedure tmsebufdataset.checkrecno(const avalue: integer); +begin + if (avalue > recordcount) or (avalue < 1) then begin + databaseerror(snosuchrecord,self); + end; +end; + +procedure tmsebufdataset.setonfilterrecord(const value: tfilterrecordevent); +begin + inherited; + if not (csdesigning in componentstate) then begin + checkfilterstate; + filterchanged; + end; +end; + +procedure tmsebufdataset.setfiltered(value: boolean); +begin + inherited; + filterchanged; +end; + +procedure tmsebufdataset.setactive(value: boolean); +var + bo1: boolean; +begin + bo1:= active; + inherited; + if bo1 <> active then begin + notifycontrols; + notifylookupclients; + end; +end; + +procedure tmsebufdataset.filterchanged1(const aloaded: boolean); +begin + if not aloaded then begin + exclude(fbstate,bs_visiblerecordcountvalid); + end; + if checkcanevent(self,tmethod(fbeforefilterchanged)) then begin + fbeforefilterchanged(self); + end; + if not aloaded then begin + if not (state in [dsinactive,dsfilter]) then begin + checkbrowsemode; + resync([]); + end; + end; + if checkcanevent(self,tmethod(fafterfilterchanged)) then begin + fafterfilterchanged(self); + end; +end; + +procedure tmsebufdataset.filterchanged(); +begin + filterchanged1(false); +end; + +function tmsebufdataset.locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; +begin + result:= locaterecord(self,afields,akeys,aisnull,akeyoptions,aoptions); +end; +{ +function tmsebufdataset.locate(const key: integer; const field: tfield; + const options: locateoptionsty = []): locateresultty; +begin + result:= locaterecord(self,key,field,options); +end; + +function tmsebufdataset.locate(const key: msestring; const field: tfield; + const options: locateoptionsty = []): locateresultty; +begin + result:= locaterecord(self,isutf8,key,field,options); +end; +} +function tmsebufdataset.locaterecno(const arecno: integer): boolean; + //moves to next valid recno, //returns true if resulting recno = arecno +var + int1: integer; +begin + result:= false; + int1:= arecno-1; + if int1 <> frecno then begin + if int1 < 0 then begin + int1:= 0; + end; + if int1 >= recordcount then begin + int1:= fbrecordcount - 1; + end; + if int1 >= 0 then begin + internalsetrecno(int1); + resync([]); + result:= int1 = frecno; + end; + end + else begin + result:= true; + end; +end; + +procedure tmsebufdataset.beginfilteredit(const akind: filtereditkindty); +begin + if state <> dsfilter then begin + ffiltereditkind:= akind; + checkbrowsemode; + if checkcanevent(self,tmethod(fbeforebeginfilteredit)) then begin + fbeforebeginfilteredit(self,akind); + end; + fbuffercountbefore:= buffercount; + setbuflistsize(1); + setstate(dsfilter); + dataevent(dedatasetchange,0); + if checkcanevent(self,tmethod(fafterbeginfilteredit)) then begin + fafterbeginfilteredit(self,akind); + end; + end; +end; + +procedure tmsebufdataset.endfilteredit; +begin + if state = dsfilter then begin + dataevent(deupdaterecord, 0); + if checkcanevent(self,tmethod(fbeforeendfilteredit)) then begin + fbeforeendfilteredit(self,ffiltereditkind); + end; + setbuflistsize(fbuffercountbefore); + setstate(dsbrowse); + resync([]); + if checkcanevent(self,tmethod(fafterendfilteredit)) then begin + fafterendfilteredit(self,ffiltereditkind); + end; + filterchanged1(true); + end; +end; + +function tmsebufdataset.beginfiltervalue( + const akind: filtereditkindty): tdatasetstate; +begin + result:= settempstate(dsfilter); + ffiltereditkind:= akind; +end; + +procedure tmsebufdataset.endfiltervalue(const astatebefore: tdatasetstate); +begin + restorestate(astatebefore); +end; + +function tmsebufdataset.fieldfiltervalue(const afield: tfield; + const akind: filtereditkindty = fek_filter): variant; +var + statebefore: tdatasetstate; + kindbefore: filtereditkindty; +begin + statebefore:= settempstate(dsfilter); + kindbefore:= ffiltereditkind; + ffiltereditkind:= akind; + result:= afield.asvariant; + ffiltereditkind:= kindbefore; + restorestate(statebefore); +end; + +function tmsebufdataset.fieldfiltervalueisnull(const afield: tfield; + const akind: filtereditkindty = fek_filter): boolean; +var + statebefore: tdatasetstate; + kindbefore: filtereditkindty; +begin + statebefore:= settempstate(dsfilter); + kindbefore:= ffiltereditkind; + ffiltereditkind:= akind; + result:= afield.isnull; + ffiltereditkind:= kindbefore; + restorestate(statebefore); +end; + +function tmsebufdataset.checkfiltervalue(const afield: tfield; + const akind: filtereditkindty = fek_filter; + const acaseinsensitive: boolean = true): boolean; +var + i1: int32; + p1: precheaderty; + v1: variant; + b1: boolean; +begin + if afield.dataset <> self then begin + databaseerror('Invalid field "'+afield.name+'"',self); + end; + result:= true; //default + i1:= afield.fieldno-1; + p1:= @ffilterbuffer[akind]^.header; + if i1 >= 0 then begin //data field + b1:= not getfieldflag(p1^.fielddata.nullmask,i1); + end + else begin //calc field + i1:= -2 - i1; + if i1 >= 0 then begin //calc field + b1:= not getfieldflag(pointer(p1)+frecordsize,i1); + end + else begin + exit;//invalid field + end; + end; + if not b1 then begin //filter not null + b1:= afield.isnull; + v1:= fieldfiltervalue(afield,akind); + if afield.datatype = ftstring then begin + if acaseinsensitive then begin + i1:= unicodecomparetext(afield.asmsestring,unicodestring(v1)); + end + else begin + i1:= unicodecomparestr(afield.asmsestring,unicodestring(v1)); + end; + case akind of + fek_filtermin: begin + result:= not b1 and (i1 >= 0); + end; + fek_filter: begin + result:= i1 = 0; + end; + fek_filtermax: begin + result:= b1 or (i1 <= 0); + end; + end; + end + else begin + case akind of + fek_filtermin: begin + result:= not b1 and (afield.value >= v1); + end; + fek_filter: begin + result:= afield.value = v1; + end; + fek_filtermax: begin + result:= b1 or (afield.value <= v1); + end; + end; + end; + end; +end; + +function tmsebufdataset.checkfiltervalues(const afield: tfield; + const acaseinsensitive: boolean = true): boolean; + //calls checkfiltervalue() for all filtereditkinds +var + f1: filtereditkindty; +begin + for f1:= low(f1) to fek_filtermax do begin + result:= checkfiltervalue(afield,f1,acaseinsensitive); + if not result then begin + break; + end; + end; +end; + +function tmsebufdataset.checkfiltervalues( + const acaseinsensitive: boolean = true): boolean; + //calls checkfiltervalue() for all fields and all filtereditkinds +var + i1: int32; +begin + result:= true; + for i1:= 0 to fields.count-1 do begin + result:= checkfiltervalues(fields[i1],acaseinsensitive); + if not result then begin + break; + end; + end; +end; + +procedure tmsebufdataset.checkfilterstate; +begin + exclude(fbstate,bs_hasfilter); + if checkcanevent(self,tmethod(onfilterrecord)) then begin + include(fbstate,bs_hasfilter); + end +end; + +procedure tmsebufdataset.loaded; +begin + inherited; + checkfilterstate; + filterchanged1(true); +end; + +procedure tmsebufdataset.readstreamingversion(reader: treader); +begin + reader.readinteger(); + card32(foldopts):= $ffffffff; //none +end; + +procedure tmsebufdataset.writestreamingversion(writer: twriter); +begin + writer.writeinteger(1); +end; + +procedure tmsebufdataset.setdelayedapplycount(const avalue: integer); +begin + if fdelayedapplycount <> avalue then begin + if active and not (csloading in componentstate) then begin + if fdelayedapplycount > 0 then begin + fdelayedapplycount:= 1; + doidleapplyupdates; //apply pending updates. + end; + fdelayedapplycount:= avalue; + if avalue > 0 then begin + registeronidle; + end + else begin + unregisteronidle; + end; + end + else begin + fdelayedapplycount:= avalue; + end; + end; +end; + +procedure tmsebufdataset.registeronidle; +begin + if not(bs1_onidleregistered in fbstate1) then begin + application.registeronidle({$ifdef FPC}@{$endif}doonidle); + include(fbstate1,bs1_onidleregistered); + end; +end; + +procedure tmsebufdataset.unregisteronidle; +begin + if bs1_onidleregistered in fbstate1 then begin + application.unregisteronidle({$ifdef FPC}@{$endif}doonidle); + exclude(fbstate1,bs1_onidleregistered); + end; +end; + +procedure tmsebufdataset.doidleapplyupdates(); +begin + //dummy +end; + +procedure tmsebufdataset.doonidle(var again: boolean); +begin + doidleapplyupdates(); +end; + +procedure tmsebufdataset.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('streamingversion',@readstreamingversion, + @writestreamingversion,true); +end; + +procedure tmsebufdataset.readstate(reader: treader); +begin + inherited; + if card32(foldopts) <> $ffffffff then begin + options:= (options - + (bufdatasetoptionsty(not(card32(foldopts)))*oldbdsoptions) + ) + (foldopts * oldbdsoptions) + end; +end; + +procedure tmsebufdataset.dofilterrecord(var acceptable: boolean); +begin + if checkcanevent(self,tmethod(onfilterrecord)) then begin + onfilterrecord(self,acceptable); + end; +end; + +function tmsebufdataset.recordisnull(): boolean; //all fields null +var + int1: integer; +begin + checkactive(); + result:= true; + for int1:= 0 to fields.count - 1 do begin + if not fields[int1].isnull then begin + result:= false; + break; + end; + end; +end; + +procedure tmsebufdataset.clearrecord(); +var + int1: integer; +begin + checkactive; + try + disablecontrols; + for int1:= 0 to fields.count - 1 do begin + with fields[int1] do begin + if state = dsfilter then begin + if not isblob then begin + clear; + end; + end + else begin + if not readonly then begin + clear; + end; + end; + end; + end; + finally + enablecontrols; + end; +end; + +procedure tmsebufdataset.clearfilter; +var + int1: integer; + statebefore: tdatasetstate; + kindbefore,kind1,firstki,lastki: filtereditkindty; +begin + checkactive; + try + disablecontrols; + statebefore:= settempstate(dsfilter); + kindbefore:= filtereditkind; + if statebefore = dsfilter then begin + firstki:= filtereditkind; + lastki:= firstki; + end + else begin + firstki:= low(filtereditkindty); + lastki:= high(filtereditkindty); + end; + for kind1:= firstki to lastki do begin + filtereditkind:= kind1; + for int1:= 0 to fields.count - 1 do begin + with fields[int1] do begin + if not isblob then begin + clear; + end; + end; + end; + end; + if (statebefore <> dsfilter) then begin + for kind1:= low(filtereditkindty) to high(filtereditkindty) do begin + if checkcanevent(self,tmethod(fbeforeendfilteredit)) then begin + fbeforeendfilteredit(self,kind1); + end; + end; + resync([]); + filterchanged1(true); + end; + finally + filtereditkind:= kindbefore; + restorestate(statebefore); + enablecontrols; + end; +end; + +procedure tmsebufdataset.fetchall; +begin + getnextpacket(true); +end; + +procedure tmsebufdataset.checksumfield(const afield: tfield; + const fieldtypes: fieldtypesty); +begin + checkbrowsemode; + if (afield.fieldno <= 0) or (afield.dataset <> self) or + not (ffieldinfos[afield.fieldno-1].base.fieldtype in + fieldtypes) then begin + raise edatabaseerror.create('Invalid sum field '+'"'+afield.fieldname+'".'); + end; +end; + +procedure tmsebufdataset.sumfield(const afield: tfield; out asum: double); +var + int1,int2: integer; + index1: integer; + po1: precheaderty; + po2: pprecheaderty; + bo1,bo2: boolean; + state1: tdatasetstate; +begin + checksumfield(afield,[ftfloat,ftcurrency]); + index1:= afield.fieldno - 1; + asum:= 0; + bo1:= filtered and assigned(onfilterrecord); + state1:= settempstate(tdatasetstate(dscheckfilter)); + try + int2:= ffieldinfos[index1].base.offset; + po2:= pointer(findexes[0]); + if bo1 then begin + for int1:= 0 to fbrecordcount - 1 do begin + fcheckfilterbuffer:= pdsrecordty(pchar(ppointeraty(po2)^[int1])- + sizeof(dsheaderty)); + bo2:= true; + onfilterrecord(self,bo2); + if bo2 and getfieldflag(@fcheckfilterbuffer^.header.fielddata.nullmask, + index1) then begin + asum:= asum + pdouble(pchar(@fcheckfilterbuffer^.header)+int2)^; + end; + end; + end + else begin + for int1:= 0 to fbrecordcount - 1 do begin + po1:= ppointeraty(po2)^[int1]; + if getfieldflag(@po1^.fielddata.nullmask,index1) then begin + asum:= asum + pdouble(pchar(po1)+int2)^; + end; + end; + end; + finally + restorestate(state1); + end; +end; + +procedure tmsebufdataset.sumfield(const afield: tfield; out asum: currency); +var + int1,int2: integer; + index1: integer; + po1: precheaderty; + po2: pprecheaderty; + bo1,bo2: boolean; + state1: tdatasetstate; +begin + checksumfield(afield,[ftbcd,ftfloat]); + index1:= afield.fieldno - 1; + asum:= 0; + bo1:= filtered and assigned(onfilterrecord); + state1:= settempstate(tdatasetstate(dscheckfilter)); + try + int2:= ffieldinfos[index1].base.offset; + po2:= pointer(findexes[0]); + case ffieldinfos[afield.fieldno-1].base.fieldtype of + ftbcd: begin + if bo1 then begin + for int1:= 0 to fbrecordcount - 1 do begin + fcheckfilterbuffer:= pdsrecordty(pchar(ppointeraty(po2)[int1])- + sizeof(dsheaderty)); + bo2:= true; + onfilterrecord(self,bo2); + if bo2 and getfieldflag( + @fcheckfilterbuffer^.header.fielddata.nullmask,index1) then begin + asum:= asum + pcurrency(pchar(@fcheckfilterbuffer^.header)+int2)^; + end; + end; + end + else begin + for int1:= 0 to fbrecordcount - 1 do begin + po1:= ppointeraty(po2)^[int1]; + if getfieldflag(@po1^.fielddata.nullmask,index1) then begin + asum:= asum + pcurrency(pchar(po1)+int2)^; + end; + end; + end; + end; + ftfloat: begin + if bo1 then begin + for int1:= 0 to fbrecordcount - 1 do begin + fcheckfilterbuffer:= pdsrecordty( + pchar(ppointeraty(po2)^[int1])-sizeof(dsheaderty)); + bo2:= true; + onfilterrecord(self,bo2); + if bo2 and getfieldflag( + @fcheckfilterbuffer^.header.fielddata.nullmask,index1) then begin + asum:= asum + pdouble(pchar(@fcheckfilterbuffer^.header)+int2)^; + end; + end; + end + else begin + for int1:= 0 to fbrecordcount - 1 do begin + po1:= ppointeraty(po2)^[int1]; + if getfieldflag(@po1^.fielddata.nullmask,index1) then begin + asum:= asum + pdouble(pchar(po1)+int2)^; + end; + end; + end; + end; + end; + finally + restorestate(state1); + end; +end; + +procedure tmsebufdataset.sumfield(const afield: tfield; out asum: int64); +var + int1,int2: integer; + index1: integer; + po1: precheaderty; + po2: pprecheaderty; + bo1,bo2: boolean; + state1: tdatasetstate; +begin + checksumfield(afield,[ftlargeint,ftinteger,ftsmallint,ftword]); + index1:= afield.fieldno - 1; + asum:= 0; + bo1:= filtered and assigned(onfilterrecord); + state1:= settempstate(tdatasetstate(dscheckfilter)); + try + int2:= ffieldinfos[index1].base.offset; + po2:= pointer(findexes[0]); + case ffieldinfos[afield.fieldno-1].base.fieldtype of + ftlargeint: begin + if bo1 then begin + for int1:= 0 to fbrecordcount - 1 do begin + fcheckfilterbuffer:= pdsrecordty(pchar(ppointeraty(po2)^[int1])- + sizeof(dsheaderty)); + bo2:= true; + onfilterrecord(self,bo2); + if bo2 and getfieldflag( + @fcheckfilterbuffer^.header.fielddata.nullmask,index1) then begin + asum:= asum + pint64(pchar(@fcheckfilterbuffer^.header)+int2)^; + end; + end; + end + else begin + for int1:= 0 to fbrecordcount - 1 do begin + po1:= ppointeraty(po2)^[int1]; + if getfieldflag(@po1^.fielddata.nullmask,index1) then begin + asum:= asum + pint64(pchar(po1)+int2)^; + end; + end; + end; + end; + ftinteger,ftsmallint,ftword: begin + if bo1 then begin + for int1:= 0 to fbrecordcount - 1 do begin + fcheckfilterbuffer:= pdsrecordty(pchar(ppointeraty(po2)^[int1])- + sizeof(dsheaderty)); + bo2:= true; + onfilterrecord(self,bo2); + if bo2 and getfieldflag( + @fcheckfilterbuffer^.header.fielddata.nullmask,index1) then begin + asum:= asum + pinteger(pchar(@fcheckfilterbuffer^.header)+int2)^; + end; + end; + end + else begin + for int1:= 0 to fbrecordcount - 1 do begin + po1:= ppointeraty(po2)^[int1]; + if getfieldflag(@po1^.fielddata.nullmask,index1) then begin + asum:= asum + pinteger(pchar(po1)+int2)^; + end; + end; + end; + end; + end; + finally + restorestate(state1); + end; +end; + +procedure tmsebufdataset.sumfield(const afield: tfield; out asum: integer); +var + int1,int2: integer; + index1: integer; + po1: precheaderty; + po2: pprecheaderty; + bo1,bo2: boolean; + state1: tdatasetstate; +begin + checksumfield(afield,[ftinteger,ftsmallint,ftword,ftboolean]); + index1:= afield.fieldno - 1; + asum:= 0; + bo1:= filtered and assigned(onfilterrecord); + state1:= settempstate(tdatasetstate(dscheckfilter)); + try + int2:= ffieldinfos[index1].base.offset; + po2:= pointer(findexes[0]); + case ffieldinfos[afield.fieldno-1].base.fieldtype of + ftinteger,ftsmallint,ftword: begin + if bo1 then begin + for int1:= 0 to fbrecordcount - 1 do begin + fcheckfilterbuffer:= pdsrecordty(pchar(ppointeraty(po2)^[int1])- + sizeof(dsheaderty)); + bo2:= true; + onfilterrecord(self,bo2); + if bo2 and getfieldflag( + @fcheckfilterbuffer^.header.fielddata.nullmask,index1) then begin + asum:= asum + pinteger(pchar(@fcheckfilterbuffer^.header)+int2)^; + end; + end; + end + else begin + for int1:= 0 to fbrecordcount - 1 do begin + po1:= ppointeraty(po2)^[int1]; + if getfieldflag(@po1^.fielddata.nullmask,index1) then begin + asum:= asum + pinteger(pchar(po1)+int2)^; + end; + end; + end; + end; + ftboolean: begin + if bo1 then begin + for int1:= 0 to fbrecordcount - 1 do begin + fcheckfilterbuffer:= pdsrecordty(pchar(ppointeraty(po2)^[int1])- + sizeof(dsheaderty)); + bo2:= true; + onfilterrecord(self,bo2); + if bo2 and getfieldflag( + @fcheckfilterbuffer^.header.fielddata.nullmask,index1) and + pwordbool(pchar(@fcheckfilterbuffer^.header)+int2)^ then begin + inc(asum); + end; + end; + end + else begin + for int1:= 0 to fbrecordcount - 1 do begin + po1:= ppointeraty(po2)^[int1]; + if getfieldflag(@po1^.fielddata.nullmask,index1) and + pwordbool(pchar(po1)+int2)^ then begin + inc(asum); + end; + end; + end; + end; + end; + finally + restorestate(state1); + end; +end; + +function tmsebufdataset.sumfielddouble(const afield: tfield): double; +begin + sumfield(afield,result); +end; + +function tmsebufdataset.sumfieldcurrency(const afield: tfield): currency; +begin + sumfield(afield,result); +end; + +function tmsebufdataset.sumfieldinteger(const afield: tfield): integer; +begin + sumfield(afield,result); +end; + +function tmsebufdataset.sumfieldint64(const afield: tfield): int64; +begin + sumfield(afield,result); +end; + +function tmsebufdataset.countvisiblerecords: integer; +var + int1{,int2}: integer; +// getresult: tgetresult; +begin + if not (state in [dsinactive,dsfilter]) then begin + checkbrowsemode; + if not (bs_visiblerecordcountvalid in fbstate) then begin + if not filtered then begin + fetchall; + fvisiblerecordcount:= fbrecordcount; + end + else begin + int1:= frecno; + disablecontrols; + getnextpacket(true); + try + fvisiblerecordcount:= 0; + internalsetrecno(0); + if (getrecord(activebuffer,gmcurrent,false) = grok) or + (getrecord(activebuffer,gmnext,false) = grok) then begin + repeat + inc(fvisiblerecordcount); + until getrecord(activebuffer,gmnext,false) <> grok; + end; + finally + internalsetrecno(int1); + getrecord(activebuffer,gmcurrent,false); + enablecontrols; + end; + end; + include(fbstate,bs_visiblerecordcountvalid); + end; + result:= fvisiblerecordcount; + end + else begin + result:= 0; + end; +end; + +const + bufdattag: bufdattagty = 'MSEBUFDAT'#0#0#0#0#0#0; + +// data format: +// +// header: bdsfheaderty +// fielddefs +// currentvalues: recbufferheader,pointer,nullmask,fielddata +// updatebuffer +// updatebufferitem: updatebufferheader,old nullmask,fielddata if not insert +// post log +// endmarker + +procedure tmsebufdataset.logupdatebuffer(const awriter: tbufstreamwriter; + const abuffer: recupdatebufferty; + const adeletedrecord: pintrecordty; + const alogging: boolean; const alogmode: logflagty); +var + header1: logbufferheaderty; + datapo: precheaderty; + int2: integer; +begin + header1.logflag:= alogmode; + with abuffer,header1.update do begin + if (info.bookmark.recordpo <> nil) or (deletedrecord <> 0{nil}) then begin + deletedrecord:= ptruint(adeletedrecord); + logging:= alogging; + if (ruf_inupdate in info.flags) and (info.updatekind = ukmodify) then begin + kind:= uk_modifyinupdate; + end + else begin + kind:= updatekindty(info.updatekind); + end; + po:= ptruint(info.bookmark.recordpo); + awriter.writelogbufferheader(header1); + if (alogmode = lf_update) and + ((kind in [uk_modify,uk_modifyinupdate]) or + not logging and (kind = uk_delete) and (po <> 0{nil})) then begin + datapo:= @(oldvalues^.header); + awriter.write(datapo^.fielddata,fnullmasksize); + for int2:= 0 to high(ffieldinfos) do begin + awriter.writefielddata(datapo,int2); + end; + end; + end; + end; +end; + +procedure tmsebufdataset.logrecbuffer(const awriter: tbufstreamwriter; + const akind: tupdatekind; const abuffer: pintrecordty); +var + datapo: precheaderty; + header1: logbufferheaderty; + int1: integer; +begin + header1.logflag:= lf_rec; + with header1.rec do begin + kind:= akind; + po:= ptruint(abuffer); + end; + awriter.writelogbufferheader(header1); + if akind in [ukmodify,ukinsert] then begin + datapo:= @(abuffer^.header); + awriter.write(datapo^.fielddata,fnullmasksize); + for int1:= 0 to high(ffieldinfos) do begin + awriter.writefielddata(datapo,int1); + end; + end; +end; + +procedure tmsebufdataset.savestate(const awriter: tbufstreamwriter); +var + header: tbsfheaderty; +// writer: tbufstreamwriter; + fieldco: integer; + int1{,int2}: integer; +begin + fieldco:= length(ffieldinfos); + with header do begin + tag:= bufdattag; + byteorder:= 0; + {$ifdef cpu64} + byteorder:= byteorder + 2; + {$endif} + version:= 2; + fieldcount:= fieldco; + fielddefcount:= fielddefs.count; + recordcount:= self.recordcount; + end; + if header.fieldcount > 0 then begin + awriter.write(header,sizeof(header)); + for int1:= 0 to header.fielddefcount - 1 do begin + awriter.writefielddef(fielddefs[int1]); + end; + for int1:= 0 to high(ffieldinfos) do begin + awriter.write(ffieldinfos[int1],sizeof(fieldinfobasety)); + end; + with findexes[0] do begin + for int1:= 0 to recordcount - 1 do begin + logrecbuffer(awriter,ukinsert,pintrecordty(ind[int1])); + end; + end; + for int1:= 0 to high(fupdatebuffer) do begin + with fupdatebuffer[int1] do begin + if info.bookmark.recordpo <> nil then begin + { + if updatekind = ukinsert then begin + logrecbuffer(awriter,updatekind, + bookmark.recordpo); + end; + } + logupdatebuffer(awriter,fupdatebuffer[int1],nil,false,lf_update); + end; + end; + end; + end; +end; + +procedure tmsebufdataset.savetostream(const astream: tstream); +var + writer: tbufstreamwriter; +begin + checkbrowsemode; + fetchallblobs; + writer:= tbufstreamwriter.create(self,astream); + try + savestate(writer); + writer.writeendmarker; + finally + writer.free; + end; +end; + +procedure tmsebufdataset.doloadfromstream; + + procedure formaterror; + begin + databaseerror('Invalid data stream.',self); + end; + +var + header: tbsfheaderty; + reader: tbufstreamreader; + fieldco: integer; + ar2: card64arty;//pointerarty; + ar3: integerarty; + appended: card64arty; //pointerarty; + po1: pointer; + + function findrec(const oldpo: card64{pointer}; out newpo: pointer; + out aindex: integer; + const delete: boolean = false): boolean; + //returns new pointer + var + int1: integer; + begin + result:= findarrayitem(oldpo,ar2,sizeof(card64),@comparecard64,int1); +// result:= findarrayitem(oldpo,ar2,sizeof(pointer),@comparepointer,int1); + if result then begin + aindex:= ar3[int1]; + newpo:= findexes[0].ind[aindex]; + if delete then begin + dec(header.recordcount); + dec(fbrecordcount); + deleteitem(findexes[0].ind,aindex); + deleteitem(ar3,int1); + deleteitem(ar2,int1); + end; + end + else begin + for int1:= 0 to high(appended) do begin + if appended[int1] = oldpo then begin + aindex:= header.recordcount+int1; + newpo:= findexes[0].ind[aindex]; + result:= true; + if delete then begin +// appended[int1]:= nil; + deleteitem(appended,int1); + deleteitem(findexes[0].ind,aindex); + dec(fbrecordcount); + end; + break; + end; + end; + end; + end; + +var + actindexbefore: integer; + oldupdatepointers: card64arty; //pointerarty; +// bo1: boolean; + int1,int2,int3: integer; + header1: logbufferheaderty; + updabuf: recupdatebufferarty; + p2: pfieldinfobasety; + +begin + initsavepoint; + updabuf:= nil; //compilerwarning + actindexbefore:= factindex; + factindex:= 0; + factindexpo:= @findexes[0]; + fbstate:= fbstate - [bs_blobscached]; + resetindex(); +// exclude(fbstate,bs_blobscached); + reader:= tbufstreamreader.create(self,floadingstream); + try + reader.readbuffer(header,sizeof(header)); + if (header.tag <> bufdattag) or (header.fielddefcount > 1000) then begin + formaterror; + end; + try + fielddefs.beginupdate; + try + fielddefs.clear; + for int1:= 0 to header.fielddefcount - 1 do begin + reader.readfielddef(fielddefs); + end; + finally + fielddefs.endupdate; + end; + dointernalopen; + fieldco:= length(ffieldinfos); + if (header.fieldcount <> fieldco) then begin + formaterror; + end; + if fieldco > 0 then begin + if header.version = 0 then begin + int1:= sizeof(fieldinfo_0ty); + end + else begin + int1:= sizeof(fieldinfobasety); + end; + getmem(p2,int1*fieldco); + po1:= p2; + try + reader.readbuffer(p2^,int1*fieldco); + for int2:= 0 to fieldco-1 do begin + with ffieldinfos[int2].base do begin + if (p2^.fieldtype <> fieldtype) or + (p2^.dbfieldsize <> dbfieldsize) then begin + formaterror(); + end; + {$ifdef cpu64} + if (header.version < 2) or + ((p2^.offset < offset) or (p2^.size < size)) then begin + reader.f32to64:= true; + end; + {$endif} + inc(p2); + end; +{ + if not comparemem(pchar(po1)+int1*int2,@ffieldinfos[int2], + sizeof(fieldinfobasety)) then begin + formaterror; + end; +} + end; + {$ifndef cpu64} + if header.version < 2 then begin + reader.f32to64:= true; + end; + {$endif} + finally + freemem(po1); + end; + setlength(ar2,header.recordcount); + {$ifdef mse_debuglogger} + debugwriteln('**log read '+inttostr(header.recordcount)+' records'); + {$endif} + for int1:= 0 to high(ar2) do begin + if not reader.readlogbufferheader(header1) or + (header1.logflag <> lf_rec) then begin + formaterror; + end; + {$ifdef mse_debuglogger} + debugwriteln(' '+inttostr(int1)+' '+hextostr(femptybuffer)); + {$endif} + ar2[int1]:= header1.rec.po; + reader.readrecord(femptybuffer); + appendrecord(femptybuffer); + femptybuffer:= intallocrecord; + end; +// ar1:= nil; + if header.recordcount > 0 then begin +// allocuninitedarray(fbrecordcount,sizeof(pointer),ar1); +// move(pointer(findexes[0])^,pointer(ar1)^,fbrecordcount*sizeof(pointer)); + sortarray(ar2,sizeof(card64),@comparecard64,ar3); + //index of old pointers + end + else begin + ar3:= nil; + end; + int2:= 0; + while reader.readlogbufferheader(header1) do begin + {$ifdef mse_debuglogger} + debugwrite(inttostr(int2)); + {$endif} + case header1.logflag of + lf_rec: begin + with header1.rec do begin + if not findrec(po,po1,int1) then begin + if kind <> ukinsert then begin + formaterror; + end; + {$ifdef mse_debuglogger} + debugwrite(' new '+hextostr(femptybuffer)); + {$endif} + reader.readrecord(femptybuffer); + appendrecord(femptybuffer); + femptybuffer:= intallocrecord; + additem(appended,po); + end + else begin + {$ifdef mse_debuglogger} + debugwrite(' found '+hextostr(po1)); + {$endif} + reader.readrecord(po1); + end; + end; + end; + lf_update: begin + if high(updabuf) < int2 then begin + setlength(updabuf,2*high(updabuf)+258); + setlength(oldupdatepointers,length(updabuf)); + end; + with updabuf[int2],header1.update do begin + if kind = uk_modifyinupdate then begin + info.updatekind:= ukmodify; + include(info.flags,ruf_inupdate); + end + else begin + info.updatekind:= tupdatekind(kind); + exclude(info.flags,ruf_inupdate); + end; + oldupdatepointers[int2]:= po; + int3:= -1; + if deletedrecord <> 0{nil} then begin + for int1:= 0 to int2 - 1 do begin + if oldupdatepointers[int1] = deletedrecord then begin + int3:= int1; + break; + end; + end; + end; + {$ifdef mse_debuglogger} + debugwrite(' '+inttostr(int3)+' '+getenumname(typeinfo(kind),ord(kind))); + {$endif} + if kind = uk_delete then begin + if logging and (po <> deletedrecord) then begin + if (int3 < 0) or not findrec(deletedrecord,po1,int1,true) then begin + formaterror; + end; + if po = 0{nil} then begin + {$ifdef mse_debuglogger} + debugwrite(' inserted '+hextostr(po1)); + {$endif} + info.bookmark.recordpo:= nil; //deleting of inserted record + intfreerecord(pintrecordty(po1)); + end + else begin //deleting of modified record + {$ifdef mse_debuglogger} + debugwrite(' modified '+ + hextostr(updabuf[int3].info.bookmark.recordpo)+ + ' old '+hextostr(updabuf[int3].oldvalues)); + {$endif} + intfreerecord(updabuf[int3].info.bookmark.recordpo); + info.bookmark.recordpo:= updabuf[int3].oldvalues; + info.bookmark.recno:= 0; + end; + updabuf[int3].info.bookmark.recordpo:= nil; //to be removed + end + else begin + if logging then begin + if not findrec(deletedrecord,pointer(info.bookmark.recordpo), + info.bookmark.recno,true) then begin + formaterror; + end; + {$ifdef mse_debuglogger} + debugwrite(' found '+hextostr(info.bookmark.recordpo)); + {$endif} + end + else begin + info.bookmark.recno:= 0; + info.bookmark.recordpo:= intallocrecord; + reader.readrecord(info.bookmark.recordpo); + {$ifdef mse_debuglogger} + debugwrite(' new '+hextostr(info.bookmark.recordpo)); + {$endif} + end; + end; + oldvalues:= info.bookmark.recordpo; + end + else begin + if not findrec(po,pointer(info.bookmark.recordpo), + info.bookmark.recno) then begin + formaterror; //old pointer not found + end; + {$ifdef mse_debuglogger} + debugwrite(' found '+hextostr(info.bookmark.recordpo)); + {$endif} + end; + if kind in [uk_modify,uk_modifyinupdate] then begin + oldvalues:= intallocrecord; + reader.readrecord(oldvalues); + {$ifdef mse_debuglogger} + debugwrite(' new oldvalues '+hextostr(oldvalues)); + {$endif} + end; + end; + inc(int2); + end; + lf_cancel: begin + with header1.update do begin + int3:= -1; + for int1:= 0 to int2 - 1 do begin + if oldupdatepointers[int1] = po then begin + int3:= int1; + break; + end; + end; + if int3 < 0 then begin + formaterror; + end; + case kind of + uk_modify,uk_modifyinupdate: begin + cancelrecupdate(updabuf[int3]); + end; + uk_delete: begin + with updabuf[int3] do begin + appendrecord(info.bookmark.recordpo); + additem(appended,oldupdatepointers[int3]); +// additem(appended,bookmark.recordpo); + end; + end; + uk_insert: begin + if not findrec(oldupdatepointers[int3],po1,int1,true) then begin + formaterror; + end; + with updabuf[int3] do begin + intfreerecord(info.bookmark.recordpo); + end; + end; + end; + updabuf[int3].info.bookmark.recordpo:= nil; + oldupdatepointers[int3]:= 0{nil}; + //inactive + end; + end; + lf_apply,lf_drop: begin + with header1.update do begin + int3:= -1; + for int1:= 0 to int2-1 do begin + if oldupdatepointers[int1] = po then begin + int3:= int1; + break; + end; + end; + if int3 < 0 then begin + formaterror; + end; + with updabuf[int3] do begin + intfreerecord(oldvalues); + info.bookmark.recordpo:= nil; + oldupdatepointers[int3]:= 0{nil}; + //inactive + end; + end; + end; + else begin + formaterror; + end; + end; + {$ifdef mse_debuglogger} + debugwriteln(''); + {$endif} + end; + setlength(updabuf,int2); + setlength(fupdatebuffer,int2); + int2:= 0; //pack updatebuffer + for int1:= 0 to high(updabuf) do begin + if updabuf[int1].info.bookmark.recordpo <> nil then begin + fupdatebuffer[int2]:= updabuf[int1]; + inc(int2); + end; + end; + setlength(fupdatebuffer,int2); + fallpacketsfetched:= true; + end; + include(fbstate,bs_blobsfetched); + sortblobcache; + except + dointernalclose; + raise; + end; + finally + reader.free; + factindex:= actindexbefore; + factindexpo:= @findexes[factindex]; + if active then begin + checkindex(factindex); + end; + end; +end; + +procedure tmsebufdataset.loadfromstream(const astream: tstream); +begin + checkinactive; + floadingstream:= astream; + include(fbstate,bs_loading); + try + active:= true; + finally + exclude(fbstate,bs_loading); + floadingstream:= nil; + end; +end; + +function tmsebufdataset.streamloading: boolean; +begin + result:= bs_loading in fbstate; +end; + +function tmsebufdataset.addblobcache(const adata: pointer; + const alength: integer): integer; +begin + if ffreedblobcount > 0 then begin + dec(ffreedblobcount); + result:= ffreedblobs[ffreedblobcount]; + if (ffreedblobcount = 0) and (high(ffreedblobs) > 10000) then begin + ffreedblobs:= nil; + end; + end + else begin + result:= fblobcount; + inc(fblobcount); + if result > high(fblobcache) then begin + setlength(fblobcache,2*result+256); + end; + end; + with fblobcache[result] do begin + id:= result; + setlength(data,alength); + {$ifdef FPC} {$checkpointer off} {$endif} //adata can be foreign memory + move(adata^,pointer(data)^,alength); + {$ifdef FPC} {$checkpointer default} {$endif} + end; + exclude(fbstate,bs_blobssorted); +end; + +function tmsebufdataset.addblobcache(const aid: int64; + const adata: string): integer; +begin + result:= fblobcount; + inc(fblobcount); + if result > high(fblobcache) then begin + setlength(fblobcache,2*result+256); + end; + with fblobcache[result] do begin + id:= aid; + data:= adata; + end; + exclude(fbstate,bs_blobssorted); +end; +{ +function tmsebufdataset.wantblobfetch: boolean; +begin + result:= false; +end; +} +{ +function tmsebufdataset.getdsoptions: datasetoptionsty; +begin + result:= []; +end; +} +procedure tmsebufdataset.checkconnected; +begin + if not (bs_connected in fbstate) then begin + databaseerror('Not connected.',self); + end; +end; + +procedure tmsebufdataset.savetofile(afilename: filenamety = ''; + const acryptohandler: tcustomcryptohandler = nil); +var + stream1: tmsefilestream; +begin + if afilename = '' then begin + checklogfile(); + afilename:= flogfilename; + end; + stream1:= tmsefilestream.createtransaction(afilename); + try + stream1.cryptohandler:= acryptohandler; + savetostream(stream1); + finally + stream1.free; + end; +end; + +procedure tmsebufdataset.loadfromfile(afilename: filenamety = ''; + const acryptohandler: tcustomcryptohandler = nil); +var + stream1: tmsefilestream; +begin + if afilename = '' then begin + checklogfile(); + afilename:= flogfilename; + end; + stream1:= tmsefilestream.create(afilename,fm_read); + try + stream1.cryptohandler:= acryptohandler; + loadfromstream(stream1); + finally + stream1.free; + end; +end; + +procedure tmsebufdataset.checklogfile; +begin + if trim(flogfilename) = '' then begin + databaseerror('No log file name.',self); + end; +end; + +procedure tmsebufdataset.recover; +begin + checklogfile; +// if islocal then begin +// active:= true; +// end +// else begin + loadfromfile(flogfilename,fcryptohandler); + startlogger; +// end; +end; + +procedure tmsebufdataset.startlogger; +var + stream1: tmsefilestream; +begin + if flogfilename <> '' then begin + if bdo_noapply in foptions then begin + databaseerror('Options bdo_noapply must not be set for logging.',self); + end; + stream1:= tmsefilestream.create(flogfilename,fm_create); + stream1.cryptohandler:= fcryptohandler; + flogger:= tbufstreamwriter.create(self,stream1); + {$ifdef mse_debuglogger} + debugwriteln('*****startlogger'); + {$endif} + savestate(flogger); + {$ifdef mse_debuglogger} + debugwriteln('-----startlogger'); + {$endif} + flogger.flushbuffer; + end; +end; + +procedure tmsebufdataset.closelogger; +var + stream1: tstream; +begin + if flogger <> nil then begin + flogger.writeendmarker; + stream1:= flogger.fstream; + freeandnil(flogger); + stream1.free; + {$ifdef mse_debuglogger} + debugwriteln('*****endlogger'); + {$endif} + end; +end; + +procedure tmsebufdataset.startlogging; + //close logfile, save state with truncated log, open logfile +begin + checklogfile; + checkbrowsemode; + closelogger; + startlogger; +end; + +procedure tmsebufdataset.stoplogging; + //close logfile +begin + closelogger; +end; + +function tmsebufdataset.getlogging: boolean; +begin + result:= flogger <> nil; +end; + +function tmsebufdataset.islocal: boolean; +begin + result:= false; +end; + +procedure tmsebufdataset.dobeforeapplyupdate; +begin + if checkcanevent(self,tmethod(fbeforeapplyupdate)) then begin + fbeforeapplyupdate(self); + end; +end; + +procedure tmsebufdataset.doafterapplyupdate; +begin + if checkcanevent(self,tmethod(fafterapplyupdate)) then begin + fafterapplyupdate(self); + end; +end; + +procedure tmsebufdataset.notifycontrols; +var + int1: integer; +begin + int1:= 0; + try + while controlsdisabled do begin + inc(int1); + enablecontrols; + end; + finally + while int1 > 0 do begin + dec(int1); + disablecontrols; + end; + end; +end; + +procedure tmsebufdataset.OpenCursor(InfoQuery: Boolean); +begin + inherited; +// tdatasetcracker(self).fbof:= true; +end; + +function tmsebufdataset.GetNextRecord: Boolean; +begin + result:= inherited getnextrecord; +// if frecno = 0 then begin +// tdatasetcracker(self).fbof:= true; +// end; +end; + +function tmsebufdataset.GetNextRecords: Longint; +begin + result:= inherited getnextrecords; +// if frecno = 0 then begin +// tdatasetcracker(self).fbof:= true; +// end; +end; + +function tmsebufdataset.getfiltereditkind: filtereditkindty; +begin + result:= ffiltereditkind; +end; + +function tmsebufdataset.getrestorerecno: boolean; +begin + result:= bs_restorerecno in fbstate; +end; + +procedure tmsebufdataset.setrestorerecno(const avalue: boolean); +begin + if avalue then begin + include(fbstate,bs_restorerecno); + end + else begin + exclude(fbstate,bs_restorerecno); + end; +end; + +function tmsebufdataset.islastrecord: boolean; +begin + result:= eof; + if not result then begin + fetchall; + result:= recno = recordcount; + end; +end; + +procedure tmsebufdataset.currentbeginupdate; +begin + currentcheckbrowsemode; + inc(fcurrentupdating); +end; +{ +procedure tmsebufdataset.currentdecupdate; +begin + dec(fcurrentupdating); + if fcurrentupdating = 0 then begin + exclude(fbstate,bs_curvalueset); + end; +end; +} +procedure tmsebufdataset.fixupcurrentset; +begin + if not (bs_recapplying in fbstate) and (fdisablecontrolscount <= 0) then begin + if factindexpo^.ind = nil then begin + bookmark:= bookmark; //possibly invalid recno + end + else begin + resync([]); + end; + end + else begin + include(fbstate1,bs1_needsresync); + end; +end; + +procedure tmsebufdataset.currentendupdate; +begin + dec(fcurrentupdating); + if fcurrentupdating = 0 then begin + if bs_curvalueset in fbstate then begin + exclude(fbstate,bs_curvalueset); + findexlocal.preparefixup; + fixupcurrentset; + end; + end; +end; + +procedure tmsebufdataset.currentcheckbrowsemode; +begin + if (state <> dsbrowse) and (fcurrentupdating = 0) and + ([bs1_recordupdating,bs1_posting] * fbstate1 = []) then begin + checkbrowsemode; + end; +end; + +function tmsebufdataset.getcurrentpo(const afield: tfield; + const afieldtype: tfieldtype; const arecord: pintrecordty): pointer; +var + int1: integer; +begin + int1:= afield.fieldno-1; + if not getfieldflag(@arecord^.header.fielddata.nullmask,int1) then begin + result:= nil; + end + else begin + with ffieldinfos[int1] do begin + if (afieldtype <> ftunknown) and + not (ext.basetype in fielddatacompatibility[afieldtype]) then begin + raise ecurrentvalueaccess.create(self,afield,'Invalid fieldtype.'); + end; + result:= pchar(pointer(arecord)) + base.offset; + end; + end; +end; + +function tmsebufdataset.getcurrentlookuppo(const afield: tfield; + const afieldtype: tfieldtype; const arecord: pintrecordty): pointer; +var + po1: pointer; + bm1: bookmarkdataty; +begin + result:= nil; + with flookupfieldinfos[-1-afield.fieldno] do begin + if indexnum < 0 then begin + raise ecurrentvalueaccess.create(self,afield,'No lookup index.'); + end; + if (afieldtype <> ftunknown) and + not (basedatatype in fielddatacompatibility[afieldtype]) then begin + raise ecurrentvalueaccess.create(self,afield,'Invalid fieldtype.'); + end; + po1:= flookuppo; + flookuppo:= arecord; + try + if afield.lookupdataset.active and + tmsebufdataset(afield.lookupdataset).indexlocal[indexnum].find( + keyfieldar,bm1,false,false,true) then begin + if lookupvaluefield.fieldno > 0 then begin + getvalue(lookupvaluefield,bm1,flookupresult); + result:= flookupresult.po; + end + else begin + if afield.lookupdataset <> nil then begin + with tmsebufdataset(afield.lookupdataset) do begin + currentcheckbrowsemode; + result:= getcurrentlookuppo(lookupvaluefield,afieldtype,bm1.recordpo); + end; + end; + end; + end; + finally + flookuppo:= po1; + end; + end; +end; + +function tmsebufdataset.beforecurrentget(const afield: tfield; + const afieldtype: tfieldtype; var aindex: integer): pointer; +begin + currentcheckbrowsemode; + if afield.dataset <> self then begin + raise ecurrentvalueaccess.create(self,afield,'Wrong dataset.'); + end; + checkindex(factindex); + if aindex < 0 then begin + aindex:= frecno; + end; + if (aindex < 0) or (aindex > high(factindexpo^.ind)) then begin + raise ecurrentvalueaccess.create(self,afield, + 'Invalid index '+inttostr(aindex)+'.'); + end; + if afield.fieldkind = fkcalculated then begin + raise ecurrentvalueaccess.create(self,afield, + 'Field can not be be fkCalculated.'); + end; + if afield.fieldno < 0 then begin + result:= getcurrentlookuppo(afield,afieldtype,factindexpo^.ind[aindex]); + end + else begin + result:= getcurrentpo(afield,afieldtype,factindexpo^.ind[aindex]); + end; +end; + +function tmsebufdataset.beforecurrentbmget(const afield: tfield; + const afieldtype: tfieldtype; const abm: bookmarkdataty): pointer; +begin + currentcheckbrowsemode; + if afield.dataset <> self then begin + raise ecurrentvalueaccess.create(self,afield,'Wrong dataset.'); + end; + if afield.fieldkind = fkcalculated then begin + raise ecurrentvalueaccess.create(self,afield, + 'Field can not be be fkCalculated.'); + end; + result:= nil; + if abm.recordpo <> nil then begin + if (afield.fieldno < 0) then begin + result:= getcurrentlookuppo(afield,afieldtype,abm.recordpo); + end + else begin + result:= getcurrentpo(afield,afieldtype,abm.recordpo); + end; + end; +end; + +function tmsebufdataset.setcurrentpo(const afield: tfield; + const afieldtype: tfieldtype; const arecord: precheaderty; + const aisnull: boolean; out changed: boolean): pointer; +var + po1: pbyte; + int1: integer; +begin +// flastcurrentrec:= pointer(arecord) - sizeof(intrecordty.intheader); + po1:= @arecord^.fielddata.nullmask; + int1:= afield.fieldno-1; + with ffieldinfos[int1] do begin + if (afieldtype <> ftunknown) and + not (ext.basetype in fielddatacompatibility[afieldtype]) then begin + raise ecurrentvalueaccess.create(self,afield,'Invalid fieldtype.'); + end; + changed:= not getfieldflag(po1,int1) xor aisnull; + if changed then begin + if aisnull then begin + clearfieldflag(po1,int1); + end + else begin + setfieldflag(po1,int1); + end; + end; + result:= pchar(pointer(arecord)) + base.offset; + end; +end; + +function tmsebufdataset.beforecurrentset(const afield: tfield; + const afieldtype: tfieldtype; var aindex: integer; + const aisnull: boolean; out changed: boolean): pointer; +begin + currentcheckbrowsemode; + if afield.dataset <> self then begin + raise ecurrentvalueaccess.create(self,afield,'Wrong dataset.'); + end; + if (afield.fieldkind <> fkinternalcalc) then begin + raise ecurrentvalueaccess.create(self,afield,'Field must be fkInternalCalc.'); + end; + checkindex(factindex); + if aindex < 0 then begin + aindex:= frecno; + end; + if (aindex < 0) or (aindex > high(factindexpo^.ind)) then begin + raise ecurrentvalueaccess.create(self,afield, + 'Invalid index '+inttostr(aindex)+'.'); + end; + flastcurrentindex:= aindex; + result:= setcurrentpo(afield,afieldtype,factindexpo^.ind[aindex], + aisnull,changed); +end; + +function tmsebufdataset.beforecurrentbmset(const afield: tfield; + const afieldtype: tfieldtype; const abm: bookmarkdataty; + const aisnull: boolean; out changed: boolean): pointer; +begin + currentcheckbrowsemode; + if afield.dataset <> self then begin + raise ecurrentvalueaccess.create(self,afield,'Wrong dataset.'); + end; + if (afield.fieldkind <> fkinternalcalc) then begin + raise ecurrentvalueaccess.create(self,afield,'Field must be fkInternalCalc.'); + end; + flastcurrentindex:= -1; + result:= setcurrentpo(afield,afieldtype,@abm.recordpo^.header,aisnull,changed); +end; + +procedure tmsebufdataset.aftercurrentset(const afield: tfield); +//var +// int1: integer; +begin + if fcurrentupdating = 0 then begin + findexlocal.fieldmodified(afield,false); + fixupcurrentset; + end + else begin + include(fbstate,bs_curvalueset); + findexlocal.fieldmodified(afield,true); + end; +end; + +function tmsebufdataset.getcurrentisnull(const afield: tfield; + aindex: integer): boolean; +begin + result:= beforecurrentget(afield,ftunknown,aindex) = nil; +end; + +function tmsebufdataset.getcurrentbmisnull(const afield: tfield; + const abm: bookmarkdataty): boolean; +begin + result:= beforecurrentbmget(afield,ftunknown,abm) = nil; +end; + +procedure tmsebufdataset.currentclear(const afield: tfield; aindex: integer); +var + bo1: boolean; +begin + beforecurrentset(afield,ftunknown,aindex,true,bo1); + if bo1 then begin + aftercurrentset(afield); + end; +end; + +procedure tmsebufdataset.currentbmclear(const afield: tfield; + const abm: bookmarkdataty); +var + bo1: boolean; +begin + beforecurrentbmset(afield,ftunknown,abm,true,bo1); + if bo1 then begin + aftercurrentset(afield); + end; +end; + +procedure tmsebufdataset.currentassign(const source: tfield; const dest: tfield; + aindex: integer); +var + po1: pointer; +begin + po1:= beforecurrentget(source,source.datatype,aindex); + if (po1 = nil) or (source.fieldno = 0) then begin + dest.clear; + end + else begin + if source.fieldno > 0 then begin + docurrentassign(po1,ffieldinfos[source.fieldno-1].ext.basetype,dest); + end + else begin + docurrentassign(po1,flookupfieldinfos[-1-source.fieldno].basedatatype,dest); + end; + end; +end; + +procedure tmsebufdataset.currentbmassign(const source: tfield; const dest: tfield; + const abm: bookmarkdataty); +var + po1: pointer; +begin + po1:= beforecurrentbmget(source,source.datatype,abm); + if (po1 = nil) or (source.fieldno = 0) then begin + dest.clear; + end + else begin + if source.fieldno > 0 then begin + docurrentassign(po1,ffieldinfos[source.fieldno-1].ext.basetype,dest); + end + else begin + docurrentassign(po1,flookupfieldinfos[-1-source.fieldno].basedatatype,dest); + end; + end; +end; + +function tmsebufdataset.getcurrentasvariant(const afield: tfield; + aindex: integer): variant; +begin + if currentisnull[afield,aindex] then begin + result:= null; + end + else begin + case afield.datatype of + ftboolean: begin + result:= getcurrentasboolean(afield,aindex); + end; + ftfloat: begin + result:= getcurrentasfloat(afield,aindex); + end; + ftdatetime,fttime,ftdate: begin + result:= getcurrentasdatetime(afield,aindex); + end; + ftbcd: begin + result:= getcurrentascurrency(afield,aindex); + end; + ftinteger,ftword,ftsmallint: begin + result:= getcurrentasinteger(afield,aindex); + end; + ftlargeint: begin + result:= getcurrentaslargeint(afield,aindex); + end; + ftstring: begin + result:= getcurrentasmsestring(afield,aindex); + end; + else begin + raise ecurrentvalueaccess.create(self,afield, + 'Invalid fieldtype field "'+afield.fieldname+'".'); + end; + end; + end; +end; + +procedure tmsebufdataset.setcurrentasvariant(const afield: tfield; + aindex: integer; const avalue: variant); +begin + if varisnull(avalue) then begin + currentclear(afield,aindex) + end + else begin + case afield.datatype of + ftboolean: begin + setcurrentasboolean(afield,aindex,avalue); + end; + ftfloat: begin + setcurrentasfloat(afield,aindex,avalue); + end; + ftdatetime,fttime,ftdate: begin + setcurrentasdatetime(afield,aindex,avalue); + end; + ftbcd: begin + setcurrentascurrency(afield,aindex,avalue); + end; + ftinteger,ftword,ftsmallint: begin + setcurrentasinteger(afield,aindex,avalue); + end; + ftlargeint: begin + setcurrentaslargeint(afield,aindex,avalue); + end; + ftstring: begin + setcurrentasmsestring(afield,aindex,avalue); + end; + else begin + raise ecurrentvalueaccess.create(self,afield, + 'Invalid fieldtype field "'+afield.fieldname+'".'); + end; + end; + end; +end; + +function tmsebufdataset.getcurrentbmasvariant(const afield: tfield; + const abm: bookmarkdataty): variant; +begin + if currentbmisnull[afield,abm] then begin + result:= null; + end + else begin + case afield.datatype of + ftboolean: begin + result:= getcurrentbmasboolean(afield,abm); + end; + ftfloat: begin + result:= getcurrentbmasfloat(afield,abm); + end; + ftdatetime,fttime,ftdate: begin + result:= getcurrentbmasdatetime(afield,abm); + end; + ftbcd: begin + result:= getcurrentbmascurrency(afield,abm); + end; + ftinteger,ftword,ftsmallint: begin + result:= getcurrentbmasinteger(afield,abm); + end; + ftlargeint: begin + result:= getcurrentbmaslargeint(afield,abm); + end; + ftstring: begin + result:= getcurrentbmasmsestring(afield,abm); + end; + else begin + raise ecurrentvalueaccess.create(self,afield, + 'Invalid fieldtype field "'+afield.fieldname+'".'); + end; + end; + end; +end; + +procedure tmsebufdataset.setcurrentbmasvariant(const afield: tfield; + const abm: bookmarkdataty; const avalue: variant); +begin + if varisnull(avalue) then begin + currentbmclear(afield,abm) + end + else begin + case afield.datatype of + ftboolean: begin + setcurrentbmasboolean(afield,abm,avalue); + end; + ftfloat: begin + setcurrentbmasfloat(afield,abm,avalue); + end; + ftdatetime,fttime,ftdate: begin + setcurrentbmasdatetime(afield,abm,avalue); + end; + ftbcd: begin + setcurrentbmascurrency(afield,abm,avalue); + end; + ftinteger,ftword,ftsmallint: begin + setcurrentbmasinteger(afield,abm,avalue); + end; + ftlargeint: begin + setcurrentbmaslargeint(afield,abm,avalue); + end; + ftstring: begin + setcurrentbmasmsestring(afield,abm,avalue); + end; + else begin + raise ecurrentvalueaccess.create(self,afield, + 'Invalid fieldtype field "'+afield.fieldname+'".'); + end; + end; + end; +end; + +function tmsebufdataset.getcurrentasguid(const afield: tfield; + aindex: integer): tguid; +var + po1: pguid; +begin + po1:= beforecurrentget(afield,ftfloat,aindex); + if po1 = nil then begin + result:= guid_null; + end + else begin + result:= po1^; + end; +end; + +procedure tmsebufdataset.setcurrentasguid(const afield: tfield; aindex: integer; + const avalue: tguid); +var + po1: pguid; + bo1: boolean; +begin + po1:= beforecurrentset(afield,ftfloat,aindex,false,bo1); + if bo1 or not isequalguid(po1^,avalue) then begin + po1^:= avalue; + aftercurrentset(afield); + end; +end; + +function tmsebufdataset.getcurrentasfloat(const afield: tfield; + aindex: integer): double; +var + po1: pdouble; +begin + po1:= beforecurrentget(afield,ftfloat,aindex); + if po1 = nil then begin + result:= emptyreal; + end + else begin + result:= po1^; + end; +end; + +function tmsebufdataset.getcurrentbmasfloat(const afield: tfield; + const abm: bookmarkdataty): double; +var + po1: pdouble; +begin + po1:= beforecurrentbmget(afield,ftfloat,abm); + if po1 = nil then begin + result:= emptyreal; + end + else begin + result:= po1^; + end; +end; + +procedure tmsebufdataset.setcurrentasfloat(const afield: tfield; + aindex: integer; const avalue: double); +var + po1: pdouble; + bo1: boolean; +begin + po1:= beforecurrentset(afield,ftfloat,aindex,avalue = emptyreal,bo1); + if bo1 or (po1^ <> avalue) then begin + po1^:= avalue; + aftercurrentset(afield); + end; +end; + +procedure tmsebufdataset.setcurrentbmasfloat(const afield: tfield; + const abm: bookmarkdataty; const avalue: double); +var + po1: pdouble; + bo1: boolean; +begin + po1:= beforecurrentbmset(afield,ftfloat,abm,avalue = emptyreal,bo1); + if bo1 or (po1^ <> avalue) then begin + po1^:= avalue; + aftercurrentset(afield); + end; +end; + +function tmsebufdataset.getcurrentasboolean(const afield: tfield; + aindex: integer): boolean; +var + po1: plongbool; +begin + po1:= beforecurrentget(afield,ftboolean,aindex); + if po1 = nil then begin + result:= false; + end + else begin + result:= po1^; + end; +end; + +function tmsebufdataset.getcurrentbmasboolean(const afield: tfield; + const abm: bookmarkdataty): boolean; +var + po1: plongbool; +begin + po1:= beforecurrentbmget(afield,ftboolean,abm); + if po1 = nil then begin + result:= false; + end + else begin + result:= po1^; + end; +end; + +procedure tmsebufdataset.setcurrentasboolean(const afield: tfield; + aindex: integer; const avalue: boolean); +var + po1: plongbool; + bo1: boolean; +begin + po1:= beforecurrentset(afield,ftboolean,aindex,false,bo1); + if bo1 or (po1^ <> avalue) then begin + po1^:= avalue; + aftercurrentset(afield); + end; +end; + +procedure tmsebufdataset.setcurrentbmasboolean(const afield: tfield; + const abm: bookmarkdataty; const avalue: boolean); +var + po1: plongbool; + bo1: boolean; +begin + po1:= beforecurrentbmset(afield,ftboolean,abm,false,bo1); + if bo1 or (po1^ <> avalue) then begin + po1^:= avalue; + aftercurrentset(afield); + end; +end; + +function tmsebufdataset.getcurrentasinteger(const afield: tfield; + aindex: integer): integer; +var + po1: pinteger; +begin + po1:= beforecurrentget(afield,ftinteger,aindex); + if po1 = nil then begin + result:= 0; + end + else begin + result:= po1^; + end; +end; + +function tmsebufdataset.getcurrentbmasinteger(const afield: tfield; + const abm: bookmarkdataty): integer; +var + po1: pinteger; +begin + po1:= beforecurrentbmget(afield,ftinteger,abm); + if po1 = nil then begin + result:= 0; + end + else begin + result:= po1^; + end; +end; + +procedure tmsebufdataset.setcurrentasinteger(const afield: tfield; + aindex: integer; const avalue: integer); +var + po1: pinteger; + bo1: boolean; +begin + po1:= beforecurrentset(afield,ftinteger,aindex,false,bo1); + if bo1 or (po1^ <> avalue) then begin + po1^:= avalue; + aftercurrentset(afield); + end; +end; + +procedure tmsebufdataset.setcurrentbmasinteger(const afield: tfield; + const abm: bookmarkdataty; const avalue: integer); +var + po1: pinteger; + bo1: boolean; +begin + po1:= beforecurrentbmset(afield,ftinteger,abm,false,bo1); + if bo1 or (po1^ <> avalue) then begin + po1^:= avalue; + aftercurrentset(afield); + end; +end; + +function tmsebufdataset.getcurrentaslargeint(const afield: tfield; + aindex: integer): int64; +var + po1: pint64; +begin + po1:= beforecurrentget(afield,ftlargeint,aindex); + if po1 = nil then begin + result:= 0; + end + else begin + result:= po1^; + end; +end; + +function tmsebufdataset.getcurrentbmaslargeint(const afield: tfield; + const abm: bookmarkdataty): int64; +var + po1: pint64; +begin + po1:= beforecurrentbmget(afield,ftlargeint,abm); + if po1 = nil then begin + result:= 0; + end + else begin + result:= po1^; + end; +end; + +procedure tmsebufdataset.setcurrentaslargeint(const afield: tfield; + aindex: integer; const avalue: int64); +var + po1: pint64; + bo1: boolean; +begin + po1:= beforecurrentset(afield,ftlargeint,aindex,false,bo1); + if bo1 or (po1^ <> avalue) then begin + po1^:= avalue; + aftercurrentset(afield); + end; +end; + +procedure tmsebufdataset.setcurrentbmaslargeint(const afield: tfield; + const abm: bookmarkdataty; const avalue: int64); +var + po1: pint64; + bo1: boolean; +begin + po1:= beforecurrentbmset(afield,ftlargeint,abm,false,bo1); + if bo1 or (po1^ <> avalue) then begin + po1^:= avalue; + aftercurrentset(afield); + end; +end; + +function tmsebufdataset.getcurrentasid(const afield: tfield; + aindex: integer): int64; +var + po1: pint64; +begin + po1:= beforecurrentget(afield,ftlargeint,aindex); + if po1 = nil then begin + result:= -1; + end + else begin + result:= po1^; + end; +end; + +function tmsebufdataset.getcurrentbmasid(const afield: tfield; + const abm: bookmarkdataty): int64; +var + po1: pint64; +begin + po1:= beforecurrentbmget(afield,ftlargeint,abm); + if po1 = nil then begin + result:= -1; + end + else begin + result:= po1^; + end; +end; + +procedure tmsebufdataset.setcurrentasid(const afield: tfield; aindex: integer; + const avalue: int64); +var + po1: pint64; + bo1: boolean; +begin + po1:= beforecurrentset(afield,ftlargeint,aindex,avalue = -1,bo1); + if bo1 or (po1^ <> avalue) then begin + po1^:= avalue; + aftercurrentset(afield); + end; +end; + +procedure tmsebufdataset.setcurrentbmasid(const afield: tfield; + const abm: bookmarkdataty; const avalue: int64); +var + po1: pint64; + bo1: boolean; +begin + po1:= beforecurrentbmset(afield,ftlargeint,abm,avalue = -1,bo1); + if bo1 or (po1^ <> avalue) then begin + po1^:= avalue; + aftercurrentset(afield); + end; +end; + +function tmsebufdataset.getcurrentasdatetime(const afield: tfield; + aindex: integer): tdatetime; +var + po1: pdatetime; +begin + po1:= beforecurrentget(afield,ftdatetime,aindex); + if po1 = nil then begin + result:= emptydatetime; + end + else begin + result:= po1^; + end; +end; + +function tmsebufdataset.getcurrentbmasdatetime(const afield: tfield; + const abm: bookmarkdataty): tdatetime; +var + po1: pdatetime; +begin + po1:= beforecurrentbmget(afield,ftdatetime,abm); + if po1 = nil then begin + result:= emptydatetime; + end + else begin + result:= po1^; + end; +end; + +procedure tmsebufdataset.setcurrentasdatetime(const afield: tfield; + aindex: integer; const avalue: tdatetime); +var + po1: pdouble; + bo1: boolean; +begin + po1:= beforecurrentset(afield,ftdatetime,aindex,avalue = emptydatetime,bo1); + if bo1 or (po1^ <> avalue) then begin + po1^:= avalue; + aftercurrentset(afield); + end; +end; + +procedure tmsebufdataset.setcurrentbmasdatetime(const afield: tfield; + const abm: bookmarkdataty; const avalue: tdatetime); +var + po1: pdouble; + bo1: boolean; +begin + po1:= beforecurrentbmset(afield,ftdatetime,abm,avalue = emptydatetime,bo1); + if bo1 or (po1^ <> avalue) then begin + po1^:= avalue; + aftercurrentset(afield); + end; +end; + +function tmsebufdataset.getcurrentascurrency(const afield: tfield; + aindex: integer): currency; +var + po1: pcurrency; +begin + po1:= beforecurrentget(afield,ftbcd,aindex); + if po1 = nil then begin + result:= 0; + end + else begin + result:= po1^; + end; +end; + +function tmsebufdataset.getcurrentbmascurrency(const afield: tfield; + const abm: bookmarkdataty): currency; +var + po1: pcurrency; +begin + po1:= beforecurrentbmget(afield,ftbcd,abm); + if po1 = nil then begin + result:= 0; + end + else begin + result:= po1^; + end; +end; + +procedure tmsebufdataset.setcurrentascurrency(const afield: tfield; + aindex: integer; const avalue: currency); +var + po1: pcurrency; + bo1: boolean; +begin + po1:= beforecurrentset(afield,ftbcd,aindex,false,bo1); + if bo1 or (po1^ <> avalue) then begin + po1^:= avalue; + aftercurrentset(afield); + end; +end; + +procedure tmsebufdataset.setcurrentbmascurrency(const afield: tfield; + const abm: bookmarkdataty; const avalue: currency); +var + po1: pcurrency; + bo1: boolean; +begin + po1:= beforecurrentbmset(afield,ftbcd,abm,false,bo1); + if bo1 or (po1^ <> avalue) then begin + po1^:= avalue; + aftercurrentset(afield); + end; +end; + +function tmsebufdataset.getcurrentasmsestring(const afield: tfield; + aindex: integer): msestring; +var + po1: pmsestring; +begin + po1:= beforecurrentget(afield,ftwidestring,aindex); + if po1 = nil then begin + result:= ''; + end + else begin + result:= po1^; + end; +end; + +function tmsebufdataset.getcurrentbmasmsestring(const afield: tfield; + const abm: bookmarkdataty): msestring; +var + po1: pmsestring; +begin + po1:= beforecurrentbmget(afield,ftwidestring,abm); + if po1 = nil then begin + result:= ''; + end + else begin + result:= po1^; + end; +end; + +function tmsebufdataset.getcurrentbmasguid(const afield: tfield; + const abm: bookmarkdataty): tguid; +var + po1: pguid; +begin + po1:= beforecurrentbmget(afield,ftguid,abm); + if po1 = nil then begin + result:= guid_null; + end + else begin + result:= po1^; + end; +end; + +procedure tmsebufdataset.setcurrentasmsestring(const afield: tfield; + aindex: integer; const avalue: msestring); +var + po1: pmsestring; + bo1: boolean; +begin + po1:= beforecurrentset(afield,ftwidestring,aindex,false,bo1); + if bo1 or (po1^ <> avalue) then begin + po1^:= avalue; + aftercurrentset(afield); + end; +end; + +procedure tmsebufdataset.setcurrentbmasmsestring(const afield: tfield; + const abm: bookmarkdataty; const avalue: msestring); +var + po1: pmsestring; + bo1: boolean; +begin + po1:= beforecurrentbmset(afield,ftwidestring,abm,false,bo1); + if bo1 or (po1^ <> avalue) then begin + po1^:= avalue; + aftercurrentset(afield); + end; +end; + +procedure tmsebufdataset.setcurrentbmasguid(const afield: tfield; + const abm: bookmarkdataty; + const avalue: tguid); +var + po1: pguid; + bo1: boolean; +begin + po1:= beforecurrentbmset(afield,ftguid,abm,false,bo1); + if bo1 or not isequalguid(po1^,avalue) then begin + po1^:= avalue; + aftercurrentset(afield); + end; +end; + +procedure tmsebufdataset.getbminteger(const afield: tfield; + const bm: bookmarkdataty; var adata: lookupdataty); +var + po1: pinteger; +begin + po1:= getcurrentpo(afield,ftunknown,@bm.recordpo^.header); + if po1 <> nil then begin + adata.int:= po1^; + adata.po:= @adata.int; + end; +end; + +procedure tmsebufdataset.getbmlargeint(const afield: tfield; + const bm: bookmarkdataty; var adata: lookupdataty); +var + po1: pint64; +begin + po1:= getcurrentpo(afield,ftunknown,@bm.recordpo^.header); + if po1 <> nil then begin + adata.lint:= po1^; + adata.po:= @adata.lint; + end; +end; + +procedure tmsebufdataset.getbmcurrency(const afield: tfield; + const bm: bookmarkdataty; var adata: lookupdataty); +var + po1: pcurrency; +begin + po1:= getcurrentpo(afield,ftunknown,@bm.recordpo^.header); + if po1 <> nil then begin + adata.cur:= po1^; + adata.po:= @adata.cur; + end; +end; + +procedure tmsebufdataset.getbmfloat(const afield: tfield; + const bm: bookmarkdataty; var adata: lookupdataty); +var + po1: pdouble; +begin + po1:= getcurrentpo(afield,ftunknown,@bm.recordpo^.header); + if po1 <> nil then begin + adata.doub:= po1^; + adata.po:= @adata.doub; + end; +end; + +procedure tmsebufdataset.getbmstring(const afield: tfield; + const bm: bookmarkdataty; var adata: lookupdataty); +var + po1: pmsestring; +begin + po1:= getcurrentpo(afield,ftunknown,@bm.recordpo^.header); + if po1 <> nil then begin + adata.mstr:= po1^; + adata.po:= @adata.mstr; + end; +end; + +procedure tmsebufdataset.getbmguid(const afield: tfield; + const bm: bookmarkdataty; var adata: lookupdataty); +var + po1: pguid; +begin + po1:= getcurrentpo(afield,ftunknown,@bm.recordpo^.header); + if po1 <> nil then begin + adata.guid:= po1^; + adata.po:= @adata.guid; + end; +end; + +procedure tmsebufdataset.getbmboolean(const afield: tfield; + const bm: bookmarkdataty; var adata: lookupdataty); +var + po1: plongbool; +begin + po1:= getcurrentpo(afield,ftunknown,@bm.recordpo^.header); + if po1 <> nil then begin + adata.boo:= po1^; + adata.po:= @adata.boo; + end; +end; + +procedure tmsebufdataset.getbmdatetime(const afield: tfield; + const bm: bookmarkdataty; var adata: lookupdataty); +var + po1: pdatetime; +begin + po1:= getcurrentpo(afield,ftunknown,@bm.recordpo^.header); + if po1 <> nil then begin + adata.dt:= po1^; + adata.po:= @adata.dt; + end; +end; + +procedure tmsebufdataset.getbmvariant(const afield: tfield; + const bm: bookmarkdataty; var adata: lookupdataty); +var + po1: pvariant; +begin + po1:= getcurrentpo(afield,ftunknown,@bm.recordpo^.header); + if po1 <> nil then begin + adata.vari:= po1^; + adata.po:= @adata.vari; + end; +end; + +procedure tmsebufdataset.dogetcoldata(const afield: tfield; + const afieldtype: tfieldtype; const step: integer; + const data: pointer); +var + po2: pointer; + offs: ptrint; + indexpo: ppointer; + int1: integer; + ft1: tfieldtype; + +begin + if afield.dataset <> self then begin + raise ecurrentvalueaccess.create(self,afield,'Wrong dataset.'); + end; + if afield.index < 0 then begin + raise ecurrentvalueaccess.create(self,afield, + 'Field can not be be fkCalculated or fkLookup.'); + end; + ft1:= afieldtype; + if ft1 = ftwidestring then begin + ft1:= ftstring + end; + checkindex(factindex); + int1:= afield.fieldno-1; + with ffieldinfos[int1] do begin + if not (ext.basetype in fielddatacompatibility[ft1]) then begin + raise ecurrentvalueaccess.create(self,afield,'Invalid fieldtype.'); + end; + offs:= base.offset; + end; + po2:= data; + indexpo:= pointer(factindexpo^.ind); + case afieldtype of + ftinteger: begin + for int1:= 0 to fbrecordcount-1 do begin + pinteger(po2)^:= pinteger(pchar(ppointeraty(indexpo)^[int1])+offs)^; + inc(pchar(po2),step); + end; + end; + ftlargeint: begin + for int1:= 0 to fbrecordcount-1 do begin + pint64(po2)^:= pint64(pchar(ppointeraty(indexpo)^[int1])+offs)^; + inc(pchar(po2),step); + end; + end; + ftboolean: begin + for int1:= 0 to fbrecordcount-1 do begin + pboolean(po2)^:= plongbool(pchar(ppointeraty(indexpo)^[int1])+offs)^; + inc(pchar(po2),step); + end; + end; + ftcurrency: begin + for int1:= 0 to fbrecordcount-1 do begin + pcurrency(po2)^:= pcurrency(pchar(ppointeraty(indexpo)^[int1])+offs)^; + inc(pchar(po2),step); + end; + end; + ftfloat,ftdatetime: begin + for int1:= 0 to fbrecordcount-1 do begin + prealty(po2)^:= pdouble(pchar(ppointeraty(indexpo)^[int1])+offs)^; + inc(pchar(po2),step); + end; + end; + ftstring: begin + for int1:= 0 to fbrecordcount-1 do begin + pansistring(po2)^:= + ansistring(pmsestring(pchar(ppointeraty(indexpo)^[int1])+offs)^); + inc(pchar(po2),step); + end; + end; + ftwidestring: begin + for int1:= 0 to fbrecordcount-1 do begin + pmsestring(po2)^:= pmsestring(pchar(ppointeraty(indexpo)^[int1])+offs)^; + inc(pchar(po2),step); + end; + end; + end; +end; + +procedure tmsebufdataset.getcoldata(const afield: tfield; + const adatalist: tdatalist); +var + type1: tfieldtype; +begin + currentcheckbrowsemode; + with adatalist do begin + type1:= ftunknown; + case adatalist.datatype of + dl_integer: begin + type1:= ftinteger; + end; + dl_int64: begin + type1:= ftlargeint; + end; + dl_currency: begin + type1:= ftcurrency; + end; + dl_real,dl_realint,dl_realsum,dl_datetime: begin + type1:= ftfloat; + end; + dl_ansistring: begin + type1:= ftstring; + end; + dl_msestring,dl_doublemsestring,dl_msestringint: begin + type1:= ftwidestring; + end; + end; + if type1 <> ftunknown then begin + beginupdate; + try + clear; + count:= fbrecordcount; + dogetcoldata(afield,type1,size,datapo); + finally + endupdate; + end; + end + else begin + raise ecurrentvalueaccess.create(self,afield, + 'Invalid datalist.'); + end; + end; +end; + +procedure tmsebufdataset.asarray(const afield: tfield; + out avalue: int64arty); +begin + currentcheckbrowsemode; + setlength(avalue,fbrecordcount); + dogetcoldata(afield,ftlargeint,sizeof(avalue[0]),pointer(avalue)); +end; + +procedure tmsebufdataset.asarray(const afield: tfield; out avalue: integerarty); +begin + currentcheckbrowsemode; + setlength(avalue,fbrecordcount); + dogetcoldata(afield,ftinteger,sizeof(avalue[0]),pointer(avalue)); +end; + +procedure tmsebufdataset.asarray(const afield: tfield; out avalue: stringarty); +begin + currentcheckbrowsemode; + setlength(avalue,fbrecordcount); + dogetcoldata(afield,ftstring,sizeof(avalue[0]),pointer(avalue)); +end; + +procedure tmsebufdataset.asarray(const afield: tfield; + out avalue: msestringarty); +begin + currentcheckbrowsemode; + setlength(avalue,fbrecordcount); + dogetcoldata(afield,ftwidestring,sizeof(avalue[0]),pointer(avalue)); +end; + +procedure tmsebufdataset.asarray(const afield: tfield; + out avalue: currencyarty); +begin + currentcheckbrowsemode; + setlength(avalue,fbrecordcount); + dogetcoldata(afield,ftcurrency,sizeof(avalue[0]),pointer(avalue)); +end; + +procedure tmsebufdataset.asarray(const afield: tfield; out avalue: realarty); +begin + currentcheckbrowsemode; + setlength(avalue,fbrecordcount); + dogetcoldata(afield,ftfloat,sizeof(avalue[0]),pointer(avalue)); +end; + +procedure tmsebufdataset.asarray(const afield: tfield; + out avalue: datetimearty); +begin + currentcheckbrowsemode; + setlength(avalue,fbrecordcount); + dogetcoldata(afield,ftdatetime,sizeof(avalue[0]),pointer(avalue)); +end; + +procedure tmsebufdataset.asarray(const afield: tfield; + out avalue: booleanarty); +begin + currentcheckbrowsemode; + setlength(avalue,fbrecordcount); + dogetcoldata(afield,ftboolean,sizeof(avalue[0]),pointer(avalue)); +end; + +function tmsebufdataset.currentrecordhigh: integer; +begin + currentcheckbrowsemode; + result:= fbrecordcount - 1; +end; + +procedure tmsebufdataset.docurrentassign(const po1: pointer; + const abasetype: tfieldtype; + const df: tfield); +begin + case abasetype of + ftwidestring: begin + if df is tmsestringfield then begin + tmsestringfield(df).asmsestring:= pmsestring(po1)^; + end + else begin + df.asstring:= ansistring(pmsestring(po1)^); + end; + end; + ftinteger: begin + df.asinteger:= pinteger(po1)^; + end; + ftboolean: begin + df.asboolean:= plongbool(po1)^; + end; + ftbcd: begin + df.ascurrency:= pcurrency(po1)^; + end; + ftfloat: begin + df.asfloat:= pdouble(po1)^; + end; + ftlargeint: begin + df.aslargeint:= pint64(po1)^; + end; + ftdatetime: begin + df.asdatetime:= pdatetime(po1)^; + end; + ftvariant: begin + df.asvariant:= pvariant(po1)^; + end + else begin + df.clear; + end; + end; +end; + +procedure tmsebufdataset.copyfieldvalues(const bm: bookmarkdataty; + const dest: tdataset); + //copies field values with same name +var + df: tfield; + int1: integer; + int2: integer; + str1: string; +begin + if not active then begin + exit; + end; + currentcheckbrowsemode; + for int1:= 0 to dest.fieldcount - 1 do begin + df:= dest.fields[int1]; + if not df.readonly then begin + str1:= uppercase(df.fieldname); + for int2:= 0 to high(ffieldinfos)do begin + with ffieldinfos[int2] do begin + if (ext.uppername = str1) and (ext.basetype <> ftblob) and + ext.field.visible and + (ext.field.fieldkind <> fkcalculated) and + (ext.field.fieldkind <> fklookup) then begin + if not getfieldflag(@bm.recordpo^.header.fielddata.nullmask,int2) then begin + df.clear; + end + else begin + docurrentassign(pchar(bm.recordpo)+base.offset, + ffieldinfos[int2].ext.basetype,df); +{ + case ext.basetype of + ftwidestring: begin + if df is tmsestringfield then begin + tmsestringfield(df).asmsestring:= pmsestring(po1)^; + end + else begin + df.asstring:= pmsestring(po1)^; + end; + end; + ftinteger: begin + df.asinteger:= pinteger(po1)^; + end; + ftboolean: begin + df.asboolean:= plongbool(po1)^; + end; + ftbcd: begin + df.ascurrency:= pcurrency(po1)^; + end; + ftfloat: begin + df.asfloat:= pdouble(po1)^; + end; + ftlargeint: begin + df.aslargeint:= pint64(po1)^; + end; + ftdatetime: begin + df.asdatetime:= pdatetime(po1)^; + end; + ftvariant: begin + df.asvariant:= pvariant(po1)^; + end + else begin +// databaseerror(name+': Invalid datatype.'); + end; + end; +} + end; + end; + end; + end; + end; + end; +end; + +procedure tmsebufdataset.copyfieldvalues(const bm: bookmarkdataty; + const dest: tmsebufdataset; const acancelupdate: boolean); +var + bo1: boolean; +begin + with dest do begin + if not self.active or not active or fcontroller.posting1 then begin + exit; + end; + bo1:= state = dsbrowse; + disablecontrols; + try + edit; + self.copyfieldvalues(bm,dest); + if acancelupdate then begin + include(fbstate,bs_noautoapply); + post; + cancelupdate(true); + end + else begin + if bo1 then begin + post; + end; + end; + finally + exclude(fbstate,bs_noautoapply); + enablecontrols; + if bo1 or acancelupdate then begin + dataevent(dedatasetchange,0); + dataevent(tdataevent(de_modified),0); + end; + end; + end; +end; + +function tmsebufdataset.refreshrecord(const asourcevalues: array of variant; + const adestfields: array of tfield; + const akeyvalue: array of variant; const keyindex: integer = 0; + const acancelupdate: boolean = true; + const restorerecno: boolean = true; + const noinsert: boolean = false): bookmarkdataty; +var + bm1,bm2: string; + int1: integer; +// bo1: boolean; +begin + if not active or fcontroller.posting1 then begin + exit; + end; + checkbrowsemode; + disablecontrols; + bm2:= bookmark; + try + if keyindex < 0 then begin + edit; + end + else begin + if indexlocal[keyindex].findvariant(akeyvalue,bm1) then begin + bookmark:= bm1; + edit; + end + else begin + if noinsert then begin + result.recno:= -1; + result.recordpo:= nil; + exit; + end; + insert; + end; + end; + for int1:= 0 to high(asourcevalues) do begin + if int1 > high(adestfields) then begin + break; + end; + adestfields[int1].value:= asourcevalues[int1]; + end; + if acancelupdate then begin + include(fbstate,bs_noautoapply); + post; + cancelupdate(true); + end + else begin + post; + end; + result.recno:= frecno; + result.recordpo:= fcurrentbuf; + finally + exclude(fbstate,bs_noautoapply); + if restorerecno and (keyindex >= 0) then begin + bookmark:= bm2; + end; + enablecontrols; + dataevent(dedatasetchange,0); + dataevent(tdataevent(de_modified),0); + end; +end; + +function tmsebufdataset.refreshrecord(const asourcefields: array of tfield; + const adestfields: array of tfield; + const akeyfield: array of tfield; const keyindex: integer = 0; + const acancelupdate: boolean = true; + const restorerecno: boolean = true; + const noinsert: boolean = false): bookmarkdataty; +begin + result:= refreshrecord(fieldvariants(asourcefields),adestfields, + fieldvariants(akeyfield),keyindex,acancelupdate,restorerecno, + noinsert); +end; + +function tmsebufdataset.refreshrecord(const asourcefields: array of tfield; + const adestfields: array of tfield; + const akeyvalue: array of variant; const keyindex: integer = 0; + const acancelupdate: boolean = true; + const restorerecno: boolean = true; + const noinsert: boolean = false): bookmarkdataty; +begin + result:= refreshrecord(fieldvariants(asourcefields),adestfields,akeyvalue,keyindex, + acancelupdate,restorerecno,noinsert); +end; + +function tmsebufdataset.refreshrecord(const asourcefields: array of tfield; + const akeyfield: array of tfield; const keyindex: integer = 0; + const acancelupdate: boolean = true; + const restorerecno: boolean = true; + const noinsert: boolean = false): bookmarkdataty; +var + int1: integer; + ar1: fieldarty; +begin + setlength(ar1,length(asourcefields)); + for int1:= 0 to high(asourcefields) do begin + ar1[int1]:= fieldbyname(asourcefields[int1].fieldname); + end; + result:= refreshrecord(asourcefields,ar1,akeyfield,keyindex, + acancelupdate,restorerecno,noinsert); +end; +{ +procedure tmsebufdataset.refreshrecord(const akeyfield: tfield; + const keyindex: integer = 0; const acancelupdate: boolean = true); +var + int1,int2: integer; + field1,field2: tfield; + sf,df: fieldarty; +begin + with akeyfield.dataset do begin + int2:= 0; + setlength(sf,fields.count); //max + setlength(df,fields.count); //max + for int1:= 0 to high(sf) do begin + field1:= fields[int1]; + if field1.visible then begin + field2:= self.findfield(field1.fieldname); + if (field2 <> nil) and not field2.readonly then begin + sf[int2]:= field1; + df[int2]:= field2; + inc(int2); + end; + end; + end; + end; + setlength(sf,int2); + setlength(df,int2); + refreshrecord(sf,df,akeyfield,keyindex,acancelupdate); +end; +} +function tmsebufdataset.refreshrecord(const sourcedatasets: array of tdataset; + const akeyvalue: array of variant; + const keyindex: integer = 0; + const acancelupdate: boolean = true; + const restorerecno: boolean = true; + const noinsert: boolean = false): bookmarkdataty; +var + int1,int2,int3: integer; + field1,field2: tfield; + sf,df: fieldarty; +begin + int2:= 0; + sf:= nil; //compilerwarning + for int3:= 0 to high(sourcedatasets) do begin + with sourcedatasets[int3] do begin + setlength(sf,length(sf)+fields.count); //max + setlength(df,length(sf)); //max + for int1:= 0 to fields.count-1 do begin + field1:= fields[int1]; + if field1.visible then begin + field2:= self.findfield(field1.fieldname); + if (field2 <> nil) and not field2.readonly then begin + sf[int2]:= field1; + df[int2]:= field2; + inc(int2); + end; + end; + end; + end; + end; + setlength(sf,int2); + setlength(df,int2); + result:= refreshrecord(sf,df,akeyvalue,keyindex,acancelupdate,restorerecno, + noinsert); +end; + +{$ifndef FPC} +function tmsebufdataset.refreshrecordvarar(const sourcedatasets: array of tdataset; + const akeyvalue: array of variant; + const keyindex: integer; + const acancelupdate: boolean; + const restorerecno: boolean; + const noinsert: boolean): bookmarkdataty; +begin + result:= refreshrecord(sourcedatasets,akeyvalue,keyindex,acancelupdate, + restorerecno,noinsert); +end; +{$endif} + +function tmsebufdataset.refreshrecord(const akeyfield: array of tfield; + const keyindex: integer = 0; const acancelupdate: boolean = true; + const restorerecno: boolean = true; + const noinsert: boolean = false): bookmarkdataty; +begin +{$ifdef fpc} + result:= refreshrecord([akeyfield[0].dataset],fieldvariants(akeyfield),keyindex, + acancelupdate,restorerecno,noinsert); +{$else} + result:= refreshrecordvarar([akeyfield[0].dataset],fieldvariants(akeyfield),keyindex, + acancelupdate,restorerecno,noinsert); +{$endif} +end; + +function tmsebufdataset.getindex(const afield: tfield): integer; +var + int1: integer; +begin + result:= -1; + for int1:= 0 to findexlocal.count - 1 do begin + with tlocalindex(findexlocal.fitems[int1]) do begin + if (fields.count > 0) and (high(findexfieldinfos) >= 0) and + (findexfieldinfos[0].fieldinstance = afield) then begin + result:= int1; + break; + end; + end; + end; +end; + +function tmsebufdataset.gettextindex(const afield: tfield; + const acaseinsensitive: boolean): integer; +var + int1: integer; +begin + result:= -1; + for int1:= 0 to findexlocal.count - 1 do begin + with tlocalindex(findexlocal.fitems[int1]) do begin + if (fields.count > 0) and (high(findexfieldinfos) >= 0) and + (findexfieldinfos[0].fieldinstance = afield) and + not (findexfieldinfos[0].caseinsensitive xor + acaseinsensitive) then begin + result:= int1; + break; + end; + end; + end; +end; + +function tmsebufdataset.updatesortfield(const afield: tfield; + const adescend: boolean): boolean; +var + int1: integer; +begin + result:= false; + if afield <> nil then begin + for int1:= 0 to findexlocal.count - 1 do begin + with tlocalindex(findexlocal.fitems[int1]) do begin + if (fields.count > 0) and (high(findexfieldinfos) >= 0) and + (findexfieldinfos[0].fieldinstance = afield) then begin + result:= true; + desc:= adescend; + active:= true; + end; + end; + end; + end; + if not result then begin +// findexlocal.activeindex:= -1; + findexlocal.activeindex:= findexlocal.defaultindex; + end; +end; + +procedure tmsebufdataset.setbookmarkdata1(const avalue: bookmarkdataty); +begin + gotobookmark(@avalue); +end; + +function tmsebufdataset.recapplying: boolean; +begin + result:= bs_recapplying in fbstate; +end; + +procedure tmsebufdataset.dropupdates(); +begin + dropupdates1(false); +end; + +function tmsebufdataset.lookuptext(const indexnum: integer; const akey: integer; + const aisnull: boolean; const valuefield: tmsestringfield): msestring; +var + bm1: bookmarkdataty; +begin + result:= ''; + if indexlocal[indexnum].find([akey],[aisnull],bm1,false,false,true) then begin + result:= currentbmasmsestring[valuefield,bm1]; + end; +end; + +function tmsebufdataset.lookuptext(const indexnum: integer; const akey: int64; + const aisnull: boolean; const valuefield: tmsestringfield): msestring; +var + bm1: bookmarkdataty; +begin + result:= ''; + if indexlocal[indexnum].find([akey],[aisnull],bm1,false,false,true) then begin + result:= currentbmasmsestring[valuefield,bm1]; + end; +end; + +function tmsebufdataset.lookuptext(const indexnum: integer; const akey: msestring; + const aisnull: boolean; const valuefield: tmsestringfield): msestring; +var + bm1: bookmarkdataty; +begin + result:= ''; + if indexlocal[indexnum].find([akey],[aisnull],bm1,false,false,true) then begin + result:= currentbmasmsestring[valuefield,bm1]; + end; +end; + +function tmsebufdataset.findtext(const indexnum: integer; const searchtext: msestring; + out arecord: integer): boolean; +var + bm1: bookmarkdataty; +begin + arecord:= -1; + result:= indexlocal[indexnum].find([searchtext],[false],bm1,false,true); + if result then begin + arecord:= bm1.recno; + end; +end; + +function tmsebufdataset.getrowtext(const indexnum: integer; + const arecord: integer; const afield: tfield): msestring; +var + bm1: bookmarkdataty; +begin + if indexnum >= 0 then begin + checkindex(indexnum+1); + end; + bm1.recno:= arecord; + bm1.recordpo:= findexes[indexnum+1].ind[arecord]; + if afield is tmsestringfield then begin + result:= currentbmasmsestring[afield,bm1]; + end + else begin + case afield.datatype of + ftboolean: begin + result:= tmsebooleanfield1(afield).fdisplays[ + false,currentbmasboolean[afield,bm1]]; + end; + ftsmallint,ftword,ftinteger: begin + result:= inttostrmse(currentbmasinteger[afield,bm1]); + end; + ftlargeint: begin + result:= inttostrmse(currentbmasinteger[afield,bm1]); + end; + ftfloat: begin + result:= formatfloatmse(currentbmasfloat[afield,bm1],''); + end; + fttime,ftdate,ftdatetime: begin + result:= tmsedatetimefield1(afield).gettext1( + currentbmasdatetime[afield,bm1],true); + end; + ftbcd: begin + result:= currencytostrmse(currentbmascurrency[afield,bm1]); + end; + else begin + result:= ''; + end; + end; + end; +end; + +function tmsebufdataset.getrowinteger(const indexnum: integer; + const arecord: integer; const afield: tfield): integer; +var + bm1: bookmarkdataty; +begin + if indexnum >= 0 then begin + checkindex(indexnum+1); + end; + bm1.recno:= arecord; + bm1.recordpo:= findexes[indexnum+1].ind[arecord]; + result:= currentbmasinteger[afield,bm1]; +end; + +function tmsebufdataset.getrowlargeint(const indexnum: integer; + const arecord: integer; const afield: tfield): int64; +var + bm1: bookmarkdataty; +begin + if indexnum >= 0 then begin + checkindex(indexnum+1); + end; + bm1.recno:= arecord; + bm1.recordpo:= findexes[indexnum+1].ind[arecord]; + result:= currentbmaslargeint[afield,bm1]; +end; + +procedure CalcLookupValue(const afield: tfield); +begin + with afield do begin + if LookupCache then begin + Value:= LookupList.ValueOfKey(DataSet.FieldValues[KeyFields]) + end + else begin + if Assigned(LookupDataSet) and DataSet.Active then begin + Value:= LookupDataSet.Lookup(LookupKeyfields, + DataSet.FieldValues[KeyFields], LookupresultField); + end; + end; + end; +end; + +procedure tmsebufdataset.CalculateFields(Buffer: PChar); +var + i: Integer; + field1: tfield; + bm1: bookmarkdataty; + state1: tdatasetstate; +begin + FCalcBuffer1:= Buffer; + if not IsUniDirectional and (State <> dsInternalCalc) then begin + state1:= settempstate(dscalcfields); + try + ClearCalcFields(FCalcBuffer1); + for i := 0 to Fields.Count - 1 do begin + field1:= fields[i]; + if (field1.FieldKind = fkLookup) and + (field1.lookupdataset <> nil) then begin + with flookupfieldinfos[-1-field1.fieldno] do begin + if indexnum >= 0 then begin + with tmsebufdataset(field1.lookupdataset) do begin + if active and + indexlocal[indexnum].find(keyfieldar,bm1,false,false,true) then begin + //no checkbrowsemode + currentbmassign(lookupvaluefield,field1,bm1); + end + else begin + field1.clear; + end; + end; + end + else begin + CalcLookupValue(field1); + end; + end; + end; + end; + DoOnCalcFields; + finally + restorestate(state1); + end; + end; +end; + +procedure tmsebufdataset.notification(acomponent: tcomponent; + operation: toperation); +var + i1: int32; +begin + inherited; + if not (csdestroying in componentstate) and (operation = opremove) then begin + for i1:= 0 to high(flookupfieldinfos) do begin + if acomponent = flookupfieldinfos[i1].lookupvaluefield then begin + active:= false; + break; + end; + end; + end; +end; + +procedure tmsebufdataset.begindisplaydata; +begin + include(fbstate,bs_displaydata); +end; + +procedure tmsebufdataset.enddisplaydata; +begin + exclude(fbstate,bs_displaydata); +end; + +function tmsebufdataset.getsavepointoptions(): savepointoptionsty; +begin + result:= []; + if bdo_postsavepoint in foptions then begin + include(result,spo_postsavepoint); + end; + if bdo_deletesavepoint in foptions then begin + include(result,spo_deletesavepoint); + end; +end; + +function tmsebufdataset.getdata(const afields: array of tfield): variantararty; +var + ar1: fieldarty; + int1,int2: integer; + po1: pvariantaty; +begin + checkbrowsemode; + ar1:= getdsfields(self,afields); + try + setlength(result,recordcount); + for int1:= 0 to high(result) do begin + setlength(result[int1],length(ar1)); + po1:= pointer(result[int1]); + for int2:= 0 to high(ar1) do begin + po1^[int2]:= currentasvariant[ar1[int2],int1]; + end; + end; + except + result:= nil; + raise; + end; +end; + +procedure tmsebufdataset.post; +begin +{ + if (bs1_posting in fbstate1) and (state in [dsedit,dsinsert]) then begin + databaseerror('Recursive post.',self); + end; +} + if not (bs1_posting in fbstate1) then begin + include(fbstate1,bs1_posting); + try + inherited; + finally + exclude(fbstate1,bs1_posting); + end; + end; +end; +{ +procedure tmsebufdataset.dscontrolleroptionschanged(const aoptions: datasetoptionsty); +begin +end; +} +procedure tmsebufdataset.savepointevent(const sender: tmdbtransaction; + const akind: savepointeventkindty; const alevel: integer); +begin + if (bs1_restoreupdate in fbstate1) and active and + ((sender = ftransactionwrite) or + (ftransactionwrite = nil) and (sender = ftransaction)) then begin + case akind of + spek_begin: begin + if fsavepointlevel < 0 then begin + fsavepointlevel:= alevel; + include(fbstate1,bs1_deferdeleterecupdatebuffer); + end; + end; + else begin + if alevel <= fsavepointlevel then begin + fsavepointlevel:= -1; + exclude(fbstate1,bs1_deferdeleterecupdatebuffer); + if akind in [spek_release,spek_committrans] then begin + postrecupdatebuffer; + end + else begin + restorerecupdatebuffer; + end; + end; + end; + end; + end; +end; + +function tmsebufdataset.getchangerecords: recupdateinfoarty; +var + int1,int2: integer; +begin + setlength(result,length(fupdatebuffer)); + int2:= 0; + for int1:= 0 to high(result) do begin + with fupdatebuffer[int1] do begin + if (info.bookmark.recordpo <> nil) and + not (ruf_applied in info.flags) then begin + result[int2]:= info; + inc(int2); + end; + end; + end; + setlength(result,int2); +end; + +function tmsebufdataset.getapplyerrorrecords: recupdateinfoarty; +var + int1,int2: integer; +begin + setlength(result,length(fupdatebuffer)); + int2:= 0; + for int1:= 0 to high(result) do begin + with fupdatebuffer[int1] do begin + if (info.bookmark.recordpo <> nil) and + (info.flags*[ruf_applied,ruf_error] = [ruf_error]) then begin + result[int2]:= info; + inc(int2); + end; + end; + end; + setlength(result,int2); +end; + +procedure tmsebufdataset.setcryptohandler(const avalue: tcustomcryptohandler); +begin + getobjectlinker.setlinkedvar(iobjectlink(self),avalue, + tmsecomponent(fcryptohandler)); +end; + +procedure tmsebufdataset.objectevent(const sender: tobject; + const event: objecteventty); +begin + //dummy +end; + +function tmsebufdataset.getobjectlinker: tobjectlinker; +begin + if fobjectlinker = nil then begin + createobjectlinker(iobjectlink(self),{$ifdef FPC}@{$endif}objectevent, + fobjectlinker); + end; + result:= fobjectlinker; +end; + +procedure tmsebufdataset.link(const source: iobjectlink; + const dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); +begin + getobjectlinker.link(source,dest,valuepo,ainterfacetype,once); +end; + +procedure tmsebufdataset.unlink(const source: iobjectlink; + const dest: iobjectlink; valuepo: pointer = nil); +begin + getobjectlinker.unlink(source,dest,valuepo); +end; + +procedure tmsebufdataset.objevent(const sender: iobjectlink; + const event: objecteventty); +begin + getobjectlinker.objevent(sender,event); +end; + +function tmsebufdataset.getinstance: tobject; +begin + result:= self; +end; + +function tmsebufdataset.getcomponent: tcomponent; +begin + result:= self; +end; + +function tmsebufdataset.recnobookmark( + const arecnozerobased: int32): bookmarkdataty; +begin + checkrecno(arecnozerobased+1); + result.recno:= arecnozerobased; + result.recordpo:= factindexpo^.ind[arecnozerobased]; +end; + +{ tlocalindexes } + +constructor tlocalindexes.create(const aowner: tmsebufdataset); +begin + inherited create(aowner,tlocalindex); +end; + +class function tlocalindexes.getitemclasstype: persistentclassty; +begin + result:= tlocalindex; +end; + +function tlocalindexes.getitems(const index: integer): tlocalindex; +begin + result:= tlocalindex(inherited items[index]); +end; + +procedure tlocalindexes.checkinactive; +begin + if tmsebufdataset(fowner).active then begin + databaseerror(SActiveDataset,tmsebufdataset(fowner)); + end; +end; + +procedure tlocalindexes.setcount1(acount: integer; doinit: boolean); +begin + checkinactive; + inherited; + if not (aps_destroying in fstate) then begin + tmsebufdataset(fowner).updatestate; + end; +end; + +procedure tlocalindexes.bindfields; +var + int1: integer; +begin + for int1:= count - 1 downto 0 do begin + items[int1].bindfields; + end; +end; + +procedure tlocalindexes.move(const curindex: integer; const newindex: integer); +begin + checkinactive; + inherited; +end; + +function tlocalindexes.getactiveindex: integer; +begin + result:= tmsebufdataset(fowner).actindex - 1; +end; + +procedure tlocalindexes.setactiveindex(const avalue: integer); +begin + if avalue < 0 then begin + tmsebufdataset(fowner).actindex:= 0; + end + else begin + items[avalue].active:= true; + end; +end; + +function tlocalindexes.fieldactive(const afield: tfield): boolean; +var + int1: integer; +begin + result:= tmsebufdataset(fowner).factindex > 0; + if result and (afield <> nil) then begin + result:= false; + with items[tmsebufdataset(fowner).factindex-1] do begin + for int1:= 0 to high(findexfieldinfos) do begin + if findexfieldinfos[int1].fieldinstance = afield then begin + result:= true; + break; + end; + end; + end; + end; +end; + +function tlocalindexes.hasfield(const afield: tfield): boolean; +var + int1,int2: integer; +begin + result:= false; + for int2:= 0 to high(fitems) do begin + with items[int2] do begin + for int1:= 0 to high(findexfieldinfos) do begin + if findexfieldinfos[int1].fieldinstance = afield then begin + result:= true; + break; + end; + end; + end; + if result then begin + break; + end; + end; +end; + +function tlocalindexes.fieldmodified(const afield: tfield; + const delayed: boolean): boolean; +var + int1,int2: integer; +begin + result:= false; + for int1:= 0 to count-1 do begin + with tlocalindex(fitems[int1]) do begin + for int2:= 0 to high(findexfieldinfos) do begin + if (afield = nil) or + (findexfieldinfos[int2].fieldinstance = afield) then begin + result:= true; + if delayed then begin + finvalid:= true; + end + else begin + with tmsebufdataset(fowner) do begin + findexes[int1+1].ind:= nil; +// exclude(tmsebufdataset(fowner).fbstate,bs_indexvalid); + end; + end; + end; + break; + end; + end; + end; +end; + +procedure tlocalindexes.preparefixup; +var + int1: integer; +begin + for int1:= 0 to count-1 do begin + with tlocalindex(fitems[int1]) do begin + if finvalid then begin + finvalid:= false; + with tmsebufdataset(fowner) do begin + findexes[int1+1].ind:= nil; +// exclude(fbstate,bs_indexvalid); + end; + end; + end; + end; +end; + +procedure tlocalindexes.doindexchanged; +begin + if checkcanevent(tmsebufdataset(fowner), + tmethod(fonindexchanged)) then begin + fonindexchanged(tmsebufdataset(fowner)); + end; +end; + +function tlocalindexes.getdefaultindex: integer; +var + int1: integer; +begin + result:= -1; + for int1:= high(fitems) downto 0 do begin + if lio_default in tlocalindex(fitems[int1]).foptions then begin + result:= int1; + break; + end; + end; +end; + +procedure tlocalindexes.setdefaultindex(const avalue: integer); +var + int1: integer; +begin + if avalue < 0 then begin + int1:= defaultindex; + if int1 >= 0 then begin + tlocalindex(fitems[int1]).default:= false; + end + else begin + tlocalindex(fitems[avalue]).default:= true; + end; + end; +end; + +function tlocalindexes.indexbyname(const aname: string): tlocalindex; +var + int1: integer; +begin + result:= nil; + for int1:= 0 to high(fitems) do begin + if tlocalindex(fitems[int1]).name = aname then begin + result:= tlocalindex(fitems[int1]); + end; + end; +end; + +{ tlocalindex } + +constructor tlocalindex.create(aowner: tobject); +begin + ffields:= tindexfields.create(self); + inherited; +end; + +destructor tlocalindex.destroy; +begin + ffields.free; + inherited; +end; + +procedure tlocalindex.setfields(const avalue: tindexfields); +begin + ffields.assign(avalue); +end; + +procedure tlocalindex.change; +var + int1: integer; +begin + with tmsebufdataset(fowner) do begin + if fopen then begin + self.bindfields; + int1:= findexlocal.indexof(self) + 1; + with findexes[int1] do begin + if ind <> nil then begin + if factindex = int1 then begin + checkbrowsemode; + end; + ind:= nil; +// exclude(fbstate,bs_indexvalid); + if factindex = int1 then begin + internalsetrecno(findrecord(fcurrentbuf)); + resync([]); + findexlocal.doindexchanged; + end; + end; + end; + end; + end; +end; + +procedure tlocalindex.setoptions(const avalue: localindexoptionsty); +var + bo1: boolean; + int1: integer; +begin + if foptions <> avalue then begin + bo1:= lio_default in foptions; + foptions:= avalue; + if not bo1 and (lio_default in foptions) then begin + with tmsebufdataset(fowner).findexlocal do begin + for int1:= 0 to high(fitems) do begin + exclude(tlocalindex(fitems[int1]).foptions,lio_default); + end; + end; + include(foptions,lio_default); + end; + change; + end; +end; + +procedure lookup1(const afield: tfield; const apo: pintrecordty; + var adata: lookupdataty); +var + bm1: bookmarkdataty; + po1: pintrecordty; +begin + adata.po:= nil; + with tmsebufdataset(afield.dataset) do begin + flookuppo:= apo; + with flookupfieldinfos[-1-afield.fieldno] do begin + with tmsebufdataset(afield.lookupdataset) do begin + if active then begin + if indexlocal[indexnum].find(keyfieldar,bm1,false,false,true) then begin + if lookupvaluefield.fieldno > 0 then begin + getvalue(lookupvaluefield,bm1,adata); + end + else begin + if lookupvaluefield.lookupdataset is tmsebufdataset then begin + with tmsebufdataset(lookupvaluefield.dataset) do begin + if active then begin + po1:= flookuppo; + try + lookup1(lookupvaluefield,bm1.recordpo,adata); + finally + flookuppo:= po1; + end; + end; + end; + end; + end; + end; + end; + end; + end; + end; +end; + +function tlocalindex.dolookupcompare(const l,r: pintrecordty; + const ainfo: indexfieldinfoty; const apartialstring: boolean): integer; + +var + ldata,rdata: lookupdataty; + +begin + result:= 0; + with tmsebufdataset(ainfo.fieldinstance.lookupdataset) do begin + if active then begin + try + lookup1(ainfo.fieldinstance,l,ldata); + lookup1(ainfo.fieldinstance,r,rdata); + finally + tmsebufdataset(self.fowner).flookuppo:= nil; + end; + if ldata.po = nil then begin + if rdata.po = nil then begin + exit; + end + else begin + dec(result); + end; + end + else begin + if rdata.po = nil then begin + inc(result); + end + else begin + result:= ainfo.comparefunc(ldata.po^,rdata.po^); + if (result <> 0) and apartialstring then begin + if ainfo.caseinsensitive then begin + result:= msepartialcomparetext(ldata.mstr,rdata.mstr); + end + else begin + result:= msepartialcomparestr(ldata.mstr,rdata.mstr); + end; + end; + end; + end; + end; + end; +end; + +function tlocalindex.dolookupcomparea(const lvalue: pointer; r: pintrecordty; + const ainfo: indexfieldinfoty; const apartialstring: boolean): integer; + //l is compare value, r can be lookup +var + {ldata,}rdata: lookupdataty; + +begin + result:= 0; + with tmsebufdataset(ainfo.fieldinstance.lookupdataset) do begin + if active then begin + try +// lookup1(ainfo.fieldinstance,l,ldata); + lookup1(ainfo.fieldinstance,r,rdata); + finally + tmsebufdataset(self.fowner).flookuppo:= nil; + end; + if lvalue = nil then begin + if rdata.po = nil then begin + exit; + end + else begin + dec(result); + end; + end + else begin + if rdata.po = nil then begin + inc(result); + end + else begin + result:= ainfo.comparefunc(lvalue^,rdata.po^); + if (result <> 0) and apartialstring then begin + if ainfo.caseinsensitive then begin + result:= msepartialcomparetext(pmsestring(lvalue)^,rdata.mstr); + end + else begin + result:= msepartialcomparestr(pmsestring(lvalue)^,rdata.mstr); + end; + end; + end; + end; + end; + end; +end; + +function tlocalindex.compare1(l,r: pintrecordty; const alastindex: integer; + const apartialstring: boolean): integer; +var + int1: integer; +begin + result:= 0; + for int1:= 0 to alastindex do begin + with findexfieldinfos[int1] do begin + if islookup then begin + result:= dolookupcompare(l,r,findexfieldinfos[int1], + apartialstring and canpartialstring and (int1 = alastindex)); + if desc then begin + result:= -result; + end; + if result <> 0 then begin + break; + end; + end + else begin + if not getfieldflag(@l^.header.fielddata.nullmask,fieldindex) then begin + if not getfieldflag(@r^.header.fielddata.nullmask,fieldindex) then begin + continue; + end + else begin + dec(result); + end; + end + else begin + if not getfieldflag(@r^.header.fielddata.nullmask,fieldindex) then begin + inc(result); + end + else begin + result:= comparefunc((pchar(l)+recoffset)^,(pchar(r)+recoffset)^); + end; + end; + if (result <> 0) then begin + if apartialstring and canpartialstring and (int1 = alastindex) then begin + if caseinsensitive then begin + result:= msepartialcomparetext(pmsestring(pointer(pchar(l)+recoffset))^, + pmsestring(pointer(pchar(r)+recoffset))^); + end + else begin + result:= msepartialcomparestr(pmsestring(pointer(pchar(l)+recoffset))^, + pmsestring(pointer(pchar(r)+recoffset))^); + end; + end; + if desc then begin + result:= -result; + end; + break; + end; + end; + end; + end; + if lio_desc in foptions then begin + result:= -result; + end; +end; + +function tlocalindex.compare1a(l,r: pintrecordty; const alastindex: integer; + const apartialstring: boolean): integer; + //l is compare value, r can be lookup +var + int1: integer; + po1: pointer; +begin + result:= 0; + for int1:= 0 to alastindex do begin + with findexfieldinfos[int1] do begin + if islookup then begin + po1:= nil; + if getfieldflag(pointer(l)+tmsebufdataset(fowner).frecordsize, + -2-fieldindex) then begin + po1:= pointer(l) + recoffset; + end; + result:= dolookupcomparea(po1,r,findexfieldinfos[int1], + apartialstring and canpartialstring and (int1 = alastindex)); + if desc then begin + result:= -result; + end; + if result <> 0 then begin + break; + end; + end + else begin + if not getfieldflag(@l^.header.fielddata.nullmask,fieldindex) then begin + if not getfieldflag(@r^.header.fielddata.nullmask,fieldindex) then begin + continue; + end + else begin + dec(result); + end; + end + else begin + if not getfieldflag(@r^.header.fielddata.nullmask,fieldindex) then begin + inc(result); + end + else begin + result:= comparefunc((pchar(l)+recoffset)^,(pchar(r)+recoffset)^); + end; + end; + if (result <> 0) then begin + if apartialstring and canpartialstring and (int1 = alastindex) then begin + if caseinsensitive then begin + result:= msepartialcomparetext(pmsestring(pointer(pchar(l)+recoffset))^, + pmsestring(pointer(pchar(r)+recoffset))^); + end + else begin + result:= msepartialcomparestr(pmsestring(pointer(pchar(l)+recoffset))^, + pmsestring(pointer(pchar(r)+recoffset))^); + end; + end; + if desc then begin + result:= -result; + end; + break; + end; + end; + end; + end; + if lio_desc in foptions then begin + result:= -result; + end; +end; + +function tlocalindex.compare2(l,r: pintrecordty): integer; +var + int1: integer; +begin + result:= 0; + for int1:= 0 to high(findexfieldinfos) do begin + with findexfieldinfos[int1] do begin + if islookup then begin + result:= dolookupcompare(l,r,findexfieldinfos[int1],false); + if desc then begin + result:= -result; + end; + if result <> 0 then begin + break; + end; + end + else begin + if not getfieldflag(@l^.header.fielddata.nullmask,fieldindex) then begin + if not getfieldflag(@r^.header.fielddata.nullmask,fieldindex) then begin + continue; + end + else begin + dec(result); + end; + end + else begin + if not getfieldflag(@r^.header.fielddata.nullmask,fieldindex) then begin + inc(result); + end + else begin + result:= comparefunc((pchar(l)+recoffset)^,(pchar(r)+recoffset)^); + end; + end; + if desc then begin + result:= -result; + end; + if result <> 0 then begin + break; + end; + end; + end; + end; + if lio_desc in foptions then begin + result:= -result; + end; +end; + +{$ifndef FPC} +function tlocalindex.compare3(l,r: pointer): integer; +begin + result:= compare2(l,r); +end; +{$endif} + +procedure tlocalindex.quicksort(l,r: integer); +var + i,j: integer; + p: integer; +// int1: integer; + po1: pintrecordty; +begin + repeat + i:= l; + j:= r; + p:= (l + r) shr 1; + repeat + while compare2(fsortarray^[i],fsortarray^[p]) < 0 do begin + inc(i); + end; + while compare2(fsortarray^[j],fsortarray^[p]) > 0 do begin + dec(j); + end; + if i <= j then begin + po1:= fsortarray^[i]; + fsortarray^[i]:= fsortarray^[j]; + fsortarray^[j]:= po1; + if p = i then begin + p:= j + end + else begin + if p = j then begin + p:= i; + end; + end; + inc(i); + dec(j); + end; + until i > j; + if l < j then begin + quicksort(l,j); + end; + l:= i; + until i >= r; +end; + +procedure tlocalindex.sort(var adata: pointerarty); +{$ifdef mse_debugdataset} +var + ts1: longword; +{$endif} +begin + if adata <> nil then begin +{$ifdef mse_debugdataset} + ts1:= timestamp; +{$endif} + if lio_quicksort in foptions then begin + fsortarray:= @adata[0]; + quicksort(0,tmsebufdataset(fowner).fbrecordcount - 1); + end + else begin + msearrayutils.mergesort(adata,tmsebufdataset(fowner).fbrecordcount, + {$ifdef FPC} + pointercomparemethodty(@compare2)); + {$else} + compare3); + {$endif} +// mergesort(adata); + end; + end; +{$ifdef mse_debugdataset} + debugoutend(ts1,tmsebufdataset(fowner),'Sort index '+ + inttostr(tmsebufdataset(fowner).findexlocal.indexof(self))); +{$endif} +end; + +function tlocalindex.findboundary(const comparefunc: indexcomparefuncty; + const arecord: pintrecordty; + const alastindex: integer; const abigger: boolean): integer; + //returns index of next bigger +var + int1: integer; + lo,up,pivot: integer; +begin + result:= 0; + with tmsebufdataset(fowner) do begin + int1:= findexlocal.indexof(self) + 1; + with findexes[int1] do begin + if fbrecordcount > 0 then begin + checkindex(int1); + int1:= 0; + lo:= 0; + up:= fbrecordcount - 1; + if abigger then begin + while lo <= up do begin + pivot:= (up + lo) div 2; + int1:= comparefunc(arecord,ind[pivot],alastindex,false); + if int1 >= 0 then begin //pivot <= rev + lo:= pivot + 1; + end + else begin + up:= pivot; + if up = lo then begin + break; + end; + end; + end; + result:= lo; + end + else begin + while lo <= up do begin + pivot:= (up + lo + 1) div 2; + int1:= comparefunc(arecord,ind[pivot],alastindex,false); + if int1 <= 0 then begin //pivot >= rev + up:= pivot - 1; + end + else begin + lo:= pivot; + if up = lo then begin + break; + end; + end; + end; + result:= up; + end; + end; + end; + end; +end; + +function tlocalindex.findrecord(const arecord: pintrecordty): integer; +var + int1: integer; + po1: ppointeraty; +begin + result:= -1; + int1:= findboundary(@compare1,arecord,high(findexfieldinfos),true) - 1; + with tmsebufdataset(fowner) do begin + po1:= pointer(findexes[findexlocal.indexof(self) + 1].ind); + end; + for int1:= int1 downto 0 do begin + if po1^[int1] = arecord then begin + result:= int1; + break; + end; + end; +end; + +function tlocalindex.getactive: boolean; +begin + with tmsebufdataset(fowner) do begin + result:= actindex = findexlocal.indexof(self) + 1; + end; +end; + +procedure tlocalindex.setactive(const avalue: boolean); +var + int1: integer; +begin + with tmsebufdataset(fowner) do begin + int1:= findexlocal.indexof(self) + 1; + if avalue then begin + if actindex <> int1 then begin + actindex:= int1; + tmsebufdataset(fowner).findexlocal.doindexchanged; + end; + end + else begin + if actindex = int1 then begin + actindex:= 0; + tmsebufdataset(fowner).findexlocal.doindexchanged; + end; + end; + end; +end; + +procedure tlocalindex.bindfields; +var + int1: integer; + field1: tfield; + kind1: fieldcomparekindty; +begin + setlength(findexfieldinfos,ffields.count); + fhaslookup:= false; + with tmsebufdataset(fowner) do begin + for int1:= 0 to high(findexfieldinfos) do begin + with ffields.items[int1],findexfieldinfos[int1] do begin + field1:= findfield(fieldname); + if field1 = nil then begin + databaseerror('Index field "'+fieldname+'" not found.', + tmsebufdataset(self.fowner)); + end; + fieldinstance:= field1; + with field1 do begin + if not((fieldkind in [fkdata,fkinternalcalc]) or + (fieldkind = fklookup) and + (flookupfieldinfos[-1-fieldno].indexnum >= 0)) or + not (datatype in indexfieldtypes) then begin + databaseerror('Invalid index field "'+fieldname+'".', + tmsebufdataset(self.fowner)); + end; + islookup:= fieldkind = fklookup; + fhaslookup:= fhaslookup or islookup; + for kind1:= low(fieldcomparekindty) to high(fieldcomparekindty) do begin + with comparefuncs[kind1] do begin + if datatype in datatypes then begin + vtype:= cvtype; + if ifo_caseinsensitive in options then begin + if ifo_natural in options then begin + comparefunc:= compfuncin; + end + else begin + comparefunc:= compfunci; + end; + end + else begin + if ifo_natural in options then begin + comparefunc:= compfuncn; + end + else begin + comparefunc:= compfunc; + end; + end; + break; + end; + end; + end; + fieldindex:= fieldno - 1; + if fieldindex >= 0 then begin + recoffset:= ffieldinfos[fieldindex].base.offset + intheadersize; + end + else begin + recoffset:= offset; //calc field + flookupfieldinfos[-2-fieldindex].hasindex:= true; + end; + desc:= ifo_desc in foptions; + caseinsensitive:= ifo_caseinsensitive in foptions; + canpartialstring:= vtype = {$ifdef mse_hasvtunicodestring}vtunicodestring + {$else}vtwidestring{$endif}; + end; + end; + end; + end; +end; + +procedure paramerror(const amessage: msestring = ''); +var + mstr1: msestring; +begin + mstr1:= 'Invalid find parameters.'; + if amessage <> '' then begin + mstr1:= mstr1 + lineend+amessage; + end; + databaseerror(ansistring(mstr1)); +end; + +function tlocalindex.find(const avalues: array of const; + const aisnull: array of boolean; out abookmark: bookmarkdataty; + const abigger: boolean = false; + const partialstring: boolean = false; + const nocheckbrowsemode: boolean = false; + const filtered: boolean = false): boolean; +var + int1: integer; +// v: tvarrec; + po1: pintrecordty; + po2: pointer; + bo1: boolean; + lastind: integer; + calcfieldpo: pointer; + b1,b2: boolean; + state1: tdatasetstate; + +label + endlab; +begin + if not nocheckbrowsemode and ([bs1_posting,bs1_recordupdating] * + tmsebufdataset(fowner).fbstate1 = []) then begin + tmsebufdataset(fowner).checkbrowsemode; + end; + lastind:= high(avalues); + if lastind > high(findexfieldinfos) then begin + paramerror; + end; + for int1:= lastind downto 0 do begin + if (avalues[int1].vtype <> vtpointer) and + (avalues[int1].vtype <> findexfieldinfos[int1].vtype) then begin + paramerror(msestring(tmsebufdataset(fowner).name)+ + 'field '+ msestring(findexfieldinfos[int1].fieldinstance.fieldname)+ + ' wanted vtype: '+ inttostrmse(findexfieldinfos[int1].vtype)+ + ' actual vtype: '+ inttostrmse(avalues[int1].vtype)); + end; + end; +// po1:= tmsebufdataset(fowner).intallocrecord; + po1:= allocmem(tmsebufdataset(fowner).fcalcrecordsize+intheadersize); + calcfieldpo:= pointer(po1) + tmsebufdataset(fowner).frecordsize; + b1:= false; + try + for int1:= lastind downto 0 do begin + with findexfieldinfos[int1],avalues[int1] do begin + po2:= pchar(po1) + recoffset; + bo1:= false; + case vtype of + vtinteger: begin + pinteger(po2)^:= vinteger; + end; + {$ifdef mse_hasvtunicodestring}vtunicodestring + {$else}vtwidestring{$endif}: begin + ppointer(po2)^:= {$ifdef mse_hasvtunicodestring}vunicodestring + {$else}vwidestring{$endif}; + end; + vtextended: begin + pdouble(po2)^:= vextended^; + bo1:= pdouble(po2)^ = emptyreal; + end; + vtcurrency: begin + pcurrency(po2)^:= vcurrency^; + end; + vtboolean: begin + pwordbool(po2)^:= vboolean; + end; + vtint64: begin + pint64(po2)^:= vint64^; + end; + vtpointer: begin + bo1:= true; + end; + mse_vtguid: begin + pguid(po2)^:= pguid(vpointer)^; + end; + else begin + paramerror; + end; + end; + if int1 <= high(aisnull) then begin + bo1:= bo1 or aisnull[int1]; + end; + if fieldindex < 0 then begin //calcfields + if not bo1 then begin + setfieldflag(calcfieldpo,-2-fieldindex); + end + else begin + clearfieldflag(calcfieldpo,-2-fieldindex); + //buffer is not initialised + end; + end + else begin + if not bo1 then begin + setfieldflag(@po1^.header.fielddata.nullmask,fieldindex); + end + else begin + clearfieldflag(@po1^.header.fielddata.nullmask,fieldindex); + //buffer is not initialised + end; + end; + end; + end; + int1:= findboundary(@compare1a,po1,lastind,abigger); + result:= false; + abookmark.recordpo:= nil; + abookmark.recno:= -1; + b1:= filtered; + with tmsebufdataset(fowner) do begin + b1:= b1 and filtered and assigned(fonfilterrecord); + if b1 then begin + state1:= settempstate(tdatasetstate(dscheckfilter)); + end; + with findexes[findexlocal.indexof(self) + 1] do begin + if abigger then begin + if int1 < 0 then begin + goto endlab; + end; + if b1 then begin + dec(int1); + b2:= false; + while int1 >= 0 do begin //find next filtered record + if compare1a(po1,ind[int1],lastind,partialstring) <> 0 then begin + break; + end; + fcheckfilterbuffer:= ind[int1] - sizeof(dsheaderty); + b2:= true; + onfilterrecord(tmsebufdataset(fowner),b2); + if b2 then begin + break; + end; + dec(int1); + end; + inc(int1); + if not b2 then begin //no exact found + while int1 < fbrecordcount do begin + fcheckfilterbuffer:= ind[int1] - sizeof(dsheaderty); + b2:= true; + onfilterrecord(tmsebufdataset(fowner),b2); + if b2 then begin + break; + end; + inc(int1); + end; + end; + if not b2 then begin + goto endlab; //no bigger found + end; + end; + if (int1 > 0) and (compare1a(po1,ind[int1-1],lastind,false) = 0) then begin + result:= true; + dec(int1); + end; + end + else begin + if b1 then begin + inc(int1); + b2:= false; + while int1 < fbrecordcount do begin //find next filtered record + if compare1a(po1,ind[int1],lastind,partialstring) <> 0 then begin + break; + end; + fcheckfilterbuffer:= ind[int1] - sizeof(dsheaderty); + b2:= true; + onfilterrecord(tmsebufdataset(fowner),b2); + if b2 then begin + break; + end; + inc(int1); + end; + dec(int1); + if not b2 then begin //no exact found + while int1 >= 0 do begin + fcheckfilterbuffer:= ind[int1] - sizeof(dsheaderty); + b2:= true; + onfilterrecord(tmsebufdataset(fowner),b2); + if b2 then begin + break; + end; + dec(int1); + end; + end; + if not b2 then begin + goto endlab; //no lower found + end; + end; + if int1 >= fbrecordcount - 1 then begin + if partialstring and (int1 > 0) and (int1 = fbrecordcount - 1) then begin + result:= compare1a(po1,ind[int1],lastind,true) = 0; + end; + if not result then begin + goto endlab; + end; + end; + if not result then begin + if compare1a(po1,ind[int1+1],lastind,false) = 0 then begin + result:= true; + inc(int1); + end; + end; + end; + if (int1 >= -1) and (int1 < fbrecordcount) then begin + if not result then begin + if partialstring then begin + if int1 >= 0 then begin + result:= compare1a(po1,ind[int1],lastind,true) = 0; + end; + if not result then begin + inc(int1); + if (int1 >= fbrecordcount) or + (compare1a(po1,ind[int1],lastind,true) <> 0) then begin + dec(int1,2); //for reversed order + if (int1 < 0) or + (compare1a(po1,ind[int1],lastind,true) <> 0) then begin + dec(int1); + if (int1 < 0) or + (compare1a(po1,ind[int1],lastind,true) <> 0) then begin + inc(int1,2); + end + else begin + result:= true; + end; + end + else begin + result:= true; + end; + end + else begin + result:= true; + end; + end; + end + else begin + if int1 < 0 then begin + goto endlab; + end; + end; + end; + b2:= true; + if b1 then begin + fcheckfilterbuffer:= ind[int1] - sizeof(dsheaderty); + onfilterrecord(tmsebufdataset(fowner),b2); + result:= result and b2; + end; + if b2 then begin + abookmark.recno:= int1; + abookmark.recordpo:= ind[int1]; + end; + end; + end; + end; +endlab: + finally + if b1 then begin + tmsebufdataset(fowner).restorestate(state1); + end; + freemem(po1); + end; +end; + +{$ifndef FPC} +function tlocalindex.findval(const avalues: array of const; + const aisnull: array of boolean; out abookmark: bookmarkdataty; + const abigger: boolean = false; + const partialstring: boolean = false; + const nocheckbrowsemode: boolean = false): boolean; +begin + result:= find(avalues,aisnull,abookmark,abigger,partialstring,nocheckbrowsemode); +end; +{$endif} + +function tlocalindex.find(const avalues: array of const; const aisnull: array of boolean; + //itemcount of avalues can be smaller than fields count in index + out abookmark: string; + const abigger: boolean = false; + const partialstring: boolean = false; + const nocheckbrowsemode: boolean = false; + const filtered: boolean = false): boolean; + //true if found else nearest lower or bigger, + //abookmark = '' if no lower or bigger found + //string values must be msestring +var + bm1: bookmarkdataty; +begin + result:= find(avalues,aisnull,bm1,abigger,partialstring, + nocheckbrowsemode,filtered); + abookmark:= tmsebufdataset(fowner).bookmarkdatatobookmark(bm1); +end; + +function tlocalindex.find(const avalues: array of const; + const aisnull: array of boolean; + const abigger: boolean = false; const partialstring: boolean = false; + const nocheckbrowsemode: boolean = false; + const exact: boolean = true; + const filtered: boolean = true): boolean; + //sets dataset cursor if found +var + str1: string; +begin + result:= find(avalues,aisnull,str1,abigger,partialstring, + nocheckbrowsemode,filtered); + if result or not exact then begin + tmsebufdataset(fowner).bookmark:= str1; + end; +end; + +function tlocalindex.find(const avalues: array of tfield; + const abigger: boolean = false; + const partialstring: boolean = false; + const nocheckbrowsemode: boolean = false; + const exact: boolean = true; + const filtered: boolean = true): boolean; + //sets dataset cursor if found +var + str1: string; +begin + result:= find(avalues,str1,abigger,partialstring, + nocheckbrowsemode,filtered); + if result or not exact then begin + tmsebufdataset(fowner).bookmark:= str1; + end; +end; + +function tlocalindex.findvariant(const avalue: array of variant; + //nil -> NULL field + //itemcount of avalues + //can be smaller than fields count in index + //itemcount of aisnull can be smaller than itemcount of avalues + out abookmark: string; + const abigger: boolean = false; + const partialstring: boolean = false; + const nocheckbrowsemode: boolean = false; + const filtered: boolean = false): boolean; + //true if found else nearest lower or bigger, + //abookmark = '' if no lower or bigger found + //string values must be msestring +var + int1: integer; + vt1: tvartype; + ar1: array of tvarrec; + ar2: msestringarty; + ar3: array of extended; +begin + setlength(ar1,length(avalue)); + setlength(ar2,length(avalue)); + setlength(ar3,length(avalue)); + for int1:= 0 to high(avalue) do begin + with ar1[int1] do begin + if varisnull(avalue[int1]) then begin + vtype:= vtpointer; + // result:= find([nil],[],abigger,partialstring,nocheckbrowsemode); + end + else begin + vt1:= vartype(avalue[int1]); + if vt1 in ordinalvartypes then begin + if vt1 = varint64 then begin + vtype:= vtint64; + vint64:= @tvardata(avalue[int1]).vint64; + end + else begin + if vt1 = varboolean then begin + vtype:= vtboolean; + vboolean:= avalue[int1]; + end + else begin + vtype:= vtinteger; + vinteger:= avalue[int1]; + end; + end; + end + else begin + case vt1 of + varcurrency: begin + vtype:= vtcurrency; + vcurrency:= @tvardata(avalue[int1]).vcurrency; + end; + varsingle,vardouble,vardate: begin + vtype:= vtextended; + ar3[int1]:= avalue[int1]; + vextended:= @ar3[int1]; + end; + varstring,varolestr: begin + vtype:= {$ifdef mse_hasvtunicodestring}vtunicodestring + {$else}vtwidestring{$endif}; + ar2[int1]:= avalue[int1]; + {$ifdef mse_hasvtunicodestring}vunicodestring + {$else}vwidestring{$endif}:= pointer(ar2[int1]); + end + else begin + paramerror; + end; + end; + end; + end; + end; + end; + result:= find(ar1,[],abookmark,abigger,partialstring, + nocheckbrowsemode,filtered); +end; + +function tlocalindex.findvariant(const avalue: array of variant; + const abigger: boolean = false; + const partialstring: boolean = false; + const nocheckbrowsemode: boolean = false; + const exact: boolean = true; + const filtered: boolean = true): boolean; + //sets dataset cursor if found +var + str1: string; +begin + result:= findvariant(avalue,str1,abigger,partialstring, + nocheckbrowsemode,filtered); + if result or not exact then begin + tmsebufdataset(fowner).bookmark:= str1; //ignores '' + end; +end; + +function tlocalindex.find(const avalues: array of tfield; + out abookmark: bookmarkdataty; + const abigger: boolean = false; + const partialstring: boolean = false; + const nocheckbrowsemode: boolean = false; + const filtered: boolean = false): boolean; + //true if found else nearest lower or bigger, + //abookmark = '' if no lower or bigger found +var + mstr1: msestring; + str1: string; + consts1: array of tvarrec; + isnull1: array of boolean; + field1: tfield; + int1: integer; + rea1: extended; + cur1: currency; + lint1: int64; + id1: tguid; + +begin + setlength(consts1,length(avalues)); + setlength(isnull1,length(avalues)); + for int1:= 0 to high(avalues) do begin + field1:= avalues[int1]; + with field1,consts1[int1] do begin + if isnull then begin + isnull1[int1]:= true; + end; + if field1 is tmsestringfield then begin + mstr1:= tmsestringfield(field1).asmsestring; + vtype:= {$ifdef mse_hasvtunicodestring}vtunicodestring + {$else}vtwidestring{$endif}; + {$ifdef mse_hasvtunicodestring}vunicodestring + {$else}vwidestring{$endif}:= pointer(mstr1); + end + else begin + case datatype of + ftString,ftFixedChar,ftmemo,ftblob: begin + str1:= asstring; + vtype:= vtansistring; + vansistring:= pointer(str1); + end; + ftSmallint,ftInteger,ftWord: begin + vtype:= vinteger; + vinteger:= asinteger; + end; + ftBoolean: begin + vboolean:= asboolean; + vtype:= vtboolean + end; + ftFloat,ftcurrency,ftDate,ftTime,ftDateTime,ftTimeStamp,ftFMTBcd: begin + rea1:= asfloat; + vtype:= vtextended; + vextended:= @rea1; + end; + ftBCD: begin + cur1:= ascurrency; + vtype:= vtcurrency; + vcurrency:= @cur1; + end; + ftguid: begin + id1:= asguid; + vtype:= mse_vtguid; + vpointer:= @id1; + end; + ftWideString: begin + mstr1:= aswidestring; + vtype:= {$ifdef mse_hasvtunicodestring}vtunicodestring + {$else}vtwidestring{$endif}; + {$ifdef mse_hasvtunicodestring}vunicodestring + {$else}vwidestring{$endif}:= pointer(mstr1); + end; + ftLargeint: begin + lint1:= aslargeint; + vtype:= vtint64; + vint64:= @lint1; + end; + end; + end; + end; + end; + result:= find(consts1,isnull1,abookmark,abigger,partialstring, + nocheckbrowsemode,filtered); +end; + +function tlocalindex.find(const avalues: array of tfield; + out abookmark: string; + const abigger: boolean = false; + const partialstring: boolean = false; + const nocheckbrowsemode: boolean = false; + const filtered: boolean = false): boolean; + //true if found else nearest lower or bigger, + //abookmark = '' if no lower or bigger found +var + bm: bookmarkdataty; +begin + result:= find(avalues,bm,abigger,partialstring,nocheckbrowsemode,filtered); + abookmark:= tmsebufdataset(fowner).bookmarkdatatobookmark(bm); +end; + +function tlocalindex.unique(const avalues: array of const): boolean; +var + bm1: bookmarkdataty; +begin + result:= not find(avalues,[],bm1,false,false,true) or + (bm1.recordpo = tmsebufdataset(fowner).bookmarkdata.recordpo); +end; + +procedure tlocalindex.deleteduplicates(); +var + i1,i2: int32; + po1,po2: pointer; + ar1: pointerarty; +begin + with tmsebufdataset(fowner) do begin + checkbrowsemode(); + disablecontrols(); + try + i1:= findexlocal.indexof(self) + 1; + checkindex(i1); + ar1:= findexes[i1].ind; + i2:= 1; + while i2 < fbrecordcount do begin + po1:= ar1[i2-1]; + po2:= ar1[i2]; + while (compare2(po1,po2) = 0) and (i2 < fbrecordcount) do begin + deleterecord(po2); + intfreerecord(po2); + po2:= ar1[i2]; + end; + inc(i2); + end; + finally + frecno:= 0; + if fbrecordcount = 0 then begin + frecno:= -1; + end; + resync([]); + enablecontrols(); + end; + end; +end; + +function tlocalindex.getbookmark(const arecno: integer): bookmarkty; +var + int1: integer; + bm1: bookmarkdataty; +begin + with tmsebufdataset(fowner) do begin + checkrecno(arecno); + int1:= findexlocal.indexof(self) + 1; + checkindex(int1); + bm1.recno:= arecno - 1; + bm1.recordpo:= findexes[int1].ind[arecno-1]; + result:= bookmarkdatatobookmark(bm1); + end; +end; + +function tlocalindex.getdesc: boolean; +begin + result:= lio_desc in foptions; +end; + +procedure tlocalindex.setdesc(const avalue: boolean); +begin + if avalue then begin + options:= options + [lio_desc]; + end + else begin + options:= options - [lio_desc]; + end; +end; + +function tlocalindex.getdefault: boolean; +begin + result:= lio_default in foptions; +end; + +procedure tlocalindex.setdefault(const avalue: boolean); +begin + if avalue then begin + options:= options + [lio_default]; + end + else begin + options:= options - [lio_default]; + end; +end; + +{ tindexfields } + +constructor tindexfields.create(const aowner: tlocalindex); +begin + inherited create(aowner,tindexfield); + count:= 1; +end; + +class function tindexfields.getitemclasstype: persistentclassty; +begin + result:= tindexfield; +end; + +function tindexfields.getitems(const index: integer): tindexfield; +begin + result:= tindexfield(inherited items[index]); +end; + +{ tindexfield } + +procedure tindexfield.change; +begin + tlocalindex(fowner).change; +end; + +procedure tindexfield.setfieldname(const avalue: string); +begin + ffieldname:= avalue; + change; +end; + +procedure tindexfield.setoptions(const avalue: indexfieldoptionsty); +begin + if foptions <> avalue then begin + foptions:= avalue; + change; + end; +end; + +{ ecurrentvalueaccess } + +constructor ecurrentvalueaccess.create(const adataset: tdataset; + const afield: tfield; const msg: string); +begin + inherited create('Current value access: '+msg+lineend+ + 'Dataset: '+adataset.name+' Field: '+ afield.fieldname); +end; + +end. diff --git a/mseide-msegui/lib/common/db/msedatabase.pas b/mseide-msegui/lib/common/db/msedatabase.pas new file mode 100644 index 0000000..4d329b6 --- /dev/null +++ b/mseide-msegui/lib/common/db/msedatabase.pas @@ -0,0 +1,1170 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 1999-2000 by Michael Van Canneyt, member of the + Free Pascal development team + + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Modified 2007-2013 by Martin Schreiber + + **********************************************************************} + +unit msedatabase; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +interface +uses + classes,mclasses,mdb,sysutils,msedb,msestrings,mseclasses,mseglob,msetypes, + mseapplication,mseinterfaces; + +type + databaseoptionty = + (dbo_utf8,dbo_noutf8,dbo_utf8message, + dbo_bcdtofloatif //use ftFloat for scale > 4 instead ftBCD + ); + databaseoptionsty = set of databaseoptionty; + + tmdbdataset = class; + tmdatabase = class; + tmdbtransaction = class; + + idbclient = interface(inullinterface) + function getcomponentinstance: tcomponent; + function getname: ansistring; + function getactive: boolean; + procedure setactive(avalue: boolean); + function gettransaction: tmdbtransaction; + function getrecno: integer; + procedure setrecno(value: integer); + procedure disablecontrols; + procedure enablecontrols; + function moveby(distance: longint): longint; + end; + + savepointeventkindty = (spek_begin,spek_release,spek_rollback, + spek_committrans,spek_rollbacktrans); + + itransactionclient = interface(idbclient) + procedure settransaction(const avalue: tmdbtransaction); + procedure settransactionwrite(const avalue: tmdbtransaction); +// function getwritetransaction: tmbtransaction; +// function getactive: boolean; + procedure checkbrowsemode; + procedure refreshtransaction; +// function getcomponentinstance: tcomponent; + procedure savepointevent(const sender: tmdbtransaction; + const akind: savepointeventkindty; const alevel: integer); + end; + itransactionclientarty = array of itransactionclient; + pitransactionclientarty = ^itransactionclientarty; + + idatabaseclient = interface(idbclient) + procedure setdatabase(const sender: tmdatabase); +/// procedure setactive(avalue: boolean); + end; + idatabaseclientarty = array of idatabaseclient; + +// tmdbtransactionClass = class of tmdbtransaction; + tmdbtransaction = class(TComponent) + Private + FActive : boolean; + FDatabase : tmdatabase; + FOpenAfterRead : boolean; +// Function GetDataSetCount : Longint; +// Function GetDataset(Index : longint) : tmdbdataset; + fopencount: integer; + procedure RegisterDataset (const DS: itransactionclient; const awrite: boolean); + procedure UnRegisterDataset(const DS: itransactionclient; const awrite: boolean); + procedure RemoveDataSets; + procedure SetActive(Value : boolean); + Protected +// FDataSets : TList; +// fcloselock: integer; + fdatasets: itransactionclientarty; + fdatasetsactive: booleanarty; + fwritedatasets: itransactionclientarty; + fwritedatasetsactive: booleanarty; + Procedure SetDatabase (Value : tmdatabase); virtual; + procedure CloseTrans; virtual; + procedure openTrans; + Procedure CheckDatabase; + Procedure CheckActive; + Procedure CheckInactive; + procedure EndTransaction; virtual; abstract; + procedure StartTransaction; virtual; abstract; + procedure finalizetransaction; virtual; + //called on connection closing + procedure InternalHandleException; virtual; + procedure Loaded; override; + procedure begintrackactivestate; + procedure endtrackactivestate; + Public + constructor Create(AOwner: TComponent); override; + Destructor destroy; override; + procedure CloseDataSets; + procedure refreshdatasets(const awrite: boolean = true; + const aread: boolean = true); +// procedure refresh; //closes transaction and reopens datasets + Property DataBase : tmdatabase Read FDatabase Write SetDatabase; + property datasets: itransactionclientarty read fdatasets; + property writedatasets: itransactionclientarty read fdatasets; + property opencount: integer read fopencount; //increments on every open + published + property Active : boolean read FActive write setactive; + end; + + TLoginEvent = procedure(Sender: TObject; Username, Password: string) of object; + + TCustomConnection = class(TComponent) + private +// FAfterConnect: TNotifyEvent; +// FAfterDisconnect: TNotifyEvent; +// FBeforeConnect: TNotifyEvent; +// FBeforeDisconnect: TNotifyEvent; +// FLoginPrompt: Boolean; +// FOnLogin: TLoginEvent; + FStreamedConnected: Boolean; +// procedure SetAfterConnect(const AValue: TNotifyEvent); +// procedure SetAfterDisconnect(const AValue: TNotifyEvent); +// procedure SetBeforeConnect(const AValue: TNotifyEvent); +// procedure SetBeforeDisconnect(const AValue: TNotifyEvent); + fwaitcursor: boolean; + factioncount: integer; + procedure setwaitcursor(const avalue: boolean); + protected + //iactivatorclient + procedure setactive(const avalue: boolean); virtual; + procedure DoConnect; virtual; + procedure DoDisconnect; virtual; + function GetConnected : boolean; virtual; + Function GetDataset(Index : longint) : TDataset; virtual; +// Function GetDataSetCount : Longint; virtual; + procedure InternalHandleException; virtual; + procedure Loaded; override; + procedure SetConnected (const avalue : boolean); virtual; + public + procedure Close; + destructor Destroy; override; + procedure Open; + procedure beforeaction; + procedure afteraction; +// property DataSetCount: Longint read GetDataSetCount; +// property DataSets[Index: Longint]: TDataSet read GetDataSet; + published + property Connected: Boolean read GetConnected write SetConnected; + property waitcursor: boolean read fwaitcursor + write setwaitcursor default false; +// property LoginPrompt: Boolean read FLoginPrompt write FLoginPrompt; +// property Streamedconnected: Boolean read FStreamedConnected write FStreamedConnected; + +// property AfterConnect : TNotifyEvent read FAfterConnect write fafterconnect; +// property AfterDisconnect : TNotifyEvent read FAfterDisconnect write fAfterDisconnect; +// property BeforeConnect : TNotifyEvent read FBeforeConnect write fBeforeConnect; +// property BeforeDisconnect : TNotifyEvent read FBeforeDisconnect write fBeforeDisconnect; +// property OnLogin: TLoginEvent read FOnLogin write FOnLogin; + end; + + isqlpropertyeditor = interface(inullinterface)[miid_isqlpropertyeditor] + procedure setactive(avalue: boolean); + function getactive: boolean; + function getdatabase: tcustomconnection; + function isutf8: boolean; + end; + + databaseeventty = procedure(const sender: tmdatabase) of object; + databaseerroreventty = procedure(const sender: tmdatabase; + const aexception: exception; var handled: boolean) of object; + + // tmdatabaseClass = Class Of tmdatabase; + tmdatabase = class(TCustomConnection) + private +// FDataSets : TList; + fdatasets: idatabaseclientarty; + FTransactions : TList; + FDirectory : String; + FKeepConnection : Boolean; + FParams : TStringlist; + FSQLBased : Boolean; + fonbeforeconnect: databaseeventty; + fonconnecterror: databaseerroreventty; + fonafterconnect: databaseeventty; + fonbeforedisconnect: databaseeventty; + fonafterdisconnect: databaseeventty; + Function GetTransactionCount : Longint; + Function GetTransaction(Index : longint) : tmdbtransaction; +// procedure RegisterDataset (DS : tmdbdataset); + procedure RegisterDataset(const DS: idatabaseclient); + procedure RegisterTransaction (TA : tmdbtransaction); + procedure UnRegisterDataset(const DS: idatabaseclient); + procedure UnRegisterTransaction(TA : tmdbtransaction); + procedure RemoveDataSets; + procedure RemoveTransactions; + procedure setparams(const avalue: tstringlist); + protected + FDataBaseName : mseString; + FConnected : Boolean; + FOpenAfterRead : boolean; + procedure setconnected(const avalue: boolean); override; + Procedure CheckConnected; + Procedure CheckDisConnected; + procedure DoConnect; override; + procedure DoDisconnect; override; + procedure doafterinternalconnect; virtual; + procedure executeparams; virtual; + procedure dobeforeinternaldisconnect; virtual; + function GetConnected : boolean; override; +// Function GetDataset(Index : longint) : TDataset; override; +// Function GetDataSetCount : Longint; override; + Procedure DoInternalConnect; Virtual;Abstract; + Procedure DoInternalDisConnect; Virtual;Abstract; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + procedure CloseDataSets; + procedure CloseTransactions; +// procedure ApplyUpdates; + procedure StartTransaction; virtual; abstract; + procedure EndTransaction; virtual; abstract; + property TransactionCount: Longint read GetTransactionCount; + property Transactions[Index: Longint]: tmdbtransaction read GetTransaction; + property Directory: string read FDirectory write FDirectory; + property IsSQLBased: Boolean read FSQLBased; + property datasets: idatabaseclientarty read fdatasets; + published + property Connected: Boolean read FConnected write SetConnected default false; + property DatabaseName: msestring read FDatabaseName write FDatabaseName; + property KeepConnection: Boolean read FKeepConnection + write FKeepConnection default false; + property Params : TStringlist read FParams Write setparams; + property onbeforeconnect: databaseeventty read fonbeforeconnect + write fonbeforeconnect; + property onafterconnect: databaseeventty read fonafterconnect + write fonafterconnect; + property onconnecterror: databaseerroreventty read fonconnecterror + write fonconnecterror; + property onbeforedisconnect: databaseeventty read fonbeforedisconnect + write fonbeforedisconnect; + property onafterdisconnect: databaseeventty read fonafterdisconnect + write fonafterdisconnect; + end; + + tmdbdatasetClass = Class of tmdbdataset; + + tmdbdataset = Class(TDataset,idatabaseclient,itransactionclient) + private + protected + fdatabase : tmdatabase; + ftransaction : tmdbtransaction; + ftransactionwrite : tmdbtransaction; + procedure setdatabase (const value: tmdatabase); virtual; + //itransactionclient + procedure settransaction(const value: tmdbtransaction); virtual; + procedure settransactionwrite(const value: tmdbtransaction); virtual; +// procedure checkdatabase; + procedure savepointevent(const sender: tmdbtransaction; + const akind: savepointeventkindty; const alevel: integer); virtual; + //idbclient + function getcomponentinstance: tcomponent; + function getname: ansistring; + function gettransaction: tmdbtransaction; + procedure refreshtransaction; virtual; abstract; + public + destructor destroy; override; + property database : tmdatabase read fdatabase write setdatabase; + property transaction : tmdbtransaction read ftransaction write settransaction; + property transactionwrite : tmdbtransaction read ftransactionwrite + write settransactionwrite; + end; + + ttacontroller = class(tactivatorcontroller) + protected + procedure setowneractive(const avalue: boolean); override; + public + constructor create(const aowner: tmdbtransaction; + const aintf: iactivatorclient); + end; + + +procedure dosetdatabase(const sender: idatabaseclient; const avalue: tmdatabase; + var dest: tmdatabase); +procedure dosettransaction(const sender: itransactionclient; + const avalue: tmdbtransaction; var dest: tmdbtransaction; + const awrite: boolean); +procedure checkdatabase(const aname: ansistring; const adatabase: tmdatabase); +procedure checktransaction(const aname: ansistring; const atransaction: tmdbtransaction); +procedure checkinactive(const active: boolean; const aname: ansistring); +procedure checkactive(const active: boolean; const aname: ansistring); + +implementation +uses + {$ifdef FPC}dbconst{$else}dbconst_del{$endif},msefileutils,msearrayutils,msebits + {$ifndef FPC},classes_del{$endif}; + +procedure checkdatabase(const aname: ansistring; const adatabase: tmdatabase); +begin + if adatabase = nil then begin + raise edatabaseerror.create(aname+': '+serrdatabasenassigned); + end; +end; + +procedure checktransaction(const aname: ansistring; + const atransaction: tmdbtransaction); +begin + if atransaction = nil then begin + raise edatabaseerror.create(aname+': '+serrtransactionnset); + end; +end; + +procedure checkinactive(const active: boolean; const aname: ansistring); +begin + if active then begin + raise edatabaseerror.create(aname+': Component is active.'); + end; +end; + +procedure checkactive(const active: boolean; const aname: ansistring); +begin + if not active then begin + raise edatabaseerror.create(aname+': Component is not active.'); + end; +end; + +procedure dosetdatabase(const sender: idatabaseclient; const avalue: tmdatabase; + var dest: tmdatabase); +begin + if avalue <> dest then begin + if sender.getactive then begin + raise edatabaseerror.create('Database client "'+sender.getname+'" is active.'); + end; + if dest <> nil then begin + dest.unregisterdataset(sender); + end; + dest:= nil; + if avalue <> nil then begin + avalue.registerdataset(sender); + end; + dest:= avalue; + end; +end; + +procedure dosettransaction(const sender: itransactionclient; + const avalue: tmdbtransaction; var dest: tmdbtransaction; + const awrite: boolean); +begin + if avalue <> dest then begin + if not awrite and sender.getactive then begin + raise edatabaseerror.create('Transaction client "'+sender.getname+'" is active.'); + end; + if dest <> nil then begin + dest.unregisterdataset(sender,awrite); + dest.removefreenotification(sender.getcomponentinstance); + end; + dest:= nil; + if avalue <> nil then begin + avalue.registerdataset(sender,awrite); + avalue.freenotification(sender.getcomponentinstance); //used by IDE for namechange link + end; + dest:= avalue; + end; +end; + +{ tmdatabase } + +constructor tmdatabase.Create(AOwner: TComponent); +begin + inherited create(aowner); + fparams:= tstringlist.create; + ftransactions:= tlist.create; +end; + +destructor tmdatabase.Destroy; + +begin + removedatasets; //needs working connection for closing + removetransactions; + connected:= false; + ftransactions.free; + fparams.free; + inherited destroy; +end; + +procedure tmdatabase.doafterinternalconnect; +begin + fconnected:= true; + executeparams; +end; + +procedure tmdatabase.executeparams; +begin + //dummy +end; + +procedure tmdatabase.dobeforeinternaldisconnect; +begin + //dummy +end; + +procedure tmdatabase.setconnected(const avalue: boolean); +var +// int1: integer; + bo1: boolean; +begin + if avalue <> fconnected then begin + if avalue then begin + if csreading in componentstate then begin + fopenafterread:= true; + exit; + end + else begin + if assigned(onbeforeconnect) then begin + onbeforeconnect(self); + end; + try + dointernalconnect(); + doafterinternalconnect; + if assigned(onafterconnect) then begin + onafterconnect(self); + end; + except + on e: exception do begin + if assigned(onconnecterror) then begin + bo1:= false; + onconnecterror(self,e,bo1); + if not bo1 then begin + raise; + end + else begin + if not connected then begin + abort; + end; + end; + end + else begin + raise; + end; + end; + end; + end; + end + else begin + if csloading in componentstate then begin + fopenafterread := false; + end + else begin + if assigned(onbeforedisconnect) then begin + onbeforedisconnect(self); + end; + dobeforeinternaldisconnect; + closetransactions; + dointernaldisconnect; + fconnected:= avalue; + if assigned(onafterdisconnect) then begin + onafterdisconnect(self); + end; + end; + end; + end; +end; + +{procedure tmdatabase.setconnected(avalue: boolean); +var + bo1: boolean; +begin + if avalue <> connected then begin + if avalue then begin + if csreading in componentstate then begin + fstreamedconnected := true; + exit; + end + else begin + if assigned(fonbeforeconnect) then begin + fonbeforeconnect(self); + end; + try + doconnect; + if assigned(fonafterconnect) then begin + fonafterconnect(self); + end; + except + on e: exception do begin + if assigned(fonconnecterror) then begin + bo1:= false; + fonconnecterror(self,e,bo1); + if not bo1 then begin + raise; + end; + end; + end; + end; + end; + end + else begin + if assigned(fonbeforedisconnect) then begin + fonbeforedisconnect(self); + end; + dodisconnect; + if assigned(fonafterdisconnect) then begin + fonafterdisconnect(self); + end; + end; + end; +end; +} +Procedure tmdatabase.CheckConnected; + +begin + If Not Connected Then + DatabaseError(SNotConnected,Self); +end; + + +Procedure tmdatabase.CheckDisConnected; +begin + If Connected Then + DatabaseError(SConnected,Self); +end; + +procedure tmdatabase.DoConnect; +begin + DoInternalConnect; + FConnected := True; +end; + +procedure tmdatabase.DoDisconnect; +begin + Closedatasets; + Closetransactions; + DoInternalDisConnect; + if csloading in ComponentState then + FOpenAfterRead := false; + FConnected := False; +end; + +function tmdatabase.GetConnected: boolean; +begin + Result:= FConnected; +end; + +procedure tmdatabase.CloseDataSets; +var + int1: integer; +begin + int1:= high(fdatasets); + while int1 > 0 do begin + fdatasets[int1].setactive(false); + dec(int1); + if int1 > high(fdatasets) then begin + int1:= high(fdatasets); //could be destroyed + end; + end; +end; + +procedure tmdatabase.CloseTransactions; + +Var I : longint; + +begin + If Assigned(FTransactions) then begin + For I:=FTransactions.Count-1 downto 0 do begin + with tmdbtransaction(FTransactions[i]) do begin + try + EndTransaction; + except + end; + finalizetransaction; + end; + end; + end; +end; + +procedure tmdatabase.RemoveDataSets; +var + int1: integer; +begin + for int1:= high(fdatasets) downto 0 do begin + with fdatasets[int1] do begin + setactive(false); + setdatabase(nil); + end; + end; +end; + +procedure tmdatabase.RemoveTransactions; + +Var I : longint; + +begin + If Assigned(FTransactions) then begin + For I:=FTransactions.Count-1 downto 0 do begin + with tmdbtransaction(FTransactions[i]) do begin + setactive(false); + Database:=Nil; + end; + end; + end; +end; +{ +Function tmdatabase.GetDataSetCount : Longint; + +begin + If Assigned(FDatasets) Then + Result:=FDatasets.Count + else + Result:=0; +end; +} +Function tmdatabase.GetTransactionCount : Longint; + +begin + If Assigned(FTransactions) Then + Result:=FTransactions.Count + else + Result:=0; +end; +{ +Function tmdatabase.GetDataset(Index : longint) : TDataset; + +begin + If Assigned(FDatasets) then + Result:=TDataset(FDatasets[Index]) + else + begin + result := nil; + DatabaseError(SNoDatasets); + end; +end; +} +Function tmdatabase.GetTransaction(Index : longint) : tmdbtransaction; + +begin + If Assigned(FTransactions) then + Result:=tmdbtransaction(FTransactions[Index]) + else + begin + result := nil; + DatabaseError(SNoTransactions); + end; +end; + +procedure tmdatabase.RegisterDataset(const DS: idatabaseclient); +var + int1: integer; +begin + int1:= high(fdatasets); + if adduniqueitem(pointerarty(fdatasets),pointer(ds)) <= int1 then begin + DatabaseErrorFmt(SDatasetRegistered,[DS.getname]); + end; +end; + +procedure tmdatabase.RegisterTransaction (TA : tmdbtransaction); + +Var I : longint; + +begin + I:=FTransactions.IndexOf(TA); + If I=-1 then + FTransactions.Add(TA) + else + DatabaseErrorFmt(STransactionRegistered,[TA.Name]); +end; + +procedure tmdatabase.UnRegisterDataset(const DS: idatabaseclient); +begin + if removeitem(pointerarty(fdatasets),pointer(ds)) < 0 then begin + DatabaseErrorFmt(SNoDatasetRegistered,[DS.getName]); + end; +end; + +procedure tmdatabase.UnRegisterTransaction (TA : tmdbtransaction); + +Var I : longint; + +begin + I:=FTransactions.IndexOf(TA); + If I<>-1 then + FTransactions.Delete(I) + else + DatabaseErrorFmt(SNoTransactionRegistered,[TA.Name]); +end; + +procedure tmdatabase.setparams(const avalue: tstringlist); +begin + fparams.assign(avalue); +end; + +{ tmdbdataset } + +Procedure tmdbdataset.SetDatabase (const Value : tmdatabase); + +begin + dosetdatabase(idatabaseclient(self),value,fdatabase); +end; + +Procedure tmdbdataset.SetTransaction (const Value : tmdbtransaction); +begin + dosettransaction(itransactionclient(self),value,ftransaction,false); +end; + +procedure tmdbdataset.settransactionwrite(const value : tmdbtransaction); +begin + dosettransaction(itransactionclient(self),value,ftransactionwrite,true); +end; + +function tmdbdataset.getcomponentinstance: tcomponent; +begin + result:= self; +end; + +function tmdbdataset.getname: ansistring; +begin + result:= name; +end; + +function tmdbdataset.gettransaction: tmdbtransaction; +begin + result:= ftransaction; +end; + +Destructor tmdbdataset.Destroy; + +begin + Database:=Nil; + Transaction:=Nil; + transactionwrite:= nil; + Inherited; +end; + +procedure tmdbdataset.savepointevent(const sender: tmdbtransaction; + const akind: savepointeventkindty; const alevel: integer); +begin + //dummy +end; + +{ tmdbtransaction } + +procedure tmdbtransaction.SetActive(Value : boolean); +begin + if FActive and (not Value) then + EndTransaction + else if (not FActive) and Value then + if csreading in ComponentState then + begin + FOpenAfterRead := true; + exit; + end + else + StartTransaction; +end; + +procedure tmdbtransaction.Loaded; + +begin + inherited; + try + if FOpenAfterRead then SetActive(true); + except + if csDesigning in Componentstate then + InternalHandleException + else + raise; + end; +end; + +Procedure tmdbtransaction.InternalHandleException; + +begin + if assigned(classes.ApplicationHandleException) then + classes.ApplicationHandleException(self) + else + ShowException(ExceptObject,ExceptAddr); +end; + +Procedure tmdbtransaction.CheckActive; + +begin + If not FActive Then + DatabaseError(STransNotActive,Self); +end; + +Procedure tmdbtransaction.CheckInActive; + +begin + If FActive Then + DatabaseError(STransActive,Self); +end; + +Procedure tmdbtransaction.CloseTrans; + +begin + FActive := false; +end; + +procedure tmdbtransaction.opentrans; + +begin + inc(fopencount); + if fopencount = 0 then begin + inc(fopencount); + end; + factive := true; +end; + +Procedure tmdbtransaction.SetDatabase (Value : tmdatabase); + +begin + If Value<>FDatabase then + begin + CheckInactive; + If Assigned(FDatabase) then + FDatabase.UnregisterTransaction(Self); + If Value<>Nil Then + Value.RegisterTransaction(Self); + FDatabase:=Value; + end; +end; + +constructor tmdbtransaction.create(AOwner : TComponent); + +begin + inherited create(AOwner); +// FDatasets:=TList.Create; +end; + +Procedure tmdbtransaction.CheckDatabase; + +begin + If (FDatabase=Nil) then + DatabaseError(SErrNoDatabaseAvailable,Self) +end; + +procedure tmdbtransaction.CloseDataSets; +var + int1: integer; +begin +// if fcloselock = 0 then begin + for int1:= high(fdatasets) downto 0 do begin + fdatasets[int1].setactive(false); + end; +// for int1:= high(fwritedatasets) downto 0 do begin +// fwritedatasets[int1].setactive(false); +// end; +// end; +end; + +procedure tmdbtransaction.refreshdatasets(const awrite: boolean = true; + const aread: boolean = true); +var + int1: integer; +begin + if awrite then begin + for int1:= high(fwritedatasets) downto 0 do begin + with fwritedatasets[int1] do begin + if getactive then begin + refreshtransaction; + end; + end; + end; + end; + if aread then begin + for int1:= high(fdatasets) downto 0 do begin + with fdatasets[int1] do begin + if getactive then begin + refreshtransaction; + end; + end; + end; + end; +end; + +Destructor tmdbtransaction.Destroy; + +begin + active:= false; + RemoveDatasets; + Database:=Nil; +// FDatasets.Free; + Inherited; +end; + +procedure tmdbtransaction.RemoveDataSets; +var + int1: integer; +begin + for int1:= high(fwritedatasets) downto 0 do begin + fwritedatasets[int1].settransactionwrite(nil); + end; + for int1:= high(fdatasets) downto 0 do begin + fdatasets[int1].settransaction(nil); + end; +end; +{ +Function tmdbtransaction.GetDataSetCount : Longint; +begin + If Assigned(FDatasets) Then + Result:=FDatasets.Count + else + Result:=0; +end; +} +procedure tmdbtransaction.UnRegisterDataset(const DS: itransactionclient; + const awrite: boolean); +var + ar1: pitransactionclientarty; + ar2: pbooleanarty; + int1: integer; +begin + if awrite then begin + ar1:= @fwritedatasets; + ar2:= @fwritedatasetsactive; + end + else begin + ar1:= @fdatasets; + ar2:= @fdatasetsactive; + end; + int1:= removeitem(pointerarty(ar1^),pointer(ds)); + if int1 < 0 then begin + DatabaseErrorFmt(SNoDatasetRegistered,[DS.getName]); + end; + if int1 <= high(ar2^) then begin + deleteitem(ar2^,int1); + end; +end; + +procedure tmdbtransaction.RegisterDataset(const DS: itransactionclient; + const awrite: boolean); +var + int1: integer; + ar1: pitransactionclientarty; +begin + if awrite then begin + ar1:= @fwritedatasets; + end + else begin + ar1:= @fdatasets; + end; + int1:= high(ar1^); + if adduniqueitem(pointerarty(ar1^),pointer(ds)) <= int1 then begin + DatabaseErrorFmt(SDatasetRegistered,[DS.getname]); + end; +end; + +procedure tmdbtransaction.finalizetransaction; +begin + //dummy +end; + +procedure tmdbtransaction.begintrackactivestate; +var + int1: integer; +begin + setlength(fdatasetsactive,length(fdatasets)); + for int1:= high(fdatasetsactive) downto 0 do begin + fdatasetsactive[int1]:= fdatasets[int1].getactive; + end; + setlength(fwritedatasetsactive,length(fwritedatasets)); + for int1:= high(fwritedatasetsactive) downto 0 do begin + fwritedatasetsactive[int1]:= fwritedatasets[int1].getactive; + end; +end; + +procedure tmdbtransaction.endtrackactivestate; +begin + fdatasetsactive:= nil; + fwritedatasetsactive:= nil; +end; +{ +Function tmdbtransaction.GetDataset(Index : longint) : tmdbdataset; + +begin + If Assigned(FDatasets) then + Result:=tmdbdataset(FDatasets[Index]) + else + begin + result := nil; + DatabaseError(SNoDatasets); + end; +end; +} +{ TCustomConnection } +{ +procedure TCustomConnection.SetAfterConnect(const AValue: TNotifyEvent); +begin +// if FAfterConnect=AValue then exit; + FAfterConnect:=AValue; +end; +} +function TCustomConnection.GetDataSet(Index: Longint): TDataSet; +begin + Result := nil; +end; +{ +function TCustomConnection.GetDataSetCount: Longint; +begin + Result := 0; +end; +} +procedure TCustomConnection.InternalHandleException; +begin + if assigned(classes.ApplicationHandleException) then + classes.ApplicationHandleException(self) + else + ShowException(ExceptObject,ExceptAddr); +end; +{ +procedure TCustomConnection.SetAfterDisconnect(const AValue: TNotifyEvent); +begin +// if FAfterDisconnect=AValue then exit; + FAfterDisconnect:=AValue; +end; + +procedure TCustomConnection.SetBeforeConnect(const AValue: TNotifyEvent); +begin +// if FBeforeConnect=AValue then exit; + FBeforeConnect:=AValue; +end; +} +procedure TCustomConnection.SetConnected(const avalue: boolean); +begin + If aValue<>Connected then + begin + If aValue then + begin + if csReading in ComponentState then + begin + FStreamedConnected := true; + exit; + end + else + begin +// if Assigned(BeforeConnect) then +// BeforeConnect(self); +// if FLoginPrompt then if assigned(FOnLogin) then +// FOnLogin(self,'',''); + DoConnect; +// if Assigned(AfterConnect) then +// AfterConnect(self); + end; + end + else + begin +// if Assigned(BeforeDisconnect) then +// BeforeDisconnect(self); + DoDisconnect; +// if Assigned(AfterDisconnect) then +// AfterDisconnect(self); + end; + end; +end; + +procedure tcustomconnection.setactive(const avalue: boolean); +begin + connected:= avalue; +end; + +{ +procedure TCustomConnection.SetBeforeDisconnect(const AValue: TNotifyEvent); +begin +// if FBeforeDisconnect=AValue then exit; + FBeforeDisconnect:=AValue; +end; +} +procedure TCustomConnection.DoConnect; + +begin + // Do nothing yet +end; + +procedure TCustomConnection.DoDisconnect; + +begin + // Do nothing yet +end; + +function TCustomConnection.GetConnected: boolean; + +begin + Result := False; +end; + +procedure TCustomConnection.Loaded; +begin + inherited Loaded; + try + if FStreamedConnected then + SetConnected(true); + except + if csDesigning in Componentstate then + InternalHandleException + else + raise; + end; +end; + +procedure TCustomConnection.Close; +begin + Connected := False; +end; + +destructor TCustomConnection.Destroy; +begin + Connected:=False; + Inherited Destroy; +end; + +procedure TCustomConnection.Open; +begin + Connected := True; +end; + +procedure TCustomConnection.setwaitcursor(const avalue: boolean); +var + bo1: boolean; +begin + if avalue <> fwaitcursor then begin + bo1:= fwaitcursor; + fwaitcursor:= avalue; + if bo1 and (factioncount > 0) then begin + application.endwait; + end; + factioncount:= 0; + end; +end; + +procedure tcustomconnection.beforeaction; +begin + if waitcursor then begin + if interlockedincrement(factioncount) = 1 then begin + application.beginwait; + end; + end; +end; + +procedure tcustomconnection.afteraction; +begin + if waitcursor then begin + if interlockeddecrement(factioncount) = 0 then begin + application.endwait; + end; + end; +end; + + +{ ttacontroller } + +constructor ttacontroller.create(const aowner: tmdbtransaction; + const aintf: iactivatorclient); +begin + inherited create(aowner,aintf); +end; + +procedure ttacontroller.setowneractive(const avalue: boolean); +begin + tmdbtransaction(fowner).active:= avalue; +end; + +end. diff --git a/mseide-msegui/lib/common/db/msedb.pas b/mseide-msegui/lib/common/db/msedb.pas new file mode 100644 index 0000000..57dbaa0 --- /dev/null +++ b/mseide-msegui/lib/common/db/msedb.pas @@ -0,0 +1,9363 @@ +{ MSEgui Copyright (c) 2004-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msedb; + +{$ifdef FPC} + {$define mse_hasvtunicodestring} +{$endif} +{$define hasaswidestring} +{$define integergetdatasize} + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,mdb,mseclasses,mseglob,msestrings,msetypes,msearrayprops, + mseapplication,mseinterfaces, + sysutils,msebintree,mseact,msetimer,maskutils,mseifiglob, + mseificompglob,mseeditglob, + msevariants{$ifndef FPC},classes_del{$endif}; + +const + mse_vtguid = $ff; + guidbuffersize = 36; //aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee + + de_modified = ord(high(tdataevent))+1; + de_afterdelete = ord(high(tdataevent))+2; + de_afterinsert = ord(high(tdataevent))+3; + de_afterpost = ord(high(tdataevent))+4; + de_hasactiveedit = ord(high(tdataevent))+5; + de_afterapplyupdate = ord(high(tdataevent))+6; + + defaultdscontrolleroptions = [{dso_cancelupdateondeleteerror}]; + allfieldkinds = [fkData,fkCalculated,fkLookup,fkInternalCalc]; + +type + lookupdatatypety = (ldt_int32,ldt_int64,ldt_string); + + bookmarkty = string; + //use instead of TBookmarkStr in order to avoid + // FPC deprecated warning +// guidbufferty = array[0..guidbuffersize-1] of char; +// pguidbufferty = ^guidbufferty; + + fieldtypearty = array of tfieldtype; + fieldtypesty = set of tfieldtype; + fieldtypesarty = array of fieldtypesty; + datasetarty = array of tdataset; + + fielddefty = record + datatype: tfieldtype; + size: integer; + name: string; + end; + pfielddefty = ^fielddefty; + fielddefarty = array of fielddefty; + +const + int32fields = [ftsmallint,ftinteger,ftword]; + int64fields = [ftlargeint]; + doublefields = [ftfloat,ftcurrency]; + datetimefields = [ftdate,fttime,ftdatetime]; + charfields = [ftstring,ftfixedchar]; + + widecharfields = [ftwidestring,ftfixedwidechar,ftwidememo]; + textfields = [ftstring,ftfixedchar,ftwidestring,ftfixedwidechar,ftmemo,ftguid]; + memofields = textfields+[ftmemo]; + integerfields = [ftsmallint,ftinteger,ftword,ftlargeint,ftbcd]; + booleanfields = [ftboolean,ftstring,ftfixedchar]+integerfields-[ftbcd]; + realfields = [ftfloat,ftcurrency,ftbcd]; + stringfields = textfields + integerfields + booleanfields + + realfields + datetimefields; + widestringfields = [ftwidestring,ftfixedwidechar,ftwidememo]; + blobfields = [ftblob,ftmemo,ftgraphic{,ftstring}]; +// defaultproviderflags = [pfInInsert,pfInUpdate,pfInWhere]; + + varsizefields = [ftstring,ftfixedchar,ftwidestring,ftfixedwidechar, + ftbytes,ftvarbytes,ftbcd,ftfmtbcd]; + + converrorstring = '?'; + +type + filtereditkindty = (fek_filter,fek_filtermin,fek_filtermax,fek_find); + locateresultty = (loc_timeout,loc_notfound,loc_ok); + recnosearchoptionty = (rso_backward); + recnosearchoptionsty = set of recnosearchoptionty; + + locatekeyoptionty = (lko_caseinsensitive,lko_partialkey,lko_posinsensitive); + locatekeyoptionsty = set of locatekeyoptionty; + locaterecordoptionty = (lro_noforward,lro_nobackward,lro_nocurrent,lro_utf8); + locaterecordoptionsty = set of locaterecordoptionty; + + fieldarty = array of tfield; + + optionmasterlinkty = (mdlo_syncedit,mdlo_syncinsert,mdlo_syncdelete, + mdlo_delayeddetailpost,mdlo_syncfields, + mdlo_inserttoupdate,mdlo_norefresh); + optionsmasterlinkty = set of optionmasterlinkty; + + imasterlink = interface(inullinterface)[miid_imasterlink] + function refreshing: boolean; + end; + + imselocate = interface(inullinterface)[miid_imselocate] + function locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; + end; + + tmsestringfield = class; + idbdata = interface(inullinterface)[miid_idbdata] + function getindex(const afield: tfield): integer; //-1 if none + function gettextindex(const afield: tfield; + const acaseinsensitive: boolean): integer; //-1 if none + function lookuptext(const indexnum: integer; const akey: integer; + const aisnull: boolean; + const valuefield: tmsestringfield): msestring; overload; + function lookuptext(const indexnum: integer; const akey: int64; + const aisnull: boolean; + const valuefield: tmsestringfield): msestring; overload; + function lookuptext(const indexnum: integer; const akey: msestring; + const aisnull: boolean; + const valuefield: tmsestringfield): msestring; overload; + function findtext(const indexnum: integer; const searchtext: msestring; + out arecord: integer): boolean; + function getrowtext(const indexnum: integer; const arecord: integer; + const afield: tfield): msestring; + function getrowinteger(const indexnum: integer; const arecord: integer; + const afield: tfield): integer; + function getrowlargeint(const indexnum: integer; const arecord: integer; + const afield: tfield): int64; + end; + + idbeditinfo = interface(inullinterface)[miid_idbeditinfo] + function getdataset(const aindex: integer): tdataset; + procedure getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); + //propertynames = nil -> propertyname = 'datafield' + end; + + ireccontrol = interface(inullinterface)[miid_ireccontrol] + procedure recchanged; + end; + + ipersistentfieldsinfo = interface(inullinterface)[miid_ipersistentfieldsinfo] + function getfieldnames: stringarty; + end; + + idatasetsum = interface(inullinterface)[miid_idatasetsum] + procedure sumfield(const afield: tfield; out asum: integer); overload; + procedure sumfield(const afield: tfield; out asum: int64); overload; + procedure sumfield(const afield: tfield; out asum: currency); overload; + procedure sumfield(const afield: tfield; out asum: double); overload; + end; + + getdatasourcefuncty = function: tdatasource of object; + + tdbfieldnamearrayprop = class(tstringarrayprop,idbeditinfo) + private + ffieldtypes: fieldtypesty; + fgetdatasource: getdatasourcefuncty; + protected + //idbeditinfo + function getdataset(const aindex: integer): tdataset; + procedure getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); + public + constructor create(const afieldtypes: fieldtypesty; + const agetdatasource: getdatasourcefuncty); + property fieldtypes: fieldtypesty read ffieldtypes write ffieldtypes; + end; + + tdscontroller = class; + + ifieldcomponent = interface; + + idsfieldcontroller = interface(inullinterface) + function getcontroller: tdscontroller; + procedure fielddestroyed(const sender: ifieldcomponent); + end; +{ + lookupfieldinfoty = record + end; + plookupfieldinfoty = ^lookupfieldinfoty; +} + ifieldcomponent = interface(inullinterface)[miid_ifieldcomponent] + procedure setdsintf(const avalue: idsfieldcontroller); + function getinstance: tfield; + end; + +// providerflag1ty = (pf1_refreshinsert,pf1_refreshupdate,pf1_nocopyrecord); +// providerflags1ty = set of providerflag1ty; + + imsefield = interface(inullinterface)[miid_imsefield] +// function getproviderflags1: providerflags1ty; +// function getlookupinfo: plookupfieldinfoty; + end; + + fieldstatety = (fis_changing); + fieldstatesty = set of fieldstatety; + + tmsefield = class(tfield,imsefield) + private +// fproviderflags1: providerflags1ty; + fstate: fieldstatesty; +// flookupinfo: lookupfieldinfoty; +// function getasmsestring: msestring; +// procedure setasmsestring(const avalue: msestring); + //imsefield +//m function getproviderflags1: providerflags1ty; +// function getlookupinfo: plookupfieldinfoty; + protected + procedure readlookup(reader: treader); + //workaround for breaking fix of FPC Mantis 12809 + procedure defineproperties(filer: tfiler); override; +// function getaswidestring: widestring; override; +// procedure setaswidestring(const avalue: widestring); override; + procedure change; override; + procedure SetDataset(AValue : TDataset); override; + public + function HasParent: Boolean; override; + procedure Clear; override; + function assql: msestring; + function asoldsql: msestring; +// property asmsestring: msestring read getasmsestring write setasmsestring; + published +// property providerflags1: providerflags1ty read fproviderflags1 +// write fproviderflags1 default []; + property DataSet stored false; +// property ProviderFlags default defaultproviderflags; + property FieldKind default fkData; + property HasConstraints default false; + property LookupCache default false; +// property ReadOnly default false; +// property Required default false; + end; + + getmsestringdataty = function(const sender: tmsestringfield; + out avalue: msestring): boolean of object; //false if null + setmsestringdataty = procedure(const sender: tmsestringfield; + avalue: msestring) of object; + + tmsestringfield = class(tstringfield,ifieldcomponent,imsefield) + private + fstate: fieldstatesty; + fdsintf: idsfieldcontroller; + fgetmsestringdata: getmsestringdataty; + fsetmsestringdata: setmsestringdataty; + fcharacterlength: integer; +// fvaluebuffer: msestring; +// fvalidating: boolean; + fisftwidestring: boolean; + fdefaultexpressionstr: msestring; + fdefaultexpressionbefore: string; + //synchronize with TField.DefaultExpression +// fproviderflags1: providerflags1ty; +// flookupinfo: lookupfieldinfoty; + //ifieldcomponent + fonsetvalue: msestringfieldsetvalueeventty; + procedure setdsintf(const avalue: idsfieldcontroller); + function getinstance: tfield; + function getdefaultexpression: msestring; + procedure setdefaultexpression(const avalue: msestring); + //imsefield +// function getproviderflags1: providerflags1ty; +// function getlookupinfo: plookupfieldinfoty; + procedure setasnullmsestring(const avalue: msestring); + protected + procedure readlookup(reader: treader); + //workaround for breaking fix of FPC Mantis 12809 + procedure defineproperties(filer: tfiler); override; + function getasunicodestring: unicodestring; override; + procedure setasunicodestring(const avalue: unicodestring); override; + function getaswidestring: widestring; override; + procedure setaswidestring(const avalue: widestring); override; + procedure setismsestring(const getter: getmsestringdataty; + const setter: setmsestringdataty; + const acharacterlength: integer; + const aisftwidestring: boolean); + function GetDataSize: integer; override; + function GetAsString: string; override; + function GetAsVariant: variant; override; + procedure SetAsString(const AValue: string); override; + procedure SetVarValue(const AValue: Variant); override; + procedure change; override; + procedure SetDataset(AValue : TDataset); override; + procedure dosetvalue(const sender: tobject; var avalue: msestring; + var accept: boolean) override; + public + destructor destroy; override; + function HasParent: Boolean; override; + procedure Clear; override; + function assql: msestring; + function asoldsql: msestring; +// property asmsestring: msestring read getasmsestring write setasmsestring; + property asnullmsestring: msestring read getasunicodestring + write setasnullmsestring; + //'' -> NULL + function oldmsestring(out aisnull: boolean): msestring; overload; + function oldmsestring: msestring; overload; + function curmsestring(out aisnull: boolean): msestring; overload; + function curmsestring: msestring; overload; +// property value: msestring read getasmsestring write setasmsestring; + property characterlength: integer read fcharacterlength; + property isftwidestring: boolean read fisftwidestring; + published + property defaultexpression: msestring read getdefaultexpression + write setdefaultexpression; +// property providerflags1: providerflags1ty read fproviderflags1 +// write fproviderflags1 default []; + property DataSet stored false; +// property ProviderFlags default defaultproviderflags; + property FieldKind default fkData; + property HasConstraints default false; + property LookupCache default false; +// property ReadOnly default false; +// property Required default false; + property Transliterate default false; + property onsetvalue: msestringfieldsetvalueeventty + read fonsetvalue write fonsetvalue; + end; + + tmseguidfield = class(tmsefield,imsefield) + private + protected + function getasvariant: variant; override; + procedure setvarvalue(const avalue: variant); override; + function getasstring: string; override; + procedure setasstring(const avalue: string); override; + function getdefaultwidth: longint; override; + function getdatasize: integer; override; + + function getasguid: tguid; override; + procedure setasguid(const avalue: tguid); override; + public + constructor create(aowner: tcomponent); override; + property asguid: tguid read getasguid write setasguid; + property value: tguid read getasguid write setasguid; + published + end; + + tmsenumericfield = class(tnumericfield,imsefield) + private + fstate: fieldstatesty; +// fproviderflags1: providerflags1ty; +// flookupinfo: lookupfieldinfoty; +// function getasmsestring: msestring; +// procedure setasmsestring(const avalue: msestring); + //imsefield +// function getproviderflags1: providerflags1ty; +// function getlookupinfo: plookupfieldinfoty; + protected + procedure readlookup(reader: treader); + //workaround for breaking fix of FPC Mantis 12809 + procedure defineproperties(filer: tfiler); override; + function getaswidestring: widestring; override; + procedure setaswidestring(const avalue: widestring); override; + procedure change; override; + procedure SetDataset(AValue : TDataset); override; + public + function HasParent: Boolean; override; + procedure Clear; override; + function assql: msestring; + function asoldsql: msestring; +// property asmsestring: msestring read getasmsestring write setasmsestring; + published +// property providerflags1: providerflags1ty read fproviderflags1 +// write fproviderflags1 default []; + property DataSet stored false; +// property ProviderFlags default defaultproviderflags; + property FieldKind default fkData; + property HasConstraints default false; + property LookupCache default false; +// property ReadOnly default false; +// property Required default false; + end; + tmselongintfield = class(tlongintfield,imsefield) + private + fstate: fieldstatesty; +// fproviderflags1: providerflags1ty; +// flookupinfo: lookupfieldinfoty; +// function getasmsestring: msestring; +// procedure setasmsestring(const avalue: msestring); + procedure setasenum(const avalue: integer); + //imsefield +// function getproviderflags1: providerflags1ty; +// function getlookupinfo: plookupfieldinfoty; + + protected + procedure readlookup(reader: treader); + //workaround for breaking fix of FPC Mantis 12809 + procedure defineproperties(filer: tfiler); override; + function getaswidestring: widestring; override; + procedure setaswidestring(const avalue: widestring); override; + function getasboolean: boolean; override; + procedure setasboolean(avalue: boolean); override; + procedure setaslargeint(avalue: largeint); override; + function getaslargeint: largeint; override; + procedure gettext(var thetext: string; adisplaytext: boolean); override; + procedure change; override; + procedure SetDataset(AValue : TDataset); override; + public + function HasParent: Boolean; override; + procedure Clear; override; + function assql: msestring; + function asoldsql: msestring; + function asoldid: integer; + function sum: integer; +// property asmsestring: msestring read getasmsestring write setasmsestring; +// property asid: integer read getasid write setasid; //-1 -> NULL + property asenum: integer read getaslongint write setasenum; + published +// property providerflags1: providerflags1ty read fproviderflags1 +// write fproviderflags1 default []; + property DataSet stored false; +// property ProviderFlags default defaultproviderflags; + property FieldKind default fkData; + property HasConstraints default false; + property LookupCache default false; +// property ReadOnly default false; +// property Required default false; + property DisplayWidth default 10; + end; + tmselargeintfield = class(tlargeintfield,imsefield) + private + fstate: fieldstatesty; +// fproviderflags1: providerflags1ty; +// flookupinfo: lookupfieldinfoty; +// function getasmsestring: msestring; +// procedure setasmsestring(const avalue: msestring); + //imsefield +// function getproviderflags1: providerflags1ty; +// function getlookupinfo: plookupfieldinfoty; + function getasid: int64; + procedure setasid(const avalue: int64); + protected + procedure readlookup(reader: treader); + //workaround for breaking fix of FPC Mantis 12809 + procedure defineproperties(filer: tfiler); override; + function getaswidestring: widestring; override; + procedure setaswidestring(const avalue: widestring); override; + function getasboolean: boolean; override; + procedure setasboolean(avalue: boolean); override; + procedure gettext(var thetext: string; adisplaytext: boolean); override; + procedure change; override; + procedure SetDataset(AValue : TDataset); override; + public + function HasParent: Boolean; override; + procedure Clear; override; + function assql: msestring; + function asoldsql: msestring; + function asoldid: int64; + function sum: int64; +// property asmsestring: msestring read getasmsestring write setasmsestring; +// property asid: int64 read getasid write setasid; //-1 -> NULL + property Value: Largeint read GetAsLargeint write SetAsLargeint; + published +// property providerflags1: providerflags1ty read fproviderflags1 +// write fproviderflags1 default []; + property DataSet stored false; +// property ProviderFlags default defaultproviderflags; + property FieldKind default fkData; + property HasConstraints default false; + property LookupCache default false; +// property ReadOnly default false; +// property Required default false; + property DisplayWidth default 10; + end; + tmsesmallintfield = class(tsmallintfield,imsefield) + private + fstate: fieldstatesty; +// fproviderflags1: providerflags1ty; +// flookupinfo: lookupfieldinfoty; +// function getasmsestring: msestring; +// procedure setasmsestring(const avalue: msestring); + //imsefield +// function getproviderflags1: providerflags1ty; +// function getlookupinfo: plookupfieldinfoty; + function getasid: integer; + procedure setasid(const avalue: integer); + protected + procedure readlookup(reader: treader); + //workaround for breaking fix of FPC Mantis 12809 + procedure defineproperties(filer: tfiler); override; + function getaswidestring: widestring; override; + procedure setaswidestring(const avalue: widestring); override; + function getasboolean: boolean; override; + procedure setasboolean(avalue: boolean); override; + procedure setaslargeint(avalue: largeint); override; + function getaslargeint: largeint; override; + procedure change; override; + procedure SetDataset(AValue : TDataset); override; + public + function HasParent: Boolean; override; + procedure Clear; override; + function assql: msestring; + function asoldsql: msestring; +// property asmsestring: msestring read getasmsestring write setasmsestring; + property asid: integer read getasid write setasid; //-1 -> NULL + published +// property providerflags1: providerflags1ty read fproviderflags1 +// write fproviderflags1 default []; + property DataSet stored false; +// property ProviderFlags default defaultproviderflags; + property FieldKind default fkData; + property HasConstraints default false; + property LookupCache default false; +// property ReadOnly default false; +// property Required default false; + property DisplayWidth default 10; + end; + tmsewordfield = class(twordfield,imsefield) + private + fstate: fieldstatesty; +// fproviderflags1: providerflags1ty; +// flookupinfo: lookupfieldinfoty; +// function getasmsestring: msestring; +// procedure setasmsestring(const avalue: msestring); + //imsefield +// function getproviderflags1: providerflags1ty; +// function getlookupinfo: plookupfieldinfoty; + protected + procedure readlookup(reader: treader); + //workaround for breaking fix of FPC Mantis 12809 + procedure defineproperties(filer: tfiler); override; + function getaswidestring: widestring; override; + procedure setaswidestring(const avalue: widestring); override; + function getasboolean: boolean; override; + procedure setasboolean(avalue: boolean); override; + procedure setaslargeint(avalue: largeint); override; + function getaslargeint: largeint; override; + procedure change; override; + procedure SetDataset(AValue : TDataset); override; + public + function HasParent: Boolean; override; + procedure Clear; override; + function assql: msestring; + function asoldsql: msestring; +// property asmsestring: msestring read getasmsestring write setasmsestring; + published +// property providerflags1: providerflags1ty read fproviderflags1 +// write fproviderflags1 default []; + property DataSet stored false; +// property ProviderFlags default defaultproviderflags; + property FieldKind default fkData; + property HasConstraints default false; + property LookupCache default false; +// property ReadOnly default false; +// property Required default false; + property DisplayWidth default 10; + end; + tmseautoincfield = class(tautoincfield,imsefield) + private + fstate: fieldstatesty; +// fproviderflags1: providerflags1ty; +// flookupinfo: lookupfieldinfoty; +// function getasmsestring: msestring; +// procedure setasmsestring(const avalue: msestring); + //imsefield +// function getproviderflags1: providerflags1ty; +// function getlookupinfo: plookupfieldinfoty; + protected + procedure readlookup(reader: treader); + //workaround for breaking fix of FPC Mantis 12809 + procedure defineproperties(filer: tfiler); override; + function getaswidestring: widestring; override; + procedure setaswidestring(const avalue: widestring); override; + procedure change; override; + procedure SetDataset(AValue : TDataset); override; + public + function HasParent: Boolean; override; + procedure Clear; override; + function assql: msestring; + function asoldsql: msestring; +// property asmsestring: msestring read getasmsestring write setasmsestring; + published +// property providerflags1: providerflags1ty read fproviderflags1 +// write fproviderflags1 default []; + property DataSet stored false; +// property ProviderFlags default defaultproviderflags; + property FieldKind default fkData; + property HasConstraints default false; + property LookupCache default false; +// property ReadOnly default false; +// property Required default false; + property DisplayWidth default 10; + end; + tmsefloatfield = class(tfloatfield,imsefield) + private + fstate: fieldstatesty; +// fproviderflags1: providerflags1ty; +// flookupinfo: lookupfieldinfoty; +// function getasmsestring: msestring; +// procedure setasmsestring(const avalue: msestring); + //imsefield +// function getproviderflags1: providerflags1ty; +// function getlookupinfo: plookupfieldinfoty; + protected + procedure readlookup(reader: treader); + //workaround for breaking fix of FPC Mantis 12809 + procedure defineproperties(filer: tfiler); override; + function getaswidestring: widestring; override; + procedure setaswidestring(const avalue: widestring); override; + function getasfloat: double; override; + function getascurrency: currency; override; + procedure setasfloat(avalue: double); override; + procedure gettext(var thetext: string; adisplaytext: boolean); override; + function GetAsLongint: Longint; override; + procedure change; override; + function GetAsLargeint: Largeint; override; + procedure SetDataset(AValue : TDataset); override; + public + function HasParent: Boolean; override; + procedure Clear; override; + function assql: msestring; + function asoldsql: msestring; + function sum: double; +// property asmsestring: msestring read getasmsestring write setasmsestring; + published +// property providerflags1: providerflags1ty read fproviderflags1 +// write fproviderflags1 default []; + property DataSet stored false; +// property ProviderFlags default defaultproviderflags; + property FieldKind default fkData; + property HasConstraints default false; + property LookupCache default false; +// property ReadOnly default false; +// property Required default false; + property DisplayWidth default 10; + end; + tmsecurrencyfield = class(tmsefloatfield) + public + constructor create(aowner: tcomponent); override; + end; + tmsebooleanfield = class(tbooleanfield,imsefield) + private + fstate: fieldstatesty; + fdisplayvalues: msestring; +// fproviderflags1: providerflags1ty; +// flookupinfo: lookupfieldinfoty; + procedure setdisplayvalues(const avalue: msestring); + //imsefield +// function getproviderflags1: providerflags1ty; +// function getlookupinfo: plookupfieldinfoty; + protected + fdisplays : array[boolean,boolean] of msestring; + procedure readlookup(reader: treader); + //workaround for breaking fix of FPC Mantis 12809 + procedure defineproperties(filer: tfiler); override; + function getaswidestring: widestring; override; + procedure setaswidestring(const avalue: widestring); override; + function getasunicodestring: unicodestring; override; + procedure setasunicodestring(const avalue: unicodestring); override; + function GetDataSize: integer; override; + function GetAsBoolean: Boolean; override; + procedure SetAsBoolean(AValue: Boolean); override; + function getasstring: string; override; + procedure setasstring(const avalue: string); override; + function GetDefaultWidth: Longint; override; + function GetAsLongint: Longint; override; + procedure SetAsLongint(AValue: Longint); override; + function GetAsVariant: variant; override; + procedure change; override; + procedure SetDataset(AValue : TDataset); override; + public + function HasParent: Boolean; override; + constructor Create(AOwner: TComponent); override; + procedure Clear; override; + function assql: msestring; + function asoldsql: msestring; + function sum: integer; //counts true values +// property asmsestring: msestring read getasmsestring write setasmsestring; + published +// property providerflags1: providerflags1ty read fproviderflags1 +// write fproviderflags1 default []; + property DataSet stored false; +// property ProviderFlags default defaultproviderflags; + property displayvalues: msestring read fdisplayvalues write setdisplayvalues; + property FieldKind default fkData; + property HasConstraints default false; +// property Lookup default false; + property LookupCache default false; +// property ReadOnly default false; +// property Required default false; +// property DisplayWidth default 5; variable! + end; + + datetimefieldoptionty = (dtfo_utc,dtfo_local); //DB time format + datetimefieldoptionsty = set of datetimefieldoptionty; + + tmsedatetimefield = class(tdatetimefield,imsefield) + private + fstate: fieldstatesty; + foptions: datetimefieldoptionsty; +// fproviderflags1: providerflags1ty; +// flookupinfo: lookupfieldinfoty; +// function getasmsestring: msestring; +// procedure setasmsestring(const avalue: msestring); + procedure setoptions(const avalue: datetimefieldoptionsty); + //imsefield +// function getproviderflags1: providerflags1ty; +// function getlookupinfo: plookupfieldinfoty; + protected + procedure readlookup(reader: treader); + //workaround for breaking fix of FPC Mantis 12809 + procedure defineproperties(filer: tfiler); override; + function getaswidestring: widestring; override; + procedure setaswidestring(const avalue: widestring); override; + function getasdatetime: tdatetime; override; + procedure setasdatetime(avalue: tdatetime); override; + procedure setasstring(const avalue: string); override; + function gettext1(const r: tdatetime; const adisplaytext: boolean): msestring; + procedure gettext(var thetext: string; adisplaytext: boolean); override; + procedure change; override; + procedure SetDataset(AValue : TDataset); override; + public + function HasParent: Boolean; override; + procedure Clear; override; + function assql: msestring; + function asoldsql: msestring; +// property asmsestring: msestring read getasmsestring write setasmsestring; + published +// property providerflags1: providerflags1ty read fproviderflags1 +// write fproviderflags1 default []; + property DataSet stored false; +// property ProviderFlags default defaultproviderflags; + property options: datetimefieldoptionsty read foptions + write setoptions default []; + property FieldKind default fkData; + property HasConstraints default false; + property LookupCache default false; +// property ReadOnly default false; +// property Required default false; + property DisplayWidth default 10; + end; + tmsedatefield = class(tmsedatetimefield) + public + constructor create(aowner: tcomponent); override; + end; + tmsetimefield = class(tmsedatetimefield) + public + constructor create(aowner: tcomponent); override; + end; + + tmsebinaryfield = class(tbinaryfield,imsefield) + private + fstate: fieldstatesty; +// fproviderflags1: providerflags1ty; +// flookupinfo: lookupfieldinfoty; + //imsefield +// function getproviderflags1: providerflags1ty; +// function getlookupinfo: plookupfieldinfoty; + protected + procedure readlookup(reader: treader); + //workaround for breaking fix of FPC Mantis 12809 + procedure defineproperties(filer: tfiler); override; + function getaswidestring: widestring; override; + procedure setaswidestring(const avalue: widestring); override; + function getasunicodestring: unicodestring; override; + procedure setasunicodestring(const avalue: unicodestring); override; + procedure change; override; + procedure SetDataset(AValue : TDataset); override; + public + function HasParent: Boolean; override; + procedure Clear; override; + function assql: msestring; + function asoldsql: msestring; +// property asmsestring: msestring read getasmsestring write setasmsestring; + published +// property providerflags1: providerflags1ty read fproviderflags1 +// write fproviderflags1 default []; + property DataSet stored false; +// property ProviderFlags default defaultproviderflags; + property FieldKind default fkData; + property HasConstraints default false; + property LookupCache default false; +// property ReadOnly default false; +// property Required default false; + end; + tmsebytesfield = class(tbytesfield,imsefield) + private + fstate: fieldstatesty; +// fproviderflags1: providerflags1ty; +// flookupinfo: lookupfieldinfoty; + //imsefield +// function getproviderflags1: providerflags1ty; +// function getlookupinfo: plookupfieldinfoty; + protected + procedure readlookup(reader: treader); + //workaround for breaking fix of FPC Mantis 12809 + procedure defineproperties(filer: tfiler); override; + function getaswidestring: widestring; override; + procedure setaswidestring(const avalue: widestring); override; + function getasunicodestring: unicodestring; override; + procedure setasunicodestring(const avalue: unicodestring); override; + function getasvariant: variant; override; + function getasstring: string; override; + procedure setasstring(const avalue: string); override; + procedure change; override; + procedure SetDataset(AValue : TDataset); override; + public + function HasParent: Boolean; override; + procedure Clear; override; + function assql: msestring; + function asoldsql: msestring; +// property asmsestring: msestring read getasmsestring write setasmsestring; + published +// property providerflags1: providerflags1ty read fproviderflags1 +// write fproviderflags1 default []; + property DataSet stored false; +// property ProviderFlags default defaultproviderflags; + property FieldKind default fkData; + property HasConstraints default false; + property LookupCache default false; +// property ReadOnly default false; +// property Required default false; + end; + tmsevarbytesfield = class(tvarbytesfield,imsefield) + private + fstate: fieldstatesty; +// fproviderflags1: providerflags1ty; +// flookupinfo: lookupfieldinfoty; + //imsefield +// function getproviderflags1: providerflags1ty; +// function getlookupinfo: plookupfieldinfoty; + protected + procedure readlookup(reader: treader); + //workaround for breaking fix of FPC Mantis 12809 + procedure defineproperties(filer: tfiler); override; +// function getaswidestring: widestring; override; +// procedure setaswidestring(const avalue: widestring); override; +// function getasunicodestring: unicodestring; override; +// procedure setasunicodestring(const avalue: unicodestring); override; + function getasvariant: variant; override; + procedure setasstring(const avalue: string); override; + function getasstring: string; override; + procedure change; override; + procedure SetDataset(AValue : TDataset); override; + public + function HasParent: Boolean; override; + procedure Clear; override; + function assql: msestring; + function asoldsql: msestring; +// property asmsestring: msestring read getasmsestring write setasmsestring; + published +// property providerflags1: providerflags1ty read fproviderflags1 +// write fproviderflags1 default []; + property DataSet stored false; +// property ProviderFlags default defaultproviderflags; + property FieldKind default fkData; + property HasConstraints default false; + property LookupCache default false; +// property ReadOnly default false; +// property Required default false; + end; + tmsebcdfield = class(tbcdfield,imsefield) + private + fstate: fieldstatesty; +// fproviderflags1: providerflags1ty; +// flookupinfo: lookupfieldinfoty; +// function getasmsestring: msestring; +// procedure setasmsestring(const avalue: msestring); + //imsefield +// function getproviderflags1: providerflags1ty; +// function getlookupinfo: plookupfieldinfoty; + protected + procedure readlookup(reader: treader); + //workaround for breaking fix of FPC Mantis 12809 + procedure defineproperties(filer: tfiler); override; + function getaswidestring: widestring; override; + procedure setaswidestring(const avalue: widestring); override; + procedure setasfloat(avalue: double); override; + procedure gettext(var thetext: string; adisplaytext: boolean); override; + class procedure checktypesize(avalue: longint); override; + procedure change; override; + procedure SetDataset(AValue : TDataset); override; + public + function HasParent: Boolean; override; + procedure Clear; override; + function assql: msestring; + function asoldsql: msestring; + function sum: currency; +// property asmsestring: msestring read getasmsestring write setasmsestring; + property Value: Currency read GetAsCurrency write SetAsCurrency; + published +// property providerflags1: providerflags1ty read fproviderflags1 +// write fproviderflags1 default []; + property DataSet stored false; +// property ProviderFlags default defaultproviderflags; + property FieldKind default fkData; + property HasConstraints default false; + property LookupCache default false; +// property ReadOnly default false; +// property Required default false; + property precision default 15; +// property displaywidth default 15; variable! + property currency default false; + end; + + blobidty = record + id: int64; + local: boolean; + end; + + getblobidfuncty = function(const afield: tfield; out aid: blobidty): boolean + of object; + + tblobcachenode = class(tstringcachenode) + private + flocal: boolean; + public + constructor create(const akey: blobidty; const adata: string); overload; + end; + + tblobcache = class(tstringcacheavltree) + private + ffindnode: tblobcachenode; + public + constructor create; + destructor destroy; override; + function addnode(const akey: blobidty; + const adata: string): tblobcachenode; overload; + function find(const akey: blobidty; + out anode: tblobcachenode): boolean; overload; + end; + + tmseblobfield = class(tblobfield,imsefield) + private + fcache: tblobcache; +// fproviderflags1: providerflags1ty; +// flookupinfo: lookupfieldinfoty; + procedure setcachekb(const avalue: integer); + function getcachekb: integer; + //imsefield +// function getproviderflags1: providerflags1ty; +// function getlookupinfo: plookupfieldinfoty; + protected + fgetblobid: getblobidfuncty; +// function getasmsestring: msestring; virtual; +// procedure setasmsestring(const avalue: msestring); virtual; + procedure readlookup(reader: treader); + //workaround for breaking fix of FPC Mantis 12809 + procedure defineproperties(filer: tfiler); override; + procedure removecache(const aid: blobidty); overload; virtual; + procedure removecache; overload; + function getasvariant: variant; override; + function getasstring: string; override; + procedure setasstring(const avalue: string); override; +// function getaswidestring: widestring; override; +// procedure setaswidestring(const avalue: widestring); override; + procedure gettext(var atext: string; adisplaytext: boolean); override; + procedure SetDataset(AValue : TDataset); override; + public + destructor destroy; override; + function HasParent: Boolean; override; + procedure Clear; override; + procedure clearcache; virtual; + function assql: msestring; + function asoldsql: msestring; +// property asmsestring: msestring read getasmsestring write setasmsestring; + procedure LoadFromStream(Stream: TStream); + procedure LoadFromFile(const FileName: filenamety); + procedure SaveToFile(const FileName: filenamety); + published +// property providerflags1: providerflags1ty read fproviderflags1 +// write fproviderflags1 default []; + property DataSet stored false; +// property ProviderFlags default defaultproviderflags; + property cachekb: integer read getcachekb write setcachekb default 0; + //cachesize in kilo bytes, 0 -> no cache + property FieldKind default fkData; + property HasConstraints default false; + property LookupCache default false; +// property ReadOnly default false; +// property Required default false; + end; + tmsememofield = class(tmseblobfield,ifieldcomponent) + private + fdsintf: idsfieldcontroller; + //ifieldcomponent + procedure setdsintf(const avalue: idsfieldcontroller); + function getinstance: tfield; + protected + function getaswidestring: widestring; override; + procedure setaswidestring(const avalue: widestring); override; + function getasunicodestring: msestring; override; + procedure setasunicodestring(const avalue: msestring); override; + function getasvariant: variant; override; + procedure setvarvalue(const avalue: variant); override; + procedure gettext(var thetext: string; adisplaytext: boolean); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure Clear; override; +// property asmsestring: msestring read getasmsestring write setasmsestring; + function oldmsestring(out aisnull: boolean): msestring; + function assql: msestring; + function asoldsql: msestring; + published + property Transliterate default True; + property DataSet stored false; +// property ProviderFlags default defaultproviderflags; + property FieldKind default fkData; + property HasConstraints default false; + property LookupCache default false; +// property ReadOnly default false; +// property Required default false; + end; + + tmsevariantfield = class; + setvardataty = procedure(const sender: tmsevariantfield; + avalue: variant) of object; + getvardataty = function(const sender: tmsevariantfield; + out avalue: variant): boolean of object; + tmsevariantfield = class(tvariantfield,imsefield) + private +// fproviderflags1: providerflags1ty; +// flookupinfo: lookupfieldinfoty; + //imsefield +//m function getproviderflags1: providerflags1ty; +// function getlookupinfo: plookupfieldinfoty; + protected + fgetvardata: getvardataty; + fsetvardata: setvardataty; + function getdatasize: integer; override; + function getasvariant: variant; override; + procedure setvarvalue(const avalue: variant); override; + + function getasboolean: boolean; override; + function getasinteger: integer; override; + function getasdatetime: tdatetime; override; + function getasfloat: double; override; +// function getasstring: string; override; +// function getaswidestring: widestring; override; +// function getasunicodestring: unicodestring; override; +// function getasmsestring: msestring; +// procedure setasmsestring(const avalue: msestring); + + function getaslongint: longint; override; + procedure setaslongint(avalue: longint); override; + function getaslargeint: largeint; override; + procedure setaslargeint(avalue: largeint); override; + function getascurrency: currency; override; + procedure setascurrency(avalue: currency); override; + procedure SetDataset(AValue : TDataset); override; + public + function assql: msestring; + function asoldsql: msestring; +// property asmsestring: msestring read getasmsestring write setasmsestring; + published +// property providerflags1: providerflags1ty read fproviderflags1 +// write fproviderflags1 default []; + property DataSet stored false; +// property ProviderFlags default defaultproviderflags; + property FieldKind default fkData; + property HasConstraints default false; + property LookupCache default false; +// property ReadOnly default false; +// property Required default false; + property DisplayWidth default 15; + end; + + tmsedatalink = class(tdatalink) + private + function getrecnozerobased: integer; + procedure setrecnozerobased(const avalue: integer); + protected + fcanclosing: integer; + fdscontroller: tdscontroller; + procedure checkcontroller; + procedure activechanged; override; + function getdataset: tdataset; + function getutf8: boolean; + function getfiltereditkind: filtereditkindty; + function GetActiveRecord: Integer; override; + procedure DataEvent(Event: TDataEvent; Info: Ptrint); override; + procedure disabledstatechange; virtual; + function canedit: boolean; + procedure setbuffercount(value: integer); override; + public + destructor destroy; override; + function moveby(distance: integer): integer; override; + function noedit: boolean; + function caninsert: boolean; + function canappend: boolean; + function candelete: boolean; + function canupdate: boolean; + property dataset: tdataset read getdataset; + property dscontroller: tdscontroller read fdscontroller; + property utf8: boolean read getutf8; + property filtereditkind: filtereditkindty read getfiltereditkind; + function canclose: boolean; + property recnozerobased: integer read getrecnozerobased + write setrecnozerobased; + end; + + fielddatalinkstatety = (fds_ismsestring,fds_islargeint,fds_isstring, + fds_editing,fds_modified,fds_filterediting, + fds_filtereditdisabled); + fielddatalinkstatesty = set of fielddatalinkstatety; + + tfieldsdatalink = class(tmsedatalink,iifidataserver) + protected + procedure activechanged; override; + procedure layoutchanged; override; + procedure updatefields; virtual; + procedure fieldchanged; virtual; + //iifiserver + procedure execute(const sender: iificlient); virtual; + procedure valuechanged(const sender: iifidatalink); virtual; + procedure statechanged(const sender: iificlient; + const astate: ifiwidgetstatesty); virtual; + procedure setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); virtual; + procedure dataentered(const sender: iificlient; + const arow: integer); virtual; + procedure closequery(const sender: iificlient; + var amodalresult: modalresultty); virtual; + procedure sendmodalresult(const sender: iificlient; + const amodalresult: modalresultty); virtual; + procedure updateoptionsedit(var avalue: optionseditty); virtual; + end; + + tfielddatalink = class(tfieldsdatalink) + private + ffield: tfield; + ffieldname: string; + fnullsymbol: msestring; + procedure setfieldname(const Value: string); + function getasmsestring: msestring; + procedure setasmsestring(const avalue: msestring); + function getmsedefaultexpression: msestring; + procedure checkfield; + function GetAsBoolean: Boolean; + procedure SetAsBoolean(const avalue: Boolean); + function GetAsCurrency: Currency; + procedure SetAsCurrency(const avalue: Currency); + function GetAsDateTime: TDateTime; + procedure SetAsDateTime(const avalue: TDateTime); + function GetAsFloat: Double; + procedure SetAsFloat(const avalue: Double); + function GetAsLongint: Longint; + procedure SetAsLongint(const avalue: Longint); + function GetAsLargeInt: LargeInt; + procedure SetAsLargeInt(const avalue: LargeInt); + function GetAsInteger: Integer; + procedure SetAsInteger(const avalue: Integer); + function GetAsString: string; + procedure SetAsString(const avalue: string); + function GetAsVariant: variant; + procedure SetAsVariant(const avalue: variant); + function getislargeint: boolean; + function getismsestring: boolean; + function getisstringfield: boolean; + protected + fstate: fielddatalinkstatesty; + procedure setfield(const value: tfield); virtual; + procedure updatefields; override; + function getsortfield: tfield; virtual; + procedure setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); override; + procedure dataentered(const sender: iificlient; + const arow: integer); override; + public + function assql: msestring; + function fieldactive: boolean; + procedure clear; + property field: tfield read ffield; + property sortfield: tfield read getsortfield; + property fieldname: string read ffieldname write setfieldname; + property state: fielddatalinkstatesty read fstate; + property islargeint: boolean read getislargeint; + property ismsestring: boolean read getismsestring; + property isstringfield: boolean read getisstringfield; + + property AsBoolean: Boolean read GetAsBoolean write SetAsBoolean; + property AsCurrency: Currency read GetAsCurrency write SetAsCurrency; + property AsDateTime: TDateTime read GetAsDateTime write SetAsDateTime; + property AsFloat: Double read GetAsFloat write SetAsFloat; + property AsLongint: Longint read GetAsLongint write SetAsLongint; + property AsLargeInt: LargeInt read GetAsLargeInt write SetAsLargeInt; + property AsInteger: Integer read GetAsInteger write SetAsInteger; + property AsString: string read GetAsString write SetAsString; + property AsVariant: variant read GetAsVariant write SetAsVariant; + property asmsestring: msestring read getasmsestring write setasmsestring; + property msedefaultexpression: msestring read getmsedefaultexpression; + function msedisplaytext(const aformat: msestring = ''; + const aedit: boolean = false): msestring; virtual; + property nullsymbol: msestring read fnullsymbol write fnullsymbol; + end; + +// fieldarrayty = array of tfield; + + fieldclassty = class of tfield; + + fieldclasstypety = (ft_unknown,ft_string,ft_guid,ft_numeric, + ft_longint,ft_largeint,ft_smallint, + ft_word,ft_autoinc,ft_float,ft_currency,ft_boolean, + ft_datetime,ft_date,ft_time, + ft_binary,ft_bytes,ft_varbytes, + ft_bcd,ft_blob,ft_memo,ft_graphic,ft_variant); + fieldclasstypearty = array of fieldclasstypety; + + tmsedatasource = class(tdatasource) + public + procedure bringtofront; //called first by dataset + end; + + tpersistentfields = class(tpersistentarrayprop,ipersistentfieldsinfo) + private + fdataset: tdataset; + procedure readfields(reader: treader); + procedure writefields(writer: twriter); + procedure setitems(const index: integer; const avalue: tfield); + function getitems(const index: integer): tfield; + protected + finvaliditems: booleanarty; + procedure createitem(const index: integer; var item: tpersistent); override; + procedure defineproperties(filer: tfiler); override; + function ispropertystored(index: integer): boolean; override; + public + constructor create(const adataset: tdataset); + class function getitemclasstype: persistentclassty; override; + procedure move(const curindex,newindex: integer); override; + procedure updateorder; + function getfieldnames: stringarty; + property dataset: tdataset read fdataset; + property items[const index: integer]: tfield read getitems write setitems; default; + end; + + datasetoptionty = (dso_utf8,dso_stringmemo,dso_numboolean, + dso_waitcursor, + dso_initinternalcalc, + + //flags below have been moved to + //tsqlquery.options + dso_postsavepoint,dso_deletesavepoint, + dso_cancelupdateonerror,dso_cancelupdatesonerror, + dso_cancelupdateondeleteerror, + dso_editonapplyerror, + dso_restoreupdateonsavepointrollback, + dso_noapply,dso_autoapply, + dso_autocommitret,dso_autocommit, + dso_refreshafterapply,dso_recnoapplyrefresh, + dso_refreshtransaction, + dso_notransactionrefresh,dso_recnotransactionrefresh, + dso_noprepare, + dso_cacheblobs, + dso_offline, //disconnect database after open + dso_local, //do not connect database on open + + dso_refreshwaitcursor, //deprecated + dso_noedit,dso_noinsert,dso_noappend,dso_noupdate, + dso_nodelete, + dso_canceloncheckbrowsemode + {, + dso_syncmasteredit,dso_syncmasterinsert, + -> optionsmasterlink + dso_syncmasterdelete,dso_delayeddetailpost, + dso_inserttoupdate,dso_syncinsertfields}); + datasetoptionsty = set of datasetoptionty; +const + deprecatedbdsoptions = [ + dso_postsavepoint,dso_deletesavepoint, + dso_cancelupdateonerror,dso_cancelupdatesonerror, + dso_cancelupdateondeleteerror, + dso_editonapplyerror, + dso_restoreupdateonsavepointrollback, + dso_noapply,dso_autoapply, + dso_autocommitret,dso_autocommit, + dso_refreshafterapply,dso_recnoapplyrefresh, + dso_refreshtransaction, + dso_notransactionrefresh,dso_recnotransactionrefresh, + dso_noprepare, + dso_cacheblobs, + dso_offline, //disconnect database after open + dso_local //do not connect database on open + ]; +type + savepointoptionty = (spo_postsavepoint,spo_deletesavepoint); + savepointoptionsty = set of savepointoptionty; + + idscontroller = interface(iactivatorclient) + procedure inheriteddataevent(const event: tdataevent; const info: ptrint); + procedure inheritedcancel; + procedure inheritedpost; + procedure inheritedinsert; + procedure inheriteddelete; + function inheritedmoveby(const distance: integer): integer; + procedure inheritedinternalinsert; + procedure inheritedinternalopen; + procedure inheritedinternalclose; + procedure openlocal; + procedure inheritedinternaldelete; + function getblobdatasize: integer; + function getnumboolean: boolean; + function getfloatdate: boolean; + function getint64currency: boolean; + function getfiltereditkind: filtereditkindty; + procedure beginfilteredit(const akind:filtereditkindty); + procedure endfilteredit; + procedure clearfilter; + procedure begindisplaydata; + procedure enddisplaydata; +// procedure doidleapplyupdates; +// procedure dscontrolleroptionschanged(const aoptions: datasetoptionsty); + function getrestorerecno: boolean; + procedure setrestorerecno(const avalue: boolean); + property restorerecno: boolean read getrestorerecno write setrestorerecno; + //for refresh + function islastrecord: boolean; + function updatesortfield(const afield: tfield; const adescend: boolean): boolean; + function getsavepointoptions(): savepointoptionsty; + end; + + igetdscontroller = interface(inullinterface)[miid_igetdscontroller] + function getcontroller: tdscontroller; + end; + + fieldlinkarty = array of ifieldcomponent; + dscontrollerstatety = (dscs_posting,dscs_posting1,dscs_canceling, + dscs_deleting,dscs_refreshing, + dscs_onidleregistered, + dscs_restorerecno); + dscontrollerstatesty = set of dscontrollerstatety; + + datasetstatechangedeventty = procedure(const sender: tdataset; + const statebefore: tdatasetstate) of object; + masterdataseteventty = procedure(const sender: tdataset; + const master: tdataset) of object; + slavedataseteventty = procedure(const sender: tdataset; + const slave: tdataset) of object; + afterdbopeventty = procedure(const sender: tdataset; + var ok: boolean) of object; + epostcancel = class(eabort); + + opkindty = (opk_post,opk_delete,opk_insert); + + tdscontroller = class(tactivatorcontroller,idsfieldcontroller) + private + ffields: tpersistentfields; +// fintf: idscontroller; + frecno: integer; + frecnovalid: boolean; + fscrollsum: integer; + factiverecordbefore: integer; + fbuffercountbefore: integer; + frecnooffset: integer; + fmovebylock: boolean; + fcancelresync: boolean; + finsertbm: bookmarkty; + flinkedfields: fieldlinkarty; + fstate: dscontrollerstatesty; +// fdelayedapplycount: integer; + fbmbackup: bookmarkty; + fupdatecount: integer; + fstatebefore: tdatasetstate; + fonstatechanged: datasetstatechangedeventty; + fonupdatemasteredit: masterdataseteventty; + fonupdatemasterinsert: masterdataseteventty; + ftimer: tsimpletimer; + fonbeforepost: tdatasetnotifyevent; + fonafterpost: afterdbopeventty; + fonbeforecopyrecord: tdatasetnotifyevent; + fonaftercopyrecord: tdatasetnotifyevent; + fonbeforedelete: tdatasetnotifyevent; + fonafterdelete: afterdbopeventty; + procedure setfields(const avalue: tpersistentfields); + function getcontroller: tdscontroller; + procedure updatelinkedfields; + function getrecnozerobased: integer; + procedure setrecnozerobased(const avalue: integer); + function getrecno: integer; + procedure setrecno(const avalue: integer); +// procedure registeronidle; +// procedure unregisteronidle; +// procedure setdelayedapplycount(const avalue: integer); + function getnoedit: boolean; + procedure setnoedit(const avalue: boolean); + procedure nosavepoint; + function getasmsestring(const afieldname: string): msestring; + procedure setasmsestring(const afieldname: string; const avalue: msestring); + function getnoinsert: boolean; + procedure setnoinsert(const avalue: boolean); + function getnoappend: boolean; + procedure setnoappend(const avalue: boolean); + function getnoupdate: boolean; + procedure setnoupdate(const avalue: boolean); + function getnodelete: boolean; + procedure setnodelete(const avalue: boolean); + procedure readdelayedapplycount(reader: treader); + protected + foptions: datasetoptionsty; + procedure setoptions(const avalue: datasetoptionsty); virtual; + procedure setowneractive(const avalue: boolean); override; + procedure fielddestroyed(const sender: ifieldcomponent); +// procedure doonidle(var again: boolean); + procedure dorefresh(const sender: tobject); + function savepointbegin: integer; virtual; + procedure savepointrollback(const aindex: integer = -1); virtual; + //-1 = toplevel + procedure savepointrelease; virtual; + function execoperation(const akind: opkindty; + const aafterop: afterdbopeventty): boolean; + procedure defineproperties(filer: tfiler) override; + public + constructor create(const aowner: tdataset; const aintf: idscontroller; + const arecnooffset: integer = -1; + const acancelresync: boolean = true); + destructor destroy; override; + function isutf8: boolean; + function getfieldar(const afieldkinds: tfieldkinds = allfieldkinds): fieldarty; + function filtereditkind: filtereditkindty; + procedure beginupdate; //calls diablecontrols, stores bookmark + procedure endupdate; //restores bookmark, calls enablecontrols + function locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; + procedure appendrecord(const values: array of const); + procedure appendrecord1(const values: array of const; + const aisnull: array of boolean); + procedure appendrecord(const values: array of const; + const afields: array of tfield); + procedure appendrecord1(const values: array of const; + const aisnull: array of boolean; const afields: array of tfield); + procedure appendrecord(const values: variantarty); + procedure appenddata(const adata: variantararty; + const afields: array of tfield); + //[] -> all + procedure getfieldclass(const fieldtype: tfieldtype; out result: tfieldclass); + procedure beginfilteredit(const akind: filtereditkindty); + procedure clearfilter(); + procedure endfilteredit; + procedure begindisplaydata; {$ifdef FPC}inline;{$endif} + procedure enddisplaydata; {$ifdef FPC}inline;{$endif} + function getcanmodify: boolean; + function updatesortfield(const alink: tfielddatalink; + const adescend: boolean): boolean; + //true if index active + + procedure modified; + procedure dataevent(const event: tdataevent; info: ptrint); + property recno: integer read getrecno write setrecno; + property recnozerobased: integer read getrecnozerobased + write setrecnozerobased; + property recnooffset: integer read frecnooffset; + function findrecno(const arecno: integer; + const options: recnosearchoptionsty = []): integer; + function findrecnozerobased(const arecno: integer; + const options: recnosearchoptionsty = []): integer; + + function moveby(const distance: integer): integer; + function islastrecord: boolean; + procedure internalinsert; + procedure internaldelete; + procedure internalopen; + procedure internalclose; + procedure closequery(var amodalresult: modalresultty); overload; + function closequery: boolean; overload; //true if ok + function post(const aafterpost: afterdbopeventty = nil): boolean; + //calls post if in edit or insert state, + //returns true if ok +// procedure insert(const aafterinsert: afterdbopeventty = nil); + function delete(const aafterdelete: afterdbopeventty = nil): boolean; + function posting: boolean; //true if in inner post procedure + function posting1: boolean; //true if in outer post procedure + procedure postcancel; //can be called in BeforePost, calls cancel after abort + procedure cancel; + function canceling: boolean; + function refreshing(): boolean; + function deleting(): boolean; + function emptyinsert: boolean; + procedure refresh(const restorerecno: boolean = false; + const delayus: integer = -1); + //-1 -> no delay, 0 -> in onidle + procedure checkrefresh; //makes pending delayed refresh + procedure copyrecord(const aappend: boolean = false); + function copying(): boolean; + + function assql(const avalue: boolean): msestring; overload; + function assql(const avalue: msestring): msestring; overload; + function assql(const avalue: integer): msestring; overload; + function assql(const avalue: int64): msestring; overload; + function assql(const avalue: currency): msestring; overload; + function assqlcurrency(const avalue: realty): msestring; overload; + function assql(const avalue: realty): msestring; overload; + function assql(const avalue: tdatetime): msestring; overload; + function assqldate(const avalue: tdatetime): msestring; + function assqltime(const avalue: tdatetime): msestring; + + property noedit: boolean read getnoedit write setnoedit; + property noinsert: boolean read getnoinsert write setnoinsert; + property noappend: boolean read getnoappend write setnoappend; + property noupdate: boolean read getnoupdate write setnoupdate; + property nodelete: boolean read getnodelete write setnodelete; + property asmsestring[const afieldname: string]: msestring + read getasmsestring write setasmsestring; + + published + property fields: tpersistentfields read ffields write setfields; + property options: datasetoptionsty read foptions write setoptions + default defaultdscontrolleroptions; +// property delayedapplycount: integer read fdelayedapplycount +// write setdelayedapplycount default 0; + //0 -> no autoapply + property onstatechanged: datasetstatechangedeventty read fonstatechanged + write fonstatechanged; + property onupdatemasteredit: masterdataseteventty read fonupdatemasteredit + write fonupdatemasteredit; + property onupdatemasterinsert: masterdataseteventty + read fonupdatemasterinsert write fonupdatemasterinsert; + property onbeforepost: tdatasetnotifyevent read fonbeforepost + write fonbeforepost; + property onafterpost: afterdbopeventty read fonafterpost write fonafterpost; + //always called + property onbeforedelete: tdatasetnotifyevent read fonbeforedelete + write fonbeforedelete; + property onafterdelete: afterdbopeventty read fonafterdelete + write fonafterdelete; + //always called + property onbeforecopyrecord: tdatasetnotifyevent read fonbeforecopyrecord + write fonbeforecopyrecord; + property onaftercopyrecord: tdatasetnotifyevent read fonaftercopyrecord + write fonaftercopyrecord; + end; + + idbcontroller = interface(iactivatorclient)[miid_idbcontroller] + procedure setinheritedconnected(const avalue: boolean); + function readsequence(const sequencename: string): msestring; + function sequencecurrvalue(const sequencename: string): msestring; + function writesequence(const sequencename: string; + const avalue: largeint): msestring; + function ExecuteDirect(const SQL : mseString; + const aisutf8: boolean): integer; + procedure updateutf8(var autf8: boolean); + end; + + tfieldlink = class; + + tfieldlinkdatalink = class(tfielddatalink) + private + fdatasource: tdatasource; + fowner: tfieldlink; + protected + procedure updatedata; override; + public + constructor create(const aowner: tfieldlink); + destructor destroy; override; + end; + + fieldeventty = procedure(const afield: tfield) of object; + + fieldlinkoptionty = (flo_disabled,flo_onlyifnull,flo_notifunmodifiedinsert, + flo_utc); + fieldlinkoptionsty = set of fieldlinkoptionty; + + tfieldlink = class(tmsecomponent,idbeditinfo) + private + fdestdatalink: tfieldlinkdatalink; + fonupdatedata: fieldeventty; + foptions: fieldlinkoptionsty; + function getdestdataset: tdataset; + procedure setdestdataset(const avalue: tdataset); + function getdestdatafield: string; + procedure setdestdatafield(const avalue: string); + //idbeditinfo + procedure getfieldtypes(out propertynames: stringarty; + out fieldtypes: fieldtypesarty); + function getdataset(const aindex: integer): tdataset; + function getenabled: boolean; + procedure setenabled(const avalue: boolean); + protected + procedure updatedata(const afield: tfield); virtual; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function field: tfield; + property enabled: boolean read getenabled write setenabled; + published + property destdataset: tdataset read getdestdataset write setdestdataset; + property destdatafield: string read getdestdatafield write setdestdatafield; + property options: fieldlinkoptionsty read foptions write foptions default []; + property onupdatedata: fieldeventty read fonupdatedata write fonupdatedata; + end; + + ttimestampfieldlink = class(tfieldlink) + protected + procedure updatedata(const afield: tfield); override; + end; + + tfieldfieldlink = class(tfieldlink,idbeditinfo) + private + fsourcedatalink: tfielddatalink; + function getfieldname: string; + procedure setfieldname(const avalue: string); + function getdatasource: tdatasource; + function getdatasource1(const aindex: integer): tdatasource; + procedure setdatasource(const avalue: tdatasource); + procedure readdatafield(reader: treader); + //idbeditinfo + procedure getfieldtypes(out propertynames: stringarty; + out fieldtypes: fieldtypesarty); + function getdataset(const aindex: integer): tdataset; + protected + procedure updatedata(const afield: tfield); override; + procedure defineproperties(filer: tfiler); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function sourcefield: tfield; + published + property fieldname: string read getfieldname + write setfieldname; + property datasource: tdatasource read getdatasource write setdatasource; + end; + + tparamconnector = class; + + tmseparam = class(tparam,idbeditinfo) + private + fconnector: tparamconnector; + fdatalink: tfielddatalink; + procedure setasvariant(const avalue: variant); +// function getasid: int64; +// procedure setasid(const avalue: int64); +// function getasmsestring: msestring; +// procedure setasmsestring(const avalue: msestring); + function getdatasource: tdatasource; + procedure setdatasource(const avalue: tdatasource); + function getfieldname: string; + procedure setfieldname(const avalue: string); + //idbeditinfo + function getdataset(const aindex: integer): tdataset; + procedure getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); + function isparamstored: boolean; + procedure setconnector(const avalue: tparamconnector); + public + constructor Create(ACollection: TCollection); overload; override; + destructor destroy; override; +// property asid: int64 read getasid write setasid; //-1 -> null +// property asmsestring: msestring read getasmsestring write setasmsestring; + published + property connector: tparamconnector read fconnector write setconnector; + property datasource: tdatasource read getdatasource write setdatasource; + property fieldname: string read getfieldname write setfieldname; + property value : variant read getasvariant write setasvariant + stored isparamstored; + end; + + tparamconnector = class(tmsecomponent) + private + fparam: tmseparam; + function getparam: tmseparam; + public + destructor destroy; override; + property param: tmseparam read getparam; + end; + + tmseparams = class(tparams) + private + fisutf8: boolean; + function getitem(const index: integer): tmseparam; + procedure setitem(const index: integer; const avalue: tmseparam); + function getvalues: variantarty; + procedure setvalues(const avalue: variantarty); + public + constructor create(aowner: tpersistent); overload; + constructor create; overload; + procedure updatevalues; + Function ParseSQL(const SQL: mseString; const DoCreate: Boolean): mseString; overload; + Function ParseSQL(const SQL: mseString; + const DoCreate,EscapeSlash,EscapeRepeat: Boolean; + const ParameterStyle : TParamStyle): mseString; overload; + Function ParseSQL(const SQL: mseString; + const DoCreate,EscapeSlash,EscapeRepeat: Boolean; + const ParameterStyle : TParamStyle; + var ParamBinding: TParambinding): mseString; overload; + Function ParseSQL(const SQL: mseString; + const DoCreate,EscapeSlash,EscapeRepeat: Boolean; + const ParameterStyle : TParamStyle; var ParamBinding: TParambinding; + var ReplaceString : msestring): mseString; overload; + function expandvalues(sql: msestring; const aparambindings: tparambinding; + const aparamreplacestring: msestring): msestring; overload; + //sql parsed with psSimulated + function expandvalues(const sql: msestring): msestring; overload; + function asdbstring(const index: integer): string; + function bindnames(const anames: msestringarty): integerarty; + //returns index in anames for paramnames, -1 if not found + //case sensitive + property isutf8: boolean read fisutf8 write fisutf8; + property items[const index: integer]: tmseparam read getitem write setitem; default; + property values: variantarty read getvalues write setvalues; + end; + +const + fieldtypeclasses: array[fieldclasstypety] of fieldclassty = + (tfield,tstringfield,tguidfield,tnumericfield, + tlongintfield,tlargeintfield,tsmallintfield, + twordfield,tautoincfield,tfloatfield,tcurrencyfield, + tbooleanfield, + tdatetimefield,tdatefield,ttimefield, + tbinaryfield,tbytesfield,tvarbytesfield, + tbcdfield,tblobfield,tmemofield,tgraphicfield, + tvariantfield); + + tfieldtypetotypety: array[tfieldtype] of fieldclasstypety = ( + //ftUnknown, ftString, ftSmallint, ftInteger, ftWord, + ft_unknown,ft_string,ft_smallint,ft_longint,ft_word, + //ftBoolean, ftFloat, ftCurrency, ftBCD, ftDate, ftTime, ftDateTime, + ft_boolean,ft_float,ft_currency,ft_bcd,ft_date,ft_time,ft_datetime, + //ftBytes, ftVarBytes, ftAutoInc, ftBlob, ftMemo, ftGraphic, ftFmtMemo, + ft_bytes,ft_varbytes,ft_autoinc,ft_blob,ft_memo,ft_graphic,ft_memo, + //ftParadoxOle, ftDBaseOle, ftTypedBinary, ftCursor, ftFixedChar, + ft_unknown,ft_unknown,ft_unknown,ft_unknown,ft_string, + //ftWideString, ftLargeint, ftADT, ftArray, ftReference, + ft_string,ft_largeint,ft_unknown,ft_unknown,ft_unknown, + //ftDataSet, ftOraBlob, ftOraClob, ftVariant, ftInterface, + ft_unknown,ft_unknown,ft_unknown,ft_variant,ft_unknown, + //ftIDispatch, ftGuid, ftTimeStamp, ftFMTBcd + ft_unknown, ft_guid,ft_unknown, ft_unknown + //ftFixedWideChar,ftWideMemo + ,ft_string, ft_string + ); + + realfcomp = [ftfloat,ftcurrency]; + datetimefcomp = [ftdate,fttime,ftdatetime]; + blobfcomp = [ftblob,ftgraphic,ftmemo]; + memofcomp = [ftmemo]; + longintfcomp = [ftboolean,ftsmallint,ftinteger,ftword]; + largeintfcomp = longintfcomp + [ftlargeint]; + stringfcomp = [ftstring,ftguid,ftfixedchar,ftwidestring,ftfixedwidechar, + ftwidememo]; + booleanfcomp = [ftboolean,ftsmallint,ftinteger,ftword]; + + fieldcompatibility: array[tfieldtype] of fieldtypesty = ( + //ftUnknown, ftString, ftSmallint, ftInteger, ftWord, + [ftunknown],stringfcomp,longintfcomp,longintfcomp,longintfcomp, + //ftBoolean, ftFloat, ftCurrency, ftBCD, + booleanfcomp,realfcomp,realfcomp,[ftbcd], + //ftDate, ftTime, tDateTime, + datetimefcomp,datetimefcomp,datetimefcomp, + //ftBytes, ftVarBytes, ftAutoInc, + [ftbytes],[ftvarbytes],[ftautoinc], + // ftBlob, ftMemo, ftGraphic, ftFmtMemo, + blobfcomp,memofcomp,blobfcomp,memofcomp, + //ftParadoxOle, ftDBaseOle, ftTypedBinary, ftCursor, tFixedChar, + [ftParadoxOle],[ftDBaseOle],[ftTypedBinary],[ftCursor],stringfcomp, + //ftWideString, ftLargeint, ftADT, ftArray, ftReference, + stringfcomp,[ftLargeint],[ftADT],[ftArray],[ftReference], + //ftDataSet, ftOraBlob, ftOraClob, ftVariant, ftInterface, + [ftDataSet],[ftOraBlob],[ftOraClob],[ftVariant],[ftInterface], + //ftIDispatch, ftGuid, ftTimeStamp, ftFMTBcd); + [ftIDispatch],[ftGuid],[ftTimeStamp],[ftFMTBcd] + //ftFixedWideChar,ftWideMemo + ,stringfcomp,stringfcomp + ); + +function getdsfields(const adataset: tdataset; + const afields: array of tfield): fieldarty; + //[] -> all +function getfielddefar(const fielddefs: tfielddefs): fielddefarty; + +function getmsefieldclass(const afieldtype: tfieldtype): tfieldclass; overload; +function getmsefieldclass(const afieldtype: fieldclasstypety): tfieldclass; overload; +function fieldvariants(const afields: array of tfield): variantarty; +function fieldclasstoclasstyp(const fieldclass: fieldclassty): fieldclasstypety; +function fieldtosql(const field: tfield): msestring; +function fieldtooldsql(const field: tfield): msestring; +function paramtosql(const aparam: tparam): msestring; +function fieldchanged(const field: tfield): boolean; +function curfieldchanged(const field: tfield): boolean; +procedure fieldtoparam(const field: tfield; const param: tparam); +procedure copyfieldvalues(const source: tdataset; const dest: tdataset); +procedure msestringtoparam(const avalue: msestring; const param: tparam); +function getasmsestring(const field: tfield; const utf8: boolean = true): msestring; +procedure setasmsestring(const avalue: msestring; + const field: tfield; const utf8: boolean = true); +function checkfieldcompatibility(const afield: tfield; + const adatatype: tfieldtype): boolean; + //true if ok +function vartorealty(const avalue: variant): realty; +{ +function locaterecord(const adataset: tdataset; const autf8: boolean; + const key: msestring; const field: tfield; + const options: locateoptionsty = []): locateresultty; +function locaterecord(const adataset: tdataset; const key: integer; + const field: tfield; + const options: locateoptionsty = []): locateresultty; +} +function locaterecord(const adataset: tdataset; const fields: array of tfield; + const keys: array of const; //nil -> NULL field + const isnull: array of boolean; + const keyoptions: array of locatekeyoptionsty; + const options: locaterecordoptionsty): locateresultty; + +function encodesqlstring(const avalue: msestring): msestring; +function encodesqlcstring(const avalue: msestring): msestring; +function encodesqlblob(const avalue: string): msestring; +function encodesqlinteger(const avalue: integer): msestring; +function encodesqllongword(const avalue: longword): msestring; +function encodesqllargeint(const avalue: int64): msestring; +function encodesqlqword(const avalue: qword): msestring; +function encodesqldatetime(const avalue: tdatetime): msestring; +function encodesqldate(const avalue: tdatetime): msestring; +function encodesqltime(const avalue: tdatetime): msestring; +function encodesqlfloat(const avalue: real): msestring; +function encodesqlcurrency(const avalue: currency): msestring; +function encodesqlboolean(const avalue: boolean): msestring; +function encodesqlvariant(const avalue: variant; cstyle: boolean): msestring; + +procedure regfieldclass(const atype: fieldclasstypety; const aclass: fieldclassty); + +procedure varianttorealty(const value: variant; out dest: realty); overload; +function varianttorealty(const value: variant):realty; overload; +procedure realtytovariant(const value: realty; out dest: variant); overload; +function realtytovariant(const value: realty): variant; overload; +function varianttoid(const value: variant): int64; //null -> -1 +function idtovariant(const value: int64): variant; //-1 -> null +function varianttomsestring(const value: variant): msestring; //null -> '' +function msestringtovariant(const value: msestring): variant; //'' -> null + +function dbtrystringtoguid(const value: string; out guid: tguid): boolean; +function dbstringtoguid(const value: string): tguid; +function dbguidtostring(const avalue: tguid): string; +function dbcreateguidstring: string; +function guidparam(const value: tguid): varrecarty; + +function opentodynarrayft(const items: array of tfieldtype): fieldtypearty; + +implementation +uses + rtlconsts,msefileutils,typinfo,{$ifdef FPC}dbconst{$else}dbconst_del{$endif}, + msearrayutils,mseformatstr,msebits,msefloattostr,msebufdataset, + msereal,variants,msedate,msesys,sysconst + {,msedbgraphics}{$ifdef unix},cwstring{$endif}; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +const + fieldnamedummy = ';%)(mse'; +var + msefieldtypeclasses: array[fieldclasstypety] of fieldclassty = + // ft_unknown, ft_string, ft_guid, ft_numeric, + (tmsefield,tmsestringfield,tmseguidfield,tmsenumericfield, + // ft_longint, ft_largeint, ft_smallint, + tmselongintfield,tmselargeintfield,tmsesmallintfield, + // ft_word, ft_autoinc, ft_float, ft_currency, + tmsewordfield,tmseautoincfield,tmsefloatfield,tmsecurrencyfield, + // ft_boolean, + tmsebooleanfield, + // ft_datetime, ft_date, ft_time, + tmsedatetimefield,tmsedatefield,tmsetimefield, + // ft_binary, ft_bytes, ft_varbytes, + tmsebinaryfield,tmsebytesfield,tmsevarbytesfield, + // ft_bcd, ft_blob, ft_memo, ft_graphic, + tmsebcdfield,tmseblobfield,tmsememofield,nil{tmsegraphicfield}, + // ft_variant + tmsevariantfield); + +type + tdataset1 = class(tdataset); + tfielddef1 = class(tfielddef); + tcollection1 = class(tcollection); + tparam1 = class(tparam); + tdatasource1 = class(tdatasource); + tmsebufdataset1 = class(tmsebufdataset); + tfield1 = class(tfield); + +function dbtrystringtoguid(const value: string; out guid: tguid): boolean; +var + int1: integer; + po1: pchar; + + function readbyte: byte; + var + by1: byte; + begin + by1:= hexchars[po1^]; + inc(po1); + if shortint(by1) < 0 then begin + dbtrystringtoguid:= false; + end; + result:= hexchars[po1^]; + inc(po1); + if shortint(result) < 0 then begin + dbtrystringtoguid:= false; + end; + result:= result or (by1 shl 4); + end; + + function checkhyphen: boolean; {$ifdef FPC}inline;{$endif} + begin + result:= po1^ = '-'; + inc(po1); + end; + +begin + po1:= pointer(value); + result:= length(value) = guidbuffersize; + if not result and (length(value) = guidbuffersize+2) and (value[1]='{') and + (value[guidbuffersize+2]='}') then begin + inc(po1); + result:= true; + end; + if result then begin + with {$ifndef FPC}tguid_fpc({$endif}guid{$ifndef FPC}){$endif} do begin + time_low:= (readbyte shl 24) or (readbyte shl 16) or (readbyte shl 8) or + readbyte; +{$warnings off} + if checkhyphen then begin + time_mid:= (readbyte shl 8) or readbyte; + if checkhyphen then begin + time_hi_and_version:= (readbyte shl 8) or readbyte; + if checkhyphen then begin + clock_seq_hi_and_reserved:= readbyte; + clock_seq_low:= readbyte; + if checkhyphen then begin + for int1:= 0 to high(node) do begin + node[int1]:= readbyte; + end; + end; + end; + end; + end; + end; + end; +end; +{$warnings on} + +function dbstringtoguid(const value: string): tguid; +begin + if not dbtrystringtoguid(value,result) then begin + raise econverterror.createfmt(sinvalidguid, [value]); + end; +end; + +function dbguidtostring(const avalue: tguid): string; +var + int1: integer; +begin + with {$ifndef FPC}tguid_fpc({$endif}avalue{$ifndef FPC}){$endif}do begin + result:= valtohex(time_low)+'-'+valtohex(time_mid)+'-'+ + valtohex(time_hi_and_version)+'-'+ + valtohex(clock_seq_hi_and_reserved)+valtohex(clock_seq_low)+'-'; + for int1:= 0 to high(node) do begin + result:= result+valtohex(node[int1]); + end; + end; +end; + +function dbcreateguidstring: string; +var + id: tguid; +begin + createguid(id); + result:= dbguidtostring(id); +end; + +function guidparam(const value: tguid): varrecarty; +begin + setlength(result,1); + with result[0] do begin + vtype:= mse_vtguid; + vpointer:= @value; + end; +end; + +function opentodynarrayft(const items: array of tfieldtype): fieldtypearty; +var + int1: integer; +begin + setlength(result,length(items)); + for int1:= 0 to high(items) do begin + result[int1]:= items[int1]; + end; +end; + +function getnumdisplaytext(const sender: tnumericfield; const avalue: double; + const adisplaytext: boolean; const acurrency: boolean): string; +var + str1: ansistring; +begin + with sender do begin + if adisplaytext then begin + str1:= sender.displayformat; + if (str1 = '') and acurrency then begin + str1:= 'c'; + end; + end + else begin + str1:= editformat; + end; + end; + result:= ansistring(formatfloatmse(avalue,msestring(str1))); +end; + +procedure varianttorealty(const value: variant; out dest: realty); +begin + if varisnull(value) then begin + dest:= emptyreal; + end + else begin + real(dest):= value; + end; +end; + +function varianttorealty(const value: variant): realty; overload; +begin + if varisnull(value) then begin + result:= emptyreal; + end + else begin + real(result):= value; + end; +end; + +procedure realtytovariant(const value: realty; out dest: variant); +begin + if value = emptyreal then begin + dest:= null; + end + else begin + dest:= value; + end; +end; + +function realtytovariant(const value: realty): variant; overload; +begin + if value = emptyreal then begin + result:= null; + end + else begin + result:= value; + end; +end; + +function varianttoid(const value: variant): int64; +begin + if varisnull(value) or varisempty(value) then begin + result:= -1; + end + else begin + result:= value; + end; +end; + +function idtovariant(const value: int64): variant; +begin + if value = -1 then begin + result:= null; + end + else begin + result:= value; + end; +end; + +function varianttomsestring(const value: variant): msestring; //null -> '' +begin + if varisnull(value) or varisempty(value) then begin + result:= ''; + end + else begin + result:= value; + end; +end; + +function msestringtovariant(const value: msestring): variant; //'' -> null +begin + if value = '' then begin + result:= null; + end + else begin + result:= value; + end; +end; + +function getdsfields(const adataset: tdataset; + const afields: array of tfield): fieldarty; +var + int1: integer; +begin + if high(afields) >= 0 then begin + setlength(result,length(afields)); + for int1:= 0 to high(result) do begin + result[int1]:= afields[int1]; + end; + end + else begin + with adataset do begin + setlength(result,fields.count); + for int1:= 0 to high(result) do begin + result[int1]:= fields[int1]; + end; + end; + end; +end; + +function getfielddefar(const fielddefs: tfielddefs): fielddefarty; +var + po1: pfielddefty; + int1: integer; +begin + setlength(result,fielddefs.count); + for int1:= 0 to high(result) do begin + po1:= @result[int1]; + with fielddefs[int1] do begin + po1^.datatype:= datatype; + po1^.size:= size; + po1^.name:= name; + end; + end; +end; + +procedure regfieldclass(const atype: fieldclasstypety; + const aclass: fieldclassty); +begin + msefieldtypeclasses[atype]:= aclass; +end; + +function getmsefieldclass(const afieldtype: tfieldtype): tfieldclass; +begin + result:= msefieldtypeclasses[tfieldtypetotypety[afieldtype]]; +end; + +function getmsefieldclass(const afieldtype: fieldclasstypety): tfieldclass; +begin + result:= msefieldtypeclasses[afieldtype]; +end; + +function fieldvariants(const afields: array of tfield): variantarty; +var + int1: integer; +begin + setlength(result,length(afields)); + for int1:= 0 to high(result) do begin + result[int1]:= afields[int1].asvariant; + end; +end; + +{ +function getasmsestring(const field: tfield): msestring; +begin + if field is tmsestringfield then begin + result:= tmsestringfield(field).asmsestring; + end + else begin + if field is tmsememofield then begin + result:= tmsememofield(field).asmsestring; + end + else begin + result:= field.asstring; + end; + end; +end; +} +function getasmsestring(const field: tfield; const utf8: boolean = true): msestring; +begin + if field = nil then begin + result:= ''; + end + else begin + if field is tmsestringfield then begin + result:= tmsestringfield(field).asmsestring; + end + else begin + if field is tmsememofield then begin + result:= tmsememofield(field).asmsestring; + end + else begin + if utf8 then begin + result:= utf8tostringansi(field.asstring); + end + else begin + result:= msestring(field.asstring); + end; + end; + end; + end; +end; + +procedure setasmsestring(const avalue: msestring; + const field: tfield; const utf8: boolean = true); +begin + if field <> nil then begin + if field is tmsestringfield then begin + tmsestringfield(field).asmsestring:= avalue; + end + else begin + if field is tmsememofield then begin + tmsememofield(field).asmsestring:= avalue; + end + else begin + if utf8 then begin + field.asstring:= stringtoutf8ansi(avalue); + end + else begin + field.asstring:= ansistring(avalue); + end; + end; + end; + end; +end; + +procedure msestringtoparam(const avalue: msestring; const param: tparam); +var + intf1: igetdscontroller; +begin + with param do begin + if dataset <> nil then begin + if getcorbainterface(dataset,typeinfo(igetdscontroller),intf1) then begin + if dso_utf8 in intf1.getcontroller.options then begin + param.asstring:= stringtoutf8ansi(avalue); + exit; + end; + end; + end; + param.asstring:= ansistring(avalue); + end; +end; + +procedure fieldtoparam(const field: tfield; const param: tparam); +begin + param.value:= field.value; //paramvalue is variant anyway + { + with param do begin + case field.datatype of + ftUnknown: DatabaseErrorFmt(SUnknownParamFieldType,[Name],DataSet); + // Need TField.AsSmallInt + ftSmallint: AsSmallInt:= Field.AsInteger; + // Need TField.AsWord + ftWord: AsWord:= Field.AsInteger; + ftInteger, + ftAutoInc: AsInteger:= Field.AsInteger; + // Need TField.AsCurrency + ftCurrency: AsCurrency:= Field.asFloat; + ftFloat: AsFloat:= Field.asFloat; + ftBoolean: AsBoolean:= Field.AsBoolean; + ftBlob, + ftGraphic..ftTypedBinary, + ftOraBlob, + ftOraClob, + ftString, + ftMemo, + ftAdt, + ftFixedChar: AsString:= Field.AsString; + ftTime, + ftDate, + ftDateTime: AsDateTime:= Field.AsDateTime; + ftBytes, + ftVarBytes: ; // Todo. + else begin + if not (DataType in [ftCursor, ftArray, ftDataset,ftReference]) then begin + DatabaseErrorFmt(SBadParamFieldType, [Name], DataSet); + end; + end; + end; + end; + } +end; + +procedure copyfieldvalues(const source: tdataset; const dest: tdataset); +var + int1: integer; + df: tfield; +begin + for int1:= 0 to source.fieldcount-1 do begin + with source.fields[int1] do begin + if visible then begin + df:= dest.findfield(fieldname); + if (df <> nil) and not df.readonly then begin + df.value:= value; + end; + end; + end; + end; +end; + +function encodesqlstring(const avalue: msestring): msestring; +var + int1: integer; + str1: msestring; + po1: pmsechar; +begin + str1:= avalue; + setlength(result,length(str1)*2 + 2); //max + po1:= pmsechar(result); + po1^:= ''''; + inc(po1); + for int1:= 1 to length(str1) do begin + po1^:= str1[int1]; + if po1^ = '''' then begin + inc(po1); + po1^:= ''''; + end; + inc(po1); + end; + po1^:= ''''; + setlength(result,po1-pmsechar(result)+1); +end; + +function encodesqlcstring(const avalue: msestring): msestring; +var + po1: pmsechar; + innum: boolean; +begin + result:= '"'; + po1:= pmsechar(avalue); + innum:= false; + while po1^ <> #0 do begin + if (po1^ < #$20) {or (po1^ > #$ff)} or (po1^ = #$7f) then begin + innum:= true; + if po1^ < #$100 then begin + result:= result + '\x'+hextostrmse(ord(po1^),2); + end + else begin + result:= result + '\x'+hextostrmse(ord(po1^),4); + end; + end + else begin + if po1^ = '"' then begin + result:= result + '\"'; + innum:= false; + end + else begin + if innum then begin + result:= result + '" "'+po1^; + innum:= false; + end + else begin + result:= result + po1^; + end; + end; + end; + inc(po1); + end; + result:= result + '"'; +end; + +function encodesqlblob(const avalue: string): msestring; +var + int1: integer; + po1: pmsechar; + po2: pbyte; + +begin + setlength(result,length(avalue)*2+3); + po1:= pmsechar(result); + po1^:= 'x'; + inc(po1); + po1^:= ''''; + inc(po1); + po2:= pointer(avalue); + for int1:= 0 to length(avalue) - 1 do begin + po1^:= msechar(byte(charhex[po2^ shr 4])); + inc(po1); + po1^:= msechar(byte(charhex[po2^ and $0f])); + inc(po1); + inc(po2); + end; + po1^:= ''''; +end; + +function encodesqlinteger(const avalue: integer): msestring; +begin + result:= inttostrmse(avalue); +end; + +function encodesqllongword(const avalue: longword): msestring; +begin + result:= msestring(wordtostr(avalue)); +end; + +function encodesqllargeint(const avalue: int64): msestring; +begin + result:= inttostrmse(avalue); +end; + +function encodesqlqword(const avalue: qword): msestring; +begin + result:= inttostrmse(avalue); +end; + +function encodesqldatetime(const avalue: tdatetime): msestring; +begin + result := '''' + + msestring(formatdatetime('yyyy-mm-dd hh:mm:ss',avalue)) + ''''; +end; + +function encodesqldate(const avalue: tdatetime): msestring; +begin + result:= '''' + msestring(formatdatetime('yyyy-mm-dd',avalue)) + ''''; +end; + +function encodesqltime(const avalue: tdatetime): msestring; +begin + result:= '''' + msestring(formatdatetime('hh:mm:ss',avalue)) + ''''; +end; + +function encodesqlfloat(const avalue: real): msestring; +begin +// result:= floattostr(avalue,defaultformatsettingsdot); + result:= doubletostring(avalue); +// result:= replacechar(floattostr(avalue), +// defaultformatsettings.decimalseparator,'.'); +//( result:= formatfloatmse(avalue,''); +end; + +function encodesqlcurrency(const avalue: currency): msestring; +begin +// result:= formatfloat('0.####',avalue,defaultformatsettingsdot); + result:= formatfloatmse(avalue,'0.####',defaultformatsettingsmse,true); +// result:= replacechar(formatfloat('0.####',avalue), +// defaultformatsettings.decimalseparator,'.') +// result:= formatfloatmse(avalue,'0.####'); +end; + +function encodesqlboolean(const avalue: boolean): msestring; +begin + if avalue then begin + result:= '''t'''; + end + else begin + result:= '''f'''; + end; +end; + +function encodesqlvariant(const avalue: variant; + cstyle: boolean): msestring; + + function encode(const atype: word; const abase: pointer): msestring; + begin + result:= ''; + case atype of + varnull: result:= 'NULL'; + varsmallint: result:= encodesqlinteger(psmallint(abase)^); + varinteger: result:= encodesqlinteger(pinteger(abase)^); +{$ifndef FPUNONE} + varsingle: result:= encodesqlfloat(psingle(abase)^); + vardouble: result:= encodesqlfloat(pdouble(abase)^); + vardate: result:= encodesqldatetime(pdatetime(abase)^); +{$endif} + varcurrency: result:= encodesqlcurrency(pcurrency(abase)^); + varolestr: begin + if cstyle then begin + result:= encodesqlcstring(pwidestring(abase)^); + end + else begin + result:= encodesqlstring(pwidestring(abase)^); + end; + end; +// vardispatch = 9; +// varerror = 10; + varboolean: begin + if cstyle then begin + if pboolean(abase)^ then begin + result:= '"t"'; + end + else begin + result:= '"f"'; + end; + end + else begin + result:= encodesqlboolean(pboolean(abase)^); + end; + end; + varvariant: result:= encodesqlvariant(pvariant(abase)^,cstyle); +// varunknown = 13; +// vardecimal = 14; + varshortint: result:= encodesqlinteger(pshortint(abase)^); + varbyte: result:= encodesqlinteger(pbyte(abase)^); + varword: result:= encodesqlinteger(pword(abase)^); + varlongword: result:= encodesqlinteger(plongword(abase)^); + varint64: result:= encodesqllargeint(pint64(abase)^); +{$ifdef FPC} + varqword: result:= encodesqlinteger(pinteger(abase)^); +{$endif} +// varrecord = 36; + +// varstrarg = $48; + varstring: begin + if cstyle then begin + result:= encodesqlstring(msestring(pansistring(abase)^)); + end + else begin + result:= encodesqlcstring(msestring(pansistring(abase)^)); + end; + end; + end; + end; //encode + + procedure handlearray(const bounds: tvararrayboundarray; + const boundsindex: integer; + var data: pointer; const atype: word; const elementsize: integer); + var + int1: integer; + begin + if cstyle then begin + result:= result + '{'; + end + else begin + result:= result + '['; + end; + if boundsindex = 0 then begin + for int1:= 0 to bounds[boundsindex].elementcount-1 do begin + if int1 <> 0 then begin + result:= result+','; + end; + result:= result + encode(atype,data); + inc(pchar(data),elementsize); + end; + end + else begin + for int1:= 0 to bounds[boundsindex].elementcount-1 do begin + if int1 <> 0 then begin + result:= result+','; + end; + handlearray(bounds,boundsindex-1,data,atype,elementsize); + end; + end; + if cstyle then begin + result:= result + '}'; + end + else begin + result:= result + ']'; + end; + end; + +var + po1: pointer; +begin + with tvardata(avalue) do begin + if vtype and vararray <> 0 then begin + if not cstyle then begin + result:= 'ARRAY'; + end + else begin + result:= ''; + end; + with varray^ do begin + po1:= data; + handlearray(bounds,dimcount-1,po1,vtype and vartypemask,elementsize); + end; + end + else begin + cstyle:= false; + result:= encode(vtype,@vsmallint); + end; + end; +end; + +function fieldtosql(const field: tfield): msestring; +begin + if (field = nil) or field.isnull then begin + result:= 'NULL' + end + else begin + case field.datatype of + ftstring,ftguid: begin + if not (field is tmsestringfield) {or + (tmsestringfield(field).fdsintf = nil)} then begin + result:= encodesqlstring(msestring(field.asstring)); +// result:= tmsestringfield(field).assql; + end + else begin + with tmsestringfield(field) do begin + result:= encodesqlstring(asmsestring); +// result:= fdsintf.getcontroller.assql(asmsestring); + end; + end; + end; + ftmemo: begin + if field is tmsememofield then begin + result:= encodesqlstring(tmsememofield(field).asmsestring); + end + else begin + result:= encodesqlstring(msestring(field.asstring)); + end; + end; + ftblob,ftgraphic,ftbytes,ftvarbytes: begin + result:= encodesqlblob(field.asstring); + end; + ftdate: begin + result := encodesqldate(field.asdatetime) + end; + fttime: begin + result := encodesqltime(field.asdatetime) + end; + ftdatetime: begin + result:= encodesqldatetime(field.asdatetime); + end; + ftfloat,ftcurrency: begin + result:= encodesqlfloat(field.asfloat); + end; + ftbcd: begin + result:= encodesqlcurrency(field.ascurrency); + end; + ftboolean: begin + result:= encodesqlboolean(field.asboolean); + end; + ftvariant: begin + result:= encodesqlvariant(field.asvariant,false); + end; + else begin + result := msestring(field.asstring); + end; + end; + end; +end; + +function fieldtooldsql(const field: tfield): msestring; +var + statebefore: tdatasetstate; +begin + statebefore:= field.dataset.state; + tdataset1(field.dataset).settempstate(dsoldvalue); + result:= fieldtosql(field); + tdataset1(field.dataset).restorestate(statebefore); +end; + +function paramtosql(const aparam: tparam): msestring; +begin + with aparam do begin + if (aparam = nil) or isnull then begin + result:= 'NULL' + end + else begin + case datatype of + { + ftstring,ftwidestring: begin + if (aparam.collection is tmseparams) and + tmseparams(aparam.collection).isutf8 then begin + result:= encodesqlstring(stringtoutf8ansi(aswidestring)); + end + else begin + result:= encodesqlstring(asstring); + end; + end; + } + ftwidestring: begin + result:= encodesqlstring(aswidestring); + end; + ftstring,ftguid: begin + result:= encodesqlstring(msestring(asstring)); + end; + ftmemo: begin + if (aparam.collection is tmseparams) and tmseparams(collection).isutf8 then begin + result:= encodesqlstring(utf8tostringansi(asstring)); + end + else begin + result:= encodesqlstring(msestring(asstring)); + end; + end; + ftblob,ftgraphic,ftbytes,ftvarbytes: begin + result:= encodesqlblob(asstring); + end; + ftdate: begin + result := encodesqldate(asdatetime) + end; + fttime: begin + result := encodesqltime(asdatetime) + end; + ftdatetime: begin + result:= encodesqldatetime(asdatetime); + end; + ftfloat,ftcurrency: begin + result:= encodesqlfloat(asfloat); + end; + ftbcd: begin + result:= encodesqlcurrency(ascurrency); + end; + ftboolean: begin + result:= encodesqlboolean(asboolean); + end; + ftvariant: begin + result:= encodesqlvariant(value,false); + end; + else begin + result:= msestring(asstring); + end; + end; + end; + end; +end; + +function dofieldchanged(const field: tfield; const astate: tdatasetstate): boolean; + //todo: fast compare in tbufdataset +var + statebefore: tdatasetstate; + isnull: boolean; + ds1: tdataset1; + int1: integer; + bo1: boolean; + str1: string; + wstr1: widestring; + mstr1: msestring; + rea1: real; + int641: int64; + cur1: currency; +begin + result:= false; + if field.fieldno > 0 then begin + ds1:= tdataset1(field.dataset); + statebefore:= ds1.state; + isnull:= field.isnull; + if field is tmsestringfield then begin + mstr1:= tmsestringfield(field).asmsestring; + ds1.settempstate(astate); + result:= (field.isnull xor isnull) or + (mstr1 <> tmsestringfield(field).asmsestring); + end + else begin + case field.datatype of + ftString,ftFixedChar,ftmemo,ftblob,ftguid: begin + str1:= field.asstring; + ds1.settempstate(astate); + result:= (field.isnull xor isnull) or (str1 <> field.asstring); + end; + ftSmallint,ftInteger,ftWord: begin + int1:= field.asinteger; + ds1.settempstate(astate); + result:= (field.isnull xor isnull) or (int1 <> field.asinteger); + end; + ftBoolean: begin + bo1:= field.asboolean; + ds1.settempstate(astate); + result:= (field.isnull xor isnull) or (bo1 <> field.asboolean); + end; + ftFloat,ftcurrency,ftDate,ftTime,ftDateTime,ftTimeStamp,ftFMTBcd: begin + rea1:= field.asfloat; + ds1.settempstate(astate); + result:= (field.isnull xor isnull) or (rea1 <> field.asfloat); + end; + {ftCurrency,}ftBCD: begin + cur1:= field.ascurrency; + ds1.settempstate(astate); + result:= (field.isnull xor isnull) or (cur1 <> field.ascurrency); + end; + // ftBytes, ftVarBytes, ftAutoInc, ftBlob, ftMemo, ftGraphic, ftFmtMemo, + // ftParadoxOle, ftDBaseOle, ftTypedBinary, ftCursor, + ftWideString: begin + // wstr1:= field.aswidestring; + wstr1:= widestring(field.asstring); + ds1.settempstate(astate); + // result:= (field.isnull xor isnull) or (wstr1 <> field.aswidestring); + result:= (field.isnull xor isnull) or + (wstr1 <> widestring(field.asstring)); + end; + ftLargeint: begin + int641:= tlargeintfield(field).aslargeint; + ds1.settempstate(astate); + result:= (field.isnull xor isnull) or + (int641 <> tlargeintfield(field).aslargeint); + end; + // ftADT, ftArray, ftReference, + // ftDataSet, ftOraBlob, ftOraClob, ftVariant, ftInterface, + // ftIDispatch, ftGuid, ftTimeStamp, ftFMTBcd); + + end; + end; + ds1.restorestate(statebefore); + end; +end; + +function fieldchanged(const field: tfield): boolean; +begin + result:= dofieldchanged(field,dsoldvalue); +end; + +function curfieldchanged(const field: tfield): boolean; +begin + result:= dofieldchanged(field,dscurvalue); +end; + +function fieldclasstoclasstyp(const fieldclass: fieldclassty): fieldclasstypety; +var + type1: fieldclasstypety; +begin + result:= fieldclasstypety(-1); + for type1:= low(fieldclasstypety) to high(fieldclasstypety) do begin + if fieldclass = fieldtypeclasses[type1] then begin + result:= type1; + break; + end; + end; + if ord(result) = -1 then begin + result:= ft_unknown; + for type1:= low(fieldclasstypety) to high(fieldclasstypety) do begin + if fieldclass = msefieldtypeclasses[type1] then begin + result:= type1; + break; + end; + end; + end; +end; + +function checkfieldcompatibility(const afield: tfield; + const adatatype: tfieldtype): boolean; + //true if ok +begin + result:= (afield.datatype in fieldcompatibility[adatatype]) or + (adatatype = ftguid) and (afield.datatype = ftbytes) and + (afield.size = 16); +end; + +function vartorealty(const avalue: variant): realty; +begin + if varisnull(avalue) then begin + result:= emptyreal; + end + else begin + real(result):= avalue; + end; +end; + +procedure fieldsetmsestring(const avalue: msestring; const sender: tfield; + const aintf: idsfieldcontroller); +begin + if (aintf <> nil) and (dso_utf8 in aintf.getcontroller.options) then begin + sender.asstring:= stringtoutf8ansi(avalue); + end + else begin + sender.asstring:= ansistring(avalue); //locale conversion + end; +end; + +function fieldgetmsestring(const sender: tfield; + const aintf: idsfieldcontroller): msestring; +begin + if (aintf <> nil) and (dso_utf8 in aintf.getcontroller.options) then begin + result:= utf8tostringansi(sender.asstring); + end + else begin + {$ifdef unix} + try + result:= msestring(sender.asstring); + except + on e: eiconv do begin + //no crash by iconverror + end + else begin + raise; + end; + end; + {$else} + result:= msestring(sender.asstring); + {$endif} + end; +end; +{ +function locaterecord(const adataset: tdataset; const key: integer; + const field: tfield; + const options: locateoptionsty = []): locateresultty; +var + bm: string; +begin + with adataset do begin + checkbrowsemode; + result:= loc_notfound; + bm:= bookmark; + disablecontrols; + try + if not (loo_noforward in options) then begin + while not eof do begin + if field.asinteger = key then begin + result:= loc_ok; + exit; + end; + next; + end; + end; + bookmark:= bm; + if not (loo_nobackward in options) then begin + while true do begin + if field.asinteger = key then begin + result:= loc_ok; + exit; + end; + if bof then begin + break; + end; + prior; + end; + end; + finally + try + if result <> loc_ok then begin + bookmark:= bm; + end; + finally + enablecontrols; + end; + end; + end; +end; + +function locaterecord(const adataset: tdataset; const key: int64; + const field: tfield; + const options: locateoptionsty = []): locateresultty; +var + bm: string; +begin + with adataset do begin + checkbrowsemode; + result:= loc_notfound; + bm:= bookmark; + disablecontrols; + try + if not (loo_noforward in options) then begin + while not eof do begin + if field.aslargeint = key then begin + result:= loc_ok; + exit; + end; + next; + end; + end; + bookmark:= bm; + if not (loo_nobackward in options) then begin + while true do begin + if field.aslargeint = key then begin + result:= loc_ok; + exit; + end; + if bof then begin + break; + end; + prior; + end; + end; + finally + try + if result <> loc_ok then begin + bookmark:= bm; + end; + finally + enablecontrols; + end; + end; + end; +end; + +function locaterecord(const adataset: tdataset; const autf8: boolean; + const key: msestring; const field: tfield; + const options: locateoptionsty = []): locateresultty; +var + int2: integer; + str1,str2,bm: string; + mstr1,mstr2: msestring; + caseinsensitive: boolean; + ismsestringfield: boolean; + + function checkmsestring: boolean; + var + int1: integer; + po1,po2: pmsechar; + begin + if ismsestringfield then begin + mstr2:= tmsestringfield(field).asmsestring; + end + else begin + if autf8 then begin + mstr2:= utf8tostringansi(field.asstring); + end + else begin + mstr2:= field.asstring; + end; + end; + if caseinsensitive then begin + mstr2:= mseuppercase(mstr2); //todo: optimize + end; + if loo_posinsensitive in options then begin + result:= pos(mstr1,mstr2) > 0; + end + else begin + result:= true; + po1:= pmsechar(mstr1); + po2:= pmsechar(mstr2); + for int1:= 0 to int2 - 1 do begin + if po1[int1] <> po2[int1] then begin + result:= false; + break; + end; + if po1[int1] = #0 then begin + break; + end; + end; + end; + end; + + function checkcasesensitive: boolean; + var + int1: integer; + begin + str2:= field.asstring; + if loo_posinsensitive in options then begin + result:= pos(str1,str2) > 0; + end + else begin + result:= true; + for int1:= 0 to int2 - 1 do begin + if pchar(str1)[int1] <> pchar(str2)[int1] then begin + result:= false; + break; + end; + if pchar(str1)[int1] = #0 then begin + break; + end; + end; + end; + end; + +begin + ismsestringfield:= field is tmsestringfield; + with adataset do begin + checkbrowsemode; + result:= loc_notfound; + bm:= bookmark; + caseinsensitive:= loo_caseinsensitive in options; + if caseinsensitive or ismsestringfield then begin + if caseinsensitive then begin + mstr1:= mseuppercase(key); + end + else begin + mstr1:= key; + end; + if loo_partialkey in options then begin + int2:= length(mstr1); + end + else begin + int2:= bigint; + end; + end + else begin + if autf8 then begin + str1:= stringtoutf8ansi(key); + end + else begin + str1:= key; + end; + if loo_partialkey in options then begin + int2:= length(str1); + end + else begin + int2:= bigint; + end; + end; + disablecontrols; + try + if not (loo_noforward in options) then begin + if caseinsensitive or ismsestringfield then begin + while not eof do begin + if checkmsestring then begin + result:= loc_ok; + exit; + end; + next; + end; + end + else begin + while not eof do begin + if checkcasesensitive then begin + result:= loc_ok; + exit; + end; + next; + end; + end; + bookmark:= bm; + end; + if not (loo_nobackward in options) then begin + if caseinsensitive or ismsestringfield then begin + while true do begin + if checkmsestring then begin + result:= loc_ok; + exit; + end; + if bof then begin + break; + end; + prior; + end; + end + else begin + while true do begin + if checkcasesensitive then begin + result:= loc_ok; + exit; + end; + if bof then begin + break; + end; + prior; + end; + end; + end; + finally + try + if result <> loc_ok then begin + bookmark:= bm; + end; + finally + enablecontrols; + end; + end; + end; +end; +} +type + locatefuncty = function (const key; const afield: tfield): boolean; + +function locatenull(const key; const afield: tfield): boolean; +begin + result:= afield.isnull; +end; + +function locateinteger(const key; const afield: tfield): boolean; +begin + result:= tvarrec(key).vinteger = afield.asinteger; +end; + +function locateint64(const key; const afield: tfield): boolean; +begin + result:= tvarrec(key).vint64^ = afield.aslargeint; +end; + +function locateboolean(const key; const afield: tfield): boolean; +begin + result:= tvarrec(key).vboolean = afield.asboolean; +end; + +function locateextended(const key; const afield: tfield): boolean; +begin + result:= tvarrec(key).vextended^ = afield.asfloat; +end; + +function locatecurrency(const key; const afield: tfield): boolean; +begin + result:= tvarrec(key).vcurrency^ = afield.ascurrency; +end; + +function locatevariant(const key; const afield: tfield): boolean; +begin + result:= tvarrec(key).vvariant^ = afield.asvariant; +end; + +function locateansistring(const key; const afield: tfield): boolean; +begin + result:= ansistring(tvarrec(key).vansistring) = afield.asstring; +end; + +function locatemsestring(const key; const afield: tfield): boolean; +begin + result:= msestring(tvarrec(key).vwidestring) = + tmsestringfield(afield).asmsestring; +end; + +function locateansistringupper(const key; const afield: tfield): boolean; +begin + result:= ansistring(tvarrec(key).vansistring) = ansiuppercase(afield.asstring); +end; + +function locatemsestringupper(const key; const afield: tfield): boolean; +begin + result:= msestring(tvarrec(key).vwidestring) = + mseuppercase(tmsestringfield(afield).asmsestring); +end; + +function locateansistringpartial(const key; const afield: tfield): boolean; +begin + result:= ansistring(tvarrec(key).vansistring) = copy(afield.asstring,1, + length(ansistring(tvarrec(key).vansistring))); +end; + +function locatemsestringpartial(const key; const afield: tfield): boolean; +begin + result:= msestring(tvarrec(key).vwidestring) = + copy(tmsestringfield(afield).asmsestring,1, + length(msestring(tvarrec(key).vwidestring))); +end; + +function locateansistringupperpartial(const key; const afield: tfield): boolean; +begin + result:= ansistring(tvarrec(key).vansistring) = ansiuppercase(copy(afield.asstring,1, + length(ansistring(tvarrec(key).vansistring)))); +end; + +function locatemsestringupperpartial(const key; const afield: tfield): boolean; +begin + result:= msestring(tvarrec(key).vwidestring) = + mseuppercase(copy(tmsestringfield(afield).asmsestring,1, + length(msestring(tvarrec(key).vwidestring)))); +end; + +function locateansistringposins(const key; const afield: tfield): boolean; +begin + result:= pos(ansistring(tvarrec(key).vansistring),afield.asstring) > 0; +end; + +function locatemsestringposins(const key; const afield: tfield): boolean; +begin + result:= pos(msestring(tvarrec(key).vwidestring), + tmsestringfield(afield).asmsestring) > 0; +end; + +function locateansistringupperposins(const key; const afield: tfield): boolean; +begin + result:= pos(ansistring(tvarrec(key).vansistring), + ansiuppercase(afield.asstring)) > 0; +end; + +function locatemsestringupperposins(const key; const afield: tfield): boolean; +begin + result:= pos(msestring(tvarrec(key).vwidestring), + mseuppercase(tmsestringfield(afield).asmsestring)) > 0; +end; + +const + ansistringcomp: array[0..7] of locatefuncty = + ({$ifdef FPC}@{$endif}locateansistring, + {$ifdef FPC}@{$endif}locateansistringupper, + {$ifdef FPC}@{$endif}locateansistringpartial, + {$ifdef FPC}@{$endif}locateansistringupperpartial, + {$ifdef FPC}@{$endif}locateansistringposins, + {$ifdef FPC}@{$endif}locateansistringupperposins, + {$ifdef FPC}@{$endif}locateansistringposins, + {$ifdef FPC}@{$endif}locateansistringupperposins); + msestringcomp: array[0..7] of locatefuncty = + ({$ifdef FPC}@{$endif}locatemsestring, + {$ifdef FPC}@{$endif}locatemsestringupper, + {$ifdef FPC}@{$endif}locatemsestringpartial, + {$ifdef FPC}@{$endif}locatemsestringupperpartial, + {$ifdef FPC}@{$endif}locatemsestringposins, + {$ifdef FPC}@{$endif}locatemsestringupperposins, + {$ifdef FPC}@{$endif}locatemsestringposins, + {$ifdef FPC}@{$endif}locatemsestringupperposins); + +function locaterecord(const adataset: tdataset; + const fields: array of tfield; + const keys: array of const; //nil -> NULL field + const isnull: array of boolean; + const keyoptions: array of locatekeyoptionsty; + const options: locaterecordoptionsty): locateresultty; +var + comparefuncar: array of locatefuncty; + + function check: boolean; + var + int1: integer; + begin + result:= true; + for int1:= 0 to high(comparefuncar) do begin + result:= comparefuncar[int1](keys[int1],fields[int1]); + if not result then begin + break; + end; + end; + end; + +var + keymsestrings: msestringarty; + keyansistrings: stringarty; + int1: integer; + bm: bookmarkty; + opt1: locatekeyoptionsty; +begin + int1:= high(keys); + if high(fields) < int1 then begin + int1:= high(fields); + end; + inc(int1); + setlength(comparefuncar,int1); + setlength(keymsestrings,int1); + setlength(keyansistrings,int1); + + for int1:= 0 to high(comparefuncar) do begin + opt1:= []; + if int1 <= high(keyoptions) then begin + opt1:= keyoptions[int1]; + end; + if (int1 <= high(isnull)) and isnull[int1] then begin + comparefuncar[int1]:= @locatenull; + end + else begin + with tvarrec(keys[int1]) do begin + case vtype of + vtpointer: begin + comparefuncar[int1]:= @locatenull; + end; + vtinteger: begin + comparefuncar[int1]:= @locateinteger; + end; + vtint64: begin + comparefuncar[int1]:= @locateint64; + end; + vtboolean: begin + comparefuncar[int1]:= @locateboolean; + end; + vtextended: begin + if vextended^ = emptyreal then begin + comparefuncar[int1]:= @locatenull; + end + else begin + comparefuncar[int1]:= @locateextended; + end; + end; + vtcurrency: begin + comparefuncar[int1]:= @locatecurrency; + end; + {$ifdef mse_hasvtunicodestring} + vtunicodestring, + {$endif} + vtwidestring: begin + if fields[int1] is tmsestringfield then begin + comparefuncar[int1]:= msestringcomp[{$ifdef FPC}longword{$else}byte{$endif}(opt1)]; + if lko_caseinsensitive in opt1 then begin + {$ifdef mse_hasvtunicodestring} + if vtype = vtunicodestring then begin + keymsestrings[int1]:= + mseuppercase(msestring(tvarrec(keys[int1]).vunicodestring)); + pvarrec(@keys[int1])^.vunicodestring:= pointer(keymsestrings[int1]); + end + else begin + {$endif} + keymsestrings[int1]:= + mseuppercase(msestring(tvarrec(keys[int1]).vwidestring)); + pvarrec(@keys[int1])^.vwidestring:= pointer(keymsestrings[int1]); + {$ifdef mse_hasvtunicodestring} + end; + {$endif} + end + end + else begin + if lro_utf8 in options then begin + if lko_caseinsensitive in opt1 then begin + {$ifdef mse_hasvtunicodestring} + if vtype = vtunicodestring then begin + keyansistrings[int1]:= stringtoutf8ansi(mseuppercase( + msestring(tvarrec(keys[int1]).vunicodestring))); + end + else begin + {$endif} + keyansistrings[int1]:= stringtoutf8ansi(mseuppercase( + msestring(tvarrec(keys[int1]).vwidestring))); + {$ifdef mse_hasvtunicodestring} + end; + {$endif} + end + else begin + {$ifdef mse_hasvtunicodestring} + if vtype = vtunicodestring then begin + keyansistrings[int1]:= + stringtoutf8ansi(msestring(tvarrec(keys[int1]).vunicodestring)); + end + else begin + {$endif} + keyansistrings[int1]:= + stringtoutf8ansi(msestring(tvarrec(keys[int1]).vwidestring)); + {$ifdef mse_hasvtunicodestring} + end; + {$endif} + end; + end + else begin + if lko_caseinsensitive in opt1 then begin + {$ifdef mse_hasvtunicodestring} + if vtype = vtunicodestring then begin + keyansistrings[int1]:= ansistring(mseuppercase( + msestring(tvarrec(keys[int1]).vunicodestring))); + end + else begin + {$endif} + keyansistrings[int1]:= ansistring( + mseuppercase(msestring(tvarrec(keys[int1]).vwidestring))); + {$ifdef mse_hasvtunicodestring} + end; + {$endif} + end + else begin + keyansistrings[int1]:= + ansistring(msestring(tvarrec(keys[int1]).vwidestring)); + end; + end; + pvarrec(@keys[int1])^.vansistring:= pointer(keyansistrings[int1]); + comparefuncar[int1]:= + ansistringcomp[{$ifdef FPC}longword{$else}byte{$endif}(opt1)]; + end; + end; + vtansistring: begin + if fields[int1] is tmsestringfield then begin + comparefuncar[int1]:= + msestringcomp[{$ifdef FPC}longword{$else}byte{$endif}(opt1)]; + if lko_caseinsensitive in opt1 then begin + keymsestrings[int1]:= + mseuppercase(msestring( + ansistring(tvarrec(keys[int1]).vansistring))); + end + else begin + keymsestrings[int1]:= msestring( + ansistring(tvarrec(keys[int1]).vansistring)); + end; + pvarrec(@keys[int1])^.vwidestring:= pointer(keymsestrings[int1]); + end + else begin + if lko_caseinsensitive in opt1 then begin + keyansistrings[int1]:= + ansiuppercase(ansistring(tvarrec(keys[int1]).vansistring)); + pvarrec(@keys[int1])^.vansistring:= pointer(keyansistrings[int1]); + end + else begin + keyansistrings[int1]:= + ansistring(tvarrec(keys[int1]).vansistring); +// keyansistrings[int1]:= +// msestring(tvarrec(keys[int1]).vwidestring); + end; + comparefuncar[int1]:= + ansistringcomp[{$ifdef FPC}longword{$else}byte{$endif}(opt1)]; + end; + end; + vtvariant: begin + comparefuncar[int1]:= @locatevariant; + end; + else begin + raise exception.create('Invalid locate data type.'); + end; + end; + end; + end; + end; + with adataset do begin + checkbrowsemode; + result:= loc_notfound; + bm:= bookmark; + disablecontrols; + try + if not (lro_nocurrent in options) then begin + if check then begin + result:= loc_ok; + exit; + end; + end; + if not (lro_noforward in options) then begin + next; + while not eof do begin + if check then begin + result:= loc_ok; + exit; + end; + next; + end; + bookmark:= bm; + end; + if not (lro_nobackward in options) then begin + prior; + while not bof do begin + if check then begin + result:= loc_ok; + exit; + end; + prior; + end; + end; + { + if not (lro_nobackward in options) then begin + while true do begin + if check then begin + result:= loc_ok; + exit; + end; + if bof then begin + break; + end; + prior; + end; + end; + } + finally + try + if result <> loc_ok then begin + bookmark:= bm; + end; + finally + enablecontrols; + end; + end; + end; +end; + +{ tmsefield } + +function tmsefield.HasParent: Boolean; +begin + result:= dataset <> nil; +end; +{ +procedure tmsefield.setmsestring(const avalue: msestring); +begin + asstring:= avalue; +end; + +function tmsefield.getasmsestring: msestring; +begin + result:= asstring; +end; +} +procedure tmsefield.Clear; +begin + setdata(nil); +end; + + +function tmsefield.assql: msestring; +begin + result:= fieldtosql(self); +end; + +function tmsefield.asoldsql: msestring; +begin + result:= fieldtooldsql(self); +end; +{ +function tmsefield.getaswidestring: widestring; +begin + result:= asmsestring; +end; + +procedure tmsefield.setaswidestring(const avalue: widestring); +begin + asmsestring:= avalue; +end; +} +procedure tmsefield.readlookup(reader: treader); +begin + reader.readboolean; +end; + +procedure tmsefield.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('Lookup',{$ifdef FPC}@{$endif}readlookup,nil,false); +end; +{ +function tmsefield.getproviderflags1: providerflags1ty; +begin + result:= fproviderflags1; +end; +} +procedure tmsefield.change; +begin + if not (fis_changing in fstate) then begin + include(fstate,fis_changing); + try + inherited; + finally + exclude(fstate,fis_changing); + end; + end; +end; + +procedure tmsefield.SetDataset(AValue: TDataset); +begin + if fieldname = '' then begin + fieldname:= fieldnamedummy; + try + inherited; + finally + fieldname:= ''; + end; + end + else begin + inherited; + end; +end; + +{ tmsestringfield } + +destructor tmsestringfield.destroy; +begin + if fdsintf <> nil then begin + fdsintf.fielddestroyed(ifieldcomponent(self)); + end; + inherited; +end; + +function tmsestringfield.HasParent: Boolean; +begin + result:= dataset <> nil; +end; + +function tmsestringfield.assql: msestring; +begin + result:= fieldtosql(self); +end; + +function tmsestringfield.getasunicodestring: unicodestring; +begin + if assigned(fgetmsestringdata) then begin + fgetmsestringdata(self,result); + end + else begin + result:= fieldgetmsestring(self,fdsintf); + end; +end; + +procedure tmsestringfield.setasnullmsestring(const avalue: msestring); +begin + if avalue = '' then begin + clear; + end + else begin + setasunicodestring(avalue); + end; +end; + +procedure tmsestringfield.setasunicodestring(const avalue: msestring); +begin + if assigned(fsetmsestringdata) then begin + fsetmsestringdata(self,avalue); + end + else begin + fieldsetmsestring(avalue,self,fdsintf); + end; +end; + +procedure tmsestringfield.readlookup(reader: treader); +begin + reader.readboolean; +end; + +procedure tmsestringfield.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('Lookup',{$ifdef FPC}@{$endif}readlookup,nil,false); +end; + +function tmsestringfield.getaswidestring: widestring; +begin + result:= asmsestring; +end; + +procedure tmsestringfield.setaswidestring(const avalue: widestring); +begin + asmsestring:= avalue; +end; + +procedure tmsestringfield.setdsintf(const avalue: idsfieldcontroller); +begin + fdsintf:= avalue; +end; + +function tmsestringfield.getinstance: tfield; +begin + result:= self; +end; + +procedure tmsestringfield.Clear; +begin + setdata(nil); +end; + +function tmsestringfield.oldmsestring(out aisnull: boolean): msestring; +var + statebefore: tdatasetstate; +begin + statebefore:= tdataset1(dataset).settempstate(dsoldvalue); + aisnull:= not getdata(nil); + result:= getasunicodestring; + tdataset1(dataset).restorestate(statebefore); +end; + +function tmsestringfield.oldmsestring: msestring; +var + bo1: boolean; +begin + result:= curmsestring(bo1); +end; + +function tmsestringfield.curmsestring(out aisnull: boolean): msestring; +var + statebefore: tdatasetstate; +begin + statebefore:= tdataset1(dataset).settempstate(dscurvalue); + aisnull:= not getdata(nil); + result:= getasunicodestring; + tdataset1(dataset).restorestate(statebefore); +end; + + +function tmsestringfield.curmsestring: msestring; +var + bo1: boolean; +begin + result:= curmsestring(bo1); +end; + +procedure tmsestringfield.setismsestring(const getter: getmsestringdataty; + const setter: setmsestringdataty; const acharacterlength: integer; + const aisftwidestring: boolean); +begin + fcharacterlength:= acharacterlength; + size:= acharacterlength; + fgetmsestringdata:= getter; + fsetmsestringdata:= setter; + fisftwidestring:= aisftwidestring; +end; + +function tmsestringfield.GetDataSize: integer; +begin + if assigned(fgetmsestringdata) then begin + result:= sizeof(msestring); + end + else begin + result:= inherited getdatasize; + end; +end; + +function tmsestringfield.GetAsString: string; +begin + if assigned(fgetmsestringdata) then begin + result:= ansistring(getasunicodestring); + end + else begin + result:= inherited getasstring; + end; +end; + +function tmsestringfield.GetAsVariant: variant; +var + mstr1: msestring; +begin + if assigned(fgetmsestringdata) then begin + if fgetmsestringdata(self,mstr1) then begin + result:= mstr1; + end + else begin + result:= null; + end; + end + else begin + result:= inherited getasvariant; + end; +end; + +procedure tmsestringfield.SetAsString(const AValue: string); +begin + if assigned(fsetmsestringdata) then begin + fsetmsestringdata(self,msestring(avalue)); + end + else begin + inherited; + end; +end; + +procedure tmsestringfield.SetVarValue(const AValue: Variant); +begin + if assigned(fsetmsestringdata) then begin + fsetmsestringdata(self,avalue); + end + else begin + inherited; + end; +end; + +function tmsestringfield.asoldsql: msestring; +begin + result:= fieldtooldsql(self); +end; + +function tmsestringfield.getdefaultexpression: msestring; +begin + if inherited defaultexpression <> fdefaultexpressionbefore then begin + fdefaultexpressionbefore:= inherited defaultexpression; + fdefaultexpressionstr:= msestring(fdefaultexpressionbefore); + end; + result:= fdefaultexpressionstr; +end; + +procedure tmsestringfield.setdefaultexpression(const avalue: msestring); +begin + fdefaultexpressionstr:= avalue; + try + fdefaultexpressionbefore:= ansistring(avalue); + inherited defaultexpression:= fdefaultexpressionbefore; + except //catch conversion exception + fdefaultexpressionbefore:= ''; + inherited defaultexpression:= ''; + end; +end; +{ +function tmsestringfield.getproviderflags1: providerflags1ty; +begin + result:= fproviderflags1; +end; +} +procedure tmsestringfield.change; +begin + if not (fis_changing in fstate) then begin + include(fstate,fis_changing); + try + inherited; + finally + exclude(fstate,fis_changing); + end; + end; +end; + +procedure tmsestringfield.SetDataset(AValue: TDataset); +begin + if fieldname = '' then begin + fieldname:= fieldnamedummy; + try + inherited; + finally + fieldname:= ''; + end; + end + else begin + inherited; + end; +end; + +procedure tmsestringfield.dosetvalue(const sender: tobject; + var avalue: msestring; var accept: boolean); +begin + if assigned(fonsetvalue) then begin + fonsetvalue(self,sender,avalue,accept); + end; +end; + +{ tmsememofield } + +constructor tmsememofield.create(aowner: tcomponent); +begin + inherited; + setdatatype(ftmemo); +end; + +destructor tmsememofield.destroy; +begin + if fdsintf <> nil then begin + fdsintf.fielddestroyed(ifieldcomponent(self)); + end; + inherited; +end; + +function tmsememofield.assql: msestring; +begin + result:= fieldtosql(self); +end; + +function tmsememofield.getasunicodestring: msestring; +begin + result:= fieldgetmsestring(self,fdsintf); +end; + +procedure tmsememofield.setasunicodestring(const avalue: msestring); +begin + fieldsetmsestring(avalue,self,fdsintf); +end; + +function tmsememofield.getaswidestring: widestring; +begin + result:= fieldgetmsestring(self,fdsintf); +end; + +procedure tmsememofield.setaswidestring(const avalue: widestring); +begin + fieldsetmsestring(avalue,self,fdsintf); +end; + +procedure tmsememofield.setdsintf(const avalue: idsfieldcontroller); +begin + fdsintf:= avalue; +end; + +function tmsememofield.getinstance: tfield; +begin + result:= self; +end; + +procedure tmsememofield.Clear; +begin + setdata(nil); +end; + +function tmsememofield.asoldsql: msestring; +begin + result:= fieldtooldsql(self); +end; + +function tmsememofield.getasvariant: variant; +begin + if isnull then begin + result:= NULL; + end + else begin + result:= getasunicodestring; + end; +end; + +procedure tmsememofield.setvarvalue(const avalue: variant); +begin + setasunicodestring(avalue); +end; + +function tmsememofield.oldmsestring(out aisnull: boolean): msestring; +var + statebefore: tdatasetstate; +begin + statebefore:= tdataset1(dataset).settempstate(dsoldvalue); + aisnull:= getdata(nil); + result:= getasunicodestring; + tdataset1(dataset).restorestate(statebefore); +end; + +procedure tmsememofield.gettext(var thetext: string; adisplaytext: boolean); +begin + thetext:= asstring; +end; + +{ tmseguidfield } + +constructor tmseguidfield.create(aowner: tcomponent); +begin + inherited; + setdatatype(ftguid); +end; + +function tmseguidfield.getasstring: string; +var + id1: tguid; +begin + if not getdata(@id1) then begin + result:= ''; + end + else begin + result:= dbguidtostring(id1); + end; +end; + +procedure tmseguidfield.setasstring(const avalue: string); +begin + if avalue = '' then begin + clear; + end + else begin + if avalue[1] = '{' then begin + asguid:= stringtoguid(avalue); + end + else begin + asguid:= dbstringtoguid(avalue); + end; + end; +end; + +function tmseguidfield.getdefaultwidth: longint; +begin + result:= guidbuffersize; +end; + +function tmseguidfield.getasguid: tguid; +begin + if not getdata(@result) then begin + result:= GUID_NULL; + end; +end; + +procedure tmseguidfield.setasguid(const avalue: tguid); +begin + setdata(@avalue); +end; + +function tmseguidfield.getasvariant: variant; +var + id1: tguid; +begin + if not getdata(@id1) then begin + result:= null; + end + else begin + result:= dbguidtostring(id1); + end; +end; + +procedure tmseguidfield.setvarvalue(const avalue: variant); +begin + asstring:= avalue; +end; + +function tmseguidfield.getdatasize: integer; +begin + result:= sizeof(tguid); +end; + +{ tmsenumericfield } + +function tmsenumericfield.HasParent: Boolean; +begin + result:= dataset <> nil; +end; + +function tmsenumericfield.assql: msestring; +begin + result:= fieldtosql(self); +end; +{ +procedure tmsenumericfield.setasmsestring(const avalue: msestring); +begin + asstring:= value; +end; + +function tmsenumericfield.getasmsestring: msestring; +begin + result:= asstring; +end; +} +procedure tmsenumericfield.readlookup(reader: treader); +begin + reader.readboolean; +end; + +procedure tmsenumericfield.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('Lookup',{$ifdef FPC}@{$endif}readlookup,nil,false); +end; + +function tmsenumericfield.getaswidestring: widestring; +begin + result:= asmsestring; +end; + +procedure tmsenumericfield.setaswidestring(const avalue: widestring); +begin + asmsestring:= avalue; +end; + +procedure tmsenumericfield.Clear; +begin + setdata(nil); +end; + +function tmsenumericfield.asoldsql: msestring; +begin + result:= fieldtooldsql(self); +end; +{ +function tmsenumericfield.getproviderflags1: providerflags1ty; +begin + result:= fproviderflags1; +end; +} +procedure tmsenumericfield.change; +begin + if not (fis_changing in fstate) then begin + include(fstate,fis_changing); + try + inherited; + finally + exclude(fstate,fis_changing); + end; + end; +end; + +procedure tmsenumericfield.SetDataset(AValue: TDataset); +begin + if fieldname = '' then begin + fieldname:= fieldnamedummy; + try + inherited; + finally + fieldname:= ''; + end; + end + else begin + inherited; + end; +end; +{ +function tmsenumericfield.getlookupinfo: plookupfieldinfoty; +begin + result:= @flookupinfo; +end; +} +{ tmselongintfield } + +function tmselongintfield.HasParent: Boolean; +begin + result:= dataset <> nil; +end; + +function tmselongintfield.assql: msestring; +begin + result:= fieldtosql(self); +end; +{ +procedure tmselongintfield.setasmsestring(const avalue: msestring); +begin + asstring:= avalue; +end; + +function tmselongintfield.getasmsestring: msestring; +begin + result:= asstring; +end; +} +procedure tmselongintfield.readlookup(reader: treader); +begin + reader.readboolean; +end; + +procedure tmselongintfield.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('Lookup',{$ifdef FPC}@{$endif}readlookup,nil,false); +end; + +function tmselongintfield.getaswidestring: widestring; +begin + result:= asmsestring; +end; + +procedure tmselongintfield.setaswidestring(const avalue: widestring); +begin + asmsestring:= avalue; +end; + +function tmselongintfield.getasboolean: boolean; +begin + result:= asinteger <> 0; +end; + +procedure tmselongintfield.setasboolean(avalue: boolean); +begin + if avalue then begin + asinteger:= 1; + end + else begin + asinteger:= 0; + end; +end; + +procedure tmselongintfield.Clear; +begin + setdata(nil); +end; + +procedure tmselongintfield.setasenum(const avalue: integer); +begin + if avalue = -1 then begin + clear; + end + else begin + asinteger:= avalue; + end; +end; + +function tmselongintfield.asoldsql: msestring; +begin + result:= fieldtooldsql(self); +end; + +procedure tmselongintfield.setaslargeint(avalue: largeint); +begin + if (avalue < minint) or (avalue > maxint) then begin + rangeerror(avalue,minint,maxint); + end; + setaslongint(avalue); +end; + +function tmselongintfield.getaslargeint: largeint; +begin + result:= getaslongint; +end; + +function tmselongintfield.sum: integer; +var + bm: bookmarkty; + int1: integer; + intf1: idatasetsum; +begin + result:= 0; + if (dataset <> nil) and dataset.active then begin + if (fieldkind in [fkdata,fkinternalcalc]) and + getcorbainterface(dataset,typeinfo(idatasetsum),intf1) then begin + intf1.sumfield(tfield(self),result); + end + else begin + with dataset do begin + disablecontrols; + try + bm:= bookmark; + first; + while not eof do begin + if getdata(@int1) then begin + result:= result + int1; + end; + next; + end; + bookmark:= bm; + finally + enablecontrols; + end; + end; + end; + end; +end; + +procedure tmselongintfield.gettext(var thetext: string; adisplaytext: boolean); +var + int1: integer; +begin + thetext:=''; + if getdata(@int1) then begin + thetext:= getnumdisplaytext(self,int1,adisplaytext,false); + end; +end; +{ +function tmselongintfield.getproviderflags1: providerflags1ty; +begin + result:= fproviderflags1; +end; +} +{ +function tmselongintfield.getasid: integer; +begin + if isnull then begin + result:= -1; + end + else begin + result:= asinteger; + end; +end; + +procedure tmselongintfield.setasid(const avalue: integer); +begin + if avalue = -1 then begin + clear; + end + else begin + asinteger:= avalue; + end; +end; +} +procedure tmselongintfield.change; +begin + if not (fis_changing in fstate) then begin + include(fstate,fis_changing); + try + inherited; + finally + exclude(fstate,fis_changing); + end; + end; +end; + +function tmselongintfield.asoldid: integer; +var + stat1: tdatasetstate; +begin + stat1:= tdataset1(dataset).settempstate(dsoldvalue); + result:= asid; + tdataset1(dataset).restorestate(stat1); +end; + +procedure tmselongintfield.SetDataset(AValue: TDataset); +begin + if fieldname = '' then begin + fieldname:= fieldnamedummy; + try + inherited; + finally + fieldname:= ''; + end; + end + else begin + inherited; + end; +end; +{ +function tmselongintfield.getlookupinfo: plookupfieldinfoty; +begin + result:= @flookupinfo; +end; +} +{ tmselargeintfield } + +function tmselargeintfield.HasParent: Boolean; +begin + result:= dataset <> nil; +end; + +function tmselargeintfield.assql: msestring; +begin + result:= fieldtosql(self); +end; +{ +procedure tmselargeintfield.setasmsestring(const avalue: msestring); +begin + asstring:= avalue; +end; + +function tmselargeintfield.getasmsestring: msestring; +begin + result:= asstring; +end; +} +procedure tmselargeintfield.readlookup(reader: treader); +begin + reader.readboolean; +end; + +procedure tmselargeintfield.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('Lookup',{$ifdef FPC}@{$endif}readlookup,nil,false); +end; + +function tmselargeintfield.getaswidestring: widestring; +begin + result:= asmsestring; +end; + +procedure tmselargeintfield.setaswidestring(const avalue: widestring); +begin + asmsestring:= avalue; +end; + +function tmselargeintfield.getasboolean: boolean; +begin + result:= asinteger <> 0; +end; + +procedure tmselargeintfield.setasboolean(avalue: boolean); +begin + if avalue then begin + asinteger:= 1; + end + else begin + asinteger:= 0; + end; +end; + +procedure tmselargeintfield.Clear; +begin + setdata(nil); +end; + +function tmselargeintfield.asoldsql: msestring; +begin + result:= fieldtooldsql(self); +end; + +function tmselargeintfield.asoldid: int64; +var + stat1: tdatasetstate; +begin + stat1:= tdataset1(dataset).settempstate(dsoldvalue); + result:= asid; + tdataset1(dataset).restorestate(stat1); +end; + +procedure tmselargeintfield.gettext(var thetext: string; adisplaytext: boolean); +var + int1: int64; +begin + thetext:=''; + if getdata(@int1) then begin + thetext:= getnumdisplaytext(self,int1,adisplaytext,false); + end; +end; + +function tmselargeintfield.sum: int64; +var + bm: bookmarkty; + lint1: int64; + intf1: idatasetsum; +begin + result:= 0; + if (dataset <> nil) and dataset.active then begin + if (fieldkind in [fkdata,fkinternalcalc]) and + getcorbainterface(dataset,typeinfo(idatasetsum),intf1) then begin + intf1.sumfield(tfield(self),result); + end + else begin + with dataset do begin + disablecontrols; + try + bm:= bookmark; + first; + while not eof do begin + if getdata(@lint1) then begin + result:= result + lint1; + end; + next; + end; + bookmark:= bm; + finally + enablecontrols; + end; + end; + end; + end; +end; +{ +function tmselargeintfield.getproviderflags1: providerflags1ty; +begin + result:= fproviderflags1; +end; +} +function tmselargeintfield.getasid: int64; +begin + if isnull then begin + result:= -1; + end + else begin + result:= aslargeint; + end; +end; + +procedure tmselargeintfield.setasid(const avalue: int64); +begin + if avalue = -1 then begin + clear; + end + else begin + aslargeint:= avalue; + end; +end; + +procedure tmselargeintfield.change; +begin + if not (fis_changing in fstate) then begin + include(fstate,fis_changing); + try + inherited; + finally + exclude(fstate,fis_changing); + end; + end; +end; + +procedure tmselargeintfield.SetDataset(AValue: TDataset); +begin + if fieldname = '' then begin + fieldname:= fieldnamedummy; + try + inherited; + finally + fieldname:= ''; + end; + end + else begin + inherited; + end; +end; +{ +function tmselargeintfield.getlookupinfo: plookupfieldinfoty; +begin + result:= @flookupinfo; +end; +} +{ tmsesmallintfield } + +function tmsesmallintfield.HasParent: Boolean; +begin + result:= dataset <> nil; +end; + +function tmsesmallintfield.assql: msestring; +begin + result:= fieldtosql(self); +end; +{ +procedure tmsesmallintfield.setasmsestring(const avalue: msestring); +begin + asstring:= avalue; +end; + +function tmsesmallintfield.getasmsestring: msestring; +begin + result:= asstring; +end; +} +procedure tmsesmallintfield.readlookup(reader: treader); +begin + reader.readboolean; +end; + +procedure tmsesmallintfield.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('Lookup',{$ifdef FPC}@{$endif}readlookup,nil,false); +end; + +function tmsesmallintfield.getaswidestring: widestring; +begin + result:= asmsestring; +end; + +procedure tmsesmallintfield.setaswidestring(const avalue: widestring); +begin + asmsestring:= avalue; +end; + +function tmsesmallintfield.getasboolean: boolean; +begin + result:= asinteger <> 0; +end; + +procedure tmsesmallintfield.setasboolean(avalue: boolean); +begin + if avalue then begin + asinteger:= 1; + end + else begin + asinteger:= 0; + end; +end; + +procedure tmsesmallintfield.setaslargeint(avalue: largeint); +begin + if (avalue < low(smallint)) or (avalue > high(smallint)) then begin + rangeerror(avalue,low(smallint),high(smallint)); + end; + setaslongint(avalue); +end; + +function tmsesmallintfield.getaslargeint: largeint; +begin + result:= getaslongint; +end; + +procedure tmsesmallintfield.Clear; +begin + setdata(nil); +end; + +function tmsesmallintfield.asoldsql: msestring; +begin + result:= fieldtooldsql(self); +end; +{ +function tmsesmallintfield.getproviderflags1: providerflags1ty; +begin + result:= fproviderflags1; +end; +} +procedure tmsesmallintfield.change; +begin + if not (fis_changing in fstate) then begin + include(fstate,fis_changing); + try + inherited; + finally + exclude(fstate,fis_changing); + end; + end; +end; + +procedure tmsesmallintfield.SetDataset(AValue: TDataset); +begin + if fieldname = '' then begin + fieldname:= fieldnamedummy; + try + inherited; + finally + fieldname:= ''; + end; + end + else begin + inherited; + end; +end; + +function tmsesmallintfield.getasid: integer; +begin + if isnull then begin + result:= -1; + end + else begin + result:= asinteger; + end; +end; + +procedure tmsesmallintfield.setasid(const avalue: integer); +begin + if avalue = -1 then begin + clear; + end + else begin + asinteger:= avalue; + end; +end; +{ +function tmsesmallintfield.getlookupinfo: plookupfieldinfoty; +begin + result:= @flookupinfo; +end; +} +{ tmsewordfield } + +function tmsewordfield.HasParent: Boolean; +begin + result:= dataset <> nil; +end; + +function tmsewordfield.assql: msestring; +begin + result:= fieldtosql(self); +end; +{ +procedure tmsewordfield.setasmsestring(const avalue: msestring); +begin + asstring:= avalue; +end; + +function tmsewordfield.getasmsestring: msestring; +begin + result:= asstring; +end; +} +procedure tmsewordfield.readlookup(reader: treader); +begin + reader.readboolean; +end; + +procedure tmsewordfield.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('Lookup',{$ifdef FPC}@{$endif}readlookup,nil,false); +end; + +function tmsewordfield.getaswidestring: widestring; +begin + result:= asmsestring; +end; + +procedure tmsewordfield.setaswidestring(const avalue: widestring); +begin + asmsestring:= avalue; +end; + +function tmsewordfield.getasboolean: boolean; +begin + result:= asinteger <> 0; +end; + +procedure tmsewordfield.setasboolean(avalue: boolean); +begin + if avalue then begin + asinteger:= 1; + end + else begin + asinteger:= 0; + end; +end; + +procedure tmsewordfield.setaslargeint(avalue: largeint); +begin + if (avalue < low(word)) or (avalue > high(word)) then begin + rangeerror(avalue,low(word),high(word)); + end; + setaslongint(avalue); +end; + +function tmsewordfield.getaslargeint: largeint; +begin + result:= getaslongint; +end; + +procedure tmsewordfield.Clear; +begin + setdata(nil); +end; + +function tmsewordfield.asoldsql: msestring; +begin + result:= fieldtooldsql(self); +end; +{ +function tmsewordfield.getproviderflags1: providerflags1ty; +begin + result:= fproviderflags1; +end; +} +procedure tmsewordfield.change; +begin + if not (fis_changing in fstate) then begin + include(fstate,fis_changing); + try + inherited; + finally + exclude(fstate,fis_changing); + end; + end; +end; + +procedure tmsewordfield.SetDataset(AValue: TDataset); +begin + if fieldname = '' then begin + fieldname:= fieldnamedummy; + try + inherited; + finally + fieldname:= ''; + end; + end + else begin + inherited; + end; +end; +{ +function tmsewordfield.getlookupinfo: plookupfieldinfoty; +begin + result:= @flookupinfo; +end; +} +{ tmseautoincfield } + +function tmseautoincfield.HasParent: Boolean; +begin + result:= dataset <> nil; +end; + +function tmseautoincfield.assql: msestring; +begin + result:= fieldtosql(self); +end; +{ +procedure tmseautoincfield.setasmsestring(const avalue: msestring); +begin + asstring:= avalue; +end; + +function tmseautoincfield.getasmsestring: msestring; +begin + result:= asstring; +end; +} +procedure tmseautoincfield.readlookup(reader: treader); +begin + reader.readboolean; +end; + +procedure tmseautoincfield.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('Lookup',{$ifdef FPC}@{$endif}readlookup,nil,false); +end; + +function tmseautoincfield.getaswidestring: widestring; +begin + result:= asmsestring; +end; + +procedure tmseautoincfield.setaswidestring(const avalue: widestring); +begin + asmsestring:= avalue; +end; + +procedure tmseautoincfield.Clear; +begin + setdata(nil); +end; + +function tmseautoincfield.asoldsql: msestring; +begin + result:= fieldtooldsql(self); +end; +{ +function tmseautoincfield.getproviderflags1: providerflags1ty; +begin + result:= fproviderflags1; +end; +} +procedure tmseautoincfield.change; +begin + if not (fis_changing in fstate) then begin + include(fstate,fis_changing); + try + inherited; + finally + exclude(fstate,fis_changing); + end; + end; +end; + +procedure tmseautoincfield.SetDataset(AValue: TDataset); +begin + if fieldname = '' then begin + fieldname:= fieldnamedummy; + try + inherited; + finally + fieldname:= ''; + end; + end + else begin + inherited; + end; +end; +{ +function tmseautoincfield.getlookupinfo: plookupfieldinfoty; +begin + result:= @flookupinfo; +end; +} +{ tmsefloatfield } + +function tmsefloatfield.HasParent: Boolean; +begin + result:= dataset <> nil; +end; + +function tmsefloatfield.assql: msestring; +begin + result:= fieldtosql(self); +end; +{ +procedure tmsefloatfield.setasmsestring(const avalue: msestring); +begin + asstring:= avalue; +end; + +function tmsefloatfield.getasmsestring: msestring; +begin + result:= asstring; +end; +} +procedure tmsefloatfield.readlookup(reader: treader); +begin + reader.readboolean; +end; + +procedure tmsefloatfield.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('Lookup',{$ifdef FPC}@{$endif}readlookup,nil,false); +end; + +function tmsefloatfield.getaswidestring: widestring; +begin + result:= asmsestring; +end; + +procedure tmsefloatfield.setaswidestring(const avalue: widestring); +begin + asmsestring:= avalue; +end; + +function tmsefloatfield.getasfloat: double; +begin + if not getdata(@result) then begin + result:= emptyreal; + end; +end; + +function tmsefloatfield.getascurrency: currency; +begin + result:= inherited getasfloat; +end; + +function tmsefloatfield.GetAsLongint: Longint; +begin + result:= round(inherited getasfloat); +end; + +function tmsefloatfield.GetAsLargeint: Largeint; +begin + result:= round(inherited getasfloat); +end; + + +procedure tmsefloatfield.setasfloat(avalue: double); +begin + if avalue = emptyreal then begin + clear; + end + else begin + inherited; + end; +end; + +procedure tmsefloatfield.Clear; +begin + setdata(nil); +end; + +function tmsefloatfield.asoldsql: msestring; +begin + result:= fieldtooldsql(self); +end; + +procedure tmsefloatfield.gettext(var thetext: string; adisplaytext: boolean); +var + do1: double; +begin + thetext:=''; + if getdata(@do1) then begin + thetext:= getnumdisplaytext(self,do1,adisplaytext,currency); + end; +end; + +function tmsefloatfield.sum: double; +var + bm: bookmarkty; + do1: double; + intf1: idatasetsum; +begin + result:= 0; + if (dataset <> nil) and dataset.active then begin + if (fieldkind in [fkdata,fkinternalcalc]) and + getcorbainterface(dataset,typeinfo(idatasetsum),intf1) then begin + intf1.sumfield(self,result); + end + else begin + with dataset do begin + disablecontrols; + try + bm:= bookmark; + first; + while not eof do begin + if getdata(@do1) then begin + result:= result + do1; + end; + next; + end; + bookmark:= bm; + finally + enablecontrols; + end; + end; + end; + end; +end; +{ +function tmsefloatfield.getproviderflags1: providerflags1ty; +begin + result:= fproviderflags1; +end; +} +procedure tmsefloatfield.change; +begin + if not (fis_changing in fstate) then begin + include(fstate,fis_changing); + try + inherited; + finally + exclude(fstate,fis_changing); + end; + end; +end; + +procedure tmsefloatfield.SetDataset(AValue: TDataset); +begin + if fieldname = '' then begin + fieldname:= fieldnamedummy; + try + inherited; + finally + fieldname:= ''; + end; + end + else begin + inherited; + end; +end; +{ +function tmsefloatfield.getlookupinfo: plookupfieldinfoty; +begin + result:= @flookupinfo; +end; +} +{ tmsecurrencyfield } + +constructor tmsecurrencyfield.create(aowner: tcomponent); +begin + inherited; + setdatatype(ftcurrency); + currency:= true; +end; + +{ tmsebooleanfield } + +constructor tmsebooleanfield.Create(AOwner: TComponent); +begin + inherited; + displayvalues:= 'True;False'; +end; + +function tmsebooleanfield.HasParent: Boolean; +begin + result:= dataset <> nil; +end; + +function tmsebooleanfield.assql: msestring; +begin + result:= fieldtosql(self); +end; + +procedure tmsebooleanfield.setasunicodestring(const avalue: msestring); +var + mstr1: msestring; +begin + if avalue= '' then begin + clear; + end + else begin + mstr1:= mseuppercase(avalue); + if (mstr1 = '0') or (pos(mstr1,fdisplays[true,false]) = 1) then begin + asboolean:= false; + end + else begin + if (mstr1 = '1') or (pos(mstr1,fdisplays[true,true]) = 1) then begin + asboolean:= true; + end + else begin + DatabaseErrorFmt(SNotABoolean,[string(AValue)]); + end; + end; + end; +end; + +function tmsebooleanfield.getasunicodestring: unicodestring; +var + int1: integer; +begin + int1:= 0; + if getdata(@int1) then begin + result:= fdisplays[false,int1 <> 0] + end + else begin + result:=''; + end; +end; + +procedure tmsebooleanfield.readlookup(reader: treader); +begin + reader.readboolean; +end; + +procedure tmsebooleanfield.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('Lookup',{$ifdef FPC}@{$endif}readlookup,nil,false); +end; + +function tmsebooleanfield.getaswidestring: widestring; +begin + result:= asmsestring; +end; + +procedure tmsebooleanfield.setaswidestring(const avalue: widestring); +begin + asmsestring:= avalue; +end; + +procedure tmsebooleanfield.Clear; +begin + setdata(nil); +end; + +procedure tmsebooleanfield.setdisplayvalues(const avalue: msestring); +var + ar1: msestringarty; +begin + if fdisplayvalues <> avalue then begin + ar1:= splitstring(avalue,msechar(';')); + if (high(ar1) <> 1) or (ar1[0] = ar1[1]) then begin + databaseerrorfmt(SInvalidDisplayValues,[string(avalue)]); + end; + fdisplayvalues:= avalue; + // Store display values and their uppercase equivalents; + fdisplays[false,true]:= ar1[0]; + fdisplays[true,true]:= mseUpperCase(ar1[0]); + fdisplays[false,false]:= ar1[1]; + fdisplays[true,false]:= mseuppercase(ar1[1]); + propertychanged(true); + end; +end; + +function tmsebooleanfield.getasstring: string; +begin + result:= ansistring(getasunicodestring()); +end; + +procedure tmsebooleanfield.setasstring(const avalue: string); +begin + setasunicodestring(msestring(avalue)); +end; + +function tmsebooleanfield.GetDefaultWidth: Longint; +begin + result:= length(fdisplays[false,false]); + if result < length(fdisplays[false,true]) then begin + result:= length(fdisplays[false,true]); + end; +end; + +function tmsebooleanfield.asoldsql: msestring; +begin + result:= fieldtooldsql(self); +end; + +function tmsebooleanfield.GetAsLongint: Longint; +begin + if getasboolean then begin +// result:= -1; + result:= 1; + end + else begin + result:= 0; + end; +end; + +procedure tmsebooleanfield.SetAsLongint(AValue: Longint); +begin + if avalue = 0 then begin + setasboolean(false); + end + else begin + setasboolean(true); + end; +end; + +function tmsebooleanfield.GetDataSize: integer; +begin + result:= sizeof(longbool); +end; + +function tmsebooleanfield.GetAsBoolean: Boolean; +var + int1: integer; +begin + int1:= 0; + if getdata(@int1) then begin + result:= int1 <> 0; + end + else begin + result:= false; + end; +end; + +procedure tmsebooleanfield.SetAsBoolean(AValue: Boolean); +var + int1: integer; +begin + if avalue then begin +// int1:= -1; + int1:= 1; + end + else begin + int1:= 0; + end; + setdata(@int1); +end; + +function tmsebooleanfield.GetAsVariant: variant; +var + int1: integer; +begin + int1:= 0; + if getdata(@int1) then begin + result:= int1 <> 0; + end + else begin + result:= null; + end; +end; + +function tmsebooleanfield.sum: integer; +var + bm: bookmarkty; +// int1: integer; + intf1: idatasetsum; + bo1: wordbool; +begin + result:= 0; + if (dataset <> nil) and dataset.active then begin + if (fieldkind in [fkdata,fkinternalcalc]) and + getcorbainterface(dataset,typeinfo(idatasetsum),intf1) then begin + intf1.sumfield(tfield(self),result); + end + else begin + with dataset do begin + disablecontrols; + try + bm:= bookmark; + first; + while not eof do begin + if getdata(@bo1) and bo1 then begin + inc(result); + end; + next; + end; + bookmark:= bm; + finally + enablecontrols; + end; + end; + end; + end; +end; +{ +function tmsebooleanfield.getproviderflags1: providerflags1ty; +begin + result:= fproviderflags1; +end; +} +procedure tmsebooleanfield.change; +begin + if not (fis_changing in fstate) then begin + include(fstate,fis_changing); + try + inherited; + finally + exclude(fstate,fis_changing); + end; + end; +end; + +procedure tmsebooleanfield.SetDataset(AValue: TDataset); +begin + if fieldname = '' then begin + fieldname:= fieldnamedummy; + try + inherited; + finally + fieldname:= ''; + end; + end + else begin + inherited; + end; +end; +{ +function tmsebooleanfield.getlookupinfo: plookupfieldinfoty; +begin + result:= @flookupinfo; +end; +} +{ tmsedatetimefield } + +function tmsedatetimefield.HasParent: Boolean; +begin + result:= dataset <> nil; +end; + +function tmsedatetimefield.assql: msestring; +begin + result:= fieldtosql(self); +end; +{ +procedure tmsedatetimefield.setasmsestring(const avalue: msestring); +begin + asstring:= avalue; +end; + +function tmsedatetimefield.getasmsestring: msestring; +begin + result:= asstring; +end; +} +procedure tmsedatetimefield.readlookup(reader: treader); +begin + reader.readboolean; +end; + +procedure tmsedatetimefield.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('Lookup',{$ifdef FPC}@{$endif}readlookup,nil,false); +end; + +function tmsedatetimefield.getaswidestring: widestring; +begin + result:= asmsestring; +end; + +procedure tmsedatetimefield.setaswidestring(const avalue: widestring); +begin + asmsestring:= avalue; +end; + +function tmsedatetimefield.getasdatetime: tdatetime; +begin + if not getdata(@result,false) then begin + result:= emptydatetime; + end + else begin + if dtfo_utc in foptions then begin + result:= utctolocaltime(result); + end; + if dtfo_local in foptions then begin + result:= localtimetoutc(result); + end; + end; +end; + +procedure tmsedatetimefield.setasdatetime(avalue: tdatetime); +begin + if avalue = emptydatetime then begin + clear; + end + else begin + if dtfo_utc in foptions then begin + avalue:= localtimetoutc(avalue); + end; + if dtfo_local in foptions then begin + avalue:= utctolocaltime(avalue); + end; + inherited; + end; +end; + +procedure tmsedatetimefield.Clear; +begin + setdata(nil); +end; + +function tmsedatetimefield.asoldsql: msestring; +begin + result:= fieldtooldsql(self); +end; + +procedure tmsedatetimefield.setoptions(const avalue: datetimefieldoptionsty); +const + mask: datetimefieldoptionsty = [dtfo_utc,dtfo_local]; +begin + foptions:= datetimefieldoptionsty(setsinglebit( + {$ifdef FPC}longword{$else}byte{$endif}(avalue), + {$ifdef FPC}longword{$else}byte{$endif}(foptions), + {$ifdef FPC}longword{$else}byte{$endif}(mask))); +end; + +procedure tmsedatetimefield.setasstring(const avalue: string); +begin + setasdatetime(strtodatetime(avalue)); +end; + +function tmsedatetimefield.gettext1(const r: tdatetime; + const adisplaytext: boolean): msestring; +var + f: string; +begin + if adisplaytext and (length(displayformat) <> 0) then begin + f:= displayformat; + end + else begin + case datatype of + fttime: f:= {$ifdef FPC}defaultformatsettings.{$endif}shorttimeformat; + ftdate: f:= {$ifdef FPC}defaultformatsettings.{$endif}shortdateformat; + else f:= 'c' + end; + end; + result:= formatdatetimemse(msestring(f),r); +end; + +procedure tmsedatetimefield.gettext(var thetext: string; adisplaytext: boolean); +//var +// r: tdatetime; +// f: string; +begin + if isnull then begin + thetext:= ''; + end + else begin + thetext:= ansistring(gettext1(getasdatetime,adisplaytext)); + end; +end; +{ +function tmsedatetimefield.getproviderflags1: providerflags1ty; +begin + result:= fproviderflags1; +end; +} +procedure tmsedatetimefield.change; +begin + if not (fis_changing in fstate) then begin + include(fstate,fis_changing); + try + inherited; + finally + exclude(fstate,fis_changing); + end; + end; +end; + +procedure tmsedatetimefield.SetDataset(AValue: TDataset); +begin + if fieldname = '' then begin + fieldname:= fieldnamedummy; + try + inherited; + finally + fieldname:= ''; + end; + end + else begin + inherited; + end; +end; +{ +function tmsedatetimefield.getlookupinfo: plookupfieldinfoty; +begin + result:= @flookupinfo; +end; +} +{ tmsedatefield } + +constructor tmsedatefield.create(aowner: tcomponent); +begin + inherited; + setdatatype(ftdate); +end; + +{ tmsetimefield } + +constructor tmsetimefield.create(aowner: tcomponent); +begin + inherited; + setdatatype(fttime); +end; + +{ tmsebinaryfield } + +function tmsebinaryfield.HasParent: Boolean; +begin + result:= dataset <> nil; +end; + +function tmsebinaryfield.assql: msestring; +begin + result:= fieldtosql(self); +end; + +procedure tmsebinaryfield.setasunicodestring(const avalue: msestring); +begin + asstring:= ansistring(avalue); +end; + +function tmsebinaryfield.getasunicodestring: msestring; +begin + result:= msestring(asstring); +end; + +procedure tmsebinaryfield.readlookup(reader: treader); +begin + reader.readboolean; +end; + +procedure tmsebinaryfield.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('Lookup',{$ifdef FPC}@{$endif}readlookup,nil,false); +end; + +function tmsebinaryfield.getaswidestring: widestring; +begin + result:= asmsestring; +end; + +procedure tmsebinaryfield.setaswidestring(const avalue: widestring); +begin + asmsestring:= avalue; +end; + +procedure tmsebinaryfield.Clear; +begin + setdata(nil); +end; + +function tmsebinaryfield.asoldsql: msestring; +begin + result:= fieldtooldsql(self); +end; +{ +function tmsebinaryfield.getproviderflags1: providerflags1ty; +begin + result:= fproviderflags1; +end; +} +procedure tmsebinaryfield.change; +begin + if not (fis_changing in fstate) then begin + include(fstate,fis_changing); + try + inherited; + finally + exclude(fstate,fis_changing); + end; + end; +end; + +procedure tmsebinaryfield.SetDataset(AValue: TDataset); +begin + if fieldname = '' then begin + fieldname:= fieldnamedummy; + try + inherited; + finally + fieldname:= ''; + end; + end + else begin + inherited; + end; +end; +{ +function tmsebinaryfield.getlookupinfo: plookupfieldinfoty; +begin + result:= @flookupinfo; +end; +} +{ tmsebytesfield } + +function tmsebytesfield.HasParent: Boolean; +begin + result:= dataset <> nil; +end; + +function tmsebytesfield.assql: msestring; +begin + result:= fieldtosql(self); +end; + +procedure tmsebytesfield.setasunicodestring(const avalue: unicodestring); +begin + asstring:= ansistring(avalue); +end; + +function tmsebytesfield.getasunicodestring: msestring; +begin + result:= asunicodestring; +end; + +procedure tmsebytesfield.readlookup(reader: treader); +begin + reader.readboolean; +end; + +procedure tmsebytesfield.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('Lookup',{$ifdef FPC}@{$endif}readlookup,nil,false); +end; + +function tmsebytesfield.getaswidestring: widestring; +begin + result:= asmsestring; +end; + +procedure tmsebytesfield.setaswidestring(const avalue: widestring); +begin + asmsestring:= avalue; +end; + +procedure tmsebytesfield.Clear; +begin + setdata(nil); +end; + +function tmsebytesfield.asoldsql: msestring; +begin + result:= fieldtooldsql(self); +end; + +function tmsebytesfield.getasvariant: variant; +begin + if isnull then begin + result:= null; + end + else begin + result:= asstring; + end; +end; + +procedure tmsebytesfield.setasstring(const avalue: string); +var + int1,int2: integer; + str1: string; +begin + int1:= datasize; + int2:= length(avalue); + if int2 < int1 then begin + str1:= avalue; + setlength(str1,int1); + fillchar((pchar(pointer(str1))+int2)^,int1-int2,0); + setdata(pointer(str1)); + end + else begin + setdata(pointer(avalue)); + end; +end; + +function tmsebytesfield.getasstring: string; +begin + setlength(result,datasize); + if not getdata(pointer(result)) then begin + result:= ''; + end; +end; +{ +function tmsebytesfield.getproviderflags1: providerflags1ty; +begin + result:= fproviderflags1; +end; +} +procedure tmsebytesfield.change; +begin + if not (fis_changing in fstate) then begin + include(fstate,fis_changing); + try + inherited; + finally + exclude(fstate,fis_changing); + end; + end; +end; + +procedure tmsebytesfield.SetDataset(AValue: TDataset); +begin + if fieldname = '' then begin + fieldname:= fieldnamedummy; + try + inherited; + finally + fieldname:= ''; + end; + end + else begin + inherited; + end; +end; +{ +function tmsebytesfield.getlookupinfo: plookupfieldinfoty; +begin + result:= @flookupinfo; +end; +} +{ tmsevarbytesfield } + +function tmsevarbytesfield.HasParent: Boolean; +begin + result:= dataset <> nil; +end; + +function tmsevarbytesfield.assql: msestring; +begin + result:= fieldtosql(self); +end; +{ +procedure tmsevarbytesfield.setasunicodestring(const avalue: unicodestring); +begin + asstring:= avalue; +end; + +function tmsevarbytesfield.getasunicodestring: unicodestring; +begin + result:= asstring; +end; +} +procedure tmsevarbytesfield.readlookup(reader: treader); +begin + reader.readboolean; +end; + +procedure tmsevarbytesfield.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('Lookup',{$ifdef FPC}@{$endif}readlookup,nil,false); +end; +{ +function tmsevarbytesfield.getaswidestring: widestring; +begin + result:= asmsestring; +end; + +procedure tmsevarbytesfield.setaswidestring(const avalue: widestring); +begin + asmsestring:= avalue; +end; +} +procedure tmsevarbytesfield.Clear; +begin + setdata(nil); +end; + +function tmsevarbytesfield.asoldsql: msestring; +begin + result:= fieldtooldsql(self); +end; + +function tmsevarbytesfield.getasvariant: variant; +begin + if isnull then begin + result:= null; + end + else begin + result:= asstring; + end; +end; + +procedure tmsevarbytesfield.setasstring(const avalue: string); +var + int1,int2: integer; + str1: string; +begin + int1:= datasize; + int2:= length(avalue); + if int2 > int1 - sizeof(word) then begin + int2:= int1 - sizeof(word); + end; + setlength(str1,int1); + pword(pointer(str1))^:= int2; + move((pchar(pointer(avalue)))^,(pchar(pointer(str1))+sizeof(word))^,int2); + setdata(pointer(str1)); +end; + +function tmsevarbytesfield.getasstring: string; +var + wo1: word; +begin + setlength(result,datasize); + if not getdata(pointer(result)) then begin + result:= ''; + end + else begin + wo1:= pword(pointer(result))^; + move((pchar(pointer(result))+2)^,pchar(pointer(result))^,wo1); + setlength(result,wo1); + end +end; +{ +function tmsevarbytesfield.getproviderflags1: providerflags1ty; +begin + result:= fproviderflags1; +end; +} +procedure tmsevarbytesfield.change; +begin + if not (fis_changing in fstate) then begin + include(fstate,fis_changing); + try + inherited; + finally + exclude(fstate,fis_changing); + end; + end; +end; + +procedure tmsevarbytesfield.SetDataset(AValue: TDataset); +begin + if fieldname = '' then begin + fieldname:= fieldnamedummy; + try + inherited; + finally + fieldname:= ''; + end; + end + else begin + inherited; + end; +end; +{ +function tmsevarbytesfield.getlookupinfo: plookupfieldinfoty; +begin + result:= @flookupinfo; +end; +} +{ tmsebcdfield } + +function tmsebcdfield.HasParent: Boolean; +begin + result:= dataset <> nil; +end; + +function tmsebcdfield.assql: msestring; +begin + result:= fieldtosql(self); +end; +{ +procedure tmsebcdfield.setasmsestring(const avalue: msestring); +begin + asstring:= avalue; +end; + +function tmsebcdfield.getasmsestring: msestring; +begin + result:= asstring; +end; +} +procedure tmsebcdfield.readlookup(reader: treader); +begin + reader.readboolean; +end; + +procedure tmsebcdfield.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('Lookup',{$ifdef FPC}@{$endif}readlookup,nil,false); +end; + +function tmsebcdfield.getaswidestring: widestring; +begin + result:= asmsestring; +end; + +procedure tmsebcdfield.setaswidestring(const avalue: widestring); +begin + asmsestring:= avalue; +end; + +procedure tmsebcdfield.Clear; +begin + setdata(nil); +end; + +function tmsebcdfield.asoldsql: msestring; +begin + result:= fieldtooldsql(self); +end; + +procedure tmsebcdfield.setasfloat(avalue: double); +begin + if avalue = emptyreal then begin + clear; + end + else begin + inherited; + end; +end; + +class procedure tmsebcdfield.checktypesize(avalue: longint); +begin + if (avalue < 0) or (avalue > 8) then begin + databaseerrorfmt(sinvalidfieldsize,[avalue]); + end; +end; + +procedure tmsebcdfield.gettext(var thetext: string; adisplaytext: boolean); +var + cu1: system.currency; +begin + thetext:=''; + if getdata(@cu1) then begin + thetext:= getnumdisplaytext(self,cu1,adisplaytext,currency); + end; +end; + +function tmsebcdfield.sum: currency; +var + curr1: system.currency; + bm: bookmarkty; + intf1: idatasetsum; +begin + result:= 0; + if (dataset <> nil) and dataset.active then begin + if (fieldkind in [fkdata,fkinternalcalc]) and + getcorbainterface(dataset,typeinfo(idatasetsum),intf1) then begin + intf1.sumfield(tfield(self),result); + end + else begin + with dataset do begin + disablecontrols; + try + bm:= bookmark; + first; + while not eof do begin + if getdata(@curr1) then begin + result:= result + curr1; + end; + next; + end; + bookmark:= bm; + finally + enablecontrols; + end; + end; + end; + end; +end; +{ +function tmsebcdfield.getproviderflags1: providerflags1ty; +begin + result:= fproviderflags1; +end; +} +procedure tmsebcdfield.change; +begin + if not (fis_changing in fstate) then begin + include(fstate,fis_changing); + try + inherited; + finally + exclude(fstate,fis_changing); + end; + end; +end; + +procedure tmsebcdfield.SetDataset(AValue: TDataset); +begin + if fieldname = '' then begin + fieldname:= fieldnamedummy; + try + inherited; + finally + fieldname:= ''; + end; + end + else begin + inherited; + end; +end; +{ +function tmsebcdfield.getlookupinfo: plookupfieldinfoty; +begin + result:= @flookupinfo; +end; +} + +{ tmseblobfield } + +destructor tmseblobfield.destroy; +begin + freeandnil(fcache); + inherited; +end; + +function tmseblobfield.HasParent: Boolean; +begin + result:= dataset <> nil; +end; + +function tmseblobfield.assql: msestring; +begin + result:= fieldtosql(self); +end; +{ +procedure tmseblobfield.setasmsestring(const avalue: msestring); +begin + asstring:= avalue; +end; + +function tmseblobfield.getasmsestring: msestring; +begin + result:= asstring; +end; +} +procedure tmseblobfield.LoadFromStream(Stream: TStream); +begin + removecache; + inherited; +end; + +procedure tmseblobfield.LoadFromFile(const FileName: filenamety); +begin + if filename = '' then begin + clear; + end + else begin + removecache; + inherited loadfromfile(ansistring(tosysfilepath(filename))); + end; +end; + +procedure tmseblobfield.SaveToFile(const FileName: filenamety); +begin + inherited savetofile(ansistring(tosysfilepath(filename))); +end; + +function tmseblobfield.asoldsql: msestring; +begin + result:= fieldtooldsql(self); +end; + +function tmseblobfield.getasvariant: variant; +begin + if isnull then begin + result:= NULL; + end + else begin + result:= getasstring; + end; +end; + +procedure tmseblobfield.setcachekb(const avalue: integer); +begin + if cachekb <> avalue then begin + if avalue > 0 then begin + if fcache = nil then begin + fcache:= tblobcache.create; + end; + fcache.maxsize:= avalue * 1024; + end + else begin + freeandnil(fcache); + end; + end; +end; + +function tmseblobfield.getcachekb: integer; +begin + result:= 0; + if fcache <> nil then begin + result:= fcache.maxsize div 1024; + end; +end; +(* +function tmseblobfield.getblobid(out aid: blobidty): boolean; +begin + result:= assigned(fgetblobid); + if result then begin + fgetblobid(aid); + end; + { + aid:= 0; + case size of + 4,8: begin + result:= getdata(@aid); + end; + else begin + if size > 0 then begin + databaseerror('Invalid cache field: '''+fieldname+'''.',self); + end; + end; + end; + } +end; +*) +function tmseblobfield.getasstring: string; +var + id1: blobidty; + n1: tblobcachenode; +begin + if (fcache <> nil) and assigned(fgetblobid) then begin + result:= ''; + if fgetblobid(self,id1) then begin + if fcache.find(id1,n1) then begin + result:= n1.data; + end + else begin + result:= inherited getasstring; + fcache.addnode(id1,result); + end; + end; + end + else begin + result:= inherited getasstring; + end; +end; + +procedure tmseblobfield.readlookup(reader: treader); +begin + reader.readboolean; +end; + +procedure tmseblobfield.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('Lookup',{$ifdef FPC}@{$endif}readlookup,nil,false); +end; + +procedure tmseblobfield.removecache(const aid: blobidty); +var + n1: tblobcachenode; +begin + if fcache <> nil then begin + if fcache.find(aid,n1) then begin + fcache.removenode(n1); + n1.free; + end; + end; +end; + +procedure tmseblobfield.removecache; +var + id1: blobidty; +begin + if assigned(fgetblobid) and fgetblobid(self,id1) then begin + removecache(id1); + end; +end; + +procedure tmseblobfield.setasstring(const avalue: string); +begin + removecache; + inherited; +end; + +procedure tmseblobfield.Clear; +begin + removecache; + inherited; +end; + +procedure tmseblobfield.clearcache; +begin + if fcache <> nil then begin + fcache.clear; + end; +end; + +procedure tmseblobfield.gettext(var atext: string; adisplaytext: boolean); +begin + if isnull then begin + atext:= '(blob)'; + end + else begin + atext:= '(BLOB)'; + end; +end; +{ +function tmseblobfield.getaswidestring: widestring; +begin + result:= getasmsestring; +end; + +procedure tmseblobfield.setaswidestring(const avalue: widestring); +begin + setasmsestring(avalue); +end; +} +{ +function tmseblobfield.getproviderflags1: providerflags1ty; +begin + result:= fproviderflags1; +end; +} +procedure tmseblobfield.SetDataset(AValue: TDataset); +begin + if fieldname = '' then begin + fieldname:= fieldnamedummy; + try + inherited; + finally + fieldname:= ''; + end; + end + else begin + inherited; + end; +end; +{ +function tmseblobfield.getlookupinfo: plookupfieldinfoty; +begin + result:= @flookupinfo; +end; +} +{ tmsevariantfield } + +function tmsevariantfield.getdatasize: integer; +begin + result:= sizeof(variant); +end; + +function tmsevariantfield.getasvariant: variant; +begin + if assigned(fgetvardata) then begin + fgetvardata(self,result); + end + else begin + result:= null; + end; +end; + +procedure tmsevariantfield.setvarvalue(const avalue: variant); +begin + if assigned(fsetvardata) then begin + fsetvardata(self,avalue); + end; +end; + +function tmsevariantfield.getasboolean: boolean; +begin + if isnull then begin + result:= false; + end + else begin + result:= getasvariant; + end; +end; + +function tmsevariantfield.getasdatetime: tdatetime; +begin + if isnull then begin + result:= emptydatetime; + end + else begin + result:= getasvariant; + end; +end; + +function tmsevariantfield.getasfloat: double; +begin + if isnull then begin + result:= emptyreal; + end + else begin + result:= getasvariant; + end; +end; + +function tmsevariantfield.getasinteger: longint; +begin + if isnull then begin + result:= 0; + end + else begin + result:= getasvariant; + end; +end; +{ +function tmsevariantfield.getasstring: string; +begin + if isnull then begin + result:= ''; + end + else begin + result:= getasvariant; + end; +end; + +function tmsevariantfield.getaswidestring: widestring; +begin + if isnull then begin + result:= ''; + end + else begin + result:= getasvariant; + end; +end; +} +function tmsevariantfield.getaslongint: longint; +begin + if isnull then begin + result:= 0; + end + else begin + result:= getasvariant; + end; +end; + +procedure tmsevariantfield.setaslongint(avalue: longint); +begin + setvarvalue(avalue); +end; + +function tmsevariantfield.getaslargeint: largeint; +begin + if isnull then begin + result:= 0; + end + else begin + result:= getasvariant; + end; +end; + +procedure tmsevariantfield.setaslargeint(avalue: largeint); +begin + setvarvalue(avalue); +end; + +function tmsevariantfield.getascurrency: currency; +begin + if isnull then begin + result:= 0; + end + else begin + result:= getasvariant; + end; +end; + +procedure tmsevariantfield.setascurrency(avalue: currency); +begin + setvarvalue(avalue); +end; + +function tmsevariantfield.assql: msestring; +begin + result:= fieldtosql(self); +end; + +function tmsevariantfield.asoldsql: msestring; +begin + result:= fieldtooldsql(self); +end; +{ +function tmsevariantfield.getproviderflags1: providerflags1ty; +begin + result:= fproviderflags1; +end; +} +procedure tmsevariantfield.SetDataset(AValue: TDataset); +begin + if fieldname = '' then begin + fieldname:= fieldnamedummy; + try + inherited; + finally + fieldname:= ''; + end; + end + else begin + inherited; + end; +end; +{ +function tmsevariantfield.getlookupinfo: plookupfieldinfoty; +begin + result:= @flookupinfo; +end; +} +{ tdbfieldnamearrayprop } + +constructor tdbfieldnamearrayprop.create(const afieldtypes: fieldtypesty; + const agetdatasource: getdatasourcefuncty); +begin + ffieldtypes:= afieldtypes; + fgetdatasource:= agetdatasource; + inherited create; +end; + +function tdbfieldnamearrayprop.getdataset(const aindex: integer): tdataset; +var + dso1: tdatasource; +begin + result:= nil; + dso1:= fgetdatasource(); + if dso1 <> nil then begin + result:= dso1.dataset; + end; +end; + +procedure tdbfieldnamearrayprop.getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); +begin + apropertynames:= nil; + setlength(afieldtypes,1); + afieldtypes[0]:= ffieldtypes; +end; + +{ tmsedatalink } + +procedure tmsedatalink.checkcontroller; +var + intf1: igetdscontroller; +begin + fdscontroller:= nil; + if dataset <> nil then begin + if getcorbainterface(dataset,typeinfo(igetdscontroller),intf1) then begin + fdscontroller:= intf1.getcontroller; + end; + end; +end; + +procedure tmsedatalink.activechanged; +//var +// intf1: igetdscontroller; +begin + checkcontroller; + inherited; +end; + +function tmsedatalink.getutf8: boolean; +begin + result:= (fdscontroller <> nil) and (dso_utf8 in fdscontroller.foptions); +end; + +function tmsedatalink.getfiltereditkind: filtereditkindty; +begin + result:= fek_filter; + if fdscontroller <> nil then begin + result:= fdscontroller.filtereditkind; + end; +end; + +function tmsedatalink.getdataset: tdataset; +begin + result:= nil; + if datasource <> nil then begin + result:= datasource.dataset; + end; +end; + +function tmsedatalink.moveby(distance: integer): integer; + +begin + result:= 0; + if (distance <> 0) and active then begin + if fdscontroller <> nil then begin + result:= fdscontroller.moveby(distance); + end + else begin + result:= inherited moveby(distance); + end; + end; +end; + +function tmsedatalink.GetActiveRecord: Integer; +begin + if (dataset = nil) or (csdestroying in dataset.componentstate) then begin + result:= -1; + end + else begin + result:= inherited getactiverecord; + end; +end; + +procedure tmsedatalink.DataEvent(Event: TDataEvent; Info: Ptrint); +begin + inherited; + if event = dedisabledstatechange then begin + disabledstatechange; + end; +end; + +function tmsedatalink.canclose: boolean; +begin + result:= (fcanclosing > 0) or not active; + if not result then begin + inc(fcanclosing); + try + dataset.checkbrowsemode; + result:= true; + except + application.handleexception(nil); + end; + dec(fcanclosing); + end; +end; + +function tmsedatalink.getrecnozerobased: integer; +var + ds1: tdataset; +begin + result:= -1; + if fdscontroller <> nil then begin + result:= fdscontroller.recnozerobased; + end + else begin + ds1:= dataset; + if (ds1 <> nil) and ds1.active then begin + result:= ds1.recno -1; + end; + end; +end; + +procedure tmsedatalink.setrecnozerobased(const avalue: integer); +var + ds1: tdataset; +begin + if fdscontroller <> nil then begin + fdscontroller.recnozerobased:= avalue; + end + else begin + ds1:= dataset; + if (ds1 <> nil) and ds1.active then begin + ds1.recno:= avalue + 1; + end; + end; +end; + +function tmsedatalink.noedit: boolean; +begin + result:= readonly or (dataset <> nil) and not dataset.canmodify; +end; + +function tmsedatalink.canedit: boolean; +begin + result:= active and not noedit; +end; + +function tmsedatalink.caninsert: boolean; +begin + result:= canedit and ((fdscontroller = nil) or not fdscontroller.noinsert); +end; + +function tmsedatalink.canappend: boolean; +begin + result:= canedit and ((fdscontroller = nil) or not fdscontroller.noappend); +end; + +function tmsedatalink.candelete: boolean; +begin + result:= canedit and ((fdscontroller = nil) or not fdscontroller.nodelete); +end; + +function tmsedatalink.canupdate: boolean; +begin + result:= canedit and ((fdscontroller = nil) or not fdscontroller.noupdate); +end; + +procedure tmsedatalink.disabledstatechange; +begin + //dummy +end; + +destructor tmsedatalink.destroy; +var + int1: integer; + ds1: tdataset1; +begin + int1:= 0; +{$warnings off} + ds1:= tdataset1(dataset); +{$warnings on} + if ds1 <> nil then begin + int1:= ds1.buffercount; + end; + inherited; + if (ds1 <> nil) and (ds1.buffercount < int1) then begin + ds1.dataevent(dedatasetchange,0); + end; +end; + +procedure tmsedatalink.setbuffercount(value: integer); +begin + inherited; + if active then begin + dataset.updatecursorpos(); + end; +end; + +{ tfieldsdatalink } + +procedure tfieldsdatalink.updatefields; +begin + //dummy +end; + +procedure tfieldsdatalink.activechanged; +begin + inherited; + updatefields; +end; + +procedure tfieldsdatalink.layoutchanged; +begin + inherited; + updatefields; +end; + +procedure tfieldsdatalink.fieldchanged; +begin + updateactive(); //active flag must be valid + recordchanged(nil); +end; + +procedure tfieldsdatalink.execute(const sender: iificlient); +begin +end; + +procedure tfieldsdatalink.valuechanged(const sender: iifidatalink); +begin + //dummy +end; + +procedure tfieldsdatalink.statechanged(const sender: iificlient; + const astate: ifiwidgetstatesty); +begin + if datasource <> nil then begin + tdatasource1(datasource).ifistatechanged(self,sender,astate); + end; +end; + +procedure tfieldsdatalink.setvalue(const sender: iificlient; var avalue; + var accept: boolean; const arow: integer); +begin + //dummy +end; + +procedure tfieldsdatalink.dataentered(const sender: iificlient; + const arow: integer); +begin + //dummy +end; + +procedure tfieldsdatalink.closequery(const sender: iificlient; + var amodalresult: modalresultty); +begin + //dummy +end; + +procedure tfieldsdatalink.sendmodalresult(const sender: iificlient; + const amodalresult: modalresultty); +begin + //dummy +end; + +procedure tfieldsdatalink.updateoptionsedit(var avalue: optionseditty); +begin + //dummy +end; + +{ tfielddatalink } + +procedure tfielddatalink.setfieldname(const Value: string); +begin + if ffieldname <> value then begin + ffieldname := value; + updatefields; + end; +end; + +procedure tfielddatalink.setfield(const value: tfield); +const + mask: fielddatalinkstatesty = [fds_ismsestring,fds_islargeint, + fds_isstring]; +var + state1: fielddatalinkstatesty; +begin + if ffield <> value then begin + ffield := value; + state1:= []; + if (ffield <> nil) then begin + if ffield is tmsestringfield then begin + include(state1,fds_ismsestring); + end; + if (ffield.datatype = ftlargeint) then begin + include(state1,fds_islargeint); + end; + if (ffield.datatype in textfields) then begin + include(state1,fds_isstring); + end; + end; + replacebits1({$ifdef FPC}longword{$else}byte{$endif}(fstate), + {$ifdef FPC}longword{$else}byte{$endif}(state1), + {$ifdef FPC}longword{$else}byte{$endif}(mask)); + fieldchanged; + editingchanged; //??? + end; +end; + +procedure tfielddatalink.updatefields; +begin + if (datasource <> nil) and (datasource.dataset <> nil) and + datasource.dataset.active and (ffieldname <> '') then begin +// if active and (ffieldname <> '') then begin + setfield(datasource.dataset.fieldbyname(ffieldname)); + end + else begin + setfield(nil); + end; +end; + +function tfielddatalink.getasmsestring: msestring; +begin + if fds_ismsestring in fstate then begin + result:= tmsestringfield(ffield).asmsestring; + end + else begin + try + if utf8 then begin + result:= utf8tostringansi(field.asstring); + end + else begin + result:= msestring(field.asstring); + end; + except + result:= converrorstring; + end; + end; +end; + +function tfielddatalink.getmsedefaultexpression: msestring; +begin + if fds_ismsestring in fstate then begin + result:= tmsestringfield(ffield).defaultexpression; + if result = #0 then begin + result:= ''; + end; + end + else begin + result:= msestring(ffield.defaultexpression); + end; +end; + +procedure tfielddatalink.setasmsestring(const avalue: msestring); +begin + if fds_ismsestring in fstate then begin + tmsestringfield(field).asmsestring:= avalue; + end + else begin + if utf8 then begin + ffield.asstring:= stringtoutf8ansi(avalue); + end + else begin + ffield.asstring:= ansistring(avalue); + end; + end; +end; + +function tfielddatalink.msedisplaytext(const aformat: msestring = ''; + const aedit: boolean = false): msestring; + function defaulttext: msestring; + begin + if utf8 and (ffield.datatype in textfields) then begin + result:= utf8tostringansi(ffield.displaytext); + end + else begin + if aedit then begin + result:= msestring(ffield.text); + end + else begin + result:= msestring(ffield.displaytext); + end; + end; + end; + +begin + result:= ''; + if ffield <> nil then begin + if not ffield.isnull then begin + if fds_ismsestring in fstate then begin + result:= aformat + tmsestringfield(ffield).asmsestring; + end + else begin + if aformat <> '' then begin + case ffield.datatype of + ftsmallint,ftinteger,ftword,ftlargeint,ftbcd,ftfloat,ftcurrency: begin + result:= formatfloatmse(field.asfloat,aformat); + end; + ftboolean: begin + result:= formatfloatmse(ord(field.asboolean),aformat); + end; + ftdate,fttime,ftdatetime: begin + result:= formatdatetimemse(aformat,field.asdatetime); + end; + else begin + result:= aformat + defaulttext; + end; + end; + end + else begin + result:= defaulttext; + end; + end; + end + else begin + result:= fnullsymbol; + end; + end; +end; + +function tfielddatalink.assql: msestring; +begin + result:= fieldtosql(ffield); +end; + +procedure tfielddatalink.checkfield; +begin + if ffield = nil then begin + raise exception.create('Field is nil.'); + end; +end; + +procedure tfielddatalink.clear; +begin + checkfield; + field.clear; +end; + +function tfielddatalink.GetAsBoolean: Boolean; +begin + checkfield; + result:= field.asboolean; +end; + +procedure tfielddatalink.SetAsBoolean(const avalue: Boolean); +begin + checkfield; + field.asboolean:= avalue; +end; + +function tfielddatalink.GetAsCurrency: Currency; +begin + checkfield; + result:= field.ascurrency; +end; + +procedure tfielddatalink.SetAsCurrency(const avalue: Currency); +begin + checkfield; + field.ascurrency:= avalue; +end; + +function tfielddatalink.GetAsDateTime: TDateTime; +begin + checkfield; + result:= field.asdatetime; +end; + +procedure tfielddatalink.SetAsDateTime(const avalue: TDateTime); +begin + checkfield; + field.asdatetime:= avalue; +end; + +function tfielddatalink.GetAsFloat: Double; +begin + checkfield; + result:= field.asfloat; +end; + +procedure tfielddatalink.SetAsFloat(const avalue: Double); +begin + checkfield; + field.asfloat:= avalue; +end; + +function tfielddatalink.GetAsLongint: Longint; +begin + checkfield; + result:= field.aslongint; +end; + +procedure tfielddatalink.SetAsLongint(const avalue: Longint); +begin + checkfield; + field.aslongint:= avalue; +end; + +function tfielddatalink.GetAsLargeInt: LargeInt; +begin + checkfield; + result:= field.aslargeint; +end; + +procedure tfielddatalink.SetAsLargeInt(const avalue: LargeInt); +begin + checkfield; + field.aslargeint:= avalue; +end; + +function tfielddatalink.GetAsInteger: Integer; +begin + checkfield; + result:= field.asinteger; +end; + +procedure tfielddatalink.SetAsInteger(const avalue: Integer); +begin + checkfield; + field.asinteger:= avalue; +end; + +function tfielddatalink.GetAsString: string; +begin + checkfield; + result:= field.asstring; +end; + +procedure tfielddatalink.SetAsString(const avalue: string); +begin + checkfield; + field.asstring:= avalue; +end; + +function tfielddatalink.GetAsVariant: variant; +begin + checkfield; + result:= field.asvariant; +end; + +procedure tfielddatalink.SetAsVariant(const avalue: variant); +begin + checkfield; + field.asvariant:= avalue; +end; + +function tfielddatalink.fieldactive: boolean; +begin + result:= (ffield <> nil) and (dataset <> nil) and (dataset.state <> dsinactive); +// result:= active and (ffield <> nil); //unreliable +end; + +function tfielddatalink.getislargeint: boolean; +begin + result:= fds_islargeint in fstate; +end; + +function tfielddatalink.getismsestring: boolean; +begin + result:= fds_ismsestring in fstate; +end; + +function tfielddatalink.getisstringfield: boolean; +begin + result:= fds_isstring in fstate; +end; + +function tfielddatalink.getsortfield: tfield; +begin + if ffield = nil then begin + updatefields; + end; + result:= ffield; +end; + +procedure tfielddatalink.setvalue(const sender: iificlient; var avalue; + var accept: boolean; const arow: integer); +begin + inherited; + if ffield <> nil then begin + case sender.getifidatatype() of + dl_integer: begin + tfield1(ffield).dosetvalue(sender.getinstance,int32(avalue),accept); + end; + dl_int64: begin + tfield1(ffield).dosetvalue(sender.getinstance,int64(avalue),accept); + end; + dl_currency: begin + tfield1(ffield).dosetvalue(sender.getinstance,currency(avalue),accept); + end; + dl_real: begin + tfield1(ffield).dosetvalue(sender.getinstance,flo64(avalue),accept); + end; + dl_msestring: begin + tfield1(ffield).dosetvalue(sender.getinstance,msestring(avalue),accept); + end; + dl_ansistring: begin + tfield1(ffield).dosetvalue(sender.getinstance,ansistring(avalue),accept); + end; + end; + end; +end; + +procedure tfielddatalink.dataentered(const sender: iificlient; + const arow: integer); +begin + inherited; + if ffield <> nil then begin + tfield1(ffield).dodataentered(sender.getinstance); + end; +end; + +{ tpersistentfields } + +constructor tpersistentfields.create(const adataset: tdataset); +begin + fdataset:= adataset; + inherited create(nil); +end; + +class function tpersistentfields.getitemclasstype: persistentclassty; +begin + result:= tfield; +end; + +procedure tpersistentfields.createitem(const index: integer; + var item: tpersistent); +begin + if csloading in fdataset.componentstate then begin + item:= nil; + end + else begin + item:= tfield.create(nil); + tfield(item).dataset:= fdataset; + end; +end; + +procedure tpersistentfields.readfields(reader: treader); +var + int1: integer; + fieldtypes: fieldclasstypearty; + wantedclass: fieldclassty; + str1: string; +begin + setlength(fieldtypes,count); + int1:= 0; + reader.readlistbegin; + reader.readlistbegin; + while not reader.endoflist do begin + if int1 > high(fieldtypes) then begin + reader.readident; + //skip + end + else begin + fieldtypes[int1]:= fieldclasstypety(getenumvalue(typeinfo(fieldclasstypety), + reader.readident)); + inc(int1); + end; + end; + reader.readlistend; + for int1:= 0 to high(fieldtypes) do begin + wantedclass:= msefieldtypeclasses[fieldtypes[int1]]; + if (fitems[int1] <> nil) and (fieldtypes[int1] <> ft_unknown) and + not (tfield(fitems[int1]) is wantedclass) then begin + if (fitems[high(fitems)] = nil) then begin + moveitem(pointerarty(fitems),high(fitems),int1); //probably inserted field + end; + { + else begin + for int2:= int1+1 to high(fitems) do begin + if tfield(fitems[int2]) is wantedclass then begin + moveitem(pointerarty(fitems),int2,int1); //try to correct invalid order + break; + end; + end; + end; + } + end; + str1:= ''; + if (fitems[int1] <> nil) and (fieldtypes[int1] <> ft_unknown) and + not (tfield(fitems[int1]) is wantedclass) then begin + str1:= tfield(fitems[int1]).fieldname; + freeandnil(tfield(fitems[int1])); //there is something wrong + end; + if fitems[int1] = nil then begin + fitems[int1]:= wantedclass.create(nil); + tfield(fitems[int1]).fieldname:= str1; + end; + end; + for int1:= 0 to high(fitems) do begin + with tfield(fitems[int1]) do begin + dataset:= fdataset; + end; + end; + readcollection(reader); + reader.readlistend; +end; + +procedure tpersistentfields.writefields(writer: twriter); +var + int1: integer; + class1: fieldclassty; +begin + writer.writelistbegin; + writer.writelistbegin; + finvaliditems:= nil; + setlength(finvaliditems,count); + for int1:= 0 to high(fitems) do begin + class1:= fieldclassty(fitems[int1].classtype); + if (writer.ancestor <> nil) and + not ((writer is twritermse) and twritermse(writer).masterancestor) then begin + with tpersistentfields(writer.ancestor) do begin + if (int1 < count) then begin + if (fitems[int1].classtype <> class1) then begin + class1:= fieldclassty(fitems[int1].classtype); + //do not change inherited field type + self.finvaliditems[int1]:= true; + end + else begin + class1:= nil; + end; + end; + end; + end; + writer.writeident(getenumname(typeinfo(fieldclasstypety), + ord(fieldclasstoclasstyp(class1)))); + end; + writer.writelistend; + writecollection(writer); + finvaliditems:= nil; + writer.writelistend; +end; + +procedure tpersistentfields.defineproperties(filer: tfiler); +//var +// int1: integer; +begin + filer.defineproperty('fields',{$ifdef FPC}@{$endif}readfields, + {$ifdef FPC}@{$endif}writefields,count > 0); +end; + +procedure tpersistentfields.setitems(const index: integer; const avalue: tfield); +begin + items[index].assign(avalue); +end; + +function tpersistentfields.getitems(const index: integer): tfield; +begin + result:= tfield(inherited getitems(index)); +end; + +procedure tpersistentfields.updateorder; +var + int1: integer; + bo1: boolean; +begin + bo1:= fdataset.active; + fdataset.active:= false; + for int1:= 0 to count - 1 do begin + items[int1].index:= int1; + end; + fdataset.active:= bo1; +end; + +procedure tpersistentfields.move(const curindex: integer; const newindex: integer); +begin + inherited; + updateorder; +end; + +function tpersistentfields.getfieldnames: stringarty; +var + int1: integer; +begin + setlength(result,count); + for int1:= 0 to high(result) do begin + result[int1]:= tfield(fitems[int1]).fieldname; + end; +end; + +function tpersistentfields.ispropertystored(index: integer): boolean; +begin + result:= inherited ispropertystored(index) and not finvaliditems[index]; +end; + + +{ tdscontroller } + +constructor tdscontroller.create(const aowner: tdataset; + const aintf: idscontroller; + const arecnooffset: integer = -1; + const acancelresync: boolean = true); +begin + ffields:= tpersistentfields.create(aowner); +// fintf:= aintf; + frecnooffset:= arecnooffset; + fcancelresync:= acancelresync; + foptions:= defaultdscontrolleroptions; + inherited create(aowner,aintf); + if aowner is tmsebufdataset then begin + with tmsebufdataset1(aowner) do begin + foldopts:= getdefaultoptions * oldbdsoptions; + end; + end; +end; + +destructor tdscontroller.destroy; +var + int1: integer; + field1: tfield; +begin +// unregisteronidle; + tdataset(fowner).active:= false; //avoid later calls from fowner + for int1:= 0 to high(flinkedfields) do begin + flinkedfields[int1].setdsintf(nil); + end; + flinkedfields:= nil; + with tdataset(fowner).fields do begin + for int1:= count-1 downto 0 do begin + field1:= fields[int1]; + if (field1.owner <> nil) and not + (csdestroying in field1.componentstate) then begin + field1.dataset:= nil; + end; + end; + end; + ffields.free; + freeandnil(ftimer); + inherited; +end; + +procedure tdscontroller.fielddestroyed(const sender: ifieldcomponent); +begin + removeitem(pointerarty(flinkedfields),pointer(sender)); +end; + +procedure tdscontroller.setowneractive(const avalue: boolean); +begin + tdataset(fowner).active:= avalue; +end; + +function tdscontroller.locate(const afields: array of tfield; + const akeys: array of const; + const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; +begin + result:= locaterecord(tdataset(fowner),afields,akeys,aisnull,akeyoptions,aoptions); +end; +{ +function tdscontroller.locate(const key: integer; const field: tfield; + const options: locateoptionsty = []): locateresultty; +begin + result:= locaterecord(tdataset(fowner),key,field,options); +end; + +function tdscontroller.locate(const key: int64; const field: tfield; + const options: locateoptionsty = []): locateresultty; +begin + result:= locaterecord(tdataset(fowner),key,field,options); +end; + +function tdscontroller.locate(const key: msestring; const field: tfield; + const options: locateoptionsty = []): locateresultty; +begin + result:= locaterecord(tdataset(fowner),dso_utf8 in foptions,key,field,options); +end; +} +procedure tdscontroller.appendrecord1(const values: array of const; + const aisnull: array of boolean; + const afields: array of tfield); +var + int1,int2: integer; + field1: tfield; +begin + with tdataset(fowner) do begin + append; + int2:= high(values); + if int2 > high(afields) then begin + int2:= high(afields); + end; + for int1:= 0 to int2 do begin + field1:= afields[int1]; + if (int1 <= high(aisnull)) and aisnull[int1] then begin + field1.clear(); + end + else begin + with values[int1] do begin + case vtype of + vtInteger: field1.asinteger:= VInteger; + vtInt64: field1.aslargeint:= VInt64^; + vtBoolean: field1.asboolean:= VBoolean; + vtChar: field1.asstring:= VChar; + vtWideChar: field1.asstring:= ansistring(VWideChar); + vtExtended: field1.asfloat:= VExtended^; + vtString: field1.asstring:= VString^; + // vtPointer: + vtPChar: field1.asstring:= VPChar; + // vtObject: + // vtClass: + vtPWideChar: field1.asstring:= VPWideChar; + vtAnsiString: field1.asstring:= ansistring(VAnsiString); + vtCurrency: field1.ascurrency:= VCurrency^; + vtVariant: field1.asvariant:= VVariant^; + // vtInterface: + {$ifdef mse_hasvtunicodestring} + vtunicodestring: begin + if (field1 is tmsestringfield) then begin + tmsestringfield(field1).asmsestring:= msestring(vunicodestring); + end + else begin + if (field1 is tmsememofield) then begin + tmsememofield(field1).asmsestring:= msestring(vunicodestring); + end + else begin + field1.asstring:= ansistring(widestring(vunicodestring)); + end; + end; + end; + {$endif} + vtWideString: begin + if (field1 is tmsestringfield) then begin + tmsestringfield(field1).asmsestring:= msestring(vwidestring); + end + else begin + if (field1 is tmsememofield) then begin + tmsememofield(field1).asmsestring:= msestring(vwidestring); + end + else begin + field1.asstring:= ansistring(widestring(vwidestring)); + end; + end; + end; + // vtInt64: + // vtQWord: + end; + end; + end; + end; + end; +end; + +procedure tdscontroller.appendrecord(const values: array of const; + const afields: array of tfield); +begin + appendrecord1(values,[],afields); +end; + +procedure tdscontroller.appendrecord1(const values: array of const; + const aisnull: array of boolean); +var + ar1: fieldarty; + int1: integer; +begin + with tdataset(fowner) do begin + setlength(ar1,fields.count); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= fields[int1]; + end; + end; + appendrecord1(values,aisnull,ar1); +end; + +procedure tdscontroller.appendrecord(const values: array of const); +begin + appendrecord1(values,[]); +end; + +procedure tdscontroller.appendrecord(const values: variantarty); +var + int1: integer; +begin + with tdataset(fowner) do begin + append; + for int1:= 0 to high(values) do begin + fields[int1].value:= values[int1]; + end; + end; +end; + +procedure tdscontroller.appenddata(const adata: variantararty; const afields: array of tfield); + //[] -> all +var + int1,int2{,int3}: integer; + ar1: fieldarty; +begin + ar1:= getdsfields(tdataset(fowner),afields); + with tdataset(fowner) do begin + checkbrowsemode; + for int1:= 0 to high(adata) do begin + if state = dsinsert then begin + post; + end; + append; + for int2:= 0 to high(ar1) do begin + if int2 > high(adata[int1]) then begin + break; + end; + ar1[int2].value:= adata[int1][int2]; + end; + end; + if state = dsinsert then begin + post; + end + end; +end; + +procedure tdscontroller.setfields(const avalue: tpersistentfields); +begin + ffields.assign(avalue); +end; + +procedure tdscontroller.getfieldclass(const fieldtype: tfieldtype; out result: tfieldclass); +begin + result:= msefieldtypeclasses[tfieldtypetotypety[fieldtype]]; +end; + +function tdscontroller.getrecnozerobased: integer; +begin + with tdataset1(fowner) do begin + if bof and eof then begin + result:= -1; + end + else begin + if not frecnovalid or tdataset(fowner).filtered or + (fbuffercountbefore <> tdataset1(fowner).buffercount) then begin + fbuffercountbefore:= tdataset1(fowner).buffercount; + if bof then begin + frecno:= 0; + end + else begin + if eof then begin + frecno:= recordcount - 1; + end + else begin + frecno:= recno + frecnooffset; + end; + end; + frecnovalid:= not tdataset(fowner).filtered; + end + else begin + inc(frecno,fscrollsum + activerecord - factiverecordbefore); + end; + factiverecordbefore:= activerecord; + fscrollsum:= 0; + result:= frecno; + end; + if (state = dsinsert) and (getbookmarkflag(activebuffer) = bfeof) then begin + inc(result); //append mode + end; + end; +end; + +procedure tdscontroller.setrecnozerobased(const avalue: integer); +begin + if avalue <> getrecnozerobased then begin + tdataset1(fowner).recno:= avalue - recnooffset; + frecno:= avalue; + factiverecordbefore:= tdataset1(fowner).activerecord; + fscrollsum:= 0; + frecnovalid:= not tdataset1(fowner).filtered; + end; +{ + if not frecnovalid or (avalue <> frecno) then begin + tdataset1(fowner).recno:= avalue - recnooffset; + frecno:= avalue; + factiverecordbefore:= tdataset1(fowner).activerecord; + fscrollsum:= 0; + frecnovalid:= true; + end; + } +end; + +function tdscontroller.getrecno: integer; +begin + result:= recnozerobased - frecnooffset; +end; + +procedure tdscontroller.setrecno(const avalue: integer); +begin + recnozerobased:= avalue + frecnooffset; +end; + +function tdscontroller.findrecno(const arecno: integer; + const options: recnosearchoptionsty): integer; +begin + result:= findrecnozerobased(arecno+frecnooffset,options)-frecnooffset; +end; + +function tdscontroller.findrecnozerobased(const arecno: integer; + const options: recnosearchoptionsty = []): integer; +begin + try + recnozerobased:= arecno; + except + with tdataset(fowner) do begin + disablecontrols; + try + resync([]); + if (recnozerobased > arecno) and (rso_backward in options) then begin + prior; + end; + finally + enablecontrols; + end; + end; + end; + result:= recnozerobased; +end; + +procedure tdscontroller.updatelinkedfields; +var + int1: integer; + intf1: ifieldcomponent; + field1: tfield; +begin + with tdataset(fowner) do begin + for int1:= 0 to fields.count - 1 do begin + field1:= fields[int1]; + if getcorbainterface(field1,typeinfo(ifieldcomponent),intf1) and + (finditem(pointerarty(flinkedfields),pointer(intf1)) < 0) then begin + additem(pointerarty(flinkedfields),pointer(intf1)); + intf1.setdsintf(idsfieldcontroller(self)); + end; + end; + for int1:= high(flinkedfields) downto 0 do begin + if fields.indexof(flinkedfields[int1].getinstance) < 0 then begin + flinkedfields[int1].setdsintf(nil); + deleteitem(pointerarty(flinkedfields),int1); + end; + end; + end; +end; + +procedure tdscontroller.dataevent(const event: tdataevent; info: ptrint); +var +// field1: tfield; + state1,state2: tdatasetstate; +begin + case event of + dedatasetscroll: begin + fmovebylock:= false; + dec(fscrollsum,info); + end; + dedatasetchange,deupdatestate: begin + frecnovalid:= false; + end; + defieldlistchange: begin + updatelinkedfields; + end; + decheckbrowsemode: begin + if (dso_canceloncheckbrowsemode in foptions) and + ([dscs_posting,dscs_canceling]*fstate = []) then begin + cancel; + end; + end; + end; + if not fmovebylock or (event <> dedatasetchange) then begin + with tdataset(fowner) do begin + if (event = deupdaterecord) and not modified and (state = dsinsert) then begin + idscontroller(fintf).inheriteddataevent(event,info); //for second notnull check + end; + end; + idscontroller(fintf).inheriteddataevent(event,info); + end; + state1:= tdataset(fowner).state; + if (state1 <> fstatebefore) then begin + state2:= fstatebefore; + fstatebefore:= state1; + if checkcanevent(fowner,tmethod(fonstatechanged)) then begin + fonstatechanged(tdataset(fowner),state2); + end; + end; +end; + +procedure tdscontroller.cancel; +var + bo1: boolean; +begin + try + include(fstate,dscs_canceling); + with tdataset1(fowner) do begin + bo1:= state = dsinsert; + if bo1 then begin + dobeforescroll; + end; + if fcancelresync and (state = dsinsert) and not modified then begin + idscontroller(fintf).inheritedcancel; + try + if finsertbm <> '' then begin + bookmark:= finsertbm; + end; + except + end; + finsertbm:= ''; + end + else begin + idscontroller(fintf).inheritedcancel; + end; + if bo1 then begin + doafterscroll; + end; + end; + finally + exclude(fstate,dscs_canceling); + end; +end; + +function tdscontroller.canceling: boolean; +begin + result:= dscs_canceling in fstate; +end; + +function tdscontroller.refreshing(): boolean; +begin + result:= dscs_refreshing in fstate; +end; + +function tdscontroller.deleting(): boolean; +begin + result:= dscs_deleting in fstate; +end; + +function tdscontroller.moveby(const distance: integer): integer; +begin + with tdataset1(fowner) do begin + if (abs(distance) = 1) and (state = dsinsert) and not modified then begin + checkbrowsemode; + end + else begin + if state = dsbrowse then begin + fmovebylock:= true; + end; + try + result:= idscontroller(fintf).inheritedmoveby(distance); + if fmovebylock then begin + fmovebylock:= false; + dataevent(dedatasetscroll,0); + end; + finally + fmovebylock:= false; + end; + end; + end; +end; + +procedure tdscontroller.internalinsert; +begin + finsertbm:= tdataset(fowner).bookmark; + idscontroller(fintf).inheritedinternalinsert; +end; + +procedure tdscontroller.internaldelete; +begin + idscontroller(fintf).inheritedinternaldelete; + modified; + tdataset1(fowner).dataevent(tdataevent(de_afterdelete),0); +end; + +procedure tdscontroller.internalopen; +var + int1,int2: integer; + bo1: boolean; +// blobdatasize: integer; +begin +// blobdatasize:= fintf.getblobdatasize; + with tdataset(fowner) do begin + { + for int1:= 0 to fields.count - 1 do begin + with fields[int1] do begin + if datatype in blobfields then begin + size:= blobdatasize; + end; + end; + end; + } + for int1:= 0 to fielddefs.count - 1 do begin +{$warnings off} + with tfielddef1(fielddefs[int1]) do begin +{$warnings on} + if ffieldno = 0 then begin + ffieldno:= int1 + 1; + end; +// if fdatatype in blobfields then begin +// fsize:= blobdatasize; +// end; + end; + end; + updatelinkedfields; + bo1:= dso_waitcursor in foptions; + if bo1 then begin + application.beginwait; + end; + try +// if dso_local in foptions then begin +// idscontroller(fintf).openlocal; +// end +// else begin + idscontroller(fintf).inheritedinternalopen; +// end; + finally + if bo1 then begin + application.endwait; + end; + end; + for int1:= 0 to fields.count - 1 do begin + with fields[int1] do begin + int2:= fielddefs.indexof(fieldname); + if (int2 >= 0) and not checkfieldcompatibility(fields[int1], + fielddefs[int2].datatype) then begin + databaseerror('Datatype mismatch dataset '''+fowner.name+''' field '''+ + fieldname+''''+lineend+ + 'expected: '''+getenumname(typeinfo(tfieldtype), + ord(fielddefs[int2].datatype))+''' actual: '''+ + getenumname(typeinfo(tfieldtype),ord(datatype))+'''.'); + end; + end; + end; + updatelinkedfields; //second check + end; +{ + if fdelayedapplycount > 0 then begin + registeronidle; + end; +} +end; +{ +procedure tdscontroller.doonidle(var again: boolean); +begin + idscontroller(fintf).doidleapplyupdates; +end; +} +(* +procedure tdscontroller.registeronidle; +begin + if not(dscs_onidleregistered in fstate) then begin + application.registeronidle({$ifdef FPC}@{$endif}doonidle); + include(fstate,dscs_onidleregistered); + end; +end; + +procedure tdscontroller.unregisteronidle; +begin + if dscs_onidleregistered in fstate then begin + application.unregisteronidle({$ifdef FPC}@{$endif}doonidle); + exclude(fstate,dscs_onidleregistered); + end; +end; +*) +procedure tdscontroller.internalclose; +var + int1: integer; + field1: tfield; +begin +// unregisteronidle; + idscontroller(fintf).inheritedinternalclose; + with tdataset(fowner) do begin + for int1:= 0 to fields.count - 1 do begin + field1:= fields[int1]; + if field1 is tmseblobfield then begin + tmseblobfield(field1).clearcache; + end; + end; + end; +end; + +function tdscontroller.getcontroller: tdscontroller; +begin + result:= self; +end; + +function tdscontroller.assql(const avalue: boolean): msestring; +begin + if idscontroller(fintf).getnumboolean then begin + if avalue then begin + result:= '1'; + end + else begin + result:= '0'; + end; + end + else begin + result:= encodesqlboolean(avalue); + end; +end; + +function tdscontroller.assql(const avalue: msestring): msestring; +begin + if avalue = '' then begin + result:= 'NULL'; + end + else begin +// if dso_utf8 in foptions then begin +// result:= encodesqlstring(stringtoutf8ansi(avalue)); +// end +// else begin + result:= encodesqlstring(avalue); +// end; + end; +end; + +function tdscontroller.assql(const avalue: integer): msestring; +begin + result:= inttostrmse(avalue); +end; + +function tdscontroller.assql(const avalue: int64): msestring; +begin + result:= inttostrmse(avalue); +end; + +function tdscontroller.assql(const avalue: realty): msestring; +begin + if avalue = emptyreal then begin + result:= 'NULL'; + end + else begin + result:= realtostrmse(avalue); + end; +end; + +function tdscontroller.assqlcurrency(const avalue: realty): msestring; +begin + if avalue = emptyreal then begin + result:= 'NULL'; + end + else begin + {$ifdef FPC} + result:= assql(currency(avalue)); + {$else} + if idscontroller(fintf).getint64currency then begin + result:= inttostr(int64(ar8ty(currency(avalue)))); + end + else begin + result:= encodesqlcurrency(avalue); + end; + {$endif} + end; +end; + +function tdscontroller.assql(const avalue: currency): msestring; +begin + if idscontroller(fintf).getint64currency then begin + {$ifdef FPC} + result:= inttostrmse(int64(avalue)); + {$else} + result:= inttostrmse(int64(ar8ty(avalue))); + {$endif} + end + else begin + result:= encodesqlcurrency(avalue); + end; +end; + +function tdscontroller.assql(const avalue: tdatetime): msestring; +begin + if avalue = emptydatetime then begin + result:= 'NULL'; + end + else begin + if idscontroller(fintf).getfloatdate then begin + result:= encodesqlfloat(avalue); + end + else begin + result:= encodesqldatetime(avalue); + end; + end; +end; + +function tdscontroller.assqldate(const avalue: tdatetime): msestring; +begin + if avalue = emptydatetime then begin + result:= 'NULL'; + end + else begin + if idscontroller(fintf).getfloatdate then begin + result:= inttostrmse(trunc(avalue)); + end + else begin + result:= encodesqldate(avalue); + end; + end; +end; + +function tdscontroller.assqltime(const avalue: tdatetime): msestring; +begin + if avalue = emptydatetime then begin + result:= 'NULL'; + end + else begin + if idscontroller(fintf).getfloatdate then begin + result:= encodesqlfloat(frac(avalue)); + end + else begin + result:= encodesqltime(avalue); + end; + end; +end; + +procedure tdscontroller.closequery(var amodalresult: modalresultty); +begin + try + with tdataset(fowner) do begin; + if state in dseditmodes then begin + checkbrowsemode; + end; + end; + except + amodalresult:= mr_exception; + application.handleexception(nil); + end; +end; + +function tdscontroller.closequery: boolean; //true if ok +var + modres1: modalresultty; +begin + modres1:= mr_canclose; + closequery(modres1); + result:= modres1 = mr_canclose; +end; + +function tdscontroller.execoperation(const akind: opkindty; + const aafterop: afterdbopeventty): boolean; +var + bo1,bo2,b3: boolean; + int1: integer; + savepointoptions: savepointoptionsty; +begin +// bo3:= dscs_posting1 in fstate; + if not (dscs_posting1 in fstate) then begin + include(fstate,dscs_posting1); + b3:= dscs_deleting in fstate; + if akind = opk_delete then begin + include(fstate,dscs_deleting); + end; + try + case akind of + opk_post: begin + if checkcanevent(tdataset(fowner),tmethod(self.fonbeforepost)) then begin + fonbeforepost(tdataset(fowner)); + end; + end; + opk_delete: begin + if checkcanevent(tdataset(fowner),tmethod(self.fonbeforedelete)) then begin + fonbeforedelete(tdataset(fowner)); + end; + end; + end; + try + savepointoptions:= idscontroller(fintf).getsavepointoptions; + case akind of + opk_post: begin + bo1:= spo_postsavepoint in savepointoptions; + end; + opk_delete: begin + bo1:= spo_deletesavepoint in savepointoptions; + end; + else begin + bo1:= false; + end; + end; + try + if bo1 then begin + int1:= savepointbegin; + end; + result:= true; + include(fstate,dscs_posting); + try + try + case akind of + opk_post: begin + idscontroller(fintf).inheritedpost(); + end; + opk_delete: begin + idscontroller(fintf).inheriteddelete(); + end; + opk_insert: begin + idscontroller(fintf).inheritedinsert(); + end; + end; + except + on epostcancel do begin + if bo1 then begin + bo1:= false; + savepointrollback(int1); + end; + result:= false; + tdataset(fowner).cancel; + end + else begin + if bo1 then begin + bo1:= false; + savepointrollback(int1); + end; + raise; + end; + end; + finally + exclude(fstate,dscs_posting); + end; + bo2:= result; + try + if result and assigned(aafterop) then begin + aafterop(tdataset(fowner),result); + end; + if result then begin + if akind = opk_post then begin + tdataset1(fowner).dataevent(tdataevent(de_afterpost),0); + end; + end; + finally + if bo2 then begin + self.modified; + end; + end; + if bo1 then begin + bo1:= false; + if result then begin + savepointrelease; + end + else begin + savepointrollback(int1); + end; + end; + except + if bo1 then begin + savepointrollback(int1); + end; + raise; + end; + finally + case akind of + opk_post: begin + if checkcanevent(tdataset(fowner),tmethod(self.fonafterpost)) then begin + fonafterpost(tdataset(fowner),result); + end; + end; + opk_delete: begin + if checkcanevent(tdataset(fowner),tmethod(self.fonafterdelete)) then begin + fonafterdelete(tdataset(fowner),result); + end; + end; + end; + end; + finally + if not b3 then begin + exclude(fstate,dscs_deleting); + end; + exclude(fstate,dscs_posting1); + end; + end; +end; + +procedure tdscontroller.readdelayedapplycount(reader: treader); +var + i1: int32; +begin + i1:= reader.readinteger(); + if fowner is tmsebufdataset then begin + tmsebufdataset(fowner).delayedapplycount:= i1; + end; +end; + +procedure tdscontroller.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('delayedapplycount',@readdelayedapplycount,nil,false); +end; + +function tdscontroller.post(const aafterpost: afterdbopeventty = nil): boolean; +begin + with tdataset(fowner) do begin + if state in dseditmodes then begin + result:= execoperation(opk_post,aafterpost); + end + else begin + result:= false; + end; + end; +end; +{ +procedure tdscontroller.insert(const aafterinsert: afterdbopeventty = nil); +begin + execoperation(opk_insert,aafterinsert); +end; +} +function tdscontroller.delete( + const aafterdelete: afterdbopeventty = nil): boolean; +begin + if tdataset(fowner).state = dsinsert then begin + cancel(); + result:= true; + end + else begin + result:= execoperation(opk_delete,aafterdelete); + end; +end; + +procedure tdscontroller.postcancel; +begin + raise epostcancel.create('Post canceled'); +end; + +function tdscontroller.emptyinsert: boolean; +begin + result:= false; + if not posting then begin + with tdataset1(fowner) do begin + if state = dsinsert then begin + DataEvent(deUpdateRecord,0); + result:= not modified; + end; + end; + end; +end; + +function tdscontroller.posting: boolean; +begin + result:= dscs_posting in fstate; +end; + +function tdscontroller.posting1: boolean; +begin + result:= dscs_posting1 in fstate; +end; + +procedure tdscontroller.modified; +begin + tdataset1(fowner).dataevent(tdataevent(de_modified),0); +end; + +procedure tdscontroller.setoptions(const avalue: datasetoptionsty); +{$ifndef FPC} +const + mask1: datasetoptionsty = [dso_autocommitret,dso_autocommit]; + mask2: datasetoptionsty = [dso_editonapplyerror,dso_cancelupdatesonerror, + dso_cancelupdateonerror,dso_cancelupdateondeleteerror]; +{$endif} +var + opt,options1{,optionsbefore}: datasetoptionsty; + bdopt: bufdatasetoptionsty; +begin + if (csreading in fowner.componentstate) and + (fowner is tmsebufdataset) then begin + with tmsebufdataset1(fowner) do begin + if card32(foldopts) <> card32($ffffffff) then begin //old streaming version + bdopt:= []; + if dso_postsavepoint in avalue then include(bdopt,bdo_postsavepoint); + if dso_postsavepoint in avalue then include(bdopt,bdo_postsavepoint); + if dso_deletesavepoint in avalue then include(bdopt,bdo_deletesavepoint); + if dso_cancelupdateonerror in avalue then include(bdopt,bdo_cancelupdateonerror); + if dso_cancelupdatesonerror in avalue then include(bdopt,bdo_cancelupdatesonerror); + if dso_cancelupdateondeleteerror in avalue then include(bdopt,bdo_cancelupdateondeleteerror); + if dso_editonapplyerror in avalue then include(bdopt,bdo_editonapplyerror); + if dso_restoreupdateonsavepointrollback in avalue then include(bdopt,bdo_restoreupdateonsavepointrollback); + if dso_noapply in avalue then include(bdopt,bdo_noapply); + if dso_autoapply in avalue then include(bdopt,bdo_autoapply); + if dso_autocommitret in avalue then include(bdopt,bdo_autocommitret); + if dso_autocommit in avalue then include(bdopt,bdo_autocommit); + if dso_refreshafterapply in avalue then include(bdopt,bdo_refreshafterapply); + if dso_recnoapplyrefresh in avalue then include(bdopt,bdo_recnoapplyrefresh); + if dso_refreshtransaction in avalue then include(bdopt,bdo_refreshtransaction); + if dso_notransactionrefresh in avalue then include(bdopt,bdo_notransactionrefresh); + if dso_recnotransactionrefresh in avalue then include(bdopt,bdo_recnotransactionrefresh); + if dso_noprepare in avalue then include(bdopt,bdo_noprepare); + if dso_cacheblobs in avalue then include(bdopt,bdo_cacheblobs); + if dso_offline in avalue then include(bdopt,bdo_offline); + if dso_local in avalue then include(bdopt,bdo_local); + foldopts:= bdopt; + end; + end; + end; +// optionsbefore:= foptions; + opt:= avalue; + if dso_refreshwaitcursor in avalue then begin + include(opt,dso_waitcursor); + end; + opt:= opt - [dso_refreshwaitcursor]-deprecatedbdsoptions; + options1:= datasetoptionsty(longword(foptions) xor longword(opt)); + foptions:= opt; +(* +{$ifdef FPC} + foptions:= datasetoptionsty(setsinglebit(longword(opt),longword(foptions), + [longword([dso_autocommitret,dso_autocommit]), + longword([dso_editonapplyerror,dso_cancelupdatesonerror, + dso_cancelupdateonerror,dso_cancelupdateondeleteerror])])); +{$else} + foptions:= datasetoptionsty(setsinglebitar32(longword(opt),longword(foptions), + [longword(mask1),longword(mask2)])); +{$endif} +*) + if [dso_noedit,dso_noinsert,dso_noappend,dso_noupdate,dso_nodelete] * + options1 <> [] then begin + if ([dso_noedit,dso_noupdate] * opt <> []) and + tdataset(fowner).active then begin + tdataset(fowner).checkbrowsemode; + end; + tdataset1(fowner).dataevent(dedisabledstatechange,0); + end; +{ + if optionsbefore <> foptions then begin + idscontroller(fintf).dscontrolleroptionschanged(foptions); + end; +} +end; + +function tdscontroller.isutf8: boolean; +begin + result:= dso_utf8 in foptions; +end; + +function tdscontroller.filtereditkind: filtereditkindty; +begin + result:= idscontroller(fintf).getfiltereditkind; +end; + +procedure tdscontroller.beginupdate; //calls diablecontrols, stores bookmark +begin + with tdataset(fowner) do begin + if fupdatecount = 0 then begin + fbmbackup:= bookmark; + end; + inc(fupdatecount); + disablecontrols; + end; +end; + +procedure tdscontroller.endupdate; //restores bookmark, calls enablecontrols +begin + with tdataset(fowner) do begin + dec(fupdatecount); + if fupdatecount = 0 then begin + bookmark:= fbmbackup; + end; + enablecontrols; + end; +end; + +procedure tdscontroller.beginfilteredit(const akind: filtereditkindty); +begin + idscontroller(fintf).beginfilteredit(akind); +end; + +procedure tdscontroller.clearfilter; +begin + idscontroller(fintf).clearfilter; +end; + +procedure tdscontroller.endfilteredit; +begin + idscontroller(fintf).endfilteredit; +end; + +function tdscontroller.getfieldar( + const afieldkinds: tfieldkinds = allfieldkinds): fieldarty; +var + int1,int2: integer; +begin + with tdataset(fowner).fields do begin + setlength(result,count); + int2:= 0; + for int1:= 0 to high(result) do begin + result[int2]:= fields[int1]; + if result[int2].fieldkind in afieldkinds then begin + inc(int2); + end; + end; + setlength(result,int2); + end; +end; +{ +procedure tdscontroller.setdelayedapplycount(const avalue: integer); +begin + if fdelayedapplycount <> avalue then begin + if tdataset(fowner).active and not (csloading in fowner.componentstate) then begin + if fdelayedapplycount > 0 then begin + fdelayedapplycount:= 1; + idscontroller(fintf).doidleapplyupdates; //apply pending updates. + end; + fdelayedapplycount:= avalue; + if avalue > 0 then begin + registeronidle; + end + else begin + unregisteronidle; + end; + end + else begin + fdelayedapplycount:= avalue; + end; + end; +end; +} +function tdscontroller.getnoedit: boolean; +begin + result:= dso_noedit in foptions; +end; + +procedure tdscontroller.setnoedit(const avalue: boolean); +begin + if avalue then begin + options:= options + [dso_noedit]; + end + else begin + options:= options - [dso_noedit]; + end; +end; + +function tdscontroller.getnoinsert: boolean; +begin + result:= dso_noinsert in foptions; +end; + +procedure tdscontroller.setnoinsert(const avalue: boolean); +begin + if avalue then begin + options:= options + [dso_noinsert]; + end + else begin + options:= options - [dso_noinsert]; + end; +end; + +function tdscontroller.getnoappend: boolean; +begin + result:= dso_noappend in foptions; +end; + +procedure tdscontroller.setnoappend(const avalue: boolean); +begin + if avalue then begin + options:= options + [dso_noappend]; + end + else begin + options:= options - [dso_noappend]; + end; +end; + +function tdscontroller.getnoupdate: boolean; +begin + result:= dso_noupdate in foptions; +end; + +procedure tdscontroller.setnoupdate(const avalue: boolean); +begin + if avalue then begin + options:= options + [dso_noupdate]; + end + else begin + options:= options - [dso_noupdate]; + end; +end; + +function tdscontroller.getnodelete: boolean; +begin + result:= dso_nodelete in foptions; +end; + +procedure tdscontroller.setnodelete(const avalue: boolean); +begin + if avalue then begin + options:= options + [dso_nodelete]; + end + else begin + options:= options - [dso_nodelete]; + end; +end; + +function tdscontroller.getcanmodify: boolean; +begin + result:= not (dso_noedit in foptions); +end; + +procedure tdscontroller.dorefresh(const sender: tobject); +var + bo1,bo2,bo3: boolean; +begin + if (sender = nil) or //not delayed + (tdataset(fowner).state = dsbrowse) then begin + bo2:= dso_waitcursor in foptions; + bo3:= dscs_refreshing in fstate; + if bo2 then begin + application.beginwait; + end; + try + if not tdataset(fowner).active then begin + tdataset(fowner).open; + end + else begin + if dscs_restorerecno in fstate then begin + exclude(fstate,dscs_restorerecno); + bo1:= idscontroller(fintf).restorerecno; + idscontroller(fintf).restorerecno:= true; + try + tdataset(fowner).refresh; + finally + if not bo1 then begin + idscontroller(fintf).restorerecno:= false; + end; + end; + end + else begin + tdataset(fowner).refresh; + end; + end; + finally + if bo2 then begin + application.endwait; + end; + if not bo3 then begin + exclude(fstate,dscs_refreshing); + end; + end; + end; +end; + +procedure tdscontroller.refresh(const restorerecno: boolean; + const delayus: integer = -1); +begin + if restorerecno then begin + include(fstate,dscs_restorerecno); + end; + if delayus < 0 then begin + freeandnil(ftimer); + dorefresh(nil); + end + else begin + if ftimer = nil then begin + ftimer:= tsimpletimer.create(delayus,{$ifdef FPC}@{$endif}dorefresh, + true,[to_single]); + end + else begin + ftimer.interval:= delayus; //single shot + ftimer.enabled:= true; + end; + end; +end; + +procedure tdscontroller.checkrefresh; //makes pending delayed refresh +begin + if ftimer <> nil then begin + ftimer.firependingandstop; //cancel wait + end; +end; + +function tdscontroller.islastrecord: boolean; +begin + with tdataset1(fowner) do begin + result:= eof; + if not result then begin + if filtered then begin + settempstate(state); + try + next; + result:= eof; + if not result then begin + prior; + end; + finally + restorestate(state); + end; + end + else begin + result:= idscontroller(fintf).islastrecord; + end; + end; + end; +end; + +procedure tdscontroller.nosavepoint; +begin + raise exception.create('Savepoints not supported.'); +end; + +function tdscontroller.savepointbegin: integer; +begin + result:= -1; + nosavepoint; +end; + +procedure tdscontroller.savepointrollback(const aindex: integer); +begin + nosavepoint; +end; + +procedure tdscontroller.savepointrelease; +begin + nosavepoint; +end; + +function tdscontroller.updatesortfield(const alink: tfielddatalink; + const adescend: boolean): boolean; +var + field1: tfield; +begin + field1:= nil; + if alink <> nil then begin + field1:= alink.sortfield; + end; + result:= idscontroller(fintf).updatesortfield(field1,adescend); +end; + +function tdscontroller.getasmsestring(const afieldname: string): msestring; +var + field1: tfield; +begin + field1:= tdataset(fowner).fieldbyname(afieldname); + if field1 is tmsestringfield then begin + result:= tmsestringfield(field1).asmsestring; + end + else begin + if field1 is tmsememofield then begin + result:= tmsememofield(field1).asmsestring; + end + else begin + if isutf8 then begin + result:= utf8tostringansi(field1.asstring); + end + else begin + result:= msestring(field1.asstring); + end; + end; + end; +end; + +procedure tdscontroller.setasmsestring(const afieldname: string; + const avalue: msestring); +var + field1: tfield; +begin + field1:= tdataset(fowner).fieldbyname(afieldname); + if field1 is tmsestringfield then begin + tmsestringfield(field1).asmsestring:= avalue; + end + else begin + if field1 is tmsememofield then begin + tmsememofield(field1).asmsestring:= avalue; + end + else begin + if isutf8 then begin + field1.asstring:= stringtoutf8ansi(avalue); + end + else begin + field1.asstring:= ansistring(avalue); + end; + end; + end; +end; + +procedure tdscontroller.begindisplaydata; +begin + idscontroller(fintf).begindisplaydata; +end; + +procedure tdscontroller.enddisplaydata; +begin + idscontroller(fintf).enddisplaydata; +end; + +procedure tdscontroller.copyrecord(const aappend: boolean = false); +var + ar1: variantarty; + ar2: booleanarty; + field1: tfield; +// intf1: imsefield; + int1: integer; + bo1: boolean; +begin + if checkcanevent(tdataset(fowner),tmethod(fonbeforecopyrecord)) then begin + fonbeforecopyrecord(tdataset(fowner)); + end; + with tdataset1(fowner) do begin + include(finternalstate,dsis_recordcopy); + try + setlength(ar1,fields.count); + setlength(ar2,length(ar1)); + for int1:= 0 to high(ar1) do begin + field1:= fields[int1]; + bo1:= (field1.fieldkind in [fkdata,fkinternalcalc]) and + not (of_nocopyrecord in field1.optionsfield); + if bo1 then begin + ar2[int1]:= true; + ar1[int1]:= field1.value; + end; + end; + if aappend then begin + append; + end + else begin + insert; + end; + for int1:= 0 to high(ar1) do begin + if ar2[int1] and not varisnull(ar1[int1]) then begin + field1:= fields[int1]; + if field1.isnull or (of_initcopy in field1.optionsfield) then begin + field1.value:= ar1[int1]; + end; + end; + end; + finally + exclude(finternalstate,dsis_recordcopy); + end; + end; + if checkcanevent(tdataset(fowner),tmethod(fonaftercopyrecord)) then begin + fonaftercopyrecord(tdataset(fowner)); + end; +end; + +function tdscontroller.copying(): boolean; +begin + result:= dsis_recordcopy in tdataset1(fowner).finternalstate; +end; + +{ tfieldlinkdatalink } + +constructor tfieldlinkdatalink.create(const aowner: tfieldlink); +begin + fowner:= aowner; + inherited create; + fdatasource:= tdatasource.create(nil); + datasource:= fdatasource; +end; + +destructor tfieldlinkdatalink.destroy; +begin + fdatasource.free; + inherited; +end; + +procedure tfieldlinkdatalink.updatedata; +begin + if field <> nil then begin + if not (flo_disabled in fowner.options) and + (not (flo_onlyifnull in fowner.foptions) or (field.isnull)) and + (not (flo_notifunmodifiedinsert in fowner.foptions) or + (datasource.dataset.modified)) then begin + fowner.updatedata(field); + end; + end; +end; + +{ tfieldlink } + +constructor tfieldlink.create(aowner: tcomponent); +begin + inherited; + fdestdatalink:= tfieldlinkdatalink.create(self); +end; + +destructor tfieldlink.destroy; +begin + fdestdatalink.free; + inherited; +end; + +procedure tfieldlink.setdestdataset(const avalue: tdataset); +begin + fdestdatalink.fdatasource.dataset:= avalue; +end; + +function tfieldlink.getdestdataset: tdataset; +begin + result:= fdestdatalink.dataset; +end; + +function tfieldlink.getdestdatafield: string; +begin + result:= fdestdatalink.fieldname; +end; + +procedure tfieldlink.setdestdatafield(const avalue: string); +begin + fdestdatalink.fieldname:= avalue; +end; + +function tfieldlink.field: tfield; +begin + result:= fdestdatalink.field; +end; + +procedure tfieldlink.getfieldtypes(out propertynames: stringarty; + out fieldtypes: fieldtypesarty); +begin + propertynames:= nil; + fieldtypes:= nil; +end; + +function tfieldlink.getdataset(const aindex: integer): tdataset; +begin + result:= fdestdatalink.dataset; +end; + +procedure tfieldlink.updatedata(const afield: tfield); +begin + if not (flo_disabled in foptions) and + canevent(tmethod(fonupdatedata)) then begin + fonupdatedata(afield); + end; +end; + +function tfieldlink.getenabled: boolean; +begin + result:= not (flo_disabled in foptions); +end; + +procedure tfieldlink.setenabled(const avalue: boolean); +begin + if avalue then begin + exclude(foptions,flo_disabled); + end + else begin + include(foptions,flo_disabled); + end; +end; + +{ tfieldfieldlink } + +constructor tfieldfieldlink.create(aowner: tcomponent); +begin + inherited; + fsourcedatalink:= tfielddatalink.create; +end; + +destructor tfieldfieldlink.destroy; +begin + fsourcedatalink.free; + inherited; +end; + +function tfieldfieldlink.getfieldname: string; +begin + result:= fsourcedatalink.fieldname; +end; + +procedure tfieldfieldlink.setfieldname(const avalue: string); +begin + fsourcedatalink.fieldname:= avalue; +end; + +function tfieldfieldlink.getdatasource: tdatasource; +begin + result:= fsourcedatalink.datasource; +end; + +function tfieldfieldlink.getdatasource1(const aindex: integer): tdatasource; +begin + if aindex = 0 then begin + result:= fsourcedatalink.datasource; + end + else begin + result:= fdestdatalink.datasource; + end; +end; + +procedure tfieldfieldlink.setdatasource(const avalue: tdatasource); +begin + fsourcedatalink.datasource:= avalue; +end; + +function tfieldfieldlink.sourcefield: tfield; +begin + result:= fsourcedatalink.field; +end; + +procedure tfieldfieldlink.getfieldtypes(out propertynames: stringarty; + out fieldtypes: fieldtypesarty); +begin + setlength(propertynames,2); + propertynames[0]:= 'fieldname'; + propertynames[1]:= 'destdatafield'; + setlength(fieldtypes,2); + fieldtypes[0]:= []; + fieldtypes[1]:= []; +end; + +function tfieldfieldlink.getdataset(const aindex: integer): tdataset; +begin + result:= nil; + case aindex of + 0: begin + result:= fsourcedatalink.dataset; + end; + 1: begin + result:= fdestdatalink.dataset; + end; + end; +end; + +procedure tfieldfieldlink.updatedata(const afield: tfield); +begin + if not (flo_disabled in foptions) and + (fsourcedatalink.field <> nil) then begin + field.value:= fsourcedatalink.field.value; + end; + inherited; +end; + +procedure tfieldfieldlink.readdatafield(reader: treader); +begin + fieldname:= reader.readstring; +end; + +procedure tfieldfieldlink.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('datafield',{$ifdef FPC}@{$endif}readdatafield,nil,false); +end; + +{ ttimestampfieldlink } + +procedure ttimestampfieldlink.updatedata(const afield: tfield); +begin + if flo_utc in foptions then begin + afield.asdatetime:= nowutc; + end + else begin + afield.asdatetime:= nowlocal; + end; + inherited; +end; + +{ tmseparams } + +constructor tmseparams.create(aowner: tpersistent); +begin + inherited create(aowner); +{$warnings off} + tcollection1(self).fitemclass:= tmseparam; +{$warnings on} +end; + +constructor tmseparams.create; +begin + create(tpersistent(nil)); +end; + +function tmseparams.parsesql(const sql: msestring; + const docreate,EscapeSlash,EscapeRepeat: boolean; + const parameterstyle: tparamstyle; + var parambinding: tparambinding; + var replacestring: msestring): msestring; + +type + // used for ParamPart + TStringPart = record + Start,Stop:integer; + end; + +const + ParamAllocStepSize = 8; + +var + IgnorePart:boolean; + p,ParamNameStart,BufStart: PmseChar; + ParamName: msestring; + QuestionMarkParamCount,ParameterIndex,NewLength:integer; + ParamCount:integer; // actual number of parameters encountered so far; + // always <= Length(ParamPart) = Length(Parambinding) + // Parambinding will have length ParamCount in the end + ParamPart:array of TStringPart; // describe which parts of buf are parameters +// NewQueryLength:integer; + NewQuery: msestring; + NewQueryIndex,BufIndex,CopyLen,i:integer; // Parambinding will have length ParamCount in the end + b:integer; + tmpParam:TParam; + +begin +// if DoCreate then Clear; //2006-11-23 mse + + // Parse the SQL and build ParamBinding + ParamCount:=0; + paramname:= ''; + paramnamestart:= nil; +// NewQueryLength:=Length(SQL); + SetLength(ParamPart,ParamAllocStepSize); + SetLength(Parambinding,ParamAllocStepSize); + QuestionMarkParamCount:=0; // number of ? params found in query so far + + ReplaceString := '$'; + if ParameterStyle = psSimulated then + while pos(ReplaceString,SQL) > 0 do ReplaceString := ReplaceString+'$'; + + p:= PmseChar(SQL); + BufStart:=p; // used to calculate ParamPart.Start values + repeat + case p^ of + '''': // single quote delimited string + begin + Inc(p); + while not ((p^ = #0) or (p^ = '''')) do + begin + if p^='\' then Inc(p,2) // make sure we handle \' and \\ correct + else Inc(p); + end; + if p^='''' then Inc(p); // skip final ' + end; + '"': // double quote delimited string + begin + Inc(p); + while not ((p^ = #0) or (p^ = '"')) do + begin + if p^='\' then Inc(p,2) // make sure we handle \" and \\ correct + else Inc(p); + end; + if p^='"' then Inc(p); // skip final " + end; + '-': // possible start of -- comment + begin + Inc(p); + if p^='-' then // -- comment + begin + repeat // skip until at end of line + Inc(p); + until (p^ = #10) or (p^ = #0); + end + end; + '/': // possible start of /* */ comment + begin + Inc(p); + if p^='*' then // /* */ comment + begin + repeat + Inc(p); + if p^='*' then // possible end of comment + begin + Inc(p); + if p^='/' then Break; // end of comment + end; + until p^=#0; + if p^='/' then Inc(p); // skip final / + end; + end; + ':','?': // parameter + begin + IgnorePart := False; + if p^=':' then + begin // find parameter name + Inc(p); + if p^=':' then // ignore ::, since some databases uses this as a cast (wb 4813) + begin + IgnorePart := True; + Inc(p); + end + else + begin + ParamNameStart:=p; + while (p^ > #127) or + not (char(byte(p^)) in (SQLDelimiterCharacters + + [#0,'=','+','-','*','\','[',']'])) do + Inc(p); + ParamName:=Copy(ParamNameStart,1,p-ParamNameStart); + end; + end + else + begin + Inc(p); + ParamNameStart:=p; + ParamName:=''; + end; + + if not IgnorePart then + begin + Inc(ParamCount); + if ParamCount>Length(ParamPart) then + begin + NewLength:=Length(ParamPart)+ParamAllocStepSize; + SetLength(ParamPart,NewLength); + SetLength(ParamBinding,NewLength); + end; + + if DoCreate then + begin + // Check if this is the first occurance of the parameter + tmpParam := FindParam(ansistring(ParamName)); + // If so, create the parameter and assign the Parameterindex + if not assigned(tmpParam) then + ParameterIndex := CreateParam(ftUnknown, + ansistring(ParamName), ptInput).Index + else // else only assign the ParameterIndex + ParameterIndex := tmpParam.Index; + end + // else find ParameterIndex + else + begin + if ParamName<>'' then + ParameterIndex:=ParamByName(ansistring(ParamName)).Index + else + begin + ParameterIndex:=QuestionMarkParamCount; + Inc(QuestionMarkParamCount); + end; + end; + { + if ParameterStyle in [psPostgreSQL,psSimulated] then + begin + if ParameterIndex > 8 then + inc(NewQueryLength,2) + else + inc(NewQueryLength,1) + end; + } + // store ParameterIndex in FParamIndex, ParamPart data + ParamBinding[ParamCount-1]:=ParameterIndex; + ParamPart[ParamCount-1].Start:=ParamNameStart-BufStart; + ParamPart[ParamCount-1].Stop:=p-BufStart+1; + + // update NewQueryLength +// Dec(NewQueryLength,p-ParamNameStart); + end; + end; + #0:Break; + else + Inc(p); + end; + until false; + + SetLength(ParamPart,ParamCount); + SetLength(ParamBinding,ParamCount); + + if ParamCount>0 then begin + //replace :ParamName by '?' for interbase, + //by '$x ' for postgresql and psSimulated + //(using ParamPart array and NewQueryLength) + SetLength(NewQuery,length(sql)+paramcount*(length(ReplaceString)+8)); + //reserve '$1234567 ' + NewQueryIndex:=1; + BufIndex:=1; + for i:=0 to High(ParamPart) do begin + CopyLen:=ParamPart[i].Start-BufIndex; + Move(SQL[BufIndex],NewQuery[NewQueryIndex],CopyLen*sizeof(msechar)); + Inc(NewQueryIndex,CopyLen); + case ParameterStyle of + psInterbase : NewQuery[NewQueryIndex]:='?'; + psPostgreSQL, + psSimulated : begin + ParamName:= IntToStrmse(ParamBinding[i]+1); + for b:= 1 to length(ReplaceString) do begin + NewQuery[NewQueryIndex]:='$'; + Inc(NewQueryIndex); + end; + for b:= 1 to length(paramname) do begin + NewQuery[NewQueryIndex]:= paramname[b]; + Inc(NewQueryIndex); + end; + newquery[newqueryindex]:= ' '; + end; + end; + Inc(NewQueryIndex); + BufIndex:=ParamPart[i].Stop; + end; + CopyLen:=Length(SQL)+1-BufIndex; + Move(SQL[BufIndex],NewQuery[NewQueryIndex],CopyLen*sizeof(msechar)); + setlength(newquery,newqueryindex+copylen-1); + end + else begin + NewQuery:=SQL; + end; + Result:= NewQuery; +end; + +function tmseparams.parsesql(const sql: msestring; + const docreate,EscapeSlash,EscapeRepeat: boolean; + const parameterstyle : tparamstyle; var parambinding: tparambinding): msestring; +var + rs: msestring; +begin + result := parsesql(sql,docreate,escapeslash,escaperepeat,parameterstyle, + parambinding,rs); +end; + +function tmseparams.parsesql(const sql: msestring; + const docreate,EscapeSlash,EscapeRepeat: boolean; + const parameterstyle: tparamstyle): msestring; +var + pb: tparambinding; + rs: msestring; +begin + result:= parsesql(sql,docreate,escapeslash,escaperepeat,parameterstyle,pb,rs); +end; + +function tmseparams.parsesql(const sql: msestring; const docreate: boolean): msestring; +var + pb: TParamBinding; + rs: msestring; +begin + result:= parsesql(sql,docreate,false,false,psinterbase,pb,rs); +end; + +function tmseparams.expandvalues(sql: msestring; + const aparambindings: tparambinding; + const aparamreplacestring: msestring): msestring; +var + int1,int2,int3,int4: integer; + po1: pmsechar; +begin + if high(aparambindings) >= 0 then begin + int3:= 1; + result:= ''; + uniquestring(sql); + po1:= pmsechar(sql)-1; + for int1:= 0 to high(aparambindings) do begin + int2:= pos(aparamreplacestring,sql); + for int4:= int2 to int2+length(aparamreplacestring)-1 do begin + (po1+int4)^:= ' '; //remove marker + end; + result:= result + copy(sql,int3,int2-int3) + + paramtosql(items[aparambindings[int1]]); + int3:= int2 + length(aparamreplacestring); + while (sql[int3] >= '0') and (sql[int3] <= '9') do begin + inc(int3); + end; + end; + result:= result + copy(sql,int3,bigint); //tail + end + else begin + result:= sql; + end; +end; + +function tmseparams.expandvalues(const sql: msestring): msestring; +var + pb: tparambinding; + str1,str2: msestring; +begin + str2:= parsesql(sql,false,false,false,pssimulated,pb,str1); + result:= expandvalues(str2,pb,str1); +end; + +function tmseparams.asdbstring(const index: integer): string; +begin + with items[index] do begin + if not (datatype in [ftblob,ftmemo,ftbytes,ftvarbytes]) and isutf8 then begin + if vartype(value) = varolestr then begin + result:= stringtoutf8ansi(aswidestring); + end + else begin + result:= stringtoutf8ansi(msestring(asstring)); + end; + end + else begin + result:= asstring; + end; + end; +end; + +function tmseparams.getitem(const index: integer): tmseparam; +begin + result:= tmseparam(inherited items[index]); +end; + +procedure tmseparams.setitem(const index: integer; const avalue: tmseparam); +begin + inherited items[index]:= avalue; +end; + +function tmseparams.bindnames(const anames: msestringarty): integerarty; +var + mstr1: msestring; + int1,int2: integer; +begin + setlength(result,count); + for int1:= high(result) downto 0 do begin + result[int1]:= -1; + mstr1:= msestring(items[int1].name); + for int2:= high(anames) downto 0 do begin + if anames[int2] = mstr1 then begin + result[int1]:= int2; + break; + end; + end; + end; +end; + +function tmseparams.getvalues: variantarty; +var + int1: integer; +begin + setlength(result,count); + for int1:= high(result) downto 0 do begin + result[int1]:= items[int1].value; + end; +end; + +procedure tmseparams.setvalues(const avalue: variantarty); +var + int1: integer; +begin + for int1:= high(avalue) downto 0 do begin + items[int1].value:= avalue[int1]; + end; +end; + +procedure tmseparams.updatevalues; +var + int1: integer; +begin + for int1:= 0 to count-1 do begin + with tmseparam(items[int1]) do begin + if fdatalink.field <> nil then begin + if pos('OLD_',name) = 1 then begin + value:= fdatalink.field.oldvalue; + end + else begin + value:= fdatalink.field.value; + end; + end; + end; + end; +end; + +{ tblobcachenode } + +constructor tblobcachenode.create(const akey: blobidty; const adata: string); +begin + flocal:= akey.local; + inherited create(akey.id,adata); +end; + +{ tblobcache } + +function compareblobid(const left,right: tavlnode): integer; +var + lint1: int64; +begin + result:= integer(tblobcachenode(left).flocal) - + integer(tblobcachenode(right).flocal); + if result = 0 then begin + lint1:= tblobcachenode(left).fkey - tblobcachenode(right).fkey; + if lint1 > 0 then begin + result:= 1; + end + else begin + if lint1 < 0 then begin + result:= -1; + end; + end; + end; +end; + +constructor tblobcache.create; +begin + ffindnode:= tblobcachenode.create; + inherited; + fcompare:= {$ifdef FPC}@{$endif}compareblobid; +end; + +destructor tblobcache.destroy; +begin + inherited; + ffindnode.free; +end; + +function tblobcache.addnode(const akey: blobidty; + const adata: string): tblobcachenode; +begin + result:= tblobcachenode.create(akey,adata); + addnode(result); +end; + +function tblobcache.find(const akey: blobidty; + out anode: tblobcachenode): boolean; +begin + ffindnode.fkey:= akey.id; + ffindnode.flocal:= akey.local; + result:= find(ffindnode,tavlnode(anode)); +end; + +{ tmseparam } + +constructor tmseparam.Create(ACollection: TCollection); +begin + fdatalink:= tfielddatalink.create; + inherited; +end; + +destructor tmseparam.destroy; +begin + connector:= nil; + fdatalink.free; + inherited; +end; + +procedure tmseparam.setconnector(const avalue: tparamconnector); +begin + if fconnector <> avalue then begin + if fconnector <> nil then begin + fconnector.fparam:= nil; + end; + fconnector:= avalue; + if fconnector <> nil then begin + if fconnector.fparam <> nil then begin + fconnector.fparam.fconnector:= nil; + end; + fconnector.fparam:= self; + end; + end; +end; + +//{$ifdef mse_withpublishedparamvalue} +procedure tmseparam.setasvariant(const avalue: variant); +begin + inherited setasvariant(avalue); +{$warnings off} + tparam1(self).fbound:= not varisclear(avalue); +{$warnings on} +end; +//{$endif mse_withpublishedparamvalue} +{ +function tmseparam.getasid: int64; +begin + if isnull then begin + result:= -1; + end + else begin + result:= aslargeint; + end; +end; + +procedure tmseparam.setasid(const avalue: int64); +begin + if avalue = -1 then begin + clear; + end + else begin + aslargeint:= avalue; + end; +end; +} +function tmseparam.getdatasource: tdatasource; +begin + result:= fdatalink.datasource; +end; + +procedure tmseparam.setdatasource(const avalue: tdatasource); +begin + fdatalink.datasource:= avalue; +end; + +function tmseparam.getfieldname: string; +begin + result:= fdatalink.fieldname; +end; + +procedure tmseparam.setfieldname(const avalue: string); +begin + fdatalink.fieldname:= avalue; +end; + +function tmseparam.getdataset(const aindex: integer): tdataset; +begin + result:= fdatalink.dataset; +end; + +procedure tmseparam.getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); +begin + apropertynames:= nil; + afieldtypes:= nil; +end; + +function tmseparam.isparamstored: boolean; +begin + result:= bound; +end; +{ +function tmseparam.getasmsestring: msestring; +begin + result:= getaswidestring; +end; + +procedure tmseparam.setasmsestring(const avalue: msestring); +begin + setaswidestring(avalue); +end; +} +{ tparamconnector } + +destructor tparamconnector.destroy; +begin + if fparam <> nil then begin + fparam.connector:= nil; + end; + inherited; +end; + +function tparamconnector.getparam: tmseparam; +begin + if fparam = nil then begin + raise exception.create(name+': no param source.'); + end; + result:= fparam; +end; + +{ tmsedatasource } + +procedure tmsedatasource.bringtofront; +var + int1: integer; +begin + if (dataset <> nil) then begin +{$warnings off} + with tdataset1(dataset) do begin +{$warnings on} + int1:= fdatasources.indexof(self); + if int1 >= 0 then begin + fdatasources.move(int1,0); + end; + sortdatasources(); + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/db/msedbcalendardatetimeedit.pas b/mseide-msegui/lib/common/db/msedbcalendardatetimeedit.pas new file mode 100644 index 0000000..6864b04 --- /dev/null +++ b/mseide-msegui/lib/common/db/msedbcalendardatetimeedit.pas @@ -0,0 +1,202 @@ +{ MSEgui Copyright (c) 1999-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} + +unit msedbcalendardatetimeedit; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mdb,classes,mclasses,msecalendardatetimeedit,msedbedit,msedb,msegui, + msewidgetgrid,mseevent,msegraphics, + msedatalist,mseeditglob,msegrids,msemenus,mseguiglob,mseedit,msedataedits, + msestrings,msetypes; + +type + tdbcalendardatetimeedit = class(tcustomcalendardatetimeedit,idbeditfieldlink, + ireccontrol) + private + fdatalink: teditwidgetdatalink; + procedure setdatalink(const avalue: teditwidgetdatalink); + protected + procedure defineproperties(filer: tfiler); override; + function nullcheckneeded(const newfocus: twidget): boolean; override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + procedure modified; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; +// function getoptionsedit: optionseditty; override; +// procedure dochange; override; +// procedure doenter; override; +// procedure doexit; override; + function getrowdatapo(const arow: integer): pointer; override; + //idbeditfieldlink + procedure valuetofield; + procedure fieldtovalue; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + function getfieldlink: tcustomeditwidgetdatalink; + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: teditwidgetdatalink read fdatalink write setdatalink; + property dropdown; + property valuemin {stored false}; + property valuemax {stored false}; + property formatedit; + property formatdisp; + property kind; + property options; + property onsetvalue; + end; + +implementation +type + teditwidgetdatalink1 = class(teditwidgetdatalink); + +{ tdbcalendardatetimeedit } + +constructor tdbcalendardatetimeedit.create(aowner: tcomponent); +begin + fdatalink:= teditwidgetdatalink.Create(idbeditfieldlink(self)); + inherited; +end; + +destructor tdbcalendardatetimeedit.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tdbcalendardatetimeedit.modified; +begin + fdatalink.modified; + inherited; +end; + +procedure tdbcalendardatetimeedit.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; +{ +function tdbcalendardatetimeedit.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); +end; +} +procedure tdbcalendardatetimeedit.valuetofield; +begin + if value = emptydatetime then begin + fdatalink.field.clear; + end + else begin + fdatalink.field.asdatetime:= value; + end; +end; + +procedure tdbcalendardatetimeedit.fieldtovalue; +var + da1: tdatetime; +begin + if fdatalink.field.isnull then begin + value:= 0; + end + else begin + da1:= fdatalink.field.asdatetime; + value:= da1; + end; +end; + +function tdbcalendardatetimeedit.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink).getdatetimebuffer( + fdatalink.field,arow); + end + else begin + result:= nil; + end; +end; + +function tdbcalendardatetimeedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdbcalendardatetimeedit.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdbcalendardatetimeedit.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +procedure tdbcalendardatetimeedit.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= datetimefields; +end; + +function tdbcalendardatetimeedit.nullcheckneeded(const newfocus: twidget): boolean; +begin + result:= inherited nullcheckneeded(newfocus); + fdatalink.nullcheckneeded(result); +end; + +procedure tdbcalendardatetimeedit.setdatalink(const avalue: teditwidgetdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbcalendardatetimeedit.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +procedure tdbcalendardatetimeedit.recchanged; +begin + fdatalink.recordchanged(nil); +end; +{ +procedure tdbcalendardatetimeedit.dochange; +begin + fdatalink.datachanged; + inherited; +end; +} +function tdbcalendardatetimeedit.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; +{ +procedure tdbcalendardatetimeedit.doenter; +begin + teditwidgetdatalink1(fdatalink).doenter(self); + inherited; +end; + +procedure tdbcalendardatetimeedit.doexit; +begin + teditwidgetdatalink1(fdatalink).doexit(self); + inherited; +end; +} +end. diff --git a/mseide-msegui/lib/common/db/msedbdialog.pas b/mseide-msegui/lib/common/db/msedbdialog.pas new file mode 100644 index 0000000..c8f5564 --- /dev/null +++ b/mseide-msegui/lib/common/db/msedbdialog.pas @@ -0,0 +1,812 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} + +unit msedbdialog; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + classes,mclasses,mseguiglob,msefiledialog,mdb,mseinplaceedit,msedbedit,msegui, + msewidgetgrid, + msedatalist,mseeditglob,msegrids,msetypes,msedb,msemenus,mseedit, + msedataedits,mseevent,msestrings,msecolordialog,msegraphutils,msedialog, + mseglob,msegraphics; + +type + tdbfilenameedit = class(tcustomfilenameedit,idbeditfieldlink,ireccontrol) + private + fdatalink: tstringeditwidgetdatalink; + procedure setdatalink(const avalue: tstringeditwidgetdatalink); + protected + procedure defineproperties(filer: tfiler); override; + procedure editnotification(var info: editnotificationinfoty); override; + function nullcheckneeded(const newfocus: twidget): boolean; override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + procedure modified; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; +// function getoptionsedit: optionseditty; override; +// procedure dochange; override; +// procedure doenter; override; +// procedure doexit; override; + function getrowdatapo(const arow: integer): pointer; override; + function getfieldlink: tcustomeditwidgetdatalink; + //idbeditfieldlink + procedure valuetofield; + procedure fieldtovalue; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: tstringeditwidgetdatalink read fdatalink write setdatalink; + property frame; + property passwordchar; + property maxlength; + property onsetvalue; + property controller; + end; + + tdbremotefilenameedit = class(tcustomremotefilenameedit,idbeditfieldlink, + ireccontrol) + private + fdatalink: tstringeditwidgetdatalink; + procedure setdatalink(const avalue: tstringeditwidgetdatalink); + protected + procedure defineproperties(filer: tfiler); override; + procedure editnotification(var info: editnotificationinfoty); override; + function nullcheckneeded(const newfocus: twidget): boolean; override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + procedure modified; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; +// function getoptionsedit: optionseditty; override; +// procedure dochange; override; +// procedure doenter; override; +// procedure doexit; override; + function getrowdatapo(const arow: integer): pointer; override; + function getfieldlink: tcustomeditwidgetdatalink; + //idbeditfieldlink + procedure valuetofield; + procedure fieldtovalue; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: tstringeditwidgetdatalink read fdatalink write setdatalink; + property frame; + property passwordchar; + property maxlength; + property onsetvalue; + property dialog; + end; + + tdbcoloredit = class(tcustomcoloredit,idbeditfieldlink,ireccontrol) + private + fdatalink: teditwidgetdatalink; + procedure setdatalink(const avalue: teditwidgetdatalink); + protected + procedure defineproperties(filer: tfiler); override; + + function internaldatatotext1( + const avalue: integer): msestring; override; + function nullcheckneeded(const newfocus: twidget): boolean; override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + procedure modified; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; +// function getoptionsedit: optionseditty; override; +// procedure dochange; override; +// procedure doenter; override; +// procedure doexit; override; + + function getrowdatapo(const arow: integer): pointer; override; + //idbeditfieldlink + procedure valuetofield; virtual; + procedure fieldtovalue; virtual; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + function getfieldlink: tcustomeditwidgetdatalink; + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: teditwidgetdatalink read fdatalink write setdatalink; + property options; + property dropdown; + property onsetvalue; + property frame; + end; + + tdbdialogstringedit = class(tdbstringedit) + private + function getframe: tellipsebuttonframe; + procedure setframe(const avalue: tellipsebuttonframe); + function getonexecute: stringdialogexeceventty; + procedure setonexecute(const avalue: stringdialogexeceventty); + protected + fcontroller: tstringdialogcontroller; + function createdialogcontroller: tstringdialogcontroller; virtual; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property textflags default defaulttextflagsnoycentered; + property textflagsactive default defaulttextflagsactivenoycentered; + property frame: tellipsebuttonframe read getframe write setframe; + property onexecute: stringdialogexeceventty read getonexecute write setonexecute; + end; + + tdbmemodialogedit = class(tdbdialogstringedit) + protected + function createdialogcontroller: tstringdialogcontroller; override; + public + end; + + tdbdialogrealedit = class(tdbrealedit) + private + function getframe: tellipsebuttonframe; + procedure setframe(const avalue: tellipsebuttonframe); + function getonexecute: realdialogexeceventty; + procedure setonexecute(const avalue: realdialogexeceventty); + protected + fdialogcontroller: trealdialogcontroller; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property frame: tellipsebuttonframe read getframe write setframe; + property onexecute: realdialogexeceventty read getonexecute + write setonexecute; + end; + + tdbdialogdatetimeedit = class(tdbdatetimeedit) + private + function getframe: tellipsebuttonframe; + procedure setframe(const avalue: tellipsebuttonframe); + function getonexecute: datetimedialogexeceventty; + procedure setonexecute(const avalue: datetimedialogexeceventty); + protected + fdialogcontroller: tdatetimedialogcontroller; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property frame: tellipsebuttonframe read getframe write setframe; + property onexecute: datetimedialogexeceventty read getonexecute + write setonexecute; + end; + + tdbdialogintegeredit = class(tdbintegeredit) + private + function getframe: tellipsebuttonframe; + procedure setframe(const avalue: tellipsebuttonframe); + function getonexecute: integerdialogexeceventty; + procedure setonexecute(const avalue: integerdialogexeceventty); + protected + fdialogcontroller: tintegerdialogcontroller; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property frame: tellipsebuttonframe read getframe write setframe; + property onexecute: integerdialogexeceventty read getonexecute + write setonexecute; + end; + +implementation +uses + typinfo,msememodialog; +type + teditwidgetdatalink1 = class(teditwidgetdatalink); + tstringeditwidgetdatalink1 = class(tstringeditwidgetdatalink); + treader1 = class(treader); + +{ tdbfilenameedit } + +constructor tdbfilenameedit.create(aowner: tcomponent); +begin + fdatalink:= tstringeditwidgetdatalink.Create(idbeditfieldlink(self)); + inherited; +end; + +destructor tdbfilenameedit.destroy; +begin + inherited; + fdatalink.free; +end; +{ +procedure tdbfilenameedit.dochange; +begin + fdatalink.datachanged; + inherited; +end; +} +procedure tdbfilenameedit.modified; +begin + fdatalink.modified; + inherited; +end; + +procedure tdbfilenameedit.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; +{ +function tdbfilenameedit.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); +end; +} +procedure tdbfilenameedit.valuetofield; +begin + if value = '' then begin + fdatalink.field.clear; + end + else begin + fdatalink.asmsestring:= value; + end; +end; + +procedure tdbfilenameedit.fieldtovalue; +begin + value:= fdatalink.asmsestring; +end; + +function tdbfilenameedit.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink).getstringbuffer(fdatalink.field,arow); + end + else begin + result:= nil; + end; +end; + +function tdbfilenameedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdbfilenameedit.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdbfilenameedit.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +procedure tdbfilenameedit.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= textfields; +end; + +function tdbfilenameedit.nullcheckneeded(const newfocus: twidget): boolean; +begin + result:= inherited nullcheckneeded(newfocus); +{$warnings off} + teditwidgetdatalink1(fdatalink).nullcheckneeded(result); +{$warnings on} +end; + +procedure tdbfilenameedit.setdatalink(const avalue: tstringeditwidgetdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbfilenameedit.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +procedure tdbfilenameedit.editnotification(var info: editnotificationinfoty); +var + int1: integer; +begin + inherited; + if info.action = ea_textedited then begin + if fdatalink.cuttext(text,int1) then begin + text:= copy(text,1,int1); + end; + end; +end; + +procedure tdbfilenameedit.recchanged; +begin +{$warnings off} + teditwidgetdatalink1(fdatalink).recordchanged(nil); +{$warnings on} +end; + +function tdbfilenameedit.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; +{ +procedure tdbfilenameedit.doenter; +begin + tstringeditwidgetdatalink1(fdatalink).doenter(self); + inherited; +end; + +procedure tdbfilenameedit.doexit; +begin + tstringeditwidgetdatalink1(fdatalink).doexit(self); + inherited; +end; +} +{ tdbremotefilenameedit } + +constructor tdbremotefilenameedit.create(aowner: tcomponent); +begin + fdatalink:= tstringeditwidgetdatalink.Create(idbeditfieldlink(self)); + inherited; +end; + +destructor tdbremotefilenameedit.destroy; +begin + inherited; + fdatalink.free; +end; +{ +procedure tdbremotefilenameedit.dochange; +begin + fdatalink.datachanged; + inherited; +end; +} +procedure tdbremotefilenameedit.modified; +begin + fdatalink.modified; + inherited; +end; + +procedure tdbremotefilenameedit.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; +{ +function tdbremotefilenameedit.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); +end; +} +procedure tdbremotefilenameedit.valuetofield; +begin + if value = '' then begin + fdatalink.field.clear; + end + else begin + fdatalink.asmsestring:= value; + end; +end; + +procedure tdbremotefilenameedit.fieldtovalue; +begin + value:= fdatalink.asmsestring; +end; + +function tdbremotefilenameedit.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink).getstringbuffer(fdatalink.field,arow); + end + else begin + result:= nil; + end; +end; + +function tdbremotefilenameedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdbremotefilenameedit.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdbremotefilenameedit.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +procedure tdbremotefilenameedit.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= textfields; +end; + +function tdbremotefilenameedit.nullcheckneeded(const newfocus: twidget): boolean; +begin + result:= inherited nullcheckneeded(newfocus); +{$warnings off} + teditwidgetdatalink1(fdatalink).nullcheckneeded(result); +{$warnings on} +end; + +procedure tdbremotefilenameedit.setdatalink(const avalue: tstringeditwidgetdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbremotefilenameedit.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +procedure tdbremotefilenameedit.editnotification(var info: editnotificationinfoty); +var + int1: integer; +begin + inherited; + if info.action = ea_textedited then begin + if fdatalink.cuttext(text,int1) then begin + text:= copy(text,1,int1); + end; + end; +end; + +procedure tdbremotefilenameedit.recchanged; +begin +{$warnings off} + teditwidgetdatalink1(fdatalink).recordchanged(nil); +{$warnings on} +end; + +function tdbremotefilenameedit.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; +{ +procedure tdbremotefilenameedit.doenter; +begin + tstringeditwidgetdatalink1(fdatalink).doenter(self); + inherited; +end; + +procedure tdbremotefilenameedit.doexit; +begin + tstringeditwidgetdatalink1(fdatalink).doexit(self); + inherited; +end; +} +{ tdbcoloredit } + +constructor tdbcoloredit.create(aowner: tcomponent); +begin + fdatalink:= teditwidgetdatalink.create(idbeditfieldlink(self)); + inherited; + valuedefault:= colorty(-1); +end; + +destructor tdbcoloredit.destroy; +begin + inherited; + fdatalink.free; +end; +{ +procedure tdbcoloredit.dochange; +begin + fdatalink.datachanged; + inherited; +end; +} +procedure tdbcoloredit.modified; +begin + fdatalink.modified; + inherited; +end; + +procedure tdbcoloredit.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; +{ +function tdbcoloredit.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); + frame.readonly:= oe_readonly in result; +end; +} +procedure tdbcoloredit.valuetofield; +begin + if value = colorty(-1) then begin + fdatalink.field.clear; + end + else begin + fdatalink.field.asinteger:= value; + end; +end; + +procedure tdbcoloredit.fieldtovalue; +begin + if fdatalink.field.isnull then begin + value:= fvaluedefault1; + end + else begin + value:= fdatalink.field.asinteger; + end; +end; + +function tdbcoloredit.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink). + getintegerbuffer(fdatalink.field,arow); + if result = nil then begin + result:= @fvaluedefault; + end; + end + else begin + result:= @fvaluedefault; + end; +end; + +function tdbcoloredit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdbcoloredit.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdbcoloredit.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +procedure tdbcoloredit.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= integerfields; +end; + +function tdbcoloredit.nullcheckneeded(const newfocus: twidget): boolean; +begin + result:= inherited nullcheckneeded(newfocus); + fdatalink.nullcheckneeded(result); +end; + +procedure tdbcoloredit.setdatalink(const avalue: teditwidgetdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbcoloredit.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +procedure tdbcoloredit.recchanged; +begin + fdatalink.recordchanged(nil); +end; + +function tdbcoloredit.internaldatatotext1(const avalue: integer): msestring; +begin + if avalue = -1 then begin + result:= ''; + end + else begin + result:= inherited internaldatatotext1(avalue); + end; +end; + +function tdbcoloredit.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; +{ +procedure tdbcoloredit.doenter; +begin + teditwidgetdatalink1(fdatalink).doenter(self); + inherited; +end; + +procedure tdbcoloredit.doexit; +begin + teditwidgetdatalink1(fdatalink).doexit(self); + inherited; +end; +} +{ tdbdialogstringedit } + +constructor tdbdialogstringedit.create(aowner: tcomponent); +begin + inherited; + ftextflags:= defaulttextflagsnoycentered; + ftextflagsactive:= defaulttextflagsactivenoycentered; + updatetextflags(); + if fcontroller = nil then begin + fcontroller:= createdialogcontroller; + end; +end; + +destructor tdbdialogstringedit.destroy; +begin + inherited; + fcontroller.free; +end; + +function tdbdialogstringedit.getframe: tellipsebuttonframe; +begin + result:= tellipsebuttonframe(inherited getframe); +end; + +procedure tdbdialogstringedit.setframe(const avalue: tellipsebuttonframe); +begin + inherited setframe(avalue); +end; + +function tdbdialogstringedit.getonexecute: stringdialogexeceventty; +begin + result:= fcontroller.onexecute; +end; + +procedure tdbdialogstringedit.setonexecute(const avalue: stringdialogexeceventty); +begin + fcontroller.onexecute:= avalue; +end; + +function tdbdialogstringedit.createdialogcontroller: tstringdialogcontroller; +begin + result:= tstringdialogcontroller.create(self); +end; + +{ tdbmemodialogedit } + +function tdbmemodialogedit.createdialogcontroller: tstringdialogcontroller; +begin + result:= tmemodialogcontroller.create(self); +end; + +{ tdbdialogrealedit } + +constructor tdbdialogrealedit.create(aowner: tcomponent); +begin + inherited; + if fdialogcontroller = nil then begin + fdialogcontroller:= trealdialogcontroller.create(self); + end; +end; + +destructor tdbdialogrealedit.destroy; +begin + inherited; + fdialogcontroller.free; +end; + +function tdbdialogrealedit.getframe: tellipsebuttonframe; +begin + result:= tellipsebuttonframe(inherited getframe); +end; + +procedure tdbdialogrealedit.setframe(const avalue: tellipsebuttonframe); +begin + inherited setframe(avalue); +end; + +function tdbdialogrealedit.getonexecute: realdialogexeceventty; +begin + result:= fdialogcontroller.onexecute; +end; + +procedure tdbdialogrealedit.setonexecute(const avalue: realdialogexeceventty); +begin + fdialogcontroller.onexecute:= avalue; +end; + +{ tdbdialogdatetimeedit } + +constructor tdbdialogdatetimeedit.create(aowner: tcomponent); +begin + inherited; + if fdialogcontroller = nil then begin + fdialogcontroller:= tdatetimedialogcontroller.create(self); + end; +end; + +destructor tdbdialogdatetimeedit.destroy; +begin + inherited; + fdialogcontroller.free; +end; + +function tdbdialogdatetimeedit.getframe: tellipsebuttonframe; +begin + result:= tellipsebuttonframe(inherited getframe); +end; + +procedure tdbdialogdatetimeedit.setframe(const avalue: tellipsebuttonframe); +begin + inherited setframe(avalue); +end; + +function tdbdialogdatetimeedit.getonexecute: datetimedialogexeceventty; +begin + result:= fdialogcontroller.onexecute; +end; + +procedure tdbdialogdatetimeedit.setonexecute(const avalue: datetimedialogexeceventty); +begin + fdialogcontroller.onexecute:= avalue; +end; + +{ tdbdialogintegeredit } + +constructor tdbdialogintegeredit.create(aowner: tcomponent); +begin + inherited; + if fdialogcontroller = nil then begin + fdialogcontroller:= tintegerdialogcontroller.create(self); + end; +end; + +destructor tdbdialogintegeredit.destroy; +begin + inherited; + fdialogcontroller.free; +end; + +function tdbdialogintegeredit.getframe: tellipsebuttonframe; +begin + result:= tellipsebuttonframe(inherited getframe); +end; + +procedure tdbdialogintegeredit.setframe(const avalue: tellipsebuttonframe); +begin + inherited setframe(avalue); +end; + +function tdbdialogintegeredit.getonexecute: integerdialogexeceventty; +begin + result:= fdialogcontroller.onexecute; +end; + +procedure tdbdialogintegeredit.setonexecute(const avalue: integerdialogexeceventty); +begin + fdialogcontroller.onexecute:= avalue; +end; + +end. diff --git a/mseide-msegui/lib/common/db/msedbdispwidgets.pas b/mseide-msegui/lib/common/db/msedbdispwidgets.pas new file mode 100644 index 0000000..8203a5d --- /dev/null +++ b/mseide-msegui/lib/common/db/msedbdispwidgets.pas @@ -0,0 +1,997 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msedbdispwidgets; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +interface +uses + mdb,classes,mclasses,msesimplewidgets,msedb,msetypes,mseclasses,mseguiglob, + mseglob,mseinterfaces,msegraphics, + msedispwidgets,msestrings,mselookupbuffer,msegui,msemenus,mseevent, + msebarcode; + +type + tdispfielddatalink = class; + + idbdispfieldlink = interface(inullinterface)[miid_idbdispfieldlink] + procedure fieldtovalue; + procedure setnullvalue; + function getwidget: twidget; + procedure getfieldtypes(var afieldtypes: fieldtypesty); //[] = all + function getfieldlink(): tdispfielddatalink; + end; + + tdispfielddatalink = class(tfielddatalink,idbeditinfo) + private + procedure readdatasource(reader: treader); + procedure readdatafield(reader: treader); + protected + fintf: idbdispfieldlink; + procedure activechanged; override; + function getdataset(const aindex: integer): tdataset; virtual; + procedure getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); virtual; + public + constructor create(const intf: idbdispfieldlink); + procedure fixupproperties(filer: tfiler); //read moved properties + procedure recordchanged(afield: tfield); override; + published + property datasource; + property fieldname; + end; + + tdblabel = class(tcustomlabel,idbdispfieldlink,ireccontrol) + private + fdatalink: tdispfielddatalink; + //idbdispfieldlink + function getfieldlink: tdispfielddatalink; + procedure getfieldtypes(var fieldtypes: fieldtypesty); + procedure fieldtovalue; + procedure setnullvalue; + //ireccontrol + procedure recchanged; + procedure setdatalink(const avalue: tdispfielddatalink); + protected + procedure defineproperties(filer: tfiler); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property options; //first + property datalink: tdispfielddatalink read fdatalink write setdatalink; + property bounds_cx default defaultlabelwidgetwidth; + property bounds_cy default defaultlabelwidgetheight; + property optionswidget default defaultlabeloptionswidget; + property font; + property textflags; + end; + + tdbstringdisp = class(tcustomstringdisp,idbdispfieldlink,ireccontrol) + private + fdatalink: tdispfielddatalink; + //idbdispfieldlink + function getfieldlink: tdispfielddatalink; + procedure getfieldtypes(var fieldtypes: fieldtypesty); virtual; + procedure fieldtovalue; virtual; + procedure setnullvalue; + //ireccontrol + procedure recchanged; + procedure setdatalink(const avalue: tdispfielddatalink); + protected + procedure defineproperties(filer: tfiler); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: tdispfielddatalink read fdatalink write setdatalink; + end; + + tdbstringdisplb = class(tdbstringdisp,idbdispfieldlink,ireccontrol, + ilookupbufferfieldinfo) + private + flookupbuffer: tcustomlookupbuffer; + flookupkeyfieldno: lookupbufferfieldnoty; + flookupvaluefieldno: lookupbufferfieldnoty; + fkeyvalue: integer; + procedure setlookupbuffer(const avalue: tcustomlookupbuffer); + //idbdispfieldlink + procedure getfieldtypes(var fieldtypes: fieldtypesty); override; + procedure fieldtovalue; override; + procedure setkeyvalue(const avalue: integer); + protected + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + //ilookupbufferfieldinfo + function getlbdatakind(const apropname: string): lbdatakindty; + function getlookupbuffer: tcustomlookupbuffer; + public + property keyvalue: integer read fkeyvalue write setkeyvalue; + published + property lookupbuffer: tcustomlookupbuffer read flookupbuffer + write setlookupbuffer; + property lookupkeyfieldno: lookupbufferfieldnoty read flookupkeyfieldno + write flookupkeyfieldno default 0; + property lookupvaluefieldno: lookupbufferfieldnoty read flookupvaluefieldno + write flookupvaluefieldno default 0; + end; + + tdbintegerdisp = class(tcustomintegerdisp,idbdispfieldlink,ireccontrol) + private + fdatalink: tdispfielddatalink; + fisnotnull: boolean; + //idbdispfieldlink + function getfieldlink: tdispfielddatalink; + procedure getfieldtypes(var fieldtypes: fieldtypesty); + procedure fieldtovalue; virtual; + procedure setnullvalue; + //ireccontrol + procedure recchanged; + procedure setdatalink(const avalue: tdispfielddatalink); + protected + procedure defineproperties(filer: tfiler); override; + function getvaluetext: msestring; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: tdispfielddatalink read fdatalink write setdatalink; + end; + + tdbintegerdisplb = class(tdbintegerdisp,idbdispfieldlink,ireccontrol, + ilookupbufferfieldinfo) + private + flookupbuffer: tcustomlookupbuffer; + flookupkeyfieldno: lookupbufferfieldnoty; + flookupvaluefieldno: lookupbufferfieldnoty; + fkeyvalue: integer; + procedure setlookupbuffer(const avalue: tcustomlookupbuffer); + //idbdispfieldlink + procedure fieldtovalue; override; + procedure setkeyvalue(const avalue: integer); + protected + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + //ilookupbufferfieldinfo + function getlbdatakind(const apropname: string): lbdatakindty; + function getlookupbuffer: tcustomlookupbuffer; + public + property keyvalue: integer read fkeyvalue write setkeyvalue; + published + property lookupbuffer: tcustomlookupbuffer read flookupbuffer + write setlookupbuffer; + property lookupkeyfieldno: lookupbufferfieldnoty read flookupkeyfieldno + write flookupkeyfieldno default 0; + property lookupvaluefieldno: lookupbufferfieldnoty read flookupvaluefieldno + write flookupvaluefieldno default 0; + end; + + tdbbooleandisp = class(tcustombooleandisp,idbdispfieldlink,ireccontrol) + private + fisnotnull: boolean; + fdatalink: tdispfielddatalink; + //idbdispfieldlink + function getfieldlink: tdispfielddatalink; + procedure getfieldtypes(var fieldtypes: fieldtypesty); + procedure fieldtovalue; + procedure setnullvalue; + //ireccontrol + procedure recchanged; + procedure setdatalink(const avalue: tdispfielddatalink); + protected + procedure defineproperties(filer: tfiler); override; + function getvaluetext: msestring; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: tdispfielddatalink read fdatalink write setdatalink; + end; + + tdbrealdisp = class(tcustomrealdisp,idbdispfieldlink,ireccontrol) + private + fdatalink: tdispfielddatalink; + //idbdispfieldlink + function getfieldlink: tdispfielddatalink; + procedure getfieldtypes(var fieldtypes: fieldtypesty); virtual; + procedure fieldtovalue; virtual; + procedure setnullvalue; + //ireccontrol + procedure recchanged; + procedure setdatalink(const avalue: tdispfielddatalink); + protected + procedure defineproperties(filer: tfiler); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: tdispfielddatalink read fdatalink write setdatalink; + end; + + tdbrealdisplb = class(tdbrealdisp,idbdispfieldlink,ireccontrol, + ilookupbufferfieldinfo) + private + flookupbuffer: tcustomlookupbuffer; + flookupkeyfieldno: lookupbufferfieldnoty; + flookupvaluefieldno: lookupbufferfieldnoty; + fkeyvalue: integer; + procedure setlookupbuffer(const avalue: tcustomlookupbuffer); + //idbdispfieldlink + procedure getfieldtypes(var fieldtypes: fieldtypesty); override; + procedure fieldtovalue; override; + procedure setkeyvalue(const avalue: integer); + protected + procedure objectevent(const sender: tobject; const event: objecteventty); override; + //ilookupbufferfieldinfo + function getlbdatakind(const apropname: string): lbdatakindty; + function getlookupbuffer: tcustomlookupbuffer; + public + property keyvalue: integer read fkeyvalue write setkeyvalue; + published + property lookupbuffer: tcustomlookupbuffer read flookupbuffer write setlookupbuffer; + property lookupkeyfieldno: lookupbufferfieldnoty read flookupkeyfieldno write flookupkeyfieldno default 0; + property lookupvaluefieldno: lookupbufferfieldnoty read flookupvaluefieldno write flookupvaluefieldno default 0; + end; + + tdbdatetimedisp = class(tcustomdatetimedisp,idbdispfieldlink,ireccontrol) + private + fdatalink: tdispfielddatalink; + //idbdispfieldlink + function getfieldlink: tdispfielddatalink; + procedure getfieldtypes(var fieldtypes: fieldtypesty); virtual; + procedure fieldtovalue; virtual; + procedure setnullvalue; + //ireccontrol + procedure recchanged; + procedure setdatalink(const avalue: tdispfielddatalink); + protected + procedure defineproperties(filer: tfiler); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: tdispfielddatalink read fdatalink write setdatalink; + end; + + tdbdatetimedisplb = class(tdbdatetimedisp,idbdispfieldlink,ireccontrol, + ilookupbufferfieldinfo) + private + flookupbuffer: tcustomlookupbuffer; + flookupkeyfieldno: lookupbufferfieldnoty; + flookupvaluefieldno: lookupbufferfieldnoty; + fkeyvalue: integer; + procedure setlookupbuffer(const avalue: tcustomlookupbuffer); + //idbdispfieldlink + procedure getfieldtypes(var fieldtypes: fieldtypesty); override; + procedure fieldtovalue; override; + procedure setkeyvalue(const avalue: integer); + protected + procedure objectevent(const sender: tobject; const event: objecteventty); override; + //ilookupbufferfieldinfo + function getlbdatakind(const apropname: string): lbdatakindty; + function getlookupbuffer: tcustomlookupbuffer; + public + property keyvalue: integer read fkeyvalue write setkeyvalue; + published + property lookupbuffer: tcustomlookupbuffer read flookupbuffer write setlookupbuffer; + property lookupkeyfieldno: lookupbufferfieldnoty read flookupkeyfieldno write flookupkeyfieldno default 0; + property lookupvaluefieldno: lookupbufferfieldnoty read flookupvaluefieldno write flookupvaluefieldno default 0; + end; + + tdbbarcode = class(tcustombarcode1,idbdispfieldlink,ireccontrol) + private + fdatalink: tdispfielddatalink; + //idbdispfieldlink + function getfieldlink: tdispfielddatalink; + procedure getfieldtypes(var fieldtypes: fieldtypesty); virtual; + procedure fieldtovalue; virtual; + procedure setnullvalue; + //ireccontrol + procedure recchanged; + procedure setdatalink(const avalue: tdispfielddatalink); + protected + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: tdispfielddatalink read fdatalink write setdatalink; + published + property options; + property kind; + property direction; + property colorbar; + property colorspace; + property fontbar; + end; + +implementation +uses + msereal,sysutils,typinfo; +type + treader1 = class(treader); + +{ tdispfielddatalink } + +constructor tdispfielddatalink.create(const intf: idbdispfieldlink); +begin + fintf:= intf; + inherited create; + visualcontrol:= true; +end; + +procedure tdispfielddatalink.readdatasource(reader: treader); +begin + treader1(reader).readpropvalue(self, + getpropinfo(typeinfo(tdispfielddatalink),'datasource')); +end; + +procedure tdispfielddatalink.readdatafield(reader: treader); +begin + fieldname:= reader.readstring; +end; + +procedure tdispfielddatalink.fixupproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('datasource',{$ifdef FPC}@{$endif}readdatasource,nil,false); + filer.defineproperty('datafield',{$ifdef FPC}@{$endif}readdatafield,nil,false); + //move values to datalink +end; + +function tdispfielddatalink.getdataset(const aindex: integer): tdataset; +begin + result:= dataset; +end; + +procedure tdispfielddatalink.getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); +begin + apropertynames:= nil; + setlength(afieldtypes,1); + afieldtypes[0]:= []; + fintf.getfieldtypes(afieldtypes[0]); + if afieldtypes[0] = [] then begin + afieldtypes:= nil; + end; +end; + +procedure tdispfielddatalink.recordchanged(afield: tfield); +begin + if (afield = nil) or (afield = field) then begin + if active and (field <> nil) and + not (dataset.eof and dataset.bof and + (dataset.state <> dsinsert)) then begin + if field.isnull then begin + fintf.setnullvalue; + end + else begin + fintf.fieldtovalue; + end; + end + else begin + fintf.setnullvalue; + end; + end; +end; + +procedure tdispfielddatalink.activechanged; +begin + try + inherited; + except + on e: exception do begin + e.message:= fintf.getwidget.name + ': ' + e.message; + raise + end; + end; +end; + +{ tdblabel } + +constructor tdblabel.create(aowner: tcomponent); +begin + fdatalink:= tdispfielddatalink.create(idbdispfieldlink(self)); + inherited; +end; + +destructor tdblabel.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tdblabel.getfieldtypes(var fieldtypes: fieldtypesty); +begin + //all types +end; + +procedure tdblabel.fieldtovalue; +begin + caption:= msestring(datalink.field.displaytext); //tmsestringfield? +end; + +procedure tdblabel.setnullvalue; +begin + caption:= ''; +end; + +procedure tdblabel.recchanged; +begin + fdatalink.recordchanged(nil); +end; + +procedure tdblabel.setdatalink(const avalue: tdispfielddatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdblabel.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +function tdblabel.getfieldlink: tdispfielddatalink; +begin + result:= fdatalink; +end; + +{ tdbstringdisp } + +constructor tdbstringdisp.create(aowner: tcomponent); +begin + fdatalink:= tdispfielddatalink.create(idbdispfieldlink(self)); + inherited; +end; + +destructor tdbstringdisp.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tdbstringdisp.getfieldtypes(var fieldtypes: fieldtypesty); +begin + fieldtypes:= textfields; +end; + +procedure tdbstringdisp.fieldtovalue; +begin + value:= datalink.asmsestring; +end; + +procedure tdbstringdisp.setnullvalue; +begin + value:= ''; +end; + +procedure tdbstringdisp.recchanged; +begin + fdatalink.recordchanged(nil); +end; + +procedure tdbstringdisp.setdatalink(const avalue: tdispfielddatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbstringdisp.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +function tdbstringdisp.getfieldlink: tdispfielddatalink; +begin + result:= fdatalink; +end; + +{ tdbbarcode } + +constructor tdbbarcode.create(aowner: tcomponent); +begin + fdatalink:= tdispfielddatalink.create(idbdispfieldlink(self)); + inherited; +end; + +destructor tdbbarcode.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tdbbarcode.getfieldtypes(var fieldtypes: fieldtypesty); +begin + fieldtypes:= textfields+integerfields; +end; + +procedure tdbbarcode.fieldtovalue; +begin + value:= datalink.asmsestring; +end; + +procedure tdbbarcode.setnullvalue; +begin + value:= ''; +end; + +procedure tdbbarcode.recchanged; +begin + fdatalink.recordchanged(nil); +end; + +procedure tdbbarcode.setdatalink(const avalue: tdispfielddatalink); +begin + fdatalink.assign(avalue); +end; + +function tdbbarcode.getfieldlink: tdispfielddatalink; +begin + result:= fdatalink; +end; + +{ tdbstringdisplb } + +procedure tdbstringdisplb.getfieldtypes(var fieldtypes: fieldtypesty); +begin + fieldtypes:= integerfields; +end; + +procedure tdbstringdisplb.fieldtovalue; +begin + keyvalue:= datalink.field.asinteger; +end; + +procedure tdbstringdisplb.setlookupbuffer(const avalue: tcustomlookupbuffer); +begin + setlinkedvar(avalue,tmsecomponent(flookupbuffer)); +end; + +procedure tdbstringdisplb.setkeyvalue(const avalue: integer); +var + int1: integer; +begin + fkeyvalue:= avalue; + if flookupbuffer <> nil then begin + if flookupbuffer.findphys(flookupkeyfieldno,fkeyvalue,int1) then begin + value:= flookupbuffer.textvaluephys(flookupvaluefieldno,int1); + end + else begin + setnullvalue; + end; + end + else begin + setnullvalue; + end; +end; + +procedure tdbstringdisplb.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (event in [oe_changed,oe_connect]) and (sender = flookupbuffer) then begin + setkeyvalue(fkeyvalue); + end; +end; + +function tdbstringdisplb.getlbdatakind(const apropname: string): lbdatakindty; +begin + if apropname = 'lookupkeyfieldno' then begin + result:= lbdk_integer; + end + else begin + result:= lbdk_text; + end; +end; + +function tdbstringdisplb.getlookupbuffer: tcustomlookupbuffer; +begin + result:= flookupbuffer; +end; + +{ tdbintegerdisp } + +constructor tdbintegerdisp.create(aowner: tcomponent); +begin + fdatalink:= tdispfielddatalink.create(idbdispfieldlink(self)); + inherited; +end; + +destructor tdbintegerdisp.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tdbintegerdisp.getfieldtypes(var fieldtypes: fieldtypesty); +begin + fieldtypes:= integerfields; +end; + +procedure tdbintegerdisp.fieldtovalue; +begin + fisnotnull:= true; + value:= datalink.field.asinteger; +end; + +procedure tdbintegerdisp.setnullvalue; +begin + fisnotnull:= false; + value:= 0; +end; + +function tdbintegerdisp.getvaluetext: msestring; +begin + if fisnotnull then begin + result:= inherited getvaluetext; + end + else begin + result:= ''; + end; +end; + +procedure tdbintegerdisp.recchanged; +begin + fdatalink.recordchanged(nil); +end; + +procedure tdbintegerdisp.setdatalink(const avalue: tdispfielddatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbintegerdisp.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +function tdbintegerdisp.getfieldlink: tdispfielddatalink; +begin + result:= fdatalink; +end; + +{ tdbintegerdisplb } + +procedure tdbintegerdisplb.fieldtovalue; +begin + keyvalue:= datalink.field.asinteger; +end; + +procedure tdbintegerdisplb.setlookupbuffer(const avalue: tcustomlookupbuffer); +begin + setlinkedvar(avalue,tmsecomponent(flookupbuffer)); +end; + +procedure tdbintegerdisplb.setkeyvalue(const avalue: integer); +var + int1: integer; +begin + fkeyvalue:= avalue; + if flookupbuffer <> nil then begin + if flookupbuffer.findphys(flookupkeyfieldno,fkeyvalue,int1) then begin + fisnotnull:= true; + value:= flookupbuffer.integervaluephys(flookupvaluefieldno,int1); + end + else begin + setnullvalue; + end; + end + else begin + setnullvalue; + end; +end; + +procedure tdbintegerdisplb.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (event in [oe_changed,oe_connect]) and (sender = flookupbuffer) then begin + setkeyvalue(fkeyvalue); + end; +end; + +function tdbintegerdisplb.getlbdatakind(const apropname: string): lbdatakindty; +begin + if apropname = 'lookupkeyfieldno' then begin + result:= lbdk_integer; + end + else begin + result:= lbdk_integer; + end; +end; + +function tdbintegerdisplb.getlookupbuffer: tcustomlookupbuffer; +begin + result:= flookupbuffer; +end; + +{ tdbbooleandisp } + +constructor tdbbooleandisp.create(aowner: tcomponent); +begin + fdatalink:= tdispfielddatalink.create(idbdispfieldlink(self)); + inherited; +end; + +destructor tdbbooleandisp.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tdbbooleandisp.getfieldtypes(var fieldtypes: fieldtypesty); +begin + fieldtypes:= booleanfields; +end; + +procedure tdbbooleandisp.fieldtovalue; +begin + fisnotnull:= true; + value:= datalink.field.asboolean; +end; + +procedure tdbbooleandisp.setnullvalue; +begin + fisnotnull:= false; + value:= false; +end; + +function tdbbooleandisp.getvaluetext: msestring; +begin + if fisnotnull then begin + result:= inherited getvaluetext; + end + else begin + result:= ''; + end; +end; + +procedure tdbbooleandisp.recchanged; +begin + fdatalink.recordchanged(nil); +end; + +procedure tdbbooleandisp.setdatalink(const avalue: tdispfielddatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbbooleandisp.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +function tdbbooleandisp.getfieldlink: tdispfielddatalink; +begin + result:= fdatalink; +end; + +{ tdbrealdisp } + +constructor tdbrealdisp.create(aowner: tcomponent); +begin + fdatalink:= tdispfielddatalink.create(idbdispfieldlink(self)); + inherited; +end; + +destructor tdbrealdisp.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tdbrealdisp.getfieldtypes(var fieldtypes: fieldtypesty); +begin + fieldtypes:= realfields; +end; + +procedure tdbrealdisp.fieldtovalue; +begin + value:= datalink.field.asfloat; +end; + +procedure tdbrealdisp.setnullvalue; +begin + value:= emptyreal; +end; + +procedure tdbrealdisp.recchanged; +begin + fdatalink.recordchanged(nil); +end; + +procedure tdbrealdisp.setdatalink(const avalue: tdispfielddatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbrealdisp.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +function tdbrealdisp.getfieldlink: tdispfielddatalink; +begin + result:= fdatalink; +end; + +{ tdbrealdisplb } + +procedure tdbrealdisplb.getfieldtypes(var fieldtypes: fieldtypesty); +begin + fieldtypes:= integerfields; +end; + +procedure tdbrealdisplb.fieldtovalue; +begin + keyvalue:= datalink.field.asinteger; +end; + +procedure tdbrealdisplb.setlookupbuffer(const avalue: tcustomlookupbuffer); +begin + setlinkedvar(avalue,tmsecomponent(flookupbuffer)); +end; + +procedure tdbrealdisplb.setkeyvalue(const avalue: integer); +var + int1: integer; +begin + fkeyvalue:= avalue; + if flookupbuffer <> nil then begin + if flookupbuffer.findphys(flookupkeyfieldno,fkeyvalue,int1) then begin + value:= flookupbuffer.floatvaluephys(flookupvaluefieldno,int1); + end + else begin + setnullvalue; + end; + end + else begin + setnullvalue; + end; +end; + +procedure tdbrealdisplb.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (event in [oe_changed,oe_connect]) and (sender = flookupbuffer) then begin + setkeyvalue(fkeyvalue); + end; +end; + +function tdbrealdisplb.getlbdatakind(const apropname: string): lbdatakindty; +begin + if apropname = 'lookupkeyfieldno' then begin + result:= lbdk_integer; + end + else begin + result:= lbdk_float; + end; +end; + +function tdbrealdisplb.getlookupbuffer: tcustomlookupbuffer; +begin + result:= flookupbuffer; +end; + +{ tdbdatetimedisp } + +constructor tdbdatetimedisp.create(aowner: tcomponent); +begin + fdatalink:= tdispfielddatalink.create(idbdispfieldlink(self)); + inherited; +end; + +destructor tdbdatetimedisp.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tdbdatetimedisp.getfieldtypes(var fieldtypes: fieldtypesty); +begin + fieldtypes:= datetimefields; +end; + +procedure tdbdatetimedisp.fieldtovalue; +var + da1: tdatetime; +begin + da1:= datalink.field.asdatetime; + value:= da1; +end; + +procedure tdbdatetimedisp.setnullvalue; +begin + value:= emptydatetime; +end; + +procedure tdbdatetimedisp.recchanged; +begin + fdatalink.recordchanged(nil); +end; + +procedure tdbdatetimedisp.setdatalink(const avalue: tdispfielddatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbdatetimedisp.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +function tdbdatetimedisp.getfieldlink: tdispfielddatalink; +begin + result:= fdatalink; +end; + +{ tdbdatetimedisplb } + +procedure tdbdatetimedisplb.getfieldtypes(var fieldtypes: fieldtypesty); +begin + fieldtypes:= integerfields; +end; + +procedure tdbdatetimedisplb.fieldtovalue; +begin + keyvalue:= datalink.field.asinteger; +end; + +procedure tdbdatetimedisplb.setlookupbuffer(const avalue: tcustomlookupbuffer); +begin + setlinkedvar(avalue,tmsecomponent(flookupbuffer)); +end; + +procedure tdbdatetimedisplb.setkeyvalue(const avalue: integer); +var + int1: integer; +begin + fkeyvalue:= avalue; + if flookupbuffer <> nil then begin + if flookupbuffer.findphys(flookupkeyfieldno,fkeyvalue,int1) then begin + value:= flookupbuffer.floatvaluephys(flookupvaluefieldno,int1); + end + else begin + setnullvalue; + end; + end + else begin + setnullvalue; + end; +end; + +procedure tdbdatetimedisplb.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (event in [oe_changed,oe_connect]) and (sender = flookupbuffer) then begin + setkeyvalue(fkeyvalue); + end; +end; + +function tdbdatetimedisplb.getlbdatakind(const apropname: string): lbdatakindty; +begin + if apropname = 'lookupkeyfieldno' then begin + result:= lbdk_integer; + end + else begin + result:= lbdk_float; + end; +end; + +function tdbdatetimedisplb.getlookupbuffer: tcustomlookupbuffer; +begin + result:= flookupbuffer; +end; + +end. diff --git a/mseide-msegui/lib/common/db/msedbedit.pas b/mseide-msegui/lib/common/db/msedbedit.pas new file mode 100644 index 0000000..daa9b13 --- /dev/null +++ b/mseide-msegui/lib/common/db/msedbedit.pas @@ -0,0 +1,12722 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} + +unit msedbedit; +{$ifdef FPC} + {$mode objfpc}{$h+}{$interfaces corba} +{$endif} +//{$ifndef mse_no_ifi} + {$define mse_with_ifi} +//{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + mdb,classes,mclasses,mseguiglob,mseclasses,msegui,msetoolbar, + mseeditglob, + mseglob,msewidgetgrid,msearrayutils,msedatalist,mseinterfaces, + msetypes,msegrids,msegraphics,mseevent,msekeyboard,mseassistiveclient, + msegraphedits,msestrings,msegraphutils,mselist,msedropdownlist, + msescrollbar,msedataedits,msewidgets,msearrayprops,msedb,mselookupbuffer, + msedialog,mseinplaceedit,msemenus,mseedit,msestat,msegridsglob,typinfo + {$ifdef mse_with_ifi},mseifiglob,mseificompglob,mseificomp{$endif}; + +type + //0 1 2 3 4 + dbnavigbuttonty = (dbnb_first,dbnb_prior,dbnb_next,dbnb_last,dbnb_insert, + // 5 6 7 + dbnb_delete,dbnb_copyrecord,dbnb_edit, + // 8 9 10 + dbnb_post,dbnb_cancel,dbnb_refresh, + // 11 12 13 14 + dbnb_filter,dbnb_filtermin,dbnb_filtermax,dbnb_filterclear, + // 15 16 + dbnb_filteronoff,dbnb_find, + // 17 18 + dbnb_autoedit,dbnb_dialog); + + dbnavigbuttonsty = set of dbnavigbuttonty; + +const + defaultdbscrollbaroptions = + (defaultthumbtrackscrollbaroptions - [sbo_showauto])+ + [sbo_show,sbo_thumbtrack]; + + defaultvisibledbnavigbuttons = + [dbnb_first,dbnb_prior,dbnb_next,dbnb_last,dbnb_insert, + dbnb_delete,dbnb_edit,dbnb_post,dbnb_cancel,dbnb_refresh]; + filterdbnavigbuttons = [dbnb_filter,dbnb_filtermin,dbnb_filtermax, + dbnb_filterclear,dbnb_find,dbnb_filteronoff]; + defaultdbnavigatorheight = 24; + defaultdbnavigatorwidth = (ord(dbnb_refresh))*defaultdbnavigatorheight; + + defaultindicatorcoloptions = [fco_mousefocus]; + + maxautodisplaywidth = 20; + +type + dbnavigatoroptionty = (dno_confirmdelete,dno_confirmcopy, + dno_append,dno_nomultiinsert,dno_shortcuthint, + dno_norefreshrecno, + dno_dialogifinactive,dno_nodialogifempty, + dno_nodialogifnoeditmode,dno_nodialogifreadonly, + dno_nonavig, //disable navigation buttons + dno_noinsert,dno_nodelete,dno_noedit, //disable buttons + dno_customdialogupdate, + dno_postbeforedialog,dno_postoncanclose, + dno_candefocuswindow); + dbnavigatoroptionsty = set of dbnavigatoroptionty; + optioneditdbty = (oed_autoedit,oed_noautoedit,oed_readonly,oed_noreadonly, + oed_autopost, + oed_nullcheckifunmodified, + oed_syncedittonavigator,oed_focusoninsert, + oed_nofilteredit,oed_nofilterminedit, + oed_nofiltermaxedit,oed_nofindedit, + oed_nonullset, //use TField.DefaultExpression for textedit + oed_nullset, //don't use TField.DefaultExpression for + //empty edit value + oed_limitcharlen); + optionseditdbty = set of optioneditdbty; + + griddatalinkoptionty = (gdo_propscrollbar,gdo_thumbtrack, + gdo_checkbrowsemodeonexit,gdo_selectautopost); + griddatalinkoptionsty = set of griddatalinkoptionty; + +const + defaultgriddatalinkoptions = [gdo_propscrollbar,gdo_thumbtrack, + gdo_selectautopost]; + defaulteditwidgetdatalinkoptions = [{oed_syncedittonavigator}]; + defaultdbnavigatoroptions = [dno_confirmdelete,dno_confirmcopy,{dno_append,} + dno_shortcuthint]; + designdbnavigbuttons = [dbnb_first,dbnb_prior,dbnb_next,dbnb_last]; + editnavigbuttons = [dbnb_insert,dbnb_delete,dbnb_edit]; + + defaultdbdropdownoptions = [deo_selectonly,deo_autodropdown,deo_keydropdown]; + defaultdropdowndatalinkoptions = [gdo_propscrollbar,gdo_thumbtrack]; + + defaulteddropdownoptions = [deo_selectonly,deo_autodropdown,deo_keydropdown]; + +type + updaterowdataeventty = procedure(const sender: tcustomgrid; + const arow: integer; const adataset: tdataset)of object; + + optiondbty = (odb_copyitems,odb_opendataset,odb_closedataset,odb_directdata); + optionsdbty = set of optiondbty; + + idbnaviglink = interface(inullinterface) + procedure setactivebuttons(const abuttons: dbnavigbuttonsty; + const afiltered: boolean); + procedure setcheckedbuttons(const abuttons: dbnavigbuttonsty; + const achecked: boolean); + function getwidget: twidget; + function getnavigoptions: dbnavigatoroptionsty; + procedure dodialogexecute; + procedure updatereadonly(const force: boolean = false); + end; + + navigdatalinkstatety = (nds_prior,nds_next,nds_datasetscrolled); + navigdatalinkstatesty = set of navigdatalinkstatety; + + tnavigdatalink = class(tmsedatalink) + private + protected + fintf: idbnaviglink; + fstate: navigdatalinkstatesty; + procedure updatebuttonstate; + procedure activechanged; override; + procedure datasetchanged; override; + procedure editingchanged; override; + procedure recordchanged(Field: TField); override; + procedure disabledstatechange; override; + procedure datasetscrolled(distance: integer) override; + function canassistive(out aintf: iassistiveclient): boolean; + public + constructor create(const intf: idbnaviglink); + procedure execbutton(const abutton: dbnavigbuttonty); + end; + + tdbnavigbutton = class(tcustomstockglyphtoolbutton) + private + procedure readtag(reader: treader); + protected + procedure defineproperties(filer: tfiler); override; + published + property imagelist; + property imagenr; + property imagenrdisabled; + property colorglyph; + property color; + property imagecheckedoffset; + property hint; + property action; + property state; + property shortcut; + property shortcut1; +// property tag; + property options; + property group; +// property onexecute; +// property onbeforeexecute; + end; + + tdbnavigbuttons = class(tstockglyphtoolbuttons) + protected + class function getbuttonclass: toolbuttonclassty; override; + end; + + tdbnavigator = class(tcustomtoolbar,idbnaviglink) + private + fdatalink: tnavigdatalink; + fvisiblebuttons: dbnavigbuttonsty; + fshortcuts: array[dbnavigbuttonty] of shortcutty; + foptions: dbnavigatoroptionsty; + fondialogexecute: notifyeventty; + fonreadonlychange: booleanchangedeventty; + fcanautoeditbefore: boolean; + function getdatasource: tdatasource; + procedure setdatasource(const Value: tdatasource); + procedure setvisiblebuttons(const avalue: dbnavigbuttonsty); + function getcolorglyph: colorty; + procedure setcolorglyph(const avalue: colorty); + procedure setoptions(const avalue: dbnavigatoroptionsty); + function getbuttonface: tface; + procedure setbuttonface(const avalue: tface); + function gettoolbutton: tdbnavigbutton; + procedure settoolbutton(const avalue: tdbnavigbutton); + function getautoedit: boolean; + procedure setautoedit(const avalue: boolean); + function getbuttonwidth: integer; + procedure setbuttonwidth(const avalue: integer); + function getbuttonheight: integer; + procedure setbuttonheight(const avalue: integer); +// function getnonavig: boolean; +// procedure setnonavig(const avalue: boolean); + protected + procedure inithints; + procedure doexecute(const sender: tobject); + procedure loaded; override; + procedure internalshortcut(var info: keyeventinfoty; const sender: twidget); + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; + procedure doasyncevent(var atag: integer); override; + procedure dostatread(const reader: tstatreader); override; + procedure dostatwrite(const writer: tstatwriter); override; + + //idbnaviglink + procedure setactivebuttons(const abuttons: dbnavigbuttonsty; + const afiltered: boolean); + procedure setcheckedbuttons(const abuttons: dbnavigbuttonsty; + const achecked: boolean); + function getnavigoptions: dbnavigatoroptionsty; + procedure dodialogexecute; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function canclose(const newfocus: twidget = nil): boolean; override; + procedure edit(); + function canautoedit(): boolean; + procedure updatereadonly(const force: boolean = false); + //call onreadonlychange +// property nonavig: boolean read getnonavig write setnonavig; + published + property statfile; + property datasource: tdatasource read getdatasource write setdatasource; + property visiblebuttons: dbnavigbuttonsty read fvisiblebuttons + write setvisiblebuttons default defaultvisibledbnavigbuttons; + property colorglyph: colorty read getcolorglyph write setcolorglyph + default cl_default; + property buttonface: tface read getbuttonface write setbuttonface; + property buttonwidth: integer read getbuttonwidth write setbuttonwidth + default 0; + property buttonheight: integer read getbuttonheight write setbuttonheight + default 0; + property bounds_cx default defaultdbnavigatorwidth; + property bounds_cy default defaultdbnavigatorheight; + property shortcut_first: shortcutty read fshortcuts[dbnb_first] + write fshortcuts[dbnb_first] default key_modctrl + ord(key_pageup); + property shortcut_prior: shortcutty read fshortcuts[dbnb_prior] + write fshortcuts[dbnb_prior] default ord(key_pageup); + property shortcut_next: shortcutty read fshortcuts[dbnb_next] + write fshortcuts[dbnb_next] default ord(key_pagedown); + property shortcut_last: shortcutty read fshortcuts[dbnb_last] + write fshortcuts[dbnb_last] default key_modctrl + ord(key_pagedown); + property shortcut_insert: shortcutty read fshortcuts[dbnb_insert] + write fshortcuts[dbnb_insert] default ord(key_none); + property shortcut_delete: shortcutty read fshortcuts[dbnb_delete] + write fshortcuts[dbnb_delete] default ord(key_none); + property shortcut_copyrecord: shortcutty read fshortcuts[dbnb_copyrecord] + write fshortcuts[dbnb_copyrecord] default ord(key_none); + property shortcut_edit: shortcutty read fshortcuts[dbnb_edit] + write fshortcuts[dbnb_edit] default ord(key_f2); + property shortcut_post: shortcutty read fshortcuts[dbnb_post] + write fshortcuts[dbnb_post] default ord(key_f2); + property shortcut_cancel: shortcutty read fshortcuts[dbnb_cancel] + write fshortcuts[dbnb_cancel] default ord(key_none); + property shortcut_refresh: shortcutty read fshortcuts[dbnb_refresh] + write fshortcuts[dbnb_refresh] default ord(key_none); + property shortcut_filter: shortcutty read fshortcuts[dbnb_filter] + write fshortcuts[dbnb_filter] default ord(key_none); + property shortcut_filtermin: shortcutty read fshortcuts[dbnb_filtermax] + write fshortcuts[dbnb_filtermin] default ord(key_none); + property shortcut_filtermax: shortcutty read fshortcuts[dbnb_filtermax] + write fshortcuts[dbnb_filtermax] default ord(key_none); + property shortcut_filteronoff: shortcutty read fshortcuts[dbnb_filteronoff] + write fshortcuts[dbnb_filteronoff] default ord(key_none); + property shortcut_find: shortcutty read fshortcuts[dbnb_find] + write fshortcuts[dbnb_find] default ord(key_none); + property shortcut_autoedit: shortcutty read fshortcuts[dbnb_autoedit] + write fshortcuts[dbnb_autoedit] default ord(key_none); +// property shortcut_dialog: shortcutty read fshortcuts[dbnb_dialog] +// write fshortcuts[dbnb_dialog] default ord(key_f3); + //use dialogbutton property! + property options: dbnavigatoroptionsty read foptions write setoptions + default defaultdbnavigatoroptions; + property autoedit: boolean read getautoedit write setautoedit default false; +// property dialoghint: msestring read getdialoghint write setdialoghint; +// + property dialogbutton: tdbnavigbutton read gettoolbutton write settoolbutton; + property ondialogexecute: notifyeventty read fondialogexecute + write fondialogexecute; + property onreadonlychange: booleanchangedeventty read fonreadonlychange + write fonreadonlychange; + end; + + tcustomeditwidgetdatalink = class; + + idbeditfieldlink = interface(inullinterface)[miid_idbeditfieldlink] + function getwidget: twidget; + function getenabled: boolean; + procedure setenabled(const avalue: boolean); + function getgridintf: iwidgetgrid; + function getgriddatasource: tdatasource; + function getedited: boolean; + function seteditfocus: boolean; + procedure initeditfocus; + function checkvalue(const quiet: boolean = false): boolean; + procedure valuetofield; + procedure fieldtovalue; + procedure setnullvalue; + function getoptionsedit: optionseditty; + procedure updatereadonlystate; + procedure getfieldtypes(var afieldtypes: fieldtypesty); //[] = all + function geteditstate: dataeditstatesty; + procedure seteditstate(const avalue: dataeditstatesty); +// procedure setisdb; + procedure setmaxlength(const avalue: integer); + function getfieldlink: tcustomeditwidgetdatalink; + //iificlient + procedure setifiserverintf(const aintf: iifiserver); + end; + + tgriddatalink = class; + +// editwidgetdatalinkstatety = (ewds_editing,ewds_modified,ewds_filterediting, +// ewds_filtereditdisabled); +// editwidgetdatalinkstatesty = set of editwidgetdatalinkstatety; + + tcustomeditwidgetdatalink = class(tfielddatalink,idbeditinfo,iobjectlink) + private +// fstate: editwidgetdatalinkstatesty; + frecordchange: integer; + fbeginedit: integer; + fmaxlength: integer; + fposting: integer; + fonbeginedit: notifyeventty; + fonendedit: notifyeventty; + fondataentered: notifyeventty; + fnavigator: tdbnavigator; + function canmodify: boolean; + procedure setediting(avalue: boolean); + function getasnullmsestring: msestring; + procedure setasnullmsestring(const avalue: msestring); + procedure readdatasource(reader: treader); + procedure readdatafield(reader: treader); + procedure readoptionsdb(reader: treader); + function getownerwidget: twidget; + procedure setnavigator(const avalue: tdbnavigator); + procedure setoptions(const avalue: optionseditdbty); + protected + fintf: idbeditfieldlink; + foptions: optionseditdbty; + fobjectlinker: tobjectlinker; + function datasourcereadonly(): boolean override; + function getobjectlinker: tobjectlinker; + function getdatasource1: tdatasource; + procedure dataevent(event: tdataevent; info: ptrint); override; + procedure activechanged; override; + procedure editingchanged; override; + procedure focuscontrol(afield: tfieldref); override; + procedure updatedata; override; + procedure disabledstatechange; override; + procedure fieldchanged; override; + procedure bindingchanged; + procedure objectevent(const sender: tobject; const event: objecteventty); virtual; + //iobjectlink + procedure link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); + procedure unlink(const source,dest: iobjectlink; valuepo: pointer = nil); + procedure objevent(const sender: iobjectlink; const event: objecteventty); + function getinstance: tobject; + //idbeditinfo + function getdataset(const aindex: integer): tdataset; + procedure getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); virtual; + //iifiserver + procedure updateoptionsedit(var avalue: optionseditty); override; + procedure valuechanged(const sender: iifidatalink); override; + public + constructor create(const intf: idbeditfieldlink); + destructor destroy; override; + procedure fixupproperties(filer: tfiler); //read moved properties + procedure recordchanged(afield: tfield); override; + procedure datasetscrolled(distance: integer) override; + procedure nullcheckneeded(var avalue: boolean); + procedure setwidgetdatasource(const avalue: tdatasource); + procedure griddatasourcechanged; + function edit: Boolean; + procedure modified; + procedure doshortcut(var info: keyeventinfoty; const sender: twidget); + +// procedure datachanged; +// procedure updateoptionsedit(var aoptions: optionseditty); + function cuttext(const atext: msestring; out maxlength: integer): boolean; + //true if text too long + property options: optionseditdbty read foptions write setoptions + default defaulteditwidgetdatalinkoptions; + property asnullmsestring: msestring read getasnullmsestring + write setasnullmsestring; + //uses nulltext + property navigator: tdbnavigator read fnavigator write setnavigator; + property onbeginedit: notifyeventty read fonbeginedit write fonbeginedit; + property onendedit: notifyeventty read fonendedit write fonendedit; + property ondataentered: notifyeventty read fondataentered + write fondataentered; + property owner: twidget read getownerwidget; + end; + + teditwidgetdatalink = class(tcustomeditwidgetdatalink) + private + published + property datasource: tdatasource read getdatasource1 + write setwidgetdatasource; + property navigator; + property fieldname; + property options; + property onbeginedit; + property onendedit; + property ondataentered; + end; + + tlookupeditdatalink = class(teditwidgetdatalink) + private + ffieldnametext: string; + ffieldtext: tfield; + procedure setfieldnametext(const avalue: string); + protected + fowner: tcustomdataedit; + fdatatype: lookupdatatypety; + procedure updatefields; override; + function getsortfield: tfield; override; + property fieldtext: tfield read ffieldtext; + procedure getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); override; + public + constructor create(const aowner: tcustomdataedit; + const adatatype: lookupdatatypety; + const intf: idbeditfieldlink); + function msedisplaytext(const aformat: msestring = ''; + const aedit: boolean = false): msestring; override; + published + property fieldnametext: string read ffieldnametext write setfieldnametext; + end; + + tstringeditwidgetdatalink = class(teditwidgetdatalink) + published + property nullsymbol; + end; + + tstringlookupeditdatalink = class(tlookupeditdatalink) + published + property nullsymbol; + end; + + tdbstringedit = class(tcustomstringedit,idbeditfieldlink,ireccontrol) + private + fdatalink: tstringeditwidgetdatalink; + procedure setdatalink(const adatalink: tstringeditwidgetdatalink); + protected + procedure defineproperties(filer: tfiler); override; +// procedure editnotification(var info: editnotificationinfoty); override; + function nullcheckneeded(const newfocus: twidget): boolean; override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + procedure modified; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; +// function getoptionsedit: optionseditty; override; +// procedure dochange; override; +// procedure doenter; override; +// procedure doexit; override; + + function getrowdatapo(const arow: integer): pointer; override; + function getnulltext: msestring; override; + //idbeditfieldlink + procedure valuetofield; + procedure fieldtovalue; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + function getfieldlink: tcustomeditwidgetdatalink; + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: tstringeditwidgetdatalink read fdatalink write setdatalink; + property passwordchar; + property maxlength; + property onsetvalue; + end; + + +{ + tdbdialogstringedit = class(tcustomdialogstringedit,idbeditfieldlink,ireccontrol) + private + fdatalink: tstringeditwidgetdatalink; + procedure setdatalink(const avalue: tstringeditwidgetdatalink); + protected + procedure defineproperties(filer: tfiler); override; + + function nullcheckneeded(const newfocus: twidget): boolean; override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + procedure modified; override; + function getoptionsedit: optionseditty; override; + procedure dochange; override; + + function getrowdatapo(const info: cellinfoty): pointer; override; + function getnulltext: msestring; override; + + //idbeditfieldlink + procedure valuetofield; + procedure fieldtovalue; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: tstringeditwidgetdatalink read fdatalink write setdatalink; + property passwordchar; + property maxlength; + property onsetvalue; + property onexecute; + end; +} + idbifidropdownlistdatalink = interface(iifidropdownlistdatalink) + end; + + tcustomdbdropdownlistedit = class(tcustomdropdownlistedit,idbeditfieldlink, + ireccontrol,idbifidropdownlistdatalink) + private + fdatalink: tstringeditwidgetdatalink; + fdropdownifilink: tifidropdownlistlinkcomp; + fdropdownifiserverintf: iifiserver; + procedure setdatalink(const avalue: tstringeditwidgetdatalink); + function getdropdownifilink: tifidropdownlistlinkcomp; + procedure setdropdownifilink(const avalue: tifidropdownlistlinkcomp); + procedure dropdownsetifiserverintf(const aintf: iifiserver); + procedure idbifidropdownlistdatalink.setifiserverintf = + dropdownsetifiserverintf; + procedure dropdownifisetvalue(var avalue; var accept: boolean); + procedure idbifidropdownlistdatalink.ifisetvalue = dropdownifisetvalue; + protected + procedure defineproperties(filer: tfiler); override; + + function nullcheckneeded(const newfocus: twidget): boolean; override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + procedure modified; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; +// function getoptionsedit: optionseditty; override; +// procedure dochange; override; +// procedure doenter; override; +// procedure doexit; override; + function getrowdatapo(const arow: integer): pointer; override; + function getnulltext: msestring; override; + //idbeditfieldlink + procedure valuetofield; + procedure fieldtovalue; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + function getfieldlink: tcustomeditwidgetdatalink; + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property datalink: tstringeditwidgetdatalink read fdatalink write setdatalink; + property dropdownifilink: tifidropdownlistlinkcomp read getdropdownifilink + write setdropdownifilink; //for dropdownlist + end; + + idbdropdownlist = interface(idropdownlist) + procedure recordselected(const arecordnum: integer; const akey: keyty); + //-2 = empty row, -1 = none + end; + + ilbdropdownlist = interface(idropdownlist) + procedure recordselected(const arecordnum: integer; const akey: keyty); + //-2 = empty row, -1 = none + function getlbkeydatakind: lbdatakindty; + end; + + tdbdropdownlistedit = class(tcustomdbdropdownlistedit) + published + property datalink; + property dropdown; + property dropdownifilink; + property onsetvalue; + property onbeforedropdown; + property onafterclosedropdown; + end; + + tcustomdbdropdownlistcontroller = class; +// tdbdropdownlistcontroller = class; + tdropdownlistcontrollerdb = class; + tcustomlbdropdownlistcontroller = class; + tdropdownlistcontrollerlb = class; + + tdbdropdownlisteditdb = class(tdbdropdownlistedit,idbdropdownlist) + private + function getdropdown: tdropdownlistcontrollerdb; + procedure setdropdown(const avalue: tdropdownlistcontrollerdb); + protected + function createdropdowncontroller: tcustomdropdowncontroller; override; + procedure recordselected(const arecordnum: integer; const akey: keyty); + published + property dropdown: tdropdownlistcontrollerdb read getdropdown + write setdropdown; + end; + + tdbdropdownlisteditlb = class(tdbdropdownlistedit,ilbdropdownlist) + private + function getdropdown: tdropdownlistcontrollerlb; + procedure setdropdown(const avalue: tdropdownlistcontrollerlb); + protected + function createdropdowncontroller: tcustomdropdowncontroller; override; + procedure recordselected(const arecordnum: integer; const akey: keyty); + //ilbdropdownlist + function getlbkeydatakind: lbdatakindty; + published + property dropdown: tdropdownlistcontrollerlb read getdropdown + write setdropdown; + end; + + tdropdownlisteditdb = class(tdropdownlistedit,idbdropdownlist) + private + function getdropdown: tdropdownlistcontrollerdb; + procedure setdropdown(const avalue: tdropdownlistcontrollerdb); + protected + function createdropdowncontroller: tcustomdropdowncontroller; override; + procedure recordselected(const arecordnum: integer; const akey: keyty); + published + property dropdown: tdropdownlistcontrollerdb read getdropdown write setdropdown; + end; + + tdropdownlisteditlb = class(tdropdownlistedit,ilbdropdownlist) + private + function getdropdown: tdropdownlistcontrollerlb; + procedure setdropdown(const avalue: tdropdownlistcontrollerlb); + protected + function createdropdowncontroller: tcustomdropdowncontroller; override; + procedure recordselected(const arecordnum: integer; const akey: keyty); + //ilbdropdownlist + function getlbkeydatakind: lbdatakindty; + published + property dropdown: tdropdownlistcontrollerlb read getdropdown + write setdropdown; + end; + + tdbkeystringedit = class(tcustomkeystringedit,idbeditfieldlink,ireccontrol) + private + fdatalink: tstringlookupeditdatalink; + procedure setdatalink(const avalue: tstringlookupeditdatalink); + protected + procedure defineproperties(filer: tfiler); override; + function nullcheckneeded(const newfocus: twidget): boolean; override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + procedure modified; override; +// function getoptionsedit: optionseditty; override; +// procedure dochange; override; +// procedure doenter; override; +// procedure doexit; override; + function getrowdatapo(const arow: integer): pointer; override; + function getnulltext: msestring; override; + //idbeditfieldlink + procedure valuetofield; + procedure fieldtovalue; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + function getfieldlink: tcustomeditwidgetdatalink; + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: tstringlookupeditdatalink read fdatalink + write setdatalink; + property dropdown; + property valuedefault; + property onsetvalue; + property onbeforedropdown; + property onafterclosedropdown; + property oninit; + end; + + tdbmemoedit = class(tcustommemoedit,idbeditfieldlink,ireccontrol) + private + fdatalink: tstringeditwidgetdatalink; + procedure setdatalink(const avalue: tstringeditwidgetdatalink); + protected + procedure defineproperties(filer: tfiler); override; + + function nullcheckneeded(const newfocus: twidget): boolean; override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + procedure modified; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; +// function getoptionsedit: optionseditty; override; +// procedure dochange; override; +// procedure doenter; override; +// procedure doexit; override; + function getrowdatapo(const arow: integer): pointer; override; + function getnulltext: msestring; override; + //idbeditfieldlink + procedure valuetofield; + procedure fieldtovalue; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + function getfieldlink: tcustomeditwidgetdatalink; + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: tstringeditwidgetdatalink read fdatalink write setdatalink; + property onsetvalue; + property frame; + end; + + tdbintegeredit = class(tcustomintegeredit,idbeditfieldlink,ireccontrol) + private + fdatalink: teditwidgetdatalink; + procedure setdatalink(const avalue: teditwidgetdatalink); + protected + procedure defineproperties(filer: tfiler); override; + + function nullcheckneeded(const newfocus: twidget): boolean; override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + procedure modified; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; +// function getoptionsedit: optionseditty; override; +// procedure dochange; override; +// procedure doenter; override; +// procedure doexit; override; + function internaldatatotext(const data): msestring; override; + procedure texttovalue(var accept: boolean; const quiet: boolean); override; +// procedure setnullvalue; override; + function getrowdatapo(const arow: integer): pointer; override; + //idbeditfieldlink + procedure valuetofield; + procedure fieldtovalue; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + function getfieldlink: tcustomeditwidgetdatalink; + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property isnull: boolean read fisnull; + published + property datalink: teditwidgetdatalink read fdatalink write setdatalink; + property base; + property bitcount; + property valuemin; + property valuemax; + property onsetvalue; + end; + + tdbbooleanedit = class(tcustombooleanedit,idbeditfieldlink,ireccontrol) + private + fdatalink: teditwidgetdatalink; + procedure setdatalink(const avalue: teditwidgetdatalink); + protected + procedure defineproperties(filer: tfiler); override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + function checkvalue(const quiet: boolean = false): boolean; reintroduce; +// procedure dochange; override; +// procedure doenter; override; +// procedure doexit; override; + procedure modified; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; +// function getoptionsedit: optionseditty; override; + function getrowdatapo(const arow: integer): pointer; override; + //idbeditfieldlink + procedure valuetofield; + procedure fieldtovalue; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + procedure setmaxlength(const avalue: integer); + function getfieldlink: tcustomeditwidgetdatalink; + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: teditwidgetdatalink read fdatalink write setdatalink; + property onsetvalue; + property bounds_cx default defaultboxsize; + property bounds_cy default defaultboxsize; + property group; + end; + + tdbdataicon = class(tcustomdataicon,idbeditfieldlink,ireccontrol) + private + fdatalink: teditwidgetdatalink; + procedure setdatalink(const avalue: teditwidgetdatalink); + protected + procedure defineproperties(filer: tfiler); override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + function checkvalue(const quiet: boolean = false): boolean; reintroduce; + procedure modified; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; +// procedure dochange; override; +// procedure doenter; override; +// procedure doexit; override; +// function getoptionsedit: optionseditty; override; + function getrowdatapo(const arow: integer): pointer; override; + //idbeditfieldlink + procedure valuetofield; + procedure fieldtovalue; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + procedure setmaxlength(const avalue: integer); + function getfieldlink: tcustomeditwidgetdatalink; + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: teditwidgetdatalink read fdatalink write setdatalink; + property onsetvalue; + property onpaintglyph; + property valuemin; + property valuemax; + property imagelist; + property imageoffset; + property imagenums; + end; + + tdbdatabutton = class(tcustomdatabutton,idbeditfieldlink,ireccontrol) + private + fdatalink: teditwidgetdatalink; + procedure setdatalink(const avalue: teditwidgetdatalink); + protected + procedure defineproperties(filer: tfiler); override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + function checkvalue(const quiet: boolean = false): boolean; reintroduce; +// procedure dochange; override; +// procedure doenter; override; +// procedure doexit; override; + procedure modified; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; +// function getoptionsedit: optionseditty; override; + function getrowdatapo(const arow: integer): pointer; override; + //idbeditfieldlink + procedure valuetofield; + procedure fieldtovalue; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + procedure setmaxlength(const avalue: integer); + function getfieldlink: tcustomeditwidgetdatalink; + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: teditwidgetdatalink read fdatalink write setdatalink; + property optionswidget; + property optionsskin; + property valuefaces; + property valuecaptions; + property valuefonts; + property font; + property action; + property caption; + property imagepos; + property shortcut; + property shortcut1; + property textflags; + property captiondist; + property imagelist; + property imagenr; + property imagenrdisabled; + property imagedist; + property imagedist1; + property imagedist2; + property colorglyph; + property options; + property focusrectdist; + property onupdate; + property onexecute; + property onbeforeexecute; + property onafterexecute; + property onmouseevent; + property onclientmouseevent; + + property imageoffset; + property imageoffsetdisabled; + property imageoffsetmouse; + property imageoffsetclicked; + property imagenums; + property onsetvalue; + property onpaintglyph; + property valuedefault; + property valuemin; + property valuemax; + property valuedisabled; + end; + + tdbbooleaneditradio = class(tcustombooleaneditradio,idbeditfieldlink,ireccontrol) + private + fdatalink: teditwidgetdatalink; + procedure setdatalink(const avalue: teditwidgetdatalink); + protected + procedure defineproperties(filer: tfiler); override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + function checkvalue(const quiet: boolean = false): boolean; reintroduce; + function docheckvalue(var avalue; const quiet: boolean): boolean; override; +// procedure dochange; override; +// procedure doenter; override; +// procedure doexit; override; + procedure modified; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; +// function getoptionsedit: optionseditty; override; + function getrowdatapo(const arow: integer): pointer; override; + //idbeditfieldlink + procedure valuetofield; + procedure fieldtovalue; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + procedure setmaxlength(const avalue: integer); + function getfieldlink: tcustomeditwidgetdatalink; + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: teditwidgetdatalink read fdatalink write setdatalink; + property onsetvalue; + property bounds_cx default defaultboxsize; + property bounds_cy default defaultboxsize; + property group; + end; + + tdbrealedit = class(tcustomrealedit,idbeditfieldlink,ireccontrol) + private + fdatalink: teditwidgetdatalink; + procedure setdatalink(const avalue: teditwidgetdatalink); + protected + procedure defineproperties(filer: tfiler); override; + function nullcheckneeded(const newfocus: twidget): boolean; override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + procedure modified; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; +// function getoptionsedit: optionseditty; override; +// procedure dochange; override; +// procedure doenter; override; +// procedure doexit; override; + function getrowdatapo(const arow: integer): pointer; override; + //idbeditfieldlink + procedure valuetofield; + procedure fieldtovalue; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + function getfieldlink: tcustomeditwidgetdatalink; + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: teditwidgetdatalink read fdatalink write setdatalink; + property valuemin {stored false}; + property valuemax {stored false}; + property formatedit; + property formatdisp; + property valuerange; + property valuestart; + property onsetvalue; + property onsetintvalue; + end; + + tdbrealspinedit = class(tcustomrealspinedit,idbeditfieldlink,ireccontrol) + private + fdatalink: teditwidgetdatalink; + procedure setdatalink(const avalue: teditwidgetdatalink); + protected + procedure defineproperties(filer: tfiler); override; + function nullcheckneeded(const newfocus: twidget): boolean; override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + procedure modified; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; +// function getoptionsedit: optionseditty; override; +// procedure dochange; override; +// procedure doenter; override; +// procedure doexit; override; + function getrowdatapo(const arow: integer): pointer; override; + //idbeditfieldlink + procedure valuetofield; + procedure fieldtovalue; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + function getfieldlink: tcustomeditwidgetdatalink; + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: teditwidgetdatalink read fdatalink write setdatalink; + property valuemin {stored false}; + property valuemax {stored false}; + property formatedit; + property formatdisp; + property valuerange; + property valuestart; + property onsetvalue; + property onsetintvalue; + property step; + end; + + tdbslider = class(tcustomslider,idbeditfieldlink,ireccontrol) + private + fdatalink: teditwidgetdatalink; + fvaluerange: real; + fvaluestart: real; + procedure setdatalink(const avalue: teditwidgetdatalink); + procedure readvaluescale(reader: treader); + protected + procedure defineproperties(filer: tfiler); override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; +// function getoptionsedit: optionseditty; override; +// procedure dochange; override; +// procedure doenter; override; +// procedure doexit; override; + procedure modified; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; + function getrowdatapo(const arow: integer): pointer; override; + //idbeditfieldlink + procedure valuetofield; + procedure fieldtovalue; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + procedure setmaxlength(const avalue: integer); + function getfieldlink: tcustomeditwidgetdatalink; + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function checkvalue(const quiet: boolean = false): boolean; reintroduce; + published + property valuerange: real read fvaluerange write fvaluerange; + property valuestart: real read fvaluestart write fvaluestart; + property datalink: teditwidgetdatalink read fdatalink write setdatalink; + property scrollbar; + property onsetvalue; + property direction; + property onpaintglyph; + end; + + tdbprogressbar = class(tcustomprogressbar,idbeditfieldlink,ireccontrol) + private + fdatalink: teditwidgetdatalink; + procedure setdatalink(const avalue: teditwidgetdatalink); + protected + procedure defineproperties(filer: tfiler); override; + function getrowdatapo(const arow: integer): pointer; override; + procedure griddatasourcechanged; override; + //idbeditfieldlink + procedure valuetofield; + procedure fieldtovalue; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + function checkvalue(const quiet: boolean = false): boolean; reintroduce; + procedure setmaxlength(const avalue: integer); + function getfieldlink: tcustomeditwidgetdatalink; + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: teditwidgetdatalink read fdatalink write setdatalink; + property onpaintglyph; + end; + + tdbdatetimeedit = class(tcustomdatetimeedit,idbeditfieldlink,ireccontrol) + private + fdatalink: teditwidgetdatalink; + procedure setdatalink(const avalue: teditwidgetdatalink); + protected + procedure defineproperties(filer: tfiler); override; + function nullcheckneeded(const newfocus: twidget): boolean; override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + procedure modified; override; +// function getoptionsedit: optionseditty; override; +// procedure dochange; override; +// procedure doenter; override; +// procedure doexit; override; + function getrowdatapo(const arow: integer): pointer; override; + //idbeditfieldlink + procedure valuetofield; + procedure fieldtovalue; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + function getfieldlink: tcustomeditwidgetdatalink; + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: teditwidgetdatalink read fdatalink write setdatalink; + property valuemin {stored false}; + property valuemax {stored false}; + property formatedit; + property formatdisp; + property kind; + property options; + property onsetvalue; + end; + + tcustomdbenumedit = class(tcustomenumedit,idbeditfieldlink,ireccontrol, + idbifidropdownlistdatalink) + private + fdatalink: tlookupeditdatalink; + fdropdownifilink: tifienumlinkcomp; + fdropdownifiserverintf: iifiserver; + procedure setdatalink(const avalue: tlookupeditdatalink); + function getdropdownifilink: tifienumlinkcomp; + procedure setdropdownifilink(const avalue: tifienumlinkcomp); + procedure dropdownsetifiserverintf(const aintf: iifiserver); + procedure idbifidropdownlistdatalink.setifiserverintf = + dropdownsetifiserverintf; + procedure dropdownifisetvalue(var avalue; var accept: boolean); + procedure idbifidropdownlistdatalink.ifisetvalue = dropdownifisetvalue; + protected + procedure defineproperties(filer: tfiler); override; + function nullcheckneeded(const newfocus: twidget): boolean; override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + procedure modified; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; +// function getoptionsedit: optionseditty; override; +// procedure dochange; override; +// procedure doenter; override; +// procedure doexit; override; + function getrowdatapo(const arow: integer): pointer; override; + //idbeditfieldlink + procedure valuetofield; virtual; + procedure fieldtovalue; virtual; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + function getfieldlink: tcustomeditwidgetdatalink; + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property datalink: tlookupeditdatalink read fdatalink write setdatalink; + property dropdownifilink: tifienumlinkcomp read getdropdownifilink + write setdropdownifilink; //for dropdownlist + end; + + tdbenumedit = class(tcustomdbenumedit) + published + property valueoffset; //before value + property datalink; + property dropdown; + property dropdownifilink; + property valuedefault; + property valueempty; + property base; + property bitcount; + property valuemin; + property valuemax; + property onsetvalue; + property onbeforedropdown; + property onafterclosedropdown; + property oninit; + end; + + tdbbooleantextedit = class(tcustomdbenumedit) + private + ftext_false: msestring; + ftext_true: msestring; + function getvalue: boolean; + procedure setvalue(const avalue: boolean); + procedure settext_false(const avalue: msestring); + procedure settext_true(const avalue: msestring); + procedure booltextchanged; + protected + function getrowdatapo(const arow: integer): pointer; override; + //idbeditfieldlink + procedure valuetofield; override; + procedure fieldtovalue; override; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + public + constructor create(aowner: tcomponent); override; + property value: boolean read getvalue write setvalue; + published + property text_false: msestring read ftext_false write settext_false; + property text_true: msestring read ftext_true write settext_true; + property datalink; + property valuedefault; + property onsetvalue; + end; + + tnolistdropdowncol = class(tdropdowncol) + end; + + tnolistdropdowncols = class(tdropdowncols) + end; + + tdbdropdowncol = class(tnolistdropdowncol,idbeditinfo) + private + fdatafield: string; + procedure setdatafield(const avalue: string); + protected + //idbeditinfo + function getdataset(const aindex: integer): tdataset; + procedure getfieldtypes(out propertynames: stringarty; + out fieldtypes: fieldtypesarty); + published + property datafield: string read fdatafield write setdatafield; + end; + + tdbdropdowncols = class(tnolistdropdowncols) + private + function getitems(const index: integer): tdbdropdowncol; + protected + function getcolclass: dropdowncolclassty; override; + public + property items[const index: integer]: tdbdropdowncol read getitems; default; + end; + + tdropdownlistdatalink = class; + + dropdowndatalinkstatety = (ddlnks_lookupvalid); + dropdowndatalinkstatesty = set of dropdowndatalinkstatety; + + tdropdowndatalink = class(tmsedatalink) + private + fowner: tcustomdbdropdownlistcontroller; + fvaluefield: tfield; + fvaluefieldname: string; + ftextfield: tfield; + procedure setvaluefield(value: tfield); + procedure setvaluefieldname(const value: string); + procedure settextfield(value: tfield); + procedure updatefields; + procedure updatelookupvalue; + function getvalueasmsestring: msestring; + function getvalueasinteger: integer; + function getvalueaslargeint: int64; + function gettextasmsestring: msestring; + protected + fdataintf: idbdata; + fkeyindex: integer; + ftextindex: integer; + flookuptext: msestring; + flastintegerkey: integer; + flastint64key: int64; + flaststringkey: msestring; + fstate: dropdowndatalinkstatesty; + procedure layoutchanged; override; + procedure activechanged; override; + procedure editingchanged; override; + public + constructor create(const aowner: tcustomdbdropdownlistcontroller); + function getlookuptext(const key: integer): msestring; overload; + function getlookuptext(const key: int64): msestring; overload; + function getlookuptext(const key: msestring): msestring; overload; + property valuefieldName: string read fvaluefieldname write setvaluefieldname; + property valuefield: tfield read fvaluefield; + property valueasmsestring: msestring read getvalueasmsestring; + property valueasinteger: integer read getvalueasinteger; + property valueaslargeint: int64 read getvalueaslargeint; + property textfield: tfield read ftextfield; + property textasmsestring: msestring read gettextasmsestring; + end; + + tdbdropdownstringcol = class(tdropdownstringcol) + private + fdatalink: tfielddatalink; + protected + function getrowtext(const arow: integer): msestring; override; + public + constructor create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); override; + destructor destroy; override; + end; + + igriddatalink = interface(inullinterface)[miid_iggriddatalink] + function getdbindicatorcol: integer; + procedure setnavigator(const avalue: tdbnavigator); + function getdatalink(): tgriddatalink; + end; + + gridrowinfoty = record + row: integer; + end; + + griddatalinkstatety = (gdls_hasrowstatefield,gdls_booleanmerged, + gdls_booleanselected); + griddatalinkstatesty = set of griddatalinkstatety; + + tgriddatalink = class(tfieldsdatalink,ievent,idbeditinfo,iobjectlink) + private + fintf: igriddatalink; + fgrid: tcustomgrid; + factiverecordbefore: integer; + ffirstrecordshift: integer; + fzebraoffset: integer; + ffirstrecordbefore: integer; + fdatasetstatebefore: tdatasetstate; + fdummystringbuffer: ansistring; + fansistringbuffer: ansistring; + fstringbuffer: msestring; + fintegerbuffer: integer; + fint64buffer: int64; + frealtybuffer: realty; + fgridinvalidated: boolean; + fstate: griddatalinkstatesty; + foptions: griddatalinkoptionsty; + fonupdaterowdata: updaterowdataeventty; + fnullchecking: integer; + fdatasetchangedlock: integer; + fobjectlinker: tobjectlinker; +// fcolordatalink: tfielddatalink; +// ffontdatalink: tfielddatalink; + frowexited: integer; + feditingbefore: boolean; + fautoinserting: boolean; + finserting: boolean; + finsertingbefore: boolean; + fonbeginedit: notifyeventty; + fonendedit: notifyeventty; + ffield_state: tfield; + ffieldname_state: string; + ffield_color: tfield; + ffieldname_color: string; + ffield_font: tfield; + ffieldname_font: string; + ffield_readonly: tfield; + ffieldname_readonly: string; + ffield_merged: tfield; + ffieldname_merged: string; + ffield_selected: tfield; + ffieldname_selected: string; + fnavigator: tdbnavigator; + fdescend: boolean; + fsortdatalink: tfielddatalink; + fmovebydistance: int32; + procedure checkzebraoffset; + procedure checkscroll; + procedure checkscrollbar; virtual; + procedure doupdaterowdata(const row: integer); + procedure beginnullchecking; + procedure endnullchecking; + procedure setfieldname_state(const avalue: string); + procedure forcecalcrange; + function getobjectlinker: tobjectlinker; + function updateoptionsgrid(const avalue: optionsgridty): optionsgridty; + function updatesortfield(const avalue: tfielddatalink; + const adescend: boolean): boolean; + //iobjectlink + procedure link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); + procedure unlink(const source,dest: iobjectlink; valuepo: pointer = nil); virtual; + procedure objevent(const sender: iobjectlink; const event: objecteventty); virtual; + function getinstance: tobject; + //ievent + procedure receiveevent(const event: tobjectevent); + //idbeditinfo + function getdataset(const aindex: integer): tdataset; + procedure getfieldtypes(out propertynames: stringarty; + out fieldtypes: fieldtypesarty); + function getdatasource1: tdatasource; + procedure settadasource1(const avalue: tdatasource); + procedure setfield_state(const avalue: tfield); + procedure setfield_color(const avalue: tfield); + procedure setfield_font(const avalue: tfield); + procedure setfield_readonly(const avalue: tfield); + procedure setfield_merged(const avalue: tfield); + procedure setfield_selected(const avalue: tfield); + procedure readdatafield(reader: treader); + procedure setfieldname_merged(const avalue: string); + procedure setfieldname_selected(const avalue: string); + procedure setfieldname_color(const avalue: string); + procedure setfieldname_font(const avalue: string); + procedure setfieldname_readonly(const avalue: string); + procedure setnavigator(const avalue: tdbnavigator); + protected + function canautoinsert: boolean; + procedure checkdelayedautoinsert; + function checkvalue: boolean; + procedure updatelayout; + procedure updaterowcount; + function begingridrow(const arow: integer; + out ainfo: gridrowinfoty): boolean; + //false if row invalid + procedure endgridrow(const ainfo: gridrowinfoty); + function getfirstrecord: integer; virtual; + procedure checkactiverecord; virtual; + function getrecordcount: integer; override; + procedure datasetscrolled(distance: integer); override; + procedure fieldchanged; override; + procedure activechanged; override; + procedure editingchanged; override; + procedure recordchanged(afield: tfield); override; + procedure datasetchanged; override; + procedure updatedata; override; + procedure updatefields; override; + procedure focuscell(var cell: gridcoordty); virtual; + procedure cellevent(var info: celleventinfoty); virtual; + procedure invalidateindicator; + function scrollevent(sender: tcustomscrollbar; + event: scrolleventty): boolean; virtual; + //true if processed + procedure doinsertrow; + procedure doappendrow; + procedure dodeleterow; + procedure rowdown; + procedure lastrow; + procedure firstrow; + function getzebrastart: integer; + procedure gridinvalidate; + function arecord: integer; + function hasdata: boolean; + procedure readdatasource(reader: treader); + procedure fixupproperties(filer: tfiler); //read moved properties + procedure defineproperties(filer: tfiler); override; + public + constructor create(const aowner: tcustomgrid; const aintf: igriddatalink); + destructor destroy; override; + property firstrecord: integer read getfirstrecord; + function getdummystringbuffer: pansistring; + function getrowfieldisnull(const afield: tfield; const row: integer): boolean; + function getansistringbuffer(const afield: tfield; const row: integer): pointer; + function getstringbuffer(const afield: tfield; const row: integer): pointer; + function getdisplaystringbuffer(const afield: tfield; const row: integer{; + const aedit: boolean}): pointer; + function getbooleanbuffer(const afield: tfield; const row: integer): pointer; + function getintegerbuffer(const afield: tfield; const row: integer): pointer; + function getint64buffer(const afield: tfield; const row: integer): pointer; + function getrealtybuffer(const afield: tfield; const row: integer): pointer; + function getdatetimebuffer(const afield: tfield; const row: integer): pointer; + function canclose(const newfocus: twidget): boolean; + procedure painted; + procedure loaded; + procedure doshortcut(var info: keyeventinfoty; const sender: twidget); + procedure setselected(const cell: gridcoordty; + const avalue: boolean); + procedure beforefocuscell(const cell: gridcoordty; + const selectaction: focuscellactionty); + function domoveby(const distance: integer): integer; virtual; + function moveby(distance: integer): integer; override; + function rowtorecnozerobased(const row: integer): integer; + function isfirstrow: boolean; + function islastrow: boolean; + property owner: tcustomgrid read fgrid; + property field_state: tfield read ffield_state; + property field_color: tfield read ffield_color; + property field_font: tfield read ffield_font; + property field_readonly: tfield read ffield_readonly; + property field_merged: tfield read ffield_merged; + property field_selected: tfield read ffield_selected; + published + property options: griddatalinkoptionsty read foptions write foptions + default defaultgriddatalinkoptions; + property onupdaterowdata: updaterowdataeventty read fonupdaterowdata + write fonupdaterowdata; + property datasource: tdatasource read getdatasource1 write settadasource1; + property fieldname_state: string read ffieldname_state + write setfieldname_state; + //integer field, selects grid rowcolor (field value and $7f), + //readonlystate (field value and $80) and + //grid rowfont ((fieldvalue shr 8) and $7f). + // $xx7f = default color, $7fxx = default font. + property fieldname_color: string read ffieldname_color + write setfieldname_color; + property fieldname_font: string read ffieldname_font + write setfieldname_font; + property fieldname_readonly: string read ffieldname_readonly + write setfieldname_readonly; + property fieldname_merged: string read ffieldname_merged + write setfieldname_merged; + property fieldname_selected: string read ffieldname_selected + write setfieldname_selected; + property navigator: tdbnavigator read fnavigator write setnavigator; + property onbeginedit: notifyeventty read fonbeginedit write fonbeginedit; + property onendedit: notifyeventty read fonendedit write fonendedit; + end; + + rowpositionty = (ropo_nearest,ropo_centeredif,ropo_bottom, + ropo_centered,ropo_top); + tdropdownlistdatalink = class(tgriddatalink) + private + fdataintf: idbdata; + fkeyindex: integer; + ftextindex: integer; + ffirstrecord: integer; + fcurrentrecord: integer; + fmaxrowcount: integer; + procedure setcurrentrecord(const avalue: integer; + const arowpos: rowpositionty); + procedure updatedatawindow(const arowpos: rowpositionty); + protected + function getasmsestring(const afield: tfield): msestring; + function getasinteger(const afield: tfield): integer; + function getaslargeint(const afield: tfield): int64; + + procedure cellevent(var info: celleventinfoty); override; + function getrecordcount: integer; override; + //workaround FPC bug 19290 +// function GetBufferCount: Integer; override; + procedure SetBufferCount(Value: Integer); override; + function getfirstrecord: integer; override; + procedure updatefocustext; + procedure recordchanged(afield: tfield); override; + function GetActiveRecord: Integer; override; + procedure SetActiveRecord(Value: Integer); override; + procedure checkscrollbar; override; + function scrollevent(sender: tcustomscrollbar; + event: scrolleventty): boolean; override; + //true if processed + procedure focuscell(var cell: gridcoordty); override; + property currentrecord: integer read fcurrentrecord{ write setcurrentrecord}; + public + constructor create(const aowner: tcustomgrid; const aintf: igriddatalink; + const adatalink: tdropdowndatalink); + function domoveby(const distance: integer): integer; override; + end; + + tdbdropdownlist = class(tdropdownlist,igriddatalink) + private + fdatalink: tdropdownlistdatalink; + //igriddatalink + function getdbindicatorcol: integer; + procedure setnavigator(const avalue: tdbnavigator); + function getdatalink(): tgriddatalink; + protected + function getassistiveflags(): assistiveflagsty override; + procedure internalcreateframe; override; + procedure createdatacol(const index: integer; out item: tdatacol); override; + procedure initcols(const acols: tdropdowncols); override; + procedure docellevent(var info: celleventinfoty); override; + procedure scrollevent(sender: tcustomscrollbar; event: scrolleventty); override; + procedure setactiveitem(const aitemindex: integer); override; + function locate(const filter: msestring): boolean; override; + procedure dopaint(const acanvas: tcanvas); override; + procedure dohide; override; + + public + constructor create(const acontroller: tcustomdbdropdownlistcontroller; + acols: tdropdowncols); + destructor destroy; override; + procedure rowup(const action: focuscellactionty = fca_focusin; + const nowrap: boolean = false) override; + procedure rowdown(const action: focuscellactionty = fca_focusin; + const nowrap: boolean = false) override; + procedure pageup(const action: focuscellactionty = fca_focusin); override; + procedure pagedown(const action: focuscellactionty = fca_focusin); override; + procedure wheelup(const action: focuscellactionty = fca_focusin); override; + procedure wheeldown(const action: focuscellactionty = fca_focusin); override; + end; + +// dbdropdownliststatety = (ddls_isstringkey); +// dbdropdownliststatesty = set of dbdropdownliststatety; + + tcustomdbdropdownlistcontroller = class( + tcustomdropdownlistcontroller,idbeditinfo) + private + fdatalink: tdropdowndatalink; +// fisstringkey: boolean; + foptionsdatalink: griddatalinkoptionsty; + foptionsdb: optionsdbty; + fbookmarks: stringarty; + function getdatasource: tdatasource; overload; + procedure setdatasource(const avalue: tdatasource); + procedure setkeyfield(const avalue: string); + function getkeyfield: string; + function getcols: tdbdropdowncols; + procedure setcols(const avalue: tdbdropdowncols); + procedure setoptionsdb(const avalue: optionsdbty); + protected +// fstate: dbdropdownliststatesty; + procedure valuecolchanged; override; + function getbuttonframeclass: dropdownbuttonframeclassty; override; + function getdropdowncolsclass: dropdowncolsclassty; override; + function createdropdownlist: tdropdownlist; override; + function candropdown: boolean; override; + procedure itemselected(const index: integer; const akey: keyty); override; + procedure doafterclosedropdown; override; + + function getasmsestring(const afield: tfield; const utf8: boolean): msestring; + function getasinteger(const afield: tfield): integer; + function getaslargeint(const afield: tfield): int64; + + //idbeditinfo + function getdataset(const aindex: integer): tdataset; + procedure getfieldtypes(out propertynames: stringarty; + out fieldtypes: fieldtypesarty); + public + constructor create(const intf: idbdropdownlist; const aisstringkey: boolean); + destructor destroy; override; + procedure dropdown; override; + property datalink: tdropdowndatalink read fdatalink; + property datasource: tdatasource read getdatasource write setdatasource; + property keyfield: string read getkeyfield write setkeyfield; + property options default defaultdbdropdownoptions; + property optionsdatalink: griddatalinkoptionsty read foptionsdatalink + write foptionsdatalink default defaultdropdowndatalinkoptions; + property optionsdb: optionsdbty read foptionsdb write setoptionsdb default []; + + property cols: tdbdropdowncols read getcols write setcols; + end; + + tdbdropdownlistcontroller = class(tcustomdbdropdownlistcontroller) + published + property datasource; + property keyfield; + property options; + property optionsdatalink; + property optionsdb; + property cols; + property dropdownrowcount; + property delay; + property valuecol; + property width; + property datarowlinewidth; + property datarowlinecolor; + property buttonlength; + property buttonminlength; + property buttonendlength; + end; + + tdropdownlistcontrollerdb = class(tcustomdbdropdownlistcontroller) + published + property datasource; +// property keyfield; + property options; + property optionsdatalink; + property optionsdb; + property cols; + property dropdownrowcount; + property delay; + property valuecol; + property width; + property datarowlinewidth; + property datarowlinecolor; + property buttonlength; + property buttonminlength; + property buttonendlength; + end; + + tdbenumeditdb = class(tdbenumedit,idbdropdownlist,ireccontrol) + private + function getdropdown: tdbdropdownlistcontroller; + procedure setdropdown(const avalue: tdbdropdownlistcontroller); + protected + function createdropdowncontroller: tcustomdropdowncontroller; override; + procedure recordselected(const arecordnum: integer; const akey: keyty); + function internaldatatotext(const data): msestring; override; + published + property dropdown: tdbdropdownlistcontroller read getdropdown write setdropdown; + end; + + tenumeditdb = class(tenumedit,idbdropdownlist) + private + function getdropdown: tdbdropdownlistcontroller; + procedure setdropdown(const avalue: tdbdropdownlistcontroller); + protected + function createdropdowncontroller: tcustomdropdowncontroller; override; + procedure recordselected(const arecordnum: integer; const akey: keyty); + function internaldatatotext(const data): msestring; override; + published + property dropdown: tdbdropdownlistcontroller read getdropdown write setdropdown; + end; + + tdbkeystringeditdb = class(tdbkeystringedit,idbdropdownlist,ireccontrol) + private +// fkeyvalue: msestring; + function getdropdown: tdbdropdownlistcontroller; + procedure setdropdown(const avalue: tdbdropdownlistcontroller); + protected + function createdropdowncontroller: tcustomdropdowncontroller; override; + procedure recordselected(const arecordnum: integer; const akey: keyty); + function internaldatatotext(const data): msestring; override; + published + property dropdown: tdbdropdownlistcontroller read getdropdown write setdropdown; + end; + + tkeystringeditdb = class(tkeystringedit,idbdropdownlist) + private + function getdropdown: tdbdropdownlistcontroller; + procedure setdropdown(const avalue: tdbdropdownlistcontroller); + protected + function createdropdowncontroller: tcustomdropdowncontroller; override; + procedure recordselected(const arecordnum: integer; const akey: keyty); + function internaldatatotext(const data): msestring; override; + published + property dropdown: tdbdropdownlistcontroller read getdropdown write setdropdown; + end; + + tdbwidgetindicatorcol = class(twidgetfixcol) + private + fcolorindicator: colorty; + procedure setcolorindicator(const avalue: colorty); + protected + procedure drawcell(const canvas: tcanvas); override; + public + constructor create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); override; + published + property colorindicator: colorty read fcolorindicator + write setcolorindicator default cl_glyph; + property options default defaultindicatorcoloptions; + end; + + tdbwidgetfixcols = class(twidgetfixcols) + private + fdbindicatorcol: integer; + fdatalink: tgriddatalink; + procedure setdbindicatorcol(const Value: integer); + function getdbindicatorcol: integer; + protected + procedure createitem(const index: integer; var item: tpersistent); override; + procedure setcount1(acount: integer; doinit: boolean); override; + public + constructor create(const aowner: tcustomwidgetgrid; + const adatalink: tgriddatalink); + published + property dbindicatorcol: integer read getdbindicatorcol + write setdbindicatorcol default -1; + end; + + tdbscrollbar = class(tthumbtrackscrollbar) + protected + procedure setoptions(const avalue: scrollbaroptionsty); override; + public + constructor create(intf: iscrollbar; org: originty = org_client; + ondimchanged: proceventty = nil); override; + published + property options default defaultdbscrollbaroptions; + property buttonlength default -1; + end; + + tdbgridframe = class(tgridframe) + protected + procedure scrollpostoclientpos(var aclientrect: rectty); override; + function getscrollbarclass(vert: boolean): framescrollbarclassty; override; + procedure scrollevent(sender: tcustomscrollbar; event: scrolleventty); override; + public + constructor create(const aintf: iscrollframe; const owner: twidget; + const autoscrollintf: iautoscrollframe); + end; + + tdbwidgetcol = class(twidgetcol) + protected + fdatalink: tfielddatalink; + + procedure dobeforedrawcell(const acanvas: tcanvas; + var processed: boolean); override; + procedure doafterdrawcell(const acanvas: tcanvas); override; + procedure setwidget(const awidget: twidget); override; + public + property datalink: tfielddatalink read fdatalink; + end; + + tdbwidgetcols = class(twidgetcols) + private + function getcols(const index: integer): tdbwidgetcol; + protected + public + class function getitemclasstype: persistentclassty; override; + property cols[const index: integer]: tdbwidgetcol read getcols; default; + end; + + tcustomdbwidgetgrid = class(tcustomwidgetgrid,igriddatalink) + private + fdatalink: tgriddatalink; +// function getdatasource: tdatasource; +// procedure setdatasource(const Value: tdatasource); + function getdatalink: tgriddatalink; + procedure setdatalink(const avalue: tgriddatalink); + function getfixcols: tdbwidgetfixcols; + procedure setfixcols(const avalue: tdbwidgetfixcols); + function getdatacols: tdbwidgetcols; + procedure setdatacols(const avalue: tdbwidgetcols); + protected + function getassistiveflags(): assistiveflagsty override; + function createdatacols: tdatacols; override; + procedure createdatacol(const index: integer; out item: tdatacol); override; + function canautoappend: boolean; override; + function getgriddatalink: pointer; override; + procedure setoptionsgrid(const avalue: optionsgridty); override; + function getfieldlink(const acol: integer): tcustomeditwidgetdatalink; + function updatesortcol(const avalue: integer): integer; override; + procedure internalcreateframe; override; + function createfixcols: tfixcols; override; + procedure dolayoutchanged; override; + procedure docellevent(var info: celleventinfoty); override; + procedure scrollevent(sender: tcustomscrollbar; event: scrolleventty); override; + function getzebrastart: integer; override; + function getnumoffset: integer; override; + procedure dopaint(const acanvas: tcanvas); override; + procedure dohide; override; + procedure loaded; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; + + procedure setselected(const cell: gridcoordty; + const avalue: boolean); override; + procedure doinsertrow(const sender: tobject); override; + procedure doappendrow(const sender: tobject); override; + procedure dodeleterow(const sender: tobject); override; + procedure beforefocuscell(const cell: gridcoordty; + const selectaction: focuscellactionty); override; + function caninsertrow: boolean; override; + function canappendrow: boolean; override; + function candeleterow: boolean; override; + function isfirstrow: boolean; override; + function islastrow: boolean; override; + procedure defineproperties(filer: tfiler); override; +// procedure doenter; override; +// procedure doexit; override; + //igriddatalink + function getdbindicatorcol: integer; + procedure setnavigator(const avalue: tdbnavigator); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function focuscell(cell: gridcoordty; + selectaction: focuscellactionty = fca_focusin; + const selectmode: selectcellmodety = scm_cell; + const ashowcell: cellpositionty = cep_nearest): boolean; override; + //true if ok + function canclose(const newfocus: twidget): boolean; override; + procedure rowup(const action: focuscellactionty = fca_focusin; + const nowrap: boolean = false); override; + procedure rowdown(const action: focuscellactionty = fca_focusin; + const nowrap: boolean = false); override; + procedure pageup(const action: focuscellactionty = fca_focusin); override; + procedure pagedown(const action: focuscellactionty = fca_focusin); override; + procedure wheelup(const action: focuscellactionty = fca_focusin); override; + procedure wheeldown(const action: focuscellactionty = fca_focusin); override; + procedure lastrow(const action: focuscellactionty = fca_focusin); override; + procedure firstrow(const action: focuscellactionty = fca_focusin); override; +// property datasource: tdatasource read getdatasource write setdatasource; + property datalink: tgriddatalink read fdatalink write setdatalink; + property zebra_step default 0; + property fixcols: tdbwidgetfixcols read getfixcols write setfixcols; + property datacols: tdbwidgetcols read getdatacols write setdatacols; + end; + + tdbwidgetgrid = class(tcustomdbwidgetgrid) + published +// property datasource; + property optionsgrid; + property optionsgrid1; + property fixcols; + property fixrows; +// property font; + property fontempty; + property gridframecolor; +// property gridframewidth; + property rowcolors; + property rowfonts; + property zebra_color; + property zebra_start; + property zebra_height; + property zebra_step; + property datacols; + property datalink; + + property datarowlinewidth; + property datarowlinecolorfix; + property datarowlinecolor; + property datarowheight; + property datarowheightmin; + property datarowheightmax; + + property statfile; + property statvarname; + property statpriority; + + property oncopyselection; + property onpasteselection; + property onbeforeupdatelayout; + property onlayoutchanged; + property oncolmoving; + property oncolmoved; + property onrowcountchanged; + property onrowdatachanged; + property onrowsdatachanged; +// property onrowsmoving; +// property onrowsmoved; +// property onrowsinserting; +// property onrowsinserted; +// property onrowsdeleting; +// property onrowsdeleted; + property oncellevent; + property onsortchanged; + property drag; + end; + + tstringcoldatalink = class(tcustomeditwidgetdatalink) + private +// fowner: tcustomstringcol; + protected + procedure updatedata; override; + procedure layoutchanged; override; + end; + + tdbstringcol = class(tcustomstringcol,idbeditfieldlink, + idbeditinfo,iificlient,iifidatalink) + private + fdatalink: tstringcoldatalink; + fmaxlength: integer; + fifiserverintf: iifiserver; + function getdatafield: string; + procedure setdatafield(const avalue: string); + //iifidatalink + procedure setifiserverintf(const aintf: iifiserver); + function getdefaultifilink: iificlient; virtual; + function getifilinkkind: ptypeinfo; + function getifidatatype(): listdatatypety virtual; + procedure updateifigriddata(const sender: tobject; const alist: tdatalist); + function getgriddata: tdatalist; + function getvalueprop: ppropinfo; + procedure getifivalue(var avalue); //for pointer property without RTTI + procedure setifivalue(const avalue); //for pointer property without RTTI + + //idbeditinfo + procedure getfieldtypes(out propertynames: stringarty; + out fieldtypes: fieldtypesarty); overload; + function getdataset(const aindex: integer): tdataset; + function getoptionsdb: optionseditdbty; + procedure setoptionsdb(const avalue: optionseditdbty); + function getnullsymbol: msestring; + procedure setnullsymbol(const avalue: msestring); + protected + function getoptionsedit: optionseditty; override; + function getitems(aindex: integer): msestring; override; + procedure setitems(aindex: integer; const Value: msestring); override; + procedure modified; override; + procedure dobeforedrawcell(const acanvas: tcanvas; + var processed: boolean); override; + procedure doafterdrawcell(const acanvas: tcanvas); override; + function getrowtext(const arow: integer): msestring; override; + function createdatalist: tdatalist; override; +// procedure docellevent(var info: celleventinfoty); override; + procedure docellfocuschanged(enter: boolean; + const cellbefore: gridcoordty; var newcell: gridcoordty; + const selectaction: focuscellactionty); override; + //idbeditfieldlink + procedure getfieldtypes(var afieldtypes: fieldtypesty); overload; + function getgriddatasource: tdatasource; virtual; + function getgridintf: iwidgetgrid; + function getwidget: twidget; + function seteditfocus: boolean; + function getedited: boolean; + procedure initeditfocus; + function checkvalue(const quiet: boolean = false): boolean; + procedure valuetofield; + procedure fieldtovalue; + procedure setnullvalue; + procedure updatereadonlystate; + procedure setmaxlength(const avalue: integer); + function getfieldlink: tcustomeditwidgetdatalink; + public + constructor create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); override; + destructor destroy; override; + property datalink: tstringcoldatalink read fdatalink; + published + property datafield: string read getdatafield write setdatafield; + property optionsdb: optionseditdbty read getoptionsdb write setoptionsdb default []; + property nullsymbol: msestring read getnullsymbol write setnullsymbol; + property focusrectdist; + property textflags; + property textflagsactive; + property optionsedit1; //before optionsedit! + property optionsedit; + property passwordchar; + property font; + property colorselect; + property fontselect; + property onsetvalue; + property ondataentered; + property oncopytoclipboard; + property onpastefromclipboard; + property ondrawcell; + end; + + tdbstringcols = class(tstringcols) + private + foptionsdb: optionseditdbty; + function getcols(const index: integer): tdbstringcol; + procedure setoptionsdb(const avalue: optionseditdbty); + protected + function getcolclass: stringcolclassty; override; + procedure datasourcechanged; override; + public + class function getitemclasstype: persistentclassty; override; + property cols[const index: integer]: tdbstringcol read getcols; default; //last! + published + property optionsdb: optionseditdbty read foptionsdb write setoptionsdb default []; + end; + + tdbstringindicatorcol = class(tfixcol) + private + fcolorindicator: colorty; + procedure setcolorindicator(const avalue: colorty); + protected + procedure drawcell(const canvas: tcanvas); override; + public + constructor create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); override; + published + property colorindicator: colorty read fcolorindicator + write setcolorindicator default cl_glyph; + property options default defaultindicatorcoloptions; + end; + + tdbstringfixcols = class(tfixcols) + private + fdbindicatorcol: integer; + fdatalink: tgriddatalink; + procedure setdbindicatorcol(const Value: integer); + function getdbindicatorcol: integer; + protected + procedure createitem(const index: integer; var item: tpersistent); override; + procedure setcount1(acount: integer; doinit: boolean); override; + public + constructor create(const aowner: tcustomgrid; + const adatalink: tgriddatalink); + published + property dbindicatorcol: integer read getdbindicatorcol + write setdbindicatorcol default -1; + end; + + dbstringgridoptionty = (dsgo_autofields); + dbstringgridoptionsty = set of dbstringgridoptionty; + + tstringgriddatalink = class(tgriddatalink) + protected + procedure activechanged; override; + end; + + tcustomdbstringgrid = class(tcustomstringgrid,iwidgetgrid,igriddatalink) + private + fdatalink: tstringgriddatalink; + foptions: dbstringgridoptionsty; + ffieldnamedisplayfixrow: integer; +// function getdatasource: tdatasource; +// procedure setdatasource(const Value: tdatasource); + function getdatacols: tdbstringcols; + procedure setdatacols(const avalue: tdbstringcols); + + //iwidgetgrid (dummy) + function getbrushorigin: pointty; + function getcol: twidgetcol; + procedure getdata(var index: integer; var dest); + procedure setdata(var index: integer; const source; + const noinvalidate: boolean = false); + procedure datachange(const arow: integer); + function getrow: integer; + procedure setrow(arow: integer); + procedure changed(); + procedure edited(); + function empty(index: integer): boolean; + procedure updateeditoptions(var aoptions: optionseditty; + const aoptions1: optionsedit1ty); + procedure showrect(const arect: rectty; const aframe: tcustomframe); + procedure widgetpainted(const canvas: tcanvas); + function nullcheckneeded(const newfocus: twidget): boolean; + function nonullcheck: boolean; + function getgrid: tcustomwidgetgrid; + function getdatapo(const arow: integer): pointer; + function getrowdatapo: pointer; + {$ifdef mse_with_ifi} + procedure updateifigriddata(const alist: tdatalist); + {$endif} + procedure setoptions(const avalue: dbstringgridoptionsty); + procedure checkautofields; + procedure setfieldnamedisplayfixrow(const avalue: integer); + function getdatalink: tgriddatalink; //igriddatalink + procedure setdatalink(const avalue: tstringgriddatalink); + function getfixcols: tdbstringfixcols; + procedure setfixcols(const avalue: tdbstringfixcols); + protected + function getassistiveflags(): assistiveflagsty override; + function canautoappend: boolean; override; + procedure setupeditor(const acell: gridcoordty; const focusin: boolean); override; +// procedure doenter; override; +// procedure doexit; override; + //igriddatalink + function getdbindicatorcol: integer; + procedure setnavigator(const avalue: tdbnavigator); + + procedure setselected(const cell: gridcoordty; + const avalue: boolean); override; + procedure updatelayout; override; +// procedure editnotification(var info: editnotificationinfoty); override; + procedure setoptionsgrid(const avalue: optionsgridty); override; + function getfieldlink(const acol: integer): tfielddatalink; + function updatesortcol(const avalue: integer): integer; override; + procedure doasyncevent(var atag: integer); override; + procedure internalcreateframe; override; +// function getoptionsedit: optionseditty; override; + function createfixcols: tfixcols; override; + function createdatacols: tdatacols; override; +// procedure initcellinfo(var info: cellinfoty); override; + procedure scrollevent(sender: tcustomscrollbar; event: scrolleventty); override; + function getzebrastart: integer; override; + function getnumoffset: integer; override; + procedure checkcellvalue(var accept: boolean); override; + procedure dopaint(const acanvas: tcanvas); override; + procedure dohide; override; + procedure loaded; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; + function cangridcopy: boolean; + + function caninsertrow: boolean; override; + function canappendrow: boolean; override; + function candeleterow: boolean; override; + + procedure doinsertrow(const sender: tobject); override; + procedure doappendrow(const sender: tobject); override; + procedure dodeleterow(const sender: tobject); override; + procedure beforefocuscell(const cell: gridcoordty; + const selectaction: focuscellactionty); override; + procedure coloptionstoeditoptions(var dest: optionseditty; + var dest1: optionsedit1ty); + function isfirstrow: boolean; override; + function islastrow: boolean; override; + procedure defineproperties(filer: tfiler); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function focuscell(cell: gridcoordty; + selectaction: focuscellactionty = fca_focusin; + const selectmode: selectcellmodety = scm_cell; + const ashowcell: cellpositionty = cep_nearest): boolean; override; + //true if ok + procedure docellevent(var info: celleventinfoty); override; + function canclose(const newfocus: twidget): boolean; override; + procedure rowup(const action: focuscellactionty = fca_focusin; + const nowrap: boolean = false); override; + procedure rowdown(const action: focuscellactionty = fca_focusin; + const nowrap: boolean = false); override; + procedure pageup(const action: focuscellactionty = fca_focusin); override; + procedure pagedown(const action: focuscellactionty = fca_focusin); override; + procedure wheelup(const action: focuscellactionty = fca_focusin); override; + procedure wheeldown(const action: focuscellactionty = fca_focusin); override; + procedure lastrow(const action: focuscellactionty = fca_focusin); override; + procedure firstrow(const action: focuscellactionty = fca_focusin); override; +// property datasource: tdatasource read getdatasource write setdatasource; + property datacols: tdbstringcols read getdatacols write setdatacols; + property datalink: tstringgriddatalink read fdatalink write setdatalink; + property options: dbstringgridoptionsty read foptions + write setoptions default []; + property fieldnamedisplayfixrow: integer read ffieldnamedisplayfixrow write + setfieldnamedisplayfixrow default -1; + //negative rowindex, 0-> none + property zebra_step default 0; + property fixcols: tdbstringfixcols read getfixcols write setfixcols; + end; + + tdbstringgrid = class(tcustomdbstringgrid) + published +// property datasource; + property options; + property fieldnamedisplayfixrow; + + property optionsgrid; + property optionsgrid1; + property datacols; + property datalink; + property fixcols; + property fixrows; + property gridframecolor; +// property gridframewidth; + property rowcolors; + property rowfonts; + property zebra_color; + property zebra_start; + property zebra_height; + property zebra_step; + + property datarowlinewidth; + property datarowlinecolorfix; + property datarowlinecolor; + property datarowheight; + property datarowheightmin; + property datarowheightmax; + property caretwidth; + + property statfile; + property statvarname; + property statpriority; + + property oncopyselection; + property onpasteselection; + property onbeforeupdatelayout; + property onlayoutchanged; + property oncolmoving; + property oncolmoved; + property onrowcountchanged; + property onrowdatachanged; + property onrowsdatachanged; +// property onrowsmoving; +// property onrowsmoved; +// property onrowsinserting; +// property onrowsinserted; +// property onrowsdeleting; +// property onrowsdeleted; + property oncellevent; + property onsortchanged; + property drag; + end; + + tlbdropdownlistcontroller = class; + + tlbdropdownstringcol = class(tdropdownstringcol) + private + flookupbuffer: tcustomlookupbuffer; + ffieldno: integer; + fsortfieldno: integer; + funsorted: boolean; + protected + function getrowtext(const arow: integer): msestring; override; + public + end; + + tcopydropdownlist = class(tdropdownlist) + private + protected + function locate(const filter: msestring): boolean; override; + end; + + eddstatety = (edds_filtered,edds_bof,edds_eof); + eddstatesty = set of eddstatety; + + texterndatadropdownlistcontroller = class; + + texterndatadropdownlist = class(tdropdownlist) + private + ffirstrecord: integer; + frecnums: integerarty; + feddstate: eddstatesty; + function getactiverecord: integer; + procedure setactiverecord(const avalue: integer); + protected + procedure dokeydown(var info: keyeventinfoty); override; + procedure findprev(var recno: integer); + procedure findnext(var recno: integer); virtual; abstract; + function getrecno(const aindex: integer): integer; + procedure dorowcountchanged(const countbefore,newcount: integer); override; + procedure internalcreateframe; override; + procedure createdatacol(const index: integer; out item: tdatacol); override; + procedure docellevent(var info: celleventinfoty); override; + procedure scrollevent(sender: tcustomscrollbar; event: scrolleventty); override; + procedure dbscrolled(distance: integer); + procedure moveby(distance: integer); + procedure filterchanged; + procedure resyncfilter; + property activerecord: integer read getactiverecord write setactiverecord; + public + constructor create(const acontroller: texterndatadropdownlistcontroller; + acols: tdropdowncols); + procedure rowup(const action: focuscellactionty = fca_focusin; + const nowrap: boolean = false); override; + procedure rowdown(const action: focuscellactionty = fca_focusin; + const nowrap: boolean = false); override; + procedure pageup(const action: focuscellactionty = fca_focusin); override; + procedure pagedown(const action: focuscellactionty = fca_focusin); override; + procedure wheelup(const action: focuscellactionty = fca_focusin); override; + procedure wheeldown(const action: focuscellactionty = fca_focusin); override; + end; + + tlbdropdownlist = class(texterndatadropdownlist) + private + protected + procedure initcols(const acols: tdropdowncols); override; + function locate(const filter: msestring): boolean; override; + procedure findnext(var recno: integer); override; + public + constructor create(const acontroller: tcustomlbdropdownlistcontroller; + acols: tdropdowncols); + end; + + tlbdropdowncol = class(tdropdowncol,ilookupbufferfieldinfo) + private + ffieldno: lookupbufferfieldnoty; + procedure setfieldno(const avalue: lookupbufferfieldnoty); + protected + //ilookupbufferfieldinfo + function getlbdatakind(const apropname: string): lbdatakindty; + function getlookupbuffer: tcustomlookupbuffer; + published + property fieldno: lookupbufferfieldnoty read ffieldno write setfieldno + default 0; + //colindex in lookupbuffer + end; + + tlbdropdowncols = class(tnolistdropdowncols) + private + function getitems(const index: integer): tlbdropdowncol; + protected + function getcolclass: dropdowncolclassty; override; + public + property items[const index: integer]: tlbdropdowncol read getitems; default; + end; + + optionlbty = (olb_copyitems,olb_unsorted); + optionslbty = set of optionlbty; + + texterndatadropdownlistcontroller = class(tcustomdropdownlistcontroller) + private + fedrecnums: integerarty; + protected + procedure dofilter(var recno: integer; var accept: boolean); virtual; abstract; + procedure valuecolchanged; override; + function getbuttonframeclass: dropdownbuttonframeclassty; override; + function getdropdowncolsclass: dropdowncolsclassty; override; + public + constructor create(const intf: ilbdropdownlist); + procedure dropdown; override; + property options default defaulteddropdownoptions; + end; + + tcustomlbdropdownlistcontroller = class(texterndatadropdownlistcontroller, + ilookupbufferfieldinfo) + private + fsortfieldno: integer; + flookupbuffer: tcustomlookupbuffer; + fkeyfieldno: lookupbufferfieldnoty; + fonfilter: lbfiltereventty; + foptionslb: optionslbty; + fonbeforefilter: dataediteventty; + function getcols: tlbdropdowncols; + procedure setcols(const avalue: tlbdropdowncols); + procedure setlookupbuffer(const avalue: tcustomlookupbuffer); + protected + procedure dofilter(var recno: integer; var accept: boolean); override; + function reloadlist: integer; override; + function createdropdownlist: tdropdownlist; override; + function candropdown: boolean; override; + procedure itemselected(const index: integer; const akey: keyty); override; + procedure objectevent(const sender: tobject; const event: objecteventty); override; + function getremoterowcount: integer; override; + //ilookupbufferfieldinfo + function getlbdatakind(const apropname: string): lbdatakindty; + function getlookupbuffer: tcustomlookupbuffer; + public + property optionslb: optionslbty read foptionslb write foptionslb default []; + property cols: tlbdropdowncols read getcols write setcols; + property lookupbuffer: tcustomlookupbuffer read flookupbuffer write setlookupbuffer; + property keyfieldno: lookupbufferfieldnoty read fkeyfieldno write fkeyfieldno default 0; + property onfilter: lbfiltereventty read fonfilter write fonfilter; + property onbeforefilter: dataediteventty read fonbeforefilter + write fonbeforefilter; + end; + + tlbdropdownlistcontroller = class(tcustomlbdropdownlistcontroller) + published + property lookupbuffer; + property keyfieldno; + property optionslb; + property options; + property cols; + property onbeforefilter; + property onfilter; + property dropdownrowcount; + property delay; + property valuecol; + property width; + property datarowlinewidth; + property datarowlinecolor; + property buttonlength; + property buttonminlength; + property buttonendlength; + end; + + tdropdownlistcontrollerlb = class(tcustomlbdropdownlistcontroller) + published + property lookupbuffer; +// property keyfieldno; + property optionslb; + property options; + property cols; + property onbeforefilter; + property onfilter; + property dropdownrowcount; + property delay; + property valuecol; + property width; + property datarowlinewidth; + property datarowlinecolor; + property buttonlength; + property buttonminlength; + property buttonendlength; + end; + + tdbenumeditlb = class(tdbenumedit,ilbdropdownlist) + private + function getdropdown: tlbdropdownlistcontroller; + procedure setdropdown(const avalue: tlbdropdownlistcontroller); + protected + function createdropdowncontroller: tcustomdropdowncontroller; override; + function internaldatatotext(const data): msestring; override; + //ilbdropdownlist + procedure recordselected(const arecordnum: integer; const akey: keyty); + function getlbkeydatakind: lbdatakindty; + published + property dropdown: tlbdropdownlistcontroller read getdropdown write setdropdown; + end; + + tenumeditlb = class(tenumedit,ilbdropdownlist) + private + function getdropdown: tlbdropdownlistcontroller; + procedure setdropdown(const avalue: tlbdropdownlistcontroller); + {$ifdef mse_with_ifi} + function getifilink: tifiintegerlinkcomp; + procedure setifilink1(const avalue: tifiintegerlinkcomp); + {$endif} + protected + function createdropdowncontroller: tcustomdropdowncontroller; override; + function internaldatatotext(const data): msestring; override; + //ilbdropdownlist + procedure recordselected(const arecordnum: integer; const akey: keyty); + function getlbkeydatakind: lbdatakindty; + public + published + property dropdown: tlbdropdownlistcontroller read getdropdown write setdropdown; +{$ifdef mse_with_ifi} + property ifilink: tifiintegerlinkcomp read getifilink write setifilink1; +{$endif} + end; + + tcustomenum64edit = class(tcustomdropdownlistedit) + private + fonsetvalue1: setint64eventty; + function getgridvalue(const index: integer): int64; + procedure setgridvalue(const index: integer; aValue: int64); + function getgridvalues: int64arty; + procedure setgridvalues(const avalue: int64arty); + procedure setvalue(const avalue: int64); + {$ifdef mse_with_ifi} + function getifilink: tifiint64linkcomp; + procedure setifilink1(const avalue: tifiint64linkcomp); + {$endif} + protected + fvalue1: int64; + fvaluedefault1: int64; + + function getdefaultvalue: pointer; override; + procedure texttovalue(var accept: boolean; const quiet: boolean); override; + procedure texttodata(const atext: msestring; var data); override; + procedure setnullvalue; override; //for dbedits + procedure valuetogrid(arow: integer); override; + procedure gridtovalue(arow: integer); override; + procedure readstatvalue(const reader: tstatreader); override; + procedure writestatvalue(const writer: tstatwriter); override; + + function createdatalist(const sender: twidgetcol): tdatalist; override; + function getdatalistclass: datalistclassty; override; + + {$ifdef mse_with_ifi} + function getifidatalinkintf: iifidatalink; override; + //iifidatalink + function getifilinkkind: ptypeinfo; override; + {$endif} + public + constructor create(aowner: tcomponent); override; + property gridvalue[const index: integer]: int64 + read getgridvalue write setgridvalue; default; + property gridvalues: int64arty read getgridvalues write setgridvalues; + property value: int64 read fvalue1 write setvalue default -1; +{$ifdef mse_with_ifi} + property ifilink: tifiint64linkcomp read getifilink write setifilink1; +{$endif} + property valuedefault: int64 read fvaluedefault1 write fvaluedefault1 default -1; + property onsetvalue: setint64eventty read fonsetvalue1 write fonsetvalue1; + end; + + tcustomenum64editlb = class(tcustomenum64edit,ilbdropdownlist) + private + function getdropdown: tlbdropdownlistcontroller; + procedure setdropdown(const avalue: tlbdropdownlistcontroller); + protected + function createdropdowncontroller: tcustomdropdowncontroller; override; + function internaldatatotext(const data): msestring; override; + //ilbdropdownlist + procedure recordselected(const arecordnum: integer; const akey: keyty); + function getlbkeydatakind: lbdatakindty; + public + property dropdown: tlbdropdownlistcontroller read getdropdown write setdropdown; + end; + + tenum64editlb = class(tcustomenum64editlb) + published +{$ifdef mse_with_ifi} + property ifilink; +{$endif} + property dropdown; + property value; + property valuedefault; + property onsetvalue; + end; + + tdbenum64editlb = class(tcustomenum64editlb,idbeditfieldlink,ireccontrol) + private + fdatalink: tlookupeditdatalink; + procedure setdatalink(const avalue: tlookupeditdatalink); + protected + procedure defineproperties(filer: tfiler); override; + + function nullcheckneeded(const newfocus: twidget): boolean; override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + procedure modified; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; +// function getoptionsedit: optionseditty; override; +// procedure dochange; override; +// procedure doenter; override; +// procedure doexit; override; + + function getrowdatapo(const arow: integer): pointer; override; + //idbeditfieldlink + procedure valuetofield; virtual; + procedure fieldtovalue; virtual; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + function getfieldlink: tcustomeditwidgetdatalink; + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: tlookupeditdatalink read fdatalink write setdatalink; + property dropdown; + property onsetvalue; + end; + + tcustomenum64editdb = class(tcustomenum64edit,idbdropdownlist) + private + function getdropdown: tdbdropdownlistcontroller; + procedure setdropdown(const avalue: tdbdropdownlistcontroller); + protected + function createdropdowncontroller: tcustomdropdowncontroller; override; + function internaldatatotext(const data): msestring; override; + //ilbdropdownlist + procedure recordselected(const arecordnum: integer; const akey: keyty); + public + property dropdown: tdbdropdownlistcontroller read getdropdown write setdropdown; + end; + + tenum64editdb = class(tcustomenum64editdb) + published +{$ifdef mse_with_ifi} + property ifilink; +{$endif} + property dropdown; + property value; + property valuedefault; + property onsetvalue; + end; + + tdbenum64editdb = class(tcustomenum64editdb,idbeditfieldlink,ireccontrol) + private + fdatalink: tlookupeditdatalink; + procedure setdatalink(const avalue: tlookupeditdatalink); + protected + procedure defineproperties(filer: tfiler); override; + function nullcheckneeded(const newfocus: twidget): boolean; override; + procedure griddatasourcechanged; override; + function getgriddatasource: tdatasource; + function createdatalist(const sender: twidgetcol): tdatalist; override; + procedure modified; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; +// function getoptionsedit: optionseditty; override; +// procedure dochange; override; +// procedure doenter; override; +// procedure doexit; override; + function getrowdatapo(const arow: integer): pointer; override; + //idbeditfieldlink + procedure valuetofield; virtual; + procedure fieldtovalue; virtual; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + function getfieldlink: tcustomeditwidgetdatalink; + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: tlookupeditdatalink read fdatalink write setdatalink; + property dropdown; + property onsetvalue; + end; + + tdbkeystringeditlb = class(tdbkeystringedit,ilbdropdownlist) + private + function getdropdown: tlbdropdownlistcontroller; + procedure setdropdown(const avalue: tlbdropdownlistcontroller); + protected + function createdropdowncontroller: tcustomdropdowncontroller; override; + function internaldatatotext(const data): msestring; override; + //ilbdropdownlist + procedure recordselected(const arecordnum: integer; const akey: keyty); + function getlbkeydatakind: lbdatakindty; + published + property dropdown: tlbdropdownlistcontroller read getdropdown write setdropdown; + end; + + tkeystringeditlb = class(tkeystringedit,ilbdropdownlist) + private + function getdropdown: tlbdropdownlistcontroller; + procedure setdropdown(const avalue: tlbdropdownlistcontroller); + protected + function createdropdowncontroller: tcustomdropdowncontroller; override; + function internaldatatotext(const data): msestring; override; + //ilbdropdownlist + procedure recordselected(const arecordnum: integer; const akey: keyty); + function getlbkeydatakind: lbdatakindty; + published + property dropdown: tlbdropdownlistcontroller read getdropdown write setdropdown; + end; + +function encoderowstate(const color: integer = -1; const font: integer = -1; + const readonly: boolean = false): integer; + +implementation +uses + msestockobjects,mseshapes,msereal,msebits, + mseassistiveserver, + mseactions,mseact,rtlconsts,msedrawtext,sysutils,msedbdispwidgets; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tcomponent1 = class(tcomponent); + twidget1 = class(twidget); + tcustomgrid1 = class(tcustomgrid); + tcustomdataedit1 = class(tcustomdataedit); + tdatacols1 = class(tdatacols); + tdropdowncols1 = class(tdropdowncols); + tdataedit1 = class(tdataedit); + tdataset1 = class(tdataset); + tdatasource1 = class(tdatasource); + ttoolbuttons1 = class(ttoolbuttons); + tcustomstringgrid1 = class(tcustomstringgrid); + treader1 = class(treader); + tcols1 = class(tcols); + + hasactiveeditinfoty = record + field: tfield; + hasedit: boolean; + end; + phasactiveeditinfoty = ^hasactiveeditinfoty; + +function encoderowstate(const color: integer = -1; const font: integer = -1; + const readonly: boolean = false): integer; +begin + result:= (color and $7f) or ((font and $7f) shl 8); + if readonly then begin + result:= result or $80; + end; +end; + +procedure drawindicatorcell(const canvas: tcanvas; const datalink: tgriddatalink; + const acolor: colorty); +var + glyph: stockglyphty; +begin + with cellinfoty(canvas.drawinfopo^) do begin + with datalink do begin + case dataset.state of + dsbrowse: glyph:= stg_dbindbrowse; + dsedit: glyph:= stg_dbindedit; + dsinsert: glyph:= stg_dbindinsert; + else glyph:= stockglyphty(-1); + end; + if ord(glyph) >= 0 then begin + stockobjects.glyphs.paint(canvas,ord(glyph),innerrect, + [al_xcentered,al_ycentered],acolor); + end; + end; + end; +end; + +function confirmdeleterecord: boolean; +begin + with stockobjects do begin + result:= askok(captions[sc_Delete_record_question],captions[sc_confirmation]) + end; +end; + +function confirmcopyrecord: boolean; +begin + with stockobjects do begin + result:= askok(captions[sc_Copy_record_question],captions[sc_confirmation]) + end; +end; + +{ tnavigdatalink } + +constructor tnavigdatalink.Create(const intf: idbnaviglink); +begin + fintf:= intf; + inherited create; + visualcontrol:= true; + fintf.setactivebuttons([],false); +end; + +procedure tnavigdatalink.updatebuttonstate; +var + bu1: dbnavigbuttonsty; + bo1: boolean; + options1: dbnavigatoroptionsty; +begin + options1:= fintf.getnavigoptions; + bu1:= [dbnb_autoedit]; + if dno_dialogifinactive in options1 then begin + bu1:= bu1+[dbnb_dialog]; + end; + bo1:= false; + if active then begin + bu1:= bu1+[dbnb_first,dbnb_prior,dbnb_next,dbnb_last]+ + filterdbnavigbuttons+[dbnb_dialog]; + if bof then begin + bu1:= bu1 - [dbnb_first,dbnb_prior]; + end; + if eof then begin + bu1:= bu1 - [dbnb_next,dbnb_last]; + end; + if (dno_dialogifinactive in options1) and bof and eof then begin + bu1:= bu1 - [dbnb_dialog]; + end; + if (dno_nodialogifnoeditmode in options1) and + not (datasource.state in dseditmodes) then begin + bu1:= bu1 - [dbnb_dialog]; + end; + if (dno_nodialogifreadonly in options1) and not canupdate then begin + bu1:= bu1 - [dbnb_dialog]; + end; + case datasource.state of + dsfilter: begin + case filtereditkind of + fek_filter: bu1:= [dbnb_filter]; + fek_filtermin: bu1:= [dbnb_filtermin]; + fek_filtermax: bu1:= [dbnb_filtermax]; + fek_find: bu1:= [dbnb_find]; + end; + fintf.setcheckedbuttons(bu1,true); + bu1:= bu1+[dbnb_filterclear]; + end; + dsedit,dsinsert: begin + bu1:= bu1 + [dbnb_post,dbnb_cancel,dbnb_refresh,dbnb_insert,dbnb_delete]; + if (datasource.state = dsinsert) and + (dno_nomultiinsert in options1) then begin + exclude(bu1,dbnb_insert); + end; + end; + else begin + fintf.setcheckedbuttons( + [dbnb_filter,dbnb_filtermin,dbnb_filtermax,dbnb_find],false); + bu1:= bu1 + [dbnb_refresh,dbnb_insert,dbnb_delete,dbnb_edit, + dbnb_filteronoff,dbnb_copyrecord]; + end; + end; +// if (fdscontroller <> nil) and fdscontroller.noedit then begin +// bu1:= bu1 - editnavigbuttons; +// end; + if not canupdate then begin + bu1:= bu1 - [dbnb_edit,dbnb_autoedit]; + end; + if dno_append in options1 then begin + if not canappend then begin + bu1:= bu1 - [dbnb_insert,dbnb_copyrecord]; + end; + end + else begin + if not caninsert then begin + bu1:= bu1 - [dbnb_insert,dbnb_copyrecord]; + end; + end; + if not candelete then begin + exclude(bu1,dbnb_delete); + end; + if bof and eof then begin + bu1:= bu1 - [dbnb_delete,dbnb_copyrecord]; + end; +// if not datasource.dataset.canmodify then begin +// bu1:= bu1 - [dbnb_edit,dbnb_delete,dbnb_insert,dbnb_copyrecord]; +// end; + if csdesigning in dataset.componentstate then begin + bu1:= bu1 * designdbnavigbuttons; + end; + bo1:= datasource.dataset.filtered; + end; + if dno_nonavig in options1 then begin + bu1:= bu1 - ([dbnb_first,dbnb_prior,dbnb_next,dbnb_last, + dbnb_insert,dbnb_delete,dbnb_filteronoff,dbnb_copyrecord]+ + filterdbnavigbuttons); + end; + if dno_nodelete in options1 then begin + bu1:= bu1 - [dbnb_delete]; + end; + if dno_noinsert in options1 then begin + bu1:= bu1 - [dbnb_insert]; + end; + if dno_noedit in options1 then begin + bu1:= bu1 - [dbnb_edit]; + end; + fintf.setactivebuttons(bu1,bo1); +end; + +procedure tnavigdatalink.activechanged; +var + intf1: igetdscontroller; +begin + fdscontroller:= nil; + if active then begin + if getcorbainterface(dataset,typeinfo(igetdscontroller),intf1) then begin + fdscontroller:= intf1.getcontroller; + end; + end; + inherited; + updatebuttonstate; +end; + +procedure tnavigdatalink.datasetchanged; +begin + inherited; + updatebuttonstate; +end; + +procedure tnavigdatalink.editingchanged; +begin + inherited; + updatebuttonstate(); + fintf.updatereadonly(); + with twidget1(fintf.getwidget) do begin + if fobjectlinker <> nil then begin + fobjectlinker.sendevent(oe_changed); + end; + end; +end; + +procedure tnavigdatalink.recordchanged(field: tfield); +begin + inherited; + updatebuttonstate; +end; + +procedure tnavigdatalink.execbutton(const abutton: dbnavigbuttonty); +var + widget1: twidget; + options1: dbnavigatoroptionsty; + intf1: iassistiveclient; +begin + if (datasource <> nil) and (datasource.State <> dsinactive) then begin + widget1:= fintf.getwidget; + options1:= fintf.getnavigoptions; + if not (abutton in [dbnb_cancel,dbnb_delete,dbnb_autoedit]) then begin + if dno_candefocuswindow in options1 then begin + if not widget1.rootwidget.canparentclose then begin + exit; + end; + end + else begin + if (widget1.parentwidget <> nil) and + not widget1.parentwidget.canparentclose then begin + exit; + end; + end; + end; + with datasource.dataset do begin + case abutton of + dbnb_first: first; + dbnb_prior: begin + include(fstate,nds_prior); + exclude(fstate,nds_datasetscrolled); + try + self.moveby(-1); + if not (nds_datasetscrolled in fstate) and canassistive(intf1) then begin + assistiveserver.dodatasetevent(intf1,adek_bof,dataset); + end; + finally + exclude(fstate,nds_prior); + end; + end; + dbnb_next: begin + include(fstate,nds_next); + try + self.moveby(1); + finally + exclude(fstate,nds_next); + end; + end; + dbnb_last: last; + dbnb_insert: begin + if dno_append in options1 then begin + append; + end + else begin + insert; + end; + end; + dbnb_delete: begin + if not (dno_confirmdelete in options1) or confirmdeleterecord then begin + delete; + end; + end; + dbnb_edit: edit; + dbnb_post: post; + dbnb_cancel: cancel; + dbnb_refresh: begin + if dscontroller <> nil then begin + dscontroller.refresh(not (dno_norefreshrecno in options1)); + end + else begin + refresh; + end; + end; + dbnb_filteronoff: filtered:= not filtered; + dbnb_dialog: begin + if (dno_postbeforedialog in options1) and (state in dseditmodes) then begin + post; + end; + fintf.dodialogexecute; + end; + dbnb_autoedit: begin + with twidget1(widget1) do begin + if fobjectlinker <> nil then begin + fobjectlinker.sendevent(oe_changed); + end; + end; + fintf.updatereadonly(); + end; + dbnb_copyrecord: begin + if (dscontroller <> nil) and + not (dno_confirmcopy in options1) or confirmcopyrecord then begin + dscontroller.copyrecord(dno_append in options1); + end; + end; + end; + if fdscontroller <> nil then begin + if state = dsfilter then begin + case abutton of + dbnb_filterclear: fdscontroller.clearfilter(); + else begin + fdscontroller.endfilteredit; + end; + end; + end + else begin + case abutton of + dbnb_filter: fdscontroller.beginfilteredit(fek_filter); + dbnb_filtermin: fdscontroller.beginfilteredit(fek_filtermin); + dbnb_filtermax: fdscontroller.beginfilteredit(fek_filtermax); + dbnb_filterclear: fdscontroller.clearfilter(); + dbnb_find: fdscontroller.beginfilteredit(fek_find); + end; + end; + end; + end; + end; +end; + +procedure tnavigdatalink.disabledstatechange; +begin + updatebuttonstate; +end; + +function tnavigdatalink.canassistive(out aintf: iassistiveclient): boolean; +var + wi1: twidget1; +begin + result:= false; + aintf:= nil; + if (assistiveserver <> nil) and active then begin + wi1:= twidget1(fintf.getwidget()); + result:= wi1.window.active; + if result then begin + aintf:= wi1.getiassistiveclient(); + end; + end; +end; + +procedure tnavigdatalink.datasetscrolled(distance: integer); +var + k1: assistivedbeventkindty; + intf1: iassistiveclient; +begin + include(fstate,nds_datasetscrolled); + inherited; + if (distance = 0) and canassistive(intf1) then begin + k1:= adek_none; + if nds_prior in fstate then begin + k1:= adek_bof; + end; + if nds_next in fstate then begin + k1:= adek_eof; + end; + if k1 <> adek_none then begin + assistiveserver.dodatasetevent(intf1,k1,dataset); + end; + end; +end; + +{ tdbnavigator } +const + dbnavigimages: array[dbnavigbuttonty] of stockglyphty = + //dbnb_first,dbnb_prior,dbnb_next,dbnb_last,dbnb_insert, + (stg_dbfirst,stg_dbprior,stg_dbnext,stg_dblast,stg_dbinsert, + +// dbnb_delete,dbnb_copyrecord,dbnb_edit, + stg_dbdelete,stg_doublesquare,stg_dbedit, +// dbnb_post,dbnb_cancel,dbnb_refresh, + stg_dbpost,stg_dbcancel,stg_dbrefresh, +// dbnb_filter,dbnb_filtermin,dbnb_filtermax,dbnb_filterclear,dbnb_filteronoff, + stg_dbfilter,stg_dbfiltermin,stg_dbfiltermax,stg_dbfilterclear,stg_dbfilteron, +// dbnb_find, + stg_dbfind, +// dbnb_autoedit,dbnb_dialog + stg_triabig,stg_ellipsesmall +); + + dbnavighints: array[dbnavigbuttonty] of stockcaptionty = + //dbnb_first,dbnb_prior,dbnb_next,dbnb_last,dbnb_insert, + (sc_first,sc_prior,sc_next,sc_last,sc_append, + +// dbnb_delete,dbnb_copyrecord,dbnb_edit, + sc_delete,sc_copy,sc_edit, +// dbnb_post,dbnb_cancel,dbnb_refresh, + sc_post,sc_cancel,sc_refresh, +// dbnb_filter,dbnb_filtermin, dbnb_filtermax, dbnb_filterclear, + sc_edit_filter,sc_edit_filter_min,sc_edit_filter_max,sc_reset_filter, +// dbnb_filteronoff,dbnb_find, + sc_filter_on,sc_search, +// dbnb_autoedit,dbnb_dialog + sc_auto_edit,sc_dialog +); + +{ tdbnavigbuttons } + +class function tdbnavigbuttons.getbuttonclass: toolbuttonclassty; +begin + result:= tdbnavigbutton; +end; + +constructor tdbnavigator.create(aowner: tcomponent); +var + int1: integer; +begin + if flayout.buttons = nil then begin + flayout.buttons:= tdbnavigbuttons.create(self); + end; + foptions:= defaultdbnavigatoroptions; + fshortcuts[dbnb_first]:= key_modctrl + ord(key_pageup); + fshortcuts[dbnb_prior]:= ord(key_pageup); + fshortcuts[dbnb_next]:= ord(key_pagedown); + fshortcuts[dbnb_last]:= key_modctrl + ord(key_pagedown); + fshortcuts[dbnb_edit]:= ord(key_f2); + fshortcuts[dbnb_post]:= ord(key_f2); +// fshortcuts[dbnb_dialog]:= ord(key_f3); + inherited; + fwidgetstate1:= fwidgetstate1 + [ws1_designactive,ws1_nodisabledclick]; + size:= makesize(defaultdbnavigatorwidth,defaultdbnavigatorheight); + include(ttoolbuttons1(buttons).fbuttonstate,tbs_nocandefocus); + buttons.count:= ord(high(dbnavigbuttonty))+1; + for int1:= 0 to ord(high(dbnavigbuttonty)) do begin + with buttons[int1] do begin + imagelist:= stockobjects.glyphs; + imagenr:= ord(dbnavigimages[dbnavigbuttonty(int1)]); + tag:= int1; + onexecute:= {$ifdef FPC}@{$endif}doexecute; + end; + end; + with buttons[ord(dbnb_autoedit)] do begin + options:= options + [mao_checkbox]; + end; + with buttons[ord(dbnb_filter)] do begin + options:= options + [mao_checkbox]; + end; + with buttons[ord(dbnb_filtermin)] do begin + options:= options + [mao_checkbox]; + end; + with buttons[ord(dbnb_filtermax)] do begin + options:= options + [mao_checkbox]; + end; + with buttons[ord(dbnb_find)] do begin + options:= options + [mao_checkbox]; + end; + with buttons[ord(dbnb_filteronoff)] do begin + options:= options + [mao_checkbox]; + end; + + fdatalink:= tnavigdatalink.Create(idbnaviglink(self)); + visiblebuttons:= defaultvisibledbnavigbuttons; +end; + +destructor tdbnavigator.destroy; +begin +// fdatalink.Free; + inherited; + fdatalink.Free; +end; + +procedure tdbnavigator.inithints; +var + int1: integer; + sc1: int32; +begin + for int1:= 0 to ord(high(dbnavigbuttonty)) do begin + with buttons[int1] do begin +// hint:= stockobjects.captions[stockcaptionty(int1+ord(sc_first))]; + hint:= stockobjects.captions[dbnavighints[dbnavigbuttonty(int1)]]; + if (dno_shortcuthint in foptions) then begin + if dbnavigbuttonty(int1) = dbnb_dialog then begin + sc1:= shortcut; + end + else begin + sc1:= fshortcuts[dbnavigbuttonty(int1)]; + end; + if sc1 <> 0 then begin + hint:= hint + ' (' + encodeshortcutname(sc1)+')'; + end; + end; + end; + end; + with buttons[ord(dbnb_insert)] do begin + if dno_append in self.options then begin + hint:= stockobjects.captions[sc_append]; + end + else begin + hint:= stockobjects.captions[sc_insert]; + end; + if (dno_shortcuthint in foptions) and + (fshortcuts[dbnb_insert] <> 0) then begin + hint:= hint + ' (' + + encodeshortcutname(fshortcuts[dbnb_insert])+')'; + end; + end; +end; + +procedure tdbnavigator.doasyncevent(var atag: integer); +begin + if atag = 0 then begin + application.mouseparkevent; + end + else begin + inherited; + end; +end; + +procedure tdbnavigator.setactivebuttons(const abuttons: dbnavigbuttonsty; + const afiltered: boolean); +var + bu1: dbnavigbuttonty; +begin + beginupdate; + try + with buttons[ord(dbnb_filteronoff)] do begin + checked:= afiltered; + { + if afiltered then begin + imagenr:= ord(stg_dbfilteroff); + hint:= stockobjects.captions[sc_filter_off]; + end + else begin + imagenr:= ord(stg_dbfilteron); + hint:= stockobjects.captions[sc_filter_on]; + end; + if (dno_shortcuthint in foptions) and + (fshortcuts[dbnb_filteronoff] <> 0) then begin + hint:= hint + ' (' + + encodeshortcutname(fshortcuts[dbnb_filteronoff])+')'; + end; + } + end; + for bu1:= low(dbnavigbuttonty) to high(dbnavigbuttonty) do begin + if (bu1 <> dbnb_dialog) or not (dno_customdialogupdate in foptions) then begin + with buttons[ord(bu1)] do begin + if bu1 in abuttons then begin + state:= state - [as_disabled]; + end + else begin + state:= state + [as_disabled]; + end; + end; + end; + end; + dialogbutton.doupdate; + finally + endupdate; + end; + if application.mousewidget = self then begin + asyncevent(0); + end; +end; + +procedure tdbnavigator.setcheckedbuttons(const abuttons: dbnavigbuttonsty; + const achecked: boolean); +var + bu1: dbnavigbuttonty; +begin + beginupdate; + try + for bu1:= low(dbnavigbuttonty) to high(dbnavigbuttonty) do begin + if bu1 in abuttons then begin + with buttons[ord(bu1)] do begin + if achecked then begin + state:= state + [as_checked]; + end + else begin + state:= state - [as_checked]; + end; + end; + end; + end; + dialogbutton.doupdate; + finally + endupdate; + end; +end; + +function tdbnavigator.getdatasource: tdatasource; +begin + result:= fdatalink.DataSource; +end; + +procedure tdbnavigator.setvisiblebuttons(const avalue: dbnavigbuttonsty); +var + bu1: dbnavigbuttonty; +begin + if fvisiblebuttons <> avalue then begin + beginupdate; + for bu1:= low(dbnavigbuttonty) to high(dbnavigbuttonty) do begin + buttons[ord(bu1)].visible:= bu1 in avalue; + end; + fvisiblebuttons:= avalue; + endupdate; + end; +end; + +function tdbnavigator.getcolorglyph: colorty; +begin + result:= buttons.colorglyph; +end; + +procedure tdbnavigator.setcolorglyph(const avalue: colorty); +begin + buttons.colorglyph:= avalue; +end; + +function tdbnavigator.getbuttonface: tface; +begin + result:= buttons.face; +end; + +procedure tdbnavigator.setbuttonface(const avalue: tface); +begin + buttons.face:= avalue; +end; + +procedure tdbnavigator.loaded; +begin + inherited; + colorglyph:= colorglyph; + inithints; + updatereadonly(true); +end; + +procedure tdbnavigator.internalshortcut(var info: keyeventinfoty; + const sender: twidget); +var + bu1: dbnavigbuttonty; +begin + if not (csdesigning in componentstate) then begin + for bu1:= low(dbnavigbuttonty) to dbnb_autoedit do begin + if checkshortcutcode(fshortcuts[bu1],info) then begin + if buttons[ord(bu1)].enabled or + (assistiveserver <> nil) and (bu1 in [dbnb_prior,dbnb_next]) then begin + fdatalink.execbutton(bu1); + include(info.eventstate,es_processed); + break; + end; + end; + end; + end; +end; + +procedure tdbnavigator.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + internalshortcut(info,sender); + if not (es_processed in info.eventstate) then begin; + inherited; + end; +end; + +procedure tdbnavigator.setdatasource(const Value: tdatasource); +begin + fdatalink.DataSource:= value; +end; + +procedure tdbnavigator.doexecute(const sender: tobject); +begin + with ttoolbutton(sender) do begin + fdatalink.execbutton(dbnavigbuttonty(tag)); + if action <> nil then begin + action.execute(); + end; + end; +end; + +function tdbnavigator.getnavigoptions: dbnavigatoroptionsty; +begin + result:= foptions; +end; + +procedure tdbnavigator.setoptions(const avalue: dbnavigatoroptionsty); +var + diff: dbnavigatoroptionsty; +begin + diff:= avalue >< foptions; + if diff <> [] then begin + foptions:= avalue; + if not (csloading in componentstate) then begin + inithints; + if dno_nonavig in diff then begin + fdatalink.updatebuttonstate() + end; + end; + end; +end; + +procedure tdbnavigator.dodialogexecute(); +begin + if canevent(tmethod(fondialogexecute)) then begin + fondialogexecute(self); + end; +end; + +procedure tdbnavigator.updatereadonly(const force: boolean = false); +var + b1: boolean; +begin + b1:= canautoedit; + if (b1 <> fcanautoeditbefore) or force then begin + fcanautoeditbefore:= b1; + if canevent(tmethod(fonreadonlychange)) then begin + fonreadonlychange(self,not b1); + end; + end; +end; + +function tdbnavigator.gettoolbutton: tdbnavigbutton; +begin + result:= tdbnavigbutton(buttons[ord(dbnb_dialog)]); +end; + +procedure tdbnavigator.settoolbutton(const avalue: tdbnavigbutton); +begin + buttons[ord(dbnb_dialog)]:= avalue; +end; + +function tdbnavigator.getautoedit: boolean; +begin + result:= buttons[ord(dbnb_autoedit)].checked; +end; + +procedure tdbnavigator.setautoedit(const avalue: boolean); +begin + if buttons[ord(dbnb_autoedit)].checked <> avalue then begin + buttons[ord(dbnb_autoedit)].checked:= avalue; + updatereadonly(); + if fobjectlinker <> nil then begin + fobjectlinker.sendevent(oe_changed); + end; + end; +end; + +procedure tdbnavigator.dostatread(const reader: tstatreader); +begin + autoedit:= reader.readboolean('autoedit',autoedit); +end; + +procedure tdbnavigator.dostatwrite(const writer: tstatwriter); +begin + writer.writeboolean('autoedit',autoedit); +end; + +procedure tdbnavigator.edit; +var + int1: integer; +begin + if fdatalink.active and (fdatalink.dataset.state = dsbrowse) then begin + int1:= -1; + if buttons[ord(dbnb_edit)].enabled then begin + int1:= ord(dbnb_edit); + end + else begin + if buttons[ord(dbnb_insert)].enabled then begin + int1:= ord(dbnb_insert); + end + end; + if int1 >= 0 then begin + fdatalink.execbutton(dbnavigbuttonty(int1)); + end; + end; +end; + +function tdbnavigator.canautoedit(): boolean; +begin + result:= autoedit or fdatalink.active and + (fdatalink.dataset.state in [dsedit,dsinsert]) +end; + +function tdbnavigator.canclose(const newfocus: twidget = nil): boolean; +begin + if (dno_postoncanclose in foptions) and fdatalink.active and + (newfocus = nil) then begin + fdatalink.dataset.checkbrowsemode; + end; + result:= inherited canclose(newfocus); +end; + +function tdbnavigator.getbuttonwidth: integer; +begin + result:= flayout.buttons.width; +end; + +procedure tdbnavigator.setbuttonwidth(const avalue: integer); +begin + flayout.buttons.width:= avalue; +end; + +function tdbnavigator.getbuttonheight: integer; +begin + result:= flayout.buttons.height; +end; + +procedure tdbnavigator.setbuttonheight(const avalue: integer); +begin + flayout.buttons.height:= avalue; +end; +{ +function tdbnavigator.getnonavig: boolean; +begin + result:= dno_nonavig in foptions; +end; + +procedure tdbnavigator.setnonavig(const avalue: boolean); +begin + if avalue then begin + options:= options + [dno_nonavig]; + end + else begin + options:= options - [dno_nonavig]; + end; +end; +} +{ tcustomeditwidgetdatalink } + +constructor tcustomeditwidgetdatalink.create(const intf: idbeditfieldlink); +//var +// intf1: iificlient; +begin + foptions:= defaulteditwidgetdatalinkoptions; + fintf:= intf; + fintf.setifiserverintf(iifidataserver(self)); +// if getcorbainterface(intf.getwidget,typeinfo(iificlient),intf1) then begin +// intf1.setifiserverintf(iifiserver(self)); +// end; + inherited Create; + visualcontrol:= true; + fintf.seteditstate(fintf.geteditstate+[des_isdb]); +// fintf.setisdb; +end; + +destructor tcustomeditwidgetdatalink.destroy; +begin + inherited; + freeandnil(fobjectlinker); +end; + +procedure tcustomeditwidgetdatalink.readdatasource(reader: treader); +begin + treader1(reader).readpropvalue(self, + getpropinfo(typeinfo(teditwidgetdatalink),'datasource')); +end; + +procedure tcustomeditwidgetdatalink.readdatafield(reader: treader); +begin + fieldname:= reader.readstring; +end; + +procedure tcustomeditwidgetdatalink.readoptionsdb(reader: treader); +begin + treader1(reader).readpropvalue(self, + getpropinfo(typeinfo(teditwidgetdatalink),'options')); +end; + +procedure tcustomeditwidgetdatalink.fixupproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('datasource',{$ifdef FPC}@{$endif}readdatasource,nil,false); + filer.defineproperty('datafield',{$ifdef FPC}@{$endif}readdatafield,nil,false); + filer.defineproperty('optionsdb',{$ifdef FPC}@{$endif}readoptionsdb,nil,false); + //move values to datalink +end; + +function tcustomeditwidgetdatalink.getasnullmsestring: msestring; +begin + if field.isnull then begin + result:= nullsymbol; + end + else begin + result:= asmsestring; + end; +end; + +procedure tcustomeditwidgetdatalink.setasnullmsestring(const avalue: msestring); +begin + if avalue = nullsymbol then begin + if oed_nonullset in foptions then begin + asmsestring:= msedefaultexpression; + end + else begin + field.clear; + end; + end + else begin + asmsestring:= avalue; + end; +end; + +procedure tcustomeditwidgetdatalink.setediting(avalue: boolean); +begin + if (fds_editing in fstate) <> avalue then begin + if avalue then begin + include(fstate,fds_editing); + end + else begin + exclude(fstate,fds_editing); + end; + exclude(fstate,fds_modified); + end; +end; + +function tcustomeditwidgetdatalink.edit: Boolean; +begin + if canmodify then begin + if (dataset.state = dsbrowse) and + ((oed_autoedit in foptions) or + (fnavigator <> nil) and fnavigator.canautoedit() + ) then begin + dataset.edit; + end + else begin + inherited edit; + end; + end; + result:= fds_editing in fstate; +end; + +function tcustomeditwidgetdatalink.canmodify: Boolean; +begin + result:= (field <> nil) and + ((fds_filterediting in fstate) or + canupdate and not field.readonly); +end; + +procedure tcustomeditwidgetdatalink.modified; +begin + if not editing and (frecordchange = 0) and + not (fds_filterediting in fstate) then begin + inc(fbeginedit); + try + edit; + finally + dec(fbeginedit); + end; + end; + include(fstate,fds_modified); +end; + +procedure tcustomeditwidgetdatalink.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + if (info.eventstate * [es_preview,es_processed] = []) and + (fnavigator <> nil) and fnavigator.showing and + fnavigator.isenabled then begin + fnavigator.internalshortcut(info,sender); + end; +end; + +procedure tcustomeditwidgetdatalink.updateoptionsedit(var avalue: optionseditty); +var + state1: tcomponentstate; +begin + state1:= fintf.getwidget.ComponentState; + if state1 * [cswriting,csdesigning] = [] then begin + if not (fds_filterediting in fstate) and + (not canmodify or + not editing and + not (canmodify and + not (oed_noautoedit in foptions) and + ((oed_autoedit in foptions) or + (datasource <> nil) and datasource.AutoEdit or + (fnavigator <> nil) and fnavigator.canautoedit + ) + ) + ) then begin + include(avalue,oe_readonly); + end; + if (field <> nil) and field.required then begin + include(avalue,oe_notnull); + end; + end; +end; + +procedure tcustomeditwidgetdatalink.editingchanged; +var + widget1: twidget; +begin + inherited; + widget1:= fintf.getwidget; + if not editing and assigned(fonendedit) and + widget1.canevent(tmethod(fonendedit)) then begin + fonendedit(self); + end; + setediting(inherited editing and canmodify); + fintf.updatereadonlystate; + if editing then begin + if (fnavigator <> nil) and (oed_syncedittonavigator in foptions) and + (dataset.state = dsedit) then begin + fnavigator.edit(); + end; + if (oed_focusoninsert in foptions) and (dataset.state = dsinsert) then begin + fintf.seteditfocus(); + end; + if assigned(fonbeginedit) and + fintf.getwidget.canevent(tmethod(fonbeginedit)) then begin + fonbeginedit(self); + end; + end; +end; + +procedure tcustomeditwidgetdatalink.dataevent(event: tdataevent; info: ptrint); +var + bo1: boolean; + bo2: boolean; +begin + bo1:= fds_filterediting in fstate; + case ord(event) of + ord(deupdatestate): begin + if (dataset <> nil) and (dataset.state = dsfilter) then begin + include(fstate,fds_filterediting); + end + else begin + exclude(fstate,fds_filterediting); + end; + end; + de_hasactiveedit: begin + with phasactiveeditinfoty(info)^ do begin + hasedit:= hasedit or (field = self.field) and + fintf.getwidget.window.active; + end; + end; + end; + inherited; + if bo1 <> (fds_filterediting in fstate) then begin + if bo1 then begin + if fds_filtereditdisabled in fstate then begin + exclude(fstate,fds_filtereditdisabled); + fintf.setenabled(true); + end; + end + else begin + case filtereditkind of + fek_filtermin: bo2:= oed_nofilterminedit in foptions; + fek_filtermax: bo2:= oed_nofiltermaxedit in foptions; + fek_find: bo2:= oed_nofindedit in foptions; + else bo2:= oed_nofilteredit in foptions; //fek_filter + end; + if bo2 then begin + include(fstate,fds_filtereditdisabled); + fintf.setenabled(false); + end; + end; + fintf.updatereadonlystate; + end; +end; + +procedure tcustomeditwidgetdatalink.bindingchanged; +begin + if active and (field <> nil) and isstringfield{ + (field.datatype in [ftstring,ftfixedchar])} then begin + if ismsestring then begin + fmaxlength:= tmsestringfield(field).characterlength; + end + else begin + fmaxlength:= field.size; + end; + if fmaxlength < 0 then begin + fmaxlength:= 0; + end; + end + else begin + fmaxlength:= 0; + end; + + if oed_limitcharlen in foptions then begin + if fmaxlength = 0 then begin + fintf.setmaxlength(-1); + end + else begin + fintf.setmaxlength(fmaxlength); + end; + end; +end; + +procedure tcustomeditwidgetdatalink.activechanged; +begin + if not active then begin + fstate:= fstate - [fds_filterediting,fds_filtereditdisabled]; + end; + fintf.updatereadonlystate; + try + inherited; + except + on e: exception do begin + e.message:= fintf.getwidget.name + ': ' + e.message; + raise + end; + end; + bindingchanged; +end; + +procedure tcustomeditwidgetdatalink.disabledstatechange; +begin + inherited; + fintf.updatereadonlystate; +end; + +function tcustomeditwidgetdatalink.getdataset(const aindex: integer): tdataset; +begin + result:= dataset; +end; + +procedure tcustomeditwidgetdatalink.getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); +begin + apropertynames:= nil; + setlength(afieldtypes,1); + fintf.getfieldtypes(afieldtypes[0]); + if afieldtypes[0] = [] then begin + afieldtypes:= nil; + end; +end; + +procedure tcustomeditwidgetdatalink.focuscontrol(afield: tfieldref); +begin + if (afield^ = field) and (field <> nil) then begin + if fintf.seteditfocus then begin + afield^:= nil; + end; + end; +end; + +procedure tcustomeditwidgetdatalink.recordchanged(afield: tfield); +var + wi1: twidget; + intf1: iassistiveclientdata; +begin + if (afield = nil) or (afield = field) then begin + if (fbeginedit = 0) and (frecordchange = 0) then begin + inc(frecordchange); + try + if (field <> nil) and active and + not (dataset.eof and dataset.bof and + not (dataset.state in [dsinsert,dsfilter])) then begin + if field.isnull then begin + fintf.setnullvalue; + end + else begin + fintf.fieldtovalue; + end; + end + else begin + fintf.setnullvalue; + end; + wi1:= fintf.getwidget; + if wi1.focused then begin + fintf.initeditfocus; + end; + if (assistiveserver <> nil) and wi1.active and + wi1.getcorbainterface(typeinfo(iassistiveclientdata),intf1) then begin + assistiveserver.dodbvaluechanged(intf1); + end; + finally + dec(frecordchange); + end; + end; + exclude(fstate,fds_modified); + end; +end; + +procedure tcustomeditwidgetdatalink.datasetscrolled(distance: integer); +begin + if distance <> 0 then begin + inherited; + end; +end; + +procedure tcustomeditwidgetdatalink.updatedata; +var + stat1: dataeditstatesty; +begin + inc(fcanclosing); + stat1:= fintf.geteditstate; + if not (des_dbnullcheck in stat1) then begin + fintf.seteditstate(stat1+[des_dbnullcheck]); + end; + try + with fintf.getwidget do begin + if canclose(nil) then begin + exclude(fstate,fds_modified); + end + else begin + activate; + raise eabort.create(''); + end; + end; + if not (oed_nullset in foptions) and (field <> nil) then begin + if ismsestring then begin + with tmsestringfield(field) do begin + if (defaultexpression <> '') and isnull and + (dataset.modified or + (fdscontroller <> nil) and fdscontroller.posting) then begin + asmsestring:= self.msedefaultexpression; + end; + end; + end + else begin + with field do begin + if (defaultexpression <> '') and isnull and + (dataset.modified or + (fdscontroller <> nil) and fdscontroller.posting) then begin + asstring:= defaultexpression; + end; + end; + end; + end; + inherited; + finally + dec(fcanclosing); + if not (des_dbnullcheck in stat1) then begin + fintf.seteditstate(fintf.geteditstate-[des_dbnullcheck]); + end; + end; +end; + +function tcustomeditwidgetdatalink.getdatasource1: tdatasource; +begin + result:= inherited datasource; +end; + +procedure tcustomeditwidgetdatalink.setwidgetdatasource(const avalue: tdatasource); +begin + if not ((csloading in fintf.getwidget.componentstate) and datasourcefixed or + (fintf.getgridintf <> nil)) then begin + inherited datasource:= avalue; + end; +end; + +procedure tcustomeditwidgetdatalink.griddatasourcechanged; +var + datasource1: tdatasource; +begin + datasource1:= fintf.getgriddatasource; + if datasource <> datasource1 then begin + datasource:= datasource1; + end; +end; + +procedure tcustomeditwidgetdatalink.nullcheckneeded(var avalue: boolean); + function findactivedatalink: boolean; + var + info1: hasactiveeditinfoty; + begin + with info1 do begin + hasedit:= false; + field:= self.field; + tdataset1(dataset).dataevent(tdataevent(de_hasactiveedit),ptruint(@info1)); + result:= hasedit; + end; + end; //findactivedatalink + +begin + avalue:= active and + ( + (avalue or fintf.getedited and (oed_autopost in foptions) or + (fcanclosing > 0) + ) and + ((dataset.state in [dsinsert,dsedit]) and + (dataset.modified or + avalue and (oed_nullcheckifunmodified in foptions) or + (dataset.state <> dsinsert) or + (fdscontroller <> nil) and fdscontroller.posting + ) + ) + ); + avalue:= avalue and (fintf.getwidget.window.active or not findactivedatalink); +end; + +function tcustomeditwidgetdatalink.cuttext(const atext: msestring; + out maxlength: integer): boolean; +begin + maxlength:= fmaxlength; + result:= (maxlength > 0) and (length(atext) > maxlength); +end; + +function tcustomeditwidgetdatalink.getownerwidget: twidget; +begin + result:= fintf.getwidget; +end; + +procedure tcustomeditwidgetdatalink.setnavigator(const avalue: tdbnavigator); +begin + getobjectlinker.setlinkedvar(iobjectlink(self),tmsecomponent(avalue), + tmsecomponent(fnavigator)); +end; + +function tcustomeditwidgetdatalink.getobjectlinker: tobjectlinker; +begin + createobjectlinker(self,{$ifdef FPC}@{$endif}objectevent,fobjectlinker); + result:= fobjectlinker; +end; + +procedure tcustomeditwidgetdatalink.link(const source: iobjectlink; + const dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); +begin + getobjectlinker.link(source,dest,valuepo,ainterfacetype,once); +end; + +procedure tcustomeditwidgetdatalink.unlink(const source: iobjectlink; + const dest: iobjectlink; valuepo: pointer = nil); +begin + getobjectlinker.unlink(source,dest,valuepo); +end; + +procedure tcustomeditwidgetdatalink.objevent(const sender: iobjectlink; + const event: objecteventty); +begin + getobjectlinker.objevent(sender,event); +end; + +function tcustomeditwidgetdatalink.getinstance: tobject; +begin + result:= self; +end; + +procedure tcustomeditwidgetdatalink.objectevent(const sender: tobject; + const event: objecteventty); +begin + if (sender = fnavigator) and (event = oe_changed) then begin + fintf.updatereadonlystate; + end; +end; + +procedure tcustomeditwidgetdatalink.fieldchanged; +begin + bindingchanged; + inherited; +end; + +procedure tcustomeditwidgetdatalink.setoptions(const avalue: optionseditdbty); +begin + foptions:= optionseditdbty( + setsinglebit(card32(avalue), + card32(foptions),[card32([oed_autoedit,oed_noautoedit]), + card32([oed_readonly,oed_noreadonly])])); +end; + +function tcustomeditwidgetdatalink.datasourcereadonly(): boolean; +begin + result:= inherited datasourcereadonly(); + if oed_readonly in foptions then begin + result:= true; + end; + if oed_noreadonly in foptions then begin + result:= false; + end; +end; + +procedure tcustomeditwidgetdatalink.valuechanged(const sender: iifidatalink); +var + widget1: twidget; + bo1,bo2: boolean; +begin + if (frecordchange = 0) and (fposting = 0) then begin + widget1:= fintf.getwidget; + if not (ws_loadedproc in widget1.widgetstate) and (field <> nil) and + not ((oe_checkmrcancel in fintf.getoptionsedit) and + (widget1.window.modalresult = mr_cancel)) then begin + if fds_filterediting in fstate then begin + fintf.valuetofield; + end + else begin + if editing then begin + fintf.valuetofield; + if assigned(fondataentered) and + fintf.getwidget.canevent(tmethod(fondataentered)) then begin + fondataentered(self); + end; + if (oed_autopost in foptions) and active then begin + widget1:= widget1.parentwidget; + try + inc(fposting); + if (widget1 <> nil) then begin + if widget1.parentwidget is tcustomgrid then begin + with tcustomgrid1(widget1.parentwidget) do begin + bo1:= fnonullcheck > 0; + if bo1 then begin + dec(fnonullcheck); //remove colchangelock + end; + end; + end + else begin + bo1:= false; + end; + try + bo2:= widget1.canparentclose; + finally + if bo1 then begin + inc(tcustomgrid1(widget1.parentwidget).fnonullcheck); + end; + end; + end; + if bo2 then begin + dataset.post; + end; + finally + dec(fposting); + end; + end; + end; + end; + end; + end; +end; +{ +procedure tcustomeditwidgetdatalink.statechanged(const sender: iificlient; + const astate: ifiwidgetstatesty); +begin +end; + +procedure tcustomeditwidgetdatalink.setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); +begin +end; + +procedure tcustomeditwidgetdatalink.sendmodalresult(const sender: iificlient; + const amodalresult: modalresultty); +begin +end; + +procedure tcustomeditwidgetdatalink.dataentered(const sender: iificlient; + const arow: integer); +begin +end; +} + +{ tdbstringedit } + +constructor tdbstringedit.create(aowner: tcomponent); +begin + fdatalink:= tstringeditwidgetdatalink.Create(idbeditfieldlink(self)); + inherited; +end; + +destructor tdbstringedit.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tdbstringedit.modified; +begin + fdatalink.modified; + inherited; +end; + +procedure tdbstringedit.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; +{ +function tdbstringedit.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); +end; +} +procedure tdbstringedit.valuetofield; +begin + fdatalink.asnullmsestring:= value; +end; + +procedure tdbstringedit.fieldtovalue; +begin + value:= fdatalink.asnullmsestring; +end; + +function tdbstringedit.getnulltext: msestring; +begin + result:= fdatalink.nullsymbol; +end; + +function tdbstringedit.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink).getstringbuffer(fdatalink.field,arow); + end + else begin + result:= nil; + end; +end; + +function tdbstringedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdbstringedit.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdbstringedit.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +procedure tdbstringedit.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= textfields; +end; + +function tdbstringedit.nullcheckneeded(const newfocus: twidget): boolean; +begin + result:= inherited nullcheckneeded(newfocus); + fdatalink.nullcheckneeded(result); +end; + +procedure tdbstringedit.setdatalink(const adatalink: tstringeditwidgetdatalink); +begin + fdatalink.assign(adatalink); +end; + +procedure tdbstringedit.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + + { repaced by oed_limitcharlen + +procedure tdbstringedit.editnotification(var info: editnotificationinfoty); +var + int1: integer; +begin + inherited; + if info.action = ea_textedited then begin + if fdatalink.cuttext(text,int1) then begin + text:= copy(text,1,int1); + end; + end; +end; + } + +procedure tdbstringedit.recchanged; +begin + fdatalink.recordchanged(nil); +end; +{ +procedure tdbstringedit.dochange; +begin + fdatalink.datachanged; + inherited; +end; + +procedure tdbstringedit.doenter; +begin + fdatalink.doenter(self); + inherited; +end; + +procedure tdbstringedit.doexit; +begin + fdatalink.doexit(self); + inherited; +end; +} +function tdbstringedit.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; + +{ +constructor tdbdialogstringedit.create(aowner: tcomponent); +begin + fdatalink:= tstringeditwidgetdatalink.Create(idbeditfieldlink(self)); + inherited; +end; + +destructor tdbdialogstringedit.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tdbdialogstringedit.modified; +begin + fdatalink.Modified; + inherited; +end; + +function tdbdialogstringedit.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); +end; + +procedure tdbdialogstringedit.valuetofield; +begin + if value = '' then begin + fdatalink.field.clear; + end + else begin + fdatalink.asmsestring:= value; + end; +end; + +procedure tdbdialogstringedit.fieldtovalue; +begin + value:= fdatalink.asmsestring; +end; + +function tdbdialogstringedit.getrowdatapo(const info: cellinfoty): pointer; +begin + with info do begin + if griddatalink <> nil then begin + result:= tgriddatalink(griddatalink).getstringbuffer(fdatalink.field,cell.row); + end + else begin + result:= nil; + end; + end; +end; + +function tdbdialogstringedit.getnulltext: msestring; +begin + result:= fdatalink.nullsymbol; +end; + +function tdbdialogstringedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdbdialogstringedit.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdbdialogstringedit.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +procedure tdbdialogstringedit.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= textfields; +end; + +function tdbdialogstringedit.nullcheckneeded(const newfocus: twidget): boolean; +begin + result:= inherited nullcheckneeded(newfocus); + fdatalink.nullcheckneeded(result); +end; + +procedure tdbdialogstringedit.setdatalink(const avalue: tstringeditwidgetdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbdialogstringedit.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +procedure tdbdialogstringedit.recchanged; +begin + fdatalink.recordchanged(nil); +end; + +procedure tdbdialogstringedit.dochange; +begin + fdatalink.dataentered; + inherited; +end; +} + +{ tcustomdbdropdownlistedit } + +constructor tcustomdbdropdownlistedit.create(aowner: tcomponent); +begin + fdatalink:= tstringeditwidgetdatalink.Create(idbeditfieldlink(self)); + inherited; +end; + +destructor tcustomdbdropdownlistedit.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tcustomdbdropdownlistedit.modified; +begin + fdatalink.Modified; + inherited; +end; + +procedure tcustomdbdropdownlistedit.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; +{ +function tcustomdbdropdownlistedit.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); +end; +} +procedure tcustomdbdropdownlistedit.valuetofield; +begin + if value = '' then begin + fdatalink.field.clear; + end + else begin + fdatalink.asmsestring:= value; + end; +end; + +procedure tcustomdbdropdownlistedit.fieldtovalue; +begin + value:= fdatalink.asmsestring; +end; + +function tcustomdbdropdownlistedit.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink).getstringbuffer(fdatalink.field,arow); + end + else begin + result:= nil; + end; +end; + +function tcustomdbdropdownlistedit.getnulltext: msestring; +begin + result:= fdatalink.nullsymbol; +end; + +function tcustomdbdropdownlistedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tcustomdbdropdownlistedit.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tcustomdbdropdownlistedit.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +procedure tcustomdbdropdownlistedit.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= textfields; +end; + +function tcustomdbdropdownlistedit.nullcheckneeded( + const newfocus: twidget): boolean; +begin + result:= inherited nullcheckneeded(newfocus); + fdatalink.nullcheckneeded(result); +end; + +procedure tcustomdbdropdownlistedit.setdatalink( + const avalue: tstringeditwidgetdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tcustomdbdropdownlistedit.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +procedure tcustomdbdropdownlistedit.recchanged; +begin + fdatalink.recordchanged(nil); +end; +{ +procedure tcustomdbdropdownlistedit.dochange; +begin + fdatalink.datachanged; + inherited; +end; +} +function tcustomdbdropdownlistedit.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; + +function tcustomdbdropdownlistedit.getdropdownifilink: tifidropdownlistlinkcomp; +begin + result:= fdropdownifilink; +end; + +procedure tcustomdbdropdownlistedit.setdropdownifilink( + const avalue: tifidropdownlistlinkcomp); +begin + mseificomp.setifilinkcomp(idbifidropdownlistdatalink(self),avalue, + tifilinkcomp(fdropdownifilink)); +end; + +procedure tcustomdbdropdownlistedit.dropdownsetifiserverintf( + const aintf: iifiserver); +begin + fdropdownifiserverintf:= aintf; +end; + +procedure tcustomdbdropdownlistedit.dropdownifisetvalue(var avalue; + var accept: boolean); +begin + //dummy +end; +{ +procedure tcustomdbdropdownlistedit.doenter; +begin + fdatalink.doenter(self); + inherited; +end; + +procedure tcustomdbdropdownlistedit.doexit; +begin + fdatalink.doexit(self); + inherited; +end; +} +{ tdbkeystringedit } + +constructor tdbkeystringedit.create(aowner: tcomponent); +begin + fdatalink:= tstringlookupeditdatalink.Create(self,ldt_string, + idbeditfieldlink(self)); + inherited; +end; + +destructor tdbkeystringedit.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tdbkeystringedit.modified; +begin + fdatalink.modified; + inherited; +end; +{ +function tdbkeystringedit.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); +// frame.readonly:= oe_readonly in result; +end; +} +procedure tdbkeystringedit.valuetofield; +begin + if value = '' then begin + fdatalink.field.clear; + if fdatalink.fieldtext <> nil then begin + fdatalink.fieldtext.clear; + end; + end + else begin + fdatalink.asmsestring:= value; + setasmsestring(text,fdatalink.fieldtext,fdatalink.utf8) + end; +end; + +procedure tdbkeystringedit.fieldtovalue; +begin + value:= fdatalink.asmsestring; +end; + +function tdbkeystringedit.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink).getstringbuffer(fdatalink.field,arow); + end + else begin + result:= nil; + end; +end; + +function tdbkeystringedit.getnulltext: msestring; +begin + result:= fdatalink.nullsymbol; +end; + +function tdbkeystringedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdbkeystringedit.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdbkeystringedit.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +procedure tdbkeystringedit.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= textfields; +end; + +function tdbkeystringedit.nullcheckneeded(const newfocus: twidget): boolean; +begin + result:= inherited nullcheckneeded(newfocus); + fdatalink.nullcheckneeded(result); +end; + +procedure tdbkeystringedit.setdatalink(const avalue: tstringlookupeditdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbkeystringedit.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +procedure tdbkeystringedit.recchanged; +begin + fdatalink.recordchanged(nil); +end; +{ +procedure tdbkeystringedit.dochange; +begin + fdatalink.datachanged; + inherited; +end; +} +function tdbkeystringedit.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; +{ +procedure tdbkeystringedit.doenter; +begin + fdatalink.doenter(self); + inherited; +end; + +procedure tdbkeystringedit.doexit; +begin + fdatalink.doexit(self); + inherited; +end; +} +{ tdbmemoedit } + +constructor tdbmemoedit.create(aowner: tcomponent); +begin + fdatalink:= tstringeditwidgetdatalink.create(idbeditfieldlink(self)); + inherited; +end; + +destructor tdbmemoedit.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tdbmemoedit.modified; +begin + fdatalink.modified; + inherited; +end; + +procedure tdbmemoedit.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; +{ +function tdbmemoedit.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); +end; +} +procedure tdbmemoedit.valuetofield; +begin + if value = '' then begin + fdatalink.field.clear; + end + else begin + fdatalink.asmsestring:= value; + end; +end; + +procedure tdbmemoedit.fieldtovalue; +begin + value:= fdatalink.asmsestring; +end; + +function tdbmemoedit.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink).getstringbuffer(fdatalink.field,arow); + end + else begin + result:= nil; + end; +end; + +function tdbmemoedit.getnulltext: msestring; +begin + result:= fdatalink.nullsymbol; +end; + +function tdbmemoedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdbmemoedit.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdbmemoedit.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +procedure tdbmemoedit.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= memofields; +end; + +function tdbmemoedit.nullcheckneeded(const newfocus: twidget): boolean; +begin + result:= inherited nullcheckneeded(newfocus); + fdatalink.nullcheckneeded(result); +end; + +procedure tdbmemoedit.setdatalink(const avalue: tstringeditwidgetdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbmemoedit.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +procedure tdbmemoedit.recchanged; +begin + fdatalink.recordchanged(nil); +end; +{ +procedure tdbmemoedit.dochange; +begin + fdatalink.datachanged; + inherited; +end; +} +function tdbmemoedit.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; +{ +procedure tdbmemoedit.doenter; +begin + fdatalink.doenter(self); + inherited; +end; + +procedure tdbmemoedit.doexit; +begin + fdatalink.doexit(self); + inherited; +end; +} +{ tdbintegeredit } + +constructor tdbintegeredit.create(aowner: tcomponent); +begin + fisnull:= true; + fdatalink:= teditwidgetdatalink.Create(idbeditfieldlink(self)); + inherited; +end; + +destructor tdbintegeredit.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tdbintegeredit.modified; +begin + fdatalink.modified; + inherited; +end; + +procedure tdbintegeredit.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; +{ +function tdbintegeredit.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); +end; +} +{ +procedure tdbintegeredit.setnullvalue; +begin + inherited; + fisnull:= true; +end; +} +function tdbintegeredit.internaldatatotext(const data): msestring; +begin + if (@data = nil) and fisnull then begin + result:= ''; + end + else begin + result:= inherited internaldatatotext(data); + end; +end; + +procedure tdbintegeredit.texttovalue(var accept: boolean; const quiet: boolean); +begin + fisnull:= text = ''; + inherited; +end; + +procedure tdbintegeredit.valuetofield; +begin + if fisnull then begin + fdatalink.field.clear; + end + else begin + fdatalink.field.asinteger:= value; + end; +end; + +procedure tdbintegeredit.fieldtovalue; +begin + fisnull:= false; + value:= fdatalink.field.asinteger; +end; + +function tdbintegeredit.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink).getintegerbuffer(fdatalink.field,arow); + end + else begin + result:= nil; + end; +end; + +procedure tdbintegeredit.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdbintegeredit.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +function tdbintegeredit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdbintegeredit.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= integerfields; +end; + +function tdbintegeredit.nullcheckneeded(const newfocus: twidget): boolean; +begin + result:= inherited nullcheckneeded(newfocus); + fdatalink.nullcheckneeded(result); +end; + +procedure tdbintegeredit.setdatalink(const avalue: teditwidgetdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbintegeredit.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +procedure tdbintegeredit.recchanged; +begin + fdatalink.recordchanged(nil); +end; +{ +procedure tdbintegeredit.dochange; +begin + fdatalink.datachanged; + inherited; +end; +} +function tdbintegeredit.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; +{ +procedure tdbintegeredit.doenter; +begin + fdatalink.doenter(self); + inherited; +end; + +procedure tdbintegeredit.doexit; +begin + fdatalink.doexit(self); + inherited; +end; +} +{ tdbbooleanedit } + +constructor tdbbooleanedit.create(aowner: tcomponent); +begin + fdatalink:= teditwidgetdatalink.Create(idbeditfieldlink(self)); + inherited; +end; + +destructor tdbbooleanedit.destroy; +begin + inherited; + fdatalink.free; +end; + +function tdbbooleanedit.checkvalue(const quiet: boolean = false): boolean; +begin + result:= false; + //dummy +end; +{ +function tdbbooleanedit.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); +end; +} +procedure tdbbooleanedit.valuetofield; +begin + fdatalink.field.asboolean:= value; +end; + +procedure tdbbooleanedit.fieldtovalue; +begin + value:= fdatalink.field.asboolean; +end; + +function tdbbooleanedit.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink).getbooleanbuffer(fdatalink.field,arow); + end + else begin + result:= nil; + end; +end; + +function tdbbooleanedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdbbooleanedit.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdbbooleanedit.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +procedure tdbbooleanedit.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= booleanfields; +end; + +procedure tdbbooleanedit.setdatalink(const avalue: teditwidgetdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbbooleanedit.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +procedure tdbbooleanedit.recchanged; +begin + fdatalink.recordchanged(nil); +end; +{ +procedure tdbbooleanedit.dochange; +begin + fdatalink.datachanged; + inherited; +end; +} +procedure tdbbooleanedit.modified; +begin + fdatalink.modified; + inherited; +end; + +procedure tdbbooleanedit.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +procedure tdbbooleanedit.setmaxlength(const avalue: integer); +begin + //dummy +end; + +function tdbbooleanedit.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; +{ +procedure tdbbooleanedit.doenter; +begin + fdatalink.doenter(self); + inherited; +end; + +procedure tdbbooleanedit.doexit; +begin + fdatalink.doexit(self); + inherited; +end; +} +{ tdbdataicon } + +constructor tdbdataicon.create(aowner: tcomponent); +begin + fdatalink:= teditwidgetdatalink.Create(idbeditfieldlink(self)); + inherited; +end; + +destructor tdbdataicon.destroy; +begin + inherited; + fdatalink.free; +end; + +function tdbdataicon.checkvalue(const quiet: boolean = false): boolean; +begin + result:= false; + //dummy +end; +{ +function tdbdataicon.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); +end; +} +procedure tdbdataicon.valuetofield; +begin + if value = -1 then begin + fdatalink.field.clear; + end + else begin + fdatalink.field.asinteger:= value; + end; +end; + +procedure tdbdataicon.fieldtovalue; +begin + value:= fdatalink.field.asinteger; +end; + +function tdbdataicon.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink).getintegerbuffer(fdatalink.field,arow); + end + else begin + result:= nil; + end; +end; + +function tdbdataicon.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdbdataicon.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdbdataicon.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +procedure tdbdataicon.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= integerfields; +end; + +procedure tdbdataicon.setdatalink(const avalue: teditwidgetdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbdataicon.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +procedure tdbdataicon.recchanged; +begin + fdatalink.recordchanged(nil); +end; +{ +procedure tdbdataicon.dochange; +begin + fdatalink.datachanged; + inherited; +end; +} +procedure tdbdataicon.modified; +begin + fdatalink.modified; + inherited; +end; + +procedure tdbdataicon.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +procedure tdbdataicon.setmaxlength(const avalue: integer); +begin + //dummy +end; + +function tdbdataicon.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; +{ +procedure tdbdataicon.doenter; +begin + fdatalink.doenter(self); + inherited; +end; + +procedure tdbdataicon.doexit; +begin + fdatalink.doexit(self); + inherited; +end; +} +{ tdbdatabutton } + +constructor tdbdatabutton.create(aowner: tcomponent); +begin + fdatalink:= teditwidgetdatalink.Create(idbeditfieldlink(self)); + inherited; +end; + +destructor tdbdatabutton.destroy; +begin + inherited; + fdatalink.free; +end; + +function tdbdatabutton.checkvalue(const quiet: boolean = false): boolean; +begin + result:= false; + //dummy +end; +{ +function tdbdatabutton.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); +end; +} +procedure tdbdatabutton.valuetofield; +begin + if value = -1 then begin + fdatalink.field.clear; + end + else begin + fdatalink.field.asinteger:= value; + end; +end; + +procedure tdbdatabutton.fieldtovalue; +begin + value:= fdatalink.field.asinteger; +end; + +function tdbdatabutton.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink).getintegerbuffer(fdatalink.field,arow); + end + else begin + result:= nil; + end; +end; + +function tdbdatabutton.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdbdatabutton.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdbdatabutton.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +procedure tdbdatabutton.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= integerfields; +end; + +procedure tdbdatabutton.setdatalink(const avalue: teditwidgetdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbdatabutton.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +procedure tdbdatabutton.recchanged; +begin + fdatalink.recordchanged(nil); +end; +{ +procedure tdbdatabutton.dochange; +begin + fdatalink.datachanged; + inherited; +end; +} +procedure tdbdatabutton.modified; +begin + if fresetting = 0 then begin + fdatalink.modified; + end; + inherited; +end; + +procedure tdbdatabutton.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +procedure tdbdatabutton.setmaxlength(const avalue: integer); +begin + //dummy +end; + +function tdbdatabutton.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; +{ +procedure tdbdatabutton.doenter; +begin + fdatalink.doenter(self); + inherited; +end; + +procedure tdbdatabutton.doexit; +begin + fdatalink.doexit(self); + inherited; +end; +} +{ tdbbooleaneditradio } + +constructor tdbbooleaneditradio.create(aowner: tcomponent); +begin + fdatalink:= teditwidgetdatalink.create(idbeditfieldlink(self)); + inherited; +end; + +destructor tdbbooleaneditradio.destroy; +begin + inherited; + fdatalink.free; +end; + +function tdbbooleaneditradio.checkvalue(const quiet: boolean = false): boolean; +begin + result:= true;//dummy +end; + +function tdbbooleaneditradio.docheckvalue(var avalue; + const quiet: boolean): boolean; +var + widget: twidget; + int1: integer; + bo1: boolean; +begin + if boolean(avalue) and (fparentwidget <> nil) then begin + bo1:= false; + for int1:= 0 to fparentwidget.widgetcount - 1 do begin + widget:= fparentwidget.widgets[int1]; + if (widget is tdbbooleaneditradio) and (widget <> self) and + (tcustombooleaneditradio(widget).group = group) then begin + tdbbooleaneditradio(widget).docheckvalue(bo1,quiet); + end; + end; + end; + result:= inherited docheckvalue(avalue,quiet); +end; +{ +procedure tdbbooleaneditradio.dochange; +begin + fdatalink.datachanged; + inherited; +end; +} +procedure tdbbooleaneditradio.modified; +begin + if fresetting = 0 then begin + fdatalink.modified; + end; + inherited; +end; + +procedure tdbbooleaneditradio.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; +{ +function tdbbooleaneditradio.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); +end; +} +procedure tdbbooleaneditradio.valuetofield; +begin + fdatalink.field.asboolean:= value; +end; + +procedure tdbbooleaneditradio.fieldtovalue; +begin + value:= fdatalink.field.asboolean; +end; + +function tdbbooleaneditradio.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink).getbooleanbuffer(fdatalink.field,arow); + end + else begin + result:= nil; + end; +end; + +function tdbbooleaneditradio.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdbbooleaneditradio.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdbbooleaneditradio.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +procedure tdbbooleaneditradio.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= booleanfields; +end; + +procedure tdbbooleaneditradio.setdatalink(const avalue: teditwidgetdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbbooleaneditradio.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +procedure tdbbooleaneditradio.recchanged; +begin + fdatalink.recordchanged(nil); +end; + +procedure tdbbooleaneditradio.setmaxlength(const avalue: integer); +begin + //dummy +end; + +function tdbbooleaneditradio.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; +{ +procedure tdbbooleaneditradio.doenter; +begin + fdatalink.doenter(self); + inherited; +end; + +procedure tdbbooleaneditradio.doexit; +begin + fdatalink.doexit(self); + inherited; +end; +} +{ tdbrealedit } + +constructor tdbrealedit.create(aowner: tcomponent); +begin + fdatalink:= teditwidgetdatalink.Create(idbeditfieldlink(self)); + inherited; +end; + +destructor tdbrealedit.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tdbrealedit.modified; +begin + fdatalink.Modified; + inherited; +end; + +procedure tdbrealedit.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; +{ +function tdbrealedit.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); +end; +} +procedure tdbrealedit.valuetofield; +begin + if value = emptyreal then begin + fdatalink.field.clear; + end + else begin + fdatalink.field.asfloat:= value; + end; +end; + +procedure tdbrealedit.fieldtovalue; +begin + if fdatalink.field.isnull then begin + value:= emptyreal; + end + else begin + value:= fdatalink.field.asfloat; + end; +end; + +function tdbrealedit.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink).getrealtybuffer(fdatalink.field,arow); + end + else begin + result:= nil; + end; +end; + +function tdbrealedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdbrealedit.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdbrealedit.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +procedure tdbrealedit.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= realfields + integerfields; +end; + +function tdbrealedit.nullcheckneeded(const newfocus: twidget): boolean; +begin + result:= inherited nullcheckneeded(newfocus); + fdatalink.nullcheckneeded(result); +end; + +procedure tdbrealedit.setdatalink(const avalue: teditwidgetdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbrealedit.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +procedure tdbrealedit.recchanged; +begin + fdatalink.recordchanged(nil); +end; +{ +procedure tdbrealedit.dochange; +begin + fdatalink.datachanged; + inherited; +end; +} +function tdbrealedit.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; +{ +procedure tdbrealedit.doenter; +begin + fdatalink.doenter(self); + inherited; +end; + +procedure tdbrealedit.doexit; +begin + fdatalink.doexit(self); + inherited; +end; +} +{ tdbrealspinedit } + +constructor tdbrealspinedit.create(aowner: tcomponent); +begin + fdatalink:= teditwidgetdatalink.Create(idbeditfieldlink(self)); + inherited; +end; + +destructor tdbrealspinedit.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tdbrealspinedit.modified; +begin + fdatalink.Modified; + inherited; +end; + +procedure tdbrealspinedit.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; +{ +function tdbrealspinedit.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); +end; +} +procedure tdbrealspinedit.valuetofield; +begin + if value = emptyreal then begin + fdatalink.field.clear; + end + else begin + fdatalink.field.asfloat:= value; + end; +end; + +procedure tdbrealspinedit.fieldtovalue; +begin + if fdatalink.field.isnull then begin + value:= emptyreal; + end + else begin + value:= fdatalink.field.asfloat; + end; +end; + +function tdbrealspinedit.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink).getrealtybuffer(fdatalink.field,arow); + end + else begin + result:= nil; + end; +end; + +function tdbrealspinedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdbrealspinedit.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdbrealspinedit.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +procedure tdbrealspinedit.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= realfields + integerfields; +end; + +function tdbrealspinedit.nullcheckneeded(const newfocus: twidget): boolean; +begin + result:= inherited nullcheckneeded(newfocus); + fdatalink.nullcheckneeded(result); +end; + +procedure tdbrealspinedit.setdatalink(const avalue: teditwidgetdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbrealspinedit.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +procedure tdbrealspinedit.recchanged; +begin + fdatalink.recordchanged(nil); +end; +{ +procedure tdbrealspinedit.dochange; +begin + fdatalink.datachanged; + inherited; +end; +} +function tdbrealspinedit.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; +{ +procedure tdbrealspinedit.doenter; +begin + fdatalink.doenter(self); + inherited; +end; + +procedure tdbrealspinedit.doexit; +begin + fdatalink.doexit(self); + inherited; +end; +} +{ tdbslider } + +constructor tdbslider.create(aowner: tcomponent); +begin +// fisdb:= true; + fvaluerange:= 1; + fdatalink:= teditwidgetdatalink.create(idbeditfieldlink(self)); + inherited; +end; + +destructor tdbslider.destroy; +begin + inherited; + fdatalink.free; +end; + +function tdbslider.checkvalue(const quiet: boolean = false): boolean; +begin + result:= false; + //dummy +end; +{ +function tdbslider.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); +end; +} +procedure tdbslider.valuetofield; +begin + if value = emptyreal then begin + fdatalink.field.clear; + end + else begin + fdatalink.field.asfloat:= applyrange(value,valuerange,valuestart); + end; +end; + +procedure tdbslider.fieldtovalue; +begin + if fdatalink.field.isnull then begin + value:= emptyreal; + end + else begin + value:= reapplyrange(fdatalink.field.asfloat,valuerange,valuestart); + end; +end; + +function tdbslider.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink).getrealtybuffer(fdatalink.field,arow); + if result <> nil then begin + preal(result)^:= reapplyrange(preal(result)^,valuerange,valuestart); + end; + end + else begin + result:= nil; + end; +end; + +function tdbslider.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdbslider.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdbslider.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +procedure tdbslider.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= realfields + integerfields; +end; + +procedure tdbslider.setdatalink(const avalue: teditwidgetdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbslider.readvaluescale(reader: treader); +begin + valuerange:= valuescaletorange(reader); +end; + +procedure tdbslider.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink + filer.defineproperty('valuescale',{$ifdef FPC}@{$endif}readvaluescale,nil,false); +end; + +procedure tdbslider.recchanged; +begin + fdatalink.recordchanged(nil); +end; +{ +procedure tdbslider.dochange; +begin + fdatalink.datachanged; + inherited; +end; +} +procedure tdbslider.modified; +begin + fdatalink.modified; + inherited; +end; + +procedure tdbslider.doshortcut(var info: keyeventinfoty; const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +procedure tdbslider.setmaxlength(const avalue: integer); +begin + //dummy +end; + +function tdbslider.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; +{ +procedure tdbslider.doenter; +begin + fdatalink.doenter(self); + inherited; +end; + +procedure tdbslider.doexit; +begin + fdatalink.doexit(self); + inherited; +end; +} +{ tdbprogressbar } + +constructor tdbprogressbar.create(aowner: tcomponent); +begin +// fisdb:= true; + fdatalink:= teditwidgetdatalink.Create(idbeditfieldlink(self)); + inherited; +end; + +destructor tdbprogressbar.destroy; +begin + inherited; + fdatalink.free; +end; + +function tdbprogressbar.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink).getrealtybuffer(fdatalink.field,arow); + if result <> nil then begin + preal(result)^:= reapplyrange(preal(result)^,valuerange,valuestart); + end; + end + else begin + result:= nil; + end; +end; + +procedure tdbprogressbar.valuetofield; +//var +// rea1: real; +begin + if value = emptyreal then begin + fdatalink.field.clear; + end + else begin + fdatalink.field.asfloat:= applyrange(value,valuerange,valuestart); + end; +end; + +procedure tdbprogressbar.fieldtovalue; +begin + if fdatalink.field.isnull then begin + value:= emptyreal; + end + else begin + value:= reapplyrange(fdatalink.field.asfloat,valuerange,valuestart); + end; +end; + +procedure tdbprogressbar.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= realfields + integerfields; +end; + +procedure tdbprogressbar.recchanged; +begin + fdatalink.recordchanged(nil); +end; + +function tdbprogressbar.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +function tdbprogressbar.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +function tdbprogressbar.checkvalue(const quiet: boolean = false): boolean; +begin + result:= false; //dummy +end; + +procedure tdbprogressbar.setdatalink(const avalue: teditwidgetdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbprogressbar.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +procedure tdbprogressbar.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +procedure tdbprogressbar.setmaxlength(const avalue: integer); +begin + //dummy +end; + +function tdbprogressbar.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; + +{ tdbdatetimeedit } + +constructor tdbdatetimeedit.create(aowner: tcomponent); +begin + fdatalink:= teditwidgetdatalink.Create(idbeditfieldlink(self)); + inherited; +end; + +destructor tdbdatetimeedit.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tdbdatetimeedit.modified; +begin + fdatalink.modified; + inherited; +end; +{ +function tdbdatetimeedit.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); +end; +} +procedure tdbdatetimeedit.valuetofield; +begin + if value = emptydatetime then begin + fdatalink.field.clear; + end + else begin + fdatalink.field.asdatetime:= value; + end; +end; + +procedure tdbdatetimeedit.fieldtovalue; +var + da1: tdatetime; +begin + if fdatalink.field.isnull then begin + value:= 0; + end + else begin + da1:= fdatalink.field.asdatetime; + value:= da1; + end; +end; + +function tdbdatetimeedit.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink).getdatetimebuffer(fdatalink.field,arow); + end + else begin + result:= nil; + end; +end; + +function tdbdatetimeedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdbdatetimeedit.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdbdatetimeedit.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +procedure tdbdatetimeedit.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= datetimefields; +end; + +function tdbdatetimeedit.nullcheckneeded(const newfocus: twidget): boolean; +begin + result:= inherited nullcheckneeded(newfocus); + fdatalink.nullcheckneeded(result); +end; + +procedure tdbdatetimeedit.setdatalink(const avalue: teditwidgetdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbdatetimeedit.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +procedure tdbdatetimeedit.recchanged; +begin + fdatalink.recordchanged(nil); +end; +{ +procedure tdbdatetimeedit.dochange; +begin + fdatalink.datachanged; + inherited; +end; +} +function tdbdatetimeedit.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; +{ +procedure tdbdatetimeedit.doenter; +begin + fdatalink.doenter(self); + inherited; +end; + +procedure tdbdatetimeedit.doexit; +begin + fdatalink.doexit(self); + inherited; +end; +} + +{ tcustomdbenumedit } + +constructor tcustomdbenumedit.create(aowner: tcomponent); +begin + fdatalink:= tlookupeditdatalink.create(self,ldt_int32,idbeditfieldlink(self)); + inherited; +end; + +destructor tcustomdbenumedit.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tcustomdbenumedit.modified; +begin + fdatalink.modified; + inherited; +end; + +procedure tcustomdbenumedit.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; +{ +function tcustomdbenumedit.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); +// frame.readonly:= oe_readonly in result; +end; +} +procedure tcustomdbenumedit.valuetofield; +begin + if value = fvalueempty then begin + fdatalink.field.clear; + if fdatalink.fieldtext <> nil then begin + fdatalink.fieldtext.clear; + end; + end + else begin + fdatalink.field.asinteger:= value; + setasmsestring(text,fdatalink.fieldtext,fdatalink.utf8) + end; +end; + +procedure tcustomdbenumedit.fieldtovalue; +begin + if fdatalink.field.isnull then begin + value:= fvaluedefault1; + end + else begin + value:= fdatalink.field.asinteger; + end; +end; + +function tcustomdbenumedit.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink). + getintegerbuffer(fdatalink.field,arow); + end + else begin + result:= nil; + end; +end; + +function tcustomdbenumedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tcustomdbenumedit.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tcustomdbenumedit.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +procedure tcustomdbenumedit.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= integerfields; +end; + +function tcustomdbenumedit.nullcheckneeded(const newfocus: twidget): boolean; +begin + result:= inherited nullcheckneeded(newfocus); + fdatalink.nullcheckneeded(result); +end; + +procedure tcustomdbenumedit.setdatalink(const avalue: tlookupeditdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tcustomdbenumedit.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +procedure tcustomdbenumedit.recchanged; +begin + fdatalink.recordchanged(nil); +end; +{ +procedure tcustomdbenumedit.dochange; +begin + fdatalink.datachanged; + inherited; +end; +} +function tcustomdbenumedit.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; + +function tcustomdbenumedit.getdropdownifilink: tifienumlinkcomp; +begin + result:= fdropdownifilink; +end; + +procedure tcustomdbenumedit.setdropdownifilink(const avalue: tifienumlinkcomp); +begin + mseificomp.setifilinkcomp(idbifidropdownlistdatalink(self),avalue, + tifilinkcomp(fdropdownifilink)); +end; + +procedure tcustomdbenumedit.dropdownsetifiserverintf(const aintf: iifiserver); +begin + fdropdownifiserverintf:= aintf; +end; + +procedure tcustomdbenumedit.dropdownifisetvalue(var avalue; + var accept: boolean); +begin + //dummy +end; +{ +procedure tcustomdbenumedit.doenter; +begin + fdatalink.doenter(self); + inherited; +end; + +procedure tcustomdbenumedit.doexit; +begin + fdatalink.doexit(self); + inherited; +end; +} +{ tdbbooleantextedit } + +constructor tdbbooleantextedit.create(aowner: tcomponent); +begin + ftext_false:= 'F'; + ftext_true:= 'T'; + inherited; + booltextchanged; +end; + +procedure tdbbooleantextedit.booltextchanged; +begin + with tenumdropdowncontroller(fdropdown) do begin + cols.count:= 1; + cols[0].count:= 2; + cols[0][0]:= ftext_false; + cols[0][1]:= ftext_true; + end; + formatchanged; +end; + +procedure tdbbooleantextedit.settext_false(const avalue: msestring); +begin + ftext_false:= avalue; + booltextchanged; +end; + +procedure tdbbooleantextedit.settext_true(const avalue: msestring); +begin + ftext_true:= avalue; + booltextchanged; +end; + +procedure tdbbooleantextedit.valuetofield; +begin + case inherited value of + -1: fdatalink.field.clear; + 0: fdatalink.field.asboolean:= false; + else fdatalink.field.asboolean:= true; + end; +end; + +procedure tdbbooleantextedit.fieldtovalue; +begin + if fdatalink.field.isnull then begin + inherited value:= -1; + end + else begin + value:= fdatalink.field.asboolean; + end; +end; + +procedure tdbbooleantextedit.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= booleanfields; +end; + +function tdbbooleantextedit.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink).getbooleanbuffer(fdatalink.field,arow); + if result = nil then begin + result:= @fvaluedefault; + end; + end + else begin + result:= @fvaluedefault; + end; +end; + +function tdbbooleantextedit.getvalue: boolean; +begin + result:= inherited value >= 0; +end; + +procedure tdbbooleantextedit.setvalue(const avalue: boolean); +begin + if avalue then begin + inherited value:= 1; + end + else begin + inherited value:= 0; + end; +end; + +{ tdbdropdowncol } + +procedure tdbdropdowncol.setdatafield(const avalue: string); +begin + if fdatafield <> avalue then begin + fdatafield:= avalue; + tcustomdbdropdownlistcontroller(fowner).fdatalink.updatefields; + end; +end; + +function tdbdropdowncol.getdataset(const aindex: integer): tdataset; +begin + if fowner is tcustomdbdropdownlistcontroller then begin + result:= tcustomdbdropdownlistcontroller(fowner).fdatalink.dataset; + end + else begin + result:= nil; + end; +end; + +procedure tdbdropdowncol.getfieldtypes(out propertynames: stringarty; + out fieldtypes: fieldtypesarty); +begin + propertynames:= nil; + setlength(fieldtypes,1); + fieldtypes[0]:= textfields; +end; + +{ tdbdropdowncols } + +function tdbdropdowncols.getitems(const index: integer): tdbdropdowncol; +begin + result:= tdbdropdowncol(inherited getitems(index)); +end; + +function tdbdropdowncols.getcolclass: dropdowncolclassty; +begin + result:= tdbdropdowncol; +end; + +{ tdropdowndatalink } + +constructor tdropdowndatalink.create( + const aowner: tcustomdbdropdownlistcontroller); +begin + flastintegerkey:= -1; + fowner:= aowner; +end; + +procedure tdropdowndatalink.setvaluefieldname(const value: string); +begin + if fvaluefieldname <> value then begin + fvaluefieldname := value; + updatefields; + end; +end; + +procedure tdropdowndatalink.setvaluefield(value: tfield); +begin + if fvaluefield <> value then begin + fvaluefield:= value; + EditingChanged; + RecordChanged(nil); + end; +end; + +procedure tdropdowndatalink.settextfield(value: tfield); +begin + if ftextfield <> value then begin + ftextfield:= value; + end; +end; + +procedure tdropdowndatalink.updatefields; + + procedure doerror(const afield: tfield); + begin + if afield <> nil then begin + raise exception.create(dataset.name+ + ': No matching local index for "'+afield.fieldname+'".'); + end; + end; //doerror + +begin + if Active and (fvaluefieldname <> '') then begin + setvaluefield(datasource.dataset.fieldbyname(fvaluefieldname)); + end + else begin + setvaluefield(nil); + end; + with fowner do begin + if active and (valuecol >= 0) and (valuecol < cols.count) and + (tdbdropdowncol(cols[valuecol]).datafield <> '') then begin + settextfield(datasource.dataset.fieldbyname( + tdbdropdowncol(cols[valuecol]).datafield)); + end + else begin + settextfield(nil); + end; + end; + fdataintf:= nil; + fkeyindex:= -1; + ftextindex:= -1; + if active then begin + if odb_directdata in fowner.foptionsdb then begin + if getcorbainterface(dataset,typeinfo(idbdata),fdataintf) then begin + if fvaluefield <> nil then begin + fkeyindex:= fdataintf.getindex(fvaluefield); + end; + if ftextfield <> nil then begin + ftextindex:= fdataintf.gettextindex(ftextfield, + not (deo_casesensitive in fowner.foptions)); + end; + end; + if fkeyindex < 0 then begin + doerror(fvaluefield); + end; + if ftextindex < 0 then begin + doerror(ftextfield); + end; + end; + end; +end; + +procedure tdropdowndatalink.updatelookupvalue; +begin + exclude(fstate,ddlnks_lookupvalid); + with tdataedit1(fowner.fintf.getwidget) do begin + if fgridintf <> nil then begin + fgridintf.getcol.changed; + end + else begin + valuetotext; + end; + end; +end; + +procedure tdropdowndatalink.activechanged; +begin + flastintegerkey:= -1; + updatefields; + inherited; + updatelookupvalue; + fowner.updatereadonlystate; +end; + +procedure tdropdowndatalink.editingchanged; +begin + inherited; + if not editing then begin + updatelookupvalue; + end; +end; + +procedure tdropdowndatalink.LayoutChanged; +begin + updatefields; + inherited; +end; + +function tdropdowndatalink.getlookuptext(const key: integer): msestring; +var + str1: string; +begin + if flastintegerkey <> key then begin + exclude(fstate,ddlnks_lookupvalid); + end; + if ddlnks_lookupvalid in fstate then begin + result:= flookuptext; + end + else begin + result:= ''; + if active and (fdscontroller <> nil) and + (fvaluefield <> nil) and (ftextfield <> nil) then begin + flastintegerkey:= key; + if fkeyindex >= 0 then begin + result:= fdataintf.lookuptext(fkeyindex,key,false, + tmsestringfield(ftextfield)); + end + else begin + dataset.disablecontrols; + try + str1:= dataset.bookmark; + if fdscontroller.locate([fvaluefield],[key],[],[]) = loc_ok then begin + result:= getasmsestring(ftextfield,utf8); + end; + dataset.bookmark:= str1; + finally + dataset.enablecontrols; + end; + end; + include(fstate,ddlnks_lookupvalid); + end; + flookuptext:= result; + end; +end; + +function tdropdowndatalink.getlookuptext(const key: int64): msestring; +var + str1: string; +begin + if flastint64key <> key then begin + exclude(fstate,ddlnks_lookupvalid); + end; + if ddlnks_lookupvalid in fstate then begin + result:= flookuptext; + end + else begin + result:= ''; + if active and (fdscontroller <> nil) and + (fvaluefield <> nil) and (ftextfield <> nil) then begin + flastint64key:= key; + if fkeyindex >= 0 then begin + result:= fdataintf.lookuptext(fkeyindex,key,false, + tmsestringfield(ftextfield)); + end + else begin + dataset.disablecontrols; + try + str1:= dataset.bookmark; + if fdscontroller.locate([fvaluefield],[key],[],[]) = loc_ok then begin + result:= getasmsestring(ftextfield,utf8); + end; + dataset.bookmark:= str1; + finally + dataset.enablecontrols; + end; + end; + include(fstate,ddlnks_lookupvalid); + end; + flookuptext:= result; + end; +end; + +function tdropdowndatalink.getlookuptext(const key: msestring): msestring; +var + str1: string; +begin + if flaststringkey <> key then begin + exclude(fstate,ddlnks_lookupvalid); + end; + if ddlnks_lookupvalid in fstate then begin + result:= flookuptext; + end + else begin + result:= ''; + if active and (fdscontroller <> nil) and + (fvaluefield <> nil) and (ftextfield <> nil) then begin + flaststringkey:= key; + if fkeyindex >= 0 then begin + result:= fdataintf.lookuptext(fkeyindex,key,false, + tmsestringfield(ftextfield)); + end + else begin + dataset.disablecontrols; + try + str1:= dataset.bookmark; + if fdscontroller.locate([fvaluefield],[key],[],[]) = loc_ok then begin + result:= getasmsestring(ftextfield,utf8); + end; + dataset.bookmark:= str1; + finally + dataset.enablecontrols; + end; + end; + include(fstate,ddlnks_lookupvalid); + end; + flookuptext:= result; + end; +end; + +function tdropdowndatalink.getvalueasmsestring: msestring; +begin + result:= ''; + if active and (fvaluefield <> nil) then begin + result:= getasmsestring(fvaluefield,utf8); + end; +end; + +function tdropdowndatalink.getvalueasinteger: integer; +begin + result:= 0; + if active and (fvaluefield <> nil) then begin + result:= fvaluefield.asinteger; + end; +end; + +function tdropdowndatalink.getvalueaslargeint: int64; +begin + result:= 0; + if active and (fvaluefield <> nil) then begin + result:= fvaluefield.aslargeint; + end; +end; + +function tdropdowndatalink.gettextasmsestring: msestring; +begin + result:= ''; + if active and (ftextfield <> nil) then begin +// with fgridlink do begin +// if fdataintf <> nil then begin +// result:= fdataintf.getrowtext(ftextindex,fcurrentrecord,ftextfield); +// end +// else begin + result:= getasmsestring(ftextfield,utf8); +// end; +// end; + end; +end; + +{ tdbdropdownstringcol } + +constructor tdbdropdownstringcol.create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); +begin + fdatalink:= tfielddatalink.create; + inherited; +end; + +destructor tdbdropdownstringcol.destroy; +begin + inherited; + fdatalink.free; +end; + +function tdbdropdownstringcol.getrowtext(const arow: integer): msestring; +var + int1: integer; +begin + if fdatalink.active and (fdatalink.field <> nil) then begin + with tdbdropdownlist(fcellinfo.grid).fdatalink do begin + if fdataintf <> nil then begin + result:= fdataintf.getrowtext(ftextindex,arow+ffirstrecord,fdatalink.field); + end + else begin + int1:= activerecord; + activerecord:= arow; + result:= fdatalink.asmsestring; + activerecord:= int1; + end; + end; + end + else begin + result:= ''; + end; +end; + +{ tdropdownlistdatalink } + +constructor tdropdownlistdatalink.create(const aowner: tcustomgrid; + const aintf: igriddatalink; const adatalink: tdropdowndatalink); +begin + with adatalink do begin + self.fdataintf:= fdataintf; + self.ftextindex:= ftextindex; + self.fkeyindex:= fkeyindex; + end; + inherited create(aowner,aintf); +end; + +procedure tdropdownlistdatalink.updatefocustext; +begin + with tdbdropdownlist(fgrid) do begin + if isdatacell(ffocusedcell) then begin + feditor.text:= tdbdropdownstringcol(datacols[ffocusedcell.col]). + getrowtext(ffocusedcell.row); + end; + end; +end; + +procedure tdropdownlistdatalink.recordchanged(afield: tfield); +begin + inherited; + updatefocustext; +end; + +function tdropdownlistdatalink.GetActiveRecord: Integer; +begin + if fdataintf = nil then begin + result:= inherited getactiverecord; + end + else begin + result:= fcurrentrecord-ffirstrecord; + end; +end; + +procedure tdropdownlistdatalink.SetActiveRecord(Value: Integer); +begin + if fdataintf = nil then begin + inherited; + end; +end; + +function tdropdownlistdatalink.domoveby(const distance: integer): integer; +var + int1: integer; +begin + if fdataintf = nil then begin + result:= inherited domoveby(distance); + end + else begin + int1:= fcurrentrecord; + setcurrentrecord(fcurrentrecord+distance,ropo_nearest); + result:= fcurrentrecord-int1; + end; +end; + +procedure tdropdownlistdatalink.checkscrollbar; +var + rea1: real; + int1: integer; +begin + if fdataintf = nil then begin + inherited; + end + else begin + int1:= dataset.recordcount-1; + if int1 <= fgrid.rowcount then begin + rea1:= 1; + end + else begin + rea1:= fgrid.rowcount/(int1+1+fgrid.rowcount); + end; + fgrid.frame.sbvert.pagesize:= rea1; + if int1 > 0 then begin + rea1:= fcurrentrecord/int1; + end + else begin + rea1:= 0; + end; + fgrid.frame.sbvert.value:= rea1; + end; +end; + +function tdropdownlistdatalink.scrollevent(sender: tcustomscrollbar; + event: scrolleventty): boolean; +//var +// int1: integer; +begin + if (fdataintf = nil) or (sender.tag <> 1) or + not (event in [sbe_thumbtrack,sbe_thumbposition]) then begin + result:= inherited scrollevent(sender,event); + end + else begin + result:= false; + if (event <> sbe_thumbtrack) or (gdo_thumbtrack in foptions) then begin + if self.active then begin + setcurrentrecord(round( + fgrid.frame.sbvert.value * dataset.recordcount),ropo_nearest); + result:= true; + end; + end; + end; +end; + +procedure tdropdownlistdatalink.focuscell(var cell: gridcoordty); +begin + if fdataintf = nil then begin + inherited; + end + else begin + if (cell.row >= 0) and (cell.row <> fgrid.row) then begin + moveby(cell.row-fgrid.row); + end; + end; +end; + +procedure tdropdownlistdatalink.setcurrentrecord(const avalue: integer; + const arowpos: rowpositionty); +var + int1,int2: integer; +begin + if active then begin + if avalue <> fcurrentrecord then begin + int2:= fcurrentrecord; + fcurrentrecord:= avalue; + if fcurrentrecord < 0 then begin + fcurrentrecord:= 0; + if int2 = 0 then begin + include(tcustomgrid1(fgrid).fstate1,gs1_scrolllimit); + end; + end; + int1:= dataset.recordcount; + if fcurrentrecord >= dataset.recordcount then begin + fcurrentrecord:= int1 - 1; + if int2 = fcurrentrecord then begin + include(tcustomgrid1(fgrid).fstate1,gs1_scrolllimit); + end; + end; + updatedatawindow(arowpos); + end; + recordchanged(nil); + end; +end; + +procedure tdropdownlistdatalink.updatedatawindow(const arowpos: rowpositionty); +var + int1,int2: integer; +begin + int1:= recordcount; + case arowpos of + ropo_top: begin + ffirstrecord:= fcurrentrecord; + end; + ropo_bottom: begin + ffirstrecord:= fcurrentrecord-int1+1; + end; + ropo_centered,ropo_centeredif: begin + if (arowpos = ropo_centered) or + (fcurrentrecord < ffirstrecord) or + (fcurrentrecord >= ffirstrecord + int1) then begin + ffirstrecord:= fcurrentrecord - int1 div 2; + end; + end; + end; + int2:= dataset.recordcount; + if ffirstrecord + int1 > int2 then begin + ffirstrecord:= int2 - int1; + end; + if ffirstrecord < 0 then begin + ffirstrecord:= 0; + end; + if fcurrentrecord >= ffirstrecord+fmaxrowcount then begin + ffirstrecord:= fcurrentrecord - fmaxrowcount + 1; + end; + if fcurrentrecord < ffirstrecord then begin + ffirstrecord:= fcurrentrecord; + end; +end; +{ +function tdropdownlistdatalink.GetBufferCount: Integer; +begin + if (fdataintf = nil) or (fmaxrowcount <= 0) then begin + result:= inherited getbuffercount; + end + else begin + result:= fmaxrowcount; + end; +end; +} +procedure tdropdownlistdatalink.SetBufferCount(Value: Integer); +begin + if fdataintf = nil then begin + inherited; + end + else begin + fmaxrowcount:= value; + end; +end; + +function tdropdownlistdatalink.getfirstrecord: integer; +begin + if fdataintf = nil then begin + result:= inherited getfirstrecord; + end + else begin + result:= ffirstrecord; + end; +end; + +function tdropdownlistdatalink.getrecordcount: integer; +begin + if fdataintf = nil then begin + result:= inherited getrecordcount; + end + else begin + result:= dataset.recordcount; + if result > fmaxrowcount then begin + result:= fmaxrowcount; + end; + end; +end; + +function tdropdownlistdatalink.getasmsestring(const afield: tfield): msestring; +begin + if fdataintf = nil then begin + result:= msedb.getasmsestring(afield,utf8); + end + else begin + result:= fdataintf.getrowtext(ftextindex,fcurrentrecord,afield); + end; +end; + +function tdropdownlistdatalink.getasinteger(const afield: tfield): integer; +begin + if fdataintf = nil then begin + result:= afield.asinteger; + end + else begin + result:= fdataintf.getrowinteger(ftextindex,fcurrentrecord,afield); + end; +end; + +function tdropdownlistdatalink.getaslargeint(const afield: tfield): int64; +begin + if fdataintf = nil then begin + result:= afield.aslargeint; + end + else begin + result:= fdataintf.getrowlargeint(ftextindex,fcurrentrecord,afield); + end; +end; + +procedure tdropdownlistdatalink.cellevent(var info: celleventinfoty); +var + int1: integer; +begin + int1:= info.newcell.row-activerecord; + inherited; + with info do begin + if (eventkind = cek_enter) and active and (int1 = 0) and + (newcell.col >= 0) then begin + updatefocustext; + end; + end; +end; + +{ tdbdropdownlist } + +constructor tdbdropdownlist.create( + const acontroller: tcustomdbdropdownlistcontroller; acols: tdropdowncols); +var + int1: integer; +begin + fdatalink:= tdropdownlistdatalink.create(self,igriddatalink(self), + acontroller.fdatalink); + inherited create(acontroller,acols,nil); + include(fstate,gs_isdb); + fzebra_step:= 0; + fdatalink.datasource:= acontroller.datasource; + fdatalink.buffercount:= acontroller.dropdownrowcount; + int1:= fdatalink.recordcount; + if int1 < 0 then begin + int1:= 0; + end; + rowcount:= int1; +end; + +destructor tdbdropdownlist.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tdbdropdownlist.pagedown(const action: focuscellactionty = fca_focusin); +begin + fdatalink.MoveBy(rowcount-1); +end; + +procedure tdbdropdownlist.pageup(const action: focuscellactionty = fca_focusin); +begin + fdatalink.MoveBy(-rowcount+1); +end; + +procedure tdbdropdownlist.wheeldown(const action: focuscellactionty = fca_focusin); +begin + fdatalink.MoveBy(wheelheight); +end; + +procedure tdbdropdownlist.wheelup(const action: focuscellactionty = fca_focusin); +begin + fdatalink.MoveBy(-wheelheight); +end; + +procedure tdbdropdownlist.rowdown(const action: focuscellactionty = fca_focusin; + const nowrap: boolean = false); +begin + fdatalink.MoveBy(1); +end; + +procedure tdbdropdownlist.rowup(const action: focuscellactionty = fca_focusin; + const nowrap: boolean = false); +begin + fdatalink.MoveBy(-1); +end; + +procedure tdbdropdownlist.internalcreateframe; +begin + tdbgridframe.create(iscrollframe(self),self,iautoscrollframe(self)); +end; + +procedure tdbdropdownlist.createdatacol(const index: integer; + out item: tdatacol); +begin + item:= tdbdropdownstringcol.create(self,fdatacols); +end; + +procedure tdbdropdownlist.initcols(const acols: tdropdowncols); +var + int1: integer; + dbstrcol1: tdbdropdownstringcol; + datasource1: tdatasource; +begin + inherited; + datasource1:= tcustomdbdropdownlistcontroller(fcontroller).datasource; + for int1:= 0 to fdatacols.count - 1 do begin + dbstrcol1:= tdbdropdownstringcol(fdatacols[int1]); + with tdbdropdowncol(acols[int1]) do begin + dbstrcol1.fdatalink.datasource:= datasource1; + dbstrcol1.fdatalink.fieldname:= datafield; + end; + end; +end; + +procedure tdbdropdownlist.docellevent(var info: celleventinfoty); +begin + inherited; + fdatalink.cellevent(info); +end; + +procedure tdbdropdownlist.scrollevent(sender: tcustomscrollbar; + event: scrolleventty); +begin + if not fdatalink.scrollevent(sender,event) then begin + inherited; + end; +end; + +function tdbdropdownlist.locate(const filter: msestring): boolean; +var + row1: integer; +begin + result:= false; + if (datacols.count > 0) then begin + with tdbdropdownstringcol(datacols[0]).fdatalink do begin + if (dscontroller <> nil) and (field <> nil) then begin + with tcustomdbdropdownlistcontroller(fcontroller).fdatalink do begin + if ftextindex >= 0 then begin + result:= fdataintf.findtext(ftextindex,filter,row1); + if result then begin + fdatalink.setcurrentrecord(row1,ropo_top); + end; + end + else begin + result:= dscontroller.locate([field],[filter],[], + [[lko_caseinsensitive]]) = loc_ok; + if not result then begin + result:= dscontroller.locate([field],[filter],[], + [[lko_caseinsensitive,lko_partialkey]]) = loc_ok; + end; + if result then begin + dataset.resync([rmcenter]); + end; + end; + end; + end; + end; + end; + if not result then begin + focuscell(makegridcoord(ffocusedcell.col,-1)); + end; +end; + +procedure tdbdropdownlist.dopaint(const acanvas: tcanvas); +begin + inherited; + fdatalink.painted; +end; + +procedure tdbdropdownlist.dohide; +begin + fdatalink.painted; + inherited; +end; + +function tdbdropdownlist.getdbindicatorcol: integer; +begin + result:= 0; //none +end; + +procedure tdbdropdownlist.setnavigator(const avalue: tdbnavigator); +begin + //dummy +end; + +function tdbdropdownlist.getdatalink(): tgriddatalink; +begin + result:= fdatalink; +end; + +function tdbdropdownlist.getassistiveflags(): assistiveflagsty; +begin + result:= inherited getassistiveflags() + [asf_db]; +end; + +procedure tdbdropdownlist.setactiveitem(const aitemindex: integer); +begin + inherited; + fdatalink.recordchanged(nil); +end; + +{ tcustomdbdropdownlistcontroller } + +constructor tcustomdbdropdownlistcontroller.create(const intf: idbdropdownlist; + const aisstringkey: boolean); +begin + if aisstringkey then begin + include(fstate,dcs_isstringkey); + end; +// fisstringkey:= aisstringkey; + foptionsdatalink:= defaultdropdowndatalinkoptions; + fdatalink:= tdropdowndatalink.create(self); + inherited create(intf); + options:= defaultdbdropdownoptions; +end; + +destructor tcustomdbdropdownlistcontroller.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tcustomdbdropdownlistcontroller.dropdown; +begin + tdropdowncols1(fcols).fitemindex:= -1; + inherited; +end; + +function tcustomdbdropdownlistcontroller.getdatasource: tdatasource; +begin + result:= fdatalink.datasource; +end; + +procedure tcustomdbdropdownlistcontroller.setdatasource(const avalue: tdatasource); +begin + fdatalink.datasource:= avalue; +end; + +procedure tcustomdbdropdownlistcontroller.setkeyfield(const avalue: string); +begin + fdatalink.valuefieldname:= avalue; +end; + +function tcustomdbdropdownlistcontroller.getkeyfield: string; +begin + result:= fdatalink.valuefieldname; +end; + +function tcustomdbdropdownlistcontroller.getcols: tdbdropdowncols; +begin + result:= tdbdropdowncols(fcols); +end; + +procedure tcustomdbdropdownlistcontroller.setcols(const avalue: tdbdropdowncols); +begin + fcols.assign(avalue); +end; + +function tcustomdbdropdownlistcontroller.getbuttonframeclass(): + dropdownbuttonframeclassty; +begin + result:= tdropdownmultibuttonframe; +end; + +procedure tcustomdbdropdownlistcontroller.valuecolchanged; +begin + inherited; + fdatalink.updatefields; +end; + +function tcustomdbdropdownlistcontroller.getdropdowncolsclass: dropdowncolsclassty; +begin + result:= tdbdropdowncols; +end; + +function tcustomdbdropdownlistcontroller.createdropdownlist: tdropdownlist; +type + pmsestringaarty = array of pmsestringaty; +var + int1,int2: integer; + datas: tdataset; + ar1: fieldarty; + ar2: pmsestringaarty; + bm: string; +begin + datas:= fdatalink.dataset; + if (datas <> nil) and (odb_closedataset in foptionsdb) then begin + datas.active:= true; + end; + if odb_copyitems in foptionsdb then begin + fcols.clear; + datas:= fdatalink.dataset; + if (datas <> nil) and datas.active then begin + setlength(ar1,fcols.count); + setlength(ar2,fcols.count); + for int1:= 0 to high(ar1) do begin + setlength(fbookmarks,datas.recordcount); + with cols[int1] do begin + count:= length(fbookmarks); //max + ar2[int1]:= datapo; + ar1[int1]:= datas.fieldbyname(datafield); + end; + end; + datas.disablecontrols; + try + bm:= datas.bookmark; + try + int2:= 0; + datas.first; + while not datas.eof do begin + fbookmarks[int2]:= datas.bookmark; + for int1:= 0 to high(ar1) do begin + ar2[int1]^[int2]:= msedb.getasmsestring(ar1[int1],fdatalink.utf8); + end; + inc(int2); + datas.next; + end; + for int1:= 0 to cols.count-1 do begin + cols[int1].count:= int2; + end; + setlength(fbookmarks,int2); + finally + datas.bookmark:= bm; + end; + finally + datas.enablecontrols; + end; + end; + result:= tdropdownlist.create(self,fcols,nil); + end + else begin + result:= tdbdropdownlist.create(self,fcols); + with tdbdropdownlist(result) do begin + fdatalink.options:= foptionsdatalink; + if gdo_propscrollbar in fdatalink.options then begin + with frame.sbvert do begin + pagesize:= 1; + end; + end; + end; + end; +end; + +function tcustomdbdropdownlistcontroller.candropdown: boolean; +begin + result:= inherited candropdown and + (fdatalink.active or + (odb_opendataset in foptionsdb) and (fdatalink.dataset <> nil)); +end; + +procedure tcustomdbdropdownlistcontroller.doafterclosedropdown; +begin + inherited; + if (odb_closedataset in foptionsdb) and fdatalink.active then begin + fdatalink.dataset.active:= false; + end; +end; + +procedure tcustomdbdropdownlistcontroller.itemselected(const index: integer; + const akey: keyty); +begin + if index < 0 then begin + if index = -2 then begin + tdropdowncols1(fcols).fitemindex:= fintf.getvalueempty; + end; + end + else begin + if odb_copyitems in foptionsdb then begin + fdatalink.dataset.bookmark:= fbookmarks[index]; + end; + tdropdowncols1(fcols).fitemindex:= index; + end; + if odb_copyitems in foptionsdb then begin + cols.clear; + fbookmarks:= nil; + end; + idbdropdownlist(fintf).recordselected(index,akey); +end; + +procedure tcustomdbdropdownlistcontroller.getfieldtypes(out propertynames: stringarty; + out fieldtypes: fieldtypesarty); +begin + setlength(propertynames,1); + propertynames[0]:= 'keyfield'; + setlength(fieldtypes,1); + if dcs_isstringkey in fstate then begin + fieldtypes[0]:= textfields; + end + else begin + fieldtypes[0]:= integerfields; + end; +end; + +function tcustomdbdropdownlistcontroller.getdataset(const aindex: integer): tdataset; +begin + result:= fdatalink.dataset; +end; + +procedure tcustomdbdropdownlistcontroller.setoptionsdb(const avalue: optionsdbty); +//var +// optionsbefore: optionsdbty; +begin + if avalue <> foptionsdb then begin + foptionsdb:= avalue; + updatereadonlystate; + end; +end; + +function tcustomdbdropdownlistcontroller.getasmsestring(const afield: tfield; + const utf8: boolean): msestring; +begin + if afield = nil then begin + result:= ''; + end + else begin + if (fdropdownlist is tdbdropdownlist) then begin + result:= tdbdropdownlist(fdropdownlist).fdatalink.getasmsestring(afield); + end + else begin + result:= msedb.getasmsestring(afield,utf8); + end; + end; +end; + +function tcustomdbdropdownlistcontroller.getasinteger(const afield: tfield): integer; +begin + if afield = nil then begin + result:= 0; + end + else begin + if (fdropdownlist is tdbdropdownlist) then begin + result:= tdbdropdownlist(fdropdownlist).fdatalink.getasinteger(afield); + end + else begin + result:= afield.asinteger; + end; + end; +end; + +function tcustomdbdropdownlistcontroller.getaslargeint(const afield: tfield): int64; +begin + if afield = nil then begin + result:= 0; + end + else begin + if (fdropdownlist is tdbdropdownlist) then begin + result:= tdbdropdownlist(fdropdownlist).fdatalink.getaslargeint(afield); + end + else begin + result:= afield.aslargeint; + end; + end; +end; + +{ tdbenumeditdb } + +function tdbenumeditdb.getdropdown: tdbdropdownlistcontroller; +begin +{$warnings off} + result:= tdbdropdownlistcontroller(inherited dropdown); +{$warnings on} +end; + +procedure tdbenumeditdb.setdropdown(const avalue: tdbdropdownlistcontroller); +begin + inherited dropdown.assign(avalue); +end; + +function tdbenumeditdb.createdropdowncontroller: tcustomdropdowncontroller; +begin + result:= tdbdropdownlistcontroller.create(idbdropdownlist(self),false); +end; + +procedure tdbenumeditdb.recordselected(const arecordnum: integer; + const akey: keyty); +var + bo1: boolean; +begin + bo1:= false; + if arecordnum >= 0 then begin + with tdbdropdownlistcontroller(fdropdown) do begin +// text:= getasmsestring(fdatalink.textfield,fdatalink.utf8); +// tdropdowncols1(fcols).fitemindex:= fdatalink.valuefield.asinteger + text:= getasmsestring(fdatalink.textfield,fdatalink.utf8); + tdropdowncols1(fcols).fitemindex:= getasinteger(fdatalink.valuefield); + end; + bo1:= checkvalue; + end + else begin + if arecordnum = -2 then begin + bo1:= checkvalue; + end + else begin + feditor.undo; + end; + end; + if bo1 and (akey = key_tab) then begin + window.postkeyevent(akey); + end; +end; + +function tdbenumeditdb.internaldatatotext(const data): msestring; +var + int1: integer; +begin + if @data = nil then begin + int1:= value; + end + else begin + int1:= integer(data); + end; + result:= tdbdropdownlistcontroller(fdropdown).fdatalink.getlookuptext(int1); +end; + +{ tdbdropdownlisteditdb } + +function tdbdropdownlisteditdb.getdropdown: tdropdownlistcontrollerdb; +begin +{$warnings off} + result:= tdropdownlistcontrollerdb(inherited dropdown); +{$warnings on} +end; + +procedure tdbdropdownlisteditdb.setdropdown(const avalue: tdropdownlistcontrollerdb); +begin + inherited dropdown.assign(avalue); +end; + +function tdbdropdownlisteditdb.createdropdowncontroller: + tcustomdropdowncontroller; +begin + result:= tdropdownlistcontrollerdb.create(idbdropdownlist(self),false); +end; + +procedure tdbdropdownlisteditdb.recordselected(const arecordnum: integer; + const akey: keyty); +var + bo1: boolean; +begin + bo1:= false; + if arecordnum >= 0 then begin + with tdropdownlistcontrollerdb(fdropdown) do begin + setdropdowntext(getasmsestring(fdatalink.textfield,fdatalink.utf8),true, + false,akey); + end; + exit; + end + else begin + if arecordnum = -2 then begin + bo1:= checkvalue; + end + else begin + if deo_selectonly in dropdown.options then begin + feditor.undo; + end; + end; + end; + if bo1 and (akey = key_tab) then begin + window.postkeyevent(akey); + end; +end; + +{ tdropdownlisteditdb } + +function tdropdownlisteditdb.getdropdown: tdropdownlistcontrollerdb; +begin +{$warnings off} + result:= tdropdownlistcontrollerdb(inherited dropdown); +{$warnings on} +end; + +procedure tdropdownlisteditdb.setdropdown(const avalue: tdropdownlistcontrollerdb); +begin + inherited dropdown.assign(avalue); +end; + +function tdropdownlisteditdb.createdropdowncontroller: + tcustomdropdowncontroller; +begin + result:= tdropdownlistcontrollerdb.create(idbdropdownlist(self),false); +end; + +procedure tdropdownlisteditdb.recordselected(const arecordnum: integer; + const akey: keyty); +var + bo1: boolean; +begin + bo1:= false; + if arecordnum >= 0 then begin + with tdropdownlistcontrollerdb(fdropdown) do begin + setdropdowntext(getasmsestring(fdatalink.textfield,fdatalink.utf8),true, + false,akey); + end; + exit; + end + else begin + if arecordnum = -2 then begin + bo1:= checkvalue; + end + else begin + if deo_selectonly in dropdown.options then begin + feditor.undo; + end; + end; + end; + if bo1 and (akey = key_tab) then begin + window.postkeyevent(akey); + end; +end; + +{ tdbdropdownlisteditlb } + +function tdbdropdownlisteditlb.getdropdown: tdropdownlistcontrollerlb; +begin +{$warnings off} + result:= tdropdownlistcontrollerlb(inherited dropdown); +{$warnings on} +end; + +procedure tdbdropdownlisteditlb.setdropdown( + const avalue: tdropdownlistcontrollerlb); +begin + inherited dropdown.assign(avalue); +end; + +function tdbdropdownlisteditlb.createdropdowncontroller: + tcustomdropdowncontroller; +begin + result:= tdropdownlistcontrollerlb.create(ilbdropdownlist(self)); +end; + +procedure tdbdropdownlisteditlb.recordselected(const arecordnum: integer; + const akey: keyty); +var + bo1: boolean; +begin + bo1:= false; + if arecordnum >= 0 then begin + with tdropdownlistcontrollerlb(fdropdown) do begin + setdropdowntext(flookupbuffer.textvaluephys(cols[0].ffieldno,arecordnum), + true,false,akey); + end; + exit; + end + else begin + if arecordnum = -2 then begin + bo1:= checkvalue; + end + else begin + if deo_selectonly in dropdown.options then begin + feditor.undo; + end; + end; + end; + if bo1 and (akey = key_tab) then begin + window.postkeyevent(akey); + end; +end; + +function tdbdropdownlisteditlb.getlbkeydatakind: lbdatakindty; +begin + result:= lbdk_none; +end; + +{ tdropdownlisteditlb } + +function tdropdownlisteditlb.getdropdown: tdropdownlistcontrollerlb; +begin +{$warnings off} + result:= tdropdownlistcontrollerlb(inherited dropdown); +{$warnings on} +end; + +procedure tdropdownlisteditlb.setdropdown( + const avalue: tdropdownlistcontrollerlb); +begin + inherited dropdown.assign(avalue); +end; + +function tdropdownlisteditlb.createdropdowncontroller: + tcustomdropdowncontroller; +begin + result:= tdropdownlistcontrollerlb.create(ilbdropdownlist(self)); +end; + +procedure tdropdownlisteditlb.recordselected(const arecordnum: integer; + const akey: keyty); +var + bo1: boolean; +begin + bo1:= false; + if arecordnum >= 0 then begin + with tdropdownlistcontrollerlb(fdropdown) do begin + setdropdowntext(flookupbuffer.textvaluephys(cols[0].ffieldno,arecordnum), + true,false,akey); + end; + exit; + end + else begin + if arecordnum = -2 then begin + bo1:= checkvalue; + end + else begin + if deo_selectonly in dropdown.options then begin + feditor.undo; + end; + end; + end; + if bo1 and (akey = key_tab) then begin + window.postkeyevent(akey); + end; +end; + +function tdropdownlisteditlb.getlbkeydatakind: lbdatakindty; +begin + result:= lbdk_none; +end; + +{ tenumeditdb } + +function tenumeditdb.getdropdown: tdbdropdownlistcontroller; +begin +{$warnings off} + result:= tdbdropdownlistcontroller(inherited dropdown); +{$warnings on} +end; + +procedure tenumeditdb.setdropdown(const avalue: tdbdropdownlistcontroller); +begin + inherited dropdown.assign(avalue); +end; + +function tenumeditdb.createdropdowncontroller: tcustomdropdowncontroller; +begin + result:= tdbdropdownlistcontroller.create(idbdropdownlist(self),false); +end; + +procedure tenumeditdb.recordselected(const arecordnum: integer; const akey: keyty); +var + bo1: boolean; +begin + bo1:= false; + if arecordnum >= 0 then begin + with tdbdropdownlistcontroller(fdropdown) do begin + text:= getasmsestring(fdatalink.textfield,fdatalink.utf8); + tdropdowncols1(fcols).fitemindex:= getasinteger(fdatalink.valuefield); + end; + bo1:= checkvalue; + end + else begin + if arecordnum = -2 then begin + bo1:= checkvalue; + end + else begin + feditor.undo; + end; + end; + if bo1 and (akey = key_tab) then begin + window.postkeyevent(akey); + end; +end; + +function tenumeditdb.internaldatatotext(const data): msestring; +var + int1: integer; +begin + if @data = nil then begin + int1:= value; + end + else begin + int1:= integer(data); + end; + result:= tdbdropdownlistcontroller(fdropdown).fdatalink.getlookuptext(int1); +end; + +{ tdbkeystringeditdb } + +function tdbkeystringeditdb.getdropdown: tdbdropdownlistcontroller; +begin +{$warnings off} + result:= tdbdropdownlistcontroller(inherited dropdown); +{$warnings on} +end; + +procedure tdbkeystringeditdb.setdropdown(const avalue: tdbdropdownlistcontroller); +begin + inherited dropdown.assign(avalue); +end; + +function tdbkeystringeditdb.createdropdowncontroller: tcustomdropdowncontroller; +begin + result:= tdbdropdownlistcontroller.create(idbdropdownlist(self),true); +end; + +procedure tdbkeystringeditdb.recordselected(const arecordnum: integer; + const akey: keyty); +var + bo1: boolean; +begin + bo1:= false; + if arecordnum >= 0 then begin + with tdbdropdownlistcontroller(fdropdown) do begin + text:= getasmsestring(fdatalink.textfield,fdatalink.utf8); + tdropdowncols1(fcols).fkeyvalue:= getasmsestring(fdatalink.valuefield, + fdatalink.utf8); + end; + bo1:= checkvalue; + end + else begin + if arecordnum = -2 then begin + bo1:= checkvalue; + end + else begin + feditor.undo; + end; + end; + if bo1 and (akey = key_tab) then begin + window.postkeyevent(akey); + end; +end; + +function tdbkeystringeditdb.internaldatatotext(const data): msestring; +var + mstr1: msestring; +begin + if @data = nil then begin + mstr1:= value; + end + else begin + mstr1:= msestring(data); + end; + result:= tdbdropdownlistcontroller(fdropdown).fdatalink.getlookuptext(mstr1); +end; + +{ tkeystringeditdb } + +function tkeystringeditdb.getdropdown: tdbdropdownlistcontroller; +begin +{$warnings off} + result:= tdbdropdownlistcontroller(inherited dropdown); +{$warnings on} +end; + +procedure tkeystringeditdb.setdropdown(const avalue: tdbdropdownlistcontroller); +begin + inherited dropdown.assign(avalue); +end; + +function tkeystringeditdb.createdropdowncontroller: tcustomdropdowncontroller; +begin + result:= tdbdropdownlistcontroller.create(idbdropdownlist(self),true); +end; + +procedure tkeystringeditdb.recordselected(const arecordnum: integer; + const akey: keyty); +var + bo1: boolean; +begin + bo1:= false; + if arecordnum >= 0 then begin + with tdbdropdownlistcontroller(fdropdown) do begin + text:= getasmsestring(fdatalink.textfield,fdatalink.utf8); + tdropdowncols1(fcols).fkeyvalue:= getasmsestring(fdatalink.valuefield, + fdatalink.utf8); + end; + bo1:= checkvalue; + end + else begin + if arecordnum = -2 then begin + bo1:= checkvalue; + end + else begin + feditor.undo; + end; + end; + if bo1 and (akey = key_tab) then begin + window.postkeyevent(akey); + end; +end; + +function tkeystringeditdb.internaldatatotext(const data): msestring; +var + mstr1: msestring; +begin + if @data = nil then begin + mstr1:= value; + end + else begin + mstr1:= msestring(data); + end; + result:= tdbdropdownlistcontroller(fdropdown).fdatalink.getlookuptext(mstr1); +end; + +{ tgriddatalink } + +constructor tgriddatalink.create(const aowner: tcustomgrid; + const aintf: igriddatalink); +begin + fintf:= aintf; + fgrid:= aowner; + include(tcustomgrid1(fgrid).fstate,gs_isdb); + iificlient(aowner).setifiserverintf(iifidataserver(self)); + inherited create; + options:= defaultgriddatalinkoptions; +// visualcontrol:= true; +end; + +destructor tgriddatalink.destroy; +begin + inc(fdatasetchangedlock); + inherited; + fobjectlinker.free; +end; + +procedure tgriddatalink.setfieldname_state(const avalue: string); +begin + if ffieldname_state <> avalue then begin + ffieldname_state:= avalue; + updatefields; + end; +end; + +procedure tgriddatalink.setfieldname_color(const avalue: string); +begin + if ffieldname_color <> avalue then begin + ffieldname_color:= avalue; + updatefields; + end; +end; + +procedure tgriddatalink.setfieldname_font(const avalue: string); +begin + if ffieldname_font <> avalue then begin + ffieldname_font:= avalue; + updatefields; + end; +end; + +procedure tgriddatalink.setfieldname_readonly(const avalue: string); +begin + if ffieldname_readonly <> avalue then begin + ffieldname_readonly:= avalue; + updatefields; + end; +end; + +procedure tgriddatalink.setfieldname_merged(const avalue: string); +begin + if ffieldname_merged <> avalue then begin + ffieldname_merged:= avalue; + updatefields; + end; +end; + +procedure tgriddatalink.setfieldname_selected(const avalue: string); +begin + if ffieldname_selected <> avalue then begin + ffieldname_selected:= avalue; + updatefields; + end; +end; + +function tgriddatalink.getfirstrecord: integer; +begin + result:= inherited firstrecord; +end; + +procedure tgriddatalink.doupdaterowdata(const row: integer); + + procedure fieldtorowstate(const arow: integer); + var + int1: integer; + longword1: longword; + begin + if field_state <> nil then begin + if field_state.isnull then begin + fgrid.rowcolorstate[arow]:= -1; + fgrid.rowfontstate[arow]:= -1; + fgrid.rowreadonlystate[arow]:= false; + end + else begin + int1:= field_state.asinteger; + fgrid.rowcolorstate[arow]:= rowstatenumty(int1 and $7f); + fgrid.rowreadonlystate[arow]:= rowstatenumty(int1 and $80) <> 0; + fgrid.rowfontstate[arow]:= rowstatenumty((int1 shr 8) and $7f); + end; + end; + if (field_color <> nil) then begin + if field_color.isnull then begin + fgrid.rowcolorstate[arow]:= -1; + end + else begin + fgrid.rowcolorstate[arow]:= field_color.asinteger; + end; + end; + if (field_font <> nil) then begin + if field_font.isnull then begin + fgrid.rowfontstate[arow]:= -1; + end + else begin + fgrid.rowfontstate[arow]:= field_font.asinteger; + end; + end; + if (field_readonly <> nil) then begin + fgrid.rowreadonlystate[arow]:= field_readonly.asboolean; + end; + if field_merged <> nil then begin + if gdls_booleanmerged in fstate then begin + if field_merged.asboolean then begin + longword1:= mergedcolall; + end + else begin + longword1:= 0; + end; + end + else begin + longword1:= longword(field_merged.asinteger); + end; + with tdatacols1(fgrid.datacols) do begin + if rowstate.merged[arow] <> longword1 then begin + rowstate.merged[arow]:= longword1; + mergechanged(arow); + end; + end; + end; + if field_selected <> nil then begin + if gdls_booleanselected in fstate then begin + if field_selected.asboolean then begin + longword1:= wholerowselectedmask; + end + else begin + longword1:= 0; + end; + end + else begin + longword1:= longword(field_selected.asinteger); + end; + with tdatacols1(fgrid.datacols) do begin + if rowstate.selected[arow] <> longword1 then begin + rowstate.selected[arow]:= longword1; + fgrid.invalidaterow(arow); + end; + end; + end; + end; + +var + int1,int2: integer; + dataset1: tdataset; + buffercount1: int32; +begin + if (fgrid.componentstate * [csloading,csdesigning,csdestroying] = []) and + (row < fgrid.rowcount) then begin + dataset1:= dataset; + if dataset1 <> nil then begin + buffercount1:= buffercount; + if gdls_hasrowstatefield in fstate then begin + if row >= 0 then begin + if row < buffercount1 then begin + fieldtorowstate(row); + end; + end + else begin + int2:= activerecord; + try + for int1:= 0 to fgrid.rowhigh do begin + if int1 >= buffercount1 then begin + break; //buffer invalid + end; + activerecord:= int1; + fieldtorowstate(int1); + end; + finally + activerecord:= int2; + end; + end; + end; + if assigned(fonupdaterowdata) then begin + if row >= 0 then begin + fonupdaterowdata(fgrid,row,dataset1); + end + else begin + int2:= activerecord; + try + for int1:= 0 to fgrid.rowhigh do begin + if int1 >= buffercount1 then begin + break; //buffer invalid + end; + activerecord:= int1; + fonupdaterowdata(fgrid,int1,dataset1); + end; + finally + activerecord:= int2; + end; + end; + end; + tdatacols1(fgrid.datacols).invalidatemaxsize(-1); + end; + end; + if row < 0 then begin + fgridinvalidated:= false; //grid possibly invisible -> no painted call + end; +end; + +function tgriddatalink.hasdata: boolean; +begin + result:= active and datasource.enabled and (recordcount > 0); +end; + +procedure tgriddatalink.readdatasource(reader: treader); +begin + treader1(reader).readpropvalue(self, + getpropinfo(typeinfo(tgriddatalink),'datasource')); +end; + +procedure tgriddatalink.fixupproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('datasource',{$ifdef FPC}@{$endif}readdatasource,nil,false); + //move values to datalink +end; + +procedure tgriddatalink.readdatafield(reader: treader); +begin + fieldname_state:= reader.readstring; +end; + +procedure tgriddatalink.defineproperties(filer: tfiler); +begin + filer.defineproperty('datafield',{$ifdef FPC}@{$endif}readdatafield,nil,false); +end; + +function tgriddatalink.getrowfieldisnull(const afield: tfield; + const row: integer): boolean; +var + rowinfo: gridrowinfoty; +begin + result:= true; + if (afield <> nil) and hasdata and begingridrow(row,rowinfo) then begin + result:= afield.isnull; + endgridrow(rowinfo); + end; +end; + +function tgriddatalink.getansistringbuffer(const afield: tfield; + const row: integer): pointer; +var + rowinfo: gridrowinfoty; +begin + result:= nil; + if (afield <> nil) and hasdata and begingridrow(row,rowinfo) then begin + if not afield.isnull then begin + result:= @fansistringbuffer; + fansistringbuffer:= afield.asstring; + end; + endgridrow(rowinfo); + end; +end; + +function tgriddatalink.getstringbuffer(const afield: tfield; + const row: integer): pointer; +var + rowinfo: gridrowinfoty; +begin + result:= nil; + if (afield <> nil) and hasdata and begingridrow(row,rowinfo) then begin + if not afield.isnull then begin + result:= @fstringbuffer; + if afield is tmsestringfield then begin + fstringbuffer:= tmsestringfield(afield).asmsestring; + end + else begin + if utf8 and (afield.datatype in textfields) then begin + fstringbuffer:= utf8tostringansi(afield.asstring); + end + else begin + fstringbuffer:= msestring(afield.asstring); + end; + end; + end; + endgridrow(rowinfo); + end; +end; + +function tgriddatalink.getdisplaystringbuffer(const afield: tfield; + const row: integer): pointer; +var + rowinfo: gridrowinfoty; +begin + result:= nil; + if (afield <> nil) and hasdata and begingridrow(row,rowinfo) then begin + if not afield.isnull then begin + result:= @fstringbuffer; + if afield is tmsestringfield then begin + fstringbuffer:= tmsestringfield(afield).asmsestring; + end + else begin + if afield is tmsememofield then begin + fstringbuffer:= tmsememofield(afield).asmsestring; + end + else begin + if utf8 and (afield.datatype in textfields) then begin + fstringbuffer:= utf8tostringansi(afield.displaytext); + end + else begin + fstringbuffer:= msestring(afield.displaytext); + end; + end; + end; + end; + endgridrow(rowinfo); + end; +end; + +function tgriddatalink.getbooleanbuffer(const afield: tfield; + const row: integer): pointer; +var + rowinfo: gridrowinfoty; +begin + result:= nil; + if (afield <> nil) and hasdata and begingridrow(row,rowinfo) then begin + if not afield.isnull then begin + result:= @fintegerbuffer; + fintegerbuffer:= integer(afield.asboolean); + end; + endgridrow(rowinfo); + end; +end; + +function tgriddatalink.getintegerbuffer(const afield: tfield; + const row: integer): pointer; +var + rowinfo: gridrowinfoty; +begin + result:= nil; + if (afield <> nil) and hasdata and begingridrow(row,rowinfo) then begin + if not afield.isnull then begin + result:= @fintegerbuffer; + fintegerbuffer:= afield.asinteger; + end; + endgridrow(rowinfo); + end; +end; + +function tgriddatalink.getint64buffer(const afield: tfield; + const row: integer): pointer; +var + rowinfo: gridrowinfoty; +begin + result:= nil; + if (afield <> nil) and hasdata and begingridrow(row,rowinfo) then begin + if not afield.isnull then begin + result:= @fint64buffer; + fint64buffer:= afield.aslargeint; + end; + endgridrow(rowinfo); + end; +end; + +function tgriddatalink.getrealtybuffer(const afield: tfield; + const row: integer): pointer; +var + rowinfo: gridrowinfoty; +begin + result:= nil; + if (afield <> nil) and hasdata and begingridrow(row,rowinfo) then begin + if not afield.isnull then begin + result:= @frealtybuffer; + frealtybuffer:= afield.asfloat; + end; + endgridrow(rowinfo); + end; +end; + +function tgriddatalink.getdatetimebuffer(const afield: tfield; + const row: integer): pointer; +var + rowinfo: gridrowinfoty; +begin + result:= nil; + if (afield <> nil) and hasdata and begingridrow(row,rowinfo) then begin + if not afield.isnull then begin + result:= @frealtybuffer; + frealtybuffer:= afield.asdatetime; + end; + endgridrow(rowinfo); + end; +end; + +procedure tgriddatalink.updatelayout; +var +// ar1: integerarty; + int1: integer; +begin + with tcustomgrid1(fgrid) do begin + int1:= fgrid.rowsperpage + 1; + if int1 = 0 then begin + int1:= 1; + end; + BufferCount:= int1; + if self.active then begin + forcecalcrange; + checkscroll; + end; + int1:= fgrid.rowcount; + self.updaterowcount; + if int1 <> fgrid.rowcount then begin + tcustomgrid1(fgrid).updatelayout; //again + exit; + end; + end; + checkscrollbar; + checkactiverecord; //show cell +end; + +procedure tgriddatalink.updaterowcount; +var + int1: integer; +begin + if not (csdestroying in fgrid.componentstate) then begin + if active then begin + int1:= recordcount; + end + else begin + int1:= 0; + end; + if fgrid.rowcount <> int1 then begin + gridinvalidate; + fgrid.rowcount:= int1; + end; + end; +end; + +procedure tgriddatalink.datasetchanged; +//var +// state1: tdatasetstate; +begin + if (fdatasetchangedlock = 0) and not (csdestroying in fgrid.componentstate) then begin + finserting:= (dataset <> nil) and (dataset.state = dsinsert); + if recordcount > fgrid.rowcount then begin + updaterowcount; //for append + end; + inherited; + gridinvalidate; + if finserting and not finsertingbefore and (fgrid.datacols.newrowcol >= 0) then begin + fgrid.col:= fgrid.datacols.newrowcol; + end; + finsertingbefore:= finserting; + checkdelayedautoinsert; + end; +end; + +procedure tgriddatalink.datasetscrolled(distance: integer); +begin + if (fmovebydistance < 0) and bof or (fmovebydistance > 0) and eof then begin + include(tcustomgrid1(fgrid).fstate1,gs1_scrolllimit); + end; + fmovebydistance:= 0; + ffirstrecordbefore:= firstrecord - distance; + recordchanged(nil); +end; + +procedure tgriddatalink.forcecalcrange; +begin + if active then begin + inc(fdatasetchangedlock); + try + dataevent(dedatasetchange,0); //force tdatalink.calcrange + finally + dec(fdatasetchangedlock); + end; + end; +end; + +procedure tgriddatalink.activechanged; +begin + inherited; + if not active then begin + fzebraoffset:= 0; + factiverecordbefore:= 0; + ffirstrecordbefore:= 0; + fdatasetstatebefore:= dsinactive; + fdscontroller:= nil; + inherited firstrecord:= 0; + end + else begin + if (fsortdatalink <> nil) and (fdscontroller <> nil) then begin + fdscontroller.updatesortfield(fsortdatalink,fdescend); + end; + end; + updaterowcount; + checkscroll; + gridinvalidate; + checkscrollbar; + if active then begin + forcecalcrange; + if (fgrid.rowcount > 0) then begin + if (fgrid.col < 0) and (fgrid.entered) then begin + fgrid.focuscell(makegridcoord(fgrid.col,activerecord),fca_entergrid); + end + else begin + fgrid.focuscell(makegridcoord(fgrid.col,activerecord)); + end; + end; + factiverecordbefore:= activerecord; + checkdelayedautoinsert; + end; +end; + +procedure tgriddatalink.checkzebraoffset; +begin + if active and (gs_needszebraoffset in tcustomgrid1(fgrid).fstate) then begin + fzebraoffset:= -(arecord - activerecord); + end + else begin + fzebraoffset:= 0; + end; +end; + +procedure tgriddatalink.checkscroll; +var + rect1,rect2: rectty; + distance: integer; +// rowbefore: integer; + int1: integer; + +begin + checkzebraoffset; + distance:= firstrecord - ffirstrecordbefore; + ffirstrecordbefore:= firstrecord; + with tcustomgrid1(fgrid) do begin +// rowbefore:= row; + if distance <> 0 then begin + inc(frowexited); + row:= invalidaxis; + end; + if (abs(distance) >= rowcount) then begin + gridinvalidate; + end + else begin + if (distance <> 0) then begin + if not fgridinvalidated then begin + rect1:= fdatarecty; + if (og_rowheight in foptionsgrid) then begin + invalidaterect(rect1,org_client); //scrolling not possible + end + else begin + int1:= -distance*ystep; + rect2:= rect1; + if int1 < 0 then begin + dec(rect2.y,int1); + inc(rect2.cy,int1); + end + else begin + dec(rect2.cy,int1); + end; + if (rect2.cy > 0) and testintersectrect(rect2,updaterect) then begin + ffirstrecordshift:= distance; + inc(fzebraoffset,distance); + try + update; //draw old position + finally + dec(fzebraoffset,distance); + ffirstrecordshift:= 0; + end; + end; + dec(factiverecordbefore,distance); + scrollrect(makepoint(0,int1),rect1,true); + end; + { + if (og_rowheight in foptionsgrid) or testintersectrect(rect1,updaterect) then begin + invalidaterect(rect1,org_client); //scrolling not possible + end + else begin + dec(factiverecordbefore,distance); + scrollrect(makepoint(0,-distance*ystep),rect1,true); + end; + } + end; + inc(fnoinvalidate); + try + doupdaterowdata(-1); + finally + dec(fnoinvalidate); + end; + if (gs_needsrowheight in fstate) then begin + fdatacols.rowstate.change(-1); + end; + end; + end; + if (activerecord < rowcount) and + not (csdestroying in componentstate) then begin + inc(fnocheckvalue); + try + row:= activerecord; + finally + dec(fnocheckvalue); + end; + end; + end; +end; + +procedure tgriddatalink.checkactiverecord; +var + int1: integer; +begin + int1:= activerecord; + if (int1 < fgrid.rowcount) and active and + (tcustomgrid1(fgrid).fcellvaluechecking = 0) then begin + with tcustomgrid1(fgrid) do begin + inc(fnocheckvalue); + try + row:= int1; //else empty dataset + showcell(makegridcoord(invalidaxis,fgrid.row),cep_nearest,true); + finally + dec(fnocheckvalue); + end; + end; + end; +end; + +procedure tgriddatalink.recordchanged(afield: tfield); +var + int1: integer; + i2: int32; +// b1: boolean; +begin + int1:= frowexited; + with tcustomgrid1(fgrid) do begin + i2:= row; + if fcellvaluechecking = 0 then begin +// b1:= gs1_nocellassistive in fstate1; +// try +// include(fstate1,gs1_nocellassistive); + checkscroll(); +// finally +// if not b1 then begin +// exclude(fstate1,gs1_nocellassistive); +// end; +// end; + end; + fgrid.invalidaterow(activerecord); + tcustomgrid1(fgrid).beginnonullcheck; + tcustomgrid1(fgrid).beginnocheckvalue; + try +// b1:= gs1_nocellassistive in fstate1; +// if row <> i2 then begin +// include(fstate1,gs1_nocellassistive); +// end; + if (row = i2) and (afield = nil) and (frowexited = int1) and + (feditingbefore = editing) then begin + fgrid.row:= invalidaxis; + end; + checkactiverecord; + finally +// if not b1 then begin +// exclude(fstate1,gs1_nocellassistive); +// end; + tcustomgrid1(fgrid).endnonullcheck; + tcustomgrid1(fgrid).endnocheckvalue; + feditingbefore:= editing; + end; + fgrid.invalidaterow(factiverecordbefore); + factiverecordbefore:= activerecord; + if afield = nil then begin + updaterowcount; + checkscrollbar; + end; + end; + doupdaterowdata(activerecord); +end; + +function tgriddatalink.arecord: integer; +begin + if fdscontroller <> nil then begin + result:= fdscontroller.recnozerobased; + end + else begin + result:= dataset.recno; + end; +end; + +function tgriddatalink.rowtorecnozerobased(const row: integer): integer; +begin + if active then begin + result:= recnozerobased + row - activerecord; + end + else begin + result:= -1; + end; +end; + +function tgriddatalink.isfirstrow: boolean; +begin + result:= not active or bof; +end; + +function tgriddatalink.islastrow: boolean; +begin + result:= not active or eof; +end; + +procedure tgriddatalink.checkscrollbar; +var + rea1: real; + int1: integer; +begin + rea1:= 0.5; + if active then begin + int1:= dataset.recordcount - 1; + if bof then begin + rea1:= 0; + end + else begin + if eof then begin + rea1:= 1; + end + else begin + if (gdo_propscrollbar in foptions) and (int1 > 0) then begin + rea1:= arecord / int1; + end; + end; + end; + if int1 < 0 then begin + int1:= 0 + end; + fgrid.frame.sbvert.pagesize:= fgrid.rowcount / (int1+1+fgrid.rowcount); + end + else begin + fgrid.frame.sbvert.pagesize:= 1; + end; + fgrid.frame.sbvert.value:= rea1; +end; + +procedure tgriddatalink.cellevent(var info: celleventinfoty); +var + int1: integer; +begin + with info do begin + if (eventkind = cek_enter) and active then begin + int1:= newcell.row-activerecord; + if int1 <> 0 then begin + moveby(int1); + end; + end; + end; +end; + +procedure tgriddatalink.invalidateindicator; +var + int1,int2: integer; +begin + int1:= fintf.getdbindicatorcol; + int2:= activerecord; + if (int1 < 0) and (int2 >= 0) then begin + fgrid.invalidatecell(makegridcoord(int1,int2)); + end; +end; + +function tgriddatalink.scrollevent(sender: tcustomscrollbar; + event: scrolleventty): boolean; + //true if processed +var + int1,int2: integer; +begin + result:= true; + if sender.tag = 1 then begin + with fgrid do begin + case event of + sbe_stepup: rowdown(fca_focusin); + sbe_stepdown: rowup(fca_focusin); + sbe_pageup: pagedown(fca_focusin); + sbe_pagedown: pageup(fca_focusin); + sbe_wheelup: wheeldown(fca_focusin); + sbe_wheeldown: wheelup(fca_focusin); + {sbe_thumbtrack,}sbe_valuechanged: begin + end; + sbe_thumbtrack,sbe_thumbposition: begin + if (event <> sbe_thumbtrack) or (gdo_thumbtrack in foptions) then begin + if self.active then begin + if (sender.value = 0) then begin + if not dataset.bof then begin + dataset.first; + end; + end + else begin + if sender.value >= 1.0 then begin + if not dataset.eof then begin + dataset.last + end; + end + else begin + if (not dataset.filtered or (dscontroller <> nil)) and + (gdo_propscrollbar in foptions) then begin + int1:= dataset.recordcount; + if int1 >= 0 then begin + int2:= round(int1 * sender.value)+1; + //are recnos allways 1-based? + if (int2 >= int1) then begin + if not dataset.eof then begin + dataset.last; + end; + end + else begin + if dscontroller = nil then begin + dataset.recno:= int2; + end + else begin + dscontroller.findrecno(int2); //use cached recno +// dscontroller.recno:= int2; //use cached recno + end; + end; + end; + end + else begin + if event <> sbe_thumbtrack then begin + if sender.value < 0.5 then begin + moveby(-fgrid.rowhigh); + end + else begin + moveby(fgrid.rowhigh); + end; + sender.value:= 0.5; + end; + end; + end; + end; + end + else begin + if event <> sbe_thumbtrack then begin + sender.value:= 0.5; + end; + end; + end + end; + else result:= false; + end; + end; + end + else begin + result:= false; + end; +end; + +procedure tgriddatalink.doinsertrow; +begin + if checkvalue and caninsert then begin + dataset.insert; + with fgrid,datacols do begin + if newrowcol >= 0 then begin + focuscell(makegridcoord(newrowcol,row)); + end; + end; + end; +end; + +procedure tgriddatalink.doappendrow; +begin + if checkvalue and canappend then begin + if not eof then begin + moveby(1); + end; + if not eof then begin + dataset.insert; + end + else begin + dataset.append; + end; + with fgrid,datacols do begin + if newrowcol >= 0 then begin + focuscell(makegridcoord(newrowcol,row)); + end; + end; + end; +end; + +procedure tgriddatalink.dodeleterow; +begin + if candelete and confirmdeleterecord then begin + dataset.delete; + end; +end; + +procedure tgriddatalink.rowdown; +begin + if checkvalue then begin + moveby(1); + if (og_autoappend in tcustomgrid1(fgrid).foptionsgrid) and canappend and eof and + (datasource.autoedit or + (navigator <> nil) and navigator.autoedit) then begin + dataset.append; + with fgrid,datacols do begin + if newrowcol >= 0 then begin + focuscell(makegridcoord(newrowcol,row)); + end; + end; + end; + end; +end; + +procedure tgriddatalink.lastrow; +begin + if active and checkvalue then begin + dataset.last; + end; +end; + +procedure tgriddatalink.firstrow; +begin + if active and checkvalue then begin + dataset.first; + end; +end; + +function tgriddatalink.getzebrastart: integer; +begin + result:= tcustomgrid1(fgrid).fzebra_start + fzebraoffset; +end; + +procedure tgriddatalink.gridinvalidate; +begin + if not fgridinvalidated then begin + fgrid.invalidate; + fgridinvalidated:= true; + application.postevent(tobjectevent.create(ek_dbupdaterowdata,ievent(self))); + end; +end; + +procedure tgriddatalink.painted; +begin + fgridinvalidated:= false; +end; + +procedure tgriddatalink.loaded; +begin + doupdaterowdata(-1); + with tcustomgrid1(fgrid) do begin + if fdatacols.sortcol >= 0 then begin + optionsgrid:= optionsgrid + [og_sorted]; + end; + end; +end; + +procedure tgriddatalink.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + if (info.eventstate * [es_preview,es_processed] = []) and + (fnavigator <> nil) and fnavigator.showing and + fnavigator.isenabled then begin + fnavigator.internalshortcut(info,sender); + end; +end; + +function tgriddatalink.checkvalue: boolean; +begin + if editing then begin + result:= fgrid.canparentclose; + end + else begin + result:= true; + end; +end; + +procedure tgriddatalink.beginnullchecking; +begin + inc(fnullchecking); + tcustomgrid1(fgrid).beginnullchecking; +end; + +procedure tgriddatalink.endnullchecking; +begin + tcustomgrid1(fgrid).endnullchecking; + dec(fnullchecking); +end; + +function tgriddatalink.domoveby(const distance: integer): integer; +begin + result:= 0; + if active and (dataset.state <> dsfilter) then begin + fmovebydistance:= distance; + result:= inherited moveby(distance); + end; +end; + +function tgriddatalink.moveby(distance: integer): integer; +begin + invalidateindicator; //grid can be defocused + result:= 0; + if fnullchecking = 0 then begin + beginnullchecking; + try + if checkvalue then begin + result:= domoveby(distance); + end + else begin + tcustomgrid1(fgrid).beginnonullcheck; + try + checkactiverecord; + finally + tcustomgrid1(fgrid).endnonullcheck; + end; + end; + finally + endnullchecking; + end; + end; +end; + +function tgriddatalink.getobjectlinker: tobjectlinker; +begin + if fobjectlinker = nil then begin + createobjectlinker(ievent(self),nil,fobjectlinker); + end; + result:= fobjectlinker; +end; + +procedure tgriddatalink.link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); +begin + getobjectlinker.link(source,dest,valuepo,ainterfacetype,once); +end; + +procedure tgriddatalink.unlink(const source,dest: iobjectlink; valuepo: pointer = nil); +begin + getobjectlinker.unlink(source,dest,valuepo); +end; + +procedure tgriddatalink.objevent(const sender: iobjectlink; + const event: objecteventty); +begin + getobjectlinker.objevent(sender,event); +end; + +function tgriddatalink.getinstance: tobject; +begin + result:= self; +end; + +procedure tgriddatalink.receiveevent(const event: tobjectevent); +begin + case event.kind of + ek_dbedit: begin + edit; + end; + ek_dbupdaterowdata: begin + doupdaterowdata(-1); + end; + ek_dbinsert: begin + if fautoinserting then begin + try + if canautoinsert then begin + dataset.insert; + end; + finally + fautoinserting:= false; + end; + end; + end; + end; +end; + +procedure tgriddatalink.updatedata; +begin + beginnullchecking; + tcustomgrid1(fgrid).beginnonullcheck; + try + if checkvalue then begin + if (og_appendempty in fgrid.optionsgrid) and + (dataset.state = dsinsert) then begin + tdataset1(dataset).setmodified(true); //FPC fixes_2_6 compatibility + //force append empty row +// dataset.modified:= true; //force append empty row + end; + inherited; + end + else begin + abort; + end; + finally + tcustomgrid1(fgrid).endnonullcheck; + endnullchecking; + end; +end; + +function tgriddatalink.getdataset(const aindex: integer): tdataset; +begin + result:= dataset; +end; + +procedure tgriddatalink.getfieldtypes(out propertynames: stringarty; + out fieldtypes: fieldtypesarty); +begin + propertynames:= nil; + setlength(fieldtypes,1); + fieldtypes[0]:= integerfields; +end; + +function tgriddatalink.canautoinsert: boolean; +begin +// result:= fgrid.focused and active and (recordcount = 0) and + result:= fgrid.entered and active and (recordcount = 0) and + (og_autofirstrow in fgrid.optionsgrid) and + (datasource.autoedit or + (navigator <> nil) and navigator.autoedit); +end; + +procedure tgriddatalink.checkdelayedautoinsert; +begin + if canautoinsert and not fautoinserting then begin + fautoinserting:= true; + application.postevent(tobjectevent.create(ek_dbinsert,ievent(self))); + end; +end; + +procedure tgriddatalink.beforefocuscell(const cell: gridcoordty; + const selectaction: focuscellactionty); +begin + if (selectaction = fca_entergrid) and canautoinsert and + not fautoinserting then begin + fautoinserting:= true; + try + dataset.insert; + fgrid.focuscell(fgrid.focusedcell,selectaction); + //focus col if necessary + finally + fautoinserting:= false; + end; + end; +end; + +function tgriddatalink.getdummystringbuffer: pansistring; +begin + fdummystringbuffer:= ''; + result:= @fdummystringbuffer; +end; + +function tgriddatalink.canclose(const newfocus: twidget): boolean; +begin + result:= not (gdo_checkbrowsemodeonexit in foptions) or + (fgrid.widgetstate * [ws_entered,ws_exiting] = []) or + fgrid.checkdescendent(newfocus) or inherited canclose; +end; + +procedure tgriddatalink.focuscell(var cell: gridcoordty); +var + int1,int2,int3,int4: integer; + ds1: tdataset; +begin + if (cell.row >= 0) and (cell.row <> fgrid.row) then begin + ds1:= dataset; + if (ds1 <> nil) then begin + int1:= rowtorecnozerobased(cell.row); + if not (finserting and not finsertingbefore) then begin + int3:= recnozerobased; + if (ds1.state <> dsfilter) and not fautoinserting and + (tcustomgrid1(fgrid).fnocheckvalue = 0) then begin + ds1.checkbrowsemode; + end; + int4:= recnozerobased; + if (int1 < int3) and (int1 >= int4) then begin + inc(int1); + end + else begin + if (int1 > int3) and (int1 <= int4) then begin + dec(int1); + end; + end; + end; + int2:= ds1.recordcount; + if (int1 >= 0) and (int1 < int2) and (ds1.state <> dsfilter) then begin + invalidateindicator; //grid can be defocused + int1:= int1-recnozerobased; + if int1 <> 0 then begin + dataset.moveby(int1); + end; + end; + cell.row:= activerecord; + end; + end; +end; + +procedure tgriddatalink.editingchanged; +begin + updaterowcount; //for insert + invalidateindicator; + inherited; + if editing and fgrid.canevent(tmethod(fonbeginedit)) then begin + fonbeginedit(self); + end; + if not editing and fgrid.canevent(tmethod(fonendedit)) then begin + fonendedit(self); + end; +end; + +function tgriddatalink.getdatasource1: tdatasource; +begin + result:= inherited datasource; +end; + +procedure tgriddatalink.settadasource1(const avalue: tdatasource); +begin + inherited datasource:= avalue; + tdatacols1(fgrid.datacols).datasourcechanged; +end; + +procedure tgriddatalink.updatefields; +begin + if active then begin + if (ffieldname_state <> '') then begin + setfield_state(datasource.dataset.fieldbyname(ffieldname_state)); + end + else begin + setfield_state(nil); + end; + if (ffieldname_color <> '') then begin + setfield_color(datasource.dataset.fieldbyname(ffieldname_color)); + end + else begin + setfield_color(nil); + end; + if (ffieldname_font <> '') then begin + setfield_font(datasource.dataset.fieldbyname(ffieldname_font)); + end + else begin + setfield_font(nil); + end; + if (ffieldname_readonly <> '') then begin + setfield_readonly(datasource.dataset.fieldbyname(ffieldname_readonly)); + end + else begin + setfield_readonly(nil); + end; + if (ffieldname_merged <> '') then begin + setfield_merged(datasource.dataset.fieldbyname(ffieldname_merged)); + end + else begin + setfield_merged(nil); + end; + if (ffieldname_selected <> '') then begin + setfield_selected(datasource.dataset.fieldbyname(ffieldname_selected)); + end + else begin + setfield_selected(nil); + end; + end + else begin + setfield_state(nil); + setfield_color(nil); + setfield_font(nil); + setfield_readonly(nil); + setfield_merged(nil); + setfield_selected(nil); + end; +end; + +procedure tgriddatalink.setfield_state(const avalue: tfield); +begin + if ffield_state <> avalue then begin + ffield_state:= avalue; + fieldchanged; + end; +end; + +procedure tgriddatalink.setfield_color(const avalue: tfield); +begin + if ffield_color <> avalue then begin + ffield_color:= avalue; + fieldchanged; + end; +end; + +procedure tgriddatalink.setfield_font(const avalue: tfield); +begin + if ffield_font <> avalue then begin + ffield_font:= avalue; + fieldchanged; + end; +end; + +procedure tgriddatalink.setfield_readonly(const avalue: tfield); +begin + if ffield_readonly <> avalue then begin + ffield_readonly:= avalue; + fieldchanged; + end; +end; + +procedure tgriddatalink.setfield_merged(const avalue: tfield); +begin + if ffield_merged <> avalue then begin + ffield_merged:= avalue; + if avalue is tbooleanfield then begin + include(fstate,gdls_booleanmerged); + end + else begin + exclude(fstate,gdls_booleanmerged); + end; + fieldchanged; + end; +end; + +procedure tgriddatalink.setfield_selected(const avalue: tfield); +begin + if ffield_selected <> avalue then begin + ffield_selected:= avalue; + if avalue is tbooleanfield then begin + include(fstate,gdls_booleanselected); + end + else begin + exclude(fstate,gdls_booleanselected); + end; + fieldchanged; + end; +end; + +procedure tgriddatalink.fieldchanged; +begin + if (ffield_state <> nil) or (ffield_color <> nil) or (ffield_font <> nil) or + (ffield_readonly <> nil) or (ffield_merged <> nil) or + (ffield_selected <> nil) then begin + include(fstate,gdls_hasrowstatefield); + end + else begin + exclude(fstate,gdls_hasrowstatefield); + end; + inherited; +end; + +procedure tgriddatalink.setselected(const cell: gridcoordty; + const avalue: boolean); +var + bo1: boolean; +begin + if (ffield_selected <> nil) and (cell.row >= 0) and + (cell.row = activerecord) then begin + bo1:= editing; + dataset.edit; + if gdls_booleanselected in fstate then begin + ffield_selected.asboolean:= avalue; + end + else begin + if cell.col < 0 then begin + if avalue then begin + ffield_selected.asinteger:= integer(wholerowselectedmask); + end + else begin + ffield_selected.asinteger:= 0; + end; + end + else begin + if cell.col <= selectedcolmax then begin + if avalue then begin + ffield_selected.asinteger:= ffield_selected.asinteger or bits[cell.col]; + end + else begin + ffield_selected.asinteger:= ffield_selected.asinteger and + not bits[cell.col]; + end; + end; + end; + end; + if not bo1 and (gdo_selectautopost in foptions) then begin + dataset.post; + end; + end; +end; + +function tgriddatalink.updateoptionsgrid( + const avalue: optionsgridty): optionsgridty; +begin + result:= avalue - [og_sorted]; + with tcustomgrid1(fgrid) do begin + if og_sorted in avalue then begin + if not (gs1_dbsorted in fstate1) then begin + include(fstate1,gs1_dbsorted); + invalidate; + end + end + else begin + if gs1_dbsorted in fstate1 then begin + exclude(fstate1,gs1_dbsorted); + updatesortfield(nil,false); + invalidate; + end; + end; + end; +end; + +function tgriddatalink.updatesortfield(const avalue: tfielddatalink; + const adescend: boolean): boolean; +begin + fdescend:= adescend; + fsortdatalink:= avalue; + result:= true; + if active then begin + result:= false; + if fdscontroller <> nil then begin + result:= fdscontroller.updatesortfield(avalue,adescend); + end; + end; +end; + +function tgriddatalink.begingridrow(const arow: integer; + out ainfo: gridrowinfoty): boolean; +var + int1: integer; +begin + int1:= arow - ffirstrecordshift; + result:= (int1 >= 0) and (int1 < recordcount); + ainfo.row:= activerecord; + if result then begin + ainfo.row:= activerecord; + { + if ainfo.row <> fgrid.row then begin + //probably changed by tdatalink.destroy -> dataset.recalcbuflistsize + result:= false; + checkzebraoffset; + checkactiverecord; + fgrid.invalidaterow(invalidaxis); + exit; + end; + } + if (fdscontroller <> nil) and (datasource.state <> dsfilter) then begin + fdscontroller.begindisplaydata; + end; + activerecord:= int1; + end; +end; + +procedure tgriddatalink.endgridrow(const ainfo: gridrowinfoty); +begin + if (fdscontroller <> nil) and (datasource.state <> dsfilter) then begin + fdscontroller.enddisplaydata; + end; + activerecord:= ainfo.row; +end; + +procedure tgriddatalink.setnavigator(const avalue: tdbnavigator); +begin + if fnavigator <> avalue then begin + getobjectlinker.setlinkedvar(iobjectlink(self),tmsecomponent(avalue), + tmsecomponent(fnavigator)); + fintf.setnavigator(avalue); + end; +end; + +function tgriddatalink.getrecordcount: integer; +begin + result:= 1; + if dataset.state <> dsfilter then begin + result:= inherited getrecordcount; + end; +end; + + +{ tdbwidgetindicatorcol } + +constructor tdbwidgetindicatorcol.create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); +begin + fcolorindicator:= cl_glyph; + inherited; + options:= defaultindicatorcoloptions; + width:= 15; +end; + +procedure tdbwidgetindicatorcol.drawcell(const canvas: tcanvas); +begin + with cellinfoty(canvas.drawinfopo^),tdbwidgetfixcols(prop) do begin + if fdatalink.active and (cell.row = fdatalink.activerecord) then begin + include(drawstate,cds_notext); + inherited; + drawindicatorcell(canvas,fdatalink,fcolorindicator); + end + else begin + inherited; + end; + end; +end; + +procedure tdbwidgetindicatorcol.setcolorindicator(const avalue: colorty); +begin + if fcolorindicator <> avalue then begin + fcolorindicator:= avalue; + changed; + end; +end; + +{ tdbwidgetfixcols } + +constructor tdbwidgetfixcols.create(const aowner: tcustomwidgetgrid; + const adatalink: tgriddatalink); +begin + fdatalink:= adatalink; + inherited create(aowner); +end; + +procedure tdbwidgetfixcols.createitem(const index: integer; var item: tpersistent); +begin + if index = fdbindicatorcol then begin + item:= tdbwidgetindicatorcol.create(fgrid,self); + end + else begin + inherited; + end; +end; + +procedure tdbwidgetfixcols.setcount1(acount: integer; doinit: boolean); +begin + if (acount <= 0) and not (csdestroying in fgrid.componentstate) then begin + acount:= 1; + end; + if fdbindicatorcol >= acount then begin + fdbindicatorcol:= acount - 1; + end; + inherited; +end; + +procedure tdbwidgetfixcols.setdbindicatorcol(const Value: integer); +var + int1,int2: integer; +begin + int1:= -1 - value; + if int1 < 0 then begin + int1:= 0; + end; + if int1 >= count then begin + int1:= count-1; + end; + int2:= fdbindicatorcol; + if int1 <> int2 then begin + move(int2,int1); + fdbindicatorcol := int1; + end; +end; + +function tdbwidgetfixcols.getdbindicatorcol: integer; +begin + result:= -1-fdbindicatorcol; +end; + +{ tdbscrollbar } + +constructor tdbscrollbar.create(intf: iscrollbar; org: originty = org_client; + ondimchanged: proceventty = nil); +begin + inherited; + foptions:= defaultdbscrollbaroptions; + buttonlength:= -1; +end; + +procedure tdbscrollbar.setoptions(const avalue: scrollbaroptionsty); +begin + inherited setoptions(avalue + [sbo_thumbtrack]); +end; + +{ tdbgridframe } + +constructor tdbgridframe.create(const aintf: iscrollframe; const owner: twidget; + const autoscrollintf: iautoscrollframe); +begin + inherited; + include(fstate,fs_sbvertfix); +end; + +function tdbgridframe.getscrollbarclass(vert: boolean): framescrollbarclassty; +begin + if vert then begin + result:= tdbscrollbar; + end + else begin + result:= inherited getscrollbarclass(vert); + end; +end; + +procedure tdbgridframe.scrollevent(sender: tcustomscrollbar; event: scrolleventty); +begin + if sender.tag = 1 then begin + fintf1.scrollevent(sender,event); + end + else begin + inherited; + end; +end; + +procedure tdbgridframe.scrollpostoclientpos(var aclientrect: rectty); +begin + with aclientrect do begin + x:= - round(fhorz.value * (cx-fpaintrect.cx)); + y:= tcustomgrid1(fowner).fscrollrect.y; + end; +end; + +{ tcustomdbwidgetgrid } + +constructor tcustomdbwidgetgrid.create(aowner: tcomponent); +begin + fdatalink:= tgriddatalink.create(self,igriddatalink(self)); + inherited; + fzebra_step:= 0; + ffixcols.count:= 1; +end; + +destructor tcustomdbwidgetgrid.destroy; +begin + inherited; + fdatalink.free; +end; + +function tcustomdbwidgetgrid.getdatalink: tgriddatalink; +begin + result:= fdatalink; +end; + +procedure tcustomdbwidgetgrid.setoptionsgrid(const avalue: optionsgridty); +begin + inherited setoptionsgrid(fdatalink.updateoptionsgrid(avalue)); +end; + +procedure tcustomdbwidgetgrid.internalcreateframe; +begin + tdbgridframe.create(iscrollframe(self),self,iautoscrollframe(self)); +end; + +function tcustomdbwidgetgrid.createfixcols: tfixcols; +begin + result:= tdbwidgetfixcols.create(self,fdatalink); +end; +{ +function tcustomdbwidgetgrid.getdatasource: tdatasource; +begin + result:= fdatalink.datasource; +end; + +procedure tcustomdbwidgetgrid.setdatasource(const Value: tdatasource); +begin + fdatalink.datasource:= value; + datacols.datasourcechanged; +end; +} +procedure tcustomdbwidgetgrid.dolayoutchanged; +begin + inherited; + fdatalink.updatelayout; +end; +{ +procedure tcustomdbwidgetgrid.initcellinfo(var info: cellinfoty); +begin + inherited; + info.griddatalink:= fdatalink; +end; +} +procedure tcustomdbwidgetgrid.docellevent(var info: celleventinfoty); +begin + inherited; + fdatalink.cellevent(info); +end; + +procedure tcustomdbwidgetgrid.scrollevent(sender: tcustomscrollbar; event: scrolleventty); +begin + if not fdatalink.scrollevent(sender,event) then begin + inherited; + end; +end; + +function tcustomdbwidgetgrid.getzebrastart: integer; +begin + result:= fdatalink.getzebrastart; +end; + +function tcustomdbwidgetgrid.getnumoffset: integer; +begin + result:= -fdatalink.fzebraoffset; +end; + +procedure tcustomdbwidgetgrid.dopaint(const acanvas: tcanvas); +begin + inherited; + fdatalink.painted; +end; + +procedure tcustomdbwidgetgrid.dohide; +begin + fdatalink.painted; + inherited; +end; + +procedure tcustomdbwidgetgrid.pagedown(const action: focuscellactionty = fca_focusin); +begin + fdatalink.MoveBy(rowcount-1); +end; + +procedure tcustomdbwidgetgrid.pageup(const action: focuscellactionty = fca_focusin); +begin + fdatalink.MoveBy(-rowcount+1); +end; + +procedure tcustomdbwidgetgrid.wheeldown(const action: focuscellactionty = fca_focusin); +begin + fdatalink.MoveBy(wheelheight); +end; + +procedure tcustomdbwidgetgrid.wheelup(const action: focuscellactionty = fca_focusin); +begin + fdatalink.MoveBy(-wheelheight); +end; + +procedure tcustomdbwidgetgrid.rowdown( + const action: focuscellactionty = fca_focusin; const nowrap: boolean = false); +begin + fdatalink.rowdown; +end; + +procedure tcustomdbwidgetgrid.rowup( + const action: focuscellactionty = fca_focusin;const nowrap: boolean = false); +begin + fdatalink.MoveBy(-1); +end; + +procedure tcustomdbwidgetgrid.lastrow(const action: focuscellactionty = fca_focusin); +begin + fdatalink.lastrow; +end; + +procedure tcustomdbwidgetgrid.firstrow(const action: focuscellactionty = fca_focusin); +begin + fdatalink.firstrow; +end; + +procedure tcustomdbwidgetgrid.dodeleterow(const sender: tobject); +begin + fdatalink.dodeleterow; +end; + +procedure tcustomdbwidgetgrid.doinsertrow(const sender: tobject); +begin + fdatalink.doinsertrow; +end; + +procedure tcustomdbwidgetgrid.doappendrow(const sender: tobject); +begin + fdatalink.doappendrow; +end; + + +procedure tcustomdbwidgetgrid.setdatalink(const avalue: tgriddatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tcustomdbwidgetgrid.loaded; +begin + inherited; + fdatalink.loaded; +end; + +procedure tcustomdbwidgetgrid.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +function tcustomdbwidgetgrid.getgriddatalink: pointer; +begin + result:= fdatalink; +end; + +procedure tcustomdbwidgetgrid.beforefocuscell(const cell: gridcoordty; + const selectaction: focuscellactionty); +begin + fdatalink.beforefocuscell(cell,selectaction); +end; + +function tcustomdbwidgetgrid.canclose(const newfocus: twidget): boolean; +begin + result:= inherited canclose(newfocus) and fdatalink.canclose(newfocus); +end; + +function tcustomdbwidgetgrid.focuscell(cell: gridcoordty; + selectaction: focuscellactionty = fca_focusin; + const selectmode: selectcellmodety = scm_cell; + const ashowcell: cellpositionty = cep_nearest): boolean; +begin + fdatalink.focuscell(cell); + result:= inherited focuscell(cell,selectaction,selectmode,ashowcell); +end; + +function tcustomdbwidgetgrid.isfirstrow: boolean; +begin + result:= fdatalink.isfirstrow; +end; + +function tcustomdbwidgetgrid.islastrow: boolean; +begin + result:= fdatalink.islastrow; +end; + +procedure tcustomdbwidgetgrid.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +function tcustomdbwidgetgrid.getdbindicatorcol: integer; +begin + result:= fixcols.dbindicatorcol; +end; + +function tcustomdbwidgetgrid.getfixcols: tdbwidgetfixcols; +begin + result:= tdbwidgetfixcols(inherited fixcols); +end; + +procedure tcustomdbwidgetgrid.setfixcols(const avalue: tdbwidgetfixcols); +begin + inherited +end; + +procedure tcustomdbwidgetgrid.setselected(const cell: gridcoordty; + const avalue: boolean); +begin + fdatalink.setselected(cell,avalue); +end; + +function tcustomdbwidgetgrid.updatesortcol(const avalue: integer): integer; +begin + result:= inherited updatesortcol(avalue); + if not fdatalink.updatesortfield(getfieldlink(avalue), + getsortdescend(avalue)) then begin + result:= -1; + end; +end; + +function tcustomdbwidgetgrid.getfieldlink( + const acol: integer): tcustomeditwidgetdatalink; +var + widget1: twidget; + intf1: idbeditfieldlink; +begin + result:= nil; + if (acol >= 0) and (acol < fdatacols.count) then begin + widget1:= twidgetcol(tdatacols1(fdatacols).fitems[acol]).editwidget; + if (widget1 <> nil) and + widget1.getcorbainterface(typeinfo(idbeditfieldlink),intf1) then begin + result:= intf1.getfieldlink; + end; + end; +end; + +function tcustomdbwidgetgrid.canautoappend: boolean; +begin + result:= inherited canautoappend and fdatalink.canautoinsert; +end; + +procedure tcustomdbwidgetgrid.setnavigator(const avalue: tdbnavigator); +var + int1: integer; + fieldlink1: tcustomeditwidgetdatalink; +begin + if not (csloading in componentstate) then begin + for int1:= 0 to fdatacols.count - 1 do begin + fieldlink1:= getfieldlink(int1); + if fieldlink1 <> nil then begin + fieldlink1.navigator:= avalue; + end; + end; + end; +end; + +function tcustomdbwidgetgrid.createdatacols: tdatacols; +begin + result:= tdbwidgetcols.create(self); +end; + +function tcustomdbwidgetgrid.caninsertrow: boolean; +begin + result:= inherited caninsertrow and fdatalink.caninsert; +end; + +function tcustomdbwidgetgrid.canappendrow: boolean; +begin + result:= inherited canappendrow and fdatalink.canappend; +end; + +function tcustomdbwidgetgrid.candeleterow: boolean; +begin + result:= inherited candeleterow and fdatalink.candelete; +end; + +procedure tcustomdbwidgetgrid.createdatacol(const index: integer; + out item: tdatacol); +begin + item:= tdbwidgetcol.create(self,fdatacols); +end; + +function tcustomdbwidgetgrid.getdatacols: tdbwidgetcols; +begin + result:= tdbwidgetcols(fdatacols); +end; + +procedure tcustomdbwidgetgrid.setdatacols(const avalue: tdbwidgetcols); +begin + inherited; +end; + +function tcustomdbwidgetgrid.getassistiveflags(): assistiveflagsty; +begin + result:= inherited getassistiveflags() + [asf_db]; +end; +{ +procedure tcustomdbwidgetgrid.doenter; +begin + fdatalink.doenter(self); + inherited; +end; + +procedure tcustomdbwidgetgrid.doexit; +begin + fdatalink.doexit(self); + inherited; +end; +} +{ tstringcoldatalink } + +procedure tstringcoldatalink.layoutchanged; +begin + inherited; + tcustomdbstringgrid(fintf.getwidget).checkautofields; +end; + +procedure tstringcoldatalink.updatedata; +var + grid1: tcustomdbstringgrid; +begin + grid1:= tcustomdbstringgrid(fintf.getwidget); + inc(grid1.fdatalink.fcanclosing); + try + inherited; + finally + dec(grid1.fdatalink.fcanclosing); + end; +end; + +{ tdbstringcol } + +constructor tdbstringcol.create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); +begin + fdatalink:= tstringcoldatalink.create(idbeditfieldlink(self)); + fdatalink.options:= tdbstringcols(aowner).foptionsdb; + fdatalink.navigator:= tcustomdbstringgrid(agrid).datalink.navigator; + inherited; + fdatalink.griddatasourcechanged; +end; + +destructor tdbstringcol.destroy; +begin + inherited; + fdatalink.free; +end; + +function tdbstringcol.getdatafield: string; +begin + result:= fdatalink.fieldname; +end; + +procedure tdbstringcol.setdatafield(const avalue: string); +begin + fdatalink.fieldname:= avalue; +end; + +procedure tdbstringcol.modified; +begin + inherited; + fdatalink.modified; +end; + +function tdbstringcol.getrowtext(const arow: integer): msestring; +var + po1: pmsestring; +begin + po1:= pmsestring( + tcustomdbstringgrid(fcellinfo.grid).fdatalink.getdisplaystringbuffer( + fdatalink.field,arow)); + if po1 = nil then begin + result:= fdatalink.nullsymbol; + end + else begin + result:= po1^; + end; +end; + +function tdbstringcol.getitems(aindex: integer): msestring; +begin +// if aindex = fgrid.row then begin +// result:= inherited getitems(aindex); +// end +// else begin + result:= getrowtext(aindex); +// end; +end; + +procedure tdbstringcol.setitems(aindex: integer; const Value: msestring); +begin + //dummy +end; + +function tdbstringcol.getgriddatasource: tdatasource; +begin + result:= tcustomdbstringgrid(fcellinfo.grid).datalink.datasource; +end; + +function tdbstringcol.getgridintf: iwidgetgrid; +begin + result:= iwidgetgrid(tcustomdbstringgrid(fcellinfo.grid)); +end; + +function tdbstringcol.getwidget: twidget; +begin + result:= fcellinfo.grid; +end; + +function tdbstringcol.seteditfocus: boolean; +begin + if not readonly then begin + grid.col:= index; + if not grid.focused then begin + if grid.canfocus then begin + grid.setfocus; + end; + end; + end; + result:= grid.entered and (grid.col = index); +end; + +function tdbstringcol.getedited: boolean; +begin + result:= fds_modified in fdatalink.fstate; +end; + +procedure tdbstringcol.initeditfocus; +begin + with tcustomstringgrid1(fcellinfo.grid) do begin + if (ffocusedcell.col = index) and (ffocusedcell.row >= 0) then begin + feditor.dofocus; + end; + end; +end; + +procedure tdbstringcol.updatereadonlystate; +begin + if (fcellinfo.grid.col = self.index) and (fcellinfo.grid.row >= 0) then begin + tcustomstringgrid1(fcellinfo.grid).feditor.updatecaret; + end; +end; + +function tdbstringcol.checkvalue(const quiet: boolean = false): boolean; +begin + result:= true; + tcustomdbstringgrid(fcellinfo.grid).checkcellvalue(result); +end; + +procedure tdbstringcol.valuetofield; +//var +// int1: integer; +// mstr1: msestring; +begin + with tcustomdbstringgrid(fcellinfo.grid) do begin + if col = index then begin + self.fdatalink.asnullmsestring:= feditor.text; + end; + end; +// int1:= tcustomdbstringgrid(fgrid).fdatalink.activerecord; +// if (int1 >= 0) and (int1 < fgrid.rowcount) then begin +// fdatalink.asnullmsestring:= items[int1]; +// end; +end; + +procedure tdbstringcol.fieldtovalue; +//var +// int1: integer; +begin + with tcustomdbstringgrid(fcellinfo.grid) do begin + if col = index then begin + feditor.text:= self.fdatalink.msedisplaytext('',true); + end + else begin + self.invalidatecell(fdatalink.activerecord); + end; + end; + datachange(fdatalink.activerecord); +// int1:= tcustomdbstringgrid(fgrid).fdatalink.activerecord; +// if (int1 >= 0) and (int1 < fgrid.rowcount) then begin +// items[int1]:= fdatalink.msedisplaytext('',true); +// end; +end; + +procedure tdbstringcol.setnullvalue; +//var +// int1: integer; +begin + with tcustomdbstringgrid(fcellinfo.grid) do begin + if col = index then begin + feditor.text:= self.fdatalink.nullsymbol; + end + else begin + self.invalidatecell(fdatalink.activerecord); + end; + end; +// int1:= tcustomdbstringgrid(fgrid).fdatalink.activerecord; +// if (int1 >= 0) and (int1 < fgrid.rowcount) then begin +// items[int1]:= fdatalink.nullsymbol; +// end; +end; + +procedure tdbstringcol.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= stringfields; +end; + +procedure tdbstringcol.getfieldtypes(out propertynames: stringarty; + out fieldtypes: fieldtypesarty); +begin + propertynames:= nil; + setlength(fieldtypes,1); + fieldtypes[0]:= stringfields; +end; + +function tdbstringcol.getdataset(const aindex: integer): tdataset; +begin + result:= tcustomdbstringgrid(fcellinfo.grid).datalink.dataset; +end; + +function tdbstringcol.getoptionsdb: optionseditdbty; +begin + result:= fdatalink.options; +end; + +procedure tdbstringcol.setoptionsdb(const avalue: optionseditdbty); +begin + fdatalink.options:= avalue; +end; + +function tdbstringcol.getnullsymbol: msestring; +begin + result:= fdatalink.nullsymbol; +end; + +procedure tdbstringcol.setnullsymbol(const avalue: msestring); +begin + fdatalink.nullsymbol:= avalue; +end; + +function tdbstringcol.createdatalist: tdatalist; +begin + result:= nil; +end; + +procedure tdbstringcol.setmaxlength(const avalue: integer); +begin + fmaxlength:= avalue; +end; + +function tdbstringcol.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; + +procedure tdbstringcol.setifiserverintf(const aintf: iifiserver); +begin + fifiserverintf:= aintf; +end; + +procedure tdbstringcol.docellfocuschanged(enter: boolean; + const cellbefore: gridcoordty; var newcell: gridcoordty; + const selectaction: focuscellactionty); +var + state1: ifiwidgetstatesty; + int1: integer; +begin + int1:= tcustomgrid1(fcellinfo.grid).ffocuscount; + inherited; + if int1 = tcustomgrid1(fcellinfo.grid).ffocuscount then begin + state1:= []; + if enter then begin + include(state1,iws_focused); + end; + if visible then begin + include(state1,iws_visible); + end; + if fcellinfo.grid.active then begin + include(state1,iws_active); + end; + fdatalink.statechanged(iificlient(self),state1); + end; +end; + +procedure tdbstringcol.dobeforedrawcell(const acanvas: tcanvas; + var processed: boolean); +var + info: gridrowinfoty; +begin + tcustomdbstringgrid(grid).fdatalink.begingridrow( + fcellinfo.cell.row,info); + try + inherited; + finally + tcustomdbstringgrid(grid).fdatalink.endgridrow(info); + end; +end; + +procedure tdbstringcol.doafterdrawcell(const acanvas: tcanvas); +var + info: gridrowinfoty; +begin + tcustomdbstringgrid(grid).fdatalink.begingridrow( + fcellinfo.cell.row,info); + try + inherited; + finally + tcustomdbstringgrid(grid).fdatalink.endgridrow(info); + end; +end; + +function tdbstringcol.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + if fifiserverintf <> nil then begin + fifiserverintf.updateoptionsedit(result); + end; +end; + +function tdbstringcol.getdefaultifilink: iificlient; +begin + result:= iificlient(self); +end; + +function tdbstringcol.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iifidatalink); +end; + +function tdbstringcol.getifidatatype(): listdatatypety; +begin + result:= dl_msestring; +end; + +procedure tdbstringcol.updateifigriddata(const sender: tobject; + const alist: tdatalist); +begin + //dummy +end; + +function tdbstringcol.getgriddata: tdatalist; +begin + result:= nil; +end; + +function tdbstringcol.getvalueprop: ppropinfo; +begin + result:= nil; +end; + +procedure tdbstringcol.getifivalue(var avalue); +begin + //dummy +end; + +procedure tdbstringcol.setifivalue(const avalue); +begin + //dummy +end; + +{ +procedure tdbstringcol.docellevent(var info: celleventinfoty); +begin + with info do begin + if cellbefore.col <> newcell.col then begin + if (info.eventkind = cek_enter) and (newcell.col = index) then begin + fdatalink.doenter(self); + end + else begin + if (info.eventkind = cek_exit) and (cellbefore.col = index) then begin + fdatalink.doexit(self); + end; + end; + end; + end; + inherited; +end; +} +{ tdropdowndbstringcol } + +{ tdbstringcols } + +class function tdbstringcols.getitemclasstype: persistentclassty; +begin + result:= tdbstringcol; +end; + +function tdbstringcols.getcols(const index: integer): tdbstringcol; +begin + result:= tdbstringcol(items[index]); +end; + +function tdbstringcols.getcolclass: stringcolclassty; +begin + result:= tdbstringcol; +end; + +procedure tdbstringcols.datasourcechanged; +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + cols[int1].fdatalink.griddatasourcechanged; + end; +end; + +procedure tdbstringcols.setoptionsdb(const avalue: optionseditdbty); +var + int1: integer; + mask: {$ifdef FPC}longword{$else}word{$endif}; +begin + if foptionsdb <> avalue then begin + mask:= {$ifdef FPC}longword{$else}word{$endif}(avalue) xor + {$ifdef FPC}longword{$else}word{$endif}(foptionsdb); + foptionsdb := avalue; + if not (csloading in fgrid.componentstate) then begin + for int1:= 0 to count - 1 do begin + tdbstringcol(items[int1]).optionsdb:= optionseditdbty( + replacebits({$ifdef FPC}longword{$else}word{$endif}(avalue), + {$ifdef FPC}longword{$else}word{$endif}(tdbstringcol(items[int1]).optionsdb), + mask)); + end; + end; + end; +end; + +{ tdbstringindicatorcol } + +constructor tdbstringindicatorcol.create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); +begin + fcolorindicator:= cl_glyph; + inherited; + options:= defaultindicatorcoloptions; + width:= 15; +end; + +procedure tdbstringindicatorcol.drawcell(const canvas: tcanvas); +begin + with cellinfoty(canvas.drawinfopo^),tdbstringfixcols(prop) do begin + if fdatalink.active and (cell.row = fdatalink.activerecord) then begin + include(drawstate,cds_notext); + inherited; + drawindicatorcell(canvas,fdatalink,fcolorindicator); + end + else begin + inherited; + end; + end; +end; + +procedure tdbstringindicatorcol.setcolorindicator(const avalue: colorty); +begin + if fcolorindicator <> avalue then begin + fcolorindicator:= avalue; + changed; + end; +end; + +{ tdbstringfixcols } + +constructor tdbstringfixcols.create(const aowner: tcustomgrid; + const adatalink: tgriddatalink); +begin + fdatalink:= adatalink; + inherited create(aowner); +end; + +procedure tdbstringfixcols.createitem(const index: integer; var item: tpersistent); +begin + if index = fdbindicatorcol then begin + item:= tdbstringindicatorcol.create(fgrid,self); + end + else begin + inherited; + end; +end; + +procedure tdbstringfixcols.setcount1(acount: integer; doinit: boolean); +begin + if (acount <= 0) and not (csdestroying in fgrid.componentstate) then begin + acount:= 1; + end; + if fdbindicatorcol >= acount then begin + fdbindicatorcol:= acount - 1; + end; + inherited; +end; + +procedure tdbstringfixcols.setdbindicatorcol(const Value: integer); +var + int1,int2: integer; +begin + int1:= -1 - value; + if int1 < 0 then begin + int1:= 0; + end; + if int1 >= count then begin + int1:= count-1; + end; + int2:= fdbindicatorcol; + if int1 <> int2 then begin + move(int2,int1); + fdbindicatorcol := int1; + end; +end; + +function tdbstringfixcols.getdbindicatorcol: integer; +begin + result:= -1-fdbindicatorcol; +end; + +{ tstringgriddatalink } + +procedure tstringgriddatalink.activechanged; +begin + if active then begin + tcustomdbstringgrid(fgrid).checkautofields; + end; + inherited; +end; + +{ tcustomdbstringgrid } + +constructor tcustomdbstringgrid.create(aowner: tcomponent); +begin + ffieldnamedisplayfixrow:= -1; + fdatalink:= tstringgriddatalink.create(self,igriddatalink(self)); + inherited; + fzebra_step:= 0; + ffixcols.count:= 1; +end; + +destructor tcustomdbstringgrid.destroy; +begin + inherited; + fdatalink.free; +end; + +//iwidgetgrid (dummy) + +function tcustomdbstringgrid.getbrushorigin: pointty; +begin + result:= nullpoint; +end; + +function tcustomdbstringgrid.getcol: twidgetcol; +begin + result:= nil; +end; + +procedure tcustomdbstringgrid.getdata(var index: integer; var dest); +begin + //dummy +end; + +procedure tcustomdbstringgrid.setdata(var index: integer; const source; + const noinvalidate: boolean = false); +begin + //dummy +end; + +procedure tcustomdbstringgrid.datachange(const arow: integer); +begin + //dummy +end; + +function tcustomdbstringgrid.getrow: integer; +begin + result:= ffocusedcell.row; +end; + +procedure tcustomdbstringgrid.setrow(arow: integer); +begin + row:= arow; +end; + +procedure tcustomdbstringgrid.changed; +begin + //dummy +end; + +procedure tcustomdbstringgrid.edited(); +begin + //dummy +end; + +function tcustomdbstringgrid.empty(index: integer): boolean; +begin + result:= false; +end; + +procedure tcustomdbstringgrid.updateeditoptions(var aoptions: optionseditty; + const aoptions1: optionsedit1ty); +begin + //dummy +end; + +procedure tcustomdbstringgrid.showrect(const arect: rectty; + const aframe: tcustomframe); +begin + //dummy +end; + +procedure tcustomdbstringgrid.widgetpainted(const canvas: tcanvas); +begin + //dummy +end; + +function tcustomdbstringgrid.nullcheckneeded(const newfocus: twidget): boolean; +begin + result:= fnonullcheck = 0; +end; + +function tcustomdbstringgrid.nonullcheck: boolean; +begin + result:= fnonullcheck > 0; +end; + +procedure tcustomdbstringgrid.internalcreateframe; +begin + tdbgridframe.create(iscrollframe(self),self,iautoscrollframe(self)); +end; +{ +function tcustomdbstringgrid.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + if ffocusedcell.col >= 0 then begin + datacols[ffocusedcell.col].fdatalink.updateoptionsedit(result); + end; +end; +} +function tcustomdbstringgrid.createfixcols: tfixcols; +begin + result:= tdbstringfixcols.create(self,fdatalink); +end; + +function tcustomdbstringgrid.createdatacols: tdatacols; +begin + result:= tdbstringcols.create(self); +end; +{ +function tcustomdbstringgrid.getdatasource: tdatasource; +begin + result:= fdatalink.datasource; +end; + +procedure tcustomdbstringgrid.setdatasource(const Value: tdatasource); +begin + fdatalink.datasource:= value; + datacols.datasourcechanged; +end; +} +function tcustomdbstringgrid.getdatacols: tdbstringcols; +begin + result:= tdbstringcols(fdatacols); +end; + +procedure tcustomdbstringgrid.setdatacols(const avalue: tdbstringcols); +begin + fdatacols.assign(avalue); +end; + +procedure tcustomdbstringgrid.updatelayout; +begin + inherited; + fdatalink.updatelayout; +end; +{ +procedure tcustomdbstringgrid.initcellinfo(var info: cellinfoty); +begin + inherited; + info.griddatalink:= fdatalink; +end; +} +procedure tcustomdbstringgrid.docellevent(var info: celleventinfoty); +begin + inherited; + fdatalink.cellevent(info); +end; + +procedure tcustomdbstringgrid.scrollevent(sender: tcustomscrollbar; event: scrolleventty); +begin + if not fdatalink.scrollevent(sender,event) then begin + inherited; + end; +end; + +function tcustomdbstringgrid.getzebrastart: integer; +begin + result:= fdatalink.getzebrastart; +end; + +function tcustomdbstringgrid.getnumoffset: integer; +begin + result:= -fdatalink.fzebraoffset; +end; + +procedure tcustomdbstringgrid.checkcellvalue(var accept: boolean); +var + co1: tdbstringcol; +begin + inherited; + if accept and (ffocusedcell.col >= 0) then begin + co1:= datacols[ffocusedcell.col]; + with co1 do begin; + if (fds_modified in fdatalink.fstate) and self.fdatalink.active then begin +// fdatalink.datachanged; + fdatalink.valuechanged(iifidatalink(co1)); + end; + end; + end; +end; + +function tcustomdbstringgrid.canclose(const newfocus: twidget): boolean; +begin + result:= true; + checkcellvalue(result); + result:= result and fdatalink.canclose(newfocus); +end; + +procedure tcustomdbstringgrid.dopaint(const acanvas: tcanvas); +begin + inherited; + fdatalink.painted; +end; + +procedure tcustomdbstringgrid.dohide; +begin + fdatalink.painted; + inherited; +end; + +procedure tcustomdbstringgrid.pagedown(const action: focuscellactionty = fca_focusin); +begin + fdatalink.MoveBy(rowcount-1); +end; + +procedure tcustomdbstringgrid.pageup(const action: focuscellactionty = fca_focusin); +begin + fdatalink.MoveBy(-rowcount+1); +end; + +procedure tcustomdbstringgrid.wheeldown(const action: focuscellactionty = fca_focusin); +begin + fdatalink.MoveBy(wheelheight); +end; + +procedure tcustomdbstringgrid.wheelup(const action: focuscellactionty = fca_focusin); +begin + fdatalink.MoveBy(-wheelheight); +end; + +procedure tcustomdbstringgrid.rowdown( + const action: focuscellactionty = fca_focusin; const nowrap: boolean = false); +begin + fdatalink.rowdown; +end; + +procedure tcustomdbstringgrid.rowup( + const action: focuscellactionty = fca_focusin; const nowrap: boolean = false); +begin + fdatalink.MoveBy(-1); +end; + +procedure tcustomdbstringgrid.lastrow(const action: focuscellactionty = fca_focusin); +begin + fdatalink.lastrow; +end; + +procedure tcustomdbstringgrid.firstrow(const action: focuscellactionty = fca_focusin); +begin + fdatalink.firstrow; +end; + +procedure tcustomdbstringgrid.dodeleterow(const sender: tobject); +begin + fdatalink.dodeleterow; +end; + +procedure tcustomdbstringgrid.doinsertrow(const sender: tobject); +begin + fdatalink.doinsertrow; +end; + +procedure tcustomdbstringgrid.doappendrow(const sender: tobject); +begin + fdatalink.doappendrow; +end; + +procedure tcustomdbstringgrid.setoptions(const avalue: dbstringgridoptionsty); +begin + if foptions <> avalue then begin + foptions:= avalue; + checkautofields; + end; +end; + +procedure tcustomdbstringgrid.setfieldnamedisplayfixrow(const avalue: integer); +begin + if avalue <> ffieldnamedisplayfixrow then begin + ffieldnamedisplayfixrow:= avalue; + if ffieldnamedisplayfixrow > 0 then begin + ffieldnamedisplayfixrow:= 0; + end; + checkautofields; + end; +end; + +function tcustomdbstringgrid.getdatalink: tgriddatalink; +begin + result:= fdatalink; +end; + +procedure tcustomdbstringgrid.setoptionsgrid(const avalue: optionsgridty); +begin + inherited setoptionsgrid(fdatalink.updateoptionsgrid(avalue)); +end; + +procedure tcustomdbstringgrid.doasyncevent(var atag: integer); +var + int1,int2: integer; + field1: tfield; + charwi: integer; + focusedcellbefore: gridcoordty; +begin + if tag = 0 then begin + beginupdate; + try + focusedcellbefore:= focusedcell; + datacols.count:= 0; + charwi:= getcanvas.getstringwidth('o'); + if fdatalink.dataset <> nil then begin + for int1:= 0 to fdatalink.dataset.fields.count - 1 do begin + field1:= fdatalink.dataset.fields[int1]; + with field1 do begin + if (datatype in stringfields) and visible then begin + datacols.count:= datacols.count + 1; + with datacols[datacols.count-1] do begin + if readonly then begin + options:= options + [co_readonly]; + end; + datafield:= fieldname; + int2:= displaywidth; + if (int2 = 0) or (int2 > maxautodisplaywidth) then begin + int2:= maxautodisplaywidth; + end; + width:= charwi * int2; + textflags:= textflags - [tf_xcentered,tf_right]; + case alignment of + tacenter: begin + textflags:= textflags + [tf_xcentered]; + end; + tarightjustify: begin + textflags:= textflags + [tf_right]; + end; + end; + if (ffieldnamedisplayfixrow < 0) and + (-ffieldnamedisplayfixrow <= ffixrows.count) then begin + with ffixrows[ffieldnamedisplayfixrow] do begin + captions.count:= datacols.count; + captions[datacols.count-1].caption:= msestring(displaylabel); + end; + end; + end; + end; + end; + end; + end; + focuscell(focusedcellbefore); + finally + endupdate; + end; + end; +end; + +procedure tcustomdbstringgrid.checkautofields; +var + int1: integer; +begin + if dsgo_autofields in foptions then begin + for int1:= 0 to datacols.count - 1 do begin + datacols[int1].datafield:= ''; + end; + asyncevent(0); //datalinks can not be destroyed + end; +end; + +procedure tcustomdbstringgrid.setdatalink(const avalue: tstringgriddatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tcustomdbstringgrid.loaded; +begin + inherited; + fdatalink.loaded; +end; + +procedure tcustomdbstringgrid.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +function tcustomdbstringgrid.cangridcopy: boolean; +begin + result:= fdatacols.hasselection; +end; + +function tcustomdbstringgrid.getgrid: tcustomwidgetgrid; +begin + result:= nil; +end; + +function tcustomdbstringgrid.getdatapo(const arow: integer): pointer; +begin + result:= nil; +end; + +function tcustomdbstringgrid.getrowdatapo: pointer; +begin + result:= nil; +end; +{$ifdef mse_with_ifi} +procedure tcustomdbstringgrid.updateifigriddata(const alist: tdatalist); +begin + //dummy +end; +{$endif} + +procedure tcustomdbstringgrid.beforefocuscell(const cell: gridcoordty; + const selectaction: focuscellactionty); +begin + fdatalink.beforefocuscell(cell,selectaction); +end; + +{ replaced by oed_limitcharlen +procedure tcustomdbstringgrid.editnotification(var info: editnotificationinfoty); +var + int1: integer; +begin + inherited; + if isdatacell(ffocusedcell) and (info.action = ea_textedited) and + datacols[ffocusedcell.col].fdatalink.cuttext(feditor.text,int1) then begin + feditor.text:= copy(feditor.text,1,int1); + end; +end; +} +function tcustomdbstringgrid.focuscell(cell: gridcoordty; + selectaction: focuscellactionty = fca_focusin; + const selectmode: selectcellmodety = scm_cell; + const ashowcell: cellpositionty = cep_nearest): boolean; +begin + fdatalink.focuscell(cell); + result:= inherited focuscell(cell,selectaction,selectmode,ashowcell); +end; + +function tcustomdbstringgrid.getfixcols: tdbstringfixcols; +begin + result:= tdbstringfixcols(inherited fixcols); +end; + +procedure tcustomdbstringgrid.setfixcols(const avalue: tdbstringfixcols); +begin + inherited; +end; + +function tcustomdbstringgrid.getassistiveflags(): assistiveflagsty; +begin + result:= inherited getassistiveflags() + [asf_db]; +end; + +function tcustomdbstringgrid.getdbindicatorcol: integer; +begin + result:= fixcols.dbindicatorcol; +end; + +procedure tcustomdbstringgrid.coloptionstoeditoptions(var dest: optionseditty; + var dest1: optionsedit1ty); +begin + //dummy +end; + +function tcustomdbstringgrid.isfirstrow: boolean; +begin + result:= fdatalink.isfirstrow; +end; + +function tcustomdbstringgrid.islastrow: boolean; +begin + result:= fdatalink.islastrow; +end; + +procedure tcustomdbstringgrid.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +procedure tcustomdbstringgrid.setselected(const cell: gridcoordty; + const avalue: boolean); +begin + fdatalink.setselected(cell,avalue); +end; + +procedure tcustomdbstringgrid.setupeditor(const acell: gridcoordty; + const focusin: boolean); +begin + if acell.col >= 0 then begin + with tdbstringcol(tdatacols1(fdatacols).fitems[acell.col]) do begin + if (fmaxlength = 0){or not (oed_limitcharlen in fdatalink.foptions)} then begin + feditor.maxlength:= -1; + end + else begin + feditor.maxlength:= fmaxlength; + end; + end; + end; + inherited; +end; + +function tcustomdbstringgrid.updatesortcol(const avalue: integer): integer; +begin + result:= inherited updatesortcol(avalue); + if not fdatalink.updatesortfield(getfieldlink(avalue),getsortdescend(avalue)) then begin + result:= -1; + end; +end; + +function tcustomdbstringgrid.getfieldlink(const acol: integer): tfielddatalink; +begin + if (acol < 0) or (acol >= fdatacols.count) then begin + result:= nil; + end + else begin + result:= tdbstringcol(tdbstringcols(fdatacols).fitems[acol]).fdatalink; + end; +end; + +function tcustomdbstringgrid.canautoappend: boolean; +begin + result:= inherited canautoappend and fdatalink.canautoinsert; +end; + +procedure tcustomdbstringgrid.setnavigator(const avalue: tdbnavigator); +var + int1: integer; +begin + for int1:= 0 to fdatacols.count - 1 do begin + tdbstringcol(tdbstringcols(fdatacols).fitems[int1]).fdatalink.navigator:= avalue; + end; +end; + +function tcustomdbstringgrid.caninsertrow: boolean; +begin + result:= inherited caninsertrow and fdatalink.caninsert; +end; + +function tcustomdbstringgrid.canappendrow: boolean; +begin + result:= inherited canappendrow and fdatalink.canappend; +end; + +function tcustomdbstringgrid.candeleterow: boolean; +begin + result:= inherited candeleterow and fdatalink.candelete; +end; +{ +procedure tcustomdbstringgrid.doenter; +begin + fdatalink.doenter(self); + inherited; +end; + +procedure tcustomdbstringgrid.doexit; +begin + fdatalink.doexit(self); + inherited; +end; +} +{ tlbdropdowncol } + +procedure tlbdropdowncol.setfieldno(const avalue: lookupbufferfieldnoty); +begin + if avalue <> ffieldno then begin + ffieldno:= avalue; + end; +end; + +function tlbdropdowncol.getlbdatakind(const apropname: string): lbdatakindty; +begin + result:= lbdk_text; +end; + +function tlbdropdowncol.getlookupbuffer: tcustomlookupbuffer; +begin + result:= tcustomlbdropdownlistcontroller(fowner).lookupbuffer; +end; + +{ tlbdropdowncols } + +function tlbdropdowncols.getitems(const index: integer): tlbdropdowncol; +begin + result:= tlbdropdowncol(inherited getitems(index)); +end; + +function tlbdropdowncols.getcolclass: dropdowncolclassty; +begin + result:= tlbdropdowncol; +end; + +{ texterndatadropdownlistcontroller } + +constructor texterndatadropdownlistcontroller.create(const intf: ilbdropdownlist); +begin + inherited create(intf); + options:= defaulteddropdownoptions; +end; + +procedure texterndatadropdownlistcontroller.valuecolchanged; +begin + //dummy +end; + +function texterndatadropdownlistcontroller.getbuttonframeclass: + dropdownbuttonframeclassty; +begin + result:= tdropdownmultibuttonframe; +end; + +function texterndatadropdownlistcontroller.getdropdowncolsclass: + dropdowncolsclassty; +begin + result:= tlbdropdowncols; +end; + + +procedure texterndatadropdownlistcontroller.dropdown; +begin + tdropdowncols1(fcols).fitemindex:= -1; + inherited; +end; + +{ tdbenumeditlb } + +function tdbenumeditlb.getdropdown: tlbdropdownlistcontroller; +begin + result:= tlbdropdownlistcontroller(fdropdown); +end; + +procedure tdbenumeditlb.setdropdown(const avalue: tlbdropdownlistcontroller); +begin + fdropdown.assign(avalue); +end; + +function tdbenumeditlb.createdropdowncontroller: tcustomdropdowncontroller; +begin + result:= tlbdropdownlistcontroller.create(ilbdropdownlist(self)); +end; + +procedure tdbenumeditlb.recordselected(const arecordnum: integer; const akey: keyty); +var + bo1: boolean; +begin + bo1:= false; + if arecordnum >= 0 then begin + with tlbdropdownlistcontroller(fdropdown) do begin + text:= flookupbuffer.textvaluephys(cols[0].ffieldno,arecordnum); + tdropdowncols1(fcols).fitemindex:= + flookupbuffer.integervaluephys(fkeyfieldno,arecordnum); + end; + bo1:= checkvalue; + end + else begin + if arecordnum = -2 then begin + bo1:= checkvalue; + end + else begin + feditor.undo; + end; + end; + if bo1 and (akey = key_tab) then begin + window.postkeyevent(akey); + end; +end; + +function tdbenumeditlb.internaldatatotext(const data): msestring; +var + int1,int2,int3,int4: integer; +begin + if @data = nil then begin + int1:= value; + end + else begin + int1:= integer(data); + end; + with tlbdropdownlistcontroller(fdropdown) do begin + int3:= cols[valuecol].ffieldno; + int4:= fkeyfieldno; + end; + with dropdown do begin + if (flookupbuffer <> nil) and (int3 < flookupbuffer.fieldcounttext) and + (int4 < flookupbuffer.fieldcountinteger) and + flookupbuffer.find(int4,int1,int2) then begin + result:= flookupbuffer.textvaluephys(int3, + flookupbuffer.integerindex(int4,int2)); + end + else begin + result:= ''; + end; + end; +end; + +function tdbenumeditlb.getlbkeydatakind: lbdatakindty; +begin + result:= lbdk_integer; +end; + +{ tenumeditlb } + +function tenumeditlb.getdropdown: tlbdropdownlistcontroller; +begin + result:= tlbdropdownlistcontroller(fdropdown); +end; + +procedure tenumeditlb.setdropdown(const avalue: tlbdropdownlistcontroller); +begin + fdropdown.assign(avalue); +end; + +function tenumeditlb.createdropdowncontroller: tcustomdropdowncontroller; +begin + result:= tlbdropdownlistcontroller.create(ilbdropdownlist(self)); +end; + +procedure tenumeditlb.recordselected(const arecordnum: integer; const akey: keyty); +var + bo1: boolean; +begin + bo1:= false; + if arecordnum >= 0 then begin + with tlbdropdownlistcontroller(fdropdown) do begin + text:= flookupbuffer.textvaluephys(cols[0].ffieldno,arecordnum); + tdropdowncols1(fcols).fitemindex:= + flookupbuffer.integervaluephys(fkeyfieldno,arecordnum); + end; + bo1:= checkvalue; + end + else begin + if arecordnum = -2 then begin //empty row selected + bo1:= checkvalue; + end + else begin + feditor.undo; + end; + end; + if bo1 and (akey = key_tab) then begin + window.postkeyevent(akey); + end; +end; + +function tenumeditlb.internaldatatotext(const data): msestring; +var + int1,int2,int3,int4: integer; +begin + if @data = nil then begin + int1:= value; + end + else begin + int1:= integer(data); + end; + with tlbdropdownlistcontroller(fdropdown) do begin + int3:= cols[valuecol].ffieldno; + int4:= fkeyfieldno; + end; + with dropdown do begin + if (flookupbuffer <> nil) and (int3 < flookupbuffer.fieldcounttext) and + (int4 < flookupbuffer.fieldcountinteger) and + flookupbuffer.find(int4,int1,int2) then begin + result:= flookupbuffer.textvaluephys(int3, + flookupbuffer.integerindex(int4,int2)); + end + else begin + result:= ''; + end; + end; +end; + +function tenumeditlb.getlbkeydatakind: lbdatakindty; +begin + result:= lbdk_integer; +end; + +{$ifdef mse_with_ifi} +function tenumeditlb.getifilink: tifiintegerlinkcomp; +begin + result:= tifiintegerlinkcomp(fifilink); +end; + +procedure tenumeditlb.setifilink1(const avalue: tifiintegerlinkcomp); +begin + setifilink0(avalue); +end; +{$endif mse_with_ifi} + +{ tcustomenum64edit } + +constructor tcustomenum64edit.create(aowner: tcomponent); +begin + fvalue1:= -1; + fvaluedefault1:= -1; + inherited; +end; + +function tcustomenum64edit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= tgridenum64datalist.create(sender); +end; + +function tcustomenum64edit.getdatalistclass: datalistclassty; +begin + result:= tgridenum64datalist; +end; + +function tcustomenum64edit.getgridvalue(const index: integer): int64; +begin + internalgetgridvalue(index,result); +end; + +procedure tcustomenum64edit.setgridvalue(const index: integer; aValue: int64); +begin + internalsetgridvalue(index,avalue); +end; + +function tcustomenum64edit.getgridvalues: int64arty; +begin + result:= tint64datalist(fgridintf.getcol.datalist).asarray; +end; + +procedure tcustomenum64edit.setgridvalues(const avalue: int64arty); +begin + tint64datalist(fgridintf.getcol.datalist).asarray:= avalue; +end; + +procedure tcustomenum64edit.setvalue(const avalue: int64); +begin +{$warnings off} + tdropdowncols1(tlbdropdownlistcontroller(fdropdown).cols).fkeyvalue64:= + avalue; +{$warnings on} + fvalue1:= avalue; + valuechanged; +end; + +function tcustomenum64edit.getdefaultvalue: pointer; +begin + result:= @fvaluedefault1; +end; + +procedure tcustomenum64edit.texttovalue(var accept: boolean; const quiet: boolean); +var + lint1: int64; +begin + if (tdropdownlistcontroller(fdropdown).itemindex < 0) and + (trim(text) = '') then begin + lint1:= valuedefault; + end + else begin +{$warnings off} + lint1:= tdropdowncols1(tlbdropdownlistcontroller(fdropdown).cols).fkeyvalue64; +{$warnings on} + end; + //no checktext call + if accept then begin + if not quiet then begin + if canevent(tmethod(fonsetvalue1)) then begin + fonsetvalue1(self,lint1,accept); + end; +{$ifdef mse_with_ifi} + ifisetvalue(lint1,accept); +{$endif} + end; + if accept then begin + value:= lint1; + end; + end; +end; + +procedure tcustomenum64edit.texttodata(const atext: msestring; var data); +begin + //not supported +end; + +procedure tcustomenum64edit.valuetogrid(arow: integer); +begin + fgridintf.setdata(arow,fvalue1); +end; + +procedure tcustomenum64edit.gridtovalue(arow: integer); +begin + fgridintf.getdata(arow,fvalue1); + valuetotext; +end; + +procedure tcustomenum64edit.readstatvalue(const reader: tstatreader); +begin + if fgridintf <> nil then begin + fgridintf.getcol.dostatread(reader); + end + else begin + value:= reader.readint64(valuevarname,value); + end; +end; + +procedure tcustomenum64edit.writestatvalue(const writer: tstatwriter); +begin + writer.writeint64(valuevarname,value); +end; + +{$ifdef mse_with_ifi} +function tcustomenum64edit.getifilink: tifiint64linkcomp; +begin + result:= tifiint64linkcomp(fifilink); +end; + +procedure tcustomenum64edit.setifilink1(const avalue: tifiint64linkcomp); +begin + setifilink0(avalue); +end; + +function tcustomenum64edit.getifidatalinkintf: iifidatalink; +begin + result:= iifidatalink(self); +end; + +function tcustomenum64edit.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iifidatalink); +end; + +{$endif mse_with_ifi} + +procedure tcustomenum64edit.setnullvalue; +begin + dropdown.itemindex:= -1; + nullvalueset(); +end; + { tcustomenum64editlb } + +function tcustomenum64editlb.getdropdown: tlbdropdownlistcontroller; +begin + result:= tlbdropdownlistcontroller(fdropdown); +end; + +procedure tcustomenum64editlb.setdropdown(const avalue: tlbdropdownlistcontroller); +begin + fdropdown.assign(avalue); +end; + +function tcustomenum64editlb.createdropdowncontroller: tcustomdropdowncontroller; +begin + result:= tlbdropdownlistcontroller.create(ilbdropdownlist(self)); +end; + +procedure tcustomenum64editlb.recordselected(const arecordnum: integer; const akey: keyty); +var + bo1: boolean; +begin + bo1:= false; + if arecordnum >= 0 then begin + with tlbdropdownlistcontroller(fdropdown) do begin + text:= flookupbuffer.textvaluephys(cols[0].ffieldno,arecordnum); + tdropdowncols1(fcols).fkeyvalue64:= + flookupbuffer.int64valuephys(fkeyfieldno,arecordnum); + end; + bo1:= checkvalue; + end + else begin + if arecordnum = -2 then begin //empty row selected + bo1:= checkvalue; + end + else begin + feditor.undo; + end; + end; + if bo1 and (akey = key_tab) then begin + window.postkeyevent(akey); + end; +end; + +function tcustomenum64editlb.internaldatatotext(const data): msestring; +var + lint1: int64; + int2,int3,int4: integer; +begin + if @data = nil then begin + lint1:= value; + end + else begin + lint1:= int64(data); + end; + with tlbdropdownlistcontroller(fdropdown) do begin + int3:= cols[valuecol].ffieldno; + int4:= fkeyfieldno; + if (flookupbuffer <> nil) and (int3 < flookupbuffer.fieldcounttext) and + (int4 < flookupbuffer.fieldcountint64) and + flookupbuffer.find(int4,lint1,int2) then begin + result:= flookupbuffer.textvaluephys(int3, + flookupbuffer.int64index(int4,int2)); + end + else begin + result:= ''; + end; + end; +end; + +function tcustomenum64editlb.getlbkeydatakind: lbdatakindty; +begin + result:= lbdk_int64; +end; + + { tcustomenum64editdb } + +function tcustomenum64editdb.getdropdown: tdbdropdownlistcontroller; +begin + result:= tdbdropdownlistcontroller(fdropdown); +end; + +procedure tcustomenum64editdb.setdropdown(const avalue: tdbdropdownlistcontroller); +begin + fdropdown.assign(avalue); +end; + +function tcustomenum64editdb.createdropdowncontroller: tcustomdropdowncontroller; +begin + result:= tdbdropdownlistcontroller.create(idbdropdownlist(self),false); +end; + +procedure tcustomenum64editdb.recordselected( + const arecordnum: integer; const akey: keyty); +var + bo1: boolean; +begin + bo1:= false; + if arecordnum >= 0 then begin + with tdbdropdownlistcontroller(fdropdown) do begin + text:= getasmsestring(fdatalink.textfield,fdatalink.utf8); + tdropdowncols1(fcols).fkeyvalue64:= getaslargeint(fdatalink.valuefield) + end; + bo1:= checkvalue; + end + else begin + if arecordnum = -2 then begin + text:= ''; + bo1:= checkvalue; + end + else begin + feditor.undo; + end; + end; + if bo1 and (akey = key_tab) then begin + window.postkeyevent(akey); + end; +end; + +function tcustomenum64editdb.internaldatatotext(const data): msestring; +var + lint1: int64; +begin + if @data = nil then begin + lint1:= value; + end + else begin + lint1:= int64(data); + end; + result:= tdbdropdownlistcontroller(fdropdown).fdatalink.getlookuptext(lint1); +end; + +{ tdbenum64editlb } + +constructor tdbenum64editlb.create(aowner: tcomponent); +begin + fdatalink:= tlookupeditdatalink.create(self,ldt_int64,idbeditfieldlink(self)); + inherited; +end; + +destructor tdbenum64editlb.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tdbenum64editlb.modified; +begin + fdatalink.modified; + inherited; +end; + +procedure tdbenum64editlb.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; +{ +function tdbenum64editlb.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); +// frame.readonly:= oe_readonly in result; +end; +} +procedure tdbenum64editlb.valuetofield; +begin + if value = -1 then begin + fdatalink.field.clear; + if fdatalink.fieldtext <> nil then begin + fdatalink.fieldtext.clear; + end; + end + else begin + fdatalink.field.aslargeint:= value; + setasmsestring(text,fdatalink.fieldtext,fdatalink.utf8) + end; +end; + +procedure tdbenum64editlb.fieldtovalue; +begin + if fdatalink.field.isnull then begin + value:= fvaluedefault1; + end + else begin + value:= fdatalink.field.aslargeint; + end; +end; + +function tdbenum64editlb.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink). + getint64buffer(fdatalink.field,arow); + if result = nil then begin + result:= @fvaluedefault; + end; + end + else begin + result:= @fvaluedefault; + end; +end; + +function tdbenum64editlb.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdbenum64editlb.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdbenum64editlb.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +procedure tdbenum64editlb.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= integerfields; +end; + +procedure tdbenum64editlb.setdatalink(const avalue: tlookupeditdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbenum64editlb.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +function tdbenum64editlb.nullcheckneeded(const newfocus: twidget): boolean; +begin + result:= inherited nullcheckneeded(newfocus); + fdatalink.nullcheckneeded(result); +end; + +procedure tdbenum64editlb.recchanged; +begin + fdatalink.recordchanged(nil); +end; +{ +procedure tdbenum64editlb.dochange; +begin + fdatalink.datachanged; + inherited; +end; +} +function tdbenum64editlb.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; +{ +procedure tdbenum64editlb.doenter; +begin + fdatalink.doenter(self); + inherited; +end; + +procedure tdbenum64editlb.doexit; +begin + fdatalink.doexit(self); + inherited; +end; +} +{ tdbenum64editdb } + +constructor tdbenum64editdb.create(aowner: tcomponent); +begin + fdatalink:= tlookupeditdatalink.create(self,ldt_int64,idbeditfieldlink(self)); + inherited; +end; + +destructor tdbenum64editdb.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tdbenum64editdb.modified; +begin + fdatalink.modified; + inherited; +end; + +procedure tdbenum64editdb.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; +{ +function tdbenum64editdb.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + fdatalink.updateoptionsedit(result); +// frame.readonly:= oe_readonly in result; +end; +} +procedure tdbenum64editdb.valuetofield; +begin + if value = -1 then begin + fdatalink.field.clear; + if fdatalink.fieldtext <> nil then begin + fdatalink.fieldtext.clear; + end; + end + else begin + fdatalink.field.aslargeint:= value; + setasmsestring(text,fdatalink.fieldtext,fdatalink.utf8) + end; +end; + +procedure tdbenum64editdb.fieldtovalue; +begin + if fdatalink.field.isnull then begin + value:= fvaluedefault1; + end + else begin + value:= fdatalink.field.aslargeint; + end; +end; + +function tdbenum64editdb.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= tgriddatalink(fgriddatalink). + getint64buffer(fdatalink.field,arow); + if result = nil then begin + result:= @fvaluedefault; + end; + end + else begin + result:= @fvaluedefault; + end; +end; + +function tdbenum64editdb.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdbenum64editdb.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdbenum64editdb.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +procedure tdbenum64editdb.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= integerfields; +end; + +procedure tdbenum64editdb.setdatalink(const avalue: tlookupeditdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbenum64editdb.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +function tdbenum64editdb.nullcheckneeded(const newfocus: twidget): boolean; +begin + result:= inherited nullcheckneeded(newfocus); + fdatalink.nullcheckneeded(result); +end; + +procedure tdbenum64editdb.recchanged; +begin + fdatalink.recordchanged(nil); +end; +{ +procedure tdbenum64editdb.dochange; +begin + fdatalink.datachanged; + inherited; +end; +} +function tdbenum64editdb.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; +{ +procedure tdbenum64editdb.doenter; +begin + fdatalink.doenter(self); + inherited; +end; + +procedure tdbenum64editdb.doexit; +begin + fdatalink.doexit(self); + inherited; +end; +} +{ tdbkeystringeditlb } + +function tdbkeystringeditlb.getdropdown: tlbdropdownlistcontroller; +begin + result:= tlbdropdownlistcontroller(fdropdown); +end; + +procedure tdbkeystringeditlb.setdropdown(const avalue: tlbdropdownlistcontroller); +begin + fdropdown.assign(avalue); +end; + +function tdbkeystringeditlb.createdropdowncontroller: tcustomdropdowncontroller; +begin + result:= tlbdropdownlistcontroller.create(ilbdropdownlist(self)); +end; + +procedure tdbkeystringeditlb.recordselected(const arecordnum: integer; + const akey: keyty); +var + bo1: boolean; +begin + bo1:= false; + if arecordnum >= 0 then begin + with tlbdropdownlistcontroller(fdropdown) do begin + text:= flookupbuffer.textvaluephys(cols[0].ffieldno,arecordnum); + tdropdowncols1(fcols).fitemindex:= arecordnum; + tdropdowncols1(fcols).fkeyvalue:= + flookupbuffer.textvaluephys(fkeyfieldno,arecordnum); + end; + bo1:= checkvalue; + end + else begin + if arecordnum = -2 then begin + bo1:= checkvalue; + end + else begin + feditor.undo; + end; + end; + if bo1 and (akey = key_tab) then begin + window.postkeyevent(akey); + end; +end; + +function tdbkeystringeditlb.internaldatatotext(const data): msestring; +var + mstr1: msestring; + int2,int3,int4: integer; +begin + if @data = nil then begin + mstr1:= value; + end + else begin + mstr1:= msestring(data); + end; + with tlbdropdownlistcontroller(fdropdown) do begin + int3:= cols[valuecol].ffieldno; + int4:= fkeyfieldno; + end; + with dropdown do begin + if (flookupbuffer <> nil) and (int3 < flookupbuffer.fieldcounttext) and + (int4 < flookupbuffer.fieldcounttext) and + flookupbuffer.find(int4,mstr1,int2,false) then begin + result:= flookupbuffer.textvaluephys(int3, + flookupbuffer.textindex(int4,int2,false)); + end + else begin + result:= ''; + end; + end; +end; + +function tdbkeystringeditlb.getlbkeydatakind: lbdatakindty; +begin + result:= lbdk_text; +end; + +{ tkeystringeditlb } + +function tkeystringeditlb.getdropdown: tlbdropdownlistcontroller; +begin + result:= tlbdropdownlistcontroller(fdropdown); +end; + +procedure tkeystringeditlb.setdropdown(const avalue: tlbdropdownlistcontroller); +begin + fdropdown.assign(avalue); +end; + +function tkeystringeditlb.createdropdowncontroller: tcustomdropdowncontroller; +begin + result:= tlbdropdownlistcontroller.create(ilbdropdownlist(self)); +end; + +procedure tkeystringeditlb.recordselected(const arecordnum: integer; + const akey: keyty); +var + bo1: boolean; +begin + bo1:= false; + if arecordnum >= 0 then begin + with tlbdropdownlistcontroller(fdropdown) do begin + text:= flookupbuffer.textvaluephys(cols[0].ffieldno,arecordnum); + tdropdowncols1(fcols).fitemindex:= arecordnum; + tdropdowncols1(fcols).fkeyvalue:= + flookupbuffer.textvaluephys(fkeyfieldno,arecordnum); + end; + bo1:= checkvalue; + end + else begin + if arecordnum = -2 then begin + bo1:= checkvalue; + end + else begin + feditor.undo; + end; + end; + if bo1 and (akey = key_tab) then begin + window.postkeyevent(akey); + end; +end; + +function tkeystringeditlb.internaldatatotext(const data): msestring; +var + mstr1: msestring; + int2,int3,int4: integer; +begin + if @data = nil then begin + mstr1:= value; + end + else begin + mstr1:= msestring(data); + end; + with tlbdropdownlistcontroller(fdropdown) do begin + int3:= cols[valuecol].ffieldno; + int4:= fkeyfieldno; + end; + with dropdown do begin + if (flookupbuffer <> nil) and (int3 < flookupbuffer.fieldcounttext) and + (int4 < flookupbuffer.fieldcounttext) and + flookupbuffer.find(int4,mstr1,int2,false) then begin + result:= flookupbuffer.textvaluephys(int3, + flookupbuffer.textindex(int4,int2,false)); + end + else begin + result:= ''; + end; + end; +end; + +function tkeystringeditlb.getlbkeydatakind: lbdatakindty; +begin + result:= lbdk_text; +end; + +{ tcopydropdownlist } + +function tcopydropdownlist.locate(const filter: msestring): boolean; +var + int1: integer; + po1: pointer; + co1: gridcoordty; +begin + po1:= cols[0].datalist.datapo; //workaround internal error 200304235 in 2.0.2 + result:= findarrayvalue(filter,po1,sizeof(msestring),rowcount, + @compareimsestring,int1); + if not result then begin + result:= (int1 < rowcount) and (msecomparetextlen(filter,cols[0][int1]) = 0); + end; + if not result then begin + inc(int1); + result:= (int1 < rowcount) and (msecomparetextlen(filter,cols[0][int1]) = 0); + end; + if result then begin + co1:= makegridcoord(ffocusedcell.col,int1); + showcell(co1,cep_top); + focuscell(makegridcoord(ffocusedcell.col,int1)); + end + else begin + focuscell(makegridcoord(ffocusedcell.col,-1)); + end; +end; + +{ tlbdropdownstringcol } + +function tlbdropdownstringcol.getrowtext(const arow: integer): msestring; +var + int1: integer; +begin + int1:= tlbdropdownlist(fcellinfo.grid).getrecno(arow); + if int1 >= 0 then begin + if funsorted then begin + result:= flookupbuffer.textvaluephys(ffieldno,int1); + end + else begin + result:= flookupbuffer.textvaluephys(ffieldno, + flookupbuffer.textindex(fsortfieldno,int1,true)); + end; + end + else begin + result:= ''; + end; +end; + +{ texterndatadropdownlist } + +constructor texterndatadropdownlist.create( + const acontroller: texterndatadropdownlistcontroller; acols: tdropdowncols); +var + int1: integer; +begin + inherited create(acontroller,acols,nil); + include(fstate,gs_isdb); + int1:= acontroller.dropdownrowcount; + if (edds_filtered in feddstate) then begin + resyncfilter; + end + else begin + if int1 > acontroller.getremoterowcount then begin + int1:= acontroller.getremoterowcount; + frame.sbvert.options:= frame.sbvert.options-[sbo_show]; + end; + rowcount:= int1; + end; + if rowcount > 0 then begin + row:= 0; + end; + with frame.sbvert do begin + buttonlength:= 0; + if acontroller.getremoterowcount > 0 then begin + pagesize:= rowcount / acontroller.getremoterowcount; + end; + end; +end; + +procedure texterndatadropdownlist.resyncfilter; +var + int1,int2,int3: integer; +begin + int1:= fcontroller.dropdownrowcount; + rowcount:= int1; //init frecnums; + int3:= -1; + for int2:= 0 to rowcount - 1 do begin + findnext(int3); + if int3 < 0 then begin + int1:= int2; + break; + end; + frecnums[int2]:= int3; + end; + ffirstrecord:= frecnums[0]; + if int3 < 0 then begin + frame.sbvert.options:= frame.sbvert.options-[sbo_show]; + rowcount:= int1; + end + else begin + frame.sbvert.options:= frame.sbvert.options+[sbo_show]; + end; +end; + +procedure texterndatadropdownlist.filterchanged; +begin + if (edds_filtered in feddstate) then begin + resyncfilter; + end; +end; + +procedure texterndatadropdownlist.dbscrolled(distance: integer); +var + rect1: rectty; +// int1: integer; +begin + if abs(distance) >= rowcount then begin + invalidate; + end + else begin + if distance <> 0 then begin + rect1:= fdatarecty; + rect1.cy:= rowcount*ystep; + scrollrect(makepoint(0,-distance*ystep),rect1,true); + end; + end; +end; + +procedure texterndatadropdownlist.moveby(distance: integer); +var + int1,int2,int3,int4,int5,int6: integer; + rowbefore: integer; + rea1: real; + ar1: integerarty; +begin + if rowcount = 0 then begin + exit; + end; + rowbefore:= row; + int1:= row + distance; + if int1 < 0 then begin + if (edds_filtered in feddstate) then begin + setlength(ar1,rowcount); + int4:= 0; + for int3:= -int1-1 downto 0 do begin + int2:= ffirstrecord; + findprev(ffirstrecord); + if ffirstrecord < 0 then begin + ffirstrecord:= int2; + break; + end; + if int3 <= high(ar1) then begin + ar1[int3]:= ffirstrecord; + end; + dec(int4); + end; + if int4 <> int1 then begin + include(feddstate,edds_bof); + int2:= ffirstrecord; + frecnums[0]:= int2; + for int3:= 1 to rowhigh do begin + findnext(int2); + if int2 < 0 then begin + for int6:= int3 to high(frecnums) do begin + frecnums[int6]:= -1; + end; + break; + end; + frecnums[int3]:= int2; + end; + end + else begin + exclude(feddstate,edds_bof); + if int4 <= - rowcount then begin + frecnums:= ar1; + end + else begin + move(frecnums[0],frecnums[-int4],(length(frecnums)+int4)*sizeof(integer)); + move(ar1[int1-int4],frecnums[0],-int4*sizeof(integer)); + end; + end; + int1:= int4; + end + else begin + ffirstrecord:= ffirstrecord + int1; + if ffirstrecord < 0 then begin + int1:= int1 - ffirstrecord; + ffirstrecord:= 0; + end; + end; + dbscrolled(int1); + dec(rowbefore,int1); + row:= 0; + end + else begin + if int1 >= rowcount then begin + int1:= int1 - rowcount + 1; + if (edds_filtered in feddstate) then begin + setlength(ar1,rowcount); + int5:= frecnums[rowcount-1]; + int4:= 0; + for int3:= 0 to int1-1 do begin + int2:= int5; + findnext(int5); + if int5 < 0 then begin + int5:= int2; + break; + end; + inc(int4); + int6:= int1 - int4; + if int6 <= high(ar1) then begin + ar1[high(ar1)-int6]:= int5; + end; + end; + if int4 <> int1 then begin + include(feddstate,edds_eof); + frecnums[rowhigh]:= int5; + for int3:= rowhigh - 1 downto 0 do begin + findprev(int5); + if int5 < 0 then begin + for int6:= int3 downto 0 do begin + frecnums[int6]:= -1; + end; + break; + end; + frecnums[int3]:= int5; + end; + end + else begin + exclude(feddstate,edds_eof); + if int4 >= rowcount then begin + frecnums:= ar1; + end + else begin + move(frecnums[int4],frecnums[0],(rowcount-int4)*sizeof(integer)); + move(ar1[rowcount-int1],frecnums[rowcount-int4],int4*sizeof(integer)); + end; + end; + ffirstrecord:= frecnums[0]; + int1:= int4; + end + else begin + ffirstrecord:= ffirstrecord + int1; + int2:= ffirstrecord + rowcount - + texterndatadropdownlistcontroller(fcontroller).getremoterowcount; + if int2 > 0 then begin + int1:= int1 - int2; + ffirstrecord:= ffirstrecord - int2; + end; + end; + dbscrolled(int1); + dec(rowbefore,int1); + row:= rowcount - 1; + end + else begin + row:= row + distance; + end; + end; + invalidaterow(rowbefore); + invalidaterow(row); + if (col >= 0) and (row >= 0) then begin + feditor.text:= tlbdropdownstringcol(fdatacols[col]).getrowtext(row); + end + else begin + feditor.text:= ''; + end; + int1:= texterndatadropdownlistcontroller(fcontroller).getremoterowcount - 1; + if int1 <= 0 then begin + rea1:= 0.5; + end + else begin + if (edds_filtered in feddstate) then begin + if edds_eof in feddstate then begin + rea1:= 1; + end + else begin + if edds_bof in feddstate then begin + rea1:= 0; + end + else begin + rea1:= 0.5; + end; + end; + end + else begin + rea1:= activerecord / int1; + end; + end; + frame.sbvert.value:= rea1; +end; + +procedure texterndatadropdownlist.pagedown(const action: focuscellactionty = fca_focusin); +begin + moveby(rowcount-1); +end; + +procedure texterndatadropdownlist.pageup(const action: focuscellactionty = fca_focusin); +begin + moveby(-rowcount+1); +end; + +procedure texterndatadropdownlist.wheeldown(const action: focuscellactionty = fca_focusin); +begin + MoveBy(wheelheight); +end; + +procedure texterndatadropdownlist.wheelup(const action: focuscellactionty = fca_focusin); +begin + MoveBy(-wheelheight); +end; + +procedure texterndatadropdownlist.rowdown( + const action: focuscellactionty = fca_focusin; const nowrap: boolean = false); +begin + moveby(1); +end; + +procedure texterndatadropdownlist.rowup( + const action: focuscellactionty = fca_focusin; const nowrap: boolean = false); +begin + moveby(-1); +end; + +function texterndatadropdownlist.getactiverecord: integer; +begin + if (edds_filtered in feddstate) then begin + result:= frecnums[row]; + end + else begin + result:= ffirstrecord + row; + end; +end; + +procedure texterndatadropdownlist.setactiverecord(const avalue: integer); +var + int1,int2,int3: integer; +begin + if rowcount > 0 then begin + if (edds_filtered in feddstate) then begin + if ffirstrecord >= 0 then begin + for int1:= 0 to high(frecnums) do begin + if frecnums[int1] = avalue then begin + if int1 > 0 then begin + exclude(feddstate,edds_bof); + end; + if int1 < rowhigh then begin + exclude(feddstate,edds_eof); + end; + moveby(int1-row); + exit; + end; + end; + end; + ffirstrecord:= avalue; + int2:= avalue; + frecnums[0]:= int2; + for int1:= 1 to rowhigh do begin + findnext(int2); + if int2 < 0 then begin + move(frecnums[0],frecnums[rowcount-int1],int1*sizeof(integer)); + int2:= avalue; + for int3:= rowhigh - int1 downto 0 do begin + findprev(int2); + frecnums[int3]:= int2; + end; + ffirstrecord:= frecnums[0]; + invalidate; + moveby((rowcount - int1)-row); + exit; + end; + frecnums[int1]:= int2 + end; + invalidate; + moveby(-row); + end + else begin + if ffirstrecord < 0 then begin + ffirstrecord:= avalue; + int1:= texterndatadropdownlistcontroller(fcontroller).getremoterowcount; + if ffirstrecord + rowcount > int1 then begin + ffirstrecord:= int1 - rowcount; + end; + moveby(avalue-ffirstrecord-row); + invalidate; + end + else begin + moveby(avalue-activerecord); + end; + end; + end; +end; + +procedure texterndatadropdownlist.internalcreateframe; +begin + tdbgridframe.create(iscrollframe(self),self,iautoscrollframe(self)); +end; + +procedure texterndatadropdownlist.createdatacol(const index: integer; + out item: tdatacol); +begin + item:= tlbdropdownstringcol.create(self,fdatacols); +end; + +procedure texterndatadropdownlist.docellevent(var info: celleventinfoty); +begin + inherited; + with info do begin + if (eventkind = cek_enter) and active then begin + if (edds_filtered in feddstate) then begin + activerecord:= frecnums[newcell.row]; + end + else begin + activerecord:= ffirstrecord + newcell.row; + end; + end; + end; +end; + +procedure texterndatadropdownlist.scrollevent(sender: tcustomscrollbar; event: scrolleventty); +var + int1: integer; + bo1: boolean; +begin + bo1:= true; + if sender.tag = 1 then begin + case event of + sbe_stepup: rowdown(fca_focusin); + sbe_stepdown: rowup(fca_focusin); + sbe_pageup: pagedown(fca_focusin); + sbe_pagedown: pageup(fca_focusin); + sbe_wheelup: wheeldown(fca_focusin); + sbe_wheeldown: wheelup(fca_focusin); + sbe_valuechanged: begin end; + sbe_thumbtrack,sbe_thumbposition: begin + int1:= texterndatadropdownlistcontroller(fcontroller).getremoterowcount - 1; + if int1 >= 0 then begin + if (edds_filtered in feddstate) then begin + if event <> sbe_thumbtrack then begin + if sender.value <= 0 then begin + moveby(minint); + end + else begin + if sender. value >= 1 then begin + moveby(maxint); + end + else begin + if sender.value < 0.5 then begin + moveby(-rowhigh); + end + else begin + moveby(rowhigh); + end; + end; + end; + end; + end + else begin + activerecord:= round(int1 * sender.value); + end; + end + else begin + sender.value:= 0.5; + end; + end; + else begin + bo1:= false; + end; + end; + end + else begin + bo1:= false; + end; + if not bo1 then begin + inherited; + end; +end; + +procedure texterndatadropdownlist.dorowcountchanged(const countbefore: integer; + const newcount: integer); +var + int1: integer; +begin + inherited; + setlength(frecnums,newcount); + for int1:= countbefore to newcount - 1 do begin + frecnums[int1]:= -1; + end; +end; + +procedure texterndatadropdownlist.findprev(var recno: integer); +var + bo1: boolean; +begin + with texterndatadropdownlistcontroller(fcontroller) do begin + repeat + dec(recno); + if recno < 0 then begin + recno:= -1; + break; + end; + bo1:= true; + dofilter(recno,bo1); + until bo1; + end; +end; + +function texterndatadropdownlist.getrecno(const aindex: integer): integer; +//var +// int1{,int2}: integer; +begin + if (edds_filtered in feddstate) then begin + result:= frecnums[aindex]; + end + else begin + result:= ffirstrecord + aindex; + end; +end; + +procedure texterndatadropdownlist.dokeydown(var info: keyeventinfoty); +begin + with info do begin + if shiftstate = [ss_ctrl] then begin + include(info.eventstate,es_processed); + case key of + key_pageup: begin + moveby(-bigint); + end; + key_pagedown: begin + moveby(bigint); + end + else begin + exclude(eventstate,es_processed); + end; + end; + end; + if not (es_processed in eventstate) then begin + inherited; + end; + end; +end; + +{ tlbdropdownlist } + +constructor tlbdropdownlist.create( + const acontroller: tcustomlbdropdownlistcontroller; acols: tdropdowncols); +begin + if assigned(acontroller.fonfilter) then begin + include(feddstate,edds_filtered); + end; + inherited create(acontroller,acols); +end; + +procedure tlbdropdownlist.initcols(const acols: tdropdowncols); +var + int1: integer; + lookupbuffer1: tcustomlookupbuffer; +begin + inherited; + with tcustomlbdropdownlistcontroller(fcontroller) do begin + lookupbuffer1:= lookupbuffer; + fsortfieldno:= cols[0].ffieldno; + end; + for int1:= 0 to fdatacols.count - 1 do begin + with tlbdropdownstringcol(fdatacols[int1]) do begin + flookupbuffer:= lookupbuffer1; + fsortfieldno:= tcustomlbdropdownlistcontroller(fcontroller).fsortfieldno; + ffieldno:= tlbdropdowncol(acols[int1]).ffieldno; + funsorted:= olb_unsorted in + tlbdropdownlistcontroller(fcontroller).foptionslb; + end; + end; +end; + +function tlbdropdownlist.locate(const filter: msestring): boolean; +var + int1: integer; +begin + int1:= 0; + result:= false; + if (datacols.count > 0) then begin + with tlbdropdownstringcol(datacols[0]) do begin + result:= flookupbuffer.find(ffieldno,filter,int1,true, + tcustomlbdropdownlistcontroller(fcontroller).fonfilter); + if not result then begin + result:= (int1 < flookupbuffer.count) and + (msepartialcomparetext(filter, + flookupbuffer.textvaluelog(ffieldno,int1,true)) = 0); + end; + if funsorted then begin + int1:= flookupbuffer.textindex(ffieldno,int1,true); //get phys recno + end; + end; + end; + if not result then begin + focuscell(makegridcoord(ffocusedcell.col,-1)); + end + else begin + ffirstrecord:= -1; + activerecord:= int1; + end; +end; + +procedure tlbdropdownlist.findnext(var recno: integer); +var + bo1: boolean; +begin + with tcustomlbdropdownlistcontroller(fcontroller) do begin + repeat + inc(recno); + if recno >= flookupbuffer.count then begin + recno:= -1; + break; + end; + bo1:= true; + dofilter(recno,bo1); + until bo1; + end; +end; + +{ tcustomlbdropdownlistcontroller } + +function tcustomlbdropdownlistcontroller.getcols: tlbdropdowncols; +begin + result:= tlbdropdowncols(fcols); +end; + +procedure tcustomlbdropdownlistcontroller.setcols(const avalue: tlbdropdowncols); +begin + fcols.assign(avalue); +end; + +procedure tcustomlbdropdownlistcontroller.dofilter(var recno: integer; + var accept: boolean); +begin + fonfilter(flookupbuffer,flookupbuffer.textindex(fsortfieldno,recno,true),accept); +end; + +function tcustomlbdropdownlistcontroller.reloadlist: integer; +var + int1,int2,int3,int4: integer; + sortfieldno: integer; + bo1: boolean; + po1: pmsestringaty; + ar1: msestringarty; +begin + result:= 0; + if assigned(fonbeforefilter) then begin + fonbeforefilter(tcustomdataedit(fintf.getwidget)); + end; + if olb_copyitems in foptionslb then begin + flookupbuffer.checkbuffer; //possibly load buffer + sortfieldno:= cols[0].fieldno; + setlength(fedrecnums,flookupbuffer.count); + if assigned(fonfilter) then begin + int3:= 0; + for int1:= 0 to high(fedrecnums) do begin + if olb_unsorted in foptionslb then begin + int4:= int1; + end + else begin + int4:= flookupbuffer.textindex(sortfieldno,int1,true); + end; + bo1:= true; + fonfilter(flookupbuffer,int4,bo1); + if bo1 then begin + fedrecnums[int3]:= int4; + inc(int3); + end; + end; + setlength(fedrecnums,int3); + end + else begin + if olb_unsorted in foptionslb then begin + setlength(fedrecnums,flookupbuffer.count); + for int1:= 0 to high(fedrecnums) do begin + fedrecnums[int1]:= int1; + end; + end + else begin + fedrecnums:= flookupbuffer.textindexar(sortfieldno,true); + end; + end; + for int1:= 0 to fcols.count - 1 do begin + with cols[int1] do begin + count:= length(fedrecnums); + int2:= fieldno; + po1:= datapo; + ar1:= flookupbuffer.textar(int2); + for int3:= 0 to high(fedrecnums) do begin + po1^[int3]:= ar1[fedrecnums[int3]]; + end; + end; + end; + end + else begin + tlbdropdownlist(fdropdownlist).filterchanged; + end; +end; + +function tcustomlbdropdownlistcontroller.createdropdownlist: tdropdownlist; +begin + if olb_copyitems in foptionslb then begin + reloadlist; + if olb_unsorted in foptionslb then begin + result:= tdropdownlist.create(self,fcols,nil); //normal locate + end + else begin + result:= tcopydropdownlist.create(self,fcols,nil); + end; + end + else begin + result:= tlbdropdownlist.create(self,fcols); + end; +end; + +function tcustomlbdropdownlistcontroller.candropdown: boolean; +begin + result:= (flookupbuffer <> nil) and (flookupbuffer.count > 0) and + (fcols.count > 0) and inherited candropdown; +end; + +procedure tcustomlbdropdownlistcontroller.itemselected(const index: integer; + const akey: keyty); +var + int1: integer; +begin + int1:= index; + if index < 0 then begin + if index = -2 then begin + tdropdowncols1(fcols).fitemindex:= fintf.getvalueempty; + end; + end + else begin + if olb_copyitems in foptionslb then begin + int1:= fedrecnums[int1]; + cols.clear; + fedrecnums:= nil; + end + else begin + int1:= tlbdropdownlist(fdropdownlist).getrecno(index); + if not (olb_unsorted in foptionslb) then begin + int1:= flookupbuffer.textindex(cols[0].fieldno,int1,true) + end; + end; + tdropdowncols1(fcols).fitemindex:= int1; + end; + ilbdropdownlist(fintf).recordselected(int1,akey); + if olb_copyitems in foptionslb then begin + cols.clear; + fedrecnums:= nil; + end; +// ilbdropdownlist(fintf).recordselected(int1,akey); +end; + +function tcustomlbdropdownlistcontroller.getremoterowcount: integer; +begin + result:= flookupbuffer.count; +end; + +procedure tcustomlbdropdownlistcontroller.setlookupbuffer( + const avalue: tcustomlookupbuffer); +begin + setlinkedvar(avalue,tmsecomponent(flookupbuffer)); +end; + +procedure tcustomlbdropdownlistcontroller.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (event in [oe_changed,oe_connect]) and (sender = flookupbuffer) + and not (csloading in flookupbuffer.componentstate) then begin + with tdataedit1(fintf.getwidget) do begin + if fgridintf <> nil then begin + fgridintf.getcol.changed; + {$ifdef FPC} {$checkpointer off} {$endif} + feditor.text:= datatotext(nil^); + {$ifdef FPC} {$checkpointer default} {$endif} + end + else begin + {$ifdef FPC} {$checkpointer off} {$endif} + feditor.text:= datatotext(nil^); + {$ifdef FPC} {$checkpointer default} {$endif} + end; + end; + updatereadonlystate; + end; +end; + +function tcustomlbdropdownlistcontroller.getlbdatakind(const apropname: string): lbdatakindty; +begin + result:= ilbdropdownlist(fintf).getlbkeydatakind; +end; + +function tcustomlbdropdownlistcontroller.getlookupbuffer: tcustomlookupbuffer; +begin + result:= flookupbuffer; +end; + +{ tlookupeditdatalink } + +constructor tlookupeditdatalink.create(const aowner: tcustomdataedit; + const adatatype: lookupdatatypety; const intf: idbeditfieldlink); +begin + inherited create(intf); + fowner:= aowner; + fdatatype:= adatatype; +end; + +function tlookupeditdatalink.msedisplaytext(const aformat: msestring = ''; + const aedit: boolean = false): msestring; +var + i1: int32; + li1: int64; + s1: msestring; +begin + if fowner <> nil then begin + result:= ''; + if (field <> nil) and not field.isnull then begin + case fdatatype of + ldt_int32: begin + i1:= field.asinteger; + result:= tcustomdataedit1(fowner).internaldatatotext(i1); + end; + ldt_int64: begin + li1:= field.aslargeint; + result:= tcustomdataedit1(fowner).internaldatatotext(li1); + end; + ldt_string: begin + s1:= field.asunicodestring; + result:= tcustomdataedit1(fowner).internaldatatotext(s1); + end; + end; + end; + end + else begin + result:= inherited msedisplaytext(aformat,aedit); + end; +end; + +procedure tlookupeditdatalink.setfieldnametext(const avalue: string); +begin + if ffieldnametext <> avalue then begin + ffieldnametext := avalue; + updatefields; + end; +end; + +procedure tlookupeditdatalink.updatefields; +begin + if active and (ffieldnametext <> '') then begin + ffieldtext:= datasource.dataset.fieldbyname(ffieldnametext); + end + else begin + ffieldtext:= nil; + end; + inherited; +end; + +procedure tlookupeditdatalink.getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); +begin + inherited; + setlength(apropertynames,2); + apropertynames[0]:= 'fieldname'; + apropertynames[1]:= 'fieldnametext'; + setlength(afieldtypes,2); + afieldtypes[1]:= textfields; +end; + +function tlookupeditdatalink.getsortfield: tfield; +begin + if ffieldtext = nil then begin + updatefields; + end; + result:= ffieldtext; + if result = nil then begin + result:= inherited getsortfield; + end; +end; + +{ tdbnavigbutton } + +procedure tdbnavigbutton.readtag(reader: treader); +begin + reader.readinteger; //dummy +end; + +procedure tdbnavigbutton.defineproperties(filer: tfiler); +begin + inherited; //backward compatibility + filer.defineproperty('tag',{$ifdef FPC}@{$endif}readtag,nil,false); +end; + +{ tdbwidgetcols } + +class function tdbwidgetcols.getitemclasstype: persistentclassty; +begin + result:= tdbwidgetcol; +end; + +function tdbwidgetcols.getcols(const index: integer): tdbwidgetcol; +begin + result:= tdbwidgetcol(items[index]); +end; + +{ tdbwidgetcol } + +procedure tdbwidgetcol.setwidget(const awidget: twidget); +var + intf1: idbeditfieldlink; + intf2: idbdispfieldlink; +begin + inherited; + if (awidget <> nil) then begin + if awidget.getcorbainterface(typeinfo(idbeditfieldlink),intf1) then begin + fdatalink:= intf1.getfieldlink(); + if fdatalink <> nil then begin + tcustomeditwidgetdatalink(fdatalink).navigator:= + tdbwidgetgrid(fcellinfo.grid).fdatalink.navigator; + end; + end + else begin + if awidget.getcorbainterface(typeinfo(idbdispfieldlink),intf2) then begin + fdatalink:= intf2.getfieldlink(); + end; + end; + end + else begin + fdatalink:= nil; + end; +end; + +procedure tdbwidgetcol.dobeforedrawcell(const acanvas: tcanvas; + var processed: boolean); +var + info: gridrowinfoty; +begin + tcustomdbwidgetgrid(grid).fdatalink.begingridrow( + fcellinfo.cell.row,info); + try + inherited; + finally + tcustomdbwidgetgrid(grid).fdatalink.endgridrow(info); + end; +end; + +procedure tdbwidgetcol.doafterdrawcell(const acanvas: tcanvas); +var + info: gridrowinfoty; +begin + tcustomdbwidgetgrid(grid).fdatalink.begingridrow( + fcellinfo.cell.row,info); + try + inherited; + finally + tcustomdbwidgetgrid(grid).fdatalink.endgridrow(info); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/db/msedbevents.pas b/mseide-msegui/lib/common/db/msedbevents.pas new file mode 100644 index 0000000..cfbbf58 --- /dev/null +++ b/mseide-msegui/lib/common/db/msedbevents.pas @@ -0,0 +1,276 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msedbevents; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface +uses + classes,mclasses,msearrayprops,mseclasses,msqldb,mdb,mseglob,msetimer, + msedatabase,mseinterfaces; + +const + defaultdbeventinterval = 1000000; //us +type + tdbevent = class; + idbevent = interface(inullinterface)[miid_idbevent] + procedure listen(const sender: tdbevent); + procedure unlisten(const sender: tdbevent); + procedure fire(const sender: tdbevent); + end; + idbeventcontroller = interface(inullinterface) + function getdbevent(var aname: string; var aid: int64): boolean; + //false if none + procedure dolisten(const sender: tdbevent); + procedure dounlisten(const sender: tdbevent); + end; + + dbeventty = procedure(const sender: tdbevent; const aid: int64) of object; + + tdbevent = class(tmsecomponent) + private + feventname: string; + fonexecute: dbeventty; + flisten: boolean; + fdatabase: tmdatabase; + fintf: idbevent; + procedure seteventname(const avalue: string); + procedure setlisten(const avalue: boolean); + procedure setdatabase(const avalue: tmdatabase); + protected + procedure doexecute(const aid: int64); virtual; + procedure checkinactive; + procedure checkactive; + procedure loaded; override; + procedure notification(acomponent: tcomponent; operation: toperation); override; + public + destructor destroy; override; + procedure fire; + published + property database: tmdatabase read fdatabase write setdatabase; + property eventname: string read feventname write seteventname; + property listen: boolean read flisten write setlisten default false; + property onexecute: dbeventty read fonexecute write fonexecute; + end; + + dbeventarty = array of tdbevent; + + tdbeventcontroller = class + private + fintf: idbeventcontroller; + ftimer: tsimpletimer; + fevents: dbeventarty; + function geteventinterval: integer; + procedure seteventinterval(const avalue: integer); + protected + procedure dotimer(const sender: tobject); + public + constructor create(const aintf: idbeventcontroller); + destructor destroy; override; + procedure register(const sender: tdbevent); + procedure unregister(const sender: tdbevent); + procedure connect; + procedure disconnect; + procedure getevents; + property eventinterval: integer read geteventinterval write seteventinterval; + end; + +implementation +uses + msearrayutils,msetypes; + +{ tdbevent } + +destructor tdbevent.destroy; +begin + listen:= false; + inherited; +end; + +procedure tdbevent.checkinactive; +begin + if (fdatabase <> nil) and fdatabase.connected and listen then begin + databaseerror('Not inactive.',self); + end; +end; + +procedure tdbevent.checkactive; +begin + if fdatabase = nil then begin + databaseerror('Database not assigned.',self); + end; + if not fdatabase.connected then begin + databaseerror('Database not connected.',self); + end; +end; + +procedure tdbevent.seteventname(const avalue: string); +begin + if avalue <> feventname then begin + if componentstate*[csloading,csdesigning] = [] then begin + checkinactive; + end; + feventname:= avalue; + end; +end; + +procedure tdbevent.setlisten(const avalue: boolean); +begin + if avalue <> flisten then begin + if (componentstate * [csloading,csdesigning] = []) and (fdatabase <> nil) then begin + if eventname = '' then begin + databaseerror('No eventname.',self); + end; + if avalue then begin + fintf.listen(self); + end + else begin + fintf.unlisten(self); + end; + end; + flisten:= avalue; + end; +end; + +procedure tdbevent.setdatabase(const avalue: tmdatabase); +begin + if avalue <> nil then begin + if not mseclasses.getcorbainterface(avalue,typeinfo(idbevent),fintf) then begin + databaseerror('Invalid Database.',self); + end; + end; + if fdatabase <> nil then begin + fdatabase.removefreenotification(self); + end; + fdatabase:= avalue; + if fdatabase <> nil then begin + fdatabase.freenotification(self); + end; +end; + +procedure tdbevent.fire; +begin + checkactive; + fintf.fire(self); +end; + +procedure tdbevent.doexecute(const aid: int64); +begin + if canevent(tmethod(fonexecute)) then begin + fonexecute(self,aid); + end; +end; + +procedure tdbevent.loaded; +begin + inherited; + if flisten and not (csdesigning in componentstate) then begin + flisten:= false; + listen:= true; + end; +end; + +procedure tdbevent.notification(acomponent: tcomponent; operation: toperation); +begin + if (operation = opremove) and (acomponent = fdatabase) then begin + fdatabase:= nil; + fintf:= nil; + end; + inherited; +end; + +{ tdbeventcontroller } + +constructor tdbeventcontroller.create(const aintf: idbeventcontroller); +begin + fintf:= aintf; + ftimer:= tsimpletimer.create(defaultdbeventinterval, + {$ifdef FPC}@{$endif}dotimer,false,[]); + inherited create; +end; + +destructor tdbeventcontroller.destroy; +begin + ftimer.free; + inherited; +end; + +procedure tdbeventcontroller.register(const sender: tdbevent); +begin + if finditem(pointerarty(fevents),sender) < 0 then begin + additem(pointerarty(fevents),sender); + end; +end; + +procedure tdbeventcontroller.unregister(const sender: tdbevent); +begin + removeitem(pointerarty(fevents),sender); +end; + +procedure tdbeventcontroller.connect; +var + int1: integer; +begin + for int1:= 0 to high(fevents) do begin + fintf.dolisten(fevents[int1]); + end; + ftimer.enabled:= ftimer.interval <> 0; +end; + +procedure tdbeventcontroller.disconnect; +var + int1: integer; +begin + ftimer.enabled:= false; + for int1:= 0 to high(fevents) do begin + try + fintf.dounlisten(fevents[int1]); + except + end; + end; +end; + +procedure tdbeventcontroller.dotimer(const sender: tobject); +var + str1: string; + lint1: int64; + int1: integer; +begin + while fintf.getdbevent(str1,lint1) do begin + for int1:= 0 to high(fevents) do begin + if fevents[int1].eventname = str1 then begin + fevents[int1].doexecute(lint1); + end; + end; + end; +end; + +function tdbeventcontroller.geteventinterval: integer; +begin + result:= ftimer.interval; +end; + +procedure tdbeventcontroller.seteventinterval(const avalue: integer); +begin + ftimer.interval:= abs(avalue); + if avalue < 0 then begin + ftimer.singleshot:= true; + ftimer.enabled:= true; //trigger oneshot + end + else begin + ftimer.singleshot:= false; + end; +end; + +procedure tdbeventcontroller.getevents; +begin + dotimer(nil); +end; + +end. diff --git a/mseide-msegui/lib/common/db/msedbf.pas b/mseide-msegui/lib/common/db/msedbf.pas new file mode 100644 index 0000000..629e52e --- /dev/null +++ b/mseide-msegui/lib/common/db/msedbf.pas @@ -0,0 +1,375 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msedbf; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses +{$warnings off} + classes,mclasses,mdb,mdbf,msedb,msetypes{msestrings},dbf_idxfile, + mseapplication; +{$warnings on} + +type + tmsedbf = class(tdbf,imselocate,idscontroller,igetdscontroller, + iactivatorclient) + private + ffilepath: filenamety; + fcontroller: tdscontroller; + procedure setfilepath(const avalue: filenamety); + procedure setcontroller(const avalue: tdscontroller); + function getcontroller: tdscontroller; + //idscontroller +// procedure inheritedresync(const mode: tresyncmode); + procedure inheriteddataevent(const event: tdataevent; const info: ptrint); + procedure inheritedcancel; + procedure inheritedpost; + procedure inheriteddelete(); + procedure inheritedinsert(); + function inheritedmoveby(const distance: integer): integer; + procedure inheritedinternalinsert; + procedure inheritedinternaldelete; + procedure inheritedinternalopen; + procedure inheritedinternalclose; + function getblobdatasize: integer; + function getnumboolean: boolean; + function getfloatdate: boolean; + function getint64currency: boolean; + function getsavepointoptions(): savepointoptionsty; + function getfiltereditkind: filtereditkindty; + procedure beginfilteredit(const akind: filtereditkindty); + procedure endfilteredit; + procedure clearfilter; +// procedure doidleapplyupdates; + function getrestorerecno: boolean; + procedure setrestorerecno(const avalue: boolean); + function updatesortfield(const afield: tfield; const adescend: boolean): boolean; + protected + procedure setactive (const value : boolean); reintroduce; + function getactive: boolean; + procedure loaded; override; + function getfieldclass(fieldtype: tfieldtype): tfieldclass; override; + procedure dataevent(event: tdataevent; info: ptrint); override; + procedure openlocal; + procedure internalopen; override; + procedure internalclose; override; + procedure internalinsert; override; + procedure internaldelete; override; + function getcanmodify: boolean; override; +// procedure dscontrolleroptionschanged(const aoptions: datasetoptionsty); + function islastrecord: boolean; + procedure begindisplaydata; + procedure enddisplaydata; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; reintroduce; + { + function locate(const key: integer; const field: tfield; + const options: locateoptionsty = []): locateresultty; + function locate(const key: msestring; const field: tfield; + const options: locateoptionsty = []): locateresultty; + } + procedure AppendRecord(const Values: array of const); + function moveby(const distance: integer): integer; + procedure cancel; override; + procedure post; override; + published + property FilePath: filenamety read ffilepath write setfilepath; + property controller: tdscontroller read fcontroller write setcontroller; + property Active: boolean read getactive write setactive default false; + property AutocalcFields default false; + property FilterOptions default []; + end; + +implementation +uses + msefileutils; + +{ tmsedbf } + +constructor tmsedbf.create(aowner: tcomponent); +begin + inherited; + fcontroller:= tdscontroller.create(self,idscontroller(self),-1); +end; + +destructor tmsedbf.destroy; +begin + fcontroller.free; + inherited; +end; +{ +function tmsedbf.locate(const key: integer; const field: tfield; + const options: locateoptionsty = []): locateresultty; +begin + result:= fcontroller.locate(key,field,options); +end; + +function tmsedbf.locate(const key: msestring; const field: tfield; + const options: locateoptionsty = []): locateresultty; +begin + result:= fcontroller.locate(key,field,options); +end; +} +function tmsedbf.locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; +begin + result:= msedb.locaterecord(self,afields,akeys,aisnull,akeyoptions,aoptions); +end; + +procedure tmsedbf.AppendRecord(const Values: array of const); +begin + fcontroller.appendrecord(values); +end; + +procedure tmsedbf.setfilepath(const avalue: filenamety); +begin + ffilepath:= tomsefilepath(avalue); + inherited filepath:= ansistring( + tosysfilepath(msefileutils.filepath(avalue,fk_default,true))); +end; + +procedure tmsedbf.setcontroller(const avalue: tdscontroller); +begin + fcontroller.assign(avalue); +end; + +procedure tmsedbf.setactive(const value: boolean); +begin + if fcontroller.setactive(value) then begin + inherited setactive(value); + end; +end; + +function tmsedbf.getactive: boolean; +begin + result:= inherited active; +end; + +procedure tmsedbf.loaded; +begin + inherited; + fcontroller.loaded; +end; + +function tmsedbf.getfieldclass(fieldtype: tfieldtype): tfieldclass; +begin + fcontroller.getfieldclass(fieldtype,result); +end; + +procedure tmsedbf.cancel; +begin + fcontroller.cancel; +end; + +function tmsedbf.getcontroller: tdscontroller; +begin + result:= fcontroller; +end; + +procedure tmsedbf.inheriteddataevent(const event: tdataevent; + const info: ptrint); +begin + inherited dataevent(event,info); +end; + +procedure tmsedbf.dataevent(event: tdataevent; info: ptrint); +begin + fcontroller.dataevent(event,info); +end; + +{ +procedure tmsedbf.inheritedresync(const mode: tresyncmode); +begin + inherited resync(mode); +end; + +procedure tmsedbf.Resync(Mode: TResyncMode); +begin + fcontroller.resync(mode); +end; +} +procedure tmsedbf.inheritedcancel; +begin + inherited cancel; +end; + +function tmsedbf.inheritedmoveby(const distance: integer): integer; +begin + result:= inherited moveby(distance); +end; + +function tmsedbf.moveby(const distance: integer): integer; +begin + result:= fcontroller.moveby(distance); +end; + +procedure tmsedbf.inheritedinternalinsert; +begin + inherited internalinsert; +end; + +procedure tmsedbf.internalinsert; +begin + fcontroller.internalinsert; +end; + +procedure tmsedbf.inheritedinternalopen; +begin + inherited internalopen; +end; + +procedure tmsedbf.internalopen; +begin + fcontroller.internalopen; +end; + +procedure tmsedbf.inheritedpost; +begin + inherited post; +end; + +procedure tmsedbf.post; +begin + fcontroller.post; +end; + +procedure tmsedbf.inheritedinternaldelete; +begin + inherited internaldelete; +end; + +procedure tmsedbf.internaldelete; +begin + fcontroller.internaldelete; +end; + +procedure tmsedbf.openlocal; +begin + inherited internalopen; +end; + +procedure tmsedbf.inheritedinternalclose; +begin + inherited internalclose; +end; + +procedure tmsedbf.internalclose; +begin + fcontroller.internalclose; +end; + +function tmsedbf.getblobdatasize: integer; +begin + result:= 0; //no blobid? +end; + +function tmsedbf.getnumboolean: boolean; +begin + result:= false; +end; + +function tmsedbf.getfloatdate: boolean; +begin + result:= false; +end; + +function tmsedbf.getint64currency: boolean; +begin + result:= false; +end; + +function tmsedbf.getsavepointoptions(): savepointoptionsty; +begin + result:= []; +end; + +function tmsedbf.getfiltereditkind: filtereditkindty; +begin + result:= fek_filter; +end; + +procedure tmsedbf.beginfilteredit(const akind: filtereditkindty); +begin + //dummy +end; + +procedure tmsedbf.endfilteredit; +begin + //dummy +end; + +procedure tmsedbf.clearfilter; +begin + //dummy +end; +{ +procedure tmsedbf.doidleapplyupdates; +begin + //dummy +end; +} +function tmsedbf.getcanmodify: boolean; +begin + result:= fcontroller.getcanmodify and inherited getcanmodify; +end; +{ +procedure tmsedbf.dscontrolleroptionschanged(const aoptions: datasetoptionsty); +begin + //dummy +end; +} +function tmsedbf.getrestorerecno: boolean; +begin + result:= false; +end; + +procedure tmsedbf.setrestorerecno(const avalue: boolean); +begin + //dummy +end; + +function tmsedbf.islastrecord: boolean; +begin + result:= eof or (recno = recordcount); +end; + +function tmsedbf.updatesortfield(const afield: tfield; + const adescend: boolean): boolean; +begin + result:= false; +end; + +procedure tmsedbf.begindisplaydata; +begin + //dummy +end; + +procedure tmsedbf.enddisplaydata; +begin + ///dummy +end; + +procedure tmsedbf.inheriteddelete; +begin + inherited delete(); +end; + +procedure tmsedbf.inheritedinsert; +begin + inherited insert(); +end; + +end. diff --git a/mseide-msegui/lib/common/db/msedbgraphics.pas b/mseide-msegui/lib/common/db/msedbgraphics.pas new file mode 100644 index 0000000..3324ca9 --- /dev/null +++ b/mseide-msegui/lib/common/db/msedbgraphics.pas @@ -0,0 +1,579 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msedbgraphics; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface +uses + classes,mclasses,mdb,mseimage,mseguiglob,msedataimage,msedbdispwidgets,msedb, + msetypes,msedbedit,typinfo, + msegrids,msewidgetgrid,msedatalist,msebitmap,msebintree,msegraphics, + msemenus,mseevent,msegui,mseifiglob,mseificompglob; + +{ add the needed graphic format units to your project: + mseformatbmpicoread, + mseformatjpgwrite,mseformatpngwrite, + mseformatpnmread,mseformattgaread,mseformatxpmread, +} + +type + idbgraphicfieldlink = interface(idbeditfieldlink) + procedure setformat(const avalue: string); + end; + + timagecachenode = class(tcachenode) + private + fimage: maskedimagety; + fformat: string; + protected + flocal: boolean; + public + constructor create(const aid: blobidty); overload; + destructor destroy; override; + property format: string read fformat write fformat; + end; + + timagecache = class(tcacheavltree) + protected + ffindnode: timagecachenode; + public + constructor create; + destructor destroy; override; + function find(const akey: blobidty; out anode: timagecachenode): boolean; + overload; + end; + + tmsegraphicfield = class(tmseblobfield) + private + fformat: string; + fimagecache: timagecache; + function getimagecachekb: integer; + procedure setimagecachekb(const avalue: integer); + protected + procedure removecache(const aid: blobidty); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function loadbitmap(const adest: tmaskedbitmap; + aformat: string = ''): string; //returns format + procedure storebitmap(const asource: tmaskedbitmap; + aformat: string = ''); overload; + procedure storebitmap(const asource: tmaskedbitmap; aformat: string; + const params: array of const); overload; + procedure clearcache; override; + published + property format: string read fformat write fformat; + property imagecachekb: integer read getimagecachekb + write setimagecachekb default 0; + //cachesize in kilo bytes, 0 -> no cache + end; + + tgraphicdatalink = class(teditwidgetdatalink) + protected + procedure setfield(const value: tfield); override; + public + constructor create(const intf: idbgraphicfieldlink); + function loadbitmap(const adest: tmaskedbitmap; + const aformat: string): string; //returns format + end; + + tdbdataimage = class(tcustomdataimage,idbgraphicfieldlink, + ireccontrol,iifidatalink) + private + fdatalink: tgraphicdatalink; +// fvaluebuffer: string; + //iifidatalink + function getifilinkkind: ptypeinfo; + procedure updateifigriddata(const sender: tobject; const alist: tdatalist); + function getgriddata: tdatalist; + function getvalueprop: ppropinfo; + procedure getifivalue(var avalue); //for pointer property without RTTI + procedure setifivalue(const avalue); //for pointer property without RTTI + //idbeditfieldlink + function getgriddatasource: tdatasource; + function getedited: boolean; + procedure initeditfocus; + function checkvalue(const quiet: boolean = false): boolean; + procedure valuetofield; + procedure updatereadonlystate; + procedure getfieldtypes(var afieldtypes: fieldtypesty); + procedure setmaxlength(const avalue: integer); + function getfieldlink: tcustomeditwidgetdatalink; + //idbgraphicfieldlink + procedure fieldtovalue; virtual; + procedure setnullvalue; + //ireccontrol + procedure recchanged; + procedure setdatalink(const avalue: tgraphicdatalink); + protected +// procedure doenter; override; +// procedure doexit; override; + procedure griddatasourcechanged; override; + procedure loadcellbmp(const acanvas: tcanvas; const abmp: tmaskedbitmap); override; + function getrowdatapo(const arow: integer): pointer; override; + function createdatalist(const sender: twidgetcol): tdatalist; override; + procedure defineproperties(filer: tfiler); override; + procedure setvalue(const avalue: string); override; + procedure gridtovalue(row: integer); override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property datalink: tgraphicdatalink read fdatalink write setdatalink; + property format; + property onbeforepaint; + property onpaintbackground; + property onpaint; + property onafterpaint; + end; + +implementation +uses + msestream,sysutils,msegraphicstream; + +type + tsimplebitmap1 = class(tsimplebitmap); + treader1 = class(treader); + + { tdbdataimage } + +function tdbdataimage.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iifidatalink); +end; + +procedure tdbdataimage.updateifigriddata(const sender: tobject; + const alist: tdatalist); +begin + //dummy +end; + +function tdbdataimage.getgriddata: tdatalist; +begin + result:= nil; +end; + +function tdbdataimage.getvalueprop: ppropinfo; +begin + result:= nil; +end; + +procedure tdbdataimage.getifivalue(var avalue); +begin + //dummy +end; + +procedure tdbdataimage.setifivalue(const avalue); +begin + //dummy +end; + +constructor tdbdataimage.create(aowner: tcomponent); +begin + fdatalink:= tgraphicdatalink.create(idbgraphicfieldlink(self)); + inherited; +{$warnings off} + include(tsimplebitmap1(bitmap).fstate,pms_nosave); +{$warnings on} +end; + +destructor tdbdataimage.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tdbdataimage.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= blobfields + [ftstring]; +end; + +procedure tdbdataimage.fieldtovalue; +begin + fcurformat:= datalink.loadbitmap(bitmap,format); +end; + +procedure tdbdataimage.setnullvalue; +begin + bitmap.clear; +end; + +procedure tdbdataimage.recchanged; +begin + fdatalink.recordchanged(nil); +end; + +procedure tdbdataimage.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdbdataimage.getgriddatasource: tdatasource; +begin + result:= tcustomdbwidgetgrid(fgridintf.getcol.grid).datalink.datasource; +end; + +function tdbdataimage.getedited: boolean; +begin + result:= false; +end; + +procedure tdbdataimage.initeditfocus; +begin + //dummy +end; + +function tdbdataimage.checkvalue(const quiet: boolean = false): boolean; +begin + result:= false; + //dummy +end; + +procedure tdbdataimage.valuetofield; +begin + if fvalue{buffer} = '' then begin + fdatalink.clear; + end + else begin + fdatalink.asstring:= fvalue{buffer}; + end; +end; + +procedure tdbdataimage.updatereadonlystate; +begin + //dummy +end; + +function tdbdataimage.getrowdatapo(const arow: integer): pointer; +begin + if (fgriddatalink <> nil) and not + tgriddatalink(fgriddatalink).getrowfieldisnull( + fdatalink.field,arow) then begin + result:= tgriddatalink(fgriddatalink).getdummystringbuffer; + pstring(result)^:= ' '; + end + else begin + result:= nil; + end; +end; + +procedure tdbdataimage.loadcellbmp(const acanvas: tcanvas; + const abmp: tmaskedbitmap); +var + int1: integer; +begin + with cellinfoty(acanvas.drawinfopo^) do begin + if fdatalink.field is tmsegraphicfield then begin + with tgriddatalink(fgriddatalink) do begin + int1:= activerecord; + activerecord:= cell.row; + tmsegraphicfield(fdatalink.field).loadbitmap(abmp,format); + activerecord:= int1; + end; + end + else begin + abmp.loadfromstring( + string(tgriddatalink(fgriddatalink).getansistringbuffer( + fdatalink.field,cell.row)^),format,[]); + end; + end; +end; + +function tdbdataimage.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdbdataimage.setdatalink(const avalue: tgraphicdatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdbdataimage.defineproperties(filer: tfiler); +begin + inherited; + fdatalink.fixupproperties(filer); //move values to datalink +end; + +procedure tdbdataimage.gridtovalue(row: integer); +begin + //dummy +end; + +procedure tdbdataimage.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + fdatalink.doshortcut(info,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +procedure tdbdataimage.setvalue(const avalue: string); +//var +// bufferbefore: string; +begin +// bufferbefore:= fvaluebuffer; +// fvaluebuffer:= avalue; +// try + fdatalink.modified; + inherited; + fdatalink.valuechanged(iifidatalink(self)); +// finally +// fvaluebuffer:= bufferbefore; +// end; +end; + +procedure tdbdataimage.setmaxlength(const avalue: integer); +begin + //dummy +end; + +function tdbdataimage.getfieldlink: tcustomeditwidgetdatalink; +begin + result:= fdatalink; +end; + +{ tmsegraphicfield } + +constructor tmsegraphicfield.create(aowner: tcomponent); +begin + inherited; + setdatatype(ftgraphic); +end; + +destructor tmsegraphicfield.destroy; +begin + freeandnil(fimagecache); + inherited; +end; + +function tmsegraphicfield.loadbitmap(const adest: tmaskedbitmap; + aformat: string = ''): string; +var + stream1: tstringcopystream; + str1: string; + id1: blobidty; + n1: timagecachenode; +begin + result:= ''; + if isnull then begin + adest.clear; + end + else begin + if (fimagecache = nil) or not assigned(fgetblobid) or not fgetblobid(self,id1) or + not fimagecache.find(id1,n1) then begin + str1:= asstring; + if str1 = '' then begin + adest.clear; + end + else begin + if aformat = '' then begin + aformat:= format; + end; + stream1:= tstringcopystream.create(str1); + try + result:= adest.loadfromstream(stream1,aformat,[]); + except + result:= ''; + adest.clear; + end; + stream1.free; + end; + if (fimagecache <> nil) and assigned(fgetblobid) then begin + n1:= timagecachenode.create(id1); + n1.format:= result; + adest.savetomaskedimage(n1.fimage); + n1.fsize:= (n1.fimage.image.length + n1.fimage.mask.length) * + sizeof(longword); + fimagecache.addnode(n1); + end; + end + else begin + adest.loadfrommaskedimage(n1.fimage); + result:= n1.format; + end; + end; +end; + +procedure tmsegraphicfield.storebitmap(const asource: tmaskedbitmap; + aformat: string; const params: array of const); +var + stream1: tmsefilestream; +begin + if aformat = '' then begin + aformat:= format; + end; + stream1:= tmsefilestream.create; + try + writegraphic(stream1,asource,aformat,params); + stream1.position:= 0; + loadfromstream(stream1); + finally + stream1.free; + end; +end; + +procedure tmsegraphicfield.storebitmap(const asource: tmaskedbitmap; + aformat: string = ''); +begin + storebitmap(asource,aformat,[]); +end; + +function tmsegraphicfield.getimagecachekb: integer; +begin + result:= 0; + if fimagecache <> nil then begin + result:= fimagecache.maxsize div 1024; + end; +end; + +procedure tmsegraphicfield.setimagecachekb(const avalue: integer); +begin + if imagecachekb <> avalue then begin + if avalue > 0 then begin + if fimagecache = nil then begin + fimagecache:= timagecache.create; + end; + fimagecache.maxsize:= avalue * 1024; + end + else begin + freeandnil(fimagecache); + end; + end; +end; + +procedure tmsegraphicfield.clearcache; +begin + if fimagecache <> nil then begin + fimagecache.clear; + end; + inherited; +end; + +procedure tmsegraphicfield.removecache(const aid: blobidty); +var + n1: timagecachenode; +begin + if fimagecache <> nil then begin + if fimagecache.find(aid,n1) then begin + fimagecache.removenode(n1); + n1.free; + end; + end; + inherited; +end; + +{ tgraphicdatalink } + +constructor tgraphicdatalink.create(const intf: idbgraphicfieldlink); +begin + inherited create(intf); +end; + +procedure tgraphicdatalink.setfield(const value: tfield); +begin + if value is tmsegraphicfield then begin + idbgraphicfieldlink(fintf).setformat(tmsegraphicfield(value).format); + end; + inherited; +end; + +function tgraphicdatalink.loadbitmap(const adest: tmaskedbitmap; + const aformat: string): string; +var + stream1: tstringcopystream; + str1: string; +begin + if field is tmsegraphicfield then begin + with tmsegraphicfield(field) do begin + result:= loadbitmap(adest,aformat); + end; + end + else begin + str1:= field.asstring; + if str1 = '' then begin + adest.clear; + end + else begin + stream1:= tstringcopystream.create(str1); + try + result:= adest.loadfromstream(stream1,aformat,[]); + except + result:= ''; + adest.clear; + end; + stream1.free; + end; + end; +end; + +{ timagecachenode } + +constructor timagecachenode.create(const aid: blobidty); +begin + flocal:= aid.local; + inherited create(aid.id); +end; + +destructor timagecachenode.destroy; +begin + freeimage(fimage); + inherited; +end; + +{ timagecache } + +function compareblobid(const left,right: tavlnode): integer; +var + lint1: int64; +begin + result:= integer(timagecachenode(left).flocal) - + integer(timagecachenode(right).flocal); + if result = 0 then begin + lint1:= timagecachenode(left).fkey - timagecachenode(right).fkey; + if lint1 > 0 then begin + result:= 1; + end + else begin + if lint1 < 0 then begin + result:= -1; + end; + end; + end; +end; + +constructor timagecache.create; +begin + ffindnode:= timagecachenode.create; + inherited; + fcompare:= {$ifdef FPC}@{$endif}compareblobid; +end; + +destructor timagecache.destroy; +begin + inherited; + ffindnode.free; +end; + +function timagecache.find(const akey: blobidty; + out anode: timagecachenode): boolean; +begin + ffindnode.fkey:= akey.id; + ffindnode.flocal:= akey.local; + result:= find(ffindnode,tavlnode(anode)); +end; + +initialization + regfieldclass(ft_graphic,tmsegraphicfield); +end. diff --git a/mseide-msegui/lib/common/db/msedblookup.pas b/mseide-msegui/lib/common/db/msedblookup.pas new file mode 100644 index 0000000..1aba58b --- /dev/null +++ b/mseide-msegui/lib/common/db/msedblookup.pas @@ -0,0 +1,2759 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msedblookup; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,mdb,msewidgetgrid,msedataedits,mseeditglob,msestrings, + msedatalist, + msedbedit,msedb,msegui,msegrids,msedbdispwidgets,mselookupbuffer,mseclasses, + mseformatstr,msetypes,mseglob,msemenus,mseguiglob,msebufdataset, + msegraphics; + +const + defaultlookupoptionsedit = defaultoptionsedit + [oe_readonly]; + +type + idblookupdispfieldlink = interface(idbdispfieldlink) + procedure formatchanged; + procedure refreshfieldvalue; + end; + + idblookuplbdispfieldlink = interface(idblookupdispfieldlink) + procedure setlookupvalue(const aindex: integer); + function lookuptext(const aindex: integer): msestring; + function getdatalbdatakind: lbdatakindty; + end; + + idblookupdbdispfieldlink = interface(idblookupdispfieldlink) + procedure setlookupvalue(const aindex: bookmarkdataty); + function lookuptext(const aindex: bookmarkdataty): msestring; + function getlookupvaluefieldtypes: fieldtypesty; + end; + + tdblookup32lb = class; + + tlookupdispfielddatalink = class(tdispfielddatalink) + private + function getdatasource1: tdatasource; + procedure setwidgetdatasource(const avalue: tdatasource); + procedure griddatasourcechanged; + protected + fowner: tcustomdataedit; + fdatatype: lookupdatatypety; + fisnull: boolean; + procedure lookupchange; + function datatotext(const data): msestring; virtual; abstract; + procedure updatelookupvalue; virtual; abstract; + procedure fieldtovalue; virtual; abstract; + function getrowdatapo(const alink: tgriddatalink; + const arow: integer): pointer; virtual; abstract; + public + constructor create(const aowner: tcustomdataedit; + const adatatype: lookupdatatypety; + const intf: idblookupdispfieldlink); + function msedisplaytext(const aformat: msestring = ''; + const aedit: boolean = false): msestring; override; + published + property datasource: tdatasource read getdatasource1 write setwidgetdatasource; + end; + + tlookupdbdispfielddatalink = class; + + tlookupdatalink = class(tfielddatalink) + private + fkeyfield: tfield; + fkeyfieldname: string; + protected + fdisplink: tlookupdbdispfielddatalink; + fcanlookup: boolean; + flookupindexnum: integer; + procedure updatefields; override; + procedure activechanged; override; + procedure dataevent(event: tdataevent; info: ptrint); override; + procedure fieldchanged; override; + end; + + tlookupdbdispfielddatalink = class(tlookupdispfielddatalink) + private + flookupdatalink: tlookupdatalink; + procedure setlookupkeyfield(const avalue: string); + procedure setlookupvaluefield(const avalue: string); + function getlookupkeyfield: string; + function getlookupvaluefield: string; + function getlookupdatasource: tdatasource; + procedure setlookupdatasource(const avalue: tdatasource); + protected + function getintegerlookupvalue(const abm: bookmarkdataty): integer; + function getstringlookupvalue(const abm: bookmarkdataty): msestring; + function getfloatlookupvalue(const abm: bookmarkdataty): double; + function getdataset(const aindex: integer): tdataset; override; + procedure getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); override; + public + constructor create(const aowner: tcustomdataedit; + const adatatype: lookupdatatypety; + const intf: idblookupdbdispfieldlink); + destructor destroy; override; + published + property lookupdatasource: tdatasource read getlookupdatasource + write setlookupdatasource; + property lookupkeyfield: string read getlookupkeyfield + write setlookupkeyfield; + property lookupvaluefield: string read getlookupvaluefield + write setlookupvaluefield; + end; + + tlookuplbdispfielddatalink = class(tlookupdispfielddatalink, + ilookupbufferfieldinfo,iobjectlink) + private + flookupbuffer: tcustomlookupbuffer; + flookupkeyfieldno: lookupbufferfieldnoty; + flookupvaluefieldno: lookupbufferfieldnoty; + fobjectlinker: tobjectlinker; + procedure setlookupbuffer(const avalue: tcustomlookupbuffer); + procedure setlookupkeyfieldno(const avalue: lookupbufferfieldnoty); + procedure setlookupvaluefieldno(const avalue: lookupbufferfieldnoty); + protected + function getkeylbdatakind: lbdatakindty; virtual; abstract; + procedure objectevent(const sender: tobject; const event: objecteventty); + //iobjectlink + procedure link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); + procedure unlink(const source,dest: iobjectlink; valuepo: pointer = nil); + procedure objevent(const sender: iobjectlink; const event: objecteventty); + function getinstance: tobject; + //ilookupbufferfieldinfo + function getlbdatakind(const apropname: string): lbdatakindty; + function getlookupbuffer: tcustomlookupbuffer; + public + constructor create(const aowner: tcustomdataedit; + const adatatype: lookupdatatypety; + const intf: idblookuplbdispfieldlink); + destructor destroy; override; + published + property lookupbuffer: tcustomlookupbuffer read flookupbuffer + write setlookupbuffer; + property lookupkeyfieldno: lookupbufferfieldnoty read flookupkeyfieldno + write setlookupkeyfieldno default 0; + property lookupvaluefieldno: lookupbufferfieldnoty read flookupvaluefieldno + write setlookupvaluefieldno default 0; + end; + + tlookup32lbdispfielddatalink = class(tlookuplbdispfielddatalink) + protected + fkey: integer; + function getkeylbdatakind: lbdatakindty; override; + procedure updatelookupvalue; override; + function datatotext(const data): msestring; override; + procedure fieldtovalue; override; + function getrowdatapo(const alink: tgriddatalink; + const arow: integer): pointer; override; + end; + + tlookup64lbdispfielddatalink = class(tlookuplbdispfielddatalink) + protected + fkey: int64; + function getkeylbdatakind: lbdatakindty; override; + procedure updatelookupvalue; override; + function datatotext(const data): msestring; override; + procedure fieldtovalue; override; + function getrowdatapo(const alink: tgriddatalink; + const arow: integer): pointer; override; + end; + + tlookupstrlbdispfielddatalink = class(tlookuplbdispfielddatalink) + protected + fkey: msestring; + function getkeylbdatakind: lbdatakindty; override; + procedure updatelookupvalue; override; + function datatotext(const data): msestring; override; + procedure fieldtovalue; override; + function getrowdatapo(const alink: tgriddatalink; + const arow: integer): pointer; override; + end; + + tlookup32dbdispfielddatalink = class(tlookupdbdispfielddatalink) + protected + fkey: integer; + procedure updatelookupvalue; override; + procedure fieldtovalue; override; + function datatotext(const data): msestring; override; + function getrowdatapo(const alink: tgriddatalink; + const arow: integer): pointer; override; + end; + + tlookup64dbdispfielddatalink = class(tlookupdbdispfielddatalink) + protected + fkey: int64; + procedure updatelookupvalue; override; + procedure fieldtovalue; override; + function datatotext(const data): msestring; override; + function getrowdatapo(const alink: tgriddatalink; + const arow: integer): pointer; override; + end; + + tlookupstrdbdispfielddatalink = class(tlookupdbdispfielddatalink) + protected + fkey: msestring; + procedure updatelookupvalue; override; + procedure fieldtovalue; override; + function datatotext(const data): msestring; override; + function getrowdatapo(const alink: tgriddatalink; + const arow: integer): pointer; override; + end; + + tdblookup1 = class(tcustomdataedit,idblookupdispfieldlink,idbdispfieldlink) + private + fdatalink: tlookupdispfielddatalink; + procedure setdatalink(const avalue: tlookupdispfielddatalink); + function getisnull: boolean; + protected + function createdatalink: tlookupdispfielddatalink; virtual; abstract; + procedure dochange; override; + + function getdatalistclass: datalistclassty; override; + procedure valuetogrid(row: integer); override; + procedure griddatasourcechanged; override; + function createdatalist(const sender: twidgetcol): tdatalist; override; + function getoptionsedit: optionseditty; override; + procedure texttovalue(var accept: boolean; const quiet: boolean); override; + procedure setnullvalue; override; + + function internaldatatotext(const data): msestring; override; + function getrowdatapo(const arow: integer): pointer; override; + + //idispfieldlink + function getfieldlink: tdispfielddatalink; + procedure fieldtovalue; + procedure valuetofield; + procedure getfieldtypes(var afieldtypes: fieldtypesty); virtual; + procedure refreshfieldvalue; + //ireccontrol + procedure recchanged; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property isnull: boolean read getisnull; + published + + property empty_color; + property empty_font; + property empty_fontstyle; + property empty_textflags; + property empty_text; + property empty_options; + property empty_textcolor; + property empty_textcolorbackground; + property optionsedit default defaultlookupoptionsedit; + property font; + property textflags; + property textflagsactive; + property caretwidth; + property onchange; + property ongettext; + property onkeydown; + property onkeyup; + end; + + tdblookup = class(tdblookup1) + private + protected + published + property datalink: tlookupdispfielddatalink read fdatalink write setdatalink; + end; + + tdblookupdb = class(tdblookup,idblookupdbdispfieldlink) + private + function getdatalink: tlookupdbdispfielddatalink; + procedure setdatalink(const avalue: tlookupdbdispfielddatalink); + protected + procedure setlookupvalue(const abm: bookmarkdataty); virtual; abstract; + function lookuptext(const abm: bookmarkdataty): msestring; virtual; abstract; + function getlookupvaluefieldtypes: fieldtypesty; virtual; abstract; + public + published + property datalink: tlookupdbdispfielddatalink read getdatalink + write setdatalink; + end; + + tdblookup32db = class(tdblookupdb,ireccontrol) + protected + function createdatalink: tlookupdispfielddatalink; override; + procedure getfieldtypes(var afieldtypes: fieldtypesty); override; + end; + + tdblookup64db = class(tdblookupdb,ireccontrol) + protected + function createdatalink: tlookupdispfielddatalink; override; + procedure getfieldtypes(var afieldtypes: fieldtypesty); override; + end; + + tdblookupstrdb = class(tdblookupdb,ireccontrol) + protected + function createdatalink: tlookupdispfielddatalink; override; + procedure getfieldtypes(var afieldtypes: fieldtypesty); override; + end; + + tdblookuplb = class(tdblookup,idblookuplbdispfieldlink) + private + procedure readlookupkeyfieldno(reader: treader); + procedure readlookupvaluefieldno(reader: treader); + function getlookupbuffer: tcustomlookupbuffer; + procedure setlookupbuffer(const avalue: tcustomlookupbuffer); + function getdatalink: tlookuplbdispfielddatalink; + procedure setdatalink(const avalue: tlookuplbdispfielddatalink); + protected + function getdatalbdatakind: lbdatakindty; virtual; abstract; + procedure defineproperties(filer: tfiler); override; + procedure setlookupvalue(const aindex: integer); virtual; abstract; + //aindex -1 -> NULL + function lookuptext(const aindex: integer): msestring; virtual; abstract; + public + published + property datalink: tlookuplbdispfielddatalink read getdatalink + write setdatalink; +{ + property lookupbuffer: tcustomlookupbuffer read getlookupbuffer + write setlookupbuffer; deprecated; + //use datalink.lookupbuffer +} + end; + + tdblookup32lb = class(tdblookuplb,ireccontrol) + protected + function createdatalink: tlookupdispfielddatalink; override; + procedure getfieldtypes(var afieldtypes: fieldtypesty); override; + public + end; + + tdblookup64lb = class(tdblookuplb,ireccontrol) + protected + function createdatalink: tlookupdispfielddatalink; override; + //idbeditfieldlink + procedure getfieldtypes(var afieldtypes: fieldtypesty); override; + public + end; + + tdblookupstrlb = class(tdblookuplb,ireccontrol) + protected + function createdatalink: tlookupdispfielddatalink; override; + //idbeditfieldlink + procedure getfieldtypes(var afieldtypes: fieldtypesty); override; + public + end; + + tdbstringlookuplb = class(tdblookup32lb) + private + fvalue: msestring; + protected + function getdatalbdatakind: lbdatakindty; override; + procedure setlookupvalue(const aindex: integer); override; + function lookuptext(const aindex: integer): msestring; override; + public + property value: msestring read fvalue; + end; + + tdbstringlookup64lb = class(tdblookup64lb) + private + fvalue: msestring; + protected + function getdatalbdatakind: lbdatakindty; override; + procedure setlookupvalue(const aindex: integer); override; + function lookuptext(const aindex: integer): msestring; override; + public + property value: msestring read fvalue; + end; + + tdbstringlookupstrlb = class(tdblookupstrlb) + private + fvalue: msestring; + protected + function getdatalbdatakind: lbdatakindty; override; + procedure setlookupvalue(const aindex: integer); override; + function lookuptext(const aindex: integer): msestring; override; + public + property value: msestring read fvalue; + end; + + tdbstringlookupdb = class(tdblookup32db) + private + fvalue: msestring; + protected + procedure setlookupvalue(const abm: bookmarkdataty); override; + function lookuptext(const abm: bookmarkdataty): msestring; override; + function getlookupvaluefieldtypes: fieldtypesty; override; + public + property value: msestring read fvalue; + end; + + tdbstringlookup64db = class(tdblookup64db) + private + fvalue: msestring; + protected + procedure setlookupvalue(const abm: bookmarkdataty); override; + function lookuptext(const abm: bookmarkdataty): msestring; override; + function getlookupvaluefieldtypes: fieldtypesty; override; + public + property value: msestring read fvalue; + end; + + tdbstringlookupstrdb = class(tdblookupstrdb) + private + fvalue: msestring; + protected + procedure setlookupvalue(const abm: bookmarkdataty); override; + function lookuptext(const abm: bookmarkdataty): msestring; override; + function getlookupvaluefieldtypes: fieldtypesty; override; + public + property value: msestring read fvalue; + end; + + tdbintegerlookuplb = class(tdblookup32lb) + private + fbase: numbasety; + fbitcount: integer; + fvalue: integer; + procedure setbase(const avalue: numbasety); + procedure setbitcount(const avalue: integer); + protected + function getdatalbdatakind: lbdatakindty; override; + procedure setlookupvalue(const aindex: integer); override; + function lookuptext(const aindex: integer): msestring; override; + public + constructor create(aaowner: tcomponent); override; + property value: integer read fvalue; + published + property base: numbasety read fbase write setbase default nb_dec; + property bitcount: integer read fbitcount write setbitcount default 32; + end; + + tdbintegerlookup64lb = class(tdblookup64lb) + private + fbase: numbasety; + fbitcount: integer; + fvalue: integer; + procedure setbase(const avalue: numbasety); + procedure setbitcount(const avalue: integer); + protected + function getdatalbdatakind: lbdatakindty; override; + procedure setlookupvalue(const aindex: integer); override; + function lookuptext(const aindex: integer): msestring; override; + public + constructor create(aaowner: tcomponent); override; + property value: integer read fvalue; + published + property base: numbasety read fbase write setbase default nb_dec; + property bitcount: integer read fbitcount write setbitcount default 32; + end; + + tdbintegerlookupstrlb = class(tdblookupstrlb) + private + fbase: numbasety; + fbitcount: integer; + fvalue: integer; + procedure setbase(const avalue: numbasety); + procedure setbitcount(const avalue: integer); + protected + function getdatalbdatakind: lbdatakindty; override; + procedure setlookupvalue(const aindex: integer); override; + function lookuptext(const aindex: integer): msestring; override; + public + constructor create(aaowner: tcomponent); override; + property value: integer read fvalue; + published + property base: numbasety read fbase write setbase default nb_dec; + property bitcount: integer read fbitcount write setbitcount default 32; + end; + + tdbintegerlookupdb = class(tdblookup32db) + private + fbase: numbasety; + fbitcount: integer; + fvalue: integer; + procedure setbase(const avalue: numbasety); + procedure setbitcount(const avalue: integer); + protected + procedure setlookupvalue(const abm: bookmarkdataty); override; + function lookuptext(const abm: bookmarkdataty): msestring; override; + function getlookupvaluefieldtypes: fieldtypesty; override; + public + constructor create(aaowner: tcomponent); override; + property value: integer read fvalue; + published + property base: numbasety read fbase write setbase default nb_dec; + property bitcount: integer read fbitcount write setbitcount default 32; + end; + + tdbintegerlookup64db = class(tdblookup64db) + private + fbase: numbasety; + fbitcount: integer; + fvalue: integer; + procedure setbase(const avalue: numbasety); + procedure setbitcount(const avalue: integer); + protected + procedure setlookupvalue(const abm: bookmarkdataty); override; + function lookuptext(const abm: bookmarkdataty): msestring; override; + function getlookupvaluefieldtypes: fieldtypesty; override; + public + constructor create(aaowner: tcomponent); override; + property value: integer read fvalue; + published + property base: numbasety read fbase write setbase default nb_dec; + property bitcount: integer read fbitcount write setbitcount default 32; + end; + + tdbintegerlookupstrdb = class(tdblookupstrdb) + private + fbase: numbasety; + fbitcount: integer; + fvalue: integer; + procedure setbase(const avalue: numbasety); + procedure setbitcount(const avalue: integer); + protected + procedure setlookupvalue(const abm: bookmarkdataty); override; + function lookuptext(const abm: bookmarkdataty): msestring; override; + function getlookupvaluefieldtypes: fieldtypesty; override; + public + constructor create(aaowner: tcomponent); override; + property value: integer read fvalue; + published + property base: numbasety read fbase write setbase default nb_dec; + property bitcount: integer read fbitcount write setbitcount default 32; + end; + + tdbreallookuplb = class(tdblookup32lb) + private + fformat: msestring; + fvaluerange: real; + fvaluestart: real; + fvalue: real; + procedure setformat(const avalue: msestring); + procedure setvaluerange(const avalue: real); + procedure setvaluestart(const avalue: real); + procedure readvaluescale(reader: treader); + protected + procedure defineproperties(filer: tfiler); override; + function getdatalbdatakind: lbdatakindty; override; + procedure setlookupvalue(const aindex: integer); override; + function lookuptext(const aindex: integer): msestring; override; + public + constructor create(aowner: tcomponent); override; + property value: real read fvalue; + published + property valuerange: real read fvaluerange write setvaluerange; + property valuestart: real read fvaluestart write setvaluestart; + property format: msestring read fformat write setformat; + end; + + tdbreallookup64lb = class(tdblookup64lb) + private + fformat: msestring; + fvaluerange: real; + fvaluestart: real; + fvalue: real; + procedure setformat(const avalue: msestring); + procedure setvaluerange(const avalue: real); + procedure setvaluestart(const avalue: real); + procedure readvaluescale(reader: treader); + protected + procedure defineproperties(filer: tfiler); override; + function getdatalbdatakind: lbdatakindty; override; + procedure setlookupvalue(const aindex: integer); override; + function lookuptext(const aindex: integer): msestring; override; + public + constructor create(aowner: tcomponent); override; + property value: real read fvalue; + published + property valuerange: real read fvaluerange write setvaluerange; + property valuestart: real read fvaluestart write setvaluestart; + property format: msestring read fformat write setformat; + end; + + tdbreallookupstrlb = class(tdblookupstrlb) + private + fformat: msestring; + fvaluerange: real; + fvaluestart: real; + fvalue: real; + procedure setformat(const avalue: msestring); + procedure setvaluerange(const avalue: real); + procedure setvaluestart(const avalue: real); + procedure readvaluescale(reader: treader); + protected + procedure defineproperties(filer: tfiler); override; + function getdatalbdatakind: lbdatakindty; override; + procedure setlookupvalue(const aindex: integer); override; + function lookuptext(const aindex: integer): msestring; override; + public + constructor create(aowner: tcomponent); override; + property value: real read fvalue; + published + property valuerange: real read fvaluerange write setvaluerange; + property valuestart: real read fvaluestart write setvaluestart; + property format: msestring read fformat write setformat; + end; + + tdbreallookupdb = class(tdblookup32db) + private + fformat: msestring; + fvaluerange: real; + fvaluestart: real; + fvalue: real; + procedure setformat(const avalue: msestring); + procedure setvaluerange(const avalue: real); + procedure setvaluestart(const avalue: real); + protected + procedure setlookupvalue(const abm: bookmarkdataty); override; + function lookuptext(const abm: bookmarkdataty): msestring; override; + function getlookupvaluefieldtypes: fieldtypesty; override; + public + constructor create(aowner: tcomponent); override; + property value: real read fvalue; + published + property valuerange: real read fvaluerange write setvaluerange; + property valuestart: real read fvaluestart write setvaluestart; + property format: msestring read fformat write setformat; + end; + + tdbreallookup64db = class(tdblookup64db) + private + fformat: msestring; + fvaluerange: real; + fvaluestart: real; + fvalue: real; + procedure setformat(const avalue: msestring); + procedure setvaluerange(const avalue: real); + procedure setvaluestart(const avalue: real); + protected + procedure setlookupvalue(const abm: bookmarkdataty); override; + function lookuptext(const abm: bookmarkdataty): msestring; override; + function getlookupvaluefieldtypes: fieldtypesty; override; + public + constructor create(aowner: tcomponent); override; + property value: real read fvalue; + published + property valuerange: real read fvaluerange write setvaluerange; + property valuestart: real read fvaluestart write setvaluestart; + property format: msestring read fformat write setformat; + end; + + tdbreallookupstrdb = class(tdblookupstrdb) + private + fformat: msestring; + fvaluerange: real; + fvaluestart: real; + fvalue: real; + procedure setformat(const avalue: msestring); + procedure setvaluerange(const avalue: real); + procedure setvaluestart(const avalue: real); + protected + procedure setlookupvalue(const abm: bookmarkdataty); override; + function lookuptext(const abm: bookmarkdataty): msestring; override; + function getlookupvaluefieldtypes: fieldtypesty; override; + public + constructor create(aowner: tcomponent); override; + property value: real read fvalue; + published + property valuerange: real read fvaluerange write setvaluerange; + property valuestart: real read fvaluestart write setvaluestart; + property format: msestring read fformat write setformat; + end; + + tdbdatetimelookuplb = class(tdblookup32lb) + private + fformat: msestring; + fkind: datetimekindty; + fvalue: tdatetime; + procedure setformat(const avalue: msestring); + procedure setkind(const avalue: datetimekindty); + protected + function getdatalbdatakind: lbdatakindty; override; + procedure setlookupvalue(const aindex: integer); override; + function lookuptext(const aindex: integer): msestring; override; + published + property kind: datetimekindty read fkind write setkind default dtk_date; + property format: msestring read fformat write setformat; + property value: tdatetime read fvalue; + end; + + tdbdatetimelookup64lb = class(tdblookup64lb) + private + fformat: msestring; + fkind: datetimekindty; + fvalue: tdatetime; + procedure setformat(const avalue: msestring); + procedure setkind(const avalue: datetimekindty); + protected + function getdatalbdatakind: lbdatakindty; override; + procedure setlookupvalue(const aindex: integer); override; + function lookuptext(const aindex: integer): msestring; override; + public + property value: tdatetime read fvalue; + published + property kind: datetimekindty read fkind write setkind default dtk_date; + property format: msestring read fformat write setformat; + end; + + tdbdatetimelookupstrlb = class(tdblookupstrlb) + private + fformat: msestring; + fkind: datetimekindty; + fvalue: tdatetime; + procedure setformat(const avalue: msestring); + procedure setkind(const avalue: datetimekindty); + protected + function getdatalbdatakind: lbdatakindty; override; + procedure setlookupvalue(const aindex: integer); override; + function lookuptext(const aindex: integer): msestring; override; + public + property value: tdatetime read fvalue; + published + property kind: datetimekindty read fkind write setkind default dtk_date; + property format: msestring read fformat write setformat; + end; + + tdbdatetimelookupdb = class(tdblookup32db) + private + fformat: msestring; + fkind: datetimekindty; + fvalue: tdatetime; + procedure setformat(const avalue: msestring); + procedure setkind(const avalue: datetimekindty); + protected + procedure setlookupvalue(const abm: bookmarkdataty); override; + function lookuptext(const abm: bookmarkdataty): msestring; override; + function getlookupvaluefieldtypes: fieldtypesty; override; + published + property kind: datetimekindty read fkind write setkind default dtk_date; + property format: msestring read fformat write setformat; + property value: tdatetime read fvalue; + end; + + tdbdatetimelookup64db = class(tdblookup64db) + private + fformat: msestring; + fkind: datetimekindty; + fvalue: tdatetime; + procedure setformat(const avalue: msestring); + procedure setkind(const avalue: datetimekindty); + protected + procedure setlookupvalue(const abm: bookmarkdataty); override; + function lookuptext(const abm: bookmarkdataty): msestring; override; + function getlookupvaluefieldtypes: fieldtypesty; override; + published + property kind: datetimekindty read fkind write setkind default dtk_date; + property format: msestring read fformat write setformat; + property value: tdatetime read fvalue; + end; + + tdbdatetimelookupstrdb = class(tdblookupstrdb) + private + fformat: msestring; + fkind: datetimekindty; + fvalue: tdatetime; + procedure setformat(const avalue: msestring); + procedure setkind(const avalue: datetimekindty); + protected + procedure setlookupvalue(const abm: bookmarkdataty); override; + function lookuptext(const abm: bookmarkdataty): msestring; override; + function getlookupvaluefieldtypes: fieldtypesty; override; + published + property kind: datetimekindty read fkind write setkind default dtk_date; + property format: msestring read fformat write setformat; + property value: tdatetime read fvalue; + end; + +implementation +uses + msereal,sysutils; +type + tcustomdataedit1 = class(tcustomdataedit); + +{ tlookupdispfielddatalink } + +constructor tlookupdispfielddatalink.create(const aowner: tcustomdataedit; + const adatatype: lookupdatatypety; + const intf: idblookupdispfieldlink); +begin + fowner:= aowner; + fdatatype:= adatatype; + fisnull:= true; + inherited create(intf); +end; + +procedure tlookupdispfielddatalink.setwidgetdatasource(const avalue: tdatasource); +begin + if not ((csloading in fowner.componentstate) and datasourcefixed or + (fowner.gridintf <> nil)) then begin + inherited datasource:= avalue; + end; +end; + +procedure tlookupdispfielddatalink.griddatasourcechanged; +var + dso1: tdatasource; +begin + with fowner do begin + dso1:= tcustomdbwidgetgrid(gridintf.getcol.grid).datalink.datasource; + end; + if dso1 <> datasource then begin + inherited datasource:= dso1; + end; +end; + +function tlookupdispfielddatalink.getdatasource1: tdatasource; +begin + result:= inherited datasource; +end; + +procedure tlookupdispfielddatalink.lookupchange; +begin + if not (csloading in fowner.componentstate) and active and + (field <> nil) then begin + idblookupdispfieldlink(fintf).formatchanged; + idblookupdispfieldlink(fintf).fieldtovalue; + end; +end; + +function tlookupdispfielddatalink.msedisplaytext(const aformat: msestring = ''; + const aedit: boolean = false): msestring; +var + i1: int32; + li1: int64; + s1: msestring; +begin + if fowner <> nil then begin + result:= ''; + if (field <> nil) and not field.isnull then begin + case fdatatype of + ldt_int32: begin + i1:= field.asinteger; + result:= tcustomdataedit1(fowner).internaldatatotext(i1); + end; + ldt_int64: begin + li1:= field.aslargeint; + result:= tcustomdataedit1(fowner).internaldatatotext(li1); + end; + ldt_string: begin + s1:= field.asunicodestring; + result:= tcustomdataedit1(fowner).internaldatatotext(s1); + end; + end; + end; + end + else begin + result:= inherited msedisplaytext(aformat,aedit); + end; +end; + +{ tdblookup1 } + +constructor tdblookup1.create(aowner: tcomponent); +begin + if fdatalink = nil then begin + fdatalink:= createdatalink; + end; + inherited; + foptionsedit:= defaultlookupoptionsedit; +end; + +destructor tdblookup1.destroy; +begin + inherited; + fdatalink.free; +end; + +function tdblookup1.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit + [oe_readonly]; +end; + +procedure tdblookup1.setnullvalue; +begin + inherited; + fdatalink.fisnull:= true; + changed; +end; + +procedure tdblookup1.texttovalue(var accept: boolean; const quiet: boolean); +begin + fdatalink.fisnull:= text = ''; +end; + +procedure tdblookup1.valuetofield; +begin + //dummy +end; + +procedure tdblookup1.griddatasourcechanged; +begin + fdatalink.griddatasourcechanged; +end; + +function tdblookup1.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= nil; +end; + +procedure tdblookup1.setdatalink(const avalue: tlookupdispfielddatalink); +begin + fdatalink.assign(avalue); +end; + +procedure tdblookup1.recchanged; +begin + fdatalink.recordchanged(nil); +end; + +function tdblookup1.getdatalistclass: datalistclassty; +begin + result:= tnonedatalist; +end; + +procedure tdblookup1.valuetogrid(row: integer); +begin + //dummy +end; + +procedure tdblookup1.refreshfieldvalue; +begin + valuetotext; + changed; +end; + +procedure tdblookup1.fieldtovalue; +begin + fdatalink.fieldtovalue; + exclude(fstate,des_dbnull); + refreshfieldvalue; +end; + +procedure tdblookup1.getfieldtypes(var afieldtypes: fieldtypesty); +begin + //dummy +end; + +procedure tdblookup1.dochange; +begin + fdatalink.updatelookupvalue; + inherited; +end; + +function tdblookup1.internaldatatotext(const data): msestring; +begin + result:= fdatalink.datatotext(data); +end; + +function tdblookup1.getisnull: boolean; +begin + result:= fdatalink.fisnull; +end; + +function tdblookup1.getrowdatapo(const arow: integer): pointer; +begin + if fgriddatalink <> nil then begin + result:= fdatalink.getrowdatapo(tgriddatalink(fgriddatalink),arow); + end + else begin + result:= nil; + end; +end; + +function tdblookup1.getfieldlink: tdispfielddatalink; +begin + result:= fdatalink; +end; + +{ tdblookuplb } + +{ tdblookup32lb } + +procedure tdblookup32lb.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= integerfields; +end; + +function tdblookup32lb.createdatalink: tlookupdispfielddatalink; +begin + result:= tlookup32lbdispfielddatalink.create(self,ldt_int32, + idblookuplbdispfieldlink(self)); +end; + +procedure tdblookup64lb.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= integerfields; +end; + +function tdblookup64lb.createdatalink: tlookupdispfielddatalink; +begin + result:= tlookup64lbdispfielddatalink.create(self,ldt_int64, + idblookuplbdispfieldlink(self)); +end; + +procedure tdblookupstrlb.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= textfields; +end; + +function tdblookupstrlb.createdatalink: tlookupdispfielddatalink; +begin + result:= tlookupstrlbdispfielddatalink.create(self,ldt_string, + idblookuplbdispfieldlink(self)); +end; + +{ tdbstringlookuplb } + +procedure tdbstringlookuplb.setlookupvalue(const aindex: integer); +begin + if aindex < 0 then begin + fvalue:= ''; + end + else begin + with tlookuplbdispfielddatalink(fdatalink) do begin + fvalue:= flookupbuffer.textvaluephys(flookupvaluefieldno,aindex); + end; + end; +end; + +function tdbstringlookuplb.lookuptext(const aindex: integer): msestring; +begin + with tlookuplbdispfielddatalink(fdatalink) do begin + result:= flookupbuffer.textvaluephys(flookupvaluefieldno,aindex); + end; +end; + +function tdbstringlookuplb.getdatalbdatakind: lbdatakindty; +begin + result:= lbdk_text; +end; + +{ tdbstringlookupdb } + +procedure tdbstringlookupdb.setlookupvalue(const abm: bookmarkdataty); +begin + fvalue:= tlookupdbdispfielddatalink(fdatalink).getstringlookupvalue(abm); +end; + +function tdbstringlookupdb.lookuptext(const abm: bookmarkdataty): msestring; +begin + result:= tlookupdbdispfielddatalink(fdatalink).getstringlookupvalue(abm); +end; + +function tdbstringlookupdb.getlookupvaluefieldtypes: fieldtypesty; +begin + result:= charfields; +end; + +{ tdbstringlookup64db } + +procedure tdbstringlookup64db.setlookupvalue(const abm: bookmarkdataty); +begin + fvalue:= tlookupdbdispfielddatalink(fdatalink).getstringlookupvalue(abm); +end; + +function tdbstringlookup64db.lookuptext(const abm: bookmarkdataty): msestring; +begin + result:= tlookupdbdispfielddatalink(fdatalink).getstringlookupvalue(abm); +end; + +function tdbstringlookup64db.getlookupvaluefieldtypes: fieldtypesty; +begin + result:= charfields; +end; + +{ tdbstringlookupstrdb } + +procedure tdbstringlookupstrdb.setlookupvalue(const abm: bookmarkdataty); +begin + fvalue:= tlookupdbdispfielddatalink(fdatalink).getstringlookupvalue(abm); +end; + +function tdbstringlookupstrdb.lookuptext(const abm: bookmarkdataty): msestring; +begin + result:= tlookupdbdispfielddatalink(fdatalink).getstringlookupvalue(abm); +end; + +function tdbstringlookupstrdb.getlookupvaluefieldtypes: fieldtypesty; +begin + result:= charfields; +end; + +{ tdbintegerlookuplb } + +constructor tdbintegerlookuplb.create(aaowner: tcomponent); +begin + fbase:= nb_dec; + fbitcount:= 32; + inherited; +end; + +procedure tdbintegerlookuplb.setlookupvalue(const aindex: integer); +begin + if aindex < 0 then begin + fvalue:= 0; + end + else begin + with tlookuplbdispfielddatalink(fdatalink) do begin + fvalue:= flookupbuffer.integervaluephys(flookupvaluefieldno,aindex); + end; + end; +end; + +function tdbintegerlookuplb.lookuptext(const aindex: integer): msestring; +begin + with tlookuplbdispfielddatalink(fdatalink) do begin + result:= msestring(intvaluetostr(flookupbuffer.integervaluephys( + flookupvaluefieldno,aindex),fbase,fbitcount)); + end; +end; + +procedure tdbintegerlookuplb.setbase(const avalue: numbasety); +begin + if fbase <> avalue then begin + fbase := avalue; + formatchanged; + end; +end; + +procedure tdbintegerlookuplb.setbitcount(const avalue: integer); +begin + if fbitcount <> avalue then begin + fbitcount := avalue; + formatchanged; + end; +end; + +function tdbintegerlookuplb.getdatalbdatakind: lbdatakindty; +begin + result:= lbdk_integer; +end; + +{ tdbintegerlookupdb } + +constructor tdbintegerlookupdb.create(aaowner: tcomponent); +begin + fbase:= nb_dec; + fbitcount:= 32; + inherited; +end; + +procedure tdbintegerlookupdb.setlookupvalue(const abm: bookmarkdataty); +begin + fvalue:= tlookupdbdispfielddatalink(fdatalink).getintegerlookupvalue(abm); +end; + +function tdbintegerlookupdb.lookuptext(const abm: bookmarkdataty): msestring; +begin + result:= msestring(intvaluetostr( + tlookupdbdispfielddatalink(fdatalink).getintegerlookupvalue(abm), + fbase,fbitcount)); +end; + +procedure tdbintegerlookupdb.setbase(const avalue: numbasety); +begin + if fbase <> avalue then begin + fbase := avalue; + formatchanged; + end; +end; + +procedure tdbintegerlookupdb.setbitcount(const avalue: integer); +begin + if fbitcount <> avalue then begin + fbitcount := avalue; + formatchanged; + end; +end; + +function tdbintegerlookupdb.getlookupvaluefieldtypes: fieldtypesty; +begin + result:= int32fields; +end; + +{ tdbintegerlookup64db } + +constructor tdbintegerlookup64db.create(aaowner: tcomponent); +begin + fbase:= nb_dec; + fbitcount:= 32; + inherited; +end; + +procedure tdbintegerlookup64db.setlookupvalue(const abm: bookmarkdataty); +begin + fvalue:= tlookupdbdispfielddatalink(fdatalink).getintegerlookupvalue(abm); +end; + +function tdbintegerlookup64db.lookuptext(const abm: bookmarkdataty): msestring; +begin + result:= msestring(intvaluetostr( + tlookupdbdispfielddatalink(fdatalink).getintegerlookupvalue(abm), + fbase,fbitcount)); +end; + +procedure tdbintegerlookup64db.setbase(const avalue: numbasety); +begin + if fbase <> avalue then begin + fbase := avalue; + formatchanged; + end; +end; + +procedure tdbintegerlookup64db.setbitcount(const avalue: integer); +begin + if fbitcount <> avalue then begin + fbitcount := avalue; + formatchanged; + end; +end; + +function tdbintegerlookup64db.getlookupvaluefieldtypes: fieldtypesty; +begin + result:= int32fields; +end; + +{ tdbintegerlookupstrdb } + +constructor tdbintegerlookupstrdb.create(aaowner: tcomponent); +begin + fbase:= nb_dec; + fbitcount:= 32; + inherited; +end; + +procedure tdbintegerlookupstrdb.setlookupvalue(const abm: bookmarkdataty); +begin + fvalue:= tlookupdbdispfielddatalink(fdatalink).getintegerlookupvalue(abm); +end; + +function tdbintegerlookupstrdb.lookuptext(const abm: bookmarkdataty): msestring; +begin + result:= msestring(intvaluetostr( + tlookupdbdispfielddatalink(fdatalink).getintegerlookupvalue(abm), + fbase,fbitcount)); +end; + +procedure tdbintegerlookupstrdb.setbase(const avalue: numbasety); +begin + if fbase <> avalue then begin + fbase := avalue; + formatchanged; + end; +end; + +procedure tdbintegerlookupstrdb.setbitcount(const avalue: integer); +begin + if fbitcount <> avalue then begin + fbitcount := avalue; + formatchanged; + end; +end; + +function tdbintegerlookupstrdb.getlookupvaluefieldtypes: fieldtypesty; +begin + result:= int32fields; +end; + +{ tdbreallookuplb } + +constructor tdbreallookuplb.create(aowner: tcomponent); +begin + fvaluerange:= 1; + inherited; +end; + +procedure tdbreallookuplb.setformat(const avalue: msestring); +begin + fformat:= avalue; + formatchanged; +end; + +procedure tdbreallookuplb.setlookupvalue(const aindex: integer); +begin + if aindex < 0 then begin + fvalue:= emptyreal; + end + else begin + with tlookuplbdispfielddatalink(fdatalink) do begin + fvalue:= reapplyrange(flookupbuffer.floatvaluephys( + flookupvaluefieldno,aindex),valuerange,valuestart); + end; + end; +end; + +function tdbreallookuplb.lookuptext(const aindex: integer): msestring; +begin + with tlookuplbdispfielddatalink(fdatalink) do begin + result:= realtytostring(flookupbuffer.floatvaluephys( + flookupvaluefieldno,aindex),fformat); + end; +end; + +procedure tdbreallookuplb.setvaluerange(const avalue: real); +begin + fvaluerange:= avalue; + formatchanged; +end; + +procedure tdbreallookuplb.setvaluestart(const avalue: real); +begin + fvaluestart:= avalue; + formatchanged; +end; + +procedure tdbreallookuplb.readvaluescale(reader: treader); +begin + valuerange:= valuescaletorange(reader); +end; + +procedure tdbreallookuplb.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('valuescale',{$ifdef FPC}@{$endif}readvaluescale,nil,false); +end; + +function tdbreallookuplb.getdatalbdatakind: lbdatakindty; +begin + result:= lbdk_float; +end; + +{ tdbreallookupdb } + +constructor tdbreallookupdb.create(aowner: tcomponent); +begin + fvaluerange:= 1; + inherited; +end; + +procedure tdbreallookupdb.setformat(const avalue: msestring); +begin + fformat:= avalue; + formatchanged; +end; + +procedure tdbreallookupdb.setlookupvalue(const abm: bookmarkdataty); +begin + if abm.recordpo = nil then begin + fvalue:= emptyreal; + end + else begin + with tlookupdbdispfielddatalink(fdatalink) do begin + fvalue:= reapplyrange(getfloatlookupvalue(abm),valuerange,valuestart); + end; + end; +end; + +function tdbreallookupdb.lookuptext(const abm: bookmarkdataty): msestring; +begin + with tlookupdbdispfielddatalink(fdatalink) do begin + result:= realtytostring(getfloatlookupvalue(abm),fformat); + end; +end; + +procedure tdbreallookupdb.setvaluerange(const avalue: real); +begin + fvaluerange:= avalue; + formatchanged; +end; + +procedure tdbreallookupdb.setvaluestart(const avalue: real); +begin + fvaluestart:= avalue; + formatchanged; +end; + +function tdbreallookupdb.getlookupvaluefieldtypes: fieldtypesty; +begin + result:= doublefields; +end; + +{ tdbreallookup64db } + +constructor tdbreallookup64db.create(aowner: tcomponent); +begin + fvaluerange:= 1; + inherited; +end; + +procedure tdbreallookup64db.setformat(const avalue: msestring); +begin + fformat:= avalue; + formatchanged; +end; + +procedure tdbreallookup64db.setlookupvalue(const abm: bookmarkdataty); +begin + if abm.recordpo = nil then begin + fvalue:= emptyreal; + end + else begin + with tlookupdbdispfielddatalink(fdatalink) do begin + fvalue:= reapplyrange(getfloatlookupvalue(abm),valuerange,valuestart); + end; + end; +end; + +function tdbreallookup64db.lookuptext(const abm: bookmarkdataty): msestring; +begin + with tlookupdbdispfielddatalink(fdatalink) do begin + result:= realtytostring(getfloatlookupvalue(abm),fformat); + end; +end; + +procedure tdbreallookup64db.setvaluerange(const avalue: real); +begin + fvaluerange:= avalue; + formatchanged; +end; + +procedure tdbreallookup64db.setvaluestart(const avalue: real); +begin + fvaluestart:= avalue; + formatchanged; +end; + +function tdbreallookup64db.getlookupvaluefieldtypes: fieldtypesty; +begin + result:= doublefields; +end; + +{ tdbreallookupstrdb } + +constructor tdbreallookupstrdb.create(aowner: tcomponent); +begin + fvaluerange:= 1; + inherited; +end; + +procedure tdbreallookupstrdb.setformat(const avalue: msestring); +begin + fformat:= avalue; + formatchanged; +end; + +procedure tdbreallookupstrdb.setlookupvalue(const abm: bookmarkdataty); +begin + if abm.recordpo = nil then begin + fvalue:= emptyreal; + end + else begin + with tlookupdbdispfielddatalink(fdatalink) do begin + fvalue:= reapplyrange(getfloatlookupvalue(abm),valuerange,valuestart); + end; + end; +end; + +function tdbreallookupstrdb.lookuptext(const abm: bookmarkdataty): msestring; +begin + with tlookupdbdispfielddatalink(fdatalink) do begin + result:= realtytostring(getfloatlookupvalue(abm),fformat); + end; +end; + +procedure tdbreallookupstrdb.setvaluerange(const avalue: real); +begin + fvaluerange:= avalue; + formatchanged; +end; + +procedure tdbreallookupstrdb.setvaluestart(const avalue: real); +begin + fvaluestart:= avalue; + formatchanged; +end; + +function tdbreallookupstrdb.getlookupvaluefieldtypes: fieldtypesty; +begin + result:= doublefields; +end; + +{ tdatetimelookuplb } + +procedure tdbdatetimelookuplb.setformat(const avalue: msestring); +begin + format:= avalue; + formatchanged; +end; + +procedure tdbdatetimelookuplb.setlookupvalue(const aindex: integer); +begin + if aindex < 0 then begin + fvalue:= emptydatetime; + end + else begin + with tlookuplbdispfielddatalink(fdatalink) do begin + fvalue:= flookupbuffer.floatvaluephys(flookupvaluefieldno,aindex); + end; + end; +end; + +function tdbdatetimelookuplb.lookuptext(const aindex: integer): msestring; +var + dat1: tdatetime; +begin + with tlookuplbdispfielddatalink(fdatalink) do begin + dat1:= flookupbuffer.floatvaluephys(flookupvaluefieldno,aindex); + end; + if fkind = dtk_time then begin + result:= mseformatstr.timetostring(dat1,fformat); + end + else begin + result:= mseformatstr.datetimetostring(dat1,fformat); + end; +end; + +procedure tdbdatetimelookuplb.setkind(const avalue: datetimekindty); +begin + if fkind <> avalue then begin + fkind:= avalue; + formatchanged; + end; +end; + +function tdbdatetimelookuplb.getdatalbdatakind: lbdatakindty; +begin + result:= lbdk_float; +end; + +{ tdatetimelookupdb } + +procedure tdbdatetimelookupdb.setformat(const avalue: msestring); +begin + format:= avalue; + formatchanged; +end; + +procedure tdbdatetimelookupdb.setlookupvalue(const abm: bookmarkdataty); +begin + if abm.recordpo = nil then begin + fvalue:= emptydatetime; + end + else begin + with tlookupdbdispfielddatalink(fdatalink) do begin + fvalue:= getfloatlookupvalue(abm); + end; + end; +end; + +function tdbdatetimelookupdb.lookuptext(const abm: bookmarkdataty): msestring; +var + dat1: tdatetime; +begin + with tlookupdbdispfielddatalink(fdatalink) do begin + dat1:= getfloatlookupvalue(abm); + end; + if fkind = dtk_time then begin + result:= mseformatstr.timetostring(dat1,fformat); + end + else begin + result:= mseformatstr.datetimetostring(dat1,fformat); + end; +end; + +procedure tdbdatetimelookupdb.setkind(const avalue: datetimekindty); +begin + if fkind <> avalue then begin + fkind:= avalue; + formatchanged; + end; +end; + +function tdbdatetimelookupdb.getlookupvaluefieldtypes: fieldtypesty; +begin + result:= datetimefields; +end; + +{ tdatetimelookup64db } + +procedure tdbdatetimelookup64db.setformat(const avalue: msestring); +begin + format:= avalue; + formatchanged; +end; + +procedure tdbdatetimelookup64db.setlookupvalue(const abm: bookmarkdataty); +begin + if abm.recordpo = nil then begin + fvalue:= emptydatetime; + end + else begin + with tlookupdbdispfielddatalink(fdatalink) do begin + fvalue:= getfloatlookupvalue(abm); + end; + end; +end; + +function tdbdatetimelookup64db.lookuptext(const abm: bookmarkdataty): msestring; +var + dat1: tdatetime; +begin + with tlookupdbdispfielddatalink(fdatalink) do begin + dat1:= getfloatlookupvalue(abm); + end; + if fkind = dtk_time then begin + result:= mseformatstr.timetostring(dat1,fformat); + end + else begin + result:= mseformatstr.datetimetostring(dat1,fformat); + end; +end; + +procedure tdbdatetimelookup64db.setkind(const avalue: datetimekindty); +begin + if fkind <> avalue then begin + fkind:= avalue; + formatchanged; + end; +end; + +function tdbdatetimelookup64db.getlookupvaluefieldtypes: fieldtypesty; +begin + result:= datetimefields; +end; + +{ tdatetimelookupstrdb } + +procedure tdbdatetimelookupstrdb.setformat(const avalue: msestring); +begin + format:= avalue; + formatchanged; +end; + +procedure tdbdatetimelookupstrdb.setlookupvalue(const abm: bookmarkdataty); +begin + if abm.recordpo = nil then begin + fvalue:= emptydatetime; + end + else begin + with tlookupdbdispfielddatalink(fdatalink) do begin + fvalue:= getfloatlookupvalue(abm); + end; + end; +end; + +function tdbdatetimelookupstrdb.lookuptext(const abm: bookmarkdataty): msestring; +var + dat1: tdatetime; +begin + with tlookupdbdispfielddatalink(fdatalink) do begin + dat1:= getfloatlookupvalue(abm); + end; + if fkind = dtk_time then begin + result:= mseformatstr.timetostring(dat1,fformat); + end + else begin + result:= mseformatstr.datetimetostring(dat1,fformat); + end; +end; + +procedure tdbdatetimelookupstrdb.setkind(const avalue: datetimekindty); +begin + if fkind <> avalue then begin + fkind:= avalue; + formatchanged; + end; +end; + +function tdbdatetimelookupstrdb.getlookupvaluefieldtypes: fieldtypesty; +begin + result:= datetimefields; +end; + +{ tdbstringlookup64lb } + +procedure tdbstringlookup64lb.setlookupvalue(const aindex: integer); +begin + if aindex < 0 then begin + fvalue:= ''; + end + else begin + with tlookuplbdispfielddatalink(fdatalink) do begin + fvalue:= flookupbuffer.textvaluephys(flookupvaluefieldno,aindex); + end; + end; +end; + +function tdbstringlookup64lb.lookuptext(const aindex: integer): msestring; +begin + with tlookuplbdispfielddatalink(fdatalink) do begin + result:= flookupbuffer.textvaluephys(flookupvaluefieldno,aindex); + end; +end; + +function tdbstringlookup64lb.getdatalbdatakind: lbdatakindty; +begin + result:= lbdk_text; +end; + +{ tdbintegerlookup64lb } + +constructor tdbintegerlookup64lb.create(aaowner: tcomponent); +begin + fbase:= nb_dec; + fbitcount:= 32; + inherited; +end; + +procedure tdbintegerlookup64lb.setlookupvalue(const aindex: integer); +begin + if aindex < 0 then begin + fvalue:= 0; + end + else begin + with tlookuplbdispfielddatalink(fdatalink) do begin + fvalue:= flookupbuffer.integervaluephys(flookupvaluefieldno,aindex); + end; + end; +end; + +function tdbintegerlookup64lb.lookuptext(const aindex: integer): msestring; +begin + with tlookuplbdispfielddatalink(fdatalink) do begin + result:= msestring(intvaluetostr(flookupbuffer.integervaluephys( + flookupvaluefieldno,aindex),fbase,fbitcount)); + end; +end; + +procedure tdbintegerlookup64lb.setbase(const avalue: numbasety); +begin + if fbase <> avalue then begin + fbase := avalue; + formatchanged; + end; +end; + +procedure tdbintegerlookup64lb.setbitcount(const avalue: integer); +begin + if fbitcount <> avalue then begin + fbitcount := avalue; + formatchanged; + end; +end; + +function tdbintegerlookup64lb.getdatalbdatakind: lbdatakindty; +begin + result:= lbdk_integer; +end; + +{ tdbreallookup64lb } + +constructor tdbreallookup64lb.create(aowner: tcomponent); +begin + fvaluerange:= 1; + inherited; +end; + +procedure tdbreallookup64lb.setformat(const avalue: msestring); +begin + fformat:= avalue; + formatchanged; +end; + +procedure tdbreallookup64lb.setlookupvalue(const aindex: integer); +begin + if aindex < 0 then begin + fvalue:= emptyreal; + end + else begin + with tlookuplbdispfielddatalink(fdatalink) do begin + fvalue:= reapplyrange(flookupbuffer.floatvaluephys(flookupvaluefieldno,aindex), + valuerange,valuestart); + end; + end; +end; + +function tdbreallookup64lb.lookuptext(const aindex: integer): msestring; +begin + with tlookuplbdispfielddatalink(fdatalink) do begin + result:= realtytostring(flookupbuffer.floatvaluephys(flookupvaluefieldno,aindex), + fformat); + end; +end; + +procedure tdbreallookup64lb.setvaluerange(const avalue: real); +begin + fvaluerange:= avalue; + formatchanged; +end; + +procedure tdbreallookup64lb.setvaluestart(const avalue: real); +begin + fvaluestart:= avalue; + formatchanged; +end; + +procedure tdbreallookup64lb.readvaluescale(reader: treader); +begin + valuerange:= valuescaletorange(reader); +end; + +procedure tdbreallookup64lb.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('valuescale',{$ifdef FPC}@{$endif}readvaluescale,nil,false); +end; + + +function tdbreallookup64lb.getdatalbdatakind: lbdatakindty; +begin + result:= lbdk_float; +end; + +{ tdatetimelookup64lb } + +procedure tdbdatetimelookup64lb.setformat(const avalue: msestring); +begin + format:= avalue; + formatchanged; +end; + +procedure tdbdatetimelookup64lb.setlookupvalue(const aindex: integer); +begin + if aindex < 0 then begin + fvalue:= emptydatetime; + end + else begin + with tlookuplbdispfielddatalink(fdatalink) do begin + fvalue:= flookupbuffer.floatvaluephys(flookupvaluefieldno,aindex); + end; + end; +end; + +function tdbdatetimelookup64lb.lookuptext(const aindex: integer): msestring; +var + dat1: tdatetime; +begin + with tlookuplbdispfielddatalink(fdatalink) do begin + dat1:= flookupbuffer.floatvaluephys(flookupvaluefieldno,aindex); + end; + if fkind = dtk_time then begin + result:= mseformatstr.timetostring(dat1,fformat); + end + else begin + result:= mseformatstr.datetimetostring(dat1,fformat); + end; +end; + +procedure tdbdatetimelookup64lb.setkind(const avalue: datetimekindty); +begin + if fkind <> avalue then begin + fkind:= avalue; + formatchanged; + end; +end; + +function tdbdatetimelookup64lb.getdatalbdatakind: lbdatakindty; +begin + result:= lbdk_float; +end; + +{ tdbstringlookupstrlb } + +function tdbstringlookupstrlb.lookuptext(const aindex: integer): msestring; +begin + with tlookuplbdispfielddatalink(fdatalink) do begin + result:= flookupbuffer.textvaluephys(flookupvaluefieldno,aindex); + end; +end; + +procedure tdbstringlookupstrlb.setlookupvalue(const aindex: integer); +begin + if aindex < 0 then begin + fvalue:= ''; + end + else begin + with tlookuplbdispfielddatalink(fdatalink) do begin + fvalue:= flookupbuffer.textvaluephys(flookupvaluefieldno,aindex); + end; + end; +end; + +function tdbstringlookupstrlb.getdatalbdatakind: lbdatakindty; +begin + result:= lbdk_text; +end; + +{ tdbintegerlookupstrlb } + +constructor tdbintegerlookupstrlb.create(aaowner: tcomponent); +begin + fbase:= nb_dec; + fbitcount:= 32; + inherited; +end; + +procedure tdbintegerlookupstrlb.setlookupvalue(const aindex: integer); +begin + if aindex < 0 then begin + fvalue:= 0; + end + else begin + with tlookuplbdispfielddatalink(fdatalink) do begin + fvalue:= flookupbuffer.integervaluephys(flookupvaluefieldno,aindex); + end; + end; +end; + +function tdbintegerlookupstrlb.lookuptext(const aindex: integer): msestring; +begin + with tlookuplbdispfielddatalink(fdatalink) do begin + result:= msestring(intvaluetostr(flookupbuffer.integervaluephys( + flookupvaluefieldno,aindex),fbase,fbitcount)); + end; +end; + +procedure tdbintegerlookupstrlb.setbase(const avalue: numbasety); +begin + if fbase <> avalue then begin + fbase := avalue; + formatchanged; + end; +end; + +procedure tdbintegerlookupstrlb.setbitcount(const avalue: integer); +begin + if fbitcount <> avalue then begin + fbitcount := avalue; + formatchanged; + end; +end; + +function tdbintegerlookupstrlb.getdatalbdatakind: lbdatakindty; +begin + result:= lbdk_integer; +end; + +{ tdbreallookupstrlb } + +constructor tdbreallookupstrlb.create(aowner: tcomponent); +begin + fvaluerange:= 1; + inherited; +end; + +procedure tdbreallookupstrlb.setformat(const avalue: msestring); +begin + fformat:= avalue; + formatchanged; +end; + +procedure tdbreallookupstrlb.setlookupvalue(const aindex: integer); +begin + if aindex < 0 then begin + fvalue:= emptyreal; + end + else begin + with tlookuplbdispfielddatalink(fdatalink) do begin + fvalue:= reapplyrange(flookupbuffer.floatvaluephys(flookupvaluefieldno,aindex), + valuerange,valuestart); + end; + end; +end; + +function tdbreallookupstrlb.lookuptext(const aindex: integer): msestring; +begin + with tlookuplbdispfielddatalink(fdatalink) do begin + result:= realtytostring(flookupbuffer.floatvaluephys(flookupvaluefieldno,aindex), + fformat); + end; +end; + +procedure tdbreallookupstrlb.setvaluerange(const avalue: real); +begin + fvaluerange:= avalue; + formatchanged; +end; + +procedure tdbreallookupstrlb.setvaluestart(const avalue: real); +begin + fvaluestart:= avalue; + formatchanged; +end; + +procedure tdbreallookupstrlb.readvaluescale(reader: treader); +begin + valuerange:= valuescaletorange(reader); +end; + +procedure tdbreallookupstrlb.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('valuescale',{$ifdef FPC}@{$endif}readvaluescale,nil,false); +end; + +function tdbreallookupstrlb.getdatalbdatakind: lbdatakindty; +begin + result:= lbdk_float; +end; + +{ tdatetimelookupstrlb } + +procedure tdbdatetimelookupstrlb.setformat(const avalue: msestring); +begin + format:= avalue; + formatchanged; +end; + +procedure tdbdatetimelookupstrlb.setlookupvalue(const aindex: integer); +begin + if aindex < 0 then begin + fvalue:= emptydatetime; + end + else begin + with tlookuplbdispfielddatalink(fdatalink) do begin + fvalue:= flookupbuffer.floatvaluephys(flookupvaluefieldno,aindex); + end; + end; +end; + +function tdbdatetimelookupstrlb.lookuptext(const aindex: integer): msestring; +var + dat1: tdatetime; +begin + with tlookuplbdispfielddatalink(fdatalink) do begin + dat1:= flookupbuffer.floatvaluephys(flookupvaluefieldno,aindex); + end; + if fkind = dtk_time then begin + result:= mseformatstr.timetostring(dat1,fformat); + end + else begin + result:= mseformatstr.datetimetostring(dat1,fformat); + end; +end; + +procedure tdbdatetimelookupstrlb.setkind(const avalue: datetimekindty); +begin + if fkind <> avalue then begin + fkind:= avalue; + formatchanged; + end; +end; + +function tdbdatetimelookupstrlb.getdatalbdatakind: lbdatakindty; +begin + result:= lbdk_float; +end; + +{ tdblookupdb } +{ +constructor tdblookupdb.create(aowner: tcomponent); +begin + inherited; +end; +} +function tdblookupdb.getdatalink: tlookupdbdispfielddatalink; +begin + result:= tlookupdbdispfielddatalink(fdatalink); +end; + +procedure tdblookupdb.setdatalink(const avalue: tlookupdbdispfielddatalink); +begin + inherited setdatalink(avalue); +end; + +{ tlookupdatalink } + +procedure tlookupdatalink.updatefields; +var + int1: integer; +begin + inherited; + fcanlookup:= false; + if active and (fkeyfieldname <> '') then begin + fkeyfield:= datasource.dataset.fieldbyname(fkeyfieldname); + flookupindexnum:= -1; + if dataset is tmsebufdataset then begin + with tmsebufdataset(dataset).indexlocal do begin + for int1:= 0 to count-1 do begin + with items[int1] do begin + if (fields.count > 0) and + sametext(fields[0].fieldname,fkeyfieldname) then begin + flookupindexnum:= int1; + break; + end; + end; + end; + end; + end; + if flookupindexnum < 0 then begin + databaseerror(dataset.name+': no loookup index for keyfield "'+ + fkeyfield.fieldname+'".'); + end; + fcanlookup:= true; + end + else begin + fkeyfield:= nil; + end; +end; + +procedure tlookupdatalink.activechanged; +begin + if not active then begin + fcanlookup:= false; + end; + inherited; + fdisplink.lookupchange; +end; + +procedure tlookupdatalink.dataevent(event: tdataevent; info: ptrint); +begin + inherited; + if event = tdataevent(de_modified) then begin + fdisplink.lookupchange; + end; +end; + +procedure tlookupdatalink.fieldchanged; +begin + inherited; + fdisplink.lookupchange; +end; + +{ tlookupdbdispfielddatalink } + +constructor tlookupdbdispfielddatalink.create( + const aowner: tcustomdataedit; const adatatype: lookupdatatypety; + const intf: idblookupdbdispfieldlink); +begin + flookupdatalink:= tlookupdatalink.create; + flookupdatalink.fdisplink:= self; + inherited create(aowner,adatatype,intf); +end; + +destructor tlookupdbdispfielddatalink.destroy; +begin + flookupdatalink.free; + inherited; +end; + +procedure tlookupdbdispfielddatalink.setlookupkeyfield(const avalue: string); +begin + with flookupdatalink do begin + if fkeyfieldname <> avalue then begin + fkeyfieldname:= avalue; + updatefields; + lookupchange; + end; + end; +end; + +procedure tlookupdbdispfielddatalink.setlookupvaluefield(const avalue: string); +begin + flookupdatalink.fieldname:= avalue; +end; + +function tlookupdbdispfielddatalink.getlookupkeyfield: string; +begin + result:= flookupdatalink.fkeyfieldname; +end; + +function tlookupdbdispfielddatalink.getlookupvaluefield: string; +begin + result:= flookupdatalink.fieldname; +end; + +function tlookupdbdispfielddatalink.getlookupdatasource: tdatasource; +begin + result:= flookupdatalink.datasource; +end; + +procedure tlookupdbdispfielddatalink.setlookupdatasource(const avalue: tdatasource); +begin + flookupdatalink.datasource:= avalue; +end; + +function tlookupdbdispfielddatalink.getintegerlookupvalue( + const abm: bookmarkdataty): integer; +begin + result:= 0; + with flookupdatalink do begin + if (abm.recordpo <> nil) and fieldactive and fcanlookup then begin + result:= tmsebufdataset(dataset).currentbmasinteger[field,abm]; + end; + end; +end; + +function tlookupdbdispfielddatalink.getstringlookupvalue( + const abm: bookmarkdataty): msestring; +begin + result:= ''; + with flookupdatalink do begin + if (abm.recordpo <> nil) and fieldactive and fcanlookup then begin + result:= tmsebufdataset(dataset).currentbmasmsestring[field,abm]; + end; + end; +end; + +function tlookupdbdispfielddatalink.getfloatlookupvalue( + const abm: bookmarkdataty): double; +begin + result:= emptyreal; + with flookupdatalink do begin + if (abm.recordpo <> nil) and fieldactive and fcanlookup then begin + result:= tmsebufdataset(dataset).currentbmasfloat[field,abm]; + end; + end; +end; + +function tlookupdbdispfielddatalink.getdataset(const aindex: integer): tdataset; +begin + result:= nil; + case aindex of + 0: begin + result:= inherited getdataset(aindex); + end; + 1,2: begin + result:= flookupdatalink.dataset; + end; + end; +end; + +procedure tlookupdbdispfielddatalink.getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); +begin + inherited; + setlength(apropertynames,3); + apropertynames[1]:= 'lookupkeyfield'; + apropertynames[2]:= 'lookupvaluefield'; + setlength(afieldtypes,3); + afieldtypes[1]:= afieldtypes[0]; //same as datafield + afieldtypes[2]:= idblookupdbdispfieldlink(fintf).getlookupvaluefieldtypes; +end; + +{ tdblookup32db } + +procedure tdblookup32db.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= int32fields; +end; + +function tdblookup32db.createdatalink: tlookupdispfielddatalink; +begin + result:= tlookup32dbdispfielddatalink.create(self,ldt_int32, + idblookupdbdispfieldlink(self)); +end; + +{ tdblookup64db } + +procedure tdblookup64db.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= int64fields; +end; + +function tdblookup64db.createdatalink: tlookupdispfielddatalink; +begin + result:= tlookup64dbdispfielddatalink.create(self,ldt_int64, + idblookupdbdispfieldlink(self)); +end; + +{ tdblookupstrdb } + +procedure tdblookupstrdb.getfieldtypes(var afieldtypes: fieldtypesty); +begin + afieldtypes:= charfields; +end; + +function tdblookupstrdb.createdatalink: tlookupdispfielddatalink; +begin + result:= tlookupstrdbdispfielddatalink.create(self,ldt_string, + idblookupdbdispfieldlink(self)); +end; + +{ tdblookup } + +{ tlookup32dbdispfielddatalink } + +function tlookup32dbdispfielddatalink.datatotext(const data): msestring; + + procedure lookup(const akey: integer); + var + bm1: bookmarkdataty; + begin + result:= ''; + with flookupdatalink do begin + if fcanlookup and (field <> nil) and + tmsebufdataset(dataset).indexlocal[flookupindexnum]. + find([akey],[],bm1,false,false,true) then begin + result:= idblookupdbdispfieldlink(fintf).lookuptext(bm1); + end; + end; + end; //lookup + +begin + result:= ''; + if (@data = nil) and fisnull then begin + end + else begin + if @data = nil then begin + lookup(fkey); + end + else begin + lookup(integer(data)); + end; + end; +end; + +procedure tlookup32dbdispfielddatalink.updatelookupvalue; +var + bm1: bookmarkdataty; +begin + bm1.recordpo:= nil; + with flookupdatalink do begin + if fcanlookup then begin + if not tmsebufdataset(dataset).indexlocal[flookupindexnum]. + find([fkey],[],bm1,false,false,true) then begin + bm1.recordpo:= nil; + end; + end; + end; + idblookupdbdispfieldlink(fintf).setlookupvalue(bm1); +end; + +function tlookup32dbdispfielddatalink.getrowdatapo(const alink: tgriddatalink; + const arow: integer): pointer; +begin + result:= alink.getintegerbuffer(field,arow); +end; + +procedure tlookup32dbdispfielddatalink.fieldtovalue; +begin + fisnull:= false; + fkey:= field.asinteger; +end; + +{ tlookup64dbdispfielddatalink } + +function tlookup64dbdispfielddatalink.datatotext(const data): msestring; + + procedure lookup(const akey: int64); + var + bm1: bookmarkdataty; + begin + result:= ''; + with flookupdatalink do begin + if fcanlookup and (field <> nil) and + tmsebufdataset(dataset).indexlocal[flookupindexnum]. + find([akey],[],bm1,false,false,true) then begin + result:= idblookupdbdispfieldlink(fintf).lookuptext(bm1); + end; + end; + end; //lookup + +begin + result:= ''; + if (@data = nil) and fisnull then begin + end + else begin + if @data = nil then begin + lookup(fkey); + end + else begin + lookup(int64(data)); + end; + end; +end; + +procedure tlookup64dbdispfielddatalink.updatelookupvalue; +var + bm1: bookmarkdataty; +begin + bm1.recordpo:= nil; + with flookupdatalink do begin + if not fisnull and fcanlookup then begin + if not tmsebufdataset(dataset).indexlocal[flookupindexnum]. + find([fkey],[],bm1,false,false,true) then begin + bm1.recordpo:= nil; + end; + end; + end; + idblookupdbdispfieldlink(fintf).setlookupvalue(bm1); +end; + +function tlookup64dbdispfielddatalink.getrowdatapo(const alink: tgriddatalink; + const arow: integer): pointer; +begin + result:= alink.getint64buffer(field,arow); +end; + +procedure tlookup64dbdispfielddatalink.fieldtovalue; +begin + fisnull:= false; + fkey:= field.aslargeint; +end; + +{ tlookupstrdbdispfielddatalink } + +function tlookupstrdbdispfielddatalink.datatotext(const data): msestring; + + procedure lookup(const akey: msestring); + var + bm1: bookmarkdataty; + begin + result:= ''; + with flookupdatalink do begin + if fcanlookup and (field <> nil) and + tmsebufdataset(dataset).indexlocal[flookupindexnum]. + find([akey],[],bm1,false,false,true) then begin + result:= idblookupdbdispfieldlink(fintf).lookuptext(bm1); + end; + end; + end; //lookup + +begin + result:= ''; + if (@data = nil) and fisnull then begin + end + else begin + if @data = nil then begin + lookup(fkey); + end + else begin + lookup(msestring(data)); + end; + end; +end; + +procedure tlookupstrdbdispfielddatalink.updatelookupvalue; +var + bm1: bookmarkdataty; +begin + bm1.recordpo:= nil; + with flookupdatalink do begin + if not fisnull and fcanlookup then begin + if not tmsebufdataset(dataset).indexlocal[flookupindexnum]. + find([fkey],[],bm1,false,false,true) then begin + bm1.recordpo:= nil; + end; + end; + end; + idblookupdbdispfieldlink(fintf).setlookupvalue(bm1); +end; + +function tlookupstrdbdispfielddatalink.getrowdatapo(const alink: tgriddatalink; + const arow: integer): pointer; +begin + result:= alink.getstringbuffer(field,arow); +end; + +procedure tlookupstrdbdispfielddatalink.fieldtovalue; +begin + fisnull:= false; + fkey:= asmsestring; +end; + +{ tlookuplbdispfielddatalink } + +constructor tlookuplbdispfielddatalink.create(const aowner: tcustomdataedit; + const adatatype: lookupdatatypety; + const intf: idblookuplbdispfieldlink); +begin + fobjectlinker:= tobjectlinker.create(iobjectlink(self), + {$ifdef FPC}@{$endif}objectevent); + inherited create(aowner,adatatype,intf); +end; + +destructor tlookuplbdispfielddatalink.destroy; +begin + fobjectlinker.free; + inherited; +end; + +function tlookuplbdispfielddatalink.getlbdatakind(const apropname: string): lbdatakindty; +begin + if apropname = 'lookupkeyfieldno' then begin + result:= getkeylbdatakind; + end + else begin + result:= idblookuplbdispfieldlink(fintf).getdatalbdatakind; + end; +end; + +function tlookuplbdispfielddatalink.getlookupbuffer: tcustomlookupbuffer; +begin + result:= flookupbuffer; +end; + +procedure tlookuplbdispfielddatalink.setlookupbuffer(const avalue: tcustomlookupbuffer); +begin + if avalue <> flookupbuffer then begin + fobjectlinker.setlinkedvar(iobjectlink(self),avalue, + tmsecomponent(flookupbuffer)); + lookupchange; + end; +end; + +procedure tlookuplbdispfielddatalink.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (event in [oe_changed,oe_connect]) and (sender = flookupbuffer) then begin + lookupchange; + end; +end; + +procedure tlookuplbdispfielddatalink.link(const source: iobjectlink; + const dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); +begin + fobjectlinker.link(source,dest,valuepo,ainterfacetype,once); +end; + +procedure tlookuplbdispfielddatalink.unlink(const source: iobjectlink; + const dest: iobjectlink; valuepo: pointer = nil); +begin + fobjectlinker.unlink(source,dest,valuepo); +end; + +procedure tlookuplbdispfielddatalink.objevent(const sender: iobjectlink; + const event: objecteventty); +begin + fobjectlinker.objevent(sender,event); +end; + +function tlookuplbdispfielddatalink.getinstance: tobject; +begin + result:= self; +end; + +procedure tlookuplbdispfielddatalink.setlookupkeyfieldno(const avalue: lookupbufferfieldnoty); +begin + if flookupkeyfieldno <> avalue then begin + flookupkeyfieldno:= avalue; + lookupchange; + end; +end; + +procedure tlookuplbdispfielddatalink.setlookupvaluefieldno(const avalue: lookupbufferfieldnoty); +begin + if flookupvaluefieldno <> avalue then begin + flookupvaluefieldno:= avalue; + lookupchange; + end; +end; + +{ tlookup32lbdispfielddatalink } + +procedure tlookup32lbdispfielddatalink.updatelookupvalue; +var + int1: integer; +begin + int1:= -1; + if not fisnull and (flookupbuffer <> nil) then begin + flookupbuffer.findphys(flookupkeyfieldno,fkey,int1); + end; + idblookuplbdispfieldlink(fintf).setlookupvalue(int1); +end; + +function tlookup32lbdispfielddatalink.datatotext(const data): msestring; + + procedure lookup(const akey: integer); + var + int1: integer; + begin + result:= ''; + if flookupbuffer <> nil then begin + if flookupbuffer.findphys(flookupkeyfieldno,akey,int1) then begin + result:= idblookuplbdispfieldlink(fintf).lookuptext(int1); + end; + end; + end; //lookup + +begin + result:= ''; + if (@data = nil) and fisnull then begin + end + else begin + if @data = nil then begin + lookup(fkey); + end + else begin + lookup(integer(data)); + end; + end; +end; + +function tlookup32lbdispfielddatalink.getkeylbdatakind: lbdatakindty; +begin + result:= lbdk_integer; +end; + +procedure tlookup32lbdispfielddatalink.fieldtovalue; +begin + fisnull:= false; + fkey:= field.asinteger; +end; + +function tlookup32lbdispfielddatalink.getrowdatapo(const alink: tgriddatalink; + const arow: integer): pointer; +begin + result:= alink.getintegerbuffer(field,arow); +end; + +{ tlookup64lbdispfielddatalink } + +procedure tlookup64lbdispfielddatalink.updatelookupvalue; +var + int1: integer; +begin + int1:= -1; + if not fisnull and (flookupbuffer <> nil) then begin + flookupbuffer.findphys(flookupkeyfieldno,fkey,int1); + end; + idblookuplbdispfieldlink(fintf).setlookupvalue(int1); +end; + +function tlookup64lbdispfielddatalink.datatotext(const data): msestring; + + procedure lookup(const akey: int64); + var + int1: integer; + begin + result:= ''; + if flookupbuffer <> nil then begin + if flookupbuffer.findphys(flookupkeyfieldno,akey,int1) then begin + result:= idblookuplbdispfieldlink(fintf).lookuptext(int1); + end; + end; + end; //lookup + +begin + result:= ''; + if (@data = nil) and fisnull then begin + end + else begin + if @data = nil then begin + lookup(fkey); + end + else begin + lookup(int64(data)); + end; + end; +end; + +function tlookup64lbdispfielddatalink.getkeylbdatakind: lbdatakindty; +begin + result:= lbdk_int64; +end; + +procedure tlookup64lbdispfielddatalink.fieldtovalue; +begin + fisnull:= false; + fkey:= field.aslargeint; +end; + +function tlookup64lbdispfielddatalink.getrowdatapo(const alink: tgriddatalink; + const arow: integer): pointer; +begin + result:= alink.getint64buffer(field,arow); +end; + +{ tlookupstrlbdispfielddatalink } + +procedure tlookupstrlbdispfielddatalink.updatelookupvalue; +var + int1: integer; +begin + int1:= -1; + if not fisnull and (flookupbuffer <> nil) then begin + flookupbuffer.findphys(flookupkeyfieldno,fkey,int1,false); + end; + idblookuplbdispfieldlink(fintf).setlookupvalue(int1); +end; + +function tlookupstrlbdispfielddatalink.datatotext(const data): msestring; + + procedure lookup(const akey: msestring); + var + int1: integer; + begin + result:= ''; + if flookupbuffer <> nil then begin + if flookupbuffer.findphys(flookupkeyfieldno,akey,int1,true) then begin + result:= idblookuplbdispfieldlink(fintf).lookuptext(int1); + end; + end; + end; //lookup + +begin + result:= ''; + if (@data = nil) and fisnull then begin + end + else begin + if @data = nil then begin + lookup(fkey); + end + else begin + lookup(msestring(data)); + end; + end; +end; + +function tlookupstrlbdispfielddatalink.getkeylbdatakind: lbdatakindty; +begin + result:= lbdk_text; +end; + +procedure tlookupstrlbdispfielddatalink.fieldtovalue; +begin + fisnull:= false; + fkey:= asmsestring; +end; + +function tlookupstrlbdispfielddatalink.getrowdatapo(const alink: tgriddatalink; + const arow: integer): pointer; +begin + result:= alink.getstringbuffer(field,arow); +end; + +{ tdblookuplb } + +procedure tdblookuplb.readlookupkeyfieldno(reader: treader); +begin + tlookuplbdispfielddatalink(fdatalink).lookupkeyfieldno:= reader.readinteger; +end; + +procedure tdblookuplb.readlookupvaluefieldno(reader: treader); +begin + tlookuplbdispfielddatalink(fdatalink).lookupvaluefieldno:= reader.readinteger; +end; + +procedure tdblookuplb.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('lookupkeyfieldno', + {$ifdef FPC}@{$endif}readlookupkeyfieldno,nil,false); + filer.defineproperty('lookupvaluefieldno', + {$ifdef FPC}@{$endif}readlookupvaluefieldno,nil,false); +end; + + +function tdblookuplb.getlookupbuffer: tcustomlookupbuffer; +begin + result:= nil; +end; + +procedure tdblookuplb.setlookupbuffer(const avalue: tcustomlookupbuffer); +begin + tlookuplbdispfielddatalink(fdatalink).lookupbuffer:= avalue; +end; + +function tdblookuplb.getdatalink: tlookuplbdispfielddatalink; +begin + result:= tlookuplbdispfielddatalink(fdatalink); +end; + +procedure tdblookuplb.setdatalink(const avalue: tlookuplbdispfielddatalink); +begin + inherited setdatalink(avalue); +end; + +end. diff --git a/mseide-msegui/lib/common/db/msefb3connection.pas b/mseide-msegui/lib/common/db/msefb3connection.pas new file mode 100644 index 0000000..3ac8b52 --- /dev/null +++ b/mseide-msegui/lib/common/db/msefb3connection.pas @@ -0,0 +1,1981 @@ +{ MSEgui Copyright (c) 2016-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +// +// todo: - prepare-less execute and openCursor (needs FB-optimisation) +// - move dbcontroller interface to tcustomsqlconnection +// +unit msefb3connection; +{$ifdef FPC}{$mode objfpc}{$h+}{$goto on}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,firebird,msqldb,msestrings,msetypes,mdb,msedb,msedatabase, + sysutils,msefirebird,msedbevents,msesystypes; + +const + SQL_DIALECT_V6 = 3; + +type + pimessagemetadata = ^imessagemetadata; + + fbconnectionoptionty = (fbo_sqlinfo); + fbconnectionoptionsty = set of fbconnectionoptionty; + + tfb3connection = class; + + tfbtrans = class(tsqlhandle) + protected + fconnection: tfb3connection; + ftransaction: itransaction; + public + constructor create(const aconnection: tfb3connection); + destructor destroy(); override; + end; + + cursorstatety = (cs_hasstatement); + cursorstatesty = set of cursorstatety; + + pfbfieldinfoty = ^fbfieldinfoty; + fetchfuncty = procedure(const info: pfbfieldinfoty; const dest: pointer); + + tfbcursor = class; + + fbfieldinfoty = record + buffer: pointer; + name: string; + _type: card32; + scale: int32; + offset: card32; + nulloffset: int32; //-1 = none + fetchfunc: fetchfuncty; + _cursor: tfbcursor; + datatype: tfieldtype; + size: int32; +// precision: int32; + buffersizead: pint32; //temp + end; + + fbfieldinfoarty = array of fbfieldinfoty; + + tfbcursor = class(tsqlcursor) + protected + fconnection: tfb3connection; + fparambinding: tparambinding; + fstatement: istatement; + fstatementflags: card32; + fempty: boolean; + ffirstfetch: boolean; //set for execute() if there is outputdata + fresultset: iresultset; + fcursorstate: cursorstatesty; + ffieldinfos: fbfieldinfoarty; + frowbuffer: string; + public + constructor create(const aowner: icursorclient; + const aconnection: tfb3connection); + destructor destroy(); override; + procedure close() override; + end; + + fbeventinfoty = record + event: tdbevent; + name: string; + count: integer; + countbefore: card32; + end; + pfbeventinfoty = ^fbeventinfoty; + + tfbeventcallback = class(ieventcallbackimpl) + private + frefcount: int32; + protected + fowner: tfb3connection; + fmutex: mutexty; + ffired: boolean; + freleased: boolean; + public + constructor create(const aowner: tfb3connection); + destructor destroy(); override; + procedure addRef() override; + function release(): Integer override; + procedure eventCallbackFunction(length: Cardinal; events: BytePtr) override; + procedure destroylocked(); + procedure storestate(); //copy current event counts to feventitems + procedure queueevents(const first: boolean); //must be locked + end; + + paramblockkindty = (pbk_database,pbk_transaction); + paramblockvaluekindty = (pbvk_none,pbvk_int,pbvk_str); + paraminfoty = record + id: int32; + name: string; + valuekind: paramblockvaluekindty; + end; + pparaminfoty = ^paraminfoty; + + tfb3connection = class(tcustomsqlconnection,iblobconnection, + idbevent,idbeventcontroller) + private + fdialect: integer; + flasterrormessage: msestring; + flastsqlcode: int32; + foptions: fbconnectionoptionsty; + function getblobstream(const acursor: tsqlcursor; const blobid: isc_quad; + const forstring: boolean = false): tmemorystream; + function getblobstring(const acursor: tsqlcursor; + const blobid: isc_quad): string; + function getdatabasename: filenamety; + procedure setdatabasename(const avalue: filenamety); + function getconnected: boolean; reintroduce; + procedure setconnected(const avalue: boolean); reintroduce; + protected + fapi: fbapity; + fattachment: iattachment; + feventcallback: tfbeventcallback; + feventcontroller: tdbeventcontroller; + feventitems: array of fbeventinfoty; + fevents: ievents; + flistencount: int32; + feventcount: int32; + feventlength: int32; + feventbuffer: pbyte; + feventcountbuffer: array of ULONG; +// procedure iniapi(); +// procedure finiapi(); + function getpb(const akind: paramblockkindty): ixpbbuilder; + function buildpb(const akind: paramblockkindty; + const ainfo: pparaminfoty; const acount: int32; + const aparams: tstringlist; + const force: boolean): ixpbbuilder; + procedure clearstatus(); inline; + function statusok(): boolean; inline; + procedure checkstatus(const aerrormessage: msestring); + procedure dointernalconnect override; + procedure dointernaldisconnect override; + + function allocatetransactionhandle : tsqlhandle override; + function gettransactionhandle(trans : tsqlhandle): pointer override; + + function startdbtransaction(const trans : tsqlhandle; + const aparams : tstringlist) : boolean override; + function commit(trans : tsqlhandle) : boolean override; + function rollback(trans : tsqlhandle) : boolean override; + procedure internalcommitretaining(trans : tsqlhandle) override; + procedure internalrollbackretaining(trans : tsqlhandle) override; + + procedure cursorclose(const cursor: tfbcursor); + procedure updateresultmetadata(const acursor: tfbcursor; + const outmetadata: pimessagemetadata); + procedure internalexecute(const cursor: tsqlcursor; + const atransaction: tsqltransaction; const aparams : tmseparams; + const autf8: boolean) override; +{ not ready, needs FB3 improvement + procedure internalexecuteunprepared(const cursor: tsqlcursor; + const atransaction: tsqltransaction; + const asql: string; const origsql: msestring; + const aparams: tmseparams) override; +} + procedure updateindexdefs(var indexdefs : tindexdefs; + const atablename : string; const acursor: tsqlcursor) override; + function getschemainfosql(schematype : tschematype; + schemaobjectname, schemapattern : msestring) : msestring override; + + function createblobstream(const field: tfield; const mode: tblobstreammode; + const acursor: tsqlcursor): tstream; override; + function getblobdatasize: integer; override; + + procedure updateevents(const aerrormessage: msestring); + procedure clearevents(); + procedure loaded() override; + //idbcontroller + function readsequence(const sequencename: string): msestring override; + function sequencecurrvalue(const sequencename: string): msestring override; + function writesequence(const sequencename: string; + const avalue: largeint): msestring override; + //iblobconnection + procedure writeblobdata(const atransaction: tsqltransaction; + const tablename: string; const acursor: tsqlcursor; + const adata: pointer; const alength: integer; + const afield: tfield; const aparam: tparam; out newid: string); + overload; + procedure setupblobdata(const afield: tfield; const acursor: tsqlcursor; + const aparam: tparam); + //idbevent + procedure listen(const sender: tdbevent); + procedure unlisten(const sender: tdbevent); + procedure fire(const sender: tdbevent); + //idbeventcontroller + function getdbevent(var aname: string; var aid: int64): boolean; + //false if none + procedure dolisten(const sender: tdbevent); + procedure dounlisten(const sender: tdbevent); + //idbcontroller + public + constructor create(aowner: tcomponent); override; + destructor destroy(); override; + procedure createdatabase(const asql: ansistring); + function allocatecursorhandle(const aowner: icursorclient; + const aname: ansistring): tsqlcursor override; + procedure deallocatecursorhandle(var cursor : tsqlcursor) override; + procedure freefldbuffers(cursor : tsqlcursor); override; + procedure preparestatement(const cursor: tsqlcursor; + const atransaction : tsqltransaction; + const asql: msestring; const aparams : tmseparams) override; + procedure unpreparestatement(cursor : tsqlcursor) override; + procedure addfielddefs(const cursor: tsqlcursor; + const fielddefs : tfielddefs) override; + function fetch(cursor : tsqlcursor) : boolean; override; + function loadfield(const cursor: tsqlcursor; + const datatype: tfieldtype; const fieldnum: integer; //zero based + const buffer: pointer; var bufsize: integer; + const aisutf8: boolean): boolean; override; + //if bufsize < 0 -> buffer was to small, should be -bufsize + function fetchblob(const cursor: tsqlcursor; + const fieldnum: integer): ansistring; override; + //zero based + function version: msestring; + property lasterrormessage: msestring read flasterrormessage; + property lastsqlcode: int32 read flastsqlcode; + published + property dialect: integer read fdialect write fdialect + default sql_dialect_v6; + property options: fbconnectionoptionsty read foptions + write foptions default []; + property Transaction; + property transactionwrite; + property CharSet; + property HostName; + property controller; + property DatabaseName: filenamety read getdatabasename write setdatabasename; + property Connected: boolean read getconnected write setconnected default false; + property Password; + property UserName; + property Role; + property ongetcredentials; + property afterconnect; + property beforedisconnect; + end; + + efberror = class(econnectionerror) + private + fgdscode: ptrint; + public + constructor create(const asender: tfb3connection; + const astatus: istatus; const aerrormessage: msestring); + property gdscode: ptrint read fgdscode; + end; + +implementation +uses + dbconst,msefbinterface,msefbutils,msesqldb,msebufdataset,msedate,msefloattostr, + msebits,msesysintf1,msearrayutils,mseformatstr; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + textblobtypes = [ftmemo,ftwidememo]; + +{ tfbeventcallback } + +constructor tfbeventcallback.create(const aowner: tfb3connection); +begin + fowner:= aowner; + sys_mutexcreate(fmutex); + inherited create(); +end; + +destructor tfbeventcallback.destroy(); +begin + inherited; + sys_mutexdestroy(fmutex); +end; + +procedure tfbeventcallback.addRef(); +begin + sys_mutexlock(fmutex); + inc(frefcount); + sys_mutexunlock(fmutex); +end; + +function tfbeventcallback.release(): Integer; +begin + sys_mutexlock(fmutex); + dec(frefcount); + result:= frefcount; + if frefcount = 0 then begin + destroy(); + exit; + end; + sys_mutexunlock(fmutex); +end; + +procedure tfbeventcallback.eventCallbackFunction(length: Cardinal; + events: BytePtr); +var + i1,i2,i3: int32; +begin + sys_mutexlock(fmutex); + if not freleased and (fowner <> nil) and //owner alive + (length > 0) then begin + //no call from queevents() + with fowner do begin + i3:= feventcount; + isc_event_counts(pointer(feventcountbuffer),length,feventbuffer,events); + for i1:= 0 to high(feventcountbuffer) do begin + i2:= feventcountbuffer[i1]; + with feventitems[i1] do begin + if count < 0 then begin //first + count:= 0; + i2:= 0; + end + else begin + count:= count + i2; + end; + end; + i3:= i3 + i2; + end; + feventcount:= i3; + feventcontroller.eventinterval:= -1; //restart timer + end; + ffired:= true; + end; + sys_mutexunlock(fmutex); +end; + +procedure tfbeventcallback.destroylocked(); +var + i1: int32; +begin + fowner.feventcallback:= nil; + freleased:= true; + if (fowner <> nil) then begin + with fowner do begin + if fevents <> nil then begin + fevents.release(); + end; + fevents:= nil; + end; + end; + fowner:= nil; + i1:= frefcount; + release(); + if i1 <> 1 then begin //destroyed otherwise + sys_mutexunlock(fmutex); + end; +end; + +type + countbufferty = array[0..3] of byte; + +procedure tfbeventcallback.storestate(); + //copy current event counts to feventitems +var + i1: int32; + po1: pbyte; + bu1: countbufferty; +begin + po1:= fowner.feventbuffer + 1; //first name + for i1:= 0 to high(fowner.feventitems) do begin + po1:= po1 + po1^ + 1; //name length + bu1[0]:= po1^; + inc(po1); + bu1[1]:= po1^; + inc(po1); + bu1[2]:= po1^; + inc(po1); + bu1[3]:= po1^; + inc(po1); + fowner.feventitems[i1].countbefore:= card32(bu1); //endianess? + end; +end; + +procedure tfbeventcallback.queueevents(const first: boolean); +var + i1: int32; + po1: pbyte; + bu1: countbufferty; +begin + ffired:= false; + with fowner do begin + if fevents <> nil then begin + fevents.release(); + end; + fevents:= fattachment.queevents( + fapi.status,feventcallback,feventlength,feventbuffer); + if first then begin //restore count values + po1:= fowner.feventbuffer + 1; //first name + for i1:= 0 to high(fowner.feventitems) do begin + bu1:= countbufferty(fowner.feventitems[i1].countbefore); //endianess? + po1:= po1 + po1^ + 1; //name length + po1^:= bu1[0]; + inc(po1); + po1^:= bu1[1]; + inc(po1); + po1^:= bu1[2]; + inc(po1); + po1^:= bu1[3]; + inc(po1); + end; + end; + end; +end; + +{ efberror } + +constructor efberror.create(const asender: tfb3connection; + const astatus: istatus; const aerrormessage: msestring); +var + str1: string; + msg1: msestring; + po1: nativeintptr; + err1: integer; +begin + str1:= formatstatus(astatus); + msg1:= aerrormessage; + if str1 <> '' then begin + msg1:= msg1 + lineend + msestring(str1); + end; + po1:= astatus.geterrors; + err1:= 0; + if po1 <> nil then begin + err1:= gds__sqlcode(po1); + if po1[0] = isc_arg_gds then begin + fgdscode:= po1[1]; + end; + end; + if asender <> nil then begin + asender.flasterrormessage:= msg1; + asender.flastsqlcode:= err1; + end; + inherited create(asender,ansistring(msg1),msg1,err1); +end; + +{ tfb3connection } + +constructor tfb3connection.create(aowner: tcomponent); +begin + fdialect:= sql_dialect_v6; + feventcontroller:= tdbeventcontroller.create(idbeventcontroller(self)); + feventcontroller.eventinterval:= -1; //event driven + inherited; + FConnOptions := FConnOptions + [sco_SupportParams,sco_forceparams, + sco_nounprepared]; + //unprepared not yet possible because FB3 provides + //no output messagemetadata for execute() +end; + +destructor tfb3connection.destroy(); +begin + inherited; + feventcontroller.free; +end; + +procedure tfb3connection.createdatabase(const asql: ansistring); +var + inited1: boolean; + bo1: boolean; + attachment1: iattachment; +begin + inited1:= fapi.master = nil; + if inited1 then begin + inifbapi(fapi); + end; + try + clearstatus(); + attachment1:= fapi.util.executecreatedatabase(fapi.status,length(asql), + pchar(asql),fdialect,@bo1); + if attachment1 <> nil then begin + attachment1.release(); + end; + checkstatus('createdatabase'); + finally + if inited1 then begin + finifbapi(fapi); + end; + end; +end; +{ +procedure tfb3connection.iniapi(); +begin + initializefirebird([],true); + with fapi do begin + if master = nil then begin + master:= fb_get_master_interface(); + end; + if status = nil then begin + status:= master.getstatus(); + end; + if provider = nil then begin + provider:= master.getdispatcher(); + end; + if util = nil then begin + util:= master.getutilinterface(); + end; + end; +end; + +procedure tfb3connection.finiapi(); +begin + with fapi do begin + util:= nil; + provider:= nil; + if status <> nil then begin + status.dispose(); + status:= nil; + end; + master:= nil; + end; +end; +} +procedure tfb3connection.clearstatus(); inline; +begin + fapi.status.init(); +end; + +function tfb3connection.statusok(): boolean; inline; +begin + result:= fapi.status.getstate() and istatus.state_errors = 0 +end; + +procedure tfb3connection.checkstatus(const aerrormessage: msestring); +begin + if fapi.status.getstate() and istatus.state_errors <> 0 then begin + raise efberror.create(self,fapi.status,aerrormessage); + end; +end; + +function tfb3connection.getpb(const akind: paramblockkindty): ixpbbuilder; +var + kind1: card32; +begin + case akind of + pbk_database: kind1:= ixpbbuilder.DPB; + pbk_transaction: kind1:= ixpbbuilder.TPB; + else begin + raise exception.create('Internalerror 20160924A'); + end; + end; + result:= fapi.util.getxpbbuilder(fapi.status,kind1,nil,0); +end; + +const + paramblockkindnames: array[paramblockkindty] of string = ( +// pbk_database,pbk_transaction + 'database', 'transaction'); + +function tfb3connection.buildpb(const akind: paramblockkindty; + const ainfo: pparaminfoty; const acount: int32; + const aparams: tstringlist; const force: boolean): ixpbbuilder; + + procedure paramerror(const s: string); + begin + raise econnectionerror.create(self, + 'Invalid '+paramblockkindnames[akind]+ + ' parameter "'+s+'"','',0); + end; //paramerror + +var + i1,i2,i3: int32; + s1,s2: string; + po1: pchar; +label + next; + +begin + result:= nil; + if (aparams.count > 0) or force then begin + result:= getpb(akind); + for i1:= 0 to aparams.count - 1 do begin + s1:= aparams[i1]; + if s1 <> '' then begin + po1:= strscan(pointer(s1),'='); + if po1 <> nil then begin + s2:= copy(s1,po1-pchar(pointer(s1))+2,bigint); + s1:= psubstr(pointer(s1),po1); + end; + s1:= trim(s1); + for i2:= 0 to acount-1 do begin + with ainfo[i2] do begin + if s1 = name then begin + if po1 <> nil then begin + case valuekind of + pbvk_int: begin + if trystrtoint(trim(s2),i3) then begin + result.insertint(fapi.status,id,i3); + goto next; + end + else begin + paramerror(aparams[i1]); + end; + end; + pbvk_str: begin + result.insertstring(fapi.status,id,pchar(unquotestring(s2,'"'))); + goto next; + end; + else begin + paramerror(aparams[i1]); + end; + end; + end; + result.inserttag(fapi.status,id); + goto next; + end; + end; + end; + paramerror(aparams[i1]); + end; +next: + end; + end; +end; + +procedure tfb3connection.dointernalconnect(); +const + utf8name = 'UTF8'; + paramconsts: array[0..3] of paraminfoty = + ((id: isc_dpb_user_name; name: 'isc_dpb_user_name'; + valuekind: pbvk_str), + (id: isc_dpb_password; name: 'isc_dpb_password'; + valuekind: pbvk_str), + (id: isc_dpb_lc_ctype; name: 'isc_dpb_lc_ctype'; + valuekind: pbvk_str), + (id: isc_dpb_sql_role_name; name: 'isc_dpb_sql_role_name'; + valuekind: pbvk_str) + ); +var + pb: ixpbbuilder; + databasename1: msestring; + u,p: msestring; + u1,p1: string; +begin + flistencount:= 0; + inifbapi(fapi); + try + inherited dointernalconnect; + pb:= buildpb(pbk_database,@paramconsts,length(paramconsts),params,true); + pb.inserttag(fapi.status,isc_dpb_utf8_filename); + getcredentials(u,p); + if u <> '' then begin + u1:= stringtoutf8(u); + pb.insertstring(fapi.status,isc_dpb_user_name,pointer(u1)); + stringsafefree(u1,false); + end; + if p <> '' then begin + p1:= stringtoutf8(p); + pb.insertstring(fapi.status,isc_dpb_password,pointer(p1)); + stringsafefree(p1,false); + end; + freecredentials(u,p); //fill with #0 before release + if role <> '' then begin + pb.insertstring(fapi.status,isc_dpb_sql_role_name, + pointer(stringtoutf8(role))); + end; + if charset <> '' then begin + pb.insertstring(fapi.status,isc_dpb_lc_ctype,pointer(stringtoutf8(charset))); + end + else begin + if dbo_utf8 in fcontroller.options then begin + pb.insertstring(fapi.status,isc_dpb_lc_ctype,utf8name); + end; + end; + if hostname <> '' then begin + databasename1:= msestring(hostname)+':'+ fdatabasename; + end + else begin + databasename1:= fdatabasename; + end; + fattachment:= nil; + clearstatus(); + fattachment:= fapi.provider.attachdatabase(fapi.status, + pchar(stringtoutf8ansi(databasename1)), + pb.getbufferlength(fapi.status),pb.getbuffer(fapi.status)); + pb.dispose(); + checkstatus('dointernalconnect'); + fattachment.addref(); + except + finifbapi(fapi); +// releasefirebird; + raise; + end; + feventcontroller.connect(); +end; + +procedure tfb3connection.dointernaldisconnect; +begin + inherited; + if fattachment <> nil then begin + fattachment.detach(fapi.status); + fattachment.release(); + fattachment:= nil; + end; + clearevents(); + feventcontroller.disconnect(); + finifbapi(fapi); +end; + +function tfb3connection.allocatetransactionhandle: tsqlhandle; +begin + result:= tfbtrans.create(self); +end; + +function tfb3connection.gettransactionhandle(trans: tsqlhandle): pointer; +begin + result:= tfbtrans(trans).ftransaction; +end; + +function tfb3connection.startdbtransaction(const trans: tsqlhandle; + const aparams: tstringlist): boolean; + +const + paramconsts: array[0..20] of paraminfoty = + ((id: isc_tpb_write; name: 'isc_tpb_write'; + valuekind: pbvk_none), + (id: isc_tpb_read; name: 'isc_tpb_read'; + valuekind: pbvk_none), + (id: isc_tpb_consistency; name: 'isc_tpb_consistency'; + valuekind: pbvk_none), + (id: isc_tpb_concurrency; name: 'isc_tpb_concurrency'; + valuekind: pbvk_none), + (id: isc_tpb_read_committed; name: 'isc_tpb_read_committed'; + valuekind: pbvk_none), + (id: isc_tpb_rec_version; name: 'isc_tpb_rec_version'; + valuekind: pbvk_none), + (id: isc_tpb_no_rec_version; name: 'isc_tpb_no_rec_version'; + valuekind: pbvk_none), + (id: isc_tpb_wait; name: 'isc_tpb_wait'; + valuekind: pbvk_none), + (id: isc_tpb_nowait; name: 'isc_tpb_nowait'; + valuekind: pbvk_none), + (id: isc_tpb_shared; name: 'isc_tpb_shared'; + valuekind: pbvk_none), + (id: isc_tpb_protected; name: 'isc_tpb_protected'; + valuekind: pbvk_none), + (id: isc_tpb_exclusive; name: 'isc_tpb_exclusive'; + valuekind: pbvk_none), + (id: isc_tpb_lock_read; name: 'isc_tpb_lock_read'; + valuekind: pbvk_none), + (id: isc_tpb_lock_write; name: 'isc_tpb_lock_write'; + valuekind: pbvk_none), + (id: isc_tpb_verb_time; name: 'isc_tpb_verb_time'; + valuekind: pbvk_none), + (id: isc_tpb_commit_time; name: 'isc_tpb_commit_time'; + valuekind: pbvk_none), + (id: isc_tpb_ignore_limbo; name: 'isc_tpb_ignore_limbo'; + valuekind: pbvk_none), + (id: isc_tpb_autocommit; name: 'isc_tpb_autocommit'; + valuekind: pbvk_none), + (id: isc_tpb_restart_requests; name: 'isc_tpb_restart_requests'; + valuekind: pbvk_none), + (id: isc_tpb_no_auto_undo; name: 'isc_tpb_no_auto_undo'; + valuekind: pbvk_none), + (id: isc_tpb_lock_timeout; name: 'isc_tpb_lock_timeout'; + valuekind: pbvk_int) + ); +var + pb: ixpbbuilder; + pbbuffer: pointer; + pblen: int32; +begin + result := false; + pb:= buildpb(pbk_transaction,@paramconsts,length(paramconsts),aparams,false); + + if pb <> nil then begin + pblen:= pb.getbufferlength(fapi.status); + pbbuffer:= pb.getbuffer(fapi.status); + end + else begin + pblen:= 0; + pbbuffer:= nil; + end; + with tfbtrans(trans) do begin + clearstatus(); + ftransaction:= fattachment.starttransaction(fapi.status,pblen,pbbuffer); + if pb <> nil then begin + pb.dispose(); + end; + checkstatus('startdbtransaction'); + end; + result:= true; +end; + +function tfb3connection.commit(trans: tsqlhandle): boolean; +begin + with tfbtrans(trans) do begin + clearstatus(); + ftransaction.commit(fconnection.fapi.status); + checkstatus('commit'); + ftransaction:= nil; + result:= true; + end; +end; + +function tfb3connection.rollback(trans: tsqlhandle): boolean; +begin + with tfbtrans(trans) do begin + clearstatus(); + ftransaction.rollback(fconnection.fapi.status); + checkstatus('rollback'); + ftransaction:= nil; + result:= true; + end; +end; + +procedure tfb3connection.internalcommitretaining(trans: tsqlhandle); +begin + with tfbtrans(trans) do begin + clearstatus(); + ftransaction.commitretaining(fapi.status); + checkstatus('commitretaining'); + end; +end; + +procedure tfb3connection.internalrollbackretaining(trans: tsqlhandle); +begin + with tfbtrans(trans) do begin + clearstatus(); + ftransaction.rollbackretaining(fapi.status); + checkstatus('rollbackretaining'); + end; +end; + +function tfb3connection.allocatecursorhandle(const aowner: icursorclient; + const aname: ansistring): tsqlcursor; +begin + result:= tfbcursor.create(aowner,self); +end; + +procedure tfb3connection.deallocatecursorhandle(var cursor: tsqlcursor); +begin + freeandnil(cursor); +end; + +procedure tfb3connection.freefldbuffers(cursor: tsqlcursor); +begin + with tfbcursor(cursor) do begin + frowbuffer:= ''; + end; +end; + +procedure tfb3connection.preparestatement(const cursor: tsqlcursor; + const atransaction: tsqltransaction; const asql: msestring; + const aparams: tmseparams); +var + str1: string; +begin + with tfbcursor(cursor) do begin + if assigned(aparams) and (aparams.count > 0) then begin + str1:= todbstring(aparams.parsesql(asql,false,false,false,psinterbase, + fparambinding)); + end + else begin + fparambinding:= nil; + str1:= todbstring(asql); + end; + with tfbtrans(atransaction.trans) do begin + clearstatus(); + fstatement:= fattachment.prepare(fapi.status,ftransaction,length(str1), + pointer(str1),dialect, + IStatement.PREPARE_PREFETCH_FLAGS or + IStatement.PREPARE_PREFETCH_OUTPUT_PARAMETERS); + if fstatement <> nil then begin + fstatementflags:= fstatement.getflags(fapi.status); + end; + checkstatus('preparestatement'); + include(fcursorstate,cs_hasstatement); + cursor.fprepared:= true; + end; + end; +end; + +procedure tfb3connection.unpreparestatement(cursor: tsqlcursor); +begin + with tfbcursor(cursor) do begin + if cs_hasstatement in fcursorstate then begin + fparambinding:= nil; + cursorclose(tfbcursor(cursor)); + clearstatus(); + fstatement.free(fapi.status); + if not statusok then begin + fstatement.release(); + end; + fstatement:= nil; + exclude(fcursorstate,cs_hasstatement); + end; + fprepared:= false; + end; +end; + +procedure tfb3connection.cursorclose(const cursor: tfbcursor); +begin + with cursor do begin + frowbuffer:= ''; + ffieldinfos:= nil; + if fresultset <> nil then begin + clearstatus(); + fresultset.close(fapi.status); + if not statusok() then begin + fresultset.release(); + end; + fresultset:= nil; + end; + end; +end; + +procedure fetchboolean(const ainfo: pfbfieldinfoty; const dest: pointer); +begin + pwordbool(dest)^:= pcard8(ainfo^.buffer + ainfo^.offset)^ <> 0; +end; + +procedure fetchint16(const ainfo: pfbfieldinfoty; const dest: pointer); +begin + pint32(dest)^:= pint16(ainfo^.buffer + ainfo^.offset)^; +end; + +procedure fetchint32(const ainfo: pfbfieldinfoty; const dest: pointer); +begin + pint32(dest)^:= pint32(ainfo^.buffer + ainfo^.offset)^; +end; + +procedure fetchint64(const ainfo: pfbfieldinfoty; const dest: pointer); +begin + pint64(dest)^:= pint64(ainfo^.buffer + ainfo^.offset)^; +end; + +procedure fetchbcd1(const ainfo: pfbfieldinfoty; const dest: pointer); +begin + pcurrency(dest)^:= pcurrency(ainfo^.buffer + ainfo^.offset)^ * 1000; +end; + +procedure fetchbcd2(const ainfo: pfbfieldinfoty; const dest: pointer); +begin + pcurrency(dest)^:= pcurrency(ainfo^.buffer + ainfo^.offset)^ * 100; +end; + +procedure fetchbcd3(const ainfo: pfbfieldinfoty; const dest: pointer); +begin + pcurrency(dest)^:= pcurrency(ainfo^.buffer + ainfo^.offset)^ * 10; +end; + +procedure fetchbcd4(const ainfo: pfbfieldinfoty; const dest: pointer); +begin + pcurrency(dest)^:= pcurrency(ainfo^.buffer + ainfo^.offset)^; +end; + +procedure fetchbcdtofloat(const ainfo: pfbfieldinfoty; const dest: pointer); +begin + pdouble(dest)^:= pint64(ainfo^.buffer + ainfo^.offset)^ * + intexp10(ainfo^.scale); +end; + +procedure fetchbcd(const ainfo: pfbfieldinfoty; const dest: pointer); +begin + pint64(dest)^:= scaleexp10(pint64(ainfo^.buffer + ainfo^.offset)^, + 4+ainfo^.scale); +end; + +procedure fetchfloat(const ainfo: pfbfieldinfoty; const dest: pointer); +begin + pdouble(dest)^:= psingle(ainfo^.buffer + ainfo^.offset)^; +end; + +procedure fetchdouble(const ainfo: pfbfieldinfoty; const dest: pointer); +begin + pdouble(dest)^:= pdouble(ainfo^.buffer + ainfo^.offset)^; +end; + +procedure fetchtime(const ainfo: pfbfieldinfoty; const dest: pointer); +begin + pdatetime(dest)^:= pisc_time(ainfo^.buffer + ainfo^.offset)^ / + (3600*24*ISC_TIME_SECONDS_PRECISION); +end; + +procedure fetchdate(const ainfo: pfbfieldinfoty; const dest: pointer); +begin + pdatetime(dest)^:= pisc_date(ainfo^.buffer + ainfo^.offset)^ + fbdatetimeoffset; +end; + +procedure fetchtimestamp(const ainfo: pfbfieldinfoty; const dest: pointer); +var + ti,da: double; + po1: pisc_timestamp; +begin + po1:= ainfo^.buffer + ainfo^.offset; + da:= po1^.timestamp_date + fbdatetimeoffset; + ti:= po1^.timestamp_time / (3600*24*ISC_TIME_SECONDS_PRECISION); + if da < 0 then begin + pdatetime(dest)^:= da - ti; + end + else begin + pdatetime(dest)^:= da + ti; + end; +end; + +procedure fetchtext(const ainfo: pfbfieldinfoty; const dest: pointer); +var + i1: int32; + po1: pchar; +begin + po1:= ainfo^.buffer + ainfo^.offset; + i1:= ainfo^.size; + if i1 > ainfo^.buffersizead^ then begin + ainfo^.buffersizead^:= -i1; + end + else begin + ainfo^.buffersizead^:= i1; + move(po1^,dest^,i1); + end; +end; + +procedure fetchguid(const ainfo: pfbfieldinfoty; const dest: pointer); +var + po1: pguid; +begin + po1:= ainfo^.buffer + ainfo^.offset; + pguid(dest)^:= po1^; +end; + +procedure fetchvarchar(const ainfo: pfbfieldinfoty; const dest: pointer); +var + i1: int32; + po1: pvary; +begin + po1:= ainfo^.buffer + ainfo^.offset; + i1:= po1^.vary_length; + if i1 > ainfo^.buffersizead^ then begin + ainfo^.buffersizead^:= -i1; + end + else begin + ainfo^.buffersizead^:= i1; + move(po1^.vary_string,dest^,i1); + end; +end; + +procedure fetchvarbytes(const ainfo: pfbfieldinfoty; const dest: pointer); +var + i1: int32; + po1: pvary; +begin + po1:= ainfo^.buffer + ainfo^.offset; + i1:= po1^.vary_length + sizeof(card16); + if i1 > ainfo^.buffersizead^ then begin + ainfo^.buffersizead^:= -i1; + end + else begin + ainfo^.buffersizead^:= i1; + pcard16(dest)^:= po1^.vary_length; + move(po1^.vary_string,(dest+sizeof(card16))^,po1^.vary_length); + end; +end; + +procedure fetchblobid(const ainfo: pfbfieldinfoty; const dest: pointer); +begin + pisc_quad(dest)^:= pisc_quad(ainfo^.buffer + ainfo^.offset)^; + //todo: wantblobfetch +end; + +procedure fetchblobidanddata(const ainfo: pfbfieldinfoty; const dest: pointer); +begin + pisc_quad(dest)^:= pisc_quad(ainfo^.buffer + ainfo^.offset)^; + ainfo^._cursor.addblobcache(pint64(dest)^, + ainfo^._cursor.fconnection.getblobstring( + ainfo^._cursor,pisc_quad(dest)^)); +end; + +procedure tfb3connection.updateresultmetadata(const acursor: tfbcursor; + const outmetadata: pimessagemetadata); +var + metadata: imessagemetadata; + i1,i2,i3: int32; + +begin + with acursor do begin + ffirstfetch:= false; + fempty:= false; + if fresultset = nil then begin //execute() + metadata:= fstatement.getoutputmetadata(fapi.status); + if metadata <> nil then begin + ffirstfetch:= true; + end + else begin + fempty:= true; + end; + end + else begin //openCursor() + metadata:= fresultset.getmetadata(fapi.status); + end; + if outmetadata <> nil then begin + outmetadata^:= metadata; + if metadata <> nil then begin + metadata.addref(); + end; + end; + if metadata <> nil then begin + i1:= metadata.getcount(fapi.status); + if (i1 = 0) and (fresultset = nil) then begin + ffirstfetch:= false; //there is no outputdata + end; + setlength(frowbuffer,metadata.getmessagelength(fapi.status)); + if statusok() then begin + setlength(ffieldinfos,i1); + for i1:= 0 to i1-1 do begin + with ffieldinfos[i1] do begin + buffer:= pointer(frowbuffer); + name:= metadata.getalias(fapi.status,i1); + offset:= metadata.getoffset(fapi.status,i1); + _type:= metadata.gettype(fapi.status,i1); + scale:= metadata.getscale(fapi.status,i1); + if metadata.isnullable(fapi.status,i1) then begin + nulloffset:= metadata.getnulloffset(fapi.status,i1); + end + else begin + nulloffset:= -1; + end; + size:= 0; + case _type of + SQL_BOOLEAN: begin + datatype:= ftboolean; + fetchfunc:= @fetchboolean; + end; + SQL_SHORT: begin + datatype:= ftsmallint; + fetchfunc:= @fetchint16; + end; + SQL_LONG: begin + datatype:= ftinteger; + fetchfunc:= @fetchint32; + end; + SQL_INT64,SQL_QUAD: begin + if (scale <> 0) then begin + datatype:= ftbcd; + case scale of + -1: begin + fetchfunc:= @fetchbcd1; + end; + -2: begin + fetchfunc:= @fetchbcd2; + end; + -3: begin + fetchfunc:= @fetchbcd3; + end; + -4: begin + fetchfunc:= @fetchbcd4; + end; + else begin + if (dbo_bcdtofloatif in controller.options) then begin + datatype:= ftfloat; + fetchfunc:= @fetchbcdtofloat; + end + else begin + fetchfunc:= @fetchbcd; + end; + end; + end; + end + else begin + datatype:= ftlargeint; + fetchfunc:= @fetchint64; + end; + end; + SQL_FLOAT: begin + datatype:= ftfloat; + fetchfunc:= @fetchfloat; + end; + SQL_DOUBLE,SQL_D_FLOAT: begin + datatype:= ftfloat; + fetchfunc:= @fetchdouble; + end; + SQL_TIMESTAMP: begin + datatype:= ftdatetime; + fetchfunc:= @fetchtimestamp; + end; + SQL_TYPE_DATE: begin + datatype:= ftdate; + fetchfunc:= @fetchdate; + end; + SQL_TYPE_TIME: begin + datatype:= fttime; + fetchfunc:= @fetchtime; + end; + SQL_TEXT,SQL_VARYING: begin + size:= metadata.getlength(fapi.status,i1); + datatype:= ftstring; + i2:= metadata.getcharset(fapi.status,i1); + if _type = SQL_TEXT then begin + fetchfunc:= @fetchtext; + if i2 = cs_binary then begin + if size = 16 then begin + datatype:= ftguid; + fetchfunc:= @fetchguid; + size:= 0; + end + else begin + datatype:= ftbytes; + end; + end; + end + else begin + if i2 = cs_binary then begin + datatype:= ftvarbytes; + fetchfunc:= @fetchvarbytes; + end + else begin + fetchfunc:= @fetchvarchar; + end; + end; + case i2 of + 5,6,{8,}44,56,57{,64}: begin + i3:= 2; + end; + 3: begin + i3:= 3; + end; + 4,59: begin + i3:= 4; + end; + else begin + i3:= 1; + end; + end; + size:= size div i3; + end; + SQL_BLOB: begin + size:= 8; + if wantblobfetch then begin + fetchfunc:= @fetchblobidanddata; + _cursor:= acursor; + end + else begin + fetchfunc:= @fetchblobid; + end; + if metadata.getsubtype(fapi.status,i1) = isc_blob_text then begin + datatype:= ftmemo; + end + else begin + datatype:= ftblob; + end; + end; + SQL_ARRAY: begin //todo: support slice access + size:= 8; + datatype:= ftlargeint; + fetchfunc:= @fetchint64; + end; + else begin + datatype:= ftunknown; + fetchfunc:= nil; + end; + end; + end; + end; + end; + metadata.release(); + end; + end; +end; + +procedure tfb3connection.internalexecute(const cursor: tsqlcursor; + const atransaction: tsqltransaction; const aparams: tmseparams; + const autf8: boolean); +var + paramdata: tparamdata; //inherits from imessagemetadata + parambuffer: pointer; + outdata1: imessagemetadata; + buf1: array[0..127] of byte; + by1: byte; + i1,i2,i3: int32; + datasize: int32; + selectcount: int32; + updatecount: int32; + deletecount: int32; + insertcount: int32; + +begin + with tfbcursor(cursor) do begin + frowsaffected:= -1; + frowsreturned:= -1; + if assigned(aparams) and (aparams.count > 0) and + (fparambinding <> nil) then begin + paramdata:= tparamdata.create(tfbcursor(cursor),aparams); + parambuffer:= paramdata.parambuffer; + end + else begin + paramdata:= nil; + parambuffer:= nil; + end; + with tfbtrans(atransaction.trans) do begin + clearstatus(); + if fstatementflags and istatement.FLAG_HAS_CURSOR <> 0 then begin + fresultset:= fstatement.opencursor(fapi.status,ftransaction, + paramdata,parambuffer,nil,0); + end + else begin + updateresultmetadata(tfbcursor(cursor),@outdata1); + fstatement.execute(fapi.status,ftransaction,paramdata,parambuffer, + outdata1,pointer(frowbuffer)); + end; + if paramdata <> nil then begin + paramdata.release(); + end; + if fresultset <> nil then begin + updateresultmetadata(tfbcursor(cursor),nil); + if fbo_sqlinfo in foptions then begin + if fetch(cursor) then begin //fetch necessary for valid sqlinfo + ffirstfetch:= true; + end + else begin + fempty:= true; + end; + end; + end; + if fbo_sqlinfo in foptions then begin + by1:= isc_info_sql_records; + fstatement.getinfo(fapi.status,1,@by1,sizeof(buf1),@buf1); + if statusok() then begin + if buf1[0] = isc_info_sql_records then begin + i2:= gds__vax_integer(@buf1[1],2)+3; //record size + if i2 <= sizeof(buf1) then begin + selectcount:= -1; + updatecount:= -1; + deletecount:= -1; + insertcount:= -1; + i1:= 3; + while true do begin + by1:= buf1[i1]; + if (by1 in [isc_info_end,isc_info_truncated]) or + (i1 >= i2-1) then begin + break; + end; + datasize:= gds__vax_integer(@buf1[i1+1],2); + inc(i1,3); + if i1 + datasize > i2 then begin + break; + end; + i3:= gds__vax_integer(@buf1[i1],datasize); + case by1 of + isc_info_req_select_count: begin + selectcount:= i3; + end; + isc_info_req_update_count: begin + updatecount:= i3; + end; + isc_info_req_delete_count: begin + deletecount:= i3; + end; + isc_info_req_insert_count: begin + insertcount:= i3; + end; + end; + inc(i1,datasize); + end; + if selectcount >= 0 then begin + frowsreturned:= selectcount; + end; + if updatecount > 0 then begin +// frowsreturned:= 0; + frowsaffected:= updatecount; + end; + if deletecount > 0 then begin +// frowsreturned:= 0; + frowsaffected:= deletecount; + end; + if insertcount > 0 then begin +// frowsreturned:= 0; + frowsaffected:= insertcount; + end; + end; + end; + end; + end; + checkstatus('execute'); + end; + end; +end; + +(* not ready, needs FB3 improvement + +procedure tfb3connection.internalexecuteunprepared(const cursor: tsqlcursor; + const atransaction: tsqltransaction; const asql: string; + const origsql: msestring; const aparams: tmseparams); + //not used +var + paramdata: tparamdata; //inherits from imessagemetadata + parambuffer: pointer; + str1: string; +begin + with tfbcursor(cursor) do begin + frowsaffected:= -1; + frowsreturned:= -1; + if assigned(aparams) and (aparams.count > 0) then begin + str1:= todbstring(aparams.parsesql(origsql,false,false,false,psinterbase, + fparambinding)); + paramdata:= tparamdata.create(tfbcursor(cursor),aparams); + parambuffer:= paramdata.parambuffer; + end + else begin + fparambinding:= nil; + str1:= asql; + paramdata:= nil; + parambuffer:= nil; + end; + with tfbtrans(atransaction.trans) do begin + clearstatus(); + // fstatement.execute(fapi.status,ftransaction,nil,nil,nil,nil); + fresultset:= fattachment.opencursor(fapi.status,ftransaction,length(str1), + pchar(str1),dialect,paramdata,parambuffer,nil,nil,0); + if paramdata <> nil then begin + paramdata.release(); + end; + if fresultset <> nil then begin + updateresultmetadata(tfbcursor(cursor),nil); + end; + checkstatus('executeunprepared'); + end; + todo: rowsreturned, rowsaffected + end; +end; +*) + +procedure tfb3connection.addfielddefs(const cursor: tsqlcursor; + const fielddefs: tfielddefs); +var + i1: int32; +begin + with tfbcursor(cursor) do begin + fielddefs.clear(); + for i1:= 0 to high(ffieldinfos) do begin + with ffieldinfos[i1] do begin + with tfielddef.create(fielddefs,name,datatype,size,false,i1+1) do begin + end; + end; + end; + end; +end; + +procedure tfb3connection.updateindexdefs(var indexdefs: tindexdefs; + const atablename: string; const acursor: tsqlcursor); +begin + fbupdateindexdefs(self,indexdefs,atablename); +end; + +function tfb3connection.getschemainfosql(schematype : tschematype; + schemaobjectname, schemapattern : msestring) : msestring; +begin + result:= fbgetschemainfosql(self,schematype,schemaobjectname,schemapattern); +end; + +function tfb3connection.fetch(cursor: tsqlcursor): boolean; +var + i1: int32; +begin + result:= false; + with tfbcursor(cursor) do begin + if ffirstfetch then begin + result:= true; //output data from exec() + ffirstfetch:= false; + end + else begin + if not fempty then begin + if fresultset <> nil then begin + clearstatus(); + i1:= fresultset.fetchnext(fapi.status,pointer(frowbuffer)); + result:= i1 = istatus.RESULT_OK; + checkstatus('fetch'); + end; + end; + end; + end; +end; + +function tfb3connection.loadfield(const cursor: tsqlcursor; + const datatype: tfieldtype; const fieldnum: integer; + const buffer: pointer; var bufsize: integer; + const aisutf8: boolean): boolean; +var + po1: pfbfieldinfoty; +begin + with tfbcursor(cursor) do begin + po1:= @ffieldinfos[fieldnum]; + if (po1^.nulloffset >= 0) and + (pisc_short(po1^.buffer + po1^.nulloffset)^ <> 0) or + (po1^.fetchfunc = nil) then begin + result:= false; + end + else begin + if buffer <> nil then begin //else null check; + po1^.buffersizead:= @bufsize; + po1^.fetchfunc(po1,buffer); + end; + result:= true; + end; + end; +end; + +function tfb3connection.fetchblob(const cursor: tsqlcursor; + const fieldnum: integer): ansistring; +var + blobId : ISC_QUAD; + int1: integer; +begin + int1:= sizeof(blobid); + if not loadfield(cursor,ftblob,fieldnum,@blobid,int1,false) then begin + result:= ''; + end + else begin + result:= getblobstring(cursor,blobid); + end; +end; + +function tfb3connection.version: msestring; +var + versioncallback: tversioncallback; +begin + checkconnected(); + versioncallback:= tversioncallback.create; + clearstatus(); + fapi.util.getfbversion(fapi.status,fattachment,versioncallback); + if isutf8 then begin + result:= utf8tostring(versioncallback.text); + end + else begin + result:= msestring(versioncallback.text); + end; + versioncallback.destroy(); + checkstatus('get version'); +end; + +const + infotags: array[0..1] of byte = + (isc_info_blob_max_segment,isc_info_blob_total_length); + +function tfb3connection.getblobstream(const acursor: tsqlcursor; + const blobid: isc_quad; + const forstring: boolean = false): tmemorystream; +var + blob: iblob; + buffer: array[0..63] of byte; + maxsegment,totallength: int32; + i1,i2,i3: int32; + po1,pe: pcard8; + by1: byte; +begin + clearstatus(); + blob:= fattachment.openblob(fapi.status,itransaction(acursor.ftrans), + @blobid,0,nil); + checkstatus('open blob'); + try + blob.getinfo(fapi.status,length(infotags),@infotags,sizeof(buffer),@buffer); + checkstatus('get blob info'); + po1:= @buffer; + pe:= po1 + sizeof(buffer); + maxsegment:= -1; + totallength:= -1; + while (po1 < pe) and (po1^ <> isc_info_end) do begin + by1:= po1^; + inc(po1); + i2:= gds__vax_integer(po1,2); + inc(po1,2); + i3:= gds__vax_integer(po1,i2); + inc(po1,i2); + case by1 of + isc_info_blob_max_segment: begin + maxsegment:= i3; + end; + isc_info_blob_total_length: begin + totallength:= i3; + end; + else begin + break; + end; + end; + end; + if (maxsegment < 0) or (totallength < 0) or + (maxsegment = 0) and (totallength <> 0)then begin + databaseerror('Invalid blob info result',self); + end; + if forstring then begin + result:= tmemorystringstream.create; + end + else begin + result:= tmemorystream.create; + end; + result.size:= totallength; + po1:= result.memory; + repeat + i3:= totallength; + if i3 > maxsegment then begin + i3:= maxsegment; + end; + i2:= blob.getsegment(fapi.status,i3,po1,@i1); + checkstatus('read blob'); + po1:= po1 + i1; + totallength:= totallength - i1; + until (totallength <= 0) or + not ((i2 = istatus.RESULT_OK) or (i2 = istatus.RESULT_SEGMENT)); + finally + blob.release(); + end; +end; + +function tfb3connection.getblobstring(const acursor: tsqlcursor; + const blobid: isc_quad): string; +begin + tmemorystringstream(getblobstream(acursor,blobid,true)).destroyasstring(result); +end; + +function tfb3connection.getdatabasename: filenamety; +begin + result:= fcontroller.getdatabasename; +end; + +procedure tfb3connection.setdatabasename(const avalue: filenamety); +begin + fcontroller.setdatabasename(avalue); +end; + +function tfb3connection.getconnected: boolean; +begin + result:= inherited connected; +end; + +procedure tfb3connection.setconnected(const avalue: boolean); +begin + if fcontroller.setactive(avalue) then begin + inherited connected:= avalue; + end; +end; + +function tfb3connection.createblobstream(const field: tfield; + const mode: tblobstreammode; const acursor: tsqlcursor): tstream; +var + blobId : ISC_QUAD; +begin + result := nil; + if mode = bmRead then begin + if not field.getData(@blobId) then begin + exit; + end; + result:= getblobstream(acursor,blobid); + end + else begin + if (mode = bmwrite) and (field.dataset is tmsesqlquery) then begin + result:= tmsebufdataset(field.dataset).createblobbuffer(field); + end; + end; +end; + +function tfb3connection.getblobdatasize: integer; +begin + result:= 8; +end; + +procedure tfb3connection.writeblobdata(const atransaction: tsqltransaction; + const tablename: string; const acursor: tsqlcursor; + const adata: pointer; const alength: integer; + const afield: tfield; const aparam: tparam; out newid: string); +const + maxsegment = $ffff; +var + blob: iblob; + id: isc_quad; + po1: pcard8; + i1: int32; +begin + clearstatus(); + blob:= fattachment.createblob(fapi.status, + tfbtrans(atransaction.trans).ftransaction,@id,0,nil); + checkstatus('createblob'); + i1:= alength; + po1:= adata; + try + while i1 > 0 do begin + if i1 > maxsegment then begin + blob.putsegment(fapi.status,maxsegment,po1); + end + else begin + blob.putsegment(fapi.status,i1,po1); + end; + inc(po1,maxsegment); + dec(i1,maxsegment); + checkstatus('put segment'); + end; + blob.close(fapi.status); + finally + blob.release(); + end; + checkstatus('writeblobdata'); + + if aparam <> nil then begin + aparam.aslargeint:= int64(id); + if afield.datatype in textblobtypes then begin + aparam.blobkind:= bk_text; + end + else begin + aparam.blobkind:= bk_binary; + end; + end + else begin + setlength(newid,sizeof(isc_quad)); + pisc_quad(pointer(newid))^:= id; + end; +end; + +procedure tfb3connection.setupblobdata(const afield: tfield; + const acursor: tsqlcursor; const aparam: tparam); +var + blobid: isc_quad; +begin + afield.getdata(@blobid); + aparam.aslargeint:= int64(blobid); + if afield.datatype in textblobtypes then begin + aparam.blobkind:= bk_text; + end + else begin + aparam.blobkind:= bk_binary; + end; +end; + +procedure tfb3connection.listen(const sender: tdbevent); +begin + feventcontroller.register(sender); + if connected then begin + dolisten(sender); + end; +end; + +procedure tfb3connection.unlisten(const sender: tdbevent); +begin + if connected then begin + dounlisten(sender); + end; + feventcontroller.unregister(sender); +end; + +procedure tfb3connection.fire(const sender: tdbevent); +var + trans: tmsesqltransaction; +begin + trans:= tmsesqltransaction.create(nil); + try + trans.database:= self; + executedirect('execute block as begin post_event '+ + encodesqlstring(msestring(sender.eventname))+'; end', + trans,nil,isutf8,true); + trans.commit(); + finally + trans.destroy(); + end; +end; + +function tfb3connection.getdbevent(var aname: string; var aid: int64): boolean; +var + i1: int32; +begin + result:= false; + if feventcallback <> nil then begin + sys_mutexlock(feventcallback.fmutex); + if feventcount > 0 then begin + dec(feventcount); + for i1:= 0 to high(feventitems) do begin + with feventitems[i1] do begin + if count > 0 then begin + dec(count); + aname:= event.eventname; + aid:= i1; + result:= true; + break; + end; + end; + end; + end; + if feventcallback.ffired then begin //restart listen + clearstatus(); + feventcallback.queueevents(false); + sys_mutexunlock(feventcallback.fmutex); + checkstatus('getdbevent'); + end + else begin + sys_mutexunlock(feventcallback.fmutex); + end; + end; +end; + +procedure tfb3connection.clearevents(); +begin + if feventcallback <> nil then begin + sys_mutexlock(feventcallback.fmutex); + feventcallback.destroylocked(); + end; + if fevents <> nil then begin + fevents.cancel(fapi.status); + fevents.release(); + fevents:= nil; + end; + freeeventblock(feventbuffer); + feventitems:= nil; + feventcountbuffer:= nil; +end; + +procedure tfb3connection.loaded(); +begin + inherited; + fcontroller.loaded; +end; + +function tfb3connection.readsequence(const sequencename: string): msestring; +begin + result:= 'select gen_id('+msestring(sequencename)+ + ',1) as res from RDB$DATABASE;'; +end; + +function tfb3connection.sequencecurrvalue(const sequencename: string): msestring; +begin + result:= 'select gen_id('+msestring(sequencename)+ + ',0) as res from RDB$DATABASE;'; +end; + +function tfb3connection.writesequence(const sequencename: string; + const avalue: largeint): msestring; +begin + result:= 'set generator '+msestring(sequencename)+ + ' to '+inttostrmse(avalue)+';'; +end; + +procedure tfb3connection.updateevents(const aerrormessage: msestring); + //mutex must be locked, event leaks possible +var + i1: integer; + ar1: array of string; +begin + if feventcallback <> nil then begin + feventcallback.destroylocked(); + end; + setlength(ar1,length(feventitems)); + setlength(feventcountbuffer,length(feventitems)); + for i1:= 0 to high(feventitems) do begin + ar1[i1]:= feventitems[i1].name; + end; + if feventitems <> nil then begin + feventcallback:= tfbeventcallback.create(self); + feventcallback.addref(); + sys_mutexlock(feventcallback.fmutex); + freeeventblock(feventbuffer); + feventlength:= event_block(feventbuffer,ar1); + + clearstatus(); + feventcallback.queueevents(true); + if fevents = nil then begin //error in queueevents + feventcallback.destroylocked(); + clearevents(); + end; + checkstatus(aerrormessage); + //eventcallback allready destroyed in case of error + end + else begin + clearevents(); + end; + if feventcallback <> nil then begin + sys_mutexunlock(feventcallback.fmutex); + end; +end; + +procedure tfb3connection.dolisten(const sender: tdbevent); +begin + if feventcallback <> nil then begin + sys_mutexlock(feventcallback.fmutex); + feventcallback.storestate(); //copy current event counts to feventitems + end; + setlength(feventitems,high(feventitems)+2); + with feventitems[high(feventitems)] do begin + count:= -1; //first + event:= sender; + name:= sender.eventname; + end; + updateevents('dolisten'); +end; + +procedure tfb3connection.dounlisten(const sender: tdbevent); +var + i1: integer; + po1: pfbeventinfoty; +begin + if feventcallback <> nil then begin + sys_mutexlock(feventcallback.fmutex); + feventcallback.storestate(); //copy current event counts to feventitems + end; + for i1:= 0 to high(feventitems) do begin + po1:= @feventitems[i1]; + if po1^.event = sender then begin + if i1 <> high(feventitems) then begin + with feventitems[high(feventitems)] do begin + stringaddref(name); //compensate decref by setlength in deleteitem() + end; + finalize(po1^); + end; + deleteitem(feventitems,typeinfo(feventitems),i1); + break; + end; + end; + updateevents('dounlisten'); +end; + +{ tfbtrans } + +constructor tfbtrans.create(const aconnection: tfb3connection); +begin + fconnection:= aconnection; +end; + +destructor tfbtrans.destroy(); +begin + inherited; + if ftransaction <> nil then begin + ftransaction.release(); + end; +end; + +{ tfbcursor } + +constructor tfbcursor.create(const aowner: icursorclient; + const aconnection: tfb3connection); +begin + fconnection:= aconnection; + inherited create(aowner,fconnection.name); +end; + +destructor tfbcursor.destroy(); +begin + inherited; + if fresultset <> nil then begin + close(); //first, close needs valid statment + end; + if fstatement <> nil then begin + fstatement.release(); + end; +end; + +procedure tfbcursor.close(); +begin + inherited; + fconnection.cursorclose(self); +end; + +end. diff --git a/mseide-msegui/lib/common/db/msefb3service.pas b/mseide-msegui/lib/common/db/msefb3service.pas new file mode 100644 index 0000000..6f30393 --- /dev/null +++ b/mseide-msegui/lib/common/db/msefb3service.pas @@ -0,0 +1,1759 @@ +unit msefb3service; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$if fpc_fullversion >= 30000} + {$define mse_fpc_3} +{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses,mseclasses,firebird,msefirebird,msetypes,mdb,msestrings, + msefb3connection, +// mibconnection, + msethread,sysutils; + +const + defaultinfotimeout = 60; //seconds + +type + fbserverinfoty = record + version: card32; + server_version: msestring; + _implementation: msestring; + capabilities: card32; + user_dbpath: msestring; + get_env: msestring; + get_env_lock: msestring; + get_env_msg: msestring; + end; + + fbuserinfoty = record + username: msestring; + firstname: msestring; + middlename: msestring; + lastname: msestring; + groupname: msestring; + rolename: msestring; + userid: card32; + groupid: card32; + admin: card32; + password: ansistring; + end; + pfbuserinfoty = ^fbuserinfoty; + fbuserinfoarty = array of fbuserinfoty; + + fbuseritemty = (fbu_username,fbu_firstname,fbu_middlename,fbu_lastname, + fbu_groupname,fbu_rolename,fbu_userid,fbu_groupid,fbu_admin, + fbu_password); + fbuseritemsty = set of fbuseritemty; + +const + allfbuseritems = [fbu_username,fbu_firstname,fbu_middlename,fbu_lastname, + fbu_groupname,fbu_rolename,fbu_userid,fbu_groupid,fbu_admin, + fbu_password]; + +type + accessmodety = (amo_readonly,amo_readwrite); + writemodety = (wmo_async,wmo_sync); + runmodety = (rmo_normal,rmo_multi,rmo_single,rmo_full); + reservespacety = (rsp_full,rsp_res); + propertyoptionty = (pro_activate,pro_dbonline); + propertyoptionsty = set of propertyoptionty; + + fbpropertyinfoty = record + pagebuffers: card32; + sweepinterval: card32; + shutdowndb: card32; + denynewattachments: card32; + denynewtransactions: card32; + reservespace: reservespacety; + writemode: writemodety; + accessmode: accessmodety; + setsqldialect: card32; + options: propertyoptionsty; + forceshutdown: card32; + attachmentsshutdown: card32; + transactionsshutdown: card32; + shutdownmode: runmodety; + onlinemode: runmodety; + end; + + fbpropertyitemty = (fbp_pagebuffers,fbp_sweepinterval,fbp_shutdowndb, + fbp_denynewattachments,fbp_denynewtransactions, + fbp_reservespace,fbp_writemode,fbp_accessmode, + fbp_setsqldialect,fbp_options,fbp_forceshutdown, + fbp_attachmentsshutdown,fbp_transactionsshutdown, + fbp_shutdownmode,fbp_onlinemode); + fbpropertyitemsty = set of fbpropertyitemty; + +const + allfbpropertyitems = [fbp_pagebuffers,fbp_sweepinterval,fbp_shutdowndb, + fbp_denynewattachments,fbp_denynewtransactions, + fbp_reservespace,fbp_writemode,fbp_accessmode, + fbp_setsqldialect,fbp_options,fbp_forceshutdown, + fbp_attachmentsshutdown,fbp_transactionsshutdown, + fbp_shutdownmode,fbp_onlinemode]; + +type + dbstatoptionty = (dbsto_datapages,dbsto_dblog,dbsto_hdrpages, + dbsto_idxpages,dbsto_sysrelations,dbsto_recordversions, + dbsto_table,dbsto_nocreation); + dbstatoptionsty = set of dbstatoptionty; + + backupoptionty = (bao_ignorechecksums,bao_ignorelimbo,bao_metadataonly, + bao_no_garbagecollect,bao_olddescriptions,bao_nontransportable, + bao_convert,bao_expand,bao_notriggers {=$8000}); + backupoptionsty = set of backupoptionty; + + restoreoptionty = (reo_deactivateidx,reo_no_shadow,reo_no_validity, + reo_one_at_a_time,reo_replace,reo_create,reo_use_all_space); + restoreoptionsty = set of restoreoptionty; + + repairoptionty = (rpo_validate_db,rpo_sweep_db,rpo_mend_db,limbo_trans, + rpo_check_db,rpo_ignore_checksum,rpo_kill_shadows,rpo_full); + repairoptionsty = set of repairoptionty; + + nbakoptionty = (nbo_notriggers); + nbakoptionsty = set of nbakoptionty; + + tfb3service = class; + + efbserviceerror3 = class(edatabaseerror) + private + ferror: integer; + ferrormessage: msestring; + fsender: tfb3service; +// fstatus: statusvectorty; + public + constructor create(const asender: tfb3service; + const astatus: istatus; const aerrormessage: msestring); + property sender: tfb3service read fsender; + property error: integer read ferror; + property errormessage: msestring read ferrormessage; +// property status: statusvectorty read fstatus; + end; + + fbservicestatety = (fbss_connected,fbss_busy); + fbservicestatesty = set of fbservicestatety; + fbserviceoptionty = (fbso_utf8,fbso_utf8message); + fbserviceoptionsty = set of fbserviceoptionty; + + fbservicetexteventty = procedure (const sender: tfb3service; + const atext: msestring) of object; + fbserviceerroreventty = procedure (const sender: tfb3service; + var e: exception; var handled: boolean) of object; + fbserviceendeventty = procedure (const sender: tfb3service; + const aborted: boolean) of object; + tfbservicemonitor3 = class(tmsethread) + private + fprocname: msestring; + protected + fowner: tfb3service; + function execute(thread: tmsethread): integer; override; + public + constructor create(const aowner: tfb3service; const procname: msestring); + destructor destroy(); override; + end; + + tfb3service = class(tmsecomponent) + private + fhostname: ansistring; + fusername: ansistring; + fpassword: ansistring; + fstate: fbservicestatesty; + fservice: iservice; +// fstatus: statusvectorty; //array [0..19] of isc_status; +// flasterror: istatus; + flasterrormessage: msestring; + foptions: fbserviceoptionsty; + finfotimeout: int32; + fonasynctext: fbservicetexteventty; + fmonitor: tfbservicemonitor3; + fonerror: fbserviceerroreventty; + fonasyncend: fbserviceendeventty; + fasynctext: msestringarty; + fasyncmaxrowcount: int32; + fonasyncendmain: fbserviceendeventty; + function getconnected: boolean; + procedure setconnected(const avalue: boolean); + protected + fapi: fbapity; + function connectionmessage(atext: pchar): msestring; + procedure loaded(); override; + procedure doasyncevent(var atag: int32); override; + procedure clearstatus(); inline; + function statusok(): boolean; inline; + procedure checkstatus(const aerrormessage: msestring); + procedure connect(); + procedure closeconn(); + procedure disconnect(); + procedure readstate(reader: treader); override; + procedure raiseerror(const e: exception; const dberr: boolean); + procedure dberror(const msg: msestring; const comp: tcomponent; + const dberr: boolean); +// procedure checkerror(const procname : string; +// const status : istatus); +// procedure checkerror(const procname : string; +// const status: integer); + procedure checkbusy(); + procedure invalidresponse(const procname: msestring); + + procedure start(const procname: msestring; const params: string); + function getinfo(const procname: msestring; const items: array of byte; + const async: boolean): string; + procedure runcommand(const procname: msestring; const params: string); + function getmsestringitem(var buffer: pointer; out res: msestring; + const cutspace: boolean = false): boolean; + //returns eof state + function getmsestringitem(var buffer: pointer; const id: int32; + var value: msestring): boolean; + procedure addmseparam(var params: string; const id: int32; + const value: msestring); + //value limited to 65535 chars + function internalusers(const ausername: string): fbuserinfoarty; + procedure gettext(const procname: msestring; const params: string; + var res: msestringarty; const maxrowcount: integer); + //ring buffer + procedure startmonitor(const procname: msestring; const aparams: string); + function serviceisrunning: boolean; + procedure tagaction(const aprocname: msestring; const aaction: int32; + var res: msestringarty; + const maxrowcount: int32); + procedure tagaction(const aprocname: msestring; const aaction: int32); + procedure traceaction(const aprocname: msestring; const aaction: int32; + const aid: card32; var res: msestringarty; + const maxrowcount: int32); + procedure adduserparams(var params1: string; + const ainfo: fbuserinfoty; const aitems: fbuseritemsty); + public + constructor create(aowner: tcomponent); override; + destructor destroy(); override; + function todbstring(const avalue: msestring): string; + function tomsestring(const avalue: string): msestring; + procedure cancel(); + function busy(): boolean; + + function serverinfo(): fbserverinfoty; + function users(): fbuserinfoarty; + function user(const ausername: msestring; var ainfo: fbuserinfoty): boolean; + //false if not found + procedure adduser(const ainfo: fbuserinfoty; const items: fbuseritemsty); + procedure modifyuser(const ainfo: fbuserinfoty; const items: fbuseritemsty); + //fbu_username must be set + procedure deleteuser(const ausername: msestring; + const arolename: msestring = ''); + procedure getlog(var res: msestringarty; const maxrowcount: int32 = -1); + //ring buffer, -1 -> unlimited + procedure tracestart(const cfg: msestring; const _name: msestring = ''); + //async, stop it by connected:= false or call of cancel() + procedure tracelist(var res: msestringarty; const maxrowcount: int32 = -1); + //ring buffer, -1 -> unlimited + procedure tracestop(const aid: card32; var res: msestringarty; + const maxrowcount: int32 = -1); + //ring buffer, -1 -> unlimited + procedure tracesuspend(const aid: card32; var res: msestringarty; + const maxrowcount: int32 = -1); + //ring buffer, -1 -> unlimited + procedure traceresume(const aid: card32; var res: msestringarty; + const maxrowcount: int32 = -1); + //ring buffer, -1 -> unlimited + procedure setmapping(); + procedure dropmapping(); + + procedure dbstats(const adbname: msestring; + const aoptions: dbstatoptionsty; const acommandline: msestring; + var res: msestringarty; const maxrowcount: int32 = -1); + //ring buffer, -1 -> unlimited + procedure properties(const adbname: msestring; + const ainfo: fbpropertyinfoty; const aitems: fbpropertyitemsty; + var res: msestringarty; const maxrowcount: integer= -1); + //ring buffer, -1 -> unlimited + + procedure validatestart(const dbname: msestring; + const tabincl: msestring = ''; const tabexcl: msestring = ''; + const idxincl: msestring = ''; const idxexcl: msestring = ''; + const locktimeout: card32 = 0); + procedure backupstart(const dbname: msestring; + const backupfiles: array of msestring; + const lengths: array of card32; //bytes, no item for last file + const verbose: boolean = false; const stat: string = ''; + //stat for FB 2.5.5 only, 1..4 chars, valid chars = T|D|R|W + const aoptions: backupoptionsty = []; const factor: card32 = 0); + procedure restorestart(const backupfiles: array of msestring; + const dbfiles: array of msestring; const lengths: array of card32; + //pages, none for last dbfile + const verbose: boolean = false; const stat: string = ''; + //stat for FB 2.5.5 only, 1..4 chars, valid chars = T|D|R|W + const aoptions: restoreoptionsty = []; + const accessmode: accessmodety = amo_readwrite; + const buffers: card32 = 0; const pagesize: card32 = 0; + const fixfssdata: string = ''; const fixfssmetadata: string = ''); + //CHARACTER SET CHARACTER SET + procedure nbakstart(const dbname: msestring; const _file: msestring; + const level: card32; const options: nbakoptionsty; + const direct: string = ''); + //'on or 'off' + procedure nreststart(const dbname: msestring; + const files: array of msestring; const options: nbakoptionsty); + procedure repairstart(const adbname: msestring; + const aoptions: repairoptionsty); + +// property lasterror: statusvectorty read flasterror; + property lasterrormessage: msestring read flasterrormessage; + property asynctext: msestringarty read fasynctext write fasynctext; + published + property asyncmaxrowcount: int32 read fasyncmaxrowcount + write fasyncmaxrowcount default 0; //-1 = unlimited + property hostname : ansistring read fhostname write fhostname; + property username : ansistring read fusername write fusername; + property password : ansistring read fpassword write fpassword; + property connected: boolean read getconnected + write setconnected default false; + //connected will be reset by a server error + property options: fbserviceoptionsty read foptions write foptions default []; + property infotimeout: int32 read finfotimeout write finfotimeout + default defaultinfotimeout; //seconds, -1 -> none + property onasynctext: fbservicetexteventty read fonasynctext + write fonasynctext; + property onasyncend: fbserviceendeventty read fonasyncend + write fonasyncend; //runs in service thread + property onasyncendmain: fbserviceendeventty read fonasyncendmain + write fonasyncendmain; //runs in main thread + + property onerror: fbserviceerroreventty read fonerror write fonerror; + end; + +implementation +uses + msebits,msearrayutils,mseapplication,msesysintf,msefileutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + restoreconsts: array[restoreoptionty] of card32 = (isc_spb_res_deactivate_idx, + isc_spb_res_no_shadow,isc_spb_res_no_validity,isc_spb_res_one_at_a_time, + isc_spb_res_replace,isc_spb_res_create,isc_spb_res_use_all_space); + accessmodeconsts: array[accessmodety] of card32 = (isc_spb_prp_am_readonly, + isc_spb_prp_am_readwrite); + writemodeconsts: array[writemodety] of card32 = (isc_spb_prp_wm_async, + isc_spb_prp_wm_sync); + propertyconsts: array[propertyoptionty] of card32 = (isc_spb_prp_activate, + isc_spb_prp_db_online); + reservespaceconsts: array[reservespacety] of card32 = (isc_spb_prp_res_use_full, + isc_spb_prp_res); +const + asyncendtag = 5790432; //not aborted, +1 -> aborted + +function readvalue16(var buffer: pbyte): card16; +begin + result:= buffer^; + inc(buffer); + result:= result + buffer^ shl 8; + inc(buffer); +end; + +function readvalue32(var buffer: pbyte): card16; +begin + result:= buffer^; + inc(buffer); + result:= result + buffer^ shl 8; + inc(buffer); + result:= result + buffer^ shl 16; + inc(buffer); + result:= result + buffer^ shl 24; + inc(buffer); +end; + +procedure storevalue(var buffer: pbyte; const value: card16); +begin + buffer^:= value; + inc(buffer); + buffer^:= value shr 8; + inc(buffer); +end; + +procedure storevalue(var buffer: pbyte; const value: card32); +begin + buffer^:= value; + inc(buffer); + buffer^:= value shr 8; + inc(buffer); + buffer^:= value shr 16; + inc(buffer); + buffer^:= value shr 24; + inc(buffer); +end; + +procedure addshortparam(var params: string; const id: int32; + const value: string); + //value limited to 255 chars +var + i1,i2: int32; + po1: pbyte; +begin + i1:= length(value); + if i1 > 255 then begin + i1:= 255; + end; + i2:= length(params); + setlength(params,i2+2+i1); + po1:= pointer(params)+i2; + po1^:= id; + inc(po1); + po1^:= i1; + inc(po1); + move(pointer(value)^,po1^,i1); +end; + +procedure addparam(var params: string; const id: int32; + const value: string); + //value limited to 65535 chars +var + i1,i2: int32; + po1: pbyte; +begin + i1:= length(value); + if i1 > 65535 then begin + i1:= 65553; + end; + i2:= length(params); + setlength(params,i2+3+i1); + po1:= pointer(params)+i2; + po1^:= id; + inc(po1); + storevalue(po1,card16(i1)); + move(pointer(value)^,po1^,i1); +end; + +procedure addparam(var params: string; const id: int32; + const value: card32); +var + i2: int32; + po1: pbyte; +begin + i2:= length(params); + setlength(params,i2+1+4); + po1:= pointer(params)+i2; + po1^:= id; + inc(po1); + storevalue(po1,value); +end; + +procedure addparam(var params: string; const id: int32); +var + i2: int32; + po1: pbyte; +begin + i2:= length(params); + setlength(params,i2+1+0); + po1:= pointer(params)+i2; + po1^:= id; +end; + +procedure addparam(var params: string; const id: int32; + const value: card8); +var + i2: int32; + po1: pbyte; +begin + i2:= length(params); + setlength(params,i2+1+1); + po1:= pointer(params)+i2; + po1^:= id; + inc(po1); + po1^:= value; + inc(po1); +end; + +procedure addtimeout(var params: string; const atimeout: card32); +var + i2: int32; + po1: pbyte; +begin + if int32(atimeout) >= 0 then begin + i2:= length(params); + setlength(params,i2+1+4+4+1); + po1:= pointer(params)+i2; + po1^:= isc_info_svc_timeout; + inc(po1); + storevalue(po1,card16(4)); //len + storevalue(po1,atimeout); + inc(po1); + po1^:= isc_info_end; + end; +end; + +function getvalueitem(var buffer: pointer; const id: int32; + var value: card32): boolean; +begin + result:= false; + if pbyte(buffer)^ = id then begin + inc(buffer); + value:= readvalue32(buffer); + result:= true; + end; +end; + +function getstringitem(var buffer: pointer; const id: int32; + var value: string): boolean; +var + i1: int32; +begin + result:= false; + if pbyte(buffer)^ = id then begin + inc(buffer); + i1:= readvalue16(buffer); + setlength(value,i1); + move((buffer)^,pointer(value)^,i1); + inc(buffer,i1); + result:= true; + end; +end; + +{ efbserviceerror3 } + +constructor efbserviceerror3.create(const asender: tfb3service; + const astatus: istatus; const aerrormessage: msestring); +var + str1: string; + msg1: msestring; + po1: nativeintptr; + err1: integer; +begin + str1:= formatstatus(astatus); + msg1:= aerrormessage; + if str1 <> '' then begin + msg1:= msg1 + lineend + msestring(str1); + end; + po1:= astatus.geterrors; + err1:= 0; + if po1 <> nil then begin + err1:= gds__sqlcode(po1); + end; + fsender:= sender; + ferror:= err1; + ferrormessage:= msg1; + if sender <> nil then begin + sender.flasterrormessage:= msg1; + end; + inherited create(asender.name+': '+ansistring(msg1)); +end; + +{ tfbservicemonitor3 } + +constructor tfbservicemonitor3.create(const aowner: tfb3service; + const procname: msestring); +begin + fowner:= aowner; + fprocname:= procname; + inherited create(); +end; + +destructor tfbservicemonitor3.destroy(); +begin + terminate(); + application.waitforthread(self); + inherited; +end; + +function tfbservicemonitor3.execute(thread: tmsethread): integer; + + procedure cancel(); + begin + if fowner.connected then begin + fowner.closeconn(); + fowner.connected:= true; + end; + end; //cancel + +var + params1,items1,buffer1: string; + po1: pointer; + i1,i2,rowmax1: int32; + str1: string; + ok: boolean; + ar1: msestringarty; + ar2: pointerarty; + rowindex1: int32; + mstr1,remainder: msestring; + po2,ps,pe: pmsechar; + + procedure add(); + begin + if length(ar1) < rowmax1 then begin + additem(ar1,remainder); + end + else begin + if rowmax1 <> 0 then begin + ar1[rowindex1]:= remainder; + inc(rowindex1); + if rowindex1 >= rowmax1 then begin + rowindex1:= 0; + end; + end; + end; + remainder:= ''; + end; //add + + procedure endtext(const canceled: boolean); + var + i1: int32; + begin + if rowindex1 = 0 then begin + fowner.fasynctext:= ar1; + end + else begin + allocuninitedarray(length(ar1),sizeof(pointer),ar2); + i1:= rowmax1-rowindex1; + move(ar1[rowindex1],ar2[0],i1*sizeof(pointer)); + move(ar1[0],ar2[i1],rowindex1*sizeof(pointer)); + fowner.fasynctext:= nil; + pointer(fowner.fasynctext):= pointer(ar1); + pointer(ar1):= nil; + end; + if assigned(fowner.fonasyncend) then begin + fowner.fonasyncend(fowner,true); + end; + if assigned(fowner.fonasyncendmain) then begin + if canceled then begin + fowner.asyncevent(asyncendtag+1); + end + else begin + fowner.asyncevent(asyncendtag); + end; + end; + end; + +const + buffersize = 4096; +begin + ok:= false; + params1:= ''; + addtimeout(params1,1); //1 sec min timeout + setlength(buffer1,buffersize); + items1:= char(isc_info_svc_to_eof); + str1:= ''; + remainder:= ''; + rowindex1:= 0; + rowmax1:= 0; + ar1:= nil; + try + while not terminated and not application.terminated do begin + fowner.clearstatus(); + fowner.fservice.query(fowner.fapi.status,length(params1),pointer(params1), + length(items1),pointer(items1),length(buffer1),pointer(buffer1)); + // fowner.checkerror(fprocname,isc_service_query(@fowner.fstatus,@fowner.fhandle, + // nil,length(params1),pointer(params1),length(items1),pointer(items1), + // length(buffer1),pointer(buffer1))); + fowner.checkstatus(fprocname); + if terminated or application.terminated then begin + break; + end; + case pbyte(pointer(buffer1))^ of + isc_info_svc_to_eof: begin + po1:= pointer(buffer1)+1; + i1:= readvalue16(po1); + if i1 > 0 then begin + i2:= length(str1); + setlength(str1,i1+i2); + move(po1^,(pointer(str1)+i2)^,i1); + end; + if i1 < buffersize-10 then begin + //not truncated, firebird seems not to fill buffer completely + if str1 <> '' then begin + application.lock(); + try + mstr1:= fowner.tomsestring(str1); + rowmax1:= fowner.fasyncmaxrowcount; + if rowmax1 < 0 then begin + rowmax1:= high(rowmax1); + end; + if length(ar1) > rowmax1 then begin + setlength(ar1,rowmax1); + end; + if rowindex1 > rowmax1 then begin + rowindex1:= 0; + end; + if rowmax1 > 0 then begin + po2:= pointer(mstr1); + ps:= po2; + pe:= po2+length(mstr1); + while po2 < pe do begin + if (po2^ = c_return) or (po2^ = c_linefeed) then begin + addstringsegment(remainder,ps,po2); + add(); + if (po2^ = c_return) then begin + inc(po2); + end; + if (po2^ = c_linefeed) then begin + inc(po2); + end; + ps:= po2; + end + else begin + inc(po2); + end; + end; + addstringsegment(remainder,ps,po2); + end; + if assigned(fowner.fonasynctext) then begin + fowner.fonasynctext(fowner,mstr1); + end; + finally + application.unlock(); + end; + str1:= ''; + end + else begin + application.lock(); + try + if not fowner.serviceisrunning() then begin + add(); + ok:= true; + cancel(); + endtext(false); + break; + end; + finally + application.unlock(); + end; + end; + end; + end; + else begin + fowner.invalidresponse(fprocname); + end; + end; + end; + finally + if not ok then begin + application.lock(); + try + add(); + cancel(); + endtext(true); + finally + application.unlock(); + end; + end; + end; + result:= 0; +end; + +{ tfb3service } + +constructor tfb3service.create(aowner: tcomponent); +begin +// fhandle:= FB_API_NULLHANDLE; + finfotimeout:= defaultinfotimeout; + inherited; +end; + +destructor tfb3service.destroy(); +begin + disconnect(); + inherited; +end; + +procedure tfb3service.cancel(); +begin + freeandnil(fmonitor); + if connected then begin + connected:= false; + connected:= true; + end; +end; + +function tfb3service.busy(): boolean; +begin + result:= fbss_busy in fstate; +end; + +function tfb3service.getconnected: boolean; +begin + result:= fservice <> nil; +end; + +procedure tfb3service.setconnected(const avalue: boolean); +begin + if csreading in componentstate then begin + updatebit1(card32(fstate),ord(fbss_connected),avalue); + end + else begin + if avalue then begin + connect(); + end + else begin + disconnect(); + end; + end; +end; + +function tfb3service.connectionmessage(atext: pchar): msestring; +begin + if fbso_utf8message in foptions then begin + result:= utf8tostring(atext); + end + else begin + result:= atext; + end; +end; + +procedure tfb3service.loaded(); +begin + inherited; + if fbss_connected in fstate then begin + connect(); + end; +end; + +procedure tfb3service.doasyncevent(var atag: int32); +begin + inherited; + if canevent(tmethod(fonasyncendmain)) then begin + if atag = asyncendtag then begin + fonasyncendmain(self,false); + end + else begin + if (atag = asyncendtag+1) then begin + fonasyncendmain(self,false); + end; + end; + end; +end; + +procedure tfb3service.clearstatus(); +begin + fapi.status.init(); +end; + +function tfb3service.statusok(): boolean; +begin + result:= fapi.status.getstate() and istatus.state_errors = 0 +end; + +procedure tfb3service.checkstatus(const aerrormessage: msestring); +begin + if fapi.status.getstate() and istatus.state_errors <> 0 then begin + raise efbserviceerror3.create(self,fapi.status,aerrormessage); + end; +end; + +procedure tfb3service.connect(); +const + servicename = 'service_mgr'; +var + params1: string; + str1: string; +begin + if fservice = nil then begin + try + inifbapi(fapi); + if fhostname = '' then begin + str1:= servicename; + end + else begin + str1:= fhostname + ':' + servicename; //tcp/ip + end; + params1:= char(isc_spb_version)+char(isc_spb_current_version); + addshortparam(params1,isc_spb_user_name,fusername); + addshortparam(params1,isc_spb_password,fpassword); + clearstatus(); +// checkerror('Connect',isc_service_attach(@fstatus,length(str1),pointer(str1), +// @fhandle,length(params1),pointer(params1))); + fservice:= fapi.provider.attachservicemanager(fapi.status,pchar(str1), + length(params1),pointer(params1)); + checkstatus('Connect'); + fservice.addref(); + except + exclude(fstate,fbss_connected); + fservice:= nil; + finifbapi(fapi); + raise; + end; + end; + include(fstate,fbss_connected); +end; + +procedure tfb3service.closeconn(); +begin + fstate:= fstate - [fbss_connected,fbss_busy]; + if fservice <> nil then begin + fservice.detach(fapi.status); + fservice.release(); + fservice:= nil; + finifbapi(fapi); + end; +end; + +procedure tfb3service.disconnect(); +begin + if (fmonitor <> nil) and + (sys_getcurrentthread() <> fmonitor.id) then begin + freeandnil(fmonitor); + end; + closeconn(); +end; + +procedure tfb3service.readstate(reader: treader); +begin + disconnect(); + inherited; +end; + +procedure tfb3service.raiseerror(const e: exception; const dberr: boolean); +var + bo1: boolean; + e1: exception; +begin + application.lock(); + try + if dberr then begin + connected:= false; //cancel possible running task + end; + e1:= e; + if canevent(tmethod(fonerror)) then begin + bo1:= false; + try + fonerror(self,e1,bo1); + except + e1.free; + raise; + end; + if bo1 then begin + e1.free; + end + else begin + raise e1; + end; + end + else begin + raise e1; + end; + finally + application.unlock(); + end; +end; + +procedure tfb3service.dberror(const msg: msestring; const comp: tcomponent; + const dberr: boolean); +begin + raiseerror(edatabaseerror.create(ansistring(msg),comp),dberr); +end; +(* +procedure tfb3service.checkerror(const procname: string; + const status: statusvectorty); +var + buf: array [0..1024] of char; + p: pointer; + Msg: msestring; +begin + if ((Status[0] = 1) and (Status[1] <> 0)) then begin + p:= @Status; + msg:= msestring(procname); +//{$warnings off} + while isc_interprete(Buf, @p) > 0 do begin + Msg := Msg + lineend +' -' + connectionmessage(Buf); + end; + flasterror:= status; + flasterrormessage:= msg; + raiseerror(efbserviceerror3.create(self,msg,status),true); + end; +end; +//{$warnings on} + +procedure tfb3service.checkerror(const procname: string; const status: integer); +begin + if status <> 0 then begin + checkerror(procname,fstatus); + end; +end; +*) +procedure tfb3service.checkbusy(); +begin + if not connected then begin + dberror('Not connected',self,false); + end; + if busy then begin + dberror('Busy',self,false); + end; +end; + +procedure tfb3service.invalidresponse(const procname: msestring); +begin + raiseerror(edatabaseerror.create( + ansistring('Invalid '+procname+' response'),self),true); +end; + +function tfb3service.todbstring(const avalue: msestring): string; +begin + if fbso_utf8 in foptions then begin + result:= stringtoutf8ansi(avalue); + end + else begin + result:= ansistring(avalue); + end; +end; + +function tfb3service.tomsestring(const avalue: string): msestring; +begin + if fbso_utf8 in foptions then begin + result:= utf8tostring(avalue); + end + else begin + result:= msestring(avalue); + end; +end; + +procedure tfb3service.start(const procname: msestring; const params: string); +begin + checkbusy(); + fasynctext:= nil; + clearstatus(); + fservice.start(fapi.status,length(params),pointer(params)); +// checkerror(procname,isc_service_start(@fstatus,@fhandle,nil, +// length(params),pointer(params))); + checkstatus(procname); + include(fstate,fbss_busy); +end; + +function tfb3service.getinfo(const procname: msestring; + const items: array of byte; const async: boolean): string; +var + params1: string; +begin + params1:= ''; + addtimeout(params1,finfotimeout); + setlength(result,1024); + while true do begin + clearstatus(); + fservice.query(fapi.status,length(params1),pointer(params1), + length(items),@items[0],length(result),pointer(result)); +// checkerror(procname,isc_service_query(@fstatus,@fhandle,nil,length(params1), +// pointer(params1),length(items),@items[0],length(result),pointer(result))); + checkstatus(procname); + if pbyte(pointer(result))^ <> isc_info_truncated then begin + if not async then begin + exclude(fstate,fbss_busy); + end; + break; + end; + setlength(result,2*length(result)); + end; +end; + +procedure tfb3service.runcommand(const procname: msestring; + const params: string); +var + ar1: msestringarty; +begin + gettext(procname,params,ar1,1); +end; + +function tfb3service.getmsestringitem(var buffer: pointer; out res: msestring; + const cutspace: boolean = false): boolean; +var + i1,i2: int32; +begin + i1:= readvalue16(buffer); + i2:= i1; + result:= i1 <= 0; + if cutspace and not result and (pchar(buffer)[i1-1] = ' ') then begin + dec(i2); + end; + if fbso_utf8 in foptions then begin + res:= utf8tostring(buffer,i2); + end + else begin + widestringmanager.ansi2unicodemoveproc(buffer, + {$ifdef mse_fpc_3}cp_acp,{$endif}res,i2); + end; + inc(buffer,i1); +end; + +function tfb3service.getmsestringitem(var buffer: pointer; const id: int32; + var value: msestring): boolean; +begin + result:= false; + if pbyte(buffer)^ = id then begin + inc(buffer); + getmsestringitem(buffer,value); + result:= true; + end; +end; + +procedure tfb3service.addmseparam(var params: string; const id: int32; + const value: msestring); +begin + addparam(params,id,todbstring(value)); +end; +{ +function tfb3service.getline(const procname: string; + var res: msestring; out eof: boolean): boolean; +var + params1: string; + items1: string; + buffer1: string; + po1: pointer; +begin + result:= true; + eof:= true; + params1:= ''; + addparam(params1,isc_info_svc_timeout,1); //minimal timeout (1sec) + setlength(buffer1,1024); //max line length + items1:= char(isc_info_svc_line); +// addparam(items1,isc_info_svc_timeout,1); //minimal timeout (1sec) + checkerror(procname,isc_service_query(@fstatus,@fhandle,nil,length(params1), + pointer(params1),length(items1),pointer(items1), + length(buffer1),pointer(buffer1))); + case pbyte(pointer(buffer1))^ of + isc_info_svc_line: begin //timeout? + po1:= pointer(buffer1)+1; + eof:= getmsestringitem(po1,res,true); + end; + else begin + invalidresponse(procname); + end; + end; +end; +} +function tfb3service.serverinfo(): fbserverinfoty; +var + buffer: string; + po1: pbyte; +begin + checkbusy(); + finalize(result); + fillchar(result,sizeof(result),0); + buffer:= getinfo('serverinfo',[isc_info_svc_version, + isc_info_svc_server_version,isc_info_svc_implementation, + isc_info_svc_capabilities,isc_info_svc_user_dbpath, + isc_info_svc_get_env,isc_info_svc_get_env_lock, + isc_info_svc_get_env_msg],false); + po1:= pointer(buffer); + with result do begin + while (po1^ <> isc_info_end) and (po1^ <> 0) do begin + if not (getvalueitem(po1,isc_info_svc_version,version) or + getmsestringitem(po1,isc_info_svc_server_version,server_version) or + getmsestringitem(po1,isc_info_svc_implementation,_implementation) or + getvalueitem(po1,isc_info_svc_capabilities,capabilities) or + getmsestringitem(po1,isc_info_svc_user_dbpath,user_dbpath) or + getmsestringitem(po1,isc_info_svc_get_env,get_env) or + getmsestringitem(po1,isc_info_svc_get_env_lock,get_env_lock) or + getmsestringitem(po1,isc_info_svc_get_env_msg,get_env_msg)) then begin + invalidresponse('serverinfo'); + end; + end; + end; +end; + +function tfb3service.internalusers(const ausername: string): fbuserinfoarty; +var + params1,buffer1: string; + po1: pbyte; + count: int32; + po2: pfbuserinfoty; +begin + checkbusy(); + params1:= char(isc_action_svc_display_user_adm); + if ausername <> '' then begin + addparam(params1,isc_spb_sec_username,ausername); + end; + start('users',params1); + result:= nil; + count:= 0; + buffer1:= getinfo('users',[isc_info_svc_get_users],false); + po1:= pointer(buffer1); + if po1^ <> isc_info_svc_get_users then begin + invalidresponse('users'); + end; + inc(po1,3); //additional bytes 50 0 ??? + while (po1^ <> isc_info_flag_end) and (po1^ <> isc_info_end) and + (po1^ <> 0) do begin + if po1^ = isc_spb_sec_username then begin //must be first field + additem(result,typeinfo(result),count); + po2:= @result[count-1]; + getmsestringitem(po1,isc_spb_sec_username,po2^.username) + end + else begin + if result = nil then begin + invalidresponse('users'); + end; + end; + with po2^ do begin + while (po1^ <> isc_spb_sec_username) and (po1^ <> isc_info_flag_end) and + (po1^ <> isc_info_end) and (po1^ <> 0) do begin + if not (getmsestringitem(po1,isc_spb_sec_firstname,firstname) or + getmsestringitem(po1,isc_spb_sec_middlename,middlename) or + getmsestringitem(po1,isc_spb_sec_lastname,lastname) or + getmsestringitem(po1,isc_spb_sec_groupname,groupname) or + getmsestringitem(po1,isc_spb_sql_role_name,rolename) or + getvalueitem(po1,isc_spb_sec_userid,userid) or + getvalueitem(po1,isc_spb_sec_groupid,groupid) or + getvalueitem(po1,isc_spb_sec_admin,admin)) then begin + invalidresponse('users'); + end; + end; + end; + end; + setlength(result,count); +end; + +function tfb3service.users(): fbuserinfoarty; +begin + result:= internalusers(''); +end; + +function tfb3service.user(const ausername: msestring; + var ainfo: fbuserinfoty): boolean; +var + ar1: fbuserinfoarty; +begin + ar1:= internalusers(todbstring(ausername)); + result:= ar1 <> nil; + if result then begin + ainfo:= ar1[0]; + end; +end; + +procedure tfb3service.adduserparams(var params1: string; + const ainfo: fbuserinfoty; const aitems: fbuseritemsty); +begin + with ainfo do begin + if fbu_username in aitems then begin + addmseparam(params1,isc_spb_sec_username,username); + end; + if fbu_firstname in aitems then begin + addmseparam(params1,isc_spb_sec_firstname,firstname); + end; + if fbu_middlename in aitems then begin + addmseparam(params1,isc_spb_sec_middlename,middlename); + end; + if fbu_lastname in aitems then begin + addmseparam(params1,isc_spb_sec_lastname,lastname); + end; + if fbu_groupname in aitems then begin + addmseparam(params1,isc_spb_sec_groupname,groupname); + end; + if fbu_rolename in aitems then begin + addmseparam(params1,isc_spb_sql_role_name,rolename); + end; + if fbu_userid in aitems then begin + addparam(params1,isc_spb_sec_userid,userid); + end; + if fbu_groupid in aitems then begin + addparam(params1,isc_spb_sec_groupid,groupid); + end; + if fbu_admin in aitems then begin + addparam(params1,isc_spb_sec_admin,admin); + end; + if fbu_password in aitems then begin + addparam(params1,isc_spb_sec_password,password); + end; + end; +end; + +procedure tfb3service.adduser(const ainfo: fbuserinfoty; + const items: fbuseritemsty); +var + params1: string; +begin + params1:= char(isc_action_svc_add_user); + adduserparams(params1,ainfo,items); + runcommand('adduser',params1); +end; + +procedure tfb3service.modifyuser(const ainfo: fbuserinfoty; + const items: fbuseritemsty); +var + params1: string; +begin + params1:= char(isc_action_svc_modify_user); + adduserparams(params1,ainfo,items); + runcommand('modifyuser',params1); +end; + +procedure tfb3service.deleteuser(const ausername: msestring; + const arolename: msestring = ''); +var + params1: string; +begin + params1:= char(isc_action_svc_delete_user); + addmseparam(params1,isc_spb_sec_username,ausername); + if arolename <> '' then begin + addmseparam(params1,isc_spb_sql_role_name,arolename); + end; + runcommand('deleteuser',params1); +end; + +procedure tfb3service.gettext(const procname: msestring; const params: string; + var res: msestringarty; const maxrowcount: integer); + +var + circindex: int32; + + procedure add(const atext: pchar; const len: int32); + var + mstr1: msestring; + begin + if fbso_utf8 in foptions then begin + mstr1:= utf8tostring(atext,len); + end + else begin + widestringmanager.ansi2unicodemoveproc(atext, + {$ifdef mse_fpc_3}cp_acp,{$endif}mstr1,len); + end; + if (maxrowcount > 0) and (length(res) >= maxrowcount) then begin + res[circindex]:= mstr1; + inc(circindex); + if circindex >= maxrowcount then begin + circindex:= 0; + end; + end + else begin + additem(res,mstr1); + end; + end; + +var + params1,items1,buffer1: string; + po1: pointer; + pa,pb,pc,pe: pchar; + i1: int32; + remainder: string; + ar1: pointerarty; +begin + checkbusy(); + start(procname,params); + res:= nil; + params1:= ''; + addtimeout(params1,finfotimeout); + setlength(buffer1,4096); + items1:= char(isc_info_svc_to_eof); + remainder:= ''; + circindex:= 0; + while true do begin + clearstatus(); + fservice.query(fapi.status,length(params1),pointer(params1), + length(items1),pointer(items1),length(buffer1),pointer(buffer1)); + checkstatus(procname); +// checkerror(procname,isc_service_query(@fstatus,@fhandle,nil,length(params1), +// pointer(params1),length(items1),pointer(items1), +// length(buffer1),pointer(buffer1))); + case pbyte(pointer(buffer1))^ of + isc_info_svc_to_eof: begin + po1:= pointer(buffer1)+1; + i1:= readvalue16(po1); + if i1 <= 0 then begin + if serviceisrunning() then begin + dberror(procname+': Timeout',self,true); + end; + break; //eof + end; + if i1 > length(buffer1)-1-2 then begin + invalidresponse(procname); + end; + if maxrowcount <> 0 then begin + pa:= po1; + pb:= pa; + pe:= pa + i1; + while (pb < pe) do begin + if pb^ = c_linefeed then begin + pc:= pb; + if (pc > pa) and ((pc-1)^ = c_return) then begin + dec(pc); + end; + if remainder <> '' then begin + remainder:= remainder+stringsegment(pa,pb); + add(pointer(remainder),length(remainder)); + remainder:= ''; + end + else begin + add(pa,pc-pa); + end; + pa:= pb+1; + end; + inc(pb); + end; + remainder:= remainder+stringsegment(pa,pe); + end; + end; + else begin + invalidresponse(procname); + end; + end; + end; + if maxrowcount <> 0 then begin + add(pointer(remainder),length(remainder)); + end; + if circindex > 0 then begin + allocuninitedarray(length(res),sizeof(pointer),ar1); + i1:= maxrowcount-circindex; + move(res[circindex],ar1[0],i1*sizeof(pointer)); + move(res[0],ar1[i1],circindex*sizeof(pointer)); + res:= pointer(ar1); + pointer(ar1):= nil; + +// ar1:= copy(res,circindex,maxrowcount-circindex); +// stackarray(copy(res,0,circindex),ar1); +// res:= ar1; + end; + exclude(fstate,fbss_busy); +end; + +procedure tfb3service.startmonitor(const procname: msestring; + const aparams: string); +begin +// checkbusy(); + start(procname,aparams); + freeandnil(fmonitor); + fmonitor:= tfbservicemonitor3.create(self,procname); +end; + +function tfb3service.serviceisrunning(): boolean; +var + buffer1: string; + po1: pointer; + ca1: card32; +begin + result:= false; + if busy then begin + buffer1:= getinfo('serviceisrunning',[isc_info_svc_running],true); + po1:= pointer(buffer1); + if getvalueitem(po1,isc_info_svc_running,ca1) then begin + result:= ca1 <> 0; + end; + end; +end; + +procedure tfb3service.getlog(var res: msestringarty; + const maxrowcount: int32 = -1); +begin + tagaction('getlog',isc_action_svc_get_fb_log,res,maxrowcount); +end; + +procedure tfb3service.tracestart(const cfg: msestring; + const _name: msestring = ''); +var + params1: string; +begin + params1:= char(isc_action_svc_trace_start); + addmseparam(params1,isc_spb_trc_cfg,cfg); + if _name <> '' then begin + addmseparam(params1,isc_spb_trc_name,_name); + end; + startmonitor('tracestart',params1); +end; + +procedure tfb3service.tagaction(const aprocname: msestring; + const aaction: int32; var res: msestringarty; + const maxrowcount: int32); +begin + gettext(aprocname,char(aaction),res,maxrowcount); +end; + +procedure tfb3service.tagaction(const aprocname: msestring; + const aaction: int32); +var + ar1: msestringarty; +begin + tagaction(aprocname,aaction,ar1,1); +end; + +procedure tfb3service.tracelist(var res: msestringarty; + const maxrowcount: int32 = -1); +begin + tagaction('tracelist',isc_action_svc_trace_list,res,maxrowcount); +end; + +procedure tfb3service.traceaction(const aprocname: msestring; + const aaction: int32; const aid: card32; var res: msestringarty; + const maxrowcount: int32); +var + params1: string; +begin + params1:= char(aaction); + addparam(params1,isc_spb_trc_id,aid); + gettext(aprocname,params1,res,maxrowcount); +end; + +procedure tfb3service.tracestop(const aid: card32; var res: msestringarty; + const maxrowcount: int32 = -1); +begin + traceaction('tracestop',isc_action_svc_trace_stop,aid,res,maxrowcount); +end; + +procedure tfb3service.tracesuspend(const aid: card32; var res: msestringarty; + const maxrowcount: int32 = -1); +begin + traceaction('tracesuspend',isc_action_svc_trace_suspend,aid,res,maxrowcount); +end; + +procedure tfb3service.traceresume(const aid: card32; var res: msestringarty; + const maxrowcount: int32 = -1); +begin + traceaction('traceresume',isc_action_svc_trace_resume,aid,res,maxrowcount); +end; + +procedure tfb3service.setmapping(); +begin + tagaction('setmapping',isc_action_svc_set_mapping); +end; + +procedure tfb3service.dropmapping(); +begin + tagaction('dropmapping',isc_action_svc_drop_mapping); +end; + +procedure tfb3service.dbstats(const adbname: msestring; + const aoptions: dbstatoptionsty; const acommandline: msestring; + var res: msestringarty; const maxrowcount: int32 = -1); +var + params1: string; +begin + params1:= char(isc_action_svc_db_stats); + addmseparam(params1,isc_spb_dbname,adbname); + addparam(params1,isc_spb_options,card32(aoptions)); + if acommandline <> '' then begin + addmseparam(params1,isc_spb_command_line,acommandline); + end; + gettext('dbstats',params1,res,maxrowcount); +end; + +procedure tfb3service.properties(const adbname: msestring; + const ainfo: fbpropertyinfoty; const aitems: fbpropertyitemsty; + var res: msestringarty; const maxrowcount: integer); +var + params1: string; + ca1: card32; + opt1: propertyoptionty; +begin + params1:= char(isc_action_svc_properties); + addmseparam(params1,isc_spb_dbname,adbname); + with ainfo do begin + if fbp_pagebuffers in aitems then begin + addparam(params1,isc_spb_prp_page_buffers,pagebuffers); + end; + if fbp_sweepinterval in aitems then begin + addparam(params1,isc_spb_prp_sweep_interval,sweepinterval); + end; + if fbp_shutdowndb in aitems then begin + addparam(params1,isc_spb_prp_shutdown_db,shutdowndb); + end; + if fbp_denynewattachments in aitems then begin + addparam(params1,isc_spb_prp_deny_new_attachments,denynewattachments); + end; + if fbp_denynewtransactions in aitems then begin + addparam(params1,isc_spb_prp_deny_new_transactions,denynewtransactions); + end; + if fbp_reservespace in aitems then begin + addparam(params1,isc_spb_prp_reserve_space, + card8(reservespaceconsts[reservespace])); + end; + if fbp_writemode in aitems then begin + addparam(params1,isc_spb_prp_write_mode, + card8(writemodeconsts[writemode])); + end; + if fbp_accessmode in aitems then begin + addparam(params1,isc_spb_prp_access_mode, + card8(accessmodeconsts[accessmode])); + end; + if fbp_setsqldialect in aitems then begin + addparam(params1,isc_spb_prp_set_sql_dialect,setsqldialect); + end; + if fbp_options in aitems then begin + ca1:= 0; + for opt1:= low(opt1) to high(opt1) do begin + ca1:= ca1 or propertyconsts[opt1]; + end; + addparam(params1,isc_spb_options,ca1); + end; + if fbp_forceshutdown in aitems then begin + addparam(params1,isc_spb_prp_force_shutdown,forceshutdown); + end; + if fbp_attachmentsshutdown in aitems then begin + addparam(params1,isc_spb_prp_attachments_shutdown,attachmentsshutdown); + end; + if fbp_transactionsshutdown in aitems then begin + addparam(params1,isc_spb_prp_transactions_shutdown,transactionsshutdown); + end; + if fbp_shutdownmode in aitems then begin + addparam(params1,isc_spb_prp_shutdown_mode,card8(shutdownmode)); + end; + if fbp_onlinemode in aitems then begin + addparam(params1,isc_spb_prp_online_mode,card8(onlinemode)); + end; + end; + gettext('properties',params1,res,maxrowcount); +end; + +procedure tfb3service.validatestart(const dbname: msestring; + const tabincl: msestring = ''; const tabexcl: msestring = ''; + const idxincl: msestring = ''; const idxexcl: msestring = ''; + const locktimeout: card32 = 0); +var + params1: string; +begin + params1:= char(isc_action_svc_validate); + addmseparam(params1,isc_spb_dbname,dbname); + if tabincl <> '' then begin + addmseparam(params1,isc_spb_val_tab_incl,tabincl); + end; + if tabexcl <> '' then begin + addmseparam(params1,isc_spb_val_tab_excl,tabexcl); + end; + if idxincl <> '' then begin + addmseparam(params1,isc_spb_val_idx_incl,idxincl); + end; + if idxexcl <> '' then begin + addmseparam(params1,isc_spb_val_idx_excl,idxexcl); + end; + if locktimeout <> 0 then begin + addparam(params1,isc_spb_val_lock_timeout,locktimeout); + end; + startmonitor('validatestart',params1); +end; + +procedure tfb3service.backupstart(const dbname: msestring; + const backupfiles: array of msestring; const lengths: array of card32; + const verbose: boolean = false; const stat: string = ''; + const aoptions: backupoptionsty = []; + const factor: card32 = 0); +var + params1: string; + i1: int32; + ca1: card32; +begin + params1:= char(isc_action_svc_backup); + addmseparam(params1,isc_spb_dbname,dbname); + for i1:= 0 to high(backupfiles) do begin + addmseparam(params1,isc_spb_bkp_file,backupfiles[i1]); + if i1 <= high(lengths) then begin + addparam(params1,isc_spb_bkp_length,lengths[i1]); + end; + end; + if verbose then begin + addparam(params1,isc_spb_verbose); + end; + if stat <> '' then begin + addparam(params1,isc_spb_bkp_stat,stat); + end; + ca1:= card32(aoptions - [bao_notriggers]); + if bao_notriggers in aoptions then begin + ca1:= ca1 or $8000; + end; + addparam(params1,isc_spb_options,ca1); + startmonitor('backupstart',params1); +end; + +procedure tfb3service.restorestart(const backupfiles: array of msestring; + const dbfiles: array of msestring; const lengths: array of card32; + const verbose: boolean = false; const stat: string = ''; + const aoptions: restoreoptionsty = []; + const accessmode: accessmodety = amo_readwrite; + const buffers: card32 = 0; const pagesize: card32 = 0; + const fixfssdata: string = ''; const fixfssmetadata: string = ''); +var + params1: string; + i1: int32; + ca1: card32; + opt1: restoreoptionty; +begin + params1:= char(isc_action_svc_restore); + for i1:= 0 to high(backupfiles) do begin + addmseparam(params1,isc_spb_bkp_file,tosysfilepath(backupfiles[i1])); + end; + for i1:= 0 to high(dbfiles) do begin + addmseparam(params1,isc_spb_dbname,tosysfilepath(dbfiles[i1])); + if i1 <= high(lengths) then begin + addparam(params1,isc_spb_res_length,lengths[i1]); + end; + end; + if verbose then begin + addparam(params1,isc_spb_verbose); + end; + if stat <> '' then begin + addparam(params1,isc_spb_res_stat,stat); + end; + if aoptions <> [] then begin + ca1:= 0; + for opt1:= low(opt1) to high(opt1) do begin + if opt1 in aoptions then begin + ca1:= ca1 or restoreconsts[opt1]; + end; + end; + addparam(params1,isc_spb_options,ca1); + end; + addparam(params1,isc_spb_res_access_mode,card8(accessmodeconsts[accessmode])); + if buffers <> 0 then begin + addparam(params1,isc_spb_res_buffers,buffers); + end; + if pagesize <> 0 then begin + addparam(params1,isc_spb_res_page_size,pagesize); + end; + if fixfssdata <> '' then begin + addparam(params1,isc_spb_res_fix_fss_data,fixfssdata); + end; + if fixfssmetadata <> '' then begin + addparam(params1,isc_spb_res_fix_fss_metadata,fixfssmetadata); + end; + startmonitor('restorestart',params1); +end; + +procedure tfb3service.nbakstart(const dbname: msestring; const _file: msestring; + const level: card32; const options: nbakoptionsty; + const direct: string = ''); +var + params1: string; +begin + params1:= char(isc_action_svc_nbak); + addmseparam(params1,isc_spb_dbname,dbname); + addmseparam(params1,isc_spb_nbk_file,_file); + addparam(params1,isc_spb_nbk_level,level); + addparam(params1,isc_spb_options,card32(options)); + if direct <> '' then begin + addparam(params1,isc_spb_nbk_direct,direct); + end; + startmonitor('nbak',params1); +end; + +procedure tfb3service.nreststart(const dbname: msestring; + const files: array of msestring; const options: nbakoptionsty); +var + params1: string; + i1: int32; +begin + params1:= char(isc_action_svc_nrest); + addmseparam(params1,isc_spb_dbname,dbname); + for i1:= 0 to high(files) do begin + addmseparam(params1,isc_spb_nbk_file,files[i1]); + end; + addparam(params1,isc_spb_options,card32(options)); + startmonitor('nrest',params1); +end; + +procedure tfb3service.repairstart(const adbname: msestring; + const aoptions: repairoptionsty); +var + params1: string; +begin + params1:= char(isc_action_svc_repair); + addmseparam(params1,isc_spb_dbname,adbname); + addparam(params1,isc_spb_options,card32(aoptions)); + startmonitor('repairstart',params1); +end; + +end. diff --git a/mseide-msegui/lib/common/db/msefbinterface.pas b/mseide-msegui/lib/common/db/msefbinterface.pas new file mode 100644 index 0000000..78e19c0 --- /dev/null +++ b/mseide-msegui/lib/common/db/msefbinterface.pas @@ -0,0 +1,397 @@ +{ MSEgui Copyright (c) 2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +// +// specialised api interfaces +// +unit msefbinterface; +{$ifdef FPC}{$mode delphi}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + firebird,msetypes,msefb3connection,mdb,msedb,msestrings; +type + + paraminfoty = record + _type: card32; + subtype: int32; + scale: int32; + charset: card32; + _length: card32; + offset: card32; + nulloffset: card32; + _isnull: boolean; + end; + paraminfoarty = array of paraminfoty; + + tparamdata = class(imessagemetadataimpl) + private + frefcount: int32; + fparambuffer: pointer; + fitems: paraminfoarty; + fcount: int32; + fmessagelength: int32; + public + constructor create(const cursor: tfbcursor; const params: tmseparams); + destructor destroy(); override; + procedure addRef() override; + function release(): Integer override; + function getCount(status: IStatus): Cardinal override; + function getField(status: IStatus; index: Cardinal): PAnsiChar override; + function getRelation(status: IStatus; index: Cardinal): PAnsiChar override; + function getOwner(status: IStatus; index: Cardinal): PAnsiChar override; + function getAlias(status: IStatus; index: Cardinal): PAnsiChar override; + function getType(status: IStatus; index: Cardinal): Cardinal override; + function isNullable(status: IStatus; index: Cardinal): Boolean override; + function getSubType(status: IStatus; index: Cardinal): Integer override; + function getLength(status: IStatus; index: Cardinal): Cardinal override; + function getScale(status: IStatus; index: Cardinal): Integer override; + function getCharSet(status: IStatus; index: Cardinal): Cardinal override; + function getOffset(status: IStatus; index: Cardinal): Cardinal override; + function getNullOffset(status: IStatus; index: Cardinal): Cardinal override; + function getBuilder(status: IStatus): IMetadataBuilder override; + function getMessageLength(status: IStatus): Cardinal override; + property parambuffer: pointer read fparambuffer; + end; + + tversioncallback = class(iversioncallbackimpl) + private + ftext: string; + public + procedure callback(status: IStatus; atext: PAnsiChar); override; + property text: string read ftext; + end; + +implementation +uses + msefirebird,dbconst,sysutils,msedate; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tfbcursor1 = class(tfbcursor); + tfbconnection1 = class(tfb3connection); + +{ tparamdata } + +constructor tparamdata.create(const cursor: tfbcursor; + const params: tmseparams); +var + i1: int32; + data: stringarty; + sqltype,sqllen: card32; + po1: pointer; + totsize1: int32; + align1: int32; + str1,str2: string; + dt1: tdatetime; + +begin + inherited create(); + addref(); + with tfbcursor1(cursor) do begin + fcount:= length(fparambinding); + totsize1:= 0; + if fcount > 0 then begin + setlength(fitems,fcount); + setlength(data,fcount); //string buffer + for i1:= 0 to fcount-1 do begin + sqltype:= 0; + sqllen:= 0; + align1:= 0; + with params[fparambinding[i1]],fitems[i1] do begin + _isnull:= isnull; + scale:= 0; + case datatype of + ftunknown: begin + if _isnull then begin + sqltype:= SQL_NULL+1; + end; + end; + ftboolean: begin + sqltype:= SQL_BOOLEAN+1; + sqllen:= 1; + end; + ftinteger,ftsmallint,ftword: begin + sqltype:= SQL_LONG+1; + sqllen:= 4; + align1:= 3; + end; + ftlargeint,ftbcd: begin + sqltype:= SQL_INT64+1; + sqllen:= 8; + if datatype = ftbcd then begin + scale:= -4; + end; + case blobkind of + bk_binary: begin + subtype:= isc_blob_untyped; + align1:= 3; //sizeof(SLONG), SLONG always 32 bit + end; + bk_text: begin + subtype:= isc_blob_text; + align1:= 3; //sizeof(SLONG), SLONG always 32 bit + end; + else begin + align1:= 7; + end; + end; + end; + ftfloat: begin + sqltype:= SQL_DOUBLE+1; + sqllen:= sizeof(double); + align1:= FB_DOUBLE_ALIGN-1; + end; + fttime,ftdate,ftdatetime: begin + sqltype:= SQL_TIMESTAMP+1; + sqllen:= sizeof(ISC_TIMESTAMP); + align1:= sizeof(ISC_DATE)-1; + end; + ftstring,ftwidestring,ftmemo,ftwidememo: begin + sqltype:= SQL_TEXT+1; + if not isnull then begin + data[i1]:= params.asdbstring(fparambinding[i1]); + sqllen:= length(data[i1]); + end; + end; + ftblob,ftgraphic,ftbytes,ftvarbytes,ftguid: begin + sqltype:= SQL_TEXT+1; + charset:= cs_binary; + if not isnull then begin + if datatype = ftguid then begin + setlength(data[i1],sizeof(tguid)); + pguid(pointer(data[i1]))^:= dbstringtoguid(asstring); + end + else begin + data[i1]:= asstring; + end; + sqllen:= length(data[i1]); + end; + end; + end; + if sqltype = 0 then begin + databaseerrorfmt(sunsupportedparameter,[fieldtypenames[datatype]], + fconnection); + end; + _type:= sqltype; + _length:= sqllen; + totsize1:= (totsize1 + align1) and not align1; + offset:= totsize1; + totsize1:= totsize1 + sqllen; + totsize1:= (totsize1 + 1) and not 1; + nulloffset:= totsize1; + totsize1:= totsize1 + 2; //null flag + end; + end; + getmem(fparambuffer,totsize1); + fmessagelength:= totsize1; + for i1:= 0 to fcount-1 do begin + with fitems[i1] do begin + po1:= fparambuffer + offset; + with params[fparambinding[i1]] do begin + if _isnull then begin + pisc_short(fparambuffer+nulloffset)^:= -1; + end + else begin; + pisc_short(fparambuffer+nulloffset)^:= 0; + end; + if _isnull then begin + if blobkind <> bk_none then begin + _type:= SQL_BLOB+1; + end; + end + else begin + case _type of + SQL_BOOLEAN+1: begin + pcard8(po1)^:= card8(asboolean); + end; + SQL_LONG+1: begin + pint32(po1)^:= asinteger; + end; + SQL_INT64+1: begin + if blobkind <> bk_none then begin + _type:= SQL_BLOB+1; + pisc_quad(po1)^:= ISC_QUAD(aslargeint); + end + else begin + if scale = -4 then begin + pcurrency(po1)^:= ascurrency; + end + else begin + pint64(po1)^:= aslargeint; + end; + end; + end; + SQL_DOUBLE+1: begin + pdouble(po1)^:= asfloat; + end; + SQL_TIMESTAMP+1: begin + dt1:= asdatetime; + pisc_timestamp(po1)^.timestamp_date:= trunc(dt1) - fbdatetimeoffset; + dt1:= abs(frac(dt1)); + pisc_timestamp(po1)^.timestamp_time:= + round(dt1*3600*24*ISC_TIME_SECONDS_PRECISION); + end; + SQL_TEXT+1: begin + move(pointer(data[i1])^,po1^,length(data[i1])); + end; + SQL_BLOB+1: begin + if subtype = isc_blob_text then begin + str1:= params.asdbstring(i1); + end + else begin + str1:= asstring; + end; + tfbconnection1(fconnection).writeblobdata(cursor.ftrans,'',nil, + pointer(str1),length(str1),nil,nil,str2); + pisc_quad(po1)^:= pisc_quad(pointer(str2))^; + end; + else begin + raise exception.create('Internal error 20160908A'); + end; + end; + end; + end; + end; + end; + end; + end; +end; + +destructor tparamdata.destroy(); +begin + inherited; + if fparambuffer <> nil then begin + freemem(fparambuffer); + end; +end; + +procedure tparamdata.addRef(); +begin + inc(frefcount); +end; + +function tparamdata.release(): Integer; +begin + dec(frefcount); + result:= frefcount; + if frefcount = 0 then begin + destroy(); + end; +end; + +function tparamdata.getCount(status: IStatus): Cardinal; +begin + result:= fcount; +end; + +function tparamdata.getField(status: IStatus; + index: Cardinal): PAnsiChar; +begin + result:= nil; +end; + +function tparamdata.getRelation(status: IStatus; + index: Cardinal): PAnsiChar; +begin + result:= nil; +end; + +function tparamdata.getOwner(status: IStatus; + index: Cardinal): PAnsiChar; +begin + result:= nil; +end; + +function tparamdata.getAlias(status: IStatus; + index: Cardinal): PAnsiChar; +begin + result:= nil; +end; + +function tparamdata.getType(status: IStatus; + index: Cardinal): Cardinal; +begin + result:= fitems[index]._type; +end; + +function tparamdata.isNullable(status: IStatus; + index: Cardinal): Boolean; +begin + result:= fitems[index]._type and 1 <> 0; +end; + +function tparamdata.getSubType(status: IStatus; + index: Cardinal): Integer; +begin + result:= fitems[index].subtype; +end; + +function tparamdata.getLength(status: IStatus; + index: Cardinal): Cardinal; +begin + result:= fitems[index]._length; +end; + +function tparamdata.getScale(status: IStatus; + index: Cardinal): Integer; +begin + result:= fitems[index].scale; +end; + +function tparamdata.getCharSet(status: IStatus; + index: Cardinal): Cardinal; +begin + result:= fitems[index].charset; +end; + +function tparamdata.getOffset(status: IStatus; + index: Cardinal): Cardinal; +begin + result:= fitems[index].offset; +end; + +function tparamdata.getNullOffset(status: IStatus; + index: Cardinal): Cardinal; +begin + result:= fitems[index].nulloffset; +end; + +function tparamdata.getBuilder(status: IStatus): IMetadataBuilder; +begin + result:= nil; +end; + +function tparamdata.getMessageLength(status: IStatus): Cardinal; +begin + result:= fmessagelength; +end; + +{ tversioncallback } + +procedure tversioncallback.callback(status: IStatus; atext: PAnsiChar); +begin + ftext:= ftext+atext+lineend; +end; + +end. diff --git a/mseide-msegui/lib/common/db/msefbservice.pas b/mseide-msegui/lib/common/db/msefbservice.pas new file mode 100644 index 0000000..397df18 --- /dev/null +++ b/mseide-msegui/lib/common/db/msefbservice.pas @@ -0,0 +1,1695 @@ +unit msefbservice; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$if fpc_fullversion >= 30000} + {$define mse_fpc_3} +{$endif} + +interface +uses + classes,mclasses,mseclasses,ibase60dyn,msetypes,mdb,msestrings,mibconnection, + msethread,sysutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + defaultinfotimeout = 60; //seconds + +type + fbserverinfoty = record + version: card32; + server_version: msestring; + _implementation: msestring; + capabilities: card32; + user_dbpath: msestring; + get_env: msestring; + get_env_lock: msestring; + get_env_msg: msestring; + end; + + fbuserinfoty = record + username: msestring; + firstname: msestring; + middlename: msestring; + lastname: msestring; + groupname: msestring; + rolename: msestring; + userid: card32; + groupid: card32; + admin: card32; + password: ansistring; + end; + pfbuserinfoty = ^fbuserinfoty; + fbuserinfoarty = array of fbuserinfoty; + + fbuseritemty = (fbu_username,fbu_firstname,fbu_middlename,fbu_lastname, + fbu_groupname,fbu_rolename,fbu_userid,fbu_groupid,fbu_admin, + fbu_password); + fbuseritemsty = set of fbuseritemty; + +const + allfbuseritems = [fbu_username,fbu_firstname,fbu_middlename,fbu_lastname, + fbu_groupname,fbu_rolename,fbu_userid,fbu_groupid,fbu_admin, + fbu_password]; + +type + accessmodety = (amo_readonly,amo_readwrite); + writemodety = (wmo_async,wmo_sync); + runmodety = (rmo_normal,rmo_multi,rmo_single,rmo_full); + reservespacety = (rsp_full,rsp_res); + propertyoptionty = (pro_activate,pro_dbonline); + propertyoptionsty = set of propertyoptionty; + + fbpropertyinfoty = record + pagebuffers: card32; + sweepinterval: card32; + shutdowndb: card32; + denynewattachments: card32; + denynewtransactions: card32; + reservespace: reservespacety; + writemode: writemodety; + accessmode: accessmodety; + setsqldialect: card32; + options: propertyoptionsty; + forceshutdown: card32; + attachmentsshutdown: card32; + transactionsshutdown: card32; + shutdownmode: runmodety; + onlinemode: runmodety; + end; + + fbpropertyitemty = (fbp_pagebuffers,fbp_sweepinterval,fbp_shutdowndb, + fbp_denynewattachments,fbp_denynewtransactions, + fbp_reservespace,fbp_writemode,fbp_accessmode, + fbp_setsqldialect,fbp_options,fbp_forceshutdown, + fbp_attachmentsshutdown,fbp_transactionsshutdown, + fbp_shutdownmode,fbp_onlinemode); + fbpropertyitemsty = set of fbpropertyitemty; + +const + allfbpropertyitems = [fbp_pagebuffers,fbp_sweepinterval,fbp_shutdowndb, + fbp_denynewattachments,fbp_denynewtransactions, + fbp_reservespace,fbp_writemode,fbp_accessmode, + fbp_setsqldialect,fbp_options,fbp_forceshutdown, + fbp_attachmentsshutdown,fbp_transactionsshutdown, + fbp_shutdownmode,fbp_onlinemode]; + +type + dbstatoptionty = (dbsto_datapages,dbsto_dblog,dbsto_hdrpages, + dbsto_idxpages,dbsto_sysrelations,dbsto_recordversions, + dbsto_table,dbsto_nocreation); + dbstatoptionsty = set of dbstatoptionty; + + backupoptionty = (bao_ignorechecksums,bao_ignorelimbo,bao_metadataonly, + bao_no_garbagecollect,bao_olddescriptions,bao_nontransportable, + bao_convert,bao_expand,bao_notriggers {=$8000}); + backupoptionsty = set of backupoptionty; + + restoreoptionty = (reo_deactivateidx,reo_no_shadow,reo_no_validity, + reo_one_at_a_time,reo_replace,reo_create,reo_use_all_space); + restoreoptionsty = set of restoreoptionty; + + repairoptionty = (rpo_validate_db,rpo_sweep_db,rpo_mend_db,limbo_trans, + rpo_check_db,rpo_ignore_checksum,rpo_kill_shadows,rpo_full); + repairoptionsty = set of repairoptionty; + + nbakoptionty = (nbo_notriggers); + nbakoptionsty = set of nbakoptionty; + + tfbservice = class; + + efbserviceerror = class(edatabaseerror) + private + ferror: integer; + ferrormessage: msestring; + fsender: tfbservice; + fstatus: statusvectorty; + public + constructor create(const asender: tfbservice; const amessage: msestring; + const aerror: statusvectorty); + property sender: tfbservice read fsender; + property error: integer read ferror; + property errormessage: msestring read ferrormessage; + property status: statusvectorty read fstatus; + end; + + fbservicestatety = (fbss_connected,fbss_busy); + fbservicestatesty = set of fbservicestatety; + fbserviceoptionty = (fbso_utf8,fbso_utf8message); + fbserviceoptionsty = set of fbserviceoptionty; + + fbservicetexteventty = procedure (const sender: tfbservice; + const atext: msestring) of object; + fbserviceerroreventty = procedure (const sender: tfbservice; + var e: exception; var handled: boolean) of object; + fbserviceendeventty = procedure (const sender: tfbservice; + const aborted: boolean) of object; + tfbservicemonitor = class(tmsethread) + private + fprocname: string; + protected + fowner: tfbservice; + function execute(thread: tmsethread): integer; override; + public + constructor create(const aowner: tfbservice; const procname: string); + destructor destroy(); override; + end; + + tfbservice = class(tmsecomponent) + private + fhostname: ansistring; + fusername: ansistring; + fpassword: ansistring; + fstate: fbservicestatesty; + fhandle: isc_svc_handle; + fstatus: statusvectorty; //array [0..19] of isc_status; + flasterror: statusvectorty; + flasterrormessage: msestring; + foptions: fbserviceoptionsty; + finfotimeout: int32; + fonasynctext: fbservicetexteventty; + fmonitor: tfbservicemonitor; + fonerror: fbserviceerroreventty; + fonasyncend: fbserviceendeventty; + fasynctext: msestringarty; + fasyncmaxrowcount: int32; + fonasyncendmain: fbserviceendeventty; + function getconnected: boolean; + procedure setconnected(const avalue: boolean); + protected + function connectionmessage(atext: pchar): msestring; + procedure loaded(); override; + procedure doasyncevent(var atag: int32); override; + procedure connect(); + procedure closeconn(); + procedure disconnect(); + procedure readstate(reader: treader); override; + procedure raiseerror(const e: exception; const dberr: boolean); + procedure dberror(const msg: string; const comp: tcomponent; + const dberr: boolean); + procedure checkerror(const procname : string; + const status : statusvectorty); + procedure checkerror(const procname : string; + const status: integer); + procedure checkbusy(); + procedure invalidresponse(const procname: string); + + procedure start(const procname: string; const params: string); + function getinfo(const procname: string; const items: array of byte; + const async: boolean): string; + procedure runcommand(const procname: string; const params: string); + function getmsestringitem(var buffer: pointer; out res: msestring; + const cutspace: boolean = false): boolean; + //returns eof state + function getmsestringitem(var buffer: pointer; const id: int32; + var value: msestring): boolean; + procedure addmseparam(var params: string; const id: int32; + const value: msestring); + //value limited to 65535 chars + function internalusers(const ausername: string): fbuserinfoarty; + procedure gettext(const procname: string; const params: string; + var res: msestringarty; const maxrowcount: integer); + //ring buffer + procedure startmonitor(const procname: string; const aparams: string); + function serviceisrunning: boolean; + procedure tagaction(const aprocname: string; const aaction: int32; + var res: msestringarty; + const maxrowcount: int32); + procedure tagaction(const aprocname: string; const aaction: int32); + procedure traceaction(const aprocname: string; const aaction: int32; + const aid: card32; var res: msestringarty; + const maxrowcount: int32); + procedure adduserparams(var params1: string; + const ainfo: fbuserinfoty; const aitems: fbuseritemsty); + public + constructor create(aowner: tcomponent); override; + destructor destroy(); override; + function todbstring(const avalue: msestring): string; + function tomsestring(const avalue: string): msestring; + procedure cancel(); + function busy(): boolean; + + function serverinfo(): fbserverinfoty; + function users(): fbuserinfoarty; + function user(const ausername: msestring; var ainfo: fbuserinfoty): boolean; + //false if not found + procedure adduser(const ainfo: fbuserinfoty; const items: fbuseritemsty); + procedure modifyuser(const ainfo: fbuserinfoty; const items: fbuseritemsty); + //fbu_username must be set + procedure deleteuser(const ausername: msestring; + const arolename: msestring = ''); + procedure getlog(var res: msestringarty; const maxrowcount: int32 = -1); + //ring buffer, -1 -> unlimited + procedure tracestart(const cfg: msestring; const _name: msestring = ''); + //async, stop it by connected:= false or call of cancel() + procedure tracelist(var res: msestringarty; const maxrowcount: int32 = -1); + //ring buffer, -1 -> unlimited + procedure tracestop(const aid: card32; var res: msestringarty; + const maxrowcount: int32 = -1); + //ring buffer, -1 -> unlimited + procedure tracesuspend(const aid: card32; var res: msestringarty; + const maxrowcount: int32 = -1); + //ring buffer, -1 -> unlimited + procedure traceresume(const aid: card32; var res: msestringarty; + const maxrowcount: int32 = -1); + //ring buffer, -1 -> unlimited + procedure setmapping(); + procedure dropmapping(); + + procedure dbstats(const adbname: msestring; + const aoptions: dbstatoptionsty; const acommandline: msestring; + var res: msestringarty; const maxrowcount: int32 = -1); + //ring buffer, -1 -> unlimited + procedure properties(const adbname: msestring; + const ainfo: fbpropertyinfoty; const aitems: fbpropertyitemsty; + var res: msestringarty; const maxrowcount: integer= -1); + //ring buffer, -1 -> unlimited + + procedure validatestart(const dbname: msestring; + const tabincl: msestring = ''; const tabexcl: msestring = ''; + const idxincl: msestring = ''; const idxexcl: msestring = ''; + const locktimeout: card32 = 0); + procedure backupstart(const dbname: msestring; + const backupfiles: array of msestring; + const lengths: array of card32; //bytes, no item for last file + const verbose: boolean = false; const stat: string = ''; + //stat for FB 2.5.5 only, 1..4 chars, valid chars = T|D|R|W + const aoptions: backupoptionsty = []; const factor: card32 = 0); + procedure restorestart(const backupfiles: array of msestring; + const dbfiles: array of msestring; const lengths: array of card32; + //pages, none for last dbfile + const verbose: boolean = false; const stat: string = ''; + //stat for FB 2.5.5 only, 1..4 chars, valid chars = T|D|R|W + const aoptions: restoreoptionsty = []; + const accessmode: accessmodety = amo_readwrite; + const buffers: card32 = 0; const pagesize: card32 = 0; + const fixfssdata: string = ''; const fixfssmetadata: string = ''); + //CHARACTER SET CHARACTER SET + procedure nbakstart(const dbname: msestring; const _file: msestring; + const level: card32; const options: nbakoptionsty; + const direct: string = ''); + //'on or 'off' + procedure nreststart(const dbname: msestring; + const files: array of msestring; const options: nbakoptionsty); + procedure repairstart(const adbname: msestring; + const aoptions: repairoptionsty); + + property lasterror: statusvectorty read flasterror; + property lasterrormessage: msestring read flasterrormessage; + property asynctext: msestringarty read fasynctext write fasynctext; + published + property asyncmaxrowcount: int32 read fasyncmaxrowcount + write fasyncmaxrowcount default 0; //-1 = unlimited + property hostname : ansistring read fhostname write fhostname; + property username : ansistring read fusername write fusername; + property password : ansistring read fpassword write fpassword; + property connected: boolean read getconnected + write setconnected default false; + //connected will be reset by a server error + property options: fbserviceoptionsty read foptions write foptions default []; + property infotimeout: int32 read finfotimeout write finfotimeout + default defaultinfotimeout; //seconds, -1 -> none + property onasynctext: fbservicetexteventty read fonasynctext + write fonasynctext; + property onasyncend: fbserviceendeventty read fonasyncend + write fonasyncend; //runs in service thread + property onasyncendmain: fbserviceendeventty read fonasyncendmain + write fonasyncendmain; //runs in main thread + + property onerror: fbserviceerroreventty read fonerror write fonerror; + end; + +implementation +uses + msebits,msearrayutils,mseapplication,msesysintf; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + restoreconsts: array[restoreoptionty] of card32 = (isc_spb_res_deactivate_idx, + isc_spb_res_no_shadow,isc_spb_res_no_validity,isc_spb_res_one_at_a_time, + isc_spb_res_replace,isc_spb_res_create,isc_spb_res_use_all_space); + accessmodeconsts: array[accessmodety] of card32 = (isc_spb_prp_am_readonly, + isc_spb_prp_am_readwrite); + writemodeconsts: array[writemodety] of card32 = (isc_spb_prp_wm_async, + isc_spb_prp_wm_sync); + propertyconsts: array[propertyoptionty] of card32 = (isc_spb_prp_activate, + isc_spb_prp_db_online); + reservespaceconsts: array[reservespacety] of card32 = (isc_spb_prp_res_use_full, + isc_spb_prp_res); +const + asyncendtag = 5790432; //not aborted, +1 -> aborted + +function readvalue16(var buffer: pbyte): card16; +begin + result:= buffer^; + inc(buffer); + result:= result + buffer^ shl 8; + inc(buffer); +end; + +function readvalue32(var buffer: pbyte): card16; +begin + result:= buffer^; + inc(buffer); + result:= result + buffer^ shl 8; + inc(buffer); + result:= result + buffer^ shl 16; + inc(buffer); + result:= result + buffer^ shl 24; + inc(buffer); +end; + +procedure storevalue(var buffer: pbyte; const value: card16); +begin + buffer^:= value; + inc(buffer); + buffer^:= value shr 8; + inc(buffer); +end; + +procedure storevalue(var buffer: pbyte; const value: card32); +begin + buffer^:= value; + inc(buffer); + buffer^:= value shr 8; + inc(buffer); + buffer^:= value shr 16; + inc(buffer); + buffer^:= value shr 24; + inc(buffer); +end; + +procedure addshortparam(var params: string; const id: int32; + const value: string); + //value limited to 255 chars +var + i1,i2: int32; + po1: pbyte; +begin + i1:= length(value); + if i1 > 255 then begin + i1:= 255; + end; + i2:= length(params); + setlength(params,i2+2+i1); + po1:= pointer(params)+i2; + po1^:= id; + inc(po1); + po1^:= i1; + inc(po1); + move(pointer(value)^,po1^,i1); +end; + +procedure addparam(var params: string; const id: int32; + const value: string); + //value limited to 65535 chars +var + i1,i2: int32; + po1: pbyte; +begin + i1:= length(value); + if i1 > 65535 then begin + i1:= 65553; + end; + i2:= length(params); + setlength(params,i2+3+i1); + po1:= pointer(params)+i2; + po1^:= id; + inc(po1); + storevalue(po1,card16(i1)); + move(pointer(value)^,po1^,i1); +end; + +procedure addparam(var params: string; const id: int32; + const value: card32); +var + i2: int32; + po1: pbyte; +begin + i2:= length(params); + setlength(params,i2+1+4); + po1:= pointer(params)+i2; + po1^:= id; + inc(po1); + storevalue(po1,value); +end; + +procedure addparam(var params: string; const id: int32); +var + i2: int32; + po1: pbyte; +begin + i2:= length(params); + setlength(params,i2+1+0); + po1:= pointer(params)+i2; + po1^:= id; +end; + +procedure addparam(var params: string; const id: int32; + const value: card8); +var + i2: int32; + po1: pbyte; +begin + i2:= length(params); + setlength(params,i2+1+1); + po1:= pointer(params)+i2; + po1^:= id; + inc(po1); + po1^:= value; + inc(po1); +end; + +procedure addtimeout(var params: string; const atimeout: card32); +var + i2: int32; + po1: pbyte; +begin + if int32(atimeout) >= 0 then begin + i2:= length(params); + setlength(params,i2+1+4+4+1); + po1:= pointer(params)+i2; + po1^:= isc_info_svc_timeout; + inc(po1); + storevalue(po1,card16(4)); //len + storevalue(po1,atimeout); + inc(po1); + po1^:= isc_info_end; + end; +end; + +function getvalueitem(var buffer: pointer; const id: int32; + var value: card32): boolean; +begin + result:= false; + if pbyte(buffer)^ = id then begin + inc(buffer); + value:= readvalue32(buffer); + result:= true; + end; +end; + +function getstringitem(var buffer: pointer; const id: int32; + var value: string): boolean; +var + i1: int32; +begin + result:= false; + if pbyte(buffer)^ = id then begin + inc(buffer); + i1:= readvalue16(buffer); + setlength(value,i1); + move((buffer)^,pointer(value)^,i1); + inc(buffer,i1); + result:= true; + end; +end; + +{ efbserviceerror } + +constructor efbserviceerror.create(const asender: tfbservice; + const amessage: msestring; const aerror: statusvectorty); +begin + fstatus:= aerror; + fsender:= sender; + ferror:= aerror[1]; + ferrormessage:= amessage; + inherited create(asender.name+': '+ansistring(amessage)); +end; + +{ tfbservicemonitor } + +constructor tfbservicemonitor.create(const aowner: tfbservice; + const procname: string); +begin + fowner:= aowner; + fprocname:= procname; + inherited create(); +end; + +destructor tfbservicemonitor.destroy(); +begin + terminate(); + application.waitforthread(self); + inherited; +end; + +function tfbservicemonitor.execute(thread: tmsethread): integer; + + procedure cancel(); + begin + if fowner.connected then begin + fowner.closeconn(); + fowner.connected:= true; + end; + end; //cancel + +var + params1,items1,buffer1: string; + po1: pointer; + i1,i2,rowmax1: int32; + str1: string; + ok: boolean; + ar1: msestringarty; + ar2: pointerarty; + rowindex1: int32; + mstr1,remainder: msestring; + po2,ps,pe: pmsechar; + + procedure add(); + begin + if length(ar1) < rowmax1 then begin + additem(ar1,remainder); + end + else begin + if rowmax1 <> 0 then begin + ar1[rowindex1]:= remainder; + inc(rowindex1); + if rowindex1 >= rowmax1 then begin + rowindex1:= 0; + end; + end; + end; + remainder:= ''; + end; //add + + procedure endtext(const canceled: boolean); + var + i1: int32; + begin + if rowindex1 = 0 then begin + fowner.fasynctext:= ar1; + end + else begin + allocuninitedarray(length(ar1),sizeof(pointer),ar2); + i1:= rowmax1-rowindex1; + move(ar1[rowindex1],ar2[0],i1*sizeof(pointer)); + move(ar1[0],ar2[i1],rowindex1*sizeof(pointer)); + fowner.fasynctext:= nil; + pointer(fowner.fasynctext):= pointer(ar1); + pointer(ar1):= nil; + end; + if assigned(fowner.fonasyncend) then begin + fowner.fonasyncend(fowner,true); + end; + if assigned(fowner.fonasyncendmain) then begin + if canceled then begin + fowner.asyncevent(asyncendtag+1); + end + else begin + fowner.asyncevent(asyncendtag); + end; + end; + end; + +const + buffersize = 4096; +begin + ok:= false; + params1:= ''; + addtimeout(params1,1); //1 sec min timeout + setlength(buffer1,buffersize); + items1:= char(isc_info_svc_to_eof); + str1:= ''; + remainder:= ''; + rowindex1:= 0; + rowmax1:= 0; + ar1:= nil; + try + while not terminated and not application.terminated do begin + fowner.checkerror(fprocname,isc_service_query(@fowner.fstatus,@fowner.fhandle, + nil,length(params1),pointer(params1),length(items1),pointer(items1), + length(buffer1),pointer(buffer1))); + if terminated or application.terminated then begin + break; + end; + case pbyte(pointer(buffer1))^ of + isc_info_svc_to_eof: begin + po1:= pointer(buffer1)+1; + i1:= readvalue16(po1); + if i1 > 0 then begin + i2:= length(str1); + setlength(str1,i1+i2); + move(po1^,(pointer(str1)+i2)^,i1); + end; + if i1 < buffersize-10 then begin + //not truncated, firebird seems not to fill buffer completely + if str1 <> '' then begin + application.lock(); + try + mstr1:= fowner.tomsestring(str1); + rowmax1:= fowner.fasyncmaxrowcount; + if rowmax1 < 0 then begin + rowmax1:= high(rowmax1); + end; + if length(ar1) > rowmax1 then begin + setlength(ar1,rowmax1); + end; + if rowindex1 > rowmax1 then begin + rowindex1:= 0; + end; + if rowmax1 > 0 then begin + po2:= pointer(mstr1); + ps:= po2; + pe:= po2+length(mstr1); + while po2 < pe do begin + if (po2^ = c_return) or (po2^ = c_linefeed) then begin + addstringsegment(remainder,ps,po2); + add(); + if (po2^ = c_return) then begin + inc(po2); + end; + if (po2^ = c_linefeed) then begin + inc(po2); + end; + ps:= po2; + end + else begin + inc(po2); + end; + end; + addstringsegment(remainder,ps,po2); + end; + if assigned(fowner.fonasynctext) then begin + fowner.fonasynctext(fowner,mstr1); + end; + finally + application.unlock(); + end; + str1:= ''; + end + else begin + application.lock(); + try + if not fowner.serviceisrunning() then begin + add(); + ok:= true; + cancel(); + endtext(false); + break; + end; + finally + application.unlock(); + end; + end; + end; + end; + else begin + fowner.invalidresponse(fprocname); + end; + end; + end; + finally + if not ok then begin + application.lock(); + try + add(); + cancel(); + endtext(true); + finally + application.unlock(); + end; + end; + end; + result:= 0; +end; + +{ tfbservice } + +constructor tfbservice.create(aowner: tcomponent); +begin + fhandle:= FB_API_NULLHANDLE; + finfotimeout:= defaultinfotimeout; + inherited; +end; + +destructor tfbservice.destroy(); +begin + disconnect(); + inherited; +end; + +procedure tfbservice.cancel(); +begin + freeandnil(fmonitor); + if connected then begin + connected:= false; + connected:= true; + end; +end; + +function tfbservice.busy(): boolean; +begin + result:= fbss_busy in fstate; +end; + +function tfbservice.getconnected: boolean; +begin + result:= fhandle <> FB_API_NULLHANDLE; +end; + +procedure tfbservice.setconnected(const avalue: boolean); +begin + if csreading in componentstate then begin + updatebit1(card32(fstate),ord(fbss_connected),avalue); + end + else begin + if avalue then begin + connect(); + end + else begin + disconnect(); + end; + end; +end; + +function tfbservice.connectionmessage(atext: pchar): msestring; +begin + if fbso_utf8message in foptions then begin + result:= utf8tostring(atext); + end + else begin + result:= atext; + end; +end; + +procedure tfbservice.loaded(); +begin + inherited; + if fbss_connected in fstate then begin + connect(); + end; +end; + +procedure tfbservice.doasyncevent(var atag: int32); +begin + inherited; + if canevent(tmethod(fonasyncendmain)) then begin + if atag = asyncendtag then begin + fonasyncendmain(self,false); + end + else begin + if (atag = asyncendtag+1) then begin + fonasyncendmain(self,false); + end; + end; + end; +end; + +procedure tfbservice.connect(); +const + servicename = 'service_mgr'; +var + params1: string; + str1: string; +begin + if fhandle = FB_API_NULLHANDLE then begin + try + initializeibase60([]); + if fhostname = '' then begin + str1:= servicename; + end + else begin + str1:= fhostname + ':' + servicename; //tcp/ip + end; + params1:= char(isc_spb_version)+char(isc_spb_current_version); + addshortparam(params1,isc_spb_user_name,fusername); + addshortparam(params1,isc_spb_password,fpassword); + checkerror('Connect',isc_service_attach(@fstatus,length(str1),pointer(str1), + @fhandle,length(params1),pointer(params1))); + except + exclude(fstate,fbss_connected); + fhandle:= FB_API_NULLHANDLE; + releaseibase60(); + raise; + end; + end; + include(fstate,fbss_connected); +end; + +procedure tfbservice.closeconn(); +begin + fstate:= fstate - [fbss_connected,fbss_busy]; + if fhandle <> FB_API_NULLHANDLE then begin + isc_service_detach(@fstatus,@fhandle); + fhandle:= FB_API_NULLHANDLE; + releaseibase60(); + end; +end; + +procedure tfbservice.disconnect(); +begin + if (fmonitor <> nil) and + (sys_getcurrentthread() <> fmonitor.id) then begin + freeandnil(fmonitor); + end; + closeconn(); +end; + +procedure tfbservice.readstate(reader: treader); +begin + disconnect(); + inherited; +end; + +procedure tfbservice.raiseerror(const e: exception; const dberr: boolean); +var + bo1: boolean; + e1: exception; +begin + application.lock(); + try + if dberr then begin + connected:= false; //cancel possible running task + end; + e1:= e; + if canevent(tmethod(fonerror)) then begin + bo1:= false; + try + fonerror(self,e1,bo1); + except + e1.free; + raise; + end; + if bo1 then begin + e1.free; + end + else begin + raise e1; + end; + end + else begin + raise e1; + end; + finally + application.unlock(); + end; +end; + +procedure tfbservice.dberror(const msg: string; const comp: tcomponent; + const dberr: boolean); +begin + raiseerror(edatabaseerror.create(msg,comp),dberr); +end; + +procedure tfbservice.checkerror(const procname: string; + const status: statusvectorty); +var + buf: array [0..1024] of char; + p: pointer; + Msg: msestring; +begin + if ((Status[0] = 1) and (Status[1] <> 0)) then begin + p:= @Status; + msg:= msestring(procname); +//{$warnings off} + while isc_interprete(Buf, @p) > 0 do begin + Msg := Msg + lineend +' -' + connectionmessage(Buf); + end; + flasterror:= status; + flasterrormessage:= msg; + raiseerror(efbserviceerror.create(self,msg,status),true); + end; +end; +//{$warnings on} + +procedure tfbservice.checkerror(const procname: string; const status: integer); +begin + if status <> 0 then begin + checkerror(procname,fstatus); + end; +end; + +procedure tfbservice.checkbusy(); +begin + if not connected then begin + dberror('Not connected',self,false); + end; + if busy then begin + dberror('Busy',self,false); + end; +end; + +procedure tfbservice.invalidresponse(const procname: string); +begin + raiseerror(edatabaseerror.create('Invalid '+procname+' response',self),true); +end; + +function tfbservice.todbstring(const avalue: msestring): string; +begin + if fbso_utf8 in foptions then begin + result:= stringtoutf8ansi(avalue); + end + else begin + result:= ansistring(avalue); + end; +end; + +function tfbservice.tomsestring(const avalue: string): msestring; +begin + if fbso_utf8 in foptions then begin + result:= utf8tostring(avalue); + end + else begin + result:= msestring(avalue); + end; +end; + +procedure tfbservice.start(const procname: string; const params: string); +begin + checkbusy(); + fasynctext:= nil; + checkerror(procname,isc_service_start(@fstatus,@fhandle,nil, + length(params),pointer(params))); + include(fstate,fbss_busy); +end; + +function tfbservice.getinfo(const procname: string; + const items: array of byte; const async: boolean): string; +var + params1: string; +begin + params1:= ''; + addtimeout(params1,finfotimeout); + setlength(result,1024); + while true do begin + checkerror(procname,isc_service_query(@fstatus,@fhandle,nil,length(params1), + pointer(params1),length(items),@items[0],length(result),pointer(result))); + if pbyte(pointer(result))^ <> isc_info_truncated then begin + if not async then begin + exclude(fstate,fbss_busy); + end; + break; + end; + setlength(result,2*length(result)); + end; +end; + +procedure tfbservice.runcommand(const procname: string; + const params: string); +var + ar1: msestringarty; +begin + gettext(procname,params,ar1,1); +end; + +function tfbservice.getmsestringitem(var buffer: pointer; out res: msestring; + const cutspace: boolean = false): boolean; +var + i1,i2: int32; +begin + i1:= readvalue16(buffer); + i2:= i1; + result:= i1 <= 0; + if cutspace and not result and (pchar(buffer)[i1-1] = ' ') then begin + dec(i2); + end; + if fbso_utf8 in foptions then begin + res:= utf8tostring(buffer,i2); + end + else begin + widestringmanager.ansi2unicodemoveproc(buffer, + {$ifdef mse_fpc_3}cp_acp,{$endif}res,i2); + end; + inc(buffer,i1); +end; + +function tfbservice.getmsestringitem(var buffer: pointer; const id: int32; + var value: msestring): boolean; +begin + result:= false; + if pbyte(buffer)^ = id then begin + inc(buffer); + getmsestringitem(buffer,value); + result:= true; + end; +end; + +procedure tfbservice.addmseparam(var params: string; const id: int32; + const value: msestring); +begin + addparam(params,id,todbstring(value)); +end; +{ +function tfbservice.getline(const procname: string; + var res: msestring; out eof: boolean): boolean; +var + params1: string; + items1: string; + buffer1: string; + po1: pointer; +begin + result:= true; + eof:= true; + params1:= ''; + addparam(params1,isc_info_svc_timeout,1); //minimal timeout (1sec) + setlength(buffer1,1024); //max line length + items1:= char(isc_info_svc_line); +// addparam(items1,isc_info_svc_timeout,1); //minimal timeout (1sec) + checkerror(procname,isc_service_query(@fstatus,@fhandle,nil,length(params1), + pointer(params1),length(items1),pointer(items1), + length(buffer1),pointer(buffer1))); + case pbyte(pointer(buffer1))^ of + isc_info_svc_line: begin //timeout? + po1:= pointer(buffer1)+1; + eof:= getmsestringitem(po1,res,true); + end; + else begin + invalidresponse(procname); + end; + end; +end; +} +function tfbservice.serverinfo(): fbserverinfoty; +var + buffer: string; + po1: pbyte; +begin + checkbusy(); + finalize(result); + fillchar(result,sizeof(result),0); + buffer:= getinfo('serverinfo',[isc_info_svc_version, + isc_info_svc_server_version,isc_info_svc_implementation, + isc_info_svc_capabilities,isc_info_svc_user_dbpath, + isc_info_svc_get_env,isc_info_svc_get_env_lock, + isc_info_svc_get_env_msg],false); + po1:= pointer(buffer); + with result do begin + while (po1^ <> isc_info_end) and (po1^ <> 0) do begin + if not (getvalueitem(po1,isc_info_svc_version,version) or + getmsestringitem(po1,isc_info_svc_server_version,server_version) or + getmsestringitem(po1,isc_info_svc_implementation,_implementation) or + getvalueitem(po1,isc_info_svc_capabilities,capabilities) or + getmsestringitem(po1,isc_info_svc_user_dbpath,user_dbpath) or + getmsestringitem(po1,isc_info_svc_get_env,get_env) or + getmsestringitem(po1,isc_info_svc_get_env_lock,get_env_lock) or + getmsestringitem(po1,isc_info_svc_get_env_msg,get_env_msg)) then begin + invalidresponse('serverinfo'); + end; + end; + end; +end; + +function tfbservice.internalusers(const ausername: string): fbuserinfoarty; +var + params1,buffer1: string; + po1: pbyte; + count: int32; + po2: pfbuserinfoty; +begin + checkbusy(); + params1:= char(isc_action_svc_display_user_adm); + if ausername <> '' then begin + addparam(params1,isc_spb_sec_username,ausername); + end; + start('users',params1); + result:= nil; + count:= 0; + buffer1:= getinfo('users',[isc_info_svc_get_users],false); + po1:= pointer(buffer1); + if po1^ <> isc_info_svc_get_users then begin + invalidresponse('users'); + end; + inc(po1,3); //additional bytes 50 0 ??? + while (po1^ <> isc_info_flag_end) and (po1^ <> isc_info_end) and + (po1^ <> 0) do begin + if po1^ = isc_spb_sec_username then begin //must be first field + additem(result,typeinfo(result),count); + po2:= @result[count-1]; + getmsestringitem(po1,isc_spb_sec_username,po2^.username) + end + else begin + if result = nil then begin + invalidresponse('users'); + end; + end; + with po2^ do begin + while (po1^ <> isc_spb_sec_username) and (po1^ <> isc_info_flag_end) and + (po1^ <> isc_info_end) and (po1^ <> 0) do begin + if not (getmsestringitem(po1,isc_spb_sec_firstname,firstname) or + getmsestringitem(po1,isc_spb_sec_middlename,middlename) or + getmsestringitem(po1,isc_spb_sec_lastname,lastname) or + getmsestringitem(po1,isc_spb_sec_groupname,groupname) or + getmsestringitem(po1,isc_spb_sql_role_name,rolename) or + getvalueitem(po1,isc_spb_sec_userid,userid) or + getvalueitem(po1,isc_spb_sec_groupid,groupid) or + getvalueitem(po1,isc_spb_sec_admin,admin)) then begin + invalidresponse('users'); + end; + end; + end; + end; + setlength(result,count); +end; + +function tfbservice.users(): fbuserinfoarty; +begin + result:= internalusers(''); +end; + +function tfbservice.user(const ausername: msestring; + var ainfo: fbuserinfoty): boolean; +var + ar1: fbuserinfoarty; +begin + ar1:= internalusers(todbstring(ausername)); + result:= ar1 <> nil; + if result then begin + ainfo:= ar1[0]; + end; +end; + +procedure tfbservice.adduserparams(var params1: string; + const ainfo: fbuserinfoty; const aitems: fbuseritemsty); +begin + with ainfo do begin + if fbu_username in aitems then begin + addmseparam(params1,isc_spb_sec_username,username); + end; + if fbu_firstname in aitems then begin + addmseparam(params1,isc_spb_sec_firstname,firstname); + end; + if fbu_middlename in aitems then begin + addmseparam(params1,isc_spb_sec_middlename,middlename); + end; + if fbu_lastname in aitems then begin + addmseparam(params1,isc_spb_sec_lastname,lastname); + end; + if fbu_groupname in aitems then begin + addmseparam(params1,isc_spb_sec_groupname,groupname); + end; + if fbu_rolename in aitems then begin + addmseparam(params1,isc_spb_sql_role_name,rolename); + end; + if fbu_userid in aitems then begin + addparam(params1,isc_spb_sec_userid,userid); + end; + if fbu_groupid in aitems then begin + addparam(params1,isc_spb_sec_groupid,groupid); + end; + if fbu_admin in aitems then begin + addparam(params1,isc_spb_sec_admin,admin); + end; + if fbu_password in aitems then begin + addparam(params1,isc_spb_sec_password,password); + end; + end; +end; + +procedure tfbservice.adduser(const ainfo: fbuserinfoty; + const items: fbuseritemsty); +var + params1: string; +begin + params1:= char(isc_action_svc_add_user); + adduserparams(params1,ainfo,items); + runcommand('adduser',params1); +end; + +procedure tfbservice.modifyuser(const ainfo: fbuserinfoty; + const items: fbuseritemsty); +var + params1: string; +begin + params1:= char(isc_action_svc_modify_user); + adduserparams(params1,ainfo,items); + runcommand('modifyuser',params1); +end; + +procedure tfbservice.deleteuser(const ausername: msestring; + const arolename: msestring = ''); +var + params1: string; +begin + params1:= char(isc_action_svc_delete_user); + addmseparam(params1,isc_spb_sec_username,ausername); + if arolename <> '' then begin + addmseparam(params1,isc_spb_sql_role_name,arolename); + end; + runcommand('deleteuser',params1); +end; + +procedure tfbservice.gettext(const procname: string; const params: string; + var res: msestringarty; const maxrowcount: integer); + +var + circindex: int32; + + procedure add(const atext: pchar; const len: int32); + var + mstr1: msestring; + begin + if fbso_utf8 in foptions then begin + mstr1:= utf8tostring(atext,len); + end + else begin + widestringmanager.ansi2unicodemoveproc(atext, + {$ifdef mse_fpc_3}cp_acp,{$endif}mstr1,len); + end; + if (maxrowcount > 0) and (length(res) >= maxrowcount) then begin + res[circindex]:= mstr1; + inc(circindex); + if circindex >= maxrowcount then begin + circindex:= 0; + end; + end + else begin + additem(res,mstr1); + end; + end; + +var + params1,items1,buffer1: string; + po1: pointer; + pa,pb,pc,pe: pchar; + i1: int32; + remainder: string; + ar1: pointerarty; +begin + checkbusy(); + start(procname,params); + res:= nil; + params1:= ''; + addtimeout(params1,finfotimeout); + setlength(buffer1,4096); + items1:= char(isc_info_svc_to_eof); + remainder:= ''; + circindex:= 0; + while true do begin + checkerror(procname,isc_service_query(@fstatus,@fhandle,nil,length(params1), + pointer(params1),length(items1),pointer(items1), + length(buffer1),pointer(buffer1))); + case pbyte(pointer(buffer1))^ of + isc_info_svc_to_eof: begin + po1:= pointer(buffer1)+1; + i1:= readvalue16(po1); + if i1 <= 0 then begin + if serviceisrunning() then begin + dberror(procname+': Timeout',self,true); + end; + break; //eof + end; + if i1 > length(buffer1)-1-2 then begin + invalidresponse(procname); + end; + if maxrowcount <> 0 then begin + pa:= po1; + pb:= pa; + pe:= pa + i1; + while (pb < pe) do begin + if pb^ = c_linefeed then begin + pc:= pb; + if (pc > pa) and ((pc-1)^ = c_return) then begin + dec(pc); + end; + if remainder <> '' then begin + remainder:= remainder+stringsegment(pa,pb); + add(pointer(remainder),length(remainder)); + remainder:= ''; + end + else begin + add(pa,pc-pa); + end; + pa:= pb+1; + end; + inc(pb); + end; + remainder:= remainder+stringsegment(pa,pe); + end; + end; + else begin + invalidresponse(procname); + end; + end; + end; + if maxrowcount <> 0 then begin + add(pointer(remainder),length(remainder)); + end; + if circindex > 0 then begin + allocuninitedarray(length(res),sizeof(pointer),ar1); + i1:= maxrowcount-circindex; + move(res[circindex],ar1[0],i1*sizeof(pointer)); + move(res[0],ar1[i1],circindex*sizeof(pointer)); + res:= pointer(ar1); + pointer(ar1):= nil; + +// ar1:= copy(res,circindex,maxrowcount-circindex); +// stackarray(copy(res,0,circindex),ar1); +// res:= ar1; + end; + exclude(fstate,fbss_busy); +end; + +procedure tfbservice.startmonitor(const procname: string; const aparams: string); +begin +// checkbusy(); + start(procname,aparams); + freeandnil(fmonitor); + fmonitor:= tfbservicemonitor.create(self,procname); +end; + +function tfbservice.serviceisrunning(): boolean; +var + buffer1: string; + po1: pointer; + ca1: card32; +begin + result:= false; + if busy then begin + buffer1:= getinfo('serviceisrunning',[isc_info_svc_running],true); + po1:= pointer(buffer1); + if getvalueitem(po1,isc_info_svc_running,ca1) then begin + result:= ca1 <> 0; + end; + end; +end; + +procedure tfbservice.getlog(var res: msestringarty; + const maxrowcount: int32 = -1); +begin + tagaction('getlog',isc_action_svc_get_fb_log,res,maxrowcount); +end; + +procedure tfbservice.tracestart(const cfg: msestring; + const _name: msestring = ''); +var + params1: string; +begin + params1:= char(isc_action_svc_trace_start); + addmseparam(params1,isc_spb_trc_cfg,cfg); + if _name <> '' then begin + addmseparam(params1,isc_spb_trc_name,_name); + end; + startmonitor('tracestart',params1); +end; + +procedure tfbservice.tagaction(const aprocname: string; const aaction: int32; + var res: msestringarty; + const maxrowcount: int32); +begin + gettext(aprocname,char(aaction),res,maxrowcount); +end; + +procedure tfbservice.tagaction(const aprocname: string; const aaction: int32); +var + ar1: msestringarty; +begin + tagaction(aprocname,aaction,ar1,1); +end; + +procedure tfbservice.tracelist(var res: msestringarty; + const maxrowcount: int32 = -1); +begin + tagaction('tracelist',isc_action_svc_trace_list,res,maxrowcount); +end; + +procedure tfbservice.traceaction(const aprocname: string; const aaction: int32; + const aid: card32; var res: msestringarty; + const maxrowcount: int32); +var + params1: string; +begin + params1:= char(aaction); + addparam(params1,isc_spb_trc_id,aid); + gettext(aprocname,params1,res,maxrowcount); +end; + +procedure tfbservice.tracestop(const aid: card32; var res: msestringarty; + const maxrowcount: int32 = -1); +begin + traceaction('tracestop',isc_action_svc_trace_stop,aid,res,maxrowcount); +end; + +procedure tfbservice.tracesuspend(const aid: card32; var res: msestringarty; + const maxrowcount: int32 = -1); +begin + traceaction('tracesuspend',isc_action_svc_trace_suspend,aid,res,maxrowcount); +end; + +procedure tfbservice.traceresume(const aid: card32; var res: msestringarty; + const maxrowcount: int32 = -1); +begin + traceaction('traceresume',isc_action_svc_trace_resume,aid,res,maxrowcount); +end; + +procedure tfbservice.setmapping(); +begin + tagaction('setmapping',isc_action_svc_set_mapping); +end; + +procedure tfbservice.dropmapping(); +begin + tagaction('dropmapping',isc_action_svc_drop_mapping); +end; + +procedure tfbservice.dbstats(const adbname: msestring; + const aoptions: dbstatoptionsty; const acommandline: msestring; + var res: msestringarty; const maxrowcount: int32 = -1); +var + params1: string; +begin + params1:= char(isc_action_svc_db_stats); + addmseparam(params1,isc_spb_dbname,adbname); + addparam(params1,isc_spb_options,card32(aoptions)); + if acommandline <> '' then begin + addmseparam(params1,isc_spb_command_line,acommandline); + end; + gettext('dbstats',params1,res,maxrowcount); +end; + +procedure tfbservice.properties(const adbname: msestring; + const ainfo: fbpropertyinfoty; const aitems: fbpropertyitemsty; + var res: msestringarty; const maxrowcount: integer); +var + params1: string; + ca1: card32; + opt1: propertyoptionty; +begin + params1:= char(isc_action_svc_properties); + addmseparam(params1,isc_spb_dbname,adbname); + with ainfo do begin + if fbp_pagebuffers in aitems then begin + addparam(params1,isc_spb_prp_page_buffers,pagebuffers); + end; + if fbp_sweepinterval in aitems then begin + addparam(params1,isc_spb_prp_sweep_interval,sweepinterval); + end; + if fbp_shutdowndb in aitems then begin + addparam(params1,isc_spb_prp_shutdown_db,shutdowndb); + end; + if fbp_denynewattachments in aitems then begin + addparam(params1,isc_spb_prp_deny_new_attachments,denynewattachments); + end; + if fbp_denynewtransactions in aitems then begin + addparam(params1,isc_spb_prp_deny_new_transactions,denynewtransactions); + end; + if fbp_reservespace in aitems then begin + addparam(params1,isc_spb_prp_reserve_space, + card8(reservespaceconsts[reservespace])); + end; + if fbp_writemode in aitems then begin + addparam(params1,isc_spb_prp_write_mode, + card8(writemodeconsts[writemode])); + end; + if fbp_accessmode in aitems then begin + addparam(params1,isc_spb_prp_access_mode, + card8(accessmodeconsts[accessmode])); + end; + if fbp_setsqldialect in aitems then begin + addparam(params1,isc_spb_prp_set_sql_dialect,setsqldialect); + end; + if fbp_options in aitems then begin + ca1:= 0; + for opt1:= low(opt1) to high(opt1) do begin + ca1:= ca1 or propertyconsts[opt1]; + end; + addparam(params1,isc_spb_options,ca1); + end; + if fbp_forceshutdown in aitems then begin + addparam(params1,isc_spb_prp_force_shutdown,forceshutdown); + end; + if fbp_attachmentsshutdown in aitems then begin + addparam(params1,isc_spb_prp_attachments_shutdown,attachmentsshutdown); + end; + if fbp_transactionsshutdown in aitems then begin + addparam(params1,isc_spb_prp_transactions_shutdown,transactionsshutdown); + end; + if fbp_shutdownmode in aitems then begin + addparam(params1,isc_spb_prp_shutdown_mode,card8(shutdownmode)); + end; + if fbp_onlinemode in aitems then begin + addparam(params1,isc_spb_prp_online_mode,card8(onlinemode)); + end; + end; + gettext('properties',params1,res,maxrowcount); +end; + +procedure tfbservice.validatestart(const dbname: msestring; + const tabincl: msestring = ''; const tabexcl: msestring = ''; + const idxincl: msestring = ''; const idxexcl: msestring = ''; + const locktimeout: card32 = 0); +var + params1: string; +begin + params1:= char(isc_action_svc_validate); + addmseparam(params1,isc_spb_dbname,dbname); + if tabincl <> '' then begin + addmseparam(params1,isc_spb_val_tab_incl,tabincl); + end; + if tabexcl <> '' then begin + addmseparam(params1,isc_spb_val_tab_excl,tabexcl); + end; + if idxincl <> '' then begin + addmseparam(params1,isc_spb_val_idx_incl,idxincl); + end; + if idxexcl <> '' then begin + addmseparam(params1,isc_spb_val_idx_excl,idxexcl); + end; + if locktimeout <> 0 then begin + addparam(params1,isc_spb_val_lock_timeout,locktimeout); + end; + startmonitor('validatestart',params1); +end; + +procedure tfbservice.backupstart(const dbname: msestring; + const backupfiles: array of msestring; const lengths: array of card32; + const verbose: boolean = false; const stat: string = ''; + const aoptions: backupoptionsty = []; + const factor: card32 = 0); +var + params1: string; + i1: int32; + ca1: card32; +begin + params1:= char(isc_action_svc_backup); + addmseparam(params1,isc_spb_dbname,dbname); + for i1:= 0 to high(backupfiles) do begin + addmseparam(params1,isc_spb_bkp_file,backupfiles[i1]); + if i1 <= high(lengths) then begin + addparam(params1,isc_spb_bkp_length,lengths[i1]); + end; + end; + if verbose then begin + addparam(params1,isc_spb_verbose); + end; + if stat <> '' then begin + addparam(params1,isc_spb_bkp_stat,stat); + end; + ca1:= card32(aoptions - [bao_notriggers]); + if bao_notriggers in aoptions then begin + ca1:= ca1 or $8000; + end; + addparam(params1,isc_spb_options,ca1); + startmonitor('backupstart',params1); +end; + +procedure tfbservice.restorestart(const backupfiles: array of msestring; + const dbfiles: array of msestring; const lengths: array of card32; + const verbose: boolean = false; const stat: string = ''; + const aoptions: restoreoptionsty = []; + const accessmode: accessmodety = amo_readwrite; + const buffers: card32 = 0; const pagesize: card32 = 0; + const fixfssdata: string = ''; const fixfssmetadata: string = ''); +var + params1: string; + i1: int32; + ca1: card32; + opt1: restoreoptionty; +begin + params1:= char(isc_action_svc_restore); + for i1:= 0 to high(backupfiles) do begin + addmseparam(params1,isc_spb_bkp_file,backupfiles[i1]); + end; + for i1:= 0 to high(dbfiles) do begin + addmseparam(params1,isc_spb_dbname,dbfiles[i1]); + if i1 <= high(lengths) then begin + addparam(params1,isc_spb_res_length,lengths[i1]); + end; + end; + if verbose then begin + addparam(params1,isc_spb_verbose); + end; + if stat <> '' then begin + addparam(params1,isc_spb_res_stat,stat); + end; + if aoptions <> [] then begin + ca1:= 0; + for opt1:= low(opt1) to high(opt1) do begin + if opt1 in aoptions then begin + ca1:= ca1 or restoreconsts[opt1]; + end; + end; + addparam(params1,isc_spb_options,ca1); + end; + addparam(params1,isc_spb_res_access_mode,card8(accessmodeconsts[accessmode])); + if buffers <> 0 then begin + addparam(params1,isc_spb_res_buffers,buffers); + end; + if pagesize <> 0 then begin + addparam(params1,isc_spb_res_page_size,pagesize); + end; + if fixfssdata <> '' then begin + addparam(params1,isc_spb_res_fix_fss_data,fixfssdata); + end; + if fixfssmetadata <> '' then begin + addparam(params1,isc_spb_res_fix_fss_metadata,fixfssmetadata); + end; + startmonitor('restorestart',params1); +end; + +procedure tfbservice.nbakstart(const dbname: msestring; const _file: msestring; + const level: card32; const options: nbakoptionsty; + const direct: string = ''); +var + params1: string; +begin + params1:= char(isc_action_svc_nbak); + addmseparam(params1,isc_spb_dbname,dbname); + addmseparam(params1,isc_spb_nbk_file,_file); + addparam(params1,isc_spb_nbk_level,level); + addparam(params1,isc_spb_options,card32(options)); + if direct <> '' then begin + addparam(params1,isc_spb_nbk_direct,direct); + end; + startmonitor('nbak',params1); +end; + +procedure tfbservice.nreststart(const dbname: msestring; + const files: array of msestring; const options: nbakoptionsty); +var + params1: string; + i1: int32; +begin + params1:= char(isc_action_svc_nrest); + addmseparam(params1,isc_spb_dbname,dbname); + for i1:= 0 to high(files) do begin + addmseparam(params1,isc_spb_nbk_file,files[i1]); + end; + addparam(params1,isc_spb_options,card32(options)); + startmonitor('nrest',params1); +end; + +procedure tfbservice.repairstart(const adbname: msestring; + const aoptions: repairoptionsty); +var + params1: string; +begin + params1:= char(isc_action_svc_repair); + addmseparam(params1,isc_spb_dbname,adbname); + addparam(params1,isc_spb_options,card32(aoptions)); + startmonitor('repairstart',params1); +end; + +end. diff --git a/mseide-msegui/lib/common/db/msefbutils.pas b/mseide-msegui/lib/common/db/msefbutils.pas new file mode 100644 index 0000000..155d261 --- /dev/null +++ b/mseide-msegui/lib/common/db/msefbutils.pas @@ -0,0 +1,165 @@ +{ MSEgui Copyright (c) 2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msefbutils; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mdb,msqldb,msetypes{msestrings}; + +procedure fbupdateindexdefs(const sender: tcustomsqlconnection; + var indexdefs : tindexdefs; + const atablename : string); +function fbgetschemainfosql(const sender: tcustomsqlconnection; + schematype: tschematype; + schemaobjectname,schemapattern: msestring): msestring; + +implementation +uses + msesqlresult,dbconst,sysutils; + +procedure fbupdateindexdefs(const sender: tcustomsqlconnection; + var indexdefs : tindexdefs; + const atablename : string); +var + res: tsqlresult; + str1: ansistring; +begin + with sender do begin + if not assigned(Transaction) then begin + DatabaseError(SErrConnTransactionnSet); + end; + res:= tsqlresult.Create(nil); + try + with res do begin + database:= sender; + sql.text:= 'select '+ + 'ind.rdb$index_name, '+ + 'ind.rdb$relation_name, '+ + 'ind.rdb$unique_flag, '+ + 'ind_seg.rdb$field_name, '+ + 'rel_con.rdb$constraint_type '+ + 'from '+ + 'rdb$index_segments ind_seg, '+ + 'rdb$indices ind '+ + 'left outer join '+ + 'rdb$relation_constraints rel_con '+ + 'on '+ + 'rel_con.rdb$index_name = ind.rdb$index_name '+ + 'where '+ + '(ind_seg.rdb$index_name = ind.rdb$index_name) and '+ + '(ind.rdb$relation_name=''' + + msestring(uppercase(atablename)) +''') '+ + 'order by '+ + 'ind.rdb$index_name;'; + active:= true; + while not eof do begin + with indexdefs.AddIndexDef do begin + str1:= datacols[0].asstring; + name:= trim(str1); + fields:= trim(res.datacols[3].asstring); + if datacols[4].asstring = 'PRIMARY KEY' then begin + options:= options + [ixPrimary]; + end; + if datacols[2].asinteger = 1 then begin + options:= options + [ixUnique]; + end; + next; + while not eof and (str1 = datacols[0].asstring) do begin + fields:= fields + ';' + trim(datacols[3].asstring); + next; + end; + end; + end; + end; + finally + res.free; + end; + end; +end; + +function fbgetschemainfosql(const sender: tcustomsqlconnection; + schematype: tschematype; + schemaobjectname,schemapattern: msestring): msestring; +var + s : msestring; + +begin + with sender do begin + s:= ''; + case SchemaType of + stTables : s := 'select '+ + 'rdb$relation_id as recno, '+ + '''' + msestring(DatabaseName) + + ''' as catalog_name, '+ + ''''' as schema_name, '+ + 'rdb$relation_name as table_name, '+ + '0 as table_type '+ + 'from '+ + 'rdb$relations '+ + 'where '+ + '(rdb$system_flag = 0 or rdb$system_flag is null) ' + // and rdb$view_blr is null + 'order by rdb$relation_name'; + + stSysTables : s := 'select '+ + 'rdb$relation_id as recno, '+ + '''' + msestring(DatabaseName) + + ''' as catalog_name, '+ + ''''' as schema_name, '+ + 'rdb$relation_name as table_name, '+ + '0 as table_type '+ + 'from '+ + 'rdb$relations '+ + 'where '+ + '(rdb$system_flag > 0) ' + // and rdb$view_blr is null + 'order by rdb$relation_name'; + + stProcedures : s := 'select '+ + 'rdb$procedure_id as recno, '+ + '''' + msestring(DatabaseName) + + ''' as catalog_name, '+ + ''''' as schema_name, '+ + 'rdb$procedure_name as proc_name, '+ + '0 as proc_type, '+ + 'rdb$procedure_inputs as in_params, '+ + 'rdb$procedure_outputs as out_params '+ + 'from '+ + 'rdb$procedures '+ + 'WHERE '+ + '(rdb$system_flag = 0 or rdb$system_flag is null)'; + stColumns : s := 'select '+ + 'rdb$field_id as recno, '+ + '''' + msestring(DatabaseName) + + ''' as catalog_name, '+ + ''''' as schema_name, '+ + 'rdb$relation_name as table_name, '+ + 'rdb$field_name as column_name, '+ + 'rdb$field_position as column_position, '+ + '0 as column_type, '+ + '0 as column_datatype, '+ + ''''' as column_typename, '+ + '0 as column_subtype, '+ + '0 as column_precision, '+ + '0 as column_scale, '+ + '0 as column_length, '+ + '0 as column_nullable '+ + 'from '+ + 'rdb$relation_fields '+ + 'WHERE '+ + '(rdb$system_flag = 0 or rdb$system_flag is null) and'+ + ' (rdb$relation_name = ''' + Uppercase(SchemaObjectName) + ''') ' + + 'order by rdb$field_name'; + else + DatabaseError(SMetadataUnavailable) + end; {case} + result := s; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/db/msefirebird.pas b/mseide-msegui/lib/common/db/msefirebird.pas new file mode 100644 index 0000000..fbb993c --- /dev/null +++ b/mseide-msegui/lib/common/db/msefirebird.pas @@ -0,0 +1,469 @@ +{ MSEgui Copyright (c) 2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msefirebird; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + firebird,msestrings,msectypes,msetypes; +{$define cvcall} +const +{$ifdef mswindows} + {$define wincall} + firebirdlib: array[0..0] of filenamety = ('fbclient.dll'); +{$else} + firebirdlib: array[0..2] of filenamety = + ('libfbclient.so.3','libfbclient.so.2','libfbclient.so'); +{$endif} + +const + SQL_TEXT = 452; + SQL_VARYING = 448; + SQL_SHORT = 500; + SQL_LONG = 496; + SQL_FLOAT = 482; + SQL_DOUBLE = 480; + SQL_D_FLOAT = 530; + SQL_TIMESTAMP = 510; + SQL_BLOB = 520; + SQL_ARRAY = 540; + SQL_QUAD = 550; + SQL_TYPE_TIME = 560; + SQL_TYPE_DATE = 570; + SQL_INT64 = 580; + SQL_BOOLEAN = 32764; + SQL_NULL = 32766; + + CS_NONE = 0; //* No Character Set */ + CS_BINARY = 1; //* BINARY BYTES */ + CS_ASCII = 2; //* ASCII */ + CS_UNICODE_FSS = 3; //* UNICODE in FSS format */ + CS_UTF8 = 4; //* UTF-8 */ + +{$ifdef cpu64} + FB_DOUBLE_ALIGN = 8; +{$else} + FB_DOUBLE_ALIGN = 4; //check! +{$endif} + ISC_TIME_SECONDS_PRECISION = 10000; + GDS_EPOCH_START = 40617; + fbdatetimeoffset = -15018; //fpdate -> tdatetime; + EPB_version1 = 1; + +(* +#define dtype_unknown 0 +#define dtype_text 1 +#define dtype_cstring 2 +#define dtype_varying 3 + +#define dtype_packed 6 +#define dtype_byte 7 +#define dtype_short 8 +#define dtype_long 9 +#define dtype_quad 10 +#define dtype_real 11 +#define dtype_double 12 +#define dtype_d_float 13 +#define dtype_sql_date 14 +#define dtype_sql_time 15 +#define dtype_timestamp 16 +#define dtype_blob 17 +#define dtype_array 18 +#define dtype_int64 19 +#define dtype_dbkey 20 +#define dtype_boolean 21 +#define DTYPE_TYPE_MAX 22 + +static const USHORT type_alignments[DTYPE_TYPE_MAX] = +{ + 0, + 0, /* dtype_text */ + 0, /* dtype_cstring */ + sizeof(SSHORT), /* dtype_varying */ + 0, /* unused */ + 0, /* unused */ + sizeof(SCHAR), /* dtype_packed */ + sizeof(SCHAR), /* dtype_byte */ + sizeof(SSHORT), /* dtype_short */ + sizeof(SLONG), /* dtype_long */ + sizeof(SLONG), /* dtype_quad */ + sizeof(float), /* dtype_real */ + FB_DOUBLE_ALIGN, /* dtype_double */ + FB_DOUBLE_ALIGN, /* dtype_d_float */ + sizeof(GDS_DATE), /* dtype_sql_date */ + sizeof(GDS_TIME), /* dtype_sql_time */ + sizeof(GDS_DATE), /* dtype_timestamp */ + sizeof(SLONG), /* dtype_blob */ + sizeof(SLONG), /* dtype_array */ + sizeof(SINT64), /* dtype_int64 */ + sizeof(ULONG), /* dtype_dbkey */ + sizeof(UCHAR) /* dtype_boolean */ +}; + +static const USHORT type_lengths[DTYPE_TYPE_MAX] = +{ + 0, + 0, /* dtype_text */ + 0, /* dtype_cstring */ + 0, /* dtype_varying */ + 0, /* unused */ + 0, /* unused */ + 0, /* dtype_packed */ + sizeof(SCHAR), /* dtype_byte */ + sizeof(SSHORT), /* dtype_short */ + sizeof(SLONG), /* dtype_long */ + sizeof(ISC_QUAD), /* dtype_quad */ + sizeof(float), /* dtype_real */ + sizeof(double), /* dtype_double */ + sizeof(double), /* dtype_d_float */ + sizeof(GDS_DATE), /* dtype_sql_date */ + sizeof(GDS_TIME), /* dtype_sql_time */ + sizeof(GDS_TIMESTAMP), /* dtype_timestamp */ + sizeof(ISC_QUAD), /* dtype_blob */ + sizeof(ISC_QUAD), /* dtype_array */ + sizeof(SINT64), /* dtype_int64 */ + sizeof(RecordNumber::Packed), /*dtype_dbkey */ + sizeof(UCHAR) /* dtype_boolean */ +}; +*) + +//****************************/ +//* Common, structural codes */ +//****************************/ + + isc_info_end = 1; + isc_info_truncated = 2; + isc_info_error = 3; + isc_info_data_not_ready = 4; + isc_info_length = 126; + isc_info_flag_end = 127; + +//**************************/ +//* Blob information items */ +//**************************/ + + isc_info_blob_num_segments = 4; + isc_info_blob_max_segment = 5; + isc_info_blob_total_length = 6; + isc_info_blob_type = 7; + +//*************************/ +//* SQL information items */ +//*************************/ + + isc_info_sql_select = 4; + isc_info_sql_bind = 5; + isc_info_sql_num_variables = 6; + isc_info_sql_describe_vars = 7; + isc_info_sql_describe_end = 8; + isc_info_sql_sqlda_seq = 9; + isc_info_sql_message_seq = 10; + isc_info_sql_type = 11; + isc_info_sql_sub_type = 12; + isc_info_sql_scale = 13; + isc_info_sql_length = 14; + isc_info_sql_null_ind = 15; + isc_info_sql_field = 16; + isc_info_sql_relation = 17; + isc_info_sql_owner = 18; + isc_info_sql_alias = 19; + isc_info_sql_sqlda_start = 20; + isc_info_sql_stmt_type = 21; + isc_info_sql_get_plan = 22; + isc_info_sql_records = 23; + isc_info_sql_batch_fetch = 24; + isc_info_sql_relation_alias = 25; + isc_info_sql_explain_plan = 26; + isc_info_sql_stmt_flags = 27; + +//*********************************/ +//* SQL information return values */ +//*********************************/ + + isc_info_sql_stmt_select = 1; + isc_info_sql_stmt_insert = 2; + isc_info_sql_stmt_update = 3; + isc_info_sql_stmt_delete = 4; + isc_info_sql_stmt_ddl = 5; + isc_info_sql_stmt_get_segment = 6; + isc_info_sql_stmt_put_segment = 7; + isc_info_sql_stmt_exec_procedure = 8; + isc_info_sql_stmt_start_trans = 9; + isc_info_sql_stmt_commit = 10; + isc_info_sql_stmt_rollback = 11; + isc_info_sql_stmt_select_for_upd = 12; + isc_info_sql_stmt_set_generator = 13; + isc_info_sql_stmt_savepoint = 14; + +//*****************************/ +//* Request information items */ +//*****************************/ + + isc_info_number_messages = 4; + isc_info_max_message = 5; + isc_info_max_send = 6; + isc_info_max_receive = 7; + isc_info_state = 8; + isc_info_message_number = 9; + isc_info_message_size = 10; + isc_info_request_cost = 11; + isc_info_access_path = 12; + isc_info_req_select_count = 13; + isc_info_req_insert_count = 14; + isc_info_req_update_count = 15; + isc_info_req_delete_count = 16; + + isc_spb_version = isc_spb_current_version; + isc_spb_user_name = isc_dpb_user_name; //shortstring + isc_spb_password = isc_dpb_password; //shortstring + isc_spb_sql_role_name = isc_dpb_sql_role_name; + isc_spb_res_stat = isc_spb_bkp_stat; + +type + {$packrecords c} + SSHORT = cshort; + USHORT = cushort; + SLONG = int32; + ULONG = card32; + pULONG = ^ULONG; + ISC_USHORT = cushort; + ISC_SHORT = cshort; + pISC_SHORT = ^ISC_SHORT; + ISC_LONG = SLONG; + pISC_QUAD = ^ISC_QUAD; + + ISC_DATE = int32; + pISC_DATE = ^ISC_DATE; + ISC_TIME = card32; + pISC_TIME = ^ISC_TIME; + + ISC_TIMESTAMP = record + timestamp_date: ISC_DATE; + timestamp_time: ISC_TIME; + end; + pISC_TIMESTAMP = ^ISC_TIMESTAMP; + ISC_STATUS = ptrint; + pISC_STATUS = ^ISC_STATUS; + + vary = record + vary_length: ISC_USHORT; + vary_string: record + end; + end; + pvary = ^vary; + + fbapity = record + master: imaster; + status: istatus; + provider: iprovider; + util: iutil; + end; + +procedure inifbapi(var api: fbapity); +procedure finifbapi(var api: fbapity); + +procedure initializefirebird(const sonames: array of filenamety; + const onlyonce: boolean = false); + //[] = default +procedure releasefirebird(); + +function formatstatus(status: istatus): string; +function event_block(out eventbuffer: pbyte; + const names: array of string): int32; +procedure freeeventblock(var eventbuffer: pbyte); + +var + fb_get_master_interface: function: IMaster + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_get_client_major_version: function(): cint + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + isc_get_client_minor_version: function(): cint + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gds__alloc: function (size_request: SLONG): pointer + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gds__free: function(blk: pointer): ULONG; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gds__vax_integer: function (ptr: pbyte; length: SSHORT): ISC_LONG; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; +(* + gds__event_block: function (event_buffer: ppbyte; result_buffer: ppbyte; + count: USHORT; names: array of const):ISC_LONG + {$ifdef cvcall}cdecl{$else}error{$endif}; {varargs;} +*) + isc_event_counts: procedure (result_vector: pULONG; legth: SSHORT; + before: pbyte; after: pbyte) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gds__sqlcode: function(status_vector: pISC_STATUS): SLONG + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +implementation +uses + msedynload,sysutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +var + libinfo: dynlibinfoty; + master: imaster; + util: iutil; + +procedure initfb(const data: pointer); +begin + master:= fb_get_master_interface(); + util:= master.getutilinterface(); +end; + +procedure releasefb(const data: pointer); +begin + master.getdispatcher().shutdown(nil,0,0); +end; + +procedure inifbapi(var api: fbapity); +begin + initializefirebird([],true); + with api do begin + if master = nil then begin + master:= fb_get_master_interface(); + end; + if status = nil then begin + status:= master.getstatus(); + end; + if provider = nil then begin + provider:= master.getdispatcher(); + end; + if util = nil then begin + util:= master.getutilinterface(); + end; + end; +end; + +procedure finifbapi(var api: fbapity); +begin + with api do begin + util:= nil; + provider:= nil; + if status <> nil then begin + status.dispose(); + status:= nil; + end; + master:= nil; + end; +end; + +procedure initializefirebird(const sonames: array of filenamety; //[] = default + const onlyonce: boolean = false); + +const + funcs: array[0..7] of funcinfoty = ( + (n: 'fb_get_master_interface'; d: @fb_get_master_interface), + (n: 'isc_get_client_major_version'; d: @isc_get_client_major_version), + (n: 'isc_get_client_minor_version'; d: @isc_get_client_minor_version), + (n: 'gds__vax_integer'; d: @gds__vax_integer), +// (n: 'gds__event_block'; d: @gds__event_block), + (n: 'isc_event_counts'; d: @isc_event_counts), + (n: 'gds__alloc'; d: @gds__alloc), + (n: 'gds__free'; d: @gds__free), + (n: 'gds__sqlcode'; d: @gds__sqlcode) + ); + errormessage = 'Can not load Firebird library. '; + +begin + if not onlyonce or (libinfo.refcount = 0) then begin + initializedynlib(libinfo,sonames,firebirdlib,funcs,[],errormessage,@initfb); + end; +end; + +procedure releasefirebird(); +begin + releasedynlib(libinfo,@releasefb); +end; + +function event_block(out eventbuffer: pbyte; + const names: array of string): int32; +var + i1,i2,i3: int32; + po1: pbyte; +begin + i2:= 1; + for i1:= 0 to high(names) do begin + i3:= length(names[i1]); + if i3 > 255 then begin + raise exception.create('event_block: name too long'); + end; + i2:= i2 + i3 + 5; + end; + result:= i2; + po1:= gds__alloc(i2); + eventbuffer:= po1; + po1^:= EPB_version1; + inc(po1); + for i1:= 0 to high(names) do begin + i3:= length(names[i1]); + po1^:= i3; + inc(po1); + move(pointer(names[i1])^,po1^,i3); + inc(po1,i3); + po1^:= 0; + inc(po1); + po1^:= 0; + inc(po1); + po1^:= 0; + inc(po1); + po1^:= 0; + inc(po1); + end; +end; + +procedure freeeventblock(var eventbuffer: pbyte); +begin + if eventbuffer <> nil then begin + gds__free(eventbuffer); + eventbuffer:= nil; + end; +end; + +function formatstatus(status: istatus): string; +var + ca1: card32; +begin + setlength(result,256); + while true do begin + ca1:= util.formatstatus(pointer(result),length(result),status); + if ca1 < length(result) then begin + break; + end; + setlength(result,2*length(result)); + end; + setlength(result,ca1); +end; + +initialization + initializelibinfo(libinfo); +finalization + if libinfo.refcount > 0 then begin + libinfo.refcount:= 1; + releasefirebird(); + end; + finalizelibinfo(libinfo); +end. diff --git a/mseide-msegui/lib/common/db/mseibconnection.pas b/mseide-msegui/lib/common/db/mseibconnection.pas new file mode 100644 index 0000000..bdb2aa7 --- /dev/null +++ b/mseide-msegui/lib/common/db/mseibconnection.pas @@ -0,0 +1,110 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseibconnection; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mdb,classes,mclasses,mibconnection,msetypes{msestrings}, + msedb,msesqldb,msqldb,ibase60dyn, + msebufdataset,msedatabase; +type + tmseibconnection = class(tibconnection,idbcontroller) + private + function getdatabasename: filenamety; + procedure setdatabasename(const avalue: filenamety); + procedure setcontroller(const avalue: tdbcontroller); + function getconnected: boolean; reintroduce; + procedure setconnected(const avalue: boolean); reintroduce; + protected + procedure loaded; override; + //idbcontroller + function readsequence(const sequencename: string): msestring; override; + function sequencecurrvalue(const sequencename: string): msestring; override; + function writesequence(const sequencename: string; + const avalue: largeint): msestring; override; + function CreateBlobStream(const Field: TField; const Mode: TBlobStreamMode; + const acursor: tsqlcursor): TStream; override; + public + published + property DatabaseName: filenamety read getdatabasename write setdatabasename; + property Connected: boolean read getconnected write setconnected default false; + end; + +implementation +uses + msefileutils,sysutils,mseformatstr; + +{ tmseibconnection } + +procedure tmseibconnection.setdatabasename(const avalue: filenamety); +begin + fcontroller.setdatabasename(avalue); +end; + +function tmseibconnection.getdatabasename: filenamety; +begin + result:= fcontroller.getdatabasename; +end; + +procedure tmseibconnection.loaded; +begin + inherited; + fcontroller.loaded; +end; + +procedure tmseibconnection.setcontroller(const avalue: tdbcontroller); +begin + fcontroller.assign(avalue); +end; + +function tmseibconnection.getconnected: boolean; +begin + result:= inherited connected; +end; + +procedure tmseibconnection.setconnected(const avalue: boolean); +begin + if fcontroller.setactive(avalue) then begin + inherited connected:= avalue; + end; +end; + +function tmseibconnection.readsequence(const sequencename: string): msestring; +begin + result:= 'select gen_id('+msestring(sequencename)+ + ',1) as res from RDB$DATABASE;'; +end; + +function tmseibconnection.sequencecurrvalue( + const sequencename: string): msestring; +begin + result:= 'select gen_id('+msestring(sequencename)+ + ',0) as res from RDB$DATABASE;'; +end; + +function tmseibconnection.writesequence(const sequencename: string; + const avalue: largeint): msestring; +begin + result:= 'set generator '+msestring(sequencename)+ + ' to '+inttostrmse(avalue)+';'; +end; + +function tmseibconnection.CreateBlobStream(const Field: TField; + const Mode: TBlobStreamMode; const acursor: tsqlcursor): TStream; +begin + if (mode = bmwrite) and (field.dataset is tmsesqlquery) then begin + result:= tmsebufdataset(field.dataset).createblobbuffer(field); + end + else begin + result:= inherited createblobstream(field,mode,acursor); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/db/mselocaldataset.pas b/mseide-msegui/lib/common/db/mselocaldataset.pas new file mode 100644 index 0000000..756fd6e --- /dev/null +++ b/mseide-msegui/lib/common/db/mselocaldataset.pas @@ -0,0 +1,426 @@ +{ MSEgui Copyright (c) 2009-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mselocaldataset; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,mdb,msestrings,msebufdataset,msedb,mseapplication,msetypes; + +const + defaultlocaldsoptions = defaultdscontrolleroptions + [dso_utf8]; + defaultlocalbdsoptions = defaultbufdatasetoptions + [bdo_local,bdo_noapply]; +type + tlocaldscontroller = class(tdscontroller) + protected +// procedure setoptions(const avalue: datasetoptionsty); override; + public + constructor create(const aowner: tdataset; const aintf: idscontroller; + const arecnooffset: integer = 0; + const acancelresync: boolean = true); + published + property options default defaultlocaldsoptions; + end; + + tlocaldataset = class(tmsebufdataset,imselocate,idscontroller,igetdscontroller, + iactivatorclient) + private +// fcontroller: tdscontroller; + procedure setcontroller(const avalue: tdscontroller); + function getcontroller: tdscontroller; + //idscontroller + procedure inheritedresync(const mode: tresyncmode); + procedure inheriteddataevent(const event: tdataevent; const info: ptrint); + procedure inheritedcancel; + procedure inheritedpost; + procedure inheriteddelete(); + procedure inheritedinsert(); + function inheritedmoveby(const distance: integer): integer; + procedure inheritedinternalinsert; + procedure inheritedinternaldelete; + procedure inheritedinternalopen; + procedure inheritedinternalclose; +// function getblobdatasize: integer; + function getnumboolean: boolean; + function getfloatdate: boolean; + function getint64currency: boolean; +// function getfiltereditkind: filtereditkindty; +// procedure beginfilteredit(const akind: filtereditkindty); +// procedure endfilteredit; +// procedure doidleapplyupdates; + protected + procedure setoptions(const avalue: bufdatasetoptionsty) override; + procedure setactive (const value : boolean); reintroduce; + function getactive: boolean; + procedure loaded; override; + function getfieldclass(fieldtype: tfieldtype): tfieldclass; override; + procedure dataevent(event: tdataevent; info: ptrint); override; +// procedure openlocal; + procedure internalopen; override; + procedure internalinsert; override; + procedure internaldelete; override; + procedure internalclose; override; + function getcanmodify: boolean; override; + function islocal: boolean; override; +// procedure dscontrolleroptionschanged( +// const aoptions: datasetoptionsty); override; + + function fetch : boolean; override; + function getblobdatasize: integer; override; + function blobscached: boolean; override; + function loadfield(const afieldno: integer; const afieldtype: tfieldtype{const afield: tfield}; + const buffer: pointer; + var bufsize: integer): boolean; override; + //if bufsize < 0 -> buffer was to small, should be -bufsize + + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; +{ + function locate(const akeys: array of const; + const afields: array of tfield; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; +} +{ + function locate(const key: integer; const field: tfield; + const options: locateoptionsty = []): locateresultty; + function locate(const key: msestring; const field: tfield; + const options: locateoptionsty = []): locateresultty; +} + function CreateBlobStream(Field: TField; Mode: TBlobStreamMode): TStream; override; + procedure appendrecord(const values: array of const); + procedure cancel; override; + procedure post; override; + function moveby(const distance: integer): integer; + published + property options default defaultlocalbdsoptions; + property controller: tdscontroller read fcontroller write setcontroller; + property Active: boolean read getactive write setactive default false; + property FieldDefs; + property BeforeOpen; + property AfterOpen; + property BeforeClose; + property AfterClose; + property BeforeInsert; + property AfterInsert; + property BeforeEdit; + property AfterEdit; + property BeforePost; + property AfterPost; + property BeforeCancel; + property AfterCancel; + property BeforeDelete; + property AfterDelete; + property BeforeScroll; + property AfterScroll; + property OnCalcFields; + property OnDeleteError; + property OnEditError; + property OnFilterRecord; + property OnNewRecord; + property OnPostError; + property onmodified; + property AutoCalcFields; + end; + +implementation + +{ tlocaldscontroller } + +constructor tlocaldscontroller.create(const aowner: tdataset; + const aintf: idscontroller; const arecnooffset: integer = 0; + const acancelresync: boolean = true); +begin + inherited; + foptions:= defaultlocaldsoptions; +end; +{ +procedure tlocaldscontroller.setoptions(const avalue: datasetoptionsty); +begin + inherited setoptions(avalue + [dso_local]); +end; +} +{ tlocaldataset } + +constructor tlocaldataset.create(aowner: tcomponent); +begin + inherited; + foptions:= defaultlocalbdsoptions; + fcontroller:= tlocaldscontroller.create(self,idscontroller(self),-1,false); +end; + +destructor tlocaldataset.destroy; +begin + fcontroller.free; + inherited; +end; +{ +function tlocaldataset.locate(const key: integer; const field: tfield; + const options: locateoptionsty = []): locateresultty; +begin + result:= fcontroller.locate(key,field,options); +end; + +function tlocaldataset.locate(const key: msestring; + const field: tfield; const options: locateoptionsty = []): locateresultty; +begin + result:= fcontroller.locate(key,field,options); +end; +} +procedure tlocaldataset.appendrecord(const values: array of const); +begin + fcontroller.appendrecord(values); +end; + +procedure tlocaldataset.setcontroller(const avalue: tdscontroller); +begin + fcontroller.assign(avalue); +end; + +function tlocaldataset.getactive: boolean; +begin + result:= inherited active; +end; + +procedure tlocaldataset.setactive(const value: boolean); +begin + if fcontroller.setactive(value) then begin + inherited setactive(value); + end; +end; + +procedure tlocaldataset.loaded; +begin + inherited; + fcontroller.loaded; +end; + +function tlocaldataset.getfieldclass(fieldtype: tfieldtype): tfieldclass; +begin + fcontroller.getfieldclass(fieldtype,result); +end; + +procedure tlocaldataset.dataevent(event: tdataevent; info: ptrint); +begin + fcontroller.dataevent(event,info); +end; + +function tlocaldataset.getcontroller: tdscontroller; +begin + result:= fcontroller; +end; + +procedure tlocaldataset.inheritedresync(const mode: tresyncmode); +begin + inherited resync(mode); +end; + +procedure tlocaldataset.inheriteddataevent(const event: tdataevent; + const info: ptrint); +begin + inherited dataevent(event,info); +end; + +procedure tlocaldataset.inheritedcancel; +begin + inherited cancel; +end; + +procedure tlocaldataset.cancel; +begin + fcontroller.cancel; +end; + +function tlocaldataset.inheritedmoveby(const distance: integer): integer; +begin + result:= inherited moveby(distance); +end; + +procedure tlocaldataset.inheritedinternalinsert; +begin + inherited internalinsert; +end; + +procedure tlocaldataset.internalinsert; +begin + fcontroller.internalinsert; +end; + +function tlocaldataset.moveby(const distance: integer): integer; +begin + result:= fcontroller.moveby(distance); +end; + +procedure tlocaldataset.inheritedinternalopen; +begin + openlocal(); +// inherited internalopen; +end; + +procedure tlocaldataset.internalopen; +begin + fcontroller.internalopen; +end; + +procedure tlocaldataset.inheritedpost; +begin + inherited post; +end; + +procedure tlocaldataset.post; +begin + fcontroller.post; +end; + +procedure tlocaldataset.inheritedinternaldelete; +begin + inherited internaldelete; +end; + +procedure tlocaldataset.internaldelete; +begin + fcontroller.internaldelete; +end; +{ +procedure tlocaldataset.openlocal; +begin + inherited internalopen; +end; +} +procedure tlocaldataset.inheritedinternalclose; +begin + if not (bs_refreshing in fbstate) then begin + if DefaultFields then begin + DestroyFields; + end; + end; + inherited internalclose; +end; + +procedure tlocaldataset.internalclose; +begin + fcontroller.internalclose; +end; + +function tlocaldataset.getblobdatasize: integer; +begin + result:= sizeof(int64); //max +end; + +function tlocaldataset.getnumboolean: boolean; +begin + result:= true; +end; + +function tlocaldataset.getfloatdate: boolean; +begin + result:= true; +end; + +function tlocaldataset.getint64currency: boolean; +begin + result:= true; +end; +{ +function tlocaldataset.getfiltereditkind: filtereditkindty; +begin + result:= fek_filter; +end; +} +{ +procedure tlocaldataset.beginfilteredit(const akind: filtereditkindty); +begin + //dummy +end; + +procedure tlocaldataset.endfilteredit; +begin + //dummy +end; +} +{ +procedure tlocaldataset.doidleapplyupdates; +begin + //dummy +end; +} +procedure tlocaldataset.setoptions(const avalue: bufdatasetoptionsty); +begin + inherited setoptions(avalue + [bdo_local]); +end; + +function tlocaldataset.getcanmodify: boolean; +begin + result:= fcontroller.getcanmodify; +end; + +function tlocaldataset.fetch: boolean; +begin + result:= false; +end; + +function tlocaldataset.blobscached: boolean; +begin + result:= false; +end; + +function tlocaldataset.islocal: boolean; +begin + result:= true; +end; + +function tlocaldataset.loadfield(const afieldno: integer; + const afieldtype: tfieldtype; const buffer: pointer; + var bufsize: integer): boolean; +begin + result:= false; +end; + +function tlocaldataset.CreateBlobStream(Field: TField; + Mode: TBlobStreamMode): TStream; +var + info: blobcacheinfoty; +// int1: integer; + blob1: blobinfoty; +begin + result:= inherited createblobstream(field,mode); + if result = nil then begin + if (bs_blobsfetched in fbstate) and (mode = bmread) then begin + info.id:= 0; //fieldsize can be 32 bit + if field.getdata(@info.id) and findcachedblob(info) then begin + blob1.data:= pointer(info.data); + blob1.datalength:= length(info.data); + result:= tblobcopy.create(blob1); + end; + end + else begin + if mode = bmwrite then begin + result:= createblobbuffer(field); + end; + end; + end; +end; + +procedure tlocaldataset.inheriteddelete(); +begin + inherited delete(); +end; + +procedure tlocaldataset.inheritedinsert(); +begin + inherited insert(); +end; +{ +procedure tlocaldataset.dscontrolleroptionschanged(const aoptions: datasetoptionsty); +begin + //dummy +end; +} +end. diff --git a/mseide-msegui/lib/common/db/mselookupbuffer.pas b/mseide-msegui/lib/common/db/mselookupbuffer.pas new file mode 100644 index 0000000..002c246 --- /dev/null +++ b/mseide-msegui/lib/common/db/mselookupbuffer.pas @@ -0,0 +1,1963 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mselookupbuffer; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +interface + +uses + classes,mclasses,mdb,msedb,msetypes,msestrings,mseclasses,msearrayprops,mselist, + msearrayutils,mseapplication,mseglob,mseinterfaces; + +const + changeeventtag = 85839; +type + tcustomlookupbuffer = class; + tcustomdblookupbuffer = class; + + lookupbufferfieldnoty = type integer; + lbdatakindty = (lbdk_none,lbdk_integer,lbdk_int64,lbdk_float,lbdk_text); + + ilookupbufferfieldinfo = interface(inullinterface)[miid_ilookupbufferfieldinfo] + function getlbdatakind(const apropname: string): lbdatakindty; + function getlookupbuffer: tcustomlookupbuffer; + end; + + lbfiltereventty = procedure(const sender: tcustomlookupbuffer; + const physindex: integer; var valid: boolean) of object; + + tlookupbufferdatalink = class(tmsedatalink) + private + fowner: tcustomlookupbuffer; + public + constructor create(const aowner: tcustomlookupbuffer); + end; + + tlookupbufferfieldsdatalink = class(tlookupbufferdatalink) + private + procedure datachanged; + protected + procedure activechanged; override; + procedure updatedata; override; + procedure dataevent(event: tdataevent; info: ptrint); override; + public + constructor create(const aowner: tcustomdblookupbuffer); + end; + + tlookupbuffermemodatalink = class(tlookupbufferdatalink) + protected + procedure recordchanged(field: tfield); override; + end; + + stringindexinfoty = record + indexcasesensitive: integerarty; + indexcaseinsensitive: integerarty; + data: msestringarty; + end; + stringindexinfoarty = array of stringindexinfoty; + + integerindexinfoty = record + index: integerarty; + data: integerarty; + end; + integerindexinfoarty = array of integerindexinfoty; + + int64indexinfoty = record + index: integerarty; + data: int64arty; + end; + int64indexinfoarty = array of int64indexinfoty; + + floatindexinfoty = record + index: integerarty; + data: realarty; + end; + floatindexinfoarty = array of floatindexinfoty; + + lookupbufferstatety = (lbs_changed,lbs_buffervalid,lbs_changeeventposted, + lbs_sourceclosed); + lookupbufferstatesty = set of lookupbufferstatety; + lookupbuffereventty = procedure(const sender: tcustomlookupbuffer) of object; + + tcustomlookupbuffer = class(tactcomponent) + private + // fbuffervalid: boolean; + fonchange: notifyeventty; + fbeforeload: lookupbuffereventty; + fafterload: lookupbuffereventty; + procedure checkindex(const index: integer); + function internalfind(const avalue; var index: integerarty; + var data; const itemsize: integer; + compfunc: arraysortcomparety; const filter: lbfiltereventty; + out aindex: integer): boolean;//true if exact else next bigger + protected + fupdating: integer; + fcount: integer; + fstate: lookupbufferstatesty; + ftextdata: stringindexinfoarty; + fintegerdata: integerindexinfoarty; + ffloatdata: floatindexinfoarty; + fint64data: int64indexinfoarty; + function getfieldcounttext: integer; virtual; + function getfieldcountinteger: integer; virtual; + function getfieldcountfloat: integer; virtual; + function getfieldcountint64: integer; virtual; + procedure setfieldcounttext(const avalue: integer); virtual; + procedure setfieldcountinteger(const avalue: integer); virtual; + procedure setfieldcountfloat(const avalue: integer); virtual; + procedure setfieldcountint64(const avalue: integer); virtual; + procedure invalidatebuffer; + procedure readonlyprop; + procedure changed; + procedure asyncchanged; //calls changed by postevent + procedure doasyncevent(var atag: integer); override; + procedure setcount(const avalue: integer); + procedure loaded; override; + function checkfilter(const filter: lbfiltereventty; + const index: integerarty; var aindex: integer): boolean; + procedure checkindexar(var aitem: integerindexinfoty); overload; + procedure checkindexar(var aitem: floatindexinfoty); overload; + procedure checkindexar(var aitem: int64indexinfoty); overload; + procedure checkindexar(var aitem: stringindexinfoty; + const caseinsensitive: boolean); overload; + procedure checkarrayindex(const value; const index: integer); + //calls checkbuffer + procedure doloadbuffer() virtual; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure beginupdate; + procedure endupdate; + procedure clearbuffer; virtual; + procedure checkbuffer; //automatically called + procedure loadbuffer; + + function find(const fieldno: integer; const avalue: integer; + out aindex: integer; const filter: lbfiltereventty = nil): boolean; overload; + //logical index, true if found else next bigger + function find(const fieldno: integer; const avalue: realty; + out aindex: integer; const filter: lbfiltereventty = nil): boolean; overload; + //logical index, true if found else next bigger + function find(const fieldno: integer; const avalue: int64; + out aindex: integer; const filter: lbfiltereventty = nil): boolean; overload; + //logical index, true if found else next bigger + function find(const fieldno: integer; const avalue: msestring; + out aindex: integer; + const caseinsensitive: boolean; + const filter: lbfiltereventty = nil): boolean; overload; + //logical index, true if found else next bigger + + function findphys(const fieldno: integer; const avalue: integer; + out aindex: integer; const filter: lbfiltereventty = nil): boolean; overload; + //physical index, true if found else -1 + function findphys(const fieldno: integer; const avalue: realty; + out aindex: integer; const filter: lbfiltereventty = nil): boolean; overload; + //physical index, true if found else -1 + function findphys(const fieldno: integer; const avalue: int64; + out aindex: integer; const filter: lbfiltereventty = nil): boolean; overload; + //physical index, true if found else -1 + function findphys(const fieldno: integer; const avalue: msestring; + out aindex: integer; + const caseinsensitive: boolean; + const filter: lbfiltereventty = nil): boolean; overload; + //physical index, true if found else -1 + + function integervaluephys(const fieldno,aindex: integer): integer; + //physical index + function integervaluelog(const fieldno,aindex: integer): integer; + //logical index + function integerindex(const fieldno,aindex: integer): integer; + //logical -> physical index + function integerindexar(const fieldno: integer): integerarty; + function integerar(const fieldno: integer): integerarty; + + function floatvaluephys(const fieldno,aindex: integer): realty; + //physical index + function floatvaluelog(const fieldno,aindex: integer): realty; + //logical index + function floatindex(const fieldno,aindex: integer): integer; + //logical -> physical index + function floatindexar(const fieldno: integer): integerarty; + function floatar(const fieldno: integer): realarty; + + function int64valuephys(const fieldno,aindex: integer): int64; + //physical index + function int64valuelog(const fieldno,aindex: integer): int64; + //logical index + function int64index(const fieldno,aindex: integer): integer; + //logical -> physical index + function int64indexar(const fieldno: integer): integerarty; + function int64ar(const fieldno: integer): int64arty; + + function textvaluephys(const fieldno,aindex: integer): msestring; + //physical index + function textvaluelog(const fieldno,aindex: integer; + const caseinsensitive: boolean): msestring; + //logical index + function textindex(const fieldno,aindex: integer; + const caseinsensitive: boolean): integer; + //logical -> physical index + function textindexar(const fieldno: integer; + const caseinsensitive: boolean): integerarty; + function textar(const fieldno: integer): msestringarty; + + function lookupinteger(const integerkeyfieldno,integerfieldno, + keyvalue: integer; + const adefault: integer = 0): integer; overload; + function lookupinteger(const int64keyfieldno,integerfieldno: integer; + const keyvalue: int64; + const adefault: integer = 0): integer; overload; + function lookupinteger(const stringkeyfieldno,integerfieldno: integer; + const keyvalue: msestring; + const adefault: integer = 0): integer; overload; + function lookupint64(const integerkeyfieldno,int64fieldno, + keyvalue: integer; + const adefault: int64 = 0): int64; overload; + function lookupint64(const int64keyfieldno,int64fieldno: integer; + const keyvalue: int64; + const adefault: int64 = 0): int64; overload; + function lookupint64(const stringkeyfieldno,int64fieldno: integer; + const keyvalue: msestring; + const adefault: int64 = 0): int64; overload; + function lookuptext(const integerkeyfieldno,textfieldno, + keyvalue: integer; + const adefault: msestring = ''): msestring; overload; + function lookuptext(const int64keyfieldno,textfieldno: integer; + const keyvalue: int64; + const adefault: msestring = ''): msestring; overload; + function lookuptext(const stringkeyfieldno,textfieldno: integer; + const keyvalue: msestring; + const adefault: msestring = ''): msestring; overload; + function lookupfloat(const integerkeyfieldno,floatfieldno,keyvalue: integer; + const adefault: realty = emptyreal): realty; overload; + function lookupfloat(const int64keyfieldno,floatfieldno: integer; + const keyvalue: int64; + const adefault: realty = emptyreal): realty; overload; + function lookupfloat(const stringkeyfieldno,floatfieldno: integer; + const keyvalue: msestring; + const adefault: realty = emptyreal): realty; overload; + + function count: integer; virtual; + procedure addrow(const integervalues: array of integer; + const textvalues: array of msestring; + const floatvalues: array of realty; + const int64values: array of int64); + procedure addrows(const integervalues: array of integerarty; + const textvalues: array of msestringarty; + const floatvalues: array of realarty; + const int64values: array of int64arty); + + function fieldnamestext: stringarty; virtual; + function fieldnamesfloat: stringarty; virtual; + function fieldnamesinteger: stringarty; virtual; + function fieldnamesint64: stringarty; virtual; + + property fieldcounttext: integer read getfieldcounttext + write setfieldcounttext default 0; + property fieldcountfloat: integer read getfieldcountfloat + write setfieldcountfloat default 0; + property fieldcountinteger: integer read getfieldcountinteger + write setfieldcountinteger default 0; + property fieldcountint64: integer read getfieldcountint64 + write setfieldcountint64 default 0; + property integervalue[const fieldno,aindex: integer]: integer + read integervaluephys; + property floatvalue[const fieldno,aindex: integer]: realty + read floatvaluephys; + property int64value[const fieldno,aindex: integer]: int64 + read int64valuephys; + property textvalue[const fieldno,aindex: integer]: msestring + read textvaluephys; + property beforeload: lookupbuffereventty read fbeforeload write fbeforeload; + property afterload: lookupbuffereventty read fafterload write fafterload; + property onchange: notifyeventty read fonchange write fonchange; + end; + + tlookupbuffer = class(tcustomlookupbuffer) + public +{ + procedure addrow(const integervalues: array of integer; + const textvalues: array of msestring; + const floatvalues: array of realty; + const int64values: array of int64); + procedure addrows(const integervalues: array of integerarty; + const textvalues: array of msestringarty; + const floatvalues: array of realarty; + const int64values: array of int64arty); +} + published + property fieldcounttext; + property fieldcountinteger; + property fieldcountint64; + property fieldcountfloat; + property beforeload; + property afterload; + property onchange; + end; + + tdatalookupbuffer = class(tcustomlookupbuffer) + protected + procedure loaded; override; + procedure setfieldcounttext(const avalue: integer); override; + procedure setfieldcountinteger(const avalue: integer); override; + procedure setfieldcountfloat(const avalue: integer); override; + procedure setfieldcountint64(const avalue: integer); override; + procedure fieldschanged(const sender: tarrayprop; const index: integer); + public + function count: integer; override; + published + property beforeload; + property afterload; + property onchange; + end; + + lbdboptionty = (olbdb_closedataset,olbdb_invalidateifmodified); + lbdboptionsty = set of lbdboptionty; + + tcustomdblookupbuffer = class(tdatalookupbuffer) + private + fdatalink: tlookupbufferdatalink; + ftextfields: tdbfieldnamearrayprop; + fintegerfields: tdbfieldnamearrayprop; + ffloatfields: tdbfieldnamearrayprop; + fint64fields: tdbfieldnamearrayprop; + foptionsdb: lbdboptionsty; + function getdatasource: tdatasource; + procedure setdatasource(const avalue: tdatasource); + procedure settextfields(const avalue: tdbfieldnamearrayprop); + procedure setintegerfields(const avalue: tdbfieldnamearrayprop); + procedure setfloatfields(const avalue: tdbfieldnamearrayprop); + procedure setint64fields(const avalue: tdbfieldnamearrayprop); + procedure getfields(out aintegerfields,atextfields,afloatfields, + aint64fields: fieldarty); + protected + function getfieldcounttext: integer; override; + function getfieldcountinteger: integer; override; + function getfieldcountfloat: integer; override; + function getfieldcountint64: integer; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure clearbuffer; override; + property datasource: tdatasource read getdatasource write setdatasource; + + function fieldnamestext: stringarty; override; + function fieldnamesfloat: stringarty; override; + function fieldnamesinteger: stringarty; override; + function fieldnamesint64: stringarty; override; + + property textfields: tdbfieldnamearrayprop read ftextfields write settextfields; + property integerfields: tdbfieldnamearrayprop read fintegerfields write setintegerfields; + property floatfields: tdbfieldnamearrayprop read ffloatfields write setfloatfields; + property int64fields: tdbfieldnamearrayprop read fint64fields write setint64fields; + property optionsdb: lbdboptionsty read foptionsdb write foptionsdb default []; + end; + + tdblookupbuffer = class(tcustomdblookupbuffer) + protected + procedure doloadbuffer; override; + public + constructor create(aowner: tcomponent); override; + published + property datasource; + property textfields; + property integerfields; + property int64fields; + property floatfields; + property optionsdb; + end; + + tdbmemolookupbuffer = class(tcustomdblookupbuffer) + protected + procedure doloadbuffer; override; + public + constructor create(aowner: tcomponent); override; + published + property datasource; + property textfields; + property integerfields; + property floatfields; + end; + +implementation +uses + rtlconsts,sysutils,{msereal,}mseformatstr; + +type + tarrayprop1 = class(tarrayprop); + +{ tcustomlookupbuffer } + +constructor tcustomlookupbuffer.create(aowner: tcomponent); +begin + inherited; +end; + +destructor tcustomlookupbuffer.destroy; +begin + inherited; +end; + +procedure tcustomlookupbuffer.invalidatebuffer; +begin + exclude(fstate,lbs_buffervalid); +// fbuffervalid:= false; +end; + +procedure tcustomlookupbuffer.clearbuffer; +var + int1: integer; +begin + for int1:= 0 to high(fintegerdata) do begin + with fintegerdata[int1] do begin + index:= nil; + data:= nil; + end; + end; + for int1:= 0 to high(fint64data) do begin + with fint64data[int1] do begin + index:= nil; + data:= nil; + end; + end; + for int1:= 0 to high(ftextdata) do begin + with ftextdata[int1] do begin + indexcasesensitive:= nil; + indexcaseinsensitive:= nil; + data:= nil; + end; + end; + for int1:= 0 to high(ffloatdata) do begin + with ffloatdata[int1] do begin + index:= nil; + data:= nil; + end; + end; + for int1:= 0 to high(fint64data) do begin + with fint64data[int1] do begin + index:= nil; + data:= nil; + end; + end; + fcount:= 0; + exclude(fstate,lbs_buffervalid); +// fbuffervalid:= false; + changed; +end; + +procedure tcustomlookupbuffer.doloadbuffer(); +begin + include(fstate,lbs_buffervalid); +// fbuffervalid:= true; +end; + +procedure tcustomlookupbuffer.loadbuffer; +begin + beginupdate(); + try + clearbuffer(); + if canevent(tmethod(fbeforeload)) then begin + fbeforeload(self); + end; + doloadbuffer(); + if canevent(tmethod(fafterload)) then begin + fafterload(self); + end; + finally + endupdate(); + end; +end; + +procedure tcustomlookupbuffer.checkbuffer; +begin + if not (lbs_buffervalid in fstate) then begin + loadbuffer; + end; +end; + +function tcustomlookupbuffer.checkfilter(const filter: lbfiltereventty; + const index: integerarty; var aindex: integer): boolean; +var + int1: integer; + bo1: boolean; +begin + for int1:= aindex to high(index) do begin + bo1:= true; + filter(self,index[int1],bo1); + if bo1 then begin + aindex:= int1; + result:= true; + exit; + end; + end; + result:= false; + aindex:= length(index); +end; + +function tcustomlookupbuffer.internalfind(const avalue; var index: integerarty; + var data; const itemsize: integer; + compfunc: arraysortcomparety; const filter: lbfiltereventty; + out aindex: integer): boolean; //true if found else next bigger +var + int1: integer; + bo1: boolean; +begin + result:= findarrayvalue(avalue,data,itemsize,index,compfunc,aindex); + if assigned(filter) then begin + if result then begin + result:= false; + for int1:= aindex downto 0 do begin + if compfunc((pchar(data)+index[int1]*itemsize)^,avalue) <> 0 then begin + break; //not found + end; + bo1:= true; + filter(self,index[int1],bo1); + if bo1 then begin + result:= true; + aindex:= int1; + break; + end; + end; + end; + if aindex <= high(index) then begin + for int1:= aindex to high(index) do begin + bo1:= true; + filter(self,index[int1],bo1); + if bo1 then begin + aindex:= int1; + exit; + end; + end; + aindex:= length(index); + end; + end; +end; + +procedure tcustomlookupbuffer.checkindexar(var aitem: integerindexinfoty); +begin + with aitem do begin + if (index = nil) and (data <> nil) then begin + application.beginwait; + try + mergesortarray(data,sizeof(integer),length(data),@compareinteger, + index,false); + finally + application.endwait; + end; + end; + end; +end; + +function tcustomlookupbuffer.find(const fieldno: integer; const avalue: integer; + out aindex: integer; const filter: lbfiltereventty = nil): boolean; +begin +// checkbuffer; + checkarrayindex(fintegerdata,fieldno); + checkindexar(fintegerdata[fieldno]); + with fintegerdata[fieldno] do begin + result:= internalfind(avalue,index,data,sizeof(integer), + @compareinteger,filter,aindex); + end; +end; + +procedure tcustomlookupbuffer.checkindexar(var aitem: floatindexinfoty); +begin + with aitem do begin + if (index = nil) and (data <> nil) then begin + application.beginwait; + try + mergesortarray(data,sizeof(realty),length(data),@comparerealty,index,false); + finally + application.endwait; + end; + end; + end; +end; + +function tcustomlookupbuffer.find(const fieldno: integer; const avalue: realty; + out aindex: integer; const filter: lbfiltereventty = nil): boolean; +begin + checkarrayindex(ffloatdata,fieldno); + checkindexar(ffloatdata[fieldno]); + with ffloatdata[fieldno] do begin + result:= internalfind(avalue,index,data,sizeof(realty), + @comparerealty,filter,aindex); + end; +end; + +procedure tcustomlookupbuffer.checkindexar(var aitem: int64indexinfoty); +begin + with aitem do begin + if (index = nil) and (data <> nil) then begin + application.beginwait; + try + mergesortarray(data,sizeof(int64),length(data),@compareint64,index,false); + finally + application.endwait; + end; + end; + end; +end; + +function tcustomlookupbuffer.find(const fieldno: integer; const avalue: int64; + out aindex: integer; const filter: lbfiltereventty = nil): boolean; +begin + checkarrayindex(fint64data,fieldno); + checkindexar(fint64data[fieldno]); + with fint64data[fieldno] do begin + result:= internalfind(avalue,index,data,sizeof(int64), + @compareint64,filter,aindex); + end; +end; + +procedure tcustomlookupbuffer.checkindexar(var aitem: stringindexinfoty; + const caseinsensitive: boolean); +begin + with aitem do begin + if caseinsensitive then begin + if (indexcaseinsensitive = nil) and (data <> nil) then begin + application.beginwait; + try + mergesortarray(data,sizeof(msestring),length(data),@compareimsestring, + indexcaseinsensitive,false); + finally + application.endwait; + end; + end; + end + else begin + if (indexcasesensitive = nil) and (data <> nil) then begin + application.beginwait; + try + mergesortarray(data,sizeof(msestring),length(data),@comparemsestring, + indexcasesensitive,false); + finally + application.endwait; + end; + end; + end; + end; +end; + +function tcustomlookupbuffer.find(const fieldno: integer; const avalue: msestring; + out aindex: integer; const caseinsensitive: boolean; + const filter: lbfiltereventty = nil): boolean; +//var +// int1: integer; +begin +// checkbuffer; + checkarrayindex(ftextdata,fieldno); + checkindexar(ftextdata[fieldno],caseinsensitive); + with ftextdata[fieldno] do begin + if caseinsensitive then begin + result:= internalfind(avalue,indexcaseinsensitive,data,sizeof(msestring), + @compareimsestring,filter,aindex); + end + else begin + result:= internalfind(avalue,indexcasesensitive,data,sizeof(msestring), + @comparemsestring,filter,aindex); + end; + end; +end; + +function tcustomlookupbuffer.findphys(const fieldno: integer; const avalue: integer; + out aindex: integer; const filter: lbfiltereventty = nil): boolean; + //physical index, true if found else -1 +var + int1: integer; +begin + result:= find(fieldno,avalue,int1,filter); + if result then begin + aindex:= integerindex(fieldno,int1); + end + else begin + aindex:= -1; + end; +end; + +function tcustomlookupbuffer.findphys(const fieldno: integer; + const avalue: realty; out aindex: integer; + const filter: lbfiltereventty = nil): boolean; + //physical index, true if found else -1 +var + int1: integer; +begin + result:= find(fieldno,avalue,int1,filter); + if result then begin + aindex:= floatindex(fieldno,int1); + end + else begin + aindex:= -1; + end; +end; + +function tcustomlookupbuffer.findphys(const fieldno: integer; + const avalue: int64; out aindex: integer; + const filter: lbfiltereventty = nil): boolean; + //physical index, true if found else -1 +var + int1: integer; +begin + result:= find(fieldno,avalue,int1,filter); + if result then begin + aindex:= int64index(fieldno,int1); + end + else begin + aindex:= -1; + end; +end; + +function tcustomlookupbuffer.findphys(const fieldno: integer; const avalue: msestring; + out aindex: integer; + const caseinsensitive: boolean; + const filter: lbfiltereventty = nil): boolean; + //physical index, true if found else -1 +var + int1: integer; +begin + result:= find(fieldno,avalue,int1,caseinsensitive,filter); + if result then begin + aindex:= textindex(fieldno,int1,caseinsensitive); + end + else begin + aindex:= -1; + end; +end; + +procedure tcustomlookupbuffer.checkindex(const index: integer); +begin + if (index < 0) or (index >= fcount) then begin + tlist.Error(SListIndexError, Index); + end; +end; + +function tcustomlookupbuffer.integervaluephys(const fieldno,aindex: integer): integer; +begin + checkarrayindex(fintegerdata,fieldno); + checkindex(aindex); + result:= fintegerdata[fieldno].data[aindex]; +end; + +function tcustomlookupbuffer.integervaluelog(const fieldno,aindex: integer): integer; +begin + checkarrayindex(fintegerdata,fieldno); + checkindexar(fintegerdata[fieldno]); + checkindex(aindex); + with fintegerdata[fieldno] do begin + result:= data[index[aindex]]; + end; +end; + +function tcustomlookupbuffer.integerindex(const fieldno,aindex: integer): integer; +begin + checkarrayindex(fintegerdata,fieldno); + checkindexar(fintegerdata[fieldno]); + checkindex(aindex); + result:= fintegerdata[fieldno].index[aindex]; +end; + +function tcustomlookupbuffer.integerindexar(const fieldno: integer): integerarty; +begin + checkarrayindex(fintegerdata,fieldno); + checkindexar(fintegerdata[fieldno]); + result:= fintegerdata[fieldno].index; +end; + +function tcustomlookupbuffer.integerar(const fieldno: integer): integerarty; +begin + checkarrayindex(fintegerdata,fieldno); + result:= fintegerdata[fieldno].data; +end; + +function tcustomlookupbuffer.floatvaluephys(const fieldno,aindex: integer): realty; +begin + checkarrayindex(ffloatdata,fieldno); + checkindex(aindex); + result:= ffloatdata[fieldno].data[aindex]; +end; + +function tcustomlookupbuffer.floatvaluelog(const fieldno,aindex: integer): realty; +begin + checkarrayindex(ffloatdata,fieldno); + checkindexar(ffloatdata[fieldno]); + checkindex(aindex); + with ffloatdata[fieldno] do begin + result:= data[index[aindex]]; + end; +end; + +function tcustomlookupbuffer.floatindex(const fieldno,aindex: integer): integer; +begin + checkarrayindex(ffloatdata,fieldno); + checkindexar(ffloatdata[fieldno]); + checkindex(aindex); + result:= ffloatdata[fieldno].index[aindex]; +end; + +function tcustomlookupbuffer.floatindexar(const fieldno: integer): integerarty; +begin + checkarrayindex(ffloatdata,fieldno); + checkindexar(ffloatdata[fieldno]); + result:= ffloatdata[fieldno].index; +end; + +function tcustomlookupbuffer.floatar(const fieldno: integer): realarty; +begin + checkarrayindex(ffloatdata,fieldno); + result:= ffloatdata[fieldno].data; +end; + +function tcustomlookupbuffer.int64valuephys(const fieldno,aindex: integer): int64; +begin + checkarrayindex(fint64data,fieldno); + checkindex(aindex); + result:= fint64data[fieldno].data[aindex]; +end; + +function tcustomlookupbuffer.int64valuelog(const fieldno,aindex: integer): int64; +begin + checkarrayindex(fint64data,fieldno); + checkindexar(fint64data[fieldno]); + checkindex(aindex); + with fint64data[fieldno] do begin + result:= data[index[aindex]]; + end; +end; + +function tcustomlookupbuffer.int64index(const fieldno,aindex: integer): integer; +begin + checkarrayindex(fint64data,fieldno); + checkindexar(fint64data[fieldno]); + checkindex(aindex); + result:= fint64data[fieldno].index[aindex]; +end; + +function tcustomlookupbuffer.int64indexar(const fieldno: integer): integerarty; +begin + checkarrayindex(fint64data,fieldno); + checkindexar(fint64data[fieldno]); + result:= fint64data[fieldno].index; +end; + +function tcustomlookupbuffer.int64ar(const fieldno: integer): int64arty; +begin + checkarrayindex(fint64data,fieldno); + result:= fint64data[fieldno].data; +end; + +function tcustomlookupbuffer.textvaluephys(const fieldno,aindex: integer): msestring; +begin + checkarrayindex(ftextdata,fieldno); + checkindex(aindex); + result:= ftextdata[fieldno].data[aindex]; +end; + +function tcustomlookupbuffer.textvaluelog(const fieldno,aindex: integer; + const caseinsensitive: boolean): msestring; +begin + checkarrayindex(ftextdata,fieldno); + checkindexar(ftextdata[fieldno],caseinsensitive); + checkindex(aindex); + with ftextdata[fieldno] do begin + if caseinsensitive then begin + result:= data[indexcaseinsensitive[aindex]]; + end + else begin + result:= data[indexcasesensitive[aindex]]; + end; + end; +end; + +function tcustomlookupbuffer.textindex(const fieldno,aindex: integer; + const caseinsensitive: boolean): integer; +begin + checkarrayindex(ftextdata,fieldno); + checkindexar(ftextdata[fieldno],caseinsensitive); + checkindex(aindex); + with ftextdata[fieldno] do begin + if caseinsensitive then begin + result:= indexcaseinsensitive[aindex]; + end + else begin + result:= indexcasesensitive[aindex]; + end; + end; +end; + +function tcustomlookupbuffer.textindexar(const fieldno: integer; + const caseinsensitive: boolean): integerarty; +begin + checkarrayindex(ftextdata,fieldno); + checkindexar(ftextdata[fieldno],caseinsensitive); + if caseinsensitive then begin + result:= ftextdata[fieldno].indexcaseinsensitive; + end + else begin + result:= ftextdata[fieldno].indexcasesensitive; + end; +end; + +function tcustomlookupbuffer.textar(const fieldno: integer): msestringarty; +begin + checkarrayindex(ftextdata,fieldno); + result:= ftextdata[fieldno].data; +end; + +function tcustomlookupbuffer.count: integer; +begin + result:= fcount; +end; + +function tcustomlookupbuffer.getfieldcounttext: integer; +begin + result:= length(ftextdata); +end; + +procedure tcustomlookupbuffer.setfieldcounttext(const avalue: integer); +begin + clearbuffer; + setlength(ftextdata,avalue); +end; + +function tcustomlookupbuffer.getfieldcountinteger: integer; +begin + result:= length(fintegerdata); +end; + +procedure tcustomlookupbuffer.setfieldcountinteger(const avalue: integer); +begin + clearbuffer; + setlength(fintegerdata,avalue); +end; + +function tcustomlookupbuffer.getfieldcountfloat: integer; +begin + result:= length(ffloatdata); +end; + +function tcustomlookupbuffer.getfieldcountint64: integer; +begin + result:= length(fint64data); +end; + +procedure tcustomlookupbuffer.setfieldcountfloat(const avalue: integer); +begin + clearbuffer; + setlength(ffloatdata,avalue); +end; + +procedure tcustomlookupbuffer.setfieldcountint64(const avalue: integer); +begin + clearbuffer; + setlength(fint64data,avalue); +end; + +procedure tcustomlookupbuffer.readonlyprop; +begin + raise exception.create('Property is readonly'); +end; + +procedure tcustomlookupbuffer.beginupdate; +begin + inc(fupdating); +end; + +procedure tcustomlookupbuffer.endupdate; +begin + dec(fupdating); + if fupdating = 0 then begin + changed; + end; +end; + +procedure tcustomlookupbuffer.changed; +begin + if fupdating = 0 then begin + if csloading in componentstate then begin + include(fstate,lbs_changed); + end + else begin + exclude(fstate,lbs_changed); + inc(fupdating); + try + sendchangeevent; + if canevent(tmethod(fonchange)) then begin + fonchange(self); + end; + finally + dec(fupdating); + end; + end; + end; +end; + +procedure tcustomlookupbuffer.doasyncevent(var atag: integer); +begin + inherited; + if atag = changeeventtag then begin + exclude(fstate,lbs_changeeventposted); + changed; + end; +end; + +procedure tcustomlookupbuffer.asyncchanged; +begin + if not (lbs_changeeventposted in fstate) and (fupdating = 0) then begin + include(fstate,lbs_changeeventposted); + asyncevent(changeeventtag); + end; +end; + +procedure tcustomlookupbuffer.setcount(const avalue: integer); +var + int1: integer; +begin + if avalue <> fcount then begin + for int1:= 0 to high(fintegerdata) do begin + with fintegerdata[int1] do begin + setlength(data,avalue); + index:= nil; + end; + end; + for int1:= 0 to high(ftextdata) do begin + with ftextdata[int1] do begin + setlength(data,avalue); + indexcasesensitive:= nil; + indexcaseinsensitive:= nil; + end; + end; + for int1:= 0 to high(ffloatdata) do begin + with ffloatdata[int1] do begin + setlength(data,avalue); + index:= nil; + end; + end; + for int1:= 0 to high(fint64data) do begin + with fint64data[int1] do begin + setlength(data,avalue); + index:= nil; + end; + end; + fcount:= avalue; +// exclude(fstate,lbs_buffervalid); + end; +end; + +procedure tcustomlookupbuffer.loaded; +begin + inherited; + if not (lbs_buffervalid in fstate) or (lbs_changed in fstate) then begin + changed; + end; +end; + +function tcustomlookupbuffer.lookupinteger(const integerkeyfieldno,integerfieldno, + keyvalue: integer; + const adefault: integer = 0): integer; +var + int1: integer; +begin + if findphys(integerkeyfieldno,keyvalue,int1) then begin + result:= integervaluephys(integerfieldno,int1); + end + else begin + result:= adefault; + end; +end; + +function tcustomlookupbuffer.lookupinteger(const int64keyfieldno, + integerfieldno: integer; const keyvalue: int64; + const adefault: integer = 0): integer; +var + int1: integer; +begin + if findphys(int64keyfieldno,keyvalue,int1) then begin + result:= integervaluephys(integerfieldno,int1); + end + else begin + result:= adefault; + end; +end; + +function tcustomlookupbuffer.lookupinteger(const stringkeyfieldno: integer; + const integerfieldno: integer; + const keyvalue: msestring; + const adefault: integer = 0): integer; +var + int1: integer; +begin + if findphys(stringkeyfieldno,keyvalue,int1,false) then begin + result:= integervaluephys(integerfieldno,int1); + end + else begin + result:= adefault; + end; +end; + +function tcustomlookupbuffer.lookupint64(const integerkeyfieldno,int64fieldno, + keyvalue: integer; + const adefault: int64 = 0): int64; +var + int1: integer; +begin + if findphys(integerkeyfieldno,keyvalue,int1) then begin + result:= int64valuephys(int64fieldno,int1); + end + else begin + result:= adefault; + end; +end; + +function tcustomlookupbuffer.lookupint64(const int64keyfieldno, + int64fieldno: integer; const keyvalue: int64; + const adefault: int64 = 0): int64; +var + int1: integer; +begin + if findphys(int64keyfieldno,keyvalue,int1) then begin + result:= int64valuephys(int64fieldno,int1); + end + else begin + result:= adefault; + end; +end; + +function tcustomlookupbuffer.lookupint64(const stringkeyfieldno, + int64fieldno: integer; + const keyvalue: msestring; + const adefault: int64 = 0): int64; +var + int1: integer; +begin + if findphys(stringkeyfieldno,keyvalue,int1,false) then begin + result:= int64valuephys(int64fieldno,int1); + end + else begin + result:= adefault; + end; +end; + +function tcustomlookupbuffer.lookuptext(const integerkeyfieldno: integer; + const textfieldno: integer; const keyvalue: integer; + const adefault: msestring = ''): msestring; +var + int1: integer; +begin + if findphys(integerkeyfieldno,keyvalue,int1) then begin + result:= textvaluephys(textfieldno,int1); + end + else begin + result:= adefault; + end; +end; + +function tcustomlookupbuffer.lookuptext(const int64keyfieldno: integer; + const textfieldno: integer; const keyvalue: int64; + const adefault: msestring = ''): msestring; +var + int1: integer; +begin + if findphys(int64keyfieldno,keyvalue,int1) then begin + result:= textvaluephys(textfieldno,int1); + end + else begin + result:= adefault; + end; +end; + +function tcustomlookupbuffer.lookuptext(const stringkeyfieldno: integer; + const textfieldno: integer; + const keyvalue: msestring; + const adefault: msestring = ''): msestring; +var + int1: integer; +begin + if findphys(stringkeyfieldno,keyvalue,int1,false) then begin + result:= textvaluephys(textfieldno,int1); + end + else begin + result:= adefault; + end; +end; + +function tcustomlookupbuffer.lookupfloat(const integerkeyfieldno: integer; + const floatfieldno: integer; const keyvalue: integer; + const adefault: realty = emptyreal): realty; +var + int1: integer; +begin + if findphys(integerkeyfieldno,keyvalue,int1) then begin + result:= floatvaluephys(floatfieldno,int1); + end + else begin + result:= adefault; + end; +end; + +function tcustomlookupbuffer.lookupfloat(const int64keyfieldno: integer; + const floatfieldno: integer; const keyvalue: int64; + const adefault: realty = emptyreal): realty; +var + int1: integer; +begin + if findphys(int64keyfieldno,keyvalue,int1) then begin + result:= floatvaluephys(floatfieldno,int1); + end + else begin + result:= adefault; + end; +end; + +function tcustomlookupbuffer.lookupfloat(const stringkeyfieldno, + floatfieldno: integer; const keyvalue: msestring; + const adefault: realty = emptyreal): realty; +var + int1: integer; +begin + if findphys(stringkeyfieldno,keyvalue,int1,false) then begin + result:= floatvaluephys(floatfieldno,int1); + end + else begin + result:= adefault; + end; +end; + +procedure tcustomlookupbuffer.checkarrayindex(const value; + const index: integer); +begin + checkbuffer; + msearrayutils.checkarrayindex(value,index); +end; + +function tcustomlookupbuffer.fieldnamestext: stringarty; +begin + result:= nil; +end; + +function tcustomlookupbuffer.fieldnamesfloat: stringarty; +begin + result:= nil; +end; + +function tcustomlookupbuffer.fieldnamesinteger: stringarty; +begin + result:= nil; +end; + +function tcustomlookupbuffer.fieldnamesint64: stringarty; +begin + result:= nil; +end; + +procedure tcustomlookupbuffer.addrow(const integervalues: array of integer; + const textvalues: array of msestring; + const floatvalues: array of realty; + const int64values: array of int64); +var + int1: integer; +begin + setcount(fcount + 1); + for int1:= 0 to high(integervalues) do begin + if int1 > high(fintegerdata) then begin + break; + end; + fintegerdata[int1].data[fcount-1]:= integervalues[int1]; + end; + for int1:= 0 to high(textvalues) do begin + if int1 > high(ftextdata) then begin + break; + end; + ftextdata[int1].data[fcount-1]:= textvalues[int1]; + end; + for int1:= 0 to high(floatvalues) do begin + if int1 > high(ffloatdata) then begin + break; + end; + ffloatdata[int1].data[fcount-1]:= floatvalues[int1]; + end; + for int1:= 0 to high(int64values) do begin + if int1 > high(fint64data) then begin + break; + end; + fint64data[int1].data[fcount-1]:= int64values[int1]; + end; + changed; +end; + +procedure tcustomlookupbuffer.addrows(const integervalues: array of integerarty; + const textvalues: array of msestringarty; + const floatvalues: array of realarty; + const int64values: array of int64arty); +var + int1,int2,int3,countbefore: integer; +begin + int2:= bigint; + for int1:= 0 to high(integervalues) do begin + if high(integervalues[int1]) < int2 then begin + int2:= high(integervalues[int1]); + end; + end; + for int1:= 0 to high(textvalues) do begin + if high(textvalues[int1]) < int2 then begin + int2:= high(textvalues[int1]); + end; + end; + for int1:= 0 to high(floatvalues) do begin + if high(floatvalues[int1]) < int2 then begin + int2:= high(floatvalues[int1]); + end; + end; + for int1:= 0 to high(int64values) do begin + if high(int64values[int1]) < int2 then begin + int2:= high(int64values[int1]); + end; + end; + countbefore:= fcount; + setcount(fcount+int2+1); + for int1:= 0 to high(integervalues) do begin + if int1 > high(fintegerdata) then begin + break; + end; + for int3:= 0 to int2 do begin + fintegerdata[int1].data[int3+countbefore]:= integervalues[int1][int3]; + end; + end; + for int1:= 0 to high(textvalues) do begin + if int1 > high(ftextdata) then begin + break; + end; + for int3:= 0 to int2 do begin + ftextdata[int1].data[int3+countbefore]:= textvalues[int1][int3]; + end; + end; + for int1:= 0 to high(floatvalues) do begin + if int1 > high(ffloatdata) then begin + break; + end; + for int3:= 0 to int2 do begin + ffloatdata[int1].data[int3+countbefore]:= floatvalues[int1][int3]; + end; + end; + for int1:= 0 to high(int64values) do begin + if int1 > high(fint64data) then begin + break; + end; + for int3:= 0 to int2 do begin + fint64data[int1].data[int3+countbefore]:= int64values[int1][int3]; + end; + end; +end; + +{ tlookupbuffer } +{ +procedure tlookupbuffer.addrow(const integervalues: array of integer; + const textvalues: array of msestring; + const floatvalues: array of realty; + const int64values: array of int64); +var + int1: integer; +begin + setcount(fcount + 1); + for int1:= 0 to high(integervalues) do begin + if int1 > high(fintegerdata) then begin + break; + end; + fintegerdata[int1].data[fcount-1]:= integervalues[int1]; + end; + for int1:= 0 to high(textvalues) do begin + if int1 > high(ftextdata) then begin + break; + end; + ftextdata[int1].data[fcount-1]:= textvalues[int1]; + end; + for int1:= 0 to high(floatvalues) do begin + if int1 > high(ffloatdata) then begin + break; + end; + ffloatdata[int1].data[fcount-1]:= floatvalues[int1]; + end; + for int1:= 0 to high(int64values) do begin + if int1 > high(fint64data) then begin + break; + end; + fint64data[int1].data[fcount-1]:= int64values[int1]; + end; + changed; +end; + +procedure tlookupbuffer.addrows(const integervalues: array of integerarty; + const textvalues: array of msestringarty; + const floatvalues: array of realarty; + const int64values: array of int64arty); +var + int1,int2,int3,countbefore: integer; +begin + int2:= bigint; + for int1:= 0 to high(integervalues) do begin + if high(integervalues[int1]) < int2 then begin + int2:= high(integervalues[int1]); + end; + end; + for int1:= 0 to high(textvalues) do begin + if high(textvalues[int1]) < int2 then begin + int2:= high(textvalues[int1]); + end; + end; + for int1:= 0 to high(floatvalues) do begin + if high(floatvalues[int1]) < int2 then begin + int2:= high(floatvalues[int1]); + end; + end; + for int1:= 0 to high(int64values) do begin + if high(int64values[int1]) < int2 then begin + int2:= high(int64values[int1]); + end; + end; + countbefore:= fcount; + setcount(fcount+int2+1); + for int1:= 0 to high(integervalues) do begin + if int1 > high(fintegerdata) then begin + break; + end; + for int3:= 0 to int2 do begin + fintegerdata[int1].data[int3+countbefore]:= integervalues[int1][int3]; + end; + end; + for int1:= 0 to high(textvalues) do begin + if int1 > high(ftextdata) then begin + break; + end; + for int3:= 0 to int2 do begin + ftextdata[int1].data[int3+countbefore]:= textvalues[int1][int3]; + end; + end; + for int1:= 0 to high(floatvalues) do begin + if int1 > high(ffloatdata) then begin + break; + end; + for int3:= 0 to int2 do begin + ffloatdata[int1].data[int3+countbefore]:= floatvalues[int1][int3]; + end; + end; + for int1:= 0 to high(int64values) do begin + if int1 > high(fint64data) then begin + break; + end; + for int3:= 0 to int2 do begin + fint64data[int1].data[int3+countbefore]:= int64values[int1][int3]; + end; + end; +end; +} +{ tdatalokupbuffer } + +procedure tdatalookupbuffer.loaded; +begin + if not (lbs_buffervalid in fstate) then begin + clearbuffer; + end; + inherited; +end; + +procedure tdatalookupbuffer.setfieldcountinteger(const avalue: integer); +begin + readonlyprop; +end; + +procedure tdatalookupbuffer.setfieldcountfloat(const avalue: integer); +begin + readonlyprop; +end; + +procedure tdatalookupbuffer.setfieldcountint64(const avalue: integer); +begin + readonlyprop; +end; + +procedure tdatalookupbuffer.setfieldcounttext(const avalue: integer); +begin + readonlyprop; +end; + +function tdatalookupbuffer.count: integer; +begin + checkbuffer; + result:= inherited count; +end; + +procedure tdatalookupbuffer.fieldschanged(const sender: tarrayprop; + const index: integer); +begin + invalidatebuffer; +end; + +{ tlookupbufferdatalink } + +constructor tlookupbufferdatalink.create(const aowner: tcustomlookupbuffer); +begin + fowner:= aowner; + inherited create; +end; + +{ tcustomdblookupbuffer } + +constructor tcustomdblookupbuffer.create(aowner: tcomponent); +begin + if fdatalink = nil then begin + fdatalink:= tlookupbufferdatalink.create(self); + end; + fintegerfields:= tdbfieldnamearrayprop.create( + msedb.integerfields+[ftboolean], + {$ifdef FPC}@{$endif}getdatasource); + ftextfields:= tdbfieldnamearrayprop.create( + msedb.textfields+[ftboolean], + {$ifdef FPC}@{$endif}getdatasource); + ffloatfields:= tdbfieldnamearrayprop.create(msedb.realfields + msedb.datetimefields, + {$ifdef FPC}@{$endif}getdatasource); + fint64fields:= tdbfieldnamearrayprop.create([ftlargeint], + {$ifdef FPC}@{$endif}getdatasource); + fintegerfields.onchange:= {$ifdef FPC}@{$endif}fieldschanged; + ftextfields.onchange:= {$ifdef FPC}@{$endif}fieldschanged; + ffloatfields.onchange:= {$ifdef FPC}@{$endif}fieldschanged; + fint64fields.onchange:= {$ifdef FPC}@{$endif}fieldschanged; + inherited; +end; + +destructor tcustomdblookupbuffer.destroy; +begin + inherited; + fdatalink.free; + fintegerfields.free; + ftextfields.free; + ffloatfields.free; + fint64fields.free; +end; + +function tcustomdblookupbuffer.getdatasource: tdatasource; +begin + result:= fdatalink.datasource; +end; + +procedure tcustomdblookupbuffer.setdatasource(const avalue: tdatasource); +begin + fdatalink.datasource:= avalue; +end; + +procedure tcustomdblookupbuffer.setintegerfields(const avalue: tdbfieldnamearrayprop); +begin + fintegerfields.assign(avalue); +end; + +procedure tcustomdblookupbuffer.setfloatfields(const avalue: tdbfieldnamearrayprop); +begin + ffloatfields.assign(avalue); +end; + +procedure tcustomdblookupbuffer.setint64fields(const avalue: tdbfieldnamearrayprop); +begin + fint64fields.assign(avalue); +end; + +procedure tcustomdblookupbuffer.settextfields(const avalue: tdbfieldnamearrayprop); +begin + ftextfields.assign(avalue); +end; + +procedure tcustomdblookupbuffer.clearbuffer; +begin + setlength(fintegerdata,fintegerfields.count); + setlength(ftextdata,ftextfields.count); + setlength(ffloatdata,ffloatfields.count); + setlength(fint64data,fint64fields.count); + inherited; +end; + +function tcustomdblookupbuffer.getfieldcounttext: integer; +begin + result:= ftextfields.count; +end; + +function tcustomdblookupbuffer.getfieldcountinteger: integer; +begin + result:= fintegerfields.count; +end; + +function tcustomdblookupbuffer.getfieldcountfloat: integer; +begin + result:= floatfields.count; +end; + +function tcustomdblookupbuffer.getfieldcountint64: integer; +begin + result:= int64fields.count; +end; + +procedure tcustomdblookupbuffer.getfields(out aintegerfields,atextfields, + afloatfields,aint64fields: fieldarty); +var + int1: integer; +begin + with fdatalink.datasource.dataset do begin + setlength(aintegerfields,fintegerfields.count); + for int1:= 0 to high(aintegerfields) do begin + aintegerfields[int1]:= fieldbyname(fintegerfields[int1]); + end; + setlength(atextfields,ftextfields.count); + for int1:= 0 to high(atextfields) do begin + atextfields[int1]:= fieldbyname(ftextfields[int1]); + end; + setlength(afloatfields,ffloatfields.count); + for int1:= 0 to high(afloatfields) do begin + afloatfields[int1]:= fieldbyname(ffloatfields[int1]); + end; + setlength(aint64fields,fint64fields.count); + for int1:= 0 to high(aint64fields) do begin + aint64fields[int1]:= fieldbyname(fint64fields[int1]); + end; + end; +end; + +function tcustomdblookupbuffer.fieldnamestext: stringarty; +begin + result:= ftextfields.itemar; +end; + +function tcustomdblookupbuffer.fieldnamesfloat: stringarty; +begin + result:= ffloatfields.itemar; +end; + +function tcustomdblookupbuffer.fieldnamesinteger: stringarty; +begin + result:= fintegerfields.itemar; +end; + +function tcustomdblookupbuffer.fieldnamesint64: stringarty; +begin + result:= fint64fields.itemar; +end; + +{ tlookupbufferfieldsdatalink } + +constructor tlookupbufferfieldsdatalink.create(const aowner: tcustomdblookupbuffer); +begin + inherited create(aowner); +end; + +procedure tlookupbufferfieldsdatalink.datachanged; +begin + with tcustomdblookupbuffer(fowner) do begin + if active or + not active and (lbs_buffervalid in fstate) and + not (olbdb_closedataset in foptionsdb) then begin + exclude(fstate,lbs_buffervalid); + asyncchanged; + end; + end; +end; + +procedure tlookupbufferfieldsdatalink.activechanged; +begin + inherited; + datachanged; +end; + +procedure tlookupbufferfieldsdatalink.updatedata; +begin + inherited; +// if olbdb_invalidateonupdatedata in tcustomdblookupbuffer(fowner).foptionsdb then begin +// datachanged; +// end; +end; + +procedure tlookupbufferfieldsdatalink.dataevent(event: tdataevent; info: ptrint); +begin + inherited; + if (event = tdataevent(de_modified)) and + (olbdb_invalidateifmodified in + tcustomdblookupbuffer(fowner).foptionsdb) then begin + datachanged; + end; +end; + +{ tdblookupbuffer } + +constructor tdblookupbuffer.create(aowner: tcomponent); +begin + fdatalink:= tlookupbufferfieldsdatalink.create(self); + inherited; +end; + +procedure tdblookupbuffer.doloadbuffer; +var + int1,int3,int4: integer; + bm: string; + textf: fieldarty; + integerf: fieldarty; + realf: fieldarty; + int64f: fieldarty; + datas: tdataset; + utf8: boolean; + bo1: boolean; + ismsestringfield: booleanarty; + statebefore: tdatasetstate; + eofbefore: boolean; +begin +{ + beginupdate; + try + clearbuffer; +} + datas:= fdatalink.dataset; + if (datas <> nil) and + (datas.active or + (olbdb_closedataset in foptionsdb) and + (lbs_sourceclosed in fstate) and + not (csloading in datas.componentstate)) then begin + utf8:= fdatalink.utf8; + bo1:= fdatalink.active; + if bo1 then begin + exclude(fstate,lbs_sourceclosed); + end; + application.beginwait; + try + datas.disablecontrols; + try + datas.active:= true; + try + bm:= datas.bookmark; + statebefore:= datas.state; + eofbefore:= datas.eof; + try + getfields(integerf,textf,realf,int64f); + setlength(ismsestringfield,length(textf)); + for int1:= high(ismsestringfield) downto 0 do begin + ismsestringfield[int1]:= textf[int1] is tmsestringfield; + end; + datas.first; + int3:= fcount; + int1:= fcount; + try + while not datas.eof do begin + if int3 <= int1 then begin + int3:= (int3 * 3) div 2 + 100; + for int4:= 0 to high(ftextdata) do begin + setlength(ftextdata[int4].data,int3); + end; + for int4:= 0 to high(fintegerdata) do begin + setlength(fintegerdata[int4].data,int3); + end; + for int4:= 0 to high(fint64data) do begin + setlength(fint64data[int4].data,int3); + end; + for int4:= 0 to high(ffloatdata) do begin + setlength(ffloatdata[int4].data,int3); + end; + end; + for int4:= 0 to high(integerf) do begin + if integerf[int4] <> nil then begin + fintegerdata[int4].data[int1]:= integerf[int4].asinteger; + end; + end; + for int4:= 0 to high(int64f) do begin + if int64f[int4] <> nil then begin + fint64data[int4].data[int1]:= int64f[int4].aslargeint; + end; + end; + for int4:= 0 to high(realf) do begin + if realf[int4] <> nil then begin + if realf[int4].isnull then begin + ffloatdata[int4].data[int1]:= emptyreal; + end + else begin + ffloatdata[int4].data[int1]:= realf[int4].asfloat; + end; + end; + end; + for int4:= 0 to high(textf) do begin + if textf[int4] <> nil then begin + if ismsestringfield[int4] then begin + ftextdata[int4].data[int1]:= tmsestringfield(textf[int4]).asmsestring; + end + else begin + try + if utf8 then begin + ftextdata[int4].data[int1]:= utf8tostringansi(textf[int4].asstring); + end + else begin + ftextdata[int4].data[int1]:= msestring(textf[int4].asstring); + end; + except + ftextdata[int4].data[int1]:= converrorstring; + end; + end; + end; + end; + inc(int1); + datas.next; + end; + finally + for int4:= 0 to high(fintegerdata) do begin + setlength(fintegerdata[int4].data,int1); + end; + for int4:= 0 to high(fint64data) do begin + setlength(fint64data[int4].data,int1); + end; + for int4:= 0 to high(ftextdata) do begin + setlength(ftextdata[int4].data,int1); + end; + for int4:= 0 to high(ffloatdata) do begin + setlength(ffloatdata[int4].data,int1); + end; + fcount:= int1; + end; + finally + datas.bookmark:= bm; + if statebefore = dsinsert then begin + if eofbefore then begin + datas.append; + end + else begin + datas.insert; + end; + end; + end; + finally + if {not bo1 and} (olbdb_closedataset in foptionsdb) and + not (csdesigning in componentstate)then begin + include(fstate,lbs_sourceclosed); + datas.active:= false; + end; + end; + include(fstate,lbs_buffervalid); //no recursion in enablecontrols + finally + datas.enablecontrols; + end; + finally + application.endwait; + end; + end; + include(fstate,lbs_buffervalid); +{ + finally + endupdate; + end; +} +end; + +{ tlookupbuffermemodatalink } + +procedure tlookupbuffermemodatalink.recordchanged(field: tfield); +begin + with fowner do begin + if (fupdating = 0) and (lbs_buffervalid in fstate) then begin + exclude(fstate,lbs_buffervalid); +// fbuffervalid:= false; + changed; + end; + end; +end; + +{ tdbmemolookupbuffer } + +constructor tdbmemolookupbuffer.create(aowner: tcomponent); +begin + fdatalink:= tlookupbuffermemodatalink.create(self); + inherited; + fintegerfields.fieldtypes:= memofields + msedb.textfields; + ftextfields.fieldtypes:= memofields + msedb.textfields; + ffloatfields.fieldtypes:= memofields + msedb.textfields; +end; + +procedure tdbmemolookupbuffer.doloadbuffer; +var + textf: fieldarty; + integerf: fieldarty; + realf: fieldarty; + int64f: fieldarty; + ar3: stringarty; + int1,int2: integer; + utf8: boolean; +begin +{ + beginupdate; + try + clearbuffer; +} + if fdatalink.active then begin + utf8:= fdatalink.utf8; + getfields(integerf,textf,realf,int64f); + for int1:= 0 to high(integerf) do begin + if not integerf[int1].isnull then begin + ar3:= breaklines(integerf[int1].asstring); + setlength(fintegerdata[int1].data,length(ar3)); + for int2:= 0 to high(ar3) do begin + fintegerdata[int1].data[int2]:= strtoint(ar3[int2]); + end; + end; + end; + for int1:= 0 to high(realf) do begin + if not realf[int1].isnull then begin + ar3:= breaklines(realf[int1].asstring); + setlength(ffloatdata[int1].data,length(ar3)); + for int2:= 0 to high(ar3) do begin + ffloatdata[int1].data[int2]:= strtorealty(ar3[int2]); + end; + end; + end; + for int1:= 0 to high(int64f) do begin + if not int64f[int1].isnull then begin + ar3:= breaklines(int64f[int1].asstring); + setlength(fint64data[int1].data,length(ar3)); + for int2:= 0 to high(ar3) do begin + fint64data[int1].data[int2]:= strtoint64(ar3[int2]); + end; + end; + end; + for int1:= 0 to high(textf) do begin + if utf8 then begin + ftextdata[int1].data:= breaklines(utf8tostringansi(textf[int1].asstring)); + end + else begin + ftextdata[int1].data:= breaklines(msestring(textf[int1].asstring)); + end; + end; + int2:= bigint; + for int1:= 0 to high(fintegerdata) do begin + if high(fintegerdata[int1].data) < int2 then begin + int2:= high(fintegerdata[int1].data); + end; + end; + for int1:= 0 to high(fint64data) do begin + if high(fint64data[int1].data) < int2 then begin + int2:= high(fint64data[int1].data); + end; + end; + for int1:= 0 to high(ffloatdata) do begin + if high(ffloatdata[int1].data) < int2 then begin + int2:= high(ffloatdata[int1].data); + end; + end; + for int1:= 0 to high(ftextdata) do begin + if high(ftextdata[int1].data) < int2 then begin + int2:= high(ftextdata[int1].data); + end; + end; + setcount(int2+1); + end; + include(fstate,lbs_buffervalid); +{ + finally +// fbuffervalid:= true; + endupdate; + end; +} +end; + +end. diff --git a/mseide-msegui/lib/common/db/msememds.pas b/mseide-msegui/lib/common/db/msememds.pas new file mode 100644 index 0000000..e2157ad --- /dev/null +++ b/mseide-msegui/lib/common/db/msememds.pas @@ -0,0 +1,354 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msememds; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,mdb,memds,msedb,msestrings,mseapplication; +type + tmsememdataset = class(tmemdataset,imselocate,idscontroller,igetdscontroller, + iactivatorclient) + private + fcontroller: tdscontroller; + procedure setcontroller(const avalue: tdscontroller); + function getcontroller: tdscontroller; + //idscontroller + procedure inheritedresync(const mode: tresyncmode); + procedure inheriteddataevent(const event: tdataevent; const info: ptrint); + procedure inheritedcancel; + procedure inheritedpost; + procedure inheriteddelete(); + procedure inheritedinsert(); + function inheritedmoveby(const distance: integer): integer; + procedure inheritedinternalinsert; + procedure inheritedinternaldelete; + procedure inheritedinternalopen; + procedure inheritedinternalclose; + function getblobdatasize: integer; + function getnumboolean: boolean; + function getfloatdate: boolean; + function getint64currency: boolean; + function getsavepointoptions(): savepointoptionsty; + function getfiltereditkind: filtereditkindty; + procedure beginfilteredit(const akind: filtereditkindty); + procedure endfilteredit; + procedure clearfilter; +// procedure doidleapplyupdates; + function getrestorerecno: boolean; + procedure setrestorerecno(const avalue: boolean); + function updatesortfield(const afield: tfield; const adescend: boolean): boolean; + protected + procedure setactive (const value : boolean); reintroduce; + function getactive: boolean; + procedure loaded; override; + function getfieldclass(fieldtype: tfieldtype): tfieldclass; override; + procedure dataevent(event: tdataevent; info: ptrint); override; + procedure openlocal; + procedure internalopen; override; + procedure internalinsert; override; + procedure internaldelete; override; + procedure internalclose; override; + function getcanmodify: boolean; override; +// procedure dscontrolleroptionschanged(const aoptions: datasetoptionsty); + function islastrecord: boolean; + procedure begindisplaydata; + procedure enddisplaydata; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; reintroduce; +{ + function locate(const key: integer; const field: tfield; + const options: locateoptionsty = []): locateresultty; + function locate(const key: msestring; const field: tfield; + const options: locateoptionsty = []): locateresultty; +} + procedure AppendRecord(const Values: array of const); + procedure cancel; override; + procedure post; override; + function moveby(const distance: integer): integer; + published + property controller: tdscontroller read fcontroller write setcontroller; + property Active: boolean read getactive write setactive default false; + end; + +implementation + +{ tmsememdataset } + +constructor tmsememdataset.create(aowner: tcomponent); +begin + inherited; + fcontroller:= tdscontroller.create(self,idscontroller(self),-1); +end; + +destructor tmsememdataset.destroy; +begin + fcontroller.free; + inherited; +end; + +function tmsememdataset.locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; +begin + result:= locaterecord(self,afields,akeys,aisnull,akeyoptions,aoptions); +end; +{ +function tmsememdataset.locate(const key: integer; const field: tfield; + const options: locateoptionsty = []): locateresultty; +begin + result:= fcontroller.locate(key,field,options); +end; + +function tmsememdataset.locate(const key: msestring; + const field: tfield; const options: locateoptionsty = []): locateresultty; +begin + result:= fcontroller.locate(key,field,options); +end; +} +procedure tmsememdataset.AppendRecord(const Values: array of const); +begin + fcontroller.appendrecord(values); +end; + +procedure tmsememdataset.setcontroller(const avalue: tdscontroller); +begin + fcontroller.assign(avalue); +end; + +function tmsememdataset.getactive: boolean; +begin + result:= inherited active; +end; + +procedure tmsememdataset.setactive(const value: boolean); +begin + if fcontroller.setactive(value) then begin + inherited setactive(value); + end; +end; + +procedure tmsememdataset.loaded; +begin + inherited; + fcontroller.loaded; +end; + +function tmsememdataset.getfieldclass(fieldtype: tfieldtype): tfieldclass; +begin + fcontroller.getfieldclass(fieldtype,result); +end; + +function tmsememdataset.getcontroller: tdscontroller; +begin + result:= fcontroller; +end; + +procedure tmsememdataset.inheritedresync(const mode: tresyncmode); +begin + inherited resync(mode); +end; + +procedure tmsememdataset.inheriteddataevent(const event: tdataevent; + const info: ptrint); +begin + inherited dataevent(event,info); +end; + +procedure tmsememdataset.inheritedcancel; +begin + inherited cancel; +end; + +procedure tmsememdataset.cancel; +begin + fcontroller.cancel; +end; + +function tmsememdataset.inheritedmoveby(const distance: integer): integer; +begin + result:= inherited moveby(distance); +end; + +procedure tmsememdataset.inheritedinternalinsert; +begin + inherited internalinsert; +end; + +procedure tmsememdataset.internalinsert; +begin + fcontroller.internalinsert; +end; + +function tmsememdataset.moveby(const distance: integer): integer; +begin + result:= fcontroller.moveby(distance); +end; + +procedure tmsememdataset.inheritedinternalopen; +begin + inherited internalopen; +end; + +procedure tmsememdataset.internalopen; +begin + if getrecordsize = 0 then begin + createtable; + end; + fcontroller.internalopen; +end; + +procedure tmsememdataset.inheritedpost; +begin + inherited post; +end; + +procedure tmsememdataset.post; +begin + fcontroller.post; +end; + +procedure tmsememdataset.inheritedinternaldelete; +begin + inherited internaldelete; +end; + +procedure tmsememdataset.internaldelete; +begin + fcontroller.internaldelete; +end; + +procedure tmsememdataset.openlocal; +begin + inherited internalopen; +end; + +procedure tmsememdataset.inheritedinternalclose; +begin + inherited internalclose; +end; + +procedure tmsememdataset.internalclose; +begin + fcontroller.internalclose; +end; + +function tmsememdataset.getblobdatasize: integer; +begin + result:= 0; //no blobs +end; + +function tmsememdataset.getnumboolean: boolean; +begin + result:= true; +end; + +function tmsememdataset.getfloatdate: boolean; +begin + result:= false; +end; + +function tmsememdataset.getint64currency: boolean; +begin + result:= false; +end; + +function tmsememdataset.getsavepointoptions(): savepointoptionsty; +begin + result:= []; +end; + +function tmsememdataset.getfiltereditkind: filtereditkindty; +begin + result:= fek_filter; +end; + +procedure tmsememdataset.beginfilteredit(const akind: filtereditkindty); +begin + //dummy +end; + +procedure tmsememdataset.endfilteredit; +begin + //dummy +end; + +procedure tmsememdataset.clearfilter; +begin + //dummy +end; +{ +procedure tmsememdataset.doidleapplyupdates; +begin + //dummy +end; +} +function tmsememdataset.getcanmodify: boolean; +begin + result:= fcontroller.getcanmodify and inherited getcanmodify; +end; +{ +procedure tmsememdataset.dscontrolleroptionschanged(const aoptions: datasetoptionsty); +begin + //dummy +end; +} +function tmsememdataset.getrestorerecno: boolean; +begin + result:= false; +end; + +procedure tmsememdataset.setrestorerecno(const avalue: boolean); +begin + //dummy +end; + +function tmsememdataset.islastrecord: boolean; +begin + result:= eof or (recno = recordcount); +end; + +procedure tmsememdataset.dataevent(event: tdataevent; info: ptrint); +begin + fcontroller.dataevent(event,info); +end; + +function tmsememdataset.updatesortfield(const afield: tfield; + const adescend: boolean): boolean; +begin + result:= false; +end; + +procedure tmsememdataset.begindisplaydata; +begin + //dummy +end; + +procedure tmsememdataset.enddisplaydata; +begin + //dummy +end; + +procedure tmsememdataset.inheriteddelete; +begin + inherited delete(); +end; + +procedure tmsememdataset.inheritedinsert; +begin + inherited insert(); +end; + +end. diff --git a/mseide-msegui/lib/common/db/msemysql40conn.pas b/mseide-msegui/lib/common/db/msemysql40conn.pas new file mode 100644 index 0000000..e40d42e --- /dev/null +++ b/mseide-msegui/lib/common/db/msemysql40conn.pas @@ -0,0 +1,65 @@ +{ MSEgui Copyright (c) 1999-2006 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msemysql40conn; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mdb,classes,mmysql40conn,msetypes{msestrings},msedb,msedatabase,msqldb; + +type + tmsemysql40connection = class(tmysql40connection,idbcontroller) + private + function getdatabasename: filenamety; + procedure setdatabasename(const avalue: filenamety); + function getconnected: boolean; reintroduce; + procedure setconnected(const avalue: boolean); reintroduce; + protected + procedure loaded; override; + public + published + property DatabaseName: filenamety read getdatabasename write setdatabasename; + property Connected: boolean read getconnected write setconnected default false; + end; + +implementation +uses + msefileutils; + +{ tmsemysql40connection } + +procedure tmsemysql40connection.setdatabasename(const avalue: filenamety); +begin + fcontroller.setdatabasename(avalue); +end; + +function tmsemysql40connection.getdatabasename: filenamety; +begin + result:= fcontroller.getdatabasename; +end; + +procedure tmsemysql40connection.loaded; +begin + inherited; + fcontroller.loaded; +end; + +function tmsemysql40connection.getconnected: boolean; +begin + result:= inherited connected; +end; + +procedure tmsemysql40connection.setconnected(const avalue: boolean); +begin + if fcontroller.setactive(avalue) then begin + inherited connected:= avalue; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/db/msemysql41conn.pas b/mseide-msegui/lib/common/db/msemysql41conn.pas new file mode 100644 index 0000000..b33f74a --- /dev/null +++ b/mseide-msegui/lib/common/db/msemysql41conn.pas @@ -0,0 +1,86 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msemysql41conn; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mdb,classes,mclasses,mmysql41conn,msetypes{msestrings}, + msedb,msqldb,msedatabase; + +type + tmsemysql41connection = class(tmysql41connection,idbcontroller) + private + function getdatabasename: filenamety; + procedure setdatabasename(const avalue: filenamety); + procedure setcontroller(const avalue: tdbcontroller); + function getconnected: boolean; reintroduce; + procedure setconnected(const avalue: boolean); reintroduce; + protected + procedure loaded; override; + function CreateBlobStream(const Field: TField; const Mode: TBlobStreamMode; + const acursor: tsqlcursor): TStream; override; + public + published + property DatabaseName: filenamety read getdatabasename write setdatabasename; + property Connected: boolean read getconnected write setconnected default false; + end; + +implementation +uses + msefileutils,msesqldb,msebufdataset; + +{ tmsemysql41connection } + +procedure tmsemysql41connection.setdatabasename(const avalue: filenamety); +begin + fcontroller.setdatabasename(avalue); +end; + +function tmsemysql41connection.getdatabasename: filenamety; +begin + result:= fcontroller.getdatabasename; +end; + +procedure tmsemysql41connection.loaded; +begin + inherited; + fcontroller.loaded; +end; + +procedure tmsemysql41connection.setcontroller(const avalue: tdbcontroller); +begin + fcontroller.assign(avalue); +end; + +function tmsemysql41connection.getconnected: boolean; +begin + result:= inherited connected; +end; + +procedure tmsemysql41connection.setconnected(const avalue: boolean); +begin + if fcontroller.setactive(avalue) then begin + inherited connected:= avalue; + end; +end; + +function tmsemysql41connection.CreateBlobStream(const Field: TField; + const Mode: TBlobStreamMode; const acursor: tsqlcursor): TStream; +begin + if (mode = bmwrite) and (field.dataset is tmsesqlquery) then begin + result:= tmsebufdataset(field.dataset).createblobbuffer(field); + end + else begin + result:= inherited createblobstream(field,mode,acursor); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/db/msemysql50conn.pas b/mseide-msegui/lib/common/db/msemysql50conn.pas new file mode 100644 index 0000000..c016010 --- /dev/null +++ b/mseide-msegui/lib/common/db/msemysql50conn.pas @@ -0,0 +1,85 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msemysql50conn; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mdb,classes,mclasses,mmysql50conn,msetypes{msestrings},msedb, + msqldb,msedatabase; + +type + tmsemysql50connection = class(tmysql50connection,idbcontroller) + private + function getdatabasename: filenamety; + procedure setdatabasename(const avalue: filenamety); + procedure setcontroller(const avalue: tdbcontroller); + function getconnected: boolean; reintroduce; + procedure setconnected(const avalue: boolean); reintroduce; + protected + procedure loaded; override; + function CreateBlobStream(const Field: TField; const Mode: TBlobStreamMode; + const acursor: tsqlcursor): TStream; override; + public + published + property DatabaseName: filenamety read getdatabasename write setdatabasename; + property Connected: boolean read getconnected write setconnected default false; + end; + +implementation +uses + msefileutils,msesqldb,msebufdataset; + +{ tmsemysql50connection } + +procedure tmsemysql50connection.setdatabasename(const avalue: filenamety); +begin + fcontroller.setdatabasename(avalue); +end; + +function tmsemysql50connection.getdatabasename: filenamety; +begin + result:= fcontroller.getdatabasename; +end; + +procedure tmsemysql50connection.loaded; +begin + inherited; + fcontroller.loaded; +end; + +procedure tmsemysql50connection.setcontroller(const avalue: tdbcontroller); +begin + fcontroller.assign(avalue); +end; + +function tmsemysql50connection.getconnected: boolean; +begin + result:= inherited connected; +end; + +procedure tmsemysql50connection.setconnected(const avalue: boolean); +begin + if fcontroller.setactive(avalue) then begin + inherited connected:= avalue; + end; +end; + +function tmsemysql50connection.CreateBlobStream(const Field: TField; + const Mode: TBlobStreamMode; const acursor: tsqlcursor): TStream; +begin + if (mode = bmwrite) and (field.dataset is tmsesqlquery) then begin + result:= tmsebufdataset(field.dataset).createblobbuffer(field); + end + else begin + result:= inherited createblobstream(field,mode,acursor); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/db/msemysqlconn.pas b/mseide-msegui/lib/common/db/msemysqlconn.pas new file mode 100644 index 0000000..1bb5454 --- /dev/null +++ b/mseide-msegui/lib/common/db/msemysqlconn.pas @@ -0,0 +1,84 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msemysqlconn; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mdb,classes,mclasses,mmysqlconn,msetypes{msestrings},msedb,msqldb,msedatabase; + +type + tmsemysqlconnection = class(tmysqlconnection,idbcontroller) + private + function getdatabasename: filenamety; + procedure setdatabasename(const avalue: filenamety); + procedure setcontroller(const avalue: tdbcontroller); + function getconnected: boolean; reintroduce; + procedure setconnected(const avalue: boolean); reintroduce; + protected + procedure loaded; override; + function CreateBlobStream(const Field: TField; const Mode: TBlobStreamMode; + const acursor: tsqlcursor): TStream; override; + public + published + property DatabaseName: filenamety read getdatabasename write setdatabasename; + property Connected: boolean read getconnected write setconnected default false; + end; + +implementation +uses + msefileutils,msesqldb,msebufdataset; + +{ tmsemysqlconnection } + +procedure tmsemysqlconnection.setdatabasename(const avalue: filenamety); +begin + fcontroller.setdatabasename(avalue); +end; + +function tmsemysqlconnection.getdatabasename: filenamety; +begin + result:= fcontroller.getdatabasename; +end; + +procedure tmsemysqlconnection.loaded; +begin + inherited; + fcontroller.loaded; +end; + +procedure tmsemysqlconnection.setcontroller(const avalue: tdbcontroller); +begin + fcontroller.assign(avalue); +end; + +function tmsemysqlconnection.getconnected: boolean; +begin + result:= inherited connected; +end; + +procedure tmsemysqlconnection.setconnected(const avalue: boolean); +begin + if fcontroller.setactive(avalue) then begin + inherited connected:= avalue; + end; +end; + +function tmsemysqlconnection.CreateBlobStream(const Field: TField; + const Mode: TBlobStreamMode; const acursor: tsqlcursor): TStream; +begin + if (mode = bmwrite) and (field.dataset is tmsesqlquery) then begin + result:= tmsebufdataset(field.dataset).createblobbuffer(field); + end + else begin + result:= inherited createblobstream(field,mode,acursor); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/db/mseodbcconn.pas b/mseide-msegui/lib/common/db/mseodbcconn.pas new file mode 100644 index 0000000..31585fc --- /dev/null +++ b/mseide-msegui/lib/common/db/mseodbcconn.pas @@ -0,0 +1,78 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseodbcconn; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mdb,classes,mclasses,modbcconn,msetypes{msestrings},msedb,msedatabase,msqldb; +type + tmseodbcconnection = class(todbcconnection,idbcontroller) + private + function getdatabasename: filenamety; + procedure setdatabasename(const avalue: filenamety); + function getconnected: boolean; reintroduce; + procedure setconnected(const avalue: boolean); reintroduce; + protected + procedure loaded; override; + function CreateBlobStream(const Field: TField; const Mode: TBlobStreamMode; + const acursor: tsqlcursor): TStream; override; + public + published + property DatabaseName: filenamety read getdatabasename write setdatabasename; + property Connected: boolean read getconnected write setconnected default false; + end; + +implementation +uses + msefileutils,msesqldb,msebufdataset; + +{ tmseodbcconnection } + +procedure tmseodbcconnection.setdatabasename(const avalue: filenamety); +begin + fcontroller.setdatabasename(avalue); +end; + +function tmseodbcconnection.getdatabasename: filenamety; +begin + result:= fcontroller.getdatabasename; +end; + +procedure tmseodbcconnection.loaded; +begin + inherited; + fcontroller.loaded; +end; + +function tmseodbcconnection.getconnected: boolean; +begin + result:= inherited connected; +end; + +procedure tmseodbcconnection.setconnected(const avalue: boolean); +begin + if fcontroller.setactive(avalue) then begin + inherited connected:= avalue; + end; +end; + +function tmseodbcconnection.CreateBlobStream(const Field: TField; + const Mode: TBlobStreamMode; const acursor: tsqlcursor): TStream; +begin + if (mode = bmwrite) and (field.dataset is tmsesqlquery) then begin + result:= tmsebufdataset(field.dataset).createblobbuffer(field); + end + else begin + result:= inherited createblobstream(field,mode,acursor); + end; +end; + + +end. diff --git a/mseide-msegui/lib/common/db/msepqconnection.pas b/mseide-msegui/lib/common/db/msepqconnection.pas new file mode 100644 index 0000000..067b877 --- /dev/null +++ b/mseide-msegui/lib/common/db/msepqconnection.pas @@ -0,0 +1,189 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msepqconnection; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + classes,mclasses,mpqconnection,msestrings,msedb,msetypes,msqldb,mdb, + msedatabase; +type + pqconnectionoptionty = (pqco_usesavepoint,pqco_closetransactiononfail); + pqconnectionoptionsty = set of pqconnectionoptionty; + +const + defaultpqconnectionoptionsty = [pqco_usesavepoint]; + +type + tmsepqconnection = class(tpqconnection,idbcontroller) + private + foptions: pqconnectionoptionsty; + fsavepointlock: boolean; + function getdatabasename: filenamety; + procedure setdatabasename(const avalue: filenamety); + procedure setcontroller(const avalue: tdbcontroller); + function getconnected: boolean; reintroduce; + procedure setconnected(const avalue: boolean); reintroduce; + procedure setoptions(const avalue: pqconnectionoptionsty); + protected + procedure loaded; override; + procedure internalexecute(const cursor: tsqlcursor; + const atransaction: tsqltransaction; + const aparams: tmseparams; const autf8: boolean); override; + function CreateBlobStream(const Field: TField; const Mode: TBlobStreamMode; + const acursor: tsqlcursor): TStream; override; + //idbcontroller + function readsequence(const sequencename: string): msestring; override; + function sequencecurrvalue(const sequencename: string): msestring; override; + function writesequence(const sequencename: string; + const avalue: largeint): msestring; override; + public + constructor create(aowner: tcomponent); override; + published + property DatabaseName: filenamety read getdatabasename write setdatabasename; + property Connected: boolean read getconnected write setconnected + default false; + property options: pqconnectionoptionsty read foptions write setoptions + default defaultpqconnectionoptionsty; +end; + +implementation +uses + msefileutils,msebits,sysutils,msedatalist,msesqldb,msebufdataset,postgres3dyn, + mseformatstr; + +{ tmsepqconnection } + +constructor tmsepqconnection.create(aowner: tcomponent); +begin + foptions:= defaultpqconnectionoptionsty; + inherited; +end; + +procedure tmsepqconnection.setdatabasename(const avalue: filenamety); +begin + fcontroller.setdatabasename(avalue); +end; + +function tmsepqconnection.getdatabasename: filenamety; +begin + result:= fcontroller.getdatabasename; +end; + +procedure tmsepqconnection.loaded; +begin + inherited; + fcontroller.loaded; +end; + +procedure tmsepqconnection.setcontroller(const avalue: tdbcontroller); +begin + fcontroller.assign(avalue); +end; + +function tmsepqconnection.getconnected: boolean; +begin + result:= inherited connected; +end; + +procedure tmsepqconnection.setconnected(const avalue: boolean); +begin + if fcontroller.setactive(avalue) then begin + inherited connected:= avalue; + end; +end; + +procedure tmsepqconnection.internalexecute(const cursor: tsqlcursor; + const atransaction: tsqltransaction; + const aparams: tmseparams; const autf8: boolean); +const + savepointname = 'mseinternal$savepoint'; +var + bo1: boolean; + conn1: ppgconn; +begin + if fsavepointlock then begin + inherited; + end + else begin + conn1:= TPQTrans(aTransaction.Handle).conn; + fsavepointlock:= true; + bo1:= (pqco_usesavepoint in foptions) and not (tao_fake in atransaction.options); + try + if bo1 then begin +// executedirect('SAVEPOINT '+savepointname+';',atransaction); + dopqexec('SAVEPOINT '+savepointname+';',conn1); + end; + try + inherited; + except + if pqco_closetransactiononfail in foptions then begin + atransaction.active:= false; + end + else begin + if bo1 then begin +// executedirect('ROLLBACK TO SAVEPOINT '+savepointname+';',atransaction); + dopqexec('ROLLBACK TO SAVEPOINT '+savepointname+';',conn1); +// executedirect('RELEASE SAVEPOINT '+savepointname+';',atransaction); + dopqexec('RELEASE SAVEPOINT '+savepointname+';',conn1); + end; + end; + raise; + end; + if bo1 then begin +// executedirect('RELEASE SAVEPOINT '+savepointname+';',atransaction); + dopqexec('RELEASE SAVEPOINT '+savepointname+';',conn1); + end; + finally + fsavepointlock:= false; + end; + end; +end; + +procedure tmsepqconnection.setoptions(const avalue: pqconnectionoptionsty); +const + mask: pqconnectionoptionsty = [pqco_usesavepoint,pqco_closetransactiononfail]; +begin + foptions:= pqconnectionoptionsty( + setsinglebit({$ifdef FPC}longword{$else}byte{$endif}(avalue), + {$ifdef FPC}longword{$else}byte{$endif}(foptions), + {$ifdef FPC}longword{$else}byte{$endif}(mask))); +end; + +function tmsepqconnection.readsequence(const sequencename: string): msestring; +begin + result:= 'select nextval(''' +msestring(sequencename)+''') as res;'; +end; + +function tmsepqconnection.sequencecurrvalue( + const sequencename: string): msestring; +begin + result:= 'select last_value from ' + msestring(sequencename) + ';'; +end; + +function tmsepqconnection.writesequence(const sequencename: string; + const avalue: largeint): msestring; +begin + result:= 'select setval(''' +msestring(sequencename)+''','+ + inttostrmse(avalue)+');'; +end; + +function tmsepqconnection.CreateBlobStream(const Field: TField; + const Mode: TBlobStreamMode; const acursor: tsqlcursor): TStream; +begin + if (mode = bmwrite) and (field.dataset is tmsesqlquery) then begin + result:= tmsebufdataset(field.dataset).createblobbuffer(field); + end + else begin + result:= inherited createblobstream(field,mode,acursor); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/db/msesdfdata.pas b/mseide-msegui/lib/common/db/msesdfdata.pas new file mode 100644 index 0000000..f5ea821 --- /dev/null +++ b/mseide-msegui/lib/common/db/msesdfdata.pas @@ -0,0 +1,725 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msesdfdata; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,mdb,msdfdata,msedb,msetypes{msestrings},mseapplication; +type + tmsefixedformatdataset = class(tfixedformatdataset,imselocate, + idscontroller,igetdscontroller,iactivatorclient) + private + ffilename: filenamety; + fcontroller: tdscontroller; + procedure setfilename(const avalue: filenamety); + procedure setcontroller(const avalue: tdscontroller); + function getcontroller: tdscontroller; + //idscontroller +// procedure inheritedresync(const mode: tresyncmode); + procedure inheriteddataevent(const event: tdataevent; const info: ptrint); + procedure inheritedcancel; + procedure inheritedpost; + procedure inheriteddelete(); + procedure inheritedinsert(); + function inheritedmoveby(const distance: integer): integer; + procedure inheritedinternalinsert; + procedure inheritedinternaldelete; + procedure inheritedinternalopen; + procedure inheritedinternalclose; + function getblobdatasize: integer; + function getnumboolean: boolean; + function getfloatdate: boolean; + function getint64currency: boolean; + function getsavepointoptions(): savepointoptionsty; + function getfiltereditkind: filtereditkindty; + procedure beginfilteredit(const akind: filtereditkindty); + procedure endfilteredit; + procedure clearfilter; +// procedure doidleapplyupdates; + function getrestorerecno: boolean; + procedure setrestorerecno(const avalue: boolean); + function updatesortfield(const afield: tfield; const adescend: boolean): boolean; + protected + procedure setactive (const value : boolean); reintroduce; + function getactive: boolean; + procedure loaded; override; + function getfieldclass(fieldtype: tfieldtype): tfieldclass; override; + procedure dataevent(event: tdataevent; info: ptrint); override; + procedure openlocal; + procedure internalopen; override; + procedure internalinsert; override; + procedure internaldelete; override; + procedure internalclose; override; + function getcanmodify: boolean; override; +// procedure dscontrolleroptionschanged(const aoptions: datasetoptionsty); + function islastrecord: boolean; + procedure begindisplaydata; + procedure enddisplaydata; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; reintroduce; + { + function locate(const key: integer; const field: tfield; + const options: locateoptionsty = []): locateresultty; + function locate(const key: msestring; const field: tfield; + const options: locateoptionsty = []): locateresultty; + } + procedure AppendRecord(const Values: array of const); + procedure cancel; override; + procedure post; override; + function moveby(const distance: integer): integer; + published + property FileName: filenamety read ffilename write setfilename; + property controller: tdscontroller read fcontroller write setcontroller; + property Active: boolean read getactive write setactive default false; + property AutocalcFields default false; + property FileMustExist default true; + property Readonly default false; + end; + + tmsesdfdataset = class(tsdfdataset,imselocate,idscontroller,igetdscontroller, + iactivatorclient) + private + ffilename: filenamety; + fcontroller: tdscontroller; + procedure setfilename(const avalue: filenamety); + procedure setcontroller(const avalue: tdscontroller); + function getcontroller: tdscontroller; + //idscontroller +// procedure inheritedresync(const mode: tresyncmode); + procedure inheriteddataevent(const event: tdataevent; const info: ptrint); + procedure inheritedcancel; + procedure inheritedpost; + procedure inheriteddelete(); + procedure inheritedinsert(); + function inheritedmoveby(const distance: integer): integer; + procedure inheritedinternalinsert; + procedure inheritedinternaldelete; + procedure inheritedinternalopen; + procedure inheritedinternalclose; + function getblobdatasize: integer; + function getnumboolean: boolean; + function getfloatdate: boolean; + function getint64currency: boolean; + function getsavepointoptions(): savepointoptionsty; + function getfiltereditkind: filtereditkindty; + procedure beginfilteredit(const akind: filtereditkindty); + procedure endfilteredit; + procedure clearfilter; +// procedure doidleapplyupdates; + function getrestorerecno: boolean; + procedure setrestorerecno(const avalue: boolean); + function updatesortfield(const afield: tfield; const adescend: boolean): boolean; + protected + procedure setactive (const value : boolean); reintroduce; + function getactive: boolean; + procedure loaded; override; + function getfieldclass(fieldtype: tfieldtype): tfieldclass; override; + procedure dataevent(event: tdataevent; info: ptrint); override; + procedure openlocal; + procedure internalopen; override; + procedure internalclose; override; + procedure internalinsert; override; + procedure internaldelete; override; + function getcanmodify: boolean; override; +// procedure dscontrolleroptionschanged(const aoptions: datasetoptionsty); + function islastrecord: boolean; + procedure begindisplaydata; + procedure enddisplaydata; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; reintroduce; +{ + function locate(const key: integer; const field: tfield; + const options: locateoptionsty = []): locateresultty; + function locate(const key: msestring; const field: tfield; + const options: locateoptionsty= []): locateresultty; +} + procedure AppendRecord(const Values: array of const); + procedure cancel; override; + procedure post; override; + function moveby(const distance: integer): integer; + published + property FileName: filenamety read ffilename write setfilename; + property controller: tdscontroller read fcontroller write setcontroller; + property Active: boolean read getactive write setactive default false; + property AutocalcFields default false; + property FileMustExist default true; + property Readonly default false; + property FirstLineAsSchema default false; + end; + +implementation +uses + msefileutils; + +{ tmsefixedformatdataset } + +constructor tmsefixedformatdataset.create(aowner: tcomponent); +begin + inherited; + fcontroller:= tdscontroller.create(self,idscontroller(self),-1); +end; + +destructor tmsefixedformatdataset.destroy; +begin + fcontroller.free; + inherited; +end; + +function tmsefixedformatdataset.locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; +begin + result:= locaterecord(self,afields,akeys,aisnull,akeyoptions,aoptions); +end; +{ +function tmsefixedformatdataset.locate(const key: integer; const field: tfield; + const options: locateoptionsty = []): locateresultty; +begin + result:= fcontroller.locate(key,field,options); +end; + +function tmsefixedformatdataset.locate(const key: msestring; + const field: tfield; const options: locateoptionsty = []): locateresultty; +begin + result:= fcontroller.locate(key,field,options); +end; +} +procedure tmsefixedformatdataset.AppendRecord(const Values: array of const); +begin + fcontroller.appendrecord(values); +end; + +procedure tmsefixedformatdataset.setfilename(const avalue: filenamety); +begin + ffilename:= tomsefilepath(avalue); + inherited filename:= ansistring( + tosysfilepath(filepath(avalue,fk_default,true))); +end; + +procedure tmsefixedformatdataset.setcontroller(const avalue: tdscontroller); +begin + fcontroller.assign(avalue); +end; + +function tmsefixedformatdataset.getactive: boolean; +begin + result:= inherited active; +end; + +procedure tmsefixedformatdataset.setactive(const value: boolean); +begin + if fcontroller.setactive(value) then begin + inherited setactive(value); + end; +end; + +procedure tmsefixedformatdataset.loaded; +begin + inherited; + fcontroller.loaded; +end; + +function tmsefixedformatdataset.getfieldclass(fieldtype: tfieldtype): tfieldclass; +begin + fcontroller.getfieldclass(fieldtype,result); +end; + +function tmsefixedformatdataset.getcontroller: tdscontroller; +begin + result:= fcontroller; +end; + +procedure tmsefixedformatdataset.inheriteddataevent(const event: tdataevent; + const info: ptrint); +begin + inherited dataevent(event,info); +end; + +procedure tmsefixedformatdataset.dataevent(event: tdataevent; info: ptrint); +begin + fcontroller.dataevent(event,info); +end; +{ +procedure tmsefixedformatdataset.inheritedresync(const mode: tresyncmode); +begin + inherited resync(mode); +end; + +procedure tmsefixedformatdataset.Resync(Mode: TResyncMode); +begin + fcontroller.resync(mode); +end; +} +procedure tmsefixedformatdataset.inheritedcancel; +begin + inherited cancel; +end; + +procedure tmsefixedformatdataset.cancel; +begin + fcontroller.cancel; +end; + +function tmsefixedformatdataset.inheritedmoveby(const distance: integer): integer; +begin + result:= inherited moveby(distance); +end; + +procedure tmsefixedformatdataset.inheritedinternalinsert; +begin + inherited internalinsert; +end; + +procedure tmsefixedformatdataset.internalinsert; +begin + fcontroller.internalinsert; +end; + + +procedure tmsefixedformatdataset.inheritedinternalopen; +begin + inherited internalopen; +end; + +procedure tmsefixedformatdataset.internalopen; +begin + fcontroller.internalopen; +end; + +procedure tmsefixedformatdataset.inheritedpost; +begin + inherited post; +end; + +procedure tmsefixedformatdataset.post; +begin + fcontroller.post; +end; + +function tmsefixedformatdataset.moveby(const distance: integer): integer; +begin + result:= fcontroller.moveby(distance); +end; + +procedure tmsefixedformatdataset.inheritedinternaldelete; +begin + inherited internaldelete; +end; + +procedure tmsefixedformatdataset.internaldelete; +begin + fcontroller.internaldelete; +end; + +procedure tmsefixedformatdataset.openlocal; +begin + inherited internalopen; +end; + +procedure tmsefixedformatdataset.inheritedinternalclose; +begin + inherited internalclose; +end; + +procedure tmsefixedformatdataset.internalclose; +begin + fcontroller.internalclose; +end; + +function tmsefixedformatdataset.getblobdatasize: integer; +begin + result:= 0; //no blobs +end; + +function tmsefixedformatdataset.getnumboolean: boolean; +begin + result:= true; +end; + +function tmsefixedformatdataset.getfloatdate: boolean; +begin + result:= false; +end; + +function tmsefixedformatdataset.getint64currency: boolean; +begin + result:= false; +end; + +function tmsefixedformatdataset.getsavepointoptions(): savepointoptionsty; +begin + result:= []; +end; + +function tmsefixedformatdataset.getfiltereditkind: filtereditkindty; +begin + result:= fek_filter; +end; + +procedure tmsefixedformatdataset.beginfilteredit(const akind: filtereditkindty); +begin + //dummy +end; + +procedure tmsefixedformatdataset.endfilteredit; +begin + //dummy +end; + +procedure tmsefixedformatdataset.clearfilter; +begin + //dummy +end; +{ +procedure tmsefixedformatdataset.doidleapplyupdates; +begin + //dummy +end; +} +function tmsefixedformatdataset.getcanmodify: boolean; +begin + result:= fcontroller.getcanmodify and inherited getcanmodify; +end; +{ +procedure tmsefixedformatdataset.dscontrolleroptionschanged(const aoptions: datasetoptionsty); +begin + //dummy +end; +} +function tmsefixedformatdataset.getrestorerecno: boolean; +begin + result:= false; +end; + +procedure tmsefixedformatdataset.setrestorerecno(const avalue: boolean); +begin + //dummy +end; + +function tmsefixedformatdataset.islastrecord: boolean; +begin + result:= eof or (recno = recordcount); +end; + +function tmsefixedformatdataset.updatesortfield(const afield: tfield; + const adescend: boolean): boolean; +begin + result:= false; +end; + +procedure tmsefixedformatdataset.begindisplaydata; +begin + //dummy +end; + +procedure tmsefixedformatdataset.enddisplaydata; +begin + //dummy +end; + +procedure tmsefixedformatdataset.inheriteddelete; +begin + inherited delete(); +end; + +procedure tmsefixedformatdataset.inheritedinsert; +begin + inherited insert(); +end; + +{ tmsesdfdataset } + +constructor tmsesdfdataset.create(aowner: tcomponent); +begin + inherited; + fcontroller:= tdscontroller.create(self,idscontroller(self),-1); +end; + +destructor tmsesdfdataset.destroy; +begin + fcontroller.free; + inherited; +end; + +function tmsesdfdataset.locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; +begin + result:= locaterecord(self,afields,akeys,aisnull,akeyoptions,aoptions); +end; +{ +function tmsesdfdataset.locate(const key: integer; const field: tfield; + const options: locateoptionsty = []): locateresultty; +begin + result:= fcontroller.locate(key,field,options); +end; + +function tmsesdfdataset.locate(const key: msestring; + const field: tfield; const options: locateoptionsty = []): locateresultty; +begin + result:= fcontroller.locate(key,field,options); +end; +} +procedure tmsesdfdataset.AppendRecord(const Values: array of const); +begin + fcontroller.appendrecord(values); +end; + +procedure tmsesdfdataset.setfilename(const avalue: filenamety); +begin + ffilename:= tomsefilepath(avalue); + inherited filename:= ansistring( + tosysfilepath(filepath(avalue,fk_default,true))); +end; + +procedure tmsesdfdataset.setcontroller(const avalue: tdscontroller); +begin + fcontroller.assign(avalue); +end; + +function tmsesdfdataset.getactive: boolean; +begin + result:= inherited active; +end; + +procedure tmsesdfdataset.setactive(const value: boolean); +begin + if fcontroller.setactive(value) then begin + inherited setactive(value); + end; +end; + +procedure tmsesdfdataset.loaded; +begin + inherited; + fcontroller.loaded; +end; + +function tmsesdfdataset.getfieldclass(fieldtype: tfieldtype): tfieldclass; +begin + fcontroller.getfieldclass(fieldtype,result); +end; + +function tmsesdfdataset.getcontroller: tdscontroller; +begin + result:= fcontroller; +end; + +procedure tmsesdfdataset.inheriteddataevent(const event: tdataevent; + const info: ptrint); +begin + inherited dataevent(event,info); +end; + +procedure tmsesdfdataset.dataevent(event: tdataevent; info: ptrint); +begin + fcontroller.dataevent(event,info); +end; + +{ +procedure tmsesdfdataset.inheritedresync(const mode: tresyncmode); +begin + inherited resync(mode); +end; + +procedure tmsesdfdataset.Resync(Mode: TResyncMode); +begin + fcontroller.resync(mode); +end; +} +procedure tmsesdfdataset.inheritedcancel; +begin + inherited cancel; +end; + +procedure tmsesdfdataset.cancel; +begin + fcontroller.cancel; +end; + +function tmsesdfdataset.inheritedmoveby(const distance: integer): integer; +begin + result:= inherited moveby(distance); +end; + +procedure tmsesdfdataset.inheritedinternalinsert; +begin + inherited internalinsert; +end; + +procedure tmsesdfdataset.internalinsert; +begin + fcontroller.internalinsert; +end; + +procedure tmsesdfdataset.inheritedinternalopen; +begin + inherited internalopen; +end; + +procedure tmsesdfdataset.internalopen; +begin + fcontroller.internalopen; +end; + +procedure tmsesdfdataset.inheritedpost; +begin + inherited post; +end; + +procedure tmsesdfdataset.post; +begin + fcontroller.post; +end; + +function tmsesdfdataset.moveby(const distance: integer): integer; +begin + result:= fcontroller.moveby(distance); +end; + +procedure tmsesdfdataset.inheritedinternaldelete; +begin + inherited internaldelete; +end; + +procedure tmsesdfdataset.internaldelete; +begin + fcontroller.internaldelete; +end; + +procedure tmsesdfdataset.openlocal; +begin + inherited internalopen; +end; + +procedure tmsesdfdataset.inheritedinternalclose; +begin + inherited internalclose; +end; + +procedure tmsesdfdataset.internalclose; +begin + fcontroller.internalclose; +end; + +function tmsesdfdataset.getblobdatasize: integer; +begin + result:= 0; //no blobs +end; + +function tmsesdfdataset.getnumboolean: boolean; +begin + result:= true; +end; + +function tmsesdfdataset.getfloatdate: boolean; +begin + result:= false; +end; + +function tmsesdfdataset.getint64currency: boolean; +begin + result:= false; +end; + +function tmsesdfdataset.getsavepointoptions(): savepointoptionsty; +begin + result:= []; +end; + +function tmsesdfdataset.getfiltereditkind: filtereditkindty; +begin + result:= fek_filter; +end; + +procedure tmsesdfdataset.beginfilteredit(const akind: filtereditkindty); +begin + //dummy +end; + +procedure tmsesdfdataset.endfilteredit; +begin + //dummy +end; + +procedure tmsesdfdataset.clearfilter; +begin + //dummy +end; +{ +procedure tmsesdfdataset.doidleapplyupdates; +begin + //dummy +end; +} +function tmsesdfdataset.getcanmodify: boolean; +begin + result:= fcontroller.getcanmodify and inherited getcanmodify; +end; +{ +procedure tmsesdfdataset.dscontrolleroptionschanged(const aoptions: datasetoptionsty); +begin + //dummy +end; +} +function tmsesdfdataset.getrestorerecno: boolean; +begin + result:= false; +end; + +procedure tmsesdfdataset.setrestorerecno(const avalue: boolean); +begin + //dummy +end; + +function tmsesdfdataset.islastrecord: boolean; +begin + result:= eof or (recno = recordcount); +end; + +function tmsesdfdataset.updatesortfield(const afield: tfield; + const adescend: boolean): boolean; +begin + result:= false; +end; + +procedure tmsesdfdataset.begindisplaydata; +begin + //dummy +end; + +procedure tmsesdfdataset.enddisplaydata; +begin + //dummy +end; + +procedure tmsesdfdataset.inheriteddelete; +begin + inherited delete(); +end; + +procedure tmsesdfdataset.inheritedinsert; +begin + inherited insert(); +end; + +end. diff --git a/mseide-msegui/lib/common/db/msesqldb.pas b/mseide-msegui/lib/common/db/msesqldb.pas new file mode 100644 index 0000000..b84d563 --- /dev/null +++ b/mseide-msegui/lib/common/db/msesqldb.pas @@ -0,0 +1,1992 @@ +{ MSEgui Copyright (c) 1999-2015 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msesqldb; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$goto on}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,mdb,msebufdataset,msqldb,msedb,mseclasses,msetypes,mseglob, + msedatabase,sysutils,msetimer,msestrings,msearrayprops,mseapplication, + msesqlquery,mseinterfaces; + +type + fieldparamlinkoptionty = ( + fplo_disabled, + fplo_autorefresh,fplo_refreshifactiveonly, + fplo_refreshifchangedonly,fplo_checkbrowsemodeonrefresh, + fplo_restorerecno, + fplo_syncmasterpost,fplo_delayedsyncmasterpost, + fplo_syncmastercancel, + fplo_syncmastercancelupdates, + fplo_syncmasterapplyupdates, + fplo_syncmastercheckbrowsemode, + fplo_syncmasteredit, + fplo_syncmasterinsert, + fplo_syncmasterdelete, + fplo_syncslavepost,fplo_delayedsyncslavepost, + fplo_syncslavecancel, + fplo_syncslaveedit, + fplo_syncslaveinsert,fplo_syncslaveinserttoedit, + fplo_syncslavedelete,fplo_syncslavedeletetoedit + ); + fieldparamlinkoptionsty = set of fieldparamlinkoptionty; +const + defaultfieldparamlinkoptions = [fplo_autorefresh,fplo_refreshifchangedonly]; + + defaultsqlcontrolleroptions = defaultdscontrolleroptions; + defaultsqlbdsoptions = defaultbufdatasetoptions + + [bdo_autoapply,bdo_autocommitret]; +type + tmsesqltransaction = class(tsqltransaction,iactivatorclient) + private + fcontroller: ttacontroller; + function getactive: boolean; + procedure setactive(const avalue: boolean); + procedure setcontroller(const avalue: ttacontroller); + protected + procedure loaded; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property Active : boolean read getactive write setactive default false; + property controller: ttacontroller read fcontroller write setcontroller; + end; + + tmsesqlquery = class; + + applyrecupdateeventty = + procedure(const sender: tmsesqlquery; const updatekind: tupdatekind; + var asql: msestring; var done: boolean) of object; + afterapplyrecupdateeventty = + procedure(const sender: tmsesqlquery; + const updatekind: tupdatekind) of object; + updateerroreventty = procedure(const sender: tmsesqlquery; + const aupdatekind: tupdatekind; + var aupdateaction: tupdateaction) of object; + + tsqldscontroller = class(tdscontroller) + protected + function savepointbegin: integer; override; + procedure savepointrollback(const alevel: integer = -1); override; + procedure savepointrelease; override; + public + constructor create(const aowner: tmsesqlquery); + published + property options default defaultsqlcontrolleroptions; + end; + + tmsesqlquery = class(tsqlquery,imselocate,idscontroller,igetdscontroller, + isqlpropertyeditor,iactivatorclient) + private + fsqlonchangebefore: notifyeventty; +// fcontroller: tdscontroller; + fonapplyrecupdate: applyrecupdateeventty; + fonapplyrecupdate2: afterapplyrecupdateeventty; + fafterapplyrecupdate: afterapplyrecupdateeventty; + ftransopenref: integer; + procedure setcontroller(const avalue: tdscontroller); + procedure setactive1(value : boolean); + function getactive: boolean; + procedure setonapplyrecupdate(const avalue: applyrecupdateeventty); + procedure setonapplyrecupdate2(const avalue: afterapplyrecupdateeventty); + function getcontroller: tdscontroller; + function getindexdefs: TIndexDefs; + procedure setindexdefs(const avalue: TIndexDefs); +// function getetstatementtype: TStatementType; +// procedure setstatementtype(const avalue: TStatementType); + procedure checkcanupdate; + protected + function getdefaultoptions(): bufdatasetoptionsty override; + procedure dobeforeapplyupdate; override; + procedure checkpendingupdates; override; + procedure setactive(avalue: boolean); override; + procedure setcontrolleractive(const avalue: boolean); + procedure idscontroller.setactive = setcontrolleractive; + procedure iactivatorclient.setactive = setcontrolleractive; + procedure afterapply; override; + procedure updateindexdefs; override; + procedure sqlonchange(const sender: tobject); + procedure loaded; override; + procedure internalopen; override; + procedure internalclose; override; + procedure DoAfterDelete; override; + procedure internalinsert; override; + procedure internaldelete; override; + procedure applyrecupdate(updatekind: tupdatekind); override; + function getcanmodify: boolean; override; + function getfieldclass(fieldtype: tfieldtype): tfieldclass; override; + procedure dataevent(event: tdataevent; info: ptrint); override; + function islocal: boolean; override; + //icursorclient + function stringmemo: boolean; override; + //memo fields are text(0) fields + //idscontroller + procedure inheriteddataevent(const event: tdataevent; const info: ptrint); + procedure inheritedcancel; + procedure inheritedpost; + procedure inheriteddelete(); + procedure inheritedinsert(); + function inheritedmoveby(const distance: integer): integer; + procedure inheritedinternalinsert; virtual; + procedure inheritedinternaldelete; virtual; + procedure inheritedinternalopen; + procedure inheritedinternalclose; + procedure doidleapplyupdates() override; + +// function wantblobfetch: boolean; override; +// function getdsoptions: datasetoptionsty; override; + procedure afterpost(const sender: tdataset; var ok: boolean); +// function cantransactionrefresh: boolean; override; +//, function refreshtransdatasets: boolean; override; + + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function isutf8: boolean; override; + procedure appendrecord(const values: array of const); + procedure appendrecord(const values: array of const; + const aisnull: array of boolean); + function moveby(const distance: integer): integer; + procedure cancel; override; + function post1(): boolean; //true if OK + procedure post override; + function delete1(): boolean; //true if ok + procedure delete override; +// procedure insert; override; + procedure applyupdates(const maxerrors: integer; + const cancelonerror: boolean; + const cancelondeleteerror: boolean = false; + const editonerror: boolean = false); overload; override; + procedure applyupdates(const maxerrors: integer = 0); overload; override; + procedure applyupdate; overload; override; + published + property FieldDefs; + property delayedapplycount; + property options default defaultsqlbdsoptions; + property controller: tdscontroller read fcontroller write setcontroller; + property Active: boolean read getactive write setactive1 default false; + property onapplyrecupdate: applyrecupdateeventty read fonapplyrecupdate + write setonapplyrecupdate; + //raise eupdateerror in order to skip update of the record + property onapplyrecupdate2: afterapplyrecupdateeventty + read fonapplyrecupdate2 + write setonapplyrecupdate2; + //called after inherited + property afterapplyrecupdate: afterapplyrecupdateeventty + read fafterapplyrecupdate write fafterapplyrecupdate; + property UpdateMode default upWhereKeyOnly; + property UsePrimaryKeyAsKey default true; + property IndexDefs : TIndexDefs read getindexdefs write setindexdefs; + //must be writable because it is streamed +// property StatementType : TStatementType read getetstatementtype +// write setstatementtype default stnone; + //must be writable because it was streamed in FPC 2.0.4 + end; + + idbparaminfo = interface(inullinterface)[miid_idbparaminfo] + function getdestdataset: tsqlquery; + end; + + tfieldparamlink = class; + + setparameventty = procedure(const sender: tfieldparamlink; + var done: boolean) of object; + + tparamsourcedatalink = class(tfielddatalink) + private + fownerlink: tfieldparamlink; + fparamset: boolean; + fchangelock: integer; + frefreshlock: integer; + protected +// procedure checkrefresh; + procedure recordchanged(afield: tfield); override; + procedure DataEvent(Event: TDataEvent; Info: Ptrint); override; + procedure CheckBrowseMode; override; + public + constructor create(const aowner: tfieldparamlink); + procedure loaded; + end; + + tparamdestdatalink = class(tmsedatalink) + private + fownerlink: tfieldparamlink; + protected + procedure updatedata; override; + function cansync(out sourceds: tdataset): boolean; + procedure DataEvent(Event: TDataEvent; Info: Ptrint); override; + procedure CheckBrowseMode; override; + public + constructor create(const aowner: tfieldparamlink); + end; + + tdestvalue = class(townedpersistent,idbeditinfo,idbparaminfo) + private + fdatalink: tfielddatalink; +// fparamname: string; + function getdatasource: tdatasource; + procedure setdatasource(const avalue: tdatasource); + function getfieldname: string; + procedure setfieldname(const avalue: string); + protected + //idbeditinfo + function getdataset(const aindex: integer): tdataset; virtual; + procedure getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); virtual; + //idbparaminfo + function getdestdataset: tsqlquery; + public + constructor create(aowner: tobject); override; + destructor destroy; override; + published + property datasource: tdatasource read getdatasource write setdatasource; + property fieldname: string read getfieldname write setfieldname; +// property paramname: string read fparamname write fparamname; + end; + + tdestparam = class(tdestvalue) + private + fparamname: string; + published + property paramname: string read fparamname write fparamname; + end; + + tdestparams = class(townedpersistentarrayprop) + public + constructor create(const aowner: tfieldparamlink); reintroduce; + class function getitemclasstype: persistentclassty; override; + //used in dumpunitgroups + end; + + destfieldoptionty = (dfo_onlyifnull,dfo_notifunmodifiedinsert); + destfieldoptionsty = set of destfieldoptionty; + + tdestfield = class(tdestvalue) + private + fdestfieldname: string; + foptions: destfieldoptionsty; + protected + //idbeditinfo + function getdataset(const aindex: integer): tdataset; override; + procedure getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); override; + published + property destfieldname: string read fdestfieldname write fdestfieldname; + property options: destfieldoptionsty read foptions write foptions default []; + end; + + tdestfields = class(townedpersistentarrayprop) + public + constructor create(const aowner: tfieldparamlink); reintroduce; + class function getitemclasstype: persistentclassty; override; + //used in dumpunitgroups + end; + + tfieldparamlink = class(tmsecomponent,idbeditinfo,idbparaminfo) + private + fsourcedatalink: tparamsourcedatalink; + fdestdataset: tsqlquery; + fdestdatasource: tdatasource; + fdestdatalink: tparamdestdatalink; + fdestcontroller: tdscontroller; + fparamname: string; + fonsetparam: setparameventty; + fonaftersetparam: notifyeventty; + fonrefresh: notifyeventty; + foptions: fieldparamlinkoptionsty; + fdelayus: integer; + fnodelay: integer; + fonupdatemasteredit: masterdataseteventty; + fonupdatemasterinsert: masterdataseteventty; + fonupdateslaveedit: slavedataseteventty; + fonupdateslaveinsert: slavedataseteventty; + fdestparams: tdestparams; + fdestfields: tdestfields; + fonmasterdelete: masterdataseteventty; + fonslavedelete: slavedataseteventty; + fonmasterpost: masterdataseteventty; + fonslavepost: slavedataseteventty; + fonmasterapplyupdate: masterdataseteventty; + function getdatasource: tdatasource; overload; + procedure setdatasource(const avalue: tdatasource); + function getvisualcontrol: boolean; + procedure setvisualcontrol(const avalue: boolean); + function getdestdataset: tsqlquery; + procedure setdestdataset(const avalue: tsqlquery); + procedure setdelayus(const avalue: integer); + procedure setdestparams(const avalue: tdestparams); + function getfieldname: string; + procedure setfieldname(const avalue: string); + procedure readdatafield(reader: treader); + procedure setdestfields(const avalue: tdestfields); + procedure setoptions(const avalue: fieldparamlinkoptionsty); + function getenabled: boolean; + procedure setenabled(const avalue: boolean); + protected + fcheckbrowsemodelock: int32; + procedure loaded; override; + procedure defineproperties(filer: tfiler); override; + //idbeditinfo + function getdataset(const aindex: integer): tdataset; overload; + procedure getfieldtypes(out propertynames: stringarty; + out fieldtypes: fieldtypesarty); + procedure notification(acomponent: tcomponent; + operation: toperation); override; + function truedelayus: integer; + function param(const aname: string): tparam; overload; + function field(const aname: string): tfield; overload; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function param: tparam; overload; + function field: tfield; overload; + procedure checkrefresh; + procedure delayoff; + procedure delayon; + property enabled: boolean read getenabled write setenabled; + published + property fieldname: string read getfieldname write setfieldname; + property datasource: tdatasource read getdatasource write setdatasource; + property visualcontrol: boolean read getvisualcontrol + write setvisualcontrol default false; + property destdataset: tsqlquery read getdestdataset write setdestdataset; + property paramname: string read fparamname write fparamname; + property delayus: integer read fdelayus write setdelayus default -1; + //-1 -> off, 0 -> on idle + property options: fieldparamlinkoptionsty read foptions write setoptions + default defaultfieldparamlinkoptions; + property destparams: tdestparams read fdestparams + write setdestparams; + property destfields: tdestfields read fdestfields + write setdestfields; + property onsetparam: setparameventty read fonsetparam write fonsetparam; + property onaftersetparam: notifyeventty read fonaftersetparam + write fonaftersetparam; + property onrefresh: notifyeventty read fonrefresh + write fonrefresh; + property onupdatemasteredit: masterdataseteventty read fonupdatemasteredit + write fonupdatemasteredit; + property onupdatemasterinsert: masterdataseteventty read fonupdatemasterinsert + write fonupdatemasterinsert; + property onupdateslaveedit: slavedataseteventty read fonupdateslaveedit + write fonupdateslaveedit; + property onupdateslaveinsert: slavedataseteventty read fonupdateslaveinsert + write fonupdateslaveinsert; + property onmasterdelete: masterdataseteventty read fonmasterdelete + write fonmasterdelete; + property onslavedelete: slavedataseteventty read fonslavedelete + write fonslavedelete; + property onmasterpost: masterdataseteventty read fonmasterpost + write fonmasterpost; + property onslavepost: slavedataseteventty read fonslavepost + write fonslavepost; + property onmasterapplyupdate: masterdataseteventty read fonmasterapplyupdate + write fonmasterapplyupdate; + end; + + tsequencelink = class; + + tsequencedatalink = class(tfielddatalink) + private + fownerlink: tsequencelink; + protected + procedure updatedata; override; + public + constructor create(const aowner: tsequencelink); + end; + + tsequencelink = class(tmsecomponent,idbeditinfo) + private + fsequencename: string; + fdatabase: tsqlconnection; + fdbintf: idbcontroller; + fdatalink: tfielddatalink; + fonupdatevalue: updateint64eventty; + flastvalue: largeint; + procedure checkintf; + procedure setdatabase(const avalue: tsqlconnection); + procedure setsequencename(const avalue: string); + function getaslargeint: largeint; + procedure setaslargeint(const avalue: largeint); + function getasinteger: integer; + procedure setasinteger(const avalue: integer); + function getdatasource: tdatasource; overload; + procedure setdatasource(const avalue: tdatasource); + function getdatafield: string; + procedure setdatafield(const avalue: string); + //idbeditinfo + function getdataset(const aindex: integer): tdataset; overload; + procedure getfieldtypes(out propertynames: stringarty; + out fieldtypes: fieldtypesarty); + protected + procedure notification(acomponent: tcomponent; operation: toperation); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property aslargeint: largeint read getaslargeint write setaslargeint; + property asinteger: integer read getasinteger write setasinteger; + function assql: string; + property lastvalue: largeint read flastvalue; + function currvalue: largeint; + published + property database: tsqlconnection read fdatabase write setdatabase; + property datasource: tdatasource read getdatasource write setdatasource; + property datafield: string read getdatafield write setdatafield; + property sequencename: string read fsequencename write setsequencename; + + property onupdatevalue: updateint64eventty read fonupdatevalue write fonupdatevalue; + end; + +implementation +uses + {$ifdef FPC}dbconst{$else}dbconst_del{$endif},msesysutils,typinfo,msedatalist, + msesqlresult,msebits; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{ tmsesqltransaction } + +constructor tmsesqltransaction.create(aowner: tcomponent); +begin + inherited; + fcontroller:= ttacontroller.create(self,iactivatorclient(self)); +end; + +destructor tmsesqltransaction.destroy; +begin + inherited; + fcontroller.free; +end; + +function tmsesqltransaction.getactive: boolean; +begin + result:= inherited active; +end; + +procedure tmsesqltransaction.setactive(const avalue: boolean); +begin + if fcontroller.setactive(avalue) then begin + inherited active:= avalue; + end; +end; + +procedure tmsesqltransaction.setcontroller(const avalue: ttacontroller); +begin + fcontroller.assign(avalue); +end; + +procedure tmsesqltransaction.loaded; +begin + inherited; + fcontroller.loaded; +end; + +{ tmsesqlquery } + +constructor tmsesqlquery.create(aowner: tcomponent); +begin + inherited; +// updatemode:= upwhereall; + fsqlonchangebefore:= sql.onchange; + sql.onchange:= {$ifdef FPC}@{$endif}sqlonchange; + fcontroller:= tsqldscontroller.create(self); +end; + +destructor tmsesqlquery.destroy; +begin + fcontroller.free; + inherited; +end; + +function tmsesqlquery.getindexdefs: TIndexDefs; +begin + result:= inherited indexdefs; +end; + +procedure tmsesqlquery.setindexdefs(const avalue: TIndexDefs); +begin + inherited indexdefs.assign(avalue); +end; + +procedure tmsesqlquery.updateindexdefs; +begin + indexdefs.clear; + inherited; +end; + +procedure tmsesqlquery.appendrecord(const values: array of const); +begin + fcontroller.appendrecord(values); +end; + +procedure tmsesqlquery.appendrecord(const values: array of const; + const aisnull: array of boolean); +begin + fcontroller.appendrecord1(values,aisnull); +end; + +procedure tmsesqlquery.sqlonchange(const sender: tobject); +begin + if (csdesigning in componentstate) and active then begin + active:= false; + fsqlonchangebefore(sender); + active:= true; + end + else begin + fsqlonchangebefore(sender); + end; +end; + +procedure tmsesqlquery.setcontroller(const avalue: tdscontroller); +begin + fcontroller.assign(avalue); +end; + +procedure tmsesqlquery.setactive1(value: boolean); +begin + if fcontroller.setactive(value) then begin + setactive(value); + end; +end; + +procedure tmsesqlquery.loaded; +begin + inherited; + fcontroller.loaded; +end; + +function tmsesqlquery.getactive: boolean; +begin + result:= inherited active; +end; + +procedure tmsesqlquery.inheritedinternalopen; +begin + if bdo_local in foptions then begin + openlocal(); + end + else begin + inherited internalopen; + end; +end; + +procedure tmsesqlquery.internalopen; +var + intf1: idbcontroller; + bo1: boolean; +begin + if dso_initinternalcalc in fcontroller.options then begin + include(fbstate,bs_initinternalcalc); + end + else begin + exclude(fbstate,bs_initinternalcalc); + end; + if (database <> nil) and + getcorbainterface(database,typeinfo(idbcontroller),intf1) then begin + bo1:= dso_utf8 in fcontroller.options; + intf1.updateutf8(bo1); + if bo1 then begin + fcontroller.options:= fcontroller.options + [dso_utf8]; + end + else begin + fcontroller.options:= fcontroller.options - [dso_utf8]; + end; + end; + fcontroller.internalopen; + if not streamloading and not (bdo_local in foptions) then begin + connected:= not (bdo_offline in foptions); + end; +end; + +procedure tmsesqlquery.setonapplyrecupdate(const avalue: applyrecupdateeventty); +begin + if not (csloading in componentstate) then begin + checkinactive; + end; + if assigned(avalue) and not (csdesigning in componentstate) then begin + include(fmstate,sqs_userapplyrecupdate); + end + else begin + if not assigned(fonapplyrecupdate2) then begin + exclude(fmstate,sqs_userapplyrecupdate); + end; + end; + fonapplyrecupdate:= avalue; +end; + +procedure tmsesqlquery.setonapplyrecupdate2( + const avalue: afterapplyrecupdateeventty); +begin + if not (csloading in componentstate) then begin + checkinactive; + end; + if assigned(avalue) and not (csdesigning in componentstate) then begin + include(fmstate,sqs_userapplyrecupdate); + end + else begin + if not assigned(fonapplyrecupdate) then begin + exclude(fmstate,sqs_userapplyrecupdate); + end; + end; + fonapplyrecupdate2:= avalue; +end; + +function tmsesqlquery.getcanmodify: Boolean; +begin + result:= fcontroller.getcanmodify and + (inherited getcanmodify or not readonly and + (sqs_userapplyrecupdate in fmstate)); +end; + +procedure tmsesqlquery.applyrecupdate(updatekind: tupdatekind); +var + bo1: boolean; + str1: msestring; +begin + try + if sqs_userapplyrecupdate in fmstate then begin + if assigned(fonapplyrecupdate) then begin + bo1:= false; + fonapplyrecupdate(self,updatekind,str1,bo1); + if not bo1 then begin + if str1 = '' then begin + inherited; + end + else begin + {$ifdef debugsqlquery} + debugwriteln(getenumname(typeinfo(tupdatekind),ord(updatekind))+' '+str1); + {$endif} + tsqlconnection(database).executedirect(str1,writetransaction); + end; + end; + end + else begin + inherited; + end; + if assigned(fonapplyrecupdate2) then begin + fonapplyrecupdate2(self,updatekind); + end; + end + else begin + internalapplyrecupdate(updatekind); + end; + if checkcanevent(self,tmethod(fafterapplyrecupdate)) then begin + fafterapplyrecupdate(self,updatekind); + end; + except + include(fmstate,sqs_updateerror); + if bdo_rollbackonupdateerror in foptions then begin + if writetransaction <> nil then begin + writetransaction.rollback(); + end; + end; + raise; + end; +end; + +procedure tmsesqlquery.afterpost(const sender: tdataset; var ok: boolean); +begin + if (bdo_autoapply in foptions) and + not(bs_noautoapply in fbstate) then begin + if bdo_autoapplyexceptions in foptions then begin + applyupdate(); + end + else begin + try + applyupdate; + except + ok:= false; + application.handleexception(self); + end; + end; + end; +end; + +function tmsesqlquery.post1(): boolean; +begin + result:= fcontroller.post(@afterpost); +end; + +procedure tmsesqlquery.post; +begin + post1(); +end; + +function tmsesqlquery.delete1(): boolean; +begin + result:= fcontroller.delete(); +end; + +procedure tmsesqlquery.delete; +begin + delete1(); +end; + +{ +procedure tmsesqlquery.insert; +begin + fcontroller.insert(); +end; +} +procedure tmsesqlquery.afterapply; +begin + if writetransaction <> nil then begin //can be nil in local mode + if (ftransopenref = writetransaction.opencount) then begin + if (writetransaction.savepointlevel < 0) then begin + if bdo_autocommitret in foptions then begin + writetransaction.commitretaining; + end; + if bdo_autocommit in foptions then begin + writetransaction.commit; + end; + end + else begin + if bdo_autocommitret in foptions then begin + writetransaction.pendingaction:= cacommitretaining; + end; + if bdo_autocommit in foptions then begin + writetransaction.pendingaction:= cacommit; + end; + end; + end; + end; + if bdo_refreshafterapply in foptions then begin + fcontroller.refresh(bdo_recnoapplyrefresh in foptions); + end; +end; + +procedure tmsesqlquery.dobeforeapplyupdate; +begin + inherited; + if writetransaction <> nil then begin + with writetransaction do begin + ftransopenref:= opencount; + end; + end; +end; + +procedure tmsesqlquery.checkcanupdate; +begin + if not islocal and (transactionwrite = nil) then begin + checkconnected; + end; +end; + +function tmsesqlquery.getdefaultoptions(): bufdatasetoptionsty; +begin + result:= defaultsqlbdsoptions; +end; + +procedure tmsesqlquery.applyupdates(const maxerrors: integer; + const cancelonerror: boolean; + const cancelondeleteerror: boolean = false; + const editonerror: boolean = false); +begin + checkcanupdate; + try + fmstate:= fmstate - [sqs_updateabort,sqs_updateerror]; + inherited; + finally + if (sqs_updateerror in fmstate) and + (bdo_cancelupdatesonerror in foptions) then begin + cancelupdates; + end; + end; +end; + +procedure tmsesqlquery.doidleapplyupdates; +var + bo1: boolean; +begin + if not (bs_idle in fbstate) and (changecount > 0) and + (changecount >= delayedapplycount) then begin + application.beginwait; + include(fbstate,bs_idle); + bo1:= false; + try + applyupdates; + except + bo1:= true; + application.endwait; + application.handleexception(self); + end; + exclude(fbstate,bs_idle); + if not bo1 then begin + application.endwait; + end; + end; +end; + +procedure tmsesqlquery.checkpendingupdates; +begin + if (state <> dsinactive) and (delayedapplycount > 0) and + (changecount > 0) then begin +// (dso_applyonidle in fcontroller.options) and (changecount > 0) then begin + applyupdates; + end; +end; + +procedure tmsesqlquery.setactive(avalue: boolean); +begin + if not avalue then begin + checkpendingupdates; + end; + inherited; +end; + +procedure tmsesqlquery.applyupdates(const maxerrors: integer = 0); +begin + applyupdates(maxerrors,foptions * + [bdo_cancelupdateonerror,bdo_cancelupdatesonerror] <> [], + bdo_cancelupdateondeleteerror in foptions, + bdo_editonapplyerror in foptions); +end; + +procedure tmsesqlquery.applyupdate; +begin + checkcanupdate; + inherited applyupdate(foptions * + [bdo_cancelupdateonerror,bdo_cancelupdatesonerror] <> [], + bdo_cancelupdateondeleteerror in foptions, + bdo_editonapplyerror in foptions); +end; + +function tmsesqlquery.getfieldclass(fieldtype: tfieldtype): tfieldclass; +begin + fcontroller.getfieldclass(fieldtype,result); +end; + +procedure tmsesqlquery.cancel; +begin + fcontroller.cancel; +end; + +procedure tmsesqlquery.dataevent(event: tdataevent; info: ptrint); +begin + fcontroller.dataevent(event,info); +end; + +function tmsesqlquery.getcontroller: tdscontroller; +begin + result:= fcontroller; +end; + +procedure tmsesqlquery.inheriteddataevent(const event: tdataevent; + const info: ptrint); +begin + inherited dataevent(event,info); +end; + +procedure tmsesqlquery.inheritedcancel; +begin + inherited cancel; +end; + +function tmsesqlquery.inheritedmoveby(const distance: integer): integer; +begin + result:= inherited moveby(distance); +end; + +function tmsesqlquery.moveby(const distance: integer): integer; +begin + result:= fcontroller.moveby(distance); +end; + +procedure tmsesqlquery.internalinsert; +begin + fcontroller.internalinsert; +end; + +procedure tmsesqlquery.inheritedinternalinsert; +begin + inherited internalinsert; +end; + +procedure tmsesqlquery.internaldelete; +begin + fcontroller.internaldelete; +end; + +procedure tmsesqlquery.inheritedinternaldelete; +begin + inherited internaldelete; +end; + +procedure tmsesqlquery.DoAfterDelete; +begin + inherited; + if (bdo_autoapply in foptions) and + not(bs_noautoapply in fbstate) then begin + applyupdates; + end; +end; +{ +function tmsesqlquery.getetstatementtype: TStatementType; +begin + result:= inherited statementtype; +end; + +procedure tmsesqlquery.setstatementtype(const avalue: TStatementType); +begin + //dummy +end; +} +procedure tmsesqlquery.inheritedpost; +begin + inherited post; +end; + +function tmsesqlquery.isutf8: boolean; +begin + result:= fcontroller.isutf8; +end; +{ +function tmsesqlquery.getdsoptions: datasetoptionsty; +begin + result:= fcontroller.options; +end; +} +{ +function tmsesqlquery.wantblobfetch: boolean; +begin + result:= (dso_cacheblobs in fcontroller.options); +end; + +function tmsesqlquery.closetransactiononrefresh: boolean; +begin + result:= (dso_refreshtransaction in fcontroller.options); +end; +} +{ +function tmsesqlquery.refreshtransdatasets: boolean; +begin + result:= (dso_refreshtransdatasets in fcontroller.options); +end; +} + +function tmsesqlquery.islocal: boolean; +begin + result:= (bdo_local in foptions) and not connected; +end; + +procedure tmsesqlquery.inheritedinternalclose; +begin + inherited internalclose; +end; + +procedure tmsesqlquery.internalclose; +begin + fcontroller.internalclose; +end; + +function tmsesqlquery.stringmemo: boolean; +begin + result:= dso_stringmemo in fcontroller.options; +end; + +procedure tmsesqlquery.setcontrolleractive(const avalue: boolean); +begin + setactive(avalue); +end; + +procedure tmsesqlquery.inheriteddelete(); +begin + inherited delete(); +end; + +procedure tmsesqlquery.inheritedinsert(); +begin + inherited insert(); +end; + +{ +procedure tmsesqlquery.dscontrolleroptionschanged(const aoptions: datasetoptionsty); +begin + //dummy +end; +} +{ +function tmsesqlquery.cantransactionrefresh: boolean; +begin + result:= not (dso_notransactionrefresh in fcontroller.options); +end; +} +{ tparamsourcedatalink } + +constructor tparamsourcedatalink.create(const aowner: tfieldparamlink); +begin + fownerlink:= aowner; + inherited create; +end; + +procedure tparamsourcedatalink.recordchanged(afield: tfield); +var + bo1,bo2: boolean; + int1: integer; + var1: variant; +begin + if not (csloading in fownerlink.componentstate) then begin + inherited; +// if frefreshlock = 0 then begin + if not (fplo_disabled in fownerlink.foptions) then begin + if active and (field <> nil) and + ((afield = nil) or (afield = self.field)) then begin + if fchangelock <> 0 then begin + databaseerror('Recursive recordchanged.',fownerlink); + end; + inc(fchangelock); + try + with fownerlink do begin + if not (csdesigning in componentstate) then begin + fparamset:= true; + bo1:= false; + bo2:= not (fplo_refreshifchangedonly in foptions) or + (fdestdataset = nil) or not fdestdataset.active; + if not bo2 then begin + var1:= param.value; + end; + if assigned(fonsetparam) then begin + fonsetparam(fownerlink,bo1); + end; + if not bo1 and (dataset <> nil) then begin + if fparamname <> '' then begin + fieldtoparam(self.field,param); + end; + with fdestparams do begin + for int1:= 0 to high(fitems) do begin + with tdestparam(fitems[int1]) do begin + if (fdatalink.field <> nil) and (fparamname <> '') then begin + fieldtoparam(fdatalink.field,param(fparamname)); + end; + end; + end; + end; + end; + if assigned(fonaftersetparam) then begin + fonaftersetparam(fownerlink); + end; + bo2:= bo2 or (var1 <> param.value); + if (frefreshlock = 0) and bo2 then begin + if (fplo_autorefresh in foptions) and + (destdataset <> nil) and + (fdestdataset.active or + not (fplo_refreshifactiveonly in foptions)) and + not((fdestdataset.state = dsinsert) and + (dataset.state = dsinsert) and + (fplo_syncmasterinsert in foptions)) and + not ((fplo_delayedsyncmasterpost in foptions) and + (self.fdscontroller <> nil) and + self.fdscontroller.posting1) then begin + if fdestdataset.active then begin + if fplo_checkbrowsemodeonrefresh in foptions then begin + fdestdataset.checkbrowsemode; + end + else begin + fdestdataset.cancel; + end; + if fdestcontroller <> nil then begin + fdestcontroller.refresh(fplo_restorerecno in foptions,truedelayus); + end + else begin + fdestdataset.refresh; + end; + end + else begin + fdestdataset.active:= true; + end; + end; + if assigned(fonrefresh) then begin + fonrefresh(fownerlink); + end; + end; + end; + end; + finally + dec(fchangelock); + end; + end; + end; + end; +end; + +procedure tparamsourcedatalink.loaded; +begin + if not fparamset then begin + recordchanged(nil); + end; +end; + +procedure tparamsourcedatalink.DataEvent(Event: TDataEvent; Info: Ptrint); +var + b1: boolean; +begin + inherited; + with fownerlink do begin + if not (fplo_disabled in foptions) then begin + b1:= (destdataset <> nil) and destdataset.active; + inc(frefreshlock); + try + case ord(event) of + ord(deupdatestate): begin + if b1 then begin + if (fplo_syncmasteredit in foptions) and (dataset.state = dsedit) and + not (fownerlink.destdataset.state = dsedit) then begin + destdataset.edit; + end; + if (fplo_syncmasterinsert in foptions) and(dataset.state = dsinsert) and + not (destdataset.state = dsinsert) then begin + destdataset.insert(); + end; + end; + end; + de_afterdelete: begin + if b1 and (fplo_syncmasterdelete in foptions) and + not destdataset.isempty then begin + destdataset.delete(); + end; + if assigned(fonmasterdelete) then begin + fonmasterdelete(destdataset,dataset); + end; + end; + de_afterpost: begin + if b1 and (fplo_delayedsyncmasterpost in foptions) and + (destdataset.state in [dsinsert,dsedit]) then begin + destdataset.post(); + end; + if assigned(fonmasterpost) then begin + fonmasterpost(destdataset,dataset); + end; + end; + de_afterapplyupdate: begin + if b1 and (fplo_syncmasterapplyupdates in foptions) then begin + destdataset.applyupdates(); + end; + if assigned(fonmasterapplyupdate) then begin + fonmasterapplyupdate(destdataset,dataset); + end; + end; + end; + finally + dec(frefreshlock); + end; + end; + end; +end; + +procedure tparamsourcedatalink.CheckBrowseMode; +label + endlab; +var + intf: igetdscontroller; + posted1: boolean; +begin + with fownerlink do begin + if not (fplo_disabled in foptions) and + (destdataset <> nil) and destdataset.active then begin + inc(frefreshlock); + try + posted1:= false; + if foptions * [fplo_syncmasteredit,fplo_syncmasterinsert, + fplo_syncmastercancel] <> [] then begin + if mseclasses.getcorbainterface(dataset, + typeinfo(igetdscontroller),intf) and + intf.getcontroller.canceling then begin + destdataset.cancel; + if fplo_syncmastercancelupdates in foptions then begin + destdataset.cancelupdates(); + end; + exit; + end + else begin + if (destdataset.state = dsinsert) and + (fplo_syncmasterpost in foptions) and + (dataset.state in [dsedit,dsinsert]) then begin + if fplo_delayedsyncmasterpost in foptions then begin + exit; + end; + dataset.updaterecord; + if dataset.modified then begin + posted1:= true; + destdataset.post; + goto endlab; + end; + end; + end; + end; + if (fplo_syncmasterpost in foptions) then begin + if fplo_delayedsyncmasterpost in foptions then begin + exit; + end; + posted1:= true; + destdataset.post; +// destdataset.checkbrowsemode; + end + else begin + if (fplo_syncmastercheckbrowsemode in foptions) and + (fcheckbrowsemodelock = 0) then begin + destdataset.checkbrowsemode(); + end; + end; + inherited; + endlab: + if (dataset.state in [dsedit,dsinsert]) and + (foptions * [fplo_syncmasteredit,fplo_syncmasterinsert] <> []) and + posted1 then begin + dataset.updaterecord; //synchronize fields + end; + if (dataset.state = dsinsert) and assigned(onupdatemasterinsert) then begin + onupdatemasterinsert(destdataset,dataset); + end; + if (dataset.state = dsedit) and assigned(onupdatemasteredit) then begin + onupdatemasteredit(destdataset,dataset); + end; + finally + dec(frefreshlock); + end; + end + else begin + inherited; + end; + end; +end; + +{ tparamdestdatalink } + +constructor tparamdestdatalink.create(const aowner: tfieldparamlink); +begin + fownerlink:= aowner; + inherited create; +end; + +function tparamdestdatalink.cansync(out sourceds: tdataset): boolean; +begin + with fownerlink.fsourcedatalink do begin + result:= false; + sourceds:= dataset; + if sourceds <> nil then begin + result:= sourceds.active; + end; + end; +end; + +procedure tparamdestdatalink.DataEvent(Event: TDataEvent; Info: Ptrint); +var + sourceds: tdataset; + b1: boolean; +begin + inherited; + with fownerlink do begin + if not (fplo_disabled in foptions) then begin + b1:= cansync(sourceds); + case ord(event) of + ord(deupdatestate): begin + if b1 then begin + if (fplo_syncslaveedit in foptions) and (dataset.state = dsedit) and + not (sourceds.state = dsedit) then begin + sourceds.edit; + end; + if ([fplo_syncslaveinsert,fplo_syncslaveinserttoedit] * foptions <> + []) and (dataset.state = dsinsert) then begin + inc(fcheckbrowsemodelock); + try + if (fplo_syncslaveinsert in foptions) and + (sourceds.state <> dsinsert) then begin + sourceds.insert(); + end + else begin + if (fplo_syncslaveinserttoedit in foptions) and + (sourceds.state <> dsedit) then begin + sourceds.edit(); + end; + end; + finally + dec(fcheckbrowsemodelock); + end; + end; + end; + end; + de_afterdelete: begin + if b1 then begin + if (fplo_syncslavedelete in foptions) and + not sourceds.isempty then begin + sourceds.delete; + end; + if fplo_syncslavedeletetoedit in foptions then begin + sourceds.edit(); + end; + end; + if assigned(fonslavedelete) then begin + fonslavedelete(destdataset,dataset); + end; + end; + de_afterpost: begin + if b1 and (fplo_delayedsyncslavepost in foptions) and + (sourceds.state in [dsinsert,dsedit]) then begin + sourceds.checkbrowsemode(); + end; + if assigned(fonslavepost) then begin + fonslavepost(destdataset,dataset); + end; + end; + end; + end; + end; +end; + +procedure tparamdestdatalink.CheckBrowseMode; +label + endlab; +var + intf: igetdscontroller; + sourceds: tdataset; + canceling: boolean; +begin + with fownerlink do begin + if not (fplo_disabled in foptions) and + cansync(sourceds) then begin + inc(fsourcedatalink.frefreshlock); + try + canceling:= mseclasses.getcorbainterface( + dataset,typeinfo(igetdscontroller),intf) and + intf.getcontroller.canceling; + if fplo_syncslavecancel in foptions then begin + if canceling then begin + if fsourcedatalink.frefreshlock = 1 then begin + sourceds.cancel; + end; + exit; + end + else begin + if (sourceds.state = dsinsert) and (dataset.state <> dsbrowse) and + (fplo_syncslavepost in foptions) then begin + dataset.updaterecord; + if dataset.modified then begin + destdataset.post; + updatedata; + goto endlab; + end; + end; + end; + end; + if (fplo_syncslavepost in foptions) and + (dataset.state <> dsbrowse) and not canceling then begin + if fplo_delayedsyncslavepost in foptions then begin + exit; + end; + sourceds.post; + updatedata; + end; + inherited; + endlab: + if (dataset.state in [dsedit,dsinsert]) and not canceling and + (foptions * [fplo_syncslaveedit,fplo_syncslaveinsert] <> []) then begin + dataset.updaterecord; //synchronize fields + end; + if (dataset.state = dsinsert) and assigned(onupdateslaveinsert) then begin + onupdateslaveinsert(destdataset,dataset); + end; + if (dataset.state = dsedit) and assigned(onupdateslaveedit) then begin + onupdateslaveedit(destdataset,dataset); + end; + finally + dec(fsourcedatalink.frefreshlock); + end; + end + else begin + inherited; + end; + end; +end; + +procedure tparamdestdatalink.updatedata(); +var + int1: integer; + field1: tfield; +begin + with fownerlink do begin + if not (fplo_disabled in foptions) then begin + with fdestfields do begin + for int1:= 0 to high(fitems) do begin + with tdestfield(fitems[int1]) do begin + if (fdatalink.field <> nil) and (fdestfieldname <> '') then begin + field1:= field(fdestfieldname); + if (not (dfo_onlyifnull in foptions) or (field1.isnull)) and + (not (dfo_notifunmodifiedinsert in foptions) or + dataset.modified) then begin + field1.value:= fdatalink.field.value; + end; + end; + end; + end; + end; + end; + end; +end; + +{ tfieldparamlink } + +constructor tfieldparamlink.create(aowner: tcomponent); +begin + fdelayus:= -1; + foptions:= defaultfieldparamlinkoptions; + fsourcedatalink:= tparamsourcedatalink.create(self); + fdestdatasource:= tdatasource.create(nil); + fdestdatalink:= tparamdestdatalink.create(self); + fdestdatalink.datasource:= fdestdatasource; + fdestparams:= tdestparams.create(self); + fdestfields:= tdestfields.create(self); +// fdestdatasource:= tlinkdatasource.create(nil); + inherited; +end; + +destructor tfieldparamlink.destroy; +begin +// freeandnil(ftimer); + inherited; + fsourcedatalink.free; + fdestdatalink.free; + fdestdatasource.free; + fdestparams.free; + fdestfields.free; +// fdestdatasource.free; +end; +{ +procedure tfieldparamlink.dotimer(const sender: tobject); +begin + fsourcedatalink.checkrefresh; +end; +} +function tfieldparamlink.getfieldname: string; +begin + result:= fsourcedatalink.fieldname; +end; + +procedure tfieldparamlink.setfieldname(const avalue: string); +begin + fsourcedatalink.fieldname:= avalue; +end; + +function tfieldparamlink.getdatasource: tdatasource; +begin + result:= fsourcedatalink.datasource; +end; + +procedure tfieldparamlink.setdatasource(const avalue: tdatasource); +begin + fsourcedatalink.datasource:= avalue; +end; + +function tfieldparamlink.getvisualcontrol: boolean; +begin + result:= fsourcedatalink.visualcontrol; +end; + +procedure tfieldparamlink.setvisualcontrol(const avalue: boolean); +begin + fsourcedatalink.visualcontrol:= avalue; +end; + +function tfieldparamlink.getdestdataset: tsqlquery; +begin + result:= fdestdataset; +end; + +procedure tfieldparamlink.setdestdataset(const avalue: tsqlquery); +var + intf: igetdscontroller; +begin + fdestdatasource.dataset:= avalue; + if fdestdataset <> nil then begin + fdestdataset.removefreenotification(self); + end; + fdestdataset:= avalue; + fdestcontroller:= nil; + if avalue <> nil then begin + avalue.freenotification(self); + if mseclasses.getcorbainterface(avalue, + typeinfo(igetdscontroller),intf) then begin + fdestcontroller:= intf.getcontroller; + end; + end; +end; + +procedure tfieldparamlink.notification(acomponent: tcomponent; + operation: toperation); +begin + if (operation = opremove) and (acomponent = fdestdataset) then begin + fdestdataset:= nil; + end; + inherited; +end; + +function tfieldparamlink.param(const aname: string): tparam; +begin + result:= nil; + if fdestdataset = nil then begin + databaseerror(name+': No destdataset'); + end + else begin + result:= fdestdataset.params.findparam(aname); + if result = nil then begin + databaseerror(name+': param "'+aname+'" not found'); + end; + end; +end; + +function tfieldparamlink.field(const aname: string): tfield; +begin + result:= nil; + if fdestdataset = nil then begin + databaseerror(name+': No destdataset'); + end + else begin + result:= fdestdataset.fieldbyname(aname); + if result = nil then begin + databaseerror(name+': field "'+aname+'" not found'); + end; + end; +end; + +function tfieldparamlink.param: tparam; +begin + result:= param(fparamname); +end; + +function tfieldparamlink.field: tfield; +begin + result:= fsourcedatalink.field; +end; + +procedure tfieldparamlink.getfieldtypes(out propertynames: stringarty; + out fieldtypes: fieldtypesarty); +begin + propertynames:= nil; + fieldtypes:= nil; +end; + +procedure tfieldparamlink.loaded; +begin + inherited; + fsourcedatalink.loaded; +end; + +function tfieldparamlink.getdataset(const aindex: integer): tdataset; +begin + result:= fsourcedatalink.dataset; +end; + +procedure tfieldparamlink.setdelayus(const avalue: integer); +begin + fdelayus:= avalue; + if fdelayus < 0 then begin + fdelayus:= -1; + checkrefresh; + end; +end; + +function tfieldparamlink.truedelayus: integer; +begin + result:= fdelayus; + if fnodelay > 0 then begin + result:= -1; + end; +end; + +procedure tfieldparamlink.checkrefresh; +begin + if fdestcontroller <> nil then begin + fdestcontroller.checkrefresh; + end; +end; + +procedure tfieldparamlink.delayoff; +begin + inc(fnodelay); + if fnodelay = 1 then begin + checkrefresh; + end; +end; + +procedure tfieldparamlink.delayon; +begin + dec(fnodelay); +end; + +procedure tfieldparamlink.setdestparams(const avalue: tdestparams); +begin + fdestparams.assign(avalue); +end; + +procedure tfieldparamlink.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('datafield',{$ifdef FPC}@{$endif}readdatafield,nil,false); +end; + +procedure tfieldparamlink.readdatafield(reader: treader); +begin + fieldname:= reader.readstring; +end; + +procedure tfieldparamlink.setdestfields(const avalue: tdestfields); +begin + fdestfields.assign(avalue); +end; + +procedure tfieldparamlink.setoptions(const avalue: fieldparamlinkoptionsty); +begin + foptions:= fieldparamlinkoptionsty(setsinglebit(card32(avalue), + card32(foptions), + [card32([fplo_syncslaveinsert,fplo_syncslaveinserttoedit]), + card32([fplo_syncslavedelete,fplo_syncslavedeletetoedit])])); + if fplo_syncmastercancelupdates in avalue then begin + foptions:= foptions + [fplo_syncmastercancel]; + end; + if not (fplo_syncmastercancel in avalue) then begin + foptions:= foptions - [fplo_syncmastercancelupdates]; + end; +end; + +function tfieldparamlink.getenabled: boolean; +begin + result:= not (fplo_disabled in foptions); +end; + +procedure tfieldparamlink.setenabled(const avalue: boolean); +begin + if avalue then begin + exclude(foptions,fplo_disabled); + end + else begin + include(foptions,fplo_disabled); + end; +end; + +{ tsequencedatalink } + +constructor tsequencedatalink.create(const aowner: tsequencelink); +begin + fownerlink:= aowner; + inherited create; +end; + +procedure tsequencedatalink.updatedata; +begin + inherited; + if (field <> nil) and field.isnull and (dataset <> nil) and + ((dataset.modified) or + (fdscontroller <> nil) and fdscontroller.posting) then begin + if field.datatype in [ftlargeint,ftfloat,ftcurrency,ftbcd] then begin + field.aslargeint:= fownerlink.aslargeint; + end + else begin + field.asinteger:= fownerlink.asinteger; + end; + end; +end; + +{ tsequencelink } + +constructor tsequencelink.create(aowner: tcomponent); +begin + fdatalink:= tsequencedatalink.create(self); + inherited; +end; + +destructor tsequencelink.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tsequencelink.setdatabase(const avalue: tsqlconnection); +begin + if fdatabase <> avalue then begin + fdbintf:= nil; + if fdatabase <> nil then begin + fdatabase.removefreenotification(self); + end; + if avalue <> nil then begin + avalue.freenotification(self); + mseclasses.getcorbainterface(avalue,typeinfo(idbcontroller),fdbintf); + end; + fdatabase:= avalue; + end; +end; + +procedure tsequencelink.setsequencename(const avalue: string); +begin + fsequencename:= avalue; +end; + +procedure tsequencelink.notification(acomponent: tcomponent; + operation: toperation); +begin + inherited; + if (acomponent = fdatabase) and (operation = opremove) then begin + fdatabase:= nil; + end; +end; + +procedure tsequencelink.checkintf; +begin + if fdbintf = nil then begin + raise edatabaseerror.create(name+': Database has no idscontroller interface.'); + end; + if fsequencename = '' then begin + raise edatabaseerror.create(name+': No sequencename.'); + end; +end; + +function tsequencelink.getaslargeint: largeint; +begin + checkintf; + flastvalue:= getsqlresultvar(fdatabase.transaction, + fdbintf.readsequence(fsequencename),[]); + if canevent(tmethod(fonupdatevalue)) then begin + fonupdatevalue(self,flastvalue); + end; + result:= flastvalue; +end; +{ +function tsequencelink.getaslargeint: largeint; +var //todo: optimize + ds1: tsqlquery; +begin + checkintf; + ds1:= tsqlquery.create(nil); + try + ds1.parsesql:= false; + ds1.sql.add(fdbintf.readsequence(fsequencename)); + ds1.database:= fdatabase; + ds1.active:= true; + flastvalue:= ds1.fields[0].aslargeint; + finally + ds1.free; + end; + if canevent(tmethod(fonupdatevalue)) then begin + fonupdatevalue(self,flastvalue); + end; + result:= flastvalue; +end; +} +function tsequencelink.currvalue: largeint; +begin + checkintf; + result:= getsqlresultvar(fdatabase.transaction, + fdbintf.sequencecurrvalue(fsequencename),[]); +end; + +procedure tsequencelink.setaslargeint(const avalue: largeint); +begin + checkintf; + fdbintf.executedirect( + fdbintf.writesequence(fsequencename,avalue),false); +end; + +function tsequencelink.getasinteger: integer; +begin + result:= getaslargeint; +end; + +procedure tsequencelink.setasinteger(const avalue: integer); +begin + setaslargeint(avalue); +end; + +function tsequencelink.getdatasource: tdatasource; +begin + result:= fdatalink.datasource; +end; + +procedure tsequencelink.setdatasource(const avalue: tdatasource); +begin + fdatalink.datasource:= avalue; + if (csdesigning in componentstate) and (fdatabase = nil) and + (fdatalink.dataset is tsqlquery) then begin + database:= tsqlconnection(tsqlquery(fdatalink.dataset).database); + end; +end; + +function tsequencelink.getdatafield: string; +begin + result:= fdatalink.fieldname; +end; + +procedure tsequencelink.setdatafield(const avalue: string); +begin + fdatalink.fieldname:= avalue; +end; + +procedure tsequencelink.getfieldtypes(out propertynames: stringarty; + out fieldtypes: fieldtypesarty); +begin + propertynames:= nil; + setlength(fieldtypes,1); + fieldtypes[0]:= integerfields; +end; + +function tsequencelink.assql: string; +begin + result:= inttostr(aslargeint); +end; + +function tsequencelink.getdataset(const aindex: integer): tdataset; +begin + result:= fdatalink.dataset; +end; + + +{ tsqldscontroller } + +function tsqldscontroller.savepointbegin: integer; +begin + result:= 0; + with tmsesqlquery(fowner) do begin + if writetransaction <> nil then begin + result:= writetransaction.savepointbegin; + end; + end; +end; + +procedure tsqldscontroller.savepointrollback(const alevel: integer = -1); +begin + with tmsesqlquery(fowner) do begin + if (writetransaction <> nil) and writetransaction.active then begin + writetransaction.savepointrollback(alevel); + end; + end; +end; + +procedure tsqldscontroller.savepointrelease; +begin + with tmsesqlquery(fowner) do begin + if (writetransaction <> nil) and writetransaction.active then begin + writetransaction.savepointrelease; + end; + end; +end; + +constructor tsqldscontroller.create(const aowner: tmsesqlquery); +begin + inherited create(aowner,idscontroller(aowner),-1,false); + foptions:= defaultsqlcontrolleroptions; +end; + +{ tdestparams } + +constructor tdestparams.create(const aowner: tfieldparamlink); +begin + inherited create(aowner,tdestparam); +end; + +class function tdestparams.getitemclasstype: persistentclassty; +begin + result:= tdestparam; +end; + +{ tdestfields } + +constructor tdestfields.create(const aowner: tfieldparamlink); +begin + inherited create(aowner,tdestfield); +end; + +class function tdestfields.getitemclasstype: persistentclassty; +begin + result:= tdestfield; +end; + +{ tdestvalue } + +constructor tdestvalue.create(aowner: tobject); +begin + inherited; + fdatalink:= tfielddatalink.create; +end; + +destructor tdestvalue.destroy; +begin + fdatalink.free; +end; + +function tdestvalue.getdatasource: tdatasource; +begin + result:= fdatalink.datasource; +end; + +procedure tdestvalue.setdatasource(const avalue: tdatasource); +begin + fdatalink.datasource:= avalue; +end; + +function tdestvalue.getfieldname: string; +begin + result:= fdatalink.fieldname; +end; + +procedure tdestvalue.setfieldname(const avalue: string); +begin + fdatalink.fieldname:= avalue; +end; + +function tdestvalue.getdataset(const aindex: integer): tdataset; +begin + result:= fdatalink.dataset; +end; + +procedure tdestvalue.getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); +begin + apropertynames:= nil; + afieldtypes:= nil; +end; + +function tdestvalue.getdestdataset: tsqlquery; +begin + result:= tfieldparamlink(fowner).destdataset; +end; + +{ tdestfield } + +function tdestfield.getdataset(const aindex: integer): tdataset; +begin + result:= nil; + case aindex of + 0: result:= fdatalink.dataset; + 1: result:= tfieldparamlink(fowner).fdestdataset; + end; +end; + +procedure tdestfield.getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); +begin + setlength(apropertynames,2); + apropertynames[0]:= 'filedname'; + apropertynames[1]:= 'destfieldname'; + afieldtypes:= nil; +end; + +end. diff --git a/mseide-msegui/lib/common/db/msesqlite3conn.pas b/mseide-msegui/lib/common/db/msesqlite3conn.pas new file mode 100644 index 0000000..f0a5413 --- /dev/null +++ b/mseide-msegui/lib/common/db/msesqlite3conn.pas @@ -0,0 +1,1160 @@ +{ MSEgui Copyright (c) 2007-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msesqlite3conn; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + classes,mclasses,msedb,msqldb,msestrings,mdb,sqlite3dyn,msetypes,msedatabase; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{ + Type name SQLite storage class Field type Data type ++--------------------+---------------------+-------------+-------------+ +| INTEGER or INT | INTEGER 4 | ftinteger | integer | +| LARGEINT | INTEGER 8 | ftlargeint | largeint | +| BIGINT | INTEGER 8 | ftlargeint | largeint | +| WORD | INTEGER 2 | ftword | word | +| SMALLINT | INTEGER 2 | ftsmallint | smallint | +| BOOLEAN | INTEGER 2 | ftboolean | wordbool | +| FLOAT[...] or REAL | REAL | ftfloat | double | +| or DOUBLE[...] | | | | +| CURRENCY | REAL | ftcurrency | double! | +| DATETIME or | REAL | ftdatetime | tdatetime | +| TIMESTAMP | | | | +| DATE | REAL | ftdate | tdatetime | +| TIME | REAL | fttime | tdatetime | +| NUMERIC[...] | INTEGER 8 (*10'000) | ftbcd | currency | +| VARCHAR[(n)] | TEXT | ftstring | msestring | +| TEXT | TEXT | ftmemo | utf8 string | +| TEXT | TEXT dso_stringmemo | ftstring | msestring | +| BLOB | BLOB | ftblob | string | ++--------------------+---------------------+-------------+-------------+ +} +type + esqlite3error = class(econnectionerror) + end; + + tsqlitetrans = class(TSQLHandle) + protected + fparams: ansistring; + end; + + sqliteoptionty = (slo_transactions,slo_designtransactions, + slo_negboolean, //boolean true = -1 instead of 1 + slo_64bitprimarykey); + //use ftlargint for "integer" primarykeyfield + sqliteoptionsty = set of sqliteoptionty; + + tsqlite3connection = class(tcustomsqlconnection,idbcontroller,iblobconnection) + private + fhandle: psqlite3; + foptions: sqliteoptionsty; + fbusytimeoutms: integer; + flasterror: integer; + flasterrormessage: msestring; + function getdatabasename: filenamety; + procedure setdatabasename(const avalue: filenamety); + procedure setcontroller(const avalue: tdbcontroller); + function getconnected: boolean; reintroduce; + procedure setconnected(const avalue: boolean); reintroduce; + + //iblobconnection + procedure writeblobdata(const atransaction: tsqltransaction; + const tablename: string; const acursor: tsqlcursor; + const adata: pointer; const alength: integer; + const afield: tfield; const aparam: tparam; + out newid: string); + procedure setupblobdata(const afield: tfield; const acursor: tsqlcursor; + const aparam: tparam); + function blobscached: boolean; + + procedure setoptions(const avalue: sqliteoptionsty); + procedure setbusytimeoutms(const avalue: integer); + procedure checkbusytimeout; + protected + procedure loaded; override; + function getfloatdate: boolean; override; + function getint64currency: boolean; override; + + function getassqltext(const field : tfield) : msestring; override; + function getassqltext(const param : tparam) : msestring; override; + + procedure resetstatement(const astatement: psqlite3_stmt); + procedure checkerror(const aerror: integer); + function cantransaction: boolean; + + procedure DoInternalConnect; override; + procedure DoInternalDisconnect; override; + function GetHandle : pointer; override; + + Function AllocateTransactionHandle : TSQLHandle; override; + + procedure internalExecute(const cursor: TSQLCursor; + const atransaction: tsqltransaction; const AParams : TmseParams; + const autf8: boolean); override; + + function GetTransactionHandle(trans : TSQLHandle): pointer; override; + function Commit(trans : TSQLHandle) : boolean; override; + function RollBack(trans : TSQLHandle) : boolean; override; + function StartdbTransaction(const trans : TSQLHandle; + const aParams: tstringlist) : boolean; override; + procedure internalCommitRetaining(trans : TSQLHandle); override; + procedure internalRollBackRetaining(trans : TSQLHandle); override; + function getblobdatasize: integer; override; + + function CreateBlobStream(const Field: TField; const Mode: TBlobStreamMode; + const acursor: tsqlcursor): TStream; override; + procedure execsql(const asql: string); + procedure UpdateIndexDefs(var IndexDefs : TIndexDefs; + const aTableName : string; const acursor: tsqlcursor); override; + function getprimarykeyfield(const atablename: string; + const acursor: tsqlcursor): string; override; + procedure updateprimarykeyfield(const afield: tfield; + const atransaction: tsqltransaction); override; + procedure beginupdate; override; + procedure endupdate; override; + public + constructor create(aowner: tcomponent); override; + Function AllocateCursorHandle(const aowner: icursorclient; + const aname: ansistring) : TSQLCursor; override; + //aowner used as blob cache + Procedure DeAllocateCursorHandle(var cursor : TSQLCursor); override; + procedure preparestatement(const cursor: tsqlcursor; + const atransaction : tsqltransaction; + const asql: msestring; const aparams : tmseparams); override; + function Fetch(cursor : TSQLCursor) : boolean; override; + procedure AddFieldDefs(const cursor: TSQLCursor; + const FieldDefs : TfieldDefs); override; + procedure UnPrepareStatement(cursor : TSQLCursor); override; + procedure FreeFldBuffers(cursor : TSQLCursor); override; + function loadfield(const cursor: tsqlcursor; + const datatype: tfieldtype; const fieldnum: integer; //null based + const buffer: pointer; var bufsize: integer; + const aisutf8: boolean): boolean; override; + //if bufsize < 0 -> buffer was to small, should be -bufsize + procedure updateutf8(var autf8: boolean); override; + function getinsertid(const atransaction: tsqltransaction): int64; override; + function fetchblob(const cursor: tsqlcursor; + const fieldnum: integer): ansistring; override; + //null based + function stringquery(const asql: string): stringarty; + function stringsquery(const asql: string): stringararty; + property lasterror: integer read flasterror; + property lasterrormessage: msestring read flasterrormessage; + published + property DatabaseName: filenamety read getdatabasename write setdatabasename; + property Connected: boolean read getconnected write setconnected default false; + property controller: tdbcontroller read fcontroller write setcontroller; + property options: sqliteoptionsty read foptions write setoptions default []; + property busytimeoutms: integer read fbusytimeoutms + write setbusytimeoutms default 0; + property Transaction; + property transactionwrite; + property afterconnect; + property beforedisconnect; + end; + +implementation +uses + msesqldb,msebufdataset,mseformatstr, + {$ifdef FPC}dbconst{$else}dbconst_del,classes_del{$endif}, + sysutils,typinfo,dateutils,msesysintf,msedate, + msefileutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + maxprecision = 18; +type + tmsebufdataset1 = class(tmsebufdataset); + + storagetypety = (st_none,st_integer,st_float,st_text,st_blob,st_null); + + tsqlite3cursor = class(tsqlcursor) + private + fstatement: psqlite3_stmt; + ftail: pchar; + fstate: integer; + fparambinding: tparambinding; + fopen: boolean; + fconnection: tsqlite3connection; + fprimarykeyfield: string; + public + constructor create(const aowner: icursorclient; const aname: ansistring; + const aconnection: tsqlite3connection); + procedure close; override; + end; + +{ tsqlite3cursor } + +constructor tsqlite3cursor.create(const aowner: icursorclient; + const aname: ansistring; const aconnection: tsqlite3connection); +begin + fconnection:= aconnection; + inherited create(aowner,aname); +end; + +procedure tsqlite3cursor.close; +begin + inherited; + if fopen then begin + fconnection.resetstatement(fstatement); + fopen:= false; + end; +end; + +{ tsqlite3connection } + +constructor tsqlite3connection.create(aowner: tcomponent); +begin + inherited; + fconnoptions:= fconnoptions + [sco_supportparams,sco_emulateretaining]; +end; + +function tsqlite3connection.getdatabasename: filenamety; +begin + result:= fcontroller.getdatabasename; +end; + +procedure tsqlite3connection.setdatabasename(const avalue: filenamety); +begin + fcontroller.setdatabasename(avalue); +end; + +procedure tsqlite3connection.loaded; +begin + inherited; + fcontroller.loaded; +end; + +procedure tsqlite3connection.setcontroller(const avalue: tdbcontroller); +begin + fcontroller.assign(avalue); +end; + +function tsqlite3connection.getconnected: boolean; +begin + result:= inherited connected; +end; + +procedure tsqlite3connection.setconnected(const avalue: boolean); +begin + if fcontroller.setactive(avalue) then begin + inherited connected:= avalue; + end; +end; + +function tsqlite3connection.CreateBlobStream(const Field: TField; + const Mode: TBlobStreamMode; const acursor: tsqlcursor): TStream; +var + blobid: integer; +// int1,int2: integer; +// str1: string; +// bo1: boolean; +begin + if (mode = bmwrite) and (field.dataset is tmsesqlquery) then begin + result:= tmsebufdataset(field.dataset).createblobbuffer(field); + end + else begin + result:= nil; + if mode = bmread then begin + if field.getData(@blobId) then begin + result:= acursor.getcachedblob(blobid); + end; + end; + end; +end; + +function tsqlite3connection.AllocateTransactionHandle: TSQLHandle; +begin + result:= tsqlitetrans.create; +end; + +function tsqlite3connection.AllocateCursorHandle(const aowner: icursorclient; + const aname: ansistring): TSQLCursor; +begin + result:= tsqlite3cursor.create(aowner,aname,self); +end; + +procedure tsqlite3connection.DeAllocateCursorHandle(var cursor: TSQLCursor); +begin + freeandnil(cursor); +end; + +procedure tsqlite3connection.preparestatement(const cursor: tsqlcursor; + const atransaction : tsqltransaction; + const asql: msestring; const aparams : tmseparams); +var + str1: string; +begin + with tsqlite3cursor(cursor) do begin + if assigned(aparams) and (aparams.count > 0) then begin + str1:= todbstring(aparams.parsesql(asql,false,false,false, + psinterbase,fparambinding)); + end + else begin + str1:= todbstring(asql); + end; + checkerror(sqlite3_prepare(fhandle,pchar(str1),length(str1),@fstatement, + @ftail)); + fprepared:= true; + end; +end; + +procedure tsqlite3connection.UnPrepareStatement(cursor: TSQLCursor); +//var +// int1: integer; +begin + with tsqlite3cursor(cursor) do begin +// int1:= sqlite3_finalize(fstatement); + sqlite3_finalize(fstatement); + fprepared:= false; + fopen:= false; + end; +end; + +procedure freebindstring(astring: pointer); cdecl; +begin + if astring <> pchar('') then begin + string(astring):= ''; + end; +end; + +procedure tsqlite3connection.AddFieldDefs(const cursor: TSQLCursor; + const FieldDefs: TfieldDefs); +const + fieldsizes: array[tfieldtype] of integer = ( //-1 invalid, -2 use fielddefs + //ftUnknown,ftString,ftSmallint, ftInteger, ftWord, + -1, -2, sizeof(smallint),sizeof(integer),sizeof(word), + //ftBoolean, ftFloat, ftCurrency, ftBCD, + sizeof(wordbool),sizeof(double),sizeof(double),sizeof(currency), + //ftDate, ftTime, ftDateTime, + sizeof(tdatetime),sizeof(tdatetime),sizeof(tdatetime), + //ftBytes,ftVarBytes,ftAutoInc,ftBlob, ftMemo, ftGraphic,ftFmtMemo, + -1, -1, -1, blobidsize,blobidsize,-1, -1, + //ftParadoxOle,ftDBaseOle,ftTypedBinary,ftCursor,ftFixedChar, + -1, -1, -1, -1, -1, + //ftWideString,ftLargeint, ftADT,ftArray,ftReference, + -1, sizeof(largeint),-1, -1, -1, + //ftDataSet,ftOraBlob,ftOraClob,ftVariant,ftInterface, + -1, -1, -1, -1, -1, + //ftIDispatch,ftGuid,ftTimeStamp,ftFMTBcd, + -1, -1, -1, -1 + // ftFixedWideChar,ftWideMemo + ,-1, -1 + ); + +var + int1,int2,int3: integer; + str1,str2: string; + ft1: tfieldtype; + size1: integer; + ar1: stringarty; + defsbefore: fielddefarty; + fd: tfielddef; +begin + defsbefore:= getfielddefar(fielddefs); + fielddefs.clear; + with tsqlite3cursor(cursor) do begin + for int1:= 0 to sqlite3_column_count(fstatement) - 1 do begin + str1:= sqlite3_column_name(fstatement,int1); + str2:= uppercase(sqlite3_column_decltype(fstatement,int1)); + ft1:= ftunknown; + size1:= 0; + if pos('INT',str2) = 1 then begin //or 'INTEGER' + ft1:= ftinteger; + if (slo_64bitprimarykey in foptions) and (str1 = fprimarykeyfield) then begin + ft1:= ftlargeint; + end; + end + else begin + if (str2 = 'LARGEINT') or (str2 = 'BIGINT') then begin + ft1:= ftlargeint; + end + else begin + if str2 = 'WORD' then begin + ft1:= ftword; + end + else begin + if str2 = 'SMALLINT' then begin + ft1:= ftsmallint; + end + else begin + if str2 = 'BOOLEAN' then begin + ft1:= ftboolean; + end + else begin + if (str2 = 'REAL') or (pos('FLOAT',str2) = 1) or + (pos('DOUBLE',str2) = 1) then begin + ft1:= ftfloat; + end + else begin + if (str2 = 'DATETIME') or (str2 = 'TIMESTAMP') then begin + ft1:= ftdatetime; + end + else begin + if str2 = 'DATE' then begin + ft1:= ftdate; + end + else begin + if str2 = 'TIME' then begin + ft1:= fttime; + end + else begin + if pos('NUMERIC',str2) = 1 then begin + ft1:= ftbcd; + end + else begin + if str2 = 'CURRENCY' then begin + ft1:= ftcurrency; + end + else begin + if pos('VARCHAR',str2) = 1 then begin + ft1:= ftstring; + ar1:= splitstring(str2,'('); + if high(ar1) >= 1 then begin + ar1:= splitstring(ar1[1],')'); + if high(ar1) >= 0 then begin + if not trystrtoint(ar1[0],size1) then begin + size1:= 0; + end; + end; + end; + end + else begin + if str2 = 'TEXT' then begin + if stringmemo then begin + ft1:= ftstring; + end + else begin + ft1:= ftmemo; + end; + end + else begin + if str2 = 'BLOB' then begin + ft1:= ftblob; + end; + end; + end; + end; + end; + end; + end; + end; + end; + end; + end; + end; + end; + end; + if (ft1 = ftunknown) then begin + int3:= -1; + for int2:= 0 to high(defsbefore) do begin + if defsbefore[int2].name = str1 then begin + int3:= int2; + break; + end; + end; + if int3 >= 0 then begin + with defsbefore[int3] do begin + ft1:= datatype; + if ft1 = ftstring then begin + size1:= size; + end; + end; + end; + if ft1 = ftunknown then begin + size1:= 0; + case storagetypety(sqlite3_column_type(fstatement,int1)) of + st_integer: ft1:= ftinteger; + st_float: ft1:= ftfloat; + st_text: ft1:= ftstring; + st_blob: ft1:= ftblob; + end; + end; + end; + if ft1 <> ftstring then begin + size1:= fieldsizes[ft1]; + end; + if ft1 = ftbcd then begin + size1:= 4; //scale fix + end; + if size1 < 0 then begin + ft1:= ftunknown; + size1:= 0; + end; + if not(ft1 in varsizefields) then begin + size1:= 0; + end; + fd:= tfielddef.create(nil,str1,ft1,size1,false,int1+1); + fd.collection:= fielddefs; + if ft1 = ftbcd then begin + fd.precision:= maxprecision; //precision fix + end; + end; + end; +end; + +procedure tsqlite3connection.resetstatement(const astatement: psqlite3_stmt); +begin + checkerror(sqlite3_reset(astatement)); + checkerror(sqlite3_clear_bindings(astatement)); +end; + +procedure tsqlite3connection.internalExecute(const cursor: TSQLCursor; + const atransaction: tsqltransaction; const AParams: TmseParams; + const autf8: boolean); +var + int1: integer; + str1: string; + cu1: currency; + do1: double; +{$ifndef CPUARM} + wo1: word; +{$endif} + po1: pchar; + i1: int32; +begin + with tsqlite3cursor(cursor) do begin + frowsaffected:= -1; + frowsreturned:= -1; + if aparams <> nil then begin + for int1:= 0 to high(fparambinding) do begin + with aparams[fparambinding[int1]] do begin + if isnull then begin + checkerror(sqlite3_bind_null(fstatement,int1+1)); + end + else begin + case datatype of + ftinteger,ftsmallint: begin + checkerror(sqlite3_bind_int(fstatement,int1+1,asinteger)); + end; + ftboolean: begin + i1:= asinteger; + if (i1 <> 0) and not (slo_negboolean in foptions) then begin + i1:= 1; + end; + checkerror(sqlite3_bind_int(fstatement,int1+1,i1)); + end; + ftword: begin + checkerror(sqlite3_bind_int(fstatement,int1+1,asword)); + end; + ftlargeint: begin + checkerror(sqlite3_bind_int64(fstatement,int1+1,aslargeint)); + end; + ftbcd: begin + cu1:= ascurrency; + checkerror(sqlite3_bind_int64(fstatement,int1+1,pint64(@cu1)^)); + end; + ftfloat,ftcurrency,ftdatetime,ftdate,fttime: begin + do1:= asfloat; + checkerror(sqlite3_bind_double(fstatement,int1+1,do1)); + end; + ftstring,ftwidestring,ftmemo,ftfixedchar,ftfixedwidechar: begin + str1:= aparams.asdbstring(fparambinding[int1]); + if str1 = '' then begin + po1:= pchar(''); + end + else begin + stringaddref(str1); + po1:= pchar(str1); + end; + checkerror(sqlite3_bind_text(fstatement,int1+1,po1, + length(str1),@freebindstring)); + end; + ftblob: begin + str1:= asstring; + stringaddref(str1); + checkerror(sqlite3_bind_blob(fstatement,int1+1,pointer(str1), + length(str1),@freebindstring)); + end; + else begin + databaseerror('Parameter type '+getenumname(typeinfo(tfieldtype), + ord(datatype))+' not supported.',self); + end; + end; + end; + end; + end; + end; + {$ifndef CPUARM} + wo1:= get8087cw; + set8087cw(wo1 or $1f); //mask exceptions, Sqlite3 has overflow + {$endif} + fstate:= sqlite3_step(fstatement); + {$ifndef CPUARM} + set8087cw(wo1); //restore + {$endif} + if fstate = sqlite_row then begin + fstate:= sqliteerrormax; //first row + fopen:= true; + end + else begin + resetstatement(fstatement); + end; + frowsaffected:= sqlite3_changes(fhandle); + end; +end; + +function tsqlite3connection.loadfield(const cursor: tsqlcursor; + const datatype: tfieldtype; const fieldnum: integer; //null based + const buffer: pointer; var bufsize: integer; + const aisutf8: boolean): boolean; +var + st1: storagetypety; + fnum: integer; +// i: integer; +// i64: int64; + int1,int2: integer; + str1: string; + ar1,ar2: stringarty; + year,month,day,hour,minute,second: integer; +begin + with tsqlite3cursor(cursor) do begin + fnum:= fieldnum; + st1:= storagetypety(sqlite3_column_type(fstatement,fnum)); + result:= st1 <> st_null; + if result then begin + if buffer = nil then begin + exit; + end; + case datatype of + ftinteger: begin + integer(buffer^):= sqlite3_column_int(fstatement,fnum); + end; + ftsmallint: begin + smallint(buffer^):= sqlite3_column_int(fstatement,fnum); + end; + ftword: begin + word(buffer^):= sqlite3_column_int(fstatement,fnum); + end; + ftboolean: begin + wordbool(buffer^):= sqlite3_column_int(fstatement,fnum) <> 0; + end; + ftlargeint,ftbcd: begin + largeint(buffer^):= sqlite3_column_int64(fstatement,fnum); + end; + ftfloat,ftcurrency: begin + double(buffer^):= sqlite3_column_double(fstatement,fnum); + end; + ftdatetime,ftdate,fttime: begin + if st1 = st_text then begin + result:= false; + setlength(str1,sqlite3_column_bytes(fstatement,fnum)); + move(sqlite3_column_text(fstatement,fnum)^,str1[1],length(str1)); + try + ar1:= splitstring(str1,' '); + if high(ar1) = 1 then begin + ar2:= splitstring(ar1[0],'-'); + if high(ar2) = 2 then begin + year:= strtoint(ar2[0]); + month:= strtoint(ar2[1]); + day:= strtoint(ar2[2]); + ar2:= splitstring(ar1[1],':'); + if high(ar2) = 2 then begin + hour:= strtoint(ar2[0]); + minute:= strtoint(ar2[1]); + second:= strtoint(ar2[2]); + tdatetime(buffer^):= encodedatetime(year,month,day, + hour,minute,second,0); + result:= true; + end; + end; + end + else begin + if high(ar1) = 0 then begin + ar2:= splitstring(ar1[0],'-'); + if high(ar2) = 2 then begin + year:= strtoint(ar2[0]); + month:= strtoint(ar2[1]); + day:= strtoint(ar2[2]); + tdatetime(buffer^):= encodedate(year,month,day); + result:= true; + end + else begin + ar2:= splitstring(ar1[0],':'); + if high(ar2) = 2 then begin + hour:= strtoint(ar2[0]); + minute:= strtoint(ar2[1]); + second:= strtoint(ar2[2]); + tdatetime(buffer^):= encodetime(hour,minute,second,0); + result:= true; + end; + end; + end; + end; + except + end; + end + else begin + tdatetime(buffer^):= sqlite3_column_double(fstatement,fnum); + end; + end; + ftstring,ftfixedchar: begin + int1:= sqlite3_column_bytes(fstatement,fnum); + if int1 > bufsize then begin + bufsize:= - int1; + end + else begin + bufsize:= int1; + if int1 > 0 then begin + move(sqlite3_column_text(fstatement,fnum)^,buffer^,int1); + end; + end; + end; + ftmemo: begin + int2:= sqlite3_column_bytes(fstatement,fnum); + int1:= addblobdata(sqlite3_column_text(fstatement,fnum),int2); + move(int1,buffer^,sizeof(int1)); + //save id + end; + ftblob: begin + int2:= sqlite3_column_bytes(fstatement,fnum); + int1:= addblobdata(sqlite3_column_blob(fstatement,fnum),int2); + move(int1,buffer^,sizeof(int1)); + //save id + end; + else begin + result:= false; // unknown + end; + end; + end; + end; +end; + +function tsqlite3connection.fetchblob(const cursor: tsqlcursor; + const fieldnum: integer): ansistring; +begin + result:= ''; + with tsqlite3cursor(cursor) do begin + if storagetypety(sqlite3_column_type(fstatement,fieldnum)) <> st_null then begin + setlength(result,sqlite3_column_bytes(fstatement,fieldnum)); + if result <> '' then begin + move(sqlite3_column_blob(fstatement,fieldnum)^,result[1],length(result)); + end; + end; + end; +end; + +function tsqlite3connection.Fetch(cursor: TSQLCursor): boolean; +begin + with tsqlite3cursor(cursor) do begin + if fstate = sqliteerrormax then begin + fstate:= sqlite_row; //first row; + end + else begin + if fstate = sqlite_row then begin + fstate:= sqlite3_step(fstatement); + if fstate <= sqliteerrormax then begin + checkerror(sqlite3_reset(fstatement)); //right error returned?? + end; + end; + end; + result:= fstate = sqlite_row; + end; +end; + +procedure tsqlite3connection.FreeFldBuffers(cursor: TSQLCursor); +begin + //dummy +end; + +function tsqlite3connection.GetTransactionHandle(trans: TSQLHandle): pointer; +begin + result:= nil; +end; + +function tsqlite3connection.Commit(trans: TSQLHandle): boolean; +begin + if cantransaction then begin + execsql('COMMIT'); + end; + result:= true; +end; + +function tsqlite3connection.RollBack(trans: TSQLHandle): boolean; +begin + if cantransaction then begin + execsql('ROLLBACK'); + end; + result:= true; +end; + +function tsqlite3connection.StartdbTransaction(const trans: TSQLHandle; + const aParams: tstringlist): boolean; +begin + if cantransaction then begin + with tsqlitetrans(trans) do begin + fparams:= aparams.text; + execsql('BEGIN '+fparams); + end; + end; + result:= true; +end; + +procedure tsqlite3connection.internalCommitRetaining(trans: TSQLHandle); +begin + commit(trans); + if cantransaction then begin + with tsqlitetrans(trans) do begin + execsql('BEGIN '+fparams); + end; + end; +end; + +procedure tsqlite3connection.internalRollBackRetaining(trans: TSQLHandle); +begin + rollback(trans); + if cantransaction then begin + with tsqlitetrans(trans) do begin + execsql('BEGIN '+fparams); + end; + end; +end; + +function tsqlite3connection.getblobdatasize: integer; +begin + result:= blobidsize; +end; + +procedure tsqlite3connection.DoInternalConnect; +var + str1: string; +begin +// if (inherited databasename = '') then begin +// DatabaseError(SErrNoDatabaseName,self); +// end; + initializesqlite3([]); + str1:= stringtoutf8ansi(msestring(inherited databasename)); + checkerror(sqlite3_open(pchar(str1),@fhandle)); + checkbusytimeout; +end; + +procedure tsqlite3connection.DoInternalDisconnect; +//var +// int1: integer; +begin + if fhandle <> nil then begin +// int1:= sqlite3_close(fhandle); + sqlite3_close(fhandle); +// if int1 = sqlite_busy then begin +// checkerror(int1); +// end; + fhandle:= nil; + releasesqlite3; + end; +end; + +function tsqlite3connection.GetHandle: pointer; +begin + result:= fhandle; +end; + +procedure tsqlite3connection.checkerror(const aerror: integer); +begin + if aerror <> sqlite_ok then begin + flasterror:= aerror; + flasterrormessage:= utf8tostringansi(sqlite3_errmsg(fhandle)); + raise esqlite3error.create(self,ansistring(flasterrormessage), + flasterrormessage,flasterror); + end; +end; + +procedure tsqlite3connection.execsql(const asql: string); +var + err: pchar; + str1: string; + int1: integer; +begin + str1:= ''; + err:= nil; +{$ifdef FPC} {$checkpointer off} {$endif}; + int1:= sqlite3_exec(fhandle,pchar(asql),nil,nil^,@err); +{$ifdef FPC} {$checkpointer default} {$endif}; + if err <> nil then begin + str1:= err; + sqlite3_free(err); + end; + if int1 <> sqlite_ok then begin + databaseerror(str1); + end; +end; + +procedure tsqlite3connection.updateutf8(var autf8: boolean); +begin + autf8:= true; +end; + +procedure tsqlite3connection.writeblobdata(const atransaction: tsqltransaction; + const tablename: string; const acursor: tsqlcursor; + const adata: pointer; const alength: integer; + const afield: tfield; const aparam: tparam; out newid: string); +var + str1: string; + int1: integer; +begin + setlength(str1,alength); + move(adata^,str1[1],alength); + if afield.datatype = ftmemo then begin + aparam.asmemo:= str1; + end + else begin + aparam.asblob:= str1; + end; + int1:= acursor.addblobdata(str1); + setlength(newid,sizeof(int1)); + move(int1,newid[1],sizeof(int1)); +end; + +procedure tsqlite3connection.setupblobdata(const afield: tfield; + const acursor: tsqlcursor; const aparam: tparam); +begin + acursor.blobfieldtoparam(afield,aparam,false); +end; + +function tsqlite3connection.blobscached: boolean; +begin + result:= true; +end; + +function execcallback(var adata; ncols: longint; //adata = stringarty + avalues: PPchar; anames: PPchar):longint; cdecl; +var + int1: integer; +begin + setlength(stringarty(adata),ncols); + for int1:= 0 to ncols - 1 do begin + stringarty(adata)[int1]:= pcharpoaty(avalues)^[int1]; + end; + result:= 0; +end; + +function tsqlite3connection.stringquery(const asql: string): stringarty; +begin + result:= nil; + checkerror(sqlite3_exec(fhandle,pchar(asql),@execcallback,result,nil)); +end; + +function execscallback(var adata; ncols: longint; //adata = stringarty + avalues: PPchar; anames: PPchar):longint; cdecl; +var + int1: integer; + po1: pstringarty; + po2: pstring; +begin + //@ operator and some indexing do not work with -O2 and FPC 2.2 + setlength(stringararty(adata),high(stringararty(adata))+2); + po1:= pointer(pchar(pointer(adata)) + high(stringararty(adata))*sizeof(pointer)); + setlength(po1^,ncols); + po2:= pointer(po1^); + for int1:= 0 to ncols - 1 do begin + po2^:= pcharpoaty(avalues)^[int1]; + inc(po2); + end; + result:= 0; +end; + +function tsqlite3connection.stringsquery(const asql: string): stringararty; +begin + result:= nil; +// checkerror(sqlite3_exec(fhandle,pchar(asql),@execscallback,@result,nil)); + checkerror(sqlite3_exec(fhandle,pchar(asql),@execscallback,result,nil)); +end; + +function tsqlite3connection.getprimarykeyfield(const atablename: string; + const acursor: tsqlcursor): string; +var + int1{,int2}: integer; + ar1: stringararty; +// str1: string; +begin + result:= ''; + if atablename <> '' then begin + try + ar1:= stringsquery('PRAGMA table_info('+atablename+');'); + for int1:= 0 to high(ar1) do begin + if (high(ar1[int1]) >= 5) and (ar1[int1][5] <> '0') then begin + result:= ar1[int1][1]; + break; + end; + end; + except + end; + end; + tsqlite3cursor(acursor).fprimarykeyfield:= result; +end; + +procedure tsqlite3connection.UpdateIndexDefs(var IndexDefs: TIndexDefs; + const aTableName: string; const acursor: tsqlcursor); +var + str1: string; +begin + try + str1:= getprimarykeyfield(atablename,acursor); + except + str1:= ''; + end; + if str1 <> '' then begin + indexdefs.add('$PRIMARY_KEY$',str1,[ixPrimary,ixUnique]); + end; +end; +{ +procedure tsqlite3connection.UpdateIndexDefs(var IndexDefs: TIndexDefs; + const TableName: string); +var + int1,int2: integer; + ar1: stringararty; + str1: string; +begin + ar1:= stringsquery('PRAGMA table_info('+tablename+');'); + for int1:= 0 to high(ar1) do begin + if (high(ar1[int1]) >= 5) and (ar1[int1][5] <> '0') then begin + indexdefs.add('$PRIMARY_KEY$',ar1[int1][1],[ixPrimary,ixUnique]); + break; + end; + end; +end; +} + +function tsqlite3connection.getinsertid(const atransaction: tsqltransaction): int64; +begin + result:= sqlite3_last_insert_rowid(fhandle); +end; + +procedure tsqlite3connection.updateprimarykeyfield(const afield: tfield; + const atransaction: tsqltransaction); +begin + if afield.datatype in integerfields then begin + afield.aslargeint:= getinsertid(nil); + end; + { + with tmsebufdataset1(afield.dataset) do begin + setcurvalue(afield,getinsertid); + end; + } +end; + +function tsqlite3connection.cantransaction: boolean; +begin + result:= (slo_transactions in foptions) and + ((slo_designtransactions in foptions) or not (csdesigning in componentstate)); +end; + +procedure tsqlite3connection.setoptions(const avalue: sqliteoptionsty); +begin + if avalue <> foptions then begin + checkdisconnected; + foptions:= avalue; + end; +end; + +procedure tsqlite3connection.setbusytimeoutms(const avalue: integer); +begin + if avalue <> fbusytimeoutms then begin + fbusytimeoutms:= avalue; + checkbusytimeout; + end; +end; + +procedure tsqlite3connection.checkbusytimeout; +begin + if fhandle <> nil then begin + sqlite3_busy_timeout(fhandle,fbusytimeoutms); + end; +end; + +procedure tsqlite3connection.beginupdate; +begin + if not (slo_transactions in foptions) then begin + execsql('BEGIN'); + end; +end; + +procedure tsqlite3connection.endupdate; +begin + if not (slo_transactions in foptions) then begin + execsql('COMMIT'); + end; +end; + +function tsqlite3connection.getassqltext(const field: tfield): msestring; +begin + if field.isnull then begin + result:= inherited getassqltext(field); + end + else begin + case field.datatype of + ftdate,ftdatetime,fttime: begin + result:= encodesqlfloat(field.asdatetime); + end; + ftbcd: begin + {$ifdef FPC} + result:= inttostrmse(int64(field.ascurrency)); + {$else} + result:= inttostrmse(int64(ar8ty(field.ascurrency))); + {$endif} + end; + else begin + result:= inherited getassqltext(field); + end; + end; + end; +end; + +function tsqlite3connection.getassqltext(const param: tparam): msestring; +begin + if param.isnull then begin + result:= inherited getassqltext(param); + end + else begin + case param.datatype of + ftdate,ftdatetime,fttime: begin + result:= encodesqlfloat(param.asdatetime); + end; + ftbcd: begin + {$ifdef FPC} + result:= inttostrmse(int64(param.ascurrency)); + {$else} + result:= inttostrmse(int64(ar8ty(param.ascurrency))); + {$endif} + end; + else begin + result:= inherited getassqltext(param); + end; + end; + end; +end; + +function tsqlite3connection.getfloatdate: boolean; +begin + result:= true; +end; + +function tsqlite3connection.getint64currency: boolean; +begin + result:= true; +end; + +end. diff --git a/mseide-msegui/lib/common/db/msesqlquery.pas b/mseide-msegui/lib/common/db/msesqlquery.pas new file mode 100644 index 0000000..57bce30 --- /dev/null +++ b/mseide-msegui/lib/common/db/msesqlquery.pas @@ -0,0 +1,2409 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msesqlquery; +{$ifdef FPC}{$mode objfpc}{$h+}{$goto on}{$endif} + +interface +uses + classes,mclasses,mdb,msetimer,msebufdataset,msqldb,msedb,msestrings, + msedatabase,mseclasses,msetypes,msesqlresult; + +type + tsqlquery = class; + tsqlmasterparamsdatalink = class(tmasterparamsdatalink) + private + fquery: tsqlquery; + frefreshlock: integer; +// fdelayus: integer; + ftimer: tsimpletimer; + protected + procedure domasterdisable; override; + procedure domasterchange; override; + procedure CheckBrowseMode; override; + procedure DataEvent(Event: TDataEvent; Info: Ptrint); override; + procedure checkrefresh; //makes pending delayed refresh + procedure dorefresh(const sender: tobject); + public + constructor create(const aowner: tsqlquery); reintroduce; + destructor destroy; override; + Procedure RefreshParamNames; override; + Procedure CopyParamsFromMaster(CopyBound : Boolean); override; +// published +// property delayus: integer read fdelayus write fdelayus default -1; + end; + + sqlquerystatety = (sqs_userapplyrecupdate,sqs_updateabort,sqs_updateerror); + sqlquerystatesty = set of sqlquerystatety; + + tupdatestringlist = class(tsqlstringlist) + end; + + tsqlquery = class (tmsebufdataset,isqlclient,icursorclient) + private + fcursor: tsqlcursor; + fupdateable: boolean; + fsql: tsqlstringlist; +// fsqlupdate,fsqlinsert: tupdatesqlstringlist; +// fsqldelete: tsqlstringlist; + fiseof: boolean; + floadingfielddefs: boolean; + findexdefs: tindexdefs; + fupdatemode: tupdatemode; + fparams: tmseparams; + fuseprimarykeyaskey: boolean; + fsqlbuf: msestring; + fsqlprepbuf: msestring; + ffrompart: msestring; + fwherestartpos: integer; + fwherestoppos: integer; + fparsesql: boolean; + fstatementtype: tstatementtype; + fmasterlink: tsqlmasterparamsdatalink; + fapplyqueries: array[tupdatekind] of tsqlresult; + fapplysql: array[tupdatekind] of tupdatestringlist; +// fupdateqry,fdeleteqry,finsertqry: tsqlquery; + fupdaterowsaffected: integer; + fblobintf: iblobconnection; + fbeforeexecute: tcustomsqlstatement; + faftercursorclose: tcustomsqlstatement; + fmasterdelayus: integer; + procedure freefldbuffers; + function getindexdefs : tindexdefs; +// function getstatementtype : tstatementtype; + procedure setindexdefs(avalue : tindexdefs); + procedure setreadonly(avalue : boolean); + procedure setparsesql(avalue : boolean); + procedure setstatementtype(const avalue: tstatementtype); + procedure setuseprimarykeyaskey(avalue : boolean); + procedure setupdatemode(avalue : tupdatemode); + procedure onchangesql(const sender : tobject); + procedure onchangemodifysql(const sender : tobject); + procedure execute; + procedure sqlparser(var asql: msestring); + procedure applyfilter; + function addfilter(sqlstr : msestring) : msestring; + function getdatabase1: tcustomsqlconnection; + procedure setdatabase1(const avalue: tcustomsqlconnection); + procedure setparams(const avalue: tmseparams); + function getconnected: boolean; + procedure setconnected(const avalue: boolean); + procedure setfsql(const avalue: tsqlstringlist); + procedure setfsqlupdate(const avalue: tupdatestringlist); + procedure setfsqlinsert(const avalue: tupdatestringlist); + procedure setfsqldelete(const avalue: tupdatestringlist); + procedure setbeforeexecute(const avalue: tcustomsqlstatement); + procedure setaftercursorclose(const avalue: tcustomsqlstatement); + function getsqltransaction: tsqltransaction; + procedure setsqltransaction(const avalue: tsqltransaction); + function getsqltransactionwrite: tsqltransaction; + procedure setsqltransactionwrite(const avalue: tsqltransaction); + procedure resetparsing; + procedure dorefresh; +// procedure setmasterlink(const avalue: tsqlmasterparamsdatalink); +// procedure setmasterdelayus(const avalue: integer); + procedure settablename(const avalue: string); + protected + fmstate: sqlquerystatesty; + FTableName: string; + FReadOnly: boolean; + fprimarykeyfield: tfield; + futf8: boolean; + foptionsmasterlink: optionsmasterlinkty; + function getdatabase: tcustomconnection; //for isqlpropertyeditor + procedure settransactionwrite(const avalue: tmdbtransaction); override; + procedure checkpendingupdates; virtual; + procedure notification(acomponent: tcomponent; operation: toperation); override; + // abstract & virtual methods of TBufDataset + function Fetch : boolean; override; + function getblobdatasize: integer; override; + function getnumboolean: boolean; virtual; + function getfloatdate: boolean; virtual; + function getint64currency: boolean; virtual; + function blobscached: boolean; override; + function loadfield(const afieldno: integer; const afieldtype: tfieldtype; + const buffer: pointer; var bufsize: integer): boolean; override; + //if bufsize < 0 -> buffer was to small, should be -bufsize + // abstract & virtual methods of TDataset +// procedure dscontrolleroptionschanged(const aoptions: datasetoptionsty); + procedure updateindexdefs; override; + procedure setdatabase(const value: tmdatabase); override; + procedure settransaction(const value : tmdbtransaction); override; + procedure internaladdrecord(buffer: pointer; aappend: boolean); override; + procedure internalclose; override; + procedure internalinitfielddefs; override; + procedure connect(const aexecute: boolean); + procedure freemodifyqueries; + procedure freequery; + procedure disconnect{(const aexecute: boolean)}; + procedure checkrecursivedatasource(const avalue: tdatasource); + procedure internalopen; override; + procedure internalrefresh; override; + procedure refreshtransaction; override; + procedure dobeforeedit; override; + procedure dobeforeinsert; override; + procedure dataevent(event: tdataevent; info: ptrint); override; + + function getcanmodify: boolean; override; + procedure updatewherepart(var sql_where : msestring; const afield: tfield); + procedure internalapplyrecupdate(updatekind : tupdatekind); + procedure dobeforeapplyupdate; override; + procedure applyrecupdate(updatekind : tupdatekind); override; + function isprepared: boolean; virtual; + Procedure SetActive (Value : Boolean); override; + procedure SetFiltered(Value: Boolean); override; + procedure SetFilterText(const Value: string); override; + Function GetDataSource : TDatasource; override; + Procedure SetDataSource(AValue : TDatasource); + //icursorclient + function stringmemo: boolean; virtual; + //memo fields are text(0) fields + public + constructor Create(AOwner : TComponent); override; + destructor Destroy; override; + function isutf8: boolean; override; + procedure applyupdate(const cancelonerror: boolean; + const cancelondeleteerror: boolean = false; + const editonerror: boolean = false); override; + procedure applyupdates(const maxerrors: integer; + const cancelonerror: boolean; + const cancelondeleteerror: boolean = false; + const editonerror: boolean = false); override; + function refreshrecquery(const update: boolean): msestring; + procedure checktablename; + function updaterecquery : msestring; + function insertrecquery : msestring; + function deleterecquery : msestring; + function writetransaction: tsqltransaction; + //self.transaction if self.transactionwrite = nil + procedure refresh(const aparams: array of variant); overload; + procedure Prepare; virtual; + procedure UnPrepare; virtual; + procedure ExecSQL; virtual; + function executedirect(const asql: msestring): integer; + //uses writetransaction of tsqlquery + function rowsreturned: integer; //-1 if not supported + function rowsaffected: integer; //-1 if not supported + property updaterowsaffected: integer read fupdaterowsaffected; + //sum of rowsaffected of insert, update and delete query, + //reset by close, applyupdate and applyupdates, -1 if not supported. +// procedure SetSchemaInfo( SchemaType : TSchemaType; SchemaObjectName, SchemaPattern : string); virtual; + function CreateBlobStream(Field: TField; Mode: TBlobStreamMode): TStream; override; + property Prepared : boolean read IsPrepared; + property connected: boolean read getconnected write setconnected; + published + property ReadOnly : Boolean read FReadOnly write SetReadOnly default false; + property ParseSQL : Boolean read FParseSQL write SetParseSQL default true; + property params : tmseparams read fparams write setparams; + //before SQL + property SQL : tsqlstringlist read FSQL write setFSQL; + property SQLUpdate : tupdatestringlist read Fapplysql[ukmodify] + write setFSQLUpdate; + property SQLInsert : tupdatestringlist read Fapplysql[ukinsert] + write setFSQLInsert; + property SQLDelete : tupdatestringlist read Fapplysql[ukdelete] + write setFSQLDelete; + property beforeexecute: tcustomsqlstatement read fbeforeexecute write setbeforeexecute; + property aftercursorclose: tcustomsqlstatement read faftercursorclose + write setaftercursorclose; + property IndexDefs : TIndexDefs read GetIndexDefs; + property UpdateMode : TUpdateMode read FUpdateMode write SetUpdateMode; + property UsePrimaryKeyAsKey : boolean read FUsePrimaryKeyAsKey write SetUsePrimaryKeyAsKey; + property tablename: string read ftablename write settablename; + property StatementType : TStatementType read fstatementtype + write setstatementtype default stnone; + Property DataSource : TDatasource Read GetDataSource Write SetDatasource; + property masterdelayus: integer read fmasterdelayus + write fmasterdelayus default -1; + property optionsmasterlink: optionsmasterlinkty read foptionsmasterlink + write foptionsmasterlink default []; + // property masterlink: tsqlmasterparamsdatalink read fmasterlink + // write setmasterlink; + property database: tcustomsqlconnection read getdatabase1 write setdatabase1; + +// property SchemaInfo : TSchemaInfo read FSchemaInfo default stNoSchema; + // redeclared data set properties + property Active; + property Filter; + property Filtered; +// property FilterOptions; + property BeforeOpen; + property AfterOpen; + property BeforeClose; + property AfterClose; + property BeforeInsert; + property AfterInsert; + property BeforeEdit; + property AfterEdit; + property BeforePost; + property AfterPost; + property BeforeCancel; + property AfterCancel; + property BeforeDelete; + property AfterDelete; + property BeforeScroll; + property AfterScroll; + property BeforeRefresh; + property AfterRefresh; + property OnCalcFields; + property OnDeleteError; + property OnEditError; + property OnFilterRecord; + property OnNewRecord; + property OnPostError; + property onmodified; + property AutoCalcFields; +// property Database; + + property Transaction: tsqltransaction read getsqltransaction write setsqltransaction; + property transactionwrite: tsqltransaction read getsqltransactionwrite + write setsqltransactionwrite; + end; + +procedure querytoupdateparams(const source: tsqlquery; const dest: tparams); +function SkipComments(var p: PmseChar) : boolean; + +implementation +uses + sysutils,{$ifdef FPC}dbconst{$else}dbconst_del,classes_del{$endif},msearrayutils,typinfo; + +type + tcustomsqlconnection1 = class(tcustomsqlconnection); + tcustomsqlstatement1 = class(tcustomsqlstatement); + tsqltransaction1 = class(tsqltransaction); + tsqlresult1 = class(tsqlresult); + tdataset1 = class(tdataset); + +function SkipComments(var p: PmseChar) : boolean; +begin + result := false; + case p^ of + '''': // single quote delimited string + begin + Inc(p); + Result := True; + while not ((p^ = #0) or (p^ = '''')) do + begin + if p^='\' then Inc(p,2) // make sure we handle \' and \\ correct + else Inc(p); + end; + if p^='''' then Inc(p); // skip final ' + end; + '"': // double quote delimited string + begin + Inc(p); + Result := True; + while not ((p^ = #0) or (p^ = '"')) do + begin + if p^='\' then Inc(p,2) // make sure we handle \" and \\ correct + else Inc(p); + end; + if p^='"' then Inc(p); // skip final " + end; + '-': // possible start of -- comment + begin + Inc(p); + if p^='-' then // -- comment + begin + Result := True; + repeat // skip until at end of line + Inc(p); + until (p^ = #10) or (p^ = #0); + end + end; + '/': // possible start of /* */ comment + begin + Inc(p); + if p^='*' then // /* */ comment + begin + Result := True; + repeat + Inc(p); + if p^='*' then // possible end of comment + begin + Inc(p); + if p^='/' then Break; // end of comment + end; + until p^=#0; + if p^='/' then Inc(p); // skip final / + end; + end; + end; {case} +end; + +procedure querytoupdateparams(const source: tsqlquery; const dest: tparams); +var + x: integer; + param1,param2: tparam; + fld: tfield; +begin + for x := 0 to dest.Count-1 do begin + param1:= dest[x]; + with param1 do begin + if leftstr(name,4)='OLD_' then begin + Fld:= source.FieldByName(copy(name,5,length(name)-4)); + source.oldfieldtoparam(fld,param1); +// AssignFieldValue(Fld,Fld.OldValue); + end + else begin + fld:= source.findfield(name); + if fld = nil then begin //search for param + param2:= source.params.findparam(name); + if param2 = nil then begin + source.fieldbyname(name); //raise exception + end + else begin + value:= param2.value; + end; + end + else begin //use field + source.fieldtoparam(fld,param1); + end; + end; + end; + end; +end; + +{ tsqlmasterparamsdatalink } + +constructor tsqlmasterparamsdatalink.create(const aowner: tsqlquery); +begin + fquery:= aowner; + inherited create(aowner); +end; + +destructor tsqlmasterparamsdatalink.destroy; +begin + freeandnil(ftimer); + inherited; +end; + +procedure tsqlmasterparamsdatalink.dorefresh(const sender: tobject); +begin + if Assigned(Params) and Assigned(DetailDataset) and + DetailDataset.Active then begin + detaildataset.refresh; + end; +end; + +procedure tsqlmasterparamsdatalink.checkrefresh; +begin + if ftimer <> nil then begin + ftimer.firependingandstop; //cancel wait + end; +end; + +procedure tsqlmasterparamsdatalink.domasterchange; +var + intf: igetdscontroller; +begin + if (frefreshlock = 0) and + (not getcorbainterface(dataset,typeinfo(igetdscontroller),intf) or + not intf.getcontroller.posting) then begin + if assigned(onmasterchange) then begin + onmasterchange(self); + end; + if assigned(params) and assigned(detaildataset) and + (detaildataset.state = dsbrowse) and + not (mdlo_norefresh in fquery.foptionsmasterlink) then begin + if fquery.masterdelayus < 0 then begin + freeandnil(ftimer); + dorefresh(nil); + end + else begin + if ftimer = nil then begin + ftimer:= tsimpletimer.create(fquery.masterdelayus, + {$ifdef FPC}@{$endif}dorefresh,true,[to_single]); + end + else begin + ftimer.interval:= fquery.masterdelayus; //single shot + ftimer.enabled:= true; + end; + end; + end; + end; +end; + +procedure tsqlmasterparamsdatalink.domasterdisable; +var + intf: imasterlink; +begin + if (dataset = nil) or + not getcorbainterface(dataset,typeinfo(imasterlink),intf) or + not intf.refreshing then begin + if assigned(onmasterdisable) then begin + onmasterdisable(self); + end; + if assigned(detaildataset) and detaildataset.active then begin + detaildataset.close; + end; + end; +end; + +procedure tsqlmasterparamsdatalink.DataEvent(Event: TDataEvent; Info: Ptrint); +begin + inherited; + with tsqlquery(detaildataset) do begin + if active then begin + case ord(event) of + ord(deupdaterecord): begin + if state in [dsinsert,dsedit] then begin + updaterecord; + if modified then begin + tdataset1(dataset).setmodified(true); //FPC fixes_2_6 compatibility +// dataset.modified:= true; + end; + end; + end; + ord(deupdatestate): begin + if (mdlo_syncedit in foptionsmasterlink) and + (dataset.state = dsedit) and not (state = dsedit) then begin + edit; + end; + if (mdlo_syncinsert in foptionsmasterlink) and + (dataset.state = dsinsert) and not (state = dsinsert) then begin + insert; + end; + end; + de_afterdelete: begin + if (mdlo_syncdelete in foptionsmasterlink) then begin + delete; + end; + end; + de_afterpost: begin + if (mdlo_delayeddetailpost in foptionsmasterlink) then begin + if (mdlo_inserttoupdate in foptionsmasterlink) and + (state = dsinsert) then begin + tdataset1(detaildataset).setmodified(true); //FPC fixes_2_6 compatibility +// detaildataset.modified:= true; + include(fbstate,bs_inserttoupdate); + try + detaildataset.checkbrowsemode; + finally + exclude(fbstate,bs_inserttoupdate); + end; + end + else begin + detaildataset.checkbrowsemode; + end; + end; + end; + end; + end; + end; +end; + +procedure tsqlmasterparamsdatalink.CheckBrowseMode; +label + endlab; +var + intf: igetdscontroller; + detailoptions: optionsmasterlinkty; +begin + if detaildataset.active then begin + inc(frefreshlock); + try + detailoptions:= tsqlquery(detaildataset).foptionsmasterlink; + if detailoptions * + [mdlo_syncedit,mdlo_syncinsert] <> [] then begin + if getcorbainterface(dataset,typeinfo(igetdscontroller),intf) and + intf.getcontroller.canceling then begin + detaildataset.cancel; + exit; + end + else begin + if mdlo_delayeddetailpost in detailoptions then begin + exit; + end; + if detaildataset.state = dsinsert then begin + dataset.updaterecord; + if dataset.modified then begin + detaildataset.post; + goto endlab; + end; + end; + end; + end; + inherited; + endlab: + if (dataset.state in [dsedit,dsinsert]) and + (detailoptions * [mdlo_syncedit,mdlo_syncinsert] <> []) then begin + dataset.updaterecord; //synchronize fields + end; + if getcorbainterface(detaildataset,typeinfo(igetdscontroller),intf) then begin + with intf.getcontroller do begin + if (dataset.state = dsinsert) and assigned(onupdatemasterinsert) then begin + onupdatemasterinsert(detaildataset,dataset); + end; + if (dataset.state = dsedit) and assigned(onupdatemasteredit) then begin + onupdatemasteredit(detaildataset,dataset); + end; + end; + end; + finally + dec(frefreshlock); + end; + end; +end; + +procedure tsqlmasterparamsdatalink.CopyParamsFromMaster(CopyBound: Boolean); +begin + if not (mdlo_norefresh in fquery.foptionsmasterlink) then begin + inherited; + end; +end; + +procedure tsqlmasterparamsdatalink.RefreshParamNames; +begin + if not (mdlo_norefresh in fquery.foptionsmasterlink) then begin + inherited; + end + else begin + fieldnames:= ''; + end; +end; + +{ TSQLQuery } + +constructor TSQLQuery.Create(AOwner : TComponent); +var + k1: tupdatekind; +begin + fmasterdelayus:= -1; + inherited Create(AOwner); + FParams := TmseParams.create(self); + FSQL := TsqlStringList.Create; + FSQL.OnChange := {$ifdef FPC}@{$endif}OnChangeSQL; + + for k1:= low(tupdatekind) to high(tupdatekind) do begin + fapplysql[k1]:= tupdatestringlist.create; + fapplysql[k1].onchange:= {$ifdef FPC}@{$endif}onchangemodifysql; + end; + { + FSQLUpdate := TupdatesqlStringList.Create; + FSQLUpdate.OnChange := @OnChangeModifySQL; + FSQLInsert := TupdatesqlStringList.Create; + FSQLInsert.OnChange := @OnChangeModifySQL; + FSQLDelete := TsqlStringList.Create; + FSQLDelete.OnChange := @OnChangeModifySQL; +} + FIndexDefs := TIndexDefs.Create(Self); + FReadOnly := false; + FParseSQL := True; + fstatementtype:= stnone; +// Delphi has upWhereAll as default, but since strings and oldvalue's don't work yet +// (variants) set it to upWhereKeyOnly + FUpdateMode := upWhereKeyOnly; + FUsePrimaryKeyAsKey := True; +end; + +destructor TSQLQuery.Destroy; +var + k1: tupdatekind; +begin + if Active then Close; + UnPrepare; + if assigned(FCursor) then (Database as tcustomsqlconnection).DeAllocateCursorHandle(FCursor); + FreeAndNil(FMasterLink); + FreeAndNil(FParams); + FreeAndNil(FSQL); + for k1:= low(tupdatekind) to high(tupdatekind) do begin + freeandnil(fapplyqueries[k1]); + freeandnil(fapplysql[k1]); + end; + { + FreeAndNil(FSQLInsert); + FreeAndNil(FSQLDelete); + FreeAndNil(FSQLUpdate); + } + FreeAndNil(FIndexDefs); + { + freeandnil(finsertqry); + freeandnil(fupdateqry); + freeandnil(fdeleteqry); + } + inherited Destroy; +end; + +procedure TSQLQuery.OnChangeSQL(const Sender : TObject); + +//var ParamName : String; +begin + UnPrepare; + if (FSQL <> nil) then + begin + FParams.ParseSQL(FSQL.Text,True); + If Assigned(FMasterLink) then + FMasterLink.RefreshParamNames; + end; +end; + +procedure TSQLQuery.OnChangeModifySQL(const Sender : TObject); +var + k1: tupdatekind; +begin + if not (csdesigning in componentstate) then begin +// CheckInactive; + if connected then begin + for k1:= low(tupdatekind) to high(tupdatekind) do begin + if sender = fapplysql[k1] then begin + with fapplyqueries[k1] do begin + active:= false; + sql.assign(fapplysql[k1]); + end; + break; + end; + end; + end; + end; +end; + +Procedure TSQLQuery.SetTransaction(const Value : tmdbtransaction); +begin + if ftransaction <> value then begin + checksqltransaction(name,value); + UnPrepare; + inherited; + end; +end; + +procedure TSQLQuery.SetDatabase(const Value : tmdatabase); +begin + dosetsqldatabase(isqlclient(self),value,fcursor,fdatabase); +{ + if (fDatabase <> Value) then begin + checksqlconnection(name,value); + UnPrepare; + if assigned(FCursor) then begin + tcustomsqlconnection(database).DeAllocateCursorHandle(FCursor); + end; + dosetsqldatabase(isqlclient(self),tcustomsqlconnection(value), + tcustomsqlconnection(fdatabase)); + } + { + inherited setdatabase(value); + with tcustomsqlconnection(value) do begin + if (value <> nil) and (self.Transaction = nil) and + (Transaction <> nil) then begin + self.transaction:= Transaction; + end; + end; + } +// end; +end; + +Function TSQLQuery.IsPrepared : Boolean; + +begin + Result := Assigned(FCursor) and FCursor.FPrepared; +end; + +Function TSQLQuery.AddFilter(SQLstr : msestring) : msestring; + +begin + if FWhereStartPos = 0 then + SQLstr := SQLstr + ' where (' + msestring(Filter) + ')' + else if FWhereStopPos > 0 then + system.insert(' and ('+msestring(Filter)+') ',SQLstr,FWhereStopPos+1) + else + system.insert(' where ('+msestring(Filter)+') ',SQLstr,FWhereStartPos); + Result := SQLstr; +end; + +procedure tsqlquery.applyfilter; +//var +// s: string; +begin + freefldbuffers; + tcustomsqlconnection(database).unpreparestatement(fcursor); + fiseof := false; + inherited internalclose; + if filtered and (filter <> '') then begin + fsqlprepbuf:= addfilter(fsqlbuf); + end + else begin + fsqlprepbuf:= fsqlbuf; + end; + if not (bdo_noprepare in foptions) then begin + tcustomsqlconnection(database).preparestatement(fcursor, + tsqltransaction(transaction),fsqlprepbuf,fparams); + end; + execute; + inherited internalopen; + first; +end; + +Procedure TSQLQuery.SetActive (Value : Boolean); + +begin + inherited SetActive(Value); +// The query is UnPrepared, so that if a transaction closes all datasets +// they also get unprepared + if not Value and IsPrepared then UnPrepare; +end; + + +procedure TSQLQuery.SetFiltered(Value: Boolean); + +begin + if Value and not FParseSQL and (filter <> '') then begin + DatabaseErrorFmt(SNoParseSQL,['Filtering ']); + end; + if (Filtered <> Value) then begin + inherited setfiltered(Value); + if active then begin + if filter <> '' then begin + ApplyFilter; + end + else begin + resync([]); + end; + end; + end; +end; + +procedure TSQLQuery.SetFilterText(const Value: string); +begin + if Value <> Filter then + begin + inherited SetFilterText(Value); + if active then ApplyFilter; + end; +end; + +procedure tsqlquery.refresh(const aparams: array of variant); +var + i1: int32; +begin + for i1:= 0 to high(aparams) do begin + params[i1].value:= aparams[i1]; + end; + if active then begin + inherited refresh(); + end + else begin + active:= true; + end; +end; + +procedure TSQLQuery.Prepare; +var + db: tcustomsqlconnection; + sqltr: tsqltransaction; + int1: integer; +const + endchars = ' '#$09#$0a#$0d; +begin + if not IsPrepared then begin + db:= tcustomsqlconnection(database); + sqltr:= tsqltransaction(transaction); + checkdatabase(name,db); + checktransaction(name,sqltr); + + if not Db.Connected then begin + db.Open; + end; + if not sqltr.Active then begin + sqltr.StartTransaction; + end; + + if not assigned(fcursor) then begin + FCursor:= Db.AllocateCursorHandle(icursorclient(self),name); + end; + fcursor.ftrans:= sqltr.handle; + + FSQLBuf:= TrimRight(FSQL.Text); + + if FSQLBuf = '' then begin + DatabaseError(SErrNoStatement); + end; + SQLParser(FSQLBuf); + + if filtered and (filter <> '') then begin + fsqlprepbuf:= AddFilter(FSQLBuf); + end + else begin + fsqlprepbuf:= fsqlbuf; + end; + if not (bdo_noprepare in foptions) then begin + Db.PrepareStatement(Fcursor,sqltr,fsqlprepBuf,FParams); + end; +// ftablename:= ''; + if (FCursor.FStatementType in datareturningtypes) then begin + FCursor.FInitFieldDef := True; + fupdateable:= not readonly and + ( + (sqs_userapplyrecupdate in fmstate) or + (fapplysql[ukmodify].count > 0) and + (fapplysql[ukinsert].count > 0) and + (fapplysql[ukdelete].count > 0) + ); + if fparsesql and (pos(',',FFromPart) <= 0) then begin + //don't change tablename otherwise + ftablename:= ansistring(ffrompart); + int1:= findchars(ftablename,endchars); + if int1 > 0 then begin + setlength(ftablename,int1-1); //use real name only + end; +// fupdateable:= not readonly; + end; + fupdateable:= fupdateable or not readonly and (ftablename <> ''); + end; + end; +end; + +procedure TSQLQuery.UnPrepare; + +begin + if connected then begin + CheckInactive; + end; + if IsPrepared and not (bs_refreshing in fbstate) then begin + with tcustomsqlconnection(Database) do begin + UnPrepareStatement(FCursor); + end; + end; +end; + +procedure TSQLQuery.FreeFldBuffers; +begin + if not (bs_refreshing in fbstate) and assigned(FCursor) then begin + tcustomsqlconnection(database).FreeFldBuffers(FCursor); + end; +end; + +function TSQLQuery.Fetch : boolean; +begin + if not (Fcursor.FStatementType in datareturningtypes) then begin + result:= false; + Exit; + end; + if not FIsEof then begin + FIsEOF:= not tcustomsqlconnection(database).Fetch(Fcursor); + if fiseof then begin + fcursor.close; + end; + end; + Result := not FIsEOF; +end; + +procedure TSQLQuery.Execute; +var +// int1: integer; + bo1: boolean; +begin + If (FParams.Count>0) and Assigned(FMasterLink) then begin + FMasterLink.CopyParamsFromMaster(False); + end; + bo1:= isutf8; + updateparams(fparams,bo1); + fcursor.ftrans:= tsqltransaction(ftransaction).handle; + if bdo_noprepare in foptions then begin + tcustomsqlconnection1(fdatabase).executeunprepared(fcursor, + tsqltransaction(ftransaction),fParams,fsqlprepbuf,bo1); + end + else begin + tcustomsqlconnection1(fdatabase).execute(fcursor, + tsqltransaction(ftransaction),fParams,bo1); + end; +// doexecute(fparams,ftransaction,fcursor,fdatabase,isutf8); +end; + +function tsqlquery.loadfield(const afieldno: integer; + const afieldtype: tfieldtype; const buffer: pointer; + var bufsize: integer): boolean; + //if bufsize < 0 -> buffer was to small, should be -bufsize +begin + result:= tcustomsqlconnection(database).LoadField(FCursor,aFieldtype, + afieldno,buffer,bufsize,isutf8) +end; + +procedure TSQLQuery.InternalAddRecord(Buffer: Pointer; AAppend: Boolean); +begin + // not implemented - sql dataset +end; + +procedure tsqlquery.freemodifyqueries; +var + k1: tupdatekind; +begin + fbstate:= fbstate - [bs_refreshinsert,bs_refreshupdate, + bs_refreshinsertindex,bs_refreshupdateindex]; + for k1:= low(tupdatekind) to high(tupdatekind) do begin + freeandnil(fapplyqueries[k1]); + end; + { + FreeAndNil(FUpdateQry); + FreeAndNil(FInsertQry); + FreeAndNil(FDeleteQry); + } +end; + +procedure tsqlquery.freequery; +begin + if not (bs_refreshing in fbstate) then begin + if ({not }IsPrepared) and (assigned(database)) and (assigned(FCursor)) then begin + tcustomsqlconnection(database).UnPrepareStatement(FCursor); + end; + if ftransactionwrite = nil then begin + freemodifyqueries; + end; + end; +end; + +procedure TSQLQuery.disconnect{(const aexecute: boolean)}; +begin + if bs_connected in fbstate then begin + if fcursor <> nil then begin + fcursor.close; + end; + freequery; + if not (bs_refreshing in fbstate) then begin + database.deallocatecursorhandle(fcursor); + end; + exclude(fbstate,bs_connected); + if faftercursorclose <> nil then begin + tcustomsqlstatement1(faftercursorclose).execute; +// faftercursorclose.execute(database,tsqltransaction(transaction)); + end; + end; +end; + +procedure TSQLQuery.InternalClose; +begin +// Database and FCursor could be nil, for example if the database is not +// assigned, and .open is called + try + disconnect{(true)}; + finally + if not (bs_refreshing in fbstate) then begin + freemodifyqueries; + fprimarykeyfield:= nil; + if DefaultFields then begin + DestroyFields; + end; + end; + fupdaterowsaffected:= 0; + fblobintf:= nil; +// if StatementType in datareturningtypes then FreeFldBuffers; + FIsEOF := False; + inherited internalclose; + end; +end; + +procedure TSQLQuery.InternalInitFieldDefs; +begin + if FLoadingFieldDefs then begin + Exit; + end; + FLoadingFieldDefs := True; + try + tcustomsqlconnection(database).AddFieldDefs(fcursor,FieldDefs); + finally + FLoadingFieldDefs := False; + end; +end; + +procedure tsqlquery.resetparsing; +begin + FWhereStartPos := 0; + FWhereStopPos := 0; + ffrompart:= ''; +// ftablename:= ''; +end; + +procedure TSQLQuery.SQLParser(var ASQL: msestring); + +type TParsePart = (ppStart,ppSelect,ppWhere,ppFrom,ppGroup,ppOrder,ppComment,ppBogus); + +Var + PSQL,CurrentP, + PhraseP, PStatementPart : pmsechar; + S : msestring; + ParsePart : TParsePart; + StrLength : Integer; + +begin + PSQL:=Pmsechar(ASQL); + ParsePart := ppStart; + PStatementPart:= nil; + CurrentP := PSQL-1; + PhraseP := PSQL; + resetparsing; + + repeat begin + inc(CurrentP); + + if SkipComments(CurrentP) then + if ParsePart = ppStart then PhraseP := CurrentP; + if (currentp^<#128) and + (char(byte(CurrentP^)) in [' ',#13,#10,#9,#0,'(',')',';']) then begin { if(1) } + if (CurrentP-PhraseP > 0) or (CurrentP^ = ';') or + (currentp^ = #0) then begin { if(2) } + strLength := CurrentP-PhraseP; + Setlength(S,strLength); + + if strLength > 0 then Move(PhraseP^,S[1],strLength*sizeof(msechar)); + s := uppercase(s); + + case ParsePart of + ppStart : begin + FCursor.FStatementType:= + tcustomsqlconnection1(database).StrToStatementType(s); + + if FCursor.FStatementType = stSelect then + ParsePart := ppSelect + else + break; + + if not FParseSQL then break; + PStatementPart := CurrentP; + end; {ppStart} + ppSelect : begin + if s = 'FROM' then begin + ParsePart := ppFrom; + PhraseP := CurrentP; + PStatementPart := CurrentP; + end; + end; {ppSelect} + ppFrom : begin + + if (s = 'WHERE') or (s = 'GROUP') or (s = 'ORDER') or (CurrentP^=#0) or (CurrentP^=';') then begin + if (s = 'WHERE') then begin + ParsePart := ppWhere; + StrLength := PhraseP-PStatementPart; + end else if (s = 'GROUP') then begin + ParsePart := ppGroup; + StrLength := PhraseP-PStatementPart + end else if (s = 'ORDER') then begin + ParsePart := ppOrder; + StrLength := PhraseP-PStatementPart + end else begin + ParsePart := ppBogus; + StrLength := CurrentP-PStatementPart; + end; + + Setlength(FFromPart,StrLength); + Move(PStatementPart^,FFromPart[1],StrLength*sizeof(msechar)); + FFrompart := trim(FFrompart); + FWhereStartPos := PStatementPart-PSQL+StrLength+1; + PStatementPart := CurrentP; + end; + + end; {ppFrom} + ppWhere : begin + if (s = 'GROUP') or (s = 'ORDER') or (CurrentP^=#0) or (CurrentP^=';') then begin + ParsePart := ppBogus; + FWhereStartPos := PStatementPart-PSQL; + + if (s = 'GROUP') or (s = 'ORDER') then + FWhereStopPos := PhraseP-PSQL+1 + else + FWhereStopPos := CurrentP-PSQL+1; + end; + end; + end; {ppWhere} + + end; {case} + + PhraseP := CurrentP+1; + end; { if(2) } + end; { if(1) } + until CurrentP^=#0; {repeat} + + if (FWhereStartPos > 0) and (FWhereStopPos > 0) and + filtered and (filter <> '') then begin + system.insert('(',ASQL,FWhereStartPos+1); + inc(FWhereStopPos); + system.insert(')',ASQL,FWhereStopPos); + end; + if not fparsesql and (fstatementtype <> stnone) then begin + fCursor.FStatementType := fstatementtype; + end; +//writeln(ASQL); +end; +(* +procedure TSQLQuery.SQLParser(var ASQL : string); + +type TParsePart = (ppStart,ppSelect,ppWhere,ppFrom,ppOrder,ppComment,ppBogus); + +Var + PSQL,CurrentP, + PhraseP, PStatementPart : pchar; + S : string; + ParsePart : TParsePart; + StrLength : Integer; + +begin + PSQL:=Pchar(ASQL); + ParsePart := ppStart; + + CurrentP := PSQL-1; + PhraseP := PSQL; + + FWhereStartPos := 0; + FWhereStopPos := 0; + + repeat + begin + inc(CurrentP); + + if CurrentP^ in [' ',#13,#10,#9,#0,'(',')',';'] then + begin + if (CurrentP-PhraseP > 0) or (CurrentP^ in [';',#0]) then + begin + strLength := CurrentP-PhraseP; + Setlength(S,strLength); + if strLength > 0 then Move(PhraseP^,S[1],(strLength)); + s := uppercase(s); + + case ParsePart of + ppStart : begin + FCursor.FStatementType := (Database as tcustomsqlconnection).StrToStatementType(s); + if FCursor.FStatementType = stSelect then ParsePart := ppSelect + else break; + if not FParseSQL then break; + PStatementPart := CurrentP; + end; + ppSelect : begin + if s = 'FROM' then + begin + ParsePart := ppFrom; + PhraseP := CurrentP; + PStatementPart := CurrentP; + end; + end; + ppFrom : begin + if (s = 'WHERE') or (s = 'ORDER') or (CurrentP^=#0) or (CurrentP^=';') then + begin + if (s = 'WHERE') then + begin + ParsePart := ppWhere; + StrLength := PhraseP-PStatementPart; + end + else if (s = 'ORDER') then + begin + ParsePart := ppOrder; + StrLength := PhraseP-PStatementPart + end + else + begin + ParsePart := ppBogus; + StrLength := CurrentP-PStatementPart; + end; + Setlength(FFromPart,StrLength); + Move(PStatementPart^,FFromPart[1],(StrLength)); + FFrompart := trim(FFrompart); + FWhereStartPos := PStatementPart-PSQL+StrLength+1; + PStatementPart := CurrentP; + end; + end; + ppWhere : begin + if (s = 'ORDER') or (CurrentP^=#0) or (CurrentP^=';') then + begin + ParsePart := ppBogus; + FWhereStartPos := PStatementPart-PSQL; + if s = 'ORDER' then + FWhereStopPos := PhraseP-PSQL+1 + else + FWhereStopPos := CurrentP-PSQL+1; + end; + end; + end; {case} + end; + PhraseP := CurrentP+1; + end + end; + until CurrentP^=#0; + if (FWhereStartPos > 0) and (FWhereStopPos > 0) then + begin + system.insert('(',ASQL,FWhereStartPos+1); + inc(FWhereStopPos); + system.insert(')',ASQL,FWhereStopPos); + end +end; +*) +{ +procedure TSQLQuery.InitUpdates(ASQL : string); +begin + if pos(',',FFromPart) > 0 then begin + FUpdateable:= (fsqlupdate.count > 0) and (fsqlinsert.count > 0) and + (fsqldelete.count > 0); + // select-statements from more then one table are not updateable + end + else begin + FUpdateable := True; + FTableName := FFromPart; + end; +end; +} + +procedure tsqlquery.connect(const aexecute: boolean); +var + tel{,fieldc}: integer; + f: TField; +// s: string; + ar1: stringarty; + IndexFields: stringarty; + str1: string; + int1: integer; + k1: tupdatekind; +begin + if database <> nil then begin + getcorbainterface(database,typeinfo(iblobconnection),fblobintf); + end; + if not streamloading then begin + try + Prepare; + if FCursor.FStatementType in datareturningtypes then begin + indexfields:= nil; + if FUpdateable then begin + if FusePrimaryKeyAsKey and not (bs_refreshing in fbstate) then begin + UpdateIndexDefs; //must be before execute because + //of MS SQL ODBC one statement per connection limitation + for tel := 0 to indexdefs.count-1 do begin + if ixPrimary in indexdefs[tel].options then begin + ar1:= nil; + splitstringquoted(indexdefs[tel].fields,ar1,'"',';'); + stackarray(ar1,indexfields); + end; + end; + end; + end; + + if aexecute then begin + if fbeforeexecute <> nil then begin + tcustomsqlstatement1(fbeforeexecute).execute; +// fbeforeexecute.execute(database,tsqltransaction(transaction)); + end; + Execute; + if FCursor.FInitFieldDef and not (bs_refreshing in fbstate) then begin + InternalInitFieldDefs; + end; + end; + if not (bs_refreshing in fbstate) then begin + if DefaultFields and aexecute then begin + CreateFields; + end; + for int1:= 0 to high(indexfields) do begin + F := Findfield(IndexFields[int1]); + if F <> nil then begin + F.optionsfield:= F.optionsfield + [of_InKey]; + end; + end; + if (database <> nil) and (ftablename <> '') then begin + str1:= tcustomsqlconnection1(database).getprimarykeyfield( + ftablename,fcursor); + if (str1 <> '') then begin + fprimarykeyfield:= fields.findfield(str1); + end; + end; + if fupdateable then begin + for k1:= low(tupdatekind) to high(tupdatekind) do begin + if fapplyqueries[k1] = nil then begin + fapplyqueries[k1]:= tsqlresult.create(nil); + with fapplyqueries[k1] do begin + transaction:= self.writetransaction; + database:= self.database; + sql.assign(fapplysql[k1]); + statementtype:= updatestatementtypes[k1]; + end; + end; + end; + end; + end; + end + else begin + DatabaseError(SErrNoSelectStatement,Self); + end; + except + on E:Exception do + raise; + end; + include(fbstate,bs_connected); + end; +end; + +procedure tsqlquery.internalopen; +{$ifdef mse_debugdataset} +var + ts: longword; +{$endif} +begin +{$ifdef mse_debugdataset} + debugoutstart(ts,self,'connect'); +{$endif} + connect(true); +{$ifdef mse_debugdataset} + debugoutend(ts,self,'connect'); +{$endif} +{$ifdef mse_debugdataset} + debugoutstart(ts,self,'internalopen'); +{$endif} + if fmasterlink <> nil then begin + checkrecursivedatasource(fmasterlink.datasource); + end; + inherited; +{$ifdef mse_debugdataset} + debugoutend(ts,self,'internalopen'); +{$endif} +end; + +procedure tsqlquery.dorefresh; +var + int1: integer; +begin + int1:= recno; + include(fbstate,bs_refreshing); + try + active:= false; + active:= true; + if (recno <> int1) and (bs_restorerecno in fbstate) then begin + setrecno1(int1,true); + end; + finally + exclude(fbstate,bs_refreshing); + if not active then begin + freefieldbuffers; + freequery; + end; + end; +end; + +procedure tsqlquery.refreshtransaction; +var + bo1: boolean; +begin + if not (bdo_notransactionrefresh in foptions) then begin + if bdo_recnotransactionrefresh in foptions then begin + bo1:= bs_restorerecno in fbstate; + include(fbstate,bs_restorerecno); + try + dorefresh; + finally + if not bo1 then begin + exclude(fbstate,bs_restorerecno); + end; + end; + end + else begin + dorefresh; + end; + end; +end; + +procedure tsqlquery.internalrefresh; +begin + if bdo_refreshtransaction in foptions then begin + if transaction.savepointlevel < 0 then begin + transaction.refresh; + end + else begin + transaction.pendingrefresh:= true; + end; + end + else begin + dorefresh; + end; +end; + +procedure TSQLQuery.ExecSQL; +begin + try + Prepare; + Execute; + finally + // FCursor has to be assigned, or else the prepare went wrong before PrepareStatment was + // called, so UnPrepareStatement shoudn't be called either + if (not IsPrepared) and (assigned(database)) and (assigned(FCursor)) then begin + (database as tcustomsqlconnection).UnPrepareStatement(Fcursor); + end; + end; +end; + +procedure TSQLQuery.SetReadOnly(AValue : Boolean); + +begin + CheckInactive; + freadonly:= avalue; +// if not AValue then +// begin +// if FParseSQL then FReadOnly := False +// else DatabaseErrorFmt(SNoParseSQL,['Updating ']); +// end +// else FReadOnly := True; +end; + +procedure TSQLQuery.SetParseSQL(AValue : Boolean); + +begin + CheckInactive; + if fparsesql <> avalue then begin + fparsesql:= avalue; + if not AValue then begin + Filtered:= False; + resetparsing; + end; + unprepare; //refresh sqlparser + end; +end; + +procedure tsqlquery.setstatementtype(const avalue: tstatementtype); +begin + CheckInactive; + if fstatementtype <> avalue then begin + fstatementtype:= avalue; + unprepare; //refresh sqlparser + end; +end; + +procedure TSQLQuery.SetUsePrimaryKeyAsKey(AValue : Boolean); + +begin + if not Active then FusePrimaryKeyAsKey := AValue + else + begin + // Just temporary, this should be possible in the future + DatabaseError(SActiveDataset); + end; +end; + +Procedure TSQLQuery.UpdateIndexDefs; + +begin + findexdefs.clear; + if assigned(DataBase) and (ftablename <> '') then begin + tcustomsqlconnection1(database).UpdateIndexDefs(FIndexDefs,FTableName,fcursor); + end; +end; + +procedure tsqlquery.updatewherepart(var sql_where : msestring; const afield: tfield); +var + quotechar: msestring; +begin + if database <> nil then begin + quotechar:= tcustomsqlconnection1(database).identquotechar; + end + else begin + quotechar:= '"'; + end; + with afield do begin + if (of_InKey in optionsfield) or + ((FUpdateMode = upWhereAll) and (of_InWhere in optionsfield)) or + ((FUpdateMode = UpWhereChanged) and + (of_InWhere in optionsfield) and + (value <> oldvalue)) then begin + sql_where := sql_where + '(' + quotechar+msestring(FieldName)+quotechar+ + '= :OLD_' + msestring(FieldName) + ') and '; + end; + end; +end; + +function tsqlquery.refreshrecquery(const update: boolean): msestring; +var + int1,int2: integer; +// intf1: imsefield; + field1: tfield; +// flags1: providerflags1ty; +begin + result:= ''; + int2:= 0; + for int1:= 0 to fields.count - 1 do begin + field1:= fields[int1]; + if (field1.fieldkind = fkdata) {and + getcorbainterface(field1,typeinfo(imsefield),intf1)} then begin +// flags1:= intf1.getproviderflags1; + if (of_refreshupdate in field1.optionsfield) and update or + (of_refreshinsert in field1.optionsfield) and not update then begin + if int2 = 0 then begin + result:= ' returning '; + end; + result:= result + msestring(field1.fieldname) + ','; + inc(int2); + if update then begin + if not (bs_refreshupdateindex in fbstate) and + indexlocal.hasfield(field1) then begin + include(fbstate,bs_refreshupdateindex); + end; + end + else begin + if not (bs_refreshinsertindex in fbstate) and + indexlocal.hasfield(field1) then begin + include(fbstate,bs_refreshinsertindex); + end; + end; + end; + end; + end; + if int2 > 0 then begin + if update then begin + include(fbstate,bs_refreshupdate); + end + else begin + include(fbstate,bs_refreshinsert); + end; + setlength(result,length(result)-1); + end + else begin + end; +end; + +procedure tsqlquery.checktablename; +begin + if ftablename = '' then begin + databaseerror('No table name in apply recupdate statement',self); + end; +end; + +function tsqlquery.updaterecquery : msestring; +var + x: integer; + sql_set: msestring; + sql_where: msestring; + field1: tfield; + quotechar: msestring; +begin + checktablename; + quotechar:= tcustomsqlconnection1(database).identquotechar; + sql_set:= ''; + sql_where:= ''; + for x := 0 to Fields.Count -1 do begin + field1:= fields[x]; + with field1 do begin + if fieldkind = fkdata then begin + UpdateWherePart(sql_where,field1); + if (of_InUpdate in optionsfield) then begin + sql_set:= sql_set + quotechar+msestring(FieldName)+quotechar + '=:' + + msestring(FieldName) + ','; + end; + end; + end; + end; + if sql_set = '' then begin + databaseerror('No "set" part in SQLUpdate statement.',self); + end; + if sql_where = '' then begin + databaseerror('No "where" part in SQLUpdate statement.',self); + end; + setlength(sql_set,length(sql_set)-1); + setlength(sql_where,length(sql_where)-5); + result := 'update ' + msestring(FTableName) + ' set ' + sql_set + + ' where ' + sql_where; + result:= result + refreshrecquery(true); +end; + + +function tsqlquery.insertrecquery: msestring; +var + x: integer; + sql_fields: msestring; + sql_values: msestring; + quotechar: msestring; +begin + checktablename; + quotechar:= tcustomsqlconnection1(database).identquotechar; + sql_fields := ''; + sql_values := ''; + for x := 0 to Fields.Count -1 do begin + with fields[x] do begin + if (fieldkind = fkdata) {and not IsNull} and + (of_InInsert in optionsfield) then begin + sql_fields:= sql_fields + quotechar+msestring(FieldName)+quotechar+ ','; + sql_values:= sql_values + ':' + msestring(FieldName) + ','; + end; + end; + end; + if sql_fields = '' then begin + databaseerror('No "values" part in SQLInsert statement.',self); + end; + setlength(sql_fields,length(sql_fields)-1); + setlength(sql_values,length(sql_values)-1); + result := 'insert into ' + msestring(FTableName) + + ' (' + sql_fields + ') values (' +sql_values + ')'; + result:= result + refreshrecquery(false); +end; + +function tsqlquery.deleterecquery : msestring; +var + x: integer; + sql_where: msestring; + field1: tfield; +begin + checktablename; + sql_where := ''; + for x := 0 to Fields.Count -1 do begin + field1:= fields[x]; + if field1.fieldkind = fkdata then begin + UpdateWherePart(sql_where,field1); + end; + end; + if sql_where = '' then begin + databaseerror('No "where" part in SQLDelete statement.',self); + end; + setlength(sql_where,length(sql_where)-5); + result := 'delete from ' + msestring(FTableName) + ' where ' + sql_where; +end; + +Procedure TSQLQuery.internalApplyRecUpdate(UpdateKind : TUpdateKind); +var + x: integer; + fld1: tfield; + param1,param2: tparam; + int1: integer; + blobspo: pblobinfoarty; + str1: string; + bo1: boolean; + freeblobar: pointerarty; + statementtypebefore: tstatementtype; + oldisnew: boolean; + rowsaffected1: integer; + +begin + oldisnew:= (updatekind = ukinsert) and (bs_inserttoupdate in fbstate); + if oldisnew then begin + updatekind:= ukmodify; + end; + blobspo:= getintblobpo; + if fapplyqueries[updatekind] = nil then begin + databaseerror(name+': No rec apply query for '+ + getenumname(typeinfo(tupdatekind),ord(updatekind))+'.'); + end; + with tsqlresult1(fapplyqueries[updatekind]) do begin + if sql.count = 0 then begin + case updatekind of + ukinsert: begin + sql.add(self.insertrecquery); + end; + ukmodify: begin + sql.add(self.updaterecquery); + end; + ukdelete: begin + sql.add(self.deleterecquery); + end; + end; + end; + futf8:= self.isutf8; + transaction.active:= true; + freeblobar:= nil; + try + for x := 0 to Params.Count-1 do begin + param1:= params[x]; + with param1 do begin + str1:= name; + bo1:= pos('OLD_',str1) = 1; + if bo1 then begin + str1:= copy(str1,5,bigint); + end; + if bo1 and not oldisnew then begin + fld1:= self.FieldByName(str1); + oldfieldtoparam(fld1,param1); + end + else begin + fld1:= self.findfield(str1); + if fld1 = nil then begin //search for param + param2:= self.params.findparam(str1); + if param2 = nil then begin + fieldbyname(str1); //raise exception + end + else begin + value:= param2.value; + end; + end + else begin //use field + if fld1 is tblobfield and (self.fblobintf <> nil) then begin + if fld1.isnull then begin + clear; + datatype:= fld1.datatype; + end + else begin + bo1:= false; + for int1:= 0 to high(blobspo^) do begin + if blobspo^[int1].field = fld1 then begin + self.fblobintf.writeblobdata(tsqltransaction(self.transaction), + self.ftablename,self.fcursor, + blobspo^[int1].data,blobspo^[int1].datalength,fld1,params[x],str1); + if str1 <> '' then begin + self.setdatastringvalue(fld1,str1); + additem(freeblobar,fld1); + end; + bo1:= true; + break; + end; + end; + if not bo1 then begin + self.fblobintf.setupblobdata(fld1,self.fcursor,params[x]); + end; + end; + end + else begin + self.fieldtoparam(fld1,param1); + end; + end; + end; + end; + end; + + if (updatekind = ukmodify) and + (bs_refreshupdate in self.fbstate) or + (updatekind = ukinsert) and + (bs_refreshinsert in self.fbstate) then begin + statementtypebefore:= statementtype; + try + statementtype:= stselect; + refresh; + if not eof then begin + for int1:= 0 to datacols.count - 1 do begin + with datacols[int1] do begin + fld1:= self.fields.fieldbyname(fieldname); + fld1.value:= asvariant; + end; + end; + end; + rowsaffected1:= fcursor.frowsaffected; + finally + clear; + statementtype:= statementtypebefore; + end; + end + else begin + execute; + rowsaffected1:= fcursor.frowsaffected; + end; + + if not (bs_refreshinsert in fbstate) and (updatekind = ukinsert) and + (self.fprimarykeyfield <> nil) then begin + tcustomsqlconnection1(database).updateprimarykeyfield( + self.fprimarykeyfield,transaction); + end; + if (self.fupdaterowsaffected < 0) or (rowsaffected1 < 0) then begin + self.fupdaterowsaffected:= rowsaffected1; + end + else begin + self.fupdaterowsaffected:= self.fupdaterowsaffected + rowsaffected1; + end; + { + if self.fupdaterowsaffected >= 0 then begin + if self.fcursor.frowsaffected < 0 then begin + self.fupdaterowsaffected:= -1; + end + else begin + inc(self.fupdaterowsaffected,rowsaffected1); + end; + end; + } + finally + for int1:= high(freeblobar) downto 0 do begin + deleteblob(blobspo^,tfield(freeblobar[int1]),true); + end; + end; + end; +end; + +Procedure TSQLQuery.ApplyRecUpdate(UpdateKind : TUpdateKind); +begin + internalapplyrecupdate(updatekind); +end; + +{ +Procedure TSQLQuery.ApplyRecUpdate(UpdateKind : TUpdateKind); + +var + s : string; + + procedure UpdateWherePart(var sql_where : string;x : integer); + + begin + if (pfInKey in Fields[x].ProviderFlags) or + ((FUpdateMode = upWhereAll) and (pfInWhere in Fields[x].ProviderFlags)) or + ((FUpdateMode = UpWhereChanged) and (pfInWhere in Fields[x].ProviderFlags) and (fields[x].value <> fields[x].oldvalue)) then + sql_where := sql_where + '(' + fields[x].FieldName + '= :OLD_' + fields[x].FieldName + ') and '; + end; + + function ModifyRecQuery : string; + + var x : integer; + sql_set : string; + sql_where : string; + + begin + sql_set := ''; + sql_where := ''; + for x := 0 to Fields.Count -1 do + begin + UpdateWherePart(sql_where,x); + + if (pfInUpdate in Fields[x].ProviderFlags) then + sql_set := sql_set + fields[x].FieldName + '=:' + fields[x].FieldName + ','; + end; + + setlength(sql_set,length(sql_set)-1); + setlength(sql_where,length(sql_where)-5); + result := 'update ' + FTableName + ' set ' + sql_set + ' where ' + sql_where; + + end; + + function InsertRecQuery : string; + + var x : integer; + sql_fields : string; + sql_values : string; + + begin + sql_fields := ''; + sql_values := ''; + for x := 0 to Fields.Count -1 do + begin + if not fields[x].IsNull then + begin + sql_fields := sql_fields + fields[x].FieldName + ','; + sql_values := sql_values + ':' + fields[x].FieldName + ','; + end; + end; + setlength(sql_fields,length(sql_fields)-1); + setlength(sql_values,length(sql_values)-1); + + result := 'insert into ' + FTableName + ' (' + sql_fields + ') values (' + sql_values + ')'; + end; + + function DeleteRecQuery : string; + + var x : integer; + sql_where : string; + + begin + sql_where := ''; + for x := 0 to Fields.Count -1 do + UpdateWherePart(sql_where,x); + + setlength(sql_where,length(sql_where)-5); + + result := 'delete from ' + FTableName + ' where ' + sql_where; + end; + +var qry : TSQLQuery; + x : integer; + Fld : TField; + +begin + case UpdateKind of + ukModify : begin + qry := FUpdateQry; + if trim(qry.sql.Text) = '' then qry.SQL.Add(ModifyRecQuery); + end; + ukInsert : begin + qry := FInsertQry; + if trim(qry.sql.Text) = '' then qry.SQL.Add(InsertRecQuery); + end; + ukDelete : begin + qry := FDeleteQry; + if trim(qry.sql.Text) = '' then qry.SQL.Add(DeleteRecQuery); + end; + end; + with qry do + begin + for x := 0 to Params.Count-1 do with params[x] do if leftstr(name,4)='OLD_' then + begin + Fld := self.FieldByName(copy(name,5,length(name)-4)); + AssignFieldValue(Fld,Fld.OldValue); + end + else + begin + Fld := self.FieldByName(name); + AssignFieldValue(Fld,Fld.Value); + end; + execsql; + end; +end; +} + +Function TSQLQuery.GetCanModify: Boolean; + +begin + if not connected then begin + result:= active and not freadonly; + end + else begin + if (fcursor <> nil) and + (FCursor.FStatementType in datareturningtypes) then begin + Result:= Active and + (FUpdateable or (bdo_noapply in foptions)) and (not FReadOnly) + end + else begin + Result:= False; + end; + end; +end; + +function TSQLQuery.GetIndexDefs : TIndexDefs; + +begin + Result := FIndexDefs; +end; + +procedure TSQLQuery.SetIndexDefs(AValue : TIndexDefs); + +begin + FIndexDefs := AValue; +end; + +procedure TSQLQuery.SetUpdateMode(AValue : TUpdateMode); + +begin + FUpdateMode := AValue; +end; +{ +procedure TSQLQuery.SetSchemaInfo( SchemaType : TSchemaType; SchemaObjectName, SchemaPattern : string); + +begin + ReadOnly := True; + SQL.Clear; + SQL.Add(tcustomsqlconnection1(database).GetSchemaInfoSQL( + SchemaType, SchemaObjectName, SchemaPattern)); +end; +} +function TSQLQuery.CreateBlobStream(Field: TField; Mode: TBlobStreamMode): TStream; +var + info: blobcacheinfoty; +// int1: integer; + blob1: blobinfoty; +begin + result:= inherited createblobstream(field,mode); + if result = nil then begin + if (bs_blobsfetched in fbstate) and (mode = bmread) then begin + info.id:= 0; //fieldsize can be 32 bit + if field.getdata(@info.id) and findcachedblob(info) then begin + blob1.data:= pointer(info.data); + blob1.datalength:= length(info.data); + result:= tblobcopy.create(blob1); + end; + end + else begin + if database = nil then begin + if mode = bmwrite then begin + result:= createblobbuffer(field); + end; + end + else begin + result:= tcustomsqlconnection1(database).CreateBlobStream(Field, + Mode,fcursor); + end; + end; + end; +end; +{ +function TSQLQuery.GetStatementType : TStatementType; + +begin + if assigned(FCursor) then Result := FCursor.FStatementType + else Result := stNone; +end; +} +procedure tsqlquery.checkrecursivedatasource(const avalue: tdatasource); +var + dso1: tdatasource; + ds1: tdataset; + int1: integer; +begin + dso1:= avalue; + int1:= 0; + while dso1 <> nil do begin + inc(int1); + if (dso1.dataset = self) or (int1 > 100) then begin + databaseerror('Recursive datasource.',self); + end; + ds1:= dso1.dataset; + if ds1 is tsqlquery then begin + dso1:= tsqlquery(ds1).datasource; + end + else begin + break; + end; + end; +end; + +Procedure TSQLQuery.SetDataSource(AVAlue : TDatasource); +Var + DS : TDatasource; +begin + checkrecursivedatasource(avalue); + DS:=DataSource; + If (AValue<>DS) then begin + If Assigned(DS) then begin + DS.RemoveFreeNotification(Self); + end; + If Assigned(AValue) then begin + AValue.FreeNotification(Self); + FMasterLink:= TsqlMasterParamsDataLink.Create(Self); + FMasterLink.Datasource:= AValue; + end + else begin + FreeAndNil(FMasterLink); + end; + end; +end; + +Function TSQLQuery.GetDataSource : TDatasource; + +begin + If Assigned(FMasterLink) then + Result:=FMasterLink.DataSource + else + Result:=Nil; +end; + +procedure tsqlquery.notification(acomponent: tcomponent; operation: toperation); +begin + inherited; + if operation = opremove then begin + if acomponent = datasource then begin + datasource:= nil; + end; + if acomponent = fbeforeexecute then begin + fbeforeexecute:= nil; + end; + if acomponent = faftercursorclose then begin + faftercursorclose:= nil; + end; + end; +end; + +function TSQLQuery.getblobdatasize: integer; +begin + if database = nil then begin + result:= sizeof(int64); //max + end + else begin + result:= tcustomsqlconnection1(database).getblobdatasize; + end; +end; + +function TSQLQuery.getdatabase1: tcustomsqlconnection; +begin + result:= tcustomsqlconnection(inherited database); +end; + +function tsqlquery.getdatabase: tcustomconnection; //for isqlpropertyeditor +begin + result:= database; +end; + +procedure TSQLQuery.setdatabase1(const avalue: tcustomsqlconnection); +begin + inherited database:= avalue; +end; +{ +procedure TSQLQuery.checkdatabase; +begin + docheckdatabase(name,fdatabase); + if inherited database = nil then begin + databaseerror(serrdatabasenassigned); + end; +end; +} +function TSQLQuery.executedirect(const asql: msestring): integer; +begin + checkdatabase(name,fdatabase); + result:= database.executedirect(asql,writetransaction); +end; + +procedure TSQLQuery.setparams(const avalue: TmseParams); +begin + fparams.assign(avalue); +end; + +function tsqlquery.getconnected: boolean; +begin + result:= bs_connected in fbstate; +// result:= (transaction <> nil) and transaction.active; +end; + +function tsqlquery.blobscached: boolean; +begin + result:= (fblobintf <> nil) and fblobintf.blobscached; +end; + +procedure TSQLQuery.setconnected(const avalue: boolean); +var + int1: integer; + uk1: tupdatekind; +begin //todo: check connect disconnect sequence + if not (bs_opening in fbstate) then begin + checkactive; + end; + if avalue <> connected then begin + if avalue then begin + closelogger; + connect(false); + end + else begin + if transaction.active then begin + fetchallblobs; + int1:= 0; + if (ftransactionwrite = nil) or (ftransactionwrite = ftransaction) then begin + for uk1:= low(tupdatekind) to high(tupdatekind) do begin + if fapplyqueries[uk1] <> nil then begin + inc(int1); + end; + end; + end; + tsqltransaction1(transaction).disconnect(self,int1); + disconnect{(false)}; + unprepare; + tcustomsqlconnection(database).DeAllocateCursorHandle(FCursor); + startlogger; + end; + end; + end; +end; + +procedure tsqlquery.setfsql(const avalue: tsqlstringlist); +begin + fsql.assign(avalue); +end; + +procedure tsqlquery.setfsqlupdate(const avalue: tupdatestringlist); +begin + fapplysql[ukmodify].assign(avalue); +end; + +procedure tsqlquery.setfsqlinsert(const avalue: tupdatestringlist); +begin + fapplysql[ukinsert].assign(avalue); +end; + +procedure tsqlquery.setfsqldelete(const avalue: tupdatestringlist); +begin + fapplysql[ukdelete].assign(avalue); +end; + +procedure TSQLQuery.setbeforeexecute(const avalue: tcustomsqlstatement); +begin + if fbeforeexecute <> nil then begin + fbeforeexecute.removefreenotification(self); + end; + fbeforeexecute:= avalue; + if fbeforeexecute <> nil then begin + fbeforeexecute.freenotification(self); + end; +end; + +procedure TSQLQuery.setaftercursorclose(const avalue: tcustomsqlstatement); +begin + if faftercursorclose <> nil then begin + faftercursorclose.removefreenotification(self); + end; + faftercursorclose:= avalue; + if faftercursorclose <> nil then begin + faftercursorclose.freenotification(self); + end; +end; + +function TSQLQuery.getnumboolean: boolean; +begin + result:= tcustomsqlconnection1(database).getnumboolean; +end; + +function TSQLQuery.getfloatdate: boolean; +begin + result:= tcustomsqlconnection1(database).getfloatdate; +end; + +function TSQLQuery.getint64currency: boolean; +begin + result:= tcustomsqlconnection1(database).getint64currency; +end; + +function TSQLQuery.getsqltransaction: tsqltransaction; +begin + result:= tsqltransaction(inherited transaction); +end; + +procedure TSQLQuery.setsqltransaction(const avalue: tsqltransaction); +begin + inherited transaction:= avalue; +end; + +function TSQLQuery.getsqltransactionwrite: tsqltransaction; +begin + result:= tsqltransaction(inherited transactionwrite); +end; + +procedure TSQLQuery.settransactionwrite(const avalue: tmdbtransaction); +begin + if avalue <> ftransactionwrite then begin + checkpendingupdates; + end; + inherited; +end; + +procedure TSQLQuery.setsqltransactionwrite(const avalue: tsqltransaction); +begin + inherited transactionwrite:= avalue; +end; + +procedure TSQLQuery.applyupdate(const cancelonerror: boolean; + const cancelondeleteerror: boolean = false; + const editonerror: boolean = false); +begin + fupdaterowsaffected:= 0; + inherited; +end; + +procedure TSQLQuery.applyupdates(const maxerrors: integer; + const cancelonerror: boolean; + const cancelondeleteerror: boolean = false; + const editonerror: boolean = false); +begin + fupdaterowsaffected:= 0; + if fdatabase = nil then begin + inherited; + end + else begin + tcustomsqlconnection1(fdatabase).beginupdate; + try + inherited; + finally + tcustomsqlconnection1(fdatabase).endupdate; + end; + end; +end; + +function TSQLQuery.writetransaction: tsqltransaction; +begin + result:= tsqltransaction(ftransactionwrite); + if result = nil then begin + result:= transaction; + end; +end; + +procedure TSQLQuery.dobeforeapplyupdate; +begin + inherited; + if writetransaction <> nil then begin + writetransaction.active:= true; + end; +end; + +function TSQLQuery.rowsreturned: integer; +begin + if active and (fcursor <> nil) then begin + result:= fcursor.frowsreturned; + end + else begin + result:= -1; + end; +end; + +function TSQLQuery.rowsaffected: integer; +begin + if active and (fcursor <> nil) then begin + result:= fcursor.frowsaffected; + end + else begin + result:= -1; + end; +end; + +procedure TSQLQuery.checkpendingupdates; +begin + //dummy +end; + +function TSQLQuery.stringmemo: boolean; +begin + result:= false; + //dummy +end; + +function TSQLQuery.isutf8: boolean; +begin + result:= futf8; +// if fdatabase <> nil then begin +// tcustomsqlconnection(fdatabase).updateutf8(result); +// end; +end; +{ +procedure TSQLQuery.dscontrolleroptionschanged(const aoptions: datasetoptionsty); +begin + fmasterlinkoptions:= []; + if dso_syncmasteredit in aoptions then begin + include(fmasterlinkoptions,mdlo_syncedit); + end; + if dso_syncmasterinsert in aoptions then begin + include(fmasterlinkoptions,mdlo_syncinsert); + end; + if dso_syncmasterdelete in aoptions then begin + include(fmasterlinkoptions,mdlo_syncdelete); + end; + if dso_delayeddetailpost in aoptions then begin + include(fmasterlinkoptions,mdlo_delayeddetailpost); + end; + if dso_syncinsertfields in aoptions then begin + include(fmasterlinkoptions,mdlo_syncinsertfields); + end; +end; +} +{ +procedure TSQLQuery.setmasterlink(const avalue: tsqlmasterparamsdatalink); +begin + fmasterlink.assign(avalue); +end; +} +procedure TSQLQuery.dobeforeedit; +begin + if (fmasterlink <> nil) then begin + fmasterlink.checkrefresh; + end; + inherited; +end; + +procedure TSQLQuery.dobeforeinsert; +begin + if (fmasterlink <> nil) then begin + fmasterlink.checkrefresh; + end; + inherited; +end; + +procedure TSQLQuery.settablename(const avalue: string); +begin + checkinactive; + ftablename:= avalue; +end; + +procedure TSQLQuery.dataevent(event: tdataevent; info: ptrint); +var + int1: integer; + sf,df: tfield; + str1: string; +begin + case event of + deupdaterecord: begin + if (mdlo_syncfields in foptionsmasterlink) and (fmasterlink <> nil) and + fmasterlink.active then begin + for int1:= 0 to fparams.count - 1 do begin + str1:= fparams[int1].name; + if (str1 <> '') then begin + df:= findfield(str1); + if df <> nil then begin + sf:= fmasterlink.dataset.findfield(str1); + if (sf <> nil) and (df.value <> sf.value) then begin + //no modified touch + df.value:= sf.value; + end; + end; + end; + end; + end; + end; + end; + inherited; +end; + +end. diff --git a/mseide-msegui/lib/common/db/msesqlresult.pas b/mseide-msegui/lib/common/db/msesqlresult.pas new file mode 100644 index 0000000..20ac0a0 --- /dev/null +++ b/mseide-msegui/lib/common/db/msesqlresult.pas @@ -0,0 +1,2458 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msesqlresult; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{$ifdef VER2_1_5} {$define mse_FPC_2_2} {$endif} +{$ifdef VER2_2} {$define mse_FPC_2_2} {$endif} +uses + classes,mclasses,mdb,msqldb,mseclasses,msedb,msedatabase,msearrayprops, + msestrings,msereal,mseinterfaces, + msetypes,mselookupbuffer,mseglob,msedatalist,msevariants,mseevent; +type + tsqlresult = class; + + tdbcol = class(tvirtualpersistent) + private + function getassql1: msestring; + function getasid: int64; + protected + fuppername: ansistring; + ffieldname: ansistring; + fsqlresult: tsqlresult; + fcursor: tsqlcursor; + fdatatype: tfieldtype; + ffieldnum: integer; + futf8: boolean; + fdatasize: integer; + function accesserror(const typename: string): edatabaseerror; + function getvariantvar: variant; virtual; + function getasvariant: variant; virtual; + function getasboolean: boolean; virtual; + function getascurrency: currency; virtual; + function getaslargeint: largeint; virtual; + function getasdatetime: tdatetime; virtual; + function getasdatetime1: tdatetime; virtual; + function getasfloat: double; virtual; + function getasfloat1: double; virtual; + function getasinteger: longint; virtual; + function getasstring: string; virtual; + function getasstring1: string; virtual; + function getasmsestring: msestring; virtual; + function getasmsestring1: msestring; virtual; + function getassql: msestring; virtual; + function getasguid: tguid; virtual; + function getisnull: boolean; virtual; + function loadfield(const buffer: pointer; var bufsize: integer): boolean; overload; + //false if null or inactive + function loadfield(const buffer: pointer): boolean; overload; + //false if null or inactive + public + constructor create(const asqlresult: tsqlresult; + const acursor: tsqlcursor; const afielddef: tfielddef); reintroduce; + property datatype: tfieldtype read fdatatype; + property fieldname: ansistring read ffieldname; + property size: integer read fdatasize; + + property asvariant: variant read getasvariant; + //empty variant returned for null fields + property asboolean: boolean read getasboolean; + property ascurrency: currency read getascurrency; + property aslargeint: largeint read getaslargeint; + property asdatetime: tdatetime read getasdatetime1; + property asfloat: double read getasfloat1; + property asinteger: longint read getasinteger; + property asstring: ansistring read getasstring1; + property asmsestring: msestring read getasmsestring1; + property assql: msestring read getassql1; + property asid: int64 read getasid; + property asguiid: tguid read getasguid; + property isnull: boolean read getisnull; + + end; + dbcolclassty = class of tdbcol; + dbcolarty = array of tdbcol; + + tstringdbcol = class(tdbcol) + private + protected + function getasmsestring1: msestring; override; + function getasmsestring: msestring; override; + function getasstring: ansistring; override; + function getasstring1: ansistring; override; + function getvariantvar: variant; override; + function getassql: msestring; override; + public + property value: msestring read getasmsestring; + end; + + tguiddbcol = class(tdbcol) + private + protected + function getasguid: tguid; override; + function getvariantvar: variant; override; + function getassql: msestring; override; + function getasstring: string; override; + end; + + tnumericdbcol = class(tdbcol) + private + protected + function getvariantvar: variant; override; + function getassql: msestring; override; + function getasstring: string; override; + function getasmsestring: msestring; override; + end; + + tlongintdbcol = class(tnumericdbcol) + protected + function getasinteger: integer; override; + public + property value: integer read getasinteger; + end; + + tlargeintdbcol = class(tnumericdbcol) + private + protected + function getaslargeint: largeint; override; + function getasinteger: integer; override; + function getvariantvar: variant; override; + function getassql: msestring; override; + function getasstring: string; override; + function getasmsestring: msestring; override; + public + property value: largeint read getaslargeint; + end; + + tsmallintdbcol = class(tnumericdbcol) + protected + function getasinteger: integer; override; + public + property value: integer read getasinteger; + end; + + tworddbcol = class(tnumericdbcol) + protected + function getasinteger: integer; override; + public + property value: integer read getasinteger; + end; + +// tautoincdbcol = class(tdbcol); + + tfloatdbcol = class(tdbcol) + private + protected + function getasfloat: double; override; + function getasfloat1: double; override; + function getascurrency: currency; override; + function getvariantvar: variant; override; + function getassql: msestring; override; + function getasstring: string; override; + function getasmsestring: msestring; override; + public + property value: double read getasfloat; + end; + + tcurrencydbcol = class(tdbcol) + private + protected + function getascurrency: currency; override; + function getasfloat: double; override; + function getvariantvar: variant; override; + function getassql: msestring; override; + function getasstring: string; override; + public + property value: currency read getascurrency; + end; + + tbooleandbcol = class(tdbcol) + private + protected + function getasboolean: boolean; override; + function getasinteger: integer; override; + function getvariantvar: variant; override; + function getassql: msestring; override; + function getasstring: string; override; + public + property value: boolean read getasboolean; + end; + + tdatetimedbcol = class(tfloatdbcol) + private + protected + function getasdatetime: tdatetime; override; + function getasdatetime1: tdatetime; override; + function getvariantvar: variant; override; + function getassql: msestring; override; + public + property value: tdatetime read getasdatetime; + end; + +// tdatedbcol = class(tdbcol); +// ttimedbcol = class(tdbcol); +// tbinarydbcol = class(tdbcol); +// tbytesdbcol = class(tdbcol); +// tvarbytesdbcol = class(tdbcol); +// tbcddbcol = class(tdbcol); + + tblobdbcol = class(tdbcol) + private + protected + function getasstring: ansistring; override; + function getvariantvar: variant; override; + function getassql: msestring; override; + public + property value: ansistring read getasstring; + end; + + tmemodbcol = class(tblobdbcol) + private + protected + function getvariantvar: variant; override; + function getassql: msestring; override; + public + property value: msestring read getasmsestring; + end; + + tvariantdbcol = class(tdbcol) + private + protected + function getvariantvar: variant; override; + public + property value: variant read getvariantvar; + end; + +// tgraphicdbcol = class(tdbcol); + + getnamefuncty = function:ansistring of object; + + tdbcols = class(tpersistentarrayprop) + private + fgetname: getnamefuncty; + function getitems(const index: integer): tdbcol; + procedure initfields(const asqlresult: tsqlresult; + const acursor: tsqlcursor; const afielddefs: tfielddefs); + public + constructor create(const agetname: getnamefuncty); + function findcol(const aname: ansistring): tdbcol; + function findcolindex(const aname: ansistring): integer; + function colbyname(const aname: ansistring): tdbcol; + function colsbyname(const anames: array of ansistring): dbcolarty; + //invalid after close! + function colsindexbyname(const anames: array of ansistring): integerarty; + property items[const index: integer]: tdbcol read getitems; default; + end; + +// tsqlresultfielddef = class; + + dbcolnamety = string; + + tsqlresultconnector = class(tmsecomponent) + private + fcol: tdbcol; +// ffielddef: tsqlresultfielddef; + fsource: tsqlresult; + fcolname: dbcolnamety; + function getcol: tdbcol; + procedure setsource(const avalue: tsqlresult); + procedure setcolname(const avalue: dbcolnamety); + protected + procedure objevent(const sender: iobjectlink; + const event: objecteventty); override; + public + destructor destroy; override; + property col: tdbcol read getcol; + published + property source: tsqlresult read fsource write setsource; + property colname: dbcolnamety read fcolname write setcolname; + end; +{ + tsqlresultfielddef = class(tfielddef) + destructor destroy; override; + private + fconnector: tsqlresultconnector; + procedure setconnector(const avalue: tsqlresultconnector); + published + property connector: tsqlresultconnector read fconnector write setconnector; + end; +} + tsqlresultfielddefs = class(tfielddefs) + private +// fsqlresult: tsqlresult; + protected + procedure setitemname(aitem: tcollectionitem); override; +// procedure bindconnectors; +// public +// constructor create(const aowner: tsqlresult); + end; + + sqlresultoptionty = (sro_utf8); + sqlresultoptionsty = set of sqlresultoptionty; + + sqlresulteventty = procedure(const sender: tsqlresult) of object; + + tsqlresult = class(tcursorsqlstatement,isqlpropertyeditor, + isqlclient,itransactionclient) + private +// fsql: tsqlstringlist; + fopenafterread: boolean; + factive: boolean; +// fdatabase: tcustomsqlconnection; +// ftransaction: tsqltransaction; +// fcursor: tsqlcursor; +// fparams: tmseparams; + ffielddefs: tsqlresultfielddefs; + fdatacols: tdbcols; + feof: boolean; + fbof: boolean; +// foptions: sqlresultoptionsty; + fbeforeopen: tmsesqlscript; + fafteropen: tmsesqlscript; + fonbeforeopen: sqlresulteventty; + fonafteropen: sqlresulteventty; + procedure setsql(const avalue: tsqlstringlist); + procedure setdatabase1(const avalue: tcustomsqlconnection); + function getsqltransaction: tsqltransaction; + procedure setsqltransaction(const avalue: tsqltransaction); + procedure setparams(const avalue: tmseparams); + procedure setbeforeopen(const avalue: tmsesqlscript); + procedure setafteropen(const avalue: tmsesqlscript); + procedure changed; + procedure setfielddefs(const avalue: tsqlresultfielddefs); + function getcols(const index: int32): tdbcol; + procedure setcols(const index: int32; const avalue: tdbcol); + protected + procedure dosqlchange(const sender : tobject); override; + function getactive: boolean; override; + procedure setactive(avalue: boolean); override; + procedure loaded; override; + procedure freefldbuffers; +// function isprepared: boolean; + procedure doclear(const isclose: boolean); + procedure checkautocommit; override; +// procedure execute; + //itransactionclient + procedure settransaction(const avalue: tmdbtransaction); + procedure settransactionwrite(const avalue: tmdbtransaction); + procedure savepointevent(const sender: tmdbtransaction; + const akind: savepointeventkindty; const alevel: integer); + //isqlclient + procedure setdatabase(const avalue: tmdatabase); + function getname: ansistring; + function gettransaction: tmdbtransaction; + function getrecno: integer; + procedure setrecno(value: integer); + procedure disablecontrols; + procedure enablecontrols; + function moveby(distance: longint): longint; + function getsqltransactionwrite: tsqltransaction; + procedure setsqltransactionwrite(const avalue: tsqltransaction); + procedure checkbrowsemode; + procedure refreshtransaction; + procedure internalloaddatalists(const acols: integerarty; + const datalists: array of tdatalist); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; +// function isutf8: boolean; + procedure prepare; override; + procedure unprepare; override; + procedure open(const aparams: array of variant); + procedure open(); + procedure close; + procedure clear; //frees buffers, does not unprepare + procedure refresh(const aparams: array of variant); + procedure refresh; + procedure next; + function countrest(): int32; //including current record + function rowsaffected: integer; //-1 if not supported + function rowsreturned: integer; //-1 if not supported +// procedure asvariant(out avalue: variant); overload; //internal compiler error + function asvariant(const aclose: boolean = false): variant; + //value of first field of first row, + //empty variant returned for null fields + function asvariantar(const aclose: boolean = false): variantarty; + //first row, empty variant returned for null fields + function asvariantarar(const aclose: boolean = false): variantararty; + //whole resultset, empty variant returned for null fields + procedure loaddatalists(const datalists: array of tdatalist); + property datacols: tdbcols read fdatacols; + property cols[const index: int32]: tdbcol read getcols write setcols; default; + property bof: boolean read fbof; + property eof: boolean read feof; + published +// property params : tmseparams read fparams write setparams; //before sql property + +// property sql: tsqlstringlist read fsql write setsql; + property beforeopen: tmsesqlscript read fbeforeopen write setbeforeopen; + property afteropen: tmsesqlscript read fafteropen write setafteropen; +// property database: tcustomsqlconnection read fdatabase write setdatabase1; +// property transaction: tsqltransaction read getsqltransaction +// write setsqltransaction; + property active: boolean read getactive write setactive default false; +// property options: sqlresultoptionsty read foptions write foptions default []; + property fielddefs: tsqlresultfielddefs read ffielddefs write setfielddefs; + property onbeforeopen: sqlresulteventty read fonbeforeopen write fonbeforeopen; + property onafteropen: sqlresulteventty read fonafteropen write fonafteropen; + + property params; + property sql; + property database; + property transaction; + property options; + property statementtype default stselect; + property onbeforeexecute; + property onafterexecute; + property onerror; + end; + + idbcolinfo = interface(inullinterface)[miid_idbcolinfo] + function getsqlresult(const aindex: integer): tsqlresult; + procedure getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); + end; + + getsqlresultfuncty = function(const aindex: integer): tsqlresult of object; + + tdbcolnamearrayprop = class(tstringarrayprop,idbcolinfo) + private + ffieldtypes: fieldtypesty; + fgetsqlresult: getsqlresultfuncty; + protected + //idbcolinfo + function getsqlresult(const aindex: integer): tsqlresult; + procedure getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); + public + constructor create(const afieldtypes: fieldtypesty; + const agetsqlresult: getsqlresultfuncty); + property fieldtypes: fieldtypesty read ffieldtypes write ffieldtypes; + end; + + lbsqoptionty = (olbsq_closesqlresult); + lbsqoptionsty = set of lbsqoptionty; + + tsqllookupbuffer = class(tdatalookupbuffer) + private + fsource: tsqlresult; + ftextcols: tdbcolnamearrayprop; + fintegercols: tdbcolnamearrayprop; + fint64cols: tdbcolnamearrayprop; + ffloatcols: tdbcolnamearrayprop; + foptionsdb: lbsqoptionsty; + procedure setsource(const avalue: tsqlresult); + function getsqlresult(const aindex: integer): tsqlresult; + procedure settextcols(const avalue: tdbcolnamearrayprop); + procedure setintegercols(const avalue: tdbcolnamearrayprop); + procedure setint64cols(const avalue: tdbcolnamearrayprop); + procedure setfloatcols(const avalue: tdbcolnamearrayprop); + protected + function getfieldcounttext: integer; override; + function getfieldcountinteger: integer; override; + function getfieldcountint64: integer; override; + function getfieldcountfloat: integer; override; + procedure setfieldcounttext(const avalue: integer); override; + procedure setfieldcountinteger(const avalue: integer); override; + procedure setfieldcountint64(const avalue: integer); override; + procedure setfieldcountfloat(const avalue: integer); override; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + procedure doloadbuffer; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function fieldnamestext: stringarty; override; + function fieldnamesfloat: stringarty; override; + function fieldnamesinteger: stringarty; override; + function fieldnamesint64: stringarty; override; + procedure clearbuffer; override; + published + property source: tsqlresult read fsource write setsource; + property textcols: tdbcolnamearrayprop read ftextcols write settextcols; + property integercols: tdbcolnamearrayprop read fintegercols write setintegercols; + property int64cols: tdbcolnamearrayprop read fint64cols write setint64cols; + property floatcols: tdbcolnamearrayprop read ffloatcols write setfloatcols; + property optionsdb: lbsqoptionsty read foptionsdb write foptionsdb default []; + end; + +//empty variant returned for null fields +procedure getsqlresult(out avalue: variant; const atransaction: tsqltransaction; + const asql: msestring; const aparams: array of variant); overload; + //first field of first row +procedure getsqlresult(out avalue: variantarty; const atransaction: tsqltransaction; + const asql: msestring; const aparams: array of variant); overload; + //first row +procedure getsqlresult(out avalue: variantararty; const atransaction: tsqltransaction; + const asql: msestring; const aparams: array of variant); overload; + //whole resultset +procedure getsqlresult(const avalues: array of tdatalist; + const atransaction: tsqltransaction; const asql: msestring; + const aparams: array of variant); overload; + //whole resultset +function getsqlresultvar( const atransaction: tsqltransaction; + const asql: msestring; + const aparams: array of variant): variant; +function getsqlresultvarar( const atransaction: tsqltransaction; + const asql: msestring; + const aparams: array of variant): variantarty; +function getsqlresultvararar( const atransaction: tsqltransaction; + const asql: msestring; + const aparams: array of variant): variantararty; + +implementation +uses + sysutils,{$ifdef FPC}dbconst{$else}dbconst_del,classes_del{$endif},rtlconsts, + mseapplication,variants,mseformatstr,msefloattostr; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +const + msedbcoltypeclasses: array[fieldclasstypety] of dbcolclassty = +// ft_unknown,ft_string, ft_guid, ft_numeric, + (tdbcol, tstringdbcol,tguiddbcol,tlongintdbcol, +// ft_longint, ft_largeint, ft_smallint, + tlongintdbcol,tlargeintdbcol,tsmallintdbcol, +// ft_word, ft_autoinc, ft_float, ft_currency, ft_boolean, + tworddbcol,tlongintdbcol,tfloatdbcol,tcurrencydbcol,tbooleandbcol, +// ft_datetime, ft_date, ft_time, + tdatetimedbcol,tdatetimedbcol,tdatetimedbcol, +// ft_binary,ft_bytes, ft_varbytes, + tdbcol, tstringdbcol, tstringdbcol, +// ft_bcd, ft_blob, ft_memo, ft_graphic, ft_variant); + tcurrencydbcol,tblobdbcol,tmemodbcol,tblobdbcol,tvariantdbcol); + SBoolean = 'Boolean'; + SDateTime = 'TDateTime'; + SFloat = 'Float'; + SInteger = 'Integer'; + SLargeInt = 'LargeInt'; + SVariant = 'Variant'; + SString = 'String'; +type + tdatalist1 = class(tdatalist); +// tcursorsqlstatement1 = class(tcursorsqlstatement); + +function dogetsqlresult(const atransaction: tsqltransaction; const asql: msestring; + const aparams: array of variant): tsqlresult; +var + int1: integer; +begin + result:= tsqlresult.create(nil); + try + result.database:= atransaction.database; + result.transaction:= atransaction; + result.sql.text:= asql; + result.prepare; + for int1:= 0 to high(aparams) do begin + result.params[int1].value:= aparams[int1]; + end; + except + result.free; + raise + end; +end; + +procedure getsqlresult(out avalue: variant; const atransaction: tsqltransaction; + const asql: msestring; const aparams: array of variant); overload; + //first field of first row +var + sqlresult: tsqlresult; +begin + sqlresult:= dogetsqlresult(atransaction,asql,aparams); + try +// sqlresult.asvariant(avalue); //internal error 2006122804 + avalue:= sqlresult.asvariant; + finally + sqlresult.free; + end; +end; + +procedure getsqlresult(out avalue: variantarty; const atransaction: tsqltransaction; + const asql: msestring; const aparams: array of variant); overload; + //first row +var + sqlresult: tsqlresult; +begin + sqlresult:= dogetsqlresult(atransaction,asql,aparams); + try + avalue:= sqlresult.asvariantar; + finally + sqlresult.free; + end; +end; + +procedure getsqlresult(out avalue: variantararty; const atransaction: tsqltransaction; + const asql: msestring; const aparams: array of variant); overload; + //whole resultset +var + sqlresult: tsqlresult; +begin + sqlresult:= dogetsqlresult(atransaction,asql,aparams); + try + avalue:= sqlresult.asvariantarar; + finally + sqlresult.free; + end; +end; + +procedure getsqlresult(const avalues: array of tdatalist; + const atransaction: tsqltransaction; const asql: msestring; + const aparams: array of variant); overload; + //whole resultset +var + sqlresult: tsqlresult; +begin + sqlresult:= dogetsqlresult(atransaction,asql,aparams); + try + sqlresult.loaddatalists(avalues); + finally + sqlresult.free; + end; +end; + +function getsqlresultvar( const atransaction: tsqltransaction; + const asql: msestring; + const aparams: array of variant): variant; +begin + getsqlresult(result,atransaction,asql,aparams); +end; + +function getsqlresultvarar( const atransaction: tsqltransaction; + const asql: msestring; + const aparams: array of variant): variantarty; +begin + getsqlresult(result,atransaction,asql,aparams); +end; + +function getsqlresultvararar( const atransaction: tsqltransaction; + const asql: msestring; + const aparams: array of variant): variantararty; +begin + getsqlresult(result,atransaction,asql,aparams); +end; + + +{ tdbcol } + +constructor tdbcol.create(const asqlresult: tsqlresult; + const acursor: tsqlcursor; const afielddef: tfielddef); +begin + fsqlresult:= asqlresult; + fcursor:= acursor; + ffieldname:= afielddef.name; + fuppername:= uppercase(ffieldname); + fdatatype:= afielddef.datatype; + ffieldnum:= afielddef.fieldno-1; + fdatasize:= afielddef.size; //used for stringcol + futf8:= asqlresult.isutf8; + inherited create; +end; + +function tdbcol.accesserror(const typename: string): edatabaseerror; +begin + result:= edatabaseerror.createfmt(sinvalidtypeconversion,[typename,ffieldname]); +end; + +function tdbcol.getvariantvar: variant; +begin + raise accesserror('variant'); + result:= 0; //compiler warning; +end; + +function tdbcol.getasvariant: variant; +begin + if isnull then begin + result:= null;//unassigned; + end + else begin + result:= getvariantvar; + end; +end; + +function tdbcol.getasboolean: boolean; +begin + result:= getasinteger <> 0; +end; + +function tdbcol.getascurrency: currency; +begin + result:= getasfloat; +end; + +function tdbcol.getaslargeint: largeint; +begin + result:= getasinteger; +end; + +function tdbcol.getasdatetime: tdatetime; +begin + raise accesserror(sdatetime); + result:= 0; //compiler warning; +end; + +function tdbcol.getasfloat: double; +begin + result:= getaslargeint; +end; + +function tdbcol.getasinteger: longint; +begin + raise accesserror(sinteger); + result:= 0; //compiler warning; +end; + +function tdbcol.getasstring: string; +begin + raise accesserror(sstring); + result:= ''; //compiler warning; +end; + +function tdbcol.getasmsestring: msestring; +var + str1: ansistring; +begin + str1:= getasstring; + if futf8 then begin + result:= utf8tostringansi(str1); + end + else begin + result:= msestring(str1); + end; +end; + +function tdbcol.getassql: msestring; +begin + raise accesserror('SQL'); + result:= ''; //compiler warning; +end; + +function tdbcol.getasguid: tguid; +begin + raise accesserror('Guid'); + result:= guid_null; //compiler warning; +end; + +function tdbcol.getassql1: msestring; +begin + if isnull then begin + result:= 'NULL'; + end + else begin + result:= getassql; + end; +end; + +function tdbcol.getisnull: boolean; +var + int1: integer; +begin + int1:= 0; + result:= not fsqlresult.active or fsqlresult.eof or + not fsqlresult.database.loadfield(fsqlresult.fcursor, + fdatatype,ffieldnum,nil,int1,false); +end; + +function tdbcol.loadfield(const buffer: pointer; var bufsize: integer): boolean; +begin + result:= fsqlresult.active; + if result then begin + result:= fsqlresult.fdatabase.loadfield(fsqlresult.fcursor, + fdatatype,ffieldnum,buffer,bufsize,futf8); + end; +end; + +function tdbcol.loadfield(const buffer: pointer): boolean; +var + int1: integer; +begin + int1:= 0; + result:= fsqlresult.active; + if result then begin + result:= fsqlresult.fdatabase.loadfield(fsqlresult.fcursor, + fdatatype,ffieldnum,buffer,int1,futf8); + end; +end; + +function tdbcol.getasid: int64; +begin + if isnull then begin + result:= -1; + end + else begin + result:= getaslargeint; + end; +end; + +function tdbcol.getasdatetime1: tdatetime; +begin + if isnull then begin + result:= emptydatetime; + end + else begin + result:= getasdatetime; + end; +end; + +function tdbcol.getasfloat1: double; +begin + if isnull then begin + result:= emptyreal; + end + else begin + result:= getasfloat; + end; +end; + +function tdbcol.getasstring1: string; +begin + if isnull then begin + result:= ''; + end + else begin + result:= getasstring; + end; +end; + +function tdbcol.getasmsestring1: msestring; +begin + if isnull then begin + result:= ''; + end + else begin + result:= getasmsestring; + end; +end; + +{ tlongintdbcol } + +function tlongintdbcol.getasinteger: integer; +begin + if not loadfield(@result) then begin + result:= 0; + end; +end; + +{ tlargeintdbcol } + +function tlargeintdbcol.getaslargeint: largeint; +begin + if not loadfield(@result) then begin + result:= 0; + end; +end; + +function tlargeintdbcol.getasinteger: integer; +begin + result:= getaslargeint; +end; + +function tlargeintdbcol.getvariantvar: variant; +begin + result:= aslargeint; +end; + +function tlargeintdbcol.getassql: msestring; +begin + result:= encodesqllargeint(aslargeint); +end; + +function tlargeintdbcol.getasstring: string; +begin + result:= inttostr(aslargeint); +end; + +function tlargeintdbcol.getasmsestring: msestring; +begin + result:= inttostrmse(aslargeint); +end; + +{ tsmallintdbcol } + +function tsmallintdbcol.getasinteger: integer; +var + buf: smallint; +begin + if not loadfield(@buf) then begin + result:= 0; + end + else begin + result:= buf; + end; +end; + +{ tworddbcol } + +function tworddbcol.getasinteger: integer; +var + buf: word; +begin + if not loadfield(@buf) then begin + result:= 0; + end + else begin + result:= buf; + end; +end; + +{ tfloatdbcol } + +function tfloatdbcol.getasfloat: double; +begin + if not loadfield(@result) then begin + result:= emptyreal; + end; +end; + +function tfloatdbcol.getasfloat1: double; +begin + result:= getasfloat; +end; + +function tfloatdbcol.getascurrency: currency; +var + do1: double; +begin + if not loadfield(@do1) then begin + result:= 0; + end + else begin + result:= do1; + end; +end; + +function tfloatdbcol.getvariantvar: variant; +begin + result:= asfloat; +end; + +function tfloatdbcol.getassql: msestring; +begin + result:= encodesqlfloat(asfloat); +end; + +function tfloatdbcol.getasstring: string; +begin + result:= ansistring(getasmsestring); +end; + +function tfloatdbcol.getasmsestring: msestring; +begin + result:= doubletostring(asfloat,0); +end; + +{ tcurrencydbcol } + +function tcurrencydbcol.getascurrency: currency; +begin + if not loadfield(@result) then begin + result:= 0; + end; +end; + +function tcurrencydbcol.getasfloat: double; +begin + result:= getascurrency; +end; + +function tcurrencydbcol.getvariantvar: variant; +begin + result:= ascurrency; +end; + +function tcurrencydbcol.getassql: msestring; +begin + result:= encodesqlcurrency(ascurrency); +end; + +function tcurrencydbcol.getasstring: string; +begin + result:= currtostr(ascurrency); +end; + +{ tbooleandbcol } + +function tbooleandbcol.getasboolean: boolean; +var + buf: wordbool; +begin + if not loadfield(@buf) then begin + result:= false; + end + else begin + result:= buf; + end; +end; + +function tbooleandbcol.getasinteger: integer; +begin + if getasboolean() then begin + result:= 1; + end + else begin + result:= 0; + end; +end; + +function tbooleandbcol.getvariantvar: variant; +begin + result:= asboolean; +end; + +function tbooleandbcol.getassql: msestring; +begin + result:= encodesqlboolean(asboolean); +end; + +function tbooleandbcol.getasstring: string; +begin + if getasboolean then begin + result:= '1'; + end + else begin + result:= '0'; + end; +end; + +{ tdatetimedbcol } + +function tdatetimedbcol.getasdatetime: tdatetime; +begin + if not loadfield(@result) then begin + result:= emptydatetime; + end +end; + +function tdatetimedbcol.getvariantvar: variant; +begin + result:= asdatetime; +end; + +function tdatetimedbcol.getassql: msestring; +begin + result:= encodesqldatetime(asdatetime); +end; + +function tdatetimedbcol.getasdatetime1: tdatetime; +begin + result:= getasdatetime; +end; + +{ tstringdbcol } + +function tstringdbcol.getasstring: ansistring; +var + int1: integer; +begin + if fdatatype in widecharfields then begin + result:= ansistring(getasmsestring); + end + else begin + int1:= fdatasize; + if not (fdatatype in [ftbytes,ftvarbytes]) then begin + int1:= int1*4+4; //room for multibyte encodings + end; + setlength(result,int1); + if not loadfield(pointer(result),int1) then begin + result:= ''; + end + else begin + if int1 < 0 then begin //too small + int1:= -int1; + setlength(result,int1); + loadfield(pointer(result),int1); + end; + setlength(result,int1); + if fdatatype = ftvarbytes then begin + int1:= int1 - sizeof(word); + move((pchar(pointer(result))+sizeof(word))^,(pchar(pointer(result)))^,int1); + setlength(result,int1); + end; + end; + end; +end; + +function tstringdbcol.getasmsestring: msestring; +var + int1: integer; +begin + if fdatatype in widecharfields then begin + int1:= fdatasize*2+4; //room for multibyte encodings + setlength(result,int1); + if not loadfield(pointer(result),int1) then begin + result:= ''; + end + else begin + if int1 < 0 then begin //too small + int1:= -int1; + setlength(result,(int1+1) div 2); + loadfield(pointer(result),int1); + end; + setlength(result,int1 div 2); + end; + end + else begin + result:= inherited getasmsestring; + end; +end; + +function tstringdbcol.getvariantvar: variant; +begin + result:= asmsestring; +end; + +function tstringdbcol.getassql: msestring; +begin + result:= encodesqlstring(asmsestring); +end; + +function tstringdbcol.getasstring1: ansistring; +begin + result:= getasstring; +end; + +function tstringdbcol.getasmsestring1: msestring; +begin + result:= getasmsestring; +end; + +{ tblobdbcol } + +function tblobdbcol.getasstring: ansistring; +begin + with fsqlresult do begin + if active then begin + result:= fdatabase.fetchblob(fcursor,ffieldnum); + end + else begin + result:= ''; + end; + end; +end; + +function tblobdbcol.getvariantvar: variant; +begin + result:= asstring; +end; + +function tblobdbcol.getassql: msestring; +begin + result:= encodesqlblob(asstring); +end; + +{ tguiddbcol } + +function tguiddbcol.getvariantvar: variant; +begin + result:= asstring; +end; + +function tguiddbcol.getassql: msestring; +begin + result:= encodesqlstring(msestring(asstring)); +end; + +function tguiddbcol.getasstring: string; +var + id1: tguid; +begin + if not loadfield(@id1) then begin + result:= ''; + end + else begin + result:= dbguidtostring(id1); + end; +end; + +function tguiddbcol.getasguid: tguid; +begin + if not loadfield(@result) then begin + result:= guid_null; + end; +end; + +{ tnumericdbcol } + +function tnumericdbcol.getvariantvar: variant; +begin + result:= asinteger; +end; + +function tnumericdbcol.getassql: msestring; +begin + result:= encodesqlinteger(asinteger); +end; + +function tnumericdbcol.getasstring: string; +begin + result:= inttostr(asinteger); +end; + +function tnumericdbcol.getasmsestring: msestring; +begin + result:= inttostrmse(asinteger); +end; + +{ tmemodbcol } + +function tmemodbcol.getvariantvar: variant; +begin + result:= asmsestring; +end; + +function tmemodbcol.getassql: msestring; +begin + result:= encodesqlstring(asmsestring); +end; + +{ tvariantdbcol } + +function tvariantdbcol.getvariantvar: variant; +begin + if not loadfield(@result) then begin + result:= null; + end; +end; + +{ tdbcols } + +constructor tdbcols.create(const agetname: getnamefuncty); +begin + fgetname:= agetname; + inherited create(tdbcol); +end; + +function tdbcols.getitems(const index: integer): tdbcol; +begin + result:= tdbcol (inherited getitems(index)); +end; + +procedure tdbcols.initfields(const asqlresult: tsqlresult; + const acursor: tsqlcursor; const afielddefs: tfielddefs); +var + int1: integer; + fdef1: tfielddef; +begin + for int1:= 0 to afielddefs.count - 1 do begin + fdef1:= afielddefs[int1]; + add(msedbcoltypeclasses[tfieldtypetotypety[fdef1.datatype]]. + create(asqlresult,acursor,fdef1)); + end; +end; + +function tdbcols.findcol(const aname: ansistring): tdbcol; +var + str1: ansistring; + int1: integer; +begin + str1:= uppercase(aname); + for int1:= 0 to high(fitems) do begin + result:= tdbcol(fitems[int1]); + if result.fuppername = str1 then begin + exit; + end; + end; + result:= nil; +end; + +function tdbcols.findcolindex(const aname: ansistring): integer; +var + str1: ansistring; + int1: integer; +begin + result:= -1; + str1:= uppercase(aname); + for int1:= 0 to high(fitems) do begin + with tdbcol(fitems[int1]) do begin + if fuppername = str1 then begin + result:= int1; + exit; + end; + end; + end; +end; + +function tdbcols.colbyname(const aname: ansistring): tdbcol; +begin + result:= findcol(aname); + if result = nil then begin + raise edatabaseerror.create(fgetname()+': col "'+aname+'" not found.'); + end; +end; + +function tdbcols.colsbyname(const anames: array of ansistring): dbcolarty; +var + int1: integer; +begin + setlength(result,high(anames)+1); + for int1:= 0 to high(result) do begin + result[int1]:= colbyname(anames[int1]); + end; +end; + +function tdbcols.colsindexbyname(const anames: array of ansistring): integerarty; +var + int1: integer; +begin + setlength(result,high(anames)+1); + for int1:= 0 to high(result) do begin + result[int1]:= findcolindex(anames[int1]); + if result[int1] < 0 then begin + raise edatabaseerror.create(fgetname()+': col "'+anames[int1]+'" not found.'); + end; + end; +end; + +{ tsqlresult } + +constructor tsqlresult.create(aowner: tcomponent); +begin + fbof:= true; + feof:= true; +// fparams:= tmseparams.create(self); + fdatacols:= tdbcols.create({$ifdef FPC}@{$endif}getname); + ffielddefs:= tsqlresultfielddefs.create(nil); +// fsql:= tsqlstringlist.create; +// fsql.onchange:= @onchangesql; + inherited; + statementtype:= stselect; +end; + +destructor tsqlresult.destroy; +begin + active:= false; + database:= nil; + transaction:= nil; + inherited; +// fsql.free; +// fparams.free; + ffielddefs.free; + fdatacols.free; +end; + +procedure tsqlresult.setsql(const avalue: tsqlstringlist); +begin + fsql.assign(avalue); +end; + +function tsqlresult.getactive: boolean; +begin + result:= factive; +end; + +procedure tsqlresult.setactive(avalue: boolean); +begin + if csreading in componentstate then begin + fopenafterread:= avalue; + end + else begin + if factive <> avalue then begin + if avalue then begin + open; + end + else begin + fopenafterread:= false; + close; + end; + end + else begin + if not avalue then begin + inherited setactive(false); //free cursor for exec call + end; + end; + end; +end; +{ +function tsqlresult.isutf8: boolean; +begin + result:= (sro_utf8 in foptions); + if fdatabase <> nil then begin + fdatabase.updateutf8(result); + end; +end; +} +procedure tsqlresult.setdatabase1(const avalue: tcustomsqlconnection); +begin + setdatabase(avalue); +end; + +procedure tsqlresult.setdatabase(const avalue: tmdatabase); +begin + dosetsqldatabase(isqlclient(self),avalue,fcursor,tmdatabase(fdatabase)); +end; + +function tsqlresult.getname: ansistring; +begin + result:= name; +end; + +function tsqlresult.getsqltransaction: tsqltransaction; +begin + result:= ftransaction; +end; + +procedure tsqlresult.setsqltransaction(const avalue: tsqltransaction); +begin + settransaction(avalue); +end; + +procedure tsqlresult.settransaction(const avalue: tmdbtransaction); +begin + dosettransaction(itransactionclient(self),avalue, + tmdbtransaction(ftransaction),false); +end; + +procedure tsqlresult.settransactionwrite(const avalue: tmdbtransaction); +begin + //dummy +end; + +procedure tsqlresult.open(const aparams: array of variant); +begin + if canevent(tmethod(fonbeforeopen)) then begin + fonbeforeopen(self); + end; + if fbeforeopen <> nil then begin + fbeforeopen.execute; + end; +// prepare; + execute(aparams); +// ffielddefs.clear; + fdatabase.addfielddefs(fcursor,ffielddefs); + fdatacols.initfields(self,fcursor,ffielddefs); +// ffielddefs.bindconnectors; + factive:= true; + feof:= false; + next; + fbof:= true; + sendchangeevent(oe_bindfields); + if fafteropen <> nil then begin + fafteropen.execute; + end; + changed; + inherited checkautocommit; + if canevent(tmethod(fonafteropen)) then begin + fonafteropen(self); + end; +end; + +procedure tsqlresult.open; +begin + open([]); +end; + +procedure tsqlresult.doclear(const isclose: boolean); +begin + if not isclose and (fcursor <> nil) then begin + fcursor.close; + end; + feof:= true; + fbof:= true; + //fcols.clear; +end; + +procedure tsqlresult.clear; +begin + doclear(false); + changed; +end; + +procedure tsqlresult.close; +begin + factive:= false; +// feof:= true; +// fbof:= true; + doclear(true); + sendchangeevent(oe_releasefields); + freefldbuffers; + inherited setactive(false); + fdatacols.clear; + changed; +end; + +procedure tsqlresult.freefldbuffers; +begin + if fcursor <> nil then begin + tcustomsqlconnection(database).FreeFldBuffers(FCursor); + end; +end; + +procedure tsqlresult.unprepare; +begin + CheckInactive(active,name); + inherited; +{ + if IsPrepared then begin + with tcustomsqlconnection(Database) do begin + UnPrepareStatement(FCursor); + end; + end; +} +end; + +{ +procedure tsqlresult.prepare; +var + db: tcustomsqlconnection; + trans: tsqltransaction; + str1: msestring; + bo1: boolean; +begin + if not isprepared then begin + checkdatabase(name,fdatabase); + bo1:= sro_utf8 in foptions; + fdatabase.updateutf8(bo1); + if bo1 then begin + foptions:= foptions + [sro_utf8]; + end + else begin + foptions:= foptions - [sro_utf8]; + end; + checktransaction(name,ftransaction); + str1:= trimright(fsql.text); + if str1 = '' then begin + raise edatabaseerror.create(name+': Empty query.'); + end; + db:= tcustomsqlconnection(fdatabase); + trans:= tsqltransaction(ftransaction); + db.connected:= true; + trans.active:= true; + if not assigned(fcursor) then begin + fcursor:= db.allocatecursorhandle(nil,name); + end; + fcursor.ftrans:= trans.handle; + fcursor.fstatementtype:= stselect; + + Db.PrepareStatement(Fcursor,trans,str1,FParams); + FCursor.FInitFieldDef:= True; + end; +end; +} + +procedure tsqlresult.prepare; +begin + inherited; + fcursor.finitfielddef:= true; +end; + +procedure tsqlresult.setparams(const avalue: tmseparams); +begin + fparams.assign(avalue); +end; +{ +procedure tsqlresult.execute; +begin + doexecute(fparams,ftransaction,fcursor,fdatabase,isutf8); +end; +} +procedure tsqlresult.loaded; +begin + inherited; + try + active:= fopenafterread; + except + if csdesigning in componentstate then begin + application.handleexception(self); + end + else begin + raise; + end; + end; +end; + +procedure tsqlresult.dosqlchange(const sender: tobject); +var + bo1: boolean; +begin + bo1:= (csdesigning in componentstate) and active; + if bo1 then begin + active:= false; + end; + inherited; +// unprepare; +// fparams.parsesql(fsql.text,true); + if bo1 then begin + active:= true; + end; +end; + +procedure tsqlresult.next; +begin + checkactive(active,name); + fbof:= false; + if feof then begin + raise edatabaseerror.create(name+': EOF.'); + end; + feof:= not fdatabase.fetch(fcursor); +end; + +function tsqlresult.countrest(): int32; +begin + result:= 0; + while not eof do begin + inc(result); + next(); + end; +end; + +procedure tsqlresult.refresh(const aparams: array of variant); +begin + if not active then begin + open(aparams); +// active:= true; + end + else begin + doclear(false); + feof:= false; + execute(aparams); + next; + fbof:= true; + changed(); + end; +end; + +procedure tsqlresult.refresh; +begin + refresh([]); +end; + +procedure tsqlresult.refreshtransaction; +begin + refresh; +end; + +procedure tsqlresult.setbeforeopen(const avalue: tmsesqlscript); +begin + setlinkedvar(avalue,tmsecomponent(fbeforeopen)); +end; + +procedure tsqlresult.setafteropen(const avalue: tmsesqlscript); +begin + setlinkedvar(avalue,tmsecomponent(fafteropen)); +end; + +procedure tsqlresult.changed; +begin + sendchangeevent; +end; + +procedure tsqlresult.setfielddefs(const avalue: tsqlresultfielddefs); +begin + ffielddefs.assign(avalue); +end; + +function tsqlresult.getcols(const index: int32): tdbcol; +begin + result:= fdatacols[index]; +end; + +procedure tsqlresult.setcols(const index: int32; const avalue: tdbcol); +begin + fdatacols[index].assign(avalue); +end; + +function tsqlresult.getsqltransactionwrite: tsqltransaction; +begin + result:= nil; +end; + +procedure tsqlresult.setsqltransactionwrite(const avalue: tsqltransaction); +begin + //dummy +end; +{ +function tsqlresult.asvariant: variant; +var + int1,int2: integer; + var1: variant; +begin + refresh; + if eof or (cols.count = 0) then begin + result:= null; + end + else begin + var1:= vararraycreate([0,cols.count-1],varvariant); + for int1:= 0 to cols.count - 1 do begin + var1[int1]:= cols[int1].asvariant; + end; + next; + if eof then begin + result:= var1; + end + else begin + result:= vararraycreate([0,cols.count-1,0,1],varvariant); + for int1:= 0 to cols.count - 1 do begin + result[int1,0]:= var1[int1]; + end; + int2:= 1; + while true do begin + for int1:= 0 to cols.count - 1 do begin + result[int1,int2]:= cols[int1].asvariant; + end; + next; + if eof then begin + break; + end; + inc(int2); + vararrayredim(result,int2); + end; + end; + end; +end; +} + +function tsqlresult.asvariant(const aclose: boolean = false): variant; +begin + refresh; + if eof or (fdatacols.count = 0) then begin + result:= null;//unassigned; + end + else begin + result:= fdatacols[0].asvariant; + end; + if aclose then begin + active:= false; + end + else begin + while not eof do begin + next; //eat the rest; + end; + end; +end; + +function tsqlresult.asvariantar(const aclose: boolean = false): variantarty; +var + int1: integer; +begin + refresh; + if eof or (fdatacols.count = 0) then begin + result:= null;//unassigned; + end + else begin + setlength(result,fdatacols.count); + for int1:= 0 to high(result) do begin + result[int1]:= fdatacols[int1].asvariant; + end; + end; + if aclose then begin + active:= false; + end + else begin + while not eof do begin + next; //eat the rest; + end; + end; +end; + +function tsqlresult.asvariantarar(const aclose: boolean = false): variantararty; +var + int1,int2: integer; +begin + refresh; + if eof or (fdatacols.count = 0) then begin + result:= nil; + while not eof do begin + next; //eat the rest; + end; + end + else begin + setlength(result,256); + int2:= 0; + while not eof do begin + if int2 > high(result) then begin + setlength(result,high(result)*2); + end; + setlength(result[int2],fdatacols.count); + for int1:= 0 to fdatacols.count - 1 do begin + result[int2][int1]:= tdbcol(fdatacols.fitems[int1]).asvariant; + end; + inc(int2); + next; + end; + setlength(result,int2); + end; + if aclose then begin + active:= false; + end; +end; + +type + datagetprocty = procedure(const source: tdbcol; const dest: pointer); + datagetprocarty = array of datagetprocty; + +procedure getintegerdata(const source: tdbcol; const dest: pointer); +begin + if not source.isnull then begin + pinteger(dest)^:= source.asinteger; + end; +end; + +procedure getint64data(const source: tdbcol; const dest: pointer); +begin + if not source.isnull then begin + pint64(dest)^:= source.aslargeint; + end; +end; + +procedure getcurrencydata(const source: tdbcol; const dest: pointer); +begin + if not source.isnull then begin + pcurrency(dest)^:= source.aslargeint; + end; +end; + +procedure getrealdata(const source: tdbcol; const dest: pointer); +begin + if not source.isnull then begin + preal(dest)^:= source.asfloat; + end; +end; + +procedure getdatetimedata(const source: tdbcol; const dest: pointer); +begin + if not source.isnull then begin + pdatetime(dest)^:= source.asdatetime; + end; +end; + +procedure getansistringdata(const source: tdbcol; const dest: pointer); +begin + if not source.isnull then begin + pansistring(dest)^:= source.asstring; + end; +end; + +procedure getmsestringdata(const source: tdbcol; const dest: pointer); +begin + if not source.isnull then begin + pmsestring(dest)^:= source.asmsestring; + end; +end; + +procedure tsqlresult.internalloaddatalists(const acols: integerarty; + const datalists: array of tdatalist); + //todo: optimize, use rowsreturned and internal list grow +var + int1,int2,int3: integer; + proc1: datagetprocarty; + col1: dbcolarty; +begin +// refresh; + int2:= length(acols); + setlength(col1,int2); + setlength(proc1,int2); + dec(int2); + for int1:= 0 to int2 do begin + col1[int1]:= tdbcol(fdatacols.fitems[acols[int1]]); + if datalists[int1] <> nil then begin + case datalists[int1].datatype of + dl_integer: begin + proc1[int1]:= @getintegerdata; + end; + dl_int64: begin + proc1[int1]:= @getint64data; + end; + dl_currency: begin + proc1[int1]:= @getcurrencydata; + end; + dl_real: begin + proc1[int1]:= @getrealdata; + end; + dl_datetime: begin + proc1[int1]:= @getdatetimedata; + end; + dl_ansistring: begin + proc1[int1]:= @getansistringdata; + end; + dl_msestring: begin + proc1[int1]:= @getmsestringdata; + end; + else begin + raise exception.create(name+ + ' tsqlresult.loaddatalists(): Invalid datalist.'); + end; + end; + end; + end; + for int1:= 0 to int2 do begin + if datalists[int1] <> nil then begin + with datalists[int1] do begin + beginupdate; + count:= 0; + end; + end; + end; + try + int3:= 0; + while not eof do begin + for int1:= 0 to int2 do begin + if datalists[int1] <> nil then begin + with datalists[int1] do begin + count:= int3 + 1; + proc1[int1](col1[int1],getitempo(int3)); + end; + end; + end; + inc(int3); + next; + end; + finally + for int1:= 0 to high(datalists) do begin + if datalists[int1] <> nil then begin + with datalists[int1] do begin + try + endupdate; + except + application.handleexception; + end; + end; + end; + end; + end; +end; + +procedure tsqlresult.loaddatalists(const datalists: array of tdatalist); +var + int1: integer; + ar1: integerarty; +begin + refresh(); + if length(datalists) > fdatacols.count then begin + componentexception(self,'Too many datalists.'); + end; + setlength(ar1,length(datalists)); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= int1; + end; + internalloaddatalists(ar1,datalists); +end; + +function tsqlresult.rowsreturned: integer; +begin + if active then begin + result:= fcursor.frowsreturned; + end + else begin + result:= -1 + end; +end; + +function tsqlresult.rowsaffected: integer; +begin + if active then begin + result:= fcursor.frowsaffected; + end + else begin + result:= -1 + end; +end; + +function tsqlresult.gettransaction: tmdbtransaction; +begin + result:= ftransaction; +end; + +function tsqlresult.getrecno: integer; +begin + result:= -1; +end; + +procedure tsqlresult.setrecno(value: integer); +begin + //dummy +end; + +procedure tsqlresult.disablecontrols; +begin + //dummy +end; + +procedure tsqlresult.enablecontrols; +begin + //dummy +end; + +function tsqlresult.moveby(distance: longint): longint; +begin + result:= 0; +end; + +procedure tsqlresult.checkbrowsemode; +begin + //dummy +end; + +procedure tsqlresult.savepointevent(const sender: tmdbtransaction; + const akind: savepointeventkindty; const alevel: integer); +begin + //dummy +end; + +procedure tsqlresult.checkautocommit; +begin + //dummy +end; + +{ tdbcolnamearrayprop } + +constructor tdbcolnamearrayprop.create(const afieldtypes: fieldtypesty; + const agetsqlresult: getsqlresultfuncty); +begin + ffieldtypes:= afieldtypes; + fgetsqlresult:= agetsqlresult; + inherited create; +end; + +function tdbcolnamearrayprop.getsqlresult(const aindex: integer): tsqlresult; +begin + result:= fgetsqlresult(aindex); +end; + +procedure tdbcolnamearrayprop.getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); +begin + apropertynames:= nil; + setlength(afieldtypes,1); + afieldtypes[0]:= ffieldtypes; +end; + +{ tsqllookupbuffer } + +constructor tsqllookupbuffer.create(aowner: tcomponent); +begin + fintegercols:= tdbcolnamearrayprop.create( + msedb.integerfields+[ftboolean], + {$ifdef FPC}@{$endif}getsqlresult); + fint64cols:= tdbcolnamearrayprop.create([ftlargeint], + {$ifdef FPC}@{$endif}getsqlresult); + ftextcols:= tdbcolnamearrayprop.create( + msedb.textfields+[ftboolean], + {$ifdef FPC}@{$endif}getsqlresult); + ffloatcols:= tdbcolnamearrayprop.create(msedb.realfields + msedb.datetimefields, + {$ifdef FPC}@{$endif}getsqlresult); + fintegercols.onchange:= {$ifdef FPC}@{$endif}fieldschanged; + fint64cols.onchange:= {$ifdef FPC}@{$endif}fieldschanged; + ftextcols.onchange:= {$ifdef FPC}@{$endif}fieldschanged; + ffloatcols.onchange:= {$ifdef FPC}@{$endif}fieldschanged; + inherited; +end; + +destructor tsqllookupbuffer.destroy; +begin + fintegercols.free; + fint64cols.free; + ftextcols.free; + ffloatcols.free; + inherited; +end; + +procedure tsqllookupbuffer.setsource(const avalue: tsqlresult); +begin + setlinkedvar(avalue,tmsecomponent(fsource)); + invalidatebuffer; +end; + +procedure tsqllookupbuffer.settextcols(const avalue: tdbcolnamearrayprop); +begin + ftextcols.assign(avalue); +end; + +procedure tsqllookupbuffer.setintegercols(const avalue: tdbcolnamearrayprop); +begin + fintegercols.assign(avalue); +end; + +procedure tsqllookupbuffer.setint64cols(const avalue: tdbcolnamearrayprop); +begin + fint64cols.assign(avalue); +end; + +procedure tsqllookupbuffer.setfloatcols(const avalue: tdbcolnamearrayprop); +begin + ffloatcols.assign(avalue); +end; + +function tsqllookupbuffer.getsqlresult(const aindex: integer): tsqlresult; +begin + result:= fsource; +end; + +procedure tsqllookupbuffer.clearbuffer; +begin + setlength(fintegerdata,fintegercols.count); + setlength(fint64data,fint64cols.count); + setlength(ftextdata,ftextcols.count); + setlength(ffloatdata,ffloatcols.count); + inherited; +end; + +function tsqllookupbuffer.getfieldcounttext: integer; +begin + result:= ftextcols.count; +end; + +function tsqllookupbuffer.getfieldcountinteger: integer; +begin + result:= fintegercols.count; +end; + +function tsqllookupbuffer.getfieldcountint64: integer; +begin + result:= fint64cols.count; +end; + +function tsqllookupbuffer.getfieldcountfloat: integer; +begin + result:= ffloatcols.count; +end; + +procedure tsqllookupbuffer.setfieldcounttext(const avalue: integer); +begin + readonlyprop; +end; + +procedure tsqllookupbuffer.setfieldcountinteger(const avalue: integer); +begin + readonlyprop; +end; + +procedure tsqllookupbuffer.setfieldcountint64(const avalue: integer); +begin + readonlyprop; +end; + +procedure tsqllookupbuffer.setfieldcountfloat(const avalue: integer); +begin + readonlyprop; +end; + +procedure tsqllookupbuffer.doloadbuffer; +var + int1,int3,int4: integer; + textf: dbcolarty; + integerf: dbcolarty; + int64f: dbcolarty; + realf: dbcolarty; + ar1: ansistringarty; + bo1: boolean; +begin + application.beginwait; +{ + beginupdate; +} + try +// clearbuffer; + with fsource do begin + if (fsource <> nil) and (active or (olbsq_closesqlresult in foptionsdb) and + (lbs_sourceclosed in fstate) and + not (csloading in componentstate)) then begin + try + bo1:= active; + if bo1 then begin + exclude(fstate,lbs_sourceclosed); + end; + if not bof or not active then begin + refresh; + end; + try + setlength(ar1,ftextcols.count); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= ftextcols[int1]; + end; + textf:= fdatacols.colsbyname(ar1); + setlength(ar1,fintegercols.count); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= fintegercols[int1]; + end; + integerf:= fdatacols.colsbyname(ar1); + setlength(ar1,fint64cols.count); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= fint64cols[int1]; + end; + int64f:= fdatacols.colsbyname(ar1); + setlength(ar1,floatcols.count); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= ffloatcols[int1]; + end; + realf:= fdatacols.colsbyname(ar1); + int3:= fcount; + int1:= fcount; + try + while not fsource.eof do begin + if int3 <= int1 then begin + int3:= (int3 * 3) div 2 + 100; + for int4:= 0 to high(ftextdata) do begin + setlength(ftextdata[int4].data,int3); + end; + for int4:= 0 to high(fintegerdata) do begin + setlength(fintegerdata[int4].data,int3); + end; + for int4:= 0 to high(fint64data) do begin + setlength(fint64data[int4].data,int3); + end; + for int4:= 0 to high(ffloatdata) do begin + setlength(ffloatdata[int4].data,int3); + end; + end; + for int4:= 0 to high(integerf) do begin + if integerf[int4] <> nil then begin + fintegerdata[int4].data[int1]:= integerf[int4].asinteger; + end; + end; + for int4:= 0 to high(int64f) do begin + if int64f[int4] <> nil then begin + fint64data[int4].data[int1]:= int64f[int4].aslargeint; + end; + end; + for int4:= 0 to high(realf) do begin + if realf[int4] <> nil then begin + if realf[int4].isnull then begin + ffloatdata[int4].data[int1]:= emptyreal; + end + else begin + ffloatdata[int4].data[int1]:= realf[int4].asfloat; + end; + end; + end; + for int4:= 0 to high(textf) do begin + if textf[int4] <> nil then begin + ftextdata[int4].data[int1]:= textf[int4].asmsestring; + end; + end; + inc(int1); + fsource.next; + end; + finally + for int4:= 0 to high(fintegerdata) do begin + setlength(fintegerdata[int4].data,int1); + end; + for int4:= 0 to high(fint64data) do begin + setlength(fint64data[int4].data,int1); + end; + for int4:= 0 to high(ftextdata) do begin + setlength(ftextdata[int4].data,int1); + end; + for int4:= 0 to high(ffloatdata) do begin + setlength(ffloatdata[int4].data,int1); + end; + fcount:= int1; + end; + finally + if {not bo1 and} (olbsq_closesqlresult in foptionsdb) and + not (csdesigning in componentstate) then begin + include(fstate,lbs_sourceclosed); + fsource.active:= false; + end; + end; + except + if csdesigning in componentstate then begin + application.handleexception(self); + end + else begin + raise; + end; + end; + end; + end; + include(fstate,lbs_buffervalid); + finally + application.endwait; +// endupdate; + end; +end; + +procedure tsqllookupbuffer.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (sender = fsource) and (event = oe_changed) and (fupdating = 0) and + (fsource <> nil) and + (fsource.active or not (olbsq_closesqlresult in foptionsdb)) then begin + invalidatebuffer; + changed; + end; +end; + +function tsqllookupbuffer.fieldnamestext: stringarty; +begin + result:= ftextcols.itemar; +end; + +function tsqllookupbuffer.fieldnamesfloat: stringarty; +begin + result:= ffloatcols.itemar; +end; + +function tsqllookupbuffer.fieldnamesinteger: stringarty; +begin + result:= fintegercols.itemar; +end; + +function tsqllookupbuffer.fieldnamesint64: stringarty; +begin + result:= fint64cols.itemar; +end; + +{ tsqlresultfielddefs } +{ +constructor tsqlresultfielddefs.create(const aowner: tsqlresult); +begin + fsqlresult:= aowner; + tdefcollection(self).create(nil,owner,tsqlresultfielddef); +end; +} +procedure tsqlresultfielddefs.setitemname(aitem: tcollectionitem); +begin + {$ifdef mse_FPC_2_2} + if aitem is tnameditem then begin + with tnameditem(aitem) do begin + {$else} + if aitem is tfielddef then begin + with tfielddef(aitem) do begin + {$endif} + if name = '' then begin + name:= 'fielddef' + inttostr(id+1); + end + else begin + inherited; + end; + end; + end + else begin + inherited; + end; +end; +{ +procedure tsqlresultfielddefs.bindconnectors; +var + int1,int2: integer; + str1: string; + col1: tdbcol; +begin + for int1:= 0 to count - 1 do begin + with tsqlresultfielddef(items[int1]) do begin + if fconnector <> nil then begin + str1:= uppercase(name); + fconnector.fcol:= nil; + for int2:= 0 to high(fsqlresult.fcols.fitems) do begin + col1:= tdbcol(fsqlresult.fcols.fitems[int2]); + if col1.fuppername = str1 then begin + fconnector.fcol:= col1; + break; + end; + end; +// if fconnector.fcol = nil then begin +// raise exception.create(fsqlresult.name+': Field "'+name+'" not found.'); +// end; + end; + end; + end; +end; +} +(* +{ tsqlresultfielddef } + +destructor tsqlresultfielddef.destroy; +begin + connector:= nil; + inherited; +end; + +procedure tsqlresultfielddef.setconnector(const avalue: tsqlresultconnector); +begin + if fconnector <> avalue then begin + if fconnector <> nil then begin + fconnector.fcol:= nil; + fconnector.ffielddef:= nil; + end; + fconnector:= avalue; + if fconnector <> nil then begin + fconnector.fcol:= nil; + fconnector.ffielddef:= self; + end; + end; +end; +*) +{ tsqlresultconnector } + +destructor tsqlresultconnector.destroy; +begin +// if ffielddef <> nil then begin +// ffielddef.connector:= nil; +// end; + inherited; +end; + +function tsqlresultconnector.getcol: tdbcol; +begin + result:= fcol; + if result = nil then begin + raise exception.create(name+': Connector not bound'); + end; +end; + +procedure tsqlresultconnector.setsource(const avalue: tsqlresult); +begin + fcol:= nil; + setlinkedvar(tmsecomponent(avalue),tmsecomponent(fsource)); +end; + +procedure tsqlresultconnector.setcolname(const avalue: dbcolnamety); +begin + fcolname:= avalue; + fcol:= nil; +end; + +procedure tsqlresultconnector.objevent(const sender: iobjectlink; + const event: objecteventty); +var + str1: string; + int1: integer; + col1: tdbcol; +begin + inherited; + case event of + oe_bindfields: begin + if (fcolname <> '') and (sender.getinstance = fsource) then begin + fcol:= nil; + str1:= uppercase(fcolname); + with fsource.fdatacols do begin + for int1:= 0 to high(fitems) do begin + col1:= tdbcol(fitems[int1]); + if col1.fuppername = str1 then begin + fcol:= col1; + break; + end; + end; + end; + end; + end; + oe_releasefields: begin + if sender.getinstance = fsource then begin + fcol:= nil; + end; + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/db/msezeos.pas b/mseide-msegui/lib/common/db/msezeos.pas new file mode 100644 index 0000000..6121af6 --- /dev/null +++ b/mseide-msegui/lib/common/db/msezeos.pas @@ -0,0 +1,1385 @@ +unit msezeos; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,mdb,ZDataset,msedb,ZStoredProcedure,msestrings, + msedbgraphics,mseapplication,msedatabase; +type + tmsezgraphicfield = class(tmsegraphicfield) + public + constructor create(aowner: tcomponent); override; + end; + + tmsezreadonlyquery = class(tzreadonlyquery,imselocate,idscontroller, + igetdscontroller,isqlpropertyeditor,iactivatorclient) + private + fcontroller: tdscontroller; + procedure setcontroller(const avalue: tdscontroller); + function getcontroller: tdscontroller; + function isutf8: boolean; + //idscontroller + procedure inheritedresync(const mode: tresyncmode); + procedure inheriteddataevent(const event: tdataevent; const info: ptrint); + procedure inheritedcancel; + procedure inheritedpost; + procedure inheritedinsert(); + procedure inheriteddelete(); + function inheritedmoveby(const distance: integer): integer; + procedure inheritedinternalinsert; + procedure inheritedinternaldelete; + procedure inheritedinternalopen; + procedure inheritedinternalclose; + function getblobdatasize: integer; + function getnumboolean: boolean; + function getfloatdate: boolean; + function getint64currency: boolean; + function getsavepointoptions(): savepointoptionsty; + function getfiltereditkind: filtereditkindty; + procedure beginfilteredit(const akind: filtereditkindty); + procedure endfilteredit; + procedure clearfilter(); +// procedure doidleapplyupdates; + function getrestorerecno: boolean; + procedure setrestorerecno(const avalue: boolean); + function updatesortfield(const afield: tfield; const adescend: boolean): boolean; + protected + procedure setactive (const value : boolean); reintroduce; + function getactive: boolean; + procedure loaded; override; + function getfieldclass(fieldtype: tfieldtype): tfieldclass; override; + procedure dataevent(event: tdataevent; info: ptrint); override; + procedure openlocal; + procedure internalopen; override; + procedure internalinsert; override; + procedure internaldelete; override; + procedure internalclose; override; + function getcanmodify: boolean; override; +// procedure dscontrolleroptionschanged(const aoptions: datasetoptionsty); + function islastrecord: boolean; + procedure begindisplaydata; + procedure enddisplaydata; + //isqlpropertyeditor + function getdatabase: tcustomconnection; //for isqlpropertyeditor + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; reintroduce; +{ + function locate(const key: integer; const field: tfield; + const aoptions: locateoptionsty = []): locateresultty; + function locate(const key: msestring; const field: tfield; + const aoptions: locateoptionsty = []): locateresultty; +} + procedure AppendRecord(const Values: array of const); + procedure cancel; override; + procedure post; override; + function moveby(const distance: integer): integer; + published + property controller: tdscontroller read fcontroller write setcontroller; + property Active: boolean read getactive write setactive default false; + property AutocalcFields default false; + end; + + tmsezquery = class(tzquery,imselocate,idscontroller,igetdscontroller, + isqlpropertyeditor,iactivatorclient) + private + fcontroller: tdscontroller; + procedure setcontroller(const avalue: tdscontroller); + function getcontroller: tdscontroller; + function isutf8: boolean; + //idscontroller + procedure inheritedresync(const mode: tresyncmode); + procedure inheriteddataevent(const event: tdataevent; const info: ptrint); + procedure inheritedcancel; + procedure inheritedpost; + procedure inheritedinsert(); + procedure inheriteddelete(); + function inheritedmoveby(const distance: integer): integer; + procedure inheritedinternalinsert; + procedure inheritedinternaldelete; + procedure inheritedinternalopen; + procedure inheritedinternalclose; + function getblobdatasize: integer; + function getnumboolean: boolean; + function getfloatdate: boolean; + function getint64currency: boolean; + function getsavepointoptions(): savepointoptionsty; + function getfiltereditkind: filtereditkindty; + procedure beginfilteredit(const akind: filtereditkindty); + procedure endfilteredit; + procedure clearfilter; +// procedure doidleapplyupdates; + function getrestorerecno: boolean; + procedure setrestorerecno(const avalue: boolean); + function updatesortfield(const afield: tfield; const adescend: boolean): boolean; + protected + procedure setactive (const value : boolean); reintroduce; + function getactive: boolean; + procedure loaded; override; + function getfieldclass(fieldtype: tfieldtype): tfieldclass; override; + procedure dataevent(event: tdataevent; info: ptrint); override; + procedure openlocal; + procedure internalopen; override; + procedure internalinsert; override; + procedure internaldelete; override; + procedure internalclose; override; + function getcanmodify: boolean; override; +// procedure dscontrolleroptionschanged(const aoptions: datasetoptionsty); + function islastrecord: boolean; + procedure begindisplaydata; + procedure enddisplaydata; + //isqlpropertyeditor + function getdatabase: tcustomconnection; //for isqlpropertyeditor + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; reintroduce; +{ + function locate(const key: integer; const field: tfield; + const aoptions: locateoptionsty = []): locateresultty; + function locate(const key: msestring; const field: tfield; + const aoptions: locateoptionsty = []): locateresultty; +} + procedure AppendRecord(const Values: array of const); + procedure cancel; override; + procedure post; override; + function moveby(const distance: integer): integer; + published + property controller: tdscontroller read fcontroller write setcontroller; + property Active: boolean read getactive write setactive default false; + property AutocalcFields default false; + end; + + tmseztable = class(tztable,imselocate,idscontroller, + igetdscontroller,iactivatorclient) + private + fcontroller: tdscontroller; + procedure setcontroller(const avalue: tdscontroller); + function getcontroller: tdscontroller; + //idscontroller + procedure inheritedresync(const mode: tresyncmode); + procedure inheriteddataevent(const event: tdataevent; const info: ptrint); + procedure inheritedcancel; + procedure inheritedpost; + procedure inheritedinsert(); + procedure inheriteddelete(); + function inheritedmoveby(const distance: integer): integer; + procedure inheritedinternalinsert; + procedure inheritedinternaldelete; + procedure inheritedinternalopen; + procedure inheritedinternalclose; + function getblobdatasize: integer; + function getnumboolean: boolean; + function getfloatdate: boolean; + function getint64currency: boolean; + function getsavepointoptions(): savepointoptionsty; + function getfiltereditkind: filtereditkindty; + procedure beginfilteredit(const akind: filtereditkindty); + procedure endfilteredit; + procedure clearfilter; +// procedure doidleapplyupdates; + function getrestorerecno: boolean; + procedure setrestorerecno(const avalue: boolean); + function updatesortfield(const afield: tfield; const adescend: boolean): boolean; + protected + procedure setactive (const value : boolean); reintroduce; + function getactive: boolean; + procedure loaded; override; + function getfieldclass(fieldtype: tfieldtype): tfieldclass; override; + procedure dataevent(event: tdataevent; info: ptrint); override; + procedure openlocal; + procedure internalopen; override; + procedure internalinsert; override; + procedure internaldelete; override; + procedure internalclose; override; + function getcanmodify: boolean; override; +// procedure dscontrolleroptionschanged(const aoptions: datasetoptionsty); + function islastrecord: boolean; + procedure begindisplaydata; + procedure enddisplaydata; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; reintroduce; +{ + function locate(const key: integer; const field: tfield; + const aoptions: locateoptionsty = []): locateresultty; + function locate(const key: msestring; const field: tfield; + const aoptions: locateoptionsty = []): locateresultty; +} + procedure AppendRecord(const Values: array of const); + procedure cancel; override; + procedure post; override; + function moveby(const distance: integer): integer; + published + property controller: tdscontroller read fcontroller write setcontroller; + property Active: boolean read getactive write setactive default false; + property AutocalcFields default false; + end; + + tmsezstoredproc = class(tzstoredproc,imselocate,idscontroller, + igetdscontroller,iactivatorclient) + private + fcontroller: tdscontroller; + procedure setcontroller(const avalue: tdscontroller); + function getcontroller: tdscontroller; + //idscontroller + procedure inheritedresync(const mode: tresyncmode); + procedure inheriteddataevent(const event: tdataevent; const info: ptrint); + procedure inheritedcancel; + procedure inheritedpost; + procedure inheritedinsert(); + procedure inheriteddelete(); + function inheritedmoveby(const distance: integer): integer; + procedure inheritedinternalinsert; + procedure inheritedinternaldelete; + procedure inheritedinternalopen; + procedure inheritedinternalclose; + function getblobdatasize: integer; + function getnumboolean: boolean; + function getfloatdate: boolean; + function getint64currency: boolean; + function getsavepointoptions(): savepointoptionsty; + function getfiltereditkind: filtereditkindty; + procedure beginfilteredit(const akind: filtereditkindty); + procedure endfilteredit; + procedure clearfilter; +// procedure doidleapplyupdates; + function getrestorerecno: boolean; + procedure setrestorerecno(const avalue: boolean); + function updatesortfield(const afield: tfield; const adescend: boolean): boolean; + protected + procedure setactive (const value : boolean); reintroduce; + function getactive: boolean; + procedure loaded; override; + function getfieldclass(fieldtype: tfieldtype): tfieldclass; override; + procedure dataevent(event: tdataevent; info: ptrint); override; + procedure openlocal; + procedure internalopen; override; + procedure internalinsert; override; + procedure internaldelete; override; + procedure internalclose; override; + function getcanmodify: boolean; override; +// procedure dscontrolleroptionschanged(const aoptions: datasetoptionsty); + function islastrecord: boolean; + procedure begindisplaydata; + procedure enddisplaydata; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; reintroduce; +{ + function locate(const key: integer; const field: tfield; + const aoptions: locateoptionsty = []): locateresultty; + function locate(const key: msestring; const field: tfield; + const aoptions: locateoptionsty = []): locateresultty; +} + procedure AppendRecord(const Values: array of const); + procedure cancel; override; + procedure post; override; + function moveby(const distance: integer): integer; + published + property controller: tdscontroller read fcontroller write setcontroller; + property Active: boolean read getactive write setactive default false; + property AutocalcFields default false; + end; + +implementation + +{ tmsezreadonlyquery } + +constructor tmsezreadonlyquery.create(aowner: tcomponent); +begin + inherited; + fcontroller:= tdscontroller.create(self,idscontroller(self),-1); +end; + +destructor tmsezreadonlyquery.destroy; +begin + fcontroller.free; + inherited; +end; + +function tmsezreadonlyquery.locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; +begin + result:= locaterecord(self,afields,akeys,aisnull,akeyoptions,aoptions); +end; +{ +function tmsezreadonlyquery.locate(const key: integer; const field: tfield; + const aoptions: locateoptionsty = []): locateresultty; +begin + result:= fcontroller.locate(key,field,aoptions); +end; + +function tmsezreadonlyquery.locate(const key: msestring; + const field: tfield; const aoptions: locateoptionsty = []): locateresultty; +begin + result:= fcontroller.locate(key,field,aoptions); +end; +} +procedure tmsezreadonlyquery.AppendRecord(const Values: array of const); +begin + fcontroller.appendrecord(values); +end; + +procedure tmsezreadonlyquery.setcontroller(const avalue: tdscontroller); +begin + fcontroller.assign(avalue); +end; + +function tmsezreadonlyquery.getactive: boolean; +begin + result:= inherited active; +end; + +procedure tmsezreadonlyquery.setactive(const value: boolean); +begin + if fcontroller.setactive(value) then begin + inherited setactive(value); + end; +end; + +procedure tmsezreadonlyquery.loaded; +begin + inherited; + fcontroller.loaded; +end; + +function tmsezreadonlyquery.getfieldclass(fieldtype: tfieldtype): tfieldclass; +begin + fcontroller.getfieldclass(fieldtype,result); +end; + +function tmsezreadonlyquery.getcontroller: tdscontroller; +begin + result:= fcontroller; +end; + +procedure tmsezreadonlyquery.inheritedresync(const mode: tresyncmode); +begin + inherited resync(mode); +end; + +procedure tmsezreadonlyquery.inheriteddataevent(const event: tdataevent; + const info: ptrint); +begin + inherited dataevent(event,info); +end; + +procedure tmsezreadonlyquery.inheritedcancel; +begin + inherited cancel; +end; + +procedure tmsezreadonlyquery.cancel; +begin + fcontroller.cancel; +end; + +function tmsezreadonlyquery.inheritedmoveby(const distance: integer): integer; +begin + result:= inherited moveby(distance); +end; + +procedure tmsezreadonlyquery.inheritedinternalinsert; +begin + inherited internalinsert; +end; + +procedure tmsezreadonlyquery.internalinsert; +begin + fcontroller.internalinsert; +end; + +function tmsezreadonlyquery.moveby(const distance: integer): integer; +begin + result:= fcontroller.moveby(distance); +end; + +procedure tmsezreadonlyquery.inheritedinternalopen; +begin + inherited internalopen; +end; + +procedure tmsezreadonlyquery.internalopen; +begin + fcontroller.internalopen; +end; + +procedure tmsezreadonlyquery.inheritedpost; +begin + inherited post; +end; + +procedure tmsezreadonlyquery.post; +begin + fcontroller.post; +end; + +procedure tmsezreadonlyquery.inheritedinternaldelete; +begin + inherited internaldelete; +end; + +procedure tmsezreadonlyquery.internaldelete; +begin + fcontroller.internaldelete; +end; + +procedure tmsezreadonlyquery.openlocal; +begin + inherited internalopen; +end; + +procedure tmsezreadonlyquery.inheritedinternalclose; +begin + inherited internalclose; +end; + +procedure tmsezreadonlyquery.internalclose; +begin + fcontroller.internalclose; +end; + +function tmsezreadonlyquery.getblobdatasize: integer; +begin + result:= 0; //no blobs +end; + +function tmsezreadonlyquery.getnumboolean: boolean; +begin + result:= true; +end; + +function tmsezreadonlyquery.isutf8: boolean; +begin + result:= fcontroller.isutf8; +end; + +function tmsezreadonlyquery.getfloatdate: boolean; +begin + result:= false; +end; + +function tmsezreadonlyquery.getint64currency: boolean; +begin + result:= false; +end; + +function tmsezreadonlyquery.getsavepointoptions(): savepointoptionsty; +begin + result:= []; +end; + +function tmsezreadonlyquery.getfiltereditkind: filtereditkindty; +begin + result:= fek_filter; +end; + +procedure tmsezreadonlyquery.beginfilteredit(const akind: filtereditkindty); +begin + //dummy +end; + +procedure tmsezreadonlyquery.endfilteredit; +begin + //dummy +end; + +procedure tmsezreadonlyquery.clearfilter; +begin + //dummy +end; +{ +procedure tmsezreadonlyquery.doidleapplyupdates; +begin + //dummy +end; +} +function tmsezreadonlyquery.getcanmodify: boolean; +begin + result:= fcontroller.getcanmodify and inherited getcanmodify; +end; +{ +procedure tmsezreadonlyquery.dscontrolleroptionschanged(const aoptions: datasetoptionsty); +begin + //dummy +end; +} +function tmsezreadonlyquery.getrestorerecno: boolean; +begin + result:= false; +end; + +procedure tmsezreadonlyquery.setrestorerecno(const avalue: boolean); +begin + //dummy +end; + +function tmsezreadonlyquery.islastrecord: boolean; +begin + result:= eof or (recno = recordcount); +end; + +procedure tmsezreadonlyquery.dataevent(event: tdataevent; info: ptrint); +begin + fcontroller.dataevent(event,info); +end; + +function tmsezreadonlyquery.updatesortfield(const afield: tfield; + const adescend: boolean): boolean; +begin + result:= false; +end; + +procedure tmsezreadonlyquery.begindisplaydata; +begin + //dummy +end; + +procedure tmsezreadonlyquery.enddisplaydata; +begin + //dummy +end; + +procedure tmsezreadonlyquery.inheritedinsert; +begin + inherited insert(); +end; + +procedure tmsezreadonlyquery.inheriteddelete; +begin + inherited delete(); +end; + +function tmsezreadonlyquery.getdatabase: tcustomconnection; +begin + result:= nil; +end; + +{ tmsezquery } + +constructor tmsezquery.create(aowner: tcomponent); +begin + inherited; + fcontroller:= tdscontroller.create(self,idscontroller(self),-1); +end; + +destructor tmsezquery.destroy; +begin + fcontroller.free; + inherited; +end; + +function tmsezquery.locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; +begin + result:= locaterecord(self,afields,akeys,aisnull,akeyoptions,aoptions); +end; +{ +function tmsezquery.locate(const key: integer; const field: tfield; + const aoptions: locateoptionsty = []): locateresultty; +begin + result:= fcontroller.locate(key,field,aoptions); +end; + +function tmsezquery.locate(const key: msestring; + const field: tfield; const aoptions: locateoptionsty = []): locateresultty; +begin + result:= fcontroller.locate(key,field,aoptions); +end; +} +procedure tmsezquery.AppendRecord(const Values: array of const); +begin + fcontroller.appendrecord(values); +end; + +procedure tmsezquery.setcontroller(const avalue: tdscontroller); +begin + fcontroller.assign(avalue); +end; + +function tmsezquery.getactive: boolean; +begin + result:= inherited active; +end; + +procedure tmsezquery.setactive(const value: boolean); +begin + if fcontroller.setactive(value) then begin + inherited setactive(value); + end; +end; + +procedure tmsezquery.loaded; +begin + inherited; + fcontroller.loaded; +end; + +function tmsezquery.getfieldclass(fieldtype: tfieldtype): tfieldclass; +begin + fcontroller.getfieldclass(fieldtype,result); +end; + +function tmsezquery.getcontroller: tdscontroller; +begin + result:= fcontroller; +end; + +procedure tmsezquery.inheritedresync(const mode: tresyncmode); +begin + inherited resync(mode); +end; + +procedure tmsezquery.inheriteddataevent(const event: tdataevent; + const info: ptrint); +begin + inherited dataevent(event,info); +end; + +procedure tmsezquery.inheritedcancel; +begin + inherited cancel; +end; + +procedure tmsezquery.cancel; +begin + fcontroller.cancel; +end; + +function tmsezquery.inheritedmoveby(const distance: integer): integer; +begin + result:= inherited moveby(distance); +end; + +procedure tmsezquery.inheritedinternalinsert; +begin + inherited internalinsert; +end; + +procedure tmsezquery.internalinsert; +begin + fcontroller.internalinsert; +end; + +function tmsezquery.moveby(const distance: integer): integer; +begin + result:= fcontroller.moveby(distance); +end; + +procedure tmsezquery.inheritedinternalopen; +begin + inherited internalopen; +end; + +procedure tmsezquery.internalopen; +begin + fcontroller.internalopen; +end; + +procedure tmsezquery.inheritedpost; +begin + inherited post; +end; + +procedure tmsezquery.post; +begin + fcontroller.post; +end; + +procedure tmsezquery.inheritedinternaldelete; +begin + inherited internaldelete; +end; + +procedure tmsezquery.internaldelete; +begin + fcontroller.internaldelete; +end; + +procedure tmsezquery.openlocal; +begin + inherited internalopen; +end; + +procedure tmsezquery.inheritedinternalclose; +begin + inherited internalclose; +end; + +procedure tmsezquery.internalclose; +begin + fcontroller.internalclose; +end; + +function tmsezquery.getblobdatasize: integer; +begin + result:= 0; //no blobs +end; + +function tmsezquery.getnumboolean: boolean; +begin + result:= true; +end; + +function tmsezquery.isutf8: boolean; +begin + result:= fcontroller.isutf8; +end; + +function tmsezquery.getfloatdate: boolean; +begin + result:= false; +end; + +function tmsezquery.getint64currency: boolean; +begin + result:= false; +end; + +function tmsezquery.getsavepointoptions(): savepointoptionsty; +begin + result:= []; +end; + +function tmsezquery.getfiltereditkind: filtereditkindty; +begin + result:= fek_filter; +end; + +procedure tmsezquery.beginfilteredit(const akind: filtereditkindty); +begin + //dummy +end; + +procedure tmsezquery.endfilteredit; +begin + //dummy +end; + +procedure tmsezquery.clearfilter; +begin + //dummy +end; +{ +procedure tmsezquery.doidleapplyupdates; +begin + //dummy +end; +} +function tmsezquery.getcanmodify: boolean; +begin + result:= fcontroller.getcanmodify and inherited getcanmodify; +end; +{ +procedure tmsezquery.dscontrolleroptionschanged(const aoptions: datasetoptionsty); +begin + //dummy +end; +} +function tmsezquery.getrestorerecno: boolean; +begin + result:= false; +end; + +procedure tmsezquery.setrestorerecno(const avalue: boolean); +begin + //dummy +end; + +function tmsezquery.islastrecord: boolean; +begin + result:= eof or (recno = recordcount); +end; + +procedure tmsezquery.dataevent(event: tdataevent; info: ptrint); +begin + fcontroller.dataevent(event,info); +end; + +function tmsezquery.updatesortfield(const afield: tfield; + const adescend: boolean): boolean; +begin + result:= false; +end; + +procedure tmsezquery.begindisplaydata; +begin + //dummy +end; + +procedure tmsezquery.enddisplaydata; +begin + //dummy +end; + +procedure tmsezquery.inheritedinsert; +begin + inherited insert(); +end; + +procedure tmsezquery.inheriteddelete; +begin + inherited delete(); +end; + +function tmsezquery.getdatabase: tcustomconnection; +begin + result:= nil; +end; + +{ tmseztable } + +constructor tmseztable.create(aowner: tcomponent); +begin + inherited; + fcontroller:= tdscontroller.create(self,idscontroller(self),-1); +end; + +destructor tmseztable.destroy; +begin + fcontroller.free; + inherited; +end; + +function tmseztable.locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; +begin + result:= locaterecord(self,afields,akeys,aisnull,akeyoptions,aoptions); +end; +{ +function tmseztable.locate(const key: integer; const field: tfield; + const aoptions: locateoptionsty = []): locateresultty; +begin + result:= fcontroller.locate(key,field,aoptions); +end; + +function tmseztable.locate(const key: msestring; + const field: tfield; const aoptions: locateoptionsty = []): locateresultty; +begin + result:= fcontroller.locate(key,field,aoptions); +end; +} +procedure tmseztable.AppendRecord(const Values: array of const); +begin + fcontroller.appendrecord(values); +end; + +procedure tmseztable.setcontroller(const avalue: tdscontroller); +begin + fcontroller.assign(avalue); +end; + +function tmseztable.getactive: boolean; +begin + result:= inherited active; +end; + +procedure tmseztable.setactive(const value: boolean); +begin + if fcontroller.setactive(value) then begin + inherited setactive(value); + end; +end; + +procedure tmseztable.loaded; +begin + inherited; + fcontroller.loaded; +end; + +function tmseztable.getfieldclass(fieldtype: tfieldtype): tfieldclass; +begin + fcontroller.getfieldclass(fieldtype,result); +end; + +function tmseztable.getcontroller: tdscontroller; +begin + result:= fcontroller; +end; + +procedure tmseztable.inheritedresync(const mode: tresyncmode); +begin + inherited resync(mode); +end; + +procedure tmseztable.inheriteddataevent(const event: tdataevent; + const info: ptrint); +begin + inherited dataevent(event,info); +end; + +procedure tmseztable.inheritedcancel; +begin + inherited cancel; +end; + +procedure tmseztable.cancel; +begin + fcontroller.cancel; +end; + +function tmseztable.inheritedmoveby(const distance: integer): integer; +begin + result:= inherited moveby(distance); +end; + +procedure tmseztable.inheritedinternalinsert; +begin + inherited internalinsert; +end; + +procedure tmseztable.internalinsert; +begin + fcontroller.internalinsert; +end; + +function tmseztable.moveby(const distance: integer): integer; +begin + result:= fcontroller.moveby(distance); +end; + +procedure tmseztable.inheritedinternalopen; +begin + inherited internalopen; +end; + +procedure tmseztable.internalopen; +begin + fcontroller.internalopen; +end; + +procedure tmseztable.inheritedpost; +begin + inherited post; +end; + +procedure tmseztable.post; +begin + fcontroller.post; +end; + +procedure tmseztable.inheritedinternaldelete; +begin + inherited internaldelete; +end; + +procedure tmseztable.internaldelete; +begin + fcontroller.internaldelete; +end; + +procedure tmseztable.openlocal; +begin + inherited internalopen; +end; + +procedure tmseztable.inheritedinternalclose; +begin + inherited internalclose; +end; + +procedure tmseztable.internalclose; +begin + fcontroller.internalclose; +end; + +function tmseztable.getblobdatasize: integer; +begin + result:= 0; //no blobs +end; + +function tmseztable.getnumboolean: boolean; +begin + result:= true; +end; + +function tmseztable.getfloatdate: boolean; +begin + result:= false; +end; + +function tmseztable.getint64currency: boolean; +begin + result:= false; +end; + +function tmseztable.getsavepointoptions(): savepointoptionsty; +begin + result:= []; +end; + +function tmseztable.getfiltereditkind: filtereditkindty; +begin + result:= fek_filter; +end; + +procedure tmseztable.beginfilteredit(const akind: filtereditkindty); +begin + //dummy +end; + +procedure tmseztable.endfilteredit; +begin + //dummy +end; + +procedure tmseztable.clearfilter; +begin + //dummy +end; +{ +procedure tmseztable.doidleapplyupdates; +begin + //dummy +end; +} +function tmseztable.getcanmodify: boolean; +begin + result:= fcontroller.getcanmodify and inherited getcanmodify; +end; +{ +procedure tmseztable.dscontrolleroptionschanged(const aoptions: datasetoptionsty); +begin + //dummy +end; +} +function tmseztable.getrestorerecno: boolean; +begin + result:= false; +end; + +procedure tmseztable.setrestorerecno(const avalue: boolean); +begin + //dummy +end; + +function tmseztable.islastrecord: boolean; +begin + result:= eof or (recno = recordcount); +end; + +procedure tmseztable.dataevent(event: tdataevent; info: ptrint); +begin + fcontroller.dataevent(event,info); +end; + +function tmseztable.updatesortfield(const afield: tfield; + const adescend: boolean): boolean; +begin + result:= false; +end; + +procedure tmseztable.begindisplaydata; +begin + //dummy +end; + +procedure tmseztable.enddisplaydata; +begin + //dummy +end; + +procedure tmseztable.inheritedinsert; +begin + inherited insert(); +end; + +procedure tmseztable.inheriteddelete; +begin + inherited delete(); +end; + +{ tmsezstoredproc } + +constructor tmsezstoredproc.create(aowner: tcomponent); +begin + inherited; + fcontroller:= tdscontroller.create(self,idscontroller(self),-1); +end; + +destructor tmsezstoredproc.destroy; +begin + fcontroller.free; + inherited; +end; + +function tmsezstoredproc.locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; +begin + result:= locaterecord(self,afields,akeys,aisnull,akeyoptions,aoptions); +end; +{ +function tmsezstoredproc.locate(const key: integer; const field: tfield; + const aoptions: locateoptionsty = []): locateresultty; +begin + result:= fcontroller.locate(key,field,aoptions); +end; + +function tmsezstoredproc.locate(const key: msestring; + const field: tfield; const aoptions: locateoptionsty = []): locateresultty; +begin + result:= fcontroller.locate(key,field,aoptions); +end; +} +procedure tmsezstoredproc.AppendRecord(const Values: array of const); +begin + fcontroller.appendrecord(values); +end; + +procedure tmsezstoredproc.setcontroller(const avalue: tdscontroller); +begin + fcontroller.assign(avalue); +end; + +function tmsezstoredproc.getactive: boolean; +begin + result:= inherited active; +end; + +procedure tmsezstoredproc.setactive(const value: boolean); +begin + if fcontroller.setactive(value) then begin + inherited setactive(value); + end; +end; + +procedure tmsezstoredproc.loaded; +begin + inherited; + fcontroller.loaded; +end; + +function tmsezstoredproc.getfieldclass(fieldtype: tfieldtype): tfieldclass; +begin + fcontroller.getfieldclass(fieldtype,result); +end; + +function tmsezstoredproc.getcontroller: tdscontroller; +begin + result:= fcontroller; +end; + +procedure tmsezstoredproc.inheritedresync(const mode: tresyncmode); +begin + inherited resync(mode); +end; + +procedure tmsezstoredproc.inheriteddataevent(const event: tdataevent; + const info: ptrint); +begin + inherited dataevent(event,info); +end; + +procedure tmsezstoredproc.inheritedcancel; +begin + inherited cancel; +end; + +procedure tmsezstoredproc.cancel; +begin + fcontroller.cancel; +end; + +function tmsezstoredproc.inheritedmoveby(const distance: integer): integer; +begin + result:= inherited moveby(distance); +end; + +procedure tmsezstoredproc.inheritedinternalinsert; +begin + inherited internalinsert; +end; + +procedure tmsezstoredproc.internalinsert; +begin + fcontroller.internalinsert; +end; + +function tmsezstoredproc.moveby(const distance: integer): integer; +begin + result:= fcontroller.moveby(distance); +end; + +procedure tmsezstoredproc.inheritedinternalopen; +begin + inherited internalopen; +end; + +procedure tmsezstoredproc.internalopen; +begin + fcontroller.internalopen; +end; + +procedure tmsezstoredproc.inheritedpost; +begin + inherited post; +end; + +procedure tmsezstoredproc.post; +begin + fcontroller.post; +end; + +procedure tmsezstoredproc.inheritedinternaldelete; +begin + inherited internaldelete; +end; + +procedure tmsezstoredproc.internaldelete; +begin + fcontroller.internaldelete; +end; + +procedure tmsezstoredproc.openlocal; +begin + inherited internalopen; +end; + +procedure tmsezstoredproc.inheritedinternalclose; +begin + inherited internalclose; +end; + +procedure tmsezstoredproc.internalclose; +begin + fcontroller.internalclose; +end; + +function tmsezstoredproc.getblobdatasize: integer; +begin + result:= 0; //no blobs +end; + +function tmsezstoredproc.getnumboolean: boolean; +begin + result:= true; +end; + +function tmsezstoredproc.getfloatdate: boolean; +begin + result:= false; +end; + +function tmsezstoredproc.getint64currency: boolean; +begin + result:= false; +end; + +function tmsezstoredproc.getsavepointoptions(): savepointoptionsty; +begin + result:= []; +end; + +function tmsezstoredproc.getfiltereditkind: filtereditkindty; +begin + result:= fek_filter; +end; + +procedure tmsezstoredproc.beginfilteredit(const akind: filtereditkindty); +begin + //dummy +end; + +procedure tmsezstoredproc.endfilteredit; +begin +//dummy +end; + +procedure tmsezstoredproc.clearfilter; +begin +//dummy +end; +{ +procedure tmsezstoredproc.doidleapplyupdates; +begin + //dummy +end; +} +function tmsezstoredproc.getcanmodify: boolean; +begin + result:= fcontroller.getcanmodify and inherited getcanmodify; +end; +{ +procedure tmsezstoredproc.dscontrolleroptionschanged(const aoptions: datasetoptionsty); +begin + //dummy +end; +} +function tmsezstoredproc.getrestorerecno: boolean; +begin + result:= false; +end; + +procedure tmsezstoredproc.setrestorerecno(const avalue: boolean); +begin + //dummy +end; + +function tmsezstoredproc.islastrecord: boolean; +begin + result:= eof or (recno = recordcount); +end; + +procedure tmsezstoredproc.dataevent(event: tdataevent; info: ptrint); +begin + fcontroller.dataevent(event,info); +end; + +function tmsezstoredproc.updatesortfield(const afield: tfield; + const adescend: boolean): boolean; +begin + result:= false; +end; + +procedure tmsezstoredproc.begindisplaydata; +begin + //dummy +end; + +procedure tmsezstoredproc.enddisplaydata; +begin + //dummy +end; + +procedure tmsezstoredproc.inheritedinsert; +begin + inherited insert(); +end; + +procedure tmsezstoredproc.inheriteddelete; +begin + inherited delete(); +end; + +{ tmsezgraphicfield } + +constructor tmsezgraphicfield.create(aowner: tcomponent); +begin + inherited; + setdatatype(ftblob); +end; + +end. diff --git a/mseide-msegui/lib/common/db/msqldb.pas b/mseide-msegui/lib/common/db/msqldb.pas new file mode 100644 index 0000000..efe84e1 --- /dev/null +++ b/mseide-msegui/lib/common/db/msqldb.pas @@ -0,0 +1,2880 @@ +{ + Copyright (c) 2004 by Joost van der Sluis + + SQL database & dataset + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Modified 2006-2017 by Martin Schreiber + + **********************************************************************} + +unit msqldb; + +{$ifdef FPC} +{$mode objfpc}{$interfaces corba}{$goto on}{$H+} +{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + sysutils,classes,mclasses,mdb,msebufdataset,msetypes,msedb,mseclasses, + msedatabase,msestrings,msearrayutils,msedatalist,mseinterfaces, + mseapplication,mseglob,msetimer,msearrayprops,msemacros; + +type + TSchemaType = (stNoSchema,stTables,stSysTables,stProcedures,stColumns, + stProcedureParams,stIndexes,stPackages); + sqlconnoptionty = (sco_supportparams,sco_forceparams, + sco_emulateretaining,sco_nounprepared, + sco_blobscached); +// dbf_params,dbf_blobscached + sqlconnoptionsty = set of sqlconnoptionty; + +// TSQLQuery = class; + + TStatementType = (stNone, stSelect, stInsert, stUpdate, stDelete, + stDDL, stGetSegment, stPutSegment, stExecProcedure, + stStartTrans, stCommit, stRollback, stSelectForUpd); + +const + updatestatementtypes: array[tupdatekind] of tstatementtype = + //(ukModify, ukInsert, ukDelete) + (stupdate, stinsert, stdelete); + StatementTokens : Array[TStatementType] of msestring = + ('(none)', 'select', + 'insert', 'update', 'delete', + 'create', 'get', 'put', 'execute', + 'start','commit','rollback', '?' + ); + datareturningtypes = [stselect,stexecprocedure]; + +type + tcustomsqlconnection = class; + TSQLTransaction = class; + + tsqlstringlist = class(tmacrostringlist) + end; + + TSQLHandle = Class(TObject) + end; + + icursorclient = interface(iblobchache) + function stringmemo: boolean; //memo fields are text(0) fields + end; + + TSQLCursor = Class(TSQLHandle) + private + fblobs: stringarty; + fblobcount: integer; + fowner: icursorclient; + protected + public + FPrepared : Boolean; + FInitFieldDef : Boolean; + FStatementType : TStatementType; + ftrans: pointer; + fname: ansistring; + frowsaffected: integer; + frowsreturned: integer; + constructor create(const aowner: icursorclient; const aname: ansistring); + //aowner can be nil + procedure close; virtual; + function wantblobfetch: boolean; + function stringmemo: boolean; + function getcachedblob(const blobid: integer): tstream; + function addblobdata(const adata: pointer; const alength: integer): integer; + overload; + procedure addblobcache(const aid: int64; const adata: string); + function addblobdata(const adata: string): integer; overload; + procedure blobfieldtoparam(const afield: tfield; const aparam: tparam; + const asstring: boolean = false); + end; + + econnectionerror = class(edatabaseerror) + private + ferror: integer; + ferrormessage: msestring; + fsender: tcustomsqlconnection; + public + constructor create(const asender: tcustomsqlconnection; + const amessage: ansistring; + const aerrormessage: msestring; const aerror: integer); + property sender: tcustomsqlconnection read fsender; + property error: integer read ferror; + property errormessage: msestring read ferrormessage; + end; + + tdbcontroller = class(tactivatorcontroller) + private + fdatabasename: filenamety; +// fintf: idbcontroller; + foptions: databaseoptionsty; +// factioncount: integer; +// factionwait: boolean; + procedure setoptions(const avalue: databaseoptionsty); + protected + procedure setowneractive(const avalue: boolean); override; + public + constructor create(const aowner: tmdatabase; const aintf: idbcontroller); + function getdatabasename: filenamety; + procedure setdatabasename(const avalue: filenamety); + published + property options: databaseoptionsty read foptions write setoptions default []; + end; + + getcredentialseventty = procedure(const sender: tcustomsqlconnection; + var ausername: msestring; var apassword: msestring) + of object; + tmsesqlscript = class; + tcustomsqlconnection = class(TmDatabase,idbcontroller,iactivatorclient) + private + FPassword : msestring; + FTransaction : TSQLTransaction; + FUserName : msestring; + FHostName : msestring; + FCharSet : msestring; + FRole : mseString; + + fafterconnect: tmsesqlscript; + fbeforedisconnect: tmsesqlscript; +// fdatasets1: datasetarty; +// frecnos: integerarty; + ftransactionwrite: tsqltransaction; + fongetcredentials: getcredentialseventty; + procedure setcontroller(const avalue: tdbcontroller); + procedure settransaction(const avalue : tsqltransaction); + procedure settransactionwrite(const avalue: tsqltransaction); + procedure GetDBInfo(const SchemaType : TSchemaType; + const SchemaObjectName, ReturnField : string; + out list: msestringarty); +// function getconnected: boolean; + procedure setafteconnect(const avalue: tmsesqlscript); + procedure setbeforedisconnect(const avalue: tmsesqlscript); +// procedure closeds; +// procedure reopends; + protected + FConnOptions: sqlconnoptionsty; + fcontroller: tdbcontroller; + function connectionmessage(atext: pchar): msestring; + procedure finalizetransaction(const atransaction: tsqlhandle); virtual; +// procedure setconnected(const avalue: boolean); + procedure notification(acomponent: tcomponent; operation: toperation); override; + + function StrToStatementType(s : msestring) : TStatementType; virtual; + procedure getcredentials(var ausername: msestring; var apassword: msestring); + procedure freecredentials(var ausername: msestring; var apassword: msestring); + //fill with #0 before free + procedure DoInternalConnect; override; + procedure doafterinternalconnect; override; + procedure dobeforeinternaldisconnect; override; + procedure DoInternalDisconnect; override; + function GetAsSQLText(const Field : TField) : msestring; overload; virtual; + function GetAsSQLText(const Param : TParam) : msestring; overload; virtual; + function GetHandle : pointer; virtual; + procedure updateprimarykeyfield(const afield: tfield; + const atransaction: tsqltransaction); virtual; + + Function AllocateTransactionHandle : TSQLHandle; virtual; abstract; + + procedure internalexecute(const cursor: tsqlcursor; const atransaction: tsqltransaction; + const aparams : tmseparams; const autf8: boolean); virtual; abstract; + procedure internalexecuteunprepared(const cursor: tsqlcursor; + const atransaction: tsqltransaction; + const asql: string; const origsql: msestring; + const aparams: tmseparams); virtual; + + procedure Execute(const cursor: TSQLCursor; const atransaction: tsqltransaction; + const AParams : TmseParams; const autf8: boolean); + procedure Executeunprepared(const cursor: TSQLCursor; + const atransaction: tsqltransaction; + const AParams : TmseParams; + const asql: msestring; const autf8: boolean); + function GetTransactionHandle(trans : TSQLHandle): pointer; virtual; abstract; + function Commit(trans : TSQLHandle) : boolean; virtual; abstract; + function RollBack(trans : TSQLHandle) : boolean; virtual; abstract; + function StartdbTransaction(const trans : TSQLHandle; + const aParams: tstringlist) : boolean; virtual; abstract; + procedure internalcommitretaining(trans : tsqlhandle); virtual; abstract; + procedure internalrollbackretaining(trans : tsqlhandle); virtual; abstract; + + procedure CommitRetaining(trans : TSQLHandle); virtual; + procedure RollBackRetaining(trans : TSQLHandle); virtual; + function getblobdatasize: integer; virtual; abstract; + function getnumboolean: boolean; virtual; + function getfloatdate: boolean; virtual; + function getint64currency: boolean; virtual; + + procedure UpdateIndexDefs(var IndexDefs : TIndexDefs; + const aTableName : string; const acursor: tsqlcursor); virtual; + function getprimarykeyfield(const atablename: string; + const acursor: tsqlcursor): string; virtual; + function GetSchemaInfoSQL(SchemaType : TSchemaType; + SchemaObjectName, SchemaPattern : msestring) : msestring; virtual; + function CreateBlobStream(const Field: TField; const Mode: TBlobStreamMode; + const acursor: tsqlcursor): TStream; virtual; + + procedure closeds(out activeds: integerarty); + procedure reopends(const activeds: integerarty); + function identquotechar: msestring; virtual; + procedure beginupdate; virtual; + procedure endupdate; virtual; + function internalExecuteDirect(const aSQL: mseString; + ATransaction: TSQLTransaction; + const aparams: tmseparams; aparamvars: array of variant; + aisutf8: boolean; const noprepare: boolean): integer; + //idbcontroller + procedure setinheritedconnected(const avalue: boolean); + function readsequence(const sequencename: string): msestring; virtual; + function sequencecurrvalue(const sequencename: string): msestring; virtual; + function writesequence(const sequencename: string; + const avalue: largeint): msestring; virtual; +// function getfeatures(): databasefeaturesty virtual; + function blobscached: boolean; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure updateutf8(var autf8: boolean); virtual; + function isutf8: boolean; + function todbstring(const avalue: msestring): string; + function tomsestring(const avalue: string): msestring; + procedure FreeFldBuffers(cursor : TSQLCursor); virtual; abstract; + Function AllocateCursorHandle(const aowner: icursorclient; + const aname: ansistring): TSQLCursor; virtual; abstract; + //aowner can be nil + //aowner used as blob cache + Procedure DeAllocateCursorHandle(var cursor : TSQLCursor); virtual; abstract; + procedure preparestatement(const cursor: tsqlcursor; + const atransaction : tsqltransaction; + const asql: msestring; const aparams : tmseparams); + overload; virtual; abstract; + procedure UnPrepareStatement(cursor : TSQLCursor); virtual; abstract; + procedure AddFieldDefs(const cursor: TSQLCursor; + const FieldDefs: TfieldDefs); virtual; abstract; + function Fetch(cursor : TSQLCursor) : boolean; virtual; abstract; + function loadfield(const cursor: tsqlcursor; + const datatype: tfieldtype; const fieldnum: integer; //null based + const buffer: pointer; var bufsize: integer; + const aisutf8: boolean): boolean; virtual; abstract; + //if bufsize < 0 -> buffer was to small, should be -bufsize + //buffer can be nil + //false if null + function fetchblob(const cursor: tsqlcursor; + const fieldnum: integer): ansistring; virtual; + //null based + + procedure Close; + procedure Open; + property Handle: Pointer read GetHandle; + procedure StartTransaction; override; + procedure EndTransaction; override; + property ConnOptions: sqlconnoptionsty read FConnOptions; + function executedirect(const asql: msestring; + const aisutf8: boolean = false): integer; overload; + //returns rowsaffected or -1 if not supported + function executedirect(const asql: msestring; + atransaction: tsqltransaction; + const aparams: tmseparams = nil; + const aisutf8: boolean = false; + const anoprepare: boolean = false): integer; overload; + function ExecuteDirect(const aSQL: mseString; + ATransaction: TSQLTransaction; + const aparams: array of variant; + const aisutf8: boolean = false; + const anoprepare: boolean = false): integer; overload; + procedure GetTableNames(out List: msestringarty; + SystemTables: Boolean = false); virtual; + procedure GetProcedureNames(out List: msestringarty); virtual; + procedure GetFieldNames(const TableName: string; + out List: msestringarty); virtual; + function getinsertid(const atransaction: tsqltransaction): int64; virtual; + function fieldtosql(const afield: tfield): msestring; + function fieldtooldsql(const afield: tfield): msestring; + function paramtosql(const aparam: tparam): msestring; + + property Password : msestring read FPassword write FPassword; + property Transaction : TSQLTransaction read FTransaction write SetTransaction; + property transactionwrite : tsqltransaction read ftransactionwrite + write settransactionwrite; + property UserName : msestring read FUserName write FUserName; + property CharSet : msestring read FCharSet write FCharSet; + property HostName : msestring Read FHostName Write FHostName; + + property Connected: boolean read getconnected write setconnected default false; + Property Role : msestring read FRole write FRole; + property afterconnect: tmsesqlscript read fafterconnect write setafteconnect; + property beforedisconnect: tmsesqlscript read fbeforedisconnect write setbeforedisconnect; + property controller: tdbcontroller read fcontroller write setcontroller; + property ongetcredentials: getcredentialseventty read fongetcredentials + write fongetcredentials; + end; + + tsqlconnection = class(tcustomsqlconnection) + published + property Password; + property Transaction; + property transactionwrite; + property UserName; + property CharSet; + property HostName; + property controller; + + property Connected; + Property Role; + property DatabaseName; + property KeepConnection; +// property LoginPrompt; + property Params; + property ongetcredentials; + property afterconnect; + property beforedisconnect; +// property OnLogin; + end; + + TCommitRollbackAction = (caNone, caCommit, caCommitRetaining, caRollback, + caRollbackRetaining); + transactionoptionty = (tao_fake,tao_fakeretaining, + tao_catcherror,tao_rollbackonerror, + tao_refreshdatasets); + transactionoptionsty = set of transactionoptionty; + sqltransactioneventty = procedure(const sender: tsqltransaction) of object; + commiterroreventty = procedure(const sender: tsqltransaction; + const aexception: exception; var handled: boolean) of object; + + TSQLTransaction = class (TmDBTransaction) + private + FTrans: TSQLHandle; + FAction: TCommitRollbackAction; + FParams: TStringList; + fstartcount: integer; + foptions: transactionoptionsty; + fonbeforestart: sqltransactioneventty; + fonafterstart: sqltransactioneventty; + fonbeforecommit: sqltransactioneventty; + fonaftercommit: sqltransactioneventty; + fonbeforecommitretaining: sqltransactioneventty; + fonaftercommitretaining: sqltransactioneventty; + fonbeforerollbackretaining: sqltransactioneventty; + fonafterrollbackretaining: sqltransactioneventty; + fonbeforerollback: sqltransactioneventty; + fonafterrollback: sqltransactioneventty; + foncommiterror: commiterroreventty; + fonbeforestop: sqltransactioneventty; + fonafterstop: sqltransactioneventty; + fpendingaction: tcommitrollbackaction; + fpendingrefresh: boolean; + procedure setparams(const avalue: TStringList); + function getdatabase: tcustomsqlconnection; + procedure setdatabase1(const avalue: tcustomsqlconnection); + function docommit(const retaining: boolean): boolean; + procedure setpendingaction(const avalue: tcommitrollbackaction); + protected + fsavepointlevel: integer; + procedure CloseTrans; override; + function GetHandle : Pointer; virtual; + Procedure SetDatabase (Value : tmdatabase); override; + procedure disconnect(const sender: itransactionclient; + const auxclients: integer); + procedure finalizetransaction; override; + procedure doendtransaction(const aaction: tcommitrollbackaction); + procedure dobeforestop; + procedure doafterstop; + procedure checkpendingaction; + procedure savepointevent(const akind: savepointeventkindty; + const alevel: integer); + procedure execerror(); + public + constructor Create(AOwner : TComponent); override; + destructor Destroy; override; + procedure refresh(aaction: tcommitrollbackaction = canone); + //canone -> action property + //closes transaction, calls refreshdatasets + function Commit(const checksavepoint: boolean = true): boolean; virtual; //true if ok + function CommitRetaining(const checksavepoint: boolean = true): boolean; virtual; + procedure Rollback; virtual; + procedure RollbackRetaining; virtual; + procedure StartTransaction; override; + property Handle: Pointer read GetHandle; + procedure EndTransaction; override; + function savepointbegin: integer; + procedure savepointrollback(alevel: integer = -1); + //-1 -> toplevel + procedure savepointrelease; + property savepointlevel: integer read fsavepointlevel; + property trans: tsqlhandle read ftrans; + property pendingaction: tcommitrollbackaction read fpendingaction + write setpendingaction; + //will be executed on savepointlevel 0 + property pendingrefresh: boolean read fpendingrefresh + write fpendingrefresh; + published + property options: transactionoptionsty read foptions write foptions default []; + property Action : TCommitRollbackAction read FAction write FAction default canone; + property Database: tcustomsqlconnection read getdatabase write setdatabase1; + property Params : TStringList read FParams write setparams; + property oncommiterror: commiterroreventty read foncommiterror + write foncommiterror; + property onbeforestart: sqltransactioneventty read fonbeforestart + write fonbeforestart; + property onafterstart: sqltransactioneventty read fonafterstart + write fonafterstart; + property onbeforestop: sqltransactioneventty read fonbeforestop + write fonbeforestop; + property onafterstop: sqltransactioneventty read fonafterstop + write fonafterstop; + property onbeforecommit: sqltransactioneventty read fonbeforecommit + write fonbeforecommit; + property onaftercommit: sqltransactioneventty read fonaftercommit + write fonaftercommit; + property onbeforecommitretaining: sqltransactioneventty + read fonbeforecommitretaining write fonbeforecommitretaining; + property onaftercommitretaining: sqltransactioneventty + read fonaftercommitretaining write fonaftercommitretaining; + property onbeforerollback: sqltransactioneventty read fonbeforerollback + write fonbeforerollback; + property onafterrollback: sqltransactioneventty read fonafterrollback + write fonafterrollback; + property onbeforerollbackretaining: sqltransactioneventty + read fonbeforerollbackretaining + write fonbeforerollbackretaining; + property onafterrollbackretaining: sqltransactioneventty + read fonafterrollbackretaining + write fonafterrollbackretaining; + end; + + tcustomsqlstatement = class; + + sqlstatementeventty = procedure(const sender: tcustomsqlstatement; + const adatabase: tcustomsqlconnection; + const atransaction: tsqltransaction) of object; + sqlstatementerroreventty = procedure(const sender: tcustomsqlstatement; + const adatabase: tcustomsqlconnection; + const atransaction: tsqltransaction; const e: exception; + var handled: boolean) of object; + + sqlstatementoptionty = (sso_utf8,sso_autocommit,sso_autocommitret, + sso_noprepare, + sso_savepoint //for tmsesqlscript + ); + sqlstatementoptionsty = set of sqlstatementoptionty; + + tcustomsqlstatement = class(tmsecomponent,itransactionclient,idatabaseclient) + private + fonbeforeexecute: sqlstatementeventty; + fonafterexecute: sqlstatementeventty; + fonerror: sqlstatementerroreventty; + procedure setsql(const avalue: tsqlstringlist); + procedure setdatabase1(const avalue: tcustomsqlconnection); + procedure setparams(const avalue: tmseparams); + procedure settransaction1(const avalue: tsqltransaction); + procedure setoptions(const avalue: sqlstatementoptionsty); + //itransactionclient + function getname: string; + function getactive: boolean; virtual; + procedure settransaction(const avalue: tmdbtransaction); + procedure settransactionwrite(const avalue: tmdbtransaction); + procedure checkbrowsemode; + procedure refreshtransaction; + procedure savepointevent(const sender: tmdbtransaction; + const akind: savepointeventkindty; const alevel: integer); + //idbclient + procedure setdatabase(const avalue: tmdatabase); + function gettransaction: tmdbtransaction; + function getrecno: integer; + procedure setrecno(value: integer); + procedure disablecontrols; + procedure enablecontrols; + function moveby(distance: longint): longint; +// procedure readoptionsold(areader: treader); +// procedure readoptions(areader: treader); +// procedure writeoptions(awriter: twriter); + protected + fsql: tsqlstringlist; + fdatabase: tcustomsqlconnection; + ftransaction: tsqltransaction; + fparams: tmseparams; + foptions: sqlstatementoptionsty; +// procedure defineproperties(afiler: tfiler); override; + function getdatabase: tcustomconnection; //for isqlpropertyeditor + procedure setactive(avalue: boolean); virtual; + procedure execute; virtual; abstract; + procedure dobeforeexecute(const adatabase: tcustomsqlconnection; + const atransaction: tsqltransaction); + procedure doafterexecute(const adatabase: tcustomsqlconnection; + const atransaction: tsqltransaction); + procedure doerror(const adatabase: tcustomsqlconnection; + const atransaction: tsqltransaction; const e: exception; + var handled: boolean); + procedure dosqlchange(const sender: tobject); virtual; + property onbeforeexecute: sqlstatementeventty read fonbeforeexecute + write fonbeforeexecute; + property onafterexecute: sqlstatementeventty read fonafterexecute + write fonafterexecute; + property onerror: sqlstatementerroreventty read fonerror write fonerror; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function isutf8: boolean; + property params : tmseparams read fparams write setparams; + property sql: tsqlstringlist read fsql write setsql; + property database: tcustomsqlconnection read fdatabase write setdatabase1; + property transaction: tsqltransaction read ftransaction write settransaction1; + //can be nil + property options: sqlstatementoptionsty read foptions + write setoptions {stored false} default [] ; + end; + + msesqlscripteventty = procedure(const sender: tmsesqlscript) of object; + + tmsesqlscript = class(tcustomsqlstatement) + private + fstatementnr: integer; + fstatementcount: integer; +// fstatements: msestringarty; + fonbeforestatement: msesqlscripteventty; + fonafterstatement: msesqlscripteventty; + fterm: msechar; + fcharescapement: boolean; + protected + procedure execute; overload; override; + public + constructor create(aowner: tcomponent); override; + procedure execute(adatabase: tcustomsqlconnection = nil; + atransaction: tsqltransaction = nil); overload; + property statementnr: integer read fstatementnr; //zero based + property statementcount: integer read fstatementcount; +// property fstatements: msestringarty read fstatements; + published + property term: msechar read fterm write fterm default ';'; + property charescapement: boolean read fcharescapement + write fcharescapement default false; + property onbeforestatement: msesqlscripteventty read fonbeforestatement + write fonbeforestatement; + property onafterstatement: msesqlscripteventty read fonafterstatement + write fonafterstatement; + property params; + property sql; + property database; + property transaction; + //can be nil + property options; + property onbeforeexecute; + property onafterexecute; + property onerror; + end; + + tcursorsqlstatement = class(tcustomsqlstatement) + private + protected + fcursor: tsqlcursor; + fstatementtype: tstatementtype; + procedure internalclose; + function getactive: boolean; override; + procedure setactive(avalue: boolean); override; + procedure dosqlchange(const sender: tobject); override; + procedure checkautocommit; virtual; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function isprepared: boolean; + procedure prepare; virtual; + procedure unprepare; virtual; + procedure execute; overload; override; + procedure execute(const aparams: array of variant); overload; + function rowsaffected: integer; + //-1 if not supported + property statementtype : tstatementtype read fstatementtype + write fstatementtype default stnone; + end; + + tsqlstatement = class(tcursorsqlstatement) + published + property params; + property sql; + property database; + property transaction; + //can be nil + property options; + property statementtype; + property onbeforeexecute; + property onafterexecute; + property onerror; + end; + +const + blobidsize = sizeof(integer); +type + iblobconnection = interface(inullinterface)[miid_iblobconnection] + procedure writeblobdata(const atransaction: tsqltransaction; + const tablename: string; const acursor: tsqlcursor; + const adata: pointer; const alength: integer; + const afield: tfield; const aparam: tparam; + out newid: string); //'' -> null, id binary otherwise + //returns blobid or data in param + procedure setupblobdata(const afield: tfield; const acursor: tsqlcursor; + const aparam: tparam); + function blobscached: boolean; + end; + + isqlclient = interface(idatabaseclient) + function getsqltransaction: tsqltransaction; + procedure setsqltransaction(const avalue: tsqltransaction); + function getsqltransactionwrite: tsqltransaction; + procedure setsqltransactionwrite(const avalue: tsqltransaction); + procedure unprepare; + end; + +procedure updateparams(const aparams: tmseparams; const autf8: boolean); +procedure doexecute(const aparams: tmseparams; const atransaction: tmdbtransaction; + const acursor: tsqlcursor; adatabase: tmdatabase; + const autf8: boolean); +procedure checksqlconnection(const aname: ansistring; const avalue: tmdatabase); +procedure checksqltransaction(const aname: ansistring; const avalue: tmdbtransaction); +procedure dosetsqldatabase(const sender: isqlclient; const avalue: tmdatabase; + var acursor: tsqlcursor; var dest: tmdatabase); + +function splitsql(const asql: msestring; const term: msechar = ';'; + const charescapement: boolean = false): msestringarty; + +//function splitsqlstatements(const asqltext: msestring): msestringarty; + +implementation +uses + {$ifdef FPC}dbconst{$else}dbconst_del{$endif},strutils,msereal,msestream, + msebits,msefileutils,mseformatstr,typinfo,msesysutils,msesqlresult; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tdataset1 = class(tdataset); + tmdatabase1 = class(tmdatabase); + +procedure updateparams(const aparams: tmseparams; const autf8: boolean); +var + int1: integer; +begin + if aparams <> nil then begin + aparams.isutf8:= autf8; + for int1:= 0 to aparams.count - 1 do begin + with aparams[int1] do begin + if not isnull and (datatype in [ftFloat,ftcurrency,ftDate,ftTime,ftDateTime]) and + (asfloat = emptyreal) then begin + clear; + end; + end; + end; + end; +end; + +procedure doexecute(const aparams: tmseparams; const atransaction: tmdbtransaction; + const acursor: tsqlcursor; adatabase: tmdatabase; + const autf8: boolean); +begin + updateparams(aparams,autf8); + acursor.ftrans:= tsqltransaction(atransaction).handle; + tcustomsqlconnection(adatabase).execute(acursor,tsqltransaction(atransaction), + aParams,autf8); +end; + +procedure checksqlconnection(const aname: ansistring; const avalue: tmdatabase); +begin + if (avalue <> nil) and not (avalue is tcustomsqlconnection) then begin + exception.create(aname+': Database must be tcustomsqlconnection.'); + end; +end; + +procedure checksqltransaction(const aname: ansistring; const avalue: tmdbtransaction); +begin + if (avalue <> nil) and not (avalue is tsqltransaction) then begin + exception.create(aname+': Transaction must be tsqltransaction.'); + end; +end; + +procedure dosetsqldatabase(const sender: isqlclient; const avalue: tmdatabase; + var acursor: tsqlcursor; var dest: tmdatabase); +begin + if (dest <> avalue) then begin + checksqlconnection(sender.getname,avalue); + sender.unprepare; + if acursor <> nil then begin + tcustomsqlconnection(dest).deallocatecursorhandle(acursor); + end; + dosetdatabase(sender,avalue,dest); + if (avalue <> nil) then begin + if (sender.getsqltransaction = nil) then begin + sender.setsqltransaction(tcustomsqlconnection(avalue).transaction); + end; + if (sender.getsqltransactionwrite = nil) then begin + sender.setsqltransactionwrite(tcustomsqlconnection(avalue).transactionwrite); + end; + end; + end; +end; + +function splitsql(const asql: msestring; + const term: msechar = ';'; + const charescapement: boolean = false): msestringarty; +var + po1,po2: pmsechar; + + procedure addstatement; + begin + setlength(result,high(result)+2); + setlength(result[high(result)],po1-po2); + move(po2^,result[high(result)][1],length(result[high(result)])*sizeof(msechar)); + end; + + procedure checkescape(var apo: pmsechar); + begin + if charescapement and (apo^ = '\') then begin + inc(apo); + if (apo^ <> #0) then begin + inc(apo); + end; + end + else begin + inc(apo); + end; + end; + +//var +// po3: pmsechar; +begin + result:= nil; + po1:= pmsechar(asql); + po2:= po1; + while po1^ <> #0 do begin + if po1^ = term then begin + po1^:= ';'; + inc(po1); + addstatement; + (po1-1)^:= term; + po2:= po1; + end + else begin + case po1^ of + '''': begin + inc(po1); + while (po1^ <> '''') and (po1^ <> #0) do begin + checkescape(po1); + end; + if po1^ = '''' then begin + inc(po1); + end; + end; + '"': begin + inc(po1); + while (po1^ <> '"') and (po1^ <> #0) do begin + checkescape(po1); + end; + if po1^ = '"' then begin + inc(po1); + end; + end; + '-': begin// possible start of -- comment + inc(po1); + if po1^ = '-' then begin // -- comment + repeat // skip until at end of line + inc(po1); + until (po1^ = #0) or (po1^ = #10); + end; + end; + '/': begin // possible start of /* */ comment + inc(po1); + if po1^ = '*' then begin // /* */ comment + repeat + inc(po1); + if po1^ = '*' then begin// possible end of comment + inc(po1); + if po1^ = '/' then begin + break; // end of comment + end; + end; + until po1^ = #0; + if po1^ = '/' then begin + inc(po1); // skip final / + end; + end; + end; + else begin + inc(po1); + end; + end; //case + end; + end; + { + if po1 <> po2 then begin //no terminating ';' + po3:= po1; + while po3 > po2 do begin //remove trailing space //////what about newline? + dec(po3); + if po3^ <> ' ' then begin + break; + end; + end; + if po3 <> po2 then begin //not empty + addstatement; + end; + end; + } +end; + + +{ tdbcontroller } + +constructor tdbcontroller.create(const aowner: tmdatabase; const aintf: idbcontroller); +begin +// fintf:= aintf; + inherited create(aowner,aintf); +end; + +procedure tdbcontroller.setowneractive(const avalue: boolean); +//var +// bo1: boolean; +begin + idbcontroller(fintf).setinheritedconnected(avalue); + { + if avalue then begin + with tmdatabase(fowner) do begin + if checkcanevent(fowner,tmethod(fonbeforeconnect)) then begin + fonbeforeconnect(tmdatabase(fowner)); + end; + try + fintf.setinheritedconnected(avalue); + except + on e: exception do begin + if checkcanevent(fowner,tmethod(fonconnecterror)) then begin + bo1:= false; + fonconnecterror(tmdatabase(fowner),e,bo1); + if not bo1 then begin + raise; + end; + end; + end; + end; + if checkcanevent(fowner,tmethod(fonafterconnect)) then begin + fonafterconnect(tmdatabase(fowner)); + end; + end; + end + else begin + fintf.setinheritedconnected(avalue); +// tmdatabase(fowner).connected:= avalue; + end; + } +end; + +function tdbcontroller.getdatabasename: filenamety; +begin + result:= fdatabasename; +end; + +procedure tdbcontroller.setdatabasename(const avalue: filenamety); +var + str1: filenamety; +begin + str1:= trim(avalue); + if (str1 <> '') and (str1[1] = '''') and + (str1[length(str1)] = '''') then begin + fdatabasename:= str1; + tmdatabase(fowner).databasename:= copy(str1,2,length(str1)-2); + end + else begin + fdatabasename:= tomsefilepath(str1); + tmdatabase(fowner).databasename:= + tosysfilepath(filepath(str1,fk_default,true)); + end; +end; + +procedure tdbcontroller.setoptions(const avalue: databaseoptionsty); +const + mask: databaseoptionsty = [dbo_utf8,dbo_noutf8]; +begin + if foptions <> avalue then begin +// tmdatabase1(fowner).checkdisconnected; + foptions:= databaseoptionsty(setsinglebit( + {$ifdef FPC}longword{$else}byte{$endif}(avalue), + {$ifdef FPC}longword{$else}byte{$endif}(foptions), + {$ifdef FPC}longword{$else}byte{$endif}(mask))); + end; +end; + +{ tcustomsqlconnection } + +constructor tcustomsqlconnection.create(aowner: tcomponent); +begin + fcontroller:= tdbcontroller.create(self,idbcontroller(self)); + inherited; +end; + +destructor tcustomsqlconnection.destroy; +begin + inherited; + fcontroller.free; +end; + +function tcustomsqlconnection.connectionmessage(atext: pchar): msestring; +begin + if dbo_utf8message in fcontroller.foptions then begin + result:= utf8tostring(atext); + end + else begin + result:= atext; + end; +end; + +procedure tcustomsqlconnection.setinheritedconnected(const avalue: boolean); +begin + connected:= avalue; +end; + +function tcustomsqlconnection.readsequence( + const sequencename: string): msestring; +begin + result:= ''; //dummy +end; + +function tcustomsqlconnection.sequencecurrvalue( + const sequencename: string): msestring; +begin + result:= ''; //dummy +end; + +function tcustomsqlconnection.writesequence(const sequencename: string; + const avalue: largeint): msestring; +begin + result:= ''; //dummy +end; +{ +function tcustomsqlconnection.getfeatures(): databasefeaturesty; +begin + result:= []; +end; +} +function tcustomsqlconnection.blobscached: boolean; +begin + result:= sco_blobscached in fconnoptions; +// result:= dbf_blobscached in getfeatures; +end; + +procedure tcustomsqlconnection.updateutf8(var autf8: boolean); +begin + if dbo_utf8 in fcontroller.options then begin + autf8:= true; + end; + if dbo_noutf8 in fcontroller.options then begin + autf8:= false; + end; +end; + +function tcustomsqlconnection.isutf8: boolean; +begin + result:= false; + updateutf8(result); +end; + +function tcustomsqlconnection.StrToStatementType(s: msestring) : TStatementType; + +var T : TStatementType; + +begin + result:= stnone; + S:= mseLowercase(s); + For t:= stselect to strollback do + if (S=StatementTokens[t]) then begin + result:= t; + Exit; + end; +end; + +procedure tcustomsqlconnection.getcredentials(var ausername: msestring; + var apassword: msestring); +begin + if assigned(fongetcredentials) then begin + ausername:= username; + apassword:= ''; + fongetcredentials(self,ausername,apassword); + end + else begin + ausername:= username; + apassword:= password; + end; + uniquestring(ausername); + uniquestring(apassword); +end; + +procedure tcustomsqlconnection.freecredentials(var ausername: msestring; + var apassword: msestring); +begin + stringsafefree(ausername,false); + stringsafefree(apassword,false); +end; + +procedure tcustomsqlconnection.settransaction(const avalue : tsqltransaction); +begin + if ftransaction <> avalue then begin + if assigned(ftransaction) and ftransaction.active then begin + databaseerror(serrasstransaction); + end; + if assigned(avalue) then begin + avalue.database:= self; + end; + ftransaction:= avalue; + end; +end; + +procedure tcustomsqlconnection.settransactionwrite(const avalue : tsqltransaction); +begin + if ftransactionwrite <> avalue then begin + if assigned(ftransactionwrite) and ftransactionwrite.active then begin + databaseerror(serrasstransaction); + end; + if assigned(avalue) then begin + avalue.database:= self; + end; + ftransactionwrite:= avalue; + end; +end; + + +procedure tcustomsqlconnection.UpdateIndexDefs(var IndexDefs : TIndexDefs; + const aTableName : string; const acursor: tsqlcursor); + +begin + //dummy +end; + +procedure tcustomsqlconnection.DoInternalConnect; +begin + if (DatabaseName = '') then + DatabaseError(SErrNoDatabaseName,self); +end; + +procedure tcustomsqlconnection.DoInternalDisconnect; +begin + //dummy +end; + +procedure tcustomsqlconnection.StartTransaction; +begin + if not assigned(Transaction) then + DatabaseError(SErrConnTransactionnSet) + else + Transaction.StartTransaction; +end; + +procedure tcustomsqlconnection.EndTransaction; +begin + if not assigned(Transaction) then + DatabaseError(SErrConnTransactionnSet) + else + Transaction.EndTransaction; +end; + +function tcustomsqlconnection.executedirect(const asql: msestring; + const aisutf8: boolean = false): integer; +begin + result:= executedirect(asql,ftransaction,[],aisutf8); +end; + +function tcustomsqlconnection.internalExecuteDirect(const aSQL: mseString; + ATransaction: TSQLTransaction; + const aparams: tmseparams; aparamvars: array of variant; + aisutf8: boolean; const noprepare: boolean): integer; +var + Cursor: TSQLCursor; + params1: tmseparams; + bo1,bo2: boolean; + int1: integer; +// str1: ansistring; +begin + if atransaction = nil then begin + atransaction:= ftransaction; + end; + bo1:= (aparams = nil) and (high(aparamvars) >= 0); + if bo1 then begin + params1:= tmseparams.create; + params1.parsesql(asql,true); + for int1:= 0 to high(aparamvars) do begin + params1[int1].value:= aparamvars[int1]; + end; + end + else begin + params1:= aparams; + end; + try + if not assigned(ATransaction) then begin + DatabaseError(SErrTransactionnSet); + end; + connected:= true; + if not ATransaction.Active then begin + ATransaction.StartTransaction; + end; + try + Cursor:= AllocateCursorHandle(nil,name); + cursor.ftrans:= atransaction.handle; + if trimright(asql) = '' then begin + DatabaseError(SErrNoStatement); + end; + Cursor.FStatementType := stNone; + if not noprepare then begin + PrepareStatement(cursor,ATransaction,aSQL,params1); + end; + cursor.ftrans:= atransaction.handle; + updateutf8(aisutf8); + if params1 <> nil then begin + bo2:= params1.isutf8; + params1.isutf8:= aisutf8; + end; + try + try + if noprepare then begin + executeunprepared(cursor,atransaction,params1,asql,aisutf8); + end + else begin + execute(cursor,atransaction,params1,aisutf8); + end; + except + atransaction.execerror(); + raise; + end; + result:= cursor.frowsaffected; + finally + UnPrepareStatement(Cursor); + if params1 <> nil then begin + params1.isutf8:= bo2; + end; + end; + finally; + DeAllocateCursorHandle(Cursor); + end; + finally + if bo1 then begin + params1.free; + end; + end; +end; + +function tcustomsqlconnection.ExecuteDirect(const aSQL: mseString; + ATransaction: TSQLTransaction; + const aparams: tmseparams = nil; + const aisutf8: boolean = false; + const anoprepare: boolean = false): integer; +begin + result:= internalexecutedirect(asql,atransaction,aparams,[],aisutf8, + anoprepare and not (sco_nounprepared in fconnoptions)); +end; + +function tcustomsqlconnection.ExecuteDirect(const aSQL: mseString; + ATransaction: TSQLTransaction; + const aparams: array of variant; + const aisutf8: boolean = false; + const anoprepare: boolean = false): integer; +begin + result:= internalexecutedirect(asql,atransaction,nil,aparams,aisutf8, + anoprepare and not (sco_nounprepared in fconnoptions)); +end; + +procedure tcustomsqlconnection.GetDBInfo(const SchemaType: TSchemaType; + const SchemaObjectName, ReturnField : string; + out list: msestringarty); +var + res: tsqlresult; + col1: tdbcol; + int1: integer; +begin + if not assigned(Transaction) then begin + DatabaseError(SErrConnTransactionnSet); + end; + res:= tsqlresult.create(nil); + try + with res do begin + database:= Self; + sql.text:= GetSchemaInfoSQL(SchemaType, msestring(SchemaObjectName), ''); + active:= true; + col1:= datacols.colbyname(returnfield); + if rowsreturned >= 0 then begin + setlength(list,rowsreturned); + end + else begin + list:= nil; + end; + int1:= 0; + while not eof do begin + if high(list) < int1 then begin + setlength(list,2*high(list)+18); + end; + list[int1]:= col1.asmsestring; + inc(int1); + next; + end; + end; + setlength(list,int1); + finally + res.free; + end; +end; + +(* +procedure tcustomsqlconnection.GetDBInfo(const SchemaType : TSchemaType; + const SchemaObjectName, ReturnField : string; List: TStrings); + +var + qry: TSQLQuery; + +begin + if not assigned(Transaction) then + DatabaseError(SErrConnTransactionnSet); + + qry := TSQLQuery.Create(nil); + qry.transaction := Transaction; + qry.database := Self; + with qry do + begin + ParseSQL := False; + SetSchemaInfo(SchemaType,SchemaObjectName,''); + open; + List.Clear; + while not eof do + begin + List.Append(fieldbyname(ReturnField).asstring); + Next; + end; + end; + qry.free; +end; +*) + +procedure tcustomsqlconnection.GetTableNames(out List: msestringarty; + SystemTables: Boolean); +begin + if not systemtables then GetDBInfo(stTables,'','table_name',List) + else GetDBInfo(stSysTables,'','table_name',List); +end; + +procedure tcustomsqlconnection.GetProcedureNames(out List: msestringarty); +begin + GetDBInfo(stProcedures,'','proc_name',List); +end; + +procedure tcustomsqlconnection.GetFieldNames(const TableName: string; + out List: msestringarty); +begin + GetDBInfo(stColumns,TableName,'column_name',List); +end; + +function tcustomsqlconnection.GetAsSQLText(const Field: TField): msestring; +begin + result:= msedb.fieldtosql(field); +end; + +function tcustomsqlconnection.GetAsSQLText(const Param: TParam): msestring; +begin + result:= msedb.paramtosql(param); +end; + + +function tcustomsqlconnection.GetHandle: pointer; +begin + Result := nil; +end; + +procedure tcustomsqlconnection.Execute(const cursor: TSQLCursor; + const atransaction: tsqltransaction; + const AParams : TmseParams; const autf8: boolean); +begin + if aparams <> nil then begin + aparams.updatevalues; + end; + beforeaction; + try + try + internalexecute(cursor,atransaction,aparams,autf8); + except + atransaction.execerror(); + raise; + end; + finally + afteraction; + end; +end; + +procedure tcustomsqlconnection.internalexecuteunprepared( + const cursor: tsqlcursor; const atransaction: tsqltransaction; + const asql: string; const origsql: msestring; + const aparams: tmseparams); +begin + raise edatabaseerror.create(name+': executeunprepared not supported.'); +end; + +procedure tcustomsqlconnection.Executeunprepared(const cursor: TSQLCursor; + const atransaction: tsqltransaction; + const AParams : TmseParams; + const asql: msestring; const autf8: boolean); +var + mstr1: msestring; + str1: ansistring; + par1: tmseparams; +begin + if aparams <> nil then begin + aparams.updatevalues; + end; + beforeaction; + try + par1:= nil; + if (aparams <> nil) and (aparams.count > 0) then begin +// if dbf_params in getfeatures then begin + if sco_forceparams in fconnoptions then begin + par1:= aparams; //asql used directly + end + else begin + mstr1:= aparams.expandvalues(asql); + end; + end + else begin + mstr1:= asql; + end; + if mstr1 <> '' then begin + if autf8 then begin + str1:= stringtoutf8ansi(mstr1); + end + else begin + str1:= ansistring(mstr1); + end; + end; + try + internalexecuteunprepared(cursor,atransaction,str1,asql,par1); + except + atransaction.execerror(); + raise; + end; + finally + afteraction; + end; +end; + +function tcustomsqlconnection.GetSchemaInfoSQL( SchemaType : TSchemaType; + SchemaObjectName, SchemaPattern : msestring) : msestring; + +begin + result:= ''; //compiler warning + DatabaseError(SMetadataUnavailable); +end; + +function tcustomsqlconnection.CreateBlobStream(const Field: TField; + const Mode: TBlobStreamMode; const acursor: tsqlcursor): TStream; + +begin + result:= nil; //compiler warning + DatabaseErrorFmt(SUnsupportedFieldType,['Blob']); +end; + +procedure tcustomsqlconnection.closeds(out activeds: integerarty); +var + int1: integer; +begin + setlength(activeds,length(datasets)); + for int1:= 0 to high(activeds) do begin + with datasets[int1] do begin + if getactive then begin + activeds[int1]:= datasets[int1].getrecno; + setactive(false); + end + else begin + activeds[int1]:= -2; + end; + end; + end; +end; + +procedure tcustomsqlconnection.reopends(const activeds: integerarty); +var + int1: integer; +begin + for int1:= 0 to high(activeds) do begin + if activeds[int1] >= -1 then begin + with datasets[int1] do begin + setactive(true); + disablecontrols; + if activeds[int1] >= 0 then begin + try + moveby(maxint); + setrecno(activeds[int1]); + except + end; + end; + enablecontrols; + end; + end; + end; +end; +{ +function tcustomsqlconnection.getconnected: boolean; +begin + result:= inherited connected; +end; +} +procedure tcustomsqlconnection.doafterinternalconnect; +begin + inherited; + if fafterconnect <> nil then begin + fafterconnect.execute(self); + end; +end; + +procedure tcustomsqlconnection.dobeforeinternaldisconnect; +var + int1: integer; +begin + if fbeforedisconnect <> nil then begin + fbeforedisconnect.execute(self); + end; + for int1:= high(datasets) downto 0 do begin + with datasets[int1] do begin + if (gettransaction = nil) or (gettransaction.active) then begin + setactive(false); //not disconnected + end; + end; + end; + { + for int1:= datasetcount - 1 downto 0 do begin + with tsqlquery(datasets[int1]) do begin + if (transaction = nil) or (transaction.active) then begin + close; //not disconnected + end; + end; + end; + } +end; +{ +procedure tcustomsqlconnection.setconnected(const avalue: boolean); +var + int1: integer; + bo1: boolean; +begin + if avalue <> fconnected then begin + if avalue then begin + if csreading in componentstate then begin + fopenafterread:= true; + exit; + end + else begin + if assigned(onbeforeconnect) then begin + onbeforeconnect(self); + end; + try + dointernalconnect; + doafterinternalconnect; + if assigned(onafterconnect) then begin + onafterconnect(self); + end; + except + on e: exception do begin + if assigned(onconnecterror) then begin + bo1:= false; + onconnecterror(self,e,bo1); + if not bo1 then begin + raise; + end + else begin + if not connected then begin + abort; + end; + end; + end + else begin + raise; + end; + end; + end; + end; + end + else begin + if assigned(onbeforedisconnect) then begin + onbeforedisconnect(self); + end; + dobeforeinternaldisconnect; + for int1:= datasetcount - 1 downto 0 do begin + with tsqlquery(datasets[int1]) do begin + if (transaction = nil) or (transaction.active) then begin + close; //not disconnected + end; + end; + end; + closetransactions; + dointernaldisconnect; + if csloading in componentstate then begin + fopenafterread := false; + end; + end; + fconnected:= avalue; + end; +end; +} +procedure tcustomsqlconnection.setafteconnect(const avalue: tmsesqlscript); +begin + if fafterconnect <> nil then begin + fafterconnect.removefreenotification(self); + end; + fafterconnect:= avalue; + if fafterconnect <> nil then begin + fafterconnect.freenotification(self); + end; +end; + +procedure tcustomsqlconnection.setbeforedisconnect(const avalue: tmsesqlscript); +begin + if fbeforedisconnect <> nil then begin + fbeforedisconnect.removefreenotification(self); + end; + fbeforedisconnect:= avalue; + if fbeforedisconnect <> nil then begin + fbeforedisconnect.freenotification(self); + end; +end; + +procedure tcustomsqlconnection.notification(acomponent: tcomponent; + operation: toperation); +//var +// int1: integer; +begin + if operation = opremove then begin + if acomponent = fafterconnect then begin + fafterconnect:= nil; + end; + if acomponent = fbeforedisconnect then begin + fbeforedisconnect:= nil; + end; + { + int1:= finditem(pointerarty(fdatasets1),acomponent); + if int1 >= 0 then begin + fdatasets1[int1]:= nil; + end; + } + end; + inherited; +end; + +procedure tcustomsqlconnection.Close; +begin + connected:= false; +end; + +procedure tcustomsqlconnection.Open; +begin + connected:= true; +end; + +procedure tcustomsqlconnection.updateprimarykeyfield(const afield: tfield; + const atransaction: tsqltransaction); +begin + //dummy +end; + +function tcustomsqlconnection.getprimarykeyfield(const atablename: string; + const acursor: tsqlcursor): string; +begin + result:= ''; +end; + +function tcustomsqlconnection.getnumboolean: boolean; +begin + result:= true; +end; + +function tcustomsqlconnection.getfloatdate: boolean; +begin + result:= false; +end; + +function tcustomsqlconnection.getint64currency: boolean; +begin + result:= false; +end; + +function tcustomsqlconnection.getinsertid(const atransaction: tsqltransaction): int64; +begin + databaseerror('Connection has no insert ID''s.'); + result:= 0; //compiler warning +end; +{ +procedure tcustomsqlconnection.closeds; +var + int1: integer; +begin + setlength(fdatasets1,datasetcount); + setlength(frecnos,length(fdatasets1)); + for int1:= high(fdatasets1) downto 0 do begin + fdatasets1[int1]:= datasets[int1]; + with fdatasets1[int1] do begin + freenotification(self); + if active then begin + frecnos[int1]:= recno; + end + else begin + frecnos[int1]:= -2; + end; + end; + end; + for int1:= high(fdatasets1) downto 0 do begin + if (fdatasets1[int1] <> nil) and + (tmdbdataset(fdatasets1[int1]).database = self) then begin + with fdatasets1[int1] do begin + active:= false; + end; + end; + end; +end; + +procedure tcustomsqlconnection.reopends; +var + int1: integer; +begin + for int1:= 0 to high(fdatasets1) do begin + if fdatasets1[int1] <> nil then begin + if frecnos[int1] >= -1 then begin + with tmdbdataset(fdatasets1[int1]) do begin + if database = self then begin + disablecontrols; + active:= true; + if frecnos[int1] >= 0 then begin + try + moveby(frecnos[int1]-recno); + except + end; + end; + enablecontrols; + end; + end; + end; + end; + end; +end; +} +procedure tcustomsqlconnection.CommitRetaining(trans: TSQLHandle); +begin + internalcommitretaining(trans); + { + if sco_emulateretaining in fconnoptions then begin + closeds; //cursors are lost + try + try + internalcommitretaining(trans); + finally + reopends; + end; + finally + fdatasets1:= nil; + frecnos:= nil; + end; + end + else begin + internalcommitretaining(trans); + end; + } +end; + +procedure tcustomsqlconnection.RollBackRetaining(trans: TSQLHandle); +begin + internalrollbackretaining(trans); +{ + if sco_emulateretaining in fconnoptions then begin + closeds; //cursors are lost + try + try + internalrollbackretaining(trans); + finally + reopends; + end; + finally + fdatasets1:= nil; + frecnos:= nil; + end; + end + else begin + internalrollbackretaining(trans); + end; +} +end; + +procedure tcustomsqlconnection.finalizetransaction(const atransaction: tsqlhandle); +begin + //dummy +end; + +function tcustomsqlconnection.fetchblob(const cursor: tsqlcursor; + const fieldnum: integer): ansistring; +begin + raise edatabaseerror.create(name+': fetchblob not supported.'); + result:= ''; //compiler warning +end; + +function tcustomsqlconnection.todbstring(const avalue: msestring): string; +begin + if isutf8 then begin + result:= stringtoutf8ansi(avalue); + end + else begin + result:= ansistring(avalue); + end; +end; + +function tcustomsqlconnection.tomsestring(const avalue: string): msestring; +begin + if isutf8 then begin + result:= utf8tostring(avalue); + end + else begin + result:= msestring(avalue); + end; +end; + +function tcustomsqlconnection.identquotechar: msestring; +begin + result:= '"'; +end; + +procedure tcustomsqlconnection.beginupdate; +begin + //dummy +end; + +procedure tcustomsqlconnection.endupdate; +begin + //dummy +end; + +function tcustomsqlconnection.fieldtosql(const afield: tfield): msestring; +begin + result:= getassqltext(afield); +end; + +function tcustomsqlconnection.fieldtooldsql(const afield: tfield): msestring; +var + statebefore: tdatasetstate; +begin + statebefore:= afield.dataset.state; + tdataset1(afield.dataset).settempstate(dsoldvalue); + result:= fieldtosql(afield); + tdataset1(afield.dataset).restorestate(statebefore); +end; + +function tcustomsqlconnection.paramtosql(const aparam: tparam): msestring; +begin + result:= getassqltext(aparam); +end; + +procedure tcustomsqlconnection.setcontroller(const avalue: tdbcontroller); +begin + fcontroller.assign(avalue); +end; + +{ TSQLTransaction } + +constructor TSQLTransaction.Create(AOwner : TComponent); +begin + fsavepointlevel:= -1; + inherited Create(AOwner); + FParams := TStringList.Create; +end; + +destructor TSQLTransaction.Destroy; +var + bo1: boolean; +begin + bo1:= active; + Rollback; + if not bo1 then begin + closedatasets; //close disconnected + end; + inherited Destroy; + FreeAndNil(FParams); + freeandnil(ftrans); +end; + +procedure TSQLTransaction.StartTransaction; +var + db: tcustomsqlconnection; + int1: integer; +begin + if Active then begin + DatabaseError(SErrTransAlreadyActive); + end; + db:= tcustomsqlconnection(database); + if Db = nil then begin + DatabaseError(SErrDatabasenAssigned); + end; + inc(fstartcount); + int1:= fstartcount; + if checkcanevent(self,tmethod(fonbeforestart)) then begin + fonbeforestart(self); + end; + if not Db.Connected then begin + Db.Open; + end; + if (int1 <> fstartcount) or not db.connected then begin + exit; + end; + if not assigned(FTrans) then begin + FTrans:= Db.AllocateTransactionHandle; + end; + if (tao_fake in foptions) or + Db.StartdbTransaction(FTrans,FParams) then begin + OpenTrans; + end; + if checkcanevent(self,tmethod(fonafterstart)) then begin + fonafterstart(self); + end; +end; + +procedure tsqltransaction.doendtransaction( + const aaction: tcommitrollbackaction); +begin + case aaction of + cacommit: commit; + cacommitretaining: commitretaining; + carollbackretaining: rollbackretaining; + else rollback; //canone,carollback + end; +end; + +procedure tsqltransaction.endtransaction; + +begin + doendtransaction(faction); +end; + +procedure tsqltransaction.refresh(aaction: tcommitrollbackaction = canone); + //canone -> action property + //closes transaction, calls refreshdatasets +var + int1: integer; +begin + int1:= bigint; + while true do begin + if int1 > high(fdatasets) then begin + int1:= high(fdatasets); + end; + if int1 < 0 then begin + break; + end; + if fdatasets[int1].getactive then begin + fdatasets[int1].checkbrowsemode; + end; + dec(int1); + end; + int1:= bigint; + while true do begin + if int1 > high(fwritedatasets) then begin + int1:= high(fwritedatasets); + end; + if int1 < 0 then begin + break; + end; + if fwritedatasets[int1].getactive then begin + fwritedatasets[int1].checkbrowsemode; + end; + dec(int1); + end; + if aaction = canone then begin + aaction:= action; + end; +// if aaction in [cacommit,cacommitretaining] then begin +// aaction:= cacommitretaining; +// end +// else begin +// aaction:= carollbackretaining; +// end; + try +// inc(fcloselock); +// try + begintrackactivestate; + try + doendtransaction(aaction); +// finally +// dec(fcloselock); +// end; + if not active then begin + starttransaction; + int1:= bigint; + while true do begin + if int1 > high(fdatasetsactive) then begin + int1:= high(fdatasetsactive); + end; + if int1 < 0 then begin + break; + end; + if fdatasetsactive[int1] then begin + fdatasets[int1].setactive(true); + end; + dec(int1); + end; + int1:= bigint; + while true do begin + if int1 > high(fwritedatasetsactive) then begin + int1:= high(fwritedatasetsactive); + end; + if int1 < 0 then begin + break; + end; + if fwritedatasetsactive[int1] then begin + fwritedatasets[int1].setactive(true); + end; + dec(int1); + end; + end + else begin + if (tao_refreshdatasets in foptions) or (aaction <> cacommit) then begin + refreshdatasets; + end; + end; + finally + endtrackactivestate; + end; + except + closedatasets; + raise; + end; +end; + +function TSQLTransaction.GetHandle: pointer; +begin + Result := (Database as tcustomsqlconnection).GetTransactionHandle(FTrans); +end; + +function tsqltransaction.docommit(const retaining: boolean): boolean; + + procedure dofinish; + begin + if retaining then begin + if tao_fakeretaining in foptions then begin + closetrans(); + starttransaction(); + end; + if (tao_refreshdatasets in foptions) then begin + refreshdatasets(true,true); + end; + end + else begin + closetrans; + closedatasets; + end; + end; + +var + bo1: boolean; +begin + result:= false; + if not (tao_fake in foptions) then begin + try + if retaining and not (tao_fakeretaining in foptions) then begin + tcustomsqlconnection(database).commitretaining(FTrans); + end + else begin + tcustomsqlconnection(database).commit(FTrans); + end; + savepointevent(spek_committrans,0); + except + on e: exception do begin + bo1:= false; + if checkcanevent(self,tmethod(foncommiterror)) then begin + foncommiterror(self,e,bo1); + end; + if not bo1 then begin + if tao_catcherror in foptions then begin + application.handleexception(self); + exit; + end + else begin + if tao_rollbackonerror in foptions then begin + try + rollback(); + except //no secondary exceptions + end; + raise; + end; + dofinish(); + raise; + end; + end; + end; + end; + end + else begin + savepointevent(spek_committrans,0); + end; + fsavepointlevel:= -1; + dofinish; + result:= true; +end; + +function TSQLTransaction.Commit(const checksavepoint: boolean = true): boolean; +begin + result:= true; + if active then begin + if checksavepoint and (fsavepointlevel >= 0) then begin + pendingaction:= cacommit; + exit; + end; + dobeforestop; + if checkcanevent(self,tmethod(fonbeforecommit)) then begin + fonbeforecommit(self); + end; + result:= docommit(false); + if result and checkcanevent(self,tmethod(fonaftercommit)) then begin + fonaftercommit(self); + end; + doafterstop; + end; +end; + +function TSQLTransaction.CommitRetaining( + const checksavepoint: boolean = true): boolean; +begin + result:= true; + if active then begin + if checksavepoint and (fsavepointlevel >= 0) then begin + pendingaction:= cacommitretaining; + exit; + end; + if checkcanevent(self,tmethod(fonbeforecommitretaining)) then begin + fonbeforecommitretaining(self); + end; + result:= docommit(true); + if result and checkcanevent(self,tmethod(fonaftercommitretaining)) then begin + fonaftercommitretaining(self); + end; + end; +end; + +procedure TSQLTransaction.Rollback; +begin + if active then begin + dobeforestop; + if checkcanevent(self,tmethod(fonbeforerollback)) then begin + fonbeforerollback(self); + end; + savepointevent(spek_rollbacktrans,0); + closedatasets; + try + if not (tao_fake in foptions) then begin + tcustomsqlconnection(database).RollBack(FTrans); + end; + finally + fsavepointlevel:= -1; + CloseTrans; + if checkcanevent(self,tmethod(fonafterrollback)) then begin + fonafterrollback(self); + end; + doafterstop; + end; + end; +end; + +procedure TSQLTransaction.RollbackRetaining; +begin + if active then begin + if checkcanevent(self,tmethod(fonbeforerollbackretaining)) then begin + fonbeforerollback(self); + end; + try + if not (tao_fake in foptions) then begin + if tao_fakeretaining in foptions then begin + tcustomsqlconnection(database).rollback(ftrans); + closetrans(); + starttransaction(); + end + else begin + tcustomsqlconnection(database).rollbackretaining(ftrans); + end; + end; + savepointevent(spek_rollbacktrans,0); + finally + fsavepointlevel:= -1; + end; + refreshdatasets(); + if checkcanevent(self,tmethod(fonafterrollbackretaining)) then begin + fonafterrollback(self); + end; + end; +end; + +procedure tsqltransaction.disconnect(const sender: itransactionclient; + const auxclients: integer); +//var +// int1: integer; +// intf1: itransactionclient; +// k1: tupdatekind; +begin +{ + int1:= 1; + if (self = sender.getwritetransaction) then begin + for k1:= low(tupdatekind) to high(tupdatekind) do begin + if sender.fapplyqueries[k1] <> nil then begin + inc(int1); + end; + end; +} + { + if sender.fupdateqry <> nil then begin + inc(int1); + end; + if sender.fdeleteqry <> nil then begin + inc(int1); + end; + if sender.finsertqry <> nil then begin + inc(int1); + end; + } +// end; + if high(fdatasets) > auxclients then begin + databaseerror('Offline mode needs exclusive transaction.', + sender.getcomponentinstance); + end; +// intf1:= itransactionclient(sender); + removeitem(pointerarty(fdatasets),pointer(sender)); + try + active:= false; + finally + insertitem(pointerarty(fdatasets),0,pointer(sender)); + end; + { + if fdatasets.count > int1 then begin + databaseerror('Offline mode needs exclusive transaction.',sender); + end; + fdatasets.remove(sender); + try + active:= false; + finally + fdatasets.insert(0,sender); + end; + } +end; + +Procedure TSQLTransaction.SetDatabase(Value : tmdatabase); + +begin + If Value <> Database then begin + CheckInactive; + If Assigned(Database) then begin + finalizetransaction; + with tcustomsqlconnection(database) do begin + if Transaction = self then begin + Transaction:= nil; + end; + if Transactionwrite = self then begin + Transactionwrite:= nil; + end; + end; + end; + inherited SetDatabase(Value); + end; +end; + +function tsqltransaction.getdatabase: tcustomsqlconnection; +begin + result:= tcustomsqlconnection(inherited database); +end; + +procedure tsqltransaction.setdatabase1(const avalue: tcustomsqlconnection); +begin + setdatabase(avalue); +end; + +procedure TSQLTransaction.setparams(const avalue: TStringList); +begin + fparams.assign(avalue); +end; + +procedure TSQLTransaction.finalizetransaction; +begin + if (database <> nil) and (ftrans <> nil) then begin + tsqlconnection(database).finalizetransaction(ftrans); + end; +end; + +function TSQLTransaction.savepointbegin: integer; +var + mstr1: msestring; +begin + active:= true; + inc(fsavepointlevel); + result:= fsavepointlevel; + mstr1:= 'sp'+inttostrmse(result); + database.executedirect('SAVEPOINT '+mstr1+';',self,nil,false,true); + savepointevent(spek_begin,result); +end; + +procedure tsqltransaction.checkpendingaction; +var + act1: tcommitrollbackaction; + bo1: boolean; +begin + if (fpendingaction <> canone) and (fsavepointlevel < 0) and active then begin + act1:= fpendingaction; + bo1:= fpendingrefresh; + fpendingaction:= canone; + fpendingrefresh:= false; + if bo1 then begin + refresh(act1); + end + else begin + doendtransaction(act1); + end; + end; +end; + +procedure TSQLTransaction.savepointrollback(alevel: integer = -1); +begin + checkactive; + if alevel = -1 then begin + alevel:= fsavepointlevel; + end; + if alevel >= 0 then begin + database.executedirect('ROLLBACK TO '+'sp'+inttostrmse(alevel)+';', + self,nil,false,true); + fsavepointlevel:= alevel-1; + savepointevent(spek_rollback,alevel); + checkpendingaction; + end; +end; + +procedure TSQLTransaction.savepointrelease; +begin + checkactive; + if fsavepointlevel >= 0 then begin + database.executedirect('RELEASE SAVEPOINT '+'sp'+ + inttostrmse(fsavepointlevel)+';',self,nil,false,true); + dec(fsavepointlevel); + savepointevent(spek_release,fsavepointlevel+1); + checkpendingaction; + end; +end; + +procedure TSQLTransaction.dobeforestop; +begin + if checkcanevent(self,tmethod(fonbeforestop)) then begin + fonbeforestop(self); + end; +end; + +procedure TSQLTransaction.doafterstop; +begin + if checkcanevent(self,tmethod(fonafterstop)) then begin + fonafterstop(self); + end; +end; + +procedure TSQLTransaction.setpendingaction(const avalue: tcommitrollbackaction); +begin + fpendingaction:= avalue; + if not (avalue in [cacommitretaining,carollbackretaining]) then begin + fpendingrefresh:= false; + end; +end; + +procedure TSQLTransaction.CloseTrans; +begin + inherited; + freeandnil(ftrans); +end; + +procedure TSQLTransaction.savepointevent(const akind: savepointeventkindty; + const alevel: integer); +var + int1: integer; +begin + int1:= bigint; + while true do begin + if int1 > high(fdatasets) then begin + int1:= high(fdatasets); + end; + if int1 < 0 then begin + break; + end; + if fdatasets[int1].getactive then begin + fdatasets[int1].savepointevent(self,akind,alevel); + end; + dec(int1); + end; + int1:= bigint; + while true do begin + if int1 > high(fwritedatasets) then begin + int1:= high(fwritedatasets); + end; + if int1 < 0 then begin + break; + end; + if fwritedatasets[int1].getactive then begin + fwritedatasets[int1].savepointevent(self,akind,alevel); + end; + dec(int1); + end; +end; + +procedure TSQLTransaction.execerror(); +begin + if (tao_rollbackonerror in foptions) and active then begin + try + rollback(); + except //no secondary exceptions + end; + end; +end; + + +{ TSQLCursor } + +constructor TSQLCursor.create(const aowner: icursorclient; const aname: ansistring); +begin + fowner:= aowner; + fname:= aname; + frowsaffected:= -1; + frowsreturned:= -1; + inherited create; +end; + +function TSQLCursor.addblobdata(const adata: pointer; + const alength: integer): integer; +begin + if fowner = nil then begin + result:= fblobcount; + inc(fblobcount); + if result > high(fblobs) then begin + setlength(fblobs,2*result+256); + end; + setlength(fblobs[result],alength); + {$ifdef FPC} {$checkpointer off} {$endif} //adata can be foreign memory + move(adata^,fblobs[result][1],alength); + {$ifdef FPC} {$checkpointer default} {$endif} + end + else begin + result:= fowner.addblobcache(adata,alength); + end; +end; + +function TSQLCursor.addblobdata(const adata: string): integer; +begin + result:= addblobdata(pointer(adata),length(adata)); +end; + +procedure TSQLCursor.addblobcache(const aid: int64; const adata: string); +begin + fowner.addblobcache(aid,adata); +end; + +procedure TSQLCursor.blobfieldtoparam(const afield: tfield; + const aparam: tparam; const asstring: boolean = false); +var + blobid: integer; + str1: string; +begin + if afield.getdata(@blobid) then begin + if fowner = nil then begin + str1:= fblobs[blobid]; + end + else begin + str1:= fowner.getblobcache[blobid].data; + end; + if asstring then begin + aparam.asstring:= str1; + end + else begin + if afield.datatype = ftmemo then begin + aparam.asmemo:= str1; + end + else begin + aparam.asblob:= str1; + end; + end; + end + else begin + aparam.clear; + end; +end; + +function TSQLCursor.getcachedblob(const blobid: integer): tstream; +begin + if fowner = nil then begin + result:= tstringcopystream.create(fblobs[blobid]); + end + else begin + result:= tstringcopystream.create(fowner.getblobcache[blobid].data); + end; +end; + +procedure TSQLCursor.close; +begin + fblobs:= nil; + fblobcount:= 0; +end; + +function TSQLCursor.wantblobfetch: boolean; +begin + result:= (fowner <> nil) and fowner.blobsarefetched(); +end; + +function TSQLCursor.stringmemo: boolean; +begin + result:= (fowner <> nil) and fowner.stringmemo; +end; + +{ tcustomsqlstatement } + +constructor tcustomsqlstatement.create(aowner: tcomponent); +begin + fparams:= tmseparams.create(self); + fsql:= tsqlstringlist.create; + fsql.onchange:= {$ifdef FPC}@{$endif}dosqlchange; + inherited; +end; + +destructor tcustomsqlstatement.destroy; +begin + database:= nil; + transaction:= nil; + fparams.free; + fsql.free; + inherited; +end; + +procedure tcustomsqlstatement.setsql(const avalue: tsqlstringlist); +begin + fsql.assign(avalue); +end; + +procedure tcustomsqlstatement.setdatabase1(const avalue: tcustomsqlconnection); +begin + setdatabase(avalue); +end; + +procedure tcustomsqlstatement.setparams(const avalue: tmseparams); +begin + fparams.assign(avalue); +end; + +procedure tcustomsqlstatement.dobeforeexecute(const adatabase: tcustomsqlconnection; + const atransaction: tsqltransaction); +begin + if canevent(tmethod(fonbeforeexecute)) then begin + fonbeforeexecute(self,adatabase,atransaction); + end; +end; + +procedure tcustomsqlstatement.doafterexecute(const adatabase: tcustomsqlconnection; + const atransaction: tsqltransaction); +begin + if canevent(tmethod(fonafterexecute)) then begin + fonafterexecute(self,adatabase,atransaction); + end; +end; + +procedure tcustomsqlstatement.doerror(const adatabase: tcustomsqlconnection; + const atransaction: tsqltransaction; const e: exception; + var handled: boolean); +begin + if canevent(tmethod(fonerror)) then begin + fonerror(self,adatabase,atransaction,e,handled); + end; +end; + +procedure tcustomsqlstatement.dosqlchange(const sender: tobject); +begin + fparams.parsesql(fsql.text,true); +end; + +procedure tcustomsqlstatement.settransaction1(const avalue: tsqltransaction); +begin + settransaction(avalue); +end; + +function tcustomsqlstatement.getname: string; +begin + result:= name; +end; + +function tcustomsqlstatement.getactive: boolean; +begin + result:= false; +end; + +function tcustomsqlstatement.getdatabase: tcustomconnection; + //for isqlpropertyeditor +begin + result:= fdatabase; +end; + +procedure tcustomsqlstatement.setactive(avalue: boolean); +begin + //dummy +end; + +procedure tcustomsqlstatement.settransaction(const avalue: tmdbtransaction); +begin + dosettransaction(itransactionclient(self),avalue, + tmdbtransaction(ftransaction),false); +end; + +procedure tcustomsqlstatement.settransactionwrite(const avalue: tmdbtransaction); +begin + //dummy +end; + +procedure tcustomsqlstatement.refreshtransaction; +begin + //dummy +end; + +procedure tcustomsqlstatement.setdatabase(const avalue: tmdatabase); +var + intf1: idbcontroller; + bo1: boolean; +begin + dosetdatabase(idatabaseclient(self),avalue,tmdatabase(fdatabase)); + if (avalue <> nil) then begin + if (ftransaction = nil) then begin + transaction:= tsqlconnection(avalue).transaction; + end; + if mseclasses.getcorbainterface( + database,typeinfo(idbcontroller),intf1) then begin + bo1:= sso_utf8 in foptions; + intf1.updateutf8(bo1); + if bo1 then begin + foptions:= foptions + [sso_utf8]; + end + else begin + foptions:= foptions - [sso_utf8]; + end; + end; + end; +end; + +function tcustomsqlstatement.isutf8: boolean; +begin + result:= sso_utf8 in foptions; +end; +{ +function tcustomsqlstatement.isutf8(const adatabase): boolean; +begin + result:= sso_utf8 in foptions; +end; +} +procedure tcustomsqlstatement.setoptions(const avalue: sqlstatementoptionsty); +const + mask: sqlstatementoptionsty = [sso_autocommit,sso_autocommitret]; +begin + if foptions <> avalue then begin + foptions:= sqlstatementoptionsty(setsinglebit( + {$ifdef FPC}longword{$else}byte{$endif}(avalue), + {$ifdef FPC}longword{$else}byte{$endif}(foptions), + {$ifdef FPC}longword{$else}byte{$endif}(mask))); + end; +end; + +function tcustomsqlstatement.gettransaction: tmdbtransaction; +begin + result:= ftransaction; +end; + +function tcustomsqlstatement.getrecno: integer; +begin + result:= -1; +end; + +procedure tcustomsqlstatement.setrecno(value: integer); +begin + //dummy +end; + +procedure tcustomsqlstatement.disablecontrols; +begin + //dummy +end; + +procedure tcustomsqlstatement.enablecontrols; +begin + //dummy +end; + +function tcustomsqlstatement.moveby(distance: longint): longint; +begin + result:= 0; +end; + +procedure tcustomsqlstatement.checkbrowsemode; +begin + //dummy +end; + +procedure tcustomsqlstatement.savepointevent(const sender: tmdbtransaction; + const akind: savepointeventkindty; const alevel: integer); +begin + //dummy +end; + +{ tmsesqlscript } + +constructor tmsesqlscript.create(aowner: tcomponent); +begin + fterm:= ';'; + inherited; +end; + +procedure tmsesqlscript.execute(adatabase: tcustomsqlconnection = nil; + atransaction: tsqltransaction = nil); +var + str1: msestring; + ar1: msestringarty; + int1,int2: integer; + bo1: boolean; +begin + if adatabase = nil then begin + adatabase:= fdatabase; + end; + if atransaction = nil then begin + atransaction:= ftransaction; + end; + if adatabase = nil then begin + databaseerror(serrdatabasenassigned,self); + end; + if sso_savepoint in foptions then begin + int2:= atransaction.savepointbegin; + end; + try + dobeforeexecute(adatabase,atransaction); + updateparams(fparams,isutf8{(adatabase)}); + str1:= fsql.text; + ar1:= splitsql(str1,fterm,fcharescapement); + fstatementcount:= length(ar1); + if high(ar1) < 0 then begin + databaseerror(serrnostatement,self); + end; + for int1:= 0 to high(ar1) do begin + fstatementnr:= int1; + if canevent(tmethod(fonbeforestatement)) then begin + fonbeforestatement(self); + end; + try + adatabase.executedirect(ar1[int1],atransaction,fparams,isutf8, + sso_noprepare in foptions); + except + on e: exception do begin + bo1:= false; + doerror(adatabase,atransaction,e,bo1); + if not bo1 then begin + raise; + end; + end; + end; + if canevent(tmethod(fonafterstatement)) then begin + fonafterstatement(self); + end; + end; + if sso_autocommit in foptions then begin + atransaction.commit; + end + else begin + if sso_autocommitret in foptions then begin + atransaction.commitretaining; + end; + end; + doafterexecute(adatabase,atransaction); + if sso_savepoint in foptions then begin + atransaction.savepointrelease; + end; + except + if sso_savepoint in foptions then begin + atransaction.savepointrollback(int2); + end; + raise; + end; +end; + +procedure tmsesqlscript.execute; +begin + execute(nil,nil); +end; + +{ tcursorsqlstatement } + +constructor tcursorsqlstatement.create(aowner: tcomponent); +begin + inherited; +end; + +destructor tcursorsqlstatement.destroy; +begin + internalclose; +// setactive(false); + inherited; +end; + +procedure tcursorsqlstatement.internalclose; +begin + unprepare; + if fcursor <> nil then begin + fdatabase.deallocatecursorhandle(fcursor); + end; +end; + +procedure tcursorsqlstatement.dosqlchange(const sender: tobject); +begin + unprepare; + inherited; +end; + +procedure tcursorsqlstatement.prepare; +var + mstr1: msestring; +begin + if (fcursor = nil) or not fcursor.fprepared then begin + checkdatabase(name,fdatabase); + checktransaction(name,ftransaction); + mstr1:= trim(fsql.text); + if mstr1 = '' then begin + raise edatabaseerror.create(name+': Empty query.'); + end; + if not fdatabase.Connected then begin + fdatabase.Open; + end; + if not ftransaction.Active then begin + ftransaction.StartTransaction; + end; + if not assigned(fcursor) then begin + FCursor:= fdatabase.AllocateCursorHandle(nil,name); + end; + fcursor.ftrans:= ftransaction.handle; + fcursor.fstatementtype:= fstatementtype; + if not (sso_noprepare in foptions) then begin + fdatabase.PrepareStatement(Fcursor,ftransaction,mstr1,FParams); +// fcursor.fprepared:= true; + end; + end; +end; + +function tcursorsqlstatement.isprepared: boolean; +begin + result:= (fcursor <> nil) and fcursor.fprepared; +end; + +procedure tcursorsqlstatement.unprepare; +begin + if (fcursor <> nil) and fcursor.fprepared then begin + fdatabase.unpreparestatement(fcursor); + //fcursor.fprepared:= false; + end; +end; + +procedure tcursorsqlstatement.checkautocommit; +begin + if not (csdesigning in componentstate) then begin + if sso_autocommit in foptions then begin + ftransaction.commit; + end + else begin + if sso_autocommitret in foptions then begin + ftransaction.commitretaining; + end; + end; + end; +end; + +procedure tcursorsqlstatement.execute; +var + bo1: boolean; +begin + dobeforeexecute(fdatabase,ftransaction); + prepare; + updateparams(fparams,isutf8); + fcursor.ftrans:= tsqltransaction(ftransaction).handle; + try + if sso_noprepare in foptions then begin + tcustomsqlconnection(fdatabase).executeunprepared(fcursor, + tsqltransaction(ftransaction),fparams,fsql.text,isutf8); + end + else begin + tcustomsqlconnection(fdatabase).execute(fcursor,tsqltransaction(ftransaction), + fparams,isutf8); + end; +// fcursor.close; + checkautocommit; + doafterexecute(fdatabase,ftransaction); + except + on e: exception do begin + bo1:= false; + doerror(fdatabase,ftransaction,e,bo1); + if not bo1 then begin + raise; + end; + end; + end; +end; + +function tcursorsqlstatement.getactive: boolean; +begin + result:= fcursor <> nil; +end; + +procedure tcursorsqlstatement.setactive(avalue: boolean); +begin + if not avalue then begin + internalclose; + end; +end; + +procedure tcursorsqlstatement.execute(const aparams: array of variant); +var + int1: integer; +begin + for int1:= 0 to high(aparams) do begin + fparams[int1].value:= aparams[int1]; + end; + execute; +end; + +function tcursorsqlstatement.rowsaffected: integer; +begin + if fcursor = nil then begin + result:= -1; + end + else begin + result:= fcursor.frowsaffected; + end; +end; + +{ econnectionerror } + +constructor econnectionerror.create(const asender: tcustomsqlconnection; + const amessage: ansistring; const aerrormessage: msestring; + const aerror: integer); +begin + fsender:= sender; + ferror:= aerror; + ferrormessage:= aerrormessage; + if asender <> nil then begin + inherited create(asender.name+': '+amessage); + end + else begin + inherited create(amessage); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/db/mysqldyn.pas b/mseide-msegui/lib/common/db/mysqldyn.pas new file mode 100644 index 0000000..c7b6a93 --- /dev/null +++ b/mseide-msegui/lib/common/db/mysqldyn.pas @@ -0,0 +1,2297 @@ +{ + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +{ + This file is created by H2Pas, and thereafter heavily edited to make it + readable and dynamically loadable. + + The goal was not to be complete, but to make it work and maintainable. + + The mysql_com.h, mysql.h and some other files are merged together into this + one file. + + Automatically converted by H2Pas 1.0.0 from mysql_com.h / mysql.h + The following command line parameters were used: + -p + -D + -l + mysqlclient + mysql_com.h / mysql.h + +Modified 2008..2009 by Martin Schreiber + +} +unit mysqldyn; + +{$DEFINE LinkDynamically} + +{$DEFINE mysql51} + +{$ifdef mysql51} + {$define mysql50} +{$endif} +{$IFDEF mysql50} + {$DEFINE mysql41} +{$ENDIF mysql50} +{$ifdef FPC}{$MODE objfpc}{$MACRO on}{$endif} + +interface + +uses +{$IFDEF LinkDynamically} + sysutils, +{$ENDIF} + {$ifdef FPC}dynlibs,{$endif}msectypes,msetypes{msestrings}; + +const +{$ifdef mswindows} + mysqllib: array[0..0] of filenamety = ('libmysql.dll'); +{$else} + mysqllib: array[0..3] of filenamety = ('libmysqlclient.so.18', + 'libmysqlclient.so.16','libmysqlclient.so.15','libmysqlclient.so'); +{$endif} + +procedure initializemysql(const sonames: array of filenamety); + //[] = default +procedure releasemysql; + +{$IFDEF Unix} +// {$DEFINE extdecl:=cdecl} +(* + const + mysqllib = 'libmysqlclient.'+sharedsuffix; + + {$IF DEFINED(mysql50)} + mysqlvlib = 'libmysqlclient.'+sharedsuffix+'.15'; + {$ELSEIF DEFINED(mysql41)} + mysqlvlib = 'libmysqlclient.'+sharedsuffix+'.14'; + {$ELSE} + mysqlvlib = 'libmysqlclient.'+sharedsuffix+'.12'; + {$ENDIF} +*) +{$ENDIF} +{$IFDEF msWindows} +// {$DEFINE extdecl:=stdcall} + {$define wincall} +(* + const + mysqllib = 'libmysql.dll'; + mysqlvlib = 'libmysql.dll'; +*) +{$ENDIF} + +{$ifdef FPC} + {$PACKRECORDS C} +{$else} + {$ALIGN 4} + {$MINENUMSIZE 4} +{$endif} + + { Copyright (C) 2000-2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA } + + type +// my_bool = cchar; + my_bool = byte; + Pmy_bool = ^my_bool; + + PVIO = Pointer; + + Pgptr = ^gptr; + gptr = ^cchar; + + Pmy_socket = ^my_socket; + my_socket = cint; + + pppchar = ^ppchar; + PPByte = ^PByte; + + pculong = ^culong; + +{ ------------ Start of declaration in "my_list.h" --------------------- } + + pst_list = ^st_list; + st_list = record + prev,next: pst_list; + data: pointer; + end; + LIST = st_list; + +{ ------------ Start of declaration in "mysql_time.h" --------------------- } + +{ + Structure which is used to represent datetime values inside MySQL. + + We assume that values in this structure are normalized, i.e. year <= 9999, + month <= 12, day <= 31, hour <= 23, hour <= 59, hour <= 59. Many functions + in server such as my_system_gmt_sec() or make_time() family of functions + rely on this (actually now usage of make_*() family relies on a bit weaker + restriction). Also functions that produce MYSQL_TIME as result ensure this. + There is one exception to this rule though if this structure holds time + value (time_type == MYSQL_TIMESTAMP_TIME) days and hour member can hold + bigger values. +} +type + enum_mysql_timestamp_type = ( + MYSQL_TIMESTAMP_NONE= -2, MYSQL_TIMESTAMP_ERROR= -1, + MYSQL_TIMESTAMP_DATE= 0, MYSQL_TIMESTAMP_DATETIME= 1, MYSQL_TIMESTAMP_TIME= 2); + + MYSQL_TIME = record + year, month, day, hour, minute, second: cuint; + second_part: culong; + neg: my_bool; + time_type: enum_mysql_timestamp_type; + end; + pmysql_time = ^mysql_time; + +{ ------------ Start of declaration in "mysql_com.h" --------------------- } + + { + ** Common definition between mysql server & client + } + + { Field/table name length } + + const + NAME_LEN = 64; + HOSTNAME_LENGTH = 60; + USERNAME_LENGTH = 16; + SERVER_VERSION_LENGTH = 60; + SQLSTATE_LENGTH = 5; + LOCAL_HOST = 'localhost'; + LOCAL_HOST_NAMEDPIPE = '.'; + + const + MYSQL_NAMEDPIPE = 'MySQL'; + MYSQL_SERVICENAME = 'MySQL'; + + type + enum_server_command = (COM_SLEEP,COM_QUIT,COM_INIT_DB,COM_QUERY, + COM_FIELD_LIST,COM_CREATE_DB,COM_DROP_DB, + COM_REFRESH,COM_SHUTDOWN,COM_STATISTICS, + COM_PROCESS_INFO,COM_CONNECT,COM_PROCESS_KILL, + COM_DEBUG,COM_PING,COM_TIME,COM_DELAYED_INSERT, + COM_CHANGE_USER,COM_BINLOG_DUMP,COM_TABLE_DUMP, + COM_CONNECT_OUT,COM_REGISTER_SLAVE, +{$IFDEF mysql50} + COM_STMT_PREPARE, COM_STMT_EXECUTE, COM_STMT_SEND_LONG_DATA, COM_STMT_CLOSE, + COM_STMT_RESET, COM_SET_OPTION, COM_STMT_FETCH, +{$ELSE} + {$IFDEF mysql41} + COM_PREPARE,COM_EXECUTE,COM_LONG_DATA,COM_CLOSE_STMT, + COM_RESET_STMT,COM_SET_OPTION, + {$ENDIF} +{$ENDIF} + COM_END + ); + + { + Length of random string sent by server on handshake; this is also length of + obfuscated password, recieved from client + } + + const + SCRAMBLE_LENGTH = 20; + SCRAMBLE_LENGTH_323 = 8; + + { length of password stored in the db: new passwords are preceeded with '*' } + + SCRAMBLED_PASSWORD_CHAR_LENGTH = SCRAMBLE_LENGTH*2+1; + SCRAMBLED_PASSWORD_CHAR_LENGTH_323 = SCRAMBLE_LENGTH_323*2; + + + NOT_NULL_FLAG = 1; // Field can't be NULL + PRI_KEY_FLAG = 2; // Field is part of a primary key + UNIQUE_KEY_FLAG = 4; // Field is part of a unique key + MULTIPLE_KEY_FLAG = 8; // Field is part of a key + BLOB_FLAG = 16; // Field is a blob + UNSIGNED_FLAG = 32; // Field is unsigned + ZEROFILL_FLAG = 64; // Field is zerofill + BINARY_FLAG = 128; // Field is binary + + { The following are only sent to new clients } + + ENUM_FLAG = 256; // field is an enum + AUTO_INCREMENT_FLAG = 512; // field is a autoincrement field + TIMESTAMP_FLAG = 1024; // Field is a timestamp + SET_FLAG = 2048; // field is a set +{$IFDEF mysql50} + NO_DEFAULT_VALUE_FLAG=4096; // Field doesn't have default value +{$ENDIF} + NUM_FLAG = 32768; // Field is num (for clients) + PART_KEY_FLAG = 16384; // Intern; Part of some key + GROUP_FLAG = 32768; // Intern: Group field + UNIQUE_FLAG = 65536; // Intern: Used by sql_yacc + BINCMP_FLAG = 131072; // Intern: Used by sql_yacc + + REFRESH_GRANT = 1; // Refresh grant tables + REFRESH_LOG = 2; // Start on new log file + REFRESH_TABLES = 4; // close all tables + REFRESH_HOSTS = 8; // Flush host cache + REFRESH_STATUS = 16; // Flush status variables + REFRESH_THREADS = 32; // Flush thread cache + REFRESH_SLAVE = 64; // Reset master info and restart slave thread + REFRESH_MASTER = 128; // Remove all bin logs in the index and truncate the index + + { The following can't be set with mysql_refresh() } + REFRESH_READ_LOCK = 16384; // Lock tables for read + REFRESH_FAST = 32768; // Intern flag + REFRESH_QUERY_CACHE = 65536; // RESET (remove all queries) from query cache + REFRESH_QUERY_CACHE_FREE = $20000; // pack query cache + + REFRESH_DES_KEY_FILE = $40000; + REFRESH_USER_RESOURCES = $80000; + + CLIENT_LONG_PASSWORD = 1; // new more secure passwords + CLIENT_FOUND_ROWS = 2; // Found instead of affected rows + CLIENT_LONG_FLAG = 4; // Get all column flags + CLIENT_CONNECT_WITH_DB = 8; // One can specify db on connect + CLIENT_NO_SCHEMA = 16; // Don't allow database.table.column + CLIENT_COMPRESS = 32; // Can use compression protocol + CLIENT_ODBC = 64; // Odbc client + CLIENT_LOCAL_FILES = 128; // Can use LOAD DATA LOCAL + CLIENT_IGNORE_SPACE = 256; // Ignore spaces before '(' + CLIENT_PROTOCOL_41 = 512; // New 4.1 protocol + CLIENT_INTERACTIVE = 1024; // This is an interactive client + CLIENT_SSL = 2048; // Switch to SSL after handshake + CLIENT_IGNORE_SIGPIPE = 4096; // IGNORE sigpipes + CLIENT_TRANSACTIONS = 8192; // Client knows about transactions + CLIENT_RESERVED = 16384; // Old flag for 4.1 protocol + CLIENT_SECURE_CONNECTION = 32768; // New 4.1 authentication + CLIENT_MULTI_STATEMENTS = 65536; // Enable/disable multi-stmt support + CLIENT_MULTI_RESULTS = 131072; // Enable/disable multi-results +// CLIENT_REMEMBER_OPTIONS : longword = 1 shl 31; + CLIENT_REMEMBER_OPTIONS = 1 shl 31; + + + SERVER_STATUS_IN_TRANS = 1; // Transaction has started + SERVER_STATUS_AUTOCOMMIT = 2; // Server in auto_commit mode + SERVER_STATUS_MORE_RESULTS = 4; // More results on server + SERVER_MORE_RESULTS_EXISTS = 8; // Multi query - next query exists + SERVER_QUERY_NO_GOOD_INDEX_USED = 16; + SERVER_QUERY_NO_INDEX_USED = 32; +{$IFDEF mysql50} + { The server was able to fulfill the clients request and opened a + read-only non-scrollable cursor for a query. This flag comes + in reply to COM_STMT_EXECUTE and COM_STMT_FETCH commands. } + SERVER_STATUS_CURSOR_EXISTS = 64; + { This flag is sent when a read-only cursor is exhausted, in reply to + COM_STMT_FETCH command. } + SERVER_STATUS_LAST_ROW_SENT = 128; +{$ENDIF} + SERVER_STATUS_DB_DROPPED = 256; // A database was dropped +{$IFDEF mysql50} + SERVER_STATUS_NO_BACKSLASH_ESCAPES = 512; +{$ENDIF} + +{$IFDEF mysql41} + MYSQL_ERRMSG_SIZE = 512; +{$ELSE} + MYSQL_ERRMSG_SIZE = 200; +{$ENDIF} + NET_READ_TIMEOUT = 30; // Timeout on read + NET_WRITE_TIMEOUT = 60; // Timeout on write + NET_WAIT_TIMEOUT = 8*60*60; // Wait for new query +{$IFDEF mysql50} + ONLY_KILL_QUERY = 1; +{$ENDIF} + + + const + MAX_TINYINT_WIDTH = 3; // Max width for a TINY w.o. sign + MAX_SMALLINT_WIDTH = 5; // Max width for a SHORT w.o. sign + MAX_MEDIUMINT_WIDTH = 8; // Max width for a INT24 w.o. sign + MAX_INT_WIDTH = 10; // Max width for a LONG w.o. sign + MAX_BIGINT_WIDTH = 20; // Max width for a LONGLONG + MAX_CHAR_WIDTH = 255; // Max length for a CHAR colum + MAX_BLOB_WIDTH = 8192; // Default width for blob + + type + Pst_net = ^st_net; + st_net = record +{ $if !defined(CHECK_EMBEDDED_DIFFERENCES) || !defined(EMBEDDED_LIBRARY)} + vio : PVio; + buff : pcuchar; + buff_end : pcuchar; + write_pos : pcuchar; + read_pos : pcuchar; + fd : my_socket; // For Perl DBI/dbd + max_packet : culong; + max_packet_size : culong; +{$IFNDEF mysql41} + last_errno : cuint; +{$ENDIF} + pkt_nr : cuint; + compress_pkt_nr : cuint; + write_timeout : cuint; + read_timeout : cuint; + retry_count : cuint; + fcntl : cint; +{$IFNDEF mysql41} + last_error : array[0..(MYSQL_ERRMSG_SIZE)-1] of char; + error : cuchar; + return_errno : my_bool; +{$ENDIF} + compress : my_bool; + { The following variable is set if we are doing several queries in one + command ( as in LOAD TABLE ... FROM MASTER ), + and do not want to confuse the client with OK at the wrong time } + remain_in_buf : culong; + length : culong; + buf_length : culong; + where_b : culong; + return_status : pcint; + reading_or_writing : cuchar; + save_char : cchar; + no_send_ok : my_bool; // For SPs and other things that do multiple stmts +{$IFDEF mysql50} + no_send_eof : my_bool; // For SPs' first version read-only cursors + no_send_error : my_bool; // Set if OK packet is already sent, and + // we do not need to send error messages +{$ENDIF} + { Pointer to query object in query cache, do not equal NULL (0) for + queries in cache that have not stored its results yet } +{ $endif} +{$IFDEF mysql41} + last_error : array[0..(MYSQL_ERRMSG_SIZE)-1] of char; + sqlstate : array[0..(SQLSTATE_LENGTH+1)-1] of char; + last_errno : cuint; + error : cuchar; +{$ENDIF} + query_cache_query : gptr; +{$IFDEF mysql41} + report_error : my_bool; // We should report error (we have unreported error) + return_errno : my_bool; +{$ENDIF} + end; + NET = st_net; + PNET = ^NET; + + const + packet_error : culong = culong(not(0)); + + {$ifdef FPC} + type + enum_field_types = (MYSQL_TYPE_DECIMAL,MYSQL_TYPE_TINY, + MYSQL_TYPE_SHORT,MYSQL_TYPE_LONG,MYSQL_TYPE_FLOAT, + MYSQL_TYPE_DOUBLE,MYSQL_TYPE_NULL, + MYSQL_TYPE_TIMESTAMP,MYSQL_TYPE_LONGLONG, + MYSQL_TYPE_INT24,MYSQL_TYPE_DATE,MYSQL_TYPE_TIME, + MYSQL_TYPE_DATETIME,MYSQL_TYPE_YEAR, + MYSQL_TYPE_NEWDATE, +{$IFDEF mysql50} + MYSQL_TYPE_VARCHAR, MYSQL_TYPE_BIT, MYSQL_TYPE_NEWDECIMAL=246, +{$ENDIF} + MYSQL_TYPE_ENUM := 247, + MYSQL_TYPE_SET := 248,MYSQL_TYPE_TINY_BLOB := 249, + MYSQL_TYPE_MEDIUM_BLOB := 250,MYSQL_TYPE_LONG_BLOB := 251, + MYSQL_TYPE_BLOB := 252,MYSQL_TYPE_VAR_STRING := 253, + MYSQL_TYPE_STRING := 254,MYSQL_TYPE_GEOMETRY := 255 + ); + { For backward compatibility } + {$else} + const + MYSQL_TYPE_DECIMAL = 0; + MYSQL_TYPE_TINY = 1; + MYSQL_TYPE_SHORT = 2; + MYSQL_TYPE_LONG = 3; + MYSQL_TYPE_FLOAT = 4; + MYSQL_TYPE_DOUBLE = 5; + MYSQL_TYPE_NULL = 6; + MYSQL_TYPE_TIMESTAMP = 7; + MYSQL_TYPE_LONGLONG = 8; + MYSQL_TYPE_INT24 = 9; + MYSQL_TYPE_DATE = 10; + MYSQL_TYPE_TIME = 11; + MYSQL_TYPE_DATETIME = 12; + MYSQL_TYPE_YEAR = 13; + MYSQL_TYPE_NEWDATE = 14; +{$IFDEF mysql50} + MYSQL_TYPE_VARCHAR = 15; + MYSQL_TYPE_BIT = 16; + MYSQL_TYPE_NEWDECIMAL = 246; +{$ENDIF} + MYSQL_TYPE_ENUM = 247; + MYSQL_TYPE_SET = 248; + MYSQL_TYPE_TINY_BLOB = 249; + MYSQL_TYPE_MEDIUM_BLOB = 250; + MYSQL_TYPE_LONG_BLOB = 251; + MYSQL_TYPE_BLOB = 252; + MYSQL_TYPE_VAR_STRING = 253; + MYSQL_TYPE_STRING = 254; + MYSQL_TYPE_GEOMETRY = 255; +type + enum_field_types = cint; //correct? + {$endif} + penum_field_types = ^enum_field_types; + + const + CLIENT_MULTI_QUERIES = CLIENT_MULTI_STATEMENTS; + FIELD_TYPE_DECIMAL = MYSQL_TYPE_DECIMAL; +{$IFDEF mysql50} + FIELD_TYPE_NEWDECIMAL = MYSQL_TYPE_NEWDECIMAL; +{$ENDIF} + FIELD_TYPE_TINY = MYSQL_TYPE_TINY; + FIELD_TYPE_SHORT = MYSQL_TYPE_SHORT; + FIELD_TYPE_LONG = MYSQL_TYPE_LONG; + FIELD_TYPE_FLOAT = MYSQL_TYPE_FLOAT; + FIELD_TYPE_DOUBLE = MYSQL_TYPE_DOUBLE; + FIELD_TYPE_NULL = MYSQL_TYPE_NULL; + FIELD_TYPE_TIMESTAMP = MYSQL_TYPE_TIMESTAMP; + FIELD_TYPE_LONGLONG = MYSQL_TYPE_LONGLONG; + FIELD_TYPE_INT24 = MYSQL_TYPE_INT24; + FIELD_TYPE_DATE = MYSQL_TYPE_DATE; + FIELD_TYPE_TIME = MYSQL_TYPE_TIME; + FIELD_TYPE_DATETIME = MYSQL_TYPE_DATETIME; + FIELD_TYPE_YEAR = MYSQL_TYPE_YEAR; + FIELD_TYPE_NEWDATE = MYSQL_TYPE_NEWDATE; + FIELD_TYPE_ENUM = MYSQL_TYPE_ENUM; + FIELD_TYPE_SET = MYSQL_TYPE_SET; + FIELD_TYPE_TINY_BLOB = MYSQL_TYPE_TINY_BLOB; + FIELD_TYPE_MEDIUM_BLOB = MYSQL_TYPE_MEDIUM_BLOB; + FIELD_TYPE_LONG_BLOB = MYSQL_TYPE_LONG_BLOB; + FIELD_TYPE_BLOB = MYSQL_TYPE_BLOB; + FIELD_TYPE_VAR_STRING = MYSQL_TYPE_VAR_STRING; + FIELD_TYPE_STRING = MYSQL_TYPE_STRING; + FIELD_TYPE_CHAR = MYSQL_TYPE_TINY; + FIELD_TYPE_INTERVAL = MYSQL_TYPE_ENUM; + FIELD_TYPE_GEOMETRY = MYSQL_TYPE_GEOMETRY; +{$IFDEF mysql50} + FIELD_TYPE_BIT = MYSQL_TYPE_BIT; +{$ENDIF} + { Shutdown/kill enums and constants } + { Bits for THD::killable. } + MYSQL_SHUTDOWN_KILLABLE_CONNECT : cuchar = 1 shl 0; + MYSQL_SHUTDOWN_KILLABLE_TRANS : cuchar = 1 shl 1; + MYSQL_SHUTDOWN_KILLABLE_LOCK_TABLE : cuchar = 1 shl 2; + MYSQL_SHUTDOWN_KILLABLE_UPDATE : cuchar = 1 shl 3; + + + { We want levels to be in growing order of hardness (because we use number + comparisons). Note that DEFAULT does not respect the growing property, but + it's ok. } + {$ifdef FPC} + type + mysql_enum_shutdown_level = (SHUTDOWN_DEFAULT := 0, + SHUTDOWN_WAIT_CONNECTIONS := 1, //MYSQL_SHUTDOWN_KILLABLE_CONNECT, // wait for existing connections to finish + SHUTDOWN_WAIT_TRANSACTIONS := 2, //MYSQL_SHUTDOWN_KILLABLE_TRANS, // wait for existing trans to finish + SHUTDOWN_WAIT_UPDATES := 8, //MYSQL_SHUTDOWN_KILLABLE_UPDATE, // wait for existing updates to finish (=> no partial MyISAM update) + SHUTDOWN_WAIT_ALL_BUFFERS := 16, //MYSQL_SHUTDOWN_KILLABLE_UPDATE shl 1,// flush InnoDB buffers and other storage engines' buffers + SHUTDOWN_WAIT_CRITICAL_BUFFERS := 17, //(MYSQL_SHUTDOWN_KILLABLE_UPDATE shl 1)+1, // don't flush InnoDB buffers, flush other storage engines' buffers + { Now the 2 levels of the KILL command } +{ $if MYSQL_VERSION_ID >= 50000} + KILL_QUERY := 254, +{ $endif} + KILL_CONNECTION := 255 + ); + {$else} +const + SHUTDOWN_DEFAULT = 0; + SHUTDOWN_WAIT_CONNECTIONS = 1; //MYSQL_SHUTDOWN_KILLABLE_CONNECT, // wait for existing connections to finish + SHUTDOWN_WAIT_TRANSACTIONS = 2; //MYSQL_SHUTDOWN_KILLABLE_TRANS, // wait for existing trans to finish + SHUTDOWN_WAIT_UPDATES = 8; //MYSQL_SHUTDOWN_KILLABLE_UPDATE, // wait for existing updates to finish (=> no partial MyISAM update) + SHUTDOWN_WAIT_ALL_BUFFERS = 16; //MYSQL_SHUTDOWN_KILLABLE_UPDATE shl 1,// flush InnoDB buffers and other storage engines' buffers + SHUTDOWN_WAIT_CRITICAL_BUFFERS = 17; //(MYSQL_SHUTDOWN_KILLABLE_UPDATE shl 1)+1, // don't flush InnoDB buffers, flush other storage engines' buffers + { Now the 2 levels of the KILL command } +{ $if MYSQL_VERSION_ID >= 50000} + KILL_QUERY = 254; +{ $endif} + KILL_CONNECTION = 255; +type + mysql_enum_shutdown_level = cint; //correct? + {$endif} + +{$IFDEF mysql50} + {$ifdef FPC} + enum_cursor_type = (CURSOR_TYPE_NO_CURSOR := 0,CURSOR_TYPE_READ_ONLY := 1, + CURSOR_TYPE_FOR_UPDATE := 2,CURSOR_TYPE_SCROLLABLE := 4 + ); + {$else} +const + CURSOR_TYPE_NO_CURSOR = 0; + CURSOR_TYPE_READ_ONLY = 1; + CURSOR_TYPE_FOR_UPDATE = 2; + CURSOR_TYPE_SCROLLABLE = 4; +type + enum_cursor_type = cint; //correct? + {$endif} +{$ENDIF} + +{$ifdef FPC} + enum_mysql_stmt_state = (MYSQL_STMT_INIT_DONE := 1,MYSQL_STMT_PREPARE_DONE, + MYSQL_STMT_EXECUTE_DONE,MYSQL_STMT_FETCH_DONE + ); +{$else} +const + MYSQL_STMT_INIT_DONE = 1; + MYSQL_STMT_PREPARE_DONE = 2; + MYSQL_STMT_EXECUTE_DONE = 3; + MYSQL_STMT_FETCH_DONE = 4; +type + enum_mysql_stmt_state = cint; //correct? +{$endif} + + { options for mysql_set_option } + enum_mysql_set_option = (MYSQL_OPTION_MULTI_STATEMENTS_ON, + MYSQL_OPTION_MULTI_STATEMENTS_OFF + ); + + function net_new_transaction(net : st_net) : st_net; + +{$IFNDEF LinkDynamically} + function my_net_init(net:PNET; vio:PVio):my_bool;cdecl;external mysqllib name 'my_net_init'; + procedure my_net_local_init(net:PNET);cdecl;external mysqllib name 'my_net_local_init'; + procedure net_end(net:PNET);cdecl;external mysqllib name 'net_end'; + procedure net_clear(net:PNET);cdecl;external mysqllib name 'net_clear'; + function net_realloc(net:PNET; length:culong):my_bool;cdecl;external mysqllib name 'net_realloc'; + function net_flush(net:PNET):my_bool;cdecl;external mysqllib name 'net_flush'; + function my_net_write(net:PNET; packet:Pchar; len:culong):my_bool;cdecl;external mysqllib name 'my_net_write'; + function net_write_command(net:PNET; command:cuchar; header:Pchar; head_len:culong; packet:Pchar; + len:culong):my_bool;cdecl;external mysqllib name 'net_write_command'; + function net_real_write(net:PNET; packet:Pchar; len:culong):cint;cdecl;external mysqllib name 'net_real_write'; + function my_net_read(net:PNET):culong;cdecl;external mysqllib name 'my_net_read'; +{$ENDIF} + { The following function is not meant for normal usage + Currently it's used internally by manager.c } + + type + Psockaddr = ^sockaddr; + sockaddr = record + // undefined structure + end; +{$IFNDEF LinkDynamically} + function my_connect(s:my_socket; name:Psockaddr; namelen:cuint; timeout:cuint):cint;cdecl;external mysqllib name 'my_connect'; +{$ENDIF} + + type + Prand_struct = ^rand_struct; + rand_struct = record + seed1 : culong; + seed2 : culong; + max_value : culong; + max_value_dbl : cdouble; + end; + + { The following is for user defined functions } +{$IFDEF mysql50} + Item_result = (STRING_RESULT,REAL_RESULT,INT_RESULT, + ROW_RESULT); +{$ELSE} + Item_result = (STRING_RESULT := 0,REAL_RESULT,INT_RESULT, + ROW_RESULT,DECIMAL_RESULT); +{$ENDIF} + PItem_result = ^Item_result; + + Pst_udf_args = ^st_udf_args; + st_udf_args = record + arg_count : cuint; // Number of arguments + arg_type : PItem_result; // Pointer to item_results + args : PPChar; // Pointer to item_results + lengths : pculong; // Length of string arguments + maybe_null : Pchar; // Length of string arguments +{$IFDEF mysql50} + attributes : PPChar; // Pointer to attribute name + attribute_lengths : pculong; // Length of attribute arguments +{$ENDIF} + end; + UDF_ARGS = st_udf_args; + PUDF_ARGS = ^UDF_ARGS; + + { This holds information about the result } + + Pst_udf_init = ^st_udf_init; + st_udf_init = record + maybe_null : my_bool; // 1 if function can return NULL + decimals : cuint; // for real functions + max_length : culong; // For string functions + ptr : Pchar; // free pointer for function data + const_item : my_bool; // free pointer for function data + end; + UDF_INIT = st_udf_init; + PUDF_INIT = ^UDF_INIT; + + { Constants when using compression } + const + NET_HEADER_SIZE = 4; // standard header size + COMP_HEADER_SIZE = 3; // compression header extra size + + { Prototypes to password functions } + + { These functions are used for authentication by client and server and + implemented in sql/password.c } +{$IFNDEF LinkDynamically} + procedure randominit(_para1:Prand_struct; seed1:culong; seed2:culong);cdecl;external mysqllib name 'randominit'; + function my_rnd(_para1:Prand_struct):cdouble;cdecl;external mysqllib name 'my_rnd'; + procedure create_random_string(fto:Pchar; length:cuint; rand_st:Prand_struct);cdecl;external mysqllib name 'create_random_string'; + procedure hash_password(fto:culong; password:Pchar; password_len:cuint);cdecl;external mysqllib name 'hash_password'; + procedure make_scrambled_password_323(fto:Pchar; password:Pchar);cdecl;external mysqllib name 'make_scrambled_password_323'; + procedure scramble_323(fto:Pchar; message:Pchar; password:Pchar);cdecl;external mysqllib name 'scramble_323'; + function check_scramble_323(_para1:Pchar; message:Pchar; salt:culong):my_bool;cdecl;external mysqllib name 'check_scramble_323'; + procedure get_salt_from_password_323(res:pculong; password:Pchar);cdecl;external mysqllib name 'get_salt_from_password_323'; + procedure make_password_from_salt_323(fto:Pchar; salt:pculong);cdecl;external mysqllib name 'make_password_from_salt_323'; +{$IFDEF mysql50} + function octet2hex(fto:Pchar; str:Pchar; len:cuint):pchar;cdecl;external mysqllib name 'octet2hex'; +{$ENDIF} + procedure make_scrambled_password(fto:Pchar; password:Pchar);cdecl;external mysqllib name 'make_scrambled_password'; + procedure scramble(fto:Pchar; message:Pchar; password:Pchar);cdecl;external mysqllib name 'scramble'; + function check_scramble(reply:Pchar; message:Pchar; hash_stage2:Pbyte):my_bool;cdecl;external mysqllib name 'check_scramble'; + procedure get_salt_from_password(res:Pbyte; password:Pchar);cdecl;external mysqllib name 'get_salt_from_password'; + procedure make_password_from_salt(fto:Pchar; hash_stage2:Pbyte);cdecl;external mysqllib name 'make_password_from_salt'; + { end of password.c } + + function get_tty_password(opt_message:Pchar):Pchar;cdecl;external mysqllib name 'get_tty_password'; + function mysql_errno_to_sqlstate(mysql_errno:cuint):Pchar;cdecl;external mysqllib name 'mysql_errno_to_sqlstate'; + + { Some other useful functions } +{$IFDEF mysql50} + function modify_defaults_file(file_location:Pchar; option:Pchar; option_value:Pchar; section_name:Pchar; remove_option:cint):cint;cdecl;external mysqllib name 'load_defaults'; +{$ENDIF} + + function load_defaults(conf_file:Pchar; groups:PPchar; argc:pcint; argv:PPPchar):cint;cdecl;external mysqllib name 'load_defaults'; + function my_init:my_bool;cdecl;external mysqllib name 'my_init'; + function my_thread_init:my_bool;cdecl;external mysqllib name 'my_thread_init'; + procedure my_thread_end;cdecl;external mysqllib name 'my_thread_end'; +{$ELSE} +{$ENDIF} + +{$ifdef _global_h} +{$IFNDEF LinkDynamically} + function net_field_length(packet:PPuchar):culong;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'net_field_length_ll'; + function net_field_length_ll(packet:PPuchar):my_ulonglong;cdecl;external mysqllib name 'net_field_length_ll'; + function net_store_length(pkg:Pchar; length:ulonglong):Pchar;cdecl;external mysqllib name 'net_store_length'; +{$ENDIF} +{$endif} + + const + NULL_LENGTH : culong = culong(not(0)); // For net_store_length + + const + MYSQL_STMT_HEADER = 4; + MYSQL_LONG_DATA_HEADER = 6; + +{ ------------ Stop of declaration in "mysql_com.h" ----------------------- } + +{ $include "mysql_time.h"} +{ $include "mysql_version.h"} +{ $include "typelib.h"} +{ $include "my_list.h" /* for LISTs used in 'MYSQL' and 'MYSQL_STMT' */} + +{$IFNDEF LinkDynamically} + var + mysql_port : cuint;cvar;external; + mysql_unix_port : Pchar;cvar;external; +{$ENDIF} + + const + CLIENT_NET_READ_TIMEOUT = 365*24*3600; // Timeout on read + CLIENT_NET_WRITE_TIMEOUT = 365*24*3600; // Timeout on write + +{$ifdef NETWARE} +(** unsupported pragma#pragma pack(push, 8) /* 8 byte alignment */*) +{$endif} + + type + Pst_mysql_field = ^st_mysql_field; + st_mysql_field = record + name : Pchar; // Name of column +{$IFDEF mysql41} + org_name : Pchar; // Original column name, if an alias +{$ENDIF} + table : Pchar; // Table of column if column was a field + org_table : Pchar; // Org table name, if table was an alias + db : Pchar; // Database for table +{$IFDEF mysql41} + catalog : Pchar; // Catalog for table +{$ENDIF} + def : Pchar; // Default value (set by mysql_list_fields) + length : culong; // Width of column (create length) + max_length : culong; // Max width for selected set +{$IFDEF mysql41} + name_length : cuint; + org_name_length : cuint; + table_length : cuint; + org_table_length : cuint; + db_length : cuint; + catalog_length : cuint; + def_length : cuint; +{$ENDIF} + flags : cuint; // Div flags + decimals : cuint; // Number of decimals in field +{$IFDEF mysql41} + charsetnr : cuint; // Character set +{$ENDIF} + ftype : enum_field_types; // Type of field. See mysql_com.h for types +{$ifdef mysql51} + extension: pointer; +{$endif} + end; + MYSQL_FIELD = st_mysql_field; + PMYSQL_FIELD = ^MYSQL_FIELD; + + PMYSQL_ROW = ^MYSQL_ROW; // return data as array of strings + MYSQL_ROW = ppchar; + + PMYSQL_FIELD_OFFSET = ^MYSQL_FIELD_OFFSET; // offset to current field + MYSQL_FIELD_OFFSET = cuint; + + function IS_PRI_KEY(n : longint) : boolean; + function IS_NOT_NULL(n : longint) : boolean; + function IS_BLOB(n : longint) : boolean; + function IS_NUM(t : enum_field_types) : boolean; + function INTERNAL_NUM_FIELD(f : Pst_mysql_field) : boolean; + function IS_NUM_FIELD(f : Pst_mysql_field) : boolean; + + type +{$if defined(NO_CLIENT_LONG_LONG)} + my_ulonglong = culong; +{$elseif defined(mswindows)} + my_ulonglong = cint64; +{$else} + my_ulonglong = culonglong; +{$ifend} + Pmy_ulonglong = ^my_ulonglong; + + const + MYSQL_COUNT_ERROR = not (my_ulonglong(0)); + + type + Pst_mysql_rows = ^st_mysql_rows; + st_mysql_rows = record + next : Pst_mysql_rows; // list of rows + data : MYSQL_ROW; +{$IFDEF mysql41} + length : culong; +{$ENDIF} + end; + MYSQL_ROWS = st_mysql_rows; + PMYSQL_ROWS = ^MYSQL_ROWS; + + PMYSQL_ROW_OFFSET = ^MYSQL_ROW_OFFSET; // offset to current row + MYSQL_ROW_OFFSET = MYSQL_ROWS; + +{ ------------ Start of declaration in "my_alloc.h" -------------------- } +{ $include "my_alloc.h"} + + const + ALLOC_MAX_BLOCK_TO_DROP = 4096; + ALLOC_MAX_BLOCK_USAGE_BEFORE_DROP = 10; + + { struct for once_alloc (block) } + type + Pst_used_mem = ^st_used_mem; + st_used_mem = record + next : Pst_used_mem; // Next block in use + left : cuint; // memory left in block + size : cuint; // size of block + end; + USED_MEM = st_used_mem; + PUSED_MEM = ^USED_MEM; + + + Pst_mem_root = ^st_mem_root; + st_mem_root = record + free : PUSED_MEM; // blocks with free memory in it + used : PUSED_MEM; // blocks almost without free memory + pre_alloc : PUSED_MEM; // preallocated block + min_malloc : cuint; // if block have less memory it will be put in 'used' list + block_size : cuint; // initial block size + block_num : cuint; // allocated blocks counter + { first free block in queue test counter (if it exceed + MAX_BLOCK_USAGE_BEFORE_DROP block will be dropped in 'used' list) } + first_block_usage : cuint; + error_handler : procedure ;cdecl; + end; + MEM_ROOT = st_mem_root; + PMEM_ROOT = ^MEM_ROOT; + +{ ------------ Stop of declaration in "my_alloc.h" ---------------------- } + + type + Pst_mysql_data = ^st_mysql_data; +{$ifdef mysql51} + st_mysql_data = record + data : PMYSQL_ROWS; + prev_ptr : ^PMYSQL_ROWS; + alloc : MEM_ROOT; + rows : my_ulonglong; + fields : cuint; + extension: pointer; + end; +{$else} + st_mysql_data = record + rows : my_ulonglong; + fields : cuint; + data : PMYSQL_ROWS; + alloc : MEM_ROOT; +{ $if !defined(CHECK_EMBEDDED_DIFFERENCES) || defined(EMBEDDED_LIBRARY)} +{$IFDEF mysql41} + prev_ptr : ^PMYSQL_ROWS; +{$ENDIF} + end; +{$endif} + MYSQL_DATA = st_mysql_data; + PMYSQL_DATA = ^MYSQL_DATA; + mysql_option = (MYSQL_OPT_CONNECT_TIMEOUT,MYSQL_OPT_COMPRESS, + MYSQL_OPT_NAMED_PIPE,MYSQL_INIT_COMMAND, + MYSQL_READ_DEFAULT_FILE,MYSQL_READ_DEFAULT_GROUP, + MYSQL_SET_CHARSET_DIR,MYSQL_SET_CHARSET_NAME, + MYSQL_OPT_LOCAL_INFILE,MYSQL_OPT_PROTOCOL, + MYSQL_SHARED_MEMORY_BASE_NAME,MYSQL_OPT_READ_TIMEOUT, + MYSQL_OPT_WRITE_TIMEOUT,MYSQL_OPT_USE_RESULT, + MYSQL_OPT_USE_REMOTE_CONNECTION,MYSQL_OPT_USE_EMBEDDED_CONNECTION, + MYSQL_OPT_GUESS_CONNECTION,MYSQL_SET_CLIENT_IP, + MYSQL_SECURE_AUTH +{$IFDEF MYSQL50} + ,MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT +{$ENDIF} + ); + + const + MAX_MYSQL_MANAGER_ERR = 256; + MAX_MYSQL_MANAGER_MSG = 256; + MANAGER_OK = 200; + MANAGER_INFO = 250; + MANAGER_ACCESS = 401; + MANAGER_CLIENT_ERR = 450; + MANAGER_INTERNAL_ERR = 500; + + type + st_dynamic_array = record + buffer : ^char; + elements : cuint; + max_element : cuint; + alloc_increment : cuint; + size_of_element : cuint; + end; + DYNAMIC_ARRAY = st_dynamic_array; + Pst_dynamic_array = ^st_dynamic_array; + + Pst_mysql_options = ^st_mysql_options; + st_mysql_options = record + connect_timeout : cuint; +{$IFNDEF mysql41} + client_flag : cuint; + port : cuint; +{$ELSE} + read_timeout : cuint; + write_timeout : cuint; +{$ENDIF} +{$IFDEF mysql41} + port : cuint; + protocol : cuint; + client_flag : culong; +{$ENDIF} + host : Pchar; +{$IFNDEF mysql41} + init_command: Pchar; +{$ENDIF} + user : Pchar; + password : Pchar; + unix_socket : Pchar; + db : Pchar; +{$IFDEF mysql41} + init_commands : Pst_dynamic_array; +{$ENDIF} + my_cnf_file : Pchar; + my_cnf_group : Pchar; + charset_dir : Pchar; + charset_name : Pchar; + ssl_key : Pchar; // PEM key file + ssl_cert : Pchar; // PEM cert file + ssl_ca : Pchar; // PEM CA file + ssl_capath : Pchar; // PEM directory of CA-s? + ssl_cipher : Pchar; // cipher to use +{$IFDEF mysql41} + shared_memory_base_name : Pchar; +{$ENDIF} + max_allowed_packet : culong; + use_ssl : my_bool; // if to use SSL or not + compress : my_bool; + named_pipe : my_bool; + { On connect, find out the replication role of the server, and + establish connections to all the peers } + rpl_probe : my_bool; + { Each call to mysql_real_query() will parse it to tell if it is a read + or a write, and direct it to the slave or the master } + rpl_parse : my_bool; + { If set, never read from a master, only from slave, when doing + a read that is replication-aware } + no_master_reads : my_bool; +{ $if !defined(CHECK_EMBEDDED_DIFFERENCES) || defined(EMBEDDED_LIBRARY)} +{$IFDEF mysql41} + separate_thread : my_bool; +{ $endif} + methods_to_use : mysql_option; + client_ip : Pchar; + secure_auth : my_bool; // Refuse client connecting to server if it uses old (pre-4.1.1) protocol +{$IFDEF mysql50} + report_data_truncation : my_bool;// 0 - never report, 1 - always report (default) +{$ENDIF} + { function pointers for local infile support } + local_infile_init : function (_para1:Ppointer; _para2:Pchar; _para3:pointer):cint;cdecl; + local_infile_read : function (_para1:pointer; _para2:Pchar; _para3:cuint):cint; + local_infile_end : procedure (_para1:pointer); + local_infile_error : function (_para1:pointer; _para2:Pchar; _para3:cuint):cint; + local_infile_userdata : pointer; +{$ENDIF} +{$ifdef mysql51} + extension: pointer; +{$endif} + end; + + mysql_status = (MYSQL_STATUS_READY,MYSQL_STATUS_GET_RESULT, + MYSQL_STATUS_USE_RESULT); + + mysql_protocol_type = (MYSQL_PROTOCOL_DEFAULT,MYSQL_PROTOCOL_TCP, + MYSQL_PROTOCOL_SOCKET,MYSQL_PROTOCOL_PIPE, + MYSQL_PROTOCOL_MEMORY); + + { There are three types of queries - the ones that have to go to + the master, the ones that go to a slave, and the adminstrative + type which must happen on the pivot connectioin } + mysql_rpl_type = (MYSQL_RPL_MASTER,MYSQL_RPL_SLAVE,MYSQL_RPL_ADMIN + ); + + charset_info_st = record + number : cuint; + primary_number : cuint; + binary_number : cuint; + state : cuint; + csname : ^char; + name : ^char; + comment : ^char; + tailoring : ^char; + ftype : ^cuchar; + to_lower : ^cuchar; + to_upper : ^cuchar; + sort_order : ^cuchar; + contractions : ^cuint16; + sort_order_big : ^pword; + tab_to_uni : ^cuint16; + tab_from_uni : pointer; // was ^MY_UNI_IDX + state_map : ^cuchar; + ident_map : ^cuchar; + strxfrm_multiply : cuint; + mbminlen : cuint; + mbmaxlen : cuint; + min_sort_char : cuint16; + max_sort_char : cuint16; + escape_with_backslash_is_dangerous : my_bool; + cset : pointer; // was ^MY_CHARSET_HANDLER + coll : pointer; // was ^MY_COLLATION_HANDLER; + end; + CHARSET_INFO = charset_info_st; + Pcharset_info_st = ^charset_info_st; + +{$IFDEF mysql50} + Pcharacter_set = ^character_set; + character_set = record + number : cuint; + state : cuint; + csname : Pchar; + name : Pchar; + comment : Pchar; + dir : Pchar; + mbminlen : cuint; + mbmaxlen : cuint; + end; + MY_CHARSET_INFO = character_set; + PMY_CHARSET_INFO = ^MY_CHARSET_INFO; +{$ENDIF} + + Pst_mysql_methods = ^st_mysql_methods; + + Pst_mysql = ^st_mysql; + st_mysql = record + net : NET; // Communication parameters +{$ifdef mysql51} + connector_fd: pbyte; // ConnectorFd for SSL +{$else} + connector_fd : gptr; // ConnectorFd for SSL +{$endif} + host : Pchar; + user : Pchar; + passwd : Pchar; + unix_socket : Pchar; + server_version : Pchar; + host_info : Pchar; + info : Pchar; + db : Pchar; + charset : Pcharset_info_st; + fields : PMYSQL_FIELD; + field_alloc : MEM_ROOT; + affected_rows : my_ulonglong; + insert_id : my_ulonglong; // id if insert on table with NEXTNR + extra_info : my_ulonglong; // Used by mysqlshow, not used by mysql 5.0 and up + thread_id : culong; // Id for connection in server + packet_length : culong; + port : cuint; + client_flag : culong; + server_capabilities : culong; + protocol_version : cuint; + field_count : cuint; + server_status : cuint; + server_language : cuint; + warning_count : cuint; + options : st_mysql_options; + status : mysql_status; + free_me : my_bool; // If free in mysql_close + reconnect : my_bool; // set to 1 if automatic reconnect + scramble : array[0..(SCRAMBLE_LENGTH+1)-1] of char; // session-wide random string + { Set if this is the original connection, not a master or a slave we have + added though mysql_rpl_probe() or mysql_set_master()/ mysql_add_slave() } + rpl_pivot : my_bool; + { Pointers to the master, and the next slave connections, points to + itself if lone connection. } + master : Pst_mysql; + next_slave : Pst_mysql; + last_used_slave : Pst_mysql; // needed for round-robin slave pick + last_used_con : Pst_mysql; // needed for send/read/store/use result to work correctly with replication +{$IFDEF mysql41} + stmts : Pointer; // was PList, list of all statements + methods : Pst_mysql_methods; + thd : pointer; + { Points to boolean flag in MYSQL_RES or MYSQL_STMT. We set this flag + from mysql_stmt_close if close had to cancel result set of this object. } + unbuffered_fetch_owner : Pmy_bool; +{$ENDIF} +{$ifdef mysql51} + info_buffer: pchar; + extension: pointer; +{$endif} + end; + MYSQL = st_mysql; + PMYSQL = ^MYSQL; + + + Pst_mysql_res = ^st_mysql_res; +{$ifdef mysql51} + st_mysql_res = record + row_count : my_ulonglong; + fields : PMYSQL_FIELD; + data : PMYSQL_DATA; + data_cursor : PMYSQL_ROWS; + lengths : pculong; // column lengths of current row + handle : PMYSQL; // for unbuffered reads + methods : Pst_mysql_methods; + row : MYSQL_ROW; // If unbuffered read + current_row : MYSQL_ROW; // buffer to current row + field_alloc : MEM_ROOT; + field_count : cuint; + current_field : cuint; + eof : my_bool; // Used by mysql_fetch_row + unbuffered_fetch_cancelled : my_bool; // mysql_stmt_close() had to cancel this result + extension: pointer; + end; +{$else} + st_mysql_res = record + row_count : my_ulonglong; + fields : PMYSQL_FIELD; + data : PMYSQL_DATA; + data_cursor : PMYSQL_ROWS; + lengths : pculong; // column lengths of current row + handle : PMYSQL; // for unbuffered reads + field_alloc : MEM_ROOT; + field_count : cuint; + current_field : cuint; + row : MYSQL_ROW; // If unbuffered read + current_row : MYSQL_ROW; // buffer to current row + eof : my_bool; // Used by mysql_fetch_row +{$IFDEF mysql41} + unbuffered_fetch_cancelled : my_bool; // mysql_stmt_close() had to cancel this result + + methods : Pst_mysql_methods; +{$ENDIF} + end; +{$endif} + MYSQL_RES = st_mysql_res; + PMYSQL_RES = ^MYSQL_RES; + + Pst_mysql_stmt = ^st_mysql_stmt; + PMYSQL_STMT = ^MYSQL_STMT; + + st_mysql_methods = record + read_query_result : function (mysql:PMYSQL):my_bool;cdecl; +{$ifdef mysql51} + advanced_command : function (mysql:PMYSQL; command:enum_server_command; header:Pbyte; header_length:culong; arg:Pbyte; + arg_length:culong; skip_check:my_bool):my_bool; +{$else} + advanced_command : function (mysql:PMYSQL; command:enum_server_command; header:Pchar; header_length:culong; arg:Pchar; + arg_length:culong; skip_check:my_bool):my_bool; +{$endif} + read_rows : function (mysql:PMYSQL; mysql_fields:PMYSQL_FIELD; fields:cuint):PMYSQL_DATA; + use_result : function (mysql:PMYSQL):PMYSQL_RES; + fetch_lengths : procedure (fto:pculong; column:MYSQL_ROW; field_count:cuint); + flush_use_result : procedure (mysql:PMYSQL); +{ $if !defined(MYSQL_SERVER) || defined(EMBEDDED_LIBRARY)} + list_fields : function (mysql:PMYSQL):PMYSQL_FIELD; + read_prepare_result : function (mysql:PMYSQL; stmt:PMYSQL_STMT):my_bool; + stmt_execute : function (stmt:PMYSQL_STMT):cint; + read_binary_rows : function (stmt:PMYSQL_STMT):cint; + unbuffered_fetch : function (mysql:PMYSQL; row:PPchar):cint; + free_embedded_thd : procedure (mysql:PMYSQL); + read_statistics : function (mysql:PMYSQL):Pchar; + next_result : function (mysql:PMYSQL):my_bool; + read_change_user_result : function (mysql:PMYSQL; buff:Pchar; passwd:Pchar):cint; +{$IFDEF mysql50} + read_rowsfrom_cursor : function (stmt:PMYSQL_STMT):cint; +{$ENDIF mysql50} +{ $endif} + end; + MYSQL_METHODS = st_mysql_methods; + PMYSQL_METHODS = ^MYSQL_METHODS; + + + Pst_mysql_manager = ^st_mysql_manager; +{$ifdef mysql51} + st_mysql_manager = record + net : NET; + host : Pchar; + user : Pchar; + passwd : Pchar; + net_buf : Pchar; + net_buf_pos : Pchar; + net_data_end : Pchar; + port : cuint; + cmd_status : cint; + last_errno : cint; + net_buf_size : cint; + free_me : my_bool; + eof : my_bool; + last_error : array[0..(MAX_MYSQL_MANAGER_ERR)-1] of char; + extension: pointer; + end; +{$else} + st_mysql_manager = record + net : NET; + host : Pchar; + user : Pchar; + passwd : Pchar; + port : cuint; + free_me : my_bool; + eof : my_bool; + cmd_status : cint; + last_errno : cint; + net_buf : Pchar; + net_buf_pos : Pchar; + net_data_end : Pchar; + net_buf_size : cint; + last_error : array[0..(MAX_MYSQL_MANAGER_ERR)-1] of char; + end; +{$endif} + MYSQL_MANAGER = st_mysql_manager; + PMYSQL_MANAGER = ^MYSQL_MANAGER; + + Pst_mysql_parameters = ^st_mysql_parameters; + st_mysql_parameters = record + p_max_allowed_packet : pculong; + p_net_buffer_length : pculong; + end; + MYSQL_PARAMETERS = st_mysql_parameters; + PMYSQL_PARAMETERS = ^MYSQL_PARAMETERS; + + { The following definitions are added for the enhanced + client-server protocol } + + { statement state } + + { + Note: this info is from the mysql-5.0 version: + + This structure is used to define bind information, and + internally by the client library. + Public members with their descriptions are listed below + (conventionally `On input' refers to the binds given to + mysql_stmt_bind_param, `On output' refers to the binds given + to mysql_stmt_bind_result): + + buffer_type - One of the MYSQL_* types, used to describe + the host language type of buffer. + On output: if column type is different from + buffer_type, column value is automatically converted + to buffer_type before it is stored in the buffer. + buffer - On input: points to the buffer with input data. + On output: points to the buffer capable to store + output data. + The type of memory pointed by buffer must correspond + to buffer_type. See the correspondence table in + the comment to mysql_stmt_bind_param. + + The two above members are mandatory for any kind of bind. + + buffer_length - the length of the buffer. You don't have to set + it for any fixed length buffer: float, double, + int, etc. It must be set however for variable-length + types, such as BLOBs or STRINGs. + + length - On input: in case when lengths of input values + are different for each execute, you can set this to + point at a variable containining value length. This + way the value length can be different in each execute. + If length is not NULL, buffer_length is not used. + Note, length can even point at buffer_length if + you keep bind structures around while fetching: + this way you can change buffer_length before + each execution, everything will work ok. + On output: if length is set, mysql_stmt_fetch will + write column length into it. + + is_null - On input: points to a boolean variable that should + be set to TRUE for NULL values. + This member is useful only if your data may be + NULL in some but not all cases. + If your data is never NULL, is_null should be set to 0. + If your data is always NULL, set buffer_type + to MYSQL_TYPE_NULL, and is_null will not be used. + + is_unsigned - On input: used to signify that values provided for one + of numeric types are unsigned. + On output describes signedness of the output buffer. + If, taking into account is_unsigned flag, column data + is out of range of the output buffer, data for this column + is regarded truncated. Note that this has no correspondence + to the sign of result set column, if you need to find it out + use mysql_stmt_result_metadata. + error - where to write a truncation error if it is present. + possible error value is: + 0 no truncation + 1 value is out of range or buffer is too small + + Please note that MYSQL_BIND also has internals members. + } + +{$ifdef mysql51} + Pst_mysql_bind_51 = ^st_mysql_bind_51; + st_mysql_bind_51 = record + length : pculong; // output length pointer + is_null : Pmy_bool; // Pointer to null indicator + buffer : pointer; // buffer to get/put data + error: pmy_bool; // set this if you want to track data truncations happened during fetch + row_ptr : PByte; // for the current data position + store_param_func : procedure (net:PNET; param:Pst_mysql_bind_51);cdecl; + fetch_result : procedure (_para1:Pst_mysql_bind_51; _para2:PMYSQL_FIELD; row:PPbyte); + skip_result : procedure (_para1:Pst_mysql_bind_51; _para2:PMYSQL_FIELD; row:PPbyte); + buffer_length : culong; // buffer length, must be set for str/binary + offset : culong; // offset position for char/binary fetch + length_value : culong; // Used if length is 0 + param_number : cuint; // For null count and error messages + pack_length : cuint; // Internal length for packed data + buffer_type : enum_field_types; // buffer type + error_value : my_bool; // used if error is 0 + is_unsigned : my_bool; // set if integer type is unsigned + long_data_used : my_bool; // If used with mysql_send_long_data + is_null_value : my_bool; // Used if is_null is 0 + extension: pointer; + end; + + MYSQL_BIND_51 = st_mysql_bind_51; + PMYSQL_BIND_51 = ^MYSQL_BIND_51; + + Pst_mysql_bind_50 = ^st_mysql_bind_50; + st_mysql_bind_50 = record + length : pculong; // output length pointer + is_null : Pmy_bool; // Pointer to null indicator + buffer : pointer; // buffer to get/put data + error: pmy_bool; // set this if you want to track data truncations happened during fetch + buffer_type : enum_field_types; // buffer type + buffer_length : culong; // buffer length, must be set for str/binary + { Following are for internal use. Set by mysql_stmt_bind_param } + row_ptr : PByte; // for the current data position + offset : culong; // offset position for char/binary fetch + length_value : culong; // Used if length is 0 + param_number : cuint; // For null count and error messages + pack_length : cuint; // Internal length for packed data + error_value : my_bool; // used if error is 0 + is_unsigned : my_bool; // set if integer type is unsigned + long_data_used : my_bool; // If used with mysql_send_long_data + is_null_value : my_bool; // Used if is_null is 0 + store_param_func : procedure (net:PNET; param:Pst_mysql_bind_50);cdecl; + fetch_result : procedure (_para1:Pst_mysql_bind_50; _para2:PMYSQL_FIELD; row:PPbyte); + skip_result : procedure (_para1:Pst_mysql_bind_50; _para2:PMYSQL_FIELD; row:PPbyte); + end; + + MYSQL_BIND_50 = st_mysql_bind_50; + PMYSQL_BIND_50 = ^MYSQL_BIND_50; +{$else} + Pst_mysql_bind = ^st_mysql_bind; + st_mysql_bind = record + length : pculong; // output length pointer + is_null : Pmy_bool; // Pointer to null indicator + buffer : pointer; // buffer to get/put data +{$IFDEF mysql50} + error: pmy_bool; // set this if you want to track data truncations happened during fetch +{$ENDIF} + buffer_type : enum_field_types; // buffer type + buffer_length : culong; // buffer length, must be set for str/binary + { Following are for internal use. Set by mysql_stmt_bind_param } +{$IFNDEF mysql50} + inter_buffer : Pbyte; // for the current data position +{$ELSE} + row_ptr : PByte; // for the current data position +{$ENDIF} + offset : culong; // offset position for char/binary fetch +{$IFNDEF mysql50} + internal_length : culong; // Used if length is 0 +{$ELSE} + length_value : culong; // Used if length is 0 +{$ENDIF} + param_number : cuint; // For null count and error messages + pack_length : cuint; // Internal length for packed data +{$IFDEF mysql50} + error_value : my_bool; // used if error is 0 +{$ENDIF} + is_unsigned : my_bool; // set if integer type is unsigned + long_data_used : my_bool; // If used with mysql_send_long_data +{$IFNDEF mysql50} + internal_is_null : my_bool; // Used if is_null is 0 +{$ELSE} + is_null_value : my_bool; // Used if is_null is 0 +{$ENDIF} + store_param_func : procedure (net:PNET; param:Pst_mysql_bind);cdecl; + fetch_result : procedure (_para1:Pst_mysql_bind; _para2:PMYSQL_FIELD; row:PPbyte); + skip_result : procedure (_para1:Pst_mysql_bind; _para2:PMYSQL_FIELD; row:PPbyte); + end; + MYSQL_BIND = st_mysql_bind; + PMYSQL_BIND = ^MYSQL_BIND; +{$endif} + + { statement handler } +{$ifdef mysql51} + st_mysql_stmt = record + mem_root : MEM_ROOT; // root allocations + list : LIST; // list to keep track of all stmts + mysql : PMYSQL; // connection handle + params : PMYSQL_BIND_51; // input parameters + bind : PMYSQL_BIND_51; // input parameters + fields : PMYSQL_FIELD; // result set metadata + result : MYSQL_DATA; // cached result set + data_cursor : PMYSQL_ROWS; // current row in cached result + { mysql_stmt_fetch() calls this function to fetch one row (it's different + for buffered, unbuffered and cursor fetch). } + read_row_func : function (stmt:Pst_mysql_stmt; row:PPbyte):cint;cdecl; + affected_rows : my_ulonglong; // copy of mysql->affected_rows after statement execution + insert_id : my_ulonglong; // copy of mysql->insert_id + stmt_id : culong; // Id for prepared statement + flags : culong; // i.e. type of cursor to open + prefetch_rows : culong; // number of rows per one COM_FETCH + server_status : cuint; // Copied from mysql->server_status after execute/fetch to know + // server-side cursor status for this statement. + last_errno : cuint; // error code + param_count : cuint; // input parameter count + field_count : cuint; // number of columns in result set + state : enum_mysql_stmt_state; // statement state + last_error : array[0..(MYSQL_ERRMSG_SIZE)-1] of char; // error message + sqlstate : array[0..(SQLSTATE_LENGTH+1)-1] of char; + send_types_to_server : my_bool; // Types of input parameters should be sent to server + bind_param_done : my_bool; // input buffers were supplied + bind_result_done : cuchar; // output buffers were supplied + + unbuffered_fetch_cancelled : my_bool; // mysql_stmt_close() had to cancel this result + { Is set to true if we need to calculate field->max_length for + metadata fields when doing mysql_stmt_store_result. } + update_max_length : my_bool; + extension: pointer; + end; +{$else} + st_mysql_stmt = record + mem_root : MEM_ROOT; // root allocations + list : LIST; // list to keep track of all stmts + mysql : PMYSQL; // connection handle + params : PMYSQL_BIND; // input parameters + bind : PMYSQL_BIND; // input parameters + fields : PMYSQL_FIELD; // result set metadata + result : MYSQL_DATA; // cached result set + data_cursor : PMYSQL_ROWS; // current row in cached result + affected_rows : my_ulonglong; // copy of mysql->affected_rows after statement execution + insert_id : my_ulonglong; // copy of mysql->insert_id + { mysql_stmt_fetch() calls this function to fetch one row (it's different + for buffered, unbuffered and cursor fetch). } + read_row_func : function (stmt:Pst_mysql_stmt; row:PPbyte):cint;cdecl; + stmt_id : culong; // Id for prepared statement +{$IFDEF mysql50} + flags : culong; // i.e. type of cursor to open + prefetch_rows : culong; // number of rows per one COM_FETCH + server_status : cuint; // Copied from mysql->server_status after execute/fetch to know + // server-side cursor status for this statement. +{$ENDIF} + last_errno : cuint; // error code + param_count : cuint; // input parameter count + field_count : cuint; // number of columns in result set + state : enum_mysql_stmt_state; // statement state + last_error : array[0..(MYSQL_ERRMSG_SIZE)-1] of char; // error message + sqlstate : array[0..(SQLSTATE_LENGTH+1)-1] of char; + send_types_to_server : my_bool; // Types of input parameters should be sent to server + bind_param_done : my_bool; // input buffers were supplied +{$IFNDEF mysql50} + bind_result_done : my_bool; // output buffers were supplied +{$ELSE} + bind_result_done : cuchar; // output buffers were supplied +{$ENDIF} + + unbuffered_fetch_cancelled : my_bool; // mysql_stmt_close() had to cancel this result + { Is set to true if we need to calculate field->max_length for + metadata fields when doing mysql_stmt_store_result. } + update_max_length : my_bool; + end; +{$endif} + + MYSQL_STMT = st_mysql_stmt; + { When doing mysql_stmt_store_result calculate max_length attribute + of statement metadata. This is to be consistent with the old API, + where this was done automatically. + In the new API we do that only by request because it slows down + mysql_stmt_store_result sufficiently. } + enum_stmt_attr_type = (STMT_ATTR_UPDATE_MAX_LENGTH +{$IFDEF mysql50} + ,STMT_ATTR_CURSOR_TYPE, // unsigned long with combination of cursor flags (read only, for update, etc) + STMT_ATTR_PREFETCH_ROWS // Amount of rows to retrieve from server per one fetch if using cursors. + // Accepts unsigned long attribute in the range 1 - ulong_max +{$ENDIF} + ); + + +//#define max_allowed_packet (*mysql_get_parameters()->p_max_allowed_packet) +//#define net_buffer_length (*mysql_get_parameters()->p_net_buffer_length) + +{$IFNDEF LinkDynamically} + { Set up and bring down the server; to ensure that applications will + work when linked against either the standard client library or the + embedded server library, these functions should be called. } + function mysql_server_init(argc:cint; argv:PPchar; groups:PPchar):cint;cdecl;external mysqllib name 'mysql_server_init'; + procedure mysql_server_end;cdecl;external mysqllib name 'mysql_server_end'; + + { mysql_server_init/end need to be called when using libmysqld or + libmysqlclient (exactly, mysql_server_init() is called by mysql_init() so + you don't need to call it explicitely; but you need to call + mysql_server_end() to free memory). The names are a bit misleading + (mysql_SERVER* to be used when using libmysqlCLIENT). So we add more general + names which suit well whether you're using libmysqld or libmysqlclient. We + intend to promote these aliases over the mysql_server* ones. } + + function mysql_library_init(argc:cint; argv:PPchar; groups:PPchar):cint;cdecl;external mysqllib name 'mysql_server_init'; + procedure mysql_library_end;cdecl;external mysqllib name 'mysql_server_end'; + + function mysql_get_parameters:PMYSQL_PARAMETERS;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_get_parameters'; + + { Set up and bring down a thread; these function should be called + for each thread in an application which opens at least one MySQL + connection. All uses of the connection(s) should be between these + function calls. } + function mysql_thread_init:my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_thread_init'; + procedure mysql_thread_end;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_thread_end'; + { Functions to get information from the MYSQL and MYSQL_RES structures + Should definitely be used if one uses shared libraries. } + function mysql_num_rows(res:PMYSQL_RES):my_ulonglong;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_num_rows'; + function mysql_num_fields(res:PMYSQL_RES):cuint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_num_fields'; + function mysql_eof(res:PMYSQL_RES):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_eof'; + function mysql_fetch_field_direct(res:PMYSQL_RES; fieldnr:cuint):PMYSQL_FIELD;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_fetch_field_direct'; + function mysql_fetch_fields(res:PMYSQL_RES):PMYSQL_FIELD;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_fetch_fields'; + function mysql_row_tell(res:PMYSQL_RES):MYSQL_ROW_OFFSET;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_row_tell'; + function mysql_field_tell(res:PMYSQL_RES):MYSQL_FIELD_OFFSET;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_field_tell'; + function mysql_field_count(mysql:PMYSQL):cuint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_field_count'; + function mysql_affected_rows(mysql:PMYSQL):my_ulonglong;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_affected_rows'; + function mysql_insert_id(mysql:PMYSQL):my_ulonglong;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_insert_id'; + function mysql_errno(mysql:PMYSQL):cuint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_errno'; + function mysql_error(mysql:PMYSQL):Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_error'; + function mysql_sqlstate(mysql:PMYSQL):Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_sqlstate'; + function mysql_warning_count(mysql:PMYSQL):cuint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_warning_count'; + function mysql_info(mysql:PMYSQL):Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_info'; + function mysql_thread_id(mysql:PMYSQL):culong;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_thread_id'; + function mysql_character_set_name(mysql:PMYSQL):Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_character_set_name'; + function mysql_set_character_set(mysql:PMYSQL; csname:Pchar):longint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_set_character_set'; + function mysql_init(mysql:PMYSQL):PMYSQL;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_init'; + function mysql_ssl_set(mysql:PMYSQL; key:Pchar; cert:Pchar; ca:Pchar; capath:Pchar; + cipher:Pchar):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_ssl_set'; + function mysql_change_user(mysql:PMYSQL; user:Pchar; passwd:Pchar; db:Pchar):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_change_user'; + function mysql_real_connect(mysql:PMYSQL; host:Pchar; user:Pchar; passwd:Pchar; db:Pchar; + port:cuint; unix_socket:Pchar; clientflag:culong):PMYSQL;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_real_connect'; + function mysql_select_db(mysql:PMYSQL; db:Pchar):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_select_db'; + function mysql_query(mysql:PMYSQL; q:Pchar):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_query'; + function mysql_send_query(mysql:PMYSQL; q:Pchar; length:culong):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_send_query'; + function mysql_real_query(mysql:PMYSQL; q:Pchar; length:culong):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_real_query'; + function mysql_store_result(mysql:PMYSQL):PMYSQL_RES;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_store_result'; + function mysql_use_result(mysql:PMYSQL):PMYSQL_RES;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_use_result'; + +{$ELSE} + +{$ENDIF} + +{$IFNDEF LinkDynamically} + { perform query on master } + function mysql_master_query(mysql:PMYSQL; q:Pchar; length:culong):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_master_query'; + function mysql_master_send_query(mysql:PMYSQL; q:Pchar; length:culong):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_master_send_query'; + + { perform query on slave } + function mysql_slave_query(mysql:PMYSQL; q:Pchar; length:culong):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_slave_query'; + function mysql_slave_send_query(mysql:PMYSQL; q:Pchar; length:culong):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_slave_send_query'; +{$IFDEF mysql50} + procedure mysql_get_character_set_info(mysql : PMYSQL; charset : PMY_CHARSET_INFO);{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_get_character_set_info'; +{$ENDIF} +{$ENDIF} + + { local infile support } + + const + LOCAL_INFILE_ERROR_LEN = 512; + +{$IFNDEF LinkDynamically} +{ procedure mysql_set_local_infile_handler(mysql:PMYSQL; local_infile_init:function (_para1:Ppointer; _para2:Pchar; _para3:pointer):longint; local_infile_read:function (_para1:pointer; _para2:Pchar; _para3:dword):longint; local_infile_end:procedure (_pa + _para6:pointer);cdecl;external mysqllib name 'mysql_set_local_infile_handler';} + procedure mysql_set_local_infile_default(mysql:PMYSQL);cdecl;external mysqllib name 'mysql_set_local_infile_default'; + + { enable/disable parsing of all queries to decide if they go on master or + slave } + procedure mysql_enable_rpl_parse(mysql:PMYSQL);{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_enable_rpl_parse'; + procedure mysql_disable_rpl_parse(mysql:PMYSQL);{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_disable_rpl_parse'; + + { get the value of the parse flag } + function mysql_rpl_parse_enabled(mysql:PMYSQL):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_rpl_parse_enabled'; + + { enable/disable reads from master } + procedure mysql_enable_reads_from_master(mysql:PMYSQL);{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_enable_reads_from_master'; + procedure mysql_disable_reads_from_master(mysql:PMYSQL);{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_disable_reads_from_master'; + + { get the value of the master read flag } + function mysql_reads_from_master_enabled(mysql:PMYSQL):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_reads_from_master_enabled'; + + function mysql_rpl_query_type(q : pchar;len : cint):mysql_rpl_type;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_rpl_query_type'; + + { discover the master and its slaves } + function mysql_rpl_probe(mysql:PMYSQL):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_rpl_probe'; + + { set the master, close/free the old one, if it is not a pivot } + function mysql_set_master(mysql:PMYSQL; host:Pchar; port:cuint; user:Pchar; passwd:Pchar):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_set_master'; + function mysql_add_slave(mysql:PMYSQL; host:Pchar; port:cuint; user:Pchar; passwd:Pchar):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_add_slave'; + function mysql_shutdown(mysql:PMYSQL; shutdown_level:mysql_enum_shutdown_level):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_shutdown'; + function mysql_dump_debug_info(mysql:PMYSQL):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_dump_debug_info'; + function mysql_refresh(mysql:PMYSQL; refresh_options:cuint):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_refresh'; + function mysql_kill(mysql:PMYSQL; pid:culong):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_kill'; + function mysql_set_server_option(mysql:PMYSQL; option:enum_mysql_set_option):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_set_server_option'; + function mysql_ping(mysql:PMYSQL):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_ping'; + function mysql_stat(mysql:PMYSQL):Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stat'; + function mysql_get_server_info(mysql:PMYSQL):Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_get_server_info'; + function mysql_get_client_info:Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_get_client_info'; + function mysql_get_client_version:culong;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_get_client_version'; + function mysql_get_host_info(mysql:PMYSQL):Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_get_host_info'; + function mysql_get_server_version(mysql:PMYSQL):culong;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_get_server_version'; + function mysql_get_proto_info(mysql:PMYSQL):cuint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_get_proto_info'; + function mysql_list_dbs(mysql:PMYSQL; wild:Pchar):PMYSQL_RES;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_list_dbs'; + + function mysql_list_tables(mysql:PMYSQL; wild:Pchar):PMYSQL_RES;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_list_tables'; + function mysql_list_processes(mysql:PMYSQL):PMYSQL_RES;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_list_processes'; +{$ifdef mysql51} + function mysql_options(mysql:PMYSQL; option:mysql_option; arg: pointer):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_options'; +{$else} + function mysql_options(mysql:PMYSQL; option:mysql_option; arg:Pchar):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_options'; +{$endif} + procedure mysql_free_result(result:PMYSQL_RES);{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_free_result'; + procedure mysql_data_seek(result:PMYSQL_RES; offset:my_ulonglong);{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_data_seek'; + function mysql_row_seek(result:PMYSQL_RES; offset:MYSQL_ROW_OFFSET):MYSQL_ROW_OFFSET;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_row_seek'; + function mysql_field_seek(result:PMYSQL_RES; offset:MYSQL_FIELD_OFFSET):MYSQL_FIELD_OFFSET;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_field_seek'; + function mysql_fetch_row(result:PMYSQL_RES):MYSQL_ROW;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_fetch_row'; + function mysql_fetch_lengths(result:PMYSQL_RES):pculong;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_fetch_lengths'; + function mysql_fetch_field(result:PMYSQL_RES):PMYSQL_FIELD;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_fetch_field'; + function mysql_list_fields(mysql:PMYSQL; table:Pchar; wild:Pchar):PMYSQL_RES;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_list_fields'; + function mysql_escape_string(fto:Pchar; from:Pchar; from_length:culong):culong;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_escape_string'; + function mysql_hex_string(fto:Pchar; from:Pchar; from_length:culong):culong;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_hex_string'; + function mysql_real_escape_string(mysql:PMYSQL; fto:Pchar; from:Pchar; length:culong):culong;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_real_escape_string'; + procedure mysql_debug(debug:Pchar);{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_debug'; +(* function mysql_odbc_escape_string(mysql:PMYSQL; fto:Pchar; to_length:dword; from:Pchar; from_length:dword; + param:pointer; extend_buffer:function (_para1:pointer; to:Pchar; length:Pdword):Pchar):Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_odbc_escape_string';*) + procedure myodbc_remove_escape(mysql:PMYSQL; name:Pchar);{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'myodbc_remove_escape'; + function mysql_thread_safe:cuint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_thread_safe'; + function mysql_embedded:my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_embedded'; + function mysql_manager_init(con:PMYSQL_MANAGER):PMYSQL_MANAGER;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_manager_init'; + function mysql_manager_connect(con:PMYSQL_MANAGER; host:Pchar; user:Pchar; passwd:Pchar; port:cuint):PMYSQL_MANAGER;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_manager_connect'; + procedure mysql_manager_close(con:PMYSQL_MANAGER);{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_manager_close'; + function mysql_manager_command(con:PMYSQL_MANAGER; cmd:Pchar; cmd_len:cint):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_manager_command'; + function mysql_manager_fetch_line(con:PMYSQL_MANAGER; res_buf:Pchar; res_buf_size:cint):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_manager_fetch_line'; + function mysql_read_query_result(mysql:PMYSQL):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_read_query_result'; + + function mysql_stmt_init(mysql:PMYSQL):PMYSQL_STMT;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_init'; + function mysql_stmt_prepare(stmt:PMYSQL_STMT; query:Pchar; length:culong):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_prepare'; + function mysql_stmt_execute(stmt:PMYSQL_STMT):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_execute'; + function mysql_stmt_fetch(stmt:PMYSQL_STMT):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_fetch'; +{$ifdef mysql51} + function mysql_stmt_fetch_column(stmt:PMYSQL_STMT; bind: pointer{PMYSQL_BIND}; column:cuint; offset:culong):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_fetch_column'; +{$else} + function mysql_stmt_fetch_column(stmt:PMYSQL_STMT; bind:PMYSQL_BIND; column:cuint; offset:culong):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_fetch_column'; +{$endif} + function mysql_stmt_store_result(stmt:PMYSQL_STMT):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_store_result'; + function mysql_stmt_param_count(stmt:PMYSQL_STMT):culong;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_param_count'; + function mysql_stmt_attr_set(stmt:PMYSQL_STMT; attr_type:enum_stmt_attr_type; attr:pointer):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_attr_set'; + function mysql_stmt_attr_get(stmt:PMYSQL_STMT; attr_type:enum_stmt_attr_type; attr:pointer):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_attr_get'; + function mysql_stmt_bind_param(stmt:PMYSQL_STMT; bnd:PMYSQL_BIND):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_bind_param'; + function mysql_stmt_bind_result(stmt:PMYSQL_STMT; bnd:PMYSQL_BIND):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_bind_result'; + function mysql_stmt_close(stmt:PMYSQL_STMT):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_close'; + function mysql_stmt_reset(stmt:PMYSQL_STMT):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_reset'; + function mysql_stmt_free_result(stmt:PMYSQL_STMT):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_free_result'; + function mysql_stmt_send_long_data(stmt:PMYSQL_STMT; param_number:cuint; data:Pchar; length:culong):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_send_long_data'; + function mysql_stmt_result_metadata(stmt:PMYSQL_STMT):PMYSQL_RES;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_result_metadata'; + function mysql_stmt_param_metadata(stmt:PMYSQL_STMT):PMYSQL_RES;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_param_metadata'; + function mysql_stmt_errno(stmt:PMYSQL_STMT):cuint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_errno'; + function mysql_stmt_error(stmt:PMYSQL_STMT):Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_error'; + function mysql_stmt_sqlstate(stmt:PMYSQL_STMT):Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_sqlstate'; + function mysql_stmt_row_seek(stmt:PMYSQL_STMT; offset:MYSQL_ROW_OFFSET):MYSQL_ROW_OFFSET;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_row_seek'; + function mysql_stmt_row_tell(stmt:PMYSQL_STMT):MYSQL_ROW_OFFSET;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_row_tell'; + procedure mysql_stmt_data_seek(stmt:PMYSQL_STMT; offset:my_ulonglong);{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_data_seek'; + function mysql_stmt_num_rows(stmt:PMYSQL_STMT):my_ulonglong;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_num_rows'; + function mysql_stmt_affected_rows(stmt:PMYSQL_STMT):my_ulonglong;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_affected_rows'; + function mysql_stmt_insert_id(stmt:PMYSQL_STMT):my_ulonglong;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_insert_id'; + function mysql_stmt_field_count(stmt:PMYSQL_STMT):cuint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_stmt_field_count'; + + function mysql_commit(mysql:PMYSQL):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_commit'; + function mysql_rollback(mysql:PMYSQL):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_rollback'; + function mysql_autocommit(mysql:PMYSQL; auto_mode:my_bool):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_autocommit'; + function mysql_more_results(mysql:PMYSQL):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_more_results'; + function mysql_next_result(mysql:PMYSQL):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_next_result'; + procedure mysql_close(sock:PMYSQL);{$ifdef wincall}stdcall{$else}cdecl{$endif};external mysqllib name 'mysql_close'; + +{$ELSE} + +{$ENDIF} + + + { status return codes } + + const + MYSQL_NO_DATA = 100; + MYSQL_DATA_TRUNCATED = 101; + + function mysql_reload(mysql : PMySQL) : cint; + +{$IFNDEF LinkDynamically} +{$ifdef USE_OLD_FUNCTIONS} + function mysql_connect(mysql:PMYSQL; host:Pchar; user:Pchar; passwd:Pchar):PMYSQL;{$ifdef wincall}stdcall{$else}cdecl{$endif};external External_library name 'mysql_connect'; + function mysql_create_db(mysql:PMYSQL; DB:Pchar):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external External_library name 'mysql_create_db'; + function mysql_drop_db(mysql:PMYSQL; DB:Pchar):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif};external External_library name 'mysql_drop_db'; + function mysql_reload(mysql : PMySQL) : cint; +{$endif} +{$endif} + +{$define HAVE_MYSQL_REAL_CONNECT} + { The following functions are mainly exported because of mysqlbinlog; + They are not for general usage } + + function simple_command(mysql,command,arg,length,skip_check : cint) : cint; +{$IFNDEF LinkDynamically} + function net_safe_read(mysql:PMYSQL):cuint;cdecl;external mysqllib name 'net_safe_read'; +{$ENDIF} + +{$ifdef NETWARE} +(** unsupported pragma#pragma pack(pop) /* restore alignment */*) +{$endif} + +{$IFDEF LinkDynamically} +//Function InitialiseMysql(Const LibraryName : String) : Integer; +//Function InitialiseMysql : Integer; + +//var MysqlLibraryHandle : TLibHandle; +{$ENDIF} + +// var +// my_init : function :my_bool;cdecl; +// my_thread_init : function :my_bool;cdecl; +// my_thread_end : procedure ;cdecl; + var + mysql_server_init: function (argc:cint; argv:PPchar; groups:PPchar):cint;cdecl; + mysql_server_end: procedure ;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_library_init: function (argc:cint; argv:PPchar; groups:PPchar):cint;cdecl; + mysql_library_end: procedure ;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_num_rows: function (res:PMYSQL_RES):my_ulonglong;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_num_fields: function (res:PMYSQL_RES):cuint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_eof: function (res:PMYSQL_RES):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_fetch_field_direct: function (res:PMYSQL_RES; fieldnr:cuint):PMYSQL_FIELD;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_fetch_fields: function (res:PMYSQL_RES):PMYSQL_FIELD;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_row_tell: function (res:PMYSQL_RES):MYSQL_ROW_OFFSET;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_field_tell: function (res:PMYSQL_RES):MYSQL_FIELD_OFFSET;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_field_count: function (mysql:PMYSQL):cuint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_affected_rows: function (mysql:PMYSQL):my_ulonglong;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_insert_id: function (mysql:PMYSQL):my_ulonglong;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_errno: function (mysql:PMYSQL):cuint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_error: function (mysql:PMYSQL):Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_sqlstate: function (mysql:PMYSQL):Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_warning_count: function (mysql:PMYSQL):cuint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_info: function (mysql:PMYSQL):Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_thread_id: function (mysql:PMYSQL):culong;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_character_set_name: function (mysql:PMYSQL):Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_set_character_set: function (mysql:PMYSQL; csname:Pchar):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_get_character_set_info: procedure(mysql : PMYSQL; charset : PMY_CHARSET_INFO);{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_init: function (mysql:PMYSQL):PMYSQL;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_ssl_set: function (mysql:PMYSQL; key:Pchar; cert:Pchar; ca:Pchar; capath:Pchar; + cipher:Pchar):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_get_ssl_cipher: function (mysql: pmysql): pchar; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_change_user: function (mysql:PMYSQL; user:Pchar; passwd:Pchar; db:Pchar):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_real_connect: function (mysql:PMYSQL; host:Pchar; user:Pchar; passwd:Pchar; db:Pchar; + port:cuint; unix_socket:Pchar; clientflag:culong):PMYSQL;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_select_db: function (mysql:PMYSQL; db:Pchar):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_query: function (mysql:PMYSQL; q:Pchar):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_send_query: function (mysql:PMYSQL; q:Pchar; length:culong):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_real_query: function (mysql:PMYSQL; q:Pchar; length:culong):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_store_result: function (mysql:PMYSQL):PMYSQL_RES;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_use_result: function (mysql:PMYSQL):PMYSQL_RES;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + var + mysql_shutdown: function (mysql:PMYSQL; shutdown_level:mysql_enum_shutdown_level):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_dump_debug_info: function (mysql:PMYSQL):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_refresh: function (mysql:PMYSQL; refresh_options:cuint):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_kill: function (mysql:PMYSQL; pid:culong):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_set_server_option: function (mysql:PMYSQL; option:enum_mysql_set_option):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_ping: function (mysql:PMYSQL):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stat: function (mysql:PMYSQL):Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_get_server_info: function (mysql:PMYSQL):Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_get_client_info: function :Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_get_client_version: function :culong;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_get_host_info: function (mysql:PMYSQL):Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_get_server_version: function (mysql:PMYSQL):culong;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_get_proto_info: function (mysql:PMYSQL):cuint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_list_dbs: function (mysql:PMYSQL; wild:Pchar):PMYSQL_RES;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + + mysql_list_tables: function (mysql:PMYSQL; wild:Pchar):PMYSQL_RES;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_list_processes: function (mysql:PMYSQL):PMYSQL_RES;{$ifdef wincall}stdcall{$else}cdecl{$endif}; +{$ifdef mysql51} + mysql_options: function (mysql:PMYSQL; option:mysql_option; arg: pointer):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; +{$else} + mysql_options: function (mysql:PMYSQL; option:mysql_option; arg:Pchar):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; +{$endif} + mysql_free_result: procedure (result:PMYSQL_RES);{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_data_seek: procedure (result:PMYSQL_RES; offset:my_ulonglong);{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_row_seek: function (result:PMYSQL_RES; offset:MYSQL_ROW_OFFSET):MYSQL_ROW_OFFSET;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_field_seek: function (result:PMYSQL_RES; offset:MYSQL_FIELD_OFFSET):MYSQL_FIELD_OFFSET;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_fetch_row: function (result:PMYSQL_RES):MYSQL_ROW;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_fetch_lengths: function (result:PMYSQL_RES):pculong;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_fetch_field: function (result:PMYSQL_RES):PMYSQL_FIELD;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_list_fields: function (mysql:PMYSQL; table:Pchar; wild:Pchar):PMYSQL_RES;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_escape_string: function (fto:Pchar; from:Pchar; from_length:culong):culong;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_hex_string: function (fto:Pchar; from:Pchar; from_length:culong):culong;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_real_escape_string: function (mysql:PMYSQL; fto:Pchar; from:Pchar; length:culong):culong;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_debug: procedure (debug:Pchar);{$ifdef wincall}stdcall{$else}cdecl{$endif}; + + mysql_rollback: function (mysql:PMYSQL):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_autocommit: function (mysql:PMYSQL; auto_mode:my_bool):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_commit: function (mysql:PMYSQL):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_more_results: function (mysql:PMYSQL):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_next_result: function (mysql:PMYSQL):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_close: procedure (sock:PMYSQL);{$ifdef wincall}stdcall{$else}cdecl{$endif}; + + mysql_stmt_init: function (mysql:PMYSQL):PMYSQL_STMT;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_prepare: function (stmt:PMYSQL_STMT; query:Pchar; length:culong):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_execute: function (stmt:PMYSQL_STMT):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_fetch: function (stmt:PMYSQL_STMT):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; +{$ifdef mysql51} + mysql_stmt_fetch_column: function (stmt:PMYSQL_STMT; bind:pointer{PMYSQL_BIND}; column:cuint; offset:culong):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; +{$else} + mysql_stmt_fetch_column: function (stmt:PMYSQL_STMT; bind:PMYSQL_BIND; column:cuint; offset:culong):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; +{$endif} + mysql_stmt_store_result: function (stmt:PMYSQL_STMT):cint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_param_count: function (stmt:PMYSQL_STMT):culong;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_attr_set: function (stmt:PMYSQL_STMT; attr_type:enum_stmt_attr_type; attr:pointer):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_attr_get: function (stmt:PMYSQL_STMT; attr_type:enum_stmt_attr_type; attr:pointer):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif}; +{$ifdef mysql51} + mysql_stmt_bind_param: function (stmt:PMYSQL_STMT; bnd:pointer{PMYSQL_BIND}):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_bind_result: function (stmt:PMYSQL_STMT; bnd:pointer{PMYSQL_BIND}):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif}; +{$else} + mysql_stmt_bind_param: function (stmt:PMYSQL_STMT; bnd:PMYSQL_BIND):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_bind_result: function (stmt:PMYSQL_STMT; bnd:PMYSQL_BIND):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif}; +{$endif} + mysql_stmt_close: function (stmt:PMYSQL_STMT):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_reset: function (stmt:PMYSQL_STMT):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_free_result: function (stmt:PMYSQL_STMT):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_send_long_data: function (stmt:PMYSQL_STMT; param_number:cuint; data:Pchar; length:culong):my_bool;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_result_metadata: function (stmt:PMYSQL_STMT):PMYSQL_RES;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_param_metadata: function (stmt:PMYSQL_STMT):PMYSQL_RES;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_errno: function (stmt:PMYSQL_STMT):cuint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_error: function (stmt:PMYSQL_STMT):Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_sqlstate: function (stmt:PMYSQL_STMT):Pchar;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_row_seek: function (stmt:PMYSQL_STMT; offset:MYSQL_ROW_OFFSET): + MYSQL_ROW_OFFSET;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_row_tell: function (stmt:PMYSQL_STMT):MYSQL_ROW_OFFSET;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_data_seek: procedure (stmt:PMYSQL_STMT; offset:my_ulonglong);{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_num_rows: function (stmt:PMYSQL_STMT):my_ulonglong;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_affected_rows: function (stmt:PMYSQL_STMT):my_ulonglong;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_insert_id: function (stmt:PMYSQL_STMT):my_ulonglong;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + mysql_stmt_field_count: function (stmt:PMYSQL_STMT):cuint;{$ifdef wincall}stdcall{$else}cdecl{$endif}; + +implementation +uses + msesys,msesysintf{,msesonames} + {$IFDEF LinkDynamically},msedynload{$endif}; + +{$IFDEF LinkDynamically} + +ResourceString + SErrAlreadyLoaded = 'MySQL interface already initialized from library %s.'; + SErrLoadFailed = 'Can not load MySQL library "%s". Please check your installation.'; + SErrDefaultsFailed = 'Can not load default MySQL library ("%s" or "%s"). Check your installation.'; + +var + libinfo: dynlibinfoty; +// liblock: mutexty; +// RefCount : integer; +// LoadedLibrary : String; + + function net_new_transaction(net : st_net) : st_net; + begin + net.pkt_nr := 0; + result := net; + end; + + function IS_PRI_KEY(n : longint) : boolean; + begin + IS_PRI_KEY:=(n and PRI_KEY_FLAG)<>0; + end; + + function IS_NOT_NULL(n : longint) : boolean; + begin + IS_NOT_NULL:=(n and NOT_NULL_FLAG)<>0; + end; + + function IS_BLOB(n : longint) : boolean; + begin + IS_BLOB:=(n and BLOB_FLAG)<>0; + end; + + function IS_NUM_FIELD(f : pst_mysql_field) : boolean; + begin + IS_NUM_FIELD:=((f^.flags) and NUM_FLAG)<>0; + end; + + function IS_NUM(t : enum_field_types) : boolean; + begin +{$IFDEF mysql50} + IS_NUM := (t <= FIELD_TYPE_INT24) or (t=FIELD_TYPE_YEAR) or (t=FIELD_TYPE_NEWDECIMAL); +{$ELSE} + IS_NUM := (t <= FIELD_TYPE_INT24) or (t=FIELD_TYPE_YEAR); +{$ENDIF} + end; + + function INTERNAL_NUM_FIELD(f : Pst_mysql_field) : boolean; + begin + INTERNAL_NUM_FIELD := (f^.ftype <= FIELD_TYPE_INT24) and ((f^.ftype <> FIELD_TYPE_TIMESTAMP) + or (f^.length = 14) or (f^.length=8)) or (f^.ftype=FIELD_TYPE_YEAR); + end; + + function mysql_reload(mysql : PMySQL) : cint; + begin + mysql_reload:=mysql_refresh(mysql,REFRESH_GRANT); + end; + + function simple_command(mysql,command,arg,length,skip_check : longint) : longint; + begin + //simple_command:=mysql^.(methods^.advanced_command)(mysqlcommandNullS0arglengthskip_check); + result := -1; + end; + +(* +function tryinitialisemysql(const alibnames: array of filenamety): boolean; +var + mstr1: filenamety; +begin + sys_mutexlock(liblock); + try + result:= true; + if refcount = 0 then begin + mysqllibraryhandle:= loadlib(alibnames,mstr1); + if mysqllibraryhandle = nilhandle then begin + result:= false; + exit; + end; + try + getprocaddresses(mysqllibraryhandle, + [ + // 'my_init', //0 + // 'my_thread_init', //1 + // 'my_thread_end', //2 + 'mysql_affected_rows', //3 + 'mysql_autocommit', //4 + 'mysql_change_user', //5 + 'mysql_close', //6 + 'mysql_commit', //7 + 'mysql_data_seek', //8 + 'mysql_debug', //9 + 'mysql_dump_debug_info', //10 + 'mysql_eof', //11 + 'mysql_errno', //12 + 'mysql_error', //13 + 'mysql_escape_string', //14 + 'mysql_fetch_field', //15 + 'mysql_fetch_field_direct', //16 + 'mysql_fetch_fields', //17 + 'mysql_fetch_lengths', //18 + 'mysql_fetch_row', //19 + 'mysql_field_seek', //20 + 'mysql_field_count', //21 + 'mysql_field_tell', //22 + 'mysql_free_result', //23 + 'mysql_get_client_info', //24 + 'mysql_get_client_version', //25 + 'mysql_get_host_info', //26 + 'mysql_get_server_version', //27 + 'mysql_get_proto_info', //28 + 'mysql_get_server_info', //29 + 'mysql_info', //30 + 'mysql_init', //31 + 'mysql_insert_id', //32 + 'mysql_kill', //33 + 'mysql_server_end', //34 + 'mysql_server_init', //35 + 'mysql_list_dbs', //36 + 'mysql_list_fields', //37 + 'mysql_list_processes', //38 + 'mysql_list_tables', //39 + 'mysql_more_results', //40 + 'mysql_next_result', //41 + 'mysql_num_fields', //42 + 'mysql_num_rows', //43 + 'mysql_options', //44 + 'mysql_ping', //45 + 'mysql_query', //46 + 'mysql_real_connect', //47 + 'mysql_real_escape_string', //48 + 'mysql_real_query', //49 + 'mysql_refresh', //50 + 'mysql_rollback', //51 + 'mysql_row_seek', //52 + 'mysql_row_tell', //53 + 'mysql_select_db', //54 + 'mysql_server_end', //55 ??? + 'mysql_server_init', //56 ??? + 'mysql_set_server_option', //57 + 'mysql_sqlstate', //58 + 'mysql_shutdown', //59 + 'mysql_stat', //60 + 'mysql_store_result', //61 + 'mysql_thread_id', //62 + 'mysql_use_result', //63 + 'mysql_warning_count', //64 + 'mysql_stmt_init', //65 + 'mysql_stmt_prepare', //66 + 'mysql_stmt_execute', //67 + 'mysql_stmt_fetch', //68 + 'mysql_stmt_fetch_column', //69 + 'mysql_stmt_store_result', //70 + 'mysql_stmt_param_count', //71 + 'mysql_stmt_attr_set', //72 + 'mysql_stmt_attr_get', //73 + 'mysql_stmt_bind_param', //74 + 'mysql_stmt_bind_result', //75 + 'mysql_stmt_close', //76 + 'mysql_stmt_reset', //77 + 'mysql_stmt_free_result', //78 + 'mysql_stmt_send_long_data', //79 + 'mysql_stmt_result_metadata', //80 + 'mysql_stmt_param_metadata', //81 + 'mysql_stmt_errno', //82 + 'mysql_stmt_error', //83 + 'mysql_stmt_sqlstate', //84 + 'mysql_stmt_row_seek', //85 + 'mysql_stmt_row_tell', //86 + 'mysql_stmt_data_seek', //87 + 'mysql_stmt_num_rows', //88 + 'mysql_stmt_affected_rows', //89 + 'mysql_stmt_insert_id', //90 + 'mysql_stmt_field_count', //91 + 'mysql_ssl_set' //92 + ], + [ + // @my_init, //0 + // @my_thread_init, //1 + // @my_thread_end, //2 + @mysql_affected_rows, //3 + @mysql_autocommit, //4 + @mysql_change_user, //5 + @mysql_close, //6 + @mysql_commit, //7 + @mysql_data_seek, //8 + @mysql_debug, //9 + @mysql_dump_debug_info, //10 + @mysql_eof, //11 + @mysql_errno, //12 + @mysql_error, //13 + @mysql_escape_string, //14 + @mysql_fetch_field, //15 + @mysql_fetch_field_direct, //16 + @mysql_fetch_fields, //17 + @mysql_fetch_lengths, //18 + @mysql_fetch_row, //19 + @mysql_field_seek, //20 + @mysql_field_count, //21 + @mysql_field_tell, //22 + @mysql_free_result, //23 + @mysql_get_client_info, //24 + @mysql_get_client_version, //25 + @mysql_get_host_info, //26 + @mysql_get_server_version, //27 + @mysql_get_proto_info, //28 + @mysql_get_server_info, //29 + @mysql_info, //30 + @mysql_init, //31 + @mysql_insert_id, //32 + @mysql_kill, //33 + @mysql_server_end, //34 + @mysql_server_init, //35 + @mysql_list_dbs, //36 + @mysql_list_fields, //37 + @mysql_list_processes, //38 + @mysql_list_tables, //39 + @mysql_more_results, //40 + @mysql_next_result, //41 + @mysql_num_fields, //42 + @mysql_num_rows, //43 + @mysql_options, //44 + @mysql_ping, //45 + @mysql_query, //46 + @mysql_real_connect, //47 + @mysql_real_escape_string, //48 + @mysql_real_query, //49 + @mysql_refresh, //50 + @mysql_rollback, //51 + @mysql_row_seek, //52 + @mysql_row_tell, //53 + @mysql_select_db, //54 + @mysql_library_end, //55 + @mysql_library_init, //56 + @mysql_set_server_option, //57 + @mysql_sqlstate, //58 + @mysql_shutdown, //59 + @mysql_stat, //60 + @mysql_store_result, //61 + @mysql_thread_id, //62 + @mysql_use_result, //63 + @mysql_warning_count, //64 + @mysql_stmt_init, //65 + @mysql_stmt_prepare, //66 + @mysql_stmt_execute, //67 + @mysql_stmt_fetch, //68 + @mysql_stmt_fetch_column, //69 + @mysql_stmt_store_result, //70 + @mysql_stmt_param_count, //71 + @mysql_stmt_attr_set, //72 + @mysql_stmt_attr_get, //73 + @mysql_stmt_bind_param, //74 + @mysql_stmt_bind_result, //75 + @mysql_stmt_close, //76 + @mysql_stmt_reset, //77 + @mysql_stmt_free_result, //78 + @mysql_stmt_send_long_data, //79 + @mysql_stmt_result_metadata, //80 + @mysql_stmt_param_metadata, //81 + @mysql_stmt_errno, //82 + @mysql_stmt_error, //83 + @mysql_stmt_sqlstate, //84 + @mysql_stmt_row_seek, //85 + @mysql_stmt_row_tell, //86 + @mysql_stmt_data_seek, //87 + @mysql_stmt_num_rows, //88 + @mysql_stmt_affected_rows, //89 + @mysql_stmt_insert_id, //90 + @mysql_stmt_field_count, //91 + @mysql_ssl_set //92 + ]); +// mysql_library_init(-1,nil,nil); + getprocaddresses(mysqllibraryhandle, + [ + 'mysql_get_ssl_cipher' + ], + [ + @mysql_get_ssl_cipher],true); + except + on e: exception do begin + e.message:= 'Library "'+mstr1+'": '+e.message; + result:= false; + if unloadlibrary(mysqllibraryhandle) then begin + mysqllibraryhandle:= nilhandle; + end; + raise; + end; + end; + end; + inc(refcount); + finally + sys_mutexunlock(liblock); + end; +end; +*) +{ +Function InitialiseMysql : Integer; + +begin + Result := 0; + If (TryInitialiseMysql(mysqlvlib) = 0) and + (TryInitialiseMysql(mysqllib) = 0) then + Raise EInOutError.CreateFmt(SErrDefaultsFailed,[mysqlvlib,mysqllib]); + Result := RefCount; +end; +} +{ +Function InitialiseMysql(Const LibraryName : String) : Integer; + +begin + Result := TryInitialiseMysql(LibraryName); + If Result = 0 then + Raise EInOutError.CreateFmt(SErrLoadFailed,[LibraryName]) + else If (LibraryName<>LoadedLibrary) then + begin + Dec(RefCount); + Result := RefCount; + Raise EInOUtError.CreateFmt(SErrAlreadyLoaded,[LoadedLibrary]); + end; +end; +} +{ +Procedure ReleaseMysql; +begin + if RefCount> 1 then + Dec(RefCount) + else if UnloadLibrary(MysqlLibraryHandle) then + begin + Dec(RefCount); + MysqlLibraryHandle := NilHandle; + LoadedLibrary:=''; + end; +end; +} + +procedure releasemysql; +begin + releasedynlib(libinfo); +end; + +procedure initializemysql(const sonames: array of filenamety); +const + funcs: array[0..92] of funcinfoty = ( + (n: 'mysql_affected_rows'; d: {$ifndef FPC}@{$endif}@mysql_affected_rows), + (n: 'mysql_autocommit'; d: {$ifndef FPC}@{$endif}@mysql_autocommit), + (n: 'mysql_change_user'; d: {$ifndef FPC}@{$endif}@mysql_change_user), + (n: 'mysql_close'; d: {$ifndef FPC}@{$endif}@mysql_close), + (n: 'mysql_commit'; d: {$ifndef FPC}@{$endif}@mysql_commit), + (n: 'mysql_data_seek'; d: {$ifndef FPC}@{$endif}@mysql_data_seek), + (n: 'mysql_debug'; d: {$ifndef FPC}@{$endif}@mysql_debug), + (n: 'mysql_dump_debug_info'; d: {$ifndef FPC}@{$endif}@mysql_dump_debug_info), + (n: 'mysql_eof'; d: {$ifndef FPC}@{$endif}@mysql_eof), + (n: 'mysql_errno'; d: {$ifndef FPC}@{$endif}@mysql_errno), + (n: 'mysql_error'; d: {$ifndef FPC}@{$endif}@mysql_error), + (n: 'mysql_escape_string'; d: {$ifndef FPC}@{$endif}@mysql_escape_string), + (n: 'mysql_fetch_field'; d: {$ifndef FPC}@{$endif}@mysql_fetch_field), + (n: 'mysql_fetch_field_direct'; d: {$ifndef FPC}@{$endif}@mysql_fetch_field_direct), + (n: 'mysql_fetch_fields'; d: {$ifndef FPC}@{$endif}@mysql_fetch_fields), + (n: 'mysql_fetch_lengths'; d: {$ifndef FPC}@{$endif}@mysql_fetch_lengths), + (n: 'mysql_fetch_row'; d: {$ifndef FPC}@{$endif}@mysql_fetch_row), + (n: 'mysql_field_seek'; d: {$ifndef FPC}@{$endif}@mysql_field_seek), + (n: 'mysql_field_count'; d: {$ifndef FPC}@{$endif}@mysql_field_count), + (n: 'mysql_field_tell'; d: {$ifndef FPC}@{$endif}@mysql_field_tell), + (n: 'mysql_free_result'; d: {$ifndef FPC}@{$endif}@mysql_free_result), + (n: 'mysql_get_client_info'; d: {$ifndef FPC}@{$endif}@mysql_get_client_info), + (n: 'mysql_get_client_version'; d: {$ifndef FPC}@{$endif}@mysql_get_client_version), + (n: 'mysql_get_host_info'; d: {$ifndef FPC}@{$endif}@mysql_get_host_info), + (n: 'mysql_get_server_version'; d: {$ifndef FPC}@{$endif}@mysql_get_server_version), + (n: 'mysql_get_proto_info'; d: {$ifndef FPC}@{$endif}@mysql_get_proto_info), + (n: 'mysql_get_server_info'; d: {$ifndef FPC}@{$endif}@mysql_get_server_info), + (n: 'mysql_info'; d: {$ifndef FPC}@{$endif}@mysql_info), + (n: 'mysql_init'; d: {$ifndef FPC}@{$endif}@mysql_init), + (n: 'mysql_insert_id'; d: {$ifndef FPC}@{$endif}@mysql_insert_id), + (n: 'mysql_kill'; d: {$ifndef FPC}@{$endif}@mysql_kill), + (n: 'mysql_server_end'; d: {$ifndef FPC}@{$endif}@mysql_server_end), + (n: 'mysql_server_init'; d: {$ifndef FPC}@{$endif}@mysql_server_init), + (n: 'mysql_list_dbs'; d: {$ifndef FPC}@{$endif}@mysql_list_dbs), + (n: 'mysql_list_fields'; d: {$ifndef FPC}@{$endif}@mysql_list_fields), + (n: 'mysql_list_processes'; d: {$ifndef FPC}@{$endif}@mysql_list_processes), + (n: 'mysql_list_tables'; d: {$ifndef FPC}@{$endif}@mysql_list_tables), + (n: 'mysql_more_results'; d: {$ifndef FPC}@{$endif}@mysql_more_results), + (n: 'mysql_next_result'; d: {$ifndef FPC}@{$endif}@mysql_next_result), + (n: 'mysql_num_fields'; d: {$ifndef FPC}@{$endif}@mysql_num_fields), + (n: 'mysql_num_rows'; d: {$ifndef FPC}@{$endif}@mysql_num_rows), + (n: 'mysql_options'; d: {$ifndef FPC}@{$endif}@mysql_options), + (n: 'mysql_ping'; d: {$ifndef FPC}@{$endif}@mysql_ping), + (n: 'mysql_query'; d: {$ifndef FPC}@{$endif}@mysql_query), + (n: 'mysql_real_connect'; d: {$ifndef FPC}@{$endif}@mysql_real_connect), + (n: 'mysql_real_escape_string'; d: {$ifndef FPC}@{$endif}@mysql_real_escape_string), + (n: 'mysql_real_query'; d: {$ifndef FPC}@{$endif}@mysql_real_query), + (n: 'mysql_refresh'; d: {$ifndef FPC}@{$endif}@mysql_refresh), + (n: 'mysql_rollback'; d: {$ifndef FPC}@{$endif}@mysql_rollback), + (n: 'mysql_row_seek'; d: {$ifndef FPC}@{$endif}@mysql_row_seek), + (n: 'mysql_row_tell'; d: {$ifndef FPC}@{$endif}@mysql_row_tell), + (n: 'mysql_select_db'; d: {$ifndef FPC}@{$endif}@mysql_select_db), + (n: 'mysql_server_end'; d: {$ifndef FPC}@{$endif}@mysql_server_end), + (n: 'mysql_server_init'; d: {$ifndef FPC}@{$endif}@mysql_server_init), + (n: 'mysql_set_server_option'; d: {$ifndef FPC}@{$endif}@mysql_set_server_option), + (n: 'mysql_sqlstate'; d: {$ifndef FPC}@{$endif}@mysql_sqlstate), + (n: 'mysql_shutdown'; d: {$ifndef FPC}@{$endif}@mysql_shutdown), + (n: 'mysql_stat'; d: {$ifndef FPC}@{$endif}@mysql_stat), + (n: 'mysql_store_result'; d: {$ifndef FPC}@{$endif}@mysql_store_result), + (n: 'mysql_thread_id'; d: {$ifndef FPC}@{$endif}@mysql_thread_id), + (n: 'mysql_use_result'; d: {$ifndef FPC}@{$endif}@mysql_use_result), + (n: 'mysql_warning_count'; d: {$ifndef FPC}@{$endif}@mysql_warning_count), + (n: 'mysql_stmt_init'; d: {$ifndef FPC}@{$endif}@mysql_stmt_init), + (n: 'mysql_stmt_prepare'; d: {$ifndef FPC}@{$endif}@mysql_stmt_prepare), + (n: 'mysql_stmt_execute'; d: {$ifndef FPC}@{$endif}@mysql_stmt_execute), + (n: 'mysql_stmt_fetch'; d: {$ifndef FPC}@{$endif}@mysql_stmt_fetch), + (n: 'mysql_stmt_fetch_column'; d: {$ifndef FPC}@{$endif}@mysql_stmt_fetch_column), + (n: 'mysql_stmt_store_result'; d: {$ifndef FPC}@{$endif}@mysql_stmt_store_result), + (n: 'mysql_stmt_param_count'; d: {$ifndef FPC}@{$endif}@mysql_stmt_param_count), + (n: 'mysql_stmt_attr_set'; d: {$ifndef FPC}@{$endif}@mysql_stmt_attr_set), + (n: 'mysql_stmt_attr_get'; d: {$ifndef FPC}@{$endif}@mysql_stmt_attr_get), + (n: 'mysql_stmt_bind_param'; d: {$ifndef FPC}@{$endif}@mysql_stmt_bind_param), + (n: 'mysql_stmt_bind_result'; d: {$ifndef FPC}@{$endif}@mysql_stmt_bind_result), + (n: 'mysql_stmt_close'; d: {$ifndef FPC}@{$endif}@mysql_stmt_close), + (n: 'mysql_stmt_reset'; d: {$ifndef FPC}@{$endif}@mysql_stmt_reset), + (n: 'mysql_stmt_free_result'; d: {$ifndef FPC}@{$endif}@mysql_stmt_free_result), + (n: 'mysql_stmt_send_long_data'; d: {$ifndef FPC}@{$endif}@mysql_stmt_send_long_data), + (n: 'mysql_stmt_result_metadata'; d: {$ifndef FPC}@{$endif}@mysql_stmt_result_metadata), + (n: 'mysql_stmt_param_metadata'; d: {$ifndef FPC}@{$endif}@mysql_stmt_param_metadata), + (n: 'mysql_stmt_errno'; d: {$ifndef FPC}@{$endif}@mysql_stmt_errno), + (n: 'mysql_stmt_error'; d: {$ifndef FPC}@{$endif}@mysql_stmt_error), + (n: 'mysql_stmt_sqlstate'; d: {$ifndef FPC}@{$endif}@mysql_stmt_sqlstate), + (n: 'mysql_stmt_row_seek'; d: {$ifndef FPC}@{$endif}@mysql_stmt_row_seek), + (n: 'mysql_stmt_row_tell'; d: {$ifndef FPC}@{$endif}@mysql_stmt_row_tell), + (n: 'mysql_stmt_data_seek'; d: {$ifndef FPC}@{$endif}@mysql_stmt_data_seek), + (n: 'mysql_stmt_num_rows'; d: {$ifndef FPC}@{$endif}@mysql_stmt_num_rows), + (n: 'mysql_stmt_affected_rows'; d: {$ifndef FPC}@{$endif}@mysql_stmt_affected_rows), + (n: 'mysql_stmt_insert_id'; d: {$ifndef FPC}@{$endif}@mysql_stmt_insert_id), + (n: 'mysql_stmt_field_count'; d: {$ifndef FPC}@{$endif}@mysql_stmt_field_count), + (n: 'mysql_ssl_set'; d: {$ifndef FPC}@{$endif}@mysql_ssl_set), + (n: 'mysql_character_set_name'; d: {$ifndef FPC}@{$endif}@mysql_character_set_name), + (n: 'mysql_get_character_set_info'; d: {$ifndef FPC}@{$endif}@mysql_get_character_set_info), + (n: 'mysql_set_character_set'; d: {$ifndef FPC}@{$endif}@mysql_set_character_set) + ); + funcsopt: array[0..0] of funcinfoty = ( + (n: 'mysql_get_ssl_cipher'; d: {$ifndef FPC}@{$endif}@mysql_get_ssl_cipher) + ); + errormessage = 'Can not load MySQL library. '; +begin + initializedynlib(libinfo,sonames,mysqllib,funcs,funcsopt,errormessage); +end; + + +{$ENDIF} + +initialization + initializelibinfo(libinfo); +finalization + finalizelibinfo(libinfo); +end. + diff --git a/mseide-msegui/lib/common/db/odbcsqldyn.pas b/mseide-msegui/lib/common/db/odbcsqldyn.pas new file mode 100644 index 0000000..566de7c --- /dev/null +++ b/mseide-msegui/lib/common/db/odbcsqldyn.pas @@ -0,0 +1,1771 @@ +unit odbcsqldyn; +{modified 2010-2012 by Martin Schreiber} + +{$DEFINE DYNLOADINGODBC} + +{$ifdef fpc} +{$mode objfpc} +{$macro on} +{$endif} + +{$h+} + +{$ifdef fpc} + // define ODBC version 3.51 by default +{$define ODBCVER:=$0351} +{$if defined(FPC) and (ODBCVER >= $0300)} + {$define ODBCVER3} +{$ifend} +{$if defined(FPC) and (ODBCVER >= $0350)} + {$define ODBCVER35} +{$ifend} +{$else fpc} + {$define ODBCVER3} + {$define ODBCVER35} +{$endif fpc} + +{$ifndef DYNLOADINGODBC} + {$linklib odbc} +{$endif} + +interface + +uses + msetypes,msestrings, + msectypes, + sysutils; + +{$IFDEF Unix} + {$DEFINE extdecl:=cdecl} +// const +// odbclib = 'libodbc.'+sharedsuffix; +{$ENDIF} +{$IFDEF msWindows} + {$DEFINE extdecl:=stdcall} +// const +// odbclib = 'odbc32.dll'; +{$ENDIF} + + +const +{$ifdef mswindows} + odbclib: array[0..0] of filenamety = ('odbc32.dll'); +{$else} + odbclib: array[0..2] of filenamety = ('libodbc.so.2','libodbc.so.1', + 'libodbc.so'); +{$endif} + +procedure initializeodbc(const sonames: array of filenamety); +procedure releaseodbc; + +(* DATA TYPES CORRESPONDENCE + BDE fields ODBC types + ---------- ------------------ + ftBlob SQL_BINARY + ftBoolean SQL_BIT + ftDate SQL_TYPE_DATE + ftTime SQL_TYPE_TIME + ftDateTime SQL_TYPE_TIMESTAMP + ftInteger SQL_INTEGER + ftSmallint SQL_SMALLINT + ftFloat SQL_DOUBLE + ftString SQL_CHAR + ftMemo SQL_BINARY // SQL_VARCHAR +*) + +type + SQLCHAR = char; + SQLSMALLINT = csshort; + SQLUSMALLINT = cushort; + SQLRETURN = SQLSMALLINT; + SQLHANDLE = pointer; + SQLHENV = SQLHANDLE; + SQLHDBC = SQLHANDLE; + SQLHSTMT = SQLHANDLE; + SQLHDESC = SQLHANDLE; + SQLINTEGER = clong; + SQLUINTEGER = culong; + SQLLEN = ptrint; + SQLULEN = ptruint; + {$ifdef CPU64} + SQLSETPOSIROW = ptruint; + {$else} + SQLSETPOSIROW = SQLUSMALLINT; + {$endif} + SQLPOINTER = pointer; + SQLREAL = cfloat; + SQLDOUBLE = cdouble; + SQLFLOAT = cdouble; + SQLHWND = pointer; + PSQLCHAR = PChar; + PSQLINTEGER = ^SQLINTEGER; + PSQLUINTEGER = ^SQLUINTEGER; + PSQLLEN = ^SQLLEN; + PSQLULEN = ^SQLULEN; + PSQLSMALLINT = ^SQLSMALLINT; + PSQLUSMALLINT = ^SQLUSMALLINT; + PSQLREAL = ^SQLREAL; + PSQLDOUBLE = ^SQLDOUBLE; + PSQLFLOAT = ^SQLFLOAT; + PSQLHANDLE = ^SQLHANDLE; + +const + { SQL data type codes } + SQL_UNKNOWN_TYPE = 0; + SQL_LONGVARCHAR =(-1); + SQL_BINARY =(-2); + SQL_VARBINARY =(-3); + SQL_LONGVARBINARY =(-4); + SQL_BIGINT =(-5); + SQL_TINYINT =(-6); + SQL_BIT =(-7); + SQL_WCHAR =(-8); + SQL_WVARCHAR =(-9); + SQL_WLONGVARCHAR =(-10); + + + SQL_CHAR = 1; + SQL_NUMERIC = 2; + SQL_DECIMAL = 3; + SQL_INTEGER = 4; + SQL_SMALLINT = 5; + SQL_FLOAT = 6; + SQL_REAL = 7; + SQL_DOUBLE = 8; + {$ifdef ODBCVER3} + SQL_DATETIME = 9; + {$endif} + SQL_VARCHAR = 12; + + {$ifdef ODBCVER3} + SQL_TYPE_DATE = 91; + SQL_TYPE_TIME = 92; + SQL_TYPE_TIMESTAMP= 93; + {$endif} + + SQL_DATE = 9; + SQL_TIME = 10; + SQL_TIMESTAMP = 11; + {$ifdef ODBCVER3} + SQL_INTERVAL = 10; + {$endif} + {$ifdef ODBCVER35} + SQL_GUID = -11; + {$endif} + + { interval codes} + {$ifdef ODBCVER3} + SQL_CODE_YEAR = 1; + SQL_CODE_MONTH = 2; + SQL_CODE_DAY = 3; + SQL_CODE_HOUR = 4; + SQL_CODE_MINUTE = 5; + SQL_CODE_SECOND = 6; + SQL_CODE_YEAR_TO_MONTH = 7; + SQL_CODE_DAY_TO_HOUR = 8; + SQL_CODE_DAY_TO_MINUTE = 9; + SQL_CODE_DAY_TO_SECOND = 10; + SQL_CODE_HOUR_TO_MINUTE = 11; + SQL_CODE_HOUR_TO_SECOND = 12; + SQL_CODE_MINUTE_TO_SECOND = 13; + + SQL_INTERVAL_YEAR = 100 + SQL_CODE_YEAR; + SQL_INTERVAL_MONTH = 100 + SQL_CODE_MONTH; + SQL_INTERVAL_DAY = 100 + SQL_CODE_DAY; + SQL_INTERVAL_HOUR = 100 + SQL_CODE_HOUR; + SQL_INTERVAL_MINUTE = 100 + SQL_CODE_MINUTE; + SQL_INTERVAL_SECOND = 100 + SQL_CODE_SECOND; + SQL_INTERVAL_YEAR_TO_MONTH = 100 + SQL_CODE_YEAR_TO_MONTH; + SQL_INTERVAL_DAY_TO_HOUR = 100 + SQL_CODE_DAY_TO_HOUR; + SQL_INTERVAL_DAY_TO_MINUTE = 100 + SQL_CODE_DAY_TO_MINUTE; + SQL_INTERVAL_DAY_TO_SECOND = 100 + SQL_CODE_DAY_TO_SECOND; + SQL_INTERVAL_HOUR_TO_MINUTE = 100 + SQL_CODE_HOUR_TO_MINUTE; + SQL_INTERVAL_HOUR_TO_SECOND = 100 + SQL_CODE_HOUR_TO_SECOND; + SQL_INTERVAL_MINUTE_TO_SECOND = 100 + SQL_CODE_MINUTE_TO_SECOND; + {$else} + SQL_INTERVAL_YEAR = -80; + SQL_INTERVAL_MONTH = -81; + SQL_INTERVAL_YEAR_TO_MONTH = -82; + SQL_INTERVAL_DAY = -83; + SQL_INTERVAL_HOUR = -84; + SQL_INTERVAL_MINUTE = -85; + SQL_INTERVAL_SECOND = -86; + SQL_INTERVAL_DAY_TO_HOUR = -87; + SQL_INTERVAL_DAY_TO_MINUTE = -88; + SQL_INTERVAL_DAY_TO_SECOND = -89; + SQL_INTERVAL_HOUR_TO_MINUTE = -90; + SQL_INTERVAL_HOUR_TO_SECOND = -91; + SQL_INTERVAL_MINUTE_TO_SECOND = -92; + {$endif} + + { Unicode data type codes } + {$ifndef ODBCVER3} + SQL_UNICODE = -95; + SQL_UNICODE_VARCHAR = -96; + SQL_UNICODE_LONGVARCHAR = -97; + SQL_UNICODE_CHAR = SQL_UNICODE; + {$else} + { The previous definitions for SQL_UNICODE_ are historical and obsolete } + SQL_UNICODE = SQL_WCHAR; + SQL_UNICODE_VARCHAR = SQL_WVARCHAR; + SQL_UNICODE_LONGVARCHAR = SQL_WLONGVARCHAR; + SQL_UNICODE_CHAR = SQL_WCHAR; + {$endif} + + { C datatype to SQL datatype mapping } + SQL_C_CHAR = SQL_CHAR; + SQL_C_WCHAR = SQL_WCHAR; + SQL_C_LONG = SQL_INTEGER; + SQL_C_SHORT = SQL_SMALLINT; + SQL_C_FLOAT = SQL_REAL; + SQL_C_DOUBLE = SQL_DOUBLE; +{$ifdef ODBCVER3} + SQL_C_NUMERIC = SQL_NUMERIC; +{$endif} + SQL_C_DEFAULT = 99; + + SQL_SIGNED_OFFSET = -20; + SQL_UNSIGNED_OFFSET = -22; + + SQL_C_DATE = SQL_DATE; + SQL_C_TIME = SQL_TIME; + SQL_C_TIMESTAMP = SQL_TIMESTAMP; +{$ifdef ODBCVER3} + SQL_C_TYPE_DATE = SQL_TYPE_DATE; + SQL_C_TYPE_TIME = SQL_TYPE_TIME; + SQL_C_TYPE_TIMESTAMP = SQL_TYPE_TIMESTAMP; + SQL_C_INTERVAL_YEAR = SQL_INTERVAL_YEAR; + SQL_C_INTERVAL_MONTH = SQL_INTERVAL_MONTH; + SQL_C_INTERVAL_DAY = SQL_INTERVAL_DAY; + SQL_C_INTERVAL_HOUR = SQL_INTERVAL_HOUR; + SQL_C_INTERVAL_MINUTE = SQL_INTERVAL_MINUTE; + SQL_C_INTERVAL_SECOND = SQL_INTERVAL_SECOND; + SQL_C_INTERVAL_YEAR_TO_MONTH = SQL_INTERVAL_YEAR_TO_MONTH; + SQL_C_INTERVAL_DAY_TO_HOUR = SQL_INTERVAL_DAY_TO_HOUR; + SQL_C_INTERVAL_DAY_TO_MINUTE = SQL_INTERVAL_DAY_TO_MINUTE; + SQL_C_INTERVAL_DAY_TO_SECOND = SQL_INTERVAL_DAY_TO_SECOND; + SQL_C_INTERVAL_HOUR_TO_MINUTE = SQL_INTERVAL_HOUR_TO_MINUTE; + SQL_C_INTERVAL_HOUR_TO_SECOND = SQL_INTERVAL_HOUR_TO_SECOND; + SQL_C_INTERVAL_MINUTE_TO_SECOND = SQL_INTERVAL_MINUTE_TO_SECOND; +{$endif} + SQL_C_BINARY = SQL_BINARY; + SQL_C_BIT = SQL_BIT; +{$ifdef ODBCVER3} + SQL_C_SBIGINT = SQL_BIGINT+SQL_SIGNED_OFFSET; // SIGNED BIGINT + SQL_C_UBIGINT = SQL_BIGINT+SQL_UNSIGNED_OFFSET; // UNSIGNED BIGINT +{$endif} + SQL_C_TINYINT = SQL_TINYINT; + SQL_C_SLONG = SQL_C_LONG +SQL_SIGNED_OFFSET; // SIGNED INTEGER + SQL_C_SSHORT = SQL_C_SHORT+SQL_SIGNED_OFFSET; // SIGNED SMALLINT + SQL_C_STINYINT = SQL_TINYINT+SQL_SIGNED_OFFSET; // SIGNED TINYINT + SQL_C_ULONG = SQL_C_LONG +SQL_UNSIGNED_OFFSET; // UNSIGNED INTEGER + SQL_C_USHORT = SQL_C_SHORT+SQL_UNSIGNED_OFFSET; // UNSIGNED SMALLINT + SQL_C_UTINYINT = SQL_TINYINT+SQL_UNSIGNED_OFFSET; // UNSIGNED TINYINT + SQL_C_BOOKMARK = SQL_C_ULONG; // BOOKMARK + +{$ifdef ODBCVER35} + SQL_C_GUID = SQL_GUID; +{$endif} + + SQL_TYPE_NULL = 0; +{$ifndef ODBCVER3} + SQL_TYPE_MIN = SQL_BIT; + SQL_TYPE_MAX = SQL_VARCHAR; +{$endif} + +{$ifdef ODBCVER3} + SQL_C_VARBOOKMARK = SQL_C_BINARY; +{$endif} + + SQL_API_SQLDESCRIBEPARAM=58; + SQL_NO_TOTAL = -4; + +type + SQL_DATE_STRUCT = packed record + Year : SQLSMALLINT; + Month : SQLUSMALLINT; + Day : SQLUSMALLINT; + end; + PSQL_DATE_STRUCT = ^SQL_DATE_STRUCT; + + SQL_TIME_STRUCT = packed record + Hour : SQLUSMALLINT; + Minute : SQLUSMALLINT; + Second : SQLUSMALLINT; + end; + PSQL_TIME_STRUCT = ^SQL_TIME_STRUCT; + + SQL_TIMESTAMP_STRUCT = packed record + Year : SQLUSMALLINT; + Month : SQLUSMALLINT; + Day : SQLUSMALLINT; + Hour : SQLUSMALLINT; + Minute : SQLUSMALLINT; + Second : SQLUSMALLINT; + Fraction : SQLUINTEGER; + end; + PSQL_TIMESTAMP_STRUCT = ^SQL_TIMESTAMP_STRUCT; + +const + SQL_NAME_LEN = 128; + + SQL_OV_ODBC3 = 3; + SQL_OV_ODBC2 = 2; + SQL_ATTR_ODBC_VERSION = 200; + + { Options for SQLDriverConnect } + SQL_DRIVER_NOPROMPT = 0; + SQL_DRIVER_COMPLETE = 1; + SQL_DRIVER_PROMPT = 2; + SQL_DRIVER_COMPLETE_REQUIRED = 3; + + { whether an attribute is a pointer or not } + SQL_IS_POINTER = (-4); + SQL_IS_UINTEGER = (-5); + SQL_IS_INTEGER = (-6); + SQL_IS_USMALLINT = (-7); + SQL_IS_SMALLINT = (-8); + { SQLExtendedFetch "fFetchType" values } + SQL_FETCH_BOOKMARK = 8; + + SQL_SCROLL_OPTIONS = 44; + + { SQL_USE_BOOKMARKS options } + SQL_UB_OFF = 0; + SQL_UB_ON = 1; + SQL_UB_DEFAULT = SQL_UB_OFF; + SQL_UB_FIXED = SQL_UB_ON; + SQL_UB_VARIABLE = 2; + + { SQL_SCROLL_OPTIONS masks } + SQL_SO_FORWARD_ONLY = $01; + SQL_SO_KEYSET_DRIVEN = $02; + SQL_SO_DYNAMIC = $04; + SQL_SO_MIXED = $08; + SQL_SO_STATIC = $10; + + SQL_BOOKMARK_PERSISTENCE = 82; + SQL_STATIC_SENSITIVITY = 83; + + { SQL_BOOKMARK_PERSISTENCE values } + SQL_BP_CLOSE = $01; + SQL_BP_DELETE = $02; + SQL_BP_DROP = $04; + SQL_BP_TRANSACTION = $08; + SQL_BP_UPDATE = $10; + SQL_BP_OTHER_HSTMT = $20; + SQL_BP_SCROLL = $40; + + SQL_DYNAMIC_CURSOR_ATTRIBUTES1 = 144; + SQL_DYNAMIC_CURSOR_ATTRIBUTES2 = 145; + SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1 = 146; + SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2 = 147; + SQL_INDEX_KEYWORDS = 148; + SQL_INFO_SCHEMA_VIEWS = 149; + SQL_KEYSET_CURSOR_ATTRIBUTES1 = 150; + SQL_KEYSET_CURSOR_ATTRIBUTES2 = 151; + SQL_STATIC_CURSOR_ATTRIBUTES1 = 167; + SQL_STATIC_CURSOR_ATTRIBUTES2 = 168; + + { supported SQLFetchScroll FetchOrientation's } + SQL_CA1_NEXT = 1; + SQL_CA1_ABSOLUTE = 2; + SQL_CA1_RELATIVE = 4; + SQL_CA1_BOOKMARK = 8; + + { supported SQLSetPos LockType's } + SQL_CA1_LOCK_NO_CHANGE= $40; + SQL_CA1_LOCK_EXCLUSIVE= $80; + SQL_CA1_LOCK_UNLOCK =$100; + + { supported SQLSetPos Operations } + SQL_CA1_POS_POSITION = $200; + SQL_CA1_POS_UPDATE = $400; + SQL_CA1_POS_DELETE = $800; + SQL_CA1_POS_REFRESH =$1000; + + { positioned updates and deletes } + SQL_CA1_POSITIONED_UPDATE=$2000; + SQL_CA1_POSITIONED_DELETE=$4000; + SQL_CA1_SELECT_FOR_UPDATE=$8000; + + { supported SQLBulkOperations operations } + SQL_CA1_BULK_ADD =$10000; + SQL_CA1_BULK_UPDATE_BY_BOOKMARK =$20000; + SQL_CA1_BULK_DELETE_BY_BOOKMARK =$40000; + SQL_CA1_BULK_FETCH_BY_BOOKMARK =$80000; + + { supported values for SQL_ATTR_SCROLL_CONCURRENCY } + SQL_CA2_READ_ONLY_CONCURRENCY = 1; + SQL_CA2_LOCK_CONCURRENCY = 2; + SQL_CA2_OPT_ROWVER_CONCURRENCY= 4; + SQL_CA2_OPT_VALUES_CONCURRENCY= 8; + + { sensitivity of the cursor to its own inserts, deletes, and updates } + SQL_CA2_SENSITIVITY_ADDITIONS =$10; + SQL_CA2_SENSITIVITY_DELETIONS =$20; + SQL_CA2_SENSITIVITY_UPDATES =$40; + +{ semantics of SQL_ATTR_MAX_ROWS } + SQL_CA2_MAX_ROWS_SELECT = $80; + SQL_CA2_MAX_ROWS_INSERT =$100; + SQL_CA2_MAX_ROWS_DELETE =$200; + SQL_CA2_MAX_ROWS_UPDATE =$400; + SQL_CA2_MAX_ROWS_CATALOG =$800; + SQL_CA2_MAX_ROWS_AFFECTS_ALL =(SQL_CA2_MAX_ROWS_SELECT or + SQL_CA2_MAX_ROWS_INSERT or SQL_CA2_MAX_ROWS_DELETE or + SQL_CA2_MAX_ROWS_UPDATE or SQL_CA2_MAX_ROWS_CATALOG); + + { semantics of SQL_DIAG_CURSOR_ROW_COUNT } + SQL_CA2_CRC_EXACT = $1000; + SQL_CA2_CRC_APPROXIMATE = $2000; + + { the kinds of positioned statements that can be simulated } + SQL_CA2_SIMULATE_NON_UNIQUE = $4000; + SQL_CA2_SIMULATE_TRY_UNIQUE = $8000; + SQL_CA2_SIMULATE_UNIQUE =$10000; + + { Operations in SQLBulkOperations } + SQL_ADD = 4; + SQL_SETPOS_MAX_OPTION_VALUE = SQL_ADD; + SQL_UPDATE_BY_BOOKMARK = 5; + SQL_DELETE_BY_BOOKMARK = 6; + SQL_FETCH_BY_BOOKMARK = 7; + + { Operations in SQLSetPos } + SQL_POSITION = 0; + SQL_REFRESH = 1; + SQL_UPDATE = 2; + SQL_DELETE = 3; + + { Lock options in SQLSetPos } + SQL_LOCK_NO_CHANGE = 0; + SQL_LOCK_EXCLUSIVE = 1; + SQL_LOCK_UNLOCK = 2; + + { SQLExtendedFetch "rgfRowStatus" element values } + SQL_ROW_SUCCESS = 0; + SQL_ROW_DELETED = 1; + SQL_ROW_UPDATED = 2; + SQL_ROW_NOROW = 3; + SQL_ROW_ADDED = 4; + SQL_ROW_ERROR = 5; + SQL_ROW_SUCCESS_WITH_INFO = 6; + + SQL_ROW_PROCEED = 0; + SQL_ROW_IGNORE = 1; + + SQL_MAX_DSN_LENGTH = 32; { maximum data source name size } + + SQL_MAX_OPTION_STRING_LENGTH = 256; + + SQL_ODBC_CURSORS = 110; + SQL_ATTR_ODBC_CURSORS = SQL_ODBC_CURSORS; + { SQL_ODBC_CURSORS options } + SQL_CUR_USE_IF_NEEDED = 0; + SQL_CUR_USE_ODBC = 1; + SQL_CUR_USE_DRIVER = 2; + SQL_CUR_DEFAULT = SQL_CUR_USE_DRIVER; + + SQL_PARAM_TYPE_UNKNOWN = 0; + SQL_PARAM_INPUT = 1; + SQL_PARAM_INPUT_OUTPUT = 2; + SQL_RESULT_COL = 3; + SQL_PARAM_OUTPUT = 4; + SQL_RETURN_VALUE = 5; + + { special length/indicator values } + SQL_NULL_DATA = (-1); + SQL_DATA_AT_EXEC = (-2); + + SQL_SUCCESS = 0; + SQL_SUCCESS_WITH_INFO = 1; + + SQL_NO_DATA = 100; + SQL_ERROR = (-1); + SQL_INVALID_HANDLE = (-2); + + SQL_STILL_EXECUTING = 2; + SQL_NEED_DATA = 99; + { flags for null-terminated string } + SQL_NTS = (-3); + + { maximum message length } + SQL_MAX_MESSAGE_LENGTH = 512; + + { date/time length constants } +{$ifdef ODBCVER3} + SQL_DATE_LEN = 10; + SQL_TIME_LEN = 8; { add P+1 if precision is nonzero } + SQL_TIMESTAMP_LEN = 19; { add P+1 if precision is nonzero } +{$endif} + + { handle type identifiers } + SQL_HANDLE_ENV = 1; + SQL_HANDLE_DBC = 2; + SQL_HANDLE_STMT = 3; + SQL_HANDLE_DESC = 4; + +{$ifdef ODBCVER3} + { environment attribute } + SQL_ATTR_OUTPUT_NTS = 10001; + { connection attributes } + SQL_ATTR_AUTO_IPD = 10001; + SQL_ATTR_METADATA_ID = 10014; +{$endif} { ODBCVER >= 0x0300 } + + { statement attributes } + SQL_ATTR_APP_ROW_DESC = 10010; + SQL_ATTR_APP_PARAM_DESC = 10011; + SQL_ATTR_IMP_ROW_DESC = 10012; + SQL_ATTR_IMP_PARAM_DESC = 10013; + SQL_ATTR_CURSOR_SCROLLABLE = (-1); + SQL_ATTR_CURSOR_SENSITIVITY = (-2); + SQL_QUERY_TIMEOUT =0; + SQL_MAX_ROWS =1; + SQL_NOSCAN =2; + SQL_MAX_LENGTH =3; + SQL_ASYNC_ENABLE =4; // same as SQL_ATTR_ASYNC_ENABLE */ + SQL_BIND_TYPE =5; + SQL_CURSOR_TYPE = 6; + SQL_CONCURRENCY = 7; + SQL_KEYSET_SIZE =8; + SQL_ROWSET_SIZE =9; + SQL_SIMULATE_CURSOR =10; + SQL_RETRIEVE_DATA =11; + SQL_USE_BOOKMARKS =12; + SQL_GET_BOOKMARK =13; // GetStmtOption Only */ + SQL_ROW_NUMBER = 14; // GetStmtOption Only */ + + SQL_ATTR_CURSOR_TYPE = SQL_CURSOR_TYPE; + SQL_ATTR_CONCURRENCY = SQL_CONCURRENCY; + SQL_ATTR_FETCH_BOOKMARK_PTR = 16; + SQL_ATTR_ROW_STATUS_PTR = 25; + SQL_ATTR_ROWS_FETCHED_PTR = 26; + SQL_AUTOCOMMIT = 102; + SQL_ATTR_AUTOCOMMIT = SQL_AUTOCOMMIT; + + SQL_ATTR_ROW_NUMBER = SQL_ROW_NUMBER; + SQL_TXN_ISOLATION = 108; + SQL_ATTR_TXN_ISOLATION = SQL_TXN_ISOLATION; + SQL_ATTR_MAX_ROWS = SQL_MAX_ROWS; + SQL_ATTR_USE_BOOKMARKS = SQL_USE_BOOKMARKS; + +//* connection attributes */ + SQL_ACCESS_MODE =101; +// SQL_AUTOCOMMIT =102; + SQL_LOGIN_TIMEOUT =103; + SQL_OPT_TRACE =104; + SQL_OPT_TRACEFILE =105; + SQL_TRANSLATE_DLL =106; + SQL_TRANSLATE_OPTION =107; +// SQL_TXN_ISOLATION =108; + SQL_CURRENT_QUALIFIER =109; +// SQL_ODBC_CURSORS =110; + SQL_QUIET_MODE =111; + SQL_PACKET_SIZE =112; + + +//* connection attributes with new names */ + SQL_ATTR_ACCESS_MODE =SQL_ACCESS_MODE; +// SQL_ATTR_AUTOCOMMIT =SQL_AUTOCOMMIT; + SQL_ATTR_CONNECTION_DEAD =1209; //* GetConnectAttr only */ + SQL_ATTR_CONNECTION_TIMEOUT =113; + SQL_ATTR_CURRENT_CATALOG =SQL_CURRENT_QUALIFIER; + SQL_ATTR_DISCONNECT_BEHAVIOR=114; + SQL_ATTR_ENLIST_IN_DTC =1207; + SQL_ATTR_ENLIST_IN_XA =1208; + SQL_ATTR_LOGIN_TIMEOUT =SQL_LOGIN_TIMEOUT; +// SQL_ATTR_ODBC_CURSORS =SQL_ODBC_CURSORS; + SQL_ATTR_PACKET_SIZE =SQL_PACKET_SIZE; + SQL_ATTR_QUIET_MODE =SQL_QUIET_MODE; + SQL_ATTR_TRACE =SQL_OPT_TRACE; + SQL_ATTR_TRACEFILE =SQL_OPT_TRACEFILE; + SQL_ATTR_TRANSLATE_LIB =SQL_TRANSLATE_DLL; + SQL_ATTR_TRANSLATE_OPTION =SQL_TRANSLATE_OPTION; +// SQL_ATTR_TXN_ISOLATION =SQL_TXN_ISOLATION; + +//* SQL_ACCESS_MODE options */ + SQL_MODE_READ_WRITE =0; + SQL_MODE_READ_ONLY =1; + SQL_MODE_DEFAULT =SQL_MODE_READ_WRITE; + + //* SQL_AUTOCOMMIT options */ + SQL_AUTOCOMMIT_OFF = 0; + SQL_AUTOCOMMIT_ON = 1; + SQL_AUTOCOMMIT_DEFAULT = SQL_AUTOCOMMIT_ON; + { SQL_ATTR_CURSOR_SCROLLABLE values } + SQL_NONSCROLLABLE = 0; + SQL_SCROLLABLE = 1; + { SQL_CURSOR_TYPE options } + SQL_CURSOR_FORWARD_ONLY = 0; + SQL_CURSOR_KEYSET_DRIVEN = 1; + SQL_CURSOR_DYNAMIC = 2; + SQL_CURSOR_STATIC = 3; + SQL_CURSOR_TYPE_DEFAULT = SQL_CURSOR_FORWARD_ONLY;{ Default value } + + { SQL_CONCURRENCY options } + SQL_CONCUR_READ_ONLY = 1; + SQL_CONCUR_LOCK = 2; + SQL_CONCUR_ROWVER = 3; + SQL_CONCUR_VALUES = 4; + SQL_CONCUR_DEFAULT = SQL_CONCUR_READ_ONLY; { Default value } + + { identifiers of fields in the SQL descriptor } + {$ifdef ODBCVER3} + SQL_DESC_COUNT = 1001; + SQL_DESC_TYPE = 1002; + SQL_DESC_LENGTH = 1003; + SQL_DESC_OCTET_LENGTH_PTR = 1004; + SQL_DESC_PRECISION = 1005; + SQL_DESC_SCALE = 1006; + SQL_DESC_DATETIME_INTERVAL_CODE = 1007; + SQL_DESC_NULLABLE = 1008; + SQL_DESC_INDICATOR_PTR = 1009; + SQL_DESC_DATA_PTR = 1010; + SQL_DESC_NAME = 1011; + SQL_DESC_UNNAMED = 1012; + SQL_DESC_OCTET_LENGTH = 1013; + SQL_DESC_ALLOC_TYPE = 1099; + {$endif} + + { identifiers of fields in the diagnostics area } +{$ifdef ODBCVER3} + SQL_DIAG_RETURNCODE = 1; + SQL_DIAG_NUMBER = 2; + SQL_DIAG_ROW_COUNT = 3; + SQL_DIAG_SQLSTATE = 4; + SQL_DIAG_NATIVE = 5; + SQL_DIAG_MESSAGE_TEXT = 6; + SQL_DIAG_DYNAMIC_FUNCTION = 7; + SQL_DIAG_CLASS_ORIGIN = 8; + SQL_DIAG_SUBCLASS_ORIGIN = 9; + SQL_DIAG_CONNECTION_NAME = 10; + SQL_DIAG_SERVER_NAME = 11; + SQL_DIAG_DYNAMIC_FUNCTION_CODE = 12; +{$endif} + + { dynamic function codes } +{$ifdef ODBCVER3} + SQL_DIAG_ALTER_TABLE = 4; + SQL_DIAG_CREATE_INDEX = (-1); + SQL_DIAG_CREATE_TABLE = 77; + SQL_DIAG_CREATE_VIEW = 84; + SQL_DIAG_DELETE_WHERE = 19; + SQL_DIAG_DROP_INDEX = (-2); + SQL_DIAG_DROP_TABLE = 32; + SQL_DIAG_DROP_VIEW = 36; + SQL_DIAG_DYNAMIC_DELETE_CURSOR = 38; + SQL_DIAG_DYNAMIC_UPDATE_CURSOR = 81; + SQL_DIAG_GRANT = 48; + SQL_DIAG_INSERT = 50; + SQL_DIAG_REVOKE = 59; + SQL_DIAG_SELECT_CURSOR = 85; + SQL_DIAG_UNKNOWN_STATEMENT = 0; + SQL_DIAG_UPDATE_WHERE = 82; + SQL_DIAG_CURSOR_ROW_COUNT = -1249; +{$endif} { ODBCVER >= 0x0300 } + + { Statement attribute values for cursor sensitivity } +{$ifdef ODBCVER3} + SQL_UNSPECIFIED = 0; + SQL_INSENSITIVE = 1; + SQL_SENSITIVE = 2; +{$endif} + + { GetTypeInfo() request for all data types } + SQL_ALL_TYPES = 0; + + { Default conversion code for SQLBindCol(), SQLBindParam() and SQLGetData() } +{$ifdef ODBCVER3} + SQL_DEFAULT = 99; +{$endif} + + { SQLGetData() code indicating that the application row descriptor + specifies the data type } +{$ifdef ODBCVER3} + SQL_ARD_TYPE = (-99); +{$endif} + + { SQL date/time type subcodes } +{$ifdef ODBCVER3} + SQL_CODE_DATE = 1; + SQL_CODE_TIME = 2; + SQL_CODE_TIMESTAMP = 3; +{$endif} + + { CLI option values } +{$ifdef ODBCVER3} + SQL_FALSE = 0; + SQL_TRUE = 1; +{$endif} + + { values of NULLABLE field in descriptor } + SQL_NO_NULLS = 0; + SQL_NULLABLE = 1; + +{ Value returned by SQLGetTypeInfo() to denote that it is + not known whether or not a data type supports null values. } + + SQL_NULLABLE_UNKNOWN = 2; +{ +/* Values returned by SQLGetTypeInfo() to show WHERE clause + * supported + +#if (ODBCVER >= 0x0300) +#define SQL_PRED_NONE 0 +#define SQL_PRED_CHAR 1 +#define SQL_PRED_BASIC 2 +#endif + +/* values of UNNAMED field in descriptor */ +#if (ODBCVER >= 0x0300) +#define SQL_NAMED 0 +#define SQL_UNNAMED 1 +#endif + +/* values of ALLOC_TYPE field in descriptor */ +#if (ODBCVER >= 0x0300) +#define SQL_DESC_ALLOC_AUTO 1 +#define SQL_DESC_ALLOC_USER 2 +#endif +} + { FreeStmt() options } + SQL_CLOSE = 0; + SQL_DROP = 1; + SQL_UNBIND = 2; + SQL_RESET_PARAMS = 3; + + { Codes used for FetchOrientation in SQLFetchScroll(), + and in SQLDataSources() } + SQL_FETCH_NEXT = 1; + SQL_FETCH_FIRST = 2; +{$ifdef odbcver3} + SQL_FETCH_FIRST_USER = 31; + SQL_FETCH_FIRST_SYSTEM = 32; +{$endif} + + { Other codes used for FetchOrientation in SQLFetchScroll() } + SQL_FETCH_LAST = 3; + SQL_FETCH_PRIOR = 4; + SQL_FETCH_ABSOLUTE = 5; + SQL_FETCH_RELATIVE = 6; +{ +/* SQLEndTran() options */ +#define SQL_COMMIT 0 +#define SQL_ROLLBACK 1} + +//* null handles returned by SQLAllocHandle() */ + SQL_NULL_HENV = SQLHENV(0); + SQL_NULL_HDBC = SQLHDBC(0); + SQL_NULL_HSTMT = SQLHSTMT(0); +{$ifdef odbcver3} + SQL_NULL_HDESC = SQLHDESC(0); +{$endif} + +//* null handle used in place of parent handle when allocating HENV */ + SQL_NULL_HANDLE = SQLHANDLE(0); + +//* Values that may appear in the result set of SQLSpecialColumns() */ + SQL_SCOPE_CURROW = 0; + SQL_SCOPE_TRANSACTION = 1; + SQL_SCOPE_SESSION = 2; + +//* Column types and scopes in SQLSpecialColumns. */ + SQL_BEST_ROWID = 1; + SQL_ROWVER = 2; + +{ +#define SQL_PC_UNKNOWN 0 +#if (ODBCVER >= 0x0300) +#define SQL_PC_NON_PSEUDO 1 +#endif +#define SQL_PC_PSEUDO 2 +} + +//* Reserved value for the IdentifierType argument of SQLSpecialColumns() */ +{$ifdef ODBCVER3} + SQL_ROW_IDENTIFIER = 1; +{$endif} + +//* Reserved values for UNIQUE argument of SQLStatistics() */ + SQL_INDEX_UNIQUE = 0; + SQL_INDEX_ALL = 1; + +//* Reserved values for RESERVED argument of SQLStatistics() */ + SQL_QUICK = 0; + SQL_ENSURE = 1; + +//* Values that may appear in the result set of SQLStatistics() */ + SQL_TABLE_STAT = 0; + SQL_INDEX_CLUSTERED = 1; + SQL_INDEX_HASHED = 2; + SQL_INDEX_OTHER = 3; +// SQL_INDEX_BTREE = ???; +// SQL_INDEX_CONTENT = ???; + +{ +/* Information requested by SQLGetInfo() */ +#if (ODBCVER >= 0x0300) +#define SQL_MAX_DRIVER_CONNECTIONS 0 +#define SQL_MAXIMUM_DRIVER_CONNECTIONS SQL_MAX_DRIVER_CONNECTIONS +#define SQL_MAX_CONCURRENT_ACTIVITIES 1 +#define SQL_MAXIMUM_CONCURRENT_ACTIVITIES SQL_MAX_CONCURRENT_ACTIVITIES +#endif +#define SQL_DATA_SOURCE_NAME 2 +#define SQL_FETCH_DIRECTION 8 +#define SQL_SERVER_NAME 13 +#define SQL_SEARCH_PATTERN_ESCAPE 14 +#define SQL_DBMS_NAME 17 +#define SQL_DBMS_VER 18 +#define SQL_ACCESSIBLE_TABLES 19 +#define SQL_ACCESSIBLE_PROCEDURES 20 +#define SQL_CURSOR_COMMIT_BEHAVIOR 23 +#define SQL_DATA_SOURCE_READ_ONLY 25 +#define SQL_DEFAULT_TXN_ISOLATION 26 +#define SQL_IDENTIFIER_CASE 28 +#define SQL_IDENTIFIER_QUOTE_CHAR 29 +#define SQL_MAX_COLUMN_NAME_LEN 30 +#define SQL_MAXIMUM_COLUMN_NAME_LENGTH SQL_MAX_COLUMN_NAME_LEN +#define SQL_MAX_CURSOR_NAME_LEN 31 +#define SQL_MAXIMUM_CURSOR_NAME_LENGTH SQL_MAX_CURSOR_NAME_LEN +#define SQL_MAX_SCHEMA_NAME_LEN 32 +#define SQL_MAXIMUM_SCHEMA_NAME_LENGTH SQL_MAX_SCHEMA_NAME_LEN +#define SQL_MAX_CATALOG_NAME_LEN 34 +#define SQL_MAXIMUM_CATALOG_NAME_LENGTH SQL_MAX_CATALOG_NAME_LEN +#define SQL_MAX_TABLE_NAME_LEN 35 +} + SQL_SCROLL_CONCURRENCY = 43; + SQL_TXN_CAPABLE = 46; + SQL_TRANSACTION_CAPABLE = SQL_TXN_CAPABLE; + SQL_USER_NAME = 47; + SQL_TXN_ISOLATION_OPTION = 72; + SQL_TRANSACTION_ISOLATION_OPTION = SQL_TXN_ISOLATION_OPTION; +{ +#define SQL_INTEGRITY 73 +#define SQL_GETDATA_EXTENSIONS 81 +#define SQL_NULL_COLLATION 85 +#define SQL_ALTER_TABLE 86 +#define SQL_ORDER_BY_COLUMNS_IN_SELECT 90 +#define SQL_SPECIAL_CHARACTERS 94 +#define SQL_MAX_COLUMNS_IN_GROUP_BY 97 +#define SQL_MAXIMUM_COLUMNS_IN_GROUP_BY SQL_MAX_COLUMNS_IN_GROUP_BY +#define SQL_MAX_COLUMNS_IN_INDEX 98 +#define SQL_MAXIMUM_COLUMNS_IN_INDEX SQL_MAX_COLUMNS_IN_INDEX +#define SQL_MAX_COLUMNS_IN_ORDER_BY 99 +#define SQL_MAXIMUM_COLUMNS_IN_ORDER_BY SQL_MAX_COLUMNS_IN_ORDER_BY +#define SQL_MAX_COLUMNS_IN_SELECT 100 +#define SQL_MAXIMUM_COLUMNS_IN_SELECT SQL_MAX_COLUMNS_IN_SELECT +#define SQL_MAX_COLUMNS_IN_TABLE 101 +#define SQL_MAX_INDEX_SIZE 102 +#define SQL_MAXIMUM_INDEX_SIZE SQL_MAX_INDEX_SIZE +#define SQL_MAX_ROW_SIZE 104 +#define SQL_MAXIMUM_ROW_SIZE SQL_MAX_ROW_SIZE +#define SQL_MAX_STATEMENT_LEN 105 +#define SQL_MAXIMUM_STATEMENT_LENGTH SQL_MAX_STATEMENT_LEN +#define SQL_MAX_TABLES_IN_SELECT 106 +#define SQL_MAXIMUM_TABLES_IN_SELECT SQL_MAX_TABLES_IN_SELECT +#define SQL_MAX_USER_NAME_LEN 107 +#define SQL_MAXIMUM_USER_NAME_LENGTH SQL_MAX_USER_NAME_LEN} +{$ifdef ODBCVER3} + SQL_OJ_CAPABILITIES = 115; + SQL_OUTER_JOIN_CAPABILITIES = SQL_OJ_CAPABILITIES; +{$endif} { ODBCVER >= 0x0300 } + +{$ifdef ODBCVER3} + SQL_XOPEN_CLI_YEAR = 10000; + SQL_CURSOR_SENSITIVITY = 10001; + SQL_DESCRIBE_PARAMETER = 10002; + SQL_CATALOG_NAME = 10003; + SQL_COLLATION_SEQ = 10004; + SQL_MAX_IDENTIFIER_LEN = 10005; + SQL_MAXIMUM_IDENTIFIER_LENGTH = SQL_MAX_IDENTIFIER_LEN; +{$endif} { ODBCVER >= 0x0300 } + +{/* SQL_ALTER_TABLE bitmasks */ +#if (ODBCVER >= 0x0200) +#define SQL_AT_ADD_COLUMN 0x00000001L +#define SQL_AT_DROP_COLUMN 0x00000002L +#endif /* ODBCVER >= 0x0200 */ + +#if (ODBCVER >= 0x0300) +#define SQL_AT_ADD_CONSTRAINT 0x00000008L + +/* The following bitmasks are ODBC extensions and defined in sqlext.h +*#define SQL_AT_COLUMN_SINGLE 0x00000020L +*#define SQL_AT_ADD_COLUMN_DEFAULT 0x00000040L +*#define SQL_AT_ADD_COLUMN_COLLATION 0x00000080L +*#define SQL_AT_SET_COLUMN_DEFAULT 0x00000100L +*#define SQL_AT_DROP_COLUMN_DEFAULT 0x00000200L +*#define SQL_AT_DROP_COLUMN_CASCADE 0x00000400L +*#define SQL_AT_DROP_COLUMN_RESTRICT 0x00000800L +*#define SQL_AT_ADD_TABLE_CONSTRAINT 0x00001000L +*#define SQL_AT_DROP_TABLE_CONSTRAINT_CASCADE 0x00002000L +*#define SQL_AT_DROP_TABLE_CONSTRAINT_RESTRICT 0x00004000L +*#define SQL_AT_CONSTRAINT_NAME_DEFINITION 0x00008000L +*#define SQL_AT_CONSTRAINT_INITIALLY_DEFERRED 0x00010000L +*#define SQL_AT_CONSTRAINT_INITIALLY_IMMEDIATE 0x00020000L +*#define SQL_AT_CONSTRAINT_DEFERRABLE 0x00040000L +*#define SQL_AT_CONSTRAINT_NON_DEFERRABLE 0x00080000L + +#endif /* ODBCVER >= 0x0300 */ + + +/* SQL_ASYNC_MODE values */ +#if (ODBCVER >= 0x0300) +#define SQL_AM_NONE 0 +#define SQL_AM_CONNECTION 1 +#define SQL_AM_STATEMENT 2 +#endif + +/* SQL_CURSOR_COMMIT_BEHAVIOR values */ +#define SQL_CB_DELETE 0 +#define SQL_CB_CLOSE 1 +#define SQL_CB_PRESERVE 2 + +/* SQL_FETCH_DIRECTION bitmasks */ +#define SQL_FD_FETCH_NEXT 0x00000001L +#define SQL_FD_FETCH_FIRST 0x00000002L +#define SQL_FD_FETCH_LAST 0x00000004L +#define SQL_FD_FETCH_PRIOR 0x00000008L +#define SQL_FD_FETCH_ABSOLUTE 0x00000010L +#define SQL_FD_FETCH_RELATIVE 0x00000020L + +/* SQL_GETDATA_EXTENSIONS bitmasks */ +#define SQL_GD_ANY_COLUMN 0x00000001L +#define SQL_GD_ANY_ORDER 0x00000002L + +/* SQL_IDENTIFIER_CASE values */ +#define SQL_IC_UPPER 1 +#define SQL_IC_LOWER 2 +#define SQL_IC_SENSITIVE 3 +#define SQL_IC_MIXED 4 + +/* SQL_OJ_CAPABILITIES bitmasks */ +/* NB: this means 'outer join', not what you may be thinking */ + + +#if (ODBCVER >= 0x0201) +#define SQL_OJ_LEFT 0x00000001L +#define SQL_OJ_RIGHT 0x00000002L +#define SQL_OJ_FULL 0x00000004L +#define SQL_OJ_NESTED 0x00000008L +#define SQL_OJ_NOT_ORDERED 0x00000010L +#define SQL_OJ_INNER 0x00000020L +#define SQL_OJ_ALL_COMPARISON_OPS 0x00000040L +#endif +} +{ SQL_SCROLL_CONCURRENCY bitmasks } + SQL_SCCO_READ_ONLY = 1; + SQL_SCCO_LOCK = 2; + SQL_SCCO_OPT_ROWVER = 4; + SQL_SCCO_OPT_VALUES = 8; + +//* SQL_TXN_CAPABLE values */ + SQL_TC_NONE = 0; + SQL_TC_DML = 1; + SQL_TC_ALL = 2; + SQL_TC_DDL_COMMIT = 3; + SQL_TC_DDL_IGNORE = 4; + +//* SQL_TXN_ISOLATION_OPTION bitmasks */ + SQL_TXN_READ_UNCOMMITTED = 1; + SQL_TRANSACTION_READ_UNCOMMITTED = SQL_TXN_READ_UNCOMMITTED; + SQL_TXN_READ_COMMITTED = 2; + SQL_TRANSACTION_READ_COMMITTED = SQL_TXN_READ_COMMITTED; + SQL_TXN_REPEATABLE_READ = 4; + SQL_TRANSACTION_REPEATABLE_READ = SQL_TXN_REPEATABLE_READ; + SQL_TXN_SERIALIZABLE = 8; + SQL_TRANSACTION_SERIALIZABLE = SQL_TXN_SERIALIZABLE; +{ +/* SQL_NULL_COLLATION values */ +#define SQL_NC_HIGH 0 +#define SQL_NC_LOW 1 + +} + +{ SQL_STATIC_SENSITIVITY values } + + SQL_SS_ADDITIONS = 1; + SQL_SS_DELETIONS = 2; + SQL_SS_UPDATES = 4; + +{ SQLColAttributes defines } + SQL_COLUMN_COUNT = 0; + SQL_COLUMN_NAME = 1; + SQL_COLUMN_TYPE = 2; + SQL_COLUMN_LENGTH = 3; + SQL_COLUMN_PRECISION = 4; + SQL_COLUMN_SCALE = 5; + SQL_COLUMN_DISPLAY_SIZE = 6; + SQL_COLUMN_NULLABLE = 7; + SQL_COLUMN_UNSIGNED = 8; + SQL_COLUMN_MONEY = 9; + SQL_COLUMN_UPDATABLE = 10; + SQL_COLUMN_AUTO_INCREMENT = 11; + SQL_COLUMN_CASE_SENSITIVE = 12; + SQL_COLUMN_SEARCHABLE = 13; + SQL_COLUMN_TYPE_NAME = 14; + SQL_COLUMN_TABLE_NAME = 15; + SQL_COLUMN_OWNER_NAME = 16; + SQL_COLUMN_QUALIFIER_NAME = 17; + SQL_COLUMN_LABEL = 18; + SQL_COLATT_OPT_MAX = SQL_COLUMN_LABEL; +{$ifdef ODBCVER3} + SQL_COLUMN_DRIVER_START = 1000; +{$endif} { ODBCVER >= 0x0300 } + + { SQLColAttribute defines } +{$ifdef ODBCVER3} + SQL_DESC_ARRAY_SIZE = 20; + SQL_DESC_ARRAY_STATUS_PTR = 21; + SQL_DESC_AUTO_UNIQUE_VALUE = SQL_COLUMN_AUTO_INCREMENT; + SQL_DESC_BASE_COLUMN_NAME = 22; + SQL_DESC_BASE_TABLE_NAME = 23; + SQL_DESC_BIND_OFFSET_PTR = 24; + SQL_DESC_BIND_TYPE = 25; + SQL_DESC_CASE_SENSITIVE = SQL_COLUMN_CASE_SENSITIVE; + SQL_DESC_CATALOG_NAME = SQL_COLUMN_QUALIFIER_NAME; + SQL_DESC_CONCISE_TYPE = SQL_COLUMN_TYPE; + SQL_DESC_DATETIME_INTERVAL_PRECISION = 26; + SQL_DESC_DISPLAY_SIZE = SQL_COLUMN_DISPLAY_SIZE; + SQL_DESC_FIXED_PREC_SCALE = SQL_COLUMN_MONEY; + SQL_DESC_LABEL = SQL_COLUMN_LABEL; + SQL_DESC_LITERAL_PREFIX = 27; + SQL_DESC_LITERAL_SUFFIX = 28; + SQL_DESC_LOCAL_TYPE_NAME = 29; + SQL_DESC_MAXIMUM_SCALE = 30; + SQL_DESC_MINIMUM_SCALE = 31; + SQL_DESC_NUM_PREC_RADIX = 32; + SQL_DESC_PARAMETER_TYPE = 33; + SQL_DESC_ROWS_PROCESSED_PTR = 34; + SQL_DESC_SCHEMA_NAME = SQL_COLUMN_OWNER_NAME; + SQL_DESC_SEARCHABLE = SQL_COLUMN_SEARCHABLE; + SQL_DESC_TYPE_NAME = SQL_COLUMN_TYPE_NAME; + SQL_DESC_TABLE_NAME = SQL_COLUMN_TABLE_NAME; + SQL_DESC_UNSIGNED = SQL_COLUMN_UNSIGNED; + SQL_DESC_UPDATABLE = SQL_COLUMN_UPDATABLE; +{$endif} + +//* SQLEndTran() options */ + SQL_COMMIT = 0; + SQL_ROLLBACK = 1; + + SQL_ATTR_ROW_ARRAY_SIZE = 27; + +//* SQLConfigDataSource() options */ + ODBC_ADD_DSN = 1; + ODBC_CONFIG_DSN = 2; + ODBC_REMOVE_DSN = 3; + ODBC_ADD_SYS_DSN = 4; + ODBC_CONFIG_SYS_DSN = 5; + ODBC_REMOVE_SYS_DSN = 6; + +{$ifdef DYNLOADINGODBC} +var + SQLAllocHandle: function(HandleType: SQLSMALLINT; + InputHandle:SQLHANDLE; Var OutputHandlePtr: SQLHANDLE): SQLRETURN; + {$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLSetEnvAttr: function (EnvironmentHandle:SQLHENV; + Attribute:SQLINTEGER;Value:SQLPOINTER; + StringLength:SQLINTEGER):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLFreeHandle: function (HandleType:SQLSMALLINT; + Handle:SQLHANDLE):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLGetDiagRec: function (HandleType:SQLSMALLINT; + Handle:SQLHANDLE;RecNumber:SQLSMALLINT; + Sqlstate:PSQLCHAR;var NativeError:SQLINTEGER; + MessageText:PSQLCHAR;BufferLength:SQLSMALLINT; + var TextLength:SQLSMALLINT ):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLGetDiagField: function (HandleType:SQLSMALLINT; + Handle:SQLHANDLE;RecNumber:SQLSMALLINT; + DiagIdentifier:SQLSMALLINT;DiagInfoPtr:SQLPOINTER; + BufferLength:SQLSMALLINT;var StringLengthPtr:SQLSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLConnect: function (ConnectionHandle:SQLHDBC; + ServerName:PSQLCHAR;NameLength1:SQLSMALLINT; + UserName:PSQLCHAR;NameLength2:SQLSMALLINT; + Authentication:PSQLCHAR;NameLength3:SQLSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLDisconnect: function(ConnectionHandle:SQLHDBC):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLDriverConnect: function (hdbc: SQLHDBC; + hwnd: SQLHWND;szCsin: PChar; + szCLen: SQLSMALLINT;szCsout: PChar; + cbCSMax: SQLSMALLINT;Var cbCsOut: SQLSMALLINT; + f: SQLUSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLExecDirect: function (StatementHandle:SQLHSTMT; + StatementText:PSQLCHAR;TextLength:SQLINTEGER):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLPrepare: function (StatementHandle:SQLHSTMT; + StatementText:PSQLCHAR;TextLength:SQLINTEGER):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLCloseCursor: function (StatementHandle:SQLHSTMT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLExecute: function (StatementHandle:SQLHSTMT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLFetch: function (StatementHandle:SQLHSTMT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLNumResultCols: function (StatementHandle:SQLHSTMT; + var ColumnCount:SQLSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLDescribeCol: function (StatementHandle:SQLHSTMT; + ColumnNumber:SQLUSMALLINT;ColumnName:PSQLCHAR; + BufferLength:SQLSMALLINT;var NameLength:SQLSMALLINT; + var DataType:SQLSMALLINT;var ColumnSize:SQLULEN; + var DecimalDigits:SQLSMALLINT;var Nullable:SQLSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLFetchScroll: function (StatementHandle:SQLHSTMT; + FetchOrientation:SQLSMALLINT;FetchOffset:SQLLEN):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLExtendedFetch: function (hstmt:SQLHSTMT; + fFetchType:SQLUSMALLINT;irow:SQLLEN; + pcrow:PSQLULEN;rgfRowStatus:PSQLUSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLGetData: function (StatementHandle:SQLHSTMT; + ColumnNumber:SQLUSMALLINT;TargetType:SQLSMALLINT; + TargetValue:SQLPOINTER;BufferLength:SQLLEN; + StrLen_or_Ind:PSQLLEN):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLSetStmtAttr: function (StatementHandle:SQLHSTMT; + Attribute:SQLINTEGER;Value:SQLPOINTER; + StringLength:SQLINTEGER):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLGetStmtAttr: function (StatementHandle:SQLHSTMT; + Attribute:SQLINTEGER;Value:SQLPOINTER; + BufferLength:SQLINTEGER;StringLength:PSQLINTEGER):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLGetInfo: function (ConnectionHandle:SQLHDBC; + InfoType:SQLUSMALLINT;InfoValue:SQLPOINTER; + BufferLength:SQLSMALLINT;StringLength:PSQLSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLBulkOperations: function (StatementHandle: SQLHSTMT; + Operation:SQLSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLPutData: function (StatementHandle:SQLHSTMT; + Data:SQLPOINTER;StrLen_or_Ind:SQLLEN):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLBindCol: function (StatementHandle:SQLHSTMT; + ColumnNumber:SQLUSMALLINT;TargetType:SQLSMALLINT; + TargetValue:SQLPOINTER;BufferLength:SQLLEN; + StrLen_or_Ind:PSQLLEN):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLSetPos: function (hstmt:SQLHSTMT; + irow:SQLSETPOSIROW;fOption:SQLUSMALLINT; + fLock:SQLUSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLDataSources: function (EnvironmentHandle:SQLHENV; + Direction:SQLUSMALLINT;ServerName:PSQLCHAR; + BufferLength1:SQLSMALLINT;NameLength1:PSQLSMALLINT; + Description:PSQLCHAR;BufferLength2:SQLSMALLINT; + NameLength2:PSQLSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLDrivers: function (EnvironmentHandle:SQLHENV; + Direction:SQLUSMALLINT;DriverDescription:PSQLCHAR; + BufferLength1:SQLSMALLINT;DescriptionLength1:PSQLSMALLINT; + DriverAttributes:PSQLCHAR;BufferLength2:SQLSMALLINT; + AttributesLength2:PSQLSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLSetConnectAttr: function (ConnectionHandle:SQLHDBC; + Attribute:SQLINTEGER; Value:SQLPOINTER; + StringLength:SQLINTEGER):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLGetCursorName: function (StatementHandle:SQLHSTMT; + CursorName:PSQLCHAR; BufferLength:SQLSMALLINT; + NameLength:PSQLSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLSetCursorName: function (StatementHandle:SQLHSTMT; + CursorName:PSQLCHAR; NameLength:SQLSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLRowCount: function (StatementHandle:SQLHSTMT; + Var RowCount:SQLLEN):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLBindParameter: function (hstmt:SQLHSTMT; + ipar:SQLUSMALLINT;fParamType:SQLSMALLINT; + fCType:SQLSMALLINT;fSqlType:SQLSMALLINT; + cbColDef:SQLULEN;ibScale:SQLSMALLINT; + rgbValue:SQLPOINTER;cbValueMax:SQLLEN; + pcbValue:PSQLLEN):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLFreeStmt: function (StatementHandle:SQLHSTMT; + Option:SQLUSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLColAttribute: function (StatementHandle:SQLHSTMT; + ColumnNumber:SQLUSMALLINT;FieldIdentifier:SQLUSMALLINT; + CharacterAttribute:PSQLCHAR;BufferLength:SQLSMALLINT; + StringLength:PSQLSMALLINT;NumericAttribute:PSQLLEN):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLEndTran: function (HandleType:SQLSMALLINT; + Handle:SQLHANDLE;CompletionType:SQLSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLTables: function ( hstmt : SQLHSTMT; + szTableQualifier : PSQLCHAR;cbTableQualifier : SQLSMALLINT; + szTableOwner : PSQLCHAR;cbTableOwner : SQLSMALLINT; + szTableName : PSQLCHAR;cbTableName : SQLSMALLINT; + szTableType : PSQLCHAR;cbTableType : SQLSMALLINT ) : SQLRETURN; {$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLColumns: function ( hstmt : SQLHSTMT; + szTableQualifier : PSQLCHAR;cbTableQualifier : SQLSMALLINT; + szTableOwner : PSQLCHAR;cbTableOwner : SQLSMALLINT; + szTableName : PSQLCHAR;cbTableName : SQLSMALLINT; + szColumnName : PSQLCHAR;cbColumnName : SQLSMALLINT ) : SQLRETURN; {$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLSpecialColumns: function (StatementHandle:SQLHSTMT; + IdentifierType:SQLUSMALLINT;CatalogName:PSQLCHAR; + NameLength1:SQLSMALLINT;SchemaName:PSQLCHAR; + NameLength2:SQLSMALLINT;TableName:PSQLCHAR; + NameLength3:SQLSMALLINT;Scope:SQLUSMALLINT; + Nullable:SQLUSMALLINT) : SQLRETURN; {$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLProcedures: function ( hstmt : SQLHSTMT; + szTableQualifier : PSQLCHAR;cbTableQualifier : SQLSMALLINT; + szTableOwner : PSQLCHAR;cbTableOwner : SQLSMALLINT; + szTableName : PSQLCHAR;cbTableName : SQLSMALLINT ) : SQLRETURN; {$ifdef fpc} extdecl {$else} stdcall {$endif}; + + SQLPrimaryKeys: function (hstmt : SQLHSTMT; + CatalogName:PSQLCHAR;NameLength1:SQLSMALLINT; + SchemaName:PSQLCHAR;NameLength2:SQLSMALLINT; + TableName:PSQLCHAR;NameLength3:SQLSMALLINT ):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif}; + SQLProcedureColumns: function(hstmt: SQLHSTMT; + CatalogName: PSQLCHAR; NameLength1: SQLSMALLINT; + SchemaName: PSQLCHAR; NameLength2: SQLSMALLINT; + ProcName: PSQLCHAR; NameLength3: SQLSMALLINT; + ColumnName: PSQLCHAR; NameLength4: SQLSMALLINT): SQLRETURN; {$ifdef fpc} extdecl {$else} stdcall {$endif}; + SQLStatistics: function (hstmt: SQLHSTMT; + CatalogName:PSQLCHAR; NameLength1:SQLSMALLINT; + SchemaName:PSQLCHAR; NameLength2:SQLSMALLINT; + TableName:PSQLCHAR; NameLength3:SQLSMALLINT; + Unique:SQLUSMALLINT; + Reserved:SQLUSMALLINT): SQLRETURN; {$ifdef fpc} extdecl {$else} stdcall {$endif}; + +// odbcversion: word; + +{$else} + + function SQLAllocHandle( + HandleType: SQLSMALLINT; + InputHandle:SQLHANDLE; + Var OutputHandlePtr: SQLHANDLE):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLSetEnvAttr( + EnvironmentHandle:SQLHENV; + Attribute: SQLINTEGER; + Value: SQLPOINTER; + StringLength: SQLINTEGER):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLGetEnvAttr( + EnvironmentHandle:SQLHENV; + Attribute:SQLINTEGER; + Value:SQLPOINTER; + BufferLength:SQLINTEGER; + StringLength:PSQLINTEGER):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLFreeHandle( + HandleType: SQLSMALLINT; + Handle: SQLHANDLE):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLGetDiagRec( + HandleType: SQLSMALLINT; + Handle: SQLHANDLE; + RecNumber: SQLSMALLINT; + Sqlstate: PSQLCHAR; + var NativeError: SQLINTEGER; + MessageText: PSQLCHAR; + BufferLength: SQLSMALLINT; + var TextLength: SQLSMALLINT ):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLGetDiagField( + HandleType:SQLSMALLINT; + Handle:SQLHANDLE; + RecNumber:SQLSMALLINT; + DiagIdentifier:SQLSMALLINT; + DiagInfoPtr:SQLPOINTER; + BufferLength:SQLSMALLINT; + var StringLengthPtr:SQLSMALLINT ):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLConnect( + ConnectionHandle:SQLHDBC; + ServerName:PSQLCHAR; NameLength1:SQLSMALLINT; + UserName:PSQLCHAR; NameLength2:SQLSMALLINT; + Authentication:PSQLCHAR;NameLength3:SQLSMALLINT + ):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLDisconnect( + ConnectionHandle:SQLHDBC):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLDriverConnect( + hdbc: SQLHDBC; + hwnd: SQLHWND; + szCsin: PChar; + szCLen: SQLSMALLINT; + szCsout: PChar; + cbCSMax: SQLSMALLINT; + Var cbCsOut: SQLSMALLINT; + f: SQLUSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLBrowseConnect( + hdbc : SQLHDBC; + szConnStrIn :PSQLCHAR; + cbConnStrIn: SQLSMALLINT; + szConnStrOut : PSQLCHAR; + cbConnStrOutMax : SQLSMALLINT; + Var cbConnStrOut : SQLSMALLINT) : SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLExecDirect( + StatementHandle:SQLHSTMT; + StatementText: PSQLCHAR; + TextLength: SQLINTEGER):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLPrepare( + StatementHandle:SQLHSTMT; + StatementText:PSQLCHAR; + TextLength:SQLINTEGER):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLCloseCursor( + StatementHandle:SQLHSTMT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLExecute( + StatementHandle:SQLHSTMT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLFetch( + StatementHandle:SQLHSTMT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLNumResultCols( + StatementHandle:SQLHSTMT; + var ColumnCount:SQLSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLDescribeCol( + StatementHandle:SQLHSTMT; + ColumnNumber:SQLUSMALLINT; + ColumnName:PSQLCHAR; + BufferLength:SQLSMALLINT; + var NameLength:SQLSMALLINT; + var DataType:SQLSMALLINT; + var ColumnSize:SQLULEN; + var DecimalDigits:SQLSMALLINT; + var Nullable:SQLSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLFetchScroll( + StatementHandle:SQLHSTMT; + FetchOrientation:SQLSMALLINT; + FetchOffset:SQLLEN):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLExtendedFetch( + hstmt:SQLHSTMT; + fFetchType:SQLUSMALLINT; + irow:SQLLEN; + pcrow:PSQLULEN; + rgfRowStatus:PSQLUSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLGetData( + StatementHandle:SQLHSTMT; + ColumnNumber:SQLUSMALLINT; + TargetType:SQLSMALLINT; + TargetValue:SQLPOINTER; + BufferLength:SQLLEN; + StrLen_or_Ind:PSQLLEN):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLSetStmtAttr( + StatementHandle:SQLHSTMT; + Attribute:SQLINTEGER; + Value:SQLPOINTER; + StringLength:SQLINTEGER):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLGetStmtAttr( + StatementHandle:SQLHSTMT; + Attribute:SQLINTEGER; + Value:SQLPOINTER; + BufferLength:SQLINTEGER; + StringLength:PSQLINTEGER):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLGetInfo( + ConnectionHandle:SQLHDBC; + InfoType:SQLUSMALLINT; + InfoValue:SQLPOINTER; + BufferLength:SQLSMALLINT; + StringLength:PSQLSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLBulkOperations( + StatementHandle: SQLHSTMT; + Operation:SQLSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLPutData( + StatementHandle:SQLHSTMT; + Data:SQLPOINTER; + StrLen_or_Ind:SQLLEN):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLBindCol( + StatementHandle:SQLHSTMT; + ColumnNumber:SQLUSMALLINT; + TargetType:SQLSMALLINT; + TargetValue:SQLPOINTER; + BufferLength:SQLLEN; + StrLen_or_Ind:PSQLLEN):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLSetPos( + hstmt:SQLHSTMT; + irow:SQLSETPOSIROW; + fOption:SQLUSMALLINT; + fLock:SQLUSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLDataSources( + EnvironmentHandle:SQLHENV; + Direction:SQLUSMALLINT; + ServerName:PSQLCHAR; + BufferLength1:SQLSMALLINT; + NameLength1:PSQLSMALLINT; + Description:PSQLCHAR; + BufferLength2:SQLSMALLINT; + NameLength2:PSQLSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLDrivers( + EnvironmentHandle:SQLHENV; + Direction:SQLUSMALLINT; + DriverDescription:PSQLCHAR; + BufferLength1:SQLSMALLINT; + DescriptionLength1:PSQLSMALLINT; + DriverAttributes:PSQLCHAR; + BufferLength2:SQLSMALLINT; + AttributesLength2:PSQLSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLSetConnectAttr( + ConnectionHandle:SQLHDBC; + Attribute:SQLINTEGER; Value:SQLPOINTER; + StringLength:SQLINTEGER):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLGetCursorName( + StatementHandle:SQLHSTMT; + CursorName:PSQLCHAR; BufferLength:SQLSMALLINT; + NameLength:PSQLSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLSetCursorName( + StatementHandle:SQLHSTMT; + CursorName:PSQLCHAR; NameLength:SQLSMALLINT + ):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLRowCount( + StatementHandle:SQLHSTMT; + Var RowCount:SQLLEN):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLBindParameter( + hstmt:SQLHSTMT; + ipar:SQLUSMALLINT; + fParamType:SQLSMALLINT; + fCType:SQLSMALLINT; + fSqlType:SQLSMALLINT; + cbColDef:SQLULEN; + ibScale:SQLSMALLINT; + rgbValue:SQLPOINTER; + cbValueMax:SQLLEN; + pcbValue:PSQLLEN):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLFreeStmt( + StatementHandle:SQLHSTMT; + Option:SQLUSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLColAttribute ( + StatementHandle:SQLHSTMT; + ColumnNumber:SQLUSMALLINT; + FieldIdentifier:SQLUSMALLINT; + CharacterAttribute:PSQLCHAR; + BufferLength:SQLSMALLINT; + StringLength:PSQLSMALLINT; + NumericAttribute:PSQLLEN):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; +{$ifdef ODBCVER3} + function SQLEndTran( + HandleType:SQLSMALLINT; + Handle:SQLHANDLE; + CompletionType:SQLSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; +{$endif} + function SQLTables( hstmt : SQLHSTMT; + szTableQualifier : PSQLCHAR; + cbTableQualifier : SQLSMALLINT; + szTableOwner : PSQLCHAR; + cbTableOwner : SQLSMALLINT; + szTableName : PSQLCHAR; + cbTableName : SQLSMALLINT; + szTableType : PSQLCHAR; + cbTableType : SQLSMALLINT ) : SQLRETURN; {$ifdef fpc} extdecl {$else} stdcall {$endif}; external odbclib; + function SQLColumns( hstmt : SQLHSTMT; + szTableQualifier : PSQLCHAR; + cbTableQualifier : SQLSMALLINT; + szTableOwner : PSQLCHAR; + cbTableOwner : SQLSMALLINT; + szTableName : PSQLCHAR; + cbTableName : SQLSMALLINT; + szColumnName : PSQLCHAR; + cbColumnName : SQLSMALLINT ) : SQLRETURN; {$ifdef fpc} extdecl {$else} stdcall {$endif}; external odbclib; + function SQLSpecialColumns(StatementHandle:SQLHSTMT; + IdentifierType:SQLUSMALLINT; + CatalogName:PSQLCHAR; + NameLength1:SQLSMALLINT; + SchemaName:PSQLCHAR; + NameLength2:SQLSMALLINT; + TableName:PSQLCHAR; + NameLength3:SQLSMALLINT; + Scope:SQLUSMALLINT; + Nullable:SQLUSMALLINT) : SQLRETURN; {$ifdef fpc} extdecl {$else} stdcall {$endif}; external odbclib; + function SQLProcedures( hstmt : SQLHSTMT; + szTableQualifier : PSQLCHAR; + cbTableQualifier : SQLSMALLINT; + szTableOwner : PSQLCHAR; + cbTableOwner : SQLSMALLINT; + szTableName : PSQLCHAR; + cbTableName : SQLSMALLINT ) : SQLRETURN; {$ifdef fpc} extdecl {$else} stdcall {$endif}; external odbclib; + function SQLPrimaryKeys(hstmt : SQLHSTMT; + CatalogName:PSQLCHAR;NameLength1:SQLSMALLINT; + SchemaName:PSQLCHAR;NameLength2:SQLSMALLINT; + TableName:PSQLCHAR; + NameLength3:SQLSMALLINT):SQLRETURN;{$ifdef fpc} extdecl {$else} stdcall {$endif};external odbclib; + function SQLProcedureColumns(hstmt: SQLHSTMT; + CatalogName: PSQLCHAR; NameLength1: SQLSMALLINT; + SchemaName: PSQLCHAR; NameLength2: SQLSMALLINT; + ProcName: PSQLCHAR; NameLength3: SQLSMALLINT; + ColumnName: PSQLCHAR; NameLength4: SQLSMALLINT): SQLRETURN; {$ifdef fpc} extdecl {$else} stdcall {$endif}; + external odbclib; + function SQLStatistics(hstmt: SQLHSTMT; + CatalogName:PSQLCHAR; NameLength1:SQLSMALLINT; + SchemaName:PSQLCHAR; NameLength2:SQLSMALLINT; + TableName:PSQLCHAR; NameLength3:SQLSMALLINT; + Unique:SQLUSMALLINT; + Reserved:SQLUSMALLINT): SQLRETURN; {$ifdef fpc} extdecl {$else} stdcall {$endif}; external odbclib; +{$endif} +// This function always load dynamic + +function DateStructToDateTime( b:PSQL_DATE_STRUCT):TDateTime; +function DateTimeToDateStruct( b:TDateTime):SQL_DATE_STRUCT; +procedure DateTime2TimeStampStruct( var Value:SQL_TIMESTAMP_STRUCT; b:TDateTime); +Function TimeStampStructToDateTime( B : PSQL_TIMESTAMP_STRUCT) : TDateTime; +Function TimeStructToDateTime (B : PSQL_TIME_STRUCT) : TDateTime; + + +{$IFDEF DYNLOADINGODBC} +//Procedure InitialiseODBC(OverrideName : string =''); +//Procedure ReleaseODBC; + +//var ODBCLibraryHandle : TLibHandle; +{$ENDIF} + +implementation + +{$IFDEF DYNLOADINGODBC} +uses + msedynload,msesys; + +var + libinfo: dynlibinfoty; + +//var RefCount : integer; +(* +Procedure InitialiseODBC(OverrideName : string =''); + +var libname : string; + +begin + inc(RefCount); + if RefCount = 1 then + begin + if OverrideName='' then + libname:=odbclib + else + libname:=OverrideName; + ODBCLibraryHandle := loadlibrary(libname); + if ODBCLibraryHandle = nilhandle then + begin + RefCount := 0; + Raise EInOutError.Create('Can not load ODBC client. Is it installed? ('+odbclib+')'); + end; + +{$ifdef fpc} + pointer(SQLAllocHandle) := GetProcedureAddress(ODBCLibraryHandle,'SQLAllocHandle'); + pointer(SQLSetEnvAttr) := GetProcedureAddress(ODBCLibraryHandle,'SQLSetEnvAttr'); + pointer(SQLFreeHandle) := GetProcedureAddress(ODBCLibraryHandle,'SQLFreeHandle'); + pointer(SQLGetInfo) := GetProcedureAddress(ODBCLibraryHandle,'SQLGetInfo'); + pointer(SQLProcedures) := GetProcedureAddress(ODBCLibraryHandle,'SQLProcedures'); + pointer(SQLColumns) := GetProcedureAddress(ODBCLibraryHandle,'SQLColumns'); + pointer(SQLSpecialColumns) := GetProcedureAddress(ODBCLibraryHandle,'SQLSpecialColumns'); + pointer(SQLGetDiagRec) := GetProcedureAddress(ODBCLibraryHandle,'SQLGetDiagRec'); + pointer(SQLGetDiagField) := GetProcedureAddress(ODBCLibraryHandle,'SQLGetDiagField'); + pointer(SQLConnect) := GetProcedureAddress(ODBCLibraryHandle,'SQLConnect'); + pointer(SQLDisconnect) := GetProcedureAddress(ODBCLibraryHandle,'SQLDisconnect'); + pointer(SQLDriverConnect) := GetProcedureAddress(ODBCLibraryHandle,'SQLDriverConnect'); + pointer(SQLExecDirect) := GetProcedureAddress(ODBCLibraryHandle,'SQLExecDirect'); + pointer(SQLPrepare) := GetProcedureAddress(ODBCLibraryHandle,'SQLPrepare'); + pointer(SQLCloseCursor) := GetProcedureAddress(ODBCLibraryHandle,'SQLCloseCursor'); + pointer(SQLExecute) := GetProcedureAddress(ODBCLibraryHandle,'SQLExecute'); + pointer(SQLFetch) := GetProcedureAddress(ODBCLibraryHandle,'SQLFetch'); + pointer(SQLNumResultCols) := GetProcedureAddress(ODBCLibraryHandle,'SQLNumResultCols'); + pointer(SQLDescribeCol) := GetProcedureAddress(ODBCLibraryHandle,'SQLDescribeCol'); + pointer(SQLFetchScroll) := GetProcedureAddress(ODBCLibraryHandle,'SQLFetchScroll'); + pointer(SQLExtendedFetch) := GetProcedureAddress(ODBCLibraryHandle,'SQLExtendedFetch'); + pointer(SQLGetData) := GetProcedureAddress(ODBCLibraryHandle,'SQLGetData'); + pointer(SQLSetStmtAttr) := GetProcedureAddress(ODBCLibraryHandle,'SQLSetStmtAttr'); + pointer(SQLGetStmtAttr) := GetProcedureAddress(ODBCLibraryHandle,'SQLGetStmtAttr'); + pointer(SQLBulkOperations) := GetProcedureAddress(ODBCLibraryHandle,'SQLBulkOperations'); + pointer(SQLPutData) := GetProcedureAddress(ODBCLibraryHandle,'SQLPutData'); + pointer(SQLBindCol) := GetProcedureAddress(ODBCLibraryHandle,'SQLBindCol'); + pointer(SQLSetPos) := GetProcedureAddress(ODBCLibraryHandle,'SQLSetPos'); + pointer(SQLDataSources) := GetProcedureAddress(ODBCLibraryHandle,'SQLDataSources'); + pointer(SQLDrivers) := GetProcedureAddress(ODBCLibraryHandle,'SQLDrivers'); + pointer(SQLSetConnectAttr) := GetProcedureAddress(ODBCLibraryHandle,'SQLSetConnectAttr'); + pointer(SQLGetCursorName) := GetProcedureAddress(ODBCLibraryHandle,'SQLGetCursorName'); + pointer(SQLSetCursorName) := GetProcedureAddress(ODBCLibraryHandle,'SQLSetCursorName'); + pointer(SQLRowCount) := GetProcedureAddress(ODBCLibraryHandle,'SQLRowCount'); + pointer(SQLBindParameter) := GetProcedureAddress(ODBCLibraryHandle,'SQLBindParameter'); + pointer(SQLFreeStmt) := GetProcedureAddress(ODBCLibraryHandle,'SQLFreeStmt'); + pointer(SQLColAttribute) := GetProcedureAddress(ODBCLibraryHandle,'SQLColAttribute'); + pointer(SQLEndTran) := GetProcedureAddress(ODBCLibraryHandle,'SQLEndTran'); + pointer(SQLTables) := GetProcedureAddress(ODBCLibraryHandle,'SQLTables'); + pointer(SQLPrimaryKeys) := GetProcedureAddress(ODBCLibraryHandle,'SQLPrimaryKeys'); + pointer(SQLProcedureColumns) := GetProcedureAddress(ODBCLibraryHandle,'SQLProcedureColumns'); + pointer(SQLStatistics) := GetProcedureAddress(ODBCLibraryHandle,'SQLStatistics'); +{$else} + SQLAllocHandle := GetProcedureAddress(ODBCLibraryHandle,'SQLAllocHandle'); + SQLSetEnvAttr := GetProcedureAddress(ODBCLibraryHandle,'SQLSetEnvAttr'); + SQLFreeHandle := GetProcedureAddress(ODBCLibraryHandle,'SQLFreeHandle'); + SQLGetInfo := GetProcedureAddress(ODBCLibraryHandle,'SQLGetInfo'); + SQLProcedures := GetProcedureAddress(ODBCLibraryHandle,'SQLProcedures'); + SQLColumns := GetProcedureAddress(ODBCLibraryHandle,'SQLColumns'); + SQLSpecialColumns := GetProcedureAddress(ODBCLibraryHandle,'SQLSpecialColumns'); + SQLGetDiagRec := GetProcedureAddress(ODBCLibraryHandle,'SQLGetDiagRec'); + SQLGetDiagField := GetProcedureAddress(ODBCLibraryHandle,'SQLGetDiagField'); + SQLConnect := GetProcedureAddress(ODBCLibraryHandle,'SQLConnect'); + SQLDisconnect := GetProcedureAddress(ODBCLibraryHandle,'SQLDisconnect'); + SQLDriverConnect := GetProcedureAddress(ODBCLibraryHandle,'SQLDriverConnect'); + SQLExecDirect := GetProcedureAddress(ODBCLibraryHandle,'SQLExecDirect'); + SQLPrepare := GetProcedureAddress(ODBCLibraryHandle,'SQLPrepare'); + SQLCloseCursor := GetProcedureAddress(ODBCLibraryHandle,'SQLCloseCursor'); + SQLExecute := GetProcedureAddress(ODBCLibraryHandle,'SQLExecute'); + SQLFetch := GetProcedureAddress(ODBCLibraryHandle,'SQLFetch'); + SQLNumResultCols := GetProcedureAddress(ODBCLibraryHandle,'SQLNumResultCols'); + SQLDescribeCol := GetProcedureAddress(ODBCLibraryHandle,'SQLDescribeCol'); + SQLFetchScroll := GetProcedureAddress(ODBCLibraryHandle,'SQLFetchScroll'); + SQLExtendedFetch := GetProcedureAddress(ODBCLibraryHandle,'SQLExtendedFetch'); + SQLGetData := GetProcedureAddress(ODBCLibraryHandle,'SQLGetData'); + SQLSetStmtAttr := GetProcedureAddress(ODBCLibraryHandle,'SQLSetStmtAttr'); + SQLGetStmtAttr := GetProcedureAddress(ODBCLibraryHandle,'SQLGetStmtAttr'); + SQLBulkOperations := GetProcedureAddress(ODBCLibraryHandle,'SQLBulkOperations'); + SQLPutData := GetProcedureAddress(ODBCLibraryHandle,'SQLPutData'); + SQLBindCol := GetProcedureAddress(ODBCLibraryHandle,'SQLBindCol'); + SQLSetPos := GetProcedureAddress(ODBCLibraryHandle,'SQLSetPos'); + SQLDataSources := GetProcedureAddress(ODBCLibraryHandle,'SQLDataSources'); + SQLDrivers := GetProcedureAddress(ODBCLibraryHandle,'SQLDrivers'); + SQLSetConnectAttr := GetProcedureAddress(ODBCLibraryHandle,'SQLSetConnectAttr'); + SQLGetCursorName := GetProcedureAddress(ODBCLibraryHandle,'SQLGetCursorName'); + SQLSetCursorName := GetProcedureAddress(ODBCLibraryHandle,'SQLSetCursorName'); + SQLRowCount := GetProcedureAddress(ODBCLibraryHandle,'SQLRowCount'); + SQLBindParameter := GetProcedureAddress(ODBCLibraryHandle,'SQLBindParameter'); + SQLGetFunctions := GetProcedureAddress(ODBCLibraryHandle,'SQLGetFunctions'); + SQLDescribeParam :=GetProcedureAddress(ODBCLibraryHandle,'SQLDescribeParam'); + SQLFreeStmt := GetProcedureAddress(ODBCLibraryHandle,'SQLFreeStmt'); + SQLColAttribute := GetProcedureAddress(ODBCLibraryHandle,'SQLColAttribute'); + SQLEndTran := GetProcedureAddress(ODBCLibraryHandle,'SQLEndTran'); + SQLTables := GetProcedureAddress(ODBCLibraryHandle,'SQLTables'); + SQLPrimaryKeys := GetProcedureAddress(ODBCLibraryHandle,'SQLPrimaryKeys'); + SQLProcedureColumns := GetProcedureAddress(ODBCLibraryHandle,'SQLProcedureColumns'); + SQLStatistics := GetProcedureAddress(ODBCLibraryHandle,'SQLStatistics'); +{$endif} + end; +end; + +Procedure ReleaseODBC; + +begin + if RefCount > 0 then dec(RefCount); + if RefCount = 0 then + begin + if not UnloadLibrary(ODBCLibraryHandle) then inc(RefCount); + end; +end; +*) +{$ENDIF} + +function DateStructToDateTime( b:PSQL_DATE_STRUCT):TDateTime; +begin + Result:=EncodeDate( b^.Year, b^.Month, b^.Day); +end; + +function DateTimeToDateStruct( b:TDateTime):SQL_DATE_STRUCT; +var + y,m,d: Word; +begin + DecodeDate( b, y, m, d); + with Result do + begin + Year:=y; Month:=m; Day:=d; + end; +end; + +procedure DateTime2TimeStampStruct( var Value:SQL_TIMESTAMP_STRUCT; b:TDateTime); +var + w1,w2,w3,w4: Word; +begin + with Value do + begin + DecodeDate(b,w1,w2,w3); + Year := w1; + Month := w2; + Day := w3; + DecodeTime(b,w1,w2,w3,w4); + Hour := w1; + Minute := w2; + Second := w3; + fraction := Integer(w4)*1000000; + end; +end; +{ + SQL_DATE_STRUCT = packed record + Year : SQLSMALLINT; + Month : SQLUSMALLINT; + Day : SQLUSMALLINT; + end; + PSQL_DATE_STRUCT = ^SQL_DATE_STRUCT; +} + +Function TimeStampStructToDateTime( B : PSQL_TIMESTAMP_STRUCT) : TDateTime; + +begin + With B^ do + Result:=EncodeDate(Year,Month,Day)+ + EncodeTime(Hour,Minute,Second,0); +end; + +Function TimeStructToDateTime (B : PSQL_TIME_STRUCT) : TDateTime; +begin + With B^ do + Result:=EncodeTime(Hour,Minute,Second,0); +end; + +procedure initializeodbc(const sonames: array of filenamety); + +const + funcs: array[0..41] of funcinfoty = ( + (n: 'SQLAllocHandle'; d: {$ifndef FPC}@{$endif}@SQLAllocHandle), + (n: 'SQLSetEnvAttr'; d: {$ifndef FPC}@{$endif}@SQLSetEnvAttr), + (n: 'SQLFreeHandle'; d: {$ifndef FPC}@{$endif}@SQLFreeHandle), + (n: 'SQLGetInfo'; d: {$ifndef FPC}@{$endif}@SQLGetInfo), + (n: 'SQLProcedures'; d: {$ifndef FPC}@{$endif}@SQLProcedures), + (n: 'SQLColumns'; d: {$ifndef FPC}@{$endif}@SQLColumns), + (n: 'SQLSpecialColumns'; d: {$ifndef FPC}@{$endif}@SQLSpecialColumns), + (n: 'SQLGetDiagRec'; d: {$ifndef FPC}@{$endif}@SQLGetDiagRec), + (n: 'SQLGetDiagField'; d: {$ifndef FPC}@{$endif}@SQLGetDiagField), + (n: 'SQLConnect'; d: {$ifndef FPC}@{$endif}@SQLConnect), + (n: 'SQLDisconnect'; d: {$ifndef FPC}@{$endif}@SQLDisconnect), + (n: 'SQLDriverConnect'; d: {$ifndef FPC}@{$endif}@SQLDriverConnect), + (n: 'SQLExecDirect'; d: {$ifndef FPC}@{$endif}@SQLExecDirect), + (n: 'SQLPrepare'; d: {$ifndef FPC}@{$endif}@SQLPrepare), + (n: 'SQLCloseCursor'; d: {$ifndef FPC}@{$endif}@SQLCloseCursor), + (n: 'SQLExecute'; d: {$ifndef FPC}@{$endif}@SQLExecute), + (n: 'SQLFetch'; d: {$ifndef FPC}@{$endif}@SQLFetch), + (n: 'SQLNumResultCols'; d: {$ifndef FPC}@{$endif}@SQLNumResultCols), + (n: 'SQLDescribeCol'; d: {$ifndef FPC}@{$endif}@SQLDescribeCol), + (n: 'SQLFetchScroll'; d: {$ifndef FPC}@{$endif}@SQLFetchScroll), + (n: 'SQLExtendedFetch'; d: {$ifndef FPC}@{$endif}@SQLExtendedFetch), + (n: 'SQLGetData'; d: {$ifndef FPC}@{$endif}@SQLGetData), + (n: 'SQLSetStmtAttr'; d: {$ifndef FPC}@{$endif}@SQLSetStmtAttr), + (n: 'SQLGetStmtAttr'; d: {$ifndef FPC}@{$endif}@SQLGetStmtAttr), + (n: 'SQLBulkOperations'; d: {$ifndef FPC}@{$endif}@SQLBulkOperations), + (n: 'SQLPutData'; d: {$ifndef FPC}@{$endif}@SQLPutData), + (n: 'SQLBindCol'; d: {$ifndef FPC}@{$endif}@SQLBindCol), + (n: 'SQLSetPos'; d: {$ifndef FPC}@{$endif}@SQLSetPos), + (n: 'SQLDataSources'; d: {$ifndef FPC}@{$endif}@SQLDataSources), + (n: 'SQLDrivers'; d: {$ifndef FPC}@{$endif}@SQLDrivers), + (n: 'SQLSetConnectAttr'; d: {$ifndef FPC}@{$endif}@SQLSetConnectAttr), + (n: 'SQLGetCursorName'; d: {$ifndef FPC}@{$endif}@SQLGetCursorName), + (n: 'SQLSetCursorName'; d: {$ifndef FPC}@{$endif}@SQLSetCursorName), + (n: 'SQLRowCount'; d: {$ifndef FPC}@{$endif}@SQLRowCount), + (n: 'SQLBindParameter'; d: {$ifndef FPC}@{$endif}@SQLBindParameter), +// (n: 'SQLGetFunctions'; d: {$ifndef FPC}@{$endif}@SQLGetFunctions), +// (n: 'SQLDescribeParam'; d: {$ifndef FPC}@{$endif}@SQLDescribeParam), + (n: 'SQLFreeStmt'; d: {$ifndef FPC}@{$endif}@SQLFreeStmt), + (n: 'SQLColAttribute'; d: {$ifndef FPC}@{$endif}@SQLColAttribute), + (n: 'SQLEndTran'; d: {$ifndef FPC}@{$endif}@SQLEndTran), + (n: 'SQLTables'; d: {$ifndef FPC}@{$endif}@SQLTables), + (n: 'SQLPrimaryKeys'; d: {$ifndef FPC}@{$endif}@SQLPrimaryKeys), + (n: 'SQLProcedureColumns'; d: {$ifndef FPC}@{$endif}@SQLProcedureColumns), + (n: 'SQLStatistics'; d: {$ifndef FPC}@{$endif}@SQLStatistics) + ); + errormessage = 'Can not load ODBC library. '; +begin + initializedynlib(libinfo,sonames,odbclib,funcs,[],errormessage); +end; + +procedure releaseodbc; +begin + releasedynlib(libinfo); +end; + +initialization + initializelibinfo(libinfo); +finalization + finalizelibinfo(libinfo); +end. diff --git a/mseide-msegui/lib/common/db/postgres3dyn.pas b/mseide-msegui/lib/common/db/postgres3dyn.pas new file mode 100644 index 0000000..f227b00 --- /dev/null +++ b/mseide-msegui/lib/common/db/postgres3dyn.pas @@ -0,0 +1,594 @@ +{ + modified 2009-2010 by Martin Schreiber +} + +{ + Contains the Postgres protocol 3 functions calls + + Call InitialisePostgres3 before using any of the calls, and call ReleasePostgres3 + when finished. +} + +unit postgres3dyn; + +{$ifdef FPC}{$mode objfpc}{$H+}{$endif} + +interface + +uses + {$ifdef FPC}dynlibs,{$else}{$endif} SysUtils, msectypes,msetypes{msestrings}; + +const +{$ifdef mswindows} + postgreslib: array[0..0] of filenamety = ('libpq.dll'); +{$else} + postgreslib: array[0..2] of filenamety = ('libpq.so.5.4','libpq.so.5','libpq.so'); +{$endif} + +procedure initializepostgres3(const sonames: array of filenamety); +procedure releasepostgres3; + +(* +{$IFDEF Unix} + const + pqlib = 'libpq.'+sharedsuffix; +{$ENDIF} +{$IFDEF Win32} + const + pqlib = 'libpq.dll'; +{$ENDIF} +*) +{$ifdef FPC} + {$PACKRECORDS C} +{$else} + {$ALIGN 4} + {$MINENUMSIZE 4} +{$endif} +//{$i postgres3types.inc} +Type + size_t = sizeint; + psize_t = ^size_t; + TFILE = Longint; + PFIle = ^TFILE; + POid = ^Oid; + Oid = dword; + +type + { Pointer types } + PDllist= ^TDllist; + PDlelem= ^TDlelem; + + TDlelem = record + dle_next : PDlelem; + dle_prev : PDlElem; + dle_val : pointer; + dle_list : PDllist; + end; + + TDllist = record + dll_head : PDlelem; + dll_tail : PDlelem; + end; + +var + DLNewList : function : PDllist;cdecl; + DLFreeList : procedure (_para1:PDllist);cdecl; + DLNewElem : function (val : pointer) :PDlelem;cdecl; + DLFreeElem : procedure (_para1:PDlelem);cdecl; + DLGetHead : function (_para1:PDllist):PDlelem;cdecl; + DLGetTail : function (_para1:PDllist):PDlelem;cdecl; + DLRemTail : function (l:PDllist):PDlelem;cdecl; + DLGetPred : function (_para1:PDlelem):PDlelem;cdecl; + DLGetSucc : function (_para1:PDlelem):PDlelem;cdecl; + DLRemove : procedure (_para1:PDlelem);cdecl; + DLAddHead : procedure (list:PDllist; node:PDlelem);cdecl; + DLAddTail : procedure (list:PDllist; node:PDlelem);cdecl; + DLRemHead : function (list:PDllist):PDlelem;cdecl; + +{ Macro translated } +Function DLE_VAL(elem : PDlelem) : pointer; + +const + ERROR_MSG_LENGTH = 4096; + CMDSTATUS_LEN = 40; + +Type + TSockAddr = Array [1..112] of byte; + TPGresAttDesc = record + name : Pchar; + adtid : Oid; + adtsize : integer; + end; + PPGresAttDesc= ^TPGresAttDesc; + PPPGresAttDesc= ^PPGresAttDesc; + TPGresAttValue = record + len : longint; + value : Pchar; + end; + PPGresAttValue= ^TPGresAttValue; + PPPGresAttValue= ^PPGresAttValue; + + PExecStatusType = ^TExecStatusType; + TExecStatusType = (PGRES_EMPTY_QUERY{$ifdef PFC} := 0{$endif},PGRES_COMMAND_OK, + PGRES_TUPLES_OK,PGRES_COPY_OUT,PGRES_COPY_IN, + PGRES_BAD_RESPONSE,PGRES_NONFATAL_ERROR, + PGRES_FATAL_ERROR); + + + TPGlobjfuncs = record + fn_lo_open : Oid; + fn_lo_close : Oid; + fn_lo_creat : Oid; + fn_lo_unlink : Oid; + fn_lo_lseek : Oid; + fn_lo_tell : Oid; + fn_lo_read : Oid; + fn_lo_write : Oid; + end; + PPGlobjfuncs= ^TPGlobjfuncs; + + PConnStatusType = ^TConnStatusType; + TConnStatusType = (CONNECTION_OK,CONNECTION_BAD,CONNECTION_STARTED, + CONNECTION_MADE,CONNECTION_AWAITING_RESPONSE, + CONNECTION_AUTH_OK,CONNECTION_SETENV, + CONNECTION_SSL_STARTUP,CONNECTION_NEEDED); + + TPGconn = record + pghost : Pchar; + pgtty : Pchar; + pgport : Pchar; + pgoptions : Pchar; + dbName : Pchar; + status : TConnStatusType; + errorMessage : array[0..(ERROR_MSG_LENGTH)-1] of char; + Pfin : PFILE; + Pfout : PFILE; + Pfdebug : PFILE; + sock : longint; + laddr : TSockAddr; + raddr : TSockAddr; + salt : array[0..(2)-1] of char; + asyncNotifyWaiting : longint; + notifyList : PDllist; + pguser : Pchar; + pgpass : Pchar; + lobjfuncs : PPGlobjfuncs; + end; + PPGconn= ^TPGconn; + + TPGresult = record + ntups : longint; + numAttributes : longint; + attDescs : PPGresAttDesc; + tuples : PPPGresAttValue; + tupArrSize : longint; + resultStatus : TExecStatusType; + cmdStatus : array[0..(CMDSTATUS_LEN)-1] of char; + binary : longint; + conn : PPGconn; + end; + PPGresult= ^TPGresult; + + + + + + PPostgresPollingStatusType = ^PostgresPollingStatusType; + PostgresPollingStatusType = (PGRES_POLLING_FAILED{$ifdef FPC} := 0{$endif}, + PGRES_POLLING_READING, + PGRES_POLLING_WRITING,PGRES_POLLING_OK, + PGRES_POLLING_ACTIVE); + + + PPGTransactionStatusType = ^PGTransactionStatusType; + PGTransactionStatusType = (PQTRANS_IDLE,PQTRANS_ACTIVE,PQTRANS_INTRANS, + PQTRANS_INERROR,PQTRANS_UNKNOWN); + + PPGVerbosity = ^PGVerbosity; + PGVerbosity = (PQERRORS_TERSE,PQERRORS_DEFAULT,PQERRORS_VERBOSE); + + PpgNotify = ^pgNotify; + pgNotify = record + relname : Pchar; + be_pid : longint; + extra : Pchar; + end; + +{ Function types for notice-handling callbacks } + PQnoticeReceiver = procedure (arg:pointer; res:PPGresult);cdecl; + PQnoticeProcessor = procedure (arg:pointer; message:Pchar);cdecl; +{ Print options for PQprint() } + Ppqbool = ^pqbool; + pqbool = char; + + P_PQprintOpt = ^_PQprintOpt; + _PQprintOpt = record + header : pqbool; + align : pqbool; + standard : pqbool; + html3 : pqbool; + expanded : pqbool; + pager : pqbool; + fieldSep : Pchar; + tableOpt : Pchar; + caption : Pchar; + fieldName : ^Pchar; + end; + PQprintOpt = _PQprintOpt; + PPQprintOpt = ^PQprintOpt; + + { ---------------- + * Structure for the conninfo parameter definitions returned by PQconndefaults + * + * All fields except "val" point at static strings which must not be altered. + * "val" is either NULL or a malloc'd current-value string. PQconninfoFree() + * will release both the val strings and the PQconninfoOption array itself. + * ---------------- + } + + P_PQconninfoOption = ^_PQconninfoOption; + _PQconninfoOption = record + keyword : Pchar; + envvar : Pchar; + compiled : Pchar; + val : Pchar; + _label : Pchar; + dispchar : Pchar; + dispsize : longint; + end; + PQconninfoOption = _PQconninfoOption; + PPQconninfoOption = ^PQconninfoOption; + { ---------------- + * PQArgBlock -- structure for PQfn() arguments + * ---------------- + } + { can't use void (dec compiler barfs) } + + PPQArgBlock = ^PQArgBlock; + PQArgBlock = record + len : longint; + isint : longint; + u : record + case longint of + 0 : ( ptr : Plongint ); + 1 : ( integer : longint ); + end; + end; + +var +{ ---------------- +* Exported functions of libpq +* ---------------- +} +{ === in fe-connect.c === } +{ make a new client connection to the backend } +{ Asynchronous (non-blocking) } +(* Const before type ignored *) + PQconnectStart : function (conninfo:Pchar):PPGconn;cdecl; + PQconnectPoll : function (conn:PPGconn):PostgresPollingStatusType;cdecl; +{ Synchronous (blocking) } +(* Const before type ignored *) + PQconnectdb : function (conninfo:Pchar):PPGconn;cdecl; + PQsetdbLogin : function (pghost:Pchar; pgport:Pchar; pgoptions:Pchar; pgtty:Pchar; dbName:Pchar;login:Pchar; pwd:Pchar):PPGconn;cdecl; +{ was #define dname(params) para_def_expr } +{ argument types are unknown } +{ return type might be wrong } +{ close the current connection and free the PGconn data structure } + PQfinish : procedure (conn:PPGconn);cdecl; +{ get info about connection options known to PQconnectdb } + PQconndefaults : function : PPQconninfoOption;cdecl; +{ free the data structure returned by PQconndefaults() } + PQconninfoFree : procedure (connOptions:PPQconninfoOption);cdecl; +{ +* close the current connection and restablish a new one with the same +* parameters +} +{ Asynchronous (non-blocking) } + PQresetStart : function (conn:PPGconn):longint;cdecl; + PQresetPoll : function (conn:PPGconn):PostgresPollingStatusType;cdecl; +{ Synchronous (blocking) } + PQreset : procedure (conn:PPGconn);cdecl; +{ issue a cancel request } + PQrequestCancel : function (conn:PPGconn):longint;cdecl; +{ Accessor functions for PGconn objects } + PQdb : function (conn:PPGconn):Pchar;cdecl; + PQuser : function (conn:PPGconn):Pchar;cdecl; + PQpass : function (conn:PPGconn):Pchar;cdecl; + PQhost : function (conn:PPGconn):Pchar;cdecl; + PQport : function (conn:PPGconn):Pchar;cdecl; + PQtty : function (conn:PPGconn):Pchar;cdecl; + PQoptions : function (conn:PPGconn):Pchar;cdecl; + PQstatus : function (conn:PPGconn):TConnStatusType;cdecl; + PQtransactionStatus : function (conn:PPGconn):PGTransactionStatusType;cdecl; + PQparameterStatus : function (conn:PPGconn; paramName:Pchar):Pchar;cdecl; + PQprotocolVersion : function (conn:PPGconn):longint;cdecl; + PQerrorMessage : function (conn:PPGconn):Pchar;cdecl; + PQsocket : function (conn:PPGconn):longint;cdecl; + PQbackendPID : function (conn:PPGconn):longint;cdecl; + PQclientEncoding : function (conn:PPGconn):longint;cdecl; + PQsetClientEncoding : function (conn:PPGconn; encoding:Pchar):longint;cdecl; +{ Set verbosity for PQerrorMessage and PQresultErrorMessage } + PQsetErrorVerbosity : function (conn:PPGconn; verbosity:PGVerbosity):PGVerbosity;cdecl; +{ Enable/disable tracing } + PQtrace : procedure (conn:PPGconn; debug_port:PFILE);cdecl; + PQuntrace : procedure (conn:PPGconn);cdecl; +{ Override default notice handling routines } + PQsetNoticeReceiver : function (conn:PPGconn; proc:PQnoticeReceiver; arg:pointer):PQnoticeReceiver;cdecl; + PQsetNoticeProcessor : function (conn:PPGconn; proc:PQnoticeProcessor; arg:pointer):PQnoticeProcessor;cdecl; +{ === in fe-exec.c === } +{ Simple synchronous query } + PQexec : function (conn:PPGconn; query:Pchar):PPGresult;cdecl; + PQexecParams : function (conn:PPGconn; command:Pchar; nParams:longint; paramTypes:POid; paramValues:PPchar;paramLengths:Plongint; paramFormats:Plongint; resultFormat:longint):PPGresult;cdecl; + PQexecPrepared : function (conn:PPGconn; stmtName:Pchar; nParams:longint; paramValues:PPchar; paramLengths:Plongint;paramFormats:Plongint; resultFormat:longint):PPGresult;cdecl; + PQPrepare : function (conn:PPGconn; stmtName:Pchar; query:Pchar; nParams:longint; paramTypes:POid):PPGresult;cdecl; +{ Interface for multiple-result or asynchronous queries } + PQsendQuery : function (conn:PPGconn; query:Pchar):longint;cdecl; + PQsendQueryParams : function (conn:PPGconn; command:Pchar; nParams:longint; paramTypes:POid; paramValues:PPchar;paramLengths:Plongint; paramFormats:Plongint; resultFormat:longint):longint;cdecl; + PQsendQueryPrepared : function (conn:PPGconn; stmtName:Pchar; nParams:longint; paramValues:PPchar; paramLengths:Plongint;paramFormats:Plongint; resultFormat:longint):longint;cdecl; + PQgetResult : function (conn:PPGconn):PPGresult;cdecl; +{ Routines for managing an asynchronous query } + PQisBusy : function (conn:PPGconn):longint;cdecl; + PQconsumeInput : function (conn:PPGconn):longint;cdecl; +{ LISTEN/NOTIFY support } + PQnotifies : function (conn:PPGconn):PPGnotify;cdecl; +{ Routines for copy in/out } + PQputCopyData : function (conn:PPGconn; buffer:Pchar; nbytes:longint):longint;cdecl; + PQputCopyEnd : function (conn:PPGconn; errormsg:Pchar):longint;cdecl; + PQgetCopyData : function (conn:PPGconn; buffer:PPchar; async:longint):longint;cdecl; +{ Deprecated routines for copy in/out } + PQgetline : function (conn:PPGconn; _string:Pchar; length:longint):longint;cdecl; + PQputline : function (conn:PPGconn; _string:Pchar):longint;cdecl; + PQgetlineAsync : function (conn:PPGconn; buffer:Pchar; bufsize:longint):longint;cdecl; + PQputnbytes : function (conn:PPGconn; buffer:Pchar; nbytes:longint):longint;cdecl; + PQendcopy : function (conn:PPGconn):longint;cdecl; +{ Set blocking/nonblocking connection to the backend } + PQsetnonblocking : function (conn:PPGconn; arg:longint):longint;cdecl; + PQisnonblocking : function (conn:PPGconn):longint;cdecl; +{ Force the write buffer to be written (or at least try) } + PQflush : function (conn:PPGconn):longint;cdecl; +{ +* "Fast path" interface --- not really recommended for application +* use +} + PQfn : function (conn:PPGconn; fnid:longint; result_buf:Plongint; result_len:Plongint; result_is_int:longint;args:PPQArgBlock; nargs:longint):PPGresult;cdecl; +{ Accessor functions for PGresult objects } + PQresultStatus : function (res:PPGresult):TExecStatusType;cdecl; + PQresStatus : function (status:TExecStatusType):Pchar;cdecl; + PQresultErrorMessage : function (res:PPGresult):Pchar;cdecl; + PQresultErrorField : function (res:PPGresult; fieldcode:longint):Pchar;cdecl; + PQntuples : function (res:PPGresult):longint;cdecl; + PQnfields : function (res:PPGresult):longint;cdecl; + PQbinaryTuples : function (res:PPGresult):longint;cdecl; + PQfname : function (res:PPGresult; field_num:longint):Pchar;cdecl; + PQfnumber : function (res:PPGresult; field_name:Pchar):longint;cdecl; + PQftable : function (res:PPGresult; field_num:longint):Oid;cdecl; + PQftablecol : function (res:PPGresult; field_num:longint):longint;cdecl; + PQfformat : function (res:PPGresult; field_num:longint):longint;cdecl; + PQftype : function (res:PPGresult; field_num:longint):Oid;cdecl; + PQfsize : function (res:PPGresult; field_num:longint):longint;cdecl; + PQfmod : function (res:PPGresult; field_num:longint):longint;cdecl; + PQcmdStatus : function (res:PPGresult):Pchar;cdecl; + PQoidStatus : function (res:PPGresult):Pchar;cdecl; +{ old and ugly } + PQoidValue : function (res:PPGresult):Oid;cdecl; +{ new and improved } + PQcmdTuples : function (res:PPGresult):Pchar;cdecl; + PQgetvalue : function (res:PPGresult; tup_num:longint; field_num:longint):Pchar;cdecl; + PQgetlength : function (res:PPGresult; tup_num:longint; field_num:longint):longint;cdecl; + PQgetisnull : function (res:PPGresult; tup_num:longint; field_num:longint):longint;cdecl; +{ Delete a PGresult } + PQclear : procedure (res:PPGresult);cdecl; +{ For freeing other alloc'd results, such as PGnotify structs } + PQfreemem : procedure (ptr:pointer);cdecl; +{ Exists for backward compatibility. bjm 2003-03-24 } +{ was #define dname(params) para_def_expr } +{ argument types are unknown } +{ return type might be wrong } +// function PQfreeNotify(ptr : longint) : longint; +{ +* Make an empty PGresult with given status (some apps find this +* useful). If conn is not NULL and status indicates an error, the +* conn's errorMessage is copied. +} + PQmakeEmptyPGresult : function (conn:PPGconn; status:TExecStatusType):PPGresult;cdecl; +{ Quoting strings before inclusion in queries. } + PQescapeString : function (till:Pchar; from:Pchar; length:size_t):size_t;cdecl; + PQescapeBytea : function (bintext:Pbyte; binlen:size_t; bytealen:Psize_t):Pbyte;cdecl; + PQunescapeBytea : function (strtext:Pbyte; retbuflen:Psize_t):Pbyte;cdecl; +{ === in fe-print.c === } +{ output stream } + PQprint : procedure (fout:PFILE; res:PPGresult; ps:PPQprintOpt);cdecl; +{ option structure } +{ +* really old printing routines +} +{ where to send the output } +{ pad the fields with spaces } +{ field separator } +{ display headers? } + PQdisplayTuples : procedure (res:PPGresult; fp:PFILE; fillAlign:longint; fieldSep:Pchar; printHeader:longint;quiet:longint);cdecl; +(* Const before type ignored *) +{ output stream } +{ print attribute names } +{ delimiter bars } + PQprintTuples : procedure (res:PPGresult; fout:PFILE; printAttName:longint; terseOutput:longint; width:longint);cdecl; +{ width of column, if 0, use variable +* width } +{ === in fe-lobj.c === } +{ Large-object access routines } + lo_open : function (conn:PPGconn; lobjId:Oid; mode:longint):longint;cdecl; + lo_close : function (conn:PPGconn; fd:longint):longint;cdecl; + lo_read : function (conn:PPGconn; fd:longint; buf:Pchar; len:size_t):longint;cdecl; + lo_write : function (conn:PPGconn; fd:longint; buf:Pchar; len:size_t):longint;cdecl; + lo_lseek : function (conn:PPGconn; fd:longint; offset:longint; whence:longint):longint;cdecl; + lo_creat : function (conn:PPGconn; mode:longint):Oid;cdecl; + lo_tell : function (conn:PPGconn; fd:longint):longint;cdecl; + lo_unlink : function (conn:PPGconn; lobjId:Oid):longint;cdecl; + lo_import : function (conn:PPGconn; filename:Pchar):Oid;cdecl; + lo_export : function (conn:PPGconn; lobjId:Oid; filename:Pchar):longint;cdecl; +{ === in fe-misc.c === } +{ Determine length of multibyte encoded char at *s } + PQmblen : function (s:Pbyte; encoding:longint):longint;cdecl; +{ Get encoding id from environment variable PGCLIENTENCODING } + PQenv2encoding: function :longint;cdecl; + +//{$ifdef USE_SSL} +{ Get the SSL structure associated with a connection } +// PQgetssl : function (conn:PPGconn):PSSL;cdecl; + PQgetssl : function (conn:PPGconn): pointer;cdecl; +//{$endif} + +implementation +uses + {msesonames,}msedynload,msesys; + +var + libinfo: dynlibinfoty; + +// This function is also defined in postgres3! +function PQsetdb(M_PGHOST,M_PGPORT,M_PGOPT,M_PGTTY,M_DBNAME : pchar) : ppgconn; +begin + PQsetdb:=PQsetdbLogin(M_PGHOST,M_PGPORT,M_PGOPT,M_PGTTY,M_DBNAME,'',''); +end; + +// This function is also defined in Dllist! +Function DLE_VAL(elem : PDlelem) : pointer; +begin + DLE_VAL:=elem^.dle_val +end; + +procedure initializepostgres3(const sonames: array of filenamety); +const + funcs: array[0..97] of funcinfoty = ( + (n: 'PQconnectStart'; d: {$ifndef FPC}@{$endif}@PQconnectStart), + (n: 'PQconnectPoll'; d: {$ifndef FPC}@{$endif}@PQconnectPoll), + (n: 'PQconnectdb'; d: {$ifndef FPC}@{$endif}@PQconnectdb), + (n: 'PQsetdbLogin'; d: {$ifndef FPC}@{$endif}@PQsetdbLogin), + (n: 'PQfinish'; d: {$ifndef FPC}@{$endif}@PQfinish), + (n: 'PQconndefaults'; d: {$ifndef FPC}@{$endif}@PQconndefaults), + (n: 'PQconninfoFree'; d: {$ifndef FPC}@{$endif}@PQconninfoFree), + (n: 'PQresetStart'; d: {$ifndef FPC}@{$endif}@PQresetStart), + (n: 'PQresetPoll'; d: {$ifndef FPC}@{$endif}@PQresetPoll), + (n: 'PQreset'; d: {$ifndef FPC}@{$endif}@PQreset), + (n: 'PQrequestCancel'; d: {$ifndef FPC}@{$endif}@PQrequestCancel), + (n: 'PQdb'; d: {$ifndef FPC}@{$endif}@PQdb), + (n: 'PQuser'; d: {$ifndef FPC}@{$endif}@PQuser), + (n: 'PQpass'; d: {$ifndef FPC}@{$endif}@PQpass), + (n: 'PQhost'; d: {$ifndef FPC}@{$endif}@PQhost), + (n: 'PQport'; d: {$ifndef FPC}@{$endif}@PQport), + (n: 'PQtty'; d: {$ifndef FPC}@{$endif}@PQtty), + (n: 'PQoptions'; d: {$ifndef FPC}@{$endif}@PQoptions), + (n: 'PQstatus'; d: {$ifndef FPC}@{$endif}@PQstatus), + (n: 'PQtransactionStatus'; d: {$ifndef FPC}@{$endif}@PQtransactionStatus), + (n: 'PQparameterStatus'; d: {$ifndef FPC}@{$endif}@PQparameterStatus), + (n: 'PQprotocolVersion'; d: {$ifndef FPC}@{$endif}@PQprotocolVersion), + (n: 'PQerrorMessage'; d: {$ifndef FPC}@{$endif}@PQerrorMessage), + (n: 'PQsocket'; d: {$ifndef FPC}@{$endif}@PQsocket), + (n: 'PQbackendPID'; d: {$ifndef FPC}@{$endif}@PQbackendPID), + (n: 'PQclientEncoding'; d: {$ifndef FPC}@{$endif}@PQclientEncoding), + (n: 'PQsetClientEncoding'; d: {$ifndef FPC}@{$endif}@PQsetClientEncoding), + (n: 'PQsetErrorVerbosity'; d: {$ifndef FPC}@{$endif}@PQsetErrorVerbosity), + (n: 'PQtrace'; d: {$ifndef FPC}@{$endif}@PQtrace), + (n: 'PQuntrace'; d: {$ifndef FPC}@{$endif}@PQuntrace), + (n: 'PQsetNoticeReceiver'; d: {$ifndef FPC}@{$endif}@PQsetNoticeReceiver), + (n: 'PQsetNoticeProcessor'; d: {$ifndef FPC}@{$endif}@PQsetNoticeProcessor), + (n: 'PQexec'; d: {$ifndef FPC}@{$endif}@PQexec), + (n: 'PQexecParams'; d: {$ifndef FPC}@{$endif}@PQexecParams), + (n: 'PQexecPrepared'; d: {$ifndef FPC}@{$endif}@PQexecPrepared), + (n: 'PQprepare'; d: {$ifndef FPC}@{$endif}@PQprepare), + (n: 'PQsendQuery'; d: {$ifndef FPC}@{$endif}@PQsendQuery), + (n: 'PQsendQueryParams'; d: {$ifndef FPC}@{$endif}@PQsendQueryParams), + (n: 'PQsendQueryPrepared'; d: {$ifndef FPC}@{$endif}@PQsendQueryPrepared), + (n: 'PQgetResult'; d: {$ifndef FPC}@{$endif}@PQgetResult), + (n: 'PQisBusy'; d: {$ifndef FPC}@{$endif}@PQisBusy), + (n: 'PQconsumeInput'; d: {$ifndef FPC}@{$endif}@PQconsumeInput), + (n: 'PQnotifies'; d: {$ifndef FPC}@{$endif}@PQnotifies), + (n: 'PQputCopyData'; d: {$ifndef FPC}@{$endif}@PQputCopyData), + (n: 'PQputCopyEnd'; d: {$ifndef FPC}@{$endif}@PQputCopyEnd), + (n: 'PQgetCopyData'; d: {$ifndef FPC}@{$endif}@PQgetCopyData), + (n: 'PQgetline'; d: {$ifndef FPC}@{$endif}@PQgetline), + (n: 'PQputline'; d: {$ifndef FPC}@{$endif}@PQputline), + (n: 'PQgetlineAsync'; d: {$ifndef FPC}@{$endif}@PQgetlineAsync), + (n: 'PQputnbytes'; d: {$ifndef FPC}@{$endif}@PQputnbytes), + (n: 'PQendcopy'; d: {$ifndef FPC}@{$endif}@PQendcopy), + (n: 'PQsetnonblocking'; d: {$ifndef FPC}@{$endif}@PQsetnonblocking), + (n: 'PQisnonblocking'; d: {$ifndef FPC}@{$endif}@PQisnonblocking), + (n: 'PQflush'; d: {$ifndef FPC}@{$endif}@PQflush), + (n: 'PQfn'; d: {$ifndef FPC}@{$endif}@PQfn), + (n: 'PQresultStatus'; d: {$ifndef FPC}@{$endif}@PQresultStatus), + (n: 'PQresStatus'; d: {$ifndef FPC}@{$endif}@PQresStatus), + (n: 'PQresultErrorMessage'; d: {$ifndef FPC}@{$endif}@PQresultErrorMessage), + (n: 'PQresultErrorField'; d: {$ifndef FPC}@{$endif}@PQresultErrorField), + (n: 'PQntuples'; d: {$ifndef FPC}@{$endif}@PQntuples), + (n: 'PQnfields'; d: {$ifndef FPC}@{$endif}@PQnfields), + (n: 'PQbinaryTuples'; d: {$ifndef FPC}@{$endif}@PQbinaryTuples), + (n: 'PQfname'; d: {$ifndef FPC}@{$endif}@PQfname), + (n: 'PQfnumber'; d: {$ifndef FPC}@{$endif}@PQfnumber), + (n: 'PQftable'; d: {$ifndef FPC}@{$endif}@PQftable), + (n: 'PQftablecol'; d: {$ifndef FPC}@{$endif}@PQftablecol), + (n: 'PQfformat'; d: {$ifndef FPC}@{$endif}@PQfformat), + (n: 'PQftype'; d: {$ifndef FPC}@{$endif}@PQftype), + (n: 'PQfsize'; d: {$ifndef FPC}@{$endif}@PQfsize), + (n: 'PQfmod'; d: {$ifndef FPC}@{$endif}@PQfmod), + (n: 'PQcmdStatus'; d: {$ifndef FPC}@{$endif}@PQcmdStatus), + (n: 'PQoidStatus'; d: {$ifndef FPC}@{$endif}@PQoidStatus), + (n: 'PQoidValue'; d: {$ifndef FPC}@{$endif}@PQoidValue), + (n: 'PQcmdTuples'; d: {$ifndef FPC}@{$endif}@PQcmdTuples), + (n: 'PQgetvalue'; d: {$ifndef FPC}@{$endif}@PQgetvalue), + (n: 'PQgetlength'; d: {$ifndef FPC}@{$endif}@PQgetlength), + (n: 'PQgetisnull'; d: {$ifndef FPC}@{$endif}@PQgetisnull), + (n: 'PQclear'; d: {$ifndef FPC}@{$endif}@PQclear), + (n: 'PQfreemem'; d: {$ifndef FPC}@{$endif}@PQfreemem), + (n: 'PQmakeEmptyPGresult'; d: {$ifndef FPC}@{$endif}@PQmakeEmptyPGresult), + (n: 'PQescapeString'; d: {$ifndef FPC}@{$endif}@PQescapeString), + (n: 'PQescapeBytea'; d: {$ifndef FPC}@{$endif}@PQescapeBytea), + (n: 'PQunescapeBytea'; d: {$ifndef FPC}@{$endif}@PQunescapeBytea), + (n: 'PQprint'; d: {$ifndef FPC}@{$endif}@PQprint), + (n: 'PQdisplayTuples'; d: {$ifndef FPC}@{$endif}@PQdisplayTuples), + (n: 'PQprintTuples'; d: {$ifndef FPC}@{$endif}@PQprintTuples), + (n: 'lo_open'; d: {$ifndef FPC}@{$endif}@lo_open), + (n: 'lo_close'; d: {$ifndef FPC}@{$endif}@lo_close), + (n: 'lo_read'; d: {$ifndef FPC}@{$endif}@lo_read), + (n: 'lo_write'; d: {$ifndef FPC}@{$endif}@lo_write), + (n: 'lo_lseek'; d: {$ifndef FPC}@{$endif}@lo_lseek), + (n: 'lo_creat'; d: {$ifndef FPC}@{$endif}@lo_creat), + (n: 'lo_tell'; d: {$ifndef FPC}@{$endif}@lo_tell), + (n: 'lo_unlink'; d: {$ifndef FPC}@{$endif}@lo_unlink), + (n: 'lo_import'; d: {$ifndef FPC}@{$endif}@lo_import), + (n: 'lo_export'; d: {$ifndef FPC}@{$endif}@lo_export), + (n: 'PQmblen'; d: {$ifndef FPC}@{$endif}@PQmblen), + (n: 'PQenv2encoding'; d: {$ifndef FPC}@{$endif}@PQenv2encoding) + ); + + funcsopt: array[0..13] of funcinfoty = ( + (n: 'PQgetssl'; d: {$ifndef FPC}@{$endif}@PQgetssl), + + (n: 'DLNewList'; d: {$ifndef FPC}@{$endif}@DLNewList), //these functions seem not to be exported by + (n: 'DLFreeList'; d: {$ifndef FPC}@{$endif}@DLFreeList),//pqlib?? + (n: 'DLNewElem'; d: {$ifndef FPC}@{$endif}@DLNewElem), + (n: 'DLFreeElem'; d: {$ifndef FPC}@{$endif}@DLFreeElem), + (n: 'DLGetHead'; d: {$ifndef FPC}@{$endif}@DLGetHead), + (n: 'DLGetTail'; d: {$ifndef FPC}@{$endif}@DLGetTail), + (n: 'DLRemTail'; d: {$ifndef FPC}@{$endif}@DLRemTail), + (n: 'DLGetPred'; d: {$ifndef FPC}@{$endif}@DLGetPred), + (n: 'DLGetSucc'; d: {$ifndef FPC}@{$endif}@DLGetSucc), + (n: 'DLRemove'; d: {$ifndef FPC}@{$endif}@DLRemove), + (n: 'DLAddHead'; d: {$ifndef FPC}@{$endif}@DLAddHead), + (n: 'DLAddTail'; d: {$ifndef FPC}@{$endif}@DLAddTail), + (n: 'DLRemHead'; d: {$ifndef FPC}@{$endif}@DLRemHead) + ); + errormessage = 'Can not load Postgres library. '; +begin + initializedynlib(libinfo,sonames,postgreslib,funcs,funcsopt,errormessage); +end; + +procedure releasepostgres3; +begin + releasedynlib(libinfo); +end; + +initialization + initializelibinfo(libinfo); +finalization + finalizelibinfo(libinfo); +end. diff --git a/mseide-msegui/lib/common/db/sqlite3dyn.pas b/mseide-msegui/lib/common/db/sqlite3dyn.pas new file mode 100644 index 0000000..4917e59 --- /dev/null +++ b/mseide-msegui/lib/common/db/sqlite3dyn.pas @@ -0,0 +1,948 @@ +unit sqlite3dyn; +{$ifdef FPC}{$mode objfpc} {$h+}{$endif} + +{$ifdef BSD} + {$linklib c} + {$linklib pthread} +{$endif} + +// use mse_sqlite3static for static linking of the SQLite3 library +// + +interface +uses + {msesonames,}msedynload,msetypes{msestrings}{$ifndef FPC}{$endif}; +const +{$ifdef mswindows} + sqlite3lib: array[0..0] of filenamety = ('sqlite3.dll'); +{$else} + sqlite3lib: array[0..1] of filenamety = ('libsqlite3.so.0','libsqlite3.so'); +{$endif} + +{ + Automatically converted by H2Pas 0.99.16 from sqlite3.h + The following command line parameters were used: + -D + -c + sqlite3.h + + Manual corrections made by Luiz Am?rico - 2005 + Martin Schreiber 2007 +} + +procedure initializesqlite3(const sonames: array of filenamety); //[] = default +procedure releasesqlite3; + +{$ifdef FPC} + {$PACKRECORDS C} +{$else} + {$ALIGN 4} + {$MINENUMSIZE 4} +{$endif} +const + +{$ifdef mse_sqlite3static} + {$ifdef mswindows} + sqlite3lib = 'sqlite3.dll'; + {$else} + sqlite3lib = 'libsqlite3.so'; + {$endif} +{$endif} + + SQLITE_INTEGER = 1; + SQLITE_FLOAT = 2; +{ #define SQLITE_TEXT 3 // See below } + SQLITE_BLOB = 4; + SQLITE_NULL = 5; + SQLITE_TEXT = 3; + SQLITE3_TEXT = 3; + SQLITE_UTF8 = 1; + SQLITE_UTF16LE = 2; + SQLITE_UTF16BE = 3; +{ Use native byte order } + SQLITE_UTF16 = 4; +{ sqlite3_create_function only } + SQLITE_ANY = 5; + + //sqlite_exec return values + SQLITE_OK = 0; + SQLITE_ERROR = 1;{ SQL error or missing database } + SQLITE_INTERNAL = 2;{ An internal logic error in SQLite } + SQLITE_PERM = 3; { Access permission denied } + SQLITE_ABORT = 4; { Callback routine requested an abort } + SQLITE_BUSY = 5; { The database file is locked } + SQLITE_LOCKED = 6;{ A table in the database is locked } + SQLITE_NOMEM = 7; { A malloc() failed } + SQLITE_READONLY = 8;{ Attempt to write a readonly database } + SQLITE_INTERRUPT = 9;{ Operation terminated by sqlite3_interrupt() } + SQLITE_IOERR = 10; { Some kind of disk I/O error occurred } + SQLITE_CORRUPT = 11; { The database disk image is malformed } + SQLITE_NOTFOUND = 12; { (Internal Only) Table or record not found } + SQLITE_FULL = 13; { Insertion failed because database is full } + SQLITE_CANTOPEN = 14; { Unable to open the database file } + SQLITE_PROTOCOL = 15; { Database lock protocol error } + SQLITE_EMPTY = 16; { Database is empty } + SQLITE_SCHEMA = 17; { The database schema changed } + SQLITE_TOOBIG = 18; { Too much data for one row of a table } + SQLITE_CONSTRAINT = 19; { Abort due to contraint violation } + SQLITE_MISMATCH = 20; { Data type mismatch } + SQLITE_MISUSE = 21; { Library used incorrectly } + SQLITE_NOLFS = 22; { Uses OS features not supported on host } + SQLITE_AUTH = 23; { Authorization denied } + SQLITE_FORMAT = 24; { Auxiliary database format error } + SQLITE_RANGE = 25; { 2nd parameter to sqlite3_bind out of range } + SQLITE_NOTADB = 26; { File opened that is not a database file } + SQLITE_ROW = 100; { sqlite3_step() has another row ready } + SQLITE_DONE = 101; { sqlite3_step() has finished executing } + + sqliteerrormax = 99; + +type + sqlite_int64 = int64; + sqlite_uint64 = qword; + PPPChar = ^PPChar; + Psqlite3 = Pointer; + PPSqlite3 = ^PSqlite3; + Psqlite3_context = Pointer; + Psqlite3_stmt = Pointer; + PPsqlite3_stmt = ^Psqlite3_stmt; + Psqlite3_value = Pointer; + PPsqlite3_value = ^Psqlite3_value; + +//Callback function types +//Notice that most functions were named using as prefix the function name that uses them, +//rather than describing their functions + +// sqlite3_callback = function (_para1:pointer; _para2:longint; _para3:PPchar; _para4:PPchar):longint;cdecl; + sqlite3_callback = function (var _para1; _para2:longint; + _para3:PPchar; _para4:PPchar):longint;cdecl; + //@ operator does not work with dynamic arrays, -O2 and FPC 2_2 + busy_handler_func = function (_para1:pointer; _para2:longint):longint;cdecl; + sqlite3_set_authorizer_func = function (_para1:pointer; _para2:longint; _para3:Pchar; _para4:Pchar; _para5:Pchar; _para6:Pchar):longint;cdecl; + sqlite3_trace_func = procedure (_para1:pointer; _para2:Pchar);cdecl; + sqlite3_progress_handler_func = function (_para1:pointer):longint;cdecl; + sqlite3_commit_hook_func = function (_para1:pointer):longint;cdecl; + bind_destructor_func = procedure (_para1:pointer);cdecl; + create_function_step_func = procedure (_para1:Psqlite3_context; _para2:longint; _para3:PPsqlite3_value);cdecl; + create_function_func_func = procedure (_para1:Psqlite3_context; _para2:longint; _para3:PPsqlite3_value);cdecl; + create_function_final_func = procedure (_para1:Psqlite3_context);cdecl; + sqlite3_set_auxdata_func = procedure (_para1:pointer);cdecl; + sqlite3_result_func = procedure (_para1:pointer);cdecl; + sqlite3_create_collation_func = function (_para1:pointer; _para2:longint; _para3:pointer; _para4:longint; _para5:pointer):longint;cdecl; + sqlite3_collation_needed_func = procedure (_para1:pointer; _para2:Psqlite3; eTextRep:longint; _para4:Pchar);cdecl; + +//{$ifndef win32} +//var +// //This is not working under windows. Any clues? +// sqlite3_temp_directory : Pchar;cvar;external; +//{$endif} + +const + SQLITE_COPY = 0; +{ Index Name Table Name } + SQLITE_CREATE_INDEX = 1; +{ Table Name NULL } + SQLITE_CREATE_TABLE = 2; +{ Index Name Table Name } + SQLITE_CREATE_TEMP_INDEX = 3; +{ Table Name NULL } + SQLITE_CREATE_TEMP_TABLE = 4; +{ Trigger Name Table Name } + SQLITE_CREATE_TEMP_TRIGGER = 5; +{ View Name NULL } + SQLITE_CREATE_TEMP_VIEW = 6; +{ Trigger Name Table Name } + SQLITE_CREATE_TRIGGER = 7; +{ View Name NULL } + SQLITE_CREATE_VIEW = 8; +{ Table Name NULL } + SQLITE_DELETE = 9; +{ Index Name Table Name } + SQLITE_DROP_INDEX = 10; +{ Table Name NULL } + SQLITE_DROP_TABLE = 11; +{ Index Name Table Name } + SQLITE_DROP_TEMP_INDEX = 12; +{ Table Name NULL } + SQLITE_DROP_TEMP_TABLE = 13; +{ Trigger Name Table Name } + SQLITE_DROP_TEMP_TRIGGER = 14; +{ View Name NULL } + SQLITE_DROP_TEMP_VIEW = 15; +{ Trigger Name Table Name } + SQLITE_DROP_TRIGGER = 16; +{ View Name NULL } + SQLITE_DROP_VIEW = 17; +{ Table Name NULL } + SQLITE_INSERT = 18; +{ Pragma Name 1st arg or NULL } + SQLITE_PRAGMA = 19; +{ Table Name Column Name } + SQLITE_READ = 20; +{ NULL NULL } + SQLITE_SELECT = 21; +{ NULL NULL } + SQLITE_TRANSACTION = 22; +{ Table Name Column Name } + SQLITE_UPDATE = 23; +{ Filename NULL } + SQLITE_ATTACH = 24; +{ Database Name NULL } + SQLITE_DETACH = 25; +{ Database Name Table Name } + SQLITE_ALTER_TABLE = 26; +{ Index Name NULL } + SQLITE_REINDEX = 27; + +{ #define SQLITE_OK 0 // Allow access (This is actually defined above) } +{ Abort the SQL statement with an error } + SQLITE_DENY = 1; +{ Don't allow access, but don't generate an error } + SQLITE_IGNORE = 2; + +// Original from sqlite3.h: +//#define SQLITE_STATIC ((void(*)(void *))0) +//#define SQLITE_TRANSIENT ((void(*)(void *))-1) +Const + SQLITE_STATIC = 0; + SQLITE_TRANSIENT = -1; + +{$ifdef mse_sqlite3static} + function sqlite3_close(_para1:Psqlite3):longint; cdecl; external sqlite3lib; +// sqlite3_exec: function(_para1: Psqlite3; sql: Pchar; _para3: sqlite3_callback; +// _para4: pointer; errmsg: PPchar): longint; cdecl; + function sqlite3_exec(_para1: Psqlite3; sql: Pchar; _para3: sqlite3_callback; + var _para4; errmsg: PPchar): longint; cdecl; external sqlite3lib; + function sqlite3_last_insert_rowid(_para1: Psqlite3): sqlite_int64; cdecl; external sqlite3lib; + function sqlite3_changes(_para1: Psqlite3): longint; cdecl; external sqlite3lib; + function sqlite3_total_changes(_para1: Psqlite3): longint; cdecl; external sqlite3lib; + procedure sqlite3_interrupt(_para1: Psqlite3); cdecl; external sqlite3lib; + function sqlite3_complete(sql: Pchar): longint; cdecl; external sqlite3lib; + function sqlite3_complete16(sql: pointer):longint; cdecl; external sqlite3lib; + function sqlite3_busy_handler(_para1: Psqlite3; _para2: busy_handler_func; + _para3: pointer):longint; cdecl; external sqlite3lib; + function sqlite3_busy_timeout(_para1: Psqlite3; ms: longint):longint; cdecl; external sqlite3lib; + function sqlite3_get_table(_para1: Psqlite3; sql: Pchar; resultp: PPPchar; + nrow: Plongint; ncolumn: Plongint; errmsg: PPchar):longint;cdecl; external sqlite3lib; + procedure sqlite3_free_table(result:PPchar);cdecl; external sqlite3lib; + +// Todo: see how translate sqlite3_mprintf, sqlite3_vmprintf, sqlite3_snprintf +// function sqlite3_mprintf(_para1:Pchar; args:array of const):Pchar;cdecl;external External_library name 'sqlite3_mprintf'; + function sqlite3_mprintf(_para1:Pchar):Pchar;cdecl; external sqlite3lib; +//function sqlite3_vmprintf(_para1:Pchar; _para2:va_list):Pchar;cdecl;external External_library name 'sqlite3_vmprintf'; + procedure sqlite3_free(z:Pchar);cdecl; external sqlite3lib; +//function sqlite3_snprintf(_para1:longint; _para2:Pchar; _para3:Pchar; args:array of const):Pchar;cdecl;external External_library name 'sqlite3_snprintf'; + function sqlite3_snprintf(_para1:longint; _para2:Pchar; _para3:Pchar):Pchar;cdecl; external sqlite3lib; + + function sqlite3_set_authorizer(_para1:Psqlite3; xAuth:sqlite3_set_authorizer_func; pUserData:pointer):longint;cdecl; external sqlite3lib; + + + function sqlite3_trace(_para1:Psqlite3; xTrace:sqlite3_trace_func; + _para3:pointer):pointer;cdecl; external sqlite3lib; + procedure sqlite3_progress_handler(_para1:Psqlite3; _para2:longint; + _para3:sqlite3_progress_handler_func; _para4:pointer);cdecl; external sqlite3lib; + function sqlite3_commit_hook(_para1:Psqlite3; + _para2:sqlite3_commit_hook_func; _para3:pointer):pointer;cdecl; external sqlite3lib; + function sqlite3_open(filename:Pchar; ppDb:PPsqlite3):longint;cdecl; external sqlite3lib; + function sqlite3_open16(filename:pointer; ppDb:PPsqlite3):longint;cdecl; external sqlite3lib; + function sqlite3_errcode(db:Psqlite3):longint;cdecl; external sqlite3lib; + function sqlite3_errmsg(_para1:Psqlite3):Pchar;cdecl; external sqlite3lib; + function sqlite3_errmsg16(_para1:Psqlite3):pointer;cdecl; external sqlite3lib; + function sqlite3_prepare(db:Psqlite3; zSql:Pchar; nBytes:longint; + ppStmt:PPsqlite3_stmt; pzTail:PPchar):longint;cdecl; external sqlite3lib; + function sqlite3_prepare16(db:Psqlite3; zSql:pointer; nBytes:longint; + ppStmt:PPsqlite3_stmt; pzTail:Ppointer):longint;cdecl; external sqlite3lib; +// sqlite3_prepare_v2: function(db:Psqlite3; zSql:Pchar; nBytes:longint; +// ppStmt:PPsqlite3_stmt; pzTail:PPchar):longint;cdecl; external sqlite3lib; +// sqlite3_prepare16_v2: function(db:Psqlite3; zSql:pointer; nBytes:longint; +// ppStmt:PPsqlite3_stmt; pzTail:Ppointer):longint;cdecl; external sqlite3lib; + function sqlite3_bind_blob(_para1:Psqlite3_stmt; _para2:longint; + _para3:pointer; n:longint; _para5:bind_destructor_func):longint;cdecl; external sqlite3lib; + function sqlite3_bind_double(_para1:Psqlite3_stmt; _para2:longint; + _para3:double):longint;cdecl; external sqlite3lib; + function sqlite3_bind_int(_para1:Psqlite3_stmt; _para2:longint; + _para3:longint):longint;cdecl; external sqlite3lib; + function sqlite3_bind_int64(_para1:Psqlite3_stmt; _para2:longint; + _para3:sqlite_int64):longint;cdecl; external sqlite3lib; + function sqlite3_bind_null(_para1:Psqlite3_stmt; + _para2:longint):longint;cdecl; external sqlite3lib; + function sqlite3_bind_text(_para1:Psqlite3_stmt; _para2:longint; + _para3:Pchar; n:longint; _para5:bind_destructor_func):longint;cdecl; external sqlite3lib; + function sqlite3_bind_text16(_para1:Psqlite3_stmt; _para2:longint; + _para3:pointer; _para4:longint; _para5:bind_destructor_func):longint;cdecl; external sqlite3lib; +//function sqlite3_bind_value(_para1:Psqlite3_stmt; _para2:longint; _para3:Psqlite3_value):longint;cdecl; external sqlite3lib;external External_library name 'sqlite3_bind_value'; + + +//These overloaded functions were introduced to allow the use of SQLITE_STATIC and SQLITE_TRANSIENT +//It's the c world man ;-) + function sqlite3_bind_blob1(_para1:Psqlite3_stmt; _para2:longint; + _para3:pointer; n:longint; _para5:longint):longint;cdecl; external sqlite3lib; + function sqlite3_bind_text1(_para1:Psqlite3_stmt; _para2:longint; + _para3:Pchar; n:longint; _para5:longint):longint;cdecl; external sqlite3lib; + function sqlite3_bind_text161(_para1:Psqlite3_stmt; _para2:longint; + _para3:pointer; _para4:longint; _para5:longint):longint;cdecl; external sqlite3lib; + + function sqlite3_bind_parameter_count(_para1:Psqlite3_stmt):longint;cdecl; external sqlite3lib; + function sqlite3_bind_parameter_name(_para1:Psqlite3_stmt; + _para2:longint):Pchar;cdecl; external sqlite3lib; + function sqlite3_bind_parameter_index(_para1:Psqlite3_stmt; + zName:Pchar):longint;cdecl; external sqlite3lib; + function sqlite3_clear_bindings(_para1:Psqlite3_stmt):longint;cdecl; external sqlite3lib; + function sqlite3_column_count(pStmt:Psqlite3_stmt):longint;cdecl; external sqlite3lib; + function sqlite3_column_name(_para1:Psqlite3_stmt; + _para2:longint):Pchar;cdecl; external sqlite3lib; + function sqlite3_column_name16(_para1:Psqlite3_stmt; + _para2:longint):pointer;cdecl; external sqlite3lib; + function sqlite3_column_decltype(_para1:Psqlite3_stmt; + i:longint):Pchar;cdecl; external sqlite3lib; + function sqlite3_column_decltype16(_para1:Psqlite3_stmt; + _para2:longint):pointer;cdecl; external sqlite3lib; + function sqlite3_step(_para1:Psqlite3_stmt):longint;cdecl; external sqlite3lib; + function sqlite3_data_count(pStmt:Psqlite3_stmt):longint;cdecl; external sqlite3lib; + function sqlite3_column_blob(_para1:Psqlite3_stmt; + iCol:longint):pointer;cdecl; external sqlite3lib; + function sqlite3_column_bytes(_para1:Psqlite3_stmt; + iCol:longint):longint;cdecl; external sqlite3lib; + function sqlite3_column_bytes16(_para1:Psqlite3_stmt; + iCol:longint):longint;cdecl; external sqlite3lib; + function sqlite3_column_double(_para1:Psqlite3_stmt; + iCol:longint):double;cdecl; external sqlite3lib; + function sqlite3_column_int(_para1:Psqlite3_stmt; + iCol:longint):longint;cdecl; external sqlite3lib; + function sqlite3_column_int64(_para1:Psqlite3_stmt; + iCol:longint):sqlite_int64;cdecl; external sqlite3lib; + function sqlite3_column_text(_para1:Psqlite3_stmt; + iCol:longint):PChar;cdecl; external sqlite3lib; + function sqlite3_column_text16(_para1:Psqlite3_stmt; + iCol:longint):pointer;cdecl; external sqlite3lib; + function sqlite3_column_type(_para1:Psqlite3_stmt; iCol:longint):longint;cdecl; external sqlite3lib; + function sqlite3_finalize(pStmt:Psqlite3_stmt):longint;cdecl; external sqlite3lib; + function sqlite3_reset(pStmt:Psqlite3_stmt):longint;cdecl; external sqlite3lib; + function sqlite3_create_function(_para1:Psqlite3; zFunctionName:Pchar; + nArg:longint; eTextRep:longint; _para5:pointer; + xFunc:create_function_func_func; xStep:create_function_step_func; + xFinal:create_function_final_func):longint;cdecl; external sqlite3lib; + function sqlite3_create_function16(_para1:Psqlite3; zFunctionName:pointer; + nArg:longint; eTextRep:longint; _para5:pointer; + xFunc:create_function_func_func; xStep:create_function_step_func; + xFinal:create_function_final_func):longint;cdecl; external sqlite3lib; + function sqlite3_aggregate_count(_para1:Psqlite3_context):longint;cdecl; external sqlite3lib; + function sqlite3_value_blob(_para1:Psqlite3_value):pointer;cdecl; external sqlite3lib; + function sqlite3_value_bytes(_para1:Psqlite3_value):longint;cdecl; external sqlite3lib; + function sqlite3_value_bytes16(_para1:Psqlite3_value):longint;cdecl; external sqlite3lib; + function sqlite3_value_double(_para1:Psqlite3_value):double;cdecl; external sqlite3lib; + function sqlite3_value_int(_para1:Psqlite3_value):longint;cdecl; external sqlite3lib; + function sqlite3_value_int64(_para1:Psqlite3_value):sqlite_int64;cdecl; external sqlite3lib; + function sqlite3_value_text(_para1:Psqlite3_value):PChar;cdecl; external sqlite3lib; + function sqlite3_value_text16(_para1:Psqlite3_value):pointer;cdecl; external sqlite3lib; + function sqlite3_value_text16le(_para1:Psqlite3_value):pointer;cdecl; external sqlite3lib; + function sqlite3_value_text16be(_para1:Psqlite3_value):pointer;cdecl; external sqlite3lib; + function sqlite3_value_type(_para1:Psqlite3_value):longint;cdecl; external sqlite3lib; + function sqlite3_aggregate_context(_para1:Psqlite3_context; + nBytes:longint):pointer;cdecl; external sqlite3lib; + function sqlite3_user_data(_para1:Psqlite3_context):pointer;cdecl; external sqlite3lib; + function sqlite3_get_auxdata(_para1:Psqlite3_context; + _para2:longint):pointer;cdecl; external sqlite3lib; + procedure sqlite3_set_auxdata(_para1:Psqlite3_context; _para2:longint; + _para3:pointer; _para4:sqlite3_set_auxdata_func);cdecl; external sqlite3lib; + procedure sqlite3_result_blob(_para1:Psqlite3_context; _para2:pointer; + _para3:longint; _para4:sqlite3_result_func);cdecl; external sqlite3lib; + procedure sqlite3_result_double(_para1:Psqlite3_context; + _para2:double);cdecl; external sqlite3lib; + procedure sqlite3_result_error(_para1:Psqlite3_context; + _para2:Pchar; _para3:longint);cdecl; external sqlite3lib; + procedure sqlite3_result_error16(_para1:Psqlite3_context; + _para2:pointer; _para3:longint);cdecl; external sqlite3lib; + procedure sqlite3_result_int(_para1:Psqlite3_context; _para2:longint);cdecl; external sqlite3lib; + procedure sqlite3_result_int64(_para1:Psqlite3_context; + _para2:sqlite_int64);cdecl; external sqlite3lib; + procedure sqlite3_result_null(_para1:Psqlite3_context);cdecl; external sqlite3lib; + procedure sqlite3_result_text(_para1:Psqlite3_context; _para2:Pchar; + _para3:longint; _para4:sqlite3_result_func);cdecl; external sqlite3lib; + procedure sqlite3_result_text16(_para1:Psqlite3_context; _para2:pointer; + _para3:longint; _para4:sqlite3_result_func);cdecl; external sqlite3lib; + procedure sqlite3_result_text16le(_para1:Psqlite3_context; _para2:pointer; + _para3:longint; _para4:sqlite3_result_func);cdecl; external sqlite3lib; + procedure sqlite3_result_text16be(_para1:Psqlite3_context; _para2:pointer; + _para3:longint; _para4:sqlite3_result_func);cdecl; external sqlite3lib; + procedure sqlite3_result_value(_para1:Psqlite3_context; + _para2:Psqlite3_value);cdecl; external sqlite3lib; + + function sqlite3_create_collation(_para1:Psqlite3; zName:Pchar; + eTextRep:longint; _para4:pointer; + xCompare:sqlite3_create_collation_func):longint;cdecl; external sqlite3lib; + function sqlite3_create_collation16(_para1:Psqlite3; zName:Pchar; + eTextRep:longint; _para4:pointer; + xCompare:sqlite3_create_collation_func):longint;cdecl; external sqlite3lib; + + function sqlite3_collation_needed(_para1:Psqlite3; _para2:pointer; + _para3:sqlite3_collation_needed_func):longint;cdecl; external sqlite3lib; + function sqlite3_collation_needed16(_para1:Psqlite3; _para2:pointer; + _para3:sqlite3_collation_needed_func):longint;cdecl; external sqlite3lib; + + function sqlite3_libversion:PChar;cdecl; external sqlite3lib; +//Alias for allowing better code portability (win32 is not working with external variables) + function sqlite3_version: PChar;cdecl; external sqlite3lib; + +// Not published functions + function sqlite3_libversion_number:longint;cdecl; external sqlite3lib; +// sqlite3_key: function(db:Psqlite3; pKey:pointer; nKey:longint):longint;cdecl; external sqlite3lib; +// sqlite3_rekey: function(db:Psqlite3; pKey:pointer; nKey:longint):longint;cdecl; external sqlite3lib; +// sqlite3_sleep: function(_para1:longint):longint;cdecl; external sqlite3lib; +// sqlite3_expired: function(_para1:Psqlite3_stmt):longint;cdecl; external sqlite3lib; +// sqlite3_global_recover: function:longint;cdecl; external sqlite3lib; +{$else} +var + sqlite3_close: function(_para1:Psqlite3):longint; cdecl; +// sqlite3_exec: function(_para1: Psqlite3; sql: Pchar; _para3: sqlite3_callback; +// _para4: pointer; errmsg: PPchar): longint; cdecl; + sqlite3_exec: function(_para1: Psqlite3; sql: Pchar; _para3: sqlite3_callback; + var _para4; errmsg: PPchar): longint; cdecl; + sqlite3_last_insert_rowid: function(_para1: Psqlite3): sqlite_int64; cdecl; + sqlite3_changes: function(_para1: Psqlite3): longint; cdecl; + sqlite3_total_changes: function(_para1: Psqlite3): longint; cdecl; + sqlite3_interrupt: procedure(_para1: Psqlite3); cdecl; + sqlite3_complete: function(sql: Pchar): longint; cdecl; + sqlite3_complete16: function(sql: pointer):longint; cdecl; + sqlite3_busy_handler: function(_para1: Psqlite3; _para2: busy_handler_func; + _para3: pointer):longint; cdecl; + sqlite3_busy_timeout: function(_para1: Psqlite3; ms: longint):longint; cdecl; + sqlite3_get_table: function(_para1: Psqlite3; sql: Pchar; resultp: PPPchar; + nrow: Plongint; ncolumn: Plongint; errmsg: PPchar):longint;cdecl; + sqlite3_free_table: procedure(result:PPchar);cdecl; + +// Todo: see how translate sqlite3_mprintf, sqlite3_vmprintf, sqlite3_snprintf +// function sqlite3_mprintf(_para1:Pchar; args:array of const):Pchar;cdecl;external External_library name 'sqlite3_mprintf'; + sqlite3_mprintf: function(_para1:Pchar):Pchar;cdecl; +//function sqlite3_vmprintf(_para1:Pchar; _para2:va_list):Pchar;cdecl;external External_library name 'sqlite3_vmprintf'; + sqlite3_free: procedure(z:Pchar);cdecl; +//function sqlite3_snprintf(_para1:longint; _para2:Pchar; _para3:Pchar; args:array of const):Pchar;cdecl;external External_library name 'sqlite3_snprintf'; + sqlite3_snprintf: function(_para1:longint; _para2:Pchar; _para3:Pchar):Pchar;cdecl; + + sqlite3_set_authorizer: function(_para1:Psqlite3; xAuth:sqlite3_set_authorizer_func; pUserData:pointer):longint;cdecl; + + + sqlite3_trace: function(_para1:Psqlite3; xTrace:sqlite3_trace_func; + _para3:pointer):pointer;cdecl; + sqlite3_progress_handler: procedure(_para1:Psqlite3; _para2:longint; + _para3:sqlite3_progress_handler_func; _para4:pointer);cdecl; + sqlite3_commit_hook: function(_para1:Psqlite3; + _para2:sqlite3_commit_hook_func; _para3:pointer):pointer;cdecl; + sqlite3_open: function(filename:Pchar; ppDb:PPsqlite3):longint;cdecl; + sqlite3_open16: function(filename:pointer; ppDb:PPsqlite3):longint;cdecl; + sqlite3_errcode: function(db:Psqlite3):longint;cdecl; + sqlite3_errmsg: function(_para1:Psqlite3):Pchar;cdecl; + sqlite3_errmsg16: function(_para1:Psqlite3):pointer;cdecl; + sqlite3_prepare: function(db:Psqlite3; zSql:Pchar; nBytes:longint; + ppStmt:PPsqlite3_stmt; pzTail:PPchar):longint;cdecl; + sqlite3_prepare16: function(db:Psqlite3; zSql:pointer; nBytes:longint; + ppStmt:PPsqlite3_stmt; pzTail:Ppointer):longint;cdecl; +// sqlite3_prepare_v2: function(db:Psqlite3; zSql:Pchar; nBytes:longint; +// ppStmt:PPsqlite3_stmt; pzTail:PPchar):longint;cdecl; +// sqlite3_prepare16_v2: function(db:Psqlite3; zSql:pointer; nBytes:longint; +// ppStmt:PPsqlite3_stmt; pzTail:Ppointer):longint;cdecl; + sqlite3_bind_blob: function(_para1:Psqlite3_stmt; _para2:longint; + _para3:pointer; n:longint; _para5:bind_destructor_func):longint;cdecl; + sqlite3_bind_double: function(_para1:Psqlite3_stmt; _para2:longint; + _para3:double):longint;cdecl; + sqlite3_bind_int: function(_para1:Psqlite3_stmt; _para2:longint; + _para3:longint):longint;cdecl; + sqlite3_bind_int64: function(_para1:Psqlite3_stmt; _para2:longint; + _para3:sqlite_int64):longint;cdecl; + sqlite3_bind_null: function(_para1:Psqlite3_stmt; + _para2:longint):longint;cdecl; + sqlite3_bind_text: function(_para1:Psqlite3_stmt; _para2:longint; + _para3:Pchar; n:longint; _para5:bind_destructor_func):longint;cdecl; + sqlite3_bind_text16: function(_para1:Psqlite3_stmt; _para2:longint; + _para3:pointer; _para4:longint; _para5:bind_destructor_func):longint;cdecl; +//function sqlite3_bind_value(_para1:Psqlite3_stmt; _para2:longint; _para3:Psqlite3_value):longint;cdecl;external External_library name 'sqlite3_bind_value'; + + +//These overloaded functions were introduced to allow the use of SQLITE_STATIC and SQLITE_TRANSIENT +//It's the c world man ;-) + sqlite3_bind_blob1: function(_para1:Psqlite3_stmt; _para2:longint; + _para3:pointer; n:longint; _para5:longint):longint;cdecl; + sqlite3_bind_text1: function(_para1:Psqlite3_stmt; _para2:longint; + _para3:Pchar; n:longint; _para5:longint):longint;cdecl; + sqlite3_bind_text161: function(_para1:Psqlite3_stmt; _para2:longint; + _para3:pointer; _para4:longint; _para5:longint):longint;cdecl; + + sqlite3_bind_parameter_count: function(_para1:Psqlite3_stmt):longint;cdecl; + sqlite3_bind_parameter_name: function(_para1:Psqlite3_stmt; + _para2:longint):Pchar;cdecl; + sqlite3_bind_parameter_index: function(_para1:Psqlite3_stmt; + zName:Pchar):longint;cdecl; + sqlite3_clear_bindings: function(_para1:Psqlite3_stmt):longint;cdecl; + sqlite3_column_count: function(pStmt:Psqlite3_stmt):longint;cdecl; + sqlite3_column_name: function(_para1:Psqlite3_stmt; + _para2:longint):Pchar;cdecl; + sqlite3_column_name16: function(_para1:Psqlite3_stmt; + _para2:longint):pointer;cdecl; + sqlite3_column_decltype: function(_para1:Psqlite3_stmt; + i:longint):Pchar;cdecl; + sqlite3_column_decltype16: function(_para1:Psqlite3_stmt; + _para2:longint):pointer;cdecl; + sqlite3_step: function(_para1:Psqlite3_stmt):longint;cdecl; + sqlite3_data_count: function(pStmt:Psqlite3_stmt):longint;cdecl; + sqlite3_column_blob: function(_para1:Psqlite3_stmt; + iCol:longint):pointer;cdecl; + sqlite3_column_bytes: function(_para1:Psqlite3_stmt; + iCol:longint):longint;cdecl; + sqlite3_column_bytes16: function(_para1:Psqlite3_stmt; + iCol:longint):longint;cdecl; + sqlite3_column_double: function(_para1:Psqlite3_stmt; + iCol:longint):double;cdecl; + sqlite3_column_int: function(_para1:Psqlite3_stmt; + iCol:longint):longint;cdecl; + sqlite3_column_int64: function(_para1:Psqlite3_stmt; + iCol:longint):sqlite_int64;cdecl; + sqlite3_column_text: function(_para1:Psqlite3_stmt; + iCol:longint):PChar;cdecl; + sqlite3_column_text16: function(_para1:Psqlite3_stmt; + iCol:longint):pointer;cdecl; + sqlite3_column_type: function(_para1:Psqlite3_stmt; iCol:longint):longint;cdecl; + sqlite3_finalize: function(pStmt:Psqlite3_stmt):longint;cdecl; + sqlite3_reset: function(pStmt:Psqlite3_stmt):longint;cdecl; + sqlite3_create_function: function(_para1:Psqlite3; zFunctionName:Pchar; + nArg:longint; eTextRep:longint; _para5:pointer; + xFunc:create_function_func_func; xStep:create_function_step_func; + xFinal:create_function_final_func):longint;cdecl; + sqlite3_create_function16: function(_para1:Psqlite3; zFunctionName:pointer; + nArg:longint; eTextRep:longint; _para5:pointer; + xFunc:create_function_func_func; xStep:create_function_step_func; + xFinal:create_function_final_func):longint;cdecl; + sqlite3_aggregate_count: function(_para1:Psqlite3_context):longint;cdecl; + sqlite3_value_blob: function(_para1:Psqlite3_value):pointer;cdecl; + sqlite3_value_bytes: function(_para1:Psqlite3_value):longint;cdecl; + sqlite3_value_bytes16: function(_para1:Psqlite3_value):longint;cdecl; + sqlite3_value_double: function(_para1:Psqlite3_value):double;cdecl; + sqlite3_value_int: function(_para1:Psqlite3_value):longint;cdecl; + sqlite3_value_int64: function(_para1:Psqlite3_value):sqlite_int64;cdecl; + sqlite3_value_text: function(_para1:Psqlite3_value):PChar;cdecl; + sqlite3_value_text16: function(_para1:Psqlite3_value):pointer;cdecl; + sqlite3_value_text16le: function(_para1:Psqlite3_value):pointer;cdecl; + sqlite3_value_text16be: function(_para1:Psqlite3_value):pointer;cdecl; + sqlite3_value_type: function(_para1:Psqlite3_value):longint;cdecl; + sqlite3_aggregate_context: function(_para1:Psqlite3_context; + nBytes:longint):pointer;cdecl; + sqlite3_user_data: function(_para1:Psqlite3_context):pointer;cdecl; + sqlite3_get_auxdata: function(_para1:Psqlite3_context; + _para2:longint):pointer;cdecl; + sqlite3_set_auxdata: procedure(_para1:Psqlite3_context; _para2:longint; + _para3:pointer; _para4:sqlite3_set_auxdata_func);cdecl; + sqlite3_result_blob: procedure(_para1:Psqlite3_context; _para2:pointer; + _para3:longint; _para4:sqlite3_result_func);cdecl; + sqlite3_result_double: procedure(_para1:Psqlite3_context; + _para2:double);cdecl; + sqlite3_result_error: procedure(_para1:Psqlite3_context; + _para2:Pchar; _para3:longint);cdecl; + sqlite3_result_error16: procedure(_para1:Psqlite3_context; + _para2:pointer; _para3:longint);cdecl; + sqlite3_result_int: procedure(_para1:Psqlite3_context; _para2:longint);cdecl; + sqlite3_result_int64: procedure(_para1:Psqlite3_context; + _para2:sqlite_int64);cdecl; + sqlite3_result_null: procedure(_para1:Psqlite3_context);cdecl; + sqlite3_result_text: procedure(_para1:Psqlite3_context; _para2:Pchar; + _para3:longint; _para4:sqlite3_result_func);cdecl; + sqlite3_result_text16: procedure(_para1:Psqlite3_context; _para2:pointer; + _para3:longint; _para4:sqlite3_result_func);cdecl; + sqlite3_result_text16le: procedure(_para1:Psqlite3_context; _para2:pointer; + _para3:longint; _para4:sqlite3_result_func);cdecl; + sqlite3_result_text16be: procedure(_para1:Psqlite3_context; _para2:pointer; + _para3:longint; _para4:sqlite3_result_func);cdecl; + sqlite3_result_value: procedure(_para1:Psqlite3_context; + _para2:Psqlite3_value);cdecl; + + sqlite3_create_collation: function(_para1:Psqlite3; zName:Pchar; + eTextRep:longint; _para4:pointer; + xCompare:sqlite3_create_collation_func):longint;cdecl; + sqlite3_create_collation16: function(_para1:Psqlite3; zName:Pchar; + eTextRep:longint; _para4:pointer; + xCompare:sqlite3_create_collation_func):longint;cdecl; + + sqlite3_collation_needed: function(_para1:Psqlite3; _para2:pointer; + _para3:sqlite3_collation_needed_func):longint;cdecl; + sqlite3_collation_needed16: function(_para1:Psqlite3; _para2:pointer; + _para3:sqlite3_collation_needed_func):longint;cdecl; + + sqlite3_libversion: function:PChar;cdecl; +//Alias for allowing better code portability (win32 is not working with external variables) +// sqlite3_version: function:PChar;cdecl; macro in 3.7.7 + +// Not published functions + sqlite3_libversion_number: function:longint;cdecl; +// sqlite3_key: function(db:Psqlite3; pKey:pointer; nKey:longint):longint;cdecl; +// sqlite3_rekey: function(db:Psqlite3; pKey:pointer; nKey:longint):longint;cdecl; +// sqlite3_sleep: function(_para1:longint):longint;cdecl; +// sqlite3_expired: function(_para1:Psqlite3_stmt):longint;cdecl; +// sqlite3_global_recover: function:longint;cdecl; + +function sqlite3_version: PChar; + +{$endif} //not mse_sqlite3static +implementation +uses + sysutils,{$ifndef mse_sqlite3static}{$ifdef FPC}dynlibs,{$endif}{$endif}msesys,msesysintf; +{$ifndef mse_sqlite3static} +var + libinfo: dynlibinfoty; + +function sqlite3_version: PChar; +begin + result:= sqlite3_libversion(); +end; + +(* +function tryinitialisesqlite3(const alibnames: array of filenamety): boolean; +var + mstr1: filenamety; +begin + sys_mutexlock(liblock); + try + result:= true; + if refcount = 0 then begin + sqlite3libraryhandle:= loadlib(alibnames,mstr1); + if sqlite3libraryhandle = nilhandle then begin + result:= false; + exit; + end; + try + getprocaddresses(sqlite3libraryhandle, + [ + 'sqlite3_close', //0 + 'sqlite3_exec', //1 + 'sqlite3_last_insert_rowid', //2 + 'sqlite3_changes', //3 + 'sqlite3_total_changes', //4 + 'sqlite3_interrupt', //5 + 'sqlite3_complete', //6 + 'sqlite3_complete16', //7 + 'sqlite3_busy_handler', //8 + 'sqlite3_busy_timeout', //9 + 'sqlite3_get_table', //10 + 'sqlite3_free_table', //11 + 'sqlite3_mprintf', //12 + 'sqlite3_free', //13 + 'sqlite3_snprintf', //14 + 'sqlite3_set_authorizer', //15 + 'sqlite3_trace', //16 + 'sqlite3_progress_handler', //17 + 'sqlite3_commit_hook', //18 + 'sqlite3_open', //19 + 'sqlite3_open16', //20 + 'sqlite3_errcode', //21 + 'sqlite3_errmsg', //22 + 'sqlite3_errmsg16', //23 + 'sqlite3_prepare', //24 + 'sqlite3_prepare16', //25 + 'sqlite3_bind_blob', //26 + 'sqlite3_bind_double', //27 + 'sqlite3_bind_int', //28 + 'sqlite3_bind_int64', //29 + 'sqlite3_bind_null', //30 + 'sqlite3_bind_text', //31 + 'sqlite3_bind_text16', //32 + 'sqlite3_bind_blob', //33 + 'sqlite3_bind_text', //34 + 'sqlite3_bind_text16', //35 + 'sqlite3_bind_parameter_count', //36 + 'sqlite3_bind_parameter_name', //37 + 'sqlite3_bind_parameter_index', //38 + 'sqlite3_column_count', //39 + 'sqlite3_column_name', //40 + 'sqlite3_column_name16', //41 + 'sqlite3_column_decltype', //42 + 'sqlite3_column_decltype16', //43 + 'sqlite3_step', //44 + 'sqlite3_data_count', //45 + 'sqlite3_column_blob', //46 + 'sqlite3_column_bytes', //47 + 'sqlite3_column_bytes16', //48 + 'sqlite3_column_double', //49 + 'sqlite3_column_int', //50 + 'sqlite3_column_int64', //51 + 'sqlite3_column_text', //52 + 'sqlite3_column_text16', //53 + 'sqlite3_column_type', //54 + 'sqlite3_finalize', //55 + 'sqlite3_reset', //56 + 'sqlite3_create_function', //57 + 'sqlite3_create_function16', //58 + 'sqlite3_aggregate_count', //59 + 'sqlite3_value_blob', //60 + 'sqlite3_value_bytes', //61 + 'sqlite3_value_bytes16', //62 + 'sqlite3_value_double', //63 + 'sqlite3_value_int', //64 + 'sqlite3_value_int64', //65 + 'sqlite3_value_text', //66 + 'sqlite3_value_text16', //67 + 'sqlite3_value_text16le', //68 + 'sqlite3_value_text16be', //69 + 'sqlite3_value_type', //70 + 'sqlite3_aggregate_context', //71 + 'sqlite3_user_data', //72 + 'sqlite3_get_auxdata', //73 + 'sqlite3_set_auxdata', //74 + 'sqlite3_result_blob', //75 + 'sqlite3_result_double', //76 + 'sqlite3_result_error', //77 + 'sqlite3_result_error16', //78 + 'sqlite3_result_int', //79 + 'sqlite3_result_int64', //80 + 'sqlite3_result_null', //81 + 'sqlite3_result_text', //82 + 'sqlite3_result_text16', //83 + 'sqlite3_result_text16le', //84 + 'sqlite3_result_text16be', //85 + 'sqlite3_result_value', //86 + 'sqlite3_create_collation', //87 + 'sqlite3_create_collation16', //88 + 'sqlite3_collation_needed', //89 + 'sqlite3_collation_needed16', //90 + 'sqlite3_libversion', //91 + 'sqlite3_version', //92 + 'sqlite3_libversion_number', //93 + 'sqlite3_clear_bindings' //94 + ], + [ + @sqlite3_close, //0 + @sqlite3_exec, //1 + @sqlite3_last_insert_rowid, //2 + @sqlite3_changes, //3 + @sqlite3_total_changes, //4 + @sqlite3_interrupt, //5 + @sqlite3_complete, //6 + @sqlite3_complete16, //7 + @sqlite3_busy_handler, //8 + @sqlite3_busy_timeout, //9 + @sqlite3_get_table, //10 + @sqlite3_free_table, //11 + @sqlite3_mprintf, //12 + @sqlite3_free, //13 + @sqlite3_snprintf, //14 + @sqlite3_set_authorizer, //15 + @sqlite3_trace, //16 + @sqlite3_progress_handler, //17 + @sqlite3_commit_hook, //18 + @sqlite3_open, //19 + @sqlite3_open16, //20 + @sqlite3_errcode, //21 + @sqlite3_errmsg, //22 + @sqlite3_errmsg16, //23 + @sqlite3_prepare, //24 + @sqlite3_prepare16, //25 + @sqlite3_bind_blob, //26 + @sqlite3_bind_double, //27 + @sqlite3_bind_int, //28 + @sqlite3_bind_int64, //29 + @sqlite3_bind_null, //30 + @sqlite3_bind_text, //31 + @sqlite3_bind_text16, //32 + @sqlite3_bind_blob1, //33 + @sqlite3_bind_text1, //34 + @sqlite3_bind_text161, //35 + @sqlite3_bind_parameter_count, //36 + @sqlite3_bind_parameter_name, //37 + @sqlite3_bind_parameter_index, //38 + @sqlite3_column_count, //39 + @sqlite3_column_name, //40 + @sqlite3_column_name16, //41 + @sqlite3_column_decltype, //42 + @sqlite3_column_decltype16, //43 + @sqlite3_step, //44 + @sqlite3_data_count, //45 + @sqlite3_column_blob, //46 + @sqlite3_column_bytes, //47 + @sqlite3_column_bytes16, //48 + @sqlite3_column_double, //49 + @sqlite3_column_int, //50 + @sqlite3_column_int64, //51 + @sqlite3_column_text, //52 + @sqlite3_column_text16, //53 + @sqlite3_column_type, //54 + @sqlite3_finalize, //55 + @sqlite3_reset, //56 + @sqlite3_create_function, //57 + @sqlite3_create_function16, //58 + @sqlite3_aggregate_count, //59 + @sqlite3_value_blob, //60 + @sqlite3_value_bytes, //61 + @sqlite3_value_bytes16, //62 + @sqlite3_value_double, //63 + @sqlite3_value_int, //64 + @sqlite3_value_int64, //65 + @sqlite3_value_text, //66 + @sqlite3_value_text16, //67 + @sqlite3_value_text16le, //68 + @sqlite3_value_text16be, //69 + @sqlite3_value_type, //70 + @sqlite3_aggregate_context, //71 + @sqlite3_user_data, //72 + @sqlite3_get_auxdata, //73 + @sqlite3_set_auxdata, //74 + @sqlite3_result_blob, //75 + @sqlite3_result_double, //76 + @sqlite3_result_error, //77 + @sqlite3_result_error16, //78 + @sqlite3_result_int, //79 + @sqlite3_result_int64, //80 + @sqlite3_result_null, //81 + @sqlite3_result_text, //82 + @sqlite3_result_text16, //83 + @sqlite3_result_text16le, //84 + @sqlite3_result_text16be, //85 + @sqlite3_result_value, //86 + @sqlite3_create_collation, //87 + @sqlite3_create_collation16, //88 + @sqlite3_collation_needed, //89 + @sqlite3_collation_needed16, //90 + @sqlite3_libversion, //91 + @sqlite3_version, //92 + @sqlite3_libversion_number, //93 + @sqlite3_clear_bindings //94 + ]); + except + on e: exception do begin + e.message:= 'Library "'+mstr1+'": '+e.message; + result:= false; + if unloadlibrary(sqlite3libraryhandle) then begin + sqlite3libraryhandle:= nilhandle; + end; + raise; + end; + end; + end; + inc(refcount); + finally + sys_mutexunlock(liblock); + end; +end; +*) + +procedure initializesqlite3(const sonames: array of filenamety); +const + funcs: array[0..93] of funcinfoty = ( + (n: 'sqlite3_close'; d: {$ifndef FPC}@{$endif}@sqlite3_close), + (n: 'sqlite3_exec'; d: {$ifndef FPC}@{$endif}@sqlite3_exec), + (n: 'sqlite3_last_insert_rowid'; d: {$ifndef FPC}@{$endif}@sqlite3_last_insert_rowid), + (n: 'sqlite3_changes'; d: {$ifndef FPC}@{$endif}@sqlite3_changes), + (n: 'sqlite3_total_changes'; d: {$ifndef FPC}@{$endif}@sqlite3_total_changes), + (n: 'sqlite3_interrupt'; d: {$ifndef FPC}@{$endif}@sqlite3_interrupt), + (n: 'sqlite3_complete'; d: {$ifndef FPC}@{$endif}@sqlite3_complete), + (n: 'sqlite3_complete16'; d: {$ifndef FPC}@{$endif}@sqlite3_complete16), + (n: 'sqlite3_busy_handler'; d: {$ifndef FPC}@{$endif}@sqlite3_busy_handler), + (n: 'sqlite3_busy_timeout'; d: {$ifndef FPC}@{$endif}@sqlite3_busy_timeout), + (n: 'sqlite3_get_table'; d: {$ifndef FPC}@{$endif}@sqlite3_get_table), + (n: 'sqlite3_free_table'; d: {$ifndef FPC}@{$endif}@sqlite3_free_table), + (n: 'sqlite3_mprintf'; d: {$ifndef FPC}@{$endif}@sqlite3_mprintf), + (n: 'sqlite3_free'; d: {$ifndef FPC}@{$endif}@sqlite3_free), + (n: 'sqlite3_snprintf'; d: {$ifndef FPC}@{$endif}@sqlite3_snprintf), + (n: 'sqlite3_set_authorizer'; d: {$ifndef FPC}@{$endif}@sqlite3_set_authorizer), + (n: 'sqlite3_trace'; d: {$ifndef FPC}@{$endif}@sqlite3_trace), + (n: 'sqlite3_progress_handler'; d: {$ifndef FPC}@{$endif}@sqlite3_progress_handler), + (n: 'sqlite3_commit_hook'; d: {$ifndef FPC}@{$endif}@sqlite3_commit_hook), + (n: 'sqlite3_open'; d: {$ifndef FPC}@{$endif}@sqlite3_open), + (n: 'sqlite3_open16'; d: {$ifndef FPC}@{$endif}@sqlite3_open16), + (n: 'sqlite3_errcode'; d: {$ifndef FPC}@{$endif}@sqlite3_errcode), + (n: 'sqlite3_errmsg'; d: {$ifndef FPC}@{$endif}@sqlite3_errmsg), + (n: 'sqlite3_errmsg16'; d: {$ifndef FPC}@{$endif}@sqlite3_errmsg16), + (n: 'sqlite3_prepare'; d: {$ifndef FPC}@{$endif}@sqlite3_prepare), + (n: 'sqlite3_prepare16'; d: {$ifndef FPC}@{$endif}@sqlite3_prepare16), + (n: 'sqlite3_bind_blob'; d: {$ifndef FPC}@{$endif}@sqlite3_bind_blob), + (n: 'sqlite3_bind_double'; d: {$ifndef FPC}@{$endif}@sqlite3_bind_double), + (n: 'sqlite3_bind_int'; d: {$ifndef FPC}@{$endif}@sqlite3_bind_int), + (n: 'sqlite3_bind_int64'; d: {$ifndef FPC}@{$endif}@sqlite3_bind_int64), + (n: 'sqlite3_bind_null'; d: {$ifndef FPC}@{$endif}@sqlite3_bind_null), + (n: 'sqlite3_bind_text'; d: {$ifndef FPC}@{$endif}@sqlite3_bind_text), + (n: 'sqlite3_bind_text16'; d: {$ifndef FPC}@{$endif}@sqlite3_bind_text16), + (n: 'sqlite3_bind_blob'; d: {$ifndef FPC}@{$endif}@sqlite3_bind_blob), + (n: 'sqlite3_bind_text'; d: {$ifndef FPC}@{$endif}@sqlite3_bind_text), + (n: 'sqlite3_bind_text16'; d: {$ifndef FPC}@{$endif}@sqlite3_bind_text16), + (n: 'sqlite3_bind_parameter_count'; d: {$ifndef FPC}@{$endif}@sqlite3_bind_parameter_count), + (n: 'sqlite3_bind_parameter_name'; d: {$ifndef FPC}@{$endif}@sqlite3_bind_parameter_name), + (n: 'sqlite3_bind_parameter_index'; d: {$ifndef FPC}@{$endif}@sqlite3_bind_parameter_index), + (n: 'sqlite3_column_count'; d: {$ifndef FPC}@{$endif}@sqlite3_column_count), + (n: 'sqlite3_column_name'; d: {$ifndef FPC}@{$endif}@sqlite3_column_name), + (n: 'sqlite3_column_name16'; d: {$ifndef FPC}@{$endif}@sqlite3_column_name16), + (n: 'sqlite3_column_decltype'; d: {$ifndef FPC}@{$endif}@sqlite3_column_decltype), + (n: 'sqlite3_column_decltype16'; d: {$ifndef FPC}@{$endif}@sqlite3_column_decltype16), + (n: 'sqlite3_step'; d: {$ifndef FPC}@{$endif}@sqlite3_step), + (n: 'sqlite3_data_count'; d: {$ifndef FPC}@{$endif}@sqlite3_data_count), + (n: 'sqlite3_column_blob'; d: {$ifndef FPC}@{$endif}@sqlite3_column_blob), + (n: 'sqlite3_column_bytes'; d: {$ifndef FPC}@{$endif}@sqlite3_column_bytes), + (n: 'sqlite3_column_bytes16'; d: {$ifndef FPC}@{$endif}@sqlite3_column_bytes16), + (n: 'sqlite3_column_double'; d: {$ifndef FPC}@{$endif}@sqlite3_column_double), + (n: 'sqlite3_column_int'; d: {$ifndef FPC}@{$endif}@sqlite3_column_int), + (n: 'sqlite3_column_int64'; d: {$ifndef FPC}@{$endif}@sqlite3_column_int64), + (n: 'sqlite3_column_text'; d: {$ifndef FPC}@{$endif}@sqlite3_column_text), + (n: 'sqlite3_column_text16'; d: {$ifndef FPC}@{$endif}@sqlite3_column_text16), + (n: 'sqlite3_column_type'; d: {$ifndef FPC}@{$endif}@sqlite3_column_type), + (n: 'sqlite3_finalize'; d: {$ifndef FPC}@{$endif}@sqlite3_finalize), + (n: 'sqlite3_reset'; d: {$ifndef FPC}@{$endif}@sqlite3_reset), + (n: 'sqlite3_create_function'; d: {$ifndef FPC}@{$endif}@sqlite3_create_function), + (n: 'sqlite3_create_function16'; d: {$ifndef FPC}@{$endif}@sqlite3_create_function16), + (n: 'sqlite3_aggregate_count'; d: {$ifndef FPC}@{$endif}@sqlite3_aggregate_count), + (n: 'sqlite3_value_blob'; d: {$ifndef FPC}@{$endif}@sqlite3_value_blob), + (n: 'sqlite3_value_bytes'; d: {$ifndef FPC}@{$endif}@sqlite3_value_bytes), + (n: 'sqlite3_value_bytes16'; d: {$ifndef FPC}@{$endif}@sqlite3_value_bytes16), + (n: 'sqlite3_value_double'; d: {$ifndef FPC}@{$endif}@sqlite3_value_double), + (n: 'sqlite3_value_int'; d: {$ifndef FPC}@{$endif}@sqlite3_value_int), + (n: 'sqlite3_value_int64'; d: {$ifndef FPC}@{$endif}@sqlite3_value_int64), + (n: 'sqlite3_value_text'; d: {$ifndef FPC}@{$endif}@sqlite3_value_text), + (n: 'sqlite3_value_text16'; d: {$ifndef FPC}@{$endif}@sqlite3_value_text16), + (n: 'sqlite3_value_text16le'; d: {$ifndef FPC}@{$endif}@sqlite3_value_text16le), + (n: 'sqlite3_value_text16be'; d: {$ifndef FPC}@{$endif}@sqlite3_value_text16be), + (n: 'sqlite3_value_type'; d: {$ifndef FPC}@{$endif}@sqlite3_value_type), + (n: 'sqlite3_aggregate_context'; d: {$ifndef FPC}@{$endif}@sqlite3_aggregate_context), + (n: 'sqlite3_user_data'; d: {$ifndef FPC}@{$endif}@sqlite3_user_data), + (n: 'sqlite3_get_auxdata'; d: {$ifndef FPC}@{$endif}@sqlite3_get_auxdata), + (n: 'sqlite3_set_auxdata'; d: {$ifndef FPC}@{$endif}@sqlite3_set_auxdata), + (n: 'sqlite3_result_blob'; d: {$ifndef FPC}@{$endif}@sqlite3_result_blob), + (n: 'sqlite3_result_double'; d: {$ifndef FPC}@{$endif}@sqlite3_result_double), + (n: 'sqlite3_result_error'; d: {$ifndef FPC}@{$endif}@sqlite3_result_error), + (n: 'sqlite3_result_error16'; d: {$ifndef FPC}@{$endif}@sqlite3_result_error16), + (n: 'sqlite3_result_int'; d: {$ifndef FPC}@{$endif}@sqlite3_result_int), + (n: 'sqlite3_result_int64'; d: {$ifndef FPC}@{$endif}@sqlite3_result_int64), + (n: 'sqlite3_result_null'; d: {$ifndef FPC}@{$endif}@sqlite3_result_null), + (n: 'sqlite3_result_text'; d: {$ifndef FPC}@{$endif}@sqlite3_result_text), + (n: 'sqlite3_result_text16'; d: {$ifndef FPC}@{$endif}@sqlite3_result_text16), + (n: 'sqlite3_result_text16le'; d: {$ifndef FPC}@{$endif}@sqlite3_result_text16le), + (n: 'sqlite3_result_text16be'; d: {$ifndef FPC}@{$endif}@sqlite3_result_text16be), + (n: 'sqlite3_result_value'; d: {$ifndef FPC}@{$endif}@sqlite3_result_value), + (n: 'sqlite3_create_collation'; d: {$ifndef FPC}@{$endif}@sqlite3_create_collation), + (n: 'sqlite3_create_collation16'; d: {$ifndef FPC}@{$endif}@sqlite3_create_collation16), + (n: 'sqlite3_collation_needed'; d: {$ifndef FPC}@{$endif}@sqlite3_collation_needed), + (n: 'sqlite3_collation_needed16'; d: {$ifndef FPC}@{$endif}@sqlite3_collation_needed16), + (n: 'sqlite3_libversion'; d: {$ifndef FPC}@{$endif}@sqlite3_libversion), +// (n: 'sqlite3_version'; d: {$ifndef FPC}@{$endif}@sqlite3_version), + (n: 'sqlite3_libversion_number'; d: {$ifndef FPC}@{$endif}@sqlite3_libversion_number), + (n: 'sqlite3_clear_bindings'; d: {$ifndef FPC}@{$endif}@sqlite3_clear_bindings) + ); + errormessage = 'Can not load Sqlite3 library. '; +begin + initializedynlib(libinfo,sonames,sqlite3lib,funcs,[],errormessage); +end; + +procedure releasesqlite3; +begin + releasedynlib(libinfo); +end; + +initialization + initializelibinfo(libinfo); +finalization + finalizelibinfo(libinfo); +{$else} +procedure initialisesqlite3; +begin + //dummy +end; + +procedure releasesqlite3; +begin + //dummy +end; + +{$endif} //mse_sqlite3static +end. diff --git a/mseide-msegui/lib/common/designutils/msecomponenteditors.pas b/mseide-msegui/lib/common/designutils/msecomponenteditors.pas new file mode 100644 index 0000000..4cbed04 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msecomponenteditors.pas @@ -0,0 +1,172 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msecomponenteditors; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + classes,mclasses,msedesignintf,mseglob,mseguiglob,mseclasses,mselist,msetypes; + +type + + componentinfoty = record + name: string; + instance: tcomponent; + end; + pcomponentinfoty = ^componentinfoty; + + tcomponenteditor = class(tnullinterfacedobject,icomponenteditor) + protected + fcomponent: tcomponent; + fstate: componenteditorstatesty; + fdesigner: idesigner; + public + constructor create(const adesigner: idesigner; acomponent: tcomponent); virtual; + function state: componenteditorstatesty; + procedure edit; virtual; + property component: tcomponent read fcomponent; + end; + + componenteditorclassty = class of tcomponenteditor; + + timagelisteditor = class(tcomponenteditor) + public + constructor create(const adesigner: idesigner; + acomponent: tcomponent); override; + procedure edit; override; + end; + + componenteditorinfoty = record + componentclass: componentclassty; + componenteditorclass: componenteditorclassty; + end; + pcomponenteditorinfoty = ^componenteditorinfoty; + + tcomponenteditors = class(trecordlist) + protected + procedure add(componentclass: componentclassty; componenteditorclass: componenteditorclassty); + public + constructor create; + function geteditorclass(const component: componentclassty): componenteditorclassty; + end; + +function componenteditors: tcomponenteditors; +procedure registercomponenteditor(componentclass: componentclassty; + componenteditorclass: componenteditorclassty); + +implementation +uses + msegui,mseimagelisteditor,msebitmap,SysUtils; + +var + acomponenteditors: tcomponenteditors; + +function componenteditors: tcomponenteditors; +begin + if acomponenteditors = nil then begin + acomponenteditors:= tcomponenteditors.create; + end; + result:= acomponenteditors; +end; + +procedure registercomponenteditor(componentclass: componentclassty; + componenteditorclass: componenteditorclassty); +begin + componenteditors.add(componentclass,componenteditorclass) +end; + + +{ tcomponenteditors } + +procedure tcomponenteditors.add(componentclass: componentclassty; + componenteditorclass: componenteditorclassty); +var + info: componenteditorinfoty; +begin + fillchar(info,sizeof(info),0); + info.componentclass:= componentclass; + info.componenteditorclass:= componenteditorclass; + inherited add(info); +end; + +constructor tcomponenteditors.create; +begin + inherited create(sizeof(componentinfoty)); +end; + +function tcomponenteditors.geteditorclass( + const component: componentclassty): componenteditorclassty; +var + level: integer; + int1: integer; + int2: integer; + po1: pcomponenteditorinfoty; + class1: tclass; +begin + result:= nil; + level:= bigint; + po1:= pcomponenteditorinfoty(fdata); + for int1:= 0 to count - 1 do begin + with po1^ do begin + class1:= component; + int2:= 0; + while (class1 <> componentclass) and (class1 <> nil) do begin + inc(int2); + class1:= class1.ClassParent; + end; + if (class1 <> nil) and (int2 < level) then begin + level:= int2; + result:= componenteditorclass; + end; + end; + inc(po1); + end; +end; + +{ tcomponenteditor } + +constructor tcomponenteditor.create(const adesigner: idesigner; acomponent: tcomponent); +begin + fdesigner:= adesigner; + fcomponent:= acomponent; +end; + +function tcomponenteditor.state: componenteditorstatesty; +begin + result:= fstate; +end; + +procedure tcomponenteditor.edit; +begin + //dummy +end; + +{ timagelisteditor } + +constructor timagelisteditor.create(const adesigner: idesigner; + acomponent: tcomponent); +begin + inherited; + fstate:= fstate + [cs_canedit]; +end; + +procedure timagelisteditor.edit; +begin + if editimagelist(timagelist(fcomponent)) = mr_ok then begin + fdesigner.componentmodified(fcomponent); + end; +end; + +initialization + acomponenteditors:= tcomponenteditors.Create; +finalization + freeandnil(acomponenteditors); +end. diff --git a/mseide-msegui/lib/common/designutils/msecornermaskeditor.mfm b/mseide-msegui/lib/common/designutils/msecornermaskeditor.mfm new file mode 100644 index 0000000..176cbd1 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msecornermaskeditor.mfm @@ -0,0 +1,130 @@ +object msecornermaskeditorfo: tmsecornermaskeditorfo + visible = False + bounds_x = 337 + bounds_y = 266 + bounds_cx = 383 + bounds_cy = 334 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 383 + 334 + ) + options = [fo_freeonclose, fo_createmodal, fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder, fo_savestate] + statfile = statfile1 + caption = 'Cornermask Editor' + oncreate = createexe + onclosequery = closequexe + moduleclassname = 'tmseform' + object tsplitter1: tsplitter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + color = -2147483645 + bounds_x = 258 + bounds_y = 293 + bounds_cx = 123 + bounds_cy = 32 + anchors = [an_right, an_bottom] + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + linktop = grid + grip = stb_none + object tbutton2: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + taborder = 1 + bounds_x = 58 + bounds_y = 10 + bounds_cx = 52 + bounds_cy = 22 + bounds_cxmin = 50 + anchors = [an_top, an_right] + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + reffontheight = 14 + end + object tbutton1: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + bounds_x = 0 + bounds_y = 10 + bounds_cx = 50 + bounds_cy = 22 + bounds_cxmin = 50 + anchors = [an_top, an_right] + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + reffontheight = 14 + end + object tspacer2: tspacer + taborder = 2 + bounds_x = 50 + bounds_y = 10 + bounds_cx = 8 + bounds_cy = 20 + linkleft = tbutton1 + linkright = tbutton2 + options = [spao_glueright] + end + end + object grid: twidgetgrid + frame.localprops = [] + frame.localprops1 = [] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 383 + bounds_cy = 293 + anchors = [an_top] + optionsgrid = [og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_selectedrowsdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixcols.count = 1 + fixcols.items = < + item + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 1 + captions.items = < + item + caption = 'Width' + end> + captionsfix.count = 1 + captionsfix.items = < + item + caption = 'Row' + end> + end> + datacols.count = 1 + datacols.options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savevalue, co_savestate, co_mousescrollrow] + datacols.items = < + item[maskwidthed] + width = 77 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savevalue, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow, co_rowdatachange] + name = 'index' + widgetname = 'maskwidthed' + dataclass = tgridintegerdatalist + end> + datarowheight = 16 + reffontheight = 14 + object maskwidthed: tintegeredit + optionsskin = [osk_framebuttononly] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 77 + bounds_cy = 16 + max = 524287 + reffontheight = 14 + end + end + object statfile1: tstatfile + filename = 'cornermask.sta' + options = [sfo_memory, sfo_transaction, sfo_activatorread, sfo_activatorwrite] + left = 80 + top = 112 + end +end diff --git a/mseide-msegui/lib/common/designutils/msecornermaskeditor.pas b/mseide-msegui/lib/common/designutils/msecornermaskeditor.pas new file mode 100644 index 0000000..54036a5 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msecornermaskeditor.pas @@ -0,0 +1,80 @@ +unit msecornermaskeditor; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,msewidgets,mseforms,msesplitter, + msesimplewidgets,msedataedits,mseedit,mseificomp,mseificompglob,mseifiglob, + msestatfile,msestream,msestrings,sysutils,msegrids,msewidgetgrid,msegraphedits, + msescrollbar,msebitmap; +type + tmsecornermaskeditorfo = class(tmseform) + tsplitter1: tsplitter; + tbutton2: tbutton; + tbutton1: tbutton; + tspacer2: tspacer; + grid: twidgetgrid; + maskwidthed: tintegeredit; + statfile1: tstatfile; + procedure createexe(const sender: TObject); + procedure closequexe(const sender: tcustommseform; + var amodalresult: modalresultty); + protected + findexlist: pmsestring; + fok: pboolean; + public + constructor create(var indexlist: msestring; out ok: boolean); + end; + +function editcornermask(var indexlist: msestring): boolean; + +implementation +uses + msecornermaskeditor_mfm; + +function editcornermask(var indexlist: msestring): boolean; +begin + tmsecornermaskeditorfo.create(indexlist,result); +end; + +{ tmsecornermaskeditorfo } + +constructor tmsecornermaskeditorfo.create(var indexlist: msestring; + out ok: boolean); +begin + findexlist:= @indexlist; + fok:= @ok; + inherited create(nil); +end; + +procedure tmsecornermaskeditorfo.createexe(const sender: TObject); +var + i1: int32; + po1: pint16; +begin + grid.beginupdate(); + grid.rowcount:= length(findexlist^); + po1:= pointer(findexlist^); + for i1:= 0 to grid.rowhigh do begin + maskwidthed[i1]:= po1[i1]; + end; + grid.endupdate(); +end; + +procedure tmsecornermaskeditorfo.closequexe(const sender: tcustommseform; + var amodalresult: modalresultty); +var + i1: int32; + po1: pint16; +begin + fok^:= amodalresult = mr_ok; + if fok^ then begin + setlength(findexlist^,grid.rowcount); + po1:= pointer(findexlist^); + for i1:= 0 to grid.rowhigh do begin + po1[i1]:= maskwidthed[i1]; + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/msecornermaskeditor_mfm.pas b/mseide-msegui/lib/common/designutils/msecornermaskeditor_mfm.pas new file mode 100644 index 0000000..0d4d34a --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msecornermaskeditor_mfm.pas @@ -0,0 +1,153 @@ +unit msecornermaskeditor_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msecornermaskeditor; + +const + objdata: record size: integer; data: array[0..2718] of byte end = + (size: 2719; data: ( + 84,80,70,48,22,116,109,115,101,99,111,114,110,101,114,109,97,115,107,101, + 100,105,116,111,114,102,111,21,109,115,101,99,111,114,110,101,114,109,97,115, + 107,101,100,105,116,111,114,102,111,7,118,105,115,105,98,108,101,8,8,98, + 111,117,110,100,115,95,120,3,81,1,8,98,111,117,110,100,115,95,121,3, + 10,1,9,98,111,117,110,100,115,95,99,120,3,127,1,9,98,111,117,110, + 100,115,95,99,121,3,78,1,26,99,111,110,116,97,105,110,101,114,46,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,27,99,111, + 110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,99,111,110,116,97,105,110,101,114,46,98,111, + 117,110,100,115,1,2,0,2,0,3,127,1,3,78,1,0,7,111,112,116, + 105,111,110,115,11,14,102,111,95,102,114,101,101,111,110,99,108,111,115,101, + 14,102,111,95,99,114,101,97,116,101,109,111,100,97,108,13,102,111,95,99, + 108,111,115,101,111,110,101,115,99,15,102,111,95,97,117,116,111,114,101,97, + 100,115,116,97,116,16,102,111,95,97,117,116,111,119,114,105,116,101,115,116, + 97,116,10,102,111,95,115,97,118,101,112,111,115,13,102,111,95,115,97,118, + 101,122,111,114,100,101,114,12,102,111,95,115,97,118,101,115,116,97,116,101, + 0,8,115,116,97,116,102,105,108,101,7,9,115,116,97,116,102,105,108,101, + 49,7,99,97,112,116,105,111,110,6,17,67,111,114,110,101,114,109,97,115, + 107,32,69,100,105,116,111,114,8,111,110,99,114,101,97,116,101,7,9,99, + 114,101,97,116,101,101,120,101,12,111,110,99,108,111,115,101,113,117,101,114, + 121,7,10,99,108,111,115,101,113,117,101,120,101,15,109,111,100,117,108,101, + 99,108,97,115,115,110,97,109,101,6,8,116,109,115,101,102,111,114,109,0, + 9,116,115,112,108,105,116,116,101,114,10,116,115,112,108,105,116,116,101,114, + 49,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,11,111,119,95, + 116,97,98,102,111,99,117,115,17,111,119,95,112,97,114,101,110,116,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98, + 102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,5,99,111,108,111,114,4,3,0,0,128,8,98,111,117,110, + 100,115,95,120,3,2,1,8,98,111,117,110,100,115,95,121,3,37,1,9, + 98,111,117,110,100,115,95,99,120,2,123,9,98,111,117,110,100,115,95,99, + 121,2,32,7,97,110,99,104,111,114,115,11,8,97,110,95,114,105,103,104, + 116,9,97,110,95,98,111,116,116,111,109,0,12,111,112,116,105,111,110,115, + 115,99,97,108,101,11,11,111,115,99,95,101,120,112,97,110,100,120,11,111, + 115,99,95,115,104,114,105,110,107,120,11,111,115,99,95,101,120,112,97,110, + 100,121,11,111,115,99,95,115,104,114,105,110,107,121,0,7,108,105,110,107, + 116,111,112,7,4,103,114,105,100,4,103,114,105,112,7,8,115,116,98,95, + 110,111,110,101,0,7,116,98,117,116,116,111,110,8,116,98,117,116,116,111, + 110,50,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111, + 119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,13,111, + 119,49,95,97,117,116,111,115,99,97,108,101,13,111,119,49,95,97,117,116, + 111,119,105,100,116,104,0,8,116,97,98,111,114,100,101,114,2,1,8,98, + 111,117,110,100,115,95,120,2,58,8,98,111,117,110,100,115,95,121,2,10, + 9,98,111,117,110,100,115,95,99,120,2,52,9,98,111,117,110,100,115,95, + 99,121,2,22,12,98,111,117,110,100,115,95,99,120,109,105,110,2,50,7, + 97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,8,97,110,95,114, + 105,103,104,116,0,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,7,38, + 67,97,110,99,101,108,11,109,111,100,97,108,114,101,115,117,108,116,7,9, + 109,114,95,99,97,110,99,101,108,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,14,0,0,7,116,98,117,116,116,111,110,8,116,98,117,116, + 116,111,110,49,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11, + 19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116, + 13,111,119,49,95,97,117,116,111,115,99,97,108,101,13,111,119,49,95,97, + 117,116,111,119,105,100,116,104,0,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,10,9,98,111,117,110,100,115,95,99, + 120,2,50,9,98,111,117,110,100,115,95,99,121,2,22,12,98,111,117,110, + 100,115,95,99,120,109,105,110,2,50,7,97,110,99,104,111,114,115,11,6, + 97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,5,115,116,97, + 116,101,11,10,97,115,95,100,101,102,97,117,108,116,15,97,115,95,108,111, + 99,97,108,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,99, + 97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,3,38,79,75, + 11,109,111,100,97,108,114,101,115,117,108,116,7,5,109,114,95,111,107,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,7,116,115, + 112,97,99,101,114,8,116,115,112,97,99,101,114,50,8,116,97,98,111,114, + 100,101,114,2,2,8,98,111,117,110,100,115,95,120,2,50,8,98,111,117, + 110,100,115,95,121,2,10,9,98,111,117,110,100,115,95,99,120,2,8,9, + 98,111,117,110,100,115,95,99,121,2,20,8,108,105,110,107,108,101,102,116, + 7,8,116,98,117,116,116,111,110,49,9,108,105,110,107,114,105,103,104,116, + 7,8,116,98,117,116,116,111,110,50,7,111,112,116,105,111,110,115,11,14, + 115,112,97,111,95,103,108,117,101,114,105,103,104,116,0,0,0,0,11,116, + 119,105,100,103,101,116,103,114,105,100,4,103,114,105,100,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114, + 100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,127,1, + 9,98,111,117,110,100,115,95,99,121,3,37,1,7,97,110,99,104,111,114, + 115,11,6,97,110,95,116,111,112,0,11,111,112,116,105,111,110,115,103,114, + 105,100,11,12,111,103,95,114,111,119,109,111,118,105,110,103,15,111,103,95, + 107,101,121,114,111,119,109,111,118,105,110,103,15,111,103,95,114,111,119,105, + 110,115,101,114,116,105,110,103,14,111,103,95,114,111,119,100,101,108,101,116, + 105,110,103,23,111,103,95,115,101,108,101,99,116,101,100,114,111,119,115,100, + 101,108,101,116,105,110,103,19,111,103,95,102,111,99,117,115,99,101,108,108, + 111,110,101,110,116,101,114,15,111,103,95,97,117,116,111,102,105,114,115,116, + 114,111,119,13,111,103,95,97,117,116,111,97,112,112,101,110,100,20,111,103, + 95,99,111,108,99,104,97,110,103,101,111,110,116,97,98,107,101,121,10,111, + 103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112, + 117,112,17,111,103,95,109,111,117,115,101,115,99,114,111,108,108,99,111,108, + 0,13,102,105,120,99,111,108,115,46,99,111,117,110,116,2,1,13,102,105, + 120,99,111,108,115,46,105,116,101,109,115,14,1,7,110,117,109,115,116,101, + 112,2,1,0,0,13,102,105,120,114,111,119,115,46,99,111,117,110,116,2, + 1,13,102,105,120,114,111,119,115,46,105,116,101,109,115,14,1,6,104,101, + 105,103,104,116,2,16,14,99,97,112,116,105,111,110,115,46,99,111,117,110, + 116,2,1,14,99,97,112,116,105,111,110,115,46,105,116,101,109,115,14,1, + 7,99,97,112,116,105,111,110,6,5,87,105,100,116,104,0,0,17,99,97, + 112,116,105,111,110,115,102,105,120,46,99,111,117,110,116,2,1,17,99,97, + 112,116,105,111,110,115,102,105,120,46,105,116,101,109,115,14,1,7,99,97, + 112,116,105,111,110,6,3,82,111,119,0,0,0,0,14,100,97,116,97,99, + 111,108,115,46,99,111,117,110,116,2,1,16,100,97,116,97,99,111,108,115, + 46,111,112,116,105,111,110,115,11,14,99,111,95,102,111,99,117,115,115,101, + 108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12, + 99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116, + 105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116, + 12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111,95,115,97,118, + 101,115,116,97,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108, + 108,114,111,119,0,14,100,97,116,97,99,111,108,115,46,105,116,101,109,115, + 14,7,11,109,97,115,107,119,105,100,116,104,101,100,1,5,119,105,100,116, + 104,2,77,7,111,112,116,105,111,110,115,11,14,99,111,95,102,111,99,117, + 115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101, + 99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109, + 117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108, + 101,99,116,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111,95, + 115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121, + 11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115, + 101,115,99,114,111,108,108,114,111,119,16,99,111,95,114,111,119,100,97,116, + 97,99,104,97,110,103,101,0,4,110,97,109,101,6,5,105,110,100,101,120, + 10,119,105,100,103,101,116,110,97,109,101,6,11,109,97,115,107,119,105,100, + 116,104,101,100,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105, + 100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,0,13,100, + 97,116,97,114,111,119,104,101,105,103,104,116,2,16,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,14,0,12,116,105,110,116,101,103,101,114, + 101,100,105,116,11,109,97,115,107,119,105,100,116,104,101,100,11,111,112,116, + 105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98, + 117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2, + 1,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2, + 0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,2,77,9,98,111,117,110,100,115,95,99,121,2,16,3,109,97,120, + 4,255,255,7,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,0,0,9,116,115,116,97,116,102,105,108,101,9,115,116,97,116,102, + 105,108,101,49,8,102,105,108,101,110,97,109,101,6,14,99,111,114,110,101, + 114,109,97,115,107,46,115,116,97,7,111,112,116,105,111,110,115,11,10,115, + 102,111,95,109,101,109,111,114,121,15,115,102,111,95,116,114,97,110,115,97, + 99,116,105,111,110,17,115,102,111,95,97,99,116,105,118,97,116,111,114,114, + 101,97,100,18,115,102,111,95,97,99,116,105,118,97,116,111,114,119,114,105, + 116,101,0,4,108,101,102,116,2,80,3,116,111,112,2,112,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tmsecornermaskeditorfo,''); +end. diff --git a/mseide-msegui/lib/common/designutils/msedbfieldeditor.mfm b/mseide-msegui/lib/common/designutils/msedbfieldeditor.mfm new file mode 100644 index 0000000..461bf15 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msedbfieldeditor.mfm @@ -0,0 +1,333 @@ +object msedbfieldeditorfo: tmsedbfieldeditorfo + optionswidget = [ow_arrowfocus, ow_subfocus, ow_destroywidgets, ow_hinton] + visible = False + bounds_x = 29 + bounds_y = 248 + bounds_cx = 601 + bounds_cy = 216 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + container.frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + container.bounds = ( + 0 + 0 + 601 + 216 + ) + options = [fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savestate] + statfile = tstatfile1 + oneventloopstart = formloaded + moduleclassname = 'tmseform' + object tbutton1: tbutton + taborder = 3 + bounds_x = 472 + bounds_y = 184 + bounds_cx = 50 + bounds_cy = 22 + anchors = [an_right, an_bottom] + state = [as_default, as_localdefault, as_localcaption] + caption = 'OK' + modalresult = mr_ok + end + object tbutton2: tbutton + bounds_x = 536 + bounds_y = 184 + bounds_cx = 50 + bounds_cy = 22 + anchors = [an_right, an_bottom] + state = [as_localcaption] + caption = 'Cancel' + modalresult = mr_cancel + end + object fielddefli: tstringgrid + frame.caption = 'Fielddefs' + frame.captionpos = cp_top + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + bounds_x = 336 + bounds_y = 7 + bounds_cx = 258 + bounds_cy = 171 + bounds_cxmin = 50 + anchors = [an_left, an_top, an_right, an_bottom] + optionsgrid = [og_colsizing, og_focuscellonenter, og_colchangeontabkey, og_wrapcol, og_autopopup] + datacols.count = 2 + datacols.options = [co_readonly, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate] + datacols.items = < + item + width = 123 + options = [co_readonly, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savestate] + optionsedit = [scoe_eatreturn] + valuefalse = '0' + valuetrue = '1' + end + item + width = 129 + options = [co_readonly, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savestate] + optionsedit = [scoe_eatreturn] + valuefalse = '0' + valuetrue = '1' + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 2 + captions.items = < + item + caption = 'Name' + end + item + caption = 'Type' + end> + end> + rowfonts.count = 1 + rowfonts.items = < + item + color = -1610612732 + name = 'stf_default' + xscale = 1 + localprops = [flp_color, flp_xscale] + end> + datarowheight = 16 + oncellevent = defscellevent + onselectionchanged = defsselectioncha + reffontheight = 14 + end + object fields: twidgetgrid + frame.caption = 'Fields' + frame.captionpos = cp_top + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + bounds_x = 8 + bounds_y = 7 + bounds_cx = 323 + bounds_cy = 171 + anchors = [an_left, an_top, an_bottom] + optionsgrid = [og_colsizing, og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_sorted, og_colchangeontabkey, og_wrapcol, og_autopopup] + fixcols.count = 1 + fixcols.items = < + item + width = 15 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 5 + captions.items = < + item + end + item + end + item + caption = 'Name' + end + item + caption = 'Class type' + end + item + caption = 'Field kind' + end> + end> + rowfonts.count = 1 + rowfonts.items = < + item + color = -1610612732 + name = 'stf_default' + xscale = 1 + localprops = [flp_color, flp_xscale] + end> + datacols.count = 5 + datacols.options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate] + datacols.items = < + item[index] + width = 13 + options = [co_invisible, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savevalue, co_savestate] + widgetname = 'index' + dataclass = tgridintegerdatalist + end + item[fieldpo] + width = 12 + options = [co_invisible, co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate] + widgetname = 'fieldpo' + dataclass = tgridpointerdatalist + end + item[fieldname] + width = 97 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savevalue, co_savestate] + widgetname = 'fieldname' + dataclass = tgridmsestringdatalist + end + item[classty] + width = 92 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savevalue, co_savestate] + widgetname = 'classty' + dataclass = tgridenumdatalist + end + item[fieldkind] + width = 84 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savevalue, co_savestate] + widgetname = 'fieldkind' + dataclass = tgridenumdatalist + end> + datarowheight = 16 + onrowsdeleting = fieldrowsdeleting + onrowsdeleted = fieldsrowdel + oncellevent = fieldcellevent + onselectionchanged = fieldselectioncha + onsort = fieldsort + reffontheight = 14 + object index: tintegeredit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_noskin] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 13 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + reffontheight = 14 + end + object fieldpo: tpointeredit + optionsskin = [osk_noskin] + taborder = 2 + bounds_x = 14 + bounds_y = 0 + bounds_cx = 12 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + end + object fieldname: tstringedit + optionsskin = [osk_framebuttononly] + taborder = 3 + visible = False + bounds_x = 27 + bounds_y = 0 + bounds_cx = 97 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + ondataentered = fieldsdataentered + onsetvalue = fieldnamesetvalue + reffontheight = 14 + end + object classty: tenumtypeedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.button.color = -1879048187 + taborder = 4 + visible = False + bounds_x = 125 + bounds_y = 0 + bounds_cx = 92 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_notnull] + valuedefault = 0 + min = 0 + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + oninit = initcla + reffontheight = 14 + end + object fieldkind: tenumtypeedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.button.width = 15 + frame.button.color = -1879048187 + taborder = 5 + visible = False + bounds_x = 218 + bounds_y = 0 + bounds_cx = 84 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_notnull] + valuedefault = 0 + min = 0 + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + oninit = initfieldkind + reffontheight = 14 + end + end + object splitter: tsplitter + color = -1879048189 + taborder = 6 + bounds_x = 331 + bounds_y = 24 + bounds_cx = 5 + bounds_cy = 154 + anchors = [an_left, an_top, an_bottom] + options = [spo_hmove, spo_hprop] + linkleft = fields + linkright = fielddefli + statfile = tstatfile1 + onupdatelayout = splitterupda + end + object deftofield: tstockglyphbutton + optionswidget = [ow_destroywidgets] + taborder = 5 + bounds_x = 338 + bounds_y = 5 + bounds_cx = 28 + bounds_cy = 15 + state = [as_disabled, as_localdisabled, as_localimagelist, as_localimagenr, as_localonexecute] + glyph = stg_arrowleft + onexecute = transferfields + end + object fieldtodef: tstockglyphbutton + optionswidget = [ow_destroywidgets] + taborder = 4 + bounds_x = 303 + bounds_y = 5 + bounds_cx = 28 + bounds_cy = 15 + state = [as_disabled, as_localdisabled, as_localimagelist, as_localimagenr, as_localonexecute] + glyph = stg_arrowright + onexecute = deletefields + end + object tstatfile1: tstatfile + filename = 'dbfieldeditor.sta' + options = [sfo_memory] + left = 24 + top = 152 + end + object c: tstringcontainer + strings.data = ( + 'Dataset' + ) + left = 152 + top = 152 + end +end diff --git a/mseide-msegui/lib/common/designutils/msedbfieldeditor.pas b/mseide-msegui/lib/common/designutils/msedbfieldeditor.pas new file mode 100644 index 0000000..1cb6795 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msedbfieldeditor.pas @@ -0,0 +1,457 @@ +{ MSEide Copyright (c) 1999-2011 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit msedbfieldeditor; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + mdb,msegui,mseclasses,mseforms,msedb,msestat,msestatfile,msesimplewidgets, + msegrids,msewidgetgrid,msesplitter,msedataedits,msetypes{msestrings},mseeditglob, + msegraphedits,mseglob,msegridsglob,msestringcontainer; + +const + dbfieldeditorstatname = 'dbfieldeditor.sta'; +type + tmsedbfieldeditorfo = class(tmseform) + tbutton1: tbutton; + tbutton2: tbutton; + index: tintegeredit; + fieldkind: tenumtypeedit; + splitter: tsplitter; + fieldpo: tpointeredit; + classty: tenumtypeedit; + tstatfile1: tstatfile; + fielddefli: tstringgrid; + fields: twidgetgrid; + fieldname: tstringedit; + deftofield: tstockglyphbutton; + fieldtodef: tstockglyphbutton; + c: tstringcontainer; + procedure formloaded(const sender: TObject); + procedure initcla(const sender: tenumtypeedit); + procedure splitterupda(const sender: TObject); + procedure defscellevent(const sender: TObject; var info: celleventinfoty); + procedure defsselectioncha(const sender: TObject); + procedure fieldnamesetvalue(const sender: TObject; var avalue: msestring; + var accept: Boolean); + procedure fieldsdataentered(const sender: TObject); + procedure fieldsrowdel(const sender: tcustomgrid; const aindex: Integer; + const acount: Integer); + procedure transferfields(const sender: TObject); + procedure fieldrowsdeleting(const sender: tcustomgrid; var aindex: Integer; + var acount: Integer); + procedure initfieldkind(const sender: tenumtypeedit); + procedure fieldcellevent(const sender: TObject; var info: celleventinfoty); + procedure fieldselectioncha(const sender: TObject); + procedure deletefields(const sender: TObject); + procedure fieldsort(const sender: tcustomgrid; const index1: Integer; + const index2: Integer; var aresult: Integer); + private + ffields: tpersistentfields; + procedure checkfielddefs; + function findfielddef(aname: msestring): integer; + public + constructor create(const afields: tpersistentfields); reintroduce; + end; + +function editpersistentfields(const instance: tpersistentfields): boolean; + +implementation +uses + mseguiglob,msedbfieldeditor_mfm,typinfo,msewidgets,msestrings; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tpersistentfields1 = class(tpersistentfields); + stringconststy = ( + str_dataset //0 Dataset + ); + +function editpersistentfields(const instance: tpersistentfields): boolean; +var + fo: tmsedbfieldeditorfo; + int1,int2: integer; + ct1: fieldclassty; + ar1: fieldarty; + activebefore: boolean; +begin + result:= false; + fo:= tmsedbfieldeditorfo.create(instance); + try + with fo,tpersistentfields1(instance) do begin + activebefore:= dataset.active; + dataset.active:= false; + for int1:= 0 to count - 1 do begin + items[int1].dataset:= nil; + end; + try + if show(true) = mr_ok then begin + fo.window.nofocus; //remove empty last line + result:= true; + setlength(ar1,fields.rowcount-dataset.fields.count); + for int1:= 0 to high(ar1) do begin + ct1:= getmsefieldclass(fieldclasstypety(classty[int1])); +// ct1:= msefieldtypeclasses[fieldclasstypety(classty[int1])]; + int2:= index[int1]; + if int2 > 0 then begin + dec(int2); + if ct1 <> items[int2].classtype then begin + ar1[int1]:= ct1.create(nil); + ar1[int1].dataset:= dataset; + end + else begin + ar1[int1]:= items[int2]; + fitems[int2]:= nil; + end; + end + else begin + if fieldpo[int1] <> nil then begin + ar1[int1]:= tfield(fieldpo[int1]); + fieldpo[int1]:= nil; + end + else begin + ar1[int1]:= ct1.create(nil); + try + ar1[int1].dataset:= dataset; + except + application.handleexception(nil); + end; + end; + end; + try + ar1[int1].fieldname:= ansistring(fieldname[int1]); + except + application.handleexception(nil); + end; + ar1[int1].fieldkind:= tfieldkind(fieldkind[int1]); + end; + for int1:= 0 to count - 1 do begin + items[int1].free; + end; + for int1:= 0 to high(ar1) do begin + tfield(fieldpo[int1]).free; + end; + fitems:= persistentarty(ar1); + end; + finally + for int1:= 0 to count - 1 do begin + items[int1].dataset:= dataset; + end; + if result then begin + for int1:= 0 to high(ar1) do begin + items[int1].index:= int1; + end; + for int1:= length(ar1) to fields.rowhigh do begin + tfield(fieldpo[int1]).index:= int1; + end; + end; + if activebefore then begin + try + dataset.active:= true; + except + application.handleexception(dataset); + end; + end; + end; + end; + finally + fo.free; + end; +end; + +{ tmsedbfieldeditorfo } + +constructor tmsedbfieldeditorfo.create(const afields: tpersistentfields); +begin + ffields:= afields; + inherited create(nil); +end; + +procedure tmsedbfieldeditorfo.formloaded(const sender: TObject); +var + int1: integer; + field1: tfield; +begin + with ffields.dataset do begin + caption:= c[ord(str_dataset)]+': ' + msestring(name); + fielddefli.rowcount:= fielddefs.count; + for int1:= 0 to fielddefs.count-1 do begin + fielddefli[0][int1]:= msestring(fielddefs[int1].name); + fielddefli[1][int1]:= msestring(getenumname(typeinfo(tfieldtype), + ord(fielddefs[int1].datatype))); + end; + end; + fields.rowcount:= ffields.count + ffields.dataset.fields.count; + for int1:= 0 to ffields.count - 1 do begin + index[int1]:= int1+1; + fieldname[int1]:= msestring(ffields[int1].fieldname); + classty[int1]:= ord(fieldclasstoclasstyp(fieldclassty(ffields[int1].classtype))); + fieldkind[int1]:= ord(ffields[int1].fieldkind); + end; + for int1:= ffields.count to fields.rowhigh do begin + index[int1]:= int1+1; + field1:= ffields.dataset.fields[int1-ffields.count]; + fieldpo[int1]:= field1; + with field1 do begin + self.fieldname[int1]:= msestring(fieldname); + classty[int1]:= ord(fieldclasstoclasstyp(fieldclassty(classtype))); + self.fieldkind[int1]:= ord(fieldkind); + end; + fields.rowfontstate[int1]:= 0; + end; + checkfielddefs; +end; + +procedure tmsedbfieldeditorfo.initcla(const sender: tenumtypeedit); +begin + sender.typeinfopo:= typeinfo(fieldclasstypety); +end; + +procedure tmsedbfieldeditorfo.initfieldkind(const sender: tenumtypeedit); +begin + sender.typeinfopo:= typeinfo(tfieldkind); +end; + +procedure tmsedbfieldeditorfo.splitterupda(const sender: TObject); +begin + deftofield.left:= splitter.left+splitter.bounds_cx; + fieldtodef.left:= splitter.left-fieldtodef.bounds_cx; +// alignx(wam_center,[splitter,deftofield]); +end; + +procedure tmsedbfieldeditorfo.defscellevent(const sender: TObject; + var info: celleventinfoty); +begin + with info do begin + if (eventkind = cek_select) and selected and + (fielddefli.rowfontstate[cell.row] <> -1) then begin + accept:= false; + end; + end; +end; + +procedure tmsedbfieldeditorfo.defsselectioncha(const sender: TObject); +begin + deftofield.enabled:= fielddefli.datacols.hasselection; +end; + +procedure tmsedbfieldeditorfo.fieldnamesetvalue(const sender: TObject; + var avalue: msestring; var accept: Boolean); +var + mstr1: msestring; + int1: integer; +begin + mstr1:= mseuppercase(avalue); + for int1:= 0 to fields.rowcount-1 do begin + if (int1 <> fields.row) and (mstr1 = mseuppercase(fieldname[int1])) then begin + showerror('Field name exists.'); + accept:= false; + break; + end; + end; +end; + +procedure tmsedbfieldeditorfo.checkfielddefs; +var + int1,int2: integer; + ar1: msestringarty; + mstr1: msestring; +begin + setlength(ar1,fields.rowcount); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= mseuppercase(fieldname[int1]); + end; + for int1:= 0 to fielddefli.rowcount - 1 do begin + mstr1:= mseuppercase(fielddefli[0][int1]); + fielddefli.rowfontstate[int1]:= -1; + for int2:= 0 to high(ar1) do begin + if mstr1 = ar1[int2] then begin + fielddefli.rowfontstate[int1]:= 0; + fielddefli.datacols.selected[makegridcoord(-1,int1)]:= false; + break; + end; + end; + end; +end; + +procedure tmsedbfieldeditorfo.fieldsdataentered(const sender: TObject); +begin + checkfielddefs; +end; + +procedure tmsedbfieldeditorfo.fieldsrowdel(const sender: tcustomgrid; + const aindex: Integer; const acount: Integer); +begin + checkfielddefs; +end; + +procedure tmsedbfieldeditorfo.transferfields(const sender: TObject); +var + int1,int2: integer; + ar1,ar2: integerarty; +begin + ar1:= fielddefli.datacols.selectedrows; + if high(ar1) >= 0 then begin + setlength(ar2,length(ar1)); + int2:= 0; + fields.beginupdate; + for int1:= 0 to high(ar1) do begin + fields.appendrow(true); + try + fields.row:= fields.rowhigh; + fieldpo[fields.rowhigh]:= + ffields.dataset.fielddefs[ar1[int1]].createfield(nil); + tfield(fieldpo[fields.rowhigh]).dataset:= nil; + fieldname[fields.rowhigh]:= fielddefli[0][ar1[int1]]; + classty[fields.rowhigh]:= ord(fieldclasstoclasstyp( + ffields.dataset.fielddefs[ar1[int1]].fieldclass)); + fieldkind[fields.rowhigh]:= ord(tfield(fieldpo[fields.rowhigh]).fieldkind); + ar2[int2]:= fields.rowhigh; + inc(int2); + except + fields.rowcount:= fields.rowcount - 1; + application.handleexception(nil); + end; + fielddefli.datacols.clearselection; + end; + setlength(ar2,int2); + fields.datacols.selectedrows:= ar2; + fields.endupdate; + // fields.sort; + checkfielddefs; + for int1:= ar1[high(ar1)] + 1 to fielddefli.rowhigh do begin + if fielddefli.rowfontstate[int1] = -1 then begin + fielddefli.row:= int1; + exit; + end; + end; + for int1:= 0 to fielddefli.rowhigh do begin + if fielddefli.rowfontstate[int1] = -1 then begin + fielddefli.row:= int1; + exit; + end; + end; + end; +end; + +procedure tmsedbfieldeditorfo.fieldrowsdeleting(const sender: tcustomgrid; + var aindex: Integer; var acount: Integer); +var + int1: integer; +begin + for int1:= aindex to aindex + acount - 1 do begin + if sender.rowfontstate[int1] <> -1 then begin + acount:= 0; + break; + end; + end; + for int1:= aindex to aindex + acount - 1 do begin + tfield(fieldpo[int1]).free; + end; +end; + +procedure tmsedbfieldeditorfo.fieldsort(const sender: tcustomgrid; + const index1: Integer; const index2: Integer; + var aresult: Integer); +begin + aresult:= fields.rowfontstate[index1] - fields.rowfontstate[index2]; +end; + +procedure tmsedbfieldeditorfo.fieldcellevent(const sender: TObject; + var info: celleventinfoty); +begin + with info do begin + if eventkind = cek_enter then begin + if fields.rowfontstate[cell.row] = -1 then begin + fields.datacols.options:= fields.datacols.options - [co_readonly]; + fields.optionsgrid:= fields.optionsgrid + [og_rowdeleting]; + end + else begin + fields.datacols.options:= fields.datacols.options + [co_readonly]; + fields.optionsgrid:= fields.optionsgrid - [og_rowdeleting]; + end; + end; + if (eventkind = cek_select) and selected then begin + if fields.rowfontstate[cell.row] <> -1 then begin + accept:= false; + end; + end; + end; +end; + +procedure tmsedbfieldeditorfo.fieldselectioncha(const sender: TObject); +begin + fieldtodef.enabled:= fields.datacols.hasselection and + (length(fields.datacols.selectedrows) > 0); +end; + +function tmsedbfieldeditorfo.findfielddef(aname: msestring): integer; +var + int1: integer; +begin + result:= invalidaxis; + aname:= struppercase(aname); + for int1:= 0 to fielddefli.rowhigh do begin + if msestringicompupper(fielddefli[0][int1],aname) = 0 then begin + result:= int1; + break; + end; + end; +end; + +procedure tmsedbfieldeditorfo.deletefields(const sender: TObject); +var + ar1,ar2: integerarty; + int1: integer; + int2: integer; +begin + ar1:= fields.datacols.selectedrows; + setlength(ar2,length(ar1)); //max + int2:= 0; + for int1:= high(ar1) downto 0 do begin + ar2[int2]:= findfielddef(fieldname[ar1[int1]]); + if ar2[int2] >= 0 then begin + inc(int2); + end; + end; + ffields.beginupdate; + for int1:= high(ar1) downto 0 do begin + fields.deleterow(ar1[int1]); + end; + ffields.endupdate; + if int2 > 0 then begin + setlength(ar2,int2); + fielddefli.row:= ar2[high(ar2)]; + fielddefli.datacols.selectedrows:= ar2; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/msedbfieldeditor_mfm.pas b/mseide-msegui/lib/common/designutils/msedbfieldeditor_mfm.pas new file mode 100644 index 0000000..504cf97 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msedbfieldeditor_mfm.pas @@ -0,0 +1,435 @@ +unit msedbfieldeditor_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msedbfieldeditor; + +const + objdata: record size: integer; data: array[0..8359] of byte end = + (size: 8360; data: ( + 84,80,70,48,19,116,109,115,101,100,98,102,105,101,108,100,101,100,105,116, + 111,114,102,111,18,109,115,101,100,98,102,105,101,108,100,101,100,105,116,111, + 114,102,111,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,11,111,119,95,115,117,98,102, + 111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,9,111,119,95,104,105,110,116,111,110,0,7,118,105,115,105,98,108, + 101,8,8,98,111,117,110,100,115,95,120,2,29,8,98,111,117,110,100,115, + 95,121,3,248,0,9,98,111,117,110,100,115,95,99,120,3,89,2,9,98, + 111,117,110,100,115,95,99,121,3,216,0,23,99,111,110,116,97,105,110,101, + 114,46,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,11,111,119,95, + 115,117,98,102,111,99,117,115,19,111,119,95,109,111,117,115,101,116,114,97, + 110,115,112,97,114,101,110,116,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,0,26,99,111,110,116,97,105,110,101,114,46,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95,102,114, + 97,109,101,105,109,97,103,101,111,102,102,115,101,116,28,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,100,105,115,97,98, + 108,101,100,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102, + 102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,97,99, + 116,105,118,101,15,102,114,108,95,111,112,116,105,111,110,115,115,107,105,110, + 0,27,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100, + 25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118, + 101,0,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1, + 2,0,2,0,3,89,2,3,216,0,0,7,111,112,116,105,111,110,115,11, + 13,102,111,95,99,108,111,115,101,111,110,101,115,99,15,102,111,95,97,117, + 116,111,114,101,97,100,115,116,97,116,16,102,111,95,97,117,116,111,119,114, + 105,116,101,115,116,97,116,10,102,111,95,115,97,118,101,112,111,115,12,102, + 111,95,115,97,118,101,115,116,97,116,101,0,8,115,116,97,116,102,105,108, + 101,7,10,116,115,116,97,116,102,105,108,101,49,16,111,110,101,118,101,110, + 116,108,111,111,112,115,116,97,114,116,7,10,102,111,114,109,108,111,97,100, + 101,100,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,8, + 116,109,115,101,102,111,114,109,0,7,116,98,117,116,116,111,110,8,116,98, + 117,116,116,111,110,49,8,116,97,98,111,114,100,101,114,2,3,8,98,111, + 117,110,100,115,95,120,3,216,1,8,98,111,117,110,100,115,95,121,3,184, + 0,9,98,111,117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115, + 95,99,121,2,22,7,97,110,99,104,111,114,115,11,8,97,110,95,114,105, + 103,104,116,9,97,110,95,98,111,116,116,111,109,0,5,115,116,97,116,101, + 11,10,97,115,95,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97, + 108,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,99,97,112, + 116,105,111,110,0,7,99,97,112,116,105,111,110,6,2,79,75,11,109,111, + 100,97,108,114,101,115,117,108,116,7,5,109,114,95,111,107,0,0,7,116, + 98,117,116,116,111,110,8,116,98,117,116,116,111,110,50,8,98,111,117,110, + 100,115,95,120,3,24,2,8,98,111,117,110,100,115,95,121,3,184,0,9, + 98,111,117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99, + 121,2,22,7,97,110,99,104,111,114,115,11,8,97,110,95,114,105,103,104, + 116,9,97,110,95,98,111,116,116,111,109,0,5,115,116,97,116,101,11,15, + 97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,7,99,97,112, + 116,105,111,110,6,6,67,97,110,99,101,108,11,109,111,100,97,108,114,101, + 115,117,108,116,7,9,109,114,95,99,97,110,99,101,108,0,0,11,116,115, + 116,114,105,110,103,103,114,105,100,10,102,105,101,108,100,100,101,102,108,105, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,9,70,105,101,108, + 100,100,101,102,115,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112, + 111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109,97,103, + 101,111,102,102,115,101,116,28,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109,111,117, + 115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,15,102,114, + 108,95,111,112,116,105,111,110,115,115,107,105,110,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98, + 108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99, + 116,105,118,101,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101, + 114,2,1,8,98,111,117,110,100,115,95,120,3,80,1,8,98,111,117,110, + 100,115,95,121,2,7,9,98,111,117,110,100,115,95,99,120,3,2,1,9, + 98,111,117,110,100,115,95,99,121,3,171,0,12,98,111,117,110,100,115,95, + 99,120,109,105,110,2,50,7,97,110,99,104,111,114,115,11,7,97,110,95, + 108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116, + 9,97,110,95,98,111,116,116,111,109,0,11,111,112,116,105,111,110,115,103, + 114,105,100,11,12,111,103,95,99,111,108,115,105,122,105,110,103,19,111,103, + 95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101,114,20,111,103, + 95,99,111,108,99,104,97,110,103,101,111,110,116,97,98,107,101,121,10,111, + 103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112, + 117,112,0,14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,2, + 16,100,97,116,97,99,111,108,115,46,111,112,116,105,111,110,115,11,11,99, + 111,95,114,101,97,100,111,110,108,121,14,99,111,95,102,111,99,117,115,115, + 101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116, + 12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108, + 116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99, + 116,12,99,111,95,115,97,118,101,115,116,97,116,101,0,14,100,97,116,97, + 99,111,108,115,46,105,116,101,109,115,14,1,5,119,105,100,116,104,2,123, + 7,111,112,116,105,111,110,115,11,11,99,111,95,114,101,97,100,111,110,108, + 121,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95, + 109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101, + 108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12, + 99,111,95,114,111,119,115,101,108,101,99,116,7,99,111,95,102,105,108,108, + 12,99,111,95,115,97,118,101,115,116,97,116,101,0,11,111,112,116,105,111, + 110,115,101,100,105,116,11,14,115,99,111,101,95,101,97,116,114,101,116,117, + 114,110,0,10,118,97,108,117,101,102,97,108,115,101,6,1,48,9,118,97, + 108,117,101,116,114,117,101,6,1,49,0,1,5,119,105,100,116,104,3,129, + 0,7,111,112,116,105,111,110,115,11,11,99,111,95,114,101,97,100,111,110, + 108,121,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111, + 95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115, + 101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116, + 12,99,111,95,114,111,119,115,101,108,101,99,116,15,99,111,95,112,114,111, + 112,111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,115,116,97, + 116,101,0,11,111,112,116,105,111,110,115,101,100,105,116,11,14,115,99,111, + 101,95,101,97,116,114,101,116,117,114,110,0,10,118,97,108,117,101,102,97, + 108,115,101,6,1,48,9,118,97,108,117,101,116,114,117,101,6,1,49,0, + 0,13,102,105,120,114,111,119,115,46,99,111,117,110,116,2,1,13,102,105, + 120,114,111,119,115,46,105,116,101,109,115,14,1,6,104,101,105,103,104,116, + 2,16,14,99,97,112,116,105,111,110,115,46,99,111,117,110,116,2,2,14, + 99,97,112,116,105,111,110,115,46,105,116,101,109,115,14,1,7,99,97,112, + 116,105,111,110,6,4,78,97,109,101,0,1,7,99,97,112,116,105,111,110, + 6,4,84,121,112,101,0,0,0,0,14,114,111,119,102,111,110,116,115,46, + 99,111,117,110,116,2,1,14,114,111,119,102,111,110,116,115,46,105,116,101, + 109,115,14,1,5,99,111,108,111,114,4,4,0,0,160,4,110,97,109,101, + 6,11,115,116,102,95,100,101,102,97,117,108,116,6,120,115,99,97,108,101, + 2,1,10,108,111,99,97,108,112,114,111,112,115,11,9,102,108,112,95,99, + 111,108,111,114,10,102,108,112,95,120,115,99,97,108,101,0,0,0,13,100, + 97,116,97,114,111,119,104,101,105,103,104,116,2,16,11,111,110,99,101,108, + 108,101,118,101,110,116,7,13,100,101,102,115,99,101,108,108,101,118,101,110, + 116,18,111,110,115,101,108,101,99,116,105,111,110,99,104,97,110,103,101,100, + 7,16,100,101,102,115,115,101,108,101,99,116,105,111,110,99,104,97,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,11,116,119,105, + 100,103,101,116,103,114,105,100,6,102,105,101,108,100,115,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,6,70,105,101,108,100,115,16,102,114, + 97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112,95,116, + 111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,28, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 100,105,115,97,98,108,101,100,25,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107, + 101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102, + 115,101,116,97,99,116,105,118,101,15,102,114,108,95,111,112,116,105,111,110, + 115,115,107,105,110,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102,97,99, + 101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111,117,115, + 101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115, + 101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2, + 0,2,0,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110, + 100,115,95,120,2,8,8,98,111,117,110,100,115,95,121,2,7,9,98,111, + 117,110,100,115,95,99,120,3,67,1,9,98,111,117,110,100,115,95,99,121, + 3,171,0,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116, + 6,97,110,95,116,111,112,9,97,110,95,98,111,116,116,111,109,0,11,111, + 112,116,105,111,110,115,103,114,105,100,11,12,111,103,95,99,111,108,115,105, + 122,105,110,103,12,111,103,95,114,111,119,109,111,118,105,110,103,15,111,103, + 95,107,101,121,114,111,119,109,111,118,105,110,103,15,111,103,95,114,111,119, + 105,110,115,101,114,116,105,110,103,14,111,103,95,114,111,119,100,101,108,101, + 116,105,110,103,19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101, + 110,116,101,114,15,111,103,95,97,117,116,111,102,105,114,115,116,114,111,119, + 13,111,103,95,97,117,116,111,97,112,112,101,110,100,9,111,103,95,115,111, + 114,116,101,100,20,111,103,95,99,111,108,99,104,97,110,103,101,111,110,116, + 97,98,107,101,121,10,111,103,95,119,114,97,112,99,111,108,12,111,103,95, + 97,117,116,111,112,111,112,117,112,0,13,102,105,120,99,111,108,115,46,99, + 111,117,110,116,2,1,13,102,105,120,99,111,108,115,46,105,116,101,109,115, + 14,1,5,119,105,100,116,104,2,15,7,110,117,109,115,116,101,112,2,1, + 0,0,13,102,105,120,114,111,119,115,46,99,111,117,110,116,2,1,13,102, + 105,120,114,111,119,115,46,105,116,101,109,115,14,1,6,104,101,105,103,104, + 116,2,16,14,99,97,112,116,105,111,110,115,46,99,111,117,110,116,2,5, + 14,99,97,112,116,105,111,110,115,46,105,116,101,109,115,14,1,0,1,0, + 1,7,99,97,112,116,105,111,110,6,4,78,97,109,101,0,1,7,99,97, + 112,116,105,111,110,6,10,67,108,97,115,115,32,116,121,112,101,0,1,7, + 99,97,112,116,105,111,110,6,10,70,105,101,108,100,32,107,105,110,100,0, + 0,0,0,14,114,111,119,102,111,110,116,115,46,99,111,117,110,116,2,1, + 14,114,111,119,102,111,110,116,115,46,105,116,101,109,115,14,1,5,99,111, + 108,111,114,4,4,0,0,160,4,110,97,109,101,6,11,115,116,102,95,100, + 101,102,97,117,108,116,6,120,115,99,97,108,101,2,1,10,108,111,99,97, + 108,112,114,111,112,115,11,9,102,108,112,95,99,111,108,111,114,10,102,108, + 112,95,120,115,99,97,108,101,0,0,0,14,100,97,116,97,99,111,108,115, + 46,99,111,117,110,116,2,5,16,100,97,116,97,99,111,108,115,46,111,112, + 116,105,111,110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99, + 116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95, + 107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101, + 108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111, + 95,115,97,118,101,115,116,97,116,101,0,14,100,97,116,97,99,111,108,115, + 46,105,116,101,109,115,14,7,5,105,110,100,101,120,1,5,119,105,100,116, + 104,2,13,7,111,112,116,105,111,110,115,11,12,99,111,95,105,110,118,105, + 115,105,98,108,101,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116, + 14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107, + 101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108, + 101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111,95, + 115,97,118,101,118,97,108,117,101,12,99,111,95,115,97,118,101,115,116,97, + 116,101,0,10,119,105,100,103,101,116,110,97,109,101,6,5,105,110,100,101, + 120,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100,105,110, + 116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,7,102,105,101,108, + 100,112,111,1,5,119,105,100,116,104,2,12,7,111,112,116,105,111,110,115, + 11,12,99,111,95,105,110,118,105,115,105,98,108,101,12,99,111,95,100,114, + 97,119,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101, + 99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111, + 95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115, + 101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99, + 111,95,115,97,118,101,115,116,97,116,101,0,10,119,105,100,103,101,116,110, + 97,109,101,6,7,102,105,101,108,100,112,111,9,100,97,116,97,99,108,97, + 115,115,7,20,116,103,114,105,100,112,111,105,110,116,101,114,100,97,116,97, + 108,105,115,116,0,7,9,102,105,101,108,100,110,97,109,101,1,5,119,105, + 100,116,104,2,97,7,111,112,116,105,111,110,115,11,14,99,111,95,102,111, + 99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101, + 108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111, + 95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115, + 101,108,101,99,116,7,99,111,95,102,105,108,108,12,99,111,95,115,97,118, + 101,118,97,108,117,101,12,99,111,95,115,97,118,101,115,116,97,116,101,0, + 10,119,105,100,103,101,116,110,97,109,101,6,9,102,105,101,108,100,110,97, + 109,101,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109, + 115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,7,99, + 108,97,115,115,116,121,1,5,119,105,100,116,104,2,92,7,111,112,116,105, + 111,110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14, + 99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101, + 121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101, + 99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,15,99,111,95,112, + 114,111,112,111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,118, + 97,108,117,101,12,99,111,95,115,97,118,101,115,116,97,116,101,0,10,119, + 105,100,103,101,116,110,97,109,101,6,7,99,108,97,115,115,116,121,9,100, + 97,116,97,99,108,97,115,115,7,17,116,103,114,105,100,101,110,117,109,100, + 97,116,97,108,105,115,116,0,7,9,102,105,101,108,100,107,105,110,100,1, + 5,119,105,100,116,104,2,84,7,111,112,116,105,111,110,115,11,14,99,111, + 95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115, + 101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116, + 14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114, + 111,119,115,101,108,101,99,116,15,99,111,95,112,114,111,112,111,114,116,105, + 111,110,97,108,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111, + 95,115,97,118,101,115,116,97,116,101,0,10,119,105,100,103,101,116,110,97, + 109,101,6,9,102,105,101,108,100,107,105,110,100,9,100,97,116,97,99,108, + 97,115,115,7,17,116,103,114,105,100,101,110,117,109,100,97,116,97,108,105, + 115,116,0,0,13,100,97,116,97,114,111,119,104,101,105,103,104,116,2,16, + 14,111,110,114,111,119,115,100,101,108,101,116,105,110,103,7,17,102,105,101, + 108,100,114,111,119,115,100,101,108,101,116,105,110,103,13,111,110,114,111,119, + 115,100,101,108,101,116,101,100,7,12,102,105,101,108,100,115,114,111,119,100, + 101,108,11,111,110,99,101,108,108,101,118,101,110,116,7,14,102,105,101,108, + 100,99,101,108,108,101,118,101,110,116,18,111,110,115,101,108,101,99,116,105, + 111,110,99,104,97,110,103,101,100,7,17,102,105,101,108,100,115,101,108,101, + 99,116,105,111,110,99,104,97,6,111,110,115,111,114,116,7,9,102,105,101, + 108,100,115,111,114,116,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,12,116,105,110,116,101,103,101,114,101,100,105,116,5,105,110,100, + 101,120,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111, + 119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,11, + 111,112,116,105,111,110,115,115,107,105,110,11,10,111,115,107,95,110,111,115, + 107,105,110,0,8,116,97,98,111,114,100,101,114,2,1,7,118,105,115,105, + 98,108,101,8,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110, + 100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,13,9,98, + 111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100, + 105,116,49,11,13,111,101,49,95,115,97,118,101,118,97,108,117,101,0,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,12,116,112, + 111,105,110,116,101,114,101,100,105,116,7,102,105,101,108,100,112,111,11,111, + 112,116,105,111,110,115,115,107,105,110,11,10,111,115,107,95,110,111,115,107, + 105,110,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100, + 115,95,120,2,14,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,120,2,12,9,98,111,117,110,100,115,95,99,121,2,16, + 11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100, + 111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121, + 16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101, + 95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114, + 101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116, + 111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115, + 111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95, + 97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101, + 108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,12,111,112, + 116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111, + 112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101, + 99,117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0,7, + 118,105,115,105,98,108,101,8,0,0,11,116,115,116,114,105,110,103,101,100, + 105,116,9,102,105,101,108,100,110,97,109,101,11,111,112,116,105,111,110,115, + 115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111, + 110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,3,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,27,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,97, + 9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115, + 101,100,105,116,49,11,13,111,101,49,95,115,97,118,101,118,97,108,117,101, + 0,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,17,102,105,101, + 108,100,115,100,97,116,97,101,110,116,101,114,101,100,10,111,110,115,101,116, + 118,97,108,117,101,7,17,102,105,101,108,100,110,97,109,101,115,101,116,118, + 97,108,117,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,0,13,116,101,110,117,109,116,121,112,101,101,100,105,116,7,99,108,97, + 115,115,116,121,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11, + 19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116, + 0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102, + 114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109, + 101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108, + 111,114,99,108,105,101,110,116,4,2,0,0,128,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101, + 108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102, + 114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95, + 102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107, + 101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,97,99,116,105,118,101,0,18,102,114,97,109,101,46,98,117,116, + 116,111,110,46,99,111,108,111,114,4,5,0,0,144,8,116,97,98,111,114, + 100,101,114,2,4,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100, + 115,95,120,2,125,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,120,2,92,9,98,111,117,110,100,115,95,99,121,2,16, + 12,111,112,116,105,111,110,115,101,100,105,116,49,11,13,111,101,49,95,115, + 97,118,101,118,97,108,117,101,0,11,111,112,116,105,111,110,115,101,100,105, + 116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99, + 108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114, + 99,97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114, + 110,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101, + 115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101, + 120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110, + 101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25, + 111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116, + 99,108,105,99,107,22,111,101,95,102,111,99,117,115,114,101,99,116,111,110, + 114,101,97,100,111,110,108,121,10,111,101,95,110,111,116,110,117,108,108,0, + 12,118,97,108,117,101,100,101,102,97,117,108,116,2,0,3,109,105,110,2, + 0,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,99,111,117,110, + 116,2,1,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,105,116, + 101,109,115,14,1,0,0,6,111,110,105,110,105,116,7,7,105,110,105,116, + 99,108,97,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0, + 0,13,116,101,110,117,109,116,121,112,101,101,100,105,116,9,102,105,101,108, + 100,107,105,110,100,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49, + 11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104, + 116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95, + 102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,12,102,114,97, + 109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99,111, + 108,111,114,99,108,105,101,110,116,4,2,0,0,128,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 28,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101, + 116,100,105,115,97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99, + 107,101,100,26,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,97,99,116,105,118,101,0,18,102,114,97,109,101,46,98,117, + 116,116,111,110,46,119,105,100,116,104,2,15,18,102,114,97,109,101,46,98, + 117,116,116,111,110,46,99,111,108,111,114,4,5,0,0,144,8,116,97,98, + 111,114,100,101,114,2,5,7,118,105,115,105,98,108,101,8,8,98,111,117, + 110,100,115,95,120,3,218,0,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,120,2,84,9,98,111,117,110,100,115,95,99, + 121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,13,111,101, + 49,95,115,97,118,101,118,97,108,117,101,0,11,111,112,116,105,111,110,115, + 101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111, + 101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99, + 107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101, + 116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101, + 95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111, + 101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110, + 100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101, + 99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105, + 114,115,116,99,108,105,99,107,22,111,101,95,102,111,99,117,115,114,101,99, + 116,111,110,114,101,97,100,111,110,108,121,10,111,101,95,110,111,116,110,117, + 108,108,0,12,118,97,108,117,101,100,101,102,97,117,108,116,2,0,3,109, + 105,110,2,0,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,99, + 111,117,110,116,2,1,19,100,114,111,112,100,111,119,110,46,99,111,108,115, + 46,105,116,101,109,115,14,1,0,0,6,111,110,105,110,105,116,7,13,105, + 110,105,116,102,105,101,108,100,107,105,110,100,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,14,0,0,0,9,116,115,112,108,105,116,116,101, + 114,8,115,112,108,105,116,116,101,114,5,99,111,108,111,114,4,3,0,0, + 144,8,116,97,98,111,114,100,101,114,2,6,8,98,111,117,110,100,115,95, + 120,3,75,1,8,98,111,117,110,100,115,95,121,2,24,9,98,111,117,110, + 100,115,95,99,120,2,5,9,98,111,117,110,100,115,95,99,121,3,154,0, + 7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110, + 95,116,111,112,9,97,110,95,98,111,116,116,111,109,0,7,111,112,116,105, + 111,110,115,11,9,115,112,111,95,104,109,111,118,101,9,115,112,111,95,104, + 112,114,111,112,0,8,108,105,110,107,108,101,102,116,7,6,102,105,101,108, + 100,115,9,108,105,110,107,114,105,103,104,116,7,10,102,105,101,108,100,100, + 101,102,108,105,8,115,116,97,116,102,105,108,101,7,10,116,115,116,97,116, + 102,105,108,101,49,14,111,110,117,112,100,97,116,101,108,97,121,111,117,116, + 7,12,115,112,108,105,116,116,101,114,117,112,100,97,0,0,17,116,115,116, + 111,99,107,103,108,121,112,104,98,117,116,116,111,110,10,100,101,102,116,111, + 102,105,101,108,100,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,8, + 116,97,98,111,114,100,101,114,2,5,8,98,111,117,110,100,115,95,120,3, + 82,1,8,98,111,117,110,100,115,95,121,2,5,9,98,111,117,110,100,115, + 95,99,120,2,28,9,98,111,117,110,100,115,95,99,121,2,15,5,115,116, + 97,116,101,11,11,97,115,95,100,105,115,97,98,108,101,100,16,97,115,95, + 108,111,99,97,108,100,105,115,97,98,108,101,100,17,97,115,95,108,111,99, + 97,108,105,109,97,103,101,108,105,115,116,15,97,115,95,108,111,99,97,108, + 105,109,97,103,101,110,114,17,97,115,95,108,111,99,97,108,111,110,101,120, + 101,99,117,116,101,0,5,103,108,121,112,104,7,13,115,116,103,95,97,114, + 114,111,119,108,101,102,116,9,111,110,101,120,101,99,117,116,101,7,14,116, + 114,97,110,115,102,101,114,102,105,101,108,100,115,0,0,17,116,115,116,111, + 99,107,103,108,121,112,104,98,117,116,116,111,110,10,102,105,101,108,100,116, + 111,100,101,102,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,8,116, + 97,98,111,114,100,101,114,2,4,8,98,111,117,110,100,115,95,120,3,47, + 1,8,98,111,117,110,100,115,95,121,2,5,9,98,111,117,110,100,115,95, + 99,120,2,28,9,98,111,117,110,100,115,95,99,121,2,15,5,115,116,97, + 116,101,11,11,97,115,95,100,105,115,97,98,108,101,100,16,97,115,95,108, + 111,99,97,108,100,105,115,97,98,108,101,100,17,97,115,95,108,111,99,97, + 108,105,109,97,103,101,108,105,115,116,15,97,115,95,108,111,99,97,108,105, + 109,97,103,101,110,114,17,97,115,95,108,111,99,97,108,111,110,101,120,101, + 99,117,116,101,0,5,103,108,121,112,104,7,14,115,116,103,95,97,114,114, + 111,119,114,105,103,104,116,9,111,110,101,120,101,99,117,116,101,7,12,100, + 101,108,101,116,101,102,105,101,108,100,115,0,0,9,116,115,116,97,116,102, + 105,108,101,10,116,115,116,97,116,102,105,108,101,49,8,102,105,108,101,110, + 97,109,101,6,17,100,98,102,105,101,108,100,101,100,105,116,111,114,46,115, + 116,97,7,111,112,116,105,111,110,115,11,10,115,102,111,95,109,101,109,111, + 114,121,0,4,108,101,102,116,2,24,3,116,111,112,3,152,0,0,0,16, + 116,115,116,114,105,110,103,99,111,110,116,97,105,110,101,114,1,99,12,115, + 116,114,105,110,103,115,46,100,97,116,97,1,6,7,68,97,116,97,115,101, + 116,0,4,108,101,102,116,3,152,0,3,116,111,112,3,152,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tmsedbfieldeditorfo,''); +end. diff --git a/mseide-msegui/lib/common/designutils/msedesignintf.pas b/mseide-msegui/lib/common/designutils/msedesignintf.pas new file mode 100644 index 0000000..3dc0922 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msedesignintf.pas @@ -0,0 +1,1674 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msedesignintf; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +{$ifndef mse_methodswap} + {$define mse_nomethodswap} +{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses,msegraphutils,mselist,sysutils,typinfo,msebitmap, + msetypes,msestrings,msegraphics,msegui,mseglob,msearrayutils, + mseclasses,mseforms,msestat,mserichstring,msecomptree; +const + defaultmoduleclassname = 'tmseform'; +type + initcomponentprocty = + procedure(const acomponent: tcomponent; const aparent: tcomponent) of object; + + componentclassinfoty = record + classtyp: tcomponentclass; + icon: integer; + page: integer; + defaultindex: integer; + end; + pcomponentclassinfoty = ^componentclassinfoty; + + comppagety = record + caption: msestring; + hint: msestring; + end; + comppagearty = array of comppagety; + + tcomponentclasslist = class(torderedrecordlist) + private + fselectedclass: tcomponentclass; + fimagelist: timagelist; + fpagenames: comppagearty; + fpagecomporders: integerararty; + fdefaultindex: integer; + fdefaultorder: boolean; + function getpagecomporders(const index: integer): integerarty; + procedure setpagecomporders(const index: integer; + const Value: integerarty); + procedure checkpageindex(const index: integer); + procedure setdefaultorder(const avalue: boolean); + protected + function findpage(const pagename: msestring): integer; + function addpage(const pagename: msestring): integer; + function getcomparefunc: sortcomparemethodty; override; + function compare(const l,r): integer; + function componentcounts: integerarty; + public + constructor create; + destructor destroy; override; + function indexof(const value: tcomponentclass): integer; //-1 if not found + function add(var value: componentclassinfoty): integer; + //-1 if allready registred + function itempo(const index: integer): pcomponentclassinfoty; + procedure registercomponents(const page: msestring; + const componentclasses: array of tcomponentclass); + procedure registercomponenttabhints(const pages: array of msestring; + const hints: array of msestring); + //pages are case sensitive, pages mustexist + function pagehigh: integer; + function pagenames: comppagearty; + property pagecomporders[const index: integer]: integerarty + read getpagecomporders write setpagecomporders; + procedure drawcomponenticon(const acomponent: tcomponent; + const canvas: tcanvas; const dest: rectty); + procedure updatestat(const filer: tstatfiler); + property selectedclass: tcomponentclass read fselectedclass write fselectedclass; + property imagelist: timagelist read fimagelist; + property defaultorder: boolean read fdefaultorder write setdefaultorder; + //nil for unselect + end; + + idesignerselections = interface(inullinterface) + function add(const item: tcomponent): integer; + function equals(const list: idesignerselections): boolean; + function get(index: integer): tcomponent; + function getcount: integer; + function getarray: componentarty; + property count: integer read getcount; + property items[index: integer]: tcomponent read get; default; + end; + + componenteditorstatety = (cs_canedit); + componenteditorstatesty = set of componenteditorstatety; + + icomponenteditor = interface(inullinterface) + procedure edit; + function state: componenteditorstatesty; + end; + + compfilterfuncty = function(const acomponent: tcomponent): boolean of object; + + idesigner = interface(inullinterface) + procedure componentmodified(const component: tobject; + const apropname: string = ''; const apropindex: int32 = -1); + function createcurrentcomponent(const module: tmsecomponent): tcomponent; + function hascurrentcomponent: boolean; + procedure addcomponent(const module: tmsecomponent; + const acomponent: tcomponent); + procedure deleteselection(adoall: Boolean = False); + procedure deletecomponent(const acomponent: tcomponent); + procedure clearselection; + procedure selectcomponent(instance: tcomponent); + procedure setselections(const list: idesignerselections); + procedure noselection; + function getmethod(const name: string; const methodowner: tmsecomponent; + const atype: ptypeinfo; const searchancestors: boolean): tmethod; + function getmethodname(const method: tmethod; const comp: tcomponent): string; + procedure changemethodname(const method: tmethod; newname: string; + const atypeinfo: ptypeinfo); + function createmethod(const name: string; const module: tmsecomponent; + const atype: ptypeinfo): tmethod; + procedure checkmethod(const method: tmethod; const name: string; + const module: tmsecomponent; const atype: ptypeinfo); + function isownedmethod(const root: tcomponent; + const method: tmethod): boolean; + function getcomponentname(const comp: tcomponent): string; + //returns qualified name + procedure validaterename(const acomponent: tcomponent; const curname, newname: string); + function getcomponentdispname(const comp: tcomponent): string; + //returns qualified name into root + function getclassname(const comp: tcomponent): string; + //returns submoduleclass if appropriate + function getcomponent(const aname: string; const aroot: tcomponent): tcomponent; + //handles qualified names for foreign forms + function componentcanedit: boolean; + function getcomponenteditor: icomponenteditor; + function getcomponentlist(const acomponentclass: tcomponentclass; + const filter: compfilterfuncty = nil; + const allmodules: boolean = false): componentarty; + function getcomponentnamelist(const acomponents: componentarty; + const amodule: tmsecomponent): msestringarty; overload; + //nil values ignored + function getcomponentnamelist(const acomponentclass: tcomponentclass; + const includeinherited: boolean; + const aowner: tcomponent = nil; + const filter: compfilterfuncty = nil): msestringarty; overload; + function getcomponentnametree(const acomponentclass: tcomponentclass; + const includeinherited: boolean; + const findmode: boolean; + const aowner: tcomponent = nil; + const filter: compfilterfuncty = nil; + const amodule: tcomponent = nil): tcompnameitem; + procedure setactivemodule(const adesignform: tcustommseform); + function getmodulex(const amodule: tmsecomponent): integer; + procedure setmodulex(const amodule: tmsecomponent; avalue: integer); + function getmoduley(const amodule: tmsecomponent): integer; + procedure setmoduley(const amodule: tmsecomponent; avalue: integer); + procedure modulesizechanged(const amodule: tmsecomponent); + end; + + idesignnotification = interface(inullinterface) + procedure itemdeleted(const adesigner: idesigner; + const amodule: tmsecomponent; const aitem: tcomponent); + procedure iteminserted(const adesigner: idesigner; + const amodule: tmsecomponent; const aitem: tcomponent); + procedure itemsmodified(const adesigner: idesigner; const aitem: tobject); + //nil for undefined aitem + procedure componentnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const aitem: tcomponent; + const newname: string); + procedure moduleclassnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); + procedure instancevarnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); + procedure selectionchanged(const adesigner: idesigner; + const aselection: idesignerSelections); + + procedure moduleactivated(const adesigner: idesigner; + const amodule: tmsecomponent); + procedure moduledeactivated(const adesigner: idesigner; + const amodule: tmsecomponent); + procedure moduledestroyed(const adesigner: idesigner; + const amodule: tmsecomponent); + + procedure methodcreated(const adesigner: idesigner; + const amodule: tmsecomponent; + const aname: string; const atype: ptypeinfo); + procedure methodnamechanged(const adesigner: idesigner; + const amodule: tmsecomponent; + const newname,oldname: string; const atypeinfo: ptypeinfo); + procedure showobjecttext(const adesigner: idesigner; + const afilename: filenamety; const backupcreated: boolean); + procedure closeobjecttext(const adesigner: idesigner; + const afilename: filenamety; var cancel: boolean); + + procedure beforefilesave(const adesigner: idesigner; + const afilename: filenamety); + procedure beforemake(const adesigner: idesigner; const maketag: integer; + var abort: boolean); + procedure aftermake(const adesigner: idesigner; const exitcode: integer); + end; + + selectedinfoty = record + instance: tcomponent; + end; + pselectedinfoty = ^selectedinfoty; + + objinfoty = record + owner: tcomponent; + parent: twidget; + ownerindex: integer; + parentindex: integer; + objtext: string; + end; + objinfoarty = array of objinfoty; + + tdesignerselections = class(trecordlist,idesignerselections) + private + fupdating: integer; + factcomp: tcomponent; + fpasteowner: tcomponent; + fpasteroot: tcomponent; + function Getitems(const index: integer): tcomponent; + procedure Setitems(const index: integer; const Value: tcomponent); + procedure dosetactcomp(component: tcomponent); + procedure doadd(component: tcomponent); + {$ifdef mse_nomethodswap} + procedure setpastemethodproperty(reader: treader; + instance: tpersistent; + propinfo: ppropinfo; const themethodname: string; + var handled: boolean); + {$else} + procedure findpastemethod(Reader: TReader; + const aMethodName: string; var Address: Pointer; var Error: Boolean); + {$endif} + procedure referencepastename(reader: treader; var name: string); + protected + procedure dochanged; virtual; + function getrecordsize: integer; virtual; + procedure addchildren(child: tcomponent); + public + constructor create; + procedure change; override; + procedure beginupdate; + procedure endupdate; + procedure decupdate; + // idesignerselections + function Add(const Item: Tcomponent): Integer; + function Equals(const List: IDesignerSelections): Boolean; reintroduce; + function Get(Index: Integer): Tcomponent; + function GetCount: Integer; + function getarray: componentarty; + + function getobjinfoar: objinfoarty; + function getobjecttext: string; + function pastefromobjecttext(const aobjecttext: string; + aowner,aparent: tcomponent; + initproc: initcomponentprocty): componentarty; + procedure copytoclipboard; + function pastefromclipboard(aowner,aparent: tcomponent; + initproc: initcomponentprocty): componentarty; + + function itempo(const index: integer): pselectedinfoty; + function indexof(const ainstance: tcomponent): integer; + function remove(const ainstance: tcomponent): integer; virtual; + procedure assign(const source: idesignerselections); + property items[const index: integer]: tcomponent + read Getitems write Setitems; default; + function isembedded(const component: tcomponent): boolean; + //true if subchild of another selected component + end; + + tdesignnotifications = class(tpointerlist) + public + procedure ItemDeleted(const ADesigner: IDesigner; const amodule: tmsecomponent; + const AItem: tcomponent); + procedure ItemInserted(const ADesigner: IDesigner; const amodule: tmsecomponent; + const AItem: tcomponent); + procedure ItemsModified(const ADesigner: IDesigner; const aitem: tobject); + //nil for undefined aitem + procedure componentnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const aitem: tcomponent; + const newname: string); + procedure moduleclassnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); + procedure instancevarnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); + procedure SelectionChanged(const ADesigner: IDesigner; + const ASelection: IDesignerSelections); + procedure moduleactivated(const adesigner: idesigner; + const amodule: tmsecomponent); + procedure moduledeactivated(const adesigner: idesigner; + const amodule: tmsecomponent); + procedure moduledestroyed(const adesigner: idesigner; + const amodule: tmsecomponent); + procedure methodcreated(const adesigner: idesigner; + const amodule: tmsecomponent; + const aname: string; const atype: ptypeinfo); + procedure methodnamechanged(const adesigner: idesigner; + const amodule: tmsecomponent; + const newname,oldname: string; const atypeinfo: ptypeinfo); + procedure showobjecttext(const adesigner: idesigner; + const afilename: filenamety; const backupcreated: boolean); + procedure closeobjecttext(const adesigner: idesigner; + const afilename: filenamety; out cancel: boolean); + procedure beforefilesave(const adesigner: idesigner; + const afilename: filenamety); + procedure beforemake(const adesigner: idesigner; const maketag: integer; + var abort: boolean); + procedure aftermake(const adesigner: idesigner; const exitcode: integer); + + procedure Registernotification(const DesignNotification: IDesignNotification); + procedure Unregisternotification(const DesignNotification: IDesignNotification); + end; + + unitgroupinfoty = record + dependents: stringarty; + group: stringarty; + end; + punitgroupinfoty = ^unitgroupinfoty; + + tunitgroups = class(trecordlist) + protected + procedure finalizerecord(var item); override; + procedure copyrecord(var item); override; + public + constructor create; + procedure registergroups(const adependents: array of string; + const agroup: array of string); + function getneededunits(const aunitname: string): stringarty; + end; + + createdesignmodulefuncty = function(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; + initdesigncomponentprocty = procedure(const amodule: tcomponent; + const acomponent: tcomponent); + getdesignscalefuncty = function(const amodule: tcomponent): real; + sourcetoformfuncty = function(const amodule: tmsecomponent; + const source: trichstringdatalist): boolean; + //true if ok + designmoduleintfty = record + createfunc: createdesignmodulefuncty; + initnewcomponent: initdesigncomponentprocty; + getscale: getdesignscalefuncty; + sourcetoform: sourcetoformfuncty; + end; + pdesignmoduleintfty = ^designmoduleintfty; + +procedure registercomponents(const page: msestring; + const componentclasses: array of tcomponentclass); +procedure registercomponenttabhints(const pages: array of msestring; + const hints: array of msestring); + //pages are case sensitive, pages mustexist +function registeredcomponents: tcomponentclasslist; +function unitgroups: tunitgroups; +procedure registerunitgroup(const adependents,agroup: array of string); + +function designnotifications: tdesignnotifications; + +procedure setcomponentpos(const component: tcomponent; const pos: pointty); +function getcomponentpos(const component: tcomponent): pointty; + +implementation +uses + msesysutils,msestream,msewidgets,msedatalist,rtlconsts,msedesigner, + msetabs,mseapplication,mseobjecttext,msedatamodules,mseformatstr; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + treader1 = class(treader); + twriter1 = class(twriter); + tcomponent1 = class(tcomponent); + +var + adesignnotifications: tdesignnotifications; + aregisteredcomponents: tcomponentclasslist; +// aregistereddesignmoduleclasses: designmoduleinfoarty; + aunitgroups: tunitgroups; + +{$ifdef FPC} +var + componentposreversed: boolean; +{$endif} + +procedure setcomponentpos(const component: tcomponent; const pos: pointty); +var + lo1: longint; +begin + {$ifdef fpc} //fpbug + if componentposreversed then begin + longrec(lo1).hi:= pos.x; + longrec(lo1).lo:= pos.y; + end + else begin + longrec(lo1).lo:= pos.x; + longrec(lo1).hi:= pos.y; + end; + {$else} + longrec(lo1).lo:= pos.x; + longrec(lo1).hi:= pos.y; + {$endif} + component.designinfo:= lo1; +end; + +function getcomponentpos(const component: tcomponent): pointty; +begin + {$ifdef fpc} //fpbug + if componentposreversed then begin + result.x:= smallint(longrec(component.designinfo).hi); + result.y:= smallint(longrec(component.designinfo).lo); + end + else begin + result.x:= smallint(longrec(component.designinfo).lo); + result.y:= smallint(longrec(component.designinfo).hi); + end; + {$else} + result.x:= smallint(longrec(component.designinfo).lo); + result.y:= smallint(longrec(component.designinfo).hi); + {$endif} +end; + +function registeredcomponents: tcomponentclasslist; +begin + if aregisteredcomponents = nil then begin + aregisteredcomponents:= tcomponentclasslist.create; + end; + result:= aregisteredcomponents; +end; + +function unitgroups: tunitgroups; +begin + if aunitgroups = nil then begin + aunitgroups:= tunitgroups.create; + end; + result:= aunitgroups; +end; + +function designnotifications: tdesignnotifications; +begin + result:= adesignnotifications; +end; + +procedure registercomponents(const page: msestring; + const componentclasses: array of tcomponentclass); +begin + registeredcomponents.registercomponents(page,componentclasses); +end; + +procedure registercomponenttabhints(const pages: array of msestring; + const hints: array of msestring); + //pages are case sensitive, pages mustexist +begin + registeredcomponents.registercomponenttabhints(pages,hints); +end; + +procedure registerunitgroup(const adependents,agroup: array of string); +begin + unitgroups.registergroups(adependents,agroup); +end; + +{ tcomponentclasslist } + +constructor tcomponentclasslist.create; +begin + fimagelist:= timagelist.create(nil); + fimagelist.size:= makesize(24,24); + fimagelist.colormask:= true; + inherited create(sizeof(componentclassinfoty)); +end; + +destructor tcomponentclasslist.destroy; +begin + fimagelist.Free; + inherited; +end; + +function tcomponentclasslist.add(var value: componentclassinfoty): integer; +begin + if indexof(value.classtyp) < 0 then begin + value.defaultindex:= fdefaultindex; + inc(fdefaultindex); + result:= inherited add(value); + end + else begin + result:= -1; + end; +end; + +procedure tcomponentclasslist.registercomponents(const page: msestring; + const componentclasses: array of tcomponentclass); +var + info: componentclassinfoty; + int1: integer; + bitmap: tbitmapcomp; + class1: tclass; + pagenr: integer; +begin + pagenr:= addpage(page); + bitmap:= tbitmapcomp.create(nil); + try + if fimagelist.count = 0 then begin + bitmap.name:= 'TComponent'; + initmsecomponent1(bitmap,nil); + fimagelist.addimage(bitmap.bitmap); + end; + with info do begin + for int1:= 0 to high(componentclasses) do begin + classtyp:= componentclasses[int1]; + page:= pagenr; + icon:= 0; + class1:= classtyp; + while class1 <> nil do begin + bitmap.bitmap.clear; + bitmap.bitmap.colormask:= false; + bitmap.name:= class1.classname; + if initmsecomponent1(bitmap,nil) then begin + if not bitmap.bitmap.colormask then begin + bitmap.bitmap.automask; + end; + icon:= fimagelist.addimage(bitmap.bitmap); + break; + end; + class1:= class1.ClassParent; + end; + mclasses.registerclass(info.classtyp); + add(info); + end; + end; + finally + bitmap.Free; + end; +end; + +procedure tcomponentclasslist.registercomponenttabhints( + const pages: array of msestring; const hints: array of msestring); + //pages are case sensitive, pages mustexist +var + int1: integer; + int2: integer; +begin + for int1:= 0 to high(pages) do begin + int2:= findpage(pages[int1]); + if (int2 >= 0) then begin + with fpagenames[int2] do begin + if int1 <= high(hints) then begin + hint:= hints[int1]; + end + else begin + hint:= ''; + end; + end; + end; + end; +end; + +function tcomponentclasslist.indexof( + const value: tcomponentclass): integer; +begin + result:= inherited indexof(value); +end; + +function tcomponentclasslist.itempo( + const index: integer): pcomponentclassinfoty; +begin + result:= pcomponentclassinfoty(getitempo(index)); +end; + +function tcomponentclasslist.findpage(const pagename: msestring): integer; +var + int1: integer; +begin + result:= -1; + for int1:= 0 to high(fpagenames) do begin + if fpagenames[int1].caption = pagename then begin + result:= int1; + break; + end; + end; +end; + +function tcomponentclasslist.addpage(const pagename: msestring): integer; +begin + result:= findpage(pagename); + if result < 0 then begin + setlength(fpagenames,length(fpagenames) + 1); + setlength(fpagecomporders,length(fpagenames)); + result:= high(fpagenames); + fpagenames[result].caption:= pagename; + end; +end; + +function tcomponentclasslist.pagenames: comppagearty; +begin + result:= fpagenames; +end; + +function tcomponentclasslist.pagehigh: integer; +begin + result:= high(fpagenames); +end; + +procedure tcomponentclasslist.drawcomponenticon(const acomponent: tcomponent; + const canvas: tcanvas; const dest: rectty); +var + int1: integer; +begin + int1:= indexof(tcomponentclass(acomponent.classtype)); + if int1 >= 0 then begin + fimagelist.paint(canvas,itempo(int1)^.icon,dest); + end; +end; + +function tcomponentclasslist.componentcounts: integerarty; +var + int1: integer; +begin + setlength(result,length(fpagenames)); + for int1:= 0 to count - 1 do begin + with itempo(int1)^ do begin + if page <= high(result) then begin + inc(result[page]); + end; + end; + end; +end; + +procedure tcomponentclasslist.updatestat(const filer: tstatfiler); +var + int1,int2: integer; + ar1,ar2,ar3: integerarty; +begin + ar1:= nil; //compiler warning + ar2:= nil; //compiler warning + filer.setsection('componentpalette'); + if filer.iswriter then begin + for int1:= 0 to high(fpagecomporders) do begin + tstatwriter(filer).writearray('order'+inttostrmse(int1), + fpagecomporders[int1]); + end; + end + else begin + ar2:= componentcounts; + for int1:= 0 to high(fpagecomporders) do begin + ar1:= tstatreader(filer).readarray('order'+inttostrmse(int1), + integerarty(nil)); + if ar1 <> nil then begin + if length(ar1) <> ar2[int1] then begin + ar1:= nil; //invalid + end + else begin + ar3:= copy(ar1); + sortarray(ar3); + for int2:= 0 to high(ar3) do begin + if ar3[int2] <> int2 then begin + ar1:= nil; //invalid + break; + end; + end; + end; + end; + fpagecomporders[int1]:= ar1; + end; + end; + filer.endlist; +end; + +function tcomponentclasslist.compare(const l, r): integer; +begin + if fdefaultorder then begin + result:= componentclassinfoty(l).defaultindex - + componentclassinfoty(r).defaultindex; + end + else begin + result:= ptruint(componentclassinfoty(l).classtyp) - + ptruint(componentclassinfoty(r).classtyp); + end; +end; + +function tcomponentclasslist.getcomparefunc: sortcomparemethodty; +begin + result:= {$ifdef FPC}@{$endif}compare; +end; + +procedure tcomponentclasslist.checkpageindex(const index: integer); +begin + if (index < 0) or (index > high(fpagecomporders)) then begin + tlist.Error(SListIndexError, Index); + end; +end; + +function tcomponentclasslist.getpagecomporders( + const index: integer): integerarty; +begin + checkpageindex(index); + result:= fpagecomporders[index]; +end; + +procedure tcomponentclasslist.setpagecomporders(const index: integer; + const Value: integerarty); +begin + checkpageindex(index); + fpagecomporders[index]:= value; +end; + +procedure tcomponentclasslist.setdefaultorder(const avalue: boolean); +begin + if fdefaultorder <> avalue then begin + fdefaultorder:= avalue; + if sorted then begin + sorted:= false; + sorted:= true; + end; + end; +end; + +{ tdesignerselections } + +constructor tdesignerselections.create; +begin + inherited create(getrecordsize); +end; + +function tdesignerselections.itempo(const index: integer): pselectedinfoty; +begin + result:= pselectedinfoty(getitempo(index)); +end; + +procedure tdesignerselections.assign(const source: idesignerselections); +var + int1: integer; +begin + clear; + count:= source.Count; + for int1:= 0 to source.count - 1 do begin + itempo(int1)^.instance:= source.Items[int1]; + end; + change; +end; + +function tdesignerselections.getarray: componentarty; +begin + if fcount > 0 then begin + setlength(result,fcount); + move(datapo^,pointer(result)^,fcount*sizeof(pointer)); + end + else begin + result:= nil; + end; +end; + +function tdesignerselections.Add(const Item: Tcomponent): Integer; +var + info: selectedinfoty; + widget1: twidget; +begin + result:= indexof(item); + if result < 0 then begin + fillchar(info,sizeof(info),0); + info.instance:= item; + result:= inherited add(info); + if item is twidget then begin + widget1:= twidget(item); + while widget1 <> nil do begin + if (widget1 is ttabpage) then begin + ttabpage(widget1).isactivepage:= true; + end; + widget1:= widget1.parentwidget; + end; + end; + change; + end; +end; + +function tdesignerselections.Equals(const List: IDesignerSelections): Boolean; +var + int1: integer; +begin + result:= false; + if list.Count = count then begin + for int1:= 0 to count-1 do begin + if list.Items[int1] <> itempo(int1)^.instance then begin + exit; + end; + end; + end; + result:= true; +end; + +function tdesignerselections.Get(Index: Integer): Tcomponent; +begin + result:= itempo(index)^.instance; +end; + +function tdesignerselections.GetCount: Integer; +begin + result:= count; +end; + +function tdesignerselections.indexof(const ainstance: tcomponent): integer; +var + int1: integer; +begin + result:= -1; + for int1:= 0 to count-1 do begin + if itempo(int1)^.instance = ainstance then begin + result:= int1; + break; + end; + end; +end; + +function tdesignerselections.remove(const ainstance: tcomponent): integer; +begin + result:= indexof(ainstance); + if result >= 0 then begin + delete(result); + change; + end; +end; + +procedure tdesignerselections.dochanged; +begin + //dummy +end; + +function tdesignerselections.getrecordsize: integer; +begin + result:= sizeof(selectedinfoty); +end; + +function tdesignerselections.Getitems(const index: integer): tcomponent; +begin + result:= itempo(index)^.instance; +end; + +procedure tdesignerselections.Setitems(const index: integer; + const Value: tcomponent); +begin + itempo(index)^.instance:= value; +end; + +procedure tdesignerselections.beginupdate; +begin + inc(fupdating); +end; + +procedure tdesignerselections.change; +begin + if fupdating = 0 then begin + dochanged; + end; +end; + +procedure tdesignerselections.endupdate; +begin + dec(fupdating); + if fupdating = 0 then begin + dochanged; + end; +end; + +procedure tdesignerselections.decupdate; +begin + dec(fupdating); +end; + +function tdesignerselections.isembedded(const component: tcomponent): boolean; + //true if subchild of another selected component +var + comp1: tcomponent; +begin + result:= false; + comp1:= component.getparentcomponent; + while comp1 <> nil do begin + if (indexof(comp1) >= 0) then begin + result:= true; + break; //stored by parent + end; + comp1:= comp1.getparentcomponent; + end; +end; + +function tdesignerselections.getobjecttext: string; +var + binstream: tmemorystream; + textstream: ttextstream; + int1: integer; + component: tcomponent; + writer: twritermse; + comp1,comp2: tcomponent; +{$ifndef mse_nomethodswap} + po1: pointer; + modulepo: pmoduleinfoty; +{$endif} +begin + result:= ''; + if count > 0 then begin + binstream:= tmemorystream.Create; + textstream:= ttextstream.Create; + try + for int1:= 0 to count -1 do begin + component:= items[int1]; + if not isembedded(component) then begin + writer:= twritermse.Create(binstream,4096,true); + comp1:= tcomponent.create(nil); + try + {$ifdef mse_nomethodswap} + writer.onwritemethodproperty:= + {$ifdef FPC}@{$endif}designer.writedesignmethod; + {$else} + modulepo:= designer.modules.findmodulebycomponent(component); + po1:= swapmethodtable(comp1, + modulepo^.methods.createmethodtable( + designer.getancestormethods(modulepo))); + designer.doswapmethodpointers(component,false); + {$endif} + try + writer.Root:= component.Owner; + designer.descendentinstancelist.beginstreaming(nil); + comp2:= designer.descendentinstancelist.findancestor(component); + writer.ancestor:= comp2; + writer.rootancestor:= comp2; + writer.onfindancestor:= {$ifdef FPC}@{$endif}designer.findancestor; + writer.writecomponent(component); + finally + designer.descendentinstancelist.endstreaming; + {$ifndef mse_nomethodswap} + designer.doswapmethodpointers(component,true); + swapmethodtable(comp1,po1); + modulepo^.methods.releasemethodtable; + {$endif} + end; + finally + comp1.free; + writer.Free; + end; + end; + end; + binstream.Position:= 0; + while binstream.Position < binstream.Size do begin + objectbinarytotextmse(binstream,textstream); + end; + textstream.Position:= 0; + result:= textstream.readdatastring; + finally + binstream.Free; + textstream.Free; + end; + end; +end; + +function tdesignerselections.getobjinfoar: objinfoarty; +var + int1: integer; + co1: tcomponent; + binstream: tmemorystream; + textstream: ttextstream; + writer: twritermse; +begin + result:= nil; + for int1:= 0 to count - 1 do begin + co1:= items[int1]; + if not isembedded(co1) then begin + setlength(result,high(result)+2); + with result[high(result)] do begin + owner:= co1.owner; + if owner <> nil then begin + ownerindex:= co1.componentindex; + end + else begin + ownerindex:= -1; + end; + if co1 is twidget then begin + parent:= twidget(co1).parentwidget; + if parent <> nil then begin + parentindex:= twidget(parent).indexofwidget(twidget(co1)); + end + else begin + parentindex:= -1; + end; + end + else begin + parent:= nil; + parentindex:= -1; + end; + binstream:= tmemorystream.create; + writer:= twritermse.create(binstream,4096,true); + textstream:= ttextstream.create; + try + writer.root:= co1.owner; + writer.writecomponent(co1); + freeandnil(writer); + binstream.position:= 0; + objectbinarytotextmse(binstream,textstream); + textstream.position:= 0; + objtext:= textstream.readdatastring; + finally + writer.free; + binstream.free; + textstream.free; + end; + end; + end; + end; +end; + +procedure tdesignerselections.copytoclipboard; +begin + msewidgets.copytoclipboard(msestring(getobjecttext)); +end; + +procedure tdesignerselections.doadd(component: tcomponent); +begin + add(component); +end; + +procedure tdesignerselections.dosetactcomp(component: tcomponent); +begin + factcomp:= component; +end; + +function getglobalcomponent(const Name: string): TComponent; +begin + result:= designer.modules.findmoduleinstancebyname(name); +end; + +var + pastingmodulepo: pmoduleinfoty; + +{$ifdef mse_nomethodswap} +procedure tdesignerselections.setpastemethodproperty(reader: treader; + instance: tpersistent; + propinfo: ppropinfo; const themethodname: string; + var handled: boolean); +var + methodinfopo: pmethodinfoty; + m1: tmethod; +begin + handled:= true; + m1.data:= nil; + m1.code:= nil; + if pastingmodulepo <> nil then begin + methodinfopo:= pastingmodulepo^.methods.findmethodbyname(themethodname); + if methodinfopo <> nil then begin + m1.data:= methodinfopo^.address; + end; + end; + setmethodprop(instance,propinfo,m1); +end; +{$else} +procedure tdesignerselections.findpastemethod(Reader: TReader; + const aMethodName: string; var Address: Pointer; var Error: Boolean); +var + methodinfopo: pmethodinfoty; +begin + error:= false; + if pastingmodulepo <> nil then begin + methodinfopo:= pastingmodulepo^.methods.findmethodbyname(amethodname); + if methodinfopo <> nil then begin + address:= methodinfopo^.address; + end; + end; +end; +{$endif} +const + pastenametrailer = '_15dtz4u67sd3r'; + +procedure tdesignerselections.referencepastename(reader: treader; var name: string); +begin + if (reader.root = fpasteroot) and (fpasteroot.findcomponent(name) = nil) and + (fpasteowner.findcomponent(name+pastenametrailer) <> nil) then begin + name:= name + pastenametrailer; + //this is dangerous, there could be a component with the same name + //but another class type, no possibility found to access the + //propertyinfo of the resolving items :-( + end; +end; + +procedure tdesignerselections.addchildren(child: tcomponent); +begin + add(child); + tcomponent1(child).getchildren({$ifdef FPC}@{$endif}addchildren,fpasteroot); +end; + +type + tpasteroot = class(tcomponent) + private + fowner: tdesignerselections; + protected + procedure notification(acomponent: tcomponent; + operation: toperation); override; + public + constructor create(const aowner: tdesignerselections); reintroduce; + end; + +{ tpasteroot } + +constructor tpasteroot.create(const aowner: tdesignerselections); +begin + fowner:= aowner; + inherited create(nil); +end; + +procedure tpasteroot.notification(acomponent: tcomponent; + operation: toperation); +var + int1: integer; +begin + if (operation = opremove) then begin + if (csdestroying in acomponent.componentstate) then begin + for int1:= 0 to fowner.count-1 do begin + if fowner.items[int1] = acomponent then begin + fowner.items[int1]:= nil; + end; + end; + inherited; + end + else begin + acomponent.freenotification(self); + end; + end + else begin + inherited; + end; +end; + +function tdesignerselections.pastefromobjecttext(const aobjecttext: string; + aowner,aparent: tcomponent; initproc: initcomponentprocty): componentarty; + //returns count of added components +var + binstream: tmemorystream; + textstream: ttextstream; + int1: integer; + countbefore: integer; + reader: treader; + comp1,comp2: tcomponent; + listend: tvaluetype; + validaterenamebefore: validaterenameeventty; + +begin + result:= nil; + if aobjecttext = '' then begin + exit; + end; + if aowner is tmsecomponent then begin + pastingmodulepo:= designer.modules.findmodule(tmsecomponent(aowner)); + end + else begin + pastingmodulepo:= nil; + end; + countbefore:= count; + try + designer.beginpasting; + fpasteowner:= aowner; + textstream:= ttextstream.Create; + comp1:= tpasteroot.create(self); + fpasteroot:= comp1; + tcomponent1(comp1).SetDesigning(true{$ifndef FPC},false{$endif}); + lockfindglobalcomponent; + RegisterFindGlobalComponentProc({$ifdef FPC}@{$endif}getglobalcomponent); + try + listend:= vanull; + textstream.writeln('object comp1: tcomponent'); + textstream.writestr(aobjecttext); + textstream.writeln('end'); + textstream.Position:= 0; + binstream:= tmemorystream.Create; + try + while textstream.position < textstream.Size do begin + binstream.Position:= 0; + objecttexttobinarymse(textstream,binstream); + binstream.Write(listend,sizeof(listend)); + binstream.Position:= 0; + reader:= treader.create(binstream,4096); + try + reader.onreferencename:= {$ifdef FPC}@{$endif}referencepastename; + {$ifdef mse_nomethodswap} + reader.onsetmethodproperty:= {$ifdef FPC}@{$endif}setpastemethodproperty; + {$else} + reader.onfindmethod:= {$ifdef FPC}@{$endif}findpastemethod; + {$endif} + reader.onancestornotfound:= {$ifdef FPC}@{$endif}designer.ancestornotfound; + reader.onfindcomponentclass:= + {$ifdef FPC}@{$endif}designer.findcomponentclass; + reader.oncreatecomponent:= designer.createcomponent(); + factcomp:= nil; + begingloballoading; + validaterenamebefore:= ondesignvalidaterename; + ondesignvalidaterename:= nil; //no sourceupdate + try + with getcomponentlist(comp1) do begin + for int1:= 0 to aowner.componentcount - 1 do begin + comp2:= aowner.components[int1]; + comp2.name:= comp2.name + pastenametrailer; //avoid nameclash + add(comp2); + end; + end; + try + reader.readrootcomponent(comp1); + finally + for int1:= 0 to aowner.componentcount - 1 do begin + comp2:= aowner.components[int1]; + comp2.name:= copy(comp2.name,1,length(comp2.name) - + length(pastenametrailer)); + //restore original name + end; + end; + finally + ondesignvalidaterename:= validaterenamebefore; + end; + for int1:= aowner.componentcount to comp1.componentcount - 1 do begin + comp2:= comp1.components[int1]; + {$ifndef mse_nomethodswap} + designer.doswapmethodpointers(comp2,true); + {$endif} + if (comp2.getparentcomponent = nil) or (comp2 is tmsedatamodule) then begin +// add(comp2); + addchildren(comp2); + additem(pointerarty(result),pointer(comp2)); + end; + end; + removefixupreferences(comp1,''); + clearpastedcomponents; + if assigned(initproc) then begin + for int1:= comp1.componentcount - 1 downto aowner.componentcount do begin + comp2:= comp1.components[int1]; + if (comp2.getparentcomponent = nil) or (comp2 is tmsedatamodule) then begin + initproc(comp2,aparent); + end; + end; + end; + if pastingmodulepo <> nil then begin + designer.checkmethodtypes(pastingmodulepo,false{,comp1}); + end; + notifygloballoading; + finally + endgloballoading; + clearpastedcomponents; + reader.Free; + end; + end; + finally + binstream.Free; + end; + finally + designer.endpasting; + unlockfindglobalcomponent; + unRegisterFindGlobalComponentProc({$ifdef FPC}@{$endif}getglobalcomponent); + textstream.Free; + clearcomponentlist(comp1); + end; + comp1.destroy(); + except +// comp1:= tpasteroot.create(self); + try + for int1:= countbefore to count -1 do begin + if items[int1] <> nil then begin + items[int1].freenotification(comp1); + end; + end; + for int1:= countbefore to count -1 do begin + items[int1].Free; + end; + count:= countbefore; + application.handleexception; + finally + comp1.destroy(); + end; + end; +// result:= count - countbefore; +end; + +function tdesignerselections.pastefromclipboard(aowner,aparent: tcomponent; + initproc: initcomponentprocty): componentarty; +var + str1: msestring; +begin + result:= nil; + if msewidgets.pastefromclipboard(str1) then begin + result:= pastefromobjecttext(ansistring(str1),aowner,aparent,initproc); + end; +end; + +{ tdesignnotifications } + +procedure tdesignnotifications.RegisterNotification(const DesignNotification: IDesignNotification); +begin + if indexof(pointer(designnotification)) = -1 then begin + add(pointer(designnotification)); + end; +end; + +procedure tdesignnotifications.UnregisterNotification(const DesignNotification: IDesignNotification); +begin + if self <> nil then begin + extract(pointer(designnotification)); + end; +end; +{ +procedure tdesignnotifications.DesignerClosed(const ADesigner: IDesigner; + AGoingDormant: Boolean); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + idesignnotification(fitems[int1]).DesignerClosed(adesigner,agoingdormant); + end; +end; + +procedure tdesignnotifications.DesignerOpened(const ADesigner: IDesigner; + AResurrecting: Boolean); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + idesignnotification(fitems[int1]).Designeropened(adesigner,aresurrecting); + end; +end; +} +procedure tdesignnotifications.ItemDeleted(const ADesigner: IDesigner; + const amodule: tmsecomponent; const AItem: tcomponent); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + idesignnotification(fitems[int1]).itemdeleted(adesigner,amodule,aitem); + end; +end; + +procedure tdesignnotifications.ItemInserted(const ADesigner: IDesigner; + const amodule: tmsecomponent; const AItem: tcomponent); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + idesignnotification(fitems[int1]).iteminserted(adesigner,amodule,aitem); + end; +end; + +procedure tdesignnotifications.ItemsModified(const ADesigner: IDesigner; + const aitem: tobject); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + idesignnotification(fitems[int1]).itemsmodified(adesigner,aitem); + end; +end; + +procedure tdesignnotifications.SelectionChanged(const ADesigner: IDesigner; + const ASelection: IDesignerSelections); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + idesignnotification(fitems[int1]).selectionchanged(adesigner,aselection); + end; +end; + +procedure tdesignnotifications.moduleactivated(const adesigner: idesigner; + const amodule: tmsecomponent); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + idesignnotification(fitems[int1]).moduleactivated(adesigner,amodule); + end; +end; + +procedure tdesignnotifications.moduledeactivated(const adesigner: idesigner; + const amodule: tmsecomponent); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + idesignnotification(fitems[int1]).moduledeactivated(adesigner,amodule); + end; +end; + +procedure tdesignnotifications.moduledestroyed(const adesigner: idesigner; + const amodule: tmsecomponent); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + idesignnotification(fitems[int1]).moduledestroyed(adesigner,amodule); + end; +end; + +procedure tdesignnotifications.methodcreated(const adesigner: idesigner; + const amodule: tmsecomponent; + const aname: string; const atype: ptypeinfo); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + idesignnotification(fitems[int1]).methodcreated(adesigner,amodule,aname,atype); + end; +end; + +procedure tdesignnotifications.methodnamechanged( + const adesigner: idesigner; const amodule: tmsecomponent; const newname, + oldname: string; const atypeinfo: ptypeinfo); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + idesignnotification(fitems[int1]).methodnamechanged(adesigner,amodule, + newname,oldname,atypeinfo); + end; +end; + +procedure tdesignnotifications.showobjecttext(const adesigner: idesigner; + const afilename: filenamety; const backupcreated: boolean); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + idesignnotification(fitems[int1]).showobjecttext(adesigner,afilename, + backupcreated); + end; +end; + +procedure tdesignnotifications.closeobjecttext(const adesigner: idesigner; + const afilename: filenamety; out cancel: boolean); +var + int1: integer; +begin + cancel:= false; + for int1:= 0 to count - 1 do begin + idesignnotification(fitems[int1]).closeobjecttext(adesigner,afilename,cancel); + if cancel then begin + break; + end; + end; +end; + +procedure tdesignnotifications.componentnamechanging( + const adesigner: idesigner; const amodule: tmsecomponent; + const aitem: tcomponent; const newname: string); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + idesignnotification(fitems[int1]).componentnamechanging(adesigner,amodule, + aitem,newname); + end; +end; + +procedure tdesignnotifications.moduleclassnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + idesignnotification(fitems[int1]).moduleclassnamechanging(adesigner,amodule, + newname); + end; +end; + +procedure tdesignnotifications.instancevarnamechanging(const adesigner: idesigner; + const amodule: tmsecomponent; const newname: string); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + idesignnotification(fitems[int1]).instancevarnamechanging(adesigner,amodule, + newname); + end; +end; + +procedure tdesignnotifications.beforefilesave(const adesigner: idesigner; + const afilename: filenamety); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + idesignnotification(fitems[int1]).beforefilesave(adesigner,afilename); + end; +end; + +procedure tdesignnotifications.beforemake(const adesigner: idesigner; + const maketag: integer; var abort: boolean); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + if abort then begin + break; + end; + idesignnotification(fitems[int1]).beforemake(adesigner,maketag,abort); + end; +end; + +procedure tdesignnotifications.aftermake(const adesigner: idesigner; + const exitcode: integer); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + idesignnotification(fitems[int1]).aftermake(adesigner,exitcode); + end; +end; + +{ tunitgroups } + +constructor tunitgroups.create; +begin + inherited create(sizeof(unitgroupinfoty),[rels_needsfinalize,rels_needscopy]); +end; + +procedure tunitgroups.registergroups(const adependents: array of string; + const agroup: array of string); +var + info: unitgroupinfoty; + int1: integer; +begin + with info do begin + setlength(dependents,length(adependents)); + for int1:= 0 to high(adependents) do begin + dependents[int1]:= struppercase(adependents[int1]); + end; + setlength(group,length(agroup)); + for int1:= 0 to high(agroup) do begin + group[int1]:= agroup[int1]; + end; + end; + add(info); +end; + +procedure tunitgroups.finalizerecord(var item); +begin + finalize(unitgroupinfoty(item)); +end; + +procedure tunitgroups.copyrecord(var item); +begin + with unitgroupinfoty(item) do begin + arrayaddref(dependents); + arrayaddref(group); + end; +end; + +function tunitgroups.getneededunits(const aunitname: string): stringarty; +//todo: optimize + + procedure doget(const aname: string; out resnormal,resupper: stringarty); + var + po1: punitgroupinfoty; + int1,int2,int3,int4: integer; + begin + resnormal:= nil; + po1:= datapo; + for int1:= 0 to count - 1 do begin + for int2:= 0 to high(po1^.dependents) do begin + if aname = po1^.dependents[int2] then begin + int3:= length(resnormal); + setlength(resnormal,int3+length(po1^.group)); + for int4:= int3 to high(resnormal) do begin + resnormal[int4]:= po1^.group[int4-int3]; + end; + break; + end; + end; + inc(po1); + end; + setlength(resnormal,high(resnormal)+2); + resnormal[high(resnormal)]:= aunitname; //add dependent + setlength(resupper,length(resnormal)); + for int1:= 0 to high(resnormal) do begin + resupper[int1]:= struppercase(resnormal[int1]); + end; + end; + +var + ar1,ar2: stringarty; + ar3: integerarty; + ar4,ar5n,ar5u: stringarty; + int1,int2{,int3,int4}: integer; + str1: string; + level: integer; + highbefore: integer; + +begin + setlength(ar4,1); + ar4[0]:= struppercase(aunitname); + level:= 0; + repeat + highbefore:= high(ar4); + ar5n:= nil; + ar5u:= nil; + for int1:= 0 to high(ar4) do begin + doget(ar4[int1],ar1,ar2); + stackarray(ar1,ar5n); + stackarray(ar2,ar5u); + end; + sortarray(ar5u,{$ifdef FPC}@{$endif}compareasciistring,ar3); + setlength(ar4,length(ar5u)); + setlength(result,length(ar5u)); + str1:= ''; + int2:= 0; + for int1:= 0 to high(ar5u) do begin + if ar5u[int1] <> str1 then begin + ar4[int2]:= ar5u[int1]; + str1:= ar4[int2]; + result[int2]:= ar5n[ar3[int1]]; + inc(int2); + end; + end; + setlength(ar4,int2); + inc(level); + until (high(ar4) = highbefore) or (level > 16); + setlength(result,length(ar4)); +end; + +{$ifdef FPC} +procedure checkreversedcomponentpos; +var + comp1: tcomponent; + writer1: twritermse; + reader1: treader; + stream1: tmemorystream; + int1: integer; + str1: string; +begin + comp1:= tcomponent.create(nil); + comp1.designinfo:= 1; + stream1:= tmemorystream.create; + writer1:= twritermse.create(stream1,256,false); +{$warnings off} + twriter1(writer1).writeproperties(comp1); +{$warnings on} + writer1.free; + stream1.position:= 0; + reader1:= treader.create(stream1,256); + str1:= reader1.driver.beginproperty; + int1:= reader1.readinteger; + componentposreversed:= (int1 = 1) xor (str1 = 'left'); + reader1.free; + stream1.free; + comp1.free; +end; +{$endif} + +initialization + {$ifdef FPC} + checkreversedcomponentpos; + {$endif} + adesignnotifications:= tdesignnotifications.Create; +// aregisteredcomponents:= tcomponentclasslist.create; +finalization + freeandnil(adesignnotifications); + freeandnil(aregisteredcomponents); + freeandnil(aunitgroups); +end. diff --git a/mseide-msegui/lib/common/designutils/msedoublereallisteditor.mfm b/mseide-msegui/lib/common/designutils/msedoublereallisteditor.mfm new file mode 100644 index 0000000..405e6cd --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msedoublereallisteditor.mfm @@ -0,0 +1,151 @@ +object doublereallisteditor: tdoublereallisteditor + bounds_x = 130 + bounds_y = 203 + bounds_cx = 279 + bounds_cy = 211 + container.bounds = ( + 0 + 0 + 279 + 211 + ) + options = [fo_closeonesc, fo_autoreadstat, fo_autowritestat] + statfile = tstatfile1 + caption = 'Doublereallisteditor' + moduleclassname = 'tmseform' + object ok: tbutton + taborder = 3 + bounds_x = 153 + bounds_y = 177 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + end + object cancel: tbutton + bounds_x = 217 + bounds_y = 177 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + end + object grid: twidgetgrid + taborder = 2 + bounds_x = 8 + bounds_y = 8 + bounds_cx = 261 + bounds_cy = 157 + bounds_cxmin = 240 + anchors = [an_left, an_top, an_right, an_bottom] + optionsgrid = [og_colsizing, og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_wrapcol] + fixcols.count = 1 + fixcols.items = < + item + width = 31 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 2 + captions.items = < + item + caption = 'a' + end + item + caption = 'b' + end> + end> + datacols.count = 2 + datacols.options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savevalue, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[vala] + width = 113 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savevalue, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'vala' + dataclass = tgridrealdatalist + end + item[valb] + width = 110 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savevalue, co_cancopy, co_canpaste] + widgetname = 'valb' + dataclass = tgridrealdatalist + end> + datarowheight = 16 + onrowcountchanged = gridonrowcountchanged + reffontheight = 14 + object vala: trealedit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.dummy = 0 + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 113 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + value = -Inf + valuedefault = -Inf + valuerange = 1 + valuestart = 0 + min = -Inf + max = 1E+300 + reffontheight = 14 + end + object valb: trealedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.dummy = 0 + taborder = 2 + visible = False + bounds_x = 114 + bounds_y = 0 + bounds_cx = 110 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + value = -Inf + valuedefault = -Inf + valuerange = 1 + valuestart = 0 + min = -Inf + max = 1E+038 + reffontheight = 14 + end + end + object rowcount: tintegeredit + frame.caption = 'Rowcount' + frame.captionpos = cp_right + frame.dummy = 0 + frame.outerframe = ( + 0 + 0 + 64 + 0 + ) + taborder = 1 + bounds_x = 8 + bounds_y = 177 + bounds_cx = 114 + anchors = [an_left, an_bottom] + onsetvalue = rowcountonsetvalue + reffontheight = 14 + end + object tstatfile1: tstatfile + filename = 'doublestringlisteditor.sta' + options = [sfo_memory] + left = 40 + top = 88 + end +end diff --git a/mseide-msegui/lib/common/designutils/msedoublereallisteditor.pas b/mseide-msegui/lib/common/designutils/msedoublereallisteditor.pas new file mode 100644 index 0000000..94c66c2 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msedoublereallisteditor.pas @@ -0,0 +1,58 @@ +{ MSEgui Copyright (c) 1999-2006 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msedoublereallisteditor; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseforms,msedataedits,msesimplewidgets,msewidgetgrid,msegrids,msestat, + msestatfile; +type + tdoublereallisteditor = class(tmseform) + cancel: tbutton; + ok: tbutton; + grid: twidgetgrid; + vala: trealedit; + valb: trealedit; + rowcount: tintegeredit; + tstatfile1: tstatfile; + procedure rowcountonsetvalue(const sender: tobject; var avalue: integer; + var accept: boolean); + procedure gridonrowcountchanged(const sender: tcustomgrid); + public + constructor create(const aonclosequery: closequeryeventty); reintroduce; + end; + +implementation +uses + msedoublereallisteditor_mfm; + +{ tdoublereallisteditor } + +constructor tdoublereallisteditor.create(const aonclosequery: closequeryeventty); +begin + onclosequery:= aonclosequery; + inherited create(nil); +end; + +procedure tdoublereallisteditor.gridonrowcountchanged( + const sender: tcustomgrid); +begin + rowcount.value:= sender.rowcount; +end; + +procedure tdoublereallisteditor.rowcountonsetvalue(const sender: tobject; + var avalue: integer; var accept: boolean); +begin + grid.rowcount:= avalue; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/msedoublereallisteditor_mfm.pas b/mseide-msegui/lib/common/designutils/msedoublereallisteditor_mfm.pas new file mode 100644 index 0000000..3bb73f9 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msedoublereallisteditor_mfm.pas @@ -0,0 +1,158 @@ +unit msedoublereallisteditor_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msedoublereallisteditor; + +const + objdata: record size: integer; data: array[0..2819] of byte end = + (size: 2820; data: ( + 84,80,70,48,21,116,100,111,117,98,108,101,114,101,97,108,108,105,115,116, + 101,100,105,116,111,114,20,100,111,117,98,108,101,114,101,97,108,108,105,115, + 116,101,100,105,116,111,114,8,98,111,117,110,100,115,95,120,3,130,0,8, + 98,111,117,110,100,115,95,121,3,203,0,9,98,111,117,110,100,115,95,99, + 120,3,23,1,9,98,111,117,110,100,115,95,99,121,3,211,0,16,99,111, + 110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0,3, + 23,1,3,211,0,0,7,111,112,116,105,111,110,115,11,13,102,111,95,99, + 108,111,115,101,111,110,101,115,99,15,102,111,95,97,117,116,111,114,101,97, + 100,115,116,97,116,16,102,111,95,97,117,116,111,119,114,105,116,101,115,116, + 97,116,0,8,115,116,97,116,102,105,108,101,7,10,116,115,116,97,116,102, + 105,108,101,49,7,99,97,112,116,105,111,110,6,20,68,111,117,98,108,101, + 114,101,97,108,108,105,115,116,101,100,105,116,111,114,15,109,111,100,117,108, + 101,99,108,97,115,115,110,97,109,101,6,8,116,109,115,101,102,111,114,109, + 0,7,116,98,117,116,116,111,110,2,111,107,8,116,97,98,111,114,100,101, + 114,2,3,8,98,111,117,110,100,115,95,120,3,153,0,8,98,111,117,110, + 100,115,95,121,3,177,0,9,98,111,117,110,100,115,95,99,120,2,50,9, + 98,111,117,110,100,115,95,99,121,2,20,7,97,110,99,104,111,114,115,11, + 8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0, + 5,115,116,97,116,101,11,10,97,115,95,100,101,102,97,117,108,116,15,97, + 115,95,108,111,99,97,108,100,101,102,97,117,108,116,15,97,115,95,108,111, + 99,97,108,99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6, + 3,38,79,75,11,109,111,100,97,108,114,101,115,117,108,116,7,5,109,114, + 95,111,107,0,0,7,116,98,117,116,116,111,110,6,99,97,110,99,101,108, + 8,98,111,117,110,100,115,95,120,3,217,0,8,98,111,117,110,100,115,95, + 121,3,177,0,9,98,111,117,110,100,115,95,99,120,2,50,9,98,111,117, + 110,100,115,95,99,121,2,20,7,97,110,99,104,111,114,115,11,8,97,110, + 95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,5,115,116, + 97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110, + 0,7,99,97,112,116,105,111,110,6,7,38,67,97,110,99,101,108,11,109, + 111,100,97,108,114,101,115,117,108,116,7,9,109,114,95,99,97,110,99,101, + 108,0,0,11,116,119,105,100,103,101,116,103,114,105,100,4,103,114,105,100, + 8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120, + 2,8,8,98,111,117,110,100,115,95,121,2,8,9,98,111,117,110,100,115, + 95,99,120,3,5,1,9,98,111,117,110,100,115,95,99,121,3,157,0,12, + 98,111,117,110,100,115,95,99,120,109,105,110,3,240,0,7,97,110,99,104, + 111,114,115,11,7,97,110,95,108,101,102,116,6,97,110,95,116,111,112,8, + 97,110,95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,11, + 111,112,116,105,111,110,115,103,114,105,100,11,12,111,103,95,99,111,108,115, + 105,122,105,110,103,12,111,103,95,114,111,119,109,111,118,105,110,103,15,111, + 103,95,107,101,121,114,111,119,109,111,118,105,110,103,15,111,103,95,114,111, + 119,105,110,115,101,114,116,105,110,103,14,111,103,95,114,111,119,100,101,108, + 101,116,105,110,103,19,111,103,95,102,111,99,117,115,99,101,108,108,111,110, + 101,110,116,101,114,15,111,103,95,97,117,116,111,102,105,114,115,116,114,111, + 119,13,111,103,95,97,117,116,111,97,112,112,101,110,100,10,111,103,95,119, + 114,97,112,99,111,108,0,13,102,105,120,99,111,108,115,46,99,111,117,110, + 116,2,1,13,102,105,120,99,111,108,115,46,105,116,101,109,115,14,1,5, + 119,105,100,116,104,2,31,7,110,117,109,115,116,101,112,2,1,0,0,13, + 102,105,120,114,111,119,115,46,99,111,117,110,116,2,1,13,102,105,120,114, + 111,119,115,46,105,116,101,109,115,14,1,6,104,101,105,103,104,116,2,16, + 14,99,97,112,116,105,111,110,115,46,99,111,117,110,116,2,2,14,99,97, + 112,116,105,111,110,115,46,105,116,101,109,115,14,1,7,99,97,112,116,105, + 111,110,6,1,97,0,1,7,99,97,112,116,105,111,110,6,1,98,0,0, + 0,0,14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,2,16, + 100,97,116,97,99,111,108,115,46,111,112,116,105,111,110,115,11,14,99,111, + 95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115, + 101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116, + 14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114, + 111,119,115,101,108,101,99,116,15,99,111,95,112,114,111,112,111,114,116,105, + 111,110,97,108,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111, + 95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112, + 121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117, + 115,101,115,99,114,111,108,108,114,111,119,0,14,100,97,116,97,99,111,108, + 115,46,105,116,101,109,115,14,7,4,118,97,108,97,1,5,119,105,100,116, + 104,2,113,7,111,112,116,105,111,110,115,11,14,99,111,95,102,111,99,117, + 115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101, + 99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109, + 117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108, + 101,99,116,15,99,111,95,112,114,111,112,111,114,116,105,111,110,97,108,12, + 99,111,95,115,97,118,101,118,97,108,117,101,12,99,111,95,115,97,118,101, + 115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95, + 99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114, + 111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,4, + 118,97,108,97,9,100,97,116,97,99,108,97,115,115,7,17,116,103,114,105, + 100,114,101,97,108,100,97,116,97,108,105,115,116,0,7,4,118,97,108,98, + 1,5,119,105,100,116,104,2,110,7,111,112,116,105,111,110,115,11,14,99, + 111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117, + 115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99, + 116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95, + 114,111,119,115,101,108,101,99,116,7,99,111,95,102,105,108,108,12,99,111, + 95,115,97,118,101,118,97,108,117,101,10,99,111,95,99,97,110,99,111,112, + 121,11,99,111,95,99,97,110,112,97,115,116,101,0,10,119,105,100,103,101, + 116,110,97,109,101,6,4,118,97,108,98,9,100,97,116,97,99,108,97,115, + 115,7,17,116,103,114,105,100,114,101,97,108,100,97,116,97,108,105,115,116, + 0,0,13,100,97,116,97,114,111,119,104,101,105,103,104,116,2,16,17,111, + 110,114,111,119,99,111,117,110,116,99,104,97,110,103,101,100,7,21,103,114, + 105,100,111,110,114,111,119,99,111,117,110,116,99,104,97,110,103,101,100,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,9,116,114,101, + 97,108,101,100,105,116,4,118,97,108,97,11,111,112,116,105,111,110,115,115, + 107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110, + 111,110,108,121,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0, + 17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,2, + 0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108, + 111,114,99,108,105,101,110,116,0,11,102,114,97,109,101,46,100,117,109,109, + 121,2,0,8,116,97,98,111,114,100,101,114,2,1,7,118,105,115,105,98, + 108,101,8,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,113,9,98,111, + 117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105, + 116,49,11,13,111,101,49,95,115,97,118,101,118,97,108,117,101,0,5,118, + 97,108,117,101,5,0,0,0,0,0,0,0,128,255,255,12,118,97,108,117, + 101,100,101,102,97,117,108,116,5,0,0,0,0,0,0,0,128,255,255,10, + 118,97,108,117,101,114,97,110,103,101,2,1,10,118,97,108,117,101,115,116, + 97,114,116,2,0,3,109,105,110,5,0,0,0,0,0,0,0,128,255,255, + 3,109,97,120,5,47,221,172,3,64,228,33,191,227,67,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,9,116,114,101,97,108,101, + 100,105,116,4,118,97,108,98,14,111,112,116,105,111,110,115,119,105,100,103, + 101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101, + 105,103,104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111, + 115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,12, + 102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101, + 46,99,111,108,111,114,99,108,105,101,110,116,4,2,0,0,128,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95, + 108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101, + 110,116,0,11,102,114,97,109,101,46,100,117,109,109,121,2,0,8,116,97, + 98,111,114,100,101,114,2,2,7,118,105,115,105,98,108,101,8,8,98,111, + 117,110,100,115,95,120,2,114,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,120,2,110,9,98,111,117,110,100,115,95,99, + 121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,13,111,101, + 49,95,115,97,118,101,118,97,108,117,101,0,5,118,97,108,117,101,5,0, + 0,0,0,0,0,0,128,255,255,12,118,97,108,117,101,100,101,102,97,117, + 108,116,5,0,0,0,0,0,0,0,128,255,255,10,118,97,108,117,101,114, + 97,110,103,101,2,1,10,118,97,108,117,101,115,116,97,114,116,2,0,3, + 109,105,110,5,0,0,0,0,0,0,0,128,255,255,3,109,97,120,5,245, + 136,13,181,80,153,118,150,125,64,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,14,0,0,0,12,116,105,110,116,101,103,101,114,101,100,105, + 116,8,114,111,119,99,111,117,110,116,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,8,82,111,119,99,111,117,110,116,16,102,114,97,109,101, + 46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104, + 116,11,102,114,97,109,101,46,100,117,109,109,121,2,0,16,102,114,97,109, + 101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,64,2, + 0,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115, + 95,120,2,8,8,98,111,117,110,100,115,95,121,3,177,0,9,98,111,117, + 110,100,115,95,99,120,2,114,7,97,110,99,104,111,114,115,11,7,97,110, + 95,108,101,102,116,9,97,110,95,98,111,116,116,111,109,0,10,111,110,115, + 101,116,118,97,108,117,101,7,18,114,111,119,99,111,117,110,116,111,110,115, + 101,116,118,97,108,117,101,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,0,9,116,115,116,97,116,102,105,108,101,10,116,115,116,97, + 116,102,105,108,101,49,8,102,105,108,101,110,97,109,101,6,26,100,111,117, + 98,108,101,115,116,114,105,110,103,108,105,115,116,101,100,105,116,111,114,46, + 115,116,97,7,111,112,116,105,111,110,115,11,10,115,102,111,95,109,101,109, + 111,114,121,0,4,108,101,102,116,2,40,3,116,111,112,2,88,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tdoublereallisteditor,''); +end. diff --git a/mseide-msegui/lib/common/designutils/msedoublestringlisteditor.mfm b/mseide-msegui/lib/common/designutils/msedoublestringlisteditor.mfm new file mode 100644 index 0000000..99c6221 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msedoublestringlisteditor.mfm @@ -0,0 +1,173 @@ +object doublestringlisteditor: tdoublestringlisteditor + optionswidget = [ow_arrowfocus, ow_subfocus, ow_destroywidgets, ow_hinton] + bounds_x = 130 + bounds_y = 203 + bounds_cx = 338 + bounds_cy = 194 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 338 + 194 + ) + options = [fo_closeonesc, fo_autoreadstat, fo_autowritestat] + statfile = tstatfile1 + caption = 'Stringlisteditor' + moduleclassname = 'tmseform' + object ok: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + taborder = 3 + bounds_x = 212 + bounds_y = 160 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + reffontheight = 14 + end + object cancel: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + bounds_x = 276 + bounds_y = 160 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + reffontheight = 14 + end + object grid: twidgetgrid + frame.localprops = [] + frame.localprops1 = [] + taborder = 2 + bounds_x = 8 + bounds_y = 8 + bounds_cx = 320 + bounds_cy = 140 + anchors = [an_left, an_top, an_right, an_bottom] + optionsgrid = [og_colsizing, og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_wrapcol, og_autopopup, og_mousescrollcol] + fixcols.count = 1 + fixcols.items = < + item + width = 31 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 3 + captions.items = < + item + caption = 'a' + textflags = [] + end + item + caption = 'b' + textflags = [] + end + item + end> + end> + datacols.count = 2 + datacols.options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savevalue, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[texta] + width = 137 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savevalue, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'texta' + dataclass = tgridmsestringdatalist + end + item[textb] + width = 145 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savevalue, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'textb' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + onrowcountchanged = gridonrowcountchanged + reffontheight = 14 + object texta: tmemodialogedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 137 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_savevalue] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + reffontheight = 14 + end + object textb: tmemodialogedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 2 + visible = False + bounds_x = 138 + bounds_y = 0 + bounds_cx = 145 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_savevalue] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + reffontheight = 14 + end + end + object rowcount: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.caption = 'Rowcount' + frame.captionpos = cp_right + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 64 + 0 + ) + taborder = 1 + bounds_x = 36 + bounds_y = 160 + bounds_cx = 114 + anchors = [an_left, an_bottom] + onsetvalue = rowcountonsetvalue + reffontheight = 14 + end + object tstatfile1: tstatfile + filename = 'doublestringlisteditor.sta' + options = [sfo_memory] + left = 40 + top = 88 + end +end diff --git a/mseide-msegui/lib/common/designutils/msedoublestringlisteditor.pas b/mseide-msegui/lib/common/designutils/msedoublestringlisteditor.pas new file mode 100644 index 0000000..864a475 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msedoublestringlisteditor.pas @@ -0,0 +1,59 @@ +{ MSEgui Copyright (c) 1999-2006 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msedoublestringlisteditor; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseforms,msedataedits,msesimplewidgets,msewidgetgrid,msegrids,mseedit,mseglob, + msegui,mseguiglob,mseifiglob,msememodialog,msemenus,msestrings,msetypes, + msedialog,msestat,msestatfile; +type + tdoublestringlisteditor = class(tmseform) + cancel: tbutton; + ok: tbutton; + grid: twidgetgrid; + rowcount: tintegeredit; + textb: tmemodialogedit; + texta: tmemodialogedit; + tstatfile1: tstatfile; + procedure rowcountonsetvalue(const sender: tobject; var avalue: integer; + var accept: boolean); + procedure gridonrowcountchanged(const sender: tcustomgrid); + public + constructor create(const aonclosequery: closequeryeventty); reintroduce; + end; + +implementation +uses + msedoublestringlisteditor_mfm; + +{ tdoublestringlisteditor } + +constructor tdoublestringlisteditor.create(const aonclosequery: closequeryeventty); +begin + onclosequery:= aonclosequery; + inherited create(nil); +end; + +procedure tdoublestringlisteditor.gridonrowcountchanged( + const sender: tcustomgrid); +begin + rowcount.value:= sender.rowcount; +end; + +procedure tdoublestringlisteditor.rowcountonsetvalue(const sender: tobject; + var avalue: integer; var accept: boolean); +begin + grid.rowcount:= avalue; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/msedoublestringlisteditor_mfm.pas b/mseide-msegui/lib/common/designutils/msedoublestringlisteditor_mfm.pas new file mode 100644 index 0000000..337d024 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msedoublestringlisteditor_mfm.pas @@ -0,0 +1,219 @@ +unit msedoublestringlisteditor_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msedoublestringlisteditor; + +const + objdata: record size: integer; data: array[0..4037] of byte end = + (size: 4038; data: ( + 84,80,70,48,23,116,100,111,117,98,108,101,115,116,114,105,110,103,108,105, + 115,116,101,100,105,116,111,114,22,100,111,117,98,108,101,115,116,114,105,110, + 103,108,105,115,116,101,100,105,116,111,114,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95,100,101,115,116, + 114,111,121,119,105,100,103,101,116,115,9,111,119,95,104,105,110,116,111,110, + 0,8,98,111,117,110,100,115,95,120,3,130,0,8,98,111,117,110,100,115, + 95,121,3,203,0,9,98,111,117,110,100,115,95,99,120,3,82,1,9,98, + 111,117,110,100,115,95,99,121,3,194,0,23,99,111,110,116,97,105,110,101, + 114,46,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,11,111,119,95, + 115,117,98,102,111,99,117,115,19,111,119,95,109,111,117,115,101,116,114,97, + 110,115,112,97,114,101,110,116,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,0,26,99,111,110,116,97,105,110,101,114,46,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,27,99,111,110, + 116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,16,99,111,110,116,97,105,110,101,114,46,98,111,117, + 110,100,115,1,2,0,2,0,3,82,1,3,194,0,0,7,111,112,116,105, + 111,110,115,11,13,102,111,95,99,108,111,115,101,111,110,101,115,99,15,102, + 111,95,97,117,116,111,114,101,97,100,115,116,97,116,16,102,111,95,97,117, + 116,111,119,114,105,116,101,115,116,97,116,0,8,115,116,97,116,102,105,108, + 101,7,10,116,115,116,97,116,102,105,108,101,49,7,99,97,112,116,105,111, + 110,6,16,83,116,114,105,110,103,108,105,115,116,101,100,105,116,111,114,15, + 109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,8,116,109,115, + 101,102,111,114,109,0,7,116,98,117,116,116,111,110,2,111,107,14,111,112, + 116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111, + 110,116,103,108,121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117, + 116,111,115,99,97,108,101,0,8,116,97,98,111,114,100,101,114,2,3,8, + 98,111,117,110,100,115,95,120,3,212,0,8,98,111,117,110,100,115,95,121, + 3,160,0,9,98,111,117,110,100,115,95,99,120,2,50,9,98,111,117,110, + 100,115,95,99,121,2,20,7,97,110,99,104,111,114,115,11,8,97,110,95, + 114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,5,115,116,97, + 116,101,11,10,97,115,95,100,101,102,97,117,108,116,15,97,115,95,108,111, + 99,97,108,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,99, + 97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,3,38,79,75, + 11,109,111,100,97,108,114,101,115,117,108,116,7,5,109,114,95,111,107,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,7,116,98, + 117,116,116,111,110,6,99,97,110,99,101,108,14,111,112,116,105,111,110,115, + 119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121, + 112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99,97, + 108,101,0,8,98,111,117,110,100,115,95,120,3,20,1,8,98,111,117,110, + 100,115,95,121,3,160,0,9,98,111,117,110,100,115,95,99,120,2,50,9, + 98,111,117,110,100,115,95,99,121,2,20,7,97,110,99,104,111,114,115,11, + 8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0, + 5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116, + 105,111,110,0,7,99,97,112,116,105,111,110,6,7,38,67,97,110,99,101, + 108,11,109,111,100,97,108,114,101,115,117,108,116,7,9,109,114,95,99,97, + 110,99,101,108,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,0,11,116,119,105,100,103,101,116,103,114,105,100,4,103,114,105,100,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116, + 97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,2,8, + 8,98,111,117,110,100,115,95,121,2,8,9,98,111,117,110,100,115,95,99, + 120,3,64,1,9,98,111,117,110,100,115,95,99,121,3,140,0,7,97,110, + 99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110,95,116,111, + 112,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109, + 0,11,111,112,116,105,111,110,115,103,114,105,100,11,12,111,103,95,99,111, + 108,115,105,122,105,110,103,12,111,103,95,114,111,119,109,111,118,105,110,103, + 15,111,103,95,107,101,121,114,111,119,109,111,118,105,110,103,15,111,103,95, + 114,111,119,105,110,115,101,114,116,105,110,103,14,111,103,95,114,111,119,100, + 101,108,101,116,105,110,103,19,111,103,95,102,111,99,117,115,99,101,108,108, + 111,110,101,110,116,101,114,15,111,103,95,97,117,116,111,102,105,114,115,116, + 114,111,119,13,111,103,95,97,117,116,111,97,112,112,101,110,100,10,111,103, + 95,119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112,117, + 112,17,111,103,95,109,111,117,115,101,115,99,114,111,108,108,99,111,108,0, + 13,102,105,120,99,111,108,115,46,99,111,117,110,116,2,1,13,102,105,120, + 99,111,108,115,46,105,116,101,109,115,14,1,5,119,105,100,116,104,2,31, + 7,110,117,109,115,116,101,112,2,1,0,0,13,102,105,120,114,111,119,115, + 46,99,111,117,110,116,2,1,13,102,105,120,114,111,119,115,46,105,116,101, + 109,115,14,1,6,104,101,105,103,104,116,2,16,14,99,97,112,116,105,111, + 110,115,46,99,111,117,110,116,2,3,14,99,97,112,116,105,111,110,115,46, + 105,116,101,109,115,14,1,7,99,97,112,116,105,111,110,6,1,97,9,116, + 101,120,116,102,108,97,103,115,11,0,0,1,7,99,97,112,116,105,111,110, + 6,1,98,9,116,101,120,116,102,108,97,103,115,11,0,0,1,0,0,0, + 0,14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,2,16,100, + 97,116,97,99,111,108,115,46,111,112,116,105,111,110,115,11,14,99,111,95, + 102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101, + 115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14, + 99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111, + 119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,118,97,108,117,101, + 12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110, + 99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95, + 109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,14,100,97,116,97, + 99,111,108,115,46,105,116,101,109,115,14,7,5,116,101,120,116,97,1,5, + 119,105,100,116,104,3,137,0,7,111,112,116,105,111,110,115,11,14,99,111, + 95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115, + 101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116, + 14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114, + 111,119,115,101,108,101,99,116,15,99,111,95,112,114,111,112,111,114,116,105, + 111,110,97,108,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111, + 95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112, + 121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117, + 115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110, + 97,109,101,6,5,116,101,120,116,97,9,100,97,116,97,99,108,97,115,115, + 7,22,116,103,114,105,100,109,115,101,115,116,114,105,110,103,100,97,116,97, + 108,105,115,116,0,7,5,116,101,120,116,98,1,5,119,105,100,116,104,3, + 145,0,7,111,112,116,105,111,110,115,11,14,99,111,95,102,111,99,117,115, + 115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99, + 116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117, + 108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101, + 99,116,7,99,111,95,102,105,108,108,12,99,111,95,115,97,118,101,118,97, + 108,117,101,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95, + 99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17, + 99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119, + 105,100,103,101,116,110,97,109,101,6,5,116,101,120,116,98,9,100,97,116, + 97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116,114,105, + 110,103,100,97,116,97,108,105,115,116,0,0,13,100,97,116,97,114,111,119, + 104,101,105,103,104,116,2,16,17,111,110,114,111,119,99,111,117,110,116,99, + 104,97,110,103,101,100,7,21,103,114,105,100,111,110,114,111,119,99,111,117, + 110,116,99,104,97,110,103,101,100,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,14,0,15,116,109,101,109,111,100,105,97,108,111,103,101,100, + 105,116,5,116,101,120,116,97,14,111,112,116,105,111,110,115,119,105,100,103, + 101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101, + 105,103,104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111, + 115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,12, + 102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101, + 46,99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95, + 108,101,118,101,108,111,10,102,114,108,95,108,101,118,101,108,105,15,102,114, + 108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,19,102,114,97,109,101, + 46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1,19,102,114,97, + 109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,5,99, + 111,108,111,114,4,5,0,0,144,7,105,109,97,103,101,110,114,2,17,0, + 0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111,114, + 4,5,0,0,144,20,102,114,97,109,101,46,98,117,116,116,111,110,46,105, + 109,97,103,101,110,114,2,17,8,116,97,98,111,114,100,101,114,2,1,7, + 118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,0,8, + 98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120, + 3,137,0,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105, + 111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112,111, + 112,117,112,109,101,110,117,13,111,101,49,95,115,97,118,101,118,97,108,117, + 101,0,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117, + 110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101, + 114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14, + 111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97, + 116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101, + 99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117, + 114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111, + 101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111, + 115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,22,111, + 101,95,102,111,99,117,115,114,101,99,116,111,110,114,101,97,100,111,110,108, + 121,18,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116, + 0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,15, + 116,109,101,109,111,100,105,97,108,111,103,101,100,105,116,5,116,101,120,116, + 98,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119, + 49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,11,111, + 112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109, + 101,98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,10, + 102,114,108,95,108,101,118,101,108,105,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,19,102,114,97,109,101,46,98,117,116,116,111,110, + 115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116,116, + 111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4,5,0, + 0,144,7,105,109,97,103,101,110,114,2,17,0,0,18,102,114,97,109,101, + 46,98,117,116,116,111,110,46,99,111,108,111,114,4,5,0,0,144,20,102, + 114,97,109,101,46,98,117,116,116,111,110,46,105,109,97,103,101,110,114,2, + 17,8,116,97,98,111,114,100,101,114,2,2,7,118,105,115,105,98,108,101, + 8,8,98,111,117,110,100,115,95,120,3,138,0,8,98,111,117,110,100,115, + 95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,145,0,9,98,111, + 117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105, + 116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110, + 117,13,111,101,49,95,115,97,118,101,118,97,108,117,101,0,11,111,112,116, + 105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101, + 115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95, + 99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105, + 102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114, + 110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120, + 105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111, + 101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111, + 115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116, + 111,110,102,105,114,115,116,99,108,105,99,107,22,111,101,95,102,111,99,117, + 115,114,101,99,116,111,110,114,101,97,100,111,110,108,121,18,111,101,95,104, + 105,110,116,99,108,105,112,112,101,100,116,101,120,116,0,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,0,12,116,105,110,116,101, + 103,101,114,101,100,105,116,8,114,111,119,99,111,117,110,116,13,111,112,116, + 105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101, + 102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119, + 95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119, + 102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117, + 115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,0,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,8,82, + 111,119,99,111,117,110,116,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,64,2,0,0, + 8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120, + 2,36,8,98,111,117,110,100,115,95,121,3,160,0,9,98,111,117,110,100, + 115,95,99,120,2,114,7,97,110,99,104,111,114,115,11,7,97,110,95,108, + 101,102,116,9,97,110,95,98,111,116,116,111,109,0,10,111,110,115,101,116, + 118,97,108,117,101,7,18,114,111,119,99,111,117,110,116,111,110,115,101,116, + 118,97,108,117,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,0,9,116,115,116,97,116,102,105,108,101,10,116,115,116,97,116,102, + 105,108,101,49,8,102,105,108,101,110,97,109,101,6,26,100,111,117,98,108, + 101,115,116,114,105,110,103,108,105,115,116,101,100,105,116,111,114,46,115,116, + 97,7,111,112,116,105,111,110,115,11,10,115,102,111,95,109,101,109,111,114, + 121,0,4,108,101,102,116,2,40,3,116,111,112,2,88,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tdoublestringlisteditor,''); +end. diff --git a/mseide-msegui/lib/common/designutils/msefaceselectorform.mfm b/mseide-msegui/lib/common/designutils/msefaceselectorform.mfm new file mode 100644 index 0000000..cbce007 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msefaceselectorform.mfm @@ -0,0 +1,44 @@ +object faceselectorfo: tfaceselectorfo + visible = False + bounds_x = 126 + bounds_y = 231 + bounds_cx = 320 + bounds_cy = 244 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 320 + 244 + ) + options = [fo_screencentered, fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder, fo_savestate] + statfile = tstatfile1 + caption = 'Face Selector' + moduleclassname = 'tmseform' + object lv: tlistview + frame.localprops = [] + frame.localprops1 = [] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 320 + bounds_cy = 244 + anchors = [] + optionsgrid = [og_colsizing, og_rowsizing, og_focuscellonenter, og_savestate, og_colchangeontabkey, og_wraprow, og_wrapcol, og_autopopup, og_mousescrollcol] + options = [lvo_readonly, lvo_horz, lvo_drawfocus, lvo_leftbuttonfocusonly, lvo_focusselect, lvo_mouseselect, lvo_savestate] + itemlist.onpaintitem = paintitemexe + itemlist.captionpos = cp_bottom + itemlist.imagewidth = 16 + itemlist.imageheight = 16 + statfile = tstatfile1 + onlayoutchanged = layoutcha + onitemevent = itemev + reffontheight = 14 + end + object tstatfile1: tstatfile + filename = 'faceselector.sta' + options = [sfo_memory, sfo_activatorread, sfo_activatorwrite] + left = 72 + top = 48 + end +end diff --git a/mseide-msegui/lib/common/designutils/msefaceselectorform.pas b/mseide-msegui/lib/common/designutils/msefaceselectorform.pas new file mode 100644 index 0000000..b8cf375 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msefaceselectorform.pas @@ -0,0 +1,109 @@ +{ MSEide Copyright (c) 1999-2015 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit msefaceselectorform; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,mseglob,mseguiglob,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,mseforms,msedataedits, + msedatanodes,mseedit,msegrids,mselistbrowser,msestrings,msetypes,msebitmap, + msestatfile; +type + tfaceselectorfo = class(tmseform) + lv: tlistview; + tstatfile1: tstatfile; + procedure itemev(const sender: tcustomlistview; const index: Integer; + var info: celleventinfoty); + procedure paintitemexe(const sender: titemviewlist; const canvas: tcanvas; + const item: tlistedititem); + procedure layoutcha(const sender: tcustomlistview); + private + ffacelist: tfacelist; + ffacenr: integer; + public + constructor create(const aowner: tcomponent; const afacelist: tfacelist; + var afacenr: integer); reintroduce; + end; +implementation +uses + msefaceselectorform_mfm,sysutils,mseformatstr; + +{ tfaceselectorfo } + +constructor tfaceselectorfo.create(const aowner: tcomponent; + const afacelist: tfacelist; var afacenr: integer); +var + int1: integer; +begin + if afacelist <> nil then begin + ffacelist:= afacelist; + ffacenr:= afacenr; + inherited create(aowner); +{ + with lv do begin + int1:= aimagelist.width + 2; + if int1 < 20 then begin + int1:= 20; + end; + cellwidth:= int1; + cellheight:= aimagelist.height + font.lineheight + 3; + cellsize:= ms(35,40); + end; +} + with lv.itemlist do begin +// imagelist:= aimagelist; + count:= afacelist.list.count; +// imagewidth:= aimagelist.width; +// imageheight:= aimagelist.height+2; + for int1:= 0 to count -1 do begin + with items[int1] do begin + imagenr:= int1; + caption:= inttostrmse(int1); + end; + end; + end; + lv.focusedindex:= ffacenr; + show(true); + afacenr:= ffacenr; + end; + release; +end; + +procedure tfaceselectorfo.itemev(const sender: tcustomlistview; + const index: Integer; var info: celleventinfoty); +begin + if iscellclick(info) then begin + ffacenr:= index; + window.modalresult:= mr_ok; + end; +end; + +procedure tfaceselectorfo.paintitemexe(const sender: titemviewlist; + const canvas: tcanvas; const item: tlistedititem); +begin + if ffacelist <> nil then begin + ffacelist.paint(canvas,item.index,sender.layoutinfo.imagerect); + end; +end; + +procedure tfaceselectorfo.layoutcha(const sender: tcustomlistview); +begin + sender.itemlist.imagesize:= + ms(sender.cellwidth,sender.cellheight-sender.font.glyphheight-2); +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/msefaceselectorform_mfm.pas b/mseide-msegui/lib/common/designutils/msefaceselectorform_mfm.pas new file mode 100644 index 0000000..60a3e56 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msefaceselectorform_mfm.pas @@ -0,0 +1,70 @@ +unit msefaceselectorform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msefaceselectorform; + +const + objdata: record size: integer; data: array[0..1056] of byte end = + (size: 1057; data: ( + 84,80,70,48,15,116,102,97,99,101,115,101,108,101,99,116,111,114,102,111, + 14,102,97,99,101,115,101,108,101,99,116,111,114,102,111,7,118,105,115,105, + 98,108,101,8,8,98,111,117,110,100,115,95,120,2,126,8,98,111,117,110, + 100,115,95,121,3,231,0,9,98,111,117,110,100,115,95,99,120,3,64,1, + 9,98,111,117,110,100,115,95,99,121,3,244,0,26,99,111,110,116,97,105, + 110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,0,27,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,99,111,110,116,97,105,110, + 101,114,46,98,111,117,110,100,115,1,2,0,2,0,3,64,1,3,244,0, + 0,7,111,112,116,105,111,110,115,11,17,102,111,95,115,99,114,101,101,110, + 99,101,110,116,101,114,101,100,13,102,111,95,99,108,111,115,101,111,110,101, + 115,99,15,102,111,95,97,117,116,111,114,101,97,100,115,116,97,116,16,102, + 111,95,97,117,116,111,119,114,105,116,101,115,116,97,116,10,102,111,95,115, + 97,118,101,112,111,115,13,102,111,95,115,97,118,101,122,111,114,100,101,114, + 12,102,111,95,115,97,118,101,115,116,97,116,101,0,8,115,116,97,116,102, + 105,108,101,7,10,116,115,116,97,116,102,105,108,101,49,7,99,97,112,116, + 105,111,110,6,13,70,97,99,101,32,83,101,108,101,99,116,111,114,15,109, + 111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,8,116,109,115,101, + 102,111,114,109,0,9,116,108,105,115,116,118,105,101,119,2,108,118,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,98,111, + 117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,120,3,64,1,9,98,111,117,110,100,115,95, + 99,121,3,244,0,7,97,110,99,104,111,114,115,11,0,11,111,112,116,105, + 111,110,115,103,114,105,100,11,12,111,103,95,99,111,108,115,105,122,105,110, + 103,12,111,103,95,114,111,119,115,105,122,105,110,103,19,111,103,95,102,111, + 99,117,115,99,101,108,108,111,110,101,110,116,101,114,12,111,103,95,115,97, + 118,101,115,116,97,116,101,20,111,103,95,99,111,108,99,104,97,110,103,101, + 111,110,116,97,98,107,101,121,10,111,103,95,119,114,97,112,114,111,119,10, + 111,103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111, + 112,117,112,17,111,103,95,109,111,117,115,101,115,99,114,111,108,108,99,111, + 108,0,7,111,112,116,105,111,110,115,11,12,108,118,111,95,114,101,97,100, + 111,110,108,121,8,108,118,111,95,104,111,114,122,13,108,118,111,95,100,114, + 97,119,102,111,99,117,115,23,108,118,111,95,108,101,102,116,98,117,116,116, + 111,110,102,111,99,117,115,111,110,108,121,15,108,118,111,95,102,111,99,117, + 115,115,101,108,101,99,116,15,108,118,111,95,109,111,117,115,101,115,101,108, + 101,99,116,13,108,118,111,95,115,97,118,101,115,116,97,116,101,0,20,105, + 116,101,109,108,105,115,116,46,111,110,112,97,105,110,116,105,116,101,109,7, + 12,112,97,105,110,116,105,116,101,109,101,120,101,19,105,116,101,109,108,105, + 115,116,46,99,97,112,116,105,111,110,112,111,115,7,9,99,112,95,98,111, + 116,116,111,109,19,105,116,101,109,108,105,115,116,46,105,109,97,103,101,119, + 105,100,116,104,2,16,20,105,116,101,109,108,105,115,116,46,105,109,97,103, + 101,104,101,105,103,104,116,2,16,8,115,116,97,116,102,105,108,101,7,10, + 116,115,116,97,116,102,105,108,101,49,15,111,110,108,97,121,111,117,116,99, + 104,97,110,103,101,100,7,9,108,97,121,111,117,116,99,104,97,11,111,110, + 105,116,101,109,101,118,101,110,116,7,6,105,116,101,109,101,118,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,9,116,115,116,97, + 116,102,105,108,101,10,116,115,116,97,116,102,105,108,101,49,8,102,105,108, + 101,110,97,109,101,6,16,102,97,99,101,115,101,108,101,99,116,111,114,46, + 115,116,97,7,111,112,116,105,111,110,115,11,10,115,102,111,95,109,101,109, + 111,114,121,17,115,102,111,95,97,99,116,105,118,97,116,111,114,114,101,97, + 100,18,115,102,111,95,97,99,116,105,118,97,116,111,114,119,114,105,116,101, + 0,4,108,101,102,116,2,72,3,116,111,112,2,48,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tfaceselectorfo,''); +end. diff --git a/mseide-msegui/lib/common/designutils/msefadeedit.mfm b/mseide-msegui/lib/common/designutils/msefadeedit.mfm new file mode 100644 index 0000000..55c3c77 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msefadeedit.mfm @@ -0,0 +1,653 @@ +object fadeeditfo: tfadeeditfo + optionswidget = [ow_arrowfocus, ow_subfocus, ow_destroywidgets, ow_hinton] + visible = False + bounds_x = 150 + bounds_y = 221 + bounds_cx = 519 + bounds_cy = 443 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 519 + 443 + ) + options = [fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savestate] + statfile = formstatfile + caption = 'Fade Edit' + windowopacity = -Inf + oncreate = createev + moduleclassname = 'tmseform' + object cont2: tsimplewidget + visible = True + bounds_x = 0 + bounds_y = 0 + bounds_cx = 519 + bounds_cy = 402 + anchors = [an_top, an_bottom] + object cont1: tsimplewidget + visible = True + bounds_x = 0 + bounds_y = 73 + bounds_cx = 519 + bounds_cy = 330 + anchors = [an_top, an_bottom] + object tsimplewidget7: tsimplewidget + optionswidget = [ow_mousetransparent, ow_destroywidgets] + color = -1610612731 + face.fade_direction = gd_down + face.localprops = [fal_fadirection] + taborder = 5 + visible = True + bounds_x = 444 + bounds_y = 56 + bounds_cx = 66 + bounds_cy = 273 + anchors = [an_top, an_right, an_bottom] + end + object gridlayout: tlayouter + bounds_x = 8 + bounds_y = 56 + bounds_cx = 431 + bounds_cy = 274 + bounds_cymin = 90 + anchors = [an_left, an_top, an_right, an_bottom] + object opagrid: twidgetgrid + Tag = 1 + frame.caption = 'Opacity' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + bounds_x = 0 + bounds_y = 147 + bounds_cx = 433 + bounds_cy = 126 + anchors = [an_left, an_right, an_bottom] + optionsgrid = [og_colsizing, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autoappend, og_sorted, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixcols.count = 1 + fixcols.items = < + item + width = 22 + numstep = 1 + end> + datacols.count = 3 + datacols.options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item + colorselect = -2147483642 + width = 24 + onbeforedrawcell = beforedrawev + options = [co_nofocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_mousescrollrow] + end + item[opaposed] + width = 89 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savevalue, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + name = 'opapos' + widgetname = 'opaposed' + dataclass = tgridrealdatalist + end + item[opacolored] + width = 290 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savevalue, co_savestate, co_nosort, co_cancopy, co_canpaste, co_mousescrollrow] + widthmin = 63 + name = 'opacolor' + widgetname = 'opacolored' + dataclass = tgridenumdatalist + end> + datarowheight = 16 + statfile = fadestatfile + onrowsinserted = rowinsertev + onrowsdeleted = rowdeleteev + oncellevent = gridcellev + reffontheight = 14 + object opaposed: trealedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + taborder = 1 + visible = False + bounds_x = 25 + bounds_y = 0 + bounds_cx = 89 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + ondataentered = dataenteterev + value = -Inf + valuedefault = -Inf + formatedit = '0.000' + formatdisp = '0.000' + valuerange = 1 + valuestart = 0 + valuemin = 0 + valuemax = 1 + reffontheight = 14 + end + object opacolored: tcoloredit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.button.color = -1879048187 + frame.buttons.count = 2 + frame.buttons.items = < + item + color = -1879048187 + end + item + color = -1879048187 + imagenr = 17 + end> + frame.buttonellipse.color = -1879048187 + frame.buttonellipse.imagenr = 17 + taborder = 2 + visible = False + bounds_x = 115 + bounds_y = 0 + bounds_cx = 290 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue, oe1_thumbtrack] + ondataentered = dataenteterev + valuedefault = -1610612731 + reffontheight = 14 + end + end + object grid: twidgetgrid + frame.localprops = [] + frame.localprops1 = [] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 433 + bounds_cy = 144 + anchors = [an_left, an_top, an_right, an_bottom] + optionsgrid = [og_colsizing, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autoappend, og_sorted, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixcols.count = 1 + fixcols.items = < + item + width = 22 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 4 + captions.items = < + item + end + item + caption = 'Pos' + end + item + caption = 'Color' + end + item + caption = 'Opacity' + end> + end> + datacols.count = 4 + datacols.options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item + colorselect = -2147483642 + width = 24 + onbeforedrawcell = beforedrawev + options = [co_nofocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_mousescrollrow] + end + item[posed] + width = 89 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savevalue, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'posed' + dataclass = tgridrealdatalist + end + item[colored] + width = 151 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savevalue, co_savestate, co_nosort, co_cancopy, co_canpaste, co_mousescrollrow] + widthmin = 63 + widgetname = 'colored' + dataclass = tgridenumdatalist + end + item[opaed] + width = 138 + options = [co_invisible, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savevalue, co_savestate, co_nosort, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'opaed' + dataclass = tgridenumdatalist + end> + datarowheight = 16 + statfile = fadestatfile + onrowsinserted = rowinsertev + onrowsdeleted = rowdeleteev + oncellevent = gridcellev + reffontheight = 14 + object posed: trealedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + taborder = 1 + visible = False + bounds_x = 25 + bounds_y = 0 + bounds_cx = 89 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + ondataentered = dataenteterev + value = -Inf + valuedefault = -Inf + formatedit = '0.000' + formatdisp = '0.000' + valuerange = 1 + valuestart = 0 + valuemin = 0 + valuemax = 1 + reffontheight = 14 + end + object colored: tcoloredit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.button.color = -1879048187 + frame.buttons.count = 2 + frame.buttons.items = < + item + color = -1879048187 + end + item + color = -1879048187 + imagenr = 17 + end> + frame.buttonellipse.color = -1879048187 + frame.buttonellipse.imagenr = 17 + taborder = 2 + visible = False + bounds_x = 115 + bounds_y = 0 + bounds_cx = 151 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue, oe1_thumbtrack] + ondataentered = dataenteterev + valuedefault = -1610612731 + reffontheight = 14 + end + object opaed: tcoloredit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.button.color = -1879048187 + frame.buttons.count = 2 + frame.buttons.items = < + item + color = -1879048187 + end + item + color = -1879048187 + imagenr = 17 + end> + frame.buttonellipse.color = -1879048187 + frame.buttonellipse.imagenr = 17 + taborder = 3 + visible = False + bounds_x = 267 + bounds_y = 0 + bounds_cx = 138 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue, oe1_thumbtrack] + ondataentered = dataenteterev + valuedefault = -1610612730 + reffontheight = 14 + end + end + object splitter: tsplitter + color = -1879048189 + taborder = 2 + bounds_x = 0 + bounds_y = 144 + bounds_cx = 431 + bounds_cy = 3 + anchors = [an_top] + options = [spo_vmove, spo_vprop, spo_dockleft, spo_docktop, spo_dockright, spo_dockbottom] + linktop = grid + linkbottom = opagrid + statfile = formstatfile + end + end + object posedit: tpickwidget + optionswidget = [ow_destroywidgets] + frame.leveli = -1 + frame.framei_bottom = 2 + frame.localprops = [frl_leveli, frl_fibottom] + frame.localprops1 = [] + taborder = 2 + onpaint = pospaintev + bounds_x = 8 + bounds_y = 0 + bounds_cx = 504 + bounds_cy = 50 + anchors = [an_left, an_top, an_right] + onclientmouseevent = mouseev + onresize = resizeev + ongetcursorshape = getcursorshapeev + ongetpickobjects = getpickobjectev + onendpickmove = endpickev + onpaintxorpic = paintxorev + object tsimplewidget3: tsimplewidget + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_mousetransparent, ow_destroywidgets] + color = -1610612731 + face.localprops = [] + taborder = 3 + visible = True + bounds_x = 1 + bounds_y = 1 + bounds_cx = 502 + bounds_cy = 40 + anchors = [an_top] + end + object tsimplewidget2: tsimplewidget + optionswidget = [ow_mousetransparent, ow_destroywidgets] + color = -1610612730 + taborder = 1 + visible = True + bounds_x = 1 + bounds_y = 0 + bounds_cx = 502 + bounds_cy = 13 + anchors = [an_top] + end + object tsimplewidget4: tsimplewidget + optionswidget = [ow_mousetransparent, ow_destroywidgets] + color = -1610612734 + taborder = 2 + visible = True + bounds_x = 1 + bounds_y = 27 + bounds_cx = 502 + bounds_cy = 13 + anchors = [an_top] + end + object fadedisp: tsimplewidget + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_mousetransparent, ow_destroywidgets] + color = -2147483645 + face.localprops = [] + visible = True + bounds_x = 1 + bounds_y = 0 + bounds_cx = 502 + bounds_cy = 40 + anchors = [an_top] + end + end + object tsimplewidget5: tsimplewidget + optionswidget = [ow_mousetransparent, ow_destroywidgets] + color = -1610612734 + taborder = 3 + visible = True + bounds_x = 445 + bounds_y = 56 + bounds_cx = 23 + bounds_cy = 273 + anchors = [an_top, an_right, an_bottom] + end + object tsimplewidget6: tsimplewidget + optionswidget = [ow_mousetransparent, ow_destroywidgets] + color = -1610612730 + taborder = 4 + visible = True + bounds_x = 489 + bounds_y = 56 + bounds_cx = 22 + bounds_cy = 273 + anchors = [an_top, an_right, an_bottom] + end + object fadevert: tsimplewidget + optionswidget = [ow_mousetransparent, ow_destroywidgets] + color = -2147483645 + frame.leveli = -1 + frame.localprops = [frl_leveli] + frame.localprops1 = [] + face.fade_direction = gd_down + face.localprops = [fal_fadirection] + taborder = 1 + visible = True + bounds_x = 444 + bounds_y = 56 + bounds_cx = 68 + bounds_cy = 274 + anchors = [an_top, an_right, an_bottom] + end + end + object opaedit: tpickwidget + Tag = 1 + optionswidget = [ow_destroywidgets] + frame.options = [cfo_fixtop] + frame.leveli = -1 + frame.framei_bottom = 2 + frame.caption = 'Opacity' + frame.localprops = [frl_leveli, frl_fibottom] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + onpaint = pospaintev + bounds_x = 8 + bounds_y = 0 + bounds_cx = 504 + bounds_cy = 67 + bounds_cxmin = 461 + anchors = [an_left, an_top, an_right] + onclientmouseevent = mouseev + onresize = resizeev + ongetcursorshape = getcursorshapeev + ongetpickobjects = getpickobjectev + onendpickmove = endpickev + onpaintxorpic = paintxorev + object opadisp: tsimplewidget + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_mousetransparent, ow_destroywidgets] + color = -2147483645 + face.localprops = [] + visible = True + bounds_x = 1 + bounds_y = 17 + bounds_cx = 502 + bounds_cy = 40 + anchors = [an_top] + end + end + end + object bottomlayout: tlayouter + taborder = 1 + bounds_x = 8 + bounds_y = 407 + bounds_cx = 504 + bounds_cy = 31 + anchors = [an_left, an_right, an_bottom] + optionsscale = [osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_placex, lao_aligny] + align_glue = wam_center + place_mindist = 5 + linktop = cont2 + dist_top = 5 + options = [spao_gluebottom] + object switchlayout: tlayouter + bounds_x = 0 + bounds_y = 0 + bounds_cx = 142 + bounds_cy = 30 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + optionslayout = [lao_placex, lao_aligny] + align_glue = wam_center + place_mindist = 5 + object splitopa: tbooleanedit + frame.caption = 'Separate'#10'Opacity' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 8 + 61 + 9 + ) + bounds_x = 68 + bounds_y = 0 + bounds_cx = 74 + bounds_cy = 30 + onsetvalue = sepopaset + end + object reverse: tbooleanedit + frame.caption = '&reverse' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 50 + 2 + ) + taborder = 1 + bounds_x = 0 + bounds_y = 7 + bounds_cx = 63 + bounds_cy = 16 + ondataentered = reverseenteredev + end + end + object buttonlayout: tlayouter + taborder = 1 + bounds_x = 176 + bounds_y = 0 + bounds_cx = 328 + bounds_cy = 31 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + optionslayout = [lao_placex] + place_mindist = 5 + object tbutton2: tbutton + optionswidget1 = [ow1_autoscale, ow1_autowidth] + bounds_x = 270 + bounds_y = 0 + bounds_cx = 58 + bounds_cy = 31 + bounds_cxmin = 58 + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_canclose + end + object tbutton1: tbutton + optionswidget1 = [ow1_autoscale, ow1_autowidth] + taborder = 1 + bounds_x = 207 + bounds_y = 0 + bounds_cx = 58 + bounds_cy = 31 + bounds_cxmin = 58 + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + end + object tsimplewidget1: tsimplewidget + taborder = 2 + bounds_x = 198 + bounds_y = 8 + bounds_cx = 4 + bounds_cy = 18 + end + object tbutton3: tbutton + optionswidget1 = [ow1_autoscale, ow1_autowidth] + taborder = 3 + bounds_x = 135 + bounds_y = 0 + bounds_cx = 58 + bounds_cy = 31 + bounds_cxmin = 58 + state = [as_localcaption, as_localonexecute] + caption = '&Save' + onexecute = saveex + end + object tbutton4: tbutton + optionswidget1 = [ow1_autoscale, ow1_autowidth] + taborder = 4 + bounds_x = 72 + bounds_y = 0 + bounds_cx = 58 + bounds_cy = 31 + bounds_cxmin = 58 + state = [as_localcaption, as_localonexecute] + caption = '&Load' + onexecute = loadex + end + object clearbu: tbutton + optionswidget1 = [ow1_autoscale, ow1_autowidth] + taborder = 5 + hint = 'Clear opacity gradient' + bounds_x = 0 + bounds_y = 0 + bounds_cx = 67 + bounds_cy = 31 + bounds_cxmin = 58 + state = [as_disabled, as_localdisabled, as_localcaption, as_localhint, as_localonexecute] + caption = 'ClearOpa' + onexecute = clearopaexe + end + end + end + object formstatfile: tstatfile + filename = 'fadeeditor.sta' + options = [sfo_memory, sfo_activatorread, sfo_activatorwrite] + left = 96 + top = 200 + end + object filedialog: tfiledialog + statfile = formstatfile + controller.filterlist.data = ( + ( + 'Fade Files' + '*.fad' + ) + ( + 'All Files' + '*' + ) + ) + controller.defaultext = 'fad' + controller.options = [fdo_checkexist, fdo_savelastdir] + controller.captionopen = 'Load Fade File' + controller.captionsave = 'Save Fade File' + left = 208 + top = 240 + end + object fadestatfile: tstatfile + filename = 'status.sta' + onstatupdate = fadestatupdateexe + left = 200 + top = 200 + end + object c: tstringcontainer + strings.data = ( + 'Do you want to synchronize opacity gradient' + 'with color gradient?' + 'Do you want to remove opacity gradient?' + ) + left = 88 + top = 344 + end +end diff --git a/mseide-msegui/lib/common/designutils/msefadeedit.pas b/mseide-msegui/lib/common/designutils/msefadeedit.pas new file mode 100644 index 0000000..bcbbfe0 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msefadeedit.pas @@ -0,0 +1,1031 @@ +unit msefadeedit; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseglob,mseguiglob,mseapplication,msestat,msemenus,msegui,msegraphics, + msegraphutils,mseevent,mseclasses,mseforms,msepickwidget,mseimage,msetypes, + msepointer,msewidgets,msedataedits,mseedit,msegrids,msestrings,msewidgetgrid, + msecolordialog,mseeditglob,msesimplewidgets,{msepropertyeditors,}msestatfile, + msegraphedits,msebitmap,msedatanodes,msefiledialog,mselistbrowser,msesys, + msegridsglob,mseobjectpicker,mseifiglob,msearrayprops,msesplitter, + msestringcontainer,mseificomp,mseificompglob,msescrollbar; + +type + nodeinfoty = record + nodepos: integerarty; + marker: pointarty; + grid: tcustomgrid; + posed: trealedit; + colored: tcoloredit; + opaed: tcoloredit; + end; + pnodeinfoty = ^nodeinfoty; + + tfadeeditfo = class(tmseform) + formstatfile: tstatfile; + filedialog: tfiledialog; + fadestatfile: tstatfile; + cont2: tsimplewidget; + cont1: tsimplewidget; + tsimplewidget7: tsimplewidget; + gridlayout: tlayouter; + opagrid: twidgetgrid; + opaposed: trealedit; + opacolored: tcoloredit; + grid: twidgetgrid; + posed: trealedit; + colored: tcoloredit; + opaed: tcoloredit; + splitter: tsplitter; + posedit: tpickwidget; + tsimplewidget3: tsimplewidget; + tsimplewidget2: tsimplewidget; + tsimplewidget4: tsimplewidget; + fadedisp: tsimplewidget; + tsimplewidget5: tsimplewidget; + tsimplewidget6: tsimplewidget; + fadevert: tsimplewidget; + opaedit: tpickwidget; + opadisp: tsimplewidget; + c: tstringcontainer; + bottomlayout: tlayouter; + switchlayout: tlayouter; + splitopa: tbooleanedit; + reverse: tbooleanedit; + buttonlayout: tlayouter; + tbutton2: tbutton; + tbutton1: tbutton; + tsimplewidget1: tsimplewidget; + tbutton3: tbutton; + tbutton4: tbutton; + clearbu: tbutton; + procedure mouseev(const sender: twidget; var info: mouseeventinfoty); + procedure pospaintev(const sender: twidget; const canvas: tcanvas); + procedure createev(const sender: TObject); + procedure getcursorshapeev(const sender: tcustompickwidget; + const picker: tobjectpicker; + var shape: cursorshapety; var found: Boolean); + procedure getpickobjectev(const sender: tcustompickwidget; + const picker: tobjectpicker; + var objects: integerarty); + procedure paintxorev(const sender: tcustompickwidget; + const picker: tobjectpicker; const canvas: tcanvas); + procedure endpickev(const sender: tcustompickwidget; + const picker: tobjectpicker); + procedure resizeev(const sender: TObject); + procedure dataenteterev(const sender: TObject); + procedure rowdeleteev(const sender: tcustomgrid; const aindex: Integer; + const acount: Integer); + procedure gridcellev(const sender: TObject; var info: celleventinfoty); + procedure rowinsertev(const sender: tcustomgrid; const aindex: Integer; + const acount: Integer); + procedure beforedrawev(const sender: tcol; const canvas: tcanvas; + var cellinfo: cellinfoty; var processed: Boolean); + procedure reverseenteredev(const sender: TObject); + procedure saveex(const sender: TObject); + procedure loadex(const sender: TObject); + procedure clearopaexe(const sender: TObject); + procedure fadestatupdateexe(const sender: TObject; const filer: tstatfiler); + procedure sepopaset(const sender: TObject; var avalue: Boolean; + var accept: Boolean); + private + fnodeinfo: nodeinfoty; + fnodeinfoopa: nodeinfoty; +// ffadepos,ffadeopapos: trealarrayprop; +// ffadecolor,ffadeopacolor: tcolorarrayprop; + fopacitycleared: boolean; + fopa: boolean; + fopasynced: boolean; + procedure movemarker(const atag: integer; apos: integer); + function findmarker(const atag: integer; const apos: pointty): integer; + //-1 if not found + function limitmarkerpos(const atag: integer; const index: integer; + const aoffset: integer): integer; + procedure setopasynced(const avalue: boolean); + protected + function nodeinfo(const atag: integer): pnodeinfoty; + function syncexe: boolean; + procedure change; + procedure doasyncevent(var atag: integer); override; + property opasynced: boolean read fopasynced write setopasynced; + end; + + +function editfade(var fadedirection: graphicdirectionty; const opa: boolean; + const fadepos,fadeopapos: trealarrayprop; + const fadecolor,fadeopacolor: tcolorarrayprop): modalresultty; + +implementation + +uses + msefadeedit_mfm,msedatalist,msearrayutils; +type + stringconsts = ( + sc_syncopa, //0 + sc_withcolor, //1 + sc_removeopacity //2 + ); + +function editfade(var fadedirection: graphicdirectionty; const opa: boolean; + const fadepos,fadeopapos: trealarrayprop; + const fadecolor,fadeopacolor: tcolorarrayprop): modalresultty; +var + form1: tfadeeditfo; + int1: integer; + bo1: boolean; +begin + form1:= tfadeeditfo.create(nil); + try + with form1 do begin + fopa:= opa; +// ffadepos:= fadepos; +// ffadeopapos:= fadeopapos; +// ffadecolor:= fadecolor; +// ffadeopacolor:= fadeopacolor; + reverse.value:= fadedirection in [gd_left,gd_up]; + end; + if opa then begin + form1.grid.rowcount:= fadeopapos.count; + for int1:= 0 to form1.grid.rowhigh do begin + form1.posed[int1]:= fadeopapos[int1]; + form1.colored[int1]:= fadeopacolor[int1]; + end; + form1.fopacitycleared:= true; + form1.splitopa.enabled:= false; + form1.opasynced:= true; + end + else begin + bo1:= (fadepos.count = fadeopapos.count) and (fadepos.count <> 0); + form1.grid.rowcount:= fadepos.count; + for int1:= 0 to form1.grid.rowhigh do begin + form1.posed[int1]:= fadepos[int1]; + form1.colored[int1]:= fadecolor[int1]; + bo1:= bo1 and (fadepos[int1] = fadeopapos[int1]); + end; + if bo1 then begin + for int1:= 0 to form1.grid.rowhigh do begin + form1.opaed[int1]:= fadeopacolor[int1]; + bo1:= bo1 and (fadepos[int1] = fadeopapos[int1]); + end; + end; + form1.fopacitycleared:= fadeopapos.count = 0; + bo1:= bo1 or form1.fopacitycleared; +// form1.splitopa.value:= bo1; + form1.clearbu.enabled:= bo1 and not form1.fopacitycleared; + form1.opasynced:= bo1; + form1.opagrid.rowcount:= fadeopapos.count; + for int1:= 0 to form1.opagrid.rowhigh do begin + form1.opaposed[int1]:= fadeopapos[int1]; + form1.opacolored[int1]:= fadeopacolor[int1]; + end; + form1.grid.datacols[3].visible:= bo1 and not form1.fopacitycleared; + end; + form1.change; + result:= form1.show(true); + if result = mr_ok then begin + if form1.reverse.value then begin + if fadedirection = gd_right then begin + fadedirection:= gd_left; + end + else begin + if fadedirection <> gd_left then begin + fadedirection:= gd_up; + end; + end; + end + else begin + if fadedirection = gd_left then begin + fadedirection:= gd_right; + end + else begin + if fadedirection <> gd_right then begin + fadedirection:= gd_down; + end; + end; + end; + if opa then begin + fadeopapos.assign(form1.fadedisp.face.fade_pos); + fadeopacolor.assign(form1.fadedisp.face.fade_color); + end + else begin + fadepos.assign(form1.fadedisp.face.fade_pos); + fadecolor.assign(form1.fadedisp.face.fade_color); + fadeopapos.assign(form1.fadedisp.face.fade_opapos); + fadeopacolor.assign(form1.fadedisp.face.fade_opacolor); + end; + end; + finally + form1.free; + end; +end; + +{ +procedure editfacefade(const aproperty: tpropertyeditor; const trans: boolean); +var + form1: tfadeeditfo; + int1: integer; + bo1: boolean; +begin + form1:= tfadeeditfo.create(nil); + try + with tcustomface(tpropertyeditor1(aproperty).instance) do begin + form1.reverse.value:= fade_direction in [gd_left,gd_up]; + if trans then begin + form1.grid.rowcount:= fade_transpos.count; + for int1:= 0 to form1.grid.rowhigh do begin + form1.posed[int1]:= fade_transpos[int1]; + form1.colored[int1]:= fade_transcolor[int1]; + end; + end + else begin + bo1:= fade_pos.count = fade_transpos.count; + form1.grid.rowcount:= fade_pos.count; + for int1:= 0 to form1.grid.rowhigh do begin + form1.posed[int1]:= fade_pos[int1]; + form1.colored[int1]:= fade_color[int1]; + bo1:= bo1 and (fade_pos[int1] = fade_transpos[int1]); + end; + if bo1 then begin + for int1:= 0 to form1.grid.rowhigh do begin + form1.transed[int1]:= fade_transcolor[int1]; + bo1:= bo1 and (fade_pos[int1] = fade_transpos[int1]); + end; + end; + syncbu.enabled:= not bo1; + end; + form1.change; + end; + if form1.show(true) = mr_ok then begin + with tpropertyeditor1(aproperty) do begin + for int1:= 0 to count - 1 do begin + with tcustomface(instance(int1)) do begin + if form1.reverse.value then begin + if fade_direction = gd_right then begin + fade_direction:= gd_left; + end + else begin + if fade_direction <> gd_left then begin + fade_direction:= gd_up; + end; + end; + end + else begin + if fade_direction = gd_left then begin + fade_direction:= gd_right; + end + else begin + if fade_direction <> gd_right then begin + fade_direction:= gd_down; + end; + end; + end; + if trans then begin + fade_transpos.assign(form1.fadedisp.face.fade_pos); + fade_transcolor.assign(form1.fadedisp.face.fade_color); + end + else begin + fade_pos.assign(form1.fadedisp.face.fade_pos); + fade_color.assign(form1.fadedisp.face.fade_color); + end; + end; + end; + modified; + end; + end; + finally + form1.free; + end; +end; +} + +{ +procedure editfacetemplatefade(const aproperty: tpropertyeditor; + const trans: boolean); +var + form1: tfadeeditfo; + int1: integer; +begin + form1:= tfadeeditfo.create(nil); + try + with tfacetemplate(tpropertyeditor1(aproperty).instance) do begin + form1.reverse.value:= fade_direction in [gd_left,gd_up]; + if trans then begin + form1.grid.rowcount:= fade_transpos.count; + for int1:= 0 to form1.grid.rowhigh do begin + form1.posed[int1]:= fade_transpos[int1]; + form1.colored[int1]:= fade_transcolor[int1]; + end; + end + else begin + form1.grid.rowcount:= fade_pos.count; + for int1:= 0 to form1.grid.rowhigh do begin + form1.posed[int1]:= fade_pos[int1]; + form1.colored[int1]:= fade_color[int1]; + end; + end; + form1.change; + end; + if form1.show(true) = mr_ok then begin + with tpropertyeditor1(aproperty) do begin + for int1:= 0 to count - 1 do begin + with tfacetemplate(instance(int1)) do begin + if form1.reverse.value then begin + if fade_direction = gd_right then begin + fade_direction:= gd_left; + end + else begin + if fade_direction <> gd_left then begin + fade_direction:= gd_up; + end; + end; + end + else begin + if fade_direction = gd_left then begin + fade_direction:= gd_right; + end + else begin + if fade_direction <> gd_right then begin + fade_direction:= gd_down; + end; + end; + end; + if trans then begin + fade_transpos.assign(form1.fadedisp.face.fade_pos); + fade_transcolor.assign(form1.fadedisp.face.fade_color); + end + else begin + fade_pos.assign(form1.fadedisp.face.fade_pos); + fade_color.assign(form1.fadedisp.face.fade_color); + end; + end; + end; + modified; + end; + end; + finally + form1.free; + end; +end; +} +{ tfadeeditfo } + +const + markerhalfwidth = 2; + markerheight = markerhalfwidth+1; + +procedure tfadeeditfo.mouseev(const sender: twidget; var info: mouseeventinfoty); +var + ar1: integerarty; + int1,int2: integer; + rea1,rea2,rea3: realty; + rect1: rectty; + posx: integer; +begin + if (info.pos.y < fadedisp.height) and sender.isleftbuttondown(info) then begin + if reverse.value then begin + posx:= posedit.paintsize.cx - info.pos.x; + end + else begin + posx:= info.pos.x; + end; + with nodeinfo(sender.tag)^ do begin + additem(nodepos,posx); + sortarray(nodepos,ar1); + if grid.rowcount < 2 then begin + int1:= grid.rowcount; + grid.rowcount:= 2; + posed[0]:= 0; + posed[1]:= 1; + if int1 < 1 then begin + colored[0]:= defaultfadecolor; + end; + if int1 < 2 then begin + colored[1]:= defaultfadecolor1; + end; + end; + int1:= 0; + for int2 := 0 to high(ar1) do begin + if ar1[int2] = high(ar1) then begin + int1:= int2 + 1; //grid row + break; + end; + end; + grid.beginupdate; + grid.onrowsinserted:= nil; + grid.insertrow(int1); + grid.onrowsinserted:= {$ifdef FPC}@{$endif}rowinsertev; + rect1:= posedit.innerclientrect; + if rect1.cx = 0 then begin + rea1:= 0; + end + else begin + rea1:= (posx - rect1.x) / rect1.cx; + end; + if rea1 < posed[int1-1] then begin + rea1:= posed[int1-1]; + end; + if rea1 > posed[int1+1] then begin + rea1:= posed[int1+1]; + end; + posed[int1]:= rea1; + rea2:= posed[int1+1] - posed[int1-1]; + if rea2 = 0 then begin + rea3:= 0; + end + else begin + rea3:= (rea1 - posed[int1-1]) / rea2; + end; + grid.row:= int1; + grid.focuscell(makegridcoord(1,int1)); + colored[int1]:= blendcolor(rea3,colored[int1-1],colored[int1+1]); + if opaed <> nil then begin + opaed[int1]:= blendcolor(rea3,opaed[int1-1],opaed[int1+1]); + end; + grid.endupdate; + change; + grid.setfocus; + end; + end; +end; + +procedure tfadeeditfo.createev(const sender: TObject); +var + rect1: rectty; +begin + rect1:= posedit.innerclientrect; + with fnodeinfo do begin + grid:= self.grid; + posed:= self.posed; + colored:= self.colored; + opaed:= self.opaed; + setlength(marker,3); + marker[0].y:= rect1.y + rect1.cy - 1; + marker[1].y:= marker[0].y - markerheight; + marker[2].y:= marker[0].y; + end; + with fnodeinfoopa do begin + grid:= self.opagrid; + posed:= self.opaposed; + colored:= self.opacolored; + opaed:= nil; + marker:= copy(fnodeinfo.marker); + end; +end; + +procedure tfadeeditfo.movemarker(const atag: integer; apos: integer); +begin + if reverse.value then begin + apos:= posedit.paintsize.cx - apos; + end; + with nodeinfo(atag)^ do begin + marker[0].x:= apos - markerhalfwidth; + marker[1].x:= apos; + marker[2].x:= apos + markerhalfwidth; + end; +end; + +procedure tfadeeditfo.change; +var + rect1: rectty; + + procedure update(var anodeinfo: nodeinfoty); + var + int1: integer; + begin + with anodeinfo do begin + if grid.rowcount < 3 then begin + nodepos:= nil; + end + else begin + setlength(nodepos,grid.rowcount - 2); + end; + if grid.rowcount > 0 then begin + posed[grid.rowhigh]:= 1; + posed[0]:= 0; + end; + for int1:= 1 to grid.rowcount - 2 do begin + nodepos[int1-1]:= rect1.x + round(posed[int1] * rect1.cx); + end; + end; + end;//update + +var + int1: integer; +// rea1: real; +begin + if reverse.value then begin + fadedisp.face.fade_direction:= gd_left; + opadisp.face.fade_direction:= gd_left; + fadevert.face.fade_direction:= gd_up; + end + else begin + fadedisp.face.fade_direction:= gd_right; + opadisp.face.fade_direction:= gd_right; + fadevert.face.fade_direction:= gd_down; + end; + rect1:= posedit.innerclientrect; + with fadedisp.face do begin + fade_pos.count:= grid.rowcount; + if grid.datacols[3].visible then begin + fade_opapos.count:= grid.rowcount; + for int1:= grid.rowhigh downto 0 do begin + fade_pos[int1]:= posed[int1]; + fade_color[int1]:= colored[int1]; + fade_opapos[int1]:= posed[int1]; + fade_opacolor[int1]:= opaed[int1]; + end; + end + else begin + for int1:= grid.rowhigh downto 0 do begin + fade_pos[int1]:= posed[int1]; + fade_color[int1]:= colored[int1]; + end; + if fopacitycleared then begin + fade_opapos.count:= 0; + opagrid.clear; + end + else begin + fade_opapos.count:= opagrid.rowcount; + for int1:= opagrid.rowhigh downto 0 do begin + fade_opapos[int1]:= opaposed[int1]; + fade_opacolor[int1]:= opacolored[int1]; + end; + end; + end; + fadevert.face.fade_pos.assign(fade_pos); + fadevert.face.fade_color.assign(fade_color); + fadevert.face.fade_opapos.assign(fade_opapos); + fadevert.face.fade_opacolor.assign(fade_opacolor); + opadisp.face.fade_pos.assign(fade_opapos); + opadisp.face.fade_color.assign(fade_opacolor); + end; + update(fnodeinfo); + update(fnodeinfoopa); + posedit.invalidate; + opaedit.invalidate; +end; + +procedure tfadeeditfo.pospaintev(const sender: twidget; const canvas: tcanvas); +var + int1: integer; +begin + with nodeinfo(sender.tag)^ do begin + for int1:= 0 to high(nodepos) do begin + movemarker(sender.tag,nodepos[int1]); + if int1 + 1 = grid.row then begin + canvas.drawlines(marker,true,cl_red); + end + else begin + canvas.drawlines(marker,true,cl_black); + end; + end; + end; +end; + +procedure tfadeeditfo.getcursorshapeev(const sender: tcustompickwidget; + const picker: tobjectpicker; + var shape: cursorshapety; var found: Boolean); +var +// rect1: rectty; + int1{,int2,int3}: integer; +begin +// if picker.shiftstate = [] then begin + int1:= findmarker(sender.tag,picker.pos); + if int1 >= 0 then begin + shape:= cr_sizehor; + found:= true; + end; +// end; +end; + +procedure tfadeeditfo.getpickobjectev(const sender: tcustompickwidget; + const picker: tobjectpicker; var objects: integerarty); +var + int1: integer; +begin + if picker.shiftstate = [ss_left] then begin + int1:= findmarker(sender.tag,picker.pickrect.pos); + if int1 >= 0 then begin + setlength(objects,1); + objects[0]:= int1; + end; + end; +end; + +function tfadeeditfo.findmarker(const atag: integer; + const apos: pointty): integer; +var + rect1: rectty; + int1,int2,int3,int4: integer; + xpos: integer; +begin + with nodeinfo(atag)^ do begin + result:= -1; + rect1:= posedit.innerclientrect; + int1:= rect1.y + rect1.cy; + int4:= high(nodepos); + if reverse.value then begin + xpos:= posedit.paintsize.cx - apos.x; + end + else begin + xpos:= apos.x; + end; + if (apos.y < int1) and (apos.y >= int1 - markerheight) then begin + int2:= xpos - markerhalfwidth; + int3:= int2 + 2 * markerhalfwidth + 1; + for int1:= 0 to int4 do begin + if (nodepos[int1] >= int2) and (nodepos[int1] <= int3) and + not ((int1 < int4) and (nodepos[int1+1] = rect1.x)) then begin + result:= int1; + break; + end; + end; + end; + end; +end; + +function tfadeeditfo.limitmarkerpos(const atag: integer; const index: integer; + const aoffset: integer): integer; +var + rect1: rectty; + +begin + with nodeinfo(atag)^ do begin + if reverse.value then begin + result:= nodepos[index] - aoffset; + end + else begin + result:= nodepos[index] + aoffset; + end; + if (index > 0) and (result < nodepos[index-1]) then begin + result:= nodepos[index-1]; + end + else begin + if index < high(nodepos) then begin + if result >= nodepos[index+1] then begin + result:= nodepos[index+1]; + end + else begin + if result < 0 then begin + result:= 0; + end; + end; + end + else begin + rect1:= posedit.innerclientrect; + rect1.x:= rect1.x + rect1.cx; + if result >= rect1.x then begin + result:= rect1.x - 1; + end; + end; + end; + end; +end; + +procedure tfadeeditfo.paintxorev(const sender: tcustompickwidget; + const picker: tobjectpicker; + const canvas: tcanvas); +begin + movemarker(sender.tag,limitmarkerpos(sender.tag,picker.currentobjects[0], + picker.pickoffset.x)); + with nodeinfo(sender.tag)^ do begin + canvas.drawlines(marker,true,cl_white); + canvas.drawline(makepoint(marker[1].x,marker[1].y-1), + makepoint(marker[1].x,posedit.innerclientpos.y),cl_white); + end; +end; + +procedure tfadeeditfo.endpickev(const sender: tcustompickwidget; + const picker: tobjectpicker); +var + int1: integer; + rect1: rectty; + rea1: real; + offsetx: integer; +begin + offsetx:= picker.pickoffset.x; + if reverse.value then begin + offsetx:= -offsetx; + end; + rect1:= sender.innerclientrect; + int1:= picker.currentobjects[0]; + with nodeinfo(sender.tag)^ do begin + if rect1.cx = 0 then begin + rea1:= 0; + end + else begin + rea1:= (nodepos[int1] - rect1.x + offsetx) / rect1.cx; + end; + if rea1 < posed[int1] then begin + rea1:= posed[int1]; + end; + if rea1 > posed[int1+2] then begin + rea1:= posed[int1+2]; + end; + posed[int1+1]:= rea1; + grid.focuscell(makegridcoord(1,int1+1)); + grid.setfocus; + end; + change; +end; + +procedure tfadeeditfo.resizeev(const sender: TObject); +begin + change; +end; + +procedure tfadeeditfo.dataenteterev(const sender: TObject); +begin + grid.sort; + opagrid.sort; + change; +end; + +procedure tfadeeditfo.rowdeleteev(const sender: tcustomgrid; const aindex: Integer; + const acount: Integer); +begin + if grid.rowcount > 0 then begin + posed[grid.rowhigh]:= 1; + posed[0]:= 0; + end; + change; +end; + +procedure tfadeeditfo.gridcellev(const sender: TObject; + var info: celleventinfoty); +begin + with info do begin + if (eventkind = cek_enter) and (newcell.row <> cellbefore.row) then begin + if tmsecomponent(sender).tag = 0 then begin + posedit.invalidate; //redraw red marker + end + else begin + opaedit.invalidate; //redraw red marker + end; + end; + end; +end; + +procedure tfadeeditfo.rowinsertev(const sender: tcustomgrid; + const aindex: Integer; const acount: Integer); +begin + if sender.userinput then begin + with nodeinfo(sender.tag)^ do begin + grid.beginupdate; + if aindex < grid.rowhigh then begin + if aindex = 0 then begin + colored[0]:= colored[1]; //pos = 0 + if sender.tag = 0 then begin + opaed[0]:= opaed[1]; //pos = 0 + end; + posed[0]:= 0; + end + else begin + colored[aindex]:= blendcolor(0.5,colored[aindex+1],colored[aindex-1]); + if sender.tag = 0 then begin + opaed[aindex]:= blendcolor(0.5,opaed[aindex+1],opaed[aindex-1]); + end; + posed[aindex]:= (posed[aindex+1] + posed[aindex-1]) / 2; + end + end + else begin + if grid.rowhigh = 0 then begin + posed[aindex]:= 0; + end + else begin + colored[aindex]:= colored[grid.rowhigh-1]; + if sender.tag = 0 then begin + opaed[aindex]:= opaed[grid.rowhigh-1]; + end; + posed[aindex]:= 1; + end; + end; + grid.endupdate; + end; + change; + end + else begin + asyncevent; + end; +end; + +procedure tfadeeditfo.beforedrawev(const sender: tcol; const canvas: tcanvas; + var cellinfo: cellinfoty; var processed: Boolean); +begin + if sender.grid.tag = 0 then begin + cellinfo.color:= colorty(colortorgb(colored[cellinfo.cell.row])); + end + else begin + cellinfo.color:= colorty(colortorgb(opacolored[cellinfo.cell.row])); + end; +end; + +procedure tfadeeditfo.reverseenteredev(const sender: TObject); +begin + change; +end; + +procedure tfadeeditfo.saveex(const sender: TObject); +begin + if filedialog.execute(fdk_save) = mr_ok then begin + fadestatfile.writestat(filedialog.controller.filename); + end; +end; + +procedure tfadeeditfo.loadex(const sender: TObject); +begin + if filedialog.execute(fdk_open) = mr_ok then begin + fadestatfile.readstat(filedialog.controller.filename); + change; + end; +end; + +procedure tfadeeditfo.doasyncevent(var atag: integer); +begin + inherited; + change; +end; + +function tfadeeditfo.syncexe: boolean; + + function scale(const apos,lopos,hipos: real; + const locolor,hicolor: colorty): colorty; + begin + if apos = lopos then begin + result:= locolor; + end + else begin + if apos = hipos then begin + result:= hicolor; + end + else begin + if lopos = hipos then begin + if locolor = hicolor then begin + result:= locolor; + end + else begin + result:= blendcolor(0.5,locolor,hicolor); + end; + end + else begin + result:= blendcolor((apos-lopos)/(hipos-lopos),locolor,hicolor); + end; + end; + end; + end; //scale + +var + int1,int2: integer; +begin + result:= askconfirmation(c[ord(sc_syncopa)]+lineend+c[ord(sc_withcolor)]); + if result then begin + grid.beginupdate; + try + fopacitycleared:= false; + int2:= 0; + if grid.rowcount < fadedisp.face.fade_opapos.count then begin + if grid.rowcount = 0 then begin + grid.rowcount:= 1; + posed[0]:= 0; + end; + if (grid.rowcount < 2) and (grid.rowcount < fadedisp.face.fade_opapos.count) then begin + grid.rowcount:= 2; + posed[1]:= 1; + colored[1]:= colored[0]; + end; + end; + for int1:= 1 to fadedisp.face.fade_opapos.count-2 do begin + while posed[int2] < fadedisp.face.fade_opapos[int1] do begin + inc(int2); + end; + if posed[int2] <> fadedisp.face.fade_opapos[int1] then begin + grid.insertrow(int2); + posed[int2]:= fadedisp.face.fade_opapos[int1]; + colored[int2]:= scale(posed[int2],posed[int2-1],posed[int2+1], + colored[int2-1],colored[int2+1]); + end; + end; + int2:= 0; + for int1:= 0 to grid.rowhigh do begin + while (int2 < fadedisp.face.fade_opapos.count) and + (fadedisp.face.fade_opapos[int2] < posed[int1]) do begin + inc(int2); + end; + case fadedisp.face.fade_opapos.count of + 0: begin + opaed[int1]:= cl_white; + end; + 1: begin + opaed[int1]:= fadedisp.face.fade_opacolor[0]; + end; + else begin + if int2 >= fadedisp.face.fade_opacolor.count then begin + opaed[int1]:= + fadedisp.face.fade_opacolor[fadedisp.face.fade_opacolor.count-1]; + end + else begin + if int2 = 0 then begin + opaed[int1]:= + fadedisp.face.fade_opacolor[0]; + end + else begin + opaed[int1]:= scale(posed[int1],fadedisp.face.fade_opapos[int2-1], + fadedisp.face.fade_opapos[int2], + fadedisp.face.fade_opacolor[int2-1], + fadedisp.face.fade_opacolor[int2]); + end; + end; + end; + end; + end; + grid.datacols[3].visible:= true; + finally + grid.endupdate; + end; +// syncbu.enabled:= false; + clearbu.enabled:= true; + change; + end; +end; + +procedure tfadeeditfo.clearopaexe(const sender: TObject); +begin + if askconfirmation(c[ord(sc_removeopacity)]) then begin + fopacitycleared:= true; + opasynced:= true; + grid.datacols[3].visible:= false; + change; + clearbu.enabled:= false; +// syncbu.enabled:= true; + end; +end; + +procedure tfadeeditfo.setopasynced(const avalue: boolean); +var + bo1: boolean; + int1: integer; +begin + fopasynced:= avalue or fopa; + grid.datacols[3].visible:= fopasynced; + bo1:= not fopasynced; + opaedit.visible:= bo1; + opagrid.visible:= bo1; + splitter.visible:= bo1; + if fopasynced then begin + splitter.linktop:= nil; + grid.height:= gridlayout.height; + cont1.top:= 4; + end + else begin + fopacitycleared:= false; + cont1.top:= opaedit.bottom+4; + splitter.linktop:= grid; + opagrid.rowcount:= fadedisp.face.fade_opapos.count; + for int1:= 0 to opagrid.rowhigh do begin + opaposed[int1]:= fadedisp.face.fade_opapos[int1]; + opacolored[int1]:= fadedisp.face.fade_opacolor[int1]; + end; + end; + cont1.bottom:= cont2.height; + grid.fixrows[-1].visible:= fopasynced; + splitopa.value:= not fopasynced; +end; + +procedure tfadeeditfo.fadestatupdateexe(const sender: TObject; + const filer: tstatfiler); +var + bo1: boolean; +begin + bo1:= opasynced; + if not filer.iswriter or fopa then begin + bo1:= false; + end; + filer.updatevalue('opasynced',bo1); + opasynced:= bo1; +end; + +procedure tfadeeditfo.sepopaset(const sender: TObject; var avalue: Boolean; + var accept: Boolean); +begin + if (avalue = opasynced) and not avalue then begin + accept:= syncexe; + end; + if accept then begin + opasynced:= not avalue; + if avalue then begin + change; + end; + end; +end; + +function tfadeeditfo.nodeinfo(const atag: integer): pnodeinfoty; +begin + if atag = 0 then begin + result:= @fnodeinfo; + end + else begin + result:= @fnodeinfoopa; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/msefadeedit_mfm.pas b/mseide-msegui/lib/common/designutils/msefadeedit_mfm.pas new file mode 100644 index 0000000..d39ae0f --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msefadeedit_mfm.pas @@ -0,0 +1,657 @@ +unit msefadeedit_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msefadeedit; + +const + objdata: record size: integer; data: array[0..12789] of byte end = + (size: 12790; data: ( + 84,80,70,48,11,116,102,97,100,101,101,100,105,116,102,111,10,102,97,100, + 101,101,100,105,116,102,111,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,13,111,119,95,97,114,114,111,119,102,111,99,117,115,11,111,119,95, + 115,117,98,102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,9,111,119,95,104,105,110,116,111,110,0,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,150,0,8,98, + 111,117,110,100,115,95,121,3,221,0,9,98,111,117,110,100,115,95,99,120, + 3,7,2,9,98,111,117,110,100,115,95,99,121,3,187,1,23,99,111,110, + 116,97,105,110,101,114,46,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,11,111,119,95,115,117,98,102,111,99,117,115,19,111,119,95,109,111,117, + 115,101,116,114,97,110,115,112,97,114,101,110,116,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,26,99,111,110,116,97,105,110, + 101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 0,27,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,16,99,111,110,116,97,105,110,101, + 114,46,98,111,117,110,100,115,1,2,0,2,0,3,7,2,3,187,1,0, + 7,111,112,116,105,111,110,115,11,13,102,111,95,99,108,111,115,101,111,110, + 101,115,99,15,102,111,95,97,117,116,111,114,101,97,100,115,116,97,116,16, + 102,111,95,97,117,116,111,119,114,105,116,101,115,116,97,116,10,102,111,95, + 115,97,118,101,112,111,115,12,102,111,95,115,97,118,101,115,116,97,116,101, + 0,8,115,116,97,116,102,105,108,101,7,12,102,111,114,109,115,116,97,116, + 102,105,108,101,7,99,97,112,116,105,111,110,6,9,70,97,100,101,32,69, + 100,105,116,13,119,105,110,100,111,119,111,112,97,99,105,116,121,5,0,0, + 0,0,0,0,0,128,255,255,8,111,110,99,114,101,97,116,101,7,8,99, + 114,101,97,116,101,101,118,15,109,111,100,117,108,101,99,108,97,115,115,110, + 97,109,101,6,8,116,109,115,101,102,111,114,109,0,13,116,115,105,109,112, + 108,101,119,105,100,103,101,116,5,99,111,110,116,50,7,118,105,115,105,98, + 108,101,9,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,7,2,9,98, + 111,117,110,100,115,95,99,121,3,146,1,7,97,110,99,104,111,114,115,11, + 6,97,110,95,116,111,112,9,97,110,95,98,111,116,116,111,109,0,0,13, + 116,115,105,109,112,108,101,119,105,100,103,101,116,5,99,111,110,116,49,7, + 118,105,115,105,98,108,101,9,8,98,111,117,110,100,115,95,120,2,0,8, + 98,111,117,110,100,115,95,121,2,73,9,98,111,117,110,100,115,95,99,120, + 3,7,2,9,98,111,117,110,100,115,95,99,121,3,74,1,7,97,110,99, + 104,111,114,115,11,6,97,110,95,116,111,112,9,97,110,95,98,111,116,116, + 111,109,0,0,13,116,115,105,109,112,108,101,119,105,100,103,101,116,14,116, + 115,105,109,112,108,101,119,105,100,103,101,116,55,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,19,111,119,95,109,111,117,115,101,116,114,97, + 110,115,112,97,114,101,110,116,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,0,5,99,111,108,111,114,4,5,0,0,160,19,102, + 97,99,101,46,102,97,100,101,95,100,105,114,101,99,116,105,111,110,7,7, + 103,100,95,100,111,119,110,15,102,97,99,101,46,108,111,99,97,108,112,114, + 111,112,115,11,15,102,97,108,95,102,97,100,105,114,101,99,116,105,111,110, + 0,8,116,97,98,111,114,100,101,114,2,5,7,118,105,115,105,98,108,101, + 9,8,98,111,117,110,100,115,95,120,3,188,1,8,98,111,117,110,100,115, + 95,121,2,56,9,98,111,117,110,100,115,95,99,120,2,66,9,98,111,117, + 110,100,115,95,99,121,3,17,1,7,97,110,99,104,111,114,115,11,6,97, + 110,95,116,111,112,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111, + 116,116,111,109,0,0,0,9,116,108,97,121,111,117,116,101,114,10,103,114, + 105,100,108,97,121,111,117,116,8,98,111,117,110,100,115,95,120,2,8,8, + 98,111,117,110,100,115,95,121,2,56,9,98,111,117,110,100,115,95,99,120, + 3,175,1,9,98,111,117,110,100,115,95,99,121,3,18,1,12,98,111,117, + 110,100,115,95,99,121,109,105,110,2,90,7,97,110,99,104,111,114,115,11, + 7,97,110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114, + 105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,0,11,116,119,105, + 100,103,101,116,103,114,105,100,7,111,112,97,103,114,105,100,3,84,97,103, + 2,1,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,7,79,112, + 97,99,105,116,121,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109, + 101,1,2,0,2,17,2,0,2,0,0,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,3,147,0,9,98,111,117,110,100, + 115,95,99,120,3,177,1,9,98,111,117,110,100,115,95,99,121,2,126,7, + 97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,8,97,110,95, + 114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,11,111,112,116, + 105,111,110,115,103,114,105,100,11,12,111,103,95,99,111,108,115,105,122,105, + 110,103,15,111,103,95,114,111,119,105,110,115,101,114,116,105,110,103,14,111, + 103,95,114,111,119,100,101,108,101,116,105,110,103,19,111,103,95,102,111,99, + 117,115,99,101,108,108,111,110,101,110,116,101,114,13,111,103,95,97,117,116, + 111,97,112,112,101,110,100,9,111,103,95,115,111,114,116,101,100,20,111,103, + 95,99,111,108,99,104,97,110,103,101,111,110,116,97,98,107,101,121,10,111, + 103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112, + 117,112,17,111,103,95,109,111,117,115,101,115,99,114,111,108,108,99,111,108, + 0,13,102,105,120,99,111,108,115,46,99,111,117,110,116,2,1,13,102,105, + 120,99,111,108,115,46,105,116,101,109,115,14,1,5,119,105,100,116,104,2, + 22,7,110,117,109,115,116,101,112,2,1,0,0,14,100,97,116,97,99,111, + 108,115,46,99,111,117,110,116,2,3,16,100,97,116,97,99,111,108,115,46, + 111,112,116,105,111,110,115,11,14,99,111,95,102,111,99,117,115,115,101,108, + 101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99, + 111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105, + 115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12, + 99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99, + 111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109, + 111,117,115,101,115,99,114,111,108,108,114,111,119,0,14,100,97,116,97,99, + 111,108,115,46,105,116,101,109,115,14,1,11,99,111,108,111,114,115,101,108, + 101,99,116,4,6,0,0,128,5,119,105,100,116,104,2,24,16,111,110,98, + 101,102,111,114,101,100,114,97,119,99,101,108,108,7,12,98,101,102,111,114, + 101,100,114,97,119,101,118,7,111,112,116,105,111,110,115,11,10,99,111,95, + 110,111,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101, + 99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111, + 95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115, + 101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99, + 111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109,111,117,115,101, + 115,99,114,111,108,108,114,111,119,0,0,7,8,111,112,97,112,111,115,101, + 100,1,5,119,105,100,116,104,2,89,7,111,112,116,105,111,110,115,11,14, + 99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111, + 117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101, + 99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111, + 95,114,111,119,115,101,108,101,99,116,15,99,111,95,112,114,111,112,111,114, + 116,105,111,110,97,108,12,99,111,95,115,97,118,101,118,97,108,117,101,12, + 99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99, + 111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109, + 111,117,115,101,115,99,114,111,108,108,114,111,119,0,4,110,97,109,101,6, + 6,111,112,97,112,111,115,10,119,105,100,103,101,116,110,97,109,101,6,8, + 111,112,97,112,111,115,101,100,9,100,97,116,97,99,108,97,115,115,7,17, + 116,103,114,105,100,114,101,97,108,100,97,116,97,108,105,115,116,0,7,10, + 111,112,97,99,111,108,111,114,101,100,1,5,119,105,100,116,104,3,34,1, + 7,111,112,116,105,111,110,115,11,14,99,111,95,102,111,99,117,115,115,101, + 108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12, + 99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116, + 105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116, + 7,99,111,95,102,105,108,108,12,99,111,95,115,97,118,101,118,97,108,117, + 101,12,99,111,95,115,97,118,101,115,116,97,116,101,9,99,111,95,110,111, + 115,111,114,116,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99, + 97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111, + 108,108,114,111,119,0,8,119,105,100,116,104,109,105,110,2,63,4,110,97, + 109,101,6,8,111,112,97,99,111,108,111,114,10,119,105,100,103,101,116,110, + 97,109,101,6,10,111,112,97,99,111,108,111,114,101,100,9,100,97,116,97, + 99,108,97,115,115,7,17,116,103,114,105,100,101,110,117,109,100,97,116,97, + 108,105,115,116,0,0,13,100,97,116,97,114,111,119,104,101,105,103,104,116, + 2,16,8,115,116,97,116,102,105,108,101,7,12,102,97,100,101,115,116,97, + 116,102,105,108,101,14,111,110,114,111,119,115,105,110,115,101,114,116,101,100, + 7,11,114,111,119,105,110,115,101,114,116,101,118,13,111,110,114,111,119,115, + 100,101,108,101,116,101,100,7,11,114,111,119,100,101,108,101,116,101,101,118, + 11,111,110,99,101,108,108,101,118,101,110,116,7,10,103,114,105,100,99,101, + 108,108,101,118,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,9,116,114,101,97,108,101,100,105,116,8,111,112,97,112,111,115,101,100, + 14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49, + 95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,11,111,112, + 116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101, + 98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101, + 118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108, + 105,101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,10,102, + 114,108,95,108,101,118,101,108,105,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,1,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,25,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,89, + 9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115, + 101,100,105,116,49,11,13,111,101,49,95,115,97,118,101,118,97,108,117,101, + 0,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,13,100,97,116, + 97,101,110,116,101,116,101,114,101,118,5,118,97,108,117,101,5,0,0,0, + 0,0,0,0,128,255,255,12,118,97,108,117,101,100,101,102,97,117,108,116, + 5,0,0,0,0,0,0,0,128,255,255,10,102,111,114,109,97,116,101,100, + 105,116,6,5,48,46,48,48,48,10,102,111,114,109,97,116,100,105,115,112, + 6,5,48,46,48,48,48,10,118,97,108,117,101,114,97,110,103,101,2,1, + 10,118,97,108,117,101,115,116,97,114,116,2,0,8,118,97,108,117,101,109, + 105,110,2,0,8,118,97,108,117,101,109,97,120,2,1,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,10,116,99,111,108,111,114, + 101,100,105,116,10,111,112,97,99,111,108,111,114,101,100,11,111,112,116,105, + 111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117, + 116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101,118,101, + 108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101, + 110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,10,102,114,108, + 95,108,101,118,101,108,105,15,102,114,108,95,99,111,108,111,114,99,108,105, + 101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111, + 108,111,114,4,5,0,0,144,19,102,114,97,109,101,46,98,117,116,116,111, + 110,115,46,99,111,117,110,116,2,2,19,102,114,97,109,101,46,98,117,116, + 116,111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4,5, + 0,0,144,0,1,5,99,111,108,111,114,4,5,0,0,144,7,105,109,97, + 103,101,110,114,2,17,0,0,25,102,114,97,109,101,46,98,117,116,116,111, + 110,101,108,108,105,112,115,101,46,99,111,108,111,114,4,5,0,0,144,27, + 102,114,97,109,101,46,98,117,116,116,111,110,101,108,108,105,112,115,101,46, + 105,109,97,103,101,110,114,2,17,8,116,97,98,111,114,100,101,114,2,2, + 7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,115, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,3,34,1,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116, + 105,111,110,115,101,100,105,116,49,11,13,111,101,49,95,115,97,118,101,118, + 97,108,117,101,14,111,101,49,95,116,104,117,109,98,116,114,97,99,107,0, + 13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,13,100,97,116,97, + 101,110,116,101,116,101,114,101,118,12,118,97,108,117,101,100,101,102,97,117, + 108,116,4,5,0,0,160,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,0,0,11,116,119,105,100,103,101,116,103,114,105,100,4,103, + 114,105,100,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115, + 95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,120,3,177,1,9,98,111,117,110,100,115,95,99,121,3,144, + 0,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97, + 110,95,116,111,112,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111, + 116,116,111,109,0,11,111,112,116,105,111,110,115,103,114,105,100,11,12,111, + 103,95,99,111,108,115,105,122,105,110,103,15,111,103,95,114,111,119,105,110, + 115,101,114,116,105,110,103,14,111,103,95,114,111,119,100,101,108,101,116,105, + 110,103,19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116, + 101,114,13,111,103,95,97,117,116,111,97,112,112,101,110,100,9,111,103,95, + 115,111,114,116,101,100,20,111,103,95,99,111,108,99,104,97,110,103,101,111, + 110,116,97,98,107,101,121,10,111,103,95,119,114,97,112,99,111,108,12,111, + 103,95,97,117,116,111,112,111,112,117,112,17,111,103,95,109,111,117,115,101, + 115,99,114,111,108,108,99,111,108,0,13,102,105,120,99,111,108,115,46,99, + 111,117,110,116,2,1,13,102,105,120,99,111,108,115,46,105,116,101,109,115, + 14,1,5,119,105,100,116,104,2,22,7,110,117,109,115,116,101,112,2,1, + 0,0,13,102,105,120,114,111,119,115,46,99,111,117,110,116,2,1,13,102, + 105,120,114,111,119,115,46,105,116,101,109,115,14,1,6,104,101,105,103,104, + 116,2,16,14,99,97,112,116,105,111,110,115,46,99,111,117,110,116,2,4, + 14,99,97,112,116,105,111,110,115,46,105,116,101,109,115,14,1,0,1,7, + 99,97,112,116,105,111,110,6,3,80,111,115,0,1,7,99,97,112,116,105, + 111,110,6,5,67,111,108,111,114,0,1,7,99,97,112,116,105,111,110,6, + 7,79,112,97,99,105,116,121,0,0,0,0,14,100,97,116,97,99,111,108, + 115,46,99,111,117,110,116,2,4,16,100,97,116,97,99,111,108,115,46,111, + 112,116,105,111,110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101, + 99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111, + 95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115, + 101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99, + 111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111, + 112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111, + 117,115,101,115,99,114,111,108,108,114,111,119,0,14,100,97,116,97,99,111, + 108,115,46,105,116,101,109,115,14,1,11,99,111,108,111,114,115,101,108,101, + 99,116,4,6,0,0,128,5,119,105,100,116,104,2,24,16,111,110,98,101, + 102,111,114,101,100,114,97,119,99,101,108,108,7,12,98,101,102,111,114,101, + 100,114,97,119,101,118,7,111,112,116,105,111,110,115,11,10,99,111,95,110, + 111,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99, + 116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95, + 107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101, + 108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111, + 95,115,97,118,101,115,116,97,116,101,17,99,111,95,109,111,117,115,101,115, + 99,114,111,108,108,114,111,119,0,0,7,5,112,111,115,101,100,1,5,119, + 105,100,116,104,2,89,7,111,112,116,105,111,110,115,11,14,99,111,95,102, + 111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115, + 101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99, + 111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119, + 115,101,108,101,99,116,15,99,111,95,112,114,111,112,111,114,116,105,111,110, + 97,108,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111,95,115, + 97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11, + 99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101, + 115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109, + 101,6,5,112,111,115,101,100,9,100,97,116,97,99,108,97,115,115,7,17, + 116,103,114,105,100,114,101,97,108,100,97,116,97,108,105,115,116,0,7,7, + 99,111,108,111,114,101,100,1,5,119,105,100,116,104,3,151,0,7,111,112, + 116,105,111,110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99, + 116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95, + 107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101, + 108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,7,99,111, + 95,102,105,108,108,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99, + 111,95,115,97,118,101,115,116,97,116,101,9,99,111,95,110,111,115,111,114, + 116,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112, + 97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114, + 111,119,0,8,119,105,100,116,104,109,105,110,2,63,10,119,105,100,103,101, + 116,110,97,109,101,6,7,99,111,108,111,114,101,100,9,100,97,116,97,99, + 108,97,115,115,7,17,116,103,114,105,100,101,110,117,109,100,97,116,97,108, + 105,115,116,0,7,5,111,112,97,101,100,1,5,119,105,100,116,104,3,138, + 0,7,111,112,116,105,111,110,115,11,12,99,111,95,105,110,118,105,115,105, + 98,108,101,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99, + 111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121, + 115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99, + 116,12,99,111,95,114,111,119,115,101,108,101,99,116,15,99,111,95,112,114, + 111,112,111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,118,97, + 108,117,101,12,99,111,95,115,97,118,101,115,116,97,116,101,9,99,111,95, + 110,111,115,111,114,116,10,99,111,95,99,97,110,99,111,112,121,11,99,111, + 95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99, + 114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6, + 5,111,112,97,101,100,9,100,97,116,97,99,108,97,115,115,7,17,116,103, + 114,105,100,101,110,117,109,100,97,116,97,108,105,115,116,0,0,13,100,97, + 116,97,114,111,119,104,101,105,103,104,116,2,16,8,115,116,97,116,102,105, + 108,101,7,12,102,97,100,101,115,116,97,116,102,105,108,101,14,111,110,114, + 111,119,115,105,110,115,101,114,116,101,100,7,11,114,111,119,105,110,115,101, + 114,116,101,118,13,111,110,114,111,119,115,100,101,108,101,116,101,100,7,11, + 114,111,119,100,101,108,101,116,101,101,118,11,111,110,99,101,108,108,101,118, + 101,110,116,7,10,103,114,105,100,99,101,108,108,101,118,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,9,116,114,101,97,108,101,100, + 105,116,5,112,111,115,101,100,14,111,112,116,105,111,110,115,119,105,100,103, + 101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101, + 105,103,104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111, + 115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,12, + 102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101, + 46,99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95, + 108,101,118,101,108,111,10,102,114,108,95,108,101,118,101,108,105,15,102,114, + 108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114, + 100,101,114,2,1,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100, + 115,95,120,2,25,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,120,2,89,9,98,111,117,110,100,115,95,99,121,2,16, + 12,111,112,116,105,111,110,115,101,100,105,116,49,11,13,111,101,49,95,115, + 97,118,101,118,97,108,117,101,0,13,111,110,100,97,116,97,101,110,116,101, + 114,101,100,7,13,100,97,116,97,101,110,116,101,116,101,114,101,118,5,118, + 97,108,117,101,5,0,0,0,0,0,0,0,128,255,255,12,118,97,108,117, + 101,100,101,102,97,117,108,116,5,0,0,0,0,0,0,0,128,255,255,10, + 102,111,114,109,97,116,101,100,105,116,6,5,48,46,48,48,48,10,102,111, + 114,109,97,116,100,105,115,112,6,5,48,46,48,48,48,10,118,97,108,117, + 101,114,97,110,103,101,2,1,10,118,97,108,117,101,115,116,97,114,116,2, + 0,8,118,97,108,117,101,109,105,110,2,0,8,118,97,108,117,101,109,97, + 120,2,1,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0, + 0,10,116,99,111,108,111,114,101,100,105,116,7,99,111,108,111,114,101,100, + 11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114, + 97,109,101,98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101, + 46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111, + 114,99,108,105,101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,10,102,114,108,95,108,101,118,101,108,105,15,102,114,108,95,99,111,108, + 111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,18,102,114,97,109,101,46,98,117,116,116, + 111,110,46,99,111,108,111,114,4,5,0,0,144,19,102,114,97,109,101,46, + 98,117,116,116,111,110,115,46,99,111,117,110,116,2,2,19,102,114,97,109, + 101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111, + 108,111,114,4,5,0,0,144,0,1,5,99,111,108,111,114,4,5,0,0, + 144,7,105,109,97,103,101,110,114,2,17,0,0,25,102,114,97,109,101,46, + 98,117,116,116,111,110,101,108,108,105,112,115,101,46,99,111,108,111,114,4, + 5,0,0,144,27,102,114,97,109,101,46,98,117,116,116,111,110,101,108,108, + 105,112,115,101,46,105,109,97,103,101,110,114,2,17,8,116,97,98,111,114, + 100,101,114,2,2,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100, + 115,95,120,2,115,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,120,3,151,0,9,98,111,117,110,100,115,95,99,121,2, + 16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,13,111,101,49,95, + 115,97,118,101,118,97,108,117,101,14,111,101,49,95,116,104,117,109,98,116, + 114,97,99,107,0,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7, + 13,100,97,116,97,101,110,116,101,116,101,114,101,118,12,118,97,108,117,101, + 100,101,102,97,117,108,116,4,5,0,0,160,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,14,0,0,10,116,99,111,108,111,114,101,100,105, + 116,5,111,112,97,101,100,14,111,112,116,105,111,110,115,119,105,100,103,101, + 116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105, + 103,104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115, + 107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,10,102,114,108,95,108,101,118,101,108,105,15,102,114,108, + 95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,18,102,114,97,109,101,46, + 98,117,116,116,111,110,46,99,111,108,111,114,4,5,0,0,144,19,102,114, + 97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,2,19, + 102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14, + 1,5,99,111,108,111,114,4,5,0,0,144,0,1,5,99,111,108,111,114, + 4,5,0,0,144,7,105,109,97,103,101,110,114,2,17,0,0,25,102,114, + 97,109,101,46,98,117,116,116,111,110,101,108,108,105,112,115,101,46,99,111, + 108,111,114,4,5,0,0,144,27,102,114,97,109,101,46,98,117,116,116,111, + 110,101,108,108,105,112,115,101,46,105,109,97,103,101,110,114,2,17,8,116, + 97,98,111,114,100,101,114,2,3,7,118,105,115,105,98,108,101,8,8,98, + 111,117,110,100,115,95,120,3,11,1,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,3,138,0,9,98,111,117,110,100, + 115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11, + 13,111,101,49,95,115,97,118,101,118,97,108,117,101,14,111,101,49,95,116, + 104,117,109,98,116,114,97,99,107,0,13,111,110,100,97,116,97,101,110,116, + 101,114,101,100,7,13,100,97,116,97,101,110,116,101,116,101,114,101,118,12, + 118,97,108,117,101,100,101,102,97,117,108,116,4,6,0,0,160,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,9,116,115,112, + 108,105,116,116,101,114,8,115,112,108,105,116,116,101,114,5,99,111,108,111, + 114,4,3,0,0,144,8,116,97,98,111,114,100,101,114,2,2,8,98,111, + 117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,3,144,0, + 9,98,111,117,110,100,115,95,99,120,3,175,1,9,98,111,117,110,100,115, + 95,99,121,2,3,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111, + 112,0,7,111,112,116,105,111,110,115,11,9,115,112,111,95,118,109,111,118, + 101,9,115,112,111,95,118,112,114,111,112,12,115,112,111,95,100,111,99,107, + 108,101,102,116,11,115,112,111,95,100,111,99,107,116,111,112,13,115,112,111, + 95,100,111,99,107,114,105,103,104,116,14,115,112,111,95,100,111,99,107,98, + 111,116,116,111,109,0,7,108,105,110,107,116,111,112,7,4,103,114,105,100, + 10,108,105,110,107,98,111,116,116,111,109,7,7,111,112,97,103,114,105,100, + 8,115,116,97,116,102,105,108,101,7,12,102,111,114,109,115,116,97,116,102, + 105,108,101,0,0,0,11,116,112,105,99,107,119,105,100,103,101,116,7,112, + 111,115,101,100,105,116,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 12,102,114,97,109,101,46,108,101,118,101,108,105,2,255,19,102,114,97,109, + 101,46,102,114,97,109,101,105,95,98,111,116,116,111,109,2,2,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95, + 108,101,118,101,108,105,12,102,114,108,95,102,105,98,111,116,116,111,109,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 8,116,97,98,111,114,100,101,114,2,2,7,111,110,112,97,105,110,116,7, + 10,112,111,115,112,97,105,110,116,101,118,8,98,111,117,110,100,115,95,120, + 2,8,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,3,248,1,9,98,111,117,110,100,115,95,99,121,2,50,7,97, + 110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110,95,116, + 111,112,8,97,110,95,114,105,103,104,116,0,18,111,110,99,108,105,101,110, + 116,109,111,117,115,101,101,118,101,110,116,7,7,109,111,117,115,101,101,118, + 8,111,110,114,101,115,105,122,101,7,8,114,101,115,105,122,101,101,118,16, + 111,110,103,101,116,99,117,114,115,111,114,115,104,97,112,101,7,16,103,101, + 116,99,117,114,115,111,114,115,104,97,112,101,101,118,16,111,110,103,101,116, + 112,105,99,107,111,98,106,101,99,116,115,7,15,103,101,116,112,105,99,107, + 111,98,106,101,99,116,101,118,13,111,110,101,110,100,112,105,99,107,109,111, + 118,101,7,9,101,110,100,112,105,99,107,101,118,13,111,110,112,97,105,110, + 116,120,111,114,112,105,99,7,10,112,97,105,110,116,120,111,114,101,118,0, + 13,116,115,105,109,112,108,101,119,105,100,103,101,116,14,116,115,105,109,112, + 108,101,119,105,100,103,101,116,51,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111, + 119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102, + 111,99,117,115,19,111,119,95,109,111,117,115,101,116,114,97,110,115,112,97, + 114,101,110,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,0,5,99,111,108,111,114,4,5,0,0,160,15,102,97,99,101,46, + 108,111,99,97,108,112,114,111,112,115,11,0,8,116,97,98,111,114,100,101, + 114,2,3,7,118,105,115,105,98,108,101,9,8,98,111,117,110,100,115,95, + 120,2,1,8,98,111,117,110,100,115,95,121,2,1,9,98,111,117,110,100, + 115,95,99,120,3,246,1,9,98,111,117,110,100,115,95,99,121,2,40,7, + 97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,0,0,0,13,116, + 115,105,109,112,108,101,119,105,100,103,101,116,14,116,115,105,109,112,108,101, + 119,105,100,103,101,116,50,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,19,111,119,95,109,111,117,115,101,116,114,97,110,115,112,97,114,101, + 110,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 0,5,99,111,108,111,114,4,6,0,0,160,8,116,97,98,111,114,100,101, + 114,2,1,7,118,105,115,105,98,108,101,9,8,98,111,117,110,100,115,95, + 120,2,1,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100, + 115,95,99,120,3,246,1,9,98,111,117,110,100,115,95,99,121,2,13,7, + 97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,0,0,0,13,116, + 115,105,109,112,108,101,119,105,100,103,101,116,14,116,115,105,109,112,108,101, + 119,105,100,103,101,116,52,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,19,111,119,95,109,111,117,115,101,116,114,97,110,115,112,97,114,101, + 110,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 0,5,99,111,108,111,114,4,2,0,0,160,8,116,97,98,111,114,100,101, + 114,2,2,7,118,105,115,105,98,108,101,9,8,98,111,117,110,100,115,95, + 120,2,1,8,98,111,117,110,100,115,95,121,2,27,9,98,111,117,110,100, + 115,95,99,120,3,246,1,9,98,111,117,110,100,115,95,99,121,2,13,7, + 97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,0,0,0,13,116, + 115,105,109,112,108,101,119,105,100,103,101,116,8,102,97,100,101,100,105,115, + 112,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,19,111,119,95, + 109,111,117,115,101,116,114,97,110,115,112,97,114,101,110,116,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,5,99,111,108,111, + 114,4,3,0,0,128,15,102,97,99,101,46,108,111,99,97,108,112,114,111, + 112,115,11,0,7,118,105,115,105,98,108,101,9,8,98,111,117,110,100,115, + 95,120,2,1,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,120,3,246,1,9,98,111,117,110,100,115,95,99,121,2,40, + 7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,0,0,0,0, + 13,116,115,105,109,112,108,101,119,105,100,103,101,116,14,116,115,105,109,112, + 108,101,119,105,100,103,101,116,53,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,19,111,119,95,109,111,117,115,101,116,114,97,110,115,112,97, + 114,101,110,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,0,5,99,111,108,111,114,4,2,0,0,160,8,116,97,98,111,114, + 100,101,114,2,3,7,118,105,115,105,98,108,101,9,8,98,111,117,110,100, + 115,95,120,3,189,1,8,98,111,117,110,100,115,95,121,2,56,9,98,111, + 117,110,100,115,95,99,120,2,23,9,98,111,117,110,100,115,95,99,121,3, + 17,1,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,8,97, + 110,95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,0,0, + 13,116,115,105,109,112,108,101,119,105,100,103,101,116,14,116,115,105,109,112, + 108,101,119,105,100,103,101,116,54,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,19,111,119,95,109,111,117,115,101,116,114,97,110,115,112,97, + 114,101,110,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,0,5,99,111,108,111,114,4,6,0,0,160,8,116,97,98,111,114, + 100,101,114,2,4,7,118,105,115,105,98,108,101,9,8,98,111,117,110,100, + 115,95,120,3,233,1,8,98,111,117,110,100,115,95,121,2,56,9,98,111, + 117,110,100,115,95,99,120,2,22,9,98,111,117,110,100,115,95,99,121,3, + 17,1,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,8,97, + 110,95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,0,0, + 13,116,115,105,109,112,108,101,119,105,100,103,101,116,8,102,97,100,101,118, + 101,114,116,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,19,111, + 119,95,109,111,117,115,101,116,114,97,110,115,112,97,114,101,110,116,17,111, + 119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,5,99,111, + 108,111,114,4,3,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108, + 105,2,255,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,114,108,95,108,101,118,101,108,105,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,19,102,97,99,101,46,102, + 97,100,101,95,100,105,114,101,99,116,105,111,110,7,7,103,100,95,100,111, + 119,110,15,102,97,99,101,46,108,111,99,97,108,112,114,111,112,115,11,15, + 102,97,108,95,102,97,100,105,114,101,99,116,105,111,110,0,8,116,97,98, + 111,114,100,101,114,2,1,7,118,105,115,105,98,108,101,9,8,98,111,117, + 110,100,115,95,120,3,188,1,8,98,111,117,110,100,115,95,121,2,56,9, + 98,111,117,110,100,115,95,99,120,2,68,9,98,111,117,110,100,115,95,99, + 121,3,18,1,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112, + 8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0, + 0,0,0,11,116,112,105,99,107,119,105,100,103,101,116,7,111,112,97,101, + 100,105,116,3,84,97,103,2,1,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,0,13,102,114,97,109,101,46,111,112,116,105,111,110,115,11,10,99, + 102,111,95,102,105,120,116,111,112,0,12,102,114,97,109,101,46,108,101,118, + 101,108,105,2,255,19,102,114,97,109,101,46,102,114,97,109,101,105,95,98, + 111,116,116,111,109,2,2,13,102,114,97,109,101,46,99,97,112,116,105,111, + 110,6,7,79,112,97,99,105,116,121,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,105,12, + 102,114,108,95,102,105,98,111,116,116,111,109,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0, + 8,116,97,98,111,114,100,101,114,2,1,7,111,110,112,97,105,110,116,7, + 10,112,111,115,112,97,105,110,116,101,118,8,98,111,117,110,100,115,95,120, + 2,8,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,3,248,1,9,98,111,117,110,100,115,95,99,121,2,67,12,98, + 111,117,110,100,115,95,99,120,109,105,110,3,205,1,7,97,110,99,104,111, + 114,115,11,7,97,110,95,108,101,102,116,6,97,110,95,116,111,112,8,97, + 110,95,114,105,103,104,116,0,18,111,110,99,108,105,101,110,116,109,111,117, + 115,101,101,118,101,110,116,7,7,109,111,117,115,101,101,118,8,111,110,114, + 101,115,105,122,101,7,8,114,101,115,105,122,101,101,118,16,111,110,103,101, + 116,99,117,114,115,111,114,115,104,97,112,101,7,16,103,101,116,99,117,114, + 115,111,114,115,104,97,112,101,101,118,16,111,110,103,101,116,112,105,99,107, + 111,98,106,101,99,116,115,7,15,103,101,116,112,105,99,107,111,98,106,101, + 99,116,101,118,13,111,110,101,110,100,112,105,99,107,109,111,118,101,7,9, + 101,110,100,112,105,99,107,101,118,13,111,110,112,97,105,110,116,120,111,114, + 112,105,99,7,10,112,97,105,110,116,120,111,114,101,118,0,13,116,115,105, + 109,112,108,101,119,105,100,103,101,116,7,111,112,97,100,105,115,112,13,111, + 112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117, + 115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13, + 111,119,95,97,114,114,111,119,102,111,99,117,115,19,111,119,95,109,111,117, + 115,101,116,114,97,110,115,112,97,114,101,110,116,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,5,99,111,108,111,114,4,3, + 0,0,128,15,102,97,99,101,46,108,111,99,97,108,112,114,111,112,115,11, + 0,7,118,105,115,105,98,108,101,9,8,98,111,117,110,100,115,95,120,2, + 1,8,98,111,117,110,100,115,95,121,2,17,9,98,111,117,110,100,115,95, + 99,120,3,246,1,9,98,111,117,110,100,115,95,99,121,2,40,7,97,110, + 99,104,111,114,115,11,6,97,110,95,116,111,112,0,0,0,0,0,9,116, + 108,97,121,111,117,116,101,114,12,98,111,116,116,111,109,108,97,121,111,117, + 116,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95, + 120,2,8,8,98,111,117,110,100,115,95,121,3,151,1,9,98,111,117,110, + 100,115,95,99,120,3,248,1,9,98,111,117,110,100,115,95,99,121,2,31, + 7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,8,97,110, + 95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,12,111,112, + 116,105,111,110,115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97, + 110,100,121,11,111,115,99,95,115,104,114,105,110,107,121,17,111,115,99,95, + 101,120,112,97,110,100,115,104,114,105,110,107,120,17,111,115,99,95,101,120, + 112,97,110,100,115,104,114,105,110,107,121,0,13,111,112,116,105,111,110,115, + 108,97,121,111,117,116,11,10,108,97,111,95,112,108,97,99,101,120,10,108, + 97,111,95,97,108,105,103,110,121,0,10,97,108,105,103,110,95,103,108,117, + 101,7,10,119,97,109,95,99,101,110,116,101,114,13,112,108,97,99,101,95, + 109,105,110,100,105,115,116,2,5,7,108,105,110,107,116,111,112,7,5,99, + 111,110,116,50,8,100,105,115,116,95,116,111,112,2,5,7,111,112,116,105, + 111,110,115,11,15,115,112,97,111,95,103,108,117,101,98,111,116,116,111,109, + 0,0,9,116,108,97,121,111,117,116,101,114,12,115,119,105,116,99,104,108, + 97,121,111,117,116,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,142,0, + 9,98,111,117,110,100,115,95,99,121,2,30,12,111,112,116,105,111,110,115, + 115,99,97,108,101,11,11,111,115,99,95,101,120,112,97,110,100,120,11,111, + 115,99,95,115,104,114,105,110,107,120,11,111,115,99,95,101,120,112,97,110, + 100,121,11,111,115,99,95,115,104,114,105,110,107,121,0,13,111,112,116,105, + 111,110,115,108,97,121,111,117,116,11,10,108,97,111,95,112,108,97,99,101, + 120,10,108,97,111,95,97,108,105,103,110,121,0,10,97,108,105,103,110,95, + 103,108,117,101,7,10,119,97,109,95,99,101,110,116,101,114,13,112,108,97, + 99,101,95,109,105,110,100,105,115,116,2,5,0,12,116,98,111,111,108,101, + 97,110,101,100,105,116,8,115,112,108,105,116,111,112,97,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,16,83,101,112,97,114,97,116,101,10, + 79,112,97,99,105,116,121,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,8,2,61,2,9,0,8,98,111,117,110,100,115, + 95,120,2,68,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,120,2,74,9,98,111,117,110,100,115,95,99,121,2,30,10, + 111,110,115,101,116,118,97,108,117,101,7,9,115,101,112,111,112,97,115,101, + 116,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,7,114,101,118, + 101,114,115,101,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,8, + 38,114,101,118,101,114,115,101,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,1,2,50,2,2,0,8,116,97,98,111,114, + 100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,2,7,9,98,111,117,110,100,115,95,99,120,2,63,9, + 98,111,117,110,100,115,95,99,121,2,16,13,111,110,100,97,116,97,101,110, + 116,101,114,101,100,7,16,114,101,118,101,114,115,101,101,110,116,101,114,101, + 100,101,118,0,0,0,9,116,108,97,121,111,117,116,101,114,12,98,117,116, + 116,111,110,108,97,121,111,117,116,8,116,97,98,111,114,100,101,114,2,1, + 8,98,111,117,110,100,115,95,120,3,176,0,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,120,3,72,1,9,98,111,117, + 110,100,115,95,99,121,2,31,12,111,112,116,105,111,110,115,115,99,97,108, + 101,11,11,111,115,99,95,101,120,112,97,110,100,120,11,111,115,99,95,115, + 104,114,105,110,107,120,11,111,115,99,95,101,120,112,97,110,100,121,11,111, + 115,99,95,115,104,114,105,110,107,121,0,13,111,112,116,105,111,110,115,108, + 97,121,111,117,116,11,10,108,97,111,95,112,108,97,99,101,120,0,13,112, + 108,97,99,101,95,109,105,110,100,105,115,116,2,5,0,7,116,98,117,116, + 116,111,110,8,116,98,117,116,116,111,110,50,14,111,112,116,105,111,110,115, + 119,105,100,103,101,116,49,11,13,111,119,49,95,97,117,116,111,115,99,97, + 108,101,13,111,119,49,95,97,117,116,111,119,105,100,116,104,0,8,98,111, + 117,110,100,115,95,120,3,14,1,8,98,111,117,110,100,115,95,121,2,0, + 9,98,111,117,110,100,115,95,99,120,2,58,9,98,111,117,110,100,115,95, + 99,121,2,31,12,98,111,117,110,100,115,95,99,120,109,105,110,2,58,5, + 115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105, + 111,110,0,7,99,97,112,116,105,111,110,6,7,38,67,97,110,99,101,108, + 11,109,111,100,97,108,114,101,115,117,108,116,7,11,109,114,95,99,97,110, + 99,108,111,115,101,0,0,7,116,98,117,116,116,111,110,8,116,98,117,116, + 116,111,110,49,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11, + 13,111,119,49,95,97,117,116,111,115,99,97,108,101,13,111,119,49,95,97, + 117,116,111,119,105,100,116,104,0,8,116,97,98,111,114,100,101,114,2,1, + 8,98,111,117,110,100,115,95,120,3,207,0,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,120,2,58,9,98,111,117,110, + 100,115,95,99,121,2,31,12,98,111,117,110,100,115,95,99,120,109,105,110, + 2,58,5,115,116,97,116,101,11,10,97,115,95,100,101,102,97,117,108,116, + 15,97,115,95,108,111,99,97,108,100,101,102,97,117,108,116,15,97,115,95, + 108,111,99,97,108,99,97,112,116,105,111,110,0,7,99,97,112,116,105,111, + 110,6,3,38,79,75,11,109,111,100,97,108,114,101,115,117,108,116,7,5, + 109,114,95,111,107,0,0,13,116,115,105,109,112,108,101,119,105,100,103,101, + 116,14,116,115,105,109,112,108,101,119,105,100,103,101,116,49,8,116,97,98, + 111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,3,198,0,8, + 98,111,117,110,100,115,95,121,2,8,9,98,111,117,110,100,115,95,99,120, + 2,4,9,98,111,117,110,100,115,95,99,121,2,18,0,0,7,116,98,117, + 116,116,111,110,8,116,98,117,116,116,111,110,51,14,111,112,116,105,111,110, + 115,119,105,100,103,101,116,49,11,13,111,119,49,95,97,117,116,111,115,99, + 97,108,101,13,111,119,49,95,97,117,116,111,119,105,100,116,104,0,8,116, + 97,98,111,114,100,101,114,2,3,8,98,111,117,110,100,115,95,120,3,135, + 0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,2,58,9,98,111,117,110,100,115,95,99,121,2,31,12,98,111,117, + 110,100,115,95,99,120,109,105,110,2,58,5,115,116,97,116,101,11,15,97, + 115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111, + 99,97,108,111,110,101,120,101,99,117,116,101,0,7,99,97,112,116,105,111, + 110,6,5,38,83,97,118,101,9,111,110,101,120,101,99,117,116,101,7,6, + 115,97,118,101,101,120,0,0,7,116,98,117,116,116,111,110,8,116,98,117, + 116,116,111,110,52,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49, + 11,13,111,119,49,95,97,117,116,111,115,99,97,108,101,13,111,119,49,95, + 97,117,116,111,119,105,100,116,104,0,8,116,97,98,111,114,100,101,114,2, + 4,8,98,111,117,110,100,115,95,120,2,72,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,120,2,58,9,98,111,117,110, + 100,115,95,99,121,2,31,12,98,111,117,110,100,115,95,99,120,109,105,110, + 2,58,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97, + 112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99, + 117,116,101,0,7,99,97,112,116,105,111,110,6,5,38,76,111,97,100,9, + 111,110,101,120,101,99,117,116,101,7,6,108,111,97,100,101,120,0,0,7, + 116,98,117,116,116,111,110,7,99,108,101,97,114,98,117,14,111,112,116,105, + 111,110,115,119,105,100,103,101,116,49,11,13,111,119,49,95,97,117,116,111, + 115,99,97,108,101,13,111,119,49,95,97,117,116,111,119,105,100,116,104,0, + 8,116,97,98,111,114,100,101,114,2,5,4,104,105,110,116,6,22,67,108, + 101,97,114,32,111,112,97,99,105,116,121,32,103,114,97,100,105,101,110,116, + 8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121, + 2,0,9,98,111,117,110,100,115,95,99,120,2,67,9,98,111,117,110,100, + 115,95,99,121,2,31,12,98,111,117,110,100,115,95,99,120,109,105,110,2, + 58,5,115,116,97,116,101,11,11,97,115,95,100,105,115,97,98,108,101,100, + 16,97,115,95,108,111,99,97,108,100,105,115,97,98,108,101,100,15,97,115, + 95,108,111,99,97,108,99,97,112,116,105,111,110,12,97,115,95,108,111,99, + 97,108,104,105,110,116,17,97,115,95,108,111,99,97,108,111,110,101,120,101, + 99,117,116,101,0,7,99,97,112,116,105,111,110,6,8,67,108,101,97,114, + 79,112,97,9,111,110,101,120,101,99,117,116,101,7,11,99,108,101,97,114, + 111,112,97,101,120,101,0,0,0,0,9,116,115,116,97,116,102,105,108,101, + 12,102,111,114,109,115,116,97,116,102,105,108,101,8,102,105,108,101,110,97, + 109,101,6,14,102,97,100,101,101,100,105,116,111,114,46,115,116,97,7,111, + 112,116,105,111,110,115,11,10,115,102,111,95,109,101,109,111,114,121,17,115, + 102,111,95,97,99,116,105,118,97,116,111,114,114,101,97,100,18,115,102,111, + 95,97,99,116,105,118,97,116,111,114,119,114,105,116,101,0,4,108,101,102, + 116,2,96,3,116,111,112,3,200,0,0,0,11,116,102,105,108,101,100,105, + 97,108,111,103,10,102,105,108,101,100,105,97,108,111,103,8,115,116,97,116, + 102,105,108,101,7,12,102,111,114,109,115,116,97,116,102,105,108,101,26,99, + 111,110,116,114,111,108,108,101,114,46,102,105,108,116,101,114,108,105,115,116, + 46,100,97,116,97,1,1,6,10,70,97,100,101,32,70,105,108,101,115,6, + 5,42,46,102,97,100,0,1,6,9,65,108,108,32,70,105,108,101,115,6, + 1,42,0,0,21,99,111,110,116,114,111,108,108,101,114,46,100,101,102,97, + 117,108,116,101,120,116,6,3,102,97,100,18,99,111,110,116,114,111,108,108, + 101,114,46,111,112,116,105,111,110,115,11,14,102,100,111,95,99,104,101,99, + 107,101,120,105,115,116,15,102,100,111,95,115,97,118,101,108,97,115,116,100, + 105,114,0,22,99,111,110,116,114,111,108,108,101,114,46,99,97,112,116,105, + 111,110,111,112,101,110,6,14,76,111,97,100,32,70,97,100,101,32,70,105, + 108,101,22,99,111,110,116,114,111,108,108,101,114,46,99,97,112,116,105,111, + 110,115,97,118,101,6,14,83,97,118,101,32,70,97,100,101,32,70,105,108, + 101,4,108,101,102,116,3,208,0,3,116,111,112,3,240,0,0,0,9,116, + 115,116,97,116,102,105,108,101,12,102,97,100,101,115,116,97,116,102,105,108, + 101,8,102,105,108,101,110,97,109,101,6,10,115,116,97,116,117,115,46,115, + 116,97,12,111,110,115,116,97,116,117,112,100,97,116,101,7,17,102,97,100, + 101,115,116,97,116,117,112,100,97,116,101,101,120,101,4,108,101,102,116,3, + 200,0,3,116,111,112,3,200,0,0,0,16,116,115,116,114,105,110,103,99, + 111,110,116,97,105,110,101,114,1,99,12,115,116,114,105,110,103,115,46,100, + 97,116,97,1,6,43,68,111,32,121,111,117,32,119,97,110,116,32,116,111, + 32,115,121,110,99,104,114,111,110,105,122,101,32,111,112,97,99,105,116,121, + 32,103,114,97,100,105,101,110,116,6,20,119,105,116,104,32,99,111,108,111, + 114,32,103,114,97,100,105,101,110,116,63,6,39,68,111,32,121,111,117,32, + 119,97,110,116,32,116,111,32,114,101,109,111,118,101,32,111,112,97,99,105, + 116,121,32,103,114,97,100,105,101,110,116,63,0,4,108,101,102,116,2,88, + 3,116,111,112,3,88,1,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tfadeeditfo,''); +end. diff --git a/mseide-msegui/lib/common/designutils/msefadepropedit.pas b/mseide-msegui/lib/common/designutils/msefadepropedit.pas new file mode 100644 index 0000000..598994e --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msefadepropedit.pas @@ -0,0 +1,256 @@ +{ MSEide Copyright (c) 2007-2013 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit msefadepropedit; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msepropertyeditors; + +type + tfacefadecoloreditor = class(tcolorarraypropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + procedure edit; override; + end; + + tfacefadeposeditor = class(trealarraypropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + procedure edit; override; + end; + + tfacetemplatefadecoloreditor = class(tcolorarraypropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + procedure edit; override; + end; + + tfacetemplatefadeposeditor = class(trealarraypropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + procedure edit; override; + end; + + tfacefadeopacoloreditor = class(tcolorarraypropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + procedure edit; override; + end; + + tfacefadeopaposeditor = class(trealarraypropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + procedure edit; override; + end; + + tfacetemplatefadeopacoloreditor = class(tcolorarraypropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + procedure edit; override; + end; + + tfacetemplatefadeopaposeditor = class(trealarraypropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + procedure edit; override; + end; + +implementation +uses + msegraphutils,msearrayprops,msegui,msefadeedit,mseglob; + +type + tpropertyeditor1 = class(tpropertyeditor); + +procedure editfacefade(const aproperty: tpropertyeditor; const opa: boolean); +var + direct: graphicdirectionty; + fadepos,fadeopapos: trealarrayprop; + fadecolor,fadeopacolor: tcolorarrayprop; + int1: integer; +begin + with tcustomface(tpropertyeditor1(aproperty).instance) do begin + direct:= fade_direction; + fadepos:= fade_pos; + fadeopapos:= fade_opapos; + fadecolor:= fade_color; + fadeopacolor:= fade_opacolor; + if editfade(direct,opa,fade_pos,fade_opapos, + fade_color,fade_opacolor) = mr_ok then begin + fade_direction:= direct; + with tpropertyeditor1(aproperty) do begin + for int1:= 1 to count - 1 do begin + with tcustomface(tpropertyeditor1(aproperty).instance(int1)) do begin + fade_direction:= direct; + if opa then begin + fade_opapos.assign(fadeopapos); + fade_opacolor.assign(fadeopacolor); + end + else begin + fade_opapos.assign(fadepos); + fade_opacolor.assign(fadecolor); + end; + end; + end; + modified; + end; + end; + end; +end; + +procedure editfacetemplatefade(const aproperty: tpropertyeditor; + const opa: boolean); +var + direct: graphicdirectionty; + fadepos,fadeopapos: trealarrayprop; + fadecolor,fadeopacolor: tcolorarrayprop; + int1: integer; +begin + with tfacetemplate(tpropertyeditor1(aproperty).instance) do begin + direct:= fade_direction; + fadepos:= fade_pos; + fadeopapos:= fade_opapos; + fadecolor:= fade_color; + fadeopacolor:= fade_opacolor; + if editfade(direct,opa,fade_pos,fade_opapos, + fade_color,fade_opacolor) = mr_ok then begin + fade_direction:= direct; + with tpropertyeditor1(aproperty) do begin + for int1:= 1 to count - 1 do begin + with tfacetemplate(tpropertyeditor1(aproperty).instance(int1)) do begin + fade_direction:= direct; + if opa then begin + fade_opapos.assign(fadeopapos); + fade_opacolor.assign(fadeopacolor); + end + else begin + fade_opapos.assign(fadepos); + fade_opacolor.assign(fadecolor); + end; + end; + end; + modified; + end; + end; + end; +end; + +{ tfacefadecoloreditor } + +function tfacefadecoloreditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_dialog]; +end; + +procedure tfacefadecoloreditor.edit; +begin + editfacefade(self,false); +end; + +{ tfacefadeposeditor } + +function tfacefadeposeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_dialog]; +end; + +procedure tfacefadeposeditor.edit; +begin + editfacefade(self,false); +end; + +{ tfacetemplatefadecoloreditor } + +function tfacetemplatefadecoloreditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_dialog]; +end; + +procedure tfacetemplatefadecoloreditor.edit; +begin + editfacetemplatefade(self,false); +end; + +{ tfacetemplatefadeposeditor } + +function tfacetemplatefadeposeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_dialog]; +end; + +procedure tfacetemplatefadeposeditor.edit; +begin + editfacetemplatefade(self,false); +end; + +{ tfacefadeopacoloreditor } + +function tfacefadeopacoloreditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_dialog]; +end; + +procedure tfacefadeopacoloreditor.edit; +begin + editfacefade(self,true); +end; + +{ tfacefadeopaposeditor } + +function tfacefadeopaposeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_dialog]; +end; + +procedure tfacefadeopaposeditor.edit; +begin + editfacefade(self,true); +end; + +{ tfacetemplatefadeopacoloreditor } + +function tfacetemplatefadeopacoloreditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_dialog]; +end; + +procedure tfacetemplatefadeopacoloreditor.edit; +begin + editfacetemplatefade(self,true); +end; + +{ tfacetemplatefadeopaposeditor } + +function tfacetemplatefadeopaposeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_dialog]; +end; + +procedure tfacetemplatefadeopaposeditor.edit; +begin + editfacetemplatefade(self,true); +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/msefircoeffeditor.mfm b/mseide-msegui/lib/common/designutils/msefircoeffeditor.mfm new file mode 100644 index 0000000..0e520e0 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msefircoeffeditor.mfm @@ -0,0 +1,100 @@ +object fircoeffeditorfo: tfircoeffeditorfo + bounds_x = 72 + bounds_y = 206 + bounds_cx = 229 + bounds_cy = 263 + container.bounds = ( + 0 + 0 + 229 + 263 + ) + statfile = tstatfile1 + caption = 'IIR Filter Coefficients' + moduleclassname = 'tmseform' + object grid: twidgetgrid + bounds_x = 0 + bounds_y = 0 + bounds_cx = 228 + bounds_cy = 221 + anchors = [an_left, an_top, an_right, an_bottom] + optionsgrid = [og_focuscellonenter, og_rowheight, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixcols.count = 1 + fixcols.items = < + item + width = 62 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 1 + captions.items = < + item + caption = 'Coefficient' + end> + captionsfix.count = 1 + captionsfix.items = < + item + caption = 'sect:z^n' + end> + end> + datacols.count = 1 + datacols.options = [co_proportional, co_savevalue, co_savestate, co_mousescrollrow] + datacols.items = < + item[coeffed] + width = 160 + options = [co_mouseselect, co_keyselect, co_multiselect, co_fill, co_savevalue, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'coeffed' + dataclass = tgridrealdatalist + end> + datarowheight = 16 + reffontheight = 14 + object coeffed: trealedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 160 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + value = 0 + valuedefault = 0 + valuerange = 1 + valuestart = 0 + min = -1E+038 + max = 1E+038 + reffontheight = 14 + end + end + object ok: tbutton + taborder = 1 + bounds_x = 102 + bounds_y = 232 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + end + object cancel: tbutton + taborder = 2 + bounds_x = 166 + bounds_y = 232 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + end + object tstatfile1: tstatfile + filename = 'fircoeffeditor.sta' + options = [sfo_memory] + left = 56 + top = 48 + end +end diff --git a/mseide-msegui/lib/common/designutils/msefircoeffeditor.pas b/mseide-msegui/lib/common/designutils/msefircoeffeditor.pas new file mode 100644 index 0000000..83219de --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msefircoeffeditor.pas @@ -0,0 +1,22 @@ +unit msefircoeffeditor; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,msewidgets,mseforms,msestatfile, + msedataedits,mseedit,msegrids,mseificomp,mseificompglob,mseifiglob,msestrings, + msewidgetgrid,msesimplewidgets; +type + tfircoeffeditorfo = class(tmseform) + tstatfile1: tstatfile; + grid: twidgetgrid; + ok: tbutton; + cancel: tbutton; + coeffed: trealedit; + end; + +implementation +uses + msefircoeffeditor_mfm; + +end. diff --git a/mseide-msegui/lib/common/designutils/msefircoeffeditor_mfm.pas b/mseide-msegui/lib/common/designutils/msefircoeffeditor_mfm.pas new file mode 100644 index 0000000..d517627 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msefircoeffeditor_mfm.pas @@ -0,0 +1,102 @@ +unit msefircoeffeditor_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msefircoeffeditor; + +const + objdata: record size: integer; data: array[0..1683] of byte end = + (size: 1684; data: ( + 84,80,70,48,17,116,102,105,114,99,111,101,102,102,101,100,105,116,111,114, + 102,111,16,102,105,114,99,111,101,102,102,101,100,105,116,111,114,102,111,8, + 98,111,117,110,100,115,95,120,2,72,8,98,111,117,110,100,115,95,121,3, + 206,0,9,98,111,117,110,100,115,95,99,120,3,229,0,9,98,111,117,110, + 100,115,95,99,121,3,7,1,16,99,111,110,116,97,105,110,101,114,46,98, + 111,117,110,100,115,1,2,0,2,0,3,229,0,3,7,1,0,8,115,116, + 97,116,102,105,108,101,7,10,116,115,116,97,116,102,105,108,101,49,7,99, + 97,112,116,105,111,110,6,23,73,73,82,32,70,105,108,116,101,114,32,67, + 111,101,102,102,105,99,105,101,110,116,115,15,109,111,100,117,108,101,99,108, + 97,115,115,110,97,109,101,6,8,116,109,115,101,102,111,114,109,0,11,116, + 119,105,100,103,101,116,103,114,105,100,4,103,114,105,100,8,98,111,117,110, + 100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,120,3,228,0,9,98,111,117,110,100,115,95,99,121, + 3,221,0,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116, + 6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,9,97,110,95, + 98,111,116,116,111,109,0,11,111,112,116,105,111,110,115,103,114,105,100,11, + 19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101,114, + 12,111,103,95,114,111,119,104,101,105,103,104,116,20,111,103,95,99,111,108, + 99,104,97,110,103,101,111,110,116,97,98,107,101,121,10,111,103,95,119,114, + 97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112,117,112,17,111, + 103,95,109,111,117,115,101,115,99,114,111,108,108,99,111,108,0,13,102,105, + 120,99,111,108,115,46,99,111,117,110,116,2,1,13,102,105,120,99,111,108, + 115,46,105,116,101,109,115,14,1,5,119,105,100,116,104,2,62,0,0,13, + 102,105,120,114,111,119,115,46,99,111,117,110,116,2,1,13,102,105,120,114, + 111,119,115,46,105,116,101,109,115,14,1,6,104,101,105,103,104,116,2,16, + 14,99,97,112,116,105,111,110,115,46,99,111,117,110,116,2,1,14,99,97, + 112,116,105,111,110,115,46,105,116,101,109,115,14,1,7,99,97,112,116,105, + 111,110,6,11,67,111,101,102,102,105,99,105,101,110,116,0,0,17,99,97, + 112,116,105,111,110,115,102,105,120,46,99,111,117,110,116,2,1,17,99,97, + 112,116,105,111,110,115,102,105,120,46,105,116,101,109,115,14,1,7,99,97, + 112,116,105,111,110,6,8,115,101,99,116,58,122,94,110,0,0,0,0,14, + 100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,1,16,100,97,116, + 97,99,111,108,115,46,111,112,116,105,111,110,115,11,15,99,111,95,112,114, + 111,112,111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,118,97, + 108,117,101,12,99,111,95,115,97,118,101,115,116,97,116,101,17,99,111,95, + 109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,14,100,97,116,97, + 99,111,108,115,46,105,116,101,109,115,14,7,7,99,111,101,102,102,101,100, + 1,5,119,105,100,116,104,3,160,0,7,111,112,116,105,111,110,115,11,14, + 99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101, + 121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101, + 99,116,7,99,111,95,102,105,108,108,12,99,111,95,115,97,118,101,118,97, + 108,117,101,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95, + 99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17, + 99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119, + 105,100,103,101,116,110,97,109,101,6,7,99,111,101,102,102,101,100,9,100, + 97,116,97,99,108,97,115,115,7,17,116,103,114,105,100,114,101,97,108,100, + 97,116,97,108,105,115,116,0,0,13,100,97,116,97,114,111,119,104,101,105, + 103,104,116,2,16,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,9,116,114,101,97,108,101,100,105,116,7,99,111,101,102,102,101,100, + 14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49, + 95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,11,111,112, + 116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101, + 98,117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114, + 2,1,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,3,160,0,9,98,111,117,110,100,115,95,99,121,2,16,12,111, + 112,116,105,111,110,115,101,100,105,116,49,11,13,111,101,49,95,115,97,118, + 101,118,97,108,117,101,0,5,118,97,108,117,101,2,0,12,118,97,108,117, + 101,100,101,102,97,117,108,116,2,0,10,118,97,108,117,101,114,97,110,103, + 101,2,1,10,118,97,108,117,101,115,116,97,114,116,2,0,3,109,105,110, + 5,245,136,13,181,80,153,118,150,125,192,3,109,97,120,5,245,136,13,181, + 80,153,118,150,125,64,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,0,7,116,98,117,116,116,111,110,2,111,107,8,116,97,98, + 111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,102,8,98, + 111,117,110,100,115,95,121,3,232,0,9,98,111,117,110,100,115,95,99,120, + 2,50,9,98,111,117,110,100,115,95,99,121,2,20,7,97,110,99,104,111, + 114,115,11,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116,116, + 111,109,0,5,115,116,97,116,101,11,10,97,115,95,100,101,102,97,117,108, + 116,15,97,115,95,108,111,99,97,108,100,101,102,97,117,108,116,15,97,115, + 95,108,111,99,97,108,99,97,112,116,105,111,110,0,7,99,97,112,116,105, + 111,110,6,3,38,79,75,11,109,111,100,97,108,114,101,115,117,108,116,7, + 5,109,114,95,111,107,0,0,7,116,98,117,116,116,111,110,6,99,97,110, + 99,101,108,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100, + 115,95,120,3,166,0,8,98,111,117,110,100,115,95,121,3,232,0,9,98, + 111,117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121, + 2,20,7,97,110,99,104,111,114,115,11,8,97,110,95,114,105,103,104,116, + 9,97,110,95,98,111,116,116,111,109,0,5,115,116,97,116,101,11,15,97, + 115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,7,99,97,112,116, + 105,111,110,6,7,38,67,97,110,99,101,108,11,109,111,100,97,108,114,101, + 115,117,108,116,7,9,109,114,95,99,97,110,99,101,108,0,0,9,116,115, + 116,97,116,102,105,108,101,10,116,115,116,97,116,102,105,108,101,49,8,102, + 105,108,101,110,97,109,101,6,18,102,105,114,99,111,101,102,102,101,100,105, + 116,111,114,46,115,116,97,7,111,112,116,105,111,110,115,11,10,115,102,111, + 95,109,101,109,111,114,121,0,4,108,101,102,116,2,56,3,116,111,112,2, + 48,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tfircoeffeditorfo,''); +end. diff --git a/mseide-msegui/lib/common/designutils/mseformdatatools.pas b/mseide-msegui/lib/common/designutils/mseformdatatools.pas new file mode 100644 index 0000000..377c97c --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseformdatatools.pas @@ -0,0 +1,333 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseformdatatools; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + msetypes,msestrings,msestream,classes,mclasses,mseclasses; +type + objformatty = (of_default,of_delphi,of_fp); + +procedure componentstoobjsource(components: componentarty; + outfilename: filenamety; + usesnames: string; //',' between names: 'unit1,unit2' + unitname: string = ''; objformat: objformatty = of_default); + +procedure formtexttoobjsource(sourcefilename: filenamety; + formclass: string = ''; + unitname: string = ''; + objformat: objformatty = of_default; + langmodule: boolean = false); + //converts objecttext to linkdata, + //if formclass = '' -> extracted from sourcefile, + //if unitname = '' -> unitname = filename + +procedure datatoobjsource(const source: tstream; const dest: ttextstream; + const unitname: msestring); + +procedure getobjforminfo(instream: ttextstream; var formname,formclass: string); + //!!!!todo var -> out (fpcbug 3221) +procedure createlanglib(const libfilename: filenamety; + const langmodules,resourcemodules: stringarty); +procedure writeconstdata(po1: pbyte; length: integer; const dataname: string; + const outstream: ttextstream); + +implementation +uses + msefileutils,sysutils,msesys,mseobjecttext; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + formdataext = '_mfm'; + objdataname = 'objdata'; + +procedure createlanglib(const libfilename: filenamety; + const langmodules,resourcemodules: stringarty); +var + outstream: ttextstream; + str1: string; + int1: integer; +begin + outstream:= ttextstream.create(libfilename,fm_create); + try + outstream.writeln('library ' + filenamebase(libfilename) + ';'); + outstream.writeln(compilerdefaults); + outstream.writeln('uses'); + str1:= ' mselanglink'; + for int1:= 0 to high(langmodules) do begin + str1:= str1 + ',' + langmodules[int1]+formdataext; + end; + for int1:= 0 to high(resourcemodules) do begin + str1:= str1 + ',' + resourcemodules[int1]; + end; + outstream.writeln(str1+';'); + outstream.writeln('exports'); + outstream.writeln(' registerlang,unregisterlang;'); + outstream.writeln('end.'); + finally + outstream.free; + end; +end; + +var + format: objformatty; + +procedure getobjforminfo(instream: ttextstream; var formname,formclass: string); +var + str1: string; + ar1: stringarty; + posbefore: longword; +begin + posbefore:= instream.position; + instream.readln(str1); + instream.position:= posbefore; + splitstring(str1,ar1,' ',true); + if (length(ar1) <> 3) or not((ar1[0] = 'object') or (ar1[0] = 'inherited')) or + (ar1[1][length(ar1[1])] <> ':') then begin + raise exception.Create('Invalid format: "'+str1+'".'); + end; + formname:= copy(ar1[1],1,length(ar1[1])-1); + formclass:= ar1[2]; +end; + +function getbytestring(var data: pbyte; var count: integer): string; +var + int1: integer; + strings: stringarty; +begin + int1:= count; + if int1 > 20 then begin + int1:= 20; + end; + dec(count,int1); + setlength(strings,int1); + for int1:= 0 to int1 - 1 do begin + strings[int1]:= inttostr(data^); + inc(data); + end; + result:= concatstrings(strings,','); +end; + +function getnameext(name: string): string; +begin + if name = '' then begin + result:= '' + end + else begin + result:= '_'+name; + end; +end; + +procedure writeconstdata(po1: pbyte; length: integer; const dataname: string; + const outstream: ttextstream); +begin + outstream.writeln('const'); + outstream.writeln(' '+dataname+': record size: integer; data: array[0..'+ + inttostr(length-1)+'] of byte end ='); + outstream.writeln(' (size: '+inttostr(length)+'; data: ('); + while length > 0 do begin + outstream.write(' '+getbytestring(po1,length)); + if length > 0 then begin + outstream.writeln(','); + end; + end; + outstream.writeln(')'); + outstream.writeln(' );'); + outstream.writeln(''); +end; + +procedure writeobjdata(datastream: tmemorystream; outstream: ttextstream; + name: string; objformat: objformatty); +var + int1: integer; + po1: pbyte; +// str1: string; +begin + int1:= datastream.Size; + po1:= datastream.Memory; +// str1:= getnameext(name); + writeconstdata(po1,int1,objdataname+getnameext(name),outstream); +end; + +procedure writeobjregister(outstream: ttextstream; aclass,name: string); +begin + outstream.writeln(' registerobjectdata(@'+objdataname+getnameext(name)+','+aclass+ + ','''+name+''');'); +end; + +procedure componentstoobjsource(components: componentarty; + outfilename: filenamety; usesnames: string; + unitname: string = ''; objformat: objformatty = of_default); +var + outstream: ttextstream; + memstream: tmemorystream; + int1: integer; + str1: string; +begin + if objformat = of_default then begin + objformat:= format; + end; + if unitname = '' then begin + unitname:= ansistring(removefileext(filename(outfilename))); + end; + outstream:= ttextstream.Create(outfilename,fm_create); + try + outstream.writeln('unit ' + unitname + ';'); + outstream.writeln(compilerdefaults); + outstream.writeln(''); + outstream.writeln('interface'); + outstream.writeln(''); + outstream.writeln('implementation'); + outstream.writeln('uses'); + if usesnames <> '' then begin + str1:= ',' + usesnames; + end + else begin + str1:= ''; + end; + outstream.writeln(' mseclasses'+str1+';'); + outstream.writeln(''); + for int1:= 0 to high(components) do begin + memstream:= tmemorystream.Create; + try + memstream.WriteComponent(components[int1]); + writeobjdata(memstream,outstream,components[int1].Name,objformat) + finally + memstream.Free; + end; + end; + outstream.writeln('initialization'); + for int1:= 0 to high(components) do begin + with components[int1] do begin + writeobjregister(outstream,classname,name); + end; + end; + outstream.writeln('end.'); + finally + outstream.Free; + end; +end; + +procedure formtexttoobjsource(sourcefilename: filenamety; + formclass: string = ''; + unitname: string = ''; + objformat: objformatty = of_default; + langmodule: boolean = false); + //converts objectext to linkdata +var + instream: ttextstream; + outstream: ttextstream; + memstream: tmemorystream; + outname: string; + str1: string; + +begin + if objformat = of_default then begin + objformat:= format; + end; + instream:= ttextstream.create(sourcefilename,fm_read); + try + if formclass = '' then begin + getobjforminfo(instream,str1,formclass); + instream.position:= 0; + end; + if unitname = '' then begin + unitname:= ansistring(removefileext(filename(sourcefilename))); + end; + outname:= ansistring(removefileext(sourcefilename)) + formdataext; + memstream:= tmemorystream.Create; + try + objecttexttobinarymse(instream,memstream); + outstream:= ttextstream.createtransaction(filenamety(outname)+'.pas'); + outstream.usewritebuffer:= true; + try + outstream.writeln('unit ' + unitname + formdataext+';'); + outstream.writeln(compilerdefaults); + outstream.writeln(''); + outstream.writeln('interface'); + outstream.writeln(''); + outstream.writeln('implementation'); + outstream.writeln('uses'); + if langmodule then begin + outstream.writeln(' msei18nglob,mselanglink;'); + outstream.writeln(''); + writeobjdata(memstream,outstream,'',objformat); + outstream.writeln('var'); + outstream.writeln(' hookbefore: registermodulehookty;'); + outstream.writeln(''); + outstream.writeln( + 'procedure registermodule(const registermoduleproc: registermodulety);'); + outstream.writeln('begin'); + outstream.writeln( + ' registermoduleproc(@'+objdataname+','''+formclass+''','''');'); + outstream.writeln(' registermodulehook:= hookbefore;'); + outstream.writeln('end;'); + outstream.writeln(''); + outstream.writeln('initialization'); + outstream.writeln(' hookbefore:= registermodulehook;'); + outstream.writeln(' registermodulehook:= @registermodule;'); + end + else begin + outstream.writeln(' mseclasses,'+unitname+';'); + outstream.writeln(''); + writeobjdata(memstream,outstream,'',objformat); + outstream.writeln('initialization'); + writeobjregister(outstream,formclass,''); + end; + outstream.writeln('end.'); + finally + outstream.Free; + end; + finally + memstream.Free; + end; + finally + instream.Free; + end; +end; + +procedure datatoobjsource(const source: tstream; const dest: ttextstream; + const unitname: msestring); +var + s1: string; +begin + dest.writeln('unit ' + unitname+';'); + dest.writeln(compilerdefaults); + dest.writeln('interface'); + s1:= readstreamdatastring(source); + writeconstdata(pointer(s1),length(s1),'data',dest); + dest.writeln('implementation'); + dest.writeln('end.'); +end; + +initialization +{$ifdef FPC} + format:= of_fp; +{$else} + format:= of_delphi; +{$endif} +end. diff --git a/mseide-msegui/lib/common/designutils/msegdbutils.pas b/mseide-msegui/lib/common/designutils/msegdbutils.pas new file mode 100644 index 0000000..151e895 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msegdbutils.pas @@ -0,0 +1,5038 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msegdbutils; + +{$ifdef FPC}{$mode objfpc}{$h+}{$goto on}{$endif} +{$ifndef FPC}{$ifdef linux} {$define UNIX} {$endif}{$endif} +//{$define mse_usedebugbreakprocess} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + msestream,mseclasses,classes,mclasses,msetypes,mseevent,msehash,msepipestream, + msestrings,mseapplication,msegui,msedatalist,msesystypes,mseprocess; + +//todo: byte endianess for remote debugging + +type + gdbresultty = (gdb_ok,gdb_error,gdb_timeout,gdb_dataerror,gdb_message, + gdb_running,gdb_writeerror,gdb_notactive); + + sigflagty = (sfl_internal,sfl_stop,sfl_handle); + sigflagsty = set of sigflagty; + + processorty = (pro_i386,pro_x86_64,pro_arm,pro_armm3, + pro_cpu32,pro_avr32,pro_rl78); + languagety = (lan_none,lan_undef,lan_pascal); + +const + gdberrortexts: array[gdbresultty] of string = + ('','Error','Timeout','Data error','Message','Target running', + 'Write error','gdb not active'); + niltext = 'nil'; + processornames: array[processorty] of ansistring = + ('i386','x86_64','arm','armm3','cpu32','avr32','rl78'); + simulatorprocessors = [pro_arm,pro_armm3,pro_rl78]; + +type + gdbstatety = (gs_syncget,gs_syncack,gs_clicommand,gs_clilist, + gs_canstop,gs_started,gs_startup,gs_attaching, + gs_execloaded,gs_attached,gs_detached, + gs_remote,gs_async,gs_downloaded,gs_downloading,gs_runafterload, + gs_internalrunning,gs_running,gs_stopped, + gs_interrupted,gs_restarted, + gs_closing,gs_gdbdied); + gdbstatesty = set of gdbstatety; + + recordclassty = + (rec_done,rec_running,rec_connected,rec_error,rec_exit, + rec_stopped,rec_download, + rec_threadcreated,rec_threadexited,rec_threadgroupexited, + rec_threadselected, + rec_libraryloaded,rec_libraryunloaded, + rec_threadgroupadded,rec_threadgroupstarted,rec_breakpointmodified); + resultclassty = rec_done..rec_exit; + asyncclassty = rec_running..high(recordclassty); +const + recordclassnames: array[recordclassty] of string = + ('done', 'running', 'connected', 'error', 'exit', + 'stopped', 'download', + 'thread-created','thread-exited', 'thread-group-exited', + 'thread-selected', + 'library-loaded','library-unloaded', + 'thread-group-added','thread-group-started','breakpoint-modified'); + recordclassnoname: array[recordclassty] of boolean = + (false, false, false, false, false, + false, true, + false, false, false, + false, + false, false, + false, false, false); + defaultsynctimeout = 2000000; //2 seconds +type + valuekindty = (vk_value,vk_tuple,vk_list); + gdbeventkindty = (gek_done,gek_error,gek_connected,gek_running, + gek_stopped,gek_download,gek_loaded, + gek_targetoutput,gek_writeerror,gek_startup, + gek_gdbdied); + + resultinfoty = record + variablename: string; + valuekind: valuekindty; + value: string; + end; + resultinfoarty = array of resultinfoty; + resultinfoararty = array of resultinfoarty; + + stopreasonty = (sr_none,sr_unknown,sr_error,sr_startup,sr_exception,sr_gdbdied, + sr_breakpoint_hit, + sr_watchpointtrigger,sr_readwatchpointtrigger, + sr_accesswatchpointtrigger, + sr_end_stepping_range,sr_function_finished, + sr_exited_normally,sr_exited,sr_detached,sr_signal_received); + stopreasontextty = array[stopreasonty] of string; +const + defaultstopreasontext: stopreasontextty = ( + '', + 'Unknown', + 'Error', + 'Startup', + 'Exception', + 'GDB died', + 'Breakpoint hit', + 'Watchpoint triggered', + 'Read Watchpoint triggered', + 'Access Watchpoint triggered', + 'End stepping range', + 'Function finished', + 'Exited normally', + 'Exited', + 'Detached', + 'Signal received' + ); +var + stopreasontext: stopreasontextty; + +type + stopinfoty = record + reason: stopreasonty; + time: tdatetime; + bkptno: integer; + threadid: qword; + exitcode: integer; + filename: filenamety; + filedir: filenamety; + line: integer; + addr: qword; + func: string; + language: languagety; + signalname: string; + signalmeaning: string; + messagetext: string; + expression,oldvalue,newvalue: string; + section: string; + sectionsent,sectionsize,totalsent,totalsize: integer; + end; +{ + errorinfoty = record + messagetext: string; + end; +} + breakpointinfoty = record + addressbreakpoint: boolean; + line: integer; //1. line = 1 + path: filenamety; + address: qword; +// filename: string; + bkptno: integer; + bkpton: boolean; + ignore: integer; + passcount: integer; + condition,conditionmessage: string; + end; + pbreakpointinfoty = ^breakpointinfoty; + breakpointinfoarty = array of breakpointinfoty; + + watchpointkindty = (wpk_write,wpk_readwrite,wpk_read); + + watchpointinfoty = record + kind: watchpointkindty; + wptno: integer; + expression: string; + ignore: integer; + condition: string; + conditionmessage: string; + end; + + paraminfoty = record + name: string; + value: string; + end; + paraminfoarty = array of paraminfoty; + + frameinfoty = record + level: integer; + addr: qword; + func: string; + filename: filenamety; + line: integer; + params: paraminfoarty; + end; + frameinfoarty = array of frameinfoty; + + registerinfoty = record + num: integer; + bits: string; //hex notation + end; + registerinfoarty = array of registerinfoty; + + asmlinety = record + address: qword; + instruction: string; + end; + asmlinearty = array of asmlinety; + + disassty = record + line: integer; + asmlines: asmlinearty; + end; + disassarty = array of disassty; + + tgdbmi = class; + + gdbeventty = procedure(const sender: tgdbmi; var eventkind: gdbeventkindty; + const values: resultinfoarty; const stoppinfo: stopinfoty) of object; + + tgdbevent = class(tobjectevent) + private + flastconsoleoutput: ansistring; + fthreadid: integer; + public + eventkind: gdbeventkindty; + values: resultinfoarty; + end; + + tgdbstartupevent = class(tgdbevent) + public + stopinfo: stopinfoty; + constructor create(const dest: ievent); + end; + + setnumprocty = procedure(var dataarray; const index: integer; const text: string); + setlenprocty = procedure(var dataarray; const len: integer); + + threadstatety = (ts_none,ts_active); + + threadinfoty = record + id: qword; //gdb id + threadid: qword; //system id + state: threadstatety; + stackframe: string; + end; + threadinfoarty = array of threadinfoty; + +{$ifdef UNIX} + tpseudoterminal = class + private + fdevicename: string; + finput: tpipereader; + foutput: tpipewriter; + fpty: integer; + procedure closeinp; + procedure setoutecho(const avalue: boolean); + function getoutecho: boolean; + public + constructor create; + destructor destroy; override; + procedure restart; + property devicename: string read fdevicename; + property input: tpipereader read finput; + property output: tpipewriter read foutput; + property outecho: boolean read getoutecho write setoutecho; + end; +{$endif} + + envvarinfoty = record + name: string; + value: string; + unset: boolean; + end; + envvararty = array of envvarinfoty; + + tgdbmi = class(tactcomponent) + private + fgdbto: tpipewriter; + fgdbfrom{,fgdberror}: tpipereader; + {$ifdef UNIX} + ftargetterminal: tpseudoterminal; + ftargetconsole: tcustommseprocess; + {$endif} + fgdb: integer; //processhandle + fstate: gdbstatesty; + fsequence: longword; + fconsolesequence: longword; + frunsequence: longword; + fsyncsequence: longword; + fsyncvalues: resultinfoarty; + fsynceventkind: gdbeventkindty; + fclivalues: string; + fclivaluelist: stringarty; + fonevent: gdbeventty; + fonerror: gdbeventty; + fguiintf: boolean; + fsourcefiles: tmsestringhashdatalist; + fsourcefiledirs: filenamearty; //dirs for fsourcefiles + fexceptionbkpt: integer; + fstartupbreakpoint: integer; + fstartupbreakpoint1: integer; + fstoponexception: boolean; + ferrormessage: string; + fprocid: int64; + fcurrentprocid: int64; + {$ifdef mswindows} + finterruptthreadid: longword; + {$endif} + fworkingdirectory: filenamety; + fprogparameters: string; + finterruptcount: integer; + fignoreexceptionclasses: stringarty; + flogtext: string; + flastbreakpoint: integer; + fenvvars: envvararty; + ftargetdebugbegin,ftargetdebugend: qword; +// {$ifdef mswindows} + fnewconsole: boolean; +// {$endif} + fremoteconnection: msestring; + fgdbdownload: boolean; + fsimulator: boolean; + flastconsoleoutput: ansistring; + fprocessor: processorty; + fbeforeload: filenamety; + fafterload: filenamety; + fbeforerun: filenamety; + fstartupbkpt: longword; + fstartupbkpton: boolean; + foverloadsleepus: integer; + floadtimeoutus: integer; + fstoptime: tdatetime; + fstopinfo: resultinfoarty; + fstopthreadid: integer; + fcurrthreadid: integer; + fsettty: boolean; + fbeforeconnect: filenamety; + fafterconnect: filenamety; + fxtermcommand: filenamety; + fcurrentlanguage: languagety; + ffpcworkaround: boolean; + procedure setstoponexception(const avalue: boolean); + procedure checkactive; + function checkconnection(const proginfo: boolean): gdbresultty; + procedure resetexec; + function getrunning: boolean; + function getexecloaded: boolean; + function getattached: boolean; + procedure setignoreexceptionclasses(const avalue: stringarty); + function getprocessorname: ansistring; + procedure setprocessorname(const avalue: ansistring); + procedure setoverloadsleepus(const avalue: integer); + protected + fpointersize: integer; + fpointerhexdigits: integer; + {$ifdef UNIX} + procedure targetfrom(const sender: tpipereader); + procedure killtargetconsole; + function createtargetconsole: boolean; + procedure xtermfrom(const sender: tpipereader); + {$endif} + procedure gdbfrom(const sender: tpipereader); + procedure gdbpipebroken(const sender: tpipereader); + procedure interpret(const line: string); + procedure consoleoutput(const text: string); + procedure targetoutput(const text: string); + procedure logoutput(const text: string); + procedure sequenceend; + procedure initstopinfo(var ainfo: stopinfoty); + procedure receiveevent(const event: tobjectevent); override; + procedure doevent(const token: longword; const eventkind: gdbeventkindty; + values: resultinfoarty); + procedure postsyncerror; + procedure checkpointersize; + procedure updateenvvars(); + procedure dorun; + function internalcommand(acommand: string): boolean; + function synccommand(const acommand: string; + atimeout: integer = defaultsynctimeout): gdbresultty; + function clicommand(const acommand: string; list: boolean = false; + timeout: integer = defaultsynctimeout): gdbresultty; + function getcliresult(const acommand: string; + var aresult: stringarty): gdbresultty; + function getcliresultstring(const acommand: string; + var aresult: string): gdbresultty; + function getclistring(const aname: string; + const response: string; out aresult: string): boolean; + function getcliinteger(const aname: string; + const response: string; out aresult: integer): boolean; + function getcliint64(const aname: string; + const response: string; out aresult: int64): boolean; + + function decodelist(const noname: boolean; const inp: string; + var value: resultinfoarty): boolean; + function ispointervalue(avalue: string; out pointervalue: qword): boolean; + function matchpascalformat(const typeinfo: string; value: string; + const expression: string): msestring; + function getpcharvar(address: qword): string; + function getpmsecharvar(address: qword): msestring; + function getnumarrayvalue(const response: resultinfoarty; + const aname: string; var avalue; setnumproc: setnumprocty; + setlenproc: setlenprocty): boolean; + function getpascalvalue(const avalue: string): string; + function getbkptid: integer; + function getwptid: integer; + procedure initinternalbkpts; + procedure initproginfo; + function internaldisassemble(out aresult: disassarty; command: string; + const mixed: boolean): gdbresultty; + function getshortstring(const address: string; out avalue: string): boolean; + function setenv(const aname,avalue: string): gdbresultty; + function unsetenv(const aname: string): gdbresultty; + function getsysregnum(const varname: string; out num: integer): boolean; + function currentlang: string; + function assignoperator: string; + function getfullname(const tup: resultinfoarty): string; + function getbreakpointinfo(var atup: resultinfoty; + var info: breakpointinfoty; const full: boolean): boolean; + procedure updatepascalexpression(var aexpression: string); + procedure updatecurrentlanguage(); + function setlangc(): string; //returns currentlang + function setlang(const alanguage: string): gdbresultty; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + + procedure startgdb(commandline: msestring); + procedure closegdb; + function interrupttarget: gdbresultty; //stop for breakpointsetting + function restarttarget: gdbresultty; + function tryconnect: boolean; + + function togdbfilepath(const filename: filenamety): filenamety; + + procedure consolecommand(acommand: string); + function source(const afilename: filenamety): gdbresultty; //run script + function micommand(const command: string; + out values: resultinfoarty): gdbresultty; + //false on error or timeout, values = nil on timeout + function geterrormessage(const aresult: gdbresultty): string; + property errormessage: string read ferrormessage; + //for synccommand if error = gdb_message + + function handle(const signame: string; + const aflags: sigflagsty): gdbresultty; + // + function breakinsert(var info: breakpointinfoty): gdbresultty; overload; + function breakinsert(const funcname: string): integer; overload; + //returns bkpt id, -1 on error + function breakinsert(const address: qword): integer; overload; + function breaklist(var list: breakpointinfoarty; + const full: boolean): gdbresultty; + //full = false -> only bkptno, address and passcount + function breakdelete(bkptnum: integer): gdbresultty; //bkptnum = 0 -> all + function breakenable(bkptnum: integer; value: boolean): gdbresultty; + //bkptnum = 0 -> all + function breakafter(bkptnum: integer; const passcount: integer): gdbresultty; + function breakcondition(bkptnum: integer; + const condition: string): gdbresultty; + function infobreakpoint(var info: breakpointinfoty; + const full: boolean = true): gdbresultty; + //updates info for breakpoint info.bkptnum + function watchinsert(var info: watchpointinfoty): gdbresultty; + + function getstopinfo(const response: resultinfoarty; + const lastconsoleoutput: ansistring; + out info: stopinfoty): boolean; + + function getvalueindex(const response: resultinfoarty; + const aname: string): integer; + //-1 if not found + function getenumvalue(const response: resultinfoarty; + const aname: string; const enums: array of string; + var avalue: integer): boolean; + function gettuplevalue(const response: resultinfoarty; const aname: string; + var avalue: resultinfoarty): boolean; overload; + function gettuplevalue(const response: resultinfoty; + var avalue: resultinfoarty): boolean; overload; + function gettuplevalue(const response: resultinfoty; const aname: string; + var avalue: resultinfoarty): boolean; overload; + function gettuplestring(const response: resultinfoarty; const aname: string; + var avalue: string): boolean; overload; + + function getstringvalue(const response: resultinfoarty; const aname: string; + var avalue: string): boolean; overload; + function getstringvalue(const response: resultinfoty; const aname: string; + var avalue: string): boolean; overload; + function getintegervalue(const response: resultinfoarty; const aname: string; + var avalue: integer): boolean; overload; + function getintegervalue(const response: resultinfoty; const aname: string; + var avalue: integer): boolean; overload; + function getinteger64value(const response: resultinfoarty; + const aname: string; + var avalue: int64): boolean; overload; + function getinteger64value(const response: resultinfoty; const aname: string; + var avalue: int64): boolean; overload; + function getbooleanvalue(const response: resultinfoarty; const aname: string; + var avalue: boolean): boolean; + function getqwordvalue(const response: resultinfoarty; const aname: string; + var avalue: qword): boolean; overload; + function getqwordvalue(const response: resultinfoty; const aname: string; + var avalue: qword): boolean; overload; + + function getarrayvalue(const response: resultinfoarty; const aname: string; + const hasitemnames: boolean; + var avalue: resultinfoarty): boolean; + + function gettuplearrayvalue(const response: resultinfoarty; + const aname: string; var avalue: resultinfoararty): boolean; + function getstringarrayvalue(const response: resultinfoarty; + const aname: string; var avalue: stringarty): boolean; + function getbytearrayvalue(const response: resultinfoarty; + const aname: string; var avalue: bytearty): boolean; + function getwordarrayvalue(const response: resultinfoarty; + const aname: string; var avalue: wordarty): boolean; + function getlongwordarrayvalue(const response: resultinfoarty; + const aname: string; var avalue: longwordarty): boolean; + function getqwordarrayvalue(const response: resultinfoarty; + const aname: string; var avalue: card64arty): boolean; + + function fileexec(const filename: filenamety; + const noproginfo: boolean = false): gdbresultty; + function filesymbol(const filename: filenamety): gdbresultty; + function attach(const procid: longword; out info: stopinfoty): gdbresultty; + function attachtarget(out info: stopinfoty): gdbresultty; + function detach: gdbresultty; + function getprocid(var aprocid: int64): boolean; + //true if ok + function clearenvvars: gdbresultty; + function setenvvar(const aname,avalue: string): gdbresultty; + function unsetenvvar(const aname: string): gdbresultty; + + function download(const runafterload: boolean): gdbresultty; + function run: gdbresultty; + procedure continue; + procedure next; + procedure step; + procedure finish; + procedure nexti; + procedure stepi; + procedure interrupt; + procedure abort; + procedure targetwriteln(const avalue: string); + //sends text to target if running + + procedure debugbegin; //calls GUI_DEBUGBEGIN in target + procedure debugend; //calls GUI_DEBUGEND in target, + //automatically on every target start + + function active: boolean; //gdb running + function cancommand: boolean; //active and target not running + function started: boolean; //target active, run command applied or attached + property running: boolean read getrunning; //target running + function downloading: boolean; + function downloaded: boolean; + + function threadselect(const aid: integer; out filename: filenamety; + out line: integer): gdbresultty; + function getthreadidlist(out idlist: integerarty): gdbresultty; + function getthreadinfolist(out infolist: threadinfoarty): gdbresultty; + + function readmemorybytes(const address: qword; const count: integer; + var aresult: bytearty): gdbresultty; + function readmemorywords(const address: qword; const count: integer; + var aresult: wordarty): gdbresultty; + function readmemorylongwords(const address: qword; const count: integer; + var aresult: longwordarty): gdbresultty; + function readmemoryqwords(const address: qword; const count: integer; + var aresult: card64arty): gdbresultty; + function readmemorybyte(const address: qword; + out aresult: byte): gdbresultty; + function readmemoryword(const address: qword; + out aresult: word): gdbresultty; + function readmemorylongword(const address: qword; + out aresult: longword): gdbresultty; + function readmemorypointer(const address: qword; + out aresult: qword): gdbresultty; + function writememory8(const address: qword; + const avalue: card8): gdbresultty; + function writememory16(const address: qword; + const avalue: card16): gdbresultty; + function writememory32(const address: qword; + const avalue: card32): gdbresultty; + function writememory64(const address: qword; + const avalue: card64): gdbresultty; + + function readpascalvariable(varname: string; + out aresult: msestring): gdbresultty; + function writepascalvariable(varname: string; const value: string; + var aresult: string): gdbresultty; + function executecommand(const acommand: string; + out aresult: string): gdbresultty; + function evaluateexpression(expression: string; out aresult: string; + const noupdatepascalexpression: boolean = false): gdbresultty; + function symboltype(symbol: string; + out aresult: ansistring): gdbresultty; + function symboladdress(symbol: string; + out aresult: ansistring): gdbresultty; + function stacklistframes(out list: frameinfoarty; first: integer = 0; + last: integer = 100): gdbresultty; + function selectstackframe(const aframe: integer): gdbresultty; + function selectstackpointer(const aframe: qword): gdbresultty; + function getsourcename(out path: filenamety; out language: languagety; + frame: integer = 0): gdbresultty; + function getprocaddress(const procname: string; + out aaddress: qword): gdbresultty; + + function getpc(out addr: qword): gdbresultty; + function getregistervalue(const aname: string; + out avalue: qword): gdbresultty; + function setregistervalue(const aname: string; + const avalue: qword): gdbresultty; + function listregisternames(out aresult: stringarty): gdbresultty; + function listregistervalues(out aresult: registerinfoarty): gdbresultty; + function listlines(const path: filenamety; out lines: integerarty; + out addresses: qwordarty): gdbresultty; + + function getsystemregister(const anumber: integer; + out avalue: qword): gdbresultty; + function setsystemregister(const anumber: integer; + const avalue: qword): gdbresultty; + //for avr32 + function infoline(const filename: filenamety; const line: integer; + out start,stop: qword): gdbresultty; overload; + function infoline(const address: qword; out filename: filenamety; + out line: integer; + out start,stop: qword): gdbresultty; overload; + function infosymbol(const symbol: msestring; + out info: msestring): gdbresultty; + function infoaddress(const symbol: msestring; + out aresult: msestring): gdbresultty; + function disassemble(out aresult: asmlinearty; const filename: filenamety; + const line: integer; const count: integer): gdbresultty; overload; + function disassemble(out aresult: asmlinearty; + const start,stop: qword): gdbresultty; overload; + function disassemble(out aresult: disassarty; const filename: filenamety; + const line: integer; const count: integer): gdbresultty; overload; + function disassemble(out aresult: disassarty; + const start,stop: qword): gdbresultty; overload; + function getframeaddress(out address: qword): gdbresultty; + + property execloaded: boolean read getexecloaded; + property attached: boolean read getattached; + property stoponexception: boolean read fstoponexception + write setstoponexception default false; + property ignoreexceptionclasses: stringarty read fignoreexceptionclasses + write setignoreexceptionclasses; + property pointersize: integer read fpointersize; + property pointerhexdigits: integer read fpointerhexdigits; + property stoptime: tdatetime read fstoptime; + + property progparameters: string read fprogparameters write fprogparameters; + property workingdirectory: filenamety read fworkingdirectory + write fworkingdirectory; + property loadtimeoutus: integer read floadtimeoutus write floadtimeoutus; + //0 -> default +// {$ifdef mswindows} + property newconsole: boolean read fnewconsole write fnewconsole; +// {$endif} + property processorname: ansistring read getprocessorname + write setprocessorname; + property currentlanguage: languagety read fcurrentlanguage; + published + property guiintf: boolean read fguiintf write fguiintf default false; + //call GUI_DEBUGBEGIN/END + property remoteconnection: msestring read fremoteconnection + write fremoteconnection; + property gdbdownload: boolean read fgdbdownload write fgdbdownload; + property settty: boolean read fsettty write fsettty default true; + property simulator: boolean read fsimulator write fsimulator; + property processor: processorty read fprocessor + write fprocessor default pro_i386; + property beforeconnect: filenamety read fbeforeconnect write fbeforeconnect; + property afterconnect: filenamety read fafterconnect write fafterconnect; + property beforeload: filenamety read fbeforeload write fbeforeload; + property afterload: filenamety read fafterload write fafterload; + property beforerun: filenamety read fbeforerun write fbeforerun; + //gdb script + property startupbkpt: longword read fstartupbkpt write fstartupbkpt; + property startupbkpton: boolean read fstartupbkpton write fstartupbkpton; + property onevent: gdbeventty read fonevent write fonevent; + property onerror: gdbeventty read fonerror write fonerror; + property overloadsleepus: integer read foverloadsleepus + write setoverloadsleepus default -1; + {$warnings off} + property xtermcommand: filenamety read fxtermcommand write fxtermcommand; + //${PTS} expands to tty pts path + //${PTSN} expands to tty pts number + //${PTSH} expands to tty pts handle + {$warnings on} + property fpcworkaround: boolean read ffpcworkaround write + ffpcworkaround default false; + end; + +procedure localizetext; + +implementation +uses + sysutils,mseformatstr,mseprocutils,msesysutils,msefileutils,msemacros, + msebits,msesysintf,msesysintf1,mseguiintf,msearrayutils,msesys,msedate, + actionsmodule + {$ifdef UNIX},mselibc{$else},windows,msedynload{$endif}; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{$ifdef mswindows} + {$ifdef mse_usedebugbreakprocess} +var + debugbreakprocess: function(Process: HANDLE): BOOL; stdcall; + {$endif} +{$endif} + +type + tpypereader1 = class(tpipereader); +const + stopreasons: array[stopreasonty] of string = + //sr_none sr_unknown, sr_error sr_startup sr_exception sr_gdbdied + ('', '', '', '', '', '', + 'breakpoint-hit','watchpoint-trigger','read-watchpoint-trigger', + 'access-watchpoint-trigger', + 'end-stepping-range','function-finished','exited-normally', + 'exited','detached','signal-received'); + +procedure getcstring(var text: pchar); +var + po1: pchar; +begin + if text <> nil then begin + if text^ = '"' then begin + po1:= text; + repeat + if po1^ = '\' then begin + inc(po1); + if po1^ = #0 then begin + break; + end; + end; + inc(po1); + until (po1^ = '"') or (po1^ = #0); + if po1^ <> #0 then begin + text:= po1+1; + end; + end; + end; +end; + +procedure gettuple(var text: pchar); +var + level: integer; + po1: pchar; +begin + if text <> nil then begin + level:= 0; + po1:= text; + repeat + case po1^ of + '{': begin + inc(level); + end; + '}': begin + dec(level); + end; + '"': begin + getcstring(po1); + dec(po1); + end; + end; + inc(po1); + until (level <= 0) or (po1^ = #0); + text:= po1; + end; +end; + +procedure getlist(var text: pchar); +var + level: integer; + po1: pchar; +begin + if text <> nil then begin + level:= 0; + po1:= text; + repeat + case po1^ of + '[': begin + inc(level); + end; + ']': begin + dec(level); + end; + '"': begin + getcstring(po1); + dec(po1); + end; + '{': begin + gettuple(po1); + dec(po1); + end; + end; + inc(po1); + until (level <= 0) or (po1^ = #0); + text:= po1; + end; +end; + +procedure decoderesult(const noname: boolean; var text: pchar; out resultinfo: resultinfoty); + +var + po1,po2: pchar; +begin + if noname then begin + po1:= text; + end + else begin + po1:= strscan(text,'='); + end; + with resultinfo do begin + if po1 = nil then begin + variablename:= text; + value:= ''; + end + else begin + variablename:= psubstr(text,po1); + if not noname then begin + inc(po1); + end; + case po1^ of + '"': begin + value:= cstringtostringvar(po1); + valuekind:= vk_value; + end; + '{': begin + po2:= po1; + gettuple(po1); + value:= psubstr(po2+1,po1-1); + valuekind:= vk_tuple; + end; + '[': begin + po2:= po1; + getlist(po1); + value:= psubstr(po2+1,po1-1); + valuekind:= vk_list; + end; + end; + end; + end; + text:= po1; +end; + +{ tgdbstartupevent } + +constructor tgdbstartupevent.create(const dest: ievent); +begin + inherited create(ek_none,dest); + eventkind:= gek_startup; +end; + +{ tgdbmi } + +constructor tgdbmi.create(aowner: tcomponent); +begin + fsettty:= true; + fpointersize:= sizeof(pointer); + fpointerhexdigits:= fpointersize * 2; + fgdb:= invalidprochandle; + fguiintf:= true; + fsourcefiles:= tmsestringhashdatalist.create(); +// fsourcefiles:= thashedmsestrings.create; + fstoptime:= emptydatetime; + {$ifdef UNIX} + ftargetterminal:= tpseudoterminal.create; + ftargetterminal.input.oninputavailable:= {$ifdef FPC}@{$endif}targetfrom; + ftargetconsole:= tcustommseprocess.create(nil); + ftargetconsole.options:= [pro_output,pro_errorouttoout]; +// ftargetconsole.filename:= 'xterm'; + ftargetconsole.output.oninputavailable:= {$ifdef FPC}@{$endif}xtermfrom; + {$endif} + foverloadsleepus:= -1; + inherited; +end; + +destructor tgdbmi.destroy; +begin + closegdb; + inherited; + fsourcefiles.free; + {$ifdef UNIX} + ftargetconsole.free; + ftargetterminal.free; + {$endif} +end; + +procedure tgdbmi.resetexec; +begin + fstate:= fstate - [gs_internalrunning,gs_running,gs_stopped, + gs_execloaded,gs_canstop, + gs_attached,gs_attaching,gs_started,gs_startup,gs_detached, + gs_remote,gs_async, + gs_interrupted,gs_restarted, + gs_downloaded,gs_downloading]; + {$ifdef mswindows} + finterruptthreadid:= 0; + {$endif} + finterruptcount:= 0; + fprocid:= 0; + fcurrentprocid:= 0; + flastbreakpoint:= 0; + ftargetdebugbegin:= 0; + ftargetdebugend:= 0; + fstartupbreakpoint:= -1; + fstartupbreakpoint1:= -1; + fstopinfo:= nil; + fstopthreadid:= -1; + fcurrthreadid:= -1; +end; + +procedure tgdbmi.closegdb; +{$ifdef mswindows} +var + int1: integer; +{$endif} +begin + if not (gs_closing in fstate) then begin + include(fstate,gs_closing); + if fgdb <> invalidprochandle then begin + abort; + end; + {$ifdef mswindows} + if fgdb <> invalidprochandle then begin + int1:= fgdb; + fgdb:= invalidprochandle; + killprocess(int1); + end; + {$else} + if fgdbfrom <> nil then begin + fgdbfrom.terminate; + end; + { + if fgdberror <> nil then begin + fgdberror.terminate; + end; + } + if fgdb <> invalidprochandle then begin + killprocess(fgdb); + fgdb:= invalidprochandle; + end; + {$endif} + fgdbto.free; + fgdbto:= nil; + fgdbfrom.free; + fgdbfrom:= nil; +// fgdberror.free; +// fgdberror:= nil; + fsourcefiles.clear; + fsourcefiledirs:= nil; + resetexec; + fstate:= fstate - [gs_closing,gs_gdbdied]; + end; +end; + +procedure tgdbmi.startgdb(commandline: msestring); +const + lcmessages = 'LC_MESSAGES'; +var +(* +{$ifdef UNIX} + bo1: boolean; + str1: string; +{$endif} + *) + haslang: boolean; + langbefore: msestring; +begin + closegdb; + fgdbto:= tpipewriter.create; + fgdbfrom:= tpipereader.create; + fgdbfrom.overloadsleepus:= foverloadsleepus; + fgdbfrom.oninputavailable:= {$ifdef FPC}@{$endif}gdbfrom; + fgdbfrom.onpipebroken:= {$ifdef FPC}@{$endif}gdbpipebroken; + fconsolesequence:= 0; + frunsequence:= 0; + fsequence:= 1; + flastbreakpoint:= 0; + haslang:= sys_getenv(lcmessages,langbefore); + sys_setenv(lcmessages,'C'); + + fgdb:= execmse2(syscommandline(commandline)+' --interpreter=mi --nx', + fgdbto,fgdbfrom,fgdbfrom,-1, + [exo_inactive,exo_tty,exo_winpipewritehandles]); + + if haslang then begin + sys_setenv(lcmessages,langbefore); + end + else begin + sys_unsetenv(lcmessages); + end; + if fgdb <> invalidprochandle then begin + if haslang then begin + setenv(lcmessages,ansistring(langbefore)); + end + else begin + unsetenv(lcmessages); + end; + clicommand('set breakpoint pending on'); + clicommand('set height 0'); + clicommand('set width 0'); + {$ifdef UNIX} + { + bo1:= true; + if synccommand('-gdb-show inferior-tty') = gdb_ok then begin + if getstringvalue(fsyncvalues,'value',str1) and (str1 <> '') then begin + bo1:= false; + end; + end; + if bo1 then begin + } + if fsettty or fnewconsole then begin + clicommand('tty '+ftargetterminal.devicename); + end; + {$endif} + end; +end; + +function tgdbmi.getrunning: boolean; +begin + result:= gs_running in fstate; +end; + +function tgdbmi.getexecloaded: boolean; +begin + result:= gs_execloaded in fstate; +end; + +function tgdbmi.getattached: boolean; +begin + result:= gs_attached in fstate; +end; + +procedure tgdbmi.debugbegin; //calls GUI_DEBUGBEGIN in target +begin + if ftargetdebugbegin <> 0 then begin + if clicommand('call GUI_DEBUGBEGIN()') <> gdb_ok then begin + clicommand('call '+inttostr(ftargetdebugbegin)+'()'); + end; + end; +end; + +procedure tgdbmi.debugend; //calls GUI_DEBUGEND in target +begin + exclude(fstate,gs_stopped); + if ftargetdebugend <> 0 then begin + if clicommand('call GUI_DEBUGEND()') <> gdb_ok then begin + clicommand('call '+inttostr(ftargetdebugend)+'()'); + end; + end; +end; + +function tgdbmi.active: boolean; +begin + result:= fgdb <> invalidprochandle; +end; + +function tgdbmi.cancommand: boolean; +begin + result:= active and not running; +end; + +procedure tgdbmi.setstoponexception(const avalue: boolean); +begin + if fstoponexception <> avalue then begin + if gs_internalrunning in fstate then begin + raise exception.Create('Target running!'); + end; + if fexceptionbkpt >= 0 then begin + breakenable(fexceptionbkpt,avalue); + fstoponexception:= avalue; + end; + end; +end; + +var + workaround: string; + +procedure tgdbmi.setignoreexceptionclasses(const avalue: stringarty); +var + int1: integer; +begin + setlength(fignoreexceptionclasses,length(avalue)); + for int1:= 0 to high(avalue) do begin + workaround:= uppercase(avalue[int1]); //see FPC Mantis 11290 + fignoreexceptionclasses[int1]:= workaround; +// fignoreexceptionclasses[int1]:= uppercase(avalue[int1]); + end; +end; + +procedure tgdbmi.checkactive; +begin + if not active then begin + raise exception.Create('GDB not active!'); + end; +end; + +procedure tgdbmi.consoleoutput(const text: string); +begin +// write(text); +end; + +procedure tgdbmi.targetoutput(const text: string); +var + ev: tgdbevent; +begin + if assigned(fonevent) then begin + ev:= tgdbevent.create(ek_none,ievent(self)); + ev.eventkind:= gek_targetoutput; + setlength(ev.values,1); + ev.values[0].value:= text; + application.postevent(ev); + end; +end; + +procedure tgdbmi.logoutput(const text: string); +begin + flogtext:= text; +// consoleoutput(text); +end; + +function tgdbmi.getprocid(var aprocid: int64): boolean; +var + ar1,ar2: stringarty; + int1: integer; + str1: string; +begin + if fcurrentprocid <> 0 then begin + aprocid:= fcurrentprocid; + result:= true; + exit; + end; + result:= false; + ar2:= nil; + if getcliresult('info program',ar1) = gdb_ok then begin + for int1:= 0 to high(ar1) do begin + if (pos('child thread',ar1[int1]) > 0) or + (pos('attached thread',ar1[int1]) > 0) or + (pos('attached LWP',ar1[int1]) > 0) then begin + splitstring(ar1[int1],ar2,' '); + if high(ar2) > 0 then begin + ar1:= nil; + splitstring(ar2[high(ar2)],ar1,'.'); + if high(ar1) > 0 then begin + if trystrtointvalue64(ar1[0],qword(aprocid)) then begin + result:= true; + end; + end; + end; + break; + end + else begin + if (pos('child Thread',ar1[int1]) > 0) or + (pos('attached Thread',ar1[int1]) > 0) then begin + splitstring(ar1[int1],ar2,' '); + if high(ar2) > 0 then begin + str1:= ar2[high(ar2)]; + if (length(str1) > 2) and (str1[length(str1)-1] = ')') then begin + str1:= copy(str1,1,length(str1) - 2); + if trystrtointvalue64(str1,qword(aprocid)) then begin + result:= true; + end; + end + else begin + if str1 <> '' then begin + ar2:= splitstring(str1,'.'); + if trystrtointvalue64(ar2[0],qword(aprocid)) then begin + result:= true; + end; + end; + end; + end; + break; + end + else begin + if (pos('child process',ar1[int1]) > 0) or + (pos('attached process',ar1[int1]) > 0) then begin + splitstring(ar1[int1],ar2,' '); + if high(ar2) > 0 then begin + str1:= ar2[high(ar2)]; + if (length(str1) > 1) and (str1[length(str1)] = '.') then begin + str1:= copy(str1,1,length(str1) - 1); + try + aprocid:= strtointvalue(str1); + result:= true; + except + end; + end; + end; + break; + end; + end; + end; + end; + end; +end; + +function tgdbmi.clearenvvars: gdbresultty; +var + int1: integer; +begin + result:= gdb_ok; + if active then begin + for int1:= 0 to high(fenvvars) do begin + with fenvvars[int1] do begin + if not unset then begin + result:= clicommand('unset environement '+fenvvars[int1].name); + if result <> gdb_ok then begin + break; + end; + end; + end; + end; + end; + fenvvars:= nil; +end; + +function tgdbmi.setenv(const aname,avalue: string): gdbresultty; +begin + result:= synccommand('-gdb-set environment '+aname+'='+avalue); +end; + +function tgdbmi.unsetenv(const aname: string): gdbresultty; +begin + result:= clicommand('unset environment '+aname); +end; + +function tgdbmi.setenvvar(const aname,avalue: string): gdbresultty; +var + int1: integer; +begin + result:= gdb_ok; + if active then begin + result:= setenv(aname,avalue); + end; + if result = gdb_ok then begin + for int1:= 0 to high(fenvvars) do begin + if aname = fenvvars[int1].name then begin + fenvvars[int1].value:= avalue; + fenvvars[int1].unset:= false; + exit; + end; + end; + setlength(fenvvars,high(fenvvars)+2); + with fenvvars[high(fenvvars)] do begin + name:= aname; + value:= avalue; + end; + end; +end; + +function tgdbmi.unsetenvvar(const aname: string): gdbresultty; +var + int1: integer; +begin + result:= gdb_ok; + if active then begin + unsetenv(aname); + end; + if result = gdb_ok then begin + for int1:= 0 to high(fenvvars) do begin + if aname = fenvvars[int1].name then begin + fenvvars[int1].value:= ''; + fenvvars[int1].unset:= true; + exit; + end; + end; + setlength(fenvvars,high(fenvvars)+2); + with fenvvars[high(fenvvars)] do begin + name:= aname; + unset:= true; + end; + end; +end; + +function tgdbmi.getshortstring(const address: string; out avalue: string): boolean; +var + str1: string; + int1: card64; + ar1: bytearty; +begin + avalue:= ''; + result:= evaluateexpression(address,str1) = gdb_ok; + if result then begin + if trystrtohex64(str1,int1) then begin + if readmemorybytes(int1,1,ar1) = gdb_ok then begin + if ar1[0] <> 0 then begin + if readmemorybytes(int1+1,ar1[0],ar1) = gdb_ok then begin + setlength(avalue,length(ar1)); + move(ar1[0],avalue[1],length(avalue)); + result:= true; + end; + end; + end; + end + else begin + result:= false; + end; + end; +end; + +procedure tgdbmi.initstopinfo(var ainfo: stopinfoty); +begin + finalize(ainfo); + fillchar(ainfo,sizeof(ainfo),0); + ainfo.time:= nowlocal; +end; + +const + getexceptionname: array[processorty] of string = ( +//pro_i386, pro_x86_64, pro_arm, pro_armm3, + '($eax^+12)^','ppointer(ppointer($rax)^+24)^','($r0^+12)^','($r0^+12)^', +//pro_cpu32,pro_avr32,pro_rl78 + '', '', ''); + +procedure tgdbmi.receiveevent(const event: tobjectevent); +var + stopinfo: stopinfoty; + bo1: boolean; + int1: integer; + str1,str2: string; + ar1: resultinfoarty; + {$ifdef mswindows} + threadids: integerarty; + {$endif} + mstr1: filenamety; + +begin + if event is tgdbevent then begin + initstopinfo(stopinfo); + with tgdbevent(event) do begin + case eventkind of + gek_startup: begin + include(self.fstate,gs_canstop); + if gs_startup in self.fstate then begin + exit; //already done + end; + include(self.fstate,gs_startup); + stopinfo:= tgdbstartupevent(event).stopinfo; + eventkind:= gek_stopped; + end; + gek_gdbdied: begin + exclude(self.fstate,gs_running); + fstoptime:= stopinfo.time; + stopinfo.reason:= sr_gdbdied; + stopinfo.messagetext:= 'Process died.'; + if getprocessexitcode(fgdb,int1,2000000) = pee_ok then begin + stopinfo.messagetext:= stopinfo.messagetext + + ' Exitcode: '+inttostr(int1)+'.'; + fgdb:= invalidprochandle; + end; + closegdb; + end; + gek_stopped: begin + exclude(self.fstate,gs_running); + fstoptime:= stopinfo.time; + if gs_canstop in self.fstate then begin + {$ifdef mswindows} + if finterruptthreadid <> 0 then begin + if getthreadidlist(threadids) = gdb_ok then begin + if high(threadids) > 0 then begin + if threadselect(threadids[1],mstr1,int1) = gdb_ok then begin + setlength(values,3); + with values[0] do begin + variablename:= 'reason'; + valuekind:= vk_value; + value:= stopreasons[sr_signal_received]; + end; + with values[1] do begin + variablename:= 'signal-name'; + valuekind:= vk_value; + value:= 'SIGTRAP'; + end; + with values[2] do begin + variablename:= 'thread-id'; + valuekind:= vk_value; + value:= inttostr(threadids[1]); + end; + if gettuplestring(fsyncvalues,'frame',str1) then begin + setlength(values,4); + with values[3] do begin + variablename:= 'frame'; + valuekind:= vk_tuple; + value:= str1; + end; + end; + end; + end; + end; + finterruptthreadid:= 0; + end; + {$endif mswindows} + if fthreadid <> -1 then begin + threadselect(fthreadid,mstr1,int1); + //there was an breakpoint in other thread + end; + bo1:= getstopinfo(values,flastconsoleoutput,stopinfo); + if not bo1 then begin + stopinfo.messagetext:= ansistring(actionsmo.c[ord(ac_stoperror)])+': ' + + stopinfo.messagetext; + end + else begin + if (stopinfo.reason = sr_breakpoint_hit) and + (stopinfo.bkptno = fexceptionbkpt) then begin + if (getexceptionname[processor] <> '') and + getshortstring(getexceptionname[processor],str1) then begin + str2:= uppercase(str1); + bo1:= false; + for int1:= 0 to high(fignoreexceptionclasses) do begin + if str2 = fignoreexceptionclasses[int1] then begin + bo1:= true; + break; + end; + end; + if bo1 then begin + self.fstate:= self.fstate + [gs_restarted,gs_running]; + continue; + stopinfo.reason:= sr_none; + end + else begin + stopinfo.messagetext:= 'Exception '+str1+'.'; + stopinfo.reason:= sr_exception; + end; + end; + end; + if stopinfo.reason in [sr_exited,sr_exited_normally] then begin + self.fstate:= self.fstate - [gs_started,gs_startup]; + end; + if stopinfo.reason = sr_startup then begin + if fstartupbreakpoint >= 0 then begin + breakdelete(fstartupbreakpoint); + fstartupbreakpoint:= -1; + end; + if fstartupbreakpoint1 >= 0 then begin + breakdelete(fstartupbreakpoint1); + fstartupbreakpoint1:= -1; + end; + fprocid:= 0; + getprocid(fprocid); + {$ifdef UNIX} + if not fnewconsole then begin + ftargetterminal.restart; + end; + {$endif} + if gs_startup in self.fstate then begin + exit; //already done + end; + include(self.fstate,gs_startup); + include(self.fstate,gs_started); //gek_running can be missed + end; + end; + end; + end; + gek_running: begin + fstoptime:= emptydatetime; + include(self.fstate,gs_running); + end; + gek_error,gek_writeerror: begin + getstringvalue(values,'msg',stopinfo.messagetext); + end; + gek_done: begin + if gs_downloading in self.fstate then begin + include(self.fstate,gs_downloaded); + with stopinfo do begin + getintegervalue(values,'load-size',totalsent); + if fafterload <> '' then begin + if source(fafterload) <> gdb_ok then begin + exclude(self.fstate,gs_downloaded); + postsyncerror; + end; + end; +// include(self.fstate,gs_downloading); +// //restore downloading flag; + if gs_runafterload in self.fstate then begin + initproginfo; + dorun; + end; + end; + end; + end; + gek_download: begin + if (high(values) >= 0) and gettuplevalue(values[0],ar1) then begin + with stopinfo do begin + getstringvalue(ar1,'section',section); + getintegervalue(ar1,'section-sent',sectionsent); + getintegervalue(ar1,'section-size',sectionsize); + getintegervalue(ar1,'total-sent',totalsent); + getintegervalue(ar1,'total-size',totalsize); + end; + end; + end; + end; + try + if assigned(fonevent) and + not((eventkind = gek_stopped) and (stopinfo.reason = sr_none)) then begin + fonevent(self,eventkind,values,stopinfo); + end; + if (eventkind = gek_error) and assigned(fonerror) then begin + fonerror(self,eventkind,values,stopinfo); + end; + if (eventkind = gek_done) and + (self.fstate * [gs_downloading,gs_runafterload] = + [gs_downloading,gs_runafterload]) then begin + exclude(self.fstate,gs_downloading); + dorun; + end; + finally + if eventkind = gek_done then begin + exclude(self.fstate,gs_downloading); + end; + end; + end; + end + else begin + inherited; + end; +end; + +procedure tgdbmi.doevent(const token: longword; const eventkind: gdbeventkindty; + values: resultinfoarty); +var + ev: tgdbevent; + id1: integer; +begin + id1:= fcurrthreadid; + if (token <> 0) and (token = fsyncsequence) then begin + fsyncvalues:= values; + fsynceventkind:= eventkind; + include(fstate,gs_syncack); + exclude(fstate,gs_syncget); + end; + if not (gs_detached in fstate) then begin + case eventkind of + gek_running: begin + frunsequence:= token; + fstate:= fstate + [gs_internalrunning,gs_started]; + end; + gek_stopped: begin + if values <> nil then begin + fstopinfo:= values; + fstopthreadid:= fcurrthreadid; + id1:= -1; //no thread switch necessary; + end; + values:= fstopinfo; + exclude(fstate,gs_internalrunning); + if gs_attaching in fstate then begin + exit; //ignore + end; + end; + gek_error: begin + exclude(fstate,gs_downloading); + end; + end; + if (eventkind = gek_error) and (token <> 0) and (token = frunsequence) then begin + doevent(token,gek_stopped,values); + end + else begin + if assigned(fonevent) and (eventkind = gek_writeerror) or + not ((eventkind = gek_stopped) and (gs_interrupted in fstate)) and + not ((eventkind = gek_running) and + ([gs_attaching,gs_restarted] * fstate <> [])) and + not ((eventkind = gek_error) and (fsyncsequence <> 0) and + (integer(token-fsyncsequence) < 0)) and + ((token = 0) or (token <> fsyncsequence) or (eventkind = gek_running) or + (eventkind = gek_stopped)) then begin + ev:= tgdbevent.create(ek_none,ievent(self)); + ev.eventkind:= eventkind; + ev.values:= copy(values); + ev.flastconsoleoutput:= flastconsoleoutput; + ev.fthreadid:= id1; + application.postevent(ev); + end; + if eventkind = gek_running then begin + exclude(fstate,gs_restarted); + end; + end; + end; +end; + +procedure tgdbmi.postsyncerror; +begin + doevent(0,gek_error,fsyncvalues); +end; + +procedure tgdbmi.sequenceend; +begin +{ + if fsequence = 1 then begin //startup + consoleoutput('(gdb)'); + end; +} +end; + +function tgdbmi.decodelist(const noname: boolean; const inp: string; + var value: resultinfoarty): boolean; +var + po1: pchar; + int1: integer; + str1: string; +begin + result:= true; + value:= nil; + if (pointer(inp) <> nil) then begin + str1:= inp; //avoid stringrelease + po1:= pchar(str1); + int1:= 0; + while true do begin + if int1 > high(value) then begin + setlength(value,int1+16); + end; + decoderesult(noname,po1,value[int1]); + inc(int1); + if (po1 = nil) or (po1^ <> ',') then begin + break; + end; + inc(po1); + end; + setlength(value,int1); + str1:= ''; //avoid stringrelease + end; +end; + +procedure tgdbmi.interpret(const line: string); + +var + po1,po2: pchar; + token: longword; + ch1: char; + recordclass: recordclassty; + isconsole: boolean; + resultar: resultinfoarty; + + function getrecordinfo(start,stop: recordclassty): boolean; + var + int1: integer; + begin + result:= false; + int1:= length(resultar); + for start:= start to stop do begin + if startsstr(pchar(recordclassnames[start]),po2) then begin + po2:= po2 + length(recordclassnames[start]); + recordclass:= start; + result:= true; + while (po2 <> nil) and (po2^ = ',') do begin + if int1 > high(resultar) then begin + setlength(resultar,2*high(resultar)+8); + end; + inc(po2); + decoderesult(recordclassnoname[recordclass],po2,resultar[int1]); + inc(int1); + end; + break; + end; + end; + setlength(resultar,int1); + end; + +var + targetoutp: boolean; + +begin +//{$ifdef mse_debuggdb} +// debugwriteln(line); +//{$endif} + resultar:= nil; + po1:= pchar(line); + po2:= po1; + while (po2^ >= '0') and (po2^ <= '9') do begin + inc(po2); + end; + if po2 <> po1 then begin + if not trystrtoint(psubstr(po1,po2),token) then begin + token:= 0; + end; + end + else begin + token:= 0; + end; + isconsole:= (token <> 0) and (token = fconsolesequence); + if isconsole then begin + fconsolesequence:= 0; + end; + ch1:= po2^; + inc(po2); + try + targetoutp:= false; + case ch1 of + '~': begin + if gs_clicommand in fstate then begin + if gs_clilist in fstate then begin + setlength(fclivaluelist,high(fclivaluelist)+2); + fclivaluelist[high(fclivaluelist)]:= cstringtostring(po2); + end + else begin + fclivalues:= fclivalues + cstringtostring(po2); + end; + end + else begin + flastconsoleoutput:= cstringtostring(po2); + consoleoutput(flastconsoleoutput); + end; + end; + '@': targetoutput(cstringtostring(po2)); + '&': logoutput(cstringtostring(po2)); + '^': begin //result + if getrecordinfo(low(resultclassty),high(resultclassty)) then begin + case recordclass of + rec_connected: begin + doevent(token,gek_connected,resultar); + end; + rec_running: begin + if not (gs_stopped in fstate) then begin + //no breakpoint while GUI_DEBUGBEGIN + doevent(token,gek_running,resultar); + end; + end; + rec_done: begin + if isconsole then begin + consoleoutput('(gdb)'); + end; + doevent(token,gek_done,resultar); + end; + rec_error: begin + if isconsole then begin + if high(resultar) >= 0 then begin + consoleoutput(resultar[0].value+#$0a'(gdb)'); + end; + end; + doevent(token,gek_error,resultar); + end; + end; + end + else begin + targetoutp:= true; + end; + end; + '*','+','=': begin + if getrecordinfo(low(asyncclassty),high(asyncclassty)) then begin + case recordclass of + rec_stopped: begin + include(fstate,gs_stopped); + doevent(token,gek_stopped,resultar); + end; + rec_download: begin + doevent(token,gek_download,resultar); + end; + rec_threadselected: begin + if not getintegervalue(resultar,'id',fcurrthreadid) then begin + fcurrthreadid:= -1; + end; + end; + rec_threadgroupstarted: begin + getinteger64value(resultar,'pid',fcurrentprocid); + end; + end; + end + else begin + targetoutp:= true; + end; + end; + '(': begin + if startsstr(pchar('gdb)'),po2) then begin + sequenceend; + end; + end; + else begin + targetoutp:= true; + end; + end; + if targetoutp and running then begin + targetoutput(line+lineend); + end; + except + end; +end; + +procedure tgdbmi.gdbpipebroken(const sender: tpipereader); +var + ev: tgdbevent; +begin + if (fgdb <> invalidprochandle) and not (gs_gdbdied in fstate) then begin + include(fstate,gs_gdbdied); + ev:= tgdbevent.create(ek_none,ievent(self)); + ev.eventkind:= gek_gdbdied; + ev.flastconsoleoutput:= flastconsoleoutput; + application.postevent(ev); + end; +end; +{ +procedure tgdbmi.gdberror(const sender: tpipereader); +var + str1: string; +begin +// if fgdberror.eof then begin +// exit; +// end; + str1:= fgdberror.readdatastring; + targetoutput(str1); +// writedebug(str1); +end; +} + +procedure tgdbmi.gdbfrom(const sender: tpipereader); +var + str1,str2: string; + b1,b2: boolean; + int1: integer; +begin + b1:= false; //compiler warning + repeat + (* + if gs_syncget in fstate then begin + bo1:= fgdbfrom.readstrln(str1); + //does not post pipereader semaphore in case of timeout + {$ifdef mse_debuggdb} + if bo1 then begin + debugwriteln(str1); + end; + {$endif} + end + else begin + *) + str1:= ''; + int1:= 0; + while true do begin + b1:= fgdbfrom.readuln(str2,b2); + {$ifdef mse_debuggdb} + if b1 then begin + debugwriteln(str2); + end + else begin + debugwrite(str2); + end; + {$endif} + str1:= str1 + str2; + if str2 <> '' then begin + int1:= 0; + end; + if b1 or (str1 = '') or (int1 > 10) then begin + break; + end; + sys_schedyield; + inc(int1); + sleep(100); //try to get the lineend + end; + { + end; + } + if b1 then begin + interpret(str1); + end + else begin + if str1 <> '' then begin + targetoutput(str1); + end; + end; + until not b2; //all data read +end; + +{$ifdef UNIX} +procedure tgdbmi.targetfrom(const sender: tpipereader); +begin + if not sender.eof then begin + targetoutput(sender.readdatastring); + end; +end; + +procedure tgdbmi.killtargetconsole; +begin + ftargetconsole.kill; + ftargetterminal.outecho:= false; +end; + +function tgdbmi.createtargetconsole: boolean; +var + ar1: stringarty; + pts,ptsn,ptsh: msestring; +begin + result:= false; + if fxtermcommand <> '' then begin + ptsn:= ''; + ftargetterminal.outecho:= true; + pts:= msestring(ftargetterminal.devicename); + ar1:= splitstring(ftargetterminal.devicename,'/'); + if ar1 <> nil then begin + ptsn:= msestring(ar1[high(ar1)]); + end; + ptsh:= inttostrmse(ftargetterminal.fpty); + ftargetconsole.commandline:= +{$ifdef FPC} + expandmacros(fxtermcommand,['PTS','PTSN','PTSH'],[pts,ptsn,ptsh], + [mao_caseinsensitive]); +{$else} + expandmacrosstr(fxtermcommand,['PTS','PTSN','PTSH'],[pts,ptsn,ptsh], + [mao_caseinsensitive]); +{$endif} + ftargetconsole.active:= true; + result:= ftargetconsole.running; + end; +end; + +procedure tgdbmi.xtermfrom(const sender: tpipereader); +begin + targetoutput(sender.readdatastring); +end; + +{$endif} + +function tgdbmi.internalcommand(acommand: string): boolean; +var + ar1: resultinfoarty; +begin + result:= false; + checkactive; + fgdbfrom.responseflag:= false; + try + fgdbto.writeln(inttostr(fsequence)+acommand); + {$ifdef mse_debuggdb} + debugwriteln('>'+inttostr(fsequence)+'>'+acommand); + {$endif} + result:= true; + except + closegdb; + setlength(ar1,1); + with ar1[0] do begin + variablename:= 'msg'; + valuekind:= vk_value; + value:= 'Can not write to gdb.'; + end; + doevent(fsequence,gek_writeerror,ar1); +// raise; + end; + inc(fsequence); + if fsequence = 0 then begin + inc(fsequence); + end; +end; + +procedure tgdbmi.consolecommand(acommand: string); +begin + internalcommand(acommand); + fconsolesequence:= fsequence; +end; + +function tgdbmi.source(const afilename: filenamety): gdbresultty; +begin + result:= synccommand('source '+ + ansistring(quotefilename(tosysfilepath(afilename)))); +end; + +function tgdbmi.synccommand(const acommand: string; + atimeout: integer = defaultsynctimeout): gdbresultty; +var + timestamp: longword; + int1: integer; + +begin + if not active then begin + result:= gdb_notactive; + exit; + end; + result:= gdb_timeout; + interrupttarget; + setlength(fsyncvalues,0); + fsyncsequence:= fsequence; + exclude(fstate,gs_syncack); + include(fstate,gs_syncget); + if not internalcommand(acommand) then begin + result:= gdb_writeerror; + exit; + end; + timestamp:= timestep(atimeout); //max delay + int1:= application.unlockall; + try + while not timeout(timestamp) do begin + if not (gs_syncack in fstate) then begin + if not fgdbfrom.waitforresponse(100000,true) then begin + if not fgdbfrom.active then begin + break; + end; + end; + end + else begin + if fsynceventkind = gek_error then begin + if getstringvalue(fsyncvalues,'msg',ferrormessage) then begin + result:= gdb_message; + end + else begin + result:= gdb_error; + end; + end + else begin + result:= gdb_ok; + end; + break; + end; + end; + finally + application.relockall(int1); + exclude(fstate,gs_syncget); + fsyncsequence:= 0; + restarttarget; + end; + if result = gdb_timeout then begin + ferrormessage:= 'Timeout.'; + end; +end; + +function tgdbmi.geterrormessage(const aresult: gdbresultty): string; +begin + if aresult = gdb_message then begin + result:= errormessage; + end + else begin + if (aresult < low(gdbresultty)) or (aresult > high(gdbresultty)) then begin + result:= 'GDB Error ' + inttostr(ord(aresult)); + end + else begin + result:= gdberrortexts[aresult]; + end; + end; +end; + +function tgdbmi.micommand(const command: string; + out values: resultinfoarty): gdbresultty; + //values = nil on timeout +begin + result:= synccommand('-'+command); + values:= fsyncvalues; +end; + +function tgdbmi.togdbfilepath(const filename: filenamety): filenamety; +begin + result:= quotefilename(tosysfilepath(filepath(filename))); + {$ifdef mswindows} + replacechar1(result,msechar('\'),msechar('/')); + {$endif} +end; + +function tgdbmi.fileexec(const filename: filenamety; + const noproginfo: boolean = false): gdbresultty; +const + {$ifdef cpuarm} + loadwaitus = 20000000; + {$else} + loadwaitus = 10000000; + {$endif} +var + int1: integer; +begin + abort; + resetexec; + if filename = '' then begin + breakdelete(0); + result:= synccommand('-file-exec-and-symbols'); + end + else begin + if floadtimeoutus = 0 then begin + int1:= loadwaitus; + end + else begin + int1:= floadtimeoutus; + end; + result:= synccommand('-file-exec-and-symbols '+ + ansistring(togdbfilepath(filename)),int1); + updatebit({$ifdef FPC}longword{$else}longword{$endif}(fstate), + ord(gs_execloaded),result = gdb_ok); + if (result = gdb_ok) and not noproginfo then begin + initinternalbkpts; + initproginfo; + end; + end; +end; + +function tgdbmi.filesymbol(const filename: filenamety): gdbresultty; +begin + abort; + resetexec; + if filename = '' then begin + breakdelete(0); + result:= synccommand('-file-symbol-file'); + end + else begin + result:= synccommand('-file-symbol-file '+ansistring(togdbfilepath(filename)), + 10000000); +// updatebit({$ifdef FPC}longword{$else}longword{$endif}(fstate), +// ord(gs_execloaded),result = gdb_ok); + if result = gdb_ok then begin + initinternalbkpts; + initproginfo; + end; + end; +end; + +function tgdbmi.attach(const procid: longword; out info: stopinfoty): gdbresultty; +var + frames1: frameinfoarty; + wo1: longword; + int1: integer; +begin + abort; + resetexec; + fstate:= fstate+[gs_attaching{,gs_stopped}]; + result:= clicommand('attach '+inttostr(procid),false,10000000); + if result = gdb_ok then begin + wo1:= timestep(5000000); //5 seconds, sometimes necessary for + while (gs_internalrunning in fstate) and not timeout(wo1) do begin + int1:= application.unlockall; + sleepus(50000); //win32 gdb 7.2 sends ^running + application.relockall(int1); + end; + if gs_internalrunning in fstate then begin + result:= gdb_timeout; + end; + end; + exclude(fstate,gs_attaching); + finalize(info); + fillchar(info,sizeof(info),0); + info.reason:= sr_error; + if result = gdb_ok then begin +// if getprocid(fprocid) and (fprocid = procid) then begin + //win32 gdb 7.1 crashes with "info program" + fprocid:= procid; + include(self.fstate,gs_canstop); + result:= stacklistframes(frames1,0,1); + if (result = gdb_ok) or (result = gdb_message) then begin + if result = gdb_message then begin + info.messagetext:= errormessage; + result:= gdb_ok; + end + else begin + info.reason:= sr_startup; + fstate:= fstate + [gs_execloaded,gs_attached,gs_started,gs_startup]; + with frames1[0] do begin + info.filename:= filename; + info.line:= line; + info.messagetext:= 'Attached to process '+inttostr(procid) + ' File: '+ + ansistring(filename)+':'+inttostr(line)+' Function: '+func; + end; + end; +// end; + initinternalbkpts; + initproginfo; + end + else begin + info.messagetext:= 'Can not Attach to process '+inttostr(procid); + end; + end; + if result <> gdb_ok then begin + if result = gdb_message then begin + info.messagetext:= errormessage; + end + else begin + info.messagetext:= gdberrortexts[result]; + end; + end; +end; + +function tgdbmi.attachtarget(out info: stopinfoty): gdbresultty; +var + frames1: frameinfoarty; +begin + abort; + resetexec; + result:= gdb_ok; + finalize(info); + fillchar(info,sizeof(info),0); + info.reason:= sr_error; + result:= checkconnection(true); + if result = gdb_ok then begin + result:= stacklistframes(frames1,0,1); + if (result = gdb_ok) or (result = gdb_message) then begin + if result = gdb_message then begin + info.messagetext:= errormessage; + result:= gdb_ok; + end + else begin + info.reason:= sr_startup; + fstate:= fstate + [gs_execloaded,gs_attached, + gs_started,gs_startup,gs_canstop]; + with frames1[0] do begin + info.filename:= filename; + info.line:= line; + info.messagetext:= 'Attached to target ' + ' File: '+ + ansistring(filename)+':'+inttostr(line)+' Function: '+func; + end; + end; + end; + initinternalbkpts; + initproginfo; + end; + if result <> gdb_ok then begin + if result = gdb_message then begin + info.messagetext:= errormessage; + end + else begin + info.messagetext:= gdberrortexts[result]; + end; + end; +end; + +function tgdbmi.detach: gdbresultty; +var + ev: tgdbevent; +begin + result:= synccommand('-target-detach'); + if result = gdb_ok then begin + ev:= tgdbevent.create(ek_none,ievent(self)); + ev.eventkind:= gek_stopped; + setlength(ev.values,1); + with ev.values[0] do begin + variablename:= 'reason'; + valuekind:= vk_value; + value:= 'detached'; + end; + resetexec; + include(fstate,gs_detached); + application.postevent(ev); + end; +end; + +function tgdbmi.download(const runafterload: boolean): gdbresultty; +begin + result:= checkconnection(false); + if result = gdb_ok then begin + if fbeforeload <> '' then begin + result:= source(fbeforeload); + end; + if result = gdb_ok then begin + if not internalcommand('-target-download') then begin + result:= gdb_writeerror; + end + else begin + fstate:= fstate + [gs_downloading,gs_runafterload]; + if not runafterload then begin + exclude(fstate,gs_runafterload); + end; + end; + end; + end; +end; + +procedure tgdbmi.checkpointersize; +var + str1: string; + int1: integer; +begin + fpointersize:= 4; + if (evaluateexpression('sizeof($pc)',str1) = gdb_ok) or + + (evaluateexpression('sizeof(void*)',str1) = gdb_ok) or + //does not work on gdb win64 7.9 + (evaluateexpression('sizeof(pointer)',str1) = gdb_ok) then begin + //I know there is a gdbcommand for this, I could not find it + if trystrtoint(str1,int1) then begin + fpointersize:= int1; + end; + end + else begin + if (clicommand('show architecture') = gdb_ok) and + (pos('x86-64',fclivalues) > 0) then begin + fpointersize:= 8; + end; + end; + fpointerhexdigits:= 2*fpointersize; +end; + +procedure tgdbmi.updateenvvars(); +var + int1: integer; +begin + for int1:= 0 to high(fenvvars) do begin + with fenvvars[int1] do begin + if unset then begin + unsetenv(name); + end + else begin + setenv(name,value); + end; + end; + end; +end; + +procedure tgdbmi.dorun; +var + int1: integer; + ar1,ar2: stringarty; + ca1: qword; + str1: string; + frames1: frameinfoarty; + ev: tgdbstartupevent; +begin +{$ifdef unix} + killtargetconsole; + if fnewconsole then begin + if not createtargetconsole then begin + raise exception.create('Can not run '+ansistring(ftargetconsole.filename)); + end; + end; +{$endif} + fstartupbreakpoint:= -1; + fstartupbreakpoint1:= -1; + exclude(fstate,gs_startup); + if fbeforerun <> '' then begin + if source(fbeforerun) <> gdb_ok then begin + postsyncerror; + exit; + end; + end; + checkpointersize; + str1:= ''; + if fstartupbkpton then begin + fstartupbreakpoint:= breakinsert(fstartupbkpt); + end + else begin + if (gs_remote in fstate) and + (stacklistframes(frames1,0,1) = gdb_ok) then begin + //already started by gdbserver + ev:= tgdbstartupevent.create(ievent(self)); + with ev do begin + stopinfo.reason:= sr_startup; + with frames1[0] do begin + stopinfo.addr:= addr; + stopinfo.filename:= filename; + stopinfo.line:= line; + stopinfo.messagetext:= 'Startup. File: '+ + ansistring(filename)+':'+inttostr(line)+' Function: '+func; + end; + end; + include(fstate,gs_started); + application.postevent(ev); + exit; + end; + if getcliresult('info file',ar1) = gdb_ok then begin + for int1:= 0 to high(ar1) do begin + if startsstr('Entry point',ar1[int1]) then begin + ar2:= nil; + splitstring(ar1[int1],ar2,' '); + if high(ar2) >= 2 then begin + str1:= ar2[2]; + end; + break; + end; + end; + end; + if str1 <> '' then begin + if trystrtointvalue64(str1,ca1) then begin + fstartupbreakpoint:= breakinsert(ca1); //does not always work + fstartupbreakpoint1:= breakinsert(ca1+1); + if (fstartupbreakpoint < 0) and (fstartupbreakpoint1 < 0) then begin + str1:= ''; + end; + end + else begin + str1:= ''; + end; + end; + if str1 = '' then begin + fstartupbreakpoint:= breakinsert('main'); + end; + end; + synccommand('-exec-arguments '+ fprogparameters); + synccommand('-environment-cd '+ + ansistring(tosysfilepath(filepath(fworkingdirectory)))); + updateenvvars(); + //for remote gdbserver too late, process has already been created + {$ifdef mswindows} + if fnewconsole then begin + synccommand('-gdb-set new-console on'); + end + else begin + synccommand('-gdb-set new-console off'); + end; + {$endif} + if gs_remote in fstate then begin + sys_schedyield(); //maybe gdbserver has to work + sleepus(100000); + application.processmessages; //maybe gdbserver has sent a stop message + end; + if gs_remote in fstate then begin + internalcommand('-exec-continue'); + end + else begin + internalcommand('-exec-run'); + end; + include(fstate,gs_canstop); +end; + +function tgdbmi.checkconnection(const proginfo: boolean): gdbresultty; +begin + result:= gdb_ok; + if fbeforeconnect <> '' then begin + result:= source(fbeforeconnect); + end; + if result = gdb_ok then begin + if fremoteconnection <> '' then begin + if synccommand('-gdb-set target-async 1') = gdb_ok then begin + include(fstate,gs_async); + end; + result:= synccommand('-target-select '+ansistring(fremoteconnection)); + if result <> gdb_ok then begin + exit; + end; + include(fstate,gs_remote); + if proginfo then begin + initproginfo; + end; + end + else begin + {result:= }synccommand('-gdb-set target-async 0'); //fails on older gdb's + end; + end; + if result = gdb_ok then begin + if fafterconnect <> '' then begin + result:= source(fafterconnect); + end; + end; +end; + +function tgdbmi.tryconnect: boolean; +begin + result:= fremoteconnection = ''; + result:= result or + (synccommand('-target-select '+ansistring(fremoteconnection)) = gdb_ok); +end; + +function tgdbmi.run: gdbresultty; +begin + result:= gdb_ok; + if fsimulator then begin + result:= synccommand('-target-select sim'); + if result = gdb_ok then begin + result:= synccommand('-target-download'); + if result = gdb_ok then begin + dorun; + end; + end; + end + else begin + if fgdbdownload and not (gs_downloaded in fstate) then begin + result:= download(true); + end + else begin + result:= checkconnection(true); + if result = gdb_ok then begin + dorun; + end; + end; + end; +end; + +procedure tgdbmi.continue; +begin + debugend; + internalcommand('-exec-continue'); +end; + +procedure tgdbmi.next; +begin + debugend; + internalcommand('-exec-next'); +end; + +procedure tgdbmi.step; +begin + debugend; + internalcommand('-exec-step'); +end; + +procedure tgdbmi.finish; +begin + debugend; + internalcommand('-exec-finish'); +end; + +procedure tgdbmi.nexti; +begin + debugend; + internalcommand('-exec-next-instruction'); +end; + +procedure tgdbmi.stepi; +begin + debugend; + internalcommand('-exec-step-instruction'); +end; + +procedure tgdbmi.interrupt; +{$ifdef mswindows} +type + createremotethreadty = function(hProcess: THandle; lpThreadAttributes: Pointer; + dwStackSize: DWORD; lpStartAddress: TFNThreadStartRoutine; + lpParameter: Pointer; dwCreationFlags: DWORD; var lpThreadId: DWORD): THandle; stdcall; +var + prochandle,modhandle,threadhandle: thandle; + debugbreakaddr: pointer; + createremotethreadaddr: createremotethreadty; + bo1: boolean; +{$endif mswindows} +begin +// internalcommand('-exec-interrupt'); + if fprocid <> 0 then begin + {$ifdef mswindows} + {$ifdef mse_usedebugbreakprocess} + if debugbreakprocess <> nil then begin + debugbreakprocess(fprocid); + end + else begin + {$endif} + prochandle:= openprocess( + PROCESS_CREATE_THREAD or PROCESS_QUERY_INFORMATION or PROCESS_VM_OPERATION or + PROCESS_VM_WRITE or PROCESS_VM_READ, False, fprocid); + if prochandle <> 0 then begin + bo1:= false; + modhandle:= GetModuleHandle(kernel32); + if modhandle <> 0 then begin + debugbreakaddr:= windows.getprocaddress(modhandle,'DebugBreak'); + if debugbreakaddr <> nil then begin + {$ifdef FPC}pointer(createremotethreadaddr){$else} + createremotethreadaddr{$endif}:= windows.GetProcAddress(modhandle, 'CreateRemoteThread'); + if assigned(createremotethreadaddr) then begin + threadhandle:= createremotethreadaddr(prochandle, nil, 0, debugbreakaddr, + nil, 0, finterruptthreadid); + if threadhandle <> 0 then begin + closehandle(threadhandle); + bo1:= true; + end; + end; + end; + end; + closehandle(prochandle); + if not bo1 then begin + GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, fprocid); + //for win95 + end; + end; + {$ifdef mse_usedebugbreakprocess} + end; + {$endif} + {$else} + kill(fprocid,sigint); + {$endif !mswindows} + end + else begin + if gs_async in fstate then begin + internalcommand('-exec-interrupt'); //runs in async mode + end + else begin + {$ifdef unix} //how to do on windows? + kill(fgdb,sigint); + {$else} + internalcommand('-exec-interrupt'); //probably no success because + //not in async mode + {$endif} + end; + end; +end; + +function tgdbmi.interrupttarget: gdbresultty; //stop for breakpointsetting +var + timestamp: longword; + int1: integer; +begin + result:= gdb_ok; + inc(finterruptcount); + if finterruptcount = 1 then begin + timestamp:= timestep(1000000); + if (gs_internalrunning in fstate) then begin + include(fstate,gs_interrupted); + interrupt; + int1:= application.unlockall; + repeat + sleep(10); + until not (gs_internalrunning in fstate) or timeout(timestamp); + application.relockall(int1); + if (gs_internalrunning in fstate) then begin + exclude(fstate,gs_interrupted); + dec(finterruptcount); + result:= gdb_timeout; + end; + end; + end; +end; + +function tgdbmi.restarttarget: gdbresultty; +begin + if finterruptcount > 0 then begin + dec(finterruptcount); + if finterruptcount = 0 then begin + if gs_interrupted in fstate then begin + exclude(fstate,gs_interrupted); + include(fstate,gs_restarted); + exclude(fstate,gs_stopped); + internalcommand('-exec-continue'); +// continue; + end; + end; + end; + result:= gdb_ok; +end; + +procedure tgdbmi.abort; +begin +// internalcommand('-exec-abort'); + if started and (interrupttarget = gdb_ok) then begin + exclude(fstate,gs_interrupted); + clicommand('kill'); + finterruptcount:= 0; + end + else begin + if downloading then begin + closegdb; + end; + end; +end; + +procedure tgdbmi.initinternalbkpts; +begin + fexceptionbkpt:= breakinsert('FPC_RAISEEXCEPTION'); + if fexceptionbkpt < 0 then begin + fexceptionbkpt:= breakinsert('__mla__raise'); + end; + if not fstoponexception and (fexceptionbkpt > 0) then begin + breakenable(fexceptionbkpt,false); //disable breakpoint + end; +end; + +procedure tgdbmi.initproginfo; +var + info1: stopinfoty; + ek1: gdbeventkindty; +begin + checkpointersize; + if fguiintf then begin + getprocaddress('MSEGUIINTF_GUI_DEBUGBEGIN',ftargetdebugbegin); + if ftargetdebugbegin = 0 then begin + getprocaddress('MSEGUIINTF_$$_GUI_DEBUGBEGIN',ftargetdebugbegin); + end; + getprocaddress('MSEGUIINTF_GUI_DEBUGEND',ftargetdebugend); + if ftargetdebugend = 0 then begin + getprocaddress('MSEGUIINTF_$$_GUI_DEBUGEND',ftargetdebugend); + end; + end + else begin + ftargetdebugbegin:= 0; + ftargetdebugend:= 0; + end; + if assigned(fonevent) then begin + initstopinfo(info1); + ek1:= gek_loaded; + fonevent(self,ek1,nil,info1); + end; +end; + +function tgdbmi.getbkptid: integer; +var + tup1: resultinfoarty; +begin + result:= -1; + if gettuplevalue(fsyncvalues,'bkpt',tup1) then begin + getintegervalue(tup1,'number',result); + end; + if result <> -1 then begin + flastbreakpoint:= result; + end; +end; + +function tgdbmi.getwptid: integer; +var + tup1: resultinfoarty; +begin + result:= -1; + if gettuplevalue(fsyncvalues,'wpt',tup1) or + gettuplevalue(fsyncvalues,'hw-awpt',tup1) or + gettuplevalue(fsyncvalues,'hw-rwpt',tup1) then begin + getintegervalue(tup1,'number',result); + end; +end; + +function tgdbmi.handle(const signame: string; const aflags: sigflagsty): gdbresultty; +var + str1: string; +begin + if sfl_stop in aflags then begin + str1:= 'stop'; + end + else begin + str1:= 'noprint'; + end; + if sfl_handle in aflags then begin + str1:= str1 + ' nopass'; + end + else begin + str1:= str1 + ' pass'; + end; + result:= clicommand('handle '+signame+' '+str1); +end; + +function tgdbmi.breakinsert(var info: breakpointinfoty): gdbresultty; +var + str1: string; +begin + with info do begin + interrupttarget; + flogtext:= ''; + if addressbreakpoint then begin + str1:= '*'+hextocstr(address,8) + end + else begin + str1:= ansistring(filename(path))+':'+inttostr(line); + end; + result:= synccommand('-break-insert '+ str1); + if (result = gdb_ok) or (result = gdb_message) then begin + if (result = gdb_ok) and (flogtext <> '') or (result = gdb_message) then begin + bkptno:= -1; + result:= clicommand('break '+str1); + inc(flastbreakpoint); + bkptno:= flastbreakpoint; + end + else begin + bkptno:= getbkptid; + end; + if bkptno < 0 then begin + result:= gdb_error; + end + else begin + if not bkpton then begin + result:= breakenable(bkptno,false); + end; + if (result = gdb_ok) and (ignore > 0) then begin + result:= breakafter(bkptno,ignore); + end; + if (result = gdb_ok) and (condition <> '') then begin + result:= breakcondition(bkptno,condition); + if result = gdb_message then begin + conditionmessage:= errormessage; + end; + end; + end; + end + else begin + bkptno:= -1; + end; + restarttarget; + end; +end; + +function tgdbmi.breakinsert(const funcname: string): integer; +begin + if synccommand('-break-insert '+funcname) <> gdb_ok then begin + result:= -1; + end + else begin + result:= getbkptid; + end; +end; + +function tgdbmi.breakinsert(const address: qword): integer; +begin + if synccommand('-break-insert *'+hextocstr(address,0)) <> gdb_ok then begin + result:= -1; + end + else begin + result:= getbkptid; + end; +end; + +function tgdbmi.watchinsert(var info: watchpointinfoty): gdbresultty; +var + str1: string; +begin + with info do begin + case kind of + wpk_readwrite: str1:= ' -a '; + wpk_read: str1:= ' -r '; + else str1:= ' '; + end; + result:= synccommand('-break-watch' + str1 + expression); + if result = gdb_ok then begin + wptno:= getwptid; + if wptno < 0 then begin + result:= gdb_error; + end + else begin + if (result = gdb_ok) and (ignore > 0) then begin + result:= breakafter(wptno,ignore); + end; + if (result = gdb_ok) and (condition <> '') then begin + result:= breakcondition(wptno,condition); + if result = gdb_message then begin + conditionmessage:= errormessage; + end; + end; + end; + { + if not bkpton then begin + result:= breakenable(bkptno,false); + end; + if (result = gdb_ok) and (ignore > 0) then begin + result:= breakafter(bkptno,ignore); + end; + if (result = gdb_ok) and (condition <> '') then begin + result:= breakcondition(bkptno,condition); + if result = gdb_message then begin + conditionmessage:= errormessage; + end; + end; + end; + } + end + else begin + wptno:= -1; + end; + end; +end; + +function tgdbmi.getfullname(const tup: resultinfoarty): string; +begin + result:=''; + if not getstringvalue(tup,'fullname',result) or (result = '') then begin + getstringvalue(tup,'file',result); + end; +end; + +function tgdbmi.getbreakpointinfo(var atup: resultinfoty; + var info: breakpointinfoty; + const full: boolean): boolean; +var + tup1: resultinfoarty; + filename: string; +begin + result:= gettuplevalue(atup,tup1); + if result then begin + with info do begin + getintegervalue(tup1,'number',bkptno); + getintegervalue(tup1,'times',passcount); + getqwordvalue(tup1,'addr',address); + if full then begin + getintegervalue(tup1,'line',line); + filename:= getfullname(tup1); + if filename <> '' then begin + path:= msestring(filename); + end; + getbooleanvalue(tup1,'enabled',bkpton); + end; + end; + end; +end; + +function tgdbmi.breaklist(var list: breakpointinfoarty; + const full: boolean): gdbresultty; +var + ar1: resultinfoarty; + int1: integer; + tup1: resultinfoarty; +begin + result:= synccommand('-break-list'); + if result = gdb_ok then begin + result:= gdb_error; + if gettuplevalue(fsyncvalues,'BreakpointTable',tup1) then begin + if getarrayvalue(tup1,'body',true,ar1) then begin + setlength(list,length(ar1)); + for int1:= 0 to high(ar1) do begin + getbreakpointinfo(ar1[int1],list[int1],full); + end; + result:= gdb_ok; + end; + end; + end; +end; + +function tgdbmi.infobreakpoint(var info: breakpointinfoty; + const full: boolean = true): gdbresultty; +var + ar1: resultinfoarty; + tup1: resultinfoarty; +begin + result:= synccommand('-break-info '+inttostr(info.bkptno)); + if result = gdb_ok then begin + result:= gdb_error; + if gettuplevalue(fsyncvalues,'BreakpointTable',tup1) then begin + if getarrayvalue(tup1,'body',true,ar1) then begin + if high(ar1) = 0 then begin + if getbreakpointinfo(ar1[0],info,full) then begin + result:= gdb_ok; + end; + end; + end; + end; + end; +end; + +function tgdbmi.breakdelete(bkptnum: integer): gdbresultty; +begin + if bkptnum = 0 then begin + result:= synccommand('-break-delete'); + initinternalbkpts; + end + else begin + result:= synccommand('-break-delete '+inttostr(bkptnum)); + end; +end; + +function tgdbmi.breakenable(bkptnum: integer; value: boolean): gdbresultty; //bkptnum = 0 -> all +begin + if value then begin + if bkptnum = 0 then begin + result:= synccommand('-break-enable'); + end + else begin + result:= synccommand('-break-enable '+inttostr(bkptnum)); + end; + end + else begin + if bkptnum = 0 then begin + result:= synccommand('-break-disable'); + end + else begin + result:= synccommand('-break-disable '+inttostr(bkptnum)); + end; + end; +end; + +function tgdbmi.breakafter(bkptnum: integer; const passcount: integer): gdbresultty; +begin + result:= synccommand('-break-after '+inttostr(bkptnum)+' '+inttostr(passcount)); +end; + +function tgdbmi.breakcondition(bkptnum: integer; + const condition: string): gdbresultty; +begin + result:= synccommand('-break-condition '+inttostr(bkptnum)+' '+condition); +end; + +function tgdbmi.getvalueindex(const response: resultinfoarty; + const aname: string): integer; +var + int1: integer; +begin + result:= -1; + for int1:= 0 to high(response) do begin + if response[int1].variablename = aname then begin + result:= int1; + break; + end; + end; +end; + +function tgdbmi.getstringvalue(const response: resultinfoarty; const aname: string; + var avalue: string): boolean; +var + int1: integer; +begin + result:= false; + int1:= getvalueindex(response,aname); + if int1 >= 0 then begin + with response[int1] do begin + if valuekind = vk_value then begin + avalue:= value; + result:= true; + end; + end; + end; +end; + +function tgdbmi.getstringvalue(const response: resultinfoty; const aname: string; + var avalue: string): boolean; +var + ar1: resultinfoarty; +begin + setlength(ar1,1); + ar1[0]:= response; + result:= getstringvalue(ar1,aname,avalue); +end; + +function tgdbmi.getqwordvalue(const response: resultinfoarty; + const aname: string; var avalue: qword): boolean; +var + int1: integer; +begin + result:= false; + int1:= getvalueindex(response,aname); + if int1 >= 0 then begin + with response[int1] do begin + if valuekind = vk_value then begin + if (length(value) > 1) and (value[1] = '0') and (value[2] <> 'x') and + (value[2] <> 'X') then begin + result:= trystrtointvalue64(msestring(value),nb_oct,avalue); + end + else begin + result:= trystrtointvalue64(value,avalue); + end; + end; + end; + end; +end; + +function tgdbmi.getintegervalue(const response: resultinfoarty; const aname: string; + var avalue: integer): boolean; +var + qwo1: qword; +begin + qwo1:= avalue; + result:= getqwordvalue(response,aname,qwo1); + avalue:= qwo1; +end; + +function tgdbmi.getinteger64value(const response: resultinfoarty; const aname: string; + var avalue: int64): boolean; +var + qwo1: qword; +begin + qwo1:= avalue; + result:= getqwordvalue(response,aname,qwo1); + avalue:= qwo1; +end; + + +function tgdbmi.getqwordvalue(const response: resultinfoty; const aname: string; + var avalue: qword): boolean; + +var + ar1: resultinfoarty; +begin + setlength(ar1,1); + ar1[0]:= response; + result:= getqwordvalue(ar1,aname,avalue); +end; + +function tgdbmi.getbooleanvalue(const response: resultinfoarty; const aname: string; + var avalue: boolean): boolean; +var + int1: integer; +begin + result:= false; + int1:= getvalueindex(response,aname); + if int1 >= 0 then begin + with response[int1] do begin + if valuekind = vk_value then begin + if value = 'y' then begin + avalue:= true; + result:= true; + end + else begin + if value = 'n' then begin + avalue:= false; + result:= true; + end; + end; + end; + end; + end; +end; + +function tgdbmi.getintegervalue(const response: resultinfoty; const aname: string; + var avalue: integer): boolean; +var + qwo1: qword; +begin + qwo1:= avalue; + result:= getqwordvalue(response,aname,qwo1); + avalue:= qwo1; +end; + +function tgdbmi.getinteger64value(const response: resultinfoty; const aname: string; + var avalue: int64): boolean; +var + qwo1: qword; +begin + qwo1:= avalue; + result:= getqwordvalue(response,aname,qwo1); + avalue:= qwo1; +end; + +procedure setstringnum(var dataarray; const index: integer; const text: string); +begin + stringarty(dataarray)[index]:= text; +end; + +procedure setbytenum(var dataarray; const index: integer; const text: string); +begin + bytearty(dataarray)[index]:= strtointvalue(text); +end; + +procedure setwordnum(var dataarray; const index: integer; const text: string); +begin + wordarty(dataarray)[index]:= strtointvalue(text); +end; + +procedure setlongwordnum(var dataarray; const index: integer; const text: string); +begin + longwordarty(dataarray)[index]:= strtointvalue(text); +end; + +procedure setqwordnum(var dataarray; const index: integer; const text: string); +begin + card64arty(dataarray)[index]:= strtointvalue64(text); +end; + +procedure setstringlen(var dataarray; const len: integer); +begin + setlength(stringarty(dataarray),len); +end; + +procedure setbytelen(var dataarray; const len: integer); +begin + setlength(bytearty(dataarray),len); +end; + +procedure setwordlen(var dataarray; const len: integer); +begin + setlength(wordarty(dataarray),len); +end; + +procedure setlongwordlen(var dataarray; const len: integer); +begin + setlength(longwordarty(dataarray),len); +end; + +procedure setqwordlen(var dataarray; const len: integer); +begin + setlength(card64arty(dataarray),len); +end; + +function tgdbmi.getnumarrayvalue(const response: resultinfoarty; const aname: string; + var avalue; setnumproc: setnumprocty; setlenproc: setlenprocty): boolean; +var + int1: integer; + po1,po2: pchar; + str1: string; +begin + result:= false; + bytearty(avalue):= nil; + int1:= getvalueindex(response,aname); + if int1 >= 0 then begin + with response[int1] do begin + if valuekind = vk_list then begin + if value = '' then begin + result:= true; + end + else begin + int1:= 0; + po1:= pointer(value); + while po1^ <> #0 do begin + if po1^ <> '"' then begin + break; + end; + inc(po1); + po2:= po1; + while (po2^ <> '"') and (po2^ <> #0) do begin + inc(po2); + end; + str1:= psubstr(po1,po2); + if high(bytearty(avalue)) < int1 then begin + setlenproc(avalue,int1+16); + end; + try + setnumproc(avalue,int1,str1); + except + bytearty(avalue):= nil; + exit; + end; + inc(int1); + inc(po2); + if po2^ = ',' then begin + inc(po2); + end; + po1:= po2; + end; + setlenproc(avalue,int1); + result:= true; + end; + end; + end; + end; +end; + +function tgdbmi.getstringarrayvalue(const response: resultinfoarty; const aname: string; + var avalue: stringarty): boolean; +begin + result:= getnumarrayvalue(response,aname,avalue,{$ifdef FPC}@{$endif}setstringnum,{$ifdef FPC}@{$endif}setstringlen); +end; + +function tgdbmi.getbytearrayvalue(const response: resultinfoarty; const aname: string; + var avalue: bytearty): boolean; +begin + result:= getnumarrayvalue(response,aname,avalue,{$ifdef FPC}@{$endif}setbytenum,{$ifdef FPC}@{$endif}setbytelen); +end; + +function tgdbmi.getwordarrayvalue(const response: resultinfoarty; const aname: string; + var avalue: wordarty): boolean; +begin + result:= getnumarrayvalue(response,aname,avalue,{$ifdef FPC}@{$endif}setwordnum, + {$ifdef FPC}@{$endif}setwordlen); +end; + +function tgdbmi.getlongwordarrayvalue(const response: resultinfoarty; const aname: string; + var avalue: longwordarty): boolean; +begin + result:= getnumarrayvalue(response,aname,avalue,{$ifdef FPC}@{$endif}setlongwordnum, + {$ifdef FPC}@{$endif}setlongwordlen); +end; + +function tgdbmi.getqwordarrayvalue(const response: resultinfoarty; + const aname: string; var avalue: card64arty): boolean; +begin + result:= getnumarrayvalue(response,aname,avalue,{$ifdef FPC}@{$endif}setqwordnum, + {$ifdef FPC}@{$endif}setqwordlen); +end; + +function tgdbmi.getenumvalue(const response: resultinfoarty; const aname: string; + const enums: array of string; var avalue: integer): boolean; +var + int1: integer; +begin + result:= false; + int1:= getvalueindex(response,aname); + if (int1 >= 0) then begin + with response[int1] do begin + if valuekind = vk_value then begin + for int1:= 0 to high(enums) do begin + if value = enums[int1] then begin + avalue:= int1; + result:= true; + break; + end; + end; + end; + end; + end; +end; + +function tgdbmi.gettuplevalue(const response: resultinfoty; + var avalue: resultinfoarty): boolean; +begin + with response do begin + if valuekind = vk_tuple then begin + result:= decodelist(false,value,avalue); + end + else begin + result:= false; + end; + end; +end; + +function tgdbmi.gettuplevalue(const response: resultinfoty; const aname: string; + var avalue: resultinfoarty): boolean; +begin + with response do begin + if (valuekind = vk_tuple) and (variablename = aname) then begin + result:= decodelist(false,value,avalue); + end + else begin + result:= false; + end; + end; +end; + +function tgdbmi.gettuplevalue(const response: resultinfoarty; + const aname: string; var avalue: resultinfoarty): boolean; +var + int1: integer; +begin + result:= false; + int1:= getvalueindex(response,aname); + if (int1 >= 0) then begin + result:= gettuplevalue(response[int1],avalue); + end; +end; + +function tgdbmi.gettuplestring(const response: resultinfoarty; const aname: string; + var avalue: string): boolean; +var + int1: integer; +begin + result:= false; + int1:= getvalueindex(response,aname); + if (int1 >= 0) then begin + with response[int1] do begin + if valuekind = vk_tuple then begin + avalue:= value; + result:= true; + end; + end; + end; +end; + +function tgdbmi.getarrayvalue(const response: resultinfoarty; + const aname: string; const hasitemnames: boolean; var avalue: resultinfoarty): boolean; +var + int1: integer; +begin + result:= false; + int1:= getvalueindex(response,aname); + if (int1 >= 0) then begin + with response[int1] do begin + if valuekind = vk_list then begin + result:= decodelist(not hasitemnames,value,avalue); + end; + end; + end; +end; + +function tgdbmi.gettuplearrayvalue(const response: resultinfoarty; const aname: string; + var avalue: resultinfoararty): boolean; +var + int1: integer; + ar1: resultinfoarty; +begin + result:= getarrayvalue(response,aname,false,ar1); + setlength(avalue,length(ar1)); + for int1:= 0 to high(ar1) do begin + if (ar1[int1].valuekind <> vk_tuple) or + not gettuplevalue(ar1[int1],avalue[int1]) then begin + result:= false; + break; + end; + end; +end; + +function tgdbmi.getsourcename(out path: filenamety; + out language: languagety;frame: integer = 0): gdbresultty; +var + strar1: stringarty; + int1: integer; + bo1: boolean; +// po1: pchar; + str1: string; + i1: int32; +begin + path:= ''; + str1:= ''; + language:= lan_undef; + if frame <> 0 then begin +// result:= synccommand('-stack-select-frame '+inttostr(frame)); //does not change soourcefile + result:= clicommand('frame ' + inttostr(frame)); + if result <> gdb_ok then begin + exit; + end; + end; + result:= getcliresult('info source',strar1); + if frame <> 0 then begin +// result:= synccommand('-stack-select-frame 0'); //does not change sourcefile + result:= clicommand('frame 0'); + end; + if result = gdb_ok then begin + bo1:= false; + for int1:= 0 to high(strar1) do begin +// if startsstr('Located in ',strar1[int1]) then begin +// path:= copy(strar1[int1],12,bigint); +// break; +// end +// else begin + if startsstr('Source language is ',strar1[int1]) then begin + i1:= findlastchar(strar1[int1],'.'); + if i1 > 0 then begin + str1:= copy(strar1[int1],20,i1-20); + end; + if str1 = 'pascal' then begin + language:= lan_pascal; + end; + end; + if path = '' then begin + if startsstr('Current source file is ',strar1[int1]) then begin + path:= msestring(copy(strar1[int1],24,bigint)); + end; + end + else begin + if not bo1 and startsstr('Compilation directory is ',strar1[int1]) then begin + path:= msestring(copy(strar1[int1],26,bigint)) + path; + bo1:= true; + end; + end; +// end; + end; + end; +end; + +function tgdbmi.getprocaddress(const procname: string; + out aaddress: qword): gdbresultty; +var + str1: string; + ar1: stringarty; + int1: integer; +begin + ar1:= nil; //compiler warning + aaddress:= 0; + result:= getcliresultstring('info address ' + procname,str1); + if result = gdb_ok then begin + result:= gdb_dataerror; + ar1:= splitstring(trim(str1),' ',true); + for int1:= 0 to high(ar1) do begin + str1:= ar1[int1]; + if startsstr('0x',str1) then begin + if str1[length(str1)] = '.' then begin + setlength(str1,length(str1)-1); + end; + if trystrtointvalue64(str1,aaddress) then begin + result:= gdb_ok; + end; + break; + end; + end; + end; +end; + +function tgdbmi.getstopinfo(const response: resultinfoarty; + const lastconsoleoutput: ansistring; + out info: stopinfoty): boolean; +var + int1: integer; + ar1: resultinfoarty; + frame: resultinfoarty; +// str1: string; + wstr1: filenamety; + frames1: frameinfoarty; + res1: gdbresultty; +begin + finalize(info); + fillchar(info,sizeof(info),0); + with info do begin + if response = nil then begin + info.reason:= sr_unknown; + res1:= stacklistframes(frames1,0,1); + result:= res1 = gdb_ok; + if result then begin + with frames1[0] do begin + info.filename:= filename; + info.line:= line; + info.messagetext:= 'Stopped. File: '+ + ansistring(filename)+':'+inttostr(line)+' Function: '+func; + end; + end + else begin + if res1 = gdb_message then begin + info.messagetext:= errormessage; + end + end; + end + else begin + if getenumvalue(response,'reason',stopreasons,int1) then begin + result:= true; + reason:= stopreasonty(int1); + end + else begin + reason:= sr_startup; + result:= false; + end; + if reason = sr_breakpoint_hit then begin + getintegervalue(response,'bkptno',info.bkptno); + if (info.bkptno = fstartupbreakpoint) or + (info.bkptno = fstartupbreakpoint1) then begin + reason:= sr_startup; + result:= false; + end; + end; + if reason = sr_signal_received then begin + getstringvalue(response,'signal-name',signalname); + getstringvalue(response,'signal-meaning',signalmeaning); + if fsimulator and (signalname = '0') then begin + signalmeaning:= lastconsoleoutput; + end; + end; + if reason = sr_watchpointtrigger then begin + if gettuplevalue(response,'wpt',ar1) then begin + getstringvalue(ar1,'exp',expression); + end; + if gettuplevalue(response,'value',ar1) then begin + getstringvalue(ar1,'old',oldvalue); + getstringvalue(ar1,'new',newvalue); + end; + end; + if reason = sr_exited then begin + getintegervalue(response,'exit-code',exitcode); + end + else begin + if not (reason in [sr_exited_normally,sr_detached]) then begin + result:= getqwordvalue(response,'thread-id',threadid); + if gettuplevalue(response,'frame',frame) then begin + filename:= msestring(getfullname(frame)); + getintegervalue(frame,'line',line); + getstringvalue(frame,'func',func); + getinteger64value(frame,'addr',int64(addr)); + if getsourcename(wstr1,language) = gdb_ok then begin + filedir:= msefileutils.filedir(wstr1); + end; + end; + end; + end; + if result then begin + messagetext:= stopreasontext[reason] + '.'; + if signalname <> '' then begin + messagetext:= messagetext + ' Signal: ' + signalname; + end; + if signalmeaning <> '' then begin + messagetext:= messagetext + ', ' + signalmeaning + '.'; + end; + if filename <> '' then begin + messagetext:= messagetext + ' File: ' + ansistring(filename); + end; + if line > 0 then begin + messagetext:= messagetext + ':'+inttostr(line); + end; + if func <> '' then begin + messagetext:= messagetext + ' Function: ' + func; + end; + if exitcode <> 0 then begin + messagetext:= messagetext + ' Exitcode: ' + inttostr(exitcode); + end; + if expression <> '' then begin + messagetext:= messagetext + ' Expression: '+expression; + end; + if oldvalue <> '' then begin + messagetext:= messagetext + ' old: '+oldvalue; + end; + if newvalue <> '' then begin + messagetext:= messagetext + ' new: '+newvalue; + end; + end + else begin + if getstringvalue(response,'msg',messagetext) then begin + if reason = sr_startup then begin + reason:= sr_error; + end; + end; + end; + end; + fcurrentlanguage:= language; + end; +end; +{ +function tgdbmi.geterrorinfo(const response: resultinfoarty; out info: errorinfoty): boolean; +var + int1: integer; +begin + finalize(info); + with info do begin + fillchar(info,sizeof(info),0); + result:= getstringvalue(response,'msg',messagetext); + end; +end; +} +function tgdbmi.executecommand(const acommand: string; + out aresult: string): gdbresultty; +begin + result:= clicommand(acommand); + case result of + gdb_ok: begin + aresult:= fclivalues; + end; + gdb_message: begin + aresult:= errormessage; + end; + else begin + aresult:= gdberrortexts[result]; + end; + end; +end; + +function tgdbmi.evaluateexpression(expression: string; out aresult: string; + const noupdatepascalexpression: boolean = false): gdbresultty; +begin + if not noupdatepascalexpression then begin + updatepascalexpression(expression); + end; + aresult:= ''; + result:= synccommand('-data-evaluate-expression ' + '"'+expression+'"'); + case result of + gdb_ok: begin + getstringvalue(fsyncvalues,'value',aresult); + end; + gdb_error: begin + getstringvalue(fsyncvalues,'msg',aresult); + end; + gdb_message: begin + aresult:= errormessage; + end; + else begin + aresult:= gdberrortexts[result]; + end; + end; +end; + +function tgdbmi.symboltype(symbol: string; + out aresult: string): gdbresultty; +begin + updatepascalexpression(symbol); + result:= clicommand('ptype '+symbol); + case result of + gdb_ok: begin + aresult:= fclivalues; + end; + gdb_message: begin + aresult:= errormessage; + end; + else begin + aresult:= ''; + end; + end; +end; + +function tgdbmi.symboladdress(symbol: ansistring; + out aresult: ansistring): gdbresultty; +begin + updatepascalexpression(symbol); + result:= evaluateexpression('@('+symbol+')',aresult); +end; + +function tgdbmi.threadselect(const aid: integer; out filename: filenamety; + out line: integer): gdbresultty; +var + str1: string; + ar1: resultinfoarty; +begin + filename:= ''; + line:= 0; + result:= synccommand('-thread-select ' + inttostr(aid)); + if result = gdb_ok then begin + if not gettuplevalue(fsyncvalues,'frame',ar1) then begin + ar1:= fsyncvalues; + end; + if getstringvalue(ar1,'file',str1) then begin + filename:= msestring(str1); + end; + getintegervalue(ar1,'line',line); + end; +end; + +function tgdbmi.getthreadidlist(out idlist: integerarty): gdbresultty; +var + ar1: resultinfoarty; + int1: integer; +begin + idlist:= nil; + result:= synccommand('-thread-list-ids'); + if result = gdb_ok then begin + result:= gdb_dataerror; + if gettuplevalue(fsyncvalues,'thread-ids',ar1) then begin + setlength(idlist,length(ar1)); + for int1:= 0 to high(ar1) do begin + if not getintegervalue(ar1[int1],'thread-id',idlist[int1]) then begin + break; + end; + end; + result:= gdb_ok; + end; + end; +end; + +function tgdbmi.getthreadinfolist(out infolist: threadinfoarty): gdbresultty; +var + int1,int2,int3: integer; + ar1,ar2: stringarty; + stackframeindex: integer; +begin + infolist:= nil; + ar1:= nil; //compiler warning + ar2:= nil; //compiler warning + result:= clicommand('info threads',true); + if result = gdb_ok then begin + result:= gdb_dataerror; + setlength(infolist,length(fclivaluelist)); //max + int2:= 0; + for int1:= 0 to high(fclivaluelist) do begin + with infolist[int2] do begin + ar1:= splitstring(trim(fclivaluelist[int1]),' ',true); + if (high(ar1) >= 2) and (ar1[0][1] <> '[') then begin + if ar1[0] = '*' then begin + state:= ts_active; + ar1:= copy(ar1,1,bigint); + end + else begin + state:= ts_none; + end; + if high(ar1) < 2 then begin + system.continue; + end; + if not trystrtoint64(ar1[0],pint64(@id)^) then begin + system.continue; + end; + if ar1[1] = 'Thread' then begin + ar1:= copy(ar1,2,bigint); + if high(ar1) < 2 then begin + system.continue; + end; + end; + threadid:= 0; + stackframeindex:= 3; + ar2:= splitstring(ar1[2],'.'); + if high(ar2) > 0 then begin + trystrtohex64(ar2[1],threadid); + end + else begin + if (high(ar1) > 1) and (ar1[1] = '(LWP') then begin + trystrtoint64(copy(ar1[2],1,length(ar1[2])-1),pint64(@threadid)^); + //delphi compatibility + end + else begin + if not trystrtoint64(ar1[0],pint64(@threadid)^) then begin + if not trystrtohex64(ar1[2],threadid) then begin + ar2:= splitstring(ar1[0],'.'); + if high(ar2) > 0 then begin + stackframeindex:= 1; + trystrtohex64(ar2[1],threadid); + end; + end; + end; + end; + end; + + if high(ar1) >= stackframeindex then begin + stackframe:= ar1[stackframeindex]; + for int3:= stackframeindex + 1 to high(ar1) do begin + stackframe:= stackframe + ' ' + ar1[int3]; + end; + end; + inc(int2); + end; + end; + end; + setlength(infolist,int2); + result:= gdb_ok; + end; +end; + +function tgdbmi.readmemorybytes(const address: qword; const count: integer; + var aresult: bytearty): gdbresultty; +var + ar1,ar2: resultinfoarty; +begin + aresult:= nil; + result:= synccommand('-data-read-memory '+ hextocstr(address,fpointerhexdigits) + ' u 1 1 ' + inttostr(count)); + if result = gdb_ok then begin + result:= gdb_dataerror; + if getarrayvalue(fsyncvalues,'memory',false,ar1) then begin + if gettuplevalue(ar1,'',ar2) then begin + if getbytearrayvalue(ar2,'data',aresult) then begin + result:= gdb_ok; + end; + end; + end; + end; +end; + +function tgdbmi.readmemorywords(const address: qword; const count: integer; + var aresult: wordarty): gdbresultty; +var + ar1,ar2: resultinfoarty; +begin + aresult:= nil; + result:= synccommand('-data-read-memory '+ + hextocstr(address,fpointerhexdigits) + ' u 2 1 ' + inttostr(count)); + if result = gdb_ok then begin + result:= gdb_dataerror; + if getarrayvalue(fsyncvalues,'memory',false,ar1) then begin + if gettuplevalue(ar1,'',ar2) then begin + if getwordarrayvalue(ar2,'data',aresult) then begin + result:= gdb_ok; + end; + end; + end; + end; +end; + +function tgdbmi.readmemorylongwords(const address: qword; const count: integer; + var aresult: longwordarty): gdbresultty; +var + ar1,ar2: resultinfoarty; +begin + aresult:= nil; + result:= synccommand('-data-read-memory '+ + hextocstr(address,fpointerhexdigits) + ' u 4 1 ' + inttostr(count)); + if result = gdb_ok then begin + result:= gdb_dataerror; + if getarrayvalue(fsyncvalues,'memory',false,ar1) then begin + if gettuplevalue(ar1,'',ar2) then begin + if getlongwordarrayvalue(ar2,'data',aresult) then begin + result:= gdb_ok; + end; + end; + end; + end; +end; + +function tgdbmi.readmemoryqwords(const address: qword; const count: integer; + var aresult: card64arty): gdbresultty; +var + ar1,ar2: resultinfoarty; +begin + aresult:= nil; + result:= synccommand('-data-read-memory '+ + hextocstr(address,fpointerhexdigits) + ' u 8 1 ' + inttostr(count)); + if result = gdb_ok then begin + result:= gdb_dataerror; + if getarrayvalue(fsyncvalues,'memory',false,ar1) then begin + if gettuplevalue(ar1,'',ar2) then begin + if getqwordarrayvalue(ar2,'data',aresult) then begin + result:= gdb_ok; + end; + end; + end; + end; +end; + +function tgdbmi.readmemorybyte(const address: qword; out aresult: byte): gdbresultty; +var + ar1: bytearty; +begin + result:= readmemorybytes(address,1,ar1); + if result = gdb_ok then begin + aresult:= ar1[0]; + end; +end; + +function tgdbmi.readmemoryword(const address: qword; out aresult: word): gdbresultty; +var + ar1: wordarty; +begin + result:= readmemorywords(address,1,ar1); + if result = gdb_ok then begin + aresult:= ar1[0]; + end; +end; + +function tgdbmi.readmemorylongword(const address: qword; out aresult: longword): gdbresultty; +var + ar1: longwordarty; +begin + result:= readmemorylongwords(address,1,ar1); + if result = gdb_ok then begin + aresult:= ar1[0]; + end; +end; + +function tgdbmi.readmemorypointer(const address: qword; out aresult: qword): gdbresultty; +var + ar1: bytearty; +begin + result:= readmemorybytes(address,fpointersize,ar1); + if result = gdb_ok then begin + if fpointersize = 8 then begin + aresult:= pqword(pointer(ar1))^; + end + else begin + aresult:= plongword(pointer(ar1))^; + end; + end; +end; +{ +function tgdbmi.readmemorypointer(const address: qword; out aresult: qword): gdbresultty; +var + ar1: bytearty; +begin //todo: endianess + result:= readmemorybytes(address,fpointersize,ar1); + if result = gdb_ok then begin + aresult:= pptruint(pointer(ar1))^; + end; +end; +} +function tgdbmi.setlangc(): string; +begin + result:= currentlang(); + if synccommand('set language c') <> gdb_ok then begin + result:= ''; + end; +end; + +function tgdbmi.setlang(const alanguage: string): gdbresultty; +begin + if alanguage <> '' then begin + result:= synccommand('set language '+alanguage); + end; +end; + +function tgdbmi.writememory8(const address: qword; + const avalue: card8): gdbresultty; +var + str1,str2,str3,str4: ansistring; +begin + str2:= hextocstr(address,fpointerhexdigits); + str3:= hextocstr(avalue,2); + str4:= setlangc(); + result:= evaluateexpression('{unsigned char} '+str2+'='+str3,str1,true); + setlang(str4); + +// if currentlang = 'pascal' then begin +// result:= evaluateexpression('pbyte('+str2+')^:='+str3,str1); +// end +// else begin +// result:= evaluateexpression('{char} '+str2+' = '+str3,str1); +// result:= evaluateexpression('*((unsigned char*)'+str2+') = '+str3,str1); +// end; +end; + +function tgdbmi.writememory16(const address: qword; + const avalue: card16): gdbresultty; +var + str1,str2,str3,str4: ansistring; +begin + str2:= hextocstr(address,fpointerhexdigits); + str3:= hextocstr(avalue,4); + str4:= setlangc(); + result:= evaluateexpression('{unsigned short} '+str2+'='+str3,str1,true); + setlang(str4); +{ + if currentlang = 'pascal' then begin + result:= evaluateexpression('pword('+str2+')^:='+str3,str1); + end + else begin + result:= evaluateexpression('*((unsigned short*)'+str2+')='+str3,str1); + end; +} +end; + +function tgdbmi.writememory32(const address: qword; + const avalue: card32): gdbresultty; +var + str1,str2,str3,str4: ansistring; +begin + str2:= hextocstr(address,fpointerhexdigits); + str3:= hextocstr(avalue,8); + str4:= setlangc(); + result:= evaluateexpression('{unsigned long} '+str2+'='+str3,str1,true); + setlang(str4); +{ + if currentlang = 'pascal' then begin + result:= evaluateexpression('plongword('+str2+')^:='+str3,str1); + end + else begin + result:= evaluateexpression('*((unsigned long*)'+str2+')='+str3,str1); + end; +} +end; + +function tgdbmi.writememory64(const address: qword; + const avalue: card64): gdbresultty; +var + str1,str2,str3,str4: ansistring; +begin + str2:= hextocstr(address,fpointerhexdigits); + str3:= hextocstr(avalue,16); + str4:= setlangc(); + result:= evaluateexpression('{unsigned long long} '+str2+'='+str3,str1,true); + setlang(str4); +end; + +function tgdbmi.infoline(const filename: filenamety; const line: integer; + out start,stop: qword): gdbresultty; +var + str1: string; +begin + result:= getcliresultstring('info line '+ansistring(filename)+':'+ + inttostr(line),str1); + if result = gdb_ok then begin + if not getcliint64('starts at address',str1,int64(start)) or + not getcliint64('ends at',str1,int64(stop)) then begin + result:= gdb_dataerror; + end; + end; +end; + +function tgdbmi.infoline(const address: qword; out filename: filenamety; out line: integer; + out start,stop: qword): gdbresultty; +var + str1,str2: string; +begin + result:= getcliresultstring('info line *'+inttostr(address),str1); + if result = gdb_ok then begin + if getclistring('of "',str1,str2) and getcliinteger('Line',str1,line) and + getcliint64('starts at address',str1,int64(start)) and + getcliint64('ends at',str1,int64(stop)) then begin + filename:= msestring(copy(str2,1,length(str2)-1)); + filename:= filepath(filename); + end + else begin + result:= gdb_dataerror; + end; + end; +end; + +function tgdbmi.infoaddress(const symbol: msestring; + out aresult: msestring): gdbresultty; +var + ar1: msestringarty; + mstr1: msestring; +begin + result:= clicommand('info address '+ansistring(symbol)); + case result of + gdb_ok: begin + aresult:= trim(removelinebreaks(msestring(fclivalues))); + ar1:= splitstring(aresult,msechar(' ')); + if (high(ar1) >= 0) then begin + mstr1:= ar1[high(ar1)]; + if msestartsstr('0x',mstr1) then begin + if mstr1[length(mstr1)] = '.' then begin + setlength(mstr1,length(mstr1)-1); + end; + aresult:= mstr1; + end; + end; + end; + gdb_message: begin + aresult:= msestring(errormessage); + end; + else begin + aresult:= ''; + end; + end; +end; + +function tgdbmi.infosymbol(const symbol: msestring; + out info: msestring): gdbresultty; +begin + result:= clicommand('info symbol '+ansistring(symbol)); + case result of + gdb_ok: begin + info:= msestring(fclivalues); + end; + gdb_message: begin + info:= msestring(errormessage); + end; + else begin + info:= ''; + end; + end; +end; + + +function tgdbmi.internaldisassemble(out aresult: disassarty; command: string; + const mixed: boolean): gdbresultty; + + function getasm(const source: resultinfoararty; out dest: asmlinearty): boolean; + var + int1: integer; + begin + result:= false; + setlength(dest,length(source)); + for int1:= 0 to high(source) do begin + with dest[int1] do begin + if not getqwordvalue(source[int1],'address',address) then exit; + if not getstringvalue(source[int1],'inst',instruction) then exit; + end; + end; + result:= true; + end; + +var + ar1,ar2: resultinfoarty; + ar3: resultinfoararty; + int1,int2: integer; +begin + aresult:= nil; + if mixed then begin + command:= command + ' -- 1'; + end + else begin + command:= command + ' -- 0'; + end; + result:= synccommand(command); + if result = gdb_ok then begin + result:= gdb_dataerror; + if mixed then begin + if getarrayvalue(fsyncvalues,'asm_insns',true,ar1) then begin + int2:= 0; + for int1:= 0 to high(ar1) do begin + additem(aresult,typeinfo(disassarty),int2); + if not gettuplevalue(ar1[int1],'src_and_asm_line',ar2) then exit; + with aresult[int2-1] do begin + if not getintegervalue(ar2,'line',line) then exit; + if not gettuplearrayvalue(ar2,'line_asm_insn',ar3) then exit; + if not getasm(ar3,asmlines) then exit; + end; + end; + setlength(aresult,int2); + end; + end + else begin + if not gettuplearrayvalue(fsyncvalues,'asm_insns',ar3) then exit; + setlength(aresult,1); + if not getasm(ar3,aresult[0].asmlines) then exit; + end; + result:= gdb_ok; + end; +end; + +function tgdbmi.disassemble(out aresult: asmlinearty; const filename: filenamety; + const line: integer; const count: integer): gdbresultty; +var + str1: string; + ar1: disassarty; +begin + str1:= '-data-disassemble -f '+ansistring(filename)+' -l '+inttostr(line) + + ' -n ' + inttostr(count); + result:= internaldisassemble(ar1,str1,false); + if result = gdb_ok then begin + aresult:= ar1[0].asmlines; + end; +end; + +function tgdbmi.disassemble(out aresult: asmlinearty; + const start,stop: qword): gdbresultty; +var + str1: string; + ar1: disassarty; +begin + str1:= '-data-disassemble -s '+qwordtocstr(start)+' -e '+qwordtocstr(stop); + result:= internaldisassemble(ar1,str1,false); + if result = gdb_ok then begin + aresult:= ar1[0].asmlines; + end; +end; + +function tgdbmi.disassemble(out aresult: disassarty; const filename: filenamety; + const line: integer; const count: integer): gdbresultty; +var + str1: string; +begin + str1:= '-data-disassemble -f '+ansistring(filename)+' -l '+inttostr(line) + + ' -n ' + inttostr(count); + result:= internaldisassemble(aresult,str1,true); +end; + +function tgdbmi.disassemble(out aresult: disassarty; + const start,stop: qword): gdbresultty; +var + str1: string; +begin + str1:= '-data-disassemble -s '+qwordtocstr(start)+' -e '+qwordtocstr(stop); + result:= internaldisassemble(aresult,str1,true); +end; + +function tgdbmi.getframeaddress(out address: qword): gdbresultty; +var + str1: ansistring; + ar1: stringarty; + int1: integer; +begin + result:= getcliresultstring('info frame',str1); + if result = gdb_ok then begin + result:= gdb_dataerror; + ar1:= splitstring(str1,' ',true); + for int1:= 0 to high(ar1)- 2 do begin + if (ar1[int1] = 'frame') and (ar1[int1+1] = 'at') then begin + setlength(ar1[int1+2],length(ar1[int1+2])-1); //remove ':' + if not trystrtointvalue64(ar1[int1+2],address) then begin + exit; + end; + break; + end; + end; + result:= gdb_ok; + end; +end; + +function tgdbmi.getregistervalue(const aname: string; out avalue: qword): gdbresultty; +var + str1: string; + int1: integer; +begin + result:= evaluateexpression('$'+aname,str1); + if result = gdb_ok then begin + int1:= findchar(str1,' '); + if int1 > 0 then begin + setlength(str1,int1-1); + end; + if not trystrtointvalue64(str1,avalue) then begin + result:= gdb_dataerror; + end; + end; +end; + +function tgdbmi.setregistervalue(const aname: string; + const avalue: qword): gdbresultty; +var + str1: ansistring; +begin + result:= writepascalvariable( + '$'+aname,inttostr(avalue),str1); +end; + +function tgdbmi.getpc(out addr: qword): gdbresultty; +begin + result:= getregistervalue('pc',addr); +end; + +function tgdbmi.listregisternames(out aresult: stringarty): gdbresultty; +{$ifdef mse_debuggdb} +var + int1: integer; +{$endif} +begin + aresult:= nil; + result:= synccommand('-data-list-register-names'); + if result = gdb_ok then begin + result:= gdb_dataerror; + if getstringarrayvalue(fsyncvalues,'register-names',aresult) then begin + result:= gdb_ok; + {$ifdef mse_debuggdb} + debugwriteln('**** registernames'); + for int1:= 0 to high(aresult) do begin + if aresult[int1] <> '' then begin + debugwriteln(inttostr(int1)+': '+aresult[int1]); + end; + end; + {$endif} + end; + end; +end; + +function tgdbmi.listregistervalues(out aresult: registerinfoarty): gdbresultty; +var + ar1,ar2: resultinfoarty; + int1: integer; +begin + aresult:= nil; + result:= synccommand('-data-list-register-values r',2*defaultsynctimeout); + if result = gdb_ok then begin + result:= gdb_dataerror; + if getarrayvalue(fsyncvalues,'register-values',false,ar1) then begin + setlength(aresult,length(ar1)); + for int1:= 0 to high(ar1) do begin + if not gettuplevalue(ar1[int1],ar2) then begin + exit; + end; + with aresult[int1] do begin + if not getintegervalue(ar2,'number',num) then begin + exit; + end; + if not getstringvalue(ar2,'value',bits) then begin + exit; + end; + end; + end; + result:= gdb_ok; + end; + end; +end; + +function tgdbmi.listlines(const path: filenamety; + out lines: integerarty; out addresses: qwordarty): gdbresultty; +var + ar1,ar2: resultinfoarty; + int1: integer; +begin + lines:= nil; + addresses:= nil; + result:= synccommand('-symbol-list-lines '+ + ansistring(filename(path)),5*defaultsynctimeout); + if result = gdb_ok then begin + result:= gdb_dataerror; + if getarrayvalue(fsyncvalues,'lines',false,ar1) then begin + setlength(lines,length(ar1)); + setlength(addresses,length(ar1)); + for int1:= 0 to high(ar1) do begin + if not gettuplevalue(ar1[int1],ar2) then begin + exit; + end; + if not getqwordvalue(ar2,'pc',addresses[int1]) then begin + exit; + end; + if not getintegervalue(ar2,'line',lines[int1]) then begin + exit; + end; + end; + end; + result:= gdb_ok; + end; +end; + +function tgdbmi.getsystemregister(const anumber: integer; + out avalue: qword): gdbresultty; + //for avr32 +var + str1: ansistring; + ar1: stringarty; +begin + avalue:= 0; + result:= getcliresultstring('show sysreg '+inttostr(anumber),str1); + if result = gdb_ok then begin + result:= gdb_dataerror; + ar1:= splitstring(str1,'=',true); + if high(ar1) = 1 then begin + if trystrtointvalue64(trimright(ar1[1]),avalue) then begin + result:= gdb_ok; + end; + end; + end; +end; + +function tgdbmi.setsystemregister(const anumber: integer; + const avalue: qword): gdbresultty; + //for avr32 +begin + result:= synccommand('set sysreg '+inttostr(anumber)+'='+qwordtocstr(avalue)); +end; + +function tgdbmi.getpcharvar(address: qword): string; +const + maxblocklength = 16; + maxlength = 10000; +var + data: bytearty; + po1: pchar; + int1,int2: integer; + bo1: boolean; + blocklength: integer; +begin + if address = 0 then begin + result:= ''''''; + end + else begin + data:= nil; + result:= ''''; + int1:= 2; + blocklength:= maxblocklength; + bo1:= false; + repeat + while true do begin + if blocklength <= 0 then begin + result:= 'Can not read memory at $'+inttohex(address,8); + exit; + end; + if readmemorybytes(address,blocklength,data) <> gdb_ok then begin + blocklength:= blocklength div 2; + end + else begin + break; + end; + end; + if high(data) >= 0 then begin + po1:= strlscan(pchar(pointer(data)),#0,length(data)); + if po1 = nil then begin + po1:= pchar(pointer(data))+length(data); + end + else begin + bo1:= true; + end; + int2:= po1-pchar(pointer(data)); + setlength(result,length(result)+int2); + move(data[0],result[int1],int2); + inc(int1,int2); + inc(address,int2); + if int1 > maxlength then begin + result:= result + '''...'; + exit; + end; + end; + until bo1 or (length(data) < blocklength); + result:= result + ''''; + end; +end; + +function tgdbmi.getpmsecharvar(address: qword): msestring; +const + maxblocklength = 16; + maxlength = 10000; +var + data: wordarty; + po1: pmsechar; + int1,int2: integer; + bo1: boolean; + blocklength: integer; +begin + data:= nil; + if address = 0 then begin + result:= ''''''; + end + else begin + result:= ''''; + int1:= 2; + blocklength:= maxblocklength; + bo1:= false; + repeat + while true do begin + if blocklength <= 0 then begin + result:= 'Can not read memory at $'+hextostrmse(address,8); + exit; + end; + if readmemorywords(address,blocklength,data) <> gdb_ok then begin + blocklength:= blocklength div 2; + end + else begin + break; + end; + end; + if high(data) >= 0 then begin + po1:= msestrlscan(pmsechar(pointer(data)),#0,length(data)); + if po1 = nil then begin + po1:= pmsechar(pointer(data))+length(data); + end + else begin + bo1:= true; + end; + int2:= po1-pmsechar(pointer(data)); + setlength(result,length(result)+int2); + move(data[0],result[int1],int2*sizeof(msechar)); + inc(int1,int2); + inc(address,int2*sizeof(msechar)); + if int1 > maxlength then begin + result:= result + '''...'; + exit; + end; + end; + until bo1 or (length(data) < blocklength); + result:= result + ''''; + end; +end; + +function tgdbmi.ispointervalue(avalue: string; out pointervalue: qword): boolean; +var + int1: integer; +begin + int1:= findchar(avalue,' '); + if int1 > 0 then begin + setlength(avalue,int1-1); + end; + result:= trystrtointvalue64(avalue,pointervalue); +end; + +function tgdbmi.matchpascalformat(const typeinfo: string; + value: string; const expression: string): msestring; +const + typetoken = 'TYPE = '; + dynartoken = 'ARRAY [0..-1] OF '; + dynartoken2 = 'ARRAY [0..0] OF '; + dynartoken3 = '^(ARRAY [0..-1] OF '; +var + ar1: stringarty; + str1,str2,str3: string; + mstr1: msestring; + ad1,ad2: qword; + ad3: int64; + res1: gdbresultty; + int1: integer; + bo1: boolean; +begin + ar1:= nil; //compiler warning + result:= msestring(value); + ar1:= breaklines(uppercase(typeinfo)); + str1:= ''; + if length(ar1) > 0 then begin + if startsstr(typetoken,ar1[0]) then begin + str1:= copy(ar1[0],length(typetoken)+1,length(ar1[0])-length(typetoken)); + end; +// str1:= struppercase(str1); + if startsstr(dynartoken2,str1) then begin + if evaluateexpression('@('+expression+')',str3) = gdb_ok then begin + if trystrtointvalue64(str3,ad1) then begin + value:= qwordtocstr(ad1); + str1:= dynartoken + copy(str1,length(dynartoken2)+1,bigint); + end; + end; + end; + end; + if ispointervalue(value,ad1) then begin + if str1 <> '' then begin + if (str1 = '^CHARACTER') or (str1 = '^CHAR') then begin + result:= msestring(getpcharvar(ad1)); + end + else begin + if (str1 = '^WCHAR') or (str1 = '^WIDECHAR') then begin + result:= getpmsecharvar(ad1); + end + else begin + str2:= ''; + bo1:= false; + if startsstr(dynartoken,str1) then begin + str2:= dynartoken; + end; + if startsstr(dynartoken3,str1) then begin //dereferenced + str2:= dynartoken3; + setlength(str1,length(str1)-1); + ad2:= ad1; + bo1:= true; + end; + if str2 <> '' then begin + if bo1 or (readmemorypointer(ad1,ad2) = gdb_ok) then begin + if ad2 = 0 then begin + result:= niltext; + end + else begin + if readmemorypointer(ad2-fpointersize,qword(ad3)) = gdb_ok then begin + //read arrayhigh + str3:= '^'+copy(str1,length(str2)+1,bigint)+'('+qwordtocstr(ad2)+')['; + result:= '('; + if ad3 >= 0 then begin + for int1:= 0 to ad3 do begin + if length(result) > 2000 then begin + result:= result +'...,'; + break; + end; + res1:= readpascalvariable(str3+inttostr(int1)+']',mstr1); + result:= result + mstr1 + ','; + if res1 <> gdb_ok then begin + break; + end; + end; + setlength(result,length(result)-1); //remove last comma + end; + result:= result + ')'; + end; + end; + end; + end; + end; + end; + end; + end; +end; + +function tgdbmi.getsysregnum(const varname: string; out num: integer): boolean; +var + str1: string; + int1: integer; +begin + result:= false; + num:= 0; + if startsstr('sysreg[',varname) then begin + int1:= findchar(varname,']') - 8; + if int1 > 0 then begin + str1:= copy(varname,8,int1); + try + num:= strtoint(str1); + result:= true; + except + end; + end; + end; +end; + +function tgdbmi.currentlang: string; +var +// str1: string; + ar1: stringarty; +// int1{,int2}: integer; +begin +// result:= 'pascal'; //default + result:= ''; + if getcliresult('show language',ar1) = gdb_ok then begin + ar1:= splitstring(ar1[0],' '); + ar1:= splitstring(ar1[high(ar1)],'"'); + if high(ar1) >= 1 then begin + result:= ar1[1]; + end; + end; +end; + +function tgdbmi.assignoperator: string; +begin + if currentlang <> 'pascal' then begin + result:= '='; + end + else begin + result:= ':='; + end; +end; + +function tgdbmi.readpascalvariable(varname: string; + out aresult: msestring): gdbresultty; +var + str1,str2,str3: string; + int1{,int2}: integer; + ar1: stringarty; +begin + if running then begin + result:= gdb_running; + aresult:= ''; + end + else begin + if getsysregnum(varname,int1) then begin + result:= getcliresultstring('show sysreg '+inttostr(int1),str2); + if result = gdb_ok then begin + ar1:= splitstring(str2,'='); + if high(ar1) = 1 then begin + aresult:= msestring(trim(ar1[1])); + end + else begin + aresult:= msestring(str2); + end; + end + else begin + aresult:= msestring(geterrormessage(result)); + end; + exit; + end; + updatepascalexpression(varname); + result:= symboltype(varname,str1); + if (pos('type = ^',str1) = 1) and + (symboltype(varname+'^' ,str3) = gdb_ok) then begin + if pos('type = array of ',str3) = 1 then begin //dwarf dynarray + str1:= 'type = ^(array [0..-1] of '+copy(trim(str3),17,bigint)+')'+lineend; + end; + end; + if result = gdb_ok then begin + result:= evaluateexpression(varname,str2); + case result of + gdb_ok: begin + aresult:= matchpascalformat(str1,str2,varname); + end; + gdb_message: begin + aresult:= msestring(errormessage); + end; + else begin + aresult:= ''; + end; + end; + end + else begin + aresult:= msestring(str1); + end; + end; +end; + +function tgdbmi.writepascalvariable(varname: string; const value: string; + var aresult: string): gdbresultty; +var + int1: integer; + mstr1: msestring; +begin + if getsysregnum(varname,int1) then begin + result:= synccommand('set sysreg '+inttostr(int1)+'='+value); + if result <> gdb_ok then begin + aresult:= geterrormessage(result); + end + else begin + result:= readpascalvariable('sysreg['+inttostr(int1)+']',mstr1); + aresult:= ansistring(mstr1); + end; + end + else begin + updatepascalexpression(varname); + result:= evaluateexpression(varname+assignoperator+value,aresult); + end; +end; + +function tgdbmi.clicommand(const acommand: string; list: boolean = false; + timeout: integer = defaultsynctimeout): gdbresultty; +begin + fclivalues:= ''; + fclivaluelist:= nil; + include(fstate,gs_clicommand); + try + if list then begin + include(fstate,gs_clilist); + end + else begin + exclude(fstate,gs_clilist); + end; + result:= synccommand(acommand,timeout); + finally + exclude(fstate,gs_clicommand); + end; +end; + +function tgdbmi.getcliresult(const acommand: string; var aresult: stringarty): gdbresultty; +var + int1: integer; +begin + result:= clicommand(acommand); + if result = gdb_ok then begin + splitstring(fclivalues,aresult,c_linefeed); + for int1:= 0 to high(aresult) do begin + aresult[int1]:= trim(replacechar(aresult[int1],c_tab,' ')); + end; + end; +end; + +function tgdbmi.getcliresultstring(const acommand: string; var aresult: string): gdbresultty; +begin + result:= clicommand(acommand); + if result = gdb_ok then begin + aresult:= fclivalues; + end; + replacechar1(aresult,#$0a,' '); + replacechar1(aresult,#$0d,' '); +end; + +function tgdbmi.getclistring(const aname: string; const response: string; out aresult: string): boolean; +var + int1: integer; + po1,po2: pchar; +begin + int1:= pos(aname,response); + if int1 > 0 then begin + aresult:= ''; + result:= true; + po1:= @response[int1+length(aname)]; + po2:= strnscan(po1,' '); + if po2 <> nil then begin + po1:= strscan(po2,' '); + if po1 <> nil then begin + setstring(aresult,po2,po1-po2); + end + else begin + setstring(aresult,po2,length(response)-(po1-pchar(pointer(response)))); + end; + end; + end + else begin + result:= false; + end; +end; + +function tgdbmi.getcliinteger(const aname: string; const response: string; out aresult: integer): boolean; +var + str1: string; +begin + result:= getclistring(aname,response,str1) and + trystrtointvalue(str1,longword(aresult)); +end; + +function tgdbmi.getcliint64(const aname: string; const response: string; + out aresult: int64): boolean; +var + str1: string; +begin + result:= getclistring(aname,response,str1) and + trystrtointvalue64(str1,qword(aresult)); +end; + +function tgdbmi.getpascalvalue(const avalue: string): string; +const + ansistringtag = '(ANSISTRING)'; +var + ca1: qword; +begin + if startsstr(ansistringtag,avalue) then begin + if ispointervalue(copy(avalue,length(ansistringtag)+1,bigint),ca1) then begin + result:= getpcharvar(ca1); + exit; + end; + end; + result:= avalue; +end; + +function tgdbmi.stacklistframes(out list: frameinfoarty; first, + last: integer): gdbresultty; +var + ar1,ar2,ar3,ar4: resultinfoarty; + int1,int2: integer; +// str1: string; + {$ifndef FPC} + lint1: int64; + {$endif} +begin + result:= synccommand('-stack-info-depth '+ inttostr(last)); + if result = gdb_ok then begin + getintegervalue(fsyncvalues,'depth',int1); + if int1 < last then begin + last:= int1; + end; + result:= synccommand('-stack-list-frames '+inttostr(first) + ' ' + inttostr(last)); + if result = gdb_ok then begin + if getarrayvalue(fsyncvalues,'stack',true,ar1) then begin + setlength(list,length(ar1)); + for int1:= 0 to high(list) do begin + gettuplevalue(ar1[int1],ar2); + with list[int1] do begin + getintegervalue(ar2,'level',level); + {$ifndef FPC} + getinteger64value(ar2,'addr',lint1); + addr:= lint1; + {$else} + getinteger64value(ar2,'addr',int64(addr)); + {$endif} + getstringvalue(ar2,'func',func); + filename:= msestring(getfullname(ar2)); + getintegervalue(ar2,'line',line); + end; + end; + result:= synccommand('-stack-list-arguments 1 '+inttostr(first) + ' ' + inttostr(last)); + if (result = gdb_ok) and (high(ar1) = high(list)) then begin + if getarrayvalue(fsyncvalues,'stack-args',true,ar1) then begin + for int1:= 0 to high(list) do begin + gettuplevalue(ar1[int1],ar2); + with list[int1] do begin + getarrayvalue(ar2,'args',false,ar3); + setlength(params,length(ar3)); + for int2:= 0 to high(ar3) do begin + decodelist(false,ar3[int2].value,ar4); + if high(ar4) = 1 then begin + params[int2].name:= ar4[0].value; + params[int2].value:= getpascalvalue(ar4[1].value); + end; + end; + end; + end; + end; + end; + end; + end; + end; +end; + +function tgdbmi.selectstackframe(const aframe: integer): gdbresultty; +begin +// result:= synccommand('-stack-select-frame '+inttostr(aframe)); does not +// switch info source + result:= synccommand('frame '+inttostr(aframe)); //switches info source + if result = gdb_ok then begin + updatecurrentlanguage(); + end; +end; + +function tgdbmi.selectstackpointer(const aframe: qword): gdbresultty; +begin + result:= synccommand('frame '+qwordtocstr(aframe)); + if result = gdb_ok then begin + updatecurrentlanguage(); + end; +end; + +function tgdbmi.started: boolean; +begin + result:= running or active and (fstate*[gs_started{,gs_attached}] <> []); +end; + +procedure tgdbmi.targetwriteln(const avalue: string); +begin + if running then begin + {$ifdef UNIX} + ftargetterminal.output.writeln(avalue); + {$else} + fgdbto.writeln(avalue); + {$endif} + end; +end; + +function tgdbmi.downloading: boolean; +begin + result:= gs_downloading in fstate; +end; + +function tgdbmi.downloaded: boolean; +begin + result:= gs_downloaded in fstate; +end; + +function tgdbmi.getprocessorname: ansistring; +begin + result:= processornames[fprocessor]; +end; + +procedure tgdbmi.setprocessorname(const avalue: ansistring); +var + pro1: processorty; +begin +{$ifdef CPU64} + fprocessor:= pro_x86_64; +{$else} + {$ifdef CPUARM} + fprocessor:= pro_arm; + {$else} + fprocessor:= pro_i386; + {$endif} +{$endif} + for pro1:= low(processorty) to high(processorty) do begin + if processornames[pro1] = avalue then begin + fprocessor:= pro1; + break; + end; + end; +end; + +procedure tgdbmi.setoverloadsleepus(const avalue: integer); +begin + foverloadsleepus:= avalue; + if fgdbfrom <> nil then begin + fgdbfrom.overloadsleepus:= avalue; + end; +{ + if fgdberror <> nil then begin + fgdberror.overloadsleepus:= avalue; + end; +} +{$ifdef UNIX} + ftargetterminal.input.overloadsleepus:= avalue; +{$endif} +end; + +procedure tgdbmi.updatepascalexpression(var aexpression: string); +begin + if (fcurrentlanguage = lan_pascal) and (pos('$',aexpression) = 0) then begin + //no register name + if ffpcworkaround then begin +// if not startsstr('self.',aexpression) and (aexpression <> 'self') then begin + aexpression:= uppercase(aexpression); + //workaround for gdb bug with class fields +// end; + end; + end; +end; + +procedure tgdbmi.updatecurrentlanguage(); +var + fna1: filenamety; +begin + getsourcename(fna1,fcurrentlanguage); +end; + +{$ifdef UNIX} +{ tpseudoterminal } + +constructor tpseudoterminal.create; + + procedure error; + begin + sys_closefile(fpty); + fpty:= invalidfilehandle; + syserror(syelasterror,'Can not create pseudoterminal:'); + end; + +const + buflen = 100; + +var + ios: termios{ty}; + +begin + fpty:= invalidfilehandle; + fpty:= getpt; + if fpty < 0 then error; + if (grantpt(fpty) < 0) or (unlockpt(fpty) < 0) then error; + setlength(fdevicename,buflen); + if ptsname_r(fpty,@fdevicename[1],buflen) < 0 then error; + setlength(fdevicename,length(pchar(fdevicename))); + fillchar(ios,sizeof(ios),0); + if msetcgetattr(fpty,ios) <> 0 then error; + ios.c_lflag:= ios.c_lflag and not (icanon or echo); + ios.c_cc[vmin]:= #1; + ios.c_cc[vtime]:= #0; + if msetcsetattr(fpty,tcsanow,ios) <> 0 then error; + finput:= tpipereader.create; + foutput:= tpipewriter.create; +// finput.handle:= pty; + foutput.handle:= fpty; +end; + +destructor tpseudoterminal.destroy; +begin + closeinp; + foutput.releasehandle; + finput.releasehandle; + foutput.free; + finput.free; + if fpty <> invalidfilehandle then begin + sys_closefile(fpty); + end; +end; + +procedure tpseudoterminal.closeinp; +var + ios: termios{ty}; +begin + finput.terminate(true); + if finput.active then begin + msetcgetattr(foutput.handle,ios); + ios.c_lflag:= (ios.c_lflag and not (icanon)) or echo; + ios.c_cc[vmin]:= #0; + ios.c_cc[vtime]:= #0; + msetcsetattr(foutput.handle,tcsanow,ios); + foutput.writeln(''); + end; +end; + +procedure tpseudoterminal.restart; +var + ios: termios{ty}; +begin + closeinp; + if foutput.handle <> invalidfilehandle then begin + if msetcgetattr(foutput.handle,ios) = 0 then begin + ios.c_lflag:= ios.c_lflag and not (icanon or echo); + ios.c_cc[vmin]:= #1; + ios.c_cc[vtime]:= #0; + if msetcsetattr(foutput.handle,tcsanow,ios) = 0 then begin + finput.releasehandle; + finput.handle:= foutput.handle; + end; + end; + end; +end; + +procedure tpseudoterminal.setoutecho(const avalue: boolean); +var + ios: termios{ty}; +begin + if msetcgetattr(fpty,ios) = 0 then begin + if avalue then begin + ios.c_lflag:= ios.c_lflag or echo; + end + else begin + ios.c_lflag:= ios.c_lflag and not echo; + end; + msetcsetattr(foutput.handle,tcsanow,ios); + end; +end; + +function tpseudoterminal.getoutecho: boolean; +var + ios: termios{ty}; +begin + result:= false; + if msetcgetattr(fpty,ios) = 0 then begin + result:= ios.c_lflag and echo <> 0; + end; +end; + +{$endif unix} + +procedure localizetext; +var + sr1: stopreasonty; +begin + for sr1:= sr_unknown to high(stopreasonty) do begin + stopreasontext[sr1]:= ansistring(actionsmo.c[ord(ac_sr_unknown)-1+ord(sr1)]); + end; +end; + +initialization + stopreasontext:= defaultstopreasontext; +{$ifdef mswindows} + {$ifdef mse_usedebugbreakprocess} + checkprocaddresses(['Kernel32.dll'], + ['DebugBreakProcess'], + [@DebugBreakProcess]); + {$endif} +{$endif} +end. diff --git a/mseide-msegui/lib/common/designutils/mseificlienteditor.mfm b/mseide-msegui/lib/common/designutils/mseificlienteditor.mfm new file mode 100644 index 0000000..cab67d5 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseificlienteditor.mfm @@ -0,0 +1,120 @@ +object mseificlienteditorfo: tmseificlienteditorfo + visible = False + bounds_x = 137 + bounds_y = 263 + bounds_cx = 284 + bounds_cy = 253 + container.bounds = ( + 0 + 0 + 284 + 253 + ) + options = [fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder, fo_savestate] + statfile = tstatfile1 + caption = 'ifi Client Editor' + moduleclassname = 'tmseform' + object grid: twidgetgrid + bounds_x = 0 + bounds_y = 0 + bounds_cx = 284 + bounds_cy = 210 + anchors = [an_top, an_bottom] + optionsgrid = [og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixcols.count = 1 + fixcols.items = < + item + width = 24 + numstep = 1 + end> + datacols.count = 2 + datacols.options = [co_savestate, co_mousescrollrow] + datacols.items = < + item[po] + options = [co_invisible, co_drawfocus, co_savestate, co_mousescrollrow] + widgetname = 'po' + dataclass = tgridpointerdatalist + end + item[na] + width = 203 + options = [co_fill, co_savestate, co_mousescrollrow] + oncellevent = celle + widgetname = 'na' + dataclass = titemeditlist + end> + datarowheight = 16 + statfile = tstatfile1 + reffontheight = 14 + object po: tpointeredit + optionsskin = [osk_framebuttononly] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 50 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate, oe1_checkvalueafterstatread] + visible = False + end + object na: tmbdropdownitemedit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.button.color = -1879048187 + frame.buttons.count = 2 + frame.buttons.items = < + item + color = -1879048187 + end + item + imagenr = 17 + onexecute = editexe + end> + taborder = 2 + visible = False + bounds_x = 51 + bounds_y = 0 + bounds_cx = 203 + bounds_cy = 16 + optionsedit1 = [] + onkeydown = keydownexe + onsetvalue = setval + dropdown.options = [deo_selectonly, deo_autodropdown, deo_keydropdown] + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + onbeforedropdown = befdrop + reffontheight = 14 + end + end + object tbutton1: tbutton + taborder = 1 + bounds_x = 168 + bounds_y = 224 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + end + object tbutton2: tbutton + taborder = 2 + bounds_x = 224 + bounds_y = 224 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_localdefault, as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + end + object tstatfile1: tstatfile + filename = 'ificlienteditor.sta' + options = [sfo_memory] + onstatupdate = statexe + left = 40 + top = 88 + end +end diff --git a/mseide-msegui/lib/common/designutils/mseificlienteditor.pas b/mseide-msegui/lib/common/designutils/mseificlienteditor.pas new file mode 100644 index 0000000..11c92e5 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseificlienteditor.pas @@ -0,0 +1,198 @@ +{ MSEgui Copyright (c) 1999-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseificlienteditor; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,mseforms,mseificomp,msedataedits, + mseedit,msegrids,msestrings,msetypes,msewidgetgrid,msesimplewidgets,msewidgets, + msegraphedits,msedatanodes,mselistbrowser,classes,mclasses,msestatfile; + +type + tmseificlienteditorfo = class(tmseform) + grid: twidgetgrid; + tbutton1: tbutton; + tbutton2: tbutton; + po: tpointeredit; + na: tmbdropdownitemedit; + tstatfile1: tstatfile; + procedure befdrop(const sender: TObject); + procedure setval(const sender: TObject; var avalue: msestring; + var accept: Boolean); + procedure celle(const sender: TObject; var info: celleventinfoty); + procedure editexe(const sender: TObject); + procedure statexe(const sender: TObject; const filer: tstatfiler); + procedure keydownexe(const sender: twidget; var ainfo: keyeventinfoty); + private + fcomp: tifilinkcomp; + finstances: ppointeraty; + fpath: msestring; + function filtercomponent(const acomponent: tcomponent): boolean; + end; + +function editificlient(const acomponent: tifilinkcomp): modalresultty; + +implementation +uses + mseificlienteditor_mfm,msepropertyeditors,msedesignintf,msedesigner, + objectinspector,typinfo,msearrayutils,msecomptree; +type + tmsecomponent1 = class(tmsecomponent); + +function getdispname(const aobject: tobject): msestring; +begin + if aobject is tcomponent then begin + result:= getcomponentpropname(tcomponent(aobject)); + end + else begin + result:= msestring(aobject.classname); + end; +end; + +function editificlient(const acomponent: tifilinkcomp): modalresultty; +var + edfo: tmseificlienteditorfo; + ar1: objectarty; + int1: integer; + ar2: pointerarty; +begin + edfo:= tmseificlienteditorfo.create(nil); + try +{$warnings off} + ar1:= tmsecomponent1(acomponent).getobjectlinker.linkedobjects( + acomponent.controller); +{$warnings on} + edfo.po.gridvalues:= pointerarty(ar1); + edfo.fcomp:= acomponent; + for int1:= 0 to high(ar1) do begin + edfo.na[int1].caption:= getdispname(ar1[int1]); + end; + edfo.caption:= edfo.caption + ' ('+msestring(acomponent.name)+')'; + result:= edfo.show(true); + if result = mr_ok then begin + ar2:= edfo.po.gridvalues; + for int1:= 0 to high(ar1) do begin //remove not linked + if finditem(ar2,ar1[int1]) < 0 then begin + setobjectprop(ar1[int1],'ifilink',nil); + designer.componentmodified(ar1[int1]); + ar1[int1]:= nil; + end; + end; + for int1:= 0 to high(ar2) do begin //add linked + if (ar2[int1] <> nil) and + (finditem(pointerarty(ar1),ar2[int1]) < 0) then begin + setobjectprop(tobject(ar2[int1]),'ifilink',acomponent); + designer.componentmodified(tcomponent(ar2[int1])); + end; + end; + end; + finally + edfo.free; + end; +end; + +function tmseificlienteditorfo.filtercomponent( + const acomponent: tcomponent): boolean; +var + int1: integer; + po1: ppropinfo; +begin + result:= fcomp.controller.canconnect(acomponent); + if result and (pointer(acomponent) <> po.value) then begin + for int1:= 0 to grid.rowhigh do begin + if finstances^[int1] = pointer(acomponent) then begin + result:= false; + exit; + end; + end; + po1:= getpropinfo(acomponent,'ifilink'); + result:= (po1 <> nil) and (po1^.proptype^.kind = tkclass) and + (fcomp is gettypedata(po1^.proptype{$ifndef FPC}^{$endif})^.classtype); + end; +end; + +procedure tmseificlienteditorfo.befdrop(const sender: TObject); +begin + finstances:= po.griddata.datapo; + with tmbdropdownitemedit(sender) do begin + dropdown.cols[0].asarray:= designer.getcomponentnamelist( + tcomponent,false,nil,{$ifdef FPC}@{$endif}filtercomponent); + end; +end; + +procedure tmseificlienteditorfo.setval(const sender: TObject; + var avalue: msestring; var accept: Boolean); +var + comp1: tcomponent; + int1: integer; +begin + comp1:= designer.getcomponent(ansistring(avalue),fcomp.owner); + po.value:= comp1; + if comp1 <> nil then begin + avalue:= getdispname(tcomponent(po.value)); + fpath:= msestring(ownernamepath(comp1)); + int1:= findlastchar(fpath,'.'); + if int1 > 0 then begin + setlength(fpath,int1-1); + end; + end; +end; + +procedure tmseificlienteditorfo.celle(const sender: TObject; + var info: celleventinfoty); +begin + if iscellclick(info,[ccr_dblclick,ccr_nokeyreturn]) then begin + designer.showformdesigner(designer.modules.findmodulebycomponent( + tcomponent(po.value))); + designer.selectcomponent(tcomponent(po.value)); + window.modalresult:= mr_ok; +// objectinspectorfo.activate; + end; +end; + +procedure tmseificlienteditorfo.editexe(const sender: TObject); +var + tree1: tcompnameitem; + mstr1: msestring; + bo1: boolean; +begin + finstances:= po.griddata.datapo; + tree1:= designer.getcomponentnametree(tcomponent,true,false,nil, + {$ifdef FPC}@{$endif}filtercomponent); + mstr1:= msestring(ownernamepath(tcomponent(po.value))); + if mstr1 = '' then begin + mstr1:= fpath; + end; + if compnamedialog(tree1,mstr1,false) = mr_ok then begin + bo1:= true; + setval(nil,mstr1,bo1); + na.item.caption:= mstr1; + end; + +end; + +procedure tmseificlienteditorfo.statexe(const sender: TObject; + const filer: tstatfiler); +begin + filer.updatevalue('path',fpath); +end; + +procedure tmseificlienteditorfo.keydownexe(const sender: twidget; + var ainfo: keyeventinfoty); +begin + if isenterkey(nil,ainfo.key) and (ainfo.shiftstate = []) and + not na.edited then begin + include(ainfo.eventstate,es_processed); + editexe(nil); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/mseificlienteditor_mfm.pas b/mseide-msegui/lib/common/designutils/mseificlienteditor_mfm.pas new file mode 100644 index 0000000..7a27c61 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseificlienteditor_mfm.pas @@ -0,0 +1,128 @@ +unit mseificlienteditor_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,mseificlienteditor; + +const + objdata: record size: integer; data: array[0..2216] of byte end = + (size: 2217; data: ( + 84,80,70,48,21,116,109,115,101,105,102,105,99,108,105,101,110,116,101,100, + 105,116,111,114,102,111,20,109,115,101,105,102,105,99,108,105,101,110,116,101, + 100,105,116,111,114,102,111,7,118,105,115,105,98,108,101,8,8,98,111,117, + 110,100,115,95,120,3,137,0,8,98,111,117,110,100,115,95,121,3,7,1, + 9,98,111,117,110,100,115,95,99,120,3,28,1,9,98,111,117,110,100,115, + 95,99,121,3,253,0,16,99,111,110,116,97,105,110,101,114,46,98,111,117, + 110,100,115,1,2,0,2,0,3,28,1,3,253,0,0,7,111,112,116,105, + 111,110,115,11,13,102,111,95,99,108,111,115,101,111,110,101,115,99,15,102, + 111,95,97,117,116,111,114,101,97,100,115,116,97,116,16,102,111,95,97,117, + 116,111,119,114,105,116,101,115,116,97,116,10,102,111,95,115,97,118,101,112, + 111,115,13,102,111,95,115,97,118,101,122,111,114,100,101,114,12,102,111,95, + 115,97,118,101,115,116,97,116,101,0,8,115,116,97,116,102,105,108,101,7, + 10,116,115,116,97,116,102,105,108,101,49,7,99,97,112,116,105,111,110,6, + 17,105,102,105,32,67,108,105,101,110,116,32,69,100,105,116,111,114,15,109, + 111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,8,116,109,115,101, + 102,111,114,109,0,11,116,119,105,100,103,101,116,103,114,105,100,4,103,114, + 105,100,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115, + 95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,28,1,9,98,111, + 117,110,100,115,95,99,121,3,210,0,7,97,110,99,104,111,114,115,11,6, + 97,110,95,116,111,112,9,97,110,95,98,111,116,116,111,109,0,11,111,112, + 116,105,111,110,115,103,114,105,100,11,15,111,103,95,114,111,119,105,110,115, + 101,114,116,105,110,103,14,111,103,95,114,111,119,100,101,108,101,116,105,110, + 103,19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101, + 114,15,111,103,95,97,117,116,111,102,105,114,115,116,114,111,119,13,111,103, + 95,97,117,116,111,97,112,112,101,110,100,20,111,103,95,99,111,108,99,104, + 97,110,103,101,111,110,116,97,98,107,101,121,10,111,103,95,119,114,97,112, + 99,111,108,12,111,103,95,97,117,116,111,112,111,112,117,112,17,111,103,95, + 109,111,117,115,101,115,99,114,111,108,108,99,111,108,0,13,102,105,120,99, + 111,108,115,46,99,111,117,110,116,2,1,13,102,105,120,99,111,108,115,46, + 105,116,101,109,115,14,1,5,119,105,100,116,104,2,24,7,110,117,109,115, + 116,101,112,2,1,0,0,14,100,97,116,97,99,111,108,115,46,99,111,117, + 110,116,2,2,16,100,97,116,97,99,111,108,115,46,111,112,116,105,111,110, + 115,11,12,99,111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109, + 111,117,115,101,115,99,114,111,108,108,114,111,119,0,14,100,97,116,97,99, + 111,108,115,46,105,116,101,109,115,14,7,2,112,111,1,7,111,112,116,105, + 111,110,115,11,12,99,111,95,105,110,118,105,115,105,98,108,101,12,99,111, + 95,100,114,97,119,102,111,99,117,115,12,99,111,95,115,97,118,101,115,116, + 97,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111, + 119,0,10,119,105,100,103,101,116,110,97,109,101,6,2,112,111,9,100,97, + 116,97,99,108,97,115,115,7,20,116,103,114,105,100,112,111,105,110,116,101, + 114,100,97,116,97,108,105,115,116,0,7,2,110,97,1,5,119,105,100,116, + 104,3,203,0,7,111,112,116,105,111,110,115,11,7,99,111,95,102,105,108, + 108,12,99,111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109,111, + 117,115,101,115,99,114,111,108,108,114,111,119,0,11,111,110,99,101,108,108, + 101,118,101,110,116,7,5,99,101,108,108,101,10,119,105,100,103,101,116,110, + 97,109,101,6,2,110,97,9,100,97,116,97,99,108,97,115,115,7,13,116, + 105,116,101,109,101,100,105,116,108,105,115,116,0,0,13,100,97,116,97,114, + 111,119,104,101,105,103,104,116,2,16,8,115,116,97,116,102,105,108,101,7, + 10,116,115,116,97,116,102,105,108,101,49,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,12,116,112,111,105,110,116,101,114,101,100,105, + 116,2,112,111,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115, + 107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116, + 97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,2,50,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105, + 111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112,111, + 112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99,117, + 116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,27,111,101,49, + 95,99,104,101,99,107,118,97,108,117,101,97,102,116,101,114,115,116,97,116, + 114,101,97,100,0,7,118,105,115,105,98,108,101,8,0,0,19,116,109,98, + 100,114,111,112,100,111,119,110,105,116,101,109,101,100,105,116,2,110,97,11, + 111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97, + 109,101,98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46, + 108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114, + 99,108,105,101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111, + 10,102,114,108,95,108,101,118,101,108,105,15,102,114,108,95,99,111,108,111, + 114,99,108,105,101,110,116,0,18,102,114,97,109,101,46,98,117,116,116,111, + 110,46,99,111,108,111,114,4,5,0,0,144,19,102,114,97,109,101,46,98, + 117,116,116,111,110,115,46,99,111,117,110,116,2,2,19,102,114,97,109,101, + 46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111,108, + 111,114,4,5,0,0,144,0,1,7,105,109,97,103,101,110,114,2,17,9, + 111,110,101,120,101,99,117,116,101,7,7,101,100,105,116,101,120,101,0,0, + 8,116,97,98,111,114,100,101,114,2,2,7,118,105,115,105,98,108,101,8, + 8,98,111,117,110,100,115,95,120,2,51,8,98,111,117,110,100,115,95,121, + 2,0,9,98,111,117,110,100,115,95,99,120,3,203,0,9,98,111,117,110, + 100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49, + 11,0,9,111,110,107,101,121,100,111,119,110,7,10,107,101,121,100,111,119, + 110,101,120,101,10,111,110,115,101,116,118,97,108,117,101,7,6,115,101,116, + 118,97,108,16,100,114,111,112,100,111,119,110,46,111,112,116,105,111,110,115, + 11,14,100,101,111,95,115,101,108,101,99,116,111,110,108,121,16,100,101,111, + 95,97,117,116,111,100,114,111,112,100,111,119,110,15,100,101,111,95,107,101, + 121,100,114,111,112,100,111,119,110,0,19,100,114,111,112,100,111,119,110,46, + 99,111,108,115,46,99,111,117,110,116,2,1,19,100,114,111,112,100,111,119, + 110,46,99,111,108,115,46,105,116,101,109,115,14,1,0,0,16,111,110,98, + 101,102,111,114,101,100,114,111,112,100,111,119,110,7,7,98,101,102,100,114, + 111,112,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0, + 0,7,116,98,117,116,116,111,110,8,116,98,117,116,116,111,110,49,8,116, + 97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,3,168, + 0,8,98,111,117,110,100,115,95,121,3,224,0,9,98,111,117,110,100,115, + 95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,20,7,97,110, + 99,104,111,114,115,11,8,97,110,95,114,105,103,104,116,9,97,110,95,98, + 111,116,116,111,109,0,5,115,116,97,116,101,11,15,97,115,95,108,111,99, + 97,108,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,99,97, + 112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,3,38,79,75,11, + 109,111,100,97,108,114,101,115,117,108,116,7,5,109,114,95,111,107,0,0, + 7,116,98,117,116,116,111,110,8,116,98,117,116,116,111,110,50,8,116,97, + 98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,3,224,0, + 8,98,111,117,110,100,115,95,121,3,224,0,9,98,111,117,110,100,115,95, + 99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,20,7,97,110,99, + 104,111,114,115,11,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111, + 116,116,111,109,0,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97, + 108,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,99,97,112, + 116,105,111,110,0,7,99,97,112,116,105,111,110,6,7,38,67,97,110,99, + 101,108,11,109,111,100,97,108,114,101,115,117,108,116,7,9,109,114,95,99, + 97,110,99,101,108,0,0,9,116,115,116,97,116,102,105,108,101,10,116,115, + 116,97,116,102,105,108,101,49,8,102,105,108,101,110,97,109,101,6,19,105, + 102,105,99,108,105,101,110,116,101,100,105,116,111,114,46,115,116,97,7,111, + 112,116,105,111,110,115,11,10,115,102,111,95,109,101,109,111,114,121,0,12, + 111,110,115,116,97,116,117,112,100,97,116,101,7,7,115,116,97,116,101,120, + 101,4,108,101,102,116,2,40,3,116,111,112,2,88,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tmseificlienteditorfo,''); +end. diff --git a/mseide-msegui/lib/common/designutils/mseificomponenteditors.pas b/mseide-msegui/lib/common/designutils/mseificomponenteditors.pas new file mode 100644 index 0000000..5244f66 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseificomponenteditors.pas @@ -0,0 +1,47 @@ +{ MSEgui Copyright (c) 2009-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseificomponenteditors; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msecomponenteditors,msedesignintf,classes,mclasses,mseificlienteditor; + +const + ificlienteditorstatname = 'ificlienteditor.sta'; + +type + tifilinkcompeditor = class(tcomponenteditor) + public + constructor create(const adesigner: idesigner; + acomponent: tcomponent); override; + procedure edit; override; + end; + +implementation +uses + mseificomp,mseglob; + +{ tifilinkcompeditor } + +constructor tifilinkcompeditor.create(const adesigner: idesigner; + acomponent: tcomponent); +begin + inherited; + fstate:= fstate + [cs_canedit]; +end; + +procedure tifilinkcompeditor.edit; +begin + if editificlient(tifilinkcomp(fcomponent)) = mr_ok then begin + fdesigner.componentmodified(fcomponent); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/mseififieldeditor.mfm b/mseide-msegui/lib/common/designutils/mseififieldeditor.mfm new file mode 100644 index 0000000..39a370e --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseififieldeditor.mfm @@ -0,0 +1,336 @@ +object mseififieldeditorfo: tmseififieldeditorfo + optionswidget = [ow_arrowfocus, ow_subfocus, ow_destroywidgets, ow_hinton] + visible = False + bounds_x = 29 + bounds_y = 248 + bounds_cx = 601 + bounds_cy = 216 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + container.frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + container.bounds = ( + 0 + 0 + 601 + 216 + ) + options = [fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savestate] + statfile = tstatfile1 + oneventloopstart = formloaded + moduleclassname = 'tmseform' + object tbutton1: tbutton + taborder = 3 + bounds_x = 472 + bounds_y = 184 + bounds_cx = 50 + bounds_cy = 22 + anchors = [an_right, an_bottom] + state = [as_default, as_localdefault, as_localcaption] + caption = 'OK' + modalresult = mr_ok + end + object tbutton2: tbutton + bounds_x = 536 + bounds_y = 184 + bounds_cx = 50 + bounds_cy = 22 + anchors = [an_right, an_bottom] + state = [as_localcaption] + caption = 'Cancel' + modalresult = mr_cancel + end + object fielddefli: tstringgrid + frame.caption = 'Fielddefs' + frame.captionpos = cp_top + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + bounds_x = 336 + bounds_y = 7 + bounds_cx = 258 + bounds_cy = 171 + bounds_cxmin = 50 + anchors = [an_left, an_top, an_right, an_bottom] + optionsgrid = [og_colsizing, og_focuscellonenter, og_colchangeontabkey, og_wrapcol, og_autopopup] + datacols.count = 2 + datacols.options = [co_readonly, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate] + datacols.items = < + item + width = 123 + options = [co_readonly, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savestate] + optionsedit = [scoe_eatreturn] + valuefalse = '0' + valuetrue = '1' + end + item + width = 129 + options = [co_readonly, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savestate] + optionsedit = [scoe_eatreturn] + valuefalse = '0' + valuetrue = '1' + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 2 + captions.items = < + item + caption = 'Name' + end + item + caption = 'Type' + end> + end> + rowfonts.count = 1 + rowfonts.items = < + item + color = -1610612732 + name = 'stf_default' + xscale = 1 + localprops = [flp_color, flp_xscale] + end> + datarowheight = 16 + oncellevent = defscellevent + onselectionchanged = defsselectioncha + reffontheight = 14 + end + object fields: twidgetgrid + frame.caption = 'Fields' + frame.captionpos = cp_top + frame.localprops = [frl_frameimageleft, frl_frameimagetop, frl_frameimageright, frl_frameimagebottom, frl_frameimageoffset, frl_frameimageoffsetdisabled, frl_frameimageoffsetmouse, frl_frameimageoffsetclicked, frl_frameimageoffsetactive, frl_optionsskin] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + bounds_x = 8 + bounds_y = 7 + bounds_cx = 323 + bounds_cy = 171 + anchors = [an_left, an_top, an_bottom] + optionsgrid = [og_colsizing, og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_sorted, og_colchangeontabkey, og_wrapcol, og_autopopup] + fixcols.count = 1 + fixcols.items = < + item + width = 15 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 5 + captions.items = < + item + end + item + end + item + caption = 'fieldname' + end + item + caption = 'sourcefieldname' + end + item + caption = 'datatype' + end> + end> + rowfonts.count = 1 + rowfonts.items = < + item + color = -1610612732 + name = 'stf_default' + xscale = 1 + localprops = [flp_color, flp_xscale] + end> + datacols.count = 5 + datacols.options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate] + datacols.items = < + item[index] + width = 13 + options = [co_invisible, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savevalue, co_savestate] + widgetname = 'index' + dataclass = tgridintegerdatalist + end + item[fieldpo] + width = 12 + options = [co_invisible, co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate] + widgetname = 'fieldpo' + dataclass = tgridpointerdatalist + end + item[fieldname] + width = 92 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savestate] + widgetname = 'fieldname' + dataclass = tgridmsestringdatalist + end + item[sourcefieldname] + width = 119 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savestate] + widgetname = 'sourcefieldname' + dataclass = tgridmsestringdatalist + end + item[datatype] + width = 62 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savevalue, co_savestate] + widgetname = 'datatype' + dataclass = tgridenumdatalist + end> + datarowheight = 16 + onrowsdeleting = fieldrowsdeleting + onrowsdeleted = fieldsrowdel + oncellevent = fieldcellevent + onselectionchanged = fieldselectioncha + onsort = fieldsort + reffontheight = 14 + object index: tintegeredit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_noskin] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 13 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + reffontheight = 14 + end + object fieldpo: tpointeredit + optionsskin = [osk_noskin] + taborder = 2 + bounds_x = 14 + bounds_y = 0 + bounds_cx = 12 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + end + object fieldname: tstringedit + optionsskin = [osk_framebuttononly] + taborder = 3 + visible = False + bounds_x = 27 + bounds_y = 0 + bounds_cx = 92 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_notnull] + ondataentered = fieldsdataentered + onsetvalue = fieldnamesetvalue + reffontheight = 14 + end + object sourcefieldname: tdropdownlistedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.button.color = -1879048187 + taborder = 4 + visible = False + bounds_x = 120 + bounds_y = 0 + bounds_cx = 119 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_notnull] + ondataentered = fieldsdataentered + onsetvalue = sourcefieldsetexe + dropdown.options = [deo_autodropdown, deo_keydropdown] + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + onbeforedropdown = sourcebefdropexe + reffontheight = 14 + end + object datatype: tenumtypeedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [frl1_framefaceoffset, frl1_framefaceoffsetdisabled, frl1_framefaceoffsetmouse, frl1_framefaceoffsetclicked, frl1_framefaceoffsetactive] + frame.button.width = 15 + frame.button.color = -1879048187 + taborder = 5 + visible = False + bounds_x = 240 + bounds_y = 0 + bounds_cx = 62 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_notnull] + ondataentered = fieldsdataentered + valuedefault = 0 + min = 0 + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + oninit = initfieldkind + reffontheight = 14 + end + end + object splitter: tsplitter + color = -1879048189 + taborder = 6 + bounds_x = 331 + bounds_y = 24 + bounds_cx = 5 + bounds_cy = 154 + anchors = [an_left, an_top, an_bottom] + options = [spo_hmove, spo_hprop] + linkleft = fields + linkright = fielddefli + statfile = tstatfile1 + onupdatelayout = splitterupda + end + object deftofield: tstockglyphbutton + optionswidget = [ow_destroywidgets] + taborder = 5 + bounds_x = 338 + bounds_y = 5 + bounds_cx = 28 + bounds_cy = 15 + state = [as_disabled, as_localdisabled, as_localimagelist, as_localimagenr, as_localonexecute] + glyph = stg_arrowleft + onexecute = transferfields + end + object fieldtodef: tstockglyphbutton + optionswidget = [ow_destroywidgets] + taborder = 4 + bounds_x = 303 + bounds_y = 5 + bounds_cx = 28 + bounds_cy = 15 + state = [as_disabled, as_localdisabled, as_localimagelist, as_localimagenr, as_localonexecute] + glyph = stg_arrowright + onexecute = deletefields + end + object tstatfile1: tstatfile + filename = 'ififieldeditor.sta' + options = [sfo_memory] + left = 24 + top = 152 + end + object c: tstringcontainer + strings.data = ( + 'Connection' + ) + left = 152 + top = 152 + end +end diff --git a/mseide-msegui/lib/common/designutils/mseififieldeditor.pas b/mseide-msegui/lib/common/designutils/mseififieldeditor.pas new file mode 100644 index 0000000..034eb98 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseififieldeditor.pas @@ -0,0 +1,572 @@ +{ MSEide Copyright (c) 1999-2014 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit mseififieldeditor; +{$ifdef FPC}{$mode objfpc}{$h+}{$goto on}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + mdb,msegui,mseclasses,mseforms,msedb,msestat,msestatfile,msesimplewidgets, + msegrids,msewidgetgrid,msesplitter,msedataedits,msestrings,mseeditglob, + msegraphedits,mseglob,msegridsglob,msestringcontainer,mseificomp,mseifidbcomp, + mseedit,mseguiglob,mseificompglob,mseifiglob,msemenus,msetypes,msedatalist; + +const + ififieldeditorstatname = 'ififieldeditor.sta'; +type + tmseififieldeditorfo = class(tmseform) + tbutton1: tbutton; + tbutton2: tbutton; + index: tintegeredit; + datatype: tenumtypeedit; + splitter: tsplitter; + fieldpo: tpointeredit; + tstatfile1: tstatfile; + fielddefli: tstringgrid; + fields: twidgetgrid; + fieldname: tstringedit; + deftofield: tstockglyphbutton; + fieldtodef: tstockglyphbutton; + c: tstringcontainer; + sourcefieldname: tdropdownlistedit; + procedure formloaded(const sender: TObject); + procedure initcla(const sender: tenumtypeedit); + procedure splitterupda(const sender: TObject); + procedure defscellevent(const sender: TObject; var info: celleventinfoty); + procedure defsselectioncha(const sender: TObject); + procedure fieldnamesetvalue(const sender: TObject; var avalue: msestring; + var accept: Boolean); + procedure fieldsdataentered(const sender: TObject); + procedure fieldsrowdel(const sender: tcustomgrid; const aindex: Integer; + const acount: Integer); + procedure transferfields(const sender: TObject); + procedure fieldrowsdeleting(const sender: tcustomgrid; var aindex: Integer; + var acount: Integer); + procedure initfieldkind(const sender: tenumtypeedit); + procedure fieldcellevent(const sender: TObject; var info: celleventinfoty); + procedure fieldselectioncha(const sender: TObject); + procedure deletefields(const sender: TObject); + procedure fieldsort(const sender: tcustomgrid; const index1: Integer; + const index2: Integer; var aresult: Integer); + procedure sourcebefdropexe(const sender: TObject); + procedure sourcefieldsetexe(const sender: TObject; var avalue: msestring; + var accept: Boolean); + private + ffields: tificonnectedfields; + ffieldintf: iifidbdataconnection; + procedure checkfielddefs; + function findfielddef(aname: msestring): integer; + function typeok(const aname: msestring; + const atype: listdatatypety): boolean; + function uniquefieldname(const aname: msestring): msestring; + public + constructor create(const afields: tificonnectedfields); reintroduce; + end; + +function editififields(const instance: tificonnectedfields): boolean; + +implementation +uses + mseififieldeditor_mfm,typinfo,msewidgets,sysutils,mseformatstr; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tificonnectedfields1 = class(tificonnectedfields); + tconnectedifidatasource1 = class(tconnectedifidatasource); + stringconststy = ( + str_connection //0 Connection + ); + +function editififields(const instance: tificonnectedfields): boolean; +var + fo: tmseififieldeditorfo; + int1{,int2}: integer; +// ct1: fieldclassty; +// ar1: fieldarty; +// activebefore: boolean; +begin + result:= false; + fo:= tmseififieldeditorfo.create(instance); + try + with fo do begin + if ffieldintf <> nil then begin + try + if show(true) = mr_ok then begin + fo.window.nofocus; //remove empty last line + result:= true; + instance.beginupdate(); + instance.count:= fields.rowcount; + for int1:= 0 to fields.rowhigh() do begin + with tififieldlink(instance[int1]) do begin + sourcefieldname:= ansistring(fo.sourcefieldname[int1]); + fieldname:= ansistring(fo.fieldname[int1]); + datatype:= listdatatypety(fo.datatype[int1]); + end; + end; + instance.endupdate(); + (* + setlength(ar1,fields.rowcount-dataset.fields.count); + for int1:= 0 to high(ar1) do begin + ct1:= getmsefieldclass(fieldclasstypety(classty[int1])); +// ct1:= msefieldtypeclasses[fieldclasstypety(classty[int1])]; + int2:= index[int1]; + if int2 > 0 then begin + dec(int2); + if ct1 <> items[int2].classtype then begin + ar1[int1]:= ct1.create(nil); + ar1[int1].dataset:= dataset; + end + else begin + ar1[int1]:= items[int2]; + fitems[int2]:= nil; + end; + end + else begin + if fieldpo[int1] <> nil then begin + ar1[int1]:= tfield(fieldpo[int1]); + fieldpo[int1]:= nil; + end + else begin + ar1[int1]:= ct1.create(nil); + try + ar1[int1].dataset:= dataset; + except + application.handleexception(nil); + end; + end; + end; + try + ar1[int1].fieldname:= fieldname[int1]; + except + application.handleexception(nil); + end; + ar1[int1].fieldkind:= tfieldkind(fieldkind[int1]); + end; + for int1:= 0 to count - 1 do begin + items[int1].free; + end; + for int1:= 0 to high(ar1) do begin + tfield(fieldpo[int1]).free; + end; + fitems:= persistentarty(ar1); + *) + end; + finally + { + for int1:= 0 to count - 1 do begin + items[int1].dataset:= dataset; + end; + if result then begin + for int1:= 0 to high(ar1) do begin + items[int1].index:= int1; + end; + for int1:= length(ar1) to fields.rowhigh do begin + tfield(fieldpo[int1]).index:= int1; + end; + end; + if activebefore then begin + try + dataset.active:= true; + except + application.handleexception(dataset); + end; + end; +} + end; + end; + end; + finally + fo.free; + end; +end; + +{ tmsedbfieldeditorfo } + +constructor tmseififieldeditorfo.create(const afields: tificonnectedfields); +begin + ffields:= afields; + mseclasses.getcorbainterface( + tificonnectedfields1(ffields).fowner.connection, + typeinfo(iifidbdataconnection),ffieldintf); + inherited create(nil); +end; + +procedure tmseififieldeditorfo.formloaded(const sender: TObject); +var + int1: integer; +// field1: tfield; + ar1: dbfieldinfoarty; +// ar2: msestringarty; +// ar3: datalistarty; + f1: tififieldlink; +begin + if ffieldintf <> nil then begin + caption:= 'ifi '+c[ord(str_connection)]+': '+ + msestring(tificonnectedfields1(ffields).fowner.name); + ar1:= ffieldintf.getfieldinfos(); + fielddefli.rowcount:= length(ar1); + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + fielddefli[0][int1]:= name; + fielddefli[1][int1]:= msestring(getenumname( + typeinfo(tfieldtype),ord(datatype))); + end; + end; + fields.rowcount:= ffields.count; + for int1:= 0 to fields.rowhigh do begin + f1:= tififieldlink(ffields[int1]); + fieldname[int1]:= msestring(f1.fieldname); + sourcefieldname[int1]:= msestring(f1.sourcefieldname); + datatype[int1]:= ord(f1.datatype); + end; + checkfielddefs(); + end; + +{ + with ffields.fowner do begin + caption:= c[ord(str_dataset)]+': '+name; + fielddefli.rowcount:= fielddefs.count; + for int1:= 0 to fielddefs.count-1 do begin + fielddefli[0][int1]:= fielddefs[int1].name; + fielddefli[1][int1]:= getenumname(typeinfo(tfieldtype), + ord(fielddefs[int1].datatype)); + end; + end; + fields.rowcount:= ffields.count + ffields.dataset.fields.count; + for int1:= 0 to ffields.count - 1 do begin + index[int1]:= int1+1; + fieldname[int1]:= ffields[int1].fieldname; + classty[int1]:= ord(fieldclasstoclasstyp(fieldclassty(ffields[int1].classtype))); + fieldkind[int1]:= ord(ffields[int1].fieldkind); + end; + for int1:= ffields.count to fields.rowhigh do begin + index[int1]:= int1+1; + field1:= ffields.dataset.fields[int1-ffields.count]; + fieldpo[int1]:= field1; + with field1 do begin + self.fieldname[int1]:= fieldname; + classty[int1]:= ord(fieldclasstoclasstyp(fieldclassty(classtype))); + self.fieldkind[int1]:= ord(fieldkind); + end; + fields.rowfontstate[int1]:= 0; + end; + checkfielddefs; +} +end; + +procedure tmseififieldeditorfo.sourcebefdropexe(const sender: TObject); +begin + sourcefieldname.dropdown.cols[0].asarray:= + ffieldintf.getfieldnames(listdatatypety(datatype.value)); +end; + +function tmseififieldeditorfo.typeok(const aname: msestring; + const atype: listdatatypety): boolean; +begin + result:= false; +end; + +function tmseififieldeditorfo.uniquefieldname( + const aname: msestring): msestring; +var + ar1: msestringarty; + int1: integer; + mstr1,mstr2: msestring; + int2: integer; +label + startlab; +begin + ar1:= fieldname.gridvalues; + for int1:= 0 to high(ar1) do begin + ar1[int1]:= mseuppercase(ar1[int1]); + end; + mstr1:= mseuppercase(aname); + int2:= 0; +startlab: + mstr2:= mstr1; + if int2 <> 0 then begin + mstr2:= mstr2+inttostrmse(int2); + end; + for int1:= 0 to high(ar1) do begin + if ar1[int1] = mstr2 then begin + inc(int2); + goto startlab; + end; + end; + result:= mstr2; +end; + +procedure tmseififieldeditorfo.sourcefieldsetexe(const sender: TObject; + var avalue: msestring; var accept: Boolean); +var +// ar1: msestringarty; + dl1: listdatatypety; +begin + if (avalue <> '') then begin + if not typeok(avalue,listdatatypety(datatype.value)) then begin + dl1:= ffieldintf.getdatatype(ansistring(avalue)); + if dl1 <> dl_none then begin + datatype.value:= ord(dl1); + end; + end; + if fieldname.value = '' then begin + fieldname.value:= uniquefieldname(avalue); + end; + end; +end; + +procedure tmseififieldeditorfo.initcla(const sender: tenumtypeedit); +begin + sender.typeinfopo:= typeinfo(fieldclasstypety); +end; + +procedure tmseififieldeditorfo.initfieldkind(const sender: tenumtypeedit); +begin + sender.typeinfopo:= typeinfo(listdatatypety); +end; + +procedure tmseififieldeditorfo.splitterupda(const sender: TObject); +begin + deftofield.left:= splitter.left+splitter.bounds_cx; + fieldtodef.left:= splitter.left-fieldtodef.bounds_cx; +// alignx(wam_center,[splitter,deftofield]); +end; + +procedure tmseififieldeditorfo.defscellevent(const sender: TObject; + var info: celleventinfoty); +begin + with info do begin + if (eventkind = cek_select) and selected and + (fielddefli.rowfontstate[cell.row] <> -1) then begin + accept:= false; + end; + end; +end; + +procedure tmseififieldeditorfo.defsselectioncha(const sender: TObject); +begin + deftofield.enabled:= fielddefli.datacols.hasselection; +end; + +procedure tmseififieldeditorfo.fieldnamesetvalue(const sender: TObject; + var avalue: msestring; var accept: Boolean); +var + mstr1: msestring; + int1: integer; +begin + mstr1:= mseuppercase(avalue); + for int1:= 0 to fields.rowcount-1 do begin + if (int1 <> fields.row) and (mstr1 = mseuppercase(fieldname[int1])) then begin + showerror('Field name exists.'); + accept:= false; + break; + end; + end; +end; + +procedure tmseififieldeditorfo.checkfielddefs; +var + int1,int2: integer; + ar1: msestringarty; + mstr1: msestring; +begin + setlength(ar1,fields.rowcount); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= mseuppercase(sourcefieldname[int1]); + end; + for int1:= 0 to fielddefli.rowcount - 1 do begin + mstr1:= mseuppercase(fielddefli[0][int1]); + fielddefli.rowfontstate[int1]:= -1; + for int2:= 0 to high(ar1) do begin + if mstr1 = ar1[int2] then begin + fielddefli.rowfontstate[int1]:= 0; + fielddefli.datacols.selected[makegridcoord(-1,int1)]:= false; + break; + end; + end; + end; +end; + +procedure tmseififieldeditorfo.fieldsdataentered(const sender: TObject); +begin + checkfielddefs; +end; + +procedure tmseififieldeditorfo.fieldsrowdel(const sender: tcustomgrid; + const aindex: Integer; const acount: Integer); +begin + checkfielddefs; +end; + +procedure tmseififieldeditorfo.transferfields(const sender: TObject); +var + int1,int2: integer; + ar1,ar2: integerarty; + mstr1: msestring; +begin + ar1:= fielddefli.datacols.selectedrows; + if high(ar1) >= 0 then begin + setlength(ar2,length(ar1)); + int2:= 0; + fields.beginupdate; + for int1:= 0 to high(ar1) do begin + fields.appendrow(true); + try + fields.row:= fields.rowhigh; +// fieldpo[fields.rowhigh]:= +// ffields.dataset.fielddefs[ar1[int1]].createfield(nil); +// tfield(fieldpo[fields.rowhigh]).dataset:= nil; + mstr1:= fielddefli[0][ar1[int1]]; + sourcefieldname[fields.rowhigh]:= mstr1; + fieldname[fields.rowhigh]:= uniquefieldname(mstr1); +// classty[fields.rowhigh]:= ord(fieldclasstoclasstyp( +/// ffields.dataset.fielddefs[ar1[int1]].fieldclass)); + datatype[fields.rowhigh]:= ord(ffieldintf.getdatatype(ansistring(mstr1))); + ar2[int2]:= fields.rowhigh; + inc(int2); + except + fields.rowcount:= fields.rowcount - 1; + application.handleexception(nil); + end; + fielddefli.datacols.clearselection; + end; + setlength(ar2,int2); + fields.datacols.selectedrows:= ar2; + fields.endupdate; + // fields.sort; + checkfielddefs; + for int1:= ar1[high(ar1)] + 1 to fielddefli.rowhigh do begin + if fielddefli.rowfontstate[int1] = -1 then begin + fielddefli.row:= int1; + exit; + end; + end; + for int1:= 0 to fielddefli.rowhigh do begin + if fielddefli.rowfontstate[int1] = -1 then begin + fielddefli.row:= int1; + exit; + end; + end; + end; +end; + +procedure tmseififieldeditorfo.fieldrowsdeleting(const sender: tcustomgrid; + var aindex: Integer; var acount: Integer); +var + int1: integer; +begin + for int1:= aindex to aindex + acount - 1 do begin + if sender.rowfontstate[int1] <> -1 then begin + acount:= 0; + break; + end; + end; + for int1:= aindex to aindex + acount - 1 do begin + tfield(fieldpo[int1]).free; + end; +end; + +procedure tmseififieldeditorfo.fieldsort(const sender: tcustomgrid; + const index1: Integer; const index2: Integer; + var aresult: Integer); +begin + aresult:= fields.rowfontstate[index1] - fields.rowfontstate[index2]; +end; + +procedure tmseififieldeditorfo.fieldcellevent(const sender: TObject; + var info: celleventinfoty); +begin + with info do begin + if eventkind = cek_enter then begin + if fields.rowfontstate[cell.row] = -1 then begin + fields.datacols.options:= fields.datacols.options - [co_readonly]; + fields.optionsgrid:= fields.optionsgrid + [og_rowdeleting]; + end + else begin + fields.datacols.options:= fields.datacols.options + [co_readonly]; + fields.optionsgrid:= fields.optionsgrid - [og_rowdeleting]; + end; + end; + if (eventkind = cek_select) and selected then begin + if fields.rowfontstate[cell.row] <> -1 then begin + accept:= false; + end; + end; + end; +end; + +procedure tmseififieldeditorfo.fieldselectioncha(const sender: TObject); +begin + fieldtodef.enabled:= fields.datacols.hasselection and + (length(fields.datacols.selectedrows) > 0); +end; + +function tmseififieldeditorfo.findfielddef(aname: msestring): integer; +var + int1: integer; +begin + result:= invalidaxis; + aname:= struppercase(aname); + for int1:= 0 to fielddefli.rowhigh do begin + if msestringicompupper(fielddefli[0][int1],aname) = 0 then begin + result:= int1; + break; + end; + end; +end; + +procedure tmseififieldeditorfo.deletefields(const sender: TObject); +var + ar1,ar2: integerarty; + int1: integer; + int2: integer; +begin + ar1:= fields.datacols.selectedrows; + setlength(ar2,length(ar1)); //max + int2:= 0; + for int1:= high(ar1) downto 0 do begin + ar2[int2]:= findfielddef(fieldname[ar1[int1]]); + if ar2[int2] >= 0 then begin + inc(int2); + end; + end; + ffields.beginupdate; + for int1:= high(ar1) downto 0 do begin + fields.deleterow(ar1[int1]); + end; + ffields.endupdate; + if int2 > 0 then begin + setlength(ar2,int2); + fielddefli.row:= ar2[high(ar2)]; + fielddefli.datacols.selectedrows:= ar2; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/mseififieldeditor_mfm.pas b/mseide-msegui/lib/common/designutils/mseififieldeditor_mfm.pas new file mode 100644 index 0000000..38dbaaa --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseififieldeditor_mfm.pas @@ -0,0 +1,447 @@ +unit mseififieldeditor_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,mseififieldeditor; + +const + objdata: record size: integer; data: array[0..8586] of byte end = + (size: 8587; data: ( + 84,80,70,48,20,116,109,115,101,105,102,105,102,105,101,108,100,101,100,105, + 116,111,114,102,111,19,109,115,101,105,102,105,102,105,101,108,100,101,100,105, + 116,111,114,102,111,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,11,111,119,95,115,117, + 98,102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100, + 103,101,116,115,9,111,119,95,104,105,110,116,111,110,0,7,118,105,115,105, + 98,108,101,8,8,98,111,117,110,100,115,95,120,2,29,8,98,111,117,110, + 100,115,95,121,3,248,0,9,98,111,117,110,100,115,95,99,120,3,89,2, + 9,98,111,117,110,100,115,95,99,121,3,216,0,23,99,111,110,116,97,105, + 110,101,114,46,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,11,111, + 119,95,115,117,98,102,111,99,117,115,19,111,119,95,109,111,117,115,101,116, + 114,97,110,115,112,97,114,101,110,116,17,111,119,95,100,101,115,116,114,111, + 121,119,105,100,103,101,116,115,0,26,99,111,110,116,97,105,110,101,114,46, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,18,102,114, + 108,95,102,114,97,109,101,105,109,97,103,101,108,101,102,116,17,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,116,111,112,19,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,114,105,103,104,116,20,102,114,108,95,102, + 114,97,109,101,105,109,97,103,101,98,111,116,116,111,109,20,102,114,108,95, + 102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,28,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,100,105,115, + 97,98,108,101,100,25,102,114,108,95,102,114,97,109,101,105,109,97,103,101, + 111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,95,102,114,97,109, + 101,105,109,97,103,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116, + 97,99,116,105,118,101,15,102,114,108,95,111,112,116,105,111,110,115,115,107, + 105,110,0,27,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114, + 97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108, + 101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102, + 115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116, + 105,118,101,0,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100, + 115,1,2,0,2,0,3,89,2,3,216,0,0,7,111,112,116,105,111,110, + 115,11,13,102,111,95,99,108,111,115,101,111,110,101,115,99,15,102,111,95, + 97,117,116,111,114,101,97,100,115,116,97,116,16,102,111,95,97,117,116,111, + 119,114,105,116,101,115,116,97,116,10,102,111,95,115,97,118,101,112,111,115, + 12,102,111,95,115,97,118,101,115,116,97,116,101,0,8,115,116,97,116,102, + 105,108,101,7,10,116,115,116,97,116,102,105,108,101,49,16,111,110,101,118, + 101,110,116,108,111,111,112,115,116,97,114,116,7,10,102,111,114,109,108,111, + 97,100,101,100,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101, + 6,8,116,109,115,101,102,111,114,109,0,7,116,98,117,116,116,111,110,8, + 116,98,117,116,116,111,110,49,8,116,97,98,111,114,100,101,114,2,3,8, + 98,111,117,110,100,115,95,120,3,216,1,8,98,111,117,110,100,115,95,121, + 3,184,0,9,98,111,117,110,100,115,95,99,120,2,50,9,98,111,117,110, + 100,115,95,99,121,2,22,7,97,110,99,104,111,114,115,11,8,97,110,95, + 114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,5,115,116,97, + 116,101,11,10,97,115,95,100,101,102,97,117,108,116,15,97,115,95,108,111, + 99,97,108,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,99, + 97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,2,79,75,11, + 109,111,100,97,108,114,101,115,117,108,116,7,5,109,114,95,111,107,0,0, + 7,116,98,117,116,116,111,110,8,116,98,117,116,116,111,110,50,8,98,111, + 117,110,100,115,95,120,3,24,2,8,98,111,117,110,100,115,95,121,3,184, + 0,9,98,111,117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115, + 95,99,121,2,22,7,97,110,99,104,111,114,115,11,8,97,110,95,114,105, + 103,104,116,9,97,110,95,98,111,116,116,111,109,0,5,115,116,97,116,101, + 11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,7,99, + 97,112,116,105,111,110,6,6,67,97,110,99,101,108,11,109,111,100,97,108, + 114,101,115,117,108,116,7,9,109,114,95,99,97,110,99,101,108,0,0,11, + 116,115,116,114,105,110,103,103,114,105,100,10,102,105,101,108,100,100,101,102, + 108,105,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,9,70,105, + 101,108,100,100,101,102,115,16,102,114,97,109,101,46,99,97,112,116,105,111, + 110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,18,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,108,101,102,116,17,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,116,111,112,19,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,114,105,103,104,116,20,102,114,108,95,102,114,97,109,101,105,109,97, + 103,101,98,111,116,116,111,109,20,102,114,108,95,102,114,97,109,101,105,109, + 97,103,101,111,102,102,115,101,116,28,102,114,108,95,102,114,97,109,101,105, + 109,97,103,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102, + 114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,109, + 111,117,115,101,27,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,95,102,114,97, + 109,101,105,109,97,103,101,111,102,102,115,101,116,97,99,116,105,118,101,15, + 102,114,108,95,111,112,116,105,111,110,115,115,107,105,110,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,20,102,114,108,49, + 95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,28,102,114,108, + 49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,100,105,115, + 97,98,108,101,100,25,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,109,111,117,115,101,27,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,99,108,105,99,107,101,100,26, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 97,99,116,105,118,101,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114, + 100,101,114,2,1,8,98,111,117,110,100,115,95,120,3,80,1,8,98,111, + 117,110,100,115,95,121,2,7,9,98,111,117,110,100,115,95,99,120,3,2, + 1,9,98,111,117,110,100,115,95,99,121,3,171,0,12,98,111,117,110,100, + 115,95,99,120,109,105,110,2,50,7,97,110,99,104,111,114,115,11,7,97, + 110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,9,97,110,95,98,111,116,116,111,109,0,11,111,112,116,105,111,110, + 115,103,114,105,100,11,12,111,103,95,99,111,108,115,105,122,105,110,103,19, + 111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101,114,20, + 111,103,95,99,111,108,99,104,97,110,103,101,111,110,116,97,98,107,101,121, + 10,111,103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112, + 111,112,117,112,0,14,100,97,116,97,99,111,108,115,46,99,111,117,110,116, + 2,2,16,100,97,116,97,99,111,108,115,46,111,112,116,105,111,110,115,11, + 11,99,111,95,114,101,97,100,111,110,108,121,14,99,111,95,102,111,99,117, + 115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101, + 99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109, + 117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108, + 101,99,116,12,99,111,95,115,97,118,101,115,116,97,116,101,0,14,100,97, + 116,97,99,111,108,115,46,105,116,101,109,115,14,1,5,119,105,100,116,104, + 2,123,7,111,112,116,105,111,110,115,11,11,99,111,95,114,101,97,100,111, + 110,108,121,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99, + 111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121, + 115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99, + 116,12,99,111,95,114,111,119,115,101,108,101,99,116,7,99,111,95,102,105, + 108,108,12,99,111,95,115,97,118,101,115,116,97,116,101,0,11,111,112,116, + 105,111,110,115,101,100,105,116,11,14,115,99,111,101,95,101,97,116,114,101, + 116,117,114,110,0,10,118,97,108,117,101,102,97,108,115,101,6,1,48,9, + 118,97,108,117,101,116,114,117,101,6,1,49,0,1,5,119,105,100,116,104, + 3,129,0,7,111,112,116,105,111,110,115,11,11,99,111,95,114,101,97,100, + 111,110,108,121,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14, + 99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101, + 121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101, + 99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,15,99,111,95,112, + 114,111,112,111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,115, + 116,97,116,101,0,11,111,112,116,105,111,110,115,101,100,105,116,11,14,115, + 99,111,101,95,101,97,116,114,101,116,117,114,110,0,10,118,97,108,117,101, + 102,97,108,115,101,6,1,48,9,118,97,108,117,101,116,114,117,101,6,1, + 49,0,0,13,102,105,120,114,111,119,115,46,99,111,117,110,116,2,1,13, + 102,105,120,114,111,119,115,46,105,116,101,109,115,14,1,6,104,101,105,103, + 104,116,2,16,14,99,97,112,116,105,111,110,115,46,99,111,117,110,116,2, + 2,14,99,97,112,116,105,111,110,115,46,105,116,101,109,115,14,1,7,99, + 97,112,116,105,111,110,6,4,78,97,109,101,0,1,7,99,97,112,116,105, + 111,110,6,4,84,121,112,101,0,0,0,0,14,114,111,119,102,111,110,116, + 115,46,99,111,117,110,116,2,1,14,114,111,119,102,111,110,116,115,46,105, + 116,101,109,115,14,1,5,99,111,108,111,114,4,4,0,0,160,4,110,97, + 109,101,6,11,115,116,102,95,100,101,102,97,117,108,116,6,120,115,99,97, + 108,101,2,1,10,108,111,99,97,108,112,114,111,112,115,11,9,102,108,112, + 95,99,111,108,111,114,10,102,108,112,95,120,115,99,97,108,101,0,0,0, + 13,100,97,116,97,114,111,119,104,101,105,103,104,116,2,16,11,111,110,99, + 101,108,108,101,118,101,110,116,7,13,100,101,102,115,99,101,108,108,101,118, + 101,110,116,18,111,110,115,101,108,101,99,116,105,111,110,99,104,97,110,103, + 101,100,7,16,100,101,102,115,115,101,108,101,99,116,105,111,110,99,104,97, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,11,116, + 119,105,100,103,101,116,103,114,105,100,6,102,105,101,108,100,115,13,102,114, + 97,109,101,46,99,97,112,116,105,111,110,6,6,70,105,101,108,100,115,16, + 102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,6,99,112, + 95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,18,102,114,108,95,102,114,97,109,101,105,109,97,103,101,108,101,102, + 116,17,102,114,108,95,102,114,97,109,101,105,109,97,103,101,116,111,112,19, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,114,105,103,104,116,20, + 102,114,108,95,102,114,97,109,101,105,109,97,103,101,98,111,116,116,111,109, + 20,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101, + 116,28,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111,102,102,115, + 101,116,100,105,115,97,98,108,101,100,25,102,114,108,95,102,114,97,109,101, + 105,109,97,103,101,111,102,102,115,101,116,109,111,117,115,101,27,102,114,108, + 95,102,114,97,109,101,105,109,97,103,101,111,102,102,115,101,116,99,108,105, + 99,107,101,100,26,102,114,108,95,102,114,97,109,101,105,109,97,103,101,111, + 102,102,115,101,116,97,99,116,105,118,101,15,102,114,108,95,111,112,116,105, + 111,110,115,115,107,105,110,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101,102,97, + 99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109,101,102, + 97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25,102,114, + 108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116,109,111, + 117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102, + 102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102,114,97, + 109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101,0,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2, + 17,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111, + 117,110,100,115,95,120,2,8,8,98,111,117,110,100,115,95,121,2,7,9, + 98,111,117,110,100,115,95,99,120,3,67,1,9,98,111,117,110,100,115,95, + 99,121,3,171,0,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101, + 102,116,6,97,110,95,116,111,112,9,97,110,95,98,111,116,116,111,109,0, + 11,111,112,116,105,111,110,115,103,114,105,100,11,12,111,103,95,99,111,108, + 115,105,122,105,110,103,12,111,103,95,114,111,119,109,111,118,105,110,103,15, + 111,103,95,107,101,121,114,111,119,109,111,118,105,110,103,15,111,103,95,114, + 111,119,105,110,115,101,114,116,105,110,103,14,111,103,95,114,111,119,100,101, + 108,101,116,105,110,103,19,111,103,95,102,111,99,117,115,99,101,108,108,111, + 110,101,110,116,101,114,15,111,103,95,97,117,116,111,102,105,114,115,116,114, + 111,119,13,111,103,95,97,117,116,111,97,112,112,101,110,100,9,111,103,95, + 115,111,114,116,101,100,20,111,103,95,99,111,108,99,104,97,110,103,101,111, + 110,116,97,98,107,101,121,10,111,103,95,119,114,97,112,99,111,108,12,111, + 103,95,97,117,116,111,112,111,112,117,112,0,13,102,105,120,99,111,108,115, + 46,99,111,117,110,116,2,1,13,102,105,120,99,111,108,115,46,105,116,101, + 109,115,14,1,5,119,105,100,116,104,2,15,7,110,117,109,115,116,101,112, + 2,1,0,0,13,102,105,120,114,111,119,115,46,99,111,117,110,116,2,1, + 13,102,105,120,114,111,119,115,46,105,116,101,109,115,14,1,6,104,101,105, + 103,104,116,2,16,14,99,97,112,116,105,111,110,115,46,99,111,117,110,116, + 2,5,14,99,97,112,116,105,111,110,115,46,105,116,101,109,115,14,1,0, + 1,0,1,7,99,97,112,116,105,111,110,6,9,102,105,101,108,100,110,97, + 109,101,0,1,7,99,97,112,116,105,111,110,6,15,115,111,117,114,99,101, + 102,105,101,108,100,110,97,109,101,0,1,7,99,97,112,116,105,111,110,6, + 8,100,97,116,97,116,121,112,101,0,0,0,0,14,114,111,119,102,111,110, + 116,115,46,99,111,117,110,116,2,1,14,114,111,119,102,111,110,116,115,46, + 105,116,101,109,115,14,1,5,99,111,108,111,114,4,4,0,0,160,4,110, + 97,109,101,6,11,115,116,102,95,100,101,102,97,117,108,116,6,120,115,99, + 97,108,101,2,1,10,108,111,99,97,108,112,114,111,112,115,11,9,102,108, + 112,95,99,111,108,111,114,10,102,108,112,95,120,115,99,97,108,101,0,0, + 0,14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,5,16,100, + 97,116,97,99,111,108,115,46,111,112,116,105,111,110,115,11,14,99,111,95, + 102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101, + 115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14, + 99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111, + 119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116,97,116,101, + 0,14,100,97,116,97,99,111,108,115,46,105,116,101,109,115,14,7,5,105, + 110,100,101,120,1,5,119,105,100,116,104,2,13,7,111,112,116,105,111,110, + 115,11,12,99,111,95,105,110,118,105,115,105,98,108,101,14,99,111,95,102, + 111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115, + 101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99, + 111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119, + 115,101,108,101,99,116,12,99,111,95,115,97,118,101,118,97,108,117,101,12, + 99,111,95,115,97,118,101,115,116,97,116,101,0,10,119,105,100,103,101,116, + 110,97,109,101,6,5,105,110,100,101,120,9,100,97,116,97,99,108,97,115, + 115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108, + 105,115,116,0,7,7,102,105,101,108,100,112,111,1,5,119,105,100,116,104, + 2,12,7,111,112,116,105,111,110,115,11,12,99,111,95,105,110,118,105,115, + 105,98,108,101,12,99,111,95,100,114,97,119,102,111,99,117,115,14,99,111, + 95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115, + 101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116, + 14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114, + 111,119,115,101,108,101,99,116,12,99,111,95,115,97,118,101,115,116,97,116, + 101,0,10,119,105,100,103,101,116,110,97,109,101,6,7,102,105,101,108,100, + 112,111,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100,112, + 111,105,110,116,101,114,100,97,116,97,108,105,115,116,0,7,9,102,105,101, + 108,100,110,97,109,101,1,5,119,105,100,116,104,2,92,7,111,112,116,105, + 111,110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14, + 99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101, + 121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101, + 99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,7,99,111,95,102, + 105,108,108,12,99,111,95,115,97,118,101,115,116,97,116,101,0,10,119,105, + 100,103,101,116,110,97,109,101,6,9,102,105,101,108,100,110,97,109,101,9, + 100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115, + 116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,15,115,111,117,114, + 99,101,102,105,101,108,100,110,97,109,101,1,5,119,105,100,116,104,2,119, + 7,111,112,116,105,111,110,115,11,14,99,111,95,102,111,99,117,115,115,101, + 108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12, + 99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116, + 105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116, + 15,99,111,95,112,114,111,112,111,114,116,105,111,110,97,108,12,99,111,95, + 115,97,118,101,115,116,97,116,101,0,10,119,105,100,103,101,116,110,97,109, + 101,6,15,115,111,117,114,99,101,102,105,101,108,100,110,97,109,101,9,100, + 97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116, + 114,105,110,103,100,97,116,97,108,105,115,116,0,7,8,100,97,116,97,116, + 121,112,101,1,5,119,105,100,116,104,2,62,7,111,112,116,105,111,110,115, + 11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95, + 109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101, + 108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12, + 99,111,95,114,111,119,115,101,108,101,99,116,15,99,111,95,112,114,111,112, + 111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,118,97,108,117, + 101,12,99,111,95,115,97,118,101,115,116,97,116,101,0,10,119,105,100,103, + 101,116,110,97,109,101,6,8,100,97,116,97,116,121,112,101,9,100,97,116, + 97,99,108,97,115,115,7,17,116,103,114,105,100,101,110,117,109,100,97,116, + 97,108,105,115,116,0,0,13,100,97,116,97,114,111,119,104,101,105,103,104, + 116,2,16,14,111,110,114,111,119,115,100,101,108,101,116,105,110,103,7,17, + 102,105,101,108,100,114,111,119,115,100,101,108,101,116,105,110,103,13,111,110, + 114,111,119,115,100,101,108,101,116,101,100,7,12,102,105,101,108,100,115,114, + 111,119,100,101,108,11,111,110,99,101,108,108,101,118,101,110,116,7,14,102, + 105,101,108,100,99,101,108,108,101,118,101,110,116,18,111,110,115,101,108,101, + 99,116,105,111,110,99,104,97,110,103,101,100,7,17,102,105,101,108,100,115, + 101,108,101,99,116,105,111,110,99,104,97,6,111,110,115,111,114,116,7,9, + 102,105,101,108,100,115,111,114,116,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,14,0,12,116,105,110,116,101,103,101,114,101,100,105,116,5, + 105,110,100,101,120,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49, + 11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104, + 116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,10,111,115,107,95, + 110,111,115,107,105,110,0,8,116,97,98,111,114,100,101,114,2,1,7,118, + 105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,0,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2, + 13,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110, + 115,101,100,105,116,49,11,13,111,101,49,95,115,97,118,101,118,97,108,117, + 101,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0, + 12,116,112,111,105,110,116,101,114,101,100,105,116,7,102,105,101,108,100,112, + 111,11,111,112,116,105,111,110,115,115,107,105,110,11,10,111,115,107,95,110, + 111,115,107,105,110,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111, + 117,110,100,115,95,120,2,14,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,120,2,12,9,98,111,117,110,100,115,95,99, + 121,2,16,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95, + 117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117, + 101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108, + 14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101, + 97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108, + 101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99, + 117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13, + 111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116, + 111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0, + 12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97, + 117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121, + 101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116, + 101,0,7,118,105,115,105,98,108,101,8,0,0,11,116,115,116,114,105,110, + 103,101,100,105,116,9,102,105,101,108,100,110,97,109,101,11,111,112,116,105, + 111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117, + 116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,3, + 7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,27, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,2,92,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105, + 111,110,115,101,100,105,116,49,11,0,11,111,112,116,105,111,110,115,101,100, + 105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95, + 99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109, + 114,99,97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117, + 114,110,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114, + 101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95, + 101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111, + 110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116, + 25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115, + 116,99,108,105,99,107,22,111,101,95,102,111,99,117,115,114,101,99,116,111, + 110,114,101,97,100,111,110,108,121,10,111,101,95,110,111,116,110,117,108,108, + 0,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,17,102,105,101, + 108,100,115,100,97,116,97,101,110,116,101,114,101,100,10,111,110,115,101,116, + 118,97,108,117,101,7,17,102,105,101,108,100,110,97,109,101,115,101,116,118, + 97,108,117,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,0,17,116,100,114,111,112,100,111,119,110,108,105,115,116,101,100,105,116, + 15,115,111,117,114,99,101,102,105,101,108,100,110,97,109,101,14,111,112,116, + 105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110, + 116,103,108,121,112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110, + 115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116, + 111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101,118,101,108,111, + 2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116, + 4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,10,102,114,108,95,108, + 101,118,101,108,105,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111, + 114,4,5,0,0,144,8,116,97,98,111,114,100,101,114,2,4,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,120,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,119, + 9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115, + 101,100,105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105,116,11, + 12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111, + 115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97, + 110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12, + 111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101, + 116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105, + 116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110, + 116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101, + 95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108, + 105,99,107,22,111,101,95,102,111,99,117,115,114,101,99,116,111,110,114,101, + 97,100,111,110,108,121,10,111,101,95,110,111,116,110,117,108,108,0,13,111, + 110,100,97,116,97,101,110,116,101,114,101,100,7,17,102,105,101,108,100,115, + 100,97,116,97,101,110,116,101,114,101,100,10,111,110,115,101,116,118,97,108, + 117,101,7,17,115,111,117,114,99,101,102,105,101,108,100,115,101,116,101,120, + 101,16,100,114,111,112,100,111,119,110,46,111,112,116,105,111,110,115,11,16, + 100,101,111,95,97,117,116,111,100,114,111,112,100,111,119,110,15,100,101,111, + 95,107,101,121,100,114,111,112,100,111,119,110,0,19,100,114,111,112,100,111, + 119,110,46,99,111,108,115,46,99,111,117,110,116,2,1,19,100,114,111,112, + 100,111,119,110,46,99,111,108,115,46,105,116,101,109,115,14,1,0,0,16, + 111,110,98,101,102,111,114,101,100,114,111,112,100,111,119,110,7,16,115,111, + 117,114,99,101,98,101,102,100,114,111,112,101,120,101,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,14,0,0,13,116,101,110,117,109,116,121, + 112,101,101,100,105,116,8,100,97,116,97,116,121,112,101,14,111,112,116,105, + 111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116, + 103,108,121,112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110,115, + 115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111, + 110,111,110,108,121,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2, + 0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4, + 2,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99,111, + 108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,20,102,114,108,49,95,102,114,97,109,101, + 102,97,99,101,111,102,102,115,101,116,28,102,114,108,49,95,102,114,97,109, + 101,102,97,99,101,111,102,102,115,101,116,100,105,115,97,98,108,101,100,25, + 102,114,108,49,95,102,114,97,109,101,102,97,99,101,111,102,102,115,101,116, + 109,111,117,115,101,27,102,114,108,49,95,102,114,97,109,101,102,97,99,101, + 111,102,102,115,101,116,99,108,105,99,107,101,100,26,102,114,108,49,95,102, + 114,97,109,101,102,97,99,101,111,102,102,115,101,116,97,99,116,105,118,101, + 0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,119,105,100,116,104, + 2,15,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111, + 114,4,5,0,0,144,8,116,97,98,111,114,100,101,114,2,5,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,240,0,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2, + 62,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110, + 115,101,100,105,116,49,11,13,111,101,49,95,115,97,118,101,118,97,108,117, + 101,0,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117, + 110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101, + 114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14, + 111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97, + 116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101, + 99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117, + 114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111, + 101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111, + 115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,22,111, + 101,95,102,111,99,117,115,114,101,99,116,111,110,114,101,97,100,111,110,108, + 121,10,111,101,95,110,111,116,110,117,108,108,0,13,111,110,100,97,116,97, + 101,110,116,101,114,101,100,7,17,102,105,101,108,100,115,100,97,116,97,101, + 110,116,101,114,101,100,12,118,97,108,117,101,100,101,102,97,117,108,116,2, + 0,3,109,105,110,2,0,19,100,114,111,112,100,111,119,110,46,99,111,108, + 115,46,99,111,117,110,116,2,1,19,100,114,111,112,100,111,119,110,46,99, + 111,108,115,46,105,116,101,109,115,14,1,0,0,6,111,110,105,110,105,116, + 7,13,105,110,105,116,102,105,101,108,100,107,105,110,100,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,0,9,116,115,112,108,105, + 116,116,101,114,8,115,112,108,105,116,116,101,114,5,99,111,108,111,114,4, + 3,0,0,144,8,116,97,98,111,114,100,101,114,2,6,8,98,111,117,110, + 100,115,95,120,3,75,1,8,98,111,117,110,100,115,95,121,2,24,9,98, + 111,117,110,100,115,95,99,120,2,5,9,98,111,117,110,100,115,95,99,121, + 3,154,0,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116, + 6,97,110,95,116,111,112,9,97,110,95,98,111,116,116,111,109,0,7,111, + 112,116,105,111,110,115,11,9,115,112,111,95,104,109,111,118,101,9,115,112, + 111,95,104,112,114,111,112,0,8,108,105,110,107,108,101,102,116,7,6,102, + 105,101,108,100,115,9,108,105,110,107,114,105,103,104,116,7,10,102,105,101, + 108,100,100,101,102,108,105,8,115,116,97,116,102,105,108,101,7,10,116,115, + 116,97,116,102,105,108,101,49,14,111,110,117,112,100,97,116,101,108,97,121, + 111,117,116,7,12,115,112,108,105,116,116,101,114,117,112,100,97,0,0,17, + 116,115,116,111,99,107,103,108,121,112,104,98,117,116,116,111,110,10,100,101, + 102,116,111,102,105,101,108,100,13,111,112,116,105,111,110,115,119,105,100,103, + 101,116,11,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116, + 115,0,8,116,97,98,111,114,100,101,114,2,5,8,98,111,117,110,100,115, + 95,120,3,82,1,8,98,111,117,110,100,115,95,121,2,5,9,98,111,117, + 110,100,115,95,99,120,2,28,9,98,111,117,110,100,115,95,99,121,2,15, + 5,115,116,97,116,101,11,11,97,115,95,100,105,115,97,98,108,101,100,16, + 97,115,95,108,111,99,97,108,100,105,115,97,98,108,101,100,17,97,115,95, + 108,111,99,97,108,105,109,97,103,101,108,105,115,116,15,97,115,95,108,111, + 99,97,108,105,109,97,103,101,110,114,17,97,115,95,108,111,99,97,108,111, + 110,101,120,101,99,117,116,101,0,5,103,108,121,112,104,7,13,115,116,103, + 95,97,114,114,111,119,108,101,102,116,9,111,110,101,120,101,99,117,116,101, + 7,14,116,114,97,110,115,102,101,114,102,105,101,108,100,115,0,0,17,116, + 115,116,111,99,107,103,108,121,112,104,98,117,116,116,111,110,10,102,105,101, + 108,100,116,111,100,101,102,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 0,8,116,97,98,111,114,100,101,114,2,4,8,98,111,117,110,100,115,95, + 120,3,47,1,8,98,111,117,110,100,115,95,121,2,5,9,98,111,117,110, + 100,115,95,99,120,2,28,9,98,111,117,110,100,115,95,99,121,2,15,5, + 115,116,97,116,101,11,11,97,115,95,100,105,115,97,98,108,101,100,16,97, + 115,95,108,111,99,97,108,100,105,115,97,98,108,101,100,17,97,115,95,108, + 111,99,97,108,105,109,97,103,101,108,105,115,116,15,97,115,95,108,111,99, + 97,108,105,109,97,103,101,110,114,17,97,115,95,108,111,99,97,108,111,110, + 101,120,101,99,117,116,101,0,5,103,108,121,112,104,7,14,115,116,103,95, + 97,114,114,111,119,114,105,103,104,116,9,111,110,101,120,101,99,117,116,101, + 7,12,100,101,108,101,116,101,102,105,101,108,100,115,0,0,9,116,115,116, + 97,116,102,105,108,101,10,116,115,116,97,116,102,105,108,101,49,8,102,105, + 108,101,110,97,109,101,6,18,105,102,105,102,105,101,108,100,101,100,105,116, + 111,114,46,115,116,97,7,111,112,116,105,111,110,115,11,10,115,102,111,95, + 109,101,109,111,114,121,0,4,108,101,102,116,2,24,3,116,111,112,3,152, + 0,0,0,16,116,115,116,114,105,110,103,99,111,110,116,97,105,110,101,114, + 1,99,12,115,116,114,105,110,103,115,46,100,97,116,97,1,6,10,67,111, + 110,110,101,99,116,105,111,110,0,4,108,101,102,116,3,152,0,3,116,111, + 112,3,152,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tmseififieldeditorfo,''); +end. diff --git a/mseide-msegui/lib/common/designutils/mseiircoeffeditor.mfm b/mseide-msegui/lib/common/designutils/mseiircoeffeditor.mfm new file mode 100644 index 0000000..bcc35c1 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseiircoeffeditor.mfm @@ -0,0 +1,189 @@ +object iircoeffeditorfo: tiircoeffeditorfo + bounds_x = 72 + bounds_y = 206 + bounds_cx = 522 + bounds_cy = 263 + container.bounds = ( + 0 + 0 + 522 + 263 + ) + statfile = tstatfile1 + caption = 'IIR Filter Coefficients' + moduleclassname = 'tmseform' + object grid: twidgetgrid + bounds_x = 0 + bounds_y = 0 + bounds_cx = 521 + bounds_cy = 221 + anchors = [an_left, an_top, an_right, an_bottom] + optionsgrid = [og_focuscellonenter, og_rowheight, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixcols.count = 1 + fixcols.items = < + item + width = 62 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 4 + captions.items = < + item + caption = 'Numerator' + end + item + caption = 'Denominator' + end + item + caption = 'Internal Num.' + end + item + caption = 'Internal Den.' + end> + captionsfix.count = 1 + captionsfix.items = < + item + caption = 'sect:z^n' + end> + end> + datacols.count = 4 + datacols.options = [co_proportional, co_savevalue, co_savestate, co_mousescrollrow] + datacols.items = < + item[numed] + width = 113 + options = [co_mouseselect, co_keyselect, co_multiselect, co_proportional, co_savevalue, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'numed' + dataclass = tgridrealdatalist + end + item[dened] + width = 106 + options = [co_mouseselect, co_keyselect, co_multiselect, co_proportional, co_savevalue, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'dened' + dataclass = tgridrealdatalist + end + item[numdi] + color = -1879048185 + width = 114 + options = [co_readonly, co_proportional, co_savevalue, co_savestate, co_mousescrollrow] + widgetname = 'numdi' + dataclass = tgridrealdatalist + end + item[dendi] + color = -1879048185 + width = 117 + options = [co_readonly, co_fill, co_savevalue, co_savestate, co_mousescrollrow] + widgetname = 'dendi' + dataclass = tgridrealdatalist + end> + datarowheight = 16 + reffontheight = 14 + object numed: trealedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 113 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + ondataentered = datentexe + value = 0 + valuedefault = 0 + valuerange = 1 + valuestart = 0 + min = -1E+038 + max = 1E+038 + reffontheight = 14 + end + object dened: trealedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 2 + visible = False + bounds_x = 114 + bounds_y = 0 + bounds_cx = 106 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + ondataentered = datentexe + value = 0 + valuedefault = 0 + valuerange = 1 + valuestart = 0 + min = -1E+038 + max = 1E+038 + reffontheight = 14 + end + object numdi: trealedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 3 + visible = False + bounds_x = 221 + bounds_y = 0 + bounds_cx = 114 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly] + textflagsactive = [tf_right, tf_ycentered] + value = -Inf + valuedefault = -Inf + valuerange = 1 + valuestart = 0 + min = -Inf + max = 1E+038 + reffontheight = 14 + end + object dendi: trealedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 4 + visible = False + bounds_x = 336 + bounds_y = 0 + bounds_cx = 117 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly] + textflagsactive = [tf_right, tf_ycentered] + value = -Inf + valuedefault = -Inf + valuerange = 1 + valuestart = 0 + min = -Inf + max = 1E+038 + reffontheight = 14 + end + end + object ok: tbutton + taborder = 1 + bounds_x = 395 + bounds_y = 232 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + end + object cancel: tbutton + taborder = 2 + bounds_x = 459 + bounds_y = 232 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + end + object tstatfile1: tstatfile + filename = 'iircoeffeditor.sta' + options = [sfo_memory] + left = 56 + top = 48 + end +end diff --git a/mseide-msegui/lib/common/designutils/mseiircoeffeditor.pas b/mseide-msegui/lib/common/designutils/mseiircoeffeditor.pas new file mode 100644 index 0000000..075f6bd --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseiircoeffeditor.pas @@ -0,0 +1,44 @@ +unit mseiircoeffeditor; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,msewidgets,mseforms,msestatfile, + msedataedits,mseedit,msegrids,mseificomp,mseificompglob,mseifiglob,msestrings, + msewidgetgrid,msesimplewidgets; +type + tiircoeffeditorfo = class(tmseform) + tstatfile1: tstatfile; + grid: twidgetgrid; + ok: tbutton; + cancel: tbutton; + numed: trealedit; + dened: trealedit; + numdi: trealedit; + dendi: trealedit; + procedure datentexe(const sender: TObject); + end; + +implementation +uses + mseiircoeffeditor_mfm; + +procedure tiircoeffeditorfo.datentexe(const sender: TObject); +var + int1: integer; + norm: real; +begin + norm:= 0; + for int1:= 0 to grid.rowhigh do begin + if (int1 = 0) or (grid.rowlinewidth[int1-1] > 1) then begin + if dened[int1] = 0 then begin + dened[int1]:= 1.0; + end; + norm:= dened[int1]; + end; + numdi[int1]:= numed[int1]/norm; + dendi[int1]:= dened[int1]/norm; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/mseiircoeffeditor_mfm.pas b/mseide-msegui/lib/common/designutils/mseiircoeffeditor_mfm.pas new file mode 100644 index 0000000..a3c18af --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseiircoeffeditor_mfm.pas @@ -0,0 +1,202 @@ +unit mseiircoeffeditor_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,mseiircoeffeditor; + +const + objdata: record size: integer; data: array[0..3690] of byte end = + (size: 3691; data: ( + 84,80,70,48,17,116,105,105,114,99,111,101,102,102,101,100,105,116,111,114, + 102,111,16,105,105,114,99,111,101,102,102,101,100,105,116,111,114,102,111,8, + 98,111,117,110,100,115,95,120,2,72,8,98,111,117,110,100,115,95,121,3, + 206,0,9,98,111,117,110,100,115,95,99,120,3,10,2,9,98,111,117,110, + 100,115,95,99,121,3,7,1,16,99,111,110,116,97,105,110,101,114,46,98, + 111,117,110,100,115,1,2,0,2,0,3,10,2,3,7,1,0,8,115,116, + 97,116,102,105,108,101,7,10,116,115,116,97,116,102,105,108,101,49,7,99, + 97,112,116,105,111,110,6,23,73,73,82,32,70,105,108,116,101,114,32,67, + 111,101,102,102,105,99,105,101,110,116,115,15,109,111,100,117,108,101,99,108, + 97,115,115,110,97,109,101,6,8,116,109,115,101,102,111,114,109,0,11,116, + 119,105,100,103,101,116,103,114,105,100,4,103,114,105,100,8,98,111,117,110, + 100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,120,3,9,2,9,98,111,117,110,100,115,95,99,121, + 3,221,0,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116, + 6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,9,97,110,95, + 98,111,116,116,111,109,0,11,111,112,116,105,111,110,115,103,114,105,100,11, + 19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101,114, + 12,111,103,95,114,111,119,104,101,105,103,104,116,20,111,103,95,99,111,108, + 99,104,97,110,103,101,111,110,116,97,98,107,101,121,10,111,103,95,119,114, + 97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112,117,112,17,111, + 103,95,109,111,117,115,101,115,99,114,111,108,108,99,111,108,0,13,102,105, + 120,99,111,108,115,46,99,111,117,110,116,2,1,13,102,105,120,99,111,108, + 115,46,105,116,101,109,115,14,1,5,119,105,100,116,104,2,62,0,0,13, + 102,105,120,114,111,119,115,46,99,111,117,110,116,2,1,13,102,105,120,114, + 111,119,115,46,105,116,101,109,115,14,1,6,104,101,105,103,104,116,2,16, + 14,99,97,112,116,105,111,110,115,46,99,111,117,110,116,2,4,14,99,97, + 112,116,105,111,110,115,46,105,116,101,109,115,14,1,7,99,97,112,116,105, + 111,110,6,9,78,117,109,101,114,97,116,111,114,0,1,7,99,97,112,116, + 105,111,110,6,11,68,101,110,111,109,105,110,97,116,111,114,0,1,7,99, + 97,112,116,105,111,110,6,13,73,110,116,101,114,110,97,108,32,78,117,109, + 46,0,1,7,99,97,112,116,105,111,110,6,13,73,110,116,101,114,110,97, + 108,32,68,101,110,46,0,0,17,99,97,112,116,105,111,110,115,102,105,120, + 46,99,111,117,110,116,2,1,17,99,97,112,116,105,111,110,115,102,105,120, + 46,105,116,101,109,115,14,1,7,99,97,112,116,105,111,110,6,8,115,101, + 99,116,58,122,94,110,0,0,0,0,14,100,97,116,97,99,111,108,115,46, + 99,111,117,110,116,2,4,16,100,97,116,97,99,111,108,115,46,111,112,116, + 105,111,110,115,11,15,99,111,95,112,114,111,112,111,114,116,105,111,110,97, + 108,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111,95,115,97, + 118,101,115,116,97,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111, + 108,108,114,111,119,0,14,100,97,116,97,99,111,108,115,46,105,116,101,109, + 115,14,7,5,110,117,109,101,100,1,5,119,105,100,116,104,2,113,7,111, + 112,116,105,111,110,115,11,14,99,111,95,109,111,117,115,101,115,101,108,101, + 99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109, + 117,108,116,105,115,101,108,101,99,116,15,99,111,95,112,114,111,112,111,114, + 116,105,111,110,97,108,12,99,111,95,115,97,118,101,118,97,108,117,101,12, + 99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99, + 111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109, + 111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101, + 116,110,97,109,101,6,5,110,117,109,101,100,9,100,97,116,97,99,108,97, + 115,115,7,17,116,103,114,105,100,114,101,97,108,100,97,116,97,108,105,115, + 116,0,7,5,100,101,110,101,100,1,5,119,105,100,116,104,2,106,7,111, + 112,116,105,111,110,115,11,14,99,111,95,109,111,117,115,101,115,101,108,101, + 99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109, + 117,108,116,105,115,101,108,101,99,116,15,99,111,95,112,114,111,112,111,114, + 116,105,111,110,97,108,12,99,111,95,115,97,118,101,118,97,108,117,101,12, + 99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99, + 111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109, + 111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101, + 116,110,97,109,101,6,5,100,101,110,101,100,9,100,97,116,97,99,108,97, + 115,115,7,17,116,103,114,105,100,114,101,97,108,100,97,116,97,108,105,115, + 116,0,7,5,110,117,109,100,105,1,5,99,111,108,111,114,4,7,0,0, + 144,5,119,105,100,116,104,2,114,7,111,112,116,105,111,110,115,11,11,99, + 111,95,114,101,97,100,111,110,108,121,15,99,111,95,112,114,111,112,111,114, + 116,105,111,110,97,108,12,99,111,95,115,97,118,101,118,97,108,117,101,12, + 99,111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109,111,117,115, + 101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97, + 109,101,6,5,110,117,109,100,105,9,100,97,116,97,99,108,97,115,115,7, + 17,116,103,114,105,100,114,101,97,108,100,97,116,97,108,105,115,116,0,7, + 5,100,101,110,100,105,1,5,99,111,108,111,114,4,7,0,0,144,5,119, + 105,100,116,104,2,117,7,111,112,116,105,111,110,115,11,11,99,111,95,114, + 101,97,100,111,110,108,121,7,99,111,95,102,105,108,108,12,99,111,95,115, + 97,118,101,118,97,108,117,101,12,99,111,95,115,97,118,101,115,116,97,116, + 101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0, + 10,119,105,100,103,101,116,110,97,109,101,6,5,100,101,110,100,105,9,100, + 97,116,97,99,108,97,115,115,7,17,116,103,114,105,100,114,101,97,108,100, + 97,116,97,108,105,115,116,0,0,13,100,97,116,97,114,111,119,104,101,105, + 103,104,116,2,16,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,9,116,114,101,97,108,101,100,105,116,5,110,117,109,101,100,14,111, + 112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102, + 111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,11,111,112,116,105, + 111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117, + 116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,1, + 7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,2,113,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105, + 111,110,115,101,100,105,116,49,11,13,111,101,49,95,115,97,118,101,118,97, + 108,117,101,0,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,9, + 100,97,116,101,110,116,101,120,101,5,118,97,108,117,101,2,0,12,118,97, + 108,117,101,100,101,102,97,117,108,116,2,0,10,118,97,108,117,101,114,97, + 110,103,101,2,1,10,118,97,108,117,101,115,116,97,114,116,2,0,3,109, + 105,110,5,245,136,13,181,80,153,118,150,125,192,3,109,97,120,5,245,136, + 13,181,80,153,118,150,125,64,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,14,0,0,9,116,114,101,97,108,101,100,105,116,5,100,101,110, + 101,100,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111, + 119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,11, + 111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97, + 109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100, + 101,114,2,2,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115, + 95,120,2,114,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,120,2,106,9,98,111,117,110,100,115,95,99,121,2,16,12, + 111,112,116,105,111,110,115,101,100,105,116,49,11,13,111,101,49,95,115,97, + 118,101,118,97,108,117,101,0,13,111,110,100,97,116,97,101,110,116,101,114, + 101,100,7,9,100,97,116,101,110,116,101,120,101,5,118,97,108,117,101,2, + 0,12,118,97,108,117,101,100,101,102,97,117,108,116,2,0,10,118,97,108, + 117,101,114,97,110,103,101,2,1,10,118,97,108,117,101,115,116,97,114,116, + 2,0,3,109,105,110,5,245,136,13,181,80,153,118,150,125,192,3,109,97, + 120,5,245,136,13,181,80,153,118,150,125,64,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,14,0,0,9,116,114,101,97,108,101,100,105,116, + 5,110,117,109,100,105,14,111,112,116,105,111,110,115,119,105,100,103,101,116, + 49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103, + 104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107, + 95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97, + 98,111,114,100,101,114,2,3,7,118,105,115,105,98,108,101,8,8,98,111, + 117,110,100,115,95,120,3,221,0,8,98,111,117,110,100,115,95,121,2,0, + 9,98,111,117,110,100,115,95,99,120,2,114,9,98,111,117,110,100,115,95, + 99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,13,111, + 101,49,95,115,97,118,101,118,97,108,117,101,0,11,111,112,116,105,111,110, + 115,101,100,105,116,11,11,111,101,95,114,101,97,100,111,110,108,121,12,111, + 101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101, + 113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99, + 101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101, + 95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115, + 101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111, + 110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101, + 114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97, + 117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99, + 107,22,111,101,95,102,111,99,117,115,114,101,99,116,111,110,114,101,97,100, + 111,110,108,121,0,15,116,101,120,116,102,108,97,103,115,97,99,116,105,118, + 101,11,8,116,102,95,114,105,103,104,116,12,116,102,95,121,99,101,110,116, + 101,114,101,100,0,5,118,97,108,117,101,5,0,0,0,0,0,0,0,128, + 255,255,12,118,97,108,117,101,100,101,102,97,117,108,116,5,0,0,0,0, + 0,0,0,128,255,255,10,118,97,108,117,101,114,97,110,103,101,2,1,10, + 118,97,108,117,101,115,116,97,114,116,2,0,3,109,105,110,5,0,0,0, + 0,0,0,0,128,255,255,3,109,97,120,5,245,136,13,181,80,153,118,150, + 125,64,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0, + 9,116,114,101,97,108,101,100,105,116,5,100,101,110,100,105,14,111,112,116, + 105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110, + 116,103,108,121,112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110, + 115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116, + 111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,4,7,118, + 105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,80,1,8, + 98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120, + 2,117,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111, + 110,115,101,100,105,116,49,11,13,111,101,49,95,115,97,118,101,118,97,108, + 117,101,0,11,111,112,116,105,111,110,115,101,100,105,116,11,11,111,101,95, + 114,101,97,100,111,110,108,121,12,111,101,95,117,110,100,111,111,110,101,115, + 99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99, + 104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105,102, + 116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114,110, + 20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105, + 116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101, + 95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115, + 101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111, + 110,102,105,114,115,116,99,108,105,99,107,22,111,101,95,102,111,99,117,115, + 114,101,99,116,111,110,114,101,97,100,111,110,108,121,0,15,116,101,120,116, + 102,108,97,103,115,97,99,116,105,118,101,11,8,116,102,95,114,105,103,104, + 116,12,116,102,95,121,99,101,110,116,101,114,101,100,0,5,118,97,108,117, + 101,5,0,0,0,0,0,0,0,128,255,255,12,118,97,108,117,101,100,101, + 102,97,117,108,116,5,0,0,0,0,0,0,0,128,255,255,10,118,97,108, + 117,101,114,97,110,103,101,2,1,10,118,97,108,117,101,115,116,97,114,116, + 2,0,3,109,105,110,5,0,0,0,0,0,0,0,128,255,255,3,109,97, + 120,5,245,136,13,181,80,153,118,150,125,64,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,14,0,0,0,7,116,98,117,116,116,111,110,2, + 111,107,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115, + 95,120,3,139,1,8,98,111,117,110,100,115,95,121,3,232,0,9,98,111, + 117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2, + 20,7,97,110,99,104,111,114,115,11,8,97,110,95,114,105,103,104,116,9, + 97,110,95,98,111,116,116,111,109,0,5,115,116,97,116,101,11,10,97,115, + 95,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,100,101,102, + 97,117,108,116,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110, + 0,7,99,97,112,116,105,111,110,6,3,38,79,75,11,109,111,100,97,108, + 114,101,115,117,108,116,7,5,109,114,95,111,107,0,0,7,116,98,117,116, + 116,111,110,6,99,97,110,99,101,108,8,116,97,98,111,114,100,101,114,2, + 2,8,98,111,117,110,100,115,95,120,3,203,1,8,98,111,117,110,100,115, + 95,121,3,232,0,9,98,111,117,110,100,115,95,99,120,2,50,9,98,111, + 117,110,100,115,95,99,121,2,20,7,97,110,99,104,111,114,115,11,8,97, + 110,95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,5,115, + 116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111, + 110,0,7,99,97,112,116,105,111,110,6,7,38,67,97,110,99,101,108,11, + 109,111,100,97,108,114,101,115,117,108,116,7,9,109,114,95,99,97,110,99, + 101,108,0,0,9,116,115,116,97,116,102,105,108,101,10,116,115,116,97,116, + 102,105,108,101,49,8,102,105,108,101,110,97,109,101,6,18,105,105,114,99, + 111,101,102,102,101,100,105,116,111,114,46,115,116,97,7,111,112,116,105,111, + 110,115,11,10,115,102,111,95,109,101,109,111,114,121,0,4,108,101,102,116, + 2,56,3,116,111,112,2,48,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tiircoeffeditorfo,''); +end. diff --git a/mseide-msegui/lib/common/designutils/mseimagelisteditor.mfm b/mseide-msegui/lib/common/designutils/mseimagelisteditor.mfm new file mode 100644 index 0000000..f94cbf1 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseimagelisteditor.mfm @@ -0,0 +1,286 @@ +object imagelisteditorfo: timagelisteditorfo + optionswidget = [ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets, ow_hinton] + visible = False + bounds_x = 220 + bounds_y = 297 + bounds_cx = 508 + bounds_cy = 355 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 508 + 355 + ) + options = [fo_closeonesc, fo_localshortcuts, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savestate] + statfile = statfile1 + caption = 'Imagelist Editor' + moduleclassname = 'tmseform' + object disp: tlistview + optionswidget1 = [ow1_fontglyphheight] + frame.localprops = [] + frame.localprops1 = [] + popupmenu = popup + bounds_x = 0 + bounds_y = 0 + bounds_cx = 508 + bounds_cy = 293 + anchors = [an_top, an_bottom] + cellheight = 62 + optionsgrid = [og_colsizing, og_rowsizing, og_focuscellonenter, og_wraprow, og_wrapcol, og_autopopup] + options = [lvo_readonly, lvo_mousemoving, lvo_keymoving, lvo_horz, lvo_drawfocus, lvo_focusselect, lvo_mouseselect, lvo_keyselect, lvo_multiselect, lvo_locate] + itemlist.oncreateitem = createitemev + itemlist.captionpos = cp_bottom + itemlist.imagelist = imagelist + itemlist.imagewidth = 16 + itemlist.imageheight = 16 + onlayoutchanged = layoutchanged + onitemevent = disponitemevent + onitemsmoved = disponitemsmoved + reffontheight = 14 + end + object tlayouter1: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + frame.framei_bottom = 5 + frame.localprops = [frl_fibottom] + frame.localprops1 = [] + taborder = 1 + bounds_x = 0 + bounds_y = 296 + bounds_cx = 314 + bounds_cy = 59 + anchors = [an_left, an_bottom] + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + linktop = disp + dist_top = 3 + options = [spao_gluebottom] + object la2: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + taborder = 1 + bounds_x = 0 + bounds_y = 33 + bounds_cx = 297 + bounds_cy = 21 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + optionslayout = [lao_aligny] + dist_top = 4 + object tlayouter2: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + taborder = 1 + bounds_x = 80 + bounds_y = 0 + bounds_cx = 217 + bounds_cy = 21 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + optionslayout = [lao_placex] + place_mindist = 5 + place_maxdist = 5 + dist_top = 3 + object ok: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + taborder = 2 + bounds_x = 110 + bounds_y = 1 + bounds_cx = 50 + bounds_cy = 20 + bounds_cxmin = 50 + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + reffontheight = 14 + end + object cancel: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + taborder = 3 + bounds_x = 165 + bounds_y = 1 + bounds_cx = 52 + bounds_cy = 20 + bounds_cxmin = 50 + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + reffontheight = 14 + end + object clear: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + taborder = 1 + bounds_x = 55 + bounds_y = 1 + bounds_cx = 50 + bounds_cy = 20 + bounds_cxmin = 50 + state = [as_localcaption, as_localonexecute] + caption = 'C&lear' + onexecute = clearonexecute + reffontheight = 14 + end + object add: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + bounds_x = 0 + bounds_y = 1 + bounds_cx = 50 + bounds_cy = 20 + bounds_cxmin = 50 + state = [as_localcaption, as_localonexecute] + caption = '&Add' + onexecute = addonexecute + reffontheight = 14 + end + end + object stretch: tbooleanedit + frame.caption = '&stretch' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 48 + 2 + ) + bounds_x = 6 + bounds_y = 3 + bounds_cx = 61 + bounds_cy = 16 + statfile = statfile1 + value = True + end + end + object la1: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + bounds_x = 6 + bounds_y = 0 + bounds_cx = 308 + bounds_cy = 30 + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + optionslayout = [lao_placex, lao_aligny] + align_glue = wam_start + place_mindist = 4 + place_maxdist = 4 + linkbottom = la2 + dist_bottom = 3 + object transparentcolor: tcoloredit + frame.caption = '&Transp.'#10'color' + frame.captionpos = cp_right + frame.localprops = [] + frame.localprops1 = [] + frame.button.width = 13 + frame.button.color = -2147483646 + frame.buttons.count = 2 + frame.buttons.items = < + item + width = 13 + color = -2147483646 + end + item + width = 13 + color = -2147483646 + imagenr = 17 + end> + frame.buttonellipse.width = 13 + frame.buttonellipse.color = -2147483646 + frame.buttonellipse.imagenr = 17 + frame.outerframe = ( + 0 + 5 + 50 + 5 + ) + taborder = 1 + hint = 'Transparent color' + bounds_x = 69 + bounds_y = 0 + bounds_cx = 156 + bounds_cy = 30 + statfile = statfile1 + value = -2147483647 + reffontheight = 14 + end + object masked: tbooleanedit + frame.caption = '&masked' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 52 + 2 + ) + bounds_x = 0 + bounds_y = 8 + bounds_cx = 65 + bounds_cy = 16 + value = True + end + object versionnum: tenumedit + frame.caption = 'Vers.'#10'Nr.' + frame.captionpos = cp_right + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + end> + frame.outerframe = ( + 0 + 5 + 35 + 5 + ) + taborder = 2 + hint = 'Current imagelist version number' + bounds_x = 229 + bounds_y = 0 + bounds_cx = 79 + bounds_cy = 30 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savevalue, oe1_savestate] + ondataentered = versiondatentev + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + value = 0 + valuedefault = 0 + min = 0 + onsetvalue = versionsetev + reffontheight = 14 + end + end + end + object imagelist: timagelist + transparentcolor = -2147483647 + left = 24 + top = 176 + end + object filedialog: tfiledialog + statfile = statfile1 + left = 112 + top = 176 + end + object statfile1: tstatfile + filename = 'imagelisteditor.sta' + options = [sfo_memory] + onstatupdate = statupdateev + left = 200 + top = 176 + end + object popup: tpopupmenu + onupdate = updatemenuexe + menu.submenu.count = 2 + menu.submenu.items = < + item + caption = 'Copy Items' + state = [as_localcaption, as_localonexecute] + onexecute = copyexe + end + item + caption = 'Paste Items' + state = [as_localcaption, as_localonexecute] + onexecute = pasteexe + end> + left = 48 + top = 96 + end +end diff --git a/mseide-msegui/lib/common/designutils/mseimagelisteditor.pas b/mseide-msegui/lib/common/designutils/mseimagelisteditor.pas new file mode 100644 index 0000000..8caed58 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseimagelisteditor.pas @@ -0,0 +1,388 @@ +{ MSEgui Copyright (c) 1999-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseimagelisteditor; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseforms,msegui,mseglob,mseguiglob,msebitmap,msesimplewidgets,msegraphics, + mselistbrowser,msegrids,msefiledialog,msestat,msestatfile,msestrings, + msegraphedits,msecolordialog,msemenus,msesplitter,msegraphutils,msewidgets, + mseifiglob,msetypes,msedataedits,mseedit,msedatanodes,mseact,mseapplication, + mseificomp,mseificompglob,msestream,sysutils; + +const + imagelisteditorstatname = 'imagelisteditor.sta'; +type + timagelisteditorfo = class(tmseform) + disp: tlistview; + imagelist: timagelist; + filedialog: tfiledialog; + statfile1: tstatfile; + tlayouter1: tlayouter; + la2: tlayouter; + tlayouter2: tlayouter; + ok: tbutton; + cancel: tbutton; + clear: tbutton; + add: tbutton; + stretch: tbooleanedit; + la1: tlayouter; + transparentcolor: tcoloredit; + masked: tbooleanedit; + popup: tpopupmenu; + versionnum: tenumedit; + procedure addonexecute(const sender: tobject); + procedure clearonexecute(const sender: tobject); + procedure disponitemevent(const sender: tcustomlistview; const index: integer; + var info: celleventinfoty); + procedure disponitemsmoved(const sender: tcustomgrid; + const fromindex,toindex,count: integer); + +// procedure disponpaint(const sender: twidget; const canvas: tcanvas); + procedure layoutchanged(const sender: tcustomlistview); + procedure updatemenuexe(const sender: tcustommenu); + procedure pasteexe(const sender: TObject); + procedure copyexe(const sender: TObject); + procedure versionsetev(const sender: TObject; var avalue: Integer; + var accept: Boolean); + procedure versiondatentev(const sender: TObject); + procedure createitemev(const sender: tcustomitemlist; + var item: tlistedititem); + procedure statupdateev(const sender: TObject; const filer: tstatfiler); + private + fcopyitems: integerarty; + procedure listchange(const sender: tobject); + procedure updateversion(); + function focuseditem: int32; + end; + +function editimagelist(aimagelist: timagelist): modalresultty; + +implementation +uses + mseimagelisteditor_mfm,mseformatstr,msegridsglob,mseactions, + msekeyboard,msefileutils,msegraphicstream; + +var + currentversion: int32; + +type + timageitem = class(tlistedititem) + public + procedure drawimage(const acanvas: tcanvas; + var alayoutinfo: listitemlayoutinfoty) override; + end; + +function editimagelist(aimagelist: timagelist): modalresultty; +var + dialog: timagelisteditorfo; + i1: int32; +begin + dialog:= timagelisteditorfo.create(nil); + try + with dialog do begin + imagelist.onchange:= {$ifdef FPC}@{$endif}listchange; + imagelist.Assign(aimagelist); + for i1:= 0 to imagelist.versioncount - 1 do begin + versionnum.dropdown.cols.addrow([inttostrmse(i1)]); + end; + if (currentversion < 0) or + (currentversion >= imagelist.versioncount) then begin + currentversion:= 0; + end; + versionnum.value:= currentversion; +// imagelist.versioncurrent:= versionnum.value; + updateversion(); + + result:= show(true); + if result = mr_ok then begin + aimagelist.Assign(imagelist); + end; + end; + finally + dialog.destroy(); + end; +end; + +{ timagelisteditorfo } + +procedure timagelisteditorfo.addonexecute(const sender: tobject); +var + bmp: tmaskedbitmap; + ar1: filenamearty; + int1: integer; + i1: int32; +begin + filedialog.controller.filename:= filedialog.controller.lastdir; + filedialog.controller.filterlist.asarraya:= graphicfilefilternames; + filedialog.controller.filterlist.asarrayb:= graphicfilefiltermasks; + if filedialog.execute = mr_ok then begin + unquotefilename(filedialog.controller.filename,ar1); + bmp:= tmaskedbitmap.create(bmk_rgb); + try + i1:= focuseditem; + for int1:= 0 to high(ar1) do begin + bmp.transparentcolor:= cl_none; + bmp.loadfromfile(ar1[int1], + graphicformatlabels[filedialog.controller.filterindex],[]); + if not bmp.masked then begin + bmp.transparentcolor:= transparentcolor.value; + end; + bmp.masked:= masked.value; + if bmp.masked then begin + if bmp.colormask then begin + imagelist.colormask:= true; + end + else begin + if bmp.graymask and not imagelist.colormask then begin + imagelist.graymask:= true; + end; + end; + end; + if currentversion = 0 then begin + if stretch.value then begin + imagelist.addimage(bmp,[al_stretchx,al_stretchy,al_intpol]); + end + else begin + imagelist.addimage(bmp); + end; + end + else begin + if stretch.value then begin + imagelist.setimage(i1,bmp,[al_stretchx,al_stretchy,al_intpol], + currentversion); + end + else begin + imagelist.setimage(i1,bmp,[],currentversion); + end; + inc(i1); + if i1 >= imagelist.count then begin + i1:= 0; + end; + end; + end; + finally + bmp.Free; + end; + end; +end; + +procedure timagelisteditorfo.clearonexecute(const sender: tobject); +begin + imagelist.clear; +end; +{ +procedure timagelisteditorfo.disponpaint(const sender: twidget; + const canvas: tcanvas); +var + int1: integer; + dest: rectty; +begin + dest.pos:= nullpoint; + dest.size:= imagelist.size; + for int1:= 0 to fimagelist.count - 1 do begin + fimagelist.paint(canvas,dest,int1); + inc(dest.x,fimagelist.width); + if dest.x + dest.cx > disp.clientrect.cx then begin + dest.x:= 0; + inc(dest.y,fimagelist.height); + end; + end; +end; +} +procedure timagelisteditorfo.disponitemevent(const sender: tcustomlistview; + const index: integer; var info: celleventinfoty); +var + int1,int2: integer; + +begin + if info.eventkind = cek_keydown then begin + if (info.keyeventinfopo^.key = key_delete) and + (info.keyeventinfopo^.shiftstate * shiftstatesrepeatmask = []) then begin + if currentversion = 0 then begin + fcopyitems:= nil; + imagelist.beginupdate; + try + int2:= 0; + for int1:= 0 to disp.itemlist.count - 1 do begin + if ns_selected in disp.itemlist[int1].state then begin + imagelist.deleteimage(int2); + end + else begin + inc(int2); + end; + end; + with disp do begin + datacols.clearselection; + if focusedindex >= 0 then begin + items[focusedindex].selected:= true; + end; + end; + finally + imagelist.endupdate; + end; + end; + end + else begin + if issysshortcut(sho_copy,info.keyeventinfopo^) then begin + copyexe(nil); + end + else begin + if issysshortcut(sho_paste,info.keyeventinfopo^) then begin + pasteexe(nil); + end; + end; + end; + end; +end; + +procedure timagelisteditorfo.disponitemsmoved(const sender: tcustomgrid; + const fromindex,toindex,count: integer); +begin + imagelist.moveimage(fromindex,toindex,currentversion); + listchange(nil); +end; + +procedure timagelisteditorfo.listchange(const sender: tobject); +var + int1{,int2}: integer; +begin +// int2:= disp.itemlist.count; + fcopyitems:= nil; + disp.itemlist.count:= imagelist.count; + disp.beginupdate; + for int1:= 0 {int} to disp.itemlist.count - 1 do begin + with disp.itemlist[int1] do begin + caption:= inttostrmse(int1); + imagenr:= int1; + end; + end; + disp.endupdate; +end; + +procedure timagelisteditorfo.updateversion(); +begin + currentversion:= versionnum.value; + if currentversion = 0 then begin + clear.enabled:= true; + add.caption:= '&Add'; + end + else begin + clear.enabled:= false; + add.caption:= '&Replace'; + end; +end; + +function timagelisteditorfo.focuseditem: int32; +begin + result:= disp.focusedindex; + if result < 0 then begin + result:= 0; + end; +end; + +procedure timagelisteditorfo.layoutchanged(const sender: tcustomlistview); +begin + with sender do begin + itemlist.imagewidth:= cellwidth; + itemlist.imageheight:= cellheight - font.glyphheight; + end; +end; + +procedure timagelisteditorfo.updatemenuexe(const sender: tcustommenu); +begin + popup.menu[1].enabled:= fcopyitems <> nil; +end; + +procedure timagelisteditorfo.pasteexe(const sender: TObject); +var + insertid,copystart: int32; + i1,i2: int32; + bmp1: tmaskedbitmap; +begin + if fcopyitems <> nil then begin + bmp1:= tmaskedbitmap.create(imagelist.kind); + bmp1.maskkind:= imagelist.maskkind; + bmp1.masked:= imagelist.masked; + imagelist.beginupdate(); + insertid:= disp.focusedindex; + copystart:= imagelist.count; + if currentversion = 0 then begin + for i1:= 0 to high(fcopyitems) do begin + imagelist.getimage(fcopyitems[i1],bmp1); + imagelist.addimage(bmp1); + end; + for i1:= 0 to high(fcopyitems) do begin + imagelist.moveimage(copystart+i1,insertid+i1); + end; + end + else begin + i2:= focuseditem; + for i1:= 0 to high(fcopyitems) do begin + imagelist.getimage(fcopyitems[i1],bmp1,currentversion); + imagelist.setimage(i2,bmp1,[],currentversion); + inc(i2); + if i2 >= imagelist.count then begin + i2:= 0; + end; + end; + end; + imagelist.endupdate(); + bmp1.free; + end; +end; + +procedure timagelisteditorfo.copyexe(const sender: TObject); +begin + fcopyitems:= disp.getselectedindexes; +end; + +procedure timagelisteditorfo.versionsetev(const sender: TObject; + var avalue: Integer; var accept: Boolean); +begin + if avalue >= imagelist.versioncount then begin + avalue:= imagelist.versioncount -1; + end; + if avalue < 0 then begin + avalue:= 0; + end; +end; + +procedure timagelisteditorfo.versiondatentev(const sender: TObject); +begin + fcopyitems:= nil; + updateversion(); + disp.invalidate(); +end; + +procedure timagelisteditorfo.createitemev(const sender: tcustomitemlist; + var item: tlistedititem); +begin + item:= timageitem.create(sender); +end; + +procedure timagelisteditorfo.statupdateev(const sender: TObject; + const filer: tstatfiler); +begin + filer.updatevalue('currentversion',currentversion); +end; + +{ timageitem } + +procedure timageitem.drawimage(const acanvas: tcanvas; + var alayoutinfo: listitemlayoutinfoty); +begin + alayoutinfo.variable.imageversion:= currentversion; + inherited; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/mseimagelisteditor_mfm.pas b/mseide-msegui/lib/common/designutils/mseimagelisteditor_mfm.pas new file mode 100644 index 0000000..39bba86 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseimagelisteditor_mfm.pas @@ -0,0 +1,296 @@ +unit mseimagelisteditor_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,mseimagelisteditor; + +const + objdata: record size: integer; data: array[0..5571] of byte end = + (size: 5572; data: ( + 84,80,70,48,18,116,105,109,97,103,101,108,105,115,116,101,100,105,116,111, + 114,102,111,17,105,109,97,103,101,108,105,115,116,101,100,105,116,111,114,102, + 111,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102, + 111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115, + 111,117,116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95,100, + 101,115,116,114,111,121,119,105,100,103,101,116,115,9,111,119,95,104,105,110, + 116,111,110,0,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115, + 95,120,3,220,0,8,98,111,117,110,100,115,95,121,3,41,1,9,98,111, + 117,110,100,115,95,99,120,3,252,1,9,98,111,117,110,100,115,95,99,121, + 3,99,1,23,99,111,110,116,97,105,110,101,114,46,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99, + 117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,11,111,119,95,115,117,98,102,111,99,117,115,19,111,119,95,109,111,117, + 115,101,116,114,97,110,115,112,97,114,101,110,116,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,26,99,111,110,116,97,105,110, + 101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 0,27,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,16,99,111,110,116,97,105,110,101, + 114,46,98,111,117,110,100,115,1,2,0,2,0,3,252,1,3,99,1,0, + 7,111,112,116,105,111,110,115,11,13,102,111,95,99,108,111,115,101,111,110, + 101,115,99,17,102,111,95,108,111,99,97,108,115,104,111,114,116,99,117,116, + 115,15,102,111,95,97,117,116,111,114,101,97,100,115,116,97,116,16,102,111, + 95,97,117,116,111,119,114,105,116,101,115,116,97,116,10,102,111,95,115,97, + 118,101,112,111,115,12,102,111,95,115,97,118,101,115,116,97,116,101,0,8, + 115,116,97,116,102,105,108,101,7,9,115,116,97,116,102,105,108,101,49,7, + 99,97,112,116,105,111,110,6,16,73,109,97,103,101,108,105,115,116,32,69, + 100,105,116,111,114,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109, + 101,6,8,116,109,115,101,102,111,114,109,0,9,116,108,105,115,116,118,105, + 101,119,4,100,105,115,112,14,111,112,116,105,111,110,115,119,105,100,103,101, + 116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105, + 103,104,116,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,9,112,111,112,117,112,109,101,110,117,7,5,112,111,112,117,112, + 8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121, + 2,0,9,98,111,117,110,100,115,95,99,120,3,252,1,9,98,111,117,110, + 100,115,95,99,121,3,37,1,7,97,110,99,104,111,114,115,11,6,97,110, + 95,116,111,112,9,97,110,95,98,111,116,116,111,109,0,10,99,101,108,108, + 104,101,105,103,104,116,2,62,11,111,112,116,105,111,110,115,103,114,105,100, + 11,12,111,103,95,99,111,108,115,105,122,105,110,103,12,111,103,95,114,111, + 119,115,105,122,105,110,103,19,111,103,95,102,111,99,117,115,99,101,108,108, + 111,110,101,110,116,101,114,10,111,103,95,119,114,97,112,114,111,119,10,111, + 103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112, + 117,112,0,7,111,112,116,105,111,110,115,11,12,108,118,111,95,114,101,97, + 100,111,110,108,121,15,108,118,111,95,109,111,117,115,101,109,111,118,105,110, + 103,13,108,118,111,95,107,101,121,109,111,118,105,110,103,8,108,118,111,95, + 104,111,114,122,13,108,118,111,95,100,114,97,119,102,111,99,117,115,15,108, + 118,111,95,102,111,99,117,115,115,101,108,101,99,116,15,108,118,111,95,109, + 111,117,115,101,115,101,108,101,99,116,13,108,118,111,95,107,101,121,115,101, + 108,101,99,116,15,108,118,111,95,109,117,108,116,105,115,101,108,101,99,116, + 10,108,118,111,95,108,111,99,97,116,101,0,21,105,116,101,109,108,105,115, + 116,46,111,110,99,114,101,97,116,101,105,116,101,109,7,12,99,114,101,97, + 116,101,105,116,101,109,101,118,19,105,116,101,109,108,105,115,116,46,99,97, + 112,116,105,111,110,112,111,115,7,9,99,112,95,98,111,116,116,111,109,18, + 105,116,101,109,108,105,115,116,46,105,109,97,103,101,108,105,115,116,7,9, + 105,109,97,103,101,108,105,115,116,19,105,116,101,109,108,105,115,116,46,105, + 109,97,103,101,119,105,100,116,104,2,16,20,105,116,101,109,108,105,115,116, + 46,105,109,97,103,101,104,101,105,103,104,116,2,16,15,111,110,108,97,121, + 111,117,116,99,104,97,110,103,101,100,7,13,108,97,121,111,117,116,99,104, + 97,110,103,101,100,11,111,110,105,116,101,109,101,118,101,110,116,7,15,100, + 105,115,112,111,110,105,116,101,109,101,118,101,110,116,12,111,110,105,116,101, + 109,115,109,111,118,101,100,7,16,100,105,115,112,111,110,105,116,101,109,115, + 109,111,118,101,100,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,0,9,116,108,97,121,111,117,116,101,114,10,116,108,97,121,111,117, + 116,101,114,49,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,11, + 111,119,95,116,97,98,102,111,99,117,115,17,111,119,95,112,97,114,101,110, + 116,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111, + 99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16, + 111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95, + 115,117,98,102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,0,19,102,114,97,109,101,46,102,114,97,109,101,105, + 95,98,111,116,116,111,109,2,5,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,12,102,114,108,95,102,105,98,111,116,116,111,109, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95, + 120,2,0,8,98,111,117,110,100,115,95,121,3,40,1,9,98,111,117,110, + 100,115,95,99,120,3,58,1,9,98,111,117,110,100,115,95,99,121,2,59, + 7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,9,97,110, + 95,98,111,116,116,111,109,0,12,111,112,116,105,111,110,115,115,99,97,108, + 101,11,11,111,115,99,95,101,120,112,97,110,100,120,11,111,115,99,95,115, + 104,114,105,110,107,120,11,111,115,99,95,101,120,112,97,110,100,121,11,111, + 115,99,95,115,104,114,105,110,107,121,0,7,108,105,110,107,116,111,112,7, + 4,100,105,115,112,8,100,105,115,116,95,116,111,112,2,3,7,111,112,116, + 105,111,110,115,11,15,115,112,97,111,95,103,108,117,101,98,111,116,116,111, + 109,0,0,9,116,108,97,121,111,117,116,101,114,3,108,97,50,13,111,112, + 116,105,111,110,115,119,105,100,103,101,116,11,11,111,119,95,116,97,98,102, + 111,99,117,115,17,111,119,95,112,97,114,101,110,116,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95, + 97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111, + 119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111,99,117, + 115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,2,33,9,98,111,117,110,100,115, + 95,99,120,3,41,1,9,98,111,117,110,100,115,95,99,121,2,21,12,111, + 112,116,105,111,110,115,115,99,97,108,101,11,11,111,115,99,95,101,120,112, + 97,110,100,120,11,111,115,99,95,115,104,114,105,110,107,120,11,111,115,99, + 95,101,120,112,97,110,100,121,11,111,115,99,95,115,104,114,105,110,107,121, + 0,13,111,112,116,105,111,110,115,108,97,121,111,117,116,11,10,108,97,111, + 95,97,108,105,103,110,121,0,8,100,105,115,116,95,116,111,112,2,4,0, + 9,116,108,97,121,111,117,116,101,114,10,116,108,97,121,111,117,116,101,114, + 50,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,11,111,119,95, + 116,97,98,102,111,99,117,115,17,111,119,95,112,97,114,101,110,116,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98, + 102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110, + 100,115,95,120,2,80,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,120,3,217,0,9,98,111,117,110,100,115,95,99,121, + 2,21,12,111,112,116,105,111,110,115,115,99,97,108,101,11,11,111,115,99, + 95,101,120,112,97,110,100,120,11,111,115,99,95,115,104,114,105,110,107,120, + 11,111,115,99,95,101,120,112,97,110,100,121,11,111,115,99,95,115,104,114, + 105,110,107,121,0,13,111,112,116,105,111,110,115,108,97,121,111,117,116,11, + 10,108,97,111,95,112,108,97,99,101,120,0,13,112,108,97,99,101,95,109, + 105,110,100,105,115,116,2,5,13,112,108,97,99,101,95,109,97,120,100,105, + 115,116,2,5,8,100,105,115,116,95,116,111,112,2,3,0,7,116,98,117, + 116,116,111,110,2,111,107,14,111,112,116,105,111,110,115,119,105,100,103,101, + 116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105, + 103,104,116,13,111,119,49,95,97,117,116,111,115,99,97,108,101,13,111,119, + 49,95,97,117,116,111,119,105,100,116,104,0,8,116,97,98,111,114,100,101, + 114,2,2,8,98,111,117,110,100,115,95,120,2,110,8,98,111,117,110,100, + 115,95,121,2,1,9,98,111,117,110,100,115,95,99,120,2,50,9,98,111, + 117,110,100,115,95,99,121,2,20,12,98,111,117,110,100,115,95,99,120,109, + 105,110,2,50,5,115,116,97,116,101,11,10,97,115,95,100,101,102,97,117, + 108,116,15,97,115,95,108,111,99,97,108,100,101,102,97,117,108,116,15,97, + 115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,7,99,97,112,116, + 105,111,110,6,3,38,79,75,11,109,111,100,97,108,114,101,115,117,108,116, + 7,5,109,114,95,111,107,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,0,7,116,98,117,116,116,111,110,6,99,97,110,99,101,108, + 14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49, + 95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,13,111,119,49, + 95,97,117,116,111,115,99,97,108,101,13,111,119,49,95,97,117,116,111,119, + 105,100,116,104,0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117, + 110,100,115,95,120,3,165,0,8,98,111,117,110,100,115,95,121,2,1,9, + 98,111,117,110,100,115,95,99,120,2,52,9,98,111,117,110,100,115,95,99, + 121,2,20,12,98,111,117,110,100,115,95,99,120,109,105,110,2,50,5,115, + 116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111, + 110,0,7,99,97,112,116,105,111,110,6,7,38,67,97,110,99,101,108,11, + 109,111,100,97,108,114,101,115,117,108,116,7,9,109,114,95,99,97,110,99, + 101,108,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0, + 7,116,98,117,116,116,111,110,5,99,108,101,97,114,14,111,112,116,105,111, + 110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103, + 108,121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115, + 99,97,108,101,13,111,119,49,95,97,117,116,111,119,105,100,116,104,0,8, + 116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2, + 55,8,98,111,117,110,100,115,95,121,2,1,9,98,111,117,110,100,115,95, + 99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,20,12,98,111,117, + 110,100,115,95,99,120,109,105,110,2,50,5,115,116,97,116,101,11,15,97, + 115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111, + 99,97,108,111,110,101,120,101,99,117,116,101,0,7,99,97,112,116,105,111, + 110,6,6,67,38,108,101,97,114,9,111,110,101,120,101,99,117,116,101,7, + 14,99,108,101,97,114,111,110,101,120,101,99,117,116,101,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,7,116,98,117,116,116,111, + 110,3,97,100,100,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49, + 11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104, + 116,13,111,119,49,95,97,117,116,111,115,99,97,108,101,13,111,119,49,95, + 97,117,116,111,119,105,100,116,104,0,8,98,111,117,110,100,115,95,120,2, + 0,8,98,111,117,110,100,115,95,121,2,1,9,98,111,117,110,100,115,95, + 99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,20,12,98,111,117, + 110,100,115,95,99,120,109,105,110,2,50,5,115,116,97,116,101,11,15,97, + 115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111, + 99,97,108,111,110,101,120,101,99,117,116,101,0,7,99,97,112,116,105,111, + 110,6,4,38,65,100,100,9,111,110,101,120,101,99,117,116,101,7,12,97, + 100,100,111,110,101,120,101,99,117,116,101,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,0,0,12,116,98,111,111,108,101,97,110,101, + 100,105,116,7,115,116,114,101,116,99,104,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,8,38,115,116,114,101,116,99,104,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101, + 46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,2,48,2,2, + 0,8,98,111,117,110,100,115,95,120,2,6,8,98,111,117,110,100,115,95, + 121,2,3,9,98,111,117,110,100,115,95,99,120,2,61,9,98,111,117,110, + 100,115,95,99,121,2,16,8,115,116,97,116,102,105,108,101,7,9,115,116, + 97,116,102,105,108,101,49,5,118,97,108,117,101,9,0,0,0,9,116,108, + 97,121,111,117,116,101,114,3,108,97,49,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,11,111,119,95,116,97,98,102,111,99,117,115,17,111, + 119,95,112,97,114,101,110,116,116,97,98,102,111,99,117,115,13,111,119,95, + 97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102, + 111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115, + 111,117,116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95,100, + 101,115,116,114,111,121,119,105,100,103,101,116,115,0,8,98,111,117,110,100, + 115,95,120,2,6,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,120,3,52,1,9,98,111,117,110,100,115,95,99,121,2, + 30,12,111,112,116,105,111,110,115,115,99,97,108,101,11,11,111,115,99,95, + 101,120,112,97,110,100,120,11,111,115,99,95,115,104,114,105,110,107,120,11, + 111,115,99,95,101,120,112,97,110,100,121,11,111,115,99,95,115,104,114,105, + 110,107,121,0,13,111,112,116,105,111,110,115,108,97,121,111,117,116,11,10, + 108,97,111,95,112,108,97,99,101,120,10,108,97,111,95,97,108,105,103,110, + 121,0,10,97,108,105,103,110,95,103,108,117,101,7,9,119,97,109,95,115, + 116,97,114,116,13,112,108,97,99,101,95,109,105,110,100,105,115,116,2,4, + 13,112,108,97,99,101,95,109,97,120,100,105,115,116,2,4,10,108,105,110, + 107,98,111,116,116,111,109,7,3,108,97,50,11,100,105,115,116,95,98,111, + 116,116,111,109,2,3,0,10,116,99,111,108,111,114,101,100,105,116,16,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,14,38,84,114,97,110,115,112,46,10, + 99,111,108,111,114,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112, + 111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,18,102,114,97,109,101,46,98,117, + 116,116,111,110,46,119,105,100,116,104,2,13,18,102,114,97,109,101,46,98, + 117,116,116,111,110,46,99,111,108,111,114,4,2,0,0,128,19,102,114,97, + 109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,2,19,102, + 114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1, + 5,119,105,100,116,104,2,13,5,99,111,108,111,114,4,2,0,0,128,0, + 1,5,119,105,100,116,104,2,13,5,99,111,108,111,114,4,2,0,0,128, + 7,105,109,97,103,101,110,114,2,17,0,0,25,102,114,97,109,101,46,98, + 117,116,116,111,110,101,108,108,105,112,115,101,46,119,105,100,116,104,2,13, + 25,102,114,97,109,101,46,98,117,116,116,111,110,101,108,108,105,112,115,101, + 46,99,111,108,111,114,4,2,0,0,128,27,102,114,97,109,101,46,98,117, + 116,116,111,110,101,108,108,105,112,115,101,46,105,109,97,103,101,110,114,2, + 17,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2, + 0,2,5,2,50,2,5,0,8,116,97,98,111,114,100,101,114,2,1,4, + 104,105,110,116,6,17,84,114,97,110,115,112,97,114,101,110,116,32,99,111, + 108,111,114,8,98,111,117,110,100,115,95,120,2,69,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,156,0,9,98, + 111,117,110,100,115,95,99,121,2,30,8,115,116,97,116,102,105,108,101,7, + 9,115,116,97,116,102,105,108,101,49,5,118,97,108,117,101,4,1,0,0, + 128,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,12, + 116,98,111,111,108,101,97,110,101,100,105,116,6,109,97,115,107,101,100,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,7,38,109,97,115,107, + 101,100,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2, + 0,2,1,2,52,2,2,0,8,98,111,117,110,100,115,95,120,2,0,8, + 98,111,117,110,100,115,95,121,2,8,9,98,111,117,110,100,115,95,99,120, + 2,65,9,98,111,117,110,100,115,95,99,121,2,16,5,118,97,108,117,101, + 9,0,0,9,116,101,110,117,109,101,100,105,116,10,118,101,114,115,105,111, + 110,110,117,109,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,9, + 86,101,114,115,46,10,78,114,46,16,102,114,97,109,101,46,99,97,112,116, + 105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,19,102,114,97,109, + 101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1,19,102,114, + 97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,0, + 0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2, + 0,2,5,2,35,2,5,0,8,116,97,98,111,114,100,101,114,2,2,4, + 104,105,110,116,6,32,67,117,114,114,101,110,116,32,105,109,97,103,101,108, + 105,115,116,32,118,101,114,115,105,111,110,32,110,117,109,98,101,114,8,98, + 111,117,110,100,115,95,120,3,229,0,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,2,79,9,98,111,117,110,100,115, + 95,99,121,2,30,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17, + 111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101, + 49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118, + 101,118,97,108,117,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101, + 0,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,15,118,101,114, + 115,105,111,110,100,97,116,101,110,116,101,118,19,100,114,111,112,100,111,119, + 110,46,99,111,108,115,46,99,111,117,110,116,2,1,19,100,114,111,112,100, + 111,119,110,46,99,111,108,115,46,105,116,101,109,115,14,1,0,0,5,118, + 97,108,117,101,2,0,12,118,97,108,117,101,100,101,102,97,117,108,116,2, + 0,3,109,105,110,2,0,10,111,110,115,101,116,118,97,108,117,101,7,12, + 118,101,114,115,105,111,110,115,101,116,101,118,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,14,0,0,0,0,10,116,105,109,97,103,101,108, + 105,115,116,9,105,109,97,103,101,108,105,115,116,16,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,1,0,0,128,4,108,101,102,116, + 2,24,3,116,111,112,3,176,0,0,0,11,116,102,105,108,101,100,105,97, + 108,111,103,10,102,105,108,101,100,105,97,108,111,103,8,115,116,97,116,102, + 105,108,101,7,9,115,116,97,116,102,105,108,101,49,4,108,101,102,116,2, + 112,3,116,111,112,3,176,0,0,0,9,116,115,116,97,116,102,105,108,101, + 9,115,116,97,116,102,105,108,101,49,8,102,105,108,101,110,97,109,101,6, + 19,105,109,97,103,101,108,105,115,116,101,100,105,116,111,114,46,115,116,97, + 7,111,112,116,105,111,110,115,11,10,115,102,111,95,109,101,109,111,114,121, + 0,12,111,110,115,116,97,116,117,112,100,97,116,101,7,12,115,116,97,116, + 117,112,100,97,116,101,101,118,4,108,101,102,116,3,200,0,3,116,111,112, + 3,176,0,0,0,10,116,112,111,112,117,112,109,101,110,117,5,112,111,112, + 117,112,8,111,110,117,112,100,97,116,101,7,13,117,112,100,97,116,101,109, + 101,110,117,101,120,101,18,109,101,110,117,46,115,117,98,109,101,110,117,46, + 99,111,117,110,116,2,2,18,109,101,110,117,46,115,117,98,109,101,110,117, + 46,105,116,101,109,115,14,1,7,99,97,112,116,105,111,110,6,10,67,111, + 112,121,32,73,116,101,109,115,5,115,116,97,116,101,11,15,97,115,95,108, + 111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108, + 111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101, + 7,7,99,111,112,121,101,120,101,0,1,7,99,97,112,116,105,111,110,6, + 11,80,97,115,116,101,32,73,116,101,109,115,5,115,116,97,116,101,11,15, + 97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108, + 111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101, + 99,117,116,101,7,8,112,97,115,116,101,101,120,101,0,0,4,108,101,102, + 116,2,48,3,116,111,112,2,96,0,0,0) + ); + +initialization + registerobjectdata(@objdata,timagelisteditorfo,''); +end. diff --git a/mseide-msegui/lib/common/designutils/mseimageselectorform.mfm b/mseide-msegui/lib/common/designutils/mseimageselectorform.mfm new file mode 100644 index 0000000..a89bd7f --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseimageselectorform.mfm @@ -0,0 +1,35 @@ +object imageselectorfo: timageselectorfo + visible = False + bounds_x = 126 + bounds_y = 231 + bounds_cx = 320 + bounds_cy = 244 + container.bounds = ( + 0 + 0 + 320 + 244 + ) + options = [fo_screencentered, fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder, fo_savestate] + statfile = tstatfile1 + caption = 'Image Selector' + moduleclassname = 'tmseform' + object lv: tlistview + bounds_x = 0 + bounds_y = 0 + bounds_cx = 320 + bounds_cy = 244 + anchors = [] + cellheight = 16 + options = [lvo_readonly, lvo_horz, lvo_drawfocus, lvo_leftbuttonfocusonly, lvo_focusselect, lvo_mouseselect] + itemlist.captionpos = cp_bottom + onitemevent = itemev + reffontheight = 14 + end + object tstatfile1: tstatfile + filename = 'imageselector.sta' + options = [sfo_memory, sfo_activatorread, sfo_activatorwrite] + left = 72 + top = 48 + end +end diff --git a/mseide-msegui/lib/common/designutils/mseimageselectorform.pas b/mseide-msegui/lib/common/designutils/mseimageselectorform.pas new file mode 100644 index 0000000..2c3ef01 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseimageselectorform.pas @@ -0,0 +1,90 @@ +{ MSEide Copyright (c) 1999-2015 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit mseimageselectorform; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,mseglob,mseguiglob,mseapplication,msestat,msemenus,msegui, + msegraphics, + msegraphutils,mseevent,mseclasses,mseforms,msedataedits,msedatanodes,mseedit, + msegrids,mselistbrowser,msestrings,msetypes,msebitmap,msestatfile; +type + timageselectorfo = class(tmseform) + lv: tlistview; + tstatfile1: tstatfile; + procedure itemev(const sender: tcustomlistview; const index: Integer; + var info: celleventinfoty); + private + fimagelist: timagelist; + fimagenr: integer; + public + constructor create(const aowner: tcomponent; const aimagelist: timagelist; + var aimagenr: integer); reintroduce; + end; +implementation +uses + mseimageselectorform_mfm,sysutils,mseformatstr; + +{ timageselectorfo } + +constructor timageselectorfo.create(const aowner: tcomponent; + const aimagelist: timagelist; var aimagenr: integer); +var + int1,i2: integer; +begin + if aimagelist <> nil then begin + fimagelist:= aimagelist; + fimagenr:= aimagenr; + inherited create(aowner); + with lv do begin + int1:= aimagelist.width + 2; + i2:= getcanvas().getstringwidth('999')+2; + if int1 < i2 then begin + int1:= i2; + end; + cellwidth:= int1; + cellheight:= aimagelist.height + font.lineheight + 3; + end; + with lv.itemlist do begin + imagelist:= aimagelist; + count:= aimagelist.count; + imagewidth:= aimagelist.width; + imageheight:= aimagelist.height+2; + for int1:= 0 to count -1 do begin + with items[int1] do begin + imagenr:= int1; + caption:= inttostrmse(int1); + end; + end; + end; + lv.focusedindex:= fimagenr; + show(true); + aimagenr:= fimagenr; + end; + release; +end; + +procedure timageselectorfo.itemev(const sender: tcustomlistview; + const index: Integer; var info: celleventinfoty); +begin + if iscellclick(info) then begin + fimagenr:= index; + window.modalresult:= mr_ok; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/mseimageselectorform_mfm.pas b/mseide-msegui/lib/common/designutils/mseimageselectorform_mfm.pas new file mode 100644 index 0000000..0d6b305 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseimageselectorform_mfm.pas @@ -0,0 +1,52 @@ +unit mseimageselectorform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,mseimageselectorform; + +const + objdata: record size: integer; data: array[0..686] of byte end = + (size: 687; data: ( + 84,80,70,48,16,116,105,109,97,103,101,115,101,108,101,99,116,111,114,102, + 111,15,105,109,97,103,101,115,101,108,101,99,116,111,114,102,111,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,126,8,98,111, + 117,110,100,115,95,121,3,231,0,9,98,111,117,110,100,115,95,99,120,3, + 64,1,9,98,111,117,110,100,115,95,99,121,3,244,0,16,99,111,110,116, + 97,105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0,3,64,1, + 3,244,0,0,7,111,112,116,105,111,110,115,11,17,102,111,95,115,99,114, + 101,101,110,99,101,110,116,101,114,101,100,13,102,111,95,99,108,111,115,101, + 111,110,101,115,99,15,102,111,95,97,117,116,111,114,101,97,100,115,116,97, + 116,16,102,111,95,97,117,116,111,119,114,105,116,101,115,116,97,116,10,102, + 111,95,115,97,118,101,112,111,115,13,102,111,95,115,97,118,101,122,111,114, + 100,101,114,12,102,111,95,115,97,118,101,115,116,97,116,101,0,8,115,116, + 97,116,102,105,108,101,7,10,116,115,116,97,116,102,105,108,101,49,7,99, + 97,112,116,105,111,110,6,14,73,109,97,103,101,32,83,101,108,101,99,116, + 111,114,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,8, + 116,109,115,101,102,111,114,109,0,9,116,108,105,115,116,118,105,101,119,2, + 108,118,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115, + 95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,64,1,9,98,111, + 117,110,100,115,95,99,121,3,244,0,7,97,110,99,104,111,114,115,11,0, + 10,99,101,108,108,104,101,105,103,104,116,2,16,7,111,112,116,105,111,110, + 115,11,12,108,118,111,95,114,101,97,100,111,110,108,121,8,108,118,111,95, + 104,111,114,122,13,108,118,111,95,100,114,97,119,102,111,99,117,115,23,108, + 118,111,95,108,101,102,116,98,117,116,116,111,110,102,111,99,117,115,111,110, + 108,121,15,108,118,111,95,102,111,99,117,115,115,101,108,101,99,116,15,108, + 118,111,95,109,111,117,115,101,115,101,108,101,99,116,0,19,105,116,101,109, + 108,105,115,116,46,99,97,112,116,105,111,110,112,111,115,7,9,99,112,95, + 98,111,116,116,111,109,11,111,110,105,116,101,109,101,118,101,110,116,7,6, + 105,116,101,109,101,118,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,9,116,115,116,97,116,102,105,108,101,10,116,115,116,97,116, + 102,105,108,101,49,8,102,105,108,101,110,97,109,101,6,17,105,109,97,103, + 101,115,101,108,101,99,116,111,114,46,115,116,97,7,111,112,116,105,111,110, + 115,11,10,115,102,111,95,109,101,109,111,114,121,17,115,102,111,95,97,99, + 116,105,118,97,116,111,114,114,101,97,100,18,115,102,111,95,97,99,116,105, + 118,97,116,111,114,119,114,105,116,101,0,4,108,101,102,116,2,72,3,116, + 111,112,2,48,0,0,0) + ); + +initialization + registerobjectdata(@objdata,timageselectorfo,''); +end. diff --git a/mseide-msegui/lib/common/designutils/mseindexlookupeditor.mfm b/mseide-msegui/lib/common/designutils/mseindexlookupeditor.mfm new file mode 100644 index 0000000..23d03fd --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseindexlookupeditor.mfm @@ -0,0 +1,161 @@ +object mseindexlookupeditorfo: tmseindexlookupeditorfo + bounds_x = 337 + bounds_y = 266 + bounds_cx = 383 + bounds_cy = 334 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 383 + 334 + ) + options = [fo_freeonclose, fo_createmodal, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder, fo_savestate] + statfile = statfile1 + caption = 'Indexlookup Editor' + oncreate = createexe + onclosequery = closequexe + moduleclassname = 'tmseform' + object tsplitter1: tsplitter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + color = -2147483645 + bounds_x = 258 + bounds_y = 293 + bounds_cx = 123 + bounds_cy = 32 + anchors = [an_right, an_bottom] + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + linktop = grid + grip = stb_none + object tbutton2: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + taborder = 1 + bounds_x = 58 + bounds_y = 10 + bounds_cx = 52 + bounds_cy = 22 + bounds_cxmin = 50 + anchors = [an_top, an_right] + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + reffontheight = 14 + end + object tbutton1: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + bounds_x = 0 + bounds_y = 10 + bounds_cx = 50 + bounds_cy = 22 + bounds_cxmin = 50 + anchors = [an_top, an_right] + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + reffontheight = 14 + end + object tspacer2: tspacer + taborder = 2 + bounds_x = 50 + bounds_y = 10 + bounds_cx = 8 + bounds_cy = 20 + linkleft = tbutton1 + linkright = tbutton2 + options = [spao_glueright] + end + end + object grid: twidgetgrid + frame.localprops = [] + frame.localprops1 = [] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 383 + bounds_cy = 293 + anchors = [an_top] + optionsgrid = [og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_selectedrowsdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixcols.count = 1 + fixcols.items = < + item + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 1 + captions.items = < + item + caption = 'Index' + end> + end> + datacols.count = 3 + datacols.options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savevalue, co_savestate, co_mousescrollrow] + datacols.items = < + item[indexed] + width = 77 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savevalue, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow, co_rowdatachange] + name = 'index' + widgetname = 'indexed' + dataclass = tgridintegerdatalist + end + item[icondi] + width = 21 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savevalue, co_savestate, co_mousescrollrow] + widgetname = 'icondi' + dataclass = tgridintegerdatalist + end + item[tstockglyphdatabutton1] + color = -2147483646 + width = 18 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savevalue, co_savestate, co_mousescrollrow] + widgetname = 'tstockglyphdatabutton1' + dataclass = tgridintegerdatalist + end> + datarowheight = 16 + onrowdatachanged = rowdatacha + reffontheight = 14 + object indexed: tintegeredit + optionsskin = [osk_framebuttononly] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 77 + bounds_cy = 16 + min = -2147483648 + reffontheight = 14 + end + object icondi: tdataicon + optionswidget1 = [] + optionsskin = [osk_framebuttononly] + taborder = 2 + bounds_x = 78 + bounds_y = 0 + bounds_cx = 21 + bounds_cy = 16 + visible = False + onpaintglyph = iconpaintexe + end + object tstockglyphdatabutton1: tstockglyphdatabutton + optionswidget1 = [] + optionsskin = [osk_framebuttononly] + taborder = 3 + bounds_x = 100 + bounds_y = 0 + bounds_cx = 18 + bounds_cy = 16 + state = [as_invisible, as_localinvisible, as_localimagelist, as_localimagenr, as_localonexecute] + glyph = stg_ellipsesmall + onexecute = selectexe + end + end + object statfile1: tstatfile + filename = 'indexlookup.sta' + options = [sfo_memory] + left = 80 + top = 112 + end +end diff --git a/mseide-msegui/lib/common/designutils/mseindexlookupeditor.pas b/mseide-msegui/lib/common/designutils/mseindexlookupeditor.pas new file mode 100644 index 0000000..d573a02 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseindexlookupeditor.pas @@ -0,0 +1,131 @@ +unit mseindexlookupeditor; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,msewidgets,mseforms,msesplitter, + msesimplewidgets,msedataedits,mseedit,mseificomp,mseificompglob,mseifiglob, + msestatfile,msestream,msestrings,sysutils,msegrids,msewidgetgrid,msegraphedits, + msescrollbar,msebitmap; +type + tmseindexlookupeditorfo = class(tmseform) + tsplitter1: tsplitter; + tbutton2: tbutton; + tbutton1: tbutton; + tspacer2: tspacer; + grid: twidgetgrid; + indexed: tintegeredit; + tstockglyphdatabutton1: tstockglyphdatabutton; + icondi: tdataicon; + statfile1: tstatfile; + procedure rowdatacha(const sender: tcustomgrid; const acell: gridcoordty); + procedure createexe(const sender: TObject); + procedure closequexe(const sender: tcustommseform; + var amodalresult: modalresultty); + procedure selectexe(const sender: TObject); + procedure iconpaintexe(const sender: tcustomintegergraphdataedit; + const acanvas: tcanvas; const avalue: Integer; + const arow: Integer); + protected + findexlist: pmsestring; + fimagelist: timagelist; + ffacelist: tfacelist; + fok: pboolean; + public + constructor create(var indexlist: msestring; const imagelist: timagelist; + const facelist: tfacelist; out ok: boolean); + end; + +function editlookupindex(var indexlist: msestring; const imagelist: timagelist; + const facelist: tfacelist): boolean; + +implementation +uses + mseindexlookupeditor_mfm,mseimageselectorform,msefaceselectorform; + +function editlookupindex(var indexlist: msestring; + const imagelist: timagelist; const facelist: tfacelist): boolean; +begin + tmseindexlookupeditorfo.create(indexlist,imagelist,facelist,result); +end; + +{ tmseindexlookupeditorfo } + +constructor tmseindexlookupeditorfo.create(var indexlist: msestring; + const imagelist: timagelist; const facelist: tfacelist; + out ok: boolean); +begin + findexlist:= @indexlist; + fimagelist:= imagelist; + ffacelist:= facelist; + fok:= @ok; + inherited create(nil); +end; + +procedure tmseindexlookupeditorfo.rowdatacha(const sender: tcustomgrid; + const acell: gridcoordty); +begin + icondi[acell.row]:= indexed[acell.row]; +end; + +procedure tmseindexlookupeditorfo.createexe(const sender: TObject); +var + i1: int32; + po1: pint16; +begin + grid.beginupdate(); + icondi.imagelist:= fimagelist; + if fimagelist = nil then begin + grid[1].visible:= false; + grid[2].visible:= false; + end; + grid.rowcount:= length(findexlist^); + po1:= pointer(findexlist^); + for i1:= 0 to grid.rowhigh do begin + indexed[i1]:= po1[i1]; + end; + grid.endupdate(); +end; + +procedure tmseindexlookupeditorfo.closequexe(const sender: tcustommseform; + var amodalresult: modalresultty); +var + i1: int32; + po1: pint16; +begin + fok^:= amodalresult = mr_ok; + if fok^ then begin + setlength(findexlist^,grid.rowcount); + po1:= pointer(findexlist^); + for i1:= 0 to grid.rowhigh do begin + po1[i1]:= indexed[i1]; + end; + end; +end; + +procedure tmseindexlookupeditorfo.selectexe(const sender: TObject); +var + i1: int32; +begin + i1:= indexed.value; + if fimagelist <> nil then begin + timageselectorfo.create(nil,fimagelist,i1); + end + else begin + if ffacelist <> nil then begin + tfaceselectorfo.create(nil,ffacelist,i1); + end; + end; + indexed.value:= i1; +end; + +procedure tmseindexlookupeditorfo.iconpaintexe( + const sender: tcustomintegergraphdataedit; const acanvas: tcanvas; + const avalue: Integer; const arow: Integer); +begin + if ffacelist <> nil then begin + ffacelist.paint(acanvas,avalue,sender.clientrect); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/mseindexlookupeditor_mfm.pas b/mseide-msegui/lib/common/designutils/mseindexlookupeditor_mfm.pas new file mode 100644 index 0000000..36d5d84 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseindexlookupeditor_mfm.pas @@ -0,0 +1,193 @@ +unit mseindexlookupeditor_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,mseindexlookupeditor; + +const + objdata: record size: integer; data: array[0..3506] of byte end = + (size: 3507; data: ( + 84,80,70,48,23,116,109,115,101,105,110,100,101,120,108,111,111,107,117,112, + 101,100,105,116,111,114,102,111,22,109,115,101,105,110,100,101,120,108,111,111, + 107,117,112,101,100,105,116,111,114,102,111,8,98,111,117,110,100,115,95,120, + 3,81,1,8,98,111,117,110,100,115,95,121,3,10,1,9,98,111,117,110, + 100,115,95,99,120,3,127,1,9,98,111,117,110,100,115,95,99,121,3,78, + 1,26,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,0,27,99,111,110,116,97,105,110,101,114, + 46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2,0, + 2,0,3,127,1,3,78,1,0,7,111,112,116,105,111,110,115,11,14,102, + 111,95,102,114,101,101,111,110,99,108,111,115,101,14,102,111,95,99,114,101, + 97,116,101,109,111,100,97,108,15,102,111,95,97,117,116,111,114,101,97,100, + 115,116,97,116,16,102,111,95,97,117,116,111,119,114,105,116,101,115,116,97, + 116,10,102,111,95,115,97,118,101,112,111,115,13,102,111,95,115,97,118,101, + 122,111,114,100,101,114,12,102,111,95,115,97,118,101,115,116,97,116,101,0, + 8,115,116,97,116,102,105,108,101,7,9,115,116,97,116,102,105,108,101,49, + 7,99,97,112,116,105,111,110,6,18,73,110,100,101,120,108,111,111,107,117, + 112,32,69,100,105,116,111,114,8,111,110,99,114,101,97,116,101,7,9,99, + 114,101,97,116,101,101,120,101,12,111,110,99,108,111,115,101,113,117,101,114, + 121,7,10,99,108,111,115,101,113,117,101,120,101,15,109,111,100,117,108,101, + 99,108,97,115,115,110,97,109,101,6,8,116,109,115,101,102,111,114,109,0, + 9,116,115,112,108,105,116,116,101,114,10,116,115,112,108,105,116,116,101,114, + 49,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,11,111,119,95, + 116,97,98,102,111,99,117,115,17,111,119,95,112,97,114,101,110,116,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98, + 102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,5,99,111,108,111,114,4,3,0,0,128,8,98,111,117,110, + 100,115,95,120,3,2,1,8,98,111,117,110,100,115,95,121,3,37,1,9, + 98,111,117,110,100,115,95,99,120,2,123,9,98,111,117,110,100,115,95,99, + 121,2,32,7,97,110,99,104,111,114,115,11,8,97,110,95,114,105,103,104, + 116,9,97,110,95,98,111,116,116,111,109,0,12,111,112,116,105,111,110,115, + 115,99,97,108,101,11,11,111,115,99,95,101,120,112,97,110,100,120,11,111, + 115,99,95,115,104,114,105,110,107,120,11,111,115,99,95,101,120,112,97,110, + 100,121,11,111,115,99,95,115,104,114,105,110,107,121,0,7,108,105,110,107, + 116,111,112,7,4,103,114,105,100,4,103,114,105,112,7,8,115,116,98,95, + 110,111,110,101,0,7,116,98,117,116,116,111,110,8,116,98,117,116,116,111, + 110,50,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111, + 119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,13,111, + 119,49,95,97,117,116,111,115,99,97,108,101,13,111,119,49,95,97,117,116, + 111,119,105,100,116,104,0,8,116,97,98,111,114,100,101,114,2,1,8,98, + 111,117,110,100,115,95,120,2,58,8,98,111,117,110,100,115,95,121,2,10, + 9,98,111,117,110,100,115,95,99,120,2,52,9,98,111,117,110,100,115,95, + 99,121,2,22,12,98,111,117,110,100,115,95,99,120,109,105,110,2,50,7, + 97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,8,97,110,95,114, + 105,103,104,116,0,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,7,38, + 67,97,110,99,101,108,11,109,111,100,97,108,114,101,115,117,108,116,7,9, + 109,114,95,99,97,110,99,101,108,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,14,0,0,7,116,98,117,116,116,111,110,8,116,98,117,116, + 116,111,110,49,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11, + 19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116, + 13,111,119,49,95,97,117,116,111,115,99,97,108,101,13,111,119,49,95,97, + 117,116,111,119,105,100,116,104,0,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,10,9,98,111,117,110,100,115,95,99, + 120,2,50,9,98,111,117,110,100,115,95,99,121,2,22,12,98,111,117,110, + 100,115,95,99,120,109,105,110,2,50,7,97,110,99,104,111,114,115,11,6, + 97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,5,115,116,97, + 116,101,11,10,97,115,95,100,101,102,97,117,108,116,15,97,115,95,108,111, + 99,97,108,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,99, + 97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,3,38,79,75, + 11,109,111,100,97,108,114,101,115,117,108,116,7,5,109,114,95,111,107,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,7,116,115, + 112,97,99,101,114,8,116,115,112,97,99,101,114,50,8,116,97,98,111,114, + 100,101,114,2,2,8,98,111,117,110,100,115,95,120,2,50,8,98,111,117, + 110,100,115,95,121,2,10,9,98,111,117,110,100,115,95,99,120,2,8,9, + 98,111,117,110,100,115,95,99,121,2,20,8,108,105,110,107,108,101,102,116, + 7,8,116,98,117,116,116,111,110,49,9,108,105,110,107,114,105,103,104,116, + 7,8,116,98,117,116,116,111,110,50,7,111,112,116,105,111,110,115,11,14, + 115,112,97,111,95,103,108,117,101,114,105,103,104,116,0,0,0,0,11,116, + 119,105,100,103,101,116,103,114,105,100,4,103,114,105,100,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114, + 100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,127,1, + 9,98,111,117,110,100,115,95,99,121,3,37,1,7,97,110,99,104,111,114, + 115,11,6,97,110,95,116,111,112,0,11,111,112,116,105,111,110,115,103,114, + 105,100,11,12,111,103,95,114,111,119,109,111,118,105,110,103,15,111,103,95, + 107,101,121,114,111,119,109,111,118,105,110,103,15,111,103,95,114,111,119,105, + 110,115,101,114,116,105,110,103,14,111,103,95,114,111,119,100,101,108,101,116, + 105,110,103,23,111,103,95,115,101,108,101,99,116,101,100,114,111,119,115,100, + 101,108,101,116,105,110,103,19,111,103,95,102,111,99,117,115,99,101,108,108, + 111,110,101,110,116,101,114,15,111,103,95,97,117,116,111,102,105,114,115,116, + 114,111,119,13,111,103,95,97,117,116,111,97,112,112,101,110,100,20,111,103, + 95,99,111,108,99,104,97,110,103,101,111,110,116,97,98,107,101,121,10,111, + 103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112, + 117,112,17,111,103,95,109,111,117,115,101,115,99,114,111,108,108,99,111,108, + 0,13,102,105,120,99,111,108,115,46,99,111,117,110,116,2,1,13,102,105, + 120,99,111,108,115,46,105,116,101,109,115,14,1,7,110,117,109,115,116,101, + 112,2,1,0,0,13,102,105,120,114,111,119,115,46,99,111,117,110,116,2, + 1,13,102,105,120,114,111,119,115,46,105,116,101,109,115,14,1,6,104,101, + 105,103,104,116,2,16,14,99,97,112,116,105,111,110,115,46,99,111,117,110, + 116,2,1,14,99,97,112,116,105,111,110,115,46,105,116,101,109,115,14,1, + 7,99,97,112,116,105,111,110,6,5,73,110,100,101,120,0,0,0,0,14, + 100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,3,16,100,97,116, + 97,99,111,108,115,46,111,112,116,105,111,110,115,11,14,99,111,95,102,111, + 99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101, + 108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111, + 95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115, + 101,108,101,99,116,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99, + 111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109,111,117,115,101, + 115,99,114,111,108,108,114,111,119,0,14,100,97,116,97,99,111,108,115,46, + 105,116,101,109,115,14,7,7,105,110,100,101,120,101,100,1,5,119,105,100, + 116,104,2,77,7,111,112,116,105,111,110,115,11,14,99,111,95,102,111,99, + 117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108, + 101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95, + 109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101, + 108,101,99,116,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111, + 95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112, + 121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117, + 115,101,115,99,114,111,108,108,114,111,119,16,99,111,95,114,111,119,100,97, + 116,97,99,104,97,110,103,101,0,4,110,97,109,101,6,5,105,110,100,101, + 120,10,119,105,100,103,101,116,110,97,109,101,6,7,105,110,100,101,120,101, + 100,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100,105,110, + 116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,6,105,99,111,110, + 100,105,1,5,119,105,100,116,104,2,21,7,111,112,116,105,111,110,115,11, + 12,99,111,95,100,114,97,119,102,111,99,117,115,14,99,111,95,102,111,99, + 117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108, + 101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95, + 109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101, + 108,101,99,116,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111, + 95,115,97,118,101,115,116,97,116,101,17,99,111,95,109,111,117,115,101,115, + 99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101, + 6,6,105,99,111,110,100,105,9,100,97,116,97,99,108,97,115,115,7,20, + 116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116, + 0,7,22,116,115,116,111,99,107,103,108,121,112,104,100,97,116,97,98,117, + 116,116,111,110,49,1,5,99,111,108,111,114,4,2,0,0,128,5,119,105, + 100,116,104,2,18,7,111,112,116,105,111,110,115,11,14,99,111,95,102,111, + 99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101, + 108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111, + 95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115, + 101,108,101,99,116,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99, + 111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109,111,117,115,101, + 115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109, + 101,6,22,116,115,116,111,99,107,103,108,121,112,104,100,97,116,97,98,117, + 116,116,111,110,49,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114, + 105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,0,13, + 100,97,116,97,114,111,119,104,101,105,103,104,116,2,16,16,111,110,114,111, + 119,100,97,116,97,99,104,97,110,103,101,100,7,10,114,111,119,100,97,116, + 97,99,104,97,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,12,116,105,110,116,101,103,101,114,101,100,105,116,7,105,110,100,101,120, + 101,100,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95, + 102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98, + 111,114,100,101,114,2,1,7,118,105,115,105,98,108,101,8,8,98,111,117, + 110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,120,2,77,9,98,111,117,110,100,115,95,99,121, + 2,16,3,109,105,110,4,0,0,0,128,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,0,9,116,100,97,116,97,105,99,111,110,6, + 105,99,111,110,100,105,14,111,112,116,105,111,110,115,119,105,100,103,101,116, + 49,11,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107, + 95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97, + 98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,2,78,8, + 98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120, + 2,21,9,98,111,117,110,100,115,95,99,121,2,16,7,118,105,115,105,98, + 108,101,8,12,111,110,112,97,105,110,116,103,108,121,112,104,7,12,105,99, + 111,110,112,97,105,110,116,101,120,101,0,0,21,116,115,116,111,99,107,103, + 108,121,112,104,100,97,116,97,98,117,116,116,111,110,22,116,115,116,111,99, + 107,103,108,121,112,104,100,97,116,97,98,117,116,116,111,110,49,14,111,112, + 116,105,111,110,115,119,105,100,103,101,116,49,11,0,11,111,112,116,105,111, + 110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116, + 116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,3,8, + 98,111,117,110,100,115,95,120,2,100,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,2,18,9,98,111,117,110,100,115, + 95,99,121,2,16,5,115,116,97,116,101,11,12,97,115,95,105,110,118,105, + 115,105,98,108,101,17,97,115,95,108,111,99,97,108,105,110,118,105,115,105, + 98,108,101,17,97,115,95,108,111,99,97,108,105,109,97,103,101,108,105,115, + 116,15,97,115,95,108,111,99,97,108,105,109,97,103,101,110,114,17,97,115, + 95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,5,103,108,121, + 112,104,7,16,115,116,103,95,101,108,108,105,112,115,101,115,109,97,108,108, + 9,111,110,101,120,101,99,117,116,101,7,9,115,101,108,101,99,116,101,120, + 101,0,0,0,9,116,115,116,97,116,102,105,108,101,9,115,116,97,116,102, + 105,108,101,49,8,102,105,108,101,110,97,109,101,6,15,105,110,100,101,120, + 108,111,111,107,117,112,46,115,116,97,7,111,112,116,105,111,110,115,11,10, + 115,102,111,95,109,101,109,111,114,121,0,4,108,101,102,116,2,80,3,116, + 111,112,2,112,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tmseindexlookupeditorfo,''); +end. diff --git a/mseide-msegui/lib/common/designutils/mseintegerlisteditor.mfm b/mseide-msegui/lib/common/designutils/mseintegerlisteditor.mfm new file mode 100644 index 0000000..73846e2 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseintegerlisteditor.mfm @@ -0,0 +1,106 @@ +object integerlisteditor: tintegerlisteditor + visible = False + bounds_x = 182 + bounds_y = 208 + bounds_cx = 133 + bounds_cy = 298 + container.bounds = ( + 0 + 0 + 133 + 298 + ) + options = [fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos] + statfile = tstatfile1 + caption = 'Integerlisteditor' + moduleclassname = 'tmseform' + object ok: tbutton + taborder = 3 + bounds_x = 4 + bounds_y = 270 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_left, an_bottom] + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + end + object cancel: tbutton + bounds_x = 68 + bounds_y = 270 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_left, an_bottom] + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + end + object grid: twidgetgrid + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 133 + bounds_cy = 242 + anchors = [an_top, an_bottom] + optionsgrid = [og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_wrapcol, og_autopopup] + fixcols.count = 1 + fixcols.items = < + item + width = 24 + numstep = 1 + end> + zebra_start = 1 + zebra_height = 1 + datacols.count = 1 + datacols.items = < + item[valueedit] + width = 103 + options = [co_fill, co_savevalue, co_savestate] + widgetname = 'valueedit' + dataclass = tgridintegerdatalist + end> + datarowheight = 16 + onrowcountchanged = gridonrowcountchanged + reffontheight = 14 + object valueedit: tintegeredit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.dummy = 0 + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 103 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + max = -1 + reffontheight = 14 + end + end + object rowcount: tintegeredit + frame.caption = 'Rowcount' + frame.captionpos = cp_right + frame.dummy = 0 + frame.outerframe = ( + 0 + 0 + 64 + 0 + ) + taborder = 2 + bounds_x = 4 + bounds_y = 246 + bounds_cx = 116 + anchors = [an_left, an_bottom] + onsetvalue = rowcountonsetvalue + reffontheight = 14 + end + object tstatfile1: tstatfile + filename = 'stringlisteditor.sta' + options = [sfo_memory] + left = 40 + top = 88 + end +end diff --git a/mseide-msegui/lib/common/designutils/mseintegerlisteditor.pas b/mseide-msegui/lib/common/designutils/mseintegerlisteditor.pas new file mode 100644 index 0000000..cb336a3 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseintegerlisteditor.pas @@ -0,0 +1,61 @@ +{ MSEgui Copyright (c) 1999-2006 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseintegerlisteditor; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseforms,msedataedits,msesimplewidgets,msewidgetgrid,msegrids,msetextedit, + msestat,msestatfile; + +const + integerlisteditorstatname = 'integerlisteditor.sta'; + +type + tintegerlisteditor = class(tmseform) + cancel: tbutton; + ok: tbutton; + grid: twidgetgrid; + rowcount: tintegeredit; + valueedit: tintegeredit; + tstatfile1: tstatfile; + procedure rowcountonsetvalue(const sender: tobject; var avalue: integer; + var accept: boolean); + procedure gridonrowcountchanged(const sender: tcustomgrid); + public + constructor create(const aonclosequery: closequeryeventty); reintroduce; + end; + +implementation +uses + mseintegerlisteditor_mfm; + +{ tintegerlisteditor } + +constructor tintegerlisteditor.create(const aonclosequery: closequeryeventty); +begin + inherited create(nil); + onclosequery:= aonclosequery; +end; + +procedure tintegerlisteditor.gridonrowcountchanged( + const sender: tcustomgrid); +begin + rowcount.value:= sender.rowcount; +end; + +procedure tintegerlisteditor.rowcountonsetvalue(const sender: tobject; + var avalue: integer; var accept: boolean); +begin + grid.rowcount:= avalue; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/mseintegerlisteditor_mfm.pas b/mseide-msegui/lib/common/designutils/mseintegerlisteditor_mfm.pas new file mode 100644 index 0000000..37be381 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseintegerlisteditor_mfm.pas @@ -0,0 +1,105 @@ +unit mseintegerlisteditor_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,mseintegerlisteditor; + +const + objdata: record size: integer; data: array[0..1755] of byte end = + (size: 1756; data: ( + 84,80,70,48,18,116,105,110,116,101,103,101,114,108,105,115,116,101,100,105, + 116,111,114,17,105,110,116,101,103,101,114,108,105,115,116,101,100,105,116,111, + 114,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3, + 182,0,8,98,111,117,110,100,115,95,121,3,208,0,9,98,111,117,110,100, + 115,95,99,120,3,133,0,9,98,111,117,110,100,115,95,99,121,3,42,1, + 16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2,0, + 2,0,3,133,0,3,42,1,0,7,111,112,116,105,111,110,115,11,13,102, + 111,95,99,108,111,115,101,111,110,101,115,99,15,102,111,95,97,117,116,111, + 114,101,97,100,115,116,97,116,16,102,111,95,97,117,116,111,119,114,105,116, + 101,115,116,97,116,10,102,111,95,115,97,118,101,112,111,115,0,8,115,116, + 97,116,102,105,108,101,7,10,116,115,116,97,116,102,105,108,101,49,7,99, + 97,112,116,105,111,110,6,17,73,110,116,101,103,101,114,108,105,115,116,101, + 100,105,116,111,114,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109, + 101,6,8,116,109,115,101,102,111,114,109,0,7,116,98,117,116,116,111,110, + 2,111,107,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117,110,100, + 115,95,120,2,4,8,98,111,117,110,100,115,95,121,3,14,1,9,98,111, + 117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2, + 20,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,9,97, + 110,95,98,111,116,116,111,109,0,5,115,116,97,116,101,11,10,97,115,95, + 100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,100,101,102,97, + 117,108,116,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0, + 7,99,97,112,116,105,111,110,6,3,38,79,75,11,109,111,100,97,108,114, + 101,115,117,108,116,7,5,109,114,95,111,107,0,0,7,116,98,117,116,116, + 111,110,6,99,97,110,99,101,108,8,98,111,117,110,100,115,95,120,2,68, + 8,98,111,117,110,100,115,95,121,3,14,1,9,98,111,117,110,100,115,95, + 99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,20,7,97,110,99, + 104,111,114,115,11,7,97,110,95,108,101,102,116,9,97,110,95,98,111,116, + 116,111,109,0,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,7,38,67, + 97,110,99,101,108,11,109,111,100,97,108,114,101,115,117,108,116,7,9,109, + 114,95,99,97,110,99,101,108,0,0,11,116,119,105,100,103,101,116,103,114, + 105,100,4,103,114,105,100,8,116,97,98,111,114,100,101,114,2,1,8,98, + 111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0, + 9,98,111,117,110,100,115,95,99,120,3,133,0,9,98,111,117,110,100,115, + 95,99,121,3,242,0,7,97,110,99,104,111,114,115,11,6,97,110,95,116, + 111,112,9,97,110,95,98,111,116,116,111,109,0,11,111,112,116,105,111,110, + 115,103,114,105,100,11,12,111,103,95,114,111,119,109,111,118,105,110,103,15, + 111,103,95,107,101,121,114,111,119,109,111,118,105,110,103,15,111,103,95,114, + 111,119,105,110,115,101,114,116,105,110,103,14,111,103,95,114,111,119,100,101, + 108,101,116,105,110,103,19,111,103,95,102,111,99,117,115,99,101,108,108,111, + 110,101,110,116,101,114,15,111,103,95,97,117,116,111,102,105,114,115,116,114, + 111,119,10,111,103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116, + 111,112,111,112,117,112,0,13,102,105,120,99,111,108,115,46,99,111,117,110, + 116,2,1,13,102,105,120,99,111,108,115,46,105,116,101,109,115,14,1,5, + 119,105,100,116,104,2,24,7,110,117,109,115,116,101,112,2,1,0,0,11, + 122,101,98,114,97,95,115,116,97,114,116,2,1,12,122,101,98,114,97,95, + 104,101,105,103,104,116,2,1,14,100,97,116,97,99,111,108,115,46,99,111, + 117,110,116,2,1,14,100,97,116,97,99,111,108,115,46,105,116,101,109,115, + 14,7,9,118,97,108,117,101,101,100,105,116,1,5,119,105,100,116,104,2, + 103,7,111,112,116,105,111,110,115,11,7,99,111,95,102,105,108,108,12,99, + 111,95,115,97,118,101,118,97,108,117,101,12,99,111,95,115,97,118,101,115, + 116,97,116,101,0,10,119,105,100,103,101,116,110,97,109,101,6,9,118,97, + 108,117,101,101,100,105,116,9,100,97,116,97,99,108,97,115,115,7,20,116, + 103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0, + 0,13,100,97,116,97,114,111,119,104,101,105,103,104,116,2,16,17,111,110, + 114,111,119,99,111,117,110,116,99,104,97,110,103,101,100,7,21,103,114,105, + 100,111,110,114,111,119,99,111,117,110,116,99,104,97,110,103,101,100,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,12,116,105,110,116, + 101,103,101,114,101,100,105,116,9,118,97,108,117,101,101,100,105,116,11,111, + 112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109, + 101,98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108, + 101,118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,11,102,114,97, + 109,101,46,100,117,109,109,121,2,0,8,116,97,98,111,114,100,101,114,2, + 1,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2, + 0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,2,103,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116, + 105,111,110,115,101,100,105,116,49,11,13,111,101,49,95,115,97,118,101,118, + 97,108,117,101,0,3,109,97,120,2,255,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,0,0,12,116,105,110,116,101,103,101,114,101, + 100,105,116,8,114,111,119,99,111,117,110,116,13,102,114,97,109,101,46,99, + 97,112,116,105,111,110,6,8,82,111,119,99,111,117,110,116,16,102,114,97, + 109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105, + 103,104,116,11,102,114,97,109,101,46,100,117,109,109,121,2,0,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2, + 64,2,0,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110, + 100,115,95,120,2,4,8,98,111,117,110,100,115,95,121,3,246,0,9,98, + 111,117,110,100,115,95,99,120,2,116,7,97,110,99,104,111,114,115,11,7, + 97,110,95,108,101,102,116,9,97,110,95,98,111,116,116,111,109,0,10,111, + 110,115,101,116,118,97,108,117,101,7,18,114,111,119,99,111,117,110,116,111, + 110,115,101,116,118,97,108,117,101,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,14,0,0,9,116,115,116,97,116,102,105,108,101,10,116,115, + 116,97,116,102,105,108,101,49,8,102,105,108,101,110,97,109,101,6,20,115, + 116,114,105,110,103,108,105,115,116,101,100,105,116,111,114,46,115,116,97,7, + 111,112,116,105,111,110,115,11,10,115,102,111,95,109,101,109,111,114,121,0, + 4,108,101,102,116,2,40,3,116,111,112,2,88,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tintegerlisteditor,''); +end. diff --git a/mseide-msegui/lib/common/designutils/mseparser.pas b/mseide-msegui/lib/common/designutils/mseparser.pas new file mode 100644 index 0000000..5e52546 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseparser.pas @@ -0,0 +1,2734 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseparser; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + Classes,msetypes,msestrings,msestream,mselist,msehash,mseglob; + +const + maxincludelevel = 32; + +type + + operatorty = (op_unknown); + tokenkindty = (tk_operator,tk_whitespace,tk_name,tk_number,tk_newline, + tk_fileend,tk_include); + + sourceposty = record + filenum: integer; //0 -> sourcepos empty + offset: integer; //byteoffset in file + filename: nameidty; + line: integer; //absolute linenr + pos: gridcoordty; + end; + psourceposty = ^sourceposty; + + tsourceposlist = class(trecordlist) + private + function getitems(const index: integer): psourceposty; + protected +// procedure copyrecord(var item); override; +// procedure finalizerecord(var item); override; + public + constructor create; + function add(const source: sourceposty): integer; + property items[const index: integer]: psourceposty read getitems; + end; + tokenstatety = (tos_linestart,tos_firstofline); + tokenstatesty = set of tokenstatety; + tokenty = record + value: lstringty; + state: tokenstatesty; + case kind: tokenkindty of + tk_operator: (op: char); + tk_newline: (linenr: integer); + tk_include: (filenr: integer); + end; + ptokenty = ^tokenty; + tokenarty = array of tokenty; + { + tokensequencety = record + token: ptokenty; + count: integer; + index: integer; + end; + } + charsetty = set of char; + tscanner = class + private + ftokens: tokenarty; + ftokencount: integer; + fsource: ansistring; //uppercase + fsourceorig: ansistring; + fpo: pchar; + fscto: ptokenty; + flinenr: integer; + fescapechar: char; + fcasesensitive: boolean; + forigoffset: integer; + ffilename: filenamety; //for check of recursive includefiles + ffileid: nameidty; + fstartline: integer; + fcount: integer; + fincludecount: integer; + flinestart: boolean; + ffirstofline: boolean; + procedure updatecase; + procedure setsource(const Value: ansistring); + procedure clear; + procedure scan; + procedure setcasesensitive(const Value: boolean); + protected + procedure scantoken; + procedure newtoken(akind: tokenkindty); + procedure endtoken; + public + constructor create; overload; virtual; + constructor create(const afilename: filenamety; + const filelist: tmseindexednamelist); overload; + procedure setfilename(const aname: filenamety; + const filelist: tmseindexednamelist); + property origoffset: integer read forigoffset; + property filename: filenamety read ffilename; + property fileid: nameidty read ffileid; + property startline: integer read fstartline; + property count: integer read fcount; + property includecount: integer read fincludecount; + property source: ansistring read fsource write setsource; + property escapechar: char read fescapechar write fescapechar; + //for newline escape + property casesensitive: boolean read fcasesensitive write setcasesensitive; + end; + + tpascalscanner = class(tscanner) + public + constructor create; override; + end; + + tcscanner = class(tscanner) + public + constructor create; override; + end; + +const + identmaxlen = 30; + {$define nohash} //first char of ident is hash value + {$ifdef nohash} + identbucketcount = 128; + {$else} + identbucketcount = 256; + {$endif} +type + identstringty = string[identmaxlen+1]; //terminated with #0 + identinfoty = record + name: identstringty; + ident: integer; + end; + pidentinfoty = ^identinfoty; + identinfoarty = array of identinfoty; + + valuekindty = (vk_none,vk_integer,vk_real,vk_string); + + tokenidty = record + scanner: longword; + token: longword; + end; + tokenidarty = array of tokenidty; + + filestackinfoty = record + tokenid: tokenidty; + lineoffset: integer; + end; + filestackinfoarty = array of filestackinfoty; + + scannerarty = array of tscanner; + + tparser = class; + + getincludefileeventty = procedure(const sender: tparser; + const scanner: tscanner) of object; + scannerclassty = class of tscanner; + +// tdefineslist = class(thashedstrings); + tdefineslist = class(tansistringhashdatalist); + defstatety = (def_none,def_skip); + + tparser = class (tnullinterfacedobject) + private + fcasesensitive: boolean; + fscanner: tscanner; + fownsscanner: boolean; + fscannernum: longword; + ftokennum: longword; + fidents: array[0..identbucketcount-1] of identinfoarty; + ffilestack: filestackinfoarty; + ftokenstack: tokenidarty; + ftokenstackcount: integer; + frecursivecomment: boolean; + flastvalidident: integer; + fincludefiledirs: filenamearty; + fongetincludefile: getincludefileeventty; + feof: boolean; + ffilelist: tmseindexednamelist; + //false if root + fdefines: tdefineslist; + fdefstate: defstatety; + fdefstates: integerarty; + fdefstatecount: integer; + fstartdefines: stringarty; + function getacttoken: tokenidty; + procedure setacttokennum(anum: longword); + procedure setacttoken(const atoken: tokenidty); + procedure enterinclude(anum: longword); + function exitinclude: boolean; + protected + fscanners: scannerarty; + fsyntaxerrorcount: integer; + fto: ptokenty; + function getscanner: tscanner; + procedure setscanner(const Value: tscanner); + procedure internalerror; + procedure syntaxerror; + function getscannerclass: scannerclassty; virtual; + + public + constructor create; overload; + constructor create(const afilelist: tmseindexednamelist); overload; virtual; + constructor create(const afilelist: tmseindexednamelist; const atext: string); overload; + destructor destroy; override; + + procedure reset; + procedure clear; virtual; + procedure initidents; virtual; + procedure parse; virtual; + property token: ptokenty read fto; + property acttoken: tokenidty read getacttoken write setacttoken; + procedure nexttoken; + procedure nextnonwhitetoken; + procedure lasttoken; + procedure lastnonwhitetoken; + + function gettoken: string; + function getorigtoken: string; //original case + function getorigtext(const start: pchar): string; + //returns text from start to actual pos + function getlastorigtext(const start: pchar): string; + //returns text from start to lasttoken + function getident: integer; overload; //-1 if none + function getident(out aident: integer): boolean; overload; + //false if none + function getnameorident(out aident: integer): boolean; overload; + //false if none, -1 if name or none + function getnameorident: boolean; overload; + function getfirstident: integer; //-1 if none or not first token in line + function checkident(const ident: integer): boolean; overload;//true if ok + function checkident(const ident: array of integer): integer; overload; + //returns found ident, -1 if none + function testident(const ident: integer): boolean; + //skips whitespace, true if ident found + function checknamenoident: boolean; + function skipnamenoident: boolean; + function checkname: boolean; overload; + function checkname(const aname: ansistring): boolean; overload; + function getname(out value: lstringty): boolean; overload; + function getorigname(out value: lstringty): boolean; overload; + function getname: string; overload; //'' if none + function getorigname: string; overload; //'' if none + function getnamenoident(out value: lstringty): boolean; + function getorignamenoident(out value: lstringty): boolean; + + function testname(const atoken: tokenty; const aname: string): boolean; + function testnames(const atoken: tokenty; + const anames: array of string): integer; + + function getoperator: char; //#0 if none + function getnextoperator: char; + function testoperator(op: char): boolean; + function checkoperator(op: char): boolean; + function checknextoperator(aoperator: char): boolean; //true if ok + function findoperator(aoperator: char): boolean; //false if not found + function findclosingbracket: boolean; //false if not found; + function getvaluestring(var value: string): valuekindty; virtual; + function getnamelist: lstringarty; //names separated by ',' + function getorignamelist: lstringarty; //names separated by ',' + + function skipcomment: boolean; virtual; //does not skip whitespace + function checknewline: boolean; + function nextline: boolean; //false if fileend + function skipwhitespace: boolean; //and comments, false if no whitespaces + function skipwhitespaceonly: boolean; + function skipnamelist: boolean; //skips [,]{,} false if no name found + function skipidents: boolean; + property eof: boolean read feof; + function isfirstnonwhitetoken: boolean; + {$ifndef nohash} + function hashident(name: pchar; len: integer): byte; overload; + function hashident(const name: string): byte; overload; + {$endif} + + procedure mark; //set mark in tokenstak + function back: boolean; + //restore tokenstack to last mark, mark must be in same file, true if ok + procedure pop; //remove mark from tokenstack + procedure setidents(idents: array of string); + + function sourceoffset: integer; + function sourcepos: sourceposty; + function nextsourcepos: sourceposty; //skips whitespace + function nexttokenornewlinepos: sourceposty; + function getsourcepos(const atoken: tokenidty): sourceposty; + //returns row and col in source + function lasttokenoffset: integer; + function lasttokenpos: sourceposty; + + function addscanner(const ascanner: tscanner): integer; + function dogetincludefile(const afilename: filenamety; + const astatementstart,astatementend: sourceposty): tscanner; virtual; + function includefile(const filename: filenamety; + const statementstart,statementend: sourceposty): integer; + //-1 on error, scanner index otherwise + procedure callincludefile(const filename: filenamety; + const startpos: sourceposty; const anum: integer); + function origoffset: integer; + property scanner: tscanner read getscanner write setscanner; + property recursivecomment: boolean read frecursivecomment + write frecursivecomment default false; + property ongetincludefile: getincludefileeventty read fongetincludefile + write fongetincludefile; + property includefiledirs: filenamearty read fincludefiledirs + write fincludefiledirs; + property startdefines: stringarty read fstartdefines write fstartdefines; + end; + +type + pascalidentty = (pid_invalid = -1, + pid_and=0,pid_array,pid_as,pid_asm,pid_begin,pid_case,pid_class,pid_const, + pid_constructor, + pid_destructor,pid_dispinterface,pid_div,pid_do,pid_downto,pid_else,pid_end, + pid_except, + pid_exports,pid_file,pid_finalization,pid_finally,pid_for,pid_function, + pid_goto,pid_if, + pid_implementation,pid_in,pid_initialization,pid_inline,pid_forward, + pid_interface, + pid_is,pid_label,pid_library,pid_method,pid_mod,pid_nil,pid_not,pid_object, + pid_of,pid_or,pid_out, + pid_overload, + pid_packed,pid_procedure,pid_program,pid_property,pid_raise,pid_record, + pid_repeat, + pid_resourcestring,pid_set,pid_shl,pid_shr,pid_then,pid_threadvar,pid_to, + pid_try,pid_type,pid_unit,pid_until,pid_uses,pid_var,pid_while,pid_with, + pid_xor, + + pid_abstract,pid_inherited,pid_override,pid_reintroduce,pid_virtual, + pid_private,pid_protected,pid_public,pid_published,pid_automated, + + pid_read,pid_write,pid_stored,pid_default,pid_nodefault); + + const + firstpascalident = pid_and; + lastpascalnormalident = integer(pid_xor); + lastpascalclassident = integer(pid_automated); + lastpascalpropertyident = integer(pid_nodefault); + lastpascalident = pid_nodefault; + + pascalidents: array[firstpascalident..lastpascalident] of string = ( + 'and','array','as','asm','begin','case','class','const','constructor', + 'destructor','dispinterface','div','do','downto','else','end','except', + 'exports','file','finalization','finally','for','function','goto','if', + 'implementation','in','initialization','inline','forward','interface', + 'is','label','library','method','mod','nil','not','object','of','or','out', + 'overload', + 'packed','procedure','program','property','raise','record','repeat', + 'resourcestring','set','shl','shr','then','threadvar','to', + 'try','type','unit','until','uses','var','while','with','xor', //default + + 'abstract','inherited','override','reintroduce','virtual', //class + 'private','protected','public','published','automated', + + 'read','write','stored','default','nodefault'); + +type + + tpascalparser = class(tparser) + protected + fnoautoparse: boolean; + function getscannerclass: scannerclassty; override; + public + constructor create(const afilelist: tmseindexednamelist); override; + destructor destroy; override; + procedure clear; override; + procedure initidents; override; + function getvaluestring(var value: string): valuekindty; override; + function skipcomment: boolean; override; //does not skip whitespace + procedure parsecompilerswitch; + function getpascalstring(var value: string): boolean; //true if ok + function concatpascalstring(var value: string): boolean; + //concats +... true if ok + function concatpascalname(var value: string): boolean; + //returns ...., true if ok + + function getclassident: pascalidentty; //-1 if none + function checkclassident(const ident: pascalidentty): boolean; //true if ok + function getpropertyident: pascalidentty; //-1 if none + function checkpropertyident(const ident: pascalidentty): boolean; //true if ok + end; + + cidentty = (cid_invalid = -1, + cid_break = 0,cid_case,cid_continue,cid_default, + cid_do,cid_else,cid_entry,cid_for,cid_goto,cid_if,cid_return, + cid_sizeof, + cid_switch,cid_while, + + cid_auto,{cid_char,}cid_const,{cid_double,}cid_enum,cid_extern,{cid_float,} + {cid_int,cid_long,}cid_register,{cid_short,}cid_signed,cid_static, + cid_struct,cid_typedef,cid_union,cid_unsigned,cid_volatile); + const + firstcident = cid_break; + lastcident = cid_volatile; + cidents: array[firstcident..lastcident] of string = ( + 'break','case','continue','default', + 'do','else','entry','for','goto','if','return', + 'sizeof', + 'switch','while', + + 'auto',{'char',}'const',{'double',}'enum','extern',{'float',} + {'int','long',}'register',{'short',}'signed','static', + 'struct','typedef','union','unsigned','volatile' + ); + + type + tcparser = class(tparser) + protected + fincomment: integer; + function getscannerclass: scannerclassty; override; + procedure parsepreprocdef; + public + constructor create(const afilelist: tmseindexednamelist); override; + procedure initidents; override; + function getvaluestring(var value: string): valuekindty; override; + function skipcomment: boolean; override; //does not skip whitespace + function getcstring(var value: string): boolean; + function skipstatement: boolean; + end; + + constinfoty = record + name: string; + valuetype: tvaluetype; + value: msestring; + resource: boolean; + case integer of + 0:(offset,len: integer); + 1:(hash: card32); + end; + pconstinfoty = ^constinfoty; + constinfoarty = array of constinfoty; + + tconstparser = class(tpascalparser) + public + function getconsts(var ar: constinfoarty): string; + //returns unitname + end; + + tfpcresstringparser = class(tpascalparser) + public + procedure getconsts(var ar: constinfoarty); + end; + + tresstringlistparser = class(tcparser) + public + constructor create(const afilelist: tmseindexednamelist); override; + procedure getconsts(var ar: constinfoarty); + end; + + +function isemptysourcepos(const value: sourceposty): boolean; +function issamesourcepos(const a,b: sourceposty): boolean; +function emptysourcepos: sourceposty; + +implementation +uses + sysutils,mseformatstr,msedatalist,typinfo,msebits,msewidgets, + msefileutils,msearrayutils,mseapplication; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + treader1 = class(treader); + twriter1 = class(twriter); + +function isemptysourcepos(const value: sourceposty): boolean; +begin + result:= value.filenum = 0; +end; + +function issamesourcepos(const a,b: sourceposty): boolean; +begin + result:= (a.filenum <> 0) and (a.filenum = b.filenum) and + (a.pos.col = b.pos.col) and (a.pos.row = b.pos.row); +end; + +function emptysourcepos: sourceposty; +begin + finalize(result); + fillchar(result,sizeof(sourceposty),0); +end; + +{ tsourceposlist } + +constructor tsourceposlist.create; +begin + inherited create(sizeof(sourceposty){,[rels_needsfinalize,rels_needscopy]}); +end; + +function tsourceposlist.add(const source: sourceposty): integer; +begin + result:= inherited add(source); +end; +{ +procedure tsourceposlist.copyrecord(var item); +begin + with sourceposty(item) do begin + stringaddref(filename); + end; +end; + +procedure tsourceposlist.finalizerecord(var item); +begin + finalize(sourceposty(item)); +end; +} +function tsourceposlist.getitems(const index: integer): psourceposty; +begin + result:= getitempo(index); +end; + +{ tscanner } + +constructor tscanner.create; +begin + inherited; +end; + +constructor tscanner.create(const afilename: filenamety; + const filelist: tmseindexednamelist); +var + stream: ttextstream; +begin + create; + setfilename(afilename,filelist); + stream:= ttextstream.create(filename); + try + source:= stream.readdatastring; + finally + stream.Free; + end; +end; + +procedure tscanner.setfilename(const aname: filenamety; + const filelist: tmseindexednamelist); +begin + ffilename:= aname; + ffileid:= filelist.add(aname); +end; + +procedure tscanner.clear; +begin + ftokencount:= 0; + ftokens:= nil; + flinenr:= 0; +end; + +procedure tscanner.newtoken(akind: tokenkindty); +begin + if ftokencount >= high(ftokens) then begin + setlength(ftokens,(3*length(ftokens)) div 2 + 256); + end; + fscto:= @ftokens[ftokencount]; + if flinestart then begin + include(fscto^.state,tos_linestart); + flinestart:= false; + end; + if ffirstofline then begin + include(fscto^.state,tos_firstofline); + if akind <> tk_whitespace then begin + ffirstofline:= false; + end; + end; + inc(ftokencount); + fscto^.kind:= akind; + fscto^.value.po:= fpo; + case akind of + tk_newline: begin + fscto^.linenr:= flinenr; + inc(flinenr); + flinestart:= true; + ffirstofline:= true; + end; + tk_operator: begin + fscto^.op:= fpo^; + end; + end; +end; + +procedure tscanner.endtoken; +begin + fscto^.value.len:= fpo - fscto^.value.po; +end; + +procedure tscanner.scantoken; +var + ch1: char; +begin +// ch1:= upcase(fpo^); + ch1:= upperchars[fpo^]; + if (ch1 = ' ') or (ch1 = c_tab) then begin + newtoken(tk_whitespace); + repeat + inc(fpo); + until not ((fpo^ = ' ') or (fpo^ = c_tab)); + end + else begin + if (ch1 >= 'A') and (ch1 <= 'Z') or (ch1 = '_') then begin + newtoken(tk_name); + repeat + inc(fpo); + ch1:= upcase(fpo^); + until not ((ch1 >= 'A') and (ch1 <= 'Z') or (ch1 = '_') or + (ch1 >= '0') and (ch1 <= '9')); + end + else begin + if (ch1 >= '0') and (ch1 <= '9') then begin + newtoken(tk_number); + repeat + inc(fpo); + until (fpo^ < '0') or (fpo^ > '9'); + end + else begin + if ch1 = c_return then begin + newtoken(tk_newline); + inc(fpo); + if fpo^ = c_linefeed then begin + inc(fpo); + end; + end + else begin + if ch1 = c_linefeed then begin + newtoken(tk_newline); + inc(fpo); + if fpo^ = c_return then begin + inc(fpo); + end; + end + else begin + newtoken(tk_operator); + inc(fpo); + end; + end; + end; + end; + end; +end; + +procedure tscanner.scan; +begin + clear; + fpo:= pointer(fsource); + if fpo <> nil then begin + flinestart:= true; + ffirstofline:= true; + while fpo^ <> #0 do begin + scantoken; + endtoken; + if fescapechar <> #0 then begin + if (ftokens[ftokencount-1].kind = tk_newline) and + (ftokencount > 1) and (ftokens[ftokencount-2].kind = tk_operator) and + (ftokens[ftokencount-2].op = fescapechar) then begin + dec(ftokencount,2); + if ftokencount > 0 then begin + with ftokens[ftokencount-1].value do begin + len:= len + ftokens[ftokencount].value.len + + ftokens[ftokencount+1].value.len; + end; + end; + end; + end; + end; + end; + newtoken(tk_fileend); +end; + +procedure tscanner.updatecase; +begin + if fcasesensitive then begin + fsource:= fsourceorig; + forigoffset:= 0; + end + else begin + fsource:= uppercase(fsourceorig); + forigoffset:= pchar(fsourceorig) - pchar(fsource); + end; +end; + +procedure tscanner.setsource(const Value: ansistring); +begin + fsourceorig:= Value; + updatecase; + scan; +end; + +procedure tscanner.setcasesensitive(const Value: boolean); +begin + if fcasesensitive <> value then begin + fcasesensitive:= Value; + updatecase; + end; +end; + +{ tpascalscanner } + +constructor tpascalscanner.create; +begin + inherited; +end; + +{ tcscanner } + +constructor tcscanner.create; +begin + inherited; + fcasesensitive:= true; + fescapechar:= '\'; +end; + +{ tparser } + +constructor tparser.create(const afilelist: tmseindexednamelist); +begin + if application.waitescaped then begin + abort; + end; + fdefines:= tdefineslist.create(); + ffilelist:= afilelist; + flastvalidident:= bigint; + setlength(fincludefiledirs,1); + fincludefiledirs[0]:= './'; +end; + +constructor tparser.create(const afilelist: tmseindexednamelist; + const atext: string); +var + ascanner: tscanner; +begin + create(afilelist); + fownsscanner:= true; + ascanner:= getscannerclass.create; + ascanner.source:= atext; + scanner:= ascanner; +end; + +constructor tparser.create; +begin + create(nil); +end; + +destructor tparser.destroy; +begin + reset; + inherited; + if fownsscanner then begin + fscanner.Free; + end; + fdefines.free; +end; + +procedure tparser.reset; +var + int1: integer; +begin + for int1:= 1 to high(fscanners) do begin + fscanners[int1].Free; + end; + fscanners:= nil; +end; + +procedure tparser.clear; +begin + feof:= false; + ftokennum:= 0; + ftokenstack:= nil; + ffilestack:= nil; + ftokenstackcount:= 0; + fscannernum:= 0; + if fscanners <> nil then begin + fscanner:= fscanners[0]; + fto:= ptokenty(pointer(fscanner.ftokens)); + setlength(ffilestack,1); + end + else begin + fscanner:= nil; + fto:= nil; + end; + fsyntaxerrorcount:= 0; +end; + +function tparser.addscanner(const ascanner: tscanner): integer; +begin + result:= length(fscanners); + if result = 0 then begin + fscanner:= ascanner; + end + else begin + ascanner.fstartline:= sourcepos.line + 1; + //dummy line for include files + end; + setlength(fscanners,result+1); + fscanners[result]:= ascanner; +end; + +function tparser.dogetincludefile(const afilename: filenamety; + const astatementstart,astatementend: sourceposty): tscanner; +begin + result:= tscanner(fscanners[0].newinstance); + if assigned(fongetincludefile) then begin + result.create; + result.setfilename(afilename,ffilelist); + fongetincludefile(self,result); + end + else begin + result.Create(afilename,ffilelist); + end; +end; + +function tparser.includefile(const filename: filenamety; + const statementstart,statementend: sourceposty): integer; + //returns scanner index +var + str1: filenamety; + ascanner: tscanner; + int1: integer; +begin + result:= -1; + if application.waitescaped then begin + abort;//exit; + end; + if high(ffilestack) < maxincludelevel then begin + if findfile(filename,fincludefiledirs,str1) then begin + for int1:= 0 to high(ffilestack) do begin + if issamefilename(str1,fscanners[ffilestack[int1].tokenid.scanner].ffilename) then begin + //recursive + syntaxerror; + exit; + end; + end; + ascanner:= dogetincludefile(str1,statementstart,statementend); + try + result:= addscanner(ascanner); + except + result:= -1; + ascanner.Free; + end; + end; + end; +end; + +procedure tparser.callincludefile(const filename: filenamety; + const startpos: sourceposty; const anum: integer); +var + int1,int2: integer; +begin + int2:= includefile(filename,startpos,sourcepos); + if int2 >= 0 then begin + for int1:= anum + 1 to ftokennum - 1 do begin + fscanner.ftokens[int1].kind:= tk_whitespace; + end; + with fscanner.ftokens[anum] do begin + kind:= tk_include; + filenr:= int2; + end; + enterinclude(int2); + end; +end; + +function tparser.origoffset: integer; +begin + result:= 0; + if fscanner <> nil then begin + result:= fscanner.forigoffset; + end; +end; + +{$ifndef nohash} + +function tparser.hashident(name: pchar; len: integer): byte; +var + sumb: byte; + xorb: byte; + by1: byte; +begin + sumb:= 0; + xorb:= 0; +// if fcasesensitive then begin + while len > 0 do begin + sumb:= sumb + byte(name^); + xorb:= xorb xor byte(name^); + inc(name); + dec(len); + end; +// end + { + else begin + while len > 0 do begin + by1:= byte(upcase(name^)); + sumb:= sumb + by1; + xorb:= xorb xor by1; + inc(name); + dec(len); + end; + end; + } + result:= sumb xor xorb; +end; + +function tparser.hashident(const name: string): byte; +begin + result:= hashident(pchar(name),length(name)); +end; + +{$endif nohash} + +procedure tparser.setidents(idents: array of string); +var + int1: integer; + str1: string; + by1: byte; +begin + for int1:= 0 to high(idents) do begin + str1:= copy(idents[int1],1,identmaxlen); + if not fcasesensitive then begin + str1:= uppercase(str1); + end; + {$ifdef nohash} + assert((length(str1) > 0) and (ord(str1[1]) < 128), + 'Invalid ident '''+str1+''''); + by1:= byte(str1[1]); + str1:= copy(str1,2,bigint); + {$else} + assert(length(str1) > 0,'Empty ident'); + by1:= hashident(str1); + {$endif} + setlength(fidents[by1],high(fidents[by1])+2); + with fidents[by1][high(fidents[by1])] do begin +// if fcasesensitive then begin + name:= str1; +// end +// else begin +// name:= uppercase(str1); +// end; + name[length(str1)+1]:= #0; + ident:= int1; + end; + end; +end; + +function tparser.sourceoffset: integer; +begin + result:= fto^.value.po - pchar(fscanner.fsource); +end; + +function tparser.getsourcepos(const atoken: tokenidty): sourceposty; + //returns row and col in source +var + int1: integer; +begin +// result.filenum:= fscannernum + 1; +// result.filename:= fscanners[fscannernum].ffileid; + result.filenum:= atoken.scanner + 1; +// with result.pos,fscanner do begin + with result.pos,fscanners[atoken.scanner] do begin + result.filename:= ffileid; + row:= 0; + col:= ftokens[atoken.token].value.po - + pchar(fsource); + result.offset:= col; //byteoffset in file + for int1:= atoken.token-1 downto 0 do begin + with ftokens[int1] do begin + if (kind = tk_newline) then begin + row:= linenr + 1; + col:= col - (ftokens[int1+1].value.po - + pchar(fsource)); + break; + end; + end; + end; + end; + result.line:= result.pos.row; + if high(ffilestack) >= 0 then begin + inc(result.line,ffilestack[high(ffilestack)].lineoffset); + end; +end; + +function tparser.sourcepos: sourceposty; +var + id: tokenidty; +begin + id.scanner:= fscannernum; + id.token:= ftokennum; + result:= getsourcepos(id); +end; + +function tparser.nextsourcepos: sourceposty; //skips whitespace +begin + skipwhitespace; + result:= sourcepos; +end; + +function tparser.nexttokenornewlinepos: sourceposty; +begin + skipwhitespaceonly; + if fto^.kind = tk_newline then begin + nexttoken; + end; + result:= sourcepos; +end; + +function tparser.lasttokenoffset: integer; +var + int1: integer; +begin + result:= 0; + with fscanner do begin + for int1:= ftokennum - 2 downto 0 do begin + if ftokens[int1].kind <> tk_whitespace then begin + result:= ftokens[int1+1].value.po - pchar(fsource); + break; + end; + end; + end; +end; + +function tparser.lasttokenpos: sourceposty; +begin + result:= sourcepos; + result.pos.col:= result.pos.col - sourceoffset + lasttokenoffset; +end; + +function tparser.getacttoken: tokenidty; +begin + result.scanner:= fscannernum; + result.token:= ftokennum; +end; + +procedure tparser.setacttokennum(anum: longword); +begin + with fscanner do begin + if anum <= longword(high(ftokens)) then begin + ftokennum:= anum; + fto:= @ftokens[ftokennum]; + end + else begin + internalerror; + end; + end; +end; + +procedure tparser.setacttoken(const atoken: tokenidty); +var + int1,int2: integer; +begin + with atoken do begin + if scanner > longword(high(fscanners)) then begin + internalerror; + end; + if ffilestack <> nil then begin + int2:= high(ffilestack); + if ffilestack[int2].tokenid.scanner <> scanner then begin + for int1:= int2 downto 0 do begin + if ffilestack[int2].tokenid.scanner = scanner then begin + setlength(ffilestack,int2+1); + end; + end; + end; + end; + fscannernum:= scanner; + fscanner:= fscanners[scanner]; + feof:= false; + with fscanner do begin + if token <= longword(high(ftokens)) then begin + ftokennum:= token; + fto:= @ftokens[ftokennum]; + end + else begin + internalerror; + end; + end; + end; +end; + +procedure tparser.enterinclude(anum: longword); +var + id1: tokenidty; + int1: integer; + aline: integer; +begin + if anum > longword(high(fscanners)) then begin + internalerror; + end; + inc(fscanner.fincludecount); + aline:= sourcepos.line; + int1:= high(ffilestack); + setlength(ffilestack,int1+2); + ffilestack[int1+1].tokenid:= acttoken; + ffilestack[int1+1].lineoffset:= aline + 1; + //dummy line for include files + id1.scanner:= anum; + id1.token:= 0; + setacttoken(id1); +end; + +function tparser.exitinclude: boolean; + //false if root +var + int1,int2: integer; + acount: integer; +begin + int1:= sourcepos.line; + if high(ffilestack) > 0 then begin + int1:= int1 - fscanner.fstartline; + if fscanner.fcount <= 0 then begin + inc(fscanner.fcount,int1); + end; + acount:= fscanner.fcount; + result:= true; + setacttoken(ffilestack[high(ffilestack)].tokenid); + if ffilestack <> nil then begin + for int2:= high(ffilestack) downto 1 do begin + with fscanners[ffilestack[int2].tokenid.scanner] do begin + if fcount <= 0 then begin + dec(fcount,acount); + end; + end; + end; + setlength(ffilestack,high(ffilestack)); + if ffilestack <> nil then begin + inc(ffilestack[high(ffilestack)].lineoffset,int1); + end; + end; + end + else begin + result:= false; + feof:= true; + if fscanners[0].fcount <= 0 then begin + inc(fscanners[0].fcount,int1); + end; + end; +end; + +procedure tparser.nexttoken; +begin + if fto^.kind <> tk_fileend then begin + inc(ftokennum); + fto:= @fscanner.ftokens[ftokennum]; + end + else begin + repeat + until (fto^.kind <> tk_fileend) or not exitinclude; + end; +end; + +procedure tparser.nextnonwhitetoken; +begin + skipwhitespace; + nexttoken; +end; + +procedure tparser.lasttoken; +begin + if ftokennum > 0 then begin + dec(ftokennum); + fto:= @fscanner.ftokens[ftokennum]; + end + else begin + if not exitinclude then begin + internalerror; + end; + end; +end; + +procedure tparser.lastnonwhitetoken; +begin + repeat + if ftokennum > 0 then begin + dec(ftokennum); + fto:= @fscanner.ftokens[ftokennum]; + end + else begin + if not exitinclude then begin + break; + end; + end; + until fto^.kind <> tk_whitespace; +end; + +procedure tparser.mark; +begin + if ftokenstackcount >= high(ftokenstack) then begin + setlength(ftokenstack,high(ftokenstack)+33); + end; + ftokenstack[ftokenstackcount].token:= ftokennum; + ftokenstack[ftokenstackcount].scanner:= fscannernum; + inc(ftokenstackcount); +end; + +function tparser.back: boolean; +begin + if ftokenstackcount = 0 then begin + internalerror; + end; + dec(ftokenstackcount); + if fscannernum = ftokenstack[ftokenstackcount].scanner then begin + setacttoken(ftokenstack[ftokenstackcount]); + result:= true; + end + else begin + result:= false; + end; +end; + +procedure tparser.pop; +begin + if ftokenstackcount = 0 then begin + internalerror; + end; + dec(ftokenstackcount); +end; + +function tparser.gettoken: string; +begin + setstring(result,fto^.value.po,fto^.value.len); + nexttoken; +end; + +function tparser.getorigtoken: string; +begin + setstring(result,fto^.value.po+fscanner.forigoffset,fto^.value.len); + nexttoken; +end; + +function tparser.getorigtext(const start: pchar): string; + //returns text from start to actual pos +begin + if fto^.value.po - start > 0 then begin + setstring(result,start+fscanner.forigoffset,fto^.value.po - start); + end + else begin + result:= ''; + end; +end; + +function tparser.getlastorigtext(const start: pchar): string; + //returns text from start to actual pos +begin + lasttoken; + if fto^.value.po - start > 0 then begin + setstring(result,start+fscanner.forigoffset,fto^.value.po - start); + end + else begin + result:= ''; + end; + nexttoken; +end; + +function tparser.checknextoperator(aoperator: char): boolean; +begin + with fscanner.ftokens[ftokennum+1] do begin + if (kind = tk_operator) and (op = aoperator) then begin + result:= true; + nexttoken; + end + else begin + result:= false; + end; + end; +end; + +function tparser.findoperator(aoperator: char): boolean; +begin + result:= false; + while (fto^.kind <> tk_fileend) or exitinclude do begin + if (fto^.kind = tk_operator) and (fto^.op = aoperator) then begin + nexttoken; + result:= true; + break; + end; + nexttoken; + end; +end; + +function tparser.getnextoperator: char; +begin + result:= #0; + while (fto^.kind <> tk_fileend) or exitinclude do begin + skipwhitespace; + if (fto^.kind = tk_operator) then begin + result:= fto^.op; + nexttoken; + break; + end; + nexttoken; + end; +end; + +function tparser.getoperator: char; +begin + skipwhitespace; + if fto^.kind = tk_operator then begin + result:= fto^.op; + nexttoken; + end + else begin + result:= #0; + end; +end; + +function tparser.testoperator(op: char): boolean; +begin + skipwhitespace; + if fto^.kind = tk_operator then begin + result:= fto^.op = op; + end + else begin + result:= false; + end; +end; + +function tparser.checkoperator(op: char): boolean; +var + ch1: char; +begin + ch1:= getoperator; + result:= op = ch1; + if not result and (ch1 <> #0) then begin + lasttoken; + end; +end; + +function tparser.findclosingbracket: boolean; //false if not found; +var + int1: integer; + ch1: char; +begin + result:= false; + int1:= 1; + repeat + ch1:= getnextoperator; + case ch1 of + ')': begin + dec(int1); + if int1 = 0 then begin + result:= true; + break; + end; + end; + '(': begin + inc(int1); + end; + end; + until ch1 = #0; +end; + +function tparser.isfirstnonwhitetoken: boolean; +var + po1,po2: ptokenty; +begin + result:= true; + po1:= fto; + po2:= @fscanner.ftokens[0]; + while po1 <> po2 do begin + dec(po1); + if po1^.kind = tk_newline then begin + break; + end + else begin + if po1^.kind <> tk_whitespace then begin + result:= false; + break; + end; + end; + end; +end; + +function tparser.skipwhitespace: boolean; +begin + result:= false; + repeat + while (fto^.kind = tk_whitespace) or (fto^.kind = tk_newline) do begin + result:= true; + nexttoken; + end; + while skipcomment do begin + result:= true; + while (fto^.kind = tk_whitespace) or (fto^.kind = tk_newline) do begin + nexttoken; + end; + if fto^.kind = tk_fileend then begin + nexttoken; //exit include file + end; + end; + if fto^.kind = tk_fileend then begin + nexttoken; //exit include file + end; + until not ((fto^.kind = tk_whitespace) or (fto^.kind = tk_newline)); +end; + +function tparser.skipwhitespaceonly: boolean; +begin + result:= false; + while (fto^.kind = tk_whitespace) do begin + result:= true; + nexttoken; + end; +end; + +function tparser.skipnamelist: boolean; + //skips [,]{,} false if no name found +begin + result:= false; + checkoperator(','); + while true do begin + if not getnameorident then begin + break; + end; + result:= true; + if not checkoperator(',') then begin + break; + end; + end; +end; + +function tparser.skipidents: boolean; +begin + result:= false; + while getident >= 0 do begin + end; +end; + +function tparser.getident: integer; +var + by1: byte; + int1,alen: integer; + po1,po2: pchar; + po3: pidentinfoty; +begin + skipwhitespace; + result:= -1; + with fto^ do begin + if kind = tk_name then begin + {$ifdef nohash} + by1:= byte(value.po^); + if by1 >= 128 then begin + exit; + end; + alen:= value.len-1; + {$else} + by1:= hashident(value.po,value.len); + alen:= value.len; + {$endif} + for int1:= 0 to high(fidents[by1]) do begin + po3:= @fidents[by1][int1]; + if length(po3^.name) = alen then begin + {$ifdef nohash} + po1:= value.po + 1; //source + {$else} + po1:= value.po; //source + {$endif} + po2:= @po3^.name[1]; + while (po2^ <> #0) and (po1^ = po2^) do begin + inc(po1); + inc(po2); + end; + if po2^= #0 then begin + result:= po3^.ident; + break; + end; + end; + end; + end; + end; + if result > flastvalidident then begin + result:= -1; + end; + if result >= 0 then begin + nexttoken; + end; +end; + +function tparser.getident(out aident: integer): boolean; + //false if none +begin + aident:= getident(); + result:= aident >= 0; +end; + +function tparser.getnameorident(out aident: integer): boolean; + //false if none, -1 if name or none +begin + aident:= getident; + result:= aident >= 0; + if not result and (fto^.kind = tk_name) then begin + result:= true; + nexttoken; + end; +end; + +function tparser.getnameorident: boolean; + //false if none, -1 if name or none +begin + skipwhitespace; + result:= fto^.kind = tk_name; + if result then begin + nexttoken; + end; +end; + +function tparser.getfirstident: integer; //-1 if none or not first token in line +begin + if (ftokennum = 0) or (fscanner.ftokens[ftokennum-1].kind = tk_newline) then begin + result:= getident; + end + else begin + skipwhitespace; + result:= -1; + end; +end; + +function tparser.testname(const atoken: tokenty; const aname: string): boolean; +begin + result:= (atoken.kind = tk_name) and (lstringcomp(atoken.value,aname) = 0); +end; + +function tparser.testnames(const atoken: tokenty; + const anames: array of string): integer; +var + int1: integer; +begin + result:= -1; + if atoken.kind = tk_name then begin + for int1:= 0 to high(anames) do begin + if (lstringcomp(atoken.value,anames[int1]) = 0) then begin + result:= int1; + break; + end; + end; + end; +end; + +function tparser.checkident(const ident: integer): boolean; +var + int1: integer; +begin + int1:= getident; + result:= ident = int1; + if not result and (int1 >= 0) then begin + lasttoken; + end; +end; + +function tparser.checkident(const ident: array of integer): integer; +var + int1,int2: integer; +begin + int1:= getident; + result:= -1; + if int1 >= 0 then begin + for int2:= 0 to high(ident) do begin + if int1 = ident[int2] then begin + result:= int1; + break; + end; + end; + end; + if (result < 0) and (int1 >= 0) then begin + lasttoken; + end; +end; + +function tparser.testident(const ident: integer): boolean; + //skips whitespace, true if ident found +begin + result:= getident = ident; + if result then begin + lasttoken; + end; +end; + +function tparser.checknamenoident: boolean; +begin + result:= (getident = -1) and (fto^.kind = tk_name); + if result then begin + nexttoken; + end; +end; + +function tparser.skipnamenoident: boolean; +begin + result:= (getident = -1); + if result and (fto^.kind = tk_name) then begin + nexttoken(); + end; +end; + +function tparser.checkname: boolean; +begin + skipwhitespace; + result:= fto^.kind = tk_name; + if result then begin + nexttoken; + end; +end; + +function tparser.checkname(const aname: ansistring): boolean; +begin + skipwhitespace; + result:= (fto^.kind = tk_name) and issamelstring(fto^.value,aname,fcasesensitive); + if result then begin + nexttoken; + end; +end; + +function tparser.getname(out value: lstringty): boolean; +begin + skipwhitespace; + result:= fto^.kind = tk_name; + if result then begin + value:= fto^.value; + nexttoken; + end + else begin + value:= emptylstring; + end; +end; + +function tparser.getname: string; +var + value: lstringty; +begin + getname(value); + setstring(result,value.po,value.len); +end; + +function tparser.getorigname(out value: lstringty): boolean; +begin + skipwhitespace; + result:= fto^.kind = tk_name; + if result then begin + value:= fto^.value; + inc(value.po,fscanner.forigoffset); + nexttoken; + end + else begin + value:= emptylstring; + end; +end; + +function tparser.getorigname: string; +var + value: lstringty; +begin + getorigname(value); + setstring(result,value.po,value.len); +end; + +function tparser.getnamenoident(out value: lstringty): boolean; +begin + if getident < 0 then begin + result:= getname(value); + end + else begin + value:= emptylstring; + result:= false; + lasttoken; + end; +end; + +function tparser.getorignamenoident(out value: lstringty): boolean; +begin + if getident < 0 then begin + result:= getorigname(value); + end + else begin + value:= emptylstring; + result:= false; + lasttoken; + end; +end; + +function tparser.skipcomment: boolean; //does not skip whitespace +begin + result:= false; //dummy +end; + +function tparser.checknewline: boolean; +begin + skipwhitespaceonly; + if fto^.kind = tk_newline then begin + result:= true; + nexttoken; + end + else begin + result:= false; + end; +end; + +function tparser.nextline: boolean; //false if fileend +var + po1: ptokenty; +begin +// result:= false; + po1:= fto; + while (fto^.kind <> tk_fileend) and (fto^.kind <> tk_newline) do begin + inc(fto); + end; + if fto^.kind <> tk_fileend then begin + inc(fto); + result:= true; + end + else begin + result:= exitinclude; + exit; + end; + inc(ftokennum,(pchar(fto)-pchar(po1)) div sizeof(tokenty)); +end; + +function tparser.getvaluestring(var value: string): valuekindty; +var + str1: string; +begin + skipwhitespace; + result:= vk_none; + str1:= ''; + case fto^.kind of + tk_number: begin + mark; + result:= vk_integer; + value:= gettoken; + if (fto^.kind = tk_operator) and (fto^.op = '.') then begin + result:= vk_real; + value:= value + '.'; + nexttoken; + if fto^.kind = tk_number then begin + str1:= str1 + gettoken; + end + end; + if (fto^.kind = tk_name) and (fto^.value.len = 1) and + ((fto^.value.po^ = 'e') or (fto^.value.po^ = 'E')) then begin + result:= vk_real; + nexttoken; + if (fto^.kind = tk_operator) and + ((fto^.op = '+') or (fto^.op = '-')) then begin + value:= value+getoperator; + end; + if (fto^.kind = tk_number) then begin + value:= value + gettoken; + end + else begin + result:= vk_none; + end; + end; + if result <> vk_none then begin + pop; + end + else begin + back; + end; + end; + end; +end; + +function tparser.getnamelist: lstringarty; //names separated by ',' +var + count: integer; +begin + count:= 0; + setlength(result,1); + while not eof do begin + if not getname(result[count]) then begin + break; + end; + inc(count); + if not checkoperator(',') and (fto^.kind = tk_operator) then begin + break; + end; + if high(result) < count then begin + setlength(result,high(result)+33); + end; + end; + setlength(result,count); +end; + +function tparser.getorignamelist: lstringarty; //names separated by ',' +var + count: integer; +begin + count:= 0; + setlength(result,1); + while not eof do begin + if not getorigname(result[count]) then begin + break; + end; + inc(count); + if not checkoperator(',') and (fto^.kind = tk_operator) then begin + break; + end; + if high(result) < count then begin + setlength(result,high(result)+33); + end; + end; + setlength(result,count); +end; + +procedure tparser.internalerror; +begin + raise exception.Create('Internal error'); +end; + +procedure tparser.syntaxerror; +begin + inc(fsyntaxerrorcount) +end; + +function tparser.getscannerclass: scannerclassty; +begin + result:= tscanner; +end; + +{ +procedure tparser.setcasesensitive(const Value: boolean); +begin + fcasesensitive := Value; +end; +} +function tparser.getscanner: tscanner; +begin + if fscanners = nil then begin + result:= nil; + end + else begin + result:= fscanners[0]; + end; +end; + +procedure tparser.setscanner(const Value: tscanner); +begin + value.casesensitive:= fcasesensitive; + reset; + addscanner(value); + clear; + parse; +end; + +procedure tparser.parse; +begin + initidents; +end; + +procedure tparser.initidents; +begin + setidents([]); +end; + +{ tpascalparser } + +type + pskwordty = (pskw_i,pskw_include,pskw_define,pskw_undef,pskw_ifdef,pskw_ifndef, + pskw_else,pskw_endif); +const + pskwords: array[pskwordty] of string = + ('I','INCLUDE','DEFINE','UNDEF','IFDEF','IFNDEF', + 'ELSE','ENDIF'); + +constructor tpascalparser.create(const afilelist: tmseindexednamelist); +begin + inherited; + flastvalidident:= lastpascalnormalident; +end; + +destructor tpascalparser.destroy; +begin + inherited; +end; + +procedure tpascalparser.clear; +var + int1: integer; +begin + inherited; + fdefstate:= def_none; + fdefstates:= nil; + fdefstatecount:= 0; + fdefines.clear; + for int1:= 0 to high(fstartdefines) do begin + fdefines.add(uppercase(fstartdefines[int1])); + end; +end; + +procedure tpascalparser.parsecompilerswitch; + + procedure skiprest; + begin + while (fto^.kind <> tk_fileend) and + not((fto^.kind = tk_operator) and (fto^.op = '}')) do begin + nexttoken; + end; + nexttoken; //skip '}' + end; + + procedure skipskip; + begin + repeat + if not skipcomment then begin + nexttoken; + end; + until (fto^.kind = tk_fileend) or (fdefstate <> def_skip); + end; + +var + int1{,int2}: integer; + str1: string; + filename: filenamety; + anum: longword; + startpos{,endpos}: sourceposty; + lstr1: lstringty; +begin + anum:= ftokennum; + int1:= testnames(fto^,pskwords); + if int1 >= 0 then begin + if int1 > 1 then begin + nexttoken; + end; + case pskwordty(int1) of + pskw_ifdef,pskw_ifndef: begin + additem(fdefstates,integer(fdefstate),fdefstatecount); + if fdefstate <> def_skip then begin + if not (getname(lstr1) and + ((fdefines.find(lstr1) <> nil) xor + (pskwordty(int1) = pskw_ifndef))) then begin + fdefstate:= def_skip; + skiprest; + skipskip; + end + else begin + skiprest; + end; + end + else begin + skiprest; + end; + end; + pskw_else: begin + skiprest; + if fdefstate = def_skip then begin + if (fdefstatecount = 0) or + (defstatety(fdefstates[fdefstatecount-1]) <> def_skip) then begin + fdefstate:= def_none; + end; + end + else begin + if fdefstatecount > 0 then begin + fdefstate:= def_skip; + skipskip; + end; + end; + end; + pskw_endif: begin + if fdefstatecount > 0 then begin + dec(fdefstatecount); + fdefstate:= defstatety(fdefstates[fdefstatecount]); + end; + skiprest; + end; + else begin + if fdefstate <> def_skip then begin + case pskwordty(int1) of + pskw_i,pskw_include: begin + startpos:= sourcepos; + nexttoken; + if checkoperator('''') or checkoperator('#')then begin + lasttoken; + if getpascalstring(str1) then begin + try + filename:= pascalstringtostring(str1); + except + end; + end; + end + else begin + str1:= ''; + skipwhitespaceonly; + while not(fto^.kind in [tk_fileend,tk_newline,tk_whitespace]) and + not((fto^.kind = tk_operator) and (fto^.op = '}')) do begin + str1:= str1 + getorigtoken; + end; + filename:= filenamety(str1); + end; + if findoperator('}') then begin +// endpos:= lasttokenpos; + end + else begin +// endpos:= sourcepos; + end; + if filename <> '' then begin + callincludefile(filename,startpos,anum); + end; + end; + pskw_define: begin + str1:= getname; + if str1 <> '' then begin + fdefines.add(str1); + end; + skiprest; + end; + pskw_undef: begin + if getname(lstr1) then begin + fdefines.delete(lstr1); + end; + skiprest; + end; + end; + end; + end; + end; + end + else begin + skiprest; + end; +end; + +function tpascalparser.skipcomment: boolean; //does not skip whitespace +var + int1: integer; + first: boolean; +begin + result:= false; + if (fto^.kind = tk_operator) and (fto^.op = '/') and + checknextoperator('/') then begin + result:= true; + while not ((fto^.kind = tk_newline) or (fto^.kind = tk_fileend)) do begin + nexttoken; + end; + end + else begin + if (fto^.kind = tk_operator) then begin + if (fto^.op = '{') then begin + nexttoken; + result:= true; + first:= true; + int1:= 1; + while (int1 > 0) and (fto^.kind <> tk_fileend) do begin + if (fto^.kind = tk_operator) then begin + if first and (fto^.op = '$') then begin //compiler switch + nexttoken; + parsecompilerswitch; + int1:= 0; + break; + end; + if fto^.op = '}' then begin + dec(int1); + end; + if (fto^.op = '{') and frecursivecomment then begin + inc(int1); + end; + end; + first:= false; + nexttoken; + end; + if int1 > 0 then begin + syntaxerror; + end; + end + else begin + if (fto^.op = '(') and checknextoperator('*') then begin + nexttoken; + result:= true; + repeat + nexttoken; + if (fto^.kind = tk_operator) and (fto^.op = '*') then begin + nexttoken; + if (fto^.kind = tk_operator) and (fto^.op = ')') then begin + nexttoken; + break; + end; + end; + until fto^.kind = tk_fileend; + end; + end; + end; + end; +end; + +function tpascalparser.getpascalstring(var value: string): boolean; +var + int1: integer; + bo1: boolean; +begin + skipwhitespace; + mark; + value:= ''; + result:= (fto^.kind = tk_operator) and ((fto^.op = '#') or (fto^.op = '''')); + while result do begin + bo1:= false; + while (fto^.kind = tk_operator) and (fto^.op = '#') do begin + value:= value + getorigtoken; + if fto^.kind = tk_number then begin + value:= value + getorigtoken; + bo1:= true; + end + else begin + result:= false; + break; + end; + end; + if result then begin + while (fto^.kind = tk_operator) and (fto^.op = '''') do begin //' + bo1:= true; + int1:= 0; + while (fto^.kind = tk_operator) and (fto^.op = '''') do begin //','','''.. + value:= value + getorigtoken; + inc(int1); + end; + if odd(int1) then begin + while (fto^.kind <> tk_fileend) and (fto^.kind <> tk_newline) and + not ((fto^.kind = tk_operator) and (fto^.op = '''')) do begin + value:= value + getorigtoken; + end; + if (fto^.kind = tk_fileend) or (fto^.kind = tk_newline) then begin + result:= false; + break; + end; + value:= value + getorigtoken; + end; + end; + end; + if not bo1 then begin + break; + end; + end; + if result then begin + pop; + end + else begin + value:= ''; + back; + end; +end; + +function tpascalparser.concatpascalstring(var value: string): boolean; +var + str1: string; +begin + value:= ''; + repeat + result:= getpascalstring(str1); + if not result then begin + break; + end; + value:= value+str1+' '; + until not checkoperator('+'); +end; + +function tpascalparser.concatpascalname(var value: string): boolean; +var + str1: string; +begin + value:= ''; + result:= false; + repeat + str1:= getorigname; + if str1 <> '' then begin + value:= value + str1; + result:= true; + if not checkoperator('.') then begin + break; + end; + value:= value + '.'; + end; + until str1 = ''; +end; + +function tpascalparser.getvaluestring(var value: string): valuekindty; +begin + result:= inherited getvaluestring(value); + if result = vk_none then begin + if getpascalstring(value) then begin + result:= vk_string; + end; + end; +end; + +function tpascalparser.getscannerclass: scannerclassty; +begin + result:= tpascalscanner; +end; + +procedure tpascalparser.initidents; +begin + setidents(pascalidents); +end; + +function tpascalparser.checkclassident(const ident: pascalidentty): boolean; +begin + flastvalidident:= lastpascalclassident; + result:= checkident(integer(ident)); + flastvalidident:= lastpascalnormalident; +end; + +function tpascalparser.getclassident: pascalidentty; +begin + flastvalidident:= lastpascalclassident; + result:= pascalidentty(getident); + flastvalidident:= lastpascalnormalident; +end; + +function tpascalparser.checkpropertyident(const ident: pascalidentty): boolean; +begin + flastvalidident:= lastpascalpropertyident; + result:= checkident(integer(ident)); + flastvalidident:= lastpascalnormalident; +end; + +function tpascalparser.getpropertyident: pascalidentty; +begin + flastvalidident:= lastpascalpropertyident; + result:= pascalidentty(getident); + flastvalidident:= lastpascalnormalident; +end; + +{ tcparser } +type + cskwordty = (cskw_if,cskw_include,cskw_define,cskw_undef,cskw_ifdef,cskw_ifndef, + cskw_else,cskw_endif); +const + cskwords: array[cskwordty] of string = + ('if','include','define','undef','ifdef','ifndef', + 'else','endif'); + +constructor tcparser.create(const afilelist: tmseindexednamelist); +begin + inherited; + fcasesensitive:= true; +end; + +function tcparser.getscannerclass: scannerclassty; +begin + result:= tcscanner; +end; + +procedure tcparser.initidents; +begin + setidents([]); +end; + +function tcparser.getcstring(var value: string): boolean; +begin + skipwhitespace; + mark; + value:= ''; + result:= false; + while (fto^.kind = tk_operator) and (fto^.op = '"') do begin + result:= true; + value:= value + getorigtoken; //leading " + while not ((fto^.kind = tk_operator) and (fto^.op = '"')) do begin + if (fto^.kind = tk_operator) and (fto^.op = '\') then begin + value:= value + getorigtoken; //escapechar + if fto^.kind = tk_newline then begin + value:= value + getorigtoken; + end; + end; + if (fto^.kind = tk_fileend) or (fto^.kind = tk_newline) then begin + result:= false; + break; + end; + value:= value + getorigtoken; + end; + if result then begin + value:= value + getorigtoken; // terminating " + if fto^.kind = tk_whitespace then begin + nexttoken; + if (fto^.kind = tk_operator) and (fto^.op = '"') then begin + lasttoken; + value:= value + getorigtoken; + end; + end; + end + else begin + break; + end; + end; + if result then begin + pop; + end + else begin + value:= ''; + back; + end; +end; + +function tcparser.getvaluestring(var value: string): valuekindty; +begin + result:= inherited getvaluestring(value); + if result = vk_none then begin + if getcstring(value) then begin + result:= vk_string; + end; + end; +end; + +procedure tcparser.parsepreprocdef; + + procedure skiprest; + begin + while not ((fto^.kind = tk_newline) or (fto^.kind = tk_fileend)) do begin + //skip rest of line + nexttoken; + end; + end; + + procedure skipskip; + begin + repeat + if not skipcomment then begin + nexttoken; + end; + until (fdefstate <> def_skip) or eof; + end; + +var + startpos: sourceposty; + anum: integer; + int1: integer; + bo1: boolean; + str1: string; + po1: pchar; + lstr1: lstringty; +begin + startpos:= sourcepos; + anum:= ftokennum; + nexttoken; + int1:= testnames(fto^,cskwords); + if int1 >= 0 then begin + nexttoken; + end; + case cskwordty(int1) of + cskw_ifdef,cskw_ifndef: begin + additem(fdefstates,integer(fdefstate),fdefstatecount); + if fdefstate <> def_skip then begin + if not (getname(lstr1) and + ((fdefines.find(lstr1) <> nil) xor + (cskwordty(int1) = cskw_ifndef))) then begin + fdefstate:= def_skip; + skiprest; + skipskip; + exit; //no skip rest + end + end + end; + cskw_else: begin + skiprest; + if fdefstate = def_skip then begin + if (fdefstatecount = 0) or + (defstatety(fdefstates[fdefstatecount-1]) <> def_skip) then begin + fdefstate:= def_none; + end; + end + else begin + if fdefstatecount > 0 then begin + fdefstate:= def_skip; + skipskip; + exit; + end; + end; + exit; //no skiprest + end; + cskw_endif: begin + if fdefstatecount > 0 then begin + dec(fdefstatecount); + fdefstate:= defstatety(fdefstates[fdefstatecount]); + end; + end; + else begin + if fdefstate <> def_skip then begin + case cskwordty(int1) of + cskw_include: begin + bo1:= getcstring(str1); + if not bo1 and checkoperator('<') then begin + po1:= fto^.value.po; + mark; + bo1:= findoperator('>'); + if bo1 then begin + pop; + str1:= getorigtext(po1); + if str1 <> '' then begin + setlength(str1,length(str1)-1); + end; + end + else begin + back; + end; + end + else begin + str1:= cstringtostring(str1); + end; + skiprest; + if bo1 then begin + callincludefile(filenamety(str1),startpos,anum); + skipcomment; + exit; //no skip of rest of line + end + end; + cskw_define: begin + str1:= getname; + if str1 <> '' then begin + fdefines.add(str1); + end; + end; + cskw_undef: begin + if getname(lstr1) then begin + fdefines.delete(lstr1); + end; + end; + end; + end; + end; + end; + skiprest; +end; + +function tcparser.skipcomment: boolean; +var + int1: integer; +// bo1: boolean; +// str1: ansistring; +begin + result:= false; + if fincomment = 0 then begin + inc(fincomment); + if (fto^.kind = tk_operator) and + ((fto^.op = '/') and checknextoperator('/') or + (fto^.op = '#') and isfirstnonwhitetoken) then begin + if fto^.op = '#' then begin + result:= true; + dec(fincomment); + parsepreprocdef; + inc(fincomment); + end + else begin + while not ((fto^.kind = tk_newline) or (fto^.kind = tk_fileend)) do begin + nexttoken; + end; + result:= true; + end; + end + else begin + if (fto^.kind = tk_operator) and (fto^.op = '/') and checknextoperator('*') then begin + result:= true; + int1:= 1; + while (int1 > 0) and (fto^.kind <> tk_fileend) do begin + if (fto^.kind = tk_operator) then begin + if fto^.op = '*' then begin + if checknextoperator('/') then begin + dec(int1); + end; + end + else begin + if (fto^.op = '/') and frecursivecomment then begin + if checknextoperator('*') then begin + inc(int1); + end; + end; + end; + end; + nexttoken; + end; + if int1 > 0 then begin + syntaxerror; + end; + end; + end; + dec(fincomment); + end; +end; + +function tcparser.skipstatement: boolean; +var +// int1: integer; + ch1: char; +begin + result:= false; +// int1:= 0; + repeat + ch1:= getnextoperator; + case ch1 of + ';','{','}': begin + result:= true; + break; + end; + end; + { + case ch1 of + '(': begin + inc(int1); + end; + ')': begin + dec(int1); + end; + ';': begin + if int1 <= 0 then begin + result:= true; + break; + end; + end; + end; + } + until ch1 = #0; +end; + +{ tconstparser } + +function tconstparser.getconsts(var ar: constinfoarty): string; //returns unitname + +var + count: integer; + + function additem: pconstinfoty; + begin + if high(ar) <= count then begin + setlength(ar,high(ar) + 33); + end; + result:= @ar[count]; + inc(count); + end; + +var + str1,str2: string; + ch1: char; + ident: pascalidentty; + resourceflag: boolean; + apos: pchar; + +begin + ar:= nil; + count:= 0; + result:= ''; + while not eof do begin + ident:= pascalidentty(getident); + if (ident = pid_unit) or (ident = pid_program) then begin + result:= getname; + end; + if (ident = pid_const) or (ident = pid_resourcestring) then begin + resourceflag:= ident = pid_resourcestring; + repeat + mark; + if getident >= 0 then begin + pop; + lasttoken; + break; + end; + str1:= getname; + if str1 <> '' then begin + ch1:= getoperator; + if ch1 = '=' then begin + skipwhitespace; + apos:= fto^.value.po; + case getvaluestring(str2) of + vk_string: begin + with additem^ do begin + valuetype:= vawstring; + name:= str1; + value:= pascalstringtostring(str2); + resource:= resourceflag; + offset:= apos-pchar(pointer(fscanner.fsource)); + len:= fto^.value.po-apos; + end; + end; + else begin + nexttoken; + end; + end; + pop; + end + else begin + back; + end; + end + else begin + pop; + nexttoken; + end; + until not checkoperator(';'); + end + else begin + nexttoken; + end; + end; + setlength(ar,count); +end; + +{ tfpcresstringparser } + +procedure tfpcresstringparser.getconsts(var ar: constinfoarty); +var + count: integer; + str1,str2: string; + apos: pchar; + mstr1: msestring; + po1: pchar; + i1: int32; + +begin + ar:= nil; + count:= 0; + while (fsyntaxerrorcount = 0) and not eof do begin + if testoperator('#') then begin + nextline; + end + else begin + if concatpascalname(str1) and checkoperator('=') then begin + skipwhitespace; + apos:= fto^.value.po; + if concatpascalstring(str2) then begin + additem(ar,typeinfo(constinfoarty),count); + with ar[count-1] do begin + valuetype:= vawstring; + name:= str1; + mstr1:= pascalstringtostring(str2); + setlength(str1,length(mstr1)); + po1:= pointer(str1); + for i1:= 1 to length(mstr1) do begin + po1^:= char(byte(mstr1[i1])); //utf8 is returned as #byte array, + inc(po1); + end; + value:= msestring(str1); //assume locale encoding, + //{$codepage} does not work with FPC 2.6.4 resourcestrings + offset:= apos-pchar(pointer(fscanner.fsource)); + len:= fto^.value.po-apos; + end; + end; + end + else begin + nextline; + end; + end; + end; + setlength(ar,count); +end; + +{ tresstringlistparser } + +constructor tresstringlistparser.create(const afilelist: tmseindexednamelist); +begin + inherited; + fcasesensitive:= true; +end; + +procedure tresstringlistparser.getconsts(var ar: constinfoarty); +type + residentty = (ri_stringtable,ri_begin,ri_end); +const + residents: array[residentty] of string = + ('STRINGTABLE','BEGIN','END'); + +var + count: integer; + + function additem: pconstinfoty; + begin + if high(ar) <= count then begin + setlength(ar,high(ar) + 33); + end; + result:= @ar[count]; + inc(count); + end; + +var + str1,str2: string; + ident: residentty; + apos: pchar; + +begin + setidents(residents); + ar:= nil; + count:= 0; + while (fsyntaxerrorcount = 0) and not eof do begin + ident:= residentty(getfirstident); + if (ident = ri_stringtable) then begin + repeat + until (residentty(getfirstident) = ri_begin) or eof; + while (fsyntaxerrorcount = 0) and not eof do begin + nextline; + if fto^.kind = tk_whitespace then begin + str1:= getname; + if str1 = '' then begin + syntaxerror; + end + else begin + if checkoperator(',') then begin + skipwhitespace; + apos:= fto^.value.po; + if getvaluestring(str2) = vk_string then begin + with additem^ do begin + valuetype:= vawstring; + name:= str1; + value:= msestring(cstringtostring(str2)); + offset:= apos-pchar(pointer(fscanner.fsource)); + len:= fto^.value.po-apos; + end; + end + else begin + syntaxerror; + end; + end + else begin + syntaxerror; + end; + end; + end + else begin + if residentty(getident) <> ri_end then begin + syntaxerror; + end; + break; + end; + end; + end + else begin + nextline; + end; + end; + setlength(ar,count); +end; + + +end. diff --git a/mseide-msegui/lib/common/designutils/msepropertyeditors.pas b/mseide-msegui/lib/common/designutils/msepropertyeditors.pas new file mode 100644 index 0000000..d42c452 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msepropertyeditors.pas @@ -0,0 +1,6158 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msepropertyeditors; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface +uses + classes,mclasses,TypInfo,msedesignintf,msetypes,msestrings,sysutils, + msearrayutils,msedatalist, + msemenus,mseevent,msegui,mseglob,mseguiglob, + mseclasses,mseforms,msegraphics,mserichstring; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + bmpfiledialogstatname = 'bmpfile.sta'; + numcharchar = msechar('['); + +type + + defaultenumerationty = (null); + defaultsetty = set of defaultenumerationty; + + tpropertyeditor = class; + propertyeditorarty = array of tpropertyeditor; + + propinstancety = record + instance: tobject; + propinfo: ppropinfo; + end; + propinstancearty = array of propinstancety; + ppropinstancearty = ^propinstancearty; + + iobjectinspector = interface(inullinterface) + procedure propertymodified(const sender: tpropertyeditor); + function getproperties(const objects: objectarty; + const amodule: tmsecomponent; + const acomponent: tcomponent): propertyeditorarty; +// procedure componentnamechanged(comp: tcomponent; newname: string); + function getmatchingmethods(const sender: tpropertyeditor; atype: ptypeinfo): msestringarty; + end; + + propertystatety = (ps_expanded,ps_subproperties,ps_volatile, + ps_refresh, //needs refresh by modified + ps_valuelist,ps_dialog,ps_sortlist,ps_owned, + ps_noadditems,ps_nodeleteitems, + ps_isordprop,ps_modified,ps_candefault,ps_component,ps_subprop, + ps_selected,ps_canselect,ps_refreshall, + ps_local, //do not display foreign components + ps_link); //do not display selected components + propertystatesty = set of propertystatety; + + iremotepropertyeditor = interface(inullinterface) + function getordvalue(const index: integer = 0): integer; + procedure setordvalue(const value: longword); overload; + procedure setordvalue(const index: integer; const value: longword); overload; + procedure setbitvalue(const value: boolean; const bitindex: integer); + function getint64value(const index: integer = 0): int64; + procedure setint64value(const value: int64); overload; + procedure setint64value(const index: integer; const value: int64); overload; + function getpointervalue(const index: integer = 0): pointer; + procedure setpointervalue(const value: pointer); overload; + procedure setpointervalue(const index: integer; const value: pointer); overload; + function getfloatvalue(const index: integer = 0): extended; + procedure setfloatvalue(const value: extended); + function getcurrencyvalue(const index: integer = 0): currency; + procedure setcurrencyvalue(const value: currency); + function getstringvalue(const index: integer = 0): string; + procedure setstringvalue(const value: string); + function getutf8stringvalue(const index: integer = 0):utf8string; + procedure setutf8stringvalue(const value: utf8string); + function getmsestringvalue(const index: integer = 0; + const raw: boolean = false): msestring; + procedure setmsestringvalue(const value: msestring; + const raw: boolean = false); + function getvariantvalue(const index: integer = 0): variant; + procedure setvariantvalue(const value: variant); + function getparenteditor: tpropertyeditor; + + function getmethodvalue(const index: integer = 0): tmethod; + procedure setmethodvalue(const value: tmethod); + function getselected: boolean; + procedure setselected(const avalue: boolean); + property selected: boolean read getselected write setselected; + function getselectedpropinstances: objectarty; + end; + + tpropertyeditor = class(tnullinterfacedobject) + private + function getexpanded: boolean; + procedure setexpanded(const Value: boolean); + function getcount: integer; + function getselected: boolean; + procedure setselected(const avalue: boolean); + function getlinkcomponent: tcomponent; + protected + fsortlevel: integer; + ftypeinfo: ptypeinfo; + fstate: propertystatesty; + fparenteditor: tpropertyeditor; + fname: msestring; + fdesigner: idesigner; + fmodule: tmsecomponent; + fcomponent: tcomponent; + fobjectinspector: iobjectinspector; + fprops: propinstancearty; + fremote: iremotepropertyeditor; + procedure properror; + + function instance(const index: integer = 0): tobject; + function typedata: ptypedata; + + function gettypinfo: ptypeinfo; virtual; + function getordvalue(const index: integer = 0): integer; virtual; + procedure setordvalue(const value: longword); virtual; overload; + procedure setordvalue(const index: integer; const value: longword); + virtual; overload; + function getint64value(const index: integer = 0): int64; virtual; + procedure setint64value(const value: int64); virtual; overload; + procedure setint64value(const index: integer; const value: int64); + virtual; overload; + function getpointervalue(const index: integer = 0): pointer; virtual; + procedure setpointervalue(const value: pointer); overload; virtual; + procedure setpointervalue(const index: integer; const value: pointer); + virtual; overload; + + procedure setbitvalue(const value: boolean; const bitindex: integer); + virtual; + function getfloatvalue(const index: integer = 0): extended; virtual; + procedure setfloatvalue(const value: extended); virtual; + function getcurrencyvalue(const index: integer = 0): currency; virtual; + procedure setcurrencyvalue(const value: currency); virtual; + function getstringvalue(const index: integer = 0): string; virtual; + procedure setstringvalue(const value: string); virtual; + function getutf8stringvalue(const index: integer = 0): utf8string virtual; + procedure setutf8stringvalue(const value: utf8string) virtual; + function getmsestringvalue(const index: integer = 0; + const raw: boolean = false): msestring; virtual; + procedure setmsestringvalue(const value: msestring; + const raw: boolean = false); virtual; + function getvariantvalue(const index: integer = 0): variant; virtual; + procedure setvariantvalue(const value: variant); virtual; + + function decodemsestring(const avalue: msestring): msestring; + function encodemsestring(const avalue: msestring): msestring; + + function getmethodvalue(const index: integer = 0): tmethod; + procedure setmethodvalue(const value: tmethod); + function getparenteditor: tpropertyeditor; + function queryselectedpropinstances: objectarty; + + procedure modified; virtual; + function getdefaultstate: propertystatesty; virtual; + procedure setsubprop; virtual; + function getvalueeditor: tpropertyeditor; virtual; + function getlinksource: tcomponent; virtual; + public + constructor create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypeinfo: ptypeinfo); virtual; + destructor destroy; override; + procedure setremote(intf: iremotepropertyeditor); + procedure updatedefaultvalue; virtual; + function canrevert: boolean; virtual; + procedure copyproperty(const asource: tobject); virtual; + + function propertyname: msestring; virtual; + function name: msestring; virtual; + function allequal: boolean; virtual; + function subproperties: propertyeditorarty; virtual; + function props: propinstancearty; + function rootprops: propinstancearty; + function propowner: componentarty; + //value of classproperty + + procedure setvalue(const value: msestring); virtual; + function getvalue: msestring; virtual; + function getvalues: msestringarty; virtual; + property state: propertystatesty read fstate; + function sortlevel: integer; + procedure dragbegin(var accept: boolean); virtual; + procedure dragover(const sender: tpropertyeditor; var accept: boolean); virtual; + procedure dragdrop(const sender: tpropertyeditor); virtual; + procedure dopopup(var amenu: tpopupmenu; const atransientfor: twidget; + var mouseinfo: mouseeventinfoty); virtual; + procedure dokeydown(var ainfo: keyeventinfoty); virtual; + procedure edit(); virtual; + procedure focused() virtual; + procedure navigevent(); virtual; + property typinfo: ptypeinfo read gettypinfo; + property count: integer read getcount; + property expanded: boolean read getexpanded write setexpanded; + property selected: boolean read getselected write setselected; + property module: tmsecomponent read fmodule; + property component: tcomponent read fcomponent; + property parenteditor: tpropertyeditor read fparenteditor; + property valueeditor: tpropertyeditor read getvalueeditor; + property linksource: tcomponent read getlinksource; + property linkcomponent: tcomponent read getlinkcomponent; + end; + + propertyeditorclassty = class of tpropertyeditor; + + tstringpropertyeditor = class(tpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + function allequal: boolean; override; + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + end; + + tutf8stringpropertyeditor = class(tpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + function allequal: boolean; override; + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + end; + + trefreshstringpropertyeditor = class(tstringpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + end; + + tnamepropertyeditor = class(tstringpropertyeditor) + procedure setvalue(const value: msestring); override; + end; + + tfontnamepropertyeditor = class(tstringpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + function getvalues: msestringarty; override; + end; + + tmsestringpropertyeditor = class(tpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + procedure edit; override; + function allequal: boolean; override; + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + end; + + trichstringpropertyeditor = class(tmsestringpropertyeditor) + public + procedure edit; override; + end; + + tordinalpropertyeditor = class(tpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + function allequal: boolean; override; + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + end; + + tvolatileordinalpropertyeditor = class(tordinalpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + end; + + tint64propertyeditor = class(tpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + function allequal: boolean; override; + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + end; + + tcharpropertyeditor = class(tordinalpropertyeditor) + public + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + end; + + twidecharpropertyeditor = class(tordinalpropertyeditor) + public + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + end; + + tbooleanpropertyeditor = class(tordinalpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + function getvalues: msestringarty; override; + end; + + tvolatilebooleanpropertyeditor = class(tbooleanpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + end; + + trefreshbooleanpropertyeditor = class(tbooleanpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + end; + + trealpropertyeditor = class(tpropertyeditor) + public + function allequal: boolean; override; + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + end; + + trealtypropertyeditor = class(tpropertyeditor) + public + function allequal: boolean; override; + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + end; + + tcurrencypropertyeditor = class(tpropertyeditor) + public + function allequal: boolean; override; + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + end; + + tdatetimepropertyeditor = class(tpropertyeditor) + public + function allequal: boolean; override; + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + end; + + tvariantpropertyeditor = class(tpropertyeditor) + protected + public + function allequal: boolean; override; + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + end; + + tenumpropertyeditor = class(tordinalpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + function gettypeinfo: ptypeinfo; virtual; + public + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + function getvalues: msestringarty; override; + end; + + tshortcutpropertyeditor = class(tenumpropertyeditor) + protected + fsc1: boolean; + fscar: boolean; + function getvaluetext(const avalue: shortcutty): msestring; + function texttovalue(const atext: msestring): shortcutty; + public + constructor create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypeinfo: ptypeinfo); override; + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + function getvalues: msestringarty; override; + end; + + tshortcutarpropertyeditor = class(tshortcutpropertyeditor) + public + constructor create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypeinfo: ptypeinfo); override; + end; + + tcolorpropertyeditor = class(tenumpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + procedure edit; override; + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + function getvalues: msestringarty; override; + end; + + tclasspropertyeditor = class(tpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + function checkfreeoptionalclass: boolean; + function dispname: msestring; virtual; + public + function getvalue: msestring; override; + function subproperties: propertyeditorarty; override; + end; + + toptionalclasspropertyeditor = class(tclasspropertyeditor) + protected + function getniltext: msestring; virtual; + function getinstance: tpersistent; virtual; + function getdefaultstate: propertystatesty; override; + procedure deleteinstance; + public + function canrevert: boolean; override; + procedure setvalue(const avalue: msestring); override; + function getvalue: msestring; override; + procedure edit; override; + end; + + ppersistent = ^tpersistent; + tparentclasspropertyeditor = class(toptionalclasspropertyeditor) + protected + function getniltext: msestring; override; + function getinstancepo(acomponent: tobject): ppersistent; virtual; abstract; + function getinstance: tpersistent; override; + public + function subproperties: propertyeditorarty; override; + procedure edit; override; + end; + + tparentfontpropertyeditor = class(tparentclasspropertyeditor) + protected + function getinstancepo(acomponent: tobject): ppersistent; override; + end; + + + //no solution found to link to streamed tpersistent or tobject, + //fork of classes.pp necessary. :-( +{ + tlinkedobjectpropertyeditor = class(tclasspropertyeditor) + protected +// function issubcomponent(const index: integer = 0): boolean; + function getdefaultstate: propertystatesty; override; + procedure checkobj(const avalue: tobject); virtual; + function filterobj(const aobj: tobject): boolean; virtual; + public + function allequal: boolean; override; + function getvalue: msestring; override; + procedure setvalue(const value: msestring); override; + function getvalues: msestringarty; override; + end; +} + tcomponentpropertyeditor = class(tclasspropertyeditor) + protected + function issubcomponent(const index: integer = 0): boolean; virtual; + function getdefaultstate: propertystatesty; override; + procedure checkcomponent(const avalue: tcomponent); virtual; + function filtercomponent(const acomponent: tcomponent): boolean; virtual; + function getlinksource: tcomponent; override; + public + procedure edit; override; + function allequal: boolean; override; + function getvalue: msestring; override; + procedure setvalue(const value: msestring); override; + function getvalues: msestringarty; override; + end; + + tsubcomponentpropertyeditor = class(tcomponentpropertyeditor) + protected + function issubcomponent(const index: integer = 0): boolean; override; + end; + + tcomponentinterfacepropertyeditor = class(tcomponentpropertyeditor) + private + fintfinfo: ptypeinfo; + protected + function filtercomponent(const acomponent: tcomponent): boolean; override; + function getintfinfo: ptypeinfo; virtual; abstract; + public + procedure updatedefaultvalue; override; + end; + + tsisterwidgetpropertyeditor = class(tcomponentpropertyeditor) + protected + function filtercomponent(const acomponent: tcomponent): boolean; override; + function getdefaultstate: propertystatesty; override; + public +// function getvalues: msestringarty; override; + end; + + tnochildrenwidgetpropertyeditor = class(tcomponentpropertyeditor) + protected + function filtercomponent(const acomponent: tcomponent): boolean; override; + function getdefaultstate: propertystatesty; override; + public +// function getvalues: msestringarty; override; + end; + + tchildwidgetpropertyeditor = class(tcomponentpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + function getvalues: msestringarty; override; + end; + + tlocalcomponentpropertyeditor = class(tcomponentpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + end; + + tlinkcomponentpropertyeditor = class(tcomponentpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + end; + + tlocallinkcomponentpropertyeditor = class(tcomponentpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + end; + + tsetpropertyeditor = class; + tsetelementeditor = class(tpropertyeditor) + protected +// fparent: tsetpropertyeditor; + findex: integer; + function getdefaultstate: propertystatesty; override; + public + constructor create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypeinfo: ptypeinfo; + const aparent: tsetpropertyeditor; const aindex: integer); + reintroduce; virtual; + procedure updatedefaultvalue; override; + function canrevert: boolean; override; + function allequal: boolean; override; + function propertyname: msestring; override; + function name: msestring; override; + function getvalue: msestring; override; + function getvalues: msestringarty; override; + procedure setvalue(const value: msestring); override; + end; + + setelementeditorclassty = class of tsetelementeditor; + + tsetpropertyeditor = class(tordinalpropertyeditor) + protected + finvisibleitems: tintegerset; + felementeditorclass: setelementeditorclassty; + function getdefaultstate: propertystatesty; override; + function getinvisibleitems: tintegerset; virtual; + public + constructor create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypeinfo: ptypeinfo); override; + function getvalue: msestring; override; + procedure setvalue(const value: msestring); override; + function subproperties: propertyeditorarty; override; + end; + + tvolatilesetpropertyeditor = class(tsetpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + constructor create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypeinfo: ptypeinfo); override; + + end; + + tmethodpropertyeditor = class(tpropertyeditor) + public + constructor create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypinfo: ptypeinfo); override; + function getdefaultstate: propertystatesty; override; + function allequal: boolean; override; + function getvalue: msestring; override; + function getvalues: msestringarty; override; + procedure setvalue(const value: msestring); override; + procedure navigevent(); override; + function method: tmethod; + end; + + tdialogclasspropertyeditor = class(tclasspropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + end; + + tbitmappropertyeditor = class(tdialogclasspropertyeditor) + public + procedure edit; override; + function getvalue: msestring; override; + procedure setvalue(const value: msestring); override; + end; + + tstringspropertyeditor = class(tdialogclasspropertyeditor) + protected + procedure closequery(const sender: tcustommseform; + var amodalresult: modalresultty); + public + procedure edit; override; + function getvalue: msestring; override; + end; + + ttextstringspropertyeditor = class(tdialogclasspropertyeditor) + protected + fmodalresult: modalresultty; + forigtext: msestringarty; + procedure closequery(const sender: tcustommseform; + var amodalresult: modalresultty); + procedure doafterclosequery(var amodalresult: modalresultty); virtual; + function getsyntaxindex: integer; virtual; + function gettestbutton: boolean; virtual; + function getutf8: boolean; virtual; + function getcaption: msestring; virtual; + procedure updateline(var aline: ansistring); virtual; + function ismsestring: boolean; virtual; + public + procedure edit; override; + procedure setvalue(const avalue: msestring); override; + function getvalue: msestring; override; + end; + + listeditformkindty = (lfk_none,lfk_msestring,lfk_real,lfk_integer, + lfk_msestringint,lfk_complex); + + tdatalistpropertyeditor = class(tdialogclasspropertyeditor) + protected + formkind: listeditformkindty; + procedure closequery(const sender: tcustommseform; + var amodalresult: modalresultty); + procedure checkformkind; + function getdefaultstate: propertystatesty; override; + public + procedure edit; override; + function getvalue: msestring; override; + end; + + toptionaldatalistpropertyeditor = class(tdatalistpropertyeditor) + protected + function getniltext: msestring; virtual; + function getinstance: tpersistent; virtual; + procedure deleteinstance; + function getdefaultstate: propertystatesty; override; + public + function canrevert: boolean; override; + procedure setvalue(const avalue: msestring); override; + function getvalue: msestring; override; + procedure edit; override; + end; + + tmsestringdatalistpropertyeditor = class(tdialogclasspropertyeditor) + procedure edit; override; + function getvalue: msestring; override; + protected + procedure closequery(const sender: tcustommseform; + var amodalresult: modalresultty); + function getdefaultstate: propertystatesty; override; + end; + + tdoublemsestringdatalistpropertyeditor = class(tdialogclasspropertyeditor) + procedure edit; override; + function getvalue: msestring; override; + protected + procedure closequery(const sender: tcustommseform; + var amodalresult: modalresultty); + function getdefaultstate: propertystatesty; override; + end; + + tmsestringintdatalistpropertyeditor = class(tdialogclasspropertyeditor) + procedure edit; override; + function getvalue: msestring; override; + protected + procedure closequery(const sender: tcustommseform; + var amodalresult: modalresultty); + function getdefaultstate: propertystatesty; override; + end; + +const + propmaxarraycount = 100; + +type + + tarraypropertyeditor = class; + + tarrayelementeditor = class(tpropertyeditor,iremotepropertyeditor) + private + feditor: tpropertyeditor; + protected + findex: integer; + function gettypinfo: ptypeinfo; override; + + procedure doinsert(const sender: tobject); + procedure doappend(const sender: tobject); + procedure dodelete(const sender: tobject); + + function getordvalue(const index: integer = 0): integer; override; + procedure setordvalue(const value: longword); override; overload; + procedure setordvalue(const index: integer; const value: longword); + override; overload; + function getint64value(const index: integer = 0): int64; override; + procedure setint64value(const value: int64); override; overload; + procedure setint64value(const index: integer; const value: int64); + override; overload; + function getpointervalue(const index: integer = 0): pointer; override; + procedure setpointervalue(const value: pointer); override; overload; + procedure setpointervalue(const index: integer; const value: pointer); + override; overload; + + procedure setbitvalue(const value: boolean; const bitindex: integer); + override; + function getfloatvalue(const index: integer = 0): extended; override; + procedure setfloatvalue(const value: extended); override; + function getstringvalue(const index: integer = 0): string; override; + procedure setstringvalue(const value: string); override; + function getmsestringvalue(const index: integer = 0; + const raw: boolean = false): msestring; override; + procedure setmsestringvalue(const value: msestring; + const raw: boolean = false); override; + + function getselectedpropinstances: objectarty; virtual; + + function getdefaultstate: propertystatesty; override; + function getvalueeditor: tpropertyeditor; override; + function getlinksource: tcomponent; override; + public + constructor create(aindex: integer; aparenteditor: tarraypropertyeditor; + aeditorclass: propertyeditorclassty; + const adesigner: idesigner; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypinfo: ptypeinfo); reintroduce; + virtual; + destructor destroy; override; + function canrevert: boolean; override; + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + function getvalues: msestringarty; override; + procedure edit; override; + procedure focused() override; + function name: msestring; override; + function subproperties: propertyeditorarty; override; + procedure dragbegin(var accept: boolean); override; + procedure dragover(const sender: tpropertyeditor; var accept: boolean); override; + procedure dragdrop(const sender: tpropertyeditor); override; + procedure dopopup(var amenu: tpopupmenu; const atransientfor: twidget; + var mouseinfo: mouseeventinfoty); override; + procedure dokeydown(var ainfo: keyeventinfoty); override; + property index:int32 read findex; + end; + + elementeditorclassty = class of tarrayelementeditor; + elementeditorarty = array of tarrayelementeditor; + + tarraypropertyeditor = class(tclasspropertyeditor) + private + fsubprops: elementeditorarty; + procedure doappend(const sender: tobject); + procedure doinsert(const sender: tobject); + protected + function getdefaultstate: propertystatesty; override; + function geteditorclass: propertyeditorclassty; virtual; + function getelementeditorclass: elementeditorclassty; virtual; + procedure itemmoved(const source,dest: integer); virtual; + function getitemtypeinfo: ptypeinfo; virtual; + + function itemgetdefaultstate( + const sender: tarrayelementeditor): propertystatesty; virtual; + function itemgetlinksource( + const sender: tarrayelementeditor): tcomponent; virtual; + procedure itemsetvalue(const sender: tarrayelementeditor; + const value: msestring); virtual; + function itemgetvalue(const sender: tarrayelementeditor): msestring; + virtual; + function itemgetvalues( + const sender: tarrayelementeditor): msestringarty; virtual; + procedure itemedit(const sender: tarrayelementeditor); virtual; + procedure itemfocused(const sender: tarrayelementeditor) virtual; + function itemname( + const sender: tarrayelementeditor): msestring; virtual; + function itemsubproperties( + const sender: tarrayelementeditor): propertyeditorarty; virtual; + + public + function itemprefix: msestring; virtual; + procedure move(const curindex,newindex: integer); virtual; + function allequal: boolean; override; + function getvalue: msestring; override; + procedure setvalue(const value: msestring); override; + function subproperties: propertyeditorarty; override; + function name: msestring; override; + procedure dopopup(var amenu: tpopupmenu; const atransientfor: twidget; + var mouseinfo: mouseeventinfoty); override; + procedure dokeydown(var ainfo: keyeventinfoty); override; + end; + + tconstelementeditor = class(tarrayelementeditor) + protected + fvalue: msestring; + public + constructor create(const avalue: msestring; + aindex: integer; aparenteditor: tarraypropertyeditor; + aeditorclass: propertyeditorclassty; + const adesigner: idesigner; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypinfo: ptypeinfo); reintroduce; + procedure dragdrop(const sender: tpropertyeditor); override; + function getvalue: msestring; override; + end; + + tconstarraypropertyeditor = class(tarraypropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + function allequal: boolean; override; + function getvalue: msestring; override; + function name: msestring; override; + procedure setvalue(const value: msestring); override; + end; + + tcollectionpropertyeditor = class; + + tcollectionitemeditor = class(tpropertyeditor,iremotepropertyeditor) + private + findex: integer; + feditor: tpropertyeditor; + protected + function getdefaultstate: propertystatesty; override; +// function getordvalue(const index: integer = 0): integer; +// procedure setordvalue(const value: longword); overload; +// procedure setordvalue(const index: integer; const value: longword); overload; + function getpointervalue(const index: integer = 0): pointer; override; + procedure setpointervalue(const value: pointer); override; overload; + procedure setpointervalue(const index: integer; const value: pointer); + override; overload; + procedure doinsert(const sender: tobject); + procedure doappend(const sender: tobject); + procedure dodelete(const sender: tobject); + function getselectedpropinstances: objectarty; + public + constructor create(aindex: integer; aparenteditor: tcollectionpropertyeditor; + aeditorclass: propertyeditorclassty; + const adesigner: idesigner; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypinfo: ptypeinfo); reintroduce; + destructor destroy; override; + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + function getvalues: msestringarty; override; + procedure edit; override; + function subproperties: propertyeditorarty; override; + function name: msestring; override; + + procedure dragbegin(var accept: boolean); override; + procedure dragover(const sender: tpropertyeditor; var accept: boolean); override; + procedure dragdrop(const sender: tpropertyeditor); override; + procedure dopopup(var amenu: tpopupmenu; const atransientfor: twidget; + var mouseinfo: mouseeventinfoty); override; + procedure dokeydown(var ainfo: keyeventinfoty); override; + end; + + collectionitemeditorclassty = class of tcollectionitemeditor; + + tcollectionpropertyeditor = class(tclasspropertyeditor) + private + procedure doinsert(const sender: tobject); + procedure doappend(const sender: tobject); + protected + function getdefaultstate: propertystatesty; override; + procedure itemmoved(const source,dest: integer); virtual; + public + function name: msestring; override; + function getvalue: msestring; override; + procedure setvalue(const value: msestring); override; + function subproperties: propertyeditorarty; override; + procedure dopopup(var amenu: tpopupmenu; const atransientfor: twidget; + var mouseinfo: mouseeventinfoty); override; + procedure dokeydown(var ainfo: keyeventinfoty); override; + end; + + tpersistentarraypropertyeditor = class(tarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + toptionalpersistentarraypropertyeditor = class(tpersistentarraypropertyeditor) + protected + function getniltext: msestring; virtual; + function getinstance: tpersistent; virtual; + function getdefaultstate: propertystatesty; override; + public + function getvalue: msestring; override; + procedure setvalue(const value: msestring); override; + procedure edit; override; + end; + + tmenuarraypropertyeditor = class(tarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + +{ + tordinalelementeditor = class(tarrayelementeditor) + public + function getvalue: msestring; override; + procedure setvalue(const value: msestring); override; + end; +} + tclasselementeditor = class(tclasspropertyeditor) + protected + function dispname: msestring; override; + function getdefaultstate: propertystatesty; override; + public + function getvalue: msestring; override; + end; + + tmenuelementeditor = class(tclasselementeditor) + public + function getvalue: msestring; override; + end; + + tintegerarraypropertyeditor = class(tarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + tsetarrayelementeditor = class(tarrayelementeditor) + public + constructor create(aindex: integer; aparenteditor: tarraypropertyeditor; + aeditorclass: propertyeditorclassty; + const adesigner: idesigner; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypinfo: ptypeinfo); override; + end; +{ + tsetarrayelementpropertyeditor = class(tsetpropertyeditor) + public + function subproperties: propertyeditorarty; override; + end; +} + tsetarraypropertyeditor = class(tarraypropertyeditor) + protected + function getelementeditorclass: elementeditorclassty; override; + function geteditorclass: propertyeditorclassty; override; + end; + + tcolorarraypropertyeditor = class(tarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + function getitemtypeinfo: ptypeinfo; override; + end; + + tstringarraypropertyeditor = class(tarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + tmsestringarraypropertyeditor = class(tarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + trealarraypropertyeditor = class(tarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + trecordpropertyeditor = class(tpropertyeditor) + private + fsubproperties: propertyeditorarty; +// fname: string; + protected + function getdefaultstate: propertystatesty; override; + procedure setsubprop; override; + public + constructor create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; const aname: string; + const subprops: propertyeditorarty); reintroduce; + destructor destroy; override; + function allequal: boolean; override; +// function name: msestring; override; + function subproperties: propertyeditorarty; override; + function getvalue: msestring; override; + end; + + propertyeditorinfoty = record + propertytype: ptypeinfo; + propertyownerclass: tclass; + propertyname: string; + editorclass: propertyeditorclassty; + editorclasslevel: integer; + end; + ppropertyeditorinfoty = ^propertyeditorinfoty; + + tpropertyeditors = class(tdynamicdatalist) + private + function getitems(const index: integer): ppropertyeditorinfoty; + protected + procedure freedata(var data); override; + procedure beforecopy(var data); override; + procedure add(apropertytype: ptypeinfo; + apropertyownerclass: tclass; const apropertyname: string; + aeditorclass: propertyeditorclassty); + public + constructor create; override; + function geteditorclass(apropertytype: ptypeinfo; + apropertyownerclass: tclass; apropertyname: string): propertyeditorclassty; + property items[const index: integer]: ppropertyeditorinfoty read getitems; default; + end; + +var + fontaliasnames: msestringarty; + +function textpropertyfont: tfont; +function propertyeditors: tpropertyeditors; +procedure registerpropertyeditor(propertytype: ptypeinfo; + propertyownerclass: tclass; const propertyname: string; + editorclass: propertyeditorclassty); +function imagefilepropedit(out afilename: filenamety; + out aformat: string): modalresultty; +function getcomponentpropname(const acomp: tcomponent): msestring; +function wantpropertydelete(const fromval,toval: int32): boolean; + +implementation +uses + mseformatstr,msebits,msearrayprops,msebitmap, + msefiledialog,mseimagelisteditor,msereal,msewidgets, + mseactions,msehash,msegraphutils, + msestringlisteditor,msedoublestringlisteditor,msestringintlisteditor, + msereallisteditor,msedoublereallisteditor,msecomptree, + mseintegerlisteditor,mseact,msesys, + msecolordialog,msememodialog, + mseshapes,msestockobjects,msetexteditor,mserichstringeditor, + msegraphicstream,msedate, + mseformatbmpicoread{$ifdef FPC},mseformatjpgread,mseformatpngread, + mseformatpnmread,mseformattgaread,mseformatxpmread,mseformattiffread{$endif}, + msestat,msestatfile,msefileutils, + msedesigner,variants,mseeditglob,msepropertyeditorsmodule,objectinspector; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + methodsortlevel = 100; + falsename = 'False'; + truename = 'True'; + +type + tmsecomponent1 = class(tmsecomponent); + twidget1 = class(twidget); + tcustomcaptionframe1 = class(tcustomcaptionframe); + tdesigner1 = class(tdesigner); + tdatalist1 = class(tdatalist); + +var + fpropertyeditors: tpropertyeditors; + ftextpropertyfont: tfont; + mo: tmsepropertyeditorsmo; + +function wantpropertydelete(const fromval,toval: int32): boolean; +begin + result:= (toval < fromval) or + askok(mo.c[ord(wishdelete)]+' '+inttostrmse(fromval) + + ' '+mo.c[ord(str_to)]+' '+ inttostrmse(toval) + '?', + stockobjects.captions[sc_confirmation]); +end; + +function getcomponentpropname(const acomp: tcomponent): msestring; +begin + if acomp = nil then begin + result:= '' + end + else begin + result:= msestring(designer.getcomponentname(acomp)); + end; + if result = '' then begin + result:= msestring(ownernamepath(acomp)); + end; +end; + +function imagefilepropedit(out afilename: filenamety; + out aformat: string): modalresultty; +var + dialog: tfiledialog; + statfile1: tstatfile; +begin + statfile1:= tstatfile.create(nil); + dialog:= tfiledialog.create(nil); + dialog.name:= 'filedialog'; //for statvarname + try + aformat:= ''; + afilename:= ''; + statfile1.options:= [sfo_memory]; + statfile1.filename:= bmpfiledialogstatname; + with dialog,controller do begin + statfile1.options:= [sfo_memory]; + statfile1.filename:= bmpfiledialogstatname; + filterlist.asarraya:= graphicfilefilternames; + filterlist.asarrayb:= graphicfilefiltermasks; + captionopen:= mo.c[ord(openimagefile)];; + statfile:= statfile1; + statfile.readstat; + filename:= filedir(filename); + result:= execute; + if result = mr_ok then begin + aformat:= graphicfilefilterlabel(filterindex); + afilename:= filename; + statfile.writestat; + end; + end; + finally + dialog.free; + statfile1.free; + end; +end; + +procedure checkdatalistnostreaming(const sender: tpropertyeditor; + var defaultstate: propertystatesty); +var + datalist1: tdatalist1; +begin + datalist1:= tdatalist1(sender.getpointervalue); + if (datalist1 = nil) {or + (ilo_nostreaming in datalist1.finternaloptions)} then begin + exclude(defaultstate,ps_dialog); + end; +end; + +function textpropertyfont: tfont; +begin + if ftextpropertyfont = nil then begin + ftextpropertyfont:= tfont.create; + end; + result:= ftextpropertyfont; +end; + +function getpointerprop1(instance: tobject; propinfo : ppropinfo): pointer; +begin +{$ifdef CPU64} + result:= pointer(ptruint(getint64prop(instance,propinfo))); +{$else} + result:= pointer(ptruint(getordprop(instance,propinfo))); +{$endif} +end; + +function propertyeditors: tpropertyeditors; +begin + if fpropertyeditors = nil then begin + fpropertyeditors:= tpropertyeditors.create; + end; + result:= fpropertyeditors; +end; + +procedure registerpropertyeditor(propertytype: ptypeinfo; + propertyownerclass: tclass; const propertyname: string; + editorclass: propertyeditorclassty); +begin + propertyeditors.add(propertytype,propertyownerclass,propertyname,editorclass); +end; + +function settostrings(const value: tintegerset; const typeinfo: ptypeinfo): msestringarty; +var + int1,int2: integer; +begin + setlength(result,32); + int2:= 0; + for int1:= 0 to 31 do begin + if longword(value) and bits[int1] <> 0 then begin + result[int2]:= msestring(getenumname(typeinfo,int1)); + inc(int2); + end; + end; + setlength(result,int2); +end; + +function stringstoset(const value: stringarty; const typeinfo: ptypeinfo): tintegerset; +var + ar1: array[0..31] of boolean; + int1,int2: integer; + typedata: ptypedata; + enumtype: ptypeinfo; +begin + fillchar(ar1,sizeof(ar1),0); + typedata:= gettypedata(typeinfo); + enumtype:= typedata^.comptype{$ifndef FPC}^{$endif}; + for int1:= 0 to high(value) do begin + int2:= getenumvalue(enumtype,value[int1]); + if (int2 < 0) then begin + raise exception.Create( + ansistring(mo.c[ord(invalidsetitem)])+': '''+value[int1]+''''); + end; + ar1[int2]:= true; + end; + result:= []; + for int1:= 0 to gettypedata(enumtype)^.MaxValue do begin + if ar1[int1] then begin + result:= tintegerset(longword(result) or bits[int1]); + end; + end; +end; + +{ tpropertyeditors } + +constructor tpropertyeditors.create; +begin + inherited; + fsize:= sizeof(propertyeditorinfoty); +end; + +procedure tpropertyeditors.add(apropertytype: ptypeinfo; + apropertyownerclass: tclass; const apropertyname: string; + aeditorclass: propertyeditorclassty); +var + info: propertyeditorinfoty; +// po1: ppropertyeditorinfoty; +// bo1: boolean; +// int1: integer; + class1: tclass; + +begin + with info do begin + propertytype:= apropertytype; + propertyownerclass:= apropertyownerclass; + propertyname:= uppercase(apropertyname); + editorclass:= aeditorclass; + class1:= aeditorclass; + editorclasslevel:= 0; + while (class1 <> tpropertyeditor) do begin + class1:= class1.ClassParent; + inc(editorclasslevel); + end; + end; + { + po1:= pointer(fdatapo); + bo1:= false; + for int1:= 0 to fcount - 1 do begin + with po1^ do begin + if (propertytype = info.propertytype) and (componentclass = info.componentclass) and + (propertyname = info.propertyname) then begin + editorclass:= info.editorclass; + bo1:= true; + break; + end; + end; + inc(po1); + end; + } + adddata(info); +end; + +procedure tpropertyeditors.freedata(var data); +begin + propertyeditorinfoty(data).propertyname:= ''; + inherited; +end; + +procedure tpropertyeditors.beforecopy(var data); +begin + stringaddref(propertyeditorinfoty(data).propertyname); +end; + +function tpropertyeditors.getitems( + const index: integer): ppropertyeditorinfoty; +begin + result:= ppropertyeditorinfoty(getitempo(index)); +end; + +function tpropertyeditors.geteditorclass(apropertytype: ptypeinfo; + apropertyownerclass: tclass; + apropertyname: string): propertyeditorclassty; + + //todo: optimize +var + int1: integer; + po1: ppropertyeditorinfoty; + kind: ttypekind; + class1: tclass; + po2: ptypeinfo; + int2: integer; + namelevel,propertyownerclasslevel,typeclasslevel,propertyeditorlevel: integer; + anamelevel,apropertyownerclasslevel,atypeclasslevel: integer; + + procedure savelevel; + begin + namelevel:= anamelevel; + propertyownerclasslevel:= apropertyownerclasslevel; + typeclasslevel:= atypeclasslevel; + propertyeditorlevel:= po1^.editorclasslevel; + result:= po1^.editorclass; + end; + +begin + apropertyname:= uppercase(apropertyname); + result:= tpropertyeditor; + po1:= ppropertyeditorinfoty(fdatapo); + kind:= apropertytype^.Kind; + namelevel:= 1; + propertyownerclasslevel:= bigint; + typeclasslevel:= bigint; + propertyeditorlevel:= 0; + + for int1:= 0 to count - 1 do begin + if kind = po1^.propertytype^.Kind then begin + if (po1^.propertyownerclass <> nil) then begin + class1:= apropertyownerclass; + int2:= 0; + while (class1 <> nil) and (class1 <> po1^.propertyownerclass) do begin + class1:= class1.ClassParent; + inc(int2) + end; + if class1 <> nil then begin + apropertyownerclasslevel:= int2; + end + else begin + apropertyownerclasslevel:= bigint + 1; + end; + end + else begin + apropertyownerclasslevel:= bigint - 1; + end; + + if po1^.propertyname = '' then begin + anamelevel:= 1; + end + else begin + if po1^.propertyname = apropertyname then begin + anamelevel:= 3; + end + else begin + anamelevel:= 0; + end; + end; + + if kind = tkclass then begin + {$ifdef FPC} + po2:= gettypedata(apropertytype)^.classtype.classinfo; + {$else} + po2:= apropertytype; + {$endif} + int2:= 0; + while (po2 <> nil) and (po2 <> po1^.propertytype) do begin + inc(int2); + {$ifdef FPC} + po2:= gettypedata(po2)^.parentinfo; + {$else} + po2:= ptypeinfo(gettypedata(po2)^.parentinfo); + if po2 <> nil then begin + po2:= pptypeinfo(po2)^; + end; + {$endif} + end; + if (po2 <> nil) then begin + atypeclasslevel:= int2 + end + else begin + atypeclasslevel:= bigint + 1; + end; + end + else begin + if (po1^.propertytype = apropertytype) {$ifdef FPC} + or (po1^.propertytype^.name = apropertytype^.name) {$endif} then begin + atypeclasslevel:= 0; + end + else begin + atypeclasslevel:= 1; + if (kind = tkset) and + (po1^.propertytype <> typeinfo(defaultsetty)) then begin + atypeclasslevel:= 2; + end; + if (kind = tkenumeration) and + (po1^.propertytype <> typeinfo(defaultenumerationty)) then begin + atypeclasslevel:= 2; + end; + end; + end; + + if kind = tkclass then begin + if (typeclasslevel > atypeclasslevel) and (anamelevel = 1) and + (apropertyownerclasslevel = bigint-1) then begin + savelevel; + end + else begin + if typeclasslevel >= atypeclasslevel then begin + if (propertyownerclasslevel > apropertyownerclasslevel) and + (anamelevel = 1) then begin + savelevel; + end + else begin + if propertyownerclasslevel >= apropertyownerclasslevel then begin + if namelevel < anamelevel then begin + savelevel; + end + else begin + if (namelevel = anamelevel) and + (propertyeditorlevel <= po1^.editorclasslevel) then begin + savelevel; + end; + end; + end; + end; + end; + end; + end + else begin + if typeclasslevel > atypeclasslevel then begin + savelevel; + end + else begin + if typeclasslevel >= atypeclasslevel then begin + //do not overwrite exact type match + if (propertyownerclasslevel > apropertyownerclasslevel) and + (anamelevel = 1) then begin + savelevel; + end + else begin + if propertyownerclasslevel >= apropertyownerclasslevel then begin + if namelevel < anamelevel then begin + savelevel; + end + else begin + if namelevel = anamelevel then begin + if (typeclasslevel = atypeclasslevel) and + (propertyeditorlevel <= po1^.editorclasslevel) then begin + savelevel; + end; + end; + end; + end; + end; + end; + end; + { + if (propertyownerclasslevel > apropertyownerclasslevel) and (anamelevel = 1) then begin + savelevel; + end + else begin + if propertyownerclasslevel >= apropertyownerclasslevel then begin + if namelevel < anamelevel then begin + savelevel; + end + else begin + if namelevel = anamelevel then begin + if typeclasslevel > atypeclasslevel then begin + savelevel; + end + else begin + if (typeclasslevel = atypeclasslevel) and + (propertyeditorlevel <= po1^.editorclasslevel) then begin + savelevel; + end; + end; + end; + end; + end; + end; + } + end; + end; + inc(po1); + end; +end; + +{ tpropertyeditor } + +constructor tpropertyeditor.create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypeinfo: ptypeinfo); +begin + fmodule:= amodule; + fcomponent:= acomponent; + fdesigner:= adesigner; + ftypeinfo:= atypeinfo; + fobjectinspector:= aobjectinspector; + if aprops <> nil then begin + fprops:= copy(aprops); //!!!! crash whithout copy, why ? +// reallocarray(fprops,sizeof(props[0])); + fname:= msestring(fprops[0].propinfo^.Name); + end; + fstate:= getdefaultstate; + updatedefaultvalue; +end; + +destructor tpropertyeditor.destroy; +begin + pointer(fdesigner):= nil; + pointer(fobjectinspector):= nil; + pointer(fremote):= nil; +end; + +procedure tpropertyeditor.setremote(intf: iremotepropertyeditor); +begin + fremote:= intf; + if fremote <> nil then begin + fparenteditor:= fremote.getparenteditor; + if (fparenteditor <> nil) and (ps_subprop in fparenteditor.fstate) then begin + include(fstate,ps_subprop); + end; + end; +end; + +function tpropertyeditor.canrevert: boolean; +begin + result:= (ftypeinfo <> nil) and (fremote = nil) and + (csancestor in component.componentstate) and (fprops[0].instance = component); +end; + +procedure tpropertyeditor.copyproperty(const asource: tobject); +begin + case ftypeinfo^.kind of + tkInteger,tkChar,tkEnumeration,tkSet,tkWChar, + {$ifdef FPC}tkBool,{$endif}tkClass: begin + setordvalue(getordprop(asource,fprops[0].propinfo)); + end; + tkFloat: begin + setfloatvalue(getfloatprop(asource,fprops[0].propinfo)); + end; + tkMethod: begin + setmethodvalue(getmethodprop(asource,fprops[0].propinfo)); + end; + {$ifdef FPC}tkSString,tkAString,{$endif}tkLString: begin + setstringvalue(getstrprop(asource,fprops[0].propinfo)); + end; + msestringtypekind: begin + setmsestringvalue(getmsestringprop(asource,fprops[0].propinfo)); + end; +// {$ifdef mse_unicodestring} +// tkUString: begin +// setmsestringvalue(getunicodestrprop(asource,fprops[0].propinfo)); +// end; +// {$endif} + tkInt64{$ifdef FPC},tkQWord{$endif}: begin + setint64value(getint64prop(asource,fprops[0].propinfo)); + end; + end; +end; + +function tpropertyeditor.getvalue: msestring; +begin + result:= mo.c[ord(unknown)]; +end; + +procedure tpropertyeditor.setvalue(const value: msestring); +begin + //dummy +end; + +function tpropertyeditor.name: msestring; +begin + result:= fname; +end; + +function tpropertyeditor.allequal: boolean; +begin + result:= high(fprops) = 0; +end; + +function tpropertyeditor.props: propinstancearty; +begin + result:= fprops; +end; + +function tpropertyeditor.rootprops: propinstancearty; +var + ed1: tpropertyeditor; +begin + result:= nil; + ed1:= getparenteditor; + if ed1 <> nil then begin + result:= ed1.rootprops; + end; + if result = nil then begin + result:= fprops; + end; +end; + +function tpropertyeditor.propowner: componentarty; +var + ed1: tpropertyeditor; + int1: integer; +begin + result:= nil; + ed1:= getparenteditor; + while ed1 <> nil do begin + if (ed1 is tcomponentpropertyeditor) and not + tcomponentpropertyeditor(ed1).issubcomponent then begin + setlength(result,count); + for int1:= 0 to high(result) do begin + result[int1]:= tcomponent(ed1.getpointervalue); + end; + break; + end; + ed1:= ed1.getparenteditor; + end; +end; + +function tpropertyeditor.instance(const index: integer = 0): tobject; +begin + result:= fprops[index].instance; +end; + +function tpropertyeditor.typedata: ptypedata; +begin + result:= gettypedata(ftypeinfo); +end; + +function tpropertyeditor.queryselectedpropinstances: objectarty; +var + editor1: tpropertyeditor; +begin + result:= nil; + editor1:= fparenteditor; + while editor1 <> nil do begin + if (editor1.fremote <> nil) and (editor1.fremote.selected) then begin + result:= editor1.fremote.getselectedpropinstances; + break; + end; + if editor1 is tclasspropertyeditor then begin + break; + end; + editor1:= editor1.fparenteditor; + end; + if result <> nil then begin + include(fstate,ps_refreshall); + end; +end; + +function tpropertyeditor.getordvalue(const index: integer): integer; + +begin + if fremote <> nil then begin + result:= fremote.getordvalue(index); + end + else begin + with fprops[index] do begin + result:= GetOrdProp(instance,propinfo); + end; + end; +end; + +procedure tpropertyeditor.setordvalue(const value: longword); +var + int1: integer; + ar1: objectarty; +begin + if fremote <> nil then begin + fremote.setordvalue(value); + end + else begin + ar1:= queryselectedpropinstances; + if ar1 = nil then begin + for int1:= 0 to high(fprops) do begin + with fprops[int1] do begin + setordprop(instance, propinfo, value); + end; + end; + end + else begin + for int1:= 0 to high(ar1) do begin + setordprop(ar1[int1],fprops[0].propinfo,value); + end; + end; + updatedefaultvalue; + modified; + end; +end; + +procedure tpropertyeditor.setordvalue(const index: integer; const value: longword); +begin + if fremote <> nil then begin + fremote.setordvalue(index,value); + end + else begin + with fprops[index] do begin + setordprop(instance, propinfo, value); + end; + updatedefaultvalue; + modified; + end; +end; + +function tpropertyeditor.getint64value(const index: integer): int64; + +begin + if fremote <> nil then begin + result:= fremote.getint64value(index); + end + else begin + with fprops[index] do begin + result:= getint64prop(instance,propinfo); + end; + end; +end; + +procedure tpropertyeditor.setint64value(const value: int64); +var + int1: integer; + ar1: objectarty; +begin + if fremote <> nil then begin + fremote.setint64value(value); + end + else begin + ar1:= queryselectedpropinstances; + if ar1 = nil then begin + for int1:= 0 to high(fprops) do begin + with fprops[int1] do begin + setint64prop(instance, propinfo, value); + end; + end; + end + else begin + for int1:= 0 to high(ar1) do begin + setint64prop(ar1[int1],fprops[0].propinfo,value); + end; + end; + updatedefaultvalue; + modified; + end; +end; + +procedure tpropertyeditor.setint64value(const index: integer; const value: int64); +begin + if fremote <> nil then begin + fremote.setint64value(index,value); + end + else begin + with fprops[index] do begin + setint64prop(instance, propinfo, value); + end; + updatedefaultvalue; + modified; + end; +end; + +function tpropertyeditor.getpointervalue(const index: integer): pointer; + +begin + if fremote <> nil then begin + result:= fremote.getpointervalue(index); + end + else begin + with fprops[index] do begin +{$ifdef CPU64} + result:= pointer(ptruint(Getint64Prop(instance,propinfo))); +{$else} + result:= pointer(ptruint(GetOrdProp(instance,propinfo))); +{$endif} + end; + end; +end; + +procedure tpropertyeditor.setpointervalue(const value: pointer); +var + int1: integer; + ar1: objectarty; +begin + if fremote <> nil then begin + fremote.setpointervalue(value); + end + else begin + ar1:= queryselectedpropinstances; + if ar1 = nil then begin + for int1:= 0 to high(fprops) do begin + with fprops[int1] do begin +{$ifdef CPU64} + setint64prop(instance, propinfo, ptrint(value)); +{$else} + setordprop(instance, propinfo, ptrint(value)); +{$endif} + end; + end; + end + else begin + for int1:= 0 to high(ar1) do begin +{$ifdef CPU64} + setint64prop(ar1[int1],fprops[0].propinfo,ptrint(value)); +{$else} + setordprop(ar1[int1],fprops[0].propinfo,ptrint(value)); +{$endif} + end; + end; + updatedefaultvalue; + modified; + end; +end; + +procedure tpropertyeditor.setpointervalue(const index: integer; const value: pointer); +begin + if fremote <> nil then begin + fremote.setpointervalue(index,value); + end + else begin + with fprops[index] do begin +{$ifdef CPU64} + setint64prop(instance, propinfo, ptrint(value)); +{$else} + setordprop(instance, propinfo, ptrint(value)); +{$endif} + end; + updatedefaultvalue; + modified; + end; +end; + +procedure tpropertyeditor.setbitvalue(const value: boolean; const bitindex: integer); +var + int1: integer; + wo1: longword; + ar1: objectarty; +begin + if fremote <> nil then begin + fremote.setbitvalue(value,bitindex); + end + else begin + ar1:= queryselectedpropinstances; + if ar1 = nil then begin + for int1:= 0 to high(fprops) do begin + with fprops[int1] do begin + wo1:= getordprop(instance,propinfo); + updatebit(wo1,bitindex,value); + setordprop(instance,propinfo,wo1); + end; + end; + end + else begin + for int1:= 0 to high(ar1) do begin + wo1:= getordprop(ar1[int1],fprops[0].propinfo); + updatebit(wo1,bitindex,value); + setordprop(ar1[int1],fprops[0].propinfo,wo1); + end; + end; + fparenteditor.updatedefaultvalue; + updatedefaultvalue; + modified; + end; +end; + +function tpropertyeditor.getfloatvalue(const index: integer): extended; +begin + if fremote <> nil then begin + result:= fremote.getfloatvalue(index); + end + else begin + with fprops[index] do begin + result:= GetfloatProp(instance,propinfo); + end; + end; +end; + +procedure tpropertyeditor.setfloatvalue(const value: extended); +var + int1: integer; + ar1: objectarty; +begin + if fremote <> nil then begin + fremote.setfloatvalue(value); + end + else begin + ar1:= queryselectedpropinstances; + if ar1 = nil then begin + for int1:= 0 to high(fprops) do begin + with fprops[int1] do begin + SetfloatProp(Instance, PropInfo, Value); + end; + end; + end + else begin + for int1:= 0 to high(ar1) do begin + setfloatprop(ar1[int1],fprops[0].propinfo,value); + end; + end; + modified; + end; +end; + +function tpropertyeditor.getcurrencyvalue(const index: integer = 0): currency; +begin + if fremote <> nil then begin + result:= fremote.getcurrencyvalue(index); + end + else begin + with fprops[index] do begin + result:= getfloatprop(instance,propinfo); + end; + end; +end; + +procedure tpropertyeditor.setcurrencyvalue(const value: currency); +var + int1: integer; + ar1: objectarty; +begin + if fremote <> nil then begin + fremote.setcurrencyvalue(value); + end + else begin + ar1:= queryselectedpropinstances; + if ar1 = nil then begin + for int1:= 0 to high(fprops) do begin + with fprops[int1] do begin + setfloatprop(instance, propinfo, value); + end; + end; + end + else begin + for int1:= 0 to high(ar1) do begin + setfloatprop(ar1[int1],fprops[0].propinfo,value); + end; + end; + modified; + end; +end; + +function tpropertyeditor.getstringvalue(const index: integer): string; +begin + if fremote <> nil then begin + result:= fremote.getstringvalue(index); + end + else begin + with fprops[index] do begin + result:= ansistring(decodemsestring( + msestring(GetstrProp(instance,propinfo)))); + end; + end; +end; + +procedure tpropertyeditor.setstringvalue(const value: string); +var + int1: integer; + str1: string; + ar1: objectarty; +begin + if fremote <> nil then begin + fremote.setstringvalue(value); + end + else begin + str1:= ansistring(encodemsestring(msestring(value))); + ar1:= queryselectedpropinstances; + if ar1 = nil then begin + for int1:= 0 to high(fprops) do begin + with fprops[int1] do begin + SetstrProp(Instance, PropInfo, str1); + end; + end; + end + else begin + for int1:= 0 to high(ar1) do begin + SetstrProp(ar1[int1], fprops[0].propinfo, str1); + end; + end; + modified; + end; +end; + +function tpropertyeditor.getutf8stringvalue( + const index: integer = 0): utf8string; +begin + if fremote <> nil then begin + result:= fremote.getutf8stringvalue(index); + end + else begin + with fprops[index] do begin + result:= stringtoutf8(decodemsestring( + msestring(GetstrProp(instance,propinfo)))); + end; + end; +end; + +procedure tpropertyeditor.setutf8stringvalue(const value: utf8string); +var + int1: integer; + str1: utf8string; + ar1: objectarty; +begin + if fremote <> nil then begin + fremote.setutf8stringvalue(value); + end + else begin + str1:= stringtoutf8(encodemsestring(msestring(value))); + ar1:= queryselectedpropinstances; + if ar1 = nil then begin + for int1:= 0 to high(fprops) do begin + with fprops[int1] do begin + SetstrProp(Instance, PropInfo, str1); + end; + end; + end + else begin + for int1:= 0 to high(ar1) do begin + SetstrProp(ar1[int1], fprops[0].propinfo, str1); + end; + end; + modified; + end; +end; + +function tpropertyeditor.decodemsestring(const avalue: msestring): msestring; +var + int1: integer; + po1: pmsechar; + mstr1: msestring; +begin + setlength(result,length(avalue) * 10); //max size + if length(avalue) > 0 then begin + po1:= pointer(result); + for int1:= 1 to length(avalue) do begin + case avalue[int1] of + c_tab: begin po1^:= numcharchar; inc(po1); po1^:= 't'; end; + c_linefeed: begin po1^:= numcharchar; inc(po1); po1^:= 'n'; end; + c_return: begin po1^:= numcharchar; inc(po1); po1^:= 'r'; end; + c_softhyphen: begin po1^:= numcharchar; inc(po1); po1^:= 's'; end; + numcharchar: begin po1^:= numcharchar; inc(po1); po1^:= numcharchar; end; + else begin + if avalue[int1] < widechar(32) then begin + mstr1:= numcharchar+inttostrmse(ord(avalue[int1])); + if (avalue[int1+1] >= '0') and (avalue[int1+1] <= '9') or + (avalue[int1+1] = ' ') then begin + mstr1:= mstr1 + ' '; + end; + move(mstr1[1],po1^,length(mstr1)*sizeof(widechar)); + inc(po1,length(mstr1)-1); + end + else begin + po1^:= avalue[int1]; + end; + end; + end; + inc(po1) + end; + setlength(result,po1-pmsechar(pointer(result))); + end; +end; + +function tpropertyeditor.encodemsestring(const avalue: msestring): msestring; +var + int1: integer; + po1: pmsechar; + int2: integer; +begin + setlength(result,length(avalue)); //max + if length(result) > 0 then begin + po1:= pointer(result); + int1:= 1; + while int1 <= length(avalue) do begin + if (avalue[int1] = numcharchar) and (int1 < length(avalue)+1) then begin + case avalue[int1+1] of + numcharchar: po1^:= numcharchar; + 't': po1^:= c_tab; + 'n': po1^:= c_linefeed; + 'r': po1^:= c_return; + 's': po1^:= c_softhyphen; + '0'..'9': begin + int2:= int1+2; + while (avalue[int2] >= '0') and (avalue[int2] <= '9') do begin + inc(int2); + end; + po1^:= widechar(strtoint(copy(avalue,int1+1,int2-int1-1))); + if avalue[int2] = ' ' then begin + inc(int2); + end; + int1:= int2-2; + end; + else begin po1^:= numcharchar; dec(int1); end; + end; + inc(int1,2); + end + else begin + po1^:= avalue[int1]; + inc(int1); + end; + inc(po1); + end; + setlength(result,po1 - pmsechar(pointer(result))); + end; +end; + +function tpropertyeditor.getmsestringvalue( + const index: integer = 0; const raw: boolean = false): msestring; + +begin + if fremote <> nil then begin + result:= fremote.getmsestringvalue(index,raw); + end + else begin + with fprops[index] do begin + if raw then begin + result:= getmsestringprop(instance,propinfo); + end + else begin + result:= decodemsestring(getmsestringprop(instance,propinfo)); + end; +// {$ifdef mse_unicodestring} +// result:= decodemsestring(GetunicodestrProp(instance,propinfo)); +// {$else} +// result:= decodemsestring(GetwidestrProp(instance,propinfo)); +// {$endif} + end; + end; +end; + +procedure tpropertyeditor.setmsestringvalue(const value: msestring; + const raw: boolean=false); +var + mstr1: msestring; + int1: integer; + ar1: objectarty; +begin + if fremote <> nil then begin + fremote.setmsestringvalue(value); + end + else begin + if raw then begin + mstr1:= value; + end + else begin + mstr1:= encodemsestring(value); + end; + ar1:= queryselectedpropinstances; + if ar1 = nil then begin + for int1:= 0 to high(fprops) do begin + with fprops[int1] do begin + setmsestringprop(instance,propinfo,mstr1); +// {$ifdef mse_unicodestring} +// setunicodestrprop(instance,propinfo,mstr1); +// {$else} +// setwidestrprop(instance,propinfo,mstr1); +// {$endif} + end; + end; + end + else begin + for int1:= 0 to high(ar1) do begin + setmsestringprop(ar1[int1],fprops[0].propinfo,mstr1); +// {$ifdef mse_unicodestring} +// setunicodestrprop(ar1[int1],fprops[0].propinfo,mstr1); +// {$else} +// setwidestrprop(ar1[int1],fprops[0].propinfo,mstr1); +// {$endif} + end; + end; + modified; + end; +end; + +function tpropertyeditor.getvariantvalue(const index: integer = 0): variant; +begin + if fremote <> nil then begin + result:= fremote.getvariantvalue(index); + end + else begin + with fprops[index] do begin + result:= getvariantprop(instance,propinfo); + end; + end; +end; + +procedure tpropertyeditor.setvariantvalue(const value: variant); +var + int1: integer; + ar1: objectarty; +begin + if fremote <> nil then begin + fremote.setvariantvalue(value); + end + else begin + ar1:= queryselectedpropinstances; + if ar1 = nil then begin + for int1:= 0 to high(fprops) do begin + with fprops[int1] do begin + setvariantprop(instance,propinfo,value); + end; + end; + end + else begin + for int1:= 0 to high(ar1) do begin + setvariantprop(ar1[int1],fprops[0].propinfo,value); + end; + end; + modified; + end; +end; + +function tpropertyeditor.getmethodvalue(const index: integer): tmethod; +begin + if fremote <> nil then begin + result:= fremote.getmethodvalue(index); + end + else begin + with fprops[index] do begin + result:= GetmethodProp(instance,propinfo); + end; + end; +end; + +procedure tpropertyeditor.setmethodvalue(const value: tmethod); +var + int1: integer; + ar1: objectarty; +begin + if fremote <> nil then begin + fremote.setmethodvalue(value); + end + else begin + ar1:= queryselectedpropinstances; + if ar1 = nil then begin + for int1:= 0 to high(fprops) do begin + with fprops[int1] do begin + SetmethodProp(Instance, PropInfo, Value); + end; + end; + end + else begin + for int1:= 0 to high(ar1) do begin + setmethodprop(ar1[int1],fprops[0].propinfo,value); + end; + end; + modified; + end; +end; + +function tpropertyeditor.getparenteditor: tpropertyeditor; +begin + if fremote <> nil then begin + result:= fremote.getparenteditor; + end + else begin + result:= fparenteditor; + end; +end; + +function tpropertyeditor.sortlevel: integer; +begin + result:= fsortlevel; +end; + +function tpropertyeditor.getexpanded: boolean; +begin + result:= ps_expanded in fstate; +end; + +function tpropertyeditor.getcount: integer; +begin + result:= length(fprops); +end; + +procedure tpropertyeditor.setexpanded(const Value: boolean); +begin + if value then begin + include(fstate,ps_expanded); + end + else begin + exclude(fstate,ps_expanded); + end; +end; + +procedure tpropertyeditor.modified; +begin + fobjectinspector.propertymodified(self); + exclude(fstate,ps_refreshall); +end; + +function tpropertyeditor.subproperties: propertyeditorarty; +begin + result:= nil; +end; + +procedure tpropertyeditor.edit; +begin + //dummy +end; + +procedure tpropertyeditor.focused(); +begin + //dummy +end; + +function tpropertyeditor.getvalues: msestringarty; +begin + result:= nil; +end; + +procedure tpropertyeditor.properror; +begin + raise exception.Create(ansistring(mo.c[ord(wrongpropertyvalue)])); +end; + +function tpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= []; + if (fparenteditor <> nil) and (ps_subprop in fparenteditor.fstate) then begin + include(result,ps_subprop); + end; +end; + +procedure tpropertyeditor.dragbegin(var accept: boolean); +begin + //dummy +end; + +procedure tpropertyeditor.dragover(const sender: tpropertyeditor; var accept: boolean); +begin + //dummy +end; + +procedure tpropertyeditor.dragdrop(const sender: tpropertyeditor); +begin + //dummy +end; + +procedure tpropertyeditor.dopopup(var amenu: tpopupmenu; + const atransientfor: twidget; var mouseinfo: mouseeventinfoty); +begin + //dummy +end; + +procedure tpropertyeditor.dokeydown(var ainfo: keyeventinfoty); +begin + //dummy +end; + +procedure tpropertyeditor.updatedefaultvalue; +begin + if (fstate * [ps_isordprop,ps_candefault] = [ps_isordprop,ps_candefault]) and + (getordvalue <> fprops[0].propinfo^.default) then begin + include(fstate,ps_modified); + end + else begin + exclude(fstate,ps_modified); + end; +end; + +function tpropertyeditor.propertyname: msestring; +begin + result:= fname; +end; + +function tpropertyeditor.getselected: boolean; +begin + result:= ps_selected in fstate; +end; + +procedure tpropertyeditor.setselected(const avalue: boolean); +begin + if avalue and (ps_canselect in fstate) then begin + include(fstate,ps_selected); + end + else begin + exclude(fstate,ps_selected); + end; +end; + +procedure tpropertyeditor.setsubprop; +begin + include(fstate,ps_subprop); +end; + +function tpropertyeditor.getvalueeditor: tpropertyeditor; +begin + result:= self; +end; + +function tpropertyeditor.getlinksource: tcomponent; +begin + result:= nil; +end; + +function tpropertyeditor.getlinkcomponent: tcomponent; +begin + result:= linksource; + while (result <> nil) and (cssubcomponent in result.componentstyle) do begin + result:= result.owner; + end; +end; + +function tpropertyeditor.gettypinfo(): ptypeinfo; +begin + result:= ftypeinfo; +end; + +procedure tpropertyeditor.navigevent(); +begin + //dummy +end; + +{ tordinalpropertyeditor } + +function tordinalpropertyeditor.allequal: boolean; +var + int1: integer; + int2: integer; +begin + result:= inherited allequal; + if not result then begin + result:= true; + int2:= getordvalue; + for int1:= 1 to high(fprops) do begin + if int2 <> getordvalue(int1) then begin + result:= false; + break; + end; + end; + end; +end; + +function tordinalpropertyeditor.getvalue: msestring; +begin + result:= inttostrmse(getordvalue); +end; + +procedure tordinalpropertyeditor.setvalue(const value: msestring); +begin + setordvalue(strtointvalue(ansistring(value))); +end; + +function tordinalpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_isordprop,ps_candefault]; +end; + +{ tvolatileintegerpropertyeditor } + +function tvolatileordinalpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_volatile]; +end; + +{ tint64propertyeditor } + +function tint64propertyeditor.allequal: boolean; +var + int1: integer; + int2: int64; +begin + result:= inherited allequal; + if not result then begin + result:= true; + int2:= getint64value; + for int1:= 1 to high(fprops) do begin + if int2 <> getint64value(int1) then begin + result:= false; + break; + end; + end; + end; +end; + +function tint64propertyeditor.getvalue: msestring; +begin + result:= inttostrmse(getint64value); +end; + +procedure tint64propertyeditor.setvalue(const value: msestring); +begin + setint64value(strtointvalue64(ansistring(value))); +end; + +function tint64propertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_isordprop,ps_candefault]; +end; + +{ tcharpropertyeditor } + +procedure tcharpropertyeditor.setvalue(const value: msestring); +var + str1: string; +begin + str1:= ansistring(encodemsestring(value)); + if str1 = '' then begin + setordvalue(0); + end + else begin + setordvalue(ord(str1[1])); + end; +end; + +function tcharpropertyeditor.getvalue: msestring; +var + int1: integer; +begin + int1:= getordvalue; + if int1 = 0 then begin + result:= ''; + end + else begin + result:= decodemsestring(msechar(char(int1))); + end; +end; + +{ twidecharpropertyeditor } + +procedure twidecharpropertyeditor.setvalue(const value: msestring); +var + str1: msestring; +begin + str1:= encodemsestring(value); + if str1 = '' then begin + setordvalue(0); + end + else begin + setordvalue(ord(str1[1])); + end; +end; + +function twidecharpropertyeditor.getvalue: msestring; +var + int1: integer; +begin + int1:= getordvalue; + if int1 = 0 then begin + result:= ''; + end + else begin + result:= decodemsestring(widechar(int1)); + end; +end; + +{ tmethodpropertyeditor } + +constructor tmethodpropertyeditor.create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; const aprops: propinstancearty; + atypinfo: ptypeinfo); +begin + inherited; + fsortlevel:= methodsortlevel; +end; + +function tmethodpropertyeditor.allequal: boolean; +var + int1: integer; + method1,method2: tmethod; +begin + result:= inherited allequal; + if not result then begin + result:= true; + method1:= getmethodvalue; + for int1:= 1 to high(fprops) do begin + method2:= getmethodvalue(int1); + if (method1.code <> method2.code) or (method1.data <> method2.data) then begin + result:= false; + break; + end; + end; + end; +end; + +function tmethodpropertyeditor.getvalue: msestring; +var + method1: tmethod; +begin + method1:= getmethodvalue; + if method1.data <> nil then begin + result:= msestring(fdesigner.getmethodname(method1,fcomponent)); + end + else begin + result:= ''; + end; +end; + +function tmethodpropertyeditor.method: tmethod; +begin + result:= getmethodvalue; +end; + +procedure tmethodpropertyeditor.setvalue(const value: msestring); + + function isselected: boolean; + var + ar1: msestringarty; + int1: integer; + begin + ar1:= getvalues; + result:= false; + for int1:= 0 to high(ar1) do begin + if value = ar1[int1] then begin + result:= true; + break; + end; + end; + end; + +var + method1,method2: tmethod; +begin + method2:= getmethodvalue; + if value = '' then begin + method1.code:= nil; + method1.data:= nil; + setmethodvalue(method1); + end + else begin + if not isvalidident(ansistring(value)) then begin + raise exception.create(ansistring( + mo.c[ord(invalidmethodname)]+' '''+value+'''.')); + end; + method1:= fdesigner.getmethod(ansistring(value),fmodule, + fprops[0].propinfo^.proptype{$ifndef FPC}^{$endif},true); + if method1.data = nil then begin //method not found + if (method2.data <> nil) and not isselected and + fdesigner.isownedmethod(fmodule,method2)then begin + fdesigner.changemethodname(method2,ansistring(value), + fprops[0].propinfo^.proptype{$ifndef FPC}^{$endif}); + method1:= method2; + end + else begin + if method1.data <> nil then begin + raise exception.create(ansistring(mo.c[ord(str_methodname)]+' '''+value+''' '+ + mo.c[ord(exists)])); + end; + method1:= fdesigner.createmethod(ansistring(value),fmodule, + fprops[0].propinfo^.proptype{$ifndef FPC}^{$endif}); + end; + end + else begin + fdesigner.checkmethod(method1,ansistring(value),fmodule, + fprops[0].propinfo^.proptype{$ifndef FPC}^{$endif}); + end; + setmethodvalue(method1); + end; +// modified; +end; + +function tmethodpropertyeditor.getvalues: msestringarty; +begin + result:= fobjectinspector.getmatchingmethods(self, + fprops[0].propinfo^.proptype{$ifndef FPC}^{$endif}); +end; + +function tmethodpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= [ps_valuelist,ps_sortlist]; +end; + +procedure tmethodpropertyeditor.navigevent; +begin + objectinspectorfo.showmethodsource(self); +end; + +{ tsetpropertyeditor } + +constructor tsetpropertyeditor.create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypeinfo: ptypeinfo); +begin + finvisibleitems:= getinvisibleitems; + if felementeditorclass = nil then begin + felementeditorclass:= tsetelementeditor; + end; + inherited; +end; + +function tsetpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_subproperties,ps_refresh]; +end; + +function tsetpropertyeditor.getvalue: msestring; +begin + {$ifdef FPC} + result:= '['+concatstrings(settostrings(tintegerset(longword(getordvalue)), + typedata^.comptype),',')+']'; + {$else} + result:= '['+concatstrings(settostrings(tintegerset(longword(getordvalue)), + typedata^.comptype^),',')+']'; + {$endif} +(* +{$ifdef FPC} + result:= '['+concatstrings(settostrings(tintegerset(longword(getordvalue)), + gettypedata(fprops[0].propinfo^.proptype)^.comptype),',')+']'; +{$else} + result:= '['+concatstrings(settostrings(tintegerset(longword(getordvalue)), + gettypedata(fprops[0].propinfo^.proptype^)^.comptype^),',')+']'; +{$endif} +*) +end; + +procedure tsetpropertyeditor.setvalue(const value: msestring); +var + str1: string; + ar1: stringarty; +begin + str1:= trim(ansistring(value)); + if (length(str1) > 0) and (str1[1] = '[') then begin + str1:= copy(str1,2,bigint); + end; + if (length(str1) > 0) and (str1[length(str1)] = ']') then begin + setlength(str1,length(str1)-1); + end; + ar1:= nil; + splitstring(str1,ar1,',',true); + setordvalue(longword(stringstoset(ar1,ftypeinfo))); +end; + +function tsetpropertyeditor.subproperties: propertyeditorarty; +var + compty: ptypeinfo; + int1: integer; + int2: integer; +begin + compty:= gettypedata(ftypeinfo)^.comptype{$ifndef FPC}^{$endif}; + setlength(result,gettypedata(compty)^.MaxValue+1); + int2:= 0; + for int1:= 0 to high(result) do begin + if not (int1 in finvisibleitems) then begin + result[int2]:= felementeditorclass.create(fdesigner,fmodule,fcomponent, + fobjectinspector,fprops,compty,self,int1); + inc(int2); + end; + end; + setlength(result,int2); +end; + +function tsetpropertyeditor.getinvisibleitems: tintegerset; +begin + result:= []; +end; + +{ tsetelementeditor } + +constructor tsetelementeditor.create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypeinfo: ptypeinfo; + const aparent: tsetpropertyeditor; const aindex: integer); +begin + findex:= aindex; + fparenteditor:= aparent; + inherited create(adesigner,amodule,acomponent,aobjectinspector,aprops,atypeinfo); + fremote:= aparent.fremote; +end; + +function tsetelementeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_valuelist,ps_candefault,ps_refresh]; + if (fparenteditor <> nil) and (ps_volatile in fparenteditor.fstate) then begin + include(result,ps_volatile); + end; +end; + +function tsetelementeditor.getvalue: msestring; +begin + if findex in tintegerset(longword(getordvalue)) then begin + result:= truename; + end + else begin + result:= falsename; + end; +end; + +function tsetelementeditor.allequal: boolean; +var + int1: integer; + bo1: boolean; +begin + result:= inherited allequal; + if not result then begin + result:= true; + bo1:= findex in tintegerset(longword(getordvalue)); + for int1:= 1 to high(fprops) do begin + if bo1 <> (findex in tintegerset(longword(getordvalue(int1)))) then begin + result:= false; + break; + end; + end; + end; +end; + +function tsetelementeditor.getvalues: msestringarty; +begin + setlength(result,2); + result[0]:= falsename; + result[1]:= truename; +end; + +function tsetelementeditor.name: msestring; +begin +{$ifdef FPC} +// result:= getenumname(gettypedata( +// fparent.fprops[0].propinfo^.proptype)^.comptype,findex); +{$else} +// result:= getenumname(gettypedata(fparent.fprops[0].propinfo^.proptype^)^.comptype^,findex); + {$endif} + result:= msestring(getenumname(ftypeinfo,findex)); +end; + +procedure tsetelementeditor.setvalue(const value: msestring); +begin + setbitvalue(value = truename,findex); +// fparenteditor.modified; +end; + +procedure tsetelementeditor.updatedefaultvalue; +begin + if (fparenteditor.getordvalue xor fparenteditor.fprops[0].propinfo^.default) and + (1 shl findex) <> 0 then begin + include(fstate,ps_modified); + end + else begin + exclude(fstate,ps_modified); + end; +end; + +function tsetelementeditor.propertyname: msestring; +begin + result:= name; +end; + +function tsetelementeditor.canrevert: boolean; +begin + result:= false; +end; + +{ tclasspropertyeditor } + +function tclasspropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + + [ps_subproperties,ps_isordprop,ps_refresh]; +end; + +function tclasspropertyeditor.checkfreeoptionalclass: boolean; +begin + result:= askok(mo.c[ord(wishdestroy)]+' ' + fname+' ('+ + msestring(ftypeinfo^.Name)+ + ')?',stockobjects.captions[sc_confirmation]); +end; + +function tclasspropertyeditor.dispname: msestring; +begin + result:= msestring(ftypeinfo^.name); +end; + +function tclasspropertyeditor.getvalue: msestring; + +begin +// result:= '('+fprops[0].propinfo^.proptype^.name+')'; + result:= '<'+dispname+'>'; +end; + +function tclasspropertyeditor.subproperties: propertyeditorarty; +var + ar1: objectarty; + int1: integer; + comp1: tcomponent; +// prop1: tpropertyeditor; +begin + setlength(ar1,count); + for int1:= 0 to high(fprops) do begin + ar1[int1]:= tobject(getpointervalue(int1)); + end; + comp1:= linkcomponent; + if comp1 = nil then begin + comp1:= fcomponent; + end; + result:= fobjectinspector.getproperties(ar1,fmodule,comp1); +// result:= fobjectinspector.getproperties(ar1,fmodule,fcomponent); + for int1:= 0 to high(result) do begin + result[int1].fparenteditor:= self; + end; + if fstate * [ps_component,ps_subprop] <> [] then begin + for int1:= 0 to high(result) do begin + result[int1].setsubprop; + end; + end; +end; + +{ tlinkedpersistentpropertyeditor } +{ +function tlinkedpersistentpropertyeditor.issubcomponent(const index: integer = 0): boolean; +var + comp: tcomponent; +begin + comp:= tcomponent(getpointervalue(index)); + if comp = nil then begin + result:= false; + end + else begin + result:= cssubcomponent in comp.ComponentStyle; + end; +end; +} +{ +function tlinkedobjectpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_valuelist,ps_volatile,ps_component]; +end; + +function tlinkedobjectpropertyeditor.allequal: boolean; +var + po1: pointer; + int1: integer; +begin + result:= inherited allequal; + if not result then begin + result:= true; + po1:= getpointervalue; + for int1:= 1 to high(fprops) do begin + if getpointervalue(int1) <> po1 then begin + result:= false; + break; + end; + end; + end; +end; + +function tlinkedobjectpropertyeditor.getvalue: msestring; +var + obj1: tobject; +begin + obj1:= tobject(getpointervalue); + if obj1 = nil then begin + result:= ''; + end + else begin + result:= obj1.classname; + end; +end; + +function tlinkedobjectpropertyeditor.getvalues: msestringarty; +begin + result:= nil; +end; + +procedure tlinkedobjectpropertyeditor.setvalue(const value: msestring); +var + obj1: tobject; +begin + obj1:= nil; + if value = '' then begin + setpointervalue(obj1); + end; +end; + +procedure tlinkedobjectpropertyeditor.checkobj(const avalue: tobject); +begin + //dummy +end; + +function tlinkedobjectpropertyeditor.filterobj(const aobj: tobject): boolean; +begin + result:= true; +end; +} +{ tcomponentpropertyeditor } + +function tcomponentpropertyeditor.issubcomponent(const index: integer = 0): boolean; +var + comp: tcomponent; +begin + comp:= tcomponent(getpointervalue(index)); + if comp = nil then begin + result:= false; + end + else begin + result:= (cssubcomponent in comp.ComponentStyle) and + ((comp.owner = nil) or ownscomponent(component,comp) and + (comp is tmsecomponent) and + not (cs_subcompref in tmsecomponent1(comp).fmsecomponentstate)); + end; +end; + +function tcomponentpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate; + if not issubcomponent then begin + result:= result + [ps_valuelist,ps_volatile,ps_component,ps_dialog]; + end; +end; + +function tcomponentpropertyeditor.allequal: boolean; +var +// ca1: cardinal; + po1: pointer; + int1: integer; +begin + result:= inherited allequal; + if not result then begin + result:= true; + if issubcomponent then begin + for int1:= 1 to high(fprops) do begin + if not issubcomponent(int1) then begin + result:= false; + break; + end; + end; + end + else begin +// ca1:= getordvalue; + po1:= getpointervalue; + for int1:= 1 to high(fprops) do begin +// if cardinal(getordvalue(int1)) <> ca1 then begin + if getpointervalue(int1) <> po1 then begin + result:= false; + break; + end; + end; + end; + end; +end; + +function tcomponentpropertyeditor.getvalue: msestring; +//var +// comp1: tcomponent; +begin + if issubcomponent then begin + result:= inherited getvalue; + end + else begin + result:= getcomponentpropname(tcomponent(getpointervalue)); + end; +end; + +function tcomponentpropertyeditor.getvalues: msestringarty; +var + co1: tcomponent; + ar1: componentarty; + int1,int2: integer; +begin + ar1:= nil; //compiler warning + if issubcomponent then begin + result:= inherited getvalues; + end + else begin + if ps_link in fstate then begin + ar1:= fdesigner.getcomponentlist(tcomponentclass(typedata^.classtype), + {$ifdef FPC}@{$endif}filtercomponent,not (ps_local in fstate)); + if ps_local in fstate then begin + co1:= fcomponent.owner; + for int1:= high(ar1) downto 0 do begin + if ar1[int1].owner <> co1 then begin + ar1[int1]:= nil; + end; + end; + end; + + for int1:= 0 to high(ar1) do begin + with tdesigner1(designer).selections do begin + for int2:= count - 1 downto 0 do begin + if items[int2] = ar1[int1] then begin + ar1[int1]:= nil; //remove selected components + break; + end; + end; + end; + end; + result:= fdesigner.getcomponentnamelist(ar1,fmodule); + { + for int1:= 0 to high(ar1) do begin + if ar1[int1] <> nil then begin + additem(result,msestring(ar1[int1].name)); + end; + end; + } + end + else begin + if ps_local in fstate then begin + co1:= fmodule; + end + else begin + co1:= nil; + end; + result:= fdesigner.getcomponentnamelist( + tcomponentclass(typedata^.classtype),true{false},co1, + {$ifdef FPC}@{$endif}filtercomponent); + end; + end; +end; + +var + fcomppath: msestring; + +procedure tcomponentpropertyeditor.edit; +var + tree1: tcompnameitem; + mstr1: msestring; + co1: tcomponent; +begin + if ps_local in fstate then begin + co1:= fmodule; + end + else begin + co1:= nil; + end; + tree1:= fdesigner.getcomponentnametree( + tcomponentclass(typedata^.classtype),true,false,co1, + {$ifdef FPC}@{$endif}filtercomponent); + co1:= tcomponent(getpointervalue); + if co1 = nil then begin + mstr1:= fcomppath; + if mstr1 = '' then begin + mstr1:= msestring(fmodule.name); + end; + end + else begin + mstr1:= msestring(ownernamepath(co1)); + end; + if compnamedialog(tree1,mstr1,false) = mr_ok then begin + fcomppath:= mstr1; + setvalue(mstr1); + end; +end; + +procedure tcomponentpropertyeditor.setvalue(const value: msestring); +var + comp: tcomponent; + int1: integer; +begin + if issubcomponent then begin + inherited setvalue(value); + end + else begin + if value = '' then begin + comp:= nil; + end + else begin + if value <> getvalue then begin + int1:= pos('<',value); + if int1 > 0 then begin + comp:= fdesigner.getcomponent(copy(ansistring(value),1,int1-1),fmodule); +// comp:= fmodule.findcomponent(copy(value,1,int1-1)); + end + else begin + comp:= fdesigner.getcomponent(ansistring(value),fmodule); + end; + if (comp = nil) or not comp.InheritsFrom(gettypedata(ftypeinfo)^.classtype) then begin + properror; + end; + checkcomponent(comp); + end + else begin + exit; + end; + end; + setpointervalue(comp); + end; +end; + +procedure tcomponentpropertyeditor.checkcomponent(const avalue: tcomponent); +begin + //dummy +end; + +function tcomponentpropertyeditor.filtercomponent( + const acomponent: tcomponent): boolean; +begin + result:= true; +end; + +function tcomponentpropertyeditor.getlinksource: tcomponent; +begin + result:= tcomponent(getpointervalue); +end; + +{ tsubcomponenteditor } + +function tsubcomponentpropertyeditor.issubcomponent(const index: integer = 0): boolean; +begin + result:= true; +end; + +{ tsisterwidgetpropertyeditor } +{ +function tsisterwidgetpropertyeditor.getvalues: msestringarty; +var + ar1: componentarty; + widget1: twidget; + int1: integer; +begin + ar1:= nil; //compiler warning + if issubcomponent then begin + result:= inherited getvalues; + end + else begin + result:= nil; + widget1:= twidget(fcomponent).parentwidget; + if widget1 <> nil then begin + ar1:= fdesigner.getcomponentlist(tcomponentclass(typedata^.classtype)); + for int1:= 0 to high(ar1) do begin + if (twidget(ar1[int1]).parentwidget <> widget1) or + (ar1[int1] = fcomponent) then begin + ar1[int1]:= nil; + end; + end; + for int1:= 0 to high(ar1) do begin + if ar1[int1] <> nil then begin + additem(result,msestring(ar1[int1].name)); + end; + end; + end; + end; +end; +} + +function tsisterwidgetpropertyeditor.filtercomponent( + const acomponent: tcomponent): boolean; +begin + result:= (acomponent <> fcomponent) and + (twidget(acomponent).parentwidget = twidget(fcomponent).parentwidget); +end; + +function tsisterwidgetpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_sortlist]; +end; + +{ tnochildrenwidgetpropertyeditor } + +function tnochildrenwidgetpropertyeditor.filtercomponent( + const acomponent: tcomponent): boolean; +begin + result:= (twidget(acomponent).window = twidget(fcomponent).window) and + not twidget(fcomponent).checkdescendent(twidget(acomponent)); +end; + +function tnochildrenwidgetpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_sortlist]; +end; + +{ tchildwidgetpropertyeditor } + +function tchildwidgetpropertyeditor.getvalues: msestringarty; +var + ar1: componentarty; + widget1: twidget; + int1: integer; +begin + ar1:= nil; //compiler warning + if issubcomponent then begin + result:= inherited getvalues; + end + else begin + result:= nil; + widget1:= twidget(fcomponent); + ar1:= fdesigner.getcomponentlist(tcomponentclass(typedata^.classtype)); + for int1:= 0 to high(ar1) do begin + if (twidget(ar1[int1]).parentwidget <> widget1) then begin + ar1[int1]:= nil; + end; + end; + for int1:= 0 to high(ar1) do begin + if ar1[int1] <> nil then begin + additem(result,msestring(ar1[int1].name)); + end; + end; + end; +end; + +function tchildwidgetpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_sortlist]; +end; + +{ tlocalcomponentpropertyeditor } + +function tlocalcomponentpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_local]; +end; + +{ tlinkcomponentpropertyeditor } + +function tlinkcomponentpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_link]; +end; + +{ tlocallinkcomponentpropertyeditor } + +function tlocallinkcomponentpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_local,ps_link]; +end; + +{ toptionalclasspropertyeditor } + +function toptionalclasspropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_dialog,ps_volatile]; +end; + +procedure toptionalclasspropertyeditor.deleteinstance; +begin + if checkfreeoptionalclass then begin + setordvalue(0); + end; +end; + +procedure toptionalclasspropertyeditor.edit; +var + obj1: tobject; +begin + obj1:= getinstance; + if obj1 = nil then begin + setordvalue(1); + end + else begin + deleteinstance; + end; +end; + +function toptionalclasspropertyeditor.getinstance: tpersistent; +begin + result:= tpersistent(getpointervalue); +end; + +function toptionalclasspropertyeditor.getniltext: msestring; +begin + result:= ''; +end; + +procedure toptionalclasspropertyeditor.setvalue(const avalue: msestring); +begin + if avalue = '' then begin + deleteinstance; + end + else begin + inherited; + end; +end; + +function toptionalclasspropertyeditor.getvalue: msestring; +begin + if getinstance = nil then begin + result:= getniltext; + end + else begin + result:= inherited getvalue; + end; +end; + +function toptionalclasspropertyeditor.canrevert: boolean; +begin + result:= false; +end; + +{ tparentclasspropertyeditor } + +procedure tparentclasspropertyeditor.edit; +var + obj1: tobject; + persist1,persist2: tpersistent; + int1: integer; +begin + obj1:= getinstance; + if obj1 = nil then begin + for int1:= 0 to count - 1 do begin + persist1:= tpersistent(getpointervalue(int1)); + setordvalue(int1,1); //create instance + persist2:= tpersistent(getpointervalue(int1)); + if (persist1 <> nil) and (persist2 <> nil) then begin + persist2.Assign(persist1); //copy default values + end; + end; + end + else begin + if not checkfreeoptionalclass then begin + exit; + end; + setordvalue(0); + end; +end; + +function tparentclasspropertyeditor.getinstance: tpersistent; +begin + result:= getinstancepo(instance)^; +end; + +function tparentclasspropertyeditor.getniltext: msestring; +begin + result:= ''; +end; + +function tparentclasspropertyeditor.subproperties: propertyeditorarty; +begin + if getinstance = nil then begin + result:= nil; + end + else begin + result:= inherited subproperties; + end; +end; + +{ tparentfontproperty } + +function tparentfontpropertyeditor.getinstancepo(acomponent: tobject): ppersistent; +begin + result:= ppersistent(parentfontclassty(typedata^.classtype).getinstancepo(acomponent)); +end; + +{ tstringpropertyeditor } + +function tstringpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_isordprop]; +end; + +function tstringpropertyeditor.allequal: boolean; +var + int1: integer; + str1: string; +begin + result:= inherited allequal; + if not result then begin + result:= true; + str1:= getstringvalue; + for int1:= 1 to high(fprops) do begin + if str1 <> getstringvalue(int1) then begin + result:= false; + break; + end; + end; + end; +end; + +function tstringpropertyeditor.getvalue: msestring; +begin + result:= msestring(getstringvalue(0)); +end; + +procedure tstringpropertyeditor.setvalue(const value: msestring); +begin + setstringvalue(ansistring(value)); +end; + +{ tutf8stringpropertyeditor } + +function tutf8stringpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_isordprop]; +end; + +function tutf8stringpropertyeditor.allequal: boolean; +var + int1: integer; + str1: utf8string; +begin + result:= inherited allequal; + if not result then begin + result:= true; + str1:= getutf8stringvalue; + for int1:= 1 to high(fprops) do begin + if str1 <> getutf8stringvalue(int1) then begin + result:= false; + break; + end; + end; + end; +end; + +function tutf8stringpropertyeditor.getvalue: msestring; +begin + result:= utf8tostring(getutf8stringvalue(0)); +end; + +procedure tutf8stringpropertyeditor.setvalue(const value: msestring); +begin + setutf8stringvalue(stringtoutf8(value)); +end; + +{ tmsestringpropertyeditor } + +function tmsestringpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_isordprop,ps_dialog]; +end; + +function tmsestringpropertyeditor.allequal: boolean; +var + int1: integer; + str1: msestring; +begin + result:= inherited allequal; + if not result then begin + result:= true; + str1:= getmsestringvalue; + for int1:= 0 to high(fprops) do begin + if str1 <> getmsestringvalue(int1) then begin + result:= false; + break; + end; + end; + end; +end; + +function tmsestringpropertyeditor.getvalue: msestring; +begin + result:= getmsestringvalue(0); +end; + +procedure tmsestringpropertyeditor.setvalue(const value: msestring); +begin + setmsestringvalue(value); +end; + +procedure tmsestringpropertyeditor.edit; +var + mstr1: msestring; +begin + mstr1:= encodemsestring(getmsestringvalue(0)); + if memodialog(mstr1,false) = mr_ok then begin + setmsestringvalue(decodemsestring(mstr1)); + end; +end; + +{ trichstringpropertyeditor } + +procedure trichstringpropertyeditor.edit; +var + intf1: irichstringprop; + rstr1: richstringty; + i1: int32; +begin + if getcorbainterface(component,typeinfo(irichstringprop),intf1) then begin + rstr1:= intf1.getrichvalue(); + rstr1.text:= encodemsestring(rstr1.text); + if richstringdialog(rstr1,false) = mr_ok then begin + rstr1.text:= decodemsestring(rstr1.text); + for i1:= 0 to high(fprops) do begin + if getcorbainterface(fprops[i1].instance, + typeinfo(irichstringprop),intf1) then begin + intf1.setrichvalue(rstr1); + end; + end; + modified; + end; + end + else begin + inherited; + end; +end; + +{ tarraypropertyeditor } + +function tarraypropertyeditor.allequal: boolean; +var + int1: integer; + int2: integer; + p1: tarrayprop; +begin + result:= inherited allequal; + if not result then begin + result:= true; + p1:= tarrayprop(getpointervalue); + if p1 <> nil then begin + int2:= p1.count; + for int1:= 1 to high(fprops) do begin + p1:= tarrayprop(getpointervalue(int1)); + if (p1 = nil) or (int2 <> p1.count) then begin + result:= false; + break; + end; + end; + end + else begin + for int1:= 1 to high(fprops) do begin + p1:= tarrayprop(getpointervalue(int1)); + if p1 <> nil then begin + result:= false; + break; + end; + end; + end; + end; +end; + +function tarraypropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tpropertyeditor; +end; + +function tarraypropertyeditor.getelementeditorclass: elementeditorclassty; +begin + result:= tarrayelementeditor; +end; + +function tarraypropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_subproperties,ps_volatile]; +end; + +function tarraypropertyeditor.getvalue: msestring; +begin + result:= inttostrmse(tarrayprop(getpointervalue).count); +end; + +function tarraypropertyeditor.name: msestring; +begin + result:= inherited name +'.count'; +end; +{ +procedure tarraypropertyeditor.setmincount(mincount: integer); +begin + +end; +} +procedure tarraypropertyeditor.setvalue(const value: msestring); +var + int1: integer; + va: integer; +begin + va:= strtoint(value); + if va < 0 then begin + va:= 0; + end + else begin + if va > propmaxarraycount then begin + va:= propmaxarraycount; + end; + end; + int1:= tarrayprop(getpointervalue).count; + if ( int1 > va) and not askok(mo.c[ord(wishdelete)]+' '+inttostrmse(va) + + ' '+mo.c[ord(str_to)]+' '+ inttostrmse(int1-1) + '?', + stockobjects.captions[sc_confirmation]) then begin + exit; + end; + if not ((ps_noadditems in fstate) and (va > int1)) then begin + for int1:= 0 to high(fprops) do begin + tarrayprop(getpointervalue(int1)).count:= va; + end; + modified; + end; +end; + +function tarraypropertyeditor.subproperties: propertyeditorarty; +var + prop: tarrayprop; + int1,int2: integer; +begin + result:= inherited subproperties; + int2:= 0; + for int1:= 0 to high(result) do begin + if result[int1].name = 'count' then begin + result[int1].Free; + end + else begin + result[int2]:= result[int1]; + inc(int2); + end; + end; + setlength(result,int2); + prop:= tarrayprop(getpointervalue); + if prop <> nil then begin + setlength(fsubprops,prop.count); + for int1:= 0 to high(fsubprops) do begin + fsubprops[int1]:= getelementeditorclass.create(int1,self,geteditorclass, + fdesigner,fobjectinspector,fprops,getitemtypeinfo); + end; + stackarray(pointerarty(fsubprops),pointerarty(result)); + end + else begin + setlength(result,0); + end; +end; + +procedure tarraypropertyeditor.itemmoved(const source,dest: integer); +begin + modified; +end; + +procedure tarraypropertyeditor.dopopup(var amenu: tpopupmenu; + const atransientfor: twidget; var mouseinfo: mouseeventinfoty); +begin + if not (ps_noadditems in fstate) then begin + tpopupmenu.additems(amenu,atransientfor,mouseinfo, + ['Insert Item'+c_tab+ + '('+encodeshortcutname(sysshortcuts[sho_rowinsert])+')', + 'Append Item'+c_tab+ + '('+encodeshortcutname(sysshortcuts[sho_rowappend])+')'], + [],[],[@doinsert,@doappend]); + end; + inherited; +end; + +procedure tarraypropertyeditor.dokeydown(var ainfo: keyeventinfoty); +begin + if not (ps_noadditems in fstate) then begin + if issysshortcut(sho_rowinsert,ainfo) then begin + doinsert(nil); + include(ainfo.eventstate,es_processed); + end + else begin + if issysshortcut(sho_rowappend,ainfo) then begin + doappend(nil); + include(ainfo.eventstate,es_processed); + end; + end; + end; +end; + +procedure tarraypropertyeditor.doappend(const sender: tobject); +begin + with tarrayprop(getpointervalue) do begin + insertdefault(count); + end; + modified; +end; + +procedure tarraypropertyeditor.doinsert(const sender: tobject); +begin + with tarrayprop(getpointervalue) do begin + insertdefault(0); + end; + modified; +end; + +procedure tarraypropertyeditor.move(const curindex: integer; + const newindex: integer); +var + int1: integer; +begin + for int1:= 0 to high(fprops) do begin + tarrayprop(getpointervalue(int1)).move(curindex,newindex); + end; + itemmoved(curindex,newindex) +end; + +function tarraypropertyeditor.itemprefix: msestring; +begin + result:= 'Item '; +end; + +function tarraypropertyeditor.getitemtypeinfo: ptypeinfo; +begin + result:= ftypeinfo; //default +end; + +function tarraypropertyeditor.itemgetdefaultstate( + const sender: tarrayelementeditor): propertystatesty; +begin + result:= sender.feditor.getdefaultstate(); +end; + +function tarraypropertyeditor.itemgetlinksource( + const sender: tarrayelementeditor): tcomponent; +begin + result:= sender.feditor.getlinksource(); +end; + +procedure tarraypropertyeditor.itemsetvalue( + const sender: tarrayelementeditor; + const value: msestring); +begin + sender.feditor.setvalue(value); +end; + +function tarraypropertyeditor.itemgetvalue( + const sender: tarrayelementeditor): msestring; +begin + result:= sender.feditor.getvalue(); +end; + +function tarraypropertyeditor.itemgetvalues( + const sender: tarrayelementeditor): msestringarty; +begin + result:= sender.feditor.getvalues(); +end; + +procedure tarraypropertyeditor.itemedit( + const sender: tarrayelementeditor); +begin + sender.feditor.edit(); +end; + +procedure tarraypropertyeditor.itemfocused(const sender: tarrayelementeditor); +begin + sender.feditor.focused(); +end; + +function tarraypropertyeditor.itemname( + const sender: tarrayelementeditor): msestring; +begin + result:= itemprefix + inttostrmse(sender.findex); +end; + +function tarraypropertyeditor.itemsubproperties( + const sender: tarrayelementeditor): propertyeditorarty; +begin + result:= sender.feditor.subproperties(); +end; + +{ tarrayelementeditor } + +constructor tarrayelementeditor.create(aindex: integer; + aparenteditor: tarraypropertyeditor; + aeditorclass: propertyeditorclassty; + const adesigner: idesigner; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypinfo: ptypeinfo); +begin + findex:= aindex; + fparenteditor:= aparenteditor; + feditor:= aeditorclass.create(adesigner,aparenteditor.fmodule, + aparenteditor.fcomponent,aobjectinspector,aprops,atypinfo); + feditor.setremote(iremotepropertyeditor(self)); + inherited create(adesigner,feditor.fmodule,feditor.fcomponent, + aobjectinspector,aprops,atypinfo); +end; + +destructor tarrayelementeditor.destroy; +begin + feditor.Free; + inherited; +end; + +function tarrayelementeditor.getordvalue(const index: integer = 0): integer; +begin + with fprops[index] do begin + result:= tintegerarrayprop(getpointerprop1(instance,propinfo))[findex]; + end; +end; + +procedure tarrayelementeditor.setordvalue(const value: longword); +var + int1: integer; +begin + for int1:= 0 to high(fprops) do begin + with fprops[int1] do begin + tintegerarrayprop(getpointerprop1(instance,propinfo))[findex]:= value; + end; + end; + modified; +end; + +procedure tarrayelementeditor.setordvalue(const index: integer; + const value: longword); +begin + with fprops[index] do begin + tintegerarrayprop(getpointerprop1(instance,propinfo))[findex]:= value; + end; + modified; +end; + +function tarrayelementeditor.getint64value(const index: integer = 0): int64; +begin + with fprops[index] do begin + result:= tint64arrayprop(getpointerprop1(instance,propinfo))[findex]; + end; +end; + +procedure tarrayelementeditor.setint64value(const value: int64); +var + int1: integer; +begin + for int1:= 0 to high(fprops) do begin + with fprops[int1] do begin + tint64arrayprop(getpointerprop1(instance,propinfo))[findex]:= value; + end; + end; + modified; +end; + +procedure tarrayelementeditor.setint64value(const index: integer; + const value: int64); +begin + with fprops[index] do begin + tint64arrayprop(getpointerprop1(instance,propinfo))[findex]:= value; + end; + modified; +end; + +function tarrayelementeditor.getpointervalue(const index: integer = 0): pointer; +begin + with fprops[index] do begin + result:= tpointerarrayprop(getpointerprop1(instance,propinfo))[findex]; + end; +end; + +procedure tarrayelementeditor.setpointervalue(const value: pointer); +var + int1: integer; +begin + for int1:= 0 to high(fprops) do begin + with fprops[int1] do begin + tpointerarrayprop(getpointerprop1(instance,propinfo))[findex]:= value; + end; + end; + modified; +end; + +procedure tarrayelementeditor.setpointervalue(const index: integer; + const value: pointer); +begin + with fprops[index] do begin + tpointerarrayprop(getpointerprop1(instance,propinfo))[findex]:= value; + end; + modified; +end; + +procedure tarrayelementeditor.setbitvalue(const value: boolean; + const bitindex: integer); +var + int1: integer; + wo1: longword; +begin + for int1:= 0 to high(fprops) do begin + with fprops[int1] do begin + wo1:= longword(tsetarrayprop(getpointerprop1(instance,propinfo))[findex]); + updatebit(wo1,bitindex,value); + tsetarrayprop(getpointerprop1(instance,propinfo))[findex]:= tintegerset(wo1); + end; + end; + modified; +end; + +function tarrayelementeditor.getfloatvalue(const index: integer = 0): extended; +begin + with fprops[index] do begin + result:= trealarrayprop(getpointerprop1(instance,propinfo))[findex]; + end; +end; + +procedure tarrayelementeditor.setfloatvalue(const value: extended); +var + int1: integer; +begin + for int1:= 0 to high(fprops) do begin + with fprops[int1] do begin + trealarrayprop(getpointerprop1(instance,propinfo))[findex]:= value; + end; + end; + modified; +end; + +function tarrayelementeditor.getstringvalue(const index: integer = 0): string; +begin + with fprops[index] do begin + result:= tstringarrayprop(getpointerprop1(instance,propinfo))[findex]; + end; +end; + +procedure tarrayelementeditor.setstringvalue(const value: string); +var + int1: integer; +begin + for int1:= 0 to high(fprops) do begin + with fprops[int1] do begin + tstringarrayprop(getpointerprop1(instance,propinfo))[findex]:= value; + end; + end; + modified; +end; + +function tarrayelementeditor.getmsestringvalue(const index: integer = 0; + const raw: boolean = false): msestring; +begin + with fprops[index] do begin + result:= tmsestringarrayprop(getpointerprop1(instance,propinfo))[findex]; + end; +end; + +procedure tarrayelementeditor.setmsestringvalue(const value: msestring; + const raw: boolean = false); +var + int1: integer; +begin + for int1:= 0 to high(fprops) do begin + with fprops[int1] do begin + tmsestringarrayprop(getpointerprop1(instance,propinfo))[findex]:= value; + end; + end; + modified; +end; +{ +function tarrayelementeditor.getclassvalue( + const aindex: integer): tpersistent; +begin + with fprops[aindex] do begin + result:= tpersistentarrayprop(GetOrdProp(instance,propinfo))[findex]; + end; +end; +} +procedure tarrayelementeditor.dragbegin(var accept: boolean); +begin + accept:= true; +end; + +procedure tarrayelementeditor.dragdrop(const sender: tpropertyeditor); +begin + if (sender is tarrayelementeditor) and + (tarrayelementeditor(sender).fparenteditor = fparenteditor) then begin + tarraypropertyeditor(fparenteditor).move(tarrayelementeditor(sender).findex, + findex); + end; +end; + +procedure tarrayelementeditor.dragover(const sender: tpropertyeditor; + var accept: boolean); +begin + accept:= (sender is tarrayelementeditor) and + (tarrayelementeditor(sender).fparenteditor = fparenteditor); +end; + +procedure tarrayelementeditor.dodelete(const sender: tobject); +begin + if askyesno('Do you wish to delete '+getvalue+'?','CONFIRMATION') then begin + tarrayprop(fparenteditor.getpointervalue).delete(findex); + fparenteditor.modified; + end; +end; + +procedure tarrayelementeditor.doinsert(const sender: tobject); +begin + tarrayprop(fparenteditor.getpointervalue).insertdefault(findex); + fparenteditor.modified; +end; + +procedure tarrayelementeditor.doappend(const sender: tobject); +begin + tarrayprop(fparenteditor.getpointervalue).insertdefault(findex+1); + fparenteditor.modified; +end; + +procedure tarrayelementeditor.dopopup(var amenu: tpopupmenu; + const atransientfor: twidget; var mouseinfo: mouseeventinfoty); +begin + if not (ps_noadditems in fparenteditor.fstate) then begin + tpopupmenu.additems(amenu,atransientfor,mouseinfo, + ['Insert Item'+c_tab+ + '('+encodeshortcutname(sysshortcuts[sho_rowinsert])+')', + 'Append Item'+c_tab+ + '('+encodeshortcutname(sysshortcuts[sho_rowappend])+')', + 'Delete Item'+c_tab+ + '('+encodeshortcutname(sysshortcuts[sho_rowdelete])+')'],[],[], + [{$ifdef FPC}@{$endif}doinsert, + {$ifdef FPC}@{$endif}doappend,{$ifdef FPC}@{$endif}dodelete]); + end + else begin + if not (ps_nodeleteitems in fparenteditor.fstate) then begin + tpopupmenu.additems(amenu,atransientfor,mouseinfo, + ['Delete Item'],[],[], + [{$ifdef FPC}@{$endif}dodelete]); + end; + end; + inherited; +end; + +procedure tarrayelementeditor.dokeydown(var ainfo: keyeventinfoty); +begin + if issysshortcut(sho_rowdelete,ainfo) then begin + if not (ps_nodeleteitems in fparenteditor.fstate) then begin + dodelete(nil); + include(ainfo.eventstate,es_processed); + end; + end + else begin + if not (ps_noadditems in fparenteditor.fstate) then begin + if issysshortcut(sho_rowinsert,ainfo) then begin + doinsert(nil); + include(ainfo.eventstate,es_processed); + end + else begin + if issysshortcut(sho_rowappend,ainfo) then begin + doappend(nil); + include(ainfo.eventstate,es_processed); + end; + end; + end; + end; +end; + +function tarrayelementeditor.name: msestring; +begin + result:= tarraypropertyeditor(fparenteditor).itemname(self); +// result:= tarraypropertyeditor(fparenteditor).itemprefix + inttostr(findex); +end; + +function tarrayelementeditor.subproperties: propertyeditorarty; +begin + result:= tarraypropertyeditor(fparenteditor).itemsubproperties(self); +end; + +procedure tarrayelementeditor.edit; +begin + tarraypropertyeditor(fparenteditor).itemedit(self); +end; + +procedure tarrayelementeditor.focused(); +begin + tarraypropertyeditor(fparenteditor).itemfocused(self); +end; + +function tarrayelementeditor.getdefaultstate: propertystatesty; +begin + result:= tarraypropertyeditor(fparenteditor).itemgetdefaultstate(self); +end; + +function tarrayelementeditor.getvalue: msestring; +begin + result:= tarraypropertyeditor(fparenteditor).itemgetvalue(self); +end; + +function tarrayelementeditor.getvalues: msestringarty; +begin + result:= tarraypropertyeditor(fparenteditor).itemgetvalues(self); +end; + +procedure tarrayelementeditor.setvalue(const value: msestring); +begin + tarraypropertyeditor(fparenteditor).itemsetvalue(self,value); +end; + +function tarrayelementeditor.canrevert: boolean; +begin + result:= false; +end; + +function tarrayelementeditor.getselectedpropinstances: objectarty; +var + int1,int2: integer; +begin + with tarraypropertyeditor(fparenteditor) do begin + setlength(result,length(fsubprops)); + int2:= 0; + for int1:= 0 to high(fsubprops) do begin + if fsubprops[int1].selected then begin + result[int2]:= tobject(fsubprops[int1].feditor.getpointervalue); + inc(int2); + end; + end; + setlength(result,int2); + end; +end; + +function tarrayelementeditor.getvalueeditor: tpropertyeditor; +begin + result:= feditor; +end; + +function tarrayelementeditor.getlinksource: tcomponent; +begin + result:= tarraypropertyeditor(fparenteditor).itemgetlinksource(self); +end; + +function tarrayelementeditor.gettypinfo: ptypeinfo; +begin + result:= getvalueeditor.typinfo; +end; + +{ tconstarraypropertyeditor } + +function tconstarraypropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + + [ps_subproperties,ps_noadditems,ps_nodeleteitems{,ps_volatile}]; +end; + +function tconstarraypropertyeditor.getvalue: msestring; +begin + result:= '' +end; + +procedure tconstarraypropertyeditor.setvalue(const value: msestring); +begin + //dummy +end; + +function tconstarraypropertyeditor.name: msestring; +begin + result:= fname; +end; + +function tconstarraypropertyeditor.allequal: boolean; +begin + result:= false; +end; + +{ tclasselementeditor } +{ +function tclasselementeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_subproperties]; +end; + +function tclasselementeditor.getvalue: msestring; +begin + result:= '('+fprops[0].propinfo^.proptype^.name+')'; +end; + +function tclasselementeditor.subproperties: propertyeditorarty; +begin + result:= fobjectinspector.getproperties(tobject(getclassvalue)); +end; +} +{ tpersistentarraypropertyeditor } + +function tpersistentarraypropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tclasselementeditor; +end; + +{ toptionalpersistentarraypropertyeditor } + +function toptionalpersistentarraypropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_dialog,ps_volatile]; +end; + +procedure toptionalpersistentarraypropertyeditor.edit; +var + obj1: tobject; +begin + obj1:= getinstance; + if obj1 = nil then begin + setordvalue(1); + end + else begin + if not checkfreeoptionalclass then begin + exit; + end; + setordvalue(0); + end; + modified; +end; + +function toptionalpersistentarraypropertyeditor.getinstance: tpersistent; +begin + result:= tpersistent(getpointervalue); +end; + +function toptionalpersistentarraypropertyeditor.getniltext: msestring; +begin + result:= ''; +end; + +function toptionalpersistentarraypropertyeditor.getvalue: msestring; +begin + if getinstance = nil then begin + result:= getniltext; + end + else begin + result:= inherited getvalue; + end; +end; + +procedure toptionalpersistentarraypropertyeditor.setvalue(const value: msestring); +begin + if getordvalue <> 0 then begin + inherited; + end; +end; + +{ tmenuelementeditor } + +function tmenuelementeditor.getvalue: msestring; +var + item1: tmenuitem; +begin + item1:= tmenuitem(getpointervalue); + if (mao_separator in item1.options) then begin + result:= '<---->'; + end + else begin + result:= '<' + decodemsestring(item1.caption) + '>'; + if item1.name <> '' then begin + result:= result + '<' + msestring(item1.name) + '>'; + end; + end; +end; + +{ tmenuarraypropertyeditor } + +function tmenuarraypropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tmenuelementeditor; +end; + +{ tintegerarraypropertyeditor } + +function tintegerarraypropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tordinalpropertyeditor; +end; + +{ tsetarrayelementeditor } + +constructor tsetarrayelementeditor.create(aindex: integer; + aparenteditor: tarraypropertyeditor; + aeditorclass: propertyeditorclassty; const adesigner: idesigner; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypinfo: ptypeinfo); +begin + inherited; + feditor.ftypeinfo:= tsetarrayprop(aparenteditor.getpointervalue).typeinfo; +end; + +{ tsetarraypropertyeditor } + +function tsetarraypropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tsetpropertyeditor; +end; + +function tsetarraypropertyeditor.getelementeditorclass: elementeditorclassty; +begin + result:= tsetarrayelementeditor; +end; + +{ trealarraypropertyeditor} + +function trealarraypropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= trealtypropertyeditor; +end; + +{ tcolorarraypropertyeditor } + +function tcolorarraypropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tcolorpropertyeditor; +end; + +function tcolorarraypropertyeditor.getitemtypeinfo: ptypeinfo; +begin + result:= typeinfo(colorty); +end; + +{ tstringarraypropertyeditor } + +function tstringarraypropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tstringpropertyeditor; +end; + +{ tmsestringarraypropertyeditor } + +function tmsestringarraypropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tmsestringpropertyeditor; +end; + +{ tordinalelementeditor } +{ +function tordinalelementeditor.getvalue: msestring; +begin + result:= inttostr(getordvalue); +end; + +procedure tordinalelementeditor.setvalue(const value: msestring); +begin + setordvalue(strtointvalue(value)); +end; +} +{ tlclasselementeditor } + +function tclasselementeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_canselect]; +end; + +function tclasselementeditor.getvalue: msestring; +var + obj1: tobject; +begin + obj1:= tobject(getpointervalue); + if obj1 = nil then begin + result:= ''; + end + else begin +// result:= '<'+obj1.classtype.classname+'>'; + result:= '<'+dispname+'>'; + end; +end; + +function tclasselementeditor.dispname: msestring; +begin + result:= msestring(tobject(getpointervalue).classtype.classname); +end; + +{ tcllectionitemeditor } + +constructor tcollectionitemeditor.create(aindex: integer; + aparenteditor: tcollectionpropertyeditor; + aeditorclass: propertyeditorclassty; + const adesigner: idesigner; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypinfo: ptypeinfo); +var + props1: propinstancearty; + int1: integer; +begin + setlength(props1,length(aprops)); + for int1:= 0 to high(props1) do begin + props1[int1].propinfo:= aprops[int1].propinfo; + props1[int1].instance:= + tcollection(aparenteditor.getpointervalue(int1)).items[aindex]; + end; + findex:= aindex; + fparenteditor:= aparenteditor; + feditor:= aeditorclass.create(adesigner,aparenteditor.fmodule, + aparenteditor.fcomponent,aobjectinspector,props1,atypinfo); + feditor.setremote(iremotepropertyeditor(self)); + inherited create(adesigner,feditor.fmodule,feditor.fcomponent, + aobjectinspector,aprops,atypinfo); +end; + +destructor tcollectionitemeditor.destroy; +begin + feditor.free; + inherited; +end; + +procedure tcollectionitemeditor.setvalue(const value: msestring); +begin + feditor.setvalue(value); +end; + +function tcollectionitemeditor.getvalue: msestring; +begin + result:= feditor.getvalue; +end; + +function tcollectionitemeditor.getvalues: msestringarty; +begin + result:= feditor.getvalues; +end; + +procedure tcollectionitemeditor.edit; +begin + feditor.edit; +end; + +function tcollectionitemeditor.subproperties: propertyeditorarty; +begin + result:= feditor.subproperties; +end; + +function tcollectionitemeditor.name: msestring; +begin + result:= 'Item '+inttostrmse(findex); +end; +{ +function tcollectionitemeditor.getordvalue(const index: integer = 0): integer; +begin + result:= integer(tcollection(fparenteditor.getpointervalue(index)).items[findex]); +end; + +procedure tcollectionitemeditor.setordvalue(const value: longword); +begin + //dummy +end; + +procedure tcollectionitemeditor.setordvalue(const index: integer; + const value: longword); +begin + //dummy +end; +} +function tcollectionitemeditor.getpointervalue(const index: integer = 0): pointer; +begin + result:= tcollection(fparenteditor.getpointervalue(index)).items[findex]; +end; + +procedure tcollectionitemeditor.setpointervalue(const value: pointer); +begin + //dummy +end; + +procedure tcollectionitemeditor.setpointervalue(const index: integer; + const value: pointer); +begin + //dummy +end; + +procedure tcollectionitemeditor.doinsert(const sender: tobject); +begin + tcollection(fparenteditor.getpointervalue).insert(findex); + fparenteditor.modified; +end; + +procedure tcollectionitemeditor.doappend(const sender: tobject); +begin + tcollection(fparenteditor.getpointervalue).insert(findex+1); + fparenteditor.modified; +end; + +procedure tcollectionitemeditor.dodelete(const sender: tobject); +begin + if askyesno('Do you wish to delete '+getvalue+'?','CONFIRMATION') then begin + tcollection(fparenteditor.getpointervalue).delete(findex); + fparenteditor.modified; + end; +end; + +function tcollectionitemeditor.getdefaultstate: propertystatesty; +begin + result:= feditor.getdefaultstate; +end; + +procedure tcollectionitemeditor.dragbegin(var accept: boolean); +begin + accept:= true; +end; + +procedure tcollectionitemeditor.dragover(const sender: tpropertyeditor; + var accept: boolean); +begin + accept:= (sender is tcollectionitemeditor) and + (tcollectionitemeditor(sender).fparenteditor = fparenteditor); +end; + +procedure tcollectionitemeditor.dragdrop(const sender: tpropertyeditor); +var + source: integer; +begin + if (sender is tcollectionitemeditor) and + (tcollectionitemeditor(sender).fparenteditor = fparenteditor) then begin + source:= tcollectionitemeditor(sender).findex; + tcollection(fparenteditor.getpointervalue).items[source].index:= findex; +// sender.modified; +// modified; + tcollectionpropertyeditor(fparenteditor).itemmoved(source,findex); + end; +end; + +procedure tcollectionitemeditor.dopopup(var amenu: tpopupmenu; const atransientfor: twidget; + var mouseinfo: mouseeventinfoty); +begin + tpopupmenu.additems(amenu,atransientfor,mouseinfo, + ['Insert Item'+c_tab+ + '('+encodeshortcutname(sysshortcuts[sho_rowinsert])+')', + 'Append Item'+c_tab+ + '('+encodeshortcutname(sysshortcuts[sho_rowappend])+')', + 'Delete Item'+c_tab+ + '('+encodeshortcutname(sysshortcuts[sho_rowdelete])+')'],[],[], + [{$ifdef FPC}@{$endif}doinsert, + {$ifdef FPC}@{$endif}doappend,{$ifdef FPC}@{$endif}dodelete]); + inherited; +end; + +procedure tcollectionitemeditor.dokeydown(var ainfo: keyeventinfoty); +begin + if issysshortcut(sho_rowdelete,ainfo) then begin + dodelete(nil); + include(ainfo.eventstate,es_processed); + end + else begin + if issysshortcut(sho_rowinsert,ainfo) then begin + doinsert(nil); + include(ainfo.eventstate,es_processed); + end + else begin + if issysshortcut(sho_rowappend,ainfo) then begin + doappend(nil); + include(ainfo.eventstate,es_processed); + end; + end; + end; +end; + +function tcollectionitemeditor.getselectedpropinstances: objectarty; +begin + result:= nil; +end; + +{ tcollectionpropertyeditor } + +function tcollectionpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_subproperties,ps_volatile]; +end; + +function tcollectionpropertyeditor.name: msestring; +begin + result:= inherited name +'.count'; +end; + +function tcollectionpropertyeditor.getvalue: msestring; +var + col1: tcollection; +begin + col1:= tcollection(getpointervalue); + if col1 <> nil then begin + result:= inttostrmse(col1.count); + end + else begin + result:= ''; + end; +end; + +procedure tcollectionpropertyeditor.setvalue(const value: msestring); +var + int1,int2: integer; + va: integer; + col1: tcollection; +begin + col1:= tcollection(getpointervalue); + if col1 <> nil then begin + va:= strtoint(value); + if va < 0 then begin + va:= 0; + end + else begin + if va > propmaxarraycount then begin + va:= propmaxarraycount; + end; + end; + int1:= col1.count; + if ( int1 > va) then begin + if askok('Do you wish to delete items '+inttostrmse(va) + + ' to '+ inttostrmse(int1-1) + '?','CONFIRMATION') then begin + for int2:= int1 - 1 downto va do begin + col1.items[int2].free; + end; + end + else begin + exit; + end; + end + else begin + for int1:= 0 to high(fprops) do begin + with tcollection(getpointervalue(int1)) do begin + for int2:= count to va - 1 do begin + add; + end; + end; + end; + end; + modified; + end; +end; + +function tcollectionpropertyeditor.subproperties: propertyeditorarty; +var + col1: tcollection; + itemtypeinfo: ptypeinfo; + edtype: propertyeditorclassty; + int1: integer; +begin + col1:= tcollection(getpointervalue); + if col1 <> nil then begin + setlength(result,col1.count); + itemtypeinfo:= ptypeinfo(col1.itemclass.classinfo); + edtype:= propertyeditors.geteditorclass( + itemtypeinfo,fcomponent.classtype,ansistring(fname)); + for int1:= 0 to high(result) do begin + result[int1]:= tcollectionitemeditor.create(int1,self,edtype,fdesigner, + fobjectinspector,fprops,itemtypeinfo); + end; + end + else begin + result:= nil; + end; +end; + +procedure tcollectionpropertyeditor.dopopup(var amenu: tpopupmenu; + const atransientfor: twidget; var mouseinfo: mouseeventinfoty); +begin + if not (ps_noadditems in fstate) then begin + tpopupmenu.additems(amenu,atransientfor,mouseinfo, + ['Insert Item'+c_tab+ + '('+encodeshortcutname(sysshortcuts[sho_rowinsert])+')', + 'Append Item'+c_tab+ + '('+encodeshortcutname(sysshortcuts[sho_rowappend])+')'], + [],[],[@doinsert,@doappend]); + end; + inherited; +end; + +procedure tcollectionpropertyeditor.dokeydown(var ainfo: keyeventinfoty); +begin + if not (ps_noadditems in fstate) then begin + if issysshortcut(sho_rowinsert,ainfo) then begin + doinsert(nil); + include(ainfo.eventstate,es_processed); + end + else begin + if issysshortcut(sho_rowappend,ainfo) then begin + doappend(nil); + include(ainfo.eventstate,es_processed); + end; + end; + end; +end; + +procedure tcollectionpropertyeditor.doappend(const sender: tobject); +begin + with tcollection(getpointervalue) do begin + insert(count); + end; + modified; +end; + +procedure tcollectionpropertyeditor.doinsert(const sender: tobject); +begin + with tcollection(getpointervalue) do begin + insert(0); + end; + modified; +end; + +procedure tcollectionpropertyeditor.itemmoved(const source: integer; + const dest: integer); +begin + modified; +end; + +{ tenumpropertyeditor } + +function tenumpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_valuelist]; +end; + +function tenumpropertyeditor.getvalue: msestring; +begin + result:= msestring(getenumname(gettypeinfo,getordvalue)); +end; + +procedure tenumpropertyeditor.setvalue(const value: msestring); +begin + setordvalue(getenumvalue(gettypeinfo,ansistring(value))); +end; + +function tenumpropertyeditor.getvalues: msestringarty; +var + typedata1: ptypedata; + atypeinfo: ptypeinfo; +begin + atypeinfo:= gettypeinfo; + typedata1:= gettypedata(atypeinfo); + with typedata1^ do begin + if minvalue < 0 then begin //for boolean + setlength(result,2); + result[0]:= msestring(getenumname(atypeinfo,0)); + result[1]:= msestring(getenumname(atypeinfo,1)); + end + else begin + result:= getenumnames(atypeinfo); + end; + end; +end; + +function tenumpropertyeditor.gettypeinfo: ptypeinfo; +begin + result:= ftypeinfo; +end; + +{ tfontnamepropertyeditor } + +function tfontnamepropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_valuelist,ps_sortlist]; +end; + +function tfontnamepropertyeditor.getvalues: msestringarty; +begin + result:= getenumnames(typeinfo(stockfontty)); + stackarray(fontaliasnames,result); +end; + +{ tbooleanpropertyeditor } + +function tbooleanpropertyeditor.getdefaultstate: propertystatesty; +begin + Result:= inherited getdefaultstate + [ps_valuelist]; +end; + +procedure tbooleanpropertyeditor.setvalue(const value: msestring); +begin + setordvalue(longword(uppercase(trim(value)) = + uppercase(msestring(truename)))); +end; + +function tbooleanpropertyeditor.getvalue: msestring; +begin + if getordvalue <> 0 then begin + result:= truename; + end + else begin + result:= falsename; + end; +end; + +function tbooleanpropertyeditor.getvalues: msestringarty; +begin + setlength(result,2); + result[0]:= falsename; + result[1]:= truename; +end; + +{ tdialogclasspropertyeditor } + +function tdialogclasspropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_dialog,ps_volatile]; +end; + +{ tbitmappropertyeditor } + +procedure tbitmappropertyeditor.edit; +var + bmp,bmp1: tmaskedbitmap; + int1: integer; + mstr1: filenamety; + format1: string; +begin + if imagefilepropedit(mstr1,format1) = mr_ok then begin + bmp:= tmaskedbitmap.create(bmk_rgb); + try + bmp.options:= bmp.options + [bmo_storeorigformat]; + bmp.loadfromfile(mstr1,format1,[]); + for int1:= 0 to high(fprops) do begin + bmp1:= tmaskedbitmap(getpointervalue(int1)); + if bmp1 <> nil then begin + bmp.alignment:= bmp1.alignment; + bmp.colorbackground:= bmp1.colorbackground; + bmp.colorforeground:= bmp1.colorforeground; + bmp.opacity:= bmp1.opacity; + bmp.transparentcolor:= bmp1.transparentcolor; + end; + setpointervalue(int1,bmp); + end; + modified; + finally + bmp.Free; + end; + end; +end; + +function tbitmappropertyeditor.getvalue: msestring; +begin + with tmaskedbitmap(getpointervalue) do begin + if source <> nil then begin + result:= msestring(fdesigner.getcomponentname(source)); + end + else begin + if isempty then begin + result:= ''; + end + else begin + result:= inherited getvalue; + end; + end; + end; +end; + +procedure tbitmappropertyeditor.setvalue(const value: msestring); +var + int1: integer; +begin + if value = '' then begin + for int1:= 0 to high(fprops) do begin + tmaskedbitmap(getpointervalue(int1)).clear; + end; + modified; + end; +end; + +{ trealpropertyeditor } + +function trealpropertyeditor.allequal: boolean; +var + int1: integer; + rea1: real; +begin + result:= inherited allequal; + if not result then begin + result:= true; + rea1:= getfloatvalue; + for int1:= 1 to high(fprops) do begin + if rea1 <> getfloatvalue(int1) then begin + result:= false; + break; + end; + end; + end; +end; + +procedure trealpropertyeditor.setvalue(const value: msestring); +begin + setfloatvalue(strtoreal(value)); +end; + +function trealpropertyeditor.getvalue: msestring; +begin + result:= msestring(realtostr(getfloatvalue)); +end; + +{ tcurrencypropertyeditor } + +function tcurrencypropertyeditor.allequal: boolean; +var + int1: integer; + cu1: currency; +begin + result:= inherited allequal; + if not result then begin + result:= true; + cu1:= getcurrencyvalue; + for int1:= 1 to high(fprops) do begin + if cu1 <> getcurrencyvalue(int1) then begin + result:= false; + break; + end; + end; + end; +end; + +procedure tcurrencypropertyeditor.setvalue(const value: msestring); +begin + setcurrencyvalue(strtoreal(value)); +end; + +function tcurrencypropertyeditor.getvalue: msestring; +begin + result:= currencytostrmse(getcurrencyvalue); +end; + +{ trealtypropertyeditor } + +function trealtypropertyeditor.allequal: boolean; +var + int1: integer; + rea1: real; +begin + result:= inherited allequal; + if not result then begin + result:= true; + rea1:= getfloatvalue; + for int1:= 1 to high(fprops) do begin + if rea1 <> getfloatvalue(int1) then begin + result:= false; + break; + end; + end; + end; +end; + +function trealtypropertyeditor.getvalue: msestring; +begin + result:= realtytostring(getfloatvalue); +end; + +procedure trealtypropertyeditor.setvalue(const value: msestring); +begin + setfloatvalue(strtorealty(value)); +end; + +{ tdatetimepropertyeditor } + +function tdatetimepropertyeditor.allequal: boolean; +var + int1: integer; + rea1: real; +begin + result:= inherited allequal; + if not result then begin + result:= true; + rea1:= getfloatvalue; + for int1:= 1 to high(fprops) do begin + if rea1 <> getfloatvalue(int1) then begin + result:= false; + break; + end; + end; + end; +end; + +function tdatetimepropertyeditor.getvalue: msestring; +var + rea1: real; +begin +// result:= datetimetostring(getfloatvalue,'dddddd t'); + rea1:= getfloatvalue; + if rea1 = emptydatetime then begin + result:= ''; + end + else begin + if trunc(rea1) = 0 then begin + result:= datetimetostring(getfloatvalue,'hh:nn:ss'); + end + else begin + if frac(rea1) = 0 then begin + result:= datetimetostring(getfloatvalue,'yyyy-mm-dd'); + end + else begin + result:= datetimetostring(getfloatvalue,'yyyy-mm-dd hh:nn:ss'); + end; + end; + end; +end; + +procedure tdatetimepropertyeditor.setvalue(const value: msestring); + + function encdate(const str: msestring): real; + var + ar2: msestringarty; + year,month,day: word; + begin + result:= 0; + ar2:= splitstring(str,msechar('-')); + if high(ar2) >= 0 then begin + year:= strtoint(ar2[0]); + month:= 1; + day:= 1; + if high(ar2) > 0 then begin + month:= strtoint(ar2[1]); + if high(ar2) > 1 then begin + day:= strtoint(ar2[2]); + end; + end; + end + else begin + raise exception.create(ansistring(mo.c[ord(emptydate)]+'.')); + end; + result:= encodedate(year,month,day); + end; + + function enctime(const str: msestring): real; + var + ar2: msestringarty; + hour,minute,second: word; + begin + result:= 0; + ar2:= splitstring(str,msechar(':'),true); + if high(ar2) >= 0 then begin + hour:= strtoint(ar2[0]); + minute:= 0; + second:= 0; + if high(ar2) > 0 then begin + minute:= strtoint(ar2[1]); + if high(ar2) > 1 then begin + second:= strtoint(ar2[2]); + end; + end; + result:= encodetime(hour,minute,second,0); + end + else begin + raise exception.create(ansistring(mo.c[ord(emptytime)]+'.')); + end; + end; + +var + rea1,rea2: real; + ar1: msestringarty; + +begin + if value = '' then begin + rea1:= emptydatetime; + end + else begin + if value = ' ' then begin + rea1:= nowlocal; + end + else begin + rea1:= 0; + rea2:= 0; + ar1:= splitstring(value,msechar(' '),true); + if high(ar1) > 0 then begin + rea1:= encdate(ar1[0]); + rea2:= enctime(ar1[1]); + end + else begin + try + rea1:= encdate(ar1[0]); + except + rea1:= enctime(ar1[0]); + end; + end; + rea1:= rea1 + rea2; + end; + end; + setfloatvalue(rea1); +end; + +{ tvariantpropertyeditor } + +function tvariantpropertyeditor.allequal: boolean; +var + int1: integer; + var1: variant; +begin + result:= inherited allequal; + if not result then begin + result:= true; + var1:= getvariantvalue; + for int1:= 1 to high(fprops) do begin + if var1 <> getvariantvalue(int1) then begin + result:= false; + break; + end; + end; + end; +end; + +procedure tvariantpropertyeditor.setvalue(const value: msestring); +var + var1: variant; +begin + if value = '' then begin + fillchar(var1,sizeof(var1),0); + setvariantvalue(var1); + end + else begin + setvariantvalue(value); + end; +end; + +function tvariantpropertyeditor.getvalue: msestring; +var + var1: variant; +begin + var1:= getvariantvalue; + result:= ''; + if not varisnull(var1) then begin + try + result:= var1; + except + end; + end; +end; + +{ tshortcutpropertyeditor } + +constructor tshortcutpropertyeditor.create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypeinfo: ptypeinfo); +begin + fsc1:= pos('shortcut1',aprops[0].propinfo^.name) = 1; + inherited; +end; + +function tshortcutpropertyeditor.getvaluetext( + const avalue: shortcutty): msestring; +{ +var + int1,int2: integer; + keys: integerarty; + names: msestringarty; +} +begin + result:= getshortcutname(avalue); +{ + int2:= avalue; + if int2 = 0 then begin + result:= ''; + end + else begin + getshortcutlist(keys,names); + for int1:= 0 to high(keys) do begin + if int2 = keys[int1] then begin + result:= names[int1]; + exit; + end; + end; + result:= '$'+intvaluetostr(int2,nb_hex,16); + end; +} +end; + +procedure tshortcutpropertyeditor.setvalue(const value: msestring); +var + ar1: msestringarty; + ar2: shortcutarty; + int1: integer; + intf1: iactionlink; + p1: pointer; +begin + ar1:= splitstring(value,widechar(' ')); + setlength(ar2,length(ar1)); + for int1:= 0 to high(ar1) do begin + ar2[int1]:= texttovalue(ar1[int1]); + end; + for int1:= 0 to high(fprops) do begin + if getcorbainterface(fprops[int1].instance,typeinfo(iactionlink), + intf1) then begin + with intf1.getactioninfopo^ do begin + if fsc1 then begin + intf1.setshortcuts1(ar2); + end + else begin + intf1.setshortcuts(ar2); + end; + end; + modified; + end + else begin + if fscar then begin + p1:= getpointervalue(); + shortcutarty(p1):= ar2; //decref/incref + setpointervalue(p1); + end + else begin + if high(ar2) = 0 then begin + setordvalue(ar2[0]); + end + else begin + setordvalue(int1,0); + end; + end; + end; + end; +end; + +function tshortcutpropertyeditor.getvalue: msestring; + + function getartext(const ashortcuts: shortcutarty): msestring; + var + i1: integer; + begin + result:= ''; + for i1:= 0 to high(ashortcuts) do begin + result:= result + getvaluetext(ashortcuts[i1]) + ' '; + end; + if result <> '' then begin + setlength(result,length(result)-1); + end; + end; //getartext + +var + ar1: shortcutarty; + intf1: iactionlink; +begin + result:= ''; + if getcorbainterface(fprops[0].instance,typeinfo(iactionlink),intf1) then begin + with intf1.getactioninfopo^ do begin + if self.fsc1 then begin + ar1:= shortcut1; + end + else begin + ar1:= shortcut; + end; + result:= getartext(ar1); + end; + end + else begin + if fscar then begin + ar1:= shortcutarty(getpointervalue); + result:= getartext(ar1); + end + else begin + result:= getvaluetext(getordvalue); + end; + end; +end; + +function tshortcutpropertyeditor.getvalues: msestringarty; +var + keys: integerarty; + names: msestringarty; +begin + getshortcutlist(keys,names); + result:= names; +end; + +function tshortcutpropertyeditor.texttovalue(const atext: msestring): shortcutty; +var + int1: integer; + keys: integerarty; + s1: msestring; + names: msestringarty; +begin + getshortcutlist(keys,names); + s1:= strlowercase(atext); + for int1:= 0 to high(names) do begin + if s1 = strlowercase(names[int1]) then begin + result:= keys[int1]; + exit; + end; + end; + if atext = '' then begin + result:= 0; + end + else begin + result:= strtointvalue(atext,nb_hex); + end; +end; +{ +procedure tshortcutpropertyeditor.setvalue(const value: msestring); +begin + setordvalue(texttovalue(value)); +end; +} +{ tshortcutarpropertyeditor } + +constructor tshortcutarpropertyeditor.create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypeinfo: ptypeinfo); +begin + fscar:= true; + inherited; +end; + + { tcolorpropertyeditorty} + +function tcolorpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_dialog]; +end; + +procedure tcolorpropertyeditor.edit; +var + col1: colorty; +begin + col1:= getordvalue; + if colordialog(col1) = mr_ok then begin + setordvalue(col1); + end; +end; + +function tcolorpropertyeditor.getvalue: msestring; +begin + result:= msestring(colortostring(getordvalue)); +end; + +function tcolorpropertyeditor.getvalues: msestringarty; +begin + result:= getcolornames; +end; + +procedure tcolorpropertyeditor.setvalue(const value: msestring); +begin + setordvalue(stringtocolor(ansistring(value))); +end; + +{ tstringspropertyeditor } + +procedure tstringspropertyeditor.closequery(const sender: tcustommseform; var amodalresult: modalresultty); +var + int1: integer; +begin + if amodalresult = mr_ok then begin + try + with tstringlisteditor(sender),tstrings(getpointervalue) do begin + beginupdate; + try + clear; + for int1:= 0 to grid.rowcount-1 do begin + Add(ansistring(valueedit[int1])); + end; + finally + endupdate + end; + end; + modified; + except + application.handleexception(nil); + amodalresult:= mr_none; + end; + end; +end; + +procedure tstringspropertyeditor.edit; +var + editform: tstringlisteditor; + int1: integer; + strings: tstrings; +begin + strings:= tstrings(getpointervalue); + editform:= tstringlisteditor.create({$ifdef FPC}@{$endif}closequery); + try + with editform do begin + grid.rowcount:= strings.Count; + for int1:= 0 to strings.Count - 1 do begin + valueedit[int1]:= msestring(strings[int1]); + end; + show(true,nil); + end; + finally + editform.Free; + end; +end; + +function tstringspropertyeditor.getvalue: msestring; +begin + if tstrings(getpointervalue).count = 0 then begin + result:= ''; + end + else begin + result:= inherited getvalue; + end; +end; + +{ ttextstringspropertyeditor } + +procedure ttextstringspropertyeditor.closequery(const sender: tcustommseform; + var amodalresult: modalresultty); +var + int1: integer; + utf8: boolean; + str1: ansistring; + backup: string; + backupm: msestringarty; +begin + fmodalresult:= amodalresult; + forigtext:= nil; + if (amodalresult = mr_ok) or (amodalresult = mr_canclose) then begin + try + with tmsetexteditorfo(sender) do begin + forigtext:= textedit.datalist.asmsestringarray; + try + if ismsestring then begin + with tmsestringdatalist(getpointervalue) do begin + backupm:= asarray; + beginupdate; + try + clear; + for int1:= 0 to grid.rowcount-1 do begin + add(textedit[int1]); + end; + finally + endupdate + end; + end; + end + else begin + with tstrings(getpointervalue) do begin + backup:= text; + utf8:= getutf8; + beginupdate; + try + clear; + for int1:= 0 to grid.rowcount-1 do begin + if utf8 then begin + str1:= stringtoutf8ansi(textedit[int1]); + end + else begin + str1:= ansistring(textedit[int1]); + end; + updateline(str1); + add(str1); + end; + finally + endupdate + end; + end; + end; + doafterclosequery(amodalresult); + finally + if amodalresult = mr_canclose then begin + if ismsestring then begin + with tmsestringdatalist(getpointervalue) do begin + asarray:= backupm; + end; + end + else begin + with tstrings(getpointervalue) do begin + text:= backup; + end; + end; + end; + end; + end; + except + application.handleexception(nil); +// if amodalresult = mr_canclose then begin + amodalresult:= mr_none; +// end; + end; + end; +end; + +procedure ttextstringspropertyeditor.edit; +var + editform: tmsetexteditorfo; + int1: integer; + strings: tstrings; + mstrings: tmsestringdatalist; + utf8: boolean; +begin + fmodalresult:= mr_cancel; + editform:= tmsetexteditorfo.create({$ifdef FPC}@{$endif}closequery, + msetexteditor.syntaxpainter,getsyntaxindex,gettestbutton); + editform.textedit.createfont; + editform.textedit.font.assign(textpropertyfont); + utf8:= getutf8; + try + with editform do begin + caption:= getcaption; + if ismsestring then begin + mstrings:= tmsestringdatalist(getpointervalue); + grid.rowcount:= mstrings.Count; + for int1:= 0 to mstrings.Count - 1 do begin + textedit[int1]:= mstrings[int1]; + end; + end + else begin + strings:= tstrings(getpointervalue); + grid.rowcount:= strings.Count; + for int1:= 0 to strings.Count - 1 do begin + if utf8 then begin + textedit[int1]:= utf8tostringansi(strings[int1]); + end + else begin + textedit[int1]:= msestring(strings[int1]); + end; + end; + end; + if show(true,nil) = mr_ok then begin + modified; + end; + end; + finally + editform.Free; + end; +end; + +function ttextstringspropertyeditor.getvalue: msestring; +begin + if ismsestring then begin + if tmsestringdatalist(getpointervalue).count = 0 then begin + result:= ''; + end + else begin + result:= inherited getvalue; + end; + end + else begin + if tstrings(getpointervalue).count = 0 then begin + result:= ''; + end + else begin + result:= inherited getvalue; + end; + end; +end; + +function ttextstringspropertyeditor.getsyntaxindex: integer; +begin + result:= -1; +end; + +procedure ttextstringspropertyeditor.doafterclosequery(var amodalresult: modalresultty); +begin + //dummy +end; + +function ttextstringspropertyeditor.gettestbutton: boolean; +begin + result:= false; +end; + +function ttextstringspropertyeditor.getutf8: boolean; +begin + result:= false; +end; + +procedure ttextstringspropertyeditor.setvalue(const avalue: msestring); +begin + if (avalue = '') and askok(mo.c[ord(wishclear)]+' "'+fname+'"?') then begin + if ismsestring then begin + tmsestringdatalist(getpointervalue).clear; + end + else begin + tstrings(getpointervalue).clear; + end; + end; + inherited; +end; + +function ttextstringspropertyeditor.getcaption: msestring; +begin + result:= mo.c[ord(texteditor)]; +end; + +procedure ttextstringspropertyeditor.updateline(var aline: ansistring); +begin + //dummy +end; + +function ttextstringspropertyeditor.ismsestring: boolean; +begin + result:= false; +end; + +{ tdatalistpropertyeditor } + +procedure tdatalistpropertyeditor.checkformkind; +var + datalist1: tdatalist; +begin + formkind:= lfk_none; + datalist1:= tdatalist(getpointervalue); + if datalist1 is tmsestringdatalist then begin + formkind:= lfk_msestring; + end + else begin + if datalist1 is trealdatalist then begin + formkind:= lfk_real; + end + else begin + if datalist1 is tintegerdatalist then begin + formkind:= lfk_integer; + end + else begin + if datalist1 is tmsestringintdatalist then begin + formkind:= lfk_msestringint; + end + else begin + if datalist1 is tcomplexdatalist then begin + formkind:= lfk_complex; + end + end; + end; + end; + end; +end; + +procedure tdatalistpropertyeditor.edit; +var + editform: tcustommseform; + realdata: trealdatalist; + complexdata: tcomplexdatalist; +begin + checkformkind; + case formkind of + lfk_msestring: begin + editform:= tstringlisteditor.create({$ifdef FPC}@{$endif}closequery); + end; + lfk_real: begin + editform:= treallisteditor.create({$ifdef FPC}@{$endif}closequery); + end; + lfk_integer: begin + editform:= tintegerlisteditor.create({$ifdef FPC}@{$endif}closequery); + end; + lfk_msestringint: begin + editform:= tmsestringintlisteditor.create({$ifdef FPC}@{$endif}closequery); + end; + lfk_complex: begin + editform:= tdoublereallisteditor.create({$ifdef FPC}@{$endif}closequery); + end; + else begin + editform:= nil; + end; + end; + try + if editform <> nil then begin + case formkind of + lfk_msestring: begin + tstringlisteditor(editform).valueedit.datalist.assign( + tmsestringdatalist(getpointervalue)); + end; + lfk_real: begin + realdata:= trealdatalist(getpointervalue); + with treallisteditor(editform).valueedit do begin + griddata.assign(realdata); + if realdata.defaultzero then begin + valuedefault:= 0; + end; + valuemin:= realdata.min; + valuemax:= realdata.max; + end; + end; + lfk_integer: begin + tintegerlisteditor(editform).valueedit.griddata.assign( + tintegerdatalist(getpointervalue)); + end; + lfk_msestringint: begin + with tmsestringintlisteditor(editform) do begin + texta.assigncol(tmsestringdatalist(getpointervalue)); + tmsestringintdatalist(getpointervalue).assigntob(textb.griddata); + end; + end; + lfk_complex: begin + complexdata:= tcomplexdatalist(getpointervalue); + with tdoublereallisteditor(editform) do begin + complexdata.assigntoa(vala.griddata); + complexdata.assigntob(valb.griddata); + if complexdata.defaultzero then begin + vala.valuedefault:= 0; + valb.valuedefault:= 0; + end; + vala.valuemin:= complexdata.min; + vala.valuemax:= complexdata.max; + valb.valuemin:= vala.valuemin; + valb.valuemax:= vala.valuemax; + end; + end; + end; + editform.show(true,nil); + end; + finally + editform.Free; + end; +end; + +function tdatalistpropertyeditor.getvalue: msestring; +var + datalist1: tdatalist; +begin + datalist1:= tdatalist(getpointervalue); + if datalist1 = nil then begin + result:= ''; + end + else begin + if datalist1.count = 0 then begin + result:= ''; + end + else begin + result:= msestring('<'+datalist1.classname+'>'); + end; + end; +end; + +procedure tdatalistpropertyeditor.closequery(const sender: tcustommseform; + var amodalresult: modalresultty); +var + datalist1: tdatalist; + int1: integer; +begin + if amodalresult = mr_ok then begin + try + for int1:= 0 to high (fprops) do begin + datalist1:= tdatalist(getpointervalue(int1)); + case formkind of + lfk_msestring: begin + tmsestringdatalist(datalist1).assign( + tstringlisteditor(sender).valueedit.datalist); + end; + lfk_real: begin + trealdatalist(datalist1).assign( + treallisteditor(sender).valueedit.griddata); + end; + lfk_integer: begin + tintegerdatalist(datalist1).assign( + tintegerlisteditor(sender).valueedit.griddata); + end; + lfk_msestringint: begin + with tmsestringintlisteditor(sender) do begin + tmsestringintdatalist(datalist1).assign(texta.griddata); + tmsestringintdatalist(datalist1).assignb(textb.griddata); + end; + end; + lfk_complex: begin + with tdoublereallisteditor(sender) do begin + tcomplexdatalist(datalist1).assign(vala.griddata); + tcomplexdatalist(datalist1).assignb(valb.griddata); + end; + end; + end; + modified; + end; + except + application.handleexception(nil); + amodalresult:= mr_none; + end; + end; +end; + +function tdatalistpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate; + checkdatalistnostreaming(self,result); +end; + +{ tmsestringdatalistpropertyeditor } + +procedure tmsestringdatalistpropertyeditor.closequery(const sender: tcustommseform; + var amodalresult: modalresultty); +var + int1: integer; +begin + if amodalresult = mr_ok then begin + for int1:= 0 to high(fprops) do begin + try + tmsestringdatalist(getpointervalue(int1)).assign( + tstringlisteditor(sender).valueedit.datalist); + modified; + except + application.handleexception(nil); + amodalresult:= mr_none; + end; + end; + end; +end; + +procedure tmsestringdatalistpropertyeditor.edit; +var + editform: tstringlisteditor; +begin + editform:= tstringlisteditor.create({$ifdef FPC}@{$endif}closequery); + try + with editform do begin + valueedit.datalist.assign(tmsestringdatalist(getpointervalue)); + valueedit.editpos:= mgc(bigint,bigint); + show(true,nil); + end; + finally + editform.Free; + end; +end; + +function tmsestringdatalistpropertyeditor.getvalue: msestring; +begin + if tmsestringdatalist(getpointervalue).count = 0 then begin + result:= ''; + end + else begin + result:= inherited getvalue; + end; +end; + +function tmsestringdatalistpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate; + checkdatalistnostreaming(self,result); +end; + +{ tdoublemsestringdatalistpropertyeditor } + +procedure tdoublemsestringdatalistpropertyeditor.closequery( + const sender: tcustommseform; var amodalresult: modalresultty); +var + list: tdoublemsestringdatalist; +begin + if amodalresult = mr_ok then begin + try + with tdoublestringlisteditor(sender) do begin + {$warnings off} + list:= tdoublemsestringdatalist.create; + {$warnings on} + try + list.assign(texta.griddata); + list.assignb(textb.griddata); + tdoublemsestringdatalist(getpointervalue).assign(list); + modified; + finally + list.Free; + end; + end; + except + application.handleexception(nil); + amodalresult:= mr_none; + end; + end; +end; + +procedure tdoublemsestringdatalistpropertyeditor.edit; +var + editform: tdoublestringlisteditor; +begin + editform:= tdoublestringlisteditor.create({$ifdef FPC}@{$endif}closequery); + try + with editform do begin + texta.assigncol(tmsestringdatalist(getpointervalue)); + tdoublemsestringdatalist(getpointervalue).assigntob(textb.griddata); + show(true,nil); + end; + finally + editform.Free; + end; +end; + +function tdoublemsestringdatalistpropertyeditor.getvalue: msestring; +begin + if tdoublemsestringdatalist(getpointervalue).count = 0 then begin + result:= ''; + end + else begin + result:= inherited getvalue; + end; +end; + +function tdoublemsestringdatalistpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate; + checkdatalistnostreaming(self,result); +end; + +{ tmsestringintdatalistpropertyeditor } + +procedure tmsestringintdatalistpropertyeditor.closequery( + const sender: tcustommseform; var amodalresult: modalresultty); +var + list: tmsestringintdatalist; +begin + if amodalresult = mr_ok then begin + try + with tmsestringintlisteditor(sender) do begin +{$warnings off} + list:= tmsestringintdatalist.create; +{$warnings on} + try + list.assign(texta.griddata); + list.assignb(textb.griddata); + tmsestringintdatalist(getpointervalue).assign(list); + modified; + finally + list.Free; + end; + end; + except + application.handleexception(nil); + amodalresult:= mr_none; + end; + end; +end; + +procedure tmsestringintdatalistpropertyeditor.edit; +var + editform: tmsestringintlisteditor; +begin + editform:= tmsestringintlisteditor.create({$ifdef FPC}@{$endif}closequery); + try + with editform do begin + texta.assigncol(tmsestringdatalist(getpointervalue)); + tmsestringintdatalist(getpointervalue).assigntob(textb.griddata); + show(true,nil); + end; + finally + editform.Free; + end; +end; + +function tmsestringintdatalistpropertyeditor.getvalue: msestring; +begin + if tmsestringintdatalist(getpointervalue).count = 0 then begin + result:= ''; + end + else begin + result:= inherited getvalue; + end; +end; + +function tmsestringintdatalistpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate; + checkdatalistnostreaming(self,result); +end; + +{ trecordpropertyeditor } + +constructor trecordpropertyeditor.create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; const aname: string; + const subprops: propertyeditorarty); +var + int1: integer; +begin + inherited create(adesigner,amodule,acomponent,aobjectinspector,nil,nil); + fname:= msestring(aname); + fsubproperties:= subprops; + for int1:= 0 to high(fsubproperties) do begin + with fsubproperties[int1] do begin + include(fstate,ps_owned); + fparenteditor:= self; + end; + end; +end; + +function trecordpropertyeditor.allequal: boolean; +begin + result:= true; +end; + + +destructor trecordpropertyeditor.destroy; +var + int1: integer; +begin + for int1:= 0 to high(fsubproperties) do begin + fsubproperties[int1].Free; + end; + inherited; +end; + +function trecordpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= [ps_subproperties]; +end; + +function trecordpropertyeditor.getvalue: msestring; +begin + result:= '_'; +end; + +function trecordpropertyeditor.subproperties: propertyeditorarty; +begin + result:= fsubproperties; +end; + +procedure trecordpropertyeditor.setsubprop; +var + int1: integer; +begin + inherited; + for int1:= 0 to high(fsubproperties) do begin + include(fsubproperties[int1].fstate,ps_subprop); + end; +end; + +{ tconstelementeditor } + +constructor tconstelementeditor.create(const avalue: msestring; aindex: integer; + aparenteditor: tarraypropertyeditor; aeditorclass: propertyeditorclassty; + const adesigner: idesigner; const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypinfo: ptypeinfo); +begin + fvalue:= avalue; + inherited create(aindex,aparenteditor,aeditorclass,adesigner,aobjectinspector, + aprops,atypinfo); +end; + +function tconstelementeditor.getvalue: msestring; +begin + result:= fvalue; +end; + +procedure tconstelementeditor.dragdrop(const sender: tpropertyeditor); +begin + if (sender is tarrayelementeditor) and + (tarrayelementeditor(sender).fparenteditor = fparenteditor) then begin +// sender.modified; +// modified; + tarraypropertyeditor(fparenteditor).itemmoved( + tarrayelementeditor(sender).findex,findex); + end; +end; + +{ tnamepropertyeditor } + +procedure tnamepropertyeditor.setvalue(const value: msestring); +begin + if (value <> '') and not isvalidident(ansistring(value)) then begin + raise exception.create( + ansistring(mo.c[ord(invalidcomponentname)]+' '''+value+'''.')); + end; + inherited; +end; + +{ trefreshstringpropertyeditor } + +function trefreshstringpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_refresh]; +end; + +{ tvolatilebooleanpropertyeditor } + +function tvolatilebooleanpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_volatile]; +end; + +{ trefreshbooleanpropertyeditor } + +function trefreshbooleanpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_refresh]; +end; + +{ tcomponentinterfacepropertyeditor } + +function tcomponentinterfacepropertyeditor.filtercomponent( + const acomponent: tcomponent): boolean; +var + po1: pointer; +begin + result:= getcorbainterface(acomponent,fintfinfo,po1); +end; + +procedure tcomponentinterfacepropertyeditor.updatedefaultvalue; +begin + fintfinfo:= getintfinfo; +end; + +{ toptionaldatalistpropertyeditor } + +function toptionaldatalistpropertyeditor.getniltext: msestring; +begin + result:= ''; +end; + +function toptionaldatalistpropertyeditor.getinstance: tpersistent; +begin + result:= tpersistent(getpointervalue); +end; + +procedure toptionaldatalistpropertyeditor.deleteinstance; +begin + if checkfreeoptionalclass then begin + setordvalue(0); + end; +end; + +function toptionaldatalistpropertyeditor.canrevert: boolean; +begin + result:= false; +end; + +procedure toptionaldatalistpropertyeditor.setvalue(const avalue: msestring); +begin + if avalue = '' then begin + deleteinstance; + end + else begin + inherited; + end; +end; + +function toptionaldatalistpropertyeditor.getvalue: msestring; +begin + if getinstance = nil then begin + result:= getniltext; + end + else begin + result:= inherited getvalue; + end; +end; + +procedure toptionaldatalistpropertyeditor.edit; +var + obj1: tobject; +begin + obj1:= getinstance; + if obj1 = nil then begin + setordvalue(1); + end; + inherited; +end; + +function toptionaldatalistpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_dialog]; +end; + +{ tvolatilesetpropertyeditor } + +function tvolatilesetpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_volatile]; +end; + +constructor tvolatilesetpropertyeditor.create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypeinfo: ptypeinfo); +begin + inherited; +end; + +initialization +// apropertyeditors:= tpropertyeditors.Create; + application.createdatamodule(tmsepropertyeditorsmo,mo); +finalization + freeandnil(fpropertyeditors); + freeandnil(ftextpropertyfont); +end. diff --git a/mseide-msegui/lib/common/designutils/msepropertyeditorsmodule.mfm b/mseide-msegui/lib/common/designutils/msepropertyeditorsmodule.mfm new file mode 100644 index 0000000..812d4b3 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msepropertyeditorsmodule.mfm @@ -0,0 +1,28 @@ +object msepropertyeditorsmo: tmsepropertyeditorsmo + bounds_cx = 100 + bounds_cy = 100 + left = 100 + top = 100 + moduleclassname = 'tmsedatamodule' + object c: tstringcontainer + strings.data = ( + 'Open image file' + 'Invalid set item' + 'Unknown' + 'Wrong property value' + 'Invalid method name' + 'Method name' + 'exists' + 'Do you wish to destroy' + 'Do you wish to delete items' + 'to' + 'Empty date' + 'Empty time' + 'Do you wish to clear' + 'Texteditor' + 'Invalid component name' + ) + left = 32 + top = 40 + end +end diff --git a/mseide-msegui/lib/common/designutils/msepropertyeditorsmodule.pas b/mseide-msegui/lib/common/designutils/msepropertyeditorsmodule.pas new file mode 100644 index 0000000..3180753 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msepropertyeditorsmodule.pas @@ -0,0 +1,32 @@ +unit msepropertyeditorsmodule; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseglob,mseapplication,mseclasses,msedatamodules,msestringcontainer,msestrings; + +type + stringconststy = ( + openimagefile, //0 Open image file + invalidsetitem, //1 Invalid set item + unknown, //2 Unknown + wrongpropertyvalue, //3 Wrong property value + invalidmethodname, //4 Invalid method name + str_methodname, //5 Method name + exists, //6 exists + wishdestroy, //7 Do you wish to destroy + wishdelete, //8 Do you wish to delete items + str_to, //9 to + emptydate, //10 Empty date + emptytime, //11 Empty time + wishclear, //12 Do you wish to clear + texteditor, //13 Texteditor + invalidcomponentname //14 Invalid component name + ); + + tmsepropertyeditorsmo = class(tmsedatamodule) + c: tstringcontainer; + end; +implementation +uses + msepropertyeditorsmodule_mfm; +end. diff --git a/mseide-msegui/lib/common/designutils/msepropertyeditorsmodule_mfm.pas b/mseide-msegui/lib/common/designutils/msepropertyeditorsmodule_mfm.pas new file mode 100644 index 0000000..21724a1 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msepropertyeditorsmodule_mfm.pas @@ -0,0 +1,38 @@ +unit msepropertyeditorsmodule_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msepropertyeditorsmodule; + +const + objdata: record size: integer; data: array[0..413] of byte end = + (size: 414; data: ( + 84,80,70,48,21,116,109,115,101,112,114,111,112,101,114,116,121,101,100,105, + 116,111,114,115,109,111,20,109,115,101,112,114,111,112,101,114,116,121,101,100, + 105,116,111,114,115,109,111,9,98,111,117,110,100,115,95,99,120,2,100,9, + 98,111,117,110,100,115,95,99,121,2,100,4,108,101,102,116,2,100,3,116, + 111,112,2,100,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101, + 6,14,116,109,115,101,100,97,116,97,109,111,100,117,108,101,0,16,116,115, + 116,114,105,110,103,99,111,110,116,97,105,110,101,114,1,99,12,115,116,114, + 105,110,103,115,46,100,97,116,97,1,6,15,79,112,101,110,32,105,109,97, + 103,101,32,102,105,108,101,6,16,73,110,118,97,108,105,100,32,115,101,116, + 32,105,116,101,109,6,7,85,110,107,110,111,119,110,6,20,87,114,111,110, + 103,32,112,114,111,112,101,114,116,121,32,118,97,108,117,101,6,19,73,110, + 118,97,108,105,100,32,109,101,116,104,111,100,32,110,97,109,101,6,11,77, + 101,116,104,111,100,32,110,97,109,101,6,6,101,120,105,115,116,115,6,22, + 68,111,32,121,111,117,32,119,105,115,104,32,116,111,32,100,101,115,116,114, + 111,121,6,27,68,111,32,121,111,117,32,119,105,115,104,32,116,111,32,100, + 101,108,101,116,101,32,105,116,101,109,115,6,2,116,111,6,10,69,109,112, + 116,121,32,100,97,116,101,6,10,69,109,112,116,121,32,116,105,109,101,6, + 20,68,111,32,121,111,117,32,119,105,115,104,32,116,111,32,99,108,101,97, + 114,6,10,84,101,120,116,101,100,105,116,111,114,6,22,73,110,118,97,108, + 105,100,32,99,111,109,112,111,110,101,110,116,32,110,97,109,101,0,4,108, + 101,102,116,2,32,3,116,111,112,2,40,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tmsepropertyeditorsmo,''); +end. diff --git a/mseide-msegui/lib/common/designutils/msereallisteditor.mfm b/mseide-msegui/lib/common/designutils/msereallisteditor.mfm new file mode 100644 index 0000000..a28ec21 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msereallisteditor.mfm @@ -0,0 +1,111 @@ +object reallisteditor: treallisteditor + visible = False + bounds_x = 182 + bounds_y = 208 + bounds_cx = 128 + bounds_cy = 297 + container.bounds = ( + 0 + 0 + 128 + 297 + ) + options = [fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos] + statfile = tstatfile1 + caption = 'Reallisteditor' + moduleclassname = 'tmseform' + object ok: tbutton + taborder = 3 + bounds_x = 4 + bounds_y = 269 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_left, an_bottom] + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + end + object cancel: tbutton + bounds_x = 68 + bounds_y = 269 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_left, an_bottom] + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + end + object grid: twidgetgrid + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 131 + bounds_cy = 241 + anchors = [an_top, an_bottom] + optionsgrid = [og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_wrapcol, og_autopopup] + fixcols.count = 1 + fixcols.items = < + item + width = 24 + numstep = 1 + end> + zebra_start = 1 + zebra_height = 1 + datacols.count = 1 + datacols.items = < + item[valueedit] + width = 101 + options = [co_fill, co_savevalue, co_savestate] + widgetname = 'valueedit' + dataclass = tgridrealdatalist + end> + datarowheight = 16 + onrowcountchanged = gridonrowcountchanged + reffontheight = 14 + object valueedit: trealedit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_colorclient] + frame.dummy = 0 + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 101 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + value = -Inf + valuedefault = -Inf + valuerange = 1 + valuestart = 0 + min = -Inf + max = 1E+038 + reffontheight = 14 + end + end + object rowcount: tintegeredit + frame.caption = 'Rowcount' + frame.captionpos = cp_right + frame.dummy = 0 + frame.outerframe = ( + 0 + 0 + 64 + 0 + ) + taborder = 2 + bounds_x = 4 + bounds_y = 245 + bounds_cx = 116 + anchors = [an_left, an_bottom] + onsetvalue = rowcountonsetvalue + reffontheight = 14 + end + object tstatfile1: tstatfile + filename = 'stringlisteditor.sta' + options = [sfo_memory] + left = 40 + top = 88 + end +end diff --git a/mseide-msegui/lib/common/designutils/msereallisteditor.pas b/mseide-msegui/lib/common/designutils/msereallisteditor.pas new file mode 100644 index 0000000..4d090c3 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msereallisteditor.pas @@ -0,0 +1,61 @@ +{ MSEgui Copyright (c) 1999-2006 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msereallisteditor; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseforms,msedataedits,msesimplewidgets,msewidgetgrid,msegrids,msetextedit, + msestat,msestatfile; + +const + reallisteditorstatname = 'reallisteditor.sta'; + +type + treallisteditor = class(tmseform) + cancel: tbutton; + ok: tbutton; + grid: twidgetgrid; + rowcount: tintegeredit; + valueedit: trealedit; + tstatfile1: tstatfile; + procedure rowcountonsetvalue(const sender: tobject; var avalue: integer; + var accept: boolean); + procedure gridonrowcountchanged(const sender: tcustomgrid); + public + constructor create(const aonclosequery: closequeryeventty); reintroduce; + end; + +implementation +uses + msereallisteditor_mfm,mseglob; + +{ treallisteditor } + +constructor treallisteditor.create(const aonclosequery: closequeryeventty); +begin + inherited create(nil); + onclosequery:= aonclosequery; +end; + +procedure treallisteditor.gridonrowcountchanged( + const sender: tcustomgrid); +begin + rowcount.value:= sender.rowcount; +end; + +procedure treallisteditor.rowcountonsetvalue(const sender: tobject; + var avalue: integer; var accept: boolean); +begin + grid.rowcount:= avalue; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/msereallisteditor_mfm.pas b/mseide-msegui/lib/common/designutils/msereallisteditor_mfm.pas new file mode 100644 index 0000000..9169e3b --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msereallisteditor_mfm.pas @@ -0,0 +1,109 @@ +unit msereallisteditor_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msereallisteditor; + +const + objdata: record size: integer; data: array[0..1831] of byte end = + (size: 1832; data: ( + 84,80,70,48,15,116,114,101,97,108,108,105,115,116,101,100,105,116,111,114, + 14,114,101,97,108,108,105,115,116,101,100,105,116,111,114,7,118,105,115,105, + 98,108,101,8,8,98,111,117,110,100,115,95,120,3,182,0,8,98,111,117, + 110,100,115,95,121,3,208,0,9,98,111,117,110,100,115,95,99,120,3,128, + 0,9,98,111,117,110,100,115,95,99,121,3,41,1,16,99,111,110,116,97, + 105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0,3,128,0,3, + 41,1,0,7,111,112,116,105,111,110,115,11,13,102,111,95,99,108,111,115, + 101,111,110,101,115,99,15,102,111,95,97,117,116,111,114,101,97,100,115,116, + 97,116,16,102,111,95,97,117,116,111,119,114,105,116,101,115,116,97,116,10, + 102,111,95,115,97,118,101,112,111,115,0,8,115,116,97,116,102,105,108,101, + 7,10,116,115,116,97,116,102,105,108,101,49,7,99,97,112,116,105,111,110, + 6,14,82,101,97,108,108,105,115,116,101,100,105,116,111,114,15,109,111,100, + 117,108,101,99,108,97,115,115,110,97,109,101,6,8,116,109,115,101,102,111, + 114,109,0,7,116,98,117,116,116,111,110,2,111,107,8,116,97,98,111,114, + 100,101,114,2,3,8,98,111,117,110,100,115,95,120,2,4,8,98,111,117, + 110,100,115,95,121,3,13,1,9,98,111,117,110,100,115,95,99,120,2,50, + 9,98,111,117,110,100,115,95,99,121,2,20,7,97,110,99,104,111,114,115, + 11,7,97,110,95,108,101,102,116,9,97,110,95,98,111,116,116,111,109,0, + 5,115,116,97,116,101,11,10,97,115,95,100,101,102,97,117,108,116,15,97, + 115,95,108,111,99,97,108,100,101,102,97,117,108,116,15,97,115,95,108,111, + 99,97,108,99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6, + 3,38,79,75,11,109,111,100,97,108,114,101,115,117,108,116,7,5,109,114, + 95,111,107,0,0,7,116,98,117,116,116,111,110,6,99,97,110,99,101,108, + 8,98,111,117,110,100,115,95,120,2,68,8,98,111,117,110,100,115,95,121, + 3,13,1,9,98,111,117,110,100,115,95,99,120,2,50,9,98,111,117,110, + 100,115,95,99,121,2,20,7,97,110,99,104,111,114,115,11,7,97,110,95, + 108,101,102,116,9,97,110,95,98,111,116,116,111,109,0,5,115,116,97,116, + 101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,7, + 99,97,112,116,105,111,110,6,7,38,67,97,110,99,101,108,11,109,111,100, + 97,108,114,101,115,117,108,116,7,9,109,114,95,99,97,110,99,101,108,0, + 0,11,116,119,105,100,103,101,116,103,114,105,100,4,103,114,105,100,8,116, + 97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,3,131,0,9,98,111,117,110,100,115,95,99,121,3,241,0,7,97,110, + 99,104,111,114,115,11,6,97,110,95,116,111,112,9,97,110,95,98,111,116, + 116,111,109,0,11,111,112,116,105,111,110,115,103,114,105,100,11,12,111,103, + 95,114,111,119,109,111,118,105,110,103,15,111,103,95,107,101,121,114,111,119, + 109,111,118,105,110,103,15,111,103,95,114,111,119,105,110,115,101,114,116,105, + 110,103,14,111,103,95,114,111,119,100,101,108,101,116,105,110,103,19,111,103, + 95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101,114,15,111,103, + 95,97,117,116,111,102,105,114,115,116,114,111,119,10,111,103,95,119,114,97, + 112,99,111,108,12,111,103,95,97,117,116,111,112,111,112,117,112,0,13,102, + 105,120,99,111,108,115,46,99,111,117,110,116,2,1,13,102,105,120,99,111, + 108,115,46,105,116,101,109,115,14,1,5,119,105,100,116,104,2,24,7,110, + 117,109,115,116,101,112,2,1,0,0,11,122,101,98,114,97,95,115,116,97, + 114,116,2,1,12,122,101,98,114,97,95,104,101,105,103,104,116,2,1,14, + 100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,1,14,100,97,116, + 97,99,111,108,115,46,105,116,101,109,115,14,7,9,118,97,108,117,101,101, + 100,105,116,1,5,119,105,100,116,104,2,101,7,111,112,116,105,111,110,115, + 11,7,99,111,95,102,105,108,108,12,99,111,95,115,97,118,101,118,97,108, + 117,101,12,99,111,95,115,97,118,101,115,116,97,116,101,0,10,119,105,100, + 103,101,116,110,97,109,101,6,9,118,97,108,117,101,101,100,105,116,9,100, + 97,116,97,99,108,97,115,115,7,17,116,103,114,105,100,114,101,97,108,100, + 97,116,97,108,105,115,116,0,0,13,100,97,116,97,114,111,119,104,101,105, + 103,104,116,2,16,17,111,110,114,111,119,99,111,117,110,116,99,104,97,110, + 103,101,100,7,21,103,114,105,100,111,110,114,111,119,99,111,117,110,116,99, + 104,97,110,103,101,100,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,9,116,114,101,97,108,101,100,105,116,9,118,97,108,117,101,101, + 100,105,116,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107, + 95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,12,102,114, + 97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99, + 111,108,111,114,99,108,105,101,110,116,4,3,0,0,128,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101, + 118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116, + 0,11,102,114,97,109,101,46,100,117,109,109,121,2,0,8,116,97,98,111, + 114,100,101,114,2,1,7,118,105,115,105,98,108,101,8,8,98,111,117,110, + 100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,120,2,101,9,98,111,117,110,100,115,95,99,121,2, + 16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,13,111,101,49,95, + 115,97,118,101,118,97,108,117,101,0,5,118,97,108,117,101,5,0,0,0, + 0,0,0,0,128,255,255,12,118,97,108,117,101,100,101,102,97,117,108,116, + 5,0,0,0,0,0,0,0,128,255,255,10,118,97,108,117,101,114,97,110, + 103,101,2,1,10,118,97,108,117,101,115,116,97,114,116,2,0,3,109,105, + 110,5,0,0,0,0,0,0,0,128,255,255,3,109,97,120,5,245,136,13, + 181,80,153,118,150,125,64,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,8, + 114,111,119,99,111,117,110,116,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,8,82,111,119,99,111,117,110,116,16,102,114,97,109,101,46,99, + 97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,11, + 102,114,97,109,101,46,100,117,109,109,121,2,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,64,2,0,0, + 8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120, + 2,4,8,98,111,117,110,100,115,95,121,3,245,0,9,98,111,117,110,100, + 115,95,99,120,2,116,7,97,110,99,104,111,114,115,11,7,97,110,95,108, + 101,102,116,9,97,110,95,98,111,116,116,111,109,0,10,111,110,115,101,116, + 118,97,108,117,101,7,18,114,111,119,99,111,117,110,116,111,110,115,101,116, + 118,97,108,117,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,0,9,116,115,116,97,116,102,105,108,101,10,116,115,116,97,116,102, + 105,108,101,49,8,102,105,108,101,110,97,109,101,6,20,115,116,114,105,110, + 103,108,105,115,116,101,100,105,116,111,114,46,115,116,97,7,111,112,116,105, + 111,110,115,11,10,115,102,111,95,109,101,109,111,114,121,0,4,108,101,102, + 116,2,40,3,116,111,112,2,88,0,0,0) + ); + +initialization + registerobjectdata(@objdata,treallisteditor,''); +end. diff --git a/mseide-msegui/lib/common/designutils/mseresourcetools.pas b/mseide-msegui/lib/common/designutils/mseresourcetools.pas new file mode 100644 index 0000000..89989e2 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseresourcetools.pas @@ -0,0 +1,163 @@ +{ MSEgui Copyright (c) 2004-2008 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseresourcetools; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msetypes,msestrings,sysutils,classes,mclasses,mseparser; + +function rsjgetconsts(const astream: tstream): constinfoarty; +procedure resourcetexttoresourcesource(const sourcefilename: filenamety; + const unitname: string; const fpcformat: boolean); + //FPC resourcestringtable to resourceunit +implementation +uses + mseformdatatools,msefileutils,msestream,msesys,typinfo, + mseclasses,msejson; + +const + destfileext = '.pas'; + dataname = 'resourcedata'; + +procedure rsjarraystart(var adata; const acount: int32); +begin + setlength(constinfoarty(adata),acount); +end; + +procedure rsjarrayitem(var adata; const aindex: int32; + const avalue: jsonvaluety); +begin + with constinfoarty(adata)[aindex] do begin + name:= stringtoutf8ansi(jsonasstring(avalue,['name'])); + value:= jsonasstring(avalue,['value']); + hash:= jsonasint32(avalue,['hash']); + valuetype:= vawstring; + end; +end; + +function rsjgetconsts(const astream: tstream): constinfoarty; +var + json: tjsoncontainer; +begin + json:= nil; + try + try + json:= tjsoncontainer.create(astream.readdatastring); + json.iteratearray(['strings'],result,@rsjarraystart,@rsjarrayitem); + except + on e: exception do begin + if astream is tmsefilestream then begin + e.message:= ansistring(tmsefilestream(astream).filename)+':'+lineend+e.message; + end; + raise; + end; + end; + finally + json.free(); + end; +end; + +procedure resourcetexttoresourcesource(const sourcefilename: filenamety; + const unitname: string; const fpcformat: boolean); +var + instream: ttextstream; + outstream: ttextstream; + outfilename: filenamety; +// mstr1: msestring; + scanner: tscanner; + parser: tparser; + ar1: constinfoarty; + int1: integer; + int2: integer; + str1: string; +// po1: pbyte; +begin + instream:= ttextstream.create(sourcefilename,fm_read); + try + if fpcformat and (fileext(sourcefilename) = 'rsj') then begin + ar1:= rsjgetconsts(instream); + end + else begin + scanner:= nil; + parser:= nil; + try + scanner:= tpascalscanner.Create; + scanner.source:= instream.readdatastring; + if fpcformat then begin + parser:= tfpcresstringparser.create(nil); + end + else begin + parser:= tresstringlistparser.Create(nil); + end; + parser.scanner:= scanner; + if fpcformat then begin + tfpcresstringparser(parser).getconsts(ar1); + end + else begin + tresstringlistparser(parser).getconsts(ar1); + end; + finally + parser.free; + scanner.free; + end; + end; + finally + instream.free; + end; + str1:= ''; + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + if valuetype = vawstring then begin + if not fpcformat then begin + for int2:= 1 to length(name) do begin + if name[int1] = '_' then begin + name[int1]:= '.'; + break; + end; + end; + end; + str1:= str1 + name + #0 + stringtoutf8ansi(value) + #0; + end; + end; + end; + outfilename:= filedir(sourcefilename) + msestring(unitname) + destfileext; + outstream:= ttextstream.create(outfilename,fm_create); + try + outstream.writeln('unit ' + unitname + ';'); + outstream.writeln(compilerdefaults); + outstream.writeln(''); + outstream.writeln('interface'); + outstream.writeln(''); + outstream.writeln('implementation'); + outstream.writeln('uses'); + outstream.writeln(' msei18nglob,mselanglink;'); + writeconstdata(pbyte(pchar(str1)),length(str1),dataname,outstream); + outstream.writeln('var'); + outstream.writeln(' hookbefore: registerresourcehookty;'); + outstream.writeln(''); + outstream.writeln( + 'procedure registerresource(const registerresourceproc: registerresourcety);'); + outstream.writeln('begin'); + outstream.writeln( + ' registerresourceproc(@'+dataname+');'); + outstream.writeln(' registerresourcehook:= hookbefore;'); + outstream.writeln('end;'); + outstream.writeln(''); + outstream.writeln('initialization'); + outstream.writeln(' hookbefore:= registerresourcehook;'); + outstream.writeln(' registerresourcehook:= @registerresource;'); + outstream.writeln('end.'); + finally + outstream.free; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/mserichstringeditor.mfm b/mseide-msegui/lib/common/designutils/mserichstringeditor.mfm new file mode 100644 index 0000000..fa57684 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mserichstringeditor.mfm @@ -0,0 +1,113 @@ +object richstringeditorfo: trichstringeditorfo + visible = False + bounds_x = 110 + bounds_y = 237 + bounds_cx = 409 + bounds_cy = 297 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 409 + 297 + ) + options = [fo_screencentered, fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savestate] + statfile = tstatfile1 + caption = 'Enter Memo Text' + moduleclassname = 'tmseform' + object memo: trichmemoedit + frame.localprops = [frl_colorclient] + frame.localprops1 = [] + frame.sbhorz.pagesize = 1 + frame.sbvert.pagesize = 1 + popupmenu = tpopupmenu1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 409 + bounds_cy = 268 + anchors = [an_top, an_bottom] + optionsedit1 = [oe1_multiline, oe1_autopopupmenu, oe1_keyexecute, oe1_savevalue, oe1_savestate] + optionsedit = [oe_closequery, oe_checkmrcancel, oe_linebreak, oe_shiftreturn, oe_resetselectonexit, oe_nofirstarrownavig, oe_caretonreadonly] + reffontheight = 14 + end + object tlayouter1: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + taborder = 1 + bounds_x = 72 + bounds_y = 272 + bounds_cx = 330 + bounds_cy = 20 + anchors = [an_left, an_right, an_bottom] + optionsscale = [osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_placex, lao_aligny] + align_glue = wam_start + place_mindist = 8 + place_maxdist = 8 + place_mode = wam_end + linktop = memo + dist_top = 4 + options = [spao_gluebottom] + object tbutton2: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + bounds_x = 278 + bounds_y = 0 + bounds_cx = 52 + bounds_cy = 20 + bounds_cxmin = 50 + state = [as_localcaption] + caption = '&Cancel' + font.name = 'stf_default' + font.localprops = [] + modalresult = mr_cancel + reffontheight = 14 + end + object tbutton1: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + taborder = 1 + bounds_x = 220 + bounds_y = 0 + bounds_cx = 50 + bounds_cy = 20 + bounds_cxmin = 50 + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + reffontheight = 14 + end + object tbutton3: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + taborder = 2 + bounds_x = 126 + bounds_y = 0 + bounds_cx = 86 + bounds_cy = 20 + bounds_cxmin = 50 + action = formatedact + reffontheight = 14 + end + end + object tstatfile1: tstatfile + filename = 'richmemodialog.sta' + options = [sfo_memory, sfo_activatorread, sfo_activatorwrite] + left = 64 + top = 104 + end + object tpopupmenu1: tpopupmenu + menu.submenu.count = 1 + menu.submenu.items = < + item + action = formatedact + end> + left = 168 + top = 104 + end + object formatedact: taction + caption = '&Font Format' + options = [ao_updateonidle] + onexecute = fontformateditev + onupdate = updateactev + left = 168 + top = 144 + end +end diff --git a/mseide-msegui/lib/common/designutils/mserichstringeditor.pas b/mseide-msegui/lib/common/designutils/mserichstringeditor.pas new file mode 100644 index 0000000..5588846 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mserichstringeditor.pas @@ -0,0 +1,81 @@ +{ MSEgui Copyright (c) 2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mserichstringeditor; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseglob,mseguiglob,mseapplication,msestat,msemenus,msegui,msegraphics, + msegraphutils,mseevent,mseclasses,mseforms,msedataedits,mseedit,msestrings, + msetypes,msestatfile,msesimplewidgets,msewidgets,msedialog,classes,mclasses, + msedropdownlist,msesplitter,mserichstring,mseactions,mseact; + +type + trichstringeditorfo = class(tmseform) + memo: trichmemoedit; + tstatfile1: tstatfile; + tlayouter1: tlayouter; + tbutton2: tbutton; + tbutton1: tbutton; + tpopupmenu1: tpopupmenu; + tbutton3: tbutton; + formatedact: taction; + procedure fontformateditev(const sender: TObject); + procedure updateactev(const sender: tcustomaction); + public + constructor create(const aowner: tcomponent; const readonly: boolean); + reintroduce; + end; + +function richstringdialog(var avalue: richstringty; + const readonly: boolean): modalresultty; + +implementation +uses + mserichstringeditor_mfm,mseeditglob,msekeyboard,msestockobjects, + msefontformatdialog; + +function richstringdialog(var avalue: richstringty; + const readonly: boolean): modalresultty; +var + dia1: trichstringeditorfo; +begin + dia1:= trichstringeditorfo.create(nil,readonly); + try + dia1.memo.richvalue:= avalue; + result:= dia1.show(true); + if result = mr_ok then begin + avalue:= dia1.memo.richvalue; + end; + finally + dia1.free; + end; +end; + +{ trichstringeditorfo } + +constructor trichstringeditorfo.create(const aowner: tcomponent; + const readonly: boolean); +begin + inherited create(aowner); + memo.readonly:= readonly; +end; + +procedure trichstringeditorfo.fontformateditev(const sender: TObject); +begin + memo.formatvalue:= editfontformat(memo.formatvalue, + memo.editor.selstart,memo.editor.sellength); +end; + +procedure trichstringeditorfo.updateactev(const sender: tcustomaction); +begin + sender.enabled:= memo.editor.hasselection; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/mserichstringeditor_mfm.pas b/mseide-msegui/lib/common/designutils/mserichstringeditor_mfm.pas new file mode 100644 index 0000000..c0d0669 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mserichstringeditor_mfm.pas @@ -0,0 +1,136 @@ +unit mserichstringeditor_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,mserichstringeditor; + +const + objdata: record size: integer; data: array[0..2379] of byte end = + (size: 2380; data: ( + 84,80,70,48,19,116,114,105,99,104,115,116,114,105,110,103,101,100,105,116, + 111,114,102,111,18,114,105,99,104,115,116,114,105,110,103,101,100,105,116,111, + 114,102,111,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95, + 120,2,110,8,98,111,117,110,100,115,95,121,3,237,0,9,98,111,117,110, + 100,115,95,99,120,3,153,1,9,98,111,117,110,100,115,95,99,121,3,41, + 1,26,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,0,27,99,111,110,116,97,105,110,101,114, + 46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2,0, + 2,0,3,153,1,3,41,1,0,7,111,112,116,105,111,110,115,11,17,102, + 111,95,115,99,114,101,101,110,99,101,110,116,101,114,101,100,13,102,111,95, + 99,108,111,115,101,111,110,101,115,99,15,102,111,95,97,117,116,111,114,101, + 97,100,115,116,97,116,16,102,111,95,97,117,116,111,119,114,105,116,101,115, + 116,97,116,10,102,111,95,115,97,118,101,112,111,115,12,102,111,95,115,97, + 118,101,115,116,97,116,101,0,8,115,116,97,116,102,105,108,101,7,10,116, + 115,116,97,116,102,105,108,101,49,7,99,97,112,116,105,111,110,6,15,69, + 110,116,101,114,32,77,101,109,111,32,84,101,120,116,15,109,111,100,117,108, + 101,99,108,97,115,115,110,97,109,101,6,8,116,109,115,101,102,111,114,109, + 0,13,116,114,105,99,104,109,101,109,111,101,100,105,116,4,109,101,109,111, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,15,102, + 114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,21,102,114,97,109, + 101,46,115,98,104,111,114,122,46,112,97,103,101,115,105,122,101,2,1,21, + 102,114,97,109,101,46,115,98,118,101,114,116,46,112,97,103,101,115,105,122, + 101,2,1,9,112,111,112,117,112,109,101,110,117,7,11,116,112,111,112,117, + 112,109,101,110,117,49,8,98,111,117,110,100,115,95,120,2,0,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,153, + 1,9,98,111,117,110,100,115,95,99,121,3,12,1,7,97,110,99,104,111, + 114,115,11,6,97,110,95,116,111,112,9,97,110,95,98,111,116,116,111,109, + 0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,13,111,101,49,95, + 109,117,108,116,105,108,105,110,101,17,111,101,49,95,97,117,116,111,112,111, + 112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99,117, + 116,101,13,111,101,49,95,115,97,118,101,118,97,108,117,101,13,111,101,49, + 95,115,97,118,101,115,116,97,116,101,0,11,111,112,116,105,111,110,115,101, + 100,105,116,11,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111, + 101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,108, + 105,110,101,98,114,101,97,107,14,111,101,95,115,104,105,102,116,114,101,116, + 117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110, + 101,120,105,116,20,111,101,95,110,111,102,105,114,115,116,97,114,114,111,119, + 110,97,118,105,103,18,111,101,95,99,97,114,101,116,111,110,114,101,97,100, + 111,110,108,121,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,0,9,116,108,97,121,111,117,116,101,114,10,116,108,97,121,111,117, + 116,101,114,49,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,11, + 111,119,95,116,97,98,102,111,99,117,115,17,111,119,95,112,97,114,101,110, + 116,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111, + 99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16, + 111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95, + 115,117,98,102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,0,8,116,97,98,111,114,100,101,114,2,1,8,98, + 111,117,110,100,115,95,120,2,72,8,98,111,117,110,100,115,95,121,3,16, + 1,9,98,111,117,110,100,115,95,99,120,3,74,1,9,98,111,117,110,100, + 115,95,99,121,2,20,7,97,110,99,104,111,114,115,11,7,97,110,95,108, + 101,102,116,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116,116, + 111,109,0,12,111,112,116,105,111,110,115,115,99,97,108,101,11,11,111,115, + 99,95,101,120,112,97,110,100,121,11,111,115,99,95,115,104,114,105,110,107, + 121,17,111,115,99,95,101,120,112,97,110,100,115,104,114,105,110,107,120,17, + 111,115,99,95,101,120,112,97,110,100,115,104,114,105,110,107,121,0,13,111, + 112,116,105,111,110,115,108,97,121,111,117,116,11,10,108,97,111,95,112,108, + 97,99,101,120,10,108,97,111,95,97,108,105,103,110,121,0,10,97,108,105, + 103,110,95,103,108,117,101,7,9,119,97,109,95,115,116,97,114,116,13,112, + 108,97,99,101,95,109,105,110,100,105,115,116,2,8,13,112,108,97,99,101, + 95,109,97,120,100,105,115,116,2,8,10,112,108,97,99,101,95,109,111,100, + 101,7,7,119,97,109,95,101,110,100,7,108,105,110,107,116,111,112,7,4, + 109,101,109,111,8,100,105,115,116,95,116,111,112,2,4,7,111,112,116,105, + 111,110,115,11,15,115,112,97,111,95,103,108,117,101,98,111,116,116,111,109, + 0,0,7,116,98,117,116,116,111,110,8,116,98,117,116,116,111,110,50,14, + 111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95, + 102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,13,111,119,49,95, + 97,117,116,111,115,99,97,108,101,13,111,119,49,95,97,117,116,111,119,105, + 100,116,104,0,8,98,111,117,110,100,115,95,120,3,22,1,8,98,111,117, + 110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,52,9, + 98,111,117,110,100,115,95,99,121,2,20,12,98,111,117,110,100,115,95,99, + 120,109,105,110,2,50,5,115,116,97,116,101,11,15,97,115,95,108,111,99, + 97,108,99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,7, + 38,67,97,110,99,101,108,9,102,111,110,116,46,110,97,109,101,6,11,115, + 116,102,95,100,101,102,97,117,108,116,15,102,111,110,116,46,108,111,99,97, + 108,112,114,111,112,115,11,0,11,109,111,100,97,108,114,101,115,117,108,116, + 7,9,109,114,95,99,97,110,99,101,108,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,0,7,116,98,117,116,116,111,110,8,116,98, + 117,116,116,111,110,49,14,111,112,116,105,111,110,115,119,105,100,103,101,116, + 49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103, + 104,116,13,111,119,49,95,97,117,116,111,115,99,97,108,101,13,111,119,49, + 95,97,117,116,111,119,105,100,116,104,0,8,116,97,98,111,114,100,101,114, + 2,1,8,98,111,117,110,100,115,95,120,3,220,0,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,50,9,98,111, + 117,110,100,115,95,99,121,2,20,12,98,111,117,110,100,115,95,99,120,109, + 105,110,2,50,5,115,116,97,116,101,11,10,97,115,95,100,101,102,97,117, + 108,116,15,97,115,95,108,111,99,97,108,100,101,102,97,117,108,116,15,97, + 115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,7,99,97,112,116, + 105,111,110,6,3,38,79,75,11,109,111,100,97,108,114,101,115,117,108,116, + 7,5,109,114,95,111,107,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,0,7,116,98,117,116,116,111,110,8,116,98,117,116,116,111, + 110,51,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111, + 119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,13,111, + 119,49,95,97,117,116,111,115,99,97,108,101,13,111,119,49,95,97,117,116, + 111,119,105,100,116,104,0,8,116,97,98,111,114,100,101,114,2,2,8,98, + 111,117,110,100,115,95,120,2,126,8,98,111,117,110,100,115,95,121,2,0, + 9,98,111,117,110,100,115,95,99,120,2,86,9,98,111,117,110,100,115,95, + 99,121,2,20,12,98,111,117,110,100,115,95,99,120,109,105,110,2,50,6, + 97,99,116,105,111,110,7,11,102,111,114,109,97,116,101,100,97,99,116,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,9,116, + 115,116,97,116,102,105,108,101,10,116,115,116,97,116,102,105,108,101,49,8, + 102,105,108,101,110,97,109,101,6,18,114,105,99,104,109,101,109,111,100,105, + 97,108,111,103,46,115,116,97,7,111,112,116,105,111,110,115,11,10,115,102, + 111,95,109,101,109,111,114,121,17,115,102,111,95,97,99,116,105,118,97,116, + 111,114,114,101,97,100,18,115,102,111,95,97,99,116,105,118,97,116,111,114, + 119,114,105,116,101,0,4,108,101,102,116,2,64,3,116,111,112,2,104,0, + 0,10,116,112,111,112,117,112,109,101,110,117,11,116,112,111,112,117,112,109, + 101,110,117,49,18,109,101,110,117,46,115,117,98,109,101,110,117,46,99,111, + 117,110,116,2,1,18,109,101,110,117,46,115,117,98,109,101,110,117,46,105, + 116,101,109,115,14,1,6,97,99,116,105,111,110,7,11,102,111,114,109,97, + 116,101,100,97,99,116,0,0,4,108,101,102,116,3,168,0,3,116,111,112, + 2,104,0,0,7,116,97,99,116,105,111,110,11,102,111,114,109,97,116,101, + 100,97,99,116,7,99,97,112,116,105,111,110,6,12,38,70,111,110,116,32, + 70,111,114,109,97,116,7,111,112,116,105,111,110,115,11,15,97,111,95,117, + 112,100,97,116,101,111,110,105,100,108,101,0,9,111,110,101,120,101,99,117, + 116,101,7,16,102,111,110,116,102,111,114,109,97,116,101,100,105,116,101,118, + 8,111,110,117,112,100,97,116,101,7,11,117,112,100,97,116,101,97,99,116, + 101,118,4,108,101,102,116,3,168,0,3,116,111,112,3,144,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,trichstringeditorfo,''); +end. diff --git a/mseide-msegui/lib/common/designutils/msesettings.mfm b/mseide-msegui/lib/common/designutils/msesettings.mfm new file mode 100644 index 0000000..647ddca --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msesettings.mfm @@ -0,0 +1,571 @@ +object settingsfo: tsettingsfo + optionswidget = [ow_arrowfocus, ow_subfocus, ow_mousewheel, ow_destroywidgets, ow_hinton] + visible = False + bounds_x = 100 + bounds_y = 106 + bounds_cx = 348 + bounds_cy = 570 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 348 + 570 + ) + options = [fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savestate] + statfile = tstatfile1 + caption = 'Configure MSE environment' + windowopacity = -Inf + oncreate = formoncreate + moduleclassname = 'tmseform' + object tsplitter1: tsplitter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + color = -2147483645 + taborder = 2 + bounds_x = 0 + bounds_y = 520 + bounds_cx = 348 + bounds_cy = 38 + anchors = [an_bottom] + optionsscale = [osc_expandy, osc_shrinky] + linktop = macrogrid + grip = stb_none + object tbutton2: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + taborder = 2 + bounds_x = 283 + bounds_y = 16 + bounds_cx = 52 + bounds_cy = 22 + bounds_cxmin = 50 + anchors = [an_top, an_right] + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + reffontheight = 14 + end + object tbutton1: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + taborder = 1 + bounds_x = 225 + bounds_y = 16 + bounds_cx = 50 + bounds_cy = 22 + bounds_cxmin = 50 + anchors = [an_top, an_right] + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + reffontheight = 14 + end + object shortcutbu: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + bounds_x = 9 + bounds_y = 16 + bounds_cx = 78 + bounds_cy = 22 + bounds_cxmin = 78 + state = [as_localcaption, as_localonexecute] + caption = '&Shortcuts' + onexecute = editshortcuts + reffontheight = 14 + end + object tspacer2: tspacer + taborder = 3 + bounds_x = 275 + bounds_y = 16 + bounds_cx = 8 + bounds_cy = 20 + linkleft = tbutton1 + linkright = tbutton2 + options = [spao_glueright] + end + end + object tlayouter1: tlayouter + bounds_x = 0 + bounds_y = 0 + bounds_cx = 348 + bounds_cy = 407 + anchors = [an_left, an_top, an_right] + optionsscale = [osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_placey] + linkbottom = macrogrid + object tspacer1: tlayouter + taborder = 9 + bounds_x = 8 + bounds_y = 333 + bounds_cx = 330 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + optionsscale = [osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_placex, lao_aligny] + align_glue = wam_start + place_mindist = 4 + place_maxdist = 4 + place_options = [plo_scalesize, plo_endmargin] + object targetosdir: tstringedit + Tag = 11 + frame.caption = '${TARGETOSDIR}' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + bounds_x = 178 + bounds_y = 0 + bounds_cx = 152 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + onsetvalue = setvalue + reffontheight = 14 + end + object target: tstringedit + Tag = 10 + frame.caption = '${TARGET}' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + bounds_x = 82 + bounds_y = 0 + bounds_cx = 92 + bounds_cy = 37 + onsetvalue = setvalue + reffontheight = 14 + end + object exeext: tstringedit + Tag = 9 + frame.caption = '${EXEEXT}' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + bounds_x = 0 + bounds_y = 0 + bounds_cx = 78 + bounds_cy = 37 + onsetvalue = setvalue + reffontheight = 14 + end + end + object printcomm: tstringedit + frame.caption = 'Print command' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 10 + bounds_x = 8 + bounds_y = 370 + bounds_cx = 330 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + onsetvalue = setprintcomm + reffontheight = 14 + end + object debugger: tfilenameedit + Tag = 8 + frame.caption = '${DEBUGGER}' + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + imagenr = 17 + end> + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 8 + hint = 'Path to debugger (gdb).' + bounds_x = 8 + bounds_y = 296 + bounds_cx = 330 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + onsetvalue = setvalue + controller.captionopen = 'Debugger path' + controller.ongetfilename = epandfilenamemacro + reffontheight = 14 + end + object compiler: tfilenameedit + Tag = 7 + frame.caption = '${COMPILER}' + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + imagenr = 17 + end> + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 7 + hint = 'Path to compiler (ppc386).' + bounds_x = 8 + bounds_y = 259 + bounds_cx = 330 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + onsetvalue = setvalue + controller.captionopen = 'Compiler path' + controller.ongetfilename = epandfilenamemacro + reffontheight = 14 + end + object compstoredir: tfilenameedit + Tag = 6 + frame.caption = '${COMPSTOREDIR}' + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + imagenr = 17 + end> + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 6 + hint = 'Directory for component store files.' + bounds_x = 8 + bounds_y = 222 + bounds_cx = 330 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + onsetvalue = setvalue + controller.filterlist.data = ( + ( + 'Project files' + '*.prj' + ) + ) + controller.options = [fdo_directory] + controller.captionopen = 'Directory for component stores' + controller.ongetfilename = epandfilenamemacro + reffontheight = 14 + end + object templatedir: tfilenameedit + Tag = 5 + frame.caption = '${TEMPLATEDIR}' + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + imagenr = 17 + end> + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 5 + hint = 'Directory for project template files.' + bounds_x = 8 + bounds_y = 185 + bounds_cx = 330 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + onsetvalue = setvalue + controller.filterlist.data = ( + ( + 'Project files' + '*.prj' + ) + ) + controller.options = [fdo_directory] + controller.captionopen = 'Project template directory' + controller.ongetfilename = epandfilenamemacro + reffontheight = 14 + end + object syntaxdefdir: tfilenameedit + Tag = 4 + frame.caption = '${SYNTAXDEFDIR}' + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + imagenr = 17 + end> + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 4 + hint = 'Directory for syntax definition files.' + bounds_x = 8 + bounds_y = 148 + bounds_cx = 330 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + onsetvalue = setvalue + controller.filterlist.data = ( + ( + 'Syntax definitions' + '*.sdef' + ) + ) + controller.options = [fdo_directory] + controller.captionopen = 'Directory for syntax definition files' + controller.ongetfilename = epandfilenamemacro + reffontheight = 14 + end + object mselibdir: tfilenameedit + Tag = 3 + frame.caption = '${MSELIBDIR}' + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + imagenr = 17 + end> + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 3 + hint = 'Root directory of MSEgui library.' + bounds_x = 8 + bounds_y = 111 + bounds_cx = 330 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + onsetvalue = setvalue + controller.options = [fdo_directory] + controller.captionopen = 'MSEgui library directory' + controller.ongetfilename = epandfilenamemacro + reffontheight = 14 + end + object msedir: tfilenameedit + Tag = 2 + frame.caption = '${MSEDIR}' + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + imagenr = 17 + end> + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + hint = 'Root directory of MSEgui.' + bounds_x = 8 + bounds_y = 74 + bounds_cx = 330 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + onsetvalue = setvalue + controller.options = [fdo_directory] + controller.captionopen = 'MSEgui root directory' + controller.ongetfilename = epandfilenamemacro + reffontheight = 14 + end + object fpclibdir: tfilenameedit + Tag = 1 + frame.caption = '${FPCLIBDIR}' + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + imagenr = 17 + end> + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + hint = 'Root directory of FPC library (not used by the default project templates).' + bounds_x = 8 + bounds_y = 37 + bounds_cx = 330 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + controller.options = [fdo_directory] + controller.captionopen = 'FPC library directory' + reffontheight = 14 + end + object fpcdir: tfilenameedit + frame.caption = '${FPCDIR}' + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + imagenr = 17 + end> + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + hint = 'Root directory of Free Pascal system (not used by the default project templates).' + bounds_x = 8 + bounds_y = 0 + bounds_cx = 330 + bounds_cy = 37 + anchors = [an_left, an_top, an_right] + onsetvalue = setvalue + controller.options = [fdo_directory] + controller.captionopen = 'FPC root directory' + controller.ongetfilename = epandfilenamemacro + reffontheight = 14 + end + end + object macrogrid: twidgetgrid + frame.caption = 'Global Macros' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + bounds_x = 8 + bounds_y = 407 + bounds_cx = 330 + bounds_cy = 113 + bounds_cymin = 80 + anchors = [an_left, an_top, an_right, an_bottom] + optionsgrid = [og_colsizing, og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_noinsertempty, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixcols.count = 1 + fixcols.items = < + item + width = 28 + numstart = 1 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 4 + captions.items = < + item + caption = 'Name' + end + item + caption = 'Value' + end + item + end + item + end> + end> + datacols.count = 2 + datacols.options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[macroname] + width = 151 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'macroname' + dataclass = tgridmsestringdatalist + end + item[macrovalue] + width = 144 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fill, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'macrovalue' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + statfile = tstatfile1 + reffontheight = 14 + object macroname: tstringedit + optionsskin = [osk_framebuttononly] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 151 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + reffontheight = 14 + end + object macrovalue: tmemodialogedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 2 + visible = False + bounds_x = 152 + bounds_y = 0 + bounds_cx = 144 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + reffontheight = 14 + end + end + object tstatfile1: tstatfile + filename = 'settingsfo.sta' + options = [sfo_memory] + left = 16 + top = 32 + end +end diff --git a/mseide-msegui/lib/common/designutils/msesettings.pas b/mseide-msegui/lib/common/designutils/msesettings.pas new file mode 100644 index 0000000..c10d9d0 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msesettings.pas @@ -0,0 +1,312 @@ +{ MSEide Copyright (c) 2002-2013 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit msesettings; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + mseglob,mseguiglob,msegui,mseclasses,mseforms,msestat,msestatfile, + msesimplewidgets,msefiledialog,msestrings,msemacros,msedataedits,msebitmap, + msedatanodes,mseedit,mseevent,msegraphutils,msegrids,mselistbrowser,msemenus, + msesys,msetypes,msegraphics,msewidgets,mseactions,mseifiglob,msesplitter, + mseificomp,mseificompglob,msememodialog,msewidgetgrid; + +type + settingsmacroty = (sma_fpcdir,sma_fpclibdir,sma_msedir,sma_mselibdir, + sma_syntaxdefdir,sma_templatedir,sma_compstoredir, + sma_compiler,sma_debugger, + sma_exeext,sma_target,sma_targetosdir); +const + statdirname = '^/.mseide'; + settingsmacronames: array[settingsmacroty] of msestring = ( + 'fpcdir','fpclibdir','msedir','mselibdir','syntaxdefdir', + 'templatedir','compstoredir','compiler','debugger', + 'exeext','target','targetosdir'); + {$ifdef mswindows} + defaultsettingmacros: array[settingsmacroty] of msestring = ( + '','','','${MSEDIR}lib/common/','${MSEDIR}apps/ide/syntaxdefs/', + '${MSEDIR}apps/ide/templates/','${MSEDIR}apps/ide/compstore/', + 'ppc386.exe','gdb.exe','.exe','i386-win32','windows'); + {$else} + {$ifdef CPU64} + defaultsettingmacros: array[settingsmacroty] of msestring = ( + '','','','${MSEDIR}lib/common/','${MSEDIR}apps/ide/syntaxdefs/', + '${MSEDIR}apps/ide/templates/','${MSEDIR}apps/ide/compstore/', + 'ppcx64','gdb','','x86_64-linux','linux'); + {$else} + {$ifdef CPUARM} + defaultsettingmacros: array[settingsmacroty] of msestring = ( + '','','','${MSEDIR}lib/common/','${MSEDIR}apps/ide/syntaxdefs/', + '${MSEDIR}apps/ide/templates/','${MSEDIR}apps/ide/compstore/', + 'ppcarm','gdb','','arm-linux','linux'); + {$else} + defaultsettingmacros: array[settingsmacroty] of msestring = ( + '','','','${MSEDIR}lib/common/','${MSEDIR}apps/ide/syntaxdefs/', + '${MSEDIR}apps/ide/templates/','${MSEDIR}apps/ide/compstore/', + 'ppc386','gdb','','i386-linux','linux'); + {$endif} + {$endif} + {$endif} + +type + settingsmacroarty = array[settingsmacroty] of filenamety; + settingsmacrosty = record + macros: settingsmacroarty; + globmacronames: msestringarty; + globmacrovalues: msestringarty; + end; + settingsty = record + macros: settingsmacrosty; + printcommand: msestring; + end; + + tsettingsfo = class(tmseform) + tstatfile1: tstatfile; + tlayouter1: tlayouter; + printcomm: tstringedit; + debugger: tfilenameedit; + compiler: tfilenameedit; + compstoredir: tfilenameedit; + templatedir: tfilenameedit; + syntaxdefdir: tfilenameedit; + mselibdir: tfilenameedit; + msedir: tfilenameedit; + fpclibdir: tfilenameedit; + fpcdir: tfilenameedit; + tspacer1: tlayouter; + targetosdir: tstringedit; + target: tstringedit; + exeext: tstringedit; + tsplitter1: tsplitter; + tbutton2: tbutton; + tbutton1: tbutton; + shortcutbu: tbutton; + macrogrid: twidgetgrid; + macroname: tstringedit; + macrovalue: tmemodialogedit; + tspacer2: tspacer; + procedure epandfilenamemacro(const sender: TObject; var avalue: msestring; + var accept: Boolean); + procedure formoncreate(const sender: TObject); + procedure setvalue(const sender: TObject; var avalue: msestring; + var accept: Boolean); + procedure setprintcomm(const sender: TObject; var avalue: msestring; + var accept: Boolean); + procedure editshortcuts(const sender: TObject); + private + fshortcutcontroller: tshortcutcontroller; + protected + function widgetstomacros: settingsmacrosty; + end; + +var + settings: settingsty; + +procedure updatesettings(const filer: tstatfiler); +function getsettingsmacros: macroinfoarty; +function getsyssettingsmacros: macroinfoarty; +function getprintcommand: msestring; +function editsettings(const acaption: msestring = ''; + const shortcuts: tshortcutcontroller = nil): boolean; + +implementation +uses + msesettings_mfm,classes,mclasses,msesysintf,msefileutils,mseshortcutdialog; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +function getsettingsmacros1(var amacros: settingsmacrosty): macroinfoarty; +var + ma1: settingsmacroty; + int1: integer; +begin + with amacros do begin + setlength(globmacrovalues,length(globmacronames)); + setlength(result,ord(high(settingsmacroty))+1+length(globmacronames)); + for ma1:= low(settingsmacroty) to high(settingsmacroty) do begin + result[ord(ma1)].name:= settingsmacronames[ma1]; + result[ord(ma1)].value:= macros[ma1]; + end; + for int1:= 0 to high(globmacronames) do begin + result[ord(high(settingsmacroty))+1+int1].name:= globmacronames[int1]; + result[ord(high(settingsmacroty))+1+int1].value:= globmacrovalues[int1]; + end; + end; +end; + +function getsettingsmacros: macroinfoarty; +begin + result:= getsettingsmacros1(settings.macros); +end; + +function getsyssettingsmacros: macroinfoarty; +var + int1: integer; +begin + result:= getsettingsmacros1(settings.macros); + for int1:= 0 to ord(sma_debugger) do begin + result[int1].value:= tosysfilepath(result[int1].value); + end; +end; + +function getprintcommand: msestring; +begin + result:= settings.printcommand; +end; + +procedure updatesettings(const filer: tstatfiler); +var + ma1: settingsmacroty; +begin + with settings,macros do begin + if filer.iswriter then begin + for ma1:= low(settingsmacroty) to high(settingsmacroty) do begin + filer.updatevalue(settingsmacronames[ma1],macros[ma1]); + end; + end + else begin + with tstatreader(filer) do begin + for ma1:= low(settingsmacroty) to high(settingsmacroty) do begin + macros[ma1]:= readmsestring(settingsmacronames[ma1],defaultsettingmacros[ma1]); + end; + end; + printcommand:= sys_getprintcommand; + end; + filer.updatevalue('printcommand',printcommand); + filer.updatevalue('globmacronames',globmacronames); + filer.updatevalue('globmacrovalues',globmacrovalues); + end; +end; + +function editsettings(const acaption: msestring = ''; + const shortcuts: tshortcutcontroller = nil): boolean; +var + settingsfo: tsettingsfo; +begin + result:= false; + settingsfo:= tsettingsfo.create(nil); + with settingsfo do begin + try + fshortcutcontroller:= shortcuts; + if shortcuts = nil then begin + shortcutbu.visible:= false; + end; + if acaption <> '' then begin + settingsfo.caption:= acaption; + end; + if show(true) = mr_ok then begin + result:= true; + with settings do begin + macros:= widgetstomacros; +// expandprojectmacros; + printcommand:= printcomm.value; + end; + end; + finally + free; + end; + end; +end; + +{ tsettingsfo } + +procedure tsettingsfo.formoncreate(const sender: TObject); +begin + with settings,macros do begin + fpcdir.value:= macros[sma_fpcdir]; + fpclibdir.value:= macros[sma_fpclibdir]; + msedir.value:= macros[sma_msedir]; + mselibdir.value:= macros[sma_mselibdir]; + syntaxdefdir.value:= macros[sma_syntaxdefdir]; + templatedir.value:= macros[sma_templatedir]; + compstoredir.value:= macros[sma_compstoredir]; + compiler.value:= macros[sma_compiler]; + debugger.value:= macros[sma_debugger]; + exeext.value:= macros[sma_exeext]; + target.value:= macros[sma_target]; + targetosdir.value:= macros[sma_targetosdir]; + printcomm.value:= printcommand; + macroname.gridvalues:= globmacronames; + macrovalue.gridvalues:= globmacrovalues; + end; +end; + +function tsettingsfo.widgetstomacros: settingsmacrosty; +begin + with result do begin + macros[sma_fpcdir]:= fpcdir.value; + macros[sma_fpclibdir]:= fpclibdir.value; + macros[sma_msedir]:= msedir.value; + macros[sma_mselibdir]:= mselibdir.value; + macros[sma_syntaxdefdir]:= syntaxdefdir.value; + macros[sma_templatedir]:= templatedir.value; + macros[sma_compstoredir]:= compstoredir.value; + macros[sma_compiler]:= compiler.value; + macros[sma_debugger]:= debugger.value; + macros[sma_exeext]:= exeext.value; + macros[sma_target]:= target.value; + macros[sma_targetosdir]:= targetosdir.value; + globmacronames:= macroname.gridvalues; + globmacrovalues:= macrovalue.gridvalues; + end; +end; + +procedure tsettingsfo.epandfilenamemacro(const sender: TObject; + var avalue: msestring; var accept: Boolean); +var + mac1: settingsmacrosty; +begin + mac1:= widgetstomacros; + avalue:= expandmacros(avalue,getsettingsmacros1(mac1)); +end; + +procedure tsettingsfo.setvalue(const sender: TObject; var avalue: msestring; + var accept: Boolean); +begin + if avalue = '' then begin + avalue:= defaultsettingmacros[settingsmacroty(tcomponent(sender).tag)]; + end; +end; + +procedure tsettingsfo.setprintcomm(const sender: TObject; var avalue: msestring; + var accept: Boolean); +begin + if avalue = '' then begin + avalue:= sys_getprintcommand; + end; +end; + +procedure tsettingsfo.editshortcuts(const sender: TObject); +begin + shortcutdialog(fshortcutcontroller); +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/msesettings_mfm.pas b/mseide-msegui/lib/common/designutils/msesettings_mfm.pas new file mode 100644 index 0000000..904b01a --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msesettings_mfm.pas @@ -0,0 +1,528 @@ +unit msesettings_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msesettings; + +const + objdata: record size: integer; data: array[0..10216] of byte end = + (size: 10217; data: ( + 84,80,70,48,11,116,115,101,116,116,105,110,103,115,102,111,10,115,101,116, + 116,105,110,103,115,102,111,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,13,111,119,95,97,114,114,111,119,102,111,99,117,115,11,111,119,95, + 115,117,98,102,111,99,117,115,13,111,119,95,109,111,117,115,101,119,104,101, + 101,108,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 9,111,119,95,104,105,110,116,111,110,0,7,118,105,115,105,98,108,101,8, + 8,98,111,117,110,100,115,95,120,2,100,8,98,111,117,110,100,115,95,121, + 2,106,9,98,111,117,110,100,115,95,99,120,3,92,1,9,98,111,117,110, + 100,115,95,99,121,3,58,2,26,99,111,110,116,97,105,110,101,114,46,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,27,99,111, + 110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,99,111,110,116,97,105,110,101,114,46,98,111, + 117,110,100,115,1,2,0,2,0,3,92,1,3,58,2,0,7,111,112,116, + 105,111,110,115,11,13,102,111,95,99,108,111,115,101,111,110,101,115,99,15, + 102,111,95,97,117,116,111,114,101,97,100,115,116,97,116,16,102,111,95,97, + 117,116,111,119,114,105,116,101,115,116,97,116,10,102,111,95,115,97,118,101, + 112,111,115,12,102,111,95,115,97,118,101,115,116,97,116,101,0,8,115,116, + 97,116,102,105,108,101,7,10,116,115,116,97,116,102,105,108,101,49,7,99, + 97,112,116,105,111,110,6,25,67,111,110,102,105,103,117,114,101,32,77,83, + 69,32,101,110,118,105,114,111,110,109,101,110,116,13,119,105,110,100,111,119, + 111,112,97,99,105,116,121,5,0,0,0,0,0,0,0,128,255,255,8,111, + 110,99,114,101,97,116,101,7,12,102,111,114,109,111,110,99,114,101,97,116, + 101,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,8,116, + 109,115,101,102,111,114,109,0,9,116,115,112,108,105,116,116,101,114,10,116, + 115,112,108,105,116,116,101,114,49,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,11,111,119,95,116,97,98,102,111,99,117,115,17,111,119,95, + 112,97,114,101,110,116,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,5,99,111,108,111,114,4,3, + 0,0,128,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100, + 115,95,120,2,0,8,98,111,117,110,100,115,95,121,3,8,2,9,98,111, + 117,110,100,115,95,99,120,3,92,1,9,98,111,117,110,100,115,95,99,121, + 2,38,7,97,110,99,104,111,114,115,11,9,97,110,95,98,111,116,116,111, + 109,0,12,111,112,116,105,111,110,115,115,99,97,108,101,11,11,111,115,99, + 95,101,120,112,97,110,100,121,11,111,115,99,95,115,104,114,105,110,107,121, + 0,7,108,105,110,107,116,111,112,7,9,109,97,99,114,111,103,114,105,100, + 4,103,114,105,112,7,8,115,116,98,95,110,111,110,101,0,7,116,98,117, + 116,116,111,110,8,116,98,117,116,116,111,110,50,14,111,112,116,105,111,110, + 115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108, + 121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99, + 97,108,101,13,111,119,49,95,97,117,116,111,119,105,100,116,104,0,8,116, + 97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,3,27, + 1,8,98,111,117,110,100,115,95,121,2,16,9,98,111,117,110,100,115,95, + 99,120,2,52,9,98,111,117,110,100,115,95,99,121,2,22,12,98,111,117, + 110,100,115,95,99,120,109,105,110,2,50,7,97,110,99,104,111,114,115,11, + 6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,5,115,116, + 97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110, + 0,7,99,97,112,116,105,111,110,6,7,38,67,97,110,99,101,108,11,109, + 111,100,97,108,114,101,115,117,108,116,7,9,109,114,95,99,97,110,99,101, + 108,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,7, + 116,98,117,116,116,111,110,8,116,98,117,116,116,111,110,49,14,111,112,116, + 105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110, + 116,103,108,121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116, + 111,115,99,97,108,101,13,111,119,49,95,97,117,116,111,119,105,100,116,104, + 0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95, + 120,3,225,0,8,98,111,117,110,100,115,95,121,2,16,9,98,111,117,110, + 100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,22,12, + 98,111,117,110,100,115,95,99,120,109,105,110,2,50,7,97,110,99,104,111, + 114,115,11,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0, + 5,115,116,97,116,101,11,10,97,115,95,100,101,102,97,117,108,116,15,97, + 115,95,108,111,99,97,108,100,101,102,97,117,108,116,15,97,115,95,108,111, + 99,97,108,99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6, + 3,38,79,75,11,109,111,100,97,108,114,101,115,117,108,116,7,5,109,114, + 95,111,107,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0, + 0,7,116,98,117,116,116,111,110,10,115,104,111,114,116,99,117,116,98,117, + 14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49, + 95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,13,111,119,49, + 95,97,117,116,111,115,99,97,108,101,13,111,119,49,95,97,117,116,111,119, + 105,100,116,104,0,8,98,111,117,110,100,115,95,120,2,9,8,98,111,117, + 110,100,115,95,121,2,16,9,98,111,117,110,100,115,95,99,120,2,78,9, + 98,111,117,110,100,115,95,99,121,2,22,12,98,111,117,110,100,115,95,99, + 120,109,105,110,2,78,5,115,116,97,116,101,11,15,97,115,95,108,111,99, + 97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110, + 101,120,101,99,117,116,101,0,7,99,97,112,116,105,111,110,6,10,38,83, + 104,111,114,116,99,117,116,115,9,111,110,101,120,101,99,117,116,101,7,13, + 101,100,105,116,115,104,111,114,116,99,117,116,115,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,14,0,0,7,116,115,112,97,99,101,114,8, + 116,115,112,97,99,101,114,50,8,116,97,98,111,114,100,101,114,2,3,8, + 98,111,117,110,100,115,95,120,3,19,1,8,98,111,117,110,100,115,95,121, + 2,16,9,98,111,117,110,100,115,95,99,120,2,8,9,98,111,117,110,100, + 115,95,99,121,2,20,8,108,105,110,107,108,101,102,116,7,8,116,98,117, + 116,116,111,110,49,9,108,105,110,107,114,105,103,104,116,7,8,116,98,117, + 116,116,111,110,50,7,111,112,116,105,111,110,115,11,14,115,112,97,111,95, + 103,108,117,101,114,105,103,104,116,0,0,0,0,9,116,108,97,121,111,117, + 116,101,114,10,116,108,97,121,111,117,116,101,114,49,8,98,111,117,110,100, + 115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,120,3,92,1,9,98,111,117,110,100,115,95,99,121,3, + 151,1,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6, + 97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,12,111,112,116, + 105,111,110,115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97,110, + 100,121,11,111,115,99,95,115,104,114,105,110,107,121,17,111,115,99,95,101, + 120,112,97,110,100,115,104,114,105,110,107,120,17,111,115,99,95,101,120,112, + 97,110,100,115,104,114,105,110,107,121,0,13,111,112,116,105,111,110,115,108, + 97,121,111,117,116,11,10,108,97,111,95,112,108,97,99,101,121,0,10,108, + 105,110,107,98,111,116,116,111,109,7,9,109,97,99,114,111,103,114,105,100, + 0,9,116,108,97,121,111,117,116,101,114,8,116,115,112,97,99,101,114,49, + 8,116,97,98,111,114,100,101,114,2,9,8,98,111,117,110,100,115,95,120, + 2,8,8,98,111,117,110,100,115,95,121,3,77,1,9,98,111,117,110,100, + 115,95,99,120,3,74,1,9,98,111,117,110,100,115,95,99,121,2,37,7, + 97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110,95, + 116,111,112,8,97,110,95,114,105,103,104,116,0,12,111,112,116,105,111,110, + 115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97,110,100,121,11, + 111,115,99,95,115,104,114,105,110,107,121,17,111,115,99,95,101,120,112,97, + 110,100,115,104,114,105,110,107,120,17,111,115,99,95,101,120,112,97,110,100, + 115,104,114,105,110,107,121,0,13,111,112,116,105,111,110,115,108,97,121,111, + 117,116,11,10,108,97,111,95,112,108,97,99,101,120,10,108,97,111,95,97, + 108,105,103,110,121,0,10,97,108,105,103,110,95,103,108,117,101,7,9,119, + 97,109,95,115,116,97,114,116,13,112,108,97,99,101,95,109,105,110,100,105, + 115,116,2,4,13,112,108,97,99,101,95,109,97,120,100,105,115,116,2,4, + 13,112,108,97,99,101,95,111,112,116,105,111,110,115,11,13,112,108,111,95, + 115,99,97,108,101,115,105,122,101,13,112,108,111,95,101,110,100,109,97,114, + 103,105,110,0,0,11,116,115,116,114,105,110,103,101,100,105,116,11,116,97, + 114,103,101,116,111,115,100,105,114,3,84,97,103,2,11,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,14,36,123,84,65,82,71,69,84,79, + 83,68,73,82,125,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109, + 101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114, + 2,2,8,98,111,117,110,100,115,95,120,3,178,0,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,152,0,9,98, + 111,117,110,100,115,95,99,121,2,37,7,97,110,99,104,111,114,115,11,7, + 97,110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105, + 103,104,116,0,10,111,110,115,101,116,118,97,108,117,101,7,8,115,101,116, + 118,97,108,117,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,0,11,116,115,116,114,105,110,103,101,100,105,116,6,116,97,114,103, + 101,116,3,84,97,103,2,10,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,9,36,123,84,65,82,71,69,84,125,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8, + 116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2, + 82,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,2,92,9,98,111,117,110,100,115,95,99,121,2,37,10,111,110,115, + 101,116,118,97,108,117,101,7,8,115,101,116,118,97,108,117,101,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,11,116,115,116,114, + 105,110,103,101,100,105,116,6,101,120,101,101,120,116,3,84,97,103,2,9, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,9,36,123,69,88, + 69,69,88,84,125,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109, + 101,1,2,0,2,17,2,0,2,0,0,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,2,78,9,98,111,117,110,100,115,95,99,121,2,37,10,111,110, + 115,101,116,118,97,108,117,101,7,8,115,101,116,118,97,108,117,101,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,11,116,115, + 116,114,105,110,103,101,100,105,116,9,112,114,105,110,116,99,111,109,109,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,13,80,114,105,110,116, + 32,99,111,109,109,97,110,100,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114, + 100,101,114,2,10,8,98,111,117,110,100,115,95,120,2,8,8,98,111,117, + 110,100,115,95,121,3,114,1,9,98,111,117,110,100,115,95,99,120,3,74, + 1,9,98,111,117,110,100,115,95,99,121,2,37,7,97,110,99,104,111,114, + 115,11,7,97,110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110, + 95,114,105,103,104,116,0,10,111,110,115,101,116,118,97,108,117,101,7,12, + 115,101,116,112,114,105,110,116,99,111,109,109,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,14,0,0,13,116,102,105,108,101,110,97,109,101, + 101,100,105,116,8,100,101,98,117,103,103,101,114,3,84,97,103,2,8,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,11,36,123,68,69,66, + 85,71,71,69,82,125,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46, + 99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116,116,111,110, + 115,46,105,116,101,109,115,14,1,7,105,109,97,103,101,110,114,2,17,0, + 0,20,102,114,97,109,101,46,98,117,116,116,111,110,46,105,109,97,103,101, + 110,114,2,17,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109, + 101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114, + 2,8,4,104,105,110,116,6,23,80,97,116,104,32,116,111,32,100,101,98, + 117,103,103,101,114,32,40,103,100,98,41,46,8,98,111,117,110,100,115,95, + 120,2,8,8,98,111,117,110,100,115,95,121,3,40,1,9,98,111,117,110, + 100,115,95,99,120,3,74,1,9,98,111,117,110,100,115,95,99,121,2,37, + 7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110, + 95,116,111,112,8,97,110,95,114,105,103,104,116,0,10,111,110,115,101,116, + 118,97,108,117,101,7,8,115,101,116,118,97,108,117,101,22,99,111,110,116, + 114,111,108,108,101,114,46,99,97,112,116,105,111,110,111,112,101,110,6,13, + 68,101,98,117,103,103,101,114,32,112,97,116,104,24,99,111,110,116,114,111, + 108,108,101,114,46,111,110,103,101,116,102,105,108,101,110,97,109,101,7,18, + 101,112,97,110,100,102,105,108,101,110,97,109,101,109,97,99,114,111,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,13,116,102,105, + 108,101,110,97,109,101,101,100,105,116,8,99,111,109,112,105,108,101,114,3, + 84,97,103,2,7,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 11,36,123,67,79,77,80,73,76,69,82,125,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,19,102,114,97,109,101,46,98,117, + 116,116,111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46, + 98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,7,105,109,97,103, + 101,110,114,2,17,0,0,20,102,114,97,109,101,46,98,117,116,116,111,110, + 46,105,109,97,103,101,110,114,2,17,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97, + 98,111,114,100,101,114,2,7,4,104,105,110,116,6,26,80,97,116,104,32, + 116,111,32,99,111,109,112,105,108,101,114,32,40,112,112,99,51,56,54,41, + 46,8,98,111,117,110,100,115,95,120,2,8,8,98,111,117,110,100,115,95, + 121,3,3,1,9,98,111,117,110,100,115,95,99,120,3,74,1,9,98,111, + 117,110,100,115,95,99,121,2,37,7,97,110,99,104,111,114,115,11,7,97, + 110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,0,10,111,110,115,101,116,118,97,108,117,101,7,8,115,101,116,118, + 97,108,117,101,22,99,111,110,116,114,111,108,108,101,114,46,99,97,112,116, + 105,111,110,111,112,101,110,6,13,67,111,109,112,105,108,101,114,32,112,97, + 116,104,24,99,111,110,116,114,111,108,108,101,114,46,111,110,103,101,116,102, + 105,108,101,110,97,109,101,7,18,101,112,97,110,100,102,105,108,101,110,97, + 109,101,109,97,99,114,111,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,0,13,116,102,105,108,101,110,97,109,101,101,100,105,116,12, + 99,111,109,112,115,116,111,114,101,100,105,114,3,84,97,103,2,6,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,15,36,123,67,79,77,80, + 83,84,79,82,69,68,73,82,125,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,19,102,114,97,109,101,46,98,117,116,116,111, + 110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116, + 116,111,110,115,46,105,116,101,109,115,14,1,7,105,109,97,103,101,110,114, + 2,17,0,0,20,102,114,97,109,101,46,98,117,116,116,111,110,46,105,109, + 97,103,101,110,114,2,17,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114, + 100,101,114,2,6,4,104,105,110,116,6,36,68,105,114,101,99,116,111,114, + 121,32,102,111,114,32,99,111,109,112,111,110,101,110,116,32,115,116,111,114, + 101,32,102,105,108,101,115,46,8,98,111,117,110,100,115,95,120,2,8,8, + 98,111,117,110,100,115,95,121,3,222,0,9,98,111,117,110,100,115,95,99, + 120,3,74,1,9,98,111,117,110,100,115,95,99,121,2,37,7,97,110,99, + 104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110,95,116,111,112, + 8,97,110,95,114,105,103,104,116,0,10,111,110,115,101,116,118,97,108,117, + 101,7,8,115,101,116,118,97,108,117,101,26,99,111,110,116,114,111,108,108, + 101,114,46,102,105,108,116,101,114,108,105,115,116,46,100,97,116,97,1,1, + 6,13,80,114,111,106,101,99,116,32,102,105,108,101,115,6,5,42,46,112, + 114,106,0,0,18,99,111,110,116,114,111,108,108,101,114,46,111,112,116,105, + 111,110,115,11,13,102,100,111,95,100,105,114,101,99,116,111,114,121,0,22, + 99,111,110,116,114,111,108,108,101,114,46,99,97,112,116,105,111,110,111,112, + 101,110,6,30,68,105,114,101,99,116,111,114,121,32,102,111,114,32,99,111, + 109,112,111,110,101,110,116,32,115,116,111,114,101,115,24,99,111,110,116,114, + 111,108,108,101,114,46,111,110,103,101,116,102,105,108,101,110,97,109,101,7, + 18,101,112,97,110,100,102,105,108,101,110,97,109,101,109,97,99,114,111,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,13,116,102, + 105,108,101,110,97,109,101,101,100,105,116,11,116,101,109,112,108,97,116,101, + 100,105,114,3,84,97,103,2,5,13,102,114,97,109,101,46,99,97,112,116, + 105,111,110,6,14,36,123,84,69,77,80,76,65,84,69,68,73,82,125,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,19,102, + 114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1, + 19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115, + 14,1,7,105,109,97,103,101,110,114,2,17,0,0,20,102,114,97,109,101, + 46,98,117,116,116,111,110,46,105,109,97,103,101,110,114,2,17,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2, + 0,2,0,0,8,116,97,98,111,114,100,101,114,2,5,4,104,105,110,116, + 6,37,68,105,114,101,99,116,111,114,121,32,102,111,114,32,112,114,111,106, + 101,99,116,32,116,101,109,112,108,97,116,101,32,102,105,108,101,115,46,8, + 98,111,117,110,100,115,95,120,2,8,8,98,111,117,110,100,115,95,121,3, + 185,0,9,98,111,117,110,100,115,95,99,120,3,74,1,9,98,111,117,110, + 100,115,95,99,121,2,37,7,97,110,99,104,111,114,115,11,7,97,110,95, + 108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116, + 0,10,111,110,115,101,116,118,97,108,117,101,7,8,115,101,116,118,97,108, + 117,101,26,99,111,110,116,114,111,108,108,101,114,46,102,105,108,116,101,114, + 108,105,115,116,46,100,97,116,97,1,1,6,13,80,114,111,106,101,99,116, + 32,102,105,108,101,115,6,5,42,46,112,114,106,0,0,18,99,111,110,116, + 114,111,108,108,101,114,46,111,112,116,105,111,110,115,11,13,102,100,111,95, + 100,105,114,101,99,116,111,114,121,0,22,99,111,110,116,114,111,108,108,101, + 114,46,99,97,112,116,105,111,110,111,112,101,110,6,26,80,114,111,106,101, + 99,116,32,116,101,109,112,108,97,116,101,32,100,105,114,101,99,116,111,114, + 121,24,99,111,110,116,114,111,108,108,101,114,46,111,110,103,101,116,102,105, + 108,101,110,97,109,101,7,18,101,112,97,110,100,102,105,108,101,110,97,109, + 101,109,97,99,114,111,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,13,116,102,105,108,101,110,97,109,101,101,100,105,116,12,115, + 121,110,116,97,120,100,101,102,100,105,114,3,84,97,103,2,4,13,102,114, + 97,109,101,46,99,97,112,116,105,111,110,6,15,36,123,83,89,78,84,65, + 88,68,69,70,68,73,82,125,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,19,102,114,97,109,101,46,98,117,116,116,111,110, + 115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116,116, + 111,110,115,46,105,116,101,109,115,14,1,7,105,109,97,103,101,110,114,2, + 17,0,0,20,102,114,97,109,101,46,98,117,116,116,111,110,46,105,109,97, + 103,101,110,114,2,17,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100, + 101,114,2,4,4,104,105,110,116,6,38,68,105,114,101,99,116,111,114,121, + 32,102,111,114,32,115,121,110,116,97,120,32,100,101,102,105,110,105,116,105, + 111,110,32,102,105,108,101,115,46,8,98,111,117,110,100,115,95,120,2,8, + 8,98,111,117,110,100,115,95,121,3,148,0,9,98,111,117,110,100,115,95, + 99,120,3,74,1,9,98,111,117,110,100,115,95,99,121,2,37,7,97,110, + 99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110,95,116,111, + 112,8,97,110,95,114,105,103,104,116,0,10,111,110,115,101,116,118,97,108, + 117,101,7,8,115,101,116,118,97,108,117,101,26,99,111,110,116,114,111,108, + 108,101,114,46,102,105,108,116,101,114,108,105,115,116,46,100,97,116,97,1, + 1,6,18,83,121,110,116,97,120,32,100,101,102,105,110,105,116,105,111,110, + 115,6,6,42,46,115,100,101,102,0,0,18,99,111,110,116,114,111,108,108, + 101,114,46,111,112,116,105,111,110,115,11,13,102,100,111,95,100,105,114,101, + 99,116,111,114,121,0,22,99,111,110,116,114,111,108,108,101,114,46,99,97, + 112,116,105,111,110,111,112,101,110,6,37,68,105,114,101,99,116,111,114,121, + 32,102,111,114,32,115,121,110,116,97,120,32,100,101,102,105,110,105,116,105, + 111,110,32,102,105,108,101,115,24,99,111,110,116,114,111,108,108,101,114,46, + 111,110,103,101,116,102,105,108,101,110,97,109,101,7,18,101,112,97,110,100, + 102,105,108,101,110,97,109,101,109,97,99,114,111,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,14,0,0,13,116,102,105,108,101,110,97,109, + 101,101,100,105,116,9,109,115,101,108,105,98,100,105,114,3,84,97,103,2, + 3,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,12,36,123,77, + 83,69,76,73,66,68,73,82,125,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,19,102,114,97,109,101,46,98,117,116,116,111, + 110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116, + 116,111,110,115,46,105,116,101,109,115,14,1,7,105,109,97,103,101,110,114, + 2,17,0,0,20,102,114,97,109,101,46,98,117,116,116,111,110,46,105,109, + 97,103,101,110,114,2,17,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114, + 100,101,114,2,3,4,104,105,110,116,6,33,82,111,111,116,32,100,105,114, + 101,99,116,111,114,121,32,111,102,32,77,83,69,103,117,105,32,108,105,98, + 114,97,114,121,46,8,98,111,117,110,100,115,95,120,2,8,8,98,111,117, + 110,100,115,95,121,2,111,9,98,111,117,110,100,115,95,99,120,3,74,1, + 9,98,111,117,110,100,115,95,99,121,2,37,7,97,110,99,104,111,114,115, + 11,7,97,110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95, + 114,105,103,104,116,0,10,111,110,115,101,116,118,97,108,117,101,7,8,115, + 101,116,118,97,108,117,101,18,99,111,110,116,114,111,108,108,101,114,46,111, + 112,116,105,111,110,115,11,13,102,100,111,95,100,105,114,101,99,116,111,114, + 121,0,22,99,111,110,116,114,111,108,108,101,114,46,99,97,112,116,105,111, + 110,111,112,101,110,6,24,77,83,69,103,117,105,32,108,105,98,114,97,114, + 121,32,100,105,114,101,99,116,111,114,121,24,99,111,110,116,114,111,108,108, + 101,114,46,111,110,103,101,116,102,105,108,101,110,97,109,101,7,18,101,112, + 97,110,100,102,105,108,101,110,97,109,101,109,97,99,114,111,13,114,101,102, + 102,111,110,116,104,101,105,103,104,116,2,14,0,0,13,116,102,105,108,101, + 110,97,109,101,101,100,105,116,6,109,115,101,100,105,114,3,84,97,103,2, + 2,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,9,36,123,77, + 83,69,68,73,82,125,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46, + 99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116,116,111,110, + 115,46,105,116,101,109,115,14,1,7,105,109,97,103,101,110,114,2,17,0, + 0,20,102,114,97,109,101,46,98,117,116,116,111,110,46,105,109,97,103,101, + 110,114,2,17,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109, + 101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114, + 2,2,4,104,105,110,116,6,25,82,111,111,116,32,100,105,114,101,99,116, + 111,114,121,32,111,102,32,77,83,69,103,117,105,46,8,98,111,117,110,100, + 115,95,120,2,8,8,98,111,117,110,100,115,95,121,2,74,9,98,111,117, + 110,100,115,95,99,120,3,74,1,9,98,111,117,110,100,115,95,99,121,2, + 37,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97, + 110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,10,111,110,115,101, + 116,118,97,108,117,101,7,8,115,101,116,118,97,108,117,101,18,99,111,110, + 116,114,111,108,108,101,114,46,111,112,116,105,111,110,115,11,13,102,100,111, + 95,100,105,114,101,99,116,111,114,121,0,22,99,111,110,116,114,111,108,108, + 101,114,46,99,97,112,116,105,111,110,111,112,101,110,6,21,77,83,69,103, + 117,105,32,114,111,111,116,32,100,105,114,101,99,116,111,114,121,24,99,111, + 110,116,114,111,108,108,101,114,46,111,110,103,101,116,102,105,108,101,110,97, + 109,101,7,18,101,112,97,110,100,102,105,108,101,110,97,109,101,109,97,99, + 114,111,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0, + 13,116,102,105,108,101,110,97,109,101,101,100,105,116,9,102,112,99,108,105, + 98,100,105,114,3,84,97,103,2,1,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,12,36,123,70,80,67,76,73,66,68,73,82,125,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,19,102,114, + 97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1,19, + 102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14, + 1,7,105,109,97,103,101,110,114,2,17,0,0,20,102,114,97,109,101,46, + 98,117,116,116,111,110,46,105,109,97,103,101,110,114,2,17,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0, + 2,0,0,8,116,97,98,111,114,100,101,114,2,1,4,104,105,110,116,6, + 74,82,111,111,116,32,100,105,114,101,99,116,111,114,121,32,111,102,32,70, + 80,67,32,108,105,98,114,97,114,121,32,40,110,111,116,32,117,115,101,100, + 32,98,121,32,116,104,101,32,100,101,102,97,117,108,116,32,112,114,111,106, + 101,99,116,32,116,101,109,112,108,97,116,101,115,41,46,8,98,111,117,110, + 100,115,95,120,2,8,8,98,111,117,110,100,115,95,121,2,37,9,98,111, + 117,110,100,115,95,99,120,3,74,1,9,98,111,117,110,100,115,95,99,121, + 2,37,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6, + 97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,18,99,111,110, + 116,114,111,108,108,101,114,46,111,112,116,105,111,110,115,11,13,102,100,111, + 95,100,105,114,101,99,116,111,114,121,0,22,99,111,110,116,114,111,108,108, + 101,114,46,99,97,112,116,105,111,110,111,112,101,110,6,21,70,80,67,32, + 108,105,98,114,97,114,121,32,100,105,114,101,99,116,111,114,121,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,13,116,102,105,108, + 101,110,97,109,101,101,100,105,116,6,102,112,99,100,105,114,13,102,114,97, + 109,101,46,99,97,112,116,105,111,110,6,9,36,123,70,80,67,68,73,82, + 125,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116, + 2,1,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101, + 109,115,14,1,7,105,109,97,103,101,110,114,2,17,0,0,20,102,114,97, + 109,101,46,98,117,116,116,111,110,46,105,109,97,103,101,110,114,2,17,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2, + 17,2,0,2,0,0,4,104,105,110,116,6,81,82,111,111,116,32,100,105, + 114,101,99,116,111,114,121,32,111,102,32,70,114,101,101,32,80,97,115,99, + 97,108,32,115,121,115,116,101,109,32,40,110,111,116,32,117,115,101,100,32, + 98,121,32,116,104,101,32,100,101,102,97,117,108,116,32,112,114,111,106,101, + 99,116,32,116,101,109,112,108,97,116,101,115,41,46,8,98,111,117,110,100, + 115,95,120,2,8,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,120,3,74,1,9,98,111,117,110,100,115,95,99,121,2, + 37,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97, + 110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,10,111,110,115,101, + 116,118,97,108,117,101,7,8,115,101,116,118,97,108,117,101,18,99,111,110, + 116,114,111,108,108,101,114,46,111,112,116,105,111,110,115,11,13,102,100,111, + 95,100,105,114,101,99,116,111,114,121,0,22,99,111,110,116,114,111,108,108, + 101,114,46,99,97,112,116,105,111,110,111,112,101,110,6,18,70,80,67,32, + 114,111,111,116,32,100,105,114,101,99,116,111,114,121,24,99,111,110,116,114, + 111,108,108,101,114,46,111,110,103,101,116,102,105,108,101,110,97,109,101,7, + 18,101,112,97,110,100,102,105,108,101,110,97,109,101,109,97,99,114,111,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,11,116, + 119,105,100,103,101,116,103,114,105,100,9,109,97,99,114,111,103,114,105,100, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,13,71,108,111,98, + 97,108,32,77,97,99,114,111,115,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111, + 114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,8,8,98,111, + 117,110,100,115,95,121,3,151,1,9,98,111,117,110,100,115,95,99,120,3, + 74,1,9,98,111,117,110,100,115,95,99,121,2,113,12,98,111,117,110,100, + 115,95,99,121,109,105,110,2,80,7,97,110,99,104,111,114,115,11,7,97, + 110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,9,97,110,95,98,111,116,116,111,109,0,11,111,112,116,105,111,110, + 115,103,114,105,100,11,12,111,103,95,99,111,108,115,105,122,105,110,103,12, + 111,103,95,114,111,119,109,111,118,105,110,103,15,111,103,95,107,101,121,114, + 111,119,109,111,118,105,110,103,15,111,103,95,114,111,119,105,110,115,101,114, + 116,105,110,103,14,111,103,95,114,111,119,100,101,108,101,116,105,110,103,19, + 111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101,114,15, + 111,103,95,97,117,116,111,102,105,114,115,116,114,111,119,13,111,103,95,97, + 117,116,111,97,112,112,101,110,100,16,111,103,95,110,111,105,110,115,101,114, + 116,101,109,112,116,121,20,111,103,95,99,111,108,99,104,97,110,103,101,111, + 110,116,97,98,107,101,121,10,111,103,95,119,114,97,112,99,111,108,12,111, + 103,95,97,117,116,111,112,111,112,117,112,17,111,103,95,109,111,117,115,101, + 115,99,114,111,108,108,99,111,108,0,13,102,105,120,99,111,108,115,46,99, + 111,117,110,116,2,1,13,102,105,120,99,111,108,115,46,105,116,101,109,115, + 14,1,5,119,105,100,116,104,2,28,8,110,117,109,115,116,97,114,116,2, + 1,7,110,117,109,115,116,101,112,2,1,0,0,13,102,105,120,114,111,119, + 115,46,99,111,117,110,116,2,1,13,102,105,120,114,111,119,115,46,105,116, + 101,109,115,14,1,6,104,101,105,103,104,116,2,16,14,99,97,112,116,105, + 111,110,115,46,99,111,117,110,116,2,4,14,99,97,112,116,105,111,110,115, + 46,105,116,101,109,115,14,1,7,99,97,112,116,105,111,110,6,4,78,97, + 109,101,0,1,7,99,97,112,116,105,111,110,6,5,86,97,108,117,101,0, + 1,0,1,0,0,0,0,14,100,97,116,97,99,111,108,115,46,99,111,117, + 110,116,2,2,16,100,97,116,97,99,111,108,115,46,111,112,116,105,111,110, + 115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111, + 95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115, + 101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116, + 12,99,111,95,114,111,119,115,101,108,101,99,116,12,99,111,95,115,97,118, + 101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111, + 95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99, + 114,111,108,108,114,111,119,0,14,100,97,116,97,99,111,108,115,46,105,116, + 101,109,115,14,7,9,109,97,99,114,111,110,97,109,101,1,5,119,105,100, + 116,104,3,151,0,7,111,112,116,105,111,110,115,11,14,99,111,95,102,111, + 99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101, + 108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111, + 95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115, + 101,108,101,99,116,15,99,111,95,112,114,111,112,111,114,116,105,111,110,97, + 108,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97, + 110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111, + 95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100, + 103,101,116,110,97,109,101,6,9,109,97,99,114,111,110,97,109,101,9,100, + 97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116, + 114,105,110,103,100,97,116,97,108,105,115,116,0,7,10,109,97,99,114,111, + 118,97,108,117,101,1,5,119,105,100,116,104,3,144,0,7,111,112,116,105, + 111,110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14, + 99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101, + 121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101, + 99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,7,99,111,95,102, + 105,108,108,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95, + 99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17, + 99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119, + 105,100,103,101,116,110,97,109,101,6,10,109,97,99,114,111,118,97,108,117, + 101,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115, + 101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,0,13,100,97, + 116,97,114,111,119,104,101,105,103,104,116,2,16,8,115,116,97,116,102,105, + 108,101,7,10,116,115,116,97,116,102,105,108,101,49,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,14,0,11,116,115,116,114,105,110,103,101, + 100,105,116,9,109,97,99,114,111,110,97,109,101,11,111,112,116,105,111,110, + 115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116, + 111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,1,7,118, + 105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,0,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3, + 151,0,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111, + 110,115,101,100,105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105, + 116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99, + 108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114, + 99,97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114, + 110,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101, + 115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101, + 120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110, + 101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25, + 111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116, + 99,108,105,99,107,22,111,101,95,102,111,99,117,115,114,101,99,116,111,110, + 114,101,97,100,111,110,108,121,18,111,101,95,104,105,110,116,99,108,105,112, + 112,101,100,116,101,120,116,0,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,14,0,0,15,116,109,101,109,111,100,105,97,108,111,103,101,100, + 105,116,10,109,97,99,114,111,118,97,108,117,101,14,111,112,116,105,111,110, + 115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108, + 121,112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110,115,115,107, + 105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111, + 110,108,121,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,17, + 102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,3,0, + 0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,114,108,95,108,101,118,101,108,111,10,102,114,108,95,108,101,118,101, + 108,105,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,19, + 102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2, + 1,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109, + 115,14,1,5,99,111,108,111,114,4,5,0,0,144,7,105,109,97,103,101, + 110,114,2,17,0,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46, + 99,111,108,111,114,4,5,0,0,144,20,102,114,97,109,101,46,98,117,116, + 116,111,110,46,105,109,97,103,101,110,114,2,17,8,116,97,98,111,114,100, + 101,114,2,2,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115, + 95,120,3,152,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,120,3,144,0,9,98,111,117,110,100,115,95,99,121,2, + 16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,0,11,111,112,116, + 105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101, + 115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95, + 99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105, + 102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114, + 110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120, + 105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111, + 101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111, + 115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116, + 111,110,102,105,114,115,116,99,108,105,99,107,22,111,101,95,102,111,99,117, + 115,114,101,99,116,111,110,114,101,97,100,111,110,108,121,18,111,101,95,104, + 105,110,116,99,108,105,112,112,101,100,116,101,120,116,0,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,0,9,116,115,116,97,116, + 102,105,108,101,10,116,115,116,97,116,102,105,108,101,49,8,102,105,108,101, + 110,97,109,101,6,14,115,101,116,116,105,110,103,115,102,111,46,115,116,97, + 7,111,112,116,105,111,110,115,11,10,115,102,111,95,109,101,109,111,114,121, + 0,4,108,101,102,116,2,16,3,116,111,112,2,32,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tsettingsfo,''); +end. diff --git a/mseide-msegui/lib/common/designutils/mseskindesign.pas b/mseide-msegui/lib/common/designutils/mseskindesign.pas new file mode 100644 index 0000000..5dcb364 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/mseskindesign.pas @@ -0,0 +1,87 @@ +{ MSEide Copyright (c) 2010 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit mseskindesign; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseskin,mseclasses,classes; + +type + tskinhandlerdesign = class(tskinhandler) + protected + factiveskincontrollerdesign: skincontrollerarty; + procedure updateactive(const sender: tcustomskincontroller); override; +// procedure updateskindesign(const ainfo: skininfoty); +// procedure removeskindesign(const ainfo: skininfoty); +// procedure doactivate(const sender: tcustomskincontroller); override; +// procedure dodeactivate(const sender: tcustomskincontroller); override; + end; + +implementation +uses + msedesigner; + +{ tskinhandlerdesign } +{ +procedure tskinhandlerdesign.updateskindesign(const ainfo: skininfoty); +begin + updateskin1(ainfo,factiveskincontrollerdesign); +end; + +procedure tskinhandlerdesign.removeskindesign(const ainfo: skininfoty); +begin + removeskin1(ainfo,factiveskincontrollerdesign); +end; +} +procedure tskinhandlerdesign.updateactive(const sender: tcustomskincontroller); +begin + if csdesigning in sender.componentstate then begin + //do nothing +// setactive(sender,factiveskincontrollerdesign, +// @updateskindesign,oninitskinobjectdesign{, +// @removeskindesign,onremoveskinobjectdesign}); + end + else begin + inherited; + end; +end; +{ +procedure tskinhandlerdesign.doactivate(const sender: tcustomskincontroller); +var + int1: integer; +begin + if csdesigning in sender.componentstate then begin + for int1:= 0 to designer.modules.count - 1 do begin + designer.modules.itempo[int1]^.instance.updateskin(true); + end; + end; +end; + +procedure tskinhandlerdesign.dodeactivate(const sender: tcustomskincontroller); +var + int1: integer; +begin + if csdesigning in sender.componentstate then begin + for int1:= 0 to designer.modules.count - 1 do begin + designer.modules.itempo[int1]^.instance.removeskin(true); + end; + end; +end; +} +initialization + setskinhandler(tskinhandlerdesign.create); +end. diff --git a/mseide-msegui/lib/common/designutils/msestringintlisteditor.mfm b/mseide-msegui/lib/common/designutils/msestringintlisteditor.mfm new file mode 100644 index 0000000..9e6d032 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msestringintlisteditor.mfm @@ -0,0 +1,133 @@ +object msestringintlisteditor: tmsestringintlisteditor + bounds_x = 130 + bounds_y = 203 + bounds_cx = 338 + bounds_cy = 194 + container.bounds = ( + 0 + 0 + 338 + 194 + ) + options = [fo_closeonesc, fo_autoreadstat, fo_autowritestat] + statfile = tstatfile1 + caption = 'Stringlisteditor' + moduleclassname = 'tmseform' + object ok: tbutton + taborder = 3 + bounds_x = 212 + bounds_y = 160 + bounds_cx = 50 + bounds_cy = 20 + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + end + object cancel: tbutton + bounds_x = 276 + bounds_y = 160 + bounds_cx = 50 + bounds_cy = 20 + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + end + object grid: twidgetgrid + taborder = 2 + bounds_x = 8 + bounds_y = 8 + bounds_cx = 320 + bounds_cy = 140 + anchors = [an_left, an_top, an_right, an_bottom] + optionsgrid = [og_colsizing, og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_wrapcol] + fixcols.count = 1 + fixcols.items = < + item + width = 31 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 3 + captions.items = < + item + caption = 'a' + textflags = [] + end + item + caption = 'b' + end + item + caption = 'b' + textflags = [] + end> + end> + datacols.count = 2 + datacols.items = < + item[texta] + width = 232 + options = [co_fill, co_savevalue, co_savestate, co_mousescrollrow] + widgetname = 'texta' + dataclass = tgridmsestringdatalist + end + item[textb] + widgetname = 'textb' + dataclass = tgridintegerdatalist + end> + datarowheight = 16 + onrowcountchanged = gridonrowcountchanged + reffontheight = 14 + object texta: tstringedit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.dummy = 0 + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 232 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + reffontheight = 14 + end + object textb: tintegeredit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 2 + visible = False + bounds_x = 233 + bounds_y = 0 + bounds_cx = 50 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + reffontheight = 14 + end + end + object rowcount: tintegeredit + frame.caption = 'Rowcount' + frame.captionpos = cp_right + frame.dummy = 0 + frame.outerframe = ( + 0 + 0 + 64 + 0 + ) + taborder = 1 + bounds_x = 36 + bounds_y = 160 + bounds_cx = 114 + onsetvalue = rowcountonsetvalue + reffontheight = 14 + end + object tstatfile1: tstatfile + filename = 'doublestringlisteditor.sta' + options = [sfo_memory] + left = 40 + top = 88 + end +end diff --git a/mseide-msegui/lib/common/designutils/msestringintlisteditor.pas b/mseide-msegui/lib/common/designutils/msestringintlisteditor.pas new file mode 100644 index 0000000..ebd4c55 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msestringintlisteditor.pas @@ -0,0 +1,59 @@ +{ MSEgui Copyright (c) 2009-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msestringintlisteditor; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseforms,msedataedits,msesimplewidgets,msewidgetgrid,msegrids,mseclasses, + msedialog,mseedit,mseglob,msegraphics,msegraphutils,msegui,mseguiglob,msemenus, + msestrings,msetypes,msestat,msestatfile; +type + tmsestringintlisteditor = class(tmseform) + cancel: tbutton; + ok: tbutton; + grid: twidgetgrid; + texta: tstringedit; + rowcount: tintegeredit; + textb: tintegeredit; + tstatfile1: tstatfile; + procedure rowcountonsetvalue(const sender: tobject; var avalue: integer; + var accept: boolean); + procedure gridonrowcountchanged(const sender: tcustomgrid); + public + constructor create(const aonclosequery: closequeryeventty); reintroduce; + end; + +implementation +uses + msestringintlisteditor_mfm; + +{ tmsestringintlisteditor } + +constructor tmsestringintlisteditor.create(const aonclosequery: closequeryeventty); +begin + onclosequery:= aonclosequery; + inherited create(nil); +end; + +procedure tmsestringintlisteditor.gridonrowcountchanged( + const sender: tcustomgrid); +begin + rowcount.value:= sender.rowcount; +end; + +procedure tmsestringintlisteditor.rowcountonsetvalue(const sender: tobject; + var avalue: integer; var accept: boolean); +begin + grid.rowcount:= avalue; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/msestringintlisteditor_mfm.pas b/mseide-msegui/lib/common/designutils/msestringintlisteditor_mfm.pas new file mode 100644 index 0000000..19c91d6 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msestringintlisteditor_mfm.pas @@ -0,0 +1,121 @@ +unit msestringintlisteditor_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msestringintlisteditor; + +const + objdata: record size: integer; data: array[0..2076] of byte end = + (size: 2077; data: ( + 84,80,70,48,23,116,109,115,101,115,116,114,105,110,103,105,110,116,108,105, + 115,116,101,100,105,116,111,114,22,109,115,101,115,116,114,105,110,103,105,110, + 116,108,105,115,116,101,100,105,116,111,114,8,98,111,117,110,100,115,95,120, + 3,130,0,8,98,111,117,110,100,115,95,121,3,203,0,9,98,111,117,110, + 100,115,95,99,120,3,82,1,9,98,111,117,110,100,115,95,99,121,3,194, + 0,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2, + 0,2,0,3,82,1,3,194,0,0,7,111,112,116,105,111,110,115,11,13, + 102,111,95,99,108,111,115,101,111,110,101,115,99,15,102,111,95,97,117,116, + 111,114,101,97,100,115,116,97,116,16,102,111,95,97,117,116,111,119,114,105, + 116,101,115,116,97,116,0,8,115,116,97,116,102,105,108,101,7,10,116,115, + 116,97,116,102,105,108,101,49,7,99,97,112,116,105,111,110,6,16,83,116, + 114,105,110,103,108,105,115,116,101,100,105,116,111,114,15,109,111,100,117,108, + 101,99,108,97,115,115,110,97,109,101,6,8,116,109,115,101,102,111,114,109, + 0,7,116,98,117,116,116,111,110,2,111,107,8,116,97,98,111,114,100,101, + 114,2,3,8,98,111,117,110,100,115,95,120,3,212,0,8,98,111,117,110, + 100,115,95,121,3,160,0,9,98,111,117,110,100,115,95,99,120,2,50,9, + 98,111,117,110,100,115,95,99,121,2,20,5,115,116,97,116,101,11,10,97, + 115,95,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,100,101, + 102,97,117,108,116,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111, + 110,0,7,99,97,112,116,105,111,110,6,3,38,79,75,11,109,111,100,97, + 108,114,101,115,117,108,116,7,5,109,114,95,111,107,0,0,7,116,98,117, + 116,116,111,110,6,99,97,110,99,101,108,8,98,111,117,110,100,115,95,120, + 3,20,1,8,98,111,117,110,100,115,95,121,3,160,0,9,98,111,117,110, + 100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,20,5, + 115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105, + 111,110,0,7,99,97,112,116,105,111,110,6,7,38,67,97,110,99,101,108, + 11,109,111,100,97,108,114,101,115,117,108,116,7,9,109,114,95,99,97,110, + 99,101,108,0,0,11,116,119,105,100,103,101,116,103,114,105,100,4,103,114, + 105,100,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115, + 95,120,2,8,8,98,111,117,110,100,115,95,121,2,8,9,98,111,117,110, + 100,115,95,99,120,3,64,1,9,98,111,117,110,100,115,95,99,121,3,140, + 0,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97, + 110,95,116,111,112,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111, + 116,116,111,109,0,11,111,112,116,105,111,110,115,103,114,105,100,11,12,111, + 103,95,99,111,108,115,105,122,105,110,103,12,111,103,95,114,111,119,109,111, + 118,105,110,103,15,111,103,95,107,101,121,114,111,119,109,111,118,105,110,103, + 15,111,103,95,114,111,119,105,110,115,101,114,116,105,110,103,14,111,103,95, + 114,111,119,100,101,108,101,116,105,110,103,19,111,103,95,102,111,99,117,115, + 99,101,108,108,111,110,101,110,116,101,114,15,111,103,95,97,117,116,111,102, + 105,114,115,116,114,111,119,13,111,103,95,97,117,116,111,97,112,112,101,110, + 100,10,111,103,95,119,114,97,112,99,111,108,0,13,102,105,120,99,111,108, + 115,46,99,111,117,110,116,2,1,13,102,105,120,99,111,108,115,46,105,116, + 101,109,115,14,1,5,119,105,100,116,104,2,31,7,110,117,109,115,116,101, + 112,2,1,0,0,13,102,105,120,114,111,119,115,46,99,111,117,110,116,2, + 1,13,102,105,120,114,111,119,115,46,105,116,101,109,115,14,1,6,104,101, + 105,103,104,116,2,16,14,99,97,112,116,105,111,110,115,46,99,111,117,110, + 116,2,3,14,99,97,112,116,105,111,110,115,46,105,116,101,109,115,14,1, + 7,99,97,112,116,105,111,110,6,1,97,9,116,101,120,116,102,108,97,103, + 115,11,0,0,1,7,99,97,112,116,105,111,110,6,1,98,0,1,7,99, + 97,112,116,105,111,110,6,1,98,9,116,101,120,116,102,108,97,103,115,11, + 0,0,0,0,0,14,100,97,116,97,99,111,108,115,46,99,111,117,110,116, + 2,2,14,100,97,116,97,99,111,108,115,46,105,116,101,109,115,14,7,5, + 116,101,120,116,97,1,5,119,105,100,116,104,3,232,0,7,111,112,116,105, + 111,110,115,11,7,99,111,95,102,105,108,108,12,99,111,95,115,97,118,101, + 118,97,108,117,101,12,99,111,95,115,97,118,101,115,116,97,116,101,17,99, + 111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105, + 100,103,101,116,110,97,109,101,6,5,116,101,120,116,97,9,100,97,116,97, + 99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116,114,105,110, + 103,100,97,116,97,108,105,115,116,0,7,5,116,101,120,116,98,1,10,119, + 105,100,103,101,116,110,97,109,101,6,5,116,101,120,116,98,9,100,97,116, + 97,99,108,97,115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114, + 100,97,116,97,108,105,115,116,0,0,13,100,97,116,97,114,111,119,104,101, + 105,103,104,116,2,16,17,111,110,114,111,119,99,111,117,110,116,99,104,97, + 110,103,101,100,7,21,103,114,105,100,111,110,114,111,119,99,111,117,110,116, + 99,104,97,110,103,101,100,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,11,116,115,116,114,105,110,103,101,100,105,116,5,116,101,120, + 116,97,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95, + 102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,12,102,114,97, + 109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99,111, + 108,111,114,99,108,105,101,110,116,4,2,0,0,128,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 11,102,114,97,109,101,46,100,117,109,109,121,2,0,8,116,97,98,111,114, + 100,101,114,2,1,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100, + 115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,120,3,232,0,9,98,111,117,110,100,115,95,99,121,2, + 16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,13,111,101,49,95, + 115,97,118,101,118,97,108,117,101,0,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,14,0,0,12,116,105,110,116,101,103,101,114,101,100,105, + 116,5,116,101,120,116,98,14,111,112,116,105,111,110,115,119,105,100,103,101, + 116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105, + 103,104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115, + 107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116, + 97,98,111,114,100,101,114,2,2,7,118,105,115,105,98,108,101,8,8,98, + 111,117,110,100,115,95,120,3,233,0,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115, + 95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,13, + 111,101,49,95,115,97,118,101,118,97,108,117,101,0,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,14,0,0,0,12,116,105,110,116,101,103, + 101,114,101,100,105,116,8,114,111,119,99,111,117,110,116,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,8,82,111,119,99,111,117,110,116,16, + 102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112, + 95,114,105,103,104,116,11,102,114,97,109,101,46,100,117,109,109,121,2,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,0,2,64,2,0,0,8,116,97,98,111,114,100,101,114,2,1,8,98, + 111,117,110,100,115,95,120,2,36,8,98,111,117,110,100,115,95,121,3,160, + 0,9,98,111,117,110,100,115,95,99,120,2,114,10,111,110,115,101,116,118, + 97,108,117,101,7,18,114,111,119,99,111,117,110,116,111,110,115,101,116,118, + 97,108,117,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,0,9,116,115,116,97,116,102,105,108,101,10,116,115,116,97,116,102,105, + 108,101,49,8,102,105,108,101,110,97,109,101,6,26,100,111,117,98,108,101, + 115,116,114,105,110,103,108,105,115,116,101,100,105,116,111,114,46,115,116,97, + 7,111,112,116,105,111,110,115,11,10,115,102,111,95,109,101,109,111,114,121, + 0,4,108,101,102,116,2,40,3,116,111,112,2,88,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tmsestringintlisteditor,''); +end. diff --git a/mseide-msegui/lib/common/designutils/msestringlisteditor.mfm b/mseide-msegui/lib/common/designutils/msestringlisteditor.mfm new file mode 100644 index 0000000..102ef4b --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msestringlisteditor.mfm @@ -0,0 +1,112 @@ +object stringlisteditor: tstringlisteditor + optionswidget = [ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets, ow_hinton] + visible = False + bounds_x = 177 + bounds_y = 203 + bounds_cx = 275 + bounds_cy = 237 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.bounds = ( + 0 + 0 + 275 + 237 + ) + options = [fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos] + statfile = tstatfile1 + caption = 'Stringlisteditor' + moduleclassname = 'tmseform' + object ok: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + taborder = 3 + bounds_x = 160 + bounds_y = 210 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_left, an_bottom] + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + reffontheight = 14 + end + object cancel: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + bounds_x = 216 + bounds_y = 210 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_left, an_bottom] + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + reffontheight = 14 + end + object grid: twidgetgrid + optionswidget1 = [ow1_fontlineheight] + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusout, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 275 + bounds_cy = 198 + anchors = [an_top, an_bottom] + optionsgrid = [og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_wrapcol, og_autopopup] + fixcols.count = 1 + fixcols.items = < + item + width = 24 + numstep = 1 + end> + zebra_start = 1 + zebra_height = 1 + datacols.count = 1 + datacols.items = < + item[valueedit] + width = 245 + options = [co_fill, co_savestate, co_mousescrollrow] + widgetname = 'valueedit' + dataclass = tgridrichstringdatalist + end> + datarowheight = 16 + onrowcountchanged = gridonrowcountchanged + reffontheight = 14 + object valueedit: ttextedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + optionsskin = [osk_framebuttononly] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 245 + bounds_cy = 16 + optionsedit1 = [oe1_keyexecute, oe1_savestate] + optionsedit = [oe_closequery, oe_checkmrcancel, oe_linebreak, oe_shiftreturn, oe_eatreturn, oe_exitoncursor] + reffontheight = 14 + end + end + object rowcount: tintegeredit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.caption = 'Rowcount' + frame.captionpos = cp_left + frame.dummy = 0 + frame.outerframe = ( + 64 + 0 + 0 + 0 + ) + taborder = 2 + bounds_x = 16 + bounds_y = 210 + bounds_cx = 116 + anchors = [an_left, an_bottom] + onsetvalue = rowcountonsetvalue + reffontheight = 14 + end + object tstatfile1: tstatfile + filename = 'stringlisteditor.sta' + options = [sfo_memory] + left = 40 + top = 88 + end +end diff --git a/mseide-msegui/lib/common/designutils/msestringlisteditor.pas b/mseide-msegui/lib/common/designutils/msestringlisteditor.pas new file mode 100644 index 0000000..8ee3809 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msestringlisteditor.pas @@ -0,0 +1,61 @@ +{ MSEgui Copyright (c) 1999-20012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msestringlisteditor; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseforms,msedataedits,msesimplewidgets,msewidgetgrid,msegrids,msetextedit, + msestat,msestatfile; + +const + stringlisteditorstatname = 'stringlisteditor.sta'; + +type + tstringlisteditor = class(tmseform) + cancel: tbutton; + ok: tbutton; + grid: twidgetgrid; + valueedit: ttextedit; + rowcount: tintegeredit; + tstatfile1: tstatfile; + procedure rowcountonsetvalue(const sender: tobject; var avalue: integer; + var accept: boolean); + procedure gridonrowcountchanged(const sender: tcustomgrid); + public + constructor create(const aonclosequery: closequeryeventty); reintroduce; + end; + +implementation +uses + msestringlisteditor_mfm,mseeditglob,msetypes; + +{ tstringlisteditor } + +constructor tstringlisteditor.create(const aonclosequery: closequeryeventty); +begin + inherited create(nil); + onclosequery:= aonclosequery; +end; + +procedure tstringlisteditor.gridonrowcountchanged( + const sender: tcustomgrid); +begin + rowcount.value:= sender.rowcount; +end; + +procedure tstringlisteditor.rowcountonsetvalue(const sender: tobject; + var avalue: integer; var accept: boolean); +begin + grid.rowcount:= avalue; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/msestringlisteditor_mfm.pas b/mseide-msegui/lib/common/designutils/msestringlisteditor_mfm.pas new file mode 100644 index 0000000..925c0ad --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msestringlisteditor_mfm.pas @@ -0,0 +1,144 @@ +unit msestringlisteditor_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msestringlisteditor; + +const + objdata: record size: integer; data: array[0..2532] of byte end = + (size: 2533; data: ( + 84,80,70,48,17,116,115,116,114,105,110,103,108,105,115,116,101,100,105,116, + 111,114,16,115,116,114,105,110,103,108,105,115,116,101,100,105,116,111,114,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,9,111,119,95,104,105,110,116,111, + 110,0,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120, + 3,177,0,8,98,111,117,110,100,115,95,121,3,203,0,9,98,111,117,110, + 100,115,95,99,120,3,19,1,9,98,111,117,110,100,115,95,99,121,3,237, + 0,23,99,111,110,116,97,105,110,101,114,46,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115, + 11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115, + 105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,11, + 111,119,95,115,117,98,102,111,99,117,115,19,111,119,95,109,111,117,115,101, + 116,114,97,110,115,112,97,114,101,110,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,16,99,111,110,116,97,105,110,101,114, + 46,98,111,117,110,100,115,1,2,0,2,0,3,19,1,3,237,0,0,7, + 111,112,116,105,111,110,115,11,13,102,111,95,99,108,111,115,101,111,110,101, + 115,99,15,102,111,95,97,117,116,111,114,101,97,100,115,116,97,116,16,102, + 111,95,97,117,116,111,119,114,105,116,101,115,116,97,116,10,102,111,95,115, + 97,118,101,112,111,115,0,8,115,116,97,116,102,105,108,101,7,10,116,115, + 116,97,116,102,105,108,101,49,7,99,97,112,116,105,111,110,6,16,83,116, + 114,105,110,103,108,105,115,116,101,100,105,116,111,114,15,109,111,100,117,108, + 101,99,108,97,115,115,110,97,109,101,6,8,116,109,115,101,102,111,114,109, + 0,7,116,98,117,116,116,111,110,2,111,107,14,111,112,116,105,111,110,115, + 119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121, + 112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99,97, + 108,101,0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117,110,100, + 115,95,120,3,160,0,8,98,111,117,110,100,115,95,121,3,210,0,9,98, + 111,117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121, + 2,20,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,9, + 97,110,95,98,111,116,116,111,109,0,5,115,116,97,116,101,11,10,97,115, + 95,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,100,101,102, + 97,117,108,116,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110, + 0,7,99,97,112,116,105,111,110,6,3,38,79,75,11,109,111,100,97,108, + 114,101,115,117,108,116,7,5,109,114,95,111,107,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,14,0,0,7,116,98,117,116,116,111,110,6, + 99,97,110,99,101,108,14,111,112,116,105,111,110,115,119,105,100,103,101,116, + 49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103, + 104,116,13,111,119,49,95,97,117,116,111,115,99,97,108,101,0,8,98,111, + 117,110,100,115,95,120,3,216,0,8,98,111,117,110,100,115,95,121,3,210, + 0,9,98,111,117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115, + 95,99,121,2,20,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101, + 102,116,9,97,110,95,98,111,116,116,111,109,0,5,115,116,97,116,101,11, + 15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,7,99,97, + 112,116,105,111,110,6,7,38,67,97,110,99,101,108,11,109,111,100,97,108, + 114,101,115,117,108,116,7,9,109,114,95,99,97,110,99,101,108,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,11,116,119,105,100, + 103,101,116,103,114,105,100,4,103,114,105,100,14,111,112,116,105,111,110,115, + 119,105,100,103,101,116,49,11,18,111,119,49,95,102,111,110,116,108,105,110, + 101,104,101,105,103,104,116,0,13,111,112,116,105,111,110,115,119,105,100,103, + 101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119, + 95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111, + 99,117,115,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116, + 17,111,119,95,102,111,99,117,115,98,97,99,107,111,110,101,115,99,13,111, + 119,95,109,111,117,115,101,119,104,101,101,108,17,111,119,95,100,101,115,116, + 114,111,121,119,105,100,103,101,116,115,0,8,116,97,98,111,114,100,101,114, + 2,1,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115, + 95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,19,1,9,98,111, + 117,110,100,115,95,99,121,3,198,0,7,97,110,99,104,111,114,115,11,6, + 97,110,95,116,111,112,9,97,110,95,98,111,116,116,111,109,0,11,111,112, + 116,105,111,110,115,103,114,105,100,11,12,111,103,95,114,111,119,109,111,118, + 105,110,103,15,111,103,95,107,101,121,114,111,119,109,111,118,105,110,103,15, + 111,103,95,114,111,119,105,110,115,101,114,116,105,110,103,14,111,103,95,114, + 111,119,100,101,108,101,116,105,110,103,19,111,103,95,102,111,99,117,115,99, + 101,108,108,111,110,101,110,116,101,114,15,111,103,95,97,117,116,111,102,105, + 114,115,116,114,111,119,10,111,103,95,119,114,97,112,99,111,108,12,111,103, + 95,97,117,116,111,112,111,112,117,112,0,13,102,105,120,99,111,108,115,46, + 99,111,117,110,116,2,1,13,102,105,120,99,111,108,115,46,105,116,101,109, + 115,14,1,5,119,105,100,116,104,2,24,7,110,117,109,115,116,101,112,2, + 1,0,0,11,122,101,98,114,97,95,115,116,97,114,116,2,1,12,122,101, + 98,114,97,95,104,101,105,103,104,116,2,1,14,100,97,116,97,99,111,108, + 115,46,99,111,117,110,116,2,1,14,100,97,116,97,99,111,108,115,46,105, + 116,101,109,115,14,7,9,118,97,108,117,101,101,100,105,116,1,5,119,105, + 100,116,104,3,245,0,7,111,112,116,105,111,110,115,11,7,99,111,95,102, + 105,108,108,12,99,111,95,115,97,118,101,115,116,97,116,101,17,99,111,95, + 109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103, + 101,116,110,97,109,101,6,9,118,97,108,117,101,101,100,105,116,9,100,97, + 116,97,99,108,97,115,115,7,23,116,103,114,105,100,114,105,99,104,115,116, + 114,105,110,103,100,97,116,97,108,105,115,116,0,0,13,100,97,116,97,114, + 111,119,104,101,105,103,104,116,2,16,17,111,110,114,111,119,99,111,117,110, + 116,99,104,97,110,103,101,100,7,21,103,114,105,100,111,110,114,111,119,99, + 111,117,110,116,99,104,97,110,103,101,100,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,9,116,116,101,120,116,101,100,105,116,9,118, + 97,108,117,101,101,100,105,116,13,111,112,116,105,111,110,115,119,105,100,103, + 101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119, + 95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111, + 99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16, + 111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,11,111,112,116,105, + 111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117, + 116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,1, + 7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,3,245,0,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116, + 105,111,110,115,101,100,105,116,49,11,14,111,101,49,95,107,101,121,101,120, + 101,99,117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0, + 11,111,112,116,105,111,110,115,101,100,105,116,11,13,111,101,95,99,108,111, + 115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97, + 110,99,101,108,12,111,101,95,108,105,110,101,98,114,101,97,107,14,111,101, + 95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114, + 101,116,117,114,110,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111, + 114,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0, + 0,12,116,105,110,116,101,103,101,114,101,100,105,116,8,114,111,119,99,111, + 117,110,116,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,8,82,111,119,99,111,117,110,116,16,102,114,97,109,101, + 46,99,97,112,116,105,111,110,112,111,115,7,7,99,112,95,108,101,102,116, + 11,102,114,97,109,101,46,100,117,109,109,121,2,0,16,102,114,97,109,101, + 46,111,117,116,101,114,102,114,97,109,101,1,2,64,2,0,2,0,2,0, + 0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95, + 120,2,16,8,98,111,117,110,100,115,95,121,3,210,0,9,98,111,117,110, + 100,115,95,99,120,2,116,7,97,110,99,104,111,114,115,11,7,97,110,95, + 108,101,102,116,9,97,110,95,98,111,116,116,111,109,0,10,111,110,115,101, + 116,118,97,108,117,101,7,18,114,111,119,99,111,117,110,116,111,110,115,101, + 116,118,97,108,117,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,9,116,115,116,97,116,102,105,108,101,10,116,115,116,97,116, + 102,105,108,101,49,8,102,105,108,101,110,97,109,101,6,20,115,116,114,105, + 110,103,108,105,115,116,101,100,105,116,111,114,46,115,116,97,7,111,112,116, + 105,111,110,115,11,10,115,102,111,95,109,101,109,111,114,121,0,4,108,101, + 102,116,2,40,3,116,111,112,2,88,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tstringlisteditor,''); +end. diff --git a/mseide-msegui/lib/common/designutils/msesyntaxedit.pas b/mseide-msegui/lib/common/designutils/msesyntaxedit.pas new file mode 100644 index 0000000..12810c3 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msesyntaxedit.pas @@ -0,0 +1,1440 @@ +{ MSEgui Copyright (c) 1999-2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msesyntaxedit; + +{$ifdef FPC}{$mode objfpc}{$h+}{$goto on}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses,msetextedit,msesyntaxpainter,mseclasses,msegraphutils, + mseglob,mseguiglob,msetypes,mseevent,mserichstring, + mseeditglob,msestrings,msewidgetgrid,msedatalist,msemenus,msegui,mseinplaceedit, + msegrids,mseedit,msegraphics; + +type + bracketkindty = (bki_none,bki_round,bki_square,bki_curly); + +const + openbrackets: array[bracketkindty] of msechar = (#0,'(','[','{'); + closebrackets: array[bracketkindty] of msechar = (#0,')',']','}'); + defaultpairmaxrowcount = 100; + +type + syntaxeditoptionty = (seo_autoindent,seo_markbrackets,seo_markpairwords, + seo_caseinsensitive,seo_defaultsyntax); + syntaxeditoptionsty = set of syntaxeditoptionty; + + tsyntaxedit = class(tundotextedit) + private + fsyntaxpainter: tsyntaxpainter; + fsyntaxpainterhandle: integer; +// fautoindent: boolean; + flinkpos: gridcoordty; + flinklength: integer; +// fdefaultsyntax: boolean; + fsyntaxchanging: integer; + fbracketsetting: integer; + fbracketchecking: integer; + fpairmarkbkgcolor: colorty; + fpairmaxrowcount: int32; + fpairwords: pairwordsty; +// fpairwordslower: msestringararty; + procedure setsyntaxpainter(const Value: tsyntaxpainter); + procedure unregistersyntaxpainter; + procedure syntaxchanged(const sender: tobject; const index: integer); +// procedure setdefaultsyntax(const avalue: boolean); + procedure checkdefaultsyntax; + procedure readautoindent(reader: treader); + procedure readdefaultsyntax(reader: treader); + function getautoindent: boolean; + procedure setautoindent(const avalue: boolean); + function getmarkbrackets: boolean; + procedure setmarkbrackets(const avalue: boolean); + procedure setoptions(const avalue: syntaxeditoptionsty); + function getmarkpairwords: boolean; + procedure setmarkpairwords(const avalue: boolean); + function getcaseinsensitive: boolean; + procedure setcaseinsensitive(const avalue: boolean); + procedure setpairwords(const avalue: pairwordsty); + protected + foptions: syntaxeditoptionsty; + fmark1,fmark2: markitemty; + procedure initsyntaxparams(); + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + procedure gridvaluechanged(const index: integer); override; + procedure insertlinebreak; override; + procedure dokeydown(var info: keyeventinfoty); override; + procedure loaded; override; + function createdatalist(const sender: twidgetcol): tdatalist; override; + procedure defineproperties(filer: tfiler); override; + procedure clearpairmarks(); + procedure checkpairmarks(); + procedure editnotification(var info: editnotificationinfoty); override; + procedure doasyncevent(var atag: integer); override; + procedure doafterpaint(const canvas: tcanvas); override; + function needsfocuspaint: boolean; override; +// procedure updatepairwords(); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure setsyntaxdef(const sourcefilename: filenamety); overload; + //'' for none + procedure setsyntaxdef(const handle: integer); overload; + procedure refreshsyntax(const start,count: integer); + + function charatpos(const apos: gridcoordty): msechar; //0 if none + function charbeforepos(const apos: gridcoordty): msechar; //0 if none + function wordatpos(const apos: gridcoordty; out word: msestring; + const delimchars: msestring; //'' -> default + const nodelimstrings: array of msestring; + const leftofcursor: boolean = false): gridcoordty; overload; + function wordatpos(const apos: gridcoordty; out start: gridcoordty; + const delimchars: msestring; + const nodelimstrings: array of msestring; + const leftofcursor: boolean = false): msestring; overload; + function wordatpos(const apos: gridcoordty; + const delimchars: msestring; + const nodelimstrings: array of msestring; + const leftofcursor: boolean = false): msestring; overload; + procedure indent(const acount: integer; const atabs: boolean); + procedure unindent(const acount: integer); + procedure removelink; + procedure showlink(const apos: gridcoordty; + const delimchars: msestring {= defaultmsedelimchars}); + procedure selectword(const apos: gridcoordty; const delimchars: msestring); + function matchbracket(const apos: gridcoordty; const akind: bracketkindty; + const open: boolean; maxrows: int32 = -1): gridcoordty; + //-1 -> use maxpairrows + function matchpairword(var apos: gridcoordty; //adjusted to word a start + out lena,lenb: int32; maxrows: int32 = -1): gridcoordty; + //-1 -> use maxpairrows + property pairwords: pairwordsty read fpairwords write setpairwords; + //last item of a pairword item is endtoken + //upprcase values must be uppercase for caseinsensitive + property syntaxpainterhandle: integer read fsyntaxpainterhandle; + function syntaxchanging: boolean; + property autoindent: boolean read getautoindent write setautoindent; + property markbrackets: boolean read getmarkbrackets write setmarkbrackets; + property markpairwords: boolean read getmarkpairwords write setmarkpairwords; + property caseinsensitive: boolean read getcaseinsensitive + write setcaseinsensitive; + published + property syntaxpainter: tsyntaxpainter read fsyntaxpainter + write setsyntaxpainter; +// property defaultsyntax: boolean read fdefaultsyntax +// write setdefaultsyntax default false; + property options: syntaxeditoptionsty read foptions write setoptions + default []; + property pairmarkbkgcolor: colorty read fpairmarkbkgcolor + write fpairmarkbkgcolor default cl_none; + //cl_none -> force none, + //cl_default -> use syntaxpainter value if defined else cl_none + //otherwise use syntaxpainter value if defined + property pairmaxrowcount: int32 read fpairmaxrowcount + write fpairmaxrowcount default defaultpairmaxrowcount; + end; + +function checkbracketkind(const achar: msechar; + out open: boolean): bracketkindty; + +implementation +uses + msekeyboard,msepointer; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + checkbrackettag = 84621847; + +type + tundoinplaceedit1 = class(tundoinplaceedit); + ttextundolist1 = class(ttextundolist); + +function checkbracketkind(const achar: msechar; out open: boolean): bracketkindty; +var + br1: bracketkindty; +begin + for br1:= bki_round to high(bracketkindty) do begin + if openbrackets[br1] = achar then begin + result:= br1; + open:= true; + exit; + end; + end; + result:= bki_none; + open:= false; + for br1:= bki_round to high(bracketkindty) do begin + if closebrackets[br1] = achar then begin + result:= br1; + break; + end; + end; +end; + +{ tsyntaxedit } + +const + invalidmark: markitemty = (bold: false; + pos: (col: invalidaxis; row: invalidaxis); len: 0); + +constructor tsyntaxedit.create(aowner: tcomponent); +begin + fsyntaxpainterhandle:= -1; + flinkpos:= invalidcell; + fmark1:= invalidmark; + fmark2:= invalidmark; + fpairmarkbkgcolor:= cl_none; + fpairmaxrowcount:= defaultpairmaxrowcount; + inherited; +end; + +destructor tsyntaxedit.destroy; +begin + unregistersyntaxpainter; + inherited; +end; + +procedure tsyntaxedit.objectevent(const sender: tobject; + const event: objecteventty); +var + int1,int2: integer; + po1: prichstringty; +begin + inherited; + if sender = fsyntaxpainter then begin + if event in [oe_destroyed,oe_disconnect] then begin + fsyntaxpainterhandle:= -1; + if flines <> nil then begin + with flines do begin + int2:= size; + po1:= datapo; + for int1:= count-1 downto 0 do begin + po1^.format:= nil; + inc(pchar(po1),int2); + end; + end; + end; + feditor.format:= nil; + if fgridintf <> nil then begin + fgridintf.changed; + end; +// fsyntaxpainter:= nil; + end; + end; +end; + +procedure tsyntaxedit.unregistersyntaxpainter; +begin + if (fsyntaxpainter <> nil) and (fsyntaxpainterhandle >= 0) then begin + fsyntaxpainter.unregisterclient(fsyntaxpainterhandle); + end; + fsyntaxpainterhandle:= -1; +end; + +procedure tsyntaxedit.checkdefaultsyntax; +begin + if (seo_defaultsyntax in foptions) and not (csloading in componentstate) and + (fsyntaxpainter <> nil) and (flines <> nil) and + (fsyntaxpainterhandle < 0) then begin + setsyntaxdef(fsyntaxpainter.defaultsyntax); + end; +end; + +procedure tsyntaxedit.setsyntaxpainter(const Value: tsyntaxpainter); +begin + if value <> fsyntaxpainter then begin + if fsyntaxpainter <> nil then begin + unregistersyntaxpainter; + end; + setlinkedvar(value,tmsecomponent(fsyntaxpainter)); + checkdefaultsyntax; + end; +end; +{ +procedure tsyntaxedit.setdefaultsyntax(const avalue: boolean); +begin + fdefaultsyntax:= avalue; + checkdefaultsyntax; +end; +} +procedure tsyntaxedit.setsyntaxdef(const sourcefilename: filenamety); +begin + if fsyntaxpainter <> nil then begin + if sourcefilename = '' then begin + unregistersyntaxpainter; + end + else begin + setsyntaxdef(fsyntaxpainter.linkdeffile(sourcefilename)); + end; + end; +end; + +procedure tsyntaxedit.initsyntaxparams(); +begin + caseinsensitive:= fsyntaxpainter.caseinsensitive[fsyntaxpainterhandle]; + pairwords:= fsyntaxpainter.pairwords[fsyntaxpainterhandle]; +end; + +procedure tsyntaxedit.setsyntaxdef(const handle: integer); +begin + if fsyntaxpainter <> nil then begin + unregistersyntaxpainter; + if handle >= 0 then begin + fsyntaxpainterhandle:= fsyntaxpainter.registerclient(self,flines, + {$ifdef FPC}@{$endif}syntaxchanged,handle); + initsyntaxparams(); + refreshsyntax(0,bigint); + end; + end; +end; + +procedure tsyntaxedit.syntaxchanged(const sender: tobject; + const index: integer); +begin + if (index < 0) and (fsyntaxpainterhandle >= 0) and + (sender <> nil) and (sender = fsyntaxpainter) then begin + initsyntaxparams(); + end; + if fgridintf <> nil then begin + inc(fsyntaxchanging); + try + fgridintf.getcol.cellchanged(index); + if index = fgridintf.getrow then begin + feditor.richtext:= flines.richitems[index]; + end; + finally + dec(fsyntaxchanging); + end; + end; +end; + +procedure tsyntaxedit.refreshsyntax(const start, count: integer); +begin + if fsyntaxpainterhandle >= 0 then begin + fsyntaxpainter.paintsyntax(fsyntaxpainterhandle,start,bigint,true); +// fsyntaxpainter.paintsyntax(fsyntaxpainterhandle,start,bigint,false); + end; +end; + +procedure tsyntaxedit.gridvaluechanged(const index: integer); +begin + inherited; + if index >= 0 then begin + refreshsyntax(index,1); + end + else begin + refreshsyntax(0,bigint); + end; +end; + +function tsyntaxedit.charatpos(const apos: gridcoordty): msechar; +var + stringpo: pmsestring; +begin + result:= #0; + if (apos.col >= 0) and (apos.row >= 0) and (apos.row < flines.count) then begin + stringpo:= pmsestring(flines.getitempo(apos.row)); + if apos.col < length(stringpo^) then begin + result:= stringpo^[apos.col+1]; + end; + end; +end; + +function tsyntaxedit.charbeforepos(const apos: gridcoordty): msechar; +var + stringpo: pmsestring; +begin + if apos.col = 0 then begin + result:= charbeforepos(makegridcoord(bigint,apos.row-1)); + end + else begin + result:= #0; + if (apos.row >= 0) and (apos.row < flines.count) and (apos.col >= 0) then begin + stringpo:= pmsestring(flines.getitempo(apos.row)); + if stringpo^ <> '' then begin + if apos.col >= length(stringpo^) then begin + result:= stringpo^[length(stringpo^)]; + end + else begin + result:= stringpo^[apos.col]; + end; + end; + end; + end; +end; + +function tsyntaxedit.wordatpos(const apos: gridcoordty; out word: msestring; + const delimchars: msestring; + const nodelimstrings: array of msestring; + const leftofcursor: boolean = false): gridcoordty; + //returns startpos +var + po1,po2: pmsechar; + stringpo: pmsestring; + gc1: gridcoordty; +begin + po2:= nil; + word:= ''; + if (apos.row < 0) or (apos.row >= flines.count) then begin + result:= invalidcell; + end + else begin + result.row:= apos.row; + stringpo:= pmsestring(flines.getitempo(apos.row)); + if stringpo^ <> '' then begin + if delimchars <> '' then begin + wordatindex(stringpo^,apos.col,po1,po2,delimchars,nodelimstrings); + end + else begin + wordatindex(stringpo^,apos.col,po1,po2,defaultmsedelimchars,nodelimstrings); + end; + if po1 = po2 then begin + po1:= nil; + end; + end + else begin + po1:= nil; + end; + if po1 = nil then begin + result.col:= -1; + end + else begin + result.col:= po1 - pmsechar(stringpo^); + word:= copy(msestring(po1),1,po2-po1); + end; + end; + if (word = '') and leftofcursor and (apos.col > 0) then begin + gc1:= apos; + dec(gc1.col); + result:= wordatpos(gc1,word,delimchars,nodelimstrings); + end; +end; + +function tsyntaxedit.wordatpos(const apos: gridcoordty; out start: gridcoordty; + const delimchars: msestring; + const nodelimstrings: array of msestring; + const leftofcursor: boolean = false): msestring; +begin + start:= wordatpos(apos,result,delimchars,nodelimstrings,leftofcursor); +end; + +function tsyntaxedit.wordatpos(const apos: gridcoordty; + const delimchars: msestring; + const nodelimstrings: array of msestring; + const leftofcursor: boolean = false): msestring; +begin + wordatpos(apos,result,delimchars,nodelimstrings,leftofcursor); +end; + + +procedure tsyntaxedit.indent(const acount: integer; const atabs: boolean); +var + int1,int2: integer; + str1: msestring; + pos1,pos2: gridcoordty; + po1: prichstringaty; + selstart,selend: gridcoordty; + ch1: msechar; +begin + selstart:= selectstart; + selend:= selectend; + getselectedrows(int1,int2); + ch1:= ' '; + if atabs then begin + ch1:= c_tab; + end; + str1:= charstring(ch1,acount); + pos1:= makegridcoord(0,int1); + pos2:= makegridcoord(acount,int1); + po1:= datalist.datapo; + beginupdate; + feditor.begingroup; + try + clearselection; + while (pos1.row <= int2) do begin + richinsert(str1,po1^[pos1.row],1); + tundoinplaceedit1(feditor).fundolist.setpos(pos1,false); + tundoinplaceedit1(feditor).fundolist.inserttext(pos1,pos2,str1,false,false); + inc(pos1.row); + pos2.row:= pos1.row; + end; + if selstart.row = selend.row then begin + editor.richtext:= po1^[int2]; + selstart.col:= selstart.col + acount; + selend.col:= selend.col + acount; + end; + setselection(selstart,selend,true); + finally + feditor.endgroup; + endupdate; + end; +end; + +procedure tsyntaxedit.unindent(const acount: integer); +var + int1,int2,int3,int4: integer; + pos1,pos2: gridcoordty; + selstart,selend: gridcoordty; + str1: msestring; + po1: prichstringaty; + +begin + selstart:= selectstart; + selend:= selectend; + getselectedrows(int1,int2); + pos1:= makegridcoord(0,int1); + pos2.row:= int1; + po1:= datalist.datapo; + beginupdate; + int4:= 0; + feditor.begingroup; + try + clearselection; + for int1:= int1 to int2 do begin + with po1^[pos1.row] do begin + if length(text) < acount then begin + int4:= length(text); + end + else begin + int4:= acount; + end; + for int3:= 1 to int4 do begin + if (text[int3] <> ' ') and (text[int3] <> c_tab) then begin + int4:= int3 - 2; + break; + end; + end; + end; + if int4 >= 0 then begin + pos2.col:= int4; + str1:= copy(po1^[pos1.row].text,1,int4); + richdelete(po1^[pos1.row],1,int4); + tundoinplaceedit1(feditor).fundolist.setpos(pos2,false); + tundoinplaceedit1(feditor).fundolist.deletetext(pos2,pos1,str1,false,true); + end; + inc(pos1.row); + inc(pos2.row); + end; + if selstart.row = selend.row then begin + if int4 < 0 then begin + int4:= 0; + end; + selstart.col:= selstart.col - int4; + selend.col:= selend.col - int4; + end; + setselection(selstart,selend,true); + finally + feditor.endgroup; + endupdate; + end; +end; + +procedure tsyntaxedit.removelink; +begin + if (flinkpos.row >= 0) then begin + application.cursorshape:= cr_default; + if (flinkpos.row < datalist.count) then begin + if updatefontstyle1(datalist.getformatpo(flinkpos.row)^,flinkpos.col, + flinklength,fs_underline,false) then begin + with fgridintf.getcol do begin + cellchanged(flinkpos.row); + if grid.row = flinkpos.row then begin + self.gridtovalue(flinkpos.row); + end; + end; + end; + end; + flinkpos.row:= invalidaxis; + end; +end; + +procedure tsyntaxedit.showlink(const apos: gridcoordty; + const delimchars: msestring {= defaultmsedelimchars}); +var + str1: msestring; + pos1: gridcoordty; + length1: integer; +begin + pos1:= wordatpos(apos,str1,delimchars,[]); + length1:= length(str1); + if (pos1.col <> flinkpos.col) or (pos1.row <> flinkpos.row) or + (length1 <> flinklength) then begin + removelink; + flinkpos:= pos1; + flinklength:= length1; + if flinklength > 0 then begin + application.cursorshape:= cr_pointinghand; + if updatefontstyle1(datalist.getformatpo(flinkpos.row)^,flinkpos.col, + flinklength,fs_underline,true) then begin + with fgridintf.getcol do begin + cellchanged(flinkpos.row); + if grid.row = flinkpos.row then begin + self.gridtovalue(flinkpos.row); + end; + end; + end; + end; + end; +end; + +procedure tsyntaxedit.selectword(const apos: gridcoordty; + const delimchars: msestring); +var + str1: msestring; + pos1: gridcoordty; +begin + pos1:= wordatpos(apos,str1,delimchars,[]); + if str1 = '' then begin + pos1:= wordatpos(apos,str1,delimchars,[],true); + end; + if str1 <> '' then begin + setselection(pos1,makegridcoord(pos1.col+length(str1),pos1.row),true); + end; +end; + +function tsyntaxedit.matchbracket(const apos: gridcoordty; + const akind: bracketkindty; + const open: boolean; maxrows: integer = -1): gridcoordty; + +var + level: integer; + strpo: pmsestring; + x,y: integer; + po1: pmsecharaty; + int1: integer; + openchar,closechar,mch1: msechar; +begin + result:= invalidcell; + level:= 0; + x:= apos.col; + y:= apos.row; + openchar:= openbrackets[akind]; + closechar:= closebrackets[akind]; + if maxrows < 0 then begin + maxrows:= fpairmaxrowcount; + end; + if open then begin + while (maxrows > 0) and (y < flines.count) do begin + strpo:= pmsestring(flines.getitempo(y)); + po1:= pmsecharaty(strpo^); + for int1:= x to length(strpo^)-1 do begin + mch1:= po1^[int1]; + if mch1 = openchar then begin + inc(level); + end; + if mch1 = closechar then begin + dec(level); + if level <= 0 then begin + result.row:= y; + result.col:= int1; + exit; + end; + end; + end; + x:= 0; + dec(maxrows); + inc(y); + end; + end + else begin + strpo:= pmsestring(flines.getitempo(y)); + while (maxrows > 0) do begin + po1:= pmsecharaty(strpo^); + for int1:= x downto 0 do begin + mch1:= po1^[int1]; + if mch1 = closechar then begin + inc(level); + end; + if mch1 = openchar then begin + dec(level); + if level <= 0 then begin + result.row:= y; + result.col:= int1; + exit; + end; + end; + end; + dec(maxrows); + dec(y); + if y < 0 then begin + break; + end; + strpo:= pmsestring(flines.getitempo(y)); + x:= length(strpo^)-1; + end; + end; +end; + +function tsyntaxedit.matchpairword(var apos: gridcoordty; + out lena,lenb: int32; + maxrows: integer = -1): gridcoordty; +var + mstr1,{mstr1l,}mstr2{,mstr2l}: msestring; + forward1: boolean; + strpo,strpe: prichstringty; + pa,pae,{pab,}pal,{palb,}{pb,pbe,pbb,pbl,pblb,}po1,po2,pe: pmsechar; + level1: int32; + i1: int32; + par1,par1l,pare: pmsestringarty; +label + lab1; +begin + if maxrows < 0 then begin + maxrows:= fpairmaxrowcount; + end; + if fpairwords.upper <> nil then begin + mstr1:= ''; + if (apos.row >= 0) and (apos.row < flines.count) then begin + mstr2:= flines.items[apos.row]; + if (mstr2 <> '') and (apos.col >= 0) and + (apos.col <= length(mstr2)) then begin + pe:= pmsechar(pointer(mstr2))+apos.col; + po1:= pe-1; + while isnamechar(pe^) do begin + inc(pe); + end; + while (po1 >= pointer(mstr2)) and isnamechar(po1^) do begin + dec(po1); + end; + inc(po1); + mstr1:= stringsegment(po1,pe); + apos.col:= po1-pmsechar(pointer(mstr2)); + end; + end; + if mstr1 <> '' then begin + if caseinsensitive then begin + mstr1:= mseuppercase(mstr1); + end; + mstr2:= ''; + par1:= pointer(fpairwords.upper); + pare:= par1+high(fpairwords.upper); + while par1 <= pare do begin + for i1:= 0 to high(par1^) do begin + if par1^[i1] = mstr1 then begin + forward1:= i1 < high(par1^); + goto lab1; + end; + end; + inc(par1); + end; +lab1: + if par1 <= pare then begin //found + par1l:= pointer(par1)-pointer(fpairwords.upper)+ + pointer(fpairwords.lower); //lowercase + lena:= length(mstr1); + strpo:= flines.getitempo(apos.row); + if forward1 then begin + level1:= 1; + po1:= @pmsechar(pointer(strpo^.text))[apos.col+lena]; + i1:= flines.count-apos.row; + if i1 > maxrows then begin + i1:= maxrows; + end; + strpe:= strpo + i1; + while true do begin + repeat + while not isnamechar(po1^) and (po1^ <> #0) do begin + inc(po1); + end; + if po1^ <> #0 then begin + for i1:= 0 to high(par1^) do begin + pa:= pmsechar(par1^[i1]); + pal:= pmsechar(par1l^[i1]); + if (po1^ = pa^) or (po1^ = pal^) then begin + po2:= po1; + repeat + inc(pa); + inc(pal); + inc(po2); + if (pa^ = #0) and not isnamechar(po2^) then begin //match + if i1 = high(par1^) then begin //end + dec(level1); + if level1 = 0 then begin //found + lenb:= length(par1^[i1]); + result.col:= po1-pmsechar(pointer(strpo^.text)); + result.row:= strpo-prichstringty(flines.datapo); + exit; + end; + break; + end + else begin + inc(level1); + po1:= po2; + break; + end; + end; + until (po2^ <> pa^) and (po2^ <> pal^); + end; + end; + while isnamechar(po1^) do begin + inc(po1); + end; + end; + until po1^ = #0; + inc(strpo); + if strpo >= strpe then begin + break; + end; + po1:= pmsechar(strpo^.text); + end; + end + else begin //backward + + level1:= 1; + pe:= pointer(strpo^.text); + po1:= pe + apos.col - 1; + i1:= apos.row; + if i1 > maxrows then begin + i1:= maxrows; + end; + strpe:= strpo - i1; + while true do begin + if pe <> nil then begin + repeat + while not isnamechar(po1^) and (po1 >= pe) do begin + dec(po1); + end; + if po1 >= pe then begin + for i1:= 0 to high(par1^) do begin + pae:= pmsechar(par1^[i1]); + pa:= pmsechar(pae+length(par1^[i1])-1); + pal:= pmsechar(par1l^[i1])+length(par1l^[i1])-1; + if (po1^ = pa^) or (po1^ = pal^) then begin + po2:= po1; + repeat + dec(pa); + dec(pal); + dec(po2); + if (pa < pae) and + ((po2 < pe) or not isnamechar(po2^)) then begin //match + if i1 = high(par1^) then begin //end + inc(level1); + po1:= po2; + break; + end + else begin + dec(level1); + if level1 = 0 then begin //found + lenb:= length(par1^[i1]); + result.col:= po2-pmsechar(pointer(strpo^.text))+1; + result.row:= strpo-prichstringty(flines.datapo); + exit; + end; + break; + end; + end; + until (po2^ <> pa^) and (po2^ <> pal^) or (po2 < pe); + end; + end; + while isnamechar(po1^) and (po1 > pe) do begin + dec(po1); + end; + dec(po1); + end; + until po1 < pe; + end; + dec(strpo); + if strpo < strpe then begin + break; + end; + pe:= pointer(strpo^.text); + po1:= pe + length(strpo^.text) - 1; + end; + end; + end; + end; + end; + result:= invalidcell; + lena:= 0; + lenb:= 0; +end; + +const + noboldchars: markinfoty = (backgroundcolor: cl_none; items: nil); + +procedure tsyntaxedit.clearpairmarks(); +var + style1: fontstylety; +begin + if (fmark1.pos.col >= 0) and (fbracketsetting = 0) then begin + inc(fbracketsetting); + try + style1:= fs_force; //do not change + if fmark1.bold then begin + style1:= fs_bold; + end; + setfontstyle(fmark1.pos,mgc(fmark1.pos.col+fmark1.len,fmark1.pos.row), + style1,false,cl_default,cl_transparent); + setfontstyle(fmark2.pos,mgc(fmark2.pos.col+fmark2.len,fmark2.pos.row), + style1,false,cl_default,cl_transparent); + refreshsyntax(fmark1.pos.row,1); + refreshsyntax(fmark2.pos.row,1); + fmark1:= invalidmark; + fmark2:= invalidmark; + if syntaxpainterhandle >= 0 then begin + syntaxpainter.boldchars[syntaxpainterhandle]:= noboldchars; + end; + finally + dec(fbracketsetting); + end; + end; +end; + +procedure tsyntaxedit.checkpairmarks(); +var + mch1: msechar; + br1,br2: bracketkindty; + open,open2: boolean; + pt1,pt2: gridcoordty; + ar1: markitemarty; + boldinfo1: markinfoty; + iswordmark: boolean; +begin + clearpairmarks(); + pt2:= invalidcell; + if seo_markbrackets in foptions then begin + fmark1.bold:= true; + fmark2.bold:= true; + fmark1.len:= 1; + fmark2.len:= 1; + pt1:= editpos; + mch1:= charatpos(pt1); + br1:= checkbracketkind(mch1,open); + if (br1 <> bki_none) then begin + if (pt1.col > 0) then begin + dec(pt1.col); + br2:= checkbracketkind(charatpos(pt1),open2); + if (br2 = bki_none) {or (open <> open2)} then begin + inc(pt1.col); + end + else begin + br1:= br2; + open:= open2; + end; + end; + pt2:= matchbracket(pt1,br1,open); + end + else begin + dec(pt1.col); + if pt1.col >= 0 then begin + mch1:= charatpos(pt1); + br1:= checkbracketkind(mch1,open); + if br1 <> bki_none then begin + pt2:= matchbracket(pt1,br1,open); + end; + end; + end; + end; + iswordmark:= false; + if (seo_markpairwords in foptions) and (pt2.col < 0) then begin + iswordmark:= true; + pt1:= editpos; + pt2:= matchpairword(pt1,fmark1.len,fmark2.len); + end; + if pt2.col >= 0 then begin + fmark1.pos:= pt1; + fmark2.pos:= pt2; + boldinfo1.backgroundcolor:= fpairmarkbkgcolor; + if iswordmark then begin + fmark1.bold:= boldinfo1.backgroundcolor = cl_none; + fmark2.bold:= fmark1.bold; + end; + if syntaxpainterhandle >= 0 then begin + setlength(ar1,2); + ar1[0]:= fmark1; + ar1[1]:= fmark2; + boldinfo1.backgroundcolor:= + syntaxpainter.colors[syntaxpainterhandle].pairmarkbackground; + if (boldinfo1.backgroundcolor = cl_default) or + (fpairmarkbkgcolor = cl_none) then begin + if fpairmarkbkgcolor = cl_default then begin + boldinfo1.backgroundcolor:= cl_none; + end + else begin + boldinfo1.backgroundcolor:= fpairmarkbkgcolor; + end; + end; + if iswordmark then begin + fmark1.bold:= boldinfo1.backgroundcolor = cl_none; + fmark2.bold:= fmark1.bold; + end; + boldinfo1.items:= ar1; + syntaxpainter.boldchars[syntaxpainterhandle]:= boldinfo1; + refreshsyntax(fmark1.pos.row,1); + refreshsyntax(fmark2.pos.row,1); + end; + inc(fbracketsetting); + try + if boldinfo1.backgroundcolor = cl_none then begin + boldinfo1.backgroundcolor:= cl_transparent; + end; + if fmark1.bold then begin + setfontstyle(pt1,makegridcoord(pt1.col+fmark1.len,pt1.row), + fs_bold,true,cl_default, boldinfo1.backgroundcolor); + setfontstyle(pt2,makegridcoord(pt2.col+fmark1.len,pt2.row), + fs_bold,true,cl_default,boldinfo1.backgroundcolor); + end + else begin + setfontstyle(pt1,makegridcoord(pt1.col+fmark1.len,pt1.row),fs_force,false, + cl_default,boldinfo1.backgroundcolor); + setfontstyle(pt2,makegridcoord(pt2.col+fmark2.len,pt2.row),fs_force,false, + cl_default,boldinfo1.backgroundcolor); + end; + finally + dec(fbracketsetting); + end; + end; +end; + +procedure tsyntaxedit.insertlinebreak; +var + mstr1: msestring; + po1: gridcoordty; + po2: pmsechar; +begin + application.caret.remove; + beginupdate; + feditor.begingroup; + try + inherited; + if seo_autoindent in foptions then begin + po1:= editpos; + if po1.row > 0 then begin + mstr1:= gridvalue[po1.row-1]; + po2:= pmsechar(mstr1); + while (po2^ = ' ') or (po2^ = c_tab) do begin + inc(po2); + end; + setlength(mstr1,po2-pmsechar(mstr1)); +// mstr1:= charstring(msechar(' '),countleadingchars(mstr1,msechar(' '))); + if mstr1 <> '' then begin + po1.col:= 0; + inserttext(po1,mstr1); + end; + end; + end; + finally + application.caret.restore; + feditor.endgroup; + endupdate; + end; +end; + +const + stopchars = [' ',c_tab,'=',':',';',',','.','''','-','+','/','*','^', + '[',']','(',')','{','}']; + +procedure tsyntaxedit.dokeydown(var info: keyeventinfoty); + + function isstopchar(const avalue: msechar): boolean; + begin + result:= (word(avalue) < $100) and (char(byte(avalue)) in stopchars) + end; + +var + int1,int2: integer; + co1: gridcoordty; + shiftstate1: shiftstatesty; +begin + with info do begin + shiftstate1:= shiftstate * shiftstatesmask; + if (shiftstate1 = [ss_ctrl]) or (shiftstate1 = [ss_ctrl,ss_shift]) then begin + case key of + key_left: begin + repeat //skip stopchars + int2:= 0; + for int1:= feditor.curindex downto 1 do begin + if not isstopchar(feditor.text[int1]) then begin + int2:= int1; + break; + end; + end; + if int2 = 0 then begin + if editpos.row > 0 then begin + co1.row:= editpos.row - 1; + co1.col:= bigint; + seteditpos(co1,ss_shift in shiftstate1); + end + else begin + break; + end; + end; + until (int2 > 0); + co1.row:= editpos.row; + co1.col:= int2; + seteditpos(co1,ss_shift in shiftstate1); + int2:= 0; //skip normal chars + for int1:= feditor.curindex downto 1 do begin + if isstopchar(feditor.text[int1]) then begin + int2:= int1; + break; + end; + end; + co1.row:= editpos.row; + co1.col:= int2; + seteditpos(co1,ss_shift in shiftstate1); + include(eventstate,es_processed); + end; + key_right: begin + repeat //skip stopchars + int2:= bigint; + for int1:= feditor.curindex + 1 to length(feditor.text) do begin + if not isstopchar(feditor.text[int1]) then begin + int2:= int1; + break; + end; + end; + if int2 = bigint then begin + if editpos.row < linecount - 1 then begin + co1.row:= editpos.row + 1; + co1.col:= 0; + seteditpos(co1,ss_shift in shiftstate1); + end + else begin + break; + end; + end; + until (int2 < bigint); + co1.row:= editpos.row; + co1.col:= int2; + seteditpos(co1,ss_shift in shiftstate1); + int2:= bigint; //skip normal chars + for int1:= feditor.curindex + 1 to length(feditor.text) do begin + if isstopchar(feditor.text[int1]) then begin + int2:= int1; + break; + end; + end; + co1.row:= editpos.row; + co1.col:= int2-1; + seteditpos(co1,ss_shift in shiftstate1); + include(eventstate,es_processed); + end; +(* + key_left: begin + repeat + int2:= 0; + for int1:= feditor.curindex downto 1 do begin + if isstopchar(feditor.text[int1]) then begin + int2:= int1; + break; + end; + end; + if int2 = 0 then begin + if editpos.row > 0 then begin + co1.row:= editpos.row - 1; + co1.col:= bigint; + seteditpos(co1,ss_shift in shiftstate1); + if (length(feditor.text) > 0) and + not isstopchar(feditor.text[length(feditor.text)]) then begin + int2:= length(feditor.text); + end; + end; + end; + until (int2 > 0) or (editpos.row <= 0); + co1.row:= editpos.row; + co1.col:= int2; + seteditpos(co1,ss_shift in shiftstate1); + repeat + int2:= 0; + for int1:= feditor.curindex downto 1 do begin + if not isstopchar(feditor.text[int1]) then begin + int2:= int1; + break; + end; + end; + if int2 = 0 then begin + if editpos.row > 0 then begin + co1.row:= editpos.row - 1; + co1.col:= bigint; + seteditpos(co1,ss_shift in shiftstate1); + end; + end; + until (int2 > 0) or (editpos.row <= 0); + if int2 > 0 then begin + co1.row:= editpos.row; + co1.col:= int2; + seteditpos(co1,ss_shift in shiftstate1); + end; + include(eventstate,es_processed); + end; + key_right: begin + repeat + int2:= bigint; + for int1:= feditor.curindex + 1 to length(feditor.text) do begin + if isstopchar(feditor.text[int1]) then begin + int2:= int1; + break; + end; + end; + if int2 = bigint then begin + if editpos.row < linecount - 1 then begin + co1.row:= editpos.row + 1; + co1.col:= 0; + seteditpos(co1,ss_shift in shiftstate1); + if (length(feditor.text) > 0) and + not isstopchar(feditor.text[1]) then begin + int2:= 0; + end; + end; + end; + until (int2 < bigint) or (editpos.row >= linecount - 1); + co1.row:= editpos.row; + co1.col:= int2; + seteditpos(co1,ss_shift in shiftstate1); + repeat + int2:= bigint; + for int1:= feditor.curindex + 1 to length(feditor.text) do begin + if not isstopchar(feditor.text[int1]) then begin + int2:= int1; + break; + end; + end; + if int2 = bigint then begin + if editpos.row < linecount - 1 then begin + co1.row:= editpos.row + 1; + co1.col:= 0; + seteditpos(co1,ss_shift in shiftstate1); + end; + end; + until (int2 < bigint) or (editpos.row >= linecount - 1); + if int2 < bigint then begin + co1.row:= editpos.row; + co1.col:= int2-1; + seteditpos(co1,ss_shift in shiftstate1); + end; + include(eventstate,es_processed); + end; +*) + end; + end; + if not (es_processed in eventstate) then begin + inherited; + end; + end; +end; + +procedure tsyntaxedit.loaded; +begin + inherited; + checkdefaultsyntax; +end; + +function tsyntaxedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= inherited createdatalist(sender); + checkdefaultsyntax; +end; + +function tsyntaxedit.syntaxchanging: boolean; +begin + result:= fsyntaxchanging <> 0; +end; + +procedure tsyntaxedit.readautoindent(reader: treader); +begin + if reader.readboolean then begin + include(foptions,seo_autoindent); + end; +end; + +procedure tsyntaxedit.readdefaultsyntax(reader: treader); +begin + if reader.readboolean then begin + include(foptions,seo_defaultsyntax); + end; +end; + +procedure tsyntaxedit.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('autoindent',@readautoindent,nil,false); + filer.defineproperty('defaultsyntax',@readdefaultsyntax,nil,false); +end; + +procedure tsyntaxedit.editnotification(var info: editnotificationinfoty); +begin + inherited; + if (info.action = ea_beforechange) and not syntaxchanging then begin + clearpairmarks(); + end + else begin + if (options * [seo_markbrackets,seo_markpairwords] <> []) and + (info.action in [ea_indexmoved,ea_delchar,ea_deleteselection, + ea_pasteselection,ea_textentered]) then begin + if (fbracketchecking = 0) then begin + inc(fbracketchecking); + asyncevent(checkbrackettag); + end; + end; + end; +end; + +procedure tsyntaxedit.doasyncevent(var atag: integer); +begin + inherited; + if atag = checkbrackettag then begin + fbracketchecking:= 0; + checkpairmarks(); + end; +end; + +procedure tsyntaxedit.doafterpaint(const canvas: tcanvas); +begin + inherited; + if (fgridintf <> nil) and not (csdesigning in componentstate) then begin + fgridintf.widgetpainted(canvas); + end; +end; + +function tsyntaxedit.needsfocuspaint: boolean; +begin + result:= (fgridintf = nil) and inherited needsfocuspaint; +end; +{ +procedure tsyntaxedit.updatepairwords(); +var + i1,i2: int32; +begin + setlength(fpairwordslower,length(fpairwords)); + if caseinsensitive then begin + for i1:= 0 to high(fpairwords) do begin + setlength(fpairwordslower[i1],length(fpairwords[i1])); + for i2:= 0 to high(fpairwords[i1]) do begin + fpairwordslower[i1,i2]:= mselowercase(fpairwords[i1,i2]); + end; + end; + end + else begin + for i1:= 0 to high(fpairwords) do begin + setlength(fpairwordslower[i1],length(fpairwords[i1])); + for i2:= 0 to high(fpairwords[i1]) do begin + fpairwordslower[i1,i2]:= fpairwords[i1,i2]; + end; + end; + end; +end; +} +function tsyntaxedit.getautoindent: boolean; +begin + result:= seo_autoindent in options; +end; + +procedure tsyntaxedit.setautoindent(const avalue: boolean); +begin + if avalue then begin + options:= options + [seo_autoindent]; + end + else begin + options:= options - [seo_autoindent]; + end; +end; + +function tsyntaxedit.getmarkbrackets: boolean; +begin + result:= seo_markbrackets in options; +end; + +procedure tsyntaxedit.setmarkbrackets(const avalue: boolean); +begin + if avalue then begin + options:= options + [seo_markbrackets]; + end + else begin + options:= options - [seo_markbrackets]; + end; +end; + +function tsyntaxedit.getmarkpairwords: boolean; +begin + result:= seo_markpairwords in options; +end; + +procedure tsyntaxedit.setmarkpairwords(const avalue: boolean); +begin + if avalue then begin + options:= options + [seo_markpairwords]; + end + else begin + options:= options - [seo_markpairwords]; + end; +end; + +function tsyntaxedit.getcaseinsensitive: boolean; +begin + result:= seo_caseinsensitive in options; +end; + +procedure tsyntaxedit.setcaseinsensitive(const avalue: boolean); +begin + if avalue then begin + options:= options + [seo_caseinsensitive]; + end + else begin + options:= options - [seo_caseinsensitive]; + end; +end; + +procedure tsyntaxedit.setpairwords(const avalue: pairwordsty); + procedure error(); + begin + componentexception(self,'Invalid pairwords'); + end; //error +var + i1,i2: int32; +begin + with avalue do begin + if high(upper) <> high(lower) then begin + error(); + end; + for i1:= 0 to high(upper) do begin + for i2:= 0 to high(upper[i1]) do begin + if length(upper[i1,i2]) <> length(lower[i1,i2]) then begin + error(); + end; + end; + end; + end; + fpairwords:= avalue; +// updatepairwords(); +end; + +procedure tsyntaxedit.setoptions(const avalue: syntaxeditoptionsty); +var + delta: syntaxeditoptionsty; +begin + delta:= foptions >< avalue; + if delta <> [] then begin + foptions:= avalue; + if seo_defaultsyntax in delta then begin + checkdefaultsyntax; + end; +// if seo_caseinsensitive in delta then begin +// updatepairwords(); +// end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/msesyntaxpainter.pas b/mseide-msegui/lib/common/designutils/msesyntaxpainter.pas new file mode 100644 index 0000000..94c27a8 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msesyntaxpainter.pas @@ -0,0 +1,1942 @@ +{ MSEgui Copyright (c) 1999-2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msesyntaxpainter; +(* + +sdef file = +{globaldefinition} +{scope} +//last scope is default scope +globaldefinition = CASEINSENSITIVE | keywordchars | addkeywordchars | + keyworddefs | editorcolors | styles | pairwords + +keywordchars = +KEYWORDCHARS newline +{{string} newline} +//default = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxy0123456789_' + +addkeywordchars = +ADDKEYWORDCHARS newline +{{string} newline} + +string = +'{character}' + +character = +ASCII-character + +styles = +STYLE newline +{stylename styledef newline} + +styledef = +[stylestring [fontcolor [colorbackground]]] + +stylestring = +'[b][i][u][s]' +//b = bold i = italic u = underline s = strikeout + +keyworddefs = +KEYWORDDEFS keyworddefsname [stylename] newline +{{keyword} newline} + +keyword = +string + +editorcolors = +COLORS [fontcolor [backgroundcolor [statementcolor [pairmarkbackgroundcolor]]]] +// cl_default for MSEide project options settings + +pairwords = +PAIRWORDS newline +{pairbegin {pairbegin} pairend newline} +// used in MSEide + +pairbegin = string +pairend = string + +scope = +SCOPE scopename [stylename] newline +{localdefinition} + +localdefinition = +keywords | calltokens | jumptokens | endtokens | RETURN newline + +keywords = +KEYWORDS [style] newline //style used as default +{keyworddefsname [style] newline} + +calltokens = +CALLTOKENS newline +{{[.|,]string}[.]} scopename newline} + + //. -> whitespace, example: + //'begin' finds 'abeginz ... + //.'begin' finds newline'beginz', ' beginz' ... + //'begin'. finds 'abegin ', 'abegin'newline ... + //.'begin'. finds newline'begin ',' begin ', ' begin'newline ... + //, -> begin of line + +jumptokens = +JUMPTOKENS newline +[{{[.]string}[.]}] scopename newline} + +// scopename newline -> unconditional jump + +endtokens = +ENDTOKENS newline +{{[.]string}[.]} [stylename] newline} + + //'' -> end of line + +*) + +{$ifdef FPC}{$mode objfpc}{$h+}{$GOTO ON}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,msestrings,mserichstring,msedatalist, + msestream,msehash,msetimer,msestat,msetypes,mseclasses,mseguiglob,mseevent, + msegraphutils; + +const + defaultkeywordchars: set of char = ['A'..'Z','a'..'z','0'..'9','_']; + defaultlinesperslice = 100; + +type + tokencharsty = set of char; + tokenflagty = (tf_firstofline,tf_startwhitespace,tf_endwhitespace); + tokenflagsty = set of tokenflagty; + tokeninfoty = record + name: msestring; + flags: tokenflagsty; + end; + ptokeninfoty = ^tokeninfoty; + tokeninfoarty = array of tokeninfoty; + + + starttokenty = record + token: tokeninfoty; + hastokenchars: boolean; + tokenchars: tokencharsty; + shortcircuit: boolean; + fontinfonr: integer; + scopenr: integer; + call: boolean; + end; + starttokenpoty = ^starttokenty; + starttokenarty = array of starttokenty; + + endtokenty = record + token: tokeninfoty; + hastokenchars: boolean; + tokenchars: tokencharsty; + fontinfonr: integer; + end; + endtokenpoty = ^endtokenty; + endtokenarty = array of endtokenty; + + keywordinfoty = record + nr: integer; + fontinfonr: integer; + end; + keywordinfoarty = array of keywordinfoty; + + scopeinfoty = record + keywords: keywordinfoarty; + starttokens: starttokenarty; + endtokens: endtokenarty; + hasendtokens: boolean; + defaulttarget: int32; + return: boolean; + fontinfonr: integer; + currfontinfonr: integer; + end; + scopeinfopoty = ^scopeinfoty; + scopeinfoarty = array of scopeinfoty; + charsty = set of char; + charspoty = ^charsty; + + tkeywordlist = class(tpointermsestringhashdatalist) + protected + fdefaultstyle: integer; + public + constructor create; + end; + + keywordarty = array of tkeywordlist; + + refreshinfoty = record + astart,count: integer; + handle: integer; +// startscopenr: integer; + end; + prefreshinfoty = ^refreshinfoty; + + trefreshinfolist = class(tdatalist) + private + function Getitems(index: integer): refreshinfoty; + procedure Setitems(index: integer; const Value: refreshinfoty); //fifo + protected + function checkassigncompatibility( + const source: tpersistent): boolean; override; + public + constructor create; override; + procedure push(const value: refreshinfoty); + function pop: boolean; overload; + function pop(out value: refreshinfoty): boolean; overload; + property items[index: integer]: refreshinfoty read Getitems + write Setitems; default; + end; + + scopestackcachety = record + startscope: integer; + stack: integerarty; + end; + + scopestackcachearty = array of scopestackcachety; + + markitemty = record + bold: boolean; + pos: gridcoordty; + len: int32; + end; + markitemarty = array of markitemty; + + markinfoty = record + backgroundcolor: colorty; + items: markitemarty; + end; + +const + emptymarkinfo: markinfoty = (backgroundcolor: cl_none; items: nil); + +type + clientinfoty = record + client: tobject; + syntaxdefhandle: integer; + scopestack: integerarty; + scopestackpo: integer; + scopestackcache: scopestackcachearty; + scopestackcachepo: integer; + list: trichstringdatalist; + onlinechanged: integerchangedeventty; + boldchars: markinfoty; + end; + pclientinfoty = ^clientinfoty; + clientinfoarty = array of clientinfoty; + + syntaxcolorinfoty = record + font: colorty; + background: colorty; + statement: colorty; + pairmarkbackground: colorty; + end; + + pairwordsty = record + upper: msestringararty; + lower: msestringararty; + end; + syntaxdefty = record + defdefsnr: integer; //-1 -> mit readdeffile geladen + charstyles: tcharstyledatalist; + pairwords: pairwordsty; + caseinsensitive: boolean; + scopeinfos: scopeinfoarty; + aktscopeinfo: integer; + keywordchars: charsty; + scopeendchars,scopestartchars: charsty; + keywordar: keywordarty; +// keywordnames: thashedstrings; + keywordnames: tpointeransistringhashdatalist; + colors: syntaxcolorinfoty; + end; + + syntaxdefpoty = ^syntaxdefty; + syntaxdefarty = array of syntaxdefty; + + tsyntaxpainter = class(tmsecomponent) + private + ftimer: tsimpletimer; + frefreshlist: trefreshinfolist; + flinesperslice: integer; + fclients: clientinfoarty; + fsyntaxdefs: syntaxdefarty; + fdefdefs: tdoublemsestringdatalist; + fdefsdir: filenamety; + fdeftext: tmsestringdatalist; + fdefaultsyntax: integer; + procedure dotimer(const sender: tobject); + procedure syntaxchanged; + procedure internalpaintsyntax(handle: integer; start,count: integer; + var startscopenr: integer); + //-1 = letzte in fscopeinfos + procedure clearsyntaxdef(handle: integer); + procedure initsyntaxdef(handle: integer); + procedure setdefdefs(const Value: tdoublemsestringdatalist); + procedure setlinesperslice(const Value: integer); + procedure calcrefreshinfo(var info: refreshinfoty; var startscope: integer); + procedure setdeftext(const avalue: tmsestringdatalist); + procedure deflistchanged(const sender: tobject); + function getboldchars(index: integer): markinfoty; + procedure setboldchars(index: integer; const avalue: markinfoty); + function getcolors(index: integer): syntaxcolorinfoty; + function getpairwords(index: int32): pairwordsty; + function getcaseinsensitive(index: int32): boolean; + protected + + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure clear; + procedure paintsyntax(handle: integer; start,count: halfinteger; + background: boolean = false); + //-1 = letzte in fscopeinfos + function registerclient(sender: tobject; alist: trichstringdatalist; + aonlinechanged: integerchangedeventty = nil; + asyntaxdefhandle: integer = 0): integer; + //-1 = alles veraendert + + procedure unregisterclient(handle: integer); + //eintreage mit alist loeschen + function readdeffile(stream: ttextstream): integer; overload; + function readdeffile(const afilename: filenamety): integer; overload; + function readdeffile(const atext: string): integer; overload; + procedure freedeffile(handle: integer); + function linkdeffile(const sourcefilename: filenamety): integer; + //-1 if syntaxdef not found + property defaultsyntax: integer read fdefaultsyntax; + property boldchars[index: integer]: markinfoty read getboldchars + write setboldchars; + property colors[index: integer]: syntaxcolorinfoty read getcolors; + property caseinsensitive[index: int32]: boolean read getcaseinsensitive; + property pairwords[index: int32]: pairwordsty read getpairwords; + published + property linesperslice: integer read flinesperslice write setlinesperslice + default defaultlinesperslice; + property defdefs: tdoublemsestringdatalist read fdefdefs write setdefdefs; + //a = filemask, b = deffilename, + // multiple masks quoted + // examples : a b + // '*.pp' 'pas.sdef' + // '"*.pp" "*.pas"' 'pas.sdef' + + property defsdir: filenamety read fdefsdir write fdefsdir; + property deftext: tmsestringdatalist read fdeftext write setdeftext; + end; + +implementation +uses + sysutils,msefileutils,msesys,mseformatstr,msegraphics,mseglob,msearrayutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +procedure markstartchars(const str: msestring; var chars: charsty; + const caseinsensitive: boolean); overload; +var + ch1: char; +begin + if length(str) = 0 then begin + include(chars,#0); + end + else begin + if getansichar(str[1],ch1) then begin + if caseinsensitive then begin + include(chars,lowerchars[ch1]); + include(chars,upperchars[ch1]); + end + else begin + include(chars,ch1); + end; + end; + end +end; + +procedure markstartchars(const strar: msestringarty; var chars: charsty; + const caseinsensitive: boolean); overload; +var + int1: integer; +begin + for int1:= 0 to high(strar) do begin + markstartchars(strar[int1],chars,caseinsensitive); + end; +end; + +procedure markstartchars(const starttokens: starttokenarty; + var chars: charsty; const caseinsensitive: boolean); overload; +var + int1: integer; + ch1: char; +begin + for int1:= 0 to high(starttokens) do begin + with starttokens[int1] do begin + if hastokenchars then begin + chars:= chars + tokenchars; + end + else begin + if length(token.name) = 0 then begin + include(chars,#0); + end + else begin + if getansichar(starttokens[int1].token.name[1],ch1) then begin + if caseinsensitive then begin + include(chars,lowerchars[ch1]); + include(chars,upperchars[ch1]); + end + else begin + include(chars,ch1); + end; + end; + end; + end; + end; + end; +end; + +{ trefreshinfolist } + +constructor trefreshinfolist.create; +begin + inherited; + fsize:= sizeof(refreshinfoty); +end; + +function trefreshinfolist.Getitems(index: integer): refreshinfoty; +begin + getdata(index,result); +end; + +procedure trefreshinfolist.Setitems(index: integer; + const Value: refreshinfoty); +begin + setdata(index,value); +end; + +function trefreshinfolist.pop: boolean; +var + po1: pbyte; +begin + po1:= nil; + {$ifdef FPC}{$checkpointer off}{$endif} + result:= popbottomdata(po1^); + {$ifdef FPC}{$checkpointer default}{$endif} +end; + +function trefreshinfolist.pop(out value: refreshinfoty): boolean; +begin + result:= popbottomdata(value); +end; + +procedure trefreshinfolist.push(const value: refreshinfoty); +begin + pushdata(value); +end; + +function trefreshinfolist.checkassigncompatibility(const source: tpersistent): boolean; +begin + result:= source.inheritsfrom(trefreshinfolist); +end; + +{ tsyntaxpainter } + +constructor tsyntaxpainter.create(aowner: tcomponent); +begin + frefreshlist:= trefreshinfolist.create; + ftimer:= tsimpletimer.Create(0,{$ifdef FPC}@{$endif}dotimer,false,[to_single]); + flinesperslice:= defaultlinesperslice; + fdefdefs:= tdoublemsestringdatalist.create; + fdefaultsyntax:= -1; +// fdefaultboldbkgcolor:= cl_none; + fdeftext:= tmsestringdatalist.create; + fdeftext.onchange:= {$ifdef FPC}@{$endif}deflistchanged; + inherited; +end; + +destructor tsyntaxpainter.destroy; +begin + clear; + inherited; + ftimer.Free; + frefreshlist.Free; + fdefdefs.free; + fdeftext.free; +end; + +procedure tsyntaxpainter.clear; +var + int1: integer; +begin + frefreshlist.clear; + for int1:= 0 to high(fclients) do begin + if fclients[int1].client <> nil then begin + unregisterclient(int1); + end; + end; + for int1:= 0 to high(fsyntaxdefs) do begin + clearsyntaxdef(int1); + end; + sendchangeevent(oe_disconnect); +end; + +procedure tsyntaxpainter.clearsyntaxdef(handle: integer); +var + int1: integer; +begin + with fsyntaxdefs[handle] do begin + freeandnil(charstyles); + freeandnil(keywordnames); + for int1:= 0 to high(keywordar) do begin + keywordar[int1].Free; + end; + end; + finalize(fsyntaxdefs[handle]); +end; + +procedure tsyntaxpainter.initsyntaxdef(handle: integer); +begin + finalize(fsyntaxdefs[handle]); + fillchar(fsyntaxdefs[handle],sizeof(syntaxdefty),0); + with fsyntaxdefs[handle] do begin + defdefsnr:= -1; + charstyles:= tcharstyledatalist.create; + charstyles.add; //default + keywordchars:= defaultkeywordchars; + keywordnames:= tpointeransistringhashdatalist.create; + with colors do begin + font:= cl_default; + background:= cl_default; + statement:= cl_default; + pairmarkbackground:= cl_default; + end; + end; +end; + +function tsyntaxpainter.registerclient(sender: tobject; + alist: trichstringdatalist; aonlinechanged: integerchangedeventty = nil; + asyntaxdefhandle: integer = 0): integer; + + procedure initclient(var info: clientinfoty); + begin + info.client:= sender; + info.syntaxdefhandle:= asyntaxdefhandle; + info.list:= alist; + info.onlinechanged:= aonlinechanged; + end; + +var + int1: integer; +begin + for int1:= 0 to high(fclients) do begin + if fclients[int1].client = nil then begin + initclient(fclients[int1]); + result:= int1; + exit; + end; + end; + setlength(fclients,length(fclients)+1); + initclient(fclients[high(fclients)]); + result:= high(fclients); +end; + +procedure tsyntaxpainter.unregisterclient(handle: integer); + //eintreage mit alist loeschen +var + int1: integer; +begin + checkarrayindex(fclients,handle); + int1:= 0; + while int1 < frefreshlist.count do begin + if frefreshlist[int1].handle = handle then begin + frefreshlist.deletedata(int1); + end + else begin + inc(int1); + end; + end; + finalize(fclients[handle]); + fillchar(fclients[handle],sizeof(clientinfoty),0); +end; + +procedure tsyntaxpainter.setlinesperslice(const Value: integer); +var + int1: integer; +begin + if flinesperslice <> value then begin + flinesperslice := Value; + for int1:= 0 to high(fclients) do begin + with fclients[int1] do begin + scopestackcache:= nil; //scopestacks are now invlid + scopestackcachepo:= 0; + end; + end; + end; +end; + +procedure tsyntaxpainter.internalpaintsyntax(handle: integer; + start,count: integer; var startscopenr: integer); +var + scopeinfopo: scopeinfopoty; + + procedure popscope; + begin + with fclients[handle] do begin + if scopestackpo > 0 then begin + dec(scopestackpo); + startscopenr:= scopestack[scopestackpo]; + scopeinfopo:= @fsyntaxdefs[syntaxdefhandle].scopeinfos[startscopenr]; + end; + end; + end; + + procedure pushscope(const starttoken: starttokenty); + var + po1: scopeinfopoty; + begin + with starttoken,fclients[handle] do begin + if call then begin + inc(scopestackpo); + if length(scopestack) <= scopestackpo then begin + setlength(scopestack,scopestackpo+1); + end; + end; + scopestack[scopestackpo]:= scopenr; + po1:= @fsyntaxdefs[syntaxdefhandle].scopeinfos[scopenr]; + if po1^.fontinfonr <> 0 then begin + po1^.currfontinfonr:= po1^.fontinfonr; + end + else begin + if starttoken.fontinfonr <> 0 then begin + po1^.currfontinfonr:= starttoken.fontinfonr; + end + else begin + po1^.currfontinfonr:= scopeinfopo^.currfontinfonr; + end; + end; + scopeinfopo:= po1; + startscopenr:= scopenr; + end; + end; + +var + startpo: pmsechar; + linestart: boolean; + + function checktokenwhitespace(const atoken: tokeninfoty; + const apo: pmsechar): boolean; + var + po1: pmsechar; + begin + result:= not (tf_firstofline in atoken.flags) or linestart; + if result then begin + result:= (not (tf_startwhitespace in atoken.flags) or + (apo = startpo) or ((apo-1)^ = ' ') or ((apo-1)^ = c_tab)); + if result and (tf_endwhitespace in atoken.flags) then begin + po1:= apo+length(atoken.name); + result:= (po1^ = ' ') or (po1^ = c_tab) or (po1^ = #0) or + (po1^ = c_return) or (po1^ = c_linefeed); + end; + end; + end; + +var + str1: msestring; + lstr1: lmsestringty; + po1: pointer; + changed: boolean; + int1,int2,int3: integer; + bo1{,bo2}: boolean; + ristr: prichstringty; + wpo1: pmsechar; + alen,keywordlen: integer; +// ar1: msestringarty; + stok1: starttokenty; + format: formatinfoarty; +// firstrow,lastrow: integer; + wpo2: pmsechar; + +label + endlab; + +begin +// ar1:= nil; //copilerwarning + format:= nil; //copilerwarning + str1:= ''; + int2:= 0; +// firstrow:= start; +// lastrow:= start+count-1; + with fclients[handle] do begin + if (syntaxdefhandle < 0) or (syntaxdefhandle > high(fsyntaxdefs)) or + (fsyntaxdefs[syntaxdefhandle].charstyles = nil) then begin + goto endlab; + end; + with fsyntaxdefs[syntaxdefhandle] do begin + if startscopenr = -1 then begin + startscopenr:= high(scopeinfos); + stok1.scopenr:= startscopenr; + stok1.fontinfonr:= 0; + stok1.call:= true; + scopestackpo:= -1; + scopeinfopo:= @scopeinfos[startscopenr]; + pushscope(stok1); + end; + if (startscopenr >= 0) and (startscopenr < length(scopeinfos)) then begin + scopeinfopo:= @scopeinfos[startscopenr]; + while count > 0 do begin + if start >= list.count then begin + goto endlab; + end; + if (flinesperslice <> 0) and (start mod flinesperslice = 0) then begin + scopestackcachepo:= start div flinesperslice + 1; + if length(scopestackcache) < scopestackcachepo then begin + setlength(scopestackcache,scopestackcachepo); + end; + scopestackcache[scopestackcachepo-1].stack:= + copy(scopestack,0,scopestackpo+1); + scopestackcache[scopestackcachepo-1].startscope:= startscopenr; + end; + changed:= false; + ristr:= list.richitemspo[start]; + format:= ristr^.format; + startpo:= pointer(ristr^.text); + linestart:= true; + wpo1:= startpo; + alen:= length(ristr^.text); + keywordlen:= 0; + changed:= setcharstyle1(format,0,bigint, + charstyles[scopeinfopo^.currfontinfonr]) or + changed; + if alen > 0 then begin + repeat + if (wpo1^ = c_return) or (wpo1^ = c_linefeed) then begin + linestart:= true; + end; + if (keywordlen <= 0) and not scopeinfopo^.return then begin + lstr1.po:= wpo1; + while char(byte(wpo1^)) in keywordchars do begin + inc(wpo1); + end; + lstr1.len:= wpo1-lstr1.po; + if lstr1.len > 0 then begin //keyword suchen + if caseinsensitive then begin + str1:= struppercase(lstr1); + end; + po1:= nil; + for int1:= 0 to high(scopeinfopo^.keywords) do begin + with keywordar[scopeinfopo^.keywords[int1].nr{-1}] do begin + if caseinsensitive then begin + po1:= find(str1); + end + else begin + po1:= find(lstr1); + end; + end; + if po1 <> nil then begin //wort gefunden + if scopeinfopo^.keywords[int1].fontinfonr <> 0 then begin + po1:= pointer(scopeinfopo^.keywords[int1].fontinfonr+1); + end; //eigene fontinfonr dominiert + break; + end; + end; + if po1 <> nil then begin + changed:= setcharstyle1(format,lstr1.po-startpo,lstr1.len, + charstyles[ptruint(po1)-1]) or changed; + dec(alen,lstr1.len); + keywordlen:= 0; + linestart:= false; + end + else begin + keywordlen:= lstr1.len; + dec(wpo1,lstr1.len); //text zurueckgeben + end; + end; + end; + bo1:= true; + if (length(scopeinfopo^.starttokens) > 0) then begin + if (char(byte(wpo1^)) in scopestartchars) then begin + //starttoken suchen + for int1:= 0 to high(scopeinfopo^.starttokens) do begin + with scopeinfopo^.starttokens[int1] do begin + if hastokenchars then begin + wpo2:= wpo1; + while (wpo2^ <= #255) and (char(byte(wpo2^)) in tokenchars) do begin + inc(wpo2); + if not shortcircuit then begin + break; + end; + end; + int2:= wpo2-wpo1; + if int2 > 0 then begin + bo1:= false; + end; + end + else begin + if caseinsensitive and msestartsstrcaseinsensitive( + pointer(token.name),wpo1) or + not caseinsensitive and + msestartsstr(pointer(token.name),wpo1) then begin + if checktokenwhitespace(token,wpo1) then begin + bo1:= false; + int2:= length(token.name); + end; + end; + end; + if not bo1 then begin + if fontinfonr <> 0 then begin + changed:= setcharstyle1(format,wpo1-startpo,int2, + charstyles[fontinfonr]) or changed; + int3:= int2; + end + else begin + int3:= 0; //keine sonderbehandlung + end; + pushscope(scopeinfopo^.starttokens[int1]); + changed:= setcharstyle1(format,wpo1-startpo+int3,bigint, + charstyles[scopeinfopo^.currfontinfonr]) or changed; + inc(wpo1,int2); + dec(alen,int2); + dec(keywordlen,int2); + break; + end; + end; + end; + end + else begin + if scopeinfopo^.defaulttarget >= 0 then begin + pushscope(scopeinfopo^.starttokens[scopeinfopo^.defaulttarget]); + changed:= setcharstyle1(format,wpo1-startpo+int3,bigint, + charstyles[scopeinfopo^.currfontinfonr]) or changed; + end; + end; + end; + if bo1 and (scopeinfopo^.hasendtokens or scopeinfopo^.return) then begin + if (length(scopeinfopo^.endtokens) > 0) then begin + if (char(byte(wpo1^)) in scopeendchars) then begin + //endtoken suchen + for int1:= 0 to high(scopeinfopo^.endtokens) do begin + with scopeinfopo^.endtokens[int1] do begin + if hastokenchars then begin + if (wpo1^ <= #255) and (char(byte(wpo1^)) in tokenchars) then begin + int2:= 1; + bo1:= false; + end; + end + else begin + if (caseinsensitive and msestartsstrcaseinsensitive( + pointer(token.name),wpo1) or + not caseinsensitive and + msestartsstr(pointer(token.name),wpo1)) and + checktokenwhitespace(token,wpo1) then begin +// if msestartsstr(pointer(token.name),wpo1) and +// checktokenwhitespace(token,wpo1) then begin + bo1:= false; + int2:= length(token.name); + end; + end; + if not bo1 then begin + if fontinfonr <> 0 then begin + int3:= fontinfonr; + end + else begin + int3:= scopeinfopo^.currfontinfonr; + end; + changed:= setcharstyle1(format,wpo1-startpo,int2, + charstyles[int3]) or changed; + inc(wpo1,int2); + if int2 = 0 then begin + int2:= 1; //zeilenende + end; + dec(alen,int2); + dec(keywordlen,int2); + popscope; + changed:= setcharstyle1(format,wpo1-startpo,bigint, + charstyles[scopeinfopo^.currfontinfonr]) or changed; + break; + end; + end; + end; + end; + end + else begin //return on any char + if not scopeinfopo^.return and (wpo1^ <> #0) then begin + inc(wpo1); + end; //else return immediately + bo1:= false; + popscope; + changed:= setcharstyle1(format,wpo1-startpo,bigint, + charstyles[scopeinfopo^.fontinfonr]) or changed; + end; + end; + + if bo1 then begin + if (wpo1^ <> ' ') and (wpo1^ <> c_tab) then begin + linestart:= false; + end; + inc(wpo1); + dec(alen); + dec(keywordlen); + end + else begin + linestart:= false; + end; + until alen < 0; + if scopeinfopo^.return then begin + popscope; + end; + end; + if changed then begin + for int1:= 0 to high(boldchars.items) do begin + with boldchars.items[int1],pos do begin + if row = start then begin + if bold then begin + bo1:= not (fs_bold in getcharstyle(format,col).fontstyle); + updatefontstyle1(format,col,len,fs_bold,bo1); + end; + if (boldchars.backgroundcolor <> cl_none) then begin + setcolorbackground1(format,col,len,boldchars.backgroundcolor); + end; + end; + end; + end; + if assigned(onlinechanged) then begin + bo1:= isequalformat(ristr^.format,format); + if not bo1 then begin + ristr^.format:= format; + onlinechanged(self,start); + end; + end + else begin + ristr^.format:= format; + end; + end; + inc(start); + dec(count); + end; + end; + end; +endlab: +{ + for int1:= 0 to high(boldchars.items) do begin + with boldchars.items[int1],pos do begin + if (row >= firstrow) and (row <= lastrow) then begin + bo2:= false; + if bold then begin + bo1:= not (fs_bold in getcharstyle( + list.richitemspo[row]^.format,col).fontstyle); + bo2:= updatefontstyle1(list.richitemspo[row]^.format,col,len,fs_bold,bo1); + end; + bo2:= (boldchars.backgroundcolor <> cl_none) and + setcolorbackground1(list.richitemspo[row]^.format,col,len, + boldchars.backgroundcolor) or bo2; + if bo2 and assigned(onlinechanged) then begin + onlinechanged(self,row); + end; + end; + end; + end; +} + end; +end; + +procedure tsyntaxpainter.calcrefreshinfo(var info: refreshinfoty; var startscope: integer); +var + startbefore: integer; + stackspo: integer; +begin + with info do begin + startbefore:= astart; + if flinesperslice > 0 then begin + stackspo:= astart div flinesperslice; + end + else begin + stackspo:= -1; + end; + with fclients[handle] do begin + if stackspo >= scopestackcachepo then begin + stackspo:= scopestackcachepo-1; + end; + if stackspo >= 0 then begin + astart:= stackspo * flinesperslice; + scopestack:= scopestackcache[stackspo].stack; + scopestackpo:= high(scopestack); + startscope:= scopestackcache[stackspo].startscope; + end + else begin + startscope:= -1; + astart:= 0; //recalc from begining + end; + count:= count + astart - startbefore; + end; + end; +end; + +procedure tsyntaxpainter.paintsyntax(handle: integer; + start,count: halfinteger; background: boolean = false); + + +var + refreshinfo: refreshinfoty; + int1,int2: integer; + startscopenr: integer; + po1: prefreshinfoty; +begin + checkarrayindex(fclients,handle); +// refreshinfo.startscopenr:= -1; + refreshinfo.handle:= handle; + refreshinfo.astart:= start; + refreshinfo.count:= count; + if background then begin + for int1:= 0 to frefreshlist.count - 1 do begin + po1:= frefreshlist.getitempo(int1); + if po1^.handle = handle then begin + int2:= start+count - (po1^.astart + po1^.count); //new endpoint - aendpoint + if po1^.astart <= start then begin + if int2 > 0 then begin //new task longer + inc(po1^.count,int2); //exend end + end; + end + else begin + if int2 > 0 then begin //new task longer + po1^.count:= count; + end + else begin + inc(po1^.count,po1^.astart-start); + end; + po1^.astart:= start; + end; + exit; //task extended + end; + end; + frefreshlist.push(refreshinfo); + ftimer.Enabled:= true; + exit; + end; + calcrefreshinfo(refreshinfo,startscopenr); + internalpaintsyntax(handle,refreshinfo.astart,refreshinfo.count,startscopenr); +end; + +procedure tsyntaxpainter.dotimer(const sender: tobject); +var + po1: prefreshinfoty; + int1: integer; + startscopenr: integer; +begin + if frefreshlist.count > 0 then begin + po1:= prefreshinfoty(frefreshlist.getitempo(0)); + calcrefreshinfo(po1^,startscopenr); + with po1^ do begin + if flinesperslice = 0 then begin + int1:= count; + end + else begin + if count > flinesperslice + 1 then begin + int1:= flinesperslice + 1; + end + else begin + int1:= count; + end; + end; + internalpaintsyntax(handle,astart,int1,startscopenr); + dec(count,int1); + if count <= 0 then begin + frefreshlist.pop + end + else begin + inc(astart,int1); + if astart >= fclients[handle].List.count then begin + frefreshlist.pop; + end + end; + end; + if frefreshlist.count <> 0 then begin + ftimer.Enabled:= true; + end; + end; +end; + +procedure checktokenchars(const ar1: tokeninfoarty; + const caseinsensitive: boolean; + out hastokenchars: boolean; out tokenchars: tokencharsty); +var + int1: integer; + ch1: char; +begin + hastokenchars:= ar1 <> nil; + tokenchars:= []; + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + if (length(name) <> 1) or (name[1] > #255) or (flags <> []) then begin + hastokenchars:= false; + break; + end; + end; + end; + if hastokenchars then begin + for int1:= 0 to high(ar1) do begin + ch1:= char(byte(ar1[int1].name[1])); + if caseinsensitive then begin + include(tokenchars,upperchars[ch1]); + include(tokenchars,lowerchars[ch1]); + end + else begin + include(tokenchars,ch1); + end; + end; + end; +end; + +function nexttokeninfo(var value: lstringty; out res: string; + out tokenflags: tokenflagsty): boolean; + //false wenn kein quote vorhanden +var + po1: pchar; + int1,int2,int3: integer; +begin + result:= false; + res:= ''; + tokenflags:= []; + po1:= strlnscan(value.po,' ',value.len); //skip spaces + if po1 = nil then begin + int1:= value.len; + end + else begin + int1:= po1-value.po; //startindex + end; + if (po1 <> nil) then begin + if po1^ = '.' then begin + include(tokenflags,tf_startwhitespace); + inc(po1); + end + else begin + if po1^ = ',' then begin + include(tokenflags,tf_firstofline); + inc(po1); + end; + end; + if po1^ = '''' then begin + result:= true; + inc(po1); + int2:= 0; + int3:= value.len-int1; + setlength(res,int3); //maximum + while po1^ <> #0 do begin + if po1^ <> '''' then begin + (pchar(pointer(res))+int2)^:= po1^; + inc(int2); + end + else begin + inc(po1); + if po1^ = '''' then begin + (pchar(pointer(res))+int2)^:= po1^; + inc(int2); + end + else begin + if po1^ = '.' then begin + include(tokenflags,tf_endwhitespace); + inc(po1); + end; + break; + end; + end; + inc(po1); + end; + setlength(res,int2); + int1:= po1-value.po; + end; + end; + inc(value.po,int1); + dec(value.len,int1); +end; + +function tsyntaxpainter.readdeffile(stream: ttextstream): integer; +type + tokennrty = (tn_styles,tn_caseinsensitive,tn_keywordchars,tn_addkeywordchars, + tn_colors,tn_pairwords,tn_keyworddefs, + tn_scope,tn_endtokens,tn_keywords,tn_jumptokens,tn_calltokens, + tn_return); +const + tn_canmultiple = [tn_keyworddefs{,tn_jumptokens,tn_calltokens,tn_endtokens}]; + + nonetoken = 'NONE'; + tokens: array[tokennrty] of string = ( + 'STYLES','CASEINSENSITIVE','KEYWORDCHARS','ADDKEYWORDCHARS', + 'COLORS','PAIRWORDS','KEYWORDDEFS', + 'SCOPE','ENDTOKENS','KEYWORDS','JUMPTOKENS','CALLTOKENS', + 'RETURN'); + tn_localstart = tn_scope; +var + linenr: integer; + line: string; + akttoken: tokennrty; + syntaxdefpo: syntaxdefpoty; + + procedure addkeywordrule(const keywordsnr: integer; afontinfonr: integer); + begin + with syntaxdefpo^ do begin + setlength(scopeinfos[aktscopeinfo].keywords, + length(scopeinfos[aktscopeinfo].keywords)+1); + with scopeinfos[aktscopeinfo].keywords[high(scopeinfos[aktscopeinfo].keywords)] do begin + nr:= keywordsnr; + fontinfonr:= afontinfonr; + end; + end; + end; + + procedure updateaktscope; + var + int1: integer; + begin + with syntaxdefpo^ do begin + if aktscopeinfo < length(scopeinfos) then begin + with scopeinfos[aktscopeinfo] do begin + markstartchars(starttokens,scopestartchars,caseinsensitive); + for int1:= 0 to high(endtokens) do begin + with endtokens[int1] do begin + if hastokenchars then begin + scopeendchars:= scopeendchars + endtokens[int1].tokenchars; + end + else begin + markstartchars(token.name,scopeendchars,caseinsensitive); + end; + end; + end; + end; + end; + end; + end; //updateaktscope + + function addscoperule(const astarttokens: starttokenarty; + const aendtokens: endtokenarty; ahasendtokens: boolean; + areturn: boolean; + afontinfonr: integer; + const akeywords: keywordinfoarty; + const adefaulttarget: int32): integer; + + begin + with syntaxdefpo^ do begin + result:= length(scopeinfos); + aktscopeinfo:= result; + setlength(scopeinfos,result+1); + with scopeinfos[result] do begin + keywords:= akeywords; + starttokens:= copy(astarttokens); + endtokens:= copy(aendtokens); + hasendtokens:= ahasendtokens; + return:= areturn; + fontinfonr:= afontinfonr; + defaulttarget:= adefaulttarget; + end; + updateaktscope; + end; + end; + + + procedure error(text: string); + begin + raise exception.Create(text+'!'); + end; + + function lineinfo: string; + begin + result:= ' at line '+ inttostr(linenr); + end; + + procedure invalidtoken; + begin + error('Invalid token '''+line+''''+lineinfo); + end; + + procedure noscope; + begin + error('No scope'+lineinfo); + end; + + procedure invalidstyle; + begin + error('Invalid style '''+line+''''+lineinfo); + end; + + procedure invalidname; + begin + error('Invalid name '''+line+''''+lineinfo); + end; + + procedure nameexists; + begin + error('Name exists. '''+line+''''+lineinfo); + end; + + procedure namenotfound; + begin + error('Name not found. '''+line+''''+lineinfo); + end; + + procedure invalidstring; + begin + error('Invalid string. '''+line+''''+lineinfo); + end; + + procedure invalidcolor; + begin + error('Invalid color. '''+line+''''+lineinfo); + end; + + function getcolor(var aline: lstringty; out acolor: colorty): boolean; + var + str1: string; + begin + result:= false; + nextword(aline,str1); + if str1 <> '' then begin + try + acolor:= stringtocolor(str1); + except + invalidcolor; + end; + end; + result:= true; + end; + + procedure addname(list: tpointeransistringhashdatalist; + const name: lstringty; nummer: integer); + var + str1: string; + begin + str1:= struppercase(name); + if list.find(str1) <> nil then begin + nameexists; + end; + if (length(str1) = 0) or not ((str1[1] >= 'A') and (str1[1] <= 'Z')) then begin + invalidname; + end; + list.add(str1,pointer(nummer+1)); + end; + + function findname(list: tpointeransistringhashdatalist; const name: lstringty): integer; + begin + result:= ptrint(list.find(struppercase(name))); + if result = 0 then begin + namenotfound; + end; + dec(result); + end; + +var + lstr1: lstringty; + + function nextline: boolean; + begin + if stream.eof then begin + lstr1.len:= 0; + lstr1.po:= nil; + result:= true; + end + else begin + stream.readln(line); + inc(linenr); + result:= (strlnscan(pointer(line),' ',length(line)) <> nil) and + (checkfirstchar(line,'#') = nil); //comment + if result then begin + stringtolstring(line,lstr1); + end; + end; + end; + + procedure addquotedtokens(var ar1: tokeninfoarty; out isnextline: boolean); + var + str1: string; + tf1: tokenflagsty; + begin + isnextline:= false; + if not stream.eof then begin + while true do begin + while nexttokeninfo(lstr1,str1,tf1) do begin + setlength(ar1,high(ar1)+2); + with ar1[high(ar1)] do begin + name:= msestring(str1); + flags:= tf1; + end; + isnextline:= false; + end; + if lstr1.len = 0 then begin + isnextline:= true; + if stream.eof then begin + break; + end; + repeat + until nextline; //skip comments + end + else begin + break; + end; + end; + end; + end; //getquotedstrings + +const + defaultname = 'DEFAULT'; +var + flags: set of tokennrty; + str1{,str2}: string; + keys: tpointeransistringhashdatalist; + scopenames,stylenames: tpointeransistringhashdatalist; + int1,int2,int3,int4: integer; + lstr2,lstr3,lstr4: lstringty; + global: boolean; + wstrar1: msestringarty; + bo1,bo2: boolean; + aktkeywordfontinfonr: integer; + ar1: tokeninfoarty; + ar2: msestringarty; + tokenchars1: tokencharsty; + isnextline: boolean; + tf1: tokenflagsty; + i5: int32; + +begin + result:= -1; + for int1:= 0 to high(fsyntaxdefs) do begin + if fsyntaxdefs[int1].charstyles = nil then begin + result:= int1; + break; + end; + end; + if result = -1 then begin + result:= length(fsyntaxdefs); + setlength(fsyntaxdefs,result+1); + end; + initsyntaxdef(result); + syntaxdefpo:= @fsyntaxdefs[result]; + with syntaxdefpo^ do begin + keys:= tpointeransistringhashdatalist.create; + scopenames:= tpointeransistringhashdatalist.create; + stylenames:= tpointeransistringhashdatalist.create; + keys.add(tokens); + stylenames.add('',pointer(1)); //default + // fcharstyles.add; //default + global:= true; + linenr:= 0; + flags:= []; + akttoken:= tokennrty(-1); + aktkeywordfontinfonr:= 0; + try + isnextline:= false; + repeat + if isnextline or nextline then begin + isnextline:= false; + nextword(lstr1,lstr2); + int1:= ptrint(keys.find(struppercase(lstr2))); + if int1 <> 0 then begin + akttoken:= tokennrty(int1-1); + if akttoken in (flags - tn_canmultiple) then begin + invalidtoken; + end; + include(flags,akttoken); + if akttoken >= tn_localstart then begin + global:= false; + end; + if global then begin + case akttoken of + tn_caseinsensitive: caseinsensitive:= true; + tn_keywordchars: begin + keywordchars:= []; + end; + tn_keyworddefs: begin + nextword(lstr1,lstr3); + if lstr3.len = 0 then begin + invalidtoken; + end; + setlength(keywordar,length(keywordar)+1); +// keywordar[high(keywordar)]:= thashedmsestrings.create; + keywordar[high(keywordar)]:= tkeywordlist.create; + addname(keywordnames,lstr3,high(keywordar)); + nextword(lstr1,lstr4); + if lstr4.len > 0 then begin + keywordar[high(keywordar)].fdefaultstyle:= + findname(stylenames,lstr4); + end; + end; + tn_colors: begin + if getcolor(lstr1,colors.font) then begin + if getcolor(lstr1,colors.background) then begin + if getcolor(lstr1,colors.statement) then begin + if getcolor(lstr1,colors.pairmarkbackground) then begin + end; + end; + end; + end; + end; + tn_addkeywordchars,tn_styles,tn_pairwords: begin + end; + else begin + invalidtoken; + end; + end; + end + else begin + case akttoken of + tn_scope: begin + nextword(lstr1,lstr2); + nextword(lstr1,lstr3); + int1:= findname(stylenames,lstr3); + updateaktscope; + addname(scopenames,lstr2,addscoperule( + nil,nil,false,false,int1,nil,-1)); + flags:= []; + end; + tn_keywords: begin + if length(scopeinfos) = 0 then begin + noscope; + end; + nextword(lstr1,lstr3); + aktkeywordfontinfonr:= findname(stylenames,lstr3); + end; + tn_return,tn_endtokens,tn_calltokens,tn_jumptokens: begin + if length(scopeinfos) = 0 then begin + noscope; + end + else begin + if akttoken = tn_endtokens then begin + if scopeinfos[aktscopeinfo].return then begin + invalidtoken; + end; + scopeinfos[aktscopeinfo].hasendtokens:= true; + end + else begin + if akttoken = tn_return then begin + if scopeinfos[aktscopeinfo].hasendtokens then begin + invalidtoken; + end; + scopeinfos[aktscopeinfo].return:= true; + end; + end; + end; + end; + else begin + invalidtoken; + end; + end; + end; + end + else begin + lstringgoback(lstr1,lstr2); + case akttoken of + tn_keyworddefs: begin + setlength(wstrar1,0); + repeat + bo1:= nextquotedstring(lstr1,str1); + if caseinsensitive then begin + str1:= struppercase(str1); + end; + if bo1 then begin + setlength(wstrar1,length(wstrar1)+1); + wstrar1[high(wstrar1)]:= msestring(str1); + end; + until not bo1; + nextword(lstr1,lstr3); + int2:= findname(stylenames,lstr3); + for int1:= 0 to high(wstrar1) do begin + keywordar[high(keywordar)].add(wstrar1[int1],pointer(int2+1)); + end; + end; + tn_keywordchars,tn_addkeywordchars: begin + nextquotedstring(lstr1,str1); + nextword(lstr1,lstr3); + if lstr3.len <> 0 then begin + invalidstring; + end; + for int1:= 1 to length(str1) do begin + include(keywordchars,str1[int1]); + end; + end; + tn_styles: begin + nextword(lstr1,lstr2); + addname(stylenames,lstr2,charstyles.count); + try + charstyles.add(lstringtostring(lstr1)); + except + invalidstyle; +// error('Invalid style '''+line+''''+lineinfo); + end; + end; + tn_pairwords: begin + ar2:= nil; + while nextquotedstring(lstr1,str1) do begin +// if caseinsensitive then begin +// str1:= struppercase(str1); +// end; + additem(ar2,msestring(str1)); + end; + if ar2 <> nil then begin + additem(pairwords.upper,ar2); + end + else begin + invalidstring; + end; + end; + tn_calltokens,tn_jumptokens: begin + bo1:= nexttokeninfo(lstr1,str1,tf1); +// bo1:= nextquotedstring(lstr1,str1); + if not bo1 then begin //at least one +// invalidstring; + ar1:= nil; //no token def + end + else begin + setlength(ar1,1); + ar1[0].name:= msestring(str1); + ar1[0].flags:= tf1; + addquotedtokens(ar1,isnextline); + end; + if not isnextline then begin + nextword(lstr1,lstr3); + int1:= findname(scopenames,lstr3); + nextword(lstr1,lstr3); + int2:= findname(stylenames,lstr3); + end + else begin + namenotfound; + end; + int3:= length(scopeinfos[aktscopeinfo].starttokens); + checktokenchars(ar1,caseinsensitive,bo2,tokenchars1); + if bo2 then begin + setlength(scopeinfos[aktscopeinfo].starttokens,int3+1); + with scopeinfos[aktscopeinfo].starttokens[int3] do begin + hastokenchars:= hastokenchars or bo1; + tokenchars:= tokenchars1; + fontinfonr:= int2; + scopenr:= int1; + call:= akttoken = tn_calltokens; + shortcircuit:= not call and (scopenr = aktscopeinfo); + end; + end + else begin + if not bo1 then begin + setlength(ar1,1); //empty tokenname + with scopeinfos[aktscopeinfo] do begin + if defaulttarget < 0 then begin //first + defaulttarget:= int3; + end; + end; + end; + i5:= high(ar1); + setlength(scopeinfos[aktscopeinfo].starttokens,int3+i5+1); + for int4:= int3 to int3 + i5 do begin + with scopeinfos[aktscopeinfo].starttokens[int4] do begin + token:= ar1[int4-int3]; + if caseinsensitive then begin + token.name:= struppercase(token.name); + end; + fontinfonr:= int2; + scopenr:= int1; + call:= akttoken = tn_calltokens; + shortcircuit:= not call and (scopenr = aktscopeinfo); + end; + end; + end; + end; + tn_endtokens: begin + with scopeinfos[aktscopeinfo] do begin + ar1:= nil; + addquotedtokens(ar1,isnextline); + int3:= length(endtokens); + if not isnextline then begin + nextword(lstr1,lstr3); + int2:= findname(stylenames,lstr3); + end + else begin + int2:= fontinfonr; + end; + checktokenchars(ar1,caseinsensitive,bo1,tokenchars1); + if bo1 then begin + setlength(endtokens,int3+1); + with endtokens[high(endtokens)] do begin + hastokenchars:= true; + tokenchars:= tokenchars1; + fontinfonr:= int2; + end; + end + else begin + setlength(scopeinfos[aktscopeinfo].endtokens,int3+length(ar1)); + for int4:= int3 to int3 + high(ar1) do begin + with scopeinfos[aktscopeinfo].endtokens[int4] do begin + token:= ar1[int4-int3]; + if caseinsensitive then begin + token.name:= struppercase(token.name); + end; + fontinfonr:= int2; + end; + end; + end; + end; + end; + tn_keywords: begin + nextword(lstr1,lstr3); + if lstr3.len > 0 then begin + int1:= findname(keywordnames,lstr3); + int2:= aktkeywordfontinfonr; + if int2 < 0 then begin + int2:= keywordar[int1].fdefaultstyle; + end; + nextword(lstr1,lstr4); + if lstr4.len > 0 then begin + int2:= findname(stylenames,lstr4); + end; + addkeywordrule(int1,int2); + end; + end; + else begin + invalidtoken; + end; + end; + end; + end; + until stream.eof and not (isnextline and (lstr1.len > 0)); + updateaktscope; + finally + keys.free; + scopenames.free; + stylenames.Free; + end; + with pairwords do begin + setlength(lower,length(upper)); + if caseinsensitive then begin + for int1:= 0 to high(upper) do begin + setlength(lower[int1],length(upper[int1])); + for int2:= 0 to high(upper[int1]) do begin + upper[int1,int2]:= mseuppercase(upper[int1,int2]); + lower[int1,int2]:= mselowercase(upper[int1,int2]); + end; + end; + end + else begin + for int1:= 0 to high(upper) do begin + setlength(lower[int1],length(upper[int1])); + for int2:= 0 to high(upper[int1]) do begin + lower[int1,int2]:= upper[int1,int2]; //copy original + end; + end; + end; + end; + end; + syntaxchanged(); +end; + +function tsyntaxpainter.readdeffile(const afilename: filenamety): integer; +var + stream1: ttextstream; +begin + stream1:= ttextstream.create(afilename,fm_read); + try + result:= readdeffile(stream1); + finally + stream1.free; + end; +end; + +procedure tsyntaxpainter.freedeffile(handle: integer); +begin + checkarrayindex(fsyntaxdefs,handle); + clearsyntaxdef(handle); +end; + +function tsyntaxpainter.readdeffile(const atext: string): integer; +var + stream1: ttextstream; +begin + stream1:= ttextstream.create; + try + stream1.writedatastring(atext); + stream1.position:= 0; + result:= readdeffile(stream1); + finally + stream1.free; + end; +end; + +procedure tsyntaxpainter.syntaxchanged; +var + int1: integer; +begin + for int1:= 0 to high(fclients) do begin + with fclients[int1] do begin + if assigned(onlinechanged) then begin + onlinechanged(self,-1); + end; + end; + end; +end; +{ +procedure tsyntaxpainter.invalidatesyntax(handle, start,count: integer); +var + int1,end1,end2: integer; + refreshinfo: refreshinfoty; +begin + for int1:= 0 to frefreshlist.count - 1 do begin + if frefreshlist[int1].handle = handle then begin + refreshinfo:= frefreshlist[int1]; + if (refreshinfo.astart <= start) then begin + if refreshinfo.count = maxint then begin + exit; //schon in arbeit + end; + end1:= refreshinfo.astart + refreshinfo.count; + if end1 >= start then begin //kann erweitert werden + if count = maxint then begin + refreshinfo.count:= maxint; + frefreshlist[int1]:= refreshinfo; + exit; + end; + end2:= start + count; + if end2 > end1 then begin + refreshinfo.count:= refreshinfo.count + end2-end1; + frefreshlist[int1]:= refreshinfo; + exit; + end; + end; + end; + end; + end; + paintsyntax(handle,start,count,true); +end; +} +procedure tsyntaxpainter.setdefdefs(const Value: tdoublemsestringdatalist); +begin + fdefdefs.assign(Value); +end; + +function tsyntaxpainter.linkdeffile(const sourcefilename: filenamety): integer; +var + int1,int2: integer; + strar1: msestringarty; + stream: ttextstream; + str1: filenamety; + +begin + result:= -1; + for int1:= 0 to fdefdefs.count - 1 do begin + strar1:= nil; + splitstringquoted(defdefs[int1].a,strar1); + for int2:= 0 to high(strar1) do begin + if checkfilename(sourcefilename,strar1[int2],true) then begin + result:= int1; + break; + end; + end; + if result >= 0 then begin + break; + end; + end; + if result >= 0 then begin + int2:= result; + result:= -1; + for int1:= 0 to high(fsyntaxdefs) do begin + with fsyntaxdefs[int1] do begin + if (charstyles <> nil) and (defdefsnr = int2) then begin + result:= int1; + break; + end; + end; + end; + if result < 0 then begin + str1:= fdefdefs[int2].b; + str1:= filepath(fdefsdir,str1); + stream:= ttextstream.create(str1,fm_read); + try + try + result:= readdeffile(stream); + except + on e: exception do begin + e.message:= ansistring( + 'tsyntaxpaintermse: file ''' +str1 + ''' ' +msestring(e.message)); + raise; + end; + end; + fsyntaxdefs[result].defdefsnr:= int2; + finally + stream.Free; + end; + end; + end; +end; + +procedure tsyntaxpainter.setdeftext(const avalue: tmsestringdatalist); +begin + fdeftext.assign(avalue); +end; + +procedure tsyntaxpainter.deflistchanged(const sender: tobject); +var + stream1: ttextstream; +begin + if not (csdesigning in componentstate) then begin + if fdefaultsyntax <> - 1 then begin + freedeffile(fdefaultsyntax); + end; + stream1:= fdeftext.dataastextstream; + try + fdefaultsyntax:= readdeffile(stream1); + finally + stream1.destroy(); + end; + end; +end; + +function tsyntaxpainter.getboldchars(index: integer): markinfoty; +begin + checkarrayindex(fclients,index); + result:= fclients[index].boldchars; +end; + +procedure tsyntaxpainter.setboldchars(index: integer; const avalue: markinfoty); +begin + checkarrayindex(fclients,index); + fclients[index].boldchars:= avalue; +end; + +function tsyntaxpainter.getcolors(index: integer): syntaxcolorinfoty; +begin + checkarrayindex(fclients,index); + result:= fsyntaxdefs[fclients[index].syntaxdefhandle].colors; +end; + +function tsyntaxpainter.getpairwords(index: int32): pairwordsty; +begin + checkarrayindex(fclients,index); + result:= fsyntaxdefs[fclients[index].syntaxdefhandle].pairwords; +end; + +function tsyntaxpainter.getcaseinsensitive(index: int32): boolean; +begin + checkarrayindex(fclients,index); + result:= fsyntaxdefs[fclients[index].syntaxdefhandle].caseinsensitive; +end; + +{ tkeywordlist } + +constructor tkeywordlist.create; +begin + fdefaultstyle:= -1; + inherited; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/msesysenvmanagereditor.mfm b/mseide-msegui/lib/common/designutils/msesysenvmanagereditor.mfm new file mode 100644 index 0000000..0e42915 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msesysenvmanagereditor.mfm @@ -0,0 +1,538 @@ +object msesysenvmanagereditorfo: tmsesysenvmanagereditorfo + visible = False + bounds_x = 57 + bounds_y = 574 + bounds_cx = 861 + bounds_cy = 229 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 861 + 229 + ) + options = [fo_freeonclose, fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder, fo_savestate] + statfile = statfile1 + caption = 'Edit tsysenvmanager' + windowopacity = -Inf + moduleclassname = 'tmseform' + object la2: tlayouter + bounds_x = 0 + bounds_y = 200 + bounds_cx = 861 + bounds_cy = 0 + anchors = [an_top] + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + optionslayout = [lao_aligny] + dist_top = 4 + end + object tlayouter2: tlayouter + taborder = 1 + bounds_x = 747 + bounds_y = 200 + bounds_cx = 107 + bounds_cy = 21 + anchors = [an_right, an_bottom] + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + optionslayout = [lao_placex] + place_mindist = 5 + place_maxdist = 5 + dist_top = 3 + object ok: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + bounds_x = 0 + bounds_y = 1 + bounds_cx = 50 + bounds_cy = 20 + bounds_cxmin = 50 + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + reffontheight = 14 + end + object cancel: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + taborder = 1 + bounds_x = 55 + bounds_y = 1 + bounds_cx = 52 + bounds_cy = 20 + bounds_cxmin = 50 + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + reffontheight = 14 + end + end + object grid: twidgetgrid + frame.localprops = [] + frame.localprops1 = [] + taborder = 2 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 861 + bounds_cy = 194 + anchors = [an_top, an_bottom] + optionsgrid = [og_colsizing, og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixcols.count = 1 + fixcols.items = < + item + width = 24 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 16 + captions.items = < + item + caption = 'Kind' + end + item + caption = 'Name' + end + item + caption = 'Alias' + end + item + caption = 'MA' + hint = 'arf_mandatory' + end + item + caption = 'AO' + hint = 'arf_argopt' + end + item + caption = 'FN' + hint = 'arf_filenames' + end + item + caption = 'SO' + hint = 'arf_statoverride' + end + item + caption = 'SA' + hint = 'arf_statadval' + end + item + caption = 'UQ' + hint = 'arf_unquote' + end + item + caption = 'IN' + hint = 'arf_integer' + end + item + caption = 'HE' + hint = 'arf_help' + end + item + caption = 'Initvalue' + end + item + caption = 'Argument' + end + item + caption = 'Help' + end + item + caption = 'Before' + end + item + caption = 'After' + end> + end> + datacols.count = 16 + datacols.options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + datacols.items = < + item[kinded] + width = 72 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'kinded' + dataclass = tgridenumdatalist + end + item[nameed] + width = 68 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'nameed' + dataclass = tgridmsestringdatalist + end + item[aliased] + width = 117 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'aliased' + dataclass = tgridmsestringdatalist + end + item[mandatory] + width = 17 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'mandatory' + dataclass = tgridintegerdatalist + end + item[argopt] + width = 17 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'argopt' + dataclass = tgridintegerdatalist + end + item[filenames] + width = 17 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'filenames' + dataclass = tgridintegerdatalist + end + item[statoverride] + width = 17 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'statoverride' + dataclass = tgridintegerdatalist + end + item[stataddval] + width = 17 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'stataddval' + dataclass = tgridintegerdatalist + end + item[unquote] + width = 17 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'unquote' + dataclass = tgridintegerdatalist + end + item[integer] + width = 17 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'integer' + dataclass = tgridintegerdatalist + end + item[help] + width = 17 + options = [co_drawfocus, co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_fixwidth, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'help' + dataclass = tgridintegerdatalist + end + item[initvalueed] + width = 121 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'initvalueed' + dataclass = tgridmsestringdatalist + end + item[argumented] + width = 72 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'argumented' + dataclass = tgridmsestringdatalist + end + item[helped] + width = 102 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'helped' + dataclass = tgridmsestringdatalist + end + item[beforeed] + width = 73 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'beforeed' + dataclass = tgridmsestringdatalist + end + item[aftered] + width = 73 + options = [co_focusselect, co_mouseselect, co_keyselect, co_multiselect, co_rowselect, co_proportional, co_savestate, co_cancopy, co_canpaste, co_mousescrollrow] + widgetname = 'aftered' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + statfile = statfile1 + reffontheight = 14 + object kinded: tenumtypeedit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.button.color = -1879048187 + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + end> + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 72 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + oninit = kindedinit + reffontheight = 14 + end + object nameed: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 2 + visible = False + bounds_x = 73 + bounds_y = 0 + bounds_cx = 68 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + reffontheight = 14 + end + object aliased: tmemodialogedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 3 + visible = False + bounds_x = 142 + bounds_y = 0 + bounds_cx = 117 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + reffontheight = 14 + end + object mandatory: tbooleanedit + Tag = 7 + optionswidget1 = [] + optionsskin = [osk_framebuttononly] + taborder = 4 + bounds_x = 260 + bounds_y = 0 + bounds_cx = 17 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate, oe1_checkvalueafterstatread] + visible = False + group = 1 + end + object argopt: tbooleanedit + Tag = 8 + optionswidget1 = [] + optionsskin = [osk_framebuttononly] + taborder = 5 + bounds_x = 278 + bounds_y = 0 + bounds_cx = 17 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate, oe1_checkvalueafterstatread] + visible = False + group = 1 + end + object filenames: tbooleanedit + Tag = 9 + optionswidget1 = [] + optionsskin = [osk_framebuttononly] + taborder = 6 + bounds_x = 296 + bounds_y = 0 + bounds_cx = 17 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate, oe1_checkvalueafterstatread] + visible = False + group = 1 + end + object statoverride: tbooleanedit + Tag = 10 + optionswidget1 = [] + optionsskin = [osk_framebuttononly] + taborder = 7 + bounds_x = 314 + bounds_y = 0 + bounds_cx = 17 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate, oe1_checkvalueafterstatread] + visible = False + group = 1 + end + object stataddval: tbooleanedit + Tag = 11 + optionswidget1 = [] + optionsskin = [osk_framebuttononly] + taborder = 8 + bounds_x = 332 + bounds_y = 0 + bounds_cx = 17 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate, oe1_checkvalueafterstatread] + visible = False + group = 1 + end + object unquote: tbooleanedit + Tag = 12 + optionswidget1 = [] + optionsskin = [osk_framebuttononly] + taborder = 9 + bounds_x = 350 + bounds_y = 0 + bounds_cx = 17 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate, oe1_checkvalueafterstatread] + visible = False + group = 1 + end + object integer: tbooleanedit + Tag = 13 + optionswidget1 = [] + optionsskin = [osk_framebuttononly] + taborder = 10 + bounds_x = 368 + bounds_y = 0 + bounds_cx = 17 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate, oe1_checkvalueafterstatread] + visible = False + group = 1 + end + object help: tbooleanedit + Tag = 14 + optionswidget1 = [] + optionsskin = [osk_framebuttononly] + taborder = 11 + bounds_x = 386 + bounds_y = 0 + bounds_cx = 17 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate, oe1_checkvalueafterstatread] + visible = False + group = 1 + end + object initvalueed: tmemodialogedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 12 + visible = False + bounds_x = 404 + bounds_y = 0 + bounds_cx = 121 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + reffontheight = 14 + end + object argumented: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + taborder = 13 + visible = False + bounds_x = 526 + bounds_y = 0 + bounds_cx = 72 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + reffontheight = 14 + end + object helped: tmemodialogedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 14 + visible = False + bounds_x = 599 + bounds_y = 0 + bounds_cx = 102 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + reffontheight = 14 + end + object beforeed: tmemodialogedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 15 + visible = False + bounds_x = 702 + bounds_y = 0 + bounds_cx = 73 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + reffontheight = 14 + end + object aftered: tmemodialogedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -1879048187 + imagenr = 17 + end> + frame.button.color = -1879048187 + frame.button.imagenr = 17 + taborder = 16 + visible = False + bounds_x = 776 + bounds_y = 0 + bounds_cx = 73 + bounds_cy = 16 + optionsedit1 = [] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + reffontheight = 14 + end + end + object statfile1: tstatfile + filename = 'sysenvmanagereditor.sta' + options = [sfo_memory] + left = 192 + top = 72 + end +end diff --git a/mseide-msegui/lib/common/designutils/msesysenvmanagereditor.pas b/mseide-msegui/lib/common/designutils/msesysenvmanagereditor.pas new file mode 100644 index 0000000..f9c1ce7 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msesysenvmanagereditor.pas @@ -0,0 +1,146 @@ +{ MSEgui Copyright (c) 2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msesysenvmanagereditor; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,mseforms,msesysenv,msesplitter, + msesimplewidgets,msewidgets,msegraphedits,mseifiglob,msetypes,msedataedits, + mseedit,msegrids,msestrings,msewidgetgrid,msememodialog,msestatfile,mseificomp, + mseificompglob,msescrollbar; + +const + sysenvmanagereditorstatname = 'sysenvmanagereditor.sta'; + +type + tmsesysenvmanagereditorfo = class(tmseform) + la2: tlayouter; + tlayouter2: tlayouter; + ok: tbutton; + cancel: tbutton; + grid: twidgetgrid; + kinded: tenumtypeedit; + nameed: tstringedit; + aliased: tmemodialogedit; + argopt: tbooleanedit; + filenames: tbooleanedit; + statoverride: tbooleanedit; + stataddval: tbooleanedit; + integer: tbooleanedit; + initvalueed: tmemodialogedit; + statfile1: tstatfile; + mandatory: tbooleanedit; + helped: tmemodialogedit; + help: tbooleanedit; + argumented: tstringedit; + beforeed: tmemodialogedit; + aftered: tmemodialogedit; + unquote: tbooleanedit; + procedure kindedinit(const sender: tenumtypeedit); + end; + +function editsysenvmanager(asysenvmanager: tsysenvmanager): modalresultty; + +implementation +uses + msesysenvmanagereditor_mfm,typinfo; + +function editsysenvmanager(asysenvmanager: tsysenvmanager): modalresultty; +var + ar1: sysenvdefarty; + int1: integer; +begin + ar1:= asysenvmanager.defs; + with tmsesysenvmanagereditorfo.create(nil) do begin + grid.rowcount:= length(ar1); + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + kinded[int1]:= ord(kind); + nameed[int1]:= name; + aliased[int1]:= concatstrings(anames,' ','"'); + mandatory.gridvaluebitmask[int1]:= longword(flags); + initvalueed[int1]:= initvalue; + argumented[int1]:= argument; + helped[int1]:= help; + beforeed[int1]:= before; + aftered[int1]:= after; + end; + end; + result:= show(ml_application); + if result = mr_ok then begin + ar1:= nil; //init with zero + setlength(ar1,grid.datarowhigh+1); + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + kind:= argumentkindty(kinded[int1]); + name:= nameed[int1]; + splitstringquoted(aliased[int1],anames); + flags:= argumentflagsty(mandatory.gridvaluebitmask[int1]); + initvalue:= initvalueed[int1]; + argument:= argumented[int1]; + help:= helped[int1]; + before:= beforeed[int1]; + after:= aftered[int1]; + end; + end; + asysenvmanager.defs:= ar1; + end; + end; +end; + +{ +function editsysenvmanager(asysenvmanager: tsysenvmanager): modalresultty; +var + ar1: argumentdefarty; + ar2: stringararty; + int1: integer; + ar3,ar4: stringarty; +begin + try + defstoarguments(asysenvmanager.defs,ar1,ar2); + except + application.handleexception; + end; + with tmsesysenvmanagereditorfo.create(nil) do begin + grid.rowcount:= length(ar1); + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + kinded[int1]:= ord(kind); + nameed[int1]:= name; + aliased[int1]:= concatstrings(ar2[int1]); + envdefined.gridvaluebitmask[int1]:= longword(flags); + initvalueed[int1]:= initvalue; + end; + end; + result:= show(ml_application); + if result = mr_ok then begin + setlength(ar4,5); + setlength(ar3,grid.datarowhigh+1); + for int1:= 0 to high(ar3) do begin + ar4[0]:= getenumname(typeinfo(argumentkindty),kinded[int1]); + ar4[1]:= nameed[int1]; + ar4[2]:= aliased[int1]; + ar4[3]:= settostring(ptypeinfo(typeinfo(argumentflagsty)), + envdefined.gridvaluebitmask[int1],false); + ar4[4]:= initvalueed[int1]; + ar3[int1]:= concatstrings(ar4,',','"'); + end; + asysenvmanager.defs:= string(concatstrings(ar3,lineend)); + end; + end; +end; +} +procedure tmsesysenvmanagereditorfo.kindedinit(const sender: tenumtypeedit); +begin + sender.typeinfopo:= typeinfo(argumentkindty); +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/msesysenvmanagereditor_mfm.pas b/mseide-msegui/lib/common/designutils/msesysenvmanagereditor_mfm.pas new file mode 100644 index 0000000..80e760b --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msesysenvmanagereditor_mfm.pas @@ -0,0 +1,659 @@ +unit msesysenvmanagereditor_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msesysenvmanagereditor; + +const + objdata: record size: integer; data: array[0..12827] of byte end = + (size: 12828; data: ( + 84,80,70,48,25,116,109,115,101,115,121,115,101,110,118,109,97,110,97,103, + 101,114,101,100,105,116,111,114,102,111,24,109,115,101,115,121,115,101,110,118, + 109,97,110,97,103,101,114,101,100,105,116,111,114,102,111,7,118,105,115,105, + 98,108,101,8,8,98,111,117,110,100,115,95,120,2,57,8,98,111,117,110, + 100,115,95,121,3,62,2,9,98,111,117,110,100,115,95,99,120,3,93,3, + 9,98,111,117,110,100,115,95,99,121,3,229,0,26,99,111,110,116,97,105, + 110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,0,27,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,99,111,110,116,97,105,110, + 101,114,46,98,111,117,110,100,115,1,2,0,2,0,3,93,3,3,229,0, + 0,7,111,112,116,105,111,110,115,11,14,102,111,95,102,114,101,101,111,110, + 99,108,111,115,101,13,102,111,95,99,108,111,115,101,111,110,101,115,99,15, + 102,111,95,97,117,116,111,114,101,97,100,115,116,97,116,16,102,111,95,97, + 117,116,111,119,114,105,116,101,115,116,97,116,10,102,111,95,115,97,118,101, + 112,111,115,13,102,111,95,115,97,118,101,122,111,114,100,101,114,12,102,111, + 95,115,97,118,101,115,116,97,116,101,0,8,115,116,97,116,102,105,108,101, + 7,9,115,116,97,116,102,105,108,101,49,7,99,97,112,116,105,111,110,6, + 19,69,100,105,116,32,116,115,121,115,101,110,118,109,97,110,97,103,101,114, + 13,119,105,110,100,111,119,111,112,97,99,105,116,121,5,0,0,0,0,0, + 0,0,128,255,255,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109, + 101,6,8,116,109,115,101,102,111,114,109,0,9,116,108,97,121,111,117,116, + 101,114,3,108,97,50,8,98,111,117,110,100,115,95,120,2,0,8,98,111, + 117,110,100,115,95,121,3,200,0,9,98,111,117,110,100,115,95,99,120,3, + 93,3,9,98,111,117,110,100,115,95,99,121,2,0,7,97,110,99,104,111, + 114,115,11,6,97,110,95,116,111,112,0,12,111,112,116,105,111,110,115,115, + 99,97,108,101,11,11,111,115,99,95,101,120,112,97,110,100,120,11,111,115, + 99,95,115,104,114,105,110,107,120,11,111,115,99,95,101,120,112,97,110,100, + 121,11,111,115,99,95,115,104,114,105,110,107,121,0,13,111,112,116,105,111, + 110,115,108,97,121,111,117,116,11,10,108,97,111,95,97,108,105,103,110,121, + 0,8,100,105,115,116,95,116,111,112,2,4,0,0,9,116,108,97,121,111, + 117,116,101,114,10,116,108,97,121,111,117,116,101,114,50,8,116,97,98,111, + 114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,3,235,2,8,98, + 111,117,110,100,115,95,121,3,200,0,9,98,111,117,110,100,115,95,99,120, + 2,107,9,98,111,117,110,100,115,95,99,121,2,21,7,97,110,99,104,111, + 114,115,11,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116,116, + 111,109,0,12,111,112,116,105,111,110,115,115,99,97,108,101,11,11,111,115, + 99,95,101,120,112,97,110,100,120,11,111,115,99,95,115,104,114,105,110,107, + 120,11,111,115,99,95,101,120,112,97,110,100,121,11,111,115,99,95,115,104, + 114,105,110,107,121,0,13,111,112,116,105,111,110,115,108,97,121,111,117,116, + 11,10,108,97,111,95,112,108,97,99,101,120,0,13,112,108,97,99,101,95, + 109,105,110,100,105,115,116,2,5,13,112,108,97,99,101,95,109,97,120,100, + 105,115,116,2,5,8,100,105,115,116,95,116,111,112,2,3,0,7,116,98, + 117,116,116,111,110,2,111,107,14,111,112,116,105,111,110,115,119,105,100,103, + 101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101, + 105,103,104,116,13,111,119,49,95,97,117,116,111,115,99,97,108,101,13,111, + 119,49,95,97,117,116,111,119,105,100,116,104,0,8,98,111,117,110,100,115, + 95,120,2,0,8,98,111,117,110,100,115,95,121,2,1,9,98,111,117,110, + 100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,20,12, + 98,111,117,110,100,115,95,99,120,109,105,110,2,50,5,115,116,97,116,101, + 11,10,97,115,95,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97, + 108,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,99,97,112, + 116,105,111,110,0,7,99,97,112,116,105,111,110,6,3,38,79,75,11,109, + 111,100,97,108,114,101,115,117,108,116,7,5,109,114,95,111,107,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,7,116,98,117,116, + 116,111,110,6,99,97,110,99,101,108,14,111,112,116,105,111,110,115,119,105, + 100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104, + 104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99,97,108,101, + 13,111,119,49,95,97,117,116,111,119,105,100,116,104,0,8,116,97,98,111, + 114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,55,8,98,111, + 117,110,100,115,95,121,2,1,9,98,111,117,110,100,115,95,99,120,2,52, + 9,98,111,117,110,100,115,95,99,121,2,20,12,98,111,117,110,100,115,95, + 99,120,109,105,110,2,50,5,115,116,97,116,101,11,15,97,115,95,108,111, + 99,97,108,99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6, + 7,38,67,97,110,99,101,108,11,109,111,100,97,108,114,101,115,117,108,116, + 7,9,109,114,95,99,97,110,99,101,108,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,0,0,11,116,119,105,100,103,101,116,103,114, + 105,100,4,103,114,105,100,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111, + 117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,120,3,93,3,9,98,111,117,110,100,115,95, + 99,121,3,194,0,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111, + 112,9,97,110,95,98,111,116,116,111,109,0,11,111,112,116,105,111,110,115, + 103,114,105,100,11,12,111,103,95,99,111,108,115,105,122,105,110,103,12,111, + 103,95,114,111,119,109,111,118,105,110,103,15,111,103,95,107,101,121,114,111, + 119,109,111,118,105,110,103,15,111,103,95,114,111,119,105,110,115,101,114,116, + 105,110,103,14,111,103,95,114,111,119,100,101,108,101,116,105,110,103,19,111, + 103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101,114,15,111, + 103,95,97,117,116,111,102,105,114,115,116,114,111,119,13,111,103,95,97,117, + 116,111,97,112,112,101,110,100,20,111,103,95,99,111,108,99,104,97,110,103, + 101,111,110,116,97,98,107,101,121,10,111,103,95,119,114,97,112,99,111,108, + 12,111,103,95,97,117,116,111,112,111,112,117,112,17,111,103,95,109,111,117, + 115,101,115,99,114,111,108,108,99,111,108,0,13,102,105,120,99,111,108,115, + 46,99,111,117,110,116,2,1,13,102,105,120,99,111,108,115,46,105,116,101, + 109,115,14,1,5,119,105,100,116,104,2,24,7,110,117,109,115,116,101,112, + 2,1,0,0,13,102,105,120,114,111,119,115,46,99,111,117,110,116,2,1, + 13,102,105,120,114,111,119,115,46,105,116,101,109,115,14,1,6,104,101,105, + 103,104,116,2,16,14,99,97,112,116,105,111,110,115,46,99,111,117,110,116, + 2,16,14,99,97,112,116,105,111,110,115,46,105,116,101,109,115,14,1,7, + 99,97,112,116,105,111,110,6,4,75,105,110,100,0,1,7,99,97,112,116, + 105,111,110,6,4,78,97,109,101,0,1,7,99,97,112,116,105,111,110,6, + 5,65,108,105,97,115,0,1,7,99,97,112,116,105,111,110,6,2,77,65, + 4,104,105,110,116,6,13,97,114,102,95,109,97,110,100,97,116,111,114,121, + 0,1,7,99,97,112,116,105,111,110,6,2,65,79,4,104,105,110,116,6, + 10,97,114,102,95,97,114,103,111,112,116,0,1,7,99,97,112,116,105,111, + 110,6,2,70,78,4,104,105,110,116,6,13,97,114,102,95,102,105,108,101, + 110,97,109,101,115,0,1,7,99,97,112,116,105,111,110,6,2,83,79,4, + 104,105,110,116,6,16,97,114,102,95,115,116,97,116,111,118,101,114,114,105, + 100,101,0,1,7,99,97,112,116,105,111,110,6,2,83,65,4,104,105,110, + 116,6,13,97,114,102,95,115,116,97,116,97,100,118,97,108,0,1,7,99, + 97,112,116,105,111,110,6,2,85,81,4,104,105,110,116,6,11,97,114,102, + 95,117,110,113,117,111,116,101,0,1,7,99,97,112,116,105,111,110,6,2, + 73,78,4,104,105,110,116,6,11,97,114,102,95,105,110,116,101,103,101,114, + 0,1,7,99,97,112,116,105,111,110,6,2,72,69,4,104,105,110,116,6, + 8,97,114,102,95,104,101,108,112,0,1,7,99,97,112,116,105,111,110,6, + 9,73,110,105,116,118,97,108,117,101,0,1,7,99,97,112,116,105,111,110, + 6,8,65,114,103,117,109,101,110,116,0,1,7,99,97,112,116,105,111,110, + 6,4,72,101,108,112,0,1,7,99,97,112,116,105,111,110,6,6,66,101, + 102,111,114,101,0,1,7,99,97,112,116,105,111,110,6,5,65,102,116,101, + 114,0,0,0,0,14,100,97,116,97,99,111,108,115,46,99,111,117,110,116, + 2,16,16,100,97,116,97,99,111,108,115,46,111,112,116,105,111,110,115,11, + 14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109, + 111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108, + 101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99, + 111,95,114,111,119,115,101,108,101,99,116,15,99,111,95,112,114,111,112,111, + 114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,115,116,97,116,101, + 10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97, + 115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111, + 119,0,14,100,97,116,97,99,111,108,115,46,105,116,101,109,115,14,7,6, + 107,105,110,100,101,100,1,5,119,105,100,116,104,2,72,7,111,112,116,105, + 111,110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14, + 99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101, + 121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101, + 99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,15,99,111,95,112, + 114,111,112,111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,115, + 116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99, + 97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111, + 108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,6,107, + 105,110,100,101,100,9,100,97,116,97,99,108,97,115,115,7,17,116,103,114, + 105,100,101,110,117,109,100,97,116,97,108,105,115,116,0,7,6,110,97,109, + 101,101,100,1,5,119,105,100,116,104,2,68,7,111,112,116,105,111,110,115, + 11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95, + 109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101, + 108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12, + 99,111,95,114,111,119,115,101,108,101,99,116,15,99,111,95,112,114,111,112, + 111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,115,116,97,116, + 101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112, + 97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114, + 111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,6,110,97,109,101, + 101,100,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109, + 115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,7,97, + 108,105,97,115,101,100,1,5,119,105,100,116,104,2,117,7,111,112,116,105, + 111,110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14, + 99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101, + 121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101, + 99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,15,99,111,95,112, + 114,111,112,111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,115, + 116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99, + 97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111, + 108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,7,97, + 108,105,97,115,101,100,9,100,97,116,97,99,108,97,115,115,7,22,116,103, + 114,105,100,109,115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116, + 0,7,9,109,97,110,100,97,116,111,114,121,1,5,119,105,100,116,104,2, + 17,7,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102,111, + 99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99, + 111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121, + 115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99, + 116,12,99,111,95,114,111,119,115,101,108,101,99,116,11,99,111,95,102,105, + 120,119,105,100,116,104,12,99,111,95,115,97,118,101,115,116,97,116,101,10, + 99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115, + 116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119, + 0,10,119,105,100,103,101,116,110,97,109,101,6,9,109,97,110,100,97,116, + 111,114,121,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100, + 105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,6,97,114, + 103,111,112,116,1,5,119,105,100,116,104,2,17,7,111,112,116,105,111,110, + 115,11,12,99,111,95,100,114,97,119,102,111,99,117,115,14,99,111,95,102, + 111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115, + 101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99, + 111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119, + 115,101,108,101,99,116,11,99,111,95,102,105,120,119,105,100,116,104,12,99, + 111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111, + 112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111, + 117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116, + 110,97,109,101,6,6,97,114,103,111,112,116,9,100,97,116,97,99,108,97, + 115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97, + 108,105,115,116,0,7,9,102,105,108,101,110,97,109,101,115,1,5,119,105, + 100,116,104,2,17,7,111,112,116,105,111,110,115,11,12,99,111,95,100,114, + 97,119,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101, + 99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111, + 95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115, + 101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,11,99, + 111,95,102,105,120,119,105,100,116,104,12,99,111,95,115,97,118,101,115,116, + 97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97, + 110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108, + 108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,9,102,105, + 108,101,110,97,109,101,115,9,100,97,116,97,99,108,97,115,115,7,20,116, + 103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0, + 7,12,115,116,97,116,111,118,101,114,114,105,100,101,1,5,119,105,100,116, + 104,2,17,7,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119, + 102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116, + 14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107, + 101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108, + 101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,11,99,111,95, + 102,105,120,119,105,100,116,104,12,99,111,95,115,97,118,101,115,116,97,116, + 101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112, + 97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114, + 111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,12,115,116,97,116, + 111,118,101,114,114,105,100,101,9,100,97,116,97,99,108,97,115,115,7,20, + 116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116, + 0,7,10,115,116,97,116,97,100,100,118,97,108,1,5,119,105,100,116,104, + 2,17,7,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119,102, + 111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14, + 99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101, + 121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101, + 99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,11,99,111,95,102, + 105,120,119,105,100,116,104,12,99,111,95,115,97,118,101,115,116,97,116,101, + 10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97, + 115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111, + 119,0,10,119,105,100,103,101,116,110,97,109,101,6,10,115,116,97,116,97, + 100,100,118,97,108,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114, + 105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,7, + 117,110,113,117,111,116,101,1,5,119,105,100,116,104,2,17,7,111,112,116, + 105,111,110,115,11,12,99,111,95,100,114,97,119,102,111,99,117,115,14,99, + 111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117, + 115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99, + 116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95, + 114,111,119,115,101,108,101,99,116,11,99,111,95,102,105,120,119,105,100,116, + 104,15,99,111,95,112,114,111,112,111,114,116,105,111,110,97,108,12,99,111, + 95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112, + 121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117, + 115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110, + 97,109,101,6,7,117,110,113,117,111,116,101,9,100,97,116,97,99,108,97, + 115,115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97, + 108,105,115,116,0,7,7,105,110,116,101,103,101,114,1,5,119,105,100,116, + 104,2,17,7,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97,119, + 102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116, + 14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107, + 101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108, + 101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,11,99,111,95, + 102,105,120,119,105,100,116,104,12,99,111,95,115,97,118,101,115,116,97,116, + 101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112, + 97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114, + 111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,7,105,110,116,101, + 103,101,114,9,100,97,116,97,99,108,97,115,115,7,20,116,103,114,105,100, + 105,110,116,101,103,101,114,100,97,116,97,108,105,115,116,0,7,4,104,101, + 108,112,1,5,119,105,100,116,104,2,17,7,111,112,116,105,111,110,115,11, + 12,99,111,95,100,114,97,119,102,111,99,117,115,14,99,111,95,102,111,99, + 117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108, + 101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95, + 109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101, + 108,101,99,116,11,99,111,95,102,105,120,119,105,100,116,104,12,99,111,95, + 115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121, + 11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115, + 101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97, + 109,101,6,4,104,101,108,112,9,100,97,116,97,99,108,97,115,115,7,20, + 116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108,105,115,116, + 0,7,11,105,110,105,116,118,97,108,117,101,101,100,1,5,119,105,100,116, + 104,2,121,7,111,112,116,105,111,110,115,11,14,99,111,95,102,111,99,117, + 115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108,101, + 99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95,109, + 117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108, + 101,99,116,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95, + 99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17, + 99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119, + 105,100,103,101,116,110,97,109,101,6,11,105,110,105,116,118,97,108,117,101, + 101,100,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109, + 115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,10,97, + 114,103,117,109,101,110,116,101,100,1,5,119,105,100,116,104,2,72,7,111, + 112,116,105,111,110,115,11,14,99,111,95,102,111,99,117,115,115,101,108,101, + 99,116,14,99,111,95,109,111,117,115,101,115,101,108,101,99,116,12,99,111, + 95,107,101,121,115,101,108,101,99,116,14,99,111,95,109,117,108,116,105,115, + 101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,15,99, + 111,95,112,114,111,112,111,114,116,105,111,110,97,108,12,99,111,95,115,97, + 118,101,115,116,97,116,101,10,99,111,95,99,97,110,99,111,112,121,11,99, + 111,95,99,97,110,112,97,115,116,101,17,99,111,95,109,111,117,115,101,115, + 99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101, + 6,10,97,114,103,117,109,101,110,116,101,100,9,100,97,116,97,99,108,97, + 115,115,7,22,116,103,114,105,100,109,115,101,115,116,114,105,110,103,100,97, + 116,97,108,105,115,116,0,7,6,104,101,108,112,101,100,1,5,119,105,100, + 116,104,2,102,7,111,112,116,105,111,110,115,11,14,99,111,95,102,111,99, + 117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115,101,115,101,108, + 101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116,14,99,111,95, + 109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101, + 108,101,99,116,15,99,111,95,112,114,111,112,111,114,116,105,111,110,97,108, + 12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111,95,99,97,110, + 99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101,17,99,111,95, + 109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103, + 101,116,110,97,109,101,6,6,104,101,108,112,101,100,9,100,97,116,97,99, + 108,97,115,115,7,22,116,103,114,105,100,109,115,101,115,116,114,105,110,103, + 100,97,116,97,108,105,115,116,0,7,8,98,101,102,111,114,101,101,100,1, + 5,119,105,100,116,104,2,73,7,111,112,116,105,111,110,115,11,14,99,111, + 95,102,111,99,117,115,115,101,108,101,99,116,14,99,111,95,109,111,117,115, + 101,115,101,108,101,99,116,12,99,111,95,107,101,121,115,101,108,101,99,116, + 14,99,111,95,109,117,108,116,105,115,101,108,101,99,116,12,99,111,95,114, + 111,119,115,101,108,101,99,116,15,99,111,95,112,114,111,112,111,114,116,105, + 111,110,97,108,12,99,111,95,115,97,118,101,115,116,97,116,101,10,99,111, + 95,99,97,110,99,111,112,121,11,99,111,95,99,97,110,112,97,115,116,101, + 17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114,111,119,0,10, + 119,105,100,103,101,116,110,97,109,101,6,8,98,101,102,111,114,101,101,100, + 9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101, + 115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,7,97,102,116, + 101,114,101,100,1,5,119,105,100,116,104,2,73,7,111,112,116,105,111,110, + 115,11,14,99,111,95,102,111,99,117,115,115,101,108,101,99,116,14,99,111, + 95,109,111,117,115,101,115,101,108,101,99,116,12,99,111,95,107,101,121,115, + 101,108,101,99,116,14,99,111,95,109,117,108,116,105,115,101,108,101,99,116, + 12,99,111,95,114,111,119,115,101,108,101,99,116,15,99,111,95,112,114,111, + 112,111,114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,115,116,97, + 116,101,10,99,111,95,99,97,110,99,111,112,121,11,99,111,95,99,97,110, + 112,97,115,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108, + 114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,7,97,102,116, + 101,114,101,100,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105, + 100,109,115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,0, + 13,100,97,116,97,114,111,119,104,101,105,103,104,116,2,16,8,115,116,97, + 116,102,105,108,101,7,9,115,116,97,116,102,105,108,101,49,13,114,101,102, + 102,111,110,116,104,101,105,103,104,116,2,14,0,13,116,101,110,117,109,116, + 121,112,101,101,100,105,116,6,107,105,110,100,101,100,11,111,112,116,105,111, + 110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116, + 116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101,118,101,108, + 111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110, + 116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,10,102,114,108,95, + 108,101,118,101,108,105,15,102,114,108,95,99,111,108,111,114,99,108,105,101, + 110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108, + 111,114,4,5,0,0,144,19,102,114,97,109,101,46,98,117,116,116,111,110, + 115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116,116, + 111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4,5,0, + 0,144,0,0,8,116,97,98,111,114,100,101,114,2,1,7,118,105,115,105, + 98,108,101,8,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110, + 100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,72,9,98, + 111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100, + 105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111, + 101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101, + 113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99, + 101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101, + 95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115, + 101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111, + 110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101, + 114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97, + 117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99, + 107,22,111,101,95,102,111,99,117,115,114,101,99,116,111,110,114,101,97,100, + 111,110,108,121,18,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116, + 101,120,116,0,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,99, + 111,117,110,116,2,1,19,100,114,111,112,100,111,119,110,46,99,111,108,115, + 46,105,116,101,109,115,14,1,0,0,6,111,110,105,110,105,116,7,10,107, + 105,110,100,101,100,105,110,105,116,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,14,0,0,11,116,115,116,114,105,110,103,101,100,105,116,6, + 110,97,109,101,101,100,14,111,112,116,105,111,110,115,119,105,100,103,101,116, + 49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103, + 104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107, + 95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97, + 98,111,114,100,101,114,2,2,7,118,105,115,105,98,108,101,8,8,98,111, + 117,110,100,115,95,120,2,73,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,120,2,68,9,98,111,117,110,100,115,95,99, + 121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,0,11,111, + 112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111, + 110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111, + 101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115, + 104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116, + 117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110, + 101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114, + 13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117, + 116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101, + 99,116,111,110,102,105,114,115,116,99,108,105,99,107,22,111,101,95,102,111, + 99,117,115,114,101,99,116,111,110,114,101,97,100,111,110,108,121,18,111,101, + 95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116,0,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,15,116,109,101,109, + 111,100,105,97,108,111,103,101,100,105,116,7,97,108,105,97,115,101,100,14, + 111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95, + 102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,11,111,112,116, + 105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98, + 117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,10,102,114, + 108,95,108,101,118,101,108,105,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46, + 99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116,116,111,110, + 115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4,5,0,0,144, + 7,105,109,97,103,101,110,114,2,17,0,0,18,102,114,97,109,101,46,98, + 117,116,116,111,110,46,99,111,108,111,114,4,5,0,0,144,20,102,114,97, + 109,101,46,98,117,116,116,111,110,46,105,109,97,103,101,110,114,2,17,8, + 116,97,98,111,114,100,101,114,2,3,7,118,105,115,105,98,108,101,8,8, + 98,111,117,110,100,115,95,120,3,142,0,8,98,111,117,110,100,115,95,121, + 2,0,9,98,111,117,110,100,115,95,99,120,2,117,9,98,111,117,110,100, + 115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11, + 0,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110, + 100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114, + 121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111, + 101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116, + 114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99, + 116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114, + 115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101, + 95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115, + 101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,22,111,101, + 95,102,111,99,117,115,114,101,99,116,111,110,114,101,97,100,111,110,108,121, + 18,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116,0, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,12,116, + 98,111,111,108,101,97,110,101,100,105,116,9,109,97,110,100,97,116,111,114, + 121,3,84,97,103,2,7,14,111,112,116,105,111,110,115,119,105,100,103,101, + 116,49,11,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115, + 107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116, + 97,98,111,114,100,101,114,2,4,8,98,111,117,110,100,115,95,120,3,4, + 1,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,2,17,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116, + 105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112, + 111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99, + 117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,27,111,101, + 49,95,99,104,101,99,107,118,97,108,117,101,97,102,116,101,114,115,116,97, + 116,114,101,97,100,0,7,118,105,115,105,98,108,101,8,5,103,114,111,117, + 112,2,1,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,6,97, + 114,103,111,112,116,3,84,97,103,2,8,14,111,112,116,105,111,110,115,119, + 105,100,103,101,116,49,11,0,11,111,112,116,105,111,110,115,115,107,105,110, + 11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108, + 121,0,8,116,97,98,111,114,100,101,114,2,5,8,98,111,117,110,100,115, + 95,120,3,22,1,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,120,2,17,9,98,111,117,110,100,115,95,99,121,2,16, + 12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97, + 117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121, + 101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116, + 101,27,111,101,49,95,99,104,101,99,107,118,97,108,117,101,97,102,116,101, + 114,115,116,97,116,114,101,97,100,0,7,118,105,115,105,98,108,101,8,5, + 103,114,111,117,112,2,1,0,0,12,116,98,111,111,108,101,97,110,101,100, + 105,116,9,102,105,108,101,110,97,109,101,115,3,84,97,103,2,9,14,111, + 112,116,105,111,110,115,119,105,100,103,101,116,49,11,0,11,111,112,116,105, + 111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117, + 116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,6, + 8,98,111,117,110,100,115,95,120,3,40,1,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,120,2,17,9,98,111,117,110, + 100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49, + 11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14, + 111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115, + 97,118,101,115,116,97,116,101,27,111,101,49,95,99,104,101,99,107,118,97, + 108,117,101,97,102,116,101,114,115,116,97,116,114,101,97,100,0,7,118,105, + 115,105,98,108,101,8,5,103,114,111,117,112,2,1,0,0,12,116,98,111, + 111,108,101,97,110,101,100,105,116,12,115,116,97,116,111,118,101,114,114,105, + 100,101,3,84,97,103,2,10,14,111,112,116,105,111,110,115,119,105,100,103, + 101,116,49,11,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111, + 115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8, + 116,97,98,111,114,100,101,114,2,7,8,98,111,117,110,100,115,95,120,3, + 58,1,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,2,17,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112, + 116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111, + 112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101, + 99,117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,27,111, + 101,49,95,99,104,101,99,107,118,97,108,117,101,97,102,116,101,114,115,116, + 97,116,114,101,97,100,0,7,118,105,115,105,98,108,101,8,5,103,114,111, + 117,112,2,1,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,10, + 115,116,97,116,97,100,100,118,97,108,3,84,97,103,2,11,14,111,112,116, + 105,111,110,115,119,105,100,103,101,116,49,11,0,11,111,112,116,105,111,110, + 115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116, + 111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,8,8,98, + 111,117,110,100,115,95,120,3,76,1,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,2,17,9,98,111,117,110,100,115, + 95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17, + 111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101, + 49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118, + 101,115,116,97,116,101,27,111,101,49,95,99,104,101,99,107,118,97,108,117, + 101,97,102,116,101,114,115,116,97,116,114,101,97,100,0,7,118,105,115,105, + 98,108,101,8,5,103,114,111,117,112,2,1,0,0,12,116,98,111,111,108, + 101,97,110,101,100,105,116,7,117,110,113,117,111,116,101,3,84,97,103,2, + 12,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,0,11,111, + 112,116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109, + 101,98,117,116,116,111,110,111,110,108,121,0,8,116,97,98,111,114,100,101, + 114,2,9,8,98,111,117,110,100,115,95,120,3,94,1,8,98,111,117,110, + 100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,17,9,98, + 111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100, + 105,116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101, + 110,117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101, + 49,95,115,97,118,101,115,116,97,116,101,27,111,101,49,95,99,104,101,99, + 107,118,97,108,117,101,97,102,116,101,114,115,116,97,116,114,101,97,100,0, + 7,118,105,115,105,98,108,101,8,5,103,114,111,117,112,2,1,0,0,12, + 116,98,111,111,108,101,97,110,101,100,105,116,7,105,110,116,101,103,101,114, + 3,84,97,103,2,13,14,111,112,116,105,111,110,115,119,105,100,103,101,116, + 49,11,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111,115,107, + 95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8,116,97, + 98,111,114,100,101,114,2,10,8,98,111,117,110,100,115,95,120,3,112,1, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,2,17,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105, + 111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112,111, + 112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99,117, + 116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,27,111,101,49, + 95,99,104,101,99,107,118,97,108,117,101,97,102,116,101,114,115,116,97,116, + 114,101,97,100,0,7,118,105,115,105,98,108,101,8,5,103,114,111,117,112, + 2,1,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,4,104,101, + 108,112,3,84,97,103,2,14,14,111,112,116,105,111,110,115,119,105,100,103, + 101,116,49,11,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111, + 115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,8, + 116,97,98,111,114,100,101,114,2,11,8,98,111,117,110,100,115,95,120,3, + 130,1,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,2,17,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112, + 116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111, + 112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101, + 99,117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,27,111, + 101,49,95,99,104,101,99,107,118,97,108,117,101,97,102,116,101,114,115,116, + 97,116,114,101,97,100,0,7,118,105,115,105,98,108,101,8,5,103,114,111, + 117,112,2,1,0,0,15,116,109,101,109,111,100,105,97,108,111,103,101,100, + 105,116,11,105,110,105,116,118,97,108,117,101,101,100,14,111,112,116,105,111, + 110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103, + 108,121,112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110,115,115, + 107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110, + 111,110,108,121,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0, + 17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,3, + 0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,10,102,114,108,95,108,101,118,101,108,111,10,102,114,108,95,108,101,118, + 101,108,105,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116, + 2,1,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101, + 109,115,14,1,5,99,111,108,111,114,4,5,0,0,144,7,105,109,97,103, + 101,110,114,2,17,0,0,18,102,114,97,109,101,46,98,117,116,116,111,110, + 46,99,111,108,111,114,4,5,0,0,144,20,102,114,97,109,101,46,98,117, + 116,116,111,110,46,105,109,97,103,101,110,114,2,17,8,116,97,98,111,114, + 100,101,114,2,12,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100, + 115,95,120,3,148,1,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,120,2,121,9,98,111,117,110,100,115,95,99,121,2, + 16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,0,11,111,112,116, + 105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101, + 115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95, + 99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105, + 102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114, + 110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120, + 105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111, + 101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111, + 115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116, + 111,110,102,105,114,115,116,99,108,105,99,107,22,111,101,95,102,111,99,117, + 115,114,101,99,116,111,110,114,101,97,100,111,110,108,121,18,111,101,95,104, + 105,110,116,99,108,105,112,112,101,100,116,101,120,116,0,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,11,116,115,116,114,105,110, + 103,101,100,105,116,10,97,114,103,117,109,101,110,116,101,100,14,111,112,116, + 105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110, + 116,103,108,121,112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110, + 115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116, + 111,110,111,110,108,121,0,8,116,97,98,111,114,100,101,114,2,13,7,118, + 105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,14,2,8, + 98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120, + 2,72,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111, + 110,115,101,100,105,116,49,11,0,11,111,112,116,105,111,110,115,101,100,105, + 116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99, + 108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114, + 99,97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114, + 110,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101, + 115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101, + 120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110, + 101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25, + 111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116, + 99,108,105,99,107,22,111,101,95,102,111,99,117,115,114,101,99,116,111,110, + 114,101,97,100,111,110,108,121,18,111,101,95,104,105,110,116,99,108,105,112, + 112,101,100,116,101,120,116,0,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,14,0,0,15,116,109,101,109,111,100,105,97,108,111,103,101,100, + 105,116,6,104,101,108,112,101,100,14,111,112,116,105,111,110,115,119,105,100, + 103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104, + 101,105,103,104,116,0,11,111,112,116,105,111,110,115,115,107,105,110,11,19, + 111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0, + 12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109, + 101,46,99,111,108,111,114,99,108,105,101,110,116,4,3,0,0,128,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108, + 95,108,101,118,101,108,111,10,102,114,108,95,108,101,118,101,108,105,15,102, + 114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,19,102,114,97,109, + 101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1,19,102,114, + 97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,5, + 99,111,108,111,114,4,5,0,0,144,7,105,109,97,103,101,110,114,2,17, + 0,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111, + 114,4,5,0,0,144,20,102,114,97,109,101,46,98,117,116,116,111,110,46, + 105,109,97,103,101,110,114,2,17,8,116,97,98,111,114,100,101,114,2,14, + 7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,87, + 2,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,2,102,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116, + 105,111,110,115,101,100,105,116,49,11,0,11,111,112,116,105,111,110,115,101, + 100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101, + 95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107, + 109,114,99,97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116, + 117,114,110,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95, + 114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101, + 95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100, + 111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99, + 116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114, + 115,116,99,108,105,99,107,22,111,101,95,102,111,99,117,115,114,101,99,116, + 111,110,114,101,97,100,111,110,108,121,18,111,101,95,104,105,110,116,99,108, + 105,112,112,101,100,116,101,120,116,0,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,14,0,0,15,116,109,101,109,111,100,105,97,108,111,103, + 101,100,105,116,8,98,101,102,111,114,101,101,100,14,111,112,116,105,111,110, + 115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108, + 121,112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110,115,115,107, + 105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111, + 110,108,121,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,17, + 102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,3,0, + 0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 10,102,114,108,95,108,101,118,101,108,111,10,102,114,108,95,108,101,118,101, + 108,105,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,19, + 102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2, + 1,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109, + 115,14,1,5,99,111,108,111,114,4,5,0,0,144,7,105,109,97,103,101, + 110,114,2,17,0,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46, + 99,111,108,111,114,4,5,0,0,144,20,102,114,97,109,101,46,98,117,116, + 116,111,110,46,105,109,97,103,101,110,114,2,17,8,116,97,98,111,114,100, + 101,114,2,15,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115, + 95,120,3,190,2,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,120,2,73,9,98,111,117,110,100,115,95,99,121,2,16, + 12,111,112,116,105,111,110,115,101,100,105,116,49,11,0,11,111,112,116,105, + 111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115, + 99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99, + 104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105,102, + 116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114,110, + 20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105, + 116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101, + 95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115, + 101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111, + 110,102,105,114,115,116,99,108,105,99,107,22,111,101,95,102,111,99,117,115, + 114,101,99,116,111,110,114,101,97,100,111,110,108,121,18,111,101,95,104,105, + 110,116,99,108,105,112,112,101,100,116,101,120,116,0,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,14,0,0,15,116,109,101,109,111,100,105, + 97,108,111,103,101,100,105,116,7,97,102,116,101,114,101,100,14,111,112,116, + 105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110, + 116,103,108,121,112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110, + 115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116, + 111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101,118,101,108,111, + 2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116, + 4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,10,102,114,108,95,108, + 101,118,101,108,105,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117, + 110,116,2,1,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105, + 116,101,109,115,14,1,5,99,111,108,111,114,4,5,0,0,144,7,105,109, + 97,103,101,110,114,2,17,0,0,18,102,114,97,109,101,46,98,117,116,116, + 111,110,46,99,111,108,111,114,4,5,0,0,144,20,102,114,97,109,101,46, + 98,117,116,116,111,110,46,105,109,97,103,101,110,114,2,17,8,116,97,98, + 111,114,100,101,114,2,16,7,118,105,115,105,98,108,101,8,8,98,111,117, + 110,100,115,95,120,3,8,3,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,120,2,73,9,98,111,117,110,100,115,95,99, + 121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,0,11,111, + 112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111, + 110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111, + 101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115, + 104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116, + 117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110, + 101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114, + 13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117, + 116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101, + 99,116,111,110,102,105,114,115,116,99,108,105,99,107,22,111,101,95,102,111, + 99,117,115,114,101,99,116,111,110,114,101,97,100,111,110,108,121,18,111,101, + 95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116,0,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,9,116,115,116, + 97,116,102,105,108,101,9,115,116,97,116,102,105,108,101,49,8,102,105,108, + 101,110,97,109,101,6,23,115,121,115,101,110,118,109,97,110,97,103,101,114, + 101,100,105,116,111,114,46,115,116,97,7,111,112,116,105,111,110,115,11,10, + 115,102,111,95,109,101,109,111,114,121,0,4,108,101,102,116,3,192,0,3, + 116,111,112,2,72,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tmsesysenvmanagereditorfo,''); +end. diff --git a/mseide-msegui/lib/common/designutils/msetaborderoverrideeditor.mfm b/mseide-msegui/lib/common/designutils/msetaborderoverrideeditor.mfm new file mode 100644 index 0000000..296184b --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msetaborderoverrideeditor.mfm @@ -0,0 +1,194 @@ +object msetaborderoverrideeditorfo: tmsetaborderoverrideeditorfo + visible = False + bounds_x = 337 + bounds_y = 266 + bounds_cx = 332 + bounds_cy = 245 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 332 + 245 + ) + options = [fo_freeonclose, fo_cancelonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder, fo_savestate] + statfile = tstatfile1 + caption = 'Taborder override' + moduleclassname = 'tmseform' + object tsplitter1: tsplitter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + color = -2147483645 + bounds_x = 208 + bounds_y = 208 + bounds_cx = 123 + bounds_cy = 30 + anchors = [an_right, an_bottom] + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + linktop = texpandingwidget1 + grip = stb_none + object tbutton2: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + taborder = 1 + bounds_x = 58 + bounds_y = 8 + bounds_cx = 52 + bounds_cy = 22 + bounds_cxmin = 50 + anchors = [an_top, an_right] + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + reffontheight = 14 + end + object tbutton1: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + bounds_x = 0 + bounds_y = 8 + bounds_cx = 50 + bounds_cy = 22 + bounds_cxmin = 50 + anchors = [an_top, an_right] + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + reffontheight = 14 + end + object tspacer2: tspacer + taborder = 2 + bounds_x = 50 + bounds_y = 8 + bounds_cx = 8 + bounds_cy = 20 + linkleft = tbutton1 + linkright = tbutton2 + options = [spao_glueright] + end + end + object texpandingwidget1: texpandingwidget + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 332 + bounds_cy = 208 + anchors = [an_top] + optionsscale = [osc_expandy, osc_expandshrinkx, osc_expandshrinky] + object grid: twidgetgrid + frame.localprops = [] + frame.localprops1 = [] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 332 + bounds_cy = 208 + anchors = [] + optionsgrid = [og_colsizing, og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixcols.count = 1 + fixcols.items = < + item + width = 27 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 2 + captions.items = < + item + caption = 'a' + end + item + caption = 'b' + end> + end> + datacols.count = 2 + datacols.options = [co_proportional, co_savevalue, co_savestate, co_mousescrollrow] + datacols.items = < + item[aed] + width = 144 + options = [co_proportional, co_savestate, co_mousescrollrow] + widgetname = 'aed' + dataclass = tgridmsestringdatalist + end + item[bed] + width = 154 + options = [co_fill, co_savestate, co_mousescrollrow] + widgetname = 'bed' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + statfile = tstatfile1 + reffontheight = 14 + object aed: tdropdownlistedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.button.color = -1879048187 + frame.buttons.count = 2 + frame.buttons.items = < + item + color = -1879048187 + end + item + imagenr = 17 + onexecute = dialogexev + end> + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 144 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate, oe1_checkvalueafterstatread] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + dropdown.options = [deo_selectonly, deo_autodropdown, deo_keydropdown, deo_cliphint] + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + reffontheight = 14 + end + object bed: tdropdownlistedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + frame.button.color = -1879048187 + frame.buttons.count = 2 + frame.buttons.items = < + item + color = -1879048187 + end + item + imagenr = 17 + onexecute = dialogexev + end> + taborder = 2 + visible = False + bounds_x = 145 + bounds_y = 0 + bounds_cx = 154 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate, oe1_checkvalueafterstatread] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + dropdown.options = [deo_selectonly, deo_autodropdown, deo_keydropdown, deo_cliphint] + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + reffontheight = 14 + end + end + end + object tstatfile1: tstatfile + filename = 'taborderoverrideeditor.sta' + options = [sfo_memory] + left = 16 + top = 216 + end +end diff --git a/mseide-msegui/lib/common/designutils/msetaborderoverrideeditor.pas b/mseide-msegui/lib/common/designutils/msetaborderoverrideeditor.pas new file mode 100644 index 0000000..9ee9279 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msetaborderoverrideeditor.pas @@ -0,0 +1,171 @@ +unit msetaborderoverrideeditor; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,msewidgets,mseforms,msestatfile, + msesplitter,msesimplewidgets,mseact,msedataedits,msedropdownlist,mseedit, + msegrids,mseificomp,mseificompglob,mseifiglob,msestream,msewidgetgrid,sysutils, + classes,mclasses,msestrings; +type + tmsetaborderoverrideeditorfo = class(tmseform) + tstatfile1: tstatfile; + tsplitter1: tsplitter; + tbutton2: tbutton; + tbutton1: tbutton; + tspacer2: tspacer; + texpandingwidget1: texpandingwidget; + grid: twidgetgrid; + aed: tdropdownlistedit; + bed: tdropdownlistedit; + procedure dialogexev(const sender: TObject); + private + frootcomp: tcomponent; + ftopwidget: twidget; + function filterwidgets(const acomponent: tcomponent): boolean; + public + constructor create(const atopwidget: twidget); reintroduce; + function findcomp(const aname: msestring): twidget; + function findwidgetcomp(const aname: msestring): twidget; + function widgetnamepath(awidget: twidget): string; + function compnamepath(acomp: tcomponent): string; + end; + +implementation +uses + msetaborderoverrideeditor_mfm,msedesigner,msecomptree; + +constructor tmsetaborderoverrideeditorfo.create( + const atopwidget: twidget); +var + ar1: msestringarty; +begin + inherited create(nil); + ftopwidget:= atopwidget; + if csinline in atopwidget.componentstate then begin + frootcomp:= atopwidget; + end + else begin + frootcomp:= atopwidget.owner; + if frootcomp = nil then begin + frootcomp:= atopwidget; + end; + end; + ar1:= designer.getwidgetnamelist(nil,ftopwidget,@filterwidgets); + aed.dropdown.cols[0].asarray:= ar1; + bed.dropdown.cols[0].asarray:= ar1; +end; + +function tmsetaborderoverrideeditorfo.findcomp(const aname: msestring): twidget; +var + str1: ansistring; + ar1: stringarty; + i1: int32; + comp1: tcomponent; + w1: twidget; +begin + str1:= ansistring(aname); + ar1:= splitstring(str1,'.'); + comp1:= frootcomp; + w1:= nil; + for i1:= 0 to high(ar1) do begin + w1:= twidget(comp1.findcomponent(ar1[i1])); + if not (w1 is twidget) then begin + w1:= nil; + break; + end; + comp1:= w1; + end; + result:= w1; +end; + +function tmsetaborderoverrideeditorfo.findwidgetcomp( + const aname: msestring): twidget; +var + str1: ansistring; + ar1: stringarty; + i1: int32; + comp1: tcomponent; + w1: twidget; +begin + str1:= ansistring(aname); + ar1:= splitstring(str1,'.'); + comp1:= frootcomp; + w1:= nil; + for i1:= 0 to high(ar1) do begin + w1:= twidget(comp1.findcomponent(ar1[i1])); + if not (w1 is twidget) then begin + w1:= nil; + break; + end; + if csinline in w1.componentstate then begin + comp1:= w1; + end; + end; + result:= w1; +end; + +function tmsetaborderoverrideeditorfo.widgetnamepath(awidget: twidget): string; +begin + result:= ''; + if awidget <> nil then begin + result:= awidget.name; + awidget:= awidget.parentwidget; + while (awidget <> nil) and (awidget <> ftopwidget) do begin + if ws_iswidget in awidget.widgetstate then begin + result:= awidget.name+'.'+result; + end; + awidget:= awidget.parentwidget; + end; + end; +end; + +function tmsetaborderoverrideeditorfo.compnamepath(acomp: tcomponent): string; +begin + result:= ''; + if acomp <> nil then begin + result:= acomp.name; + acomp:= acomp.owner; + while (acomp <> nil) and (acomp <> frootcomp) do begin + result:= acomp.name+'.'+result; + acomp:= acomp.owner; + end; + end; +end; + +function tmsetaborderoverrideeditorfo.filterwidgets( + const acomponent: tcomponent): boolean; +begin + result:= ws_iswidget in twidget(acomponent).widgetstate; +end; + +procedure tmsetaborderoverrideeditorfo.dialogexev(const sender: TObject); +var + w1: tdropdownlistedit; + w2: twidget; + tree1: tcompnameitem; + mstr1: msestring; +begin +// if ftopcomponent is twidget then begin + tree1:= designer.getwidgetnametree(ftopwidget); + w1:= tdropdownlistedit(tcustomframe( + tframebutton(sender).owner).intf.getwidget); + w2:= findcomp(w1.value); + if w2 <> nil then begin + mstr1:= msestring(widgetnamepath(w2)); + end + else begin + mstr1:= w1.value; + end; + if compnamedialog(tree1,mstr1,false) = mr_ok then begin + replacechar1(mstr1,':','.'); + w2:= findwidgetcomp(mstr1); + if w2 <> nil then begin + mstr1:= msestring(compnamepath(w2)); + end; + w1.value:= mstr1; + end; +// end; +end; + +end. diff --git a/mseide-msegui/lib/common/designutils/msetaborderoverrideeditor_mfm.pas b/mseide-msegui/lib/common/designutils/msetaborderoverrideeditor_mfm.pas new file mode 100644 index 0000000..27bfc8c --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msetaborderoverrideeditor_mfm.pas @@ -0,0 +1,229 @@ +unit msetaborderoverrideeditor_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msetaborderoverrideeditor; + +const + objdata: record size: integer; data: array[0..4238] of byte end = + (size: 4239; data: ( + 84,80,70,48,28,116,109,115,101,116,97,98,111,114,100,101,114,111,118,101, + 114,114,105,100,101,101,100,105,116,111,114,102,111,27,109,115,101,116,97,98, + 111,114,100,101,114,111,118,101,114,114,105,100,101,101,100,105,116,111,114,102, + 111,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3, + 81,1,8,98,111,117,110,100,115,95,121,3,10,1,9,98,111,117,110,100, + 115,95,99,120,3,76,1,9,98,111,117,110,100,115,95,99,121,3,245,0, + 26,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,0,27,99,111,110,116,97,105,110,101,114,46, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16, + 99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2,0,2, + 0,3,76,1,3,245,0,0,7,111,112,116,105,111,110,115,11,14,102,111, + 95,102,114,101,101,111,110,99,108,111,115,101,14,102,111,95,99,97,110,99, + 101,108,111,110,101,115,99,15,102,111,95,97,117,116,111,114,101,97,100,115, + 116,97,116,16,102,111,95,97,117,116,111,119,114,105,116,101,115,116,97,116, + 10,102,111,95,115,97,118,101,112,111,115,13,102,111,95,115,97,118,101,122, + 111,114,100,101,114,12,102,111,95,115,97,118,101,115,116,97,116,101,0,8, + 115,116,97,116,102,105,108,101,7,10,116,115,116,97,116,102,105,108,101,49, + 7,99,97,112,116,105,111,110,6,17,84,97,98,111,114,100,101,114,32,111, + 118,101,114,114,105,100,101,15,109,111,100,117,108,101,99,108,97,115,115,110, + 97,109,101,6,8,116,109,115,101,102,111,114,109,0,9,116,115,112,108,105, + 116,116,101,114,10,116,115,112,108,105,116,116,101,114,49,13,111,112,116,105, + 111,110,115,119,105,100,103,101,116,11,11,111,119,95,116,97,98,102,111,99, + 117,115,17,111,119,95,112,97,114,101,110,116,116,97,98,102,111,99,117,115, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114, + 114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102, + 111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111,99,117,115,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,5,99, + 111,108,111,114,4,3,0,0,128,8,98,111,117,110,100,115,95,120,3,208, + 0,8,98,111,117,110,100,115,95,121,3,208,0,9,98,111,117,110,100,115, + 95,99,120,2,123,9,98,111,117,110,100,115,95,99,121,2,30,7,97,110, + 99,104,111,114,115,11,8,97,110,95,114,105,103,104,116,9,97,110,95,98, + 111,116,116,111,109,0,12,111,112,116,105,111,110,115,115,99,97,108,101,11, + 11,111,115,99,95,101,120,112,97,110,100,120,11,111,115,99,95,115,104,114, + 105,110,107,120,11,111,115,99,95,101,120,112,97,110,100,121,11,111,115,99, + 95,115,104,114,105,110,107,121,0,7,108,105,110,107,116,111,112,7,17,116, + 101,120,112,97,110,100,105,110,103,119,105,100,103,101,116,49,4,103,114,105, + 112,7,8,115,116,98,95,110,111,110,101,0,7,116,98,117,116,116,111,110, + 8,116,98,117,116,116,111,110,50,14,111,112,116,105,111,110,115,119,105,100, + 103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104, + 101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99,97,108,101,13, + 111,119,49,95,97,117,116,111,119,105,100,116,104,0,8,116,97,98,111,114, + 100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,58,8,98,111,117, + 110,100,115,95,121,2,8,9,98,111,117,110,100,115,95,99,120,2,52,9, + 98,111,117,110,100,115,95,99,121,2,22,12,98,111,117,110,100,115,95,99, + 120,109,105,110,2,50,7,97,110,99,104,111,114,115,11,6,97,110,95,116, + 111,112,8,97,110,95,114,105,103,104,116,0,5,115,116,97,116,101,11,15, + 97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,7,99,97,112, + 116,105,111,110,6,7,38,67,97,110,99,101,108,11,109,111,100,97,108,114, + 101,115,117,108,116,7,9,109,114,95,99,97,110,99,101,108,13,114,101,102, + 102,111,110,116,104,101,105,103,104,116,2,14,0,0,7,116,98,117,116,116, + 111,110,8,116,98,117,116,116,111,110,49,14,111,112,116,105,111,110,115,119, + 105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112, + 104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99,97,108, + 101,13,111,119,49,95,97,117,116,111,119,105,100,116,104,0,8,98,111,117, + 110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,8,9,98, + 111,117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121, + 2,22,12,98,111,117,110,100,115,95,99,120,109,105,110,2,50,7,97,110, + 99,104,111,114,115,11,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,0,5,115,116,97,116,101,11,10,97,115,95,100,101,102,97,117,108, + 116,15,97,115,95,108,111,99,97,108,100,101,102,97,117,108,116,15,97,115, + 95,108,111,99,97,108,99,97,112,116,105,111,110,0,7,99,97,112,116,105, + 111,110,6,3,38,79,75,11,109,111,100,97,108,114,101,115,117,108,116,7, + 5,109,114,95,111,107,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,7,116,115,112,97,99,101,114,8,116,115,112,97,99,101,114, + 50,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95, + 120,2,50,8,98,111,117,110,100,115,95,121,2,8,9,98,111,117,110,100, + 115,95,99,120,2,8,9,98,111,117,110,100,115,95,99,121,2,20,8,108, + 105,110,107,108,101,102,116,7,8,116,98,117,116,116,111,110,49,9,108,105, + 110,107,114,105,103,104,116,7,8,116,98,117,116,116,111,110,50,7,111,112, + 116,105,111,110,115,11,14,115,112,97,111,95,103,108,117,101,114,105,103,104, + 116,0,0,0,0,16,116,101,120,112,97,110,100,105,110,103,119,105,100,103, + 101,116,17,116,101,120,112,97,110,100,105,110,103,119,105,100,103,101,116,49, + 8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,3,76,1,9,98,111,117,110,100,115,95,99,121,3,208,0,7, + 97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,0,12,111,112,116, + 105,111,110,115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97,110, + 100,121,17,111,115,99,95,101,120,112,97,110,100,115,104,114,105,110,107,120, + 17,111,115,99,95,101,120,112,97,110,100,115,104,114,105,110,107,121,0,0, + 11,116,119,105,100,103,101,116,103,114,105,100,4,103,114,105,100,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,98,111,117, + 110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,120,3,76,1,9,98,111,117,110,100,115,95,99, + 121,3,208,0,7,97,110,99,104,111,114,115,11,0,11,111,112,116,105,111, + 110,115,103,114,105,100,11,12,111,103,95,99,111,108,115,105,122,105,110,103, + 12,111,103,95,114,111,119,109,111,118,105,110,103,15,111,103,95,107,101,121, + 114,111,119,109,111,118,105,110,103,15,111,103,95,114,111,119,105,110,115,101, + 114,116,105,110,103,14,111,103,95,114,111,119,100,101,108,101,116,105,110,103, + 19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101,114, + 15,111,103,95,97,117,116,111,102,105,114,115,116,114,111,119,13,111,103,95, + 97,117,116,111,97,112,112,101,110,100,20,111,103,95,99,111,108,99,104,97, + 110,103,101,111,110,116,97,98,107,101,121,10,111,103,95,119,114,97,112,99, + 111,108,12,111,103,95,97,117,116,111,112,111,112,117,112,17,111,103,95,109, + 111,117,115,101,115,99,114,111,108,108,99,111,108,0,13,102,105,120,99,111, + 108,115,46,99,111,117,110,116,2,1,13,102,105,120,99,111,108,115,46,105, + 116,101,109,115,14,1,5,119,105,100,116,104,2,27,7,110,117,109,115,116, + 101,112,2,1,0,0,13,102,105,120,114,111,119,115,46,99,111,117,110,116, + 2,1,13,102,105,120,114,111,119,115,46,105,116,101,109,115,14,1,6,104, + 101,105,103,104,116,2,16,14,99,97,112,116,105,111,110,115,46,99,111,117, + 110,116,2,2,14,99,97,112,116,105,111,110,115,46,105,116,101,109,115,14, + 1,7,99,97,112,116,105,111,110,6,1,97,0,1,7,99,97,112,116,105, + 111,110,6,1,98,0,0,0,0,14,100,97,116,97,99,111,108,115,46,99, + 111,117,110,116,2,2,16,100,97,116,97,99,111,108,115,46,111,112,116,105, + 111,110,115,11,15,99,111,95,112,114,111,112,111,114,116,105,111,110,97,108, + 12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111,95,115,97,118, + 101,115,116,97,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108, + 108,114,111,119,0,14,100,97,116,97,99,111,108,115,46,105,116,101,109,115, + 14,7,3,97,101,100,1,5,119,105,100,116,104,3,144,0,7,111,112,116, + 105,111,110,115,11,15,99,111,95,112,114,111,112,111,114,116,105,111,110,97, + 108,12,99,111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109,111, + 117,115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116, + 110,97,109,101,6,3,97,101,100,9,100,97,116,97,99,108,97,115,115,7, + 22,116,103,114,105,100,109,115,101,115,116,114,105,110,103,100,97,116,97,108, + 105,115,116,0,7,3,98,101,100,1,5,119,105,100,116,104,3,154,0,7, + 111,112,116,105,111,110,115,11,7,99,111,95,102,105,108,108,12,99,111,95, + 115,97,118,101,115,116,97,116,101,17,99,111,95,109,111,117,115,101,115,99, + 114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6, + 3,98,101,100,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105, + 100,109,115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,0, + 13,100,97,116,97,114,111,119,104,101,105,103,104,116,2,16,8,115,116,97, + 116,102,105,108,101,7,10,116,115,116,97,116,102,105,108,101,49,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,17,116,100,114,111,112, + 100,111,119,110,108,105,115,116,101,100,105,116,3,97,101,100,14,111,112,116, + 105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110, + 116,103,108,121,112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110, + 115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116, + 111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101,118,101,108,111, + 2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116, + 4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,10,102,114,108,95,108, + 101,118,101,108,105,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110, + 116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111, + 114,4,5,0,0,144,19,102,114,97,109,101,46,98,117,116,116,111,110,115, + 46,99,111,117,110,116,2,2,19,102,114,97,109,101,46,98,117,116,116,111, + 110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4,5,0,0, + 144,0,1,7,105,109,97,103,101,110,114,2,17,9,111,110,101,120,101,99, + 117,116,101,7,10,100,105,97,108,111,103,101,120,101,118,0,0,8,116,97, + 98,111,114,100,101,114,2,1,7,118,105,115,105,98,108,101,8,8,98,111, + 117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,120,3,144,0,9,98,111,117,110,100,115,95, + 99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111, + 101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49, + 95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101, + 115,116,97,116,101,27,111,101,49,95,99,104,101,99,107,118,97,108,117,101, + 97,102,116,101,114,115,116,97,116,114,101,97,100,0,11,111,112,116,105,111, + 110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99, + 13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104, + 101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105,102,116, + 114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114,110,20, + 111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116, + 15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95, + 101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101, + 108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110, + 102,105,114,115,116,99,108,105,99,107,22,111,101,95,102,111,99,117,115,114, + 101,99,116,111,110,114,101,97,100,111,110,108,121,18,111,101,95,104,105,110, + 116,99,108,105,112,112,101,100,116,101,120,116,0,16,100,114,111,112,100,111, + 119,110,46,111,112,116,105,111,110,115,11,14,100,101,111,95,115,101,108,101, + 99,116,111,110,108,121,16,100,101,111,95,97,117,116,111,100,114,111,112,100, + 111,119,110,15,100,101,111,95,107,101,121,100,114,111,112,100,111,119,110,12, + 100,101,111,95,99,108,105,112,104,105,110,116,0,19,100,114,111,112,100,111, + 119,110,46,99,111,108,115,46,99,111,117,110,116,2,1,19,100,114,111,112, + 100,111,119,110,46,99,111,108,115,46,105,116,101,109,115,14,1,0,0,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,17,116,100, + 114,111,112,100,111,119,110,108,105,115,116,101,100,105,116,3,98,101,100,14, + 111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95, + 102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,11,111,112,116, + 105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98, + 117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,10,102,114, + 108,95,108,101,118,101,108,105,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99, + 111,108,111,114,4,5,0,0,144,19,102,114,97,109,101,46,98,117,116,116, + 111,110,115,46,99,111,117,110,116,2,2,19,102,114,97,109,101,46,98,117, + 116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4, + 5,0,0,144,0,1,7,105,109,97,103,101,110,114,2,17,9,111,110,101, + 120,101,99,117,116,101,7,10,100,105,97,108,111,103,101,120,101,118,0,0, + 8,116,97,98,111,114,100,101,114,2,2,7,118,105,115,105,98,108,101,8, + 8,98,111,117,110,100,115,95,120,3,145,0,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,120,3,154,0,9,98,111,117, + 110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116, + 49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117, + 14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95, + 115,97,118,101,115,116,97,116,101,27,111,101,49,95,99,104,101,99,107,118, + 97,108,117,101,97,102,116,101,114,115,116,97,116,114,101,97,100,0,11,111, + 112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111, + 110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111, + 101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115, + 104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116, + 117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110, + 101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114, + 13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117, + 116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101,108,101, + 99,116,111,110,102,105,114,115,116,99,108,105,99,107,22,111,101,95,102,111, + 99,117,115,114,101,99,116,111,110,114,101,97,100,111,110,108,121,18,111,101, + 95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116,0,16,100,114, + 111,112,100,111,119,110,46,111,112,116,105,111,110,115,11,14,100,101,111,95, + 115,101,108,101,99,116,111,110,108,121,16,100,101,111,95,97,117,116,111,100, + 114,111,112,100,111,119,110,15,100,101,111,95,107,101,121,100,114,111,112,100, + 111,119,110,12,100,101,111,95,99,108,105,112,104,105,110,116,0,19,100,114, + 111,112,100,111,119,110,46,99,111,108,115,46,99,111,117,110,116,2,1,19, + 100,114,111,112,100,111,119,110,46,99,111,108,115,46,105,116,101,109,115,14, + 1,0,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0, + 0,0,0,9,116,115,116,97,116,102,105,108,101,10,116,115,116,97,116,102, + 105,108,101,49,8,102,105,108,101,110,97,109,101,6,26,116,97,98,111,114, + 100,101,114,111,118,101,114,114,105,100,101,101,100,105,116,111,114,46,115,116, + 97,7,111,112,116,105,111,110,115,11,10,115,102,111,95,109,101,109,111,114, + 121,0,4,108,101,102,116,2,16,3,116,111,112,3,216,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tmsetaborderoverrideeditorfo,''); +end. diff --git a/mseide-msegui/lib/common/designutils/msetexteditor.mfm b/mseide-msegui/lib/common/designutils/msetexteditor.mfm new file mode 100644 index 0000000..f558df7 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msetexteditor.mfm @@ -0,0 +1,213 @@ +object msetexteditorfo: tmsetexteditorfo + optionswidget = [ow_arrowfocus, ow_subfocus, ow_destroywidgets, ow_hinton] + visible = False + bounds_x = 74 + bounds_y = 214 + bounds_cx = 369 + bounds_cy = 268 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 369 + 268 + ) + options = [fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savestate] + statfile = tstatfile1 + caption = 'Texteditor' + moduleclassname = 'tmseform' + object ok: tbutton + bounds_x = 248 + bounds_y = 240 + bounds_cx = 50 + bounds_cy = 22 + anchors = [an_right, an_bottom] + state = [as_localcaption] + caption = '&OK' + modalresult = mr_ok + end + object cancel: tbutton + taborder = 1 + bounds_x = 312 + bounds_y = 240 + bounds_cx = 50 + bounds_cy = 22 + anchors = [an_right, an_bottom] + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + end + object grid: twidgetgrid + frame.localprops = [] + frame.localprops1 = [] + taborder = 2 + popupmenu = tpopupmenu1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 369 + bounds_cy = 234 + anchors = [an_top, an_bottom] + optionsgrid = [og_focuscellonenter, og_autofirstrow, og_autoappend, og_colchangeontabkey, og_wrapcol, og_autopopup] + fixcols.count = 1 + fixcols.items = < + item + linewidth = 0 + width = 40 + numstart = 1 + numstep = 1 + end> + datacols.count = 1 + datacols.items = < + item[textedit] + width = 2000 + options = [co_leftbuttonfocusonly, co_savevalue, co_savestate, co_mousescrollrow] + widgetname = 'textedit' + dataclass = tgridrichstringdatalist + end> + datarowlinewidth = 0 + datarowheight = 14 + reffontheight = 14 + object textedit: tsyntaxedit + frame.levelo = 0 + frame.framei_top = 0 + frame.framei_bottom = 0 + frame.localprops = [frl_levelo, frl_fileft, frl_fitop, frl_firight, frl_fibottom] + frame.localprops1 = [] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 2000 + bounds_cy = 14 + optionsedit1 = [oe1_keyexecute, oe1_savevalue, oe1_savestate] + optionsedit = [oe_closequery, oe_checkmrcancel, oe_linebreak, oe_eatreturn, oe_exitoncursor, oe_nofirstarrownavig] + options = [seo_autoindent, seo_markbrackets] + oneditnotifcation = editnotify + reffontheight = 14 + end + end + object linedisp: tstringdisp + frame.localprops = [] + frame.localprops1 = [] + taborder = 4 + bounds_x = 8 + bounds_y = 242 + bounds_cx = 76 + anchors = [an_left, an_bottom] + textflags = [tf_xcentered, tf_ycentered] + reffontheight = 14 + end + object test: tbutton + taborder = 3 + bounds_x = 184 + bounds_y = 240 + bounds_cx = 50 + bounds_cy = 22 + anchors = [an_right, an_bottom] + state = [as_disabled, as_invisible, as_localdisabled, as_localinvisible, as_localcaption, as_localonexecute] + caption = '&Test' + onexecute = testexe + end + object tpopupmenu1: tpopupmenu + onupdate = popupuponupdate + menu.submenu.count = 8 + menu.submenu.items = < + item + action = undoact + name = 'undo' + end + item + action = redoact + name = 'redo' + end + item + caption = '&Copy' + name = 'copy' + state = [as_localcaption, as_localshortcut, as_localonexecute] + onexecute = copyexe + sc = ( + 1 + 16451 + ) + end + item + caption = 'Cu&t' + name = 'cut' + state = [as_localcaption, as_localshortcut, as_localonexecute] + onexecute = cutexe + sc = ( + 1 + 16472 + ) + end + item + caption = '&Paste' + name = 'paste' + state = [as_localcaption, as_localshortcut, as_localonexecute] + onexecute = pasteexe + sc = ( + 1 + 16470 + ) + end + item + options = [mao_separator, mao_shortcutcaption] + end + item + caption = '&Load file' + state = [as_localcaption, as_localonexecute] + onexecute = loadfileexe + end + item + caption = '&Save file' + state = [as_localcaption, as_localonexecute] + onexecute = savefileexe + end> + left = 80 + top = 64 + end + object filedialog: tfiledialog + statfile = tstatfile1 + controller.captionopen = 'Load file' + controller.captionsave = 'Save file' + left = 80 + top = 104 + end + object tstatfile1: tstatfile + filename = 'texteditor.sta' + options = [sfo_memory] + left = 80 + top = 152 + end + object undoact: taction + caption = '&Undo' + options = [ao_globalshortcut] + onexecute = undoexe + left = 216 + top = 72 + sc = ( + 1 + 16474 + ) + end + object redoact: taction + caption = '&Redo' + options = [ao_globalshortcut] + onexecute = redoexe + left = 216 + top = 112 + sc = ( + 1 + 24666 + ) + end + object c: tstringcontainer + strings.data = ( + 'Test OK' + ) + left = 192 + top = 152 + end +end diff --git a/mseide-msegui/lib/common/designutils/msetexteditor.pas b/mseide-msegui/lib/common/designutils/msetexteditor.pas new file mode 100644 index 0000000..530ef48 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msetexteditor.pas @@ -0,0 +1,153 @@ +unit msetexteditor; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msegui,mseglob,mseguiglob,mseclasses,mseforms,msesimplewidgets,msewidgetgrid, + msesyntaxedit,msemenus,msefiledialog,msestat,msestatfile,msesyntaxpainter, + msedispwidgets,mseinplaceedit,mseact,mseactions,mseeditglob,msestringcontainer, + msestrings; + +const + texteditorstatname = 'texteditor.sta'; +type + tmsetexteditorfo = class(tmseform) + ok: tbutton; + cancel: tbutton; + filedialog: tfiledialog; + undoact: taction; + redoact: taction; + test: tbutton; + tpopupmenu1: tpopupmenu; + textedit: tsyntaxedit; + tstatfile1: tstatfile; + linedisp: tstringdisp; + grid: twidgetgrid; + c: tstringcontainer; + procedure undoexe(const sender: TObject); + procedure redoexe(const sender: TObject); + procedure popupuponupdate(const sender: tcustommenu); + procedure loadfileexe(const sender: TObject); + procedure savefileexe(const sender: TObject); + procedure editnotify(const sender: TObject; var info: editnotificationinfoty); + procedure copyexe(const sender: TObject); + procedure cutexe(const sender: TObject); + procedure pasteexe(const sender: TObject); + procedure testexe(const sender: TObject); + procedure undoupda(const sender: tcustomaction); + procedure redoupda(const sender: tcustomaction); + public + constructor create(const aonclosequery: closequeryeventty; + const asyntaxpainter: tsyntaxpainter; + const asyntaxindex: integer; const testbutton: boolean); reintroduce; + end; + +var + syntaxpainter: tsyntaxpainter; + +implementation +uses + msetexteditor_mfm,sysutils,msewidgets,mseshapes,mseformatstr; + +const + sqlsyntaxdef = ''; +type + strinconststy = ( + testok //0 Test OK + ); + +constructor tmsetexteditorfo.create(const aonclosequery: closequeryeventty; + const asyntaxpainter: tsyntaxpainter; const asyntaxindex: integer; + const testbutton: boolean); +begin + inherited create(nil); + onclosequery:= aonclosequery; + if (asyntaxpainter <> nil) and (asyntaxindex >= 0) then begin + textedit.syntaxpainter:= asyntaxpainter; + textedit.setsyntaxdef(asyntaxindex); + end; + if testbutton then begin + test.state:= test.state - [as_invisible,as_disabled]; + end; +end; + +procedure tmsetexteditorfo.loadfileexe(const sender: TObject); +begin + if filedialog.execute(fdk_open) = mr_ok then begin + textedit.loadfromfile(filedialog.controller.filename); + end; +end; + +procedure tmsetexteditorfo.savefileexe(const sender: TObject); +begin + if filedialog.execute(fdk_save) = mr_ok then begin + textedit.savetofile(filedialog.controller.filename); + end; +end; + +procedure tmsetexteditorfo.editnotify(const sender: TObject; + var info: editnotificationinfoty); +begin + if info.action = ea_indexmoved then begin + linedisp.value:= inttostrmse(textedit.editpos.row+1) + ':'+ + inttostrmse(textedit.editpos.col+1); + end; +end; + +procedure tmsetexteditorfo.popupuponupdate(const sender: tcustommenu); +begin + sender.menu.itembyname('undo').enabled:= textedit.canundo; + sender.menu.itembyname('redo').enabled:= textedit.canredo; + sender.menu.itembyname('copy').enabled:= textedit.hasselection; + sender.menu.itembyname('cut').enabled:= textedit.hasselection; + sender.menu.itembyname('paste').enabled:= textedit.canpaste; +end; + +procedure tmsetexteditorfo.undoexe(const sender: TObject); +begin + textedit.undo; +end; + +procedure tmsetexteditorfo.redoexe(const sender: TObject); +begin + textedit.redo; +end; + +procedure tmsetexteditorfo.copyexe(const sender: TObject); +begin + textedit.copyselection; +end; + +procedure tmsetexteditorfo.cutexe(const sender: TObject); +begin + textedit.cutselection; +end; + +procedure tmsetexteditorfo.pasteexe(const sender: TObject); +begin + textedit.paste; +end; + +procedure tmsetexteditorfo.testexe(const sender: TObject); +var + modres: modalresultty; +begin + modres:= mr_canclose; + onclosequery(self,modres); + if modres = mr_canclose then begin + showmessage(c[ord(testok)]); + end; +end; + +procedure tmsetexteditorfo.undoupda(const sender: tcustomaction); +begin +end; + +procedure tmsetexteditorfo.redoupda(const sender: tcustomaction); +begin +end; + +initialization + syntaxpainter:= tsyntaxpainter.create(nil); +finalization + syntaxpainter.free; +end. diff --git a/mseide-msegui/lib/common/designutils/msetexteditor_mfm.pas b/mseide-msegui/lib/common/designutils/msetexteditor_mfm.pas new file mode 100644 index 0000000..ad16a59 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/msetexteditor_mfm.pas @@ -0,0 +1,195 @@ +unit msetexteditor_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msetexteditor; + +const + objdata: record size: integer; data: array[0..3558] of byte end = + (size: 3559; data: ( + 84,80,70,48,16,116,109,115,101,116,101,120,116,101,100,105,116,111,114,102, + 111,15,109,115,101,116,101,120,116,101,100,105,116,111,114,102,111,13,111,112, + 116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,97,114,114,111, + 119,102,111,99,117,115,11,111,119,95,115,117,98,102,111,99,117,115,17,111, + 119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,9,111,119,95, + 104,105,110,116,111,110,0,7,118,105,115,105,98,108,101,8,8,98,111,117, + 110,100,115,95,120,2,74,8,98,111,117,110,100,115,95,121,3,214,0,9, + 98,111,117,110,100,115,95,99,120,3,113,1,9,98,111,117,110,100,115,95, + 99,121,3,12,1,23,99,111,110,116,97,105,110,101,114,46,111,112,116,105, + 111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102, + 111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95, + 97,114,114,111,119,102,111,99,117,115,11,111,119,95,115,117,98,102,111,99, + 117,115,19,111,119,95,109,111,117,115,101,116,114,97,110,115,112,97,114,101, + 110,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 0,26,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,0,27,99,111,110,116,97,105,110,101,114, + 46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2,0, + 2,0,3,113,1,3,12,1,0,7,111,112,116,105,111,110,115,11,13,102, + 111,95,99,108,111,115,101,111,110,101,115,99,15,102,111,95,97,117,116,111, + 114,101,97,100,115,116,97,116,16,102,111,95,97,117,116,111,119,114,105,116, + 101,115,116,97,116,10,102,111,95,115,97,118,101,112,111,115,12,102,111,95, + 115,97,118,101,115,116,97,116,101,0,8,115,116,97,116,102,105,108,101,7, + 10,116,115,116,97,116,102,105,108,101,49,7,99,97,112,116,105,111,110,6, + 10,84,101,120,116,101,100,105,116,111,114,15,109,111,100,117,108,101,99,108, + 97,115,115,110,97,109,101,6,8,116,109,115,101,102,111,114,109,0,7,116, + 98,117,116,116,111,110,2,111,107,8,98,111,117,110,100,115,95,120,3,248, + 0,8,98,111,117,110,100,115,95,121,3,240,0,9,98,111,117,110,100,115, + 95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,22,7,97,110, + 99,104,111,114,115,11,8,97,110,95,114,105,103,104,116,9,97,110,95,98, + 111,116,116,111,109,0,5,115,116,97,116,101,11,15,97,115,95,108,111,99, + 97,108,99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,3, + 38,79,75,11,109,111,100,97,108,114,101,115,117,108,116,7,5,109,114,95, + 111,107,0,0,7,116,98,117,116,116,111,110,6,99,97,110,99,101,108,8, + 116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,3, + 56,1,8,98,111,117,110,100,115,95,121,3,240,0,9,98,111,117,110,100, + 115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,22,7,97, + 110,99,104,111,114,115,11,8,97,110,95,114,105,103,104,116,9,97,110,95, + 98,111,116,116,111,109,0,5,115,116,97,116,101,11,15,97,115,95,108,111, + 99,97,108,99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6, + 7,38,67,97,110,99,101,108,11,109,111,100,97,108,114,101,115,117,108,116, + 7,9,109,114,95,99,97,110,99,101,108,0,0,11,116,119,105,100,103,101, + 116,103,114,105,100,4,103,114,105,100,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,2, + 9,112,111,112,117,112,109,101,110,117,7,11,116,112,111,112,117,112,109,101, + 110,117,49,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100, + 115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,113,1,9,98, + 111,117,110,100,115,95,99,121,3,234,0,7,97,110,99,104,111,114,115,11, + 6,97,110,95,116,111,112,9,97,110,95,98,111,116,116,111,109,0,11,111, + 112,116,105,111,110,115,103,114,105,100,11,19,111,103,95,102,111,99,117,115, + 99,101,108,108,111,110,101,110,116,101,114,15,111,103,95,97,117,116,111,102, + 105,114,115,116,114,111,119,13,111,103,95,97,117,116,111,97,112,112,101,110, + 100,20,111,103,95,99,111,108,99,104,97,110,103,101,111,110,116,97,98,107, + 101,121,10,111,103,95,119,114,97,112,99,111,108,12,111,103,95,97,117,116, + 111,112,111,112,117,112,0,13,102,105,120,99,111,108,115,46,99,111,117,110, + 116,2,1,13,102,105,120,99,111,108,115,46,105,116,101,109,115,14,1,9, + 108,105,110,101,119,105,100,116,104,2,0,5,119,105,100,116,104,2,40,8, + 110,117,109,115,116,97,114,116,2,1,7,110,117,109,115,116,101,112,2,1, + 0,0,14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,1,14, + 100,97,116,97,99,111,108,115,46,105,116,101,109,115,14,7,8,116,101,120, + 116,101,100,105,116,1,5,119,105,100,116,104,3,208,7,7,111,112,116,105, + 111,110,115,11,22,99,111,95,108,101,102,116,98,117,116,116,111,110,102,111, + 99,117,115,111,110,108,121,12,99,111,95,115,97,118,101,118,97,108,117,101, + 12,99,111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109,111,117, + 115,101,115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110, + 97,109,101,6,8,116,101,120,116,101,100,105,116,9,100,97,116,97,99,108, + 97,115,115,7,23,116,103,114,105,100,114,105,99,104,115,116,114,105,110,103, + 100,97,116,97,108,105,115,116,0,0,16,100,97,116,97,114,111,119,108,105, + 110,101,119,105,100,116,104,2,0,13,100,97,116,97,114,111,119,104,101,105, + 103,104,116,2,14,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,11,116,115,121,110,116,97,120,101,100,105,116,8,116,101,120,116,101, + 100,105,116,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,16,102, + 114,97,109,101,46,102,114,97,109,101,105,95,116,111,112,2,0,19,102,114, + 97,109,101,46,102,114,97,109,101,105,95,98,111,116,116,111,109,2,0,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,10,102,114,108,95,102,105,108,101,102,116,9, + 102,114,108,95,102,105,116,111,112,11,102,114,108,95,102,105,114,105,103,104, + 116,12,102,114,108,95,102,105,98,111,116,116,111,109,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111, + 114,100,101,114,2,1,7,118,105,115,105,98,108,101,8,8,98,111,117,110, + 100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,120,3,208,7,9,98,111,117,110,100,115,95,99,121, + 2,14,12,111,112,116,105,111,110,115,101,100,105,116,49,11,14,111,101,49, + 95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101, + 118,97,108,117,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0, + 11,111,112,116,105,111,110,115,101,100,105,116,11,13,111,101,95,99,108,111, + 115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97, + 110,99,101,108,12,111,101,95,108,105,110,101,98,114,101,97,107,12,111,101, + 95,101,97,116,114,101,116,117,114,110,15,111,101,95,101,120,105,116,111,110, + 99,117,114,115,111,114,20,111,101,95,110,111,102,105,114,115,116,97,114,114, + 111,119,110,97,118,105,103,0,7,111,112,116,105,111,110,115,11,14,115,101, + 111,95,97,117,116,111,105,110,100,101,110,116,16,115,101,111,95,109,97,114, + 107,98,114,97,99,107,101,116,115,0,17,111,110,101,100,105,116,110,111,116, + 105,102,99,97,116,105,111,110,7,10,101,100,105,116,110,111,116,105,102,121, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,11, + 116,115,116,114,105,110,103,100,105,115,112,8,108,105,110,101,100,105,115,112, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8, + 116,97,98,111,114,100,101,114,2,4,8,98,111,117,110,100,115,95,120,2, + 8,8,98,111,117,110,100,115,95,121,3,242,0,9,98,111,117,110,100,115, + 95,99,120,2,76,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101, + 102,116,9,97,110,95,98,111,116,116,111,109,0,9,116,101,120,116,102,108, + 97,103,115,11,12,116,102,95,120,99,101,110,116,101,114,101,100,12,116,102, + 95,121,99,101,110,116,101,114,101,100,0,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,14,0,0,7,116,98,117,116,116,111,110,4,116,101, + 115,116,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117,110,100,115, + 95,120,3,184,0,8,98,111,117,110,100,115,95,121,3,240,0,9,98,111, + 117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2, + 22,7,97,110,99,104,111,114,115,11,8,97,110,95,114,105,103,104,116,9, + 97,110,95,98,111,116,116,111,109,0,5,115,116,97,116,101,11,11,97,115, + 95,100,105,115,97,98,108,101,100,12,97,115,95,105,110,118,105,115,105,98, + 108,101,16,97,115,95,108,111,99,97,108,100,105,115,97,98,108,101,100,17, + 97,115,95,108,111,99,97,108,105,110,118,105,115,105,98,108,101,15,97,115, + 95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99, + 97,108,111,110,101,120,101,99,117,116,101,0,7,99,97,112,116,105,111,110, + 6,5,38,84,101,115,116,9,111,110,101,120,101,99,117,116,101,7,7,116, + 101,115,116,101,120,101,0,0,10,116,112,111,112,117,112,109,101,110,117,11, + 116,112,111,112,117,112,109,101,110,117,49,8,111,110,117,112,100,97,116,101, + 7,15,112,111,112,117,112,117,112,111,110,117,112,100,97,116,101,18,109,101, + 110,117,46,115,117,98,109,101,110,117,46,99,111,117,110,116,2,8,18,109, + 101,110,117,46,115,117,98,109,101,110,117,46,105,116,101,109,115,14,1,6, + 97,99,116,105,111,110,7,7,117,110,100,111,97,99,116,4,110,97,109,101, + 6,4,117,110,100,111,0,1,6,97,99,116,105,111,110,7,7,114,101,100, + 111,97,99,116,4,110,97,109,101,6,4,114,101,100,111,0,1,7,99,97, + 112,116,105,111,110,6,5,38,67,111,112,121,4,110,97,109,101,6,4,99, + 111,112,121,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99, + 97,112,116,105,111,110,16,97,115,95,108,111,99,97,108,115,104,111,114,116, + 99,117,116,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116, + 101,0,9,111,110,101,120,101,99,117,116,101,7,7,99,111,112,121,101,120, + 101,2,115,99,1,2,1,3,67,64,0,0,1,7,99,97,112,116,105,111, + 110,6,4,67,117,38,116,4,110,97,109,101,6,3,99,117,116,5,115,116, + 97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110, + 16,97,115,95,108,111,99,97,108,115,104,111,114,116,99,117,116,17,97,115, + 95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101, + 120,101,99,117,116,101,7,6,99,117,116,101,120,101,2,115,99,1,2,1, + 3,88,64,0,0,1,7,99,97,112,116,105,111,110,6,6,38,80,97,115, + 116,101,4,110,97,109,101,6,5,112,97,115,116,101,5,115,116,97,116,101, + 11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,16,97,115, + 95,108,111,99,97,108,115,104,111,114,116,99,117,116,17,97,115,95,108,111, + 99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99, + 117,116,101,7,8,112,97,115,116,101,101,120,101,2,115,99,1,2,1,3, + 86,64,0,0,1,7,111,112,116,105,111,110,115,11,13,109,97,111,95,115, + 101,112,97,114,97,116,111,114,19,109,97,111,95,115,104,111,114,116,99,117, + 116,99,97,112,116,105,111,110,0,0,1,7,99,97,112,116,105,111,110,6, + 10,38,76,111,97,100,32,102,105,108,101,5,115,116,97,116,101,11,15,97, + 115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111, + 99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99, + 117,116,101,7,11,108,111,97,100,102,105,108,101,101,120,101,0,1,7,99, + 97,112,116,105,111,110,6,10,38,83,97,118,101,32,102,105,108,101,5,115, + 116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111, + 110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0, + 9,111,110,101,120,101,99,117,116,101,7,11,115,97,118,101,102,105,108,101, + 101,120,101,0,0,4,108,101,102,116,2,80,3,116,111,112,2,64,0,0, + 11,116,102,105,108,101,100,105,97,108,111,103,10,102,105,108,101,100,105,97, + 108,111,103,8,115,116,97,116,102,105,108,101,7,10,116,115,116,97,116,102, + 105,108,101,49,22,99,111,110,116,114,111,108,108,101,114,46,99,97,112,116, + 105,111,110,111,112,101,110,6,9,76,111,97,100,32,102,105,108,101,22,99, + 111,110,116,114,111,108,108,101,114,46,99,97,112,116,105,111,110,115,97,118, + 101,6,9,83,97,118,101,32,102,105,108,101,4,108,101,102,116,2,80,3, + 116,111,112,2,104,0,0,9,116,115,116,97,116,102,105,108,101,10,116,115, + 116,97,116,102,105,108,101,49,8,102,105,108,101,110,97,109,101,6,14,116, + 101,120,116,101,100,105,116,111,114,46,115,116,97,7,111,112,116,105,111,110, + 115,11,10,115,102,111,95,109,101,109,111,114,121,0,4,108,101,102,116,2, + 80,3,116,111,112,3,152,0,0,0,7,116,97,99,116,105,111,110,7,117, + 110,100,111,97,99,116,7,99,97,112,116,105,111,110,6,5,38,85,110,100, + 111,7,111,112,116,105,111,110,115,11,17,97,111,95,103,108,111,98,97,108, + 115,104,111,114,116,99,117,116,0,9,111,110,101,120,101,99,117,116,101,7, + 7,117,110,100,111,101,120,101,4,108,101,102,116,3,216,0,3,116,111,112, + 2,72,2,115,99,1,2,1,3,90,64,0,0,0,7,116,97,99,116,105, + 111,110,7,114,101,100,111,97,99,116,7,99,97,112,116,105,111,110,6,5, + 38,82,101,100,111,7,111,112,116,105,111,110,115,11,17,97,111,95,103,108, + 111,98,97,108,115,104,111,114,116,99,117,116,0,9,111,110,101,120,101,99, + 117,116,101,7,7,114,101,100,111,101,120,101,4,108,101,102,116,3,216,0, + 3,116,111,112,2,112,2,115,99,1,2,1,3,90,96,0,0,0,16,116, + 115,116,114,105,110,103,99,111,110,116,97,105,110,101,114,1,99,12,115,116, + 114,105,110,103,115,46,100,97,116,97,1,6,7,84,101,115,116,32,79,75, + 0,4,108,101,102,116,3,192,0,3,116,111,112,3,152,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tmsetexteditorfo,''); +end. diff --git a/mseide-msegui/lib/common/designutils/panelform.mfm b/mseide-msegui/lib/common/designutils/panelform.mfm new file mode 100644 index 0000000..7e40563 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/panelform.mfm @@ -0,0 +1,37 @@ +object panelfo: tpanelfo + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_hinton] + frame.localprops = [] + frame.localprops1 = [] + frame.grip_size = 10 + frame.grip_options = [go_closebutton, go_fixsizebutton, go_floatbutton, go_topbutton, go_backgroundbutton, go_lockbutton, go_nolockbutton, go_buttonhints] + onpaint = paintexe + visible = False + bounds_x = 157 + bounds_y = 493 + bounds_cx = 323 + bounds_cy = 195 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_mousetransparent] + container.frame.framei_left = 0 + container.frame.framei_top = 0 + container.frame.framei_right = 0 + container.frame.framei_bottom = 0 + container.frame.localprops = [frl_fileft, frl_fitop, frl_firight, frl_fibottom] + container.frame.localprops1 = [] + container.onpaint = paintexe + container.bounds = ( + 0 + 0 + 313 + 195 + ) + dragdock.tab_options = [tabo_dragsource, tabo_dragdest, tabo_hintclippedtext] + dragdock.tab_textflags = [tf_ycentered, tf_ellipseright] + dragdock.tab_widthmax = 100 + dragdock.optionsdock = [od_savepos, od_savezorder, od_canmove, od_canfloat, od_candock, od_acceptsdock, od_dockparent, od_splitvert, od_splithorz, od_tabed, od_proportional, od_propsize, od_captionhint, od_childicons] + dragdock.onlayoutchanged = panellayoutchanged + dragdock.oncaptionchanged = panellayoutchanged + options = [fo_savepos, fo_savezorder, fo_savestate] + statfile = mainfo.projectstatfile + onclose = onclo + moduleclassname = 'tdockform' +end diff --git a/mseide-msegui/lib/common/designutils/panelform.pas b/mseide-msegui/lib/common/designutils/panelform.pas new file mode 100644 index 0000000..3fedab6 --- /dev/null +++ b/mseide-msegui/lib/common/designutils/panelform.pas @@ -0,0 +1,292 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} + +unit panelform; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + classes,mclasses,msegui,mseclasses,mseforms,msemenus,msestat, + msetypes{msestrings}, + msedock,msegraphutils,msegraphics,mseguiglob,msesimplewidgets,msewidgets, + msestringcontainer; + +type + + tpanelfo = class(tdockform) + procedure onclo(const sender: TObject); + procedure panellayoutchanged(const sender: tdockcontroller); + procedure paintexe(const sender: twidget; const acanvas: tcanvas); + private + fmenuitem: tmenuitem; + fnameindex: integer; //0 for unnumbered + procedure showexecute(const sender: tobject); + protected + procedure updatecaption(acaption: msestring); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function canclose(const newfocus: twidget): boolean; override; + end; + +function newpanel(aname: string = ''): tpanelfo; +procedure updatestat(const filer: tstatfiler); +procedure docktopanel(const controller: tdockcontroller; + const panelname: string; const arect: rectty); +procedure beginpanelplacement(); +procedure endpanelplacement(); + +implementation + +uses + panelform_mfm,main,sysutils,msekeyboard,mselist,msedatalist, + msearrayutils,mseformatstr; + +var + panellist: tpointerlist; + +procedure updatestat(const filer: tstatfiler); +var + ar1: msestringarty; + int1: integer; +begin + ar1:= nil; + if filer.iswriter then begin + setlength(ar1,panellist.count); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= msestring(tpanelfo(panellist[int1]).name); + end; + end; + filer.updatevalue('panels',ar1); + if not filer.iswriter then begin + for int1:= panellist.count - 1 downto 0 do begin + tpanelfo(panellist[int1]).free; + end; + for int1:= 0 to high(ar1) do begin + try + newpanel(ansistring(ar1[int1])); + except + end; + end; + end; +end; + +procedure docktopanel(const controller: tdockcontroller; + const panelname: string; const arect: rectty); +var + int1: integer; +begin + for int1:= 0 to panellist.count-1 do begin + with tpanelfo(panellist[int1]) do begin + if name = panelname then begin + dragdock.dock(controller,arect); + break; + end; + end; + end; +end; + +procedure beginpanelplacement(); +var + int1: integer; +begin + for int1:= 0 to panellist.count-1 do begin + with tpanelfo(panellist[int1]) do begin + dragdock.beginplacement(); + end; + end; +end; + +procedure endpanelplacement(); +var + int1: integer; +begin + for int1:= 0 to panellist.count-1 do begin + with tpanelfo(panellist[int1]) do begin + try + dragdock.endplacement(); + except + application.handleexception(); + end; + end; + end; +end; + +function newpanel(aname: string = ''): tpanelfo; +var + item1: tmenuitem; + int1,int2: integer; + ar1: integerarty; +begin + item1:= mainfo.mainmenu.menu.itembyname('view').itembyname('panels'); + if aname = '' then begin + setlength(ar1,panellist.count); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= tpanelfo(panellist[int1]).fnameindex; + end; + sortarray(ar1); + int2:= length(ar1); + for int1:= 0 to high(ar1) do begin //find first gap + if ar1[int1] <> int1 then begin + int2:= int1; + break; + end; + end; + end + else begin + int2:= strtoint(copy(aname,6,bigint))-1; + end; + result:= tpanelfo.create(mainfo); + int1:= int2 + 1; + if aname = '' then begin + aname:= 'panel'+inttostr(int1); + end; + with result do begin + name:= aname; + fnameindex:= int2; + fmenuitem:= tmenuitem.create(nil,nil); + updatecaption(''); + end; + if int2 > item1.count - 2 then begin + int2:= item1.count - 2; + end; + item1.submenu.insert(int2,result.fmenuitem); +end; + +{ tpanelfo } + +constructor tpanelfo.create(aowner: tcomponent); +begin + inherited create(aowner); + panellist.add(self); +end; + +destructor tpanelfo.destroy; +begin + if panellist <> nil then begin + panellist.remove(self); + end; + if not (csdestroying in mainfo.componentstate) then begin + fmenuitem.parentmenu.submenu.delete(fmenuitem.index); + end; + inherited; +end; + +procedure tpanelfo.updatecaption(acaption: msestring); + +begin + if acaption = '' then begin + acaption:= 'Panel'; + end; + if length(acaption) > 40 then begin + setlength(acaption,40); + acaption:= acaption+'...'; + end; + with fmenuitem do begin + onexecute:= {$ifdef FPC}@{$endif}showexecute; + if fnameindex < 9 then begin + shortcut:= (ord(key_f1) or key_modctrl) + fnameindex; + caption:= '&' + inttostrmse(fnameindex+1)+' '+acaption; + end + else begin + shortcut:= 0; + caption:= acaption; + end; + if shortcut <> 0 then begin + acaption:= acaption + ' (Ctrl+F' + inttostrmse(fnameindex+1)+')'; + end; + self.caption:= acaption; + end; +end; + +procedure tpanelfo.showexecute(const sender: tobject); +begin + activate; +end; + +function tpanelfo.canclose(const newfocus: twidget): boolean; + + function containerempty: boolean; + var + int1: integer; + begin + result:= container.widgetcount = 0; + if not result then begin + for int1:= 0 to container.widgetcount - 1 do begin + if container.widgets[int1].visible then begin + exit; + end; + end; + end; + result:= true; + end; + +begin + result:= inherited canclose(newfocus); + { + if result and (newfocus = nil) and containerempty then begin + release; + end; + } +end; + +procedure tpanelfo.onclo(const sender: TObject); + function containerempty: boolean; + var + int1: integer; + begin + result:= container.widgetcount = 0; + if not result then begin + for int1:= 0 to container.widgetcount - 1 do begin + if container.widgets[int1].visible then begin + exit; + end; + end; + end; + result:= true; + end; +begin + if containerempty then begin + release; + end; +end; + +procedure tpanelfo.panellayoutchanged(const sender: tdockcontroller); +var + intf1: idocktarget; + mstr1: msestring; + int1: integer; + ar1: widgetarty; +begin + mstr1:= ''; + ar1:= sender.getitems; + for int1:= 0 to high(ar1) do begin + if ar1[int1].getcorbainterface(typeinfo(idocktarget),intf1) then begin + mstr1:= mstr1 + intf1.getdockcontroller.getdockcaption+','; + end; + end; + if mstr1 <> '' then begin + setlength(mstr1,length(mstr1)-1); + end; + fdragdock.caption:= mstr1; + updatecaption(mstr1); +end; + +procedure tpanelfo.paintexe(const sender: twidget; const acanvas: tcanvas); +begin + paintdockingareacaption(acanvas,sender,mainfo.c[ord(dockingarea)]); +end; + +initialization + panellist:= tpointerlist.Create; +finalization + freeandnil(panellist); +end. diff --git a/mseide-msegui/lib/common/designutils/panelform_mfm.pas b/mseide-msegui/lib/common/designutils/panelform_mfm.pas new file mode 100644 index 0000000..b40827a --- /dev/null +++ b/mseide-msegui/lib/common/designutils/panelform_mfm.pas @@ -0,0 +1,87 @@ +unit panelform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,panelform; + +const + objdata: record size: integer; data: array[0..1397] of byte end = + (size: 1398; data: ( + 84,80,70,48,8,116,112,97,110,101,108,102,111,7,112,97,110,101,108,102, + 111,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95, + 97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111, + 119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111,99,117, + 115,9,111,119,95,104,105,110,116,111,110,0,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,15,102,114,97,109,101,46,103,114, + 105,112,95,115,105,122,101,2,10,18,102,114,97,109,101,46,103,114,105,112, + 95,111,112,116,105,111,110,115,11,14,103,111,95,99,108,111,115,101,98,117, + 116,116,111,110,16,103,111,95,102,105,120,115,105,122,101,98,117,116,116,111, + 110,14,103,111,95,102,108,111,97,116,98,117,116,116,111,110,12,103,111,95, + 116,111,112,98,117,116,116,111,110,19,103,111,95,98,97,99,107,103,114,111, + 117,110,100,98,117,116,116,111,110,13,103,111,95,108,111,99,107,98,117,116, + 116,111,110,15,103,111,95,110,111,108,111,99,107,98,117,116,116,111,110,14, + 103,111,95,98,117,116,116,111,110,104,105,110,116,115,0,7,111,110,112,97, + 105,110,116,7,8,112,97,105,110,116,101,120,101,7,118,105,115,105,98,108, + 101,8,8,98,111,117,110,100,115,95,120,3,157,0,8,98,111,117,110,100, + 115,95,121,3,237,1,9,98,111,117,110,100,115,95,99,120,3,67,1,9, + 98,111,117,110,100,115,95,99,121,3,195,0,23,99,111,110,116,97,105,110, + 101,114,46,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119, + 95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111, + 99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119, + 95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114, + 111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111,99, + 117,115,19,111,119,95,109,111,117,115,101,116,114,97,110,115,112,97,114,101, + 110,116,0,27,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46, + 102,114,97,109,101,105,95,108,101,102,116,2,0,26,99,111,110,116,97,105, + 110,101,114,46,102,114,97,109,101,46,102,114,97,109,101,105,95,116,111,112, + 2,0,28,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,102, + 114,97,109,101,105,95,114,105,103,104,116,2,0,29,99,111,110,116,97,105, + 110,101,114,46,102,114,97,109,101,46,102,114,97,109,101,105,95,98,111,116, + 116,111,109,2,0,26,99,111,110,116,97,105,110,101,114,46,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,102,105, + 108,101,102,116,9,102,114,108,95,102,105,116,111,112,11,102,114,108,95,102, + 105,114,105,103,104,116,12,102,114,108,95,102,105,98,111,116,116,111,109,0, + 27,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,17,99,111,110,116,97,105,110,101,114, + 46,111,110,112,97,105,110,116,7,8,112,97,105,110,116,101,120,101,16,99, + 111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0, + 3,57,1,3,195,0,0,20,100,114,97,103,100,111,99,107,46,116,97,98, + 95,111,112,116,105,111,110,115,11,15,116,97,98,111,95,100,114,97,103,115, + 111,117,114,99,101,13,116,97,98,111,95,100,114,97,103,100,101,115,116,20, + 116,97,98,111,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116, + 0,22,100,114,97,103,100,111,99,107,46,116,97,98,95,116,101,120,116,102, + 108,97,103,115,11,12,116,102,95,121,99,101,110,116,101,114,101,100,15,116, + 102,95,101,108,108,105,112,115,101,114,105,103,104,116,0,21,100,114,97,103, + 100,111,99,107,46,116,97,98,95,119,105,100,116,104,109,97,120,2,100,20, + 100,114,97,103,100,111,99,107,46,111,112,116,105,111,110,115,100,111,99,107, + 11,10,111,100,95,115,97,118,101,112,111,115,13,111,100,95,115,97,118,101, + 122,111,114,100,101,114,10,111,100,95,99,97,110,109,111,118,101,11,111,100, + 95,99,97,110,102,108,111,97,116,10,111,100,95,99,97,110,100,111,99,107, + 14,111,100,95,97,99,99,101,112,116,115,100,111,99,107,13,111,100,95,100, + 111,99,107,112,97,114,101,110,116,12,111,100,95,115,112,108,105,116,118,101, + 114,116,12,111,100,95,115,112,108,105,116,104,111,114,122,8,111,100,95,116, + 97,98,101,100,15,111,100,95,112,114,111,112,111,114,116,105,111,110,97,108, + 11,111,100,95,112,114,111,112,115,105,122,101,14,111,100,95,99,97,112,116, + 105,111,110,104,105,110,116,13,111,100,95,99,104,105,108,100,105,99,111,110, + 115,0,24,100,114,97,103,100,111,99,107,46,111,110,108,97,121,111,117,116, + 99,104,97,110,103,101,100,7,18,112,97,110,101,108,108,97,121,111,117,116, + 99,104,97,110,103,101,100,25,100,114,97,103,100,111,99,107,46,111,110,99, + 97,112,116,105,111,110,99,104,97,110,103,101,100,7,18,112,97,110,101,108, + 108,97,121,111,117,116,99,104,97,110,103,101,100,7,111,112,116,105,111,110, + 115,11,10,102,111,95,115,97,118,101,112,111,115,13,102,111,95,115,97,118, + 101,122,111,114,100,101,114,12,102,111,95,115,97,118,101,115,116,97,116,101, + 0,8,115,116,97,116,102,105,108,101,7,22,109,97,105,110,102,111,46,112, + 114,111,106,101,99,116,115,116,97,116,102,105,108,101,7,111,110,99,108,111, + 115,101,7,5,111,110,99,108,111,15,109,111,100,117,108,101,99,108,97,115, + 115,110,97,109,101,6,9,116,100,111,99,107,102,111,114,109,0,0) + ); + +initialization + registerobjectdata(@objdata,tpanelfo,''); +end. diff --git a/mseide-msegui/lib/common/dialogs/msecolordialog.mfm b/mseide-msegui/lib/common/dialogs/msecolordialog.mfm new file mode 100644 index 0000000..bb272ee --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msecolordialog.mfm @@ -0,0 +1,561 @@ +object colordialogfo: tcolordialogfo + visible = False + bounds_x = 140 + bounds_y = 234 + bounds_cx = 338 + bounds_cy = 298 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.onlayout = layoutexe + container.bounds = ( + 0 + 0 + 338 + 298 + ) + onshortcut = shortcutexe + options = [fo_closeonesc, fo_localshortcuts, fo_autoreadstat, fo_autowritestat, fo_savepos] + statfile = tstatfile1 + caption = 'Select Color' + onloaded = loadedexe + onmouseevent = mouseeventexe + onlayout = layoutexe + moduleclassname = 'tmseform' + object colorpibu: tdatabutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + taborder = 6 + bounds_x = 4 + bounds_y = 237 + bounds_cx = 97 + bounds_cy = 18 + bounds_cxmin = 97 + anchors = [an_left, an_bottom] + state = [as_localinvisible, as_localcaption, as_localonexecute] + valuefaces.count = 1 + valuefaces.items = < + item + fade_pos.count = 3 + fade_pos.items = ( + 0 + 0.42629482071713 + 1 + ) + fade_color.count = 3 + fade_color.items = ( + 16762880 + 16772001 + 15903324 + ) + fade_direction = gd_down + localprops = [fal_fadirection] + end> + caption = 'Color &Picker' + onexecute = colorpickexe + reffontheight = 14 + end + object colorarea: tpaintbox + optionswidget = [ow_destroywidgets] + color = -2147483645 + frame.options = [cfo_captionnoclip] + frame.colorframe = -1610612734 + frame.colorclient = -1879048174 + frame.caption = 'new' + frame.captionpos = cp_bottom + frame.localprops = [frl_colorframe, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 0 + 17 + ) + taborder = 5 + bounds_x = 51 + bounds_y = 3 + bounds_cx = 50 + bounds_cy = 226 + anchors = [an_left, an_top, an_bottom] + end + object colorareabefore: tpaintbox + optionswidget = [ow_destroywidgets] + color = -2147483645 + frame.options = [cfo_captionnoclip] + frame.colorframe = -1610612734 + frame.colorclient = -1879048180 + frame.caption = 'old' + frame.captionpos = cp_bottom + frame.localprops = [frl_colorframe, frl_colorclient] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 0 + 0 + 17 + ) + taborder = 4 + bounds_x = 3 + bounds_y = 3 + bounds_cx = 50 + bounds_cy = 226 + anchors = [an_left, an_top, an_bottom] + end + object tlayouter1: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + taborder = 1 + bounds_x = 112 + bounds_y = 219 + bounds_cx = 221 + bounds_cy = 37 + anchors = [an_left, an_bottom] + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + linktop = tlayouter3 + linkbottom = tlayouter2 + options = [spao_gluebottom] + object blue: tintegeredit + color = -2147483645 + frame.caption = '&blue' + frame.captionpos = cp_top + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 5 + bounds_x = 185 + bounds_y = 0 + bounds_cx = 36 + bounds_cy = 37 + onchange = rgbchange + ondataentered = componentsdataentered + max = 255 + reffontheight = 14 + end + object green: tintegeredit + color = -2147483645 + frame.caption = '&green' + frame.captionpos = cp_top + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 1 + 17 + 2 + 0 + ) + taborder = 4 + bounds_x = 147 + bounds_y = 0 + bounds_cx = 39 + bounds_cy = 37 + onchange = rgbchange + ondataentered = componentsdataentered + max = 255 + reffontheight = 14 + end + object red: tintegeredit + color = -2147483645 + frame.caption = '&red' + frame.captionpos = cp_top + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 3 + bounds_x = 111 + bounds_y = 0 + bounds_cx = 36 + bounds_cy = 37 + onchange = rgbchange + ondataentered = componentsdataentered + max = 255 + reffontheight = 14 + end + object bright: tintegeredit + color = -2147483645 + frame.caption = '&BRI' + frame.captionpos = cp_top + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + bounds_x = 72 + bounds_y = 0 + bounds_cx = 36 + bounds_cy = 37 + onchange = hsbchange + ondataentered = componentsdataentered + max = 100 + reffontheight = 14 + end + object sat: tintegeredit + color = -2147483645 + frame.caption = '&SAT' + frame.captionpos = cp_top + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + bounds_x = 36 + bounds_y = 0 + bounds_cx = 36 + bounds_cy = 37 + onchange = hsbchange + ondataentered = componentsdataentered + max = 100 + reffontheight = 14 + end + object hue: tintegeredit + color = -2147483645 + frame.caption = '&HUE' + frame.captionpos = cp_top + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + bounds_x = 0 + bounds_y = 0 + bounds_cx = 36 + bounds_cy = 37 + onchange = hsbchange + ondataentered = componentsdataentered + max = 360 + reffontheight = 14 + end + end + object tlayouter2: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + bounds_x = 11 + bounds_y = 256 + bounds_cx = 324 + bounds_cy = 38 + anchors = [an_left, an_bottom] + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + font.name = 'stf_default' + font.localprops = [] + optionslayout = [lao_aligny] + align_glue = wam_start + linktop = tlayouter1 + options = [spao_gluebottom] + object cancel: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + color = -2147483645 + taborder = 3 + bounds_x = 272 + bounds_y = 17 + bounds_cx = 52 + bounds_cy = 21 + bounds_cxmin = 50 + state = [as_localcaption, as_localcolor] + caption = '&Cancel' + modalresult = mr_cancel + reffontheight = 14 + end + object ok: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + taborder = 2 + bounds_x = 216 + bounds_y = 17 + bounds_cx = 50 + bounds_cy = 21 + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + reffontheight = 14 + end + object colored: tcoloredit + frame.caption = 'Color' + frame.captionpos = cp_top + frame.localprops = [] + frame.localprops1 = [] + frame.buttonellipse.width = -1 + frame.buttonellipse.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + bounds_x = 102 + bounds_y = 0 + bounds_cx = 108 + bounds_cy = 37 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + onchange = colorchangeev + ondataentered = coloreddataentered + dropdown.options = [deo_autodropdown, deo_keydropdown, deo_cliphint] + reffontheight = 14 + end + object rgbed: tintegeredit + frame.caption = 'RGB' + frame.captionpos = cp_top + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + bounds_x = 32 + bounds_y = 0 + bounds_cx = 68 + bounds_cy = 37 + ondataentered = rgbeddataentered + base = nb_hex + bitcount = 24 + reffontheight = 14 + end + end + object tlayouter3: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + taborder = 2 + bounds_x = 112 + bounds_y = 0 + bounds_cx = 221 + bounds_cy = 219 + optionslayout = [lao_aligny] + align_mode = wam_start + object sliderblue: tslider + color = -2147483646 + frame.levelo = -1 + frame.colorclient = -2147483647 + frame.localprops = [frl_levelo, frl_fileft, frl_fitop, frl_firight, frl_fibottom, frl_colorclient] + frame.localprops1 = [] + taborder = 5 + bounds_x = 196 + bounds_y = 3 + bounds_cx = 15 + bounds_cy = 214 + anchors = [an_left, an_top, an_bottom] + ondataentered = componentsdataentered + value = 0 + scrollbar.face.image.transparentcolor = -2147483648 + scrollbar.face.fade_pos.count = 2 + scrollbar.face.fade_pos.items = ( + 0 + 1 + ) + scrollbar.face.fade_color.count = 2 + scrollbar.face.fade_color.items = ( + -1610612734 + -1610612727 + ) + scrollbar.face.fade_direction = gd_up + scrollbar.face.localprops = [fal_fadirection, fal_faopacity] + scrollbar.color = -2147483645 + scrollbar.colorpattern = -2147483642 + onsetvalue = blueonsetvalue + direction = gd_up + end + object slidergreen: tslider + color = -2147483646 + frame.levelo = -1 + frame.colorclient = -2147483647 + frame.localprops = [frl_levelo, frl_fileft, frl_fitop, frl_firight, frl_fibottom, frl_colorclient] + frame.localprops1 = [] + taborder = 4 + bounds_x = 160 + bounds_y = 3 + bounds_cx = 15 + bounds_cy = 214 + anchors = [an_left, an_top, an_bottom] + ondataentered = componentsdataentered + value = 0 + scrollbar.face.image.transparentcolor = -2147483648 + scrollbar.face.fade_pos.count = 2 + scrollbar.face.fade_pos.items = ( + 0 + 1 + ) + scrollbar.face.fade_color.count = 2 + scrollbar.face.fade_color.items = ( + -1610612734 + -1610612728 + ) + scrollbar.face.fade_direction = gd_up + scrollbar.face.localprops = [fal_fadirection, fal_faopacity] + scrollbar.color = -2147483645 + scrollbar.colorpattern = -2147483642 + onsetvalue = greenonsetvalue + direction = gd_up + end + object sliderred: tslider + color = -2147483646 + frame.levelo = -1 + frame.colorclient = -2147483647 + frame.localprops = [frl_levelo, frl_fileft, frl_fitop, frl_firight, frl_fibottom, frl_colorclient] + frame.localprops1 = [] + taborder = 3 + bounds_x = 124 + bounds_y = 3 + bounds_cx = 15 + bounds_cy = 214 + anchors = [an_left, an_top, an_bottom] + ondataentered = componentsdataentered + value = 0 + scrollbar.face.image.transparentcolor = -2147483648 + scrollbar.face.fade_pos.count = 2 + scrollbar.face.fade_pos.items = ( + 0 + 1 + ) + scrollbar.face.fade_color.count = 2 + scrollbar.face.fade_color.items = ( + -1610612734 + -1610612729 + ) + scrollbar.face.fade_direction = gd_up + scrollbar.face.localprops = [fal_fadirection, fal_faopacity] + scrollbar.color = -2147483645 + scrollbar.colorpattern = -2147483642 + onsetvalue = redonsetvalue + direction = gd_up + end + object sliderbright: tslider + color = -2147483646 + frame.levelo = -1 + frame.colorclient = -2147483647 + frame.localprops = [frl_levelo, frl_fileft, frl_fitop, frl_firight, frl_fibottom, frl_colorclient] + frame.localprops1 = [] + taborder = 2 + bounds_x = 83 + bounds_y = 3 + bounds_cx = 15 + bounds_cy = 214 + anchors = [an_left, an_top, an_bottom] + ondataentered = componentsdataentered + value = 0 + scrollbar.face.image.transparentcolor = -2147483648 + scrollbar.face.fade_pos.count = 2 + scrollbar.face.fade_pos.items = ( + 0 + 1 + ) + scrollbar.face.fade_color.count = 2 + scrollbar.face.fade_color.items = ( + -1610612734 + -1610612730 + ) + scrollbar.face.fade_direction = gd_up + scrollbar.face.localprops = [fal_fadirection, fal_faopacity] + scrollbar.color = -2147483645 + scrollbar.colorpattern = -2147483642 + onsetvalue = brightonsetvalue + direction = gd_up + end + object slidersat: tslider + color = -2147483646 + frame.levelo = -1 + frame.colorclient = -2147483647 + frame.localprops = [frl_levelo, frl_fileft, frl_fitop, frl_firight, frl_fibottom, frl_colorclient] + frame.localprops1 = [] + taborder = 1 + bounds_x = 48 + bounds_y = 3 + bounds_cx = 15 + bounds_cy = 214 + anchors = [an_left, an_top, an_bottom] + ondataentered = componentsdataentered + value = 0 + scrollbar.face.image.transparentcolor = -2147483648 + scrollbar.face.fade_pos.count = 2 + scrollbar.face.fade_pos.items = ( + 0 + 1 + ) + scrollbar.face.fade_color.count = 2 + scrollbar.face.fade_color.items = ( + -1610612730 + -1610612730 + ) + scrollbar.face.fade_direction = gd_up + scrollbar.face.localprops = [fal_fadirection, fal_faopacity] + scrollbar.color = -2147483645 + scrollbar.colorpattern = -2147483642 + onsetvalue = satonsetvalue + direction = gd_up + end + object sliderhue: tslider + color = -2147483646 + frame.levelo = -1 + frame.colorclient = -2147483647 + frame.localprops = [frl_levelo, frl_fileft, frl_fitop, frl_firight, frl_fibottom, frl_colorclient] + frame.localprops1 = [] + bounds_x = 12 + bounds_y = 3 + bounds_cx = 15 + bounds_cy = 214 + anchors = [an_left, an_top, an_bottom] + ondataentered = componentsdataentered + value = 0 + scrollbar.face.image.transparentcolor = -2147483648 + scrollbar.face.fade_pos.count = 7 + scrollbar.face.fade_pos.items = ( + 0 + 0.166666666 + 0.333333333 + 0.5 + 0.66666666 + 0.83333333 + 1 + ) + scrollbar.face.fade_color.count = 7 + scrollbar.face.fade_color.items = ( + -1610612729 + -1610612724 + -1610612728 + -1610612726 + -1610612727 + -1610612725 + -1610612729 + ) + scrollbar.face.fade_direction = gd_up + scrollbar.face.localprops = [fal_fadirection, fal_faopacity] + scrollbar.color = -2147483645 + scrollbar.colorpattern = -2147483642 + onsetvalue = hueonsetvalue + direction = gd_up + end + end + object gb: tgroupbox + optionswidget = [ow_parenttabfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + optionsskin = [osk_noskin] + color = -2147483645 + frame.localprops = [frl_levelo, frl_leveli] + frame.localprops1 = [] + taborder = 3 + bounds_x = 3 + bounds_y = 3 + bounds_cx = 100 + bounds_cy = 209 + anchors = [an_left, an_top, an_bottom] + end + object tstatfile1: tstatfile + filename = 'colordialog.sta' + options = [sfo_memory] + left = 24 + top = 104 + end +end diff --git a/mseide-msegui/lib/common/dialogs/msecolordialog.pas b/mseide-msegui/lib/common/dialogs/msecolordialog.pas new file mode 100644 index 0000000..3aefe75 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msecolordialog.pas @@ -0,0 +1,952 @@ +{ MSEgui Copyright (c) 1999-2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msecolordialog; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msegui,mseclasses,mseforms,msegraphedits,msewidgets,msesimplewidgets, + msedataedits,msegraphics,mseglob,mseguiglob,msedialog,classes,mclasses, + msetypes,msedropdownlist,msegrids,msestrings,mseedit,msestat,msestatfile, + msegraphutils,msemenus,mseevent,mseificomp,mseificompglob,mseifiglob, + msesplitter,msedispwidgets,mserichstring,msescrollbar; + +const + colordialogstatname = 'colordialog.sta'; + +type + + coloreventty = procedure(const sender: tobject; + const avalue: colorty) of object; + setcoloreventty = procedure(const sender: tobject; var avalue: colorty; + var accept: boolean) of object; + + tellipsedropdownbuttonframe = class(tdropdownmultibuttonframe) + private + function getbuttonellipse: tdropdownbutton; + procedure setbuttonellipse(const avalue: tdropdownbutton); + public + constructor create(const aintf: icaptionframe; + const buttonintf: ibutton); override; + published + property buttonellipse: tdropdownbutton read getbuttonellipse + write setbuttonellipse; + end; + + colordialogoptionty = (cdo_rgbtext); + colordialogoptionsty = set of colordialogoptionty; + + coloreditoptionty = (ceo_rgbtext); + coloreditoptionsty = set of coloreditoptionty; + + tcustomcoloredit = class(tcustomenumedit) + private + foncolorchange: coloreventty; + foptions: coloreditoptionsty; + function getvalue: colorty; + procedure setvalue(avalue: colorty); + function getvaluedefault: colorty; + procedure setvaluedefault(avalue: colorty); + + function getonsetvalue: setcoloreventty; + procedure setonsetvalue(const avalue: setcoloreventty); + function getframe: tellipsedropdownbuttonframe; + procedure setframe(const avalue: tellipsedropdownbuttonframe); + function getgridvalue(const index: integer): colorty; + procedure setgridvalue(const index: integer; const avalue: colorty); + function getgridvalues: colorarty; + procedure setgridvalues(const avalue: colorarty); + procedure setoptions(const avalue: coloreditoptionsty); + protected + procedure setvaluedata(const source); override; + procedure getvaluedata(out dest); override; + function internaldatatotext1( + const avalue: integer): msestring; virtual; + function internaldatatotext(const data): msestring; override; + function createdropdowncontroller: tcustomdropdowncontroller; override; + procedure texttovalue(var accept: boolean; const quiet: boolean); override; + procedure paintimage(const canvas: tcanvas); override; + function geteditframe: framety; override; + procedure colorenter(const acolor: colorty); + procedure buttonaction(var action: buttonactionty; + const buttonindex: integer); override; + procedure dochange(); override; + procedure docolorchange(const sender: tobject; const acolor: colorty); + public + constructor create(aowner: tcomponent); override; + property value: colorty read getvalue write setvalue default cl_none; + property valuedefault: colorty read getvaluedefault + write setvaluedefault default cl_none; + property options: coloreditoptionsty read foptions + write setoptions default []; + property frame: tellipsedropdownbuttonframe read getframe write setframe; + property gridvalue[const index: integer]: colorty + read getgridvalue write setgridvalue; default; + property gridvalues: colorarty read getgridvalues write setgridvalues; + property onsetvalue: setcoloreventty read getonsetvalue write setonsetvalue; + property oncolorchange: coloreventty read foncolorchange + write foncolorchange; + //sender is tcolordialogfo or tcustomcoloredit + end; + + tcoloredit = class(tcustomcoloredit) + published + property value; + property valuedefault; + property options; +{$ifdef mse_with_ifi} + property ifilink; +{$endif} + property dropdown; + property onsetvalue; + property oncolorchange; + property frame; + end; + + tcolordialogfo = class(tmseform) + tstatfile1: tstatfile; + tlayouter1: tlayouter; + blue: tintegeredit; + green: tintegeredit; + red: tintegeredit; + bright: tintegeredit; + sat: tintegeredit; + hue: tintegeredit; + tlayouter2: tlayouter; + cancel: tbutton; + ok: tbutton; + colored: tcoloredit; + rgbed: tintegeredit; + tlayouter3: tlayouter; + sliderblue: tslider; + slidergreen: tslider; + sliderred: tslider; + sliderbright: tslider; + slidersat: tslider; + sliderhue: tslider; + gb: tgroupbox; + colorareabefore: tpaintbox; + colorarea: tpaintbox; + colorpibu: tdatabutton; + procedure hueonsetvalue(const sender: TObject; var avalue: realty; + var accept: Boolean); + procedure satonsetvalue(const sender: TObject; var avalue: realty; + var accept: Boolean); + procedure brightonsetvalue(const sender: TObject; var avalue: realty; + var accept: Boolean); + procedure hsbchange(const sender: TObject); + procedure redonsetvalue(const sender: TObject; var avalue: realty; + var accept: Boolean); + procedure greenonsetvalue(const sender: TObject; var avalue: realty; + var accept: Boolean); + procedure blueonsetvalue(const sender: TObject; var avalue: realty; + var accept: Boolean); + procedure rgbchange(const sender: TObject); + procedure componentsdataentered(const sender: TObject); + procedure layoutexe(const sender: TObject); + procedure rgbeddataentered(const sender: TObject); + procedure coloreddataentered(const sender: TObject); + procedure loadedexe(const sender: TObject); + procedure colorpickexe(const sender: TObject); + procedure mouseeventexe(const sender: twidget; var ainfo: mouseeventinfoty); + procedure shortcutexe(const sender: twidget; var ainfo: keyeventinfoty; + const origin: twidget); + procedure colorchangeev(const sender: TObject); + private + fupdating: boolean; + foncolorchange: coloreventty; + procedure updatecomponents; + protected + fcolorpicking: boolean; + fcolorbefore: colorty; + procedure begincolorpick(); + procedure endcolorpick(); + procedure dochange(); + published + property oncolorchange: coloreventty read foncolorchange + write foncolorchange; + end; + + tcolordropdowncontroller = class(tnocolsdropdownlistcontroller) + protected + fcolorvalues: colorarty; + function getbuttonframeclass: dropdownbuttonframeclassty; override; + function getfixcolclass: dropdownfixcolclassty; override; + public + constructor create(const intf: idropdownlist); + published + property options default defaultautodropdownoptions; + end; + +function colordialog(var acolor: colorty; + const aoncolorchange: coloreventty = nil; + const aoptions: colordialogoptionsty = []): modalresultty; +//threadsafe +procedure paintcolorimage(const sender: twidget; const canvas: tcanvas; + const acolor: colorty); +procedure paintcolorrect(const canvas: tcanvas; const arect: rectty; + const acolor: colorty); + +implementation +uses + msecolordialog_mfm,msestockobjects,mseformatstr,sysutils,msepointer, + msekeyboard,mseguiintf,mseeditglob; +type + twidget1 = class(twidget); + + tcolorfixcol = class(tdropdownfixcol) + protected + ficonrect: rectty; + procedure drawcell(const canvas: tcanvas); override; + public + constructor create(const agrid: tcustomgrid; + const aowner: tgridarrayprop; + const acontroller: tcustomdropdownlistcontroller); override; + end; + +function colordialog(var acolor: colorty; + const aoncolorchange: coloreventty = nil; + const aoptions: colordialogoptionsty = []): modalresultty; +var + fo: tcolordialogfo; + col1: rgbtriplety; +begin + application.lock; + try + fo:= tcolordialogfo.create(nil); + fo.oncolorchange:= aoncolorchange; + fo.colored.options:= coloreditoptionsty(aoptions); + try + try + col1:= colortorgb(acolor); + fo.colored.value:= acolor; + except + fillchar(col1,sizeof(col1),0); + fo.colored.value:= 0; + end; + fo.rgbed.value:= integer(col1); + fo.colorareabefore.frame.colorclient:= colorty(col1); + fo.red.value:= col1.red; + fo.green.value:= col1.green; + fo.blue.value:= col1.blue; + result:= fo.show(true); + if result = mr_ok then begin + acolor:= fo.colored.value; + end + else begin + if fo.canevent(tmethod(aoncolorchange)) then begin + aoncolorchange(fo,acolor); + end; + end; + finally + fo.free; + end; + finally + application.unlock; + end; +end; + +{ tellipsedropdownbuttonframe } + +constructor tellipsedropdownbuttonframe.create(const aintf: icaptionframe; + const buttonintf: ibutton); +begin + inherited; + buttons.count:= 2; + buttons[1].assign(buttons[0]); + buttons[1].imagenr:= ord(stg_ellipsesmall); + buttons[0].imagenr:= ord(stg_arrowdownsmall); + activebutton:= 0; +end; + +function tellipsedropdownbuttonframe.getbuttonellipse: tdropdownbutton; +begin + result:= tdropdownbutton(buttons[1]); +end; + +procedure tellipsedropdownbuttonframe.setbuttonellipse( + const avalue: tdropdownbutton); +begin + buttons[1].assign(avalue); +end; + +{ tcolorfixcol } + +constructor tcolorfixcol.create(const agrid: tcustomgrid; + const aowner: tgridarrayprop; + const acontroller: tcustomdropdownlistcontroller); +begin + inherited; + width:= agrid.datarowheight; + ficonrect.x:= 1; + ficonrect.y:= 1; + ficonrect.cy:= width - 2; + ficonrect.cx:= ficonrect.cy; +end; + +procedure tcolorfixcol.drawcell(const canvas: tcanvas); +begin + inherited; + with cellinfoty(canvas.drawinfopo^) do begin + paintcolorrect(canvas,ficonrect, + tcolordropdowncontroller(fcontroller).fcolorvalues[cell.row]); + end; +end; + +{ tcolordropdowncontroller } + +constructor tcolordropdowncontroller.create(const intf: idropdownlist); +//var +// int1: integer; +begin + inherited; + valuelist.asarray:= getcolornames; + fcolorvalues:= getcolorvalues; + { + for int1:= 0 to high(fcolorvalues) do begin + fcolorvalues[int1]:= colorty(colortorgb(fcolorvalues[int1])); + end; + } + options:= defaultautodropdownoptions; +end; + +function tcolordropdowncontroller.getbuttonframeclass(): + dropdownbuttonframeclassty; +begin + result:= tellipsedropdownbuttonframe; +end; + +function tcolordropdowncontroller.getfixcolclass: dropdownfixcolclassty; +begin + result:= tcolorfixcol; +end; + +{ tcustomcoloredit } + +constructor tcustomcoloredit.create(aowner: tcomponent); +begin + inherited; + enums:= integerarty(getcolorvalues); + valuemin:= minint; + base:= nb_hex; + valuedefault:= cl_none; + value:= valuedefault; +end; + +function tcustomcoloredit.createdropdowncontroller: tcustomdropdowncontroller; +begin + result:= tcolordropdowncontroller.create(idropdownlist(self)); +end; + +procedure tcustomcoloredit.texttovalue(var accept: boolean; + const quiet: boolean); +var + co1: colorty; + int1: integer; + mstr1: msestring; +begin + if trim(text) = '' then begin + co1:= valuedefault; + end + else begin + int1:= tdropdownlistcontroller(fdropdown).itemindex; + if (int1 >= 0) and (int1 <= high(enums)) then begin + co1:= enums[int1]; + end + else begin + mstr1:= feditor.text; + checktext(mstr1,accept); + if not accept then begin + exit; + end; + if not trystringtocolor(ansistring(mstr1),co1) then begin + accept:= false; + formaterror(quiet); + end; + end; + end; + if accept then begin + if not quiet and canevent(tmethod(fonsetvalue1)) then begin + fonsetvalue1(self,integer(co1),accept); + end; + if accept then begin + value:= co1; + end; + end; +end; + +procedure tcustomcoloredit.colorenter(const acolor: colorty); +begin + tcolordropdowncontroller(fdropdown).resetselection; + text:= msestring(colortostring(acolor)); + checkvalue(); +end; + +procedure tcustomcoloredit.buttonaction(var action: buttonactionty; + const buttonindex: integer); +var + co1: colorty; +begin + if buttonindex = 1 then begin + case action of + ba_buttonpress: begin + if canfocus then begin + setfocus; + end; + end; + ba_click: begin + if focused then begin + co1:= value; + if colordialog(co1, + @docolorchange,colordialogoptionsty(options)) = mr_ok then begin + colorenter(co1); + end; + end; + end; + end; + end; +end; + +function tcustomcoloredit.internaldatatotext1(const avalue: integer): msestring; +begin + if ceo_rgbtext in foptions then begin + result:= msestring(colortostring(colorty(colortorgb(avalue)))); + end + else begin + result:= msestring(colortostring(avalue)); + end; +end; + +function tcustomcoloredit.internaldatatotext(const data): msestring; +var + int1: integer; +begin + if @data = nil then begin + int1:= fvalue1; + end + else begin + int1:= integer(data); + end; + result:= internaldatatotext1(int1); +end; + +function tcustomcoloredit.getvalue: colorty; +begin + result:= inherited value; +end; + +procedure tcustomcoloredit.setvalue(avalue: colorty); +begin + if avalue = cl_invalid then begin + avalue:= cl_none; + end; + inherited value:= avalue; +end; + +function tcustomcoloredit.getvaluedefault: colorty; +begin + result:= inherited valuedefault; +end; + +procedure tcustomcoloredit.setvaluedefault(avalue: colorty); +begin + if avalue = cl_invalid then begin + avalue:= cl_none; + end; + inherited valuedefault:= avalue; +end; + +function tcustomcoloredit.getonsetvalue: setcoloreventty; +begin + result:= setcoloreventty(inherited onsetvalue); +end; + +procedure tcustomcoloredit.setonsetvalue(const avalue: setcoloreventty); +begin + inherited onsetvalue:= setintegereventty(avalue); +end; + +function tcustomcoloredit.getframe: tellipsedropdownbuttonframe; +begin + result:= tellipsedropdownbuttonframe(inherited frame); +end; + +procedure tcustomcoloredit.setframe(const avalue: tellipsedropdownbuttonframe); +begin + inherited frame:= avalue; +end; + +function tcustomcoloredit.getgridvalue(const index: integer): colorty; +begin + result:= inherited gridvalue[index]; +end; + +procedure tcustomcoloredit.setgridvalue(const index: integer; + const avalue: colorty); +begin + inherited gridvalue[index]:= avalue; +end; + +function tcustomcoloredit.getgridvalues: colorarty; +begin + result:= colorarty(inherited gridvalues); +end; + +procedure tcustomcoloredit.setgridvalues(const avalue: colorarty); +begin + inherited gridvalues:= integerarty(avalue); +end; + +procedure tcustomcoloredit.setoptions(const avalue: coloreditoptionsty); +begin + if avalue <> foptions then begin + foptions:= avalue; + formatchanged(); + end; +end; + +function tcustomcoloredit.geteditframe: framety; +begin + result.left:= innerclientsize.cy + 1; + result.right:= 0; + result.top:= 0; + result.bottom:= 0; +end; + +procedure tcustomcoloredit.paintimage(const canvas: tcanvas); +var + co1: colorty; +begin + if canvas.drawinfopo <> nil then begin + with cellinfoty(canvas.drawinfopo^) do begin + co1:= pcolorty(datapo)^; + end; + end + else begin + co1:= value; + end; + paintcolorimage(self,canvas,co1); +end; + +procedure tcustomcoloredit.dochange(); +begin + inherited; + invalidate(); + if not (des_updating in fstate) then begin + if canevent(tmethod(foncolorchange)) then begin + include(fstate,des_updating); + try + foncolorchange(self,value); + finally + exclude(fstate,des_updating); + end; + end; + end; +end; + +procedure tcustomcoloredit.docolorchange(const sender: tobject; + const acolor: colorty); +begin //callback from colordialog + if not (des_updating in fstate) then begin + include(fstate,des_updating); + try + if oe1_thumbtrack in optionsedit1 then begin + colorenter(acolor); + if canevent(tmethod(foncolorchange)) then begin + foncolorchange(sender,value); + end; + end + else begin + if canevent(tmethod(foncolorchange)) then begin + foncolorchange(sender,acolor); + end; + end; + finally + exclude(fstate,des_updating); + end; + end; +end; + +procedure tcustomcoloredit.setvaluedata(const source); +begin + value:= colorty(source); +end; + +procedure tcustomcoloredit.getvaluedata(out dest); +begin + colorty(dest):= value; +end; + +procedure paintcolorrect(const canvas: tcanvas; const arect: rectty; + const acolor: colorty); +var + co1: colorty; +begin + canvas.fillrect(arect,colorty(colortorgb(acolor))); + co1:= cl_black; + if acolor and speccolormask = cl_functional then begin + co1:= cl_gray; + end; + canvas.drawrect(arect,co1); +end; + +procedure paintcolorimage(const sender: twidget; const canvas: tcanvas; + const acolor: colorty); +var + rect1: rectty; +begin + with sender do begin + if canvas.drawinfopo <> nil then begin + with cellinfoty(canvas.drawinfopo^) do begin + rect1:= innerrect; + end; + end + else begin + rect1:= innerclientrect; + end; + rect1.x:= 1; + dec(rect1.cy); + rect1.cx:= rect1.cy; + paintcolorrect(canvas,rect1,acolor); + { + canvas.fillrect(rect1,colorty(colortorgb(acolor))); + co1:= cl_black; + if acolor and speccolormask = cl_functional then begin + co1:= cl_gray; + end; + canvas.drawrect(rect1,co1); + } + end; +end; + +{ tcolordialogfo } + +procedure tcolordialogfo.hueonsetvalue(const sender: TObject; + var avalue: realty; var accept: Boolean); +begin + hue.value:= round(avalue * 360); +end; + +procedure tcolordialogfo.satonsetvalue(const sender: TObject; + var avalue: realty; var accept: Boolean); +begin + sat.value:= round(avalue * 100); +end; + +procedure tcolordialogfo.brightonsetvalue(const sender: TObject; + var avalue: realty; var accept: Boolean); +begin + bright.value:= round(avalue * 100); +end; + +procedure tcolordialogfo.hsbchange(const sender: TObject); +var + r,g,b: real; + r1,g1,b1: integer; + int1: integer; + rea1,rea2: real; +begin + int1:= hue.value; + r:= 0; + g:= 0; + b:= 0; + if int1 < 60 then begin + r:= 60; + g:= int1; + end + else begin + if int1 < 120 then begin + r:= 120 - int1; + g:= 60; + end + else begin + if int1 < 180 then begin + g:= 60; + b:= int1 - 120; + end + else begin + if int1 < 240 then begin + g:= 240 - int1; + b:= 60 + end + else begin + if int1 < 300 then begin + b:= 60; + r:= int1 - 240; + end + else begin + b:= 360 - int1; + r:= 60; + end; + end; + end; + end; + end; + r1:= round(r*255/60); + g1:= round(g*255/60); + b1:= round(b*255/60); + slidersat.scrollbar.face.fade_color[1]:= rgbtocolor(r1,g1,b1); + rea1:= sat.value / 100; + rea2:= 1-rea1; + rea1:= rea1 / 60; + r:= r * rea1 + rea2; + g:= g * rea1 + rea2; + b:= b * rea1 + rea2; + r1:= round(r*255); + g1:= round(g*255); + b1:= round(b*255); + sliderbright.scrollbar.face.fade_color[1]:= rgbtocolor(r1,g1,b1); + rea1:= bright.value / 100; + r:= r*rea1; + g:= g*rea1; + b:= b*rea1; + sliderhue.value:= hue.value/360; + slidersat.value:= sat.value/100; + sliderbright.value:= bright.value/100; + if not fupdating then begin + fupdating:= true; + red.value:= round(r*255); + green.value:= round(g*255); + blue.value:= round(b*255); + fupdating:= false; + end; +end; + +procedure tcolordialogfo.blueonsetvalue(const sender: TObject; + var avalue: realty; var accept: Boolean); +begin + blue.value:= round(avalue * 255); +end; + +procedure tcolordialogfo.greenonsetvalue(const sender: TObject; + var avalue: realty; var accept: Boolean); +begin + green.value:= round(avalue * 255); +end; + +procedure tcolordialogfo.redonsetvalue(const sender: TObject; + var avalue: realty; var accept: Boolean); +begin + red.value:= round(avalue * 255); +end; + + +procedure tcolordialogfo.rgbchange(const sender: TObject); + +type + colorsegmentty = (cs_red,cs_green,cs_blue); +var + min,max: integer; +// r1,g1,b1: integer; + br,sa,hu: real; + segment: colorsegmentty; + + function calchue(l,c,r: integer): real; //range -1 .. +1, 0-> center + begin + if c > min then begin + if l > r then begin + result:= -(l-min)/(c-min); + end + else begin + result:= (r-min)/(c-min); + end; + end + else begin + result:= 0; + end; + end; + +begin + colorarea.frame.colorclient:= rgbtocolor(red.value,green.value,blue.value); + sliderred.value:= red.value / 255; + slidergreen.value:= green.value / 255; + sliderblue.value:= blue.value / 255; + if not fupdating then begin + fupdating:= true; + max:= 0; + segment:= cs_red; + if red.value > max then begin + max:= red.value; + end; + if green.value > max then begin + max:= green.value; + segment:= cs_green; + end; + if blue.value > max then begin + max:= blue.value; + segment:= cs_blue; + end; + min:= 255; + if red.value < min then begin + min:= red.value; + end; + if green.value < min then begin + min:= green.value; + end; + if blue.value < min then begin + min:= blue.value; + end; + br:= max/255; + if br > 0 then begin + sa:= 1-min/(255*br); + if sa < 0 then begin + sa:= 0; + end; + end + else begin + sa:= 0 + end; + bright.value:= round(br*100); + sat.value:= round(sa*100); + case segment of + cs_red: begin + hu:= calchue(blue.value,red.value,green.value); + hue.value:= (round(hu*60)+360) mod 360; + end; + cs_green: begin + hu:= calchue(red.value,green.value,blue.value); + hue.value:= round(hu*60) + 120; + end; + cs_blue: begin + hu:= calchue(green.value,blue.value,red.value); + hue.value:= (round(hu*60) + 240) mod 360; + end; + end; + fupdating:= false; + end; +end; + +procedure tcolordialogfo.updatecomponents; +var + rgb1: rgbtriplety; +begin + if not fupdating then begin + fupdating:= true; + rgb1:= rgbtriplety(rgbed.value); + red.value:= rgb1.red; + green.value:= rgb1.green; + blue.value:= rgb1.blue; + fupdating:= false; + rgbchange(nil); + end; +end; + +procedure tcolordialogfo.componentsdataentered(const sender: TObject); +begin + rgbed.value:= integer(rgbtocolor(red.value,green.value,blue.value)); + colored.value:= rgbed.value; +end; + +procedure tcolordialogfo.layoutexe(const sender: TObject); +begin + gb.height:= sliderhue.height; + colorareabefore.frameheight:= gb.height; + colorarea.frameheight:= gb.height; + aligny(wam_center,[hue,colorpibu]); +end; + +procedure tcolordialogfo.rgbeddataentered(const sender: TObject); +begin + colored.value:= colorty(rgbed.value); + updatecomponents; +end; + +procedure tcolordialogfo.coloreddataentered(const sender: TObject); +begin + rgbed.value:= integer(colortorgb(colored.value)); + updatecomponents; +end; + +procedure tcolordialogfo.loadedexe(const sender: TObject); +begin + colored.activate; +end; + +procedure tcolordialogfo.colorpickexe(const sender: TObject); +begin + begincolorpick(); +end; + +procedure tcolordialogfo.begincolorpick(); +begin + fcolorbefore:= colored.value; + capturemouse(true); + application.cursorshape:= cr_pointinghand; + colorpibu.value:= 0; + colorpibu.createfont; + with colorpibu.font do begin + color:= cl_red; + shadow_color:= cl_white; + end; + fcolorpicking:= true; +end; + +procedure tcolordialogfo.endcolorpick(); +begin + releasemouse(true); + fcolorpicking:= false; + colorpibu.value:= -1; + application.cursorshape:= cr_default; + colorpibu.font:= nil; +end; + +procedure tcolordialogfo.dochange(); +begin + if canevent(tmethod(foncolorchange)) then begin + foncolorchange(self,colored.value); + end; +end; + +procedure tcolordialogfo.mouseeventexe(const sender: twidget; + var ainfo: mouseeventinfoty); +var + px1: pixelty; + co1: colorty; +begin + if fcolorpicking then begin + if (ainfo.eventkind in [ek_buttonpress,ek_mousemove]) and + (ainfo.shiftstate * buttonshiftstatesmask = [ss_left]) then begin + if gui_getpixel(gui_getrootwindow(window.winid), + translatewidgetpoint(ainfo.pos,self,nil),px1) = gue_ok then begin + co1:= gui_pixeltorgb(px1); + if colored.value <> co1 then begin + colored.value:= co1; + colored.checkvalue(); + end; + end; + end + else begin + if (ainfo.eventkind = ek_buttonrelease) then begin + endcolorpick(); + end; + end; + end; +end; + +procedure tcolordialogfo.shortcutexe(const sender: twidget; + var ainfo: keyeventinfoty; const origin: twidget); +begin + if fcolorpicking then begin + if ainfo.key = key_escape then begin + endcolorpick(); + colored.value:= fcolorbefore; + colored.checkvalue(); + end; + include(ainfo.eventstate,es_processed); + end; +end; + +procedure tcolordialogfo.colorchangeev(const sender: TObject); +begin + dochange(); +end; + +end. diff --git a/mseide-msegui/lib/common/dialogs/msecolordialog_mfm.pas b/mseide-msegui/lib/common/dialogs/msecolordialog_mfm.pas new file mode 100644 index 0000000..c6f9b66 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msecolordialog_mfm.pas @@ -0,0 +1,542 @@ +unit msecolordialog_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msecolordialog; + +const + objdata: record size: integer; data: array[0..10490] of byte end = + (size: 10491; data: ( + 84,80,70,48,14,116,99,111,108,111,114,100,105,97,108,111,103,102,111,13, + 99,111,108,111,114,100,105,97,108,111,103,102,111,7,118,105,115,105,98,108, + 101,8,8,98,111,117,110,100,115,95,120,3,140,0,8,98,111,117,110,100, + 115,95,121,3,234,0,9,98,111,117,110,100,115,95,99,120,3,82,1,9, + 98,111,117,110,100,115,95,99,121,3,42,1,26,99,111,110,116,97,105,110, + 101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 0,27,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,18,99,111,110,116,97,105,110,101, + 114,46,111,110,108,97,121,111,117,116,7,9,108,97,121,111,117,116,101,120, + 101,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2, + 0,2,0,3,82,1,3,42,1,0,10,111,110,115,104,111,114,116,99,117, + 116,7,11,115,104,111,114,116,99,117,116,101,120,101,7,111,112,116,105,111, + 110,115,11,13,102,111,95,99,108,111,115,101,111,110,101,115,99,17,102,111, + 95,108,111,99,97,108,115,104,111,114,116,99,117,116,115,15,102,111,95,97, + 117,116,111,114,101,97,100,115,116,97,116,16,102,111,95,97,117,116,111,119, + 114,105,116,101,115,116,97,116,10,102,111,95,115,97,118,101,112,111,115,0, + 8,115,116,97,116,102,105,108,101,7,10,116,115,116,97,116,102,105,108,101, + 49,7,99,97,112,116,105,111,110,6,12,83,101,108,101,99,116,32,67,111, + 108,111,114,8,111,110,108,111,97,100,101,100,7,9,108,111,97,100,101,100, + 101,120,101,12,111,110,109,111,117,115,101,101,118,101,110,116,7,13,109,111, + 117,115,101,101,118,101,110,116,101,120,101,8,111,110,108,97,121,111,117,116, + 7,9,108,97,121,111,117,116,101,120,101,15,109,111,100,117,108,101,99,108, + 97,115,115,110,97,109,101,6,8,116,109,115,101,102,111,114,109,0,11,116, + 100,97,116,97,98,117,116,116,111,110,9,99,111,108,111,114,112,105,98,117, + 14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49, + 95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,13,111,119,49, + 95,97,117,116,111,115,99,97,108,101,13,111,119,49,95,97,117,116,111,119, + 105,100,116,104,0,8,116,97,98,111,114,100,101,114,2,6,8,98,111,117, + 110,100,115,95,120,2,4,8,98,111,117,110,100,115,95,121,3,237,0,9, + 98,111,117,110,100,115,95,99,120,2,97,9,98,111,117,110,100,115,95,99, + 121,2,18,12,98,111,117,110,100,115,95,99,120,109,105,110,2,97,7,97, + 110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,9,97,110,95,98, + 111,116,116,111,109,0,5,115,116,97,116,101,11,17,97,115,95,108,111,99, + 97,108,105,110,118,105,115,105,98,108,101,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120, + 101,99,117,116,101,0,16,118,97,108,117,101,102,97,99,101,115,46,99,111, + 117,110,116,2,1,16,118,97,108,117,101,102,97,99,101,115,46,105,116,101, + 109,115,14,1,14,102,97,100,101,95,112,111,115,46,99,111,117,110,116,2, + 3,14,102,97,100,101,95,112,111,115,46,105,116,101,109,115,1,2,0,5, + 32,226,86,222,146,80,67,218,253,63,2,1,0,16,102,97,100,101,95,99, + 111,108,111,114,46,99,111,117,110,116,2,3,16,102,97,100,101,95,99,111, + 108,111,114,46,105,116,101,109,115,1,4,0,200,255,0,4,161,235,255,0, + 4,92,170,242,0,0,14,102,97,100,101,95,100,105,114,101,99,116,105,111, + 110,7,7,103,100,95,100,111,119,110,10,108,111,99,97,108,112,114,111,112, + 115,11,15,102,97,108,95,102,97,100,105,114,101,99,116,105,111,110,0,0, + 0,7,99,97,112,116,105,111,110,6,13,67,111,108,111,114,32,38,80,105, + 99,107,101,114,9,111,110,101,120,101,99,117,116,101,7,12,99,111,108,111, + 114,112,105,99,107,101,120,101,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,14,0,0,9,116,112,97,105,110,116,98,111,120,9,99,111,108, + 111,114,97,114,101,97,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 5,99,111,108,111,114,4,3,0,0,128,13,102,114,97,109,101,46,111,112, + 116,105,111,110,115,11,17,99,102,111,95,99,97,112,116,105,111,110,110,111, + 99,108,105,112,0,16,102,114,97,109,101,46,99,111,108,111,114,102,114,97, + 109,101,4,2,0,0,160,17,102,114,97,109,101,46,99,111,108,111,114,99, + 108,105,101,110,116,4,18,0,0,144,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,3,110,101,119,16,102,114,97,109,101,46,99,97,112,116, + 105,111,110,112,111,115,7,9,99,112,95,98,111,116,116,111,109,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,14,102,114,108,95, + 99,111,108,111,114,102,114,97,109,101,15,102,114,108,95,99,111,108,111,114, + 99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102, + 114,97,109,101,1,2,0,2,0,2,0,2,17,0,8,116,97,98,111,114, + 100,101,114,2,5,8,98,111,117,110,100,115,95,120,2,51,8,98,111,117, + 110,100,115,95,121,2,3,9,98,111,117,110,100,115,95,99,120,2,50,9, + 98,111,117,110,100,115,95,99,121,3,226,0,7,97,110,99,104,111,114,115, + 11,7,97,110,95,108,101,102,116,6,97,110,95,116,111,112,9,97,110,95, + 98,111,116,116,111,109,0,0,0,9,116,112,97,105,110,116,98,111,120,15, + 99,111,108,111,114,97,114,101,97,98,101,102,111,114,101,13,111,112,116,105, + 111,110,115,119,105,100,103,101,116,11,17,111,119,95,100,101,115,116,114,111, + 121,119,105,100,103,101,116,115,0,5,99,111,108,111,114,4,3,0,0,128, + 13,102,114,97,109,101,46,111,112,116,105,111,110,115,11,17,99,102,111,95, + 99,97,112,116,105,111,110,110,111,99,108,105,112,0,16,102,114,97,109,101, + 46,99,111,108,111,114,102,114,97,109,101,4,2,0,0,160,17,102,114,97, + 109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,12,0,0,144,13, + 102,114,97,109,101,46,99,97,112,116,105,111,110,6,3,111,108,100,16,102, + 114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7,9,99,112,95, + 98,111,116,116,111,109,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,14,102,114,108,95,99,111,108,111,114,102,114,97,109,101,15, + 102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2,0, + 2,17,0,8,116,97,98,111,114,100,101,114,2,4,8,98,111,117,110,100, + 115,95,120,2,3,8,98,111,117,110,100,115,95,121,2,3,9,98,111,117, + 110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,3,226, + 0,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97, + 110,95,116,111,112,9,97,110,95,98,111,116,116,111,109,0,0,0,9,116, + 108,97,121,111,117,116,101,114,10,116,108,97,121,111,117,116,101,114,49,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,11,111,119,95,116,97, + 98,102,111,99,117,115,17,111,119,95,112,97,114,101,110,116,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111, + 99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116, + 115,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115, + 95,120,2,112,8,98,111,117,110,100,115,95,121,3,219,0,9,98,111,117, + 110,100,115,95,99,120,3,221,0,9,98,111,117,110,100,115,95,99,121,2, + 37,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,9,97, + 110,95,98,111,116,116,111,109,0,12,111,112,116,105,111,110,115,115,99,97, + 108,101,11,11,111,115,99,95,101,120,112,97,110,100,120,11,111,115,99,95, + 115,104,114,105,110,107,120,11,111,115,99,95,101,120,112,97,110,100,121,11, + 111,115,99,95,115,104,114,105,110,107,121,17,111,115,99,95,101,120,112,97, + 110,100,115,104,114,105,110,107,120,17,111,115,99,95,101,120,112,97,110,100, + 115,104,114,105,110,107,121,0,7,108,105,110,107,116,111,112,7,10,116,108, + 97,121,111,117,116,101,114,51,10,108,105,110,107,98,111,116,116,111,109,7, + 10,116,108,97,121,111,117,116,101,114,50,7,111,112,116,105,111,110,115,11, + 15,115,112,97,111,95,103,108,117,101,98,111,116,116,111,109,0,0,12,116, + 105,110,116,101,103,101,114,101,100,105,116,4,98,108,117,101,5,99,111,108, + 111,114,4,3,0,0,128,13,102,114,97,109,101,46,99,97,112,116,105,111, + 110,6,5,38,98,108,117,101,16,102,114,97,109,101,46,99,97,112,116,105, + 111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8, + 116,97,98,111,114,100,101,114,2,5,8,98,111,117,110,100,115,95,120,3, + 185,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,2,36,9,98,111,117,110,100,115,95,99,121,2,37,8,111,110, + 99,104,97,110,103,101,7,9,114,103,98,99,104,97,110,103,101,13,111,110, + 100,97,116,97,101,110,116,101,114,101,100,7,21,99,111,109,112,111,110,101, + 110,116,115,100,97,116,97,101,110,116,101,114,101,100,3,109,97,120,3,255, + 0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,12, + 116,105,110,116,101,103,101,114,101,100,105,116,5,103,114,101,101,110,5,99, + 111,108,111,114,4,3,0,0,128,13,102,114,97,109,101,46,99,97,112,116, + 105,111,110,6,6,38,103,114,101,101,110,16,102,114,97,109,101,46,99,97, + 112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109, + 101,46,111,117,116,101,114,102,114,97,109,101,1,2,1,2,17,2,2,2, + 0,0,8,116,97,98,111,114,100,101,114,2,4,8,98,111,117,110,100,115, + 95,120,3,147,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,120,2,39,9,98,111,117,110,100,115,95,99,121,2,37, + 8,111,110,99,104,97,110,103,101,7,9,114,103,98,99,104,97,110,103,101, + 13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,21,99,111,109,112, + 111,110,101,110,116,115,100,97,116,97,101,110,116,101,114,101,100,3,109,97, + 120,3,255,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,3,114,101,100,5, + 99,111,108,111,114,4,3,0,0,128,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,4,38,114,101,100,16,102,114,97,109,101,46,99,97,112, + 116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101, + 46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0, + 0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117,110,100,115,95, + 120,2,111,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100, + 115,95,99,120,2,36,9,98,111,117,110,100,115,95,99,121,2,37,8,111, + 110,99,104,97,110,103,101,7,9,114,103,98,99,104,97,110,103,101,13,111, + 110,100,97,116,97,101,110,116,101,114,101,100,7,21,99,111,109,112,111,110, + 101,110,116,115,100,97,116,97,101,110,116,101,114,101,100,3,109,97,120,3, + 255,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0, + 12,116,105,110,116,101,103,101,114,101,100,105,116,6,98,114,105,103,104,116, + 5,99,111,108,111,114,4,3,0,0,128,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,4,38,66,82,73,16,102,114,97,109,101,46,99,97, + 112,116,105,111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109, + 101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2, + 0,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115, + 95,120,2,72,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,120,2,36,9,98,111,117,110,100,115,95,99,121,2,37,8, + 111,110,99,104,97,110,103,101,7,9,104,115,98,99,104,97,110,103,101,13, + 111,110,100,97,116,97,101,110,116,101,114,101,100,7,21,99,111,109,112,111, + 110,101,110,116,115,100,97,116,97,101,110,116,101,114,101,100,3,109,97,120, + 2,100,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0, + 12,116,105,110,116,101,103,101,114,101,100,105,116,3,115,97,116,5,99,111, + 108,111,114,4,3,0,0,128,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,4,38,83,65,84,16,102,114,97,109,101,46,99,97,112,116,105, + 111,110,112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8, + 116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2, + 36,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,2,36,9,98,111,117,110,100,115,95,99,121,2,37,8,111,110,99, + 104,97,110,103,101,7,9,104,115,98,99,104,97,110,103,101,13,111,110,100, + 97,116,97,101,110,116,101,114,101,100,7,21,99,111,109,112,111,110,101,110, + 116,115,100,97,116,97,101,110,116,101,114,101,100,3,109,97,120,2,100,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,12,116,105, + 110,116,101,103,101,114,101,100,105,116,3,104,117,101,5,99,111,108,111,114, + 4,3,0,0,128,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 4,38,72,85,69,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112, + 111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101, + 114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,98,111,117, + 110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,120,2,36,9,98,111,117,110,100,115,95,99,121, + 2,37,8,111,110,99,104,97,110,103,101,7,9,104,115,98,99,104,97,110, + 103,101,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,21,99,111, + 109,112,111,110,101,110,116,115,100,97,116,97,101,110,116,101,114,101,100,3, + 109,97,120,3,104,1,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,0,9,116,108,97,121,111,117,116,101,114,10,116,108,97,121, + 111,117,116,101,114,50,13,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,11,111,119,95,116,97,98,102,111,99,117,115,17,111,119,95,112,97,114, + 101,110,116,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119, + 102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105, + 110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,11,111, + 119,95,115,117,98,102,111,99,117,115,17,111,119,95,100,101,115,116,114,111, + 121,119,105,100,103,101,116,115,0,8,98,111,117,110,100,115,95,120,2,11, + 8,98,111,117,110,100,115,95,121,3,0,1,9,98,111,117,110,100,115,95, + 99,120,3,68,1,9,98,111,117,110,100,115,95,99,121,2,38,7,97,110, + 99,104,111,114,115,11,7,97,110,95,108,101,102,116,9,97,110,95,98,111, + 116,116,111,109,0,12,111,112,116,105,111,110,115,115,99,97,108,101,11,11, + 111,115,99,95,101,120,112,97,110,100,120,11,111,115,99,95,115,104,114,105, + 110,107,120,11,111,115,99,95,101,120,112,97,110,100,121,11,111,115,99,95, + 115,104,114,105,110,107,121,17,111,115,99,95,101,120,112,97,110,100,115,104, + 114,105,110,107,120,17,111,115,99,95,101,120,112,97,110,100,115,104,114,105, + 110,107,121,0,9,102,111,110,116,46,110,97,109,101,6,11,115,116,102,95, + 100,101,102,97,117,108,116,15,102,111,110,116,46,108,111,99,97,108,112,114, + 111,112,115,11,0,13,111,112,116,105,111,110,115,108,97,121,111,117,116,11, + 10,108,97,111,95,97,108,105,103,110,121,0,10,97,108,105,103,110,95,103, + 108,117,101,7,9,119,97,109,95,115,116,97,114,116,7,108,105,110,107,116, + 111,112,7,10,116,108,97,121,111,117,116,101,114,49,7,111,112,116,105,111, + 110,115,11,15,115,112,97,111,95,103,108,117,101,98,111,116,116,111,109,0, + 0,7,116,98,117,116,116,111,110,6,99,97,110,99,101,108,14,111,112,116, + 105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110, + 116,103,108,121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116, + 111,115,99,97,108,101,13,111,119,49,95,97,117,116,111,119,105,100,116,104, + 0,5,99,111,108,111,114,4,3,0,0,128,8,116,97,98,111,114,100,101, + 114,2,3,8,98,111,117,110,100,115,95,120,3,16,1,8,98,111,117,110, + 100,115,95,121,2,17,9,98,111,117,110,100,115,95,99,120,2,52,9,98, + 111,117,110,100,115,95,99,121,2,21,12,98,111,117,110,100,115,95,99,120, + 109,105,110,2,50,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,13,97,115,95,108,111,99,97,108,99,111,108, + 111,114,0,7,99,97,112,116,105,111,110,6,7,38,67,97,110,99,101,108, + 11,109,111,100,97,108,114,101,115,117,108,116,7,9,109,114,95,99,97,110, + 99,101,108,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0, + 0,7,116,98,117,116,116,111,110,2,111,107,14,111,112,116,105,111,110,115, + 119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121, + 112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99,97, + 108,101,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100, + 115,95,120,3,216,0,8,98,111,117,110,100,115,95,121,2,17,9,98,111, + 117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2, + 21,5,115,116,97,116,101,11,10,97,115,95,100,101,102,97,117,108,116,15, + 97,115,95,108,111,99,97,108,100,101,102,97,117,108,116,15,97,115,95,108, + 111,99,97,108,99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110, + 6,3,38,79,75,11,109,111,100,97,108,114,101,115,117,108,116,7,5,109, + 114,95,111,107,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,0,10,116,99,111,108,111,114,101,100,105,116,7,99,111,108,111,114,101, + 100,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,5,67,111,108, + 111,114,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7, + 6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,25,102,114,97,109,101,46,98,117,116,116,111,110,101, + 108,108,105,112,115,101,46,119,105,100,116,104,2,255,27,102,114,97,109,101, + 46,98,117,116,116,111,110,101,108,108,105,112,115,101,46,105,109,97,103,101, + 110,114,2,17,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109, + 101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111,114,100,101,114, + 2,1,8,98,111,117,110,100,115,95,120,2,102,8,98,111,117,110,100,115, + 95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,108,9,98,111,117, + 110,100,115,95,99,121,2,37,11,111,112,116,105,111,110,115,101,100,105,116, + 11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108, + 111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99, + 97,110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110, + 12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115, + 101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120, + 105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101, + 110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111, + 101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99, + 108,105,99,107,22,111,101,95,102,111,99,117,115,114,101,99,116,111,110,114, + 101,97,100,111,110,108,121,18,111,101,95,104,105,110,116,99,108,105,112,112, + 101,100,116,101,120,116,0,8,111,110,99,104,97,110,103,101,7,13,99,111, + 108,111,114,99,104,97,110,103,101,101,118,13,111,110,100,97,116,97,101,110, + 116,101,114,101,100,7,18,99,111,108,111,114,101,100,100,97,116,97,101,110, + 116,101,114,101,100,16,100,114,111,112,100,111,119,110,46,111,112,116,105,111, + 110,115,11,16,100,101,111,95,97,117,116,111,100,114,111,112,100,111,119,110, + 15,100,101,111,95,107,101,121,100,114,111,112,100,111,119,110,12,100,101,111, + 95,99,108,105,112,104,105,110,116,0,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,14,0,0,12,116,105,110,116,101,103,101,114,101,100,105, + 116,5,114,103,98,101,100,13,102,114,97,109,101,46,99,97,112,116,105,111, + 110,6,3,82,71,66,16,102,114,97,109,101,46,99,97,112,116,105,111,110, + 112,111,115,7,6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116, + 101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,98,111, + 117,110,100,115,95,120,2,32,8,98,111,117,110,100,115,95,121,2,0,9, + 98,111,117,110,100,115,95,99,120,2,68,9,98,111,117,110,100,115,95,99, + 121,2,37,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,16,114, + 103,98,101,100,100,97,116,97,101,110,116,101,114,101,100,4,98,97,115,101, + 7,6,110,98,95,104,101,120,8,98,105,116,99,111,117,110,116,2,24,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,9,116, + 108,97,121,111,117,116,101,114,10,116,108,97,121,111,117,116,101,114,51,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,11,111,119,95,116,97, + 98,102,111,99,117,115,17,111,119,95,112,97,114,101,110,116,116,97,98,102, + 111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111, + 119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114, + 114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111, + 99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116, + 115,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115, + 95,120,2,112,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,120,3,221,0,9,98,111,117,110,100,115,95,99,121,3,219, + 0,13,111,112,116,105,111,110,115,108,97,121,111,117,116,11,10,108,97,111, + 95,97,108,105,103,110,121,0,10,97,108,105,103,110,95,109,111,100,101,7, + 9,119,97,109,95,115,116,97,114,116,0,7,116,115,108,105,100,101,114,10, + 115,108,105,100,101,114,98,108,117,101,5,99,111,108,111,114,4,2,0,0, + 128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97, + 109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,1,0,0,128,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,10,102,114,108,95,102,105,108,101,102,116,9, + 102,114,108,95,102,105,116,111,112,11,102,114,108,95,102,105,114,105,103,104, + 116,12,102,114,108,95,102,105,98,111,116,116,111,109,15,102,114,108,95,99, + 111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114, + 2,5,8,98,111,117,110,100,115,95,120,3,196,0,8,98,111,117,110,100, + 115,95,121,2,3,9,98,111,117,110,100,115,95,99,120,2,15,9,98,111, + 117,110,100,115,95,99,121,3,214,0,7,97,110,99,104,111,114,115,11,7, + 97,110,95,108,101,102,116,6,97,110,95,116,111,112,9,97,110,95,98,111, + 116,116,111,109,0,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7, + 21,99,111,109,112,111,110,101,110,116,115,100,97,116,97,101,110,116,101,114, + 101,100,5,118,97,108,117,101,2,0,37,115,99,114,111,108,108,98,97,114, + 46,102,97,99,101,46,105,109,97,103,101,46,116,114,97,110,115,112,97,114, + 101,110,116,99,111,108,111,114,4,0,0,0,128,29,115,99,114,111,108,108, + 98,97,114,46,102,97,99,101,46,102,97,100,101,95,112,111,115,46,99,111, + 117,110,116,2,2,29,115,99,114,111,108,108,98,97,114,46,102,97,99,101, + 46,102,97,100,101,95,112,111,115,46,105,116,101,109,115,1,2,0,2,1, + 0,31,115,99,114,111,108,108,98,97,114,46,102,97,99,101,46,102,97,100, + 101,95,99,111,108,111,114,46,99,111,117,110,116,2,2,31,115,99,114,111, + 108,108,98,97,114,46,102,97,99,101,46,102,97,100,101,95,99,111,108,111, + 114,46,105,116,101,109,115,1,4,2,0,0,160,4,9,0,0,160,0,29, + 115,99,114,111,108,108,98,97,114,46,102,97,99,101,46,102,97,100,101,95, + 100,105,114,101,99,116,105,111,110,7,5,103,100,95,117,112,25,115,99,114, + 111,108,108,98,97,114,46,102,97,99,101,46,108,111,99,97,108,112,114,111, + 112,115,11,15,102,97,108,95,102,97,100,105,114,101,99,116,105,111,110,13, + 102,97,108,95,102,97,111,112,97,99,105,116,121,0,15,115,99,114,111,108, + 108,98,97,114,46,99,111,108,111,114,4,3,0,0,128,22,115,99,114,111, + 108,108,98,97,114,46,99,111,108,111,114,112,97,116,116,101,114,110,4,6, + 0,0,128,10,111,110,115,101,116,118,97,108,117,101,7,14,98,108,117,101, + 111,110,115,101,116,118,97,108,117,101,9,100,105,114,101,99,116,105,111,110, + 7,5,103,100,95,117,112,0,0,7,116,115,108,105,100,101,114,11,115,108, + 105,100,101,114,103,114,101,101,110,5,99,111,108,111,114,4,2,0,0,128, + 12,102,114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109, + 101,46,99,111,108,111,114,99,108,105,101,110,116,4,1,0,0,128,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108, + 95,108,101,118,101,108,111,10,102,114,108,95,102,105,108,101,102,116,9,102, + 114,108,95,102,105,116,111,112,11,102,114,108,95,102,105,114,105,103,104,116, + 12,102,114,108,95,102,105,98,111,116,116,111,109,15,102,114,108,95,99,111, + 108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2, + 4,8,98,111,117,110,100,115,95,120,3,160,0,8,98,111,117,110,100,115, + 95,121,2,3,9,98,111,117,110,100,115,95,99,120,2,15,9,98,111,117, + 110,100,115,95,99,121,3,214,0,7,97,110,99,104,111,114,115,11,7,97, + 110,95,108,101,102,116,6,97,110,95,116,111,112,9,97,110,95,98,111,116, + 116,111,109,0,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,21, + 99,111,109,112,111,110,101,110,116,115,100,97,116,97,101,110,116,101,114,101, + 100,5,118,97,108,117,101,2,0,37,115,99,114,111,108,108,98,97,114,46, + 102,97,99,101,46,105,109,97,103,101,46,116,114,97,110,115,112,97,114,101, + 110,116,99,111,108,111,114,4,0,0,0,128,29,115,99,114,111,108,108,98, + 97,114,46,102,97,99,101,46,102,97,100,101,95,112,111,115,46,99,111,117, + 110,116,2,2,29,115,99,114,111,108,108,98,97,114,46,102,97,99,101,46, + 102,97,100,101,95,112,111,115,46,105,116,101,109,115,1,2,0,2,1,0, + 31,115,99,114,111,108,108,98,97,114,46,102,97,99,101,46,102,97,100,101, + 95,99,111,108,111,114,46,99,111,117,110,116,2,2,31,115,99,114,111,108, + 108,98,97,114,46,102,97,99,101,46,102,97,100,101,95,99,111,108,111,114, + 46,105,116,101,109,115,1,4,2,0,0,160,4,8,0,0,160,0,29,115, + 99,114,111,108,108,98,97,114,46,102,97,99,101,46,102,97,100,101,95,100, + 105,114,101,99,116,105,111,110,7,5,103,100,95,117,112,25,115,99,114,111, + 108,108,98,97,114,46,102,97,99,101,46,108,111,99,97,108,112,114,111,112, + 115,11,15,102,97,108,95,102,97,100,105,114,101,99,116,105,111,110,13,102, + 97,108,95,102,97,111,112,97,99,105,116,121,0,15,115,99,114,111,108,108, + 98,97,114,46,99,111,108,111,114,4,3,0,0,128,22,115,99,114,111,108, + 108,98,97,114,46,99,111,108,111,114,112,97,116,116,101,114,110,4,6,0, + 0,128,10,111,110,115,101,116,118,97,108,117,101,7,15,103,114,101,101,110, + 111,110,115,101,116,118,97,108,117,101,9,100,105,114,101,99,116,105,111,110, + 7,5,103,100,95,117,112,0,0,7,116,115,108,105,100,101,114,9,115,108, + 105,100,101,114,114,101,100,5,99,111,108,111,114,4,2,0,0,128,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46, + 99,111,108,111,114,99,108,105,101,110,116,4,1,0,0,128,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108, + 101,118,101,108,111,10,102,114,108,95,102,105,108,101,102,116,9,102,114,108, + 95,102,105,116,111,112,11,102,114,108,95,102,105,114,105,103,104,116,12,102, + 114,108,95,102,105,98,111,116,116,111,109,15,102,114,108,95,99,111,108,111, + 114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,3,8, + 98,111,117,110,100,115,95,120,2,124,8,98,111,117,110,100,115,95,121,2, + 3,9,98,111,117,110,100,115,95,99,120,2,15,9,98,111,117,110,100,115, + 95,99,121,3,214,0,7,97,110,99,104,111,114,115,11,7,97,110,95,108, + 101,102,116,6,97,110,95,116,111,112,9,97,110,95,98,111,116,116,111,109, + 0,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,21,99,111,109, + 112,111,110,101,110,116,115,100,97,116,97,101,110,116,101,114,101,100,5,118, + 97,108,117,101,2,0,37,115,99,114,111,108,108,98,97,114,46,102,97,99, + 101,46,105,109,97,103,101,46,116,114,97,110,115,112,97,114,101,110,116,99, + 111,108,111,114,4,0,0,0,128,29,115,99,114,111,108,108,98,97,114,46, + 102,97,99,101,46,102,97,100,101,95,112,111,115,46,99,111,117,110,116,2, + 2,29,115,99,114,111,108,108,98,97,114,46,102,97,99,101,46,102,97,100, + 101,95,112,111,115,46,105,116,101,109,115,1,2,0,2,1,0,31,115,99, + 114,111,108,108,98,97,114,46,102,97,99,101,46,102,97,100,101,95,99,111, + 108,111,114,46,99,111,117,110,116,2,2,31,115,99,114,111,108,108,98,97, + 114,46,102,97,99,101,46,102,97,100,101,95,99,111,108,111,114,46,105,116, + 101,109,115,1,4,2,0,0,160,4,7,0,0,160,0,29,115,99,114,111, + 108,108,98,97,114,46,102,97,99,101,46,102,97,100,101,95,100,105,114,101, + 99,116,105,111,110,7,5,103,100,95,117,112,25,115,99,114,111,108,108,98, + 97,114,46,102,97,99,101,46,108,111,99,97,108,112,114,111,112,115,11,15, + 102,97,108,95,102,97,100,105,114,101,99,116,105,111,110,13,102,97,108,95, + 102,97,111,112,97,99,105,116,121,0,15,115,99,114,111,108,108,98,97,114, + 46,99,111,108,111,114,4,3,0,0,128,22,115,99,114,111,108,108,98,97, + 114,46,99,111,108,111,114,112,97,116,116,101,114,110,4,6,0,0,128,10, + 111,110,115,101,116,118,97,108,117,101,7,13,114,101,100,111,110,115,101,116, + 118,97,108,117,101,9,100,105,114,101,99,116,105,111,110,7,5,103,100,95, + 117,112,0,0,7,116,115,108,105,100,101,114,12,115,108,105,100,101,114,98, + 114,105,103,104,116,5,99,111,108,111,114,4,2,0,0,128,12,102,114,97, + 109,101,46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111, + 108,111,114,99,108,105,101,110,116,4,1,0,0,128,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,10,102,114,108,95,102,105,108,101,102,116,9,102,114,108,95,102, + 105,116,111,112,11,102,114,108,95,102,105,114,105,103,104,116,12,102,114,108, + 95,102,105,98,111,116,116,111,109,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111, + 117,110,100,115,95,120,2,83,8,98,111,117,110,100,115,95,121,2,3,9, + 98,111,117,110,100,115,95,99,120,2,15,9,98,111,117,110,100,115,95,99, + 121,3,214,0,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102, + 116,6,97,110,95,116,111,112,9,97,110,95,98,111,116,116,111,109,0,13, + 111,110,100,97,116,97,101,110,116,101,114,101,100,7,21,99,111,109,112,111, + 110,101,110,116,115,100,97,116,97,101,110,116,101,114,101,100,5,118,97,108, + 117,101,2,0,37,115,99,114,111,108,108,98,97,114,46,102,97,99,101,46, + 105,109,97,103,101,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108, + 111,114,4,0,0,0,128,29,115,99,114,111,108,108,98,97,114,46,102,97, + 99,101,46,102,97,100,101,95,112,111,115,46,99,111,117,110,116,2,2,29, + 115,99,114,111,108,108,98,97,114,46,102,97,99,101,46,102,97,100,101,95, + 112,111,115,46,105,116,101,109,115,1,2,0,2,1,0,31,115,99,114,111, + 108,108,98,97,114,46,102,97,99,101,46,102,97,100,101,95,99,111,108,111, + 114,46,99,111,117,110,116,2,2,31,115,99,114,111,108,108,98,97,114,46, + 102,97,99,101,46,102,97,100,101,95,99,111,108,111,114,46,105,116,101,109, + 115,1,4,2,0,0,160,4,6,0,0,160,0,29,115,99,114,111,108,108, + 98,97,114,46,102,97,99,101,46,102,97,100,101,95,100,105,114,101,99,116, + 105,111,110,7,5,103,100,95,117,112,25,115,99,114,111,108,108,98,97,114, + 46,102,97,99,101,46,108,111,99,97,108,112,114,111,112,115,11,15,102,97, + 108,95,102,97,100,105,114,101,99,116,105,111,110,13,102,97,108,95,102,97, + 111,112,97,99,105,116,121,0,15,115,99,114,111,108,108,98,97,114,46,99, + 111,108,111,114,4,3,0,0,128,22,115,99,114,111,108,108,98,97,114,46, + 99,111,108,111,114,112,97,116,116,101,114,110,4,6,0,0,128,10,111,110, + 115,101,116,118,97,108,117,101,7,16,98,114,105,103,104,116,111,110,115,101, + 116,118,97,108,117,101,9,100,105,114,101,99,116,105,111,110,7,5,103,100, + 95,117,112,0,0,7,116,115,108,105,100,101,114,9,115,108,105,100,101,114, + 115,97,116,5,99,111,108,111,114,4,2,0,0,128,12,102,114,97,109,101, + 46,108,101,118,101,108,111,2,255,17,102,114,97,109,101,46,99,111,108,111, + 114,99,108,105,101,110,116,4,1,0,0,128,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,10,102,114,108,95,102,105,108,101,102,116,9,102,114,108,95,102,105,116, + 111,112,11,102,114,108,95,102,105,114,105,103,104,116,12,102,114,108,95,102, + 105,98,111,116,116,111,109,15,102,114,108,95,99,111,108,111,114,99,108,105, + 101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110, + 100,115,95,120,2,48,8,98,111,117,110,100,115,95,121,2,3,9,98,111, + 117,110,100,115,95,99,120,2,15,9,98,111,117,110,100,115,95,99,121,3, + 214,0,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6, + 97,110,95,116,111,112,9,97,110,95,98,111,116,116,111,109,0,13,111,110, + 100,97,116,97,101,110,116,101,114,101,100,7,21,99,111,109,112,111,110,101, + 110,116,115,100,97,116,97,101,110,116,101,114,101,100,5,118,97,108,117,101, + 2,0,37,115,99,114,111,108,108,98,97,114,46,102,97,99,101,46,105,109, + 97,103,101,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,0,0,0,128,29,115,99,114,111,108,108,98,97,114,46,102,97,99,101, + 46,102,97,100,101,95,112,111,115,46,99,111,117,110,116,2,2,29,115,99, + 114,111,108,108,98,97,114,46,102,97,99,101,46,102,97,100,101,95,112,111, + 115,46,105,116,101,109,115,1,2,0,2,1,0,31,115,99,114,111,108,108, + 98,97,114,46,102,97,99,101,46,102,97,100,101,95,99,111,108,111,114,46, + 99,111,117,110,116,2,2,31,115,99,114,111,108,108,98,97,114,46,102,97, + 99,101,46,102,97,100,101,95,99,111,108,111,114,46,105,116,101,109,115,1, + 4,6,0,0,160,4,6,0,0,160,0,29,115,99,114,111,108,108,98,97, + 114,46,102,97,99,101,46,102,97,100,101,95,100,105,114,101,99,116,105,111, + 110,7,5,103,100,95,117,112,25,115,99,114,111,108,108,98,97,114,46,102, + 97,99,101,46,108,111,99,97,108,112,114,111,112,115,11,15,102,97,108,95, + 102,97,100,105,114,101,99,116,105,111,110,13,102,97,108,95,102,97,111,112, + 97,99,105,116,121,0,15,115,99,114,111,108,108,98,97,114,46,99,111,108, + 111,114,4,3,0,0,128,22,115,99,114,111,108,108,98,97,114,46,99,111, + 108,111,114,112,97,116,116,101,114,110,4,6,0,0,128,10,111,110,115,101, + 116,118,97,108,117,101,7,13,115,97,116,111,110,115,101,116,118,97,108,117, + 101,9,100,105,114,101,99,116,105,111,110,7,5,103,100,95,117,112,0,0, + 7,116,115,108,105,100,101,114,9,115,108,105,100,101,114,104,117,101,5,99, + 111,108,111,114,4,2,0,0,128,12,102,114,97,109,101,46,108,101,118,101, + 108,111,2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101, + 110,116,4,1,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,10,102,114,108, + 95,102,105,108,101,102,116,9,102,114,108,95,102,105,116,111,112,11,102,114, + 108,95,102,105,114,105,103,104,116,12,102,114,108,95,102,105,98,111,116,116, + 111,109,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8, + 98,111,117,110,100,115,95,120,2,12,8,98,111,117,110,100,115,95,121,2, + 3,9,98,111,117,110,100,115,95,99,120,2,15,9,98,111,117,110,100,115, + 95,99,121,3,214,0,7,97,110,99,104,111,114,115,11,7,97,110,95,108, + 101,102,116,6,97,110,95,116,111,112,9,97,110,95,98,111,116,116,111,109, + 0,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,21,99,111,109, + 112,111,110,101,110,116,115,100,97,116,97,101,110,116,101,114,101,100,5,118, + 97,108,117,101,2,0,37,115,99,114,111,108,108,98,97,114,46,102,97,99, + 101,46,105,109,97,103,101,46,116,114,97,110,115,112,97,114,101,110,116,99, + 111,108,111,114,4,0,0,0,128,29,115,99,114,111,108,108,98,97,114,46, + 102,97,99,101,46,102,97,100,101,95,112,111,115,46,99,111,117,110,116,2, + 7,29,115,99,114,111,108,108,98,97,114,46,102,97,99,101,46,102,97,100, + 101,95,112,111,115,46,105,116,101,109,115,1,2,0,5,145,186,162,54,159, + 170,170,170,252,63,5,164,174,168,205,167,170,170,170,253,63,5,0,0,0, + 0,0,0,0,128,254,63,5,106,210,150,8,142,170,170,170,254,63,5,53, + 105,75,4,71,85,85,213,254,63,2,1,0,31,115,99,114,111,108,108,98, + 97,114,46,102,97,99,101,46,102,97,100,101,95,99,111,108,111,114,46,99, + 111,117,110,116,2,7,31,115,99,114,111,108,108,98,97,114,46,102,97,99, + 101,46,102,97,100,101,95,99,111,108,111,114,46,105,116,101,109,115,1,4, + 7,0,0,160,4,12,0,0,160,4,8,0,0,160,4,10,0,0,160,4, + 9,0,0,160,4,11,0,0,160,4,7,0,0,160,0,29,115,99,114,111, + 108,108,98,97,114,46,102,97,99,101,46,102,97,100,101,95,100,105,114,101, + 99,116,105,111,110,7,5,103,100,95,117,112,25,115,99,114,111,108,108,98, + 97,114,46,102,97,99,101,46,108,111,99,97,108,112,114,111,112,115,11,15, + 102,97,108,95,102,97,100,105,114,101,99,116,105,111,110,13,102,97,108,95, + 102,97,111,112,97,99,105,116,121,0,15,115,99,114,111,108,108,98,97,114, + 46,99,111,108,111,114,4,3,0,0,128,22,115,99,114,111,108,108,98,97, + 114,46,99,111,108,111,114,112,97,116,116,101,114,110,4,6,0,0,128,10, + 111,110,115,101,116,118,97,108,117,101,7,13,104,117,101,111,110,115,101,116, + 118,97,108,117,101,9,100,105,114,101,99,116,105,111,110,7,5,103,100,95, + 117,112,0,0,0,9,116,103,114,111,117,112,98,111,120,2,103,98,13,111, + 112,116,105,111,110,115,119,105,100,103,101,116,11,17,111,119,95,112,97,114, + 101,110,116,116,97,98,102,111,99,117,115,15,111,119,95,97,114,114,111,119, + 102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117, + 115,111,117,116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,11,111,112,116,105, + 111,110,115,115,107,105,110,11,10,111,115,107,95,110,111,115,107,105,110,0, + 5,99,111,108,111,114,4,3,0,0,128,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111, + 10,102,114,108,95,108,101,118,101,108,105,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101, + 114,2,3,8,98,111,117,110,100,115,95,120,2,3,8,98,111,117,110,100, + 115,95,121,2,3,9,98,111,117,110,100,115,95,99,120,2,100,9,98,111, + 117,110,100,115,95,99,121,3,209,0,7,97,110,99,104,111,114,115,11,7, + 97,110,95,108,101,102,116,6,97,110,95,116,111,112,9,97,110,95,98,111, + 116,116,111,109,0,0,0,9,116,115,116,97,116,102,105,108,101,10,116,115, + 116,97,116,102,105,108,101,49,8,102,105,108,101,110,97,109,101,6,15,99, + 111,108,111,114,100,105,97,108,111,103,46,115,116,97,7,111,112,116,105,111, + 110,115,11,10,115,102,111,95,109,101,109,111,114,121,0,4,108,101,102,116, + 2,24,3,116,111,112,2,104,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tcolordialogfo,''); +end. diff --git a/mseide-msegui/lib/common/dialogs/msedialog.pas b/mseide-msegui/lib/common/dialogs/msedialog.pas new file mode 100644 index 0000000..e602fc8 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msedialog.pas @@ -0,0 +1,673 @@ +{ MSEgui Copyright (c) 1999-2015 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msedialog; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface + +uses + mseclasses,msegui,mseglob,mseguiglob, + mseforms,msedataedits,mseedit,classes,mclasses,mseevent, + msemenus,msestrings,mseeditglob,msetypes,msegraphics; + +type + tdialogform = class(tmseform) + protected + procedure updatewindowinfo(var info: windowinfoty); override; + class function hasresource: boolean; override; + end; + + tdialog = class(tmsecomponent) + public + function execute: modalresultty; virtual; abstract; + end; + + tellipsebuttonframe = class(tmultibuttonframe) + private + function getbutton: tstockglyphframebutton; + procedure setbutton(const avalue: tstockglyphframebutton); + public + constructor create(const aintf: icaptionframe; + const buttonintf: ibutton); reintroduce; + published + property button: tstockglyphframebutton read getbutton write setbutton; + end; + + tdataeditcontroller = class(teventpersistent) + end; + + tdialogcontroller = class(tdataeditcontroller,ibutton,idataeditcontroller) + protected + fowner: tcustomdataedit; + procedure internalexecute; virtual; abstract; + function iskeyexecute(const info: keyeventinfoty): boolean; virtual; + //ibutton + procedure buttonaction(var action: buttonactionty; const buttonindex: integer); + + //idataeditcontroller + procedure mouseevent(var info: mouseeventinfoty); virtual; + procedure domousewheelevent(var info: mousewheeleventinfoty); virtual; + procedure dokeydown(var info: keyeventinfoty); virtual; + procedure updatereadonlystate; virtual; + procedure internalcreateframe; virtual; + procedure editnotification(var info: editnotificationinfoty); virtual; + public + constructor create(const aowner: tcustomdataedit); reintroduce; + end; + + stringdialogexeceventty = procedure(const sender: tcustomdataedit; + var avalue:msestring; var modresult: modalresultty) of object; + //default mr_ok + tstringdialogcontroller = class(tdialogcontroller) + protected + fonexecute: stringdialogexeceventty; + procedure internalexecute; override; + function execute(var avalue: msestring): boolean; virtual; + procedure setexecresult(var avalue: msestring); virtual; + public + constructor create(const aowner: tcustomstringedit); + property onexecute: stringdialogexeceventty read fonexecute write fonexecute; + end; + + tcustomdialogstringed = class(tstringedit) + private + function getframe: tellipsebuttonframe; + procedure setframe(const avalue: tellipsebuttonframe); + protected + fdialogcontroller: tdialogcontroller; + function createdialogcontroller: tstringdialogcontroller; virtual; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property frame: tellipsebuttonframe read getframe write setframe; + end; + + tdialogstringed = class(tcustomdialogstringed) + published + property frame; + property passwordchar; + property maxlength; + property value; + property onsetvalue; + end; + + tcustomdialogstringedit = class(tcustomdialogstringed) + private + function getonexecute: stringdialogexeceventty; + procedure setonexecute(const avalue: stringdialogexeceventty); + protected +// function execute(var avalue: msestring): boolean; override; + public + property onexecute: stringdialogexeceventty read getonexecute + write setonexecute; + end; + + tdialogstringedit = class(tcustomdialogstringedit) + published + property onexecute; + end; + + realdialogexeceventty = procedure(const sender: tcustomdataedit; + var avalue: realty; var modresult: modalresultty) of object; + //default mr_ok + trealdialogcontroller = class(tdialogcontroller) + private + protected + fonexecute: realdialogexeceventty; + procedure internalexecute; override; + function execute(var avalue: realty): boolean; virtual; + procedure setexecresult(var avalue: realty); virtual; + public + constructor create(const aowner: tcustomrealedit); + property onexecute: realdialogexeceventty read fonexecute write fonexecute; + end; + + tdialogrealedit = class(trealedit) + private + function getframe: tellipsebuttonframe; + procedure setframe(const avalue: tellipsebuttonframe); + function getonexecute: realdialogexeceventty; + procedure setonexecute(const avalue: realdialogexeceventty); + protected + fdialogcontroller: trealdialogcontroller; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property frame: tellipsebuttonframe read getframe write setframe; + property onexecute: realdialogexeceventty read getonexecute + write setonexecute; + end; + + datetimedialogexeceventty = procedure(const sender: tcustomdataedit; + var avalue: tdatetime; var modresult: modalresultty) of object; + //default mr_ok + tdatetimedialogcontroller = class(tdialogcontroller) + private + protected + fonexecute: datetimedialogexeceventty; + procedure internalexecute; override; + function execute(var avalue: tdatetime): boolean; virtual; + procedure setexecresult(var avalue: tdatetime); virtual; + public + constructor create(const aowner: tcustomdatetimeedit); + property onexecute: datetimedialogexeceventty read fonexecute write fonexecute; + end; + + tdialogdatetimeedit = class(tdatetimeedit) + private + function getframe: tellipsebuttonframe; + procedure setframe(const avalue: tellipsebuttonframe); + function getonexecute: datetimedialogexeceventty; + procedure setonexecute(const avalue: datetimedialogexeceventty); + protected + fdialogcontroller: tdatetimedialogcontroller; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property frame: tellipsebuttonframe read getframe write setframe; + property onexecute: datetimedialogexeceventty read getonexecute + write setonexecute; + end; + + integerdialogexeceventty = procedure(const sender: tcustomdataedit; + var avalue: integer; var modresult: modalresultty) of object; + //default mr_ok + tintegerdialogcontroller = class(tdialogcontroller) + private + protected + fonexecute: integerdialogexeceventty; + procedure internalexecute; override; + function execute(var avalue: integer): boolean; virtual; + procedure setexecresult(var avalue: integer); virtual; + public + constructor create(const aowner: tcustomintegeredit); + property onexecute: integerdialogexeceventty read fonexecute write fonexecute; + end; + + tdialogintegeredit = class(tintegeredit) + private + function getframe: tellipsebuttonframe; + procedure setframe(const avalue: tellipsebuttonframe); + function getonexecute: integerdialogexeceventty; + procedure setonexecute(const avalue: integerdialogexeceventty); + protected + fdialogcontroller: tintegerdialogcontroller; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property frame: tellipsebuttonframe read getframe write setframe; + property onexecute: integerdialogexeceventty read getonexecute + write setonexecute; + end; + + +implementation +uses + msestockobjects,msekeyboard,mseformatstr,msereal,sysutils; + +type + tcustomdataedit1 = class(tcustomdataedit); + tcustomrealedit1 = class(tcustomrealedit); + tcustomdatetimeedit1 = class(tcustomdatetimeedit); + tcustomintegeredit1 = class(tcustomintegeredit); + tcustomstringedit1 = class(tcustomstringedit); + +{ tdialogform } + +procedure tdialogform.updatewindowinfo(var info: windowinfoty); +begin + inherited; + info.options:= [wo_message]; +end; + +class function tdialogform.hasresource: boolean; +begin + result:= false; +end; + +{ tellipsebuttonframe } + +constructor tellipsebuttonframe.create(const aintf: icaptionframe; + const buttonintf: ibutton); +begin + inherited; +// buttons.count:= 1; + with buttons[0] do begin + imagelist:= stockobjects.glyphs; + imagenr:= ord(stg_ellipsesmall); + end; +end; + +function tellipsebuttonframe.getbutton: tstockglyphframebutton; +begin + result:= tstockglyphframebutton(inherited getbutton()); +end; + +procedure tellipsebuttonframe.setbutton(const avalue: tstockglyphframebutton); +begin + inherited setbutton(avalue); +end; + +{ tdialogcontroller } + +constructor tdialogcontroller.create(const aowner: tcustomdataedit); +begin + fowner:= aowner; + tcustomdataedit1(fowner).fcontrollerintf:= idataeditcontroller(self); + internalcreateframe; +end; + +procedure tdialogcontroller.buttonaction(var action: buttonactionty; + const buttonindex: integer); +begin + with fowner do begin + if action = ba_click then begin + if canfocus and not setfocus then begin + exit; + end; + internalexecute; + end; + end; +end; + +procedure tdialogcontroller.dokeydown(var info: keyeventinfoty); +begin + with info do begin + if iskeyexecute(info) then begin + include(info.eventstate,es_processed); + internalexecute; + end; + end; +end; + +function tdialogcontroller.iskeyexecute(const info: keyeventinfoty): boolean; +begin + with fowner,info do begin + result:= (not readonly or (oe1_readonlydialog in optionsedit1)) and + (oe1_keyexecute in optionsedit1) and (key = key_down) and + (shiftstate = [ss_alt]); + end; +end; + +procedure tdialogcontroller.updatereadonlystate; +begin + with tcustomdataedit1(fowner) do begin + if fframe <> nil then begin + with tcustombuttonframe(fframe) do begin + if buttons.count > 0 then begin + buttons[0].enabled:= not (oe_readonly in getoptionsedit) or + (oe1_readonlydialog in optionsedit1); + end; + end; + end; + end; +end; + +procedure tdialogcontroller.internalcreateframe; +begin + tellipsebuttonframe.create(iscrollframe(fowner),ibutton(self)); + updatereadonlystate; +end; + +procedure tdialogcontroller.mouseevent(var info: mouseeventinfoty); +begin + with tcustomdataedit1(fowner) do begin + tcustombuttonframe(fframe).mouseevent(info); + end; +end; + +procedure tdialogcontroller.domousewheelevent(var info: mousewheeleventinfoty); +begin + //dummy +end; + +procedure tdialogcontroller.editnotification(var info: editnotificationinfoty); +begin + //dummy +end; + +{ tstringdialogcontroller } + +constructor tstringdialogcontroller.create(const aowner: tcustomstringedit); +begin + inherited create(aowner); +end; + +procedure tstringdialogcontroller.internalexecute; +var + str1: msestring; +begin + with tcustomstringedit(fowner) do begin + str1:= text; + if execute(str1) and not readonly then begin + setexecresult(str1); + checkvalue; + end; + end; +end; + +function tstringdialogcontroller.execute(var avalue: msestring): boolean; +var + mr1: modalresultty; +begin + if fowner.canevent(tmethod(fonexecute)) then begin + mr1:= mr_ok; + fonexecute(fowner,avalue,mr1); + result:= mr1 = mr_ok; + end + else begin + result:= false; + end; +end; + +procedure tstringdialogcontroller.setexecresult(var avalue: msestring); +begin + with tcustomstringedit1(fowner) do begin + text:= avalue; //setcurrenttext(avalue); + end; +end; + +{ tcustomdialogstringed } + +constructor tcustomdialogstringed.create(aowner: tcomponent); +begin + inherited; + if fdialogcontroller = nil then begin + fdialogcontroller:= createdialogcontroller; + end; +// fbuttonintf:= ibutton(fcontroller); +// inherited; +// internalcreateframe; +end; + +destructor tcustomdialogstringed.destroy; +begin + inherited; + fdialogcontroller.free; +end; + +function tcustomdialogstringed.createdialogcontroller: tstringdialogcontroller; +begin + result:= tstringdialogcontroller.create(self); +end; + +function tcustomdialogstringed.getframe: tellipsebuttonframe; +begin + result:= tellipsebuttonframe(inherited getframe); +end; + +procedure tcustomdialogstringed.setframe(const avalue: tellipsebuttonframe); +begin + inherited setframe(avalue); +end; + +function tcustomdialogstringedit.getonexecute: stringdialogexeceventty; +begin + result:= tstringdialogcontroller(fdialogcontroller).onexecute; +end; + +procedure tcustomdialogstringedit.setonexecute(const avalue: stringdialogexeceventty); +begin + tstringdialogcontroller(fdialogcontroller).onexecute:= avalue; +end; + +{ trealdialogcontroller } + +constructor trealdialogcontroller.create(const aowner: tcustomrealedit); +begin + inherited create(aowner); +end; + +procedure trealdialogcontroller.internalexecute; +var + rea1: realty; + bo1: boolean; +begin + with tcustomrealedit1(fowner) do begin + bo1:= true; + rea1:= gettextvalue(bo1,false); + if bo1 and execute(rea1) then begin + setexecresult(rea1); + checkvalue; + end; + end; +end; + +function trealdialogcontroller.execute(var avalue: realty): boolean; +var + mr1: modalresultty; +begin + if fowner.canevent(tmethod(fonexecute)) then begin + mr1:= mr_ok; + fonexecute(fowner,avalue,mr1); + result:= mr1 = mr_ok; + end + else begin + result:= false; + end; +end; + +procedure trealdialogcontroller.setexecresult(var avalue: realty); +begin + with tcustomrealedit(fowner) do begin + text:= realtytostrrange(avalue,formatedit,valuerange,valuestart); + end; +end; + +{ tdialogrealedit } + +constructor tdialogrealedit.create(aowner: tcomponent); +begin + inherited; + if fdialogcontroller = nil then begin + fdialogcontroller:= trealdialogcontroller.create(self); + end; +end; + +destructor tdialogrealedit.destroy; +begin + inherited; + fdialogcontroller.free; +end; + +function tdialogrealedit.getframe: tellipsebuttonframe; +begin + result:= tellipsebuttonframe(inherited getframe); +end; + +procedure tdialogrealedit.setframe(const avalue: tellipsebuttonframe); +begin + inherited setframe(avalue); +end; + +function tdialogrealedit.getonexecute: realdialogexeceventty; +begin + result:= fdialogcontroller.onexecute; +end; + +procedure tdialogrealedit.setonexecute(const avalue: realdialogexeceventty); +begin + fdialogcontroller.onexecute:= avalue; +end; + +{ tdatetimedialogcontroller } + +constructor tdatetimedialogcontroller.create(const aowner: tcustomdatetimeedit); +begin + inherited create(aowner); +end; + +procedure tdatetimedialogcontroller.internalexecute; +var + dat1: tdatetime; + bo1: boolean; +begin + with tcustomdatetimeedit1(fowner) do begin + bo1:= true; + dat1:= gettextvalue(bo1,false); + if bo1 and execute(dat1) then begin + setexecresult(dat1); + checkvalue; + end; + end; +end; + +function tdatetimedialogcontroller.execute(var avalue: tdatetime): boolean; +var + mr1: modalresultty; +begin + if fowner.canevent(tmethod(fonexecute)) then begin + mr1:= mr_ok; + fonexecute(fowner,avalue,mr1); + result:= mr1 = mr_ok; + end + else begin + result:= false; + end; +end; + +procedure tdatetimedialogcontroller.setexecresult(var avalue: tdatetime); +begin + with tcustomdatetimeedit(fowner) do begin + case kind of + dtk_time: begin + text:= mseformatstr.timetostring(avalue,formatedit); + end; + dtk_date: begin + text:= mseformatstr.datetostring(avalue,formatedit); + end; + else begin + text:= mseformatstr.datetimetostring(avalue,formatedit); + end; + end; + end; +end; + +{ tdialogdatetimeedit } + +constructor tdialogdatetimeedit.create(aowner: tcomponent); +begin + inherited; + if fdialogcontroller = nil then begin + fdialogcontroller:= tdatetimedialogcontroller.create(self); + end; +end; + +destructor tdialogdatetimeedit.destroy; +begin + inherited; + fdialogcontroller.free; +end; + +function tdialogdatetimeedit.getframe: tellipsebuttonframe; +begin + result:= tellipsebuttonframe(inherited getframe); +end; + +procedure tdialogdatetimeedit.setframe(const avalue: tellipsebuttonframe); +begin + inherited setframe(avalue); +end; + +function tdialogdatetimeedit.getonexecute: datetimedialogexeceventty; +begin + result:= fdialogcontroller.onexecute; +end; + +procedure tdialogdatetimeedit.setonexecute(const avalue: datetimedialogexeceventty); +begin + fdialogcontroller.onexecute:= avalue; +end; + +{ tintegerdialogcontroller } + +constructor tintegerdialogcontroller.create(const aowner: tcustomintegeredit); +begin + inherited create(aowner); +end; + +procedure tintegerdialogcontroller.internalexecute; +var + int1: integer; + bo1: boolean; +begin + with tcustomintegeredit1(fowner) do begin + bo1:= true; + int1:= gettextvalue(bo1,false); + if bo1 and execute(int1) then begin + setexecresult(int1); + checkvalue; + end; + end; +end; + +function tintegerdialogcontroller.execute(var avalue: integer): boolean; +var + mr1: modalresultty; +begin + if fowner.canevent(tmethod(fonexecute)) then begin + mr1:= mr_ok; + fonexecute(fowner,avalue,mr1); + result:= mr1 = mr_ok; + end + else begin + result:= false; + end; +end; + +procedure tintegerdialogcontroller.setexecresult(var avalue: integer); +begin + with tcustomintegeredit(fowner) do begin + text:= inttostrmse(avalue); + end; +end; + +{ tdialogintegeredit } + +constructor tdialogintegeredit.create(aowner: tcomponent); +begin + inherited; + if fdialogcontroller = nil then begin + fdialogcontroller:= tintegerdialogcontroller.create(self); + end; +end; + +destructor tdialogintegeredit.destroy; +begin + inherited; + fdialogcontroller.free; +end; + +function tdialogintegeredit.getframe: tellipsebuttonframe; +begin + result:= tellipsebuttonframe(inherited getframe); +end; + +procedure tdialogintegeredit.setframe(const avalue: tellipsebuttonframe); +begin + inherited setframe(avalue); +end; + +function tdialogintegeredit.getonexecute: integerdialogexeceventty; +begin + result:= fdialogcontroller.onexecute; +end; + +procedure tdialogintegeredit.setonexecute(const avalue: integerdialogexeceventty); +begin + fdialogcontroller.onexecute:= avalue; +end; + +end. diff --git a/mseide-msegui/lib/common/dialogs/msedirtree.mfm b/mseide-msegui/lib/common/dialogs/msedirtree.mfm new file mode 100644 index 0000000..d628508 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msedirtree.mfm @@ -0,0 +1,70 @@ +object dirtreefo: tdirtreefo + visible = False + bounds_x = 80 + bounds_y = 374 + bounds_cx = 300 + bounds_cy = 203 + bounds_cxmin = 200 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 300 + 203 + ) + optionswindow = [wo_popup, wo_buttonendmodal] + options = [fo_closeonesc, fo_localshortcuts, fo_autoreadstat, fo_autowritestat] + moduleclassname = 'tmseform' + object grid: twidgetgrid + frame.levelo = 0 + frame.framewidth = 1 + frame.colorframe = -1610612734 + frame.localprops = [frl_levelo, frl_framewidth, frl_colorframe] + frame.localprops1 = [] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 300 + bounds_cy = 203 + anchors = [] + datacols.count = 1 + datacols.items = < + item[treeitem] + linewidth = 0 + colorfocused = -1879048185 + width = 298 + options = [co_readonly, co_fill, co_savevalue] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcoloractive, co1_rowcolorfocused, co1_rowreadonly, co1_autocolwidth] + widgetname = 'treeitem' + dataclass = ttreeitemeditlist + datalist.imagelist = filedialogres.images + datalist.imagewidth = 16 + datalist.imageheight = 16 + datalist.onitemnotification = treeitemonitemnotification + datalist.oncreateitem = treeitemoncreateitem + end> + datarowlinewidth = 0 + datarowheight = 16 + reffontheight = 14 + object treeitem: ttreeitemedit + optionsskin = [osk_framebuttononly] + cursor = cr_arrow + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 298 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_readonly, oe_undoonesc, oe_checkmrcancel, oe_forcereturncheckvalue, oe_hintclippedtext, oe_locate] + ondataentered = treeitemondataentered + oncellevent = treeitemoncellevent + options = [teo_treecolnavig, teo_enteronimageclick] + reffontheight = 14 + end + end +end diff --git a/mseide-msegui/lib/common/dialogs/msedirtree.pas b/mseide-msegui/lib/common/dialogs/msedirtree.pas new file mode 100644 index 0000000..6b5290f --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msedirtree.pas @@ -0,0 +1,514 @@ +{ MSEgui Copyright (c) 1999-2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msedirtree; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + mseforms,msewidgetgrid,mselistbrowser,msedatanodes,msefileutils,msetypes, + msestrings,msegui,mseglob,mseclasses,msegrids,msesys,msegridsglob, + mseapplication,msebitmap,msedataedits,mseedit,msegraphics,msesizingform, + msegraphutils,mseguiglob,mseificomp,mseificompglob,mseifiglob,msemenus,msestat, + msestatfile,msestream,sysutils; +type + + tdirlistitem = class(ttreelistedititem) + private + finfo: fileinfoty; + froot: filenamety; + protected + flistonly: boolean; + procedure updateinfo; + public + constructor create(const aowner: tcustomitemlist = nil; + const aparent: ttreelistitem = nil); override; + procedure setentries(const list: tcustomfiledatalist; + const achecksubdirectories,ashowhidden,acheckbox: boolean); + function findsubdir(const aname: filenamety): tdirlistitem; + function getpath: filenamety; + end; + + dirlistitemarty = array of tdirlistitem; + + dirtreeoptionty = (dto_casesensitive,dto_showhiddenfiles, + dto_checksubdir,dto_checkbox, + dto_nocollapseclear, //normally collapsed nodes are freed + //if dto_checkbox is not set + dto_expandonclick,dto_expandondblclick); + dirtreeoptionsty = set of dirtreeoptionty; + + tdirtreefo = class(tsizingform) + grid: twidgetgrid; + treeitem: ttreeitemedit; + procedure treeitemoncreateitem(const sender: tcustomitemlist; + var item: ttreelistedititem); virtual; + procedure treeitemonitemnotification(const sender: tlistitem; + var action: nodeactionty); virtual; + procedure treeitemondataentered(const sender: tobject); virtual; + procedure treeitemoncellevent(const sender: tobject; + var info: celleventinfoty); virtual; + private +// fshowhiddenfiles: boolean; +// fcasesensitive: boolean; +// fpath: filenamety; + fonpathchanged: notifyeventty; +// fchecksubdir: boolean; + foptionsdir: dirtreeoptionsty; +// fchecksubdir: boolean; + fonselctionchanged: listitemeventty; + fonselectionchanged: listitemeventty; + procedure setpath(const avalue: filenamety); + function getpath: filenamety; + procedure adddir(const aitem: tdirlistitem); + function getshowhiddenfiles: boolean; + procedure setshowhiddenfiles(const avalue: boolean); + function getcasesensitive: boolean; + procedure setcasesensitive(const avalue: boolean); + function getchecksubdir: boolean; + procedure setchecksubdir(const avalue: boolean); + procedure setroot(const avalue: filenamety); + protected + fpath: filenamety; + froot: filenamety; + frootitem: tdirlistitem; + procedure updatepath(); + procedure doondataentered(); virtual; + public + destructor destroy(); override; + function getcheckednodes(const amode: getnodemodety = + gno_nochildren): dirlistitemarty; + function getcheckedfilenames(const amode: getnodemodety = + gno_nochildren): filenamearty; + property casesensitive: boolean read getcasesensitive write setcasesensitive; + property showhiddenfiles: boolean read getshowhiddenfiles + write setshowhiddenfiles; + property checksubdir: boolean read getchecksubdir write setchecksubdir; + property path: filenamety read getpath write setpath; + property root: filenamety read froot write setroot; + property optionsdir: dirtreeoptionsty read foptionsdir + write foptionsdir default []; + property onpathchanged: notifyeventty read fonpathchanged + write fonpathchanged; + property onselectionchanged: listitemeventty read fonselctionchanged + write fonselectionchanged; + end; +{ + tdiredit = class(tstringedit) + private + end; +} +//var +// dirtreefo: tdirtreefo; + +implementation +uses + msedirtree_mfm,msesysintf,mseeditglob,msefiledialog,mseevent, + classes,mclasses; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{ tdirlistitem } + +constructor tdirlistitem.create(const aowner: tcustomitemlist; + const aparent: ttreelistitem); +begin + inherited; + include(fstate,ns_subitems); +end; + +function tdirlistitem.getpath: filenamety; +begin + if fparent = nil then begin + result:= fcaption; + end + else begin + if froot = '' then begin + result:= copy(concatstrings(rootcaptions,'/'),2,bigint); + end + else begin + result:= filepath(froot,concatstrings(rootcaptions(),'/'),fk_dir); + end; + end; +end; + +procedure tdirlistitem.updateinfo; +begin + updatefileinfo(self,finfo,true); +end; + +procedure tdirlistitem.setentries(const list: tcustomfiledatalist; + const achecksubdirectories,ashowhidden,acheckbox: boolean); +var + po1: pfileinfoty; + ar1: treelistedititemarty; + int1: integer; + item1: tdirlistitem; +// dirstream: dirstreamty; + excl: fileattributesty; + fna1: filenamety; +begin + clear; + if list <> nil then begin + po1:= list.datapo; + if ashowhidden then begin + excl:= []; + end + else begin + excl:= [fa_hidden]; + end; + setlength(ar1,list.count); + for int1:= 0 to list.count - 1 do begin + item1:= tdirlistitem.create; + item1.froot:= froot; + if acheckbox then begin + item1.fstate:= item1.fstate + [ns_checkbox,ns_showchildchecked]; + end; + ar1[int1]:= item1; + item1.finfo:= po1^; + item1.updateinfo; + if achecksubdirectories and + (item1.finfo.extinfo1.filetype = ft_dir) then begin + fna1:= filepath(getpath,item1.finfo.name,fk_file); + if {$ifdef mswindows} + (treelevel = 0) and (length(fna1) = 4) and (fna1[3] = ':') and + (fna1[4] = '/')or + //'/x:/' could be a floppy disk on windows which throws an error + // on query + {$endif} + dirhasentries(fna1,[fa_dir],excl) then begin + include(item1.fstate,ns_subitems); + end + else begin + exclude(item1.fstate,ns_subitems); + end; + end; + inc(po1); + end; + add(ar1); + end; +end; + +function tdirlistitem.findsubdir(const aname: filenamety): tdirlistitem; +begin + result:= tdirlistitem(finditembycaption(aname,true)); + if (result = nil) and sys_filesystemiscaseinsensitive then begin + result:= tdirlistitem(finditembycaption(aname,false)); + end; +end; + +{ tdirtreefo } + +destructor tdirtreefo.destroy(); +begin + freeandnil(frootitem); + inherited; +end; + +procedure tdirtreefo.adddir(const aitem: tdirlistitem); +var + list: tcustomfiledatalist; + exclude: fileattributesty; +begin + list:= tcustomfiledatalist.create; + try + if casesensitive then begin + list.options:= [flo_sortname,flo_casesensitive]; + end + else begin + list.options:= [flo_sortname]; + end; + if showhiddenfiles then begin + exclude:= []; + end + else begin + exclude:= [fa_hidden]; + end; + list.adddirectory(aitem.getpath,fil_name,nil,[fa_dir],exclude); + aitem.setentries(list,checksubdir,showhiddenfiles, + dto_checkbox in foptionsdir); + finally + list.free; + end; +end; + +function tdirtreefo.getshowhiddenfiles: boolean; +begin + result:= dto_showhiddenfiles in foptionsdir; +end; + +procedure tdirtreefo.setshowhiddenfiles(const avalue: boolean); +begin + if avalue then begin + include(foptionsdir,dto_showhiddenfiles); + end + else begin + exclude(foptionsdir,dto_showhiddenfiles); + end; +end; + +function tdirtreefo.getcasesensitive: boolean; +begin + result:= dto_casesensitive in foptionsdir; +end; + +procedure tdirtreefo.setcasesensitive(const avalue: boolean); +begin + if avalue then begin + include(foptionsdir,dto_casesensitive); + end + else begin + exclude(foptionsdir,dto_casesensitive); + end; +end; + +function tdirtreefo.getchecksubdir: boolean; +begin + result:= dto_checksubdir in foptionsdir; +end; + +procedure tdirtreefo.setchecksubdir(const avalue: boolean); +begin + if avalue then begin + include(foptionsdir,dto_checksubdir); + end + else begin + exclude(foptionsdir,dto_checksubdir); + end; +end; + +procedure tdirtreefo.setroot(const avalue: filenamety); +begin + froot:= avalue; + updatepath(); +end; + +function tdirtreefo.getcheckednodes(const amode: getnodemodety = + gno_nochildren): dirlistitemarty; +begin + result:= dirlistitemarty(treeitem.itemlist.getcheckednodes(amode)); +end; + +function tdirtreefo.getcheckedfilenames(const amode: getnodemodety = + gno_nochildren): filenamearty; +var + ar1: dirlistitemarty; + int1: integer; +begin + ar1:= getcheckednodes(amode); + setlength(result,length(ar1)); + for int1:= 0 to high(ar1) do begin + result[int1]:= ar1[int1].getpath; + end; +end; + +function tdirtreefo.getpath: filenamety; +begin + if treeitem.item = nil then begin + result:= ''; + end + else begin + result:= filepath(tdirlistitem(treeitem.item).getpath,fk_dir); + end; +end; + +procedure tdirtreefo.updatepath(); +var + ar1: msestringarty; + int1: integer; + aitem,item1: tdirlistitem; + {$ifdef mswindows} + uncitem: tdirlistitem; + {$endif} + avalue: filenamety; + info1: fileinfoty; +begin + avalue:= fpath; + if dto_checkbox in foptionsdir then begin + treeitem.itemlist.options:= treeitem.itemlist.options + + [no_checkbox,no_updatechildchecked]; + end + else begin + treeitem.itemlist.options:= treeitem.itemlist.options - + [no_checkbox,no_updatechildchecked]; + end; + treeitem.itemlist.clear; + int1:= 0; + if froot = '' then begin + treeitem.itemlist.options:= treeitem.itemlist.options - [no_nofreeitems]; + treeitem.itemlist.count:= 1; + aitem:= tdirlistitem(treeitem.itemlist[0]); + ar1:= splitrootpath(avalue); + {$ifdef mswindows} + treeitem.itemlist.count:= 2; + uncitem:= tdirlistitem(treeitem.itemlist[1]); + initdirfileinfo(uncitem.finfo,'//'); //UNC + uncitem.updateinfo; + {$endif} + + if (high(ar1) > 0) and (ar1[0] = '') then begin + {$ifdef mswindows} + initdirfileinfo(aitem.finfo,'/'); + aitem.updateinfo; + aitem:= uncitem; + {$else} + initdirfileinfo(aitem.finfo,'//'); //UNC simulation + {$endif} + int1:= 1; + end + else begin + initdirfileinfo(aitem.finfo,'/'); + end; + aitem.updateinfo; + end + else begin + frootitem.free(); + initdirfileinfo(info1,filepath(froot,fk_file)); + frootitem:= tdirlistitem.create(nil,nil); + aitem:= frootitem; + initdirfileinfo(aitem.finfo,filepath(froot)); + aitem.froot:= froot; + aitem.updateinfo; + aitem.expanded:= true; + adddir(aitem); + treeitem.itemlist.options:= treeitem.itemlist.options + [no_nofreeitems]; + //destroyed by root node + treeitem.itemlist.addchildren(aitem); + ar1:= splitfilepath(relativepath(filepath(froot,avalue),froot,fk_file)); + if (ar1 <> nil) and (ar1[0] = '..') then begin + int1:= 1; //UNC + end; + end; + item1:= aitem; + for int1:= int1 to high(ar1) do begin + aitem.expanded:= true; + aitem:= aitem.findsubdir(ar1[int1]); + if aitem = nil then begin + break; + end; + item1:= aitem; + end; + grid.focuscell(makegridcoord(0,treeitem.itemlist.indexof(item1)), + fca_setfocusedcell); +end; + +procedure tdirtreefo.setpath(const avalue: filenamety); +begin + fpath:= avalue; + updatepath(); +end; + +procedure tdirtreefo.treeitemoncellevent(const sender: tobject; + var info: celleventinfoty); +begin + case info.eventkind of + cek_enter: begin + if assigned(fonpathchanged) then begin + fonpathchanged(self); + end; + end; + end; + if treeitem.item <> nil then begin + if (info.zone = cz_caption) then begin + if iscellclick(info) then begin + treeitem.checkvalue; + end; + end; + if iscellclick(info,[],[],keyshiftstatesmask) and + (info.zone in [cz_caption,cz_image]) then begin + if (ss_double in info.mouseeventinfopo^.shiftstate) and + (dto_expandondblclick in foptionsdir) then begin + treeitem.item.expanded:= not treeitem.item.expanded; + end + else begin + if (dto_expandonclick in foptionsdir) then begin + treeitem.item.expanded:= true; + end; + end; + end; + end; +end; + +procedure tdirtreefo.treeitemoncreateitem(const sender: tcustomitemlist; + var item: ttreelistedititem); +begin + item:= tdirlistitem.create(sender); + if dto_checkbox in foptionsdir then begin + with tdirlistitem(item) do begin + fstate:= fstate + [ns_checkbox,ns_showchildchecked]; + froot:= self.froot; + end; + end; +end; + +procedure tdirtreefo.doondataentered(); +begin + window.modalresult:= mr_ok; +end; + +procedure tdirtreefo.treeitemondataentered(const sender: tobject); +begin + doondataentered(); +end; + +procedure tdirtreefo.treeitemonitemnotification(const sender: tlistitem; + var action: nodeactionty); +var + bo1: boolean; +begin + with tdirlistitem(sender) do begin + case action of + na_checkedchange: begin + if canevent(tmethod(fonselectionchanged)) then begin + fonselectionchanged(self,sender); + end; + end; + na_expand: begin + include(finfo.state,fis_diropen); + updateinfo; + if (count = 0) or + (foptionsdir*[dto_checkbox,dto_nocollapseclear] = []) then begin + adddir(tdirlistitem(sender)); + end; + if count = 0 then begin + state:= state - [ns_subitems,ns_expanded]; + action:= na_none; + end; + end; + na_collapse: begin + bo1:= count > 0; + if foptionsdir * [dto_checkbox,dto_nocollapseclear] = [] then begin + clear; + end; + if bo1 then begin + state:= state + [ns_subitems]; + end; + exclude(finfo.state,fis_diropen); + updateinfo; + end; + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/dialogs/msedirtree_mfm.pas b/mseide-msegui/lib/common/dialogs/msedirtree_mfm.pas new file mode 100644 index 0000000..306ea2d --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msedirtree_mfm.pas @@ -0,0 +1,98 @@ +unit msedirtree_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msedirtree; + +const + objdata: record size: integer; data: array[0..1604] of byte end = + (size: 1605; data: ( + 84,80,70,48,10,116,100,105,114,116,114,101,101,102,111,9,100,105,114,116, + 114,101,101,102,111,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100, + 115,95,120,2,80,8,98,111,117,110,100,115,95,121,3,118,1,9,98,111, + 117,110,100,115,95,99,120,3,44,1,9,98,111,117,110,100,115,95,99,121, + 3,203,0,12,98,111,117,110,100,115,95,99,120,109,105,110,3,200,0,26, + 99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,0,27,99,111,110,116,97,105,110,101,114,46,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,99, + 111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0, + 3,44,1,3,203,0,0,13,111,112,116,105,111,110,115,119,105,110,100,111, + 119,11,8,119,111,95,112,111,112,117,112,17,119,111,95,98,117,116,116,111, + 110,101,110,100,109,111,100,97,108,0,7,111,112,116,105,111,110,115,11,13, + 102,111,95,99,108,111,115,101,111,110,101,115,99,17,102,111,95,108,111,99, + 97,108,115,104,111,114,116,99,117,116,115,15,102,111,95,97,117,116,111,114, + 101,97,100,115,116,97,116,16,102,111,95,97,117,116,111,119,114,105,116,101, + 115,116,97,116,0,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109, + 101,6,8,116,109,115,101,102,111,114,109,0,11,116,119,105,100,103,101,116, + 103,114,105,100,4,103,114,105,100,12,102,114,97,109,101,46,108,101,118,101, + 108,111,2,0,16,102,114,97,109,101,46,102,114,97,109,101,119,105,100,116, + 104,2,1,16,102,114,97,109,101,46,99,111,108,111,114,102,114,97,109,101, + 4,2,0,0,160,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,14,102,114,108,95,102, + 114,97,109,101,119,105,100,116,104,14,102,114,108,95,99,111,108,111,114,102, + 114,97,109,101,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,44,1, + 9,98,111,117,110,100,115,95,99,121,3,203,0,7,97,110,99,104,111,114, + 115,11,0,14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,1, + 14,100,97,116,97,99,111,108,115,46,105,116,101,109,115,14,7,8,116,114, + 101,101,105,116,101,109,1,9,108,105,110,101,119,105,100,116,104,2,0,12, + 99,111,108,111,114,102,111,99,117,115,101,100,4,7,0,0,144,5,119,105, + 100,116,104,3,42,1,7,111,112,116,105,111,110,115,11,11,99,111,95,114, + 101,97,100,111,110,108,121,7,99,111,95,102,105,108,108,12,99,111,95,115, + 97,118,101,118,97,108,117,101,0,8,111,112,116,105,111,110,115,49,11,11, + 99,111,49,95,114,111,119,102,111,110,116,12,99,111,49,95,114,111,119,99, + 111,108,111,114,14,99,111,49,95,122,101,98,114,97,99,111,108,111,114,18, + 99,111,49,95,114,111,119,99,111,108,111,114,97,99,116,105,118,101,19,99, + 111,49,95,114,111,119,99,111,108,111,114,102,111,99,117,115,101,100,15,99, + 111,49,95,114,111,119,114,101,97,100,111,110,108,121,16,99,111,49,95,97, + 117,116,111,99,111,108,119,105,100,116,104,0,10,119,105,100,103,101,116,110, + 97,109,101,6,8,116,114,101,101,105,116,101,109,9,100,97,116,97,99,108, + 97,115,115,7,17,116,116,114,101,101,105,116,101,109,101,100,105,116,108,105, + 115,116,18,100,97,116,97,108,105,115,116,46,105,109,97,103,101,108,105,115, + 116,7,20,102,105,108,101,100,105,97,108,111,103,114,101,115,46,105,109,97, + 103,101,115,19,100,97,116,97,108,105,115,116,46,105,109,97,103,101,119,105, + 100,116,104,2,16,20,100,97,116,97,108,105,115,116,46,105,109,97,103,101, + 104,101,105,103,104,116,2,16,27,100,97,116,97,108,105,115,116,46,111,110, + 105,116,101,109,110,111,116,105,102,105,99,97,116,105,111,110,7,26,116,114, + 101,101,105,116,101,109,111,110,105,116,101,109,110,111,116,105,102,105,99,97, + 116,105,111,110,21,100,97,116,97,108,105,115,116,46,111,110,99,114,101,97, + 116,101,105,116,101,109,7,20,116,114,101,101,105,116,101,109,111,110,99,114, + 101,97,116,101,105,116,101,109,0,0,16,100,97,116,97,114,111,119,108,105, + 110,101,119,105,100,116,104,2,0,13,100,97,116,97,114,111,119,104,101,105, + 103,104,116,2,16,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,13,116,116,114,101,101,105,116,101,109,101,100,105,116,8,116,114,101, + 101,105,116,101,109,11,111,112,116,105,111,110,115,115,107,105,110,11,19,111, + 115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110,108,121,0,6, + 99,117,114,115,111,114,7,8,99,114,95,97,114,114,111,119,12,102,114,97, + 109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99,111, + 108,111,114,99,108,105,101,110,116,4,2,0,0,128,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118, + 101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 8,116,97,98,111,114,100,101,114,2,1,7,118,105,115,105,98,108,101,8, + 8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121, + 2,0,9,98,111,117,110,100,115,95,99,120,3,42,1,9,98,111,117,110, + 100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49, + 11,13,111,101,49,95,115,97,118,101,118,97,108,117,101,0,11,111,112,116, + 105,111,110,115,101,100,105,116,11,11,111,101,95,114,101,97,100,111,110,108, + 121,12,111,101,95,117,110,100,111,111,110,101,115,99,16,111,101,95,99,104, + 101,99,107,109,114,99,97,110,99,101,108,24,111,101,95,102,111,114,99,101, + 114,101,116,117,114,110,99,104,101,99,107,118,97,108,117,101,18,111,101,95, + 104,105,110,116,99,108,105,112,112,101,100,116,101,120,116,9,111,101,95,108, + 111,99,97,116,101,0,13,111,110,100,97,116,97,101,110,116,101,114,101,100, + 7,21,116,114,101,101,105,116,101,109,111,110,100,97,116,97,101,110,116,101, + 114,101,100,11,111,110,99,101,108,108,101,118,101,110,116,7,19,116,114,101, + 101,105,116,101,109,111,110,99,101,108,108,101,118,101,110,116,7,111,112,116, + 105,111,110,115,11,16,116,101,111,95,116,114,101,101,99,111,108,110,97,118, + 105,103,21,116,101,111,95,101,110,116,101,114,111,110,105,109,97,103,101,99, + 108,105,99,107,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tdirtreefo,''); +end. diff --git a/mseide-msegui/lib/common/dialogs/msedirtreesub.mfm b/mseide-msegui/lib/common/dialogs/msedirtreesub.mfm new file mode 100644 index 0000000..43e5e28 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msedirtreesub.mfm @@ -0,0 +1,21 @@ +inherited dirtreesubfo: tdirtreesubfo + visible = True + container.bounds = ( + 0 + 0 + 300 + 203 + ) + moduleclassname = 'tdirtreefo' + inherited grid: twidgetgrid + frame.levelo = -2 + frame.framewidth = 0 + datacols.items = < + item[treeitem] + width = 296 + end> + inherited treeitem: ttreeitemedit + bounds_cx = 296 + end + end +end diff --git a/mseide-msegui/lib/common/dialogs/msedirtreesub.pas b/mseide-msegui/lib/common/dialogs/msedirtreesub.pas new file mode 100644 index 0000000..556e414 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msedirtreesub.pas @@ -0,0 +1,35 @@ +unit msedirtreesub; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,msewidgets,mseforms, + msedirtree,msefiledialog,mclasses; + +type + tdirtreesubfo = class(tdirtreefo) + private + protected + procedure doondataentered(); override; + public + constructor create(aowner: tcomponent); override; + published + end; + +implementation +uses + msedirtreesub_mfm; + +{ tdirtreesubfo } + +procedure tdirtreesubfo.doondataentered(); +begin + //do nothing +end; + +constructor tdirtreesubfo.create(aowner: tcomponent); +begin + inherited; +end; + +end. diff --git a/mseide-msegui/lib/common/dialogs/msedirtreesub_mfm.pas b/mseide-msegui/lib/common/dialogs/msedirtreesub_mfm.pas new file mode 100644 index 0000000..b43463c --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msedirtreesub_mfm.pas @@ -0,0 +1,29 @@ +unit msedirtreesub_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msedirtreesub; + +const + objdata: record size: integer; data: array[0..230] of byte end = + (size: 231; data: ( + 84,80,70,48,241,13,116,100,105,114,116,114,101,101,115,117,98,102,111,12, + 100,105,114,116,114,101,101,115,117,98,102,111,7,118,105,115,105,98,108,101, + 9,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2, + 0,2,0,3,44,1,3,203,0,0,15,109,111,100,117,108,101,99,108,97, + 115,115,110,97,109,101,6,10,116,100,105,114,116,114,101,101,102,111,0,241, + 11,116,119,105,100,103,101,116,103,114,105,100,4,103,114,105,100,12,102,114, + 97,109,101,46,108,101,118,101,108,111,2,254,16,102,114,97,109,101,46,102, + 114,97,109,101,119,105,100,116,104,2,0,14,100,97,116,97,99,111,108,115, + 46,105,116,101,109,115,14,7,8,116,114,101,101,105,116,101,109,1,5,119, + 105,100,116,104,3,40,1,0,0,0,241,13,116,116,114,101,101,105,116,101, + 109,101,100,105,116,8,116,114,101,101,105,116,101,109,9,98,111,117,110,100, + 115,95,99,120,3,40,1,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tdirtreesubfo,''); +end. diff --git a/mseide-msegui/lib/common/dialogs/msefiledialog.mfm b/mseide-msegui/lib/common/dialogs/msefiledialog.mfm new file mode 100644 index 0000000..3d04c98 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msefiledialog.mfm @@ -0,0 +1,346 @@ +object filedialogfo: Tfiledialogfo + optionswidget = [ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets, ow_hinton] + visible = False + bounds_x = 14 + bounds_y = 326 + bounds_cx = 587 + bounds_cy = 307 + bounds_cxmin = 360 + bounds_cymin = 150 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.frame.localprops = [] + container.frame.localprops1 = [] + container.onlayout = layoutev + container.bounds = ( + 0 + 0 + 587 + 307 + ) + options = [fo_screencentered, fo_closeonesc, fo_localshortcuts, fo_autoreadstat, fo_autowritestat, fo_savepos] + onloaded = formoncreate + onkeydown = listviewonkeydown + onlayout = layoutev + left = 239 + top = 138 + moduleclassname = 'tmseform' + object listview: tfilelistview + optionswidget = [ow_mousefocus, ow_arrowfocus, ow_focusbackonesc, ow_mousewheel, ow_destroywidgets] + frame.localprops = [] + frame.localprops1 = [] + taborder = 1 + bounds_x = 0 + bounds_y = 24 + bounds_cx = 587 + bounds_cy = 236 + anchors = [an_top] + onkeydown = listviewonkeydown + datarowlinecolor = -1610612731 + datacollinecolor = -1610612731 + cellwidth = 174 + cellheight = 15 + optionsgrid = [og_colsizing, og_focuscellonenter, og_mousescrollcol] + options = [lvo_readonly, lvo_drawfocus, lvo_mouseselect, lvo_keyselect, lvo_multiselect, lvo_locate, lvo_hintclippedtext] + itemlist.imagelist = filedialogres.images + itemlist.imagewidth = 16 + itemlist.imageheight = 16 + cellwidthmin = 50 + onselectionchanged = listviewselectionchanged + onitemevent = listviewitemevent + filelist.options = [flo_sortname, flo_sorttype] + onlistread = listviewonlistread + reffontheight = 14 + end + object tlayouter2: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + bounds_x = 0 + bounds_y = 262 + bounds_cx = 585 + bounds_cy = 42 + anchors = [an_left, an_right, an_bottom] + optionsscale = [osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + linktop = listview + dist_top = 2 + options = [spao_gluebottom] + object bucont: tspacer + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_mousewheel, ow_destroywidgets] + taborder = 1 + visible = True + bounds_x = 454 + bounds_y = 0 + bounds_cx = 131 + bounds_cy = 42 + anchors = [an_top, an_right] + optionsscale = [osc_expandx, osc_shrinkx, osc_expandy, osc_shrinky] + linkleft = tlayouter1 + options = [spao_glueright, spao_gluebottom] + object showhidden: tbooleanedit + frame.caption = '&Show hidden files' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 112 + 2 + ) + bounds_x = 6 + bounds_y = 4 + bounds_cx = 125 + bounds_cy = 16 + onsetvalue = showhiddenonsetvalue + end + object tspacer4: tspacer + taborder = 3 + bounds_x = 41 + bounds_y = 22 + bounds_cx = 8 + bounds_cy = 20 + linkleft = ok + linkright = cancel + end + object cancel: tbutton + optionswidget1 = [ow1_autowidth, ow1_autoheight] + optionswidget = [ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + taborder = 2 + bounds_x = 49 + bounds_y = 22 + bounds_cx = 52 + bounds_cy = 20 + bounds_cxmin = 35 + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + options = [bo_executeonclick, bo_executeonkey, bo_executeonshortcut, bo_executedefaultonenterkey, bo_candefocuswindow] + end + object ok: tbutton + optionswidget1 = [ow1_autowidth, ow1_autoheight] + optionswidget = [ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + color = -1879048187 + taborder = 1 + bounds_x = 6 + bounds_y = 22 + bounds_cx = 35 + bounds_cy = 20 + bounds_cxmin = 35 + state = [as_default, as_localdefault, as_localcaption, as_localonexecute] + caption = '&Ok' + options = [bo_executeonclick, bo_executeonkey, bo_executeonshortcut, bo_executedefaultonenterkey, bo_candefocuswindow] + onexecute = okonexecute + end + end + object tlayouter1: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + bounds_x = 1 + bounds_y = 0 + bounds_cx = 453 + bounds_cy = 42 + optionsscale = [osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_alignx, lao_placey] + align_mode = wam_end + align_glue = wam_end + place_mindist = 2 + place_maxdist = 2 + object filter: tdropdownlistedit + frame.caption = '&Filter' + frame.captionpos = cp_right + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + end> + frame.outerframe = ( + 0 + 0 + 34 + 0 + ) + taborder = 1 + bounds_x = 0 + bounds_y = 22 + bounds_cx = 448 + ondataentered = filepathentered + onsetvalue = filteronsetvalue + dropdown.options = [deo_keydropdown, deo_cliphint] + dropdown.cols.count = 2 + dropdown.cols.items = < + item + end + item + options = [co_readonly, co_invisible, co_focusselect, co_fill] + end> + dropdown.valuecol = 1 + onafterclosedropdown = filteronafterclosedropdown + reffontheight = 14 + end + object filename: thistoryedit + frame.caption = '&Name' + frame.captionpos = cp_right + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + end> + frame.outerframe = ( + 0 + 0 + 39 + 0 + ) + bounds_x = 0 + bounds_y = 0 + bounds_cx = 453 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savevalue, oe1_savestate] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_resetselectonexit, oe_exitoncursor, oe_autoselect, oe_autoselectonfirstclick] + oncopytoclipboard = copytoclip + onpastefromclipboard = pastefromclip + onsetvalue = filenamesetvalue + dropdown.options = [deo_keydropdown, deo_cliphint] + dropdown.dropdownrowcount = 10 + dropdown.cols.count = 1 + dropdown.cols.items = < + item + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + end> + reffontheight = 14 + end + end + end + object tlayouter3: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + taborder = 2 + bounds_x = 1 + bounds_y = 2 + bounds_cx = 584 + bounds_cy = 20 + anchors = [an_left, an_top, an_right] + optionsscale = [osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_placex, lao_aligny] + align_glue = wam_start + place_mindist = 2 + place_maxdist = 2 + place_options = [plo_endmargin] + linkbottom = listview + dist_bottom = 2 + object createdir: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + optionswidget = [ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + taborder = 5 + bounds_x = 528 + bounds_y = 0 + bounds_cx = 56 + bounds_cy = 20 + bounds_cxmin = 35 + anchors = [an_top, an_right] + state = [as_localcaption, as_localonexecute] + caption = '&New dir' + options = [bo_executeonclick, bo_executeonkey, bo_executeonshortcut, bo_executedefaultonenterkey, bo_candefocuswindow] + onexecute = createdironexecute + reffontheight = 14 + end + object home: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + optionswidget = [ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + taborder = 4 + bounds_x = 480 + bounds_y = 0 + bounds_cx = 46 + bounds_cy = 20 + bounds_cxmin = 35 + anchors = [an_top, an_right] + state = [as_localcaption, as_localonexecute] + caption = '&Home' + options = [bo_executeonclick, bo_executeonkey, bo_executeonshortcut, bo_executedefaultonenterkey, bo_candefocuswindow] + onexecute = homeaction + reffontheight = 14 + end + object forward: tstockglyphbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_tabfocus, ow_arrowfocus, ow_destroywidgets, ow_disabledhint] + taborder = 3 + onshowhint = buttonshowhint + bounds_x = 465 + bounds_y = 0 + bounds_cx = 13 + bounds_cy = 20 + anchors = [an_top, an_right] + state = [as_disabled, as_localdisabled, as_localimagelist, as_localimagenr, as_localshortcut, as_localonexecute] + glyph = stg_arrowright + autosize_cx = -10 + onexecute = forwardexe + reffontheight = 14 + sc = ( + 1 + 24666 + ) + end + object back: tstockglyphbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_tabfocus, ow_arrowfocus, ow_destroywidgets, ow_disabledhint] + taborder = 2 + onshowhint = buttonshowhint + bounds_x = 450 + bounds_y = 0 + bounds_cx = 13 + bounds_cy = 20 + anchors = [an_top, an_right] + state = [as_disabled, as_localdisabled, as_localimagelist, as_localimagenr, as_localshortcut, as_localonexecute] + glyph = stg_arrowleft + autosize_cx = -10 + onexecute = backexe + reffontheight = 14 + sc = ( + 1 + 16474 + ) + end + object up: tstockglyphbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale] + optionswidget = [ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + taborder = 1 + onshowhint = buttonshowhint + bounds_x = 431 + bounds_y = 0 + bounds_cx = 17 + bounds_cy = 20 + anchors = [an_top, an_right] + state = [as_localcaption, as_localimagelist, as_localimagenr, as_localshortcut, as_localonexecute] + glyph = stg_arrowup + options = [bo_executeonclick, bo_executeonkey, bo_executeonshortcut, bo_executedefaultonenterkey, bo_candefocuswindow] + onexecute = upaction + reffontheight = 14 + sc = ( + 1 + 16662 + ) + end + object dir: tdirdropdownedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.caption = '&Dir' + frame.captionpos = cp_right + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + end> + frame.outerframe = ( + 0 + 0 + 20 + 0 + ) + onshowhint = dirshowhint + bounds_x = 0 + bounds_y = 0 + bounds_cx = 429 + anchors = [an_left, an_top, an_right] + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + dropdown.options = [deo_selectonly, deo_keydropdown] + onsetvalue = dironsetvalue + reffontheight = 14 + end + end +end diff --git a/mseide-msegui/lib/common/dialogs/msefiledialog.pas b/mseide-msegui/lib/common/dialogs/msefiledialog.pas new file mode 100644 index 0000000..3c43993 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msefiledialog.pas @@ -0,0 +1,2811 @@ +{ MSEgui Copyright (c) 1999-2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msefiledialog; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + mseglob,mseguiglob,mseforms,classes,mclasses,mseclasses,msewidgets,msegrids, + mselistbrowser,mseedit,msesimplewidgets,msedataedits,msedialog,msetypes, + msestrings,msesystypes,msesys,msedispwidgets,msedatalist,msestat,msestatfile, + msebitmap,msedatanodes,msefileutils,msedropdownlist,mseevent,msegraphedits, + mseeditglob,msesplitter,msemenus,msegridsglob,msegraphics,msegraphutils, + msedirtree,msewidgetgrid,mseact,mseapplication,msegui,mseificomp, + mseificompglob,mseifiglob,msestream,sysutils,msemenuwidgets,msescrollbar; + +const + defaultlistviewoptionsfile = defaultlistviewoptions + [lvo_readonly]; + +type + tfilelistitem = class(tlistitem) + private + protected + public + constructor create(const aowner: tcustomitemlist); override; + end; + pfilelistitem = ^tfilelistitem; + + tfileitemlist = class(titemviewlist) + protected + procedure createitem(out item: tlistitem); override; + end; + + getfileiconeventty = procedure(const sender: tobject; const ainfo: fileinfoty; + var imagelist: timagelist; var imagenr: integer) of object; + + tfilelistview = class(tlistview) + private + ffilelist: tfiledatalist; + foptionsfile: filelistviewoptionsty; + fmaskar: filenamearty; + fdirectory: filenamety; + ffilecount: integer; + fincludeattrib,fexcludeattrib: fileattributesty; + fonlistread: notifyeventty; + ffocusmoved: boolean; + fongetfileicon: getfileiconeventty; + foncheckfile: checkfileeventty; + procedure filelistchanged(const sender: tobject); + procedure setfilelist(const Value: tfiledatalist); + function getpath: msestring; + procedure setpath(const Value: msestring); + procedure setdirectory(const Value: msestring); + function getmask: filenamety; + procedure setmask(const value: filenamety); + function getselectednames: filenamearty; + procedure setselectednames(const avalue: filenamearty); + function getchecksubdir: boolean; + procedure setchecksubdir(const avalue: boolean); + procedure setoptionsfile(const avalue: filelistviewoptionsty); + procedure checkcasesensitive; + protected + foptionsdir: dirstreamoptionsty; + fcaseinsensitive: boolean; +// procedure setoptions(const Value: listviewoptionsty); override; + procedure docellevent(var info: celleventinfoty); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure readlist; + procedure updir; + function filecount: integer; + property directory: filenamety read fdirectory write setdirectory; + property includeattrib: fileattributesty read fincludeattrib + write fincludeattrib default [fa_all]; + property excludeattrib: fileattributesty read fexcludeattrib + write fexcludeattrib default [fa_hidden]; + property maskar: filenamearty read fmaskar write fmaskar; //nil -> all + property path: filenamety read getpath write setpath; + //calls readlist + property selectednames: filenamearty read getselectednames write setselectednames; + property checksubdir: boolean read getchecksubdir write setchecksubdir; + published + property mask: filenamety read getmask write setmask; //'' -> all + property options default defaultlistviewoptionsfile; + property optionsfile: filelistviewoptionsty read foptionsfile + write setoptionsfile default defaultfilelistviewoptions; + property filelist: tfiledatalist read ffilelist write setfilelist; + property onlistread: notifyeventty read fonlistread write fonlistread; + property ongetfileicon: getfileiconeventty read fongetfileicon + write fongetfileicon; + property oncheckfile: checkfileeventty read foncheckfile write foncheckfile; + end; + +const + defaulthistorymaxcount = 20; + +type + filedialogoptionty = (fdo_filtercasesensitive, //flvo_maskcasesensitive + fdo_filtercaseinsensitive, //flvo_maskcaseinsensitive + fdo_save, + fdo_dispname,fdo_dispnoext,fdo_sysfilename,fdo_params, + fdo_directory,fdo_file, + fdo_absolute,fdo_relative,fdo_lastdirrelative, + fdo_basedirrelative, + fdo_quotesingle, + fdo_link, //links lastdir of controllers with same group + fdo_checkexist,fdo_acceptempty,fdo_single, + fdo_chdir,fdo_savelastdir, + fdo_checksubdir); + filedialogoptionsty = set of filedialogoptionty; +const + defaultfiledialogoptions = [fdo_savelastdir]; +type + filedialogkindty = (fdk_none,fdk_open,fdk_save,fdk_new); + + tfiledialogcontroller = class; + + filedialogbeforeexecuteeventty = procedure(const sender: tfiledialogcontroller; + var dialogkind: filedialogkindty; var aresult: modalresultty) of object; + filedialogafterexecuteeventty = procedure(const sender: tfiledialogcontroller; + var aresult: modalresultty) of object; + + tfiledialogcontroller = class(tlinkedpersistent) + private + fowner: tmsecomponent; + fgroup: integer; + fonchange: proceventty; + ffilenames: filenamearty; + ffilterlist: tdoublemsestringdatalist; + ffilter: filenamety; + ffilterindex: integer; + fcolwidth: integer; + fwindowrect: rectty; + fhistorymaxcount: integer; + fhistory: msestringarty; + fcaptionopen: msestring; + fcaptionsave: msestring; + fcaptionnew: msestring; + finclude: fileattributesty; + fexclude: fileattributesty; + fonbeforeexecute: filedialogbeforeexecuteeventty; + fonafterexecute: filedialogafterexecuteeventty; + fongetfilename: setstringeventty; + fongetfileicon: getfileiconeventty; + foncheckfile: checkfileeventty; + fimagelist: timagelist; + fparams: msestring; + procedure setfilterlist(const Value: tdoublemsestringdatalist); + procedure sethistorymaxcount(const Value: integer); + function getfilename: filenamety; + procedure setfilename(const avalue: filenamety); + procedure dochange; + procedure setdefaultext(const avalue: filenamety); + procedure setoptions(Value: filedialogoptionsty); + procedure checklink; + procedure setlastdir(const avalue: filenamety); + procedure setimagelist(const avalue: timagelist); + function getsysfilename: filenamety; + protected + flastdir: filenamety; + fbasedir: filenamety; + fdefaultext: filenamety; + foptions: filedialogoptionsty; + public + constructor create(const aowner: tmsecomponent = nil; + const onchange: proceventty = nil); reintroduce; + destructor destroy; override; + procedure readstatvalue(const reader: tstatreader); + procedure readstatstate(const reader: tstatreader); + procedure readstatoptions(const reader: tstatreader); + procedure writestatvalue(const writer: tstatwriter); + procedure writestatstate(const writer: tstatwriter); + procedure writestatoptions(const writer: tstatwriter); + function actcaption(const dialogkind: filedialogkindty): msestring; + function execute(dialogkind: filedialogkindty = fdk_none): modalresultty; overload; + //fdk_none -> use options fdo_save + function execute(dialogkind: filedialogkindty; const acaption: msestring; + aoptions: filedialogoptionsty): modalresultty; overload; + function execute(const dialogkind: filedialogkindty; + const acaption: msestring): modalresultty; overload; + function execute(const dialogkind: filedialogkindty; + const aoptions: filedialogoptionsty): modalresultty; overload; + function execute(var avalue: filenamety; + dialogkind: filedialogkindty = fdk_none): boolean; overload; + function execute(var avalue: filenamety; const dialogkind: filedialogkindty; + const acaption: msestring): boolean; overload; + function execute(var avalue: filenamety; const dialogkind: filedialogkindty; + const acaption: msestring; + aoptions: filedialogoptionsty): boolean; overload; + function canoverwrite(): boolean; + //true if current filename is allowed to write + procedure clear; + procedure setfilenamelastdir(const afilename: filenamety); + //lastdir relative + procedure componentevent(const event: tcomponentevent); + property history: msestringarty read fhistory write fhistory; + property filenames: filenamearty read ffilenames write ffilenames; + property syscommandline: filenamety read getsysfilename; deprecated; + property sysfilename: filenamety read getsysfilename; + property params: msestring read fparams; + published + property filename: filenamety read getfilename write setfilename; + property lastdir: filenamety read flastdir write setlastdir; + property basedir: filenamety read fbasedir write fbasedir; + property filter: filenamety read ffilter write ffilter; + property filterlist: tdoublemsestringdatalist read ffilterlist write setfilterlist; + property filterindex: integer read ffilterindex write ffilterindex default 0; + property include: fileattributesty read finclude write finclude default [fa_all]; + property exclude: fileattributesty read fexclude write fexclude default [fa_hidden]; + property colwidth: integer read fcolwidth write fcolwidth default 0; + property defaultext: filenamety read fdefaultext write setdefaultext; + property options: filedialogoptionsty read foptions write setoptions + default defaultfiledialogoptions; + property historymaxcount: integer read fhistorymaxcount + write sethistorymaxcount default defaulthistorymaxcount; + property captionopen: msestring read fcaptionopen write fcaptionopen; + property captionsave: msestring read fcaptionsave write fcaptionsave; + property captionnew: msestring read fcaptionnew write fcaptionnew; + property group: integer read fgroup write fgroup default 0; + property imagelist: timagelist read fimagelist write setimagelist; + property ongetfilename: setstringeventty read fongetfilename write fongetfilename; + property ongetfileicon: getfileiconeventty read fongetfileicon + write fongetfileicon; + property oncheckfile: checkfileeventty read foncheckfile write foncheckfile; + property onbeforeexecute: filedialogbeforeexecuteeventty + read fonbeforeexecute write fonbeforeexecute; + property onafterexecute: filedialogafterexecuteeventty + read fonafterexecute write fonafterexecute; + end; + +const + defaultfiledialogoptionsedit1 = defaultoptionsedit1+ + [oe1_savevalue,oe1_savestate,oe1_saveoptions]; + +type + tfiledialog = class(tdialog,istatfile) + private + fcontroller: tfiledialogcontroller; + fstatvarname: msestring; + fstatfile: tstatfile; + fdialogkind: filedialogkindty; +// foptionsedit: optionseditty; + foptionsedit1: optionsedit1ty; + fstatpriority: integer; + procedure setcontroller(const value: tfiledialogcontroller); + procedure setstatfile(const Value: tstatfile); + procedure readoptionsedit(reader: treader); + protected + procedure defineproperties(filer: tfiler); override; + //istatfile + procedure dostatread(const reader: tstatreader); + procedure dostatwrite(const writer: tstatwriter); + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function execute: modalresultty; overload; override; + function execute(const akind: filedialogkindty): modalresultty; + reintroduce; overload; + function execute(const akind: filedialogkindty; + const aoptions: filedialogoptionsty): modalresultty; + reintroduce; overload; + procedure componentevent(const event: tcomponentevent); override; + published + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read getstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + property controller: tfiledialogcontroller read fcontroller + write setcontroller; + property dialogkind: filedialogkindty read fdialogkind write fdialogkind + default fdk_none; + property optionsedit1: optionsedit1ty read foptionsedit1 write foptionsedit1 + default defaultfiledialogoptionsedit1; + end; + + tcustomfilenameedit1 = class; + tfilenameeditcontroller = class(tstringdialogcontroller) + protected + function execute(var avalue: msestring): boolean; override; + public + constructor create(const aowner: tcustomfilenameedit1); + end; + + tcustomfilenameedit1 = class(tcustomdialogstringed) + private + fcontroller: tfiledialogcontroller; + procedure setcontroller(const avalue: tfiledialogcontroller); + function getsysvalue: filenamety; + procedure setsysvalue(const avalue: filenamety); + function getsysvaluequoted: filenamety; + protected + function createdialogcontroller: tstringdialogcontroller; override; + procedure texttovalue(var accept: boolean; const quiet: boolean); override; + procedure updatedisptext(var avalue: msestring); override; + function getvaluetext: msestring; override; + procedure readstatvalue(const reader: tstatreader); override; + procedure readstatstate(const reader: tstatreader); override; + procedure readstatoptions(const reader: tstatreader); override; + procedure writestatvalue(const writer: tstatwriter); override; + procedure writestatstate(const writer: tstatwriter); override; + procedure writestatoptions(const writer: tstatwriter); override; + procedure valuechanged; override; + procedure updatecopytoclipboard(var atext: msestring); override; + procedure updatepastefromclipboard(var atext: msestring); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure componentevent(const event: tcomponentevent); override; + property controller: tfiledialogcontroller read fcontroller + write setcontroller; + property sysvalue: filenamety read getsysvalue write setsysvalue; + property sysvaluequoted: filenamety read getsysvaluequoted write setsysvalue; + published + property optionsedit1 default defaultfiledialogoptionsedit1; + end; + + tcustomfilenameedit = class(tcustomfilenameedit1) + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + end; + + tcustomremotefilenameedit = class(tcustomfilenameedit1) + private + fdialog: tfiledialog; + procedure setfiledialog(const avalue: tfiledialog); + protected + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + public + property dialog: tfiledialog read fdialog write setfiledialog; + end; + + tfilenameedit = class(tcustomfilenameedit) + published + property frame; + property passwordchar; + property maxlength; + property value; + property onsetvalue; + property controller; + end; + + tremotefilenameedit = class(tcustomremotefilenameedit) + published + property frame; + property passwordchar; + property maxlength; + property value; + property onsetvalue; + property dialog; + end; + + dirdropdowneditoptionty = (ddeo_showhiddenfiles,ddeo_checksubdir); + dirdropdowneditoptionsty = set of dirdropdowneditoptionty; + + tdirdropdownedit = class(tdropdownwidgetedit) + private + foptions: dirdropdowneditoptionsty; + function getshowhiddenfiles: boolean; + procedure setshowhiddenfiles(const avalue: boolean); + function getchecksubdir: boolean; + procedure setchecksubdir(const avalue: boolean); + protected + procedure createdropdownwidget(const atext: msestring; + out awidget: twidget); override; + function getdropdowntext(const awidget: twidget): msestring; override; + procedure pathchanged(const sender: tobject); + procedure doafterclosedropdown; override; + procedure updatecopytoclipboard(var atext: msestring); override; + procedure updatepastefromclipboard(var atext: msestring); override; + public + property showhiddenfiles: boolean read getshowhiddenfiles + write setshowhiddenfiles; + property checksubdir: boolean read getchecksubdir + write setchecksubdir; + published + property options: dirdropdowneditoptionsty read foptions + write foptions default []; + end; + + dirtreepatheventty = procedure(const sender: tobject; + const avalue: msestring) of object; + + tdirtreeview = class(tpublishedwidget,icaptionframe) + private + fonpathchanged: dirtreepatheventty; + fonpathselected: dirtreepatheventty; + fonselectionchanged: listitemeventty; + function getoptions: dirtreeoptionsty; + procedure setoptions(const avalue: dirtreeoptionsty); + function getpath: filenamety; + procedure setpath(const avalue: filenamety); + procedure setroot(const avalue: filenamety); + function getgrid: twidgetgrid; + procedure setgrid(const avalue: twidgetgrid); + function getoptionstree: treeitemeditoptionsty; + procedure setoptionstree(const avalue: treeitemeditoptionsty); + function getoptionsedit: optionseditty; + procedure setoptionsedit(const avalue: optionseditty); + function getcol_color: colorty; + procedure setcol_color(const avalue: colorty); + function getcol_coloractive: colorty; + procedure setcol_coloractive(const avalue: colorty); + function getcol_colorfocused: colorty; + procedure setcol_colorfocused(const avalue: colorty); + function getcell_options: coloptionsty; + procedure setcell_options(const avalue: coloptionsty); + { + function getcell_frame: tcellframe; + procedure setcell_frame(const avalue: tcellframe); + function getcell_face: tcellface; + procedure setcell_face(const avalue: tcellface); + function getcell_datalist: ttreeitemeditlist; + procedure setcell_datalist(const avalue: ttreeitemeditlist); + } + protected + fdirview: tdirtreefo; + fpath: filenamety; + froot: filenamety; + procedure dopathchanged(const sender: tobject); + procedure dopathselected(const sender: tobject); + procedure doselectionchanged(const sender: tobject; const aitem: tlistitem); + procedure internalcreateframe; override; + procedure loaded(); override; + class function classskininfo: skininfoty; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy(); override; + procedure refresh(); + property dirview: tdirtreefo read fdirview; + property path: filenamety read getpath write setpath; + property root: filenamety read froot write setroot; + published + property font: twidgetfont read getfont write setfont stored isfontstored; + property options: dirtreeoptionsty read getoptions + write setoptions default []; + property optionstree: treeitemeditoptionsty read getoptionstree + write setoptionstree default [teo_treecolnavig,teo_enteronimageclick]; + property optionsedit: optionseditty read getoptionsedit write setoptionsedit + default [oe_readonly,oe_undoonesc,oe_checkmrcancel, + oe_forcereturncheckvalue,oe_hintclippedtext,oe_locate]; + property col_color: colorty read getcol_color + write setcol_color default cl_default; + property col_coloractive: colorty read getcol_coloractive + write setcol_coloractive default cl_none; + property col_colorfocused: colorty read getcol_colorfocused + write setcol_colorfocused default cl_active; + property col_options: coloptionsty read getcell_options + write setcell_options default [co_readonly,co_fill,co_savevalue]; +// property col_frame: tcellframe read getcell_frame write setcell_frame; +// property col_face: tcellface read getcell_face write setcell_face; +// property col_datalist: ttreeitemeditlist read getcell_datalist +// write setcell_datalist; + property onpathchanged: dirtreepatheventty read + fonpathchanged write fonpathchanged; + property onpathselected: dirtreepatheventty read + fonpathselected write fonpathselected; + property onselectionchanged: listitemeventty read + fonselectionchanged write fonselectionchanged; //for checkboxes + property optionswidget default defaultoptionswidgetsubfocus; + end; + + tfiledialogfo = class(tmseform) + listview: tfilelistview; + tlayouter2: tlayouter; + bucont: tspacer; + showhidden: tbooleanedit; + tspacer4: tspacer; + cancel: tbutton; + ok: tbutton; + tlayouter1: tlayouter; + filter: tdropdownlistedit; + filename: thistoryedit; + tlayouter3: tlayouter; + createdir: tbutton; + home: tbutton; + forward: tstockglyphbutton; + back: tstockglyphbutton; + up: tstockglyphbutton; + dir: tdirdropdownedit; + procedure createdironexecute(const sender: TObject); + procedure listviewselectionchanged(const sender: tcustomlistview); + procedure listviewitemevent(const sender: tcustomlistview; + const index: Integer; var info: celleventinfoty); + procedure listviewonkeydown(const sender: twidget; var info: keyeventinfoty); + procedure upaction(const sender: TObject); + procedure dironsetvalue(const sender: TObject; var avalue: mseString; + var accept: Boolean); + procedure filenamesetvalue(const sender: TObject; var avalue: mseString; + var accept: Boolean); + procedure listviewonlistread(const sender: tobject); + procedure filteronafterclosedropdown(const sender: tobject); + procedure filteronsetvalue(const sender: tobject; var avalue: msestring; var accept: boolean); + procedure filepathentered(const sender: tobject); + procedure okonexecute(const sender: tobject); + procedure layoutev(const sender: TObject); + procedure showhiddenonsetvalue(const sender: TObject; var avalue: Boolean; + var accept: Boolean); + procedure formoncreate(const sender: TObject); + procedure dirshowhint(const sender: TObject; var info: hintinfoty); + procedure copytoclip(const sender: TObject; var avalue: msestring); + procedure pastefromclip(const sender: TObject; var avalue: msestring); + procedure homeaction(const sender: TObject); + procedure backexe(const sender: TObject); + procedure forwardexe(const sender: TObject); + procedure buttonshowhint(const sender: TObject; var ainfo: hintinfoty); + private + fselectednames: filenamearty; + finit: boolean; + fcourse: filenamearty; + fcourseid: int32; + fcourselock: boolean; + procedure updatefiltertext; + function tryreadlist(const adir: filenamety; + const errormessage: boolean): boolean; + //restores old dir on error + function changedir(const adir: filenamety): boolean; + procedure checkcoursebuttons(); + procedure course(const adir: filenamety); + procedure doup(); + public + dialogoptions: filedialogoptionsty; + defaultext: filenamety; + filenames: filenamearty; + end; + +function filedialog(var afilenames: filenamearty; + const aoptions: filedialogoptionsty; + const acaption: msestring; //'' -> 'Open' or 'Save' + const filterdesc: array of msestring; + const filtermask: array of msestring; + const adefaultext: filenamety = ''; + const filterindex: pinteger = nil; //nil -> 0 + const filter: pfilenamety = nil; //nil -> unused + const colwidth: pinteger = nil; //nil -> default + const includeattrib: fileattributesty = [fa_all]; + const excludeattrib: fileattributesty = [fa_hidden]; + const history: pmsestringarty = nil; + const historymaxcount: integer = defaulthistorymaxcount; + const imagelist: timagelist = nil; + const ongetfileicon: getfileiconeventty = nil; + const oncheckfile: checkfileeventty = nil + ): modalresultty; overload; +//threadsafe +function filedialog(var afilename: filenamety; + const aoptions: filedialogoptionsty; + const acaption: msestring; + const filterdesc: array of msestring; + const filtermask: array of msestring; + const adefaultext: filenamety = ''; + const filterindex: pinteger = nil; //nil -> 0 + const filter: pfilenamety = nil; //nil -> unused + const colwidth: pinteger = nil; //nil -> default + const includeattrib: fileattributesty = [fa_all]; + const excludeattrib: fileattributesty = [fa_hidden]; + const history: pmsestringarty = nil; + const historymaxcount: integer = defaulthistorymaxcount; + const imagelist: timagelist = nil; + const ongetfileicon: getfileiconeventty = nil; + const oncheckfile: checkfileeventty = nil + ): modalresultty; overload; +//threadsafe + +procedure getfileicon(const info: fileinfoty; var imagelist: timagelist; + out imagenr: integer); +procedure updatefileinfo(const item: tlistitem; const info: fileinfoty; + const withicon: boolean); + +implementation +uses + msefiledialog_mfm,msebits,mseactions, + msestringenter,msefiledialogres,msekeyboard, + msestockobjects,msesysintf,msearrayutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tdirtreefo1 = class(tdirtreefo); + tcomponent1 = class(tcomponent); + +procedure getfileicon(const info: fileinfoty; var imagelist: timagelist; + out imagenr: integer); +begin + with info do begin +// imagelist:= nil; + imagenr:= -1; + if fis_typevalid in state then begin + case extinfo1.filetype of + ft_dir: begin + if fis_diropen in state then begin + filedialogres.getfileicon(fdi_diropen,imagelist,imagenr); + end + else begin + if fis_hasentry in state then begin + filedialogres.getfileicon(fdi_direntry,imagelist,imagenr); + end + else begin + filedialogres.getfileicon(fdi_dir,imagelist,imagenr); + end; + end; + end; + ft_reg,ft_lnk: begin + filedialogres.getfileicon(fdi_file,imagelist,imagenr); + end; + end; + end; + end; +end; + +procedure updatefileinfo(const item: tlistitem; const info: fileinfoty; + const withicon: boolean); +var + aimagelist: timagelist; + aimagenr: integer; +begin + aimagelist:= item.imagelist; + item.caption:= info.name; + if withicon then begin + getfileicon(info,aimagelist,aimagenr); + item.imagelist:= aimagelist; + if aimagelist <> nil then begin + item.imagenr:= aimagenr; + end; + end; +end; + +function filedialog1(dialog: tfiledialogfo; var afilenames: filenamearty; + const filterdesc: array of msestring; + const filtermask: array of msestring; + const filterindex: pinteger; + const afilter: pfilenamety; //nil -> unused + const colwidth: pinteger; //nil -> default + const includeattrib: fileattributesty; + const excludeattrib: fileattributesty; + const history: pmsestringarty; + const historymaxcount: integer; + const acaption: msestring; + const aoptions: filedialogoptionsty; + const adefaultext: filenamety; + const imagelist: timagelist; + const ongetfileicon: getfileiconeventty; + const oncheckfile: checkfileeventty + ): modalresultty; +var + i1: integer; +begin + with dialog do begin + dir.checksubdir:= fdo_checksubdir in aoptions; + listview.checksubdir:= fdo_checksubdir in aoptions; + dialogoptions:= aoptions; + if fdo_filtercasesensitive in aoptions then begin + listview.optionsfile:= listview.optionsfile + [flvo_maskcasesensitive]; + end; + if fdo_filtercaseinsensitive in aoptions then begin + listview.optionsfile:= listview.optionsfile + [flvo_maskcaseinsensitive]; + end; + if fdo_single in aoptions then begin + listview.options:= listview.options - [lvo_multiselect]; + end; + defaultext:= adefaultext; + caption:= acaption; + listview.includeattrib:= includeattrib; + listview.excludeattrib:= excludeattrib; + listview.itemlist.imagelist:= imagelist; + if imagelist <> nil then begin + listview.itemlist.imagesize:= imagelist.size; + end; + listview.ongetfileicon:= ongetfileicon; + listview.oncheckfile:= oncheckfile; + filter.dropdown.cols[0].count:= high(filtermask) + 1; + for i1:= 0 to high(filtermask) do begin + if (i1 <= high(filterdesc)) and (filterdesc[i1] <> '') then begin + filter.dropdown.cols[0][i1]:= filterdesc[i1] + ' ('+filtermask[i1] + ')'; + end + else begin + filter.dropdown.cols[0][i1]:= filtermask[i1]; + end; + end; + filter.dropdown.cols[1].assignopenarray(filtermask); + if filterindex <> nil then begin + filter.dropdown.itemindex:= filterindex^; + end + else begin + filter.dropdown.itemindex:= 0; + end; + if (afilter = nil) or (afilter^ = '') or + (filter.dropdown.itemindex >= 0) and + (afilter^ = filter.dropdown.cols[1][filter.dropdown.itemindex]) then begin + updatefiltertext; + end + else begin + filter.value:= afilter^; + listview.mask:= afilter^; + end; + if history <> nil then begin + filename.dropdown.valuelist.asarray:= history^; + filename.dropdown.historymaxcount:= historymaxcount; + end + else begin + filename.dropdown.options:= [deo_disabled]; + end; + if (high(afilenames) = 0) and (fdo_directory in aoptions) then begin + filename.value:= filepath(afilenames[0]); + end + else begin + filename.value:= quotefilename(afilenames); + end; + if (colwidth <> nil) and (colwidth^ <> 0) then begin + listview.cellwidth:= colwidth^; + end; + finit:= true; + try + filename.checkvalue; + finally + finit:= false; + end; + showhidden.value:= not (fa_hidden in excludeattrib); + show(true); + result:= window.modalresult; + if result <> mr_ok then begin + result:= mr_cancel; + end; + if (colwidth <> nil) then begin + colwidth^:= listview.cellwidth; + end; + if result = mr_ok then begin + afilenames:= filenames; + if fdo_sysfilename in aoptions then begin + for i1:= 0 to high(afilenames) do begin + tosysfilepath1(afilenames[i1]); + end; + end; + if filterindex <> nil then begin + filterindex^:= filter.dropdown.itemindex; + end; + if afilter <> nil then begin + afilter^:= listview.mask; + end; + if high(afilenames) = 0 then begin + filename.dropdown.savehistoryvalue(afilenames[0]); + end; + if history <> nil then begin + history^:= filename.dropdown.valuelist.asarray; + end; + if fdo_chdir in aoptions then begin + setcurrentdirmse(listview.directory); + end; + end; + end; +end; + +function filedialog(var afilenames: filenamearty; + const aoptions: filedialogoptionsty; + const acaption: msestring; + const filterdesc: array of msestring; + const filtermask: array of msestring; + const adefaultext: filenamety = ''; + const filterindex: pinteger = nil; + const filter: pfilenamety = nil; //nil -> unused + const colwidth: pinteger = nil; //nil -> default + const includeattrib: fileattributesty = [fa_all]; + const excludeattrib: fileattributesty = [fa_hidden]; + const history: pmsestringarty = nil; + const historymaxcount: integer = defaulthistorymaxcount; + const imagelist: timagelist = nil; + const ongetfileicon: getfileiconeventty = nil; + const oncheckfile: checkfileeventty = nil + ): modalresultty; +var + dialog: tfiledialogfo; + str1: msestring; +begin + application.lock; + try + dialog:= tfiledialogfo.create(nil); + if acaption = '' then begin + with stockobjects do begin + if fdo_save in aoptions then begin + str1:= captions[sc_save]; + end + else begin + str1:= captions[sc_open]; + end; + end; + end + else begin + str1:= acaption; + end; + try + result:= filedialog1(dialog,afilenames,filterdesc,filtermask, + filterindex,filter,colwidth, + includeattrib,excludeattrib,history,historymaxcount,str1,aoptions, + adefaultext,imagelist,ongetfileicon,oncheckfile); + + finally + dialog.Free; + end; + finally + application.unlock; + end; +end; + +function filedialog(var afilename: filenamety; + const aoptions: filedialogoptionsty; + const acaption: msestring; + const filterdesc: array of msestring; + const filtermask: array of msestring; + const adefaultext: filenamety = ''; + const filterindex: pinteger = nil; + const filter: pfilenamety = nil; //nil -> unused + const colwidth: pinteger = nil; //nil -> default + const includeattrib: fileattributesty = [fa_all]; + const excludeattrib: fileattributesty = [fa_hidden]; + const history: pmsestringarty = nil; + const historymaxcount: integer = defaulthistorymaxcount; + const imagelist: timagelist = nil; + const ongetfileicon: getfileiconeventty = nil; + const oncheckfile: checkfileeventty = nil + ): modalresultty; +var + ar1: filenamearty; +begin + setlength(ar1,1); + ar1[0]:= afilename; + result:= filedialog(ar1,aoptions,acaption,filterdesc,filtermask,adefaultext, + filterindex, + filter,colwidth,includeattrib,excludeattrib,history,historymaxcount, + imagelist,ongetfileicon,oncheckfile); + if result = mr_ok then begin + if (high(ar1) > 0) or (fdo_quotesingle in aoptions) then begin + afilename:= quotefilename(ar1); + end + else begin + if high(ar1) = 0 then begin + afilename:= ar1[0]; + end + else begin + afilename:= ''; + end; + end; + end; +end; + +{ tfilelistview } + +constructor tfilelistview.create(aowner: tcomponent); +begin + fcaseinsensitive:= filesystemiscaseinsensitive; + fincludeattrib:= [fa_all]; + fexcludeattrib:= [fa_hidden]; + fitemlist:= tfileitemlist.create(self); + foptionsfile:= defaultfilelistviewoptions; + ffilelist:= tfiledatalist.create; + ffilelist.onchange:= {$ifdef FPC}@{$endif}filelistchanged; + inherited; + options:= defaultlistviewoptionsfile; + checkcasesensitive; +end; + +destructor tfilelistview.destroy; +begin + inherited; + ffilelist.Free; +end; + +procedure tfilelistview.checkcasesensitive; +begin + fcaseinsensitive:= filesystemiscaseinsensitive; + if flvo_maskcasesensitive in foptionsfile then begin + fcaseinsensitive:= false; + end; + if flvo_maskcaseinsensitive in foptionsfile then begin + fcaseinsensitive:= true; + end; +// options:= options; //set casesensitive +end; +{ +procedure tfilelistview.setoptions(const Value: listviewoptionsty); +begin + if fcaseinsensitive then begin + inherited setoptions(value - [lvo_casesensitive]); + end + else begin + inherited setoptions(value + [lvo_casesensitive]); + end; +end; +} +procedure tfilelistview.docellevent(var info: celleventinfoty); +var + index: integer; +begin + with info do begin + if iscellclick(info,[ccr_buttonpress]) then begin + options:= options + [lvo_focusselect]; + end; + case eventkind of + cek_enter: begin + if ffocusmoved then begin + options:= options + [lvo_focusselect]; + end + else begin + ffocusmoved:= true; + end; + inherited; + end; + cek_select: begin + index:= celltoindex(cell,false); + if index >= 0 then begin + if (flvo_nofileselect in foptionsfile) and + (ffilelist[index].extinfo1.filetype <> ft_dir) then begin + accept:= false; + end + else begin + if (flvo_nodirselect in foptionsfile) and + (ffilelist[index].extinfo1.filetype = ft_dir) then begin + accept:= false; + end; + end; + inherited; + end + else begin + inherited; + end; + end; + else begin + inherited; + end; + end; + end; +end; + +procedure tfilelistview.filelistchanged(const sender: tobject); +var + int1: integer; + po1: pfilelistitem; + po2: pfileinfoty; + imlist1: timagelist; + imnr1: integer; + bo1: boolean; +begin + options:= options - [lvo_focusselect]; + ffocusmoved:= false; + with ffilelist do begin + self.beginupdate; + self.fitemlist.beginupdate; + try + self.fitemlist.clear; + self.fitemlist.count:= count; + po1:= pfilelistitem(self.fitemlist.datapo); + po2:= pfileinfoty(datapo); + bo1:= checksubdir; + for int1:= 0 to count - 1 do begin + if bo1 and (po2^.extinfo1.filetype = ft_dir) and + dirhasentries(path+'/'+po2^.name,includeattrib,excludeattrib) then begin + include(po2^.state,fis_hasentry); + end; + updatefileinfo(po1^,po2^,true); + if assigned(fongetfileicon) then begin + imlist1:= po1^.imagelist; + imnr1:= po1^.imagenr; + fongetfileicon(self,po2^,imlist1,imnr1); + po1^.imagelist:= imlist1; + po1^.imagenr:= imnr1; + end; + inc(po1); + inc(po2); + end; + finally + self.fitemlist.endupdate; + self.endupdate; + end; + end; +end; + +function tfilelistview.getselectednames: msestringarty; +var + int1,int2: integer; +begin + int2:=0; + result:= nil; + for int1:= 0 to ffilelist.count - 1 do begin + if fitemlist[int1].selected then begin + additem(result,ffilelist[int1].name,int2); + end; + end; + setlength(result,int2); +end; + +procedure tfilelistview.setselectednames(const avalue: filenamearty); +var + int1: integer; + item1: tlistitem; + po1: plistitematy; +// cell1: gridcoordty; +begin + po1:= fitemlist.datapo; + fitemlist.beginupdate; + try + for int1:= 0 to fitemlist.count - 1 do begin + po1^[int1].selected:= false; + end; + for int1:= 0 to high(avalue) do begin + item1:= finditembycaption(avalue[int1]); + if item1 <> nil then begin + item1.selected:= true; + end; + end; + finally + fitemlist.endupdate; + end; +{ + for int1:= 0 to high(avalue) do begin + if findcellbycaption(avalue[int1],cell1) then begin + fdatacols.selected[cell1]:= true; + end; + end; + } +// focuscell(cell1); +end; + +procedure tfilelistview.setfilelist(const Value: tfiledatalist); +begin + if ffilelist <> value then begin + ffilelist.Assign(value); + end; +end; + +procedure tfilelistview.readlist; +var + int1: integer; + po1: pfileinfoty; + level1: fileinfolevelty; +begin + beginupdate; + try + defocuscell; + fdatacols.clearselection; + ffilelist.clear; + ffilecount:= 0; + level1:= fil_type; + if assigned(foncheckfile) then begin + level1:= fil_ext2; + end; + if fmaskar = nil then begin + ffilelist.adddirectory(fdirectory,level1,fmaskar, + fincludeattrib,fexcludeattrib,foptionsdir, + foncheckfile); + if ffilelist.count > 0 then begin + po1:= ffilelist.itempo(0); + for int1:= 0 to ffilelist.count - 1 do begin + if not (fa_dir in po1^.extinfo1.attributes) then begin + inc(ffilecount); + end; + inc(po1); + end; + end; + end + else begin + if (fincludeattrib = [fa_all]) or not(fa_dir in fincludeattrib) then begin + ffilelist.adddirectory(fdirectory,level1,nil,[fa_dir], + fexcludeattrib*[fa_hidden],foptionsdir,foncheckfile); + int1:= ffilelist.count; + ffilelist.adddirectory(fdirectory,level1,fmaskar,fincludeattrib, + fexcludeattrib+[fa_dir],foptionsdir,foncheckfile); + ffilecount:= ffilelist.count - int1; + end + else begin + ffilelist.adddirectory(fdirectory,level1,fmaskar, + fincludeattrib,fexcludeattrib,foptionsdir,foncheckfile); + ffilecount:= ffilelist.count; + end; + end; + finally + endupdate; + end; + if assigned(fonlistread) then begin + fonlistread(self); + end; +end; + +procedure tfilelistview.updir; +var + str1: msestring; + int1: integer; +begin + str1:= removelastdir(fdirectory,fdirectory); + if str1 <> '' then begin + readlist; + int1:= ffilelist.indexof(str1); + if int1 >= 0 then begin + focuscell(indextocell(int1),fca_focusin); + end; + end; +end; + +procedure tfilelistview.setdirectory(const Value: msestring); +begin + fdirectory:= filepath(value,fk_dir); +end; + +function tfilelistview.getpath: msestring; +begin + if fmaskar = nil then begin + result:= filepath(fdirectory); + end + else begin + result:= filepath(fdirectory,fmaskar[0]); + end; +end; + +procedure tfilelistview.setpath(const Value: filenamety); +var + str1: msestring; +begin + splitfilepath(value,fdirectory,str1); + mask:= str1; + readlist; +end; + +procedure tfilelistview.setmask(const value: filenamety); +begin + unquotefilename(value,fmaskar); +end; + +function tfilelistview.getmask: filenamety; +begin + result:= quotefilename(fmaskar); +end; + +function tfilelistview.filecount: integer; +begin + if ffilelist.count < ffilecount then begin + ffilecount:= 0; + end; + result:= ffilecount; +end; + +function tfilelistview.getchecksubdir: boolean; +begin + result:= flvo_checksubdir in foptionsfile; +end; + +procedure tfilelistview.setchecksubdir(const avalue: boolean); +begin + if avalue then begin + include(foptionsfile,flvo_checksubdir); + end + else begin + exclude(foptionsfile,flvo_checksubdir); + end; +end; + +procedure tfilelistview.setoptionsfile(const avalue: filelistviewoptionsty); +const + mask1: filelistviewoptionsty = [flvo_maskcasesensitive,flvo_maskcaseinsensitive]; +begin + if avalue <> foptionsfile then begin + foptionsfile:= filelistviewoptionsty( + setsinglebit({$ifdef FPC}longword{$else}byte{$endif}(avalue), + {$ifdef FPC}longword{$else}byte{$endif}(foptionsfile), + {$ifdef FPC}longword{$else}byte{$endif}(mask1))); + foptionsdir:= dirstreamoptionsty(foptionsfile) * + [dso_casesensitive,dso_caseinsensitive]; + checkcasesensitive; + end; +end; + +{ tfilelistitem } + +constructor tfilelistitem.create(const aowner: tcustomitemlist); +begin + inherited; +end; + +{ tfileitemlist } + +procedure tfileitemlist.createitem(out item: tlistitem); +begin + item:= tfilelistitem.create(self); +end; + + { tfiledialogfo } + +procedure Tfiledialogfo.createdironexecute(const sender: TObject); +var + mstr1: msestring; +begin + mstr1:= ''; + with stockobjects do begin + if stringenter(mstr1,captions[sc_name], + captions[sc_create_new_directory]) = mr_ok then begin + mstr1:= filepath(listview.directory,mstr1,fk_file); + msefileutils.createdir(mstr1); + changedir(mstr1); + filename.setfocus; + end; + end; +end; + +procedure tfiledialogfo.listviewselectionchanged(const sender: tcustomlistview); +var + ar1: msestringarty; +begin + ar1:= nil; //compiler warning + if not (fdo_directory in dialogoptions) then begin + ar1:= listview.selectednames; + if length(ar1) > 0 then begin + if length(ar1) > 1 then begin + filename.value:= quotefilename(ar1); + end + else begin + filename.value:= ar1[0]; + end; + end + else begin +// filename.value:= ''; //dir chanaged + end; + end; +end; + +function tfiledialogfo.changedir(const adir: filenamety): boolean; +begin + result:= tryreadlist(filepath(adir),true); + if result then begin + course(adir); + end; + with listview do begin + if filelist.count > 0 then begin + focuscell(makegridcoord(0,0)); + end; + end; +end; + +procedure tfiledialogfo.listviewitemevent(const sender: tcustomlistview; + const index: Integer; var info: celleventinfoty); +var + str1: filenamety; +begin + with tfilelistview(sender) do begin + if iscellclick(info) then begin + if filelist.isdir(index) then begin + str1:= filepath(directory+filelist[index].name); + changedir(str1); + end + else begin + if info.eventkind = cek_keydown then begin + system.exclude(info.keyeventinfopo^.eventstate,es_processed); + //do not eat key_return + end; + if iscellclick(info,[ccr_dblclick,ccr_nokeyreturn]) and + (length(fdatacols.selectedcells) = 1) then begin + okonexecute(nil); + end; + end; + end; + end; +end; + +procedure tfiledialogfo.doup(); +begin + listview.updir(); + course(listview.directory); +end; + +procedure tfiledialogfo.listviewonkeydown(const sender: twidget; var info: keyeventinfoty); +begin + with info do begin + if (key = key_pageup) and (shiftstate = [ss_ctrl]) then begin + doup(); + include(info.eventstate,es_processed); + end; + end; +end; + +procedure Tfiledialogfo.upaction(const sender: TObject); +begin + doup(); +end; +{ +function tfiledialogfo.readlist: boolean; +begin + result:= true; + try + with listview do begin + readlist; + end; + except + on ex: esys do begin + result:= false; + // if esys(ex).error = sye_dirstream then begin + listview.directory:= ''; + with stockobjects do begin + showerror(captions[sc_can_not_read_directory]+ ' ' + esys(ex).text, + captions[sc_error]); +// showerror('Can not read directory '''+ esys(ex).text+'''.','Error'); + end; + try + listview.readlist; + except + application.handleexception(self); + end; +// end +// else begin +// application.handleexception(self); +// end; + end; + else begin + result:= false; + application.handleexception(self); + end; + end; +end; +} +function tfiledialogfo.tryreadlist(const adir: filenamety; + const errormessage: boolean): boolean; + //restores old dir on error +var + dirbefore: filenamety; +begin + dirbefore:= listview.directory; + listview.directory:= adir; + result:= false; + try + listview.readlist; + result:= true; + except + on ex: esys do begin + result:= false; + if errormessage then begin + with stockobjects do begin + showerror(captions[sc_can_not_read_directory]+ ' ' + + msestring(esys(ex).text),captions[sc_error]); + end; + end; + end; + else begin + result:= false; + application.handleexception(self); + end; + end; + if not result then begin + listview.directory:= dirbefore; + try + listview.readlist; + except + listview.directory:= ''; + listview.readlist; + end; + end; +end; + +procedure Tfiledialogfo.filenamesetvalue(const sender: TObject; + var avalue: msestring; var accept: Boolean); +var + str1,str2,str3: filenamety; +// ar1: msestringarty; + bo1: boolean; + newdir: filenamety; +begin + newdir:= ''; + avalue:= trim(avalue); + unquotefilename(avalue,fselectednames); + if (fdo_single in dialogoptions) and (high(fselectednames) > 0) then begin + with stockobjects do begin + showmessage(captions[sc_single_item_only]+'.',captions[sc_error]); + end; + accept:= false; + exit; + end; + bo1:= false; + if high(fselectednames) > 0 then begin + str1:= extractrootpath(fselectednames); + if str1 <> '' then begin + bo1:= true; + newdir:= str1; + avalue:= quotefilename(fselectednames); + end; + end + else begin + str3:= filepath(listview.directory,avalue); + splitfilepath(str3,str1,str2); + newdir:= str1; + if hasmaskchars(str2) then begin + filter.value:= str2; + listview.mask:= str2; + str2:= ''; + end + else begin + if searchfile(str3,true) <> '' then begin + newdir:= str3; + str2:= ''; + end; + end; + avalue:= str2; + if str2 = '' then begin + fselectednames:= nil; + end + else begin + setlength(fselectednames,1); + fselectednames[0]:= str2; + end; + bo1:= true; + end; + if bo1 then begin + if tryreadlist(newdir,not finit) then begin + if finit then begin + setlength(fcourse,1); + fcourse[0]:= newdir; + fcourseid:= 0; + end + else begin + course(newdir); + end; + end; + if fdo_directory in dialogoptions then begin + avalue:= listview.directory; + end; + end; + listview.selectednames:= fselectednames; +end; + +procedure tfiledialogfo.filepathentered(const sender: tobject); +begin + tryreadlist(listview.directory,true); +// readlist; +end; + +procedure tfiledialogfo.dironsetvalue(const sender: TObject; + var avalue: mseString; var accept: Boolean); +begin +// + accept:= tryreadlist(avalue,true); + if accept then begin + course(avalue); + end; +// listview.directory:= avalue; +end; + +procedure tfiledialogfo.listviewonlistread(const sender: tobject); +begin + with listview do begin + dir.value:= directory; +// if fa_dir in finclude then begin + if fdo_directory in self.dialogoptions then begin + filename.value:= directory; + end; + end; +end; + +procedure tfiledialogfo.updatefiltertext; +begin + with filter,dropdown do begin + if itemindex >= 0 then begin + value:= cols[0][itemindex]; + listview.mask:= cols[1][itemindex]; + end; + end; +end; + +procedure tfiledialogfo.filteronafterclosedropdown(const sender: tobject); +begin + updatefiltertext; + filter.initfocus; +end; + +procedure tfiledialogfo.filteronsetvalue(const sender: tobject; + var avalue: msestring; var accept: boolean); +begin + listview.mask:= avalue; +end; + +procedure tfiledialogfo.okonexecute(const sender: tobject); +var + bo1: boolean; + int1: integer; + str1: filenamety; +begin +// if filename.checkvalue then begin + if (filename.value <> '') or (fdo_acceptempty in dialogoptions) then begin + if fdo_directory in dialogoptions then begin + str1:= quotefilename(listview.directory); + end + else begin + str1:= quotefilename(listview.directory,filename.value); + end; + unquotefilename(str1,filenames); + if (defaultext <> '') then begin + for int1:= 0 to high(filenames) do begin + if not hasfileext(filenames[int1]) then begin + filenames[int1]:= filenames[int1] + '.'+defaultext; + end; + end; + end; + if (fdo_checkexist in dialogoptions) and + not ((filename.value = '') and (fdo_acceptempty in dialogoptions)) then begin + if fdo_directory in dialogoptions then begin + bo1:= finddir(filenames[0]); + end + else begin + bo1:= findfile(filenames[0]); + end; + if fdo_save in dialogoptions then begin + if bo1 then begin + with stockobjects do begin + if not askok(captions[sc_file]+' "'+filenames[0]+ + '" '+ captions[sc_exists_overwrite], + captions[sc_warningupper]) then begin +// if not askok('File "'+filenames[0]+ +// '" exists, do you want to overwrite?','WARNING') then begin + filename.setfocus; + exit; + end; + end; + end; + end + else begin + if not bo1 then begin + with stockobjects do begin + showerror(captions[sc_file]+' "'+filenames[0]+'" '+ + captions[sc_does_not_exist]+'.', + captions[sc_errorupper]); + end; +// showerror('File "'+filenames[0]+'" does not exist.'); + filename.setfocus; + exit; + end; + end; + end; + window.modalresult:= mr_ok; + end + else begin + filename.setfocus; + end; +// end; +end; + +procedure tfiledialogfo.layoutev(const sender: TObject); +begin +// placeyorder(2,[2],[dir,listview],2); +// aligny(wam_center,[dir,back,forward,home,up,createdir]); + aligny(wam_center,[filename,showhidden]); + if ok.height <= filter.height then begin + aligny(wam_center,[filter,ok,cancel]); + end + else begin + ok.top:= showhidden.bottom + 4; + aligny(wam_center,[ok,cancel]); + end; +// syncpaintwidth([filename,filter],namecont.bounds_cx); + listview.synctofontheight; +end; + +procedure tfiledialogfo.showhiddenonsetvalue(const sender: TObject; + var avalue: Boolean; var accept: Boolean); +begin + dir.showhiddenfiles:= avalue; + if avalue then begin + listview.excludeattrib:= listview.excludeattrib - [fa_hidden]; + end + else begin + listview.excludeattrib:= listview.excludeattrib + [fa_hidden]; + end; + listview.readlist; +end; + +procedure tfiledialogfo.formoncreate(const sender: TObject); +begin + fcourseid:= -1; + with stockobjects do begin + dir.frame.caption:= captions[sc_dirhk]; + home.caption:= captions[sc_homehk]; +// up.caption:= captions[sc_uphk]; + createdir.caption:= captions[sc_new_dirhk]; + filename.frame.caption:= captions[sc_namehk]; + filter.frame.caption:= captions[sc_filterhk]; + showhidden.frame.caption:= captions[sc_show_hidden_fileshk]; + ok.caption:= modalresulttext[mr_ok]; + cancel.caption:= modalresulttext[mr_cancel]; + end; + back.tag:= ord(sc_back); + forward.tag:= ord(sc_forward); + up.tag:= ord(sc_up); +end; + +procedure tfiledialogfo.dirshowhint(const sender: TObject; + var info: hintinfoty); +begin + if dir.editor.textclipped then begin + info.caption:= dir.value; + end; +end; + +procedure tfiledialogfo.copytoclip(const sender: TObject; var avalue: msestring); +begin + tosysfilepath1(avalue); +end; + +procedure tfiledialogfo.pastefromclip(const sender: TObject; + var avalue: msestring); +begin + tomsefilepath1(avalue); +end; + +procedure tfiledialogfo.homeaction(const sender: TObject); +begin + if tryreadlist(sys_getuserhomedir,true) then begin + dir.value:= listview.directory; + course(listview.directory); + end; +end; + +procedure tfiledialogfo.checkcoursebuttons(); +begin + back.enabled:= fcourseid > 0; + forward.enabled:= fcourseid < high(fcourse); +end; + +procedure tfiledialogfo.course(const adir: filenamety); +begin + if not fcourselock then begin + inc(fcourseid); + setlength(fcourse,fcourseid+1); + fcourse[fcourseid]:= adir; + checkcoursebuttons(); + end; +end; + +procedure tfiledialogfo.backexe(const sender: TObject); +begin + fcourselock:= true; + try + dec(fcourseid); + if changedir(fcourse[fcourseid]) then begin + checkcoursebuttons(); + end + else begin + inc(fcourseid); + end; + finally + fcourselock:= false; + end; +end; + +procedure tfiledialogfo.forwardexe(const sender: TObject); +begin + fcourselock:= true; + try + inc(fcourseid); + if changedir(fcourse[fcourseid]) then begin + checkcoursebuttons(); + end + else begin + dec(fcourseid); + end; + finally + fcourselock:= false; + end; +end; + +procedure tfiledialogfo.buttonshowhint(const sender: TObject; + var ainfo: hintinfoty); +begin + with tcustombutton(sender) do begin + ainfo.caption:= sc(stockcaptionty(tag))+' '+ + '('+encodeshortcutname(shortcut)+')'; + end; +end; + +{ tfiledialogcontroller } + +constructor tfiledialogcontroller.create(const aowner: tmsecomponent = nil; + const onchange: proceventty = nil); +begin + foptions:= defaultfiledialogoptions; + fhistorymaxcount:= defaulthistorymaxcount; + fowner:= aowner; + ffilterlist:= tdoublemsestringdatalist.create; + finclude:= [fa_all]; + fexclude:= [fa_hidden]; + fonchange:= onchange; + inherited create; +end; + +destructor tfiledialogcontroller.destroy; +begin + inherited; + ffilterlist.Free; +end; + +procedure tfiledialogcontroller.readstatvalue(const reader: tstatreader); +begin + ffilenames:= reader.readarray('filenames',ffilenames); + if fdo_params in foptions then begin + fparams:= reader.readmsestring('params',fparams); + end; +end; + +procedure tfiledialogcontroller.readstatstate(const reader: tstatreader); +begin + ffilterindex:= reader.readinteger('filefilterindex',ffilterindex); + ffilter:= reader.readmsestring('filefilter',ffilter); + fwindowrect.x:= reader.readinteger('x',fwindowrect.x); + fwindowrect.y:= reader.readinteger('y',fwindowrect.y); + fwindowrect.cx:= reader.readinteger('cx',fwindowrect.cx); + fwindowrect.cy:= reader.readinteger('cy',fwindowrect.cy); + fcolwidth:= reader.readinteger('filecolwidth',fcolwidth); + if fdo_chdir in foptions then begin +// try + trysetcurrentdirmse(flastdir); +// except +// end; + end; +end; + +procedure tfiledialogcontroller.readstatoptions(const reader: tstatreader); +begin + if fdo_savelastdir in foptions then begin + flastdir:= reader.readmsestring('lastdir',flastdir); + end; + if fhistorymaxcount > 0 then begin + fhistory:= reader.readarray('filehistory',fhistory); + end; +end; + +procedure tfiledialogcontroller.writestatvalue(const writer: tstatwriter); +begin + writer.writearray('filenames',ffilenames); + if fdo_params in foptions then begin + writer.writemsestring('params',fparams); + end; +end; + +procedure tfiledialogcontroller.writestatstate(const writer: tstatwriter); +begin + writer.writeinteger('filecolwidth',fcolwidth); + writer.writeinteger('x',fwindowrect.x); + writer.writeinteger('y',fwindowrect.y); + writer.writeinteger('cx',fwindowrect.cx); + writer.writeinteger('cy',fwindowrect.cy); +end; + +procedure tfiledialogcontroller.writestatoptions(const writer: tstatwriter); +begin + if fdo_savelastdir in foptions then begin + writer.writemsestring('lastdir',flastdir); + end; + if fhistorymaxcount > 0 then begin + writer.writearray('filehistory',fhistory); + end; + writer.writeinteger('filefilterindex',ffilterindex); + writer.writemsestring('filefilter',ffilter); +end; + +procedure tfiledialogcontroller.componentevent(const event: tcomponentevent); +begin + if (fdo_link in foptions) and (event.sender <> self) and + (event.sender is tfiledialogcontroller) then begin + with tfiledialogcontroller(event.sender) do begin + if fgroup = self.fgroup then begin + self.flastdir:= flastdir; + end; + end; + end; +end; + +procedure tfiledialogcontroller.checklink; +begin + if (fdo_link in foptions) and (fowner <> nil) then begin + fowner.sendrootcomponentevent(tcomponentevent.create(self),true); + end; +end; + +function tfiledialogcontroller.execute(dialogkind: filedialogkindty; + const acaption: msestring; + aoptions: filedialogoptionsty): modalresultty; +var + po1: pmsestringarty; + fo: tfiledialogfo; + ara,arb: msestringarty; + rectbefore: rectty; +begin + ara:= nil; //compiler warning + arb:= nil; //compiler warning + result:= mr_ok; + if assigned(fonbeforeexecute) then begin + fonbeforeexecute(self,dialogkind,result); + if result <> mr_ok then begin + exit; + end; + end; + if fhistorymaxcount > 0 then begin + po1:= @fhistory; + end + else begin + po1:= nil; + end; + fo:= tfiledialogfo.create(nil); + try + {$ifdef FPC} {$checkpointer off} {$endif} //todo!!!!! bug 3348 + ara:= ffilterlist.asarraya; + arb:= ffilterlist.asarrayb; + if dialogkind <> fdk_none then begin + if dialogkind in [fdk_save,fdk_new] then begin + system.include(aoptions,fdo_save); + end + else begin + system.exclude(aoptions,fdo_save); + end; + end; + if fdo_relative in foptions then begin + fo.listview.directory:= getcurrentdirmse; + end + else begin + fo.listview.directory:= flastdir; + end; + if (fwindowrect.cx > 0) and (fwindowrect.cy > 0) then begin + fo.widgetrect:= clipinrect(fwindowrect,application.screenrect(fo.window)); + end; + rectbefore:= fo.widgetrect; + result:= filedialog1(fo,ffilenames,ara,arb, + @ffilterindex,@ffilter,@fcolwidth,finclude, + fexclude,po1,fhistorymaxcount,acaption, + aoptions-[fdo_sysfilename],fdefaultext, + fimagelist,fongetfileicon,foncheckfile); + if not rectisequal(fo.widgetrect,rectbefore) then begin + fwindowrect:= fo.widgetrect; + end; + if assigned(fonafterexecute) then begin + fonafterexecute(self,result); + end; + {$ifdef FPC} {$checkpointer default} {$endif} + if result = mr_ok then begin + if fdo_relative in foptions then begin + flastdir:= getcurrentdirmse; + end + else begin + flastdir:= fo.dir.value; + end; + end; + finally + fo.Free; + end; +end; + +function tfiledialogcontroller.execute(const dialogkind: filedialogkindty; + const acaption: msestring): modalresultty; +begin + result:= execute(dialogkind,acaption,foptions); +end; + +function tfiledialogcontroller.actcaption( + const dialogkind: filedialogkindty): msestring; +begin + case dialogkind of + fdk_save: begin + result:= fcaptionsave; + end; + fdk_new: begin + result:= fcaptionnew; + end; + else begin + result:= fcaptionopen; + end; + end; +end; + +function tfiledialogcontroller.execute(const dialogkind: filedialogkindty; + const aoptions: filedialogoptionsty): modalresultty; +begin + result:= execute(dialogkind,actcaption(dialogkind),aoptions); +end; + +function tfiledialogcontroller.execute( + dialogkind: filedialogkindty = fdk_none): modalresultty; +begin + if dialogkind = fdk_none then begin + if fdo_save in foptions then begin + dialogkind:= fdk_save; + end + else begin + dialogkind:= fdk_open; + end; + end; + result:= execute(dialogkind,actcaption(dialogkind)); +end; + +function tfiledialogcontroller.execute(var avalue: filenamety; + dialogkind: filedialogkindty = fdk_none): boolean; +begin + if dialogkind = fdk_none then begin + if fdo_save in foptions then begin + dialogkind:= fdk_save; + end + else begin + dialogkind:= fdk_open; + end; + end; + result:= execute(avalue,dialogkind,actcaption(dialogkind)); +end; + +function tfiledialogcontroller.execute(var avalue: filenamety; + const dialogkind: filedialogkindty; const acaption: msestring; + aoptions: filedialogoptionsty): boolean; +var + wstr1: filenamety; +begin + wstr1:= filename; + if assigned(fongetfilename) then begin + result:= true; + fongetfilename(self,avalue,result); + if not result then begin + exit; + end; + end; + filename:= avalue; + result:= execute(dialogkind,acaption,aoptions) = mr_ok; + if result then begin + avalue:= filename; + checklink; + end + else begin + filename:= wstr1; + end; +end; + +function tfiledialogcontroller.canoverwrite(): boolean; +begin + with stockobjects do begin + result:= not findfile(filename) or + askok(captions[sc_file]+' "'+filename+ + '" '+ captions[sc_exists_overwrite], + captions[sc_warningupper]); + end; +end; + +function tfiledialogcontroller.execute(var avalue: filenamety; + const dialogkind: filedialogkindty; + const acaption: msestring): boolean; +begin + result:= execute(avalue,dialogkind,acaption,foptions); +end; + +function tfiledialogcontroller.getfilename: filenamety; +begin + if (high(ffilenames) > 0) or (fdo_quotesingle in foptions) or + (fdo_params in foptions) and (high(ffilenames) = 0) and + (findchar(pmsechar(ffilenames[0]),' ') > 0) then begin + result:= quotefilename(ffilenames); + end + else begin + if high(ffilenames) = 0 then begin + result:= ffilenames[0]; + end + else begin + result:= ''; + end; + end; + if (fdo_params in foptions) and (fparams <> '') then begin + if fdo_sysfilename in foptions then begin + tosysfilepath1(result); + end; + result:= result + ' '+fparams; + end + else begin + if fdo_sysfilename in foptions then begin + tosysfilepath1(result); + end; + end; +end; + +const + quotechar = msechar('"'); + +procedure tfiledialogcontroller.setfilename(const avalue: filenamety); +var + int1: integer; + akind: filekindty; +begin + unquotefilename(avalue,ffilenames); + if fdo_params in foptions then begin + fparams:= ''; + if high(ffilenames) >= 0 then begin + if avalue[1] = quotechar then begin + fparams:= copy(avalue,length(ffilenames[0])+3,bigint); + if (fparams <> '') and (fparams[1] = ' ') then begin + delete(fparams,1,1); + end; + setlength(ffilenames,1); + end + else begin + int1:= findchar(ffilenames[0],' '); + if int1 > 0 then begin + fparams:= copy(ffilenames[0],int1+1,bigint); + setlength(ffilenames[0],int1-1); + end; + end; + end; + end; + akind:= fk_default; + if fdo_directory in foptions then begin + akind:= fk_dir; + if fdo_file in foptions then begin + akind:= fk_file; + end; + end + else begin + if fdo_file in foptions then begin + akind:= fk_file; + end; + end; + if [fdo_relative,fdo_lastdirrelative,fdo_basedirrelative] * + foptions <> [] then begin + if fdo_relative in foptions then begin + flastdir:= getcurrentdirmse; + end + else begin + if fdo_basedirrelative in foptions then begin + flastdir:= fbasedir; + end; + end; + for int1:= 0 to high(ffilenames) do begin + if isrootpath(filenames[int1]) then begin + ffilenames[int1]:= relativepath(filenames[int1],flastdir,akind); + end; + end; + end + else begin + if high(ffilenames) = 0 then begin + if fdo_directory in foptions{akind = fk_dir} then begin + flastdir:= filepath(avalue,fk_dir); + end + else begin + flastdir:= filedir(avalue); + end; + end; + for int1:= 0 to high(ffilenames) do begin + ffilenames[int1]:= filepath(filenames[int1],akind, + not (fdo_absolute in foptions)); + end; + end; +end; + +procedure tfiledialogcontroller.setfilterlist( + const Value: tdoublemsestringdatalist); +begin + ffilterlist.assign(Value); +end; + +procedure tfiledialogcontroller.sethistorymaxcount(const Value: integer); +begin + fhistorymaxcount := Value; + if length(fhistory) > fhistorymaxcount then begin + setlength(fhistory,fhistorymaxcount); + end; +end; + +procedure tfiledialogcontroller.dochange; +begin + if assigned(fonchange) then begin + fonchange; + end; +end; + +procedure tfiledialogcontroller.setdefaultext(const avalue: filenamety); +begin + if fdefaultext <> avalue then begin + fdefaultext := avalue; + dochange; + end; +end; + +procedure tfiledialogcontroller.setoptions(Value: filedialogoptionsty); +(* +const + mask1: filedialogoptionsty = [fdo_absolute,fdo_relative]; +// mask2: filedialogoptionsty = [fdo_directory,fdo_file]; + mask3: filedialogoptionsty = [fdo_filtercasesensitive,fdo_filtercaseinsensitive]; +*) +begin + value:= filedialogoptionsty(setsinglebit(card32(value),card32(foptions), + [card32([fdo_absolute,fdo_relative,fdo_lastdirrelative, + fdo_basedirrelative]), + card32([fdo_filtercasesensitive,fdo_filtercaseinsensitive])])); + (* + {$ifdef FPC}longword{$else}longword{$endif}(value):= + setsinglebit({$ifdef FPC}longword{$else}longword{$endif}(value), + {$ifdef FPC}longword{$else}longword{$endif}(foptions), + {$ifdef FPC}longword{$else}longword{$endif}(mask1)); +// {$ifdef FPC}longword{$else}longword{$endif}(value):= +// setsinglebit({$ifdef FPC}longword{$else}longword{$endif}(value), +// {$ifdef FPC}longword{$else}longword{$endif}(foptions), +// {$ifdef FPC}longword{$else}longword{$endif}(mask2)); + {$ifdef FPC}longword{$else}longword{$endif}(value):= + setsinglebit({$ifdef FPC}longword{$else}longword{$endif}(value), + {$ifdef FPC}longword{$else}longword{$endif}(foptions), + {$ifdef FPC}longword{$else}longword{$endif}(mask3)); + *) + if foptions <> value then begin + foptions:= Value; + if not (fdo_params in foptions) then begin + fparams:= ''; + end; + dochange; + end; +end; + +procedure tfiledialogcontroller.clear; +begin + ffilenames:= nil; + flastdir:= ''; + fhistory:= nil; +end; + +procedure tfiledialogcontroller.setfilenamelastdir(const afilename: filenamety); +begin + filename:= filepath(lastdir,afilename); +end; + +procedure tfiledialogcontroller.setlastdir(const avalue: filenamety); +begin + flastdir:= avalue; + checklink; +end; + +procedure tfiledialogcontroller.setimagelist(const avalue: timagelist); +begin + setlinkedvar(avalue,tmsecomponent(fimagelist)); +end; + +function tfiledialogcontroller.getsysfilename: filenamety; +var + bo1: boolean; +begin + bo1:= fdo_sysfilename in foptions; + system.include(foptions,fdo_sysfilename); + result:= getfilename; + if not bo1 then begin + system.exclude(foptions,fdo_sysfilename); + end; +end; + +{ tfiledialog } + +constructor tfiledialog.create(aowner: tcomponent); +begin +// foptionsedit:= defaultfiledialogoptionsedit; + foptionsedit1:= defaultfiledialogoptionsedit1; + fcontroller:= tfiledialogcontroller.create(nil); + inherited; +end; + +destructor tfiledialog.destroy; +begin + inherited; + fcontroller.free; +end; + +function tfiledialog.execute: modalresultty; +begin + result:= fcontroller.execute(fdialogkind); +end; + +function tfiledialog.execute(const akind: filedialogkindty): modalresultty; +begin + result:= fcontroller.execute(akind); +end; + +function tfiledialog.execute(const akind: filedialogkindty; + const aoptions: filedialogoptionsty): modalresultty; +begin + result:= fcontroller.execute(akind,aoptions); +end; + +procedure tfiledialog.setcontroller(const value: tfiledialogcontroller); +begin + fcontroller.assign(value); +end; + +procedure tfiledialog.dostatread(const reader: tstatreader); +begin + if canstatvalue(foptionsedit1,reader) then begin + fcontroller.readstatvalue(reader); + end; + if canstatstate(foptionsedit1,reader) then begin + fcontroller.readstatstate(reader); + end; + if canstatoptions(foptionsedit1,reader) then begin + fcontroller.readstatoptions(reader); + end; +end; + +procedure tfiledialog.dostatwrite(const writer: tstatwriter); +begin + if canstatvalue(foptionsedit1,writer) then begin + fcontroller.writestatvalue(writer); + end; + if canstatstate(foptionsedit1,writer) then begin + fcontroller.writestatstate(writer); + end; + if canstatoptions(foptionsedit1,writer) then begin + fcontroller.writestatoptions(writer); + end; +end; + +function tfiledialog.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +procedure tfiledialog.setstatfile(const Value: tstatfile); +begin + setstatfilevar(istatfile(self),value,fstatfile); +end; + +procedure tfiledialog.statreading; +begin + //dummy +end; + +procedure tfiledialog.statread; +begin + //dummy +end; + +procedure tfiledialog.componentevent(const event: tcomponentevent); +begin + fcontroller.componentevent(event); + inherited; +end; + +function tfiledialog.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +procedure tfiledialog.readoptionsedit(reader: treader); +var + opt1: optionseditty; +begin + opt1:= optionseditty(reader.readset(typeinfo(optionseditty))); + updatebit(longword(foptionsedit1),ord(oe1_savevalue),oe_savevalue in opt1); + updatebit(longword(foptionsedit1),ord(oe1_savestate),oe_savestate in opt1); + updatebit(longword(foptionsedit1),ord(oe1_saveoptions),oe_saveoptions in opt1); + updatebit(longword(foptionsedit1),ord(oe1_checkvalueafterstatread), + oe_checkvaluepaststatread in opt1); +end; + +procedure tfiledialog.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('optionsedit',@readoptionsedit,nil,false); +end; + +{ tfilenameeditcontroller } + +constructor tfilenameeditcontroller.create(const aowner: tcustomfilenameedit1); +begin + inherited create(aowner); +end; + +function tfilenameeditcontroller.execute(var avalue: msestring): boolean; +begin + with tcustomfilenameedit1(fowner) do begin + if fcontroller <> nil then begin + result:= fcontroller.execute(avalue); + end + else begin + result:= false; + end; + end; +end; + +{ tcustomfilenameedit1 } + +constructor tcustomfilenameedit1.create(aowner: tcomponent); +begin +// fcontroller:= tfiledialogcontroller.create(self,{$ifdef FPC}@{$endif}formatchanged); + inherited; + optionsedit1:= defaultfiledialogoptionsedit1; +end; + +destructor tcustomfilenameedit1.destroy; +begin + inherited; +// fcontroller.Free; +end; +{ +function tcustomfilenameedit.execute(var avalue: msestring): boolean; +begin + result:= fcontroller.execute(avalue); +end; +} +procedure tcustomfilenameedit1.setcontroller(const avalue: tfiledialogcontroller); +begin + if fcontroller <> nil then begin + fcontroller.assign(avalue); + end; +end; + +procedure tcustomfilenameedit1.readstatvalue(const reader: tstatreader); +begin + if fgridintf <> nil then begin + inherited; + end + else begin + if fcontroller <> nil then begin + fcontroller.readstatvalue(reader); + value:= fcontroller.filename; + end; + end; +end; + +procedure tcustomfilenameedit1.readstatstate(const reader: tstatreader); +begin + if fcontroller <> nil then begin + fcontroller.readstatstate(reader); + end; +end; + +procedure tcustomfilenameedit1.readstatoptions(const reader: tstatreader); +begin + if fcontroller <> nil then begin + fcontroller.readstatoptions(reader); + end; +end; + +procedure tcustomfilenameedit1.writestatvalue(const writer: tstatwriter); +begin + if fgridintf <> nil then begin + inherited; + end + else begin + if fcontroller <> nil then begin + fcontroller.writestatvalue(writer); + end; + end; +end; + +procedure tcustomfilenameedit1.writestatstate(const writer: tstatwriter); +begin + if fcontroller <> nil then begin + fcontroller.writestatstate(writer); + end; +end; + +procedure tcustomfilenameedit1.writestatoptions(const writer: tstatwriter); +begin + if fcontroller <> nil then begin + fcontroller.writestatoptions(writer); + end; +end; + +function tcustomfilenameedit1.getvaluetext: msestring; +begin +// result:= filepath(fcontroller.filename); + if fcontroller <> nil then begin + result:= fcontroller.filename; + end + else begin + result:= ''; + end; +end; + +procedure tcustomfilenameedit1.texttovalue(var accept: boolean; + const quiet: boolean); +var + ar1: filenamearty; + mstr1: filenamety; + int1: integer; +begin + if fcontroller <> nil then begin + if (fcontroller.defaultext <> '') then begin + unquotefilename(text,ar1); + for int1:= 0 to high(ar1) do begin + if not hasfileext(ar1[int1]) then begin + ar1[int1]:= ar1[int1] + '.'+controller.defaultext; + end; + end; + mstr1:= quotefilename(ar1); + end + else begin + mstr1:= text; + end; + fcontroller.filename:= mstr1; + end; + inherited; +end; + +procedure tcustomfilenameedit1.updatedisptext(var avalue: msestring); +begin + if fcontroller <> nil then begin + with fcontroller do begin + if fdo_dispname in foptions then begin + avalue:= msefileutils.filename(avalue); + end; + if fdo_dispnoext in foptions then begin + avalue:= removefileext(avalue); + end; + end; + end; +end; + +procedure tcustomfilenameedit1.valuechanged; +begin + if fcontroller <> nil then begin + fcontroller.filename:= value; + end; + inherited; +end; + +procedure tcustomfilenameedit1.componentevent(const event: tcomponentevent); +begin + if fcontroller <> nil then begin + fcontroller.componentevent(event); + end; + inherited; +end; + +procedure tcustomfilenameedit1.updatecopytoclipboard(var atext: msestring); +begin + tosysfilepath1(atext); + inherited; +end; + +procedure tcustomfilenameedit1.updatepastefromclipboard(var atext: msestring); +begin + tomsefilepath1(atext); + inherited; +end; + +function tcustomfilenameedit1.createdialogcontroller: tstringdialogcontroller; +begin + result:= tfilenameeditcontroller.create(self); +end; + +function tcustomfilenameedit1.getsysvalue: filenamety; +begin + result:= tosysfilepath(value); +end; + +procedure tcustomfilenameedit1.setsysvalue(const avalue: filenamety); +begin + value:= tomsefilepath(avalue); +end; + +function tcustomfilenameedit1.getsysvaluequoted: filenamety; +begin + result:= tosysfilepath(value,true); +end; + +{ tcustomfilenameedit } + +constructor tcustomfilenameedit.create(aowner: tcomponent); +begin + fcontroller:= tfiledialogcontroller.create(self, + {$ifdef FPC}@{$endif}formatchanged); + inherited; +end; + +destructor tcustomfilenameedit.destroy; +begin + inherited; + fcontroller.Free; +end; + +{ tdirdropdownedit } + +procedure tdirdropdownedit.createdropdownwidget(const atext: msestring; + out awidget: twidget); +begin + awidget:= tdirtreefo.create(nil); + with tdirtreefo(awidget) do begin + showhiddenfiles:= ddeo_showhiddenfiles in foptions; + checksubdir:= ddeo_checksubdir in foptions; + path:= atext; + onpathchanged:= {$ifdef FPC}@{$endif}pathchanged; + text:= path; + if deo_colsizing in fdropdown.options then begin + optionssizing:= [osi_right]; + end; + end; + feditor.sellength:= 0; +end; + +procedure tdirdropdownedit.doafterclosedropdown; +begin + text:= value; + feditor.selectall; + inherited; +end; + +function tdirdropdownedit.getdropdowntext(const awidget: twidget): msestring; +begin + result:= tdirtreefo(awidget).path; +end; + +procedure tdirdropdownedit.pathchanged(const sender: tobject); +begin + text:= tdirtreefo(sender).path; +end; + +function tdirdropdownedit.getshowhiddenfiles: boolean; +begin + result:= ddeo_showhiddenfiles in foptions; +end; + +procedure tdirdropdownedit.setshowhiddenfiles(const avalue: boolean); +begin + if avalue then begin + include(foptions,ddeo_showhiddenfiles) + end + else begin + exclude(foptions,ddeo_showhiddenfiles) + end; +end; + +function tdirdropdownedit.getchecksubdir: boolean; +begin + result:= ddeo_checksubdir in foptions; +end; + +procedure tdirdropdownedit.setchecksubdir(const avalue: boolean); +begin + if avalue then begin + include(foptions,ddeo_checksubdir) + end + else begin + exclude(foptions,ddeo_checksubdir) + end; +end; + +procedure tdirdropdownedit.updatecopytoclipboard(var atext: msestring); +begin + tosysfilepath1(atext); + inherited; +end; + +procedure tdirdropdownedit.updatepastefromclipboard(var atext: msestring); +begin + tomsefilepath1(atext); + inherited; +end; + +{ tcustomremotefilenameedit } + +procedure tcustomremotefilenameedit.setfiledialog(const avalue: tfiledialog); +begin + setlinkedvar(avalue,tmsecomponent(fdialog)); + if avalue = nil then begin + fcontroller:= nil; + end + else begin + fcontroller:= avalue.fcontroller; + end; +end; + +procedure tcustomremotefilenameedit.objectevent(const sender: tobject; + const event: objecteventty); +begin + if (event = oe_destroyed) and (sender = fdialog) then begin + fcontroller:= nil; + end; + inherited; +end; + +{ tdirtreeview } + +constructor tdirtreeview.create(aowner: tcomponent); +begin + inherited; + createframe(); + foptionswidget:= defaultoptionswidgetsubfocus; + fdirview:= tdirtreefo.create(nil,self,false); + //owner must be nil because of streaming + fdirview.onpathchanged:= @dopathchanged; + fdirview.onselectionchanged:= @doselectionchanged; + fdirview.treeitem.ondataentered:= @dopathselected; + fdirview.grid.frame.framewidth:= 0; + fdirview.bounds_cxmin:= 0; + fdirview.anchors:= []; + fdirview.visible:= true; +end; + +destructor tdirtreeview.destroy(); +begin + fdirview.free(); + inherited; //fdirview destroyed by destroy children +end; + +procedure tdirtreeview.refresh(); +begin + tdirtreefo1(fdirview).updatepath(); +end; + +function tdirtreeview.getoptions: dirtreeoptionsty; +begin + result:= fdirview.optionsdir; +end; + +procedure tdirtreeview.setoptions(const avalue: dirtreeoptionsty); +begin + fdirview.optionsdir:= avalue; +end; + +function tdirtreeview.getpath: filenamety; +begin + if csdesigning in componentstate then begin + result:= fpath; + end + else begin + result:= fdirview.path; + end; +end; + +procedure tdirtreeview.setpath(const avalue: filenamety); +begin + fpath:= avalue; + if componentstate * [csdesigning,csloading] = [] then begin + fdirview.path:= avalue; + end; +end; + +procedure tdirtreeview.setroot(const avalue: filenamety); +begin + froot:= avalue; + if componentstate * [csdesigning,csloading] = [] then begin + fdirview.root:= avalue; + end; +end; + +function tdirtreeview.getgrid: twidgetgrid; +begin + result:= fdirview.grid; +end; + +procedure tdirtreeview.setgrid(const avalue: twidgetgrid); +begin + //dummy +end; + +function tdirtreeview.getoptionstree: treeitemeditoptionsty; +begin + result:= fdirview.treeitem.options; +end; + +procedure tdirtreeview.setoptionstree(const avalue: treeitemeditoptionsty); +begin + fdirview.treeitem.options:= avalue; +end; + +function tdirtreeview.getoptionsedit: optionseditty; +begin + result:= fdirview.treeitem.optionsedit; +end; + +procedure tdirtreeview.setoptionsedit(const avalue: optionseditty); +begin + fdirview.treeitem.optionsedit:= avalue; +end; + +function tdirtreeview.getcol_color: colorty; +begin + result:= fdirview.grid.datacols[0].color; +end; + +procedure tdirtreeview.setcol_color(const avalue: colorty); +begin + fdirview.grid.datacols[0].color:= avalue; +end; + +function tdirtreeview.getcol_coloractive: colorty; +begin + result:= fdirview.grid.datacols[0].coloractive; +end; + +procedure tdirtreeview.setcol_coloractive(const avalue: colorty); +begin + fdirview.grid.datacols[0].coloractive:= avalue; +end; + +function tdirtreeview.getcol_colorfocused: colorty; +begin + result:= fdirview.grid.datacols[0].colorfocused; +end; + +procedure tdirtreeview.setcol_colorfocused(const avalue: colorty); +begin + fdirview.grid.datacols[0].colorfocused:= avalue; +end; + +function tdirtreeview.getcell_options: coloptionsty; +begin + result:= fdirview.grid.datacols[0].options; +end; + +procedure tdirtreeview.setcell_options(const avalue: coloptionsty); +begin + fdirview.grid.datacols[0].options:= avalue; +end; +{ +function tdirtreeview.getcell_frame: tcellframe; +begin + if csreading in componentstate then begin + fdirview.grid.datacols[0].createframe(); + end; + result:= fdirview.grid.datacols[0].frame; +end; + +procedure tdirtreeview.setcell_frame(const avalue: tcellframe); +begin + fdirview.grid.datacols[0].frame:= avalue; +end; + +function tdirtreeview.getcell_face: tcellface; +begin + if csreading in componentstate then begin + fdirview.grid.datacols[0].createface(); + end; + result:= fdirview.grid.datacols[0].face; +end; + +procedure tdirtreeview.setcell_face(const avalue: tcellface); +begin + if avalue <> nil then begin + fdirview.grid.datacols[0].createface(); + end; + fdirview.grid.datacols[0].face:= avalue; +end; + +function tdirtreeview.getcell_datalist: ttreeitemeditlist; +begin + result:= ttreeitemeditlist(fdirview.grid.datacols[0].datalist); +end; + +procedure tdirtreeview.setcell_datalist(const avalue: ttreeitemeditlist); +begin + fdirview.grid.datacols[0].datalist:= avalue; +end; +} +procedure tdirtreeview.dopathchanged(const sender: tobject); +begin + if canevent(tmethod(fonpathchanged)) then begin + fonpathchanged(self,fdirview.path); + end; +end; + +procedure tdirtreeview.dopathselected(const sender: tobject); +begin + if canevent(tmethod(fonpathselected)) then begin + fonpathselected(self,fdirview.path); + end; +end; + +procedure tdirtreeview.doselectionchanged(const sender: tobject; + const aitem: tlistitem); +begin + if canevent(tmethod(fonselectionchanged)) then begin + fonselectionchanged(self,aitem); + end; +end; + +procedure tdirtreeview.internalcreateframe; +begin + timpressedcaptionframe.create(icaptionframe(self)); +end; + +procedure tdirtreeview.loaded(); +begin + inherited; + if not (csdesigning in componentstate) then begin + with tdirtreefo1(fdirview) do begin + froot:= self.froot; + path:= self.fpath; + end; + end; +end; + +class function tdirtreeview.classskininfo: skininfoty; +begin + result:= inherited classskininfo; + result.objectkind:= sok_dataedit; +end; + +end. diff --git a/mseide-msegui/lib/common/dialogs/msefiledialog_mfm.pas b/mseide-msegui/lib/common/dialogs/msefiledialog_mfm.pas new file mode 100644 index 0000000..4105b61 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msefiledialog_mfm.pas @@ -0,0 +1,440 @@ +unit msefiledialog_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msefiledialog; + +const + objdata: record size: integer; data: array[0..8445] of byte end = + (size: 8446; data: ( + 84,80,70,48,13,84,102,105,108,101,100,105,97,108,111,103,102,111,12,102, + 105,108,101,100,105,97,108,111,103,102,111,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98, + 102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,9,111,119,95,104,105,110,116,111,110,0,7,118,105,115,105,98, + 108,101,8,8,98,111,117,110,100,115,95,120,2,14,8,98,111,117,110,100, + 115,95,121,3,70,1,9,98,111,117,110,100,115,95,99,120,3,75,2,9, + 98,111,117,110,100,115,95,99,121,3,51,1,12,98,111,117,110,100,115,95, + 99,120,109,105,110,3,104,1,12,98,111,117,110,100,115,95,99,121,109,105, + 110,3,150,0,23,99,111,110,116,97,105,110,101,114,46,111,112,116,105,111, + 110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111, + 99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97, + 114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111, + 99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111, + 117,116,11,111,119,95,115,117,98,102,111,99,117,115,19,111,119,95,109,111, + 117,115,101,116,114,97,110,115,112,97,114,101,110,116,17,111,119,95,100,101, + 115,116,114,111,121,119,105,100,103,101,116,115,0,26,99,111,110,116,97,105, + 110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,0,27,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,18,99,111,110,116,97,105,110, + 101,114,46,111,110,108,97,121,111,117,116,7,8,108,97,121,111,117,116,101, + 118,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2, + 0,2,0,3,75,2,3,51,1,0,7,111,112,116,105,111,110,115,11,17, + 102,111,95,115,99,114,101,101,110,99,101,110,116,101,114,101,100,13,102,111, + 95,99,108,111,115,101,111,110,101,115,99,17,102,111,95,108,111,99,97,108, + 115,104,111,114,116,99,117,116,115,15,102,111,95,97,117,116,111,114,101,97, + 100,115,116,97,116,16,102,111,95,97,117,116,111,119,114,105,116,101,115,116, + 97,116,10,102,111,95,115,97,118,101,112,111,115,0,8,111,110,108,111,97, + 100,101,100,7,12,102,111,114,109,111,110,99,114,101,97,116,101,9,111,110, + 107,101,121,100,111,119,110,7,17,108,105,115,116,118,105,101,119,111,110,107, + 101,121,100,111,119,110,8,111,110,108,97,121,111,117,116,7,8,108,97,121, + 111,117,116,101,118,4,108,101,102,116,3,239,0,3,116,111,112,3,138,0, + 15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,8,116,109, + 115,101,102,111,114,109,0,13,116,102,105,108,101,108,105,115,116,118,105,101, + 119,8,108,105,115,116,118,105,101,119,13,111,112,116,105,111,110,115,119,105, + 100,103,101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,13, + 111,119,95,97,114,114,111,119,102,111,99,117,115,17,111,119,95,102,111,99, + 117,115,98,97,99,107,111,110,101,115,99,13,111,119,95,109,111,117,115,101, + 119,104,101,101,108,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100, + 115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,24,9,98,111,117, + 110,100,115,95,99,120,3,75,2,9,98,111,117,110,100,115,95,99,121,3, + 236,0,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,0,9, + 111,110,107,101,121,100,111,119,110,7,17,108,105,115,116,118,105,101,119,111, + 110,107,101,121,100,111,119,110,16,100,97,116,97,114,111,119,108,105,110,101, + 99,111,108,111,114,4,5,0,0,160,16,100,97,116,97,99,111,108,108,105, + 110,101,99,111,108,111,114,4,5,0,0,160,9,99,101,108,108,119,105,100, + 116,104,3,174,0,10,99,101,108,108,104,101,105,103,104,116,2,15,11,111, + 112,116,105,111,110,115,103,114,105,100,11,12,111,103,95,99,111,108,115,105, + 122,105,110,103,19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101, + 110,116,101,114,17,111,103,95,109,111,117,115,101,115,99,114,111,108,108,99, + 111,108,0,7,111,112,116,105,111,110,115,11,12,108,118,111,95,114,101,97, + 100,111,110,108,121,13,108,118,111,95,100,114,97,119,102,111,99,117,115,15, + 108,118,111,95,109,111,117,115,101,115,101,108,101,99,116,13,108,118,111,95, + 107,101,121,115,101,108,101,99,116,15,108,118,111,95,109,117,108,116,105,115, + 101,108,101,99,116,10,108,118,111,95,108,111,99,97,116,101,19,108,118,111, + 95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116,0,18,105,116, + 101,109,108,105,115,116,46,105,109,97,103,101,108,105,115,116,7,20,102,105, + 108,101,100,105,97,108,111,103,114,101,115,46,105,109,97,103,101,115,19,105, + 116,101,109,108,105,115,116,46,105,109,97,103,101,119,105,100,116,104,2,16, + 20,105,116,101,109,108,105,115,116,46,105,109,97,103,101,104,101,105,103,104, + 116,2,16,12,99,101,108,108,119,105,100,116,104,109,105,110,2,50,18,111, + 110,115,101,108,101,99,116,105,111,110,99,104,97,110,103,101,100,7,24,108, + 105,115,116,118,105,101,119,115,101,108,101,99,116,105,111,110,99,104,97,110, + 103,101,100,11,111,110,105,116,101,109,101,118,101,110,116,7,17,108,105,115, + 116,118,105,101,119,105,116,101,109,101,118,101,110,116,16,102,105,108,101,108, + 105,115,116,46,111,112,116,105,111,110,115,11,12,102,108,111,95,115,111,114, + 116,110,97,109,101,12,102,108,111,95,115,111,114,116,116,121,112,101,0,10, + 111,110,108,105,115,116,114,101,97,100,7,18,108,105,115,116,118,105,101,119, + 111,110,108,105,115,116,114,101,97,100,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,14,0,0,9,116,108,97,121,111,117,116,101,114,10,116, + 108,97,121,111,117,116,101,114,50,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,11,111,119,95,116,97,98,102,111,99,117,115,17,111,119,95, + 112,97,114,101,110,116,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,8,98,111,117,110,100,115,95, + 120,2,0,8,98,111,117,110,100,115,95,121,3,6,1,9,98,111,117,110, + 100,115,95,99,120,3,73,2,9,98,111,117,110,100,115,95,99,121,2,42, + 7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,8,97,110, + 95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,12,111,112, + 116,105,111,110,115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97, + 110,100,121,11,111,115,99,95,115,104,114,105,110,107,121,17,111,115,99,95, + 101,120,112,97,110,100,115,104,114,105,110,107,120,17,111,115,99,95,101,120, + 112,97,110,100,115,104,114,105,110,107,121,0,7,108,105,110,107,116,111,112, + 7,8,108,105,115,116,118,105,101,119,8,100,105,115,116,95,116,111,112,2, + 2,7,111,112,116,105,111,110,115,11,15,115,112,97,111,95,103,108,117,101, + 98,111,116,116,111,109,0,0,7,116,115,112,97,99,101,114,6,98,117,99, + 111,110,116,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,11,111, + 119,95,116,97,98,102,111,99,117,115,17,111,119,95,112,97,114,101,110,116, + 116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111, + 119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115, + 117,98,102,111,99,117,115,13,111,119,95,109,111,117,115,101,119,104,101,101, + 108,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 8,116,97,98,111,114,100,101,114,2,1,7,118,105,115,105,98,108,101,9, + 8,98,111,117,110,100,115,95,120,3,198,1,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,120,3,131,0,9,98,111,117, + 110,100,115,95,99,121,2,42,7,97,110,99,104,111,114,115,11,6,97,110, + 95,116,111,112,8,97,110,95,114,105,103,104,116,0,12,111,112,116,105,111, + 110,115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97,110,100,120, + 11,111,115,99,95,115,104,114,105,110,107,120,11,111,115,99,95,101,120,112, + 97,110,100,121,11,111,115,99,95,115,104,114,105,110,107,121,0,8,108,105, + 110,107,108,101,102,116,7,10,116,108,97,121,111,117,116,101,114,49,7,111, + 112,116,105,111,110,115,11,14,115,112,97,111,95,103,108,117,101,114,105,103, + 104,116,15,115,112,97,111,95,103,108,117,101,98,111,116,116,111,109,0,0, + 12,116,98,111,111,108,101,97,110,101,100,105,116,10,115,104,111,119,104,105, + 100,100,101,110,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,18, + 38,83,104,111,119,32,104,105,100,100,101,110,32,102,105,108,101,115,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,2, + 112,2,2,0,8,98,111,117,110,100,115,95,120,2,6,8,98,111,117,110, + 100,115,95,121,2,4,9,98,111,117,110,100,115,95,99,120,2,125,9,98, + 111,117,110,100,115,95,99,121,2,16,10,111,110,115,101,116,118,97,108,117, + 101,7,20,115,104,111,119,104,105,100,100,101,110,111,110,115,101,116,118,97, + 108,117,101,0,0,7,116,115,112,97,99,101,114,8,116,115,112,97,99,101, + 114,52,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117,110,100,115, + 95,120,2,41,8,98,111,117,110,100,115,95,121,2,22,9,98,111,117,110, + 100,115,95,99,120,2,8,9,98,111,117,110,100,115,95,99,121,2,20,8, + 108,105,110,107,108,101,102,116,7,2,111,107,9,108,105,110,107,114,105,103, + 104,116,7,6,99,97,110,99,101,108,0,0,7,116,98,117,116,116,111,110, + 6,99,97,110,99,101,108,14,111,112,116,105,111,110,115,119,105,100,103,101, + 116,49,11,13,111,119,49,95,97,117,116,111,119,105,100,116,104,14,111,119, + 49,95,97,117,116,111,104,101,105,103,104,116,0,13,111,112,116,105,111,110, + 115,119,105,100,103,101,116,11,11,111,119,95,116,97,98,102,111,99,117,115, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114, + 114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102, + 111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111, + 117,110,100,115,95,120,2,49,8,98,111,117,110,100,115,95,121,2,22,9, + 98,111,117,110,100,115,95,99,120,2,52,9,98,111,117,110,100,115,95,99, + 121,2,20,12,98,111,117,110,100,115,95,99,120,109,105,110,2,35,5,115, + 116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111, + 110,0,7,99,97,112,116,105,111,110,6,7,38,67,97,110,99,101,108,11, + 109,111,100,97,108,114,101,115,117,108,116,7,9,109,114,95,99,97,110,99, + 101,108,7,111,112,116,105,111,110,115,11,17,98,111,95,101,120,101,99,117, + 116,101,111,110,99,108,105,99,107,15,98,111,95,101,120,101,99,117,116,101, + 111,110,107,101,121,20,98,111,95,101,120,101,99,117,116,101,111,110,115,104, + 111,114,116,99,117,116,27,98,111,95,101,120,101,99,117,116,101,100,101,102, + 97,117,108,116,111,110,101,110,116,101,114,107,101,121,19,98,111,95,99,97, + 110,100,101,102,111,99,117,115,119,105,110,100,111,119,0,0,0,7,116,98, + 117,116,116,111,110,2,111,107,14,111,112,116,105,111,110,115,119,105,100,103, + 101,116,49,11,13,111,119,49,95,97,117,116,111,119,105,100,116,104,14,111, + 119,49,95,97,117,116,111,104,101,105,103,104,116,0,13,111,112,116,105,111, + 110,115,119,105,100,103,101,116,11,11,111,119,95,116,97,98,102,111,99,117, + 115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97, + 114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119, + 102,111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,0,5,99,111,108,111,114,4,5,0,0,144,8,116, + 97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,6, + 8,98,111,117,110,100,115,95,121,2,22,9,98,111,117,110,100,115,95,99, + 120,2,35,9,98,111,117,110,100,115,95,99,121,2,20,12,98,111,117,110, + 100,115,95,99,120,109,105,110,2,35,5,115,116,97,116,101,11,10,97,115, + 95,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,100,101,102, + 97,117,108,116,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110, + 17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,7, + 99,97,112,116,105,111,110,6,3,38,79,107,7,111,112,116,105,111,110,115, + 11,17,98,111,95,101,120,101,99,117,116,101,111,110,99,108,105,99,107,15, + 98,111,95,101,120,101,99,117,116,101,111,110,107,101,121,20,98,111,95,101, + 120,101,99,117,116,101,111,110,115,104,111,114,116,99,117,116,27,98,111,95, + 101,120,101,99,117,116,101,100,101,102,97,117,108,116,111,110,101,110,116,101, + 114,107,101,121,19,98,111,95,99,97,110,100,101,102,111,99,117,115,119,105, + 110,100,111,119,0,9,111,110,101,120,101,99,117,116,101,7,11,111,107,111, + 110,101,120,101,99,117,116,101,0,0,0,9,116,108,97,121,111,117,116,101, + 114,10,116,108,97,121,111,117,116,101,114,49,13,111,112,116,105,111,110,115, + 119,105,100,103,101,116,11,11,111,119,95,116,97,98,102,111,99,117,115,17, + 111,119,95,112,97,114,101,110,116,116,97,98,102,111,99,117,115,13,111,119, + 95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119, + 102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117, + 115,111,117,116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,8,98,111,117,110, + 100,115,95,120,2,1,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,120,3,197,1,9,98,111,117,110,100,115,95,99,121, + 2,42,12,111,112,116,105,111,110,115,115,99,97,108,101,11,11,111,115,99, + 95,101,120,112,97,110,100,121,11,111,115,99,95,115,104,114,105,110,107,121, + 17,111,115,99,95,101,120,112,97,110,100,115,104,114,105,110,107,120,17,111, + 115,99,95,101,120,112,97,110,100,115,104,114,105,110,107,121,0,13,111,112, + 116,105,111,110,115,108,97,121,111,117,116,11,10,108,97,111,95,97,108,105, + 103,110,120,10,108,97,111,95,112,108,97,99,101,121,0,10,97,108,105,103, + 110,95,109,111,100,101,7,7,119,97,109,95,101,110,100,10,97,108,105,103, + 110,95,103,108,117,101,7,7,119,97,109,95,101,110,100,13,112,108,97,99, + 101,95,109,105,110,100,105,115,116,2,2,13,112,108,97,99,101,95,109,97, + 120,100,105,115,116,2,2,0,17,116,100,114,111,112,100,111,119,110,108,105, + 115,116,101,100,105,116,6,102,105,108,116,101,114,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,7,38,70,105,108,116,101,114,16,102,114,97, + 109,101,46,99,97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105, + 103,104,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117, + 110,116,2,1,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105, + 116,101,109,115,14,1,0,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,0,2,34,2,0,0,8,116,97,98,111, + 114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0,8,98,111, + 117,110,100,115,95,121,2,22,9,98,111,117,110,100,115,95,99,120,3,192, + 1,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,15,102,105,108, + 101,112,97,116,104,101,110,116,101,114,101,100,10,111,110,115,101,116,118,97, + 108,117,101,7,16,102,105,108,116,101,114,111,110,115,101,116,118,97,108,117, + 101,16,100,114,111,112,100,111,119,110,46,111,112,116,105,111,110,115,11,15, + 100,101,111,95,107,101,121,100,114,111,112,100,111,119,110,12,100,101,111,95, + 99,108,105,112,104,105,110,116,0,19,100,114,111,112,100,111,119,110,46,99, + 111,108,115,46,99,111,117,110,116,2,2,19,100,114,111,112,100,111,119,110, + 46,99,111,108,115,46,105,116,101,109,115,14,1,0,1,7,111,112,116,105, + 111,110,115,11,11,99,111,95,114,101,97,100,111,110,108,121,12,99,111,95, + 105,110,118,105,115,105,98,108,101,14,99,111,95,102,111,99,117,115,115,101, + 108,101,99,116,7,99,111,95,102,105,108,108,0,0,0,17,100,114,111,112, + 100,111,119,110,46,118,97,108,117,101,99,111,108,2,1,20,111,110,97,102, + 116,101,114,99,108,111,115,101,100,114,111,112,100,111,119,110,7,26,102,105, + 108,116,101,114,111,110,97,102,116,101,114,99,108,111,115,101,100,114,111,112, + 100,111,119,110,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,0,12,116,104,105,115,116,111,114,121,101,100,105,116,8,102,105,108,101, + 110,97,109,101,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,5, + 38,78,97,109,101,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112, + 111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,19,102,114,97,109,101,46,98,117, + 116,116,111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46, + 98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,0,0,16,102,114, + 97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0,2, + 39,2,0,0,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110, + 100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,197,1,12, + 111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117, + 116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101, + 120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,118,97,108,117,101, + 13,111,101,49,95,115,97,118,101,115,116,97,116,101,0,11,111,112,116,105, + 111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115, + 99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99, + 104,101,99,107,109,114,99,97,110,99,101,108,20,111,101,95,114,101,115,101, + 116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105, + 116,111,110,99,117,114,115,111,114,13,111,101,95,97,117,116,111,115,101,108, + 101,99,116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102, + 105,114,115,116,99,108,105,99,107,0,17,111,110,99,111,112,121,116,111,99, + 108,105,112,98,111,97,114,100,7,10,99,111,112,121,116,111,99,108,105,112, + 20,111,110,112,97,115,116,101,102,114,111,109,99,108,105,112,98,111,97,114, + 100,7,13,112,97,115,116,101,102,114,111,109,99,108,105,112,10,111,110,115, + 101,116,118,97,108,117,101,7,16,102,105,108,101,110,97,109,101,115,101,116, + 118,97,108,117,101,16,100,114,111,112,100,111,119,110,46,111,112,116,105,111, + 110,115,11,15,100,101,111,95,107,101,121,100,114,111,112,100,111,119,110,12, + 100,101,111,95,99,108,105,112,104,105,110,116,0,25,100,114,111,112,100,111, + 119,110,46,100,114,111,112,100,111,119,110,114,111,119,99,111,117,110,116,2, + 10,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,99,111,117,110, + 116,2,1,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,105,116, + 101,109,115,14,1,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95, + 121,99,101,110,116,101,114,101,100,11,116,102,95,110,111,115,101,108,101,99, + 116,14,116,102,95,101,108,108,105,112,115,101,108,101,102,116,0,0,0,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,0,9, + 116,108,97,121,111,117,116,101,114,10,116,108,97,121,111,117,116,101,114,51, + 13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,11,111,119,95,116, + 97,98,102,111,99,117,115,17,111,119,95,112,97,114,101,110,116,116,97,98, + 102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15, + 111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97, + 114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102, + 111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100, + 115,95,120,2,1,8,98,111,117,110,100,115,95,121,2,2,9,98,111,117, + 110,100,115,95,99,120,3,72,2,9,98,111,117,110,100,115,95,99,121,2, + 20,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97, + 110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,12,111,112,116,105, + 111,110,115,115,99,97,108,101,11,11,111,115,99,95,101,120,112,97,110,100, + 121,11,111,115,99,95,115,104,114,105,110,107,121,17,111,115,99,95,101,120, + 112,97,110,100,115,104,114,105,110,107,120,17,111,115,99,95,101,120,112,97, + 110,100,115,104,114,105,110,107,121,0,13,111,112,116,105,111,110,115,108,97, + 121,111,117,116,11,10,108,97,111,95,112,108,97,99,101,120,10,108,97,111, + 95,97,108,105,103,110,121,0,10,97,108,105,103,110,95,103,108,117,101,7, + 9,119,97,109,95,115,116,97,114,116,13,112,108,97,99,101,95,109,105,110, + 100,105,115,116,2,2,13,112,108,97,99,101,95,109,97,120,100,105,115,116, + 2,2,13,112,108,97,99,101,95,111,112,116,105,111,110,115,11,13,112,108, + 111,95,101,110,100,109,97,114,103,105,110,0,10,108,105,110,107,98,111,116, + 116,111,109,7,8,108,105,115,116,118,105,101,119,11,100,105,115,116,95,98, + 111,116,116,111,109,2,2,0,7,116,98,117,116,116,111,110,9,99,114,101, + 97,116,101,100,105,114,14,111,112,116,105,111,110,115,119,105,100,103,101,116, + 49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103, + 104,116,13,111,119,49,95,97,117,116,111,115,99,97,108,101,13,111,119,49, + 95,97,117,116,111,119,105,100,116,104,0,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,11,111,119,95,116,97,98,102,111,99,117,115,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111, + 119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99, + 117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,8,116,97,98,111,114,100,101,114,2,5,8,98,111,117,110, + 100,115,95,120,3,16,2,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,120,2,56,9,98,111,117,110,100,115,95,99,121, + 2,20,12,98,111,117,110,100,115,95,99,120,109,105,110,2,35,7,97,110, + 99,104,111,114,115,11,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,0,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99, + 97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101, + 99,117,116,101,0,7,99,97,112,116,105,111,110,6,8,38,78,101,119,32, + 100,105,114,7,111,112,116,105,111,110,115,11,17,98,111,95,101,120,101,99, + 117,116,101,111,110,99,108,105,99,107,15,98,111,95,101,120,101,99,117,116, + 101,111,110,107,101,121,20,98,111,95,101,120,101,99,117,116,101,111,110,115, + 104,111,114,116,99,117,116,27,98,111,95,101,120,101,99,117,116,101,100,101, + 102,97,117,108,116,111,110,101,110,116,101,114,107,101,121,19,98,111,95,99, + 97,110,100,101,102,111,99,117,115,119,105,110,100,111,119,0,9,111,110,101, + 120,101,99,117,116,101,7,18,99,114,101,97,116,101,100,105,114,111,110,101, + 120,101,99,117,116,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,7,116,98,117,116,116,111,110,4,104,111,109,101,14,111,112, + 116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111, + 110,116,103,108,121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117, + 116,111,115,99,97,108,101,13,111,119,49,95,97,117,116,111,119,105,100,116, + 104,0,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,11,111,119, + 95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111, + 99,117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16, + 111,119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,8,116,97,98,111, + 114,100,101,114,2,4,8,98,111,117,110,100,115,95,120,3,224,1,8,98, + 111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2, + 46,9,98,111,117,110,100,115,95,99,121,2,20,12,98,111,117,110,100,115, + 95,99,120,109,105,110,2,35,7,97,110,99,104,111,114,115,11,6,97,110, + 95,116,111,112,8,97,110,95,114,105,103,104,116,0,5,115,116,97,116,101, + 11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115, + 95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,7,99,97,112, + 116,105,111,110,6,5,38,72,111,109,101,7,111,112,116,105,111,110,115,11, + 17,98,111,95,101,120,101,99,117,116,101,111,110,99,108,105,99,107,15,98, + 111,95,101,120,101,99,117,116,101,111,110,107,101,121,20,98,111,95,101,120, + 101,99,117,116,101,111,110,115,104,111,114,116,99,117,116,27,98,111,95,101, + 120,101,99,117,116,101,100,101,102,97,117,108,116,111,110,101,110,116,101,114, + 107,101,121,19,98,111,95,99,97,110,100,101,102,111,99,117,115,119,105,110, + 100,111,119,0,9,111,110,101,120,101,99,117,116,101,7,10,104,111,109,101, + 97,99,116,105,111,110,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,17,116,115,116,111,99,107,103,108,121,112,104,98,117,116,116, + 111,110,7,102,111,114,119,97,114,100,14,111,112,116,105,111,110,115,119,105, + 100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104, + 104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99,97,108,101, + 0,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,11,111,119,95, + 116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115, + 15,111,119,95,100,105,115,97,98,108,101,100,104,105,110,116,0,8,116,97, + 98,111,114,100,101,114,2,3,10,111,110,115,104,111,119,104,105,110,116,7, + 14,98,117,116,116,111,110,115,104,111,119,104,105,110,116,8,98,111,117,110, + 100,115,95,120,3,209,1,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,120,2,13,9,98,111,117,110,100,115,95,99,121, + 2,20,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,8,97, + 110,95,114,105,103,104,116,0,5,115,116,97,116,101,11,11,97,115,95,100, + 105,115,97,98,108,101,100,16,97,115,95,108,111,99,97,108,100,105,115,97, + 98,108,101,100,17,97,115,95,108,111,99,97,108,105,109,97,103,101,108,105, + 115,116,15,97,115,95,108,111,99,97,108,105,109,97,103,101,110,114,16,97, + 115,95,108,111,99,97,108,115,104,111,114,116,99,117,116,17,97,115,95,108, + 111,99,97,108,111,110,101,120,101,99,117,116,101,0,5,103,108,121,112,104, + 7,14,115,116,103,95,97,114,114,111,119,114,105,103,104,116,11,97,117,116, + 111,115,105,122,101,95,99,120,2,246,9,111,110,101,120,101,99,117,116,101, + 7,10,102,111,114,119,97,114,100,101,120,101,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,14,2,115,99,1,2,1,3,90,96,0,0,0, + 17,116,115,116,111,99,107,103,108,121,112,104,98,117,116,116,111,110,4,98, + 97,99,107,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19, + 111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,13, + 111,119,49,95,97,117,116,111,115,99,97,108,101,0,13,111,112,116,105,111, + 110,115,119,105,100,103,101,116,11,11,111,119,95,116,97,98,102,111,99,117, + 115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,17,111,119,95,100, + 101,115,116,114,111,121,119,105,100,103,101,116,115,15,111,119,95,100,105,115, + 97,98,108,101,100,104,105,110,116,0,8,116,97,98,111,114,100,101,114,2, + 2,10,111,110,115,104,111,119,104,105,110,116,7,14,98,117,116,116,111,110, + 115,104,111,119,104,105,110,116,8,98,111,117,110,100,115,95,120,3,194,1, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,2,13,9,98,111,117,110,100,115,95,99,121,2,20,7,97,110,99,104, + 111,114,115,11,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116, + 0,5,115,116,97,116,101,11,11,97,115,95,100,105,115,97,98,108,101,100, + 16,97,115,95,108,111,99,97,108,100,105,115,97,98,108,101,100,17,97,115, + 95,108,111,99,97,108,105,109,97,103,101,108,105,115,116,15,97,115,95,108, + 111,99,97,108,105,109,97,103,101,110,114,16,97,115,95,108,111,99,97,108, + 115,104,111,114,116,99,117,116,17,97,115,95,108,111,99,97,108,111,110,101, + 120,101,99,117,116,101,0,5,103,108,121,112,104,7,13,115,116,103,95,97, + 114,114,111,119,108,101,102,116,11,97,117,116,111,115,105,122,101,95,99,120, + 2,246,9,111,110,101,120,101,99,117,116,101,7,7,98,97,99,107,101,120, + 101,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,2,115,99, + 1,2,1,3,90,64,0,0,0,17,116,115,116,111,99,107,103,108,121,112, + 104,98,117,116,116,111,110,2,117,112,14,111,112,116,105,111,110,115,119,105, + 100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104, + 104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99,97,108,101, + 0,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,11,111,119,95, + 116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111, + 119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,17,111,119,95,100, + 101,115,116,114,111,121,119,105,100,103,101,116,115,0,8,116,97,98,111,114, + 100,101,114,2,1,10,111,110,115,104,111,119,104,105,110,116,7,14,98,117, + 116,116,111,110,115,104,111,119,104,105,110,116,8,98,111,117,110,100,115,95, + 120,3,175,1,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,120,2,17,9,98,111,117,110,100,115,95,99,121,2,20,7, + 97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,8,97,110,95,114, + 105,103,104,116,0,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,105,109,97, + 103,101,108,105,115,116,15,97,115,95,108,111,99,97,108,105,109,97,103,101, + 110,114,16,97,115,95,108,111,99,97,108,115,104,111,114,116,99,117,116,17, + 97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,5,103, + 108,121,112,104,7,11,115,116,103,95,97,114,114,111,119,117,112,7,111,112, + 116,105,111,110,115,11,17,98,111,95,101,120,101,99,117,116,101,111,110,99, + 108,105,99,107,15,98,111,95,101,120,101,99,117,116,101,111,110,107,101,121, + 20,98,111,95,101,120,101,99,117,116,101,111,110,115,104,111,114,116,99,117, + 116,27,98,111,95,101,120,101,99,117,116,101,100,101,102,97,117,108,116,111, + 110,101,110,116,101,114,107,101,121,19,98,111,95,99,97,110,100,101,102,111, + 99,117,115,119,105,110,100,111,119,0,9,111,110,101,120,101,99,117,116,101, + 7,8,117,112,97,99,116,105,111,110,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,14,2,115,99,1,2,1,3,22,65,0,0,0,16,116, + 100,105,114,100,114,111,112,100,111,119,110,101,100,105,116,3,100,105,114,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111, + 117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114, + 114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102, + 111,99,117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,0,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,4,38,68,105,114,16,102,114,97,109,101,46,99,97,112,116,105,111,110, + 112,111,115,7,8,99,112,95,114,105,103,104,116,16,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,49,11,0,19,102,114,97,109,101,46,98, + 117,116,116,111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101, + 46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,0,0,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,0, + 2,20,2,0,0,10,111,110,115,104,111,119,104,105,110,116,7,11,100,105, + 114,115,104,111,119,104,105,110,116,8,98,111,117,110,100,115,95,120,2,0, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,3,173,1,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102, + 116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,9,116, + 101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101,110,116,101,114, + 101,100,11,116,102,95,110,111,115,101,108,101,99,116,14,116,102,95,101,108, + 108,105,112,115,101,108,101,102,116,0,16,100,114,111,112,100,111,119,110,46, + 111,112,116,105,111,110,115,11,14,100,101,111,95,115,101,108,101,99,116,111, + 110,108,121,15,100,101,111,95,107,101,121,100,114,111,112,100,111,119,110,0, + 10,111,110,115,101,116,118,97,108,117,101,7,13,100,105,114,111,110,115,101, + 116,118,97,108,117,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,Tfiledialogfo,''); +end. diff --git a/mseide-msegui/lib/common/dialogs/msefiledialogres.mfm b/mseide-msegui/lib/common/dialogs/msefiledialogres.mfm new file mode 100644 index 0000000..a65ffe7 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msefiledialogres.mfm @@ -0,0 +1,178 @@ +object filedialogres: tfiledialogres + bounds_cx = 235 + bounds_cy = 117 + left = 93 + top = 396 + moduleclassname = 'tmsedatamodule' + object images: timagelist + count = 16 + left = 32 + top = 32 + image = { + 0000000002000000400000004000000038120000000000000000000000000000 + 0000000000000000000000000000000000000000FF00FFA300000006FF00FF1A + 7F7F7F01000000047F7F7F01FF00FF097F7F7F01000000047F7F7F01FF00FF0B + 00000001FFFFFF0400000002FF00FF097F7F7F01000000047F7F7F01FF00FF0A + 00000001FFFFFF0100FFFF01FFFFFF0100FFFF0100000001FF00FF0900000001 + 00FFFF01FFFFFF0100FFFF01FFFFFF0100000001FF00FF0B00000001FFFFFF04 + 00000001FFFFFF0100000001FF00FF0800000001FFFFFF0100FFFF01FFFFFF01 + 00FFFF0100000001FF00FF090000000AFF00FF050000000100FFFF01FFFFFF01 + 00FFFF01FFFFFF0100FFFF01FFFFFF0100000003FF00FF0800000001FFFFFF04 + 00000001FFFFFF0200000001FF00FF060000000AFF00FF0600000001FFFFFF01 + 00FFFF01FFFFFF0100FFFF01FFFFFF0100FFFF01FFFFFF0100FFFF01FFFFFF01 + 00000001FF00FF0400000001FFFFFF0100FFFF01FFFFFF0100FFFF01FFFFFF01 + 00FFFF01FFFFFF0100FFFF01FFFFFF0100000001FF00FF0700000001FFFFFF04 + 00000005FF00FF0500000001FFFFFF0100FFFF01FFFFFF0100FFFF01FFFFFF01 + 00FFFF01FFFFFF0100FFFF01FFFFFF0100000001FF00FF050000000100FFFF01 + FFFFFF0100FFFF01FFFFFF0100FFFF01FFFFFF0100FFFF01FFFFFF0100FFFF01 + 00000001FF00FF040000000100FFFF01FFFFFF0100FFFF01FFFFFF0100FFFF01 + FFFFFF0100FFFF01FFFFFF0100FFFF0100000001FF00FF0700000001FFFFFF08 + 0000000180808001FF00FF040000000100FFFF01FFFFFF0100FFFF01FFFFFF01 + 00000001FFFFFF0100FFFF01FFFFFF0100FFFF0100000001FF00FF0500000001 + FFFFFF0100FFFF01FFFFFF0100FFFF01FFFFFF0100FFFF01FFFFFF0100FFFF01 + FFFFFF0100000001FF00FF0400000001FFFFFF0100FFFF01FFFFFF010000000A + FF00FF0400000001FFFFFF080000000180808001FF00FF0400000001FFFFFF01 + 00FFFF01FFFFFF0100FFFF010000000100FFFF01FFFFFF0100FFFF01FFFFFF01 + 00000001FF00FF050000000100FFFF01FFFFFF0100FFFF01FFFFFF0100FFFF01 + FFFFFF0100FFFF01FFFFFF0100FFFF0100000001FF00FF040000000100FFFF01 + FFFFFF010000000100FFFF01BFBFBF0100FFFF01BFBFBF0100FFFF01BFBFBF01 + 00FFFF01BFBFBF0100FFFF0100000001FF00FF0400000001FFFFFF0800000001 + 80808001FF00FF040000000100FFFF01FFFFFF0100000005FFFFFF0100FFFF01 + 00000001FF00FF0500000001FFFFFF0100FFFF01FFFFFF0100FFFF01FFFFFF01 + 00FFFF01FFFFFF0100FFFF01FFFFFF0100000001FF00FF0400000001FFFFFF01 + 0000000100FFFF01BFBFBF0100FFFF01BFBFBF0100FFFF01BFBFBF0100FFFF01 + BFBFBF0100FFFF0100000001FF00FF0500000001FFFFFF080000000180808001 + FF00FF0400000001FFFFFF0100FFFF01FFFFFF0100FFFF010000000100FFFF01 + FFFFFF0100FFFF01FFFFFF0100000001FF00FF050000000100FFFF01FFFFFF01 + 00FFFF01FFFFFF0100FFFF01FFFFFF0100FFFF01FFFFFF0100FFFF0100000001 + FF00FF040000000200FFFF01BFBFBF0100FFFF01BFBFBF0100FFFF01BFBFBF01 + 00FFFF01BFBFBF0100FFFF0100000001FF00FF0600000001FFFFFF0800000001 + 80808001FF00FF040000000100FFFF01FFFFFF0100FFFF01FFFFFF0100000001 + FFFFFF0100FFFF01FFFFFF0100FFFF0100000001FF00FF060000000AFF00FF05 + 0000000AFF00FF0700000001FFFFFF080000000180808001FF00FF050000000A + FF00FF260000000A80808001FF00FF368080800AFF00FFF500000006FF00FF1A + 7F7F7F01000000047F7F7F01FF00FF097F7F7F01000000047F7F7F01FF00FF0B + 000000017B00FF0400000002FF00FF097F7F7F01000000047F7F7F01FF00FF0A + 00000001FFFFFF017B00FF01FFFFFF017B00FF0100000001FF00FF0900000001 + 7B00FF01FFFFFF017B00FF01FFFFFF0100000001FF00FF0B000000017B00FF04 + 000000017B00FF0100000001FF00FF0800000001FFFFFF017B00FF01FFFFFF01 + 7B00FF0100000001FF00FF090000000AFF00FF05000000017B00FF01FFFFFF01 + 7B00FF01FFFFFF017B00FF01FFFFFF0100000003FF00FF08000000017B00FF04 + 000000017B00FF0200000001FF00FF060000000AFF00FF0600000001FFFFFF01 + 7B00FF01FFFFFF017B00FF01FFFFFF017B00FF01FFFFFF017B00FF01FFFFFF01 + 00000001FF00FF0400000001FFFFFF017B00FF01FFFFFF017B00FF01FFFFFF01 + 7B00FF01FFFFFF017B00FF01FFFFFF0100000001FF00FF07000000017B00FF04 + 00000005FF00FF0500000001FFFFFF017B00FF01FFFFFF017B00FF01FFFFFF01 + 7B00FF01FFFFFF017B00FF01FFFFFF0100000001FF00FF05000000017B00FF01 + FFFFFF017B00FF01FFFFFF017B00FF01FFFFFF017B00FF01FFFFFF017B00FF01 + 00000001FF00FF04000000017B00FF01FFFFFF017B00FF01FFFFFF017B00FF01 + FFFFFF017B00FF01FFFFFF017B00FF0100000001FF00FF07000000017B00FF08 + 0000000180808001FF00FF04000000017B00FF01FFFFFF017B00FF01FFFFFF01 + 00000001FFFFFF017B00FF01FFFFFF017B00FF0100000001FF00FF0500000001 + FFFFFF017B00FF01FFFFFF017B00FF01FFFFFF017B00FF01FFFFFF017B00FF01 + FFFFFF0100000001FF00FF0400000001FFFFFF017B00FF01FFFFFF010000000A + FF00FF04000000017B00FF080000000180808001FF00FF0400000001FFFFFF01 + 7B00FF01FFFFFF017B00FF01000000017B00FF01FFFFFF017B00FF01FFFFFF01 + 00000001FF00FF05000000017B00FF01FFFFFF017B00FF01FFFFFF017B00FF01 + FFFFFF017B00FF01FFFFFF017B00FF0100000001FF00FF04000000017B00FF01 + FFFFFF01000000017B00FF01BFBFBF017B00FF01BFBFBF017B00FF01BFBFBF01 + 7B00FF01BFBFBF017B00FF0100000001FF00FF04000000017B00FF0800000001 + 80808001FF00FF04000000017B00FF01FFFFFF0100000005FFFFFF017B00FF01 + 00000001FF00FF0500000001FFFFFF017B00FF01FFFFFF017B00FF01FFFFFF01 + 7B00FF01FFFFFF017B00FF01FFFFFF0100000001FF00FF0400000001FFFFFF01 + 000000017B00FF01BFBFBF017B00FF01BFBFBF017B00FF01BFBFBF017B00FF01 + BFBFBF017B00FF0100000001FF00FF05000000017B00FF080000000180808001 + FF00FF0400000001FFFFFF017B00FF01FFFFFF017B00FF01000000017B00FF01 + FFFFFF017B00FF01FFFFFF0100000001FF00FF05000000017B00FF01FFFFFF01 + 7B00FF01FFFFFF017B00FF01FFFFFF017B00FF01FFFFFF017B00FF0100000001 + FF00FF04000000027B00FF01BFBFBF017B00FF01BFBFBF017B00FF01BFBFBF01 + 7B00FF01BFBFBF017B00FF0100000001FF00FF06000000017B00FF0800000001 + 80808001FF00FF04000000017B00FF01FFFFFF017B00FF01FFFFFF0100000001 + FFFFFF017B00FF01FFFFFF017B00FF0100000001FF00FF060000000AFF00FF05 + 0000000AFF00FF07000000017B00FF080000000180808001FF00FF050000000A + FF00FF260000000A80808001FF00FF368080800AFF00FFF500000006FF00FF1A + 7F7F7F01000000047F7F7F01FF00FF097F7F7F01000000047F7F7F01FF00FF0B + 0000000100FF000400000002FF00FF097F7F7F01000000047F7F7F01FF00FF0A + 00000001FFFFFF0100FF0001FFFFFF0100FF000100000001FF00FF0900000001 + 00FF0001FFFFFF0100FF0001FFFFFF0100000001FF00FF0B0000000100FF0004 + 0000000100FF000100000001FF00FF0800000001FFFFFF0100FF0001FFFFFF01 + 00FF000100000001FF00FF090000000AFF00FF050000000100FF0001FFFFFF01 + 00FF0001FFFFFF0100FF0001FFFFFF0100000003FF00FF080000000100FF0004 + 0000000100FF000200000001FF00FF060000000AFF00FF0600000001FFFFFF01 + 00FF0001FFFFFF0100FF0001FFFFFF0100FF0001FFFFFF0100FF0001FFFFFF01 + 00000001FF00FF0400000001FFFFFF0100FF0001FFFFFF0100FF0001FFFFFF01 + 00FF0001FFFFFF0100FF0001FFFFFF0100000001FF00FF070000000100FF0004 + 00000005FF00FF0500000001FFFFFF0100FF0001FFFFFF0100FF0001FFFFFF01 + 00FF0001FFFFFF0100FF0001FFFFFF0100000001FF00FF050000000100FF0001 + FFFFFF0100FF0001FFFFFF0100FF0001FFFFFF0100FF0001FFFFFF0100FF0001 + 00000001FF00FF040000000100FF0001FFFFFF0100FF0001FFFFFF0100FF0001 + FFFFFF0100FF0001FFFFFF0100FF000100000001FF00FF070000000100FF0008 + 0000000180808001FF00FF040000000100FF0001FFFFFF0100FF0001FFFFFF01 + 00000001FFFFFF0100FF0001FFFFFF0100FF000100000001FF00FF0500000001 + FFFFFF0100FF0001FFFFFF0100FF0001FFFFFF0100FF0001FFFFFF0100FF0001 + FFFFFF0100000001FF00FF0400000001FFFFFF0100FF0001FFFFFF010000000A + FF00FF040000000100FF00080000000180808001FF00FF0400000001FFFFFF01 + 00FF0001FFFFFF0100FF00010000000100FF0001FFFFFF0100FF0001FFFFFF01 + 00000001FF00FF050000000100FF0001FFFFFF0100FF0001FFFFFF0100FF0001 + FFFFFF0100FF0001FFFFFF0100FF000100000001FF00FF040000000100FF0001 + FFFFFF010000000100FF0001BFBFBF0100FF0001BFBFBF0100FF0001BFBFBF01 + 00FF0001BFBFBF0100FF000100000001FF00FF040000000100FF000800000001 + 80808001FF00FF040000000100FF0001FFFFFF0100000005FFFFFF0100FF0001 + 00000001FF00FF0500000001FFFFFF0100FF0001FFFFFF0100FF0001FFFFFF01 + 00FF0001FFFFFF0100FF0001FFFFFF0100000001FF00FF0400000001FFFFFF01 + 0000000100FF0001BFBFBF0100FF0001BFBFBF0100FF0001BFBFBF0100FF0001 + BFBFBF0100FF000100000001FF00FF050000000100FF00080000000180808001 + FF00FF0400000001FFFFFF0100FF0001FFFFFF0100FF00010000000100FF0001 + FFFFFF0100FF0001FFFFFF0100000001FF00FF050000000100FF0001FFFFFF01 + 00FF0001FFFFFF0100FF0001FFFFFF0100FF0001FFFFFF0100FF000100000001 + FF00FF040000000200FF0001BFBFBF0100FF0001BFBFBF0100FF0001BFBFBF01 + 00FF0001BFBFBF0100FF000100000001FF00FF060000000100FF000800000001 + 80808001FF00FF040000000100FF0001FFFFFF0100FF0001FFFFFF0100000001 + FFFFFF0100FF0001FFFFFF0100FF000100000001FF00FF060000000AFF00FF05 + 0000000AFF00FF070000000100FF00080000000180808001FF00FF050000000A + FF00FF260000000A80808001FF00FF368080800AFF00FFF500000006FF00FF1A + 7F7F7F01000000047F7F7F01FF00FF097F7F7F01000000047F7F7F01FF00FF0B + 00000001FFFFFF0400000002FF00FF097F7F7F01000000047F7F7F01FF00FF0A + 00000001FFFFFF0400000001FF00FF0900000001FFFFFF0400000001FF00FF0B + 00000001FFFFFF0400000001FFFFFF0100000001FF00FF0800000001FFFFFF04 + 00000001FF00FF090000000AFF00FF0500000001FFFFFF0600000003FF00FF08 + 00000001FFFFFF0400000001FFFFFF0200000001FF00FF060000000AFF00FF06 + 00000001FFFFFF0900000001FF00FF0400000001FFFFFF0900000001FF00FF07 + 00000001FFFFFF0400000005FF00FF0500000001FFFFFF0900000001FF00FF05 + 00000001FFFFFF0900000001FF00FF0400000001FFFFFF0900000001FF00FF07 + 00000001FFFFFF080000000180808001FF00FF0400000001FFFFFF0400000001 + FFFFFF0400000001FF00FF0500000001FFFFFF0900000001FF00FF0400000001 + FFFFFF030000000AFF00FF0400000001FFFFFF080000000180808001FF00FF04 + 00000001FFFFFF0400000001FFFFFF0400000001FF00FF0500000001FFFFFF09 + 00000001FF00FF0400000001FFFFFF0200000001FFFFFF01BFBFBF01FFFFFF01 + BFBFBF01FFFFFF01BFBFBF01FFFFFF01BFBFBF01FFFFFF0100000001FF00FF04 + 00000001FFFFFF080000000180808001FF00FF0400000001FFFFFF0200000005 + FFFFFF0200000001FF00FF0500000001FFFFFF0900000001FF00FF0400000001 + FFFFFF0100000001FFFFFF01BFBFBF01FFFFFF01BFBFBF01FFFFFF01BFBFBF01 + FFFFFF01BFBFBF01FFFFFF0100000001FF00FF0500000001FFFFFF0800000001 + 80808001FF00FF0400000001FFFFFF0400000001FFFFFF0400000001FF00FF05 + 00000001FFFFFF0900000001FF00FF0400000002FFFFFF01BFBFBF01FFFFFF01 + BFBFBF01FFFFFF01BFBFBF01FFFFFF01BFBFBF01FFFFFF0100000001FF00FF06 + 00000001FFFFFF080000000180808001FF00FF0400000001FFFFFF0400000001 + FFFFFF0400000001FF00FF060000000AFF00FF050000000AFF00FF0700000001 + FFFFFF080000000180808001FF00FF050000000AFF00FF260000000A80808001 + FF00FF368080800AFF00FF520000000000000000000000000000000000000000 + F8010000F801FC00F803F801F801FC00F807F801FC0FFE07F80FFC0FFC1FFE0F + F81FFC1FFC1FFE0FF83FFC1FFC1FFE7FF83FFC1FFC1FFE7FF83FFC1FFC1FFE3F + F83FFC1FFC1FFE1FF83FFC1FF81FFC0FF83FF81F00000000F83F000000000000 + F03F000000000000000000000000000000000000000000000000000000000000 + F8010000F801FC00F803F801F801FC00F807F801FC0FFE07F80FFC0FFC1FFE0F + F81FFC1FFC1FFE0FF83FFC1FFC1FFE7FF83FFC1FFC1FFE7FF83FFC1FFC1FFE3F + F83FFC1FFC1FFE1FF83FFC1FF81FFC0FF83FF81F00000000F83F000000000000 + F03F000000000000000000000000000000000000000000000000000000000000 + F8010000F801FC00F803F801F801FC00F807F801FC0FFE07F80FFC0FFC1FFE0F + F81FFC1FFC1FFE0FF83FFC1FFC1FFE7FF83FFC1FFC1FFE7FF83FFC1FFC1FFE3F + F83FFC1FFC1FFE1FF83FFC1FF81FFC0FF83FF81F00000000F83F000000000000 + F03F000000000000000000000000000000000000000000000000000000000000 + F8010000F801FC00F803F801F801FC00F807F801FC0FFE07F80FFC0FFC1FFE0F + F81FFC1FFC1FFE0FF83FFC1FFC1FFE7FF83FFC1FFC1FFE7FF83FFC1FFC1FFE3F + F83FFC1FFC1FFE1FF83FFC1FF81FFC0FF83FF81F00000000F83F000000000000 + F03F00000000000000000000 + } + end +end diff --git a/mseide-msegui/lib/common/dialogs/msefiledialogres.pas b/mseide-msegui/lib/common/dialogs/msefiledialogres.pas new file mode 100644 index 0000000..c0bad49 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msefiledialogres.pas @@ -0,0 +1,61 @@ +{ MSEgui Copyright (c) 1999-2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msefiledialogres; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseclasses,msebitmap,msegui,msedatamodules; + +type + filedialogiconty = (fdi_dir,fdi_diropen,fdi_file,fdi_direntry); + tfiledialogres = class(tmsedatamodule) + images: timagelist; + public + procedure getfileicon(const aimage: filedialogiconty; var imagelist: timagelist; + out imagenr: integer); + end; + +function filedialogres: tfiledialogres; + +implementation + +uses + msefiledialogres_mfm,sysutils; +var + ffiledialogres: tfiledialogres; + +function filedialogres: tfiledialogres; +begin + result:= ffiledialogres; +end; + +{ tfiledialogres } + +procedure tfiledialogres.getfileicon(const aimage: filedialogiconty; + var imagelist: timagelist; out imagenr: integer); +begin + if imagelist = nil then begin + imagelist:= images; + end; + imagenr:= ord(aimage); +end; + +initialization + application.lock; //create application instance + try + createmodule(nil,tfiledialogres,ffiledialogres); + finally + application.unlock; + end; +finalization + freeandnil(ffiledialogres); +end. diff --git a/mseide-msegui/lib/common/dialogs/msefiledialogres_mfm.pas b/mseide-msegui/lib/common/dialogs/msefiledialogres_mfm.pas new file mode 100644 index 0000000..f0b5983 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msefiledialogres_mfm.pas @@ -0,0 +1,287 @@ +unit msefiledialogres_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msefiledialogres; + +const + objdata: record size: integer; data: array[0..5385] of byte end = + (size: 5386; data: ( + 84,80,70,48,14,116,102,105,108,101,100,105,97,108,111,103,114,101,115,13, + 102,105,108,101,100,105,97,108,111,103,114,101,115,9,98,111,117,110,100,115, + 95,99,120,3,235,0,9,98,111,117,110,100,115,95,99,121,2,117,4,108, + 101,102,116,2,93,3,116,111,112,3,140,1,15,109,111,100,117,108,101,99, + 108,97,115,115,110,97,109,101,6,14,116,109,115,101,100,97,116,97,109,111, + 100,117,108,101,0,10,116,105,109,97,103,101,108,105,115,116,6,105,109,97, + 103,101,115,5,99,111,117,110,116,2,16,4,108,101,102,116,2,32,3,116, + 111,112,2,32,5,105,109,97,103,101,10,108,20,0,0,0,0,0,0,2, + 0,0,0,64,0,0,0,64,0,0,0,56,18,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,255,0,255,163,0,0,0,6,255,0,255,26,127, + 127,127,1,0,0,0,4,127,127,127,1,255,0,255,9,127,127,127,1,0, + 0,0,4,127,127,127,1,255,0,255,11,0,0,0,1,255,255,255,4,0, + 0,0,2,255,0,255,9,127,127,127,1,0,0,0,4,127,127,127,1,255, + 0,255,10,0,0,0,1,255,255,255,1,0,255,255,1,255,255,255,1,0, + 255,255,1,0,0,0,1,255,0,255,9,0,0,0,1,0,255,255,1,255, + 255,255,1,0,255,255,1,255,255,255,1,0,0,0,1,255,0,255,11,0, + 0,0,1,255,255,255,4,0,0,0,1,255,255,255,1,0,0,0,1,255, + 0,255,8,0,0,0,1,255,255,255,1,0,255,255,1,255,255,255,1,0, + 255,255,1,0,0,0,1,255,0,255,9,0,0,0,10,255,0,255,5,0, + 0,0,1,0,255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0, + 255,255,1,255,255,255,1,0,0,0,3,255,0,255,8,0,0,0,1,255, + 255,255,4,0,0,0,1,255,255,255,2,0,0,0,1,255,0,255,6,0, + 0,0,10,255,0,255,6,0,0,0,1,255,255,255,1,0,255,255,1,255, + 255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0, + 255,255,1,255,255,255,1,0,0,0,1,255,0,255,4,0,0,0,1,255, + 255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0, + 255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0,0,0,1,255, + 0,255,7,0,0,0,1,255,255,255,4,0,0,0,5,255,0,255,5,0, + 0,0,1,255,255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,255, + 255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0, + 0,0,1,255,0,255,5,0,0,0,1,0,255,255,1,255,255,255,1,0, + 255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,255, + 255,255,1,0,255,255,1,0,0,0,1,255,0,255,4,0,0,0,1,0, + 255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,255, + 255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,0,0,0,1,255, + 0,255,7,0,0,0,1,255,255,255,8,0,0,0,1,128,128,128,1,255, + 0,255,4,0,0,0,1,0,255,255,1,255,255,255,1,0,255,255,1,255, + 255,255,1,0,0,0,1,255,255,255,1,0,255,255,1,255,255,255,1,0, + 255,255,1,0,0,0,1,255,0,255,5,0,0,0,1,255,255,255,1,0, + 255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,255, + 255,255,1,0,255,255,1,255,255,255,1,0,0,0,1,255,0,255,4,0, + 0,0,1,255,255,255,1,0,255,255,1,255,255,255,1,0,0,0,10,255, + 0,255,4,0,0,0,1,255,255,255,8,0,0,0,1,128,128,128,1,255, + 0,255,4,0,0,0,1,255,255,255,1,0,255,255,1,255,255,255,1,0, + 255,255,1,0,0,0,1,0,255,255,1,255,255,255,1,0,255,255,1,255, + 255,255,1,0,0,0,1,255,0,255,5,0,0,0,1,0,255,255,1,255, + 255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0, + 255,255,1,255,255,255,1,0,255,255,1,0,0,0,1,255,0,255,4,0, + 0,0,1,0,255,255,1,255,255,255,1,0,0,0,1,0,255,255,1,191, + 191,191,1,0,255,255,1,191,191,191,1,0,255,255,1,191,191,191,1,0, + 255,255,1,191,191,191,1,0,255,255,1,0,0,0,1,255,0,255,4,0, + 0,0,1,255,255,255,8,0,0,0,1,128,128,128,1,255,0,255,4,0, + 0,0,1,0,255,255,1,255,255,255,1,0,0,0,5,255,255,255,1,0, + 255,255,1,0,0,0,1,255,0,255,5,0,0,0,1,255,255,255,1,0, + 255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,255, + 255,255,1,0,255,255,1,255,255,255,1,0,0,0,1,255,0,255,4,0, + 0,0,1,255,255,255,1,0,0,0,1,0,255,255,1,191,191,191,1,0, + 255,255,1,191,191,191,1,0,255,255,1,191,191,191,1,0,255,255,1,191, + 191,191,1,0,255,255,1,0,0,0,1,255,0,255,5,0,0,0,1,255, + 255,255,8,0,0,0,1,128,128,128,1,255,0,255,4,0,0,0,1,255, + 255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,0,0,0,1,0, + 255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0,0,0,1,255, + 0,255,5,0,0,0,1,0,255,255,1,255,255,255,1,0,255,255,1,255, + 255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0, + 255,255,1,0,0,0,1,255,0,255,4,0,0,0,2,0,255,255,1,191, + 191,191,1,0,255,255,1,191,191,191,1,0,255,255,1,191,191,191,1,0, + 255,255,1,191,191,191,1,0,255,255,1,0,0,0,1,255,0,255,6,0, + 0,0,1,255,255,255,8,0,0,0,1,128,128,128,1,255,0,255,4,0, + 0,0,1,0,255,255,1,255,255,255,1,0,255,255,1,255,255,255,1,0, + 0,0,1,255,255,255,1,0,255,255,1,255,255,255,1,0,255,255,1,0, + 0,0,1,255,0,255,6,0,0,0,10,255,0,255,5,0,0,0,10,255, + 0,255,7,0,0,0,1,255,255,255,8,0,0,0,1,128,128,128,1,255, + 0,255,5,0,0,0,10,255,0,255,38,0,0,0,10,128,128,128,1,255, + 0,255,54,128,128,128,10,255,0,255,245,0,0,0,6,255,0,255,26,127, + 127,127,1,0,0,0,4,127,127,127,1,255,0,255,9,127,127,127,1,0, + 0,0,4,127,127,127,1,255,0,255,11,0,0,0,1,123,0,255,4,0, + 0,0,2,255,0,255,9,127,127,127,1,0,0,0,4,127,127,127,1,255, + 0,255,10,0,0,0,1,255,255,255,1,123,0,255,1,255,255,255,1,123, + 0,255,1,0,0,0,1,255,0,255,9,0,0,0,1,123,0,255,1,255, + 255,255,1,123,0,255,1,255,255,255,1,0,0,0,1,255,0,255,11,0, + 0,0,1,123,0,255,4,0,0,0,1,123,0,255,1,0,0,0,1,255, + 0,255,8,0,0,0,1,255,255,255,1,123,0,255,1,255,255,255,1,123, + 0,255,1,0,0,0,1,255,0,255,9,0,0,0,10,255,0,255,5,0, + 0,0,1,123,0,255,1,255,255,255,1,123,0,255,1,255,255,255,1,123, + 0,255,1,255,255,255,1,0,0,0,3,255,0,255,8,0,0,0,1,123, + 0,255,4,0,0,0,1,123,0,255,2,0,0,0,1,255,0,255,6,0, + 0,0,10,255,0,255,6,0,0,0,1,255,255,255,1,123,0,255,1,255, + 255,255,1,123,0,255,1,255,255,255,1,123,0,255,1,255,255,255,1,123, + 0,255,1,255,255,255,1,0,0,0,1,255,0,255,4,0,0,0,1,255, + 255,255,1,123,0,255,1,255,255,255,1,123,0,255,1,255,255,255,1,123, + 0,255,1,255,255,255,1,123,0,255,1,255,255,255,1,0,0,0,1,255, + 0,255,7,0,0,0,1,123,0,255,4,0,0,0,5,255,0,255,5,0, + 0,0,1,255,255,255,1,123,0,255,1,255,255,255,1,123,0,255,1,255, + 255,255,1,123,0,255,1,255,255,255,1,123,0,255,1,255,255,255,1,0, + 0,0,1,255,0,255,5,0,0,0,1,123,0,255,1,255,255,255,1,123, + 0,255,1,255,255,255,1,123,0,255,1,255,255,255,1,123,0,255,1,255, + 255,255,1,123,0,255,1,0,0,0,1,255,0,255,4,0,0,0,1,123, + 0,255,1,255,255,255,1,123,0,255,1,255,255,255,1,123,0,255,1,255, + 255,255,1,123,0,255,1,255,255,255,1,123,0,255,1,0,0,0,1,255, + 0,255,7,0,0,0,1,123,0,255,8,0,0,0,1,128,128,128,1,255, + 0,255,4,0,0,0,1,123,0,255,1,255,255,255,1,123,0,255,1,255, + 255,255,1,0,0,0,1,255,255,255,1,123,0,255,1,255,255,255,1,123, + 0,255,1,0,0,0,1,255,0,255,5,0,0,0,1,255,255,255,1,123, + 0,255,1,255,255,255,1,123,0,255,1,255,255,255,1,123,0,255,1,255, + 255,255,1,123,0,255,1,255,255,255,1,0,0,0,1,255,0,255,4,0, + 0,0,1,255,255,255,1,123,0,255,1,255,255,255,1,0,0,0,10,255, + 0,255,4,0,0,0,1,123,0,255,8,0,0,0,1,128,128,128,1,255, + 0,255,4,0,0,0,1,255,255,255,1,123,0,255,1,255,255,255,1,123, + 0,255,1,0,0,0,1,123,0,255,1,255,255,255,1,123,0,255,1,255, + 255,255,1,0,0,0,1,255,0,255,5,0,0,0,1,123,0,255,1,255, + 255,255,1,123,0,255,1,255,255,255,1,123,0,255,1,255,255,255,1,123, + 0,255,1,255,255,255,1,123,0,255,1,0,0,0,1,255,0,255,4,0, + 0,0,1,123,0,255,1,255,255,255,1,0,0,0,1,123,0,255,1,191, + 191,191,1,123,0,255,1,191,191,191,1,123,0,255,1,191,191,191,1,123, + 0,255,1,191,191,191,1,123,0,255,1,0,0,0,1,255,0,255,4,0, + 0,0,1,123,0,255,8,0,0,0,1,128,128,128,1,255,0,255,4,0, + 0,0,1,123,0,255,1,255,255,255,1,0,0,0,5,255,255,255,1,123, + 0,255,1,0,0,0,1,255,0,255,5,0,0,0,1,255,255,255,1,123, + 0,255,1,255,255,255,1,123,0,255,1,255,255,255,1,123,0,255,1,255, + 255,255,1,123,0,255,1,255,255,255,1,0,0,0,1,255,0,255,4,0, + 0,0,1,255,255,255,1,0,0,0,1,123,0,255,1,191,191,191,1,123, + 0,255,1,191,191,191,1,123,0,255,1,191,191,191,1,123,0,255,1,191, + 191,191,1,123,0,255,1,0,0,0,1,255,0,255,5,0,0,0,1,123, + 0,255,8,0,0,0,1,128,128,128,1,255,0,255,4,0,0,0,1,255, + 255,255,1,123,0,255,1,255,255,255,1,123,0,255,1,0,0,0,1,123, + 0,255,1,255,255,255,1,123,0,255,1,255,255,255,1,0,0,0,1,255, + 0,255,5,0,0,0,1,123,0,255,1,255,255,255,1,123,0,255,1,255, + 255,255,1,123,0,255,1,255,255,255,1,123,0,255,1,255,255,255,1,123, + 0,255,1,0,0,0,1,255,0,255,4,0,0,0,2,123,0,255,1,191, + 191,191,1,123,0,255,1,191,191,191,1,123,0,255,1,191,191,191,1,123, + 0,255,1,191,191,191,1,123,0,255,1,0,0,0,1,255,0,255,6,0, + 0,0,1,123,0,255,8,0,0,0,1,128,128,128,1,255,0,255,4,0, + 0,0,1,123,0,255,1,255,255,255,1,123,0,255,1,255,255,255,1,0, + 0,0,1,255,255,255,1,123,0,255,1,255,255,255,1,123,0,255,1,0, + 0,0,1,255,0,255,6,0,0,0,10,255,0,255,5,0,0,0,10,255, + 0,255,7,0,0,0,1,123,0,255,8,0,0,0,1,128,128,128,1,255, + 0,255,5,0,0,0,10,255,0,255,38,0,0,0,10,128,128,128,1,255, + 0,255,54,128,128,128,10,255,0,255,245,0,0,0,6,255,0,255,26,127, + 127,127,1,0,0,0,4,127,127,127,1,255,0,255,9,127,127,127,1,0, + 0,0,4,127,127,127,1,255,0,255,11,0,0,0,1,0,255,0,4,0, + 0,0,2,255,0,255,9,127,127,127,1,0,0,0,4,127,127,127,1,255, + 0,255,10,0,0,0,1,255,255,255,1,0,255,0,1,255,255,255,1,0, + 255,0,1,0,0,0,1,255,0,255,9,0,0,0,1,0,255,0,1,255, + 255,255,1,0,255,0,1,255,255,255,1,0,0,0,1,255,0,255,11,0, + 0,0,1,0,255,0,4,0,0,0,1,0,255,0,1,0,0,0,1,255, + 0,255,8,0,0,0,1,255,255,255,1,0,255,0,1,255,255,255,1,0, + 255,0,1,0,0,0,1,255,0,255,9,0,0,0,10,255,0,255,5,0, + 0,0,1,0,255,0,1,255,255,255,1,0,255,0,1,255,255,255,1,0, + 255,0,1,255,255,255,1,0,0,0,3,255,0,255,8,0,0,0,1,0, + 255,0,4,0,0,0,1,0,255,0,2,0,0,0,1,255,0,255,6,0, + 0,0,10,255,0,255,6,0,0,0,1,255,255,255,1,0,255,0,1,255, + 255,255,1,0,255,0,1,255,255,255,1,0,255,0,1,255,255,255,1,0, + 255,0,1,255,255,255,1,0,0,0,1,255,0,255,4,0,0,0,1,255, + 255,255,1,0,255,0,1,255,255,255,1,0,255,0,1,255,255,255,1,0, + 255,0,1,255,255,255,1,0,255,0,1,255,255,255,1,0,0,0,1,255, + 0,255,7,0,0,0,1,0,255,0,4,0,0,0,5,255,0,255,5,0, + 0,0,1,255,255,255,1,0,255,0,1,255,255,255,1,0,255,0,1,255, + 255,255,1,0,255,0,1,255,255,255,1,0,255,0,1,255,255,255,1,0, + 0,0,1,255,0,255,5,0,0,0,1,0,255,0,1,255,255,255,1,0, + 255,0,1,255,255,255,1,0,255,0,1,255,255,255,1,0,255,0,1,255, + 255,255,1,0,255,0,1,0,0,0,1,255,0,255,4,0,0,0,1,0, + 255,0,1,255,255,255,1,0,255,0,1,255,255,255,1,0,255,0,1,255, + 255,255,1,0,255,0,1,255,255,255,1,0,255,0,1,0,0,0,1,255, + 0,255,7,0,0,0,1,0,255,0,8,0,0,0,1,128,128,128,1,255, + 0,255,4,0,0,0,1,0,255,0,1,255,255,255,1,0,255,0,1,255, + 255,255,1,0,0,0,1,255,255,255,1,0,255,0,1,255,255,255,1,0, + 255,0,1,0,0,0,1,255,0,255,5,0,0,0,1,255,255,255,1,0, + 255,0,1,255,255,255,1,0,255,0,1,255,255,255,1,0,255,0,1,255, + 255,255,1,0,255,0,1,255,255,255,1,0,0,0,1,255,0,255,4,0, + 0,0,1,255,255,255,1,0,255,0,1,255,255,255,1,0,0,0,10,255, + 0,255,4,0,0,0,1,0,255,0,8,0,0,0,1,128,128,128,1,255, + 0,255,4,0,0,0,1,255,255,255,1,0,255,0,1,255,255,255,1,0, + 255,0,1,0,0,0,1,0,255,0,1,255,255,255,1,0,255,0,1,255, + 255,255,1,0,0,0,1,255,0,255,5,0,0,0,1,0,255,0,1,255, + 255,255,1,0,255,0,1,255,255,255,1,0,255,0,1,255,255,255,1,0, + 255,0,1,255,255,255,1,0,255,0,1,0,0,0,1,255,0,255,4,0, + 0,0,1,0,255,0,1,255,255,255,1,0,0,0,1,0,255,0,1,191, + 191,191,1,0,255,0,1,191,191,191,1,0,255,0,1,191,191,191,1,0, + 255,0,1,191,191,191,1,0,255,0,1,0,0,0,1,255,0,255,4,0, + 0,0,1,0,255,0,8,0,0,0,1,128,128,128,1,255,0,255,4,0, + 0,0,1,0,255,0,1,255,255,255,1,0,0,0,5,255,255,255,1,0, + 255,0,1,0,0,0,1,255,0,255,5,0,0,0,1,255,255,255,1,0, + 255,0,1,255,255,255,1,0,255,0,1,255,255,255,1,0,255,0,1,255, + 255,255,1,0,255,0,1,255,255,255,1,0,0,0,1,255,0,255,4,0, + 0,0,1,255,255,255,1,0,0,0,1,0,255,0,1,191,191,191,1,0, + 255,0,1,191,191,191,1,0,255,0,1,191,191,191,1,0,255,0,1,191, + 191,191,1,0,255,0,1,0,0,0,1,255,0,255,5,0,0,0,1,0, + 255,0,8,0,0,0,1,128,128,128,1,255,0,255,4,0,0,0,1,255, + 255,255,1,0,255,0,1,255,255,255,1,0,255,0,1,0,0,0,1,0, + 255,0,1,255,255,255,1,0,255,0,1,255,255,255,1,0,0,0,1,255, + 0,255,5,0,0,0,1,0,255,0,1,255,255,255,1,0,255,0,1,255, + 255,255,1,0,255,0,1,255,255,255,1,0,255,0,1,255,255,255,1,0, + 255,0,1,0,0,0,1,255,0,255,4,0,0,0,2,0,255,0,1,191, + 191,191,1,0,255,0,1,191,191,191,1,0,255,0,1,191,191,191,1,0, + 255,0,1,191,191,191,1,0,255,0,1,0,0,0,1,255,0,255,6,0, + 0,0,1,0,255,0,8,0,0,0,1,128,128,128,1,255,0,255,4,0, + 0,0,1,0,255,0,1,255,255,255,1,0,255,0,1,255,255,255,1,0, + 0,0,1,255,255,255,1,0,255,0,1,255,255,255,1,0,255,0,1,0, + 0,0,1,255,0,255,6,0,0,0,10,255,0,255,5,0,0,0,10,255, + 0,255,7,0,0,0,1,0,255,0,8,0,0,0,1,128,128,128,1,255, + 0,255,5,0,0,0,10,255,0,255,38,0,0,0,10,128,128,128,1,255, + 0,255,54,128,128,128,10,255,0,255,245,0,0,0,6,255,0,255,26,127, + 127,127,1,0,0,0,4,127,127,127,1,255,0,255,9,127,127,127,1,0, + 0,0,4,127,127,127,1,255,0,255,11,0,0,0,1,255,255,255,4,0, + 0,0,2,255,0,255,9,127,127,127,1,0,0,0,4,127,127,127,1,255, + 0,255,10,0,0,0,1,255,255,255,4,0,0,0,1,255,0,255,9,0, + 0,0,1,255,255,255,4,0,0,0,1,255,0,255,11,0,0,0,1,255, + 255,255,4,0,0,0,1,255,255,255,1,0,0,0,1,255,0,255,8,0, + 0,0,1,255,255,255,4,0,0,0,1,255,0,255,9,0,0,0,10,255, + 0,255,5,0,0,0,1,255,255,255,6,0,0,0,3,255,0,255,8,0, + 0,0,1,255,255,255,4,0,0,0,1,255,255,255,2,0,0,0,1,255, + 0,255,6,0,0,0,10,255,0,255,6,0,0,0,1,255,255,255,9,0, + 0,0,1,255,0,255,4,0,0,0,1,255,255,255,9,0,0,0,1,255, + 0,255,7,0,0,0,1,255,255,255,4,0,0,0,5,255,0,255,5,0, + 0,0,1,255,255,255,9,0,0,0,1,255,0,255,5,0,0,0,1,255, + 255,255,9,0,0,0,1,255,0,255,4,0,0,0,1,255,255,255,9,0, + 0,0,1,255,0,255,7,0,0,0,1,255,255,255,8,0,0,0,1,128, + 128,128,1,255,0,255,4,0,0,0,1,255,255,255,4,0,0,0,1,255, + 255,255,4,0,0,0,1,255,0,255,5,0,0,0,1,255,255,255,9,0, + 0,0,1,255,0,255,4,0,0,0,1,255,255,255,3,0,0,0,10,255, + 0,255,4,0,0,0,1,255,255,255,8,0,0,0,1,128,128,128,1,255, + 0,255,4,0,0,0,1,255,255,255,4,0,0,0,1,255,255,255,4,0, + 0,0,1,255,0,255,5,0,0,0,1,255,255,255,9,0,0,0,1,255, + 0,255,4,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,1,191, + 191,191,1,255,255,255,1,191,191,191,1,255,255,255,1,191,191,191,1,255, + 255,255,1,191,191,191,1,255,255,255,1,0,0,0,1,255,0,255,4,0, + 0,0,1,255,255,255,8,0,0,0,1,128,128,128,1,255,0,255,4,0, + 0,0,1,255,255,255,2,0,0,0,5,255,255,255,2,0,0,0,1,255, + 0,255,5,0,0,0,1,255,255,255,9,0,0,0,1,255,0,255,4,0, + 0,0,1,255,255,255,1,0,0,0,1,255,255,255,1,191,191,191,1,255, + 255,255,1,191,191,191,1,255,255,255,1,191,191,191,1,255,255,255,1,191, + 191,191,1,255,255,255,1,0,0,0,1,255,0,255,5,0,0,0,1,255, + 255,255,8,0,0,0,1,128,128,128,1,255,0,255,4,0,0,0,1,255, + 255,255,4,0,0,0,1,255,255,255,4,0,0,0,1,255,0,255,5,0, + 0,0,1,255,255,255,9,0,0,0,1,255,0,255,4,0,0,0,2,255, + 255,255,1,191,191,191,1,255,255,255,1,191,191,191,1,255,255,255,1,191, + 191,191,1,255,255,255,1,191,191,191,1,255,255,255,1,0,0,0,1,255, + 0,255,6,0,0,0,1,255,255,255,8,0,0,0,1,128,128,128,1,255, + 0,255,4,0,0,0,1,255,255,255,4,0,0,0,1,255,255,255,4,0, + 0,0,1,255,0,255,6,0,0,0,10,255,0,255,5,0,0,0,10,255, + 0,255,7,0,0,0,1,255,255,255,8,0,0,0,1,128,128,128,1,255, + 0,255,5,0,0,0,10,255,0,255,38,0,0,0,10,128,128,128,1,255, + 0,255,54,128,128,128,10,255,0,255,82,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,248,1,0,0,248,1,252,0,248, + 3,248,1,248,1,252,0,248,7,248,1,252,15,254,7,248,15,252,15,252, + 31,254,15,248,31,252,31,252,31,254,15,248,63,252,31,252,31,254,127,248, + 63,252,31,252,31,254,127,248,63,252,31,252,31,254,63,248,63,252,31,252, + 31,254,31,248,63,252,31,248,31,252,15,248,63,248,31,0,0,0,0,248, + 63,0,0,0,0,0,0,240,63,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248, + 1,0,0,248,1,252,0,248,3,248,1,248,1,252,0,248,7,248,1,252, + 15,254,7,248,15,252,15,252,31,254,15,248,31,252,31,252,31,254,15,248, + 63,252,31,252,31,254,127,248,63,252,31,252,31,254,127,248,63,252,31,252, + 31,254,63,248,63,252,31,252,31,254,31,248,63,252,31,248,31,252,15,248, + 63,248,31,0,0,0,0,248,63,0,0,0,0,0,0,240,63,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,248,1,0,0,248,1,252,0,248,3,248,1,248, + 1,252,0,248,7,248,1,252,15,254,7,248,15,252,15,252,31,254,15,248, + 31,252,31,252,31,254,15,248,63,252,31,252,31,254,127,248,63,252,31,252, + 31,254,127,248,63,252,31,252,31,254,63,248,63,252,31,252,31,254,31,248, + 63,252,31,248,31,252,15,248,63,248,31,0,0,0,0,248,63,0,0,0, + 0,0,0,240,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,1,0,0,248, + 1,252,0,248,3,248,1,248,1,252,0,248,7,248,1,252,15,254,7,248, + 15,252,15,252,31,254,15,248,31,252,31,252,31,254,15,248,63,252,31,252, + 31,254,127,248,63,252,31,252,31,254,127,248,63,252,31,252,31,254,63,248, + 63,252,31,252,31,254,31,248,63,252,31,248,31,252,15,248,63,248,31,0, + 0,0,0,248,63,0,0,0,0,0,0,240,63,0,0,0,0,0,0,0, + 0,0,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tfiledialogres,''); +end. diff --git a/mseide-msegui/lib/common/dialogs/msefontformatdialog.mfm b/mseide-msegui/lib/common/dialogs/msefontformatdialog.mfm new file mode 100644 index 0000000..190bba0 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msefontformatdialog.mfm @@ -0,0 +1,232 @@ +object fontformatdialogfo: tfontformatdialogfo + visible = False + bounds_x = 399 + bounds_y = 175 + bounds_cx = 279 + bounds_cy = 160 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 279 + 160 + ) + options = [fo_freeonclose, fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savezorder, fo_savestate] + statfile = tstatfile1 + caption = 'Edit Font Format' + moduleclassname = 'tmseform' + object tlayouter1: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + bounds_x = 80 + bounds_y = 133 + bounds_cx = 192 + bounds_cy = 20 + anchors = [an_left, an_right, an_bottom] + optionsscale = [osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_placex, lao_aligny] + align_glue = wam_start + place_mindist = 8 + place_maxdist = 8 + place_mode = wam_end + linktop = tlayouter2 + dist_top = 4 + options = [spao_gluebottom] + object tbutton2: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + bounds_x = 140 + bounds_y = 0 + bounds_cx = 52 + bounds_cy = 20 + bounds_cxmin = 50 + state = [as_localcaption] + caption = '&Cancel' + font.name = 'stf_default' + font.localprops = [] + modalresult = mr_cancel + reffontheight = 14 + end + object tbutton1: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + taborder = 1 + bounds_x = 82 + bounds_y = 0 + bounds_cx = 50 + bounds_cy = 20 + bounds_cxmin = 50 + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + reffontheight = 14 + end + end + object tlayouter2: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 279 + bounds_cy = 129 + anchors = [an_top, an_bottom] + object tlayouter3: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + taborder = 1 + bounds_x = 156 + bounds_y = 3 + bounds_cx = 84 + bounds_cy = 126 + anchors = [an_left, an_top, an_bottom] + optionsscale = [osc_expandx, osc_shrinkx, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_placey] + place_mindist = 4 + place_maxdist = 4 + object bolded: tbooleanedit + frame.caption = 'B&old' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 30 + 2 + ) + bounds_x = 8 + bounds_y = 0 + bounds_cx = 43 + bounds_cy = 16 + end + object italiced: tbooleanedit + frame.caption = '&Italic' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 32 + 2 + ) + taborder = 1 + bounds_x = 8 + bounds_y = 20 + bounds_cx = 45 + bounds_cy = 16 + end + object underlineed: tbooleanedit + frame.caption = '&Underline' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 63 + 2 + ) + taborder = 2 + bounds_x = 8 + bounds_y = 40 + bounds_cx = 76 + bounds_cy = 16 + end + object strikeouted: tbooleanedit + frame.caption = '&Strikeout' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 60 + 2 + ) + taborder = 3 + bounds_x = 8 + bounds_y = 60 + bounds_cx = 73 + bounds_cy = 16 + end + object blanked: tbooleanedit + frame.caption = 'Bl&ank' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 1 + 37 + 2 + ) + taborder = 4 + bounds_x = 8 + bounds_y = 80 + bounds_cx = 50 + bounds_cy = 16 + end + end + object tlayouter4: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 156 + bounds_cy = 129 + anchors = [an_left, an_top, an_bottom] + optionsscale = [osc_expandx, osc_shrinkx, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_placey] + place_mindist = 4 + place_maxdist = 4 + linkright = tlayouter3 + object backgroundcolored: tcoloredit + frame.caption = '&Backgroundcolor' + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 2 + frame.buttons.items = < + item + end + item + imagenr = 17 + end> + frame.buttonellipse.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 1 + bounds_x = 8 + bounds_y = 41 + bounds_cx = 148 + bounds_cy = 37 + reffontheight = 14 + end + object fontcolored: tcoloredit + frame.caption = '&Fontcolor' + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 2 + frame.buttons.items = < + item + end + item + imagenr = 17 + end> + frame.buttonellipse.imagenr = 17 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + bounds_x = 8 + bounds_y = 0 + bounds_cx = 148 + bounds_cy = 37 + reffontheight = 14 + end + end + end + object tstatfile1: tstatfile + filename = 'fontformatdialog.sta' + options = [sfo_memory, sfo_activatorread, sfo_activatorwrite] + left = 64 + top = 104 + end +end diff --git a/mseide-msegui/lib/common/dialogs/msefontformatdialog.pas b/mseide-msegui/lib/common/dialogs/msefontformatdialog.pas new file mode 100644 index 0000000..40b9205 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msefontformatdialog.pas @@ -0,0 +1,90 @@ +{ MSEgui Copyright (c) 2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msefontformatdialog; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,msewidgets,mseforms, + mserichstring,msesplitter,msesimplewidgets,msestatfile,mseact,msecolordialog, + msedataedits,mseedit,mseificomp,mseificompglob,mseifiglob,msestream,msestrings, + sysutils,msegraphedits,msescrollbar; +type + tfontformatdialogfo = class(tmseform) + tlayouter1: tlayouter; + tbutton2: tbutton; + tbutton1: tbutton; + tlayouter2: tlayouter; + tstatfile1: tstatfile; + tlayouter3: tlayouter; + bolded: tbooleanedit; + italiced: tbooleanedit; + underlineed: tbooleanedit; + strikeouted: tbooleanedit; + blanked: tbooleanedit; + tlayouter4: tlayouter; + backgroundcolored: tcoloredit; + fontcolored: tcoloredit; + end; + +function editfontformat(const avalue: formatinfoarty; + const start,count: int32): formatinfoarty; + +implementation +uses + msefontformatdialog_mfm; + +function editfontformat(const avalue: formatinfoarty; + const start,count: int32): formatinfoarty; +var + style1: charstylety; +begin + result:= copy(avalue); + with tfontformatdialogfo.create(nil) do begin + style1:= getcharstyle(avalue,start); + fontcolored.value:= charstyletocolor(style1.fontcolor); + backgroundcolored.value:= charstyletocolor(style1.colorbackground); + bolded.value:= fs_bold in style1.fontstyle; + italiced.value:= fs_italic in style1.fontstyle; + underlineed.value:= fs_underline in style1.fontstyle; + strikeouted.value:= fs_strikeout in style1.fontstyle; +// selecteded.value:= fs_selected in style1.fontstyle; + blanked.value:= fs_blank in style1.fontstyle; + if show(ml_application) = mr_ok then begin + style1.fontcolor:= colortocharstyle(fontcolored.value); + style1.colorbackground:= colortocharstyle(backgroundcolored.value); + style1.fontstyle:= style1.fontstyle - [fs_bold,fs_italic,fs_underline, + fs_strikeout{,fs_selected},fs_blank]; + if bolded.value then begin + include(style1.fontstyle,fs_bold); + end; + if italiced.value then begin + include(style1.fontstyle,fs_italic); + end; + if underlineed.value then begin + include(style1.fontstyle,fs_underline); + end; + if strikeouted.value then begin + include(style1.fontstyle,fs_strikeout); + end; + { + if selecteded.value then begin + include(style1.fontstyle,fs_selected); + end; + } + if blanked.value then begin + include(style1.fontstyle,fs_blank); + end; + setcharstyle1(result,start,count,style1); + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/dialogs/msefontformatdialog_mfm.pas b/mseide-msegui/lib/common/dialogs/msefontformatdialog_mfm.pas new file mode 100644 index 0000000..953fd65 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msefontformatdialog_mfm.pas @@ -0,0 +1,212 @@ +unit msefontformatdialog_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msefontformatdialog; + +const + objdata: record size: integer; data: array[0..3890] of byte end = + (size: 3891; data: ( + 84,80,70,48,19,116,102,111,110,116,102,111,114,109,97,116,100,105,97,108, + 111,103,102,111,18,102,111,110,116,102,111,114,109,97,116,100,105,97,108,111, + 103,102,111,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95, + 120,3,143,1,8,98,111,117,110,100,115,95,121,3,175,0,9,98,111,117, + 110,100,115,95,99,120,3,23,1,9,98,111,117,110,100,115,95,99,121,3, + 160,0,26,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,0,27,99,111,110,116,97,105,110,101, + 114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 0,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2, + 0,2,0,3,23,1,3,160,0,0,7,111,112,116,105,111,110,115,11,14, + 102,111,95,102,114,101,101,111,110,99,108,111,115,101,13,102,111,95,99,108, + 111,115,101,111,110,101,115,99,15,102,111,95,97,117,116,111,114,101,97,100, + 115,116,97,116,16,102,111,95,97,117,116,111,119,114,105,116,101,115,116,97, + 116,10,102,111,95,115,97,118,101,112,111,115,13,102,111,95,115,97,118,101, + 122,111,114,100,101,114,12,102,111,95,115,97,118,101,115,116,97,116,101,0, + 8,115,116,97,116,102,105,108,101,7,10,116,115,116,97,116,102,105,108,101, + 49,7,99,97,112,116,105,111,110,6,16,69,100,105,116,32,70,111,110,116, + 32,70,111,114,109,97,116,15,109,111,100,117,108,101,99,108,97,115,115,110, + 97,109,101,6,8,116,109,115,101,102,111,114,109,0,9,116,108,97,121,111, + 117,116,101,114,10,116,108,97,121,111,117,116,101,114,49,13,111,112,116,105, + 111,110,115,119,105,100,103,101,116,11,11,111,119,95,116,97,98,102,111,99, + 117,115,17,111,119,95,112,97,114,101,110,116,116,97,98,102,111,99,117,115, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114, + 114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102, + 111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111,99,117,115,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,8,98, + 111,117,110,100,115,95,120,2,80,8,98,111,117,110,100,115,95,121,3,133, + 0,9,98,111,117,110,100,115,95,99,120,3,192,0,9,98,111,117,110,100, + 115,95,99,121,2,20,7,97,110,99,104,111,114,115,11,7,97,110,95,108, + 101,102,116,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116,116, + 111,109,0,12,111,112,116,105,111,110,115,115,99,97,108,101,11,11,111,115, + 99,95,101,120,112,97,110,100,121,11,111,115,99,95,115,104,114,105,110,107, + 121,17,111,115,99,95,101,120,112,97,110,100,115,104,114,105,110,107,120,17, + 111,115,99,95,101,120,112,97,110,100,115,104,114,105,110,107,121,0,13,111, + 112,116,105,111,110,115,108,97,121,111,117,116,11,10,108,97,111,95,112,108, + 97,99,101,120,10,108,97,111,95,97,108,105,103,110,121,0,10,97,108,105, + 103,110,95,103,108,117,101,7,9,119,97,109,95,115,116,97,114,116,13,112, + 108,97,99,101,95,109,105,110,100,105,115,116,2,8,13,112,108,97,99,101, + 95,109,97,120,100,105,115,116,2,8,10,112,108,97,99,101,95,109,111,100, + 101,7,7,119,97,109,95,101,110,100,7,108,105,110,107,116,111,112,7,10, + 116,108,97,121,111,117,116,101,114,50,8,100,105,115,116,95,116,111,112,2, + 4,7,111,112,116,105,111,110,115,11,15,115,112,97,111,95,103,108,117,101, + 98,111,116,116,111,109,0,0,7,116,98,117,116,116,111,110,8,116,98,117, + 116,116,111,110,50,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49, + 11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104, + 116,13,111,119,49,95,97,117,116,111,115,99,97,108,101,13,111,119,49,95, + 97,117,116,111,119,105,100,116,104,0,8,98,111,117,110,100,115,95,120,3, + 140,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,2,52,9,98,111,117,110,100,115,95,99,121,2,20,12,98,111, + 117,110,100,115,95,99,120,109,105,110,2,50,5,115,116,97,116,101,11,15, + 97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,7,99,97,112, + 116,105,111,110,6,7,38,67,97,110,99,101,108,9,102,111,110,116,46,110, + 97,109,101,6,11,115,116,102,95,100,101,102,97,117,108,116,15,102,111,110, + 116,46,108,111,99,97,108,112,114,111,112,115,11,0,11,109,111,100,97,108, + 114,101,115,117,108,116,7,9,109,114,95,99,97,110,99,101,108,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,7,116,98,117,116, + 116,111,110,8,116,98,117,116,116,111,110,49,14,111,112,116,105,111,110,115, + 119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121, + 112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99,97, + 108,101,13,111,119,49,95,97,117,116,111,119,105,100,116,104,0,8,116,97, + 98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,82,8, + 98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120, + 2,50,9,98,111,117,110,100,115,95,99,121,2,20,12,98,111,117,110,100, + 115,95,99,120,109,105,110,2,50,5,115,116,97,116,101,11,10,97,115,95, + 100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,100,101,102,97, + 117,108,116,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0, + 7,99,97,112,116,105,111,110,6,3,38,79,75,11,109,111,100,97,108,114, + 101,115,117,108,116,7,5,109,114,95,111,107,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,14,0,0,0,9,116,108,97,121,111,117,116,101, + 114,10,116,108,97,121,111,117,116,101,114,50,13,111,112,116,105,111,110,115, + 119,105,100,103,101,116,11,11,111,119,95,116,97,98,102,111,99,117,115,17, + 111,119,95,112,97,114,101,110,116,116,97,98,102,111,99,117,115,13,111,119, + 95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119, + 102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117, + 115,111,117,116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,8,116,97,98,111, + 114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,0,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,23, + 1,9,98,111,117,110,100,115,95,99,121,3,129,0,7,97,110,99,104,111, + 114,115,11,6,97,110,95,116,111,112,9,97,110,95,98,111,116,116,111,109, + 0,0,9,116,108,97,121,111,117,116,101,114,10,116,108,97,121,111,117,116, + 101,114,51,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,11,111, + 119,95,116,97,98,102,111,99,117,115,17,111,119,95,112,97,114,101,110,116, + 116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111, + 119,95,97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115, + 117,98,102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105, + 100,103,101,116,115,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111, + 117,110,100,115,95,120,3,156,0,8,98,111,117,110,100,115,95,121,2,3, + 9,98,111,117,110,100,115,95,99,120,2,84,9,98,111,117,110,100,115,95, + 99,121,2,126,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102, + 116,6,97,110,95,116,111,112,9,97,110,95,98,111,116,116,111,109,0,12, + 111,112,116,105,111,110,115,115,99,97,108,101,11,11,111,115,99,95,101,120, + 112,97,110,100,120,11,111,115,99,95,115,104,114,105,110,107,120,17,111,115, + 99,95,101,120,112,97,110,100,115,104,114,105,110,107,120,17,111,115,99,95, + 101,120,112,97,110,100,115,104,114,105,110,107,121,0,13,111,112,116,105,111, + 110,115,108,97,121,111,117,116,11,10,108,97,111,95,112,108,97,99,101,121, + 0,13,112,108,97,99,101,95,109,105,110,100,105,115,116,2,4,13,112,108, + 97,99,101,95,109,97,120,100,105,115,116,2,4,0,12,116,98,111,111,108, + 101,97,110,101,100,105,116,6,98,111,108,100,101,100,13,102,114,97,109,101, + 46,99,97,112,116,105,111,110,6,5,66,38,111,108,100,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101, + 46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,2,30,2,2, + 0,8,98,111,117,110,100,115,95,120,2,8,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,120,2,43,9,98,111,117,110, + 100,115,95,99,121,2,16,0,0,12,116,98,111,111,108,101,97,110,101,100, + 105,116,8,105,116,97,108,105,99,101,100,13,102,114,97,109,101,46,99,97, + 112,116,105,111,110,6,7,38,73,116,97,108,105,99,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,2,32,2,2,0, + 8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120, + 2,8,8,98,111,117,110,100,115,95,121,2,20,9,98,111,117,110,100,115, + 95,99,120,2,45,9,98,111,117,110,100,115,95,99,121,2,16,0,0,12, + 116,98,111,111,108,101,97,110,101,100,105,116,11,117,110,100,101,114,108,105, + 110,101,101,100,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,10, + 38,85,110,100,101,114,108,105,110,101,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101, + 114,102,114,97,109,101,1,2,0,2,1,2,63,2,2,0,8,116,97,98, + 111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,2,8,8,98, + 111,117,110,100,115,95,121,2,40,9,98,111,117,110,100,115,95,99,120,2, + 76,9,98,111,117,110,100,115,95,99,121,2,16,0,0,12,116,98,111,111, + 108,101,97,110,101,100,105,116,11,115,116,114,105,107,101,111,117,116,101,100, + 13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,10,38,83,116,114, + 105,107,101,111,117,116,16,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,1,2,60,2,2,0,8,116,97,98,111,114,100,101, + 114,2,3,8,98,111,117,110,100,115,95,120,2,8,8,98,111,117,110,100, + 115,95,121,2,60,9,98,111,117,110,100,115,95,99,120,2,73,9,98,111, + 117,110,100,115,95,99,121,2,16,0,0,12,116,98,111,111,108,101,97,110, + 101,100,105,116,7,98,108,97,110,107,101,100,13,102,114,97,109,101,46,99, + 97,112,116,105,111,110,6,6,66,108,38,97,110,107,16,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46, + 108,111,99,97,108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,2,37,2,2,0, + 8,116,97,98,111,114,100,101,114,2,4,8,98,111,117,110,100,115,95,120, + 2,8,8,98,111,117,110,100,115,95,121,2,80,9,98,111,117,110,100,115, + 95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,16,0,0,0, + 9,116,108,97,121,111,117,116,101,114,10,116,108,97,121,111,117,116,101,114, + 52,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,11,111,119,95, + 116,97,98,102,111,99,117,115,17,111,119,95,112,97,114,101,110,116,116,97, + 98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115, + 15,111,119,95,97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95, + 97,114,114,111,119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98, + 102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110, + 100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,156,0,9, + 98,111,117,110,100,115,95,99,121,3,129,0,7,97,110,99,104,111,114,115, + 11,7,97,110,95,108,101,102,116,6,97,110,95,116,111,112,9,97,110,95, + 98,111,116,116,111,109,0,12,111,112,116,105,111,110,115,115,99,97,108,101, + 11,11,111,115,99,95,101,120,112,97,110,100,120,11,111,115,99,95,115,104, + 114,105,110,107,120,17,111,115,99,95,101,120,112,97,110,100,115,104,114,105, + 110,107,120,17,111,115,99,95,101,120,112,97,110,100,115,104,114,105,110,107, + 121,0,13,111,112,116,105,111,110,115,108,97,121,111,117,116,11,10,108,97, + 111,95,112,108,97,99,101,121,0,13,112,108,97,99,101,95,109,105,110,100, + 105,115,116,2,4,13,112,108,97,99,101,95,109,97,120,100,105,115,116,2, + 4,9,108,105,110,107,114,105,103,104,116,7,10,116,108,97,121,111,117,116, + 101,114,51,0,10,116,99,111,108,111,114,101,100,105,116,17,98,97,99,107, + 103,114,111,117,110,100,99,111,108,111,114,101,100,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,16,38,66,97,99,107,103,114,111,117,110,100, + 99,111,108,111,114,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,99, + 111,117,110,116,2,2,19,102,114,97,109,101,46,98,117,116,116,111,110,115, + 46,105,116,101,109,115,14,1,0,1,7,105,109,97,103,101,110,114,2,17, + 0,0,27,102,114,97,109,101,46,98,117,116,116,111,110,101,108,108,105,112, + 115,101,46,105,109,97,103,101,110,114,2,17,16,102,114,97,109,101,46,111, + 117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8, + 116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2, + 8,8,98,111,117,110,100,115,95,121,2,41,9,98,111,117,110,100,115,95, + 99,120,3,148,0,9,98,111,117,110,100,115,95,99,121,2,37,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,10,116,99,111,108, + 111,114,101,100,105,116,11,102,111,110,116,99,111,108,111,114,101,100,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,10,38,70,111,110,116,99, + 111,108,111,114,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 49,11,0,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111, + 117,110,116,2,2,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46, + 105,116,101,109,115,14,1,0,1,7,105,109,97,103,101,110,114,2,17,0, + 0,27,102,114,97,109,101,46,98,117,116,116,111,110,101,108,108,105,112,115, + 101,46,105,109,97,103,101,110,114,2,17,16,102,114,97,109,101,46,111,117, + 116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,98, + 111,117,110,100,115,95,120,2,8,8,98,111,117,110,100,115,95,121,2,0, + 9,98,111,117,110,100,115,95,99,120,3,148,0,9,98,111,117,110,100,115, + 95,99,121,2,37,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2, + 14,0,0,0,0,9,116,115,116,97,116,102,105,108,101,10,116,115,116,97, + 116,102,105,108,101,49,8,102,105,108,101,110,97,109,101,6,20,102,111,110, + 116,102,111,114,109,97,116,100,105,97,108,111,103,46,115,116,97,7,111,112, + 116,105,111,110,115,11,10,115,102,111,95,109,101,109,111,114,121,17,115,102, + 111,95,97,99,116,105,118,97,116,111,114,114,101,97,100,18,115,102,111,95, + 97,99,116,105,118,97,116,111,114,119,114,105,116,101,0,4,108,101,102,116, + 2,64,3,116,111,112,2,104,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tfontformatdialogfo,''); +end. diff --git a/mseide-msegui/lib/common/dialogs/mseintegerenter.mfm b/mseide-msegui/lib/common/dialogs/mseintegerenter.mfm new file mode 100644 index 0000000..c3856d6 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/mseintegerenter.mfm @@ -0,0 +1,58 @@ +object integerenterfo: tintegerenterfo + visible = False + bounds_x = 395 + bounds_y = 323 + bounds_cx = 233 + bounds_cy = 88 + bounds_cymin = 75 + container.bounds = ( + 0 + 0 + 233 + 88 + ) + options = [fo_screencentered, fo_closeonesc, fo_localshortcuts, fo_autoreadstat, fo_autowritestat] + moduleclassname = 'tmseform' + object lab: tlabel + optionswidget1 = [ow1_autoheight] + taborder = 3 + bounds_x = 8 + bounds_y = 41 + bounds_cx = 217 + bounds_cy = 14 + anchors = [an_left, an_top, an_right, an_bottom] + caption = 'lab' + textflags = [tf_ycentered, tf_wordbreak] + end + object ok: tbutton + taborder = 1 + bounds_x = 120 + bounds_y = 62 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + end + object cancel: tbutton + taborder = 2 + bounds_x = 176 + bounds_y = 62 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + end + object value: tintegeredit + frame.dummy = 0 + bounds_x = 8 + bounds_y = 62 + anchors = [an_left, an_right, an_bottom] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savevalue, oe1_savestate] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end +end diff --git a/mseide-msegui/lib/common/dialogs/mseintegerenter.pas b/mseide-msegui/lib/common/dialogs/mseintegerenter.pas new file mode 100644 index 0000000..2d93cf4 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/mseintegerenter.pas @@ -0,0 +1,62 @@ +{ MSEgui Copyright (c) 1999-2008 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseintegerenter; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseforms,msedataedits,msesimplewidgets,msetypes,mseglob,mseguiglob,msegui, + msedialog,msestrings; + +type + tintegerenterfo = class(tdialogform) + lab: tlabel; + ok: tbutton; + cancel: tbutton; + value: tintegeredit; + end; + +function integerenter(var avalue: integer; const amin,amax: integer; + const text: msestring = ''; const acaption: msestring = ''): modalresultty; +//threadsave +implementation +uses + mseintegerenter_mfm; + +function integerenter(var avalue: integer; const amin,amax: integer; const text: msestring = ''; + const acaption: msestring = ''): modalresultty; +var + fo: tintegerenterfo; +begin + application.lock; + try + fo:= tintegerenterfo.create(nil); + try + with fo do begin + value.value:= avalue; + value.valuemin:= amin; + value.valuemax:= amax; + caption:= acaption; + lab.caption:= text; + result:= fo.show(true,nil); + if result = mr_ok then begin + avalue:= value.value; + end; + end; + finally + fo.Free; + end; + finally + application.unlock; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/dialogs/mseintegerenter_mfm.pas b/mseide-msegui/lib/common/dialogs/mseintegerenter_mfm.pas new file mode 100644 index 0000000..76c2355 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/mseintegerenter_mfm.pas @@ -0,0 +1,74 @@ +unit mseintegerenter_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,mseintegerenter; + +const + objdata: record size: integer; data: array[0..1139] of byte end = + (size: 1140; data: ( + 84,80,70,48,15,116,105,110,116,101,103,101,114,101,110,116,101,114,102,111, + 14,105,110,116,101,103,101,114,101,110,116,101,114,102,111,7,118,105,115,105, + 98,108,101,8,8,98,111,117,110,100,115,95,120,3,139,1,8,98,111,117, + 110,100,115,95,121,3,67,1,9,98,111,117,110,100,115,95,99,120,3,233, + 0,9,98,111,117,110,100,115,95,99,121,2,88,12,98,111,117,110,100,115, + 95,99,121,109,105,110,2,75,16,99,111,110,116,97,105,110,101,114,46,98, + 111,117,110,100,115,1,2,0,2,0,3,233,0,2,88,0,7,111,112,116, + 105,111,110,115,11,17,102,111,95,115,99,114,101,101,110,99,101,110,116,101, + 114,101,100,13,102,111,95,99,108,111,115,101,111,110,101,115,99,17,102,111, + 95,108,111,99,97,108,115,104,111,114,116,99,117,116,115,15,102,111,95,97, + 117,116,111,114,101,97,100,115,116,97,116,16,102,111,95,97,117,116,111,119, + 114,105,116,101,115,116,97,116,0,15,109,111,100,117,108,101,99,108,97,115, + 115,110,97,109,101,6,8,116,109,115,101,102,111,114,109,0,6,116,108,97, + 98,101,108,3,108,97,98,14,111,112,116,105,111,110,115,119,105,100,103,101, + 116,49,11,14,111,119,49,95,97,117,116,111,104,101,105,103,104,116,0,8, + 116,97,98,111,114,100,101,114,2,3,8,98,111,117,110,100,115,95,120,2, + 8,8,98,111,117,110,100,115,95,121,2,41,9,98,111,117,110,100,115,95, + 99,120,3,217,0,9,98,111,117,110,100,115,95,99,121,2,14,7,97,110, + 99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110,95,116,111, + 112,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109, + 0,7,99,97,112,116,105,111,110,6,3,108,97,98,9,116,101,120,116,102, + 108,97,103,115,11,12,116,102,95,121,99,101,110,116,101,114,101,100,12,116, + 102,95,119,111,114,100,98,114,101,97,107,0,0,0,7,116,98,117,116,116, + 111,110,2,111,107,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117, + 110,100,115,95,120,2,120,8,98,111,117,110,100,115,95,121,2,62,9,98, + 111,117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121, + 2,20,7,97,110,99,104,111,114,115,11,8,97,110,95,114,105,103,104,116, + 9,97,110,95,98,111,116,116,111,109,0,5,115,116,97,116,101,11,10,97, + 115,95,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,100,101, + 102,97,117,108,116,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111, + 110,0,7,99,97,112,116,105,111,110,6,3,38,79,75,11,109,111,100,97, + 108,114,101,115,117,108,116,7,5,109,114,95,111,107,0,0,7,116,98,117, + 116,116,111,110,6,99,97,110,99,101,108,8,116,97,98,111,114,100,101,114, + 2,2,8,98,111,117,110,100,115,95,120,3,176,0,8,98,111,117,110,100, + 115,95,121,2,62,9,98,111,117,110,100,115,95,99,120,2,50,9,98,111, + 117,110,100,115,95,99,121,2,20,7,97,110,99,104,111,114,115,11,8,97, + 110,95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,5,115, + 116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111, + 110,0,7,99,97,112,116,105,111,110,6,7,38,67,97,110,99,101,108,11, + 109,111,100,97,108,114,101,115,117,108,116,7,9,109,114,95,99,97,110,99, + 101,108,0,0,12,116,105,110,116,101,103,101,114,101,100,105,116,5,118,97, + 108,117,101,11,102,114,97,109,101,46,100,117,109,109,121,2,0,8,98,111, + 117,110,100,115,95,120,2,8,8,98,111,117,110,100,115,95,121,2,62,7, + 97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,8,97,110,95, + 114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,12,111,112,116, + 105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112, + 111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99, + 117,116,101,13,111,101,49,95,115,97,118,101,118,97,108,117,101,13,111,101, + 49,95,115,97,118,101,115,116,97,116,101,0,11,111,112,116,105,111,110,115, + 101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101,115,99,13,111, + 101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104,101,99, + 107,109,114,99,97,110,99,101,108,20,111,101,95,114,101,115,101,116,115,101, + 108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110, + 99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114, + 13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117, + 116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107, + 0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tintegerenterfo,''); +end. diff --git a/mseide-msegui/lib/common/dialogs/msememodialog.mfm b/mseide-msegui/lib/common/dialogs/msememodialog.mfm new file mode 100644 index 0000000..7453017 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msememodialog.mfm @@ -0,0 +1,84 @@ +object msememodialogfo: tmsememodialogfo + visible = False + bounds_x = 110 + bounds_y = 237 + bounds_cx = 409 + bounds_cy = 297 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 409 + 297 + ) + options = [fo_screencentered, fo_closeonesc, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savestate] + statfile = tstatfile1 + caption = 'Enter Memo Text' + moduleclassname = 'tmseform' + object memo: tmemoedit + frame.localprops = [frl_colorclient] + frame.localprops1 = [] + frame.sbhorz.pagesize = 1 + frame.sbvert.pagesize = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 409 + bounds_cy = 268 + anchors = [an_top, an_bottom] + optionsedit1 = [oe1_multiline, oe1_autopopupmenu, oe1_keyexecute, oe1_savevalue, oe1_savestate] + optionsedit = [oe_closequery, oe_checkmrcancel, oe_linebreak, oe_shiftreturn, oe_resetselectonexit, oe_nofirstarrownavig, oe_caretonreadonly] + reffontheight = 14 + end + object tlayouter1: tlayouter + optionswidget = [ow_tabfocus, ow_parenttabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets] + taborder = 1 + bounds_x = 72 + bounds_y = 272 + bounds_cx = 330 + bounds_cy = 20 + anchors = [an_left, an_right, an_bottom] + optionsscale = [osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_placex, lao_aligny] + align_glue = wam_start + place_mindist = 8 + place_maxdist = 8 + place_mode = wam_end + linktop = memo + dist_top = 4 + options = [spao_gluebottom] + object tbutton2: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + bounds_x = 278 + bounds_y = 0 + bounds_cx = 52 + bounds_cy = 20 + bounds_cxmin = 50 + state = [as_localcaption] + caption = '&Cancel' + font.name = 'stf_default' + font.localprops = [] + modalresult = mr_cancel + reffontheight = 14 + end + object tbutton1: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + taborder = 1 + bounds_x = 220 + bounds_y = 0 + bounds_cx = 50 + bounds_cy = 20 + bounds_cxmin = 50 + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + reffontheight = 14 + end + end + object tstatfile1: tstatfile + filename = 'memodialog.sta' + options = [sfo_memory, sfo_activatorread, sfo_activatorwrite] + left = 64 + top = 104 + end +end diff --git a/mseide-msegui/lib/common/dialogs/msememodialog.pas b/mseide-msegui/lib/common/dialogs/msememodialog.pas new file mode 100644 index 0000000..723dbe2 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msememodialog.pas @@ -0,0 +1,232 @@ +{ MSEgui Copyright (c) 1999-2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msememodialog; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseglob,mseguiglob,mseapplication,msestat,msemenus,msegui,msegraphics, + msegraphutils,mseevent,mseclasses,mseforms,msedataedits,mseedit,msestrings, + msetypes,msestatfile,msesimplewidgets,msewidgets,msedialog,classes,mclasses, + msedropdownlist,msesplitter; + +type + tmemodialogcontroller = class(tstringdialogcontroller) + protected + function execute(var avalue: msestring): boolean; override; + end; + + tmemodialogedit = class(tcustomdialogstringed) + protected + function createdialogcontroller: tstringdialogcontroller; override; + public + constructor create(aowner: tcomponent); override; + published + property textflags default defaulttextflagsnoycentered; + property textflagsactive default defaulttextflagsactivenoycentered; + end; + + tmsememodialogfo = class(tmseform) + memo: tmemoedit; + tstatfile1: tstatfile; + tlayouter1: tlayouter; + tbutton2: tbutton; + tbutton1: tbutton; + public + constructor create(const aowner: tcomponent; const readonly: boolean); + reintroduce; + end; + + tdialogdropdownbuttonframe = class(tdropdownmultibuttonframe) + private + function getbuttondialog: tdropdownbutton; + procedure setbuttondialog(const avalue: tdropdownbutton); + public + constructor create(const aintf: icaptionframe; + const buttonintf: ibutton); override; + published + property buttondialog: tdropdownbutton read getbuttondialog + write setbuttondialog; + end; + + tdialoghistorycontroller = class(thistorycontroller) + protected + function getbuttonframeclass: dropdownbuttonframeclassty; override; + end; + + tmemodialoghistoryedit = class(thistoryedit,ibutton) + private +// function getframe: tellipsebuttonframe; +// procedure setframe(const avalue: tellipsebuttonframe); + protected + function createdropdowncontroller: tcustomdropdowncontroller; override; +// procedure internalcreateframe; override; +// procedure dokeydown(var info: keyeventinfoty); override; +// procedure mouseevent(var info: mouseeventinfoty); override; +// procedure updatereadonlystate; override; + //ibutton + procedure buttonaction(var action: buttonactionty; + const buttonindex: integer); override; + + procedure internalexecute; + function execute(var avalue: msestring): boolean; virtual; + procedure setexecresult(var avalue: msestring); virtual; +// function iskeyexecute(const info: keyeventinfoty): boolean; virtual; + public + constructor create(aowner: tcomponent); override; +// property frame: tellipsebuttonframe read getframe write setframe; + end; + +function memodialog(var avalue: msestring; const readonly: boolean): modalresultty; + +implementation +uses + msememodialog_mfm,mseeditglob,msekeyboard,msestockobjects; + +function memodialog(var avalue: msestring; const readonly: boolean): modalresultty; +var + dia1: tmsememodialogfo; +begin + dia1:= tmsememodialogfo.create(nil,readonly); + try + dia1.memo.value:= avalue; + result:= dia1.show(true); + if result = mr_ok then begin + avalue:= dia1.memo.value; + end; + finally + dia1.free; + end; +end; + +{ tmemodialogcontroller } + +function tmemodialogcontroller.execute(var avalue: msestring): boolean; +begin + result:= memodialog(avalue,not fowner.editor.canedit) = mr_ok; +end; + +{ tmemodialogedit } + +constructor tmemodialogedit.create(aowner: tcomponent); +begin + inherited; + ftextflags:= defaulttextflagsnoycentered; + ftextflagsactive:= defaulttextflagsactivenoycentered; + updatetextflags(); +end; + +function tmemodialogedit.createdialogcontroller: tstringdialogcontroller; +begin + result:= tmemodialogcontroller.create(self); +end; + + +{ +function tmemodialogedit.execute(var avalue: msestring): boolean; +begin + result:= memodialog(avalue) = mr_ok; +end; +} +{ tmemodialoghistoryedit } + +constructor tmemodialoghistoryedit.create(aowner: tcomponent); +begin + inherited; +// internalcreateframe; +end; + +procedure tmemodialoghistoryedit.buttonaction(var action: buttonactionty; + const buttonindex: integer); +begin + if buttonindex = 1 then begin + if action = ba_click then begin + if canfocus and not setfocus then begin + exit; + end; + internalexecute; + end; + end + else begin + inherited; + end; +end; +{ +procedure tmemodialoghistoryedit.internalcreateframe; +begin + tellipsebuttonframe.create(iscrollframe(self),ibutton(self)); + updatereadonlystate; +end; +} +function tmemodialoghistoryedit.execute(var avalue: msestring): boolean; +begin + result:= memodialog(avalue,readonly) = mr_ok; +end; + +procedure tmemodialoghistoryedit.setexecresult(var avalue: msestring); +begin + text:= avalue; +end; + +procedure tmemodialoghistoryedit.internalexecute; +var + str1: msestring; +begin + str1:= text; + if execute(str1) then begin + setexecresult(str1); + checkvalue; + end; +end; + +function tmemodialoghistoryedit.createdropdowncontroller: tcustomdropdowncontroller; +begin + result:= tdialoghistorycontroller.create(idropdownlist(self)); +end; + +{ tdialoghistorycontroller } + +function tdialoghistorycontroller.getbuttonframeclass: dropdownbuttonframeclassty; +begin + result:= tdialogdropdownbuttonframe; +end; + +{ tdialogdropdownbuttonframe } + +constructor tdialogdropdownbuttonframe.create(const aintf: icaptionframe; + const buttonintf: ibutton); +begin + inherited; + buttons.count:= 2; + buttons[1].imagenr:= ord(stg_ellipsesmall); +end; + +function tdialogdropdownbuttonframe.getbuttondialog: tdropdownbutton; +begin + result:= tdropdownbutton(buttons[1]); +end; + +procedure tdialogdropdownbuttonframe.setbuttondialog(const avalue: tdropdownbutton); +begin + tdropdownbutton(buttons[1]).assign(avalue); +end; + +{ tmsememodialogfo } + +constructor tmsememodialogfo.create(const aowner: tcomponent; + const readonly: boolean); +begin + inherited create(aowner); + if readonly then begin + caption:= 'Memo text'; + end; + memo.readonly:= readonly; +end; + +end. diff --git a/mseide-msegui/lib/common/dialogs/msememodialog_mfm.pas b/mseide-msegui/lib/common/dialogs/msememodialog_mfm.pas new file mode 100644 index 0000000..06d1a08 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msememodialog_mfm.pas @@ -0,0 +1,113 @@ +unit msememodialog_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msememodialog; + +const + objdata: record size: integer; data: array[0..1912] of byte end = + (size: 1913; data: ( + 84,80,70,48,16,116,109,115,101,109,101,109,111,100,105,97,108,111,103,102, + 111,15,109,115,101,109,101,109,111,100,105,97,108,111,103,102,111,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,110,8,98,111, + 117,110,100,115,95,121,3,237,0,9,98,111,117,110,100,115,95,99,120,3, + 153,1,9,98,111,117,110,100,115,95,99,121,3,41,1,26,99,111,110,116, + 97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,0,27,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,99,111,110,116,97, + 105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0,3,153,1,3, + 41,1,0,7,111,112,116,105,111,110,115,11,17,102,111,95,115,99,114,101, + 101,110,99,101,110,116,101,114,101,100,13,102,111,95,99,108,111,115,101,111, + 110,101,115,99,15,102,111,95,97,117,116,111,114,101,97,100,115,116,97,116, + 16,102,111,95,97,117,116,111,119,114,105,116,101,115,116,97,116,10,102,111, + 95,115,97,118,101,112,111,115,12,102,111,95,115,97,118,101,115,116,97,116, + 101,0,8,115,116,97,116,102,105,108,101,7,10,116,115,116,97,116,102,105, + 108,101,49,7,99,97,112,116,105,111,110,6,15,69,110,116,101,114,32,77, + 101,109,111,32,84,101,120,116,15,109,111,100,117,108,101,99,108,97,115,115, + 110,97,109,101,6,8,116,109,115,101,102,111,114,109,0,9,116,109,101,109, + 111,101,100,105,116,4,109,101,109,111,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,21,102,114,97,109,101,46,115,98,104,111,114,122,46,112, + 97,103,101,115,105,122,101,2,1,21,102,114,97,109,101,46,115,98,118,101, + 114,116,46,112,97,103,101,115,105,122,101,2,1,8,98,111,117,110,100,115, + 95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,120,3,153,1,9,98,111,117,110,100,115,95,99,121,3,12, + 1,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,9,97,110, + 95,98,111,116,116,111,109,0,12,111,112,116,105,111,110,115,101,100,105,116, + 49,11,13,111,101,49,95,109,117,108,116,105,108,105,110,101,17,111,101,49, + 95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95,107, + 101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,118,97, + 108,117,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0,11,111, + 112,116,105,111,110,115,101,100,105,116,11,13,111,101,95,99,108,111,115,101, + 113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99, + 101,108,12,111,101,95,108,105,110,101,98,114,101,97,107,14,111,101,95,115, + 104,105,102,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115, + 101,108,101,99,116,111,110,101,120,105,116,20,111,101,95,110,111,102,105,114, + 115,116,97,114,114,111,119,110,97,118,105,103,18,111,101,95,99,97,114,101, + 116,111,110,114,101,97,100,111,110,108,121,0,13,114,101,102,102,111,110,116, + 104,101,105,103,104,116,2,14,0,0,9,116,108,97,121,111,117,116,101,114, + 10,116,108,97,121,111,117,116,101,114,49,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,11,111,119,95,116,97,98,102,111,99,117,115,17,111, + 119,95,112,97,114,101,110,116,116,97,98,102,111,99,117,115,13,111,119,95, + 97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102, + 111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115, + 111,117,116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95,100, + 101,115,116,114,111,121,119,105,100,103,101,116,115,0,8,116,97,98,111,114, + 100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,72,8,98,111,117, + 110,100,115,95,121,3,16,1,9,98,111,117,110,100,115,95,99,120,3,74, + 1,9,98,111,117,110,100,115,95,99,121,2,20,7,97,110,99,104,111,114, + 115,11,7,97,110,95,108,101,102,116,8,97,110,95,114,105,103,104,116,9, + 97,110,95,98,111,116,116,111,109,0,12,111,112,116,105,111,110,115,115,99, + 97,108,101,11,11,111,115,99,95,101,120,112,97,110,100,121,11,111,115,99, + 95,115,104,114,105,110,107,121,17,111,115,99,95,101,120,112,97,110,100,115, + 104,114,105,110,107,120,17,111,115,99,95,101,120,112,97,110,100,115,104,114, + 105,110,107,121,0,13,111,112,116,105,111,110,115,108,97,121,111,117,116,11, + 10,108,97,111,95,112,108,97,99,101,120,10,108,97,111,95,97,108,105,103, + 110,121,0,10,97,108,105,103,110,95,103,108,117,101,7,9,119,97,109,95, + 115,116,97,114,116,13,112,108,97,99,101,95,109,105,110,100,105,115,116,2, + 8,13,112,108,97,99,101,95,109,97,120,100,105,115,116,2,8,10,112,108, + 97,99,101,95,109,111,100,101,7,7,119,97,109,95,101,110,100,7,108,105, + 110,107,116,111,112,7,4,109,101,109,111,8,100,105,115,116,95,116,111,112, + 2,4,7,111,112,116,105,111,110,115,11,15,115,112,97,111,95,103,108,117, + 101,98,111,116,116,111,109,0,0,7,116,98,117,116,116,111,110,8,116,98, + 117,116,116,111,110,50,14,111,112,116,105,111,110,115,119,105,100,103,101,116, + 49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103, + 104,116,13,111,119,49,95,97,117,116,111,115,99,97,108,101,13,111,119,49, + 95,97,117,116,111,119,105,100,116,104,0,8,98,111,117,110,100,115,95,120, + 3,22,1,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100, + 115,95,99,120,2,52,9,98,111,117,110,100,115,95,99,121,2,20,12,98, + 111,117,110,100,115,95,99,120,109,105,110,2,50,5,115,116,97,116,101,11, + 15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,7,99,97, + 112,116,105,111,110,6,7,38,67,97,110,99,101,108,9,102,111,110,116,46, + 110,97,109,101,6,11,115,116,102,95,100,101,102,97,117,108,116,15,102,111, + 110,116,46,108,111,99,97,108,112,114,111,112,115,11,0,11,109,111,100,97, + 108,114,101,115,117,108,116,7,9,109,114,95,99,97,110,99,101,108,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,7,116,98,117, + 116,116,111,110,8,116,98,117,116,116,111,110,49,14,111,112,116,105,111,110, + 115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108, + 121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111,115,99, + 97,108,101,13,111,119,49,95,97,117,116,111,119,105,100,116,104,0,8,116, + 97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,3,220, + 0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,20,12,98,111,117, + 110,100,115,95,99,120,109,105,110,2,50,5,115,116,97,116,101,11,10,97, + 115,95,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,100,101, + 102,97,117,108,116,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111, + 110,0,7,99,97,112,116,105,111,110,6,3,38,79,75,11,109,111,100,97, + 108,114,101,115,117,108,116,7,5,109,114,95,111,107,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,14,0,0,0,9,116,115,116,97,116,102, + 105,108,101,10,116,115,116,97,116,102,105,108,101,49,8,102,105,108,101,110, + 97,109,101,6,14,109,101,109,111,100,105,97,108,111,103,46,115,116,97,7, + 111,112,116,105,111,110,115,11,10,115,102,111,95,109,101,109,111,114,121,17, + 115,102,111,95,97,99,116,105,118,97,116,111,114,114,101,97,100,18,115,102, + 111,95,97,99,116,105,118,97,116,111,114,119,114,105,116,101,0,4,108,101, + 102,116,2,64,3,116,111,112,2,104,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tmsememodialogfo,''); +end. diff --git a/mseide-msegui/lib/common/dialogs/msepopupcalendar.mfm b/mseide-msegui/lib/common/dialogs/msepopupcalendar.mfm new file mode 100644 index 0000000..7ede7c1 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msepopupcalendar.mfm @@ -0,0 +1,213 @@ +object msepopupcalendarfo: tpopupcalendarfo + optionswidget = [ow_arrowfocus, ow_subfocus, ow_destroywidgets, ow_hinton] + frame.framewidth = 1 + frame.colorframe = -1610612734 + frame.localprops = [frl_framewidth, frl_colorframe] + frame.dummy = 0 + visible = False + bounds_x = 341 + bounds_y = 304 + bounds_cx = 233 + bounds_cy = 179 + anchors = [an_left, an_top, an_bottom] + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.frame.localprops = [frl_framewidth] + container.frame.sbhorz.options = [sbo_thumbtrack, sbo_moveauto] + container.frame.sbvert.options = [sbo_thumbtrack, sbo_moveauto] + container.bounds = ( + 1 + 1 + 231 + 177 + ) + optionswindow = [wo_popup, wo_buttonendmodal] + options = [fo_freeonclose, fo_closeonesc, fo_localshortcuts, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savestate] + oncreate = formoncreate + moduleclassname = 'tmseform' + object grid: tdrawgrid + optionswidget1 = [ow1_fontglyphheight] + frame.levelo = 0 + frame.framewidth = 1 + frame.colorframe = -1610612733 + frame.sbvert.options = [sbo_thumbtrack] + frame.sbhorz.options = [sbo_thumbtrack] + frame.localprops = [frl_levelo, frl_leveli, frl_framewidth, frl_colorframe, frl_fileft, frl_fitop, frl_firight, frl_fibottom] + taborder = 6 + bounds_x = 0 + bounds_y = 22 + bounds_cx = 233 + bounds_cy = 156 + anchors = [an_left, an_top, an_right] + datacols.count = 7 + datacols.coloractive = -1879048185 + datacols.width = 32 + datacols.options = [co_readonly, co_drawfocus, co_savevalue, co_savestate] + datacols.options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcolorfocused, co1_rowreadonly] + datacols.items = < + item + coloractive = -1879048185 + width = 32 + options = [co_readonly, co_drawfocus, co_savevalue, co_savestate] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcolorfocused, co1_rowreadonly] + focusrectdist = 1 + ondrawcell = drawcell + end + item + coloractive = -1879048185 + width = 32 + options = [co_readonly, co_drawfocus, co_savevalue, co_savestate] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcolorfocused, co1_rowreadonly] + focusrectdist = 1 + ondrawcell = drawcell + end + item + coloractive = -1879048185 + width = 32 + options = [co_readonly, co_drawfocus, co_savevalue, co_savestate] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcolorfocused, co1_rowreadonly] + focusrectdist = 1 + ondrawcell = drawcell + end + item + coloractive = -1879048185 + width = 32 + options = [co_readonly, co_drawfocus, co_savevalue, co_savestate] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcolorfocused, co1_rowreadonly] + focusrectdist = 1 + ondrawcell = drawcell + end + item + coloractive = -1879048185 + width = 32 + options = [co_readonly, co_drawfocus, co_savevalue, co_savestate] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcolorfocused, co1_rowreadonly] + focusrectdist = 1 + ondrawcell = drawcell + end + item + coloractive = -1879048185 + width = 32 + options = [co_readonly, co_drawfocus, co_savevalue, co_savestate] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcolorfocused, co1_rowreadonly] + focusrectdist = 1 + ondrawcell = drawcell + end + item + linewidth = 0 + coloractive = -1879048185 + width = 32 + options = [co_readonly, co_drawfocus, co_savevalue, co_savestate] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcolorfocused, co1_rowreadonly] + focusrectdist = 1 + ondrawcell = drawcell + end> + fixrows.count = 1 + fixrows.items = < + item + height = 21 + captions.count = 7 + captions.items = < + item + options = [] + end + item + options = [] + end + item + options = [] + end + item + options = [] + end + item + options = [] + end + item + options = [] + end + item + options = [] + end> + end> + rowcount = 6 + gridframecolor = -2147483645 + datarowheight = 21 + oncellevent = cellevent + reffontheight = 14 + end + object monthdisp: tdatetimedisp + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousewheel, ow_destroywidgets] + color = -1879048186 + taborder = 5 + bounds_x = 83 + bounds_y = 0 + bounds_cx = 137 + bounds_cy = 22 + textflags = [tf_xcentered, tf_right, tf_ycentered] + format = 'mmmm' + value = -Inf + reffontheight = 14 + end + object yeardisp: tdatetimedisp + optionswidget1 = [ow1_fontglyphheight] + optionswidget = [ow_mousewheel, ow_destroywidgets] + color = -1879048186 + taborder = 4 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 72 + bounds_cy = 22 + textflags = [tf_xcentered, tf_right, tf_ycentered] + format = 'yyyy' + value = -Inf + reffontheight = 14 + end + object tstockglyphbutton1: tstockglyphbutton + optionswidget = [ow_mousewheel, ow_destroywidgets] + taborder = 3 + bounds_x = 220 + bounds_y = 0 + bounds_cx = 11 + bounds_cy = 11 + state = [as_localimagelist, as_localimagenr, as_localonexecute] + glyph = stg_arrowupsmall + options = [bo_executeonclick, bo_executeonkey, bo_executeonshortcut, bo_executedefaultonenterkey, bo_nocandefocus] + onexecute = moup + end + object tstockglyphbutton2: tstockglyphbutton + optionswidget = [ow_mousewheel, ow_destroywidgets] + taborder = 1 + bounds_x = 220 + bounds_y = 11 + bounds_cx = 11 + bounds_cy = 11 + state = [as_localimagelist, as_localimagenr, as_localonexecute] + glyph = stg_arrowdownsmall + options = [bo_executeonclick, bo_executeonkey, bo_executeonshortcut, bo_executedefaultonenterkey, bo_nocandefocus] + onexecute = modown + end + object buup: tstockglyphbutton + optionswidget = [ow_mousewheel, ow_destroywidgets] + taborder = 2 + bounds_x = 72 + bounds_y = 0 + bounds_cx = 11 + bounds_cy = 11 + state = [as_localimagelist, as_localimagenr, as_localonexecute] + glyph = stg_arrowupsmall + options = [bo_executeonclick, bo_executeonkey, bo_executeonshortcut, bo_executedefaultonenterkey, bo_nocandefocus] + onexecute = yearup + end + object budo: tstockglyphbutton + optionswidget = [ow_mousewheel, ow_destroywidgets] + bounds_x = 72 + bounds_y = 11 + bounds_cx = 11 + bounds_cy = 11 + state = [as_localimagelist, as_localimagenr, as_localonexecute] + glyph = stg_arrowdownsmall + options = [bo_executeonclick, bo_executeonkey, bo_executeonshortcut, bo_executedefaultonenterkey, bo_nocandefocus] + onexecute = yeardown + end +end diff --git a/mseide-msegui/lib/common/dialogs/msepopupcalendar.pas b/mseide-msegui/lib/common/dialogs/msepopupcalendar.pas new file mode 100644 index 0000000..dfb1296 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msepopupcalendar.pas @@ -0,0 +1,417 @@ +{ MSEgui Copyright (c) 1999-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msepopupcalendar; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +{$ifndef FPC}{$ifdef linux} {$define UNIX} {$endif}{$endif} +interface +uses + msegui,mseclasses,mseforms,msegraphutils,msegrids,msedispwidgets,classes, + mclasses, + msegraphics,mseeditglob,msetypes,msedropdownlist,msetimer,msesimplewidgets, + mseinplaceedit,mseevent,mseguiglob,msegridsglob,msestrings; + +const + popupcalendarwidth = 233; + +type + idropdowncalendar = interface(idropdownwidget) + end; + + tcalendarcontroller = class(tdropdownwidgetcontroller) + private + ffirstdayofweek: dayofweekty; + freddayofweek: dayofweekty; + protected + procedure dropdownkeydown(var info: keyeventinfoty); + public + constructor create(const intf: idropdowncalendar); + procedure editnotification(var info: editnotificationinfoty); override; + published + property bounds_cx default popupcalendarwidth; + property firstdayofweek: dayofweekty read ffirstdayofweek + write ffirstdayofweek default dw_mon; + property reddayofweek: dayofweekty read freddayofweek + write freddayofweek default dw_sun; + end; + + tpopupcalendarfo = class(tmseform) + grid: tdrawgrid; + monthdisp: tdatetimedisp; + tstockglyphbutton1: tstockglyphbutton; + tstockglyphbutton2: tstockglyphbutton; + buup: tstockglyphbutton; + budo: tstockglyphbutton; + yeardisp: tdatetimedisp; + procedure formoncreate(const sender: TObject); + procedure drawcell(const sender: tcol; const canvas: tcanvas; + var cellinfo: cellinfoty); + procedure cellevent(const sender: TObject; var info: celleventinfoty); + procedure moup(const sender: TObject); + procedure modown(const sender: TObject); + procedure yearup(const sender: TObject); + procedure yeardown(const sender: TObject); + private + fvalue: tdatetime; + ffirstdate: tdatetime; + ffirstcol,flastcol,flastrow: integer; + fvalueupdating: integer; + fcontroller: tcalendarcontroller; + fformatedit: msestring; + procedure setvalue(const avalue: tdatetime); + function isinvalidcell(const acell: gridcoordty): boolean; + protected + fdayofweekoffset: integer; +// freddayofweeknum: integer; +// procedure mousewheelevent(var info: mousewheeleventinfoty); override; + procedure dokeydown(var info: keyeventinfoty); override; + procedure doactivate; override; + procedure dodeactivate; override; + procedure mousewheelevent(var info: mousewheeleventinfoty); override; + public + constructor create(const aowner: tcomponent; + const acontroller: tcalendarcontroller); reintroduce; + property value: tdatetime read fvalue write setvalue; + property formatedit: msestring read fformatedit write fformatedit; + end; + +implementation +uses + mseformatstr,msepopupcalendar_mfm,sysutils,msesys, + {$ifndef UNIX} + dateutils, + {$else} + {$ifdef FPC}dateutils,{$endif} + {$endif} //kylix compatibility + msedrawtext, + msekeyboard; + + {$ifdef UNIX} + {$ifndef FPC} //kylix compatibility + //copied from dateutil.inc + +Function DayOf(const AValue: TDateTime): Word; + +Var + Y,M : Word; + +begin + DecodeDate(AValue,Y,M,Result); +end; + +Function DaysBetween(const ANow, AThen: TDateTime): Integer; +begin + Result:=Trunc(Abs(ANow-AThen)); +end; + +Function DaysInMonth(const AValue: TDateTime): Word; + +Var + Y,M,D : Word; + +begin + Decodedate(AValue,Y,M,D); + Result:=MonthDays[IsLeapYear(Y),M]; +end; + +Function IncDay(const AValue: TDateTime; const ANumberOfDays: Integer): TDateTime; +begin + Result:=AValue+ANumberOfDays; //1899 step? +end; + {$endif} +{$endif} + +{ tcalendarcontroller } + +constructor tcalendarcontroller.create(const intf: idropdowncalendar); +begin + ffirstdayofweek:= dw_mon; + freddayofweek:= dw_sun; + inherited create(intf); + include(fstate,dcs_forcecaret); +// fforcecaret:= true; + bounds_cx:= popupcalendarwidth; +end; + +procedure tcalendarcontroller.editnotification(var info: editnotificationinfoty); +var + dt1: tdatetime; +begin + inherited; + if fdropdownwidget <> nil then begin + case info.action of + ea_textedited: begin + if trystringtodate(fintf.geteditor.text,dt1) then begin + tpopupcalendarfo(fdropdownwidget).value:= dt1; + end; + end + end; + end; +end; + +procedure tcalendarcontroller.dropdownkeydown(var info: keyeventinfoty); +var + editor1: tinplaceedit; +begin + editor1:= fintf.geteditor; + editor1.dokeydown(info); +end; + +{ tpopupcalendarfo } + +constructor tpopupcalendarfo.create(const aowner: tcomponent; + const acontroller: tcalendarcontroller); +begin + fcontroller:= acontroller; + fdayofweekoffset:= ord(fcontroller.ffirstdayofweek)+1; +// freddayofweeknum:= ord(fcontroller.freddayofweek)+1; + inherited create(aowner); +end; + +procedure tpopupcalendarfo.formoncreate(const sender: TObject); +var + int1,int2: integer; +begin + with grid.fixrows[-1] do begin + int2:= ord(fcontroller.ffirstdayofweek); + for int1:= 0 to 6 do begin + captions[int1].caption:= + defaultformatsettingsmse.shortdaynames[((int1+int2) mod 7)+1]; + end; + { + for int1:= 2 to 7 do begin + captions[int1-2].caption:= defaultformatsettingsmse.shortdaynames[int1]; + end; + captions[6].caption:= defaultformatsettingsmse.shortdaynames[1]; + } + end; + int2:= ord(fcontroller.freddayofweek) - int2; + if int2 < 0 then begin + int2:= int2 + 7; + end; + with grid.datacols[int2] do begin +// with grid.datacols[(7-int2) mod 7] do begin + createfont; + font.color:= cl_red; + end; + value:= fvalue; +end; + +procedure tpopupcalendarfo.setvalue(const avalue: tdatetime); +var + year,month,day: word; + int1: integer; + dat1: tdatetime; +begin + if fvalueupdating = 0 then begin + inc(fvalueupdating); + fvalue:= avalue; + if yeardisp <> nil then begin + yeardisp.value:= avalue; + end; + if monthdisp <> nil then begin + monthdisp.value:= avalue; + end; + decodedate(avalue,year,month,day); + dat1:= encodedate(year,month,1); + int1:= fdayofweekoffset-dayofweek(dat1); + if int1 > 0 then begin + int1:= int1 - 7; + end; + ffirstdate:= incday(dat1,int1); + ffirstcol:= - int1; + flastcol:= dayofweek(encodedate(year,month,daysinmonth(avalue))- + fdayofweekoffset) mod 7; + flastrow:= (ffirstcol + daysinmonth(avalue) - 1) div 7; + int1:= daysbetween(ffirstdate,avalue); + grid.focuscell(makegridcoord(int1 mod 7,int1 div 7)); + dec(fvalueupdating); + invalidate; + end; +end; + +function tpopupcalendarfo.isinvalidcell(const acell: gridcoordty): boolean; +begin + result:= (acell.row = 0) and (acell.col < ffirstcol) or + (acell.row > flastrow) or + (acell.row >= flastrow) and (acell.col > flastcol); +end; + +procedure tpopupcalendarfo.drawcell(const sender: tcol; const canvas: tcanvas; + var cellinfo: cellinfoty); +var + flags1: textflagsty; +begin + with cellinfo do begin + if isinvalidcell(cell) then begin + flags1:= [tf_xcentered,tf_ycentered,tf_grayed]; + end + else begin + flags1:= [tf_xcentered,tf_ycentered]; + end; + drawtext(canvas, + msestring(inttostr(dayof(incday(ffirstdate,cell.row*7+cell.col)))), + rect,flags1); + end; +end; + +procedure tpopupcalendarfo.cellevent(const sender: TObject; + var info: celleventinfoty); + procedure setcellvalue; + begin + if (fvalueupdating = 0) then begin + with grid.focusedcell do begin + value:= incday(ffirstdate,row*7+col); + end; + end; + end; + +begin + if (fcontroller <> nil) and iscellclick(info,[ccr_buttonpress]) then begin + setcellvalue; + options:= options - [fo_freeonclose]; + hide; //do not show error messages above the popup window + if fcontroller.setdropdowntext( + mseformatstr.datetimetostring(fvalue,fformatedit), + true,false,key_none) then begin +// release; + end; + release; + end + else begin + with info do begin + case eventkind of + cek_enter: begin + setcellvalue; + end; + cek_keydown: begin + with keyeventinfopo^ do begin + include(eventstate,es_processed); + case key of + key_pagedown{,key_wheeldown}: begin + if shiftstate = [ss_ctrl] then begin + yearup(nil); + end + else begin + moup(nil); + end; + end; + key_pageup{,key_wheelup}: begin + if shiftstate = [ss_ctrl] then begin + yeardown(nil); + end + else begin + modown(nil); + end; + end; + key_up: begin + if cell.row = 0 then begin + value:= incday(fvalue,-7); + end + else begin + exclude(eventstate,es_processed); + end; + end; + key_down: begin + if cell.row = 5 then begin + value:= incday(fvalue,7); + end + else begin + exclude(eventstate,es_processed); + end; + end; + else begin + exclude(eventstate,es_processed); + end; + end; + end; + end; + end; + end; + end; +end; + +procedure tpopupcalendarfo.mousewheelevent(var info: mousewheeleventinfoty); + function bigstep: boolean; + begin + with info do begin + result:= (shiftstate = [ss_ctrl]) or + pointinrect(pos,yeardisp.widgetrect) or + pointinrect(pos,buup.widgetrect) or + pointinrect(pos,budo.widgetrect); + end; + end; + +begin + with info do begin + if not (es_processed in eventstate) then begin + include(eventstate,es_processed); + case wheel of + mw_up: begin + if bigstep then begin + yearup(nil); + end + else begin + moup(nil); + end; + end; + mw_down: begin + if bigstep then begin + yeardown(nil); + end + else begin + modown(nil); + end; + end; + end; + end; + end; +end; + +procedure tpopupcalendarfo.moup(const sender: TObject); +begin + value:= incmonth(fvalue,1); +end; + +procedure tpopupcalendarfo.modown(const sender: TObject); +begin + value:= incmonth(fvalue,-1); +end; + +procedure tpopupcalendarfo.yearup(const sender: TObject); +begin + value:= incmonth(fvalue,12); +end; + +procedure tpopupcalendarfo.yeardown(const sender: TObject); +begin + value:= incmonth(fvalue,-12); +end; + +procedure tpopupcalendarfo.dokeydown(var info: keyeventinfoty); +begin + inherited; + if not (es_processed in info.eventstate) then begin + fcontroller.dropdownkeydown(info); + end; +end; + +procedure tpopupcalendarfo.doactivate; +begin + inherited; + fcontroller.dropdownactivated; +end; + +procedure tpopupcalendarfo.dodeactivate; +begin + inherited; + fcontroller.dropdowndeactivated; +end; + +end. diff --git a/mseide-msegui/lib/common/dialogs/msepopupcalendar_mfm.pas b/mseide-msegui/lib/common/dialogs/msepopupcalendar_mfm.pas new file mode 100644 index 0000000..d2c7f4b --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msepopupcalendar_mfm.pas @@ -0,0 +1,274 @@ +unit msepopupcalendar_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msepopupcalendar; + +const + objdata: record size: integer; data: array[0..5139] of byte end = + (size: 5140; data: ( + 84,80,70,48,16,116,112,111,112,117,112,99,97,108,101,110,100,97,114,102, + 111,18,109,115,101,112,111,112,117,112,99,97,108,101,110,100,97,114,102,111, + 13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,97, + 114,114,111,119,102,111,99,117,115,11,111,119,95,115,117,98,102,111,99,117, + 115,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,9, + 111,119,95,104,105,110,116,111,110,0,16,102,114,97,109,101,46,102,114,97, + 109,101,119,105,100,116,104,2,1,16,102,114,97,109,101,46,99,111,108,111, + 114,102,114,97,109,101,4,2,0,0,160,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,14,102,114,108,95,102,114,97,109,101,119, + 105,100,116,104,14,102,114,108,95,99,111,108,111,114,102,114,97,109,101,0, + 11,102,114,97,109,101,46,100,117,109,109,121,2,0,7,118,105,115,105,98, + 108,101,8,8,98,111,117,110,100,115,95,120,3,85,1,8,98,111,117,110, + 100,115,95,121,3,48,1,9,98,111,117,110,100,115,95,99,120,3,233,0, + 9,98,111,117,110,100,115,95,99,121,3,179,0,7,97,110,99,104,111,114, + 115,11,7,97,110,95,108,101,102,116,6,97,110,95,116,111,112,9,97,110, + 95,98,111,116,116,111,109,0,23,99,111,110,116,97,105,110,101,114,46,111, + 112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117, + 115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13, + 111,119,95,97,114,114,111,119,102,111,99,117,115,11,111,119,95,115,117,98, + 102,111,99,117,115,19,111,119,95,109,111,117,115,101,116,114,97,110,115,112, + 97,114,101,110,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,26,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101, + 46,108,111,99,97,108,112,114,111,112,115,11,14,102,114,108,95,102,114,97, + 109,101,119,105,100,116,104,0,30,99,111,110,116,97,105,110,101,114,46,102, + 114,97,109,101,46,115,98,104,111,114,122,46,111,112,116,105,111,110,115,11, + 14,115,98,111,95,116,104,117,109,98,116,114,97,99,107,12,115,98,111,95, + 109,111,118,101,97,117,116,111,0,30,99,111,110,116,97,105,110,101,114,46, + 102,114,97,109,101,46,115,98,118,101,114,116,46,111,112,116,105,111,110,115, + 11,14,115,98,111,95,116,104,117,109,98,116,114,97,99,107,12,115,98,111, + 95,109,111,118,101,97,117,116,111,0,16,99,111,110,116,97,105,110,101,114, + 46,98,111,117,110,100,115,1,2,1,2,1,3,231,0,3,177,0,0,13, + 111,112,116,105,111,110,115,119,105,110,100,111,119,11,8,119,111,95,112,111, + 112,117,112,17,119,111,95,98,117,116,116,111,110,101,110,100,109,111,100,97, + 108,0,7,111,112,116,105,111,110,115,11,14,102,111,95,102,114,101,101,111, + 110,99,108,111,115,101,13,102,111,95,99,108,111,115,101,111,110,101,115,99, + 17,102,111,95,108,111,99,97,108,115,104,111,114,116,99,117,116,115,15,102, + 111,95,97,117,116,111,114,101,97,100,115,116,97,116,16,102,111,95,97,117, + 116,111,119,114,105,116,101,115,116,97,116,10,102,111,95,115,97,118,101,112, + 111,115,12,102,111,95,115,97,118,101,115,116,97,116,101,0,8,111,110,99, + 114,101,97,116,101,7,12,102,111,114,109,111,110,99,114,101,97,116,101,15, + 109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,8,116,109,115, + 101,102,111,114,109,0,9,116,100,114,97,119,103,114,105,100,4,103,114,105, + 100,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119, + 49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,12,102, + 114,97,109,101,46,108,101,118,101,108,111,2,0,16,102,114,97,109,101,46, + 102,114,97,109,101,119,105,100,116,104,2,1,16,102,114,97,109,101,46,99, + 111,108,111,114,102,114,97,109,101,4,3,0,0,160,20,102,114,97,109,101, + 46,115,98,118,101,114,116,46,111,112,116,105,111,110,115,11,14,115,98,111, + 95,116,104,117,109,98,116,114,97,99,107,0,20,102,114,97,109,101,46,115, + 98,104,111,114,122,46,111,112,116,105,111,110,115,11,14,115,98,111,95,116, + 104,117,109,98,116,114,97,99,107,0,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,10, + 102,114,108,95,108,101,118,101,108,105,14,102,114,108,95,102,114,97,109,101, + 119,105,100,116,104,14,102,114,108,95,99,111,108,111,114,102,114,97,109,101, + 10,102,114,108,95,102,105,108,101,102,116,9,102,114,108,95,102,105,116,111, + 112,11,102,114,108,95,102,105,114,105,103,104,116,12,102,114,108,95,102,105, + 98,111,116,116,111,109,0,8,116,97,98,111,114,100,101,114,2,6,8,98, + 111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,22, + 9,98,111,117,110,100,115,95,99,120,3,233,0,9,98,111,117,110,100,115, + 95,99,121,3,156,0,7,97,110,99,104,111,114,115,11,7,97,110,95,108, + 101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0, + 14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,7,20,100,97, + 116,97,99,111,108,115,46,99,111,108,111,114,97,99,116,105,118,101,4,7, + 0,0,144,14,100,97,116,97,99,111,108,115,46,119,105,100,116,104,2,32, + 16,100,97,116,97,99,111,108,115,46,111,112,116,105,111,110,115,11,11,99, + 111,95,114,101,97,100,111,110,108,121,12,99,111,95,100,114,97,119,102,111, + 99,117,115,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111,95, + 115,97,118,101,115,116,97,116,101,0,17,100,97,116,97,99,111,108,115,46, + 111,112,116,105,111,110,115,49,11,11,99,111,49,95,114,111,119,102,111,110, + 116,12,99,111,49,95,114,111,119,99,111,108,111,114,14,99,111,49,95,122, + 101,98,114,97,99,111,108,111,114,19,99,111,49,95,114,111,119,99,111,108, + 111,114,102,111,99,117,115,101,100,15,99,111,49,95,114,111,119,114,101,97, + 100,111,110,108,121,0,14,100,97,116,97,99,111,108,115,46,105,116,101,109, + 115,14,1,11,99,111,108,111,114,97,99,116,105,118,101,4,7,0,0,144, + 5,119,105,100,116,104,2,32,7,111,112,116,105,111,110,115,11,11,99,111, + 95,114,101,97,100,111,110,108,121,12,99,111,95,100,114,97,119,102,111,99, + 117,115,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111,95,115, + 97,118,101,115,116,97,116,101,0,8,111,112,116,105,111,110,115,49,11,11, + 99,111,49,95,114,111,119,102,111,110,116,12,99,111,49,95,114,111,119,99, + 111,108,111,114,14,99,111,49,95,122,101,98,114,97,99,111,108,111,114,19, + 99,111,49,95,114,111,119,99,111,108,111,114,102,111,99,117,115,101,100,15, + 99,111,49,95,114,111,119,114,101,97,100,111,110,108,121,0,13,102,111,99, + 117,115,114,101,99,116,100,105,115,116,2,1,10,111,110,100,114,97,119,99, + 101,108,108,7,8,100,114,97,119,99,101,108,108,0,1,11,99,111,108,111, + 114,97,99,116,105,118,101,4,7,0,0,144,5,119,105,100,116,104,2,32, + 7,111,112,116,105,111,110,115,11,11,99,111,95,114,101,97,100,111,110,108, + 121,12,99,111,95,100,114,97,119,102,111,99,117,115,12,99,111,95,115,97, + 118,101,118,97,108,117,101,12,99,111,95,115,97,118,101,115,116,97,116,101, + 0,8,111,112,116,105,111,110,115,49,11,11,99,111,49,95,114,111,119,102, + 111,110,116,12,99,111,49,95,114,111,119,99,111,108,111,114,14,99,111,49, + 95,122,101,98,114,97,99,111,108,111,114,19,99,111,49,95,114,111,119,99, + 111,108,111,114,102,111,99,117,115,101,100,15,99,111,49,95,114,111,119,114, + 101,97,100,111,110,108,121,0,13,102,111,99,117,115,114,101,99,116,100,105, + 115,116,2,1,10,111,110,100,114,97,119,99,101,108,108,7,8,100,114,97, + 119,99,101,108,108,0,1,11,99,111,108,111,114,97,99,116,105,118,101,4, + 7,0,0,144,5,119,105,100,116,104,2,32,7,111,112,116,105,111,110,115, + 11,11,99,111,95,114,101,97,100,111,110,108,121,12,99,111,95,100,114,97, + 119,102,111,99,117,115,12,99,111,95,115,97,118,101,118,97,108,117,101,12, + 99,111,95,115,97,118,101,115,116,97,116,101,0,8,111,112,116,105,111,110, + 115,49,11,11,99,111,49,95,114,111,119,102,111,110,116,12,99,111,49,95, + 114,111,119,99,111,108,111,114,14,99,111,49,95,122,101,98,114,97,99,111, + 108,111,114,19,99,111,49,95,114,111,119,99,111,108,111,114,102,111,99,117, + 115,101,100,15,99,111,49,95,114,111,119,114,101,97,100,111,110,108,121,0, + 13,102,111,99,117,115,114,101,99,116,100,105,115,116,2,1,10,111,110,100, + 114,97,119,99,101,108,108,7,8,100,114,97,119,99,101,108,108,0,1,11, + 99,111,108,111,114,97,99,116,105,118,101,4,7,0,0,144,5,119,105,100, + 116,104,2,32,7,111,112,116,105,111,110,115,11,11,99,111,95,114,101,97, + 100,111,110,108,121,12,99,111,95,100,114,97,119,102,111,99,117,115,12,99, + 111,95,115,97,118,101,118,97,108,117,101,12,99,111,95,115,97,118,101,115, + 116,97,116,101,0,8,111,112,116,105,111,110,115,49,11,11,99,111,49,95, + 114,111,119,102,111,110,116,12,99,111,49,95,114,111,119,99,111,108,111,114, + 14,99,111,49,95,122,101,98,114,97,99,111,108,111,114,19,99,111,49,95, + 114,111,119,99,111,108,111,114,102,111,99,117,115,101,100,15,99,111,49,95, + 114,111,119,114,101,97,100,111,110,108,121,0,13,102,111,99,117,115,114,101, + 99,116,100,105,115,116,2,1,10,111,110,100,114,97,119,99,101,108,108,7, + 8,100,114,97,119,99,101,108,108,0,1,11,99,111,108,111,114,97,99,116, + 105,118,101,4,7,0,0,144,5,119,105,100,116,104,2,32,7,111,112,116, + 105,111,110,115,11,11,99,111,95,114,101,97,100,111,110,108,121,12,99,111, + 95,100,114,97,119,102,111,99,117,115,12,99,111,95,115,97,118,101,118,97, + 108,117,101,12,99,111,95,115,97,118,101,115,116,97,116,101,0,8,111,112, + 116,105,111,110,115,49,11,11,99,111,49,95,114,111,119,102,111,110,116,12, + 99,111,49,95,114,111,119,99,111,108,111,114,14,99,111,49,95,122,101,98, + 114,97,99,111,108,111,114,19,99,111,49,95,114,111,119,99,111,108,111,114, + 102,111,99,117,115,101,100,15,99,111,49,95,114,111,119,114,101,97,100,111, + 110,108,121,0,13,102,111,99,117,115,114,101,99,116,100,105,115,116,2,1, + 10,111,110,100,114,97,119,99,101,108,108,7,8,100,114,97,119,99,101,108, + 108,0,1,11,99,111,108,111,114,97,99,116,105,118,101,4,7,0,0,144, + 5,119,105,100,116,104,2,32,7,111,112,116,105,111,110,115,11,11,99,111, + 95,114,101,97,100,111,110,108,121,12,99,111,95,100,114,97,119,102,111,99, + 117,115,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111,95,115, + 97,118,101,115,116,97,116,101,0,8,111,112,116,105,111,110,115,49,11,11, + 99,111,49,95,114,111,119,102,111,110,116,12,99,111,49,95,114,111,119,99, + 111,108,111,114,14,99,111,49,95,122,101,98,114,97,99,111,108,111,114,19, + 99,111,49,95,114,111,119,99,111,108,111,114,102,111,99,117,115,101,100,15, + 99,111,49,95,114,111,119,114,101,97,100,111,110,108,121,0,13,102,111,99, + 117,115,114,101,99,116,100,105,115,116,2,1,10,111,110,100,114,97,119,99, + 101,108,108,7,8,100,114,97,119,99,101,108,108,0,1,9,108,105,110,101, + 119,105,100,116,104,2,0,11,99,111,108,111,114,97,99,116,105,118,101,4, + 7,0,0,144,5,119,105,100,116,104,2,32,7,111,112,116,105,111,110,115, + 11,11,99,111,95,114,101,97,100,111,110,108,121,12,99,111,95,100,114,97, + 119,102,111,99,117,115,12,99,111,95,115,97,118,101,118,97,108,117,101,12, + 99,111,95,115,97,118,101,115,116,97,116,101,0,8,111,112,116,105,111,110, + 115,49,11,11,99,111,49,95,114,111,119,102,111,110,116,12,99,111,49,95, + 114,111,119,99,111,108,111,114,14,99,111,49,95,122,101,98,114,97,99,111, + 108,111,114,19,99,111,49,95,114,111,119,99,111,108,111,114,102,111,99,117, + 115,101,100,15,99,111,49,95,114,111,119,114,101,97,100,111,110,108,121,0, + 13,102,111,99,117,115,114,101,99,116,100,105,115,116,2,1,10,111,110,100, + 114,97,119,99,101,108,108,7,8,100,114,97,119,99,101,108,108,0,0,13, + 102,105,120,114,111,119,115,46,99,111,117,110,116,2,1,13,102,105,120,114, + 111,119,115,46,105,116,101,109,115,14,1,6,104,101,105,103,104,116,2,21, + 14,99,97,112,116,105,111,110,115,46,99,111,117,110,116,2,7,14,99,97, + 112,116,105,111,110,115,46,105,116,101,109,115,14,1,7,111,112,116,105,111, + 110,115,11,0,0,1,7,111,112,116,105,111,110,115,11,0,0,1,7,111, + 112,116,105,111,110,115,11,0,0,1,7,111,112,116,105,111,110,115,11,0, + 0,1,7,111,112,116,105,111,110,115,11,0,0,1,7,111,112,116,105,111, + 110,115,11,0,0,1,7,111,112,116,105,111,110,115,11,0,0,0,0,0, + 8,114,111,119,99,111,117,110,116,2,6,14,103,114,105,100,102,114,97,109, + 101,99,111,108,111,114,4,3,0,0,128,13,100,97,116,97,114,111,119,104, + 101,105,103,104,116,2,21,11,111,110,99,101,108,108,101,118,101,110,116,7, + 9,99,101,108,108,101,118,101,110,116,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,14,0,0,13,116,100,97,116,101,116,105,109,101,100,105, + 115,112,9,109,111,110,116,104,100,105,115,112,14,111,112,116,105,111,110,115, + 119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121, + 112,104,104,101,105,103,104,116,0,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,13,111,119,95,109,111,117,115,101,119,104,101,101,108,17,111, + 119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,5,99,111, + 108,111,114,4,6,0,0,144,8,116,97,98,111,114,100,101,114,2,5,8, + 98,111,117,110,100,115,95,120,2,83,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,3,137,0,9,98,111,117,110,100, + 115,95,99,121,2,22,9,116,101,120,116,102,108,97,103,115,11,12,116,102, + 95,120,99,101,110,116,101,114,101,100,8,116,102,95,114,105,103,104,116,12, + 116,102,95,121,99,101,110,116,101,114,101,100,0,6,102,111,114,109,97,116, + 6,4,109,109,109,109,5,118,97,108,117,101,5,0,0,0,0,0,0,0, + 128,255,255,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0, + 0,13,116,100,97,116,101,116,105,109,101,100,105,115,112,8,121,101,97,114, + 100,105,115,112,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11, + 19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116, + 0,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 109,111,117,115,101,119,104,101,101,108,17,111,119,95,100,101,115,116,114,111, + 121,119,105,100,103,101,116,115,0,5,99,111,108,111,114,4,6,0,0,144, + 8,116,97,98,111,114,100,101,114,2,4,8,98,111,117,110,100,115,95,120, + 2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115, + 95,99,120,2,72,9,98,111,117,110,100,115,95,99,121,2,22,9,116,101, + 120,116,102,108,97,103,115,11,12,116,102,95,120,99,101,110,116,101,114,101, + 100,8,116,102,95,114,105,103,104,116,12,116,102,95,121,99,101,110,116,101, + 114,101,100,0,6,102,111,114,109,97,116,6,4,121,121,121,121,5,118,97, + 108,117,101,5,0,0,0,0,0,0,0,128,255,255,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,14,0,0,17,116,115,116,111,99,107,103, + 108,121,112,104,98,117,116,116,111,110,18,116,115,116,111,99,107,103,108,121, + 112,104,98,117,116,116,111,110,49,13,111,112,116,105,111,110,115,119,105,100, + 103,101,116,11,13,111,119,95,109,111,117,115,101,119,104,101,101,108,17,111, + 119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,8,116,97, + 98,111,114,100,101,114,2,3,8,98,111,117,110,100,115,95,120,3,220,0, + 8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99, + 120,2,11,9,98,111,117,110,100,115,95,99,121,2,11,5,115,116,97,116, + 101,11,17,97,115,95,108,111,99,97,108,105,109,97,103,101,108,105,115,116, + 15,97,115,95,108,111,99,97,108,105,109,97,103,101,110,114,17,97,115,95, + 108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,5,103,108,121,112, + 104,7,16,115,116,103,95,97,114,114,111,119,117,112,115,109,97,108,108,7, + 111,112,116,105,111,110,115,11,17,98,111,95,101,120,101,99,117,116,101,111, + 110,99,108,105,99,107,15,98,111,95,101,120,101,99,117,116,101,111,110,107, + 101,121,20,98,111,95,101,120,101,99,117,116,101,111,110,115,104,111,114,116, + 99,117,116,27,98,111,95,101,120,101,99,117,116,101,100,101,102,97,117,108, + 116,111,110,101,110,116,101,114,107,101,121,15,98,111,95,110,111,99,97,110, + 100,101,102,111,99,117,115,0,9,111,110,101,120,101,99,117,116,101,7,4, + 109,111,117,112,0,0,17,116,115,116,111,99,107,103,108,121,112,104,98,117, + 116,116,111,110,18,116,115,116,111,99,107,103,108,121,112,104,98,117,116,116, + 111,110,50,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111, + 119,95,109,111,117,115,101,119,104,101,101,108,17,111,119,95,100,101,115,116, + 114,111,121,119,105,100,103,101,116,115,0,8,116,97,98,111,114,100,101,114, + 2,1,8,98,111,117,110,100,115,95,120,3,220,0,8,98,111,117,110,100, + 115,95,121,2,11,9,98,111,117,110,100,115,95,99,120,2,11,9,98,111, + 117,110,100,115,95,99,121,2,11,5,115,116,97,116,101,11,17,97,115,95, + 108,111,99,97,108,105,109,97,103,101,108,105,115,116,15,97,115,95,108,111, + 99,97,108,105,109,97,103,101,110,114,17,97,115,95,108,111,99,97,108,111, + 110,101,120,101,99,117,116,101,0,5,103,108,121,112,104,7,18,115,116,103, + 95,97,114,114,111,119,100,111,119,110,115,109,97,108,108,7,111,112,116,105, + 111,110,115,11,17,98,111,95,101,120,101,99,117,116,101,111,110,99,108,105, + 99,107,15,98,111,95,101,120,101,99,117,116,101,111,110,107,101,121,20,98, + 111,95,101,120,101,99,117,116,101,111,110,115,104,111,114,116,99,117,116,27, + 98,111,95,101,120,101,99,117,116,101,100,101,102,97,117,108,116,111,110,101, + 110,116,101,114,107,101,121,15,98,111,95,110,111,99,97,110,100,101,102,111, + 99,117,115,0,9,111,110,101,120,101,99,117,116,101,7,6,109,111,100,111, + 119,110,0,0,17,116,115,116,111,99,107,103,108,121,112,104,98,117,116,116, + 111,110,4,98,117,117,112,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,13,111,119,95,109,111,117,115,101,119,104,101,101,108,17,111,119,95, + 100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,8,116,97,98,111, + 114,100,101,114,2,2,8,98,111,117,110,100,115,95,120,2,72,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,11, + 9,98,111,117,110,100,115,95,99,121,2,11,5,115,116,97,116,101,11,17, + 97,115,95,108,111,99,97,108,105,109,97,103,101,108,105,115,116,15,97,115, + 95,108,111,99,97,108,105,109,97,103,101,110,114,17,97,115,95,108,111,99, + 97,108,111,110,101,120,101,99,117,116,101,0,5,103,108,121,112,104,7,16, + 115,116,103,95,97,114,114,111,119,117,112,115,109,97,108,108,7,111,112,116, + 105,111,110,115,11,17,98,111,95,101,120,101,99,117,116,101,111,110,99,108, + 105,99,107,15,98,111,95,101,120,101,99,117,116,101,111,110,107,101,121,20, + 98,111,95,101,120,101,99,117,116,101,111,110,115,104,111,114,116,99,117,116, + 27,98,111,95,101,120,101,99,117,116,101,100,101,102,97,117,108,116,111,110, + 101,110,116,101,114,107,101,121,15,98,111,95,110,111,99,97,110,100,101,102, + 111,99,117,115,0,9,111,110,101,120,101,99,117,116,101,7,6,121,101,97, + 114,117,112,0,0,17,116,115,116,111,99,107,103,108,121,112,104,98,117,116, + 116,111,110,4,98,117,100,111,13,111,112,116,105,111,110,115,119,105,100,103, + 101,116,11,13,111,119,95,109,111,117,115,101,119,104,101,101,108,17,111,119, + 95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,8,98,111,117, + 110,100,115,95,120,2,72,8,98,111,117,110,100,115,95,121,2,11,9,98, + 111,117,110,100,115,95,99,120,2,11,9,98,111,117,110,100,115,95,99,121, + 2,11,5,115,116,97,116,101,11,17,97,115,95,108,111,99,97,108,105,109, + 97,103,101,108,105,115,116,15,97,115,95,108,111,99,97,108,105,109,97,103, + 101,110,114,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116, + 101,0,5,103,108,121,112,104,7,18,115,116,103,95,97,114,114,111,119,100, + 111,119,110,115,109,97,108,108,7,111,112,116,105,111,110,115,11,17,98,111, + 95,101,120,101,99,117,116,101,111,110,99,108,105,99,107,15,98,111,95,101, + 120,101,99,117,116,101,111,110,107,101,121,20,98,111,95,101,120,101,99,117, + 116,101,111,110,115,104,111,114,116,99,117,116,27,98,111,95,101,120,101,99, + 117,116,101,100,101,102,97,117,108,116,111,110,101,110,116,101,114,107,101,121, + 15,98,111,95,110,111,99,97,110,100,101,102,111,99,117,115,0,9,111,110, + 101,120,101,99,117,116,101,7,8,121,101,97,114,100,111,119,110,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tpopupcalendarfo,''); +end. diff --git a/mseide-msegui/lib/common/dialogs/mserealenter.mfm b/mseide-msegui/lib/common/dialogs/mserealenter.mfm new file mode 100644 index 0000000..8b6976e --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/mserealenter.mfm @@ -0,0 +1,64 @@ +object realenterfo: trealenterfo + visible = False + bounds_x = 395 + bounds_y = 323 + bounds_cx = 233 + bounds_cy = 88 + bounds_cymin = 75 + container.bounds = ( + 0 + 0 + 233 + 88 + ) + options = [fo_screencentered, fo_closeonesc, fo_localshortcuts, fo_autoreadstat, fo_autowritestat] + moduleclassname = 'tmseform' + object lab: tlabel + optionswidget1 = [ow1_autoheight] + taborder = 3 + bounds_x = 8 + bounds_y = 41 + bounds_cx = 217 + bounds_cy = 14 + anchors = [an_left, an_top, an_right, an_bottom] + caption = 'lab' + textflags = [tf_ycentered, tf_wordbreak] + end + object value: trealedit + frame.dummy = 0 + bounds_x = 8 + bounds_y = 62 + anchors = [an_left, an_right, an_bottom] + optionsedit1 = [oe1_autopopupmenu, oe1_savevalue, oe1_savestate] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + value = -Inf + valuedefault = -Inf + valuerange = 0 + valuestart = 0 + min = -Inf + max = 1E+038 + reffontheight = 14 + end + object ok: tbutton + taborder = 1 + bounds_x = 120 + bounds_y = 62 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + end + object cancel: tbutton + taborder = 2 + bounds_x = 176 + bounds_y = 62 + bounds_cx = 50 + bounds_cy = 20 + anchors = [an_right, an_bottom] + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + end +end diff --git a/mseide-msegui/lib/common/dialogs/mserealenter.pas b/mseide-msegui/lib/common/dialogs/mserealenter.pas new file mode 100644 index 0000000..f346fcc --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/mserealenter.pas @@ -0,0 +1,62 @@ +{ MSEgui Copyright (c) 1999-2008 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mserealenter; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseglob,mseforms,msedataedits,msesimplewidgets,msetypes,mseguiglob,msegui,msedialog, + msereal,msestrings; + +type + trealenterfo = class(tdialogform) + value: trealedit; + lab: tlabel; + ok: tbutton; + cancel: tbutton; + end; + +function realenter(var avalue: realty; const amin,amax: realty; const text: msestring = ''; + const acaption: msestring = ''): modalresultty; +//threadsave +implementation +uses + mserealenter_mfm; + +function realenter(var avalue: realty; const amin,amax: realty; const text: msestring = ''; + const acaption: msestring = ''): modalresultty; +var + fo: trealenterfo; +begin + application.lock; + try + fo:= trealenterfo.create(nil); + try + with fo do begin + value.min:= amin; + value.max:= amax; + value.value:= avalue; + caption:= acaption; + lab.caption:= text; + result:= fo.show(true,nil); + if result = mr_ok then begin + avalue:= value.value; + end; + end; + finally + fo.Free; + end; + finally + application.unlock; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/dialogs/mserealenter_mfm.pas b/mseide-msegui/lib/common/dialogs/mserealenter_mfm.pas new file mode 100644 index 0000000..caefdd9 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/mserealenter_mfm.pas @@ -0,0 +1,79 @@ +unit mserealenter_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,mserealenter; + +const + objdata: record size: integer; data: array[0..1227] of byte end = + (size: 1228; data: ( + 84,80,70,48,12,116,114,101,97,108,101,110,116,101,114,102,111,11,114,101, + 97,108,101,110,116,101,114,102,111,7,118,105,115,105,98,108,101,8,8,98, + 111,117,110,100,115,95,120,3,139,1,8,98,111,117,110,100,115,95,121,3, + 67,1,9,98,111,117,110,100,115,95,99,120,3,233,0,9,98,111,117,110, + 100,115,95,99,121,2,88,12,98,111,117,110,100,115,95,99,121,109,105,110, + 2,75,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1, + 2,0,2,0,3,233,0,2,88,0,7,111,112,116,105,111,110,115,11,17, + 102,111,95,115,99,114,101,101,110,99,101,110,116,101,114,101,100,13,102,111, + 95,99,108,111,115,101,111,110,101,115,99,17,102,111,95,108,111,99,97,108, + 115,104,111,114,116,99,117,116,115,15,102,111,95,97,117,116,111,114,101,97, + 100,115,116,97,116,16,102,111,95,97,117,116,111,119,114,105,116,101,115,116, + 97,116,0,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6, + 8,116,109,115,101,102,111,114,109,0,6,116,108,97,98,101,108,3,108,97, + 98,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,14,111,119, + 49,95,97,117,116,111,104,101,105,103,104,116,0,8,116,97,98,111,114,100, + 101,114,2,3,8,98,111,117,110,100,115,95,120,2,8,8,98,111,117,110, + 100,115,95,121,2,41,9,98,111,117,110,100,115,95,99,120,3,217,0,9, + 98,111,117,110,100,115,95,99,121,2,14,7,97,110,99,104,111,114,115,11, + 7,97,110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114, + 105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,7,99,97,112,116, + 105,111,110,6,3,108,97,98,9,116,101,120,116,102,108,97,103,115,11,12, + 116,102,95,121,99,101,110,116,101,114,101,100,12,116,102,95,119,111,114,100, + 98,114,101,97,107,0,0,0,9,116,114,101,97,108,101,100,105,116,5,118, + 97,108,117,101,11,102,114,97,109,101,46,100,117,109,109,121,2,0,8,98, + 111,117,110,100,115,95,120,2,8,8,98,111,117,110,100,115,95,121,2,62, + 7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,8,97,110, + 95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,12,111,112, + 116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111, + 112,111,112,117,112,109,101,110,117,13,111,101,49,95,115,97,118,101,118,97, + 108,117,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0,11,111, + 112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111, + 110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111, + 101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115, + 104,105,102,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115, + 101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111, + 110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101, + 114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97, + 117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99, + 107,0,5,118,97,108,117,101,5,0,0,0,0,0,0,0,128,255,255,12, + 118,97,108,117,101,100,101,102,97,117,108,116,5,0,0,0,0,0,0,0, + 128,255,255,10,118,97,108,117,101,114,97,110,103,101,2,0,10,118,97,108, + 117,101,115,116,97,114,116,2,0,3,109,105,110,5,0,0,0,0,0,0, + 0,128,255,255,3,109,97,120,5,245,136,13,181,80,153,118,150,125,64,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,7,116,98, + 117,116,116,111,110,2,111,107,8,116,97,98,111,114,100,101,114,2,1,8, + 98,111,117,110,100,115,95,120,2,120,8,98,111,117,110,100,115,95,121,2, + 62,9,98,111,117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115, + 95,99,121,2,20,7,97,110,99,104,111,114,115,11,8,97,110,95,114,105, + 103,104,116,9,97,110,95,98,111,116,116,111,109,0,5,115,116,97,116,101, + 11,10,97,115,95,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97, + 108,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,99,97,112, + 116,105,111,110,0,7,99,97,112,116,105,111,110,6,3,38,79,75,11,109, + 111,100,97,108,114,101,115,117,108,116,7,5,109,114,95,111,107,0,0,7, + 116,98,117,116,116,111,110,6,99,97,110,99,101,108,8,116,97,98,111,114, + 100,101,114,2,2,8,98,111,117,110,100,115,95,120,3,176,0,8,98,111, + 117,110,100,115,95,121,2,62,9,98,111,117,110,100,115,95,99,120,2,50, + 9,98,111,117,110,100,115,95,99,121,2,20,7,97,110,99,104,111,114,115, + 11,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109, + 0,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112, + 116,105,111,110,0,7,99,97,112,116,105,111,110,6,7,38,67,97,110,99, + 101,108,11,109,111,100,97,108,114,101,115,117,108,116,7,9,109,114,95,99, + 97,110,99,101,108,0,0,0) + ); + +initialization + registerobjectdata(@objdata,trealenterfo,''); +end. diff --git a/mseide-msegui/lib/common/dialogs/mseshortcutdialog.mfm b/mseide-msegui/lib/common/dialogs/mseshortcutdialog.mfm new file mode 100644 index 0000000..051b959 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/mseshortcutdialog.mfm @@ -0,0 +1,314 @@ +object mseshortcutdialogfo: tmseshortcutdialogfo + visible = False + bounds_x = 87 + bounds_y = 222 + bounds_cx = 595 + bounds_cy = 340 + container.onlayout = layoutexe + container.bounds = ( + 0 + 0 + 595 + 340 + ) + options = [fo_screencentered, fo_closeonesc, fo_localshortcuts, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savestate] + caption = 'Shortcuts' + onlayout = layoutexe + moduleclassname = 'tmseform' + object tsimplewidget1: tsimplewidget + taborder = 4 + visible = True + bounds_x = 71 + bounds_y = 285 + bounds_cx = 403 + bounds_cy = 53 + bounds_cxmin = 200 + anchors = [an_left, an_right, an_bottom] + object sc1ed: tstringedit + Tag = 1 + frame.options = [cfo_fixtop] + frame.levelo = 0 + frame.framewidth = 1 + frame.colorframe = -1610612734 + frame.colorclient = -1879048185 + frame.caption = '&Alternate' + frame.localprops = [frl_levelo, frl_framewidth, frl_colorframe, frl_fileft, frl_colorclient] + frame.dummy = 0 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + hint = 'Press the desired key combination.' + onshowhint = keyhint + onactivate = edactivate + ondeactivate = eddeactivate + bounds_x = 208 + bounds_y = 4 + bounds_cx = 189 + bounds_cy = 37 + anchors = [an_left, an_right, an_bottom] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savevalue, oe1_savestate] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + onkeydown = scdikey + onkeyup = scdikey + reffontheight = 14 + end + object tsplitter1: tsplitter + color = -1879048189 + taborder = 1 + visible = False + bounds_x = 200 + bounds_y = 19 + bounds_cx = 8 + bounds_cy = 20 + anchors = [an_left, an_bottom] + options = [spo_hprop, spo_dockleft, spo_docktop, spo_dockright, spo_dockbottom] + linkleft = sced + linkright = sc1ed + end + object sced: tstringedit + frame.options = [cfo_fixtop] + frame.levelo = 0 + frame.framewidth = 1 + frame.colorframe = -1610612734 + frame.colorclient = -1879048185 + frame.caption = '&Shortcut' + frame.localprops = [frl_levelo, frl_framewidth, frl_colorframe, frl_colorclient] + frame.dummy = 0 + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 2 + hint = 'Press the desired key combination.' + onshowhint = keyhint + onactivate = edactivate + ondeactivate = eddeactivate + bounds_x = 3 + bounds_y = 4 + bounds_cx = 197 + bounds_cy = 37 + anchors = [an_left, an_bottom] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savevalue, oe1_savestate] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + onkeydown = scdikey + onkeyup = scdikey + reffontheight = 14 + end + end + object grid: twidgetgrid + popupmenu = tpopupmenu1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 595 + bounds_cy = 286 + anchors = [an_top, an_bottom] + optionsgrid = [og_colsizing, og_focuscellonenter, og_colchangeontabkey, og_wrapcol, og_autopopup, og_mousescrollcol] + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 3 + captions.items = < + item + caption = 'Action' + font.name = 'stf_default' + font.xscale = 1 + font.dummy = 0 + end + item + caption = 'Shortcut' + font.name = 'stf_default' + font.xscale = 1 + font.dummy = 0 + end + item + caption = 'Alternate' + font.name = 'stf_default' + font.xscale = 1 + font.dummy = 0 + end> + end> + datacols.count = 3 + datacols.options = [co_focusselect, co_rowselect, co_savevalue, co_savestate, co_mousescrollrow] + datacols.items = < + item[sc] + width = 338 + onbeforedrawcell = beforedrawnode + options = [co_readonly, co_drawfocus, co_focusselect, co_rowselect, co_fill, co_savevalue, co_savestate, co_mousescrollrow] + widgetname = 'sc' + dataclass = ttreeitemeditlist + end + item[scdi] + width = 125 + onbeforedrawcell = beforedraw + options = [co_readonly, co_nofocus, co_focusselect, co_rowselect, co_savevalue, co_savestate, co_mousescrollrow] + widgetname = 'scdi' + dataclass = tgridmsestringdatalist + end + item[sc1di] + width = 125 + onbeforedrawcell = beforedraw1 + options = [co_readonly, co_nofocus, co_focusselect, co_rowselect, co_savevalue, co_savestate, co_mousescrollrow] + widgetname = 'sc1di' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + oncellevent = gridcellevent + reffontheight = 14 + object sc: ttreeitemedit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 338 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_locate] + onupdaterowvalues = updaterowvalues + options = [teo_treecolnavig] + reffontheight = 14 + end + object scdi: tstringedit + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.dummy = 0 + taborder = 2 + visible = False + bounds_x = 339 + bounds_y = 0 + bounds_cx = 125 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + object sc1di: tstringedit + Tag = 1 + optionswidget1 = [ow1_fontglyphheight] + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.dummy = 0 + taborder = 3 + visible = False + bounds_x = 465 + bounds_y = 0 + bounds_cx = 125 + bounds_cy = 16 + optionsedit1 = [oe1_savevalue] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 14 + end + end + object okbu: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + taborder = 1 + bounds_x = 482 + bounds_y = 306 + bounds_cx = 50 + bounds_cy = 20 + bounds_cxmin = 50 + anchors = [an_right, an_bottom] + state = [as_localcaption] + caption = '&OK' + modalresult = mr_ok + reffontheight = 14 + end + object cancelbu: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + taborder = 2 + bounds_x = 540 + bounds_y = 306 + bounds_cx = 52 + bounds_cy = 20 + bounds_cxmin = 50 + anchors = [an_right, an_bottom] + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + reffontheight = 14 + end + object defaultbu: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + color = -2147483645 + taborder = 3 + bounds_x = 8 + bounds_y = 306 + bounds_cx = 55 + bounds_cy = 20 + bounds_cxmin = 50 + anchors = [an_left, an_bottom] + state = [as_localcaption, as_localcolor, as_localonexecute] + caption = '&Default' + onexecute = defaultex + reffontheight = 14 + end + object tspacer2: tspacer + taborder = 5 + bounds_x = 532 + bounds_y = 304 + bounds_cx = 8 + bounds_cy = 20 + anchors = [an_left, an_bottom] + linkleft = okbu + linkright = cancelbu + options = [spao_glueright] + end + object tspacer1: tspacer + taborder = 6 + bounds_x = 474 + bounds_y = 304 + bounds_cx = 8 + bounds_cy = 20 + anchors = [an_left, an_bottom] + linkleft = tsimplewidget1 + linkright = okbu + options = [spao_glueright] + end + object tspacer3: tspacer + taborder = 7 + bounds_x = 63 + bounds_y = 304 + bounds_cx = 8 + bounds_cy = 20 + anchors = [an_left, an_bottom] + linkleft = defaultbu + linkright = tsimplewidget1 + end + object tpopupmenu1: tpopupmenu + menu.submenu.count = 2 + menu.submenu.items = < + item + caption = 'Expand all' + state = [as_localcaption, as_localonexecute] + onexecute = expandall + end + item + caption = 'Collapse all' + state = [as_localcaption, as_localonexecute] + onexecute = collapseall + end> + left = 32 + top = 64 + end + object timer: ttimer + interval = 1500000 + options = [to_single] + ontimer = keytimeout + left = 160 + top = 64 + end +end diff --git a/mseide-msegui/lib/common/dialogs/mseshortcutdialog.pas b/mseide-msegui/lib/common/dialogs/mseshortcutdialog.pas new file mode 100644 index 0000000..6dc9bc8 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/mseshortcutdialog.pas @@ -0,0 +1,697 @@ +{ MSEgui Copyright (c) 2008-2010 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseshortcutdialog; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseglob,mseguiglob,mseapplication,msestat,msemenus,msegui,msegraphics, + msegraphutils,mseevent,mseclasses,mseforms,msedataedits,mseedit,msegrids, + msestrings,msetypes,msewidgetgrid,msedatanodes,mselistbrowser,mseactions, + msesimplewidgets,msewidgets,msegridsglob,msetimer,msesplitter,mseificomp, + mseificompglob,mseifiglob; + +type + tmseshortcutdialogfo = class(tmseform) + grid: twidgetgrid; + sc: ttreeitemedit; + scdi: tstringedit; + sc1di: tstringedit; + okbu: tbutton; + cancelbu: tbutton; + defaultbu: tbutton; + tpopupmenu1: tpopupmenu; + timer: ttimer; + tsimplewidget1: tsimplewidget; + sc1ed: tstringedit; + tsplitter1: tsplitter; + sced: tstringedit; + tspacer2: tspacer; + tspacer1: tspacer; + tspacer3: tspacer; + procedure updaterowvalues(const sender: TObject; const aindex: Integer; + const aitem: tlistitem); + procedure scdikey(const sender: twidget; var info: keyeventinfoty); + procedure gridcellevent(const sender: TObject; var info: celleventinfoty); + procedure edactivate(const sender: TObject); + procedure eddeactivate(const sender: TObject); + procedure defaultex(const sender: TObject); + procedure collapseall(const sender: TObject); + procedure expandall(const sender: TObject); + procedure beforedrawnode(const sender: tcol; const canvas: tcanvas; + var cellinfo: cellinfoty; var processed: Boolean); + procedure beforedraw(const sender: tcol; const canvas: tcanvas; + var cellinfo: cellinfoty; var processed: Boolean); + procedure beforedraw1(const sender: tcol; const canvas: tcanvas; + var cellinfo: cellinfoty; var processed: Boolean); + procedure keyhint(const sender: TObject; var info: hintinfoty); + procedure keytimeout(const sender: TObject); + procedure layoutexe(const sender: TObject); + private +// fkeyentering: boolean; + frootnodes: treelistedititemarty; + procedure updateedits; + procedure checkconflict; + end; + +function shortcutdialog(const acontroller: tshortcutcontroller): modalresultty; + +implementation +uses + mseshortcutdialog_mfm,msekeyboard,msedatalist,msearrayutils,msestockobjects; + +const + errorcolor = cl_ltred; + +type + tshortcutitem = class(ttreelistedititem) + private + fisgroup: boolean; + fshortcut: shortcutarty; + fshortcut1: shortcutarty; + fshortcutdefault: shortcutarty; + fshortcut1default: shortcutarty; + fconflict: boolean; + fconflict1: boolean; + procedure setshortcut(const avalue: shortcutarty); + procedure setshortcut1(const avalue: shortcutarty); + public + constructor create(const aitem: tshortcutaction); overload; + procedure resetconflict; + property shortcut: shortcutarty read fshortcut write setshortcut; + property shortcut1: shortcutarty read fshortcut1 write setshortcut1; + end; + + tsysshortcutitem = class(tshortcutitem) + public + constructor create(const acaption: msestring); overload; + constructor create(const acontroller: tshortcutcontroller; + const aindex: sysshortcutty); overload; + end; + + tassistiveshortcutitem = class(tshortcutitem) + public + constructor create(const acaption: msestring); overload; + constructor create(const acontroller: tshortcutcontroller; + const aindex: assistiveshortcutty); overload; + end; + +function shortcutdialog(const acontroller: tshortcutcontroller): modalresultty; +var + fo1: tmseshortcutdialogfo; + no: tshortcutitem; + no1: tsysshortcutitem; + no2: tassistiveshortcutitem; + item1: tshortcutaction; + int1,int2: integer; + ss1: sysshortcutty; + as1: assistiveshortcutty; +begin + fo1:= tmseshortcutdialogfo.create(nil); + try + no1:= tsysshortcutitem.create(stockobjects.captions[sc_system]); + for ss1:= low(ss1) to high(ss1) do begin + no1.add(tsysshortcutitem.create(acontroller,ss1)); + end; + no2:= tassistiveshortcutitem.create(stockobjects.captions[sc_voiceoutput]); + for as1:= low(as1) to high(as1) do begin + no2.add(tassistiveshortcutitem.create(acontroller,as1)); + end; + no1.add(no2); + fo1.sc.itemlist.add(no1); + additem(pointerarty(fo1.frootnodes),no1); + additem(pointerarty(fo1.frootnodes),no2); + with acontroller.actions do begin + if count > 0 then begin + if items[0].action <> nil then begin + no:= tshortcutitem.create(items[0]); + end + else begin + no:= nil; + end; + for int1:= 0 to count - 1 do begin + item1:= items[int1]; + with item1 do begin + if action = nil then begin + if no <> nil then begin + fo1.sc.itemlist.add(no); + additem(pointerarty(fo1.frootnodes),no); + end; + no:= tshortcutitem.create(item1); + end + else begin + no.add(tshortcutitem.create(item1)); + end; + end; + end; + if no <> nil then begin + fo1.sc.itemlist.add(no); + additem(pointerarty(fo1.frootnodes),no); + end; + end; + end; + fo1.sc.itemlist.expandall; + fo1.checkconflict; + result:= fo1.show(true); + if result = mr_ok then begin + fo1.sc.itemlist.expandall; + acontroller.sysshortcuts.beginupdate; + acontroller.sysshortcuts1.beginupdate; + for ss1:= low(ss1) to high(ss1) do begin + with tsysshortcutitem(no1[ord(ss1)]) do begin + acontroller.sysshortcuts[ss1]:= getsimpleshortcut(fshortcut); + acontroller.sysshortcuts1[ss1]:= getsimpleshortcut(fshortcut1); + end; + end; + acontroller.sysshortcuts.endupdate; + acontroller.sysshortcuts1.endupdate; + + acontroller.assistiveshortcuts.beginupdate(); + acontroller.assistiveshortcuts1.beginupdate(); + for as1:= low(as1) to high(as1) do begin + with tassistiveshortcutitem(no2[ord(as1)]) do begin + acontroller.assistiveshortcuts[as1]:= fshortcut; + acontroller.assistiveshortcuts1[as1]:= fshortcut1; + end; + end; + acontroller.assistiveshortcuts.endupdate(); + acontroller.assistiveshortcuts1.endupdate(); + + int2:= ord(high(ss1))+ord(high(as1)) + 4; + for int1:= int2 to fo1.grid.rowhigh do begin + with tshortcutitem(fo1.sc[int1]) do begin + if not fisgroup then begin + with acontroller.actions[int1-int2].action do begin + shortcuts:= fshortcut; + shortcuts1:= fshortcut1; + end; + end; + end; + end; + acontroller.doafterupdate; + end; + finally + fo1.free; + end; +end; + +{ tshortcutitem } + +constructor tshortcutitem.create(const aitem: tshortcutaction); +begin + inherited create; + with aitem do begin + caption:= aitem.dispname; + fisgroup:= action = nil; + if action <> nil then begin + fshortcut:= action.shortcuts; + fshortcut1:= action.shortcuts1; + fshortcutdefault:= shortcutsdefault; + fshortcut1default:= shortcuts1default; + end; + end; +end; + +procedure tshortcutitem.setshortcut(const avalue: shortcutarty); +begin + fshortcut:= avalue; + change; +end; + +procedure tshortcutitem.setshortcut1(const avalue: shortcutarty); +begin + fshortcut1:= avalue; + change; +end; + +procedure tshortcutitem.resetconflict; +var + int1: integer; +begin + fconflict:= false; + fconflict1:= false; + for int1:= 0 to count - 1 do begin + tshortcutitem(fitems[int1]).resetconflict; + end; +end; + +{ tsysshortcutitem } + +constructor tsysshortcutitem.create(const acaption: msestring); +begin + inherited create(nil,nil); + caption:= acaption; + fisgroup:= true; +end; + +constructor tsysshortcutitem.create(const acontroller: tshortcutcontroller; + const aindex: sysshortcutty); +begin + inherited create(nil,nil); + caption:= getsysshortcutdispname(aindex); + with acontroller do begin + setsimpleshortcut(sysshortcuts[aindex],fshortcut); + setsimpleshortcut(sysshortcuts1[aindex],fshortcut1); + setsimpleshortcut(defaultsysshortcuts[aindex],fshortcutdefault); + setsimpleshortcut(defaultsysshortcuts1[aindex],fshortcut1default); + end; +end; + +{ tassistiveshortcutitem } + +constructor tassistiveshortcutitem.create(const acaption: msestring); +begin + inherited create(nil,nil); + caption:= acaption; + fisgroup:= true; +end; + +constructor tassistiveshortcutitem.create(const acontroller: tshortcutcontroller; + const aindex: assistiveshortcutty); + + procedure setdefault(const source: shortcutconstty; out dest: shortcutarty); + var + i1: int32; + begin + dest:= nil; + for i1:= 0 to high(source) do begin + if source[i1] = 0 then begin + break; + end; + additem(int16arty(dest),int16(source[i1])); + end; + end; //setdefault + +begin + inherited create(nil,nil); + caption:= getassistiveshortcutdispname(aindex); + with acontroller do begin + fshortcut:= assistiveshortcuts[aindex]; + fshortcut1:= assistiveshortcuts1[aindex]; + setdefault(defaultassistiveshortcuts[aindex],fshortcutdefault); + setdefault(defaultassistiveshortcuts1[aindex],fshortcut1default); + end; +end; + + +{ tmseshortcutdialogfo } + +procedure tmseshortcutdialogfo.updaterowvalues(const sender: TObject; + const aindex: Integer; const aitem: tlistitem); +begin + with tshortcutitem(aitem) do begin + if fisgroup then begin + scdi[aindex]:= ''; + sc1di[aindex]:= ''; + end + else begin + scdi[aindex]:= encodeshortcutname(fshortcut); + sc1di[aindex]:= encodeshortcutname(fshortcut1); + end; + end; +end; + +procedure tmseshortcutdialogfo.updateedits; +begin + if sc.item <> nil then begin + with tshortcutitem(sc.item) do begin + if fisgroup and (fconflict or fconflict1) then begin + sc.color:= errorcolor; + end + else begin + sc.color:= cl_default; + end; + end; + end; + sced.value:= scdi.value; + sc1ed.value:= sc1di.value; +end; + +procedure tmseshortcutdialogfo.keytimeout(const sender: TObject); +begin + if sced.focused then begin + sced.editor.selectall; + end + else begin + if sc1ed.focused then begin + sc1ed.editor.selectall; + end; + end; +end; + +procedure tmseshortcutdialogfo.scdikey(const sender: twidget; + var info: keyeventinfoty); + function setkey(const akey: shortcutty; + const existing: shortcutarty): shortcutarty; + begin + result:= nil; + if timer.enabled then begin + result:= existing; + end; + if akey and not modmask <> 0 then begin + setlength(result,high(result)+2); + result[high(result)]:= akey; + end; + end; //setkey + +var + mstr1: msestring; + sc1: shortcutty; + ar1: shortcutarty; +begin + with info do begin + with tshortcutitem(sc.item) do begin + if sender.tag = 0 then begin + ar1:= shortcut; + end + else begin + ar1:= shortcut1; + end; + if eventkind = ek_keypress then begin + sc1:= 0; + if not timer.enabled or (sc.item is tsysshortcutitem) then begin + ar1:= nil; + end; + mstr1:= encodeshortcutname(ar1); + if mstr1 <> '' then begin + mstr1:= mstr1 + ' '; + end; + if ss_shift in shiftstate then begin + mstr1:= mstr1+'Shift+'; + sc1:= sc1 + ord(key_modshift); + end; + if ss_ctrl in shiftstate then begin + mstr1:= mstr1+'Ctrl+'; + sc1:= sc1 + ord(key_modctrl); + end; + if ss_alt in shiftstate then begin + mstr1:= mstr1+'Alt+'; + sc1:= sc1 + ord(key_modalt); + end; + if ss_second in shiftstate then begin + mstr1:= mstr1+'Pad+'; + sc1:= sc1 + ord(key_modpad); + end; + if (keynomod = key_shift) or (keynomod = key_control) or + (keynomod = key_alt) then begin + sc1:= 0; + end; + case key of + key_shift,key_alt,key_control: begin + end + else begin + sc1:= sc1 or (ord(keynomod) and not modmask); + if (high(ar1) >= 0) or isvalidshortcut(sc1) or + (keyty(sc1) = key_delete) then begin + if (high(ar1) < 0) and (keyty(sc1) = key_delete) then begin + sc1:= 0; + tstringedit(sender).value:= ''; + end; + ar1:= setkey(sc1,ar1); + if sender.tag = 0 then begin + shortcut:= ar1; + end + else begin + shortcut1:= ar1; + end; + sc.itemlist.refreshitemvalues(-1,1); //show changes + include(eventstate,es_processed); + if not (sc.item is tsysshortcutitem) then begin + timer.enabled:= true; + timer.interval:= timer.interval; + end; + end; + checkconflict; + end; + end; + if mstr1 <> '' then begin + tstringedit(sender).value:= mstr1; + end; + end + else begin + if eventkind = ek_keyrelease then begin + tstringedit(sender).value:= encodeshortcutname(ar1); + updateedits; + end; + end; + end; + end; + if timer.enabled then begin + tstringedit(sender).editor.clearselection; + end; +end; + +procedure tmseshortcutdialogfo.gridcellevent(const sender: TObject; + var info: celleventinfoty); +var + bo1: boolean; +begin + case info.eventkind of + cek_focusedcellchanged: begin + updateedits; + bo1:= not ((sc.item = nil) or tshortcutitem(sc.item).fisgroup); + sced.enabled:= bo1; + sc1ed.enabled:= bo1; + defaultbu.enabled:= bo1; + end; + cek_buttonrelease: begin + if iscellclick(info) then begin + if info.cell.row >= 0 then begin + if not tshortcutitem(sc.item).fisgroup then begin + case info.cell.col of + 1: begin + sced.setfocus; + end; + 2: begin + sc1ed.setfocus; + end; + end; + end; + end; + end; + end; + end; +end; + +procedure tmseshortcutdialogfo.edactivate(const sender: TObject); +begin + with tstringedit(sender) do begin + frame.colorframe:= cl_red; + end; +end; + +procedure tmseshortcutdialogfo.eddeactivate(const sender: TObject); +begin + with tstringedit(sender) do begin + frame.colorframe:= cl_black; + end; +end; + +procedure tmseshortcutdialogfo.defaultex(const sender: TObject); +begin + with tshortcutitem(sc.item) do begin + shortcut:= fshortcutdefault; + shortcut1:= fshortcut1default; + end; + sc.itemlist.refreshitemvalues(grid.row,1); + checkconflict; +end; + +procedure tmseshortcutdialogfo.collapseall(const sender: TObject); +begin + sc.itemlist.collapseall; +end; + +procedure tmseshortcutdialogfo.expandall(const sender: TObject); +begin + sc.itemlist.expandall; +end; + +procedure tmseshortcutdialogfo.checkconflict; +var + int1,int2,int3,int4: integer; + rootnode1: tshortcutitem; + rootnode2: tshortcutitem; + node1: tshortcutitem; + scut,scut1: shortcutarty; + conflict,conflict1: boolean; +begin + conflict:= false; + conflict1:= false; + for int1:= 0 to high(frootnodes) do begin + tshortcutitem(frootnodes[int1]).resetconflict; + end; + for int1:= 0 to high(frootnodes) do begin + rootnode1:= tshortcutitem(frootnodes[int1]); + with rootnode1 do begin + for int2:= 0 to count - 1 do begin + node1:= tshortcutitem(fitems[int2]); + with node1 do begin + scut:= fshortcut; + scut1:= fshortcut1; + for int3:= int2 + 1 to rootnode1.count - 1 do begin + //leafs in current node + with tshortcutitem(rootnode1.fitems[int3]) do begin + if (scut <> nil) then begin + if checkshortcutconflict(fshortcut,scut) then begin + node1.fconflict:= true; + rootnode1.fconflict:= true; + fconflict:= true; + conflict:= true; + end; + if checkshortcutconflict(fshortcut1,scut) then begin + node1.fconflict:= true; + conflict:= true; + rootnode1.fconflict:= true; + fconflict1:= true; + conflict1:= true; + end; + end; + if (scut1 <> nil) then begin + if checkshortcutconflict(fshortcut,scut1) then begin + node1.fconflict1:= true; + conflict1:= true; + rootnode1.fconflict1:= true; + fconflict:= true; + conflict:= true; + end; + if checkshortcutconflict(fshortcut1,scut1) then begin + node1.fconflict1:= true; + conflict1:= true; + rootnode1.fconflict1:= true; + fconflict1:= true; + end; + end; + end; + end; + for int4:= int1+1 to high(frootnodes) do begin + //remaining nodes + rootnode2:= tshortcutitem(frootnodes[int4]); + for int3:= 0 to rootnode2.count - 1 do begin + with tshortcutitem(rootnode2.fitems[int3]) do begin + if (scut <> nil) then begin + if checkshortcutconflict(fshortcut,scut) then begin + node1.fconflict:= true; + conflict:= true; + rootnode1.fconflict:= true; + fconflict:= true; + rootnode2.fconflict:= true; + end; + if checkshortcutconflict(fshortcut1,scut) then begin + node1.fconflict:= true; + conflict:= true; + rootnode1.fconflict:= true; + fconflict1:= true; + conflict1:= true; + rootnode2.fconflict1:= true; + end; + end; + if (scut1 <> nil) then begin + if checkshortcutconflict(fshortcut,scut1) then begin + node1.fconflict1:= true; + conflict1:= true; + rootnode1.fconflict1:= true; + fconflict:= true; + conflict:= true; + rootnode2.fconflict:= true; + end; + if checkshortcutconflict(fshortcut1,scut1) then begin + node1.fconflict1:= true; + conflict1:= true; + rootnode1.fconflict1:= true; + fconflict1:= true; + rootnode2.fconflict1:= true; + end; + end; + end; + end; + end; + end; + end; + end; + end; + with grid.fixrows[-1] do begin + if conflict then begin + captions[1].font.color:= cl_red; + end + else begin + captions[1].font.color:= cl_text; + end; + if conflict1 then begin + captions[2].font.color:= cl_red; + end + else begin + captions[2].font.color:= cl_text; + end; + end; + grid.invalidate; + updateedits; +end; + +procedure tmseshortcutdialogfo.beforedrawnode(const sender: tcol; + const canvas: tcanvas; var cellinfo: cellinfoty; + var processed: Boolean); +begin + with tshortcutitem(cellinfo.datapo^) do begin + if fisgroup and (fconflict or fconflict1) then begin + cellinfo.color:= errorcolor; + end; + end; +end; + +procedure tmseshortcutdialogfo.beforedraw(const sender: tcol; + const canvas: tcanvas; var cellinfo: cellinfoty; + var processed: Boolean); +begin + with tshortcutitem(sc[cellinfo.cell.row]) do begin + if not fisgroup then begin + if fconflict then begin + cellinfo.color:= errorcolor; + end + else begin + if not issameshortcut(fshortcut,fshortcutdefault) then begin + cellinfo.color:= cl_infobackground; + end; + end; + end; + end; +end; + +procedure tmseshortcutdialogfo.beforedraw1(const sender: tcol; + const canvas: tcanvas; var cellinfo: cellinfoty; + var processed: Boolean); +begin + with tshortcutitem(sc[cellinfo.cell.row]) do begin + if not fisgroup then begin + if fconflict1 then begin + cellinfo.color:= errorcolor; + end + else begin + if not issameshortcut(fshortcut1,fshortcut1default) then begin + cellinfo.color:= cl_infobackground; + end; + end; + end; + end; +end; + +procedure tmseshortcutdialogfo.keyhint(const sender: TObject; + var info: hintinfoty); +begin + if not twidget(sender).active then begin + info.caption:= ''; + end; +end; + +procedure tmseshortcutdialogfo.layoutexe(const sender: TObject); +begin + aligny(wam_center,[sced,defaultbu,okbu,cancelbu]); +end; + +end. diff --git a/mseide-msegui/lib/common/dialogs/mseshortcutdialog_mfm.pas b/mseide-msegui/lib/common/dialogs/mseshortcutdialog_mfm.pas new file mode 100644 index 0000000..0e58c3b --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/mseshortcutdialog_mfm.pas @@ -0,0 +1,356 @@ +unit mseshortcutdialog_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,mseshortcutdialog; + +const + objdata: record size: integer; data: array[0..6779] of byte end = + (size: 6780; data: ( + 84,80,70,48,20,116,109,115,101,115,104,111,114,116,99,117,116,100,105,97, + 108,111,103,102,111,19,109,115,101,115,104,111,114,116,99,117,116,100,105,97, + 108,111,103,102,111,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100, + 115,95,120,2,87,8,98,111,117,110,100,115,95,121,3,222,0,9,98,111, + 117,110,100,115,95,99,120,3,83,2,9,98,111,117,110,100,115,95,99,121, + 3,84,1,18,99,111,110,116,97,105,110,101,114,46,111,110,108,97,121,111, + 117,116,7,9,108,97,121,111,117,116,101,120,101,16,99,111,110,116,97,105, + 110,101,114,46,98,111,117,110,100,115,1,2,0,2,0,3,83,2,3,84, + 1,0,7,111,112,116,105,111,110,115,11,17,102,111,95,115,99,114,101,101, + 110,99,101,110,116,101,114,101,100,13,102,111,95,99,108,111,115,101,111,110, + 101,115,99,17,102,111,95,108,111,99,97,108,115,104,111,114,116,99,117,116, + 115,15,102,111,95,97,117,116,111,114,101,97,100,115,116,97,116,16,102,111, + 95,97,117,116,111,119,114,105,116,101,115,116,97,116,10,102,111,95,115,97, + 118,101,112,111,115,12,102,111,95,115,97,118,101,115,116,97,116,101,0,7, + 99,97,112,116,105,111,110,6,9,83,104,111,114,116,99,117,116,115,8,111, + 110,108,97,121,111,117,116,7,9,108,97,121,111,117,116,101,120,101,15,109, + 111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,8,116,109,115,101, + 102,111,114,109,0,13,116,115,105,109,112,108,101,119,105,100,103,101,116,14, + 116,115,105,109,112,108,101,119,105,100,103,101,116,49,8,116,97,98,111,114, + 100,101,114,2,4,7,118,105,115,105,98,108,101,9,8,98,111,117,110,100, + 115,95,120,2,71,8,98,111,117,110,100,115,95,121,3,29,1,9,98,111, + 117,110,100,115,95,99,120,3,147,1,9,98,111,117,110,100,115,95,99,121, + 2,53,12,98,111,117,110,100,115,95,99,120,109,105,110,3,200,0,7,97, + 110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,8,97,110,95,114, + 105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,0,11,116,115,116, + 114,105,110,103,101,100,105,116,5,115,99,49,101,100,3,84,97,103,2,1, + 13,102,114,97,109,101,46,111,112,116,105,111,110,115,11,10,99,102,111,95, + 102,105,120,116,111,112,0,12,102,114,97,109,101,46,108,101,118,101,108,111, + 2,0,16,102,114,97,109,101,46,102,114,97,109,101,119,105,100,116,104,2, + 1,16,102,114,97,109,101,46,99,111,108,111,114,102,114,97,109,101,4,2, + 0,0,160,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110, + 116,4,7,0,0,144,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,10,38,65,108,116,101,114,110,97,116,101,16,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,14,102,114,108,95,102,114,97,109,101,119,105,100,116,104,14,102,114,108, + 95,99,111,108,111,114,102,114,97,109,101,10,102,114,108,95,102,105,108,101, + 102,116,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,11, + 102,114,97,109,101,46,100,117,109,109,121,2,0,16,102,114,97,109,101,46, + 111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0, + 4,104,105,110,116,6,34,80,114,101,115,115,32,116,104,101,32,100,101,115, + 105,114,101,100,32,107,101,121,32,99,111,109,98,105,110,97,116,105,111,110, + 46,10,111,110,115,104,111,119,104,105,110,116,7,7,107,101,121,104,105,110, + 116,10,111,110,97,99,116,105,118,97,116,101,7,10,101,100,97,99,116,105, + 118,97,116,101,12,111,110,100,101,97,99,116,105,118,97,116,101,7,12,101, + 100,100,101,97,99,116,105,118,97,116,101,8,98,111,117,110,100,115,95,120, + 3,208,0,8,98,111,117,110,100,115,95,121,2,4,9,98,111,117,110,100, + 115,95,99,120,3,189,0,9,98,111,117,110,100,115,95,99,121,2,37,7, + 97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,8,97,110,95, + 114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0,12,111,112,116, + 105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112, + 111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99, + 117,116,101,13,111,101,49,95,115,97,118,101,118,97,108,117,101,13,111,101, + 49,95,115,97,118,101,115,116,97,116,101,0,11,111,112,116,105,111,110,115, + 101,100,105,116,11,11,111,101,95,114,101,97,100,111,110,108,121,12,111,101, + 95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113, + 117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101, + 108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95, + 101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101, + 108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110, + 99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114, + 13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117, + 116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107, + 0,9,111,110,107,101,121,100,111,119,110,7,7,115,99,100,105,107,101,121, + 7,111,110,107,101,121,117,112,7,7,115,99,100,105,107,101,121,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,9,116,115,112,108, + 105,116,116,101,114,10,116,115,112,108,105,116,116,101,114,49,5,99,111,108, + 111,114,4,3,0,0,144,8,116,97,98,111,114,100,101,114,2,1,7,118, + 105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,200,0,8, + 98,111,117,110,100,115,95,121,2,19,9,98,111,117,110,100,115,95,99,120, + 2,8,9,98,111,117,110,100,115,95,99,121,2,20,7,97,110,99,104,111, + 114,115,11,7,97,110,95,108,101,102,116,9,97,110,95,98,111,116,116,111, + 109,0,7,111,112,116,105,111,110,115,11,9,115,112,111,95,104,112,114,111, + 112,12,115,112,111,95,100,111,99,107,108,101,102,116,11,115,112,111,95,100, + 111,99,107,116,111,112,13,115,112,111,95,100,111,99,107,114,105,103,104,116, + 14,115,112,111,95,100,111,99,107,98,111,116,116,111,109,0,8,108,105,110, + 107,108,101,102,116,7,4,115,99,101,100,9,108,105,110,107,114,105,103,104, + 116,7,5,115,99,49,101,100,0,0,11,116,115,116,114,105,110,103,101,100, + 105,116,4,115,99,101,100,13,102,114,97,109,101,46,111,112,116,105,111,110, + 115,11,10,99,102,111,95,102,105,120,116,111,112,0,12,102,114,97,109,101, + 46,108,101,118,101,108,111,2,0,16,102,114,97,109,101,46,102,114,97,109, + 101,119,105,100,116,104,2,1,16,102,114,97,109,101,46,99,111,108,111,114, + 102,114,97,109,101,4,2,0,0,160,17,102,114,97,109,101,46,99,111,108, + 111,114,99,108,105,101,110,116,4,7,0,0,144,13,102,114,97,109,101,46, + 99,97,112,116,105,111,110,6,9,38,83,104,111,114,116,99,117,116,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108, + 95,108,101,118,101,108,111,14,102,114,108,95,102,114,97,109,101,119,105,100, + 116,104,14,102,114,108,95,99,111,108,111,114,102,114,97,109,101,15,102,114, + 108,95,99,111,108,111,114,99,108,105,101,110,116,0,11,102,114,97,109,101, + 46,100,117,109,109,121,2,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116,97,98,111, + 114,100,101,114,2,2,4,104,105,110,116,6,34,80,114,101,115,115,32,116, + 104,101,32,100,101,115,105,114,101,100,32,107,101,121,32,99,111,109,98,105, + 110,97,116,105,111,110,46,10,111,110,115,104,111,119,104,105,110,116,7,7, + 107,101,121,104,105,110,116,10,111,110,97,99,116,105,118,97,116,101,7,10, + 101,100,97,99,116,105,118,97,116,101,12,111,110,100,101,97,99,116,105,118, + 97,116,101,7,12,101,100,100,101,97,99,116,105,118,97,116,101,8,98,111, + 117,110,100,115,95,120,2,3,8,98,111,117,110,100,115,95,121,2,4,9, + 98,111,117,110,100,115,95,99,120,3,197,0,9,98,111,117,110,100,115,95, + 99,121,2,37,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102, + 116,9,97,110,95,98,111,116,116,111,109,0,12,111,112,116,105,111,110,115, + 101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112, + 109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13, + 111,101,49,95,115,97,118,101,118,97,108,117,101,13,111,101,49,95,115,97, + 118,101,115,116,97,116,101,0,11,111,112,116,105,111,110,115,101,100,105,116, + 11,11,111,101,95,114,101,97,100,111,110,108,121,12,111,101,95,117,110,100, + 111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121, + 16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101, + 95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114, + 101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116, + 111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115, + 111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95, + 97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101, + 108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,9,111,110, + 107,101,121,100,111,119,110,7,7,115,99,100,105,107,101,121,7,111,110,107, + 101,121,117,112,7,7,115,99,100,105,107,101,121,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,14,0,0,0,11,116,119,105,100,103,101,116, + 103,114,105,100,4,103,114,105,100,9,112,111,112,117,112,109,101,110,117,7, + 11,116,112,111,112,117,112,109,101,110,117,49,8,98,111,117,110,100,115,95, + 120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100, + 115,95,99,120,3,83,2,9,98,111,117,110,100,115,95,99,121,3,30,1, + 7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,9,97,110,95, + 98,111,116,116,111,109,0,11,111,112,116,105,111,110,115,103,114,105,100,11, + 12,111,103,95,99,111,108,115,105,122,105,110,103,19,111,103,95,102,111,99, + 117,115,99,101,108,108,111,110,101,110,116,101,114,20,111,103,95,99,111,108, + 99,104,97,110,103,101,111,110,116,97,98,107,101,121,10,111,103,95,119,114, + 97,112,99,111,108,12,111,103,95,97,117,116,111,112,111,112,117,112,17,111, + 103,95,109,111,117,115,101,115,99,114,111,108,108,99,111,108,0,13,102,105, + 120,114,111,119,115,46,99,111,117,110,116,2,1,13,102,105,120,114,111,119, + 115,46,105,116,101,109,115,14,1,6,104,101,105,103,104,116,2,16,14,99, + 97,112,116,105,111,110,115,46,99,111,117,110,116,2,3,14,99,97,112,116, + 105,111,110,115,46,105,116,101,109,115,14,1,7,99,97,112,116,105,111,110, + 6,6,65,99,116,105,111,110,9,102,111,110,116,46,110,97,109,101,6,11, + 115,116,102,95,100,101,102,97,117,108,116,11,102,111,110,116,46,120,115,99, + 97,108,101,2,1,10,102,111,110,116,46,100,117,109,109,121,2,0,0,1, + 7,99,97,112,116,105,111,110,6,8,83,104,111,114,116,99,117,116,9,102, + 111,110,116,46,110,97,109,101,6,11,115,116,102,95,100,101,102,97,117,108, + 116,11,102,111,110,116,46,120,115,99,97,108,101,2,1,10,102,111,110,116, + 46,100,117,109,109,121,2,0,0,1,7,99,97,112,116,105,111,110,6,9, + 65,108,116,101,114,110,97,116,101,9,102,111,110,116,46,110,97,109,101,6, + 11,115,116,102,95,100,101,102,97,117,108,116,11,102,111,110,116,46,120,115, + 99,97,108,101,2,1,10,102,111,110,116,46,100,117,109,109,121,2,0,0, + 0,0,0,14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,3, + 16,100,97,116,97,99,111,108,115,46,111,112,116,105,111,110,115,11,14,99, + 111,95,102,111,99,117,115,115,101,108,101,99,116,12,99,111,95,114,111,119, + 115,101,108,101,99,116,12,99,111,95,115,97,118,101,118,97,108,117,101,12, + 99,111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109,111,117,115, + 101,115,99,114,111,108,108,114,111,119,0,14,100,97,116,97,99,111,108,115, + 46,105,116,101,109,115,14,7,2,115,99,1,5,119,105,100,116,104,3,82, + 1,16,111,110,98,101,102,111,114,101,100,114,97,119,99,101,108,108,7,14, + 98,101,102,111,114,101,100,114,97,119,110,111,100,101,7,111,112,116,105,111, + 110,115,11,11,99,111,95,114,101,97,100,111,110,108,121,12,99,111,95,100, + 114,97,119,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115,101,108, + 101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,7,99,111,95, + 102,105,108,108,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111, + 95,115,97,118,101,115,116,97,116,101,17,99,111,95,109,111,117,115,101,115, + 99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101, + 6,2,115,99,9,100,97,116,97,99,108,97,115,115,7,17,116,116,114,101, + 101,105,116,101,109,101,100,105,116,108,105,115,116,0,7,4,115,99,100,105, + 1,5,119,105,100,116,104,2,125,16,111,110,98,101,102,111,114,101,100,114, + 97,119,99,101,108,108,7,10,98,101,102,111,114,101,100,114,97,119,7,111, + 112,116,105,111,110,115,11,11,99,111,95,114,101,97,100,111,110,108,121,10, + 99,111,95,110,111,102,111,99,117,115,14,99,111,95,102,111,99,117,115,115, + 101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99,116,12,99, + 111,95,115,97,118,101,118,97,108,117,101,12,99,111,95,115,97,118,101,115, + 116,97,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111,108,108,114, + 111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,4,115,99,100,105, + 9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101, + 115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,5,115,99,49, + 100,105,1,5,119,105,100,116,104,2,125,16,111,110,98,101,102,111,114,101, + 100,114,97,119,99,101,108,108,7,11,98,101,102,111,114,101,100,114,97,119, + 49,7,111,112,116,105,111,110,115,11,11,99,111,95,114,101,97,100,111,110, + 108,121,10,99,111,95,110,111,102,111,99,117,115,14,99,111,95,102,111,99, + 117,115,115,101,108,101,99,116,12,99,111,95,114,111,119,115,101,108,101,99, + 116,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99,111,95,115,97, + 118,101,115,116,97,116,101,17,99,111,95,109,111,117,115,101,115,99,114,111, + 108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109,101,6,5,115, + 99,49,100,105,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105, + 100,109,115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,0, + 13,100,97,116,97,114,111,119,104,101,105,103,104,116,2,16,11,111,110,99, + 101,108,108,101,118,101,110,116,7,13,103,114,105,100,99,101,108,108,101,118, + 101,110,116,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0, + 13,116,116,114,101,101,105,116,101,109,101,100,105,116,2,115,99,11,111,112, + 116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101, + 98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101, + 118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108, + 105,101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,10,102, + 114,108,95,108,101,118,101,108,105,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,8,116,97,98,111,114,100,101,114,2,1,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,0,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,82, + 1,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110, + 115,101,100,105,116,49,11,13,111,101,49,95,115,97,118,101,118,97,108,117, + 101,0,11,111,112,116,105,111,110,115,101,100,105,116,11,11,111,101,95,114, + 101,97,100,111,110,108,121,12,111,101,95,117,110,100,111,111,110,101,115,99, + 13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95,99,104, + 101,99,107,109,114,99,97,110,99,101,108,14,111,101,95,115,104,105,102,116, + 114,101,116,117,114,110,12,111,101,95,101,97,116,114,101,116,117,114,110,20, + 111,101,95,114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116, + 15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95, + 101,110,100,111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101, + 108,101,99,116,9,111,101,95,108,111,99,97,116,101,0,17,111,110,117,112, + 100,97,116,101,114,111,119,118,97,108,117,101,115,7,15,117,112,100,97,116, + 101,114,111,119,118,97,108,117,101,115,7,111,112,116,105,111,110,115,11,16, + 116,101,111,95,116,114,101,101,99,111,108,110,97,118,105,103,0,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,11,116,115,116,114, + 105,110,103,101,100,105,116,4,115,99,100,105,14,111,112,116,105,111,110,115, + 119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121, + 112,104,104,101,105,103,104,116,0,11,111,112,116,105,111,110,115,115,107,105, + 110,11,19,111,115,107,95,102,114,97,109,101,98,117,116,116,111,110,111,110, + 108,121,0,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102, + 114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,3,0,0, + 128,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10, + 102,114,108,95,108,101,118,101,108,111,10,102,114,108,95,108,101,118,101,108, + 105,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,11,102, + 114,97,109,101,46,100,117,109,109,121,2,0,8,116,97,98,111,114,100,101, + 114,2,2,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95, + 120,3,83,1,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110, + 100,115,95,99,120,2,125,9,98,111,117,110,100,115,95,99,121,2,16,12, + 111,112,116,105,111,110,115,101,100,105,116,49,11,13,111,101,49,95,115,97, + 118,101,118,97,108,117,101,0,11,111,112,116,105,111,110,115,101,100,105,116, + 11,11,111,101,95,114,101,97,100,111,110,108,121,12,111,101,95,117,110,100, + 111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121, + 16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101, + 95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116,114, + 101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99,116, + 111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114,115, + 111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101,95, + 97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115,101, + 108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,11,116,115,116,114, + 105,110,103,101,100,105,116,5,115,99,49,100,105,3,84,97,103,2,1,14, + 111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95, + 102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,11,111,112,116, + 105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101,98, + 117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101,118, + 101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105, + 101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,10,102,114, + 108,95,108,101,118,101,108,105,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,11,102,114,97,109,101,46,100,117,109,109,121,2,0,8, + 116,97,98,111,114,100,101,114,2,3,7,118,105,115,105,98,108,101,8,8, + 98,111,117,110,100,115,95,120,3,209,1,8,98,111,117,110,100,115,95,121, + 2,0,9,98,111,117,110,100,115,95,99,120,2,125,9,98,111,117,110,100, + 115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11, + 13,111,101,49,95,115,97,118,101,118,97,108,117,101,0,11,111,112,116,105, + 111,110,115,101,100,105,116,11,11,111,101,95,114,101,97,100,111,110,108,121, + 12,111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111, + 115,101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97, + 110,99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12, + 111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101, + 116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105, + 116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110, + 116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101, + 95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108, + 105,99,107,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,0,0,7,116,98,117,116,116,111,110,4,111,107,98,117,14,111,112,116, + 105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110, + 116,103,108,121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116, + 111,115,99,97,108,101,13,111,119,49,95,97,117,116,111,119,105,100,116,104, + 0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95, + 120,3,226,1,8,98,111,117,110,100,115,95,121,3,50,1,9,98,111,117, + 110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,20, + 12,98,111,117,110,100,115,95,99,120,109,105,110,2,50,7,97,110,99,104, + 111,114,115,11,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116, + 116,111,109,0,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,3,38,79, + 75,11,109,111,100,97,108,114,101,115,117,108,116,7,5,109,114,95,111,107, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,7,116, + 98,117,116,116,111,110,8,99,97,110,99,101,108,98,117,14,111,112,116,105, + 111,110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116, + 103,108,121,112,104,104,101,105,103,104,116,13,111,119,49,95,97,117,116,111, + 115,99,97,108,101,13,111,119,49,95,97,117,116,111,119,105,100,116,104,0, + 8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120, + 3,28,2,8,98,111,117,110,100,115,95,121,3,50,1,9,98,111,117,110, + 100,115,95,99,120,2,52,9,98,111,117,110,100,115,95,99,121,2,20,12, + 98,111,117,110,100,115,95,99,120,109,105,110,2,50,7,97,110,99,104,111, + 114,115,11,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116,116, + 111,109,0,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99, + 97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,7,38,67,97, + 110,99,101,108,11,109,111,100,97,108,114,101,115,117,108,116,7,9,109,114, + 95,99,97,110,99,101,108,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,0,7,116,98,117,116,116,111,110,9,100,101,102,97,117,108, + 116,98,117,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19, + 111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,13, + 111,119,49,95,97,117,116,111,115,99,97,108,101,13,111,119,49,95,97,117, + 116,111,119,105,100,116,104,0,5,99,111,108,111,114,4,3,0,0,128,8, + 116,97,98,111,114,100,101,114,2,3,8,98,111,117,110,100,115,95,120,2, + 8,8,98,111,117,110,100,115,95,121,3,50,1,9,98,111,117,110,100,115, + 95,99,120,2,55,9,98,111,117,110,100,115,95,99,121,2,20,12,98,111, + 117,110,100,115,95,99,120,109,105,110,2,50,7,97,110,99,104,111,114,115, + 11,7,97,110,95,108,101,102,116,9,97,110,95,98,111,116,116,111,109,0, + 5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116, + 105,111,110,13,97,115,95,108,111,99,97,108,99,111,108,111,114,17,97,115, + 95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,7,99,97,112, + 116,105,111,110,6,8,38,68,101,102,97,117,108,116,9,111,110,101,120,101, + 99,117,116,101,7,9,100,101,102,97,117,108,116,101,120,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,14,0,0,7,116,115,112,97,99,101, + 114,8,116,115,112,97,99,101,114,50,8,116,97,98,111,114,100,101,114,2, + 5,8,98,111,117,110,100,115,95,120,3,20,2,8,98,111,117,110,100,115, + 95,121,3,48,1,9,98,111,117,110,100,115,95,99,120,2,8,9,98,111, + 117,110,100,115,95,99,121,2,20,7,97,110,99,104,111,114,115,11,7,97, + 110,95,108,101,102,116,9,97,110,95,98,111,116,116,111,109,0,8,108,105, + 110,107,108,101,102,116,7,4,111,107,98,117,9,108,105,110,107,114,105,103, + 104,116,7,8,99,97,110,99,101,108,98,117,7,111,112,116,105,111,110,115, + 11,14,115,112,97,111,95,103,108,117,101,114,105,103,104,116,0,0,0,7, + 116,115,112,97,99,101,114,8,116,115,112,97,99,101,114,49,8,116,97,98, + 111,114,100,101,114,2,6,8,98,111,117,110,100,115,95,120,3,218,1,8, + 98,111,117,110,100,115,95,121,3,48,1,9,98,111,117,110,100,115,95,99, + 120,2,8,9,98,111,117,110,100,115,95,99,121,2,20,7,97,110,99,104, + 111,114,115,11,7,97,110,95,108,101,102,116,9,97,110,95,98,111,116,116, + 111,109,0,8,108,105,110,107,108,101,102,116,7,14,116,115,105,109,112,108, + 101,119,105,100,103,101,116,49,9,108,105,110,107,114,105,103,104,116,7,4, + 111,107,98,117,7,111,112,116,105,111,110,115,11,14,115,112,97,111,95,103, + 108,117,101,114,105,103,104,116,0,0,0,7,116,115,112,97,99,101,114,8, + 116,115,112,97,99,101,114,51,8,116,97,98,111,114,100,101,114,2,7,8, + 98,111,117,110,100,115,95,120,2,63,8,98,111,117,110,100,115,95,121,3, + 48,1,9,98,111,117,110,100,115,95,99,120,2,8,9,98,111,117,110,100, + 115,95,99,121,2,20,7,97,110,99,104,111,114,115,11,7,97,110,95,108, + 101,102,116,9,97,110,95,98,111,116,116,111,109,0,8,108,105,110,107,108, + 101,102,116,7,9,100,101,102,97,117,108,116,98,117,9,108,105,110,107,114, + 105,103,104,116,7,14,116,115,105,109,112,108,101,119,105,100,103,101,116,49, + 0,0,10,116,112,111,112,117,112,109,101,110,117,11,116,112,111,112,117,112, + 109,101,110,117,49,18,109,101,110,117,46,115,117,98,109,101,110,117,46,99, + 111,117,110,116,2,2,18,109,101,110,117,46,115,117,98,109,101,110,117,46, + 105,116,101,109,115,14,1,7,99,97,112,116,105,111,110,6,10,69,120,112, + 97,110,100,32,97,108,108,5,115,116,97,116,101,11,15,97,115,95,108,111, + 99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111, + 110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7, + 9,101,120,112,97,110,100,97,108,108,0,1,7,99,97,112,116,105,111,110, + 6,12,67,111,108,108,97,112,115,101,32,97,108,108,5,115,116,97,116,101, + 11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115, + 95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101, + 120,101,99,117,116,101,7,11,99,111,108,108,97,112,115,101,97,108,108,0, + 0,4,108,101,102,116,2,32,3,116,111,112,2,64,0,0,6,116,116,105, + 109,101,114,5,116,105,109,101,114,8,105,110,116,101,114,118,97,108,4,96, + 227,22,0,7,111,112,116,105,111,110,115,11,9,116,111,95,115,105,110,103, + 108,101,0,7,111,110,116,105,109,101,114,7,10,107,101,121,116,105,109,101, + 111,117,116,4,108,101,102,116,3,160,0,3,116,111,112,2,64,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tmseshortcutdialogfo,''); +end. diff --git a/mseide-msegui/lib/common/dialogs/msestringenter.mfm b/mseide-msegui/lib/common/dialogs/msestringenter.mfm new file mode 100644 index 0000000..d0b2fe3 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msestringenter.mfm @@ -0,0 +1,94 @@ +object stringenterfo: tstringenterfo + optionswidget1 = [ow1_autoscale, ow1_autoheight] + optionswidget = [ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_destroywidgets, ow_hinton] + visible = False + bounds_x = 340 + bounds_y = 323 + bounds_cx = 398 + bounds_cy = 70 + bounds_cxmin = 200 + bounds_cymin = 70 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.frame.framei_bottom = 10 + container.frame.localprops = [frl_fibottom] + container.frame.localprops1 = [] + container.onlayout = layoutexe + container.bounds = ( + 0 + 0 + 398 + 70 + ) + options = [fo_screencentered, fo_closeonesc, fo_localshortcuts, fo_autoreadstat, fo_autowritestat] + windowopacity = -Inf + onlayout = layoutexe + moduleclassname = 'tmseform' + object lab: tlabel + optionswidget1 = [ow1_autoheight] + optionswidget = [ow_mousewheel, ow_destroywidgets] + taborder = 1 + bounds_x = 7 + bounds_y = 12 + bounds_cx = 384 + bounds_cy = 16 + anchors = [an_left, an_top, an_right] + caption = 'lab' + textflags = [tf_ycentered, tf_wordbreak] + end + object tlayouter1: tlayouter + bounds_x = 8 + bounds_y = 36 + bounds_cx = 383 + bounds_cy = 22 + anchors = [an_left, an_top, an_right] + optionsscale = [osc_expandy, osc_shrinky, osc_expandshrinkx, osc_expandshrinky] + optionslayout = [lao_placex, lao_aligny] + align_glue = wam_start + place_mindist = 8 + place_maxdist = 8 + place_options = [plo_endmargin] + linktop = lab + dist_top = 8 + object cancel: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth, ow1_autosizeanright] + optionswidget = [ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + taborder = 2 + bounds_x = 333 + bounds_y = 0 + bounds_cx = 50 + bounds_cy = 22 + bounds_cxmin = 50 + state = [as_localcaption] + caption = '&Cancel' + modalresult = mr_cancel + reffontheight = 16 + end + object ok: tbutton + optionswidget1 = [ow1_fontglyphheight, ow1_autoscale, ow1_autowidth] + optionswidget = [ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + taborder = 1 + bounds_x = 275 + bounds_y = 0 + bounds_cx = 50 + bounds_cy = 22 + bounds_cxmin = 50 + state = [as_default, as_localdefault, as_localcaption] + caption = '&OK' + modalresult = mr_ok + reffontheight = 16 + end + object value: tstringedit + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_arrowfocusin, ow_arrowfocusout, ow_destroywidgets] + frame.localprops = [] + frame.localprops1 = [] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 267 + bounds_cy = 22 + anchors = [an_left, an_top, an_right] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savevalue, oe1_savestate] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 16 + end + end +end diff --git a/mseide-msegui/lib/common/dialogs/msestringenter.pas b/mseide-msegui/lib/common/dialogs/msestringenter.pas new file mode 100644 index 0000000..55937fd --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msestringenter.pas @@ -0,0 +1,110 @@ +{ MSEgui Copyright (c) 1999-2008 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msestringenter; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseforms,msedataedits,msesimplewidgets,msetypes,msegui,mseglob,mseguiglob, + msedialog,msestrings,msestringcontainer,msemenus,msesplitter,msegraphics, + msegraphutils,msewidgets,mseapplication,mseedit,mseificomp,mseificompglob, + mseifiglob,msestat,msestatfile,msestream,sysutils; + +type + tstringenterfo = class(tdialogform) + lab: tlabel; + tlayouter1: tlayouter; + cancel: tbutton; + ok: tbutton; + value: tstringedit; + procedure layoutexe(const sender: TObject); + end; + +//functions below are threadsave +function stringenter(var avalue: msestring; const text: msestring = ''; + const acaption: msestring = ''): modalresultty; + +function checkpassword(const password: msestring): boolean; overload; +function checkpassword(const password: msestring; var modalresult: modalresultty): boolean; overload; + +implementation +uses + msestringenter_mfm,msestockobjects; + +function stringenter(var avalue: msestring; const text: msestring = ''; + const acaption: msestring = ''): modalresultty; +var + fo: tstringenterfo; +begin + application.lock; + try + fo:= tstringenterfo.create(nil); + try + with fo do begin + value.value:= avalue; + caption:= acaption; + lab.caption:= text; + result:= fo.show(true,nil); + if result = mr_ok then begin + avalue:= value.value; + end; + end; + finally + fo.Free; + end; + finally + application.unlock; + end; +end; + +function checkpassword(const password: msestring; var modalresult: modalresultty): boolean; +var + fo: tstringenterfo; +begin + application.lock; + try + fo:= tstringenterfo.create(nil); + try + with fo do begin + caption:= stockobjects.captions[sc_passwordupper]; + lab.caption:= stockobjects.captions[sc_enterpassword]+':'; + value.passwordchar:= '*'; + value.value:= ''; + modalresult:= fo.show(true,nil); + result:= (modalresult = mr_ok) and (password = value.value); + if not result and (modalresult = mr_ok) then begin + showerror(stockobjects.captions[sc_invalidpassword]); + end; + end; + finally + fo.Free; + end; + finally + application.unlock; + end; +end; + +function checkpassword(const password: msestring): boolean; +var + res: modalresultty; +begin + res:= mr_none; + repeat + result:= checkpassword(password,res); + until result or (res <> mr_ok); +end; + +procedure tstringenterfo.layoutexe(const sender: TObject); +begin + optionswidget1:= optionswidget1-[ow1_autoheight]; //only on startup +end; + +end. diff --git a/mseide-msegui/lib/common/dialogs/msestringenter_mfm.pas b/mseide-msegui/lib/common/dialogs/msestringenter_mfm.pas new file mode 100644 index 0000000..627de83 --- /dev/null +++ b/mseide-msegui/lib/common/dialogs/msestringenter_mfm.pas @@ -0,0 +1,143 @@ +unit msestringenter_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msestringenter; + +const + objdata: record size: integer; data: array[0..2502] of byte end = + (size: 2503; data: ( + 84,80,70,48,14,116,115,116,114,105,110,103,101,110,116,101,114,102,111,13, + 115,116,114,105,110,103,101,110,116,101,114,102,111,14,111,112,116,105,111,110, + 115,119,105,100,103,101,116,49,11,13,111,119,49,95,97,117,116,111,115,99, + 97,108,101,14,111,119,49,95,97,117,116,111,104,101,105,103,104,116,0,13, + 111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,11,111,119,95,115,117,98,102,111,99,117,115,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,9,111,119,95,104,105,110,116,111, + 110,0,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120, + 3,84,1,8,98,111,117,110,100,115,95,121,3,67,1,9,98,111,117,110, + 100,115,95,99,120,3,142,1,9,98,111,117,110,100,115,95,99,121,2,70, + 12,98,111,117,110,100,115,95,99,120,109,105,110,3,200,0,12,98,111,117, + 110,100,115,95,99,121,109,105,110,2,70,23,99,111,110,116,97,105,110,101, + 114,46,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95, + 109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99, + 117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95, + 97,114,114,111,119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111, + 119,102,111,99,117,115,111,117,116,11,111,119,95,115,117,98,102,111,99,117, + 115,19,111,119,95,109,111,117,115,101,116,114,97,110,115,112,97,114,101,110, + 116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 29,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,102,114,97, + 109,101,105,95,98,111,116,116,111,109,2,10,26,99,111,110,116,97,105,110, + 101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 12,102,114,108,95,102,105,98,111,116,116,111,109,0,27,99,111,110,116,97, + 105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,18,99,111,110,116,97,105,110,101,114,46,111,110,108,97,121, + 111,117,116,7,9,108,97,121,111,117,116,101,120,101,16,99,111,110,116,97, + 105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0,3,142,1,2, + 70,0,7,111,112,116,105,111,110,115,11,17,102,111,95,115,99,114,101,101, + 110,99,101,110,116,101,114,101,100,13,102,111,95,99,108,111,115,101,111,110, + 101,115,99,17,102,111,95,108,111,99,97,108,115,104,111,114,116,99,117,116, + 115,15,102,111,95,97,117,116,111,114,101,97,100,115,116,97,116,16,102,111, + 95,97,117,116,111,119,114,105,116,101,115,116,97,116,0,13,119,105,110,100, + 111,119,111,112,97,99,105,116,121,5,0,0,0,0,0,0,0,128,255,255, + 8,111,110,108,97,121,111,117,116,7,9,108,97,121,111,117,116,101,120,101, + 15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101,6,8,116,109, + 115,101,102,111,114,109,0,6,116,108,97,98,101,108,3,108,97,98,14,111, + 112,116,105,111,110,115,119,105,100,103,101,116,49,11,14,111,119,49,95,97, + 117,116,111,104,101,105,103,104,116,0,13,111,112,116,105,111,110,115,119,105, + 100,103,101,116,11,13,111,119,95,109,111,117,115,101,119,104,101,101,108,17, + 111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,8,116, + 97,98,111,114,100,101,114,2,1,8,98,111,117,110,100,115,95,120,2,7, + 8,98,111,117,110,100,115,95,121,2,12,9,98,111,117,110,100,115,95,99, + 120,3,128,1,9,98,111,117,110,100,115,95,99,121,2,16,7,97,110,99, + 104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110,95,116,111,112, + 8,97,110,95,114,105,103,104,116,0,7,99,97,112,116,105,111,110,6,3, + 108,97,98,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99, + 101,110,116,101,114,101,100,12,116,102,95,119,111,114,100,98,114,101,97,107, + 0,0,0,9,116,108,97,121,111,117,116,101,114,10,116,108,97,121,111,117, + 116,101,114,49,8,98,111,117,110,100,115,95,120,2,8,8,98,111,117,110, + 100,115,95,121,2,36,9,98,111,117,110,100,115,95,99,120,3,127,1,9, + 98,111,117,110,100,115,95,99,121,2,22,7,97,110,99,104,111,114,115,11, + 7,97,110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114, + 105,103,104,116,0,12,111,112,116,105,111,110,115,115,99,97,108,101,11,11, + 111,115,99,95,101,120,112,97,110,100,121,11,111,115,99,95,115,104,114,105, + 110,107,121,17,111,115,99,95,101,120,112,97,110,100,115,104,114,105,110,107, + 120,17,111,115,99,95,101,120,112,97,110,100,115,104,114,105,110,107,121,0, + 13,111,112,116,105,111,110,115,108,97,121,111,117,116,11,10,108,97,111,95, + 112,108,97,99,101,120,10,108,97,111,95,97,108,105,103,110,121,0,10,97, + 108,105,103,110,95,103,108,117,101,7,9,119,97,109,95,115,116,97,114,116, + 13,112,108,97,99,101,95,109,105,110,100,105,115,116,2,8,13,112,108,97, + 99,101,95,109,97,120,100,105,115,116,2,8,13,112,108,97,99,101,95,111, + 112,116,105,111,110,115,11,13,112,108,111,95,101,110,100,109,97,114,103,105, + 110,0,7,108,105,110,107,116,111,112,7,3,108,97,98,8,100,105,115,116, + 95,116,111,112,2,8,0,7,116,98,117,116,116,111,110,6,99,97,110,99, + 101,108,14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111, + 119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,13,111, + 119,49,95,97,117,116,111,115,99,97,108,101,13,111,119,49,95,97,117,116, + 111,119,105,100,116,104,19,111,119,49,95,97,117,116,111,115,105,122,101,97, + 110,114,105,103,104,116,0,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119,95,97,114, + 114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119,102,111,99, + 117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117,115,111,117, + 116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95,120, + 3,77,1,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100, + 115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,22,12,98, + 111,117,110,100,115,95,99,120,109,105,110,2,50,5,115,116,97,116,101,11, + 15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,7,99,97, + 112,116,105,111,110,6,7,38,67,97,110,99,101,108,11,109,111,100,97,108, + 114,101,115,117,108,116,7,9,109,114,95,99,97,110,99,101,108,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,7,116,98,117,116, + 116,111,110,2,111,107,14,111,112,116,105,111,110,115,119,105,100,103,101,116, + 49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104,101,105,103, + 104,116,13,111,119,49,95,97,117,116,111,115,99,97,108,101,13,111,119,49, + 95,97,117,116,111,119,105,100,116,104,0,13,111,112,116,105,111,110,115,119, + 105,100,103,101,116,11,11,111,119,95,116,97,98,102,111,99,117,115,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111, + 119,102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99, + 117,115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103, + 101,116,115,0,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110, + 100,115,95,120,3,19,1,8,98,111,117,110,100,115,95,121,2,0,9,98, + 111,117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121, + 2,22,12,98,111,117,110,100,115,95,99,120,109,105,110,2,50,5,115,116, + 97,116,101,11,10,97,115,95,100,101,102,97,117,108,116,15,97,115,95,108, + 111,99,97,108,100,101,102,97,117,108,116,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,3,38,79, + 75,11,109,111,100,97,108,114,101,115,117,108,116,7,5,109,114,95,111,107, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0,0,11,116, + 115,116,114,105,110,103,101,100,105,116,5,118,97,108,117,101,13,111,112,116, + 105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115,101, + 102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111,119, + 95,97,114,114,111,119,102,111,99,117,115,15,111,119,95,97,114,114,111,119, + 102,111,99,117,115,105,110,16,111,119,95,97,114,114,111,119,102,111,99,117, + 115,111,117,116,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101, + 116,115,0,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115, + 95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,11,1,9,98,111, + 117,110,100,115,95,99,121,2,22,7,97,110,99,104,111,114,115,11,7,97, + 110,95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103, + 104,116,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101, + 49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95, + 107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,118, + 97,108,117,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0,11, + 111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111, + 111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16, + 111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111,101,95, + 115,104,105,102,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116, + 115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116, + 111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116, + 101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95, + 97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105, + 99,107,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,16,0, + 0,0,0) + ); + +initialization + registerobjectdata(@objdata,tstringenterfo,''); +end. diff --git a/mseide-msegui/lib/common/editwidgets/msecalendardatetimeedit.pas b/mseide-msegui/lib/common/editwidgets/msecalendardatetimeedit.pas new file mode 100644 index 0000000..fb403f6 --- /dev/null +++ b/mseide-msegui/lib/common/editwidgets/msecalendardatetimeedit.pas @@ -0,0 +1,182 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} + +unit msecalendardatetimeedit; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} +interface +uses + classes,mclasses,msedataedits,msepopupcalendar,msedropdownlist,msetypes, + msegraphutils, + mseguiglob,mseinplaceedit,mseedit,msestrings,msegui,mseevent,msemenus, + mseeditglob,msegraphics; + +type + tcustomcalendardatetimeedit = class(tcustomdatetimeedit,idropdowncalendar) + private + fdropdown: tcalendarcontroller; + procedure setframe(const avalue: tdropdownmultibuttonframe); + function getframe: tdropdownmultibuttonframe; + protected + function getcellframe: framety; override; + //idropdownwidget + procedure buttonaction(var action: buttonactionty; const buttonindex: integer); + procedure dobeforedropdown; + procedure doafterclosedropdown; + procedure createdropdownwidget(const atext: msestring; out awidget: twidget); + function getdropdowntext(const awidget: twidget): msestring; + function getvalueempty: integer; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property dropdown: tcalendarcontroller read fdropdown write fdropdown; + published + property frame: tdropdownmultibuttonframe read getframe write setframe; + end; + + tcalendardatetimeedit = class(tcustomcalendardatetimeedit) + published + property onsetvalue; + property value {stored false}; + property formatedit; + property formatdisp; + property valuemin {stored false}; + property valuemax {stored false}; + property kind; + property options; +{$ifdef mse_with_ifi} + property ifilink; +{$endif} + property dropdown; + end; + + +implementation +uses + sysutils,mseformatstr,msesys,msedate; + +{ tcustomcalendardatetimeedit } + +constructor tcustomcalendardatetimeedit.create(aowner: tcomponent); +begin + inherited; + fdropdown:= tcalendarcontroller.create(idropdowncalendar(self)); + fcontrollerintf:= idataeditcontroller(fdropdown); +end; + +destructor tcustomcalendardatetimeedit.destroy; +begin + fdropdown.free; + inherited; +end; + +procedure tcustomcalendardatetimeedit.setframe( + const avalue: tdropdownmultibuttonframe); +begin + inherited setframe(avalue); +end; + +function tcustomcalendardatetimeedit.getframe: tdropdownmultibuttonframe; +begin + result:= tdropdownmultibuttonframe(inherited getframe); +end; +{ +procedure tcustomcalendardatetimeedit.internalcreateframe; +begin + fdropdown.createframe; +end; + +procedure tcustomcalendardatetimeedit.dokeydown(var info: keyeventinfoty); +begin + fdropdown.dokeydown(info); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +procedure tcustomcalendardatetimeedit.domousewheelevent( + var info: mousewheeleventinfoty); +begin + fdropdown.domousewheelevent(info); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +procedure tcustomcalendardatetimeedit.mouseevent(var info: mouseeventinfoty); +begin + tcustombuttonframe(fframe).mouseevent(info); + inherited; +end; +} +procedure tcustomcalendardatetimeedit.buttonaction(var action: buttonactionty; + const buttonindex: integer); +begin + //dummy +end; + +procedure tcustomcalendardatetimeedit.dobeforedropdown; +begin + //dummy +end; + +procedure tcustomcalendardatetimeedit.doafterclosedropdown; +begin + //dummy +end; + +procedure tcustomcalendardatetimeedit.createdropdownwidget( + const atext: msestring; out awidget: twidget); +var + dat1: tdatetime; + mstr1: msestring; + bo1: boolean; +begin + bo1:= true; + mstr1:= atext; + checktext(mstr1,bo1); + if not bo1 then begin + abort; + end; + awidget:= tpopupcalendarfo.create(nil,fdropdown); + dat1:= nowlocal; + if trim(mstr1) <> '' then begin + try + dat1:= stringtodatetime(mstr1,formatedit); + except + end; + end; + with tpopupcalendarfo(awidget) do begin + formatedit:= self.formatedit; + value:= dat1; + end; +end; + +function tcustomcalendardatetimeedit.getdropdowntext( + const awidget: twidget): msestring; +begin + result:= text; +end; + +function tcustomcalendardatetimeedit.getcellframe: framety; +begin + result:= fframe.cellframe; +end; + +function tcustomcalendardatetimeedit.getvalueempty: integer; +begin + result:= -1; //dummy +end; + +end. diff --git a/mseide-msegui/lib/common/editwidgets/msedataedits.pas b/mseide-msegui/lib/common/editwidgets/msedataedits.pas new file mode 100644 index 0000000..e7402bd --- /dev/null +++ b/mseide-msegui/lib/common/editwidgets/msedataedits.pas @@ -0,0 +1,6755 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msedataedits; + +{$ifdef FPC} + {$mode objfpc}{$h+}{$goto on} +{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses,msegui,mseinplaceedit,mseeditglob,msegraphics,mseedit, + msetypes,msestrings,msedatalist,mseglob,mseguiglob,msedragglob, + mseevent,msegraphutils,msedrawtext,msestat,msestatfile,mseclasses, + msearrayprops,msegrids,msewidgetgrid,msedropdownlist,msedrag,{mseforms,} + mseformatstr,typinfo,msemenus,msebitmap,mseassistiveclient,mserichstring, + msescrollbar,msewidgets,{msepopupcalendar,}msekeyboard,msepointer,msegridsglob + {$ifdef mse_with_ifi} + ,mseificomp,mseifiglob,mseificompglob + {$endif} + ; + +const + emptyinteger = minint; + valuevarname = 'value'; + +type + tcustomdataedit = class; + + checkvalueeventty = procedure(const sender: tcustomdataedit; + const quiet: boolean; var accept: boolean) of object; + + gettexteventty = procedure(const sender: tcustomdataedit; var atext: msestring; + const aedit: boolean) of object; + settexteventty = procedure(const sender: tcustomdataedit; + var atext: msestring; var accept: boolean) of object; + textchangeeventty = procedure(const sender: tcustomdataedit; + const atext: msestring) of object; + + tcustomdataedit = class(tcustomedit,igridwidget,istatfile,idragcontroller, + iassistiveclientgridwidget + {$ifdef mse_with_ifi},iifidatalink{$endif}) + private + fontextchange: textchangeeventty; + fondataentered: notifyeventty; + foncheckvalue: checkvalueeventty; + fnullchecking: integer; + fvaluechecking: integer; + fstatfile: tstatfile; + fstatvarname: msestring; + fongettext: gettexteventty; + fonsettext: settexteventty; + fstatpriority: integer; + + procedure setstatfile(const Value: tstatfile); + function getgridrow: integer; + procedure setgridrow(const avalue: integer); + function getdisptext: msestring; + protected + fgridintf: iwidgetgrid; + fgriddatalink: pointer; + fdatalist: tdatalist; + fcontrollerintf: idataeditcontroller; + fparentintf: igridwidget; +{$ifdef mse_with_ifi} + fifilink: tifivaluelinkcomp; + function getdefaultifilink: iificlient; override; + function getifidatalinkintf: iifidatalink; override; + function getoptionsedit: optionseditty; override; + procedure dochange; override; + //iificlient + function getifidatatype(): listdatatypety override; + //iifidatalink + procedure ifisetvalue(var avalue; var accept: boolean); + procedure getifivalue(var avalue) virtual; + procedure setifivalue(const avalue) virtual; + function getifilinkkind: ptypeinfo; virtual; + procedure setifilink(const avalue: tifilinkcomp); + procedure updateifigriddata(const sender: tobject; + const alist: tdatalist); virtual; + function getgriddata: tdatalist; + function getvalueprop: ppropinfo; +{$endif} +// procedure setisdb; + procedure updatedatalist; virtual; + function geteditstate: dataeditstatesty; + procedure seteditstate(const avalue: dataeditstatesty); +// procedure updateedittext(const force: boolean); + function getgridintf: iwidgetgrid; + procedure checkgrid; + function checkgriddata: tdatalist; overload; + function checkgriddata(var index: integer): tdatalist; overload; + //index -1 -> grid.row, nil if no focused row + procedure internalgetgridvalue(index: integer; var value); + procedure internalsetgridvalue(index: integer; const Value); + procedure internalfillcol(const value); + procedure internalassigncol(const value); + function getinnerframe: framety; override; + procedure valuechanged; virtual; + procedure dotextchange; virtual; + procedure modified; virtual; //for dbedits + function gettext: msestring override; + function getedittext(): msestring override; + procedure checktext(var atext: msestring; var accept: boolean); + procedure texttovalue(var accept: boolean; + const quiet: boolean); virtual; abstract; + procedure texttodata(const atext: msestring; var data); virtual; + //used for clipboard paste in widgetgrid + function datatotext(const data): msestring; + function internaldatatotext(const data): msestring; virtual; abstract; + procedure valuetotext; + procedure setenabled(const avalue: boolean); override; +// procedure updatetextflags; override; + procedure dodefocus; override; + procedure dofocus; override; + procedure formatchanged; override; + procedure loaded; override; + procedure fontchanged; override; + procedure dofontheightdelta(var delta: integer); override; + procedure sizechanged; override; + function geteditfont: tfont; override; + class function classskininfo: skininfoty; override; + + function setdropdowntext(const avalue: msestring; const docheckvalue: boolean; + const canceled: boolean; const akey: keyty): boolean; + procedure initeditfocus; + {$ifdef mse_with_ifi} + procedure setifilink0(const avalue: tifilinkcomp); + {$endif} + + //mirrored to fcontrollerintf + procedure mouseevent(var info: mouseeventinfoty); override; + procedure dokeydown(var info: keyeventinfoty); override; + procedure internalcreateframe; override; + procedure updatereadonlystate; override; + procedure editnotification(var info: editnotificationinfoty); override; + procedure domousewheelevent(var info: mousewheeleventinfoty); override; + + //iedit + function locatecount: integer; override; //number of locate values + function locatecurrentindex: integer; override; //index of current row + procedure locatesetcurrentindex(const aindex: integer); override; + function getkeystring(const aindex: integer): msestring; override; //locate text + //igridwidget + procedure setfirstclick(var ainfo: mouseeventinfoty); virtual; + function createdatalist(const sender: twidgetcol): tdatalist; + virtual; abstract; + procedure datalistdestroyed; virtual; + function getdatalistclass: datalistclassty; virtual; abstract; + function getdefaultvalue: pointer; virtual; + function getrowdatapo(const arow: integer): pointer; virtual; + procedure setgridintf(const intf: iwidgetgrid); virtual; + function getcellframe: framety; virtual; + function needscellfocuspaint(): boolean; + function getcellcursor(const arow: integer; const acellzone: cellzonety; + const apos: pointty): cursorshapety; virtual; + procedure updatecellzone(const row: integer; const apos: pointty; + var result: cellzonety); virtual; + function getnulltext: msestring; virtual; + function getcelltext(const datapo: pointer; out empty: boolean): msestring; + function getiassistiveclient(): iassistiveclient override; + function getassistivecelltext(const arow: int32): msestring; + //iassistiveclient + function getassistiveflags(): assistiveflagsty override; + function getassistivetext(): msestring; override; + function getassistivecolumncaption(): msestring virtual; + + procedure drawcell(const canvas: tcanvas); virtual; + procedure updateautocellsize(const canvas: tcanvas); virtual; + procedure beforecelldragevent(var ainfo: draginfoty; const arow: integer; + var handled: boolean); virtual; + procedure aftercelldragevent(var ainfo: draginfoty; const arow: integer; + var handled: boolean); virtual; + procedure valuetogrid(row: integer); virtual; abstract; + procedure gridtovalue(row: integer); virtual; + procedure setvaluedata(const source); virtual; abstract; + procedure getvaluedata(out dest); virtual; abstract; + procedure docellevent(const ownedcol: boolean; + var info: celleventinfoty); virtual; + function sortfunc(const l,r): integer; virtual; + procedure gridvaluechanged(const index: integer); virtual; + procedure updatecoloptions(const aoptions: coloptionsty); + procedure updatecoloptions1(const aoptions: coloptions1ty); + procedure setoptionsedit(const avalue: optionseditty); override; + procedure setoptionsedit1(const avalue: optionsedit1ty); override; + procedure statdataread; virtual; + procedure griddatasourcechanged; virtual; + {$ifdef mse_with_ifi} + function getifilink: tifilinkcomp; + {$endif} + procedure setparentgridwidget(const intf: igridwidget); + procedure childdataentered(const sender: igridwidget); virtual; + procedure childfocused(const sender: igridwidget); virtual; + + procedure formaterror(const quiet: boolean); + procedure rangeerror(const min,max; const quiet: boolean); + procedure notnullerror(const quiet: boolean); + + procedure doafterpaint(const canvas: tcanvas); override; + function needsfocuspaint: boolean; override; + + //istatfile + procedure dostatread(const reader: tstatreader); virtual; + procedure dostatwrite(const writer: tstatwriter); virtual; + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + + procedure readstatvalue(const reader: tstatreader); virtual; + procedure readstatstate(const reader: tstatreader); virtual; + procedure readstatoptions(const reader: tstatreader); virtual; + procedure writestatvalue(const writer: tstatwriter); virtual; + procedure writestatstate(const writer: tstatwriter); virtual; + procedure writestatoptions(const writer: tstatwriter); virtual; + + function cangridcopy: boolean; override; + function isempty (const atext: msestring): boolean; virtual; + procedure nullvalueset; + procedure setnullvalue; virtual; //for dbedits + function nullcheckneeded(const newfocus: twidget): boolean; virtual; + function textcellcopy: boolean; virtual; + function getedited: boolean; override; + procedure setedited(const avalue: boolean); virtual; + public + + procedure initnewwidget(const ascale: real); override; + procedure initgridwidget; virtual; + procedure paint(const canvas: tcanvas); override; + procedure synctofontheight; override; + function actualcolor: colorty; override; + function actualcursor(const apos: pointty): cursorshapety; override; + function widgetcol: twidgetcol; + function grid: tcustomwidgetgrid; + property gridrow: integer read getgridrow write setgridrow; + //returns -1 if no grid, setting ignored if no grid + function gridrowhigh: int32; //-1 if no grid + function griddatarowhigh: int32; //-1 if no grid + function gridcol: integer; + function griddata: tdatalist; + property gridintf: iwidgetgrid read fgridintf; + function textclipped(const arow: integer; + out acellrect: rectty): boolean; virtual; + function textclipped(const arow: integer): boolean; + + function checkvalue(const quiet: boolean = false): boolean; virtual; + function canclose(const newfocus: twidget): boolean; override; + property edited: boolean read getedited write setedited; + function emptytext: boolean; + function seteditfocus: boolean; + function isnull: boolean; virtual; + + property disptext: msestring read getdisptext; + property dataeditstate: dataeditstatesty read fstate; + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read getstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + property oncheckvalue: checkvalueeventty read foncheckvalue + write foncheckvalue; + property ondataentered: notifyeventty read fondataentered + write fondataentered; + property ongettext: gettexteventty read fongettext write fongettext; + property onsettext: settexteventty read fonsettext write fonsettext; + property ontextchange: textchangeeventty read fontextchange + write fontextchange; + end; + + dataediteventty = procedure(const sender: tcustomdataedit) of object; + + tdataedit = class(tcustomdataedit) + published + property statfile; + property statvarname; + property statpriority; + property empty_color; + property empty_font; + property empty_fontstyle; + property empty_textflags; + property empty_text; + property empty_options; + property empty_textcolor; + property empty_textcolorbackground; + + property optionsedit1; //before optionsedit! + property optionsedit; + property font; + property textflags; + property textflagsactive; + property caretwidth; + property cursorreadonly; + property onchange; + property ontextchange; + property onkeydown; + property onkeyup; + property onmouseevent; + property onclientmouseevent; + property onmousewheelevent; + property oncopytoclipboard; + property onpastefromclipboard; + + property ontextedited; + property oncheckvalue; + property ondataentered; + property ongettext; + property onsettext; + end; + + tcustomstringedit = class(tdataedit) + private + fonsetvalue: setstringeventty; + procedure setvalue(const Value: msestring); + function getgridvalue(const index: integer): msestring; + procedure setgridvalue(const index: integer; const Value: msestring); + function getgridvalues: msestringarty; + procedure setgridvalues(const Value: msestringarty); + {$ifdef mse_with_ifi} + function getifilink: tifistringlinkcomp; + procedure setifilink(const avalue: tifistringlinkcomp); + {$endif} + protected + fvalue: msestring; + fvaluedefault: msestring; + procedure setvaluedata(const source); override; + procedure getvaluedata(out dest); override; + function getvaluetext: msestring; virtual; + procedure updatedisptext(var avalue: msestring); virtual; + + procedure dosetvalue(var avalue: msestring; var accept: boolean); virtual; + procedure texttovalue(var accept: boolean; const quiet: boolean); override; + function internaldatatotext(const data): msestring; override; + procedure texttodata(const atext: msestring; var data); override; + function createdatalist(const sender: twidgetcol): tdatalist; override; + function getdatalistclass: datalistclassty; override; + procedure valuetogrid(arow: integer); override; + procedure gridtovalue(arow: integer); override; + procedure readstatvalue(const reader: tstatreader); override; + procedure writestatvalue(const writer: tstatwriter); override; + function sortfunc(const l,r): integer; override; + function getdefaultvalue: pointer; override; + + public + function checkvalue(const quiet: boolean = false): boolean; override; + function isnull: boolean; override; + procedure dragevent(var info: draginfoty); override; + procedure fillcol(const value: msestring); + procedure assigncol(const value: tmsestringdatalist); + property onsetvalue: setstringeventty read fonsetvalue write fonsetvalue; + property value: msestring read fvalue write setvalue; + property valuedefault: msestring read fvaluedefault write fvaluedefault; + property gridvalue[const index: integer]: msestring + read getgridvalue write setgridvalue; default; + property gridvalues: msestringarty read getgridvalues write setgridvalues; + function griddata: tgridmsestringdatalist; +{$ifdef mse_with_ifi} + property ifilink: tifistringlinkcomp read getifilink write setifilink; +{$endif} + end; + + tstringedit = class(tcustomstringedit) + published + property passwordchar; + property maxlength; + property value; + property valuedefault; + property onsetvalue; +{$ifdef mse_with_ifi} + property ifilink; +{$endif} + end; + +const + defaultmemotextflags = (defaulttextflags - [tf_ycentered]) + [tf_wordbreak]; + defaultmemotextflagsactive = (defaulttextflagsactive - [tf_ycentered]) + + [tf_wordbreak]; + defaultmemooptionsedit = (defaultoptionsedit - + [oe_undoonesc,oe_exitoncursor,oe_shiftreturn, + oe_endonenter,oe_homeonenter, + oe_autoselect,oe_autoselectonfirstclick]) + + [oe_linebreak,oe_nofirstarrownavig]; + defaultmemooptionsedit1 = defaultoptionsedit1 + [oe1_multiline]; + +type + + tcustommemoedit = class(tcustomstringedit,iscrollbar) + private + ftextrectbefore: rectty; + fclientsizebefore: sizety; + fcreated: boolean; + fxpos: integer; + fupdatescrollbarcount: integer; + function getframe: tscrolleditframe; + procedure setframe(const avalue: tscrolleditframe); + procedure updatescrollbars; + protected + procedure setupeditor; override; + procedure editnotification(var info: editnotificationinfoty); override; + procedure internalcreateframe; override; + procedure mouseevent(var info: mouseeventinfoty); override; + procedure domousewheelevent(var info: mousewheeleventinfoty); override; + procedure dokeydown(var info: keyeventinfoty); override; + function getnoscroll(): boolean override; + //iscrollbar + procedure scrollevent(sender: tcustomscrollbar; event: scrolleventty); + public + constructor create(aowner: tcomponent); override; + procedure afterconstruction; override; + property frame: tscrolleditframe read getframe write setframe; + property textflags default defaultmemotextflags; + property textflagsactive default defaultmemotextflagsactive; + published + property optionsedit default defaultmemooptionsedit; + property optionsedit1 default defaultmemooptionsedit1; + property optionswidget default defaultoptionswidgetmousewheel; + end; + + tmemoedit = class(tcustommemoedit) + published + property value; + property valuedefault; + property onsetvalue; + property frame; + property textflags; + property textflagsactive; +{$ifdef mse_with_ifi} + property ifilink; +{$endif} + end; + + tcustomrichmemoedit = class(tcustommemoedit,irichstringprop) + private + procedure readrichvalue(reader: treader); + procedure writerichvalue(writer: twriter); + protected + fformat: formatinfoarty; + frichflags: richflagsty; + function getformat: formatinfoarty override; + procedure setformat(const avalue: formatinfoarty); + procedure defineproperties(filer: tfiler) override; + //irichstringprop + function getrichvalue(): richstringty; + procedure setrichvalue(const avalue: richstringty); + public + property value stored false; + property richvalue: richstringty read getrichvalue write setrichvalue; + property formatvalue: formatinfoarty read fformat write setformat; + end; + + trichmemoedit = class(tcustomrichmemoedit) + published + property value; + property valuedefault; + property onsetvalue; + property frame; + property textflags; + property textflagsactive; +{$ifdef mse_with_ifi} + property ifilink; +{$endif} + end; + + thexstringedit = class(tdataedit) + private + fonsetvalue: setansistringeventty; + procedure setvalue(const Value: string); + function getgridvalue(const index: integer): ansistring; + procedure setgridvalue(const index: integer; const Value: ansistring); + function getgridvalues: stringarty; + procedure setgridvalues(const Value: stringarty); + protected + fvalue: ansistring; + procedure setvaluedata(const source); override; + procedure getvaluedata(out dest); override; + procedure dosetvalue(var avalue: ansistring; var accept: boolean); virtual; + procedure texttovalue(var accept: boolean; const quiet: boolean); override; + function internaldatatotext(const data): msestring; override; + function createdatalist(const sender: twidgetcol): tdatalist; override; + function getdatalistclass: datalistclassty; override; + procedure valuetogrid(arow: integer); override; + procedure gridtovalue(arow: integer); override; + procedure readstatvalue(const reader: tstatreader); override; + procedure writestatvalue(const writer: tstatwriter); override; + function sortfunc(const l,r): integer; override; + public + procedure fillcol(const value: string); + procedure assigncol(const value: tansistringdatalist); + property gridvalue[const index: integer]: ansistring + read getgridvalue write setgridvalue; default; + property gridvalues: stringarty read getgridvalues write setgridvalues; + function griddata: tgridansistringdatalist; + published + property value: ansistring read fvalue write setvalue; + property onsetvalue: setansistringeventty read fonsetvalue write fonsetvalue; + end; + +const + defaultenumdropdownoptions = [deo_selectonly,deo_autodropdown,deo_keydropdown]; + defaultkeystringdropdownoptions = [deo_selectonly,deo_autodropdown,deo_keydropdown]; + +type + + tcustomdropdownedit = class(tcustomstringedit,idropdown + {$ifdef mse_with_ifi},iifidropdownlistdatalink{$endif}) + private + fonbeforedropdown: notifyeventty; + fonafterclosedropdown: notifyeventty; + function getframe: tdropdownmultibuttonframe; + procedure setframe(const avalue: tdropdownmultibuttonframe); + protected + fdropdown: tcustomdropdowncontroller; + function createdropdowncontroller: tcustomdropdowncontroller; virtual; + procedure loaded() override; + procedure texttovalue(var accept: boolean; const quiet: boolean); override; + procedure dohide; override; + function getassistiveflags(): assistiveflagsty override; +// function getassistivecaption(): msestring override; +// function getassistivetext(): msestring override; + {$ifdef mse_with_ifi} + function getifidatalinkintf: iifidatalink; override; + //iifidropdownlistdatalink + procedure ifidropdownlistchanged(const acols: tifidropdowncols); + {$endif} + //idropdown + procedure buttonaction(var action: buttonactionty; const buttonindex: integer); virtual; + procedure dobeforedropdown; virtual; + procedure doafterclosedropdown; virtual; + function getvalueempty: integer; virtual; + procedure dostatread(const reader: tstatreader); override; + procedure dostatwrite(const writer: tstatwriter); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property onbeforedropdown: notifyeventty read fonbeforedropdown write fonbeforedropdown; + property onafterclosedropdown: notifyeventty read fonafterclosedropdown + write fonafterclosedropdown; + published + property frame: tdropdownmultibuttonframe read getframe write setframe; + end; + + tcustomdropdownwidgetedit = class(tcustomdropdownedit,idropdownwidget) + private + function getdropdown: tdropdownwidgetcontroller; + procedure setdropdown(const avalue: tdropdownwidgetcontroller); + protected + function createdropdowncontroller: tcustomdropdowncontroller; override; + //idropdownwidget + procedure createdropdownwidget(const atext: msestring; + out awidget: twidget); virtual; abstract; + function getdropdowntext(const awidget: twidget): msestring; virtual; abstract; + public + property dropdown: tdropdownwidgetcontroller read getdropdown + write setdropdown; + end; + + tdropdownwidgetedit = class(tcustomdropdownwidgetedit) + published + property value; + property valuedefault; +{$ifdef mse_with_ifi} + property ifilink; +{$endif} + property dropdown; + property onsetvalue; + property onbeforedropdown; + property onafterclosedropdown; + end; + + tcustomdropdownlistedit = class(tcustomdropdownedit,idropdownlist + {$ifdef mse_with_ifi},iifidropdownlistdatalink{$endif}) + private + procedure setdropdown(const avalue: tdropdownlistcontroller); + function getdropdown: tdropdownlistcontroller; + {$ifdef mse_with_ifi} + function getifilink: tifidropdownlistlinkcomp; + procedure setifilink1(const avalue: tifidropdownlistlinkcomp); + procedure ifidropdownlistchanged(const acols: tifidropdowncols); + {$endif} + protected + //idropdownlist + procedure imagelistchanged; + procedure paintimage(const canvas: tcanvas); override; + procedure dochange; override; + {$ifdef mse_with_ifi} + function getifidatalinkintf: iifidatalink; override; + //iifidatalink + function getifilinkkind: ptypeinfo; override; + {$endif} + //idropdownlist + function getdropdownitems: tdropdowndatacols; virtual; + function createdropdowncontroller: tcustomdropdowncontroller; override; + procedure internalsort(const acol: integer; + out sortlist: integerarty); virtual; + function geteditframe: framety; override; + procedure getautopaintsize(var asize: sizety); override; + public + procedure sort(const acol: integer = 0); + property dropdown: tdropdownlistcontroller read getdropdown write setdropdown; +{$ifdef mse_with_ifi} + property ifilink: tifidropdownlistlinkcomp read getifilink write setifilink1; +{$endif} + end; + + tdropdownlistedit = class(tcustomdropdownlistedit) + published + property maxlength; + property value; + property valuedefault; + property onsetvalue; +{$ifdef mse_with_ifi} + property ifilink; +{$endif} + property dropdown; + property onbeforedropdown; + property onafterclosedropdown; + end; + +const + defaulthistorymaxcount = 20; + defaulthistoryeditoptions = defaultdropdownoptionsedit + [deo_autosavehistory]; + +type + + thistorycontroller = class(tdropdownlistcontroller) + private + fhistorymaxcount: integer; + procedure sethistorymaxcount(const avalue: integer); + function gethistory: msestringarty; + procedure sethistory(const avalue: msestringarty); + protected + procedure checkmaxcount; + public + constructor create(const intf: idropdownlist); + procedure readstate(const reader: tstatreader); + procedure writestate(const writer: tstatwriter); + procedure savehistoryvalue(const avalue: msestring); + property history: msestringarty read gethistory write sethistory; + published + property dropdownrowcount; //first + property delay; + property historymaxcount: integer read fhistorymaxcount + write sethistorymaxcount default defaulthistorymaxcount; + procedure clearhistory; + property options default defaulthistoryeditoptions; + property width; + property cols; + end; + + tcustomhistoryedit = class(tcustomdropdownlistedit) + private + procedure setdropdown(const avalue: thistorycontroller); + function getdropdown: thistorycontroller; + protected + procedure texttovalue(var accept: boolean; const quiet: boolean); override; + procedure loaded; override; + procedure readstatstate(const reader: tstatreader); override; + procedure writestatstate(const writer: tstatwriter); override; + function createdropdowncontroller: tcustomdropdowncontroller; override; + public + constructor create(aowner: tcomponent); override; + procedure savehistoryvalue; + property dropdown: thistorycontroller read getdropdown write setdropdown; + end; + + thistoryedit = class(tcustomhistoryedit) + published + property maxlength; + property value; + property valuedefault; + property onsetvalue; +{$ifdef mse_with_ifi} + property ifilink; +{$endif} + property dropdown; + property onbeforedropdown; + property onafterclosedropdown; + + end; + +const + defaultnumedittextflags = defaulttextflags + [tf_right]; + +type + + tnumedit = class(tdataedit) + public + constructor create(aowner: tcomponent); override; + published + property textflags default defaultnumedittextflags; + end; + + tcustomintegeredit = class(tnumedit) + private + fonsetvalue: setintegereventty; + fvalue: integer; + fbase: numbasety; + fbitcount: integer; + fvaluemin: integer; + fvaluemax: integer; + fvaluedefault: integer; + procedure setvalue(const Value: integer); + procedure setbase(const Value: numbasety); + procedure setbitcount(const Value: integer); + function getgridvalue(const index: integer): integer; + procedure setgridvalue(const index, Value: integer); + function getgridvalues: integerarty; + procedure setgridvalues(const Value: integerarty); + {$ifdef mse_with_ifi} + function getifilink: tifiintegerlinkcomp; + procedure setifilink(const avalue: tifiintegerlinkcomp); + {$endif} + procedure setvaluemin(const avalue: integer); + procedure setvaluemax(const avalue: integer); + procedure readmin(reader: treader); + procedure readmax(reader: treader); + protected + fisnull: boolean; //used in tdbintegeredit + procedure setvaluedata(const source); override; + procedure getvaluedata(out dest); override; + function gettextvalue(var accept: boolean; const quiet: boolean): integer; + procedure texttovalue(var accept: boolean; const quiet: boolean); override; + function internaldatatotext(const data): msestring; override; + procedure texttodata(const atext: msestring; var data); override; + function createdatalist(const sender: twidgetcol): tdatalist; override; + function getdatalistclass: datalistclassty; override; + procedure valuetogrid(arow: integer); override; + procedure gridtovalue(arow: integer); override; + procedure readstatvalue(const reader: tstatreader); override; + procedure writestatvalue(const writer: tstatwriter); override; + procedure setnullvalue; override; + function getdefaultvalue: pointer; override; + procedure updatedatalist; override; + procedure defineproperties(filer: tfiler) override; + public + constructor create(aowner: tcomponent); override; + procedure fillcol(const value: integer); + procedure assigncol(const value: tintegerdatalist); + property onsetvalue: setintegereventty read fonsetvalue write fonsetvalue; + property value: integer read fvalue write setvalue default 0; + property valuedefault: integer read fvaluedefault + write fvaluedefault default 0; + property base: numbasety read fbase write setbase default nb_dec; + property bitcount: integer read fbitcount write setbitcount default 32; + property valuemin: integer read fvaluemin write setvaluemin default 0; + property valuemax: integer read fvaluemax write setvaluemax default maxint; + + property gridvalue[const index: integer]: integer + read getgridvalue write setgridvalue; default; + property gridvalues: integerarty read getgridvalues write setgridvalues; + function griddata: tgridintegerdatalist; +{$ifdef mse_with_ifi} + property ifilink: tifiintegerlinkcomp read getifilink write setifilink; +{$endif} + end; + + tintegeredit = class(tcustomintegeredit) + published + property onsetvalue; + property value; + property valuedefault; + property base; + property bitcount; + property valuemin; + property valuemax; + {$ifdef mse_with_ifi} + property ifilink; + {$endif} + end; + + tcustomint64edit = class(tnumedit) + private + fonsetvalue: setint64eventty; + fvalue: int64; + fbase: numbasety; + fbitcount: integer; + fvaluemin: int64; + fvaluemax: int64; + fvaluedefault: int64; + procedure setvalue(const Value: int64); + procedure setbase(const Value: numbasety); + procedure setbitcount(const Value: integer); + function getgridvalue(const index: integer): int64; + procedure setgridvalue(const index: integer; const Value: int64); + function getgridvalues: int64arty; + procedure setgridvalues(const Value: int64arty); +// procedure setmin(const avalue: int64); +// procedure setmax(const avalue: int64); + {$ifdef mse_with_ifi} + function getifilink: tifiint64linkcomp; + procedure setifilink(const avalue: tifiint64linkcomp); + {$endif} + procedure readmin(reader: treader); + procedure readmax(reader: treader); + protected + fisnull: boolean; //used in tdbintegeredit + procedure defineproperties(filer: tfiler) override; + procedure setvaluedata(const source); override; + procedure getvaluedata(out dest); override; + procedure texttovalue(var accept: boolean; const quiet: boolean); override; + function internaldatatotext(const data): msestring; override; + procedure texttodata(const atext: msestring; var data); override; + function createdatalist(const sender: twidgetcol): tdatalist; override; + function getdatalistclass: datalistclassty; override; + procedure valuetogrid(arow: integer); override; + procedure gridtovalue(arow: integer); override; + procedure readstatvalue(const reader: tstatreader); override; + procedure writestatvalue(const writer: tstatwriter); override; + procedure setnullvalue; override; + function getdefaultvalue: pointer; override; +// procedure updatedatalist; override; + public + constructor create(aowner: tcomponent); override; + procedure fillcol(const value: int64); + procedure assigncol(const value: tint64datalist); + property onsetvalue: setint64eventty read fonsetvalue write fonsetvalue; + property value: int64 read fvalue write setvalue default 0; + property valuedefault: int64 read fvaluedefault write fvaluedefault default 0; + property base: numbasety read fbase write setbase default nb_dec; + property bitcount: integer read fbitcount write setbitcount default 64; + property valuemin: int64 read fvaluemin write fvaluemin{setmin} default 0; + property valuemax: int64 read fvaluemax write fvaluemax{setmax}; + // {$ifdef FPC}default maxint64{$endif}; + + property gridvalue[const index: integer]: int64 + read getgridvalue write setgridvalue; default; + property gridvalues: int64arty read getgridvalues write setgridvalues; + function griddata: tgridint64datalist; +{$ifdef mse_with_ifi} + property ifilink: tifiint64linkcomp read getifilink write setifilink; +{$endif} + end; + + tint64edit = class(tcustomint64edit) + published + property onsetvalue; + property value; + property valuedefault; + property base; + property bitcount; + property valuemin; + property valuemax; + {$ifdef mse_with_ifi} + property ifilink; + {$endif} + end; + + tkeystringdropdowncontroller = class(tdropdownlistcontroller) + protected + public + constructor create(const intf: idropdownlist); + function getindex(const akey: msestring): integer; + //todo: non linear search + published + property options default defaultkeystringdropdownoptions; + property valuecol default 1; + end; + + tcustomkeystringedit = class; + keystringediteventty = procedure(const sender: tcustomkeystringedit) of object; + + tcustomkeystringedit = class(tcustomdropdownlistedit) + private +// fvaluedefault: msestring; + foninit: keystringediteventty; + protected + fvalue1: msestring; + procedure setvalue(const avalue: msestring); + procedure setvaluedata(const source); override; + procedure getvaluedata(out dest); override; + function createdropdowncontroller: tcustomdropdowncontroller; override; + procedure texttovalue(var accept: boolean; const quiet: boolean); override; + procedure setnullvalue; override; //for dbedits + function internaldatatotext(const data): msestring; override; + procedure texttodata(const atext: msestring; var data); override; +// function getdefaultvalue: pointer; override; + procedure valuetogrid(arow: integer); override; + procedure gridtovalue(arow: integer); override; + + procedure readstatvalue(const reader: tstatreader); override; + procedure writestatvalue(const writer: tstatwriter); override; + procedure loaded; override; + public + property value: msestring read fvalue1 write setvalue; +// property valuedefault: msestring read fvaluedefault write fvaluedefault; + property oninit: keystringediteventty read foninit write foninit; + end; + + + tkeystringedit = class(tcustomkeystringedit) + published + property value; + property valuedefault; + property onsetvalue; +{$ifdef mse_with_ifi} + property ifilink; +{$endif} + property dropdown; + property onbeforedropdown; + property onafterclosedropdown; + property oninit; + end; + + tnocolsenumdropdowncontroller = class(tnocolsdropdownlistcontroller) + private + procedure readitemindex(reader: treader); + protected + procedure defineproperties(filer: tfiler); override; + public + constructor create(const intf: idropdownlist); + published + property options default defaultenumdropdownoptions; + property imagelist; + property imageframe_left; + property imageframe_top; + property imageframe_right; + property imageframe_bottom; +// property valuecol; +// property itemindex; + end; + + tenumdropdowncontroller = class(tnocolsenumdropdowncontroller) + public + constructor create(const intf: idropdownlist); + published + property cols; + property valuecol; //after cols + end; + + tcustomenuedit = class(tcustomdropdownlistedit) + private + fbitcount: integer; + fbase: numbasety; + fvaluemin,fvaluemax: integer; + fvalueoffset: integer; + function getgridvalue(const index: integer): integer; + procedure setgridvalue(const index, aValue: integer); + function getgridvalues: integerarty; + procedure setgridvalues(const avalue: integerarty); + function getindex(avalue: integer): integer; + procedure setbase(const avalue: numbasety); + procedure setbitcount(const avalue: integer); + procedure setvalueoffset(avalue: integer); + {$ifdef mse_with_ifi} + function getifilink: tifienumlinkcomp; + procedure setifilink1(const avalue: tifienumlinkcomp); + {$endif} + procedure setvaluemin(const avalue: integer); + procedure setvaluemax(const avalue: integer); + function getdropdown: tenumdropdowncontroller; + procedure setdropdown(const avalue: tenumdropdowncontroller); + procedure readmin(reader: treader); + procedure readmax(reader: treader); + protected + fonsetvalue1: setintegereventty; + fvalue1: integer; + fvaluedefault1: integer; + fvalueempty: integer; + procedure setvalue(const avalue: integer); + procedure setvaluedata(const source); override; + procedure getvaluedata(out dest); override; + procedure setnullvalue; override; //for dbedits + function createdatalist(const sender: twidgetcol): tdatalist; override; + function getdatalistclass: datalistclassty; override; + function getdefaultvalue: pointer; override; + procedure texttovalue(var accept: boolean; const quiet: boolean); override; + procedure texttodata(const atext: msestring; var data); override; + function internaldatatotext(const data): msestring; override; + procedure valuetogrid(arow: integer); override; + procedure gridtovalue(arow: integer); override; + procedure readstatvalue(const reader: tstatreader); override; + procedure writestatvalue(const writer: tstatwriter); override; + function createdropdowncontroller: tcustomdropdowncontroller; override; + procedure internalsort(const acol: integer; + out sortlist: integerarty); override; + function sortfunc(const l,r): integer; override; + + function getvalueempty: integer; override; + function textcellcopy: boolean; override; + procedure updatedatalist; override; + procedure paintimage(const canvas: tcanvas); override; + procedure defineproperties(filer: tfiler) override; + public + enums: integerarty; //nil -> enum = item rowindex + valueoffset + constructor create(aowner: tcomponent); override; + procedure clear; + function enumname(const avalue: integer): msestring; + function addrow(const aitems: array of msestring; + const enum: integer = -1): integer; //returns itemindex + //enum = -1 -> no enum set + procedure fillcol(const avalue: integer); + procedure assigncol(const avalue: tintegerdatalist); + property valueoffset: integer read fvalueoffset write setvalueoffset default 0; + //before value + property value: integer read fvalue1 write setvalue default -1; + property valuedefault: integer read fvaluedefault1 + write fvaluedefault1 default -1; + property valueempty: integer read fvalueempty write fvalueempty default -1; + property base: numbasety read fbase write setbase default nb_dec; + property bitcount: integer read fbitcount write setbitcount default 32; + property valuemin: integer read fvaluemin write setvaluemin default -1; + property valuemax: integer read fvaluemax write setvaluemax default maxint; + property gridvalue[const index: integer]: integer + read getgridvalue write setgridvalue; default; + property gridvalues: integerarty read getgridvalues write setgridvalues; + function griddata: tgridenumdatalist; + property dropdown: tenumdropdowncontroller read getdropdown + write setdropdown; + property onsetvalue: setintegereventty read fonsetvalue1 write fonsetvalue1; +{$ifdef mse_with_ifi} + property ifilink: tifienumlinkcomp read getifilink write setifilink1; +{$endif} + end; + + tcustomenumedit = class; + enumediteventty = procedure (const sender: tcustomenumedit) of object; + + tcustomenumedit = class(tcustomenuedit) + private + foninit: enumediteventty; + protected + procedure loaded; override; + public + property oninit: enumediteventty read foninit write foninit; + end; + + tenumedit = class(tcustomenumedit) + published + property dropdown; //first + property valueoffset; //before value + property value; + property valuedefault; + property valueempty; + property base; + property bitcount; + property valuemin; + property valuemax; + property onsetvalue; +{$ifdef mse_with_ifi} + property ifilink; +{$endif} + property onbeforedropdown; + property onafterclosedropdown; + property oninit; + end; + + tenumtypeedit = class; + enumtypeediteventty = procedure (const sender: tenumtypeedit) of object; + + tenumtypeedit = class(tcustomenumedit) + private + ftypeinfopo: ptypeinfo; + procedure settypeinfopo(const avalue: ptypeinfo); + procedure setoninit(const aValue: enumtypeediteventty); + function getoninit: enumtypeediteventty; + protected + public + property typeinfopo: ptypeinfo read ftypeinfopo write settypeinfopo; + published + property value; + property valuedefault; + property base; + property bitcount; + property valuemin; + property valuemax; + property onsetvalue; +{$ifdef mse_with_ifi} + property ifilink; +{$endif} + property dropdown; + property onbeforedropdown; + property onafterclosedropdown; + property oninit: enumtypeediteventty read getoninit write setoninit; + end; + + tcustomselector = class(tcustomenuedit) + private + fdropdownitems: tdropdowndatacols; + fdropdownenums: integerarty; + protected + procedure texttovalue(var accept: boolean; const quiet: boolean); override; + procedure dobeforedropdown; override; + procedure getdropdowninfo(var aenums: integerarty; + const names: tdropdowndatacols); virtual; abstract; + function getdropdownitems: tdropdowndatacols; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + end; + + tselector = class; + selectoreventty = procedure (const sender: tselector) of object; + + tselector = class(tcustomselector) + private + fongetdropdowninfo: selectoreventty; + foninit: selectoreventty; + procedure setdropdownitems(const avalue: tdropdowndatacols); + protected + procedure getdropdowninfo(var aenums: integerarty; + const names: tdropdowndatacols); override; + procedure loaded; override; + public + published + property dropdownitems: tdropdowndatacols read getdropdownitems + write setdropdownitems; + property ongetdropdowninfo: selectoreventty read fongetdropdowninfo + write fongetdropdowninfo; + property oninit: selectoreventty read foninit write foninit; + property valueoffset; //before value + property value; + property onsetvalue; +{$ifdef mse_with_ifi} + property ifilink; +{$endif} + property dropdown; + property onbeforedropdown; + property onafterclosedropdown; + end; + + gettypeeventty = procedure(const sender: tobject; var atype: ptypeinfo) of object; + + tcustomrealedit = class(tnumedit) + private + fonsetvalue: setrealeventty; + fonsetintvalue: setintegereventty; + fformatdisp: msestring; + fformatedit: msestring; + fvaluerange: real; + fvaluestart: real; + procedure setvalue(const Value: realty); + procedure setformatdisp(const Value: msestring); + procedure setformatedit(const Value: msestring); + procedure readvalue(reader: treader); + procedure readvaluedefault(reader: treader); + procedure readmin1(reader: treader); + procedure readmax1(reader: treader); + function getgridvalue(const index: integer): realty; + function getgridintvalue(const index: integer): integer; + procedure setgridvalue(const index: integer; const avalue: realty); + procedure setgridintvalue(const index: integer; const avalue: integer); + function getgridvalues: realarty; + function getgridintvalues: integerarty; + procedure setgridvalues(const avalue: realarty); + procedure setgridintvalues(const avalue: integerarty); + procedure setvaluerange(const avalue: real); + procedure setvaluestart(const avalue: real); + function getasinteger: integer; + procedure setasinteger(const avalue: integer); + function getascurrency: currency; + procedure setascurrency(const avalue: currency); + procedure readvaluescale(reader: treader); + {$ifdef mse_with_ifi} + function getifilink: tifireallinkcomp; + procedure setifilink(const avalue: tifireallinkcomp); + {$endif} + function getasstring: msestring; + procedure setasstring(const avalue: msestring); + function getintvalue: integer; + procedure setintvalue(const avalue: integer); + procedure readmin(reader: treader); + procedure readmax(reader: treader); + protected + fvalue: realty; + fvaluedefault: realty; + fvaluemin: realty; + fvaluemax: realty; + procedure setvaluedata(const source); override; + procedure getvaluedata(out dest); override; + procedure updatedatalist; override; + procedure setvaluemin(const avalue: realty); virtual; + procedure setvaluemax(const avalue: realty); virtual; + function gettextvalue(var accept: boolean; + const quiet: boolean): realty; virtual; + procedure texttovalue(var accept: boolean; const quiet: boolean); override; + function internaldatatotext(const data): msestring; override; + procedure texttodata(const atext: msestring; var data); override; + function createdatalist(const sender: twidgetcol): tdatalist; override; + function getdatalistclass: datalistclassty; override; + procedure valuetogrid(arow: integer); override; + procedure gridtovalue(arow: integer); override; + procedure defineproperties(filer: tfiler); override; + procedure readstatvalue(const reader: tstatreader); override; + procedure writestatvalue(const writer: tstatwriter); override; + function getdefaultvalue: pointer; override; + procedure setnullvalue(); override; + procedure updatereadonlystate(); override; + public + constructor create(aowner: tcomponent); override; +// function griddata: trealdatalist; + procedure fillcol(const value: realty); + procedure assigncol(const value: trealdatalist); + function isnull: boolean; override; + property asstring: msestring read getasstring write setasstring; + property asinteger: integer read getasinteger write setasinteger; + //returns minint for empty value + property ascurrency: currency read getascurrency write setascurrency; + property onsetvalue: setrealeventty read fonsetvalue write fonsetvalue; + property onsetintvalue: setintegereventty read fonsetintvalue + write fonsetintvalue; + //overrides onsetvalue + property value: realty read fvalue write setvalue {stored false}; + property intvalue: integer read getintvalue write setintvalue; + property valuedefault: realty read fvaluedefault + write fvaluedefault {stored false}; + property formatedit: msestring read fformatedit write setformatedit; + property formatdisp: msestring read fformatdisp write setformatdisp; + property valuerange: real read fvaluerange write setvaluerange; + property valuestart: real read fvaluestart write setvaluestart; + property valuemin: realty read fvaluemin write setvaluemin; + property valuemax: realty read fvaluemax write setvaluemax; + property gridvalue[const index: integer]: realty + read getgridvalue write setgridvalue; default; + property gridintvalue[const index: integer]: integer + read getgridintvalue write setgridintvalue; + property gridvalues: realarty read getgridvalues write setgridvalues; + property gridintvalues: integerarty read getgridintvalues + write setgridintvalues; + function griddata: tgridrealdatalist; +{$ifdef mse_with_ifi} + property ifilink: tifireallinkcomp read getifilink write setifilink; +{$endif} + published + property optionswidget default defaulteditwidgetoptions + [ow_mousewheel]; //first! + end; + + trealedit = class(tcustomrealedit) + published + property onsetvalue; + property onsetintvalue; + property value; + property valuedefault; + property formatedit; + property formatdisp; + property valuerange; + property valuestart; + property valuemin; + property valuemax; + {$ifdef mse_with_ifi} + property ifilink; + {$endif} + end; + +const + spinstepbuttons = [sk_up,sk_down,sk_first,sk_last]; + +type + tspineditframe = class(tcustomstepframe) + private + procedure setbuttonsvisible(const avalue: stepkindsty); + protected + function actualcolorclient(): colorty override; + public + constructor create(const aintf: icaptionframe; const stepintf: istepbar); + property buttonsinvisible default []; + published + property options; + property levelo default -2; + property leveli; + property framewidth; + property colorframe; + property colorframeactive; + property colorframedisabled; + property colorframemouse; + property colorframeclicked; + property colorframedefault; + property colordkshadow; + property colorshadow; + property colorlight; + property colorhighlight; + property colordkwidth; + property colorhlwidth; + property hiddenedges; + property colorclient {default cl_foreground}; + property colorbutton; + property colorglyph; + property framei_left default -1; + property framei_top default -1; + property framei_right default -1; + property framei_bottom default -1; + + property frameimage_list; + property frameimage_left; + property frameimage_top; + property frameimage_right; + property frameimage_bottom; + property frameimage_offset; + property frameimage_offset1; + property frameimage_offsetdisabled; + property frameimage_offsetmouse; + property frameimage_offsetclicked; + property frameimage_offsetactive; + property frameimage_offsetfocused; +{ + property frameimage_offsetactivemouse; + property frameimage_offsetactiveclicked; +} + property frameface_list; + property frameface_offset; + property frameface_offset1; + property frameface_offsetdisabled; + property frameface_offsetmouse; + property frameface_offsetclicked; + property frameface_offsetactive; + property frameface_offsetfocused; +{ + property frameface_offsetactivemouse; + property frameface_offsetactiveclicked; +} + property optionsskin; + + property caption; + property captionpos; + property font; + property localprops; //before template + property localprops1; //before template + property template; + property buttonface; + property buttonframe; + property buttonsvisible read fforcevisiblebuttons write setbuttonsvisible + default [sk_up,sk_down]; + property buttonsize; + property buttonpos; + property buttonslast; + property buttonsinline; + end; + + tcustomrealspinedit = class(tcustomrealedit,istepbar) + private + fstep: real; + fstepflag: stepkindty; +// fstepfact: integer; + fstepfact: real; + fstepctrlfact: real; + fstepshiftfact: real; + fwheelsensitivity: real; + function getframe: tspineditframe; + procedure setframe(const avalue: tspineditframe); + protected + function gettextvalue(var accept: boolean; + const quiet: boolean): realty; override; + procedure internalcreateframe; override; + procedure mouseevent(var info: mouseeventinfoty); override; + procedure dokeydown(var info: keyeventinfoty); override; + procedure domousewheelevent(var info: mousewheeleventinfoty); override; + procedure updatebuttonstate(); + procedure updatereadonlystate; override; + procedure enabledchanged(); override; + //istepbar + function dostep(const event: stepkindty; const adelta: real; + ashiftstate: shiftstatesty): boolean; + public + constructor create(aowner: tcomponent); override; + property step: real read fstep write fstep; //default 1 + property stepctrlfact: real read fstepctrlfact write fstepctrlfact; + //default = 0 -> no ctrl step + property stepshiftfact: real read fstepshiftfact write fstepshiftfact; + //default = 0 -> no shift step + property wheelsensitivity: real read fwheelsensitivity + write fwheelsensitivity; + published + property frame: tspineditframe read getframe write setframe; + end; + + trealspinedit = class(tcustomrealspinedit) + published + property onsetvalue; + property onsetintvalue; + property value; + property valuedefault; + property formatedit; + property formatdisp; + property valuerange; + property valuestart; + property valuemin; + property valuemax; + property step; + property stepctrlfact; + property stepshiftfact; + property wheelsensitivity; + end; + + datetimeeditoptionty = (dteo_showlocal,dteo_showutc); + datetimeeditoptionsty = set of datetimeeditoptionty; + + tcustomdatetimeedit = class(tnumedit) + private + fonsetvalue: setdatetimeeventty; + fvalue: tdatetime; + fvaluedefault: tdatetime; + fformatdisp: msestring; + fformatedit: msestring; + fvaluemin: tdatetime; + fvaluemax: tdatetime; + fkind: datetimekindty; + foptions: datetimeeditoptionsty; + fconvert: dateconvertty; + procedure setvalue(const Value: tdatetime); + procedure setformatdisp(const Value: msestring); + procedure setformatedit(const Value: msestring); + function getgridvalue(const index: integer): tdatetime; + procedure setgridvalue(const index: integer; const Value: tdatetime); + function getgridvalues: datetimearty; + procedure setgridvalues(const Value: datetimearty); + function checkkind(const avalue: tdatetime): tdatetime; + procedure setkind(const avalue: datetimekindty); + procedure readvalue(reader: treader); + procedure readvaluedefault(reader: treader); + procedure readmin1(reader: treader); + procedure readmax1(reader: treader); + {$ifdef mse_with_ifi} + function getifilink: tifidatetimelinkcomp; + procedure setifilink(const avalue: tifidatetimelinkcomp); + {$endif} + procedure setoptions(const avalue: datetimeeditoptionsty); + procedure setvaluemin(const avalue: tdatetime); + procedure setvaluemax(const avalue: tdatetime); + function getshowlocal: boolean; + procedure setshowlocal(const avalue: boolean); + function getshowutc: boolean; + procedure setshowutc(const avalue: boolean); + procedure readmin(reader: treader); + procedure readmax(reader: treader); + protected + procedure setvaluedata(const source); override; + procedure getvaluedata(out dest); override; + function gettextvalue(var accept: boolean; const quiet: boolean): tdatetime; + procedure texttovalue(var accept: boolean; const quiet: boolean); override; + function internaldatatotext(const data): msestring; override; + procedure texttodata(const atext: msestring; var data); override; + function createdatalist(const sender: twidgetcol): tdatalist; override; + function getdatalistclass: datalistclassty; override; + procedure valuetogrid(arow: integer); override; + procedure gridtovalue(arow: integer); override; + procedure defineproperties(filer: tfiler); override; + procedure readstatvalue(const reader: tstatreader); override; + procedure writestatvalue(const writer: tstatwriter); override; + function isempty (const atext: msestring): boolean; override; + function getdefaultvalue: pointer; override; + procedure setnullvalue(); override; + procedure updatedatalist; override; + procedure updatereadonlystate(); override; + //iassistiveclient + function getassistiveflags: assistiveflagsty; override; + public + constructor create(aowner: tcomponent); override; + procedure fillcol(const value: tdatetime); + procedure assigncol(const value: trealdatalist); + function isnull: boolean; override; + property onsetvalue: setdatetimeeventty read fonsetvalue write fonsetvalue; + property value: tdatetime read fvalue write setvalue {stored false}; + property valuedefault: tdatetime read fvaluedefault + write fvaluedefault {stored false}; + property formatedit: msestring read fformatedit write setformatedit; + property formatdisp: msestring read fformatdisp write setformatdisp; + property valuemin: tdatetime read fvaluemin write setvaluemin; + property valuemax: tdatetime read fvaluemax write setvaluemax; + property kind: datetimekindty read fkind write setkind default dtk_date; + property options: datetimeeditoptionsty read foptions write setoptions + default []; + property showlocal: boolean read getshowlocal write setshowlocal; + property showutc: boolean read getshowutc write setshowutc; + property gridvalue[const index: integer]: tdatetime + read getgridvalue write setgridvalue; default; + property gridvalues: datetimearty read getgridvalues write setgridvalues; + function griddata: tgridrealdatalist; +{$ifdef mse_with_ifi} + property ifilink: tifidatetimelinkcomp read getifilink write setifilink; +{$endif} + end; + + tdatetimeedit = class(tcustomdatetimeedit) + published + property onsetvalue; + property value {stored false}; + property valuedefault {stored false}; + property formatedit; + property formatdisp; + property valuemin {stored false}; + property valuemax {stored false}; + property kind; + property options; + {$ifdef mse_with_ifi} + property ifilink; + {$endif} + end; + +function realtytoint(const avalue: realty): integer; +function inttorealty(const avalue: integer): realty; + +implementation +uses + sysutils,msereal,msebits,msestreaming,msestockobjects,msefloattostr, + mseassistiveserver; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tdatalist1 = class(tdatalist); + twidget1 = class(twidget); + tcustombuttonframe1 = class(tcustombuttonframe); + twidgetcol1 = class(twidgetcol); + tdropdowncols1 = class(tdropdowncols); + tcustomframe1 = class(tcustomframe); + tcustomgrid1 = class(tcustomgrid); + tcustomwidgetgrid1 = class(tcustomwidgetgrid); + tdropdowncontroller1 = class(tdropdowncontroller); + tcustomdropdownlistcontroller1 = class(tcustomdropdownlistcontroller); + tcustomdropdowncontroller1 = class(tcustomdropdowncontroller); + tinplaceedit1 = class(tinplaceedit); +// tdatacol1 = class(tdatacol); + +function realtytoint(const avalue: realty): integer; +begin + if avalue = emptyreal then begin + result:= emptyinteger; + end + else begin + result:= round(avalue); + end; +end; + +function inttorealty(const avalue: integer): realty; +begin + if avalue = emptyinteger then begin + result:= emptyreal; + end + else begin + result:= avalue; + end; +end; + + { teditemptyfont } +{ +class function teditemptyfont.getinstancepo(owner: tobject): pfont; +begin + result:= @tcustomdataedit(owner).fempty_font; +end; +} +{ tcustomdataedit } +{ +constructor tcustomdataedit.create(aowner: tcomponent); +begin + include(fstate,des_isdataedit); + inherited; +end; +} +{ +destructor tcustomdataedit.destroy; +begin + inherited; + fempty_font.free; +end; +} +function tcustomdataedit.checkvalue(const quiet: boolean = false): boolean; +begin + result:= true; + if not ((oe_checkmrcancel in foptionsedit) and + (window.modalresult = mr_cancel)) and (fvaluechecking = 0) then begin + inc(fvaluechecking); + try + if canevent(tmethod(foncheckvalue)) then begin + foncheckvalue(self,quiet,result); + end; + if result then begin + if (oe_notnull in optionsedit) and isempty(text) and + nullcheckneeded(nil) then begin + result:= false; + try + if fgridintf = nil then begin + show; + setfocus; + end; + finally + notnullerror(quiet); + end; + exit; + end; + texttovalue(result,quiet); + if result then begin + exclude(fstate,des_edited); + if fparentintf <> nil then begin + fparentintf.childdataentered(igridwidget(self)); + end; + if not quiet and canevent(tmethod(fondataentered)) then begin + fondataentered(self); + end; + {$ifdef mse_with_ifi} + if fifiserverintf <> nil then begin + fifiserverintf.dataentered(getifidatalinkintf,gridrow); + end; + {$endif} + if (oe1_sendchangeeventbycheckvalue in optionsedit1) then begin + sendchangeevent(); + end; + if focused then begin + initfocus; + end; + if canassistive() and not quiet and + not (des_statreading in fstate) then begin + assistiveserver.dodataentered( + iassistiveclientdata(getiassistiveclient())); + end; + end; + end; + finally + dec(fvaluechecking); + end; + end; +end; + +function tcustomdataedit.canclose(const newfocus: twidget): boolean; +var + widget1: twidget; +begin + result:= true; + if not (csdesigning in componentstate) and + (oe_closequery in foptionsedit) and isenabled then begin + if (oe_notnull in optionsedit) and (fnullchecking = 0) and + nullcheckneeded(newfocus) and isempty(text) and + (not(ow1_nocancloseifhidden in foptionswidget1) or + showing) then begin + widget1:= window.focusedwidget; + result:= checkvalue; + if not result and (widget1 = window.focusedwidget) then begin + inc(fnullchecking); + try + if fgridintf <> nil then begin + with fgridintf.getcol do begin + {$warnings off} + tcustomgrid1(grid).beginnullchecking; + {$warnings on} + try + grid.col:= index; + grid.show; + if not focused then begin + {$warnings off} + tcustomgrid1(grid).beginnonullcheck; + {$warnings on} + try + grid.setfocus; + finally + {$warnings off} + tcustomgrid1(grid).endnonullcheck; + {$warnings on} + end; + end; + finally + {$warnings off} + tcustomgrid1(grid).endnullchecking; + {$warnings on} + end; + end; + end; + finally + dec(fnullchecking); + end; + end; + end + else begin + if focused and (des_edited in fstate) and + ((fgridintf = nil) or not fgridintf.nocheckvalue) then begin + result:= checkvalue; + end; + end; + end; + if result then begin + result:= inherited canclose(newfocus); + end; +end; + +procedure tcustomdataedit.valuetotext; +begin + updateedittext(false); + feditor.initfocus; + exclude(fstate,des_edited); +end; + +procedure tcustomdataedit.gridtovalue(row: integer); +begin + valuetotext; +end; + +procedure tcustomdataedit.dofocus; +begin + if fparentintf <> nil then begin + fparentintf.childfocused(igridwidget(self)); + end; + valuetotext(); + inherited; +end; + +procedure tcustomdataedit.synctofontheight; +begin + inherited; + if (fgridintf <> nil) and not (tf_rotate90 in textflags) then begin + fgridintf.getcol.grid.datarowheight:= bounds_cy; + end; +end; + +function tcustomdataedit.actualcolor: colorty; +begin + if (fgridintf <> nil) and (fcolor = cl_default) and + not (csdestroying in componentstate) then begin + result:= fgridintf.getcol.rowcolor(fgridintf.getrow); + if result = cl_transparent then begin + result:= fgridintf.getcol.actualcolor; + if result = cl_transparent then begin + result:= inherited actualcolor; + end; + end; + end + else begin + result:= inherited actualcolor; + end; +end; + +function tcustomdataedit.getedited: boolean; +begin + result:= des_edited in fstate; +end; + +procedure tcustomdataedit.setedited(const avalue: boolean); +begin + if avalue then begin + include(fstate,des_edited); + end + else begin + exclude(fstate,des_edited); + end; +end; + +function tcustomdataedit.geteditstate: dataeditstatesty; +begin + result:= fstate; +end; + +procedure tcustomdataedit.seteditstate(const avalue: dataeditstatesty); +begin + fstate:= avalue; +end; +{ +procedure tcustomdataedit.setisdb; +begin + include(fstate,des_isdb); +end; +} +function tcustomdataedit.emptytext: boolean; +begin + result:= des_emptytext in fstate; +end; +{ +procedure tcustomdataedit.updatetextflags; +var + aflags: textflagsty; +begin + if not (csloading in componentstate) then begin + if (des_emptytext in fstate) and (fempty_text <> '') then begin + aflags:= fempty_textflags; + end + else begin + aflags:= textflags; + end; + if isenabled or (oe_nogray in foptionsedit) then begin + exclude(fstate,des_grayed); + feditor.textflags:= aflags; + feditor.textflagsactive:= textflagsactive; + end + else begin + include(fstate,des_grayed); + feditor.textflags:= aflags + [tf_grayed]; + feditor.textflagsactive:= textflagsactive + [tf_grayed]; + end; + end; +end; +} + +function tcustomdataedit.gettext: msestring; +begin + result:= inherited gettext(); + if des_emptytext in fstate then begin + result:= ''; + end; +end; + +function tcustomdataedit.getedittext(): msestring; +begin + result:= datatotext(nil^); +end; + +function tcustomdataedit.getdisptext: msestring; +var + mstr1: msestring; +begin + {$ifdef FPC} {$checkpointer off} {$endif} + mstr1:= datatotext(nil^); + {$ifdef FPC} {$checkpointer default} {$endif} + if (not(des_isdb in fstate) and (mstr1 = '') or + (des_dbnull in fstate)) then begin + mstr1:= empty_text; + end; + result:= mstr1; +end; + +procedure tcustomdataedit.dodefocus; +begin + updateedittext(false); + exclude(fstate,des_edited); + inherited; +end; + +function tcustomdataedit.cangridcopy: boolean; +begin + result:= (fgridintf <> nil) and fgridintf.cangridcopy; +end; + +procedure tcustomdataedit.initgridwidget; +begin + defaultinitgridwidget(self,fgridintf); +end; + +function tcustomdataedit.getinnerframe: framety; +begin + if fgridintf <> nil then begin + result:= fgridintf.getcol.innerframe; + end + else begin + result:= inherited getinnerframe; + end; +end; + +procedure tcustomdataedit.formatchanged(); +begin + if not (csloading in componentstate) then begin + if fgridintf <> nil then begin + fgridintf.changed; + end; + if not (des_edited in fstate) then begin + updateedittext(false); //do not touch pending modifications + end; + inherited; + end; +end; + +procedure tcustomdataedit.formaterror(const quiet: boolean); +begin + if not quiet then begin + showmessage(''''+text+''' '+stockobjects.captions[sc_is_invalid]+'.', + stockobjects.captions[sc_Format_error]); + end; +end; + +procedure tcustomdataedit.notnullerror(const quiet: boolean); +begin + if not quiet then begin + showmessage(stockobjects.captions[sc_Value_is_required]+'.', + stockobjects.captions[sc_Error]); + end; +end; + +procedure tcustomdataedit.rangeerror(const min, max; const quiet: boolean); +begin + if not quiet then begin + showmessage(stockobjects.captions[sc_min]+': '+datatotext(min)+' '+ + stockobjects.captions[sc_Max]+': ' + + datatotext(max) + '.',stockobjects.captions[sc_Range_error]); + end; +end; + +procedure tcustomdataedit.loaded; +begin + inherited; + include(fwidgetstate,ws_loadedproc); + try + valuechanged; + formatchanged; + finally + exclude(fwidgetstate,ws_loadedproc); + end; +end; + +procedure tcustomdataedit.fontchanged; +begin + inherited; + if fgridintf <> nil then begin + fgridintf.getcol.changed; + end; +end; + +procedure tcustomdataedit.dofontheightdelta(var delta: integer); +begin + inherited; + gridwidgetfontheightdelta(self,fgridintf,delta); +end; + +function tcustomdataedit.geteditfont: tfont; +begin + if {(fempty_font <> nil) and} (des_emptytext in fstate) then begin + result:= getfontempty1{fempty_font}; + end + else begin + if (fgridintf <> nil) and (ffont = nil) then begin + with fgridintf.getcol do begin + result:= rowfont(grid.row); + end; + end + else begin + result:= inherited geteditfont; + end; + end; +end; + +class function tcustomdataedit.classskininfo: skininfoty; +begin + result:= inherited classskininfo; + result.objectkind:= sok_dataedit; +end; + +function tcustomdataedit.setdropdowntext(const avalue: msestring; + const docheckvalue: boolean; const canceled: boolean; + const akey: keyty): boolean; +var + bo1: boolean; +begin + result:= true; + if canceled then begin + feditor.undo; + end + else begin + text:= avalue; //setcurrenttext(avalue); + if docheckvalue then begin + result:= checkvalue(); + if not result then begin + feditor.undo; + end + else begin + if akey = key_tab then begin + window.postkeyevent(akey,[],false); + end; + end; + end + else begin + if not canceled then begin + bo1:= true; + texttovalue(bo1,true); + end; + end; + end; +end; + +procedure tcustomdataedit.setgridintf(const intf: iwidgetgrid); +begin + fgridintf:= intf; + if fgridintf <> nil then begin +{$ifdef mse_with_ifi} +{ + if (fifilink <> nil) and (fifilink.controller.datalist <> nil) then begin + updateifigriddata(fifilink.controller.datalist); + end; +} +{$endif} + fdatalist:= fgridintf.getcol.datalist; + if fdatalist <> nil then begin + updatedatalist; + end; + fgriddatalink:= tcustomwidgetgrid1(fgridintf.getgrid).getgriddatalink; + fgridintf.updateeditoptions(foptionsedit,feditor.optionsedit1); + if (ow1_autoscale in foptionswidget1) and + (foptionswidget1 * [ow1_fontglyphheight,ow1_fontlineheight] <> []) then begin + fgridintf.getcol.grid.datarowheight:= bounds_cy; + end; + end + else begin + fdatalist:= nil; + fgriddatalink:= nil; + end; +end; + +function tcustomdataedit.getcellframe: framety; +begin + if fframe <> nil then begin + result:= frame.cellframe; + end + else begin + if fgridintf <> nil then begin + result:= tgridarrayprop(fgridintf.getcol.prop).innerframe; + end + else begin + result:= getinnerframe; + end; + end; +end; + +function tcustomdataedit.needscellfocuspaint(): boolean; +begin + result:= inherited needsfocuspaint(); +end; + +procedure tcustomdataedit.updatecoloptions(const aoptions: coloptionsty); +var + opt1: optionseditty; + opt2: optionsedit1ty; +begin + opt1:= foptionsedit; + opt2:= optionsedit1; + fgridintf.coloptionstoeditoptions(opt1,opt2); + optionsedit:= opt1; + optionsedit1:= opt2; +end; + +procedure tcustomdataedit.setoptionsedit(const avalue: optionseditty); +begin + if foptionsedit <> avalue then begin + inherited; + if fgridintf <> nil then begin + fgridintf.updateeditoptions(foptionsedit,feditor.optionsedit1); + end; + end; +end; + +procedure tcustomdataedit.setoptionsedit1(const avalue: optionsedit1ty); +begin + inherited; + if fgridintf <> nil then begin + fgridintf.updateeditoptions(foptionsedit,feditor.optionsedit1); + end; +end; + +procedure tcustomdataedit.updatecoloptions1(const aoptions: coloptions1ty); +begin + //dummy +end; + +procedure tcustomdataedit.statdataread; +begin + //dummy +end; + +procedure tcustomdataedit.griddatasourcechanged; +begin + //dummy +end; + +procedure tcustomdataedit.modified; +begin + if fgridintf <> nil then begin + fgridintf.edited(); + end; +end; + +procedure tcustomdataedit.valuechanged; +begin + if not (csloading in componentstate) then begin + if not (ws_loadedproc in fwidgetstate) then begin + exclude(fstate,des_dbnull); + end; + if (fgridintf <> nil) and not (csdesigning in componentstate) then begin + valuetogrid(fgridintf.getrow); + end; + updateedittext(false); + if focused then begin + feditor.initfocus; + end + else begin + feditor.sellength:= 0; + feditor.curindex:= bigint; + end; + if not (ws_loadedproc in fwidgetstate) then begin + modified; + end; + dochange; + end; +end; + +procedure tcustomdataedit.dotextchange; +begin + if canevent(tmethod(fontextchange)) then begin + fontextchange(self,text); + end; +end; + +procedure tcustomdataedit.checktext(var atext: msestring; var accept: boolean); +begin + if canevent(tmethod(fonsettext)) then begin + fonsettext(self,atext,accept); + end; +end; + +procedure tcustomdataedit.texttodata(const atext: msestring; var data); +begin + //dummy +end; + +procedure tcustomdataedit.setstatfile(const Value: tstatfile); +begin + setstatfilevar(istatfile(self),value,fstatfile); +end; + +procedure tcustomdataedit.dostatwrite(const writer: tstatwriter); +begin + if not (des_isdb in fstate) and (fgridintf = nil) and + canstatvalue(optionsedit1,writer) then begin + writestatvalue(writer); + end; + if canstatstate(optionsedit1,writer) then begin + writestatstate(writer); + end; + if canstatoptions(optionsedit1,writer) then begin + writestatoptions(writer); + end; +end; + +procedure tcustomdataedit.dostatread(const reader: tstatreader); +begin + exclude(fstate,des_valueread); + if not (des_isdb in fstate) and (fgridintf = nil) + and canstatvalue(optionsedit1,reader) then begin + readstatvalue(reader); + include(fstate,des_valueread); + end; + if canstatstate(optionsedit1,reader) then begin + readstatstate(reader); + end; + if canstatoptions(optionsedit1,reader) then begin + readstatoptions(reader); + end; +end; + +procedure tcustomdataedit.statreading; +begin + //dummy +end; + +procedure tcustomdataedit.statread; +var + bo1: boolean; +begin + if (oe1_checkvalueafterstatread in optionsedit1) and + (des_valueread in fstate) then begin + bo1:= des_statreading in fstate; + include(fstate,des_statreading); + try +// checkvalue(true); + checkvalue(); + finally + if not bo1 then begin + exclude(fstate,des_statreading); + end; + end; + end; +end; + +function tcustomdataedit.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +procedure tcustomdataedit.readstatoptions(const reader: tstatreader); +begin + //dummy +end; + +procedure tcustomdataedit.readstatstate(const reader: tstatreader); +begin + //dummy +end; + +procedure tcustomdataedit.readstatvalue(const reader: tstatreader); +begin + //dummy +end; + +procedure tcustomdataedit.writestatoptions(const writer: tstatwriter); +begin + //dummy +end; + +procedure tcustomdataedit.writestatstate(const writer: tstatwriter); +begin + //dummy +end; + +procedure tcustomdataedit.writestatvalue(const writer: tstatwriter); +begin + //dummy +end; + +procedure tcustomdataedit.nullvalueset(); +begin + include(fstate,des_dbnull); + updateedittext(true); //change to textempty +end; + +procedure tcustomdataedit.setnullvalue(); //for dbedits +var + bo1: boolean; +begin + text:= getnulltext; + bo1:= true; + texttovalue(bo1,true); //setvalue call + nullvalueset(); +end; + +procedure tcustomdataedit.setfirstclick(var ainfo: mouseeventinfoty); +begin + feditor.setfirstclick(ainfo); +end; + +function tcustomdataedit.getdefaultvalue: pointer; +begin + result:= nil; +end; + +function tcustomdataedit.getrowdatapo(const arow: integer): pointer; +begin + result:= nil; +end; + +function tcustomdataedit.getnulltext: msestring; +begin + result:= ''; +end; + +function tcustomdataedit.getcelltext(const datapo: pointer; + out empty: boolean): msestring; +var + mstr1: msestring; + //avoid refcount 0 because of const param in internaldatatotext() +begin + empty:= false; + if datapo <> nil then begin + mstr1:= internaldatatotext(datapo^); + if passwordchar <> #0 then begin + mstr1:= charstring(passwordchar,length(mstr1)); + end; + if not (des_isdb in fstate) and (mstr1 = '') and + (empty_text <> '') then begin + empty:= true; + mstr1:= empty_text; + end; + end + else begin + empty:= true; + mstr1:= empty_text; + end; + if canevent(tmethod(fongettext)) then begin + fongettext(self,mstr1,false); + end; + result:= mstr1; +end; + +function tcustomdataedit.getiassistiveclient(): iassistiveclient; +begin + result:= iassistiveclientgridwidget(self); +end; + +function tcustomdataedit.getassistivecelltext(const arow: int32): msestring; +var + bo1: boolean; +begin + if fdatalist <> nil then begin + result:= getcelltext(fdatalist.getitempo(arow),bo1); + end + else begin + result:= ''; + end; +end; + +function tcustomdataedit.getassistivetext(): msestring; +begin + result:= feditor.text; +end; + +function tcustomdataedit.getassistivecolumncaption(): msestring; +begin + result:= ''; + if fgridintf <> nil then begin + result:= fgridintf.getcol.defaultcaption(); + end; +end; + +function tcustomdataedit.getassistiveflags: assistiveflagsty; +begin + result:= inherited getassistiveflags; + if fgridintf <> nil then begin + result:= result + [{asf_gridcell,}asf_gridwidget]; + if gs1_scrolllimit in tcustomwidgetgrid1(fgridintf.getgrid).fstate1 then begin + include(result,asf_scrolllimit); + end; + end; + if des_isdb in fstate then begin + include(result,asf_db); + end; +end; + +procedure tcustomdataedit.drawcell(const canvas: tcanvas); +var + mstr1: msestring; + atextflags: textflagsty; + bo1: boolean; + int1: integer; + rect1: rectty; + fra1: framety; + + procedure cellpaint(const rect: rectty; const innerrect: rectty); + begin + if (rect.cx > 0) and (rect.cy > 0) then begin + if bo1 and (empty_color <> cl_none) and + not (des_grayed in fstate) then begin + canvas.fillrect(rect,empty_color); + end; + paintimage(canvas); + if mstr1 <> '' then begin + if bo1 then begin + canvas.font:= getfontempty1{fempty_font}; + atextflags:= empty_textflags; + if empty_textcolor <> cl_none then begin + canvas.font.color:= empty_textcolor; + end; + if empty_textcolorbackground <> cl_none then begin + canvas.font.color:= empty_textcolorbackground; + end; + end; + if des_grayed in fstate then begin + include(atextflags,tf_grayed); + end; + drawtext(canvas,mstr1,deflaterect(innerrect,fra1),deflaterect(rect,fra1), + atextflags); + end; + end; + end; //cellpaint + +var + outer1,inner1: rectty; + pt1: pointty; + +begin + atextflags:= textflags; + with cellinfoty(canvas.drawinfopo^) do begin + mstr1:= getcelltext(datapo,bo1); + if bo1 then begin + if empty_fontstyle <> [] then begin + canvas.font.style:= empty_fontstyle; + end; + end; + fra1:= geteditframe; + if calcautocellsize then begin + rect1:= textrect(canvas,mstr1,deflaterect(innerrect,fra1),atextflags); + int1:= rect1.cx - innerrect.cx + rect.cx; + if int1 > autocellsize.cx then begin + autocellsize.cx:= int1; + end; + int1:= rect1.cy - innerrect.cy + rect.cy; + if int1 > autocellsize.cy then begin + autocellsize.cy:= int1; + end; + end + else begin + if (fgridintf = nil) and (fparentintf <> nil) and + (oe1_nocellpaint in optionsedit1) then begin + if (fwidgetrect.cx > 0) and (fwidgetrect.cy > 0) then begin + paintbackground(canvas,fwidgetrect); + gettextrects(outer1,inner1); + pt1:= paintparentpos; + addpoint1(outer1.pos,pt1); + addpoint1(inner1.pos,pt1); + cellpaint(outer1,inner1); + paintoverlay(canvas,fwidgetrect); + end; + end + else begin + cellpaint(rect,innerrect); + end; + end; + end; +end; + +procedure tcustomdataedit.updateautocellsize(const canvas: tcanvas); +begin + drawcell(canvas); +end; + +procedure tcustomdataedit.doafterpaint(const canvas: tcanvas); +begin + inherited; + if (fgridintf <> nil) and not (csdesigning in componentstate) then begin + fgridintf.widgetpainted(canvas); + end; +end; + +function tcustomdataedit.needsfocuspaint: boolean; +begin + result:= (fgridintf = nil) and inherited needsfocuspaint; +end; + +function tcustomdataedit.getgridintf: iwidgetgrid; +begin + result:= fgridintf; +end; + +function tcustomdataedit.checkgriddata: tdatalist; +begin + if fgridintf = nil then begin + raise exception.Create('No grid.'); + end; +// result:= fgridintf.getcol.datalist; + result:= fdatalist; + if result = nil then begin + raise exception.Create('No datalist.'); + end; +end; + +procedure tcustomdataedit.checkgrid; +begin + if fgridintf = nil then begin + raise exception.Create('No grid.'); + end; +end; + +function tcustomdataedit.checkgriddata(var index: integer): tdatalist; + //index -1 -> grid.row, nil if no focused row +begin + result:= checkgriddata(); + if index = -1 then begin + index:= fgridintf.getcol.grid.row; + end; + if index < 0 then begin + result:= nil; + end; +end; + +procedure tcustomdataedit.internalgetgridvalue(index: integer; var value); +begin + checkgrid; + fgridintf.getdata(index,value); +end; + +procedure tcustomdataedit.internalsetgridvalue(index: integer; + const Value); +begin + checkgrid; + fgridintf.setdata(index,value); +end; + +procedure tcustomdataedit.internalfillcol(const value); +begin +// checkgrid; +// with tdatalist1(fgridintf.getcol.datalist) do begin + with tdatalist1(checkgriddata) do begin + {tdatalist1(fgridintf.getcol.datalist).}internalfill(count,value); + end; +end; + +procedure tcustomdataedit.internalassigncol(const value); +begin + checkgrid; + with fgridintf.getcol do begin + datalist.Assign(tdatalist(value)); + end; +end; + +function tcustomdataedit.widgetcol: twidgetcol; +begin + if fgridintf = nil then begin + result:= nil; + end + else begin + result:= fgridintf.getcol; + end; +end; + +function tcustomdataedit.grid: tcustomwidgetgrid; +begin + if fgridintf = nil then begin + result:= nil; + end + else begin + result:= fgridintf.getgrid(); + end; +end; + +function tcustomdataedit.getgridrow: integer; +begin + if fgridintf = nil then begin + result:= -1; + end + else begin + result:= fgridintf.getcol.grid.row; + end; +end; + +function tcustomdataedit.gridrowhigh: int32; +begin + if fgridintf = nil then begin + result:= -1; + end + else begin + result:= fgridintf.getcol.grid.rowhigh; + end; +end; + +function tcustomdataedit.griddatarowhigh: int32; +begin + if fgridintf = nil then begin + result:= -1; + end + else begin + result:= fgridintf.getcol.grid.datarowhigh; + end; +end; + +procedure tcustomdataedit.setgridrow(const avalue: integer); +begin + if fgridintf <> nil then begin + fgridintf.getcol.grid.row:= avalue; + end; +end; + +function tcustomdataedit.gridcol: integer; +begin + if fgridintf = nil then begin + result:= -1; + end + else begin + result:= fgridintf.getcol.index; + end; +end; + +function tcustomdataedit.sortfunc(const l,r): integer; +begin +// result:= tdatalist1(twidgetcol1(fgridintf.getcol).fdata).compare(l,r); + result:= tdatalist1(fdatalist).compare(l,r); +end; + +function tcustomdataedit.griddata: tdatalist; +begin + checkgrid; + result:= fdatalist; +end; + +function tcustomdataedit.textclipped(const arow: integer; + out acellrect: rectty): boolean; +var + rect2: rectty; + canvas1: tcanvas; + cell1: gridcoordty; + grid1: tcustomgrid; + bo1: boolean; +begin + checkgrid; + with twidgetcol1(fgridintf.getcol) do begin + grid1:= grid; + cell1.row:= arow; + cell1.col:= colindex; + result:= grid1.isdatacell(cell1); + if result then begin + acellrect:= grid1.clippedcellrect(cell1,cil_inner); + canvas1:= getcanvas; + rect2:= textrect(canvas1,getcelltext(getdatapo(arow),bo1), + acellrect,feditor.textflags,font); + result:= not rectinrect(rect2,acellrect); + end + else begin + acellrect:= nullrect; + end; + end; +end; + +function tcustomdataedit.textclipped(const arow: integer): boolean; +var + rect1: rectty; +begin + result:= textclipped(arow,rect1); +end; + +procedure tcustomdataedit.docellevent(const ownedcol: boolean; var info: celleventinfoty); + +var + hintinfo: hintinfoty; +begin + if ownedcol then begin + if (info.eventkind = cek_enter) then begin + setupeditor; //setrowfont + feditor.initfocus; + end; + if (oe_hintclippedtext in foptionsedit) and + (info.eventkind = cek_firstmousepark) and application.active and + textclipped(info.cell.row) and + ((info.grid.row <> info.cell.row) or (info.grid.col <> info.cell.col)) and + {$warnings off} + twidget1(info.grid).getshowhint then begin + {$warnings on} + application.inithintinfo(hintinfo,info.grid); + {$warnings off} + hintinfo.caption:= + datatotext(twidgetcol1(fgridintf.getcol).getdatapo(info.cell.row)^); + {$warnings on} + application.showhint(info.grid,hintinfo); + end; + end; +end; + +procedure tcustomdataedit.gridvaluechanged(const index: integer); +begin + //dummy +end; + +function tcustomdataedit.isempty(const atext: msestring): boolean; +begin + result:= trim(atext) = getnulltext; +end; + +function tcustomdataedit.nullcheckneeded(const newfocus: twidget): boolean; +begin + result:= false; + if (newfocus <> self) and not (des_statreading in fstate) and + not ((oe_checkmrcancel in foptionsedit) and + (window.modalresult = mr_cancel)) and + not readonly then begin + if fgridintf = nil then begin + result:= (newfocus = nil) and + (not (des_isdb in fstate) or (des_dbnullcheck in fstate) or + (oe_directdbnullcheck in optionsedit)); + end + else begin + result:= fgridintf.nullcheckneeded(newfocus); + end; + end; +end; + +procedure tcustomdataedit.setenabled(const avalue: boolean); +begin + inherited; + if (fgridintf <> nil) and not (csloading in componentstate) then begin + fgridintf.getcol.enabled:= avalue; + end; +end; + +function tcustomdataedit.seteditfocus: boolean; +begin + if not readonly then begin + if fgridintf = nil then begin + if canfocus then begin + setfocus; + end; + end + else begin + with fgridintf.getcol do begin + grid.col:= index; + if grid.canfocus then begin + if not focused then begin + grid.setfocus; + end; + end; + end; + end; + end; + result:= focused; +end; + +procedure tcustomdataedit.beforecelldragevent(var ainfo: draginfoty; const arow: integer; + var handled: boolean); +begin + //dummy +end; + +procedure tcustomdataedit.aftercelldragevent(var ainfo: draginfoty; const arow: integer; + var handled: boolean); +begin + //dummy +end; + +procedure tcustomdataedit.initeditfocus; +begin + exclude(fstate,des_edited); + initfocus; +end; + +function tcustomdataedit.datatotext(const data): msestring; +var + mstr1: msestring; + //avoid refcount 0 because of const param in internaldatatotext() +begin + mstr1:= internaldatatotext(data); + if canevent(tmethod(fongettext)) then begin + fongettext(self,mstr1,focused); + end; + result:= mstr1; +end; + +(* +procedure tcustomdataedit.createfontempty; +begin + if fempty_font = nil then begin + fempty_font:= teditemptyfont.create; + fempty_font.onchange:= {$ifdef FPC}@{$endif}fontemptychanged; + end; +end; + +function tcustomdataedit.getempty_font: teditemptyfont; +begin + getoptionalobject(fempty_font,{$ifdef FPC}@{$endif}createfontempty); + result:= fempty_font; + if result = nil then begin + result:= teditemptyfont(getfont1); + end; +end; + +procedure tcustomdataedit.setempty_font(const avalue: teditemptyfont); +begin + if fempty_font <> avalue then begin + setoptionalobject(avalue,fempty_font,{$ifdef FPC}@{$endif}createfontempty); + end; +end; + +function tcustomdataedit.isempty_fontstored: boolean; +begin + result:= fempty_font <> nil; +end; + +procedure tcustomdataedit.fontemptychanged(const sender: tobject); +begin + emptychanged; +end; +*) +function tcustomdataedit.locatecount: integer; +//var +// datalist1: tdatalist; +begin + result:= 0; + if fgridintf <> nil then begin +// datalist1:= fgridintf.getcol.datalist; + if fdatalist <> nil then begin + result:= fdatalist.count; + end; + end; +end; + +function tcustomdataedit.locatecurrentindex: integer; +begin + result:= fgridintf.getcol.grid.row; +end; + +procedure tcustomdataedit.locatesetcurrentindex(const aindex: integer); +begin + fgridintf.getcol.grid.row:= aindex; +end; + +function tcustomdataedit.getkeystring(const aindex: integer): msestring; +begin + with fgridintf.getcol do begin + if grid.rowhidden[aindex] then begin + result:= ''; + end + else begin + result:= datatotext(datalist.getitempo(aindex)^); + end; + end; +end; + +function tcustomdataedit.actualcursor(const apos: pointty): cursorshapety; +var + zone1: cellzonety; + int1: integer; +begin + if (fgridintf <> nil) and not (des_actualcursor in fstate) then begin + include(fstate,des_actualcursor); + try + zone1:= cz_default; + int1:= fgridintf.grid.row; + if int1 >= 0 then begin + updatecellzone(int1,widgetpostoclientpos(apos),zone1); +// result:= getcellcursor(int1,zone1); + result:= getcellcursor(-1,zone1,apos); + exit; + end; + finally + exclude(fstate,des_actualcursor); + end; + end; + result:= inherited actualcursor(apos); +end; + +function tcustomdataedit.getcellcursor(const arow: integer; + const acellzone: cellzonety; const apos: pointty): cursorshapety; +var + bo1: boolean; +begin + bo1:= des_actualcursor in fstate; + include(fstate,des_actualcursor); + result:= actualcursor(nullpoint); + if not bo1 then begin + exclude(fstate,des_actualcursor); + end; +end; + +procedure tcustomdataedit.updatecellzone(const row: integer; + const apos: pointty; var result: cellzonety); +begin + //dummy +end; + +procedure tcustomdataedit.mouseevent(var info: mouseeventinfoty); +begin + if fcontrollerintf <> nil then begin + fcontrollerintf.mouseevent(info); + end; + inherited; +end; + +procedure tcustomdataedit.domousewheelevent(var info: mousewheeleventinfoty); +begin + if fcontrollerintf <> nil then begin + fcontrollerintf.domousewheelevent(info); + end; + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + + +procedure tcustomdataedit.dokeydown(var info: keyeventinfoty); +begin + if fcontrollerintf <> nil then begin + fcontrollerintf.dokeydown(info); + end; + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +procedure tcustomdataedit.updatereadonlystate; +begin + inherited; + if fcontrollerintf <> nil then begin + fcontrollerintf.updatereadonlystate; + end; +end; + +procedure tcustomdataedit.internalcreateframe; +begin + if (fframe = nil) and (fcontrollerintf <> nil) then begin + fcontrollerintf.internalcreateframe; + end; + if fframe = nil then begin + inherited; + end; +end; + +procedure tcustomdataedit.editnotification(var info: editnotificationinfoty); +var + bo1: boolean; +begin + if fcontrollerintf <> nil then begin + fcontrollerintf.editnotification(info); + end; + case info.action of + ea_textentered: begin + bo1:= true; + if (des_edited in fstate) or + (oe_forcereturncheckvalue in foptionsedit) then begin + bo1:= checkvalue; + if not bo1 or (oe_eatreturn in foptionsedit) then begin + info.action:= ea_none; + end; + end; + if bo1 then begin + if (fgridintf <> nil) and + (og_colchangeonreturnkey in fgridintf.getcol.grid.optionsgrid)then begin + info.action:= ea_none; + fgridintf.getcol.grid.colstep(fca_focusin,1,true,false,true); + end; + end; + end; + ea_textedited: begin + include(fstate,des_edited); + modified(); + inherited; + end; + ea_resetemptytext: begin + inherited; + end; + ea_undone: begin + updateedittext(true); //restore empty_* setings + end; + ea_textchanged: begin + dotextchange; + end; + ea_undo: begin + exclude(fstate,des_edited); + end; + ea_caretupdating: begin + if (fgridintf <> nil) and focused then begin + fgridintf.showcaretrect(info.caretrect,fframe); + end; + end; + end; +end; + +procedure tcustomdataedit.initnewwidget(const ascale: real); +begin +{ + if fgridintf <> nil then begin + fgridintf.getcol.options:= fgridintf.getcol.grid.datacols.options; + //restore default options + end; +} + inherited; +end; + +function tcustomdataedit.textcellcopy: boolean; +begin + result:= true; +end; + +procedure tcustomdataedit.datalistdestroyed; +begin + fdatalist:= nil; +end; + +{$ifdef mse_with_ifi} +function tcustomdataedit.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iifidatalink); +end; + +procedure tcustomdataedit.setifilink0(const avalue: tifilinkcomp); +begin + mseificomp.setifilinkcomp(getifidatalinkintf,avalue,tifilinkcomp(fifilink)); +end; + +procedure tcustomdataedit.setifilink(const avalue: tifilinkcomp); +begin + setifilink0(avalue); +end; +{ +function tcustomdataedit.ifigriddata: tdatalist; +begin + result:= fdatalist; +end; +} +procedure tcustomdataedit.updateifigriddata(const sender: tobject; + const alist: tdatalist); +begin + if fgridintf <> nil then begin + fgridintf.updateifigriddata(alist); + fdatalist:= alist; + end; +end; + +function tcustomdataedit.getgriddata: tdatalist; +begin + result:= fdatalist; +end; + +function tcustomdataedit.getvalueprop: ppropinfo; +begin + result:= getpropinfo(self,'value'); +end; + +function tcustomdataedit.getifidatalinkintf: iifidatalink; +begin + result:= iifidatalink(self); +end; + +function tcustomdataedit.getdefaultifilink: iificlient; +begin + result:= getifidatalinkintf; +end; + +function tcustomdataedit.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + if fifiserverintf <> nil then begin + fifiserverintf.updateoptionsedit(result); + end; +end; + +procedure tcustomdataedit.ifisetvalue(var avalue; var accept: boolean); +begin + if accept and (fifiserverintf <> nil) then begin + iifidataserver(fifiserverintf).setvalue( + getifidatalinkintf,avalue,accept,gridrow); + end; +end; + +procedure tcustomdataedit.getifivalue(var avalue); +begin + //dummy +end; + +procedure tcustomdataedit.setifivalue(const avalue); +begin + //dummy +end; + +function tcustomdataedit.getifilink: tifilinkcomp; +begin + result:= fifilink; +end; + +procedure tcustomdataedit.dochange; +begin + inherited; + if not (ws_loadedproc in fwidgetstate) then begin + if fifiserverintf <> nil then begin + iifidataserver(fifiserverintf).valuechanged(getifidatalinkintf); + end; + end; +end; + +{$endif mse_with_ifi} + +function tcustomdataedit.getifidatatype(): listdatatypety; +begin + result:= getdatalistclass().datatype(); +end; + +procedure tcustomdataedit.sizechanged; +begin + inherited; + gridwidgetsized(self,fgridintf); +end; + +procedure tcustomdataedit.paint(const canvas: tcanvas); +begin + if (fgridintf = nil) or + not (twidgetcol1(fgridintf.getcol).checkautocolwidth) then begin + inherited; + end; +end; + +procedure tcustomdataedit.updatedatalist; +begin + //dummy +end; + +function tcustomdataedit.isnull: boolean; +begin + result:= false; //dummy +end; + +function tcustomdataedit.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +procedure tcustomdataedit.setparentgridwidget(const intf: igridwidget); +begin + fparentintf:= intf; +end; + +procedure tcustomdataedit.childdataentered(const sender: igridwidget); +begin + //dummy +end; + +procedure tcustomdataedit.childfocused(const sender: igridwidget); +begin + //dummy +end; + +{ tcustomstringedit } + +function tcustomstringedit.internaldatatotext(const data): msestring; +begin + if @data = nil then begin + result:= fvalue; + end + else begin + result:= msestring(data); + end; + updatedisptext(result); +end; + +procedure tcustomstringedit.texttodata(const atext: msestring; var data); +begin + msestring(data):= atext; +end; + +function tcustomstringedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= tgridmsestringdatalist.create(sender); +end; + +function tcustomstringedit.getdatalistclass: datalistclassty; +begin + result:= tgridmsestringdatalist; +end; + +procedure tcustomstringedit.setvalue(const Value: msestring); +begin + fvalue:= Value; + valuechanged; +end; + +function tcustomstringedit.getvaluetext: msestring; +begin + result:= text; +end; + +procedure tcustomstringedit.updatedisptext(var avalue: msestring); +begin + updateflagtext(avalue); +end; + +procedure tcustomstringedit.dosetvalue(var avalue: msestring; var accept: boolean); +begin + if canevent(tmethod(fonsetvalue)) then begin + fonsetvalue(self,avalue,accept); + end; +end; + +procedure tcustomstringedit.texttovalue(var accept: boolean; + const quiet: boolean); +var + mstr1: msestring; +begin + mstr1:= getvaluetext; + updateflagtext(mstr1); + checktext(mstr1,accept); + if not accept then begin + exit; + end; + if not quiet then begin + dosetvalue(mstr1,accept); +{$ifdef mse_with_ifi} + ifisetvalue(mstr1,accept); +{$endif} + end; + if accept then begin + value:= mstr1; + end; +end; + +function tcustomstringedit.checkvalue(const quiet: boolean = false): boolean; +//var +// mstr1: msestring; +begin +{ + if optionsedit * + [oe_trimleft,oe_trimright,oe_uppercase,oe_lowercase] <> [] then begin + mstr1:= getvaluetext; + updateflagtext(mstr1); + text:= mstr1; + end; +} + result:= inherited checkvalue(quiet); +end; + +procedure tcustomstringedit.valuetogrid(arow: integer); +begin + fgridintf.setdata(arow,fvalue); +end; + +procedure tcustomstringedit.gridtovalue(arow: integer); +begin + fgridintf.getdata(arow,fvalue); + inherited; +end; + +procedure tcustomstringedit.readstatvalue(const reader: tstatreader); +//var +// ar1: msestringarty; +begin +// ar1:= nil; //compiler warning +// if fgridintf = nil then begin +// ar1:= nil; +// ar1:= reader.readarray(valuevarname+'ar',ar1); +// if high(ar1) >= 0 then begin +// value:= concatstrings(ar1,lineend); +// end +// else begin + value:= reader.readmsestring(valuevarname,value); +// end; +// end; +end; + +procedure tcustomstringedit.writestatvalue(const writer: tstatwriter); +//var +// ar1: msestringarty; +begin +// ar1:= breaklines(value); +// if high(ar1) > 0 then begin +// writer.writearray(valuevarname+'ar',ar1); +// end +// else begin + writer.writemsestring(valuevarname,value); +// end; +end; + +procedure tcustomstringedit.dragevent(var info: draginfoty); +begin + with info do begin + case eventkind of + dek_check: begin + inherited; + accept:= accept or (dragobjectpo^ is tstringdragobject); + end; + dek_drop: begin + if dragobjectpo^ is tstringdragobject then begin + value:= msestring(tstringdragobject(dragobjectpo^).data); + end + else begin + inherited; + end; + end; + else begin + inherited; + end; + end; + end; +end; + +procedure tcustomstringedit.fillcol(const value: msestring); +begin + internalfillcol(value); +end; + +procedure tcustomstringedit.assigncol(const value: tmsestringdatalist); +begin + internalassigncol(value); +end; + +function tcustomstringedit.getgridvalue(const index: integer): msestring; +begin + internalgetgridvalue(index,result); +end; + +procedure tcustomstringedit.setgridvalue(const index: integer; + const Value: msestring); +begin + internalsetgridvalue(index,value); +end; + +function tcustomstringedit.sortfunc(const l,r): integer; +begin + if oe_casesensitive in foptionsedit then begin + result:= msecomparestr(msestring(l),msestring(r)); + end + else begin + result:= msecomparetext(msestring(l),msestring(r)); + end; +end; + +function tcustomstringedit.getgridvalues: msestringarty; +begin + result:= tmsestringdatalist(checkgriddata).asarray; +// result:= tmsestringdatalist(fgridintf.getcol.datalist).asarray; +end; + +procedure tcustomstringedit.setgridvalues(const Value: msestringarty); +begin + tmsestringdatalist(checkgriddata).asarray:= value; +// tmsestringdatalist(fgridintf.getcol.datalist).asarray:= value; +end; +{ +function tcustomstringedit.isempty(const atext: msestring): boolean; +begin + if fvaluedefault <> '' then begin + result:= atext = fvaluedefault; + end + else begin + result:= atext = getnulltext; + end; +end; +} + +function tcustomstringedit.getdefaultvalue: pointer; +begin + result:= @fvaluedefault; +end; + +{$ifdef mse_with_ifi} +function tcustomstringedit.getifilink: tifistringlinkcomp; +begin + result:= tifistringlinkcomp(fifilink); +end; + +procedure tcustomstringedit.setifilink(const avalue: tifistringlinkcomp); +begin + inherited setifilink(avalue); +end; + +{$endif} + +function tcustomstringedit.isnull: boolean; +begin + result:= value = ''; +end; + +function tcustomstringedit.griddata: tgridmsestringdatalist; +begin + result:= tgridmsestringdatalist(inherited griddata); +end; + +procedure tcustomstringedit.setvaluedata(const source); +begin + value:= msestring(source); +end; + +procedure tcustomstringedit.getvaluedata(out dest); +begin + msestring(dest):= value; +end; + +{ tstringedit } + +{ tcustommemoedit } + +constructor tcustommemoedit.create(aowner: tcomponent); +begin + inherited; + internalcreateframe; + foptionswidget:= defaultoptionswidgetmousewheel; + foptionsedit:= defaultmemooptionsedit; + optionsedit1:= defaultmemooptionsedit1; + textflags:= defaultmemotextflags; + textflagsactive:= defaultmemotextflagsactive; +end; + +procedure tcustommemoedit.afterconstruction; +begin + inherited; + fcreated:= true; +end; + +procedure tcustommemoedit.internalcreateframe; +begin + tscrolleditframe.create(iscrollframe(self),iscrollbar(self)); + with frame do begin + sbhorz.pagesize:= 1; + sbvert.pagesize:= 1; + end; +end; + +procedure tcustommemoedit.mouseevent(var info: mouseeventinfoty); +begin + tscrolleditframe(fframe).mouseevent(info); + inherited; +end; + +function tcustommemoedit.getframe: tscrolleditframe; +begin + result:= tscrolleditframe(inherited getframe); +end; + +procedure tcustommemoedit.setframe(const avalue: tscrolleditframe); +begin + inherited setframe(avalue); +end; + +procedure tcustommemoedit.scrollevent(sender: tcustomscrollbar; + event: scrolleventty); +var + pagesize: integer; + stepsize: integer; + + procedure init; + begin + if sender = frame.sbvert then begin + stepsize:= feditor.font.lineheight; + if stepsize > 0 then begin + pagesize:= ((innerclientsize.cy - stepsize div 2) div stepsize) * stepsize; + end + else begin + pagesize:= innerclientsize.cy; + end; + end + else begin + stepsize:= innerclientsize.cx div 10; + pagesize:= innerclientsize.cx - stepsize; + end; + if stepsize < 2 then begin + stepsize:= 2; + end; + if pagesize < stepsize then begin + pagesize:= stepsize; + end; + end; + +var + int1: integer; + size1: sizety; + +begin + int1:= 0; + stepsize:= 0; + pagesize:= 0; + case event of + sbe_stepup: begin + init; + int1:= stepsize; + end; + sbe_stepdown: begin + init; + int1:= -stepsize; + end; + sbe_pageup,sbe_wheelup: begin + init; + int1:= pagesize; + end; + sbe_pagedown,sbe_wheeldown: begin + init; + int1:= -pagesize; + end; + sbe_valuechanged: begin + feditor.setscrollvalue(sender.value,sender = frame.sbhorz); + end; + end; + if int1 <> 0 then begin + size1:= feditor.textrect.size; + subsize1(size1,innerclientsize); + if sender = frame.sbvert then begin + if size1.cy > 0 then begin + sender.value:= sender.value + int1 / size1.cy; + end; + end + else begin + if size1.cx > 0 then begin + sender.value:= sender.value + int1 / size1.cx; + end; + end; + end; +end; + +procedure tcustommemoedit.updatescrollbars; +var + rect1: rectty; + size1: sizety; +begin + rect1:= feditor.textrect; + size1:= innerclientsize; + if (ftextrectbefore.cx <> rect1.cx) or + (ftextrectbefore.cy <> rect1.cy) or + (size1.cx <> fclientsizebefore.cx) or + (size1.cy <> fclientsizebefore.cy) then begin + ftextrectbefore:= rect1; + fclientsizebefore:= size1; + with frame do begin + if rect1.cx > 0 then begin + sbhorz.pagesize:= size1.cx / rect1.cx; + end + else begin + sbhorz.pagesize:= 1; + end; + if rect1.cy > 0 then begin + sbvert.pagesize:= size1.cy / rect1.cy; + end + else begin + sbvert.pagesize:= 1; + end; + if fupdatescrollbarcount < 10 then begin //limit recursions + inc(fupdatescrollbarcount); + try + tcustomframe1(fframe).updatestate; + finally + dec(fupdatescrollbarcount); + end; + end; + end; + end; +end; + +procedure tcustommemoedit.editnotification(var info: editnotificationinfoty); +var + rect1: rectty; +begin + inherited; + if fcreated and windowallocated then begin + case info.action of + ea_textchanged: begin + updatescrollbars; + end; + ea_caretupdating: begin + if fframe <> nil then begin + rect1.size:= feditor.textrect.size; + subsize1(rect1.size,feditor.destrect.size); + rect1.pos:= feditor.destrect.pos; + subpoint1(rect1.pos,innerclientpos); + with frame do begin + if rect1.cx > 0 then begin + sbhorz.value:= -rect1.x / rect1.cx; + end + else begin + sbhorz.value:= 0; + end; + if rect1.cy > 0 then begin + sbvert.value:= -rect1.y / rect1.cy; + end + else begin + sbvert.value:= 0; + end; + end; + end; + end; + ea_indexmoved: begin + fxpos:= feditor.caretpos.x; + end; + end; + end; +end; + +procedure tcustommemoedit.dokeydown(var info: keyeventinfoty); +var + int1,int2: integer; + rect1: rectty; + indexbefore: integer; +begin + if not (es_processed in info.eventstate) then begin + if info.shiftstate * shiftstatesmask - [ss_shift] = [] then begin + include(info.eventstate,es_processed); + with feditor do begin + int2:= fxpos; + int1:= 0; + case info.key of + key_pageup: begin + int1:= -(innerpaintrect.cy - self.font.lineheight); + end; + key_pagedown: begin + int1:= (innerpaintrect.cy - self.font.lineheight); + end; + key_up: begin + int1:= - self.font.lineheight; + end; + key_down: begin + int1:= self.font.lineheight; + end; + else begin + exclude(info.eventstate,es_processed); + end; + end; + if int1 <> 0 then begin + int1:= caretpos.y + int1; + rect1:= textrect; + if int1 < rect1.y then begin + int1:= rect1.y; + end; + if int1 >= rect1.y + rect1.cy then begin + int1:= rect1.y + rect1.cy - 1; + end; + indexbefore:= curindex; + moveindex(mousepostotextindex(makepoint(fxpos,int1)), + ss_shift in info.shiftstate); + if ss_shift in info.shiftstate then begin + invalidate; + end; + if fxpos < int2 then begin + fxpos:= int2; + end; + if (oe_exitoncursor in foptionsedit) and (indexbefore = curindex) and + (info.shiftstate = []) and + ((info.key = key_down) or (info.key = key_up)) then begin + exclude(info.eventstate,es_processed); + end; + end; + end; + end; + if not (es_processed in info.eventstate) then begin + inherited; + end; + end; +end; + +function tcustommemoedit.getnoscroll(): boolean; +begin + result:= inherited getnoscroll() or needsfocuspaintstate() and + (tcustomframe1(fframe).haspaintrectfocus()); + //do not scroll focusrect +end; + +procedure tcustommemoedit.setupeditor; +begin + inherited; + if not (fs_creating in tcustomframe1(fframe).fstate) then begin + updatescrollbars; + end; +end; + +procedure tcustommemoedit.domousewheelevent(var info: mousewheeleventinfoty); +begin + if fframe <> nil then begin + frame.domousewheelevent(info,false); + end; + inherited; +end; + +{ thexstringedit } + +function thexstringedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= tgridansistringdatalist.create(sender); +end; + +function thexstringedit.getdatalistclass: datalistclassty; +begin + result:= tgridansistringdatalist; +end; + +function thexstringedit.getgridvalue(const index: integer): ansistring; +begin + internalgetgridvalue(index,result); +end; + +procedure thexstringedit.setgridvalue(const index: integer; const Value: ansistring); +begin + internalsetgridvalue(index,value); +end; + +function thexstringedit.getgridvalues: stringarty; +begin + result:= tansistringdatalist(checkgriddata).asarray; +// result:= tansistringdatalist(fgridintf.getcol.datalist).asarray; +end; + +procedure thexstringedit.setgridvalues(const Value: stringarty); +begin + tansistringdatalist(checkgriddata).asarray:= value; +// tansistringdatalist(fgridintf.getcol.datalist).asarray:= value; +end; + +procedure thexstringedit.fillcol(const value: string); +begin + internalfillcol(value); +end; + +procedure thexstringedit.assigncol(const value: tansistringdatalist); +begin + internalassigncol(value); +end; + +procedure thexstringedit.dosetvalue(var avalue: ansistring; var accept: boolean); +begin + if accept and canevent(tmethod(fonsetvalue)) then begin + fonsetvalue(self,avalue,accept); + end; +end; + +procedure thexstringedit.texttovalue(var accept: boolean; const quiet: boolean); +var + mstr1: msestring; + str1: ansistring; +begin + try + mstr1:= feditor.text; + checktext(mstr1,accept); + if not accept then begin + exit; + end; + str1:= strtobytestr(printableascii(ansistring(mstr1))) + except + formaterror(quiet); + accept:= false + end; + if accept then begin + if not quiet then begin + dosetvalue(str1,accept); + end; + if accept then begin + value:= str1; + end; + end; +end; + +function thexstringedit.internaldatatotext(const data): msestring; +var + str1: ansistring; +begin + if @data = nil then begin + str1:= fvalue; + end + else begin + str1:= ansistring(data); + end; + if length(str1) > 256 then begin + result:= msestring(bytestrtostr(copy(str1,1,256),nb_hex,' '))+'...'; + end + else begin + result:= msestring(bytestrtostr(str1,nb_hex,' ')); + end; +end; + +procedure thexstringedit.valuetogrid(arow: integer); +begin + fgridintf.setdata(arow,fvalue); +end; + +procedure thexstringedit.gridtovalue(arow: integer); +begin + fgridintf.getdata(arow,fvalue); + inherited; +end; + +procedure thexstringedit.readstatvalue(const reader: tstatreader); +begin +// if fgridintf = nil then begin + value:= reader.readbinarystring(valuevarname,value); +// end; +end; + +procedure thexstringedit.writestatvalue(const writer: tstatwriter); +begin + writer.writebinarystring(valuevarname,value); +end; + +function thexstringedit.sortfunc(const l,r): integer; +begin + result:= stringcomp(ansistring(l),ansistring(r)); +end; + +procedure thexstringedit.setvalue(const Value: string); +begin + fvalue := Value; + valuechanged; +end; + +function thexstringedit.griddata: tgridansistringdatalist; +begin + result:= tgridansistringdatalist(inherited griddata); +end; + +procedure thexstringedit.setvaluedata(const source); +begin + value:= string(source); +end; + +procedure thexstringedit.getvaluedata(out dest); +begin + string(dest):= value; +end; + +{ tcustomdropdownedit } + +constructor tcustomdropdownedit.create(aowner: tcomponent); +begin + inherited; + fdropdown:= createdropdowncontroller; + fcontrollerintf:= idataeditcontroller(fdropdown); +end; + +destructor tcustomdropdownedit.destroy; +begin + inherited; + fdropdown.Free; +end; +{ +procedure tcustomdropdownedit.editnotification(var info: editnotificationinfoty); +begin + if fdropdown <> nil then begin + fdropdown.editnotification(info); + end; + inherited; +end; +} +{ +procedure tcustomdropdownedit.dokeydown(var info: keyeventinfoty); +begin + fdropdown.dokeydown(info); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; +} +{ +procedure tcustomdropdownedit.domousewheelevent(var info: mousewheeleventinfoty); +begin + fdropdown.domousewheelevent(info); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; +} +function tcustomdropdownedit.createdropdowncontroller: tcustomdropdowncontroller; +begin + result:= tdropdowncontroller.create(idropdown(self)); +end; + +procedure tcustomdropdownedit.loaded(); +begin + inherited; + tcustomdropdowncontroller1(fdropdown).updatereadonlystate(); + //for db dropdowns +end; + +procedure tcustomdropdownedit.dobeforedropdown; +begin + if canevent(tmethod(fonbeforedropdown)) then begin + fonbeforedropdown(self); + end; +end; + +procedure tcustomdropdownedit.doafterclosedropdown; +begin + if canevent(tmethod(fonafterclosedropdown)) then begin + fonafterclosedropdown(self); + end; +end; + +procedure tcustomdropdownedit.buttonaction(var action: buttonactionty; + const buttonindex: integer); +begin + //dummy +end; +{ +procedure tcustomdropdownedit.mouseevent(var info: mouseeventinfoty); +begin + tcustombuttonframe(fframe).mouseevent(info); + inherited; +end; +} +procedure tcustomdropdownedit.texttovalue(var accept: boolean; + const quiet: boolean); +begin + if (deo_selectonly in fdropdown.options) and + not fdropdown.dataselected then begin + if (text <> '') then begin + if not quiet and not (des_statreading in fstate) and + not (deo_autodropdown in fdropdown.options) then begin + accept:= false; + fdropdown.dropdown; + end + else begin + if feditor.canundo then begin //otherwise no userentry + accept:= false; + feditor.undo; + end; + end + end + else begin + tdropdowncontroller1(fdropdown).resetselection; + inherited; + end; + end + else begin + inherited; + end; +end; +{ +function tcustomdropdownedit.getcellframe: framety; +begin + result:= fframe.cellframe; +end; +} +function tcustomdropdownedit.getframe: tdropdownmultibuttonframe; +begin + result:= tdropdownmultibuttonframe(inherited getframe); +end; + +procedure tcustomdropdownedit.setframe(const avalue: tdropdownmultibuttonframe); +begin + inherited setframe(avalue); +end; +{ +procedure tcustomdropdownedit.internalcreateframe; +begin + fdropdown.createframe; +end; +} +procedure tcustomdropdownedit.dohide; +begin + fdropdown.canceldropdown; + inherited; +end; + +function tcustomdropdownedit.getassistiveflags(): assistiveflagsty; +begin + result:= inherited getassistiveflags(); + if fdropdown.hasdropdown() then begin + include(result,asf_hasdropdown); + end; +end; +{ +function tcustomdropdownedit.getassistivecaption(): msestring; +var + wi1: tcustomgrid; + intf1: iassistiveclientgrid; +begin + if fdropdown.hasdropdown() then begin + wi1:= tcustomgrid(fdropdown.dropdownwidget); + result:= iassistiveclientgrid(wi1).getassistivecellcaption(wi1.focusedcell); + end + else begin + result:= inherited getassistivecaption(); + end; +end; + +function tcustomdropdownedit.getassistivetext(): msestring; +var + wi1: tcustomgrid; + intf1: iassistiveclientgrid; +begin + if fdropdown.hasdropdown() then begin + wi1:= tcustomgrid(fdropdown.dropdownwidget); + result:= iassistiveclientgrid(wi1).getassistivecelltext(wi1.focusedcell); + end + else begin + result:= inherited getassistivetext(); + end; +end; +} +{ +procedure tcustomdropdownedit.updatereadonlystate; +begin + inherited; + if fdropdown <> nil then begin + fdropdown.updatereadonlystate; + end; +end; +} +function tcustomdropdownedit.getvalueempty: integer; +begin + result:= -1; +end; + +procedure tcustomdropdownedit.dostatread(const reader: tstatreader); +begin + inherited; + fdropdown.dostatread(reader); +end; + +procedure tcustomdropdownedit.dostatwrite(const writer: tstatwriter); +begin + inherited; + fdropdown.dostatwrite(writer); +end; + +{$ifdef mse_with_ifi} +function tcustomdropdownedit.getifidatalinkintf: iifidatalink; +begin + result:= iifidropdownlistdatalink(self); +end; + +procedure tcustomdropdownedit.ifidropdownlistchanged(const acols: tifidropdowncols); +begin +end; +{$endif} + +{ +function tcustomdropdownedit.getbutton: tdropdownbutton; +begin + with tdropdownmultibuttonframe(fframe) do begin + result:= tdropdownbutton(buttons[activebutton]); + end; +end; + +procedure tcustomdropdownedit.setbutton(const avalue: tdropdownbutton); +begin + with tdropdownmultibuttonframe(fframe) do begin + tdropdownbutton(buttons[activebutton]).assign(avalue); + end; +end; +} +{ tcustomdropdownwidgetedit } + +function tcustomdropdownwidgetedit.createdropdowncontroller: tcustomdropdowncontroller; +begin + result:= tdropdownwidgetcontroller.create(idropdownwidget(self)); +end; + +function tcustomdropdownwidgetedit.getdropdown: tdropdownwidgetcontroller; +begin + result:= tdropdownwidgetcontroller(fdropdown); +end; + +procedure tcustomdropdownwidgetedit.setdropdown( + const avalue: tdropdownwidgetcontroller); +begin + fdropdown.Assign(avalue); +end; + +{ tcustomdropdownlistedit } + +function tcustomdropdownlistedit.getdropdownitems: tdropdowndatacols; +begin + result:= nil; +end; + +function tcustomdropdownlistedit.getdropdown: tdropdownlistcontroller; +begin + result:= tdropdownlistcontroller(fdropdown); +end; + +procedure tcustomdropdownlistedit.setdropdown( + const avalue: tdropdownlistcontroller); +begin + fdropdown.Assign(avalue); +end; + +function tcustomdropdownlistedit.createdropdowncontroller: + tcustomdropdowncontroller; +begin + result:= tdropdownlistcontroller.create(idropdownlist(self)); +end; + +procedure tcustomdropdownlistedit.internalsort(const acol: integer; + out sortlist: integerarty); +var + int1: integer; +begin + with tdropdownlistcontroller(fdropdown) do begin + cols.beginupdate; + try + cols[acol].sort(sortlist,false); + for int1:= 0 to cols.count - 1 do begin + cols[int1].rearange(sortlist); + end; + finally + cols.endupdate; + end; + end; +end; + +procedure tcustomdropdownlistedit.sort(const acol: integer); +var + ar1: integerarty; +begin + internalsort(acol,ar1); +end; + +{$ifdef mse_with_ifi} +function tcustomdropdownlistedit.getifilink: tifidropdownlistlinkcomp; +begin + result:= tifidropdownlistlinkcomp(fifilink); +end; + +procedure tcustomdropdownlistedit.setifilink1(const avalue: tifidropdownlistlinkcomp); +begin + setifilink0(avalue); +end; + +function tcustomdropdownlistedit.getifidatalinkintf: iifidatalink; +begin + result:= iifidropdownlistdatalink(self); +end; + +function tcustomdropdownlistedit.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iifidropdownlistdatalink); +end; + +procedure tcustomdropdownlistedit.ifidropdownlistchanged( + const acols: tifidropdowncols); +begin + dropdown.cols.assign(acols); +end; + +{$endif} + +function tcustomdropdownlistedit.geteditframe: framety; +begin + result:= nullframe; + if (fdropdown <> nil) and not(csdestroying in componentstate) and + (tcustomdropdownlistcontroller(fdropdown).imagelist <> nil) then begin + with tcustomdropdownlistcontroller1(fdropdown)do begin + result.left:= tcustomdropdownlistcontroller(fdropdown).imagelist.width + + fimageframe.left + fimageframe.right; + end; + end; +end; + +procedure tcustomdropdownlistedit.getautopaintsize(var asize: sizety); +var + int1: integer; +begin + inherited; + with tcustomdropdownlistcontroller1(fdropdown)do begin + if fimagelist <> nil then begin + int1:= fimagelist.height + fimageframe.top + fimageframe.bottom; + if int1 > asize.cy then begin + asize.cy:= int1; + end; + end; + end; +end; + +procedure tcustomdropdownlistedit.imagelistchanged; +begin + if componentstate*[csloading,csdestroying] = [] then begin + setupeditor; + formatchanged(); +// checkautosize; + end; +end; + +procedure tcustomdropdownlistedit.paintimage(const canvas: tcanvas); +begin + with tcustomdropdownlistcontroller1(fdropdown) do begin + if imagelist <> nil then begin + imagelist.paint(canvas,itemindex, + deflaterect(clientrect,fimageframe),[al_ycentered]); + end; + end; + inherited; +end; + +procedure tcustomdropdownlistedit.dochange; +begin + if tcustomdropdownlistcontroller(fdropdown).imagelist <> nil then begin + invalidate; + end; + inherited; +end; + +{ thistorycontroller } + +constructor thistorycontroller.create(const intf: idropdownlist); +begin + inherited; + fhistorymaxcount:= defaulthistorymaxcount; + foptions:= defaulthistoryeditoptions; +end; + +procedure thistorycontroller.checkmaxcount; +begin + if valuelist.count > fhistorymaxcount then begin + valuelist.count:= fhistorymaxcount; + end; +end; + +procedure thistorycontroller.sethistorymaxcount(const aValue: integer); +begin + fhistorymaxcount := avalue; + checkmaxcount; +end; + +procedure thistorycontroller.clearhistory; +begin + cols.clear; +end; +{ +function thistorycontroller.gethistory: tmsestringdatalist; +begin + result:= valuelist; +end; +} +procedure thistorycontroller.savehistoryvalue(const avalue: msestring); +var + int1: integer; + list: tmsestringdatalist; +begin + list:= valuelist; + list.insert(0,avalue); + int1:= 1; + while int1 < list.count do begin + if list[int1] = avalue then begin + list.deletedata(int1); + end + else begin + inc(int1); + end; + end; + checkmaxcount; +end; + +procedure thistorycontroller.readstate(const reader: tstatreader); +begin + reader.readdatalist('history',valuelist); +end; + +procedure thistorycontroller.writestate(const writer: tstatwriter); +begin + writer.writedatalist('history',valuelist); +end; + +function thistorycontroller.gethistory: msestringarty; +begin + result:= valuelist.asarray; +end; + +procedure thistorycontroller.sethistory(const avalue: msestringarty); +begin + valuelist.asarray:= copy(avalue,0,fhistorymaxcount); +end; + +{ tcustomhistoryedit } + +constructor tcustomhistoryedit.create(aowner: tcomponent); +begin + inherited; +end; + +procedure tcustomhistoryedit.savehistoryvalue; +begin + thistorycontroller(fdropdown).savehistoryvalue(fvalue); +end; + +procedure tcustomhistoryedit.loaded; +begin + inherited; +// checkmaxcount; +end; + +procedure tcustomhistoryedit.readstatstate(const reader: tstatreader); +begin + inherited; + thistorycontroller(fdropdown).readstate(reader); +end; + +procedure tcustomhistoryedit.writestatstate(const writer: tstatwriter); +begin + inherited; + thistorycontroller(fdropdown).writestate(writer); +end; + +procedure tcustomhistoryedit.setdropdown(const avalue: thistorycontroller); +begin + fdropdown.Assign(avalue); +end; + +function tcustomhistoryedit.getdropdown: thistorycontroller; +begin + result:= thistorycontroller(fdropdown); +end; + +procedure tcustomhistoryedit.texttovalue(var accept: boolean; const quiet: boolean); +begin + inherited; + if not quiet and accept and + (deo_autosavehistory in thistorycontroller(fdropdown).foptions) then begin + savehistoryvalue; + end; +end; + +function tcustomhistoryedit.createdropdowncontroller: tcustomdropdowncontroller; +begin + result:= thistorycontroller.create(idropdownlist(self)); +end; + +{ tnumedit } + +constructor tnumedit.create(aowner: tcomponent); +begin + inherited; + textflags:= defaultnumedittextflags; +end; + +{ tcustomintegeredit } + +constructor tcustomintegeredit.create(aowner: tcomponent); +begin + fbase:= nb_dec; + fbitcount:= 32; + fvaluemax:= maxint; + inherited; +end; + +function tcustomintegeredit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= tgridintegerdatalist.create(sender); +end; + +function tcustomintegeredit.getdatalistclass: datalistclassty; +begin + result:= tgridintegerdatalist; +end; + +procedure tcustomintegeredit.valuetogrid(arow: integer); +begin + fgridintf.setdata(arow,fvalue); +end; + +procedure tcustomintegeredit.gridtovalue(arow: integer); +begin + fgridintf.getdata(arow,fvalue); + inherited; +end; + +procedure tcustomintegeredit.setvalue(const Value: integer); +begin + fvalue := Value; + if fvaluechecking = 0 then begin + fisnull:= false; + end; + valuechanged; +end; + +function tcustomintegeredit.gettextvalue(var accept: boolean; + const quiet: boolean): integer; +var + mstr1: msestring; +begin + if fisnull then begin + result:= 0; + end + else begin + try + mstr1:= text; + checktext(mstr1,accept); + if not accept then begin + exit; + end; + result:= strtointvalue(mstr1,fbase); + except + formaterror(quiet); + accept:= false + end; + end; +end; + +procedure tcustomintegeredit.texttovalue(var accept: boolean; const quiet: boolean); +var + int1: integer; +// mstr1: msestring; +begin + int1:= gettextvalue(accept,quiet); +{ + if fisnull then begin + int1:= 0; + end + else begin + try + mstr1:= feditor.text; + checktext(mstr1,accept); + if not accept then begin + exit; + end; + int1:= strtointvalue(mstr1,fbase); + except + formaterror(quiet); + accept:= false + end; + end; +} + if accept then begin + if not fisnull then begin + if fvaluemax < fvaluemin then begin //unsigned + if (longword(int1) < longword(fvaluemin)) or + (longword(int1) > longword(fvaluemax)) then begin + rangeerror(fvaluemin,fvaluemax,quiet); + accept:= false; + end; + end + else begin + if (int1 < fvaluemin) or (int1 > fvaluemax) then begin + rangeerror(fvaluemin,fvaluemax,quiet); + accept:= false; + end; + end; + end; + if accept then begin + if not quiet then begin + if canevent(tmethod(fonsetvalue)) then begin + fonsetvalue(self,int1,accept); + end; + {$ifdef mse_with_ifi} + ifisetvalue(int1,accept); + {$endif} + end; + if accept then begin + value:= int1; + end; + end; + end; +end; + +procedure tcustomintegeredit.texttodata(const atext: msestring; var data); +var + int1: integer; +begin + try + int1:= strtointvalue(atext,fbase); + except + int1:= 0; + end; + if int1 < fvaluemin then begin + int1:= fvaluemin; + end; + if int1 > fvaluemax then begin + int1:= fvaluemax; + end; + integer(data):= int1; +end; + +procedure tcustomintegeredit.readstatvalue(const reader: tstatreader); +begin +// if fgridintf <> nil then begin +// with fgridintf.getcol do begin +// with tintegerdatalist(datalist) do begin +// min:= fmin; +// max:= fmax; +// end; +// dostatread(reader); +// end; +// reader.readintegerdatalist(valuevarname, +// tintegerdatalist(fgridintf.getcol.datalist),fmin,fmax); +// end +// else begin + value:= reader.readinteger(valuevarname,value,fvaluemin,fvaluemax); +// end; +end; + +procedure tcustomintegeredit.writestatvalue(const writer: tstatwriter); +begin + writer.writeinteger(valuevarname,value); +end; + +procedure tcustomintegeredit.setnullvalue; +begin + value:= 0; + fisnull:= true; + nullvalueset(); +end; + +procedure tcustomintegeredit.setbase(const Value: numbasety); +begin + if fbase <> value then begin + fbase := Value; + formatchanged; + end; +end; + +procedure tcustomintegeredit.setbitcount(const Value: integer); +begin + if fbitcount <> value then begin + fbitcount := Value; + formatchanged; + end; +end; + +function tcustomintegeredit.internaldatatotext(const data): msestring; +begin + if @data = nil then begin + result:= msestring(intvaluetostr(fvalue,fbase,fbitcount)); + end + else begin + result:= msestring(intvaluetostr(integer(data),fbase,fbitcount)); + end; +end; + +function tcustomintegeredit.getgridvalue(const index: integer): integer; +begin + internalgetgridvalue(index,result); +end; + +procedure tcustomintegeredit.setgridvalue(const index, Value: integer); +begin + internalsetgridvalue(index,value); +end; + +function tcustomintegeredit.getgridvalues: integerarty; +begin + result:= tintegerdatalist(checkgriddata).asarray; +// result:= tintegerdatalist(fgridintf.getcol.datalist).asarray; +end; + +procedure tcustomintegeredit.setgridvalues(const Value: integerarty); +begin + tintegerdatalist(checkgriddata).asarray:= value; +// tintegerdatalist(fgridintf.getcol.datalist).asarray:= value; +end; + +procedure tcustomintegeredit.fillcol(const value: integer); +begin + internalfillcol(value); +end; + +procedure tcustomintegeredit.assigncol(const value: tintegerdatalist); +begin + internalassigncol(value); +end; + +{$ifdef mse_with_ifi} +function tcustomintegeredit.getifilink: tifiintegerlinkcomp; +begin + result:= tifiintegerlinkcomp(fifilink); +end; + +procedure tcustomintegeredit.setifilink(const avalue: tifiintegerlinkcomp); +begin + inherited setifilink(avalue); +end; + +{$endif} + +function tcustomintegeredit.getdefaultvalue: pointer; +begin + result:= @fvaluedefault; +end; + +procedure tcustomintegeredit.setvaluemin(const avalue: integer); +begin + fvaluemin:= avalue; + if fdatalist <> nil then begin + with tgridintegerdatalist(fdatalist) do begin + min:= avalue; + end; + end; +end; + +procedure tcustomintegeredit.setvaluemax(const avalue: integer); +begin + fvaluemax:= avalue; + if fdatalist <> nil then begin + with tgridintegerdatalist(fdatalist) do begin + max:= avalue; + end; + end; +end; + + +procedure tcustomintegeredit.updatedatalist; +begin + with tgridintegerdatalist(fdatalist) do begin + min:= self.valuemin; + max:= self.valuemax; + end; +end; + +procedure tcustomintegeredit.readmin(reader: treader); +begin + valuemin:= reader.readinteger; +end; + +procedure tcustomintegeredit.readmax(reader: treader); +begin + valuemax:= reader.readinteger; +end; + +procedure tcustomintegeredit.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('min',@readmin,nil,false); + filer.defineproperty('max',@readmax,nil,false); +end; + +function tcustomintegeredit.griddata: tgridintegerdatalist; +begin + result:= tgridintegerdatalist(inherited griddata); +end; + +procedure tcustomintegeredit.setvaluedata(const source); +begin + value:= integer(source); +end; + +procedure tcustomintegeredit.getvaluedata(out dest); +begin + integer(dest):= value; +end; + +{ tcustomint64edit } + +constructor tcustomint64edit.create(aowner: tcomponent); +begin + fbase:= nb_dec; + fbitcount:= 64; + fvaluemax:= maxint64; + inherited; +end; + +function tcustomint64edit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= tgridint64datalist.create(sender); +end; + +function tcustomint64edit.getdatalistclass: datalistclassty; +begin + result:= tgridint64datalist; +end; + +procedure tcustomint64edit.valuetogrid(arow: integer); +begin + fgridintf.setdata(arow,fvalue); +end; + +procedure tcustomint64edit.gridtovalue(arow: integer); +begin + fgridintf.getdata(arow,fvalue); + inherited; +end; + +procedure tcustomint64edit.setvalue(const Value: int64); +begin + fvalue := Value; + if fvaluechecking = 0 then begin + fisnull:= false; + end; + valuechanged; +end; + +procedure tcustomint64edit.texttovalue(var accept: boolean; const quiet: boolean); +var + int1: int64; + mstr1: msestring; +begin + if fisnull then begin + int1:= 0; + end + else begin + try + mstr1:= feditor.text; + checktext(mstr1,accept); + if not accept then begin + exit; + end; + int1:= strtointvalue64(mstr1,fbase); + except + formaterror(quiet); + accept:= false + end; + end; + if accept then begin + if not fisnull then begin + if fvaluemax < fvaluemin then begin //unsigned + if (uint64(int1) < uint64(fvaluemin)) or + (uint64(int1) > uint64(fvaluemax)) then begin + rangeerror(fvaluemin,fvaluemax,quiet); + accept:= false; + end; + end + else begin + if (int1 < fvaluemin) or (int1 > fvaluemax) then begin + rangeerror(fvaluemin,fvaluemax,quiet); + accept:= false; + end; + end; + end; + if accept then begin + if not quiet then begin + if canevent(tmethod(fonsetvalue)) then begin + fonsetvalue(self,int1,accept); + end; + {$ifdef mse_with_ifi} + ifisetvalue(int1,accept); + {$endif} + end; + if accept then begin + value:= int1; + end; + end; + end; +end; + +procedure tcustomint64edit.texttodata(const atext: msestring; var data); +var + int1: int64; +begin + try + int1:= strtointvalue64(atext,fbase); + except + int1:= 0; + end; + if int1 < fvaluemin then begin + int1:= fvaluemin; + end; + if int1 > fvaluemax then begin + int1:= fvaluemax; + end; + int64(data):= int1; +end; + +procedure tcustomint64edit.readstatvalue(const reader: tstatreader); +begin +// if fgridintf <> nil then begin +// with fgridintf.getcol do begin +// with tint64datalist(datalist) do begin +// min:= fmin; +// max:= fmax; +// end; +// dostatread(reader); +// end; +// reader.readintegerdatalist(valuevarname, +// tintegerdatalist(fgridintf.getcol.datalist),fmin,fmax); +// end +// else begin + value:= reader.readint64(valuevarname,value,fvaluemin,fvaluemax); +// end; +end; + +procedure tcustomint64edit.writestatvalue(const writer: tstatwriter); +begin + writer.writeint64(valuevarname,value); +end; + +procedure tcustomint64edit.setnullvalue; +begin + value:= 0; +// text:= ''; + fisnull:= true; + nullvalueset(); +end; + +procedure tcustomint64edit.setbase(const Value: numbasety); +begin + if fbase <> value then begin + fbase := Value; + formatchanged; + end; +end; + +procedure tcustomint64edit.setbitcount(const Value: integer); +begin + if fbitcount <> value then begin + fbitcount := Value; + formatchanged; + end; +end; + +function tcustomint64edit.internaldatatotext(const data): msestring; +begin + if @data = nil then begin + result:= msestring(intvaluetostr(fvalue,fbase,fbitcount)); + end + else begin + result:= msestring(intvaluetostr(int64(data),fbase,fbitcount)); + end; +end; + +function tcustomint64edit.getgridvalue(const index: integer): int64; +begin + internalgetgridvalue(index,result); +end; + +procedure tcustomint64edit.setgridvalue(const index: integer; + const Value: int64); +begin + internalsetgridvalue(index,value); +end; + +function tcustomint64edit.getgridvalues: int64arty; +begin + result:= tint64datalist(checkgriddata).asarray; +// result:= tint64datalist(fgridintf.getcol.datalist).asarray; +end; + +procedure tcustomint64edit.setgridvalues(const Value: int64arty); +begin + tint64datalist(checkgriddata).asarray:= value; +// tint64datalist(fgridintf.getcol.datalist).asarray:= value; +end; + +{$ifdef mse_with_ifi} +function tcustomint64edit.getifilink: tifiint64linkcomp; +begin + result:= tifiint64linkcomp(fifilink); +end; + +procedure tcustomint64edit.setifilink(const avalue: tifiint64linkcomp); +begin + inherited setifilink(avalue); +end; + +procedure tcustomint64edit.readmin(reader: treader); +begin + valuemin:= reader.readint64; +end; + +procedure tcustomint64edit.readmax(reader: treader); +begin + valuemax:= reader.readint64; +end; + +procedure tcustomint64edit.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('min',@readmin,nil,false); + filer.defineproperty('max',@readmax,nil,false); +end; + +{$endif} +procedure tcustomint64edit.fillcol(const value: int64); +begin + internalfillcol(value); +end; + +procedure tcustomint64edit.assigncol(const value: tint64datalist); +begin + internalassigncol(value); +end; + +function tcustomint64edit.getdefaultvalue: pointer; +begin + result:= @fvaluedefault; +end; + +function tcustomint64edit.griddata: tgridint64datalist; +begin + result:= tgridint64datalist(inherited griddata); +end; + +procedure tcustomint64edit.setvaluedata(const source); +begin + value:= int64(source); +end; + +procedure tcustomint64edit.getvaluedata(out dest); +begin + int64(dest):= value; +end; +{ +procedure tcustomint64edit.setmin(const avalue: int64); +begin + fmin:= avalue; + if fdatalist <> nil then begin + with tgridint64datalist(fdatalist) do begin + min:= avalue + end; + end; +end; + +procedure tcustomint64edit.setmax(const avalue: int64); +begin + fmax:= avalue; + if fdatalist <> nil then begin + with tgridint64datalist(fdatalist) do begin + max:= avalue + end; + end; +end; + +procedure tcustomint64edit.updatedatalist; +begin + with tgridint64datalist(fdatalist) do begin + min:= self.min; + max:= self.max; + end; +end; +} + +{ tkeystringdropdowncontroller } + +constructor tkeystringdropdowncontroller.create(const intf: idropdownlist); +begin + inherited; + options:= defaultkeystringdropdownoptions; + cols.count:= 2; + valuecol:= 1; + cols[1].options:= cols[1].options + [co_invisible]; +end; + +function tkeystringdropdowncontroller.getindex(const akey: msestring): integer; + //todo: non linear search +var + int1: integer; + po1: pmsestringaty; +begin + result:= -1; + with cols[valuecol] do begin + po1:= datapo; + for int1:= 0 to count - 1 do begin + if po1^[int1] = akey then begin + result:= int1; + break; + end; + end; + end; +end; + +{ tcustomkeystringedit } + +procedure tcustomkeystringedit.setvalue(const avalue: msestring); +begin + with tkeystringdropdowncontroller(fdropdown) do begin + with tdropdowncols1(cols) do begin + fitemindex:= getindex(avalue); + if fitemindex >= 0 then begin + fkeyvalue:= avalue; + end; + end; + end; + fvalue1:= avalue; + valuechanged; +end; + +procedure tcustomkeystringedit.readstatvalue(const reader: tstatreader); +begin + value:= reader.readmsestring(valuevarname,value); +end; + +procedure tcustomkeystringedit.writestatvalue(const writer: tstatwriter); +begin + writer.writemsestring(valuevarname,value); +end; + +function tcustomkeystringedit.createdropdowncontroller: tcustomdropdowncontroller; +begin + result:= tkeystringdropdowncontroller.create(idropdownlist(self)); +end; + +procedure tcustomkeystringedit.texttovalue(var accept: boolean; + const quiet: boolean); +var + mstr1: msestring; + int1: integer; +begin + with tdropdownlistcontroller(fdropdown) do begin + int1:= itemindex; + if (int1 >= 0) and (text <> '') then begin +// mstr1:= cols[valuecol][int1]; + mstr1:= tdropdowncols1(cols).fkeyvalue; + end + else begin + mstr1:= ''; + end; + end; + checktext(mstr1,accept); + if not accept then begin + exit; + end; + if not quiet then begin + if canevent(tmethod(fonsetvalue)) then begin + fonsetvalue(self,mstr1,accept); + end; +{$ifdef mse_with_ifi} + ifisetvalue(mstr1,accept); +{$endif} + end; + if accept then begin + value:= mstr1; + end; + if int1 < 0 then begin + text:= ''; //for setnullvalue + end; +end; + +procedure tcustomkeystringedit.setnullvalue; +begin + dropdown.itemindex:= -1; + nullvalueset(); +end; + +function tcustomkeystringedit.internaldatatotext(const data): msestring; +var + int1: integer; +begin + with tkeystringdropdowncontroller(fdropdown) do begin + if @data = nil then begin + int1:= itemindex; + if int1 = -3 then begin + int1:= getindex(fvalue1); + tdropdowncols1(cols).fitemindex:= int1; + end; + end + else begin + int1:= getindex(msestring(data)); + end; + if int1 >= 0 then begin + result:= cols[0][int1]; + end + else begin + result:= ''; + end; + end; +end; + +procedure tcustomkeystringedit.texttodata(const atext: msestring; var data); +begin + //not supported +end; + +//function tcustomkeystringedit.getdefaultvalue: pointer; +//begin +// result:= @fvaluedefault; +//end; + +procedure tcustomkeystringedit.valuetogrid(arow: integer); +begin + fgridintf.setdata(arow,fvalue1); +end; + +procedure tcustomkeystringedit.gridtovalue(arow: integer); +begin + fgridintf.getdata(arow,fvalue1); + tdropdowncols1(tkeystringdropdowncontroller(fdropdown).cols).fitemindex:= -3; + valuetotext; +end; + +procedure tcustomkeystringedit.loaded; +begin + inherited; + if canevent(tmethod(foninit)) then begin + foninit(self); + end; +end; + +procedure tcustomkeystringedit.setvaluedata(const source); +begin + value:= msestring(source); +end; + +procedure tcustomkeystringedit.getvaluedata(out dest); +begin + msestring(dest):= value; +end; + +{ tcustomenuedit } + +constructor tcustomenuedit.create(aowner: tcomponent); +begin + fvalue1:= -1; + fvaluedefault1:= -1; + fvalueempty:= -1; + fbase:= nb_dec; + fbitcount:= 32; + fvaluemin:= -1; + fvaluemax:= maxint; + inherited; +end; + +function getindex1(const avalue: integer; + const enums: integerarty; const offset: integer): integer; +var + int1: integer; +begin + if enums <> nil then begin + result:= -1; + for int1:= 0 to high(enums) do begin + if avalue = enums[int1] then begin + result:= int1; + break; + end; + end; + end + else begin + result:= avalue - offset; + if result < 0 then begin + result:= -1; + end; + end; +end; + +function tcustomenuedit.getindex(avalue: integer): integer; +begin + if avalue = fvalueempty then begin + result:= -1; + end + else begin + result:= getindex1(avalue,enums,fvalueoffset); + if result < 0 then begin + result:= -1; + end; + end; +end; + +procedure tcustomenuedit.texttodata(const atext: msestring; var data); +begin + //not supported +end; + +function tcustomenuedit.internaldatatotext(const data): msestring; +var + int1,int2: integer; +begin + with tdropdownlistcontroller(fdropdown) do begin + if @data = nil then begin + int1:= fvalue1; + end + else begin + int1:= integer(data); + end; + int2:= getindex(int1); + if (int2 < 0) or (int2 >= valuelist.count) then begin + if not (deo_selectonly in options) and (int1 <> fvalueempty) then begin + result:= msestring(intvaluetostr(int1,fbase,fbitcount)); + end + else begin + result:= ''; + end; + end + else begin + result:= valuelist[int2]; + end; + end; +end; + +function tcustomenuedit.enumname(const avalue: integer): msestring; +begin + result:= datatotext(avalue); +end; + +procedure tcustomenuedit.clear; +begin + enums:= nil; + tdropdownlistcontroller(fdropdown).cols.clear; +end; + +function tcustomenuedit.addrow(const aitems: array of msestring; + const enum: integer = -1): integer; //returns itemindex + //enum = -1 -> no enum set +var + int1,int2: integer; +begin + result:= tdropdownlistcontroller(fdropdown).cols.addrow(aitems); + if enum >= 0 then begin + int1:= length(enums); + if int1 <= result then begin + setlength(enums,result+1); + for int2:= int1 to result-1 do begin + enums[int2]:= -1; + end; + end; + enums[result]:= enum; + end; +end; + +procedure tcustomenuedit.fillcol(const avalue: integer); +begin + internalfillcol(avalue); +end; + +function tcustomenuedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= tgridenumdatalist.create(sender); +end; + +function tcustomenuedit.getdatalistclass: datalistclassty; +begin + result:= tgridenumdatalist; +end; + +procedure tcustomenuedit.setvalue(const avalue: integer); +begin + tdropdowncols1(tcustomdropdownlistcontroller(fdropdown).cols).fitemindex:= + getindex(avalue); + fvalue1:= avalue; + valuechanged; +end; + +function tcustomenuedit.getgridvalue(const index: integer): integer; +begin + internalgetgridvalue(index,result); +end; + +procedure tcustomenuedit.setgridvalue(const index, aValue: integer); +begin + internalsetgridvalue(index,avalue); +end; + +function tcustomenuedit.getgridvalues: integerarty; +begin + result:= tintegerdatalist(checkgriddata).asarray; +// result:= tintegerdatalist(fgridintf.getcol.datalist).asarray; +end; + +procedure tcustomenuedit.setgridvalues(const avalue: integerarty); +begin + tintegerdatalist(checkgriddata).asarray:= avalue; +// tintegerdatalist(fgridintf.getcol.datalist).asarray:= avalue; +end; + +function tcustomenuedit.getdefaultvalue: pointer; +begin + result:= @fvaluedefault1; +end; + +procedure tcustomenuedit.gridtovalue(arow: integer); +begin + fgridintf.getdata(arow,fvalue1); + valuetotext; +end; + +procedure tcustomenuedit.texttovalue(var accept: boolean; const quiet: boolean); +var + int1: integer; + mstr1: msestring; +begin + if (tdropdownlistcontroller(fdropdown).itemindex < 0) and + (trim(text) = '') then begin + int1:= fvalueempty; + end + else begin + int1:= tdropdownlistcontroller(fdropdown).itemindex; + if (int1 >= 0) and (int1 <= high(enums)) then begin + int1:= enums[int1]; + end + else begin + if int1 >= 0 then begin + int1:= int1 + fvalueoffset; + end + else begin + if not (deo_selectonly in fdropdown.options) and + not (des_isdb in fstate) then begin + try + mstr1:= feditor.text; + checktext(mstr1,accept); + if not accept then begin + exit; + end; + int1:= strtointvalue(mstr1,fbase); + except + accept:= false; + formaterror(quiet); + end; + end; + end; + end; + end; + if not ({(des_isdb in fstate) and} (int1 = fvalueempty)) and + (int1 < fvaluemin) or (int1 > fvaluemax) then begin + rangeerror(fvaluemin,fvaluemax,quiet); + accept:= false; + end; + if accept then begin + if not quiet then begin + if canevent(tmethod(fonsetvalue1)) then begin + fonsetvalue1(self,int1,accept); + end; + {$ifdef mse_with_ifi} + ifisetvalue(int1,accept); + {$endif} + end; + if accept then begin + value:= int1; + end; + end; +end; + +procedure tcustomenuedit.valuetogrid(arow: integer); +begin + fgridintf.setdata(arow,fvalue1); +end; + +procedure tcustomenuedit.readstatvalue(const reader: tstatreader); +var + min1,max1: integer; +begin +// if fgridintf <> nil then begin +// fgridintf.getcol.dostatread(reader); +// end +// else begin + if enums <> nil then begin + min1:= fvaluemin; + max1:= fvaluemax; + end + else begin + if deo_forceselect in fdropdown.options then begin + min1:= 0; + end + else begin + min1:= fvalueempty; + end; + with tenumdropdowncontroller(fdropdown) do begin + max1:= cols[valuecol].count - 1; + end; + end; + value:= reader.readinteger(valuevarname,value,min1,max1); +// end; +end; + +procedure tcustomenuedit.writestatvalue(const writer: tstatwriter); +begin + writer.writeinteger(valuevarname,value); +end; + +function tcustomenuedit.createdropdowncontroller: tcustomdropdowncontroller; +begin + result:= tenumdropdowncontroller.create(idropdownlist(self)); +end; + +procedure tcustomenuedit.internalsort(const acol: integer; + out sortlist: integerarty); +var + enum1: integerarty; + int1: integer; +begin + tdropdownlistcontroller(fdropdown).cols.beginupdate; + try + inherited internalsort(acol,sortlist); + if enums <> nil then begin + setlength(enum1,length(sortlist)); + for int1:= 0 to high(enum1) do begin + if sortlist[int1] > high(enums) then begin + enum1[int1]:= -1; + end + else begin + enum1[int1]:= enums[sortlist[int1]]; + end; + end; + enums:= enum1; + end; + finally + tdropdownlistcontroller(fdropdown).cols.endupdate; + end; +end; + +procedure tcustomenuedit.setbase(const avalue: numbasety); +begin + if fbase <> avalue then begin + fbase:= avalue; + formatchanged; + end; +end; + +procedure tcustomenuedit.setbitcount(const avalue: integer); +begin + if fbitcount <> avalue then begin + fbitcount:= avalue; + formatchanged; + end; +end; + +procedure tcustomenuedit.setvalueoffset(avalue: integer); +begin + if avalue < 0 then begin + avalue:= 0; + end; + if avalue <> fvalueoffset then begin + fvalueoffset:= avalue; + value:= value; //update itemindex + end; +end; + +procedure tcustomenuedit.assigncol(const avalue: tintegerdatalist); +begin + internalassigncol(avalue); +end; + +function tcustomenuedit.getvalueempty: integer; +begin + result:= fvalueempty; +end; + +function tcustomenuedit.textcellcopy: boolean; +begin + result:= false; +end; + +{$ifdef mse_with_ifi} +function tcustomenuedit.getifilink: tifienumlinkcomp; +begin + result:= tifienumlinkcomp(fifilink); +end; + +procedure tcustomenuedit.setifilink1(const avalue: tifienumlinkcomp); +begin + setifilink0(avalue); +end; +{$endif} + +procedure tcustomenuedit.setvaluemin(const avalue: integer); +begin + fvaluemin:= avalue; + if fdatalist <> nil then begin + with tgridenumdatalist(fdatalist) do begin + min:= avalue; + end; + end; +end; + +procedure tcustomenuedit.setvaluemax(const avalue: integer); +begin + fvaluemax:= avalue; + if fdatalist <> nil then begin + with tgridenumdatalist(fdatalist) do begin + max:= avalue; + end; + end; +end; + +procedure tcustomenuedit.updatedatalist; +begin + with tgridenumdatalist(fdatalist) do begin + min:= self.valuemin; + max:= self.valuemax; + end; +end; + +procedure tcustomenuedit.paintimage(const canvas: tcanvas); +var + int1: integer; +begin + with tcustomdropdownlistcontroller1(fdropdown) do begin + if imagelist <> nil then begin + int1:= value; + if canvas.drawinfopo <> nil then begin + with cellinfoty(canvas.drawinfopo^) do begin + int1:= pinteger(datapo)^; + end; + end; + imagelist.paint(canvas,int1, + deflaterect(clientrect,fimageframe),[al_ycentered]); + end; + end; +end; + +procedure tcustomenuedit.readmin(reader: treader); +begin + valuemin:= reader.readinteger; +end; + +procedure tcustomenuedit.readmax(reader: treader); +begin + valuemax:= reader.readinteger; +end; + +procedure tcustomenuedit.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('min',@readmin,nil,false); + filer.defineproperty('max',@readmax,nil,false); +end; + +function tcustomenuedit.getdropdown: tenumdropdowncontroller; +begin + result:= tenumdropdowncontroller(fdropdown); +end; + +procedure tcustomenuedit.setdropdown(const avalue: tenumdropdowncontroller); +begin + fdropdown.assign(avalue); +end; + +function tcustomenuedit.griddata: tgridenumdatalist; +begin + checkgrid(); + result:= tgridenumdatalist(fdatalist); +end; + +procedure tcustomenuedit.setnullvalue; +begin + dropdown.itemindex:= -1; + nullvalueset(); +end; + +function tcustomenuedit.sortfunc(const l; const r): integer; +begin +// result:= tdatalist1(twidgetcol1(fgridintf.getcol).fdata).compare(l,r); + result:= tdatalist1(fdatalist).compare(l,r); +end; + +procedure tcustomenuedit.setvaluedata(const source); +begin + value:= integer(source); +end; + +procedure tcustomenuedit.getvaluedata(out dest); +begin + integer(dest):= value; +end; + +{ tnocolsenumdropdowncontroller } + +constructor tnocolsenumdropdowncontroller.create(const intf: idropdownlist); +begin + inherited; + options:= defaultenumdropdownoptions; +end; + +procedure tnocolsenumdropdowncontroller.readitemindex(reader: treader); +begin + reader.readinteger; //dummy +end; + +procedure tnocolsenumdropdowncontroller.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('itemindex',{$ifdef FPC}@{$endif}readitemindex, + nil,false); +end; + +{ tcustomenumedit } + +procedure tcustomenumedit.loaded; +begin + inherited; + if canevent(tmethod(foninit)) then begin + foninit(self); + end; +end; + +{ tenumtypeedit } + +procedure tenumtypeedit.setoninit(const aValue: enumtypeediteventty); +begin + foninit:= enumediteventty(avalue); +end; + +function tenumtypeedit.getoninit: enumtypeediteventty; +begin + result:= enumtypeediteventty(foninit); +end; + +procedure tenumtypeedit.settypeinfopo(const avalue: ptypeinfo); +begin + if avalue <> ftypeinfopo then begin + if avalue <> nil then begin + dropdown.cols[dropdown.valuecol].asarray:= getenumnames(avalue); + end + else begin + dropdown.cols[dropdown.valuecol].clear; + end; + formatchanged; + end; +end; + +{ tcustomselector } + +constructor tcustomselector.create(aowner: tcomponent); +begin + inherited; + fdropdownitems:= tdropdowndatacols.create( + tcustomdropdownlistcontroller(fdropdown)); +// inherited; +end; + +destructor tcustomselector.destroy; +begin + inherited; + fdropdownitems.Free; +end; + +procedure tcustomselector.dobeforedropdown; +begin + inherited; + fdropdownenums:= copy(enums); + getdropdowninfo(fdropdownenums,fdropdownitems); + tdropdowncols1(dropdown.cols).fitemindex:= + getindex1(fvalue1,fdropdownenums,fvalueoffset); +end; + +function tcustomselector.getdropdownitems: tdropdowndatacols; +begin + result:= fdropdownitems; +end; + +procedure tcustomselector.texttovalue(var accept: boolean; const quiet: boolean); +var + int1: integer; +begin + with tdropdownlistcontroller(fdropdown) do begin + if (trim(text) = '') or (itemindex < 0) or + (itemindex >= length(fdropdownenums)) and (length(fdropdownenums) <> 0) then begin + int1:= -1; + end + else begin + if length(fdropdownenums) = 0 then begin + int1:= itemindex + fvalueoffset; + end + else begin + int1:= fdropdownenums[itemindex]; + end; + end; + fdropdownenums:= nil; + if not quiet then begin + if canevent(tmethod(fonsetvalue1)) then begin + fonsetvalue1(self,int1,accept); + end; + {$ifdef mse_with_ifi} + ifisetvalue(int1,accept); + {$endif} + end; + if accept then begin + value:= int1; + end; + end; +end; + +{ tselector } + +procedure tselector.getdropdowninfo(var aenums: integerarty; + const names: tdropdowndatacols); +begin + if canevent(tmethod(fongetdropdowninfo)) then begin + fongetdropdowninfo(self) + end; +end; + +procedure tselector.loaded; +begin + inherited; + if canevent(tmethod(foninit)) then begin + foninit(self); + end; +end; + +procedure tselector.setdropdownitems(const avalue: tdropdowndatacols); +begin + fdropdownitems.Assign(avalue); +end; + +{ tcustomrealedit } + +constructor tcustomrealedit.create(aowner: tcomponent); +begin + fvalue:= emptyreal; + fvaluedefault:= emptyreal; + fvaluemin:= emptyreal; + fvaluemax:= bigreal; + fvaluerange:= 1; + inherited; + include(foptionswidget,ow_mousewheel); +end; +{ +function tcustomrealedit.griddata: trealdatalist; +begin + checkgrid; + result:= trealdatalist(fdatalist); +end; +} +procedure tcustomrealedit.setformatdisp(const Value: msestring); +begin + fformatdisp := Value; + formatchanged; +end; + +procedure tcustomrealedit.setformatedit(const Value: msestring); +begin + fformatedit := Value; + formatchanged; +end; + +function tcustomrealedit.internaldatatotext(const data): msestring; +var + rea1: real; +begin + if @data = nil then begin + rea1:= fvalue; + end + else begin + rea1:= realty(data); + end; + if (@data = nil) and focused then begin + result:= realtytostrrange(rea1,fformatedit,fvaluerange,fvaluestart); + end + else begin + result:= realtytostrrange(rea1,fformatdisp,fvaluerange,fvaluestart); + end; +end; + +function tcustomrealedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= tgridrealdatalist.create(sender); +end; + +function tcustomrealedit.getdatalistclass: datalistclassty; +begin + result:= tgridrealdatalist; +end; + +procedure tcustomrealedit.gridtovalue(arow: integer); +begin + fgridintf.getdata(arow,fvalue); + inherited; +end; + +procedure tcustomrealedit.valuetogrid(arow: integer); +begin + fgridintf.setdata(arow,fvalue); +end; + +procedure tcustomrealedit.setvalue(const Value: realty); +begin + fvalue := Value; + valuechanged; +end; + +function tcustomrealedit.gettextvalue(var accept: boolean; + const quiet: boolean): realty; +var + mstr1: msestring; +begin + try + if focused then begin + mstr1:= text; + end + else begin + mstr1:= realtytostrrange(fvalue,fformatedit,fvaluerange,fvaluestart) + end; + checktext(mstr1,accept); + if not accept then begin + result:= emptyreal; //compiler warning + exit; + end; + result:= strtorealty(mstr1); + except + formaterror(quiet); + accept:= false + end; +end; + +procedure tcustomrealedit.texttovalue(var accept: boolean; const quiet: boolean); +var + rea1,rea2: realty; + str1: msestring; + int1: integer; +begin + rea1:= gettextvalue(accept,quiet); + if accept then begin + str1:= realtytostring(rea1,fformatedit); + if trystrtorealty(str1,rea2) then begin //round to editformat + rea1:= rea2; + end; +{ + try + rea2:= strtorealty(str1); //round to editformat + rea1:= rea2; + except + end; +} + rea1:= reapplyrange(rea1,fvaluerange,fvaluestart); + if not (((des_isdb in fstate) or (oe_null in foptionsedit)) and + (rea1 = emptyreal)) then begin + if (cmprealty(fvaluemin,rea1) > 0) or + (cmprealty(fvaluemax,rea1) < 0) then begin + rangeerror(fvaluemin,fvaluemax,quiet); + accept:= false; + end; + end; + if accept then begin + if not quiet then begin + if canevent(tmethod(fonsetintvalue)) then begin + int1:= realtytoint(rea1); + fonsetintvalue(self,int1,accept); + rea1:= inttorealty(int1); + end + else begin + if canevent(tmethod(fonsetvalue)) then begin + fonsetvalue(self,rea1,accept); + end; + end; + {$ifdef mse_with_ifi} + ifisetvalue(rea1,accept); + {$endif} + end; + if accept then begin + value:= rea1; + end; + end; + end; +end; + +procedure tcustomrealedit.texttodata(const atext: msestring; var data); +var + rea1: realty; +begin + try + rea1:= reapplyrange(strtorealty(atext),fvaluerange,fvaluestart); + except + rea1:= emptyreal; + end; + if cmprealty(fvaluemin,rea1) > 0 then begin + rea1:= fvaluemin; + end; + if cmprealty(fvaluemax,rea1) < 0 then begin + rea1:= fvaluemax; + end; + realty(data):= rea1; +end; + +procedure tcustomrealedit.readvalue(reader: treader); +begin + value:= readrealty(reader); +end; + +procedure tcustomrealedit.readvaluedefault(reader: treader); +begin + valuedefault:= readrealty(reader); +end; + +procedure tcustomrealedit.readmin1(reader: treader); +begin + fvaluemin:= readrealty(reader); +end; + +procedure tcustomrealedit.readmax1(reader: treader); +begin + fvaluemax:= readrealty(reader); +end; + +procedure tcustomrealedit.readvaluescale(reader: treader); +begin + valuerange:= valuescaletorange(reader); +end; + +procedure tcustomrealedit.readmin(reader: treader); +begin + valuemin:= reader.readfloat; +end; + +procedure tcustomrealedit.readmax(reader: treader); +begin + valuemax:= reader.readfloat; +end; + +procedure tcustomrealedit.defineproperties(filer: tfiler); +//var +// bo1,bo2{,bo3,bo4}: boolean; +begin + inherited; + + filer.DefineProperty('val', + {$ifdef FPC}@{$endif}readvalue,nil,false); + filer.DefineProperty('mi',{$ifdef FPC}@{$endif}readmin1,nil,false); + filer.DefineProperty('ma',{$ifdef FPC}@{$endif}readmax1,nil,false); + filer.DefineProperty('def',{$ifdef FPC}@{$endif}readvaluedefault,nil,false); + filer.defineproperty('valuescale',@readvaluescale,nil,false); + filer.defineproperty('min',@readmin,nil,false); + filer.defineproperty('max',@readmax,nil,false); +end; + +procedure tcustomrealedit.readstatvalue(const reader: tstatreader); +begin + value:= reader.readreal(valuevarname,value,fvaluemin,fvaluemax, + oe_null in foptionsedit); +end; + +procedure tcustomrealedit.writestatvalue(const writer: tstatwriter); +begin + writer.writereal(valuevarname,value); +end; + +function tcustomrealedit.getgridvalue(const index: integer): realty; +begin + internalgetgridvalue(index,result); +end; + +function tcustomrealedit.getgridintvalue(const index: integer): integer; +var + rea1: realty; +begin + internalgetgridvalue(index,rea1); + result:= realtytoint(rea1); +end; + +procedure tcustomrealedit.setgridvalue(const index: integer; + const avalue: realty); +begin + internalsetgridvalue(index,avalue); +end; + +procedure tcustomrealedit.setgridintvalue(const index: integer; + const avalue: integer); +var + rea1: realty; +begin + rea1:= inttorealty(avalue); //avoid FPC crash + internalsetgridvalue(index,rea1); +end; + +function tcustomrealedit.getgridvalues: realarty; +begin + result:= trealdatalist(checkgriddata).asarray; +// result:= trealdatalist(fgridintf.getcol.datalist).asarray; +end; + +function tcustomrealedit.getgridintvalues: integerarty; +var + ar1: realarty; + int1: integer; +begin + ar1:= trealdatalist(checkgriddata).asarray; + setlength(result,length(ar1)); + for int1:= 0 to high(ar1) do begin + result[int1]:= realtytoint(ar1[int1]); + end; +end; + +procedure tcustomrealedit.setgridvalues(const avalue: realarty); +begin + trealdatalist(checkgriddata).asarray:= avalue; +// trealdatalist(fgridintf.getcol.datalist).asarray:= avalue; +end; + +procedure tcustomrealedit.setgridintvalues(const avalue: integerarty); +var + ar1: realarty; + int1: integer; +begin + setlength(ar1,length(avalue)); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= inttorealty(avalue[int1]); + end; + trealdatalist(checkgriddata).asarray:= ar1; +end; + +procedure tcustomrealedit.setvaluerange(const avalue: real); +begin + if fvaluerange <> avalue then begin + fvaluerange:= avalue; + valuetotext; + end; +end; + +procedure tcustomrealedit.setvaluestart(const avalue: real); +begin + if fvaluestart <> avalue then begin + fvaluestart:= avalue; + valuetotext; + end; +end; + +procedure tcustomrealedit.fillcol(const value: realty); +begin + internalfillcol(value); +end; + +procedure tcustomrealedit.assigncol(const value: trealdatalist); +begin + internalassigncol(value); +end; + +function tcustomrealedit.getasinteger: integer; +begin + result:= realtytoint(value); +end; + +procedure tcustomrealedit.setasinteger(const avalue: integer); +begin + value:= inttorealty(avalue); +end; + +function tcustomrealedit.getascurrency: currency; +begin + if isnull then begin + result:= 0; + end + else begin + result:= value; + end; +end; + +procedure tcustomrealedit.setascurrency(const avalue: currency); +begin + value:= avalue; +end; + +function tcustomrealedit.isnull: boolean; +begin + result:= value = emptyreal; +end; + +function tcustomrealedit.getasstring: msestring; +begin + result:= doubletostring(value); +end; + +procedure tcustomrealedit.setasstring(const avalue: msestring); +begin + value:= strtorealtydot(avalue); +end; + +{$ifdef mse_with_ifi} + +function tcustomrealedit.getifilink: tifireallinkcomp; +begin + result:= tifireallinkcomp(fifilink); +end; + +procedure tcustomrealedit.setifilink(const avalue: tifireallinkcomp); +begin + inherited setifilink(avalue); +end; + +{$endif} + +function tcustomrealedit.getdefaultvalue: pointer; +begin + result:= @fvaluedefault; +end; + +procedure tcustomrealedit.setvaluemin(const avalue: realty); +begin + fvaluemin:= avalue; + if fdatalist <> nil then begin + with tgridrealdatalist(fdatalist) do begin + min:= avalue; + end; + end; +end; + +procedure tcustomrealedit.setvaluemax(const avalue: realty); +begin + fvaluemax:= avalue; + if fdatalist <> nil then begin + with tgridrealdatalist(fdatalist) do begin + max:= avalue; + end; + end; +end; + +procedure tcustomrealedit.updatedatalist; +begin + with tgridrealdatalist(fdatalist) do begin + min:= self.valuemin; + max:= self.valuemax; + updateeditoptions(foptionsedit); + end; +end; + +function tcustomrealedit.getintvalue: integer; +begin + result:= realtytoint(value); +end; + +procedure tcustomrealedit.setintvalue(const avalue: integer); +begin + value:= avalue; +end; + +function tcustomrealedit.griddata: tgridrealdatalist; +begin + result:= tgridrealdatalist(inherited griddata); +end; + +procedure tcustomrealedit.setnullvalue; +begin + value:= emptyreal; + nullvalueset(); +end; + +procedure tcustomrealedit.updatereadonlystate(); +begin + inherited; + if fdatalist <> nil then begin + tgridrealdatalist(fdatalist).updateeditoptions(foptionsedit); + //for acceptempty + end; +end; + +procedure tcustomrealedit.setvaluedata(const source); +begin + value:= realty(source); +end; + +procedure tcustomrealedit.getvaluedata(out dest); +begin + realty(dest):= value; +end; + +{ tspineditframe } + +constructor tspineditframe.create(const aintf: icaptionframe; + const stepintf: istepbar); +begin + include(fstepstate,sfs_spinedit); + inherited; + fi.levelo:= -2; + inflateframe1(fi.innerframe,1); + fforcevisiblebuttons:= [sk_up,sk_down]; + fforceinvisiblebuttons:= []; + internalupdatestate; +end; + +function tspineditframe.actualcolorclient(): colorty; +begin + result:= fi.colorclient; + if result = cl_default then begin + result:= cl_foreground; + end; +end; + +procedure tspineditframe.setbuttonsvisible(const avalue: stepkindsty); +begin + inherited buttonsvisible:= avalue * spinstepbuttons; +end; + +{ tcustomrealspinedit } + +constructor tcustomrealspinedit.create(aowner: tcomponent); +begin + fstep:= 1; + fwheelsensitivity:= 1; + inherited; +end; + +procedure tcustomrealspinedit.internalcreateframe; +begin + tspineditframe.create(iscrollframe(self),istepbar(self)); +end; + +function tcustomrealspinedit.gettextvalue(var accept: boolean; + const quiet: boolean): realty; + function initvalue: realty; + begin + result:= 0; + if result < fvaluemin then begin + result:= fvaluemin; + end; + if result > fvaluemax then begin + result:= fvaluemax; + end; + end; + +label + endlab,endlab1; +begin + case fstepflag of + sk_last: begin + result:= fvaluemax; + end; + sk_first: begin + result:= fvaluemin; + end; + sk_up: begin + result:= fvalue; + if fvalue = emptyreal then begin + result:= initvalue; + goto endlab; + end; + result:= result + fstep*fstepfact; + end; + sk_down: begin + result:= fvalue; + if fvalue = emptyreal then begin + result:= initvalue; + goto endlab; + end; + result:= result - fstep*fstepfact; + end; + else begin + result:= inherited gettextvalue(accept,quiet); + goto endlab1; + end; + end; +endlab: + if result < fvaluemin then begin + result:= fvaluemin; + end; + if result > fvaluemax then begin + result:= fvaluemax; + end; +endlab1: + fstepflag:= stepkindty(-1); +end; + +function tcustomrealspinedit.dostep(const event: stepkindty; + const adelta: real; ashiftstate: shiftstatesty): boolean; +begin + result:= false; + if not (csdesigning in componentstate) then begin + if event in [sk_up,sk_down,sk_first,sk_last] then begin + result:= true; + if edited then begin + if not checkvalue then begin + exit; + end; + end; + fstepflag:= event; + if (adelta = 0) or (application.mousewheeldeltamin <= 0) then begin + fstepfact:= 1; + end + else begin + fstepfact:= round(0.03 * fwheelsensitivity * + abs(adelta/application.mousewheeldeltamin)); + end; + if fstepfact < 1 then begin + fstepfact:= 1; + end; + ashiftstate:= ashiftstate * keyshiftstatesmask; + if (ashiftstate = [ss_ctrl]) and (fstepctrlfact <> 0) then begin + fstepfact:= fstepfact * fstepctrlfact; + end + else begin + if (ashiftstate = [ss_shift]) and (fstepshiftfact <> 0) then begin + fstepfact:= fstepfact * fstepshiftfact; + end; + end; + checkvalue; + end; + end; +end; + +procedure tcustomrealspinedit.mouseevent(var info: mouseeventinfoty); +begin + tspineditframe(fframe).mouseevent(info); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +function tcustomrealspinedit.getframe: tspineditframe; +begin + result:= tspineditframe(pointer(inherited frame)); +end; + +procedure tcustomrealspinedit.setframe(const avalue: tspineditframe); +begin + inherited frame:= tcaptionframe(pointer(avalue)); +end; + +procedure tcustomrealspinedit.domousewheelevent(var info: mousewheeleventinfoty); +begin + tspineditframe(fframe).domousewheelevent(info); + inherited; +end; + +procedure tcustomrealspinedit.updatebuttonstate(); +begin + if fframe <> nil then begin + if readonly or not isenabled then begin + frame.disabledbuttons:= allstepkinds; + end + else begin + frame.disabledbuttons:= []; + end; + end; +end; + +procedure tcustomrealspinedit.updatereadonlystate; +begin + inherited; + updatebuttonstate(); +end; + +procedure tcustomrealspinedit.enabledchanged; +begin + inherited; + updatebuttonstate(); +end; + +procedure tcustomrealspinedit.dokeydown(var info: keyeventinfoty); +var + shiftstate1: shiftstatesty; +begin + with info do begin + if ((shiftstate * keyshiftstatesmask) - [ss_shift,ss_alt,ss_ctrl] = []) and + (ss_alt in shiftstate) and not readonly and + not (es_processed in eventstate) then begin + include(eventstate,es_processed); + shiftstate1:= shiftstate - [ss_alt]; + case key of + key_up: begin + dostep(sk_up,0,shiftstate1); + end; + key_down: begin + dostep(sk_down,0,shiftstate1); + end; + else begin + exclude(eventstate,es_processed); + end; + end; + end; + if not (es_processed in eventstate) then begin + inherited; + end; + end; +end; + +{ tcustomdatetimeedit } + +constructor tcustomdatetimeedit.create(aowner: tcomponent); +begin + fvalue:= emptydatetime; + fvaluedefault:= emptydatetime; + fvaluemin:= emptydatetime; + fvaluemax:= bigdatetime; + inherited; +end; + +procedure tcustomdatetimeedit.setvalue(const Value: tdatetime); +begin + fvalue := Value; + valuechanged; +end; + +procedure tcustomdatetimeedit.setformatdisp(const Value: msestring); +begin + fformatdisp := Value; + formatchanged; +end; + +procedure tcustomdatetimeedit.setformatedit(const Value: msestring); +begin + fformatedit := Value; + formatchanged; +end; + +function tcustomdatetimeedit.getgridvalue(const index: integer): tdatetime; +begin + internalgetgridvalue(index,result); +end; + +procedure tcustomdatetimeedit.setgridvalue(const index: integer; const Value: tdatetime); +begin + internalsetgridvalue(index,value); +end; + +function tcustomdatetimeedit.getgridvalues: datetimearty; +begin + result:= datetimearty(trealdatalist(checkgriddata).asarray); +end; + +procedure tcustomdatetimeedit.setgridvalues(const Value: datetimearty); +begin + trealdatalist(checkgriddata).asarray:= realarty(value); +end; + +function tcustomdatetimeedit.checkkind(const avalue: tdatetime): tdatetime; +begin + if avalue = emptydatetime then begin + result:= avalue; + end + else begin + case fkind of + dtk_date: result:= trunc(avalue); + dtk_time: result:= frac(avalue); + else result:= avalue; + end; + end; +end; + +function tcustomdatetimeedit.gettextvalue(var accept: boolean; + const quiet: boolean): tdatetime; +var + mstr1: msestring; + bo1: boolean; +begin + mstr1:= text; + checktext(mstr1,accept); + if not accept then begin + result:= emptydatetime; //compiler warning + exit; + end; + bo1:= false; + case fkind of + dtk_time: begin + bo1:= trystringtotime(mstr1,fformatedit,result); + end; + dtk_date: begin + bo1:= trystringtodate(mstr1,fformatedit,result); + end; + else begin + bo1:= trystringtodatetime(mstr1,fformatedit,result); + end; + end; + if not bo1 then begin + formaterror(quiet); + accept:= false + end + else begin + checkdateconvert(fconvert,result); + end; +end; + +procedure tcustomdatetimeedit.texttovalue(var accept: boolean; + const quiet: boolean); +var + dat1: tdatetime; +// mstr1: msestring; +begin + dat1:= gettextvalue(accept,quiet); + if accept then begin + if not (((des_isdb in fstate) or (oe_null in foptionsedit)) and + (dat1 = emptydatetime)) then begin + if fkind = dtk_time then begin + if (fvaluemax = emptydatetime) and not (dat1 = emptydatetime) or + not (fvaluemin = emptydatetime) and (dat1 < frac(fvaluemin)) or + (dat1 > frac(fvaluemax)) then begin + rangeerror(fvaluemin,fvaluemax,quiet); + accept:= false; + end; + end + else begin + if (cmprealty(fvaluemin,dat1) > 0) or + (cmprealty(fvaluemax,dat1) < 0) then begin + rangeerror(fvaluemin,fvaluemax,quiet); + accept:= false; + end; + end; + end; + if accept then begin + if not quiet then begin + if canevent(tmethod(fonsetvalue)) then begin + fonsetvalue(self,dat1,accept); + end; + {$ifdef mse_with_ifi} + ifisetvalue(dat1,accept); + {$endif} + end; + if accept then begin + value:= dat1; + end; + end; + end; +end; + +procedure tcustomdatetimeedit.texttodata(const atext: msestring; var data); +var + dat1: tdatetime; + bo1: boolean; +begin + if fkind = dtk_time then begin + bo1:= trystringtotime(atext,fformatedit,dat1,fconvert); + end + else begin + bo1:= trystringtodatetime(atext,fformatedit,dat1,fconvert); + end; + if not bo1 then begin + bo1:= trystrtorealty(atext,realty(dat1)); + if not bo1 then begin + dat1:= emptyreal; + end + else begin + checkdateconvert(fconvert,dat1); + end; + end; + if cmprealty(fvaluemin,dat1) > 0 then begin + dat1:= fvaluemin; + end; + if cmprealty(fvaluemax,dat1) < 0 then begin + dat1:= fvaluemax; + end; + tdatetime(data):= dat1; +end; + +function tcustomdatetimeedit.internaldatatotext(const data): msestring; +var + dat1: tdatetime; + mstr1: msestring; +begin + if @data = nil then begin + dat1:= fvalue; + end + else begin + dat1:= tdatetime(data); + end; + checkdatereconvert(fconvert,dat1); + if (@data = nil) and focused then begin + mstr1:= fformatedit; + end + else begin + mstr1:= fformatdisp; + end; + case fkind of + dtk_time: begin + result:= mseformatstr.timetostring(dat1,mstr1); + end; + dtk_date: begin + result:= mseformatstr.datetostring(dat1,mstr1); + end; + else begin + result:= mseformatstr.datetimetostring(dat1,mstr1); + end; + end; +end; + +function tcustomdatetimeedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= tgridrealdatalist.create(sender); +end; + +function tcustomdatetimeedit.getdatalistclass: datalistclassty; +begin + result:= tgridrealdatalist; +end; + +procedure tcustomdatetimeedit.valuetogrid(arow: integer); +begin + fgridintf.setdata(arow,fvalue); +end; + +procedure tcustomdatetimeedit.gridtovalue(arow: integer); +begin + fgridintf.getdata(arow,fvalue); + inherited; +end; + +procedure tcustomdatetimeedit.readstatvalue(const reader: tstatreader); +begin + value:= reader.readreal(valuevarname,value,fvaluemin,fvaluemax, + oe_null in foptionsedit); +end; + +procedure tcustomdatetimeedit.writestatvalue(const writer: tstatwriter); +begin + writer.writereal(valuevarname,value); +end; + +procedure tcustomdatetimeedit.fillcol(const value: tdatetime); +begin + internalfillcol(value); +end; + +procedure tcustomdatetimeedit.assigncol(const value: trealdatalist); +begin + internalassigncol(value); +end; + +procedure tcustomdatetimeedit.setkind(const avalue: datetimekindty); +begin + if fkind <> avalue then begin + fkind:= avalue; + formatchanged; + end; +end; + +procedure tcustomdatetimeedit.readvalue(reader: treader); +begin + value:= readrealty(reader); +end; + +procedure tcustomdatetimeedit.readvaluedefault(reader: treader); +begin + valuedefault:= readrealty(reader); +end; + +procedure tcustomdatetimeedit.readmin1(reader: treader); +begin + fvaluemin:= readrealty(reader); +end; + +procedure tcustomdatetimeedit.readmax1(reader: treader); +begin + fvaluemax:= readrealty(reader); +end; + +procedure tcustomdatetimeedit.readmin(reader: treader); +begin + valuemin:= reader.readfloat(); +end; + +procedure tcustomdatetimeedit.readmax(reader: treader); +begin + valuemax:= reader.readfloat(); +end; + + +procedure tcustomdatetimeedit.defineproperties(filer: tfiler); +begin + inherited; + + filer.DefineProperty('val', + {$ifdef FPC}@{$endif}readvalue,nil,false); + filer.DefineProperty('mi',{$ifdef FPC}@{$endif}readmin1,nil,false); + filer.DefineProperty('ma',{$ifdef FPC}@{$endif}readmax1,nil,false); + filer.DefineProperty('def', + {$ifdef FPC}@{$endif}readvaluedefault,nil,false); + filer.defineproperty('min',@readmin,nil,false); + filer.defineproperty('max',@readmax,nil,false); +end; + +function tcustomdatetimeedit.isempty(const atext: msestring): boolean; +begin + result:= (atext <> ' ') and inherited isempty(atext); +end; + +function tcustomdatetimeedit.isnull: boolean; +begin + result:= value = emptydatetime; +end; +{ +function tcustomdatetimeedit.griddata: trealdatalist; +begin + result:= trealdatalist(fdatalist); +end; +} +{$ifdef mse_with_ifi} +function tcustomdatetimeedit.getifilink: tifidatetimelinkcomp; +begin + result:= tifidatetimelinkcomp(fifilink); +end; + +procedure tcustomdatetimeedit.setifilink(const avalue: tifidatetimelinkcomp); +begin + inherited setifilink(avalue); +end; +{$endif} + +function tcustomdatetimeedit.getdefaultvalue: pointer; +begin + result:= @fvaluedefault; +end; + +procedure tcustomdatetimeedit.setoptions(const avalue: datetimeeditoptionsty); +{$ifndef FPC} +const + mask1: datetimeeditoptionsty = [dteo_showlocal,dteo_showutc]; +{$endif} +begin + if avalue <> foptions then begin + foptions:= datetimeeditoptionsty( + {$ifdef FPC} + setsinglebit(longword(avalue),longword(foptions), + longword([dteo_showlocal,dteo_showutc]))); + {$else} + setsinglebit(byte(avalue),byte(foptions),byte(mask1))); + {$endif} + fconvert:= dc_none; + if dteo_showutc in foptions then begin + fconvert:= dc_tolocal; + end; + if dteo_showlocal in foptions then begin + fconvert:= dc_toutc; + end; + formatchanged; + end; +end; + +procedure tcustomdatetimeedit.setvaluemin(const avalue: tdatetime); +begin + fvaluemin:= avalue; + if fdatalist <> nil then begin + with tgridrealdatalist(fdatalist) do begin + min:= avalue; + end; + end; +end; + +procedure tcustomdatetimeedit.setvaluemax(const avalue: tdatetime); +begin + fvaluemax:= avalue; + if fdatalist <> nil then begin + with tgridrealdatalist(fdatalist) do begin + max:= avalue; + end; + end; +end; + +procedure tcustomdatetimeedit.updatedatalist; +begin + with tgridrealdatalist(fdatalist) do begin + min:= self.valuemin; + max:= self.valuemax; + updateeditoptions(foptionsedit); + end; +end; + +function tcustomdatetimeedit.getshowlocal: boolean; +begin + result:= dteo_showlocal in foptions; +end; + +procedure tcustomdatetimeedit.setshowlocal(const avalue: boolean); +begin + if avalue then begin + options:= options + [dteo_showlocal]; + end + else begin + options:= options - [dteo_showlocal]; + end; +end; + +function tcustomdatetimeedit.getshowutc: boolean; +begin + result:= dteo_showutc in foptions; +end; + +procedure tcustomdatetimeedit.setshowutc(const avalue: boolean); +begin + if avalue then begin + options:= options + [dteo_showutc]; + end + else begin + options:= options - [dteo_showutc]; + end; +end; + +function tcustomdatetimeedit.griddata: tgridrealdatalist; +begin + result:= tgridrealdatalist(inherited griddata); +end; + +procedure tcustomdatetimeedit.setnullvalue; +begin + value:= emptydatetime; + nullvalueset(); +end; + +procedure tcustomdatetimeedit.updatereadonlystate(); +begin + inherited; + if fdatalist <> nil then begin + tgridrealdatalist(fdatalist).updateeditoptions(foptionsedit); + //for acceptempty + end; +end; + +function tcustomdatetimeedit.getassistiveflags: assistiveflagsty; +begin + result:= inherited getassistiveflags() + [asf_datetime]; +end; + +procedure tcustomdatetimeedit.setvaluedata(const source); +begin + value:= tdatetime(source); +end; + +procedure tcustomdatetimeedit.getvaluedata(out dest); +begin + tdatetime(dest):= value; +end; + +{ tenumdropdowncontroller } + +constructor tenumdropdowncontroller.create(const intf: idropdownlist); +begin + inherited; + cols.nostreaming:= false; +end; + +{ tcustomrichmemoedit } + +function tcustomrichmemoedit.getformat: formatinfoarty; +begin + result:= fformat; +end; + +procedure tcustomrichmemoedit.setformat(const avalue: formatinfoarty); +begin + fformat:= copy(avalue); + feditor.format:= fformat; +// valuechanged(); +end; + +function tcustomrichmemoedit.getrichvalue(): richstringty; +begin + result.text:= value; + result.format:= fformat; + result.flags:= frichflags; +end; + +procedure tcustomrichmemoedit.setrichvalue(const avalue: richstringty); +begin + fformat:= copy(avalue.format); + frichflags:= avalue.flags; + value:= avalue.text; +end; + +procedure tcustomrichmemoedit.readrichvalue(reader: treader); +begin + richvalue:= readrichstring(reader); +end; + +procedure tcustomrichmemoedit.writerichvalue(writer: twriter); +begin + writerichstring(writer,richvalue); +end; + +procedure tcustomrichmemoedit.defineproperties(filer: tfiler); +var + b1: boolean; +begin + inherited; + if filer.ancestor <> nil then begin + b1:= isequalrichstring(tcustomrichmemoedit(filer.ancestor).richvalue, + richvalue); + end + else begin + b1:= not isemptyrichstring(richvalue); + end; + filer.defineproperty('richvalue',@readrichvalue,@writerichvalue,b1); +end; + +end. diff --git a/mseide-msegui/lib/common/editwidgets/msedataimage.pas b/mseide-msegui/lib/common/editwidgets/msedataimage.pas new file mode 100644 index 0000000..e0c9fc0 --- /dev/null +++ b/mseide-msegui/lib/common/editwidgets/msedataimage.pas @@ -0,0 +1,860 @@ +{ MSEgui Copyright (c) 1999-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msedataimage; +{$ifdef FPC} + {$mode objfpc}{$h+}{$interfaces corba} +{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,mseguiglob,msegui,mseimage,msewidgetgrid,msegrids,msedatalist, + msegraphutils,msedragglob, + msegraphics,mseclasses,mseeditglob,msebitmap,msemenus,mseevent, + msetypes{msestrings}, + msepointer,msegridsglob{$ifdef mse_with_ifi},mseificomp,mseifiglob{$endif}, + mseglob,msehash; + +type + imagecachedataty = record + data: pointer; + image: maskedimagety; + prev: int32; //offset from fdata + next: int32; //offset from fdata + end; + imagecachehashdataty = record + header: hashheaderty; + data: imagecachedataty; + end; + pimagecachehashdataty = ^imagecachehashdataty; + + timagecache = class(thashdatalist) + private + fmaxsize: int32; + fimagedatasize: int32; + ffirst: int32; //offset from fdata + flast: int32; //offset from fdata + protected + function getrecordsize(): int32 override; +// procedure inititem(const aitem: phashdataty) override; + procedure finalizeitem(const aitem: phashdataty) override; + function hashkey(const akey): hashvaluety override; + function checkkey(const akey; const aitem: phashdataty): boolean override; + public + constructor create(); + procedure clear() override; + function find(const adata: string; out aimage: maskedimagety): boolean; + procedure add(const adata: string; const aimage: maskedimagety); + procedure delete(const adata: string); + property maxsize: int32 read fmaxsize write fmaxsize; + end; + + tcustomdataimage = class(timage,igridwidget) + private + fonchange: notifyeventty; + fformat: string; + fgridsettingx: integer; + procedure checkgrid; + function getgridvalue(index: integer): string; + procedure setgridvalue(index: integer; const avalue: string); + procedure readvalue(stream: tstream); + procedure writevalue(stream: tstream); + function getcachesize: int32; + procedure setcachesize(const avalue: int32); +// function getvalue: string; + protected + fgridintf: iwidgetgrid; + fgriddatalink: pointer; + fvalue: string; //in design mode only + fcurformat: string; + feditstate: dataeditstatesty; + fcache: timagecache; +// procedure setisdb; + function geteditstate: dataeditstatesty; + procedure seteditstate(const avalue: dataeditstatesty); + function getgridintf: iwidgetgrid; + procedure defineproperties(filer: tfiler); override; + procedure setvalue(const avalue: string); virtual; + procedure setformat(const avalue: string); + procedure internaldrawcell(const canvas: tcanvas; const dest: rectty); + + //igridwidget + procedure initgridwidget; virtual; + function getoptionsedit: optionseditty; + procedure setfirstclick(var ainfo: mouseeventinfoty); + procedure setreadonly(const avalue: boolean); + function createdatalist(const sender: twidgetcol): tdatalist; virtual; + procedure datalistdestroyed; + function getdatalistclass: datalistclassty; + function getdefaultvalue: pointer; + function getrowdatapo(const arow: integer): pointer; virtual; + procedure setgridintf(const intf: iwidgetgrid); + function getcellframe: framety; + function needscellfocuspaint(): boolean; + function getcellcursor(const arow: integer; const acellzone: cellzonety; + const apos: pointty): cursorshapety; + procedure updatecellzone(const row: integer; const apos: pointty; + var result: cellzonety); + function getnulltext: msestring; + function getassistivecelltext(const arow: int32): msestring; + procedure loadcellbmp(const acanvas: tcanvas; + const abmp: tmaskedbitmap); virtual; + procedure drawcell(const canvas: tcanvas); + procedure updateautocellsize(const canvas: tcanvas); + procedure beforecelldragevent(var ainfo: draginfoty; const arow: integer; + var handled: boolean); virtual; + procedure aftercelldragevent(var ainfo: draginfoty; const arow: integer; + var handled: boolean); virtual; + procedure valuetogrid(row: integer); virtual; + procedure gridtovalue(row: integer); virtual; + procedure setvaluedata(const source); virtual; + procedure getvaluedata(out dest); virtual; + procedure docellevent(const ownedcol: boolean; var info: celleventinfoty); virtual; + function sortfunc(const l,r): integer; virtual; + procedure gridvaluechanged(const index: integer); virtual; + procedure updatecoloptions(const aoptions: coloptionsty); + procedure updatecoloptions1(const aoptions: coloptions1ty); + procedure statdataread; virtual; + procedure griddatasourcechanged; virtual; + {$ifdef mse_with_ifi} + function getifilink: tifilinkcomp; + {$endif} + procedure setparentgridwidget(const intf: igridwidget); + procedure childdataentered(const sender: igridwidget); virtual; + procedure childfocused(const sender: igridwidget); virtual; + public + constructor create(aowner: tcomponent); override; + destructor destroy(); override; + function seteditfocus: boolean; + procedure changed; override; + function actualcolor: colorty; override; + function loadfromstream(const astream: tstream): string; //returns format + function loadfromfile(const afilename: filenamety): string; //returns format + procedure storeimage(const aformat: string; const params: array of const); + //writes image data to value property + procedure drawimage(const canvas: tcanvas; const cellinfo: pcellinfoty; + const dest: rectty); + property value: string read fvalue{getvalue} write setvalue stored false; + property gridvalue[index: integer]: string read getgridvalue + write setgridvalue; default; + property format: string read fformat write setformat; + property cachesize: int32 read getcachesize + write setcachesize default 0; + //kibibyte + property onchange: notifyeventty read fonchange write fonchange; + end; + + tdataimage = class(tcustomdataimage) + published + property value; + property format; + property cachesize; + property onbeforepaint; + property onpaintbackground; + property onpaint; + property onafterpaint; + end; + +implementation +uses + msestream,sysutils,mseformatstr; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tsimplebitmap1 = class(tsimplebitmap); + tcustomwidgetgrid1 = class(tcustomwidgetgrid); + +{ timagecache } + +constructor timagecache.create(); +begin + inherited; + fstate:= fstate + [hls_needsfinalize]; +end; + +procedure timagecache.clear(); +begin + inherited; + fimagedatasize:= 0; + ffirst:= 0; + flast:= 0; +end; + +function timagecache.getrecordsize(): int32; +begin + result:= sizeof(imagecachehashdataty); +end; +{ +procedure timagecache.inititem(const aitem: phashdataty); +begin + initialize(pimagecachehashdataty(aitem)^); +end; +} +procedure timagecache.finalizeitem(const aitem: phashdataty); +begin + freeimage(pimagecachehashdataty(aitem)^.data.image); +end; + +function timagecache.hashkey(const akey): hashvaluety; +begin + result:= pointerhash(pointer(akey)); +end; + +function timagecache.checkkey(const akey; const aitem: phashdataty): boolean; +begin + result:= pointer(akey) = pimagecachehashdataty(aitem)^.data.data; +end; + +function timagecache.find(const adata: string; + out aimage: maskedimagety): boolean; +var + p1: pimagecachehashdataty; +begin + result:= false; + if fmaxsize > 0 then begin + p1:= pimagecachehashdataty(internalfind(pointer(adata))); + if p1 <> nil then begin + aimage:= p1^.data.image; + result:= true; + end; + end; +end; + +procedure timagecache.add(const adata: string; const aimage: maskedimagety); +var + i1: int32; + p1: pimagecachehashdataty; +begin + if (fmaxsize > 0) and (adata <> '') then begin + if (fimagedatasize > fmaxsize) and (ffirst <> 0) then begin + p1:= fdata+ffirst; + delete(string(p1^.data.data)); + end; + p1:= pimagecachehashdataty(internaladd(pointer(adata))); + p1^.data.data:= pointer(adata); + p1^.data.image:= aimage; + p1^.data.prev:= flast; + p1^.data.next:= 0; + i1:= pointer(p1)-fdata; + if ffirst = 0 then begin + ffirst:= i1; + end; + if flast <> 0 then begin + pimagecachehashdataty(fdata+flast)^.data.next:= i1; + end; + flast:= i1; + fimagedatasize:= fimagedatasize + (aimage.image.length+aimage.mask.length)*4; + end; +end; + +procedure timagecache.delete(const adata: string); +var + i1: int32; + p1: pimagecachehashdataty; +begin + if (fmaxsize > 0) and (adata <> '') then begin + p1:= pimagecachehashdataty(internalfind(pointer(adata))); + if p1 <> nil then begin + i1:= pointer(p1)-data; + if p1^.data.prev <> 0 then begin + pimagecachehashdataty(fdata+p1^.data.prev)^.data.next:= i1; + end; + if p1^.data.next <> 0 then begin + pimagecachehashdataty(fdata+p1^.data.next)^.data.prev:= i1; + end; + if i1 = ffirst then begin + ffirst:= p1^.data.next; + end; + if i1 = flast then begin + flast:= p1^.data.prev; + end; + fimagedatasize:= fimagedatasize - + (p1^.data.image.image.length+p1^.data.image.mask.length)*4; + internaldeleteitem(phashdataty(p1)); + end; + end; +end; + +{ tcustomdataimage } + +constructor tcustomdataimage.create(aowner: tcomponent); +begin + fcache:= timagecache.create(); + inherited; +{$warnings off} + include(tsimplebitmap1(bitmap).fstate,pms_nosave); +{$warnings on} +end; + +destructor tcustomdataimage.destroy(); +begin + inherited; + fcache.free; +end; + +procedure tcustomdataimage.setvalue(const avalue: string); +var + int1: integer; + str1: string; +begin + if pointer(fvalue) <> pointer(avalue) then begin + { + if pointer(avalue) <> pointer(fvalue) then begin + fcache.delete(fvalue); + end; + } + fvalue:= avalue; + try + fcurformat:= bitmap.loadfromstring(avalue,fformat,[]); + except + fcurformat:= ''; + bitmap.clear; + end; + if (fgridintf <> nil) and not (csdesigning in componentstate) and + (fgridsettingx = 0) then begin + int1:= fgridintf.getrow(); + fgridintf.getdata(int1,str1); + fgridintf.setdata(int1,avalue,false); + if pointer(avalue) <> pointer(str1) then begin + fcache.delete(str1); + end; + end; + end; +// if csdesigning in componentstate then begin +// fvalue:= avalue; +// end; + changed; +end; +{ +procedure tcustomdataimage.setvalue(const avalue: string); +var + int1: integer; + str1: string; +begin + if (fgridintf <> nil) and not (csdesigning in componentstate) then begin + inc(fgridsetting); + try + int1:= -1; + fgridintf.getdata(int1,str1); + fgridintf.setdata(int1,avalue); + finally + dec(fgridsetting); + end; + end; + try + fcurformat:= bitmap.loadfromstring(avalue,fformat,[]); + except + fcurformat:= ''; + bitmap.clear; + end; + if csdesigning in componentstate then begin + fvalue:= avalue; + end; + changed; + if pointer(avalue) <> pointer(str1) then begin + fcache.delete(str1); + end; +end; +} +function tcustomdataimage.seteditfocus: boolean; +begin + if fgridintf = nil then begin + if canfocus then begin + setfocus; + end; + end + else begin + with fgridintf.getcol do begin + grid.col:= index; + if grid.canfocus then begin + if not focused then begin + grid.setfocus; + end; + end; + end; + end; + result:= focused; +end; + +procedure tcustomdataimage.changed; +begin + inherited; + if not (ws_loadedproc in fwidgetstate) and + canevent(tmethod(fonchange)) then begin + fonchange(self); + end; +end; + +procedure tcustomdataimage.setfirstclick(var ainfo: mouseeventinfoty); +begin + //dummy +end; + +function tcustomdataimage.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= tgridbinarystringdatalist.create(sender); +end; + +function tcustomdataimage.getdatalistclass: datalistclassty; +begin + result:= tgridbinarystringdatalist; +end; + +function tcustomdataimage.getdefaultvalue: pointer; +begin + result:= nil; +end; + +function tcustomdataimage.getrowdatapo(const arow: integer): pointer; +begin + result:= nil; +end; + +procedure tcustomdataimage.setgridintf(const intf: iwidgetgrid); +begin + fgridintf:= intf; + if fgridintf <> nil then begin + fgriddatalink:= tcustomwidgetgrid1(fgridintf.getgrid).getgriddatalink; + end + else begin + fgriddatalink:= nil; + end; +end; + +function tcustomdataimage.getcellframe: framety; +begin + if fframe <> nil then begin + result:= fframe.cellframe; + end + else begin + result:= nullframe; + end; +end; + +function tcustomdataimage.needscellfocuspaint(): boolean; +begin + result:= inherited needsfocuspaint(); +end; + +function tcustomdataimage.getcellcursor(const arow: integer; + const acellzone: cellzonety; + const apos: pointty): cursorshapety; +begin + result:= actualcursor(nullpoint); +end; + +procedure tcustomdataimage.updatecellzone(const row: integer; + const apos: pointty; var result: cellzonety); +begin + //dummy +end; + +function tcustomdataimage.getnulltext: msestring; +begin + result:= ''; +end; + +function tcustomdataimage.getassistivecelltext(const arow: int32): msestring; +begin + result:= ''; +end; + +procedure tcustomdataimage.loadcellbmp(const acanvas: tcanvas; + const abmp: tmaskedbitmap); +var + image1: maskedimagety; +begin + with cellinfoty(acanvas.drawinfopo^) do begin + if fcache.maxsize > 0 then begin + if fcache.find(string(datapo^),image1) then begin + abmp.loadfrommaskedimage(image1); + end + else begin + abmp.loadfromstring(string(datapo^),fformat,[]); + abmp.savetomaskedimage(image1); + fcache.add(string(datapo^),image1); + end; + end + else begin + abmp.loadfromstring(string(datapo^),fformat,[]); + end; + end; +end; + +procedure tcustomdataimage.internaldrawcell(const canvas: tcanvas; + const dest: rectty); +var + bmp: tmaskedbitmap; + int1: integer; +begin + with cellinfoty(canvas.drawinfopo^) do begin + if (datapo <> nil) and (string(datapo^) <> '') then begin + bmp:= tmaskedbitmap.create(bitmap.kind); + try + with bitmap do begin + bmp.alignment:= alignment; + bmp.options:= options; + bmp.opacity:= opacity; + bmp.transparentcolor:= transparentcolor; + end; + loadcellbmp(canvas,bmp); + if calcautocellsize then begin + int1:= bmp.size.cx - innerrect.cx + rect.cx; + if int1 > autocellsize.cx then begin + autocellsize.cx:= int1; + end; + int1:= bmp.size.cy - innerrect.cy + rect.cy; + if int1 > autocellsize.cy then begin + autocellsize.cy:= int1; + end; + end + else begin + paintbmp(canvas,bmp,dest); + end; + except; + end; + bmp.free; + end; + end; +end; + +procedure tcustomdataimage.drawcell(const canvas: tcanvas); +begin + with cellinfoty(canvas.drawinfopo^) do begin + internaldrawcell(canvas,innerrect); + end; +end; + +procedure tcustomdataimage.drawimage(const canvas: tcanvas; + const cellinfo: pcellinfoty; const dest: rectty); +var + p1: pointer; + p2: pcellinfoty; + cellinfo1: cellinfoty; +begin + p2:= canvas.drawinfopo; + if cellinfo = nil then begin + canvas.drawinfopo:= @cellinfo1; + cellinfo1.cell.row:= fgridintf.getgrid.row; + cellinfo1.calcautocellsize:= false; + end + else begin + canvas.drawinfopo:= cellinfo; + end; + with pcellinfoty(canvas.drawinfopo)^ do begin + p1:= datapo; + datapo:= fgridintf.getdatapo(cell.row); + internaldrawcell(canvas,dest); + datapo:= p1; + end; + canvas.drawinfopo:= p2; +end; + +procedure tcustomdataimage.updateautocellsize(const canvas: tcanvas); +begin + drawcell(canvas); +end; + +procedure tcustomdataimage.valuetogrid(row: integer); +begin + //dummy +end; + +procedure tcustomdataimage.gridtovalue(row: integer); +var + str1: string; +begin +// if fgridsetting = 0 then begin +// if row <> -2 then begin //not default value + inc(fgridsettingx); + try + fgridintf.getdata(row,str1); + value:= str1; + finally + dec(fgridsettingx); + end; +// end; +// end; +end; + +procedure tcustomdataimage.docellevent(const ownedcol: boolean; + var info: celleventinfoty); +begin + //dummy +end; + +function tcustomdataimage.sortfunc(const l,r): integer; +begin + result:= 0; +end; + +procedure tcustomdataimage.gridvaluechanged(const index: integer); +begin + //dummy +end; + +procedure tcustomdataimage.updatecoloptions(const aoptions: coloptionsty); +begin + //dummy +end; + +procedure tcustomdataimage.updatecoloptions1(const aoptions: coloptions1ty); +begin + //dummy +end; + +procedure tcustomdataimage.statdataread; +begin + //dummy +end; + +procedure tcustomdataimage.griddatasourcechanged; +begin + //dummy +end; + +{$ifdef mse_with_ifi} +function tcustomdataimage.getifilink: tifilinkcomp; +begin + result:= nil; +end; +{$endif} + +function tcustomdataimage.getoptionsedit: optionseditty; +begin + result:= [oe_readonly]; +end; + +procedure tcustomdataimage.initgridwidget; +begin + defaultinitgridwidget(self,fgridintf); +end; + +procedure tcustomdataimage.setformat(const avalue: string); +begin + fformat:= avalue; +end; + +procedure tcustomdataimage.checkgrid; +begin + if fgridintf = nil then begin + raise exception.Create('No grid.'); + end; + if fgridintf.getcol = nil then begin + raise exception.Create('No datalist.'); + end; +end; + +function tcustomdataimage.getgridvalue(index: integer): string; +begin + checkgrid; + fgridintf.getdata(index,result); +end; + +function tcustomdataimage.geteditstate: dataeditstatesty; +begin + result:= feditstate; +end; + +procedure tcustomdataimage.seteditstate(const avalue: dataeditstatesty); +begin + feditstate:= avalue; +end; +{ +procedure tcustomdataimage.setisdb; +begin + //dummy +end; +} +procedure tcustomdataimage.setgridvalue(index: integer; + const avalue: string); +var + str1: string; +begin + checkgrid; + fgridintf.getdata(index,str1); + fgridintf.setdata(index,avalue); + fcache.delete(str1); +end; + +function tcustomdataimage.getgridintf: iwidgetgrid; +begin + result:= fgridintf; +end; + +procedure tcustomdataimage.beforecelldragevent(var ainfo: draginfoty; + const arow: integer; var handled: boolean); +begin + //dummy +end; + +procedure tcustomdataimage.aftercelldragevent(var ainfo: draginfoty; + const arow: integer; var handled: boolean); +begin + //dummy +end; + +procedure tcustomdataimage.setreadonly(const avalue: boolean); +begin + //dummy +end; + +procedure tcustomdataimage.readvalue(stream: tstream); +var + str1: string; + int1: integer; +begin + stream.readbuffer(int1,sizeof(integer)); + setlength(str1,int1); + stream.readbuffer(pointer(str1)^,int1); + value:= str1; +end; + +procedure tcustomdataimage.writevalue(stream: tstream); +var + int1: integer; +begin + int1:= length(fvalue); + stream.writebuffer(int1,sizeof(integer)); + stream.writebuffer(pointer(fvalue)^,int1); +end; + +function tcustomdataimage.getcachesize: int32; +begin + result:= fcache.maxsize; +end; + +procedure tcustomdataimage.setcachesize(const avalue: int32); +begin + fcache.maxsize:= avalue; + if avalue = 0 then begin + fcache.clear; + end; +end; +(* +function tcustomdataimage.getvalue: string; +//var +// i1: int32; +begin + result:= fvalue; +{ + result:= ''; + if fgridintf <> nil then begin + i1:= fgridintf.getgrid.row; + if i1 >= 0 then begin + result:= gridvalue[i1]; + end; + end; +} +end; +*) +procedure tcustomdataimage.defineproperties(filer: tfiler); +begin + inherited; + filer.definebinaryproperty('valuedata',{$ifdef FPC}@{$endif}readvalue, + {$ifdef FPC}@{$endif}writevalue, + (filer.ancestor = nil) and (fvalue <> '') or + (filer.ancestor <> nil) and + (tcustomdataimage(filer.ancestor).fvalue <> fvalue)); +end; + +function tcustomdataimage.actualcolor: colorty; +begin + if (fgridintf <> nil) and (fcolor = cl_default) then begin + result:= fgridintf.getcol.rowcolor(fgridintf.getrow); + end + else begin + result:= inherited actualcolor; + end; +end; + +function tcustomdataimage.loadfromstream(const astream: tstream): string; +//var +// str1: string; +begin + fcurformat:= ''; + value:= readstreamdatastring(astream); + result:= fcurformat; +end; + +function tcustomdataimage.loadfromfile(const afilename: filenamety): string; +var + stream1: tmsefilestream; +begin + stream1:= tmsefilestream.create(afilename); + try + result:= loadfromstream(stream1); + finally + stream1.free; + end; +end; + +procedure tcustomdataimage.storeimage(const aformat: string; + const params: array of const); +var + str1: string; +begin + if aformat <> '' then begin + str1:= aformat; + end + else begin + str1:= format; + end; + value:= bitmap.writetostring(str1,params); +end; + +procedure tcustomdataimage.datalistdestroyed; +begin + //dummy +end; + +procedure tcustomdataimage.setvaluedata(const source); +begin + value:= string(source); +end; + +procedure tcustomdataimage.getvaluedata(out dest); +begin + //dummy +end; + +procedure tcustomdataimage.setparentgridwidget(const intf: igridwidget); +begin + //dummy +end; + +procedure tcustomdataimage.childdataentered(const sender: igridwidget); +begin + //dummy +end; + +procedure tcustomdataimage.childfocused(const sender: igridwidget); +begin + //dummy +end; + +end. diff --git a/mseide-msegui/lib/common/editwidgets/msedatanodes.pas b/mseide-msegui/lib/common/editwidgets/msedatanodes.pas new file mode 100644 index 0000000..4d48c14 --- /dev/null +++ b/mseide-msegui/lib/common/editwidgets/msedatanodes.pas @@ -0,0 +1,4019 @@ +{ MSEgui Copyright (c) 1999-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msedatanodes; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$goto on}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses,msegraphutils,msedrawtext,msegraphics,msedatalist,mseglob, + mseguiglob,msegui,msestockobjects, + msebitmap,mseclasses,mseevent,msegrids,msetypes,msestrings,mseinplaceedit, + msestat,msegridsglob,mselist,msearrayutils,msearrayprops; + +type + + nodestatty = (ns_expanded,ns_selected,ns_readonly,ns_checked, + ns_subitems,ns_drawemptybox,ns_imagenrfix, +// ns_destroying,ns_updating,ns_noowner, + ns_checkbox,ns_showchildchecked,ns_showchildnotchecked, + ns_showparentnotchecked, + ns_nosubnodestat, + ns_casesensitive,ns_sorted,//ns_captionclipped, + ns_drawemptyexpand,ns_res15, + ns_useri0,ns_useri1,ns_useri2,ns_useri3, + //with invalidate and statsave + ns_useri4,ns_useri5,ns_useri6,ns_useri7, + //with invalidate, no statsave + ns_user0,ns_user1,ns_user2,ns_user3, + //without invalidate, with statsave + ns_user4,ns_user5,ns_user6,ns_user7); + //without invalidate, no statsave + + nodestatesty = set of nodestatty; + nodestate1ty = (ns1_statechanged,ns1_rootchange,ns1_candrag, + ns1_destroying,ns1_notbyownerdestroying, + ns1_updating,ns1_noowner,ns1_captionclipped, + ns1_childchecked,ns1_childnotchecked,ns1_parentnotchecked, + ns1_checkboxclicked,ns1_customsort, + ns1_nofreeroot,ns1_top,ns1_fixedcaption,ns1_nodefaultimagelist + // ns1_irecordfield, //implements irecordfield + // ns1_irecordvaluefield //irecordvaluefield + ); + nodestates1ty = set of nodestate1ty; + + nodeoptionty = (no_drawemptybox,no_drawemptyexpand,no_solidline,no_checkbox, + no_updatechildchecked, + //track ns1_childchecked state, slow! + no_updatechildnotchecked, + //track ns1_childnotchecked state, slow! + no_updateparentnotchecked, + //track ns1_parentnotchecked state, slow! + no_cellitemselect, //copy cell select state to item select + no_nofreeitems, //do not free items for removed rows + no_createvalueitems //titemeditlist creates items depending + //on statread type value + ); + nodeoptionsty = set of nodeoptionty; + + treeitemboxty = (tib_none,tib_empty,tib_expand,tib_expanded, + tib_checkbox,tib_checkboxchecked, + tib_checkboxparentnotchecked,tib_checkboxchildchecked, + tib_checkboxchildnotchecked); + itemdrawoptionty = (ido_solidline); + itemdrawoptionsty = set of itemdrawoptionty; + treeitemboxidarty = array[treeitemboxty] of int32; + ptreeitemboxidarty = treeitemboxidarty; + +const + invalidatestates = [ns_expanded,ns_selected,ns_checked, + ns_subitems,ns_drawemptybox,ns_checkbox, + ns_useri0..ns_useri7]; + invalidateallstates = [ns_expanded]; + valuechangestates = [ns_checked]; + statstates: nodestatesty = [ns_expanded,ns_selected,ns_checked,{ns_checkbox,} + ns_useri0..ns_useri3,ns_user0..ns_user3]; + defaultlevelstep = 10; + +type + getnodemodety = (gno_matching,gno_allchildren,gno_nochildren); + + extrainfoty = record + image: sizety; //first because of backward compatibility of extendimageeventty + caption: sizety; + end; + + variablelistiteminfoty = record + extra: extrainfoty; + imageextend: sizety; + treelevelshift: integer; + rowindex: integer; + widgetstate: widgetstatesty; + calcautocellsize: boolean; + colorline: colorty; + colorglyph: colorty; +// boxids: ptreeitemboxidarty; + glyphversion: int32; //for stockglyphs + imageversion: int32; //for imagelist + end; + + listitemlayoutinfoty = record + widget: twidget; //titemedit or tcustomlistview + cellsize: sizety; + minsize: sizety; + captionrect: rectty; + captioninnerrect: rectty; + imagerect: rectty; + imagealignment: alignmentsty; + textflags: textflagsty; + expandboxrect: rectty; + checkboxrect: rectty; + checkboxinnerrect: rectty; +// colorline: colorty; + boxids: treeitemboxidarty; +// drawoptions: itemdrawoptionsty; + variable: variablelistiteminfoty; //variable + end; + plistitemlayoutinfoty = ^listitemlayoutinfoty; + + nodeactionty = (na_none,na_change,na_valuechange,na_checkedchange, + na_expand,na_collapse,na_countchange, + na_destroying,na_aftersort); + nodeactioninfoty = record + case action: nodeactionty of + na_countchange: ( + treeheightbefore: integer; + ); + end; + + tlistitem = class; + + iitemlist = interface(inullinterface) + function getgrid: tcustomgrid; + function getlayoutinfo(const acellinfo: pcellinfoty): plistitemlayoutinfoty; + procedure updatelayout; + procedure itemcountchanged; +// function getcolorglyph: colorty; + procedure updateitemvalues(const index: integer; const count: integer); + function getcomponentstate: tcomponentstate; + end; + + tcustomitemlist = class; + + tlistitem = class(tnullinterfacedobject) + private + procedure setstate(const Value: nodestatesty); + procedure setimagenr(const Value: integer); + function getselected: boolean; + procedure setselected(const Value: boolean); + function getchecked: boolean; + function getimagelist: timagelist; + procedure setimagelist(const Value: timagelist); + procedure setvaluetext1(const avalue: msestring); + function gettop: boolean; + procedure settop(const avalue: boolean); + function getcheckbox: boolean; + procedure setcheckbox(const avalue: boolean); + protected + fstate: nodestatesty; + fstate1: nodestates1ty; + findex: integer; + fimagelist: timagelist; + fimagenr: integer; + fcaption: msestring; + fowner: tcustomitemlist; + procedure setchecked(const avalue: boolean); virtual; + procedure setcaption(const avalue: msestring); virtual; + function checkaction(aaction: nodeactionty): boolean; + procedure actionnotification(var ainfo: nodeactioninfoty); virtual; + function getactimagenr( + const alayoutinfo: listitemlayoutinfoty): integer; virtual; + procedure objectevent(const sender: tobject; + const event: objecteventty); virtual; + procedure setowner(const aowner: tcustomitemlist); virtual; + function compare(const r: tlistitem; + const acasesensitive: boolean): integer; virtual; + function cancaptionedit: boolean; virtual; + function canvalueedit: boolean; virtual; + function getvalueitem: tlistitem; virtual; + procedure setvalueitem(const avalue: tlistitem); virtual; + function getownerintf: iitemlist inline; + public + tag: integer; + tagpo: pointer; + property tagpointer: pointer read tagpo write tagpo; + deprecated 'Use tagpo instead'; + constructor create(const aowner: tcustomitemlist); overload; virtual; + constructor createassign(const aowner: tcustomitemlist; + const asource: tlistitem); overload; + destructor destroy; override; + class procedure calcitemlayout(const asize: sizety; + const ainnerframe: framety; const list: tcustomitemlist; + var info: listitemlayoutinfoty); virtual; + + procedure assign(const source: tlistitem); overload; virtual; + procedure beginupdate; + procedure endupdate; + procedure releaseowner; virtual; + + function empty: boolean; virtual; + procedure change(); virtual; + procedure valuechange(const delta: nodestatesty = []); virtual; + procedure updatecellzone(const pos: pointty; var zone: cellzonety); virtual; + procedure drawimage(const acanvas: tcanvas; + var alayoutinfo: listitemlayoutinfoty) virtual; + procedure updatecaption(const acanvas: tcanvas; + var alayoutinfo: listitemlayoutinfoty; + var ainfo: drawtextinfoty); virtual; + procedure drawcell(const acanvas: tcanvas); virtual; + procedure mouseevent(var info: mouseeventinfoty); virtual; + property index: integer read findex; + procedure focusrow(); //set assigned grid row to index + procedure setupeditor(const editor: tinplaceedit; + const font: tfont; const notext: boolean); virtual; + + procedure dostatupdate(const filer: tstatfiler); + procedure dostatread(const reader: tstatreader); virtual; + procedure dostatwrite(const writer: tstatwriter); virtual; + + function captionclipped: boolean; + property caption: msestring read fcaption write setcaption; + property state: nodestatesty read fstate write setstate; + property state1: nodestates1ty read fstate1; + property imagelist: timagelist read getimagelist write setimagelist; + //nil -> fowner.imagelist + property imagenr: integer read fimagenr write setimagenr; + property selected: boolean read getselected write setselected; + property checkbox: boolean read getcheckbox write setcheckbox; + property checked: boolean read getchecked write setchecked; + property owner: tcustomitemlist read fowner; + function getvaluetext: msestring; virtual; + procedure setvaluetext(var avalue: msestring); virtual; + property valuetext: msestring read getvaluetext write setvaluetext1; + property valueitem: tlistitem read getvalueitem; + property top: boolean read gettop write settop; + end; + + plistitem = ^tlistitem; + listitemclassty = class of tlistitem; + listitemarty = array of tlistitem; + listitematy = array[0..0] of tlistitem; + plistitematy = ^listitematy; + + ttreelistitem = class; + treelistitemarty = array of ttreelistitem; + treelistitematy = array[0..0] of ttreelistitem; + ptreelistitematy = ^treelistitematy; + + treelistitemclassty = class of ttreelistitem; + checktreelistitemprocty = procedure(const sender: ttreelistitem; + var delete: boolean) of object; + ttreelistitemcomparefuncty = function( + const l,r: ttreelistitem): integer of object; + tlistitemcomparefuncty = function (const r: tlistitem; + const acasesensitive: boolean): integer of object; + +{ + treeitemdrawinfoty = record + boxkind: treeitemboxty; //set by caller + boximageid: int32; + flags: treeitemdrawingflagsty; + end; +} + ttreelistitem = class(tlistitem) + private + function getexpanded: boolean; + function getitems(const aindex: integer): ttreelistitem; + procedure dosetitems(const aindex: integer; const value: ttreelistitem); + procedure setitems(const aindex: integer; const value: ttreelistitem); + procedure unsetitem(const aindex: integer); + procedure internalcheckitems(const checkdelete: checktreelistitemprocty); + procedure setdestroying; + procedure setnotbyownerdestroying; + //destroyed by parentitem with owner = nil + function inccount: integer; //returns itemindex + function getrootexpanded: boolean; + procedure setrootexpanded(const avalue: boolean); + function getsubitems: boolean; + procedure setsubitems(const avalue: boolean); + protected + fparent: ttreelistitem; + fparentindex: integer; + fitems: treelistitemarty; + fcount: integer; + ftreelevel: integer; + procedure setexpanded(const Value: boolean) virtual; + procedure statechanged virtual; + procedure aftermove virtual; + procedure checksort; virtual; + procedure setcaption(const avalue: msestring); override; + procedure setowner(const aowner: tcustomitemlist); override; + procedure setchecked(const avalue: boolean); override; + procedure checkindex(const aindex: integer); + procedure settreelevel(const value: integer); + procedure countchange(const atreeheightbefore: integer; + const notifyowner: boolean); + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + function createsubnode: ttreelistitem; virtual; + procedure internalswap(const a,b: integer); + procedure internalmove(const source,dest: integer); + procedure statreadsubnode(const reader: tstatreader; + var anode: ttreelistitem); virtual; + procedure internalexpandall; + procedure internalcollapseall; + procedure internalgetnodes(var aresult: treelistitemarty; var acount: integer; + const must: nodestatesty; const mustnot: nodestatesty; + const amode: getnodemodety; const addself: boolean); + function customcompare(const l,r: ttreelistitem): integer; virtual; + + function comparecasesens(const l: ttreelistitem; + const r: ttreelistitem): integer; + function comparecaseinsens(const l: ttreelistitem; + const r: ttreelistitem): integer; + procedure doupdateparentnotcheckedstate(const aset: boolean); +// procedure updatedrawinfo(var ainfo: treeitemdrawinfoty) virtual; + public + constructor create(const aowner: tcustomitemlist = nil; + const aparent: ttreelistitem = nil); reintroduce; virtual; + destructor destroy; override; + class procedure calcitemlayout(const asize: sizety; + const ainnerframe: framety; const list: tcustomitemlist; + var info: listitemlayoutinfoty); override; + + procedure releaseowner; override; + procedure releasechildren(); + + procedure dostatread(const reader: tstatreader); override; + procedure dostatwrite(const writer: tstatwriter); override; + + procedure updatechildcheckedstate(); //updates ancestors + procedure updatechildcheckedtree(); //updates self and descendents + procedure updatechildnotcheckedtree(); //updates self and descendents + procedure updatechildnotcheckedstate(); //updates ancestors + procedure updateparentnotcheckedstate(); //updates affected descendents + procedure updateparentnotcheckedtree(); //updates all descendents + property parent: ttreelistitem read fparent; + function parentorself: ttreelistitem; + function parentindex: integer; + property treelevel: integer read ftreelevel; + function levelshift: integer; + function treeheight: integer; //total hight of children + function rowheight: integer; //toatal needed grid rows + function isroot: boolean; + function issinglerootrow: boolean; //keyrowmove can be used + function islastnode: boolean; + property subitems: boolean read getsubitems write setsubitems; + function findsibling(const asibling: ttreelistitem): ttreelistitem; + function nextnode: ttreelistitem; //node of next row + function nextnodeparent: ttreelistitem; + function checkdescendent(node: ttreelistitem): boolean; + //true if node is descendent or self + function checkancestor(node: ttreelistitem): boolean; + //true if node is ancestor or self + function isstatechanged: boolean; + function candrag: boolean; virtual; + function candrop(const source: ttreelistitem): boolean; virtual; + + function finditembycaption(const acaption: msestring; + var dest: ttreelistitem): boolean; overload; + function finditembycaption(const acaption: msestring; + const acasesensitive: boolean = false; + const aexpand: boolean = false): ttreelistitem; overload; + function finditembycaption(const acaption: lmsestringty; + const aexpand: boolean = false): ttreelistitem; overload; + function finditembycaption(const acaptions: msestringarty; + const acasesensitive: boolean = false; + const aexpand: boolean = false; + const apartial: boolean = false): ttreelistitem; overload; + function rootnode: ttreelistitem; + function rootpath: treelistitemarty; + //top-down + function rootcaptions: msestringarty; overload; + function rootcaptions(const aowner: tcustomitemlist): msestringarty; overload; + //stops if not owned by aowner + procedure checkitems(const checkdelete: checktreelistitemprocty); + + procedure updatecellzone(const pos: pointty; var zone: cellzonety); override; + procedure mouseevent(var info: mouseeventinfoty); override; + procedure drawimage(const acanvas: tcanvas; + var alayoutinfo: listitemlayoutinfoty) override; + procedure addchildren(const aitem: ttreelistitem); + //transfers children + function add(const aitem: ttreelistitem): integer; overload; + //returns index, nil ignored + procedure add(const aitems: treelistitemarty); overload; + function add(const itemclass: treelistitemclassty = nil): + ttreelistitem; overload; + procedure add(const acount: integer; + const itemclass: treelistitemclassty = nil; + const defaultstate: nodestatesty = []); overload; + procedure insert(aindex: integer; const aitem: ttreelistitem); + procedure insert(const aitem: ttreelistitem; aindex: integer); deprecated; + //use insert(aindex,aitem) above instead + procedure move(const source,dest: integer); + procedure swap(const a,b: integer); + procedure clear; virtual; + + function getnodes(const must: nodestatesty; + const mustnot: nodestatesty; + const amode: getnodemodety = gno_matching; + const addself: boolean = false): treelistitemarty; + function getselectednodes(const amode: getnodemodety = gno_matching; + const addself: boolean = false): treelistitemarty; + function getcheckednodes(const amode: getnodemodety = gno_matching; + const addself: boolean = false): treelistitemarty; + + procedure expandall; + procedure collapseall; + procedure expandtoroot(const afocusrow: boolean = true); + procedure collapsetoroot; + function remove(const aindex: integer): ttreelistitem; + procedure sort(const casesensitive: boolean; + const recursive: boolean = false); overload; + procedure sort(const sortfunc: arraysortcomparety; + const recursive: boolean = false); overload; + property count: integer read fcount; + procedure setupeditor(const editor: tinplaceedit; + const font: tfont; const notext: boolean); override; + property rootexpanded: boolean read getrootexpanded write setrootexpanded; + //stops after toplevel item of itemlist + property expanded: boolean read getexpanded write setexpanded; + function treechecked: boolean; //true if checked and not parentnotchecked + property items[const aindex: integer]: ttreelistitem read getitems; default; + end; + + tfontarrayprop = class(tpersistentarrayprop) + private + procedure setitems(const index: integer; const avalue: tfont); + protected + function getitems(const index: integer): tfont; + procedure createitem(const index: integer; var item: tpersistent); override; + public + constructor create(); + class function getitemclasstype: persistentclassty; override; + //used in dumpunitgroups + property items[const index: integer]: tfont read getitems + write setitems; default; + end; + + ptreelistitem = ^ttreelistitem; + + itemliststatety = (ils_destroying,ils_updateitemvalues, + ils_subnodecountinvalid,ils_subnodecountupdating, + ils_subnodedeleting, + ils_freelock); + itemliststatesty = set of itemliststatety; + statreaditemeventty = procedure(const sender: tobject; const reader: tstatreader; + var aitem: tlistitem) of object; + statreadtreeitemeventty = procedure(const sender: tobject; + const reader: tstatreader; + var aitem: ttreelistitem) of object; + statwriteitemeventty = procedure(const sender: tobject; + const writer: tstatwriter; const aitem: tlistitem) of object; + statwritetreeitemeventty = procedure(const sender: tobject; + const writer: tstatwriter; const aitem: ttreelistitem) of object; + + statreaditemlisteventty = procedure(const sender: tcustomitemlist; + const areader: tstatreader; + const aname: msestring) of object; + statwriteitemlisteventty = procedure(const sender: tcustomitemlist; + const areader: tstatwriter; + const aname: msestring) of object; + tcustomitemlist = class(tobjectdatalist,iobjectlink) + private + fonstatreaditem: statreaditemeventty; + fonstatreadtreeitem: statreadtreeitemeventty; + fonstatwriteitem: statwriteitemeventty; + fonstatwritetreeitem: statwritetreeitemeventty; + fonstatwrite: statwriteitemlisteventty; + fonstatread: statreaditemlisteventty; + ffonts: tfontarrayprop; + fimnr_focused: integer; + fimnr_active: integer; + procedure setimnr_base(const Value: integer); + procedure setimnr_expanded(const Value: integer); + procedure setimnr_selected(const Value: integer); + procedure setimnr_readonly(const Value: integer); + procedure setimnr_checked(const Value: integer); + procedure setimnr_subitems(const Value: integer); + procedure setimagelist(const Value: timagelist); + procedure setoptions(const Value: nodeoptionsty); + procedure setcaptionpos(const Value: captionposty); + procedure setlevelstep(const Value: integer); + procedure setimageheight(const Value: integer); + procedure setimagewidth(const Value: integer); + procedure setimagesize(const avalue: sizety); + procedure setimagealignment(const avalue: alignmentsty); + procedure setfonts(const avalue: tfontarrayprop); + procedure setimnr_focused(const avalue: integer); + procedure setimnr_active(const avalue: integer); + protected + fdefaultnodestate: nodestatesty; + fimagelist: timagelist; + fimagesize: sizety; + fimagealignment: alignmentsty; + fimnr_base: integer; + fimnr_expanded,fimnr_selected,fimnr_readonly,fimnr_checked, + fimnr_subitems: integer; + flevelstep: integer; + fintf: iitemlist; + foptions: nodeoptionsty; + fcaptionpos: captionposty; + fitemstate: itemliststatesty; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + function getitems1(const index: integer): tlistitem; + procedure setitems(const index: integer; const Value: tlistitem); + procedure setcount(const value: integer); override; + procedure freedata(var data); override; + procedure removeitem(const aindex: integer); //no free item + procedure change(const item: tlistitem); reintroduce; overload; + procedure nodenotification(const sender: tlistitem; + var ainfo: nodeactioninfoty); virtual; + procedure setitemselected(const row: integer; const value: boolean); override; + procedure doitemchange(const index: integer); override; + procedure invalidate; virtual; + procedure updatelayout; virtual; + procedure docreateobject(var instance: tobject); override; + procedure createitem(out item: tlistitem); virtual; + procedure createstatitem(const reader: tstatreader; + out item: tlistitem); virtual; + procedure statreaditem(const reader: tstatreader; + var aitem: tlistitem); virtual; + procedure statreadtreeitem(const reader: tstatreader; + const parent: ttreelistitem; var aitem: ttreelistitem); virtual; + procedure statwriteitem(const writer: tstatwriter; + const aitem: tlistitem); virtual; + procedure statwritetreeitem(const writer: tstatwriter; + const aitem: ttreelistitem); virtual; + + procedure dostatread(const reader: tstatreader; + const name: msestring); virtual; + procedure dostatwrite(const writer: tstatwriter; + const name: msestring); virtual; + procedure writestate(const writer; const name: msestring); override; + procedure readstate(const reader; const acount: integer; + const name: msestring); override; + + public + constructor create; overload; override; + constructor create(const intf: iitemlist); reintroduce; overload; + destructor destroy; override; + procedure registerobject(const aobject: iobjectlink); + //call objectevent method of items + procedure unregisterobject(const aobject: iobjectlink); + function layoutinfopo: plistitemlayoutinfoty; + + function add(const aitem: tlistitem): integer; overload; + function add(const aitem: msestring): integer; overload; + procedure add(const aitems: listitemarty); overload; + procedure add(const aitems: msestringarty); overload; + procedure add(const aitems: array of msestring); overload; + + function empty(const index: integer): boolean; override; + function indexof(const aitem: tlistitem): integer; + function nodezone(const point: pointty): cellzonety; + function getitems(const must: nodestatesty; + const mustnot: nodestatesty): listitemarty; + function getindexes(const must: nodestatesty; + const mustnot: nodestatesty): integerarty; + function getselecteditems: listitemarty; + function getselectedindexes: integerarty; + function getcheckeditems: listitemarty; + function getcheckedindexes: integerarty; + property itemlistintf: iitemlist read fintf; + property items[const index: integer]: tlistitem read getitems1 write setitems; + default; + property imnr_base: integer read fimnr_base write setimnr_base default 0; + property imnr_expanded: integer read fimnr_expanded + write setimnr_expanded default 0; + property imnr_selected: integer read fimnr_selected + write setimnr_selected default 0; + property imnr_readonly: integer read fimnr_readonly + write setimnr_readonly default 0; + property imnr_checked: integer read fimnr_checked + write setimnr_checked default 0; + property imnr_subitems: integer read fimnr_subitems + write setimnr_subitems default 0; + property imnr_focused: integer read fimnr_focused + write setimnr_focused default 0; + property imnr_active: integer read fimnr_active + write setimnr_active default 0; + property imagelist: timagelist read fimagelist write setimagelist; + property imagewidth: integer read fimagesize.cx + write setimagewidth default 0; + property imageheight: integer read fimagesize.cy + write setimageheight default 0; + property imagesize: sizety read fimagesize write setimagesize; + property imagealignment: alignmentsty read fimagealignment + write setimagealignment default [al_xcentered,al_ycentered]; + property options: nodeoptionsty read foptions write setoptions default []; + property captionpos: captionposty read fcaptionpos write setcaptionpos + default cp_right; + property fonts: tfontarrayprop read ffonts write setfonts; + property levelstep: integer read flevelstep write setlevelstep + default defaultlevelstep; + property defaultnodestate: nodestatesty read fdefaultnodestate + write fdefaultnodestate default []; + + property onstatreaditem: statreaditemeventty read fonstatreaditem + write fonstatreaditem; + property onstatreadtreeitem: statreadtreeitemeventty + read fonstatreadtreeitem write fonstatreadtreeitem; + property onstatwriteitem: statwriteitemeventty read fonstatwriteitem + write fonstatwriteitem; + property onstatwritetreeitem: statwritetreeitemeventty + read fonstatwritetreeitem write fonstatwritetreeitem; + + property onstatwrite: statwriteitemlisteventty read fonstatwrite + write fonstatwrite; //called before items + property onstatread: statreaditemlisteventty read fonstatread + write fonstatread; //called before items + end; + + ttreenode = class; + treenodeclassty = class of ttreenode; + treenodearty = array of ttreenode; + nodeeventty = procedure(const sender: ttreenode) of object; + treenodefilterfuncty = function(const sender: ttreenode): boolean of object; + + ttreenode = class + private + procedure setcount(const value: integer); + procedure checkindex(const index: integer); + procedure convertflat(const listitem: ttreelistitem; + const filterfunc: treenodefilterfuncty); + function converttree(const filterfunc: treenodefilterfuncty): ttreelistitem; + protected + fitems: treenodearty; + fcount: integer; + fparent: ttreenode; + function getitems(const index: integer): ttreenode; + procedure setitems(const index: integer; const Value: ttreenode); + function treenodeclass: treenodeclassty; virtual; + function listitemclass: treelistitemclassty; virtual; + procedure nodetoitem(const listitem: ttreelistitem); virtual; + public + destructor destroy; override; + procedure clear; virtual; + function count: integer; + function add(const anode: ttreenode): integer; + procedure iterate(const event: nodeeventty); + function converttotreelistitem(flat: boolean = false; + withrootnode: boolean = false; + filterfunc: treenodefilterfuncty = nil): ttreelistitem; + property items[const index: integer]: ttreenode read getitems + write setitems; default; + property parent: ttreenode read fparent; + end; + + ptreenode = ^ttreenode; + + function copylistitems(const asource: listitemarty): listitemarty; + +implementation +uses + {$ifdef FPCc}rtlconst{$else}rtlconsts{$endif}, + sysutils,msebits,msesysintf; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + imageextendcaptionpos = [cp_right,cp_righttop{,cp_rightcenter},cp_rightbottom]; + +function copylistitems(const asource: listitemarty): listitemarty; +var + int1: integer; +begin + result:= nil; + allocuninitedarray(length(asource),sizeof(pointer),result); + for int1:= 0 to high(result) do begin + result[int1]:= listitemclassty(asource[int1].classtype).create(nil); + result[int1].assign(asource[int1]); + end; +end; + +{ tfontarrayprop } + +constructor tfontarrayprop.create(); +begin + inherited create(tfont); +end; + +procedure tfontarrayprop.setitems(const index: integer; const avalue: tfont); +begin + checkindex(index); + if fitems[index] <> nil then begin + fitems[index].assign(avalue); + end; +end; + +function tfontarrayprop.getitems(const index: integer): tfont; +begin + result:= tfont(inherited getitems(index)); +end; + +procedure tfontarrayprop.createitem(const index: integer; + var item: tpersistent); +begin + item:= tfont.create; + item.assign(stockobjects.fonts[stf_default]); +end; + +class function tfontarrayprop.getitemclasstype: persistentclassty; +begin + result:= tfont; +end; + +{ tlistitem } + +constructor tlistitem.create(const aowner: tcustomitemlist); +begin + findex:= -1; + if aowner <> nil then begin + setowner(aowner); + end; + if (fowner <> nil) then begin + fstate:= fowner.fdefaultnodestate; + end; +end; + +constructor tlistitem.createassign(const aowner: tcustomitemlist; + const asource: tlistitem); +begin + create(aowner); + assign(asource); +end; + +destructor tlistitem.destroy; +begin + if not (ns1_destroying in fstate1) then begin + include(fstate1,ns1_destroying); + if (fowner <> nil) then begin + if not(ils_destroying in fowner.fitemstate) then begin + checkaction(na_destroying); + end; + end; + end; + inherited; +end; + +procedure tlistitem.assign(const source: tlistitem); +begin + beginupdate; + tag:= source.tag; + tagpo:= source.tagpo; + caption:= source.fcaption; + state:= source.fstate; + imagelist:= source.fimagelist; + imagenr:= source.fimagenr; + endupdate; +end; + +class procedure tlistitem.calcitemlayout(const asize: sizety; + const ainnerframe: framety; + const list: tcustomitemlist; var info: listitemlayoutinfoty); +var + aimagesize: sizety; +const + checkboxdist = 1; +begin + with list do begin + aimagesize:= fimagesize; + info.imagealignment:= fimagealignment; + end; + with info do begin + cellsize:= asize; + captionrect:= makerect(nullpoint,asize); + imagerect:= captionrect; + if no_checkbox in list.foptions then begin + checkboxrect.size.cx:= checkboxsize + 2*checkboxdist; + checkboxrect.size.cy:= checkboxrect.size.cx; + aimagesize.cx:= aimagesize.cx + checkboxrect.size.cx; + if aimagesize.cy < checkboxsize then begin + aimagesize.cy:= checkboxsize; + end; + end + else begin + checkboxrect.size:= nullsize; + checkboxinnerrect.size:= nullsize; + end; + textflags:= [tf_xcentered,tf_ycentered]; + case list.fcaptionpos of + cp_left,cp_lefttop,cp_leftbottom: begin + dec(captionrect.cx,aimagesize.cx); + imagerect.x:= captionrect.cx; + imagerect.cx:= aimagesize.cx; + case list.fcaptionpos of + cp_lefttop: textflags:= [tf_right]; + cp_leftbottom: textflags:= [tf_ycentered,tf_right]; + else textflags:= [tf_bottom,tf_right]; + end; + end; + cp_right,cp_righttop,cp_rightbottom: begin + captionrect.x:= aimagesize.cx; + dec(captionrect.cx,aimagesize.cx); + imagerect.cx:= aimagesize.cx; + case list.captionpos of + cp_righttop: textflags:= []; + cp_rightbottom: textflags:= [tf_bottom]; + else textflags:= [tf_ycentered]; + end; + end; + cp_top,cp_topleft,cp_topright: begin + dec(captionrect.cy,aimagesize.cy); + imagerect.y:= captionrect.cy; + imagerect.cy:= aimagesize.cy; + case list.captionpos of + cp_topleft: textflags:= [tf_ycentered]; + cp_topright: textflags:= [tf_ycentered,tf_right]; + else textflags:= [tf_ycentered,tf_xcentered]; + end; + end; + cp_bottom,cp_bottomleft,cp_bottomright: begin + captionrect.y:= aimagesize.cy; + dec(captionrect.cy,aimagesize.cy); + imagerect.cy:= aimagesize.cy; + case list.captionpos of + cp_bottomleft: textflags:= [tf_ycentered]; + cp_bottomright: textflags:= [tf_ycentered,tf_right]; + else textflags:= [tf_ycentered,tf_xcentered]; + end; + end; + end; + captioninnerrect:= deflaterect(captionrect,ainnerframe); + checkboxrect.y:= imagerect.y + (imagerect.cy - checkboxrect.cy) div 2; + checkboxrect.x:= imagerect.x; + if no_checkbox in list.foptions then begin + imagerect.x:= imagerect.x + checkboxrect.cx; + imagerect.cx:= imagerect.cx - checkboxrect.cx; + checkboxinnerrect:= inflaterect(checkboxrect,-checkboxdist); + end + else begin + checkboxinnerrect.pos:= checkboxrect.pos; + end; + minsize:= aimagesize; + end; +end; + +procedure tlistitem.drawimage(const acanvas: tcanvas; + var alayoutinfo: listitemlayoutinfoty); +var + int1: integer; + aimagelist: timagelist; + glyphno: int32; + nopaint: boolean; +begin + aimagelist:= imagelist; + nopaint:= (acanvas = nil) or alayoutinfo.variable.calcautocellsize; + with fowner,alayoutinfo do begin + variable.imageextend:= nullsize; + if not nopaint then begin //acanvas <> nil then begin + if (no_checkbox in foptions) and (ns_checkbox in self.fstate) then begin + glyphno:= boxids[tib_checkbox]; + if ns_checked in self.fstate then begin + glyphno:= boxids[tib_checkboxchecked]; + if (ns_showparentnotchecked in self.fstate) and + (ns1_parentnotchecked in self.fstate1) then begin + glyphno:= boxids[tib_checkboxparentnotchecked]; + end + else begin + if (ns_showchildnotchecked in self.fstate) and + (ns1_childnotchecked in self.fstate1) then begin + glyphno:= boxids[tib_checkboxchildnotchecked]; + end; + end; + end + else begin + if (ns_showchildchecked in self.fstate) and + (ns1_childchecked in self.fstate1) then begin + glyphno:= boxids[tib_checkboxchildchecked]; + end; + end; + stockobjects.glyphs.paint(acanvas,glyphno,checkboxrect, + [al_xcentered,al_ycentered],variable.colorglyph, + cl_default,cl_default,variable.glyphversion); + end; + end; + if aimagelist <> nil then begin + if fowner.captionpos in imageextendcaptionpos then begin + variable.imageextend.cx:= aimagelist.size.cx + variable.extra.image.cx - + imagerect.cx; + end; + if not nopaint then begin //acanvas <> nil then begin + int1:= getactimagenr(alayoutinfo); + if (int1 >= 0) and (int1 < aimagelist.count) then begin + //todo: check imagepos and the like + with imagerect do begin + aimagelist.paint(acanvas,int1,mr(x,y,cx+variable.imageextend.cx,cy), + imagealignment,variable.colorglyph, + cl_default,cl_default,variable.imageversion); + end; + end; + end; + end + else begin + if fowner.captionpos in imageextendcaptionpos then begin + variable.imageextend.cx:= variable.extra.image.cx - imagerect.cx; + end; + end; + end; +end; + +procedure tlistitem.updatecaption(const acanvas: tcanvas; + var alayoutinfo: listitemlayoutinfoty; + var ainfo: drawtextinfoty); +var + int1: integer; +begin +//toto: check captionpos and the like + with alayoutinfo do begin + ainfo.dest.cx:= ainfo.dest.cx - variable.treelevelshift; + ainfo.clip.cx:= ainfo.clip.cx - variable.treelevelshift; +// if fimagelist <> nil then begin + if (variable.imageextend.cx <> 0) and + (fowner.captionpos in imageextendcaptionpos) then begin + int1:= variable.imageextend.cx; + with ainfo.dest do begin + x:= x+int1; + cx:= cx-int1; + end; + with ainfo.clip do begin + x:= x+int1; + cx:= cx-int1; + end; + end; +// end; + end; +end; + +procedure tlistitem.drawcell(const acanvas: tcanvas); +var + info: drawtextinfoty; +// pt1: pointty; + po1: pcellinfoty; + layoutinfopo: plistitemlayoutinfoty; + size1: sizety; +begin +// pt1:= acanvas.origin; + po1:= pcellinfoty(acanvas.drawinfopo); + layoutinfopo:= fowner.fintf.getlayoutinfo(po1); + layoutinfopo^.variable.calcautocellsize:= po1^.calcautocellsize; +// if not po1^.calcautocellsize then begin + drawimage(acanvas,layoutinfopo^); //ttreelistitem shifts origin +// end +// else begin +// drawimage(layoutinfopo^,nil); +// end; + with layoutinfopo^ do begin + info.text.text:= fcaption; + info.text.format:= nil; + info.dest:= captioninnerrect; + inc(info.dest.cx,variable.extra.caption.cx); + inc(info.dest.cy,variable.extra.caption.cy); + info.clip:= captionrect; + inc(info.clip.cx,variable.extra.caption.cx); + inc(info.clip.cy,variable.extra.caption.cy); + info.flags:= textflags {- [tf_clipo]}; + info.font:= nil; + info.tabulators:= nil; + updatecaption(acanvas,layoutinfopo^,info); + if po1^.calcautocellsize then begin + textrect(acanvas,info); + size1.cx:= po1^.rect.cx + info.res.cx - info.dest.cx; + if size1.cx < minsize.cx then begin + size1.cx:= minsize.cx; + end; + size1.cy:= po1^.rect.cy + info.res.cy - info.dest.cy; + if size1.cy < minsize.cy then begin + size1.cy:= minsize.cy; + end; + if size1.cx > po1^.autocellsize.cx then begin + po1^.autocellsize.cx:= size1.cx; + end; + if size1.cy > po1^.autocellsize.cy then begin + po1^.autocellsize.cy:= size1.cy; + end; + end + else begin + drawtext(acanvas,info); + if not rectinrect(info.res,info.dest) then begin + include(fstate1,ns1_captionclipped); + end + else begin + exclude(fstate1,ns1_captionclipped); + end; + { + with info.res do begin + x:= x + captioninnerrect.x - info.dest.x; + y:= y + captioninnerrect.y - info.dest.y; + cx:= cx + captioninnerrect.cx - info.dest.cx; + cy:= cy + captioninnerrect.cy - info.dest.cy; + end; + if not rectinrect(info.res, + moverect(captioninnerrect,subpoint(pt1,acanvas.origin))) then begin + include(fstate1,ns1_captionclipped); + end + else begin + exclude(fstate1,ns1_captionclipped); + end; + } + end; + end; +end; + +function tlistitem.captionclipped: boolean; +begin + result:= ns1_captionclipped in fstate1; +end; + +procedure tlistitem.updatecellzone(const pos: pointty; var zone: cellzonety); +begin + with fowner.fintf.getlayoutinfo(nil)^ do begin + if pointinrect(pos,captionrect) then begin + zone:= cz_caption; + end + else begin + if (ns_checkbox in fstate) and pointinrect(pos,checkboxinnerrect) then begin + zone:= cz_checkbox; + end + else begin + if pointinrect(pos,imagerect) then begin + zone:= cz_image; + end; + end; + end; + end; +end; + +procedure tlistitem.setupeditor(const editor: tinplaceedit; const font: tfont; + const notext: boolean); +var + info1: drawtextinfoty; + po1: plistitemlayoutinfoty; +begin + po1:= fowner.fintf.getlayoutinfo(nil); + po1^.variable.calcautocellsize:= true; + drawimage(editor.getfontcanvas(),po1^); //calc image extend + with po1^ do begin + info1.font:= font; + with info1 do begin + tabulators:= nil; + dest:= captioninnerrect; + inc(dest.cx,variable.extra.caption.cx); + inc(dest.cy,variable.extra.caption.cy); + clip:= captionrect; + inc(clip.cx,variable.extra.caption.cx); + inc(clip.cy,variable.extra.caption.cy); + if not notext then begin + text.text:= fcaption; + end + else begin + text.text:= editor.text; + end; + flags:= textflags; + + updatecaption(editor.getfontcanvas(),po1^,info1); + editor.setup(text.text,editor.curindex,false,dest,clip,text.format,nil,font); + end; + end; +end; + +procedure tlistitem.change(); +var + action: nodeactioninfoty; +begin + if fowner <> nil {and (fowner.fnochange = 0)} then begin + action.action:= na_change; + fowner.nodenotification(self,action); + end; +end; + +procedure tlistitem.valuechange(const delta: nodestatesty = []); +var + action: nodeactioninfoty; +begin + if fowner <> nil then begin + if ns_checked in delta then begin + action.action:= na_checkedchange; + end + else begin + action.action:= na_valuechange; + end; + fowner.nodenotification(self,action); + end; +end; + +procedure tlistitem.setcaption(const avalue: msestring); +begin + fcaption:= avalue; + change(); + if not (ns1_fixedcaption in fstate1) then begin + valuechange([]); + end; +end; + +procedure tlistitem.setstate(const Value: nodestatesty); +var + stat1: nodestatesty; +begin + stat1:= nodestatesty(longword(fstate) xor longword(value)); + fstate := Value; + if stat1 * invalidatestates <> [] then begin + change(); + end; + if stat1 * valuechangestates <> [] then begin + valuechange(stat1); + end; +end; + +procedure tlistitem.setimagenr(const Value: integer); +begin + if fimagenr <> value then begin + fimagenr := Value; + change; + end; +end; + +procedure tlistitem.mouseevent(var info: mouseeventinfoty); +//var +// bo1: boolean; +begin + with info do begin + if eventkind in mouseposevents then begin + if pointinrect(pos, + fowner.fintf.getlayoutinfo(nil)^.checkboxinnerrect) then begin + if (eventkind = ek_buttonrelease) then begin + if (shiftstate * keyshiftstatesmask = []) and (button = mb_left) and + (ns1_checkboxclicked in fstate1) then begin + checked:= not checked; + include(eventstate,es_processed); + end; + exclude(fstate1,ns1_checkboxclicked); + end + else begin + if (eventkind = ek_buttonpress) and + (shiftstate * keyshiftstatesmask = []) and + (button = mb_left) then begin + include(fstate1,ns1_checkboxclicked); + end; + end; + end + else begin + exclude(fstate1,ns1_checkboxclicked); + end + end; + if eventkind in [ek_mouseleave,ek_clientmouseleave] then begin + exclude(fstate1,ns1_checkboxclicked); + end; + end; +end; + +procedure tlistitem.focusrow(); +var + grid1: tcustomgrid; +begin + if (fowner <> nil) then begin + grid1:= fowner.fintf.getgrid(); + if grid1 <> nil then begin + grid1.row:= findex; + end; + end; +end; + +function tlistitem.getselected: boolean; +begin + result:= ns_selected in fstate; +end; + +procedure tlistitem.setselected(const Value: boolean); +begin + if value then begin + setstate(fstate + [ns_selected]); + end + else begin + setstate(fstate - [ns_selected]); + end; +end; + +function tlistitem.getchecked: boolean; +begin + result:= ns_checked in fstate; +end; + +procedure tlistitem.setchecked(const avalue: boolean); +begin + if avalue then begin + setstate(fstate + [ns_checked]); + end + else begin + setstate(fstate - [ns_checked]); + end; +end; + +function tlistitem.getcheckbox: boolean; +begin + result:= ns_checkbox in fstate; +end; + +procedure tlistitem.setcheckbox(const avalue: boolean); +begin + if avalue then begin + setstate(fstate + [ns_checkbox]); + end + else begin + setstate(fstate - [ns_checkbox]); + end; +end; + +function tlistitem.checkaction(aaction: nodeactionty): boolean; +var + action: nodeactioninfoty; +begin + action.action:= aaction; + actionnotification(action); + result:= action.action = aaction; +end; + +procedure tlistitem.actionnotification(var ainfo: nodeactioninfoty); +begin + if fowner <> nil then begin + fowner.nodenotification(self,ainfo); + end; +end; + +function tlistitem.getactimagenr( + const alayoutinfo: listitemlayoutinfoty): integer; +begin + result:= fowner.fimnr_base + fimagenr; + if not (ns_imagenrfix in fstate) then begin + if ns_expanded in fstate then begin + inc(result,fowner.fimnr_expanded); + end; + if ns_selected in fstate then begin + inc(result,fowner.fimnr_selected); + end; + if ns_readonly in fstate then begin + inc(result,fowner.fimnr_readonly); + end; + if ns_checked in fstate then begin + inc(result,fowner.fimnr_checked); + end; + if ns_subitems in fstate then begin + inc(result,fowner.fimnr_subitems); + end; + if ws_focused in alayoutinfo.variable.widgetstate then begin + inc(result,fowner.fimnr_focused); + end; + if ws_active in alayoutinfo.variable.widgetstate then begin + inc(result,fowner.fimnr_active); + end; + end; +end; + +procedure tlistitem.setimagelist(const Value: timagelist); +begin + if fimagelist <> value then begin + if fowner <> nil then begin + if (fimagelist <> nil) and (fimagelist <> fowner.imagelist) then begin + fowner.unregisterobject(ievent(fimagelist)); + end; + if (value <> nil) and (value <> fowner.fimagelist) then begin + fowner.registerobject(ievent(value)); + end; + end; + fimagelist:= value; + change; + end; +end; + +function tlistitem.getimagelist: timagelist; +begin + if fimagelist = nil then begin + if (fowner <> nil) and not (ns1_nodefaultimagelist in fstate1) then begin + result:= fowner.fimagelist; + end + else begin + result:= nil; + end; + end + else begin + result:= fimagelist; + end; +end; + +function tlistitem.getvaluetext: msestring; +begin + result:= fcaption; +end; + +procedure tlistitem.setvaluetext(var avalue: msestring); +begin + caption:= avalue; +end; + +procedure tlistitem.setvaluetext1(const avalue: msestring); +var + str1: msestring; +begin + str1:= avalue; + setvaluetext(str1); +end; + +procedure tlistitem.objectevent(const sender: tobject; + const event: objecteventty); +begin + if sender = fimagelist then begin + case event of + oe_destroyed: begin + fimagelist:= nil; + change; + end; + oe_changed: begin + change; + end; + end; + end; +end; + +procedure tlistitem.setowner(const aowner: tcustomitemlist); +begin + if aowner <> fowner then begin + findex:= -1; + if (fowner <> nil) and (fimagelist <> nil) then begin + fowner.unregisterobject(ievent(fimagelist)); + end; + fowner:= aowner; + if (fimagelist <> nil) and (fowner <> nil) then begin + fowner.registerobject(ievent(fimagelist)); + end; + end; +end; + +procedure tlistitem.beginupdate; +begin + if fowner <> nil then begin + fowner.beginupdate; + end; +end; + +procedure tlistitem.endupdate; +begin + if fowner <> nil then begin + fowner.endupdate; + end; +end; + +procedure tlistitem.dostatread(const reader: tstatreader); +var + ca1: longword; +begin + reader.readrecord('a',[@tag,@ca1,@fimagenr,@fcaption], + [tag,longword(fstate),fimagenr,fcaption]); + fstate:= nodestatesty(replacebits(ca1,longword(fstate),longword(statstates))); +end; + +procedure tlistitem.dostatwrite(const writer: tstatwriter); +begin + writer.writerecord('a',[tag,longword(fstate),fimagenr,fcaption]); +end; + +procedure tlistitem.dostatupdate(const filer: tstatfiler); +begin + if filer.iswriter then begin + dostatwrite(tstatwriter(filer)); + end + else begin + dostatread(tstatreader(filer)); + end; +end; + +function tlistitem.empty: boolean; +begin + result:= fcaption = ''; +end; + +procedure tlistitem.releaseowner; +begin + setowner(nil); +end; + +function tlistitem.compare(const r: tlistitem; + const acasesensitive: boolean): integer; +begin + result:= 0; + if ns1_top in fstate1 then begin + dec(result); + end; + if ns1_top in r.fstate1 then begin + inc(result); + end; + if result = 0 then begin + if acasesensitive then begin +// result:= msestringcomp(fcaption,r.fcaption); + result:= msecomparestr(fcaption,r.fcaption); + end + else begin +// result:= msestringicomp(fcaption,r.fcaption); + result:= msecomparetext(fcaption,r.fcaption); + end; + end; +end; + +{ tcustomitemlist } + +constructor tcustomitemlist.create; +begin + fcaptionpos:= cp_right; + fimagealignment:= [al_xcentered,al_ycentered]; + flevelstep:= defaultlevelstep; + ffonts:= tfontarrayprop.create(); + inherited; + fitemclass:= tlistitem; +end; + +constructor tcustomitemlist.create(const intf: iitemlist); +begin + fintf:= intf; + create; +end; + +destructor tcustomitemlist.destroy; +begin + include(fitemstate,ils_destroying); + inherited; + ffonts.free(); + fobjectlinker.free; +end; + +function tcustomitemlist.indexof(const aitem: tlistitem): integer; +var + po1: ppointeraty; + int1: integer; +begin + result:= -1; + normalizering; + po1:= datapo; + for int1:= 0 to fcount - 1 do begin + if tlistitem(po1^[int1]) = aitem then begin + result:= int1; + break; + end; + end; +end; + +procedure tcustomitemlist.doitemchange(const index: integer); +var + int1: integer; + po1: ^tlistitem; +begin + if index = -1 then begin + po1:= datapo; + for int1:= 0 to count-1 do begin + if po1^ <> nil then begin + po1^.findex:= int1; + end; + inc(po1); + end; + end; + inherited; +end; + +function tcustomitemlist.getitems1(const index: integer): tlistitem; +begin + result:= tlistitem(inherited items[index]); +end; + +procedure tcustomitemlist.setitems(const index: integer; + const Value: tlistitem); +begin + inherited items[index]:= value; +end; +(* +function tcustomitemlist.getobjectlinker: tobjectlinker; +begin + createobjectlinker(self,{$ifdef FPC}@{$endif}objectevent, + fobjectlinker); + result:= fobjectlinker; +end; +*) +procedure tcustomitemlist.objectevent(const sender: tobject; + const event: objecteventty); +var + po1,pe: plistitem; +begin + inherited; + if (event <> oe_connect) then begin + normalizering; + po1:= plistitem(fdatapo); + pe:= po1 + count; + while po1 < pe do begin + po1^.objectevent(sender,event); + inc(po1); + end; + if sender = fimagelist then begin + case event of + // oe_destroyed: imagelist:= nil; + oe_changed: invalidate; + end; + end; + end; +end; + +procedure tcustomitemlist.invalidate; +begin + //dummy +end; + +procedure tcustomitemlist.setimageheight(const Value: integer); +begin + if fimagesize.cy <> value then begin + fimagesize.cy := Value; + updatelayout; +// invalidate; + end; +end; + +procedure tcustomitemlist.setimagewidth(const Value: integer); +begin + if fimagesize.cx <> value then begin + fimagesize.cx := Value; + updatelayout; +// invalidate; + end; +end; + +procedure tcustomitemlist.setimagesize(const avalue: sizety); +begin + if (fimagesize.cx <> avalue.cx) or (fimagesize.cy <> avalue.cy) then begin + fimagesize:= avalue; + updatelayout; + end; +end; + +procedure tcustomitemlist.setimagealignment(const avalue: alignmentsty); +begin + if fimagealignment <> avalue then begin + movealignment(avalue,fimagealignment); + updatelayout; + end; +end; + +procedure tcustomitemlist.setimagelist(const Value: timagelist); +var + imagelistbefore: timagelist; +begin + if fimagelist <> value then begin + imagelistbefore:= fimagelist; + setlinkedcomponent(iobjectlink(self),value,tmsecomponent(fimagelist)); + if (fimagelist <> nil) and + (fintf.getcomponentstate * [csdesigning,csloading] = + [csdesigning]) then begin + if (imagelistbefore = nil) or + (imagelistbefore.width = fimagesize.cx) then begin + fimagesize.cx:= fimagelist.width; + end; + if (imagelistbefore = nil) or + (imagelistbefore.height = fimagesize.cy) then begin + fimagesize.cy:= fimagelist.height; + end; + end; + updatelayout; +// invalidate; + end; +end; + +procedure tcustomitemlist.setimnr_base(const Value: integer); +begin + if fimnr_base <> value then begin + fimnr_base:= Value; + invalidate; + end; +end; + +procedure tcustomitemlist.setimnr_expanded(const Value: integer); +begin + if fimnr_expanded <> value then begin + fimnr_expanded:= Value; + invalidate; + end; +end; + +procedure tcustomitemlist.setimnr_selected(const Value: integer); +begin + if fimnr_selected <> value then begin + fimnr_selected:= Value; + invalidate; + end; +end; + +procedure tcustomitemlist.setimnr_readonly(const Value: integer); +begin + if fimnr_readonly <> value then begin + fimnr_readonly:= Value; + invalidate; + end; +end; + +procedure tcustomitemlist.setimnr_checked(const Value: integer); +begin + if fimnr_checked <> value then begin + fimnr_checked := Value; + invalidate; + end; +end; + +procedure tcustomitemlist.setimnr_subitems(const Value: integer); +begin + if fimnr_subitems <> value then begin + fimnr_subitems := Value; + invalidate; + end; +end; + +procedure tcustomitemlist.setimnr_focused(const avalue: integer); +begin + if fimnr_focused <> avalue then begin + fimnr_focused := avalue; + invalidate; + end; +end; + +procedure tcustomitemlist.setimnr_active(const avalue: integer); +begin + if fimnr_active <> avalue then begin + fimnr_active := avalue; + invalidate; + end; +end; + +procedure tcustomitemlist.setoptions(const Value: nodeoptionsty); +var + optionsbefore: nodeoptionsty; +begin + if foptions <> value then begin + optionsbefore:= foptions; + foptions:= Value; + if no_nofreeitems in value then begin + exclude(fstate,dls_needsfree); + end + else begin + include(fstate,dls_needsfree); + end; + if nodeoptionsty({$ifdef FPC}longword{$else}byte{$endif}(foptions) xor + {$ifdef FPC}longword{$else}byte{$endif}(optionsbefore)) * + [no_checkbox] <> [] then begin + updatelayout; + end + else begin + invalidate; + end; + end; +end; + +procedure tcustomitemlist.setcaptionpos(const Value: captionposty); +begin + if fcaptionpos <> value then begin + fcaptionpos := Value; + updatelayout; + end; +end; + +procedure tcustomitemlist.updatelayout; +begin + if fintf <> nil then begin + fintf.updatelayout; + invalidate; + end; +end; + +procedure tcustomitemlist.docreateobject(var instance: tobject); +begin + inherited; + if instance = nil then begin + createitem(tlistitem(instance)); + end; +end; + +procedure tcustomitemlist.createitem(out item: tlistitem); +begin + item:= listitemclassty(fitemclass).create(self); +end; + +procedure tcustomitemlist.createstatitem(const reader: tstatreader; + out item: tlistitem); +begin + createitem(item); +end; + +procedure tcustomitemlist.statreaditem(const reader: tstatreader; + var aitem: tlistitem); +begin + if assigned(fonstatreaditem) then begin + fonstatreaditem(self,reader,aitem); + end; + if aitem = nil then begin + createstatitem(reader,aitem); + end; +end; + +procedure tcustomitemlist.statreadtreeitem(const reader: tstatreader; + const parent: ttreelistitem; var aitem: ttreelistitem); +begin + if assigned(fonstatreadtreeitem) then begin + fonstatreadtreeitem(self,reader,aitem); + end; + if aitem = nil then begin + if parent <> nil then begin + aitem:= parent.createsubnode; + end + else begin + createitem(tlistitem(aitem)); + end; + end; +end; + +procedure tcustomitemlist.statwriteitem(const writer: tstatwriter; + const aitem: tlistitem); +begin + if assigned(fonstatwriteitem) then begin + fonstatwriteitem(self,writer,aitem); + end; +end; + +procedure tcustomitemlist.statwritetreeitem(const writer: tstatwriter; + const aitem: ttreelistitem); +begin + if assigned(fonstatwritetreeitem) then begin + fonstatwritetreeitem(self,writer,aitem); + end; +end; + +function tcustomitemlist.nodezone(const point: pointty): cellzonety; +begin + result:= cz_default; + with fintf.getlayoutinfo(nil)^ do begin + if pointinrect(point,captionrect) then begin + result:= cz_caption; + end + else begin + if pointinrect(point,imagerect) then begin + result:= cz_image; + end; + end; + end; +end; + +procedure tcustomitemlist.nodenotification(const sender: tlistitem; + var ainfo: nodeactioninfoty); +begin + if ainfo.action = na_destroying then begin + if not deleting then begin + deletedata(sender.index); + end; + end + else begin + if (ainfo.action = na_change) then begin + change(sender); + end; + end; +end; + +procedure tcustomitemlist.setitemselected(const row: integer; + const value: boolean); +var + po1: plistitematy; + int1: integer; +begin + if (no_cellitemselect in foptions) and + not (dls_selectsetting in fstate) then begin + if row >= 0 then begin + with items[row] do begin + if value then begin + include(fstate,ns_selected); + end + else begin + exclude(fstate,ns_selected); + end; + end; + end + else begin + po1:= datapo; + if value then begin + for int1:= 0 to count - 1 do begin + include(po1^[int1].fstate,ns_selected); + end; + end + else begin + for int1:= 0 to count - 1 do begin + exclude(po1^[int1].fstate,ns_selected); + end; + end; + end; + end; +end; + +procedure tcustomitemlist.freedata(var data); +begin + if not (no_nofreeitems in foptions) and (tlistitem(data) <> nil) and + not (ns1_destroying in tlistitem(data).fstate1) then begin + inherited; + end; +end; + +procedure tcustomitemlist.change(const item: tlistitem); +begin + if item = nil then begin + change(-1); + end + else begin + change(item.findex); + end; +end; + +procedure tcustomitemlist.setlevelstep(const Value: integer); +begin + if flevelstep <> value then begin + flevelstep := Value; + change(-1); + end; +end; + +procedure tcustomitemlist.registerobject(const aobject: iobjectlink); +begin + getobjectlinker.link(iobjectlink(self),aobject); +end; + +procedure tcustomitemlist.unregisterobject(const aobject: iobjectlink); +begin + getobjectlinker.unlink(iobjectlink(self),aobject); +end; + +function tcustomitemlist.add(const aitem: tlistitem): integer; +begin + aitem.setowner(self); + result:= inherited add(aitem); +end; + +procedure tcustomitemlist.add(const aitems: array of msestring); +var + int1,int2: integer; + po1: plistitem; +begin + beginupdate; + try + int1:= count; + count:= count + length(aitems); + po1:= datapo; + inc(po1,int1); + for int2:= 0 to high(aitems) do begin + po1^.caption:= aitems[int2]; + inc(po1); + end; + finally + endupdate; + end; +end; + +procedure tcustomitemlist.add(const aitems: msestringarty); +var + int1,int2: integer; + po1: plistitem; +begin + beginupdate; + try + int1:= count; + count:= count + length(aitems); + po1:= datapo; + inc(po1,int1); + for int2:= 0 to high(aitems) do begin + po1^.caption:= aitems[int2]; + inc(po1); + end; + finally + endupdate; + end; +end; + +function tcustomitemlist.add(const aitem: msestring): integer; +begin + result:= count; + add([aitem]); +end; + +procedure tcustomitemlist.add(const aitems: listitemarty); +var + int1: integer; +begin + beginupdate; + try + for int1:= 0 to high(aitems) do begin + add(aitems[int1]); + end; + finally + endupdate; + end; +end; + +procedure tcustomitemlist.writestate(const writer; const name: msestring); +var + int1: integer; + po1: ppointeraty; + item1: tlistitem; +begin + dostatwrite(tstatwriter(writer),name); + po1:= datapo; + with tstatwriter(writer) do begin + writeinteger(name,count); + for int1:= 0 to count - 1 do begin + beginlist; + item1:= tlistitem(po1^[int1]); + statwriteitem(tstatwriter(writer),item1); + item1.dostatwrite(tstatwriter(writer)); + endlist; + end; + end; +end; + +procedure tcustomitemlist.readstate(const reader; const acount: integer; + const name: msestring); +var + int1: integer; + item1: tlistitem; +begin + dostatread(tstatreader(reader),name); + with tstatreader(reader) do begin + int1:= acount; + if int1 >= 0 then begin + beginupdate; + try + clear; + for int1:= 0 to acount - 1 do begin + beginlist; + item1:= nil; + statreaditem(tstatreader(reader),item1); + if item1 <> nil then begin + add(item1); + item1.dostatread(tstatreader(reader)); + end; + endlist; + end; + finally + endupdate; + end; + end; + end; +end; + +function tcustomitemlist.getitems(const must: nodestatesty; + const mustnot: nodestatesty): listitemarty; +var + int1: integer; + int2: integer; + item1: tlistitem; + po1: ppointeraty; +begin + result:= nil; + int2:= 0; + po1:= datapo; + for int1:= 0 to count - 1 do begin + item1:= tlistitem(po1^[int1]); + with item1 do begin + if (fstate * must = must) and (fstate * mustnot = []) then begin + if int2 > high(result) then begin + setlength(result,10+length(result)*2); + end; + result[int2]:= item1; + inc(int2); + end; + end; + end; + setlength(result,int2); +end; + +function tcustomitemlist.getindexes(const must: nodestatesty; + const mustnot: nodestatesty): integerarty; +var + int1: integer; + int2: integer; + item1: tlistitem; + po1: ppointeraty; +begin + result:= nil; + int2:= 0; + po1:= datapo; + for int1:= 0 to count - 1 do begin + item1:= tlistitem(po1^[int1]); + with item1 do begin + if (fstate * must = must) and (fstate * mustnot = []) then begin + if int2 > high(result) then begin + setlength(result,10+length(result)*2); + end; + result[int2]:= int1; + inc(int2); + end; + end; + end; + setlength(result,int2); +end; + +function tcustomitemlist.getselecteditems: listitemarty; +begin + result:= getitems([ns_selected],[]); +end; + +function tcustomitemlist.getselectedindexes: integerarty; +begin + result:= getindexes([ns_selected],[]); +end; + +function tcustomitemlist.getcheckeditems: listitemarty; +begin + result:= getitems([ns_checked],[]); +end; + +function tcustomitemlist.getcheckedindexes: integerarty; +begin + result:= getindexes([ns_checked],[]); +end; + +function tcustomitemlist.empty(const index: integer): boolean; +var + item1: tlistitem; +begin + item1:= items[index]; + result:= (item1 = nil) or item1.empty; +end; + +function tcustomitemlist.layoutinfopo: plistitemlayoutinfoty; +begin + result:= fintf.getlayoutinfo(nil); +end; + +procedure tcustomitemlist.dostatread(const reader: tstatreader; + const name: msestring); +begin + if assigned(fonstatread) then begin + fonstatread(self,reader,name); + end; +end; + +procedure tcustomitemlist.dostatwrite(const writer: tstatwriter; + const name: msestring); +begin + if assigned(fonstatwrite) then begin + fonstatwrite(self,writer,name); + end; +end; + +procedure tcustomitemlist.removeitem(const aindex: integer); +var + bo1: boolean; +begin + bo1:= ils_freelock in fitemstate; + include(fitemstate,ils_freelock); + try + deleteitems(aindex,1); + finally + if not bo1 then begin + exclude(fitemstate,ils_freelock); + end; + end; +end; + +procedure tcustomitemlist.setfonts(const avalue: tfontarrayprop); +begin + ffonts.assign(avalue); +end; + +procedure tcustomitemlist.setcount(const value: integer); +begin + if value < fcount then begin + inc(fdeleting); + try + inherited; + finally + dec(fdeleting); + end; + end + else begin + inherited; + end; +end; + +function tlistitem.gettop: boolean; +begin + result:= ns1_top in fstate1; +end; + +procedure tlistitem.settop(const avalue: boolean); +begin + if avalue then begin + include(fstate1,ns1_top); + end + else begin + exclude(fstate1,ns1_top); + end; +end; + +function tlistitem.cancaptionedit: boolean; +begin + result:= not (ns_readonly in fstate) and not (ns1_fixedcaption in fstate1); +end; + +function tlistitem.canvalueedit: boolean; +begin + result:= not (ns_readonly in fstate); +end; + +function tlistitem.getvalueitem: tlistitem; +begin + result:= self; +end; + +procedure tlistitem.setvalueitem(const avalue: tlistitem); +begin + //dummy +end; + +function tlistitem.getownerintf: iitemlist inline; +begin + result:= fowner.fintf; +end; + +{ ttreelistitem } + +constructor ttreelistitem.create(const aowner: tcustomitemlist = nil; + const aparent: ttreelistitem = nil); +begin + if aparent <> nil then begin + if aparent <> fparent then begin + fparent:= aparent; + fparentindex:= -1; + end; + end; + if fparent = nil then begin + fparentindex:= -1; + end; + inherited create(aowner); +end; + +destructor ttreelistitem.destroy; +begin + if not (ns1_destroying in fstate1) then begin + include(fstate1,ns1_destroying); + if (fowner <> nil) and not (ils_destroying in fowner.fitemstate) then begin + checkaction(na_destroying); + end; + end; + if (fparent <> nil) and not (ns1_destroying in fparent.fstate1) then begin + fparent.remove(fparentindex); + end; + clear; + inherited; +end; + +procedure ttreelistitem.countchange(const atreeheightbefore: integer; + const notifyowner: boolean); +var + info1: nodeactioninfoty; +begin + if (fowner <> nil) and notifyowner then begin + info1.action:= na_countchange; + info1.treeheightbefore:= atreeheightbefore; + fowner.nodenotification(self,info1); + end; + if fcount > 0 then begin + state:= fstate + [ns_subitems]; + end + else begin + state:= fstate - [ns_subitems]; + end; +end; + +function ttreelistitem.getitems(const aindex: integer): ttreelistitem; +begin + checkindex(aindex); + result:= fitems[aindex]; +end; + +procedure ttreelistitem.dosetitems(const aindex: integer; + const value: ttreelistitem); +begin + fitems[aindex]:= value; + value.fparentindex:= aindex; + value.fparent:= self; + value.settreelevel(ftreelevel+1); + if (fowner <> nil) and (ns_expanded in fstate) then begin + value.setowner(fowner); + end; +end; + +procedure ttreelistitem.setitems(const aindex: integer; const value: ttreelistitem); + //for internal use +begin + dosetitems(aindex,value); + checksort; +end; + +procedure ttreelistitem.unsetitem(const aindex: integer); +begin + with fitems[aindex] do begin + fparent:= nil; + fparentindex:= -1; + setowner(nil); + settreelevel(0); + end; +end; + +function ttreelistitem.inccount: integer; //returns itemindex +begin + result:= fcount; + if fcount > high(fitems) then begin + setlength(fitems,(fcount*8) div 7 + 16); + end; + inc(fcount) +end; + +function ttreelistitem.add(const aitem: ttreelistitem): integer; +var + int1: integer; +begin + result:= -1; + if aitem <> nil then begin + if aitem = self then begin + raise exception.create('Can not add self.'); + end; + if aitem.parent = self then begin + internalmove(aitem.parentindex,fcount-1); + end + else begin + if aitem.fparent <> nil then begin + aitem.fparent.remove(aitem.fparentindex); + end + else begin + if aitem.fowner <> nil then begin + aitem.fowner.removeitem(aitem.findex); + end; + end; + int1:= treeheight; + dosetitems(inccount,aitem); + countchange(int1,true); + end; + checksort; + result:= aitem.fparentindex; + end; +end; + +procedure ttreelistitem.aftermove; +begin + countchange(fcount,true); //refresh grid + checksort; +end; + +procedure ttreelistitem.insert(aindex: integer; const aitem: ttreelistitem); +var + int1,int2: integer; +begin + if aindex > count then begin + aindex:= count; + end; + if aitem.parent = self then begin + if aindex = count then begin + dec(aindex); + end; + internalmove(aitem.parentindex,aindex); + aftermove; + end + else begin + if aindex <> count then begin + checkindex(aindex); + end; + int2:= treeheight; + if aitem.fparent <> nil then begin + aitem.fparent.remove(aitem.fparentindex); + end; + inccount; + insertitem(pointerarty(fitems),aindex,aitem); + fitems[aindex]:= aitem; + for int1:= aindex to count-1 do begin + fitems[int1].fparentindex:= int1; + end; + dosetitems(aindex,aitem); + countchange(int2,true); + checksort; + end; +end; + +procedure ttreelistitem.insert(const aitem: ttreelistitem; + aindex: integer); +begin + insert(aindex,aitem); +end; + +procedure ttreelistitem.move(const source: integer; const dest: integer); +begin + internalmove(source,dest); + aftermove; +end; + +procedure ttreelistitem.add(const aitems: treelistitemarty); +var + int1,int2: integer; +begin + if length(aitems) > 0 then begin + int2:= treeheight; + if fcount + length(aitems) >= length(fitems) then begin + setlength(fitems,fcount + length(aitems)); + end; + for int1:= 0 to high(aitems) do begin + dosetitems(fcount,aitems[int1]); + inc(fcount); + end; + countchange(int2,true); + checksort; + end; +end; + +procedure ttreelistitem.addchildren(const aitem: ttreelistitem); + //transfers children +begin + setlength(aitem.fitems,aitem.fcount); + add(aitem.fitems); + aitem.fcount:= 0; +end; + +function ttreelistitem.createsubnode: ttreelistitem; +begin + result:= treelistitemclassty(classtype).create(fowner); + //child class = parent class +end; + +procedure ttreelistitem.internalswap(const a,b: integer); +var + item1: ttreelistitem; +begin + checkindex(a); + checkindex(b); + item1:= fitems[a]; + item1.fparentindex:= b; + fitems[a]:= fitems[b]; + fitems[a].fparentindex:= a; + fitems[b]:= item1; +end; + +procedure ttreelistitem.swap(const a,b: integer); +begin + internalswap(a,b); + aftermove(); +end; + +procedure ttreelistitem.internalmove(const source,dest: integer); +var + int1: integer; +begin + checkindex(source); + checkindex(dest); + moveitem(pointerarty(fitems),source,dest); + if source < dest then begin + for int1:= source to dest do begin + fitems[int1].fparentindex:= int1; + end; + end + else begin + for int1:= dest to source do begin + fitems[int1].fparentindex:= int1; + end; + end; +end; + +function ttreelistitem.add(const itemclass: treelistitemclassty = nil): ttreelistitem; +begin + if itemclass <> nil then begin + result:= itemclass.create; + end + else begin + result:= createsubnode; + end; + add(result); +end; + +procedure ttreelistitem.add(const acount: integer; + const itemclass: treelistitemclassty = nil; + const defaultstate: nodestatesty = []); +var + int1,int2: integer; +begin + int2:= treeheight; + if length(fitems) < fcount + acount then begin + setlength(fitems,fcount + acount); + end; + if itemclass <> nil then begin + for int1:= 0 to acount-1 do begin + dosetitems(fcount,itemclass.create); + if defaultstate <> [] then begin + fitems[count].fstate:= defaultstate; + end; + inc(fcount); + end; + end + else begin + for int1:= 0 to acount-1 do begin + dosetitems(fcount,createsubnode); + if defaultstate <> [] then begin + fitems[count].fstate:= defaultstate; + end; + inc(fcount); + end; + end; + countchange(int2,true); + checksort; +end; + +procedure ttreelistitem.setdestroying; +var + int1: integer; +begin + include(fstate1,ns1_destroying); + for int1:= 0 to fcount - 1 do begin + fitems[int1].setdestroying; + end; +end; + +procedure ttreelistitem.setnotbyownerdestroying; +var + int1: integer; +begin + fstate1:= fstate1+[ns1_destroying,ns1_notbyownerdestroying]; + for int1:= 0 to fcount - 1 do begin + fitems[int1].setnotbyownerdestroying; + end; +end; + +procedure ttreelistitem.clear; +var + int1,int2: integer; + acount: integer; + aitems: treelistitemarty; + adestroying: boolean; +begin + aitems:= nil; //compilerwarning + if fcount > 0 then begin + int2:= treeheight; + adestroying:= ns1_destroying in fstate1; + if not (ns1_noowner in fstate1) then begin + if fowner = nil then begin + setnotbyownerdestroying(); + end + else begin + setdestroying(); + end; + end; + aitems:= fitems; + fitems:= nil; + acount:= fcount; + fcount:= 0; + countchange(int2,true); + if not (ns1_noowner in fstate1) then begin + for int1:= 0 to acount-1 do begin + with aitems[int1] do begin + if not adestroying or + (ns1_notbyownerdestroying in fstate1) and (fowner <> nil) then begin + setowner(nil); + end; + Free; + end; + end; + end + else begin + for int1:= 0 to acount-1 do begin + with aitems[int1] do begin + fparent:= nil; + fparentindex:= -1; + end; + end; + end; + if not adestroying then begin + exclude(fstate1,ns1_destroying); + end; + end; + fitems:= nil; //ev. free unused memory + exclude(fstate1,ns1_noowner); +end; + +procedure ttreelistitem.internalgetnodes(var aresult: treelistitemarty; + var acount: integer; + const must: nodestatesty; const mustnot: nodestatesty; + const amode: getnodemodety; const addself: boolean); + + procedure addchi(anode: ttreelistitem); + var + int1: integer; + begin + with anode do begin + for int1:= 0 to fcount - 1 do begin + if acount > high(aresult) then begin + setlength(aresult,10+length(aresult)*2); + end; + aresult[acount]:= fitems[int1]; + inc(acount); + addchi(fitems[int1]); + end; + end; + end; //addchi + +var + first: boolean; + + procedure check(anode: ttreelistitem); + var + int1: integer; + bo1: boolean; + begin + with anode do begin + if not first then begin + bo1:= (fstate * must = must) and (fstate * mustnot = []); + if bo1 then begin + if acount > high(aresult) then begin + setlength(aresult,10+length(aresult)*2); + end; + aresult[acount]:= anode; + inc(acount); + end; + end + else begin + first:= false; + bo1:= false; + end; + case amode of + gno_nochildren: begin + if bo1 then begin + exit; + end; + end; + gno_allchildren: begin + if bo1 then begin + addchi(anode); + exit; + end; + end; + end; + for int1:= 0 to fcount - 1 do begin + check(fitems[int1]); + end; + end; + end; //check + +begin + first:= not addself; + check(self); +end; + +function ttreelistitem.getnodes(const must: nodestatesty; + const mustnot: nodestatesty; + const amode: getnodemodety = gno_matching; + const addself: boolean = false): treelistitemarty; +var + int2: integer; +begin + result:= nil; + int2:= 0; + internalgetnodes(result,int2,must,mustnot,amode,addself); + setlength(result,int2); +end; + +function ttreelistitem.getselectednodes( + const amode: getnodemodety = gno_matching; + const addself: boolean = false): treelistitemarty; +begin + result:= getnodes([ns_selected],[],amode); +end; + +function ttreelistitem.getcheckednodes( + const amode: getnodemodety = gno_matching; + const addself: boolean = false): treelistitemarty; +begin + result:= getnodes([ns_checked],[],amode,addself); +end; + + +procedure ttreelistitem.internalcollapseall; +var + int1: integer; +begin + expanded:= false; + for int1:= 0 to count - 1 do begin + fitems[int1].internalcollapseall; + end; +end; + +procedure ttreelistitem.collapseall; +begin + beginupdate; + try + internalcollapseall; + finally + endupdate; + end; +end; + +procedure ttreelistitem.internalexpandall; +var + int1: integer; +begin + expanded:= true; + for int1:= 0 to count - 1 do begin + fitems[int1].internalexpandall; + end; +end; + +procedure ttreelistitem.expandall; +begin + beginupdate; + try + internalexpandall; + finally + endupdate; + end; +end; + +procedure ttreelistitem.expandtoroot(const afocusrow: boolean = true); +var + item1: ttreelistitem; +begin + item1:= fparent; + while item1 <> nil do begin + item1.expanded:= true; + item1:= item1.fparent; + end; + if afocusrow then begin + focusrow(); + end; +end; + +procedure ttreelistitem.collapsetoroot; +var + item1: ttreelistitem; +begin + item1:= fparent; + while item1 <> nil do begin + item1.expanded:= false; + item1:= item1.fparent; + end; +end; + +procedure ttreelistitem.internalcheckitems( + const checkdelete: checktreelistitemprocty); +var + int1,int2: integer; + bo1,bo2: boolean; + ar1: treelistitemarty; + aitem: ttreelistitem; +begin + bo1:= false; + for int1:= 0 to fcount - 1 do begin + aitem:= fitems[int1]; + aitem.internalcheckitems(checkdelete); + bo2:= false; + checkdelete(aitem,bo2); + if bo2 then begin + aitem.fparent:= nil; + aitem.fowner:= nil; + fitems[int1]:= nil; + aitem.Free; + bo1:= true; + end; + end; + if bo1 then begin + setlength(ar1,fcount); + int2:= 0; + for int1:= 0 to fcount -1 do begin + if fitems[int1] <> nil then begin + ar1[int2]:= fitems[int1]; + ar1[int2].fparentindex:= int2; + inc(int2); + end; + end; + setlength(ar1,int2); + fcount:= int2; + fitems:= ar1; + end; +end; + +procedure ttreelistitem.checkitems(const checkdelete: checktreelistitemprocty); +var + int1: integer; +begin + int1:= treeheight; + internalcheckitems(checkdelete); + countchange(int1,true); +end; + +function ttreelistitem.remove(const aindex: integer): ttreelistitem; +var + int1,int2: integer; +begin + checkindex(aindex); + int2:= treeheight; + result:= fitems[aindex]; + unsetitem(aindex); + int1:= (fcount-aindex-1)*sizeof(pointer); + if int1 > 0 then begin + system.move(fitems[aindex+1],fitems[aindex],int1); + end; + dec(fcount); + for int1:= aindex to fcount-1 do begin + fitems[int1].fparentindex:= int1; + end; + countchange(int2,not (ns1_destroying in result.fstate1)); +end; +{ +function comparetreelistitemcasesensitive(const l,r): integer; +begin + result:= 0; + if ns1_top in ttreelistitem(l).fstate1 then begin + dec(result); + end; + if ns1_top in ttreelistitem(r).fstate1 then begin + inc(result); + end; + if result = 0 then begin + result:= msestringcomp(ttreelistitem(l).caption,ttreelistitem(r).caption); + end; +end; + +function comparetreelistitemcaseinsensitive(const l,r): integer; +begin + result:= 0; + if ns1_top in ttreelistitem(l).fstate1 then begin + dec(result); + end; + if ns1_top in ttreelistitem(r).fstate1 then begin + inc(result); + end; + if result = 0 then begin + result:= msestringicomp(ttreelistitem(l).caption,ttreelistitem(r).caption); + end; +end; +} +function ttreelistitem.customcompare(const l: ttreelistitem; + const r: ttreelistitem): integer; +begin + result:= 0; + if ns1_top in l.fstate1 then begin + dec(result); + end; + if ns1_top in r.fstate1 then begin + inc(result); + end; +end; + +function ttreelistitem.comparecasesens(const l: ttreelistitem; + const r: ttreelistitem): integer; +begin + result:= l.compare(r,true); +end; + +function ttreelistitem.comparecaseinsens(const l: ttreelistitem; + const r: ttreelistitem): integer; +begin + result:= l.compare(r,false); +end; + +procedure ttreelistitem.sort(const casesensitive: boolean; + const recursive: boolean = false); +var + int1: integer; +{$ifndef FPC} + po1: ttreelistitemcomparefuncty; +{$endif} +begin + if ns1_customsort in fstate1 then begin + {$ifdef FPC} + mergesort(pointerarty(fitems),fcount,pointercomparemethodty(@customcompare)); + {$else} + po1:= self.customcompare; + mergesort(pointerarty(fitems),fcount,pointercomparemethodty(po1)); + {$endif} + end + else begin + if casesensitive then begin + {$ifdef FPC} + mergesort(pointerarty(fitems),fcount,pointercomparemethodty( + @comparecasesens)); + {$else} + po1:= self.comparecasesens; + mergesort(pointerarty(fitems),fcount,pointercomparemethodty(po1)); + {$endif} + end + else begin + {$ifdef FPC} + mergesort(pointerarty(fitems),fcount,pointercomparemethodty( + @comparecaseinsens)); + {$else} + po1:= self.comparecaseinsens; + mergesort(pointerarty(fitems),fcount,pointercomparemethodty(po1)); + {$endif} + end; + end; + for int1:= 0 to fcount-1 do begin + fitems[int1].fparentindex:= int1; + end; + if recursive then begin + for int1:= 0 to fcount-1 do begin + fitems[int1].sort(casesensitive,true); + end; + end; + checkaction(na_aftersort); + change; +end; + +procedure ttreelistitem.sort(const sortfunc: arraysortcomparety; + const recursive: boolean = false); +var + int1: integer; +begin + setlength(fitems,fcount); + sortarray(pointerarty(fitems),sortfunc); + for int1:= 0 to high(fitems) do begin + fitems[int1].fparentindex:= int1; + end; + if recursive then begin + for int1:= 0 to high(fitems) do begin + fitems[int1].sort(sortfunc,true); + end; + end; + checkaction(na_aftersort); + change; +end; + +procedure ttreelistitem.checksort; +begin + if ns_sorted in fstate then begin + sort(ns_casesensitive in fstate); + end; +end; + +procedure ttreelistitem.setcaption(const avalue: msestring); +begin + inherited; + if fparent <> nil then begin + fparent.checksort; + end; +end; + +procedure ttreelistitem.setowner(const aowner: tcustomitemlist); +var + int1: integer; +begin + inherited; + if (aowner = nil) or (ns_expanded in fstate) then begin + for int1:= 0 to fcount - 1 do begin + fitems[int1].setowner(aowner); + end; + end; + change(); +end; + +procedure ttreelistitem.updatechildcheckedstate; +var + node1: ttreelistitem; + int1: integer; +begin + node1:= fparent; + if ns_checked in fstate then begin + while (node1 <> nil) and not (ns1_childchecked in node1.fstate1) do begin + include(node1.fstate1,ns1_childchecked); + node1.change; + node1:= node1.fparent; + end; + end + else begin + if not (ns1_childchecked in fstate1) then begin + while (node1 <> nil) and (ns_showchildchecked in node1.fstate) and + (ns1_childchecked in node1.fstate1) do begin + with node1 do begin + for int1:= 0 to fcount-1 do begin + with fitems[int1] do begin + if (ns_checked in fstate) or (ns1_childchecked in fstate1) then begin + exit; + end; + end; + end; + exclude(fstate1,ns1_childchecked); + change; + if ns_checked in fstate then begin + exit; + end; + node1:= fparent; + end; + end; + end; + end; +end; + +procedure ttreelistitem.updatechildnotcheckedstate(); +var + node1: ttreelistitem; + i1: integer; +begin + if not (ns1_childnotchecked in fstate1) then begin + node1:= fparent; + if ns_checked in fstate then begin + while (node1 <> nil) and (ns_showchildnotchecked in node1.fstate) and + (ns1_childnotchecked in node1.fstate1) do begin + with node1 do begin + for i1:= 0 to fcount-1 do begin + with fitems[i1] do begin + if not (ns_checked in fstate) or + (ns1_childnotchecked in fstate1) then begin + exit; + end; + end; + end; + exclude(fstate1,ns1_childnotchecked); + change(); + node1:= fparent; + end; + end; + end + else begin + while (node1 <> nil) and (ns_showchildnotchecked in node1.fstate) and + not (ns1_childnotchecked in node1.fstate1) do begin + with node1 do begin + include(fstate1,ns1_childnotchecked); + change(); + node1:= fparent; + end; + end; + end; + end; +end; + +procedure ttreelistitem.updatechildcheckedtree; +var + int1: integer; +begin + updatechildcheckedstate; + for int1:= 0 to fcount-1 do begin + with fitems[int1] do begin + updatechildcheckedtree; + end; + end; +end; + +procedure ttreelistitem.updatechildnotcheckedtree; +var + int1: integer; +begin + updatechildnotcheckedstate; + for int1:= 0 to fcount-1 do begin + with fitems[int1] do begin + updatechildnotcheckedtree; + end; + end; +end; + +procedure ttreelistitem.doupdateparentnotcheckedstate(const aset: boolean); + + procedure doset(const anode: ttreelistitem); + var + int1: integer; + begin + with anode do begin + if not (ns1_parentnotchecked in fstate1) then begin + include(fstate1,ns1_parentnotchecked); + for int1:= 0 to fcount-1 do begin + doset(fitems[int1]); + end; + change(); + end; + end; + end; + + procedure doclear(const anode: ttreelistitem); + var + int1: integer; + begin + with anode do begin + exclude(fstate1,ns1_parentnotchecked); + for int1:= 0 to fcount-1 do begin + if ns_checked in fstate then begin + doclear(fitems[int1]); + end; + end; + change(); + end; + end; + +var + int1: integer; + +begin + if aset then begin + for int1:= 0 to fcount-1 do begin + doset(fitems[int1]); + end; + end + else begin + for int1:= 0 to fcount-1 do begin + doclear(fitems[int1]); + end; + end; +end; + +procedure ttreelistitem.updateparentnotcheckedstate(); +begin + doupdateparentnotcheckedstate(not (ns_checked in fstate) or + (ns1_parentnotchecked in fstate1)); +end; + +procedure ttreelistitem.updateparentnotcheckedtree(); + + procedure doupdate(const anode: ttreelistitem; avalue: boolean); + var + int1: integer; + begin + with anode do begin + if avalue then begin + include(fstate1,ns1_parentnotchecked); + end + else begin + exclude(fstate1,ns1_parentnotchecked); + end; + avalue:= avalue or not checked; + for int1:= 0 to fcount-1 do begin + doupdate(fitems[int1],avalue); + end; + end; + end; + +var + int1: integer; + bo1: boolean; +begin + bo1:= not (ns_checked in fstate); + for int1:= 0 to fcount-1 do begin + doupdate(fitems[int1],bo1); + end; +end; + + +procedure ttreelistitem.setchecked(const avalue: boolean); +begin + if avalue xor (ns_checked in fstate) then begin + inherited; + if (fowner <> nil) then begin + if (no_updatechildchecked in fowner.foptions) then begin + updatechildcheckedstate(); + end; + if (no_updatechildnotchecked in fowner.foptions) then begin + updatechildnotcheckedstate(); + end; + if (no_updateparentnotchecked in fowner.foptions) then begin + updateparentnotcheckedstate(); + end; + end; + end; +end; +{ +procedure ttreelistitem.updatedrawinfo(var ainfo: treeitemdrawinfoty); +begin + //dummy +end; +} +procedure ttreelistitem.drawimage(const acanvas: tcanvas; + var alayoutinfo: listitemlayoutinfoty); +var + po1,poend: ptreelistitem; + + function isnotlast(const aitem: ttreelistitem): boolean; + begin + if po1 = nil then begin + result:= aitem.fparentindex <> aitem.fparent.fcount - 1; + end + else begin + result:= po1 = poend; + while pchar(po1) < pchar(poend) do begin + if po1^.treelevel <= aitem.treelevel then begin + result:= po1^.treelevel = aitem.treelevel; + break; + end; + inc(po1); + end; + end; + end; + +var + box: treeitemboxty; + int1: integer; + bo1: boolean; + {$ifdef mswindows} +/// int2: integer; + {$endif} + item1: ttreelistitem; + seg: segmentty; + lines: segmentarty; + cellheight{,boxy}: integer; + nopaint: boolean; +// drawinfo: treeitemdrawinfoty; + +begin + nopaint:= (acanvas = nil) or alayoutinfo.variable.calcautocellsize; + alayoutinfo.variable.treelevelshift:= levelshift; + if not nopaint then begin //acanvas <> nil then begin + if (fcount = 0) and not (ns_subitems in fstate) and + not ((ns_drawemptyexpand in fstate) or + (no_drawemptyexpand in fowner.foptions)) then begin + if (ns_drawemptybox in fstate) or + (no_drawemptybox in fowner.foptions) then begin + box:= tib_empty; + end + else begin + box:= tib_none; + end; + end + else begin + if ns_expanded in fstate then begin + box:= tib_expanded;//integer(stg_boxexpanded); + end + else begin + box:= tib_expand;//integer(stg_boxexpand); + end; + end; + { + with drawinfo do begin + boxkind:= box; + boximageid:= treeitemboxids[box]; + flags:= treeitemdrawingflags; + end; + updatedrawinfo(drawinfo); + } + setlength(lines,ftreelevel+2); //last line can be doubled + horz. line + with fowner,alayoutinfo do begin + acanvas.move(makepoint(variable.treelevelshift,0)); + cellheight:= cellsize.cy; + seg.a.x:= (expandboxrect.x + expandboxrect.cx) div 2; + seg.a.y:= 0; + seg.b.x:= seg.a.x; + seg.b.y:= cellheight-1; + item1:= self; + int1:= 0; + po1:= nil; + if (fowner <> nil) and fowner.frearanged then begin + po1:= ptreelistitem(fowner.datapo); + poend:= @ppointeraty(po1)[fowner.count-1]; + po1:= @ppointeraty(po1)[variable.rowindex + 1]; + end; + bo1:= (fparent = nil) or isnotlast(self); + //bo1 not used if parent = nil + while item1.fparent <> nil do begin + if (int1 = 0) or isnotlast(item1) then begin + lines[int1]:= seg; + inc(int1); + end; + dec(seg.a.x,flevelstep); + seg.b.x:= seg.a.x; + item1:= item1.fparent; + end; + if int1 > 0 then begin + if bo1 then begin +// if fparentindex <> fparent.fcount - 1 then begin + if box <> tib_none then begin + lines[0].b.y:= expandboxrect.y-1; //top of splited vert. + lines[int1]:= lines[0]; + with lines[int1] do begin + a.y:= b.y + expandboxrect.cy; //bottom of splited vert. + b.y:= cellheight-1; + end; + inc(int1); + end; + end + else begin //last vert. + if box <> tib_none then begin + lines[0].b.y:= expandboxrect.y-1; //to top of box + end + else begin + lines[0].b.y:= cellheight div 2; + end; + end; + with lines[int1] do begin + if box <> tib_none then begin + dec(int1); + end + else begin + a.y:= cellheight div 2; + b.y:= a.y; + a.x:= lines[0].a.x + 1; + b.x:= checkboxrect.x - 1; //horizontal line + if b.x < a.x then begin + dec(int1); + end; + end; + end; + setlength(lines,int1+1); + if no_solidline in options then begin + acanvas.drawlinesegments(lines,variable.colorline); + end + else begin + drawdottedlinesegments(acanvas,lines,variable.colorline); + end; + end; + if box <> tib_none then begin + stockobjects.glyphs.paint(acanvas,boxids[box],expandboxrect, + [al_xcentered,al_ycentered],variable.colorglyph, + cl_default,cl_default,variable.glyphversion); + end; + end; + end; + inherited; +end; + +procedure ttreelistitem.setupeditor(const editor: tinplaceedit; + const font: tfont; const notext: boolean); +var +// int1: integer; + info1: drawtextinfoty; + po1: plistitemlayoutinfoty; +begin + if fowner <> nil then begin + po1:= fowner.fintf.getlayoutinfo(nil); + po1^.variable.calcautocellsize:= true; + drawimage(editor.getfontcanvas(),po1^); //calc image extend + with po1^ do begin + info1.font:= font; + with info1 do begin + tabulators:= nil; + dest:= captioninnerrect; + inc(dest.cx,variable.extra.caption.cx); + inc(dest.cy,variable.extra.caption.cy); + clip:= captionrect; + inc(clip.cx,variable.extra.caption.cx); + inc(clip.cy,variable.extra.caption.cy); + if not notext then begin + text.text:= fcaption; + end + else begin + text.text:= editor.text; + end; + flags:= textflags; + inc(dest.x,variable.treelevelshift); + inc(clip.x,variable.treelevelshift); + { + int1:= levelshift; + inc(dest.x,int1); + dec(dest.cx,int1); + inc(clip.x,int1); + dec(clip.cx,int1); + } + updatecaption(editor.getfontcanvas,po1^,info1); + editor.setup(text.text,editor.curindex,false,dest,clip,nil,nil,font); + end; + end; + end; +end; + +class procedure ttreelistitem.calcitemlayout(const asize: sizety; + const ainnerframe: framety; const list: tcustomitemlist; + var info: listitemlayoutinfoty); +var + boxdist: integer; +begin +// info.colorline:= cl_gray; + inherited; + boxdist:= boxsize + 2; + with info.captionrect do begin + inc(x,boxdist); + dec(cx,boxdist); + end; + with info.captioninnerrect do begin + inc(x,boxdist); + dec(cx,boxdist); + end; + with info.checkboxrect do begin + inc(x,boxdist); + end; + with info.checkboxinnerrect do begin + inc(x,boxdist); + end; + inc(info.imagerect.x,boxdist); + with info.expandboxrect do begin + x:= 0; + y:= (asize.cy - boxsize) div 2; + cx:= boxsize; + cy:= boxsize; + end; + info.minsize.cx:= info.minsize.cx + boxdist; + if info.minsize.cy < boxsize then begin + info.minsize.cy:= boxsize; + end; +end; + +procedure ttreelistitem.updatecellzone(const pos: pointty; var zone: cellzonety); +var + po1: pointty; +begin + po1:= pos; + dec(po1.x,levelshift); + inherited updatecellzone(po1,zone); +end; + +procedure ttreelistitem.mouseevent(var info: mouseeventinfoty); +begin + with info do begin + dec(pos.x,levelshift); + try + inherited; + if (eventkind = ek_buttonpress) and + (shiftstate * keyshiftstatesmask = []) and (button = mb_left) and + pointinrect(pos,fowner.fintf.getlayoutinfo(nil)^.expandboxrect) then begin + expanded:= not expanded; + include(eventstate,es_processed); + end; + finally + inc(pos.x,levelshift); + end; + end; +end; + +function ttreelistitem.getexpanded: boolean; +begin + result:= ns_expanded in fstate; +end; + +function ttreelistitem.getrootexpanded: boolean; +begin + result:= fowner <> nil; +end; + +procedure ttreelistitem.setrootexpanded(const avalue: boolean); +var + n1,n2: ttreelistitem; + bo1: boolean; +begin + n1:= self.fparent; + if avalue then begin + bo1:= false; + n2:= self; + while n2 <> nil do begin //check if tree has itemlist + bo1:= n2.fowner <> nil; + if bo1 then begin + break; + end; + n2:= n2.fparent; + end; + while bo1 and (n1 <> nil) do begin + bo1:= n1.fowner = nil; //stop after first expanded + n1.expanded:= true; + n1:= n1.fparent; + end; + end + else begin + while (n1 <> nil) and (n1.fowner <> nil) do begin + n1.expanded:= false; + n1:= n1.fparent; + end; + end; +end; + +function ttreelistitem.getsubitems: boolean; +begin + result:= ns_subitems in fstate; +end; + +procedure ttreelistitem.setsubitems(const avalue: boolean); +begin + if avalue then begin + state:= state + [ns_subitems]; + end + else begin + state:= state - [ns_subitems]; + end; +end; + +procedure ttreelistitem.statechanged; +begin + include(fstate1,ns1_statechanged); + if ns1_rootchange in fstate1 then begin + include(rootnode.fstate1,ns1_statechanged); + end; +end; + +procedure ttreelistitem.setexpanded(const Value: boolean); +begin + if value then begin + if not (ns_expanded in fstate) then begin + if checkaction(na_expand) then begin + include(fstate,ns_expanded); + statechanged; + end; + end; + end + else begin + if ns_expanded in fstate then begin + if checkaction(na_collapse) then begin + exclude(fstate,ns_expanded); + statechanged; + end; + end; + end; +end; + +procedure ttreelistitem.checkindex(const aindex: integer); +begin + if (aIndex < 0) or (aIndex >= FCount) then begin + tlist.Error(SListIndexError, aIndex); + end; +end; + +procedure ttreelistitem.settreelevel(const value: integer); +var + int1: integer; +begin + ftreelevel:= value; + for int1:= 0 to fcount - 1 do begin + fitems[int1].settreelevel(value+1); + end; +end; + +function ttreelistitem.levelshift: integer; +begin + if fowner <> nil then begin + result:= ftreelevel*fowner.flevelstep; + end + else begin + result:= 0; + end; +end; + +function ttreelistitem.treeheight: integer; //total hight of children +var + int1: integer; +begin + result:= 0; + for int1:= 0 to fcount - 1 do begin + inc(result); + with ttreelistitem(fitems[int1]) do begin + if expanded then begin + result:= result + treeheight; + end; + end; + end; +end; + +function ttreelistitem.rowheight: integer; //total needed grid rows +begin + if expanded then begin + result:= treeheight + 1; + end + else begin + result:= 1; + end; +end; + +function ttreelistitem.finditembycaption(const acaption: msestring; + const acasesensitive: boolean = false; + const aexpand: boolean = false): ttreelistitem; +var + int1: integer; + compfunc: function(const a,b: msestring): integer; +begin + result:= nil; + if acasesensitive then begin + compfunc:= {$ifdef FPC}@{$endif}msecomparestr; + end + else begin + compfunc:= {$ifdef FPC}@{$endif}msecomparetext; + end; + for int1:= 0 to fcount - 1 do begin + if compfunc(acaption,fitems[int1].fcaption) = 0 then begin + result:= fitems[int1]; + break; + end; + end; + if aexpand and (result <> nil) then begin + result.rootexpanded:= true; + end; +end; + +function ttreelistitem.finditembycaption(const acaption: msestring; + var dest: ttreelistitem): boolean; +var + int1: integer; +begin + result:= false; + for int1:= 0 to fcount-1 do begin + if fitems[int1].fcaption = acaption then begin + dest:= fitems[int1]; + result:= true; + end; + end; +end; + +function ttreelistitem.finditembycaption(const acaption: lmsestringty; + const aexpand: boolean = false): ttreelistitem; +var + po1,po2: pmsechar; + int1,int2: integer; +label + nextitem; +begin + result:= nil; + for int1:= 0 to fcount - 1 do begin + with fitems[int1] do begin + if length(fcaption) = acaption.len then begin + po1:= pointer(fcaption); + po2:= acaption.po; + for int2:= 0 to acaption.len-1 do begin + if (po1+int2)^ <> (po2+int2)^ then begin + goto nextitem; + end; + end; + result:= self.fitems[int1]; + end; + end; +nextitem: + end; + if aexpand and (result <> nil) then begin + result.rootexpanded:= true; + end; +end; + +function ttreelistitem.finditembycaption(const acaptions: msestringarty; + const acasesensitive: boolean = false; + const aexpand: boolean = false; + const apartial: boolean = false): ttreelistitem; +var + int1: integer; + it1,it2: ttreelistitem; +begin + it1:= self; + it2:= it1; + for int1:= 0 to high(acaptions) do begin + it1:= it1.finditembycaption(acaptions[int1],acasesensitive); + if it1 = nil then begin + if apartial then begin + it1:= it2; + end; + break; + it2:= it1; + end; + end; + if aexpand and (it1 <> nil) then begin + it1.rootexpanded:= true; + end; + result:= it1; +end; + +function ttreelistitem.isroot: boolean; +begin + result:= fparent = nil; +end; + +function ttreelistitem.issinglerootrow: boolean; +begin + result:= (treelevel = 0) and (not expanded or (count = 0)); +end; + +function ttreelistitem.nextnode: ttreelistitem; +var + n1: ttreelistitem; +begin + result:= nil; + n1:= self; + while n1.fparent <> nil do begin + if (n1.fparentindex < n1.fparent.fcount-1) then begin + result:= n1.fparent.fitems[n1.fparentindex+1]; + break; + end; + n1:= n1.fparent; + end; +end; + +function ttreelistitem.nextnodeparent: ttreelistitem; +begin + result:= nextnode; + if result <> nil then begin + result:= result.fparent; + end; +end; + +function ttreelistitem.checkdescendent(node: ttreelistitem): boolean; + //true if node is descendent or self +begin + result:= false; + while node <> nil do begin + if node = self then begin + result:= true; + break; + end; + node:= node.parent; + end; +end; + +function ttreelistitem.checkancestor(node: ttreelistitem): boolean; + //true if node is ancestor or self +begin + result:= (node <> nil) and node.checkdescendent(self); +end; + +function ttreelistitem.parentindex: integer; +begin + if fparent <> nil then begin + result:= fparentindex; + end + else begin + result:= -1; + end; +end; + +function ttreelistitem.rootpath: treelistitemarty; +var + int1: integer; + item: ttreelistitem; +begin + setlength(result,ftreelevel+1); + int1:= ftreelevel; + item:= self; + while int1 >= 0 do begin + result[int1]:= item; + item:= item.fparent; + dec(int1); + end; +end; + +function ttreelistitem.rootnode: ttreelistitem; +begin + result:= self; + while result.fparent <> nil do begin + result:= result.fparent; + end; +end; + +function ttreelistitem.rootcaptions: msestringarty; +var + int1: integer; + item: ttreelistitem; +begin + setlength(result,ftreelevel+1); + item:= self; + for int1:= high(result) downto 0 do begin + result[int1]:= item.fcaption; + item:= item.fparent; + end; +end; + +function ttreelistitem.rootcaptions(const aowner: tcustomitemlist): msestringarty; +var + int1,int2: integer; + item: ttreelistitem; +begin + int2:= ftreelevel+1; + setlength(result,int2); //max + item:= self; + for int1:= high(result) downto 0 do begin + if item.fowner <> aowner then begin + break; + end; + result[int1]:= item.fcaption; + item:= item.fparent; + dec(int2); + end; + if int2 <> 0 then begin + int1:= (length(result)-int2); + system.move(result[int2],result[0],int1*sizeof(pointer)); + setlength(pointerarty(result),int1); + end; +end; + +procedure ttreelistitem.objectevent(const sender: tobject; + const event: objecteventty); +var + int1: integer; +begin + for int1:= 0 to fcount - 1 do begin + fitems[int1].objectevent(sender,event); + end; + inherited; +end; + +procedure ttreelistitem.statreadsubnode(const reader: tstatreader; + var anode: ttreelistitem); +begin + if fowner <> nil then begin + fowner.statreadtreeitem(reader,self,anode); + end + else begin + if anode = nil then begin + anode:= createsubnode; + end; + end; +end; + +procedure ttreelistitem.dostatread(const reader: tstatreader); +var + int1{,int2}: integer; + node1: ttreelistitem; + bo1: boolean; +begin + inherited; + if not (ns_nosubnodestat in fstate) then begin + clear; + int1:= reader.readinteger('c',-1,0,bigint); + if int1 > 0 then begin + bo1:= ns_sorted in fstate; + exclude(fstate,ns_sorted); + for int1:= 0 to int1 - 1 do begin + if not reader.beginlist then begin + break; + end; + node1:= nil; + statreadsubnode(reader,node1); + if node1 <> nil then begin + dosetitems(inccount,node1); + node1.dostatread(reader); + end; + reader.endlist; + end; + if bo1 then begin + include(fstate,ns_sorted); + checksort; + end; + countchange(0,true); + end; + end; + exclude(fstate1,ns1_statechanged); +end; + +procedure ttreelistitem.dostatwrite(const writer: tstatwriter); +var + int1: integer; +begin + inherited; + if (fcount > 0) and not (ns_nosubnodestat in fstate) then begin + writer.writeinteger('c',fcount); + for int1:= 0 to fcount - 1 do begin + writer.beginlist; + fitems[int1].dostatwrite(writer); + writer.endlist; + end; + end; +end; + +function ttreelistitem.isstatechanged: boolean; +begin + result:= ns1_statechanged in fstate1; +end; + +function ttreelistitem.candrag: boolean; +begin + result:= ns1_candrag in fstate1; +end; + +function ttreelistitem.candrop(const source: ttreelistitem): boolean; +begin + result:= false; +end; + +procedure ttreelistitem.releaseowner; +var + int1: integer; +begin + for int1:= 0 to fcount - 1 do begin + fitems[int1].releaseowner; + end; + inherited; +end; + +procedure ttreelistitem.releasechildren(); +begin + include(fstate1,ns1_noowner); + clear(); +end; + +function ttreelistitem.parentorself: ttreelistitem; +begin + result:= fparent; + if fparent = nil then begin + result:= self; + end; +end; + +function ttreelistitem.islastnode: boolean; +begin + result:= (fparent = nil) or (fparentindex = fparent.fcount-1); +end; + +function ttreelistitem.findsibling( + const asibling: ttreelistitem): ttreelistitem; +var + n1: ttreelistitem; +begin + result:= nil; +// if asibling.fparent <> nil then begin + n1:= self; + while n1 <> nil do begin + if n1.fparent = asibling.fparent then begin + result:= n1; + break; + end; + n1:= n1.fparent; + end; +// end; +end; + +function ttreelistitem.treechecked: boolean; +begin + result:= (ns_checked in fstate) and not (ns1_parentnotchecked in fstate1); +end; + +{ ttreenode } + +destructor ttreenode.destroy; +begin + clear; + inherited; +end; + +procedure ttreenode.clear; +var + int1: integer; +begin + for int1:= 0 to fcount - 1 do begin + fitems[int1].Free; + end; + fcount:= 0; + fitems:= nil; +end; + +function ttreenode.add(const anode: ttreenode): integer; +begin + result:= fcount; + setcount(fcount + 1); + items[fcount-1]:= anode; +end; + +procedure ttreenode.setcount(const value: integer); +begin + if high(fitems) <= value then begin + setlength(fitems,(value*8) div 7 + 32); + end; + fcount:= value; +end; + +function ttreenode.getitems(const index: integer): ttreenode; +begin + checkindex(index); + result:= fitems[index]; +end; + +procedure ttreenode.setitems(const index: integer; const Value: ttreenode); +begin + checkindex(index); + fitems[index].Free; + fitems[index]:= value; + value.fparent:= self; +end; + +procedure ttreenode.checkindex(const index: integer); +begin + if (index < 0) or (index >= fcount) then begin + tlist.error(slistindexerror,index); + end; +end; + +procedure ttreenode.iterate(const event: nodeeventty); +var + int1: integer; +begin + event(self); + for int1:= 0 to fcount - 1 do begin + fitems[int1].iterate(event); + end; +end; + +procedure ttreenode.convertflat(const listitem: ttreelistitem; + const filterfunc: treenodefilterfuncty); +var + item1: ttreelistitem; + int1: integer; +begin + if assigned(filterfunc) and not filterfunc(self) then begin + exit; + end; + item1:= listitemclass.create; + nodetoitem(item1); + listitem.add(item1); + for int1:= 0 to fcount - 1 do begin + fitems[int1].convertflat(listitem,filterfunc); + end; +end; + +function ttreenode.converttree(const filterfunc: treenodefilterfuncty): ttreelistitem; +var + int1: integer; +begin + if assigned(filterfunc) and not filterfunc(self) then begin + result:= nil; + end + else begin + result:= listitemclass.create; + nodetoitem(result); + for int1:= 0 to fcount - 1 do begin + result.add(fitems[int1].converttree(filterfunc)); + end; + end; +end; + +function ttreenode.converttotreelistitem(flat: boolean = false; withrootnode: boolean = false; + filterfunc: treenodefilterfuncty = nil): ttreelistitem; +var + int1: integer; +begin + result:= listitemclass.create; //container + if withrootnode then begin + if flat then begin + convertflat(result,filterfunc); + end + else begin + result.add(converttree(filterfunc)); + end; + end + else begin + for int1:= 0 to fcount - 1 do begin + if flat then begin + fitems[int1].convertflat(result,filterfunc); + end + else begin + result.add(fitems[int1].converttree(filterfunc)); + end; + end; + end; +end; + +{ +procedure ttreenode.assigntotreelistitem(const listitem: ttreelistitem); +var + int1: integer; + ar1: treelistitemarty; +begin + nodetoitem(listitem); + listitem.clear; + if fcount > 0 then begin + setlength(ar1,fcount); + for int1:= 0 to fcount - 1 do begin + ar1[int1]:= fitems[int1].listitemclass.create; + end; + listitem.add(ar1); + for int1:= 0 to fcount - 1 do begin + fitems[int1].assigntotreelistitem(ar1[int1]); + end; + end; +end; + +procedure ttreenode.assigntreelistitem(const listitem: ttreelistitem); +var + int1: integer; + ar1: treenodearty; +begin + itemtonode(listitem); + clear; + if listitem.count > 0 then begin + setlength(ar1,listitem.count); + for int1:= 0 to listitem.count - 1 do begin + add(treenodeclass.create); + end; + for int1:= 0 to fcount - 1 do begin + fitems[int1].assigntotreelistitem(listitem[int1]); + end; + end; +end; +} +procedure ttreenode.nodetoitem(const listitem: ttreelistitem); +begin + //dummy +end; +{ +procedure ttreenode.itemtonode(const listitem: ttreelistitem); +begin + //dummy +end; +} +function ttreenode.listitemclass: treelistitemclassty; +begin + result:= ttreelistitem; +end; + +function ttreenode.treenodeclass: treenodeclassty; +begin + result:= ttreenode; +end; + +function ttreenode.count: integer; +begin + result:= fcount; +end; + +end. diff --git a/mseide-msegui/lib/common/editwidgets/msedropdownlist.pas b/mseide-msegui/lib/common/editwidgets/msedropdownlist.pas new file mode 100644 index 0000000..f1b0600 --- /dev/null +++ b/mseide-msegui/lib/common/editwidgets/msedropdownlist.pas @@ -0,0 +1,2998 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msedropdownlist; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + mseclasses,mseedit,mseevent,mseglob,mseguiglob,msegrids,msedatalist,msegui, + mseinplaceedit,msearrayprops,classes,mclasses,msegraphics,msedrawtext, + msegraphutils,mseassistiveclient, + msetimer,{mseforms,}msetypes,msestrings,msestockobjects,msescrollbar, + msekeyboard,msegridsglob,mseeditglob,msestat,msebitmap; + +const + defaultdropdowncoloptions = [co_fill,co_readonly,co_focusselect, + co_mousemovefocus,co_rowselect]; + defaultdropdowncoltextflags = defaultcoltextflags + [tf_noselect]; + mouseautoscrollheight = 4; + dropdownitemselectedevent = 345; + +type + + dropdownlistoptionty = (dlo_casesensitive,dlo_posinsensitive,dlo_livefilter); + dropdownlistoptionsty = set of dropdownlistoptionty; + + dropdownliststatety = (dls_firstmousemoved,dls_mousemoved,dls_scrollup); + dropdownliststatesty = set of dropdownliststatety; + + dropdowneditoptionty = (deo_selectonly,deo_forceselect, + deo_autodropdown, + deo_keydropdown,//shift down starts dropdown + deo_modifiedbeforedropdown, + //edit.modified called before dropdown + deo_casesensitive,deo_posinsensitive, + deo_livefilter, + deo_customfilter, //do not hide rows + deo_sorted,deo_disabled,deo_autosavehistory, + deo_cliphint,deo_right,deo_colsizing,deo_savestate); + dropdowneditoptionsty = set of dropdowneditoptionty; + +const + defaultdropdownoptionsedit = [deo_keydropdown]; + defaultautodropdownoptions = defaultdropdownoptionsedit + [deo_autodropdown]; +type + tcustomdropdownlistcontroller = class; + + tdropdowncolfont = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + tdropdowncolfontselect = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + tdropdowndata = class(tmsestringdatalist) + end; + + tdropdowndatacols = class(townedpersistentarrayprop) + private + fupdating1: integer; + fonitemchange: indexeventty; + function getitems(const index: integer): tdropdowndata; + protected + function maxrowcount: integer; + function minrowcount: integer; + procedure createitem(const index: integer; var item: tpersistent); override; + procedure itemchanged(const sender: tdatalist; const index: integer); + //sender = nil -> col undefined + procedure checkrowindex(const aindex: integer); + procedure setrowcount(const avalue: integer); + public + constructor create(const aowner: tcustomdropdownlistcontroller); reintroduce; + class function getitemclasstype: persistentclassty; override; + procedure beginupdate; + procedure endupdate; + procedure clear; + function addrow(const aitems: array of msestring): integer; + //returns itemindex + procedure insertrow(const aindex: integer; const aitems: array of msestring); + procedure deleterow(const aindex: integer); + function getrow(const aindex: integer): msestringarty; + property rowcount: integer read maxrowcount write setrowcount; + property items[const index: integer]: tdropdowndata read getitems; default; + end; + + tdropdowncol = class(tdropdowndata) + private + fwidth: integer; + foptions: coloptionsty; + flinewidth: integer; + flinecolor: colorty; + ftextflags: textflagsty; + fcolor: colorty; + fcolorselect: colorty; +// ffontcolorselect: colorty; + fcaption: msestring; + fpasswordchar: msechar; + ffont: tdropdowncolfont; + ffontselect: tdropdowncolfontselect; + fframetemplate: tframecomp; + ffacetemplate: tfacecomp; + procedure setoptions(const avalue: coloptionsty); + function getfont: tdropdowncolfont; + procedure setfont(const avalue: tdropdowncolfont); + function getfontselect: tdropdowncolfontselect; + procedure setfontselect(const avalue: tdropdowncolfontselect); + procedure readfontcolorselect(reader: treader); + procedure setframetemplate(const avalue: tframecomp); + procedure setfacetemplate(const avalue: tfacecomp); + protected + fowner: tobject; +// fdata: tdropdowndata; //for tselector + procedure defineproperties(filer: tfiler); override; + public + constructor create(const aowner: tcustomdropdownlistcontroller); reintroduce; + destructor destroy(); override; + procedure createfont(); + procedure createfontselect(); + published + property width: integer read fwidth write fwidth default griddefaultcolwidth; + property options: coloptionsty read foptions write setoptions + default defaultdropdowncoloptions; + property textflags: textflagsty read ftextflags write ftextflags + default defaultdropdowncoltextflags; + property passwordchar: msechar read fpasswordchar write fpasswordchar + default #0; + property linewidth: integer read flinewidth write flinewidth default 0; + property linecolor: colorty read flinecolor write flinecolor default cl_gray; + property color: colorty read fcolor write fcolor default cl_default; + property colorselect: colorty read fcolorselect write fcolorselect + default cl_default; +// property fontcolorselect: colorty read ffontcolorselect +// write ffontcolorselect default cl_default; + property font: tdropdowncolfont read getfont write setfont; + property fontselect: tdropdowncolfontselect read getfontselect + write setfontselect; + property frametemplate: tframecomp read fframetemplate + write setframetemplate; + property facetemplate: tfacecomp read ffacetemplate + write setfacetemplate; + property caption: msestring read fcaption write fcaption; + end; + + dropdowncolclassty = class of tdropdowncol; + + tdropdownfont = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + tdropdownfontselect = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + tdropdowncols = class(tdropdowndatacols) + private + fnostreaming: boolean; +// maxrowcount: integer; + fwidth: integer; + foptions: coloptionsty; + ftextflags: textflagsty; + flinewidth: integer; + flinecolor: colorty; + fcolor: colorty; + fcolorselect: colorty; +// ffontcolorselect: colorty; + ffont: tdropdownfont; + ffontselect: tdropdownfontselect; + fframetemplate: tframecomp; + ffacetemplate: tfacecomp; + function getitems(const index: integer): tdropdowncol; + procedure setnostreaming(const avalue: boolean); + procedure setwidth(const avalue: integer); + procedure setoptions(const avalue: coloptionsty); + procedure settextflags(const avalue: textflagsty); + procedure setlinewidth(const avalue: integer); + procedure setlinecolor(const avalue: colorty); + procedure setcolor(const avalue: colorty); + procedure setcolorselect(const avalue: colorty); +// procedure setfontcolorselect(const avalue: colorty); + function getfont: tdropdownfont; + procedure setfont(const avalue: tdropdownfont); + function getfontselect: tdropdownfontselect; + procedure setfontselect(const avalue: tdropdownfontselect); + procedure readfontcolorselect(reader: treader); + procedure setframetemplate(const avalue: tframecomp); + procedure setfacetemplate(const avalue: tfacecomp); + protected + fdatacols: tdropdowndatacols; //for tselector + fitemindex: integer; + fkeyvalue64: int64; + fkeyvalue: msestring; + procedure setcount1(acount: integer; doinit: boolean); override; + procedure createitem(const index: integer; var item: tpersistent); override; + function getcolclass: dropdowncolclassty; virtual; + procedure defineproperties(filer: tfiler); override; + public + constructor create(const aowner: tcustomdropdownlistcontroller); reintroduce; + destructor destroy(); override; + class function getitemclasstype: persistentclassty; override; + procedure createfont(); + procedure createfontselect(); + property nostreaming: boolean read fnostreaming + write setnostreaming; + property onitemchange: indexeventty read fonitemchange write fonitemchange; + property items[const index: integer]: tdropdowncol read getitems; default; + published + property width: integer read fwidth write setwidth default griddefaultcolwidth; + property options: coloptionsty read foptions write setoptions + default defaultdropdowncoloptions; + property textflags: textflagsty read ftextflags write settextflags + default defaultdropdowncoltextflags; + property linewidth: integer read flinewidth write setlinewidth default 0; + property linecolor: colorty read flinecolor write setlinecolor default cl_gray; + property color: colorty read fcolor write setcolor default cl_default; + property colorselect: colorty read fcolorselect write setcolorselect + default cl_default; +// property fontcolorselect: colorty read ffontcolorselect +// write setfontcolorselect default cl_default; + property font: tdropdownfont read getfont write setfont; + property fontselect: tdropdownfontselect read getfontselect + write setfontselect; + property frametemplate: tframecomp read fframetemplate + write setframetemplate; + property facetemplate: tfacecomp read ffacetemplate + write setfacetemplate; + end; + + dropdowncolsclassty = class of tdropdowncols; + + idropdown = interface(inullinterface) + function getvalueempty: integer; + function getwidget: twidget; + function geteditor: tinplaceedit; + function getedited: boolean; + procedure modified; + procedure dobeforedropdown; + procedure doafterclosedropdown; + function setdropdowntext(const avalue: msestring; const docheckvalue: boolean; + const canceled: boolean; const akey: keyty): boolean; //true if accepted + procedure buttonaction(var action: buttonactionty; const buttonindex: integer); + end; + + idropdownlist = interface(idropdown) + function getdropdownitems: tdropdowndatacols; + //nil -> dropdowncontroller.fdropdownitems + procedure imagelistchanged; + end; + + idropdownwidget = interface(idropdown) + procedure createdropdownwidget(const atext: msestring; out awidget: twidget); + function getdropdowntext(const awidget: twidget): msestring; + end; + + idropdowncontroller = interface(inullinterface) + function getwidget: twidget; + procedure updatedropdownpos(const arect: rectty); + end; + + idropdownlistcontroller = interface(idropdowncontroller) + procedure dropdownactivated; + procedure dropdowndeactivated; + procedure itemselected(const index: integer; const akey: keyty); + procedure dropdownkeydown(var info: keyeventinfoty); + end; + + tdropdownstringcol = class(tstringcol) + protected + function createdatalist: tdatalist; override; + public + destructor destroy; override; + constructor create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); override; + end; + + titemselectedevent = class(tcomponentevent) + private + frow: integer; + public + constructor create(const dest: tmsecomponent; const arow: integer); + end; + + tdropdownfixcol = class(tfixcol) + protected + fcontroller: tcustomdropdownlistcontroller; + public + constructor create(const agrid: tcustomgrid; + const aowner: tgridarrayprop; + const acontroller: tcustomdropdownlistcontroller); reintroduce; virtual; + end; + dropdownfixcolclassty = class of tdropdownfixcol; + +type + tdropdownlist = class(tcustomstringgrid) + private + foptions1: dropdownlistoptionsty; + fdropdownstate: dropdownliststatesty; + ffirstmousepos: pointty; + frepeater: tsimpletimer; + ffiltertext: msestring; + fselectedindex: integer; + fupdatelayoutcount: int32; + procedure canceldropdown; + procedure killrepeater; + procedure startrepeater(up: boolean); + procedure itemselected(const index: integer; const akey: keyty); + protected + fcontroller: tcustomdropdownlistcontroller; + fdropdownrowcount: integer; + function getassistiveflags(): assistiveflagsty override; + procedure setfiltertext(const Value: msestring); virtual; + procedure updatewindowinfo(var info: windowinfoty); override; + procedure createdatacol(const index: integer; out item: tdatacol); override; + procedure dokeydown(var info: keyeventinfoty); override; + procedure clientmouseevent(var info: mouseeventinfoty); override; + procedure mouseevent(var info: mouseeventinfoty); override; + procedure doactivate; override; + procedure dodeactivate; override; + procedure docellevent(var info: celleventinfoty); override; + function getkeystring(const aindex: integer): msestring; + function getkeystringnohidden(const aindex: integer): msestring; + function locate(const filter: msestring): boolean; virtual; + function updatevisiblerows(): integer; virtual; + //returns first visible row + procedure dorepeat(const sender: tobject); + procedure initcols(const acols: tdropdowncols); virtual; + procedure updatelayout; override; + function dropdownheight: integer; virtual; + procedure setactiveitem(const aitemindex: integer); virtual; + function getassistiveparent(): iassistiveclient override; + public + constructor create(const acontroller: tcustomdropdownlistcontroller; + const acols: tdropdowncols; + const afixcolclass: dropdownfixcolclassty); reintroduce; + destructor destroy; override; + procedure show(awidth: integer; const arowcount: integer; + var aitemindex: integer; afiltertext: msestring); reintroduce; + property filtertext: msestring read ffiltertext write setfiltertext; + property options: dropdownlistoptionsty read foptions1 write foptions1; + end; + + tdropdownbutton = class(tstockglyphframebutton) + public + constructor create(aowner: tobject); override; + published + property imagenr default ord(stg_arrowdownsmall); + end; + + tcustomdropdownbuttonframe = class(tcustombuttonframe) + private + freadonly: boolean; + procedure setreadonly(const Value: boolean); + protected + procedure updatestate() override; + function getbuttonclass: framebuttonclassty override; + function getbutton: tdropdownbutton; + procedure setbutton(const avalue: tdropdownbutton); + public + constructor create(const aintf: icaptionframe; + const buttonintf: ibutton); override; + procedure updatedropdownoptions(const avalue: dropdowneditoptionsty); + property readonly: boolean read freadonly write setreadonly default false; + property button: tdropdownbutton read getbutton write setbutton; + end; + + dropdownbuttonframeclassty = class of tcustomdropdownbuttonframe; + + tdropdownbuttonframe = class(tcustomdropdownbuttonframe) + published + property button; + end; + + tdropdownmultibuttonframe = class(tdropdownbuttonframe) + published + property buttons; + property activebutton; + end; + + dropdowncontrollerstatety = (dcs_forcecaret,dcs_itemselecting,dcs_isstringkey); + dropdowncontrollerstatesty = set of dropdowncontrollerstatety; + + tcustomdropdowncontroller = class(teventpersistent,ibutton,ievent, + idropdowncontroller,idataeditcontroller) + private + fframetemplate: tframecomp; + ffacetemplate: tfacecomp; + procedure setframetemplate(const avalue: tframecomp); + procedure setfacetemplate(const avalue: tfacecomp); + protected + fowner: twidget; + fdataselected: boolean; + fcolor: colorty; + fcolorclient: colorty; + fdropdowncount: integer; + fselectkey: keyty; + fintf: idropdown; + foptions: dropdowneditoptionsty; + fstate: dropdowncontrollerstatesty; +// fforcecaret: boolean; + procedure applicationactivechanged(const avalue: boolean); virtual; + function getbuttonframeclass: dropdownbuttonframeclassty; virtual; + procedure updatedropdownbounds(var arect: rectty); virtual; + procedure updatedropdownpos(const arect: rectty); + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + procedure setoptions(const Value: dropdowneditoptionsty); virtual; + function getdropdownwidget: twidget; virtual; + function getwidget: twidget; + procedure dobeforedropdown; virtual; + procedure doafterclosedropdown; virtual; + procedure internaldropdown; virtual; + function setdropdowntext(const avalue: msestring; + const docheckvalue: boolean; const canceled: boolean; + const akey: keyty): boolean; + //true if selected + function candropdown: boolean; virtual; + procedure selectnone(const akey: keyty); virtual; + function isloading: boolean; + procedure resetselection; virtual; + function componentstate: tcomponentstate; + //ibutton + procedure buttonaction(var action: buttonactionty; + const buttonindex: integer); + + //idataeditcontroller + procedure mouseevent(var info: mouseeventinfoty); + procedure dokeydown(var info: keyeventinfoty); + procedure internalcreateframe; virtual; + procedure updatereadonlystate; + procedure domousewheelevent(var info: mousewheeleventinfoty); + procedure editnotification(var info: editnotificationinfoty); virtual; + public + constructor create(const intf: idropdown); reintroduce; + destructor destroy; override; + function hasdropdown(): boolean; + property dropdownwidget: twidget read getdropdownwidget; + procedure dostatread(const reader: tstatreader); virtual; + procedure dostatwrite(const writer: tstatwriter); virtual; + procedure dropdown; virtual; + procedure canceldropdown; + procedure dropdownactivated; + procedure dropdowndeactivated; + function dataselected: boolean; + property options: dropdowneditoptionsty read foptions write setoptions + default defaultdropdownoptionsedit; + published + property color: colorty read fcolor write fcolor default cl_default; + property colorclient: colorty read fcolorclient write fcolorclient + default cl_default; + property frametemplate: tframecomp read fframetemplate + write setframetemplate; + property facetemplate: tfacecomp read ffacetemplate + write setfacetemplate; + end; + + tdropdowncontroller = class(tcustomdropdowncontroller) + protected + function getbuttonframeclass: dropdownbuttonframeclassty; override; + published + property options; + end; + dropdownwidgeteventty = procedure(const sender: twidget; + const dropdown: twidget) of object; + tdropdownwidgetcontroller = class(tdropdowncontroller) + private + fondropdown: dropdownwidgeteventty; + protected + fbounds_cy: integer; + fbounds_cx: integer; + fdropdownwidget: twidget; + fdropdownwidth: int32; + procedure internaldropdown; override; + procedure updatedropdownbounds(var arect: rectty); override; + procedure receiveevent(const event: tobjectevent); override; + function getdropdownwidget: twidget; override; + public + constructor create(const intf: idropdownwidget); + procedure editnotification(var info: editnotificationinfoty); override; + procedure dostatread(const reader: tstatreader); override; + procedure dostatwrite(const writer: tstatwriter); override; + property dropdownwidget: twidget read fdropdownwidget; + published + property bounds_cx: integer read fbounds_cx write fbounds_cx default 0; + //0 -> ownerwidget.bounds_cx + property bounds_cy: integer read fbounds_cy write fbounds_cy default 0; + //0 -> dropdownwidget.bounds_cy + property ondropdown: dropdownwidgeteventty read fondropdown + write fondropdown; + end; + + dropdownlisteventty = procedure(const sender: twidget; + const dropdown: tdropdownlist) of object; + tcustomdropdownlistcontroller = class(tcustomdropdowncontroller, + idropdownlistcontroller) + private + fondropdown: dropdownlisteventty; + procedure setcols(const Value: tdropdowncols); + function getitemindex: integer; + procedure setitemindex(const Value: integer); + procedure setvaluecol(const avalue: integer); + procedure setimagelist(const avalue: timagelist); + procedure imagelistchanged; + procedure setimageframe(const avalue: framety); + procedure setimageframe_left(const avalue: integer); + procedure setimageframe_top(const avalue: integer); + procedure setimageframe_right(const avalue: integer); + procedure setimageframe_bottom(const avalue: integer); + function getdelay: integer; + procedure setdelay(avalue: integer); + protected + ftimer: tsimpletimer; + fimagelist: timagelist; + fimageframe: framety; + fdropdownrowcount: integer; + fwidth: integer; + fvaluecol: integer; + fdatarowlinewidth: integer; + fdatarowlinecolor: colorty; + fbuttonlength: integer; + fbuttonendlength: integer; + fbuttonminlength: integer; +// fdropdownitems: tdropdowncols; + fdropdownlist: tdropdownlist; + fcols: tdropdowncols; + procedure dotimer(const sender: tobject); + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + procedure valuecolchanged; virtual; + function getdropdownwidget: twidget; override; + procedure itemchanged(const sender: tdatalist; const index: integer); + function getdropdowncolsclass: dropdowncolsclassty; virtual; + procedure selectnone(const akey: keyty); override; + procedure resetselection; override; //sets fcols.fitemindex to -1, no events + function reloadlist: integer; virtual; + //returns first visible row + function getremoterowcount: integer; virtual; + procedure dobeforedropdown; override; + procedure doafterclosedropdown; override; + + //idropdownlist + procedure itemselected(const index: integer; const akey: keyty); virtual; + //-2 -> no selection, -1 -> cancel + procedure dropdownkeydown(var info: keyeventinfoty); + + function getautowidth: integer; + procedure updatedropdownbounds(var arect: rectty); override; + procedure receiveevent(const event: tobjectevent); override; + function createdropdownlist: tdropdownlist; virtual; + function getfixcolclass: dropdownfixcolclassty; virtual; + procedure internaldropdown; override; + procedure editnotification(var info: editnotificationinfoty); override; + public + constructor create(const intf: idropdownlist); + destructor destroy; override; + procedure dostatread(const reader: tstatreader); override; + procedure dostatwrite(const writer: tstatwriter); override; + function valuelist: tmsestringdatalist; + property cols: tdropdowncols read fcols write setcols; + property valuecol: integer read fvaluecol write setvaluecol default 0; + property itemindex: integer read getitemindex write setitemindex default -1; + property delay: integer read getdelay write setdelay default 0; + //ms, -1 = idle + property dropdownrowcount: integer read fdropdownrowcount + write fdropdownrowcount default 8; + property width: integer read fwidth write fwidth default 0; + property datarowlinewidth: integer read fdatarowlinewidth + write fdatarowlinewidth default 0; + property datarowlinecolor: colorty read fdatarowlinecolor + write fdatarowlinecolor default defaultdatalinecolor; + property buttonlength: integer read fbuttonlength + write fbuttonlength default 0; + property buttonendlength: integer read fbuttonendlength + write fbuttonendlength default 0; + property buttonminlength: integer read fbuttonminlength + write fbuttonminlength default defaultbuttonminlength; + property imagelist: timagelist read fimagelist write setimagelist; + property imageframe: framety read fimageframe write setimageframe; + property imageframe_left: integer read fimageframe.left + write setimageframe_left default 0; + property imageframe_top: integer read fimageframe.top + write setimageframe_top default 0; + property imageframe_right: integer read fimageframe.right + write setimageframe_right default 0; + property imageframe_bottom: integer read fimageframe.bottom + write setimageframe_bottom default 0; + property ondropdown: dropdownlisteventty read fondropdown + write fondropdown; + end; + + tnocolsdropdownlistcontroller = class(tcustomdropdownlistcontroller) + protected + function getbuttonframeclass: dropdownbuttonframeclassty; override; + public + constructor create(const intf: idropdownlist); + published + property options; + property dropdownrowcount; + property delay; + property width; + property datarowlinewidth; + property datarowlinecolor; + property buttonlength; + property buttonminlength; + property buttonendlength; + property ondropdown; + end; + + tdropdownlistcontroller = class(tnocolsdropdownlistcontroller) + public + constructor create(const intf: idropdownlist); + published + property imagelist; + property imageframe_left; + property imageframe_top; + property imageframe_right; + property imageframe_bottom; + property cols; + property valuecol; + property itemindex; + end; + + dropdownlistcontrollerclassty = class of tcustomdropdownlistcontroller; + + tmbdropdownlistcontroller = class(tdropdownlistcontroller) + protected + function getbuttonframeclass: dropdownbuttonframeclassty; override; + end; + + +implementation +uses + sysutils,msewidgets,mseguiintf,rtlconsts,msebits; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tcustomframe1= class(tcustomframe); + tdatacols1 = class(tdatacols); + twidget1 = class(twidget); + tcustombuttonframe1 = class(tcustombuttonframe); + tstringcol1 = class(tstringcol); + tframebutton1 = class(tframebutton); + tframebuttons1 = class(tframebuttons); + tinplaceedit1 = class(tinplaceedit); + + timagefixcol = class(tdropdownfixcol) + private + fimagelist: timagelist; + fimageframe: framety; + protected + procedure drawcell(const canvas: tcanvas); override; + public + constructor create(const agrid: tcustomgrid; const aowner: tgridarrayprop; + const acontroller: tcustomdropdownlistcontroller); override; + end; + + +const + defaultdropdowncellinnerframe: framety = + (left: 1; top: 0; right: 1; bottom: 0); + +{ tdropdowncolfont } + +class function tdropdowncolfont.getinstancepo(owner: tobject): pfont; +begin + result:= @tdropdowncol(owner).ffont; +end; + +{ tdropdowncolfontselect } + +class function tdropdowncolfontselect.getinstancepo(owner: tobject): pfont; +begin + result:= @tdropdowncol(owner).ffontselect; +end; + +{ tdropdowncol } + +constructor tdropdowncol.create(const aowner: tcustomdropdownlistcontroller); +begin + fowner:= aowner; + fwidth:= griddefaultcolwidth; + foptions:= defaultdropdowncoloptions; + flinecolor:= cl_gray; + ftextflags:= defaultdropdowncoltextflags; + fcolor:= cl_default; + fcolorselect:= cl_default; +// ffontcolorselect:= cl_default; + inherited create; +end; + +destructor tdropdowncol.destroy; +begin + inherited; + ffont.free(); +end; + +procedure tdropdowncol.setoptions(const avalue: coloptionsty); +begin + foptions:= avalue + [co_focusselect]; +end; + +procedure tdropdowncol.createfont; +begin + if ffont = nil then begin + ffont:= tdropdowncolfont.create(); + end; +end; + +procedure tdropdowncol.createfontselect; +begin + if ffontselect = nil then begin + ffontselect:= tdropdowncolfontselect.create(); + end; +end; + +function tdropdowncol.getfont: tdropdowncolfont; +begin + if fowner <> nil then begin + getoptionalobject(tcustomdropdownlistcontroller(fowner).componentstate, + ffont,@createfont); + end; + result:= ffont; +end; + +procedure tdropdowncol.setfont(const avalue: tdropdowncolfont); +begin + if fowner <> nil then begin + if avalue <> ffont then begin + setoptionalobject(tcustomdropdownlistcontroller(fowner).componentstate,avalue, + ffont,@createfont); + end; + end; +end; + +function tdropdowncol.getfontselect: tdropdowncolfontselect; +begin + if fowner <> nil then begin + getoptionalobject(tcustomdropdownlistcontroller(fowner).componentstate, + ffontselect,@createfontselect); + end; + result:= ffontselect; +end; + +procedure tdropdowncol.setfontselect(const avalue: tdropdowncolfontselect); +begin + if fowner <> nil then begin + if avalue <> ffontselect then begin + setoptionalobject( + tcustomdropdownlistcontroller(fowner).componentstate,avalue, + ffontselect,@createfontselect); + end; + end; +end; + +procedure tdropdowncol.readfontcolorselect(reader: treader); +var + co1: colorty; +begin + co1:= reader.readinteger(); + if co1 <> cl_default then begin + createfontselect(); + ffontselect.color:= co1; + end; +end; + +procedure tdropdowncol.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('fontcolorselect',@readfontcolorselect,nil,false); +end; + +procedure tdropdowncol.setframetemplate(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fframetemplate)); +end; + +procedure tdropdowncol.setfacetemplate(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ffacetemplate)); +end; + +{ tdropdownfont } + +class function tdropdownfont.getinstancepo(owner: tobject): pfont; +begin + result:= @tdropdowncols(owner).ffont; +end; + +{ tdropdownfontselect } + +class function tdropdownfontselect.getinstancepo(owner: tobject): pfont; +begin + result:= @tdropdowncols(owner).ffontselect; +end; + +{ tdropdowndatacols } + +constructor tdropdowndatacols.create( + const aowner: tcustomdropdownlistcontroller); +begin + inherited create(aowner,nil); + count:= 1; +end; + +class function tdropdowndatacols.getitemclasstype: persistentclassty; +begin + result:= tdropdowndata; +end; + +procedure tdropdowndatacols.createitem(const index: integer; + var item: tpersistent); +begin + item:= tdropdowndata.create(); +end; + +function tdropdowndatacols.getitems(const index: integer): tdropdowndata; +begin + result:= tdropdowndata(inherited getitems(index)); +end; + +procedure tdropdowndatacols.checkrowindex(const aindex: integer); +begin + if count = 0 then begin + raise exception.create('No columns.'); + end; + if (aindex < 0) or (aindex >= maxrowcount) then begin + tlist.error(slistindexerror,aindex); + end; +end; + +procedure tdropdowndatacols.setrowcount(const avalue: integer); +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + tdropdowndata(fitems[int1]).count:= avalue; + end; +end; + +procedure tdropdowndatacols.itemchanged(const sender: tdatalist; + const index: integer); +begin + if (fupdating1 = 0 ) and assigned(fonitemchange) then begin + fonitemchange(sender,index); + end; +end; + +function tdropdowndatacols.maxrowcount: integer; +var + int1,int2: integer; +begin + result:= 0; + for int1:= 0 to count - 1 do begin + int2:= items[int1].count; + if int2 > result then begin + result:= int2; + end; + end; +end; + +function tdropdowndatacols.minrowcount: integer; +var + int1,int2: integer; +begin + if count > 0 then begin + result:= bigint; + for int1:= 0 to count - 1 do begin + int2:= items[int1].count; + if int2 < result then begin + result:= int2; + end; + end; + end + else begin + result:= 0; + end; +end; + +procedure tdropdowndatacols.beginupdate; +begin + inc(fupdating1); +end; + +procedure tdropdowndatacols.endupdate; +begin + dec(fupdating1); + if fupdating1 = 0 then begin + itemchanged(nil,-1); + end; +end; + +procedure tdropdowndatacols.clear; +var + int1: integer; +begin + beginupdate; + try + for int1:= 0 to count - 1 do begin + items[int1].count:= 0; + end; + finally + endupdate; + end; +end; + +function tdropdowndatacols.getrow(const aindex: integer): msestringarty; +var + int1: integer; +begin + if (aindex < 0) or (aindex >= minrowcount) then begin + tlist.error({$ifndef fpc}@{$endif}slistindexerror, aindex); + end; + setlength(result,count); + for int1:= 0 to high(fitems) do begin + result[int1]:= pmsestring(tdropdowndata(fitems[int1]).fdatapo + + aindex * sizeof(msestring))^; + end; +end; + +function tdropdowndatacols.addrow(const aitems: array of msestring): integer; +var + int1: integer; +begin + result:= maxrowcount; + beginupdate; + try + for int1:= 0 to count - 1 do begin + items[int1].count:= result + 1; + if int1 < length(aitems) then begin + items[int1][result]:= aitems[int1]; + end; + end; + finally + endupdate; + end; +end; + +procedure tdropdowndatacols.insertrow(const aindex: integer; + const aitems: array of msestring); +var + int1,int2: integer; +begin + int2:= maxrowcount; + if aindex = int2 then begin + addrow(aitems); + end + else begin + checkrowindex(aindex); + beginupdate; + try + for int1:= 0 to count - 1 do begin + with items[int1] do begin + count:= int2; + if int1 <= high(aitems) then begin + insert(aindex,aitems[int1]); + end + else begin + insert(aindex,''); + end; + end; + end; + finally + endupdate; + end; + end; +end; + +procedure tdropdowndatacols.deleterow(const aindex: integer); +var + int1,int2: integer; +begin + checkrowindex(aindex); + int2:= maxrowcount; + beginupdate; + try + for int1:= 0 to count - 1 do begin + with items[int1] do begin + count:= int2; + deletedata(aindex); + end; + end; + finally + endupdate; + end; +end; + +{ tdropdowncols } + +constructor tdropdowncols.create(const aowner: tcustomdropdownlistcontroller); +begin + fwidth:= griddefaultcolwidth; + foptions:= defaultdropdowncoloptions; + flinecolor:= cl_gray; + ftextflags:= defaultdropdowncoltextflags; + fcolor:= cl_default; + fcolorselect:= cl_default; +// ffontcolorselect:= cl_default; + + inherited create(aowner{,nil}); +// items[0].options:= items[0].options + [co_fill]; +end; + +destructor tdropdowncols.destroy; +begin + inherited; + ffont.free(); + ffontselect.free(); +end; + +class function tdropdowncols.getitemclasstype: persistentclassty; +begin + result:= tdropdowncol; +end; + +function tdropdowncols.getcolclass: dropdowncolclassty; +begin + result:= tdropdowncol; +end; + +procedure tdropdowncols.createitem(const index: integer; var item: tpersistent); +begin + item:= getcolclass.create(tcustomdropdownlistcontroller(fowner)); + with tdropdowncol(item) do begin + onitemchange:= {$ifdef FPC}@{$endif}itemchanged; + if fnostreaming then begin + include(fstate,dls_nostreaming); + end; + fwidth:= self.fwidth; + foptions:= self.foptions; + ftextflags:= self.ftextflags; + flinewidth:= self.flinewidth; + flinecolor:= self.flinecolor; + fcolor:= self.fcolor; + fcolorselect:= self.fcolorselect; +// ffontcolorselect:= self.ffontcolorselect; + end; +end; + +procedure tdropdowncols.createfont(); +begin + if ffont = nil then begin + ffont:= tdropdownfont.create(); + end; +end; + +procedure tdropdowncols.createfontselect(); +begin + if ffontselect = nil then begin + ffontselect:= tdropdownfontselect.create(); + end; +end; + +function tdropdowncols.getfont: tdropdownfont; +begin + if fowner <> nil then begin + getoptionalobject(tcustomdropdownlistcontroller(fowner).componentstate, + ffont,@createfont); + end; + result:= ffont; +end; + +procedure tdropdowncols.setfont(const avalue: tdropdownfont); +begin + if fowner <> nil then begin + if avalue <> ffont then begin + setoptionalobject( + tcustomdropdownlistcontroller(fowner).componentstate,avalue, + ffont,@createfont); + end; + end; +end; + +function tdropdowncols.getfontselect: tdropdownfontselect; +begin + if fowner <> nil then begin + getoptionalobject(tcustomdropdownlistcontroller(fowner).componentstate, + ffontselect,@createfontselect); + end; + result:= ffontselect; +end; + +procedure tdropdowncols.setfontselect(const avalue: tdropdownfontselect); +begin + if fowner <> nil then begin + if avalue <> ffontselect then begin + setoptionalobject( + tcustomdropdownlistcontroller(fowner).componentstate,avalue, + ffontselect,@createfontselect); + end; + end; +end; + +procedure tdropdowncols.setnostreaming(const avalue: boolean); +var + int1: integer; +begin + if fnostreaming <> avalue then begin + fnostreaming:= avalue; + if avalue then begin + for int1:= 0 to count - 1 do begin + include(tdropdowncol(items[int1]).fstate,dls_nostreaming); + end; + end + else begin + for int1:= 0 to count - 1 do begin + exclude(tdropdowncol(items[int1]).fstate,dls_nostreaming); + end; + end; + end; +end; + +function tdropdowncols.getitems(const index: integer): tdropdowncol; +begin + result:= tdropdowncol(inherited getitems(index)); +end; + +procedure tdropdowncols.setcount1(acount: integer; doinit: boolean); +begin + if not (aps_destroying in fstate) and (fowner <> nil) and + (acount <= tcustomdropdownlistcontroller(fowner).fvaluecol) then begin + acount:= tcustomdropdownlistcontroller(fowner).fvaluecol + 1; + end; + inherited; +end; + +procedure tdropdowncols.setwidth(const avalue: integer); +var + int1: integer; +begin + if fwidth <> avalue then begin + fwidth:= avalue; + if not tcustomdropdownlistcontroller(fowner).isloading then begin + for int1:= 0 to count - 1 do begin + tdropdowncol(fitems[int1]).width:= avalue; + end; + end; + end; +end; + +procedure tdropdowncols.setoptions(const avalue: coloptionsty); +var + int1: integer; + mask: longword; +begin + if foptions <> avalue then begin + mask:= longword(avalue) xor longword(foptions); + foptions:= avalue; + if not tcustomdropdownlistcontroller(fowner).isloading then begin + for int1:= 0 to count - 1 do begin + tdropdowncol(fitems[int1]).options:= + coloptionsty(replacebits(longword(foptions), + longword(tdropdowncol(fitems[int1]).options),mask)); + end; + end; + end; +end; + +procedure tdropdowncols.settextflags(const avalue: textflagsty); +var + int1: integer; + mask: longword; +begin + if ftextflags <> avalue then begin + mask:= longword(avalue) xor longword(ftextflags); + ftextflags:= avalue; + if not tcustomdropdownlistcontroller(fowner).isloading then begin + for int1:= 0 to count - 1 do begin + tdropdowncol(fitems[int1]).textflags:= + textflagsty(replacebits(longword(ftextflags), + longword(tdropdowncol(fitems[int1]).textflags),mask)); + end; + end; + end; +end; + +procedure tdropdowncols.setlinewidth(const avalue: integer); +var + int1: integer; +begin + if fwidth <> avalue then begin + flinewidth:= avalue; + if not tcustomdropdownlistcontroller(fowner).isloading then begin + for int1:= 0 to count - 1 do begin + tdropdowncol(fitems[int1]).linewidth:= avalue; + end; + end; + end; +end; + +procedure tdropdowncols.setlinecolor(const avalue: colorty); +var + int1: integer; +begin + if flinecolor <> avalue then begin + flinecolor:= avalue; + if not tcustomdropdownlistcontroller(fowner).isloading then begin + for int1:= 0 to count - 1 do begin + tdropdowncol(fitems[int1]).linecolor:= avalue; + end; + end; + end; +end; + +procedure tdropdowncols.setcolor(const avalue: colorty); +var + int1: integer; +begin + if fcolor <> avalue then begin + fcolor:= avalue; + if not tcustomdropdownlistcontroller(fowner).isloading then begin + for int1:= 0 to count - 1 do begin + tdropdowncol(fitems[int1]).color:= avalue; + end; + end; + end; +end; + +procedure tdropdowncols.setcolorselect(const avalue: colorty); +var + int1: integer; +begin + if fcolorselect <> avalue then begin + fcolorselect:= avalue; + if not tcustomdropdownlistcontroller(fowner).isloading then begin + for int1:= 0 to count - 1 do begin + tdropdowncol(fitems[int1]).colorselect:= avalue; + end; + end; + end; +end; + +procedure tdropdowncols.readfontcolorselect(reader: treader); +var + co1: colorty; +begin + co1:= reader.readinteger(); + if co1 <> cl_default then begin + createfontselect(); + ffontselect.color:= co1; + end; +end; + +procedure tdropdowncols.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('fontcolorselect',@readfontcolorselect,nil,false); +end; + +procedure tdropdowncols.setframetemplate(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fframetemplate)); +end; + +procedure tdropdowncols.setfacetemplate(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ffacetemplate)); +end; + +{ +procedure tdropdowncols.setfontcolorselect(const avalue: colorty); +var + int1: integer; +begin + if ffontcolorselect <> avalue then begin + ffontcolorselect:= avalue; + if not tcustomdropdownlistcontroller(fowner).isloading then begin + for int1:= 0 to count - 1 do begin + tdropdowncol(fitems[int1]).fontcolorselect:= avalue; + end; + end; + end; +end; +} +{ tcustomdropdownbuttonframe } + +constructor tcustomdropdownbuttonframe.create(const aintf: icaptionframe; + const buttonintf: ibutton); +begin + inherited; +end; + +procedure tcustomdropdownbuttonframe.setreadonly(const Value: boolean); +begin + if (freadonly <> value) then begin + freadonly:= Value; + updatestate(); + end; +{ + if (freadonly <> value) and (factivebutton < buttons.count) then begin + freadonly:= Value; + buttons[factivebutton].enabled:= not value; + end; +} +end; + +procedure tcustomdropdownbuttonframe.updatestate(); +var + i1: integer; +begin + for i1:= 0 to buttons.count - 1 do begin + tframebutton1(tframebuttons1(buttons).fitems[i1]).freadonly:= freadonly; + end; + inherited; +end; + +function tcustomdropdownbuttonframe.getbuttonclass: framebuttonclassty; +begin + result:= tdropdownbutton; +end; + +procedure tcustomdropdownbuttonframe.updatedropdownoptions( + const avalue: dropdowneditoptionsty); +begin + buttons[factivebutton].visible:= not (deo_disabled in avalue); +end; + +function tcustomdropdownbuttonframe.getbutton: tdropdownbutton; +begin + result:= tdropdownbutton(inherited getbutton); +end; + +procedure tcustomdropdownbuttonframe.setbutton(const avalue: tdropdownbutton); +begin + inherited setbutton(avalue); +end; + +{ tcustomdropdowncontroller } + +constructor tcustomdropdowncontroller.create(const intf: idropdown); +begin + fintf:= intf; + fowner:= intf.getwidget; + foptions:= defaultdropdownoptionsedit; + fcolor:= cl_default; + fcolorclient:= cl_default; + inherited create; + internalcreateframe; +end; + +destructor tcustomdropdowncontroller.destroy; +begin + application.unregisteronapplicationactivechanged( + {$ifdef FPC}@{$endif}applicationactivechanged); + getdropdownwidget.Free; + inherited; +end; + +function tcustomdropdowncontroller.hasdropdown(): boolean; +var + wi1: twidget; +begin + wi1:= getdropdownwidget(); + result:= (wi1 <> nil) and not wi1.releasing(); +end; + +procedure tcustomdropdowncontroller.dostatread(const reader: tstatreader); +begin + //dummy +end; + +procedure tcustomdropdowncontroller.dostatwrite(const writer: tstatwriter); +begin + //dummy +end; + +function tcustomdropdowncontroller.getbuttonframeclass: + dropdownbuttonframeclassty; +begin + result:= tcustomdropdownbuttonframe; +end; + +procedure tcustomdropdowncontroller.internalcreateframe; +var + widget: twidget; +begin + widget:= fintf.getwidget; + if twidget1(widget).fframe = nil then begin + getbuttonframeclass.create(iscrollframe(widget),ibutton(self)); + end; + updatereadonlystate(); +end; + +procedure tcustomdropdowncontroller.setoptions( + const Value: dropdowneditoptionsty); +begin + foptions := Value; + tcustomdropdownbuttonframe( + twidget1(fintf.getwidget).fframe).updatedropdownoptions(value); +end; + +procedure tcustomdropdowncontroller.updatereadonlystate; +begin + tcustomdropdownbuttonframe(twidget1(fintf.getwidget).fframe).readonly:= + not fintf.geteditor.canedit or not candropdown; +end; + +function tcustomdropdowncontroller.candropdown: boolean; +begin + result:= fintf.geteditor.canedit; +end; + +procedure tcustomdropdowncontroller.internaldropdown; +begin + //dummy +end; + +procedure tcustomdropdowncontroller.dobeforedropdown; +begin + fintf.dobeforedropdown; + if deo_modifiedbeforedropdown in foptions then begin + fintf.modified; + end; +end; + +procedure tcustomdropdowncontroller.doafterclosedropdown; +begin + fintf.doafterclosedropdown; +end; + +procedure tcustomdropdowncontroller.dropdown; +begin + if not (deo_disabled in foptions) and candropdown and + (fdropdowncount = 0) then begin + dobeforedropdown; + internaldropdown; + application.postevent(tobjectevent.create(ek_dropdown,ievent(self))); + inc(fdropdowncount); + fintf.getwidget.window.registermovenotification(ievent(self)); + end; +end; + +procedure tcustomdropdowncontroller.canceldropdown; +var + widget1: twidget; +begin + widget1:= getdropdownwidget; + if widget1 <> nil then begin + widget1.window.modalresult:= mr_cancel; + end; +end; + +procedure tcustomdropdowncontroller.buttonaction(var action: buttonactionty; + const buttonindex: integer); +begin + fintf.buttonaction(action,buttonindex); + if buttonindex = tcustomdropdownbuttonframe( + twidget1(fintf.getwidget).fframe).factivebutton then begin + with fintf.getwidget do begin + case action of + ba_buttonpress: begin + if canfocus then begin + setfocus; + end; + end; + ba_click: begin + if focused then begin + dropdown; + end; + end; + end; + end; + end; +end; + +procedure tcustomdropdowncontroller.mouseevent(var info: mouseeventinfoty); +begin + tcustombuttonframe( twidget1(fowner).fframe).mouseevent(info); +end; + +procedure tcustomdropdowncontroller.dokeydown(var info: keyeventinfoty); +begin + with info do begin + if (key = key_down) and (shiftstate = [ss_alt]) and + (deo_keydropdown in foptions) and fintf.geteditor.canedit then begin + exclude(eventstate,es_processed); + dropdown; + include(eventstate,es_processed); + end; + end; +end; + +procedure tcustomdropdowncontroller.domousewheelevent( + var info: mousewheeleventinfoty); +begin + with info do begin + if not (es_processed in info.eventstate) then begin + if (wheel = mw_down) and fintf.getwidget.active then begin + dropdown; + include(info.eventstate,es_processed); + end + else begin + if (wheel = mw_up) and (getdropdownwidget <> nil) then begin + canceldropdown; + include(info.eventstate,es_processed); + end; + end; + end; + end; +end; + +procedure tcustomdropdowncontroller.selectnone(const akey: keyty); +begin + fdataselected:= true; + fintf.setdropdowntext('',true,false,akey); +end; + +procedure tcustomdropdowncontroller.editnotification( + var info: editnotificationinfoty); +begin + case info.action of + ea_textedited: begin + fdataselected:= false; + end; + ea_textentered: begin + if (deo_selectonly in foptions) and not fdataselected and + fintf.getedited then begin + if not (deo_forceselect in foptions) and + (fintf.geteditor.text = '') then begin + info.action:= ea_none; + selectnone(key_return); + end + else begin + if candropdown then begin + info.action:= ea_none; + dropdown; + end; + end; + end; + end; + end; +end; + +procedure tcustomdropdowncontroller.updatedropdownbounds(var arect: rectty); +begin + //dummy +end; + +procedure tcustomdropdowncontroller.updatedropdownpos(const arect: rectty); +var + widget1: twidget; + rect1: rectty; +begin + widget1:= getdropdownwidget; + if widget1 <> nil then begin + rect1:= arect; //widget1.widgetrect; + updatedropdownbounds(rect1); + getdropdownpos(fintf.getwidget,deo_right in foptions,rect1); + widget1.widgetrect:= rect1; + end; +end; + +procedure tcustomdropdowncontroller.objectevent(const sender: tobject; + const event: objecteventty); +begin + if (event = oe_destroyed) and (sender = getdropdownwidget) then begin + dec(fdropdowncount); + fintf.getwidget.window.unregistermovenotification(ievent(self)); + application.unregisteronapplicationactivechanged( + {$ifdef FPC}@{$endif}applicationactivechanged); + end; + inherited; + if (event = oe_changed) and (sender = fintf.getwidget.window) and + (getdropdownwidget <> nil) then begin + updatedropdownpos(getdropdownwidget.widgetrect); + end; +end; + +function tcustomdropdowncontroller.getwidget: twidget; +begin + result:= fintf.getwidget; +end; + +function tcustomdropdowncontroller.getdropdownwidget: twidget; +begin + result:= nil; +end; + +function tcustomdropdowncontroller.dataselected: boolean; +begin + result:= fdataselected; +end; + +function tcustomdropdowncontroller.setdropdowntext(const avalue: msestring; + const docheckvalue: boolean; const canceled: boolean; + const akey: keyty): boolean; +begin + fdataselected:= fdataselected or docheckvalue; + fdataselected:= fintf.setdropdowntext(avalue,docheckvalue,canceled,akey); + result:= fdataselected; +end; + +procedure tcustomdropdowncontroller.applicationactivechanged(const avalue: boolean); +var + widget1: twidget; +begin + if not avalue then begin + widget1:= getdropdownwidget; + if (widget1 <> nil) and not widget1.window.hastransientfor then begin + canceldropdown; + end; +// getdropdownwidget.release; + end; +end; + +procedure tcustomdropdowncontroller.dropdownactivated; +begin + if dcs_forcecaret in fstate then begin + fintf.geteditor.doactivate; + end; +end; + +procedure tcustomdropdowncontroller.dropdowndeactivated; +begin + if dcs_forcecaret in fstate then begin + fintf.geteditor.dodeactivate; + end; +end; + +function tcustomdropdowncontroller.isloading: boolean; +begin + result:= csloading in fintf.getwidget.componentstate; +end; + +procedure tcustomdropdowncontroller.resetselection; +begin + //dummy +end; + +function tcustomdropdowncontroller.componentstate: tcomponentstate; +begin + result:= fintf.getwidget.componentstate; +end; + +procedure tcustomdropdowncontroller.setframetemplate(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fframetemplate)); +end; + +procedure tcustomdropdowncontroller.setfacetemplate(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ffacetemplate)); +end; + +{ tdropdowncontroller } + +function tdropdowncontroller.getbuttonframeclass: dropdownbuttonframeclassty; +begin + result:= tdropdownmultibuttonframe; +end; + +{ tdropdownwidgetcontroller } + +constructor tdropdownwidgetcontroller.create(const intf: idropdownwidget); +begin + inherited create(intf); +end; + +procedure tdropdownwidgetcontroller.internaldropdown; +var + widget1: twidget; +begin + inherited; + if fdropdownwidget = nil then begin + widget1:= nil; + try + idropdownwidget(fintf).createdropdownwidget(fintf.geteditor.text,widget1); + setlinkedvar(widget1,tmsecomponent(fdropdownwidget)); + if (deo_colsizing in options) and (fdropdownwidth > 0) then begin + bounds_cx:= fdropdownwidth; + end; + except + if widget1 <> nil then begin + widget1.release; + end; + raise; + end; + end; + fdropdownwidget.name:= '_dropdownwidget'; //debug purposes +end; + +function tdropdownwidgetcontroller.getdropdownwidget: twidget; +begin + result:= fdropdownwidget; +end; + +procedure tdropdownwidgetcontroller.updatedropdownbounds(var arect: rectty); +begin + if fbounds_cx > 0 then begin + arect.cx:= fbounds_cx; + end + else begin + arect.cx:= fintf.getwidget.framesize.cx; + end; + if fbounds_cy > 0 then begin + arect.cy:= fbounds_cy; + end; +end; + +procedure tdropdownwidgetcontroller.receiveevent(const event: tobjectevent); +begin + inherited; + if event.kind = ek_dropdown then begin + if fdropdownwidget <> nil then begin + updatedropdownpos(fdropdownwidget.widgetrect); + fdropdownwidget.window.winid; //update window.options + if fdropdownwidget.window.ispopup then begin + application.registeronapplicationactivechanged( + {$ifdef FPC}@{$endif}applicationactivechanged); + end; + if dcs_forcecaret in fstate then begin + fintf.geteditor.forcecaret:= true; + end; + try + if assigned(fondropdown) then begin + fondropdown(fintf.getwidget,fdropdownwidget); + end; + if fdropdownwidget.show(true,fintf.getwidget.window) = mr_ok then begin + fintf.geteditor.forcecaret:= false; + setdropdowntext(idropdownwidget(fintf).getdropdowntext(fdropdownwidget), + true,false,fselectkey); + end; + finally + fintf.geteditor.forcecaret:= false; + doafterclosedropdown; + end; + if deo_colsizing in foptions then begin + fdropdownwidth:= fdropdownwidget.width; + end; + fdropdownwidget.Free; + fdropdownwidget:= nil; + end; + end; +end; + +procedure tdropdownwidgetcontroller.editnotification( + var info: editnotificationinfoty); +begin + inherited; + case info.action of + ea_textedited: begin + if fdropdownwidget = nil then begin + if (deo_autodropdown in foptions) and + ((fintf.geteditor.text <> '') or (deo_forceselect in foptions)) then begin + dropdown; + end; + end; + end; + end; +end; + +procedure tdropdownwidgetcontroller.dostatread(const reader: tstatreader); +begin + if deo_savestate in foptions then begin + fdropdownwidth:= reader.readinteger('dropdownwidth',0); + end; +end; + +procedure tdropdownwidgetcontroller.dostatwrite(const writer: tstatwriter); +begin + if deo_savestate in foptions then begin + writer.writeinteger('dropdownwidth',fdropdownwidth); + end; +end; + +{ tcustomdropdownlistcontroller } + +constructor tcustomdropdownlistcontroller.create(const intf: idropdownlist); +begin + include(fstate,dcs_forcecaret); + fcols:= getdropdowncolsclass.create(self); + fcols.onitemchange:= {$ifdef FPC}@{$endif}itemchanged; + fcols.fitemindex:= -1; + fdropdownrowcount:= 8; + fdatarowlinecolor:= defaultdatalinecolor; + fbuttonminlength:= defaultbuttonminlength; + inherited create(intf); +end; + +destructor tcustomdropdownlistcontroller.destroy; +begin + freeandnil(ftimer); + inherited; + fcols.Free; +end; + +function tcustomdropdownlistcontroller.getdropdowncolsclass: dropdowncolsclassty; +begin + result:= tdropdowncols; +end; + +procedure tcustomdropdownlistcontroller.dotimer(const sender: tobject); +begin + if fdropdownlist <> nil then begin + if not (dcs_itemselecting in fstate) then begin + fdropdownlist.filtertext:= fintf.geteditor.text; + end; + end + else begin + if (deo_autodropdown in foptions) then begin + if candropdown and ((fintf.geteditor.text <> '') or + (deo_forceselect in foptions)) then begin + dropdown; + end; + end + else begin + fcols.fitemindex:= -1; + end; + end; +end; + +procedure tcustomdropdownlistcontroller.editnotification( + var info: editnotificationinfoty); +begin + inherited; + case info.action of + ea_textedited: begin + if ftimer = nil then begin + dotimer(nil); + end + else begin + ftimer.restart; + end; + end; + end; +end; + +function tcustomdropdownlistcontroller.valuelist: tmsestringdatalist; +begin + result:= fcols[fvaluecol]; +end; + +procedure tcustomdropdownlistcontroller.itemchanged( + const sender: tdatalist; const index: integer); +begin + if (deo_selectonly in foptions) and (index = fcols.fitemindex) and + (index >= 0) then begin + setdropdowntext(valuelist[index],false,false,key_none); + end; +end; + +function tcustomdropdownlistcontroller.createdropdownlist: tdropdownlist; +begin + result:= tdropdownlist.create(self,fcols,getfixcolclass); + result.name:= '_dropdownlist'; //debug purposes +end; + +procedure tcustomdropdownlistcontroller.updatedropdownbounds(var arect: rectty); +begin + if fwidth = 0 then begin + arect.cx:= fintf.getwidget.framesize.cx; + end + else begin + if fwidth = -1 then begin + arect.cx:= getautowidth; + end + else begin + arect.cx:= fwidth; + end; + end; +end; + +function tcustomdropdownlistcontroller.getautowidth: integer; +var + int1: integer; +begin + result:= 0; + if fdropdownlist = nil then begin + for int1:= 0 to high(fcols.fitems) do begin + with tdropdowncol(fcols.fitems[int1]) do begin + if not (co_invisible in foptions) then begin + result:= result+fwidth+flinewidth; + end; + end; + end; + end + else begin + for int1:= 0 to fdropdownlist.datacols.count -1 do begin + with tdatacol(tdatacols1(fdropdownlist.fdatacols).fitems[int1]) do begin + if not (co_invisible in options) then begin + result:= result+width+linewidth; + end; + end; + end; + result:= result + fdropdownlist.framedim.cx; + end; +end; + +procedure tcustomdropdownlistcontroller.receiveevent(const event: tobjectevent); +var + int1,int2{,int3,int4}: integer; +// rect1: rectty; + str1: msestring; + widget1: twidget; + items1: tdropdowndatacols; + bo1: boolean; +begin + inherited; + if event.kind = ek_dropdown then begin + if fdropdownlist = nil then begin + items1:= idropdownlist(fintf).getdropdownitems; + if items1 <> nil then begin //tselector + if fcols.count < items1.count then begin + fcols.count:= items1.count; + end; + fcols.fdatacols:= items1; + end + else begin + fcols.fdatacols:= fcols; + end; + setlinkedcomponent(ievent(self),createdropdownlist, + tmsecomponent(fdropdownlist)); + fdropdownlist.name:= '_dropdownlist'; //debug purpose + fdropdownlist.updateskin; + try + with fdropdownlist.frame.sbvert do begin + buttonminlength:= fbuttonminlength; + buttonlength:= fbuttonlength; + buttonendlength:= fbuttonendlength; + end; + application.registeronapplicationactivechanged( + {$ifdef FPC}@{$endif}applicationactivechanged); + fintf.geteditor.forcecaret:= true; + try + widget1:= self.fintf.getwidget; + with fdropdownlist do begin + if deo_casesensitive in self.foptions then begin + options:= options + [dlo_casesensitive]; + end; + if deo_posinsensitive in self.foptions then begin + options:= options + [dlo_posinsensitive]; + end; + if deo_livefilter in self.foptions then begin + options:= options + [dlo_livefilter]; + end; + if deo_sorted in self.foptions then begin + sort; + end; + if fwidth = 0 then begin + int1:= widget1.framesize.cx; + end + else begin + if fwidth = -1 then begin + int1:= getautowidth; + end + else begin + int1:= fwidth; + end; + end; + with self.fintf.geteditor do begin + str1:= text; + bo1:= canundo(); + end; + int2:= fcols.fitemindex; + if (int2 >= 0) and + ((fcols.fdatacols.count = 0) or (int2 >= fcols.fdatacols[0].count) or + (str1 <> fcols.fdatacols[0][int2]) and + (bo1 or (fcols.fdatacols = fcols))) then begin + //no tselector + int2:= -1; + end; + fselectkey:= key_none; + if assigned(fondropdown) then begin + fondropdown(widget1,fdropdownlist); + end; + show(int1,self.fdropdownrowcount,int2,str1); + fintf.geteditor.forcecaret:= false; + include(self.fstate,dcs_itemselecting); + self.itemselected(int2,fselectkey); + end; + finally + exclude(self.fstate,dcs_itemselecting); + fintf.geteditor.forcecaret:= false; + doafterclosedropdown; + end; + if deo_colsizing in options then begin + for int1:= 0 to high(fcols.fitems) do begin + tdropdowncol(fcols.fitems[int1]).width:= + tdatacol(tdatacols1(fdropdownlist.fdatacols).fitems[int1]).width; + end; + end; + finally + fdropdownlist.free; + freeandnil(fdropdownlist); + end; + end; + end; +end; + +function tcustomdropdownlistcontroller.getitemindex: integer; +begin + result:= fcols.fitemindex; +end; + +procedure tcustomdropdownlistcontroller.setitemindex(const Value: integer); +begin + if (value >= valuelist.Count) or (value < 0) then begin + fcols.fitemindex:= -1; + end + else begin + fcols.fitemindex:= Value; + end; + if fcols.fitemindex < 0 then begin + fcols.fkeyvalue:= ''; + setdropdowntext('',false,false,key_none); + end + else begin + fcols.fkeyvalue:= valuelist[fcols.fitemindex]; + fdataselected:= true; + setdropdowntext(fcols.fkeyvalue,false,false,key_none); + end; +end; + +procedure tcustomdropdownlistcontroller.setcols(const Value: tdropdowncols); +begin + fcols.assign(value); +end; + +procedure tcustomdropdownlistcontroller.dropdownkeydown(var info: keyeventinfoty); +var + editor1: tinplaceedit1; + str1: msestring; +begin + editor1:= tinplaceedit1(fintf.geteditor); + editor1.dokeydown(info); + with info do begin + if not (es_processed in eventstate) and (shiftstate*shiftstatesmask = []) then begin + case key of + key_right: begin + with fdropdownlist do begin + if (row >= 0) then begin + str1:= tstringcol1(fdropdownlist[fvaluecol]).getrowtext(row); + if length(str1) > editor1.curindex then begin + editor1.text:= copy(str1,1,editor1.curindex); + editor1.enterchars(copy(str1,editor1.curindex+1,1)); +// editor1.text:= copy(str1,1,editor1.curindex+1); +// editor1.curindex:= editor1.curindex + 1; + include(eventstate,es_processed); + end; + end; + end; + end; + end; + end; + end; +end; + +procedure tcustomdropdownlistcontroller.itemselected(const index: integer; + const akey: keyty); +var + int1: integer; +begin + int1:= index; + if deo_forceselect in foptions then begin + if int1 < 0 then begin + int1:= fcols.fitemindex; + end; + end + else begin + if int1 = -2 then begin //empty row selected + int1:= -1; + fcols.fitemindex:= int1; + if deo_selectonly in foptions then begin +// fcols.fitemindex:= int1; + fcols.fkeyvalue:= ''; + setdropdowntext('',true,false,akey); + end + else begin + setdropdowntext(fintf.geteditor.text,true,false,akey); + end; + end + else begin + if (int1 < 0) and (deo_selectonly in foptions) then begin + setdropdowntext(fintf.geteditor.text,false,true,akey); + //editor.undo + end; + end; + end; + if index <> -1 then begin + fcols.fitemindex:= int1; + end; + if int1 >= 0 then begin + fcols.fkeyvalue:= valuelist[int1]; + setdropdowntext(fcols.fkeyvalue,index <> - 1,index = -1,akey); + end; +end; + +function tcustomdropdownlistcontroller.getdropdownwidget: twidget; +begin + result:= fdropdownlist; +end; + +procedure tcustomdropdownlistcontroller.setvaluecol(const avalue: integer); +begin + if fvaluecol <> avalue then begin + fcols.checkindex(avalue); + fvaluecol:= avalue; + valuecolchanged; + end; +end; + +procedure tcustomdropdownlistcontroller.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (sender = fimagelist) then begin + case event of + oe_destroyed: begin + fimagelist:= nil; + imagelistchanged; + end; + oe_changed: begin + imagelistchanged; + end; + end; + end; +end; + +procedure tcustomdropdownlistcontroller.setimagelist(const avalue: timagelist); +begin + if fimagelist <> avalue then begin + setlinkedvar(avalue,tmsecomponent(fimagelist)); + imagelistchanged; + end; +end; + +procedure tcustomdropdownlistcontroller.valuecolchanged; +begin + //dummy +end; + +procedure tcustomdropdownlistcontroller.selectnone(const akey: keyty); +begin + itemselected(-2,akey); +end; + +procedure tcustomdropdownlistcontroller.resetselection; +begin + fcols.fitemindex:= -1; +end; + +function tcustomdropdownlistcontroller.reloadlist: integer; +begin + result:= fdropdownlist.updatevisiblerows(); +end; + +function tcustomdropdownlistcontroller.getremoterowcount: integer; +begin + result:= 0; //dummy +end; + +procedure tcustomdropdownlistcontroller.internaldropdown; +begin + inherited; +end; + +procedure tcustomdropdownlistcontroller.dostatread(const reader: tstatreader); +var + ar1: integerarty; + int1: integer; +begin + if deo_savestate in foptions then begin + ar1:= reader.readarray('dropdowncolwidths',integerarty(nil)); + for int1:= 0 to high(ar1) do begin + if int1 > high(fcols.fitems) then begin + break; + end; + tdropdowncol(fcols.fitems[int1]).fwidth:= ar1[int1]; + end; + end; +end; + +procedure tcustomdropdownlistcontroller.dostatwrite(const writer: tstatwriter); +var + int1: integer; + ar1: integerarty; +begin + if deo_savestate in foptions then begin + setlength(ar1,fcols.count); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= tdropdowncol(fcols.fitems[int1]).fwidth; + end; + writer.writearray('dropdowncolwidths',ar1); + end; +end; + +procedure tcustomdropdownlistcontroller.imagelistchanged; +begin + idropdownlist(fintf).imagelistchanged; +end; + +procedure tcustomdropdownlistcontroller.setimageframe(const avalue: framety); +begin + fimageframe:= avalue; + imagelistchanged; +end; + +procedure tcustomdropdownlistcontroller.setimageframe_left(const avalue: integer); +begin + fimageframe.left:= avalue; + imagelistchanged; +end; + +procedure tcustomdropdownlistcontroller.setimageframe_top(const avalue: integer); +begin + fimageframe.top:= avalue; + imagelistchanged; +end; + +procedure tcustomdropdownlistcontroller.setimageframe_right(const avalue: integer); +begin + fimageframe.right:= avalue; + imagelistchanged; +end; + +procedure tcustomdropdownlistcontroller.setimageframe_bottom(const avalue: integer); +begin + fimageframe.bottom:= avalue; + imagelistchanged; +end; + +function tcustomdropdownlistcontroller.getfixcolclass: dropdownfixcolclassty; +begin + result:= nil; //dummy +end; + +procedure tcustomdropdownlistcontroller.dobeforedropdown; +begin + if deo_livefilter in foptions then begin + with fintf.geteditor do begin + if not canundo then begin + text:= ''; + end; + end; + end; + inherited; +end; + +procedure tcustomdropdownlistcontroller.doafterclosedropdown; +begin + if ftimer <> nil then begin + ftimer.enabled:= false; //cancel pending updates + end; + inherited; +end; + +function tcustomdropdownlistcontroller.getdelay: integer; +begin + result:= 0; + if ftimer <> nil then begin + result:= ftimer.interval div 1000; + if result = 0 then begin + result:= -1; + end; + end; +end; + +procedure tcustomdropdownlistcontroller.setdelay(avalue: integer); +begin + if avalue = 0 then begin + freeandnil(ftimer); + end + else begin + if avalue < 0 then begin + avalue:= 0; + end; + avalue:= avalue * 1000; + if ftimer = nil then begin + ftimer:= tsimpletimer.create(avalue,@dotimer,false,[to_single]); + end; + ftimer.interval:= avalue; + end; +end; + +{ tnocolsdropdownlistcontroller } + +constructor tnocolsdropdownlistcontroller.create(const intf: idropdownlist); +begin + inherited; + cols.nostreaming:= true; +end; + +function tnocolsdropdownlistcontroller.getbuttonframeclass: dropdownbuttonframeclassty; +begin + result:= tdropdownmultibuttonframe; +end; + +{ tdropdownlistcontroller } + +constructor tdropdownlistcontroller.create(const intf: idropdownlist); +begin + inherited; + cols.nostreaming:= false; +end; + +{ tmbdropdownlistcontroller } + +function tmbdropdownlistcontroller.getbuttonframeclass: dropdownbuttonframeclassty; +begin + result:= tdropdownmultibuttonframe; +end; + +{ tdropdownstringcol } + +destructor tdropdownstringcol.destroy; +begin + fdata:= nil; + inherited; +end; + +function tdropdownstringcol.createdatalist: tdatalist; +begin + result:= nil; +end; + +constructor tdropdownstringcol.create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); +begin + inherited; + include(foptions,co_readonly); +end; + +{ titemselectedevent } + +constructor titemselectedevent.create(const dest: tmsecomponent; const arow: integer); +begin + frow:= arow; + inherited create(self); +end; + +{ tdropdownlist } + +constructor tdropdownlist.create( + const acontroller: tcustomdropdownlistcontroller; + const acols : tdropdowncols; + const afixcolclass: dropdownfixcolclassty); +var + aparent: twidget; + widget1: twidget; + col1: colorty; + int1: integer; +begin + fcontroller:= acontroller; + aparent:= fcontroller.getwidget; + inherited create(nil); + fdatacols.innerframe:= defaultdropdowncellinnerframe; + visible:= false; + beginupdate; + try + datarowlinewidth:= acontroller.fdatarowlinewidth; + datarowlinecolor:= acontroller.fdatarowlinecolor; + exclude(foptionsgrid,og_focuscellonenter); + ffocusedcell.col:= 0; + if fcontroller.color = cl_default then begin + widget1:= aparent; + repeat + col1:= widget1.parentcolor; + widget1:= widget1.parentwidget; + until (col1 <> cl_transparent) or (widget1 = nil); + if col1 = cl_transparent then begin + col1:= cl_background; + end; + color:= col1; + end + else begin + color:= fcontroller.color; + end; + tcustomframe1(fframe).fi.levelo:= 0; + tcustomframe1(fframe).fi.framewidth:= 1; + tcustomframe1(fframe).fi.colorframe:= cl_black; + if fcontroller.fframetemplate <> nil then begin + fframe.template:= fcontroller.fframetemplate; + end; + if (fcontroller.colorclient <> cl_default) and (fframe <> nil) then begin + fframe.colorclient:= fcontroller.colorclient; + end; + if fcontroller.ffacetemplate <> nil then begin + createface(); + fface.template:= fcontroller.ffacetemplate; + end; + fdatacols.options:= fdatacols.options + [co_focusselect,co_readonly]; + font:= twidget1(aparent).getfont; + initcols(acols); + if afixcolclass <> nil then begin + tcustomframe1(fframe).updatestate(); + synctofontheight(); + ffixcols.add(afixcolclass.create(self,ffixcols,fcontroller)); + end; + tcustomframe1(fframe).updatestate(); + synctofontheight(); + if acontroller.imagelist <> nil then begin + ffixcols.add(timagefixcol.create(self,ffixcols,fcontroller)); + int1:= fcontroller.imagelist.height + fcontroller.fimageframe.top + + fcontroller.fimageframe.bottom; + if datarowheight < int1 then begin + datarowheight:= int1; + end; + end; + finally + endupdate; + end; +end; + +destructor tdropdownlist.destroy; +begin + killrepeater; + inherited; +end; + +procedure tdropdownlist.initcols(const acols: tdropdowncols); +var + int1,int2: integer; + col1: tdropdowncol; + frata1: tframecomp; + fata1: tfacecomp; +begin + if acols.font <> nil then begin + createfont(); + font.assign(acols.font); + end; + if acols.fontselect <> nil then begin + fdatacols.createfontselect(); + datacols.fontselect.assign(acols.fontselect); + end; + if (acols.count > 0) and (acols.fdatacols.count > 0) then begin + if deo_colsizing in fcontroller.options then begin + optionsgrid:= optionsgrid + [og_colsizing]; + end; + int2:= acols.fdatacols.maxrowcount; + rowcount:= int2; + fdatacols.count:= acols.count; + for int1:= 0 to acols.count - 1 do begin + col1:= acols[int1]; + with tstringcol1(fdatacols[int1]) do begin + if acols.fdatacols.count > int1 then begin + fdata:= acols.fdatacols[int1]; + fdata.count:= int2; + end; +// fdata:= col1.fdata; + options:= col1.foptions; + optionsedit:= defaultstringcoleditoptions - [scoe_autoselect,scoe_autoselectonfirstclick]; + width:= col1.fwidth; + linewidth:= col1.flinewidth; + linecolor:= col1.flinecolor; + textflags:= col1.ftextflags; + passwordchar:= col1.passwordchar; + textflagsactive:= col1.ftextflags; + if col1.fcolor <> cl_default then begin + color:= col1.fcolor; + end; + if col1.fcolorselect <> cl_default then begin + colorselect:= col1.fcolorselect; + end; + { + if col1.ffontcolorselect <> cl_default then begin + createfontselect; + fontselect.assign(getfont); + fontselect.color:= col1.ffontcolorselect; + end; + } + if col1.font <> nil then begin + createfont(); + font.assign(col1.font); + end; + if col1.fontselect <> nil then begin + createfontselect(); + fontselect.assign(col1.fontselect); + end; + frata1:= col1.fframetemplate; + if frata1 = nil then begin + frata1:= acols.fframetemplate; + end; + if frata1 <> nil then begin + createframe(); + fframe.template:= frata1; + end; + fata1:= col1.ffacetemplate; + if fata1 = nil then begin + fata1:= acols.ffacetemplate; + end; + if frata1 <> nil then begin + createface(); + fface.template:= fata1; + end; + end; + if col1.caption <> '' then begin + fixrows.count:= 1; + with fixrows[-1] do begin + captions.count:= int1 + 1; + captions[int1].caption:= col1.caption; + end; + end; + end; + end; +end; + +procedure tdropdownlist.createdatacol(const index: integer; + out item: tdatacol); +begin + item:= tdropdownstringcol.create(self,fdatacols); +end; + +procedure tdropdownlist.doactivate; +begin + capturemouse; + inherited; + fcontroller.dropdownactivated; +end; + +procedure tdropdownlist.dodeactivate; +begin + inherited; + fcontroller.dropdowndeactivated; +end; + +procedure tdropdownlist.dokeydown(var info: keyeventinfoty); +begin + with info do begin + if shiftstate*shiftstatesrepeatmask = [] then begin + include(eventstate,es_processed); + case key of + key_return,{key_enter,}key_tab: begin + if ffocusedcell.row < 0 then begin + itemselected(-2,key); //nil selection + end + else begin + itemselected(ffocusedcell.row,key); + end; + end; + key_up,key_down: begin + if (focusedcell.row < 0) and (frowcount > 0) then begin + if key = key_down then begin + row:= 0; + end + else begin + row:= rowcount -1; + end; + end + else begin + exclude(eventstate,es_processed); + end; + end; + key_escape: begin + canceldropdown; + exit; + end; + else begin + exclude(eventstate,es_processed); + end; + end; + end; + if not (es_processed in eventstate) then begin + fcontroller.dropdownkeydown(info); + if not (es_processed in eventstate) then begin + inherited; + end; + end; + end; +end; + +procedure tdropdownlist.mouseevent(var info: mouseeventinfoty); +begin + inherited; + if (info.eventkind = ek_buttonpress) and + not pointinrect(translatewidgetpoint(info.pos,self,nil), + fwidgetrect) then begin + canceldropdown; + end; +end; + +procedure tdropdownlist.setactiveitem(const aitemindex: integer); +begin + focuscell(makegridcoord(0,aitemindex)); +end; + +function tdropdownlist.getassistiveparent(): iassistiveclient; +begin + result:= twidget1(fcontroller.fintf.getwidget()).getiassistiveclient(); +end; + +function tdropdownlist.dropdownheight: integer; +var + int1,int2: integer; +begin + int2:= fdatacols.rowstate.visiblerowcount; + if fdropdownrowcount = 0 then begin + int1:= int2; + end + else begin + int1:= fdropdownrowcount; + end; + if (int1 > int2){ and not + (deo_livefilter in fcontroller.foptions)} then begin + int1:= int2; + end; + if int1 = 0 then begin + result:= ystep div 2; + end + else begin + result:= int1 * ystep; + end; + if fixrows.count > 0 then begin + with fixrows[-1] do begin + result:= result+ height + linewidth; + end; + end; + result:= result + fframe.paintframedim.cy; +end; + +procedure tdropdownlist.show(awidth: integer; const arowcount: integer; + var aitemindex: integer; afiltertext: msestring); +var + rect1: rectty; + int1: integer; +begin + fstate:= fstate * [gs_isdb]; + bounds_cx:= awidth; + rect1:= widgetrect; + rect1.cx:= awidth; + fdropdownrowcount:= arowcount; +// rect1.cy:= dropdownheight; +// fcontroller.updatedropdownpos(rect1); + ffiltertext:= afiltertext; + if deo_livefilter in fcontroller.foptions then begin + int1:= updatevisiblerows(); + if afiltertext <> '' then begin + setactiveitem(int1); + end + else begin + setactiveitem(aitemindex); + end; + end + else begin + if (aitemindex = -1) and (ffiltertext <> '') then begin + application.beginnoignorewaitevents; + try + locate(ffiltertext); + finally + application.endnoignorewaitevents; + end; + end + else begin + setactiveitem(aitemindex); + end; + end; + rect1.cy:= dropdownheight; + fcontroller.updatedropdownpos(rect1); + if inherited show(true,fcontroller.getwidget.window) = mr_ok then begin + aitemindex:= fselectedindex; + end + else begin + aitemindex:= -1; + end; +end; + +procedure tdropdownlist.updatewindowinfo(var info: windowinfoty); +begin + inherited; + with info do begin + options:= options + [wo_popup]; + transientfor:= fcontroller.getwidget.window; + end; +end; + +procedure tdropdownlist.itemselected(const index: integer; const akey: keyty); +begin + fselectedindex:= index; + fcontroller.fselectkey:= akey; + window.modalresult:= mr_ok; +end; + +function tdropdownlist.getassistiveflags(): assistiveflagsty; +begin + result:= inherited getassistiveflags(); + if ownswindow then begin + result:= result + [asf_popup]; + end; +end; + +procedure tdropdownlist.docellevent(var info: celleventinfoty); +var + hintinfo: hintinfoty; +begin + with info do begin + if iscellclick(info,[ccr_buttonpress],[],keyshiftstatesmask) then begin + itemselected(cell.row,key_none); + end + else begin + if (deo_cliphint in fcontroller.foptions) and + (eventkind = cek_firstmousepark) and + textclipped(cell) then begin + application.inithintinfo(hintinfo,self); + hintinfo.caption:= tdropdownstringcol(self[cell.col]).getrowtext(cell.row); + application.showhint(self,hintinfo); + include(mouseeventinfopo^.eventstate,es_processed); + end + else begin + inherited; + end; + end; + end; +end; + +procedure tdropdownlist.canceldropdown; +begin + itemselected(-1,key_none); //canceled +end; + +procedure tdropdownlist.clientmouseevent(var info: mouseeventinfoty); +begin + if (info.eventkind = ek_mousemove) and not canassistive() then begin + if dls_mousemoved in fdropdownstate then begin + if fobjectpicker.active then begin + killrepeater(); + end + else begin + with fdatarecty do begin + if (info.pos.y < y + mouseautoscrollheight) and + (info.pos.y >= y) then begin + startrepeater(false); + end + else begin + if info.pos.y >= y + cy - mouseautoscrollheight then begin + startrepeater(true); + end + else begin + killrepeater(); + end; + end; + end; + end; + end + else begin + if not (dls_firstmousemoved in fdropdownstate) then begin + ffirstmousepos:= info.pos; + include(fdropdownstate,dls_firstmousemoved); + end + else begin + if distance(info.pos,ffirstmousepos) > 3 then begin + include(fdropdownstate,dls_mousemoved); + end; + end; + end; + end + else begin + if info.eventkind = ek_clientmouseleave then begin + killrepeater; + end; + end; + inherited; +end; + +function tdropdownlist.getkeystring(const aindex: integer): msestring; +begin + if folded and rowhidden[aindex] then begin + result:= ''; + end + else begin + with tstringcol(fdatacols[0]) do begin + result:= items[aindex]; + end; + end; +end; + +function tdropdownlist.getkeystringnohidden(const aindex: integer): msestring; +begin + with tstringcol(fdatacols[0]) do begin + result:= items[aindex]; + end; +end; + +function tdropdownlist.locate(const filter: msestring): boolean; +var + int1: integer; + opt1: locatestringoptionsty; + co1: gridcoordty; +begin + if (rowcount > 0) and (fdatacols.count > 0) then begin + int1:= focusedcell.row; + opt1:= []; + if dlo_casesensitive in foptions1 then begin + opt1:= [lso_casesensitive]; + end; + if dlo_posinsensitive in foptions1 then begin + include(opt1,lso_posinsensitive); + end; + result:= locatestring(filter,{$ifdef FPC}@{$endif}getkeystring,opt1, + fdatacols[0].datalist.count,int1); + if result then begin + co1:= makegridcoord(ffocusedcell.col,int1); + showcell(co1,cep_top); + focuscell(co1); + end + else begin + focuscell(makegridcoord(ffocusedcell.col,-1)); + end; + end + else begin + result:= false; + end; +end; + +function tdropdownlist.updatevisiblerows(): integer; +var + int1,int2,int3,count1: integer; + opt1: locatestringoptionsty; + bo1: boolean; + s1: msestring; +begin + result:= invalidaxis; + if (rowcount > 0) and (fdatacols.count > 0) then begin + if deo_customfilter in fcontroller.options then begin + result:= 0; + end + else begin + folded:= true; + beginupdate; + int1:= 0; + opt1:= [lso_nodown,lso_noexact]; + if dlo_casesensitive in foptions1 then begin + include(opt1,lso_casesensitive); + s1:= ffiltertext; + end + else begin + include(opt1,lso_filterisuppercase); + s1:= mseuppercase(ffiltertext); + end; + if dlo_posinsensitive in foptions1 then begin + include(opt1,lso_posinsensitive); + end; + count1:= fdatacols[0].datalist.count; + repeat + int2:= int1; + bo1:= locatestring(s1,{$ifdef FPC}@{$endif}getkeystringnohidden, + opt1,count1,int1); + if not bo1 then begin + int1:= fdatacols[0].datalist.count; + end; + for int3:= int2 to int1 - 1 do begin + rowhidden[int3]:= true; + end; + if bo1 then begin + rowhidden[int1]:= false; + if result = invalidaxis then begin + result:= int1; + end; + inc(int1); + end; + until not bo1 or (int1 >= count1); + endupdate; + end; + end; +end; + +procedure tdropdownlist.setfiltertext(const Value: msestring); +var + li1: tdatalist; + rect1: rectty; + int1: integer; +begin + ffiltertext:= Value; + if dlo_livefilter in foptions1 then begin + int1:= fcontroller.reloadlist(); + if (fdatacols.count > 0) then begin + li1:= tdropdownstringcol(fdatacols[0]).fdata; + if li1 <> nil then begin + rowcount:= li1.count; + end; + end; + rect1:= widgetrect; + rect1.cy:= dropdownheight; + fcontroller.updatedropdownpos(rect1); + invalidate; + row:= int1; + setupeditor(ffocusedcell,true); + end + else begin + locate(ffiltertext); + end; +end; + +procedure tdropdownlist.killrepeater; +begin + freeandnil(frepeater); +end; + +procedure tdropdownlist.startrepeater(up: boolean); +begin + if frepeater = nil then begin + frepeater:= tsimpletimer.create(100000,{$ifdef FPC}@{$endif}dorepeat,true,[]); + end; + if up then begin + include(fdropdownstate,dls_scrollup); + end + else begin + exclude(fdropdownstate,dls_scrollup); + end; +end; + +procedure tdropdownlist.dorepeat(const sender: tobject); +begin + if dls_scrollup in fdropdownstate then begin + rowdown(fca_focusin); + end + else begin + rowup(fca_focusin); + end; +end; + +procedure tdropdownlist.updatelayout; +var + int1: integer; +begin + try + inc(fupdatelayoutcount); + if fupdatelayoutcount < 16 then begin + inherited; + if fcontroller.width = -1 then begin + int1:= fcontroller.getautowidth; + if width <> int1 then begin + width:= int1; + updatelayout; + end; + end; + end; + finally + dec(fupdatelayoutcount); + end; +end; + +{ tdropdownbutton } + +constructor tdropdownbutton.create(aowner: tobject); +begin + inherited; + finfo.ca.imagenr:= ord(stg_arrowdownsmall); +end; + +{ tdropdownfixcol } + +constructor tdropdownfixcol.create(const agrid: tcustomgrid; + const aowner: tgridarrayprop; + const acontroller: tcustomdropdownlistcontroller); +begin + fcontroller:= acontroller; + inherited create(agrid,aowner); + linewidth:= 0; + color:= acontroller.color; +end; + +{ timagefixcol } + +constructor timagefixcol.create(const agrid: tcustomgrid; + const aowner: tgridarrayprop; + const acontroller: tcustomdropdownlistcontroller); +begin + inherited create(agrid,aowner,acontroller); + fimagelist:= acontroller.imagelist; + fimageframe:= acontroller.imageframe; + width:= fimagelist.width + acontroller.fimageframe.left + + acontroller.fimageframe.right; + fcolorselect:= acontroller.cols.colorselect; +end; + +procedure timagefixcol.drawcell(const canvas: tcanvas); +begin + inherited; + with cellinfoty(canvas.drawinfopo^) do begin + fimagelist.paint(canvas,cell.row,deflaterect(rect,fimageframe), + [al_ycentered]); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/editwidgets/mseedit.pas b/mseide-msegui/lib/common/editwidgets/mseedit.pas new file mode 100644 index 0000000..69326ed --- /dev/null +++ b/mseide-msegui/lib/common/editwidgets/mseedit.pas @@ -0,0 +1,2437 @@ +{ MSEgui Copyright (c) 1999-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseedit; + +{$ifdef FPC} + {$mode objfpc}{$h+}{$interfaces corba} +{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} + +interface +uses + msegui,mseeditglob,msegraphics,msegraphutils,msedatalist, + mseevent,mseglob,mseguiglob,msestat,msestatfile,mserichstring, + mseinplaceedit,msegrids,msetypes,mseshapes,msewidgets, + msedrawtext,classes,mclasses,msereal,mseclasses,msearrayprops, + msebitmap,msemenus,msetimer,mseactions,msekeyboard, + msesimplewidgets,msepointer,msestrings,msescrollbar,mseassistiveclient + {$ifdef mse_with_ifi},mseifiglob{$endif}; + +const + defaulteditwidgetoptions = defaultoptionswidget + {+[ow_fontglyphheight,ow_autoscale]}; + defaulteditwidgetoptions1 = defaultoptionswidget1+ + [ow1_fontglyphheight,ow1_autoscale]; + defaulteditwidgetwidth = 100; + defaulteditwidgetheight = 20; + defaulttextflags = [tf_ycentered,tf_noselect]; + defaulttextflagsactive = [tf_ycentered]; + defaulttextflagsnoycentered = defaulttextflags - [tf_ycentered]; + defaulttextflagsactivenoycentered = defaulttextflagsactive - [tf_ycentered]; + defaulttextflagsempty = [tf_ycentered,tf_xcentered]; + +type + + teditframe = class(tcustomcaptionframe) + protected + function actualcolorclient(): colorty override; + public + constructor create(const aintf: icaptionframe); + published + property options; + property levelo default -2; + property leveli; + property framewidth; + property colorframe; + property colorframeactive; + property colorframedisabled; + property colorframemouse; + property colorframeclicked; + property colorframedefault; + property colordkshadow; + property colorshadow; + property colorlight; + property colorhighlight; + property colordkwidth; + property colorhlwidth; + property hiddenedges; + property framei_left default 1; + property framei_top default 1; + property framei_right default 1; + property framei_bottom default 1; + property frameo_left; + property frameo_top; + property frameo_right; + property frameo_bottom; + + + property frameimage_list; + property frameimage_left; + property frameimage_top; + property frameimage_right; + property frameimage_bottom; + property frameimage_offset; + property frameimage_offset1; + property frameimage_offsetdisabled; + property frameimage_offsetmouse; + property frameimage_offsetclicked; + property frameimage_offsetactive; + property frameimage_offsetfocused; +{ + property frameimage_offsetactivemouse; + property frameimage_offsetactiveclicked; +} + property frameface_list; + property frameface_offset; + property frameface_offset1; + property frameface_offsetdisabled; + property frameface_offsetmouse; + property frameface_offsetclicked; + property frameface_offsetactive; + property frameface_offsetfocused; +{ + property frameface_offsetactivemouse; + property frameface_offsetactiveclicked; +} + property colorclient {default cl_foreground}; + property caption; + property captiontextflags; + property captionpos; + property captiondist; + property captionoffset; + property focusrectdist; + property extraspace; + property imagedist; + property imagedist1; + property imagedist2; + property font; + property localprops; //before template + property localprops1; //before template + property template; + end; + + tscrolleditframe = class(tcustomthumbtrackscrollframe) + protected + function actualcolorclient(): colorty override; + public + constructor create(const aintf: iscrollframe; const scrollintf: iscrollbar); + published + property options; + property optionsscroll; + property dragbuttons; + property levelo default -2; + property leveli; + property framewidth; + property colorframe; + property colorframeactive; + property colorframedisabled; + property colorframemouse; + property colorframeclicked; + property colorframedefault; + property colordkshadow; + property colorshadow; + property colorlight; + property colorhighlight; + property colordkwidth; + property colorhlwidth; + property hiddenedges; + property colorclient {default cl_foreground}; + property framei_left default 1; + property framei_top default 1; + property framei_right default 1; + property framei_bottom default 1; + property frameo_left; + property frameo_top; + property frameo_right; + property frameo_bottom; + + property frameimage_list; + property frameimage_left; + property frameimage_top; + property frameimage_right; + property frameimage_bottom; + property frameimage_offset; + property frameimage_offset1; + property frameimage_offsetdisabled; + property frameimage_offsetmouse; + property frameimage_offsetclicked; + property frameimage_offsetactive; + property frameimage_offsetfocused; +{ + property frameimage_offsetactivemouse; + property frameimage_offsetactiveclicked; +} + property frameface_list; + property frameface_offset; + property frameface_offset1; + property frameface_offsetdisabled; + property frameface_offsetmouse; + property frameface_offsetclicked; + property frameface_offsetactive; + property frameface_offsetfocused; +{ + property frameface_offsetactivemouse; + property frameface_offsetactiveclicked; +} + property optionsskin; + + property caption; + property captiontextflags; + property captionpos; + property captiondist; + property captionoffset; + property focusrectdist; + property extraspace; + property imagedist; + property imagedist1; + property imagedist2; + property font; + property localprops; //before template + property localprops1; //before template + property template; + property sbhorz; + property sbvert; + end; + + tscrollboxeditframe = class(tcustomscrollboxframe) + protected + function actualcolorclient(): colorty override; + public + constructor create(const aintf: iscrollframe; const owner: twidget); + published + property levelo default -2; + property leveli; + property framewidth; + property colorframe; + property colorframeactive; + property colorframedisabled; + property colorframemouse; + property colorframeclicked; + property colorframedefault; + property colordkshadow; + property colorshadow; + property colorlight; + property colorhighlight; + property colordkwidth; + property colorhlwidth; + property hiddenedges; + property framei_left default 1; + property framei_top default 1; + property framei_right default 1; + property framei_bottom default 1; + property sbhorz; + property sbvert; + property colorclient {default cl_foreground}; + property caption; + property captiontextflags; + property captionpos; + property captiondist; + property captionoffset; + property font; + property localprops; //before template + property localprops1; //before template + property template; + end; + + buttonactionty = (ba_none,ba_buttonpress,ba_buttonrelease,ba_click); + ibutton = interface(inullinterface) + procedure buttonaction(var action: buttonactionty; const buttonindex: integer); + end; + buttoneventty = procedure(const sender: tobject; var action: buttonactionty; + const buttonindex: integer) of object; + framebuttonoptionty = + (fbo_left,fbo_invisible,fbo_inactiveinvisible, + fbo_disabled,fbo_enabled, //overrides frame readonly state + fbo_executeonclientdblclick, + fbo_flat,fbo_noanim,fbo_nomouseanim,fbo_noclickanim,fbo_nofocusanim); + framebuttonoptionsty = set of framebuttonoptionty; + + tcustombuttonsframe = class; + + tframebutton = class(townedeventpersistent,iframe,iimagelistinfo) + private + fbuttonwidth: integer; + foptions: framebuttonoptionsty; + fonexecute: notifyeventty; + faction: taction; + fshortcut: shortcutty; + procedure setbuttonwidth(const Value: integer); + procedure setoptions(const Value: framebuttonoptionsty); + procedure optionstostate(); + procedure changed; + function getleft: boolean; + procedure setleft(const Value: boolean); + function getvisible: boolean; + procedure setvisible(const Value: boolean); + function getenabled: boolean; + procedure setenabled(const Value: boolean); + procedure setcolor(const avalue: colorty); + procedure setcolorglyph(const avalue: colorty); + procedure setimagelist(const Value: timagelist); + procedure setimagenr(const avalue: imagenrty); + procedure setimagenrdisabled(const avalue: imagenrty); + function getface: tface; + procedure setface(const avalue: tface); + function getframe: tframe; + procedure setframe(const avalue: tframe); + //iframe + procedure setframeinstance(instance: tcustomframe); + procedure setstaticframe(value: boolean); + function getstaticframe: boolean; + function getwidgetrect: rectty; + function getcomponentstate: tcomponentstate; + function getmsecomponentstate: msecomponentstatesty; + procedure scrollwidgets(const dist: pointty); + procedure clientrectchanged; + procedure invalidate; + procedure invalidatewidget; + procedure invalidaterect(const rect: rectty; const org: originty = org_client; + const noclip: boolean = false); + function getwidget: twidget; + function getframestateflags: framestateflagsty; virtual; + function getimagelist: timagelist; + procedure setaction(const avalue: taction); + protected + fframerect: rectty; + finfo: shapeinfoty; + fframe: tframe; + freadonly: boolean; //for checkreadonlystate of tbuttonframe + procedure doexec(); + procedure mouseevent(var info: mouseeventinfoty; + const intf: iframe; const buttonintf: ibutton; + const index: integer); + public + constructor create(aowner: tobject); override; + destructor destroy; override; + procedure createface; + procedure createframe; + procedure checktemplate(const sender: tobject); + procedure updatewidgetstate(const awidget: twidget); + procedure assign(source: tpersistent); override; + property visible: boolean read getvisible write setvisible default true; + property enabled: boolean read getenabled write setenabled default true; + property left: boolean read getleft write setleft default false; + published + property width: integer read fbuttonwidth write setbuttonwidth default 0; + property color: colorty read finfo.color write setcolor default cl_default; + property colorglyph: colorty read finfo.ca.colorglyph + write setcolorglyph default cl_default; + //cl_default maps to cl_glyph + property face: tface read getface write setface; + property frame: tframe read getframe write setframe; + property imagelist: timagelist read finfo.ca.imagelist write setimagelist; + property imagenr: imagenrty read finfo.ca.imagenr write setimagenr + default -1; + property imagenrdisabled: imagenrty read finfo.imagenrdisabled + write setimagenrdisabled default -2; //grayed + property options: framebuttonoptionsty read foptions write setoptions + default []; + property shortcut: shortcutty read fshortcut write fshortcut + default ord(key_none) ; + property action: taction read faction write setaction; + property onexecute: notifyeventty read fonexecute write fonexecute; + //executed after action execute + end; + + tstockglyphframebutton = class(tframebutton) + private + function isimageliststored: boolean; + procedure setimagelist(const Value: timagelist); + public + constructor create(aowner: tobject); override; + published + property imagelist read finfo.ca.imagelist write setimagelist + stored isimageliststored; + end; + + framebuttonclassty = class of tframebutton; + + tframebuttons = class(townedeventpersistentarrayprop) + private + function getitems1(const index: integer): tframebutton; + protected + procedure dosizechanged; override; + procedure checkcount(var acount: integer); override; + procedure updatestate; + public + constructor create(const aowner: tcustombuttonsframe; + const buttonclass: framebuttonclassty); + class function getitemclasstype: persistentclassty; override; + procedure updatewidgetstate; + function wantmouseevent(const apos: pointty): boolean; + procedure dokeydown(var info: keyeventinfoty); + public + property items[const index: integer]: tframebutton read getitems1; default; + procedure checktemplate(const sender: tobject); + end; + + tcustombuttonsframe = class(teditframe) + private + fbuttons: tframebuttons; + procedure setbuttons(const Value: tframebuttons); + protected + factivebutton: integer; + fbuttonintf: ibutton; + procedure getpaintframe(var aframe: framety); override; + function getbuttonclass: framebuttonclassty; virtual; + procedure updatestate; override; + procedure internalpaintoverlay(const canvas: tcanvas; + const arect: rectty) override; + procedure dokeydown(var info: keyeventinfoty) override; + public + constructor create(const aintf: icaptionframe; const buttonintf: ibutton); + reintroduce; virtual; + destructor destroy; override; + procedure checktemplate(const sender: tobject); override; + function buttonframe: framety; + procedure updatemousestate(const sender: twidget; + const info: mouseeventinfoty); override; + procedure updatewidgetstate; override; + procedure mouseevent(var info: mouseeventinfoty); + procedure initgridframe; override; + property buttons: tframebuttons read fbuttons write setbuttons; + end; + + tbuttonsframe = class(tcustombuttonsframe) + published + property buttons; + end; + + tcustombuttonframe = class(tcustombuttonsframe) //has at least one button + private + protected + procedure setactivebutton(avalue: integer); + function getbutton: tframebutton; + procedure setbutton(const avalue: tframebutton); + public + constructor create(const aintf: icaptionframe; const buttonintf: ibutton); + override; + property activebutton: integer read factivebutton write setactivebutton + default 0; + property button: tframebutton read getbutton write setbutton; + end; + + tbuttonframe = class(tcustombuttonframe) + end; + + tmultibuttonframe = class(tcustombuttonframe) + published + property activebutton; + property buttons; + end; + + tcustomedit = class; + texteditedeventty = procedure(const sender: tcustomedit; + var atext: msestring) of object; + + emptyoptionty = (eo_defaulttext, //use text of tfacecontroller + eo_showfocused, //show empty_text if focused + eo_nocolorfocused); //do not show empty_color if focused + emptyoptionsty = set of emptyoptionty; + + tcustomedit = class(tpublishedwidget,iedit) + private + fonchange: notifyeventty; + fontextedited: texteditedeventty; + foncopytoclipboard: updatestringeventty; + fonpastefromclipboard: updatestringeventty; + fcursorreadonly: cursorshapety; + fonpaintimage: painteventty; + fempty_text: msestring; + fempty_textflags: textflagsty; + fempty_textcolor: colorty; + fempty_textcolorbackground: colorty; + fempty_fontstyle: fontstylesty; + fempty_color: colorty; + fempty_options: emptyoptionsty; + function getmaxlength: integer; + function getpasswordchar: msechar; + procedure setpasswordchar(const Value: msechar); + function getoldtext: msestring; + procedure settextflags(const value: textflagsty); + procedure settextflagsactive(const value: textflagsty); + function getcaretwidth: integer; + procedure setcaretwidth(const Value: integer); + procedure setcursorreadonly(const avalue: cursorshapety); + function getoptionsedit1: optionsedit1ty; + procedure setempty_text(const avalue: msestring); + procedure setempty_textflags(const avalue: textflagsty); + procedure setempty_textcolor(const avalue: colorty); + procedure setempty_textcolorbackground(const avalue: colorty); + procedure setempty_fontstyle(const avalue: fontstylesty); + procedure setempty_color(const avalue: colorty); + protected + ftextflags: textflagsty; + ftextflagsactive: textflagsty; + feditor: tinplaceedit; + foptionsedit: optionseditty; + fstate: dataeditstatesty; + function gettext: msestring virtual; + procedure settext(const avalue: msestring) virtual; +// procedure setcurrenttext(const avalue: msestring); + function getreadonly: boolean; virtual; + procedure setreadonly(const avalue: boolean); virtual; + procedure setmaxlength(const avalue: integer); + procedure updatetextflags; virtual; + function getedittext: msestring; virtual; + procedure updateedittext(const force: boolean); + procedure updateemptytext(); + procedure updateflagtext(var avalue: msestring); + function geteditor: tinplaceedit; + function geteditfont: tfont; virtual; + function getinnerframe: framety; virtual; + function geteditframe: framety; virtual; + procedure gettextrects(out outer: rectty; out inner: rectty); + procedure setupeditor; virtual; + function getformat(): formatinfoarty virtual; + procedure internalcreateframe; override; + procedure clientrectchanged; override; + procedure getautopaintsize(var asize: sizety); override; + procedure fontchanged; override; + procedure enabledchanged; override; + procedure dragstarted; override; + function navigrect: rectty; override; + + class function classskininfo: skininfoty; override; + + //interface to inplaceedit + procedure dokeydown(var info: keyeventinfoty); override; + procedure clientmouseevent(var info: mouseeventinfoty); override; + procedure updatepopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); override; + procedure doactivate; override; + procedure dodeactivate; override; + procedure dofocus; override; + procedure dodefocus; override; + procedure dopaintforeground(const canvas: tcanvas); override; + procedure dopaintbackground(const canvas: tcanvas); override; + procedure paintimage(const canvas: tcanvas); virtual; + procedure painttext(const canvas: tcanvas); virtual; + function needsfocuspaint: boolean; override; +// procedure doafterpaint(const canvas: tcanvas); override; + procedure rootchanged(const aflags: rootchangeflagsty); override; + function gettextcliprect(): rectty; virtual; + procedure showhint(const aid: int32; var info: hintinfoty); override; + + procedure dochange; virtual; + procedure formatchanged; virtual; + procedure internaltextedited(const aevent: texteditedeventty); + procedure dotextedited; virtual; + procedure emptychanged; + procedure readpwchar(reader: treader); + procedure writepwchar(writer: twriter); + procedure defineproperties(filer: tfiler); override; + function verticalfontheightdelta: boolean; override; + procedure setoptionsedit1(const avalue: optionsedit1ty); virtual; + //iassistiveclient + function getassistivecaretindex(): int32 override; + function getassistiveflags(): assistiveflagsty override; + //iedit + function getoptionsedit: optionseditty; virtual; + function hasselection: boolean; virtual; + function cangridcopy: boolean; virtual; + procedure setoptionsedit(const avalue: optionseditty); virtual; + procedure updatereadonlystate; virtual; + procedure editnotification(var info: editnotificationinfoty); virtual; + procedure updatecopytoclipboard(var atext: msestring); virtual; + procedure updatepastefromclipboard(var atext: msestring); virtual; + function locatecount: integer; virtual; //number of locate values + function locatecurrentindex: integer; virtual; //index of current row + procedure locatesetcurrentindex(const aindex: integer); virtual; + function getkeystring(const aindex: integer): msestring; virtual; //locate text + function getedited: boolean; virtual; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure initnewcomponent(const ascale: real); override; + procedure changed; + procedure initfocus; + procedure synctofontheight; override; + function actualcursor(const apos: pointty): cursorshapety; override; + + property editor: tinplaceedit read feditor; + property readonly: boolean read getreadonly write setreadonly; + property optionsedit: optionseditty read getoptionsedit write setoptionsedit + default defaultoptionsedit; + property optionsedit1: optionsedit1ty read getoptionsedit1 + write setoptionsedit1 default defaultoptionsedit1; + property passwordchar: msechar read getpasswordchar + write setpasswordchar stored false default #0; + //FPC and Delphi bug: widechars are not streamed + property cursorreadonly: cursorshapety read fcursorreadonly + write setcursorreadonly default cr_default; + property maxlength: integer read getmaxlength write setmaxlength + default -1; + property text: msestring read gettext write settext; + property oldtext: msestring read getoldtext; + property textflags: textflagsty read ftextflags write settextflags + default defaulttextflags; + property textflagsactive: textflagsty read ftextflagsactive + write settextflagsactive default defaulttextflagsactive; + property font: twidgetfont read getfont write setfont stored isfontstored; + property caretwidth: integer read getcaretwidth write setcaretwidth + default defaultcaretwidth; + + property empty_options: emptyoptionsty read fempty_options + write fempty_options default []; + property empty_color: colorty read fempty_color write setempty_color + default cl_none; + property empty_font: twidgetfontempty read getfontempty write setfontempty + stored isfontemptystored; + property empty_fontstyle: fontstylesty read fempty_fontstyle + write setempty_fontstyle default []; + property empty_textflags: textflagsty read fempty_textflags + write setempty_textflags default defaulttextflagsempty; + property empty_text: msestring read fempty_text write setempty_text; + property empty_textcolor: colorty read fempty_textcolor + write setempty_textcolor default cl_none; + property empty_textcolorbackground: colorty read fempty_textcolorbackground + write setempty_textcolorbackground default cl_none; + + property onchange: notifyeventty read fonchange write fonchange; + property ontextedited: texteditedeventty read fontextedited + write fontextedited; + property oncopytoclipboard: updatestringeventty read foncopytoclipboard + write foncopytoclipboard; + property onpastefromclipboard: updatestringeventty + read fonpastefromclipboard write fonpastefromclipboard; + property onpaintimage: painteventty read fonpaintimage write fonpaintimage; + published + property optionswidget1 default defaulteditwidgetoptions1; //first! + property optionswidget default defaulteditwidgetoptions; //first! + property bounds_cx default defaulteditwidgetwidth; + property bounds_cy default defaulteditwidgetheight; + end; + + tedit = class(tcustomedit,istatfile) + private + ftimer: tsimpletimer; + fontextediteddelayed: texteditedeventty; + fstatfile: tstatfile; + fstatvarname: msestring; + fstatpriority: integer; + procedure dotimer(const sender: tobject); virtual; + function getdelay: integer; + procedure setdelay(const avalue: integer); + procedure setstatfile(const avalue: tstatfile); + protected + function gettext: msestring override; + procedure settext(const avalue: msestring) override; + procedure dotextedited; override; + procedure editnotification(var info: editnotificationinfoty); override; + procedure loaded() override; + procedure dofocus() override; + procedure dodefocus() override; + + //istatfile + procedure dostatread(const reader: tstatreader); virtual; + procedure dostatwrite(const writer: tstatwriter); virtual; + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read getstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + property delay: integer read getdelay write setdelay default 0; //ms + property ontextediteddelayed: texteditedeventty read fontextediteddelayed + write fontextediteddelayed; + property optionsedit1; //before optionsedit! + property optionsedit; + property font; + property textflags; + property textflagsactive; + property passwordchar; + + property empty_options; + property empty_color; + property empty_font; + property empty_fontstyle; + property empty_textflags; + property empty_text; + property empty_textcolor; + property empty_textcolorbackground; + + property maxlength; + property caretwidth; + property cursorreadonly; + property text; + property onchange; + property ontextedited; + property onkeydown; + property onkeyup; + property oncopytoclipboard; + property onpastefromclipboard; + end; + +implementation +uses + sysutils,msebits,msedataedits,msestockobjects,mseact, + mseassistiveserver; + +type + twidget1 = class(twidget); + tdatacol1 = class(tdatacol); +// tcustombuttonframe1 = class(tcustombuttonframe); + tinplaceedit1 = class(tinplaceedit); + +{ teditframe } + +constructor teditframe.create(const aintf: icaptionframe); +begin + inherited; + fi.levelo:= -2; + inflateframe1(fi.innerframe,1); + internalupdatestate; +end; + +function teditframe.actualcolorclient(): colorty; +begin + result:= fi.colorclient; + if result = cl_default then begin + result:= cl_foreground; + end; +end; + + +{ tscrolleditframe } + +constructor tscrolleditframe.create(const aintf: iscrollframe; + const scrollintf: iscrollbar); +begin + inherited; + fi.levelo:= -2; + inflateframe1(fi.innerframe,1); + internalupdatestate; +end; + +function tscrolleditframe.actualcolorclient(): colorty; +begin + result:= fi.colorclient; + if result = cl_default then begin + result:= cl_foreground; + end; +end; + +{ tscrollboxeditframe } + +constructor tscrollboxeditframe.create(const aintf: iscrollframe; + const owner: twidget); +begin + inherited; + fi.levelo:= -2; + inflateframe1(fi.innerframe,1); + internalupdatestate; +end; + +function tscrollboxeditframe.actualcolorclient(): colorty; +begin + result:= fi.colorclient; + if result = cl_default then begin + result:= cl_foreground; + end; +end; + +{ tframebutton } + +constructor tframebutton.create(aowner: tobject); +begin + finfo.color:= cl_default; + finfo.ca.colorglyph:= cl_default; + finfo.ca.imagenr:= -1; + finfo.imagenrdisabled:= -2; + fshortcut:= ord(key_none); + include(finfo.state,shs_widgetorg); + inherited; +end; + +destructor tframebutton.destroy; +begin + inherited; + action:= nil; //remove link + finfo.face.free; + fframe.free; +end; + +procedure tframebutton.changed; +begin + if not (csloading in tcustombuttonframe(fowner). + fintf.getwidget.componentstate) then begin + tcustombuttonframe(fowner).updatestate; + end; +end; + +procedure tframebutton.optionstostate(); +begin + updatebit(longword(finfo.state),ord(shs_invisible), + (fbo_invisible in foptions)); + updatebit(longword(finfo.state),ord(shs_disabled),fbo_disabled in foptions); + updatebit(longword(finfo.state),ord(shs_flat),fbo_flat in foptions); + updatebit(longword(finfo.state),ord(shs_noanimation),fbo_noanim in foptions); + updatebit(longword(finfo.state),ord(shs_nomouseanimation), + fbo_nomouseanim in foptions); + updatebit(longword(finfo.state),ord(shs_noclickanimation), + fbo_noclickanim in foptions); + updatebit(longword(finfo.state),ord(shs_nofocusanimation), + fbo_nofocusanim in foptions); +end; + +procedure tframebutton.setoptions(const Value: framebuttonoptionsty); +var + statebefore: shapestatesty; + optionsbefore: framebuttonoptionsty; +begin + statebefore:= finfo.state; + optionsbefore:= foptions; + card32(foptions):= setsinglebit(card32(Value),card32(foptions), + card32([fbo_disabled,fbo_enabled]));; + optionstostate(); + if (statebefore <> finfo.state) or + ((optionsbefore >< foptions) * + [fbo_left,fbo_invisible,fbo_inactiveinvisible] <> []) then begin + changed(); + end; +end; + +function tframebutton.getleft: boolean; +begin + result:= fbo_left in foptions; +end; + +procedure tframebutton.setleft(const Value: boolean); +begin + if value then begin + setoptions(foptions + [fbo_left]); + end + else begin + setoptions(foptions - [fbo_left]); + end; +end; + +function tframebutton.getvisible: boolean; +begin + result:= not (fbo_invisible in foptions); +end; + +procedure tframebutton.setvisible(const Value: boolean); +begin + if value then begin + setoptions(foptions - [fbo_invisible]); + end + else begin + setoptions(foptions + [fbo_invisible]); + end; +end; + +function tframebutton.getenabled: boolean; +begin + result:= not (fbo_disabled in foptions); +end; + +procedure tframebutton.setenabled(const Value: boolean); +begin + if value then begin + setoptions(foptions - [fbo_disabled]); + end + else begin + setoptions(foptions + [fbo_disabled]); + end; +end; + +procedure tframebutton.setbuttonwidth(const Value: integer); +begin + if fbuttonwidth <> value then begin + fbuttonwidth := Value; + changed; + end; +end; + +procedure tframebutton.setcolor(const avalue: colorty); +begin + if finfo.color <> avalue then begin + finfo.color := avalue; + changed; + end; +end; + +procedure tframebutton.setcolorglyph(const avalue: colorty); +begin + if finfo.ca.colorglyph <> avalue then begin + finfo.ca.colorglyph := avalue; + changed; + end; +end; + +procedure tframebutton.doexec(); +begin + if faction <> nil then begin + faction.execute(); + end; + if assigned(fonexecute) then begin + fonexecute(self); + end; +end; //doexe + +procedure tframebutton.mouseevent(var info: mouseeventinfoty; + const intf: iframe; const buttonintf: ibutton; const index: integer); + +var + bo1,bo2: boolean; + action1: buttonactionty; +begin + bo2:= false; + with finfo do begin + bo1:= shs_clicked in state; + if updatemouseshapestate(finfo,info,nil,nil) then begin + invalidate; + end; + if shs_clicked in state then begin + if not bo1 then begin + action1:= ba_buttonpress; + buttonintf.buttonaction(action1,index); + end; + end + else begin + if bo1 then begin + action1:= ba_buttonrelease; + buttonintf.buttonaction(action1,index); + end; + end; + if bo1 and (info.eventkind = ek_buttonrelease) then begin + action1:= ba_click; + buttonintf.buttonaction(action1,index); + if action1 = ba_click then begin + doexec(); + bo2:= true; + end; + end; + end; + if (fbo_executeonclientdblclick in foptions) and not bo2 and + (finfo.state * [shs_disabled,shs_invisible] = []) then begin + with getwidget() do begin + if iswidgetdblclicked(info) then begin + doexec(); + end; + end; + end; +end; + +procedure tframebutton.setimagelist(const Value: timagelist); +begin + setlinkedcomponent(iobjectlink(self),value,tmsecomponent(finfo.ca.imagelist)); + changed; +end; + +procedure tframebutton.setimagenr(const avalue: imagenrty); +begin + if finfo.ca.imagenr <> avalue then begin + finfo.ca.imagenr := avalue; + changed; + end; +end; + +procedure tframebutton.setimagenrdisabled(const avalue: imagenrty); +begin + if finfo.imagenrdisabled <> avalue then begin + finfo.imagenrdisabled := avalue; + changed; + end; +end; + + +procedure tframebutton.createface; +begin + if finfo.face = nil then begin + finfo.face:= tface.create(iface(tcustombuttonframe(fowner).fintf.getwidget)); + end; +end; + +procedure tframebutton.createframe; +begin + if fframe = nil then begin + tframe.create(iframe(self)); + end; +end; + +function tframebutton.getface: tface; +begin + tcustombuttonframe(fowner).fintf.getwidget.getoptionalobject(finfo.face, + {$ifdef FPC}@{$endif}createface); + result:= tface(finfo.face); +end; + +procedure tframebutton.setface(const avalue: tface); +begin + tcustombuttonframe(fowner).fintf.getwidget.setoptionalobject(avalue,finfo.face, + {$ifdef FPC}@{$endif}createface); + tcustombuttonframe(fowner).fintf.getwidget.invalidate; +end; + +function tframebutton.getframe: tframe; +begin + tcustombuttonframe(fowner).fintf.getwidget.getoptionalobject(fframe, + {$ifdef FPC}@{$endif}createframe); + result:= fframe; +end; + +procedure tframebutton.setframe(const avalue: tframe); +begin + tcustombuttonframe(fowner).fintf.getwidget.setoptionalobject(avalue,fframe, + {$ifdef FPC}@{$endif}createframe); +// tcustombuttonframe(fowner).fintf.getwidget.invalidate; + changed(); +end; + +procedure tframebutton.updatewidgetstate(const awidget: twidget); +//var +// invisiblebefore: boolean; +begin +// invisiblebefore:= ss_invisible in finfo.state; + updatewidgetshapestate(finfo,awidget,(fbo_disabled in foptions) or + freadonly and not (fbo_enabled in foptions), + {fbo_invisible in foptions,}fframe); + if (fbo_inactiveinvisible in foptions) and + (awidget.componentstate * [csdesigning,csdestroying] = []) then begin + if awidget.active xor not(shs_invisible in finfo.state) then begin + togglebit1(longword(finfo.state),ord(shs_invisible)); + tcustombuttonframe(fowner).internalupdatestate(); + end; + end; +// updatebit(longword(finfo.state),ord(ss_invisible),invisiblebefore); +end; + +procedure tframebutton.assign(source: tpersistent); +begin + if source is tframebutton then begin + with tframebutton(source) do begin + self.setoptions(foptions); + self.left:= left; + self.color:= color; + self.imagelist:= imagelist; + self.imagenr:= imagenr; + self.onexecute:= onexecute; + self.frame:= frame; + self.face:= face; + end; + end; +end; + +procedure tframebutton.checktemplate(const sender: tobject); +begin + if finfo.face <> nil then begin + finfo.face.checktemplate(sender); + end; + if fframe <> nil then begin + fframe.checktemplate(sender); + end; +end; + +procedure tframebutton.setframeinstance(instance: tcustomframe); +begin + fframe:= tframe(instance); +end; + +procedure tframebutton.setstaticframe(value: boolean); +begin + //dummy +end; + +function tframebutton.getstaticframe: boolean; +begin + result:= false; +end; + +function tframebutton.getwidgetrect: rectty; +begin + result:= nullrect; +end; + +function tframebutton.getcomponentstate: tcomponentstate; +begin + result:= tcustombuttonframe(fowner).fintf.getwidget.componentstate; +end; + +function tframebutton.getmsecomponentstate: msecomponentstatesty; +begin + result:= tcustombuttonframe(fowner).fintf.getwidget.msecomponentstate; +end; + +procedure tframebutton.scrollwidgets(const dist: pointty); +begin + //dummy +end; + +procedure tframebutton.clientrectchanged; +begin + changed; +end; + +procedure tframebutton.invalidate; +begin + tcustombuttonframe(fowner).fintf.getwidget.invalidaterect( + fframerect,org_widget); +end; + +procedure tframebutton.invalidatewidget; +begin + invalidate; +end; + +procedure tframebutton.invalidaterect(const rect: rectty; + const org: originty = org_client; const noclip: boolean = false); +begin + invalidate; +end; + +function tframebutton.getwidget: twidget; +begin + result:= tcustombuttonframe(fowner).fintf.getwidget +end; + +function tframebutton.getframestateflags: framestateflagsty; +begin + with getwidget,finfo do begin + result:= combineframestateflags(shs_disabled in state,focused,active, + shs_mouse in state,shs_clicked in state); + end; +end; + +function tframebutton.getimagelist: timagelist; +begin + result:= finfo.ca.imagelist; +end; + +procedure tframebutton.setaction(const avalue: taction); +begin + twidget1(iframe(tcustombuttonsframe(fowner).fintf).getwidget). + setlinkedvar(avalue,tmsecomponent(faction)); +end; + +{ tstockglyphframebutton} + +constructor tstockglyphframebutton.create(aowner: tobject); +begin + inherited; + finfo.ca.imagelist:= stockobjects.glyphs; +end; + +function tstockglyphframebutton.isimageliststored: boolean; +begin + result:= finfo.ca.imagelist <> stockobjects.glyphs; +end; + +procedure tstockglyphframebutton.setimagelist(const Value: timagelist); +begin + if value = nil then begin + inherited setimagelist(stockobjects.glyphs); + end + else begin + inherited setimagelist(value); + end; +end; + +{ tframebuttons } + +constructor tframebuttons.create(const aowner: tcustombuttonsframe; + const buttonclass: framebuttonclassty); +begin + inherited create(aowner,buttonclass{tframebutton}); +end; + +class function tframebuttons.getitemclasstype: persistentclassty; +begin + result:= tframebutton; +end; + +procedure tframebuttons.dosizechanged; +begin + if not (csloading in + tcustombuttonframe(fowner).fintf.getwidget.componentstate) then begin + tcustombuttonframe(fowner).updatestate; + end; + inherited; +end; + +function tframebuttons.getitems1(const index: integer): tframebutton; +begin + result:= tframebutton(inherited getitems(index)); +end; + +procedure tframebuttons.updatewidgetstate; +var + int1: integer; + widget1: twidget; +begin + widget1:= tcustombuttonsframe(fowner).fintf.getwidget; + for int1:= 0 to high(fitems) do begin +// updatewidgetshapestate(tframebutton(fitems[int1]).finfo,widget1); + tframebutton(fitems[int1]).updatewidgetstate(widget1); + end; +end; + +function tframebuttons.wantmouseevent(const apos: pointty): boolean; +var + int1: integer; +begin + result:= false; + for int1:= 0 to high(fitems) do begin + with tframebutton(fitems[int1]) do begin + if not (fbo_invisible in foptions) and pointinrect(apos,fframerect) then begin + result:= true; + break; + end; + end; + end; +end; + +procedure tframebuttons.dokeydown(var info: keyeventinfoty); +var + i1: int32; +begin + for i1:= 0 to high(fitems) do begin + with tframebutton(fitems[i1]) do begin + if (finfo.state * [shs_disabled,shs_invisible] = []) and + checkshortcutcode(fshortcut,info) then begin + include(info.eventstate,es_processed); + doexec(); + break; + end; + end; + end; +end; + +procedure tframebuttons.checktemplate(const sender: tobject); +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + tframebutton(fitems[int1]).checktemplate(sender); + end; +end; + +procedure tframebuttons.updatestate; +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + with tframebutton(fitems[int1]) do begin + frameskinoptionstoshapestate(fframe,finfo); + finfo.state:= finfo.state - [shs_showfocusrect,shs_showdefaultrect]; + if (fframe = nil) then begin + optionstostate(); //restore flat and anim settings + end; + end; + end; + updatewidgetstate(); //restore disabled state +end; + +procedure tframebuttons.checkcount(var acount: integer); +begin + inherited; + if acount <= tcustombuttonsframe(fowner).factivebutton then begin + acount:= tcustombuttonsframe(fowner).factivebutton+1; + end; +end; + +{ tcustombuttonsframe } + +constructor tcustombuttonsframe.create(const aintf: icaptionframe; + const buttonintf: ibutton); +begin + factivebutton:= -1; //none + fbuttons:= tframebuttons.create(self,getbuttonclass); + fbuttonintf:= buttonintf; + aintf.setstaticframe(true); + inherited create(aintf); +end; + +destructor tcustombuttonsframe.destroy; +begin + inherited; + fbuttons.free; +end; + +function tcustombuttonsframe.getbuttonclass: framebuttonclassty; +begin + result:= tstockglyphframebutton; +end; + +function tcustombuttonsframe.buttonframe: framety; +var + int1: integer; +begin + result:= nullframe; + for int1:= 0 to fbuttons.count - 1 do begin + with fbuttons[int1],finfo do begin + if not (shs_invisible in state) then begin + if fbo_left in foptions then begin + inc(result.left,fframerect.cx); + end + else begin + inc(result.right,fframerect.cx); + end; + end; + end; + end; +end; + +procedure tcustombuttonsframe.getpaintframe(var aframe: framety); +var + int1: integer; +begin + inherited; + for int1:= 0 to fbuttons.count-1 do begin + with fbuttons[int1],finfo,fframerect do begin + if not (shs_invisible in state) then begin + cy:= fintf.getwidgetrect.cy - frameframedim.cy; + if fbuttonwidth = 0 then begin + cx:= cy; + end + else begin + cx:= fbuttonwidth; + if cx < 0 then begin + cx:= 0; + end; + end; + y:= fouterframe.top + fwidth.top; + if fbo_left in foptions then begin + x:= fouterframe.left + fwidth.left + aframe.left; + inc(aframe.left,cx); + end + else begin + x:= fintf.getwidgetrect.cx - + (fouterframe.right + fwidth.right + cx + aframe.right); + inc(aframe.right,cx); + end; + if (fframe <> nil) and + not (fso_noinnerrect in fframe.optionsskin) then begin + finfo.ca.dim:= deflaterect(fframerect,fframe.paintframe); + deflaterect1(finfo.ca.dim,fframe.frameo); +// finfo.ca.dim:= deflaterect(fframerect,fframe.innerframe); + end + else begin + finfo.ca.dim:= fframerect; + end; + end; + end; + end; +end; + +procedure tcustombuttonsframe.initgridframe; +var + int1: integer; +begin + inherited; + for int1:= 0 to fbuttons.count - 1 do begin + fbuttons.items[int1].finfo.color:= cl_background; + end; +end; + +procedure tcustombuttonsframe.mouseevent(var info: mouseeventinfoty); +var + int1: integer; +begin + if not (csdesigning in fintf.getcomponentstate) then begin + for int1:= 0 to fbuttons.count-1 do begin + fbuttons[int1].mouseevent(info,fintf,fbuttonintf,int1); + end; + end; +end; + +procedure tcustombuttonsframe.internalpaintoverlay(const canvas: tcanvas; + const arect: rectty); +var + int1: integer; + color1,color2: colorty; +begin + color2:= cl_none; + for int1:= 0 to fbuttons.count-1 do begin + with fbuttons[int1] do begin + if not (shs_invisible in finfo.state) + {(fbo_invisible in foptions)} then begin + if fframe <> nil then begin + canvas.save; + fframe.paintbackground(canvas,fframerect,true,false); + end; + if (color = cl_default) or (color = cl_parent) then begin + if color2 = cl_none then begin + color2:= fintf.getwidget.parentcolor; + end; + color1:= finfo.color; + finfo.color:= color2; + drawtoolbutton(canvas,finfo); + finfo.color:= color1; + end + else begin + drawtoolbutton(canvas,finfo); + end; + if fframe <> nil then begin + canvas.restore; + fframe.paintoverlay(canvas,fframerect); + end; + end; + end; + end; + inherited; +end; + +procedure tcustombuttonsframe.dokeydown(var info: keyeventinfoty); +begin + if not (es_processed in info.eventstate) then begin + fbuttons.dokeydown(info); + if not (es_processed in info.eventstate) then begin + inherited; + end; + end; +end; + +procedure tcustombuttonsframe.setbuttons(const Value: tframebuttons); +begin + fbuttons.Assign(Value); +end; + +procedure tcustombuttonsframe.updatemousestate(const sender: twidget; + const info: mouseeventinfoty); +begin + inherited; + if fbuttons.wantmouseevent(info.pos) then begin + with twidget1(sender) do begin + fwidgetstate:= fwidgetstate + [ws_wantmousebutton,ws_wantmousemove, + ws_wantmousefocus]; + end; + end; +end; + +procedure tcustombuttonsframe.updatewidgetstate; +begin + inherited; + fbuttons.updatewidgetstate; +end; + +procedure tcustombuttonsframe.checktemplate(const sender: tobject); +begin + inherited; + fbuttons.checktemplate(sender); +end; + +procedure tcustombuttonsframe.updatestate; +begin + fbuttons.updatestate; //set skin options + inherited; +end; + +{ tcutombuttonframe } + +constructor tcustombuttonframe.create(const aintf: icaptionframe; + const buttonintf: ibutton); +begin + inherited; + buttons.count:= 1; + setactivebutton(0); +end; + +procedure tcustombuttonframe.setactivebutton(avalue: integer); +begin + if avalue < 0 then begin + avalue:= 0; + end; + if avalue >= fbuttons.count then begin + avalue:= fbuttons.count-1; + end; + factivebutton:= avalue; +end; + +function tcustombuttonframe.getbutton: tframebutton; +begin + result:= buttons[factivebutton]; +end; + +procedure tcustombuttonframe.setbutton(const avalue: tframebutton); +begin + buttons[factivebutton].assign(avalue); +end; + +{ tcustomedit } + +constructor tcustomedit.create(aowner: tcomponent); +begin + inherited; +// cursor:= cr_ibeam; + fcursorreadonly:= cr_default; + foptionsedit:= defaultoptionsedit; + fwidgetrect.cx:= defaulteditwidgetwidth; + fwidgetrect.cy:= defaulteditwidgetheight; + if feditor = nil then begin + feditor:= tinplaceedit.create(self,iedit(self),true); + end; + maxlength:= -1; + foptionswidget:= defaulteditwidgetoptions; + foptionswidget1:= defaulteditwidgetoptions1; + ftextflags:= defaulttextflags; + ftextflagsactive:= defaulttextflagsactive; + fempty_textflags:= defaulttextflagsempty; + fempty_textcolor:= cl_none; + fempty_textcolorbackground:= cl_none; + fempty_color:= cl_none; + updatetextflags; +end; + +destructor tcustomedit.destroy; +begin + inherited; + feditor.free; +end; + +procedure tcustomedit.doactivate; +begin + inherited; + feditor.doactivate; + if (oe_focusrectonreadonly in foptionsedit) and + (oe_readonly in optionsedit) and focused then begin + invalidate; + end; +end; + +procedure tcustomedit.dodeactivate; +begin + inherited; + feditor.dodeactivate; + if (oe_focusrectonreadonly in foptionsedit) and + (oe_readonly in optionsedit) and focused then begin + invalidate; + end; +end; + +procedure tcustomedit.dofocus; +begin + inherited; + initfocus; +end; + +procedure tcustomedit.dodefocus; +begin + if not (csdestroying in componentstate) and (fwindow <> nil) and + fwindow.haswinid + then begin + feditor.dodefocus; + end; + inherited; +end; + +procedure tcustomedit.dokeydown(var info: keyeventinfoty); +begin + doonkeydown(info); + if not (es_processed in info.eventstate) then begin + if not (es_child in info.eventstate) then begin + feditor.dokeydown(info); + end; + if not (es_processed in info.eventstate) then begin + inherited; + end; + end; +end; +{ +procedure tcustomedit.dokeyup(var info: keyeventinfoty); +begin + if canevent(tmethod(fonkeyup)) then begin + fonkeyup(self,info); + end; + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; +} +procedure tcustomedit.clientmouseevent(var info: mouseeventinfoty); +begin + feditor.mouseevent(info); + inherited; +end; + +procedure tcustomedit.painttext(const canvas: tcanvas); +begin + feditor.dopaint(canvas); +end; + +procedure tcustomedit.dopaintforeground(const canvas: tcanvas); +begin + inherited; + paintimage(canvas); + painttext(canvas); +end; + +procedure tcustomedit.dopaintbackground(const canvas: tcanvas); +begin + inherited; + if (fempty_color <> cl_none) and + (fstate * [des_emptytext,des_grayed] = [des_emptytext]) and + (not (eo_nocolorfocused in fempty_options) or not focused)then begin + canvas.fillrect(paintclientrect,fempty_color); + end; +end; + +function tcustomedit.needsfocuspaint: boolean; +begin + result:= inherited needsfocuspaint or + ([oe_focusrectonreadonly,oe_readonly] * optionsedit = + [oe_focusrectonreadonly,oe_readonly]); +end; +{ +procedure tcustomedit.doafterpaint(const canvas: tcanvas); +begin + if ([oe_focusrectonreadonly,oe_readonly] * optionsedit = + [oe_focusrectonreadonly,oe_readonly]) and focused and active then begin + drawfocusrect(canvas,paintrect); + end; + inherited; +end; +} +procedure tcustomedit.editnotification(var info: editnotificationinfoty); +begin + case info.action of + ea_textchanged: begin + dochange; + end; + ea_textedited,ea_undone: begin + dotextedited; + end; + ea_resetemptytext: begin + if des_emptytext in fstate then begin + exclude(fstate,des_emptytext); + updateemptytext(); + end; + end; + end; +end; + +procedure tcustomedit.updatecopytoclipboard(var atext: msestring); +begin + if canevent(tmethod(foncopytoclipboard)) then begin + foncopytoclipboard(self,atext); + end; +end; + +procedure tcustomedit.updatepastefromclipboard(var atext: msestring); +begin + if canevent(tmethod(fonpastefromclipboard)) then begin + fonpastefromclipboard(self,atext); + end; +end; + +function tcustomedit.locatecount: integer; //number of locate values +begin + result:= 0; +end; + +function tcustomedit.locatecurrentindex: integer; //index of current row +begin + result:= -1; +end; + +procedure tcustomedit.locatesetcurrentindex(const aindex: integer); +begin + //dummy +end; + +function tcustomedit.getkeystring(const aindex: integer): msestring; //locate text +begin + result:= ''; +end; + +class function tcustomedit.classskininfo: skininfoty; +begin + result:= inherited classskininfo; + result.objectkind:= sok_edit; +end; + +function tcustomedit.getoptionsedit: optionseditty; +begin + result:= foptionsedit; +end; + +function tcustomedit.getreadonly: boolean; +begin + result:= oe_readonly in foptionsedit; +end; + +procedure tcustomedit.setreadonly(const avalue: boolean); +begin + if avalue <> (oe_readonly in foptionsedit) then begin + if avalue then begin + optionsedit:= optionsedit + [oe_readonly]; + end + else begin + optionsedit:= optionsedit - [oe_readonly]; + end; + setupeditor; + end; +end; + +procedure tcustomedit.setoptionsedit(const avalue: optionseditty); +var + opt1: optionsedit1ty; + opt: optionseditty; +begin + if foptionsedit <> avalue then begin + opt1:= feditor.optionsedit1; + transferoptionsedit(self,avalue,opt,opt1); + feditor.optionsedit1:= opt1; + foptionsedit:= optionseditty(setsinglebit(card32(opt),card32(foptionsedit), + card32([oe_homeonenter,oe_endonenter]))); + updatereadonlystate; + end; +end; + +function tcustomedit.getoptionsedit1: optionsedit1ty; +begin + result:= feditor.optionsedit1; +end; + +procedure tcustomedit.setempty_text(const avalue: msestring); +begin + fempty_text:= avalue; + formatchanged; +end; + +procedure tcustomedit.setempty_textflags(const avalue: textflagsty); +begin + if avalue <> fempty_textflags then begin + fempty_textflags:= checktextflags(fempty_textflags,avalue); + emptychanged; + end; +end; + +procedure tcustomedit.setempty_textcolor(const avalue: colorty); +begin + if avalue <> fempty_textcolor then begin + fempty_textcolor:= avalue; + emptychanged; + end; +end; + +procedure tcustomedit.setempty_textcolorbackground(const avalue: colorty); +begin + if avalue <> fempty_textcolorbackground then begin + fempty_textcolorbackground:= avalue; + emptychanged; + end; +end; + +procedure tcustomedit.setempty_fontstyle(const avalue: fontstylesty); +begin + if avalue <> fempty_fontstyle then begin + fempty_fontstyle:= avalue; + emptychanged; + end; +end; + +procedure tcustomedit.setempty_color(const avalue: colorty); +begin + if avalue <> fempty_color then begin + fempty_color:= avalue; + invalidate; + end; +end; + +procedure tcustomedit.setoptionsedit1(const avalue: optionsedit1ty); +var + optbefore: optionsedit1ty; +begin + optbefore:= feditor.optionsedit1; + feditor.optionsedit1:= avalue; + if oe1_readonlydialog in optionsedit1ty( + {$ifdef FPC}longword{$else}byte{$endif}(avalue) xor + {$ifdef FPC}longword{$else}byte{$endif}(optbefore)) then begin + updatereadonlystate; + end; +end; + +function tcustomedit.getassistivecaretindex(): int32; +begin + result:= feditor.curindex; +end; + +function tcustomedit.getassistiveflags(): assistiveflagsty; +begin + result:= inherited getassistiveflags + [asf_textedit]; + if not feditor.canedit then begin + include(result,asf_readonly); + end; +end; + +function tcustomedit.geteditfont: tfont; +begin + result:= getfont1; +end; + +function tcustomedit.getinnerframe: framety; +begin + result:= minimalframe; +end; + +function tcustomedit.geteditframe: framety; +begin + result:= nullframe; +end; + +procedure tcustomedit.gettextrects(out outer: rectty; out inner: rectty); +var + fra1: framety; +begin + fra1:= geteditframe; + if fframe = nil then begin + outer:= deflaterect(clientrect,fra1); + inner:= deflaterect(outer,getinnerframe); + end + else begin + outer:= deflaterect(clientsizerect,fra1); + inner:= deflaterect(innerclientrect,fra1); + end; +end; + +procedure tcustomedit.setupeditor; +var + outer1,inner1: rectty; +begin + if not (csloading in componentstate) then begin + gettextrects(outer1,inner1); + with feditor do begin + setup(text,curindex,true,inner1,outer1,getformat(),nil,geteditfont); + end; + end; +end; + +function tcustomedit.getformat(): formatinfoarty; +begin + result:= nil; +end; + +{ +procedure tcustomedit.setupeditor; +var + fra1: framety; +begin + if not (csloading in componentstate) then begin + fra1:= geteditframe; + with feditor do begin + if fframe = nil then begin + setup(text,curindex,true, + deflaterect(clientrect,addframe(fra1,getinnerframe)), + deflaterect(clientrect,fra1),nil,nil,geteditfont); + end + else begin + setup(text,curindex,true,deflaterect(innerclientrect,fra1), + deflaterect(makerect(nullpoint,clientsize),fra1),nil,nil,geteditfont); + end; + end; + end; +end; +} +function tcustomedit.verticalfontheightdelta: boolean; +begin + result:= tf_rotate90 in textflags; +end; + +procedure tcustomedit.synctofontheight; +var +// int1: integer; + fram1: framety; +begin + inherited; + fram1:= getinnerframe; + if tf_rotate90 in ftextflags then begin + syncsinglelinefontheight(false,fram1.left + fram1.right); + end + else begin + syncsinglelinefontheight(false,fram1.top + fram1.bottom); + end; +end; + +procedure tcustomedit.clientrectchanged; +begin + inherited; + setupeditor; +end; + +procedure tcustomedit.getautopaintsize(var asize: sizety); +var + fram1: framety; +begin + if fframe = nil then begin + fram1:= getinnerframe; + end + else begin +// fram1:= fframe.innerframe; + fram1:= fframe.framei; + end; + asize:= feditor.textrect.size; + asize.cx:= asize.cx + fram1.left + fram1.right; + asize.cy:= asize.cy + fram1.top + fram1.bottom; + fram1:= geteditframe; + asize.cx:= asize.cx + fram1.left+fram1.right; + asize.cy:= asize.cy + fram1.top+fram1.bottom; +end; + +procedure tcustomedit.fontchanged; +begin + inherited; + setupeditor; + checkautosize(); +end; + +function tcustomedit.getmaxlength: integer; +begin + result:= feditor.maxlength; +end; + +function tcustomedit.getpasswordchar: msechar; +begin + result:= feditor.passwordchar; +end; + +procedure tcustomedit.setmaxlength(const avalue: integer); +begin + feditor.maxlength:= avalue; +end; + +procedure tcustomedit.setpasswordchar(const Value: msechar); +begin + feditor.passwordchar:= value; +end; + +procedure tcustomedit.internalcreateframe; +begin + teditframe.create(iscrollframe(self)); +end; + +function tcustomedit.gettext: msestring; +begin + result:= feditor.text; +end; + +function tcustomedit.getoldtext: msestring; +begin + result:= feditor.oldtext; +end; + +procedure tcustomedit.settext(const avalue: msestring); +begin + feditor.text:= avalue; + if (avalue = '') and (not focused or + (eo_showfocused in fempty_options)) then begin + if not (des_emptytext in fstate) then begin + include(fstate,des_emptytext); + updateemptytext(); + end; + end + else begin + if des_emptytext in fstate then begin + exclude(fstate,des_emptytext); + updateemptytext(); + end; + end; +end; +{ +procedure tcustomedit.setcurrenttext(const avalue: msestring); +begin + feditor.text:= avalue; + if avalue <> '' then begin + exclude(fstate,des_emptytext); + end; +end; +} +function tcustomedit.getedittext: msestring; +begin + result:= text; +end; + +procedure tcustomedit.updateemptytext(); +begin + if des_emptytext in fstate then begin + include(tinplaceedit1(feditor).fstate,ies_emptytext); + feditor.font:= getfontempty1{fempty_font}; + if fempty_textcolor <> cl_none then begin + feditor.fontcolor:= fempty_textcolor; + end; + if fempty_textcolorbackground <> cl_none then begin + feditor.fontcolorbackground:= fempty_textcolorbackground; + end; + if fempty_fontstyle <> [] then begin + feditor.fontstyle:= fempty_fontstyle; + end; + end + else begin + exclude(tinplaceedit1(feditor).fstate,ies_emptytext); + feditor.font:= geteditfont; + feditor.fontcolor:= cl_none; + feditor.fontcolorbackground:= cl_none; + feditor.fontstyle:= []; + end; + updatetextflags(); +end; + +procedure tcustomedit.updateedittext(const force: boolean); +var + mstr1: msestring; + state1: dataeditstatesty; +begin + state1:= fstate; + mstr1:= getedittext(); + if (not(des_isdb in fstate) and (mstr1 = '') or (des_dbnull in fstate)) and + (not focused or (eo_showfocused in fempty_options)) then begin + mstr1:= fempty_text; + include(fstate,des_emptytext); + end + else begin + exclude(fstate,des_emptytext); + end; + feditor.text:= mstr1; + if force or ((des_emptytext in fstate) xor + (des_emptytext in state1)) then begin + updateemptytext(); + end; + +{ + if not (csloading in componentstate) then begin + if isenabled or (oe_nogray in foptionsedit) then begin + feditor.textflags:= ftextflags; + feditor.textflagsactive:= ftextflagsactive; + end + else begin + feditor.textflags:= ftextflags + [tf_grayed]; + feditor.textflagsactive:= ftextflagsactive + [tf_grayed]; + end; + end; +} +end; + +procedure tcustomedit.updatetextflags; +var + aflags,aflagsactive: textflagsty; +begin + if not (csloading in componentstate) then begin + if (des_emptytext in fstate) {and (fempty_text <> '')} and + (fempty_textflags <> []) then begin + aflags:= fempty_textflags; + aflagsactive:= aflags; + end + else begin + aflags:= textflags; + aflagsactive:= textflagsactive; + end; + if isenabled or (oe_nogray in foptionsedit) then begin + exclude(fstate,des_grayed); + feditor.textflags:= aflags; + feditor.textflagsactive:= aflagsactive; + end + else begin + include(fstate,des_grayed); + feditor.textflags:= aflags + [tf_grayed]; + feditor.textflagsactive:= aflagsactive + [tf_grayed]; + end; + end; +end; + +procedure tcustomedit.enabledchanged; +begin + inherited; + updatetextflags; + if (fempty_color <> cl_none) and (des_emptytext in fstate) then begin + invalidate(); + end; +end; + +procedure tcustomedit.settextflags(const value: textflagsty); +begin + if ftextflags <> value then begin + ftextflags:= checktextflags(ftextflags,value); + updatetextflags; + end; +end; + +procedure tcustomedit.settextflagsactive(const value: textflagsty); +begin + if ftextflagsactive <> value then begin + ftextflagsactive:= checktextflags(ftextflagsactive,value) {- ellipsemask}; + updatetextflags; + end; +end; + +procedure tcustomedit.dochange; +begin + checkautosize(); + if not (ws_loadedproc in fwidgetstate) then begin + if assistiveserver <> nil then begin + assistiveserver.dochange(getiassistiveclient()); + end; + if canevent(tmethod(fonchange)) then begin + fonchange(self); + end; + (* +{$ifdef mse_with_ifi} + if fifiserverintf <> nil then begin + fifiserverintf.valuechanged(iificlient(self)); + end; +{$endif} + *) + end; +end; + +procedure tcustomedit.formatchanged(); +begin + if not (csloading in componentstate) then begin + invalidate(); + checkautosize(); + end; +end; + +procedure tcustomedit.internaltextedited(const aevent: texteditedeventty); +var + mstr1: msestring; +begin + if canevent(tmethod(aevent)) then begin + mstr1:= text; + aevent(self,mstr1); + if mstr1 <> text then begin + text:= mstr1; + end; +// feditor.oldtext:= mstr1; + end; +end; + +procedure tcustomedit.dotextedited; +begin + internaltextedited(fontextedited); +end; + +procedure tcustomedit.emptychanged; +begin + if not (csloading in componentstate) then begin + updateedittext(true); + end; +end; + +procedure tcustomedit.initnewcomponent(const ascale: real); +begin + createframe; + fframe.scale(ascale); + inherited; +end; + +procedure tcustomedit.initfocus; +begin + feditor.dofocus; +end; + +procedure tcustomedit.rootchanged(const aflags: rootchangeflagsty); +begin + inherited; + feditor.poschanged; +end; + +function tcustomedit.getedited: boolean; +begin + result:= false; +end; + +procedure tcustomedit.changed; +begin + dochange; +end; + +procedure tcustomedit.updateflagtext(var avalue: msestring); +begin + if oe_trimleft in foptionsedit then begin + avalue:= trimleft(avalue); + end; + if oe_trimright in foptionsedit then begin + avalue:= trimright(avalue); + end; + if oe_uppercase in foptionsedit then begin + avalue:= mseuppercase(avalue); + end + else begin + if oe_lowercase in foptionsedit then begin + avalue:= mselowercase(avalue); + end; + end; +end; + +function tcustomedit.geteditor: tinplaceedit; +begin + result:= feditor; +end; + +procedure tcustomedit.updatepopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); +begin + if oe1_autopopupmenu in feditor.optionsedit1 then begin + feditor.updatepopupmenu(amenu,popupmenu,mouseinfo,hasselection); + end; + inherited; +end; + +function tcustomedit.getcaretwidth: integer; +begin + result:= feditor.caretwidth; +end; + +procedure tcustomedit.setcaretwidth(const Value: integer); +begin + feditor.caretwidth:= value; +end; + +procedure tcustomedit.readpwchar(reader: treader); +begin + passwordchar:= msechar(reader.readinteger); +end; + +procedure tcustomedit.writepwchar(writer: twriter); +begin + writer.writeinteger(ord(passwordchar)); +end; + +procedure tcustomedit.defineproperties(filer: tfiler); +var + bo1: boolean; +begin + inherited; + if filer.ancestor <> nil then begin + bo1:= tcustomedit(filer.ancestor).passwordchar <> passwordchar; + end + else begin + bo1:= passwordchar <> #0; + end; + filer.defineproperty('pwchar',{$ifdef FPC}@{$endif}readpwchar, + {$ifdef FPC}@{$endif}writepwchar,bo1); +end; + +procedure tcustomedit.updatereadonlystate; +begin + if feditor <> nil then begin + feditor.updatecaret; + end; + cursorchanged; + if (oe_focusrectonreadonly in foptionsedit) and focused and active then begin + invalidate; + end; +end; + +function tcustomedit.hasselection: boolean; +begin + result:= false; +end; + +function tcustomedit.cangridcopy: boolean; +begin + result:= false; +end; + +function tcustomedit.gettextcliprect(): rectty; +begin + result:= clippedpaintrect(); + subpoint1(result.pos,paintpos); +end; + +procedure tcustomedit.showhint(const aid: int32; var info: hintinfoty); +begin + if (oe_hintclippedtext in foptionsedit) and + editor.lasttextclipped(gettextcliprect) and getshowhint then begin + info.caption:= text; + end; + inherited; +end; + +procedure tcustomedit.dragstarted; +begin + feditor.dragstarted; + inherited; +end; + +procedure tcustomedit.setcursorreadonly(const avalue: cursorshapety); +begin + if fcursorreadonly <> avalue then begin + fcursorreadonly:= avalue; + cursorchanged; + end; +end; + +function tcustomedit.actualcursor(const apos: pointty): cursorshapety; +begin + if oe_readonly in foptionsedit then begin + result:= fcursorreadonly; + end + else begin + result:= inherited actualcursor(apos); + if result = cr_default then begin + result:= cr_ibeam; + end; + end; +end; + +procedure tcustomedit.paintimage(const canvas: tcanvas); +begin + if canevent(tmethod(fonpaintimage)) then begin + fonpaintimage(self,canvas); + end; +end; + +function tcustomedit.navigrect: rectty; +begin + result:= inherited navigrect(); +// result:= frameinnerrect; +// result:= paintframerect; +end; + +{ tedit } + +constructor tedit.create(aowner: tcomponent); +begin + inherited; + ftimer:= tsimpletimer.create(0,@dotimer,false,[to_single]); +end; + +destructor tedit.destroy; +begin + ftimer.free; + inherited; +end; + +procedure tedit.dotimer(const sender: tobject); +begin + internaltextedited(fontextediteddelayed); +end; + +function tedit.getdelay: integer; +begin + result:= ftimer.interval div 1000; +end; + +procedure tedit.setdelay(const avalue: integer); +begin + ftimer.interval:= avalue * 1000; +end; + +procedure tedit.dotextedited; +begin + inherited; + ftimer.restart; +end; + +procedure tedit.editnotification(var info: editnotificationinfoty); +var + mstr1: msestring; +begin + inherited; + case info.action of + ea_textentered: begin + mstr1:= text; + updateflagtext(mstr1); + text:= mstr1; + ftimer.fireandstop; + initfocus; + end; + ea_undone: begin + updateedittext(false); + end; + end; +end; + +procedure tedit.loaded(); +begin + inherited; + updateedittext(false); +end; + +procedure tedit.dofocus(); +begin + updateedittext(false); + inherited; +end; + +procedure tedit.dodefocus(); +var + info1: editnotificationinfoty; +begin + with tinplaceedit1(feditor) do begin + if ies_edited in fstate then begin + info1:= initactioninfo(ea_textentered); + editnotification(info1); + end + else begin + updateedittext(false); + end; + end; + inherited; +end; + +procedure tedit.setstatfile(const avalue: tstatfile); +begin + setstatfilevar(istatfile(self),avalue,fstatfile); +end; + +function tedit.gettext: msestring; +begin + result:= inherited gettext(); + if des_emptytext in fstate then begin + result:= ''; + end; +end; + +procedure tedit.settext(const avalue: msestring); +begin + inherited; + if not (csloading in componentstate) then begin + if avalue <> '' then begin + exclude(fstate,des_emptytext); + end; + updateedittext(true); + end; +end; + +procedure tedit.dostatwrite(const writer: tstatwriter); +begin + writer.writemsestring('text',text); +end; + +procedure tedit.dostatread(const reader: tstatreader); +begin + text:= reader.readmsestring('text',text); +end; + +procedure tedit.statreading; +begin + //dummy +end; + +procedure tedit.statread; +begin + if (oe1_checkvalueafterstatread in optionsedit1) then begin + dotextedited; + end; +end; + +function tedit.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +function tedit.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +end. diff --git a/mseide-msegui/lib/common/editwidgets/msefoldedit.pas b/mseide-msegui/lib/common/editwidgets/msefoldedit.pas new file mode 100644 index 0000000..0a27ea8 --- /dev/null +++ b/mseide-msegui/lib/common/editwidgets/msefoldedit.pas @@ -0,0 +1,878 @@ +{ MSEgui Copyright (c) 2009-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msefoldedit; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,mseclasses,msedataedits,msegraphics,mseguiglob,msegrids, + mseevent,msegui, + msegraphutils,msebitmap,mseeditglob,msedatalist,msewidgetgrid,mseedit, + msedrawtext,msetypes,msestat,msepointer,msemenus,msestrings,msegridsglob; + +const + defaultfoldedittextflags = defaulttextflags + [tf_clipo]; + defaultfoldedittextflagsactive = defaulttextflagsactive + [tf_clipo]; +type + tgridmsestringintdatalist = class(tmsestringintdatalist) + private + fowner: twidgetcol; + protected + function getdefault: pointer; override; + public + constructor create(owner: twidgetcol); reintroduce; + end; + + foldeditoptionty = (feo_menulevel,feo_menuissum); + foldeditoptionsty = set of foldeditoptionty; + + tfoldedit = class(tstringedit) + private + foncellevent: celleventty; + fonclientmouseevent: mouseeventty; + flevelstep: integer; + fimagesize: sizety; + fimnr_base: integer; + fimnr_expanded: integer; + fimnr_selected: integer; + fimnr_readonly: integer; + fimnr_subitems: integer; + fimagelist: timagelist; + fdefault: msestringintty; + + fimnr_value: integer; + fimnr_valuebase: integer; + fimnr_valueexpanded: integer; + fimnr_valueselected: integer; + fimnr_valuereadonly: integer; + fimnr_valuesubitems: integer; + fimagelistvalue: timagelist; + foptions: foldeditoptionsty; + procedure setlevelstep(const avalue: integer); + procedure setimagesize(const avalue: sizety); + procedure setimagewidth(const avalue: integer); + procedure setimageheight(const avalue: integer); + procedure setimnr_base(const avalue: integer); + procedure setimnr_expanded(const avalue: integer); + procedure setimnr_selected(const avalue: integer); + procedure setimnr_readonly(const avalue: integer); + procedure setimnr_subitems(const avalue: integer); + procedure setimagelist(const avalue: timagelist); + function getgridimnr(index: integer): integer; + procedure setgridimnr(index: integer; const avalue: integer); + function getgridimnrs: integerarty; + procedure setgridimnrs(const avalue: integerarty); + procedure setimnr_value(const avalue: integer); + procedure setimnr_valuebase(const avalue: integer); + procedure setimnr_valueexpanded(const avalue: integer); + procedure setimnr_valueselected(const avalue: integer); + procedure setimnr_valuereadonly(const avalue: integer); + procedure setimnr_valuesubitems(const avalue: integer); + procedure setimagelistvalue(const avalue: timagelist); + procedure dolevelup(const sender: tobject); + procedure doleveldown(const sender: tobject); + procedure doissum(const sender: tobject); + protected + procedure updatelayout; + procedure drawimage(const acanvas: tcanvas; + const ainfo: prowfoldinfoty; var arect: rectty; + const isselected,isreadonly: boolean; + const datapo: pmsestringintty); + procedure drawcell(const canvas: tcanvas); override; + procedure clientmouseevent(var ainfo: mouseeventinfoty); override; + procedure docellevent(const ownedcol: boolean; + var info: celleventinfoty); override; + procedure updatecellzone(const row: integer; const apos: pointty; + var result: cellzonety); override; + procedure updatelevelcellzone(const alevel: integer; const apos: pointty; + var azone: cellzonety); virtual; + function getcellcursor(const arow: integer; const acellzone: cellzonety; + const apos: pointty): cursorshapety; override; + procedure doonpaint(const acanvas: tcanvas); override; + function createdatalist(const sender: twidgetcol): tdatalist; override; + function getdefaultvalue: pointer; override; + function imageshift(arow: integer): integer; + //-1 -> focused row + procedure setupeditor; override; + procedure gridtovalue(arow: integer); override; + procedure valuetogrid(arow: integer); override; + procedure writestatvalue(const writer: tstatwriter); override; + procedure readstatvalue(const reader: tstatreader); override; + procedure updatepopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); override; + public + constructor create(aowner: tcomponent); override; + procedure synctofontheight; override; + property imagesize: sizety read fimagesize write setimagesize; + property gridimnr[index: integer]: integer + read getgridimnr write setgridimnr; + property gridimnrs: integerarty read getgridimnrs write setgridimnrs; + published + property options: foldeditoptionsty read foptions write foptions default []; + property oncellevent: celleventty read foncellevent write foncellevent; + property onclientmouseevent: mouseeventty read fonclientmouseevent + write fonclientmouseevent; + property levelstep: integer read flevelstep write setlevelstep default 10; + + property imnr_base: integer read fimnr_base write setimnr_base default 0; + property imnr_expanded: integer read fimnr_expanded + write setimnr_expanded default 0; + property imnr_selected: integer read fimnr_selected + write setimnr_selected default 0; + property imnr_readonly: integer read fimnr_readonly + write setimnr_readonly default 0; + property imnr_subitems: integer read fimnr_subitems + write setimnr_subitems default 0; + + + property imnr_value: integer read fimnr_value write setimnr_value default -1; + //-1 -> use imagelist, imnr_base, imnr_expanded, imnr_selected + //imnr_readonly, imnr_subitems + //-2 none + // >= 0 use imagelistvalue, imnr_value + imnr_base, imnr_expanded, imnr_selected + //imnr_readonly, imnr_subitems + property imnr_valuebase: integer read fimnr_valuebase + write setimnr_valuebase default 0; + property imnr_valueexpanded: integer read fimnr_valueexpanded + write setimnr_valueexpanded default 0; + property imnr_valueselected: integer read fimnr_valueselected + write setimnr_valueselected default 0; + property imnr_valuereadonly: integer read fimnr_valuereadonly + write setimnr_valuereadonly default 0; + property imnr_valuesubitems: integer read fimnr_valuesubitems + write setimnr_valuesubitems default 0; + + property imagelist: timagelist read fimagelist write setimagelist; + property imagelistvalue: timagelist read fimagelistvalue + write setimagelistvalue; + property imagewidth: integer read fimagesize.cx write setimagewidth default 0; + property imageheight: integer read fimagesize.cy write setimageheight default 0; + property textflags default defaultfoldedittextflags; + property textflagsactive default defaultfoldedittextflagsactive; +// property cursor default cr_default; + end; + +implementation +uses + msestockobjects,msesumlist,mseact; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tdatacols1 = class(tdatacols); + twidgetcol1 = class(twidgetcol); + +{ tgridmsestringintdatalist } + +constructor tgridmsestringintdatalist.create(owner: twidgetcol); +begin + fowner:= owner; + inherited create; +end; + +function tgridmsestringintdatalist.getdefault: pointer; +begin + result:= nil; + with twidgetcol1(fowner) do begin + if fintf <> nil then begin + result:= fintf.getdefaultvalue; + end; + end; +end; + +{ tfoldedit } + +constructor tfoldedit.create(aowner: tcomponent); +begin + flevelstep:= 10; + fdefault.int:= -1; + fimnr_value:= -1; + inherited; +// cursor:= cr_default; + textflags:= defaultfoldedittextflags; + textflagsactive:= defaultfoldedittextflagsactive; +end; + +procedure tfoldedit.drawimage(const acanvas: tcanvas; + const ainfo: prowfoldinfoty; var arect: rectty; + const isselected,isreadonly: boolean; + const datapo: pmsestringintty); +const + boxsize = 11; +var + levelshift: integer; + int1,int2,int3,int4: integer; + glyph1: stockglyphty; + lines: segmentarty; + ycenter,xbefore: integer; + imli1: timagelist; +begin + if ainfo <> nil then begin + with ainfo^ do begin + xbefore:= arect.x; + ycenter:= arect.cy div 2; + levelshift:= flevelstep*foldlevel; + glyph1:= stg_none; + if haschildren then begin + if isopen then begin + glyph1:= stg_boxexpanded; + end + else begin + glyph1:= stg_boxexpand; + end; + end; + inc(arect.x,levelshift); + int3:= flevelstep + flevelstep div 2; + int4:= 0; + setlength(lines,foldlevel+2); + for int2:= 0 to high(nolines) - 1 do begin + with lines[int4] do begin + if not nolines[int2] then begin + a.x:= int3; + b.x:= int3; + a.y:= 0; + b.y:= arect.cy; + inc(int4); + end; + end; + inc(int3,flevelstep); + end; + if foldlevel > 0 then begin + with lines[int4] do begin + a.x:= int3; + b.x:= int3; + a.y:= 0; + if (glyph1 = stg_none) then begin + if nolines[high(nolines)] then begin + b.y:= ycenter; + end + else begin + b.y:= arect.cy; + end; + inc(int4); + with lines[int4] do begin + a.x:= int3; + b.x:= int3 + flevelstep div 2; + a.y:= ycenter; + b.y:= ycenter; + end; + end + else begin + b.y:= ycenter - boxsize div 2; + if not nolines[high(nolines)] then begin + inc(int4); + with lines[int4] do begin + a.x:= int3; + b.x:= int3; + a.y:= ycenter + boxsize div 2; + b.y:= arect.cy; + end; + end; + end; + inc(int4); + end; + end; + if int4 > 0 then begin + setlength(lines,int4); + drawdottedlinesegments(acanvas,lines,cl_shadow); + end; + if glyph1 <> stg_none then begin + int1:= arect.cx; + arect.cx:= flevelstep; + stockobjects.glyphs.paint(acanvas,ord(glyph1),arect, + [al_ycentered,al_xcentered],cl_glyph); + arect.cx:= int1; + end; + inc(arect.x,flevelstep); + imli1:= nil; + if datapo <> nil then begin + int1:= datapo^.int; + end + else begin + int1:= fimnr_value; + end; + if int1 <> -1 then begin + if fimagelistvalue <> nil then begin + imli1:= fimagelistvalue; + inc(int1,fimnr_valuebase); + if isopen then begin + inc(int1,fimnr_valueexpanded); + end; + if isselected then begin + inc(int1,fimnr_valueselected); + end; + if isreadonly then begin + inc(int1,fimnr_valuereadonly); + end; + if isselected then begin + inc(int1,fimnr_valueselected); + end; + if haschildren then begin + inc(int1,fimnr_valuesubitems); + end; + end; + end + else begin + if fimagelist <> nil then begin + imli1:= fimagelist; + int1:= fimnr_base { fimagenr}; + if isopen then begin + inc(int1,fimnr_expanded); + end; + if isselected then begin + inc(int1,fimnr_selected); + end; + if isreadonly then begin + inc(int1,fimnr_readonly); + end; + if isselected then begin + inc(int1,fimnr_selected); + end; + if haschildren then begin + inc(int1,fimnr_subitems); + end; + end; + end; + if (imli1 <> nil) and (int1 >= 0) then begin + int2:= arect.cx; + arect.cx:= fimagesize.cx; + imli1.paint(acanvas,int1,arect,[al_ycentered,al_xcentered]); + inc(arect.x,fimagesize.cx); + arect.cx:= int2; + end; + arect.cx:= arect.cx - (arect.x-xbefore); + end; + end; +end; + +procedure tfoldedit.drawcell(const canvas: tcanvas); +var + rect1: rectty; + int1,int2,int3: integer; +begin + with cellinfoty(canvas.drawinfopo^) do begin + rect1:= rect; + drawimage(canvas,foldinfo,rect,cds_selected in drawstate, + cds_readonly in drawstate,pmsestringintty(datapo)); + int1:= innerrect.x; + int2:= innerrect.cx; + try + int3:= rect.x - rect1.x; //apply adjustments to innerrect + innerrect.x:= innerrect.x + int3; + innerrect.cx:= innerrect.cx - int3; + if innerrect.cx < 0 then begin + innerrect.cx:= 0; + end; + inherited; + finally + innerrect.x:= int1; + innerrect.cx:= int2; + rect:= rect1; + end; + end; +end; + +procedure tfoldedit.doonpaint(const acanvas: tcanvas); +var + rect1: rectty; + int1: integer; +begin + if (fgridintf <> nil) then begin + acanvas.rootbrushorigin:= fgridintf.getbrushorigin; + rect1:= clientrect; + with fgridintf.getcol,grid do begin + int1:= row; + if int1 >= 0 then begin //not csdesigning + drawimage(acanvas,rowfoldinfo,rect1, + datacols.selected[makegridcoord(index,int1)], + rowreadonlystate[int1],nil); + end + else begin + drawimage(acanvas,rowfoldinfo,rect1,false,false,nil); + end; + end; + end; + inherited; +end; + +procedure tfoldedit.clientmouseevent(var ainfo: mouseeventinfoty); +var + isvisible1,haschildren1,isopen1: boolean; + foldlevel1: byte; + zone1: cellzonety; + row1: integer; +begin + if canevent(tmethod(fonclientmouseevent)) then begin + fonclientmouseevent(self,ainfo); + end; + if not (es_processed in ainfo.eventstate) and (fgridintf <> nil) then begin + with ainfo do begin + if isleftbuttondown(ainfo,[]) then begin +{$warnings off} + with fgridintf.getcol.grid,tdatacols1(datacols).frowstate do begin +{$warnings on} + row1:= row; + if row1 >= 0 then begin //no csdesigning + getfoldstate(row1,isvisible1,foldlevel1,haschildren1,isopen1); + zone1:= cz_default; + updatelevelcellzone(foldlevel1,ainfo.pos,zone1); + if (zone1 = cz_default) and + (ainfo.pos.x >= foldlevel1 * flevelstep) then begin + if isopen1 then begin + hidechildren(row1); + end + else begin + showchildren(row1); + end; + end; + end; + end; + end; + end; + if not (es_processed in ainfo.eventstate) then begin + inherited; + end; + end; +end; + +procedure tfoldedit.docellevent(const ownedcol: boolean; + var info: celleventinfoty); +begin + with info do begin + if ownedcol then begin + if (eventkind in mousecellevents) and (info.cell.row >= 0) then begin + updatelevelcellzone(fgridintf.getcol.grid.rowfoldlevel[info.cell.row], + info.mouseeventinfopo^.pos,info.zone); + end + else begin + if eventkind = cek_exit then begin + end; + end; + end; +{ + if (info.eventkind = cek_enter) or + (info.eventkind = cek_exit) then begin + if oe_locate in foptionsedit then begin + editing:= false; + end; + factiverow:= info.newcell.row; + if fvalue <> nil then begin + if info.eventkind = cek_enter then begin + updateitemvalues(info.newcell.row,1); + end + else begin + updateitemvalues(info.cellbefore.row,1); + end; + end; + end; +} + end; + if canevent(tmethod(foncellevent)) then begin + foncellevent(self,info); + end; + inherited; +end; + +procedure tfoldedit.updatelevelcellzone(const alevel: integer; const apos: pointty; + var azone: cellzonety); +var + int1: integer; +begin + int1:= (alevel+1) * flevelstep; + if apos.x >= int1 + fimagesize.cx then begin + azone:= cz_caption; + end + else begin + if apos.x >= int1 then begin + azone:= cz_image; + end; + end; +end; + +procedure tfoldedit.updatecellzone(const row: integer; const apos: pointty; + var result: cellzonety); +begin + if row >= 0 then begin + updatelevelcellzone(fgridintf.getcol.grid.rowfoldlevel[row],apos,result); + end; +end; + +procedure tfoldedit.setlevelstep(const avalue: integer); +begin + if avalue <> flevelstep then begin + flevelstep:= avalue; + updatelayout; + end; +end; + +procedure tfoldedit.setimageheight(const avalue: integer); +begin + if fimagesize.cy <> avalue then begin + fimagesize.cy := avalue; + updatelayout; +// invalidate; + end; +end; + +procedure tfoldedit.setimagewidth(const avalue: integer); +begin + if fimagesize.cx <> avalue then begin + fimagesize.cx := avalue; + updatelayout; +// invalidate; + end; +end; + +procedure tfoldedit.setimagesize(const avalue: sizety); +begin + if (fimagesize.cx <> avalue.cx) or (fimagesize.cy <> avalue.cy) then begin + fimagesize:= avalue; + updatelayout; + end; +end; + +procedure tfoldedit.setimagelist(const avalue: timagelist); +begin + if fimagelist <> avalue then begin + setlinkedvar(avalue,tmsecomponent(fimagelist)); + if (fimagelist <> nil) and (csdesigning in componentstate) then begin + fimagesize:= fimagelist.size; + end; + updatelayout; +// invalidate; + end; +end; + +procedure tfoldedit.setimagelistvalue(const avalue: timagelist); +begin + if fimagelistvalue <> avalue then begin + setlinkedvar(avalue,tmsecomponent(fimagelistvalue)); + if (fimagelistvalue <> nil) and (csdesigning in componentstate) then begin + fimagesize:= fimagelistvalue.size; + end; + updatelayout; +// invalidate; + end; +end; + +procedure tfoldedit.setimnr_base(const avalue: integer); +begin + if fimnr_base <> avalue then begin + fimnr_base:= avalue; + formatchanged; + end; +end; + +procedure tfoldedit.setimnr_expanded(const avalue: integer); +begin + if fimnr_expanded <> avalue then begin + fimnr_expanded:= avalue; + formatchanged; + end; +end; + +procedure tfoldedit.setimnr_selected(const avalue: integer); +begin + if fimnr_selected <> avalue then begin + fimnr_selected:= avalue; + formatchanged; + end; +end; + +procedure tfoldedit.setimnr_readonly(const avalue: integer); +begin + if fimnr_readonly <> avalue then begin + fimnr_readonly:= avalue; + formatchanged; + end; +end; + +procedure tfoldedit.setimnr_subitems(const avalue: integer); +begin + if fimnr_subitems <> avalue then begin + fimnr_subitems:= avalue; + formatchanged; + end; +end; + +procedure tfoldedit.setimnr_value(const avalue: integer); +begin + if fimnr_value <> avalue then begin + fimnr_value:= avalue; + valuechanged; + end; +end; + +procedure tfoldedit.setimnr_valuebase(const avalue: integer); +begin + if fimnr_valuebase <> avalue then begin + fimnr_valuebase:= avalue; + formatchanged; + end; +end; + +procedure tfoldedit.setimnr_valueexpanded(const avalue: integer); +begin + if fimnr_valueexpanded <> avalue then begin + fimnr_valueexpanded:= avalue; + formatchanged; + end; +end; + +procedure tfoldedit.setimnr_valueselected(const avalue: integer); +begin + if fimnr_valueselected <> avalue then begin + fimnr_valueselected:= avalue; + formatchanged; + end; +end; + +procedure tfoldedit.setimnr_valuereadonly(const avalue: integer); +begin + if fimnr_valuereadonly <> avalue then begin + fimnr_valuereadonly:= avalue; + formatchanged; + end; +end; + +procedure tfoldedit.setimnr_valuesubitems(const avalue: integer); +begin + if fimnr_valuesubitems <> avalue then begin + fimnr_valuesubitems:= avalue; + formatchanged; + end; +end; + +procedure tfoldedit.updatelayout; +begin + formatchanged; +end; + +function tfoldedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= tgridmsestringintdatalist.create(sender); +end; + +function tfoldedit.getdefaultvalue: pointer; +begin + result:= @fdefault; +end; + +function tfoldedit.imageshift(arow: integer): integer; +begin + result:= 0; + if fimagelist <> nil then begin + inc(result,fimagesize.cx); + end; + if fgridintf <> nil then begin + with fgridintf.getcol.grid do begin + if arow < 0 then begin + arow:= row; + end; + if arow >= 0 then begin + inc(result,(rowfoldlevel[arow]+1)*flevelstep); + end; + end; + end; +end; + +procedure tfoldedit.setupeditor; +var + int1: integer; + rect1,rect2: rectty; +begin + inherited; + int1:= imageshift(-1); + if int1 > 0 then begin + rect1:= feditor.cliprect; + rect2:= feditor.destrect; + inc(rect1.x,int1); + dec(rect1.cx,int1); + if rect1.cx < 0 then begin + rect1.cx:= 0; + end; + inc(rect2.x,int1); + dec(rect2.cx,int1); + if rect2.cx < 0 then begin + rect2.cx:= 0; + end; + feditor.updatepos(rect2,rect1); + end; +end; + +function tfoldedit.getgridimnr(index: integer): integer; +var + list: tdatalist; +begin + list:= checkgriddata(index); + if list <> nil then begin + result:= tmsestringintdatalist(list).itemsb[index]; + end + else begin + result:= -1; + end; +end; + +procedure tfoldedit.setgridimnr(index: integer; const avalue: integer); +var + list: tdatalist; +begin + list:= checkgriddata(index); + if list <> nil then begin + tmsestringintdatalist(list).itemsb[index]:= avalue; + end; +end; + +function tfoldedit.getgridimnrs: integerarty; +begin + checkgrid; + result:= tmsestringintdatalist(fgridintf.getcol.datalist).asarrayb; +end; + +procedure tfoldedit.setgridimnrs(const avalue: integerarty); +begin + checkgrid; + tmsestringintdatalist(fgridintf.getcol.datalist).asarrayb:= avalue; +end; + +procedure tfoldedit.gridtovalue(arow: integer); +var + val1: msestringintty; +begin + fgridintf.getdata(arow,val1); + fvalue:= val1.mstr; + fimnr_value:= val1.int; + valuetotext; +end; + +procedure tfoldedit.valuetogrid(arow: integer); +var + val1: msestringintty; +begin + val1.mstr:= fvalue; + val1.int:= fimnr_value; + fgridintf.setdata(arow,val1); +end; + +procedure tfoldedit.writestatvalue(const writer: tstatwriter); +begin + inherited; + writer.writeinteger(valuevarname+'_imnr',fimnr_value); +end; + +procedure tfoldedit.readstatvalue(const reader: tstatreader); +begin + inherited; + if fgridintf = nil then begin + imnr_value:= reader.readinteger(valuevarname+'_imnr',imnr_value); + end; +end; + +procedure tfoldedit.synctofontheight; +var + size1: sizety; +begin + inherited; + size1:= paintsize; + if size1.cy < fimagesize.cy then begin + size1.cy:= fimagesize.cy; + paintsize:= size1; + if fgridintf <> nil then begin + fgridintf.getcol.grid.datarowheight:= bounds_cy; + end; + end; +end; + +procedure tfoldedit.dolevelup(const sender: tobject); +begin + with fgridintf.getgrid do begin + rowfoldlevel[-1]:= rowfoldlevel[-1] + 1; + end; +end; + +procedure tfoldedit.doleveldown(const sender: tobject); +begin + with fgridintf.getgrid do begin + rowfoldlevel[-1]:= rowfoldlevel[-1] - 1; + end; +end; + +procedure tfoldedit.doissum(const sender: tobject); +begin + with fgridintf.getgrid do begin + rowfoldissum[-1]:= not rowfoldissum[-1]; + end; +end; + +procedure tfoldedit.updatepopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); +var + state1: actionstatesty; +begin + inherited; + if fgridintf <> nil then begin + if feo_menulevel in foptions then begin + tpopupmenu.additems(amenu,self,mouseinfo,['Levelup','Leveldown'], + [],[],[{$ifdef FPC}@{$endif}dolevelup, + {$ifdef FPC}@{$endif}doleveldown]); + end; + if feo_menuissum in foptions then begin + state1:= []; + if fgridintf.getgrid.rowfoldissum[-1] then begin + state1:= [as_checked]; + end; + tpopupmenu.additems(amenu,self,mouseinfo,['Issum'], + [[mao_checkbox]],[state1],[{$ifdef FPC}@{$endif}doissum],false); + end; + end; +end; + +function tfoldedit.getcellcursor(const arow: integer; + const acellzone: cellzonety; const apos: pointty): cursorshapety; +begin + if acellzone = cz_caption then begin + result:= inherited getcellcursor(arow,acellzone,apos); + end + else begin + result:= cr_arrow; + end; +end; + +{ +function tfoldedit.getinnerframe: framety; +begin + result:= inherited getinnerframe; +// result.left:= result.left + imageshift(-1); +end; +} +function createtgridmsestringintdatalist(const aowner:twidgetcol): tdatalist; +begin + result:= tgridmsestringintdatalist.create(aowner); +end; + +initialization + registergriddatalistclass(tgridmsestringintdatalist.classname, + {$ifdef FPC}@{$endif}createtgridmsestringintdatalist); +end. diff --git a/mseide-msegui/lib/common/editwidgets/msegraphedits.pas b/mseide-msegui/lib/common/editwidgets/msegraphedits.pas new file mode 100644 index 0000000..fcb2015 --- /dev/null +++ b/mseide-msegui/lib/common/editwidgets/msegraphedits.pas @@ -0,0 +1,5180 @@ +{ MSEgui Copyright (c) 1999-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msegraphedits; +{$ifdef FPC} + {$mode objfpc}{$h+} +{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,msegui, + mseglob,mseguiglob,msescrollbar,msegraphutils,msegraphics,mseevent, + msewidgets,mseeditglob,msestockobjects,msestat,msestatfile,mseassistiveclient, + mseclasses,msesimplewidgets,msemenus,mseact,typinfo,msedragglob, + msegrids,msewidgetgrid,msedatalist,msebitmap,msetypes,msestrings,msearrayprops, + msedrawtext,mseshapes + {$ifdef mse_with_ifi}{,mseifi},mseifiglob,mseificomp,mseificompglob{$endif}, + msepointer,msegridsglob; + +const + defaultsliderwidth = 200; + defaultsliderheight = 20; + defaultboxsize = 13; + defaultsliderscrollbaroptions = defaultscrollbaroptions + + [sbo_valuekeys,sbo_thumbtrack]; + defaultgrapheditframeoptions = defaultcaptionframeoptions + [cfo_captionfocus]; + +type + tgrapheditframe = class(tcustomcaptionframe) + protected +// function getdefaultcolorclient: colorty; virtual; +// function actualcolorclient(): colorty override; + public + constructor create(const aintf: icaptionframe); + published + property options default defaultgrapheditframeoptions; + property levelo default -2; + property leveli; + property framewidth; + property colorframe; + property colorframeactive; + property colorframedisabled; + property colorframemouse; + property colorframeclicked; + property colorframedefault; + property colordkshadow; + property colorshadow; + property colorlight; + property colorhighlight; + property colordkwidth; + property colorhlwidth; + property hiddenedges; + property framei_left; + property framei_top; + property framei_right; + property framei_bottom; + property frameo_left; + property frameo_top; + property frameo_right; + property frameo_bottom; + + property frameimage_list; + property frameimage_left; + property frameimage_top; + property frameimage_right; + property frameimage_bottom; + property frameimage_offset; + property frameimage_offset1; + property frameimage_offsetdisabled; + property frameimage_offsetmouse; + property frameimage_offsetclicked; + property frameimage_offsetactive; + property frameimage_offsetfocused; +{ + property frameimage_offsetactivemouse; + property frameimage_offsetactiveclicked; +} + property frameface_list; + property frameface_offset; + property frameface_offset1; + property frameface_offsetdisabled; + property frameface_offsetmouse; + property frameface_offsetclicked; + property frameface_offsetactive; + property frameface_offsetfocused; +{ + property frameface_offsetactivemouse; + property frameface_offsetactiveclicked; +} + property colorclient {default cl_transparent}; + property caption; + property captionpos default cp_right; + property captiondist; + property captionoffset; + property font; + property localprops; //before template + property localprops1; //before template + property template; + end; + + ttogglegrapheditframe = class(tgrapheditframe) + protected + function actualcolorclient: colorty override; + published + property colorclient {default cl_foreground}; + end; + + tgraphdataedit = class(tactionpublishedwidget,igridwidget,istatfile, + iassistiveclientgridwidget + {$ifdef mse_with_ifi},iifidatalink{$endif}) + private + fonchange: notifyeventty; + fondataentered: notifyeventty; + fcolorglyph: colorty; + fstatvarname: msestring; + fstatfile: tstatfile; + foptionsedit: optionseditty; + foptionsedit1: optionsedit1ty; + fedited: boolean; + fvalueread: boolean; + fstatpriority: integer; + procedure setcolorglyph(const Value: colorty); + procedure setstatfile(const Value: tstatfile); + procedure setoptionsedit(const avalue: optionseditty); + function getreadonly: boolean; + procedure setreadonly(const avalue: boolean); + procedure setedited(const avalue: boolean); virtual; + procedure setoptionsedit1(const avalue: optionsedit1ty); + protected + fdatalist: tdatalist; + fgridintf: iwidgetgrid; + fgriddatalink: pointer; + fparentintf: igridwidget; + fstate: dataeditstatesty; +{$ifdef mse_with_ifi} + fifilink: tifivaluelinkcomp; + function getdefaultifilink: iificlient; override; + procedure ifisetvalue(var avalue; var accept: boolean); + procedure getifivalue(var avalue) virtual; + procedure setifivalue(const avalue) virtual; + function getifilinkkind: ptypeinfo; + procedure setifilink(const avalue: tifilinkcomp); + function getifilink: tifilinkcomp; + //iificlient + function getifidatatype(): listdatatypety override; +// function ifigriddata: tdatalist; + procedure updateifigriddata(const sender: tobject; const alist: tdatalist); + function getgriddata: tdatalist; + function getvalueprop: ppropinfo; + function getiassistiveclient(): iassistiveclient override; + //iassistiveclientgridwidget + function getifidatalinkintf(): iifidatalink; override; + function getassistiveflags: assistiveflagsty; override; + function getassistivecolumncaption(): msestring virtual; +{$endif} + function getedited: boolean; virtual; + function geteditstate: dataeditstatesty; + procedure seteditstate(const avalue: dataeditstatesty); + function getoptionsedit: optionseditty; virtual; + procedure updateoptions; virtual; + procedure loaded; override; + procedure internalcreateframe; override; + procedure enabledchanged() override; + procedure setenabled(const avalue: boolean); override; + procedure dofocus; override; + + function getgridintf: iwidgetgrid; + procedure checkgrid; + function checkgriddata: tdatalist; + procedure internalfillcol(const value); + procedure internalassigncol(const value); + procedure internalgetgridvalue(index: integer; out value); + procedure internalsetgridvalue(index: integer; const avalue); + procedure dochange; virtual; + function docheckvalue(var avalue; const quiet: boolean): boolean; virtual; + procedure valuechanged; virtual; + procedure modified; virtual; //for dbwidgets + procedure formatchanged(); + procedure dopaintforeground(const canvas: tcanvas); override; + function needsfocuspaint: boolean; override; + procedure internalcheckvalue(var avalue; var accept: boolean); + virtual; abstract; + procedure paintglyph(const canvas: tcanvas; const acolorglyph: colorty; + const avalue; const arect: rectty); + virtual; abstract; + procedure dofontheightdelta(var delta: integer); override; + procedure sizechanged; override; + + procedure updatereadonlystate; virtual; + procedure initeditfocus; + procedure updatedatalist; virtual; + + //igridwidget + procedure setfirstclick(var ainfo: mouseeventinfoty); + function createdatalist(const sender: twidgetcol): tdatalist; + virtual; abstract; + procedure datalistdestroyed; virtual; + function getdatalistclass: datalistclassty; virtual; abstract; + function getdefaultvalue: pointer; virtual; + function getrowdatapo(const arow: integer): pointer; virtual; + procedure setgridintf(const intf: iwidgetgrid); virtual; + function getcellframe: framety; virtual; + function needscellfocuspaint(): boolean; + function getcellcursor(const arow: integer; const acellzone: cellzonety; + const apos: pointty): cursorshapety; virtual; + procedure updatecellzone(const arow: integer; const apos: pointty; + var result: cellzonety); virtual; + procedure drawcell(const canvas: tcanvas); + procedure updateautocellsize(const canvas: tcanvas); virtual; + procedure beforecelldragevent(var ainfo: draginfoty; const arow: integer; + var handled: boolean); virtual; + procedure aftercelldragevent(var ainfo: draginfoty; const arow: integer; + var handled: boolean); virtual; + procedure valuetogrid(row: integer); virtual; abstract; + procedure gridtovalue(row: integer); virtual; + procedure setvaluedata(const source); virtual; abstract; + procedure getvaluedata(out dest); virtual; abstract; + function getnulltext: msestring; virtual; + function getassistivecelltext(const arow: int32): msestring; virtual; + procedure docellevent(const ownedcol: boolean; + var info: celleventinfoty); virtual; + function sortfunc(const l,r): integer; virtual; + procedure gridvaluechanged(const index: integer); virtual; + procedure updatecoloptions(const aoptions: coloptionsty); + procedure updatecoloptions1(const aoptions: coloptions1ty); + procedure statdataread; virtual; + procedure griddatasourcechanged; virtual; + procedure fontchanged; override; + procedure setparentgridwidget(const intf: igridwidget); + procedure childdataentered(const sender: igridwidget); virtual; + procedure childfocused(const sender: igridwidget); virtual; + + //istatfile + procedure dostatread(const reader: tstatreader); + procedure dostatwrite(const writer: tstatwriter); + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + + procedure readstatvalue(const reader: tstatreader); virtual; + procedure writestatvalue(const writer: tstatwriter); virtual; + procedure readstatstate(const reader: tstatreader); virtual; + procedure writestatstate(const writer: tstatwriter); virtual; + procedure readstatoptions(const reader: tstatreader); virtual; + procedure writestatoptions(const writer: tstatwriter); virtual; + + public + constructor create(aowner: tcomponent); override; + procedure initnewcomponent(const ascale: real); override; + procedure initnewwidget(const ascale: real); override; + procedure initgridwidget; virtual; + procedure paint(const canvas: tcanvas); override; + + property edited: boolean read getedited write setedited; + function actualcolor: colorty; override; + function widgetcol: twidgetcol; + function grid: tcustomwidgetgrid; + function gridrow: integer; + function gridrowhigh: int32; //-1 if no grid + function griddatarowhigh: int32; //-1 if no grid + function gridcol: integer; + function griddata: tdatalist; + + function checkvalue(const quiet: boolean = false): boolean virtual abstract; + function seteditfocus: boolean; + + property objectlinker: tobjectlinker read getobjectlinker + {$ifdef msehasimplements}implements istatfile{$endif}; + property colorglyph: colorty read fcolorglyph write setcolorglyph + default cl_default; + //cl_default -> cl_glyph + property readonly: boolean read getreadonly write setreadonly; + published + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read getstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + property optionsedit: optionseditty read getoptionsedit write setoptionsedit + default defaultoptionsedit; + property optionsedit1: optionsedit1ty read foptionsedit1 + write setoptionsedit1 default defaultoptionsedit1; + property onchange: notifyeventty read fonchange write fonchange; + property ondataentered: notifyeventty read fondataentered + write fondataentered; + end; + + tpointeredit = class; + + paintpointerglypheventty = procedure(const sender: tpointeredit; + const acanvas: tcanvas; const avalue: pointer; + const arow: integer) of object; + + tpointeredit = class(tgraphdataedit) + private + fvalue: pointer; + fonpaintglyph: paintpointerglypheventty; + procedure setvalue(const avalue: pointer); + function getgridvalue(const index: integer): pointer; + procedure setgridvalue(const index: integer; const avalue: pointer); + function getgridvalues: pointerarty; + procedure setgridvalues(const avalue: pointerarty); + protected + procedure setvaluedata(const source); override; + procedure getvaluedata(out dest); override; + function createdatalist(const sender: twidgetcol): tdatalist; override; + function getdatalistclass: datalistclassty; override; + procedure paintglyph(const canvas: tcanvas; const acolorglyph: colorty; + const avalue; const arect: rectty); override; + procedure gridtovalue(arow: integer); override; + procedure valuetogrid(arow: integer); override; + public + procedure initnewcomponent(const ascale: real); override; + property value: pointer read fvalue write setvalue default nil; + property gridvalue[const index: integer]: pointer + read getgridvalue write setgridvalue; default; + property gridvalues: pointerarty read getgridvalues write setgridvalues; + function griddata: tgridpointerdatalist; + published + property visible; + property enabled; + property onpaintglyph: paintpointerglypheventty read fonpaintglyph + write fonpaintglyph; + end; + + tsliderscrollbar = class(tscrollbar,iface) + private + protected + public + constructor create(intf: iscrollbar; org: originty = org_client; + ondimchanged: proceventty = nil); override; + destructor destroy; override; + published + property options default defaultsliderscrollbaroptions; + property buttonlength default defaultbuttonminlength; + end; + + tcustomrealgraphdataedit = class; + + paintrealglypheventty = procedure( + const sender: tcustomrealgraphdataedit; + const acanvas: tcanvas; const avalue: real; + const arow: integer) of object; + + tcustomrealgraphdataedit = class(tgraphdataedit) + private + fonsetvalue: setrealeventty; + fdirection: graphicdirectionty; + fonpaintglyph: paintrealglypheventty; + procedure setvalue(const avalue: realty); + function getgridvalue(const index: integer): realty; + procedure setgridvalue(const index: integer; const avalue: realty); + function getgridvalues: realarty; + procedure setgridvalues(const avalue: realarty); + protected + fvalue: realty; + procedure setvaluedata(const source); override; + procedure getvaluedata(out dest); override; + procedure internalcreateframe; override; + procedure paintglyph(const canvas: tcanvas; const acolorglyph: colorty; + const avalue; const arect: rectty); override; + procedure setdirection(const avalue: graphicdirectionty); virtual; + function createdatalist(const sender: twidgetcol): tdatalist; override; + function getdatalistclass: datalistclassty; override; + procedure valuetogrid(arow: integer); override; + procedure gridtovalue(arow: integer); override; + procedure internalcheckvalue(var avalue; var accept: boolean); override; + procedure readstatvalue(const reader: tstatreader); override; + procedure writestatvalue(const writer: tstatwriter); override; + procedure setnullvalue; virtual; //for dbedits + {$ifdef mse_with_ifi} + function getifilink: tifireallinkcomp; + procedure setifilink(const avalue: tifireallinkcomp); + {$endif} + public + constructor create(aowner: tcomponent); override; + procedure fillcol(const value: realty); + procedure assigncol(const avalue: trealdatalist); + function checkvalue(const quiet: boolean = false): boolean override; + function isnull: boolean; + property gridvalue[const index: integer]: realty + read getgridvalue write setgridvalue; default; + property gridvalues: realarty read getgridvalues write setgridvalues; + function griddata: tgridrealdatalist; + property value: realty read fvalue write setvalue; + property direction: graphicdirectionty read fdirection write setdirection + default gd_right; + property onsetvalue: setrealeventty read fonsetvalue write fonsetvalue; + property onpaintglyph: paintrealglypheventty read fonpaintglyph + write fonpaintglyph; + published + property visible; + property enabled; + property bounds_cx default defaultsliderwidth; + property bounds_cy default defaultsliderheight; + {$ifdef mse_with_ifi} + property ifilink: tifireallinkcomp read getifilink write setifilink; + {$endif} + end; + + trealgraphdataedit = class(tcustomrealgraphdataedit) + published + property value; + property onsetvalue; + property direction; + property onpaintglyph; + end; + + tsliderframe = class(tgrapheditframe) + protected + procedure settemplateinfo(const ainfo: frameinfoty); override; + end; + +const + defaultslideroptionswidget = defaultoptionswidget + [ow_mousewheel]; +type + tcustomslider = class(tcustomrealgraphdataedit,iscrollbar) + private + fscrollbar: tsliderscrollbar; + fupdating: integer; + procedure setscrollbar(const avalue: tsliderscrollbar); + protected + procedure beginpaint(); //disable invalidate and updating + procedure endpaint(); + procedure setdirection(const avalue: graphicdirectionty); override; + procedure objectchanged(const sender: tobject); override; + procedure clientrectchanged; override; + procedure clientmouseevent(var info: mouseeventinfoty); override; + procedure domousewheelevent(var info: mousewheeleventinfoty); override; + procedure dokeydown(var info: keyeventinfoty); override; + procedure doenter; override; + procedure doexit; override; + procedure activechanged; override; + procedure enabledchanged; override; + procedure scrollevent(sender: tcustomscrollbar; event: scrolleventty); + + procedure dochange; override; + procedure paintglyph(const canvas: tcanvas; const acolorglyph: colorty; + const avalue; const arect: rectty); override; + class function classskininfo: skininfoty; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure initgridwidget; override; + property scrollbar: tsliderscrollbar read fscrollbar write setscrollbar; + published + property optionswidget default defaultslideroptionswidget; + end; + + tslider = class(tcustomslider) + published + property value; + property scrollbar; + property onsetvalue; + property direction; + property onpaintglyph; + end; + +const + defaultbarcolor = cl_ltblue; + +type + tbarface = class(tface) + public + constructor create(const intf: iface); reintroduce; + end; + + tcustomprogressbar = class; + + tbarframe = class(tframe) + private + fowner: tcustomprogressbar; + public + constructor create(const aowner: tcustomprogressbar); + end; + + tcustomprogressbar = class(tcustomrealgraphdataedit,iface) + private + fbar_face: tbarface; + fbar_frame: tbarframe; + ffacerect: rectty; + fframebarrect: rectty; + ffacebarrect: rectty; + fvaluerange: real; + fvaluestart: real; + fformat: msestring; + ftextflags: textflagsty; + fonfinished: progresseventty; + fonprogress: progresseventty; + fcancel: boolean; + procedure setvalue(const avalue: realty); + procedure setbar_face(const avalue: tbarface); + procedure updatebarrect(const avalue: realty; const arect: rectty; + out facedest,framebardest,facebardest: rectty); + procedure updatebar; + procedure setvaluerange(const avalue: real); + procedure setvaluestart(const avalue: real); + procedure setformat(const avalue: msestring); + procedure settextflags(const avalue: textflagsty); + procedure setbar_frame(const avalue: tbarframe); + procedure readformat(reader: treader); + procedure writeformat(writer: twriter); + procedure readvaluescale(reader: treader); + protected + procedure clientrectchanged; override; + procedure dochange; override; + procedure paintglyph(const canvas: tcanvas; const acolorglyph: colorty; + const avalue; const arect: rectty); override; + procedure internalcreateframe; override; + procedure defineproperties(filer: tfiler); override; + procedure gridtovalue(arow: integer); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure changedirection(const avalue: graphicdirectionty; + var dest: graphicdirectionty); override; + procedure doprogress(const sender: tobject; const avalue: real; + var acancel: boolean); + //threadsave + property cancel: boolean read fcancel write fcancel; + //ored with doprogress.acancel, resetted by value:= 0.0 + property value: realty read fvalue write setvalue; + //thread safe, range 0 .. 1.0 + published + property onsetvalue; + property direction; + + property optionswidget default defaultoptionswidgetnofocus; + property bar_face: tbarface read fbar_face write setbar_face; + property bar_frame: tbarframe read fbar_frame write setbar_frame; + property valuerange: real read fvaluerange write setvaluerange; //default 100 + property valuestart: real read fvaluestart write setvaluestart; + property format: msestring read fformat write setformat stored false; + //default '0%', '' for no numeric + property textflags: textflagsty read ftextflags write settextflags default + [tf_ycentered,tf_xcentered]; + property font: twidgetfont read getfont write setfont stored isfontstored; + property onprogress: progresseventty read fonprogress write fonprogress; + //called from doprogress + property onfinished: progresseventty read fonfinished write fonfinished; + //called in doprogress if avalue = 1.0 or canceled + end; + + tprogressbar = class(tcustomprogressbar) + published + property value; + property onpaintglyph; + end; + + ttogglegraphdataedit = class(tgraphdataedit) + private + foptions: buttonoptionsty; + function getcheckedrow: integer; + procedure setcheckedrow(const avalue: integer); + function getcheckedtag: integer; + procedure setcheckedtag(const avalue: integer); + protected + fgroup: integer; + fcheckcaption: boolean; + fclickedrow: integer; + fresetting: integer; //for db edits + procedure internalcreateframe; override; + procedure setoptions(const avalue: buttonoptionsty); virtual; + procedure resetradioitems(); + procedure togglevalue(const areadonly: boolean; + const down: boolean) virtual abstract; + procedure docheck() virtual abstract; + procedure douncheck() virtual abstract; + function ischecked(): boolean virtual abstract; + procedure togglegridvalue(const index: integer) virtual abstract; + procedure resetgridvalue(const index: integer) virtual abstract; + procedure checkgridvalue(const index: integer) virtual abstract; + function gridvaluechecked(const aindex: integer): boolean virtual abstract; + procedure mouseevent(var info: mouseeventinfoty) override; + procedure dokeydown(var info: keyeventinfoty) override; + procedure dokeyup(var info: keyeventinfoty) override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget) override; + procedure statechanged; override; + procedure docellevent(const ownedcol: boolean; + var info: celleventinfoty); override; + procedure modified; override; + procedure checkradiorow(aindex: integer); + function internalcheckeditem(out single: boolean): ttogglegraphdataedit; + //nil if none + function navigrect: rectty; override; + public + constructor create(aowner: tcomponent); override; + property group: integer read fgroup write fgroup default 0; + property checkedrow: integer read getcheckedrow write setcheckedrow; + //needs bo_radiotemcol, -1 if none + property checkedtag: integer read getcheckedtag write setcheckedtag; + //-1 if none checked + published + property options: buttonoptionsty read foptions write setoptions + default defaultbuttonoptions; + property colorglyph; + end; + + tcustombooleanedit = class; + booleaneditarty = array of tcustombooleanedit; + + tcustombooleanedit = class(ttogglegraphdataedit) + private + fvalue: longbool; + fvaluedefault: longbool; + fonsetvalue: setbooleaneventty; + procedure setvalue(const Value: boolean); virtual; + function getglyph: stockglyphty; virtual; + function getgridvalue(const index: integer): longbool; + procedure setgridvalue(const index: integer; const Value: longbool); virtual; + function getgridvalues: longboolarty; + procedure setgridvalues(const Value: longboolarty); + function getgridbooleanvalues: booleanarty; + procedure setgridbooleanvalues(const Value: booleanarty); + function getvalue: boolean; + function getvaluedefault: boolean; + procedure setvaluedefault(const Value: boolean); + {$ifdef mse_with_ifi} + function getifilink: tifibooleanlinkcomp; + procedure setifilink(const avalue: tifibooleanlinkcomp); + {$endif} + protected + class function classskininfo: skininfoty; override; + procedure setvaluedata(const source); override; + procedure getvaluedata(out dest); override; + procedure setnullvalue; + function getdefaultvalue: pointer; override; + procedure valuetogrid(arow: integer); override; + procedure gridtovalue(arow: integer); override; + procedure resetgridvalue(const index: integer); override; + procedure checkgridvalue(const index: integer); override; + function gridvaluechecked(const aindex: integer): boolean; override; + function createdatalist(const sender: twidgetcol): tdatalist; override; + function getdatalistclass: datalistclassty; override; + procedure togglevalue(const areadonly: boolean; + const down: boolean); override; + procedure docheck() override; //set value to not valuedefault + procedure douncheck() override; //set value to valuedefault + function ischecked(): boolean; override; + procedure paintglyph(const canvas: tcanvas; const acolorglyph: colorty; + const avalue; const arect: rectty); override; + procedure internalcheckvalue(var avalue; var accept: boolean); override; + procedure readstatvalue(const reader: tstatreader); override; + procedure writestatvalue(const writer: tstatwriter); override; + function getvaluebitmask: longword; + procedure setvaluebitmask(const avalue: longword); + function getgridvaluebitmask(const index: integer): longword; + procedure setgridvaluebitmask(const index: integer; const avalue: longword); + procedure dokeydown(var info: keyeventinfoty); override; + + function getassistivetext(): msestring override; + public + constructor create(aowner: tcomponent); override; + procedure fillcol(const avalue: longbool); + function checkvalue(const quiet: boolean = false): boolean override; + procedure togglegridvalue(const index: integer); override; + + property value: boolean read getvalue write setvalue default false; + property valuedefault: boolean read getvaluedefault + write setvaluedefault default false; + //streaming of longbool does not work on kylix and fpc + property gridvalue[const index: integer]: longbool + read getgridvalue write setgridvalue; default; + function valuetag(const falsevalue: integer): integer; + function valuetagbit: longword; + //if value -> bits[tag] else -> 0 + function gridvaluetagbit(const index: integer): longword; + //if value -> bits[tag] else -> 0 + property valuebitmask: longword read getvaluebitmask write setvaluebitmask; + //ored valuetagbit of all edits in group + property gridvaluebitmask[const index: integer]: longword + read getgridvaluebitmask write setgridvaluebitmask; + //ored valuetagbit of all edits in group + + function gridvaluetag(const index: integer; + const falsevalue: integer): integer; + //if value = true -> tag, falsevalue otherwise + procedure updatetagvalue(const bitset: integer); + //value -> true if bitset and tag <> 0 + procedure gridupdatetagvalue(const index: integer; const bitset: integer); + property gridvalues: longboolarty read getgridvalues write setgridvalues; + property gridbooleanvalues: booleanarty read getgridbooleanvalues + write setgridbooleanvalues; + function griddata: tgridintegerdatalist; + function groupmembers: booleaneditarty; + function tagitem(const atag: integer): tcustombooleanedit; //nil if none + + property bounds_cx default defaultboxsize; + property bounds_cy default defaultboxsize; + property onsetvalue: setbooleaneventty read fonsetvalue write fonsetvalue; +{$ifdef mse_with_ifi} + property ifilink: tifibooleanlinkcomp read getifilink write setifilink; +{$endif} + published + property visible; + property enabled; + end; + + tbooleanedit = class(tcustombooleanedit) + published + property bounds_cx default defaultboxsize; + property bounds_cy default defaultboxsize; + property onsetvalue; + property value; + property valuedefault; + property group; +{$ifdef mse_with_ifi} + property ifilink; +{$endif} + end; + + tcustombooleaneditradio = class(tcustombooleanedit) + private + function getglyph: stockglyphty; override; +// procedure reset; + procedure setvalue(const avalue: boolean) override; + procedure setgridvalue(const aindex: integer; + const aValue: longbool) override; + protected + procedure togglevalue(const areadonly: boolean; + const down: boolean) override; + public + procedure togglegridvalue(const index: integer) override; + function checkeditem: tcustombooleaneditradio; //nil if none + end; + + tbooleaneditradio = class(tcustombooleaneditradio) + published + property bounds_cx default defaultboxsize; + property bounds_cy default defaultboxsize; + property onsetvalue; + property value; + property valuedefault; + property group; +{$ifdef mse_with_ifi} + property ifilink; +{$endif} + end; + + tcustomintegergraphdataedit = class; + + paintintegerglypheventty = procedure( + const sender: tcustomintegergraphdataedit; + const acanvas: tcanvas; const avalue: integer; + const arow: integer) of object; + + tcustomintegergraphdataedit = class(ttogglegraphdataedit) + private + fvalue: integer; + fvaluedefault: integer; + fonsetvalue: setintegereventty; + fvaluemin: integer; + fvaluemax: integer; +// fdatalist: tintegerdatalist; + fonpaintglyph: paintintegerglypheventty; + procedure setvalue(const avalue: integer); + function getgridvalue(const index: integer): integer; + procedure setgridvalue(const index, Value: integer); + function getgridvalues: integerarty; + procedure setgridvalues(const Value: integerarty); + {$ifdef mse_with_ifi} + function getifilink: tifiintegerlinkcomp; + procedure setifilink(const avalue: tifiintegerlinkcomp); + {$endif} + procedure setvaluemin(const avalue: integer); + procedure setvaluemax(const avalue: integer); + function getdatalist: tintegerdatalist; + procedure readmin(reader: treader); + procedure readmax(reader: treader); + protected +// procedure setgridintf(const intf: iwidgetgrid); override; + procedure setvaluedata(const source); override; + procedure getvaluedata(out dest); override; + function createdatalist(const sender: twidgetcol): tdatalist; override; + function getdatalistclass: datalistclassty; override; + function getdefaultvalue: pointer; override; + procedure valuetogrid(arow: integer); override; + procedure gridtovalue(arow: integer); override; + procedure resetgridvalue(const index: integer); override; + procedure checkgridvalue(const index: integer); override; + function gridvaluechecked(const aindex: integer): boolean; override; + procedure internalcheckvalue(var avalue; var accept: boolean); override; + procedure readstatvalue(const reader: tstatreader); override; + procedure writestatvalue(const writer: tstatwriter); override; + procedure togglevalue(const areadonly: boolean; + const down: boolean); override; + function ischecked(): boolean; override; + procedure docheck() override; //set value to valuedefault+1 + procedure douncheck() override; //set value to valuedefault + function doinc(var avalue: integer; const down: boolean): boolean; + //false if no change + procedure paintglyph(const canvas: tcanvas; const acolorglyph: colorty; + const avalue; const arect: rectty); override; + procedure datalistdestroyed; override; + procedure updatedatalist; override; + procedure defineproperties(filer: tfiler) override; + public + function checkvalue(const quiet: boolean = false): boolean override; + procedure togglegridvalue(const index: integer); override; + procedure fillcol(const avalue: integer); + property gridvalue[const index: integer]: integer + read getgridvalue write setgridvalue; default; + property gridvalues: integerarty read getgridvalues write setgridvalues; + function griddata: tgridintegerdatalist; + property datalist: tintegerdatalist read getdatalist; + property onsetvalue: setintegereventty read fonsetvalue write fonsetvalue; + property value: integer read fvalue write setvalue default 0; + property valuedefault: integer read fvaluedefault + write fvaluedefault default 0; + property valuemin: integer read fvaluemin write setvaluemin default 0; + //checked by togglevalue + property valuemax: integer read fvaluemax write setvaluemax default 0; + //checked by togglevalue + property onpaintglyph: paintintegerglypheventty read fonpaintglyph + write fonpaintglyph; + published + {$ifdef mse_with_ifi} + property ifilink: tifiintegerlinkcomp read getifilink write setifilink; + {$endif} + end; + + tcustomdatabutton = class; + + tvaluefacearrayprop = class(tpersistentarrayprop) + private + fowner: tcustomdatabutton; + protected + function getitems(const index: integer): tface; + procedure createitem(const index: integer; var item: tpersistent); override; + public + constructor create(const aowner: tcustomdatabutton); + class function getitemclasstype: persistentclassty; override; + property items[const index: integer]: tface read getitems; default; + end; + + databuttoneventty = procedure(const sender: tcustomdatabutton) of object; + + tvaluefontarrayprop = class(tpersistentarrayprop) + private + fowner: tcustomdatabutton; + procedure setitems(const index: integer; const avalue: tfont); + protected + function getitems(const index: integer): tfont; + procedure createitem(const index: integer; var item: tpersistent); override; + procedure fontchange(const sender: tobject); + public + constructor create(const aowner: tcustomdatabutton); + class function getitemclasstype: persistentclassty; override; + //used in dumpunitgroups + property items[const index: integer]: tfont read getitems + write setitems; default; + end; + + tcustomdatabutton = class(tcustomintegergraphdataedit,iactionlink,iimagelistinfo) + private +// fonexecute: notifyeventty; + fvaluefaces: tvaluefacearrayprop; + fimageoffset: integer; + fimagenums: tintegerarrayprop; + fimagenr: integer; + fimagenrdisabled: integer; + fimageoffsetdisabled: integer; + fimageoffsetmouse: integer; + fimageoffsetclicked: integer; + fvaluecaptions: tmsestringarrayprop; + fonupdate: databuttoneventty; + fvaluedisabled: integer; + fvaluefonts: tvaluefontarrayprop; + procedure setcolorglyph(const avalue: colorty); + function iscolorglyphstored: boolean; + procedure setvaluefaces(const avalue: tvaluefacearrayprop); + procedure setvaluecaptions(const avalue: tmsestringarrayprop); + procedure setcaption(const avalue: captionty); + function iscaptionstored: boolean; + function getimagelist: timagelist; + procedure setimagelist(const avalue: timagelist); + function isimageliststored: Boolean; + procedure setcaptiondist(const avalue: integer); + procedure setimagepos(const avalue: imageposty); + procedure setimagenr(const avalue: imagenrty); + function isimagenrstored: boolean; + procedure setimageoffset(const avalue: integer); + procedure setimagenums(const avalue: tintegerarrayprop); + procedure setimagenrdisabled(const avalue: imagenrty); + function isimagenrdisabledstored: Boolean; + procedure setimageoffsetdisabled(const avalue: integer); + procedure setimagedist(const avalue: integer); + procedure setimagedist1(const avalue: integer); + procedure setimagedist2(const avalue: integer); + procedure setshortcut(const avalue: shortcutty); + function isshortcutstored: boolean; + function getshortcut: shortcutty; + function getshortcut1: shortcutty; + procedure setshortcut1(const avalue: shortcutty); + function isshortcut1stored: boolean; + procedure setonexecute(const avalue: notifyeventty); + function isonexecutestored: boolean; + procedure setonbeforeexecute(const avalue: accepteventty); + function isonbeforeexecutestored: boolean; + procedure setonafterexecute(const avalue: notifyeventty); + function isonafterexecutestored: boolean; + procedure setstate(const avalue: actionstatesty); + function isstatestored: boolean; + + procedure setaction(const avalue: tcustomaction); + procedure readcaptionpos(reader: treader); + procedure settextflags(const avalue: textflagsty); + procedure setshortcuts(const avalue: shortcutarty); + procedure setshortcuts1(const avalue: shortcutarty); + procedure readshortcut(reader: treader); + procedure readshortcut1(reader: treader); + procedure readsc(reader: treader); + procedure writesc(writer: twriter); + procedure readsc1(reader: treader); + procedure writesc1(writer: twriter); + procedure setimageoffsetmouse(const avalue: integer); + procedure setimageoffsetclicked(const avalue: integer); + procedure setvaluedisabled(const avalue: integer); + procedure setvaluefonts(const avalue: tvaluefontarrayprop); + protected + finfo: shapeinfoty; + factioninfo: actioninfoty; + procedure doidle(var again: boolean); + procedure internalexecute; + procedure doasyncevent(var atag: integer); override; + procedure defineproperties(filer: tfiler); override; + procedure loaded; override; + procedure setenabled(const avalue: boolean); override; + procedure setvisible(const avalue: boolean); override; + + procedure docellevent(const ownedcol: boolean; + var info: celleventinfoty); override; + procedure gridtovalue(arow: integer); override; + + procedure setcolor(const avalue: colorty); override; + procedure objectchanged(const sender: tobject); override; + function getassistiveflags(): assistiveflagsty override; + function getassistivecaption(): msestring override; + + //iactionlink + function getactioninfopo: pactioninfoty; + function shortcutseparator: msechar; + procedure calccaptiontext(var ainfo: actioninfoty); + procedure actionchanged; + + procedure setnullvalue; + procedure doexecute; virtual; + procedure domousewheelevent(var info: mousewheeleventinfoty); override; + procedure togglevalue(const areadonly: boolean; + const down: boolean); override; + procedure statechanged; override; + function valueenabledstate(const avalue: integer): boolean; + procedure checkdisabled(); + procedure valuechanged(); override; + + procedure mouseevent(var info: mouseeventinfoty); override; + procedure dokeydown(var info: keyeventinfoty); override; + procedure dokeyup(var info: keyeventinfoty); override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; + procedure clientrectchanged; override; +// function getframestateflags: framestateflagsty; override; + procedure paintglyph(const canvas: tcanvas; const acolorglyph: colorty; + const avalue; const arect: rectty); override; + procedure internalcreateframe; override; + procedure setgridintf(const intf: iwidgetgrid); override; + function checkfocusshortcut(var info: keyeventinfoty): boolean; override; + procedure setactualimagenr(const avalue: integer); + procedure setoptions(const avalue: buttonoptionsty); override; + function verticalfontheightdelta: boolean; override; + + class function classskininfo: skininfoty; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure execute(); + procedure initnewwidget(const ascale: real); override; + procedure updatehotkeys() override; + procedure doupdate; + procedure synctofontheight; override; + procedure initgridwidget; override; + procedure initnewcomponent(const ascale: real); override; + procedure togglegridvalue(const index: integer); override; + function checkeditem: tcustomdatabutton; //nil if none + property valuefaces: tvaluefacearrayprop read fvaluefaces + write setvaluefaces; + property valuecaptions: tmsestringarrayprop read fvaluecaptions + write setvaluecaptions; + property valuefonts: tvaluefontarrayprop read fvaluefonts + write setvaluefonts; + property font: twidgetfont read getfont write setfont stored isfontstored; + property action: tcustomaction read factioninfo.action write setaction; + property caption: captionty read factioninfo.captiontext write setcaption + stored iscaptionstored; + property textflags: textflagsty read finfo.ca.textflags + write settextflags default defaultcaptiontextflags; + property imagepos: imageposty read finfo.ca.imagepos write setimagepos + default ip_center; +// property captionpos: captionposty read finfo.ca.captionpos write setcaptionpos +// default cp_center; + property captiondist: integer read finfo.ca.captiondist write setcaptiondist + default defaultshapecaptiondist; + property imagelist: timagelist read getimagelist write setimagelist + stored isimageliststored; + property imagenr: imagenrty read factioninfo.imagenr write setimagenr + stored isimagenrstored default -1; + property imagenrdisabled: imagenrty read factioninfo.imagenrdisabled + write setimagenrdisabled + stored isimagenrdisabledstored default -2; + //-1 = none, -2 = grayed, -3 = imageoffsetdisabled + property imagedist: integer read finfo.ca.imagedist + write setimagedist default 0; + property imagedist1: integer read finfo.ca.imagedist1 + write setimagedist1 default 0; + property imagedist2: integer read finfo.ca.imagedist2 + write setimagedist2 default 0; + property colorglyph: colorty read factioninfo.colorglyph write setcolorglyph + stored iscolorglyphstored default cl_default; + property shortcut: shortcutty read getshortcut write setshortcut + stored false default 0; + property shortcut1: shortcutty read getshortcut1 write setshortcut1 + stored false default 0; + property shortcuts: shortcutarty read factioninfo.shortcut + write setshortcuts; + property shortcuts1: shortcutarty read factioninfo.shortcut1 + write setshortcuts1; + property onupdate: databuttoneventty read fonupdate write fonupdate; + property onexecute: notifyeventty read factioninfo.onexecute + write setonexecute stored isonexecutestored; + property onbeforeexecute: accepteventty read factioninfo.onbeforeexecute + write setonbeforeexecute stored isonbeforeexecutestored; + property onafterexecute: notifyeventty read factioninfo.onafterexecute + write setonafterexecute stored isonafterexecutestored; + + property imageoffset: integer read fimageoffset + write setimageoffset default 0; + property imageoffsetdisabled: integer read fimageoffsetdisabled + write setimageoffsetdisabled default 0; + property imageoffsetmouse: integer read fimageoffsetmouse + write setimageoffsetmouse default 0; + property imageoffsetclicked: integer read fimageoffsetclicked + write setimageoffsetclicked default 0; + property imagenums: tintegerarrayprop read fimagenums write setimagenums; + + property options; + property focusrectdist: integer read finfo.focusrectdist + write finfo.focusrectdist default defaultshapefocusrectdist; + property onsetvalue; + property value default -1; + property valuedefault default -1; + property valuedisabled: integer read fvaluedisabled + write setvaluedisabled default -2; + //button.enabled:= value <> valuedisabled + //-2 -> not checked + property valuemin default -1; + property valuemax default 0; + property optionswidget default defaultoptionswidget - [ow_mousefocus]; + published + property visible stored false; + property enabled stored false; + property state: actionstatesty read factioninfo.state write setstate + stored isstatestored default []; + end; + + tdatabutton = class(tcustomdatabutton) + published + property optionswidget; + property optionsskin; + property valuefaces; + property valuecaptions; + property valuefonts; + property font; + + property action; + property caption; + property textflags; + property shortcut; + property shortcut1; + property imagepos; + property captiondist; + property imagelist; + property imagenr; + property imagenrdisabled; + property imagedist; + property imagedist1; + property imagedist2; + property colorglyph; + property options; + property focusrectdist; + property onupdate; + property onexecute; + property onbeforeexecute; + property onafterexecute; + property onmouseevent; + property onclientmouseevent; + + property imageoffset; + property imageoffsetdisabled; + property imageoffsetmouse; + property imageoffsetclicked; + property imagenums; + property onsetvalue; + property onpaintglyph; + property group; + property value; + property valuedefault; + property valuemin; + property valuemax; + property valuedisabled; + end; + + tstockglyphdatabutton = class(tcustomdatabutton) + private + fglyph: stockglyphty; + procedure setglyph(const avalue: stockglyphty); + public + constructor create(aowner: tcomponent); override; + published + property action; + + property glyph: stockglyphty read fglyph write setglyph default stg_none; + property imagenums; + property optionswidget; + property optionsskin; + property valuefaces; + property font; + property caption; + property textflags; + property imagepos; + property captiondist; + property options; + property imagedist; + property imagedist1; + property imagedist2; + property focusrectdist; + property onupdate; + property onexecute; + property onbeforeexecute; + property onafterexecute; + property onsetvalue; + property onpaintglyph; + property onmouseevent; + property onclientmouseevent; + property value; + property valuedefault; + property valuemin; + property valuemax; + property valuedisabled; + end; + + tcustomdataicon = class(tcustomintegergraphdataedit) + //if value = -1 then blank else + // if value < 0 then imagenums[0..30] are painted if bit[0..30] is 1 + // else image[value] is painted + private + fimagelist: timagelist; + fimageoffset: integer; + fimagenums: tintegerarrayprop; + procedure setimagelist(const aValue: timagelist); + procedure setimageoffset(const aValue: integer); + procedure imagenumschanged(const sender: tarrayprop; const index: integer); + procedure setimagenums(const avalue: tintegerarrayprop); + protected + procedure setnullvalue; + procedure paintglyph(const canvas: tcanvas; const acolorglyph: colorty; + const avalue; const arect: rectty); override; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property imagelist: timagelist read fimagelist write setimagelist; + property imageoffset: integer read fimageoffset write setimageoffset default 0; + property imagenums: tintegerarrayprop read fimagenums write setimagenums; + property valuedefault default -1; + property value default -1; + published + property visible; + property enabled; + end; + + tdataicon = class(tcustomdataicon) + published + property onsetvalue; + property onpaintglyph; + property value default -1; + property valuedefault default -1; + property valuemin; + property valuemax; + property imagelist; + property imageoffset; + property imagenums; + end; + +implementation +uses + SysUtils,msekeyboard,msebits,msereal,msedispwidgets,mseformatstr,mserichstring, + mseactions,msestreaming,mseassistiveserver; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tcustomframe1 = class(tcustomframe); + tdatalist1 = class(tdatalist); + twidgetcol1 = class(twidgetcol); + twidget1 = class(twidget); + tarrayprop1 = class(tarrayprop); + tcustomwidgetgrid1 = class(tcustomwidgetgrid); + twidgetdatacol1 = class(twidgetcol); + +const + valuevarname = 'value'; + +{ tgrapheditframe } + +constructor tgrapheditframe.create(const aintf: icaptionframe); +begin + inherited; + options:= defaultgrapheditframeoptions; + fstate:= fstate + [fs_drawfocusrect,fs_captionfocus,fs_captionhint, + fs_paintrectfocus]; + fi.levelo:= -2; + captionpos:= cp_right; + internalupdatestate; +end; +{ +function tgrapheditframe.actualcolorclient(): colorty; +begin + result:= fi.colorclient; + if result = cl_default then begin + result:= cl_transparent; + end; +end; +} +{ +function tgrapheditframe.getdefaultcolorclient: colorty; +begin + result:= cl_transparent; +end; +} +{ ttogglegrapheditframe } + +function ttogglegrapheditframe.actualcolorclient: colorty; +begin + result:= fi.colorclient; + if result = cl_default then begin + result:= cl_foreground; + end; +end; +{ +function ttogglegrapheditframe.getdefaultcolorclient: colorty; +begin + result:= cl_foreground; +end; +} +{ tsliderscrollbar } + +constructor tsliderscrollbar.create(intf: iscrollbar; org: originty; + ondimchanged: proceventty); +begin + inherited; + foptions:= defaultsliderscrollbaroptions; + buttonlength:= defaultbuttonminlength; +// fface:= tface.create(iface(self)); +end; + +destructor tsliderscrollbar.destroy; +begin + inherited; +end; + +{ +function tsliderscrollbar.getwidget: twidget; +begin + result:= fintf.getwidget; +end; +} +{ +function tsliderscrollbar.translatecolor(const acolor: colorty): colorty; +begin + result:= fintf.translatecolor(acolor); +end; + +procedure tsliderscrollbar.paint(const canvas: tcanvas; + const acolor: colorty = cl_none); +begin + if fface <> nil then begin + fface.paint(canvas,fdrawinfo.scrollrect); + end; + inherited; +end; +} +{ +procedure tsliderscrollbar.invalidate; +begin + fintf.getwidget.invalidate; +end; +} +{ +function tsliderscrollbar.getclientrect: rectty; +begin + result:= fintf.getwidget.clientrect; +end; +} +{ +procedure tsliderscrollbar.setlinkedvar(const source: tmsecomponent; + var dest: tmsecomponent; const linkintf: iobjectlink = nil); +begin + twidget1(fintf.getwidget).setlinkedvar(source,dest,linkintf); +end; +} +{ +function tsliderscrollbar.getcomponentstate: tcomponentstate; +begin + result:= fintf.getwidget.componentstate; +end; +} +{ +procedure tsliderscrollbar.widgetregioninvalid; +begin + twidget1(fintf.getwidget).widgetregioninvalid; +end; +} +{ tcustomrealgraphdataedit } + +constructor tcustomrealgraphdataedit.create(aowner: tcomponent); +begin + inherited; + size:= makesize(defaultsliderwidth,defaultsliderheight); +end; + +procedure tcustomrealgraphdataedit.setvalue(const avalue: realty); +begin + if fvalue <> avalue then begin + if not (des_isdb in fstate) and (avalue = emptyreal) then begin + fvalue:= 0; + end + else begin + fvalue:= avalue; + end; + valuechanged; + end; +end; + +function tcustomrealgraphdataedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= tgridrealdatalist.create(sender); +end; + +function tcustomrealgraphdataedit.getdatalistclass: datalistclassty; +begin + result:= tgridrealdatalist; +end; + +procedure tcustomrealgraphdataedit.internalcheckvalue(var avalue; var accept: boolean); +begin + if canevent(tmethod(fonsetvalue)) then begin + fonsetvalue(self,realty(avalue),accept); + end; +{$ifdef mse_with_ifi} + ifisetvalue(avalue,accept); +{$endif} + if accept then begin + value:= realty(avalue); + end; +end; + +procedure tcustomrealgraphdataedit.valuetogrid(arow: integer); +begin + fgridintf.setdata(arow,fvalue); +end; + +procedure tcustomrealgraphdataedit.gridtovalue(arow: integer); +begin + fgridintf.getdata(arow,fvalue); + inherited; +end; + +procedure tcustomrealgraphdataedit.readstatvalue(const reader: tstatreader); +begin + value:= reader.readreal(valuevarname,fvalue); +end; + +procedure tcustomrealgraphdataedit.writestatvalue(const writer: tstatwriter); +begin + writer.writereal(valuevarname,fvalue); +end; + +procedure tcustomrealgraphdataedit.setdirection(const avalue: graphicdirectionty); +begin + if fdirection <> avalue then begin + if not (csreading in componentstate) then begin + changedirection(avalue,fdirection); + end + else begin + fdirection:= avalue; + end; + end; +end; + +function tcustomrealgraphdataedit.getgridvalue(const index: integer): realty; +begin + internalgetgridvalue(index,result); +end; + +procedure tcustomrealgraphdataedit.setgridvalue(const index: integer; + const avalue: realty); +begin + internalsetgridvalue(index,avalue); +end; + +function tcustomrealgraphdataedit.getgridvalues: realarty; +begin + result:= trealdatalist(checkgriddata).asarray; +end; + +procedure tcustomrealgraphdataedit.setgridvalues(const avalue: realarty); +begin + trealdatalist(checkgriddata).asarray:= avalue; +end; + +procedure tcustomrealgraphdataedit.fillcol(const value: realty); +begin + internalfillcol(value); +end; + +procedure tcustomrealgraphdataedit.assigncol(const avalue: trealdatalist); +begin + internalassigncol(avalue); +end; + +function tcustomrealgraphdataedit.isnull: boolean; +begin + result:= value = emptyreal; +end; + +procedure tcustomrealgraphdataedit.setnullvalue; +begin + value:= emptyreal; +end; + +function tcustomrealgraphdataedit.checkvalue( + const quiet: boolean = false): boolean; +begin + result:= docheckvalue(fvalue,quiet); +end; + +{$ifdef mse_with_ifi} +function tcustomrealgraphdataedit.getifilink: tifireallinkcomp; +begin + result:= tifireallinkcomp(fifilink); +end; + +procedure tcustomrealgraphdataedit.setifilink(const avalue: tifireallinkcomp); +begin + inherited setifilink(avalue); +end; + +{$endif} + +function tcustomrealgraphdataedit.griddata: tgridrealdatalist; +begin + result:= tgridrealdatalist(inherited griddata); +end; + +procedure tcustomrealgraphdataedit.paintglyph(const canvas: tcanvas; + const acolorglyph: colorty; const avalue; const arect: rectty); +var + int1: integer; + val1: real; +begin + if canevent(tmethod(fonpaintglyph)) then begin + if @avalue = nil then begin + val1:= fvalue; + int1:= gridrow; + end + else begin + val1:= real(avalue); + int1:= pcellinfoty(canvas.drawinfopo)^.cell.row; + end; + fonpaintglyph(self,canvas,val1,int1); + end; +end; + +procedure tcustomrealgraphdataedit.internalcreateframe; +begin + tsliderframe.create(iscrollframe(self)); +end; + +procedure tcustomrealgraphdataedit.setvaluedata(const source); +begin + value:= realty(source); +end; + +procedure tcustomrealgraphdataedit.getvaluedata(out dest); +begin + realty(dest):= value; +end; + +{ tcustomslider } + +constructor tcustomslider.create(aowner: tcomponent); +begin + fscrollbar:= tsliderscrollbar.create(iscrollbar(self)); +// fscrollbar.options:= [sbo_moveauto]; + inherited; + optionswidget:= defaultslideroptionswidget; + size:= makesize(defaultsliderwidth,defaultsliderheight); +end; + +destructor tcustomslider.destroy; +begin + fscrollbar.Free; + inherited; +end; + +procedure tcustomslider.paintglyph(const canvas: tcanvas; + const acolorglyph: colorty; const avalue; const arect: rectty); +var + rea1,rea2: realty; + col1: colorty; + bo1: boolean; +begin + bo1:= false; + col1:= cl_none; + if @avalue = nil then begin + rea1:= fvalue; + end + else begin + rea1:= realty(avalue); //cell + if (fgridintf <> nil) then begin + with cellinfoty(canvas.drawinfopo^) do begin + col1:= color; + canvas.move(innerrect.pos); + end; + end + else begin + if fparentintf <> nil then begin + canvas.move(arect.pos); //innerrext? + end; + end; + end; + if rea1 = emptyreal then begin + rea1:= 0; + end; + beginpaint(); + rea2:= fscrollbar.value; + if @avalue <> nil then begin //cell + fscrollbar.value:= rea1; + bo1:= fscrollbar.focused; + fscrollbar.focused:= false; + end + else begin + if not fscrollbar.buttonmoving then begin + fscrollbar.value:= rea1; + rea2:= rea1; + end; + end; + fscrollbar.paint(canvas,col1); + fscrollbar.value:= rea2; + if @avalue <> nil then begin + fscrollbar.focused:= bo1; + if (fgridintf <> nil) then begin + canvas.remove(cellinfoty(canvas.drawinfopo^).innerrect.pos); + end + else begin + canvas.remove(arect.pos); //innerrext? + end; + end; + endpaint(); + inherited; +end; + +procedure tcustomslider.setdirection(const avalue: graphicdirectionty); +begin + fscrollbar.direction:= avalue; + inherited; +end; + +procedure tcustomslider.clientrectchanged; +begin + inherited; + fscrollbar.dim:= innerclientrect; +end; + +procedure tcustomslider.clientmouseevent(var info: mouseeventinfoty); +begin + if not (es_processed in info.eventstate) and + not (csdesigning in componentstate) and + not (oe_readonly in getoptionsedit) then begin + fscrollbar.mouseevent(info); + end; + inherited; +end; + +procedure tcustomslider.domousewheelevent(var info: mousewheeleventinfoty); +begin + scrollbar.mousewheelevent(info); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +procedure tcustomslider.dokeydown(var info: keyeventinfoty); +begin + if not (es_processed in info.eventstate) and + not (csdesigning in componentstate) and + not (oe_readonly in getoptionsedit) then begin + fscrollbar.keydown(info); + end; + inherited; +end; + +procedure tcustomslider.scrollevent(sender: tcustomscrollbar; + event: scrolleventty); +var + rea1: realty; +begin + case event of + sbe_setvalue{valuechanged}: begin + if fupdating = 0 then begin + inc(fupdating); + rea1:= sender.value; + if not docheckvalue(rea1,false) then begin + sender.value:= value; + end + else begin + sender.value:= rea1; + end; + dec(fupdating); + end; + end; + end; +end; + +procedure tcustomslider.doenter; +begin + fscrollbar.enter; + inherited; +end; + +procedure tcustomslider.doexit; +begin + fscrollbar.exit; + inherited; +end; + +procedure tcustomslider.activechanged; +begin + fscrollbar.activechanged(); + inherited; +end; + +procedure tcustomslider.enabledchanged; +begin + fscrollbar.disabled:= not enabled; +end; + +procedure tcustomslider.setscrollbar(const avalue: tsliderscrollbar); +begin + fscrollbar.assign(avalue); +end; + +procedure tcustomslider.beginpaint(); +begin + inc(fupdating); + inc(fnoinvalidate); +end; + +procedure tcustomslider.endpaint(); +begin + dec(fupdating); + dec(fnoinvalidate); +end; + +procedure tcustomslider.dochange; +begin + inc(fupdating); + fscrollbar.value:= fvalue; + dec(fupdating); + inherited; +end; + +procedure tcustomslider.objectchanged(const sender: tobject); +begin + inherited; + fscrollbar.checktemplate(sender); +end; + +procedure tcustomslider.initgridwidget; +begin + inherited; + fscrollbar.options:= fscrollbar.options + + [sbo_noarrowkeys,sbo_nopagekeys,sbo_noreflectedclick]; +// color:= cl_parent; + if fgridintf <> nil then begin + with fgridintf.getcol do begin + if self.color = cl_default then begin + color:= cl_parent; + end + else begin + color:= self.color; + end; + options:= options - [co_drawfocus]; + end; + end; +end; + +class function tcustomslider.classskininfo: skininfoty; +begin + result:= inherited classskininfo; + result.objectkind:= sok_slider; +end; + +{ tgraphdataedit } + +constructor tgraphdataedit.create(aowner: tcomponent); +begin + foptionsedit:= defaultoptionsedit; + foptionsedit1:= defaultoptionsedit1; + inherited; + fcolorglyph:= cl_default; +end; + +procedure tgraphdataedit.internalcreateframe; +begin + tgrapheditframe.create(iscrollframe(self)); +end; + +procedure tgraphdataedit.enabledchanged(); +begin + inherited; + invalidate(); +end; + +procedure tgraphdataedit.setcolorglyph(const Value: colorty); +begin + if fcolorglyph <> value then begin + fcolorglyph := Value; + invalidate; + end; +end; + +procedure tgraphdataedit.paint(const canvas: tcanvas); +begin + if (fgridintf = nil) or + not (twidgetcol1(fgridintf.getcol).checkautocolwidth) then begin + inherited; + end; +end; + +procedure tgraphdataedit.dopaintforeground(const canvas: tcanvas); +var + col1: colorty; +begin + inherited; + col1:= fcolorglyph; + if col1 = cl_font then begin + if (fgridintf <> nil) and (ffont = nil) then begin + with fgridintf.getcol do begin + col1:= rowfont(grid.row).color; + end; + end + else begin + col1:= getfont1.color; + end; + end; + if (innerclientrect.cx > 0) and (innerclientrect.cy > 0) then begin + paintglyph(canvas,col1,nil^,innerclientrect); + end; + if (fgridintf <> nil) and not (csdesigning in componentstate) then begin + fgridintf.widgetpainted(canvas); + end; +end; + +function tgraphdataedit.needsfocuspaint: boolean; +begin + result:= (fgridintf = nil) and inherited needsfocuspaint; +end; + +procedure tgraphdataedit.dofontheightdelta(var delta: integer); +begin + inherited; + gridwidgetfontheightdelta(self,fgridintf,delta); +end; + +procedure tgraphdataedit.sizechanged; +begin + inherited; + gridwidgetsized(self,fgridintf); +end; + +procedure tgraphdataedit.dochange; +begin + if not (ws_loadedproc in fwidgetstate) then begin + if assistiveserver <> nil then begin + assistiveserver.dochange(getiassistiveclient()); + end; + if canevent(tmethod(fonchange)) then begin + fonchange(self); + end; +{$ifdef mse_with_ifi} + if fifiserverintf <> nil then begin + iifidataserver(fifiserverintf).valuechanged(iifidatalink(self)); + end; +{$endif} + end; + invalidate; +end; + +procedure tgraphdataedit.setgridintf(const intf: iwidgetgrid); +begin + fgridintf:= intf; + if fgridintf <> nil then begin + fdatalist:= fgridintf.getcol.datalist; + if fdatalist <> nil then begin + updatedatalist; + end; + fgriddatalink:= tcustomwidgetgrid1(fgridintf.getgrid).getgriddatalink; + end + else begin + fdatalist:= nil; + fgriddatalink:= nil; + end; + {$ifdef mse_with_ifi} +{ + if fgridintf <> nil then begin + if (fifilink <> nil) and (fifilink.controller.datalist <> nil) then begin + updateifigriddata(fifilink.controller.datalist); + end; + end; +} +{$endif} + +end; + +function tgraphdataedit.getcellframe: framety; +begin + if fframe <> nil then begin + result:= fframe.cellframe; + end + else begin + result:= nullframe; + end; +end; + +function tgraphdataedit.needscellfocuspaint(): boolean; +begin + result:= inherited needsfocuspaint(); +end; + +procedure tgraphdataedit.drawcell(const canvas: tcanvas); +var + col1: colorty; + rect1: rectty; +begin + with cellinfoty(canvas.drawinfopo^) do begin + if datapo <> nil then begin + col1:= fcolorglyph; + if col1 = cl_font then begin + col1:= font.color; + end; + if (fgridintf = nil) and (fparentintf <> nil) and + (oe1_nocellpaint in optionsedit1) then begin + if (fwidgetrect.cx > 0) and (fwidgetrect.cy > 0) then begin + paintbackground(canvas,widgetrect); + rect1:= self.innerparentrect; + if (rect1.cx > 0) and (rect1.cy > 0) then begin + paintglyph(canvas,col1,datapo^,rect1); + end; + paintoverlay(canvas,widgetrect); + end; + end + else begin + if (innerrect.cx > 0) and (innerrect.cy > 0) then begin + paintglyph(canvas,col1,datapo^,innerrect); + end; + end; + end; + end; +end; + +procedure tgraphdataedit.updateautocellsize(const canvas: tcanvas); +begin + //dummy; +end; + +procedure tgraphdataedit.initgridwidget; +begin + defaultinitgridwidget(self,fgridintf); + if fgridintf <> nil then begin + fgridintf.getcol.options:= fgridintf.getcol.options + [co_drawfocus]; + end; +end; + +function tgraphdataedit.docheckvalue(var avalue; const quiet: boolean): boolean; +begin + if fgridintf <> nil then begin + fgridintf.edited(); + end; + result:= true; + internalcheckvalue(avalue,result); + if result then begin + fedited:= false; + if fparentintf <> nil then begin + fparentintf.childdataentered(igridwidget(self)); + end; + if canevent(tmethod(fondataentered)) then begin + fondataentered(self); + end; + {$ifdef mse_with_ifi} + if fifiserverintf <> nil then begin + fifiserverintf.dataentered(iifidatalink(self),gridrow); + end; + {$endif} + if (oe1_sendchangeeventbycheckvalue in optionsedit1) then begin + sendchangeevent(); + end; + if canassistive() and not quiet then begin + assistiveserver.dodataentered(iassistiveclientdata(getiassistiveclient())); + end; + end; +end; + +procedure tgraphdataedit.dofocus; +begin + if fparentintf <> nil then begin + fparentintf.childfocused(igridwidget(self)); + end; + inherited; +end; + +{ +function tgraphdataedit.edited: boolean; +begin + result:= fedited; +end; +} +procedure tgraphdataedit.initeditfocus; +begin + //dummy +end; + +procedure tgraphdataedit.initnewwidget(const ascale: real); +begin + if fgridintf <> nil then begin + fgridintf.getcol.options:= + fgridintf.getcol.grid.datacols.options + [co_drawfocus]; + //restore default options + end; + inherited; +end; + +function tgraphdataedit.actualcolor: colorty; +begin + if (fgridintf <> nil) and (fcolor = cl_default) then begin + result:= fgridintf.getcol.rowcolor(fgridintf.getrow); + end + else begin + result:= inherited actualcolor; + end; +end; + +procedure tgraphdataedit.initnewcomponent(const ascale: real); +begin + inherited; + internalcreateframe; + fframe.scale(ascale); +end; + +function tgraphdataedit.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +procedure tgraphdataedit.dostatread(const reader: tstatreader); +begin + fvalueread:= false; + if not (des_isdb in fstate) and (fgridintf = nil) and + canstatvalue(foptionsedit1,reader) then begin + fvalueread:= true; + readstatvalue(reader); + end; + if canstatstate(foptionsedit1,reader) then begin + readstatstate(reader); + end; + if canstatoptions(foptionsedit1,reader) then begin + readstatoptions(reader); + end; +end; + +procedure tgraphdataedit.dostatwrite(const writer: tstatwriter); +begin + if not (des_isdb in fstate) and (fgridintf = nil) and + canstatvalue(foptionsedit1,writer) then begin + writestatvalue(writer); + end; + if canstatstate(foptionsedit1,writer) then begin + writestatstate(writer); + end; + if canstatoptions(foptionsedit1,writer) then begin + writestatoptions(writer); + end; +end; + +procedure tgraphdataedit.setstatfile(const Value: tstatfile); +begin + setstatfilevar(istatfile(self),value,fstatfile); +end; + +procedure tgraphdataedit.statreading; +begin + //dummy +end; + +procedure tgraphdataedit.statread; +begin + if (oe1_checkvalueafterstatread in foptionsedit1) and fvalueread then begin + checkvalue(true); + end; +end; + +procedure tgraphdataedit.setfirstclick(var ainfo: mouseeventinfoty); +begin + //dummy +end; + +function tgraphdataedit.getdefaultvalue: pointer; +begin + result:= nil; +end; + +function tgraphdataedit.getrowdatapo(const arow: integer): pointer; +begin + result:= nil; +end; + +function tgraphdataedit.getgridintf: iwidgetgrid; +begin + result:= fgridintf; +end; + +procedure tgraphdataedit.checkgrid; +begin + if fgridintf = nil then begin + raise exception.Create('No grid.'); + end; +end; + +function tgraphdataedit.checkgriddata: tdatalist; +begin + if fgridintf = nil then begin + raise exception.Create('No grid.'); + end; + result:= fdatalist; + if result = nil then begin + raise exception.Create('No datalist.'); + end; +end; + +function tgraphdataedit.seteditfocus: boolean; +begin + if not readonly then begin + if fgridintf = nil then begin + if canfocus then begin + setfocus; + end; + end + else begin + with fgridintf.getcol do begin + grid.col:= index; + if grid.canfocus then begin + if not focused then begin + grid.setfocus; + end; + end; + end; + end; + end; + result:= focused; +end; + +function tgraphdataedit.griddata: tdatalist; +begin + checkgrid; + result:= fdatalist; +end; + +function tgraphdataedit.widgetcol: twidgetcol; +begin + if fgridintf = nil then begin + result:= nil; + end + else begin + result:= fgridintf.getcol; + end; +end; + +function tgraphdataedit.grid: tcustomwidgetgrid; +begin + if fgridintf = nil then begin + result:= nil; + end + else begin + result:= fgridintf.getgrid; + end; +end; + +function tgraphdataedit.gridrow: integer; +begin + if fgridintf = nil then begin + result:= -1; + end + else begin + result:= fgridintf.getcol.grid.row; + end; +end; + +function tgraphdataedit.gridrowhigh: int32; +begin + if fgridintf = nil then begin + result:= -1; + end + else begin + result:= fgridintf.getcol.grid.rowhigh; + end; +end; + +function tgraphdataedit.griddatarowhigh: int32; +begin + if fgridintf = nil then begin + result:= -1; + end + else begin + result:= fgridintf.getcol.grid.datarowhigh; + end; +end; + +function tgraphdataedit.gridcol: integer; +begin + if fgridintf = nil then begin + result:= -1; + end + else begin + result:= fgridintf.getcol.index; + end; +end; + +procedure tgraphdataedit.gridtovalue(row: integer); +begin + invalidate; + //dochange; +end; + +function tgraphdataedit.getnulltext: msestring; +begin + result:= ''; +end; + +function tgraphdataedit.getassistivecelltext(const arow: int32): msestring; +begin + result:= ''; +end; + +procedure tgraphdataedit.readstatoptions(const reader: tstatreader); +begin + //dummy +end; + +procedure tgraphdataedit.readstatstate(const reader: tstatreader); +begin + //dummy +end; + +procedure tgraphdataedit.readstatvalue(const reader: tstatreader); +begin + //dummy +end; + +procedure tgraphdataedit.writestatoptions(const writer: tstatwriter); +begin + //dummy +end; + +procedure tgraphdataedit.writestatstate(const writer: tstatwriter); +begin + //dummy +end; + +procedure tgraphdataedit.writestatvalue(const writer: tstatwriter); +begin + //dummy +end; + +function tgraphdataedit.geteditstate: dataeditstatesty; +begin + result:= fstate; +end; + +procedure tgraphdataedit.seteditstate(const avalue: dataeditstatesty); +begin + fstate:= avalue; +end; +{ +procedure tgraphdataedit.setisdb; +begin + fisdb:= true; +end; +} +function tgraphdataedit.getoptionsedit: optionseditty; +begin + result:= foptionsedit; +{$ifdef mse_with_ifi} + if fifiserverintf <> nil then begin + fifiserverintf.updateoptionsedit(result); + end; +{$endif} +end; + +procedure tgraphdataedit.updateoptions; +begin + //dummy +end; + +procedure tgraphdataedit.setoptionsedit(const avalue: optionseditty); +begin + if foptionsedit <> avalue then begin + transferoptionsedit(self,avalue,foptionsedit,foptionsedit1); + //move deprecated flags + if fgridintf <> nil then begin + fgridintf.updateeditoptions(foptionsedit,foptionsedit1); + end; + updateoptions; + end; +end; + +procedure tgraphdataedit.setoptionsedit1(const avalue: optionsedit1ty); +begin + if foptionsedit1 <> avalue then begin + foptionsedit1:= avalue; + if fgridintf <> nil then begin + fgridintf.updateeditoptions(foptionsedit,foptionsedit1); + end; + updateoptions; + end; +end; + +function tgraphdataedit.sortfunc(const l, r): integer; +begin + result:= tdatalist1(twidgetcol1(fgridintf.getcol).fdata).compare(l,r); +end; + +procedure tgraphdataedit.internalgetgridvalue(index: integer; + out value); +begin + checkgrid; + fgridintf.getdata(index,value); +end; + +procedure tgraphdataedit.internalsetgridvalue(index: integer; + const avalue); +begin + checkgrid; + fgridintf.setdata(index,avalue); +end; + +procedure tgraphdataedit.docellevent(const ownedcol: boolean; var info: celleventinfoty); +begin + //dummy +end; + +procedure tgraphdataedit.valuechanged(); +begin + if not (csloading in componentstate) then begin + if (fgridintf <> nil) and not (csdesigning in componentstate) then begin + valuetogrid(fgridintf.getrow); + end; + if not (ws_loadedproc in fwidgetstate) then begin + modified; + end; + dochange; + end; +end; + +procedure tgraphdataedit.formatchanged(); +begin + if not (csloading in componentstate) then begin + if fgridintf <> nil then begin + fgridintf.changed; + end; + invalidate(); + checkautosize(); + end; +end; + +procedure tgraphdataedit.loaded(); +begin + inherited; + include(fwidgetstate,ws_loadedproc); + try + valuechanged; + formatchanged; + finally + exclude(fwidgetstate,ws_loadedproc); + end; +end; + +procedure tgraphdataedit.gridvaluechanged(const index: integer); +begin + //dummy +end; + +procedure tgraphdataedit.updatecoloptions(const aoptions: coloptionsty); +var + opt1: optionseditty; + opt2: optionsedit1ty; +begin + opt1:= foptionsedit; + opt2:= foptionsedit1; + fgridintf.coloptionstoeditoptions(opt1,opt2); + optionsedit:= opt1; + optionsedit1:= opt2; +end; + +procedure tgraphdataedit.updatecoloptions1(const aoptions: coloptions1ty); +begin + //dummy +end; + +procedure tgraphdataedit.statdataread; +begin + //dummy +end; + +procedure tgraphdataedit.griddatasourcechanged; +begin + //dummy +end; + +procedure tgraphdataedit.updatereadonlystate; +begin + //dummy +end; + +procedure tgraphdataedit.internalfillcol(const value); +begin + with tdatalist1(checkgriddata) do begin + internalfill(count,value); + end; +end; + +procedure tgraphdataedit.internalassigncol(const value); +begin + checkgrid; + with fgridintf.getcol do begin + datalist.Assign(tdatalist(value)); + end; +end; + +procedure tgraphdataedit.setenabled(const avalue: boolean); +begin + inherited; + if (fgridintf <> nil) and not (csloading in componentstate){ and + not (des_noenablesync in fstate)} then begin + fgridintf.getcol.enabled:= avalue; + end; +end; + +function tgraphdataedit.getreadonly: boolean; +begin + result:= oe_readonly in foptionsedit; +end; + +procedure tgraphdataedit.setreadonly(const avalue: boolean); +begin + if avalue then begin + optionsedit:= optionsedit + [oe_readonly]; + end + else begin + optionsedit:= optionsedit - [oe_readonly]; + end; +end; + +procedure tgraphdataedit.beforecelldragevent(var ainfo: draginfoty; + const arow: integer; var handled: boolean); +begin + //dummy +end; + +procedure tgraphdataedit.aftercelldragevent(var ainfo: draginfoty; + const arow: integer; var handled: boolean); +begin + //dummy +end; + +procedure tgraphdataedit.fontchanged; +begin + inherited; + if fcolorglyph = cl_font then begin + invalidate; + end; +end; + +procedure tgraphdataedit.modified; +begin + //dummy +end; + +function tgraphdataedit.getcellcursor(const arow: integer; + const acellzone: cellzonety; const apos: pointty): cursorshapety; +begin + result:= actualcursor(nullpoint); +end; + +procedure tgraphdataedit.updatecellzone(const arow: integer; + const apos: pointty; var result: cellzonety); +begin + //dummy +end; + +procedure tgraphdataedit.datalistdestroyed; +begin + fdatalist:= nil; +end; + +{$ifdef mse_with_ifi} +function tgraphdataedit.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iifidatalink); +end; + +function tgraphdataedit.getifilink: tifilinkcomp; +begin + result:= fifilink; +end; + +function tgraphdataedit.getifidatatype(): listdatatypety; +begin + result:= getdatalistclass().datatype(); +end; + +procedure tgraphdataedit.setifilink(const avalue: tifilinkcomp); +begin + mseificomp.setifilinkcomp(iifidatalink(self),avalue,tifilinkcomp(fifilink)); +end; + +procedure tgraphdataedit.ifisetvalue(var avalue; var accept: boolean); +begin + if accept and (fifiserverintf <> nil) then begin + iifidataserver(fifiserverintf).setvalue( + iifidatalink(self),avalue,accept,gridrow); + end; +end; + +procedure tgraphdataedit.getifivalue(var avalue); +begin + //dummy +end; + +procedure tgraphdataedit.setifivalue(const avalue); +begin + //dummy +end; +{ +function tgraphdataedit.ifigriddata: tdatalist; +begin + result:= nil; + if fgridintf <> nil then begin + result:= fdatalist; + end; +end; +} +procedure tgraphdataedit.updateifigriddata(const sender: tobject; + const alist: tdatalist); +begin + if fgridintf <> nil then begin + fgridintf.updateifigriddata(alist); + end; +end; + +function tgraphdataedit.getgriddata: tdatalist; +begin + result:= nil; + if fgridintf <> nil then begin + result:= fdatalist; + end; +end; + +function tgraphdataedit.getvalueprop: ppropinfo; +begin + result:= getpropinfo(self,'value'); +end; + +function tgraphdataedit.getiassistiveclient(): iassistiveclient; +begin + result:= iassistiveclientgridwidget(self); +end; + +function tgraphdataedit.getifidatalinkintf(): iifidatalink; +begin + result:= iifidatalink(self); +end; + +function tgraphdataedit.getassistiveflags: assistiveflagsty; +begin + result:= inherited getassistiveflags; + result:= result + [asf_graphicedit]; + if readonly then begin + include(result,asf_readonly); + end; + if fgridintf <> nil then begin + include(result,asf_gridwidget); + end; +end; + +function tgraphdataedit.getassistivecolumncaption(): msestring; +begin + result:= ''; + if fgridintf <> nil then begin + result:= fgridintf.getcol.defaultcaption(); + end; +end; + +function tgraphdataedit.getdefaultifilink: iificlient; +begin + result:= iifidatalink(self); +end; +{$endif mse_with_ifi} + +function tgraphdataedit.getedited: boolean; +begin + result:= fedited; +end; + +procedure tgraphdataedit.setedited(const avalue: boolean); +begin + fedited:= avalue; +end; + +procedure tgraphdataedit.updatedatalist; +begin + //dummy +end; + +function tgraphdataedit.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +procedure tgraphdataedit.setparentgridwidget(const intf: igridwidget); +begin + fparentintf:= intf; +end; + +procedure tgraphdataedit.childdataentered(const sender: igridwidget); +begin + //dummy +end; + +procedure tgraphdataedit.childfocused(const sender: igridwidget); +begin + //dummy +end; + +{ ttogglegraphdataedit} + +constructor ttogglegraphdataedit.create(aowner: tcomponent); +begin + fclickedrow:= -1; + foptions:= defaultbuttonoptions; + inherited; +end; + +procedure ttogglegraphdataedit.internalcreateframe; +begin + ttogglegrapheditframe.create(iscrollframe(self)); +end; + +procedure ttogglegraphdataedit.dokeydown(var info: keyeventinfoty); +begin + with info do begin + if (aso_returntogglevalue in assistiveoptions) and + (shiftstate * keyshiftstatesmask = []) and + (bo_executeonkey in foptions) and (isenterkey(self,key)) then begin + include(eventstate,es_processed); + togglevalue(oe_readonly in getoptionsedit,false); + end; + end; + inherited; +end; + +procedure ttogglegraphdataedit.dokeyup(var info: keyeventinfoty); +begin + with info do begin + if (key = key_space) and (shiftstate*keyshiftstatesmask = []) and + (bo_executeonkey in foptions) then begin + include(eventstate,es_processed); + togglevalue(oe_readonly in getoptionsedit,false); + end; + end; + inherited; +end; + +procedure ttogglegraphdataedit.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + if (bo_executeonshortcut in foptions) and checkfocusshortcut(info) then begin + include(info.eventstate,es_processed); + togglevalue(oe_readonly in getoptionsedit,false); + if (bo_focusonshortcut in foptions) and canfocus then begin + setfocus; + end; + end; + if not (es_processed in info .eventstate) then begin + inherited; + end; +end; + +procedure ttogglegraphdataedit.mouseevent(var info: mouseeventinfoty); +var + bo1: boolean; +begin + bo1:= not (csdesigning in componentstate) and + iswidgetclick(info,fcheckcaption) and (bo_executeonclick in foptions); + inherited; + if bo1 and not (des_disabled in fstate) then begin + //twidgetgrid needs childmouseevent + togglevalue(oe_readonly in getoptionsedit,false); + end; +end; + +procedure ttogglegraphdataedit.docellevent(const ownedcol: boolean; + var info: celleventinfoty); +var + clickedrowbefore: integer; +begin + inherited; + if (bo_resetcheckedonrowexit in foptions) and isrowchange(info) and + (info.newcell.row <> checkedrow) then begin + checkedrow:= -1; + end; + if ownedcol and (info.eventkind in + [cek_buttonpress,cek_buttonrelease,cek_mouseleave]) then begin + clickedrowbefore:= fclickedrow; + case info.eventkind of + cek_mouseleave: begin + fclickedrow:= -1; + end; + cek_buttonpress: begin + if (bo_executeonclick in foptions) and + (info.mouseeventinfopo^.shiftstate*keyshiftstatesmask = []) and + (info.mouseeventinfopo^.button = mb_left) and + enabled and not (des_disabled in fstate) and not readonly then begin + fclickedrow:= info.cell.row; + end; + end; + cek_buttonrelease: begin + if {not info.processed and} not focused and (fclickedrow >= 0) then begin + togglegridvalue(fclickedrow); + checkradiorow(fclickedrow); + end; + fclickedrow:= -1; + end; + end; + if fclickedrow <> clickedrowbefore then begin + fgridintf.getcol.grid.invalidatecell(info.cell); + end; + end; +end; + +procedure ttogglegraphdataedit.statechanged; +begin + if not enabled then begin + fclickedrow:= -1; + end; + inherited; +end; + +procedure ttogglegraphdataedit.setoptions(const avalue: buttonoptionsty); +begin + foptions:= avalue; +end; + +procedure ttogglegraphdataedit.resetradioitems(); +var + int1: int32; + widget1: twidget; +begin + if fparentwidget <> nil then begin + for int1:= 0 to fparentwidget.widgetcount - 1 do begin + widget1:= fparentwidget.widgets[int1]; + if (widget1 is self.classtype) and (widget1 <> self) and + (ttogglegraphdataedit(widget1).fgroup = fgroup) then begin + with ttogglegraphdataedit(widget1) do begin + inc(fresetting); + try + douncheck(); + finally + dec(fresetting); + end; + end; + end; + end; + end; +end; + +procedure ttogglegraphdataedit.checkradiorow(aindex: integer); +var + datalist1: tdatalist; + int1: integer; +begin + if (fgridintf <> nil) and (bo_radioitemcol in foptions) then begin + if aindex < 0 then begin + aindex:= fgridintf.grid.row; + end; + datalist1:= fgridintf.getcol.datalist; + int1:= datalist1.checkeditem; + if gridvaluechecked(aindex) then begin + if (int1 >= 0) and (int1 <> aindex) then begin + resetgridvalue(int1); + end; + datalist1.checkeditem:= aindex; + end + else begin + if (int1 >= 0) and (int1 = aindex) then begin + datalist1.checkeditem:= -1; + end; + end; + end; +end; + +function ttogglegraphdataedit.internalcheckeditem( + out single: boolean): ttogglegraphdataedit; //nil if none +var + widget: twidget; + int1,int2: integer; +begin + result:= nil; + int2:= 0; + if fparentwidget <> nil then begin + for int1:= 0 to fparentwidget.widgetcount - 1 do begin + widget:= fparentwidget.widgets[int1]; + if (widget is self.classtype{tcustombooleaneditradio}) then begin + with ttogglegraphdataedit(widget) do begin + if (fgroup = self.fgroup) and ischecked() then begin + inc(int2); + if result <> nil then begin + break; + end; + result:= ttogglegraphdataedit(widget); + end; + end; + end; + end; + end + else begin + if ischecked() then begin + result:= self; + end; + end; + single:= int2 <= 1; +end; + +procedure ttogglegraphdataedit.modified; +begin + checkradiorow(-1); + inherited; +end; + +function ttogglegraphdataedit.getcheckedrow: integer; +begin + result:= -1; + if (fgridintf <> nil) and (bo_radioitemcol in foptions) then begin + if fdatalist <> nil then begin + result:= fdatalist.checkeditem; + end; + end; +end; + +procedure ttogglegraphdataedit.setcheckedrow(const avalue: integer); +begin + if checkedrow <> avalue then begin + if (fgridintf <> nil) and (bo_radioitemcol in foptions) then begin + if fdatalist <> nil then begin + if avalue < 0 then begin + if fdatalist.checkeditem >= 0 then begin + resetgridvalue(fdatalist.checkeditem); + fdatalist.checkeditem:= -1; + end; + end + else begin + checkgridvalue(avalue); + checkradiorow(avalue); + end; + end; + end; + end; +end; + +function ttogglegraphdataedit.getcheckedtag: integer; +var + item: ttogglegraphdataedit; + bo1: boolean; +begin + item:= internalcheckeditem(bo1); + if item <> nil then begin + result:= item.Tag; + end + else begin + result:= -1; + end; +end; + +procedure ttogglegraphdataedit.setcheckedtag(const avalue: integer); +var + widget: twidget; + item: ttogglegraphdataedit; + int1: integer; + bo1: boolean; +begin + if fparentwidget <> nil then begin + for int1:= 0 to fparentwidget.widgetcount - 1 do begin + widget:= fparentwidget.widgets[int1]; + if (widget is self.classtype) and + (ttogglegraphdataedit(widget).fgroup = fgroup) and + (widget.tag = avalue) then begin + ttogglegraphdataedit(widget).docheck(); + exit; + end; + end; + item:= internalcheckeditem(bo1); + if item <> nil then begin + item.douncheck(); + end; + end; +end; + +function ttogglegraphdataedit.navigrect: rectty; +var + p1: captionposty; +begin + result:= widgetsizerect; + if (fframe <> nil) then begin + p1:= tcaptionframe(fframe).captionpos; + if p1 in rightcaptionpos then begin + result.x:= paintpos.x; + end; + if p1 in bottomcaptionpos then begin + result.y:= paintpos.y; + end; + end; +end; + +{ tcustombooleanedit } + +procedure tcustombooleanedit.internalcheckvalue(var avalue; var accept: boolean); +var + bo1: boolean; +begin + if canevent(tmethod(fonsetvalue)) then begin + bo1:= longbool(avalue); + fonsetvalue(self,bo1,accept); + longbool(avalue):= bo1; + end; +{$ifdef mse_with_ifi} + ifisetvalue(avalue,accept); +{$endif} + if accept then begin + value:= longbool(avalue); + end; +end; + +procedure tcustombooleanedit.togglevalue(const areadonly: boolean; + const down: boolean); +var + bo1: longbool; +begin + if not areadonly then begin + bo1:= not fvalue; + fedited:= true; + docheckvalue(bo1,false); + end; +end; + +procedure tcustombooleanedit.docheck(); +begin + value:= not valuedefault; +end; + +procedure tcustombooleanedit.douncheck(); +begin + value:= valuedefault; +end; + +function tcustombooleanedit.ischecked(): boolean; +begin + result:= fvalue; +end; + +procedure tcustombooleanedit.togglegridvalue(const index: integer); +begin + gridvalue[index]:= not gridvalue[index]; +end; + +constructor tcustombooleanedit.create(aowner: tcomponent); +begin + fcheckcaption:= true; + inherited; + size:= makesize(defaultboxsize,defaultboxsize); +end; + +function tcustombooleanedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= tgridintegerdatalist.create(sender); +end; + +function tcustombooleanedit.getdatalistclass: datalistclassty; +begin + result:= tgridintegerdatalist; +end; + +function tcustombooleanedit.getglyph: stockglyphty; +begin + result:= stg_checked; +end; + +procedure tcustombooleanedit.paintglyph(const canvas: tcanvas; + const acolorglyph: colorty; const avalue; + const arect: rectty); +var + bo1: boolean; + co1: colorty; +begin + if @avalue = nil then begin + bo1:= fvalue; + end + else begin + bo1:= boolean(avalue); + end; + co1:= acolorglyph; + if co1 = cl_default then begin + co1:= cl_glyph; + end; + if (bo_coloractive in foptions) and active then begin + canvas.fillrect(arect,cl_selectedtextbackground); + co1:= cl_selectedtext; + end; + if bo1 xor (bo_reversed in foptions) then begin + stockobjects.paintglyph(canvas,getglyph,arect,not isenabled,co1); + end; +// inherited; +end; + +procedure tcustombooleanedit.setvalue(const Value: boolean); +begin + fvalue := Value; + valuechanged; +end; + +procedure tcustombooleanedit.readstatvalue(const reader: tstatreader); +begin + value:= reader.readboolean(valuevarname,value); +end; + +procedure tcustombooleanedit.writestatvalue(const writer: tstatwriter); +begin + writer.writeboolean(valuevarname,value); +end; + +function tcustombooleanedit.getdefaultvalue: pointer; +begin + result:= @fvaluedefault; +end; + +class function tcustombooleanedit.classskininfo: skininfoty; +begin + result:= inherited classskininfo; + result.objectkind:= sok_booleanedit; +end; + +procedure tcustombooleanedit.setnullvalue; +begin + value:= false; +end; + +procedure tcustombooleanedit.gridtovalue(arow: integer); +var + int1: integer; +begin + int1:= 0; + if fvalue then begin + int1:= 1; + end; + fgridintf.getdata(arow,int1); + fvalue:= int1 <> 0; + inherited; +end; + +procedure tcustombooleanedit.valuetogrid(arow: integer); +var + int1: integer; +begin + int1:= integer(longbool(fvalue)); + fgridintf.setdata(arow,int1); +end; + +procedure tcustombooleanedit.fillcol(const avalue: longbool); +begin + checkgrid; + with tdatalist1(fgridintf.getcol.datalist) do begin + tdatalist1(fgridintf.getcol.datalist).internalfill(count,avalue); + end; + fgridintf.getcol.changed; +end; + +function tcustombooleanedit.checkvalue(const quiet: boolean = false): boolean; +begin + result:= docheckvalue(fvalue,quiet); +end; + +function tcustombooleanedit.getgridvalue(const index: integer): longbool; +begin + internalgetgridvalue(index,result); +end; + +procedure tcustombooleanedit.setgridvalue(const index: integer; + const Value: longbool); +begin + internalsetgridvalue(index,value); +end; + +function tcustombooleanedit.getgridvalues: longboolarty; +begin + result:= longboolarty(tintegerdatalist(fgridintf.getcol.datalist).asarray); +end; + +procedure tcustombooleanedit.setgridvalues(const Value: longboolarty); +begin + tintegerdatalist(fgridintf.getcol.datalist).asarray:= integerarty(value); +end; + +function tcustombooleanedit.getgridbooleanvalues: booleanarty; +begin + result:= tintegerdatalist(fgridintf.getcol.datalist).asbooleanarray; +end; + +procedure tcustombooleanedit.setgridbooleanvalues(const Value: booleanarty); +begin + tintegerdatalist(fgridintf.getcol.datalist).asbooleanarray:= value; +end; + +function tcustombooleanedit.valuetag(const falsevalue: integer): integer; +begin + if fvalue then begin + result:= tag; + end + else begin + result:= falsevalue; + end; +end; + +function tcustombooleanedit.gridvaluetag(const index: integer; + const falsevalue: integer): integer; +begin + if getgridvalue(index) then begin + result:= tag; + end + else begin + result:= falsevalue; + end; +end; + +procedure tcustombooleanedit.updatetagvalue(const bitset: integer); + //value -> true if bitset and tag <> 0 +begin + value:= bitset and tag <> 0; +end; + +procedure tcustombooleanedit.gridupdatetagvalue(const index: integer; const bitset: integer); +begin + setgridvalue(index,bitset and tag <> 0); +end; + +function tcustombooleanedit.valuetagbit: longword; + //if value -> bits[tag] else -> 0 +begin + if fvalue then begin + result:= bits[tag and $1f]; + end + else begin + result:= 0; + end; +end; + +function tcustombooleanedit.gridvaluetagbit(const index: integer): longword; + //if value -> bits[tag] else -> 0 +begin + if gridvalue[index] then begin + result:= bits[tag and $1f]; + end + else begin + result:= 0; + end; +end; + +function tcustombooleanedit.getvaluebitmask: longword; + //ored valuetagbit of all edits in group +var + ar1: booleaneditarty; + int1: integer; +begin + ar1:= groupmembers; + result:= 0; + for int1:= 0 to high(ar1) do begin + result:= result or ar1[int1].valuetagbit; + end; +end; + +procedure tcustombooleanedit.setvaluebitmask(const avalue: longword); +var + ar1: booleaneditarty; + int1: integer; +begin + ar1:= groupmembers; + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + value:= avalue and bits[tag and $1f] <> 0; + end; + end; +end; + +function tcustombooleanedit.getgridvaluebitmask(const index: integer): longword; + //ored valuetagbit of all edits in group +var + ar1: booleaneditarty; + int1: integer; +begin + ar1:= groupmembers; + result:= 0; + for int1:= 0 to high(ar1) do begin + result:= result or ar1[int1].gridvaluetagbit(index); + end; +end; + +procedure tcustombooleanedit.setgridvaluebitmask(const index: integer; const avalue: longword); +var + ar1: booleaneditarty; + int1: integer; +begin + ar1:= groupmembers; + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + gridvalue[index]:= avalue and bits[tag and $1f] <> 0; + end; + end; +end; + +function tcustombooleanedit.getvalue: boolean; +begin + result:= fvalue; +end; + +function tcustombooleanedit.getvaluedefault: boolean; +begin + result:= fvaluedefault; +end; + +procedure tcustombooleanedit.setvaluedefault(const Value: boolean); +begin + fvaluedefault:= value; +end; + +function tcustombooleanedit.groupmembers: booleaneditarty; +var + int1,int2: integer; + widget1: twidget; +begin + if fparentwidget = nil then begin + setlength(result,1); + result[0]:= self; + end + else begin + setlength(result,fparentwidget.widgetcount); //max + int2:= 0; + for int1:= 0 to high(result) do begin + widget1:= twidget1(fparentwidget).fwidgets[int1]; + if (widget1 is tcustombooleanedit) and + (tcustombooleanedit(widget1).fgroup = self.fgroup) then begin + result[int2]:= tcustombooleanedit(widget1); + inc(int2); + end; + end; + setlength(result,int2); + end; +end; + +function tcustombooleanedit.tagitem(const atag: integer): tcustombooleanedit; //nil if none +var + int1: integer; + widget1: twidget; +begin + result:= nil; + if fparentwidget <> nil then begin + for int1:= 0 to fparentwidget.widgetcount - 1 do begin + widget1:= twidget1(fparentwidget).fwidgets[int1]; + if (widget1 is tcustombooleanedit) and + (tcustombooleanedit(widget1).fgroup = self.fgroup) and + (widget1.tag = atag) then begin + result:= tbooleanedit(widget1); + break; + end; + end; + end; +end; + +procedure tcustombooleanedit.dokeydown(var info: keyeventinfoty); +begin + with info do begin + if not (es_processed in eventstate) then begin + if ((key = key_0) or (key = key_1) or (key = key_period)) and + (shiftstate = []) and (bo_executeonkey in foptions) then begin + include(eventstate,es_processed); + if ((key = key_1) xor value) or (key = key_period) then begin + togglevalue(oe_readonly in getoptionsedit,false); + end; + end; + if not (es_processed in eventstate) then begin + inherited; + end; + end; + end; +end; + +function tcustombooleanedit.getassistivetext(): msestring; +begin + if value then begin + result:= stockobjects.captions[sc_on]; + end + else begin + result:= stockobjects.captions[sc_off]; + end; +end; + +{$ifdef mse_with_ifi} +function tcustombooleanedit.getifilink: tifibooleanlinkcomp; +begin + result:= tifibooleanlinkcomp(fifilink); +end; + +procedure tcustombooleanedit.setifilink(const avalue: tifibooleanlinkcomp); +begin + inherited setifilink(avalue); +end; + +{$endif} + +procedure tcustombooleanedit.resetgridvalue(const index: integer); +begin + gridvalue[index]:= false; +end; + +procedure tcustombooleanedit.checkgridvalue(const index: integer); +begin + gridvalue[index]:= true; +end; + +function tcustombooleanedit.gridvaluechecked(const aindex: integer): boolean; +begin + result:= gridvalue[aindex]; +end; + +function tcustombooleanedit.griddata: tgridintegerdatalist; +begin + result:= tgridintegerdatalist(inherited griddata); +end; + +procedure tcustombooleanedit.setvaluedata(const source); +begin + value:= boolean(source); +end; + +procedure tcustombooleanedit.getvaluedata(out dest); +begin + boolean(dest):= value; +end; + +{ tcustombooleaneditradio } + +function tcustombooleaneditradio.getglyph: stockglyphty; +begin + result:= stg_checkedradio; +end; +{ +procedure tcustombooleaneditradio.reset; +begin + if value then begin + inc(fresetting); + try + value:= false + finally + dec(fresetting); + end; + end; +end; +} +procedure tcustombooleaneditradio.setvalue(const avalue: boolean); +begin + if avalue then begin + resetradioitems(); + end; + inherited; +end; + +procedure tcustombooleaneditradio.setgridvalue(const aindex: integer; + const avalue: longbool); +var + widget: twidget; + int1: integer; +begin + if avalue and (fparentwidget <> nil) then begin + for int1:= 0 to fparentwidget.widgetcount - 1 do begin + widget:= fparentwidget.widgets[int1]; + if (widget is tcustombooleaneditradio) and (widget <> self) and + (tcustombooleaneditradio(widget).fgroup = fgroup) then begin + tcustombooleaneditradio(widget).gridvalue[aindex]:= false; + end; + end; + end; + inherited; +end; + +function tcustombooleaneditradio.checkeditem: tcustombooleaneditradio; + //nil if none +var + bo1: boolean; +begin + result:= tcustombooleaneditradio(internalcheckeditem(bo1)); +end; + +procedure tcustombooleaneditradio.togglevalue(const areadonly: boolean; + const down: boolean); +var + bo1: boolean; + bo2: longbool; +begin + if not areadonly then begin + internalcheckeditem(bo1); + if (bo_cantoggle in foptions) or not fvalue or not bo1 then begin + bo2:= not fvalue; + docheckvalue(bo2,false); + end; + end; +end; + +procedure tcustombooleaneditradio.togglegridvalue(const index: integer); +begin + if not getgridvalue(index) then begin + setgridvalue(index,true); + end; +end; + +{ tcustomintegergraphdataedit } + +procedure tcustomintegergraphdataedit.internalcheckvalue(var avalue; + var accept: boolean); +begin + if canevent(tmethod(fonsetvalue)) then begin + fonsetvalue(self,integer(avalue),accept); + end; +{$ifdef mse_with_ifi} + ifisetvalue(avalue,accept); +{$endif} + if accept then begin + value:= integer(avalue); + end; +end; + +procedure tcustomintegergraphdataedit.setvalue(const avalue: integer); +begin + if (bo_radioitem in foptions) and (avalue <> fvaluedefault) then begin + resetradioitems(); + end; + fvalue := avalue; + valuechanged; +end; + +procedure tcustomintegergraphdataedit.readstatvalue(const reader: tstatreader); +begin + value:= reader.readinteger(valuevarname,value); +end; + +procedure tcustomintegergraphdataedit.writestatvalue(const writer: tstatwriter); +begin + writer.writeinteger(valuevarname,value); +end; + +function tcustomintegergraphdataedit.getdefaultvalue: pointer; +begin + result:= @fvaluedefault; +end; + +procedure tcustomintegergraphdataedit.gridtovalue(arow: integer); +begin + fgridintf.getdata(arow,fvalue); + inherited; +end; + +procedure tcustomintegergraphdataedit.valuetogrid(arow: integer); +begin + fgridintf.setdata(arow,fvalue); +end; + +function tcustomintegergraphdataedit.checkvalue( + const quiet: boolean = false): boolean; +begin + result:= docheckvalue(fvalue,quiet); +end; + +function tcustomintegergraphdataedit.doinc(var avalue: integer; + const down: boolean): boolean; +begin + result:= false; + if (foptions * [bo_radioitem,bo_radioitemcol] = []) or + (bo_cantoggle in foptions) or (value = fvaluedefault) then begin + if down then begin + dec(avalue); + if avalue < fvaluemin then begin + avalue:= fvaluemax; + end; + end + else begin + inc(avalue); + if avalue > fvaluemax then begin + avalue:= fvaluemin; + end; + end; + result:= true; + end; +end; + +procedure tcustomintegergraphdataedit.paintglyph(const canvas: tcanvas; + const acolorglyph: colorty; + const avalue; const arect: rectty); +var + int1,val1: integer; +begin + if canevent(tmethod(fonpaintglyph)) then begin + if @avalue = nil then begin + val1:= fvalue; + int1:= gridrow; + end + else begin + val1:= integer(avalue); + int1:= pcellinfoty(canvas.drawinfopo)^.cell.row; + end; + fonpaintglyph(self,canvas,val1,int1); + end; +// inherited; +end; + +procedure tcustomintegergraphdataedit.togglevalue(const areadonly: boolean; + const down: boolean); +var + int1: integer; +begin + if not areadonly and (fvaluemin <> fvaluemax) then begin + int1:= fvalue; + if doinc(int1,down) then begin + docheckvalue(int1,false); + end; + end; +end; + +function tcustomintegergraphdataedit.ischecked(): boolean; +begin + result:= fvalue <> fvaluedefault; +end; + +procedure tcustomintegergraphdataedit.docheck(); +begin + value:= valuedefault+1; +end; + +procedure tcustomintegergraphdataedit.douncheck(); +begin + value:= valuedefault; +end; + +procedure tcustomintegergraphdataedit.togglegridvalue(const index: integer); +var + int1: integer; +begin + if fvaluemin <> fvaluemax then begin + int1:= gridvalue[index]; + if doinc(int1,false) then begin + gridvalue[index]:= int1; + end; + end; +end; + +procedure tcustomintegergraphdataedit.fillcol(const avalue: integer); +begin + checkgrid; + tgridintegerdatalist(fdatalist).fill(fdatalist.count,avalue); +end; + +function tcustomintegergraphdataedit.createdatalist( + const sender: twidgetcol): tdatalist; +begin + fdatalist:= tgridintegerdatalist.create(sender); + tgridintegerdatalist(fdatalist).notcheckedvalue:= fvaluedefault; + result:= fdatalist; +end; + +function tcustomintegergraphdataedit.getdatalistclass: datalistclassty; +begin + result:= tgridintegerdatalist; +end; + +function tcustomintegergraphdataedit.getgridvalue(const index: integer): integer; +begin + internalgetgridvalue(index,result); +end; + +procedure tcustomintegergraphdataedit.setgridvalue(const index, Value: integer); +begin + internalsetgridvalue(index,value); +end; + +function tcustomintegergraphdataedit.getgridvalues: integerarty; +begin + checkgrid; + result:= tgridintegerdatalist(fdatalist).asarray; +end; + +procedure tcustomintegergraphdataedit.setgridvalues(const Value: integerarty); +begin + checkgrid; + tgridintegerdatalist(fdatalist).asarray:= value; +end; +{ +procedure tcustomintegergraphdataedit.setgridintf(const intf: iwidgetgrid); +begin + if intf <> nil then begin + fdatalist:= tintegerdatalist(intf.getcol.datalist); + end + else begin + fdatalist:= nil; + end; + inherited; +end; +} +procedure tcustomintegergraphdataedit.resetgridvalue(const index: integer); +begin + gridvalue[index]:= valuedefault; +end; + +procedure tcustomintegergraphdataedit.checkgridvalue(const index: integer); +var + int1: integer; +begin + int1:= fvaluedefault + 1; + if int1 > fvaluemax then begin + int1:= int1 -2; + if int1 < fvaluemin then begin + int1:= fvaluemin; + end; + end; + gridvalue[index]:= int1; +end; + +function tcustomintegergraphdataedit.gridvaluechecked( + const aindex: integer): boolean; +begin + result:= gridvalue[aindex] <> valuedefault; +end; + +procedure tcustomintegergraphdataedit.datalistdestroyed; +begin + fdatalist:= nil; +end; + +{$ifdef mse_with_ifi} +function tcustomintegergraphdataedit.getifilink: tifiintegerlinkcomp; +begin + result:= tifiintegerlinkcomp(fifilink); +end; + +procedure tcustomintegergraphdataedit.setifilink(const avalue: tifiintegerlinkcomp); +begin + inherited setifilink(avalue); +end; +{$endif} + +procedure tcustomintegergraphdataedit.setvaluemin(const avalue: integer); +begin + fvaluemin:= avalue; + if fdatalist <> nil then begin + with tgridintegerdatalist(fdatalist) do begin + min:= avalue; + end; + end; +end; + +procedure tcustomintegergraphdataedit.setvaluemax(const avalue: integer); +begin + fvaluemax:= avalue; + if fdatalist <> nil then begin + with tgridintegerdatalist(fdatalist) do begin + max:= avalue; + end; + end; +end; + +procedure tcustomintegergraphdataedit.updatedatalist; +begin + with tgridintegerdatalist(fdatalist) do begin + min:= self.valuemin; + max:= self.valuemax; + notcheckedvalue:= self.valuedefault; + end; +end; + +procedure tcustomintegergraphdataedit.readmin(reader: treader); +begin + valuemin:= reader.readinteger(); +end; + +procedure tcustomintegergraphdataedit.readmax(reader: treader); +begin + valuemax:= reader.readinteger(); +end; + +procedure tcustomintegergraphdataedit.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('min',@readmin,nil,false); + filer.defineproperty('max',@readmax,nil,false); +end; + +function tcustomintegergraphdataedit.getdatalist: tintegerdatalist; +begin + result:= tintegerdatalist(checkgriddata); +end; + +function tcustomintegergraphdataedit.griddata: tgridintegerdatalist; +begin + result:= tgridintegerdatalist(inherited griddata); +end; + +procedure tcustomintegergraphdataedit.setvaluedata(const source); +begin + value:= integer(source); +end; + +procedure tcustomintegergraphdataedit.getvaluedata(out dest); +begin + integer(dest):= value; +end; + + +{ tvaluefacearrayprop } + +constructor tvaluefacearrayprop.create(const aowner: tcustomdatabutton); +begin + fowner:= aowner; + inherited create(nil); +end; + +class function tvaluefacearrayprop.getitemclasstype: persistentclassty; +begin + result:= tface; +end; + +procedure tvaluefacearrayprop.createitem(const index: integer; + var item: tpersistent); +begin + item:= tface.create(iface(fowner)); +end; + +function tvaluefacearrayprop.getitems(const index: integer): tface; +begin + result:= tface(inherited getitems(index)); +end; + +{ tvaluefontarrayprop } + +constructor tvaluefontarrayprop.create(const aowner: tcustomdatabutton); +begin + fowner:= aowner; + inherited create(nil); +end; + +class function tvaluefontarrayprop.getitemclasstype: persistentclassty; +begin + result:= tfont; +end; + +procedure tvaluefontarrayprop.createitem(const index: integer; + var item: tpersistent); +begin + item:= tfont.create; + item.assign(fowner.font); + tfont(item).onchange:= @fontchange; +end; + +procedure tvaluefontarrayprop.fontchange(const sender: tobject); +begin + fowner.formatchanged; +end; + +procedure tvaluefontarrayprop.setitems(const index: integer; const avalue: tfont); +begin + checkindex(index); + if fitems[index] <> nil then begin + fitems[index].assign(avalue); + end; +end; + +function tvaluefontarrayprop.getitems(const index: integer): tfont; +begin + result:= tfont(inherited getitems(index)); +end; + +{ tcustomdatabutton } + +constructor tcustomdatabutton.create(aowner: tcomponent); +begin + foptions:= defaultbuttonoptions; + initactioninfo(factioninfo); + fvaluedisabled:= -2; + inherited; + fimagenums:= tintegerarrayprop.create; + fimagenr:= -1; + fimagenrdisabled:= -2; + fvalue:= -1; + fvaluedefault:= -1; + fvaluemin:= -1; + fvaluemax:= 0; + fvaluefaces:= tvaluefacearrayprop.create(self); + fvaluecaptions:= tmsestringarrayprop.create; + fvaluefonts:= tvaluefontarrayprop.create(self); + optionswidget:= defaultoptionswidget - [ow_mousefocus]; + initshapeinfo(finfo); + finfo.ca.imagepos:= ip_center; + finfo.ca.dim:= innerclientrect; + finfo.color:= cl_transparent; + finfo.ca.colorglyph:= cl_black; + finfo.state:= finfo.state + [shs_showfocusrect,shs_showdefaultrect]; + include(fwidgetstate1,ws1_nodesignframe); + size:= makesize(defaultbuttonwidth,defaultbuttonheight); +end; + +destructor tcustomdatabutton.destroy; +begin + if bo_updateonidle in foptions then begin + application.unregisteronidle({$ifdef FPC}@{$endif}doidle); + end; + fvaluefaces.free; + fvaluecaptions.free; + fvaluefonts.free; + fimagenums.free; + inherited; +end; + +procedure tcustomdatabutton.execute(); +begin + if not (shs_disabled in finfo.state) then begin + internalexecute; + end; +end; + +class function tcustomdatabutton.classskininfo: skininfoty; +begin + result:= inherited classskininfo; + result.objectkind:= sok_databutton; +end; + +function tcustomdatabutton.verticalfontheightdelta: boolean; +begin + result:= tf_rotate90 in textflags; +end; + +procedure tcustomdatabutton.synctofontheight; +begin + inherited; + if tf_rotate90 in textflags then begin + bounds_cx:= font.glyphheight + innerclientframewidth.cx + 6; + end + else begin + bounds_cy:= font.glyphheight + innerclientframewidth.cy + 6; + end; +end; + +procedure tcustomdatabutton.initnewcomponent(const ascale: real); +begin + //dummy +end; + +procedure tcustomdatabutton.clientrectchanged; +begin + inherited; + frameskinoptionstoshapestate(fframe,finfo); + if (fframe = nil) and (fgridintf <> nil) then begin + exclude(finfo.state,shs_showdefaultrect); + end; + if shs_flat in finfo.state then begin + exclude(fwidgetstate1,ws1_nodesignframe); + end + else begin + include(fwidgetstate1,ws1_nodesignframe); + end; + finfo.ca.dim:= clientrect; + if (fframe <> nil) and not(shs_noinnerrect in finfo.state) then begin + //otherwise mouse rect + deflaterect1(finfo.ca.dim,fframe.frameo); + end; + { + if shs_noinnerrect in finfo.state then begin + finfo.ca.dim:= clientrect; + end + else begin + finfo.ca.dim:= innerclientrect; + end; + } +end; +{ +function tcustomdatabutton.getframestateflags: framestateflagsty; +begin + with finfo do begin + result:= combineframestateflags(not isenabled,focused, + not (bo_nodefaultframeactive in foptions) and + (shs_default in finfo.state) or active, + shs_mouse in state,shs_clicked in state); + end; +end; +} +{ +function tcustomdatabutton.getframeclicked: boolean; +begin + result:= ss_clicked in finfo.state; +end; + +function tcustomdatabutton.getframemouse: boolean; +begin + result:= ss_mouse in finfo.state; +end; + +function tcustomdatabutton.getframeactive: boolean; +begin + result:= not (bo_nodefaultframeactive in foptions) and + (ss_default in finfo.state) or active; +end; +} +procedure tcustomdatabutton.doexecute; +begin + if (options * [bo_nocandefocus,bo_candefocuswindow] <> [bo_candefocuswindow]) or + rootwidget.canparentclose then begin + doactionexecute(self,factioninfo,false, + (options * [bo_nocandefocus,bo_candefocuswindow] <> [])); + end; +// doactionexecute(self,factioninfo); +end; + +procedure tcustomdatabutton.mouseevent(var info: mouseeventinfoty); +begin + inherited; + if not (csdesigning in componentstate) {and + not (es_processed in info.eventstate)} then begin + subpoint1(info.pos,paintpos); + try + updatemouseshapestate(finfo,info,self,fframe,nil, + bo_executeonclick in foptions); + finally + addpoint1(info.pos,paintpos); + end; + end; +end; + +procedure tcustomdatabutton.dokeydown(var info: keyeventinfoty); +begin + inherited; + if (info.shiftstate = []) and (bo_executeonkey in foptions) and + not (des_disabled in fstate) then begin + if (info.key = key_space) then begin + include(finfo.state,shs_clicked); + invalidaterect(finfo.ca.dim); + end + else begin + if isenterkey(self,info.key) then begin + include(info.eventstate,es_processed); + togglevalue(oe_readonly in getoptionsedit,false); + end; + end; + end; +end; + +procedure tcustomdatabutton.dokeyup(var info: keyeventinfoty); +begin + if (info.key = key_space) and (shs_clicked in finfo.state) then begin + exclude(finfo.state,shs_clicked); + invalidaterect(finfo.ca.dim); + end; + inherited; +end; + +procedure tcustomdatabutton.doshortcut(var info: keyeventinfoty; const sender: twidget); +var + bo1,bo2: boolean; +begin + if not (es_processed in info.eventstate) and + not (csdesigning in componentstate) and + not (shs_disabled in finfo.state) then begin + if checkfocusshortcut(info) then begin + setfocus; + end; + bo1:= checkactionshortcut(factioninfo,info); + if not bo1 then begin + if not (es_preview in info.eventstate) then begin + bo2:= es_processed in info.eventstate; + exclude(info.eventstate,es_processed); + bo1:= (bo_executeonshortcut in options) and + msegui.checkshortcut(info,factioninfo.captiontext, + bo_altshortcut in options) or + (finfo.state * [shs_invisible,shs_disabled,shs_default] = [shs_default]) and + (info.key = key_return) and + ((info.shiftstate = []) or + (bo_executedefaultonenterkey in options) and + (info.shiftstate = [ss_second])); + if bo1 then begin + bo2:= true; + togglevalue(oe_readonly in getoptionsedit,false); + // internalexecute; + end; + if bo2 then begin + include(info.eventstate,es_processed); + end; + end; + end + else begin + togglevalue(oe_readonly in getoptionsedit,false); + end; + if not (es_processed in info.eventstate) then begin + inherited; + end; + end; +end; + +procedure tcustomdatabutton.statechanged; +begin + inherited; + updatewidgetshapestate(finfo,self); + if (fgridintf <> nil) and (fvaluedisabled <> -2) then begin + checkdisabled(); + end; +end; + +procedure tcustomdatabutton.setcolorglyph(const avalue: colorty); +begin + setactioncolorglyph(iactionlink(self),avalue); +end; + +function tcustomdatabutton.iscolorglyphstored: boolean; +begin + result:= isactioncolorglyphstored(factioninfo); +end; + +procedure tcustomdatabutton.setactualimagenr(const avalue: integer); +begin + with finfo,ca do begin + if (avalue >= 0) and (avalue < fimagenums.count) then begin + imagenr:= fimagenums[avalue]; + end + else begin + imagenr:= fimagenr; + end; + if shs_disabled in finfo.state then begin + if fimagenrdisabled = -3 then begin + if imagenr >= 0 then begin + imagenrdisabled:= imagenr + fimageoffsetdisabled; + end; + end + else begin + imagenrdisabled:= fimagenrdisabled; + end; + end + else begin + if shs_clicked in state then begin + inc(imagenr,fimageoffsetclicked); + end + else begin + if shs_mouse in state then begin + inc(imagenr,fimageoffsetmouse); + end + end; + if imagenr >= 0 then begin + inc(imagenr,fimageoffset); + end; + end; + end; +end; + +procedure tcustomdatabutton.paintglyph(const canvas: tcanvas; + const acolorglyph: colorty; const avalue; + const arect: rectty); + + function actualcaption(const aindex: integer): richstringty; + begin + if (aindex >= 0) and (aindex < fvaluecaptions.count) then begin + result.text:= fvaluecaptions[aindex]; + result.format:= nil; + end + else begin + result:= factioninfo.caption1; + end; + end; + + function actualface(const aindex: integer): tface; + begin + if (aindex >= 0) and (aindex < fvaluefaces.count) then begin + result:= fvaluefaces[aindex]; + end + else begin + result:= nil; + end; + end; + + function actualfont(const aindex: integer): tfont; + begin + if (aindex >= 0) and (aindex < fvaluefonts.count) then begin + result:= fvaluefonts[aindex]; + end + else begin + result:= font; + end; + end; + +var + statebefore: shapestatesty; + dimbefore: rectty; +begin + finfo.ca.colorglyph:= acolorglyph; + finfo.imagenrdisabled:= fimagenrdisabled; + if (@avalue <> nil) then begin + finfo.ca.caption:= actualcaption(integer(avalue)); + finfo.face:= actualface(integer(avalue)); + finfo.ca.font:= actualfont(int32(avalue)); + statebefore:= finfo.state; + dimbefore:= finfo.ca.dim; + finfo.ca.dim:= arect; + finfo.state:= finfo.state - [shs_focused,shs_clicked,shs_mouse]; + if not valueenabledstate(integer(avalue)) then begin + include(finfo.state,shs_disabled); + end + else begin + exclude(finfo.state,shs_disabled); + end; + with pcellinfoty(canvas.drawinfopo)^ do begin + if (cds_ismousecell in drawstate) and (bo_executeonclick in foptions) and + not(shs_disabled in finfo.state) and not readonly then begin + include(finfo.state,shs_mouse); + end; + if cell.row = fclickedrow then begin + include(finfo.state,shs_clicked); + end; + end; + setactualimagenr(integer(avalue)); + drawbutton(canvas,finfo); + finfo.state:= statebefore; + finfo.ca.dim:= dimbefore; + end + else begin + finfo.ca.caption:= actualcaption(fvalue); + finfo.face:= actualface(fvalue); + finfo.ca.font:= actualfont(fvalue); + setactualimagenr(fvalue); + drawbutton(canvas,finfo); + end; + inherited; +end; + +procedure tcustomdatabutton.internalcreateframe; +begin + tcaptionframe.create(iscrollframe(self)); +end; + +procedure tcustomdatabutton.initgridwidget; +begin + inherited; + if fgridintf <> nil then begin + with fgridintf.getcol do begin + if self.color = cl_default then begin + color:= cl_parent; + end + else begin + color:= self.color; + end; + options:= options - [co_drawfocus]; + end; + end; +end; + +procedure tcustomdatabutton.setvaluefaces(const avalue: tvaluefacearrayprop); +begin + fvaluefaces.assign(avalue); +end; + +procedure tcustomdatabutton.setvaluecaptions(const avalue: tmsestringarrayprop); +begin + fvaluecaptions.assign(avalue); +end; + +procedure tcustomdatabutton.setcaption(const avalue: captionty); +begin + setactioncaption(iactionlink(self),avalue); +// formatchanged; +end; + +procedure tcustomdatabutton.settextflags(const avalue: textflagsty); +begin + if finfo.ca.textflags <> avalue then begin + finfo.ca.textflags:= checktextflags(finfo.ca.textflags,avalue); + invalidate; + checkautosize(); + end; +end; + +function tcustomdatabutton.iscaptionstored: boolean; +begin + result:= isactioncaptionstored(factioninfo); +end; + +procedure tcustomdatabutton.setcaptiondist(const avalue: integer); +begin + if avalue <> finfo.ca.captiondist then begin + finfo.ca.captiondist:= avalue; + formatchanged(); +// checkautosize(); + end; +end; + +procedure tcustomdatabutton.setimagepos(const avalue: imageposty); +begin + if avalue <> finfo.ca.imagepos then begin + finfo.ca.imagepos:= avalue; + formatchanged; +// checkautosize; + end; +end; + +function tcustomdatabutton.getimagelist: timagelist; +begin + result:= timagelist(factioninfo.imagelist); +end; + +procedure tcustomdatabutton.setimagelist(const avalue: timagelist); +begin + setactionimagelist(iactionlink(self),avalue); +end; + +function tcustomdatabutton.isimageliststored: Boolean; +begin + result:= isactionimageliststored(factioninfo); +end; + +procedure tcustomdatabutton.setimagenr(const avalue: imagenrty); +begin + fimagenr:= avalue; + setactionimagenr(iactionlink(self),avalue); +end; + +function tcustomdatabutton.isimagenrstored: Boolean; +begin + result:= isactionimagenrstored(factioninfo); +end; + +procedure tcustomdatabutton.setimagenrdisabled(const avalue: imagenrty); +begin + fimagenrdisabled:= avalue; + setactionimagenrdisabled(iactionlink(self),avalue); +end; + +function tcustomdatabutton.isimagenrdisabledstored: Boolean; +begin + result:= isactionimagenrdisabledstored(factioninfo); +end; + +procedure tcustomdatabutton.setnullvalue; +begin + value:= -1; +end; + +procedure tcustomdatabutton.setgridintf(const intf: iwidgetgrid); +begin + inherited; + exclude(finfo.state,shs_showdefaultrect); +end; + +function tcustomdatabutton.checkfocusshortcut(var info: keyeventinfoty): boolean; +begin + result:= inherited checkfocusshortcut(info) or + msegui.checkshortcut(info,factioninfo.captiontext,true); +end; + +procedure tcustomdatabutton.togglevalue(const areadonly: boolean; + const down: boolean); +begin + if not (des_disabled in fstate) then begin + inherited; + internalexecute; + end; +end; + +procedure tcustomdatabutton.togglegridvalue(const index: integer); +begin + inherited; + internalexecute; +end; + +function tcustomdatabutton.checkeditem: tcustomdatabutton; +var + bo1: boolean; +begin + result:= tcustomdatabutton(internalcheckeditem(bo1)); +end; + +procedure tcustomdatabutton.setimageoffset(const avalue: integer); +begin + if fimageoffset <> avalue then begin + fimageoffset := aValue; + formatchanged; + end; +end; + +procedure tcustomdatabutton.setimageoffsetdisabled(const avalue: integer); +begin + if fimageoffsetdisabled <> avalue then begin + fimageoffsetdisabled := avalue; + formatchanged; + end; +end; + +procedure tcustomdatabutton.setimageoffsetmouse(const avalue: integer); +begin + if fimageoffsetmouse <> avalue then begin + fimageoffsetmouse := avalue; + formatchanged; + end; +end; + +procedure tcustomdatabutton.setimageoffsetclicked(const avalue: integer); +begin + if fimageoffsetclicked <> avalue then begin + fimageoffsetclicked := avalue; + formatchanged; + end; +end; + +procedure tcustomdatabutton.setshortcut(const avalue: shortcutty); +begin + setactionshortcut(iactionlink(self),avalue); +end; + +function tcustomdatabutton.isshortcutstored: boolean; +begin + result:= isactionshortcutstored(factioninfo); +end; + +function tcustomdatabutton.getshortcut: shortcutty; +begin + result:= getsimpleshortcut(factioninfo); +end; + +function tcustomdatabutton.getshortcut1: shortcutty; +begin + result:= getsimpleshortcut1(factioninfo); +end; + +procedure tcustomdatabutton.setshortcut1(const avalue: shortcutty); +begin + setactionshortcut1(iactionlink(self),avalue); +end; + +function tcustomdatabutton.isshortcut1stored: boolean; +begin + result:= isactionshortcut1stored(factioninfo); +end; + +procedure tcustomdatabutton.setonexecute(const avalue: notifyeventty); +begin + setactiononexecute(iactionlink(self),avalue,csloading in componentstate); +end; + +function tcustomdatabutton.isonexecutestored: boolean; +begin + result:= isactiononexecutestored(factioninfo); +end; + +procedure tcustomdatabutton.setonbeforeexecute(const avalue: accepteventty); +begin + setactiononbeforeexecute(iactionlink(self),avalue,csloading in componentstate); +end; + +function tcustomdatabutton.isonbeforeexecutestored: boolean; +begin + result:= isactiononbeforeexecutestored(factioninfo); +end; + +procedure tcustomdatabutton.setonafterexecute(const avalue: notifyeventty); +begin + setactiononafterexecute(iactionlink(self),avalue,csloading in componentstate); +end; + +function tcustomdatabutton.isonafterexecutestored: boolean; +begin + result:= isactiononafterexecutestored(factioninfo); +end; + +procedure tcustomdatabutton.setimagedist(const avalue: integer); +begin + if avalue <> finfo.ca.imagedist then begin + finfo.ca.imagedist:= avalue; + formatchanged; +// checkautosize; + end; +end; + +procedure tcustomdatabutton.setimagedist1(const avalue: integer); +begin + if avalue <> finfo.ca.imagedist1 then begin + finfo.ca.imagedist1:= avalue; + formatchanged; +// checkautosize; + end; +end; + +procedure tcustomdatabutton.setimagedist2(const avalue: integer); +begin + if avalue <> finfo.ca.imagedist2 then begin + finfo.ca.imagedist2:= avalue; + formatchanged; +// checkautosize; + end; +end; + +procedure tcustomdatabutton.setimagenums(const avalue: tintegerarrayprop); +begin + fimagenums.assign(avalue); +end; + +procedure tcustomdatabutton.setoptions(const avalue: buttonoptionsty); +var + delta: buttonoptionsty; +begin + if avalue <> foptions then begin + delta:= buttonoptionsty( + {$ifdef FPC}longword{$else}longword{$endif}(foptions) xor + {$ifdef FPC}longword{$else}longword{$endif}(avalue)); + if bo_updateonidle in delta then begin + if (bo_updateonidle in avalue) and + not (csdesigning in componentstate) then begin + application.registeronidle({$ifdef FPC}@{$endif}doidle); + end + else begin + application.unregisteronidle({$ifdef FPC}@{$endif}doidle); + end; + end; + foptions:= avalue; + buttonoptionstoshapestate(foptions,finfo.state); + invalidate; + if bo_shortcutcaption in avalue then begin + setactionoptions(iactionlink(self),factioninfo.options + [mao_shortcutcaption]); + end + else begin + setactionoptions(iactionlink(self),factioninfo.options - [mao_shortcutcaption]); + end; + end; +end; +{ +begin + if foptions <> avalue then begin + foptions:= avalue - [bo_shortcutcaption]; + buttonoptionstoshapestate(foptions,finfo.state); + invalidate; + end; +end; +} +function tcustomdatabutton.getactioninfopo: pactioninfoty; +begin + result:= @factioninfo; +end; + +function tcustomdatabutton.shortcutseparator: msechar; +begin + result:= ' '; +end; + +procedure tcustomdatabutton.calccaptiontext(var ainfo: actioninfoty); +begin + mseactions.calccaptiontext(ainfo,shortcutseparator); +end; + +procedure tcustomdatabutton.updatehotkeys(); +begin + inherited; + calccaptiontext(factioninfo); +end; + +procedure tcustomdatabutton.actionchanged; +begin + finfo.color:= fcolor; + actioninfotoshapeinfo(self,factioninfo,finfo,foptions); + inherited setcolor(finfo.color); + finfo.color:= cl_transparent; +// if csdesigning in componentstate then begin + exclude(finfo.state,shs_invisible); +// end; + formatchanged(); +// checkautosize; +end; + +procedure tcustomdatabutton.setaction(const avalue: tcustomaction); +begin + linktoaction(iactionlink(self),avalue,factioninfo); +end; + +procedure tcustomdatabutton.setstate(const avalue: actionstatesty); +begin + setactionstate(iactionlink(self),avalue); + visible:= not (as_invisible in factioninfo.state); + enabled:= not (as_disabled in factioninfo.state); +end; + +procedure tcustomdatabutton.setenabled(const avalue: boolean); +begin + if avalue then begin + setactionstate(iactionlink(self),state - [as_disabled]); + end + else begin + setactionstate(iactionlink(self),state + [as_disabled]); + end; + inherited; +end; + +procedure tcustomdatabutton.setvisible(const avalue: boolean); +begin + if avalue then begin + setactionstate(iactionlink(self),state - [as_invisible]); + end + else begin + setactionstate(iactionlink(self),state + [as_invisible]); + end; + inherited; +end; + +function tcustomdatabutton.isstatestored: boolean; +begin + result:= isactionstatestored(factioninfo); +end; + +procedure tcustomdatabutton.readcaptionpos(reader: treader); +begin + imagepos:= readcaptiontoimagepos(reader); +end; + +procedure tcustomdatabutton.readshortcut(reader: treader); +begin + shortcut:= translateshortcut(reader.readinteger); +end; + +procedure tcustomdatabutton.readshortcut1(reader: treader); +begin + shortcut1:= translateshortcut(reader.readinteger); +end; + +procedure tcustomdatabutton.readsc(reader: treader); +begin + shortcuts:= readshortcutarty(reader); +end; + +procedure tcustomdatabutton.writesc(writer: twriter); +begin + writeshortcutarty(writer,factioninfo.shortcut); +end; + +procedure tcustomdatabutton.readsc1(reader: treader); +begin + shortcuts1:= readshortcutarty(reader); +end; + +procedure tcustomdatabutton.writesc1(writer: twriter); +begin + writeshortcutarty(writer,factioninfo.shortcut1); +end; + +procedure tcustomdatabutton.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('captionpos',{$ifdef FPC}@{$endif}readcaptionpos,nil,false); + filer.defineproperty('shortcut',{$ifdef FPC}@{$endif}readshortcut,nil,false); + filer.defineproperty('shortcut1',{$ifdef FPC}@{$endif}readshortcut1,nil,false); + filer.defineproperty('sc',{$ifdef FPC}@{$endif}readsc, + {$ifdef FPC}@{$endif}writesc, + isactionshortcutstored(factioninfo) and + ((filer.ancestor = nil) and (factioninfo.shortcut <> nil) or + ((filer.ancestor <> nil) and + not issameshortcut(factioninfo.shortcut, + tcustombutton(filer.ancestor).shortcuts)))); + filer.defineproperty('sc1',{$ifdef FPC}@{$endif}readsc1, + {$ifdef FPC}@{$endif}writesc1, + isactionshortcut1stored(factioninfo) and + ((filer.ancestor = nil) and (factioninfo.shortcut1 <> nil) or + ((filer.ancestor <> nil) and + not issameshortcut(factioninfo.shortcut, + tcustombutton(filer.ancestor).shortcuts)))); +end; + +procedure tcustomdatabutton.loaded; +begin + inherited; + actionendload(iactionlink(self)); +end; + +procedure tcustomdatabutton.docellevent(const ownedcol: boolean; + var info: celleventinfoty); +begin + inherited; + if ownedcol and (info.eventkind in [cek_mouseenter,cek_mouseleave]) then begin + fgridintf.getcol.grid.invalidatecell(info.cell); + end; +end; + +procedure tcustomdatabutton.setshortcuts(const avalue: shortcutarty); +begin + setactionshortcuts(iactionlink(self),avalue); +end; + +procedure tcustomdatabutton.setshortcuts1(const avalue: shortcutarty); +begin + setactionshortcuts1(iactionlink(self),avalue); +end; + +procedure tcustomdatabutton.internalexecute; +begin + if bo_asyncexecute in foptions then begin + asyncevent; + end + else begin + doexecute; + end; +end; + +procedure tcustomdatabutton.doasyncevent(var atag: integer); +begin + if atag = 0 then begin + doexecute; + end; +end; + +procedure tcustomdatabutton.setcolor(const avalue: colorty); +begin + if csloading in componentstate then begin + inherited; //no actionchanged + end; + setactioncolor(iactionlink(self),avalue); +end; + +procedure tcustomdatabutton.objectchanged(const sender: tobject); +var + i1: int32; +begin + inherited; + for i1:= 0 to high(fvaluefaces.fitems) do begin + tcustomface(fvaluefaces.fitems[i1]).checktemplate(sender); + end; +end; + +function tcustomdatabutton.getassistiveflags(): assistiveflagsty; +begin + result:= inherited getassistiveflags() + [asf_button]; +end; + +function tcustomdatabutton.getassistivecaption(): msestring; +begin + result:= factioninfo.captiontext; + if result = '' then begin + result:= inherited getassistivecaption(); + end; +end; + +procedure tcustomdatabutton.doupdate; +begin + if factioninfo.action <> nil then begin + factioninfo.action.doupdate; + end; + if canevent(tmethod(fonupdate)) then begin + fonupdate(self); + end; +end; + +procedure tcustomdatabutton.doidle(var again: boolean); +begin + doupdate; +end; + +procedure tcustomdatabutton.domousewheelevent(var info: mousewheeleventinfoty); +begin + if not (es_transientfor in info.eventstate) then begin + inherited togglevalue(oe_readonly in getoptionsedit,info.wheel = mw_down); + end + else begin + inherited; + end; +end; + +procedure tcustomdatabutton.setvaluedisabled(const avalue: integer); +begin + if fvaluedisabled <> avalue then begin + fvaluedisabled:= avalue; + { + if fvaluedisabled = -2 then begin + exclude(fstate,des_noenablesync); + end + else begin + include(fstate,des_noenablesync); + checkdisabled(); + end; + } + end; +end; + +procedure tcustomdatabutton.setvaluefonts(const avalue: tvaluefontarrayprop); +begin + fvaluefonts.assign(avalue); +end; + +function tcustomdatabutton.valueenabledstate(const avalue: integer): boolean; +begin + result:= enabled; + if (fvaluedisabled <> -2) then begin + result:= avalue <> fvaluedisabled; + end; +end; + +procedure tcustomdatabutton.checkdisabled(); +begin + if (fgridintf = nil) then begin + //no check if inactive gridrow + enabled:= valueenabledstate(fvalue); + end + else begin + if valueenabledstate(fvalue) then begin + exclude(finfo.state,shs_disabled); + exclude(fstate,des_disabled); + end + else begin + include(finfo.state,shs_disabled); + include(fstate,des_disabled); + end; + end; +end; + +procedure tcustomdatabutton.valuechanged; +begin + checkdisabled(); + inherited; +end; + +procedure tcustomdatabutton.gridtovalue(arow: integer); +begin + inherited; + checkdisabled(); +end; + +procedure tcustomdatabutton.initnewwidget(const ascale: real); +begin + inherited; + if fgridintf <> nil then begin + fgridintf.getcol.options:= + fgridintf.getcol.grid.datacols.options - [co_drawfocus]; + end; +end; + +{ tstockglyphdatabutton } + +constructor tstockglyphdatabutton.create(aowner: tcomponent); +begin + inherited; + imagelist:= stockobjects.glyphs; + glyph:= stg_none; +end; + +procedure tstockglyphdatabutton.setglyph(const avalue: stockglyphty); +begin + fglyph:= avalue; + imagenr:= ord(avalue); +end; + +{ tcustomdataicon } + +constructor tcustomdataicon.create(aowner: tcomponent); +begin + inherited; + fvaluedefault:= -1; + fvalue:= fvaluedefault; + fimagenums:= tintegerarrayprop.create; + fimagenums.onchange:= {$ifdef FPC}@{$endif}imagenumschanged; +end; + +destructor tcustomdataicon.destroy; +begin + fimagenums.free; + inherited; +end; + +procedure tcustomdataicon.setnullvalue; +begin + value:= -1; +end; + +procedure tcustomdataicon.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (sender = fimagelist) and (event = oe_changed) then begin + formatchanged; + end; +end; + +procedure tcustomdataicon.paintglyph(const canvas: tcanvas; + const acolorglyph: colorty; const avalue; + const arect: rectty); +var + int1,int2: integer; + po1: pintegeraty; +begin + if (fimagelist <> nil) then begin + if @avalue = nil then begin + int1:= fvalue + end + else begin + int1:= integer(avalue); + end; + if (int1 >= 0) then begin + int1:= int1 + fimageoffset; + if (int1 < fimagelist.count) and (int1 >= 0) then begin + fimagelist.paint(canvas,int1,arect,[al_ycentered,al_xcentered]); + end; + end + else begin + if (int1 <> -1) and (longword(int1) <> $80000000) then begin + {$warnings off} + po1:= pintegeraty(tarrayprop1(fimagenums).getdatapo^); + {$warnings on} + for int2:= 0 to fimagenums.count-1 do begin + if int1 and bits[int2] <> 0 then begin + fimagelist.paint(canvas,po1^[int2],arect,[al_ycentered,al_xcentered]); + end; + end; + end; + end; + end; + inherited; +end; + +procedure tcustomdataicon.setimagelist(const aValue: timagelist); +begin + setlinkedvar(avalue,tmsecomponent(fimagelist)); + formatchanged; +end; + +procedure tcustomdataicon.setimageoffset(const aValue: integer); +begin + if fimageoffset <> avalue then begin + fimageoffset := aValue; + formatchanged; + end; +end; + +procedure tcustomdataicon.setimagenums(const avalue: tintegerarrayprop); +begin + fimagenums.assign(avalue); +end; + +procedure tcustomdataicon.imagenumschanged(const sender: tarrayprop; const index: integer); +begin + formatchanged; +end; + + +{ tpointeredit } + +function tpointeredit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= tgridpointerdatalist.create(sender); +end; + +function tpointeredit.getdatalistclass: datalistclassty; +begin + result:= tgridpointerdatalist; +end; + +procedure tpointeredit.setvalue(const avalue: pointer); +begin + fvalue:= avalue; + valuechanged; +end; + +function tpointeredit.getgridvalue(const index: integer): pointer; +begin + internalgetgridvalue(index,result); +end; + +procedure tpointeredit.setgridvalue(const index: integer; const avalue: pointer); +begin + internalsetgridvalue(index,avalue); +end; + +function tpointeredit.getgridvalues: pointerarty; +begin + result:= tpointerdatalist(fgridintf.getcol.datalist).asarray; +end; + +procedure tpointeredit.setgridvalues(const avalue: pointerarty); +begin + tpointerdatalist(fgridintf.getcol.datalist).asarray:= avalue; +end; + +procedure tpointeredit.initnewcomponent(const ascale: real); +begin + //do nothing +end; + +procedure tpointeredit.paintglyph(const canvas: tcanvas; + const acolorglyph: colorty; const avalue; + const arect: rectty); +var + po1: pointer; + int1: integer; +begin + if canevent(tmethod(fonpaintglyph)) then begin + if @avalue = nil then begin + po1:= fvalue; + int1:= gridrow; + end + else begin + po1:= pointer(avalue); + int1:= pcellinfoty(canvas.drawinfopo)^.cell.row; + end; + fonpaintglyph(self,canvas,po1,int1); + end; +// inherited; +end; + +procedure tpointeredit.gridtovalue(arow: integer); +begin + fgridintf.getdata(arow,fvalue); + inherited; +end; + +procedure tpointeredit.valuetogrid(arow: integer); +begin + fgridintf.setdata(arow,fvalue); +end; + +function tpointeredit.griddata: tgridpointerdatalist; +begin + result:= tgridpointerdatalist(inherited griddata); +end; + +procedure tpointeredit.setvaluedata(const source); +begin + value:= pointer(source); +end; + +procedure tpointeredit.getvaluedata(out dest); +begin + pointer(dest):= value; +end; + +{ tbarface } + +constructor tbarface.create(const intf: iface); +begin + inherited; + with fade_color do begin + count:= 1; + items[0]:= defaultbarcolor; + end; +end; + +{ tbarframe } + +constructor tbarframe.create(const aowner: tcustomprogressbar); +begin + fowner:= aowner; + fstate:= [fs_nowidget,fs_nosetinstance]; + inherited create(iscrollframe(aowner)); +end; + +{ tcustomprogressbar } + +constructor tcustomprogressbar.create(aowner: tcomponent); +begin + fbar_face:= tbarface.create(iface(self)); + fbar_frame:= tbarframe.create(self); + fformat:= '0%'; + fvaluerange:= 100; + ftextflags:= [tf_ycentered,tf_xcentered]; + inherited; + optionswidget:= defaultoptionswidgetnofocus; +end; + +destructor tcustomprogressbar.destroy; +begin + inherited; + fbar_face.free; + fbar_frame.free; +end; + +procedure tcustomprogressbar.setvalue(const avalue: realty); +begin + if not (csloading in componentstate) then begin + application.lock; + try + if avalue = 0.0 then begin + fcancel:= false; + end; + inherited; + finally + application.unlock; + end; + end + else begin + inherited; + end; +end; + +procedure tcustomprogressbar.setbar_face(const avalue: tbarface); +begin + fbar_face.assign(avalue); +end; + +procedure tcustomprogressbar.updatebarrect(const avalue: realty; const arect: rectty; + out facedest,framebardest,facebardest: rectty); +var + int1,int2,int3: integer; +begin + if avalue = emptyreal then begin + facedest:= nullrect; + framebardest:= nullrect; + facebardest:= nullrect; + end + else begin + with fbar_frame do begin + facedest.x:= arect.x + fi.innerframe.left; //origin = paintpos + facedest.y:= arect.y + fi.innerframe.top; + int2:= (finnerframe.left+finnerframe.right); + int3:= (finnerframe.top+finnerframe.bottom); + facedest.cx:= arect.cx - int2; + facedest.cy:= arect.cy - int3; + end; +// facedest:= deflaterect(arect,fbar_frame.innerframe); +// facedest.pos:= pointty(fbar_frame.fi.innerframe.topleft); + //origin = paintpos + framebardest:= arect; + if fdirection in [gd_right,gd_left] then begin + int1:= round(avalue*facedest.cx) + int2; + if fdirection = gd_left then begin + inc(framebardest.x,framebardest.cx - int1); + end; + framebardest.cx:= int1; + end + else begin + int1:= round(avalue*facedest.cy) + int3; + if fdirection = gd_up then begin + inc(framebardest.y,framebardest.cy - int1); + end; + framebardest.cy:= int1; + end; + facebardest:= deflaterect(framebardest,fbar_frame.innerframe); + subpoint1(facebardest.pos,pointty(fbar_frame.fpaintframe.topleft)); + //origin = paintpos + end; +end; + +procedure tcustomprogressbar.updatebar; +begin + updatebarrect(fvalue,innerclientrect,ffacerect,fframebarrect,ffacebarrect); +end; + +procedure tcustomprogressbar.clientrectchanged; +begin + inherited; + updatebar; +end; + +procedure tcustomprogressbar.dochange; +begin + updatebar; + inherited; +end; + +procedure tcustomprogressbar.changedirection(const avalue: graphicdirectionty; + var dest: graphicdirectionty); +begin + fbar_face.fade_direction:= rotatedirection(fbar_face.fade_direction,avalue,dest); + fbar_frame.changedirection(avalue,dest); + inherited; + updatebar; +end; + +procedure tcustomprogressbar.paintglyph(const canvas: tcanvas; + const acolorglyph: colorty; const avalue; + const arect: rectty); +var + po1,po2,po3: prectty; + rect1,rect2,rect3: rectty; + rea1: realty; +begin + if @avalue = nil then begin + po1:= @ffacerect; + po2:= @fframebarrect; + po3:= @ffacebarrect; + rea1:= fvalue; + end + else begin + po1:= @rect1; + po2:= @rect2; + po3:= @rect3; + rea1:= realty(avalue); + updatebarrect(realty(avalue),arect,rect1,rect2,rect3); + end; + if not (rea1 = emptyreal) then begin + canvas.save; + fbar_frame.paintbackground(canvas,po2^,true,true); + //moves origin to paintrect and sets cliprect + canvas.intersectcliprect(po3^); + fbar_face.paint(canvas,po1^); + canvas.restore; + fbar_frame.paintoverlay(canvas,po2^); + if fformat <> '' then begin + drawtext(canvas,realtytostring(applyrange(rea1,fvaluerange,fvaluestart), + fformat),arect,ftextflags,ffont); + end; + end; + inherited; +end; + +procedure tcustomprogressbar.internalcreateframe; +begin + tdispframe.create(iscrollframe(self)); +end; + +procedure tcustomprogressbar.setvaluerange(const avalue: real); +begin + fvaluerange:= avalue; + formatchanged; +end; + +procedure tcustomprogressbar.setvaluestart(const avalue: real); +begin + fvaluestart:= avalue; + formatchanged; +end; + +procedure tcustomprogressbar.setformat(const avalue: msestring); +begin + fformat:= avalue; + formatchanged; +end; + +procedure tcustomprogressbar.settextflags(const avalue: textflagsty); +begin + ftextflags:= avalue; + formatchanged; +end; + +procedure tcustomprogressbar.setbar_frame(const avalue: tbarframe); +begin + fbar_frame.assign(avalue); +end; + +procedure tcustomprogressbar.doprogress(const sender: tobject; const avalue: real; + var acancel: boolean); +begin + application.lock; + try + value:= avalue; + acancel:= acancel or cancel; + if canevent(tmethod(fonprogress)) then begin + fonprogress(sender,avalue,acancel); + end; + if (acancel or (avalue >= 1.0)) and canevent(tmethod(fonfinished)) then begin + fonfinished(sender,avalue,acancel); + end; + finally + application.unlock; + end; +end; + +procedure tcustomprogressbar.readformat(reader: treader); +begin + fformat:= treader_readmsestring(reader); +// {$ifdef mse_unicodestring} +// fformat:= reader.readunicodestring; +// {$else} +// fformat:= reader.readwidestring; +// {$endif} +end; + +procedure tcustomprogressbar.writeformat(writer: twriter); +begin + twriter_writemsestring(writer,fformat); +// {$ifdef mse_unicodestring} +// writer.writeunicodestring(fformat); +// {$else} +// writer.writewidestring(fformat); +// {$endif} +end; + +procedure tcustomprogressbar.readvaluescale(reader: treader); +begin + valuerange:= valuescaletorange(reader); +end; + +procedure tcustomprogressbar.defineproperties(filer: tfiler); +begin + filer.defineproperty('format',{$ifdef FPC}@{$endif}readformat, + {$ifdef FPC}@{$endif}writeformat,true); + filer.defineproperty('valuescale',{$ifdef FPC}@{$endif}readvaluescale,nil,false); +end; + +procedure tcustomprogressbar.gridtovalue(arow: integer); +begin + inherited; + updatebar(); +end; + +{ tsliderframe } + +procedure tsliderframe.settemplateinfo(const ainfo: frameinfoty); +begin + inherited; + if not (frl1_colorglyph in flocalprops1) and + (ainfo.ba.colorglyph <> cl_default) then begin + tslider(fintf.getwidget).scrollbar.colorglyph:= ainfo.ba.colorglyph; + end; + if not (frl1_colorpattern in flocalprops1) and + (ainfo.ba.colorpattern <> cl_default) then begin + tslider(fintf.getwidget).scrollbar.colorpattern:= ainfo.ba.colorpattern; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/editwidgets/mselistbrowser.pas b/mseide-msegui/lib/common/editwidgets/mselistbrowser.pas new file mode 100644 index 0000000..ffa86b4 --- /dev/null +++ b/mseide-msegui/lib/common/editwidgets/mselistbrowser.pas @@ -0,0 +1,7180 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mselistbrowser; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + mseglob,classes,mclasses,msegrids,msedatanodes,msedatalist,msedragglob, + msegraphics,msegraphutils,msetypes,msestrings,msemenus,msestockobjects, + msebitmap,mseclasses,mseguiglob,msedrawtext,msefileutils,msedataedits, + mseeditglob,msewidgetgrid,msewidgets,mseedit,mseevent,msegui,msedropdownlist, + msesys,msedrag,msestat,mseinplaceedit,msepointer,msegridsglob, + mserichstring,msearrayprops,msevaluenodesglob + {$ifdef mse_with_ifi} + ,mseificomp,mseifiglob,mseificompglob,mseifigui + {$endif} + ; + +const + defaultcellwidth = 50; + defaultcellheight = 50; + defaultcellwidthmin = 10; + defaultitemedittextflags = defaulttextflags + [tf_clipo]; + defaultitemedittextflagsactive = defaulttextflagsactive + [tf_clipo]; + +type + listviewoptionty = ( //matched with coloptionty + lvo_readonly,lvo_mousemoving,lvo_keymoving,lvo_horz, + lvo_drawfocus,lvo_mousemovefocus, + lvo_leftbuttonfocusonly,lvo_middlebuttonfocus, + lvo_noctrlmousefocus, + lvo_focusselect,lvo_mouseselect,lvo_keyselect, + lvo_multiselect,lvo_resetselectonexit,{lvo_noresetselect,} + lvo_fill, + lvo_locate,lvo_casesensitive,lvo_savevalue,lvo_savestate, + lvo_hintclippedtext + ); + listviewoptionsty = set of listviewoptionty; + + filelistviewoptionty = (flvo_maskcasesensitive, //dso_casesensitive, + flvo_maskcaseinsensitive, //dso_caseinsensitive + flvo_nodirselect,flvo_nofileselect,flvo_checksubdir); + //same layout as dirstreamoptionty + filelistviewoptionsty = set of filelistviewoptionty; + +const + defaultlistviewoptionsgrid = defaultoptionsgrid + [og_wraprow,og_mousescrollcol]; + defaultlistviewoptions = [lvo_focusselect,lvo_mouseselect,lvo_drawfocus, + lvo_leftbuttonfocusonly,lvo_locate]; + defaultfilelistviewoptions = [flvo_nodirselect]; + coloptionsmask: listviewoptionsty = + [lvo_readonly,{lvo_mousemoving,lvo_keymoving,lvo_horz,} + lvo_drawfocus,lvo_mousemovefocus,lvo_leftbuttonfocusonly, + lvo_middlebuttonfocus, + lvo_noctrlmousefocus, + lvo_focusselect,lvo_mouseselect,lvo_keyselect, + lvo_multiselect,lvo_resetselectonexit{,lvo_noresetselect}]; +// lvo_coloptions = lvo_drawfocus; + +type + tcustomlistview = class; + + tlistedititem = class(tlistitem) + end; + + listedititemarty = array of tlistitem; + listedititemclassty = class of tlistedititem; + + trichlistedititem = class(tlistedititem) + private + function getrichcaption: richstringty; + procedure setrichcaption(const avalue: richstringty); + procedure setcaptionformat(const avalue: formatinfoarty); + protected + fformat: formatinfoarty; + public + procedure updatecaption(const acanvas: tcanvas; + var alayoutinfo: listitemlayoutinfoty; + var ainfo: drawtextinfoty); override; + property richcaption: richstringty read getrichcaption write setrichcaption; + property captionformat: formatinfoarty read fformat write setcaptionformat; + end; + + tlisteditvalueitem = class(tlistitem) + protected + end; + + ttreeitemeditlist = class; + ttreelistedititem = class; + treelistedititemclassty = class of ttreelistedititem; + treelistedititemarty = array of ttreelistedititem; + treelistedititematy = array[0..0] of ttreelistedititem; + ptreelistedititematy = ^treelistedititematy; + + ttreeitemedit = class; + + ttreelistedititem = class(ttreelistitem) + private + factiveindex: integer; + function getactiveindex: integer; + public + constructor create(const aowner: tcustomitemlist = nil; + const aparent: ttreelistitem = nil); override; + procedure assign(source: ttreeitemeditlist); overload; + //source remains owner of items, parent of items is unchanged + function add(const aitem: ttreelistedititem): integer; overload; + //returns index, nil ignored + procedure add(const aitems: treelistedititemarty); overload; + function add(const itemclass: treelistedititemclassty = nil): + ttreelistedititem; overload; + procedure add(const acount: integer; + const itemclass: treelistedititemclassty = nil); overload; + procedure add(const captions: array of msestring; + const itemclass: treelistedititemclassty = nil); overload; + property activeindex: integer read getactiveindex; + function endtreerow: integer; + //returns index of last row of tree + function editwidget: ttreeitemedit; + procedure activate; + end; + ptreelistedititem = ^ttreelistedititem; + + tdirtreenode = class(ttreelistedititem) + protected + procedure checkfiles(var afiles: filenamearty); virtual; + public + procedure loaddirtree(const apath: filenamety); virtual; + function path(const astart: integer = 0): filenamety; + end; + + createlistitemeventty = procedure(const sender: tcustomitemlist; + var item: tlistedititem) of object; + createtreelistitemeventty = procedure(const sender: tcustomitemlist; + var item: ttreelistedititem) of object; + nodenotificationeventty = procedure(const sender: tlistitem; + var action: nodeactionty) of object; + listitemeventty = procedure(const sender: tobject; + const aitem: tlistitem) of object; + + titemviewlist = class; + + paintlistitemeventty = procedure(const sender: titemviewlist; + const canvas: tcanvas; const item: tlistedititem) of object; + +const + defaultboxids: treeitemboxidarty = ( + //tib_none, tib_empty, tib_expand, tib_expanded + -1,ord(stg_box),ord(stg_boxexpand),ord(stg_boxexpanded), + //tib_checkbox, tib_checkboxchecked + ord(stg_checkbox),ord(stg_checkboxchecked), + //tib_checkboxparentnotchecked,tib_checkboxchildchecked + ord(stg_checkboxparentnotchecked),ord(stg_checkboxchildchecked), + //tib_checkboxchildnotchecked + ord(stg_checkboxchildnotchecked) + ); +type + titemviewlist = class(tcustomitemlist,iitemlist) + private + flistview: tcustomlistview; + fonpaintitem: paintlistitemeventty; + function getoncreateitem: createlistitemeventty; + procedure setoncreateitem(const Value: createlistitemeventty); + protected + flayoutinfo: listitemlayoutinfoty; + procedure doitemchange(const index: integer); override; + procedure updatelayout; override; + procedure invalidate; override; + + //iitemlist + function getgrid: tcustomgrid; + function getlayoutinfo(const acellinfo: pcellinfoty): plistitemlayoutinfoty; + procedure itemcountchanged; +// function getcolorglyph: colorty; + procedure updateitemvalues(const index: integer; const acount: integer); + function getcomponentstate: tcomponentstate; + + public + constructor create(const alistview: tcustomlistview); + property listview: tcustomlistview read flistview; + property layoutinfo: listitemlayoutinfoty read flayoutinfo; + published + property oncreateitem: createlistitemeventty read getoncreateitem + write setoncreateitem; + property onpaintitem: paintlistitemeventty read fonpaintitem + write fonpaintitem; + property options; + property captionpos; + property fonts; + property imnr_base; + property imagelist; + property imagewidth; + property imageheight; + property imagealignment; + end; + + + tlistcol = class(tdatacol) + private + function getitems(const aindex: integer): tlistitem; + procedure setitems(const aindex: integer; const Value: tlistitem); + protected + function getselected(const row: integer): boolean; override; + procedure setselected(const row: integer; value: boolean); override; + procedure drawcell(const acanvas: tcanvas); override; + procedure setwidth(const Value: integer); override; + procedure setoptions(const Value: coloptionsty); override; + procedure docellevent(var info: celleventinfoty); override; + public + constructor create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); override; + procedure updatecellzone(const row: integer; const pos: pointty; + var result: cellzonety); override; + property items[const aindex: integer]: tlistitem read getitems write setitems; + default; + end; + + tlistcols = class(tdatacols) + protected + procedure changeselectedrange(const start,oldend,newend: gridcoordty; + calldoselectcell: boolean); override; + procedure gridrecttoindex(const rect: gridrectty; out start,stop: integer); + procedure dostatread(const reader: tstatreader; + const aorder: boolean); override; + procedure dostatwrite(const writer: tstatwriter; + const aorder: boolean); override; + public + constructor create(aowner: tcustomlistview); + procedure setselectedrange(const start,stop: gridcoordty; + const value: boolean; + const calldoselectcell: boolean = false; + const checkmultiselect: boolean = false); overload; override; + end; + + itemeventty = procedure(const sender: tcustomlistview; const index: integer; + var info: celleventinfoty) of object; + + tlistitemdragobject = class(tobjectdragobject) + public + constructor create(const asender: tobject; var instance: tdragobject; + const apickpos: pointty; const aitem: tlistitem); + function item: tlistitem; + end; + + tlistitemsdragobject = class(tdragobject) + private + fitems: listitemarty; + public + constructor create(const asender: tobject; var instance: tdragobject; + const apickpos: pointty; const aitems: array of tlistitem); + property items: listitemarty read fitems; + end; + + listvieweventty = procedure(const sender: tcustomlistview) of object; + + tcustomlistview = class(tcellgrid,iedit) + private + feditor: tinplaceedit; + fonitemevent: itemeventty; + fcellwidthmax: integer; + fcellwidthmin: integer; + foptions: listviewoptionsty; + fcellwidth: integer; + fcolorglyph: colorty; + fcolorglyphactive: colorty; + fediting: boolean; + fonitemsmoved: gridblockmovedeventty; + fcellframe: tcellframe; + foncopytoclipboard: updatestringeventty; + fonpastefromclipboard: updatestringeventty; + fcellcursor: cursorshapety; + fglyphversionactive: int32; + procedure createcellframe; + function getcellframe: tcellframe; + procedure setcellframe(const avalue: tcellframe); + function getitems(const index: integer): tlistitem; + procedure setitems(const index: integer; const Value: tlistitem); + procedure setitemlist(value: titemviewlist); + procedure setcellwidthmax(const Value: integer); + procedure setcellwidthmin(Value: integer); + procedure initdatacol(const item: tdatacol); + procedure updatecoloptions; + procedure setcellwidth(const Value: integer); + function getcolorselect: colorty; + procedure setcolorselect(const Value: colorty); + procedure setcolorglyph(const Value: colorty); + procedure setcolorglyphactive(const Value: colorty); + procedure setediting(const Value: boolean); + function getkeystring(const index: integer): msestring; + function getfocusedindex: integer; + procedure setfocusedindex(const avalue: integer); + procedure setupeditor(const newcell: gridcoordty{; posonly: boolean}); + function getdatacollinecolor: colorty; + function getdatacollinewidth: integer; + procedure setdatacollinecolor(const Value: colorty); + procedure setdatacollinewidth(const Value: integer); + function getcellfocusrectdist: integer; + procedure setcellfocusrectdist(const avalue: integer); + function getonselectionchanged: listvieweventty; + procedure setonselectionchanged(const avalue: listvieweventty); + function getonlayoutchanged: listvieweventty; + procedure setonlayoutchanged(const avalue: listvieweventty); + function getcellheight: integer; + procedure setcellheight(const avalue: integer); + function getonbeforeupdatelayout: listvieweventty; + procedure setonbeforeupdatelayout(const avalue: listvieweventty); + function getcellheightmin: integer; + procedure setcellheightmin(const avalue: integer); + function getcellheightmax: integer; + procedure setcellheightmax(const avalue: integer); + procedure setcellcursor(const avalue: cursorshapety); + function getcellsize: sizety; + procedure setcellsize(const avalue: sizety); + procedure setglyphversionactive(const avalue: int32); + protected + fitemlist: titemviewlist; + class function classskininfo: skininfoty; override; + procedure setframeinstance(instance: tcustomframe); override; + procedure limitcellwidth(var avalue: integer); + + procedure setoptions(const avalue: listviewoptionsty); virtual; + procedure rootchanged(const aflags: rootchangeflagsty); override; + procedure doitemchange(index: integer); + procedure doitemevent(const index: integer; + var info: celleventinfoty); virtual; + procedure docellevent(var info: celleventinfoty); override; + function createdatacols: tdatacols; override; + procedure createdatacol(const index: integer; out item: tdatacol); override; + procedure updatelayout; override; + procedure drawfocusedcell(const acanvas: tcanvas); override; + procedure loaded; override; + procedure dokeydown(var info: keyeventinfoty); override; + procedure scrolled(const dist: pointty); override; + + procedure dostatread(const reader: tstatreader); override; + procedure dostatwrite(const writer: tstatwriter); override; + + //iedit + function getoptionsedit: optionseditty; + procedure editnotification(var info: editnotificationinfoty); + function hasselection: boolean; + procedure updatecopytoclipboard(var atext: msestring); virtual; + procedure updatepastefromclipboard(var atext: msestring); virtual; + function locatecount: integer; virtual; //number of locate values + function locatecurrentindex: integer; virtual; //index of current row + procedure locatesetcurrentindex(const aindex: integer); + function getedited: boolean; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure synctofontheight; override; + function internaldragevent(var info: draginfoty): boolean; override; + //true if processed + procedure moveitem(const source,dest: tlistitem; focus: boolean); + function indextocell(const index: integer): gridcoordty; + function celltoindex(const cell: gridcoordty; limit: boolean): integer; + function itematpos(const apos: pointty): tlistitem; + function focuseditem: tlistitem; + property focusedindex: integer read getfocusedindex write setfocusedindex; + function celltoitem(const acell: gridcoordty): tlistitem; + function finditembycaption(const acaption: msestring): tlistitem; + function findcellbycaption(const acaption: msestring; + var cell: gridcoordty): boolean; + function getselecteditems: listitemarty; + function getselectedindexes: integerarty; + + property items[const index: integer]: tlistitem read getitems + write setitems; default; + property editing: boolean read fediting write setediting; + property editor: tinplaceedit read feditor; + + property colorselect: colorty read getcolorselect + write setcolorselect default cl_default; + property colorglyph: colorty read fcolorglyph + write setcolorglyph default cl_glyph; + property colorglyphactive: colorty read fcolorglyphactive + write setcolorglyphactive default cl_glyphactive; + property glyphversionactive: int32 read fglyphversionactive write + setglyphversionactive default 0; + property cellwidth: integer read fcellwidth write setcellwidth + default defaultcellwidth; + property cellheight: integer read getcellheight write setcellheight + default defaultcellheight; + property cellheightmin: integer read getcellheightmin write setcellheightmin + default 1; + property cellheightmax: integer read getcellheightmax write setcellheightmax + default maxint; + property cellwidthmin: integer read fcellwidthmin + write setcellwidthmin default defaultcellwidthmin; + property cellwidthmax: integer read fcellwidthmax + write setcellwidthmax default 0; + property cellsize: sizety read getcellsize write setcellsize; + property cellframe: tcellframe read getcellframe write setcellframe; + property cellcursor: cursorshapety read fcellcursor write setcellcursor + default cr_default; + + property itemlist: titemviewlist read fitemlist write setitemlist; + property options: listviewoptionsty read foptions write setoptions + default defaultlistviewoptions; + property cellfocusrectdist: integer read getcellfocusrectdist + write setcellfocusrectdist default 0; + property datacollinewidth: integer read getdatacollinewidth + write setdatacollinewidth default defaultgridlinewidth; + property datacollinecolor: colorty read getdatacollinecolor + write setdatacollinecolor default defaultdatalinecolor; + property onitemevent: itemeventty read fonitemevent write fonitemevent; + + property onitemsmoved: gridblockmovedeventty read fonitemsmoved + write fonitemsmoved; + property optionsgrid default defaultlistviewoptionsgrid; + property onselectionchanged: listvieweventty read getonselectionchanged + write setonselectionchanged; + property onbeforeupdatelayout: listvieweventty read getonbeforeupdatelayout + write setonbeforeupdatelayout; + property onlayoutchanged: listvieweventty read getonlayoutchanged + write setonlayoutchanged; + property oncopytoclipboard: updatestringeventty read foncopytoclipboard + write foncopytoclipboard; + property onpastefromclipboard: updatestringeventty read fonpastefromclipboard + write fonpastefromclipboard; + end; + + tlistview = class(tcustomlistview) + published + property datarowlinewidth; + property datarowlinecolorfix; + property datarowlinecolor; + property datacollinewidth; + property datacollinecolor; + property colorselect; + property colorglyph; + property cellwidth; + property cellheight; + property cellframe; + property cellcursor; + property cellfocusrectdist; + property fixcols; + property fixrows; + property optionsgrid; + property optionsgrid1; + property options; + property gridframecolor; + property itemlist; + property cellwidthmin; + property cellwidthmax; + property cellheightmin; + property cellheightmax; + property statvarname; + property statpriority; + property statfile; + property onselectionchanged; + property oncopyselection; + property onpasteselection; + property onbeforeupdatelayout; + property onlayoutchanged; + property onitemevent; + property drag; + property onitemsmoved; + property oncopytoclipboard; + property onpastefromclipboard; + end; + + tcustomitemedit = class; + + tcustomitemeditlist = class(tcustomitemlist,iimagelistinfo) + private + fcolorglyph: colorty; + fcolorglyphactive: colorty; + fcolorline: colorty; + fcolorlineactive: colorty; + fowner: tcustomitemedit; + fonitemnotification: nodenotificationeventty; +// fboxglyph_list: timagelist; +// fboxglyph_listactive: timagelist; + fboxglyph_versionactive: int32; + procedure setcolorglyph(const avalue: colorty); + procedure setcolorglyphactive(const avalue: colorty); + function getboxglyph_checkbox: stockglyphty; + procedure setboxglyph_checkbox(const avalue: stockglyphty); + function getboxglyph_checkboxchecked: stockglyphty; + procedure setboxglyph_checkboxchecked(const avalue: stockglyphty); + function getboxglyph_checkboxparentnotchecked: stockglyphty; + procedure setboxglyph_checkboxparentnotchecked(const avalue: stockglyphty); + function getboxglyph_checkboxchildchecked: stockglyphty; + procedure setboxglyph_checkboxchildchecked(const avalue: stockglyphty); + function getboxglyph_checkboxchildnotchecked: stockglyphty; + procedure setboxglyph_checkboxchildnotchecked(const avalue: stockglyphty); +// procedure setboxglyp_list(const avalue: timagelist); +// procedure setboxglyp_listactive(const avalue: timagelist); + procedure setboxglyph_versionactive(const avalue: int32); + protected + fboxids: treeitemboxidarty; + procedure createstatitem(const reader: tstatreader; + out item: tlistitem); override; + procedure doitemchange(const index: integer); override; + procedure nodenotification(const sender: tlistitem; + var ainfo: nodeactioninfoty); override; + function compare(const l,r): integer; override; + class function defaultitemclass(): listedititemclassty; virtual; + procedure itemclasschanged(); + //iimagelistinfo + function getimagelist: timagelist; + public + constructor create; overload; override; + constructor create(const intf: iitemlist; + const owner: tcustomitemedit); reintroduce; overload; + procedure assign(const aitems: listitemarty); reintroduce; overload; + procedure insert(const aindex: integer; const anode: tlistitem); + procedure add(const anode: tlistitem); + procedure refreshitemvalues(aindex: integer = 0; //-1 = current grid row + acount: integer = -1); //-1 = all + property owner: tcustomitemedit read fowner; + property colorglyph: colorty read fcolorglyph + write setcolorglyph default cl_glyph; + //for monochrome imagelist + property colorglyphactive: colorty read fcolorglyphactive + write setcolorglyphactive default cl_glyphactive; + //for monochrome imagelist +// property boxglyph_list: timagelist read fboxglyph_list write setboxglyp_list; +// property boxglyph_listactive: timagelist read fboxglyph_listactive +// write setboxglyp_listactive; + property boxglyph_versionactive: int32 read fboxglyph_versionactive write + setboxglyph_versionactive default 0; + property boxglyph_checkbox: stockglyphty read getboxglyph_checkbox + write setboxglyph_checkbox default stg_checkbox; + property boxglyph_checkboxchecked: stockglyphty + read getboxglyph_checkboxchecked + write setboxglyph_checkboxchecked default stg_checkboxchecked; + property boxglyph_checkboxparentnotchecked: stockglyphty + read getboxglyph_checkboxparentnotchecked + write setboxglyph_checkboxparentnotchecked + default stg_checkboxparentnotchecked; + property boxglyph_checkboxchildchecked: stockglyphty + read getboxglyph_checkboxchildchecked + write setboxglyph_checkboxchildchecked default stg_checkboxchildchecked; + property boxglyph_checkboxchildnotchecked: stockglyphty + read getboxglyph_checkboxchildnotchecked + write setboxglyph_checkboxchildnotchecked + default stg_checkboxchildnotchecked; + property onitemnotification: nodenotificationeventty + read fonitemnotification write fonitemnotification; + published + end; + + titemeditlist = class(tcustomitemeditlist) + private + procedure setoncreateitem(const value: createlistitemeventty); + function getoncreateitem: createlistitemeventty; + function getitemclass: listedititemclassty; + procedure setitemclass(const avalue: listedititemclassty); + protected + public + property itemclass: listedititemclassty read getitemclass write setitemclass; + published + property colorglyph; + property colorglyphactive; + property boxglyph_versionactive; +// property boxglyph_list; +// property boxglyph_listactive; + property boxglyph_checkbox; + property boxglyph_checkboxchecked; + property boxglyph_checkboxparentnotchecked; + property boxglyph_checkboxchildchecked; + property imnr_base; + property imnr_expanded; + property imnr_selected; + property imnr_readonly; + property imnr_checked; + property imnr_subitems; + property imnr_focused; + property imnr_active; + property imagelist; + property imagewidth; + property imageheight; + property imagealignment; + property defaultnodestate; + property captionpos; + property fonts; + property options; + property onitemnotification; + property oncreateitem: createlistitemeventty read getoncreateitem + write setoncreateitem; + property onstatreaditem; + property onstatwrite; + property onstatread; + end; + + trecordfielditem = class(tlistedititem) + protected + fvalueitem: tlistitem; + function getvalueitem: tlistitem; override; + procedure setvalueitem(const avalue: tlistitem); override; + public + end; + + trecordfielditemeditlist = class(titemeditlist) + protected + class function defaultitemclass(): listedititemclassty; override; + end; + + valueeditinfoty = record + datatype: listdatatypety; + valueindex: int32; + editwidget: twidget; + gridintf: igridwidget; + visible: boolean; + end; + pvalueeditinfoty = ^valueeditinfoty; + + tvalueedititem = class(townedpersistent) + private + finfo: valueeditinfoty; + procedure seteditwidget(const avalue: twidget); + procedure setvalueindex(const avalue: int32); + protected + procedure changed(); + public + destructor destroy(); override; + published + property valueindex: int32 read finfo.valueindex write + setvalueindex default 0; + property editwidget: twidget read finfo.editwidget write seteditwidget; + end; + + tvalueedits = class(townedpersistentarrayprop) + public + constructor create(const aowner: tcustomitemedit); reintroduce; + class function getitemclasstype: persistentclassty; override; + published + end; + + itemindexeventty = procedure(const sender: tobject; const aindex: integer; + const aitem: tlistitem) of object; + itemcanediteventty = procedure(const sender: tobject; + const aitem: tlistitem; var canedit: boolean) of object; + + extendimageeventty = procedure(const sender: twidget; + const cellinfopo: pcellinfoty; //nil for non cell call + var ainfo: extrainfoty) of object; + tcustomitemedit = class(tdataedit,iitemlist,ibutton) + private + fitemlist: tcustomitemeditlist; + fonsetvalue: setstringeventty; + fonclientmouseevent: mouseeventty; + fonbuttonaction: buttoneventty; + fonupdaterowvalues: itemindexeventty; + foncellevent: celleventty; + factiverow: integer; + fcalcsize: sizety; + foncheckcanedit: itemcanediteventty; + fonextendimage: extendimageeventty; + + fvalueedits: tvalueedits; + {$ifdef mse_with_ifi} + fitemifilink: boolean; + {$endif} + function getframe: tbuttonsframe; + procedure setframe(const avalue: tbuttonsframe); + function getitemlist: titemeditlist; + procedure setitemlist(const Value: titemeditlist); + function getitems(const index: integer): tlistitem; + procedure setitems(const index: integer; const Value: tlistitem); + function getediting: boolean; + procedure setediting(const avalue: boolean); + {$ifdef mse_with_ifi} + function getifilink: tifistringlinkcomp; + procedure setifilink(const avalue: tifistringlinkcomp); + function getifilink1: tifilinkcomp; + procedure setifilink1(const avalue: tifilinkcomp); +// function getifiitemlink: tifiitemlinkcomp; +// procedure setifiitemlink(const avalue: tifiitemlinkcomp); + {$endif} + procedure setvalueedits(const avalue: tvalueedits); + protected + factiveinfo: valueeditinfoty; + fvisiblevalueeditcount: int32; + flastzonewidget: twidget; + flayoutinfofocused: listitemlayoutinfoty; + flayoutinfocell: listitemlayoutinfoty; + fentryedge: graphicdirectionty; + fvalue: tlistitem; + + procedure valueeditchanged(); + procedure unregisterchildwidget(const child: twidget); override; + //track removing of field edits + procedure loaded(); override; + procedure dofocus; override; + + function valuecanedit: boolean; + procedure doextendimage(const cellinfopo: pcellinfoty; + var ainfo: extrainfoty); virtual; + procedure getautopaintsize(var asize: sizety); override; + procedure getautocellsize(const acanvas: tcanvas; + var asize: sizety); override; + procedure calclayout(const asize: sizety; + out alayout: listitemlayoutinfoty); + function finddataedits(aitem: tlistitem; out ainfos: recvaluearty): boolean; + function updateeditwidget(): boolean; //true if editwidgetactivated + procedure childdataentered(const sender: igridwidget); override; + procedure childfocused(const sender: igridwidget); override; + + {$ifdef mse_with_ifi} + //iifidatalink + procedure updateifigriddata(const sender: tobject; + const alist: tdatalist); override; + {$endif} + + //iedit + function locatecount: integer; override; //number of locate values + function getkeystring(const index: integer): msestring; override; + + procedure itemchanged(const index: integer); virtual; + procedure createnode(var item: tlistitem); virtual; + + procedure doupdatelayout(const nocolinvalidate: boolean); virtual; + procedure doupdatecelllayout; virtual; + + //iitemlist + function getgrid: tcustomgrid; + function getlayoutinfo(const acellinfo: pcellinfoty): plistitemlayoutinfoty; + procedure itemcountchanged; +// function getcolorglyph: colorty; + + //igridwidget + procedure setfirstclick(var ainfo: mouseeventinfoty); override; + function getcellcursor(const arow: integer; const acellzone: cellzonety; + const apos: pointty): cursorshapety; override; + procedure updatecellzone(const row: integer; const apos: pointty; + var result: cellzonety); override; + procedure setgridintf(const intf: iwidgetgrid); override; + function createdatalist(const sender: twidgetcol): tdatalist; override; + procedure datalistdestroyed; override; + function getdatalistclass: datalistclassty; override; + procedure drawcell(const canvas: tcanvas); override; + procedure valuetogrid(arow: integer); override; + procedure gridtovalue(arow: integer); override; + function internaldatatotext(const data): msestring; override; + procedure dosetvalue(var avalue: msestring; var accept: boolean); virtual; + procedure storevalue(var avalue: msestring); virtual; + procedure texttovalue(var accept: boolean; const quiet: boolean); override; + procedure clientrectchanged; override; + procedure updatelayout(); + procedure doitembuttonpress(var info: mouseeventinfoty); virtual; + procedure clientmouseevent(var info: mouseeventinfoty); override; + function getitemclass: listitemclassty; virtual; + procedure setupeditor; override; + procedure dopaintforeground(const acanvas: tcanvas); override; + procedure dokeydown(var info: keyeventinfoty); override; + + procedure getitemvalues; virtual; + procedure internalcreateframe; override; + + //ibuttonaction + procedure buttonaction(var action: buttonactionty; + const buttonindex: integer); virtual; + + procedure mouseevent(var info: mouseeventinfoty); override; + procedure docellevent(const ownedcol: boolean; + var info: celleventinfoty); override; + + function getoptionsedit: optionseditty; override; + property editing: boolean read getediting write setediting; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure insertwidget(const awidget: twidget; + const apos: pointty); override; + function textclipped(const arow: integer; + out acellrect: rectty): boolean; overload; override; + function getvaluetext: msestring; + procedure setvaluetext(var avalue: msestring); + function isnull: boolean; override; + function item: tlistedititem; + property items[const index: integer]: tlistitem read getitems + write setitems; default; + function selecteditems: listedititemarty; + + procedure beginedit; + procedure endedit; + procedure updateitemvalues(const index: integer; + const count: integer); virtual; + procedure updateitemvalues; + //calls updateitemvalues for current grid row + property activerow: integer read factiverow; + published + property itemlist: titemeditlist read getitemlist + write setitemlist stored false; +{$ifdef mse_with_ifi} + property ifilink: tifistringlinkcomp read getifilink write setifilink; +// property ifiitemlink: tifiitemlinkcomp read getifiitemlink +// write setifiitemlink; +{$endif} + property onsetvalue: setstringeventty read fonsetvalue write fonsetvalue; + property onclientmouseevent: mouseeventty read fonclientmouseevent + write fonclientmouseevent; + property optionsedit1; //before optionsedit! + property optionsedit; + property font; + property passwordchar; + property maxlength; + property textflags default defaultitemedittextflags; + property textflagsactive default defaultitemedittextflagsactive; + property frame: tbuttonsframe read getframe write setframe; + property valueedits: tvalueedits read fvalueedits write setvalueedits; + property onchange; +// property onbeforepaint; +// property onpaintbackground; +// property onpaint; + property onpaintimage; + property onextendimage: extendimageeventty read fonextendimage + write fonextendimage; +// property onafterpaint; + property onbuttonaction: buttoneventty read fonbuttonaction + write fonbuttonaction; + property onupdaterowvalues: itemindexeventty read fonupdaterowvalues + write fonupdaterowvalues; + property oncellevent: celleventty read foncellevent write foncellevent; + property oncheckcanedit: itemcanediteventty read foncheckcanedit + write foncheckcanedit; + end; + + titemedit = class; + + titemclientcontroller = class(tvalueclientcontroller) + private + fitemedit: tcustomitemedit; + function getitemlist(): titemeditlist; + function getitemedit: titemedit; + protected + function createdatalist: tdatalist override; + function getlistdatatypes: listdatatypesty override; + function getlistitem(): tlistedititem; + procedure linkset(const alink: iificlient); override; + public + property item: tlistedititem read getlistitem; + property itemlist: titemeditlist read getitemlist; + property itemedit: titemedit read getitemedit; + end; + + tifiitemlinkcomp = class(tifivaluelinkcomp) + private + function getcontroller: titemclientcontroller; + procedure setcontroller(const avalue: titemclientcontroller); + protected + function getcontrollerclass: customificlientcontrollerclassty; override; + public + property c: titemclientcontroller read getcontroller + write setcontroller; + published + property controller: titemclientcontroller read getcontroller + write setcontroller; + end; + + titemedit = class(tcustomitemedit) + private + {$ifdef mse_with_ifi} + function getifiitemlink: tifiitemlinkcomp; + procedure setifiitemlink(const avalue: tifiitemlinkcomp); + {$endif} + published +{$ifdef mse_with_ifi} + property ifiitemlink: tifiitemlinkcomp read getifiitemlink + write setifiitemlink; +{$endif} + end; + + tdropdownitemedit = class(titemedit,idropdownlist) + private + fdropdown: tcustomdropdownlistcontroller; + fonbeforedropdown: notifyeventty; + fonafterclosedropdown: notifyeventty; + procedure setdropdown(const Value: tcustomdropdownlistcontroller); + protected + procedure doupdatecelllayout; override; + function getframe: tdropdownmultibuttonframe; + procedure setframe(const avalue: tdropdownmultibuttonframe); + function getdropdowncontrollerclass: dropdownlistcontrollerclassty; virtual; + //idropdown + procedure dobeforedropdown; virtual; + procedure doafterclosedropdown; virtual; + function getdropdownitems: tdropdowndatacols; + function getvalueempty: integer; virtual; + procedure imagelistchanged; virtual; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property frame: tdropdownmultibuttonframe read getframe write setframe; + property dropdown: tcustomdropdownlistcontroller read fdropdown + write setdropdown; + property onbeforedropdown: notifyeventty read fonbeforedropdown + write fonbeforedropdown; + property onafterclosedropdown: notifyeventty read fonafterclosedropdown + write fonafterclosedropdown; + end; + + tmbdropdownitemedit = class(tdropdownitemedit) + //redundant, all dropdowns are multibutton + private + protected + function getframe: tdropdownmultibuttonframe; + procedure setframe(const Value: tdropdownmultibuttonframe); + function getdropdowncontrollerclass: dropdownlistcontrollerclassty; override; + published + property frame: tdropdownmultibuttonframe read getframe write setframe; + end; + + ttreeeditnode = class(ttreenode) + protected + function listitemclass: treelistitemclassty; override; + public + function converttotreelistitem(flat: boolean = false; + withrootnode: boolean = false; + filterfunc: treenodefilterfuncty = nil): ttreelistedititem; + end; + + ttreeitemdragobject = class(tdragobject) + private + fitem: ttreelistitem; + fdestrow: integer; + public + constructor create(const asender: tobject; var instance: tdragobject; + const apickpos: pointty; const aitem: ttreelistitem); + property item: ttreelistitem read fitem; + property destrow: integer read fdestrow; + end; + + treeitemdragbegineventty = procedure(const sender: ttreeitemedit; + const aitem: ttreelistitem; + var candrag: boolean; var dragobject: ttreeitemdragobject; + var processed: boolean) of object; + treeitemdragovereventty = procedure(const sender: ttreeitemedit; + const source,dest: ttreelistitem; + var dragobject: ttreeitemdragobject; var accept: boolean; + var processed: boolean) of object; + treeitemdragdropeventty = procedure(const sender: ttreeitemedit; + const source,dest: ttreelistitem; + var dragobject: ttreeitemdragobject; + var processed: boolean) of object; + + expandedinfoty = record + path: msestringarty; + end; + expandedinfoarty = array of expandedinfoty; + + ttreeitemeditlist = class(tcustomitemeditlist) + private + fchangingnode: ttreelistitem; + finsertcount: integer; + finsertindex: integer; + fondragbegin: treeitemdragbegineventty; + fondragover: treeitemdragovereventty; + fondragdrop: treeitemdragdropeventty; + frootnode: ttreelistedititem; + finsertparent: ttreelistedititem; + finsertparentindex: integer; +// foptionsdraw: itemdrawoptionsty; + procedure setoncreateitem(const value: createtreelistitemeventty); + function getoncreateitem: createtreelistitemeventty; + procedure setcolorline(const value: colorty); + procedure setcolorlineactive(const value: colorty); + function getonstatreaditem: statreadtreeitemeventty; + procedure setonstatreaditem(const avalue: statreadtreeitemeventty); + function getitems1(const index: integer): ttreelistedititem; + procedure setitems(const index: integer; const avalue: ttreelistedititem); + function getitemclass: treelistedititemclassty; + procedure setitemclass(const avalue: treelistedititemclassty); + function getexpandedstate: expandedinfoarty; + procedure setexpandedstate(const avalue: expandedinfoarty); + function getonstatwriteitem: statwritetreeitemeventty; + procedure setonstatwriteitem(const avalue: statwritetreeitemeventty); + procedure setrootnode(const avalue: ttreelistedititem); + function getboxglyph_empty: stockglyphty; + procedure setboxglyph_empty(const avalue: stockglyphty); + function getboxglyph_expand: stockglyphty; + procedure setboxglyph_expand(const avalue: stockglyphty); + function getboxglyph_expanded: stockglyphty; + procedure setboxglyph_expanded(const avalue: stockglyphty); +// procedure setoptionsdraw(const avalue: itemdrawoptionsty); +{ + function getboxglyphactive_empty: stockglyphty; + procedure setboxglyphactive_empty(const avalue: stockglyphty); + function getboxglyphactive_expand: stockglyphty; + procedure setboxglyphactive_expand(const avalue: stockglyphty); + function getboxglyphactive_expanded: stockglyphty; + procedure setboxglyphactive_expanded(const avalue: stockglyphty); +} + protected +// fboxidsactive: treeitemboxidarty; + procedure freedata(var data); override; + procedure docreateobject(var instance: tobject); override; + procedure createitem(out item: tlistitem); override; + procedure nodenotification(const sender: tlistitem; + var ainfo: nodeactioninfoty); override; + function compare(const l,r): integer; override; + procedure statreaditem(const reader: tstatreader; + var aitem: tlistitem); override; + procedure statwriteitem(const writer: tstatwriter; + const aitem: tlistitem); override; + procedure readstate(const reader; const acount: integer; + const aname: msestring); override; + procedure writestate(const writer; const name: msestring); override; + procedure beforedragevent(var ainfo: draginfoty; const arow: integer; + var processed: boolean); + procedure afterdragevent(var ainfo: draginfoty; const arow: integer; + var processed: boolean); + public + constructor create; overload; override; + constructor create(const intf: iitemlist; const aowner: ttreeitemedit); + reintroduce; overload; + procedure beginupdate; override; + procedure endupdate; override; + procedure change(const index: integer); override; + procedure deleteitems(index,acount: integer); override; + procedure insertitems(index,acount: integer); override; + + procedure assign(const root: ttreelistedititem; + const freeroot: boolean = true); reintroduce; overload; + procedure assign(const aitems: treelistedititemarty); reintroduce; overload; + procedure add(const anode: ttreelistedititem; + const freeroot: boolean = true); overload; + + //adds toplevel node + procedure add(const anodes: treelistedititemarty); overload; + procedure add(const acount: integer; + aitemclass: treelistedititemclassty = nil); overload; + procedure addchildren(const anode: ttreelistedititem); + //adds children as toplevel nodes + procedure insert(const aindex: integer;const anode: ttreelistedititem; + const freeroot: boolean = true); + //inserts in parent of items[aindex] + procedure delete(const aindex: integer); + procedure readnode(const aname: msestring; const reader: tstatreader; + const anode: ttreelistitem); + procedure writenode(const aname: msestring; const writer: tstatwriter; + const anode: ttreelistitem); + procedure updatenode(const aname: msestring; const filer: tstatfiler; + const anode: ttreelistitem); + + function toplevelnodes: treelistedititemarty; + function getnodes(const must: nodestatesty; const mustnot: nodestatesty; + const amode: getnodemodety = gno_matching): treelistitemarty; + function getselectednodes(const amode: getnodemodety = + gno_matching): treelistitemarty; + function getcheckednodes(const amode: getnodemodety = + gno_matching): treelistitemarty; + procedure updatechildcheckedtree; //slow! + procedure updatechildnotcheckedtree; //slow! + procedure updateparentnotcheckedtree; //slow! + + procedure expandall; + procedure collapseall; + procedure moverow(const source,dest: integer); + //source and dest must belong to the same parent, ignored otherwise + property itemclass: treelistedititemclassty read getitemclass + write setitemclass; + property items[const index: integer]: ttreelistedititem read getitems1 + write setitems; default; + property expandedstate: expandedinfoarty read getexpandedstate + write setexpandedstate; + + property rootnode: ttreelistedititem read frootnode write setrootnode; + //clears list and adds children + property insertparent: ttreelistedititem read finsertparent; + //valid in oncreateitem + property insertparentindex: integer read finsertparentindex; + //valid in oncreateitem + published + property colorglyph; + property colorglyphactive; + property boxglyph_versionactive; +// property boxglyph_list; +// property boxglyph_listactive; + property boxglyph_checkbox; + property boxglyph_checkboxchecked; + property boxglyph_checkboxparentnotchecked; + property boxglyph_checkboxchildchecked; + property imnr_base; + property imnr_expanded; + property imnr_selected; + property imnr_readonly; + property imnr_checked; + property imnr_subitems; + property imnr_focused; + property imnr_active; + property imagelist; + property imagewidth; + property imageheight; + property imagealignment; + property defaultnodestate; + property captionpos; + property fonts; + property options; + property onitemnotification; +// property optionsdraw: itemdrawoptionsty read foptionsdraw +// write setoptionsdraw default []; + property colorline: colorty read fcolorline write setcolorline + default cl_treeline; + property colorlineactive: colorty read fcolorlineactive + write setcolorlineactive default cl_treelineactive; + property boxglyph_empty: stockglyphty read getboxglyph_empty + write setboxglyph_empty default stg_box; + property boxglyph_expand: stockglyphty read getboxglyph_expand + write setboxglyph_expand default stg_boxexpand; + property boxglyph_expanded: stockglyphty read getboxglyph_expanded + write setboxglyph_expanded default stg_boxexpanded; +{ + property boxglyphactive_empty: stockglyphty read getboxglyphactive_empty + write setboxglyphactive_empty default stg_box; + property boxglyphactive_expand: stockglyphty read getboxglyphactive_expand + write setboxglyphactive_expand default stg_boxexpand; + property boxglyphactive_expanded: stockglyphty + read getboxglyphactive_expanded + write setboxglyphactive_expanded default stg_boxexpanded; +} + property oncreateitem: createtreelistitemeventty read getoncreateitem + write setoncreateitem; + property onstatwriteitem: statwritetreeitemeventty read getonstatwriteitem + write setonstatwriteitem; + property onstatreaditem: statreadtreeitemeventty read getonstatreaditem + write setonstatreaditem; + property onstatwrite; + property onstatread; + property ondragbegin: treeitemdragbegineventty read fondragbegin + write fondragbegin; + property ondragover: treeitemdragovereventty read fondragover + write fondragover; + property ondragdrop: treeitemdragdropeventty read fondragdrop + write fondragdrop; + property levelstep; + end; + + treeitemeditoptionty = (teo_treecolnavig,teo_treerownavig,teo_keyrowmoving, + teo_enteronimageclick,teo_enterondoubleclick); + treeitemeditoptionsty = set of treeitemeditoptionty; + + checkmoveeventty = procedure(const curindex,newindex: integer; + var accept: boolean) of object; + + trecordfieldedit = class(tmbdropdownitemedit) + private + fitemedit: ttreeitemedit; + protected + procedure storevalue(var avalue: msestring); override; +// procedure dosetvalue(var avalue: msestring; var accept: boolean); override; + function getoptionsedit: optionseditty; override; + public + constructor create(aowner: tcomponent); override; + end; + + ttreeitemclientcontroller = class(titemclientcontroller) + private + protected + function getlistitem(): ttreelistedititem; + function getitemlist(): ttreeitemeditlist; + function getitemedit(): ttreeitemedit; + public + property item: ttreelistedititem read getlistitem; + property itemlist: ttreeitemeditlist read getitemlist; + property itemedit: ttreeitemedit read getitemedit; + end; + + tifitreeitemlinkcomp = class(tifivaluelinkcomp) + private + function getcontroller: ttreeitemclientcontroller; + procedure setcontroller(const avalue: ttreeitemclientcontroller); + protected + function getcontrollerclass: customificlientcontrollerclassty; override; + public + property c: ttreeitemclientcontroller read getcontroller + write setcontroller; + published + property controller: ttreeitemclientcontroller read getcontroller + write setcontroller; + end; + + ttreeitemedit = class(tcustomitemedit,idragcontroller) + private + foptions: treeitemeditoptionsty; + foncheckrowmove: checkmoveeventty; + ffieldedit: trecordfieldedit; + function getitemlist: ttreeitemeditlist; + procedure setitemlist(const Value: ttreeitemeditlist); + function getitems(const index: integer): ttreelistedititem; + procedure setitems(const index: integer; const Value: ttreelistedititem); + procedure expandedchanged(const avalue: boolean); + procedure setfieldedit(const avalue: trecordfieldedit); + private + {$ifdef mse_with_ifi} + function getifiitemlink: tifitreeitemlinkcomp; + procedure setifiitemlink(const avalue: tifitreeitemlinkcomp); + {$endif} + protected + procedure doitembuttonpress(var info: mouseeventinfoty); override; + function locatecount: integer; override; //number of locate values + function locatecurrentindex: integer; override; //index of current row + procedure locatesetcurrentindex(const aindex: integer); override; + function getkeystring(const aindex: integer): msestring; override; + //locate text + procedure doupdatelayout(const nocolinvalidate: boolean); override; +// function getitemclass: listitemclassty; override; + procedure dokeydown(var info: keyeventinfoty); override; + procedure docellevent(const ownedcol: boolean; + var info: celleventinfoty); override; + function checkrowmove(const curindex,newindex: integer): boolean; + procedure beforecelldragevent(var ainfo: draginfoty; const arow: integer; + var processed: boolean); override; + procedure aftercelldragevent(var ainfo: draginfoty; const arow: integer; + var processed: boolean); override; + function getdatalistclass: datalistclassty; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function item: ttreelistedititem; + property items[const index: integer]: ttreelistedititem read getitems + write setitems; default; + function selecteditems: treelistedititemarty; + + function candragsource(const apos: pointty): boolean; + procedure dragdrop(const adragobject: ttreeitemdragobject); + procedure comparerow(const lindex,rindex: integer; var aresult: integer); + procedure updateitemvalues(const index: integer; + const count: integer); override; + procedure updateitemvalues(); + procedure updateparentvalues(const index: integer); + published + property itemlist: ttreeitemeditlist read getitemlist + write setitemlist stored false; + property fieldedit: trecordfieldedit read ffieldedit write setfieldedit; + property options: treeitemeditoptionsty read foptions + write foptions default []; +{$ifdef mse_with_ifi} + property ifiitemlink: tifitreeitemlinkcomp read getifiitemlink + write setifiitemlink; +{$endif} + property oncheckrowmove: checkmoveeventty read foncheckrowmove + write foncheckrowmove; + end; + +implementation +uses + sysutils,msebits,msekeyboard,msearrayutils,msevaluenodes; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tdatalist1 = class(tdatalist); + tcustomgrid1 = class(tcustomgrid); + twidgetgrid1 = class(twidgetgrid); + ttreelistitem1 = class(ttreelistitem); + tlistitem1 = class(tlistitem); + tdatacol1 = class(tdatacol); + tframe1 = class(tcustomframe); + twidgetcol1 = class(twidgetcol); + tdatacols1 = class(tdatacols); + twidget1 = class(twidget); + +{ titemviewlist } + +constructor titemviewlist.create(const alistview: tcustomlistview); +begin + flistview:= alistview; + with flayoutinfo do begin + widget:= alistview; + boxids:= defaultboxids; + end; + inherited create(iitemlist(self)); +end; + +function titemviewlist.getlayoutinfo( + const acellinfo: pcellinfoty): plistitemlayoutinfoty; +begin + if acellinfo <> nil then begin + flayoutinfo.variable.glyphversion:= 0; + if cds_usecoloractive in acellinfo^.drawstate then begin + flayoutinfo.variable.colorglyph:= flistview.colorglyph; + if flistview.glyphversionactive < stockobjects.glyphs.versioncount then begin + flayoutinfo.variable.glyphversion:= flistview.glyphversionactive; + end; + end + else begin + flayoutinfo.variable.colorglyph:= flistview.colorglyphactive; + end; + end; + result:= @flayoutinfo; +end; + +procedure titemviewlist.itemcountchanged; +begin + flistview.layoutchanged; +end; + +procedure titemviewlist.doitemchange(const index: integer); +begin + inherited; + flistview.doitemchange(index); +end; + +procedure titemviewlist.invalidate; +begin + flistview.invalidate; +end; + +procedure titemviewlist.updatelayout; +begin + with flistview do begin + if fcellframe = nil then begin + tlistitem.calcitemlayout(makesize(cellwidth,cellheight),minimalframe, + self,flayoutinfo); + end + else begin +{$warnings off} + tlistitem.calcitemlayout(subsize(makesize(cellwidth,cellheight), + fcellframe.paintframedim), + tframe1(fcellframe).fi.innerframe,self,flayoutinfo); +{$warnings on} + end; + layoutchanged; + end; +// invalidate; +end; +{ +function titemviewlist.getcolorglyph: colorty; +begin + result:= flistview.fcolorglyph; +end; +} +procedure titemviewlist.updateitemvalues(const index: integer; + const acount: integer); +begin + //dummy +end; + +function titemviewlist.getcomponentstate: tcomponentstate; +begin + result:= flistview.componentstate; +end; + +function titemviewlist.getoncreateitem: createlistitemeventty; +begin + result:= createlistitemeventty(oncreateobject); +end; + +procedure titemviewlist.setoncreateitem(const value: createlistitemeventty); +begin + oncreateobject:= createobjecteventty(value); +end; + +function titemviewlist.getgrid: tcustomgrid; +begin + result:= flistview; +end; + +{ tlistcol } + +constructor tlistcol.create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); +begin + inherited; + fwidth:= tcustomlistview(fcellinfo.grid).cellwidth; + foptions:= (foptions - [co_savestate]) + [co_mousescrollrow]; +end; + +procedure tlistcol.setwidth(const Value: integer); +var + int1: integer; +begin + int1:= value; + tcustomlistview(fcellinfo.grid).limitcellwidth(int1); + inherited setwidth(int1); + tcustomlistview(fcellinfo.grid).cellwidth:= fwidth; +end; + +procedure tlistcol.setoptions(const Value: coloptionsty); +begin + inherited setoptions(value - [co_savevalue]); +end; + +procedure tlistcol.drawcell(const acanvas: tcanvas); +var + item1: tlistitem; +begin + inherited; + with cellinfoty(acanvas.drawinfopo^) do begin + item1:= items[cell.row]; + if item1 <> nil then begin + item1.drawcell(acanvas); + with tcustomlistview(grid),fitemlist do begin + if assigned(fonpaintitem) then begin + fonpaintitem(fitemlist,acanvas,tlistedititem(pointer(item1))); + end; + end; + end; + end; +end; + +function tlistcol.getitems(const aindex: integer): tlistitem; +var + int1: integer; +begin + int1:= tcustomlistview(fcellinfo.grid).celltoindex( + makegridcoord(colindex,aindex),false); + if int1 >= 0 then begin + result:= tcustomlistview(fcellinfo.grid).fitemlist[int1]; + end + else begin + result:= nil; + end; +end; + +procedure tlistcol.setitems(const aindex: integer; const Value: tlistitem); +var + int1: integer; +begin + int1:= tcustomlistview(fcellinfo.grid).celltoindex( + makegridcoord(colindex,aindex),false); + if int1 >= 0 then begin + tcustomlistview(fcellinfo.grid).fitemlist[int1]:= value; + end; +end; + +procedure tlistcol.updatecellzone(const row: integer; const pos: pointty; + var result: cellzonety); +begin + if pointinrect(pos,tcustomlistview( + fcellinfo.grid).fitemlist.flayoutinfo.captionrect) then begin + result:= cz_caption; + end + else begin + if pointinrect(pos, + tcustomlistview(fcellinfo.grid).fitemlist.flayoutinfo.imagerect) then begin + result:= cz_image; + end + else begin + inherited; + end; + end; +end; + +function tlistcol.getselected(const row: integer): boolean; +var + int1: integer; +begin + int1:= tcustomlistview(fcellinfo.grid).celltoindex(makegridcoord(colindex,row), + false); + if int1 >= 0 then begin + result:= tcustomlistview(fcellinfo.grid).fitemlist[int1].selected; + end + else begin + result:= false; + end; +end; + +procedure tlistcol.setselected(const row: integer; value: boolean); + + procedure updateselected(const index: integer); + var + item: tlistitem; + begin + item:= items[index]; + if (item <> nil) and (item.selected <> value) then begin + include(tcustomgrid1(fcellinfo.grid).fstate,gs_selectionchanged); + item.selected:= value; + end; + end; + +var + int1: integer; +begin + if row < 0 then begin + for int1:= 0 to fcellinfo.grid.rowcount-1 do begin + updateselected(int1); + end; + end + else begin + updateselected(row); + end; + inherited; +end; + +procedure tlistcol.docellevent(var info: celleventinfoty); +var + hintinfo: hintinfoty; + item1: tlistitem; +begin + with tcustomlistview(fcellinfo.grid) do begin + if (lvo_hintclippedtext in foptions) and + (info.eventkind = cek_firstmousepark) and application.active and + getshowhint and (info.cell.row >= 0) then begin + item1:= self[info.cell.row]; + if item1 <> nil then begin + with item1 do begin + if captionclipped then begin + application.inithintinfo(hintinfo,fcellinfo.grid); + hintinfo.caption:= caption; + application.showhint(fcellinfo.grid,hintinfo); + end; + end; + end; + end; + end; + inherited; +end; + +{ tlistcols} + +constructor tlistcols.create(aowner: tcustomlistview); +begin + inherited create(aowner,tlistcol); +end; + +procedure tlistcols.gridrecttoindex(const rect: gridrectty; out start,stop: integer); +begin + if (rect.rowcount <= 0) or (rect.colcount <= 0) then begin + start:= -1; + stop:= -2; + end + else begin + with tcustomlistview(fgrid),rect do begin + start:= celltoindex(pos,true); + stop:= celltoindex(makegridcoord(col+colcount-1,row+rowcount-1),true); + if stop < 0 then begin + stop:= fitemlist.count-1; + if start < 0 then begin + stop:= start - 1; + end; + end; + end; + end; +end; + +procedure tlistcols.dostatread(const reader: tstatreader; + const aorder: boolean); +begin + inherited; + with tcustomlistview(fgrid) do begin + if (lvo_savevalue in foptions) and reader.candata then begin + reader.readdatalist('values',fitemlist); + end; + end; +end; + +procedure tlistcols.dostatwrite(const writer: tstatwriter; + const aorder: boolean); +begin + inherited; + with tcustomlistview(fgrid) do begin + if (lvo_savevalue in foptions) and writer.candata then begin + writer.writedatalist('values',fitemlist); + end; + end; +end; + +procedure tlistcols.setselectedrange(const start,stop: gridcoordty; + const value: boolean; + const calldoselectcell: boolean = false; + const checkmultiselect: boolean = false); +var + int1,int2,int3: integer; + sto1: gridcoordty; +begin + sto1:= stop; + if sto1.col < start.col then begin + inc(sto1.col); + end + else begin + if sto1.col = start.col then begin + exit; + end; + dec(sto1.col); + end; + if sto1.row < start.row then begin + inc(sto1.row); + end + else begin + if sto1.row = start.row then begin + exit; + end; + dec(sto1.row); + end; + + if value and checkmultiselect and + not (lvo_multiselect in tcustomlistview(fgrid).foptions) then begin + with tcustomlistview(fgrid) do begin + if calldoselectcell then begin + selectcell(invalidcell,csm_deselect); + selectcell(sto1,csm_select); + end + else begin + selected[invalidcell]:= false; + selected[sto1]:= true; + end; + end; + exit; + end; + + with tcustomlistview(fgrid) do begin + int1:= celltoindex(start,true); + int2:= celltoindex(sto1,true); + if int1 > int2 then begin //swap values + int3:= int1; + int1:= int2; + int2:= int3; + end; + if calldoselectcell and value then begin + for int1:= int1 to int2 do begin + selectcell(indextocell(int1),csm_select); + end; + end + else begin + for int1:= int1 to int2 do begin + selected[indextocell(int1)]:= value; + end; + end; + end; +end; + +procedure tlistcols.changeselectedrange(const start,oldend,newend: gridcoordty; + calldoselectcell: boolean); + + procedure select(start,stop: integer; value: boolean); + var + int1: integer; + mo1: cellselectmodety; + begin + with tcustomlistview(fgrid) do begin + if calldoselectcell then begin + if value then begin + mo1:= csm_select; + end + else begin + mo1:= csm_deselect; + end; + for int1:= start to stop do begin + selectcell(indextocell(int1),mo1{value,false}); + end; + end + else begin + for int1:= start to stop do begin + selected[indextocell(int1)]:= value; + end; + end; + end; + end; + +var + int1,int2,int3,int4,int5: integer; + +begin + with tcustomlistview(fgrid) do begin + if not (lvo_multiselect in options) then begin + if calldoselectcell then begin + selectcell(invalidcell,csm_deselect); + selectcell(newend,csm_select); + end + else begin + selected[invalidcell]:= false; + selected[newend]:= true; + end; + exit; + end; + int1:= celltoindex(start,true); + int2:= celltoindex(oldend,true); + int4:= celltoindex(newend,true); + int3:= int1; + if int2 < int1 then begin + int1:= int2; + int2:= int3; + end; + if int4 < int3 then begin + int5:= int4; + int4:= int3; + int3:= int5; + end; + end; + if (oldend.col >= 0) and (oldend.row >= 0) then begin + if (int1 > int4) or (int3 > int2) then begin + select(int1,int2,false); + select(int3,int4,true); + end + else begin + if int1 < int3 then begin + select(int1,int3-1,false) + end + else begin + if int1 > int3 then begin + select(int3,int1-1,true); + end; + end; + if int4 < int2 then begin + select(int4+1,int2,false) + end + else begin + if int4 > int2 then begin + select(int2+1,int4,true); + end; + end; + end; + end; +end; + +{ tlistitemdragobject } + +constructor tlistitemdragobject.create(const asender: tobject; + var instance: tdragobject; const apickpos: pointty; const aitem: tlistitem); +begin + inherited create(asender,instance,apickpos,aitem); +end; + +function tlistitemdragobject.item: tlistitem; +begin + result:= tlistitem(fdata); +end; + +{ tlistitemsdragobject } + +constructor tlistitemsdragobject.create(const asender: tobject; + var instance: tdragobject; const apickpos: pointty; + const aitems: array of tlistitem); +var + i1: int32; +begin + setlength(fitems,length(aitems)); + for i1:= 0 to high(fitems) do begin + fitems[i1]:= aitems[i1]; + end; + inherited create(asender,instance,apickpos); +end; + +{ tcustomlistview } + +constructor tcustomlistview.create(aowner: tcomponent); +begin + foptions:= defaultlistviewoptions; + fcolorglyph:= cl_glyph; + fcolorglyphactive:= cl_glyphactive; + fcellcursor:= cr_default; + if fitemlist = nil then begin + fitemlist:= titemviewlist.create(self); + end; + inherited; + fstate:= fstate + [gs_islist]; + fcellwidthmin:= defaultcellwidthmin; + cellwidth:= defaultcellwidth; + cellheight:= defaultcellheight; + optionsgrid:= defaultlistviewoptionsgrid; + feditor:= tinplaceedit.create(self,iedit(self)); +end; + +destructor tcustomlistview.destroy; +begin + inherited; + feditor.Free; + fitemlist.Free; + fcellframe.free; +end; + +function tcustomlistview.createdatacols: tdatacols; +begin + result:= tlistcols.create(self); +end; + +procedure tcustomlistview.createdatacol(const index: integer; + out item: tdatacol); +begin + item:= tlistcol.create(self,fdatacols); + initdatacol(item); +end; + +procedure tcustomlistview.initdatacol(const item: tdatacol); +var + opt1: coloptionsty; +begin +// item.options:= coloptionsty( +// replacebits( +// {$ifdef FPC}longword{$else}word{$endif}(foptionslist) shl listviewoptionshift, +// {$ifdef FPC}longword{$else}longword{$endif}(item.options), +// {$ifdef FPC}longword{$else}longword{$endif}(bitmask[integer(lvo_coloptions)+1]) +// shl listviewoptionshift)); + opt1:= coloptionsty( + replacebits( + {$ifdef FPC}longword{$else}longword{$endif}(foptions), + {$ifdef FPC}longword{$else}longword{$endif}(item.options), + {$ifdef FPC}longword{$else}longword{$endif}(coloptionsmask))); +// updatebit(longword(opt1),ord(co_savestate),lvo_savestate in foptions); + item.options:= opt1; + if fcellframe <> nil then begin + item.frame:= fcellframe; + end; +// tdatacol1(item).fcolorselect:= fcolorselect; +end; + +procedure tcustomlistview.updatecoloptions; +var + int1: integer; +begin + if not (csloading in componentstate) then begin + for int1:= 0 to fdatacols.count - 1 do begin + initdatacol(fdatacols[int1]); + end; + invalidate; + end; +end; + +procedure tcustomlistview.setframeinstance(instance: tcustomframe); +begin + if instance is tcellframe then begin + fcellframe:= tcellframe(instance); + end + else begin + inherited; + end; +end; + +procedure tcustomlistview.createcellframe; +begin + tcellframe.create(iscrollframe(self)); +end; + +function tcustomlistview.getcellframe: tcellframe; +begin + getoptionalobject(fcellframe,{$ifdef FPC}@{$endif}createcellframe); + result:= fcellframe; +end; + +procedure tcustomlistview.setcellframe(const avalue: tcellframe); +begin + setoptionalobject(avalue,fcellframe,{$ifdef FPC}@{$endif}createcellframe); +end; + +function tcustomlistview.getitems(const index: integer): tlistitem; +var + cell: gridcoordty; +begin + cell:= indextocell(index); + result:= tlistcol(fdatacols[cell.col])[cell.row]; +end; + +procedure tcustomlistview.setitems(const index: integer; const Value: tlistitem); +var + cell: gridcoordty; +begin + cell:= indextocell(index); + tlistcol(fdatacols[cell.col])[cell.row]:= value; +end; + +function tcustomlistview.celltoindex(const cell: gridcoordty; limit: boolean): integer; +begin + if (cell.row < 0) or (cell.col < 0) then begin + result:= -1; + end + else begin + internalupdatelayout; + if lvo_horz in foptions then begin + result:= cell.row*fdatacols.count + cell.col; + end + else begin + result:= cell.col*frowcount + cell.row; + end; + if result >= fitemlist.count then begin + if limit then begin + result:= fitemlist.count - 1; + end + else begin + result:= -1; + end; + end; + end; +end; + +function tcustomlistview.indextocell(const index: integer): gridcoordty; +begin + internalupdatelayout; + if (frowcount > 0) and (fdatacols.count > 0) then begin + if lvo_horz in foptions then begin + result.row:= index div fdatacols.count; + result.col:= index mod fdatacols.count; + end + else begin + result.col:= index div frowcount; + result.row:= index mod frowcount; + end; + end + else begin + result:= invalidcell; + end; +end; + +function tcustomlistview.itematpos(const apos: pointty): tlistitem; +var + int1: integer; +begin + int1:= celltoindex(cellatpos(apos),false); + if int1 >= 0 then begin + result:= fitemlist[int1]; + end + else begin + result:= nil; + end; +end; + +function tcustomlistview.celltoitem(const acell: gridcoordty): tlistitem; +var + int1: integer; +begin + int1:= celltoindex(acell,false); + if int1 >= 0 then begin + result:= fitemlist[int1]; + end + else begin + result:= nil; + end; +end; + +function tcustomlistview.focuseditem: tlistitem; +begin + result:= celltoitem(ffocusedcell); +end; + +function tcustomlistview.getfocusedindex: integer; +begin + result:= celltoindex(ffocusedcell,true); +end; + +procedure tcustomlistview.setfocusedindex(const avalue: integer); +begin + if (avalue < 0) or (avalue >= fitemlist.count) then begin + focuscell(invalidcell); + end + else begin + focuscell(indextocell(avalue)); + end; +end; + +function tcustomlistview.finditembycaption(const acaption: msestring): tlistitem; +var + int1: integer; + locopt: locatestringoptionsty; +begin + int1:= -1; + if lvo_casesensitive in foptions then begin + locopt:= [lso_exact,lso_casesensitive]; + end + else begin + locopt:= [lso_exact]; + end; + if locatestring(acaption,{$ifdef FPC}@{$endif}getkeystring,locopt, + fitemlist.count,int1) then begin + result:= fitemlist[int1]; + end + else begin + result:= nil; + end; +end; + +function tcustomlistview.findcellbycaption(const acaption: msestring; var cell: gridcoordty): boolean; +var + item1: tlistitem; +begin + item1:= finditembycaption(acaption); + if item1 <> nil then begin + result:= true; + cell:= indextocell(item1.index); + end + else begin + result:= false; + end; +end; + +procedure tcustomlistview.limitcellwidth(var avalue: integer); +begin + if (avalue <> 0) and (fcellwidthmin > avalue) then begin + avalue:= fcellwidthmin; + end; + if (fcellwidthmax <> 0) and (fcellwidthmax < avalue) then begin + avalue:= fcellwidthmax; + end; +end; + +procedure tcustomlistview.updatelayout; +var + int1,int2: integer; + bo1: boolean; + indexbefore: integer; + cell1: gridcoordty; + width1,height1: integer; +begin + indexbefore:= celltoindex(ffocusedcell,true); +// fitemlist.updatelayout; + width1:= fcellwidth; + height1:= datarowheight; + if lvo_fill in foptions then begin + inherited; + if lvo_horz in foptions then begin + width1:= fdatarect.cx - datacollinewidth; + end + else begin + height1:= fdatarect.cy - datarowlinewidth; + end; + end; + limitcellwidth(width1); + datarowheight:= height1; + for int1:= 0 to fdatacols.count-1 do begin + fdatacols[int1].width:= width1; + fdatacols[int1].cursor:= fcellcursor; + end; + fitemlist.updatelayout; + repeat + inherited; + bo1:= false; + if lvo_horz in foptions then begin + int1:= tlistcol.defaultstep(width1); + if int1 = 0 then begin + int1:= 1; + end; + int2:= fdatarect.cx div int1; + if int2 = 0 then begin + int2:= 1; + end; + if fdatacols.count <> int2 then begin + fdatacols.count:= int2; + bo1:= true; + end; + int1:= (fitemlist.count + int2 - 1) div int2; + if int1 <> frowcount then begin + rowcount:= int1; + bo1:= true; + end; + end + else begin + int1:= ystep; + if int1 = 0 then begin + int1:= 1; + end; + int2:= fdatarect.cy div int1; + if int2 = 0 then begin + int2:= 1; + end; + if rowcount <> int2 then begin + rowcount:= int2; + bo1:= true; + end; + int1:= (fitemlist.count + int2 - 1) div int2; + if int1 <> fdatacols.count then begin + fdatacols.count:= int1; + bo1:= true; + end; + end; + until not bo1; + if (indexbefore >= 0) then begin + cell1:= indextocell(indexbefore); + if (cell1.col <> ffocusedcell.col) or (cell1.row <> ffocusedcell.row) then begin + focuscell(cell1); + end; + setupeditor(ffocusedcell{,true}); + end; +end; + +procedure tcustomlistview.setitemlist(value: titemviewlist); +begin + fitemlist.Assign(value); +end; + +procedure tcustomlistview.setcellwidthmax(const Value: integer); +begin + if fcellwidthmax <> value then begin + fcellwidthmax:= Value; + layoutchanged; + end; +end; + +procedure tcustomlistview.setcellwidthmin(Value: integer); +begin + if value < 1 then begin + value:= 1; + end; + if fcellwidthmin <> value then begin + fcellwidthmin := Value; + layoutchanged; + end; +end; + +procedure tcustomlistview.drawfocusedcell(const acanvas: tcanvas); +var + pt1: pointty; + item1: tlistitem1; +begin + if cellinfoty(acanvas.drawinfopo^).calcautocellsize then begin + if focuseditem <> nil then begin + focuseditem.drawcell(acanvas); + end; + end + else begin + acanvas.save; + drawcellbackground(acanvas); + item1:= tlistitem1(focuseditem); + if item1 <> nil then begin + fitemlist.flayoutinfo.variable.calcautocellsize:= false; + item1.drawimage(acanvas,fitemlist.flayoutinfo); + if assigned(fitemlist.fonpaintitem) then begin + fitemlist.fonpaintitem(fitemlist,acanvas,tlistedititem(pointer(item1))); + end; + pt1:= cellrect(ffocusedcell,cil_paint).pos; + acanvas.remove(pt1); + feditor.dopaint(acanvas); + acanvas.move(pt1); + if feditor.lasttextclipped then begin + include(item1.fstate1,ns1_captionclipped); + end + else begin + exclude(item1.fstate1,ns1_captionclipped); + end; + end; + acanvas.restore; + drawcelloverlay(acanvas); + end; +end; + +procedure tcustomlistview.setoptions(const avalue: listviewoptionsty); +const + mask: listviewoptionsty = [lvo_horz,lvo_fill]; +var + optbefore: listviewoptionsty; +begin + if foptions <> avalue then begin + optbefore:= foptions; + foptions:= avalue; + updatecoloptions; + if (longword(foptions) xor longword(optbefore)) and + longword(mask) <> 0 then begin + layoutchanged; + end; + end; +end; + +function tcustomlistview.getcellfocusrectdist: integer; +begin + result:= fdatacols.focusrectdist; +end; + +procedure tcustomlistview.setcellfocusrectdist(const avalue: integer); +begin + fdatacols.focusrectdist:= avalue; +end; + +procedure tcustomlistview.loaded; +begin + inherited; + updatecoloptions; +end; + +function tcustomlistview.locatecount: integer; //number of locate values +begin + result:= fitemlist.count; +end; + +function tcustomlistview.locatecurrentindex: integer; //index of current row +begin + result:= celltoindex(ffocusedcell,false); +end; + +procedure tcustomlistview.locatesetcurrentindex(const aindex: integer); +begin + focuscell(indextocell(aindex)); +end; + +function tcustomlistview.getedited: boolean; +begin + result:= false; +end; + +function tcustomlistview.getkeystring(const index: integer): msestring; +begin + result:= fitemlist[index].caption; +end; + +procedure tcustomlistview.setediting(const Value: boolean); +var + item1: tlistitem; +begin + if fediting <> value then begin + if not (value and (lvo_readonly in foptions)) then begin + fediting := Value; + invalidatefocusedcell; + if not value then begin + if feditor.canundo then begin + item1:= focuseditem; + if item1 <> nil then begin + item1.caption:= feditor.text; + end; + end; + feditor.dodefocus; + end + else begin + feditor.dofocus; + end; + feditor.updatecaret; + end; + end; +end; + +procedure tcustomlistview.setupeditor(const newcell: gridcoordty{; + posonly: boolean}); +var + pt1: pointty; +// rect1,rect2: rectty; + int1: integer; +begin +// rect1:= moverect(fitemlist.flayoutinfo.captionrect,po1); +// rect2:= moverect(fitemlist.flayoutinfo.captioninnerrect,po1); + int1:= celltoindex(newcell,false); + if int1 >= 0 then begin +// if posonly then begin +// feditor.updatepos(rect2,rect1); +// end +// else begin +// feditor.setup(fitemlist[int1].caption,0,false,rect2,rect1,nil,nil,getfont); + + pt1:= cellrect(newcell,cil_paint).pos; + with fitemlist[int1] do begin +// if not posonly then begin + feditor.textflags:= fitemlist.flayoutinfo.textflags + [tf_clipo]; + feditor.textflagsactive:= feditor.textflags; + feditor.text:= caption; +// end; + setupeditor(feditor,getfont,true); + feditor.movepos(pt1); + end; + +// end; + end; +end; + +procedure tcustomlistview.docellevent(var info: celleventinfoty); +var + int1: integer; + +begin + if not (gs_layoutupdating in fstate) then begin + with info do begin + case eventkind of + cek_enter: begin + int1:= celltoindex(newcell,false); + if int1 < 0 then begin + focuscell(indextocell(fitemlist.count - 1),info.selectaction); + exit; + end; + setupeditor(newcell{,false}); + end; + cek_exit: begin + editing:= false; +// filtertext:= ''; + end; + cek_select: begin + if selected and (celltoindex(cell,false) < 0) then begin + accept:= false; + end; + end; + end; + end; + inherited; + int1:= celltoindex(info.cell,false); + if int1 >= 0 then begin + doitemevent(int1,info); + end; + end + else begin + inherited; + end; +end; + +procedure tcustomlistview.doitemevent(const index: integer; var info: celleventinfoty); +var + po1: pointty; +begin + with info do begin + if eventkind in mousecellevents then begin + fitemlist[index].mouseevent(mouseeventinfopo^); + if not (es_processed in mouseeventinfopo^.eventstate) then begin + po1:= mouseeventinfopo^.pos; + mouseeventinfopo^.pos:= gridmousepos; + if editing or (eventkind = cek_buttonrelease) or + (info.mouseeventinfopo^.shiftstate * keyshiftstatesmask = []) then begin + feditor.mouseevent(mouseeventinfopo^); + end; + if isdblclick(mouseeventinfopo^) then begin + editing:= true; + end; + mouseeventinfopo^.pos:= po1; + end; + end; + end; + if canevent(tmethod(fonitemevent)) then begin + fonitemevent(self,index,info); + end; +end; + +procedure tcustomlistview.setcellwidth(const Value: integer); +begin + if fcellwidth <> value then begin + fcellwidth:= Value; + layoutchanged; + end; +end; + +function tcustomlistview.getcellheight: integer; +begin + result:= datarowheight; +end; + +procedure tcustomlistview.setcellheight(const avalue: integer); +begin + datarowheight:= avalue; +{ + if fcellheight <> avalue then begin + fcellheight:= avalue; + layoutchanged; + end; +} +end; + +procedure tcustomlistview.rootchanged(const aflags: rootchangeflagsty); +begin + inherited; + feditor.poschanged; +end; + +procedure tcustomlistview.doitemchange(index: integer); + + procedure itemstatetocellstate(const itemindex: integer; const cell: gridcoordty); + begin + with fitemlist[itemindex] do begin + fdatacols.selected[cell]:= selected; + if (cell.row = ffocusedcell.row) and (cell.col = ffocusedcell.col) then begin + feditor.text:= caption; + end; + end; + end; + +var + cell: gridcoordty; + int1: integer; +begin + if index < 0 then begin + layoutchanged; + updatelayout; + beginupdate; + try + for int1:= fitemlist.count to rowcount * datacols.count - 1 do begin + fdatacols.selected[indextocell(int1)]:= false; //empty cells + end; + if focusedcellvalid() then begin + int1:= celltoindex(ffocusedcell,false); + if int1 >= 0 then begin + if (lvo_focusselect in foptions) then begin + itemlist[int1].selected:= true; + end; + itemstatetocellstate(int1,ffocusedcell); + end; + end; + finally + endupdate; + end; + end + else begin + cell:= indextocell(index); + invalidatecell(cell); + itemstatetocellstate(index,cell); + end; +end; + +function tcustomlistview.getcolorselect: colorty; +begin + result:= fdatacols.colorselect; +end; + +procedure tcustomlistview.setcolorselect(const Value: colorty); +begin + fdatacols.colorselect:= value; +end; + +procedure tcustomlistview.setcolorglyph(const Value: colorty); +begin + if fcolorglyph <> value then begin + fcolorglyph:= Value; + invalidate; + end; +end; + +procedure tcustomlistview.setcolorglyphactive(const Value: colorty); +begin + if fcolorglyphactive <> value then begin + fcolorglyphactive:= Value; + invalidate; + end; +end; + +procedure tcustomlistview.moveitem(const source,dest: tlistitem; focus: boolean); +var + int1: integer; +begin + int1:= source.index; + fitemlist.movedata(int1,dest.index); + if focus then begin + focuscell(indextocell(source.index)); + end; + if canevent(tmethod(fonitemsmoved)) then begin + fonitemsmoved(self,int1,source.index,1); + end; +end; + +procedure tcustomlistview.scrolled(const dist: pointty); +begin + inherited; + if focusedcellvalid then begin + feditor.scroll(dist); + end; +end; + +procedure tcustomlistview.dostatread(const reader: tstatreader); +begin + if lvo_savestate in foptions then begin + cellwidth:= reader.readinteger('cellwidth',cellwidth); + end; + inherited; +end; + +procedure tcustomlistview.dostatwrite(const writer: tstatwriter); +begin + if (lvo_savestate in foptions) and writer.canstate then begin + writer.writeinteger('cellwidth',cellwidth); + end; + inherited; +end; + +function tcustomlistview.getoptionsedit: optionseditty; +begin + result:= [oe_autoselect,oe_resetselectonexit,oe_exitoncursor]; + if lvo_locate in foptions then begin + include(result,oe_locate); + end; + if lvo_casesensitive in foptions then begin + include(result,oe_casesensitive); + end; + if not fediting then begin + include(result,oe_readonly); + end; +end; + +procedure tcustomlistview.editnotification(var info: editnotificationinfoty); +begin + //dummy +end; + +procedure tcustomlistview.synctofontheight; +var + int1: integer; +begin + inherited; + if cellframe = nil then begin + int1:= font.glyphheight + 2; + end + else begin + int1:= font.glyphheight + cellframe.innerframedim.cy; + end; + if (itemlist.imagelist <> nil) then begin + if itemlist.captionpos in [cp_left,cp_center,cp_right] then begin + if itemlist.imagelist.size.cy > int1 then begin + int1:= itemlist.imagelist.size.cy; + end; + end + else begin + int1:= int1 + itemlist.imagelist.size.cy; + end; + end; + cellheight:= int1; +end; + +function tcustomlistview.internaldragevent(var info: draginfoty): boolean; +var + item: tlistitem; +begin + if lvo_mousemoving in foptions then begin + result:= true; + with info do begin + item:= itematpos(pos); + if item <> nil then begin + case eventkind of + dek_begin: begin + tlistitemdragobject.create(self,dragobjectpo^,fdragcontroller.pickpos,item); + end; + dek_check: begin + accept:= (item <> focuseditem) and (info.dragobjectpo <> nil) and + isobjectdrag(info.dragobjectpo^,tlistitem) and + (tlistitem(tobjectdragobject(info.dragobjectpo^).data).owner = + fitemlist); + end; + dek_drop: begin + moveitem(tlistitemdragobject(dragobjectpo^).item,item,true); + end; + end; + end; + end; + end + else begin + result:= inherited internaldragevent(info); + end; +end; +(* +procedure tcustomlistview.setfiltertext(const value: msestring); +var + int1: integer; +begin + if value = '' then begin + ffiltertext:= ''; + end + else begin + int1:= celltoindex(ffocusedcell,false); + fitemlist.datapo; //normalize ring + if locatestring(value,{$ifdef FPC}@{$endif}getkeystring,[],fitemlist.count,int1) then begin + focuscell(indextocell(int1)); + ffiltertext:= value; + end; + end; + if not editing then begin + feditor.selstart:= 0; + feditor.sellength:= length(ffiltertext); + end; +end; +*) +procedure tcustomlistview.dokeydown(var info: keyeventinfoty); +var + item: tlistitem; + int1: integer; +// str1: msestring; + action1: focuscellactionty; +begin + with info do begin + feditor.dokeydown(info); +// if fediting then begin +// if ((key = key_left) or (key = key_right)) and (shiftstate - [ss_shift] = []) then begin +// include(eventstate,es_processed); +// end; +// end +// else begin + { + if (key = key_backspace) and (shiftstate = []) then begin + filtertext:= copy(ffiltertext,1,length(ffiltertext)-1); + end + else begin + if (key = key_home) and (shiftstate = []) then begin + filtertext:= ''; + end + else begin + str1:= mseextractprintchars(info.chars); + if (str1 <> '') and (shiftstate - [ss_shift] = []) then begin + filtertext:= ffiltertext + str1; + include(eventstate,es_processed); + end; + end; + end; + } +// end; + if not (es_processed in eventstate) then begin + if (lvo_keymoving in foptions) and (shiftstate = [ss_ctrl]) + and (focuseditem <> nil) then begin + item:= nil; + case info.key of + key_up: begin + if ffocusedcell.row > 0 then begin + item:= celltoitem(makegridcoord(ffocusedcell.col,ffocusedcell.row - 1)); + end; + end; + key_down: begin + if ffocusedcell.row < frowcount - 1 then begin + item:= celltoitem(makegridcoord(ffocusedcell.col,ffocusedcell.row + 1)); + end; + end; + key_left: begin + if ffocusedcell.col > 0 then begin + item:= celltoitem(makegridcoord(ffocusedcell.col - 1,ffocusedcell.row)); + end; + end; + key_right: begin + if ffocusedcell.col < fdatacols.count - 1 then begin + item:= celltoitem(makegridcoord(ffocusedcell.col + 1,ffocusedcell.row)); + end; + end; + end; + if item <> nil then begin + moveitem(focuseditem,item,true); + include(eventstate,es_processed); + end; + end; + if not (es_processed in info.eventstate) then begin + if (shiftstate = []) and isenterkey(nil,key) then begin + if not editing then begin + editing:= (focuseditem <> nil) and tlistitem1(focuseditem).cancaptionedit(); + if editing then begin + include(eventstate,es_processed); + end; + end + else begin + editing:= false; + include(eventstate,es_processed); + end; + end + else begin + if not editing and (ss_ctrl in shiftstate) and (shiftstate - [ss_ctrl,ss_shift] = []) and + ((key = key_home) or (key = key_end)) and (fitemlist.count > 0) then begin + include(eventstate,es_processed); + if ss_shift in shiftstate then begin + if lvo_keyselect in foptions then begin + action1:= fca_selectend; + end + else begin + action1:= fca_focusinshift; + end; + end + else begin + action1:= fca_focusin; + end; + if key = key_home then begin + focuscell(indextocell(0),action1); + end + else begin + focuscell(indextocell(fitemlist.count - 1),action1); + end; + end; + if not (es_processed in eventstate) and (shiftstate - [ss_shift] = []) and + (og_colchangeontabkey in foptionsgrid) and + (fitemlist.count > 0) then begin + int1:= celltoindex(ffocusedcell,true); + case key of + key_tab: begin + inc(int1); + if int1 = fitemlist.count then begin + int1:= 0; + end; + end; + key_backtab: begin + dec(int1); + if int1 < 0 then begin + int1:= fitemlist.count - 1; + end; + end; + else begin + int1:= -1; + end; + end; + if int1 >= 0 then begin + include(eventstate,es_processed); + focuscell(indextocell(int1)); + end; + end; + end; + if not (es_processed in eventstate) then begin + inherited; + end; + end; + end; + end; +end; + +function tcustomlistview.getdatacollinecolor: colorty; +begin + result:= fdatacols.linecolor; +end; + +procedure tcustomlistview.setdatacollinecolor(const Value: colorty); +begin + fdatacols.linecolor:= value; +end; + +function tcustomlistview.getdatacollinewidth: integer; +begin + result:= fdatacols.linewidth; +end; + +procedure tcustomlistview.setdatacollinewidth(const Value: integer); +begin + fdatacols.linewidth:= value; +end; + +procedure tcustomlistview.setcellcursor(const avalue: cursorshapety); +var + int1: integer; +begin + if avalue <> fcellcursor then begin + fcellcursor:= avalue; + with tdatacols1(fdatacols) do begin + cursor:= avalue; + for int1:= 0 to count-1 do begin + tdatacol(fitems[int1]).cursor:= avalue; + end; + end; + end; +end; + +function tcustomlistview.getcellsize: sizety; +begin + result:= ms(cellwidth,cellheight); +end; + +procedure tcustomlistview.setcellsize(const avalue: sizety); +begin + cellwidth:= avalue.cx; + cellheight:= avalue.cy; +end; + +procedure tcustomlistview.setglyphversionactive(const avalue: int32); +begin + if fglyphversionactive <> avalue then begin + fglyphversionactive:= avalue; + if fglyphversionactive < 0 then begin + fglyphversionactive:= 0; + end; + end; +end; + +class function tcustomlistview.classskininfo: skininfoty; +begin + result:= inherited classskininfo; + result.objectkind:= sok_dataedit; +end; + +function tcustomlistview.getonselectionchanged: listvieweventty; +begin + result:= listvieweventty(inherited onselectionchanged); +end; + +procedure tcustomlistview.setonselectionchanged(const avalue: listvieweventty); +begin + inherited onselectionchanged:= notifyeventty(avalue); +end; + +function tcustomlistview.getselecteditems: listitemarty; +begin + if datacols.hasselection then begin + result:= fitemlist.getselecteditems; + end + else begin + result:= nil; + end; +end; + +function tcustomlistview.getselectedindexes: integerarty; +begin + if datacols.hasselection then begin + result:= fitemlist.getselectedindexes(); + end + else begin + result:= nil; + end; +end; + +function tcustomlistview.hasselection: boolean; +begin + result:= false; +end; + +procedure tcustomlistview.updatecopytoclipboard(var atext: msestring); +begin + if canevent(tmethod(foncopytoclipboard)) then begin + foncopytoclipboard(self,atext); + end; +end; + +procedure tcustomlistview.updatepastefromclipboard(var atext: msestring); +begin + if canevent(tmethod(fonpastefromclipboard)) then begin + fonpastefromclipboard(self,atext); + end; +end; + +function tcustomlistview.getonlayoutchanged: listvieweventty; +begin + result:= listvieweventty(inherited onlayoutchanged); +end; + +procedure tcustomlistview.setonlayoutchanged(const avalue: listvieweventty); +begin + inherited onlayoutchanged:= gridnotifyeventty(avalue); +end; + +function tcustomlistview.getonbeforeupdatelayout: listvieweventty; +begin + result:= listvieweventty(inherited onbeforeupdatelayout); +end; + +procedure tcustomlistview.setonbeforeupdatelayout(const avalue: listvieweventty); +begin + inherited onbeforeupdatelayout:= gridnotifyeventty(avalue); +end; + +function tcustomlistview.getcellheightmin: integer; +begin + result:= datarowheightmin; +end; + +procedure tcustomlistview.setcellheightmin(const avalue: integer); +begin + datarowheightmin:= avalue; +end; + +function tcustomlistview.getcellheightmax: integer; +begin + result:= datarowheightmax; +end; + +procedure tcustomlistview.setcellheightmax(const avalue: integer); +begin + datarowheightmax:= avalue; +end; + +{ tcustomitemeditlist } + +constructor tcustomitemeditlist.create; +begin + fcolorglyph:= cl_glyph; + fcolorglyphactive:= cl_glyphactive; + fboxids:= defaultboxids; + inherited; + fitemclass:= defaultitemclass(); + fstate:= fstate + [dls_nogridstreaming,dls_propertystreaming]; +end; + +constructor tcustomitemeditlist.create(const intf: iitemlist; + const owner: tcustomitemedit); +begin + fowner:= owner; + inherited create(intf); +end; + +class function tcustomitemeditlist.defaultitemclass(): listedititemclassty; +begin + result:= tlistedititem; +end; + +procedure tcustomitemeditlist.itemclasschanged(); +begin + fowner.updatelayout(); +end; + +function tcustomitemeditlist.getimagelist: timagelist; +begin + result:= nil; +// result:= fboxglyph_list; +end; + +procedure tcustomitemeditlist.setcolorglyph(const avalue: colorty); +begin + if fcolorglyph <> avalue then begin + fcolorglyph:= avalue; + fowner.itemchanged(-1); + end; +end; + +procedure tcustomitemeditlist.setcolorglyphactive(const avalue: colorty); +begin + if fcolorglyphactive <> avalue then begin + fcolorglyphactive:= avalue; + fowner.itemchanged(-1); + end; +end; + +function tcustomitemeditlist.getboxglyph_checkbox: stockglyphty; +begin + result:= stockglyphty(fboxids[tib_checkbox]); +end; + +procedure tcustomitemeditlist.setboxglyph_checkbox(const avalue: stockglyphty); +begin + if stockglyphty(fboxids[tib_checkbox]) <> avalue then begin + stockglyphty(fboxids[tib_checkbox]):= avalue; + if fowner <> nil then begin + fowner.itemchanged(-1); + end; + end; +end; + +function tcustomitemeditlist.getboxglyph_checkboxchecked: stockglyphty; +begin + result:= stockglyphty(fboxids[tib_checkboxchecked]); +end; + +procedure tcustomitemeditlist.setboxglyph_checkboxchecked( + const avalue: stockglyphty); +begin + if stockglyphty(fboxids[tib_checkboxchecked]) <> avalue then begin + stockglyphty(fboxids[tib_checkboxchecked]):= avalue; + if fowner <> nil then begin + fowner.itemchanged(-1); + end; + end; +end; + +function tcustomitemeditlist.getboxglyph_checkboxparentnotchecked: stockglyphty; +begin + result:= stockglyphty(fboxids[tib_checkboxparentnotchecked]); +end; + +procedure tcustomitemeditlist.setboxglyph_checkboxparentnotchecked( + const avalue: stockglyphty); +begin + if stockglyphty(fboxids[tib_checkboxparentnotchecked]) <> avalue then begin + stockglyphty(fboxids[tib_checkboxparentnotchecked]):= avalue; + if fowner <> nil then begin + fowner.itemchanged(-1); + end; + end; +end; + +function tcustomitemeditlist.getboxglyph_checkboxchildchecked: stockglyphty; +begin + result:= stockglyphty(fboxids[tib_checkboxchildchecked]); +end; + +procedure tcustomitemeditlist.setboxglyph_checkboxchildchecked( + const avalue: stockglyphty); +begin + if stockglyphty(fboxids[tib_checkboxchildchecked]) <> avalue then begin + stockglyphty(fboxids[tib_checkboxchildchecked]):= avalue; + if fowner <> nil then begin + fowner.itemchanged(-1); + end; + end; +end; + +function tcustomitemeditlist.getboxglyph_checkboxchildnotchecked: stockglyphty; +begin + result:= stockglyphty(fboxids[tib_checkboxchildnotchecked]); +end; + +procedure tcustomitemeditlist.setboxglyph_checkboxchildnotchecked( + const avalue: stockglyphty); +begin + if stockglyphty(fboxids[tib_checkboxchildnotchecked]) <> avalue then begin + stockglyphty(fboxids[tib_checkboxchildnotchecked]):= avalue; + if fowner <> nil then begin + fowner.itemchanged(-1); + end; + end; +end; +{ +procedure tcustomitemeditlist.setboxglyp_list(const avalue: timagelist); +begin + setlinkedvar(avalue,tmsecomponent(fboxglyph_list)); +end; + +procedure tcustomitemeditlist.setboxglyp_listactive(const avalue: timagelist); +begin + setlinkedvar(avalue,tmsecomponent(fboxglyph_listactive)); +end; +} +procedure tcustomitemeditlist.setboxglyph_versionactive(const avalue: int32); +begin + if fboxglyph_versionactive <> avalue then begin + fboxglyph_versionactive:= avalue; + if fboxglyph_versionactive < 0 then begin + fboxglyph_versionactive:= 0; + end; + if fowner <> nil then begin + fowner.itemchanged(-1); + end; + end; +end; + +procedure tcustomitemeditlist.assign(const aitems: listitemarty); +var + po1: plistitem; + int1: integer; +begin + beginupdate; + try + exclude(fitemstate,ils_subnodecountupdating); //free nodes + clear; + include(fitemstate,ils_subnodecountupdating); + capacity:= length(aitems); + fcount:= length(aitems); + if fcount > 0 then begin + move(aitems[0],fdatapo^,length(aitems)*fsize); + end; + po1:= plistitem(fdatapo); + for int1:= 0 to fcount - 1 do begin + tlistitem1(po1^).setowner(self); + inc(po1); + end; + fintf.itemcountchanged; + fintf.updateitemvalues(0,fcount); + finally + endupdate; + end; +end; + +procedure tcustomitemeditlist.add(const anode: tlistitem); +var + int1: integer; +begin + checkitemclass(anode); + beginupdate; + try + int1:= internaladddata(anode,false); + tlistitem1(anode).setowner(self); + tlistitem1(anode).findex:= int1; + fintf.itemcountchanged; + fintf.updateitemvalues(int1,1); + finally + endupdate; + end; +// adddata(anode); +end; + +procedure tcustomitemeditlist.insert(const aindex: integer; + const anode: tlistitem); +begin + checkitemclass(anode); + with fintf.getgrid do begin + insertrow(aindex); + end; + tlistitem1(anode).setowner(self); + tlistitem1(anode).findex:= aindex; + items[aindex]:= anode; + fintf.updateitemvalues(aindex,1); +{ + beginupdate; + try + internalinsertdata(aindex,anode,false); + tlistitem1(anode).setowner(self); + tlistitem1(anode).findex:= aindex; + fintf.itemcountchanged; + fintf.updateitemvalues(aindex,1); + finally + endupdate; + end; +} +end; + +procedure tcustomitemeditlist.refreshitemvalues(aindex: integer = 0; + acount: integer = -1); +begin + beginupdate; + try + if aindex < 0 then begin + aindex:= fowner.gridrow; + end; + if (aindex >= 0) and (aindex < fcount) then begin + if acount < 0 then begin + acount:= fcount; + end; + if acount + aindex > fcount then begin + acount:= fcount - aindex; + end; + fintf.updateitemvalues(aindex,acount); + end; + finally + endupdate; + end; +end; + +procedure tcustomitemeditlist.doitemchange(const index: integer); +begin + if fowner <> nil then begin + fowner.itemchanged(index); + end; + inherited; +end; + +procedure tcustomitemeditlist.nodenotification(const sender: tlistitem; + var ainfo: nodeactioninfoty); +var + grid: tcustomgrid; +begin + if ainfo.action = na_destroying then begin + tlistitem1(sender).setowner(nil); + if not deleting then begin + grid:= fowner.fgridintf.getcol.grid; + if sender.index < grid.rowcount then begin + grid.deleterow(sender.index); + end; + end; + end + else begin + if not (ainfo.action in [na_change,na_valuechange,na_checkedchange]) or + (nochange = 0) then begin + if fowner.canevent(tmethod(fonitemnotification)) then begin + fonitemnotification(sender,ainfo.action); + end; + end; + inherited; + if ainfo.action in [na_expand,na_collapse] then begin + change(sender); + end; + if (nochange = 0) and + (ainfo.action in [na_valuechange,na_checkedchange]) and + not (ils_updateitemvalues in fitemstate) then begin + include(fitemstate,ils_updateitemvalues); + try + fintf.updateitemvalues(sender.index,1); + finally + exclude(fitemstate,ils_updateitemvalues); + end; + end; + end; +end; + +function tcustomitemeditlist.compare(const l,r): integer; +begin + result:= tlistitem1(l).compare(tlistitem(r), + oe_casesensitive in fowner.foptionsedit); +{ + if oe_casesensitive in fowner.foptionsedit then begin + result:= msecomparestr(tlistitem1(l).fcaption,tlistitem1(r).fcaption); + end + else begin + result:= msecomparetext(tlistitem1(l).fcaption,tlistitem1(r).fcaption); + end; +} +end; + +procedure tcustomitemeditlist.createstatitem(const reader: tstatreader; + out item: tlistitem); +var + i1: int32; +begin + if no_createvalueitems in foptions then begin + i1:= reader.readinteger(valuenodetypename); + if (i1 <= 0) or (i1 > ord(high(valuenodeclasses))) then begin + inherited; + end + else begin + item:= valuenodeclasses[listdatatypety(i1)].create(self); + end; + end + else begin + inherited; + end; +end; + +{ titemeditlist} + +function titemeditlist.getitemclass: listedititemclassty; +begin + result:= listedititemclassty(fitemclass); +end; + +procedure titemeditlist.setitemclass(const avalue: listedititemclassty); +begin + fitemclass:= avalue; + itemclasschanged(); +end; + +function titemeditlist.getoncreateitem: createlistitemeventty; +begin + result:= createlistitemeventty(oncreateobject); +end; + +procedure titemeditlist.setoncreateitem(const value: createlistitemeventty); +begin + oncreateobject:= createobjecteventty(value); +end; + +{ tvalueedititem } + +destructor tvalueedititem.destroy; +begin + editwidget:= nil; //remove link, objectlinker of owner is used. + inherited; +end; + +procedure tvalueedititem.changed; +begin + with tcustomitemedit(fowner) do begin + if componentstate * [csloading,csdestroying] = [] then begin + valueeditchanged(); + end; + end; +end; + +procedure tvalueedititem.seteditwidget(const avalue: twidget); +begin + if avalue <> finfo.editwidget then begin + if (avalue <> nil) and (not getcorbainterface(avalue,typeinfo(igridwidget), + finfo.gridintf) or + (avalue.parentwidget <> fowner)) then begin + raise exception.create('Invalid item field edit widget "'+avalue.name+'".'); + end; + if (finfo.editwidget <> nil) and (finfo.gridintf <> nil) then begin + finfo.gridintf.setparentgridwidget(nil); + end; + tcustomitemedit(fowner).setlinkedvar(avalue,tmsecomponent(finfo.editwidget)); + if avalue = nil then begin + finfo.gridintf:= nil; + finfo.datatype:= dl_none; + end + else begin + finfo.gridintf.setparentgridwidget(igridwidget(tcustomitemedit(fowner))); + finfo.datatype:= finfo.gridintf.getdatalistclass().datatype(); + end; + changed(); + end; +end; + +procedure tvalueedititem.setvalueindex(const avalue: int32); +begin + if finfo.valueindex <> avalue then begin + finfo.valueindex:= avalue; + changed(); + end; +end; + +{ tvalueedits } + +constructor tvalueedits.create(const aowner: tcustomitemedit); +begin + inherited create(aowner,tvalueedititem); +end; + +class function tvalueedits.getitemclasstype: persistentclassty; +begin + result:= tvalueedititem; +end; + +{ tcustomitemedit } + +constructor tcustomitemedit.create(aowner: tcomponent); +begin + fentryedge:= gd_none; + fvalueedits:= tvalueedits.create(self); + include(fstate,des_editing); +// fediting:= true; + if fitemlist = nil then begin + fitemlist:= titemeditlist.create(iitemlist(self),self); + end; + flayoutinfofocused.widget:= self; + inherited; + textflags:= defaultitemedittextflags; + textflagsactive:= defaultitemedittextflagsactive; +// createframe; +end; + +destructor tcustomitemedit.destroy; +begin + if fgridintf = nil then begin + freeandnil(fitemlist); + end; + fvalueedits.free(); + inherited; +end; + +function tcustomitemedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= fitemlist; +end; + +function tcustomitemedit.getdatalistclass: datalistclassty; +begin + result:= titemeditlist; +end; + +procedure tcustomitemedit.setgridintf(const intf: iwidgetgrid); +var + li1: tcustomitemeditlist; +begin + inherited; + if intf <> nil then begin + li1:= tcustomitemeditlist(intf.getcol.datalist); + if li1 <> nil then begin + if fitemlist = nil then begin //changed inherited grid col + fitemlist:= tcustomitemeditlist(intf.getcol.datalist); + end + else begin + if fitemlist <> li1 then begin + fitemlist.free; + fitemlist:= li1; + end; + end; + fitemlist.fowner:= self; + fitemlist.fintf:= iitemlist(self); + end; + if fitemlist.count > 0 then begin + itemcountchanged; + end + else begin + fitemlist.count:= intf.getcol.grid.rowcount; + end; + updatelayout; + end; +end; + +procedure tcustomitemedit.createnode(var item: tlistitem); +begin + item:= tlistitem.create(fitemlist); +end; + +function tcustomitemedit.getlayoutinfo( + const acellinfo: pcellinfoty): plistitemlayoutinfoty; +begin + if (ws1_painting in fwidgetstate1) or (des_updatelayout in fstate) then begin + result:= @flayoutinfofocused; //active + with result^.variable do begin + colorglyph:= fitemlist.fcolorglyphactive; + colorline:= fitemlist.fcolorlineactive; + glyphversion:= fitemlist.boxglyph_versionactive; + end; + end + else begin + result:= @flayoutinfocell; + if (acellinfo <> nil) and + ((acellinfo^.rect.cx <> fcalcsize.cx) or + (acellinfo^.rect.cy <> fcalcsize.cy)) then begin + fcalcsize:= acellinfo^.rect.size; + calclayout(fcalcsize,flayoutinfocell); + end; + end; + with result^.variable do begin + if acellinfo <> nil then begin + if cds_usecoloractive in acellinfo^.drawstate then begin + colorglyph:= fitemlist.fcolorglyphactive; + colorline:= fitemlist.fcolorlineactive; + glyphversion:= fitemlist.boxglyph_versionactive; + end + else begin + colorglyph:= fitemlist.fcolorglyph; + colorline:= fitemlist.fcolorline; + glyphversion:= 0; + end; + end; + if stockobjects.glyphs.versioncount <= glyphversion then begin + glyphversion:= 0; + end; + end; +end; + +procedure tcustomitemedit.updateitemvalues(const index: integer; const count: integer); +var + int1,int2: integer; + po1: plistitem; + po2: plistitematy; + col1: tdatacol; +begin + if (no_cellitemselect in fitemlist.options) and (fgridintf <> nil) then begin + col1:= fgridintf.getcol; + po2:= fitemlist.datapo; + for int1:= index to index + count - 1 do begin + col1.selected[int1]:= ns_selected in tlistitem1(po2^[int1]).fstate; + end; + end; + if canevent(tmethod(fonupdaterowvalues)) then begin + if index >= 0 then begin + if count > 1 then begin + fitemlist.beginupdate; + end; + try + po1:= fitemlist.datapo; + inc(po1,index); + int2:= index + count - 1; + if int2 >= fitemlist.fcount then begin + int2:= fitemlist.fcount - 1; + end; + for int1:= index to int2 do begin + fonupdaterowvalues(self,int1,po1^); + inc(po1); + end; + finally + if count > 1 then begin + fitemlist.endupdate; + end; + end; + end; + end; + if (fgridintf <> nil) then begin + {$warnings off} + with tcustomgrid1(fgridintf.getcol.grid) do begin + {$warnings on} +// sortinvalid(invalidaxis,invalidaxis); + rowdatachanged(makegridcoord(invalidaxis,index),count); +// if not fitemlist.updating then begin +// checksort; +// end; + end; + end; +end; + +procedure tcustomitemedit.updateitemvalues(); + //calls updateitemvalues for current grid row +var + int1: integer; +begin + if fgridintf <> nil then begin + int1:= fgridintf.getrow; + if int1 >= 0 then begin + updateitemvalues(int1,1); + end; + end; +end; + +procedure tcustomitemedit.itemcountchanged; +begin + fvalue:= nil; //invalid + if fgridintf <> nil then begin + with fgridintf.getcol.grid do begin + rowcount:= fitemlist.count; +// rowdatachanged(makegridcoord(invalidaxis,0),fitemlist.count); + end; + end; +end; + +procedure tcustomitemedit.getitemvalues; +begin + if fvalue = nil then begin + text:= ''; + end + else begin + text:= fvalue.caption; + end; + updateeditwidget(); + setupeditor; +end; + +procedure tcustomitemedit.gridtovalue(arow: integer); +var + int1: integer; +begin + int1:= arow; + if int1 = -1 then begin + int1:= fgridintf.getcol.grid.row; + end; + if int1 < 0 then begin + fvalue:= nil; + end + else begin + fvalue:= fitemlist[int1]; + end; + getitemvalues; + inherited; +end; + +procedure tcustomitemedit.valuetogrid(arow: integer); +begin + if arow >= 0 then begin + fitemlist.incupdate; + try + updateitemvalues(arow,1); + finally + fitemlist.decupdate; + end; + end; +end; + +function tcustomitemedit.finddataedits(aitem: tlistitem; + out ainfos: recvaluearty): boolean; +var + i1,i2: int32; + po1: precvaluety; + intf1: irecordvaluefield; +begin + result:= false; + if (fvalueedits.count > 0) and (aitem <> nil) and + mseclasses.getcorbainterface(aitem.valueitem, + typeinfo(irecordvaluefield),intf1) then begin + +// (aitem is trecordlistedititem) then begin +// with irecordvaluefield(trecordlistedititem(aitem)) do begin + with intf1 do begin + getvalueinfo(ainfos); + for i1:= 0 to high(ainfos) do begin + po1:= @ainfos[i1]; + po1^.dummypointer:= nil; + if po1^.datatype <> dl_none then begin + if (po1^.valueindex >= 0) then begin + for i2:= 0 to fvalueedits.count - 1 do begin + with tvalueedititem(fvalueedits.fitems[i2]) do begin + if (finfo.datatype = po1^.datatype) and + (finfo.valueindex = po1^.valueindex) then begin + po1^.dummypointer:= @finfo; //check index match + result:= true; + break; + end; + end; + end; + end; + if po1^.dummypointer = nil then begin + for i2:= 0 to fvalueedits.count - 1 do begin + with tvalueedititem(fvalueedits.fitems[i2]) do begin + if finfo.datatype = po1^.datatype then begin + po1^.dummypointer:= @finfo; //check any match + result:= true; + break; + end; + end; + end; + end; + end; + end; + end; + end; +end; + +function tcustomitemedit.updateeditwidget(): boolean; + //true if editwidgetactivated +var + infos1: recvaluearty; + i1: int32; + bo1: boolean; + widget1: twidget; +begin + result:= finddataedits(fvalue,infos1); + if result then begin + for i1:= 0 to fvalueedits.count - 1 do begin + with tvalueedititem(fvalueedits.fitems[i1]) do begin + finfo.visible:= false; + end; + end; + bo1:= false; + fvisiblevalueeditcount:= 0; + for i1:= 0 to high(infos1) do begin + with infos1[i1] do begin + if dummypointer <> nil then begin + with pvalueeditinfoty(dummypointer)^ do begin + if gridintf <> nil then begin + visible:= true; + gridintf.setvaluedata(valuead^); + editwidget.visible:= true; + inc(fvisiblevalueeditcount); + if not bo1 then begin + bo1:= true; + factiveinfo:= pvalueeditinfoty(dummypointer)^; +{ + if focused then begin + editwidget.setfocus(); + end; +} + end; + end; + end; + end; + end; + end; + for i1:= 0 to fvalueedits.count - 1 do begin + with tvalueedititem(fvalueedits.fitems[i1]) do begin + if not finfo.visible and (finfo.editwidget <> nil) then begin + finfo.editwidget.visible:= false; + end; + end; + end; + if focused then begin + widget1:= getcornerwidget(fentryedge,true); + if widget1 <> nil then begin + widget1.setfocus(); + end + else begin + if factiveinfo.editwidget <> nil then begin + factiveinfo.editwidget.setfocus(); + end; + end; + end; + end + else begin + fillchar(factiveinfo,sizeof(factiveinfo),0); + for i1:= 0 to fvalueedits.count - 1 do begin + with tvalueedititem(fvalueedits.fitems[i1]) do begin + finfo.visible:= false; + if finfo.editwidget <> nil then begin + finfo.editwidget.visible:= false; + end; + end; + end; + end; +end; + +procedure tcustomitemedit.drawcell(const canvas: tcanvas); +var + databefore: pointer; + infos1: recvaluearty; + i1: int32; + fra1,fra2: framety; + fs1: widgetstatesty; +begin + with cellinfoty(canvas.drawinfopo^) do begin + fs1:= []; + if focused then begin + include(fs1,ws_focused); + if active then begin + include(fs1,ws_active); + end; + end; + flayoutinfocell.variable.widgetstate:= fs1; + doextendimage(canvas.drawinfopo,flayoutinfocell.variable.extra); + flayoutinfocell.variable.rowindex:= cell.row; + flayoutinfocell.textflags:= textflags; + if finddataedits(tlistitem(datapo^),infos1) then begin + databefore:= datapo; + fra1:= getcellframe; + inflaterect1(innerrect,fra1); + for i1:= 0 to high(infos1) do begin + with infos1[i1] do begin + if dummypointer <> nil then begin + with pvalueeditinfoty(dummypointer)^ do begin + datapo:= valuead; + fra2:= gridintf.getcellframe; + deflaterect1(innerrect,fra2); + gridintf.drawcell(canvas); + inflaterect1(innerrect,fra2); + end; + end; + end; + datapo:= databefore; + deflaterect1(innerrect,fra1); + end; + end + else begin + tlistitem(datapo^).drawcell(canvas); + end; + end; + paintimage(canvas); +end; + +procedure tcustomitemedit.childdataentered(const sender: igridwidget); +var + intf1: irecordvaluefield; +begin + if sender = factiveinfo.gridintf then begin + if (fvalue <> nil) and mseclasses.getcorbainterface(fvalue.valueitem, + typeinfo(irecordvaluefield),intf1) then begin +// if fvalue is trecordlistedititem then begin +// with irecordvaluefield(trecordlistedititem(fvalue)) do begin + with intf1 do begin + setvalue(factiveinfo.datatype,factiveinfo.valueindex,@sender.getvaluedata); + end; + end; + end; +end; + +procedure tcustomitemedit.childfocused(const sender: igridwidget); +var + infos1: recvaluearty; + i1: int32; + widget1: twidget; + intf1: irecordvaluefield; +begin + if mseclasses.getcorbainterface(fvalue, + typeinfo(irecordvaluefield),intf1) then begin +// if fvalue is trecordlistedititem then begin + if finddataedits(tlistitem(fvalue),infos1) then begin + widget1:= sender.getwidget; + for i1:= 0 to high(infos1) do begin + with infos1[i1] do begin + if (dummypointer <> nil) then begin + with pvalueeditinfoty(dummypointer)^ do begin + if editwidget = widget1 then begin + factiveinfo:= pvalueeditinfoty(dummypointer)^; + break; + end; + end; + end; + end; + end; + end; + end; +end; + +function tcustomitemedit.internaldatatotext(const data): msestring; +var + po: plistitem; +begin + if @data = nil then begin + po:= @fvalue; + end + else begin + po:= @data; + end; + if po^ <> nil then begin + result:= po^.caption; + end + else begin + result:= ''; + end; +end; + +procedure tcustomitemedit.dosetvalue(var avalue: msestring; var accept: boolean); +begin + if canevent(tmethod(fonsetvalue)) then begin + fonsetvalue(self,avalue,accept); + end; +end; + +procedure tcustomitemedit.storevalue(var avalue: msestring); +begin + fvalue.caption:= avalue; +end; + +procedure tcustomitemedit.texttovalue(var accept: boolean; const quiet: boolean); +var + mstr1: msestring; +begin + mstr1:= feditor.text; + checktext(mstr1,accept); + if not accept then begin + exit; + end; + if not quiet then begin + dosetvalue(mstr1,accept); + end; + if accept and (fvalue <> nil) then begin + storevalue(mstr1); + end; +end; + +procedure tcustomitemedit.calclayout(const asize: sizety; + out alayout: listitemlayoutinfoty); +begin + if fframe <> nil then begin + getitemclass.calcitemlayout(asize,tframe1(fframe).fi.innerframe, + fitemlist,alayout); + end + else begin + getitemclass.calcitemlayout(asize,minimalframe,fitemlist,alayout); + end; + alayout.textflags:= textflags; +end; + +procedure tcustomitemedit.doupdatelayout(const nocolinvalidate: boolean); +begin + if (fgridintf <> nil) and (fitemlist <> nil) then begin + calclayout(paintrect.size,flayoutinfofocused); + invalidate; + if not fitemlist.updating and not nocolinvalidate then begin + fgridintf.getcol.changed; + end; + end; +end; + +procedure tcustomitemedit.doupdatecelllayout; +begin + flayoutinfocell:= flayoutinfofocused; + fcalcsize:= flayoutinfofocused.cellsize; +end; + +procedure tcustomitemedit.updatelayout; +begin + doupdatelayout(false); + doupdatecelllayout; +end; + +procedure tcustomitemedit.clientrectchanged; +var + bo1: boolean; +begin + doupdatelayout(true); //col invalidated by grid + doupdatecelllayout; + bo1:= des_updatelayout in fstate; + include(fstate,des_updatelayout); //for setupeditor + try + inherited; + finally + if not bo1 then begin + exclude(fstate,des_updatelayout); + end; + end; +end; + +procedure tcustomitemedit.doitembuttonpress(var info: mouseeventinfoty); +begin + //dummy +end; + +procedure tcustomitemedit.clientmouseevent(var info: mouseeventinfoty); +var + po1: pointty; + zone1: cellzonety; +begin + if (fvalue <> nil) and (info.eventkind in mouseposevents) then begin + zone1:= cz_default; + fvalue.updatecellzone(info.pos,zone1); + application.widgetcursorshape:= getcellcursor(-1,zone1,info.pos); + end; + if canevent(tmethod(fonclientmouseevent)) then begin + fonclientmouseevent(self,info); + end; + if not (es_processed in info.eventstate) then begin + if fvalue <> nil then begin + if (info.eventkind = ek_buttonpress) and (fgridintf <> nil) then begin + with fgridintf.getcol.grid,frame do begin + po1:= scrollpos; + fvalue.mouseevent(info); + if not (es_processed in info.eventstate) then begin + doitembuttonpress(info); + end; + po1:= subpoint(scrollpos,po1); + if (po1.x <> 0) or (po1.y <> 0) then begin + self.releasemouse; + addpoint1(info.pos,po1); + end; + end; + end + else begin + fvalue.mouseevent(info); + end; + end; + if not (es_processed in info.eventstate) then begin + inherited; + end; + end; +end; + +function tcustomitemedit.getitemclass: listitemclassty; +begin +// result:= tlistitem; + result:= listitemclassty(fitemlist.fitemclass); +end; + +procedure tcustomitemedit.setupeditor; +var + bo1: boolean; +begin + if not (csloading in componentstate) then begin + if fvalue = nil then begin + with feditor,flayoutinfofocused do begin + feditor.setup(text,curindex,false,captioninnerrect,captionrect,nil,nil, + geteditfont); + end; + end + else begin + bo1:= des_updatelayout in fstate; + include(fstate,des_updatelayout); + doextendimage(nil,flayoutinfofocused.variable.extra); + fvalue.setupeditor(feditor,geteditfont,true); + if not bo1 then begin + exclude(fstate,des_updatelayout); + end; + end; + end; +end; + +procedure tcustomitemedit.dopaintforeground(const acanvas: tcanvas); +begin + if fvalue <> nil then begin + doextendimage(acanvas.drawinfopo,flayoutinfofocused.variable.extra); + end; + inherited; + if fvalue <> nil then begin + if fgridintf <> nil then begin + acanvas.rootbrushorigin:= fgridintf.getbrushorigin; + flayoutinfofocused.variable.rowindex:= fgridintf.grid.row; + end; + with tlistitem1(fvalue) do begin + flayoutinfofocused.variable.calcautocellsize:= false; + flayoutinfofocused.variable.widgetstate:= widgetstate; + drawimage(acanvas,flayoutinfofocused); + if feditor.lasttextclipped then begin + include(fstate1,ns1_captionclipped); + end + else begin + exclude(fstate1,ns1_captionclipped); + end; + end; + end; +end; + +procedure tcustomitemedit.itemchanged(const index: integer); +begin + if (fgridintf <> nil) then begin + if (factiverow < 0) or (factiverow >= fitemlist.count) then begin + fvalue:= nil; + end; + fgridintf.getcol.cellchanged(index); + end; + changed; +end; + +function tcustomitemedit.getitemlist: titemeditlist; +begin + result:= titemeditlist(fitemlist); +end; + +procedure tcustomitemedit.setitemlist(const Value: titemeditlist); +begin + fitemlist.Assign(Value); +end; + +procedure tcustomitemedit.dokeydown(var info: keyeventinfoty); +var + widget1: twidget; +begin + doonkeydown(info); + with info do begin + if not(es_processed in eventstate) then begin + if not (es_child in info.eventstate) then begin + if (oe_locate in foptionsedit) and isenterkey(nil,key) and + (shiftstate = []) then begin + if not editing then begin + editing:= not (oe_readonly in foptionsedit) and valuecanedit() and + ((fvalue = nil) or tlistitem1(fvalue).cancaptionedit()); + + ; + if editing then begin + include(eventstate,es_processed); + end; + end + else begin + if not editing then begin + include(eventstate,es_processed); //trigger checkvalue otherwise + end; + editing:= false; + end; + end + else begin + if (key = key_space) and + (shiftstate * shiftstatesrepeatmask = []) and + not (es_processed in eventstate) and + (not editing) and valuecanedit() and + (ns_checkbox in fvalue.state) and + (editor.filtertext = '') then begin + fvalue.checked:= not fvalue.checked; + end; + end; + end + else begin + if (fvisiblevalueeditcount > 0) then begin + widget1:= window.focusedwidget; + if checkdescendent(widget1) then begin + twidget1(widget1).handlenavigkeys(info,true); //nowrap + end; + if window.focusedwidget = widget1 then begin + exclude(info.eventstate,es_processed); + end; + end; + end; + end; + end; + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +function tcustomitemedit.getvaluetext: msestring; +begin + if (fvalue <> nil) then begin + result:= fvalue.getvaluetext; + end + else begin + result:= ''; + end; +end; + +procedure tcustomitemedit.setvaluetext(var avalue: msestring); +begin + if (fvalue <> nil) then begin + fvalue.setvaluetext(avalue); + end; +end; + +function tcustomitemedit.item: tlistedititem; +begin + result:= tlistedititem(fvalue); +end; + +procedure tcustomitemedit.internalcreateframe; +begin + tbuttonsframe.create(iscrollframe(self),ibutton(self)); +end; + +{$ifdef mse_with_ifi} +function tcustomitemedit.getifilink: tifistringlinkcomp; +begin + if fitemifilink then begin + result:= nil; + end + else begin + result:= tifistringlinkcomp(fifilink); + end; +end; + +procedure tcustomitemedit.setifilink(const avalue: tifistringlinkcomp); +begin + fitemifilink:= false; + inherited setifilink(avalue); +end; + +function tcustomitemedit.getifilink1: tifilinkcomp; +begin + if not fitemifilink then begin + result:= nil; + end + else begin + result:= fifilink; + end; +end; + +procedure tcustomitemedit.setifilink1(const avalue: tifilinkcomp); +begin + fitemifilink:= true; + inherited setifilink(avalue); +end; + +procedure tcustomitemedit.updateifigriddata(const sender: tobject; + const alist: tdatalist); +begin + //dummy, common datalist not possible +end; + +{$endif} + +function tcustomitemedit.isnull: boolean; +begin + result:= (item = nil) or (item.caption = ''); +end; + +procedure tcustomitemedit.buttonaction(var action: buttonactionty; + const buttonindex: integer); +begin + if canevent(tmethod(fonbuttonaction)) then begin + fonbuttonaction(self,action,buttonindex); + end; +end; + +procedure tcustomitemedit.mouseevent(var info: mouseeventinfoty); +begin + if fframe <> nil then begin + tcustombuttonframe(fframe).mouseevent(info); + end; + inherited; +end; + +{ +procedure tcustomitemedit.sortfunc(const l, r; var result: integer); +begin + if oe_casesensitive in foptionsedit then begin + result:= msecomparestr(tlistitem1(l).fcaption,tlistitem1(r).fcaption); + end + else begin + result:= msecomparetext(tlistitem1(l).fcaption,tlistitem1(r).fcaption); + end; +end; +} +function tcustomitemedit.getitems(const index: integer): tlistitem; +begin + result:= tlistitem(fitemlist[index]); +end; + +procedure tcustomitemedit.setitems(const index: integer; const Value: tlistitem); +begin + fitemlist[index]:= value; +end; + +function tcustomitemedit.locatecount: integer; //number of locate values +begin + result:= fitemlist.count; +end; + +function tcustomitemedit.getkeystring(const index: integer): msestring; +begin + result:= fitemlist[index].caption; +end; +{ +function tcustomitemedit.islocating: boolean; +begin + result:= not editing and (oe_locate in foptionsedit) +end; +} +(* +procedure tcustomitemedit.setfiltertext(const value: msestring); +var + int1: integer; + opt1: locatestringoptionsty; +begin + if value = '' then begin + ffiltertext:= ''; + end + else begin + int1:= factiverow; + if oe_casesensitive in foptionsedit then begin + opt1:= [lso_casesensitive]; + end + else begin + opt1:= []; + end; + fitemlist.datapo; //normalize ring + if locatestring(value,{$ifdef FPC}@{$endif}getkeystring,opt1, + fitemlist.count,int1) then begin + with tcustomgrid1(fgridintf.getcol.grid) do begin + focuscell(makegridcoord(ffocusedcell.col,int1)); + end; + ffiltertext:= value; + end; + end; + updatefilterselect; +end; +*) +{ +function tcustomitemedit.getcolorglyph: colorty; +begin + result:= fitemlist.fcolorglyph; +end; +} +procedure tcustomitemedit.docellevent(const ownedcol: boolean; + var info: celleventinfoty); +begin + with info do begin + if ownedcol then begin + if eventkind in mousecellevents then begin + if fvalue <> nil then begin + fvalue.updatecellzone(info.mouseeventinfopo^.pos,info.zone); + end; + end; + if (info.eventkind = cek_enter) then begin + if (widgetcount > 1) and (cellbefore.col >= 0) and + (cellbefore.row >= 0) then begin + fentryedge:= gd_none; + if cellbefore.row < cell.row then begin + fentryedge:= gd_up; + end + else begin + if cellbefore.row > cell.row then begin + fentryedge:= gd_down; + end + else begin + if cellbefore.col < cell.col then begin + fentryedge:= gd_left; + end + else begin + if cellbefore.col > cell.col then begin + fentryedge:= gd_right; + end; + end; + end; + end; + end; + end + else begin + if eventkind = cek_exit then begin + fentryedge:= gd_none; + end; + end; + end; + if (info.eventkind = cek_enter) or + (info.eventkind = cek_exit) then begin + if oe_locate in foptionsedit then begin + editing:= false; + end; + factiverow:= info.newcell.row; + end; + end; + if canevent(tmethod(foncellevent)) then begin + foncellevent(self,info); + end; + inherited; +end; + +function tcustomitemedit.getediting: boolean; +begin + result:= des_editing in fstate; +end; + +procedure tcustomitemedit.setediting(const avalue: boolean); +begin + if editing <> avalue then begin + if avalue or (oe_locate in foptionsedit) then begin + if avalue then begin + include(fstate,des_editing); + end + else begin + exclude(fstate,des_editing); + end; + setupeditor; + if editing then begin + feditor.selectall; + end + else begin + if foptionsedit * [oe_autoselect,oe_locate] = [oe_autoselect] then begin + feditor.selectall; + end; + end; + end + else begin + exclude(fstate,des_editing); + end; +// cursorchanged; + updatereadonlystate; + end; +end; + +function tcustomitemedit.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + if oe_readonly in result then begin + editing:= false; + end; + if not editing and not (csdesigning in componentstate) then begin + include(result,oe_readonly); + end; +end; + +procedure tcustomitemedit.beginedit; +begin + editing:= true; +end; + +procedure tcustomitemedit.endedit; +begin + editing:= false; +end; + +function tcustomitemedit.valuecanedit: boolean; +begin + result:= (fvalue <> nil) and tlistitem1(fvalue).canvalueedit(); + if (fvalue <> nil) and canevent(tmethod(foncheckcanedit)) then begin + foncheckcanedit(self,fvalue,result); + end; +end; + +procedure tcustomitemedit.doextendimage(const cellinfopo: pcellinfoty; + var ainfo: extrainfoty); +begin + fillchar(ainfo,sizeof(ainfo),#0); + if canevent(tmethod(fonextendimage)) then begin + fonextendimage(self,cellinfopo,ainfo); + end; +end; + +procedure tcustomitemedit.getautopaintsize(var asize: sizety); +begin + inherited; + if (fvalue <> nil) and (fvalue.owner <> nil) then begin + with flayoutinfofocused.variable do begin + calcautocellsize:= true; + fillchar(extra,sizeof(extra),#0); + end; + fvalue.drawimage(editor.getfontcanvas(),flayoutinfofocused); + end; + with flayoutinfofocused do begin + asize.cx:= asize.cx + imagerect.cx + variable.imageextend.cx + + {imageextra.cx +} + variable.treelevelshift; //??? + if asize.cy < minsize.cy then begin + asize.cy:= minsize.cy; + end; + if asize.cx < minsize.cx then begin + asize.cx:= minsize.cx; + end; + end; +end; + +procedure tcustomitemedit.getautocellsize(const acanvas: tcanvas; + var asize: sizety); +begin + if fvalue <> nil then begin + drawcell(acanvas); //called from twidgetcol.drawfocusedcell() + asize:= cellinfoty(acanvas.drawinfopo^).autocellsize; + end + else begin + inherited; + end; +end; + +function tcustomitemedit.getcellcursor(const arow: integer; + const acellzone: cellzonety; const apos: pointty): cursorshapety; +begin + if acellzone = cz_child then begin + if flastzonewidget <> nil then begin + result:= flastzonewidget.actualcursor(apos); + end + else begin + result:= cr_default; + end; + end + else begin + if (acellzone = cz_caption) and + ((foptionsedit * [oe_locate,oe_readonly] = []) or + (arow < 0) and (editing)) then begin + result:= cursor; + if result = cr_default then begin + result:= cr_ibeam; + end; + end + else begin + if (acellzone = cz_caption) and + (foptionsedit * [oe_locate,oe_readonly] <> []) then begin + result:= cursorreadonly; + if result = cr_default then begin + result:= cr_arrow; + end; + end + else begin + result:= cr_arrow; + // result:= cr_default; + end; + end; + end; +end; + +procedure tcustomitemedit.updatecellzone(const row: integer; const apos: pointty; + var result: cellzonety); +var + ar1: recvaluearty; + i1: int32; +begin + inherited; + if fitemlist <> nil then begin + flastzonewidget:= nil; + if (fvalueedits.count > 0) and finddataedits(fitemlist[row],ar1) then begin + for i1:= 0 to high(ar1) do begin + with ar1[i1] do begin + if dummypointer <> nil then begin + with pvalueeditinfoty(dummypointer)^ do begin + if (editwidget <> nil) and + pointinrect(apos,editwidget.widgetrect) then begin + result:= cz_child; + flastzonewidget:= editwidget; + end; + end; + end; + end; + end; + end; + if flastzonewidget = nil then begin + fitemlist[row].updatecellzone(apos,result); + end; + end; +end; + +function tcustomitemedit.getgrid: tcustomgrid; +begin + result:= nil; + if fgridintf <> nil then begin + result:= fgridintf.getcol.grid; + end; +end; + +function tcustomitemedit.selecteditems: listedititemarty; +var + int1: integer; + ar1: integerarty; + po1: ppointeraty; +begin + result:= nil; + if fgridintf <> nil then begin + with fgridintf.getcol do begin + if datalist <> nil then begin + ar1:= selectedcells; + setlength(result,length(ar1)); + po1:= datalist.datapo; + for int1:= 0 to high(result) do begin + result[int1]:= tlistitem(po1^[ar1[int1]]); + end; + end; + end; + end; +end; + +procedure tcustomitemedit.datalistdestroyed; +begin + fitemlist:= nil; +end; + +function tcustomitemedit.textclipped(const arow: integer; + out acellrect: rectty): boolean; +var + cell1: gridcoordty; + grid1: tcustomgrid; +// bo1: boolean; +begin + checkgrid; + with twidgetcol1(fgridintf.getcol) do begin + grid1:= grid; + cell1.row:= arow; + cell1.col:= colindex; + result:= grid1.isdatacell(cell1); + if result then begin + acellrect:= grid1.clippedcellrect(cell1,cil_inner); + if focused and (arow = grid1.row) then begin + result:= feditor.lasttextclipped; //todo: check value edit widget + end + else begin + result:= ns1_captionclipped in tlistitem1(fitemlist[arow]).fstate1; + end; + end + else begin + acellrect:= nullrect; + end; + end; +end; + +function tcustomitemedit.getframe(): tbuttonsframe; +begin + result:= tbuttonsframe(inherited getframe()); +end; + +procedure tcustomitemedit.setframe(const avalue: tbuttonsframe); +begin + inherited setframe(avalue); +end; + +procedure tcustomitemedit.insertwidget(const awidget: twidget; const apos: pointty); +var + intf1: igridwidget; +begin + inherited; + if not (csloading in componentstate) then begin + if awidget.getcorbainterface(typeinfo(igridwidget),intf1) then begin + awidget.visible:= false; + intf1.initgridwidget(); + awidget.anchors:= []; + end; + end; +end; + +procedure tcustomitemedit.setvalueedits(const avalue: tvalueedits); +begin + fvalueedits.assign(avalue); +end; + +procedure tcustomitemedit.valueeditchanged(); +begin +end; + +procedure tcustomitemedit.loaded(); +begin + inherited; + valueeditchanged(); +end; + +procedure tcustomitemedit.setfirstclick(var ainfo: mouseeventinfoty); +begin + if (factiveinfo.editwidget <> nil) and + pointinrect(ainfo.pos,factiveinfo.editwidget.paintparentrect) then begin + factiveinfo.gridintf.setfirstclick(ainfo); + end + else begin + inherited; + end; +end; + +procedure tcustomitemedit.dofocus(); +var + widget1: twidget; +begin + widget1:= getcornerwidget(fentryedge,true); + if widget1 <> nil then begin + widget1.setfocus(); + end + else begin + if factiveinfo.editwidget <> nil then begin + factiveinfo.editwidget.setfocus(); + end + else begin + inherited; + end; + end; +end; + +procedure tcustomitemedit.unregisterchildwidget(const child: twidget); +var + i1: int32; +begin + if not (csdestroying in componentstate) then begin + if child = factiveinfo.editwidget then begin + factiveinfo.gridintf.setparentgridwidget(nil); + fillchar(factiveinfo,sizeof(factiveinfo),0); + end; + for i1:= 0 to fvalueedits.count - 1 do begin + with tvalueedititem(fvalueedits.fitems[i1]) do begin + if finfo.editwidget = child then begin + editwidget:= nil; + end; + end; + end; + if child = flastzonewidget then begin + flastzonewidget:= nil; + end; + end; + inherited; +end; + +{ +function tcustomitemedit.actualcursor(const apos: pointty): cursorshapety; +var + zone1: cellzonety; + int1: integer; +begin + if fgridintf <> nil then begin + zone1:= cz_default; + int1:= fgridintf.grid.row; + if int1 >= 0 then begin + updatecellzone(int1,widgetpostoclientpos(apos),zone1); + result:= getcellcursor(int1,zone1); + exit; + end; + end; + result:= inherited actualcursor(apos); +end; +} +{ +procedure tcustomitemedit.dostatwrite(const writer: tstatwriter); +begin + fitemlist.statwrite(writer); +end; + +procedure tcustomitemedit.dostatread(const reader: tstatreader); +begin + fitemlist.statread(reader); +end; +} + +{ titemedit } + +function titemedit.getifiitemlink: tifiitemlinkcomp; +begin + result:= tifiitemlinkcomp(getifilink1()); +end; + +procedure titemedit.setifiitemlink(const avalue: tifiitemlinkcomp); +begin + setifilink1(avalue); +// inherited setifilink(avalue); +end; + +{ tdropdownitemedit } + +constructor tdropdownitemedit.create(aowner: tcomponent); +begin + inherited; + fdropdown:= getdropdowncontrollerclass.create(idropdownlist(self)); + fcontrollerintf:= idataeditcontroller(fdropdown); +end; + +destructor tdropdownitemedit.destroy; +begin + inherited; + fdropdown.free; +end; + +function tdropdownitemedit.getdropdowncontrollerclass(): + dropdownlistcontrollerclassty; +begin + result:= tdropdownlistcontroller; +end; +{ +procedure tdropdownitemedit.internalcreateframe; +begin + fdropdown.createframe; +end; +} +function tdropdownitemedit.getframe: tdropdownmultibuttonframe; +begin + result:= tdropdownmultibuttonframe(pointer(inherited getframe)); +end; + +procedure tdropdownitemedit.setframe(const avalue: tdropdownmultibuttonframe); +begin + inherited setframe(tbuttonsframe(pointer(avalue))); +end; +{ +function tdropdownitemedit.getbutton: tdropdownbutton; +begin + with tdropdownmultibuttonframe(fframe) do begin + result:= tdropdownbutton(buttons[activebutton]); + end; +end; + +procedure tdropdownitemedit.setbutton(const avalue: tdropdownbutton); +begin + with tdropdownmultibuttonframe(fframe) do begin + tdropdownbutton(buttons[activebutton]).assign(avalue); + end; +end; +} +procedure tdropdownitemedit.doafterclosedropdown; +begin + if canevent(tmethod(fonafterclosedropdown)) then begin + fonafterclosedropdown(self); + end; +end; +{ +procedure tdropdownitemedit.editnotification(var info: editnotificationinfoty); +begin + if fdropdown <> nil then begin + fdropdown.editnotification(info); + end; + inherited; +end; +} +procedure tdropdownitemedit.dobeforedropdown; +begin + if canevent(tmethod(fonbeforedropdown)) then begin + fonbeforedropdown(self); + end; +end; +{ +procedure tdropdownitemedit.dokeydown(var info: keyeventinfoty); +begin + fdropdown.dokeydown(info); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; +} +function tdropdownitemedit.getdropdownitems: tdropdowndatacols; +begin + result:= nil; +end; + +procedure tdropdownitemedit.setdropdown(const Value: tcustomdropdownlistcontroller); +begin + fdropdown.assign(Value); +end; + +function tdropdownitemedit.getvalueempty: integer; +begin + result:= -1; +end; + +procedure tdropdownitemedit.doupdatecelllayout; +begin + inherited; + if fframe <> nil then begin + with tframe1(fframe) do begin + inflaterect1(flayoutinfocell.captionrect,fpaintframe); //remove buttons + inflaterect1(flayoutinfocell.captioninnerrect,fpaintframe); //remove buttons + end; + end; +end; + +procedure tdropdownitemedit.imagelistchanged; +begin + //dummy +end; +{ +function tdropdownitemedit.setdropdowntext(const value: msestring; + const docheckvalue: boolean;const canceled: boolean): boolean; +begin + result:= true; + if canceled then begin + feditor.undo; + end + else begin + feditor.text:= value; + if docheckvalue then begin + result:= checkvalue; + end; + end; +end; +} +{ tmbdropdownitemedit } + +function tmbdropdownitemedit.getframe: tdropdownmultibuttonframe; +begin + result:= tdropdownmultibuttonframe(inherited getframe); +end; + +procedure tmbdropdownitemedit.setframe(const Value: tdropdownmultibuttonframe); +begin + inherited setframe(value); +end; + +function tmbdropdownitemedit.getdropdowncontrollerclass: + dropdownlistcontrollerclassty; +begin + result:= tmbdropdownlistcontroller; +end; + +{ ttreeeditnode } + +function ttreeeditnode.converttotreelistitem(flat, withrootnode: boolean; + filterfunc: treenodefilterfuncty): ttreelistedititem; +begin + result:= ttreelistedititem(inherited + converttotreelistitem(flat,withrootnode,filterfunc)); +end; + +function ttreeeditnode.listitemclass: treelistitemclassty; +begin + result:= ttreelistedititem; +end; + +{ ttreelistedititem } + +constructor ttreelistedititem.create(const aowner: tcustomitemlist; + const aparent: ttreelistitem); +begin + factiveindex:= -1; + inherited; +end; + +procedure ttreelistedititem.assign(source: ttreeitemeditlist); +var + int1,int2: integer; + po1: ptreelistitem; +begin + clear; + include(fstate1,ns1_noowner); + if source.count > 0 then begin + po1:= source.datapo; + setlength(fitems,source.count); + int2:= 0; + for int1:= 0 to high(fitems) do begin + if ttreelistitem1(po1^).fparent = nil then begin + fitems[int2]:= po1^; + ttreelistitem1(po1^).fparentindex:= int2; + inc(int2); + end; + inc(po1); + end; + setlength(fitems,int2); + fcount:= int2; + end; +end; + +function ttreelistedititem.add(const aitem: ttreelistedititem): integer; +begin + result:= inherited add(aitem); +end; + +function ttreelistedititem.add( + const itemclass: treelistedititemclassty = nil): ttreelistedititem; +begin + result:= ttreelistedititem(inherited add(itemclass)); +end; + +procedure ttreelistedititem.add(const aitems: treelistedititemarty); +begin + inherited add(treelistitemarty(aitems)); +end; + +procedure ttreelistedititem.add(const acount: integer; + const itemclass: treelistedititemclassty = nil); +begin + inherited add(acount,itemclass); +end; + +procedure ttreelistedititem.add(const captions: array of msestring; + const itemclass: treelistedititemclassty = nil); +var + countbefore: integer; + int1: integer; +begin + countbefore:= count; + inherited add(length(captions),itemclass); + for int1:= countbefore to count-1 do begin + ttreelistedititem(fitems[int1]).caption:= captions[int1-countbefore]; + end; +end; + +function ttreelistedititem.getactiveindex: integer; +begin + if factiveindex < fcount then begin + result:= factiveindex; + end + else begin + result:= -1; + end; +end; + +function ttreelistedititem.endtreerow: integer; +begin + result:= findex; + if expanded then begin + result:= result + treeheight; + end; +end; + +function ttreelistedititem.editwidget: ttreeitemedit; +var + node1: ttreelistedititem; +begin + result:= nil; + node1:= self; + repeat + if node1.fowner <> nil then begin + result:= ttreeitemedit(ttreeitemeditlist(node1.fowner).fowner); + break; + end; + node1:= ttreelistedititem(node1.parent); + until not (node1 is ttreelistedititem); +end; + +procedure ttreelistedititem.activate; +var + wi1: ttreeitemedit; +begin + wi1:= editwidget; + if wi1 <> nil then begin + rootexpanded:= true; + with wi1.widgetcol do begin; + grid.focuscell(mgc(index,self.findex)); + grid.activate; + end; +// wi1.activate; + end; +end; + +{ ttreeitemeditlist } + +constructor ttreeitemeditlist.create; +begin + fcolorline:= cl_treeline; + fcolorlineactive:= cl_treelineactive; + inherited; + fitemclass:= ttreelistedititem; +end; + +constructor ttreeitemeditlist.create(const intf: iitemlist; + const aowner: ttreeitemedit); +begin +// inherited; + inherited create(intf,aowner); +end; +{ +procedure ttreeitemeditlist.setoptionsdraw(const avalue: itemdrawoptionsty); +begin + if foptionsdraw <> avalue then begin + foptionsdraw:= avalue; + if fowner <> nil then begin + fowner.itemchanged(-1); + end; + end; +end; +} +procedure ttreeitemeditlist.setcolorline(const value: colorty); +begin + if fcolorline <> value then begin + fcolorline:= value; + if fowner <> nil then begin + fowner.itemchanged(-1); + end; + end; +end; + +procedure ttreeitemeditlist.setcolorlineactive(const value: colorty); +begin + if fcolorlineactive <> value then begin + fcolorlineactive:= value; + if fowner <> nil then begin + fowner.itemchanged(-1); + end; + end; +end; + +function ttreeitemeditlist.getboxglyph_empty: stockglyphty; +begin + result:= stockglyphty(fboxids[tib_empty]); +end; + +procedure ttreeitemeditlist.setboxglyph_empty(const avalue: stockglyphty); +begin + if stockglyphty(fboxids[tib_empty]) <> avalue then begin + stockglyphty(fboxids[tib_empty]):= avalue; + if fowner <> nil then begin + fowner.itemchanged(-1); + end; + end; +end; + +function ttreeitemeditlist.getboxglyph_expand: stockglyphty; +begin + result:= stockglyphty(fboxids[tib_expand]); +end; + +procedure ttreeitemeditlist.setboxglyph_expand(const avalue: stockglyphty); +begin + if stockglyphty(fboxids[tib_expand]) <> avalue then begin + stockglyphty(fboxids[tib_expand]):= avalue; + if fowner <> nil then begin + fowner.itemchanged(-1); + end; + end; +end; + +function ttreeitemeditlist.getboxglyph_expanded: stockglyphty; +begin + result:= stockglyphty(fboxids[tib_expanded]); +end; + +procedure ttreeitemeditlist.setboxglyph_expanded(const avalue: stockglyphty); +begin + if stockglyphty(fboxids[tib_expanded]) <> avalue then begin + stockglyphty(fboxids[tib_expanded]):= avalue; + if fowner <> nil then begin + fowner.itemchanged(-1); + end; + end; +end; +{ +function ttreeitemeditlist.getboxglyphactive_empty: stockglyphty; +begin + result:= stockglyphty(fboxidsactive[tib_empty]); +end; + +procedure ttreeitemeditlist.setboxglyphactive_empty(const avalue: stockglyphty); +begin + if stockglyphty(fboxidsactive[tib_empty]) <> avalue then begin + stockglyphty(fboxidsactive[tib_empty]):= avalue; + if fowner <> nil then begin + fowner.itemchanged(-1); + end; + end; +end; + +function ttreeitemeditlist.getboxglyphactive_expand: stockglyphty; +begin + result:= stockglyphty(fboxidsactive[tib_expand]); +end; + +procedure ttreeitemeditlist.setboxglyphactive_expand( + const avalue: stockglyphty); +begin + if stockglyphty(fboxidsactive[tib_expand]) <> avalue then begin + stockglyphty(fboxids[tib_expand]):= avalue; + if fowner <> nil then begin + fowner.itemchanged(-1); + end; + end; +end; + +function ttreeitemeditlist.getboxglyphactive_expanded: stockglyphty; +begin + result:= stockglyphty(fboxidsactive[tib_expanded]); +end; + +procedure ttreeitemeditlist.setboxglyphactive_expanded( + const avalue: stockglyphty); +begin + if stockglyphty(fboxidsactive[tib_expanded]) <> avalue then begin + stockglyphty(fboxidsactive[tib_expanded]):= avalue; + if fowner <> nil then begin + fowner.itemchanged(-1); + end; + end; +end; +} +function ttreeitemeditlist.getonstatreaditem: statreadtreeitemeventty; +begin + result:= onstatreadtreeitem; +end; + +procedure ttreeitemeditlist.setonstatreaditem(const avalue: statreadtreeitemeventty); +begin + onstatreadtreeitem:= avalue; +end; + +function ttreeitemeditlist.getonstatwriteitem: statwritetreeitemeventty; +begin + result:= onstatwritetreeitem; +end; + +procedure ttreeitemeditlist.setonstatwriteitem(const avalue: statwritetreeitemeventty); +begin + onstatwritetreeitem:= avalue; +end; + +procedure ttreeitemeditlist.createitem(out item: tlistitem); +begin + item:= treelistedititemclassty(fitemclass).create(self); +end; + +procedure ttreeitemeditlist.docreateobject(var instance: tobject); +begin + if fchangingnode = nil then begin + inherited; + if (finsertparent <> nil) and + (ttreelistitem1(instance).parent = finsertparent) then begin + inc(finsertparentindex); + end; + end + else begin + instance:= fchangingnode[finsertindex]; + with ttreelistitem1(instance) do begin + fowner:= self; + findex:= finsertcount; + inc(finsertcount); + if expanded and (fcount > 0) then begin + fchangingnode:= ttreelistitem(instance); + finsertindex:= 0; + end + else begin + inc(finsertindex); + while (fchangingnode <> nil) and + (finsertindex >= ttreelistitem1(fchangingnode).fcount) do begin + finsertindex:= ttreelistitem1(fchangingnode).fparentindex + 1; + fchangingnode:= ttreelistitem1(fchangingnode).fparent; + end; + end; + end; + end; +end; + +procedure ttreeitemeditlist.change(const index: integer); +begin + if (index < 0) and (nochange = 0) and + ((no_updatechildchecked in foptions) or + (no_updatechildnotchecked in foptions) or + (no_updateparentnotchecked in foptions)) then begin + inherited beginupdate; //no ils_subnodecountupdating + try + if (no_updatechildchecked in foptions) then begin + updatechildcheckedtree(); + end; + if (no_updatechildnotchecked in foptions) then begin + updatechildnotcheckedtree(); + end; + if (no_updateparentnotchecked in foptions) then begin + updateparentnotcheckedtree(); + end; + finally + decupdate; + end; + end; + inherited change(index); +end; + +procedure ttreeitemeditlist.freedata(var data); +var + int1,int2: integer; + po1: ptreelistitem; +begin + if not (ils_freelock in fitemstate) then begin + if pointer(data) <> nil then begin + with ttreelistitem1(data) do begin + int2:= findex+1; + if fowner <> nil then begin + setowner(nil); + end; + if not (ils_subnodecountupdating in self.fitemstate) then begin + int1:= int2; + while int1 < self.fcount do begin + po1:= ptreelistitem(getitempo(int1)); + if (po1^ <> nil) and + (ttreelistitem1(po1^).ftreelevel <= ftreelevel) then begin + break; //next same level node + end; + po1^:= nil; + inc(int1); + end; + self.fitemstate:= self.fitemstate + [ils_subnodecountupdating, + ils_subnodedeleting]; + if (fparent <> nil) and + ((ttreelistitem1(fparent).fowner = self) or + (fparent = frootnode)) then begin + if dls_rowdeleting in self.fstate then begin + inherited; //destroy node + end; + end + else begin + { + if not updating and not(ils_destroying in self.fitemstate) then begin + int1:= int1 - int2; + if int1 > 0 then begin + include(self.fitemstate,ils_freelock); + try + self.fowner.fgridintf.getcol.grid.deleterow(int2,int1); + finally + exclude(self.fitemstate,ils_freelock); + end; + end; + end; + } + if not (ns1_nofreeroot in fstate1) then begin + inherited; //free node + end; + end; + self.fitemstate:= self.fitemstate - [ils_subnodecountupdating, + ils_subnodedeleting]; + end; + end; + end; + end + else begin + if pointer(data) <> nil then begin + ttreelistitem1(data).findex:= -1; + end; + end; +end; + +procedure ttreeitemeditlist.writestate(const writer; const name: msestring); +var + int1,int2: integer; + po1: ^ttreelistitem1; +begin + dostatwrite(tstatwriter(writer),name); + with tstatwriter(writer) do begin + po1:= datapo; + int2:= 0; + for int1:= 0 to fcount - 1 do begin + if po1^.ftreelevel = 0 then begin + inc(int2); + end; + inc(po1); + end; + writeinteger(name,int2); + po1:= datapo; + for int1:= 0 to count - 1 do begin + if po1^.ftreelevel = 0 then begin + beginlist; + po1^.dostatwrite(tstatwriter(writer)); + endlist; + end; + inc(po1); + end; + end; +end; + +procedure ttreeitemeditlist.readstate(const reader; const acount: integer; + const aname: msestring); +type + expandedinfoty = record + item: ttreelistitem; + exp: boolean; + end; + +var + int1: integer; + po1: ^ttreelistitem1; + expanded: array of expandedinfoty; +begin + dostatread(tstatreader(reader),aname); + with tstatreader(reader) do begin + int1:= acount; + if int1 >= 0 then begin + beginupdate; + try + exclude(fitemstate,ils_subnodecountupdating); //free nodes + clear; + include(fitemstate,ils_subnodecountupdating); + count:= int1; + setlength(expanded,count); + po1:= datapo; + for int1:= 0 to count - 1 do begin + beginlist; + po1^.dostatread(tstatreader(reader)); + endlist; + if ns_expanded in po1^.fstate then begin + with expanded[int1] do begin + item:= po1^; + exp:= true; + end; + exclude(po1^.fstate,ns_expanded); + end; + inc(po1); + end; + finally + endupdate; + end; + for int1:= 0 to high(expanded) do begin + with expanded[int1] do begin + if exp then begin + item.expanded:= true; + end; + end; + end; + end; + end; +end; + +procedure ttreeitemeditlist.readnode(const aname: msestring; + const reader: tstatreader; const anode: ttreelistitem); +begin + if reader.beginlist(aname) then begin + anode.expanded:= false; //remove existing bindings + beginupdate; + try + anode.dostatread(reader); + reader.endlist; + finally + endupdate; + end; + end; +end; + +procedure ttreeitemeditlist.writenode(const aname: msestring; + const writer: tstatwriter; const anode: ttreelistitem); +begin + writer.beginlist(aname); + anode.dostatwrite(writer); + writer.endlist; +end; + +procedure ttreeitemeditlist.updatenode(const aname: msestring; + const filer: tstatfiler; const anode: ttreelistitem); +begin + if filer.iswriter then begin + writenode(aname,tstatwriter(filer),anode); + end + else begin + readnode(aname,tstatreader(filer),anode); + end; +end; + +procedure ttreeitemeditlist.assign(const root: ttreelistedititem; + const freeroot: boolean = true); +var + ar1: treelistedititemarty; + int1: integer; +begin +{$warnings off} + with ttreelistitem1(root) do begin +{$warnings on} + if fcount > 0 then begin + setlength(ar1,fcount); + for int1:= fcount-1 downto 0 do begin + ar1[int1]:= ttreelistedititem(remove(int1)); + end; + self.assign(ar1); + end + else begin + self.clear; + end; + end; + if freeroot then begin + root.Free; + end; +end; + +procedure ttreeitemeditlist.assign(const aitems: treelistedititemarty); +var + int1,int2: integer; + ar1: listitemarty; + + procedure doadd(const aitem: ttreelistedititem); + var + int1: integer; + begin + additem(pointerarty(ar1),aitem,int2); + if aitem.expanded then begin + for int1:= 0 to aitem.count-1 do begin + doadd(ttreelistedititem(aitem.fitems[int1])); + end; + end; + end; + +begin + int2:= 0; + setlength(ar1,length(aitems)); //min + int2:= 0; + for int1:= 0 to high(aitems) do begin + doadd(aitems[int1]); + end; + setlength(ar1,int2); + inherited assign(listitemarty(ar1)); +end; + +procedure ttreeitemeditlist.add(const anode: ttreelistedititem; + const freeroot: boolean = true); //adds toplevel node +var + bo1: boolean; +begin + if freeroot then begin + exclude(anode.fstate1,ns1_nofreeroot); + end + else begin + include(anode.fstate1,ns1_nofreeroot); + end; + bo1:= anode.expanded; + anode.expanded:= false; + inherited add(anode); + anode.expanded:= bo1; +end; + +procedure ttreeitemeditlist.insert(const aindex: integer; + const anode: ttreelistedititem; + const freeroot: boolean = true); +var + int1: integer; + rowbefore: integer; + n1,n2: ttreelistitem; +// po1: ptreelistitem; + bo1: boolean; + grid1: tcustomgrid; +begin +// beginupdate(); +// try + if freeroot then begin + exclude(anode.fstate1,ns1_nofreeroot); + end + else begin + include(anode.fstate1,ns1_nofreeroot); + end; + int1:= aindex; + n1:= nil; + if int1 >= count then begin + int1:= count; + if int1 > 0 then begin + n1:= items[int1-1]; + int1:= n1.parentindex+1; + end + else begin + int1:= 0; + end; + end + else begin + if int1 < 0 then begin + int1:= 0; + end; + if int1 < count then begin + n1:= items[int1]; + int1:= n1.parentindex; + end; + end; + n2:= nil; + if n1 <> nil then begin + n2:= n1.parent; + end; + if n2 = nil then begin + n2:= frootnode; + end; + bo1:= anode.expanded; + grid1:= nil; + grid1:= fintf.getgrid(); + rowbefore:= -1; + if grid1 <> nil then begin + rowbefore:= grid1.row; + if rowbefore <= aindex then begin + grid1.row:= invalidaxis; + end; + end; + anode.expanded:= false; + if n2 <> nil then begin + n2.insert(int1,anode); + if n2.owner <> self then begin + inherited insert(aindex,anode); //top level node + end; + if ns_showparentnotchecked in anode.fstate then begin + if n2.checked and not (ns1_parentnotchecked in n2.state1) then begin + exclude(anode.fstate1,ns1_parentnotchecked); + anode.doupdateparentnotcheckedstate(false); + end + else begin + include(anode.fstate1,ns1_parentnotchecked); + anode.doupdateparentnotcheckedstate(true); + end; + end; + if ns_showchildchecked in n2.state then begin + anode.updatechildcheckedstate(); + end; + if ns_showchildnotchecked in n2.state then begin + anode.updatechildnotcheckedstate(); + end; + end + else begin + inherited insert(aindex,anode); //top level node + end; + anode.expanded:= bo1; + if grid1 <> nil then begin + if (rowbefore <= aindex) and (rowbefore >= 0) then begin + grid1.row:= rowbefore+anode.rowheight; + end; + end; +// finally +// endupdate(); +// end; +end; + +procedure ttreeitemeditlist.add(const anodes: treelistedititemarty); +var + int1: integer; +begin + beginupdate; + try + for int1:= 0 to high(anodes) do begin + add(anodes[int1]); + end; + finally + endupdate; + end; +end; + +procedure ttreeitemeditlist.addchildren(const anode: ttreelistedititem); + //adds children as toplevel nodes +var + int1: integer; + po1: ptreelistedititematy; + n1: ttreelistedititem; +begin + beginupdate; + try + po1:= pointer(anode.fitems); + for int1:= 0 to anode.count-1 do begin + n1:= ttreelistedititem(po1^[int1]); + n1.settreelevel(0); + add(n1); + end; + finally + endupdate; + end; +end; + +procedure ttreeitemeditlist.add(const acount: integer; + aitemclass: treelistedititemclassty = nil); +var + int1: integer; +begin + beginupdate; + if aitemclass = nil then begin + aitemclass:= itemclass; //default + end; + try + for int1:= 0 to acount - 1 do begin + add(aitemclass.create); + end; + finally + endupdate; + end; +end; + +function ttreeitemeditlist.getoncreateitem: createtreelistitemeventty; +begin + result:= createtreelistitemeventty(oncreateobject); +end; + +procedure ttreeitemeditlist.nodenotification(const sender: tlistitem; + var ainfo: nodeactioninfoty); + + procedure expand; + var + int1,int2: integer; + grid1: tcustomgrid; + po1: ptreelistedititematy; + begin + with ttreeitemedit(fowner) do begin + if ttreelistitem1(sender).fcount > 0 then begin + fchangingnode:= ttreelistitem(sender); + int2:= sender.index+1; //list row insert position + finsertcount:= int2; //list row insert position counter + finsertindex:= 0; + int1:= ttreelistitem(sender).treeheight; + try + include(fstate,des_updating); + grid1:= fgridintf.getcol.grid; + incupdate; + try + grid1.insertrow(finsertcount,int1); + finally + decupdate; + exclude(fstate,des_updating); + end; + fintf.updateitemvalues(int2,int1); + int1:= int2+int1; + if int2 < fcount then begin + po1:= datapo; + if ils_subnodedeleting in fitemstate then begin + for int1:= int1 to fcount - 1 do begin + if po1^[int1] <> nil then begin + po1^[int1].findex:= int1; + end; + end; + end + else begin + for int1:= int1 to fcount - 1 do begin + po1^[int1].findex:= int1; + end; + end; + end; + finally + exclude(fstate,des_updating); + fchangingnode:= nil; + end; + end; + end; + end; + +var + curnode: ttreelistedititem; + newrow: integer; + ind1: integer; + po1: ptreelistitem; + + procedure scan(const anode: ttreelistedititem); + var + int1: integer; + begin + po1^:= anode; + anode.findex:= ind1; + if anode = curnode then begin + newrow:= ind1; + end; + inc(po1); + inc(ind1); + if ns_expanded in anode.fstate then begin + for int1:= 0 to anode.count-1 do begin + scan(ttreelistedititem(anode.fitems[int1])); + end; + end; + end; + +var + int1,int2: integer; + bo1: boolean; + po2: ptreelistedititematy; + i1: int32; + g1: tcustomgrid; + +begin + if ainfo.action = na_destroying then begin + int2:= sender.index; + tlistitem1(sender).setowner(nil); + if not deleting {and (ttreelistitem(sender).parent = nil)} then begin + with ttreelistitem(sender) do begin + if expanded then begin + int1:= treeheight+1; + end + else begin + int1:= 1; + end; + end; + incupdate; + include(self.fitemstate,ils_freelock); + with fowner.fgridintf.getcol.grid do begin +// if (row >= int1) and (row < int2+int1) then begin +// fowner.fvalue:= nil; //invalid +// end; + deleterow(int2,int1); + po2:= datapo; + for int1:= int2 to fcount-1 do begin + po2^[int1].findex:= int1; + end; + end; + exclude(self.fitemstate,ils_freelock); + decupdate; + end; + end + else begin + if ainfo.action in [na_expand,na_collapse] then begin +{$warnings off} + with tcustomgrid1(self.fowner.fgridintf.getcol.grid) do begin +{$warnings on} + if not(docheckcellvalue and container.canclose) then begin + ainfo.action:= na_none; + exit; + end; + end; + end; + inherited; + case ainfo.action of + na_valuechange: begin + if not updating and (ttreeitemedit(fowner).fieldedit <> nil) then begin + int1:= sender.index; + ttreeitemedit(fowner).ffieldedit[int1].valuetext:= fowner[int1].valuetext; + end; + end; + na_countchange: begin + if not updating then begin + with ttreelistitem1(sender) do begin + if ns_expanded in fstate then begin + g1:= nil; + if self.fowner <> nil then begin + g1:= self.fowner.grid; + end; + if g1 <> nil then begin + i1:= g1.row; + end; + int1:= findex+1; + if (findex < self.fcount-1) then begin + int2:= ainfo.treeheightbefore; + if ils_subnodedeleting in fitemstate then begin + dec(int2); + end; + if int2 > 0 then begin + include(self.fitemstate,ils_freelock); + {$warnings off} + with tcustomgrid1(self.fowner.fgridintf.getcol.grid) do begin + {$warnings on} + try + bo1:= gs1_autoappendlock in fstate1; + include(fstate1,gs1_autoappendlock); + if (g1 <> nil) and + (g1.row >= int1) and (g1.row > int1 + int2) then begin + g1.row:= invalidaxis; + end; + deleterow(int1,int2); + finally + if not bo1 then begin + exclude(fstate1,gs1_autoappendlock); + end; + exclude(self.fitemstate,ils_freelock); + end; + end; + end; + end; + expand; + if g1 <> nil then begin + g1.row:= i1; + end; + end; + end; + end + else begin + include(fitemstate,ils_subnodecountinvalid); + end; + end; + na_expand: begin + if not (ils_subnodecountupdating in fitemstate) then begin + expand; + with ttreeitemedit(fowner) do begin + if fvalue = sender then begin + expandedchanged(true); + end; + end; + end + else begin + include(fitemstate,ils_subnodecountinvalid); + end; + end; + na_collapse: begin + if not (ils_subnodecountupdating in fitemstate) then begin + with ttreeitemedit(fowner) do begin + include(fitemstate,ils_subnodecountupdating); + fgridintf.getcol.grid.deleterow(sender.index+1, + ttreelistitem(sender).treeheight); + exclude(fitemstate,ils_subnodecountupdating); + if fvalue = sender then begin + expandedchanged(false); + end; + end; + end + else begin + include(fitemstate,ils_subnodecountinvalid); + end; + end; + na_aftersort: begin + if not updating and ttreelistedititem(sender).rootexpanded then begin + curnode:= ttreelistedititem(ttreeitemedit(fowner).item); + newrow:= -1; + po1:= datapo; + ind1:= ttreelistedititem(sender).findex; + int2:= ind1+1; + inc(po1,ind1); + scan(ttreelistedititem(sender)); + fintf.updateitemvalues(int2,ind1-int2); + if newrow >= 0 then begin +{$warnings off} + with tcustomgrid1(fowner.fgridintf.getcol.grid) do begin +{$warnings on} + ffocusedcell.row:= newrow; + layoutchanged; + end; + end; + change(-1); + end; + end; + end; + end; +end; + +function ttreeitemeditlist.toplevelnodes: treelistedititemarty; +var + int1,int2: integer; + po1: ptreelistedititematy; +begin + result:= nil; + int2:= 0; + po1:= datapo; + for int1:= 0 to count - 1 do begin + if po1^[int1].ftreelevel = 0 then begin + additem(pointerarty(result),po1^[int1],int2); + end; + end; + setlength(result,int2); +end; + +function ttreeitemeditlist.getnodes(const must: nodestatesty; + const mustnot: nodestatesty; + const amode: getnodemodety = gno_matching): treelistitemarty; +var + int2: integer; + po1,pe: ptreelistitem; +begin + result:= nil; + int2:= 0; + po1:= datapo; + pe:= po1 + count; + while po1 < pe do begin + if (po1^.parent = nil) or (po1^.parent.owner <> self) then begin + ttreelistitem1(po1^).internalgetnodes(result,int2,must, + mustnot,amode,true); + end; + inc(po1); + end; + setlength(result,int2); +end; + +function ttreeitemeditlist.getselectednodes( + const amode: getnodemodety = gno_matching): treelistitemarty; +begin + result:= getnodes([ns_selected],[],amode); +end; + +function ttreeitemeditlist.getcheckednodes( + const amode: getnodemodety = gno_matching): treelistitemarty; +begin + result:= getnodes([ns_checked],[],amode); +end; + +procedure ttreeitemeditlist.updatechildcheckedtree; +var + po1,pe: ptreelistedititem; +begin + beginupdate; + try + po1:= datapo; + pe:= po1 + count; + while po1 < pe do begin + if po1^ <> nil then begin + with po1^ do begin + if ftreelevel = 0 then begin + updatechildcheckedtree; + end; + end; + end; + inc(po1); + end; + finally + endupdate; + end; +end; + +procedure ttreeitemeditlist.updatechildnotcheckedtree; +var + po1,pe: ptreelistedititem; +begin + beginupdate; + try + po1:= datapo; + pe:= po1 + count; + while po1 < pe do begin + if po1^ <> nil then begin + with po1^ do begin + if ftreelevel = 0 then begin + updatechildnotcheckedtree; + end; + end; + end; + inc(po1); + end; + finally + endupdate; + end; +end; + +procedure ttreeitemeditlist.updateparentnotcheckedtree; +var + int1: integer; + po1: ptreelistedititematy; +begin + beginupdate; + try + po1:= datapo; + for int1:= 0 to count - 1 do begin + with po1^[int1] do begin + if ftreelevel = 0 then begin + updateparentnotcheckedtree; + end; + end; + end; + finally + endupdate; + end; +end; + +procedure ttreeitemeditlist.expandall; +var + int1: integer; + po1: ptreelistedititematy; +begin + beginupdate; + try + po1:= datapo; + for int1:= 0 to count - 1 do begin + with po1^[int1] do begin + if ftreelevel = 0 then begin + expandall; + end; + end; + end; + finally + endupdate; + end; +end; + +procedure ttreeitemeditlist.collapseall; +var + int1: integer; + po1: ptreelistedititematy; +begin + beginupdate; + try + po1:= datapo; + for int1:= 0 to count - 1 do begin + with po1^[int1] do begin + if ftreelevel = 0 then begin + collapseall; + end; + end; + end; + finally + endupdate; + end; +end; + +procedure ttreeitemeditlist.beginupdate; +begin + if nochange = 0 then begin + include(fitemstate,ils_subnodecountupdating); + end; + inherited; +end; + +procedure ttreeitemeditlist.endupdate; +var + ar1: treelistedititemarty; +begin + ar1:= nil; //compilerwarning + if (nochange = 1) then begin + if (ils_subnodecountinvalid in fitemstate) then begin + exclude(fitemstate,ils_subnodecountinvalid); + ar1:= toplevelnodes; + include(fitemstate,ils_subnodecountupdating); + fowner.fgridintf.getcol.grid.rowcount:= 0; + clear; + exclude(fitemstate,ils_subnodecountupdating); + add(ar1); + end + else begin + exclude(fitemstate,ils_subnodecountupdating); + end; + end; + inherited; +end; + +procedure ttreeitemeditlist.setoncreateitem(const value: createtreelistitemeventty); +begin + oncreateobject:= createobjecteventty(value); +end; + +function ttreeitemeditlist.compare(const l,r): integer; +var + pathl,pathr: treelistitemarty; + int1,int2,int3: integer; +begin + pathl:= ttreelistitem(l).rootpath; + pathr:= ttreelistitem(r).rootpath; + int1:= high(pathl); + if int1 > high(pathr) then begin + int1:= high(pathr); + end; + int3:= -1; + for int2:= 0 to int1 do begin + if pathl[int2] <> pathr[int2] then begin + int3:= int2; + break; + end; + end; + if int3 >= 0 then begin + result:= inherited compare(pathl[int3],pathr[int3]); + end + else begin + result:= length(pathl) - length(pathr); + if fgridsortdescend then begin + result:= -result; + end; + end; +end; +{ +function ttreeitemeditlist.compare(const l,r): integer; +var + pathl,pathr: treelistitemarty; + int1,int2,int3: integer; +begin + pathl:= ttreelistitem(l).rootpath; + pathr:= ttreelistitem(r).rootpath; + int1:= length(pathl); + if int1 > length(pathr) then begin + int1:= length(pathr); + end; + int3:= -1; + for int2:= 0 to int1-1 do begin + if pathl[int2] <> pathr[int2] then begin + int3:= int2; + break; + end; + end; + if int3 >= 0 then begin + result:= inherited compare(pathl[int3],pathr[int3]); + end + else begin + result:= length(pathl) - length(pathr); + end; +end; +} +procedure ttreeitemeditlist.statreaditem(const reader: tstatreader; + var aitem: tlistitem); +begin + statreadtreeitem(reader,nil,ttreelistitem(aitem)); +end; + +procedure ttreeitemeditlist.statwriteitem(const writer: tstatwriter; + const aitem: tlistitem); +begin + statwritetreeitem(writer,ttreelistitem(aitem)); +end; + +function istreeitemdrag(const ainfo: draginfoty): boolean; +begin + result:= (ainfo.dragobjectpo <> nil) and + (ainfo.dragobjectpo^ is ttreeitemdragobject); +end; + +procedure ttreeitemeditlist.beforedragevent(var ainfo: draginfoty; + const arow: integer; var processed: boolean); +var + bo1: boolean; + item1: ttreelistitem; + zone1: cellzonety; +// rect1: rectty; +begin + item1:= ttreelistitem(items[arow]); + case ainfo.eventkind of + dek_begin: begin + zone1:= cz_none; + item1.updatecellzone(fowner.fgridintf.getcol.translatetocell(arow, + ainfo.clientpickpos),zone1); + if zone1 = cz_caption then begin + bo1:= item1.candrag; + if assigned(fondragbegin) then begin + fondragbegin(ttreeitemedit(fowner),item1,bo1, + ttreeitemdragobject(ainfo.dragobjectpo^),processed); + end; + if not processed and bo1 then begin + if ainfo.dragobjectpo^ = nil then begin + ttreeitemdragobject.create(ttreeitemedit(fowner),ainfo.dragobjectpo^, + ainfo.pickpos,item1); + processed:= true; + end; + end; +// if ainfo.dragobjectpo^ <> nil then begin +// ttreeitemdragobject(ainfo.dragobjectpo^).fsourcerow:= arow; +// end; + end; + end; + dek_check: begin + if istreeitemdrag(ainfo) then begin + with ttreeitemdragobject(ainfo.dragobjectpo^) do begin + if item <> item1 then begin + bo1:= item1.candrop(item); + if assigned(fondragover) then begin + fdestrow:= arow; + fondragover(ttreeitemedit(fowner),item,item1, + ttreeitemdragobject(ainfo.dragobjectpo^),bo1,processed); + ainfo.accept:= bo1; + end; + end; + end; + end; + end; + dek_drop: begin + if istreeitemdrag(ainfo) then begin + with ttreeitemdragobject(ainfo.dragobjectpo^) do begin + if (item.owner = self) and assigned(fondragdrop) then begin + fdestrow:= arow; + fondragdrop(ttreeitemedit(fowner),item,item1, + ttreeitemdragobject(ainfo.dragobjectpo^),processed); + end; + end; + end; + end; + end; +end; + +procedure ttreeitemeditlist.afterdragevent(var ainfo: draginfoty; + const arow: integer; var processed: boolean); +begin + //dummy +end; + +procedure ttreeitemeditlist.moverow(const source: integer; const dest: integer); +var + so,de,si: ttreelistitem1; + int1,int2,int3: integer; + po1: ppointeraty; + +begin + if source <> dest then begin + {$warnings off} + so:= ttreelistitem1(items[source]); + de:= ttreelistitem1(items[dest]); + si:= ttreelistitem1(de.findsibling(so)); + {$warnings on} + if si <> nil then begin + int1:= source; + if (source < dest) then begin + if si = so then begin + int3:= si.findex+1; + if si.expanded then begin + int3:= int3 + si.treeheight; + end; + if int3 < fcount then begin + {$warnings off} + si:= ttreelistitem1(items[int3]); //next equal or higher level + {$warnings on} + if si.parent <> so.parent then begin + si:= so; //invalid + end; + end; + end; + end; + if si <> so then begin + if si.fparent <> nil then begin + ttreelistitem1(si.parent).internalmove(so.parentindex,si.parentindex); + end; + int2:= si.findex; + int3:= 1; + if so.expanded then begin + int3:= int3 + so.treeheight; + if source < dest then begin + int2:= int2 - so.treeheight; + end; + end; + if si.expanded and (source < dest) then begin + int2:= int2 + si.treeheight; + end; + fowner.fgridintf.getcol.grid.moverow(int1,int2,int3); + po1:= datapo; + dec(int3); + if int2 < int1 then begin + for int1:= int2 to int1 + int3 do begin + ttreelistedititem(po1^[int1]).findex:= int1; + end; + end + else begin + for int1:= int1 to int2 + int3 do begin + ttreelistedititem(po1^[int1]).findex:= int1; + end; + end; + end; + end; + end; +end; + +function ttreeitemeditlist.getitems1(const index: integer): ttreelistedititem; +begin + result:= ttreelistedititem(inherited getitems1(index)); +end; + +procedure ttreeitemeditlist.setitems(const index: integer; + const avalue: ttreelistedititem); +begin + inherited setitems(index,avalue); +end; + +function ttreeitemeditlist.getitemclass: treelistedititemclassty; +begin + result:= treelistedititemclassty(fitemclass); +end; + +procedure ttreeitemeditlist.setitemclass(const avalue: treelistedititemclassty); +begin + fitemclass:= avalue; + itemclasschanged(); +end; + +function ttreeitemeditlist.getexpandedstate: expandedinfoarty; +var + grid: tcustomgrid; + po1: ptreelistitematy; + int1,int2: integer; +begin + result:= nil; + grid:= fintf.getgrid; + if grid <> nil then begin + setlength(result,count+1); //max + po1:= datapo; + if grid.row >= 0 then begin + result[0].path:= po1^[grid.row].rootcaptions(self); //focused row + end; + int2:= 1; + for int1:= 0 to count-1 do begin + if po1^[int1].expanded then begin + result[int2].path:= po1^[int1].rootcaptions(self); + inc(int2); + end; + end; + setlength(result,int2); + end; +end; + +procedure ttreeitemeditlist.setexpandedstate(const avalue: expandedinfoarty); +var + ar1: treelistedititemarty; + + function find(const acaption: msestring): ttreelistedititem; + var + int1: integer; + begin + result:= nil; + for int1:= 0 to high(ar1) do begin + if ar1[int1].caption = acaption then begin + result:= ar1[int1]; + break; + end; + end; + end; //find + +var + grid: tcustomgrid; + n1: ttreelistedititem; + int1,int2: integer; +begin + grid:= fintf.getgrid; + if grid <> nil then begin + grid.row:= invalidaxis; + if avalue <> nil then begin + ar1:= toplevelnodes; + for int1:= 1 to high(avalue) do begin + n1:= find(avalue[int1].path[0]); + if n1 <> nil then begin + n1.expanded:= true; + for int2:= 1 to high(avalue[int1].path) do begin + n1:= ttreelistedititem(n1.finditembycaption(avalue[int1].path[int2])); + if n1 = nil then begin + break; + end; + n1.expanded:= true; + end; + end; + end; + if (ar1 <> nil) and (avalue[0].path <> nil) then begin + n1:= find(avalue[0].path[0]); //restore focused row + if n1 <> nil then begin + int1:= n1.findex; + for int2:= 1 to high(avalue[0].path) do begin + n1:= ttreelistedititem(n1.finditembycaption(avalue[0].path[int2])); + if n1 = nil then begin + break; + end; + int1:= n1.findex; + end; + grid.row:= int1; + end; + end; + end; + end; +end; + +procedure ttreeitemeditlist.setrootnode(const avalue: ttreelistedititem); +begin + beginupdate(); + try + clear(); + frootnode:= avalue; + if frootnode <> nil then begin + frootnode.ftreelevel:= -1; + addchildren(frootnode); + end; + finally + endupdate(); + end; +end; + +procedure ttreeitemeditlist.deleteitems(index: integer; acount: integer); +var + bo1: boolean; +begin + bo1:= dls_rowdeleting in fstate; + include(fstate,dls_rowdeleting); + try + inherited; + finally + if not bo1 then begin + exclude(fstate,dls_rowdeleting); + end; + end; +end; + +procedure ttreeitemeditlist.insertitems(index: integer; acount: integer); +var + int1: integer; +begin + int1:= index; + if int1 >= count then begin + int1:= count - 1; + end; + if int1 >= 0 then begin + with items[int1] do begin + finsertparent:= ttreelistedititem(parent); + finsertparentindex:= parentindex; + end; + end + else begin + finsertparent:= rootnode; + finsertparentindex:= 0; + end; + try + inherited; + finally + finsertparent:= nil; + finsertparentindex:= -1; + end; +end; + +procedure ttreeitemeditlist.delete(const aindex: integer); +begin + ttreelistedititem(items[aindex]).expanded:= false; + fintf.getgrid.deleterow(aindex); +// deleteitems(aindex,1); +end; + +{ trecordfielditem } + +function trecordfielditem.getvalueitem: tlistitem; +begin + if fvalueitem <> nil then begin + result:= fvalueitem; + end + else begin + result:= self; + end; +end; + +procedure trecordfielditem.setvalueitem(const avalue: tlistitem); +begin + fvalueitem:= avalue; +end; + +{ trecordfielditemeditlist } + +class function trecordfielditemeditlist.defaultitemclass: listedititemclassty; +begin + result:= trecordfielditem; +end; + +{ trecordfieldedit } + +constructor trecordfieldedit.create(aowner: tcomponent); +begin + if fitemlist = nil then begin + fitemlist:= trecordfielditemeditlist.create(iitemlist(self),self); + end; + inherited; +end; + +function trecordfieldedit.getoptionsedit: optionseditty; +begin + result:= inherited getoptionsedit; + if not (csdesigning in componentstate) and (fitemedit <> nil) and + not fitemedit.valuecanedit then begin + include(result,oe_readonly); + end; +end; + +procedure trecordfieldedit.storevalue(var avalue: msestring); +begin + inherited; + if fitemedit <> nil then begin + fitemedit.setvaluetext(avalue); + end; +end; + +{ ttreeitemedit } + +constructor ttreeitemedit.create(aowner: tcomponent); +begin +// fdragcontroller:= ttreeitemdragcontroller.create(self); + if fitemlist = nil then begin + fitemlist:= ttreeitemeditlist.create(iitemlist(self),self); + end; + inherited; +// cursor:= cr_default; +end; + +destructor ttreeitemedit.destroy; +begin +// fdragcontroller.free; + inherited; +end; + +function ttreeitemedit.getdatalistclass: datalistclassty; +begin + result:= ttreeitemeditlist; +end; + +function ttreeitemedit.candragsource(const apos: pointty): boolean; +var + zone1: cellzonety; +begin + result:= item <> nil; + if result then begin + zone1:= cz_none; + item.updatecellzone(apos,zone1); + result:= zone1 = cz_caption; + end; +end; +{ +function ttreeitemedit.getitemclass: listitemclassty; +begin + result:= ttreelistedititem; +end; +} +(* +function ttreeitemedit.getkeystring1(const aindex: integer): msestring; +begin +// if (aindex < fitemlist.count) then begin +// result:= true; + with ttreelistitem1(fitemlist[aindex]) do begin + if treelevel = 0 then begin + result:= caption; + end + else begin + result:= ''; + end; + end; +// end +// else begin +// result:= false; +// end; +end; + +function ttreeitemedit.getkeystring2(const aindex: integer): msestring; +begin + with ttreelistitem1(ttreelistitem1(fvalue).fparent) do begin +// if aindex < fcount then begin + result:= fitems[aindex].caption; +// result:= true; +// end +// else begin +// result:= false; +// end; + end; +end; +*) + +function ttreeitemedit.locatecount: integer; //number of locate values +begin + if (fvalue = nil) or (ttreelistitem1(fvalue).treelevel = 0) then begin + result:= fitemlist.count; + end + else begin + result:= ttreelistitem1(ttreelistitem1(fvalue).fparent).count + end; +end; + +function ttreeitemedit.locatecurrentindex: integer; //index of current row +begin + if (fvalue = nil) or (ttreelistitem1(fvalue).treelevel = 0) then begin + result:= factiverow; + end + else begin + result:= ttreelistitem1(fvalue).fparentindex + end; +end; + +procedure ttreeitemedit.locatesetcurrentindex(const aindex: integer); +begin + if (fvalue = nil) or (ttreelistitem1(fvalue).treelevel = 0) then begin + inherited; + end + else begin + fgridintf.getcol.grid.row:= + ttreelistitem1(ttreelistitem1(ttreelistitem1(fvalue).fparent). + fitems[aindex]).findex; + end; +end; + +function ttreeitemedit.getkeystring(const aindex: integer): msestring; //locate text +begin + if (fvalue = nil) or (ttreelistitem1(fvalue).treelevel = 0) then begin + with ttreelistitem1(fitemlist[aindex]) do begin + if treelevel = 0 then begin + result:= caption; + end + else begin + result:= ''; + end; + end; + end + else begin + with ttreelistitem1(ttreelistitem1(fvalue).fparent) do begin + result:= fitems[aindex].caption; + end; + end; +end; + +(* +procedure ttreeitemedit.setfiltertext(const value: msestring); +var + int1: integer; + opt1: locatestringoptionsty; +// func1: getkeystringfuncty; +begin + if value = '' then begin + ffiltertext:= ''; + end + else begin + if oe_casesensitive in foptionsedit then begin + opt1:= [lso_casesensitive]; + end + else begin + opt1:= []; + end; + if (fvalue = nil) or (ttreelistitem1(fvalue).treelevel = 0) then begin + int1:= factiverow; + if locatestring(value,{$ifdef FPC}@{$endif}getkeystring1,opt1, + fitemlist.count,int1) then begin + with tcustomgrid1(fgridintf.getcol.grid) do begin + focuscell(makegridcoord(ffocusedcell.col,int1)); + end; + ffiltertext:= value; + end; + end + else begin + int1:= ttreelistitem1(fvalue).fparentindex; + if locatestring(value,{$ifdef FPC}@{$endif}getkeystring2,opt1, + ttreelistitem1(ttreelistitem1(fvalue).fparent).count,int1) then begin + with tcustomgrid1(fgridintf.getcol.grid) do begin + focuscell(makegridcoord(ffocusedcell.col, + ttreelistitem1(ttreelistitem1(ttreelistitem1(fvalue).fparent). + fitems[int1]).findex)); + end; + ffiltertext:= value; + end; + end; + end; + if islocating then begin + feditor.selstart:= 0; + feditor.sellength:= length(ffiltertext); + end; +end; +*) + +procedure ttreeitemedit.doupdatelayout(const nocolinvalidate: boolean); +begin + inherited; +// flayoutinfofocused.drawoptions:= ttreeitemeditlist(fitemlist).foptionsdraw; +// flayoutinfofocused.colorline:= ttreeitemeditlist(fitemlist).fcolorline; + flayoutinfofocused.boxids:= ttreeitemeditlist(fitemlist).fboxids; +end; + +{ +procedure ttreeitemedit.itemchanged(const index: integer); +var + state1: nodestatesty; + node1: ttreelistitem; +begin + inherited; + if index >= 0 then begin + node1:= ttreelistitem(fitemlist[index]); + with node1 do begin + state1:= changedstates; + if ns_expanded in state1 then begin + if ns_expanded in state then begin + factnode:= node1; + factindex:= 0; + try + fgridintf.getcol.grid.insertrow(index+1,node1.count); + finally + factnode:= nil; + end; + end + else begin + fgridintf.getcol.grid.deleterow(index+1,node1.count); + end; + end; + end; + end; +end; +} +function ttreeitemedit.getitemlist: ttreeitemeditlist; +begin + result:= ttreeitemeditlist(fitemlist); +end; + +procedure ttreeitemedit.setitemlist(const Value: ttreeitemeditlist); +begin + fitemlist.assign(value); +end; + +function ttreeitemedit.item: ttreelistedititem; +begin + result:= ttreelistedititem(fvalue); +end; + +function ttreeitemedit.getitems(const index: integer): ttreelistedititem; +begin + result:= ttreelistedititem(fitemlist[index]); +end; + +procedure ttreeitemedit.setitems(const index: integer; + const Value: ttreelistedititem); +begin + fitemlist[index]:= value; +end; +{ +procedure ttreeitemedit.sortfunc(const l, r; var result: integer); +var + pathl,pathr: treelistitemarty; + int1,int2,int3: integer; +begin + pathl:= ttreelistitem(l).rootpath; + pathr:= ttreelistitem(r).rootpath; + int1:= length(pathl); + if int1 > length(pathr) then begin + int1:= length(pathr); + end; + int3:= -1; + for int2:= 0 to int1-1 do begin + if pathl[int2] <> pathr[int2] then begin + int3:= int2; + break; + end; + end; + if int3 >= 0 then begin + while true do begin + inherited sortfunc(pathl[int3],pathr[int3],result); + if result = 0 then begin + inc(int3); + if int3 >= length(pathl) then begin + if int3 = length(pathr) then begin + break; + end + else begin + result:= -1; + end; + end + else begin + if int3 = length(pathr) then begin + result:= 1; + break; + end; + end; + end + else begin + break; + end; + end; + end; +end; +} +procedure ttreeitemedit.expandedchanged(const avalue: boolean); +var + int1: integer; +begin + with ttreelistitem1(fvalue) do begin + if avalue and (fcount > 0) then begin + int1:= treeheight+1; + with fgridintf.getcol.grid do begin + if int1 > rowsperpage then begin + showcell(makegridcoord(col,index),cep_top); + end + else begin + int1:= index+int1-1; + if rowvisible(int1) > 0 then begin + showcell(makegridcoord(col,int1),cep_bottom); + end; + end; + focuscell(makegridcoord(col,index+1)); + end; + end; + end; +end; + +procedure ttreeitemedit.setfieldedit(const avalue: trecordfieldedit); +begin + setlinkedvar(avalue,tmsecomponent(ffieldedit)); + if avalue <> nil then begin + avalue.setlinkedvar(self,tmsecomponent(avalue.fitemedit)); + end; +end; + +function ttreeitemedit.getifiitemlink: tifitreeitemlinkcomp; +begin + result:= tifitreeitemlinkcomp(getifilink1()); +end; + +procedure ttreeitemedit.setifiitemlink(const avalue: tifitreeitemlinkcomp); +begin + setifilink1(avalue); +end; + +function ttreeitemedit.checkrowmove(const curindex, + newindex: integer): boolean; +begin + if canevent(tmethod(foncheckrowmove)) then begin + result:= false; + foncheckrowmove(curindex,newindex,result); + end + else begin + result:= true; + end; +end; + +procedure ttreeitemedit.updateitemvalues(const index: integer; + const count: integer); +var + int1: integer; + po1: ptreelistedititem; +begin + if ffieldedit <> nil then begin + po1:= fitemlist.getitempo(index); + for int1:= index to index + count - 1 do begin + with tlistitem1(ffieldedit[int1]) do begin + valuetext:= po1^.valuetext; + setvalueitem(po1^); + end; + inc(po1); + end; + end; + inherited; +end; + +procedure ttreeitemedit.updateitemvalues(); +begin + inherited; +end; + +procedure ttreeitemedit.updateparentvalues(const index: integer); +var + n1: ttreelistitem; +begin + n1:= ttreelistitem(fitemlist.items[index]).parent; + while (n1 <> nil) and (n1.owner = fitemlist) do begin + updateitemvalues(n1.index,1); + n1:= n1.parent; + end; +end; + +procedure ttreeitemedit.dokeydown(var info: keyeventinfoty); +var + int1,int2: integer; + equallevelindex,atreelevel: integer; + cellbefore: gridcoordty; + +begin + doonkeydown(info); + with info do begin + if not (es_child in eventstate) and (fgridintf <> nil) and + not (es_processed in eventstate) and (fvalue <> nil) then begin + with twidgetgrid1(fgridintf.getcol.grid),ttreelistitem1(fvalue) do begin + if shiftstate = [] then begin + atreelevel:= treelevel; + equallevelindex:= -1; + cellbefore:= ffocusedcell; + if (teo_treecolnavig in self.foptions) and + not editing then begin + include(eventstate,es_processed); + case key of + key_right: begin + if expanded then begin + if count > 0 then begin + row:= row + 1; + end; + end + else begin + if (fstate * [ns_subitems,ns_drawemptyexpand] <> []) or + (no_drawemptyexpand in fitemlist.foptions) then begin + expanded:= true; + dec(cellbefore.col);//no processed reset + end; + end; + end; + key_left: begin + if ns_expanded in state then begin + expanded:= false; + dec(cellbefore.col);//no processed reset + end + else begin + if (fparent <> nil) and (fparent.owner = fitemlist) then begin + row:= fparent.index; + end; +// int1:= fitemlist.indexof(parent); +// if int1 >= 0 then begin +// row:= int1; +// end; + end; + end; + end; + end; + if teo_treerownavig in self.foptions then begin + include(eventstate,es_processed); + case key of + key_up: begin + for int1:= ffocusedcell.row - 1 downto 0 do begin + int2:= ttreelistitem(fitemlist[int1]).treelevel; + if int2 <= atreelevel then begin + equallevelindex:= int1; + break; + end; + end; + if equallevelindex >= 0 then begin + row:= equallevelindex; + end; + end; + key_down: begin + for int1:= ffocusedcell.row + 1 to frowcount - 1 do begin + int2:= ttreelistitem(fitemlist[int1]).treelevel; + if int2 = atreelevel then begin + equallevelindex:= int1; + break; + end; + if int2 < atreelevel then begin + break; + end; + end; + if equallevelindex >= 0 then begin + row:= equallevelindex; + end; + end; + end; + end; + if (ffocusedcell.row = cellbefore.row) and + (ffocusedcell.col = cellbefore.col) then begin + exclude(eventstate,es_processed); + end; + end + else begin + if (teo_keyrowmoving in foptions) and (shiftstate = [ss_ctrl]) and + ((key = key_up) or (key = key_down)) then begin + include(eventstate,es_processed); + if ((count = 0) or not expanded) then begin + if ftreelevel > 0 then begin + int1:= parentindex; + if key = key_up then begin + if (int1 > 0) and (itemlist[row].parent = itemlist[row-1].parent) and + checkrowmove(row,row-1) then begin + ttreelistitem1(fparent).internalswap(int1,int1-1); + moverow(row,row-1,1); + end; + end + else begin //key_down + if (int1 < fparent.count-1) and + (itemlist[row].parent = itemlist[row+1].parent) and + checkrowmove(row,row+1) then begin + ttreelistitem1(fparent).internalswap(int1,int1+1); + moverow(row,row+1,1); + end; + end; + end + else begin + if key = key_up then begin + if (row > 0) then begin + if ttreelistitem(itemlist[row-1]).issinglerootrow and + checkrowmove(row,row-1) then begin + moverow(row,row-1,1); + end; + end; + end + else begin //key_down + if (row < rowhigh) then begin + if ttreelistitem(itemlist[row+1]).issinglerootrow and + checkrowmove(row,row+1) then begin + moverow(row,row+1,1); + end; + end; + end; + end; + end; + showcell(focusedcell); + end; + end; + end + end; + if not (es_processed in eventstate) then begin + inherited; + end; + end; +end; + +procedure ttreeitemedit.dragdrop(const adragobject: ttreeitemdragobject); +var + bo1: boolean; + de,pa: ttreelistitem; + sourcer: integer; + destr: integer; +begin + if fgridintf <> nil then begin + with adragobject do begin + de:= items[destrow]; + pa:= de.parent; + if pa <> nil then begin + fitemlist.beginupdate; + bo1:= (item.owner = fitemlist) and + not (ils_subnodecountinvalid in fitemlist.fitemstate); + sourcer:= item.index; + pa.insert(de.parentindex,item); + if bo1 then begin + destr:= destrow; + if destr > sourcer then begin + destr:= destr + de.rowheight - 1; + end; + fgridintf.getcol.grid.moverow(sourcer,destr,item.rowheight); + exclude(fitemlist.fitemstate,ils_subnodecountinvalid); + end; + fitemlist.endupdate; + end; + end; + end; +end; + +procedure ttreeitemedit.doitembuttonpress(var info: mouseeventinfoty); +var + cellzone: cellzonety; +begin + if (info.button = mb_left) and (info.shiftstate*keyshiftstatesmask = []) and + ([teo_enteronimageclick,teo_enterondoubleclick]*foptions <> []) then begin + cellzone:= cz_none; + with ttreelistedititem(fvalue) do begin + updatecellzone(info.pos,cellzone); + if (cellzone = cz_image) and (teo_enteronimageclick in foptions) or + (teo_enterondoubleclick in foptions) and + (ss_double in info.shiftstate) then begin + expanded:= not expanded; + include(info.eventstate,es_processed); + end; + end; + end; +end; + +procedure ttreeitemedit.docellevent(const ownedcol: boolean; + var info: celleventinfoty); +begin + inherited; + if fvalue <> nil then begin + with info,ttreelistedititem(fvalue) do begin + if (eventkind = cek_enter) and (fparent <> nil) then begin + ttreelistedititem(fparent).factiveindex:= fparentindex; + end; + end; + end; +end; +{ +procedure ttreeitemedit.setdrag(const avalue: ttreeitemdragcontroller); +begin + fdragcontroller.assign(avalue); +end; +} +(* +procedure ttreeitemedit.clientmouseevent(var info: mouseeventinfoty); +begin + inherited; + { + if not (es_processed in info.eventstate) then begin + fdragcontroller.clientmouseevent(info); + end; + } +end; +*) +{ +procedure ttreeitemedit.dragevent(var info: draginfoty); +begin + if not fdragcontroller.beforedragevent(info) then begin + inherited; + end; + fdragcontroller.afterdragevent(info); +end; +} +procedure ttreeitemedit.beforecelldragevent(var ainfo: draginfoty; + const arow: integer; var processed: boolean); +begin + ttreeitemeditlist(fitemlist).beforedragevent(ainfo,arow,processed); +end; + +procedure ttreeitemedit.aftercelldragevent(var ainfo: draginfoty; + const arow: integer; var processed: boolean); +begin + ttreeitemeditlist(fitemlist).afterdragevent(ainfo,arow,processed); +end; + +function ttreeitemedit.selecteditems: treelistedititemarty; +begin + result:= treelistedititemarty(inherited selecteditems); +end; + +procedure ttreeitemedit.comparerow(const lindex: integer; + const rindex: integer; var aresult: integer); +var + pol,por: ptreelistitem; + col1: tdatacol; +begin + if fitemlist <> nil then begin + col1:= fgridintf.getcol; + pol:= fitemlist.datapo; + por:= @ppointeraty(pol)[rindex]; + pol:= @ppointeraty(pol)[lindex]; + if (col1.grid.datacols.sortcol = col1.index) or + (pol^.count = 0) and (por^.count = 0) and + (pol^.parent = por^.parent) then begin + aresult:= col1.grid.datacols.sortfunc(lindex,rindex); + end; + end; +end; +{ +procedure ttreeitemedit.updateitemvalues; +begin + inherited; +end; +} +{ +procedure ttreeitemedit.drawcell(const canvas: tcanvas); +begin + with cellinfoty(canvas.drawinfopo^) do begin + flayoutinfocell.islast:= (cell.row >= grid.rowhigh) or + (fitemlist <> nil) and + (ptreelistitem(datapo)^.treelevel = 0) or + (ptreelistitem(datapo)^.treelevel > + (ptreelistitem(datapo)+1)^.treelevel); + end; + flayoutinfofocused.islast:= flayoutinfocell.islast; + inherited; +end; +} +(* +{ ttreeitemdragcontroller } + +constructor ttreeitemdragcontroller.create(const aowner: ttreeitemedit); +begin + fowner:= aowner; + inherited create(idragcontroller(aowner)); +end; + +function ttreeitemdragcontroller.beforedragevent(var info: draginfoty): boolean; +var + bo1: boolean; + item1: ttreelistitem; +begin + result:= false; + item1:= fowner.item; + case info.eventkind of + dek_begin: begin + bo1:= item1.candrag; + if assigned(fondragbegin) then begin + fondragbegin(fowner,item1,bo1,ttreeitemdragobject(info.dragobjectpo^),result); + end; + if not result and bo1 and (info.dragobjectpo^ = nil) then begin + ttreeitemdragobject.create(fowner,info.dragobjectpo^,info.pickpos,item1); + result:= true; + end; + end; + end; +end; + +function ttreeitemdragcontroller.afterdragevent(var info: draginfoty): boolean; +begin + result:= false; +end; +*) +{ ttreeitemdragobject } + +constructor ttreeitemdragobject.create(const asender: tobject; + var instance: tdragobject; const apickpos: pointty; + const aitem: ttreelistitem); +begin + fitem:= aitem; +// fsourcerow:= invalidaxis; + fdestrow:= invalidaxis; + inherited create(asender,instance,apickpos); +end; + +{ tdirtreenode } + +procedure tdirtreenode.loaddirtree(const apath: filenamety); + + procedure doload(const anode: tdirtreenode; const apath: filenamety); + var + ar1: filenamearty; + int1: integer; + begin + ar1:= searchfiles('*',apath,[fa_dir]); + if ar1 <> nil then begin + checkfiles(ar1); + end; + with anode do begin + add(length(ar1)); + for int1:= 0 to high(ar1) do begin + fitems[int1].caption:= filename(ar1[int1]); + doload(tdirtreenode(fitems[int1]),ar1[int1]); + end; + end; + end; + +begin + beginupdate; + clear; + try + doload(self,apath); + finally + endupdate; + end; +end; + +procedure tdirtreenode.checkfiles(var afiles: filenamearty); +begin + //dummy +end; + +function tdirtreenode.path(const astart: integer = 0): filenamety; +var + ar1: treelistitemarty; + int1: integer; +begin + result:= ''; + ar1:= rootpath; + if high(ar1) >= astart then begin + result:= ar1[astart].caption; + for int1:= astart+1 to high(ar1) do begin + result:= result+'/'+ar1[int1].caption; + end; + if (result <> '') and (result <> '/') then begin + result:= result + '/'; + end; + end; +end; + +function createtitemeditlist(const aowner: twidgetcol): tdatalist; +begin + result:= titemeditlist.create; +end; + +function createtrecordfielditemeditlist(const aowner: twidgetcol): tdatalist; +begin + result:= trecordfielditemeditlist.create; +end; + +function createttreeitemeditlist(const aowner: twidgetcol): tdatalist; +begin + result:= ttreeitemeditlist.create; +end; + +{ trichlistedititem } + +function trichlistedititem.getrichcaption: richstringty; +begin + result.text:= fcaption; + result.format:= fformat; +end; + +procedure trichlistedititem.setrichcaption(const avalue: richstringty); +begin + fformat:= avalue.format; + caption:= avalue.text; +end; + +procedure trichlistedititem.updatecaption(const acanvas: tcanvas; + var alayoutinfo: listitemlayoutinfoty; var ainfo: drawtextinfoty); +begin + inherited; + ainfo.text.format:= fformat; +end; + +procedure trichlistedititem.setcaptionformat(const avalue: formatinfoarty); +begin + fformat:= avalue; + change; +end; + +{ titemclientcontroller } + +function titemclientcontroller.getitemlist(): titemeditlist; +begin + result:= nil; + if fitemedit <> nil then begin + result:= tcustomitemedit(fitemedit).itemlist; + end; +end; + +function titemclientcontroller.getitemedit: titemedit; +begin + pointer(result):= fitemedit; +end; + +function titemclientcontroller.createdatalist: tdatalist; +begin + result:= nil; +end; + +function titemclientcontroller.getlistdatatypes: listdatatypesty; +begin + result:= []; +end; + +function titemclientcontroller.getlistitem(): tlistedititem; +begin + result:= nil; + if fitemedit <> nil then begin + result:= tcustomitemedit(fitemedit).item; + end; +end; + +procedure titemclientcontroller.linkset(const alink: iificlient); +var + obj1: tobject; +begin + inherited; + obj1:= alink.getinstance; + if obj1 is tcustomitemedit then begin + setlinkedvar(tcustomitemedit(obj1),tmsecomponent(fitemedit)); + end; +end; + +{ ttreeitemclientcontroller } + +function ttreeitemclientcontroller.getlistitem(): ttreelistedititem; +begin + pointer(result):= inherited getlistitem(); +end; + +function ttreeitemclientcontroller.getitemlist(): ttreeitemeditlist; +begin + pointer(result):= inherited getitemlist(); +end; + +function ttreeitemclientcontroller.getitemedit(): ttreeitemedit; +begin + pointer(result):= fitemedit; +end; + +{ tifiitemlinkcomp } + +function tifiitemlinkcomp.getcontroller: titemclientcontroller; +begin + result:= titemclientcontroller(inherited controller); +end; + +procedure tifiitemlinkcomp.setcontroller(const avalue: titemclientcontroller); +begin + inherited setcontroller(avalue); +end; + +function tifiitemlinkcomp.getcontrollerclass: customificlientcontrollerclassty; +begin + result:= titemclientcontroller; +end; + +{ tifitreeitemlinkcomp } + +function tifitreeitemlinkcomp.getcontroller: ttreeitemclientcontroller; +begin + result:= ttreeitemclientcontroller(inherited controller); +end; + +procedure tifitreeitemlinkcomp.setcontroller( + const avalue: ttreeitemclientcontroller); +begin + inherited setcontroller(avalue); +end; + +function tifitreeitemlinkcomp.getcontrollerclass: + customificlientcontrollerclassty; +begin + result:= ttreeitemclientcontroller; +end; + +initialization + registergriddatalistclass(titemeditlist.classname, + @createtitemeditlist); + registergriddatalistclass(trecordfielditemeditlist.classname, + @createtrecordfielditemeditlist); + registergriddatalistclass(ttreeitemeditlist.classname, + @createttreeitemeditlist); +end. diff --git a/mseide-msegui/lib/common/editwidgets/mserealsumedit.pas b/mseide-msegui/lib/common/editwidgets/mserealsumedit.pas new file mode 100644 index 0000000..9ca9284 --- /dev/null +++ b/mseide-msegui/lib/common/editwidgets/mserealsumedit.pas @@ -0,0 +1,219 @@ +unit mserealsumedit; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msesumlist,msedataedits,msewidgetgrid,msedatalist,msestrings,mseeditglob, + msegrids,msegui,msemenus,msetypes,mseevent,mseguiglob,mseedit,msegraphics; + +type + + tgridrealsumlist = class(trealsumlist) + private + fowner: twidgetcol; + protected + procedure setoptions(const avalue: optionssumty); override; + function getdefault: pointer; override; + procedure setsourcevalue(const avalue: string); override; + procedure setsourcelevel(const avalue: string); override; + procedure setsourceissum(const avalue: string); override; + public + constructor create(owner: twidgetcol); reintroduce; + procedure linksource(const source: tdatalist; const atag: integer); override; + published + property sourcevalue; + property sourcelevel; + property sourceissum; + end; + + trealsumedit = class(trealedit) + private + function getsumlevel(index: integer): integer; + procedure setsumlevel(index: integer; const avalue: integer); + protected + function createdatalist(const sender: twidgetcol): tdatalist; override; + function getdatalistclass: datalistclassty; override; +// function internaldatatotext(const data): msestring; override; +// procedure valuetogrid(const arow: integer); override; + function getoptionsedit: optionseditty; override; + function internaldatatotext(const data): msestring; override; + public + function griddata: tgridrealsumlist; + property gridsumlevel[index: integer]: integer read getsumlevel + write setsumlevel; + end; + +implementation + +{ tgridrealsumlist } + +constructor tgridrealsumlist.create(owner: twidgetcol); +begin + fowner:= owner; + inherited create; + fstate:= fstate + [dls_nostreaming,dls_propertystreaming]; +end; + +function tgridrealsumlist.getdefault: pointer; +begin + result:= inherited getdefault; +end; + +procedure tgridrealsumlist.setsourcevalue(const avalue: string); +begin + inherited; + fowner.sourcenamechanged(0); +end; + +procedure tgridrealsumlist.setsourcelevel(const avalue: string); +begin + inherited; + fowner.sourcenamechanged(sumleveltag); +end; + +procedure tgridrealsumlist.setsourceissum(const avalue: string); +begin + inherited; + fowner.sourcenamechanged(2); +end; + +procedure tgridrealsumlist.setoptions(const avalue: optionssumty); +var + optionsbefore: optionssumty; +begin + if foptions <> avalue then begin + optionsbefore:= foptions; + inherited; + if osu_foldsum in + optionssumty({$ifdef FPC}longword{$else}byte{$endif}(avalue) xor + {$ifdef FPC}longword{$else}byte{$endif}(optionsbefore)) then begin + fowner.sourcenamechanged(sumleveltag); + end; + change(-1); + end; +end; + +procedure tgridrealsumlist.linksource(const source: tdatalist; + const atag: integer); +begin + if {(source = nil) and} (atag = sumleveltag) and + (osu_foldsum in options) then begin + inherited linksource(fowner.grid.datacols.rowstate,atag); + end + else begin + inherited; + end; +end; + +{ trealsumedit } + +function trealsumedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + result:= tgridrealsumlist.create(sender); +end; + +function trealsumedit.getdatalistclass: datalistclassty; +begin + result:= tgridrealsumlist; +end; + +function trealsumedit.griddata: tgridrealsumlist; +begin + checkgrid(); + result:= tgridrealsumlist(fdatalist); +end; + +function trealsumedit.getoptionsedit: optionseditty; +var + po1: prealsumty; +// datacol1: tdatacol; +// data1: tgridrealsumlist; +// int1: integer; +begin + result:= inherited getoptionsedit; + if fgridintf <> nil then begin + po1:= fgridintf.getrowdatapo; + if (po1 <> nil) then begin + if osu_foldsum in trealsumlist(fdatalist).options then begin + if (po1^.issum) then begin + include(result,oe_readonly); + end; + end + else begin + if (po1^.data.int <> 0) then begin + include(result,oe_readonly); + end; + end; + end; + end; +end; + +function trealsumedit.internaldatatotext(const data): msestring; +var + po1: prealsumty; +begin + if (fdatalist <> nil) and ([osu_sumsonly,osu_valuesonly] * + tgridrealsumlist(fdatalist).options <> []) then begin + po1:= @data; + if (po1 = nil) then begin + po1:= fgridintf.getrowdatapo; + end; + if (po1 <> nil) and ((po1^.data.int = 0) xor + (osu_valuesonly in tgridrealsumlist(fdatalist).options)) then begin + result:= ''; + exit; + end; + end; + result:= inherited internaldatatotext(data); +end; + +function trealsumedit.getsumlevel(index: integer): integer; +var + list: tdatalist; +begin + list:= checkgriddata(index); + if list <> nil then begin + result:= tgridrealsumlist(list).sumlevel[index]; + end + else begin + result:= 0; + end; +end; + +procedure trealsumedit.setsumlevel(index: integer; const avalue: integer); +var + list: tdatalist; +begin + list:= checkgriddata(index); + if list <> nil then begin + tgridrealsumlist(list).sumlevel[index]:= avalue; + fgridintf.datachange(index); + end; +end; + +{ +procedure trealsumedit.valuetogrid(const arow: integer); +begin + griddata.setgriddata(arow,fvalue); +end; +} +{ +function trealsumedit.internaldatatotext(const data): msestring; +begin + if (@data = nil) or (realsumty(data).level = 0) then begin + result:= inherited internaldatatotext(data); + end + else begin + result:= inherited internaldatatotext(realsumty(data).sum); + end; +end; +} +function createtgridrealsumlist(const aowner:twidgetcol): tdatalist; +begin + result:= tgridrealsumlist.create(aowner); +end; + +initialization + registergriddatalistclass(tgridrealsumlist.classname, + {$ifdef FPC}@{$endif}createtgridrealsumlist); + +end. diff --git a/mseide-msegui/lib/common/editwidgets/msestringlistedit.pas b/mseide-msegui/lib/common/editwidgets/msestringlistedit.pas new file mode 100644 index 0000000..2abc6e4 --- /dev/null +++ b/mseide-msegui/lib/common/editwidgets/msestringlistedit.pas @@ -0,0 +1,433 @@ +{ MSEgui Copyright (c) 1999-2006 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msestringlistedit; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + Classes,msegrids,mseinplaceedit,mseeditglob,mseevent,msegraphics,msegraphutils, + msedatalist,mserichstring,msestring,mseguiglob,msetypes; + +type + editposty = record + col,row: integer; + end; + +const + defaultstringlistcoloptions = []; + invalideditpos: editposty = (col: -1; row: -1); + +type + + tstringlistcol = class(tstringcol,iedit) + private + feditor: tinplaceedit; + feditpos: editposty; + feditcol: integer; + fstartanchor: editposty; + fendanchor: editposty; + fsel1,fsel2: editposty; + function getdata: trichstringdatalist; + procedure selectstart(const pos: editposty); + procedure selectend(const pos: editposty); + procedure clearselection; + procedure extendselection; + procedure updateselection; + protected + function getoptionsedit: optionseditty; //iedit + procedure editnotification(var info: editnotificationinfoty); virtual; + + procedure scrolled(const dist: pointty); override; + procedure fontchanged(const sender: tobject); override; + procedure dofocusedcellchanged(enter: boolean; + const cellbefore: gridcoordty; var newcell: gridcoordty; + const action: focuscellactionty); override; + procedure doactivate; override; + procedure dodeactivate; override; + procedure clientmouseevent(const acell: gridcoordty; var info: mouseeventinfoty); override; + procedure dokeyevent(var info: keyeventinfoty; up: boolean); override; + function createdatalist: tdatalist; override; + procedure drawcell(const canvas: tcanvas); override; + procedure drawfocusedcell(const canvas: tcanvas); override; + procedure itemchanged(sender: tdatalist; index: integer); override; + + public + constructor create(agrid: tcustomgrid; aowner: tgridarrayprop); override; + destructor destroy; override; + function getselection(out start,stop: editposty): boolean; + property data: trichstringdatalist read getdata; + published + property font; + end; + + tstringlistedit = class(tcustomgrid) + private + fstringlistcolindex: integer; + function gettext: trichstringdatalist; + procedure settext(const Value: trichstringdatalist); + function gettextwidth: integer; + procedure settextwidth(const Value: integer); + protected + procedure createdatacol(const index: integer; out item: tdatacol); override; + public + constructor create(aowner: tcomponent); override; + property text: trichstringdatalist read gettext write settext; + published + property textwidth: integer read gettextwidth write settextwidth default 0; + property font; + property rowcount; + end; + +function makeeditpos(col,row: integer): editposty; + +implementation +uses + SysUtils,msegui; + +type + twidget1 = class(twidget); + +function makeeditpos(col,row: integer): editposty; +begin + result.col:= col; + result.row:= row; +end; + +{ tstringlistcol } + +constructor tstringlistcol.create(agrid: tcustomgrid; + aowner: tgridarrayprop); +begin + inherited; + foptions:= defaultstringlistcoloptions; + feditor:= tinplaceedit.create(fgrid,iedit(self)); + fstartanchor:= invalideditpos; + fendanchor:= invalideditpos; + fsel1:= invalideditpos; + fsel2:= invalideditpos; +end; + +destructor tstringlistcol.destroy; +begin + feditor.Free; + ffont.free; + inherited; +end; + +procedure tstringlistcol.fontchanged(const sender: tobject); +begin + inherited; + if (sender = self) or (ffont = nil) then begin + changed; + end; +end; + +procedure tstringlistcol.dofocusedcellchanged(enter: boolean; + const cellbefore: gridcoordty; var newcell: gridcoordty; + const action: focuscellactionty); +var + rect1: rectty; +begin + if enter then begin + rect1:= fgrid.cellrect(newcell); + feditor.setup(items[newcell.row],0,false,inflaterect(rect1,-1), + rect1,data.formats[newcell.row],nil,font); + feditpos.row:= newcell.row; + if action = fca_selectend then begin + extendselection; + end; + // feditor.curindex:= feditcol; + feditor.moveindex(feditcol,action = fca_selectend); + feditor.dofocus; + end + else begin + items[cellbefore.row]:= feditor.text; + if action = fca_selectend then begin + if fstartanchor.row < 0 then begin + fstartanchor:= feditpos; + end; + end + else begin + clearselection; + end; + feditor.dodefocus; + end; + inherited; +end; + +procedure tstringlistcol.clientmouseevent(const acell: gridcoordty; + var info: mouseeventinfoty); +begin + feditor.mouseevent(info); + inherited; +end; + +procedure tstringlistcol.dokeyevent(var info: keyeventinfoty; up: boolean); +begin + if not up then begin + feditor.dokeydown(info); + end; + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; +{ +procedure tstringlistcol.dokeyup(var info: keyeventinfoty); +begin + feditor.dokeyup(info); + if not info.processed then begin + inherited; + end; +end; +} +procedure tstringlistcol.editnotification(var info: editnotificationinfoty); +begin + case info.action of + ea_indexmoved: begin + feditpos.col:= feditor.curindex; + feditcol:= feditpos.col; + if not(eas_shift in info.state) then begin + selectstart(feditpos); + end + else begin + selectend(feditpos); + end; + end; + ea_clearselection: clearselection; + ea_textedited: begin + include(fstate,cos_noinvalidate); + data.richitems[feditpos.row]:= feditor.richtext; + exclude(fstate,cos_noinvalidate); + end; + end; +end; + +function tstringlistcol.getoptionsedit: optionseditty; +begin + result:= []; //[oe_noautoselect,oe_noresetselectonexit]; +end; + +procedure tstringlistcol.drawcell(const canvas: tcanvas); +begin + ftextinfo.text.format:= data.formats[cellinfoty(canvas.drawinfopo^).cell.row]; + inherited; +end; + +procedure tstringlistcol.drawfocusedcell(const canvas: tcanvas); +var + po1: pointty; +begin + drawcellbackground(canvas); + po1:= fgrid.cellrect(cellinfoty(canvas.drawinfopo^).cell).pos; + canvas.remove(po1); + feditor.dopaint(canvas); + canvas.move(po1); +end; + +procedure tstringlistcol.scrolled(const dist: pointty); +begin + inherited; + feditor.scroll(dist); + if fgrid.active then begin + application.caret.move(dist); + end; +end; + +function tstringlistcol.createdatalist: tdatalist; +begin + result:= trichstringdatalist.create; +end; + +function tstringlistcol.getdata: trichstringdatalist; +begin + result:= trichstringdatalist(fdata); +end; + +procedure tstringlistcol.selectstart(const pos: editposty); +begin + clearselection; + fstartanchor:= pos; + fendanchor:= invalideditpos; +end; + +procedure tstringlistcol.selectend(const pos: editposty); +begin + fendanchor:= pos; + updateselection; +end; + +procedure tstringlistcol.extendselection; +begin + fendanchor:= feditpos; + updateselection; +end; + +procedure tstringlistcol.clearselection; +var + int1: integer; + po1,po2: editposty; +begin + if getselection(po1,po2) then begin + for int1:= po1.row to po2.row do begin + updatefontstyle(data.getformatpo(int1)^,0,bigint,fs_selected,false); + cellchanged(int1); + end; + end; + fstartanchor:= feditpos; + fendanchor:= invalideditpos; + fsel1:= invalideditpos; + fsel2:= invalideditpos; +end; + +procedure tstringlistcol.updateselection; + + procedure setselected1(const po1,po2: editposty; select: boolean); + var + int1: integer; + begin + int1:= po2.col - po1.col; + if po2.row > po1.row then begin + int1:= bigint; + end; + updatefontstyle(data.getformatpo(po1.row)^,po1.col,int1,fs_selected,select); + cellchanged(po1.row); + for int1:= po1.row + 1 to po2.row-1 do begin + updatefontstyle(data.getformatpo(int1)^,0,bigint,fs_selected,select); + cellchanged(int1); + end; + if po2.row > po1.row then begin + updatefontstyle(data.getformatpo(po2.row)^,0,po2.col,fs_selected,select); + cellchanged(po2.row); + end; + end; + +var + po1,po2: editposty; +begin + if getselection(po1,po2) then begin + if fsel1.row >= 0 then begin + setselected1(fsel1,po1,false); + setselected1(po2,fsel2,false); + setselected1(po1,fsel1,true); + setselected1(fsel2,po2,true); + end + else begin + setselected1(po1,po2,true); + end; + if feditpos.row >= po1.row then begin + if feditpos.row = po1.row then begin + feditor.selstart:= po1.col; + if feditpos.row = po2.row then begin + feditor.sellength:= po2.col - po1.col; + end + else begin + feditor.sellength:= length(feditor.text); + end; + end + else begin + feditor.selstart:= 0; + if feditpos.row = po2.row then begin + feditor.sellength:= po2.col; + end + else begin + feditor.sellength:= length(feditor.text); + end; + end; + end; + fsel1:= po1; + fsel2:= po2; + end; +end; + +function tstringlistcol.getselection(out start, stop: editposty): boolean; +begin + if (fstartanchor.row >= 0) and (fendanchor.row >= 0) then begin + result:= true; + if fendanchor.row < fstartanchor.row then begin + start:= fendanchor; + stop:= fstartanchor; + end + else begin + stop:= fendanchor; + start:= fstartanchor; + if fendanchor.row = fstartanchor.row then begin + if fendanchor.col < fstartanchor.col then begin + start.col:= fendanchor.col; + stop.col:= fstartanchor.col; + end; + end; + end; + end + else begin + result:= false; + end; +end; + +procedure tstringlistcol.doactivate; +begin + feditor.doactivate; + inherited; +end; + +procedure tstringlistcol.dodeactivate; +begin + feditor.dodeactivate; + inherited; +end; + +procedure tstringlistcol.itemchanged(sender: tdatalist; index: integer); +begin + if not (cos_noinvalidate in fstate) and (feditpos.row >= 0) and + ((index < 0) or (index = feditpos.row)) then begin + feditor.richtext:= data.richitems[feditpos.row]; + end; + inherited; +end; + +{ tstringlistedit } + +constructor tstringlistedit.create(aowner: tcomponent); +begin + inherited; + fstringlistcolindex:= 0; + datacols.count:= 1; +end; + +procedure tstringlistedit.createdatacol(const index: integer; + out item: tdatacol); +begin + if index = fstringlistcolindex then begin + item:= tstringlistcol.create(self,fdatacols); + item.options:= item.options + [co_fill]; + end; +end; + +function tstringlistedit.gettext: trichstringdatalist; +begin + result:= tstringlistcol(fdatacols[0]).data; +end; + +procedure tstringlistedit.settextwidth(const Value: integer); +begin + fdatacols[fstringlistcolindex].widthmin:= value; +end; + +function tstringlistedit.gettextwidth: integer; +begin + result:= fdatacols[fstringlistcolindex].widthmin; +end; + +procedure tstringlistedit.settext(const Value: trichstringdatalist); +begin + tstringlistcol(fdatacols[0]).data.assign(value); +end; + +end. diff --git a/mseide-msegui/lib/common/editwidgets/mseterminal.pas b/mseide-msegui/lib/common/editwidgets/mseterminal.pas new file mode 100644 index 0000000..9e0c254 --- /dev/null +++ b/mseide-msegui/lib/common/editwidgets/mseterminal.pas @@ -0,0 +1,848 @@ +{ MSEgui Copyright (c) 1999-2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseterminal; + +{$ifdef FPC}{$mode objfpc}{$h+}{$goto on}{$endif} + +interface +uses + msetypes,msegrids,classes,mclasses,msestream,mseclasses,msepipestream,mseevent, + mseinplaceedit,mserichstring, + msetextedit,msestrings,msesys,mseeditglob,msemenus,msegui,mseguiglob, + mseprocess,msegridsglob,mseedit,mseglob,msewidgetgrid,msegraphics; +type + sendtexteventty = procedure(const sender: tobject; + var atext: msestring; var donotsend: boolean) of object; + receivetexteventty = procedure(const sender: tobject; + var atext: ansistring; const errorinput: boolean) of object; + terminaloptionty = (teo_readonly,teo_bufferchunks,teo_stripescsequence, + teo_utf8); + terminaloptionsty = set of terminaloptionty; +const + defaultterminaleditoptions = (defaulttexteditoptions + [oe_caretonreadonly])- + [oe_linebreak]; + defaultterminaloptions = [{teo_tty}]; + defaultoptionsprocess = [pro_output,pro_errorouttoout,pro_input, + pro_winpipewritehandles,pro_inactive,pro_tty,pro_ctrlc]; +type +// terminalstatety = ({ts_running,}ts_listening); +// terminalstatesty = set of terminalstatety; + + + tterminal = class(tcustomtextedit,igridwidget) + private + foninputpipebroken: notifyeventty; + fonerrorpipebroken: notifyeventty; + finputcolindex: integer; + fonsendtext: sendtexteventty; + fonreceivetext: receivetexteventty; + foptions: terminaloptionsty; + fmaxchars: integer; + fupdatingcount: integer; + fonprocfinished: notifyeventty; + fmaxcommandhistory: integer; + fcommandhistory: msestringarty; + fhistoryindex: integer; + fprocess: tcustommseprocess; + function getinputfd: integer; + procedure setinoutfd(const Value: integer); + procedure setoptions(const avalue: terminaloptionsty); + function getoutputfd: integer; + procedure setoutputfd(const avalue: integer); + function geterrorfd: integer; + procedure seterrorfd(const avalue: integer); + function getoptionsprocess: processoptionsty; + procedure setoptionsprocess(const avalue: processoptionsty); + procedure setmaxcommandhistory(const avalue: integer); + function getcommand: msestring; + procedure setcommand(const avalue: msestring); + function getpipewaitus: integer; + procedure setpipewaitus(const avalue: integer); + function getprompt: msestring; + procedure setprompt(const avalue: msestring); + procedure setprocess(const avalue: tcustommseprocess); + protected + finternalprocess: tcustommseprocess; + procedure linkprocess(const aprocess: tcustommseprocess); + procedure unlinkprocess(const aprocess: tcustommseprocess); + function curprocess: tcustommseprocess; + procedure setreadonly1(const avalue: boolean); + procedure igridwidget.setreadonly = setreadonly1; + procedure setreadonly(const avalue: boolean); override; + procedure doinputavailable(const sender: tpipereader); + procedure dopipebroken(const sender: tpipereader); + procedure doprocfinished(const sender: tobject); + function echoisoff: boolean; + function echooff(out aechoisoff: boolean): boolean; + procedure echoon(const avalue: boolean); + procedure dokeydown(var info: keyeventinfoty); override; + procedure editnotification(var info: editnotificationinfoty); override; + procedure docellevent(const ownedcol: boolean; + var info: celleventinfoty); override; + procedure updateeditpos; +// function stripescapesequences(avalue: msestring): msestring; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function prochandle: integer; + function execprog(const acommandline: msestring; + const aworkingdirectory: filenamety = ''; + const aparams: msestringarty = nil; + const aenvvars: msestringarty = nil): integer; + //returns prochandle + procedure terminateprocess; + procedure killprocess; + function waitforprocess: integer; //returns exitcode + function exitcode: integer; + function running: boolean; + procedure addchars(const avalue: msestring); virtual; + procedure addline(const avalue: msestring); //thread safe + procedure writestr(const atext: string); + procedure writestrln(const atext: string); + property inputfd: integer read getinputfd write setinoutfd; + property outputfd: integer read getoutputfd write setoutputfd; + property errorfd: integer read geterrorfd write seterrorfd; + procedure beginupdate; override; + procedure endupdate; override; + property prompt: msestring read getprompt write setprompt; + property command: msestring read getcommand write setcommand; + property commandhistory: msestringarty read fcommandhistory + write fcommandhistory; + property inputcolindex: integer read finputcolindex write finputcolindex; + published + property process: tcustommseprocess read fprocess write setprocess; + //replaces internal process, + //event properties in source will be owerwritten + property optionsedit1; //before optionsedit! + property optionsedit default defaultterminaleditoptions; + property font; + property cursorreadonly; + property maxchars: integer read fmaxchars write fmaxchars default 0; + property maxcommandhistory: integer read fmaxcommandhistory + write setmaxcommandhistory default 0; + property tabulators; + + property caretwidth; + property textflags; + property textflagsactive; + + property marginlinepos; + //offset to innerclientrect.x + property marginlinecolor; + + property onchange; + property ontextedited; + property onkeydown; + property onkeyup; + property oncopytoclipboard; + property onpastefromclipboard; + + property statfile; + property statvarname; + property statpriority; + property encoding; + + property onfontchanged; + property onmodifiedchanged; + property ontextmouseevent; + property oneditnotifcation; + property oncellevent; + property ondrawtext; + property onsetupeditor; + + property oninputpipebroken: notifyeventty read foninputpipebroken + write foninputpipebroken; + property onerrorpipebroken: notifyeventty read fonerrorpipebroken + write fonerrorpipebroken; + property onprocfinished: notifyeventty + read fonprocfinished write fonprocfinished; + + property onsendtext: sendtexteventty read fonsendtext write fonsendtext; + property onreceivetext: receivetexteventty read fonreceivetext + write fonreceivetext; + property options: terminaloptionsty read foptions write setoptions + default defaultterminaloptions; + property optionsprocess: processoptionsty read getoptionsprocess + write setoptionsprocess default defaultoptionsprocess; + property pipewaitus: integer read getpipewaitus write setpipewaitus + default defaultpipewaitus; + end; + +implementation +uses + msesysutils,mseprocutils,msewidgets,mseprocmonitor, + msekeyboard,sysutils,msesysintf,rtlconsts,msegraphutils,msearrayutils, + msesysintf1,msedatalist + {$ifdef unix},mselibc{$endif}; +type + tinplaceedit1 = class(tinplaceedit); + +{ tterminal } + +constructor tterminal.create(aowner: tcomponent); +begin + foptions:= defaultterminaloptions; +// fhistoryindex:= -1; + inherited; + optionsedit:= defaultterminaleditoptions; + finternalprocess:= tcustommseprocess.create(nil); + linkprocess(finternalprocess); + with finternalprocess do begin + output.overloadsleepus:= 50000; + erroroutput.overloadsleepus:= 50000; + options:= defaultoptionsprocess; +// options:= [pro_output,pro_erroroutput,pro_input,pro_tty]; + end +end; + +destructor tterminal.destroy; +begin + process:= nil; //unlink + finternalprocess.free; + inherited; +end; + +procedure tterminal.linkprocess(const aprocess: tcustommseprocess); +begin + if not (csdesigning in componentstate) then begin + with aprocess do begin + output.oninputavailable:= @doinputavailable; + output.onpipebroken:= @dopipebroken; + erroroutput.oninputavailable:= @doinputavailable; + erroroutput.onpipebroken:= @dopipebroken; + onprocfinished:= @doprocfinished; + end; + end; +end; + +procedure tterminal.unlinkprocess(const aprocess: tcustommseprocess); +begin + if not (csdesigning in componentstate) then begin + with aprocess do begin + output.oninputavailable:= nil; + output.onpipebroken:= nil; + erroroutput.oninputavailable:= nil; + erroroutput.onpipebroken:= nil; + onprocfinished:= nil; + end; + end; +end; + +function tterminal.curprocess: tcustommseprocess; +begin + result:= fprocess; + if result = nil then begin + result:= finternalprocess; + end; +end; + +procedure tterminal.docellevent(const ownedcol: boolean; + var info: celleventinfoty); +begin + case info.eventkind of + cek_enter: begin + if (info.newcell.row = fgridintf.getcol.grid.rowhigh) and + not (teo_readonly in foptions) then begin + optionsedit:= optionsedit - [oe_readonly]; + end + else begin + optionsedit:= optionsedit + [oe_readonly]; + end; + end; + end; + inherited; +end; + +function tterminal.getprompt: msestring; +var + int1: integer; +begin + result:= ''; + if fgridintf <> nil then begin + int1:= fgridintf.getcol.grid.rowhigh; + if int1 >= 0 then begin + result:= copy(gridvalue[int1],0,finputcolindex); + end; + end; +end; + +procedure tterminal.setprompt(const avalue: msestring); +//var +// mstr1: msestring; +begin + if fgridintf <> nil then begin + with fgridintf.getcol.grid do begin + if rowhigh >= 0 then begin + gridvalue[rowhigh]:= avalue + + copy(gridvalue[rowhigh],finputcolindex+1,bigint); + finputcolindex:= length(avalue); + flines.feditcharindex:= finputcolindex; + if row = rowhigh then begin + feditor.curindex:= bigint; + end; + end; + end; + end; +end; + +procedure tterminal.setprocess(const avalue: tcustommseprocess); +begin + if fprocess <> nil then begin + unlinkprocess(fprocess); + end; + fprocess:= avalue; + if fprocess <> nil then begin + linkprocess(fprocess); + end; +end; + +function tterminal.getcommand: msestring; +var + int1: integer; +begin + result:= ''; + if fgridintf <> nil then begin + int1:= fgridintf.getcol.grid.rowhigh; + if int1 >= 0 then begin + result:= copy(gridvalue[int1],finputcolindex+1,bigint); + end; + end; +end; + +procedure tterminal.setcommand(const avalue: msestring); +//var +// int1: integer; +begin + if fgridintf <> nil then begin + with fgridintf.getcol.grid do begin + if rowhigh >= 0 then begin + gridvalue[rowhigh]:= copy(gridvalue[rowhigh],1,finputcolindex)+avalue; + if row = rowhigh then begin + feditor.curindex:= bigint; + end; + end; + end; + end; +end; + +procedure tterminal.editnotification(var info: editnotificationinfoty); +var + mstr1: msestring; + bo1,bo2,bo3: boolean; + ar1: msestringarty; + int1: integer; +begin + if fgridintf <> nil then begin + with fgridintf.getcol.grid do begin + case info.action of + ea_textedited: begin + if echoisoff then begin + feditor.format:= updatefontstyle(feditor.format, + finputcolindex,bigint,fs_blank,true); + end; + end; + ea_indexmoved: begin + if editpos.row = datalist.count - 1 then begin + if (editpos.col < finputcolindex) or (teo_readonly in foptions) then begin + optionsedit:= optionsedit + [oe_readonly]; + end + else begin + optionsedit:= optionsedit - [oe_readonly]; + end; + end; + end; + ea_delchar: begin + if (info.dir = gd_left) and (editpos.col <= finputcolindex) then begin + info.action:= ea_none; + end; + end; + ea_textentered: begin + if (row = rowhigh) and not (teo_readonly in foptions) then begin + info.action:= ea_none; + mstr1:= copy(feditor.text,finputcolindex+1,bigint); + if (fmaxcommandhistory > 0) and not running then begin + fhistoryindex:= 0; + if((fcommandhistory = nil) or (fcommandhistory[0] <> mstr1)) then begin + if (fcommandhistory = nil) then begin + setlength(fcommandhistory,1); + end; + fcommandhistory[0]:= mstr1; + insertitem(fcommandhistory,0,''); + if length(fcommandhistory) > fmaxcommandhistory then begin + setlength(fcommandhistory,fmaxcommandhistory); + end; + end; + end; + bo1:= false; + if assigned(fonsendtext) then begin + fonsendtext(self,mstr1,bo1); + end; + if not bo1 then begin + bo2:= echooff(bo3); + try + if teo_utf8 in foptions then begin + curprocess.input.pipewriter.writeln(stringtoutf8ansi(mstr1)); + end + else begin + curprocess.input.pipewriter.writeln(mstr1); + end; + if not bo3 then begin + datalist.add(''); + end; + except + feditor.text:= ''; + gridvalue[row]:= copy(gridvalue[row],1,finputcolindex); + end; + echoon(bo2); + end; +// else begin +// datalist.add(''); +// end; + updateeditpos; + end; + end; + ea_pasteselection: begin + if msewidgets.pastefromclipboard(mstr1,info.bufferkind) then begin + clearselection; + ar1:= breaklines(mstr1); + if high(ar1) >= 0 then begin +// datalist[rowhigh]:= datalist[rowhigh] + ar1[0]; + editor.inserttext(ar1[0],false); + for int1:= 1 to high(ar1) do begin + tinplaceedit1(editor).checkaction(ea_textentered); + datalist[rowhigh]:= ar1[int1]; + end; + if high(ar1) > 0 then begin + editpos:= makegridcoord(length(datalist[rowhigh]),rowhigh); + end; + end; +// editpos:= makegridcoord(length(datalist[rowhigh]),rowhigh); + end; + info.action:= ea_none; + end; + end; + if info.action <> ea_none then begin + inherited; + end; + end; + end; +end; + +function tterminal.echoisoff: boolean; +{$ifdef unix} +var + terminfo: termios; +{$endif} +begin + result:= false; +{$ifdef unix} + if (pro_echo in curprocess.options) and running and + (msetcgetattr(outputfd,terminfo) = 0) then begin + result:= terminfo.c_lflag and echo = 0; + end; +{$endif} +end; + +function tterminal.echooff(out aechoisoff: boolean): boolean; +{$ifdef unix} +var + terminfo: termios; +{$endif} +begin + result:= false; + aechoisoff:= false; +{$ifdef unix} + if (pro_echo in curprocess.options) and running and + (msetcgetattr(outputfd,terminfo) = 0) then begin + result:= terminfo.c_lflag and echo <> 0; + aechoisoff:= not result; + if result then begin + tcdrain(outputfd); + usleep(0); //why is this necessary? no tcdrain without + terminfo.c_lflag:= terminfo.c_lflag and not echo; + msetcsetattr(outputfd,tcsadrain,terminfo); + end; + end; +{$endif} +end; + +procedure tterminal.echoon(const avalue: boolean); +{$ifdef unix} +var + terminfo: termios; +{$endif} +begin +{$ifdef unix} + if avalue and (msetcgetattr(inputfd,terminfo) = 0) then begin + terminfo.c_lflag:= terminfo.c_lflag or echo; + tcdrain(outputfd); + usleep(0); //why is this necessary? no tcdrain without + msetcsetattr(outputfd,tcsadrain,terminfo); + end; +{$endif} +end; + +procedure tterminal.dokeydown(var info: keyeventinfoty); +begin + if fgridintf <> nil then begin + with info do begin + if (key = key_c) and (shiftstate = [ss_ctrl]) and + (pro_ctrlc in optionsprocess) and running then begin + command:= '^C'; + finputcolindex:= finputcolindex + 2; + include(info.eventstate,es_processed); + try + curprocess.terminate; + except + curprocess.kill; + end; + end + else begin + if shiftstate - [ss_shift] = [] then begin + if (chars <> '') and + ((editpos.row < datalist.count - 1) or + (editpos.col < finputcolindex)) then begin + editpos:= makegridcoord(bigint,bigint); + end + else begin + if (key = key_home) and (editpos.row = datalist.count - 1) then begin + editor.moveindex(finputcolindex,ss_shift in shiftstate); + include(eventstate,es_processed); + end; + end; + end; + if not (es_processed in info.eventstate) then begin + if (fmaxcommandhistory > 0) and not running then begin + include(info.eventstate,es_processed); + case key of + key_up,key_down: begin + if fcommandhistory = nil then begin + setlength(fcommandhistory,1); + fhistoryindex:= 0; + end; + fcommandhistory[fhistoryindex]:= command; + if key = key_up then begin + if fhistoryindex < high(fcommandhistory) then begin + inc(fhistoryindex); + end; + end + else begin + if fhistoryindex > 0 then begin + dec(fhistoryindex); + end; + end; + command:= fcommandhistory[fhistoryindex]; + end; + else begin + exclude(info.eventstate,es_processed); + end; + end; + if (es_processed in eventstate) and (fgridintf <> nil) then begin + fgridintf.getcol.grid.row:= bigint; + feditor.curindex:= bigint; + if not (teo_readonly in foptions) then begin + optionsedit:= optionsedit - [oe_readonly]; + end; + end; + end; + end; + if not (es_processed in eventstate) then begin + inherited; + end; + end; + end; + end; +end; + +procedure tterminal.updateeditpos; +var + int1: integer; +begin + if (fgridintf <> nil) and (fupdatingcount = 0) then begin + int1:= datalist.count-1; + if int1 >= 0 then begin + finputcolindex:= length(datalist[int1]); + end; + editpos:= makegridcoord(finputcolindex,int1); + end; +end; + +procedure tterminal.doinputavailable(const sender: tpipereader); +var + str1: string; + int1: integer; +begin + try + if teo_bufferchunks in foptions then begin + str1:= sender.readbuffer; + end + else begin + str1:= sender.readdatastring; + end; + if not (csdestroying in componentstate) then begin + if canevent(tmethod(fonreceivetext)) then begin + fonreceivetext(self,str1,sender = curprocess.erroroutput.pipereader); + end; + if teo_utf8 in foptions then begin + addchars(utf8tostringansi(str1)); + end + else begin + addchars(msestring(str1)); + end; + if teo_bufferchunks in foptions then begin + int1:= application.unlockall; + sleepus(0); //sched_yield + application.relockall(int1); + end; + end; + except + end; +end; + +procedure tterminal.addchars(const avalue: msestring); +var + mstr1: msestring; +begin + if fgridintf <> nil then begin + if datalist.count > 0 then begin + mstr1:= datalist[datalist.count-1]; + if length(mstr1) > finputcolindex then begin + datalist[datalist.count-1]:= copy(mstr1,1,finputcolindex); + //remove entered characters + end; + end; + if teo_stripescsequence in foptions then begin + mstr1:= stripescapesequences(avalue); + end + else begin + mstr1:= avalue; + end; + datalist.addchars(mstr1,[aco_processeditchars],fmaxchars); + if window.haswinid then begin //possible deadlock by synchronize() otherwise + updateeditpos; + end; + end; +end; + +procedure tterminal.addline(const avalue: msestring); +begin + if fgridintf <> nil then begin + application.lock; + try + addchars(avalue+lineend); + finally + application.unlock; + end; + end; +end; + +procedure tterminal.dopipebroken(const sender: tpipereader); +begin + if sender = curprocess.output.pipereader then begin + if canevent(tmethod(foninputpipebroken)) then begin + foninputpipebroken(self); + end; + end + else begin + if canevent(tmethod(fonerrorpipebroken)) then begin + fonerrorpipebroken(self); + end; + end; +end; + +procedure tterminal.doprocfinished(const sender: tobject); +begin + if canevent(tmethod(fonprocfinished)) then begin + fonprocfinished(self); + end; +end; + +function tterminal.execprog(const acommandline: msestring; + const aworkingdirectory: filenamety = ''; + const aparams: msestringarty = nil; + const aenvvars: msestringarty = nil): integer; +begin + with curprocess do begin + active:= false; +// if active then begin +// componentexception(self,'Process already active.'); +// end; + commandline:= acommandline; + workingdirectory:= aworkingdirectory; + params.asarray:= aparams; + envvars.asarray:= aenvvars; + active:= true; + result:= lastprochandle; + end; +end; + +function tterminal.getinputfd: integer; +begin + result:= curprocess.output.pipereader.handle; +end; + +function tterminal.prochandle: integer; +begin + result:= curprocess.prochandle; +end; + +procedure tterminal.setinoutfd(const Value: integer); +begin + curprocess.output.pipereader.handle:= value; +end; + +function tterminal.waitforprocess: integer; +begin + result:= curprocess.waitforprocess; +end; + +function tterminal.exitcode: integer; +begin + result:= curprocess.exitcode; +end; + +function tterminal.running: boolean; +begin + result:= curprocess.running; +end; + +procedure tterminal.setoptions(const avalue: terminaloptionsty); +begin + foptions:= avalue; + if (teo_readonly in foptions) then begin + optionsedit:= optionsedit + [oe_readonly]; + end; +end; + +function tterminal.getoutputfd: integer; +begin + result:= curprocess.input.pipewriter.handle; +end; + +procedure tterminal.setoutputfd(const avalue: integer); +begin + curprocess.input.pipewriter.handle:= avalue; +end; + +function tterminal.geterrorfd: integer; +begin + result:= curprocess.erroroutput.pipereader.handle; +end; + +procedure tterminal.seterrorfd(const avalue: integer); +begin + curprocess.erroroutput.pipereader.handle:= avalue; +end; + +procedure tterminal.writestr(const atext: string); +var + bo1,bo2: boolean; +begin + bo1:= echooff(bo2); + try + if sys_write(outputfd,pointer(atext),length(atext)) <> length(atext) then begin + syserror(syelasterror); + end; + finally + echoon(bo1); + end; +end; + +procedure tterminal.writestrln(const atext: string); +begin + writestr(atext+lineend); +end; +{ +function tterminal.getonprocfinished: notifyeventty; +begin + result:= fprocess.onprocfinished; +end; + +procedure tterminal.setonprocfinished(const avalue: notifyeventty); +begin + fprocess.onprocfinished:= avalue; +end; +} +procedure tterminal.terminateprocess; +begin + curprocess.terminate; +end; + +procedure tterminal.killprocess; +begin + curprocess.kill; +end; + +function tterminal.getoptionsprocess: processoptionsty; +begin + result:= finternalprocess.options; +end; + +procedure tterminal.setoptionsprocess(const avalue: processoptionsty); +begin + finternalprocess.options:= avalue; +end; + +procedure tterminal.beginupdate; +begin + inc(fupdatingcount); + inherited; +end; + +procedure tterminal.endupdate; +begin + try + inherited; + finally + dec(fupdatingcount); + if fupdatingcount = 0 then begin + updateeditpos; + end; + end; +end; + +procedure tterminal.setmaxcommandhistory(const avalue: integer); +begin + fmaxcommandhistory:= avalue; + if length(fcommandhistory) > avalue then begin + setlength(fcommandhistory,avalue); + end; + if fhistoryindex > high(fcommandhistory) then begin + fhistoryindex:= high(fcommandhistory); + end; +end; + +function tterminal.getpipewaitus: integer; +begin + result:= finternalprocess.pipewaitus; +end; + +procedure tterminal.setpipewaitus(const avalue: integer); +begin + finternalprocess.pipewaitus:= avalue; +end; + +procedure tterminal.setreadonly(const avalue: boolean); +begin + if avalue then begin + options:= options + [teo_readonly]; + end + else begin + options:= options - [teo_readonly]; + end; + inherited; +end; + +procedure tterminal.setreadonly1(const avalue: boolean); +begin + //dummy for igridwidget +end; + +end. diff --git a/mseide-msegui/lib/common/editwidgets/msetextedit.pas b/mseide-msegui/lib/common/editwidgets/msetextedit.pas new file mode 100644 index 0000000..40fe4d1 --- /dev/null +++ b/mseide-msegui/lib/common/editwidgets/msetextedit.pas @@ -0,0 +1,2834 @@ +{ MSEgui Copyright (c) 1999-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msetextedit; + +{$ifdef FPC} + {$mode objfpc}{$h+}{$interfaces corba} +{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} + +interface +uses + mseeditglob,mseedit,msewidgetgrid,classes,mclasses,msedatalist, + msegraphics,msestream,msedragglob,msesys,mseassistiveclient, + msetypes,mserichstring,msestat,msestatfile,mseclasses,mseinplaceedit,msegrids, + mseevent,mseguiglob,msegui,msegraphutils,msestrings,msedrawtext,msearrayprops, + msemenus,msepointer,msegridsglob{$ifdef mse_with_ifi},mseificomp{$endif}, + mseglob; + +const + + defaulttexteditoptions = (defaultoptionsedit + + [oe_linebreak,oe_nofirstarrownavig]) - + [oe_autoselect,oe_autoselectonfirstclick,oe_endonenter, + oe_resetselectonexit,oe_undoonesc,oe_shiftreturn, + oe_trimleft,oe_trimright,oe_uppercase,oe_lowercase]; + + texteditminimalframe: framety = (left: 1; top: 0; right: 1; bottom: 0); + defaulttexteditwidgetoptions = + (defaulteditwidgetoptions + { - [ow_fontglyphheight]}){ + [ow_fontlineheight]}; + defaulttexteditwidgetoptions1 = + (defaulteditwidgetoptions1 - [ow1_fontglyphheight]) + + [ow1_fontlineheight]; + +type + + textmouseeventinfoty = record + eventkind: celleventkindty; + mouseeventinfopo: pmouseeventinfoty; + pos: gridcoordty; + end; + + tcustomtextedit = class; + textmouseeventty = procedure(const sender: tobject; + var info: textmouseeventinfoty) of object; + textdraweventty = procedure(const sender: tcustomtextedit; + const canvas: tcanvas; const atext: richstringty; + const cellinfo: pcellinfoty; var handled: boolean) of object; + //cellinfo = nil for focused widget + setupeditoreventty = procedure(const sender: tcustomtextedit) of object; + + texteditstatety = (tes_selectinvalid,tes_cellentering,tes_xposinvalid); + texteditstatesty = set of texteditstatety; + + tgridrichstringdatalist = class(trichstringdatalist) + private + fowner: twidgetcol; + protected + function getdefault: pointer; override; + public + constructor create(owner: twidgetcol); reintroduce; + end; + + texteditoptionty = (teeo_bom,teeo_nobom); //[] -> use loaded + texteditoptionsty = set of texteditoptionty; + + tcustomtextedit = class(tcustomedit,igridwidget,istatfile, + iassistiveclientgridwidget) + private + fstatfile: tstatfile; + fstatvarname: msestring; + fselectstart,fselectend: gridcoordty; + fmodified: boolean; + fonmodifiedchanged: booleanchangedeventty; + fontextmouseevent: textmouseeventty; + fmousetextpos: gridcoordty; + foneditnotification: editnotificationeventty; + foncellevent: celleventty; + fonfontchanged: notifyeventty; + fmarginlinecolor: colorty; + fmarginlinepos: integer; + ftabulators: ttabulators; + fencoding: charencodingty; + fxpos: integer; + fstatpriority: integer; + fhasbom: boolean; + foptions: texteditoptionsty; + feolstyle: eolstylety; + fondrawtext: textdraweventty; + fonsetupeditor: setupeditoreventty; + procedure setstatfile(const Value: tstatfile); + function geteditpos: gridcoordty; + procedure seteditpos1(const value: gridcoordty); + function getgridvalue(const index: integer): msestring; + procedure setgridvalue(const index: integer; const Value: msestring); + function getgridvalues: msestringarty; + procedure setgridvalues(const Value: msestringarty); + function getrichlines(const index: integer): richstringty; + procedure setrichlines(const index: integer; const Value: richstringty); + function getrichformats(const index: integer): formatinfoarty; + procedure setrichformats(const index: integer; const avalue: formatinfoarty); + procedure setmodified(const avalue: boolean); + procedure setdatalist(const avalue: tgridrichstringdatalist); + + procedure mousepostotextpos1(const row: integer; const mousepos: pointty; + var textpos: gridcoordty; var result: boolean); + procedure setmarginlinecolor(avalue: colorty); + procedure setmarginlinepos(const avalue: integer); + procedure colchanged; + function gettabulators: ttabulators; + procedure settabulators(const Value: ttabulators); +// procedure setreadonly(const avalue: boolean); + function getrow: integer; + procedure setrow(const avalue: integer); + function getcol: integer; + procedure setcol(const avalue: integer); + procedure setoptions(const avalue: texteditoptionsty); + protected + ftextstate: texteditstatesty; + fgridintf: iwidgetgrid; + fupdating: integer; + fnotificationchangelock: integer; + ffilename: filenamety; + ffilerights: filerightsty; + flines: tgridrichstringdatalist; + ffoundeolstyle: eolstylety; + procedure setoptionsedit(const avalue: optionseditty); override; + procedure setoptionsedit1(const avalue: optionsedit1ty); override; + + function beforechange: boolean; //true if not aborted + procedure fontchanged; override; + procedure tabulatorschanged(const sender: tarrayprop; const index: integer); + procedure painttext(const canvas: tcanvas); override; + procedure dobeforepaintforeground(const canvas: tcanvas); override; + procedure dokeydown(var info: keyeventinfoty); override; + procedure getstate(out state: texteditstatety); virtual; + procedure setstate(const state: texteditstatety); virtual; + procedure setfilename(value: filenamety); //no const! + procedure insertlinebreak; virtual; + procedure editnotification(var info: editnotificationinfoty); override; + procedure updateindex(select: boolean); + procedure textinserted(const apos: gridcoordty; + const atext: msestring; const selected: boolean; + const endpos: gridcoordty; const backwards: boolean); virtual; + procedure textdeleted(const apos: gridcoordty; + const atext: msestring; const selected: boolean; + const endpos: gridcoordty; const backwards: boolean); virtual; + + procedure dotextmouseevent(var info: textmouseeventinfoty); + procedure dosetupeditor(); + procedure setupeditor; override; + procedure dofontheightdelta(var delta: integer); override; + procedure sizechanged; override; + function getinnerframe: framety; override; + function textclipped(const arow: integer; + out acellrect: rectty): boolean; virtual; + function textclipped(const arow: integer): boolean; + + function getiassistiveclient(): iassistiveclient override; + //iassistiveclientgridwidget + function getassistivecolumncaption(): msestring virtual; + //igridwidget + procedure setfirstclick(var ainfo: mouseeventinfoty); + function createdatalist(const sender: twidgetcol): tdatalist; virtual; + procedure datalistdestroyed; + function getdatalistclass: datalistclassty; virtual; + function getinitvalue: pointer; + function getdefaultvalue: pointer; + function getrowdatapo(const arow: integer): pointer; virtual; + procedure setgridintf(const intf: iwidgetgrid); + function getgridintf: iwidgetgrid; + function needscellfocuspaint(): boolean; + function getcellcursor(const arow: integer; const acellzone: cellzonety; + const apos: pointty): cursorshapety; virtual; + procedure updatecellzone(const row: integer; const apos: pointty; + var result: cellzonety); virtual; + function getnulltext: msestring; + procedure drawcell(const canvas: tcanvas); + procedure updateautocellsize(const canvas: tcanvas); virtual; + procedure beforecelldragevent(var ainfo: draginfoty; const arow: integer; + var handled: boolean); virtual; + procedure aftercelldragevent(var ainfo: draginfoty; const arow: integer; + var handled: boolean); virtual; + procedure initgridwidget; + procedure valuetogrid(row: integer); + procedure gridtovalue(row: integer); + procedure setvaluedata(const source); virtual; + procedure getvaluedata(out dest); virtual; + procedure docellevent(const ownedcol: boolean; + var info: celleventinfoty); virtual; + function sortfunc(const l,r): integer; + procedure gridvaluechanged(const index: integer); virtual; + procedure updatecoloptions(const aoptions: coloptionsty); + procedure updatecoloptions1(const aoptions: coloptions1ty); + procedure statdataread; virtual; + procedure griddatasourcechanged; + {$ifdef mse_with_ifi} + function getifilink: tifilinkcomp; + procedure dochange; override; + {$endif} + procedure setparentgridwidget(const intf: igridwidget); + procedure childdataentered(const sender: igridwidget); virtual; + procedure childfocused(const sender: igridwidget); virtual; + + //istatfile + procedure dostatread(const reader: tstatreader); + procedure dostatwrite(const writer: tstatwriter); + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + procedure checkgrid; + + procedure setedpos(const Value: gridcoordty; const select: boolean; + const donotify: boolean; + const ashowcell: cellpositionty); + procedure internalclearselection; + procedure internaldeletetext(const start, stop: gridcoordty; + const userinput: boolean); + //iassistiveclient + function getassistivetext(): msestring; override; + function getassistiveflags: assistiveflagsty; override; + //iassistiveclientgrid + function getassistivecelltext(const arow: int32): msestring; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure createtabulators; + function actualcolor: colorty; override; + procedure synctofontheight; override; + procedure reloadfile(restorestate: boolean = true); + procedure loadfromstream(const stream: ttextstream; + restorestate: boolean = false); + procedure loadfromfile(afilename: filenamety; //no const! + restorestate: boolean = false); virtual; + procedure savetostream(const stream: ttextstream; + const resetmodified: boolean); + procedure savetofile(const afilename: filenamety = ''); + //afilename = '' -> current filename + property filename: filenamety read ffilename; + property filerights: filerightsty read ffilerights write ffilerights; + + procedure beginupdate; virtual; + procedure endupdate; virtual; + procedure clear; virtual; +// function filename: filenamety; + + procedure seteditpos(const Value: gridcoordty; const select: boolean = false; + const ashowcell: cellpositionty = cep_nearest); + procedure inserttext(const apos: gridcoordty; const atext: msestring; + out aendpos: gridcoordty; + selected: boolean = false; + insertbackwards: boolean = false); overload; + procedure inserttext(const apos: gridcoordty; const atext: msestring; + selected: boolean = false; + insertbackwards: boolean = false); overload; + procedure inserttext(const atext: msestring; + selected: boolean = false); overload; + procedure deletetext(const start,stop: gridcoordty); + function appendrow(const atext: msestring): integer; overload; + function appendrow(const atext: richstringty): integer; overload; + + function hasselection: boolean; override; + function selectedtext: msestring; + function selectedrichtext: richstringty; + procedure getselectedrows(out start,stop: integer); + + property optionsedit default defaulttexteditoptions; + procedure setfontstyle(const start,stop: gridcoordty; + const astyle: fontstylety; const aset: boolean; + const afontcolor: colorty = cl_default; + const acolorbackground: colorty = cl_default); + //astyle = fs_force -> set colors only + property selectstart: gridcoordty read fselectstart; + property selectend: gridcoordty read fselectend; + procedure setselection(const start,stop: gridcoordty; + const aseteditpos: boolean = false; + const ashowcell: cellpositionty = cep_nearest); + procedure clearselection; + procedure copyselection; + procedure cutselection; + function canpaste: boolean; + procedure paste; + procedure deleteselection; + procedure selectall; + + function find(const atext: msestring; options: searchoptionsty; + var textpos: gridcoordty; const endpos: gridcoordty; + selectfound: boolean = false; + const ashowcell: cellpositionty = cep_nearest): boolean; + + function gettext(const start, stop: gridcoordty): msestring + overload reintroduce; + function gettext: msestring overload reintroduce; + procedure settext(const atext: msestring) reintroduce; + function getrichtext(const start, stop: gridcoordty): richstringty; + + function getcellframe: framety; virtual; + + function linecount: integer; + property gridvalue[const index: integer]: msestring + read getgridvalue write setgridvalue; default; + property gridvalues: msestringarty read getgridvalues write setgridvalues; + property richlines[const index: integer]: richstringty + read getrichlines write setrichlines; + property richformats[const index: integer]: formatinfoarty + read getrichformats write setrichformats; + property datalist: tgridrichstringdatalist read flines write setdatalist; + + function mousepostotextpos(const mousepos: pointty; out textpos: gridcoordty; + widgetorg: boolean = false): boolean; + //if widgetorg = false -> org mousepos = topleft of col + // org mousepos = clientpos otherwise + //false if out of text, textpos clamped to textrange + function textpostomousepos(const textpos: gridcoordty; + const screenorg: boolean = false): pointty; + function textpostomouserect(const textpos: gridcoordty; + const screenorg: boolean = false): rectty; + //y:= top of character cell cx = 0 cy = linespacing + property editpos: gridcoordty read geteditpos write seteditpos1; + property row: integer read getrow write setrow; + property col: integer read getcol write setcol; + property modified: boolean read fmodified write setmodified; + + property encoding: charencodingty read fencoding write fencoding + default ce_locale; + property eolstyle: eolstylety read feolstyle write feolstyle + default eol_default; + //applied to write stream if stream.eolstyle = ce_default + //ce_default -> use foundeolstyle of last read stream + //ce_default -> system eol + property options: texteditoptionsty read foptions write setoptions + default []; + property textflags default defaulttextflags - [tf_noselect]; + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read getstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + property tabulators: ttabulators read gettabulators write settabulators; + property marginlinepos: integer read fmarginlinepos + write setmarginlinepos default 0; + //offset to innerclientrect.x + property marginlinecolor: colorty read fmarginlinecolor + write setmarginlinecolor default cl_none; + property onfontchanged: notifyeventty read fonfontchanged + write fonfontchanged; + property onmodifiedchanged: booleanchangedeventty read fonmodifiedchanged + write fonmodifiedchanged; + property ontextmouseevent: textmouseeventty read fontextmouseevent + write fontextmouseevent; + property oneditnotifcation: editnotificationeventty read foneditnotification + write foneditnotification; + property ondrawtext: textdraweventty read fondrawtext write fondrawtext; + property onsetupeditor: setupeditoreventty read fonsetupeditor + write fonsetupeditor; + property oncellevent: celleventty read foncellevent write foncellevent; + published + property optionswidget default defaulttexteditwidgetoptions; + property optionswidget1 default defaulttexteditwidgetoptions1; + end; + + ttextedit = class(tcustomtextedit) + published + property font; + property caretwidth; + property cursorreadonly; + property optionsedit1; //before optionsedit! + property optionsedit; + property textflags; + property textflagsactive; + + property statfile; + property statvarname; + property statpriority; + property encoding; + property options; + property marginlinepos; + //offset to innerclientrect.x + property marginlinecolor; + property tabulators; + + property onchange; + property ontextedited; + property onkeydown; + property onkeyup; + property oncopytoclipboard; + property onpastefromclipboard; + + property onfontchanged; + property onmodifiedchanged; + property ontextmouseevent; + property oneditnotifcation; + property oncellevent; + property ondrawtext; + property onsetupeditor; + end; + + tundotextedit = class(ttextedit,iundo) + private + function getmaxundocount: integer; + procedure setmaxundocount(const Value: integer); + function getmaxundosize: integer; + procedure setmaxundosize(const Value: integer); + protected + procedure textinserted(const apos: gridcoordty; + const atext: msestring; const selected: boolean; + const endpos: gridcoordty; const backwards: boolean); override; + procedure textdeleted(const apos: gridcoordty; + const atext: msestring; const selected: boolean; + const endpos: gridcoordty; const backwards: boolean); override; + procedure getselectstart(var selectstartpos: gridcoordty); + procedure setselectstart(const selectstartpos: gridcoordty); + protected + public + constructor create(aowner: tcomponent); override; + procedure clear; override; + procedure undo; + procedure redo; + function canundo: boolean; + function canredo: boolean; + procedure lowercase; //selection -> lowercase; + procedure uppercase; //selection -> uppercase + procedure tabtospace; //selection tab -> space + published + property maxundocount: integer read getmaxundocount write + setmaxundocount default defaultundomaxcount; + property maxundosize: integer read getmaxundosize write + setmaxundosize default defaultundobuffermaxsize; + end; + +procedure normalizetextrect(const po1,po2: gridcoordty; + out start,stop: gridcoordty); +function istextdblclick(const ainfo: textmouseeventinfoty): boolean; + +implementation +uses + msefileutils,sysutils,msesysutils,msewidgets,msebits, + msekeyboard,mseactions; + +const + valuevarname = 'value'; +type + tcustomwidgetgrid1 = class(tcustomwidgetgrid); + tinplaceedit1 = class(tinplaceedit); + twidgetcol1 = class(twidgetcol); + tcustomrowstatelist1 = class(tcustomrowstatelist); + twidget1 = class(twidget); + +procedure normalizetextrect(const po1,po2: gridcoordty; out start,stop: gridcoordty); +begin + if po1.row > po2.row then begin + start:= po2; + stop:= po1; + end + else begin + if po1.row < po2.row then begin + start:= po1; + stop:= po2; + end + else begin + if po1.col > po2.col then begin + start:= po2; + stop:= po1; + end + else begin + start:= po1; + stop:= po2; + end; + end; + end; +end; + +function istextdblclick(const ainfo: textmouseeventinfoty): boolean; +begin + result:= (ainfo.eventkind = cek_buttonpress) and + (ss_double in ainfo.mouseeventinfopo^.shiftstate); +end; + +function createtgridrichstringdatalist(const aowner:twidgetcol): tdatalist; +begin + result:= tgridrichstringdatalist.create(aowner); +end; + +{ tgridrichstringdatalist } + +constructor tgridrichstringdatalist.create(owner: twidgetcol); +begin + fowner:= owner; + inherited create; + include(fstate,dls_nostreaming); +end; + +function tgridrichstringdatalist.getdefault: pointer; +begin + if twidgetcol1(fowner).fintf <> nil then begin + result:= twidgetcol1(fowner).fintf.getdefaultvalue; + end + else begin + result:= inherited getdefault; + end; +end; + +{ tcustomtextedit } + +constructor tcustomtextedit.create(aowner: tcomponent); +begin + feolstyle:= eol_default; + ffilerights:= defaultfilerights; + fmousetextpos:= invalidcell; + fmarginlinecolor:= cl_none; + if feditor = nil then begin + feditor:= tinplaceedit.create(self,iedit(self),true); + end; + inherited; + foptionswidget:= defaulttexteditwidgetoptions; + foptionswidget1:= defaulttexteditwidgetoptions1; + optionsedit:= defaulttexteditoptions; + textflags:= defaulttextflags - [tf_noselect]; +end; + +destructor tcustomtextedit.destroy; +begin + inherited; + ftabulators.Free; +end; + +function tcustomtextedit.actualcolor: colorty; +begin + if (fgridintf <> nil) and (fcolor = cl_default) then begin + result:= fgridintf.getcol.rowcolor(fgridintf.getrow); + end + else begin + result:= inherited actualcolor; + end; +end; + +procedure tcustomtextedit.synctofontheight; +begin + inherited; + if (fgridintf <> nil) and not (tf_rotate90 in textflags) then begin + fgridintf.getcol.grid.datarowheight:= bounds_cy - font.glyphheight + font.lineheight; + end; +end; + +procedure tcustomtextedit.dofontheightdelta(var delta: integer); +begin + inherited; + gridwidgetfontheightdelta(self,fgridintf,delta); +{ + inherited; + if fgridintf <> nil then begin + with fgridintf.getcol.grid do begin + datarowheight:= datarowheight + delta; + end; + end; +} +end; + +procedure tcustomtextedit.sizechanged; +begin + inherited; + gridwidgetsized(self,fgridintf); +end; + +procedure tcustomtextedit.setgridintf(const intf: iwidgetgrid); +begin + fgridintf:= intf; + if (intf <> nil) then begin + flines:= tgridrichstringdatalist(fgridintf.getcol.datalist); + if (ow1_autoscale in foptionswidget1) and + (foptionswidget1 * [ow1_fontglyphheight,ow1_fontlineheight] + <> []) then begin + fgridintf.getcol.grid.datarowheight:= bounds_cy; + end; + end; +end; + +function tcustomtextedit.getcellframe: framety; +begin + if fframe <> nil then begin + result:= frame.cellframe; + end + else begin + if fgridintf <> nil then begin + result:= tgridarrayprop(fgridintf.getcol.prop).innerframe; + end + else begin + result:= getinnerframe; + end; + end; +end; + +function tcustomtextedit.needscellfocuspaint(): boolean; +begin + result:= inherited needsfocuspaint(); +end; + +function tcustomtextedit.getcellcursor(const arow: integer; + const acellzone: cellzonety; + const apos: pointty): cursorshapety; +begin + result:= actualcursor(nullpoint); +end; + +procedure tcustomtextedit.updatecellzone(const row: integer; + const apos: pointty; var result: cellzonety); +begin + //dummy +end; + +function tcustomtextedit.getnulltext: msestring; +begin + result:= ''; +end; + +function tcustomtextedit.createdatalist(const sender: twidgetcol): tdatalist; +begin + flines:= tgridrichstringdatalist.create(sender); + result:= flines; +end; + +function tcustomtextedit.getdatalistclass: datalistclassty; +begin + result:= tgridrichstringdatalist; +end; + +procedure tcustomtextedit.dobeforepaintforeground(const canvas: tcanvas); +var + int1: integer; +begin + if fmarginlinecolor <> cl_none then begin + int1:= innerclientpos.x + fmarginlinepos; + if fframe = nil then begin + inc(int1,texteditminimalframe.left); + end; + canvas.drawline(makepoint(int1,0),makepoint(int1,clientsize.cy), + fmarginlinecolor); + end; +end; + +procedure tcustomtextedit.painttext(const canvas: tcanvas); +var + b1: boolean; +begin + if assigned(fondrawtext) then begin + b1:= false; + fondrawtext(self,canvas,feditor.richtext,nil,b1); + if b1 then begin + exit; + end; + end; + inherited; +end; + +procedure tcustomtextedit.drawcell(const canvas: tcanvas); +var + rect1: rectty; + int1: integer; + b1: boolean; +begin + with cellinfoty(canvas.drawinfopo^) do begin + if assigned(fondrawtext) then begin + b1:= false; + fondrawtext(self,canvas,prichstringty(datapo)^,canvas.drawinfopo,b1); + if b1 then begin + exit; + end; + end; + if calcautocellsize then begin + rect1:= textrect(canvas,prichstringty(datapo)^,innerrect, + feditor.textflags,nil,ftabulators); + int1:= rect.cx + rect1.cx - innerrect.cx; + if int1 > autocellsize.cx then begin + autocellsize.cx:= rect1.cx; + end; + int1:= rect.cy + rect1.cy - innerrect.cy; + if int1 > autocellsize.cy then begin + autocellsize.cy:= int1; + end; + end + else begin + if fmarginlinecolor <> cl_none then begin + int1:= innerrect.x + fmarginlinepos; + canvas.drawline(makepoint(int1,0),makepoint(int1,rect.cy),fmarginlinecolor); + end; + drawtext(canvas,prichstringty(datapo)^,innerrect,feditor.textflags,nil, + ftabulators); + end; + end; +end; + +procedure tcustomtextedit.updateautocellsize(const canvas: tcanvas); +begin + drawcell(canvas); +end; + +function tcustomtextedit.beforechange: boolean; //true if not aborted +begin + result:= feditor.beforechange; +end; + +procedure tcustomtextedit.fontchanged; +begin + inherited; + if fgridintf <> nil then begin + fgridintf.getcol.changed; + end; + if canevent(tmethod(fonfontchanged)) then begin + fonfontchanged(self); + end; +end; + +{ +procedure tcustomtextedit.updatecellzone(const pos: pointty; var result: cellzonety); +begin + //dummy +end; +} +function tcustomtextedit.getdefaultvalue: pointer; +begin + result:= nil; +end; + +function tcustomtextedit.getrowdatapo(const arow: integer): pointer; +begin + result:= nil; +end; + +procedure tcustomtextedit.setfirstclick(var ainfo: mouseeventinfoty); +begin + //dummy +end; + +function tcustomtextedit.getinitvalue: pointer; +begin + result:= nil; +end; + +procedure tcustomtextedit.valuetogrid(row: integer); +begin + fgridintf.setdata(row,feditor.richtext); +end; + +procedure tcustomtextedit.gridtovalue(row: integer); +var + text1: richstringty; +begin + if fupdating = 0 then begin + fgridintf.getdata(row,text1); + inc(fupdating); + try + feditor.richtext:= text1; + finally + dec(fupdating); + end; + end; +end; + +procedure tcustomtextedit.initgridwidget; +begin + optionswidget1:= optionswidget1 - [ow1_autoscale]; + frame:= nil; + with fgridintf.grid do begin + optionsgrid:= optionsgrid + [og_autofirstrow]; + end; + optionsskin:= optionsskin + defaultgridskinoptions; +end; + +function tcustomtextedit.sortfunc(const l,r): integer; +begin + result:= 0; +end; + +procedure tcustomtextedit.gridvaluechanged(const index: integer); +begin + modified:= true; +end; + +procedure tcustomtextedit.updatecoloptions(const aoptions: coloptionsty); +var + opt1: optionsedit1ty; +begin + opt1:= feditor.optionsedit1; + fgridintf.coloptionstoeditoptions(foptionsedit,opt1); + feditor.optionsedit1:= opt1; +end; + +procedure tcustomtextedit.updatecoloptions1(const aoptions: coloptions1ty); +begin + //dummy +end; + +procedure tcustomtextedit.statdataread; +begin + modified:= false; +end; + +procedure tcustomtextedit.griddatasourcechanged; +begin + //dummy +end; + +{$ifdef mse_with_ifi} +function tcustomtextedit.getifilink: tifilinkcomp; +begin + result:= nil; +end; + +procedure tcustomtextedit.dochange; +begin + inherited; + { + if not (ws_loadedproc in fwidgetstate) then begin + if fifiserverintf <> nil then begin + fifiserverintf.valuechanged(iificlient(self)); + end; + end; + } +end; +{$endif mse_with_ifi} + +procedure tcustomtextedit.setoptionsedit(const avalue: optionseditty); +var + opt1: optionseditty; +begin + opt1:= avalue - [oe_trimleft,oe_trimright,oe_uppercase,oe_lowercase]; + if foptionsedit <> opt1 then begin + inherited setoptionsedit(opt1); + if fgridintf <> nil then begin + fgridintf.updateeditoptions(foptionsedit,feditor.optionsedit1); + end; + end; +end; + +procedure tcustomtextedit.setoptionsedit1(const avalue: optionsedit1ty); +begin + inherited; + if fgridintf <> nil then begin + fgridintf.updateeditoptions(foptionsedit,feditor.optionsedit1); + end; +end; + +procedure tcustomtextedit.dokeydown(var info: keyeventinfoty); +var + shiftstate1: shiftstatesty; + int1,int2: integer; + indexbefore: integer; + rect1: rectty; + bo1,bo2: boolean; +begin + with info do begin + shiftstate1:= shiftstate * shiftstatesmask; + if (tf_wordbreak in textflagsactive) and + (shiftstate1 - [ss_shift] = []) then begin + include(info.eventstate,es_processed); + with feditor do begin + int2:= fxpos; + int1:= 0; + case key of + key_up: begin + int1:= - self.font.lineheight; + end; + key_down: begin + int1:= self.font.lineheight; + end; + else begin + exclude(info.eventstate,es_processed); + end; + end; + if int1 <> 0 then begin + int1:= caretpos.y + int1; + rect1:= textrect; + if int1 < rect1.y then begin + int1:= rect1.y; + end; + if int1 >= rect1.y + rect1.cy then begin + int1:= rect1.y + rect1.cy - 1; + end; + indexbefore:= curindex; + moveindex(mousepostotextindex(makepoint(fxpos,int1)), + ss_shift in info.shiftstate); + if ss_shift in info.shiftstate then begin + invalidate; + end; +// if fxpos < int2 then begin + fxpos:= int2; //restore +// end; + if {(oe_exitoncursor in foptionsedit) and} (indexbefore = curindex) and + {(info.shiftstate = []) and} + ((info.key = key_down) or (info.key = key_up)) then begin + exclude(info.eventstate,es_processed); + end; + end; + end; + end; + if not (es_processed in eventstate) and (fgridintf <> nil) then begin + if ((shiftstate1 = [ss_shift,ss_ctrl]) or (shiftstate1 = [ss_ctrl])) then begin + if key = key_home then begin + seteditpos(makegridcoord(0,0),ss_shift in shiftstate1); + include(eventstate,es_processed); + end + else begin + if key = key_end then begin + seteditpos(makegridcoord(bigint,bigint),ss_shift in shiftstate1); + include(eventstate,es_processed); + end; + end; + end; + if isenterkey(self,info.key) and (shiftstate1 - [ss_shift] = []) and + (foptionsedit * [oe_readonly,oe_linebreak] = [oe_linebreak]) and + ((ss_shift in shiftstate1) xor not (oe_shiftreturn in foptionsedit)) + then begin + insertlinebreak; + include(eventstate,es_processed); + end; + end; + if flines <> nil then begin + if not (es_processed in eventstate) and + issysshortcut(sho_rowdelete,info) then begin + int1:= col; + feditor.begingroup; + try + if (fgridintf <> nil) and + tcustomwidgetgrid1(fgridintf.getcol.grid). + deleterowconfirmation() then begin + + internaldeletetext(mgc(0,row),mgc(0,row+1),true); + col:= int1; + end; + finally + feditor.endgroup; + end; + include(eventstate,es_processed); + end; + if not (es_processed in eventstate) then begin + bo1:= issysshortcut(sho_rowappend,info); + if bo1 or issysshortcut(sho_rowinsert,info) then begin + feditor.begingroup; + try + bo2:= false; + int1:= col; + clearselection; + if bo1 then begin //append + col:= length(flines[row]); + end + else begin + if row = 0 then begin + bo2:= true; + col:= 0; + end + else begin + editpos:= mgc(length(flines[row-1]),row-1); + end; + end; + insertlinebreak; + if not bo1 then begin //insert + int2:= row; + if not bo2 then begin + inc(int2); + end; + editpos:= mgc(int1,int2); + end; + finally + feditor.endgroup; + end; + include(eventstate,es_processed); + end; + end; + end; + if not (es_processed in eventstate) then begin + inherited; + end; + end; +end; + +procedure tcustomtextedit.reloadfile(restorestate: boolean = true); +begin + inc(fnotificationchangelock); + try + loadfromfile(ffilename,restorestate); + finally + dec(fnotificationchangelock); + end; +end; + +procedure tcustomtextedit.loadfromstream(const stream: ttextstream; + restorestate: boolean = false); +var + statsave: texteditstatety; + po1: pmsestring; +begin + checkgrid; + if restorestate then begin + getstate(statsave); + end; + beginupdate; + try + clear(); + ffilerights:= stream.filerights; + flines.loadfromstream(stream); + ffoundeolstyle:= stream.foundeolstyle(); + fhasbom:= false; + if stream.encoding = ce_utf8 then begin + if (flines.count > 0) then begin + po1:= flines.datapo; + if (po1^ <> '') and (card16(po1^[1]) = $feff) then begin + fhasbom:= true; + po1^:= copy(po1^,2,bigint); + end; + end; + end; + fgridintf.getcol.grid.rowcount:= flines.count; + if restorestate then begin + setstate(statsave); + end; + finally + endupdate; + end; + modified:= false; +end; + +procedure tcustomtextedit.loadfromfile(afilename: filenamety; + restorestate: boolean = false); +var + stream: ttextstream; + +begin + checkgrid; + stream:= ttextstream.Create(afilename,fm_read); + try + stream.encoding:= fencoding; + loadfromstream(stream,restorestate); + setfilename(afilename); + finally + stream.Free; + end; +end; + +procedure tcustomtextedit.savetostream(const stream: ttextstream; + const resetmodified: boolean); +const + bom: array[0..2] of byte = ($ef,$bb,$bf); +begin + stream.encoding:= fencoding; + if stream.eolstyle = eol_default then begin + if feolstyle = eol_default then begin + stream.eolstyle:= ffoundeolstyle; + end + else begin + stream.eolstyle:= feolstyle; + end; + end; +// stream.filerights:= ffilerights; + if (fencoding = ce_utf8) and (fhasbom or (teeo_bom in foptions)) and + not(teeo_nobom in foptions) then begin + stream.writebuffer(bom,length(bom)); + end; + flines.savetostream(stream); + if resetmodified then begin + modified:= false; + end; +end; + +procedure tcustomtextedit.savetofile(const afilename: filenamety = ''); + //afilename = '' -> current filename +var + stream: ttextstream; + str1: filenamety; +begin + if afilename = '' then begin + str1:= ffilename; + end + else begin + str1:= afilename; + end; + stream:= ttextstream.createtransaction(str1,ffilerights); + try + savetostream(stream,true); + setfilename(str1); + finally + stream.Free; + end; +end; + +procedure tcustomtextedit.getstate(out state: texteditstatety); +begin + //dummy +end; + +procedure tcustomtextedit.setstate(const state: texteditstatety); +begin + //dummy +end; + +procedure tcustomtextedit.beginupdate; +begin + feditor.beginupdate; + if flines <> nil then begin + flines.beginupdate; + end; +end; + +procedure tcustomtextedit.endupdate; +begin + if flines <> nil then begin + flines.endupdate; + end; + feditor.endupdate; + if not feditor.updating and (tes_xposinvalid in ftextstate) then begin + fxpos:= feditor.caretpos.x; + exclude(ftextstate,tes_xposinvalid); + end; +end; + +procedure tcustomtextedit.clear; +begin + beforechange; + fselectstart:= nullcoord; + fselectend:= nullcoord; + ffilename:= ''; + ffilerights:= defaultfilerights; + if flines <> nil then begin + flines.clear; +// fgridintf.getcol.grid.rowcount:= 0; + end; + ffoundeolstyle:= eol_default; + modified:= false; +end; + +procedure tcustomtextedit.setfilename(value: filenamety); +begin + ffilename:= filepath(value); +{ + removefilechangenotification; + ffilepath:= expanduncfilename(value); + addfilechangenotification; + if (seo_autosyntax in foptions) and (fsyntaxpainter <> nil) then begin + try + syntaxhandle:= fsyntaxpainter.linkdeffile(fileext(value)); + except + on e: exception do begin + writeexceptionmessage(e); + syntaxhandle:= -1; + end; + end; + end; + } +end; +{ +function tcustomtextedit.filename: filenamety; +begin + result:= ffilename; +end; +} +procedure tcustomtextedit.dostatread(const reader: tstatreader); +begin + if (fgridintf = nil) and canstatvalue(feditor.optionsedit1,reader) then begin +// value:= reader.readmsestring(valuevarname,value); + end; + if canstatstate(feditor.optionsedit1,reader) then begin +// readstatstate(reader); + end; + if canstatoptions(feditor.optionsedit1,reader) then begin +// readstatoptions(reader); + end; +end; + +procedure tcustomtextedit.dostatwrite(const writer: tstatwriter); +begin + if (fgridintf = nil) and canstatvalue(feditor.optionsedit1,writer) then begin +// writestatvalue(writer); + end; + if canstatstate(feditor.optionsedit1,writer) then begin +// writestatstate(writer); + end; + if canstatoptions(feditor.optionsedit1,writer) then begin +// writestatoptions(writer); + end; +end; + +function tcustomtextedit.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +procedure tcustomtextedit.setstatfile(const Value: tstatfile); +begin + setstatfilevar(istatfile(self),value,fstatfile); +end; + +procedure tcustomtextedit.statreading; +begin + //dummy +end; + +procedure tcustomtextedit.statread; +begin + //dummy +end; + +procedure tcustomtextedit.inserttext(const apos: gridcoordty; const atext: msestring; + out aendpos: gridcoordty; + selected: boolean = false; + insertbackwards: boolean = false); +var + ar1: msestringarty; + int1: integer; +begin + beforechange; + beginupdate; + feditor.begingroup; + try + clearselection; + ar1:= breaklines(atext); + with fgridintf.getcol do begin + if ar1 = nil then begin + aendpos.col:= 0; + aendpos.row:= apos.row; + end + else begin + aendpos.col:= length(ar1[high(ar1)]); + aendpos.row:= apos.row + high(ar1); + end; + if length(ar1) > 1 then begin + ar1[high(ar1)]:= ar1[high(ar1)] + copy(flines[apos.row],apos.col + 1,bigint); + if apos.col = 0 then begin + grid.insertrow(apos.row,high(ar1)); + end + else begin + grid.insertrow(apos.row+1,high(ar1)); + end; + for int1:= 1 to high(ar1) do begin + flines.items[apos.row+int1]:= ar1[int1]; + end; + flines[apos.row]:= copy(flines[apos.row],1,apos.col) + ar1[0]; + end + else begin + richinsert(atext,prichstringty(flines.getitempo(apos.row))^,apos.col+1); + aendpos.col:= aendpos.col + apos.col; + end; + end; + int1:= fgridintf.getrow; + if (int1 >= 0) and (int1 < flines.count) then begin + feditor.richtext:= flines.richitems[int1]; + end; + if insertbackwards then begin + seteditpos(aendpos,false); + textinserted(aendpos,atext,selected,apos,true); + seteditpos(apos,false); + if selected then begin + fselectstart:= aendpos; + fselectend:= aendpos; + end; + end + else begin + seteditpos(apos,false); + textinserted(apos,atext,selected,aendpos,false); + seteditpos(aendpos,false); + if selected then begin + fselectstart:= apos; + fselectend:= apos; + end; + end; + updateindex(selected); + finally + feditor.endgroup; + endupdate; + end; +end; + +procedure tcustomtextedit.inserttext(const apos: gridcoordty; + const atext: msestring; selected: boolean = false; + insertbackwards: boolean = false); +var + po1: gridcoordty; +begin + inserttext(apos,atext,po1,selected,insertbackwards); +end; + +procedure tcustomtextedit.internaldeletetext(const start, stop: gridcoordty; + const userinput: boolean); +var + po1,po2: gridcoordty; + bo1: boolean; + grid: tcustomwidgetgrid1; +begin + if (start.col <> stop.col) or (start.row <> stop.row) then begin + beforechange; + normalizetextrect(start,stop,po1,po2); + beginupdate; + feditor.begingroup; + application.caret.remove; + grid:= tcustomwidgetgrid1(fgridintf.getcol.grid); + bo1:= og_appendempty in grid.optionsgrid; + try + include(grid.foptionsgrid,og_appendempty); + clearselection; + seteditpos(stop,false); + textdeleted(stop,gettext(po1,po2),false,po1, + isequalgridcoord(po2,stop)); + seteditpos(po1,false); +// feditor.updatecaret; //locked by beginupdate + if po1.row = po2.row then begin + richdelete(prichstringty(flines.getitempo(po1.row))^,po1.col+1, + po2.col-po1.col); + end + else begin + if po1.col > 0 then begin + richdelete(prichstringty(flines.getitempo(po1.row))^,po1.col+1,bigint); + end; + if po2.col > 0 then begin + richdelete(prichstringty(flines.getitempo(po2.row))^,1,po2.col); + end; + if po1.col > 0 then begin + if po2.row < flines.count then begin + prichstringty(flines.getitempo(po1.row))^:= + richconcat(prichstringty(flines.getitempo(po1.row))^, + prichstringty(flines.getitempo(po2.row))^); + end; + inc(po1.row); + if po1.row < flines.count then begin + grid.deleterow(po1.row,po2.row-po1.row+1,userinput); + end; + end + else begin + grid.deleterow(po1.row,po2.row-po1.row,userinput); + end; +{ + if po2.row < flines.count then begin + prichstringty(flines.getitempo(po1.row))^:= + richconcat(prichstringty(flines.getitempo(po1.row))^, + prichstringty(flines.getitempo(po2.row))^); + end; + if (po1.row+1 < flines.count) then begin + grid.deleterow(po1.row+1,po2.row-po1.row); + end + else begin + if po1.col = 0 then begin + grid.deleterow(po1.row,po2.row-po1.row); + end; + end; +} + end; + if grid.updating then begin + gridtovalue(-1); + end; + finally + application.caret.restore; + feditor.endgroup; + if not bo1 then begin + exclude(grid.foptionsgrid,og_appendempty); + end; + endupdate; + end; + end; +end; + +procedure tcustomtextedit.deletetext(const start, stop: gridcoordty); +begin + internaldeletetext(start,stop,false); +end; + +function tcustomtextedit.appendrow(const atext: richstringty): integer; +begin + checkgrid; + result:= fgridintf.getcol.grid.appendrow; + richlines[result]:= atext; +end; + +function tcustomtextedit.appendrow(const atext: msestring): integer; +var + richstring: richstringty; +begin + richstring.text:= atext; + richstring.format:= nil; + result:= appendrow(richstring); +end; + +function intersecttextrect(const a1,a2,b1,b2: gridcoordty; + out i1,i2: gridcoordty): boolean; + //i = a * b, true if intersection exist, values have to be ordered +begin + if b1.row > a1.row then begin + i1:= b1; + end + else begin + i1:= a1; + if (b1.row = a1.row) and (b1.col > a1.col) then begin + i1.col:= b1.col; + end; + end; + if b2.row < a2.row then begin + i2:= b2; + end + else begin + i2:= a2; + if (b2.row = a2.row) and (b2.col < a2.col) then begin + i2.col:= b2.col; + end; + end; + result:= (i1.row < i2.row) or (i1.row = i2.row) and (i1.col < i2.col); +end; + +function compgridcoord(const a,b: gridcoordty): integer; +begin + result:= a.row-b.row; + if result = 0 then begin + result:= a.col - b.col; + end; +end; + +procedure tcustomtextedit.setselection(const start,stop: gridcoordty; + const aseteditpos: boolean = false; + const ashowcell: cellpositionty = cep_nearest); +var + astart,astop: gridcoordty; + + function checkoverlap(const a1,a2,b1,b2: gridcoordty): boolean; + //true if a <> (a ^ b) + var + int1: integer; + i1,i2: gridcoordty; + begin + if not intersecttextrect(a1,a2,b1,b2,i1,i2) then begin + result:= true; + astart:= a1; + astop:= a2; + exit; //no intersection + end; + result:= (a1.row <> i1.row) or (a1.col <> i1.col) or + (a2.row <> i2.row) or (a2.col <> i2.col); + if result then begin + int1:= compgridcoord(a1,i1); + if int1 < 0 then begin + astart:= a1; + astop:= i1; + end + else begin + astart:= i2; + astop:= a2; + end; + end; + end; + +var + col1: twidgetcol; + grid: twidgetgrid; + cell: gridcoordty; + + procedure updatestyle(value: boolean); + var + int1,int2: integer; + po1: prichstringty; + begin + po1:= prichstringty(flines.getitempo(astart.row)); + for int1:= astart.row to astop.row do begin //deselect old + if int1 = astop.row then begin + int2:= astop.col - astart.col; + end + else begin + int2:= length(po1^.text)-astart.col; + end; + if int2 > 0 then begin + updatefontstyle1(po1^.format, + astart.col,int2,fs_selected,value); + cell.row:= int1; + grid.invalidatecell(cell); + end; + astart.col:= 0; + inc(po1); + end; + end; + +var + new1,new2,old1,old2: gridcoordty; + int1: integer; + +begin + if (start.col < 0) or (start.row < 0) or (stop.col < 0) or + (stop.row < 0) then begin + exit; + end; + if aseteditpos then begin + if ashowcell <> cep_none then begin + seteditpos(start,false); + end; + seteditpos(stop,true,ashowcell); + end + else begin + col1:= fgridintf.getcol; + grid:= twidgetgrid(col1.grid); + cell.col:= col1.colindex; + + normalizetextrect(start,stop,new1,new2); + int1:= grid.row; + if int1 > new1.row then begin + if int1 < new2.row then begin + feditor.selstart:= 0; + feditor.sellength:= bigint; + end + else begin + if int1 = new2.row then begin + if new1.row < int1 then begin + feditor.selstart:= 0; + end + else begin + feditor.selstart:= new1.col; + end; + feditor.sellength:= new2.col-feditor.selstart; + end + else begin + feditor.sellength:= 0; + end; + end; + end + else begin + if int1 = new1.row then begin + feditor.selstart:= new1.col; + if new2.row > int1 then begin + feditor.sellength:= bigint; + end + else begin + feditor.sellength:= new2.col - new1.col; + end; + end + else begin + feditor.sellength:= 0; + end; + end; + normalizetextrect(fselectstart,fselectend,old1,old2); + fselectstart:= start; + fselectend:= stop; + int1:= fgridintf.getcol.grid.rowcount; + if old1.row >= int1 then begin + old1.row:= int1 - 1; + old1.col:= 0; + old2:= old1; + end + else begin + if old2.row >= int1 then begin + old2.row:= int1-1; + old2.col:= bigint; + end; + end; + if tes_selectinvalid in ftextstate then begin + astart:= new1; + astop:= new2; + updatestyle(true); + exclude(ftextstate,tes_selectinvalid); + end + else begin + if checkoverlap(old1,old2,new1,new2) then begin + updatestyle(false); + end; + if checkoverlap(new1,new2,old1,old2) then begin + updatestyle(true); + end; + end; + end; +end; + +procedure tcustomtextedit.selectall; +begin + setselection(makegridcoord(0,0), + makegridcoord(bigint,fgridintf.grid.rowhigh),true); +end; + +procedure tcustomtextedit.setfontstyle(const start,stop: gridcoordty; + const astyle: fontstylety; const aset: boolean; + const afontcolor: colorty = cl_default; + const acolorbackground: colorty = cl_default); +var + a,b: gridcoordty; + int1,int2: integer; + po1: prichstringty; + bo1: boolean; +begin + normalizetextrect(start,stop,a,b); + int2:= bigint; + for int1:= a.row to b.row do begin + po1:= flines.richitemspo[int1]; + if int1 = b.row then begin + int2:= b.col - a.col; + end; + bo1:= (astyle <> fs_force) and + updatefontstyle1(po1^.format,a.col,int2,astyle,aset); + if afontcolor <> cl_default then begin + bo1:= setfontcolor1(po1^.format,a.col,int2,afontcolor) or bo1; + end; + if acolorbackground <> cl_default then begin + bo1:= setcolorbackground1(po1^.format,a.col,int2,acolorbackground) or bo1; + end; + if bo1 then begin + with fgridintf.getcol do begin + invalidatecell(int1); + if int1 = grid.row then begin + tinplaceedit1(feditor).format:= po1^.format; + end; + end; + end; + a.col:= 0; + end; +end; + +procedure tcustomtextedit.updateindex(select: boolean); +var + selectstart1,selectend1: gridcoordty; + +begin + selectstart1:= fselectstart; + selectend1:= fselectend; + if select then begin + selectend1.col:= feditor.curindex; + selectend1.row:= tcustomwidgetgrid1(fgridintf.getcol.grid).row + end + else begin + selectstart1.col:= feditor.curindex; + selectstart1.row:= tcustomwidgetgrid1(fgridintf.getcol.grid).row; + selectend1:= selectstart1; + end; + setselection(selectstart1,selectend1); +end; + +procedure tcustomtextedit.insertlinebreak; +begin + feditor.begingroup; + try + deleteselection; + inserttext(fselectstart,lineend); + finally + feditor.endgroup; + end; +end; + +procedure tcustomtextedit.editnotification(var info: editnotificationinfoty); +var + int1: integer; + str1: msestring; + po1,po2: gridcoordty; + grid: tcustomgrid; + +begin + if canevent(tmethod(foneditnotification)) then begin + foneditnotification(self,info); + end; + if fgridintf <> nil then begin + grid:= fgridintf.getcol.grid; + with info do begin + case action of + ea_clearselection: begin + internalclearselection; + end; + ea_textedited: begin + if not (csdesigning in componentstate) then begin + if fupdating = 0 then begin + inc(fupdating); + try + fgridintf.edited(); + int1:= fgridintf.getrow; + fgridintf.setdata(int1,feditor.richtext,true); + gridvaluechanged(int1); + finally + dec(fupdating); + end; + inherited; + end; + end; + end; + ea_indexmoved: begin + fxpos:= feditor.caretpos.x; + updateindex(eas_shift in state); + end; + ea_textsizechanged: begin + if not (tes_cellentering in ftextstate) then begin + with fgridintf.getcol do begin + if info.sizebefore.cy <> info.newsize.cy then begin + autocellheightchanged(grid.row); + end; + if info.sizebefore.cx <> info.newsize.cx then begin + autocellwidthchanged(grid.row); + end; + end; + end; + end; + ea_delchar: begin + if dir <> gd_left then begin //no backspace + if (fselectstart.col = fselectend.col) and (fselectstart.row = fselectend.row) then begin + if (feditor.curindex = length(feditor.text)) then begin + if fselectstart.row < grid.rowcount - 1 then begin + fselectstart.row:= fselectend.row+1; + fselectstart.col:= 0; + deleteselection; //remove linebreak + action:= ea_none; + end; + end; + end + else begin + deleteselection; + action:= ea_none; + end; + end; + end; + ea_selectall: begin + selectall; + action:= ea_none; + end; + ea_deleteselection: begin + deleteselection; + action:= ea_none; + end; + ea_copyselection: begin +// copyselection; + if hasselection then begin + msewidgets.copytoclipboard(selectedtext,bufferkind); + end; + action:= ea_none; + end; + ea_pasteselection: begin + if msewidgets.pastefromclipboard(str1,bufferkind) then begin + beginupdate; + feditor.begingroup; + try + deleteselection; + po2:= editpos; + inserttext(po2,str1,po1,false); + finally + feditor.endgroup; + endupdate; + end; + end; + action:= ea_none; + end; + ea_exit: begin + action:= ea_none; + if dir = gd_left then begin + if editpos.row > 0 then begin + int1:= length(flines[editpos.row-1]); + if (eas_delete in state) then begin + if hasselection then begin + deleteselection + end + else begin + deletetext(makegridcoord(0,editpos.row),makegridcoord(int1,editpos.row-1)); + end; + end + else begin + seteditpos(makegridcoord(int1,editpos.row - 1),state = [eas_shift]); + end; + end + else begin + if not (eas_shift in state) then begin + internalclearselection; + end; + end; + end + else begin + if dir = gd_right then begin + if editpos.row < linecount - 1 then begin + seteditpos(makegridcoord(0,editpos.row + 1),state = [eas_shift]); + end + else begin + if not (eas_shift in state) then begin + internalclearselection; + end; + end; + end; + end; + end; + ea_caretupdating: begin + if focused and not grid.updating then begin + fgridintf.showcaretrect(info.caretrect,fframe); + end; + end; + end; + end; + end; + inherited; +end; + +procedure tcustomtextedit.mousepostotextpos1( const row: integer; + const mousepos: pointty; + var textpos: gridcoordty; var result: boolean); +var + textinfo: drawtextinfoty; + col1: twidgetcol; +begin + col1:= fgridintf.getcol; + textinfo.text:= flines.richitems[row]; + textinfo.font:= col1.rowfont(row); + textinfo.flags:= feditor.textflags; + if row = col1.grid.row then begin + textinfo.dest:= innerclientrect; + end + else begin + textinfo.dest:= col1.grid.cellrect(mgc(col1.index,row),cil_inner,false,true); + end; + textinfo.tabulators:= ftabulators; + result:= postotextindex(getcanvas,textinfo,mousepos,textpos.col); + textpos.row:= row; +end; + +function tcustomtextedit.mousepostotextpos(const mousepos: pointty; + out textpos: gridcoordty; widgetorg: boolean = false): boolean; + //false if out of text, textpos clamped to textrange +var + grid: tcustomwidgetgrid1; + arow: integer; + {po1,}pt2: pointty; +// int1: integer; +begin + result:= true; + grid:= tcustomwidgetgrid1(fgridintf.getcol.grid); + pt2:= mousepos; + if widgetorg then begin + pt2.y:= pt2.y + grid.rowpos(grid.row); //grid client data origin + end + else begin + subpoint1(pt2,fgridintf.getcol.cellorigin); + end; + arow:= grid.rowatpos(pt2.y); + { + if widgetorg then begin + int1:= fgridintf.getrow * grid.ystep; + end + else begin + int1:= 0; + end; + int1:= (mousepos.y + int1); + arow:= int1 div grid.ystep; + int1:= int1 - arow * grid.ystep; + } + if arow < 0 then begin + result:= false; + arow:= 0; + end + else begin + if arow >= grid.frowcount then begin + result:= false; + arow:= grid.frowcount-1; + end; + end; + pt2.y:= pt2.y - grid.rowpos(arow); + mousepostotextpos1(arow,pt2,textpos,result); + { + if widgetorg then begin + mousepostotextpos1(arow,makepoint(mousepos.x,int1),textpos,result); + end + else begin + po1:= fgridintf.getcol.cellorigin; + mousepostotextpos1(arow,makepoint(mousepos.x - po1.x, + mousepos.y - arow*grid.ystep - po1.y),textpos,result); + end; + } +end; + +function tcustomtextedit.textpostomousepos(const textpos: gridcoordty; + const screenorg: boolean = false): pointty; +var + po1,po2: pointty; + textinfo: drawtextinfoty; +begin + textinfo.text:= flines.richitems[textpos.row]; + textinfo.font:= fgridintf.getcol.rowfont(textpos.row); + textinfo.flags:= feditor.textflags; + textinfo.dest:= innerclientrect; + textinfo.tabulators:= ftabulators; + po1:= textindextopos(getcanvas,textinfo,textpos.col); + po2:= fgridintf.getcol.cellorigin; + result.y:= po1.y + {po2.y +} + tcustomwidgetgrid1(fgridintf.getcol.grid).cellrect(mgc(0,textpos.row)).y; +// textpos.row * tcustomwidgetgrid1(fgridintf.getcol.grid).ystep; + result.x:= po1.x + po2.x; + if screenorg then begin + translateclientpoint1(result,fgridintf.getcol.grid,nil); + end; +end; + +function tcustomtextedit.textpostomouserect(const textpos: gridcoordty; + const screenorg: boolean = false): rectty; + //y:= top of character cell cx = 0 cy = linespacing +begin + result.pos:= textpostomousepos(textpos,screenorg); + result.cx:= 0; + result.cy:= font.lineheight; + dec(result.y,font.ascent); +end; + +procedure tcustomtextedit.dotextmouseevent(var info: textmouseeventinfoty); +begin + if canevent(tmethod(fontextmouseevent)) then begin + fontextmouseevent(self,info); + end; +end; + +function tcustomtextedit.textclipped(const arow: integer; + out acellrect: rectty): boolean; +var + rect2: rectty; + canvas1: tcanvas; + cell1: gridcoordty; + grid1: tcustomgrid; +begin + checkgrid; + with twidgetcol1(fgridintf.getcol) do begin + grid1:= grid; + cell1.row:= arow; + cell1.col:= colindex; + result:= grid1.isdatacell(cell1); + if result then begin + acellrect:= grid1.clippedcellrect(cell1,cil_inner); + canvas1:= getcanvas; + rect2:= textrect(canvas1,richstringty(getdatapo(arow)^), + acellrect,feditor.textflags,font); + result:= not rectinrect(rect2,acellrect); + end + else begin + acellrect:= nullrect; + end; + end; +end; + +function tcustomtextedit.textclipped(const arow: integer): boolean; +var + rect1: rectty; +begin + result:= textclipped(arow,rect1); +end; + +function tcustomtextedit.getiassistiveclient(): iassistiveclient; +begin + result:= iassistiveclientgridwidget(self); +end; + +function tcustomtextedit.getassistivecolumncaption(): msestring; +begin + result:= ''; + if fgridintf <> nil then begin + result:= fgridintf.getcol.defaultcaption(); + end; +end; + +procedure tcustomtextedit.docellevent(const ownedcol: boolean; + var info: celleventinfoty); +var + textinfo: textmouseeventinfoty; + bo1: boolean; + po1: pointty; + int1,int2: integer; + rect1: rectty; + hintinfo: hintinfoty; +begin + if ownedcol then begin + with info do begin + textinfo.eventkind:= eventkind; + if eventkind = cek_enter then begin + tinplaceedit1(feditor).frow:= newcell.row; + end; + if canevent(tmethod(foncellevent)) then begin + foncellevent(self,info); + end; + case eventkind of + cek_enter: begin + bo1:= tes_cellentering in ftextstate; + include(ftextstate,tes_cellentering); + try + with fgridintf.getcol.grid do begin + if fselectstart.row >= rowcount then begin + fselectstart.row:= rowcount - 1; + fselectstart.col:= length(flines[fselectstart.row]); + //check for removed empty row + end; + end; + if cellbefore.row <> newcell.row then begin + with tinplaceedit1(feditor) do begin + rect1:= textrect; + if cellbefore.row < newcell.row then begin + int1:= mousepostotextindex(makepoint(fxpos,rect1.x)); + end + else begin + int1:= mousepostotextindex(makepoint(fxpos,rect1.y+rect1.cy-1)); + end; + int2:= fxpos; + moveindex(int1, + selectaction in [fca_focusinshift,fca_focusinrepeater],true{false}); + exclude(self.ftextstate,tes_xposinvalid); + fxpos:= int2; //restore + end; + end; + if selectaction = fca_focusinrepeater then begin + fgridintf.getcol.grid.setcellclientclick(self); + end; + dosetupeditor(); + finally + if not bo1 then begin + exclude(ftextstate,tes_cellentering); + end; + end; + end; + cek_mousemove,cek_mousepark,cek_buttonpress,cek_buttonrelease: begin + if cell.row >= 0 then begin + mousepostotextpos1(cell.row,mouseeventinfopo^.pos,textinfo.pos,bo1); + if (eventkind = cek_mousemove) and + (cell.row <> fgridintf.getcol.grid.row) and + (info.mouseeventinfopo^.shiftstate = [ss_left]) and + grid.cellclicked then begin + fxpos:= textpostomousepos(textinfo.pos).x; + + with fgridintf.getcol.grid do begin + focuscell(cell,fca_focusinshift); + setcellclientclick(self); +// setclientclick; + exit; + end; + end; + if not bo1 then begin + textinfo.pos:= invalidcell; + end; + end + else begin + textinfo.pos:= invalidcell; + end; + if not(eventkind in [cek_mousemove]) or (textinfo.pos.col <> fmousetextpos.col) or + (textinfo.pos.row <> fmousetextpos.row) then begin + fmousetextpos:= textinfo.pos; + po1:= subpoint(gridmousepos,mouseeventinfopo^.pos); + mouseeventinfopo^.pos:= gridmousepos; + textinfo.mouseeventinfopo:= mouseeventinfopo; + try + dotextmouseevent(textinfo); + finally + subpoint1(mouseeventinfopo^.pos,po1); + end; + end; + end; + cek_firstmousepark: begin + if (oe_hintclippedtext in foptionsedit) and application.active and + textclipped(info.cell.row) and + ((info.grid.row <> info.cell.row) or + (info.grid.col <> info.cell.col)) and + {$warnings off} + twidget1(info.grid).getshowhint then begin + {$warnings on} + application.inithintinfo(hintinfo,info.grid); + {$warnings off} + hintinfo.caption:= + richstringty( + twidgetcol1(fgridintf.getcol).getdatapo(info.cell.row)^).text; + {$warnings on} + application.showhint(info.grid,hintinfo); + end; + end; + cek_mouseleave: begin + fmousetextpos:= invalidcell; + textinfo.pos:= invalidcell; + textinfo.mouseeventinfopo:= mouseeventinfopo; + dotextmouseevent(textinfo); + end; + end; + end; + end; + inherited; +end; + +procedure tcustomtextedit.internalclearselection; +begin + setselection(editpos,editpos); +end; + +function tcustomtextedit.getassistivetext(): msestring; +begin + result:= feditor.text; +end; + +function tcustomtextedit.getassistiveflags: assistiveflagsty; +begin + result:= inherited getassistiveflags; + if fgridintf <> nil then begin + include(result,asf_gridwidget); + end; +end; + +function tcustomtextedit.getassistivecelltext(const arow: int32): msestring; +begin + if flines <> nil then begin + result:= flines[arow]; + end + else begin + result:= ''; + end; +end; + +procedure tcustomtextedit.clearselection; +begin + seteditpos(editpos,false); +end; + +procedure tcustomtextedit.setedpos(const Value: gridcoordty; + const select: boolean; const donotify: boolean; + const ashowcell: cellpositionty); +var + po1: gridcoordty; +begin + tinplaceedit1(feditor).frow:= value.row; + po1.row:= value.row; + po1.col:= fgridintf.getcol.colindex; + if select then begin + fgridintf.getcol.grid.focuscell(po1,fca_focusinshift,scm_cell,ashowcell); + end + else begin + fgridintf.getcol.grid.focuscell(po1,fca_focusin,scm_cell,ashowcell); + end; + feditor.moveindex(value.col,select,donotify); + if donotify then begin + if feditor.updating then begin + include(ftextstate,tes_xposinvalid);; + end + else begin + fxpos:= feditor.caretpos.x; + end; + end; + updateindex(select); +end; + +procedure tcustomtextedit.seteditpos(const Value: gridcoordty; + const select: boolean = false; + const ashowcell: cellpositionty = cep_nearest); +begin + setedpos(value,select,true,ashowcell); +end; + +procedure tcustomtextedit.seteditpos1(const Value: gridcoordty); +begin + seteditpos(value,false,cep_nearest); +end; + +function tcustomtextedit.geteditpos: gridcoordty; +begin + result:= makegridcoord(feditor.curindex,fgridintf.getrow); +end; + +function tcustomtextedit.getrow: integer; +begin + result:= fgridintf.getrow; +end; + +procedure tcustomtextedit.setrow(const avalue: integer); +begin + editpos:= makegridcoord(col,avalue); +end; + +function tcustomtextedit.getcol: integer; +begin + result:= feditor.curindex; +end; + +procedure tcustomtextedit.setcol(const avalue: integer); +begin + editpos:= makegridcoord(avalue,row); +end; + +procedure tcustomtextedit.getselectedrows(out start,stop: integer); +var + int1: integer; +begin + int1:= fselectend.row - fselectstart.row; + if int1 > 0 then begin + start:= fselectstart.row; + stop:= fselectend.row; + if fselectend.col = 0 then begin + dec(stop); + end; + end + else begin + if int1 <> 0 then begin + start:= fselectend.row; + stop:= fselectstart.row; + if fselectstart.col = 0 then begin + dec(stop); + end; + end + else begin + start:= editpos.row; + stop:= start; + end; + end; +end; + +procedure tcustomtextedit.deleteselection; +begin + if hasselection then begin + deletetext(fselectstart,fselectend); + end; +end; + +procedure tcustomtextedit.copyselection; +begin + if hasselection then begin + msewidgets.copytoclipboard(selectedtext); + end; +end; + +procedure tcustomtextedit.cutselection; +begin + copyselection; + deleteselection; +end; + +function tcustomtextedit.canpaste: boolean; +begin + result:= canpastefromclipboard; +end; + +procedure tcustomtextedit.paste; +var + str1: msestring; +begin + if msewidgets.pastefromclipboard(str1) then begin + feditor.begingroup; + try + deleteselection; + inserttext(editpos,str1,true); + finally + feditor.endgroup; + end; + end; +end; + +function tcustomtextedit.gettext(const start,stop: gridcoordty): msestring; +var + po1,po2: gridcoordty; + int1: integer; +begin + normalizetextrect(start,stop,po1,po2); + if po1.row = po2.row then begin + result:= copy(flines[po1.row],po1.col+1,po2.col-po1.col); + end + else begin + result:= copy(flines[po1.row],po1.col+1,bigint); + for int1:= po1.row + 1 to po2.row - 1 do begin + if flines.noparagraphs[int1] then begin + result:= result + flines[int1]; + end + else begin + result:= result + lineend + flines[int1]; + end; + end; + if po2.row < flines.count then begin + if not flines.noparagraphs[po2.row] then begin + result:= result + lineend; //paragraph + end; + result:= result + copy(flines[po2.row],1,po2.col); + end; + end; +end; + +function tcustomtextedit.getrichtext(const start, + stop: gridcoordty): richstringty; +var + po1,po2: gridcoordty; + int1: integer; +begin + normalizetextrect(start,stop,po1,po2); + if po1.row = po2.row then begin + result:= richcopy(flines.richitems[po1.row],po1.col+1,po2.col-po1.col); + end + else begin + result:= richcopy(flines.richitems[po1.row],po1.col+1,bigint); + for int1:= po1.row + 1 to po2.row - 1 do begin + if flines.noparagraphs[int1] then begin + result:= richconcat(result,flines.richitems[int1]); + end + else begin + result:= richconcat(result,richlineend); + result:= richconcat(result,flines.richitems[int1]); + end; + end; + if po2.row < flines.count then begin + if not flines.noparagraphs[po2.row] then begin + result:= richconcat(result,richlineend); //paragraph + end; + result:= richconcat(result,richcopy(flines.richitems[po2.row],1,po2.col)); + end; + end; +end; + +function tcustomtextedit.gettext: msestring; +begin + result:= flines.gettext; +end; + +procedure tcustomtextedit.settext(const atext: msestring); +begin + flines.settext(atext); +end; + +function tcustomtextedit.hasselection: boolean; +begin + result:= (fselectstart.row <> fselectend.row) or + (fselectstart.col <> fselectend.col); +end; + +function tcustomtextedit.selectedtext: msestring; +begin + if hasselection then begin + result:= gettext(fselectstart,fselectend); + end + else begin + result:= ''; + end; +end; + +function tcustomtextedit.selectedrichtext: richstringty; +begin + if hasselection then begin + result:= getrichtext(fselectstart,fselectend); + end + else begin + result:= emptyrichstring; + end; +end; + +function tcustomtextedit.find(const atext: msestring; options: searchoptionsty; + var textpos: gridcoordty; const endpos: gridcoordty; + selectfound: boolean = false; + const ashowcell: cellpositionty = cep_nearest): boolean; +var + int1,int2: integer; + endrow: integer; + + + function checkresult: boolean; + begin + if (int1 > 0) and ((int2 < endrow) or + (int2 = endrow) and (int1 - 1 + length(atext) <= endpos.col)) then begin + textpos.row:= int2; + textpos.col:= int1-1; + result:= true; + if selectfound then begin + setselection(textpos,makegridcoord(textpos.col + length(atext),textpos.row), + true,ashowcell); + end; + end + else begin + result:= false; + end; + end; + + function checkresultback: boolean; + begin + if (int1 > 0) and ((int2 > endpos.row) or + (int2 = textpos.row) and (int1 <= textpos.col)) then begin + textpos.row:= int2; + textpos.col:= int1-length(atext); + result:= true; + if selectfound then begin + setselection(makegridcoord(textpos.col + length(atext),textpos.row),textpos, + true,ashowcell); + end; + end + else begin + result:= false; + end; + end; + +var + po1: prichstringty; + pos1: gridcoordty; + str1,str2: msestring; + isback: boolean; +begin + result:= false; + if flines.count > 0 then begin + if so_caseinsensitive in options then begin + str1:= mselowercase(atext); + str2:= mseuppercase(atext); + end + else begin + str1:= atext; + str2:= ''; + end; + isback:= so_backward in options; + pos1:= textpos; + endrow:= endpos.row; + if endrow >= flines.count then begin + endrow:= flines.count - 1; + end; + if isback and (endrow < 0) then begin + endrow:= 0; + end; + po1:= flines.datapo; + if pos1.row < 0 then begin + if isback then begin + exit; + end; + pos1.row:= 0; + pos1.col:= 1; + end + else begin + if isback then begin + if pos1.row >= flines.count then begin + pos1.row:= flines.count-1; + end; + end + else begin + if pos1.row <= endrow then begin + inc(pos1.col); + if pos1.col < 1 then begin + pos1.col:= 1; + end; + end; + end; + end; + inc(po1,pos1.row); + int1:= msestringsearch(str1,po1^.text,pos1.col,options,str2); + int2:= pos1.row; + if isback then begin + while true do begin + if checkresultback then begin + result:= true; + exit; + end; + dec(int2); + if int2 < endrow then begin + exit; + end; + dec(po1); + int1:= msestringsearch(str1,po1^.text,bigint,options,str2); + end; + end + else begin + while true do begin + if checkresult then begin + result:= true; + exit; + end; + inc(int2); + if int2 > endrow then begin + exit; + end; + inc(po1); + int1:= msestringsearch(str1,po1^.text,1,options,str2); + end; + end; + end; +end; + +function tcustomtextedit.getgridvalue(const index: integer): msestring; +begin + result:= flines[index]; +end; + +procedure tcustomtextedit.setgridvalue(const index: integer; + const Value: msestring); +begin + flines[index]:= value; +end; + +function tcustomtextedit.linecount: integer; +begin + if flines = nil then begin + result:= 0; + end + else begin + result:= flines.count; + end; +end; + +function tcustomtextedit.getgridvalues: msestringarty; +begin + result:= flines.asmsestringarray; +end; + +procedure tcustomtextedit.setgridvalues(const Value: msestringarty); +begin + flines.asmsestringarray:= value; +end; + +function tcustomtextedit.getrichlines(const index: integer): richstringty; +begin + result:= flines.richitems[index]; +end; + +procedure tcustomtextedit.setrichlines(const index: integer; + const Value: richstringty); +begin + flines.richitems[index]:= value; +end; + +function tcustomtextedit.getrichformats(const index: integer): formatinfoarty; +begin + result:= flines.formats[index]; +end; + +procedure tcustomtextedit.setrichformats(const index: integer; + const avalue: formatinfoarty); +begin + flines.formats[index]:= avalue; +end; + +procedure tcustomtextedit.setmodified(const avalue: boolean); +begin + if fmodified <> avalue then begin + fmodified := avalue; + if canevent(tmethod(fonmodifiedchanged)) then begin + fonmodifiedchanged(self,avalue); + end; + end; +end; + +procedure tcustomtextedit.setdatalist(const avalue: tgridrichstringdatalist); +begin + flines.assign(avalue); +end; + +procedure tcustomtextedit.textinserted (const apos: gridcoordty; + const atext: msestring; const selected: boolean; + const endpos: gridcoordty; const backwards: boolean); +begin + //dummy +end; + +procedure tcustomtextedit.textdeleted(const apos: gridcoordty; + const atext: msestring; const selected: boolean; + const endpos: gridcoordty; const backwards: boolean); +begin + //dummy +end; + +procedure tcustomtextedit.dosetupeditor(); +begin + if canevent(tmethod(fonsetupeditor)) then begin + fonsetupeditor(self); + end; +end; + +procedure tcustomtextedit.setupeditor; +var + rect1: rectty; +begin + if not (csloading in componentstate) then begin + with feditor do begin + //feditor text already set + rect1:= innerclientrect; + if fframe = nil then begin + deflaterect1(rect1,texteditminimalframe); + end; + setup(text,curindex,false,rect1,clientrect,richtext.format,ftabulators,font); + end; + dosetupeditor(); + end; +end; + +procedure tcustomtextedit.checkgrid; +begin + if fgridintf = nil then begin + raise exception.Create('No grid.'); + end; +end; + +procedure tcustomtextedit.colchanged; +begin + invalidate; + if fgridintf <> nil then begin + fgridintf.getcol.invalidate; + end; +end; + +procedure tcustomtextedit.setmarginlinecolor(avalue: colorty); +begin + if avalue = cl_invalid then begin + avalue:= cl_none; + end; + if fmarginlinecolor <> avalue then begin + fmarginlinecolor := avalue; + colchanged; + end; +end; + +procedure tcustomtextedit.setmarginlinepos(const avalue: integer); +begin + if fmarginlinepos <> avalue then begin + fmarginlinepos := avalue; + colchanged; + end; +end; + +procedure tcustomtextedit.createtabulators; +begin + ftabulators:= ttabulators.create; + ftabulators.onchange:= {$ifdef FPC}@{$endif}tabulatorschanged; + tabulatorschanged(nil,-1); +end; + +function tcustomtextedit.gettabulators: ttabulators; +begin + getoptionalobject(ftabulators,{$ifdef FPC}@{$endif}createtabulators); + result:= ftabulators; +end; + +procedure tcustomtextedit.settabulators(const Value: ttabulators); +begin + setoptionalobject(value,ftabulators,{$ifdef FPC}@{$endif}createtabulators); +end; + +procedure tcustomtextedit.tabulatorschanged(const sender: tarrayprop; + const index: integer); +begin + if not (csloading in componentstate) then begin + colchanged; + end; +end; + +procedure tcustomtextedit.inserttext(const atext: msestring; + selected: boolean = false); +begin + inserttext(editpos,atext,selected); +end; + +procedure tcustomtextedit.beforecelldragevent(var ainfo: draginfoty; + const arow: integer; var handled: boolean); +begin + //dummy +end; + +procedure tcustomtextedit.aftercelldragevent(var ainfo: draginfoty; + const arow: integer; var handled: boolean); +begin + //dummy +end; +{ +procedure tcustomtextedit.setreadonly(const avalue: boolean); +begin + if avalue then begin + optionsedit:= optionsedit + [oe_readonly]; + end + else begin + optionsedit:= optionsedit - [oe_readonly]; + end; +end; +} +function tcustomtextedit.getinnerframe: framety; +begin + result:= minimaltextframe; +end; + +function tcustomtextedit.getgridintf: iwidgetgrid; +begin + result:= fgridintf; +end; + +procedure tcustomtextedit.datalistdestroyed; +begin + flines:= nil; +end; + +function tcustomtextedit.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +procedure tcustomtextedit.setvaluedata(const source); +begin + text:= msestring(source); +end; + +procedure tcustomtextedit.setparentgridwidget(const intf: igridwidget); +begin + //dummy +end; + +procedure tcustomtextedit.childdataentered(const sender: igridwidget); +begin + //dummy +end; + +procedure tcustomtextedit.childfocused(const sender: igridwidget); +begin + //dummy +end; + +procedure tcustomtextedit.getvaluedata(out dest); +begin + msestring(dest):= text; +end; + +procedure tcustomtextedit.setoptions(const avalue: texteditoptionsty); +begin + if foptions <> avalue then begin + foptions:= texteditoptionsty(setsinglebit(card32(avalue),card32(foptions), + card32([teeo_bom,teeo_nobom]))); + end; +end; + +{ tundotextedit } + +constructor tundotextedit.create(aowner: tcomponent); +begin + feditor:= tundoinplaceedit.create(self,iedit(self),iundo(self),true); + inherited; +end; + +function tundotextedit.canredo: boolean; +begin + result:= tundoinplaceedit(feditor).undolist.canredo; +end; + +function tundotextedit.canundo: boolean; +begin + result:= tundoinplaceedit(feditor).undolist.canundo; +end; + +function tundotextedit.getmaxundocount: integer; +begin + result:= tundoinplaceedit(feditor).undolist.maxcount; +end; + +procedure tundotextedit.setmaxundocount(const Value: integer); +begin + tundoinplaceedit(feditor).undolist.maxcount:= value; +end; + +function tundotextedit.getmaxundosize: integer; +begin + result:= tundoinplaceedit(feditor).undolist.maxsize; +end; + +procedure tundotextedit.setmaxundosize(const Value: integer); +begin + tundoinplaceedit(feditor).undolist.maxsize:= value; +end; + +procedure tundotextedit.undo; +begin + tundoinplaceedit(feditor).undolist.undo; +end; + +procedure tundotextedit.redo; +begin + tundoinplaceedit(feditor).undolist.redo; +end; + +procedure tundotextedit.textinserted(const apos: gridcoordty; const atext: msestring; + const selected: boolean; const endpos: gridcoordty; const backwards: boolean); +begin + tundoinplaceedit(feditor).undolist.inserttext(apos,endpos,atext,selected,backwards); +end; + +procedure tundotextedit.textdeleted(const apos: gridcoordty; + const atext: msestring; const selected: boolean; + const endpos: gridcoordty; const backwards: boolean); +begin + tundoinplaceedit(feditor).undolist.deletetext(apos,endpos,atext,selected,backwards) +end; + +procedure tundotextedit.getselectstart(var selectstartpos: gridcoordty); +begin + selectstartpos:= fselectstart; +end; + +procedure tundotextedit.setselectstart(const selectstartpos: gridcoordty); +begin + internalclearselection; + include(ftextstate,tes_selectinvalid); + fselectstart:= selectstartpos; +end; + +procedure tundotextedit.lowercase; +var + mstr1: msestring; +begin + if hasselection then begin + tundoinplaceedit(feditor).begingroup; + try + mstr1:= selectedtext; + deleteselection; + inserttext(mselowercase(mstr1),true); + finally + tundoinplaceedit(feditor).endgroup; + end; + end; +end; + +procedure tundotextedit.uppercase; +var + mstr1: msestring; +begin + if hasselection then begin + tundoinplaceedit(feditor).begingroup; + try + mstr1:= selectedtext; + deleteselection; + inserttext(mseuppercase(mstr1),true); + finally + tundoinplaceedit(feditor).endgroup; + end; + end; +end; + +procedure tundotextedit.tabtospace; +var + mstr1: msestring; +begin + if hasselection then begin + tundoinplaceedit(feditor).begingroup; + try + mstr1:= selectedtext; + replacechar1(mstr1,msechar(c_tab),msechar(' ')); + deleteselection; + inserttext(mstr1,true); + finally + tundoinplaceedit(feditor).endgroup; + end; + end; +end; + +procedure tundotextedit.clear; +begin + tundoinplaceedit(feditor).undolist.clear; + inherited; +end; + +initialization + registergriddatalistclass(tgridrichstringdatalist.classname, + {$ifdef FPC}@{$endif}createtgridrichstringdatalist); +end. diff --git a/mseide-msegui/lib/common/editwidgets/msevaluenodes.pas b/mseide-msegui/lib/common/editwidgets/msevaluenodes.pas new file mode 100644 index 0000000..a688b9a --- /dev/null +++ b/mseide-msegui/lib/common/editwidgets/msevaluenodes.pas @@ -0,0 +1,777 @@ +{ MSEgui Copyright (c) 1999-2015 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msevaluenodes; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + mseglob,msestrings,msedatalist,msedatanodes,msebitmap,mselistbrowser, + msetypes,msevaluenodesglob,mseinterfaces,msestat; + +const + valuenodetypename = 't'; + valuenodeindexname = 'i'; + valuenodevaluename = 'v'; + +type + irecordfield = interface(inullinterface) [miid_irecordfield] + function getfieldtext(const afieldindex: integer): msestring; + procedure setfieldtext(const afieldindex: integer; var avalue: msestring); + end; + + getvaluemethodty = procedure(out dest) of object; + + irecordvaluefield = interface(irecordfield) [miid_irecordvaluefield] + procedure getvalueinfo(out avalues: recvaluearty; const aindex: int32 = -1); + //-1 -> all + procedure setvalue(const atype: listdatatypety; + const aindex: int32; const getvaluemethod: getvaluemethodty); + end; + + trecordfielditem = class(ttreelistitem) + private + ffieldindex: integer; + fintf: irecordfield; + protected + public + constructor create(const intf: irecordfield; const afieldindex: integer; + const acaption: msestring; + const fixedcaption: boolean = false; + const aimagenr: integer = 0; + const aimagelist: timagelist = nil); reintroduce; + function getvaluetext: msestring; override; + procedure setvaluetext(var avalue: msestring); override; + property fieldindex: integer read ffieldindex; +// property valuetext: msestring read getvaluetext write setvaluetext; + end; + + trecordfieldvalueitem = class(trecordfielditem,irecordvaluefield) + protected + function getfieldtext(const afieldindex: integer): msestring; + procedure setfieldtext(const afieldindex: integer; var avalue: msestring); + procedure getvalueinfo(out avalues: recvaluearty; const aindex: int32 = -1); + procedure setvalue(const atype: listdatatypety; + const aindex: int32; const getvaluemethod: getvaluemethodty); + public + constructor create(const intf: irecordvaluefield; const afieldindex: integer; + const acaption: msestring; + const fixedcaption: boolean = false; + const aimagenr: integer = 0; + const aimagelist: timagelist = nil); + end; + + fieldinfoty = record + datatype: listdatatypety; + data: pointer; + end; + +// +// hint: irecordvaluefield can be slow +// + trecordlistedititem = class(tlistedititem,irecordvaluefield) + private + protected + //irecordvaluefield + procedure getvalueinfo(out avalues: recvaluearty; const aindex: int32 = -1); + virtual; + function getfieldtext(const fieldindex: integer): msestring; virtual; + procedure setfieldtext(const fieldindex: integer; + var avalue: msestring); virtual; + procedure setvalue(const atype: listdatatypety; + const aindex: int32; const getvaluemethod: getvaluemethodty); virtual; + public + end; + + trecordtreelistedititem = class(ttreelistedititem,irecordvaluefield) + //does not statsave subitems + protected + //irecordvaluefield + procedure getvalueinfo(out avalues: recvaluearty; const aindex: int32 = -1); + virtual; + function getfieldtext(const fieldindex: integer): msestring; virtual; + procedure setfieldtext(const fieldindex: integer; + var avalue: msestring); virtual; + procedure setvalue(const atype: listdatatypety; + const aindex: int32; const getvaluemethod: getvaluemethodty); virtual; + public + constructor create(const aowner: tcustomitemlist = nil; + const aparent: ttreelistitem = nil); override; + end; + +{ + trecordtreelistedititem = class(tlistedititem,irecordvaluefield) + private + protected + procedure initvalueinfo(out ainfo: recvaluety); + procedure initvalueinfo(const aindex: int32; var avalue: int32; + out ainfo: recvaluety); + procedure initvalueinfo(const aindex: int32; var avalue: longbool; + out ainfo: recvaluety); + procedure initvalueinfo(const aindex: int32; var avalue: realty; + out ainfo: recvaluety); + procedure initvalueinfo(const aindex: int32; var avalue: tdatetime; + out ainfo: recvaluety); + procedure initvalueinfo(const aindex: int32; var avalue: msestring; + out ainfo: recvaluety); + //irecordvaluefield + procedure getvalueinfo(out avalues: recvaluearty); virtual; + function getfieldtext(const fieldindex: integer): msestring; virtual; + procedure setfieldtext(const fieldindex: integer; + var avalue: msestring); virtual; + procedure setvalue(const atype: listdatatypety; + const aindex: int32; const getvaluemethod: getvaluemethodty); virtual; + public + end; +} + trecordvaluelistedititem = class(trecordlistedititem) + private + protected + fvalueindex: int32; + procedure getvalueinfo(out avalues: recvaluearty; const aindex: int32 = -1); + override; + function getvaluetype: listdatatypety; virtual; + public + constructor create(const avalueindex: int32 = -1; + const aowner: tcustomitemlist = nil); virtual; + procedure dostatread(const reader: tstatreader); override; + procedure dostatwrite(const writer: tstatwriter); override; + property valueindex: int32 read fvalueindex write fvalueindex; + //-1 -> any + end; + recordvaluelistedititemty = class of trecordvaluelistedititem; + + tintegervaluelistedititem = class(trecordvaluelistedititem) + private + fvalue: int32; + procedure setvalue(const avalue: int32); + protected + function getvaluetype: listdatatypety; override; + procedure getvalueinfo(out avalues: recvaluearty; const aindex: int32 = -1); + override; + procedure setvalue(const atype: listdatatypety; + const aindex: int32; const getvaluemethod: getvaluemethodty); override; + public + procedure dostatread(const reader: tstatreader); override; + procedure dostatwrite(const writer: tstatwriter); override; + property value: int32 read fvalue write setvalue; + end; + + tbooleanvaluelistedititem = class(tintegervaluelistedititem) + private + procedure setvalue(const avalue: boolean); reintroduce; + function getvalue: boolean; + protected + public + property value: boolean read getvalue write setvalue; + end; + + trealvaluelistedititem = class(trecordvaluelistedititem) + private + fvalue: realty; + procedure setvalue(const avalue: realty); + protected + function getvaluetype: listdatatypety; override; + procedure getvalueinfo(out avalues: recvaluearty; const aindex: int32 = -1); + override; + procedure setvalue(const atype: listdatatypety; + const aindex: int32; const getvaluemethod: getvaluemethodty); override; + public + procedure dostatread(const reader: tstatreader); override; + procedure dostatwrite(const writer: tstatwriter); override; + property value: realty read fvalue write setvalue; + end; + + tdatetimevaluelistedititem = class(trealvaluelistedititem) + private +// fvalue: tdatetime; + procedure setvalue(const avalue: tdatetime); reintroduce; + protected +// procedure getvalueinfo(out avalues: recvaluearty; const aindex: int32 = -1); +// override; +// procedure setvalue(const atype: listdatatypety; +// const aindex: int32; const getvaluemethod: getvaluemethodty); override; + public + property value: tdatetime read fvalue write setvalue; + end; + + tmsestringvaluelistedititem = class(trecordvaluelistedititem) + private + fvalue: msestring; + procedure setvalue(const avalue: msestring); + protected + function getvaluetype: listdatatypety; override; + procedure getvalueinfo(out avalues: recvaluearty; const aindex: int32 = -1); + override; + procedure setvalue(const atype: listdatatypety; + const aindex: int32; const getvaluemethod: getvaluemethodty); override; + public + procedure dostatread(const reader: tstatreader); override; + procedure dostatwrite(const writer: tstatwriter); override; + property value: msestring read fvalue write setvalue; + end; + +const + valuenodeclasses: array[listdatatypety] of recordvaluelistedititemty = ( +//dl_none, dl_integer, + trecordvaluelistedititem,tintegervaluelistedititem, +//dl_int64, dl_currency, + trecordvaluelistedititem,trecordvaluelistedititem, +//dl_real, dl_realint, dl_realsum, + trealvaluelistedititem,trecordvaluelistedititem,trecordvaluelistedititem, +//dl_datetime, + tdatetimevaluelistedititem, +//dl_pointer + trecordvaluelistedititem, +//dl_ansistring, dl_msestring, + trecordvaluelistedititem,tmsestringvaluelistedititem, +//dl_doublemsestring, dl_msestringint, + trecordvaluelistedititem,trecordvaluelistedititem, +//dl_complex, dl_rowstate, dl_custom + trecordvaluelistedititem,trecordvaluelistedititem,trecordvaluelistedititem + ); + +procedure initvalueinfo(out ainfo: recvaluety); +procedure initvalueinfo(const aindex: int32; var avalue: int32; + out ainfo: recvaluety); +procedure initvalueinfo(const aindex: int32; var avalue: longbool; + out ainfo: recvaluety); +procedure initvalueinfo(const aindex: int32; var avalue: realty; + out ainfo: recvaluety); +procedure initvalueinfo(const aindex: int32; var avalue: tdatetime; + out ainfo: recvaluety); +procedure initvalueinfo(const aindex: int32; var avalue: msestring; + out ainfo: recvaluety); +function valuefield(var avalue: int32): fieldinfoty; +function valuefield(var avalue: longbool): fieldinfoty; +function valuefield(var avalue: real): fieldinfoty; +function valuefield(var avalue: realty): fieldinfoty; +function valuefield(var avalue: tdatetime): fieldinfoty; +function valuefield(var avalue: msestring): fieldinfoty; +function buildvalueinfos(const afields: array of fieldinfoty; + const aindex: int32): recvaluearty; + //-1 -> all + +implementation +uses + msearrayutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +procedure initvalueinfo(out ainfo: recvaluety); +begin + ainfo.dummypointer:= nil; +end; + +procedure initvalueinfo(const aindex: int32; + var avalue: int32; out ainfo: recvaluety); +begin + initvalueinfo(ainfo); + ainfo.datatype:= dl_integer; + ainfo.valueindex:= aindex; + ainfo.valuead:= @avalue; +end; + +procedure initvalueinfo(const aindex: int32; + var avalue: longbool; out ainfo: recvaluety); +begin + initvalueinfo(ainfo); + ainfo.datatype:= dl_integer; + ainfo.valueindex:= aindex; + ainfo.valuead:= @avalue; +end; + +procedure initvalueinfo(const aindex: int32; + var avalue: realty; out ainfo: recvaluety); +begin + initvalueinfo(ainfo); + ainfo.datatype:= dl_real; + ainfo.valueindex:= aindex; + ainfo.valuead:= @avalue; +end; + +procedure initvalueinfo(const aindex: int32; + var avalue: tdatetime; out ainfo: recvaluety); +begin + initvalueinfo(ainfo); + ainfo.datatype:= dl_real; + ainfo.valueindex:= aindex; + ainfo.valuead:= @avalue; +end; + +procedure initvalueinfo(const aindex: int32; + var avalue: msestring; out ainfo: recvaluety); +begin + initvalueinfo(ainfo); + ainfo.datatype:= dl_msestring; + ainfo.valueindex:= aindex; + ainfo.valuead:= @avalue; +end; + +function valuefield(var avalue: int32): fieldinfoty; +begin + result.datatype:= dl_integer; + result.data:= @avalue; +end; + +function valuefield(var avalue: longbool): fieldinfoty; +begin + result.datatype:= dl_integer; + result.data:= @avalue; +end; + +function valuefield(var avalue: real): fieldinfoty; +begin + result.datatype:= dl_real; + result.data:= @avalue; +end; + +function valuefield(var avalue: realty): fieldinfoty; +begin + result.datatype:= dl_real; + result.data:= @avalue; +end; + +function valuefield(var avalue: tdatetime): fieldinfoty; +begin + result.datatype:= dl_real; + result.data:= @avalue; +end; + +function valuefield(var avalue: msestring): fieldinfoty; +begin + result.datatype:= dl_msestring; + result.data:= @avalue; +end; + +function buildvalueinfos( + const afields: array of fieldinfoty; + const aindex: int32): recvaluearty; + + procedure setup(const aindex: int32; const source: fieldinfoty; + out dest: recvaluety); + begin + initvalueinfo(dest); + dest.datatype:= source.datatype; + dest.valueindex:= aindex; + dest.valuead:= source.data; + end;//setup + +var + i1: int32; +begin + if aindex < 0 then begin + setlength(result,length(afields)); + for i1:= 0 to high(result) do begin + setup(i1,afields[i1],result[i1]); + end; + end + else begin + if aindex <= high(afields) then begin + setlength(result,1); + setup(aindex,afields[aindex],result[0]); + end + else begin + result:= nil; + end; + end; +end; + +{ trecordfielditem } + +constructor trecordfielditem.create(const intf: irecordfield; + const afieldindex: integer; + const acaption: msestring; const fixedcaption: boolean; + const aimagenr: integer = 0; + const aimagelist: timagelist = nil); +begin + fintf:= intf; + ffieldindex:= afieldindex; + inherited create; + fcaption:= acaption; + fimagenr:= aimagenr; + imagelist:= aimagelist; + if fixedcaption then begin + fstate1:= fstate1 + [ns1_fixedcaption]; + end; +end; + +function trecordfielditem.getvaluetext: msestring; +begin + if fintf <> nil then begin + result:= fintf.getfieldtext(ffieldindex); + end + else begin + result:= inherited getvaluetext; + end; +end; + +procedure trecordfielditem.setvaluetext(var avalue: msestring); +begin + if fintf <> nil then begin + fintf.setfieldtext(ffieldindex,avalue); + end + else begin + if not (ns1_fixedcaption in fstate1) then begin + inherited; + end; + end; +end; + +{ trecordfieldvalueitem } + +constructor trecordfieldvalueitem.create(const intf: irecordvaluefield; + const afieldindex: integer; const acaption: msestring; + const fixedcaption: boolean = false; const aimagenr: integer = 0; + const aimagelist: timagelist = nil); +begin + inherited create(intf,afieldindex,acaption,fixedcaption,aimagenr,aimagelist); +end; + +procedure trecordfieldvalueitem.getvalueinfo(out avalues: recvaluearty; + const aindex: int32 = -1); +begin + irecordvaluefield(fintf).getvalueinfo(avalues,fieldindex); +end; + +procedure trecordfieldvalueitem.setvalue(const atype: listdatatypety; + const aindex: int32; const getvaluemethod: getvaluemethodty); +begin + irecordvaluefield(fintf).setvalue(atype,aindex,getvaluemethod); +end; + +function trecordfieldvalueitem.getfieldtext( + const afieldindex: integer): msestring; +begin + result:= ''; +end; + +procedure trecordfieldvalueitem.setfieldtext(const afieldindex: integer; + var avalue: msestring); +begin + //dummy +end; + +{ trecordtreelistedititem } + +constructor trecordtreelistedititem.create(const aowner: tcustomitemlist; + const aparent: ttreelistitem); +begin + inherited; + include(fstate,ns_nosubnodestat); +end; + +function trecordtreelistedititem.getfieldtext( + const fieldindex: integer): msestring; +begin + result:= ''; +end; + +procedure trecordtreelistedititem.setfieldtext(const fieldindex: integer; + var avalue: msestring); +begin + //dummy +end; + +procedure trecordtreelistedititem.setvalue(const atype: listdatatypety; + const aindex: int32; const getvaluemethod: getvaluemethodty); +var + values1: recvaluearty; +begin + if aindex >= 0 then begin + getvalueinfo(values1,aindex); + if (values1 <> nil) then begin + with values1[0] do begin + if datatype = atype then begin + getvaluemethod(valuead^); + end; + end; + end; + end; +end; + +procedure trecordtreelistedititem.getvalueinfo(out avalues: recvaluearty; + const aindex: int32 = -1); +begin + avalues:= nil; +end; + +{ trecordlistedititem } + +procedure trecordlistedititem.getvalueinfo(out avalues: recvaluearty; + const aindex: int32 = -1); +begin + avalues:= nil; +end; + +function trecordlistedititem.getfieldtext( + const fieldindex: integer): msestring; +begin + result:= ''; +end; + +procedure trecordlistedititem.setfieldtext(const fieldindex: integer; + var avalue: msestring); +begin + //dummy +end; + +procedure trecordlistedititem.setvalue(const atype: listdatatypety; + const aindex: int32; const getvaluemethod: getvaluemethodty); +begin + //dummy +end; + +{ trecordvaluelistedititem } + +constructor trecordvaluelistedititem.create(const avalueindex: int32; + const aowner: tcustomitemlist = nil); +begin + fvalueindex:= avalueindex; + create(aowner); +end; + +procedure trecordvaluelistedititem.getvalueinfo(out avalues: recvaluearty; + const aindex: int32 = -1); +begin + avalues:= nil; + allocuninitedarray(1,sizeof(recvaluety),avalues); + with avalues[0] do begin + datatype:= dl_none; + valueindex:= fvalueindex; + valuead:= nil; + dummypointer:= nil; + end; +end; + +procedure trecordvaluelistedititem.dostatread(const reader: tstatreader); +begin + inherited; + fvalueindex:= reader.readinteger(valuenodeindexname,fvalueindex); +end; + +procedure trecordvaluelistedititem.dostatwrite(const writer: tstatwriter); +begin + inherited; + writer.writeinteger(valuenodetypename,ord(getvaluetype)); + writer.writeinteger(valuenodeindexname,fvalueindex); +end; + +function trecordvaluelistedititem.getvaluetype: listdatatypety; +begin + result:= dl_none; +end; + +{ tintegervaluelistedititem } + +procedure tintegervaluelistedititem.setvalue(const avalue: int32); +begin + if fvalue <> avalue then begin + fvalue:= avalue; + valuechange([]); + end; +end; + +procedure tintegervaluelistedititem.getvalueinfo(out avalues: recvaluearty; + const aindex: int32 = -1); +begin + inherited; + with avalues[0] do begin + datatype:= dl_integer; + valuead:= @fvalue; + end; +end; + +procedure tintegervaluelistedititem.setvalue(const atype: listdatatypety; + const aindex: int32; const getvaluemethod: getvaluemethodty); +var + i1: int32; +begin + if (atype = dl_integer) then begin + getvaluemethod(i1); + value:= i1; + end; +end; + +procedure tintegervaluelistedititem.dostatread(const reader: tstatreader); +begin + inherited; + fvalue:= reader.readinteger(valuenodevaluename,fvalue); +end; + +procedure tintegervaluelistedititem.dostatwrite(const writer: tstatwriter); +begin + inherited; + writer.writeinteger(valuenodevaluename,fvalue); +end; + +function tintegervaluelistedititem.getvaluetype: listdatatypety; +begin + result:= dl_integer; +end; + +{ tbooleanvaluelistedititem } + +procedure tbooleanvaluelistedititem.setvalue(const avalue: boolean); +begin + if longbool(fvalue) <> avalue then begin + longbool(fvalue):= avalue; + valuechange([]); + end; +end; + +function tbooleanvaluelistedititem.getvalue: boolean; +begin + result:= longbool(fvalue); +end; + +{ trealvaluelistedititem } + +procedure trealvaluelistedititem.setvalue(const avalue: realty); +begin + if fvalue <> avalue then begin + fvalue:= avalue; + valuechange([]); + end; +end; + +procedure trealvaluelistedititem.getvalueinfo(out avalues: recvaluearty; + const aindex: int32 = -1); +begin + inherited; + with avalues[0] do begin + datatype:= dl_real; + valuead:= @fvalue; + end; +end; + +procedure trealvaluelistedititem.setvalue(const atype: listdatatypety; + const aindex: int32; const getvaluemethod: getvaluemethodty); +var + rea1: realty; +begin + if (atype = dl_real) then begin + getvaluemethod(rea1); + value:= rea1; + end; +end; + +function trealvaluelistedititem.getvaluetype: listdatatypety; +begin + result:= dl_real; +end; + +procedure trealvaluelistedititem.dostatread(const reader: tstatreader); +begin + inherited; + fvalue:= reader.readreal(valuenodevaluename,fvalue); +end; + +procedure trealvaluelistedititem.dostatwrite(const writer: tstatwriter); +begin + inherited; + writer.writereal(valuenodevaluename,fvalue); +end; + +{ tdatetimevaluelistedititem } + +procedure tdatetimevaluelistedititem.setvalue(const avalue: tdatetime); +begin + inherited setvalue(avalue); +{ + if fvalue <> avalue then begin + fvalue:= avalue; + valuechange(); + end; +} +end; +{ +procedure tdatetimevaluelistedititem.getvalueinfo(out avalues: recvaluearty; + const aindex: int32 = -1); +begin + inherited; + with avalues[0] do begin + datatype:= dl_real; + valuead:= @fvalue; + end; +end; + +procedure tdatetimevaluelistedititem.setvalue(const atype: listdatatypety; + const aindex: int32; const getvaluemethod: getvaluemethodty); +var + dat1: tdatetime; +begin + if (atype = dl_real) then begin + getvaluemethod(dat1); + value:= dat1; + end; +end; +} +{ tmsestringvaluelistedititem } + +procedure tmsestringvaluelistedititem.setvalue(const avalue: msestring); +begin + if fvalue <> avalue then begin + fvalue:= avalue; + valuechange([]); + end; +end; + +procedure tmsestringvaluelistedititem.getvalueinfo(out avalues: recvaluearty; + const aindex: int32 = -1); +begin + inherited; + with avalues[0] do begin + datatype:= dl_msestring; + valuead:= @fvalue; + end; +end; + +procedure tmsestringvaluelistedititem.setvalue(const atype: listdatatypety; + const aindex: int32; const getvaluemethod: getvaluemethodty); +var + mstr1: msestring; +begin + if (atype = dl_msestring) then begin + getvaluemethod(mstr1); + value:= mstr1; + end; +end; + +function tmsestringvaluelistedititem.getvaluetype: listdatatypety; +begin + result:= dl_msestring; +end; + +procedure tmsestringvaluelistedititem.dostatread(const reader: tstatreader); +begin + inherited; + fvalue:= reader.readmsestring(valuenodevaluename,fvalue); +end; + +procedure tmsestringvaluelistedititem.dostatwrite(const writer: tstatwriter); +begin + inherited; + writer.writemsestring(valuenodevaluename,fvalue); +end; + +end. diff --git a/mseide-msegui/lib/common/editwidgets/msevaluenodesglob.pas b/mseide-msegui/lib/common/editwidgets/msevaluenodesglob.pas new file mode 100644 index 0000000..c77e6d0 --- /dev/null +++ b/mseide-msegui/lib/common/editwidgets/msevaluenodesglob.pas @@ -0,0 +1,26 @@ +{ MSEgui Copyright (c) 1999-2015 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msevaluenodesglob; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msedatalist,mseglob; +type + recvaluety = record + datatype: listdatatypety; + valueindex: int32; + valuead: pointer; + dummypointer: pointer; //can be used by clients, inited with nil + end; + precvaluety = ^recvaluety; + recvaluearty = array of recvaluety; + +implementation +end. diff --git a/mseide-msegui/lib/common/editwidgets/msewidgetgrid.pas b/mseide-msegui/lib/common/editwidgets/msewidgetgrid.pas new file mode 100644 index 0000000..f83b207 --- /dev/null +++ b/mseide-msegui/lib/common/editwidgets/msewidgetgrid.pas @@ -0,0 +1,4084 @@ +{ MSEgui Copyright (c) 1999-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msewidgetgrid; +{$ifdef FPC} + {$mode objfpc}{$h+}{$interfaces corba} +{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + mseclasses,msegrids,msegui,msegraphutils,mseglob,mseguiglob,mseeditglob, + classes,mclasses,msemenus,msearrayutils,msedragglob,mseinterfaces, + msegraphics,mseevent,msedatalist,msetypes,msepointer,msestrings, + mseassistiveclient, + msegridsglob{$ifdef mse_with_ifi},mseificomp{$endif}; + +//todo: simplify handling of changed column widgets in inherited grids + +type + + twidgetcol = class; + tcustomwidgetgrid = class; + + iwidgetgrid = interface(inullinterface) + function getgrid: tcustomwidgetgrid; + function getbrushorigin: pointty; + function getcol: twidgetcol; + function getdatapo(const arow: integer): pointer; + function getrowdatapo: pointer; + procedure getdata(var index: integer; var dest); + procedure setdata(var index: integer; const source; + const noinvalidate: boolean = false); + procedure datachange(const index: integer); + function getrow: integer; + procedure setrow(arow: integer); + procedure changed(); + procedure edited(); + function empty(index: integer): boolean; + function cangridcopy: boolean; + procedure updateeditoptions(var aoptions: optionseditty; + const aoptions1: optionsedit1ty); + procedure coloptionstoeditoptions(var dest: optionseditty; + var dest1: optionsedit1ty); + function showcaretrect(const arect: rectty; + const aframe: tcustomframe): pointty; + procedure widgetpainted(const canvas: tcanvas); + function nullcheckneeded(const newfocus: twidget): boolean; + function nonullcheck: boolean; + function nocheckvalue: boolean; + property grid: tcustomwidgetgrid read getgrid; + {$ifdef mse_with_ifi} + procedure updateifigriddata(const alist: tdatalist); + {$endif} + end; + + igridwidget = interface(inullinterface)[miid_igridwidget] + procedure setfirstclick(var ainfo: mouseeventinfoty); + function getwidget: twidget; + procedure getautocellsize(const acanvas: tcanvas; var asize: sizety); + procedure updatepopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); + function getcellframe: framety; + function needscellfocuspaint(): boolean; + function getcellcursor(const arow: integer; //-1 -> widget + const acellzone: cellzonety; const apos: pointty): cursorshapety; + procedure updatecellzone(const arow: integer; //-1 -> widget + const apos: pointty; + var result: cellzonety); + function createdatalist(const sender: twidgetcol): tdatalist; + function getdatalistclass: datalistclassty; + procedure datalistdestroyed; + function getdefaultvalue: pointer; +// function getrowdatapo(const info: cellinfoty): pointer; + function getrowdatapo(const arow: integer): pointer; + function getoptionsedit: optionseditty; + procedure setgridintf(const intf: iwidgetgrid); + function getgridintf: iwidgetgrid; + procedure drawcell(const canvas: tcanvas); + procedure updateautocellsize(const canvas: tcanvas); + procedure beforecelldragevent(var ainfo: draginfoty; const arow: integer; + var processed: boolean); + procedure aftercelldragevent(var ainfo: draginfoty; const arow: integer; + var processed: boolean); + procedure initgridwidget; + procedure gridtovalue(row: integer); //row = -1 -> focused row, + // -2 -> default value + procedure valuetogrid(row: integer); //row = -1 -> focused row + function getnulltext: msestring; + function getassistivecelltext(const arow: int32): msestring; + procedure docellevent(const ownedcol: boolean; var info: celleventinfoty); + function sortfunc(const l,r): integer; + procedure gridvaluechanged(const index: integer); //index = -1 -> undefined, all + procedure updatecoloptions(const aoptions: coloptionsty); + procedure updatecoloptions1(const aoptions: coloptions1ty); + procedure statdataread; + procedure griddatasourcechanged; + procedure setreadonly(const avalue: boolean); + {$ifdef mse_with_ifi} + function getifilink: tifilinkcomp; + {$endif} + //for titemedit children + procedure setparentgridwidget(const intf: igridwidget); + procedure setvaluedata(const source); + procedure getvaluedata(out dest); + procedure childdataentered(const sender: igridwidget); + procedure childfocused(const sender: igridwidget); + end; + + twidgetcol = class(tdatacol,iwidgetgrid,idatalistclient) + private + fwidgetname: string; + ffixrowwidgets: widgetarty; + ffixrowwidgetnames: stringarty; + fondrawcell: drawcelleventty; + procedure updatewidgetrect(const updatedata: boolean = false); + procedure readwidgetname(reader: treader); + procedure writewidgetname(writer: twriter); + procedure readfixwidgetnames(reader: treader); + procedure writefixwidgetnames(writer: twriter); + procedure readdataclass(reader: treader); + procedure writedataclass(writer: twriter); + procedure readdatatype(reader: treader); + procedure writedatatype(writer: twriter); + procedure readdata(reader: treader); + procedure writedata(writer: twriter); + procedure readdataprops(reader: treader); + procedure writedataprops(writer: twriter); + function getfixrowwidgets(aindex: integer): twidget; + procedure setfixrowwidgets(aindex: integer; const avalue: twidget); + protected + fintf: igridwidget; + //iwidgetgrid + function getgrid: tcustomwidgetgrid; + procedure edited(); + function getbrushorigin: pointty; + function getcol: twidgetcol; + procedure getdata(var arow: integer; var dest); + procedure setdata(var arow: integer; + const source; const noinvalidate: boolean = false); virtual; + function getrow: integer; + procedure setrow(arow: integer); + function empty(arow: integer): boolean; + function cangridcopy: boolean; + procedure updateeditoptions(var aoptions: optionseditty; + const aoptions1: optionsedit1ty); + function showcaretrect(const arect: rectty; const aframe: tcustomframe): pointty; + procedure widgetpainted(const canvas: tcanvas); + function nullcheckneeded(const newfocus: twidget): boolean; + function nonullcheck: boolean; + function nocheckvalue: boolean; + {$ifdef mse_with_ifi} + procedure updateifigriddata(const alist: tdatalist); + {$endif} + + procedure checkcanclose(var accepted: boolean); + procedure docellfocuschanged(enter: boolean; + const cellbefore: gridcoordty; var newcell: gridcoordty; + const selectaction: focuscellactionty); override; + procedure defineproperties(filer: tfiler); override; + function getdatapo(const arow: integer): pointer; override; + procedure drawcell(const canvas: tcanvas); override; + procedure drawfocusedcell(const acanvas: tcanvas); override; + procedure drawfocus(const acanvas: tcanvas); override; + function sortcompare(const index1,index2: integer): integer; override; + procedure itemchanged(const sender: tdatalist; + const aindex: integer); override; + procedure setwidget(const awidget: twidget); virtual; + procedure seteditwidget(const value: twidget); + procedure setfixrowwidget(const awidget: twidget; const rowindex: integer); + function geteditwidget: twidget; + function getinnerframe: framety; override; + procedure setoptions(const avalue: coloptionsty); override; + procedure setoptions1(const avalue: coloptions1ty); override; + function getcursor(const arow: integer; const actcellzone: cellzonety; + const amousepos: pointty): cursorshapety; override; + procedure datasourcechanged; + procedure beforedragevent(var ainfo: draginfoty; const arow: integer; + var processed: boolean); override; + procedure afterdragevent(var ainfo: draginfoty; const arow: integer; + var processed: boolean); override; + + public + constructor create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); override; + destructor destroy; override; + procedure sourcenamechanged(const atag: integer); + procedure updatecellzone(const row: integer; const pos: pointty; + var result: cellzonety); override; + function actualfont: tfont; override; + property editwidget: twidget read geteditwidget write seteditwidget; + property fixrowwidgets[aindex: integer]: twidget read getfixrowwidgets + write setfixrowwidgets; + property grid: tcustomwidgetgrid read getgrid; + published + property datalist stored false; //stored by defineproperties + property ondrawcell: drawcelleventty read fondrawcell write fondrawcell; + end; + widgetcolarty = array of twidgetcol; + twidgetfixrow = class(tfixrow) + end; + + twidgetfixrows = class(tfixrows) + private + fwidgetrectupdating: integer; + procedure unregisterchildwidget(const child: twidget); + function getrows(const aindex: integer): twidgetfixrow; + procedure updatewidgetrect; + protected + procedure countchanged; override; + public + constructor create(const owner: tcustomwidgetgrid); + procedure move(const curindex,newindex: integer); override; + property rows[const index: integer]: twidgetfixrow read getrows; default; + end; + + twidgetcols = class(tdatacols) + private + fcolorder: stringarty; + fcolcount: integer; + function getcols(const index: integer): twidgetcol; + procedure unregisterchildwidget(const child: twidget); + procedure updatecolorder; + procedure writeorder(writer: twriter); + procedure readorder(reader: treader); + protected + procedure updatedatastate(var accepted: boolean); override; + procedure defineproperties(filer: tfiler); override; + function getcollectionname(const aindex: integer): string; override; + procedure setcount1(acount: integer; doinit: boolean); override; + public + constructor create(const aowner: tcustomwidgetgrid); + class function getitemclasstype: persistentclassty; override; + procedure datasourcechanged; override; + property cols[const index: integer]: twidgetcol read getcols; default; + end; + + twidgetfixcol = class(tfixcol) + private + ffixrowwidgets: widgetarty; + ffixrowwidgetnames: stringarty; + procedure readfixwidgetnames(reader: treader); + procedure writefixwidgetnames(writer: twriter); + function getfixrowwidgets(aindex: integer): twidget; + procedure setfixrowwidgets(aindex: integer; const avalue: twidget); + protected + procedure defineproperties(filer: tfiler); override; + procedure setfixrowwidget(const awidget: twidget; const rowindex: integer); + public + constructor create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); override; + destructor destroy; override; + property fixrowwidgets[aindex: integer]: twidget read getfixrowwidgets + write setfixrowwidgets; + end; + + twidgetfixcols = class(tfixcols) + private + function getcols(const index: integer): twidgetfixcol; + protected + procedure unregisterchildwidget(const child: twidget); + public + constructor create(const aowner: tcustomwidgetgrid); + property cols[const index: integer]: twidgetfixcol read getcols; default; + end; + + tdummywidget = class(twidget) + protected + function getassistiveflags(): assistiveflagsty override; + public + constructor create(aowner: tcomponent); override; + function setfocus(aactivate: boolean = true): boolean; override; + //unsetsfocus if not focusable + end; + + tcustomwidgetgrid = class(tcustomgrid) + private + fcontainer0: twidget; //nohscroll + fcontainer1: twidget; //top + fcontainer2: twidget; //grid + fcontainer3: twidget; //bottom + flastfocusedfixwidget: twidget; + fwidgetdummy: tdummywidget; + fmouseinfopo: pmouseeventinfoty; + function getdatacols: twidgetcols; + procedure setdatacols(const avalue: twidgetcols); + procedure initcopyars(out dataedits: widgetarty; + out datalists: datalistarty); + procedure dowidgetcellevent(var info: celleventinfoty); + function getfixrows: twidgetfixrows; + procedure setfixrows(const avalue: twidgetfixrows); + function getfixcols: twidgetfixcols; + procedure setfixcols(const avalue: twidgetfixcols); + protected + ffocuslock: integer; + factivewidget: twidget; + function getgriddatalink: pointer; virtual; + procedure setoptionswidget(const avalue: optionswidgetty); override; + procedure setoptionsgrid(const avalue: optionsgridty); override; + function checksubfocus(const aactivate: boolean): boolean; override; + procedure dochildfocused(const sender: twidget); override; + procedure unregisterchildwidget(const child: twidget); override; + procedure widgetregionchanged(const sender: twidget); override; + function createdatacols: tdatacols; override; + function createfixrows: tfixrows; override; + function createfixcols: tfixcols; override; + procedure createdatacol(const index: integer; out item: tdatacol); override; + procedure scrolled(const dist: pointty); override; + procedure updatecontainerrect; + procedure updatelayout; override; + procedure getchildren(proc: tgetchildproc; root: tcomponent); override; +// procedure dobeginread; override; + procedure doendread; override; + function scrollcaret(const vertical: boolean): boolean; override; + procedure docellevent(var info: celleventinfoty); override; + procedure checkcellvalue(var accept: boolean); override; //store edited value to grid + procedure dofocusedcellposchanged; override; + procedure dorowsmoved(const fromindex,toindex,count: integer); override; + procedure mouseevent(var info: mouseeventinfoty); override; + procedure childmouseevent(const sender: twidget; var info: mouseeventinfoty); override; + procedure clientmouseevent(var info: mouseeventinfoty); override; + procedure dokeydown(var info: keyeventinfoty); override; + procedure doexit; override; + procedure navigrequest(var info: naviginfoty; + const nowrap: boolean); override; + procedure checkrowreadonlystate; override; + procedure updaterowdata; override; + function cellhasfocus: boolean; override; + + function getcontainer: twidget; override; + function getchildwidgets(const index: integer): twidget; override; + procedure removefixwidget(const awidget: twidget); + procedure updatepopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); override; + //iassistiveclientgrid + function getassistiveflags(): assistiveflagsty override; + function getassistivecelltext(const acell: gridcoordty; + out aflags: assistiveflagsty): msestring; override; + function getassistivecaretindex(): int32; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure writestate(writer: twriter); override; + procedure insertwidget(const awidget: twidget; const apos: pointty); override; + function childrencount: integer; override; + function getlogicalchildren: widgetarty; override; + + procedure focuslock; //beginupdate + no cell widget focus/defocus + procedure focusunlock; + + procedure seteditfocus; + procedure setcellclientclick(const awidget: twidget); + function editwidgetatpos(const apos: pointty; out cell: gridcoordty): twidget; + function widgetcell(const awidget: twidget): gridcoordty; + function cellwidget(const acell: gridcoordty): twidget; + function copyselection: boolean; override; + //false if no copy + function pasteselection: boolean; override; + //false if no paste + property datacols: twidgetcols read getdatacols write setdatacols; + property fixcols: twidgetfixcols read getfixcols write setfixcols; + property fixrows: twidgetfixrows read getfixrows write setfixrows; + end; + + twidgetgrid = class(tcustomwidgetgrid) + public + procedure initnewcomponent(const ascale: real); override; + published + property optionsgrid; + property optionsgrid1; + property optionsfold; + property rowstatelist; + property fixcols; + property fixrows; + property rowcount; + property rowcountmax; + property gridframecolor; +// property gridframewidth; + property rowcolors; + property rowfonts; + property zebra_color; + property zebra_start; + property zebra_height; + property zebra_step; + property datacols; + {$ifdef mse_with_ifi} + property ifilink; + {$endif} + + property datarowlinewidth; + property datarowlinecolorfix; + property datarowlinecolor; + property datarowheight; + property datarowheightmin; + property datarowheightmax; + + property statfile; + property statvarname; + property statpriority; + + property oncopyselection; + property onpasteselection; + property onbeforeupdatelayout; + property onlayoutchanged; + property oncolmoving; + property oncolmoved; + property onrowcountchanged; + property onrowdatachanged; + property onrowsdatachanged; + property onrowsmoving; + property onrowsmoved; + property onrowsinserting; + property onrowsinserted; + property onrowsdeleting; + property onrowsdeleted; + property onrowsmodified; + property onedited; + property onscrollrows; + property ongetmorerows; + property oncellevent; + property onselectionchanged; + property onsort; + property onsortchanged; + property drag; + end; + + tgridmsestringdatalist = class(tmsestringdatalist) + private + fowner: twidgetcol; + protected + function getdefault: pointer; override; + public + constructor create(owner: twidgetcol); reintroduce; + function empty(const index: integer): boolean; override; //true wenn leer + published + property facultative; + end; + + tgridansistringdatalist = class(tansistringdatalist) + private + fowner: twidgetcol; + protected + function getdefault: pointer; override; + public + constructor create(owner: twidgetcol); reintroduce; + published + property facultative; + end; + tgridbinarystringdatalist = class(tgridansistringdatalist) + public + constructor create(owner: twidgetcol); + end; + + + tgridpointerdatalist = class(tpointerdatalist) + private + fowner: twidgetcol; + protected + function getdefault: pointer; override; + public + constructor create(owner: twidgetcol); reintroduce; + published + property facultative; + end; + + tgridintegerdatalist = class(tintegerdatalist) + private + fowner: twidgetcol; + protected + function getdefault: pointer; override; + public + constructor create(owner: twidgetcol); reintroduce; + published + property facultative; + end; + + tgridint64datalist = class(tint64datalist) + private + fowner: twidgetcol; + protected + function getdefault: pointer; override; + public + constructor create(owner: twidgetcol); reintroduce; + published + property facultative; + end; + + tgridenumdatalist = class(tenumdatalist) + private + fowner: twidgetcol; + protected + function getdefaultenum: integer; + public + constructor create(owner: twidgetcol); reintroduce; + published + property facultative; + end; + + tgridenum64datalist = class(tenum64datalist) + private + fowner: twidgetcol; + protected + function getdefaultenum: int64; + public + constructor create(owner: twidgetcol); reintroduce; + published + property facultative; + end; + + tgridrealdatalist = class(trealdatalist) + private + fowner: twidgetcol; + protected + function getdefault: pointer; override; + public + constructor create(owner: twidgetcol); reintroduce; + function empty(const index: integer): boolean; override; //true wenn leer + procedure updateeditoptions(const aoptions: optionseditty); + published + property facultative; + end; + +type + creategriddatalistty = function(const aowner: twidgetcol): tdatalist; + +procedure registergriddatalistclass(const tag: ansistring; + const createfunc: creategriddatalistty); + +procedure gridwidgetfontheightdelta(const sender: twidget; + const gridintf: iwidgetgrid; const delta: integer); +procedure gridwidgetsized(const sender: twidget; const gridintf: iwidgetgrid); +procedure defaultinitgridwidget(const awidget: twidget; + const agridintf: iwidgetgrid); + +implementation +uses + sysutils,msebits,msedataedits,msewidgets,mseshapes,msekeyboard,typinfo, + msereal,mseapplication,msehash,msesumlist; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tdatalist1 = class(tdatalist); + twidget1 = class(twidget); + tcustomgrid1 = class(tcustomgrid); + tdataedit1 = class(tdataedit); + twriter1 = class(twriter); + treader1 = class(treader); + tdatacol1 = class(tdatacol); + + tcontainer1 = class(twidget) + protected + fgrid: tcustomwidgetgrid; + procedure doexit; override; + procedure doenter; override; + function getiassistiveclient(): iassistiveclient; override; + public + end; + + tfixcontainer = class(tcontainer1) + protected + procedure unregisterchildwidget(const child: twidget); override; + procedure widgetregionchanged(const sender: twidget); override; + procedure dochildfocused(const sender: twidget); override; + procedure doenter; override; + public + constructor create(aowner: tcustomwidgetgrid); reintroduce; + function focusback(const aactivate: boolean = true): boolean; override; + end; + + ttopcontainer = class(tfixcontainer) + end; + + tbottomcontainer = class(tfixcontainer) + end; + + twidgetdummy = class(twidget) + protected + fgrid: tcustomwidgetgrid; + public + constructor create(aowner: tcustomwidgetgrid); reintroduce; + end; + + tgridcontainer = class(tcontainer1) + private + flayoutupdating: integer; + protected + procedure unregisterchildwidget(const child: twidget); override; + procedure doenter; override; + procedure doexit; override; + procedure dofocus; override; + public + constructor create(aowner: tcustomwidgetgrid); reintroduce; + function focusback(const aactivate: boolean = true): boolean; override; + end; + + tscrollgridcontainer = class(tgridcontainer) + protected + procedure widgetregionchanged(const sender: twidget); override; + end; + + tnoscrollgridcontainer = class(tscrollgridcontainer) + public +// constructor create(aowner: tcustomwidgetgrid); + end; + +var + griddatalists: tpointeransistringhashdatalist; + +procedure defaultinitgridwidget(const awidget: twidget; + const agridintf: iwidgetgrid); + +begin + with twidget1(awidget) do begin + optionswidget1:= optionswidget1 - [ow1_autoscale]; + optionsskin:= optionsskin + defaultgridskinoptions; + if (fframe <> nil) then begin + if (ws_staticframe in fwidgetstate) then begin + fframe.initgridframe; + if agridintf <> nil then begin + fframe.framei:= agridintf.getgrid.datacols.innerframe; + end; + end + else begin + freeandnil(fframe); + end; + end; + synctofontheight; + end; +end; + +procedure gridwidgetfontheightdelta(const sender: twidget; const gridintf: iwidgetgrid; + const delta: integer); +var + cell1: gridcoordty; + widget1: twidget; +begin + with twidget1(sender) do begin + if (ow1_autoscale in foptionswidget1) and + not (csdesigning in componentstate) then begin + //in designmode widgetsize -> cellsize + if gridintf <> nil then begin + with gridintf.getcol.grid do begin + datarowheight:= datarowheight + delta; + end; + end + else begin + widget1:= parentofcontainer; + if widget1 is tcustomwidgetgrid then begin + with tcustomwidgetgrid(widget1) do begin + cell1:= widgetcell(sender); + if (cell1.row < 0) and (cell1.row >= -fixrows.count) then begin + fixrows[cell1.row].height:= fixrows[cell1.row].height + delta; + end; + end; + end; + end; + end; + end; +end; + +procedure gridwidgetsized(const sender: twidget; const gridintf: iwidgetgrid); +var + cell1: gridcoordty; + widget1: twidget; +begin + with twidget1(sender) do begin + if (foptionswidget1*[ow1_autowidth,ow1_autoheight] <> []) and + not (csdesigning in componentstate) then begin + //in designmode widgetsize -> cellsize + if gridintf <> nil then begin + with gridintf.getcol do begin + if not (gs1_cellsizesyncing in grid.fstate1) then begin + include(grid.fstate1,gs1_cellsizesyncing); + try + if ow1_autowidth in foptionswidget1 then begin + width:= bounds_cx; + end; + if ow1_autoheight in foptionswidget1 then begin + grid.datarowheight:= bounds_cy; + end; + finally + exclude(grid.fstate1,gs1_cellsizesyncing); + end; + end; + end; + end + else begin + widget1:= parentofcontainer; + if widget1 is tcustomwidgetgrid then begin + with tcustomwidgetgrid(widget1) do begin + if not (gs1_cellsizesyncing in fstate1) then begin + include(fstate1,gs1_cellsizesyncing); + try + cell1:= widgetcell(sender); + if ow1_autowidth in sender.optionswidget1 then begin + if (cell1.col >= 0) then begin + if (cell1.col < datacols.count) then begin + datacols[cell1.col].width:= sender.bounds_cx; + end; + end + else begin + if cell1.col >= -fixcols.count then begin + fixcols[cell1.col].width:= sender.bounds_cx; + end; + end; + end; + if ow1_autoheight in sender.optionswidget1 then begin + if (cell1.row < 0) and (cell1.row >= -fixrows.count) then begin + fixrows[cell1.row].height:= sender.bounds_cy; + end; + end; + finally + exclude(fstate1,gs1_cellsizesyncing); + end; + end; + end; + end; + end; + end; + end; +end; + +{ tgridmsestringdatalist } + +constructor tgridmsestringdatalist.create(owner: twidgetcol); +begin + fowner:= owner; + inherited create; + include(fstate,dls_nostreaming); +end; + +function tgridmsestringdatalist.getdefault: pointer; +begin + if fowner.fintf <> nil then begin + result:= fowner.fintf.getdefaultvalue; + end + else begin + result:= inherited getdefault; + end; +end; + +function tgridmsestringdatalist.empty(const index: integer): boolean; +var + po1: pmsestring; +begin + po1:= nil; + if fowner.fintf <> nil then begin + po1:= fowner.fintf.getdefaultvalue; + end; + if po1 <> nil then begin + result:= msestring(getitempo(index)^) = po1^; + end + else begin + result:= inherited empty(index); + end; +end; + +{ tgridansistringdatalist } + +constructor tgridansistringdatalist.create(owner: twidgetcol); +begin + fowner:= owner; + inherited create; + include(fstate,dls_nostreaming); +end; + +function tgridansistringdatalist.getdefault: pointer; +begin + if fowner.fintf <> nil then begin + result:= fowner.fintf.getdefaultvalue; + end + else begin + result:= inherited getdefault; + end; +end; + +{ tgridpointerdatalist } + +constructor tgridpointerdatalist.create(owner: twidgetcol); +begin + fowner:= owner; + inherited create; + include(fstate,dls_nostreaming); +end; + +function tgridpointerdatalist.getdefault: pointer; +begin + if fowner.fintf <> nil then begin + result:= fowner.fintf.getdefaultvalue; + end + else begin + result:= inherited getdefault; + end; +end; + +{ tgridintegerdatalist } + +constructor tgridintegerdatalist.create(owner: twidgetcol); +begin + fowner:= owner; + inherited create; + include(fstate,dls_nostreaming); +end; + +function tgridintegerdatalist.getdefault: pointer; +begin + if fowner.fintf <> nil then begin + result:= fowner.fintf.getdefaultvalue; + end + else begin + result:= inherited getdefault; + end; +end; + +{ tgridint64datalist } + +constructor tgridint64datalist.create(owner: twidgetcol); +begin + fowner:= owner; + inherited create; + include(fstate,dls_nostreaming); +end; + +function tgridint64datalist.getdefault: pointer; +begin + if fowner.fintf <> nil then begin + result:= fowner.fintf.getdefaultvalue; + end + else begin + result:= inherited getdefault; + end; +end; + +{ tgridenumdatalist } + +constructor tgridenumdatalist.create(owner: twidgetcol); +begin + fowner:= owner; + inherited create({$ifdef FPC}@{$endif}getdefaultenum); + include(fstate,dls_nostreaming); +end; + +function tgridenumdatalist.getdefaultenum: integer; +begin + if fowner.fintf <> nil then begin + result:= integer(fowner.fintf.getdefaultvalue^); + end + else begin + result:= 0; +// result:= integer(inherited getdefault^); + end; +end; + +{ tgridenum64datalist } + +constructor tgridenum64datalist.create(owner: twidgetcol); +begin + fowner:= owner; + inherited create({$ifdef FPC}@{$endif}getdefaultenum); + include(fstate,dls_nostreaming); +end; + +function tgridenum64datalist.getdefaultenum: int64; +begin + if fowner.fintf <> nil then begin + result:= int64(fowner.fintf.getdefaultvalue^); + end + else begin +// result:= int64(inherited getdefault^); + result:= 0; + end; +end; + +{ tgridrealdatalist } + +constructor tgridrealdatalist.create(owner: twidgetcol); +begin + fowner:= owner; + inherited create; + include(fstate,dls_nostreaming); +end; + +function tgridrealdatalist.getdefault: pointer; +begin + if fowner.fintf <> nil then begin + result:= fowner.fintf.getdefaultvalue; + end + else begin + result:= nil; + end; + if result = nil then begin + result:= inherited getdefault; + end; +end; + +function tgridrealdatalist.empty(const index: integer): boolean; +var + po1: prealty; +begin + po1:= nil; + if fowner.fintf <> nil then begin + po1:= fowner.fintf.getdefaultvalue; + end; + if po1 <> nil then begin + result:= realty(getitempo(index)^) = po1^; + end + else begin + result:= inherited empty(index); + end; +end; + +procedure tgridrealdatalist.updateeditoptions(const aoptions: optionseditty); +begin + acceptempty:= oe_null in aoptions; +end; + +{ twidgetfixrow } + + +{ twidgetfixrows } + +constructor twidgetfixrows.create(const owner: tcustomwidgetgrid); +begin + inherited create(owner); + fitemclasstype:= twidgetfixrow; +end; + +procedure twidgetfixrows.unregisterchildwidget(const child: twidget); +var + int1,int2: integer; +begin + if (fwidgetrectupdating = 0) and + not (csdestroying in fgrid.componentstate) then begin + for int1:= 0 to fgrid.datacols.count - 1 do begin + with tcustomwidgetgrid(fgrid).datacols[int1] do begin + for int2:= 0 to high(ffixrowwidgets) do begin + if ffixrowwidgets[int2] = child then begin + ffixrowwidgets[int2]:= nil; + break; + end; + end; + end; + end; + end; +end; + +function twidgetfixrows.getrows(const aindex: integer): twidgetfixrow; +begin + result:= twidgetfixrow(inherited rows[aindex]); +end; + +procedure twidgetfixrows.updatewidgetrect; +var + rect1: rectty; + int1,int2: integer; + coord1: gridcoordty; +begin + inc(fwidgetrectupdating); + try + for int1:= 0 to fgrid.datacols.count - 1 do begin + with tcustomwidgetgrid(fgrid).datacols[int1] do begin + for int2:= 0 to high(ffixrowwidgets) do begin + if ffixrowwidgets[int2] <> nil then begin + with ffixrowwidgets[int2] do begin + if co_nohscroll in foptions then begin + parentwidget:= fgrid; + end + else begin + if int2 >= fgrid.fixrows.count - fgrid.fixrows.oppositecount then begin + parentwidget:= tcustomwidgetgrid(fgrid).fcontainer3; + end + else begin + parentwidget:= tcustomwidgetgrid(fgrid).fcontainer1; + end; + end; + coord1:= makegridcoord(int1,-int2-1); + if fgrid.cellvisible(coord1) or (csdesigning in fgrid.componentstate) then begin + rect1:= fgrid.cellrect(coord1,cil_noline); + rect1.pos:= translatewidgetpoint(addpoint(rect1.pos,fgrid.paintpos), + fgrid,parentwidget); + widgetrect:= rect1; + end + else begin + bounds_y:= -bounds_cy; //shift out of view + end; + end; + end; + end; + end; + end; + for int1:= -fgrid.fixcols.count to -1 do begin + with tcustomwidgetgrid(fgrid).fixcols[int1] do begin + for int2:= 0 to high(ffixrowwidgets) do begin + if ffixrowwidgets[int2] <> nil then begin + with ffixrowwidgets[int2] do begin + parentwidget:= fgrid; + coord1:= makegridcoord(int1,-int2-1); + if fgrid.cellvisible(coord1) then begin + rect1:= fgrid.cellrect(coord1,cil_noline); + rect1.pos:= translatewidgetpoint(addpoint(rect1.pos,fgrid.paintpos), + fgrid,parentwidget); + widgetrect:= rect1; + end + else begin + bounds_y:= -bounds_cy; //shift out of view + end; + end; + end; + end; + end; + end; + with tcustomwidgetgrid(fgrid) do begin + if fcontainer1 <> nil then begin //else call from tcustomwidgetgrid.create + if fcontainer1.widgetcount = 0 then begin + exclude(twidget1(fcontainer1).foptionswidget,ow_arrowfocus); + end + else begin + include(twidget1(fcontainer1).foptionswidget,ow_arrowfocus); + end; + if fcontainer3.widgetcount = 0 then begin + exclude(twidget1(fcontainer3).foptionswidget,ow_arrowfocus); + end + else begin + include(twidget1(fcontainer3).foptionswidget,ow_arrowfocus); + end; + end; + end; + finally + dec(fwidgetrectupdating); + end; +end; + +procedure twidgetfixrows.countchanged; +var + int1,int2: integer; + ar1: widgetarty; +begin + if not (csdestroying in fgrid.componentstate) then begin + for int1:= 0 to fgrid.datacols.count - 1 do begin + with tcustomwidgetgrid(fgrid).datacols[int1] do begin + ar1:= ffixrowwidgets; + setlength(ffixrowwidgets,self.count); + for int2:= high(ar1) downto self.count do begin + if ar1[int2] <> nil then begin + freedesigncomponent(ar1[int2]); //inhibit deleting of inherited widget + end; + end; + end; + end; + for int1:= 0 to fgrid.fixcols.count - 1 do begin + with twidgetfixcol(fgrid.fixcols.items[int1]) do begin + ar1:= ffixrowwidgets; + setlength(ffixrowwidgets,self.count); + for int2:= high(ar1) downto self.count do begin + if ar1[int2] <> nil then begin + freedesigncomponent(ar1[int2]); //inhibit deleting of inherited widget + end; + end; + end; + end; + end; + inherited; +end; + +procedure twidgetfixrows.move(const curindex,newindex: integer); +var + int1: integer; +begin + inherited; + for int1:= 0 to fgrid.datacols.count - 1 do begin + with tcustomwidgetgrid(fgrid).datacols[int1] do begin + moveitem(pointerarty(ffixrowwidgets),curindex,newindex); + end; + end; + for int1:= 0 to fgrid.fixcols.count - 1 do begin + with twidgetfixcol(fgrid.fixcols.items[int1]) do begin + moveitem(pointerarty(ffixrowwidgets),curindex,newindex); + end; + end; +end; + +{ twidgetcol } + +constructor twidgetcol.create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); +begin + setlength(ffixrowwidgets,agrid.fixrows.count); + inherited; +end; + +destructor twidgetcol.destroy; +var + aintf: igridwidget; + int1: integer; +begin + if not (csdestroying in fcellinfo.grid.componentstate) then begin + if fintf <> nil then begin + aintf:= fintf; + fintf:= nil; + aintf.setgridintf(nil); + if not (csreading in fcellinfo.grid.componentstate) then begin + //refreshancestor otherwise + freedesigncomponent(aintf.getwidget); //inhibit deleting of inherited widget + end; + end; + if not (csreading in fcellinfo.grid.componentstate) then begin + //refreshancestor otherwise + for int1:= 0 to high(ffixrowwidgets) do begin + if ffixrowwidgets[int1] <> nil then begin + freedesigncomponent(ffixrowwidgets[int1]); + //inhibit deleting of inherited widget + end; + end; + end; + end; +{$ifndef FPC} + pointer(fintf):= nil; //workaround for com decref +{$endif} + inherited; +end; + +{$ifdef FPC}{$checkpointer off}{$endif} +procedure twidgetcol.updatewidgetrect(const updatedata: boolean = false); +var + rect1: rectty; + widget1: twidget; +begin + with tcustomwidgetgrid(fcellinfo.grid) do begin + if (fintf <> nil) then begin //bug in fixes_2_0 2850 with checkpointer + widget1:= fintf.getwidget; + if co_nohscroll in foptions then begin + widget1.parentwidget:= fcontainer0; + end + else begin + widget1.parentwidget:= fcontainer2; + end; + if (csdesigning in componentstate) or (ffocusedcell.row < 0) then begin + rect1:= cellrect(makegridcoord(colindex,invalidaxis),cil_noline); + rect1.cy:= datarowheight; + if not (csdesigning in componentstate) then begin + if row >= 0 then begin + rect1.cx:= rect1.cx + fdatacols.mergedwidth(index, + fdatacols.rowstate.merged[row]); + end; + end; + if co_nohscroll in self.foptions then begin + rect1.y:= 0; + rect1.x:= rect1.x - fdatarecty.x; + widget1.widgetrect:= rect1; + end + else begin + rect1.y:= 0; + dec(rect1.x,fdatarect.x); + widget1.widgetrect:= rect1; + end; + end + else begin + rect1:= cellrect(makegridcoord(colindex,ffocusedcell.row),cil_noline); + if co_nohscroll in self.foptions then begin + removerect1(rect1,fdatarecty.pos); + end + else begin + removerect1(rect1,fdatarect.pos); + end; + widget1.widgetrect:= rect1; + end; + if updatedata then begin + fintf.gridtovalue(-1); + end; + end; + end; +end; +{$ifdef FPC}{$checkpointer default}{$endif} + +procedure twidgetcol.checkcanclose(var accepted: boolean); +begin + if (fintf <> nil) and fintf.getwidget.focused and + not tcustomgrid1(fcellinfo.grid).nocheckvalue and accepted then begin + accepted:= fintf.getwidget.canclose(nil); + end; +end; + +procedure twidgetcol.docellfocuschanged(enter: boolean; + const cellbefore: gridcoordty; var newcell: gridcoordty; + const selectaction: focuscellactionty); +var + widget1: twidget; + activewidgetbefore: twidget; + intf: igridwidget; + focuscount: integer; + bo1: boolean; + +begin + with twidgetgrid(fcellinfo.grid) do begin + if ffocuslock > 0 then begin + if not enter then begin + factivewidget:= nil; + end + else begin + end; + inherited; + exit; + end; + + focuscount:= ffocuscount; + activewidgetbefore:= factivewidget; + if not enter and + ((selectaction <> fca_exitgrid) or (newcell.row < 0)) then begin + factivewidget:= nil; + bo1:= true; + if not (gs1_rowdeleting in twidgetgrid(fcellinfo.grid).fstate1) then begin + checkcanclose(bo1); + end; + if bo1 then begin + if (activewidgetbefore <> nil) and + activewidgetbefore.clicked then begin + with fcellinfo.grid do begin + capturemouse; + fwidgetstate:= fwidgetstate + [ws_clientmousecaptured]; + include(fstate,gs_childmousecaptured); + end; + end; + if (activewidgetbefore <> nil) then begin + if activewidgetbefore.focused then begin + fwidgetdummy.setfocus(active); + end; + activewidgetbefore.visible:= false; + end; + inherited; + end + else begin + focuscell(cellbefore,fca_none); + end; + end + else begin + if (fintf <> nil) then begin + if fcellinfo.grid.canwindow then begin + updatewidgetrect; + end; + inherited; + bo1:= (tcustomwidgetgrid(fcellinfo.grid).fmouseinfopo <> nil) and + tcustomwidgetgrid(fcellinfo.grid).wantmousefocus(fmouseinfopo^); + if fcellinfo.grid.entered or + not (gs_cellexiting in tcustomwidgetgrid(fcellinfo.grid).fstate) and + bo1 then begin + widget1:= fintf.getwidget; + with widget1 do begin + if not visible then begin +// twidgetgrid(fcellinfo.grid).fmouseactivewidget:= nil; + visible:= true; + end; + if (fwindow <> nil) and + canfocus and (tcustomwidgetgrid(fcellinfo.grid).entered or bo1) and + ( + not fcellinfo.grid.checkdescendent(fwindow.focusedwidget) or + (fwindow.focusedwidget = fcellinfo.grid) or + fcontainer2.checkdescendent(fwindow.focusedwidget) or + fcontainer0.checkdescendent(fwindow.focusedwidget)) then begin + bo1:= gs1_focuscellonenterlock in twidgetgrid(fcellinfo.grid).fstate1; + include(twidgetgrid(fcellinfo.grid).fstate1,gs1_focuscellonenterlock); + try + setfocus(fcellinfo.grid.active); + finally + if not bo1 then begin + exclude(twidgetgrid(fcellinfo.grid).fstate1,gs1_focuscellonenterlock); + end; + end; + end; + end; + if ffocuscount = focuscount then begin + factivewidget:= widget1; + end; + end; + end + else begin + if ffocuscount = focuscount then begin + factivewidget:= nil; + end; + end; + if (activewidgetbefore = nil) and (cellbefore.col >= 0) then begin + intf:= twidgetcol(fdatacols[cellbefore.col]).fintf; + if intf <> nil then begin + activewidgetbefore:= intf.getwidget; + end; + end; + if (activewidgetbefore <> nil) and + (activewidgetbefore <> factivewidget) then begin + activewidgetbefore.visible:= false; + end; + end; + end; +end; + +procedure twidgetcol.readfixwidgetnames(reader: treader); +begin + readstringar(reader,ffixrowwidgetnames); +end; + +procedure twidgetcol.writefixwidgetnames(writer: twriter); +begin + writewidgetnames(writer,ffixrowwidgets); +end; + +procedure twidgetcol.readwidgetname(reader: treader); +begin + fwidgetname:= reader.readstring; +end; + +procedure twidgetcol.writewidgetname(writer: twriter); +begin + writer.writestring(fintf.getwidget.name); +end; + +procedure twidgetcol.readdataclass(reader: treader); +var + createproc: creategriddatalistty; + str1: string; +begin + str1:= reader.readident; + if (fdata = nil) or (fdata.classname <> str1) then begin + if fdata <> nil then begin + if fintf <> nil then begin + fintf.datalistdestroyed; + end; + freeandnil(fdata); + end; + if griddatalists.find(str1,pointer({$ifndef FPC}@{$endif}createproc)) then begin + fdata:= createproc(self); + include(fstate,gps_datalistvalid); + end + else begin + raise exception.create('Unknown grid datalist type '+str1+'.'); + end; + end; +end; + +procedure twidgetcol.writedataclass(writer: twriter); +begin + writer.writeident(fdata.classname); +end; + +procedure twidgetcol.readdatatype(reader: treader); +var + str1: string; + int1: integer; + licla: datalistclassty; +begin + str1:= reader.readident; + int1:= getenumvalue(typeinfo(listdatatypety),str1); + if int1 >= 0 then begin + freeandnil(fdata); + licla:= getdatalistclass(listdatatypety(int1)); + if licla <> nil then begin + fdata:= licla.create; + end; + end; +end; + +procedure twidgetcol.writedatatype(writer: twriter); +begin + writer.writeident(getenumname(typeinfo(listdatatypety),integer(fdata.datatype))); +end; + +procedure twidgetcol.readdata(reader: treader); +begin + reader.readlistbegin; + if reader.nextvalue <> valist then begin + readdatatype(reader); + end; + if fdata <> nil then begin + tdatalist1(fdata).readdata(reader); + end + else begin + reader.driver.skipvalue; + end; + reader.readlistend; +end; + +procedure twidgetcol.writedata(writer: twriter); +begin + writer.writelistbegin; +// writedatatype(writer); + tdatalist1(fdata).writedata(writer); + writer.writelistend; +end; + +procedure twidgetcol.readdataprops(reader: treader); +begin + reader.readlistbegin; + while not reader.endoflist do begin + treader1(reader).readproperty(fdata); + end; + reader.readlistend; +end; + +procedure twidgetcol.writedataprops(writer: twriter); +begin + writer.writelistbegin; + twriter1(writer).writeproperties(fdata); + writer.writelistend; +end; + +procedure twidgetcol.defineproperties(filer: tfiler); +var + bo1,bo2: boolean; + col1: twidgetcol; + str1,str2: string; + ancestorbefore: tpersistent; +begin + inherited; + filer.defineproperty('widgetname',{$ifdef FPC}@{$endif}readwidgetname, + {$ifdef FPC}@{$endif}writewidgetname, + (fintf <> nil) and + ((filer.ancestor = nil) or + (twidgetcol(filer.ancestor).fwidgetname <> fwidgetname))); + filer.defineproperty('fixwidgetnames',{$ifdef FPC}@{$endif}readfixwidgetnames, + {$ifdef FPC}@{$endif}writefixwidgetnames, + (filer.ancestor = nil) and needswidgetnamewriting(ffixrowwidgets) or + (filer.ancestor <> nil) and + needswidgetnamewriting(ffixrowwidgets, + twidgetcol(filer.ancestor).ffixrowwidgets)); + bo1:= false; + if (fdata <> nil) and ([dls_nogridstreaming,dls_remote] * + tdatalist1(fdata).fstate = []) then begin + col1:= twidgetcol(filer.ancestor); + if col1 <> nil then begin + bo1:= (col1.fdata = nil) or (fdata.datatype <> col1.fdata.datatype); + filer.ancestor:= col1.fdata; + end; + bo1:= bo1 or fdata.checkwritedata(filer); + filer.ancestor:= col1; + end; + bo2:= (fdata <> nil) and not (dls_remote in fdata.state) and + (not(dls_nogridstreaming in fdata.state) or + (dls_propertystreaming in fdata.state)); + if (filer is twriter) and (twriter(filer).ancestor <> nil) then begin + with twidgetcol(twriter(filer).ancestor) do begin + if (fdata <> nil) and (fdata is self.fdata.classtype) then begin + bo2:= false; + end; + end; + end; + filer.defineproperty('dataclass',{$ifdef FPC}@{$endif}readdataclass, + {$ifdef FPC}@{$endif}writedataclass,bo2); + filer.defineproperty('data',{$ifdef FPC}@{$endif}readdata, + {$ifdef FPC}@{$endif}writedata,bo1); + if (fdata <> nil) and (dls_propertystreaming in + tdatalist1(fdata).fstate) and (filer is twriter) then begin + with twriter1(filer) do begin + str1:= getfproppath(twriter(filer)); + if str1 = '' then begin + str2:= 'datalist.'; + end + else begin + str2:= str1+'.datalist.'; + end; + ancestorbefore:= filer.ancestor; + if ancestorbefore <> nil then begin + filer.ancestor:= twidgetcol(ancestor).fdata; + end; + setfproppath(twriter(filer),str2); + writeproperties(fdata); + setfproppath(twriter(filer),str1); + filer.ancestor:= ancestorbefore; + end; + end; +end; + +procedure twidgetcol.setfixrowwidget(const awidget: twidget; + const rowindex: integer); +begin + tcustomwidgetgrid(fcellinfo.grid).removefixwidget(awidget); + ffixrowwidgets[-rowindex-1]:= awidget; + fcellinfo.grid.layoutchanged; +end; + +procedure twidgetcol.setwidget(const awidget: twidget); +var + po1: pointer; + dl1: tdatalist; +{$ifdef mse_with_ifi} + ifilink1: tifilinkcomp; +{$endif} +begin + dl1:= fdata; + fdata:= nil; +{$ifdef mse_with_ifi} + ifilink1:= nil; +{$endif} + try + if fintf <> nil then begin + if fdata <> nil then begin + fdata.linksource(nil,0); + end; + fintf.setgridintf(nil); + {$ifdef mse_with_ifi} + updateifigriddata(nil); + {$endif} + end; + if awidget <> nil then begin + fwidgetname:= awidget.name; + awidget.visible:= false; + awidget.getcorbainterface(typeinfo(igridwidget),fintf); + if not (gps_datalistvalid in fstate) then begin + fdata:= fintf.createdatalist(self); + end + else begin + if (dl1 <> nil) and not (dl1 is fintf.getdatalistclass) then begin + dl1.destroy(); + dl1:= fintf.createdatalist(self); //fix wrong datalist class + end; + fdata:= dl1; + end; + fintf.setgridintf(iwidgetgrid(self)); + options:= foptions; //call updatecoloptions; + {$ifdef mse_with_ifi} + ifilink1:= fintf.getifilink; + if (ifilink1 <> nil) and not(csloading in ifilink1.componentstate) and + (ifilink1 is tifivaluelinkcomp) and (vco_datalist in + tifivaluelinkcomp(ifilink1).controller.optionsvalue) then begin + if fdata = dl1 then begin + dl1:= nil; //no double free + end; + updateifigriddata(tifivaluelinkcomp(ifilink1).controller.datalist); + end + else begin + {$endif} + po1:= fintf.getdefaultvalue; + if fdata <> nil then begin + if dl1 <> nil then begin //from streaming + if dl1 <> fdata then begin + fdata.assign(dl1); + end + else begin + dl1:= nil; + end; + end + else begin + if po1 <> nil then begin + tdatalist1(fdata).internalfill(fcellinfo.grid.rowcount,po1^); + end + else begin + fdata.count:= fcellinfo.grid.rowcount; + end; + end; + fdata.maxcount:= fcellinfo.grid.rowcountmax; + fdata.onitemchange:= {$ifdef FPC}@{$endif}itemchanged; + end; + {$ifdef mse_with_ifi} + end; + {$endif} + if gs_isdb in tcustomgrid1(fcellinfo.grid).fstate then begin + datasourcechanged; + end; + sourcenamechanged(-1); + tcustomgrid1(fcellinfo.grid).layoutchanged; + end + else begin + fwidgetname:= ''; + fintf:= nil; + if (dl1 <> nil) and (dls_remote in dl1.state) then begin + dl1:= nil; //no free + end; + end; + finally + dl1.free; + end; +end; + +procedure twidgetcol.getdata(var arow: integer; var dest); +var + datatype: listdatatypety; + info: cellinfoty; + po1: pointer; +begin + if arow = -1 then begin + arow:= twidgetgrid(fcellinfo.grid).ffocusedcell.row; + end; + if fdata <> nil then begin + if (arow >= 0) and (arow < fdata.count) then begin + tdatalist1(fdata).getgriddata(arow,dest); + end + else begin + tdatalist1(fdata).getgriddefaultdata(dest); + end; + end + else begin + if fintf <> nil then begin + datatype:= fintf.getdatalistclass.datatype; + if arow >= 0 then begin + info.cell.row:= arow; + po1:= fintf.getrowdatapo(info.cell.row); + end + else begin + po1:= nil; + end; + case datatype of + dl_integer: begin + if po1 = nil then begin + integer(dest):= 0; + end + else begin + integer(dest):= pinteger(po1)^; + end; + end; + dl_real: begin + if po1 = nil then begin + real(dest):= emptyreal; + end + else begin + real(dest):= preal(po1)^; + end; + end; + dl_datetime: begin + if po1 = nil then begin + tdatetime(dest):= emptydatetime; + end + else begin + tdatetime(dest):= pdatetime(po1)^; + end; + end; + dl_msestring: begin + if po1 = nil then begin + msestring(dest):= fintf.getnulltext; + end + else begin + msestring(dest):= pmsestring(po1)^; + end; + end; + dl_ansistring: begin + if po1 = nil then begin + ansistring(dest):= ''; + end + else begin + ansistring(dest):= pansistring(po1)^; + end; + end; + end; + end; + end; +end; + +procedure twidgetcol.setdata(var arow: integer; const source; + const noinvalidate: boolean = false); +begin + if fdata <> nil then begin + if arow = -1 then begin + arow:= twidgetgrid(fcellinfo.grid).ffocusedcell.row; + end; + if arow >= 0 then begin + if noinvalidate then begin + fdata.beginupdate; + end; + tdatalist1(fdata).setgriddata(arow,source); + if (arow = twidgetgrid(fcellinfo.grid).ffocusedcell.row) and + (fintf <> nil) then begin + fintf.gridtovalue(arow); + end; + if noinvalidate then begin + fdata.decupdate; + if (not fdata.updating) and assigned(fonchange) then begin + fonchange(self,arow); + end; + end; + end; + end + else begin + if assigned(fonchange) then begin + fonchange(self,arow); + end; + end; + datachange(arow); +end; + +function twidgetcol.empty(arow: integer): boolean; +begin + result:= true; + if fdata <> nil then begin + if arow = -1 then begin + arow:= twidgetgrid(fcellinfo.grid).ffocusedcell.row; + end; + if arow >= 0 then begin + result:= tdatalist1(fdata).empty(arow); + end; + end; +end; + +function twidgetcol.cangridcopy: boolean; +begin + result:= tcustomwidgetgrid(fcellinfo.grid).datacols.hasselection; +end; + +procedure twidgetcol.updateeditoptions(var aoptions: optionseditty; + const aoptions1: optionsedit1ty); +begin + if not (gps_readonlyupdating in fstate) then begin + updatebit(longword(foptions),ord(co_readonly),oe_readonly in aoptions); + updatebit(longword(foptions),ord(co_savevalue),oe1_savevalue in aoptions1); + end; +end; + +function twidgetcol.showcaretrect(const arect: rectty; + const aframe: tcustomframe): pointty; +begin + result:= grid.showcaretrect(makerect(translateclientpoint(arect.pos, + fintf.getwidget,fcellinfo.grid),arect.size),aframe); +end; + +procedure twidgetcol.widgetpainted(const canvas: tcanvas); +begin + if (co_drawfocus in self.foptions) or fintf.needscellfocuspaint() then begin + with fintf.getwidget() do begin + if active then begin + drawfocusrect(canvas,inflaterect(paintrect,self.ffocusrectdist)); + end; + end; + end; +end; + +function twidgetcol.getdatapo(const arow: integer): pointer; +begin + if (fdata = nil) then begin + result:= nil; + if fintf <> nil then begin + result:= fintf.getrowdatapo(arow); + end; + end + else begin + result:= inherited getdatapo(arow); + end; +end; + +procedure twidgetcol.drawcell(const canvas: tcanvas); +var + face1: tcustomface; +begin + with cellinfoty(canvas.drawinfopo^) do begin + inherited; + if fintf <> nil then begin + if calcautocellsize then begin + fintf.updateautocellsize(canvas); + end + else begin + if (fface = nil) then begin + face1:= fintf.getwidget.face; + if face1 <> nil then begin + face1.paint(canvas,cellinfoty(canvas.drawinfopo^).rect); + end; + end; + fintf.drawcell(canvas); + end; + end; + if assigned(fondrawcell) then begin + fondrawcell(self,canvas,cellinfoty(canvas.drawinfopo^)); + end; + end; +end; + +function twidgetcol.getrow: integer; +begin + result:= twidgetgrid(fcellinfo.grid).factiverow; +end; + +procedure twidgetcol.setrow(arow: integer); +begin + with twidgetgrid(fcellinfo.grid) do begin + focuscell(makegridcoord(colindex,arow)); + end; +end; + +function twidgetcol.getcol: twidgetcol; +begin + result:= self; +end; +{ +procedure twidgetcol.cellchanged(const row: integer); +var + int1: integer; +begin + inherited; + if (fintf <> nil) and (fdata <> nil) then begin + int1:= fgrid.row; + if (int1 >= 0) and ((row = int1) or (row < 0)) and (int1 < fdata.count) and + not (gs_rowremoving in tcustomgrid1(fgrid).fstate) then begin + fintf.gridtovalue(int1); + end; + end; +end; +} +{ +procedure twidgetcol.changed; +begin + inherited; + if (fintf <> nil) and (fgrid.row >= 0) then begin + fintf.gridtovalue(fgrid.row); + end; +end; +} +function twidgetcol.getinnerframe: framety; +begin + if fintf <> nil then begin + result:= fintf.getcellframe; + end + else begin + result:= inherited getinnerframe; + end; +end; + +function twidgetcol.geteditwidget: twidget; +begin + if fintf = nil then begin + result:= nil; + end + else begin + result:= fintf.getwidget; + end; +end; + +procedure twidgetcol.seteditwidget(const value: twidget); +begin + setwidget(value); + if value <> nil then begin + value.parentwidget:= twidgetgrid(fcellinfo.grid).fcontainer2; + end; +end; + +procedure twidgetcol.drawfocusedcell(const acanvas: tcanvas); +var + size1: sizety; +begin + with tcustomwidgetgrid(fcellinfo.grid) do begin + if (factivewidget = nil) or not factivewidget.visible then begin + inherited; + end + else begin + with fcellinfo do begin + if calcautocellsize and (fintf <> nil) then begin + size1:= rect.size; + fintf.getautocellsize(acanvas,size1); + if size1.cx > autocellsize.cx then begin + autocellsize.cx:= size1.cx; + end; + if size1.cy > autocellsize.cy then begin + autocellsize.cy:= size1.cy; + end; + end; + end; + end + end; +end; + +procedure twidgetcol.drawfocus(const acanvas: tcanvas); +begin + with tcustomwidgetgrid(fcellinfo.grid) do begin + if (factivewidget = nil) or not factivewidget.visible then begin + inherited; + end; + end; + //else no paint, done in widgetpainted +end; + +function twidgetcol.sortcompare(const index1,index2: integer): integer; +begin + result:= 0; + if (fintf <> nil) then begin + if fdata <> nil then begin + with tdatalist1(fdata) do begin + result:= fintf.sortfunc((fdatapo+index1*fsize)^,(fdatapo+index2*fsize)^); + end; + end; + end + else begin + result:= inherited sortcompare(index1,index2); + end; +end; + +procedure twidgetcol.itemchanged(const sender: tdatalist; const aindex: integer); +begin + inherited; + if {(tcustomwidgetgrid(fgrid).fupdating = 0) and} (fintf <> nil) and + not (gs_rowremoving in tcustomgrid1(fcellinfo.grid).fstate) and + not (gps_changelock in fstate)then begin + fintf.gridvaluechanged(aindex); + if ((aindex < 0) or (aindex = grid.row)) and (grid.row >= 0) then begin + fintf.gridtovalue(aindex); + end; + end; +end; + +function twidgetcol.actualfont: tfont; +begin + result:= nil; + if fintf <> nil then begin + with twidget1(fintf.getwidget) do begin + result:= ffont; + end; + end; + if result = nil then begin + result:= inherited actualfont; + end; +end; + +procedure twidgetcol.setoptions(const avalue: coloptionsty); +//var +// aoptions: coloptionsty; +begin +// aoptions:= avalue; +// inherited setoptions(aoptions); + inherited; + if fintf <> nil then begin + fintf.updatecoloptions(foptions); + end; +end; + +procedure twidgetcol.setoptions1(const avalue: coloptions1ty); +begin + inherited; + if fintf <> nil then begin + fintf.updatecoloptions1(foptions1); + end; +end; + +function twidgetcol.getcursor(const arow: integer; + const actcellzone: cellzonety; + const amousepos: pointty): cursorshapety; +begin + result:= inherited getcursor(arow,actcellzone,amousepos); + if (result = cr_default) and (fintf <> nil){ and + not (co_readonly in foptions)} then begin + result:= fintf.getcellcursor(arow,actcellzone,amousepos); + end; +end; + +procedure twidgetcol.datasourcechanged; +begin + if fintf <> nil then begin + fintf.griddatasourcechanged; + end; +end; + +function twidgetcol.nullcheckneeded(const newfocus: twidget): boolean; +begin + with twidgetgrid(fcellinfo.grid) do begin + result:= not (gs_isdb in fstate) and (fnonullcheck = 0) and ( + not (fcontainer1.checkdescendent(newfocus) or + fcontainer3.checkdescendent(newfocus))) and + (row >= 0) and not (gs_rowremoving in fstate) and + ((gs1_forcenullcheck in fstate1) or + not ((row = rowhigh) and isautoappend or + isinsertempty)); + end; +end; + +function twidgetcol.nonullcheck: boolean; +begin + result:= tcustomgrid1(fcellinfo.grid).fnonullcheck > 0; +end; + +function twidgetcol.nocheckvalue: boolean; +begin + with tcustomgrid1(fcellinfo.grid) do begin + result:= (fnocheckvalue > 0) or (gs_rowremoving in fstate); + end; +end; + +{$ifdef mse_with_ifi} +procedure twidgetcol.updateifigriddata(const alist: tdatalist); +begin + if (fdata <> nil) and not (dls_remote in fdata.state) {and + (alist <> nil)} then begin + freeandnil(fdata); //free internal datalist + end; + if not (csdesigning in fcellinfo.grid.componentstate) then begin + setremotedatalist(idatalistclient(self),alist,fdata); + end; +end; +{$endif} + +function twidgetcol.getgrid: tcustomwidgetgrid; +begin + result:= tcustomwidgetgrid(fcellinfo.grid); +end; + +procedure twidgetcol.edited(); +begin + tcustomwidgetgrid(fcellinfo.grid).doedited(); +end; + +function twidgetcol.getbrushorigin: pointty; +begin + result:= tcustomwidgetgrid(fcellinfo.grid).fbrushorigin; +end; + +procedure twidgetcol.beforedragevent(var ainfo: draginfoty; const arow: integer; + var processed: boolean); +begin + if fintf <> nil then begin + fintf.beforecelldragevent(ainfo,arow,processed); + end; +end; + +procedure twidgetcol.afterdragevent(var ainfo: draginfoty; const arow: integer; + var processed: boolean); +begin + if fintf <> nil then begin + fintf.aftercelldragevent(ainfo,arow,processed); + end; +end; + +procedure twidgetcol.updatecellzone(const row: integer; const pos: pointty; var result: cellzonety); +begin + inherited; + if fintf <> nil then begin + fintf.updatecellzone(row,pos,result); + end; +end; + +procedure twidgetcol.sourcenamechanged(const atag: integer); +var + datalist1: tdatalist; + str1: string; + int1: integer; +begin + if fdata <> nil then begin + if atag >= 0 then begin + str1:= fdata.getsourcename(atag); + datalist1:= nil; + if str1 <> '' then begin + datalist1:= fcellinfo.grid.datacols.datalistbyname(str1); + end; + fdata.linksource(datalist1,atag); + end + else begin + for int1:= 0 to fdata.getsourcecount-1 do begin + str1:= fdata.getsourcename(int1); //link all source lists + datalist1:= nil; + if str1 <> '' then begin + datalist1:= fcellinfo.grid.datacols.datalistbyname(str1); + end; + fdata.linksource(datalist1,int1); + end; + end; + end; +end; + +function twidgetcol.getfixrowwidgets(aindex: integer): twidget; +var + i1: int32; +begin + i1:= -1-aindex; + checkarrayindex(ffixrowwidgets,i1); + result:= ffixrowwidgets[i1]; +end; + +procedure twidgetcol.setfixrowwidgets(aindex: integer; const avalue: twidget); +begin + checkarrayindex(ffixrowwidgets,-1-aindex); + setfixrowwidget(avalue,aindex); +end; + +{ twidgetcols } + +constructor twidgetcols.create(const aowner: tcustomwidgetgrid); +begin + inherited create(aowner,twidgetcol); +end; + +class function twidgetcols.getitemclasstype: persistentclassty; +begin + result:= twidgetcol; +end; + +procedure twidgetcols.datasourcechanged; +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + cols[int1].datasourcechanged; + end; +end; + +function twidgetcols.getcols(const index: integer): twidgetcol; +begin + result:= twidgetcol(items[index]); +end; + +procedure twidgetcols.unregisterchildwidget(const child: twidget); +var + int1: integer; +begin + with twidgetgrid(fgrid) do begin + if factivewidget = child then begin + factivewidget:= nil; + end; + end; + int1:= 0; + if not (gs_layoutupdating in tcustomwidgetgrid(fgrid).fstate) then begin + while int1 < count do begin + with cols[int1] do begin + if (fintf <> nil) and (fintf.getwidget = child) then begin + setwidget(nil); + delete(int1); + end + else begin + inc(int1); + end; + end; + end; + end; +end; + +procedure twidgetcols.updatedatastate(var accepted: boolean); +var + int1: integer; +begin + if not (csdestroying in fgrid.componentstate) and + not (gs1_rowdeleting in twidgetgrid(fgrid).fstate1)then begin + for int1:= 0 to count - 1 do begin + if not accepted then begin + break; + end; + cols[int1].checkcanclose(accepted); + end; + end; + inherited; +end; + +procedure twidgetcols.updatecolorder; +var + ar1,ar2: widgetcolarty; + int1,int2: integer; +begin + if (count > 0) and (fcolorder <> nil) then begin //inherited + if length(fcolorder) > count then begin + fcolcount:= length(fcolorder); + inherited setcount1(fcolcount,true); + end; + ar1:= widgetcolarty(copy(fitems)); + setlength(ar2,fcolcount); //new count + setlength(fcolorder,fcolcount); + for int1:= 0 to high(fcolorder) do begin + if fcolorder[int1] <> '' then begin + for int2:= 0 to high(ar1) do begin + if (ar1[int2] <> nil) and + (ar1[int2].fwidgetname = fcolorder[int1]) then begin + ar2[int1]:= ar1[int2]; + ar1[int2]:= nil; + break; + end; + end; + end; + end; + int2:= 0; + for int1:= 0 to high(ar1) do begin + if (ar1[int1] <> nil) and + (ar1[int1].fwidgetname <> '') then begin + //new inherited widget + additem(pointerarty(ar2),ar1[int1]); + ar1[int1]:= nil; + end; + end; + int1:= length(ar2)-fcolcount; + if int1 > 0 then begin + fcolcount:= length(ar2); + int2:= count; + inherited setcount1(int2+int1,true); + setlength(ar1,length(fitems)); + for int1:= int2 to high(fitems) do begin + ar1[int1]:= twidgetcol(fitems[int1]); //new inherited + end; + end; + int2:= 0; + for int1:= 0 to high(ar2) do begin + if ar2[int1] = nil then begin + while ar1[int2] = nil do begin + inc(int2); + end; + ar2[int1]:= ar1[int2]; //new + ar1[int2]:= nil; + end; + end; + for int1:= 0 to high(ar1) do begin + ar1[int1].free; //not used + end; + fitems:= persistentarty(ar2); + fcolorder:= nil; + clearorder; //new order is default + end + else begin + inherited setcount1(fcolcount,true); + end; +end; + +procedure twidgetcols.setcount1(acount: integer; doinit: boolean); +begin + fcolcount:= acount; + if (acount = 0) or + not ((fgrid.componentstate*[csdesigning,csreading] = [csdesigning,csreading]) + and (acount < count)) then begin + inherited; //else delay to updatecolorder, possibly refreshing inherited + end; +end; + +procedure twidgetcols.readorder(reader: treader); +begin + readstringar(reader,fcolorder); + updatecolorder; +end; + +procedure twidgetcols.writeorder(writer: twriter); +var + ar1: stringarty; + int1: integer; +begin + setlength(ar1,count); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= twidgetcol(fitems[int1]).fwidgetname; + end; + writestringar(writer,ar1); +end; + +procedure twidgetcols.defineproperties(filer: tfiler); +var + bo1: boolean; + int1: integer; +begin + bo1:= (filer is twriter) and (twriter(filer).ancestor <> nil); + if bo1 then begin + with twidgetcols(twriter(filer).ancestor) do begin + if count = self.count then begin + bo1:= false; + for int1:= 0 to count-1 do begin + if twidgetcol(fitems[int1]).fwidgetname <> + twidgetcol(self.fitems[int1]).fwidgetname then begin + bo1:= true; + break; + end; + end; + end; + end; + end; + filer.defineproperty('colorder',{$ifdef FPC}@{$endif}readorder, + {$ifdef FPC}@{$endif}writeorder,bo1); + inherited; +end; + +function twidgetcols.getcollectionname(const aindex: integer): string; +begin + result:= twidgetcol(fitems[aindex]).fwidgetname; +end; + +{ twidgetfixcol } + +constructor twidgetfixcol.create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); +begin + setlength(ffixrowwidgets,agrid.fixrows.count); + inherited; +end; + +destructor twidgetfixcol.destroy; +var + int1: integer; +begin + if not (csdestroying in fcellinfo.grid.componentstate) then begin + for int1:= 0 to high(ffixrowwidgets) do begin + if ffixrowwidgets[int1] <> nil then begin + freedesigncomponent(ffixrowwidgets[int1]); + //inhibit deleting of inherited widget + end; + end; + end; + inherited; +end; + +procedure twidgetfixcol.readfixwidgetnames(reader: treader); +begin + readstringar(reader,ffixrowwidgetnames); +end; + +procedure twidgetfixcol.writefixwidgetnames(writer: twriter); +begin + writewidgetnames(writer,ffixrowwidgets); +end; + +procedure twidgetfixcol.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('fixwidgetnames',{$ifdef FPC}@{$endif}readfixwidgetnames, + {$ifdef FPC}@{$endif}writefixwidgetnames, + (filer.ancestor = nil) and needswidgetnamewriting(ffixrowwidgets) or + (filer.ancestor <> nil) and + needswidgetnamewriting(ffixrowwidgets, + twidgetfixcol(filer.ancestor).ffixrowwidgets)); +end; + +procedure twidgetfixcol.setfixrowwidget(const awidget: twidget; const rowindex: integer); +begin + tcustomwidgetgrid(fcellinfo.grid).removefixwidget(awidget); + ffixrowwidgets[-rowindex-1]:= awidget; + fcellinfo.grid.layoutchanged; +end; + +function twidgetfixcol.getfixrowwidgets(aindex: integer): twidget; +var + i1: int32; +begin + i1:= -1-aindex; + checkarrayindex(ffixrowwidgets,i1); + result:= ffixrowwidgets[i1]; +end; + +procedure twidgetfixcol.setfixrowwidgets(aindex: integer; + const avalue: twidget); +begin + checkarrayindex(ffixrowwidgets,-1-aindex); + setfixrowwidget(avalue,aindex); +end; + +{ twidgetfixcols } + +constructor twidgetfixcols.create(const aowner: tcustomwidgetgrid); +begin + inherited create(aowner); + fitemclasstype:= twidgetfixcol; +end; + +function twidgetfixcols.getcols(const index: integer): twidgetfixcol; +begin + result:= twidgetfixcol(inherited cols[index]); +end; + +procedure twidgetfixcols.unregisterchildwidget(const child: twidget); +var + int1,int2: integer; +begin + if not (csdestroying in fgrid.componentstate) then begin + for int1:= 0 to count - 1 do begin + with twidgetfixcol(items[int1]) do begin + for int2:= 0 to high(ffixrowwidgets) do begin + if ffixrowwidgets[int2] = child then begin + ffixrowwidgets[int2]:= nil; + break; + end; + end; + end; + end; + end; +end; + +{ tdummywidget } + +constructor tdummywidget.create(aowner: tcomponent); +begin + inherited; + foptionswidget:= defaultoptionswidgetnofocus; + exclude(fwidgetstate,ws_iswidget); + size:= nullsize; +end; + +function tdummywidget.getassistiveflags(): assistiveflagsty; +begin + result:= inherited getassistiveflags() + [asf_dummy]; +end; + +function tdummywidget.setfocus(aactivate: boolean = true): boolean; +begin + if canfocus then begin + result:= inherited setfocus(aactivate); + end + else begin + window.nofocus; + result:= false; + end; +end; + +{ tcontainer1 } + +procedure tcontainer1.doexit; +begin +// if fgrid.factivewidget <> nil then begin +// fgrid.factivewidget.visible:= false; +// end; + inherited; +end; + +procedure tcontainer1.doenter; +begin + if fgrid.factivewidget <> nil then begin + fgrid.factivewidget.visible:= true; + end; + inherited; +end; + +function tcontainer1.getiassistiveclient(): iassistiveclient; +begin +// result:= iassistiveclientgrid(fgrid); + result:= fgrid.getiassistiveclient(); +end; + +{ +procedure tcontainer1.registerchildwidget(const child: twidget); +var + int1: integer; +begin + if ws1_oldautoscale in twidget1(child).fwidgetstate1 then begin + foldautoscale:= true; + end; + if foldautoscale then begin + for int1:= 0 to high(fwidgets) do begin + with twidget1(fwidgets[int1]) do begin + if not (ws1_oldautoscale in fwidgetstate1) then begin + exclude(foptionswidget1,ow1_autoscale); + end; + end; + end; + end; + inherited; +end; +} +{ tfixcontainer } + +constructor tfixcontainer.create(aowner: tcustomwidgetgrid); +begin + fgrid:= aowner; + inherited create({nil}aowner); + include(fwidgetstate,ws_nopaint); + exclude(fwidgetstate,ws_opaque); + exclude(fwidgetstate,ws_iswidget); + foptionswidget:= foptionswidget + + [ow_mousetransparent,ow_arrowfocusin,ow_arrowfocusout,ow_subfocus, + ow_focusbackonesc]; + setlockedparentwidget(aowner); +// parentwidget:= aowner; +end; + +procedure tfixcontainer.unregisterchildwidget(const child: twidget); +begin + twidgetfixrows(fgrid.ffixrows).unregisterchildwidget(child); + inherited; +end; + +procedure handlewidgetregionchanged(const self: twidget; + const grid: tcustomwidgetgrid; const sender: twidget); +var + cell1,cell2: gridcoordty; + int1,int2,int3: integer; + pt1: pointty; +begin + with self do begin + if not (gs_layoutupdating in grid.fstate) and (sender <> nil) and + (grid.componentstate * [csdesigning,csdestroying] = [csdesigning]) and + (not (csloading in grid.componentstate) or + (ws1_autoscaling in twidget1(sender).fwidgetstate1)) and + (twidget1(sender).fparentwidget = self) then begin + with grid do begin + cell1:= widgetcell(sender); + if cell1.row <> invalidaxis then begin + if self = grid then begin + pt1:= self.paintpos; + pt1.x:= -pt1.x; + pt1.y:= -pt1.y; + end + else begin + pt1:= self.parentpaintpos; + end; + if (cellatpos(addpoint( + rectcenter(sender.widgetrect),pt1),cell2) in + [ck_fixrow,ck_fixcolrow]) and + ((cell1.col <> cell2.col) or (cell1.row <> cell2.row)) and + (cellwidget(cell2) = nil) then begin + if cell1.col >= 0 then begin + datacols[cell1.col].ffixrowwidgets[-1-cell1.row]:= nil; + end + else begin + fixcols[cell1.col].ffixrowwidgets[-1-cell1.row]:= nil; + end; + if cell2.col >= 0 then begin + datacols[cell2.col].ffixrowwidgets[-1-cell2.row]:= sender; + end + else begin + fixcols[cell2.col].ffixrowwidgets[-1-cell2.row]:= sender; + end; + end + else begin + with ffixrows[cell1.row] do begin + height:= sender.bounds_cy; + int1:= 0; + int3:= 0; + if cell1.col < 0 then begin + int2:= -1-cell1.col; + if (int2 < captionsfix.count) and (int2 >= 0) then begin + with captionsfix[cell1.col] do begin + int1:= mergedcx; + int3:= mergedcy; + end; + end; + ffixcols[cell1.col].width:= sender.bounds_cx - int1; + end + else begin + if cell1.col < captions.count then begin + with captions[cell1.col] do begin + int1:= mergedcx; + int3:= mergedcy; + end; + end; + fdatacols[cell1.col].width:= sender.bounds_cx - int1; + end; + height:= sender.bounds_cy - int3; + end; + end; + layoutchanged; + end; + end; + end; + end; +end; + +procedure tfixcontainer.widgetregionchanged(const sender: twidget); +begin + inherited; + handlewidgetregionchanged(self,fgrid,sender); +end; + +procedure tfixcontainer.dochildfocused(const sender: twidget); +begin + inherited; + fgrid.showcell(fgrid.widgetcell(sender)); +end; + +procedure tfixcontainer.doenter; +begin + fgrid.flastfocusedfixwidget:= self; + inherited; +end; + +function tfixcontainer.focusback(const aactivate: boolean = true): boolean; +begin + if (fgrid.factivewidget <> nil) and + (og_containerfocusbackonesc in fgrid.foptionsgrid) then begin + fgrid.factivewidget.activate; + result:= true; + end + else begin + result:= inherited focusback(aactivate); + end; +end; + +{ twidgetdummy } + +constructor twidgetdummy.create(aowner: tcustomwidgetgrid); +begin + fgrid:= aowner; + inherited create(nil{aowner}); + foptionswidget:= []; + include(fwidgetstate,ws_nopaint); + exclude(fwidgetstate,ws_iswidget); + widgetrect:= nullrect; + parentwidget:= aowner.fcontainer2; +end; + +{ tgridcontainer } + +constructor tgridcontainer.create(aowner: tcustomwidgetgrid); +begin + fgrid:= aowner; + inherited create(nil{aowner}); + include(fwidgetstate,ws_nopaint); + exclude(fwidgetstate,ws_opaque); + exclude(fwidgetstate,ws_iswidget); + foptionswidget:= foptionswidget + [ow_mousetransparent, + ow_subfocus,ow_focusbackonesc]; + foptionswidget:= foptionswidget - [ow_tabfocus]; + setlockedparentwidget(aowner); +// parentwidget:= aowner; +end; + +procedure tgridcontainer.unregisterchildwidget(const child: twidget); +begin + twidgetcols(fgrid.fdatacols).unregisterchildwidget(child); + inherited; +end; + +procedure tgridcontainer.dofocus; +begin + if fgrid.factivewidget = nil then begin + fgrid.setfocus; + end + else begin + fgrid.factivewidget.visible:= true; + inherited; + end; +end; + +function tgridcontainer.focusback(const aactivate: boolean = true): boolean; +begin + if fgrid.flastfocusedfixwidget <> nil then begin + fgrid.flastfocusedfixwidget.setfocus(aactivate); + result:= true; + end + else begin + result:= inherited focusback(aactivate); + end; +end; + +procedure tgridcontainer.doenter; +begin + fgrid.invalidatefocusedcell; + inherited; +end; + +procedure tgridcontainer.doexit; +begin + fgrid.invalidatefocusedcell; + inherited; +end; + +{ tscrollgridcontainer } + +procedure tscrollgridcontainer.widgetregionchanged(const sender: twidget); +var + int1,int2,int3,int4: integer; + po1: pointty; + rect1: rectty; + firstscroll,lastscroll: integer; +begin + if not (csdestroying in fgrid.componentstate) then begin + inherited; + if not (gs_layoutupdating in fgrid.fstate) and (sender <> nil) and + (fgrid.componentstate * [csdesigning,csdestroying] = [csdesigning]) and + (not (csloading in fgrid.componentstate) or + (ws1_autoscaling in twidget1(sender).fwidgetstate1)) and + (flayoutupdating = 0) and + (twidget1(sender).fparentwidget = self) then begin + with fgrid do begin + int3:= -1; + for int1:= 0 to datacols.count-1 do begin + with datacols[int1] do begin + if sender = editwidget then begin + int3:= int1; + break; + end; + end + end; + if int3 >= 0 then begin + int4:= sender.bounds_cy; //updatelayout modifies widgetrect + rect1:= cellrect(makegridcoord(0,0)); + po1:= translatepaintpoint(nullpoint,sender,fgrid); + int2:= datacols.count; + for int1:= 0 to datacols.count-1 do begin + with datacols[int1] do begin + if po1.x < rect1.x + width div 2 then begin + int2:= int1; + break; + end; + inc(rect1.x,step); + end; + end; + if int2 > int3 then begin + dec(int2); + end; + inc(flayoutupdating); + try + sender.bounds_cy:= int4; + datarowheight:= int4; + datacols[int3].width:= sender.bounds_cx; + layoutchanged; + firstscroll:= bigint; + if int2 <> int3 then begin + for int1:= 0 to datacols.count-1 do begin + if tdatacol1(twidgetcols(fdatacols).fitems[int1]).scrollable() then begin + firstscroll:= int1; + break; + end; + end; + lastscroll:= -1; + for int1:= datacols.count-1 downto 0 do begin + if tdatacol1(twidgetcols(fdatacols).fitems[int1]).scrollable() then begin + lastscroll:= int1; + break; + end; + end; + if tdatacol1(twidgetcols(datacols).fitems[int3]).scrollable() then begin + if int2 > int3 then begin //scrollable to right + if int2 > lastscroll then begin + int2:= lastscroll; + end; + end + else begin + if int2 <= firstscroll then begin //scrolable to left + int2:= firstscroll; + end; + end; + end + else begin + if int2 > int3 then begin //fix to right + if int2 >= firstscroll then begin + if int2 < lastscroll then begin + int2:= lastscroll; + end; + end; + end + else begin //fix to left + if int2 <= lastscroll then begin + if int2 > firstscroll then begin + int2:= firstscroll; + end; + end; + end; + end; + if int3 <> int2 then begin + movecol(int3,int2); + end; + end; + finally + dec(flayoutupdating); + end; + end; + internalupdatelayout; + //updatelayout; + end; + end; + end; +end; + +{ tnoscrollgridcontainer } +{ +constructor tnoscrollgridcontainer.create(aowner: tcustomwidgetgrid); +begin + inherited; + optionswidget:= optionswidget - [ow_arrowfocusin]; +end; +} +{ tcustomwidgetgrid } + +constructor tcustomwidgetgrid.create(aowner: tcomponent); +begin +// fmousefocusedcell.col:= -1; + inherited; + fcontainer0:= tnoscrollgridcontainer.create(self); + fcontainer0.name:= '_co0'; //debug purpose + fcontainer1:= ttopcontainer.create(self); + fcontainer1.name:= '_co1'; //debug purpose + fcontainer2:= tscrollgridcontainer.create(self); + fcontainer2.name:= '_co2'; //debug purpose + fcontainer3:= tbottomcontainer.create(self); + fcontainer3.name:= '_co3'; //debug purpose + fwidgetdummy:= tdummywidget.create(self); + include(fstate,gs_layoutupdating); + fwidgetdummy.setlockedparentwidget(fcontainer2); + exclude(fstate,gs_layoutupdating); +// fwidgetdummy.parentwidget:= fcontainer2; + setoptionsgrid(foptionsgrid); //synchronize container +// fcontainer.Name:= 'container'; +end; + +destructor tcustomwidgetgrid.destroy; +begin + flastfocusedfixwidget:= nil; + fwidgetdummy.free; + fcontainer1.free; + freeandnil(fcontainer2); + freeandnil(fcontainer0); + fcontainer3.free; + inherited; +end; + +procedure tcustomwidgetgrid.setoptionsgrid(const avalue: optionsgridty); +begin + if fcontainer2 <> nil then begin + with fcontainer2 do begin + if og_containerfocusbackonesc in avalue then begin + optionswidget:= optionswidget + [ow_focusbackonesc]; + end + else begin + optionswidget:= optionswidget - [ow_focusbackonesc]; + end; + end; + end; + if fcontainer0 <> nil then begin + with fcontainer0 do begin + if og_containerfocusbackonesc in avalue then begin + optionswidget:= optionswidget + [ow_focusbackonesc]; + end + else begin + optionswidget:= optionswidget - [ow_focusbackonesc]; + end; + end; + end; + inherited; +end; + +procedure tcustomwidgetgrid.createdatacol(const index: integer; + out item: tdatacol); +begin + item:= twidgetcol.create(self,fdatacols); +end; + +procedure tcustomwidgetgrid.updatecontainerrect; +var + rect1: rectty; +begin + if fcontainer0 <> nil then begin + rect1:= fdatarecty; + fcontainer0.widgetrect:= moverect(rect1,paintpos); + //for nohscroll widgets + end; + rect1:= fdatarectx; + if fcontainer1 <> nil then begin + rect1.cy:= fdatarect.y - rect1.y; + fcontainer1.widgetrect:= moverect(rect1,paintpos); + end; + if fcontainer3 <> nil then begin + rect1.y:= fdatarect.y + fdatarect.cy; + rect1.cy:= fdatarectx.y + fdatarectx.cy - rect1.y; + fcontainer3.widgetrect:= moverect(rect1,paintpos); + end; + if fcontainer2 <> nil then begin + fcontainer2.widgetrect:= moverect(fdatarect,paintpos); + { + if csdesigning in componentstate then begin + rect1:= fdatarect; +// dec(rect1.x,ffirstnohscroll); +// inc(rect1.cx,ffirstnohscroll); + end + else begin + if noscrollingcol then begin + rect1:= fdatarecty; + end + else begin + rect1:= fdatarect; + end; + end; + fcontainer2.widgetrect:= moverect(rect1,paintpos); + } + end; +end; + +procedure tcustomwidgetgrid.updatelayout; +var + int1: integer; +begin + inherited; + updatecontainerrect; + for int1:= 0 to fdatacols.count - 1 do begin + twidgetcols(fdatacols)[int1].updatewidgetrect + end; + twidgetfixrows(ffixrows).updatewidgetrect; +end; + +procedure tcustomwidgetgrid.dofocusedcellposchanged; +begin + if ffocusedcell.col >= 0 then begin + twidgetcols(fdatacols)[ffocusedcell.col].updatewidgetrect; + end; + inherited; +end; + +procedure tcustomwidgetgrid.dorowsmoved(const fromindex,toindex,count: integer); +var + int1: integer; +begin + if ffocusedcell.col >= 0 then begin + if (focusedcell.row >= toindex) and (focusedcell.row < toindex + count) then begin + for int1:= 0 to fdatacols.count - 1 do begin + with twidgetcols(fdatacols)[int1] do begin + if (co_norearange in foptions) and (fintf <> nil) then begin + fintf.gridtovalue(ffocusedcell.row); + end; + end; + end; + end; + end; + inherited; +end; + +function tcustomwidgetgrid.getdatacols: twidgetcols; +begin + result:= twidgetcols(fdatacols); +end; + +procedure tcustomwidgetgrid.setdatacols(const avalue: twidgetcols); +begin + inherited; +end; + +function tcustomwidgetgrid.getfixcols: twidgetfixcols; +begin + result:= twidgetfixcols(ffixcols); +end; + +procedure tcustomwidgetgrid.setfixcols(const avalue: twidgetfixcols); +begin + inherited; +end; + +function tcustomwidgetgrid.getfixrows: twidgetfixrows; +begin + result:= twidgetfixrows(ffixrows); +end; + +procedure tcustomwidgetgrid.setfixrows(const avalue: twidgetfixrows); +begin + inherited; +end; + +procedure tcustomwidgetgrid.insertwidget(const awidget: twidget; + const apos: pointty); +var + po1: pointty; + cell1,cell2: gridcoordty; + intf: igridwidget; + leftnohscroll,rightnohscroll: boolean; +begin + if not (csloading in componentstate) then begin + internalupdatelayout; + po1:= subpoint(apos,paintpos); + cell1:= cellatpos(po1); + if (cell1.row <> invalidaxis) and (cell1.col <> invalidaxis) and + (cell1.row < 0) then begin + if not checkdescendent(awidget) then begin //new insert + exclude(twidget1(awidget).foptionswidget1,ow1_autoscale); + end; + if cell1.col >= 0 then begin + datacols[cell1.col].setfixrowwidget(awidget,cell1.row); + end + else begin + fixcols[cell1.col].setfixrowwidget(awidget,cell1.row); + end; + end + else begin + if (cell1.col >= 0) or (cell1.col = invalidaxis) then begin + if not checkdescendent(awidget) then begin //new insert + if not awidget.getcorbainterface(typeinfo(igridwidget),intf) then begin + error(gre_invalidwidget); + end; + if cell1.col < 0 then begin + cell1.col:= fdatacols.count; + end + else begin + with twidgetcol(fdatacols[cell1.col]) do begin + po1.x:= po1.x + (fend - fstart) div 2; + cell2:= cellatpos(po1); + if cell2.col <> cell1.col then begin + inc(cell1.col); //next col + end; + end; + end; + fdatacols.insertdefault(cell1.col); + leftnohscroll:= false; + rightnohscroll:= false; + if cell1.col > 0 then begin + leftnohscroll:= co_nohscroll in fdatacols[cell1.col-1].options; + end; + if cell1.col < datacols.count-1 then begin + rightnohscroll:= co_nohscroll in fdatacols[cell1.col+1].options; + end; + if cell1.col = 0 then begin + leftnohscroll:= rightnohscroll; + end; + if cell1.col = datacols.count-1 then begin + rightnohscroll:= leftnohscroll; + end; + if leftnohscroll and rightnohscroll then begin + fdatacols[cell1.col].options:= fdatacols[cell1.col].options + + [co_nohscroll]; + end; + awidget.parentwidget:= fcontainer2; + datacols[cell1.col].setwidget(awidget); + intf.initgridwidget; + end; + end + else begin + inherited; + end; + end; + end + else begin + inherited; + end; +end; + +function tcustomwidgetgrid.editwidgetatpos(const apos: pointty; + out cell: gridcoordty): twidget; +begin + if cellatpos(apos,cell) = ck_data then begin + result:= datacols[cell.col].editwidget; + end + else begin + result:= nil; + end; +end; + +function tcustomwidgetgrid.widgetcell(const awidget: twidget): gridcoordty; +var + int1,int2{,int3}: integer; +begin + if awidget <> nil then begin + for int1:= 0 to fdatacols.count - 1 do begin + with twidgetcol(fdatacols.items[int1]) do begin + if (fintf <> nil) and (fintf.getwidget = awidget) then begin + result.col:= int1; + result.row:= row; + exit; + end; + for int2:= 0 to high(ffixrowwidgets) do begin + if ffixrowwidgets[int2] = awidget then begin + result.col:= int1; + result.row:= -int2-1; //int2-ffixrows.count; + exit; + end; + end; + end; + end; + for int1:= 0 to ffixcols.count - 1 do begin + with twidgetfixcol(ffixcols.items[int1]) do begin + for int2:= 0 to high(ffixrowwidgets) do begin + if ffixrowwidgets[int2] = awidget then begin + result.col:= -int1 - 1; //int1 - fixcols.count; + result.row:= -int2 - 1; //int2 - fixrows.count; + exit; + end; + end; + end; + end; + end; + result:= invalidcell; +end; + +function tcustomwidgetgrid.cellwidget(const acell: gridcoordty): twidget; +var + co1,ro1: integer; +begin + result:= nil; + if acell.col >= 0 then begin + if acell.col < fdatacols.count then begin + if acell.row >= 0 then begin + if acell.row < rowcount then begin + result:= datacols[acell.col].editwidget; + end; + end + else begin + ro1:= -1-acell.row; + with datacols[acell.col] do begin + if ro1 <= high(ffixrowwidgets) then begin + result:= ffixrowwidgets[ro1]; + end; + end; + end; + end; + end + else begin + co1:= -1-acell.col; + if (co1 < fixcols.count) and (acell.row < 0) then begin + ro1:= -1-acell.row; + with twidgetfixcol(twidgetfixcols(ffixcols).fitems[co1]) do begin + if ro1 <= high(ffixrowwidgets) then begin + result:= ffixrowwidgets[ro1]; + end; + end; + end; + end; +end; + +function tcustomwidgetgrid.getcontainer: twidget; +begin + result:= fcontainer2; +end; + +function tcustomwidgetgrid.getchildwidgets(const index: integer): twidget; +var + int1,int2: integer; +begin + int2:= fcontainer2.childrencount; + if index < int2 then begin + result:= fcontainer2.children[index]; + end + else begin + int1:= index - int2; + int2:= fcontainer0.childrencount; + if int1 < int2 then begin + result:= fcontainer0.children[int1]; + end; + int1:= index - int2; + int2:= fcontainer1.childrencount; + if int1 < int2 then begin + result:= fcontainer1.children[int1]; + end + else begin + result:= fcontainer3.children[int1-int2]; + end; + end; +end; + +procedure tcustomwidgetgrid.removefixwidget(const awidget: twidget); +var + int1,int2: integer; +begin + if awidget <> nil then begin + if flastfocusedfixwidget = awidget then begin + flastfocusedfixwidget:= nil; + end; + for int1:= 0 to high(twidgetcols(fdatacols).fitems) do begin + with twidgetcol(twidgetcols(fdatacols).fitems[int1]) do begin + for int2:= 0 to high(ffixrowwidgets) do begin + if ffixrowwidgets[int2] = awidget then begin + ffixrowwidgets[int2]:= nil; + end; + end; + end; + end; + for int1:= 0 to high(twidgetfixcols(ffixcols).fitems) do begin + with twidgetfixcol(twidgetfixcols(ffixcols).fitems[int1]) do begin + for int2:= 0 to high(ffixrowwidgets) do begin + if ffixrowwidgets[int2] = awidget then begin + ffixrowwidgets[int2]:= nil; + end; + end; + end; + end; + end; +end; + +function tcustomwidgetgrid.childrencount: integer; +begin + result:= fcontainer0.childrencount + fcontainer2.childrencount + + fcontainer1.childrencount + fcontainer3.childrencount; +end; + +function tcustomwidgetgrid.getlogicalchildren: widgetarty; +begin + result:= inherited getlogicalchildren; + fcontainer1.addlogicalchildren(result); + fcontainer3.addlogicalchildren(result); +end; + +function tcustomwidgetgrid.createdatacols: tdatacols; +begin + result:= twidgetcols.create(self); +end; + +function tcustomwidgetgrid.createfixrows: tfixrows; +begin + result:= twidgetfixrows.create(self); +end; + +function tcustomwidgetgrid.createfixcols: tfixcols; +begin + result:= twidgetfixcols.create(self); +end; + +procedure tcustomwidgetgrid.setoptionswidget(const avalue: optionswidgetty); +begin + inherited setoptionswidget(avalue - [ow_subfocus]); +end; +{ +procedure tcustomwidgetgrid.focusedcellchanged; +begin + inherited; + if col >= 0 then begin + with twidgetcol(twidgetcols(fdatacols).fitems[col]) do begin + updatewidgetrect(true); + end; + end; +end; +} +function tcustomwidgetgrid.checksubfocus(const aactivate: boolean): boolean; +begin + result:= false; + if (factivewidget <> nil) and (factivewidget <> fwidgetdummy) then begin + factivewidget.visible:= true; + if factivewidget.canfocus then begin + factivewidget.setfocus(aactivate); + result:= true; + end; + end; + if not result then begin + result:= inherited checksubfocus(aactivate); + end; +end; +{ +procedure tcustomwidgetgrid.dofocus; +begin + inherited; + if (factivewidget <> nil) and (factivewidget <> fwidgetdummy) then begin + factivewidget.visible:= true; + if factivewidget.canfocus then begin + factivewidget.setfocus(false); + end; + end; +end; +} +procedure tcustomwidgetgrid.unregisterchildwidget(const child: twidget); +begin + twidgetfixrows(ffixrows).unregisterchildwidget(child); + twidgetfixcols(ffixcols).unregisterchildwidget(child); + inherited; +end; + +procedure tcustomwidgetgrid.widgetregionchanged(const sender: twidget); +begin + inherited; + handlewidgetregionchanged(self,self,sender); +end; + +procedure tcustomwidgetgrid.scrolled(const dist: pointty); +var + po1: pointty; + bo1: boolean; +begin + po1:= dist; + if csdesigning in componentstate then begin + po1.y:= 0; + end; + twidget1(fcontainer2).scrollwidgets(po1); + po1.x:= 0; + twidget1(fcontainer0).scrollwidgets(po1); + if dist.x <> 0 then begin + if csdesigning in componentstate then begin + bo1:= gs_layoutupdating in fstate; + include(fstate,gs_layoutupdating); + try + twidgetfixrows(ffixrows).updatewidgetrect; + finally + if not bo1 then begin + exclude(fstate,gs_layoutupdating); + end; + end; + end + else begin + twidgetfixrows(ffixrows).updatewidgetrect; + end; + end; + inherited; +end; + +procedure tcustomwidgetgrid.getchildren(proc: tgetchildproc; root: tcomponent); +begin + inherited; + twidget1(fcontainer2).getchildren(proc,root); + twidget1(fcontainer0).getchildren(proc,root); + twidget1(fcontainer1).getchildren(proc,root); + twidget1(fcontainer3).getchildren(proc,root); +end; +{ +procedure tcustomwidgetgrid.dobeginread; +var + int1: integer; +begin + setlength(fwidgetcolorder,fdatacols.count); + for int1:= 0 to high(fwidgetcolorder) do begin + with fwidgetcolorder[int1], + twidgetcol(twidgetcols(fdatacols).fitems[int1]) do begin + colwidgetname:= fwidgetname; + coldatalist:= fdata; + end; + end; + inherited; +end; +} +procedure tcustomwidgetgrid.doendread; +var + int1,int2,int3: integer; + ar1: widgetarty; +// ar2: array of igridwidget; + str1: string; +// intf1: igridwidget; +begin + twidgetcols(fdatacols).updatecolorder; + inc(tgridcontainer(fcontainer2).flayoutupdating); + include(fstate,gs_layoutupdating); + try + ar1:= copy(fwidgets); + for int1:= 0 to high(fwidgets) do begin + with twidget1(fwidgets[int1]) do begin + for int2:= 0 to high(fwidgets) do begin + additem(pointerarty(ar1),pointer(fwidgets[int2])); + //add children, possibly inherited + end; + end; + end; +{ + if (csdesigning in componentstate) then begin + setlength(ar2,length(ar1)); //init check deleted widgets + for int1:= 0 to high(ar2) do begin + if ar1[int1].getcorbainterface(typeinfo(igridwidget),intf1) and + (intf1.getgridintf <> nil) then begin + ar2[int1]:= intf1; + end; + end; + end; +} + for int1:= 0 to fdatacols.count - 1 do begin + with twidgetcols(fdatacols)[int1] do begin + for int2:= 0 to high(ar1) do begin + if ar1[int2] <> nil then begin + str1:= findpastedcomponentname(ar1[int2]); + if str1 = '' then begin + str1:= ar1[int2].name; + end; + if str1 <> '' then begin + if (str1 = fwidgetname) then begin + ar1[int2].parentwidget:= fcontainer2; +// if (csdesigning in componentstate) then begin +// ar2[int2]:= nil; //linked +// end; + fintf:= nil; + //do not remove existing link, inherited order could be changed +{ for int3:= 0 to high(fwidgetcolorder) do begin + with fwidgetcolorder[int3] do begin + if colwidgetname = str1 then begin + fdata:= coldatalist; //repair inherited col order + break; + end; + end; + end; + } + setwidget(ar1[int2]); + ar1[int2]:= nil; + end; + if ar1[int2] <> nil then begin + for int3:= 0 to high(ffixrowwidgetnames) do begin + if str1 = ffixrowwidgetnames[int3] then begin + setfixrowwidget(ar1[int2],-int3-1); + ffixrowwidgetnames[int3]:= ''; + ar1[int2]:= nil; + break; + end; + end; + end; + end; + end; + end; + ffixrowwidgetnames:= nil; + end; + end; +{ + if csdesigning in componentstate then begin //check deleted inherited widgets + for int1:= 0 to high(ar2) do begin + if ar2[int1] <> nil then begin + ar2[int1].setgridintf(nil); + end; + end; + end; +} + for int1:= 0 to fdatacols.count - 1 do begin + twidgetcols(fdatacols)[int1].sourcenamechanged(-1); + end; + for int1:= 0 to ffixcols.count - 1 do begin + with twidgetfixcol(ffixcols.items[int1]) do begin + for int2:= 0 to high(ar1) do begin + if ar1[int2] <> nil then begin + str1:= ar1[int2].name; + if str1 <> '' then begin + for int3:= 0 to high(ffixrowwidgetnames) do begin + if str1 = ffixrowwidgetnames[int3] then begin + setfixrowwidget(ar1[int2],-int3-1); + ffixrowwidgetnames[int3]:= ''; + ar1[int2]:= nil; + break; + end; + end; + end; + end; + end; + end; + end; + finally + exclude(fstate,gs_layoutupdating); + dec(tgridcontainer(fcontainer2).flayoutupdating); + end; + inherited; +end; + +function tcustomwidgetgrid.scrollcaret(const vertical: boolean): boolean; +begin + result:= (factivewidget <> nil) and + ((factivewidget.parentwidget = fcontainer2) or vertical) and + twidget1(factivewidget).hascaret; +end; + +procedure tcustomwidgetgrid.childmouseevent(const sender: twidget; + var info: mouseeventinfoty); +var + po1: pointty; +begin + with info do begin + if not (es_reflected in eventstate) then begin + if (eventkind in [ek_mousemove,ek_mousepark, + ek_buttonpress,ek_buttonrelease]) then begin + po1:= translateclientpoint(nullpoint,sender,self); + addpoint1(pos,po1); + if sender.checkancestor(factivewidget) then begin + clientmouseevent(info); + end + else begin + with fobjectpicker do begin + if (sender <> fcontainer2) and (sender <> self) and + ((fpickkind = pok_datacolsize) or + (eventkind <> ek_buttonpress)) then begin + include(fstate,gs_child); + mouseevent(info); + exclude(fstate,gs_child); + if not (fpickkind in [pok_datacolsize,pok_datacol]) then begin + exclude(eventstate,es_processed); + end + else begin + include(eventstate,es_processed); + end; + end; + end; + end; + subpoint1(pos,po1); + end + else begin + if (eventkind = ek_mousecaptureend) and (sender = factivewidget) then begin + clientmouseevent(info); + end; + end; + end + end; + inherited; +end; + +procedure tcustomwidgetgrid.clientmouseevent(var info: mouseeventinfoty); +begin + fmouseinfopo:= @info; + try + inherited; + finally; +// fmouseinfopo:= @info; + fmouseinfopo:= nil; + end; + if (info.eventkind = ek_buttonpress) and + (factivewidget <> nil) and entered then begin + include(info.eventstate,es_nofocus); //do not set focus to grid + end; + if (info.eventkind = ek_buttonrelease) and (info.button = mb_left) and + (gs_childmousecaptured in fstate) then begin + exclude(fstate,gs_childmousecaptured); + releasemouse; + end; +end; + +procedure tcustomwidgetgrid.initcopyars(out dataedits: widgetarty; + out datalists: datalistarty); +var + int1: integer; +begin + setlength(dataedits,datacols.count); + setlength(datalists,length(dataedits)); + for int1:= 0 to high(dataedits) do begin + dataedits[int1]:= datacols[int1].editwidget; + datalists[int1]:= datacols[int1].datalist; + if not (dataedits[int1] is tcustomdataedit) or + not tdataedit1(dataedits[int1]).textcellcopy then begin + dataedits[int1]:= nil; + end; + end; +end; + +function tcustomwidgetgrid.copyselection: boolean; +var + ar2: widgetarty; + ar3: datalistarty; + ar1: gridcoordarty; + wstr1,wstr2: msestring; + int1,int2: integer; + +begin + result:= inherited copyselection; + if result then begin + exit; + end; + ar1:= datacols.selectedcells; + if ar1 <> nil then begin + initcopyars(ar2,ar3); + wstr1:= ''; + int2:= ar1[0].row; + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + if row <> int2 then begin + removetabterminator(wstr1); + wstr1:= wstr1 + lineend; + int2:= row; + end; + wstr2:= ''; + if co_cancopy in datacols[ar1[int1].col].foptions then begin + if ar2[col] <> nil then begin + with tdataedit1(ar2[col]) do begin + wstr2:= datatotext(ar3[col].getitempo(row)^); + end; + end + else begin + if ar3[col] <> nil then begin + wstr2:= ar3[col].getastext(row); + { + case ar3[col].datatype of + dl_integer: wstr2:= inttostr(tintegerdatalist(ar3[col]).items[row]); + end; + } + end; + end; + wstr1:= wstr1 + wstr2 + c_tab; + end; + end; + end; + removetabterminator(wstr1); + wstr1:= wstr1 + lineend; //terminator + copytoclipboard(wstr1); + result:= true; + end; +end; + +function tcustomwidgetgrid.pasteselection: boolean; +var + ar2: widgetarty; + ar3: datalistarty; + ar1: gridcoordarty; + wstr1: msestring; + int1,int2,int3,int5: integer; + ar4,ar5: msestringarty; + bo1,bo2: boolean; + + procedure setcelltext(const atext: msestring; const acol,arow: integer); + begin + if ar2[acol] <> nil then begin + if ar3[acol] <> nil then begin + tdataedit1(ar2[acol]).texttodata(atext,ar3[acol].getitempo(arow)^); + ar3[acol].change(arow); + end; + end + else begin + if ar3[acol] <> nil then begin + ar3[acol].setastext(arow,atext); + end; + end; + end; //setcelltext + +begin + result:= inherited pasteselection; + if result then begin + exit; + end; + ar1:= nil; //compiler warning + ar4:= nil; + ar5:= nil; + initcopyars(ar2,ar3); +// result:= false; + bo1:= false; + for int1:= 0 to datacols.count - 1 do begin + if co_canpaste in datacols[int1].options then begin + bo1:= true; + end + else begin + ar2[int1]:= nil; + ar3[int1]:= nil; + end; + end; + if bo1 and pastefromclipboard(wstr1) then begin + ar4:= breaklines(wstr1); + bo2:= high(ar4) > 0; + if high(ar4) >= 0 then begin + if ar4[high(ar4)] = '' then begin + setlength(ar4,high(ar4)); //remove terminator + end; + beginupdate; + try + if (og1_pasteinselection in optionsgrid1) and (high(ar4) = 0) and + datacols.hasselection and (findchar(ar4[0],c_tab) = 0) then begin + ar1:= datacols.selectedcells; + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + setcelltext(ar4[0],col,row); + end; + end; + end + else begin + if not bo2 then begin + exit; + end; + int5:= row; + if int5 < 0 then begin + int5:= 0; + end; + datacols.clearselection; + // int1:= row; + bo2:= og_rowinserting in optionsgrid; + if bo2 then begin + insertrow(int5,length(ar4)); + end; + if high(ar4) >= rowcount - int5 then begin + setlength(ar4,rowcount-int5); + end; + for int1:= 0 to high(ar4) do begin + if bo2 then begin + datacols.selected[makegridcoord(invalidaxis,int5)]:= true; + end; + ar5:= splitstring(ar4[int1],c_tab); + int3:= 0; + for int2:= 0 to high(ar5) do begin + while (int3 < datacols.count) and + not (co_canpaste in datacols[int3].options) do begin + inc(int3); + end; + if int3 >= datacols.count then begin + break; + end; + if not bo2 then begin + datacols[int3].selected[int5]:= true; + end; + try + setcelltext(ar5[int2],int3,int5); + except + end; + inc(int3); + end; + inc(int5); + end; + end; + finally + try + updaterowdata; + finally + endupdate; + end; + end; + result:= true; + end; + end; +end; + +procedure tcustomwidgetgrid.mouseevent(var info: mouseeventinfoty); +var + bo1: boolean; + fmousefocusedcell: gridcoordty; + fmouseactivewidget: twidget; + fmousefocusedwidget: twidget; + pt1: pointty; + widget1: twidget; +begin + fmousefocusedcell:= ffocusedcell; + fmouseactivewidget:= factivewidget; + fmousefocusedwidget:= window.focusedwidget; + inherited; + if (info.eventstate * [es_processed,es_child] = []) and + not (gs_mousecellredirected in fstate) and + (factivewidget <> nil) and + ((fmouseactivewidget <> factivewidget) or + ((ffocusedcell.row <> fmousefocusedcell.row)) or + (fmousefocusedwidget <> window.focusedwidget)) and + (factivewidget.checkdescendent(mouseeventwidget(info))) then begin + bo1:= gs1_mousecaptureendlock in fstate1; + include(fstate1,gs1_mousecaptureendlock); + try + releasemouse; + finally + if not bo1 then begin + exclude(fstate1,gs1_mousecaptureendlock); + end; + end; + if ffocusedcell.col >= 0 then begin + with twidgetcols(fdatacols)[ffocusedcell.col] do begin + if (fintf <> nil) then begin + widget1:= fintf.getwidget(); + pt1:= info.pos; + try + translatewidgetpoint1(info.pos,self,widget1); + fintf.setfirstclick(info); + finally + info.pos:= pt1; + end; + end; + end; + end; + reflectmouseevent(info); + end; +end; + +procedure tcustomwidgetgrid.dowidgetcellevent(var info: celleventinfoty); +var + int1: integer; +begin + if (info.cell.col >= 0) and (info.cell.col < fdatacols.count) and + (twidgetcols(fdatacols)[info.cell.col].fintf <> nil) then begin + twidgetcols(fdatacols)[info.cell.col].fintf.docellevent(true,info); + //chance to update info.cellzone + end; + for int1:= 0 to fdatacols.count - 1 do begin + with twidgetcols(fdatacols)[int1] do begin + if (fintf <> nil) and (info.cell.col <> int1) then begin + fintf.docellevent(false,info); + end; + end; + end; +end; + +procedure tcustomwidgetgrid.docellevent(var info: celleventinfoty); +var + int1: integer; +begin + if (info.cellbefore.row <> info.newcell.row) and + ((info.eventkind = cek_enter) or + (info.eventkind = cek_focusedcellchanged) and + (info.newcell.col = invalidaxis) and + (info.newcell.row >= 0)) then begin + //there was no cek_enter + for int1:= 0 to fdatacols.count - 1 do begin + with twidgetcols(fdatacols)[int1] do begin + if fintf <> nil then begin + fintf.gridtovalue(info.newcell.row); + end; + end; + end; + end + else begin + if (info.eventkind = cek_exit) and (info.newcell.row < 0) and + (info.selectaction <> fca_exitgrid) then begin + for int1:= 0 to fdatacols.count - 1 do begin + with twidgetcols(fdatacols)[int1] do begin + if fintf <> nil then begin + fintf.gridtovalue(-2); + end; + end; + end; + end; + end; + dowidgetcellevent(info); + inherited; +end; + +procedure tcustomwidgetgrid.checkcellvalue(var accept: boolean); +begin + twidgetcols(fdatacols)[ffocusedcell.col].checkcanclose(accept); +end; + +procedure tcustomwidgetgrid.dokeydown(var info: keyeventinfoty); +begin + if not (es_child in info.eventstate) or + ((factivewidget <> nil) and + factivewidget.checkdescendent(window.focusedwidget)) or + (factivewidget = nil) and + not (fcontainer1.entered or fcontainer3.entered) then begin + inherited; + end + else begin + if (info.key = key_escape) and (info.shiftstate = []) and + (og_containerfocusbackonesc in foptionsgrid) and + (flastfocusedfixwidget <> nil) and (factivewidget <> nil) and + flastfocusedfixwidget.focused then begin + factivewidget.activate; + end; + end; +end; + +function tcustomwidgetgrid.getgriddatalink: pointer; +begin + result:= nil; +end; + +procedure tcustomwidgetgrid.doexit; +begin + if canclose(nil) then begin + flastfocusedfixwidget:= nil; + if factivewidget <> nil then begin + factivewidget.visible:= false; + end; + inherited; + end; +end; + +procedure tcustomwidgetgrid.checkrowreadonlystate; +begin + inherited; + if isdatacell(ffocusedcell) then begin + with datacols[ffocusedcell.col] do begin + if fintf <> nil then begin + include(fstate,gps_readonlyupdating); + fintf.setreadonly(isreadonly); + exclude(fstate,gps_readonlyupdating); + end; + end; + end; +end; + +procedure tcustomwidgetgrid.updaterowdata; +var + int1,int2: integer; +begin + int2:= -2; + if ffocusedcell.row >= 0 then begin + int2:= -1; + end; + for int1:= 0 to datacols.count - 1 do begin + with twidgetcol(fdatacols[int1]) do begin + if fintf <> nil then begin + fintf.gridtovalue(int2); //restore grid value + end; + end; + end; +end; + +procedure tcustomwidgetgrid.focuslock; +begin + beginupdate; + inc(ffocuslock); +end; + +procedure tcustomwidgetgrid.focusunlock; +begin + dec(ffocuslock); + if (ffocuslock = 0) and (col >= 0) then begin + twidgetcol(twidgetcols(fdatacols).fitems[col]).updatewidgetrect; + end; + endupdate; +end; + +procedure tcustomwidgetgrid.updatepopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); +var + cell1: gridcoordty; + widget1: twidget; +begin + if not (es_child in mouseinfo.eventstate) then begin + cell1:= cellatpos(mouseinfo.pos); + if (cell1.col >= 0) and + ((cell1.row >= 0) {or (cell1.row = invalidaxis)}) then begin + with datacols[cell1.col] do begin + if fintf <> nil then begin + widget1:= fintf.getwidget; + if widget1 <> nil then begin + translateclientpoint1(mouseinfo.pos,self,widget1); + mouseinfo.eventstate:= mouseinfo.eventstate + [es_parent{,es_child}]; + try + fintf.updatepopupmenu(amenu,mouseinfo); + finally + translateclientpoint1(mouseinfo.pos,widget1,self); + mouseinfo.eventstate:= mouseinfo.eventstate - [es_parent{,es_child}]; + end; + end; + end; + end; + end; + end; + inherited; +end; + +function tcustomwidgetgrid.getassistiveflags(): assistiveflagsty; +var + w1: twidget1; +begin + result:= inherited getassistiveflags(); + include(result,asf_widgetgrid); + if focusedcellvalid then begin + w1:= twidget1(datacols[ffocusedcell.col].editwidget); + if (w1 <> nil) and + (asf_gridwidget in w1.getiassistiveclient().getassistiveflags()) then begin + result:= result + [asf_widgetcell]; + end; + end; +end; + +function tcustomwidgetgrid.getassistivecelltext( + const acell: gridcoordty; out aflags: assistiveflagsty): msestring; +var + w1: twidget; +begin + if isdatacell(acell) then begin + with datacols[acell.col] do begin + if fintf <> nil then begin + result:= fintf.getassistivecelltext(acell.row); + w1:= editwidget; + if w1 <> nil then begin + aflags:= twidget1(w1).getassistiveflags(); + end + else begin + inherited getassistivecelltext(acell,aflags); + end; + end + else begin + result:= inherited getassistivecelltext(acell,aflags); +// result:= ''; + end; + end; + end + else begin + result:= inherited getassistivecelltext(acell,aflags); + end; +end; + +function tcustomwidgetgrid.getassistivecaretindex(): int32; +begin + if factivewidget <> nil then begin + result:= twidget1(factivewidget).getassistivecaretindex(); + end + else begin + result:= inherited getassistivecaretindex(); + end; +end; + +procedure tcustomwidgetgrid.seteditfocus; +begin + if factivewidget <> nil then begin + factivewidget.activate; + end + else begin + activate; + end; +end; + +procedure tcustomwidgetgrid.setcellclientclick(const awidget: twidget); +var + bo1: boolean; +begin + if factivewidget = awidget then begin + bo1:= gs1_mousecaptureendlock in fstate1; + try + include(fstate1,gs1_mousecaptureendlock); + twidget1(awidget).setclientclick; + finally + if not bo1 then begin + exclude(fstate1,gs1_mousecaptureendlock); + end; + end; + end; +end; + +procedure tcustomwidgetgrid.navigrequest(var info: naviginfoty; + const nowrap: boolean); +begin + inherited; + if (info.nearest = fcontainer0) or (info.nearest = fcontainer2) then begin + if factivewidget <> nil then begin + factivewidget.show; + info.nearest:= factivewidget; + end; + end; +end; + +procedure tcustomwidgetgrid.dochildfocused(const sender: twidget); +begin + if (sender <> fcontainer2) and (sender <> fcontainer0) then begin + flastfocusedfixwidget:= sender; + end; + inherited; +end; + +function tcustomwidgetgrid.cellhasfocus: boolean; +begin + result:= fcontainer2.entered or fcontainer0.entered or focused; +end; + +procedure tcustomwidgetgrid.writestate(writer: twriter); +var + int1: integer; +begin + for int1:= 0 to fdatacols.count-1 do begin + with twidgetcol(twidgetcols(fdatacols).fitems[int1]) do begin + if fintf = nil then begin + fwidgetname:= ''; + end + else begin + fwidgetname:= fintf.getwidget.name; + end; + end; + end; + inherited; +end; + +procedure registergriddatalistclass(const tag: ansistring; + const createfunc: creategriddatalistty); +begin + griddatalists.addunique(tag,{$ifndef FPC}@{$endif}createfunc); +end; + +function createtgridmsestringdatalist(const aowner:twidgetcol): tdatalist; +begin + result:= tgridmsestringdatalist.create(aowner); +end; + +function createtgridansistringdatalist(const aowner:twidgetcol): tdatalist; +begin + result:= tgridansistringdatalist.create(aowner); +end; + +function createtgridbinarystringdatalist(const aowner:twidgetcol): tdatalist; +begin + result:= tgridbinarystringdatalist.create(aowner); +end; + +function createtgridpointerdatalist(const aowner:twidgetcol): tdatalist; +begin + result:= tgridpointerdatalist.create(aowner); +end; + +function createtgridintegerdatalist(const aowner:twidgetcol): tdatalist; +begin + result:= tgridintegerdatalist.create(aowner); +end; + +function createtgridint64datalist(const aowner:twidgetcol): tdatalist; +begin + result:= tgridint64datalist.create(aowner); +end; + +function createtgridenumdatalist(const aowner:twidgetcol): tdatalist; +begin + result:= tgridenumdatalist.create(aowner); +end; + +function createtgridenum64datalist(const aowner:twidgetcol): tdatalist; +begin + result:= tgridenum64datalist.create(aowner); +end; + +function createtgridrealdatalist(const aowner:twidgetcol): tdatalist; +begin + result:= tgridrealdatalist.create(aowner); +end; + +{ twidgetgrid } + +procedure twidgetgrid.initnewcomponent(const ascale: real); +begin + inherited; + optionsgrid:= optionsgrid + newcomponentoptionsgridadd; +end; + +{ tgridbinarystringdatalist } + +constructor tgridbinarystringdatalist.create(owner: twidgetcol); +begin + inherited; + include(fstate,dls_binarydata); +end; + +initialization + griddatalists:= tpointeransistringhashdatalist.create; + registergriddatalistclass(tgridmsestringdatalist.classname, + {$ifdef FPC}@{$endif}createtgridmsestringdatalist); + registergriddatalistclass(tgridansistringdatalist.classname, + {$ifdef FPC}@{$endif}createtgridansistringdatalist); + registergriddatalistclass(tgridbinarystringdatalist.classname, + {$ifdef FPC}@{$endif}createtgridbinarystringdatalist); + registergriddatalistclass(tgridpointerdatalist.classname, + {$ifdef FPC}@{$endif}createtgridpointerdatalist); + registergriddatalistclass(tgridintegerdatalist.classname, + {$ifdef FPC}@{$endif}createtgridintegerdatalist); + registergriddatalistclass(tgridint64datalist.classname, + {$ifdef FPC}@{$endif}createtgridint64datalist); + registergriddatalistclass(tgridenumdatalist.classname, + {$ifdef FPC}@{$endif}createtgridenumdatalist); + registergriddatalistclass(tgridenum64datalist.classname, + {$ifdef FPC}@{$endif}createtgridenum64datalist); + registergriddatalistclass(tgridrealdatalist.classname, + {$ifdef FPC}@{$endif}createtgridrealdatalist); +finalization + griddatalists.free; +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_avl.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_avl.pas new file mode 100644 index 0000000..294c4f3 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_avl.pas @@ -0,0 +1,435 @@ +unit dbf_avl; + +interface + +{$I dbf_common.inc} + +uses + Dbf_Common; + +type + TBal = -1..1; + + TAvlTree = class; + + TKeyType = Cardinal; + TExtraData = Pointer; + + PData = ^TData; + TData = record + ID: TKeyType; + ExtraData: TExtraData; + end; + + PNode = ^TNode; + TNode = record + Data: TData; + Left: PNode; + Right: PNode; + Bal: TBal; // balance factor: h(Right) - h(Left) + end; + + TAvlTreeEvent = procedure(Sender: TAvlTree; Data: PData) of object; + + TAvlTree = class(TObject) + private + FRoot: PNode; + FCount: Cardinal; + FOnDelete: TAvlTreeEvent; + FHeightChange: Boolean; + + function InternalInsert(X: PNode; var P: PNode): Boolean; + procedure InternalDelete(X: TKeyType; var P: PNode); + + procedure DeleteNode(X: PNode); + procedure TreeDispose(X: PNode); + public + constructor Create; + destructor Destroy; override; + + procedure Clear; + function Find(Key: TKeyType): TExtraData; + function Insert(Key: TKeyType; Extra: TExtraData): Boolean; + procedure Delete(Key: TKeyType); + + function Lowest: PData; + + property Count: Cardinal read FCount; + property OnDelete: TAvlTreeEvent read FOnDelete write FOnDelete; + end; + + +implementation + +uses + Math; + +procedure RotL(var P: PNode); +var + P1: PNode; +begin + P1 := P^.Right; + P^.Right := P1^.Left; + P1^.Left := P; + P := P1; +end; + +procedure RotR(var P: PNode); +var + P1: PNode; +begin + P1 := P^.Left; + P^.Left := P1^.Right; + P1^.Right := P; + P := P1; +end; + +function Height(X: PNode): Integer; +begin + if X = nil then + Result := 0 + else + Result := 1+Max(Height(X^.Left), Height(X^.Right)); +end; + +function CheckTree_T(X: PNode; var H: Integer): Boolean; +var + HR: Integer; +begin + if X = nil then + begin + Result := true; + H := 0; + end else begin + Result := CheckTree_T(X^.Left, H) and CheckTree_T(X^.Right, HR) and + ((X^.Left = nil) or (X^.Left^.Data.ID < X^.Data.ID)) and + ((X^.Right = nil) or (X^.Right^.Data.ID > X^.Data.ID)) and +// ((Height(X^.Right) - Height(X^.Left)) = X^.Bal); + (HR - H = X^.Bal); + H := 1 + Max(H, HR); + end; +end; + +function CheckTree(X: PNode): Boolean; +var + H: Integer; +begin + Result := CheckTree_T(X, H); +end; + +procedure BalanceLeft(var P: PNode; var HeightChange: Boolean); +var + B1, B2: TBal; +{HeightChange = true, left branch has become less high} +begin + case P^.Bal of + -1: begin P^.Bal := 0 end; + 0: begin P^.Bal := 1; HeightChange := false end; + 1: begin {Rebalance} + B1 := P^.Right^.Bal; + if B1 >= 0 + then {single L rotation} + begin + RotL(P); + //adjust balance factors: + if B1 = 0 + then + begin P^.Bal :=-1; P^.Left^.Bal := 1; HeightChange := false end + else + begin P^.Bal := 0; P^.Left^.Bal := 0 end; + end + else {double RL rotation} + begin + B2 := P^.Right^.Left^.Bal; + RotR(P^.Right); + RotL(P); + //adjust balance factors: + if B2=+1 then P^.Left^.Bal := -1 else P^.Left^.Bal := 0; + if B2=-1 then P^.Right^.Bal := 1 else P^.Right^.Bal := 0; + P^.Bal := 0; + end; + end;{1} + end{case} +end;{BalanceLeft} + +procedure BalanceRight(var P: PNode; var HeightChange: Boolean); +var + B1, B2: TBal; +{HeightChange = true, right branch has become less high} +begin + case P^.Bal of + 1: begin P^.Bal := 0 end; + 0: begin P^.Bal := -1; HeightChange := false end; + -1: begin {Rebalance} + B1 := P^.Left^.Bal; + if B1 <= 0 + then {single R rotation} + begin + RotR(P); + //adjust balance factors} + if B1 = 0 + then + begin P^.Bal :=1; P^.Right^.Bal :=-1; HeightChange:= false end + else + begin P^.Bal := 0; P^.Right^.Bal := 0 end; + end + else {double LR rotation} + begin + B2 := P^.Left^.Right^.Bal; + RotL(P^.Left); + RotR(P); + //adjust balance factors + if B2=-1 then P^.Right^.Bal := 1 else P^.Right^.Bal := 0; + if B2= 1 then P^.Left^.Bal := -1 else P^.Left^.Bal := 0; + P^.Bal := 0; + end; + end;{-1} + end{case} +end;{BalanceRight} + +procedure DelRM(var R: PNode; var S: PNode; var HeightChange: Boolean); +// Make S refer to rightmost element of tree with root R; +// Remove that element from the tree +begin + if R^.Right = nil then + begin S := R; R := R^.Left; HeightChange := true end + else + begin + DelRM(R^.Right, S, HeightChange); + if HeightChange then BalanceRight(R, HeightChange) + end +end; + +//--------------------------------------- +//---****--- Class TAvlTree ---*****----- +//--------------------------------------- + +constructor TAvlTree.Create; +begin + inherited; + + FRoot := nil; +end; + +destructor TAvlTree.Destroy; +begin + Clear; + + inherited; +end; + +procedure TAvlTree.Clear; +begin + TreeDispose(FRoot); + FRoot := nil; +end; + +procedure TAvlTree.DeleteNode(X: PNode); +begin + // delete handler installed? + if Assigned(FOnDelete) then + FOnDelete(Self, @X^.Data); + + // dispose of memory + Dispose(X); + Dec(FCount); +end; + +procedure TAvlTree.TreeDispose(X: PNode); +var + P: PNode; +begin + // nothing to dispose of? + if X = nil then + exit; + + // use in-order visiting, maybe someone likes sequential ordering + TreeDispose(X^.Left); + P := X^.Right; + + // free mem + DeleteNode(X); + + // free right child + TreeDispose(P); +end; + +function TAvlTree.Find(Key: TKeyType): TExtraData; +var + H: PNode; +begin + H := FRoot; + while (H <> nil) and (H^.Data.ID <> Key) do // use conditional and + if Key < H^.Data.ID then + H := H^.Left + else + H := H^.Right; + + if H <> nil then + Result := H^.Data.ExtraData + else + Result := nil; +end; + +function TAvlTree.Insert(Key: TKeyType; Extra: TExtraData): boolean; +var + H: PNode; +begin + // make new node + New(H); + with H^ do + begin + Data.ID := Key; + Data.ExtraData := Extra; + Left := nil; + Right := nil; + Bal := 0; + end; + // insert new node + Result := InternalInsert(H, FRoot); + if not Result then + Dispose(H); + // check tree +// assert(CheckTree(FRoot)); +end; + +procedure TAvlTree.Delete(Key: TKeyType); +begin + InternalDelete(Key, FRoot); +// assert(CheckTree(FRoot)); +end; + +function TAvlTree.InternalInsert(X: PNode; var P: PNode): boolean; +begin + if P = nil then + begin + P := X; + Inc(FCount); + FHeightChange := true; + Result := true; + end else begin + if X^.Data.ID < P^.Data.ID then + begin + { less } + Result := InternalInsert(X, P^.Left); + if FHeightChange then {Left branch has grown higher} + case P^.Bal of + 1: begin P^.Bal := 0; FHeightChange := false end; + 0: begin P^.Bal := -1 end; + -1: begin {Rebalance} + if P^.Left^.Bal = -1 + then {single R rotation} + begin + RotR(P); + //adjust balance factor: + P^.Right^.Bal := 0; + end + else {double LR rotation} + begin + RotL(P^.Left); + RotR(P); + //adjust balance factor: + case P^.Bal of + -1: begin P^.Left^.Bal := 0; P^.Right^.Bal := 1 end; + 0: begin P^.Left^.Bal := 0; P^.Right^.Bal := 0 end; + 1: begin P^.Left^.Bal := -1; P^.Right^.Bal := 0 end; + end; + end; + P^.Bal := 0; + FHeightChange := false; +// assert(CheckTree(P)); + end{-1} + end{case} + end else + if X^.Data.ID > P^.Data.ID then + begin + { greater } + Result := InternalInsert(X, P^.Right); + if FHeightChange then {Right branch has grown higher} + case P^.Bal of + -1: begin P^.Bal := 0; FHeightChange := false end; + 0: begin P^.Bal := 1 end; + 1: begin {Rebalance} + if P^.Right^.Bal = 1 + then {single L rotation} + begin + RotL(P); + //adjust balance factor: + P^.Left.Bal := 0; + end + else {double RL rotation} + begin + RotR(P^.Right); + RotL(P); + //adjust balance factor + case P^.Bal of + 1: begin P^.Right^.Bal := 0; P^.Left^.Bal := -1 end; + 0: begin P^.Right^.Bal := 0; P^.Left^.Bal := 0 end; + -1: begin P^.Right^.Bal := 1; P^.Left^.Bal := 0 end; + end; + end; + P^.Bal := 0; + FHeightChange := false; +// assert(CheckTree(P)); + end{1} + end{case} + end {greater} else begin + {X already present; do not insert again} + FHeightChange := false; + Result := false; + end; + end; +// assert(CheckTree(P)); +end;{InternalInsert} + +procedure TAvlTree.InternalDelete(X: TKeyType; var P: PNode); +var + Q: PNode; + H: TData; +begin + if P = nil then + FHeightChange := false + else + if X < P^.Data.ID then + begin + InternalDelete(X, P^.Left); + if FHeightChange then BalanceLeft(P, FHeightChange) + end else + if X > P^.Data.ID then + begin + InternalDelete(X, P^.Right); + if FHeightChange then BalanceRight(P, FHeightChange) + end else begin + if P^.Right = nil then + begin Q := P; P := P^.Left; FHeightChange := true end + else if P^.Left = nil then + begin Q := P; P := P^.Right; FHeightChange := true end + else + begin + DelRM(P^.Left, Q, FHeightChange); + H := P^.Data; + P^.Data := Q^.Data; + Q^.Data := H; + if FHeightChange then BalanceLeft(P, FHeightChange) + end; + DeleteNode(Q) + end;{eq} +end;{InternalDelete} + +function TAvlTree.Lowest: PData; +var + H: PNode; +begin + H := FRoot; + if H = nil then + begin + Result := nil; + exit; + end; + + while H^.Left <> nil do + H := H^.Left; + Result := @H^.Data; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_collate.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_collate.pas new file mode 100644 index 0000000..40fa24c --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_collate.pas @@ -0,0 +1,2347 @@ +unit dbf_collate; + +{$i dbf_common.inc} + + +interface + +uses + SysUtils; + + + +type + TCollationTable = array[0..255] of Byte; + PCollationTable = ^TCollationTable; + TCollationBDEName = string[8]; + + TCollationDefinition = record + CollationBDEName :TCollationBDEName; + CollationTable :PCollationTable; + end; + + + +const + BINARY_COLLATION :PCollationTable = PCollationTable($111); + UNKNOWN_COLLATION :PCollationTable = PCollationTable($222); + + + +function GetCollationTable( DbfLangId :integer ) :PCollationTable; +function DbfCompareString( CollationTable :PCollationTable; String1 :PChar; nLength1 :integer; String2 :PChar; nLength2 :integer ) :integer; +function RegisterCollation( DbfLangId :integer; CollationTable :PCollationTable; BDEName :TCollationBDEName ) :Boolean; + + +var + CollationTables :array[0..255] of TCollationDefinition; + + +implementation +uses dbf_lang, math; + + +procedure InitialiseCollationTables; +var + nCnt :integer; +begin + for nCnt := Low(CollationTables) to High(CollationTables) do + begin + CollationTables[nCnt].CollationTable := BINARY_COLLATION; + CollationTables[nCnt].CollationBDEName := ''; + end; +end; + +function GetCollationTable( DbfLangId :integer ) :PCollationTable; +begin + if (DbfLangId < Low(CollationTables)) or (DbfLangId > High(CollationTables)) then + begin + Result := nil; + end + else + begin + Result := CollationTables[DbfLangId].CollationTable; + end; +end; + +function DbfCompareString( CollationTable :PCollationTable; String1 :PChar; nLength1 :integer; String2 :PChar; nLength2 :integer ) :integer; +var + nCnt, nMax, nVal1, nVal2 :integer; +const + ONE_LESS_THAN_TWO = 1; + EQUAL = 2; + TWO_LESS_THAN_ONE = 3; +begin + result := EQUAL; + + if CollationTable = BINARY_COLLATION then + begin + // binary collation + nMax := Min( nLength1, nLength2 ); + for nCnt := 1 to nMax do + begin + if Ord(String1^) < Ord(String2^) then + begin + result := ONE_LESS_THAN_TWO; + break; + end + else if Ord(String1^) > Ord(String2^) then + begin + result := TWO_LESS_THAN_ONE; + break; + end; + + Inc(String1); + Inc(String2); + end; + end + + else + + begin + // collation via collation table + nMax := Min( nLength1, nLength2 ); + for nCnt := 1 to nMax do + begin + nVal1 := CollationTable[Ord(String1^)]; + nVal2 := CollationTable[Ord(String2^)]; + + if nVal1 < nVal2 then + begin + result := ONE_LESS_THAN_TWO; + break; + end + + else if nVal1 > nVal2 then + begin + result := TWO_LESS_THAN_ONE; + break; + end; + + Inc(String1); + Inc(String2); + end; + + end; + + + if result = EQUAL then + begin + // If the two strings are of different lengths, they are compared up to the + // length of the shortest one. If they are equal to that point, then the + // return value will indicate that the longer string is greater. + if nLength1 < nLength2 then + result := ONE_LESS_THAN_TWO + else if nLength1 > nLength2 then + result := TWO_LESS_THAN_ONE; + end; + +end; + + +function RegisterCollation( DbfLangId :integer; CollationTable :PCollationTable; BDEName :TCollationBDEName ) :Boolean; +begin + if (DbfLangId < Low(CollationTables)) or (DbfLangId > High(CollationTables)) then + begin + result := false; + end + else + begin + CollationTables[DbfLangId].CollationTable := CollationTable; + CollationTables[DbfLangId].CollationBDEName := BDEName; + result := true; + end; +end; + + + + +const + + {$IFDEF PARADOX_COLLATIONS} + + // intl 55764 + _intl :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 069, 073, 076, 079, 085, 088, 090, 092, 098, 100, 102, 104, 106, 109, 115, + 119, 121, 123, 125, 128, 133, 137, 139, 141, 144, 146, 149, 150, 151, 152, 153, + 154, 065, 072, 074, 078, 080, 087, 089, 091, 093, 099, 101, 103, 105, 107, 111, + 118, 120, 122, 124, 127, 129, 136, 138, 140, 142, 145, 155, 156, 157, 158, 159, + 035, 035, 035, 165, 035, 035, 035, 035, 035, 035, 125, 035, 115, 035, 035, 035, + 035, 035, 035, 035, 035, 035, 035, 035, 035, 035, 124, 035, 111, 035, 035, 144, + 181, 172, 162, 163, 035, 164, 035, 035, 035, 035, 166, 173, 169, 035, 035, 035, + 178, 176, 180, 035, 035, 175, 035, 179, 035, 035, 167, 174, 171, 170, 035, 168, + 069, 069, 069, 069, 071, 148, 161, 077, 085, 086, 085, 085, 098, 098, 098, 098, + 079, 110, 115, 115, 115, 115, 117, 035, 115, 133, 133, 133, 135, 144, 035, 126, + 067, 066, 068, 065, 070, 147, 160, 075, 083, 082, 084, 081, 096, 095, 097, 094, + 078, 108, 113, 112, 114, 111, 116, 177, 111, 131, 130, 132, 134, 142, 035, 143 + ); + + intl :PCollationTable = @_intl; + + {$ENDIF} + + + + + {$IFDEF PARADOX_COLLATIONS} + + // nordan 1610 + + _nordan :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 069, 071, 074, 077, 083, 086, 088, 090, 096, 098, 100, 102, 104, 107, 113, + 115, 117, 119, 121, 123, 128, 130, 132, 134, 138, 141, 152, 153, 154, 155, 156, + 157, 065, 070, 072, 076, 078, 085, 087, 089, 091, 097, 099, 101, 103, 105, 109, + 114, 116, 118, 120, 122, 124, 129, 131, 133, 135, 140, 158, 159, 160, 161, 162, + 035, 035, 035, 164, 035, 035, 035, 035, 035, 035, 121, 035, 113, 035, 035, 035, + 035, 035, 035, 035, 035, 035, 035, 035, 035, 035, 120, 035, 109, 035, 035, 138, + 181, 171, 035, 163, 173, 035, 035, 035, 035, 035, 165, 172, 168, 035, 035, 035, + 178, 176, 180, 035, 035, 175, 035, 179, 035, 035, 166, 035, 170, 169, 035, 167, + 069, 069, 069, 069, 145, 151, 144, 075, 083, 084, 083, 083, 096, 096, 096, 096, + 077, 108, 113, 113, 113, 113, 149, 035, 148, 128, 128, 128, 139, 138, 035, 174, + 067, 066, 068, 065, 143, 150, 142, 073, 081, 080, 082, 079, 094, 093, 095, 092, + 076, 106, 111, 110, 112, 109, 147, 177, 146, 126, 125, 127, 136, 135, 035, 137 + ); + nordan :PCollationTable = @_nordan; + + {$ENDIF} + + + + + {$IFDEF PARADOX_COLLATIONS} + + // nordan40 31338 + + _nordan40 :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 065, 070, 072, 076, 078, 085, 087, 089, 091, 097, 099, 101, 103, 105, 109, + 114, 116, 118, 120, 122, 124, 129, 131, 133, 135, 140, 152, 153, 154, 155, 156, + 157, 066, 071, 074, 077, 080, 086, 088, 090, 092, 098, 100, 102, 104, 107, 110, + 115, 117, 119, 121, 123, 125, 130, 132, 134, 137, 141, 158, 159, 160, 161, 162, + 035, 035, 035, 164, 035, 035, 035, 035, 035, 035, 120, 035, 109, 035, 035, 035, + 035, 035, 035, 035, 035, 035, 035, 035, 035, 035, 121, 035, 110, 035, 035, 135, + 181, 171, 035, 163, 173, 035, 035, 035, 035, 035, 165, 172, 168, 035, 035, 035, + 178, 176, 180, 035, 035, 175, 035, 179, 035, 035, 166, 035, 170, 169, 035, 167, + 065, 065, 065, 065, 143, 150, 142, 073, 078, 079, 078, 078, 091, 091, 091, 091, + 076, 106, 109, 109, 109, 109, 147, 035, 146, 124, 124, 124, 136, 135, 035, 174, + 068, 067, 069, 066, 145, 151, 144, 075, 083, 082, 084, 081, 095, 094, 096, 093, + 077, 108, 112, 111, 113, 110, 149, 177, 148, 127, 126, 128, 139, 137, 035, 138 + ); + nordan40 :PCollationTable = @_nordan40; + + {$ENDIF} + + + + + {$IFDEF PARADOX_COLLATIONS} + + // swedfin 6461 + + _swedfin :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 069, 071, 074, 077, 083, 086, 088, 090, 096, 098, 100, 102, 104, 107, 113, + 115, 117, 119, 121, 123, 128, 130, 132, 134, 137, 139, 150, 151, 152, 153, 154, + 155, 065, 070, 072, 076, 078, 085, 087, 089, 091, 097, 099, 101, 103, 105, 109, + 114, 116, 118, 120, 122, 124, 129, 131, 133, 135, 138, 156, 157, 158, 159, 160, + 035, 035, 035, 164, 035, 035, 035, 035, 035, 035, 121, 035, 113, 035, 035, 035, + 035, 035, 035, 035, 035, 035, 035, 035, 035, 035, 120, 035, 109, 035, 035, 137, + 181, 171, 161, 162, 035, 163, 035, 035, 035, 035, 165, 172, 168, 035, 035, 035, + 178, 176, 180, 035, 035, 175, 035, 179, 035, 035, 166, 173, 170, 169, 035, 167, + 069, 069, 069, 069, 145, 143, 141, 075, 083, 084, 083, 083, 096, 096, 096, 096, + 077, 108, 113, 113, 113, 113, 147, 035, 113, 128, 128, 128, 149, 137, 035, 174, + 067, 066, 068, 065, 144, 142, 140, 073, 081, 080, 082, 079, 094, 093, 095, 092, + 076, 106, 111, 110, 112, 109, 146, 177, 109, 126, 125, 127, 148, 135, 035, 136 + ); + swedfin :PCollationTable = @_swedfin; + + {$ENDIF} + + + + + // DB865DA0 Checksum: 51597 + + _DB865DA0 :TCollationTable = ( + 000, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, + 001, 118, 130, 124, 125, 110, 123, 132, 099, 100, 111, 108, 113, 109, 112, 119, + 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 115, 114, 105, 107, 106, 117, + 122, 012, 013, 014, 016, 017, 019, 020, 021, 022, 023, 024, 025, 026, 027, 029, + 030, 031, 032, 033, 034, 035, 037, 038, 039, 040, 041, 101, 120, 102, 133, 135, + 131, 047, 051, 052, 054, 055, 060, 061, 062, 063, 068, 069, 070, 071, 072, 074, + 078, 079, 080, 081, 082, 083, 088, 089, 090, 091, 093, 103, 121, 104, 134, 169, + 015, 087, 056, 050, 095, 049, 098, 053, 058, 059, 057, 067, 066, 065, 043, 046, + 018, 094, 042, 077, 097, 076, 086, 085, 092, 045, 036, 096, 126, 044, 128, 127, + 048, 064, 075, 084, 073, 028, 136, 137, 116, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 129, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 + ); + DB865DA0 :PCollationTable = @_DB865DA0; + + DB865NO0 :PCollationTable = @_DB865DA0; + + + + + // DB437NL0 Checksum: 26538 + + _DB437NL0 :TCollationTable = ( + 000, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, + 001, 114, 130, 120, 121, 106, 119, 132, 095, 096, 107, 104, 109, 105, 108, 115, + 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 111, 110, 101, 103, 102, 113, + 118, 012, 015, 016, 018, 019, 021, 022, 023, 024, 025, 026, 027, 028, 029, 031, + 033, 034, 035, 036, 037, 038, 040, 041, 042, 043, 044, 097, 116, 098, 133, 135, + 131, 045, 051, 052, 054, 055, 060, 061, 062, 063, 068, 069, 070, 071, 072, 074, + 079, 080, 081, 082, 083, 084, 089, 090, 091, 092, 094, 099, 117, 100, 134, 169, + 017, 088, 056, 048, 049, 047, 050, 053, 058, 059, 057, 067, 066, 065, 013, 014, + 020, 127, 128, 077, 078, 076, 087, 086, 093, 032, 039, 122, 123, 124, 126, 125, + 046, 064, 075, 085, 073, 030, 136, 137, 112, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 129, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 + ); + DB437NL0 :PCollationTable = @_DB437NL0; + + DB437UK0 :PCollationTable = @_DB437NL0; + + DB437IT0 :PCollationTable = @_DB437NL0; + + DB437FR0 :PCollationTable = @_DB437NL0; + + + + + // DB850NL0 Checksum: 4071 + + _DB850NL0 :TCollationTable = ( + 000, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, + 001, 176, 189, 213, 206, 214, 212, 006, 192, 193, 210, 215, 173, 005, 181, 180, + 007, 011, 013, 015, 017, 018, 019, 020, 021, 022, 175, 174, 219, 220, 221, 178, + 203, 024, 041, 043, 047, 051, 061, 063, 065, 067, 078, 080, 082, 084, 086, 090, + 105, 107, 109, 111, 114, 118, 128, 130, 132, 134, 139, 194, 211, 195, 184, 003, + 183, 023, 040, 042, 046, 050, 060, 062, 064, 066, 077, 079, 081, 083, 085, 089, + 104, 106, 108, 110, 113, 117, 127, 129, 131, 133, 138, 196, 223, 197, 186, 227, + 045, 125, 052, 030, 034, 028, 032, 044, 056, 058, 054, 074, 072, 070, 035, 033, + 053, 038, 039, 096, 098, 094, 123, 121, 137, 099, 126, 102, 208, 103, 218, 207, + 026, 068, 092, 119, 087, 088, 025, 091, 179, 202, 222, 009, 008, 177, 190, 191, + 230, 231, 232, 243, 239, 027, 031, 029, 201, 250, 254, 247, 253, 205, 209, 236, + 240, 241, 235, 237, 244, 238, 036, 037, 251, 245, 252, 246, 248, 255, 249, 204, + 048, 049, 057, 059, 055, 076, 069, 073, 075, 242, 234, 233, 229, 224, 071, 228, + 093, 112, 097, 095, 100, 101, 226, 115, 116, 120, 124, 122, 135, 136, 171, 182, + 004, 216, 172, 010, 200, 199, 217, 188, 225, 185, 187, 012, 016, 014, 198, 002 + ); + DB850NL0 :PCollationTable = @_DB850NL0; + + DB850FR0 :PCollationTable = @_DB850NL0; + + DB850IT1 :PCollationTable = @_DB850NL0; + + DB850ES0 :PCollationTable = @_DB850NL0; + + DB850UK0 :PCollationTable = @_DB850NL0; + + + + + // DB437FI0 Checksum: 33363 + + _DB437FI0 :TCollationTable = ( + 000, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, + 001, 118, 130, 124, 125, 110, 123, 132, 099, 100, 111, 108, 113, 109, 112, 119, + 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 115, 114, 105, 107, 106, 117, + 122, 012, 013, 014, 016, 017, 019, 020, 021, 022, 023, 024, 025, 026, 027, 029, + 030, 031, 032, 033, 034, 035, 037, 038, 039, 040, 041, 101, 120, 102, 133, 135, + 131, 047, 051, 052, 054, 055, 060, 061, 062, 063, 068, 069, 070, 071, 072, 074, + 078, 079, 080, 081, 082, 083, 088, 089, 090, 091, 093, 103, 121, 104, 134, 169, + 015, 087, 056, 050, 095, 049, 094, 053, 058, 059, 057, 067, 066, 065, 043, 042, + 018, 096, 044, 077, 097, 076, 086, 085, 092, 045, 036, 098, 126, 046, 128, 127, + 048, 064, 075, 084, 073, 028, 136, 137, 116, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 129, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 + ); + DB437FI0 :PCollationTable = @_DB437FI0; + + + + + // DB437DE0 Checksum: 51657 + _DB437DE0 :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 048, 049, 050, 051, 052, 053, + 054, 168, 172, 173, 175, 176, 178, 179, 180, 181, 182, 183, 184, 185, 186, 188, + 190, 191, 192, 193, 194, 195, 197, 198, 199, 200, 201, 055, 056, 057, 058, 059, + 060, 202, 210, 211, 213, 214, 219, 220, 221, 222, 227, 228, 229, 230, 231, 233, + 239, 240, 241, 242, 244, 245, 250, 251, 252, 253, 255, 061, 062, 063, 064, 065, + 174, 249, 215, 205, 206, 204, 207, 212, 217, 218, 216, 226, 225, 224, 169, 170, + 177, 208, 171, 236, 237, 235, 248, 247, 254, 189, 196, 066, 067, 068, 069, 070, + 203, 223, 234, 246, 232, 187, 209, 238, 071, 072, 073, 074, 075, 076, 077, 078, + 079, 080, 081, 082, 083, 084, 085, 086, 087, 088, 089, 090, 091, 092, 093, 094, + 095, 096, 097, 098, 099, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, + 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, + 127, 243, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, + 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157 + ); + + DB437DE0 :PCollationTable = @_DB437DE0; + + + + + // DB850DE0 Checksum: 60384 + _DB850DE0 :TCollationTable = ( + 000, 007, 008, 009, 010, 011, 012, 013, 014, 015, 016, 017, 018, 019, 020, 021, + 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, 032, 033, 034, 035, 036, 037, + 001, 043, 056, 080, 073, 081, 079, 006, 059, 060, 077, 082, 040, 005, 048, 047, + 240, 244, 246, 248, 250, 251, 252, 253, 254, 255, 042, 041, 086, 087, 088, 045, + 070, 124, 141, 143, 147, 151, 161, 163, 165, 167, 178, 180, 182, 184, 186, 190, + 205, 207, 209, 211, 214, 218, 228, 230, 232, 234, 239, 061, 078, 062, 051, 003, + 050, 123, 140, 142, 146, 150, 160, 162, 164, 166, 177, 179, 181, 183, 185, 189, + 204, 206, 208, 210, 213, 217, 227, 229, 231, 233, 238, 063, 090, 064, 053, 094, + 145, 225, 152, 130, 134, 128, 132, 144, 156, 158, 154, 174, 172, 170, 135, 133, + 153, 138, 139, 196, 198, 194, 223, 221, 237, 199, 226, 202, 075, 203, 085, 074, + 126, 168, 192, 219, 187, 188, 125, 191, 046, 069, 089, 242, 241, 044, 057, 058, + 097, 098, 099, 110, 106, 127, 131, 129, 068, 117, 121, 114, 120, 072, 076, 103, + 107, 108, 102, 104, 111, 105, 136, 137, 118, 112, 119, 113, 115, 122, 116, 071, + 148, 149, 157, 159, 155, 176, 169, 173, 175, 109, 101, 100, 096, 091, 171, 095, + 193, 212, 197, 195, 200, 201, 093, 215, 216, 220, 224, 222, 235, 236, 038, 049, + 004, 083, 039, 243, 067, 066, 084, 055, 092, 052, 054, 245, 249, 247, 065, 002 + ); + + DB850DE0 :PCollationTable = @_DB850DE0; + + + + + // DB437SV0 Checksum: 5835 + + _DB437SV0 :TCollationTable = ( + 000, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, + 001, 117, 130, 123, 124, 109, 122, 132, 098, 099, 110, 107, 112, 108, 111, 118, + 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 114, 113, 104, 106, 105, 116, + 121, 012, 013, 014, 016, 017, 019, 020, 021, 022, 023, 024, 025, 026, 027, 029, + 030, 031, 032, 033, 034, 035, 037, 038, 039, 040, 041, 100, 119, 101, 133, 135, + 131, 045, 049, 050, 052, 053, 058, 059, 060, 061, 066, 067, 068, 069, 070, 072, + 076, 077, 078, 079, 081, 082, 087, 088, 089, 090, 092, 102, 120, 103, 134, 169, + 015, 086, 054, 048, 094, 047, 093, 051, 056, 057, 055, 065, 064, 063, 043, 042, + 018, 095, 096, 075, 097, 074, 085, 084, 091, 044, 036, 125, 126, 127, 129, 128, + 046, 062, 073, 083, 071, 028, 136, 137, 115, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 080, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 + ); + DB437SV0 :PCollationTable = @_DB437SV0; + + + + + // DB850SV1 Checksum: 15648 + + _DB850SV1 :TCollationTable = ( + 000, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, + 001, 176, 189, 213, 206, 214, 212, 006, 192, 193, 210, 215, 173, 005, 181, 180, + 007, 011, 013, 015, 017, 018, 019, 020, 021, 022, 175, 174, 219, 220, 221, 178, + 203, 024, 035, 037, 041, 045, 055, 057, 059, 061, 072, 074, 076, 078, 080, 084, + 095, 097, 099, 101, 104, 108, 116, 118, 120, 122, 129, 194, 211, 195, 184, 003, + 183, 023, 034, 036, 040, 044, 054, 056, 058, 060, 071, 073, 075, 077, 079, 083, + 094, 096, 098, 100, 103, 107, 115, 117, 119, 121, 128, 196, 223, 197, 186, 227, + 039, 126, 046, 030, 132, 028, 130, 038, 050, 052, 048, 068, 066, 064, 133, 131, + 047, 134, 135, 090, 136, 088, 113, 111, 125, 137, 127, 138, 208, 139, 218, 207, + 026, 062, 086, 109, 081, 082, 025, 085, 179, 202, 222, 009, 008, 177, 190, 191, + 230, 231, 232, 243, 239, 027, 031, 029, 201, 250, 254, 247, 253, 205, 209, 236, + 240, 241, 235, 237, 244, 238, 032, 033, 251, 245, 252, 246, 248, 255, 249, 204, + 042, 043, 051, 053, 049, 070, 063, 067, 069, 242, 234, 233, 229, 224, 065, 228, + 087, 102, 091, 089, 092, 093, 226, 105, 106, 110, 114, 112, 123, 124, 171, 182, + 004, 216, 172, 010, 200, 199, 217, 188, 225, 185, 187, 012, 016, 014, 198, 002 + ); + DB850SV1 :PCollationTable = @_DB850SV1; + + + + + // DB437ES1 Checksum: 29895 + + _DB437ES1 :TCollationTable = ( + 000, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, + 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, + 001, 114, 131, 121, 122, 107, 120, 133, 096, 097, 108, 105, 002, 106, 109, 116, + 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 111, 110, 102, 104, 103, 113, + 119, 013, 016, 017, 019, 020, 022, 023, 024, 025, 026, 027, 028, 029, 030, 032, + 034, 035, 036, 037, 038, 039, 041, 042, 043, 044, 045, 098, 117, 099, 134, 136, + 132, 046, 052, 053, 055, 056, 061, 062, 063, 064, 069, 070, 071, 072, 073, 075, + 080, 081, 082, 083, 084, 085, 090, 091, 092, 093, 095, 100, 118, 101, 135, 170, + 018, 088, 057, 049, 050, 048, 051, 054, 059, 060, 058, 067, 068, 066, 014, 015, + 021, 128, 129, 078, 079, 077, 089, 087, 094, 033, 040, 123, 124, 125, 126, 127, + 047, 065, 076, 086, 074, 031, 137, 138, 112, 171, 172, 173, 174, 115, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 130, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 + ); + DB437ES1 :PCollationTable = @_DB437ES1 ; + + + + + // DB437US0 Checksum: 43413 + + _DB437US0 :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 065, 066, 067, 068, 069, 070, 071, 072, 073, 074, 075, 076, 077, 078, 079, + 080, 081, 082, 083, 084, 085, 086, 087, 088, 089, 090, 091, 092, 093, 094, 095, + 096, 097, 098, 099, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 + ); + DB437US0 :PCollationTable = @_DB437US0; + + + + + // DB863CF1 Checksum: 34446 + + _DB863CF1 :TCollationTable = ( + 000, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, + 146, 147, 148, 149, 150, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, + 001, 110, 123, 116, 117, 103, 115, 125, 092, 093, 104, 101, 106, 102, 105, 111, + 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 108, 107, 098, 100, 099, 109, + 114, 012, 015, 016, 018, 019, 024, 025, 026, 027, 030, 031, 032, 033, 034, 035, + 037, 038, 039, 040, 041, 042, 046, 047, 048, 049, 050, 094, 112, 095, 126, 128, + 124, 051, 054, 055, 057, 058, 063, 064, 065, 066, 069, 070, 071, 072, 073, 074, + 077, 078, 079, 080, 081, 082, 087, 088, 089, 090, 091, 096, 113, 097, 127, 163, + 017, 086, 059, 053, 014, 052, 151, 056, 061, 062, 060, 068, 067, 252, 013, 121, + 020, 021, 022, 076, 023, 029, 085, 084, 254, 036, 045, 118, 119, 043, 044, 120, + 250, 251, 075, 083, 253, 249, 129, 130, 028, 164, 165, 166, 167, 168, 169, 170, + 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, + 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, + 219, 122, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, + 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 255 + ); + DB863CF1 :PCollationTable = @_DB863CF1; + + + + + // DB850CF0 Checksum: 4704 + + _DB850CF0 :TCollationTable = ( + 000, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, + 001, 136, 152, 142, 143, 128, 141, 154, 117, 118, 129, 126, 131, 127, 130, 137, + 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 133, 132, 123, 125, 124, 135, + 140, 012, 019, 020, 022, 023, 028, 029, 030, 031, 036, 037, 038, 039, 040, 042, + 048, 049, 050, 051, 052, 053, 058, 059, 060, 061, 063, 119, 138, 120, 155, 157, + 153, 064, 071, 072, 074, 075, 080, 081, 082, 083, 088, 089, 090, 091, 092, 094, + 100, 101, 102, 103, 104, 105, 110, 111, 112, 113, 116, 121, 139, 122, 156, 191, + 021, 109, 076, 067, 068, 066, 069, 073, 078, 079, 077, 087, 086, 085, 016, 017, + 024, 149, 150, 097, 098, 096, 108, 107, 115, 046, 057, 144, 145, 146, 148, 147, + 065, 084, 095, 106, 093, 041, 158, 159, 134, 192, 193, 194, 195, 196, 197, 198, + 199, 200, 201, 202, 203, 013, 015, 014, 204, 205, 206, 207, 208, 209, 210, 211, + 212, 213, 214, 215, 216, 217, 070, 018, 218, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 026, 027, 025, 228, 032, 034, 035, 229, 230, 231, 232, 233, 033, 234, + 043, 151, 045, 044, 099, 047, 235, 236, 237, 054, 056, 055, 114, 062, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 + ); + DB850CF0 :PCollationTable = @_DB850CF0; + + + + + // DB852CZ0 Checksum: 35661 + + _DB852CZ0 :TCollationTable = ( + 000, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 172, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 001, 149, 151, 192, 174, 173, 169, 152, 159, 160, 191, 187, 146, 154, 145, 157, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 150, 147, 163, 186, 164, 148, + 170, 003, 015, 017, 025, 031, 041, 043, 045, 047, 053, 055, 057, 065, 067, 073, + 083, 085, 087, 094, 102, 108, 118, 120, 122, 124, 128, 161, 158, 162, 188, 155, + 153, 002, 014, 016, 024, 030, 040, 042, 044, 046, 052, 054, 056, 064, 066, 072, + 082, 084, 086, 093, 101, 107, 117, 119, 121, 123, 127, 165, 156, 166, 193, 222, + 021, 113, 032, 006, 010, 111, 018, 020, 062, 036, 081, 080, 050, 132, 011, 019, + 033, 059, 058, 076, 078, 061, 060, 096, 095, 079, 114, 104, 103, 063, 189, 022, + 004, 048, 074, 109, 013, 012, 134, 133, 039, 038, 255, 131, 023, 097, 167, 168, + 216, 217, 218, 194, 195, 005, 007, 035, 098, 205, 206, 207, 208, 130, 129, 196, + 197, 198, 199, 200, 201, 202, 009, 008, 209, 210, 211, 212, 213, 214, 215, 175, + 028, 029, 027, 037, 026, 071, 049, 051, 034, 203, 204, 219, 220, 106, 112, 221, + 075, 092, 077, 069, 068, 070, 100, 099, 089, 110, 088, 116, 125, 126, 105, 177, + 185, 182, 184, 178, 179, 171, 190, 183, 180, 181, 176, 115, 091, 090, 223, 224 + ); + DB852CZ0 :PCollationTable = @_DB852CZ0; + + + + + // DB867CZ0 Checksum: 9099 + + _DB867CZ0 :TCollationTable = ( + 000, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, + 001, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, + 099, 100, 101, 102, 103, 104, 105, 106, 107, 108, 124, 125, 126, 127, 128, 129, + 130, 003, 009, 011, 015, 019, 025, 027, 029, 031, 035, 037, 039, 045, 047, 051, + 059, 061, 063, 070, 074, 078, 086, 088, 090, 092, 096, 131, 132, 133, 134, 135, + 136, 002, 008, 010, 014, 018, 024, 026, 028, 030, 034, 036, 038, 044, 046, 050, + 058, 060, 062, 069, 073, 077, 085, 087, 089, 091, 095, 137, 138, 139, 140, 141, + 013, 083, 020, 016, 006, 017, 076, 012, 022, 023, 041, 033, 042, 040, 007, 005, + 021, 097, 098, 054, 056, 053, 081, 080, 093, 057, 084, 072, 043, 094, 067, 075, + 004, 032, 052, 079, 048, 049, 082, 055, 071, 066, 064, 065, 142, 143, 144, 145, + 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, + 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, + 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, + 194, 068, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224 + ); + DB867CZ0 :PCollationTable = @_DB867CZ0; + + + + + // db852hdc Checksum: 7023 + + _db852hdc :TCollationTable = ( + 000, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, + 001, 162, 172, 168, 169, 155, 167, 174, 144, 145, 156, 153, 158, 154, 157, 163, + 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 160, 159, 150, 152, 151, 161, + 166, 012, 018, 019, 023, 026, 031, 032, 033, 034, 038, 039, 040, 044, 045, 048, + 053, 054, 055, 058, 062, 065, 070, 071, 072, 073, 075, 146, 164, 147, 175, 177, + 173, 079, 085, 086, 090, 093, 098, 099, 100, 101, 104, 105, 106, 109, 110, 113, + 118, 119, 120, 123, 127, 130, 135, 136, 137, 138, 140, 148, 165, 149, 176, 209, + 020, 133, 097, 082, 080, 131, 089, 087, 107, 094, 052, 117, 102, 078, 013, 022, + 030, 043, 036, 114, 116, 042, 108, 061, 126, 051, 068, 064, 129, 041, 170, 088, + 084, 103, 115, 132, 014, 081, 077, 142, 028, 095, 210, 143, 021, 124, 211, 212, + 213, 214, 215, 216, 217, 017, 015, 029, 059, 218, 219, 220, 221, 076, 141, 222, + 223, 224, 225, 226, 227, 228, 016, 083, 229, 230, 231, 232, 233, 234, 235, 236, + 091, 024, 025, 027, 092, 047, 037, 035, 096, 237, 238, 239, 240, 063, 066, 241, + 050, 171, 049, 046, 112, 111, 060, 125, 057, 067, 122, 069, 139, 074, 128, 242, + 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 134, 056, 121, 254, 255 + ); + db852hdc :PCollationTable = @_db852hdc; + + + + + // db852po0 Checksum: 64062 + + _db852po0 :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 194, 203, 200, 201, 187, 199, 205, 176, 177, 188, 185, 190, 186, 189, 195, + 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 192, 191, 182, 184, 183, 193, + 198, 044, 056, 058, 066, 072, 082, 084, 086, 088, 094, 096, 098, 106, 108, 114, + 124, 126, 128, 134, 143, 149, 159, 161, 163, 165, 169, 178, 196, 179, 206, 208, + 204, 043, 055, 057, 065, 071, 081, 083, 085, 087, 093, 095, 097, 105, 107, 113, + 123, 125, 127, 133, 142, 148, 158, 160, 162, 164, 168, 180, 197, 181, 207, 209, + 062, 154, 073, 047, 051, 152, 059, 061, 103, 077, 122, 121, 091, 171, 052, 060, + 074, 100, 099, 117, 119, 102, 101, 139, 138, 120, 155, 145, 144, 104, 202, 063, + 045, 089, 115, 150, 053, 054, 175, 174, 080, 079, 210, 170, 064, 135, 211, 212, + 213, 214, 215, 216, 217, 046, 050, 076, 136, 218, 219, 220, 221, 173, 172, 222, + 223, 224, 225, 226, 227, 228, 049, 048, 229, 230, 231, 232, 233, 234, 235, 236, + 069, 070, 068, 078, 067, 112, 090, 092, 075, 237, 238, 239, 240, 147, 153, 241, + 116, 137, 118, 110, 109, 111, 141, 140, 130, 151, 129, 157, 166, 167, 146, 242, + 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 156, 132, 131, 254, 255 + ); + db852po0 :PCollationTable = @_db852po0; + + + + + // DB860PT0 Checksum: 33927 + + _DB860PT0 :TCollationTable = ( + 000, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, 016, + 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, 032, + 001, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 048, 049, 050, 051, 052, 053, + 054, 168, 178, 180, 184, 186, 194, 196, 198, 200, 206, 208, 210, 212, 214, 218, + 228, 230, 232, 234, 236, 238, 246, 248, 250, 252, 254, 055, 056, 057, 058, 059, + 060, 173, 179, 182, 185, 190, 195, 197, 199, 203, 207, 209, 211, 213, 215, 223, + 229, 231, 233, 235, 237, 242, 247, 249, 251, 253, 255, 061, 062, 063, 064, 065, + 181, 244, 192, 174, 177, 176, 170, 183, 191, 187, 193, 201, 219, 205, 172, 169, + 188, 171, 189, 224, 226, 227, 239, 245, 202, 221, 240, 066, 067, 241, 068, 220, + 175, 204, 225, 243, 217, 216, 069, 070, 071, 222, 072, 073, 074, 075, 076, 077, + 078, 079, 080, 081, 082, 083, 084, 085, 086, 087, 088, 089, 090, 091, 092, 093, + 094, 095, 096, 097, 098, 099, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, + 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, + 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157 + ); + DB860PT0 :PCollationTable = @_DB860PT0; + + + + + // DB850PT0 Checksum: 5850 + + _DB850PT0 :TCollationTable = ( + 000, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, 016, + 017, 018, 019, 020, 021, 023, 025, 026, 027, 028, 029, 030, 031, 032, 033, 034, + 001, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, 048, 049, + 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 050, 051, 052, 053, 054, 055, + 056, 151, 165, 167, 171, 173, 183, 185, 187, 189, 199, 201, 203, 205, 207, 211, + 223, 225, 227, 229, 231, 233, 243, 245, 247, 249, 254, 057, 058, 059, 060, 061, + 062, 158, 166, 169, 172, 178, 184, 186, 188, 194, 200, 202, 204, 206, 208, 217, + 224, 226, 228, 230, 232, 238, 244, 246, 248, 251, 255, 063, 064, 065, 066, 067, + 168, 240, 180, 159, 163, 161, 164, 170, 179, 182, 181, 198, 196, 197, 156, 157, + 176, 068, 069, 218, 222, 221, 242, 241, 253, 216, 235, 070, 071, 072, 073, 074, + 160, 195, 219, 239, 210, 209, 075, 076, 077, 078, 079, 080, 081, 082, 083, 084, + 085, 086, 087, 088, 089, 153, 152, 154, 090, 091, 092, 093, 094, 095, 096, 097, + 098, 099, 100, 101, 102, 103, 162, 155, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 174, 177, 175, 114, 190, 191, 193, 115, 116, 117, 118, 119, 192, 120, + 213, 121, 212, 214, 220, 215, 122, 123, 124, 234, 237, 236, 252, 250, 125, 126, + 127, 128, 129, 130, 022, 024, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140 + ); + DB850PT0 :PCollationTable = @_DB850PT0; + + + + + // db866ru0 Checksum: 43413 + + _db866ru0 :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 065, 066, 067, 068, 069, 070, 071, 072, 073, 074, 075, 076, 077, 078, 079, + 080, 081, 082, 083, 084, 085, 086, 087, 088, 089, 090, 091, 092, 093, 094, 095, + 096, 097, 098, 099, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 + ); + db866ru0 :PCollationTable = @_db866ru0; + + +{$ifdef USE_BORLAND_COLLATION_TABLES} + + // BLLT1DA0 64770 + + _BLLT1DA0 :TCollationTable = ( + 000, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, + 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, + 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, + 002, 006, 008, 010, 012, 013, 014, 015, 016, 017, 020, 020, 020, 020, 020, 020, + 020, 018, 030, 032, 036, 040, 050, 052, 054, 056, 066, 068, 070, 072, 074, 078, + 089, 091, 093, 095, 098, 102, 110, 112, 114, 116, 123, 020, 020, 020, 020, 020, + 020, 019, 031, 033, 037, 041, 051, 053, 055, 057, 067, 069, 071, 073, 075, 079, + 090, 092, 094, 096, 099, 103, 111, 113, 115, 117, 124, 020, 020, 020, 020, 020, + 135, 136, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 137, 138, 139, + 140, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 141, 142, 020, + 001, 020, 020, 020, 020, 020, 020, 020, 020, 020, 021, 020, 020, 020, 020, 020, + 020, 020, 009, 011, 020, 020, 020, 020, 020, 007, 080, 020, 003, 004, 005, 020, + 024, 022, 026, 028, 127, 133, 125, 034, 044, 042, 046, 048, 060, 058, 062, 064, + 038, 076, 083, 081, 085, 087, 131, 020, 129, 106, 104, 108, 121, 118, 100, 097, + 025, 023, 027, 029, 128, 134, 126, 035, 045, 043, 047, 049, 061, 059, 063, 065, + 039, 077, 084, 082, 086, 088, 132, 020, 130, 107, 105, 109, 122, 119, 101, 120 + ); + BLLT1DA0 :PCollationTable = @_BLLT1DA0; + + + + + // BLLT1NL0 30499 + + _BLLT1NL0 :TCollationTable = ( + 000, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, + 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, + 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, + 002, 006, 008, 010, 012, 013, 014, 015, 016, 017, 018, 018, 018, 018, 018, 018, + 018, 020, 037, 039, 043, 047, 057, 059, 061, 063, 073, 075, 077, 079, 081, 085, + 100, 102, 104, 106, 109, 113, 123, 125, 127, 129, 134, 018, 018, 018, 018, 018, + 018, 019, 036, 038, 042, 046, 056, 058, 060, 062, 072, 074, 076, 078, 080, 084, + 099, 101, 103, 105, 108, 112, 122, 124, 126, 128, 133, 018, 018, 018, 018, 018, + 135, 136, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 137, 138, 139, + 140, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 141, 142, 018, + 001, 018, 018, 018, 018, 018, 018, 018, 018, 018, 021, 018, 018, 018, 018, 018, + 018, 018, 009, 011, 018, 018, 018, 018, 018, 007, 086, 018, 003, 004, 005, 018, + 025, 023, 027, 033, 031, 029, 035, 041, 051, 049, 053, 055, 067, 065, 069, 071, + 045, 083, 090, 088, 092, 096, 094, 018, 098, 117, 115, 119, 121, 131, 111, 107, + 024, 022, 026, 032, 030, 028, 034, 040, 050, 048, 052, 054, 066, 064, 068, 070, + 044, 082, 089, 087, 091, 095, 093, 018, 097, 116, 114, 118, 120, 130, 110, 132 + ); + BLLT1NL0 :PCollationTable = @_BLLT1NL0; + + BLLT1CA0 :PCollationTable = @_BLLT1NL0; + + BLLT1IT0 :PCollationTable = @_BLLT1NL0; + + BLLT1ES0 :PCollationTable = @_BLLT1NL0; + + BLLT1UK0 :PCollationTable = @_BLLT1NL0; + + BLLT1PT0 :PCollationTable = @_BLLT1NL0; + + + + + // BLLT1FI0 29479 + + _BLLT1FI0 :TCollationTable = ( + 000, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, + 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, + 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, + 002, 006, 008, 010, 012, 013, 014, 015, 016, 017, 018, 018, 018, 018, 018, 018, + 018, 020, 031, 033, 037, 041, 051, 053, 055, 057, 067, 069, 071, 073, 075, 079, + 090, 092, 094, 096, 099, 103, 111, 113, 115, 117, 124, 018, 018, 018, 018, 018, + 018, 019, 030, 032, 036, 040, 050, 052, 054, 056, 066, 068, 070, 072, 074, 078, + 089, 091, 093, 095, 098, 102, 110, 112, 114, 116, 123, 018, 018, 018, 018, 018, + 135, 136, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 137, 138, 139, + 140, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 141, 142, 018, + 001, 018, 018, 018, 018, 018, 018, 018, 018, 018, 021, 018, 018, 018, 018, 018, + 018, 018, 009, 011, 018, 018, 018, 018, 018, 007, 080, 018, 003, 004, 005, 018, + 025, 023, 027, 029, 128, 126, 130, 035, 045, 043, 047, 049, 061, 059, 063, 065, + 039, 077, 084, 082, 086, 088, 132, 018, 134, 107, 105, 109, 122, 119, 101, 097, + 024, 022, 026, 028, 127, 125, 129, 034, 044, 042, 046, 048, 060, 058, 062, 064, + 038, 076, 083, 081, 085, 087, 131, 018, 133, 106, 104, 108, 121, 118, 100, 120 + ); + BLLT1FI0 :PCollationTable = @_BLLT1FI0; + + BLLT1SV0 :PCollationTable = @_BLLT1FI0; + + + + + // BLLT1FR0 48778 + + _BLLT1FR0 :TCollationTable = ( + 000, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, 032, + 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, 048, + 049, 057, 071, 093, 087, 094, 092, 070, 074, 075, 090, 095, 054, 053, 062, 061, + 002, 006, 008, 010, 012, 013, 014, 015, 016, 017, 056, 055, 099, 100, 101, 059, + 084, 133, 150, 152, 156, 160, 170, 172, 174, 176, 186, 188, 190, 192, 194, 198, + 213, 215, 217, 219, 222, 226, 236, 238, 240, 242, 247, 076, 091, 077, 065, 050, + 064, 132, 149, 151, 155, 159, 169, 171, 173, 175, 185, 187, 189, 191, 193, 197, + 212, 214, 216, 218, 221, 225, 235, 237, 239, 241, 246, 078, 103, 079, 067, 107, + 248, 249, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 250, 251, 252, + 253, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 254, 255, 131, + 001, 058, 086, 088, 085, 089, 104, 080, 066, 082, 134, 072, 102, 052, 083, 051, + 105, 096, 009, 011, 063, 106, 081, 068, 069, 007, 199, 073, 003, 004, 005, 060, + 138, 136, 140, 146, 144, 142, 148, 154, 164, 162, 166, 168, 180, 178, 182, 184, + 158, 196, 203, 201, 205, 209, 207, 098, 211, 230, 228, 232, 234, 244, 224, 220, + 137, 135, 139, 145, 143, 141, 147, 153, 163, 161, 165, 167, 179, 177, 181, 183, + 157, 195, 202, 200, 204, 208, 206, 097, 210, 229, 227, 231, 233, 243, 223, 245 + ); + BLLT1FR0 :PCollationTable = @_BLLT1FR0; + + BLLT1DE0 :PCollationTable = @_BLLT1FR0; + + + + + // BLLT1IS0 64857 + + _BLLT1IS0 :TCollationTable = ( + 000, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, + 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, + 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, + 002, 006, 008, 010, 012, 013, 014, 015, 016, 017, 018, 018, 018, 018, 018, 018, + 018, 020, 035, 037, 041, 045, 055, 057, 059, 061, 071, 073, 075, 077, 079, 083, + 094, 096, 098, 100, 103, 105, 115, 117, 119, 121, 126, 018, 018, 018, 018, 018, + 018, 019, 034, 036, 040, 044, 054, 056, 058, 060, 070, 072, 074, 076, 078, 082, + 093, 095, 097, 099, 102, 104, 114, 116, 118, 120, 125, 018, 018, 018, 018, 018, + 135, 136, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 137, 138, 139, + 140, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 018, 141, 142, 018, + 001, 018, 018, 018, 018, 018, 018, 018, 018, 018, 021, 018, 018, 018, 018, 018, + 018, 018, 009, 011, 018, 018, 018, 018, 018, 007, 084, 018, 003, 004, 005, 018, + 023, 033, 025, 031, 029, 027, 130, 039, 047, 053, 049, 051, 063, 069, 065, 067, + 043, 081, 086, 092, 088, 090, 132, 018, 134, 107, 113, 109, 111, 124, 128, 101, + 022, 032, 024, 030, 028, 026, 129, 038, 046, 052, 048, 050, 062, 068, 064, 066, + 042, 080, 085, 091, 087, 089, 131, 018, 133, 106, 112, 108, 110, 123, 127, 122 + ); + BLLT1IS0 :PCollationTable = @_BLLT1IS0; + + + + + // BLLT1NO0 17250 + + _BLLT1NO0 :TCollationTable = ( + 000, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, + 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, + 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, + 002, 006, 008, 010, 012, 013, 014, 015, 016, 017, 020, 020, 020, 020, 020, 020, + 020, 019, 033, 035, 039, 043, 053, 055, 057, 059, 069, 071, 073, 075, 077, 081, + 094, 096, 098, 100, 103, 107, 117, 119, 121, 123, 128, 020, 020, 020, 020, 020, + 020, 018, 032, 034, 038, 042, 052, 054, 056, 058, 068, 070, 072, 074, 076, 080, + 093, 095, 097, 099, 102, 106, 116, 118, 120, 122, 127, 020, 020, 020, 020, 020, + 135, 136, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 137, 138, 139, + 140, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 020, 141, 142, 020, + 001, 020, 020, 020, 020, 020, 020, 020, 020, 020, 021, 020, 020, 020, 020, 020, + 020, 020, 009, 011, 020, 020, 020, 020, 020, 007, 082, 020, 003, 004, 005, 020, + 025, 023, 027, 031, 029, 134, 130, 037, 047, 045, 049, 051, 063, 061, 065, 067, + 041, 079, 086, 084, 088, 092, 090, 020, 132, 111, 109, 113, 115, 125, 105, 101, + 024, 022, 026, 030, 028, 133, 129, 036, 046, 044, 048, 050, 062, 060, 064, 066, + 040, 078, 085, 083, 087, 091, 089, 020, 131, 110, 108, 112, 114, 124, 104, 126 + ); + BLLT1NO0 :PCollationTable = @_BLLT1NO0; + +{$endif} + + + // DB850US0 Checksum: 43413 + + _DB850US0 :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 065, 066, 067, 068, 069, 070, 071, 072, 073, 074, 075, 076, 077, 078, 079, + 080, 081, 082, 083, 084, 085, 086, 087, 088, 089, 090, 091, 092, 093, 094, 095, + 096, 097, 098, 099, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 + ); + DB850US0 :PCollationTable = @_DB850US0; + + + + +{$ifdef USE_PARADOX_COLLATIONS} + + // intl850 43039 + + _intl850 :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 073, 083, 086, 090, 097, 103, 105, 107, 113, 119, 121, 123, 125, 128, 137, + 146, 148, 150, 152, 155, 162, 169, 171, 173, 177, 180, 181, 182, 183, 184, 185, + 186, 065, 082, 084, 088, 092, 102, 104, 106, 108, 118, 120, 122, 124, 126, 130, + 145, 147, 149, 151, 154, 158, 168, 170, 172, 174, 179, 187, 188, 189, 190, 191, + 035, 035, 035, 194, 035, 035, 035, 035, 035, 035, 152, 035, 137, 035, 035, 035, + 035, 035, 035, 035, 035, 035, 035, 035, 035, 035, 151, 035, 130, 035, 035, 177, + 224, 200, 204, 192, 206, 205, 207, 215, 219, 203, 066, 201, 197, 211, 196, 209, + 218, 212, 223, 222, 210, 208, 214, 220, 217, 221, 131, 202, 199, 198, 213, 195, + 076, 075, 077, 079, 081, 078, 074, 087, 100, 099, 101, 098, 116, 115, 117, 114, + 091, 129, 139, 138, 140, 141, 144, 193, 142, 164, 163, 165, 167, 178, 157, 153, + 069, 068, 070, 072, 080, 071, 067, 085, 095, 094, 096, 093, 111, 110, 112, 109, + 089, 127, 133, 132, 134, 135, 143, 216, 136, 160, 159, 161, 166, 176, 156, 175 + ); + intl850 :PCollationTable = @_intl850; + + + // SPANISH 20109 + + _SPANISH :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, 048, + 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, 064, + 066, 074, 080, 083, 086, 092, 095, 097, 099, 105, 107, 109, 111, 113, 115, 124, + 127, 129, 131, 133, 136, 142, 145, 147, 149, 152, 154, 155, 156, 157, 158, 159, + 160, 067, 079, 081, 085, 087, 094, 096, 098, 100, 106, 108, 110, 112, 114, 118, + 126, 128, 130, 132, 135, 137, 144, 146, 148, 150, 153, 161, 162, 163, 164, 165, + 036, 036, 036, 169, 036, 036, 036, 036, 036, 036, 133, 036, 124, 036, 036, 036, + 036, 036, 036, 036, 036, 036, 036, 036, 036, 036, 132, 036, 118, 036, 036, 152, + 181, 034, 166, 167, 036, 168, 036, 036, 036, 036, 068, 173, 170, 036, 036, 036, + 178, 176, 180, 036, 036, 175, 036, 179, 036, 036, 119, 174, 172, 171, 036, 065, + 074, 074, 074, 074, 075, 076, 078, 084, 092, 093, 092, 092, 105, 105, 105, 105, + 086, 117, 124, 124, 124, 124, 125, 036, 124, 142, 142, 142, 143, 152, 036, 134, + 070, 069, 071, 067, 072, 073, 077, 082, 089, 088, 090, 091, 102, 101, 103, 104, + 085, 116, 121, 120, 122, 118, 123, 177, 118, 139, 138, 140, 141, 150, 036, 151 + ); + SPANISH :PCollationTable = @_SPANISH; + + + + + + + // iceland 23936 + + _iceland :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 070, 076, 079, 082, 089, 093, 095, 097, 099, 103, 105, 107, 109, 111, 114, + 118, 120, 122, 124, 126, 130, 135, 137, 139, 141, 145, 154, 155, 156, 157, 158, + 159, 065, 075, 077, 081, 085, 092, 094, 096, 098, 102, 104, 106, 108, 110, 112, + 117, 119, 121, 123, 125, 127, 134, 136, 138, 140, 144, 160, 161, 162, 163, 035, + 035, 035, 035, 165, 035, 035, 035, 035, 035, 035, 124, 035, 114, 035, 035, 035, + 035, 035, 035, 035, 035, 035, 035, 035, 035, 035, 123, 035, 112, 035, 035, 141, + 180, 170, 035, 164, 035, 035, 035, 035, 035, 035, 035, 171, 167, 035, 035, 035, + 177, 175, 179, 035, 035, 174, 035, 178, 035, 035, 035, 172, 169, 168, 035, 166, + 070, 074, 070, 070, 072, 071, 149, 080, 089, 091, 089, 089, 099, 101, 099, 099, + 084, 111, 114, 116, 114, 114, 152, 035, 153, 130, 133, 130, 131, 143, 147, 173, + 066, 073, 067, 065, 069, 068, 148, 078, 086, 090, 087, 088, 098, 100, 098, 098, + 083, 110, 112, 115, 113, 112, 150, 176, 151, 127, 132, 128, 129, 142, 146, 140 + ); + iceland :PCollationTable = @_iceland; + + + + + + + // ANSIINTL 58462 + + _ANSIINTL :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 070, 078, 081, 085, 092, 098, 100, 102, 108, 114, 116, 118, 120, 123, 131, + 140, 142, 144, 146, 149, 156, 163, 165, 167, 171, 174, 177, 178, 179, 180, 181, + 182, 065, 077, 079, 083, 087, 097, 099, 101, 103, 113, 115, 117, 119, 121, 125, + 139, 141, 143, 145, 148, 152, 162, 164, 166, 168, 173, 183, 184, 185, 186, 187, + 248, 249, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 250, 251, 252, + 253, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 254, 255, 213, + 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, + 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, + 072, 071, 073, 074, 076, 176, 189, 082, 095, 094, 096, 093, 111, 110, 112, 109, + 086, 124, 133, 132, 134, 135, 138, 246, 136, 158, 157, 159, 161, 172, 151, 147, + 067, 066, 068, 069, 075, 175, 188, 080, 090, 089, 091, 088, 106, 105, 107, 104, + 084, 122, 127, 126, 128, 129, 137, 247, 130, 154, 153, 155, 160, 170, 150, 169 + ); + ANSIINTL :PCollationTable = @_ANSIINTL; + + + + + + + // ANSII850 29000 + + _ANSII850 :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 073, 083, 086, 090, 097, 103, 105, 107, 113, 119, 121, 123, 125, 128, 137, + 146, 148, 150, 152, 155, 162, 169, 171, 173, 177, 180, 181, 182, 183, 184, 185, + 186, 065, 082, 084, 088, 092, 102, 104, 106, 108, 118, 120, 122, 124, 126, 130, + 145, 147, 149, 151, 154, 158, 168, 170, 172, 174, 179, 187, 188, 189, 190, 191, + 248, 249, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 250, 251, 252, + 253, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 254, 255, 215, + 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 066, 226, 227, 228, 229, 230, + 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 131, 241, 242, 243, 244, 245, + 076, 075, 077, 079, 081, 078, 074, 087, 100, 099, 101, 098, 116, 115, 117, 114, + 091, 129, 139, 138, 140, 141, 144, 246, 142, 164, 163, 165, 167, 178, 157, 153, + 069, 068, 070, 072, 080, 071, 067, 085, 095, 094, 096, 093, 111, 110, 112, 109, + 089, 127, 133, 132, 134, 135, 143, 247, 136, 160, 159, 161, 166, 176, 156, 175 + ); + ANSII850 :PCollationTable = @_ANSII850; + + + + + + + // ANSISPAN 33308 + + _ANSISPAN :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, 048, + 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, 064, + 066, 075, 085, 088, 092, 099, 105, 107, 109, 115, 121, 123, 125, 127, 129, 140, + 148, 150, 152, 154, 158, 165, 171, 173, 175, 179, 182, 183, 184, 185, 186, 187, + 188, 067, 084, 086, 090, 094, 104, 106, 108, 110, 120, 122, 124, 126, 128, 132, + 147, 149, 151, 153, 156, 160, 170, 172, 174, 176, 181, 189, 190, 191, 192, 193, + 248, 249, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 250, 251, 252, + 253, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 254, 255, 217, + 218, 034, 219, 220, 221, 222, 223, 224, 225, 226, 069, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 133, 242, 243, 244, 245, 065, + 077, 076, 078, 079, 080, 081, 083, 089, 102, 101, 103, 100, 118, 117, 119, 116, + 093, 131, 142, 141, 143, 145, 144, 246, 146, 167, 166, 168, 169, 180, 159, 155, + 070, 068, 071, 072, 073, 074, 082, 087, 096, 095, 097, 098, 112, 111, 113, 114, + 091, 130, 135, 134, 136, 138, 137, 247, 139, 162, 161, 163, 164, 177, 157, 178 + ); + ANSISPAN :PCollationTable = @_ANSISPAN; + + + + + + + // ANSISWFN 44782 + + _ANSISWFN :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 070, 076, 079, 083, 090, 096, 098, 100, 106, 112, 114, 116, 118, 121, 128, + 134, 136, 138, 140, 142, 149, 154, 156, 158, 162, 165, 178, 179, 180, 181, 182, + 183, 065, 075, 077, 081, 085, 095, 097, 099, 101, 111, 113, 115, 117, 119, 123, + 133, 135, 137, 139, 141, 145, 153, 155, 157, 159, 164, 184, 185, 186, 187, 188, + 248, 249, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 250, 251, 252, + 253, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 254, 255, 212, + 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, + 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 072, 071, 073, 074, 173, 171, 167, 080, 093, 092, 094, 091, 109, 108, 110, 107, + 084, 122, 130, 129, 131, 132, 175, 245, 169, 151, 150, 152, 177, 163, 144, 246, + 067, 066, 068, 069, 172, 170, 166, 078, 088, 087, 089, 086, 104, 103, 105, 102, + 082, 120, 125, 124, 126, 127, 174, 247, 168, 147, 146, 148, 176, 160, 143, 161 + ); + ANSISWFN :PCollationTable = @_ANSISWFN; + + + + + + + // ANSINOR4 55290 + + _ANSINOR4 :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 065, 075, 077, 081, 085, 095, 097, 099, 101, 111, 113, 115, 117, 119, 123, + 133, 135, 137, 139, 141, 145, 153, 155, 157, 159, 166, 178, 179, 180, 181, 182, + 183, 070, 076, 079, 083, 090, 096, 098, 100, 106, 112, 114, 116, 118, 121, 128, + 134, 136, 138, 140, 142, 149, 154, 156, 158, 162, 167, 184, 185, 186, 187, 188, + 248, 249, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 250, 251, 252, + 253, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 254, 255, 212, + 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, + 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 067, 066, 068, 069, 169, 176, 168, 078, 088, 087, 089, 086, 104, 103, 105, 102, + 082, 120, 125, 124, 126, 127, 173, 245, 172, 147, 146, 148, 161, 160, 143, 246, + 072, 071, 073, 074, 171, 177, 170, 080, 093, 092, 094, 091, 109, 108, 110, 107, + 084, 122, 130, 129, 131, 132, 175, 247, 174, 151, 150, 152, 165, 164, 144, 163 + ); + ANSINOR4 :PCollationTable = @_ANSINOR4; + +{$endif} + + + + + // china 54324 + + _china :TCollationTable = ( + 000, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, + 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, + 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 065, 066, 067, 068, 069, 070, 071, 072, 073, 074, 075, 076, 077, 078, 079, + 080, 081, 082, 083, 084, 085, 086, 087, 088, 089, 090, 091, 092, 093, 094, 095, + 096, 097, 098, 099, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127 + ); + + DB936CN0 :PCollationTable = @_china; + + DB949KO0 :PCollationTable = @_china; + + DB950TW0 :PCollationTable = @_china; + + + + + // thai Checksum: 9864 + + _thai :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 065, 066, 067, 068, 069, 070, 071, 072, 073, 074, 075, 076, 077, 078, 079, + 080, 081, 082, 083, 084, 085, 086, 087, 088, 089, 090, 091, 092, 093, 094, 095, + 096, 097, 098, 099, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, + 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, + 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 191, + 192, 183, 193, 184, 185, 186, 187, 188, 189, 190, 175, 243, 244, 245, 246, 194, + 247, 248, 249, 250, 251, 195, 196, 176, 177, 178, 179, 180, 181, 182, 197, 198, + 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 252, 253, 254, 255 + ); + +{$ifdef USE_PARADOX_COLLATIONS} + china :PCollationTable = @_china; + + korea :PCollationTable = @_china; + + taiwan :PCollationTable = @_china; + + thai :PCollationTable = @_thai; +{$endif} + + db874th0 :PCollationTable = @_thai; + + + + + // DB932JP1 Checksum: 8911 + + _DB932JP1 :TCollationTable = ( + 000, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 065, 075, 118, 135, 133, 134, 136, 117, 119, 120, 137, 127, 069, 128, 070, 114, + 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 072, 073, 130, 129, 131, 074, + 138, 149, 151, 153, 155, 157, 159, 161, 163, 165, 167, 169, 171, 173, 175, 177, + 179, 181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 121, 132, 122, 078, 111, + 112, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, + 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 123, 116, 124, 115, 110, + 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, 016, + 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, 032, + 066, 068, 125, 126, 067, 071, 254, 201, 203, 205, 207, 209, 242, 244, 246, 223, + 113, 202, 204, 206, 208, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, + 221, 222, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, + 238, 239, 240, 241, 243, 245, 247, 248, 249, 250, 251, 252, 253, 255, 076, 077, + 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, 048, + 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, 064 + ); + DB932JP1 :PCollationTable = @_DB932JP1; + + + + + // DBWINWE0 5562 + + _DBWINWE0 :TCollationTable = ( + 000, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, 016, + 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, 032, + 001, 041, 055, 077, 071, 078, 076, 054, 058, 059, 074, 079, 038, 037, 046, 045, + 111, 115, 117, 119, 121, 122, 123, 124, 125, 126, 040, 039, 083, 084, 085, 043, + 068, 128, 145, 147, 151, 155, 165, 167, 169, 171, 181, 183, 185, 187, 189, 193, + 210, 212, 214, 216, 221, 225, 235, 237, 239, 241, 247, 060, 075, 061, 049, 034, + 048, 127, 144, 146, 150, 154, 164, 166, 168, 170, 180, 182, 184, 186, 188, 192, + 209, 211, 213, 215, 220, 224, 234, 236, 238, 240, 246, 062, 087, 063, 051, 091, + 248, 249, 092, 093, 094, 095, 096, 097, 098, 099, 218, 100, 208, 250, 251, 252, + 253, 101, 102, 103, 104, 105, 106, 107, 108, 109, 217, 110, 207, 254, 255, 245, + 033, 042, 070, 072, 069, 073, 088, 064, 050, 066, 129, 056, 086, 036, 067, 035, + 089, 080, 118, 120, 047, 090, 065, 052, 053, 116, 194, 057, 112, 113, 114, 044, + 133, 131, 135, 141, 139, 137, 143, 149, 159, 157, 161, 163, 175, 173, 177, 179, + 153, 191, 198, 196, 200, 204, 202, 082, 206, 229, 227, 231, 233, 243, 223, 219, + 132, 130, 134, 140, 138, 136, 142, 148, 158, 156, 160, 162, 174, 172, 176, 178, + 152, 190, 197, 195, 199, 203, 201, 081, 205, 228, 226, 230, 232, 242, 222, 244 + ); + DBWINWE0 :PCollationTable = @_DBWINWE0; + + DBWINES0 :PCollationTable = @_DBWINWE0; + + +{$ifdef USE_ACCESS_COLLATIONS} + + // ACCGEN 19621 + + _ACCGEN :TCollationTable = ( + 000, 001, 001, 001, 001, 001, 001, 001, 001, 002, 001, 001, 001, 001, 001, 001, + 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, + 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, 016, 017, 018, + 072, 073, 074, 075, 076, 077, 078, 079, 080, 081, 019, 020, 021, 022, 023, 024, + 025, 082, 090, 091, 093, 095, 100, 101, 102, 103, 108, 109, 110, 111, 112, 114, + 121, 122, 123, 124, 127, 128, 133, 134, 135, 136, 139, 026, 027, 028, 029, 030, + 031, 082, 090, 091, 093, 095, 100, 101, 102, 103, 108, 109, 110, 111, 112, 114, + 121, 122, 123, 124, 127, 128, 133, 134, 135, 136, 139, 032, 033, 034, 035, 001, + 142, 143, 010, 036, 005, 037, 038, 039, 040, 041, 125, 010, 120, 144, 145, 146, + 147, 010, 010, 005, 005, 042, 016, 016, 043, 044, 125, 010, 120, 148, 149, 138, + 003, 045, 046, 047, 048, 049, 050, 051, 052, 053, 054, 005, 055, 016, 056, 057, + 058, 059, 074, 075, 060, 061, 062, 063, 064, 073, 065, 005, 066, 067, 068, 069, + 083, 084, 085, 087, 086, 088, 089, 092, 096, 097, 098, 099, 104, 105, 106, 107, + 094, 113, 115, 116, 117, 119, 118, 070, 141, 129, 130, 131, 132, 137, 140, 126, + 083, 084, 085, 087, 086, 088, 089, 092, 096, 097, 098, 099, 104, 105, 106, 107, + 094, 113, 115, 116, 117, 119, 118, 071, 141, 129, 130, 131, 132, 137, 140, 138 + ); + ACCGEN :PCollationTable = @_ACCGEN; + + + + + // ACCNRDAN 24816 + + _ACCNRDAN :TCollationTable = ( + 000, 001, 001, 001, 001, 001, 001, 001, 001, 002, 001, 001, 001, 001, 001, 001, + 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, + 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, 016, 017, 018, + 072, 073, 074, 075, 076, 077, 078, 079, 080, 081, 019, 020, 021, 022, 023, 024, + 025, 140, 086, 087, 089, 091, 096, 097, 098, 099, 104, 105, 106, 107, 108, 110, + 116, 117, 118, 119, 122, 124, 128, 129, 130, 131, 135, 026, 027, 028, 029, 030, + 031, 140, 086, 087, 089, 091, 096, 097, 098, 099, 104, 105, 106, 107, 108, 110, + 116, 117, 118, 119, 122, 124, 128, 129, 130, 131, 135, 032, 033, 034, 035, 001, + 142, 143, 010, 036, 005, 037, 038, 039, 040, 041, 120, 010, 115, 144, 145, 146, + 147, 010, 010, 005, 005, 042, 016, 016, 043, 044, 120, 010, 115, 148, 149, 133, + 003, 045, 046, 047, 048, 049, 050, 051, 052, 053, 054, 005, 055, 016, 056, 057, + 058, 059, 074, 075, 060, 061, 062, 063, 064, 073, 065, 005, 066, 067, 068, 069, + 083, 082, 084, 085, 137, 141, 136, 088, 093, 092, 094, 095, 101, 100, 102, 103, + 090, 109, 112, 111, 113, 114, 139, 070, 138, 126, 125, 127, 134, 132, 123, 121, + 083, 082, 084, 085, 137, 141, 136, 088, 093, 092, 094, 095, 101, 100, 102, 103, + 090, 109, 112, 111, 113, 114, 139, 071, 138, 126, 125, 127, 134, 132, 123, 133 + ); + ACCNRDAN :PCollationTable = @_ACCNRDAN; + + + + + // ACCSWFIN 39386 + + _ACCSWFIN :TCollationTable = ( + 000, 001, 001, 001, 001, 001, 001, 001, 001, 002, 001, 001, 001, 001, 001, 001, + 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, + 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, 016, 017, 018, + 072, 073, 074, 075, 076, 077, 078, 079, 080, 081, 019, 020, 021, 022, 023, 024, + 025, 082, 088, 089, 091, 093, 098, 099, 100, 101, 106, 107, 108, 109, 110, 112, + 118, 119, 120, 121, 124, 126, 130, 131, 132, 133, 137, 026, 027, 028, 029, 030, + 031, 082, 088, 089, 091, 093, 098, 099, 100, 101, 106, 107, 108, 109, 110, 112, + 118, 119, 120, 121, 124, 126, 130, 131, 132, 133, 137, 032, 033, 034, 035, 001, + 142, 143, 010, 036, 005, 037, 038, 039, 040, 041, 122, 010, 117, 144, 145, 146, + 147, 010, 010, 005, 005, 042, 016, 016, 043, 044, 122, 010, 117, 148, 149, 135, + 003, 045, 046, 047, 048, 049, 050, 051, 052, 053, 054, 005, 055, 016, 056, 057, + 058, 059, 074, 075, 060, 061, 062, 063, 064, 073, 065, 005, 066, 067, 068, 069, + 084, 083, 085, 086, 139, 138, 087, 090, 095, 094, 096, 097, 103, 102, 104, 105, + 092, 111, 114, 113, 115, 116, 140, 070, 141, 128, 127, 129, 136, 134, 125, 123, + 084, 083, 085, 086, 139, 138, 087, 090, 095, 094, 096, 097, 103, 102, 104, 105, + 092, 111, 114, 113, 115, 116, 140, 071, 141, 128, 127, 129, 136, 134, 125, 135 + ); + ACCSWFIN :PCollationTable = @_ACCSWFIN; + +{$endif} + + + // FOXDE437 Checksum: 21075 + + _FOXDE437 :TCollationTable = ( + 000, 125, 125, 125, 125, 125, 125, 125, 125, 127, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 143, 144, 145, 146, 147, 148, + 149, 171, 182, 184, 188, 190, 197, 199, 201, 203, 209, 211, 213, 215, 217, 221, + 226, 228, 230, 232, 237, 239, 246, 248, 250, 252, 255, 150, 151, 152, 153, 154, + 155, 171, 182, 184, 188, 190, 197, 199, 201, 203, 209, 211, 213, 215, 217, 221, + 226, 228, 230, 232, 237, 239, 246, 248, 250, 252, 255, 156, 157, 158, 159, 125, + 186, 244, 192, 174, 180, 173, 176, 186, 194, 195, 193, 207, 206, 205, 180, 176, + 192, 180, 180, 224, 235, 223, 242, 241, 253, 235, 244, 125, 125, 125, 125, 125, + 172, 204, 222, 240, 219, 219, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 235, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125 + ); + FOXDE437 :PCollationTable = @_FOXDE437; + + + + + // FOXNO437 Checksum: 473 + + _FOXNO437 :TCollationTable = ( + 000, 125, 125, 125, 125, 125, 125, 125, 125, 127, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 143, 144, 145, 146, 147, 148, + 149, 171, 176, 178, 182, 184, 191, 193, 195, 197, 203, 205, 207, 209, 211, 215, + 220, 222, 224, 226, 229, 231, 236, 238, 240, 242, 247, 150, 151, 152, 153, 154, + 155, 171, 176, 178, 182, 184, 191, 193, 195, 197, 203, 205, 207, 209, 211, 215, + 220, 222, 224, 226, 229, 231, 236, 238, 240, 242, 247, 156, 157, 158, 159, 125, + 180, 245, 187, 174, 251, 172, 255, 180, 188, 189, 185, 201, 200, 198, 251, 255, + 187, 249, 249, 218, 253, 216, 234, 232, 245, 253, 245, 125, 125, 125, 125, 125, + 173, 199, 217, 233, 213, 213, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 227, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125 + ); + FOXNO437 :PCollationTable = @_FOXNO437 ; + + + + + // FOXNO850 Checksum: 62 + + _FOXNO850 :TCollationTable = ( + 000, 096, 096, 096, 096, 096, 096, 096, 096, 098, 096, 096, 096, 096, 096, 096, + 096, 096, 096, 096, 096, 096, 096, 096, 096, 096, 096, 096, 096, 096, 096, 096, + 098, 099, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 114, 115, 116, 117, 118, 119, + 120, 143, 153, 155, 159, 163, 173, 175, 177, 179, 189, 191, 193, 195, 197, 201, + 211, 213, 215, 217, 220, 222, 230, 232, 234, 236, 243, 121, 122, 123, 124, 125, + 126, 143, 153, 155, 159, 163, 173, 175, 177, 179, 189, 191, 193, 195, 197, 201, + 211, 213, 215, 217, 220, 222, 230, 232, 234, 236, 243, 127, 128, 129, 130, 096, + 157, 241, 167, 149, 249, 145, 255, 157, 169, 171, 165, 187, 185, 181, 249, 255, + 167, 247, 247, 207, 253, 203, 228, 224, 241, 253, 241, 251, 096, 251, 096, 096, + 147, 183, 205, 226, 199, 199, 096, 096, 096, 096, 096, 096, 096, 096, 096, 096, + 096, 096, 096, 096, 096, 147, 149, 145, 131, 096, 096, 096, 096, 096, 096, 096, + 096, 096, 096, 096, 096, 096, 151, 151, 096, 096, 096, 096, 096, 096, 096, 096, + 161, 161, 169, 171, 165, 096, 183, 185, 187, 096, 096, 096, 096, 096, 181, 096, + 205, 218, 207, 203, 209, 209, 096, 245, 245, 226, 228, 224, 238, 238, 096, 096, + 096, 096, 096, 096, 096, 096, 096, 096, 096, 096, 096, 096, 096, 096, 096, 096 + ); + FOXNO850 :PCollationTable = @_FOXNO850; + + + + + // FOXDEWIN 44890 + + _FOXDEWIN :TCollationTable = ( + 000, 001, 001, 001, 001, 001, 001, 001, 001, 002, 001, 001, 001, 001, 001, 001, + 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, + 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, 016, 017, + 072, 073, 074, 075, 076, 077, 078, 079, 080, 081, 019, 020, 021, 022, 023, 024, + 025, 082, 089, 090, 092, 094, 099, 100, 101, 102, 107, 108, 109, 110, 111, 113, + 119, 120, 121, 122, 125, 127, 132, 133, 134, 135, 138, 026, 027, 028, 029, 030, + 031, 082, 089, 090, 092, 094, 099, 100, 101, 102, 107, 108, 109, 110, 111, 113, + 119, 120, 121, 122, 125, 127, 132, 133, 134, 135, 138, 032, 033, 034, 035, 001, + 140, 141, 009, 036, 004, 037, 038, 039, 040, 041, 123, 009, 118, 142, 143, 144, + 145, 009, 009, 004, 004, 042, 015, 015, 043, 044, 123, 009, 118, 146, 147, 137, + 018, 045, 046, 047, 048, 049, 050, 051, 052, 053, 054, 004, 055, 015, 056, 057, + 058, 059, 074, 075, 060, 061, 062, 063, 064, 073, 065, 004, 066, 067, 068, 069, + 084, 083, 085, 086, 088, 087, 088, 091, 096, 095, 097, 098, 104, 103, 105, 106, + 093, 112, 115, 114, 116, 117, 118, 070, 139, 129, 128, 130, 131, 136, 126, 124, + 084, 083, 085, 086, 088, 087, 088, 091, 096, 095, 097, 098, 104, 103, 105, 106, + 093, 112, 115, 114, 116, 117, 118, 071, 139, 129, 128, 130, 131, 136, 126, 137 + ); + FOXDEWIN :PCollationTable = @_FOXDEWIN; + + + + + // FOXNOWIN Checksum: 58863 + + _FOXNOWIN :TCollationTable = ( + 000, 031, 031, 031, 031, 031, 031, 031, 031, 033, 031, 031, 031, 031, 031, 031, + 031, 031, 031, 031, 031, 031, 031, 031, 031, 031, 031, 031, 031, 031, 031, 031, + 033, 035, 041, 042, 043, 044, 045, 051, 052, 053, 054, 055, 056, 060, 061, 062, + 116, 118, 120, 122, 123, 124, 125, 126, 127, 128, 063, 064, 065, 066, 067, 068, + 069, 130, 140, 142, 146, 150, 160, 162, 164, 166, 176, 178, 180, 182, 184, 188, + 200, 202, 204, 206, 211, 213, 223, 225, 227, 229, 235, 070, 071, 072, 073, 074, + 075, 130, 140, 142, 146, 150, 160, 162, 164, 166, 176, 178, 180, 182, 184, 188, + 200, 202, 204, 206, 211, 213, 223, 225, 227, 229, 235, 076, 077, 078, 079, 031, + 248, 249, 051, 080, 041, 081, 082, 083, 084, 085, 208, 051, 198, 250, 251, 252, + 253, 051, 051, 041, 041, 086, 060, 060, 087, 088, 208, 051, 198, 254, 255, 233, + 034, 089, 090, 091, 092, 093, 094, 095, 096, 097, 098, 041, 099, 060, 100, 101, + 102, 103, 120, 122, 104, 105, 106, 107, 108, 118, 109, 041, 110, 111, 112, 113, + 134, 132, 136, 138, 241, 247, 239, 144, 154, 152, 156, 158, 170, 168, 172, 174, + 148, 186, 192, 190, 194, 196, 245, 114, 243, 217, 215, 219, 221, 231, 237, 209, + 134, 132, 136, 138, 241, 247, 239, 144, 154, 152, 156, 158, 170, 168, 172, 174, + 148, 186, 192, 190, 194, 196, 245, 115, 243, 217, 215, 219, 221, 231, 237, 233 + ); + FOXNOWIN :PCollationTable = @_FOXNOWIN; + + + + +{$ifdef USE_PARADOX_COLLATIONS} + + // czech 30844 + + _czech :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 066, 074, 076, 080, 082, 088, 090, 092, 094, 100, 102, 104, 106, 108, 110, + 118, 120, 122, 124, 129, 131, 137, 139, 141, 143, 147, 148, 149, 150, 151, 152, + 153, 065, 073, 075, 079, 081, 087, 089, 091, 093, 099, 101, 103, 105, 107, 109, + 117, 119, 121, 123, 128, 130, 136, 138, 140, 142, 146, 154, 155, 156, 157, 035, + 035, 035, 035, 087, 035, 035, 035, 035, 035, 035, 127, 035, 110, 035, 035, 035, + 035, 035, 035, 035, 035, 035, 035, 035, 035, 035, 126, 035, 109, 035, 035, 143, + 170, 035, 035, 035, 162, 035, 035, 165, 169, 035, 035, 160, 159, 164, 035, 035, + 168, 035, 035, 035, 163, 035, 035, 035, 167, 035, 035, 161, 035, 035, 035, 035, + 066, 068, 070, 066, 072, 066, 066, 078, 082, 084, 082, 086, 094, 096, 098, 094, + 080, 108, 110, 112, 114, 110, 116, 158, 110, 131, 133, 131, 135, 145, 035, 125, + 065, 067, 069, 065, 071, 065, 065, 077, 081, 083, 081, 085, 093, 095, 097, 093, + 079, 107, 109, 111, 113, 109, 115, 166, 109, 130, 132, 130, 134, 144, 035, 142 + ); + czech :PCollationTable = @_czech; + + + + + // czechw 30844 + + czechw :PCollationTable = @_czech; + + + + + + // il2czw 13611 + + _il2czw :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 066, 074, 076, 080, 082, 088, 090, 092, 094, 100, 102, 104, 106, 108, 110, + 118, 120, 122, 124, 129, 131, 137, 139, 141, 143, 147, 148, 149, 150, 151, 152, + 153, 065, 073, 075, 079, 081, 087, 089, 091, 093, 099, 101, 103, 105, 107, 109, + 117, 119, 121, 123, 128, 130, 136, 138, 140, 142, 146, 154, 155, 156, 157, 035, + 035, 035, 035, 087, 035, 035, 035, 035, 035, 035, 127, 035, 110, 035, 035, 035, + 035, 035, 035, 035, 035, 035, 035, 035, 035, 035, 126, 035, 109, 035, 035, 143, + 158, 035, 035, 035, 159, 035, 035, 160, 161, 035, 035, 035, 035, 162, 035, 035, + 163, 035, 035, 035, 164, 035, 035, 035, 165, 035, 035, 035, 035, 035, 035, 035, + 066, 068, 070, 066, 072, 066, 066, 078, 082, 084, 082, 086, 094, 096, 098, 094, + 080, 108, 110, 112, 114, 110, 116, 166, 110, 131, 133, 131, 135, 145, 035, 125, + 065, 067, 069, 065, 071, 065, 065, 077, 081, 083, 081, 085, 093, 095, 097, 093, + 079, 107, 109, 111, 113, 109, 115, 167, 109, 130, 132, 130, 134, 144, 035, 142 + ); + il2czw :PCollationTable = @_il2czw; + + + + + + // polish 59020 + + _polish :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 066, 074, 076, 080, 082, 088, 090, 092, 094, 100, 102, 104, 106, 108, 110, + 118, 120, 122, 124, 129, 131, 137, 139, 141, 143, 147, 148, 149, 150, 151, 152, + 153, 065, 073, 075, 079, 081, 087, 089, 091, 093, 099, 101, 103, 105, 107, 109, + 117, 119, 121, 123, 128, 130, 136, 138, 140, 142, 146, 154, 155, 156, 157, 035, + 035, 035, 035, 087, 035, 035, 035, 035, 035, 035, 126, 035, 110, 035, 035, 035, + 035, 035, 035, 035, 035, 035, 035, 035, 035, 035, 125, 035, 109, 035, 035, 143, + 170, 035, 035, 035, 162, 035, 035, 165, 169, 035, 035, 160, 159, 164, 035, 035, + 168, 035, 035, 035, 163, 035, 035, 035, 167, 035, 035, 161, 035, 035, 035, 035, + 066, 068, 070, 066, 072, 066, 066, 078, 082, 084, 082, 086, 094, 096, 098, 094, + 080, 108, 110, 112, 114, 110, 116, 158, 110, 131, 133, 131, 135, 145, 035, 127, + 065, 067, 069, 065, 071, 065, 065, 077, 081, 083, 081, 085, 093, 095, 097, 093, + 079, 107, 109, 111, 113, 109, 115, 166, 109, 130, 132, 130, 134, 144, 035, 142 + ); + polish :PCollationTable = @_polish; + + + + + + + // cyrr 20081 + + _cyrr :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 066, 068, 070, 072, 074, 076, 078, 080, 082, 084, 086, 088, 090, 092, 094, + 096, 098, 100, 102, 104, 106, 108, 110, 112, 114, 116, 117, 118, 119, 120, 121, + 122, 065, 067, 069, 071, 073, 075, 077, 079, 081, 083, 085, 087, 089, 091, 093, + 095, 097, 099, 101, 103, 105, 107, 109, 111, 113, 115, 123, 124, 125, 126, 127, + 035, 035, 035, 075, 035, 035, 035, 035, 035, 035, 102, 035, 094, 035, 035, 035, + 035, 035, 035, 035, 035, 035, 035, 035, 035, 035, 101, 035, 093, 035, 035, 114, + 131, 035, 035, 035, 130, 035, 035, 035, 035, 035, 035, 035, 035, 035, 035, 035, + 128, 035, 035, 035, 035, 035, 035, 129, 035, 035, 035, 035, 035, 035, 035, 035, + 066, 066, 066, 066, 066, 066, 066, 070, 074, 074, 074, 074, 082, 082, 082, 082, + 072, 092, 094, 094, 094, 094, 094, 035, 094, 106, 106, 106, 106, 114, 035, 035, + 065, 065, 065, 065, 065, 065, 065, 069, 073, 073, 073, 073, 081, 081, 081, 081, + 071, 091, 093, 093, 093, 093, 093, 035, 093, 105, 105, 105, 105, 113, 035, 113 + ); + cyrr :PCollationTable = @_cyrr; + + + + + + + // hun852dc 62898 + + _hun852dc :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 066, 070, 072, 074, 076, 080, 082, 084, 086, 090, 092, 094, 096, 098, 100, + 107, 109, 111, 113, 115, 117, 123, 125, 127, 129, 131, 132, 133, 134, 135, 136, + 137, 065, 069, 071, 073, 075, 079, 081, 083, 085, 089, 091, 093, 095, 097, 099, + 106, 108, 110, 112, 114, 116, 122, 124, 126, 128, 130, 138, 139, 140, 141, 035, + 035, 035, 035, 079, 035, 035, 035, 035, 035, 035, 159, 035, 100, 035, 035, 035, + 035, 035, 035, 035, 035, 035, 035, 035, 035, 035, 160, 035, 099, 035, 035, 129, + 170, 035, 035, 035, 154, 035, 035, 165, 169, 035, 035, 151, 150, 164, 035, 035, + 168, 035, 035, 035, 163, 035, 035, 035, 167, 035, 035, 152, 035, 035, 035, 035, + 066, 068, 153, 066, 148, 066, 066, 142, 076, 078, 076, 155, 086, 088, 156, 086, + 074, 098, 100, 102, 158, 100, 105, 149, 100, 117, 119, 117, 121, 162, 035, 157, + 065, 067, 143, 065, 144, 065, 065, 145, 075, 077, 075, 146, 085, 087, 147, 085, + 073, 097, 099, 101, 104, 099, 103, 166, 099, 116, 118, 116, 120, 161, 035, 128 + ); + hun852dc :PCollationTable = @_hun852dc; + +{$endif} + + + + + // grcp437 Checksum: 35367 + + _grcp437 :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 066, 068, 070, 072, 074, 076, 078, 080, 082, 084, 086, 088, 090, 092, 094, + 096, 098, 100, 102, 104, 106, 108, 110, 112, 114, 116, 182, 183, 184, 185, 186, + 187, 065, 067, 069, 071, 073, 075, 077, 079, 081, 083, 085, 087, 089, 091, 093, + 095, 097, 099, 101, 103, 105, 107, 109, 111, 113, 115, 188, 189, 190, 191, 192, + 117, 119, 120, 121, 122, 124, 125, 127, 128, 130, 131, 132, 133, 134, 135, 137, + 138, 139, 140, 141, 143, 144, 145, 146, 148, 150, 151, 152, 153, 155, 156, 158, + 159, 162, 163, 164, 165, 166, 167, 169, 170, 171, 172, 173, 174, 177, 178, 179, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, + 180, 149, 154, 157, 160, 161, 168, 176, 175, 181, 118, 123, 126, 129, 136, 142, + 147, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 + ); + + db437gr0 :PCollationTable = @_grcp437; + + + + + // dbHebrew Checksum: 43413 + + _dbHebrew :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 065, 066, 067, 068, 069, 070, 071, 072, 073, 074, 075, 076, 077, 078, 079, + 080, 081, 082, 083, 084, 085, 086, 087, 088, 089, 090, 091, 092, 093, 094, 095, + 096, 097, 098, 099, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 + ); + dbhebrew :PCollationTable = @_dbhebrew; + + + + + + // slovene Checksum: 48585 + + _slovene :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 071, 078, 081, 089, 098, 104, 106, 108, 112, 116, 118, 123, 128, 132, 140, + 146, 148, 152, 159, 167, 175, 181, 183, 185, 188, 193, 198, 199, 200, 201, 202, + 203, 065, 077, 079, 087, 093, 103, 105, 107, 109, 115, 117, 119, 127, 129, 135, + 145, 147, 149, 155, 164, 170, 180, 182, 184, 186, 190, 204, 205, 206, 207, 208, + 082, 171, 095, 068, 066, 174, 085, 080, 121, 094, 144, 139, 111, 194, 072, 086, + 100, 124, 120, 138, 136, 126, 122, 160, 156, 141, 176, 168, 165, 125, 209, 083, + 067, 110, 137, 172, 076, 070, 197, 196, 102, 097, 210, 191, 084, 157, 211, 212, + 213, 214, 215, 216, 217, 073, 074, 101, 161, 218, 219, 220, 221, 195, 192, 222, + 223, 224, 225, 226, 227, 228, 075, 069, 229, 230, 231, 232, 233, 234, 235, 236, + 091, 092, 090, 099, 088, 134, 113, 114, 096, 237, 238, 239, 240, 169, 179, 241, + 142, 158, 143, 133, 130, 131, 163, 162, 153, 177, 150, 178, 187, 189, 166, 242, + 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 173, 154, 151, 254, 255 + ); + db852sl0 :PCollationTable = @_slovene; + +{$ifdef USE_PARADOX_COLLATIONS} + grcp437 :PCollationTable = @_grcp437; + + hebrew :PCollationTable = @_dbhebrew; + + slovene :PCollationTable = @_slovene; +{$endif} + + + + {$IFDEF PARADOX_COLLATIONS} + + // turk 8582 + + _turk :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 072, 082, 084, 088, 094, 100, 102, 104, 109, 116, 118, 120, 122, 125, 132, + 140, 142, 144, 146, 149, 154, 161, 163, 165, 168, 170, 171, 172, 173, 174, 175, + 176, 065, 081, 083, 087, 089, 099, 101, 103, 114, 115, 117, 119, 121, 123, 127, + 139, 141, 143, 145, 148, 150, 160, 162, 164, 166, 169, 177, 178, 179, 180, 035, + 035, 035, 035, 099, 035, 035, 035, 035, 035, 035, 146, 035, 132, 035, 035, 035, + 035, 035, 035, 035, 035, 035, 035, 035, 035, 035, 145, 035, 127, 035, 035, 168, + 216, 189, 193, 182, 195, 194, 198, 207, 211, 192, 197, 190, 186, 203, 185, 201, + 210, 204, 215, 214, 202, 199, 206, 212, 209, 213, 196, 191, 188, 187, 205, 184, + 074, 076, 075, 077, 080, 073, 078, 086, 098, 095, 096, 097, 113, 110, 111, 112, + 088, 126, 135, 133, 134, 136, 138, 200, 183, 157, 155, 156, 159, 168, 035, 147, + 067, 069, 068, 070, 079, 066, 071, 085, 093, 090, 091, 092, 108, 107, 106, 105, + 087, 124, 129, 128, 130, 131, 137, 208, 181, 152, 153, 151, 158, 166, 035, 167 + ); + turk :PCollationTable = @_turk; + + {$ENDIF} + + + + + {$IFDEF PARADOX_COLLATIONS} + + // anczech 44872 + + _anczech :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 066, 078, 080, 088, 094, 104, 106, 108, 110, 116, 118, 120, 128, 130, 136, + 146, 148, 150, 156, 165, 171, 181, 183, 185, 187, 191, 198, 199, 200, 201, 202, + 203, 065, 077, 079, 087, 093, 103, 105, 107, 109, 115, 117, 119, 127, 129, 135, + 145, 147, 149, 155, 164, 170, 180, 182, 184, 186, 190, 204, 205, 206, 207, 208, + 250, 251, 209, 252, 210, 211, 212, 213, 253, 214, 163, 215, 158, 167, 197, 195, + 254, 216, 217, 218, 219, 220, 221, 222, 255, 223, 162, 224, 157, 166, 196, 194, + 225, 226, 227, 122, 228, 074, 229, 230, 231, 232, 160, 233, 234, 235, 236, 193, + 237, 238, 239, 121, 240, 241, 242, 243, 244, 073, 159, 245, 126, 246, 125, 192, + 152, 068, 070, 072, 076, 124, 082, 084, 086, 096, 100, 102, 098, 112, 114, 092, + 090, 132, 134, 138, 140, 144, 142, 247, 154, 175, 173, 179, 177, 189, 169, 161, + 151, 067, 069, 071, 075, 123, 081, 083, 085, 095, 099, 101, 097, 111, 113, 091, + 089, 131, 133, 137, 139, 143, 141, 248, 153, 174, 172, 178, 176, 188, 168, 249 + ); + anczech :PCollationTable = @_anczech; + + anczechw :PCollationTable = @_anczech; + + anil2czw :PCollationTable = @_anczech; + + {$ENDIF} + + + + {$IFDEF PARADOX_COLLATIONS} + + // cskamenw 40577 + + _cskamenw :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 066, 072, 074, 076, 078, 082, 084, 086, 088, 092, 094, 096, 098, 100, 102, + 110, 112, 114, 116, 120, 122, 128, 130, 132, 134, 138, 139, 140, 141, 142, 143, + 144, 065, 071, 073, 075, 077, 081, 083, 085, 087, 091, 093, 095, 097, 099, 101, + 109, 111, 113, 115, 119, 121, 127, 129, 131, 133, 137, 145, 146, 147, 148, 149, + 035, 035, 035, 081, 035, 035, 035, 035, 035, 035, 118, 035, 102, 035, 035, 035, + 035, 035, 035, 035, 035, 035, 035, 035, 035, 035, 117, 035, 101, 035, 035, 134, + 161, 035, 035, 035, 035, 035, 035, 151, 035, 035, 035, 152, 035, 035, 035, 035, + 158, 156, 160, 035, 035, 155, 035, 159, 035, 035, 035, 153, 150, 035, 035, 035, + 066, 068, 066, 066, 070, 066, 066, 074, 078, 080, 078, 078, 088, 090, 088, 088, + 076, 100, 102, 104, 106, 102, 108, 035, 102, 122, 124, 122, 126, 136, 035, 154, + 065, 067, 065, 065, 069, 065, 065, 073, 077, 079, 077, 077, 087, 089, 087, 087, + 075, 099, 101, 103, 105, 101, 107, 157, 101, 121, 123, 121, 125, 135, 035, 133 + ); + cskamenw :PCollationTable = @_cskamenw; + + cskamen :PCollationTable = @_cskamenw; + + {$ENDIF} + + + + + {$IFDEF PARADOX_COLLATIONS} + + // anpolish 44922 + + _anpolish :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 066, 078, 080, 088, 094, 104, 106, 108, 110, 116, 118, 120, 128, 130, 136, + 146, 148, 150, 156, 165, 171, 181, 183, 185, 187, 191, 198, 199, 200, 201, 202, + 203, 065, 077, 079, 087, 093, 103, 105, 107, 109, 115, 117, 119, 127, 129, 135, + 145, 147, 149, 155, 164, 170, 180, 182, 184, 186, 190, 204, 205, 206, 207, 208, + 250, 251, 237, 252, 229, 230, 231, 233, 253, 234, 162, 236, 158, 167, 197, 193, + 254, 217, 222, 223, 224, 225, 226, 227, 255, 232, 161, 249, 157, 166, 196, 192, + 210, 241, 242, 122, 228, 074, 218, 243, 247, 220, 160, 211, 235, 238, 219, 195, + 246, 221, 240, 121, 213, 214, 215, 216, 245, 073, 159, 212, 126, 239, 125, 194, + 152, 068, 070, 072, 076, 124, 082, 084, 086, 096, 100, 102, 098, 112, 114, 092, + 090, 132, 134, 138, 140, 144, 142, 209, 154, 175, 173, 179, 177, 189, 169, 163, + 151, 067, 069, 071, 075, 123, 081, 083, 085, 095, 099, 101, 097, 111, 113, 091, + 089, 131, 133, 137, 139, 143, 141, 244, 153, 174, 172, 178, 176, 188, 168, 248 + ); + anpolish :PCollationTable = @_anpolish; + + {$ENDIF} + + + + + {$IFDEF PARADOX_COLLATIONS} + + // ancyrr 15158 + + _ancyrr :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 066, 068, 070, 072, 074, 076, 078, 080, 082, 084, 086, 088, 090, 092, 094, + 096, 098, 100, 102, 104, 106, 108, 110, 112, 114, 116, 183, 184, 185, 186, 187, + 188, 065, 067, 069, 071, 073, 075, 077, 079, 081, 083, 085, 087, 089, 091, 093, + 095, 097, 099, 101, 103, 105, 107, 109, 111, 113, 115, 189, 190, 191, 192, 193, + 194, 195, 196, 197, 198, 199, 200, 201, 254, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, 255, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, 130, 232, 233, 234, 235, 236, 237, 238, + 239, 240, 241, 242, 243, 244, 245, 246, 129, 247, 248, 249, 250, 251, 252, 253, + 118, 120, 122, 124, 126, 128, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, + 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, + 117, 119, 121, 123, 125, 127, 131, 133, 135, 137, 139, 141, 143, 145, 147, 149, + 151, 153, 155, 157, 159, 161, 163, 165, 167, 169, 171, 173, 175, 177, 179, 181 + ); + ancyrr :PCollationTable = @_ancyrr; + + {$ENDIF} + + + + + {$IFDEF PARADOX_COLLATIONS} + + // anhundc 19132 + + _anhundc :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 066, 071, 073, 075, 077, 081, 083, 085, 087, 092, 094, 096, 098, 100, 102, + 113, 115, 117, 119, 121, 123, 134, 136, 138, 140, 142, 143, 144, 145, 146, 147, + 148, 065, 070, 072, 074, 076, 080, 082, 084, 086, 091, 093, 095, 097, 099, 101, + 112, 114, 116, 118, 120, 122, 133, 135, 137, 139, 141, 149, 150, 151, 152, 153, + 250, 251, 154, 252, 155, 156, 157, 158, 253, 159, 160, 161, 126, 162, 163, 090, + 254, 164, 165, 166, 167, 168, 169, 170, 255, 171, 172, 173, 132, 174, 111, 175, + 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 105, 204, 130, 205, + 206, 068, 207, 208, 209, 210, 069, 211, 212, 079, 213, 214, 215, 089, 216, 217, + 218, 219, 220, 104, 221, 110, 107, 222, 223, 224, 125, 131, 128, 225, 226, 227, + 228, 067, 229, 230, 231, 232, 233, 234, 235, 078, 236, 237, 238, 088, 239, 240, + 241, 242, 243, 103, 109, 108, 106, 244, 245, 246, 124, 129, 127, 247, 248, 249 + ); + anhundc :PCollationTable = @_anhundc; + + {$ENDIF} + + + + {$IFDEF PARADOX_COLLATIONS} + + // angreek1 39126 + + _angreek1 :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 066, 068, 070, 072, 074, 076, 078, 080, 082, 084, 086, 088, 090, 092, 094, + 096, 098, 100, 102, 104, 106, 108, 110, 112, 114, 116, 186, 187, 188, 189, 190, + 191, 065, 067, 069, 071, 073, 075, 077, 079, 081, 083, 085, 087, 089, 091, 093, + 095, 097, 099, 101, 103, 105, 107, 109, 111, 113, 115, 192, 193, 194, 195, 196, + 238, 239, 197, 198, 199, 200, 201, 202, 240, 203, 241, 204, 242, 243, 244, 245, + 246, 205, 206, 207, 208, 209, 210, 211, 247, 212, 248, 213, 249, 250, 251, 252, + 214, 215, 120, 216, 217, 218, 219, 220, 221, 222, 253, 223, 224, 225, 226, 227, + 228, 229, 230, 231, 232, 233, 234, 235, 130, 136, 144, 236, 159, 237, 174, 185, + 142, 119, 122, 124, 126, 129, 132, 135, 138, 143, 147, 149, 151, 153, 155, 158, + 161, 163, 254, 166, 168, 173, 177, 179, 181, 184, 145, 175, 118, 128, 134, 140, + 172, 117, 121, 123, 125, 127, 131, 133, 137, 139, 146, 148, 150, 152, 154, 156, + 160, 162, 165, 164, 167, 169, 176, 178, 180, 182, 141, 171, 157, 170, 183, 255 + ); + angreek1 :PCollationTable = @_angreek1; + + ACCGREEK :PCollationTable = @_angreek1; + + {$ENDIF} + + {$IFDEF PARADOX_COLLATIONS} + + // ansislov 61480 + + _ansislov :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 071, 078, 081, 089, 098, 104, 106, 108, 112, 116, 118, 123, 128, 132, 140, + 146, 148, 152, 159, 167, 175, 181, 183, 185, 188, 193, 198, 199, 200, 201, 202, + 203, 065, 077, 079, 087, 093, 103, 105, 107, 109, 115, 117, 119, 127, 129, 135, + 145, 147, 149, 155, 164, 170, 180, 182, 184, 186, 190, 204, 205, 206, 207, 208, + 250, 251, 209, 252, 210, 211, 212, 213, 253, 214, 163, 215, 160, 168, 197, 194, + 254, 216, 217, 218, 219, 220, 221, 222, 255, 223, 162, 224, 156, 165, 196, 191, + 225, 226, 227, 125, 228, 076, 229, 230, 231, 232, 161, 233, 234, 235, 236, 195, + 237, 238, 239, 121, 240, 241, 242, 243, 244, 070, 157, 245, 126, 246, 122, 192, + 153, 073, 074, 075, 072, 124, 086, 082, 084, 100, 102, 099, 101, 113, 114, 090, + 092, 133, 134, 142, 143, 144, 141, 247, 154, 179, 177, 178, 176, 189, 169, 158, + 150, 067, 068, 069, 066, 120, 085, 080, 083, 095, 097, 094, 096, 110, 111, 088, + 091, 130, 131, 137, 138, 139, 136, 248, 151, 174, 172, 173, 171, 187, 166, 249 + ); + ansislov :PCollationTable = @_ansislov; + + {$ENDIF} + + + + {$IFDEF USE_PARADOX_COLLATIONS} + + // ANTURK 24004 + + _ANTURK :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 072, 082, 084, 088, 094, 100, 102, 106, 112, 120, 122, 124, 126, 129, 136, + 144, 146, 148, 150, 155, 160, 167, 169, 171, 174, 176, 177, 178, 179, 180, 181, + 182, 065, 081, 083, 087, 089, 099, 101, 105, 117, 119, 121, 123, 125, 127, 131, + 143, 145, 147, 149, 154, 156, 166, 168, 170, 172, 175, 183, 184, 185, 186, 187, + 248, 249, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 250, 251, 252, + 253, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 254, 255, 211, + 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, + 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, + 074, 076, 075, 077, 080, 073, 078, 086, 098, 095, 096, 097, 116, 113, 114, 115, + 104, 130, 139, 137, 138, 140, 142, 244, 245, 163, 161, 162, 165, 118, 153, 151, + 067, 069, 068, 070, 079, 066, 071, 085, 093, 090, 091, 092, 111, 110, 109, 108, + 103, 128, 133, 132, 134, 135, 141, 246, 247, 158, 159, 157, 164, 107, 152, 173 + ); + ANTURK :PCollationTable = @_ANTURK; + + {$ENDIF} + + + + // DB857TR0 Checksum: 20238 + + _DB857TR0 :TCollationTable = ( + 000, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, + 001, 141, 154, 147, 148, 133, 146, 156, 122, 123, 134, 131, 136, 132, 135, 142, + 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 138, 137, 128, 130, 129, 140, + 145, 012, 020, 021, 023, 024, 029, 030, 032, 033, 039, 040, 041, 042, 043, 045, + 051, 052, 053, 054, 056, 057, 062, 063, 064, 065, 066, 124, 143, 125, 157, 159, + 155, 067, 074, 075, 077, 078, 083, 084, 086, 092, 093, 094, 095, 096, 097, 099, + 105, 106, 107, 108, 110, 111, 116, 117, 118, 119, 121, 126, 144, 127, 158, 191, + 022, 115, 079, 071, 072, 069, 073, 076, 081, 082, 080, 091, 089, 087, 013, 014, + 028, 152, 019, 103, 104, 102, 114, 113, 038, 050, 061, 149, 150, 151, 055, 109, + 068, 088, 100, 112, 098, 044, 031, 085, 139, 192, 193, 194, 195, 196, 197, 198, + 199, 200, 201, 202, 203, 015, 016, 018, 204, 205, 206, 207, 208, 209, 210, 211, + 212, 213, 214, 215, 216, 217, 070, 017, 218, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 025, 026, 027, 253, 034, 035, 037, 228, 229, 230, 231, 232, 036, 233, + 046, 153, 047, 049, 101, 048, 234, 254, 235, 058, 059, 060, 090, 120, 236, 237, + 238, 239, 255, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252 + ); + DB857TR0 :PCollationTable = @_DB857TR0; + + + + + // FOXCZWIN 29353 + + _FOXCZWIN :TCollationTable = ( + 000, 001, 001, 001, 001, 001, 001, 001, 001, 002, 003, 004, 005, 006, 001, 001, + 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, 001, + 016, 007, 008, 009, 010, 011, 012, 013, 014, 015, 016, 017, 018, 019, 020, 021, + 080, 081, 082, 083, 084, 085, 086, 087, 088, 089, 022, 023, 024, 025, 026, 027, + 028, 090, 097, 098, 102, 105, 110, 111, 112, 113, 116, 117, 118, 122, 123, 126, + 131, 132, 133, 136, 141, 144, 150, 151, 152, 153, 155, 029, 030, 031, 032, 033, + 034, 090, 097, 098, 102, 105, 110, 111, 112, 113, 116, 117, 118, 122, 123, 126, + 131, 132, 133, 136, 141, 144, 150, 151, 152, 153, 155, 035, 036, 037, 038, 001, + 159, 160, 039, 161, 040, 041, 042, 043, 162, 044, 140, 045, 137, 142, 158, 157, + 163, 046, 047, 048, 049, 050, 051, 052, 164, 053, 140, 054, 137, 142, 158, 157, + 055, 056, 057, 121, 058, 095, 059, 060, 061, 062, 138, 063, 064, 065, 066, 156, + 067, 068, 069, 121, 070, 071, 072, 073, 074, 096, 138, 075, 120, 076, 120, 156, + 134, 092, 093, 094, 091, 119, 099, 100, 101, 107, 109, 106, 108, 114, 115, 103, + 104, 124, 125, 128, 130, 129, 127, 077, 135, 146, 145, 147, 145, 154, 143, 139, + 134, 092, 093, 094, 091, 119, 099, 100, 101, 107, 109, 106, 108, 114, 115, 103, + 104, 124, 125, 128, 130, 129, 127, 078, 135, 147, 146, 148, 149, 154, 143, 079 + ); + FOXCZWIN :PCollationTable = @_FOXCZWIN; + + + + + // FOXCZ895 Checksum: 42384 + + _FOXCZ895 :TCollationTable = ( + 000, 032, 032, 032, 032, 032, 032, 032, 032, 032, 032, 032, 032, 032, 032, 032, + 032, 032, 032, 032, 032, 032, 032, 032, 032, 032, 032, 032, 032, 032, 032, 032, + 048, 036, 037, 038, 039, 040, 041, 033, 042, 043, 044, 063, 045, 034, 046, 048, + 131, 133, 134, 136, 137, 138, 139, 140, 141, 142, 049, 050, 065, 066, 067, 051, + 052, 145, 152, 154, 158, 162, 168, 170, 172, 174, 178, 180, 182, 188, 191, 195, + 203, 205, 207, 213, 218, 223, 231, 233, 235, 237, 241, 053, 054, 055, 056, 057, + 058, 145, 152, 154, 158, 162, 168, 170, 172, 174, 178, 180, 182, 188, 191, 195, + 203, 205, 207, 213, 218, 223, 231, 233, 235, 237, 241, 059, 060, 061, 062, 032, + 156, 225, 164, 160, 147, 160, 220, 156, 166, 166, 184, 176, 186, 184, 147, 149, + 164, 243, 243, 201, 197, 199, 229, 227, 239, 197, 225, 216, 186, 239, 211, 220, + 149, 176, 199, 227, 193, 193, 229, 201, 216, 211, 209, 209, 132, 127, 069, 070, + 124, 125, 126, 083, 105, 106, 150, 091, 090, 107, 084, 092, 100, 099, 098, 089, + 093, 112, 108, 101, 081, 116, 102, 103, 096, 088, 115, 111, 104, 082, 119, 113, + 114, 109, 110, 095, 094, 086, 087, 118, 117, 097, 085, 123, 121, 221, 122, 120, + 244, 214, 245, 249, 251, 251, 129, 252, 254, 248, 255, 246, 143, 254, 247, 073, + 075, 068, 077, 076, 078, 079, 071, 074, 128, 064, 130, 072, 191, 135, 080, 035 + ); + FOXCZ895 :PCollationTable = @_FOXCZ895; + + + + {$IFDEF USE_ACCESS_COLLATIONS} + + // BLROM800 28847 + + _BLROM800 :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 048, 049, 050, 051, 052, 053, 054, 055, 056, 057, 058, 059, 060, 061, 062, 063, + 064, 065, 066, 067, 068, 069, 070, 071, 072, 073, 074, 075, 076, 077, 078, 079, + 080, 081, 082, 083, 084, 085, 086, 087, 088, 089, 090, 091, 092, 093, 094, 095, + 096, 097, 098, 099, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 035, 161, 035, 035, 035, 035, 035, 035, 206, 035, 079, 130, 131, 132, + 133, 035, 035, 035, 035, 035, 035, 217, 035, 035, 207, 035, 111, 134, 135, 209, + 136, 155, 162, 158, 157, 159, 035, 160, 145, 035, 220, 222, 035, 035, 035, 035, + 150, 224, 035, 035, 144, 214, 215, 213, 035, 035, 221, 223, 218, 219, 216, 156, + 137, 195, 138, 196, 187, 179, 182, 151, 139, 191, 140, 141, 201, 200, 142, 143, + 198, 153, 203, 202, 194, 204, 189, 035, 181, 146, 208, 147, 190, 148, 211, 193, + 171, 167, 163, 197, 175, 183, 186, 152, 172, 168, 164, 176, 188, 184, 180, 192, + 199, 154, 173, 169, 165, 205, 177, 035, 185, 174, 170, 166, 178, 149, 212, 210 + ); + BLROM800 :PCollationTable = @_BLROM800; + + {$ENDIF} + + + {$IFDEF USE_ORACLE_COLLATIONS} + + // ORAWE850 31378 + + _ORAWE850 :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 048, 049, 050, 051, 052, 053, + 054, 101, 117, 119, 123, 127, 137, 139, 141, 143, 153, 155, 157, 159, 161, 165, + 179, 181, 183, 185, 188, 192, 202, 204, 206, 208, 213, 055, 056, 057, 058, 059, + 060, 102, 118, 120, 124, 128, 138, 140, 142, 144, 154, 156, 158, 160, 162, 166, + 180, 182, 184, 186, 189, 193, 203, 205, 207, 209, 214, 061, 062, 063, 064, 065, + 035, 035, 035, 068, 035, 035, 035, 035, 035, 035, 185, 035, 165, 035, 035, 035, + 035, 035, 035, 035, 035, 035, 035, 035, 035, 035, 186, 035, 166, 035, 035, 208, + 100, 076, 080, 066, 082, 081, 083, 091, 095, 079, 069, 077, 073, 087, 072, 085, + 094, 088, 099, 098, 086, 084, 090, 096, 093, 097, 070, 078, 075, 074, 089, 071, + 105, 103, 107, 111, 109, 113, 115, 121, 131, 129, 133, 135, 147, 145, 149, 151, + 125, 163, 169, 167, 171, 175, 173, 067, 177, 196, 194, 198, 200, 210, 190, 187, + 106, 104, 108, 112, 110, 114, 116, 122, 132, 130, 134, 136, 148, 146, 150, 152, + 126, 164, 170, 168, 172, 176, 174, 092, 178, 197, 195, 199, 201, 211, 191, 212 + ); + ORAWE850 :PCollationTable = @_ORAWE850 ; + + {$ENDIF} + + + + {$IFDEF USE_SYBASE_COLLATIONS} + + // SYDC850 46023 + + _SYDC850 :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 048, 049, 050, 051, 052, 053, + 054, 111, 127, 129, 133, 135, 145, 147, 149, 151, 161, 163, 165, 167, 169, 173, + 187, 189, 191, 193, 196, 198, 208, 210, 212, 214, 219, 055, 056, 057, 058, 059, + 060, 112, 128, 130, 134, 136, 146, 148, 150, 152, 162, 164, 166, 168, 170, 174, + 188, 190, 192, 194, 197, 199, 209, 211, 213, 215, 220, 061, 062, 063, 064, 065, + 035, 035, 035, 068, 035, 035, 035, 035, 035, 035, 193, 035, 173, 035, 035, 035, + 035, 035, 035, 035, 035, 035, 035, 035, 035, 035, 194, 035, 174, 035, 035, 214, + 100, 076, 080, 066, 082, 081, 083, 091, 095, 079, 069, 077, 073, 087, 072, 085, + 094, 088, 099, 098, 086, 084, 090, 096, 093, 097, 070, 078, 075, 074, 089, 071, + 113, 115, 117, 119, 121, 123, 125, 131, 137, 139, 141, 143, 153, 155, 157, 159, + 221, 171, 175, 177, 179, 181, 183, 067, 185, 200, 202, 204, 206, 216, 224, 195, + 114, 116, 118, 120, 122, 124, 126, 132, 138, 140, 142, 144, 154, 156, 158, 160, + 222, 172, 176, 178, 180, 182, 184, 092, 186, 201, 203, 205, 207, 217, 223, 218 + ); + SYDC850 :PCollationTable = @_SYDC850; + + + + + // SYDC437 16660 + + _SYDC437 :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 034, 035, 036, 037, 038, 039, 040, 041, 042, 043, 044, 045, 046, 047, + 085, 086, 087, 088, 089, 090, 091, 092, 093, 094, 048, 049, 050, 051, 052, 053, + 054, 095, 106, 108, 112, 114, 121, 123, 125, 127, 133, 135, 137, 139, 141, 145, + 152, 154, 156, 158, 160, 162, 169, 171, 173, 175, 178, 055, 056, 057, 058, 059, + 060, 096, 107, 109, 113, 115, 122, 124, 126, 128, 134, 136, 138, 140, 142, 146, + 153, 155, 157, 159, 161, 163, 170, 172, 174, 176, 179, 061, 062, 063, 064, 065, + 035, 035, 035, 069, 035, 035, 035, 035, 035, 035, 158, 035, 145, 035, 035, 035, + 035, 035, 035, 035, 035, 035, 035, 035, 035, 035, 159, 035, 146, 035, 035, 175, + 084, 076, 066, 067, 035, 068, 035, 035, 035, 035, 070, 077, 073, 035, 035, 035, + 081, 079, 083, 035, 035, 181, 035, 082, 035, 035, 071, 078, 075, 074, 035, 072, + 095, 095, 095, 095, 100, 102, 104, 110, 114, 117, 114, 114, 127, 127, 127, 127, + 112, 143, 145, 145, 145, 145, 150, 035, 145, 162, 162, 162, 167, 175, 035, 180, + 097, 098, 099, 096, 101, 103, 105, 111, 116, 118, 119, 120, 129, 130, 131, 132, + 113, 144, 147, 148, 149, 146, 151, 080, 146, 164, 165, 166, 168, 176, 035, 177 + ); + SYDC437 :PCollationTable = @_SYDC437; + + {$ENDIF} + + + {$IFDEF USE_DB2_COLLATIONS} + + // db2andeu 8683 + + _db2andeu :TCollationTable = ( + 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, + 016, 017, 018, 019, 020, 021, 022, 023, 024, 025, 026, 027, 028, 029, 030, 031, + 032, 033, 035, 038, 039, 045, 046, 047, 048, 049, 050, 051, 052, 053, 054, 055, + 056, 057, 058, 059, 060, 061, 062, 063, 064, 065, 066, 067, 068, 069, 070, 071, + 073, 074, 085, 087, 091, 094, 101, 103, 105, 107, 113, 115, 117, 119, 121, 125, + 132, 134, 136, 138, 141, 143, 150, 152, 154, 156, 159, 161, 162, 163, 164, 165, + 166, 075, 086, 088, 092, 095, 102, 104, 106, 108, 114, 116, 118, 120, 122, 126, + 133, 135, 137, 139, 142, 144, 151, 153, 155, 157, 160, 168, 169, 170, 171, 172, + 233, 234, 235, 041, 236, 237, 238, 239, 240, 241, 231, 242, 229, 243, 244, 245, + 246, 167, 211, 226, 227, 247, 248, 249, 250, 251, 230, 252, 228, 253, 254, 232, + 032, 034, 042, 040, 185, 043, 193, 217, 221, 182, 173, 036, 176, 213, 175, 210, + 220, 214, 225, 224, 212, 200, 216, 222, 219, 223, 174, 037, 178, 177, 215, 072, + 181, 179, 180, 184, 080, 081, 083, 089, 189, 100, 187, 188, 194, 190, 191, 192, + 093, 124, 197, 195, 196, 199, 130, 044, 202, 207, 205, 206, 148, 209, 204, 140, + 078, 084, 076, 183, 077, 079, 082, 090, 099, 096, 097, 098, 111, 112, 110, 109, + 186, 123, 129, 131, 127, 198, 128, 218, 201, 147, 149, 146, 145, 208, 203, 158 + ); + db2andeu :PCollationTable = @_db2andeu; + + {$ENDIF} + +initialization + + InitialiseCollationTables; + + RegisterCollation( DbfLangId_Spanish_1252, DBWINES0, 'DBWINES0' ); // 'Spanish' ANSI + RegisterCollation( DbfLangId_Ascii_1252, BINARY_COLLATION, 'DBWINUS0' ); // 'ascii' ANSI + RegisterCollation( DbfLangId_WEurope_1252, DBWINWE0, 'DBWINWE0' ); // 'WEurope' ANSI + + //DbfLangId_BUL_868 = $8E; // is it used? does not exist in BDE + //DbfLangId_FIN_850 = $0C; // is it used? does not exist in BDE + RegisterCollation( DbfLangId_DEU_437, DB437DE0, 'DB437DE0' ); // dBASE DEU cp437 + RegisterCollation( DbfLangId_ESP_437, DB437ES1, 'DB437ES1' ); // dBASE ESP cp437 + RegisterCollation( DbfLangId_FIN_437, DB437FI0, 'DB437FI0' ); // dBASE FIN cp437 + RegisterCollation( DbfLangId_FRA_437, DB437FR0, 'DB437FR0' ); // dBASE FRA cp437 + RegisterCollation( DbfLangId_ELL_437, db437gr0, 'db437gr0' ); // dBASE ELL GR437 + RegisterCollation( DbfLangId_ITA_437, DB437IT0, 'DB437IT0' ); // dBASE ITA cp437 + RegisterCollation( DbfLangId_NLD_437, DB437NL0, 'DB437NL0' ); // dBASE NLD cp437 + RegisterCollation( DbfLangId_SVE_437, DB437SV0, 'DB437SV0' ); // dBASE SVE cp437 + RegisterCollation( DbfLangId_ENG_437, DB437UK0, 'DB437UK0' ); // dBASE ENG cp437 + RegisterCollation( DbfLangId_ENU_437, DB437US0, 'DB437US0' ); // dBASE ENU cp437 + RegisterCollation( DbfLangId_FRC_850, DB850CF0, 'DB850CF0' ); // dBASE FRC cp850 + RegisterCollation( DbfLangId_DEU_850, DB850DE0, 'DB850DE0' ); // dBASE DEU cp850 + RegisterCollation( DbfLangId_ESP_850, DB850ES0, 'DB850ES0' ); // dBASE ESP cp850 + RegisterCollation( DbfLangId_FRA_850, DB850FR0, 'DB850FR0' ); // dBASE FRA cp850 + RegisterCollation( DbfLangId_ITA_850, DB850IT1, 'DB850IT1' ); // dBASE ITA cp850 + RegisterCollation( DbfLangId_NLD_850, DB850NL0, 'DB850NL0' ); // dBASE NLD cp850 + RegisterCollation( DbfLangId_PTB_850, DB850PT0, 'DB850PT0' ); // dBASE PTB cp850 + RegisterCollation( DbfLangId_SVE_850, DB850SV1, 'DB850SV1' ); // dBASE SVE cp850 + RegisterCollation( DbfLangId_ENG_850, DB850UK0, 'DB850UK0' ); // dBASE ENG cp850 + RegisterCollation( DbfLangId_ENU_850, DB850US0, 'DB850US0' ); // dBASE ENU cp850 + RegisterCollation( DbfLangId_CSY_852, DB852CZ0, 'DB852CZ0' ); // dBASE CSY cp852 + RegisterCollation( DbfLangId_HUN_852, db852hdc, 'db852hdc' ); // dBASE HUN cp852 + RegisterCollation( DbfLangId_PLK_852, db852po0, 'db852po0' ); // dBASE PLK cp852 + RegisterCollation( DbfLangId_SLO_852, db852sl0, 'db852sl0' ); // dBASE SLO cp852 + RegisterCollation( DbfLangId_TRK_857, DB857TR0, 'DB857TR0' ); // dBASE TRK cp857 + RegisterCollation( DbfLangId_PTG_860, DB860PT0, 'DB860PT0' ); // dBASE PTG cp860 + RegisterCollation( DbfLangId_FRC_863, DB863CF1, 'DB863CF1' ); // dBASE FRC cp863 + RegisterCollation( DbfLangId_DAN_865, DB865DA0, 'DB865DA0' ); // dBASE DAN cp865 + RegisterCollation( DbfLangId_NOR_865, DB865NO0, 'DB865NO0' ); // dBASE NOR cp865 + RegisterCollation( DbfLangId_RUS_866, db866ru0, 'db866ru0' ); // dBASE RUS cp866 + RegisterCollation( DbfLangId_CSY_867, DB867CZ0, 'DB867CZ0' ); // dBASE CSY cp867 + RegisterCollation( DbfLangId_THA_874, db874th0, 'db874th0' ); // dBASE THA cp874 + RegisterCollation( DbfLangId_JPN_932, BINARY_COLLATION, 'DB932JP0' ); // dBASE JPN cp932 + RegisterCollation( DbfLangId_JPN_DIC_932, DB932JP1, 'DB932JP1' ); // dBASE JPN Dic932 + RegisterCollation( DbfLangId_CHS_936, DB936CN0, 'DB936CN0' ); // dBASE CHS cp936 + RegisterCollation( DbfLangId_KOR_949, DB949KO0, 'DB949KO0' ); // dBASE KOR cp949 + RegisterCollation( DbfLangId_CHT_950, DB950TW0, 'DB950TW0' ); // dBASE CHT cp950 + RegisterCollation( DbfLangId_Hebrew, dbHebrew, 'dbHebrew' ); // Hebrew dBASE + //RegisterCollation( XXXXXXXXXXXX, BLLT1CA0 ); // Borland FRC Latin-1 + //RegisterCollation( XXXXXXXXXXXX, BLLT1DA0 ); // Borland DAN Latin-1 + //RegisterCollation( XXXXXXXXXXXX, BLLT1DE0 ); // Borland DEU Latin-1 + //RegisterCollation( XXXXXXXXXXXX, BLLT1ES0 ); // Borland ESP Latin-1 + //RegisterCollation( XXXXXXXXXXXX, BLLT1FI0 ); // Borland FIN Latin-1 + //RegisterCollation( XXXXXXXXXXXX, BLLT1FR0 ); // Borland FRA Latin-1 + //RegisterCollation( XXXXXXXXXXXX, BLLT1IS0 ); // Borland ISL Latin-1 + //RegisterCollation( XXXXXXXXXXXX, BLLT1IT0 ); // Borland ITA Latin-1 + //RegisterCollation( XXXXXXXXXXXX, BLLT1NL0 ); // Borland NLD Latin-1 + //RegisterCollation( XXXXXXXXXXXX, BLLT1NO0 ); // Borland NOR Latin-1 + //RegisterCollation( XXXXXXXXXXXX, BLLT1PT0 ); // Borland PTG Latin-1 + //RegisterCollation( XXXXXXXXXXXX, BLLT1SV0 ); // Borland SVE Latin-1 + //RegisterCollation( XXXXXXXXXXXX, BLLT1UK0 ); // Borland ENG Latin-1 + //RegisterCollation( XXXXXXXXXXXX, BLLT1US0 ); // Borland ENU Latin-1 + +(* + + FoxLangId_ENU_437 = $01; + FoxLangId_Intl_850 = $02; + FoxLangId_Windows_1252 = $03; + FoxLangId_Mac_10000 = $04; + + FoxLangId_EEurope_852 = $64; + FoxLangId_Russia_866 = $65; + FoxLangId_Nordic_865 = $66; + FoxLangId_Iceland_861 = $67; + + DbfLangId_POL_620 = $69; + + FoxLangId_Greek_737 = $6A; + FoxLangId_Turkish_857 = $6B; + + FoxLangId_Taiwan_950 = $78; + FoxLangId_Korean_949 = $79; + FoxLangId_Chinese_936 = $7A; + FoxLangId_Japan_932 = $7B; + FoxLangId_Thai_874 = $7C; + FoxLangId_Hebrew_1255 = $7D; + FoxLangId_Arabic_1256 = $7E; + + FoxLangId_Russia_10007 = $96; + FoxLangId_EEurope_10029 = $97; + FoxLangId_Greek_10006 = $98; + + FoxLangId_Czech_850 = $9C; // DOS + + FoxLangId_EEurope_1250 = $C8; + FoxLangId_Russia_1251 = $C9; + FoxLangId_Turkish_1254 = $CA; + FoxLangId_Greek_1253 = $CB; + +*) + + + RegisterCollation( FoxLangId_Czech_895, FOXCZ895, 'FOXCZ895' ); // FoxPro Czech DOS895 + RegisterCollation( FoxLangId_Czech_1250, FOXCZWIN, 'FOXCZWIN' ); // FoxPro Czech 1250 + RegisterCollation( FoxLangId_German_437, FOXDE437, 'FOXDE437' ); // FoxPro German 437 + RegisterCollation( FoxLangId_German_1252, FOXDEWIN, 'FOXDEWIN' ); // FoxPro German 1252 + RegisterCollation( FoxLangId_Nordic_437, FOXNO437, 'FOXNO437' ); // FoxPro Nordic 437 + RegisterCollation( FoxLangId_Nordic_850, FOXNO850, 'FOXNO850' ); // FoxPro Nordic 850 + RegisterCollation( FoxLangId_Nordic_1252, FOXNOWIN, 'FOXNOWIN' ); // FoxPro Nordic 1252 + + //RegisterCollation( XXXXXXXXXXXX, BLROM800 ); // SQL Link ROMAN8 + //RegisterCollation( XXXXXXXXXXXX, db2andeu ); // DB2 SQL ANSI DEU + //RegisterCollation( XXXXXXXXXXXX, SYDC437 ); // Sybase SQL Dic437 + //RegisterCollation( XXXXXXXXXXXX, SYDC850 ); // Sybase SQL Dic850 + //RegisterCollation( XXXXXXXXXXXX, ORAWE850 ); // Oracle SQL WE850 + + //RegisterCollation( XXXXXXXXXXXX, ACCGEN ); // Access General + //RegisterCollation( XXXXXXXXXXXX, ACCGREEK ); // Access Greece + //RegisterCollation( XXXXXXXXXXXX, ACCJAPAN ); // Access Japanese + //RegisterCollation( XXXXXXXXXXXX, ACCNRDAN ); // Access Nord/Danish + //RegisterCollation( XXXXXXXXXXXX, ACCSWFIN ); // Access Swed/Finnish + + //RegisterCollation( XXXXXXXXXXXX, ancyrr ); // Pdox ANSI Cyrillic + //RegisterCollation( XXXXXXXXXXXX, anczech ); // Pdox ANSI Czech + //RegisterCollation( XXXXXXXXXXXX, anczechw ); // pdx ANSI Czech 'CH' + //RegisterCollation( XXXXXXXXXXXX, angreek1 ); // Pdox ANSI Greek + //RegisterCollation( XXXXXXXXXXXX, ANHEBREW ); // Paradox ANSI HEBREW + //RegisterCollation( XXXXXXXXXXXX, anhundc ); // Pdox ANSI Hun. DC + //RegisterCollation( XXXXXXXXXXXX, anil2czw ); // pdx ANSI ISO L_2 CZ + //RegisterCollation( XXXXXXXXXXXX, anpolish ); // Pdox ANSI Polish + //RegisterCollation( XXXXXXXXXXXX, ANSII850 ); // Pdox ANSI Intl850 + //RegisterCollation( XXXXXXXXXXXX, ANSIINTL ); // Pdox ANSI Intl + //RegisterCollation( XXXXXXXXXXXX, ANSINOR4 ); // Pdox ANSI Nordan4 + //RegisterCollation( XXXXXXXXXXXX, ansislov ); // Pdox ANSI Slovene + //RegisterCollation( XXXXXXXXXXXX, ANSISPAN ); // Pdox ANSI Spanish + //RegisterCollation( XXXXXXXXXXXX, ANSISWFN ); // Pdox ANSI Swedfin + //RegisterCollation( XXXXXXXXXXXX, ANTURK ); // Pdox ANSI Turkish + //RegisterCollation( XXXXXXXXXXXX, china ); // Paradox China 936 + //RegisterCollation( XXXXXXXXXXXX, cskamen ); // Paradox Czech 867 + //RegisterCollation( XXXXXXXXXXXX, cskamenw ); // pdx Czech 867 'CH' + //RegisterCollation( XXXXXXXXXXXX, cyrr ); // Paradox Cyrr 866 + //RegisterCollation( XXXXXXXXXXXX, czech ); // Paradox Czech 852 + //RegisterCollation( XXXXXXXXXXXX, czechw ); // pdx Czech 852 'CH' + //RegisterCollation( XXXXXXXXXXXX, grcp437 ); // Paradox Greek GR437 + //RegisterCollation( XXXXXXXXXXXX, hebrew ); // Paradox 'hebrew' + //RegisterCollation( XXXXXXXXXXXX, hun852dc ); // Paradox Hun 852 DC + //RegisterCollation( XXXXXXXXXXXX, iceland ); // Paradox ISL 861 + //RegisterCollation( XXXXXXXXXXXX, il2czw ); // pdx ISO L_2 Czech + //RegisterCollation( XXXXXXXXXXXX, intl ); // Paradox 'intl' + //RegisterCollation( XXXXXXXXXXXX, intl850 ); // Paradox 'intl' 850 + //RegisterCollation( XXXXXXXXXXXX, japan ); // Paradox 'japan' + //RegisterCollation( XXXXXXXXXXXX, korea ); // Paradox Korea 949 + //RegisterCollation( XXXXXXXXXXXX, nordan ); // Paradox 'nordan' + //RegisterCollation( XXXXXXXXXXXX, nordan40 ); // Paradox 'nordan40' + //RegisterCollation( XXXXXXXXXXXX, polish ); // Paradox Polish 852 + //RegisterCollation( XXXXXXXXXXXX, slovene ); // Paradox Slovene 852 + //RegisterCollation( XXXXXXXXXXXX, SPANISH ); // Paradox ESP 437 + //RegisterCollation( XXXXXXXXXXXX, swedfin ); // Paradox 'swedfin' + //RegisterCollation( XXXXXXXXXXXX, taiwan ); // Paradox Taiwan 950 + //RegisterCollation( XXXXXXXXXXXX, thai ); // Paradox Thai 874 + //RegisterCollation( XXXXXXXXXXXX, turk ); // Paradox 'turk' + +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_common.inc b/mseide-msegui/lib/common/fpccompatibility/dbf_common.inc new file mode 100644 index 0000000..ef4e275 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_common.inc @@ -0,0 +1,262 @@ +// define this if you need more SPEEEEEDDDD!!! +// useful if you index dbf files over a network + +{.$define USE_CACHE} + +// define the following if you want support for 65535 length character +// fields for all dbase files (and not only foxpro); if you define this, +// you will not be able to read MS Excel generated .dbf files! + +{.$define USE_LONG_CHAR_FIELDS} + +// modifies unix unit dbf_wtil to use hungarian encodings (hack) + +{.$define HUNGARIAN} + +// enables assembler routines, 486+ only + +{$define USE_ASSEMBLER_486_UP} + +// test compatibility + +{.$define TDBF_UPDATE_FIRSTLAST_NODE} + +// use this directive to suppress math exceptions, +// instead NAN is returned. +// Using this directive is slightly less efficient +// +// used in Dbf_PrsDef +// +// NAN support needs to be rewritten and is currently absent + +{.$define NAN} + +//------------------------------------------------------ +//--- Define all SUPPORT_xxx; undef if not supported --- +//------------------------------------------------------ + + +//------------------------------------------------------ +//--- Delphi versions --- +//------------------------------------------------------ + + +{$ifdef VER80} // Delphi 1.0 + #ERROR tDbf needs Delphi or C++ Builder 3 minimum. +{$endif} + +{$ifdef VER90} // Delphi 2.0 + #ERROR tDbf needs Delphi or C++ Builder 3 minimum. +{$endif} + +{$ifdef VER93} // is BCB++ 1.0 + #ERROR tDbf needs Delphi or C++ Builder 3 minimum. +{$endif} + +{$ifdef VER100} // Delphi 3 + {$define DELPHI_3} +{$endif} + +{$ifdef VER110} // CBuilder 3 + {$define DELPHI_3} +{$endif} + +{$ifdef VER120} // Delphi 4 + {$define DELPHI_4} + {$define DELPHI_3} +{$endif} + +{$ifdef VER125} // C++ BUILDER 4 + {$define DELPHI_4} + {$define DELPHI_3} +{$endif} + +{$ifdef VER130} // Delphi 5 + {$define DELPHI_5} + {$define DELPHI_4} + {$define DELPHI_3} +{$endif} + +{$ifdef VER135} // C++ Builder 5 ?? + {$define DELPHI_5} + {$define DELPHI_4} + {$define DELPHI_3} +{$endif} + +{$ifdef VER140} // Delphi 6 + {$define DELPHI_6} + {$define DELPHI_5} + {$define DELPHI_4} + {$define DELPHI_3} +{$endif} + +{$ifdef VER145} // C++ Builder 6 + {$define DELPHI_6} + {$define DELPHI_5} + {$define DELPHI_4} + {$define DELPHI_3} +{$endif} + +{$ifdef VER150} // Delphi 7 :-) For once I am not late (12/07/2001) + {$define DELPHI_7} + {$define DELPHI_6} + {$define DELPHI_5} + {$define DELPHI_4} + {$define DELPHI_3} +{$endif} + +{$ifdef VER155} // C++ Builder 7 + {$define DELPHI_7} + {$define DELPHI_6} + {$define DELPHI_5} + {$define DELPHI_4} + {$define DELPHI_3} +{$endif} + +{$ifdef VER160} // Delphi 8 + {$define DELPHI_2005} + {$define DELPHI_8} + {$define DELPHI_7} + {$define DELPHI_6} + {$define DELPHI_5} + {$define DELPHI_4} + {$define DELPHI_3} +{$endif} + +{$ifdef VER170} // Delphi 2005 + {$define DELPHI_2005} + {$define DELPHI_8} + {$define DELPHI_7} + {$define DELPHI_6} + {$define DELPHI_5} + {$define DELPHI_4} + {$define DELPHI_3} +{$endif} + +{$ifdef VER180} // Delphi 2006 + {$define DELPHI_2006} + {$define DELPHI_2005} + {$define DELPHI_8} + {$define DELPHI_7} + {$define DELPHI_6} + {$define DELPHI_5} + {$define DELPHI_4} + {$define DELPHI_3} +{$endif} + +{$ifdef VER185} // Delphi 2007 + {$define DELPHI_2007} + { Delphi 2007 also defines VER180, so other DELPHI defines already done } +{$endif} + +//------------------------------------------------------- +//--- Conclude supported features from delphi version --- +//------------------------------------------------------- + +{$ifdef DELPHI_3} + + {$define SUPPORT_VARIANTS} + {$define WINDOWS} + {$define ENDIAN_LITTLE} + +{$ifdef DELPHI_4} + + {$define SUPPORT_DEFCHANGED} + {$define SUPPORT_DEFAULT_PARAMS} + {$define SUPPORT_OVERLOAD} + {$define SUPPORT_NEW_TRANSLATE} + {$define SUPPORT_INT64} + {$define SUPPORT_REINTRODUCE} + {$define SUPPORT_FIELDDEFS_UPDATED} + {$define SUPPORT_FIELDDEF_ATTRIBUTES} + {$define SUPPORT_FIELDDEF_TPERSISTENT} + {$define SUPPORT_FIELDDEF_INDEX} + {$define SUPPORT_FIELDTYPES_V4} + {$define SUPPORT_UINT32_CARDINAL} + {$define SUPPORT_MATH_UNIT} + +{$ifdef DELPHI_5} + + {$define SUPPORT_BACKWARD_FIELDDATA} + {$define SUPPORT_INITDEFSFROMFIELDS} + {$define SUPPORT_REFRESHEVENTS} + {$define SUPPORT_DEF_DELETE} + {$define SUPPORT_FREEANDNIL} + +{$ifdef DELPHI_6} + + {$define SUPPORT_PATHDELIM} + {$define SUPPORT_SEPARATE_VARIANTS_UNIT} + +{$endif} +{$endif} +{$endif} +{$endif} + +//------------------------------------------------------ +//--- Conclude supported features in FreePascal --- +//------------------------------------------------------ + +{$ifdef FPC_VERSION} + + {$mode delphi} + {$h+} + +{$ifndef CPUI386} + {$undef USE_ASSEMBLER_486_UP} +{$endif} + +{$ifdef USE_ASSEMBLER_486_UP} + {$asmmode intel} +{$endif} + + {$define SUPPORT_INT64} + {$define SUPPORT_DEFAULT_PARAMS} + {$define SUPPORT_OVERLOAD} + {$define SUPPORT_NEW_TRANSLATE} + {$define SUPPORT_FIELDDEF_TPERSISTENT} + {$define SUPPORT_FIELDTYPES_V4} + {$define SUPPORT_UINT32_CARDINAL} + {$define SUPPORT_REINTRODUCE} + {$define SUPPORT_MATH_UNIT} + {$define SUPPORT_VARIANTS} + {$define SUPPORT_SEPARATE_VARIANTS_UNIT} + {$define SUPPORT_REFRESHEVENTS} + + // FPC 2.0.x improvements + {$ifdef VER2} + {$ifndef VER2_0_0} + {$define SUPPORT_BACKWARD_FIELDDATA} + {$endif} + {$endif} + + // FPC 1.0.x exceptions: no 0/0 support + {$ifdef VER1_0} + {$undef NAN} + {$undef SUPPORT_DEFAULT_PARAMS} + {$undef SUPPORT_NEW_TRANSLATE} + + {$message error TDbf needs fpc 1.9 minimum.} + + {$endif} + +{$endif} + +//---------------------------------------------------------- +//--- Conclude supported features in non-Windows platforms --- +//---------------------------------------------------------- + +{$ifndef WINDOWS} + + {$define SUPPORT_PATHDELIM} + {$define SUPPORT_INCLUDETRAILPATHDELIM} + {$define SUPPORT_INCLUDETRAILBACKSLASH} + +{$endif} + +{$ifndef ENDIAN_LITTLE} +{$ifndef ENDIAN_BIG} +{$error Neither ENDIAN_LITTLE nor ENDIAN_BIG defined!} +{$endif} +{$endif} + diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_common.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_common.pas new file mode 100644 index 0000000..cb4bd94 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_common.pas @@ -0,0 +1,455 @@ +unit dbf_common; + +// Modified 2013 by Martin Schreiber + +interface + +{$I dbf_common.inc} + +uses + SysUtils, classes,mclasses,mdb +{$ifndef WINDOWS} + , Types, dbf_wtil +{$ifdef KYLIX} + , Libc +{$endif} +{$endif} + ; + + +const + TDBF_MAJOR_VERSION = 6; + TDBF_MINOR_VERSION = 9; + TDBF_SUB_MINOR_VERSION = 2; + + TDBF_TABLELEVEL_FOXPRO = 25; + + JulianDateDelta = 1721425; { number of days between 1.1.4714 BC and "0" } + +type + EDbfError = class (EDatabaseError); + EDbfWriteError = class (EDbfError); + + TDbfFieldType = char; + + TXBaseVersion = (xUnknown, xClipper, xBaseIII, xBaseIV, xBaseV, xFoxPro, xBaseVII); + TSearchKeyType = (stEqual, stGreaterEqual, stGreater); + + TDateTimeHandling = (dtDateTime, dtBDETimeStamp); + +//------------------------------------- + + PDateTime = ^TDateTime; +{$ifndef FPC_VERSION} + PtrInt = Longint; +{$endif} + + PSmallInt = ^SmallInt; + PCardinal = ^Cardinal; + PDouble = ^Double; + PString = ^String; + +{$ifdef DELPHI_3} + dword = cardinal; +{$endif} + +//------------------------------------- + +{$ifndef SUPPORT_FREEANDNIL} +// some procedures for the less lucky who don't have newer versions yet :-) +procedure FreeAndNil(var v); +{$endif} +procedure FreeMemAndNil(var P: Pointer); + +//------------------------------------- + +{$ifndef SUPPORT_PATHDELIM} +const +{$ifdef msWINDOWS} + PathDelim = '\'; +{$else} + PathDelim = '/'; +{$endif} +{$endif} + +{$ifndef SUPPORT_INCLTRAILPATHDELIM} +function IncludeTrailingPathDelimiter(const Path: string): string; +{$endif} + +//------------------------------------- + +function GetCompletePath(const Base, Path: string): string; +function GetCompleteFileName(const Base, FileName: string): string; +function IsFullFilePath(const Path: string): Boolean; // full means not relative +function DateTimeToBDETimeStamp(aDT: TDateTime): double; +function BDETimeStampToDateTime(aBT: double): TDateTime; +procedure FindNextName(BaseName: string; var OutName: string; var Modifier: Integer); +{$ifdef USE_CACHE} +function GetFreeMemory: Integer; +{$endif} + +function SwapWordBE(const Value: word): word; +function SwapWordLE(const Value: word): word; +function SwapIntBE(const Value: dword): dword; +function SwapIntLE(const Value: dword): dword; +{$ifdef SUPPORT_INT64} +procedure SwapInt64BE(Value, Result: Pointer); register; +procedure SwapInt64LE(Value, Result: Pointer); register; +{$endif} + +function TranslateString(FromCP, ToCP: Cardinal; Src, Dest: PChar; Length: Integer): Integer; + +// Returns a pointer to the first occurence of Chr in Str within the first Length characters +// Does not stop at null (#0) terminator! +function MemScan(const Buffer: Pointer; Chr: Byte; Length: Integer): Pointer; + +// Delphi 3 does not have a Min function +{$ifdef DELPHI_3} +{$ifndef DELPHI_4} +function Min(x, y: integer): integer; +function Max(x, y: integer): integer; +{$endif} +{$endif} + +implementation + +{$ifdef msWINDOWS} +uses + Windows; +{$endif} + +//==================================================================== + +function GetCompletePath(const Base, Path: string): string; +begin + if IsFullFilePath(Path) + then begin + Result := Path; + end else begin + if Length(Base) > 0 then + Result := ExpandFileName(IncludeTrailingPathDelimiter(Base) + Path) + else + Result := ExpandFileName(Path); + end; + + // add last backslash if not present + if Length(Result) > 0 then + Result := IncludeTrailingPathDelimiter(Result); +end; + +function IsFullFilePath(const Path: string): Boolean; // full means not relative +begin +{$ifdef msWINDOWS} + Result := Length(Path) > 1; + if Result then + // check for 'x:' or '\\' at start of path + Result := ((Path[2]=':') and (upcase(Path[1]) in ['A'..'Z'])) + or ((Path[1]='\') and (Path[2]='\')); +{$else} // Linux + Result := Length(Path) > 0; + if Result then + Result := Path[1]='/'; + {$endif} +end; + +//==================================================================== + +function GetCompleteFileName(const Base, FileName: string): string; +var + lpath: string; + lfile: string; +begin + lpath := GetCompletePath(Base, ExtractFilePath(FileName)); + lfile := ExtractFileName(FileName); + lpath := lpath + lfile; + result := lpath; +end; + +function DateTimeToBDETimeStamp(aDT: TDateTime): double; +var + aTS: TTimeStamp; +begin + aTS := DateTimeToTimeStamp(aDT); + Result := TimeStampToMSecs(aTS); +end; + +function BDETimeStampToDateTime(aBT: double): TDateTime; +var + aTS: TTimeStamp; +begin + aTS := MSecsToTimeStamp(Round(aBT)); + Result := TimeStampToDateTime(aTS); +end; + +//==================================================================== + +{$ifndef SUPPORT_FREEANDNIL} + +procedure FreeAndNil(var v); +var + Temp: TObject; +begin + Temp := TObject(v); + TObject(v) := nil; + Temp.Free; +end; + +{$endif} + +procedure FreeMemAndNil(var P: Pointer); +var + Temp: Pointer; +begin + Temp := P; + P := nil; + FreeMem(Temp); +end; + +//==================================================================== + +{$ifndef SUPPORT_INCLTRAILPATHDELIM} +{$ifndef SUPPORT_INCLTRAILBACKSLASH} + +function IncludeTrailingPathDelimiter(const Path: string): string; +var + len: Integer; +begin + Result := Path; + len := Length(Result); + if len = 0 then + Result := PathDelim + else + if Result[len] <> PathDelim then + Result := Result + PathDelim; +end; + +{$else} + +function IncludeTrailingPathDelimiter(const Path: string): string; +begin +{$ifdef msWINDOWS} + Result := IncludeTrailingBackslash(Path); +{$else} + Result := IncludeTrailingSlash(Path); +{$endif} +end; + +{$endif} +{$endif} + +{$ifdef USE_CACHE} + +function GetFreeMemory: Integer; +var + MemStatus: TMemoryStatus; +begin + GlobalMemoryStatus(MemStatus); + Result := MemStatus.dwAvailPhys; +end; + +{$endif} + +//==================================================================== +// Utility routines +//==================================================================== + +{$ifdef ENDIAN_LITTLE} +function SwapWordBE(const Value: word): word; +{$else} +function SwapWordLE(const Value: word): word; +{$endif} +begin + Result := ((Value and $FF) shl 8) or ((Value shr 8) and $FF); +end; + +{$ifdef ENDIAN_LITTLE} +function SwapWordLE(const Value: word): word; +{$else} +function SwapWordBE(const Value: word): word; +{$endif} +begin + Result := Value; +end; + +{$ifdef FPC} + +function SwapIntBE(const Value: dword): dword; +begin + Result := BEtoN(Value); +end; + +function SwapIntLE(const Value: dword): dword; +begin + Result := LEtoN(Value); +end; + +procedure SwapInt64BE(Value, Result: Pointer); +begin + PInt64(Result)^ := BEtoN(PInt64(Value)^); +end; + +procedure SwapInt64LE(Value, Result: Pointer); +begin + PInt64(Result)^ := LEtoN(PInt64(Value)^); +end; + +{$else} +{$ifdef USE_ASSEMBLER_486_UP} + +function SwapIntBE(const Value: dword): dword; register; assembler; +asm + BSWAP EAX; +end; + +procedure SwapInt64BE(Value {EAX}, Result {EDX}: Pointer); register; assembler; +asm + MOV ECX, dword ptr [EAX] + MOV EAX, dword ptr [EAX + 4] + BSWAP ECX + BSWAP EAX + MOV dword ptr [EDX+4], ECX + MOV dword ptr [EDX], EAX +end; + +{$else} + +function SwapIntBE(const Value: Cardinal): Cardinal; +begin + PByteArray(@Result)[0] := PByteArray(@Value)[3]; + PByteArray(@Result)[1] := PByteArray(@Value)[2]; + PByteArray(@Result)[2] := PByteArray(@Value)[1]; + PByteArray(@Result)[3] := PByteArray(@Value)[0]; +end; + +procedure SwapInt64BE(Value, Result: Pointer); register; +var + PtrResult: PByteArray; + PtrSource: PByteArray; +begin + // temporary storage is actually not needed, but otherwise compiler crashes (?) + PtrResult := PByteArray(Result); + PtrSource := PByteArray(Value); + PtrResult[0] := PtrSource[7]; + PtrResult[1] := PtrSource[6]; + PtrResult[2] := PtrSource[5]; + PtrResult[3] := PtrSource[4]; + PtrResult[4] := PtrSource[3]; + PtrResult[5] := PtrSource[2]; + PtrResult[6] := PtrSource[1]; + PtrResult[7] := PtrSource[0]; +end; + +{$endif} + +function SwapIntLE(const Value: dword): dword; +begin + Result := Value; +end; + +{$ifdef SUPPORT_INT64} + +procedure SwapInt64LE(Value, Result: Pointer); +begin + PInt64(Result)^ := PInt64(Value)^; +end; + +{$endif} + +{$endif} + +function TranslateString(FromCP, ToCP: Cardinal; Src, Dest: PChar; Length: Integer): Integer; +var + WideCharStr: array[0..1023] of WideChar; + wideBytes: Cardinal; +begin + if Length = -1 then + Length := StrLen(Src); + Result := Length; +{$ifndef WINCE} + if (FromCP = GetOEMCP) and (ToCP = GetACP) then + OemToCharBuff(Src, Dest, Length) + else + if (FromCP = GetACP) and (ToCP = GetOEMCP) then + CharToOemBuff(Src, Dest, Length) + else +{$endif} + if FromCP = ToCP then + begin + if Src <> Dest then + Move(Src^, Dest^, Length); + end else begin + // does this work on Win95/98/ME? + wideBytes := MultiByteToWideChar(FromCP, MB_PRECOMPOSED, Src, Length, LPWSTR(@WideCharStr[0]), 1024); + Result := WideCharToMultiByte(ToCP, 0, LPWSTR(@WideCharStr[0]), wideBytes, Dest, Length, nil, nil); + end; +end; + +procedure FindNextName(BaseName: string; var OutName: string; var Modifier: Integer); +var + Extension: string; +begin + Extension := ExtractFileExt(BaseName); + BaseName := Copy(BaseName, 1, Length(BaseName)-Length(Extension)); + repeat + Inc(Modifier); + OutName := ChangeFileExt(BaseName+'_'+IntToStr(Modifier), Extension); + until not FileExists(OutName); +end; + +{$ifdef FPC} + +function MemScan(const Buffer: Pointer; Chr: Byte; Length: Integer): Pointer; +var + I: Integer; +begin + I := System.IndexByte(Buffer, Length, Chr); + if I = -1 then + Result := nil + else + Result := Buffer+I; +end; + +{$else} + +function MemScan(const Buffer: Pointer; Chr: Byte; Length: Integer): Pointer; +asm + PUSH EDI + MOV EDI,Buffer + MOV AL, Chr + MOV ECX,Length + REPNE SCASB + MOV EAX,0 + JNE @@1 + MOV EAX,EDI + DEC EAX +@@1: POP EDI +end; + +{$endif} + +{$ifdef DELPHI_3} +{$ifndef DELPHI_4} + +function Min(x, y: integer): integer; +begin + if x < y then + result := x + else + result := y; +end; + +function Max(x, y: integer): integer; +begin + if x < y then + result := y + else + result := x; +end; + +{$endif} +{$endif} + +end. + + + diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_cursor.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_cursor.pas new file mode 100644 index 0000000..7f106f2 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_cursor.pas @@ -0,0 +1,64 @@ +unit dbf_cursor; + +interface + +{$I dbf_common.inc} + +uses + SysUtils, + classes,mclasses, + dbf_pgfile, + dbf_common; + +type + +//==================================================================== + TVirtualCursor = class(TObject) + private + FFile: TPagedFile; + + protected + function GetPhysicalRecNo: Integer; virtual; abstract; + function GetSequentialRecNo: Integer; virtual; abstract; + function GetSequentialRecordCount: Integer; virtual; abstract; + procedure SetPhysicalRecNo(RecNo: Integer); virtual; abstract; + procedure SetSequentialRecNo(RecNo: Integer); virtual; abstract; + + public + constructor Create(pFile: TPagedFile); + destructor Destroy; override; + + function RecordSize: Integer; + + function Next: Boolean; virtual; abstract; + function Prev: Boolean; virtual; abstract; + procedure First; virtual; abstract; + procedure Last; virtual; abstract; + + property PagedFile: TPagedFile read FFile; + property PhysicalRecNo: Integer read GetPhysicalRecNo write SetPhysicalRecNo; + property SequentialRecNo: Integer read GetSequentialRecNo write SetSequentialRecNo; + property SequentialRecordCount: Integer read GetSequentialRecordCount; + end; + +implementation + +constructor TVirtualCursor.Create(pFile: TPagedFile); +begin + FFile := pFile; +end; + +destructor TVirtualCursor.Destroy; {override;} +begin +end; + +function TVirtualCursor.RecordSize : Integer; +begin + if FFile = nil then + Result := 0 + else + Result := FFile.RecordSize; +end; + +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_dbffile.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_dbffile.pas new file mode 100644 index 0000000..b90e03b --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_dbffile.pas @@ -0,0 +1,2848 @@ +unit dbf_dbffile; + +// Modified 2013 by Martin Schreiber + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{$I dbf_common.inc} + +uses + classes,mclasses,SysUtils, +{$ifdef msWINDOWS} + Windows, +{$else} +{$ifdef KYLIX} + Libc, +{$endif} + Types, dbf_wtil, +{$endif} + mdb, + dbf_common, + dbf_cursor, + dbf_pgfile, + dbf_fields, + dbf_memo, + dbf_idxfile; + +//==================================================================== +//=== Dbf support (first part) +//==================================================================== +// TxBaseVersion = (xUnknown,xClipper,xBaseIII,xBaseIV,xBaseV,xFoxPro,xVisualFoxPro); +// TPagedFileMode = (pfOpen,pfCreate); +// TDbfGetMode = (xFirst,xPrev,xCurrent, xNext, xLast); +// TDbfGetResult = (xOK, xBOF, xEOF, xError); + +type + +//==================================================================== + TDbfIndexMissingEvent = procedure(var DeleteLink: Boolean) of object; + TUpdateNullField = (unClear, unSet); + +//==================================================================== + TDbfGlobals = class; +//==================================================================== + + TDbfFile = class(TPagedFile) + protected + FMdxFile: TIndexFile; + FMemoFile: TMemoFile; + FFieldDefs: TDbfFieldDefs; + FIndexNames: TStringList; + FIndexFiles: TList; + FDbfVersion: TXBaseVersion; + FPrevBuffer: TRecordBuffer; + FDefaultBuffer: TRecordBuffer; + FRecordBufferSize: Integer; + FLockUserLen: DWORD; + FFileCodePage: Cardinal; + FUseCodePage: Cardinal; + FFileLangId: Byte; + FCountUse: Integer; + FCurIndex: Integer; + FForceClose: Boolean; + FLockField: TDbfFieldDef; + FNullField: TDbfFieldDef; + FAutoIncPresent: Boolean; + FCopyDateTimeAsString: Boolean; + FDateTimeHandling: TDateTimeHandling; + FOnLocaleError: TDbfLocaleErrorEvent; + FOnIndexMissing: TDbfIndexMissingEvent; + + function HasBlob: Boolean; + function GetMemoExt: string; + + function GetLanguageId: Integer; + function GetLanguageStr: string; + + protected + procedure ConstructFieldDefs; + procedure InitDefaultBuffer; + procedure UpdateNullField(Buffer: Pointer; AFieldDef: TDbfFieldDef; Action: TUpdateNullField); + procedure WriteLockInfo(Buffer: TRecordBuffer); + + public + constructor Create; + destructor Destroy; override; + + procedure Open; + procedure Close; + procedure Zap; + + procedure FinishCreate(AFieldDefs: TDbfFieldDefs; MemoSize: Integer); + function GetIndexByName(AIndexName: string): TIndexFile; + procedure SetRecordSize(NewSize: Integer); override; + + procedure TryExclusive; override; + procedure EndExclusive; override; + procedure OpenIndex(IndexName, IndexField: string; CreateIndex: Boolean; Options: TIndexOptions); + function DeleteIndex(const AIndexName: string): Boolean; + procedure CloseIndex(AIndexName: string); + procedure RepageIndex(AIndexFile: string); + procedure CompactIndex(AIndexFile: string); + function Insert(Buffer: TRecordBuffer): integer; + procedure WriteHeader; override; + procedure ApplyAutoIncToBuffer(DestBuf: TRecordBuffer); // dBase7 support. Writeback last next-autoinc value + procedure FastPackTable; + procedure RestructureTable(DbfFieldDefs: TDbfFieldDefs; Pack: Boolean); + procedure Rename(DestFileName: string; NewIndexFileNames: TStrings; DeleteFiles: boolean); + function GetFieldInfo(FieldName: string): TDbfFieldDef; + function GetFieldData(Column: Integer; DataType: TFieldType; Src,Dst: Pointer; + NativeFormat: boolean): Boolean; + function GetFieldDataFromDef(AFieldDef: TDbfFieldDef; DataType: TFieldType; + Src, Dst: Pointer; NativeFormat: boolean): Boolean; + procedure SetFieldData(Column: Integer; DataType: TFieldType; Src,Dst: Pointer; NativeFormat: boolean); + procedure InitRecord(DestBuf: TRecordBuffer); + procedure PackIndex(lIndexFile: TIndexFile; AIndexName: string); + procedure RegenerateIndexes; + procedure LockRecord(RecNo: Integer; Buffer: TRecordBuffer); + procedure UnlockRecord(RecNo: Integer; Buffer: TRecordBuffer); + procedure RecordDeleted(RecNo: Integer; Buffer: TRecordBuffer); + procedure RecordRecalled(RecNo: Integer; Buffer: TRecordBuffer); + + property MemoFile: TMemoFile read FMemoFile; + property FieldDefs: TDbfFieldDefs read FFieldDefs; + property IndexNames: TStringList read FIndexNames; + property IndexFiles: TList read FIndexFiles; + property MdxFile: TIndexFile read FMdxFile; + property LanguageId: Integer read GetLanguageId; + property LanguageStr: string read GetLanguageStr; + property FileCodePage: Cardinal read FFileCodePage; + property UseCodePage: Cardinal read FUseCodePage write FUseCodePage; + property FileLangId: Byte read FFileLangId write FFileLangId; + property DbfVersion: TXBaseVersion read FDbfVersion write FDbfVersion; + property PrevBuffer: TRecordBuffer read FPrevBuffer; + property ForceClose: Boolean read FForceClose; + property CopyDateTimeAsString: Boolean read FCopyDateTimeAsString write FCopyDateTimeAsString; + property DateTimeHandling: TDateTimeHandling read FDateTimeHandling write FDateTimeHandling; + + property OnIndexMissing: TDbfIndexMissingEvent read FOnIndexMissing write FOnIndexMissing; + property OnLocaleError: TDbfLocaleErrorEvent read FOnLocaleError write FOnLocaleError; + end; + +//==================================================================== + TDbfCursor = class(TVirtualCursor) + protected + FPhysicalRecNo: Integer; + public + constructor Create(DbfFile: TDbfFile); + function Next: Boolean; override; + function Prev: Boolean; override; + procedure First; override; + procedure Last; override; + + function GetPhysicalRecNo: Integer; override; + procedure SetPhysicalRecNo(RecNo: Integer); override; + + function GetSequentialRecordCount: Integer; override; + function GetSequentialRecNo: Integer; override; + procedure SetSequentialRecNo(RecNo: Integer); override; + end; + +//==================================================================== + TDbfGlobals = class + protected + FCodePages: TList; + FCurrencyAsBCD: Boolean; + FDefaultOpenCodePage: Integer; + FDefaultCreateLangId: Byte; + FUserName: string; + FUserNameLen: DWORD; + + function GetDefaultCreateCodePage: Integer; + procedure SetDefaultCreateCodePage(NewCodePage: Integer); + procedure InitUserName; + public + constructor Create; + destructor Destroy; override; + + function CodePageInstalled(ACodePage: Integer): Boolean; + + property CurrencyAsBCD: Boolean read FCurrencyAsBCD write FCurrencyAsBCD; + property DefaultOpenCodePage: Integer read FDefaultOpenCodePage write FDefaultOpenCodePage; + property DefaultCreateCodePage: Integer read GetDefaultCreateCodePage write SetDefaultCreateCodePage; + property DefaultCreateLangId: Byte read FDefaultCreateLangId write FDefaultCreateLangId; + property UserName: string read FUserName; + property UserNameLen: DWORD read FUserNameLen; + end; + +var + DbfGlobals: TDbfGlobals; + +implementation + +uses +{$ifndef WINDOWS} +{$ifndef FPC} + RTLConsts, +{$else} + BaseUnix, +{$endif} +{$endif} +{$ifdef SUPPORT_MATH_UNIT} + Math, +{$endif} + dbf_str, dbf_lang, mdbf_prssupp, mdbf_prsdef; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + sDBF_DEC_SEP = '.'; + +{$I dbf_struct.inc} + +//==================================================================== +// International separator +// thanks to Bruno Depero from Italy +// and Andreas W�nstein from Denmark +//==================================================================== +function DbfStrToFloat(const Src: PChar; const Size: Integer): Extended; +var + iPos: PChar; + eValue: extended; + endChar: Char; +begin + // temp null-term string + endChar := (Src + Size)^; + (Src + Size)^ := #0; + // we only have to convert if decimal separator different +{$warnings off} + if DecimalSeparator <> sDBF_DEC_SEP then +{$warnings on} + begin + // search dec sep + iPos := StrScan(Src, sDBF_DEC_SEP); + // replace + if iPos <> nil then +{$warnings off} + iPos^ := DecimalSeparator; +{$warnings on} + end else + iPos := nil; + // convert to double + if TextToFloat(Src, eValue {$ifndef VER1_0}, fvExtended{$endif}) then + Result := eValue + else + Result := 0; + // restore dec sep + if iPos <> nil then + iPos^ := sDBF_DEC_SEP; + // restore Char of null-term + (Src + Size)^ := endChar; +end; + +procedure FloatToDbfStr(const Val: Extended; const Size, Precision: Integer; const Dest: PChar); +var + Buffer: array [0..24] of Char; + resLen: Integer; + iPos: PChar; +begin + // convert to temporary buffer + resLen := FloatToText(@Buffer[0], Val, {$ifndef FPC_VERSION}fvExtended,{$endif} ffFixed, Size, Precision); + // prevent overflow in destination buffer + if resLen > Size then + resLen := Size; + // null-terminate buffer + Buffer[resLen] := #0; + // we only have to convert if decimal separator different +{$warnings off} + if DecimalSeparator <> sDBF_DEC_SEP then +{$warnings on} + begin +{$warnings off} + iPos := StrScan(@Buffer[0], DecimalSeparator); +{$warnings on} + if iPos <> nil then + iPos^ := sDBF_DEC_SEP; + end; + // fill destination with spaces + FillChar(Dest^, Size, ' '); + // now copy right-aligned to destination + Move(Buffer[0], Dest[Size-resLen], resLen); +end; + +function GetIntFromStrLength(Src: Pointer; Size: Integer; Default: Integer): Integer; +var + endChar: Char; + Code: Integer; +begin + // save Char at pos term. null + endChar := (PChar(Src) + Size)^; + (PChar(Src) + Size)^ := #0; + // convert + Val(PChar(Src), Result, Code); + // check success + if Code <> 0 then + Result := Default; + // restore prev. ending Char + (PChar(Src) + Size)^ := endChar; +end; + +//==================================================================== +// TDbfFile +//==================================================================== +constructor TDbfFile.Create; +begin + // init variables first + FFieldDefs := TDbfFieldDefs.Create(nil); + FIndexNames := TStringList.Create; + FIndexFiles := TList.Create; + + // now initialize inherited + inherited; +end; + +destructor TDbfFile.Destroy; +var + I: Integer; +begin + // close file + Close; + + // free files + for I := 0 to Pred(FIndexFiles.Count) do + TPagedFile(FIndexFiles.Items[I]).Free; + + // free lists + FreeAndNil(FIndexFiles); + FreeAndNil(FIndexNames); + FreeAndNil(FFieldDefs); + + // call ancestor + inherited; +end; + +procedure TDbfFile.Open; +var + lMemoFileName: string; + lMdxFileName: string; + MemoFileClass: TMemoFileClass; + I: Integer; + deleteLink: Boolean; + lModified: boolean; + LangStr: PChar; + version: byte; +begin + // check if not already opened + if not Active then + begin + // open requested file + OpenFile; + + // check if we opened an already existing file + lModified := false; + if not FileCreated then + begin + HeaderSize := sizeof(rDbfHdr); // temporary + // OH 2000-11-15 dBase7 support. I build dBase Tables with different + // BDE dBase Level (1. without Memo, 2. with Memo) + // Header Byte ($1d hex) (29 dec) -> Language driver ID. + // $03,$83 xBaseIII Header Byte $1d=$00, Float -> N($13.$04) DateTime C($1E) + // $03,$8B xBaseIV/V Header Byte $1d=$58, Float -> N($14.$04) + // $04,$8C xBaseVII Header Byte $1d=$00 Float -> O($08) DateTime @($08) + // $03,$F5 FoxPro Level 25 Header Byte $1d=$03, Float -> N($14.$04) + // Access 97 + // $03,$83 dBaseIII Header Byte $1d=$00, Float -> N($13.$05) DateTime D($08) + // $03,$8B dBaseIV/V Header Byte $1d=$00, Float -> N($14.$05) DateTime D($08) + // $03,$F5 FoxPro Level 25 Header Byte $1d=$09, Float -> N($14.$05) DateTime D($08) + + version := PDbfHdr(Header)^.VerDBF; + case (version and $07) of + $03: + if LanguageID = 0 then + FDbfVersion := xBaseIII + else + FDbfVersion := xBaseIV; + $04: + FDbfVersion := xBaseVII; + $02, $05: + FDbfVersion := xFoxPro; + else + // check visual foxpro + if ((version and $FE) = $30) or (version = $F5) or (version = $FB) then + begin + FDbfVersion := xFoxPro; + end else begin + // not a valid DBF file + raise EDbfError.Create(STRING_INVALID_DBF_FILE); + end; + end; + FFieldDefs.DbfVersion := FDbfVersion; + RecordSize := PDbfHdr(Header)^.RecordSize; + HeaderSize := PDbfHdr(Header)^.FullHdrSize; + if (HeaderSize = 0) or (RecordSize = 0) then + begin + HeaderSize := 0; + RecordSize := 0; + RecordCount := 0; + FForceClose := true; + exit; + end; + // check if specified recordcount correct + if PDbfHdr(Header)^.RecordCount <> RecordCount then + begin + // This message was annoying + // and was not understood by most people + // ShowMessage('Invalid Record Count,'+^M+ + // 'RecordCount in Hdr : '+IntToStr(PDbfHdr(Header).RecordCount)+^M+ + // 'expected : '+IntToStr(RecordCount)); + PDbfHdr(Header)^.RecordCount := RecordCount; + lModified := true; + end; + // determine codepage + if FDbfVersion >= xBaseVII then + begin + // cache language str + LangStr := @PAfterHdrVII(PChar(Header) + SizeOf(rDbfHdr))^.LanguageDriverName; + // VdBase 7 Language strings + // 'DBWIN...' -> Charset 1252 (ansi) + // 'DB999...' -> Code page 999, 9 any digit + // 'DBHEBREW' -> Code page 1255 ?? + // 'FOX..999' -> Code page 999, 9 any digit + // 'FOX..WIN' -> Charset 1252 (ansi) + if (LangStr[0] = 'D') and (LangStr[1] = 'B') then + begin + if StrLComp(LangStr+2, 'WIN', 3) = 0 then + FFileCodePage := 1252 + else + if StrLComp(LangStr+2, 'HEBREW', 6) = 0 then + begin + FFileCodePage := 1255; + end else begin + FFileCodePage := GetIntFromStrLength(LangStr+2, 3, 0); + if (Ord(LangStr[5]) >= Ord('0')) and (Ord(LangStr[5]) <= Ord('9')) then + FFileCodePage := FFileCodePage * 10 + Ord(LangStr[5]) - Ord('0'); + end; + end else + if StrLComp(LangStr, 'FOX', 3) = 0 then + begin + if StrLComp(LangStr+5, 'WIN', 3) = 0 then + FFileCodePage := 1252 + else + FFileCodePage := GetIntFromStrLength(LangStr+5, 3, 0) + end else begin + FFileCodePage := 0; + end; + FFileLangId := GetLangId_From_LangName(LanguageStr); + end else begin + // FDbfVersion <= xBaseV + FFileLangId := PDbfHdr(Header)^.Language; + FFileCodePage := LangId_To_CodePage[FFileLangId]; + end; + // determine used codepage, if no codepage, then use default codepage + FUseCodePage := FFileCodePage; + if FUseCodePage = 0 then + FUseCodePage := DbfGlobals.DefaultOpenCodePage; + // get list of fields + ConstructFieldDefs; + // open blob file if present + lMemoFileName := ChangeFileExt(FileName, GetMemoExt); + if HasBlob then + begin + // open blob file + if not FileExists(lMemoFileName) then + MemoFileClass := TNullMemoFile + else if FDbfVersion = xFoxPro then + MemoFileClass := TFoxProMemoFile + else + MemoFileClass := TDbaseMemoFile; + FMemoFile := MemoFileClass.Create(Self); + FMemoFile.FileName := lMemoFileName; + FMemoFile.Mode := Mode; + FMemoFile.AutoCreate := false; + FMemoFile.MemoRecordSize := 0; + FMemoFile.DbfVersion := FDbfVersion; + FMemoFile.Open; + // set header blob flag corresponding to field list + if FDbfVersion <> xFoxPro then + begin + PDbfHdr(Header)^.VerDBF := PDbfHdr(Header)^.VerDBF or $80; + lModified := true; + end; + end else + if FDbfVersion <> xFoxPro then + begin + PDbfHdr(Header)^.VerDBF := PDbfHdr(Header)^.VerDBF and $7F; + lModified := true; + end; + // check if mdx flagged + if (FDbfVersion <> xFoxPro) and (PDbfHdr(Header)^.MDXFlag <> 0) then + begin + // open mdx file if present + lMdxFileName := ChangeFileExt(FileName, '.mdx'); + if FileExists(lMdxFileName) then + begin + // open file + FMdxFile := TIndexFile.Create(Self); + FMdxFile.FileName := lMdxFileName; + FMdxFile.Mode := Mode; + FMdxFile.AutoCreate := false; + FMdxFile.OnLocaleError := FOnLocaleError; + FMdxFile.CodePage := UseCodePage; + FMdxFile.Open; + // is index ready for use? + if not FMdxFile.ForceClose then + begin + FIndexFiles.Add(FMdxFile); + // get index tag names known + FMdxFile.GetIndexNames(FIndexNames); + end else begin + // asked to close! close file + FreeAndNil(FMdxFile); + end; + end else begin + // ask user + deleteLink := true; + if Assigned(FOnIndexMissing) then + FOnIndexMissing(deleteLink); + // correct flag + if deleteLink then + begin + PDbfHdr(Header)^.MDXFlag := 0; + lModified := true; + end else + FForceClose := true; + end; + end; + end; + + // record changes + if lModified then + WriteHeader; + + // open indexes + for I := 0 to FIndexFiles.Count - 1 do + TIndexFile(FIndexFiles.Items[I]).Open; + end; +end; + +procedure TDbfFile.Close; +var + MdxIndex, I: Integer; +begin + if Active then + begin + // close index files first + MdxIndex := -1; + for I := 0 to FIndexFiles.Count - 1 do + begin + TIndexFile(FIndexFiles.Items[I]).Close; + if TIndexFile(FIndexFiles.Items[I]) = FMdxFile then + MdxIndex := I; + end; + // free memo file if any + FreeAndNil(FMemoFile); + + // now we can close physical dbf file + CloseFile; + + // free FMdxFile, remove it from the FIndexFiles and Names lists + if MdxIndex >= 0 then + FIndexFiles.Delete(MdxIndex); + I := 0; + while I < FIndexNames.Count do + begin + if FIndexNames.Objects[I] = FMdxFile then + begin + FIndexNames.Delete(I); + end else begin + Inc(I); + end; + end; + FreeAndNil(FMdxFile); + FreeMemAndNil(Pointer(FPrevBuffer)); + FreeMemAndNil(Pointer(FDefaultBuffer)); + + // reset variables + FFileLangId := 0; + end; +end; + +procedure TDbfFile.FinishCreate(AFieldDefs: TDbfFieldDefs; MemoSize: Integer); +var + lFieldDescIII: rFieldDescIII; + lFieldDescVII: rFieldDescVII; + lFieldDescPtr: Pointer; + lFieldDef: TDbfFieldDef; + lMemoFileName: string; + I, lFieldOffset, lSize, lPrec: Integer; + lHasBlob: Boolean; + lLocaleID: LCID; + +begin + try + // first reset file + RecordCount := 0; + lHasBlob := false; + // determine codepage & locale + if FFileLangId = 0 then + FFileLangId := DbfGlobals.DefaultCreateLangId; + FFileCodePage := LangId_To_CodePage[FFileLangId]; + lLocaleID := LangId_To_Locale[FFileLangId]; + FUseCodePage := FFileCodePage; + // prepare header size + if FDbfVersion = xBaseVII then + begin + // version xBaseVII without memo + HeaderSize := SizeOf(rDbfHdr) + SizeOf(rAfterHdrVII); + RecordSize := SizeOf(rFieldDescVII); + FillChar(Header^, HeaderSize, #0); + PDbfHdr(Header)^.VerDBF := $04; + // write language string + StrPLCopy( + @PAfterHdrVII(PChar(Header)+SizeOf(rDbfHdr))^.LanguageDriverName[32], + ConstructLangName(FFileCodePage, lLocaleID, false), + 63-32); + lFieldDescPtr := @lFieldDescVII; + end else begin + // version xBaseIII/IV/V without memo + HeaderSize := SizeOf(rDbfHdr) + SizeOf(rAfterHdrIII); + RecordSize := SizeOf(rFieldDescIII); + FillChar(Header^, HeaderSize, #0); + if FDbfVersion = xFoxPro then + begin + PDbfHdr(Header)^.VerDBF := $02 + end else + PDbfHdr(Header)^.VerDBF := $03; + // standard language WE, dBase III no language support + if FDbfVersion = xBaseIII then + PDbfHdr(Header)^.Language := 0 + else + PDbfHdr(Header)^.Language := FFileLangId; + // init field ptr + lFieldDescPtr := @lFieldDescIII; + end; + // begin writing fields + FFieldDefs.Clear; + // deleted mark 1 byte + lFieldOffset := 1; + for I := 1 to AFieldDefs.Count do + begin + lFieldDef := AFieldDefs.Items[I-1]; + + // check if datetime conversion + if FCopyDateTimeAsString then + if lFieldDef.FieldType = ftDateTime then + begin + // convert to string + lFieldDef.FieldType := ftString; + lFieldDef.Size := 22; + end; + + // update source + lFieldDef.FieldName := AnsiUpperCase(lFieldDef.FieldName); + lFieldDef.Offset := lFieldOffset; + lHasBlob := lHasBlob or lFieldDef.IsBlob; + + // apply field transformation tricks + lSize := lFieldDef.Size; + lPrec := lFieldDef.Precision; + if (lFieldDef.NativeFieldType = 'C') +{$ifndef USE_LONG_CHAR_FIELDS} + and (FDbfVersion = xFoxPro) +{$endif} + then + begin + lPrec := lSize shr 8; + lSize := lSize and $FF; + end; + + // update temp field props + if FDbfVersion = xBaseVII then + begin + FillChar(lFieldDescVII, SizeOf(lFieldDescVII), #0); + StrPLCopy(lFieldDescVII.FieldName, lFieldDef.FieldName, SizeOf(lFieldDescVII.FieldName)-1); + lFieldDescVII.FieldType := lFieldDef.NativeFieldType; + lFieldDescVII.FieldSize := lSize; + lFieldDescVII.FieldPrecision := lPrec; + lFieldDescVII.NextAutoInc := SwapIntLE(lFieldDef.AutoInc); + //lFieldDescVII.MDXFlag := ??? + end else begin + FillChar(lFieldDescIII, SizeOf(lFieldDescIII), #0); + StrPLCopy(lFieldDescIII.FieldName, lFieldDef.FieldName, SizeOf(lFieldDescIII.FieldName)-1); + lFieldDescIII.FieldType := lFieldDef.NativeFieldType; + lFieldDescIII.FieldSize := lSize; + lFieldDescIII.FieldPrecision := lPrec; + if FDbfVersion = xFoxPro then + lFieldDescIII.FieldOffset := SwapIntLE(lFieldOffset); + if (PDbfHdr(Header)^.VerDBF = $02) and (lFieldDef.NativeFieldType in ['0', 'Y', 'T', 'O', '+']) then + PDbfHdr(Header)^.VerDBF := $30; + if (PDbfHdr(Header)^.VerDBF = $30) and (lFieldDef.NativeFieldType = '+') then + PDbfHdr(Header)^.VerDBF := $31; + end; + + // update our field list + with FFieldDefs.AddFieldDef do + begin + Assign(lFieldDef); + Offset := lFieldOffset; + AutoInc := 0; + end; + + // save field props + WriteRecord(I, lFieldDescPtr); + Inc(lFieldOffset, lFieldDef.Size); + end; + // end of header + WriteChar($0D); + + // write memo bit + if lHasBlob then + begin + if FDbfVersion = xBaseIII then + PDbfHdr(Header)^.VerDBF := PDbfHdr(Header)^.VerDBF or $80 + else + if FDbfVersion = xFoxPro then + begin + if PDbfHdr(Header)^.VerDBF = $02 then + PDbfHdr(Header)^.VerDBF := $F5; + end else + PDbfHdr(Header)^.VerDBF := PDbfHdr(Header)^.VerDBF or $88; + end; + + // update header + PDbfHdr(Header)^.RecordSize := lFieldOffset; + PDbfHdr(Header)^.FullHdrSize := HeaderSize + RecordSize * AFieldDefs.Count + 1; + // add empty "back-link" info, whatever it is: + { A 263-byte range that contains the backlink, which is the relative path of + an associated database (.dbc) file, information. If the first byte is 0x00, + the file is not associated with a database. Therefore, database files always + contain 0x00. } + if FDbfVersion = xFoxPro then + Inc(PDbfHdr(Header)^.FullHdrSize, 263); + + // write dbf header to disk + inherited WriteHeader; + finally + RecordSize := PDbfHdr(Header)^.RecordSize; + HeaderSize := PDbfHdr(Header)^.FullHdrSize; + + // write full header to disk (dbf+fields) + WriteHeader; + end; + + if HasBlob and (FMemoFile=nil) then + begin + lMemoFileName := ChangeFileExt(FileName, GetMemoExt); + if FDbfVersion = xFoxPro then + FMemoFile := TFoxProMemoFile.Create(Self) + else + FMemoFile := TDbaseMemoFile.Create(Self); + FMemoFile.FileName := lMemoFileName; + FMemoFile.Mode := Mode; + FMemoFile.AutoCreate := AutoCreate; + FMemoFile.MemoRecordSize := MemoSize; + FMemoFile.DbfVersion := FDbfVersion; + FMemoFile.Open; + end; +end; + +function TDbfFile.HasBlob: Boolean; +var + I: Integer; +begin + Result := false; + for I := 0 to FFieldDefs.Count-1 do + if FFieldDefs.Items[I].IsBlob then + Result := true; +end; + +function TDbfFile.GetMemoExt: string; +begin + if FDbfVersion = xFoxPro then + Result := '.fpt' + else + Result := '.dbt'; +end; + +procedure TDbfFile.Zap; +begin + // make recordcount zero + RecordCount := 0; + // update recordcount + PDbfHdr(Header)^.RecordCount := RecordCount; + // update disk header + WriteHeader; + // update indexes + RegenerateIndexes; +end; + +procedure TDbfFile.WriteHeader; +var + SystemTime: TSystemTime; + lDataHdr: PDbfHdr; + EofTerminator: Byte; +begin + if (HeaderSize=0) then + exit; + + //FillHeader(0); + lDataHdr := PDbfHdr(Header); + GetLocalTime(SystemTime); + lDataHdr^.Year := SystemTime.wYear - 1900; + lDataHdr^.Month := SystemTime.wMonth; + lDataHdr^.Day := SystemTime.wDay; +// lDataHdr.RecordCount := RecordCount; + inherited WriteHeader; + + EofTerminator := $1A; + WriteBlock(@EofTerminator, 1, CalcPageOffset(RecordCount+1)); +end; + +procedure TDbfFile.ConstructFieldDefs; +var + {lColumnCount,}lHeaderSize,lFieldSize: Integer; + lPropHdrOffset, lFieldOffset: Integer; + lFieldDescIII: rFieldDescIII; + lFieldDescVII: rFieldDescVII; + lFieldPropsHdr: rFieldPropsHdr; + lStdProp: rStdPropEntry; + TempFieldDef: TDbfFieldDef; + lSize,lPrec,I, lColumnCount: Integer; + lAutoInc: Cardinal; + dataPtr: PChar; + lNativeFieldType: Char; + lFieldName: string; + lCanHoldNull: boolean; + lCurrentNullPosition: integer; +begin + FFieldDefs.Clear; + if DbfVersion >= xBaseVII then + begin + lHeaderSize := SizeOf(rAfterHdrVII) + SizeOf(rDbfHdr); + lFieldSize := SizeOf(rFieldDescVII); + end else begin + lHeaderSize := SizeOf(rAfterHdrIII) + SizeOf(rDbfHdr); + lFieldSize := SizeOf(rFieldDescIII); + end; + HeaderSize := lHeaderSize; + RecordSize := lFieldSize; + + FLockField := nil; + FNullField := nil; + FAutoIncPresent := false; + lColumnCount := (PDbfHdr(Header)^.FullHdrSize - lHeaderSize) div lFieldSize; + lFieldOffset := 1; + lAutoInc := 0; + I := 1; + lCurrentNullPosition := 0; + lCanHoldNull := false; + try + // there has to be minimum of one field + repeat + // version field info? + if FDbfVersion >= xBaseVII then + begin + ReadRecord(I, @lFieldDescVII); + lFieldName := AnsiUpperCase(PChar(@lFieldDescVII.FieldName[0])); + lSize := lFieldDescVII.FieldSize; + lPrec := lFieldDescVII.FieldPrecision; + lNativeFieldType := lFieldDescVII.FieldType; + lAutoInc := SwapIntLE(lFieldDescVII.NextAutoInc); + if lNativeFieldType = '+' then + FAutoIncPresent := true; + end else begin + ReadRecord(I, @lFieldDescIII); + lFieldName := AnsiUpperCase(PChar(@lFieldDescIII.FieldName[0])); + lSize := lFieldDescIII.FieldSize; + lPrec := lFieldDescIII.FieldPrecision; + lNativeFieldType := lFieldDescIII.FieldType; + lCanHoldNull := (FDbfVersion = xFoxPro) and + ((lFieldDescIII.FoxProFlags and $2) <> 0) and + (lFieldName <> '_NULLFLAGS'); + end; + + // apply field transformation tricks + if (lNativeFieldType = 'C') +{$ifndef USE_LONG_CHAR_FIELDS} + and (FDbfVersion = xFoxPro) +{$endif} + then + begin + lSize := lSize + lPrec shl 8; + lPrec := 0; + end; + + // add field + TempFieldDef := FFieldDefs.AddFieldDef; + with TempFieldDef do + begin + FieldName := lFieldName; + Offset := lFieldOffset; + Size := lSize; + Precision := lPrec; + AutoInc := lAutoInc; + NativeFieldType := lNativeFieldType; + if lCanHoldNull then + begin + NullPosition := lCurrentNullPosition; + inc(lCurrentNullPosition); + end else + NullPosition := -1; + end; + + // check valid field: + // 1) non-empty field name + // 2) known field type + // {3) no changes have to be made to precision or size} + if (Length(lFieldName) = 0) or (TempFieldDef.FieldType = ftUnknown) then + raise EDbfError.Create(STRING_INVALID_DBF_FILE); + + // determine if lock field present, if present, then store additional info + if lFieldName = '_DBASELOCK' then + begin + FLockField := TempFieldDef; + FLockUserLen := lSize - 8; + if FLockUserLen > DbfGlobals.UserNameLen then + FLockUserLen := DbfGlobals.UserNameLen; + end else + if UpperCase(lFieldName) = '_NULLFLAGS' then + FNullField := TempFieldDef; + + // goto next field + Inc(lFieldOffset, lSize); + Inc(I); + + // continue until header termination character found + // or end of header reached + until (I > lColumnCount) or (ReadChar = $0D); + + // test if not too many fields + if FFieldDefs.Count >= 4096 then + raise EDbfError.CreateFmt(STRING_INVALID_FIELD_COUNT, [FFieldDefs.Count]); + + // do not check FieldOffset = PDbfHdr(Header).RecordSize because additional + // data could be present in record + + // get current position + lPropHdrOffset := Stream.Position; + + // dBase 7 -> read field properties, test if enough space, maybe no header + if (FDbfVersion = xBaseVII) and (lPropHdrOffset + Sizeof(lFieldPropsHdr) < + PDbfHdr(Header)^.FullHdrSize) then + begin + // read in field properties header + ReadBlock(@lFieldPropsHdr, SizeOf(lFieldPropsHdr), lPropHdrOffset); + // read in standard properties + lFieldOffset := lPropHdrOffset + lFieldPropsHdr.StartStdProps; + for I := 0 to lFieldPropsHdr.NumStdProps - 1 do + begin + // read property data + ReadBlock(@lStdProp, SizeOf(lStdProp), lFieldOffset+I*SizeOf(lStdProp)); + // is this a constraint? + if lStdProp.FieldOffset = 0 then + begin + // this is a constraint...not implemented + end else if lStdProp.FieldOffset <= FFieldDefs.Count then begin + // get fielddef for this property + TempFieldDef := FFieldDefs.Items[lStdProp.FieldOffset-1]; + // allocate space to store data + TempFieldDef.AllocBuffers; + // dataPtr = nil -> no data to retrieve + dataPtr := nil; + // store data + case lStdProp.PropType of + FieldPropType_Required: TempFieldDef.Required := true; + FieldPropType_Default: + begin + dataPtr := TempFieldDef.DefaultBuf; + TempFieldDef.HasDefault := true; + end; + FieldPropType_Min: + begin + dataPtr := TempFieldDef.MinBuf; + TempFieldDef.HasMin := true; + end; + FieldPropType_Max: + begin + dataPtr := TempFieldDef.MaxBuf; + TempFieldDef.HasMax := true; + end; + end; + // get data for this property + if dataPtr <> nil then + ReadBlock(dataPtr, lStdProp.DataSize, lPropHdrOffset + lStdProp.DataOffset); + end; + end; + // read custom properties...not implemented + // read RI properties...not implemented + end; + finally + HeaderSize := PDbfHdr(Header)^.FullHdrSize; + RecordSize := PDbfHdr(Header)^.RecordSize; + end; +end; + +function TDbfFile.GetLanguageId: Integer; +begin + Result := PDbfHdr(Header)^.Language; +end; + +function TDbfFile.GetLanguageStr: String; +begin + result:= ''; + if FDbfVersion >= xBaseVII then + Result := PAfterHdrVII(PChar(Header) + SizeOf(rDbfHdr))^.LanguageDriverName; +end; + +{ + I fill the holes with the last records. + now we can do an 'in-place' pack +} +procedure TDbfFile.FastPackTable; +var + iDel,iNormal: Integer; + pDel,pNormal: PChar; + + function FindFirstDel: Boolean; + begin + while iDel<=iNormal do + begin + ReadRecord(iDel, pDel); + if (PChar(pDel)^ <> ' ') then + begin + Result := true; + exit; + end; + Inc(iDel); + end; + Result := false; + end; + + function FindLastNormal: Boolean; + begin + while iNormal>=iDel do + begin + ReadRecord(iNormal, pNormal); + if (PChar(pNormal)^= ' ') then + begin + Result := true; + exit; + end; + dec(iNormal); + end; + Result := false; + end; + +begin + if RecordSize < 1 then Exit; + + GetMem(pNormal, RecordSize); + GetMem(pDel, RecordSize); + try + iDel := 1; + iNormal := RecordCount; + + while FindFirstDel do + begin + // iDel is definitely deleted + if FindLastNormal then + begin + // but is not anymore + WriteRecord(iDel, pNormal); + PChar(pNormal)^ := '*'; + WriteRecord(iNormal, pNormal); + end else begin + // Cannot found a record after iDel so iDel must be deleted + dec(iDel); + break; + end; + end; + // FindFirstDel failed means than iDel is full + RecordCount := iDel; + RegenerateIndexes; + // Pack Memofields + finally + FreeMem(pNormal); + FreeMem(pDel); + end; +end; + +procedure TDbfFile.Rename(DestFileName: string; NewIndexFileNames: TStrings; DeleteFiles: boolean); +var + lIndexFileNames: TStrings; + lIndexFile: TIndexFile; + NewBaseName: string; + I: integer; +begin + // get memory for index file list + lIndexFileNames := TStringList.Create; + try + // save index filenames + for I := 0 to FIndexFiles.Count - 1 do + begin + lIndexFile := TIndexFile(IndexFiles[I]); + lIndexFileNames.Add(lIndexFile.FileName); + // prepare changing the dbf file name, needs changes in index files + lIndexFile.PrepareRename(NewIndexFileNames[I]); + end; + + // close file + Close; + + if DeleteFiles then + begin + SysUtils.DeleteFile(DestFileName); + SysUtils.DeleteFile(ChangeFileExt(DestFileName, GetMemoExt)); + end else begin + I := 0; + FindNextName(DestFileName, NewBaseName, I); + SysUtils.RenameFile(DestFileName, NewBaseName); + SysUtils.RenameFile(ChangeFileExt(DestFileName, GetMemoExt), + ChangeFileExt(NewBaseName, GetMemoExt)); + end; + // delete old index files + for I := 0 to NewIndexFileNames.Count - 1 do + SysUtils.DeleteFile(NewIndexFileNames.Strings[I]); + // rename the new dbf files + SysUtils.RenameFile(FileName, DestFileName); + SysUtils.RenameFile(ChangeFileExt(FileName, GetMemoExt), + ChangeFileExt(DestFileName, GetMemoExt)); + // rename new index files + for I := 0 to NewIndexFileNames.Count - 1 do + SysUtils.RenameFile(lIndexFileNames.Strings[I], NewIndexFileNames.Strings[I]); + finally + lIndexFileNames.Free; + end; +end; + +type + TRestructFieldInfo = record + SourceOffset: Integer; + DestOffset: Integer; + Size: Integer; + end; + + { assume nobody has more than 8192 fields, otherwise possibly range check error } + PRestructFieldInfo = ^TRestructFieldInfoArray; + TRestructFieldInfoArray = array[0..8191] of TRestructFieldInfo; + +procedure TDbfFile.RestructureTable(DbfFieldDefs: TDbfFieldDefs; Pack: Boolean); +var + DestDbfFile: TDbfFile; + TempIndexDef: TDbfIndexDef; + TempIndexFile: TIndexFile; + DestFieldDefs: TDbfFieldDefs; + TempDstDef, TempSrcDef: TDbfFieldDef; + OldIndexFiles: TStrings; + IndexName, NewBaseName: string; + I, lRecNo, lFieldNo, lFieldSize, lBlobPageNo, lWRecNo, srcOffset, dstOffset: Integer; + pBuff, pDestBuff: TRecordBuffer; + RestructFieldInfo: PRestructFieldInfo; + BlobStream: TMemoryStream; +begin + // nothing to do? + if (RecordSize < 1) or ((DbfFieldDefs = nil) and not Pack) then + exit; + + // if no exclusive access, terrible things can happen! + CheckExclusiveAccess; + + // make up some temporary filenames + lRecNo := 0; + FindNextName(FileName, NewBaseName, lRecNo); + + // select final field definition list + if DbfFieldDefs = nil then + begin + DestFieldDefs := FFieldDefs; + end else begin + DestFieldDefs := DbfFieldDefs; + // copy autoinc values + for I := 0 to DbfFieldDefs.Count - 1 do + begin + lFieldNo := DbfFieldDefs.Items[I].CopyFrom; + if (lFieldNo >= 0) and (lFieldNo < FFieldDefs.Count) then + DbfFieldDefs.Items[I].AutoInc := FFieldDefs.Items[lFieldNo].AutoInc; + end; + end; + + // create temporary dbf + DestDbfFile := TDbfFile.Create; + DestDbfFile.FileName := NewBaseName; + DestDbfFile.AutoCreate := true; + DestDbfFile.Mode := pfExclusiveCreate; + DestDbfFile.OnIndexMissing := FOnIndexMissing; + DestDbfFile.OnLocaleError := FOnLocaleError; + DestDbfFile.DbfVersion := FDbfVersion; + DestDbfFile.FileLangId := FileLangId; + DestDbfFile.Open; + // create dbf header + if FMemoFile <> nil then + DestDbfFile.FinishCreate(DestFieldDefs, FMemoFile.RecordSize) + else + DestDbfFile.FinishCreate(DestFieldDefs, 512); + + // adjust size and offsets of fields + GetMem(RestructFieldInfo, sizeof(TRestructFieldInfo)*DestFieldDefs.Count); + for lFieldNo := 0 to DestFieldDefs.Count - 1 do + begin + TempDstDef := DestFieldDefs.Items[lFieldNo]; + if TempDstDef.CopyFrom >= 0 then + begin + TempSrcDef := FFieldDefs.Items[TempDstDef.CopyFrom]; + if TempDstDef.NativeFieldType in ['F', 'N'] then + begin + // get minimum field length + lFieldSize := Min(TempSrcDef.Precision, TempDstDef.Precision) + + Min(TempSrcDef.Size - TempSrcDef.Precision, + TempDstDef.Size - TempDstDef.Precision); + // if one has dec separator, but other not, we lose one digit + if (TempDstDef.Precision > 0) xor + ((TempSrcDef.NativeFieldType in ['F', 'N']) and (TempSrcDef.Precision > 0)) then + Dec(lFieldSize); + // should not happen, but check nevertheless (maybe corrupt data) + if lFieldSize < 0 then + lFieldSize := 0; + srcOffset := TempSrcDef.Size - TempSrcDef.Precision - + (TempDstDef.Size - TempDstDef.Precision); + if srcOffset < 0 then + begin + dstOffset := -srcOffset; + srcOffset := 0; + end else begin + dstOffset := 0; + end; + end else begin + lFieldSize := Min(TempSrcDef.Size, TempDstDef.Size); + srcOffset := 0; + dstOffset := 0; + end; + with RestructFieldInfo[lFieldNo] do + begin + Size := lFieldSize; + SourceOffset := TempSrcDef.Offset + srcOffset; + DestOffset := TempDstDef.Offset + dstOffset; + end; + end; + end; + + // add indexes + TempIndexDef := TDbfIndexDef.Create(nil); + for I := 0 to FIndexNames.Count - 1 do + begin + // get length of extension -> determines MDX or NDX + IndexName := FIndexNames.Strings[I]; + TempIndexFile := TIndexFile(FIndexNames.Objects[I]); + TempIndexFile.GetIndexInfo(IndexName, TempIndexDef); + if Length(ExtractFileExt(IndexName)) > 0 then + begin + // NDX index, get unique file name + lRecNo := 0; + FindNextName(IndexName, IndexName, lRecNo); + end; + // add this index + DestDbfFile.OpenIndex(IndexName, TempIndexDef.SortField, true, TempIndexDef.Options); + end; + TempIndexDef.Free; + + // get memory for record buffers + GetMem(pBuff, RecordSize); + BlobStream := TMemoryStream.Create; + OldIndexFiles := TStringList.Create; + // if restructure, we need memory for dest buffer, otherwise use source + if DbfFieldDefs = nil then + pDestBuff := pBuff + else + GetMem(pDestBuff, DestDbfFile.RecordSize); + + // let the games begin! + try +{$ifdef USE_CACHE} + BufferAhead := true; + DestDbfFile.BufferAhead := true; +{$endif} + lWRecNo := 1; + for lRecNo := 1 to RecordCount do + begin + // read record from original dbf + ReadRecord(lRecNo, pBuff); + // copy record? + if (ansichar(pBuff^) <> '*') or not Pack then + begin + // if restructure, initialize dest + if DbfFieldDefs <> nil then + begin + DestDbfFile.InitRecord(pDestBuff); + // copy deleted mark (the first byte) + pDestBuff^ := pBuff^; + end; + + if (DbfFieldDefs <> nil) or (FMemoFile <> nil) then + begin + // copy fields + for lFieldNo := 0 to DestFieldDefs.Count-1 do + begin + TempDstDef := DestFieldDefs.Items[lFieldNo]; + // handle blob fields differently + // don't try to copy new blob fields! + // DbfFieldDefs = nil -> pack only + // TempDstDef.CopyFrom >= 0 -> copy existing (blob) field + if TempDstDef.IsBlob and ((DbfFieldDefs = nil) or (TempDstDef.CopyFrom >= 0)) then + begin + // get current blob blockno + GetFieldData(lFieldNo, ftInteger, pBuff, @lBlobPageNo, false); + // valid blockno read? + if lBlobPageNo > 0 then + begin + BlobStream.Clear; + FMemoFile.ReadMemo(lBlobPageNo, BlobStream); + BlobStream.Position := 0; + // always append + DestDbfFile.FMemoFile.WriteMemo(lBlobPageNo, 0, BlobStream); + end; + // write new blockno + DestDbfFile.SetFieldData(lFieldNo, ftInteger, @lBlobPageNo, pDestBuff, false); + end else if (DbfFieldDefs <> nil) and (TempDstDef.CopyFrom >= 0) then + begin + // copy content of field + with RestructFieldInfo[lFieldNo] do + Move(pBuff[SourceOffset], pDestBuff[DestOffset], Size); + end; + end; + end; + + // write record + DestDbfFile.WriteRecord(lWRecNo, pDestBuff); + // update indexes + for I := 0 to DestDbfFile.IndexFiles.Count - 1 do + TIndexFile(DestDbfFile.IndexFiles.Items[I]).Insert(lWRecNo, pDestBuff); + + // go to next record + Inc(lWRecNo); + end; + end; + +{$ifdef USE_CACHE} + BufferAhead := false; + DestDbfFile.BufferAhead := false; +{$endif} + + // save index filenames + for I := 0 to FIndexFiles.Count - 1 do + OldIndexFiles.Add(TIndexFile(IndexFiles[I]).FileName); + + // close dbf + Close; + + // if restructure -> rename the old dbf files + // if pack only -> delete the old dbf files + DestDbfFile.Rename(FileName, OldIndexFiles, DbfFieldDefs = nil); + + // we have to reinit fielddefs if restructured + Open; + + // crop deleted records + RecordCount := lWRecNo - 1; + // update date/time stamp, recordcount + PDbfHdr(Header)^.RecordCount := RecordCount; + WriteHeader; + finally + // close temporary file + FreeAndNil(DestDbfFile); + // free mem + FreeAndNil(OldIndexFiles); + FreeMem(pBuff); + FreeAndNil(BlobStream); + FreeMem(RestructFieldInfo); + if DbfFieldDefs <> nil then + FreeMem(pDestBuff); + end; +end; + +procedure TDbfFile.RegenerateIndexes; +var + lIndexNo: Integer; +begin + // recreate every index in every file + for lIndexNo := 0 to FIndexFiles.Count-1 do + begin + PackIndex(TIndexFile(FIndexFiles.Items[lIndexNo]), EmptyStr); + end; +end; + +function TDbfFile.GetFieldInfo(FieldName: string): TDbfFieldDef; +var + I: Integer; + lfi: TDbfFieldDef; +begin + FieldName := AnsiUpperCase(FieldName); + for I := 0 to FFieldDefs.Count-1 do + begin + lfi := TDbfFieldDef(FFieldDefs.Items[I]); + if lfi.fieldName = FieldName then + begin + Result := lfi; + exit; + end; + end; + Result := nil; +end; + +// NOTE: Dst may be nil! +function TDbfFile.GetFieldData(Column: Integer; DataType: TFieldType; + Src, Dst: Pointer; NativeFormat: boolean): Boolean; +var + TempFieldDef: TDbfFieldDef; +begin + TempFieldDef := TDbfFieldDef(FFieldDefs.Items[Column]); + Result := GetFieldDataFromDef(TempFieldDef, DataType, Src, Dst, NativeFormat); +end; + +// NOTE: Dst may be nil! +function TDbfFile.GetFieldDataFromDef(AFieldDef: TDbfFieldDef; DataType: TFieldType; + Src, Dst: Pointer; NativeFormat: boolean): Boolean; +var + FieldOffset, FieldSize: Integer; +// s: string; + ldd, ldm, ldy, lth, ltm, lts: Integer; + date: TDateTime; + timeStamp: TTimeStamp; + asciiContents: boolean; + +{$ifdef SUPPORT_INT64} + function GetInt64FromStrLength(Src: Pointer; Size: Integer; Default: Int64): Int64; + var + endChar: Char; + Code: Integer; + begin + // save Char at pos term. null + endChar := (PChar(Src) + Size)^; + (PChar(Src) + Size)^ := #0; + // convert + Val(PChar(Src), Result, Code); + // check success + if Code <> 0 then Result := Default; + // restore prev. ending Char + (PChar(Src) + Size)^ := endChar; + end; +{$endif} + + procedure CorrectYear(var wYear: Integer); + var wD, wM, wY, CenturyBase: Word; +(* +{$ifndef DELPHI_5} + // Delphi 3 standard-behavior no change possible + const TwoDigitYearCenturyWindow= 0; +{$endif} +*) + begin + if wYear >= 100 then + Exit; + DecodeDate(Date, wY, wm, wD); + // use Delphi-Date-Window + CenturyBase := wY{must be CurrentYear} - TwoDigitYearCenturyWindow; + Inc(wYear, CenturyBase div 100 * 100); + if (TwoDigitYearCenturyWindow > 0) and (wYear < CenturyBase) then + Inc(wYear, 100); + end; + + procedure SaveDateToDst; + begin + if not NativeFormat then + begin + // Delphi 5 requests a TDateTime + PDateTime(Dst)^ := date; + end else begin + // Delphi 3 and 4 request a TDateTimeRec + // date is TTimeStamp.date + // datetime = msecs == BDE timestamp as we implemented it + if DataType = ftDateTime then + begin + PDateTimeRec(Dst)^.DateTime := date; + end else begin + PLongInt(Dst)^ := DateTimeToTimeStamp(date).Date; + end; + end; + end; + +begin + // test if non-nil source (record buffer) + if Src = nil then + begin + Result := false; + exit; + end; + + // check Dst = nil, called with dst = nil to check empty field + if (FNullField <> nil) and (Dst = nil) and (AFieldDef.NullPosition >= 0) then + begin + // go to byte with null flag of this field + Src := PChar(Src) + FNullField.Offset + (AFieldDef.NullPosition shr 3); + Result := (PByte(Src)^ and (1 shl (AFieldDef.NullPosition and $7))) <> 0; + exit; + end; + + FieldOffset := AFieldDef.Offset; + FieldSize := AFieldDef.Size; + Src := PChar(Src) + FieldOffset; + asciiContents := false; + Result := true; + // field types that are binary and of which the fieldsize should not be truncated + case AFieldDef.NativeFieldType of + '+', 'I': + begin + if FDbfVersion <> xFoxPro then + begin + Result := PDWord(Src)^ <> 0; + if Result and (Dst <> nil) then + begin + PDWord(Dst)^ := SwapIntBE(PDWord(Src)^); + if Result then + PInteger(Dst)^ := Integer(PDWord(Dst)^ xor $80000000); + end; + end else begin + Result := true; + if Dst <> nil then + PInteger(Dst)^ := SwapIntLE(PInteger(Src)^); + end; + end; + 'O': + begin +{$ifdef SUPPORT_INT64} + Result := PInt64(Src)^ <> 0; + if Result and (Dst <> nil) then + begin + SwapInt64BE(Src, Dst); + if PInt64(Dst)^ > 0 then + PInt64(Dst)^ := not PInt64(Dst)^ + else + PDouble(Dst)^ := PDouble(Dst)^ * -1; + end; +{$endif} + end; + '@': + begin + Result := (PInteger(Src)^ <> 0) and (PInteger(PChar(Src)+4)^ <> 0); + if Result and (Dst <> nil) then + begin + SwapInt64BE(Src, Dst); + if FDateTimeHandling = dtBDETimeStamp then + date := BDETimeStampToDateTime(PDouble(Dst)^) + else + date := PDateTime(Dst)^; + SaveDateToDst; + end; + end; + 'T': + begin + // all binary zeroes -> empty datetime +{$ifdef SUPPORT_INT64} + Result := PInt64(Src)^ <> 0; +{$else} + Result := (PInteger(Src)^ <> 0) or (PInteger(PChar(Src)+4)^ <> 0); +{$endif} + if Result and (Dst <> nil) then + begin + timeStamp.Date := SwapIntLE(PInteger(Src)^) - JulianDateDelta; + timeStamp.Time := SwapIntLE(PInteger(PChar(Src)+4)^); + date := TimeStampToDateTime(timeStamp); + SaveDateToDst; + end; + end; + 'Y': + begin +{$ifdef SUPPORT_INT64} + Result := true; + if Dst <> nil then + begin + PInt64(Dst)^ := SwapIntLE(PInt64(Src)^); + if DataType = ftCurrency then + PDouble(Dst)^ := PInt64(Dst)^ / 10000.0; + end; +{$endif} + end; + 'B': // foxpro double + begin + if FDbfVersion = xFoxPro then + begin + Result := true; + if Dst <> nil then + PInt64(Dst)^ := SwapIntLE(PInt64(Src)^); + end else + asciiContents := true; + end; + 'M': + begin + if FieldSize = 4 then + begin + Result := PInteger(Src)^ <> 0; + if Dst <> nil then + PInteger(Dst)^ := SwapIntLE(PInteger(Src)^); + end else + asciiContents := true; + end; + else + asciiContents := true; + end; + if asciiContents then + begin + // SetString(s, PChar(Src) + FieldOffset, FieldSize ); + // s := {TrimStr(s)} TrimRight(s); + // truncate spaces at end by shortening fieldsize + while (FieldSize > 0) and ((PChar(Src) + FieldSize - 1)^ = ' ') do + dec(FieldSize); + // if not string field, truncate spaces at beginning too + if DataType <> ftString then + while (FieldSize > 0) and (PChar(Src)^ = ' ') do + begin + inc(PChar(Src)); + dec(FieldSize); + end; + // return if field is empty + Result := FieldSize > 0; + if Result and (Dst <> nil) then // data not needed if Result= false or Dst=nil + case DataType of + ftBoolean: + begin + // in DBase- FileDescription lowercase t is allowed too + // with asking for Result= true s must be longer then 0 + // else it happens an AV, maybe field is NULL + if (PChar(Src)^ = 'T') or (PChar(Src)^ = 't') then + PWord(Dst)^ := 1 + else + PWord(Dst)^ := 0; + end; + ftSmallInt: + PSmallInt(Dst)^ := GetIntFromStrLength(Src, FieldSize, 0); +{$ifdef SUPPORT_INT64} + ftLargeInt: + PLargeInt(Dst)^ := GetInt64FromStrLength(Src, FieldSize, 0); +{$endif} + ftInteger: + PInteger(Dst)^ := GetIntFromStrLength(Src, FieldSize, 0); + ftFloat, ftCurrency: + PDouble(Dst)^ := DbfStrToFloat(Src, FieldSize); + ftDate, ftDateTime: + begin + // get year, month, day + ldy := GetIntFromStrLength(PChar(Src) + 0, 4, 1); + ldm := GetIntFromStrLength(PChar(Src) + 4, 2, 1); + ldd := GetIntFromStrLength(PChar(Src) + 6, 2, 1); + //if (ly<1900) or (ly>2100) then ly := 1900; + //Year from 0001 to 9999 is possible + //everyting else is an error, an empty string too + //Do DateCorrection with Delphis possibillities for one or two digits + if (ldy < 100) and (PChar(Src)[0] = #32) and (PChar(Src)[1] = #32) then + CorrectYear(ldy); + try + date := EncodeDate(ldy, ldm, ldd); + except + date := 0; + end; + + // time stored too? + if (AFieldDef.FieldType = ftDateTime) and (DataType = ftDateTime) then + begin + // get hour, minute, second + lth := GetIntFromStrLength(PChar(Src) + 8, 2, 1); + ltm := GetIntFromStrLength(PChar(Src) + 10, 2, 1); + lts := GetIntFromStrLength(PChar(Src) + 12, 2, 1); + // encode + try + date := date + EncodeTime(lth, ltm, lts, 0); + except + date := 0; + end; + end; + + SaveDateToDst; + end; + ftString: + StrLCopy(Dst, Src, FieldSize); + end else begin + case DataType of + ftString: + if Dst <> nil then + PChar(Dst)[0] := #0; + end; + end; + end; +end; + +procedure TDbfFile.UpdateNullField(Buffer: Pointer; AFieldDef: TDbfFieldDef; + Action: TUpdateNullField); +var + NullDst: pbyte; + Mask: byte; +begin + // this field has null setting capability + NullDst := PByte(PChar(Buffer) + FNullField.Offset + (AFieldDef.NullPosition shr 3)); + Mask := 1 shl (AFieldDef.NullPosition and $7); + if Action = unSet then + begin + // clear the field, set null flag + NullDst^ := NullDst^ or Mask; + end else begin + // set field data, clear null flag + NullDst^ := NullDst^ and not Mask; + end; +end; + +procedure TDbfFile.SetFieldData(Column: Integer; DataType: TFieldType; + Src, Dst: Pointer; NativeFormat: boolean); +const + IsBlobFieldToPadChar: array[Boolean] of Char = (#32, '0'); + SrcNilToUpdateNullField: array[boolean] of TUpdateNullField = (unClear, unSet); +var + FieldSize,FieldPrec: Integer; + TempFieldDef: TDbfFieldDef; + Len: Integer; + IntValue: dword; + year, month, day: Word; + hour, minute, sec, msec: Word; + date: TDateTime; + timeStamp: TTimeStamp; + asciiContents: boolean; + + procedure LoadDateFromSrc; + begin + if not NativeFormat then + begin + // Delphi 5, new format, passes a TDateTime + date := PDateTime(Src)^; + end else begin + // Delphi 3 and 4, old "native" format, pass a TDateTimeRec with a time stamp + // date = integer + // datetime = msecs == BDETimeStampToDateTime as we implemented it + if DataType = ftDateTime then + begin + date := PDouble(Src)^; + end else begin + timeStamp.Time := 0; + timeStamp.Date := PLongInt(Src)^; + date := TimeStampToDateTime(timeStamp); + end; + end; + end; + +begin + date:= 0; + TempFieldDef := TDbfFieldDef(FFieldDefs.Items[Column]); + FieldSize := TempFieldDef.Size; + FieldPrec := TempFieldDef.Precision; + + // if src = nil then write empty field + // symmetry with above + + // foxpro has special _nullfield for flagging fields as `null' + if (FNullField <> nil) and (TempFieldDef.NullPosition >= 0) then + UpdateNullField(Dst, TempFieldDef, SrcNilToUpdateNullField[Src = nil]); + + // copy field data to record buffer + Dst := PChar(Dst) + TempFieldDef.Offset; + asciiContents := false; + case TempFieldDef.NativeFieldType of + '+', 'I': + begin + if FDbfVersion <> xFoxPro then + begin + if Src = nil then + IntValue := 0 + else + IntValue := PDWord(Src)^ xor $80000000; + PDWord(Dst)^ := SwapIntBE(IntValue); + end else begin + if Src = nil then + PDWord(Dst)^ := 0 + else + PDWord(Dst)^ := SwapIntLE(PDWord(Src)^); + end; + end; + 'O': + begin +{$ifdef SUPPORT_INT64} + if Src = nil then + begin + PInt64(Dst)^ := 0; + end else begin + if PDouble(Src)^ < 0 then + PInt64(Dst)^ := not PInt64(Src)^ + else + PDouble(Dst)^ := (PDouble(Src)^) * -1; + SwapInt64BE(Dst, Dst); + end; +{$endif} + end; + '@': + begin + if Src = nil then + begin +{$ifdef SUPPORT_INT64} + PInt64(Dst)^ := 0; +{$else} + PInteger(Dst)^ := 0; + PInteger(PChar(Dst)+4)^ := 0; +{$endif} + end else begin + LoadDateFromSrc; + if FDateTimeHandling = dtBDETimeStamp then + date := DateTimeToBDETimeStamp(date); + SwapInt64BE(@date, Dst); + end; + end; + 'T': + begin + // all binary zeroes -> empty datetime + if Src = nil then + begin +{$ifdef SUPPORT_INT64} + PInt64(Dst)^ := 0; +{$else} + PInteger(Dst)^ := 0; + PInteger(PChar(Dst)+4)^ := 0; +{$endif} + end else begin + LoadDateFromSrc; + timeStamp := DateTimeToTimeStamp(date); + PInteger(Dst)^ := SwapIntLE(timeStamp.Date + JulianDateDelta); + PInteger(PChar(Dst)+4)^ := SwapIntLE(timeStamp.Time); + end; + end; + 'Y': + begin +{$ifdef SUPPORT_INT64} + if Src = nil then + begin + PInt64(Dst)^ := 0; + end else begin + case DataType of + ftCurrency: + PInt64(Dst)^ := Trunc(PDouble(Src)^ * 10000); + ftBCD: + PCurrency(Dst)^ := PCurrency(Src)^; + end; + SwapInt64LE(Dst, Dst); + end; +{$endif} + end; + 'B': + begin + if DbfVersion = xFoxPro then + begin + if Src = nil then + PDouble(Dst)^ := 0 + else + SwapInt64LE(Src, Dst); + end else + asciiContents := true; + end; + 'M': + begin + if FieldSize = 4 then + begin + if Src = nil then + PInteger(Dst)^ := 0 + else + PInteger(Dst)^ := SwapIntLE(PInteger(Src)^); + end else + asciiContents := true; + end; + else + asciiContents := true; + end; + if asciiContents then + begin + if Src = nil then + begin + FillChar(Dst^, FieldSize, ' '); + end else begin + case DataType of + ftBoolean: + begin + if PWord(Src)^ <> 0 then + PChar(Dst)^ := 'T' + else + PChar(Dst)^ := 'F'; + end; + ftSmallInt: + GetStrFromInt_Width(PSmallInt(Src)^, FieldSize, PChar(Dst), #32); +{$ifdef SUPPORT_INT64} + ftLargeInt: + GetStrFromInt64_Width(PLargeInt(Src)^, FieldSize, PChar(Dst), #32); +{$endif} + ftFloat, ftCurrency: + FloatToDbfStr(PDouble(Src)^, FieldSize, FieldPrec, PChar(Dst)); + ftInteger: + GetStrFromInt_Width(PInteger(Src)^, FieldSize, PChar(Dst), + IsBlobFieldToPadChar[TempFieldDef.IsBlob]); + ftDate, ftDateTime: + begin + LoadDateFromSrc; + // decode + DecodeDate(date, year, month, day); + // format is yyyymmdd + GetStrFromInt_Width(year, 4, PChar(Dst), '0'); + GetStrFromInt_Width(month, 2, PChar(Dst)+4, '0'); + GetStrFromInt_Width(day, 2, PChar(Dst)+6, '0'); + // do time too if datetime + if DataType = ftDateTime then + begin + DecodeTime(date, hour, minute, sec, msec); + // format is hhmmss + GetStrFromInt_Width(hour, 2, PChar(Dst)+8, '0'); + GetStrFromInt_Width(minute, 2, PChar(Dst)+10, '0'); + GetStrFromInt_Width(sec, 2, PChar(Dst)+12, '0'); + end; + end; + ftString: + begin + // copy data + Len := StrLen(Src); + if Len > FieldSize then + Len := FieldSize; + Move(Src^, Dst^, Len); + // fill remaining space with spaces + FillChar((PChar(Dst)+Len)^, FieldSize - Len, ' '); + end; + end; // case datatype + end; + end; +end; + +procedure TDbfFile.InitDefaultBuffer; +var + lRecordSize: integer; + TempFieldDef: TDbfFieldDef; + I: Integer; +begin + lRecordSize := PDbfHdr(Header)^.RecordSize; + // clear buffer (assume all string, fix specific fields later) + // note: Self.RecordSize is used for reading fielddefs too + GetMem(FDefaultBuffer, lRecordSize+1); + FillChar(FDefaultBuffer^, lRecordSize, ' '); + + // set nullflags field so that all fields are null + if FNullField <> nil then + FillChar(PChar(FDefaultBuffer+FNullField.Offset)^, FNullField.Size, $FF); + + // check binary and default fields + for I := 0 to FFieldDefs.Count-1 do + begin + TempFieldDef := FFieldDefs.Items[I]; + // binary field? (foxpro memo fields are binary, but dbase not) + if (TempFieldDef.NativeFieldType in ['I', 'O', '@', '+', '0', 'Y']) + or ((TempFieldDef.NativeFieldType = 'M') and (TempFieldDef.Size = 4)) then + FillChar(PChar(FDefaultBuffer+TempFieldDef.Offset)^, TempFieldDef.Size, 0); + // copy default value? + if TempFieldDef.HasDefault then + begin + Move(TempFieldDef.DefaultBuf[0], FDefaultBuffer[TempFieldDef.Offset], TempFieldDef.Size); + // clear the null flag, this field has a value + if FNullField <> nil then + UpdateNullField(FDefaultBuffer, TempFieldDef, unClear); + end; + end; +end; + +procedure TDbfFile.InitRecord(DestBuf: TRecordBuffer); +begin + if FDefaultBuffer = nil then + InitDefaultBuffer; + Move(FDefaultBuffer^, DestBuf^, RecordSize); +end; + +procedure TDbfFile.ApplyAutoIncToBuffer(DestBuf: TRecordBuffer); +var + TempFieldDef: TDbfFieldDef; + I, NextVal, lAutoIncOffset: {LongWord} Cardinal; {Delphi 3 does not know LongWord?} +begin + if FAutoIncPresent then + begin + // if shared, reread header to find new autoinc values + if NeedLocks then + begin + // lock header so nobody else can use this value + LockPage(0, true); + end; + + // find autoinc fields + for I := 0 to FFieldDefs.Count-1 do + begin + TempFieldDef := FFieldDefs.Items[I]; + if (TempFieldDef.NativeFieldType = '+') then + begin + // read current auto inc, from header or field, depending on sharing + lAutoIncOffset := sizeof(rDbfHdr) + sizeof(rAfterHdrVII) + + FieldDescVII_AutoIncOffset + I * sizeof(rFieldDescVII); + if NeedLocks then + begin + ReadBlock(@NextVal, 4, lAutoIncOffset); + NextVal := SwapIntLE(NextVal); + end else + NextVal := TempFieldDef.AutoInc; + // store to buffer, positive = high bit on, so flip it + PCardinal(DestBuf+TempFieldDef.Offset)^ := SwapIntBE(NextVal or $80000000); + // increase + Inc(NextVal); + TempFieldDef.AutoInc := NextVal; + // write new value to header buffer + PCardinal(FHeader+lAutoIncOffset)^ := SwapIntLE(NextVal); + end; + end; + + // write modified header (new autoinc values) to file + WriteHeader; + + // release lock if locked + if NeedLocks then + UnlockPage(0); + end; +end; + +procedure TDbfFile.TryExclusive; +var + I: Integer; +begin + inherited; + + // exclusive succeeded? open index & memo exclusive too + if Mode in [pfMemoryCreate..pfExclusiveOpen] then + begin + // indexes + for I := 0 to FIndexFiles.Count - 1 do + TPagedFile(FIndexFiles[I]).TryExclusive; + // memo + if FMemoFile <> nil then + FMemoFile.TryExclusive; + end; +end; + +procedure TDbfFile.EndExclusive; +var + I: Integer; +begin + // end exclusive on index & memo too + for I := 0 to FIndexFiles.Count - 1 do + TPagedFile(FIndexFiles[I]).EndExclusive; + // memo + if FMemoFile <> nil then + FMemoFile.EndExclusive; + // dbf file + inherited; +end; + +procedure TDbfFile.OpenIndex(IndexName, IndexField: string; CreateIndex: Boolean; Options: TIndexOptions); + // + // assumes IndexName is not empty + // +const + // memcr, memop, excr, exopen, rwcr, rwopen, rdonly + IndexOpenMode: array[boolean, pfMemoryCreate..pfReadOnly] of TPagedFileMode = + ((pfMemoryCreate, pfMemoryCreate, pfExclusiveOpen, pfExclusiveOpen, pfReadWriteOpen, pfReadWriteOpen, + pfReadOnly), + (pfMemoryCreate, pfMemoryCreate, pfExclusiveCreate, pfExclusiveCreate, pfReadWriteCreate, pfReadWriteCreate, + pfReadOnly)); +var + lIndexFile: TIndexFile; + lIndexFileName: string; + createMdxFile: Boolean; + tempExclusive: boolean; + addedIndexFile: Integer; + addedIndexName: Integer; +begin + // init + addedIndexFile := -1; + addedIndexName := -1; + createMdxFile := false; + // index already opened? + lIndexFile := GetIndexByName(IndexName); + if (lIndexFile <> nil) and (lIndexFile = FMdxFile) and CreateIndex then + begin + // index already exists in MDX file + // delete it to save space, this causes a repage + FMdxFile.DeleteIndex(IndexName); + // index no longer exists + lIndexFile := nil; + end; + if (lIndexFile = nil) and (IndexName <> EmptyStr) then + begin + // check if no extension, then create MDX index + if Length(ExtractFileExt(IndexName)) = 0 then + begin + // check if mdx index already opened + if FMdxFile <> nil then + begin + lIndexFileName := EmptyStr; + lIndexFile := FMdxFile; + end else begin + lIndexFileName := ChangeFileExt(FileName, '.mdx'); + createMdxFile := true; + end; + end else begin + lIndexFileName := IndexName; + end; + // do we need to open / create file? + if lIndexFileName <> EmptyStr then + begin + // try to open / create the file + lIndexFile := TIndexFile.Create(Self); + lIndexFile.FileName := lIndexFileName; + lIndexFile.Mode := IndexOpenMode[CreateIndex, Mode]; + lIndexFile.AutoCreate := CreateIndex or (Length(IndexField) > 0); + lIndexFile.CodePage := UseCodePage; + lIndexFile.OnLocaleError := FOnLocaleError; + lIndexFile.Open; + // index file ready for use? + if not lIndexFile.ForceClose then + begin + // if we had to create the index, store that info + CreateIndex := lIndexFile.FileCreated; + // check if trying to create empty index + if CreateIndex and (IndexField = EmptyStr) then + begin + FreeAndNil(lIndexFile); + CreateIndex := false; + createMdxFile := false; + end else begin + // add new index file to list + addedIndexFile := FIndexFiles.Add(lIndexFile); + end; + // created accompanying mdx file? + if createMdxFile then + FMdxFile := lIndexFile; + end else begin + // asked to close! close file + FreeAndNil(lIndexFile); + end; + end; + + // check if file succesfully opened + if lIndexFile <> nil then + begin + // add index to list + addedIndexName := FIndexNames.AddObject(IndexName, lIndexFile); + end; + end; + // create it or open it? + if lIndexFile <> nil then + begin + if not CreateIndex then + if lIndexFile = FMdxFile then + CreateIndex := lIndexFile.IndexOf(IndexName) < 0; + if CreateIndex then + begin + // try get exclusive mode + tempExclusive := IsSharedAccess; + if tempExclusive then TryExclusive; + // always uppercase index expression + IndexField := AnsiUpperCase(IndexField); + try + try + // create index if asked + lIndexFile.CreateIndex(IndexField, IndexName, Options); + // add all records + PackIndex(lIndexFile, IndexName); + // if we wanted to open index readonly, but we created it, then reopen + if Mode = pfReadOnly then + begin + lIndexFile.CloseFile; + lIndexFile.Mode := pfReadOnly; + lIndexFile.OpenFile; + end; + // if mdx file just created, write changes to dbf header + // set MDX flag to true + PDbfHdr(Header)^.MDXFlag := 1; + WriteHeader; + except + on EDbfError do + begin + // :-( need to undo 'damage'.... + // remove index from list(s) if just added + if addedIndexFile >= 0 then + FIndexFiles.Delete(addedIndexFile); + if addedIndexName >= 0 then + FIndexNames.Delete(addedIndexName); + // if no file created, do not destroy! + if addedIndexFile >= 0 then + begin + lIndexFile.Close; + Sysutils.DeleteFile(lIndexFileName); + if FMdxFile = lIndexFile then + FMdxFile := nil; + lIndexFile.Free; + end; + raise; + end; + end; + finally + // return to previous mode + if tempExclusive then EndExclusive; + end; + end; + end; +end; + +procedure TDbfFile.PackIndex(lIndexFile: TIndexFile; AIndexName: string); +var + prevMode: TIndexUpdateMode; + prevIndex: string; + cur, last: Integer; +{$ifdef USE_CACHE} + prevCache: Integer; +{$endif} +begin + // save current mode in case we change it + prevMode := lIndexFile.UpdateMode; + prevIndex := lIndexFile.IndexName; + // check if index specified + if Length(AIndexName) > 0 then + begin + // only pack specified index, not all + lIndexFile.IndexName := AIndexName; + lIndexFile.ClearIndex; + lIndexFile.UpdateMode := umCurrent; + end else begin + lIndexFile.IndexName := EmptyStr; + lIndexFile.Clear; + lIndexFile.UpdateMode := umAll; + end; + // prepare update + cur := 1; + last := RecordCount; +{$ifdef USE_CACHE} + BufferAhead := true; + prevCache := lIndexFile.CacheSize; + lIndexFile.CacheSize := GetFreeMemory; + if lIndexFile.CacheSize < 16384 * 1024 then + lIndexFile.CacheSize := 16384 * 1024; +{$endif} + try + try + while cur <= last do + begin + ReadRecord(cur, FPrevBuffer); + lIndexFile.Insert(cur, FPrevBuffer); + inc(cur); + end; + except + on E: EDbfError do + begin + lIndexFile.DeleteIndex(lIndexFile.IndexName); + raise; + end; + end; + finally + // restore previous mode +{$ifdef USE_CACHE} + BufferAhead := false; + lIndexFile.BufferAhead := true; +{$endif} + lIndexFile.Flush; +{$ifdef USE_CACHE} + lIndexFile.BufferAhead := false; + lIndexFile.CacheSize := prevCache; +{$endif} + lIndexFile.UpdateMode := prevMode; + lIndexFile.IndexName := prevIndex; + end; +end; + +procedure TDbfFile.RepageIndex(AIndexFile: string); +var + lIndexNo: Integer; +begin + // DBF MDX index? + if Length(AIndexFile) = 0 then + begin + if FMdxFile <> nil then + begin + // repage attached mdx + FMdxFile.RepageFile; + end; + end else begin + // search index file + lIndexNo := FIndexNames.IndexOf(AIndexFile); + // index found? + if lIndexNo >= 0 then + TIndexFile(FIndexNames.Objects[lIndexNo]).RepageFile; + end; +end; + +procedure TDbfFile.CompactIndex(AIndexFile: string); +var + lIndexNo: Integer; +begin + // DBF MDX index? + if Length(AIndexFile) = 0 then + begin + if FMdxFile <> nil then + begin + // repage attached mdx + FMdxFile.CompactFile; + end; + end else begin + // search index file + lIndexNo := FIndexNames.IndexOf(AIndexFile); + // index found? + if lIndexNo >= 0 then + TIndexFile(FIndexNames.Objects[lIndexNo]).CompactFile; + end; +end; + +procedure TDbfFile.CloseIndex(AIndexName: string); +var + lIndexNo: Integer; + lIndex: TIndexFile; +begin + // search index file + lIndexNo := FIndexNames.IndexOf(AIndexName); + // don't close mdx file + if (lIndexNo >= 0) then + begin + // get index pointer + lIndex := TIndexFile(FIndexNames.Objects[lIndexNo]); + if (lIndex <> FMdxFile) then + begin + // close file + lIndex.Free; + // remove from lists + FIndexFiles.Remove(lIndex); + FIndexNames.Delete(lIndexNo); + // was this the current index? + if (FCurIndex = lIndexNo) then + begin + FCurIndex := -1; + //FCursor := FDbfCursor; + end; + end; + end; +end; + +function TDbfFile.DeleteIndex(const AIndexName: string): Boolean; +var + lIndexNo: Integer; + lIndex: TIndexFile; + lFileName: string; +begin + // search index file + lIndexNo := FIndexNames.IndexOf(AIndexName); + Result := lIndexNo >= 0; + // found index? + if Result then + begin + // can only delete indexes from MDX files + lIndex := TIndexFile(FIndexNames.Objects[lIndexNo]); + if lIndex = FMdxFile then + begin + lIndex.DeleteIndex(AIndexName); + // remove it from the list + FIndexNames.Delete(lIndexNo); + // no more MDX indexes? + lIndexNo := FIndexNames.IndexOfObject(FMdxFile); + if lIndexNo = -1 then + begin + // no MDX indexes left + lIndexNo := FIndexFiles.IndexOf(FMdxFile); + if lIndexNo >= 0 then + FIndexFiles.Delete(lIndexNo); + lFileName := FMdxFile.FileName; + FreeAndNil(FMdxFile); + // erase file + Sysutils.DeleteFile(lFileName); + // clear mdx flag + PDbfHdr(Header)^.MDXFlag := 0; + WriteHeader; + end; + end else begin + // close index first + CloseIndex(AIndexName); + // delete file from disk + SysUtils.DeleteFile(AIndexName); + end; + end; +end; + +function TDbfFile.Insert(Buffer: TRecordBuffer): integer; +type + TErrorContext = (ecNone, ecInsert, ecWriteIndex, ecWriteDbf); +var + newRecord: Integer; + lIndex: TIndexFile; + + procedure RollBackIndexesAndRaise(Count: Integer; ErrorContext: TErrorContext); + var + errorMsg: string; + I: Integer; + begin + errormsg:= ''; + // rollback committed indexes + for I := 0 to Count-1 do + begin + lIndex := TIndexFile(FIndexFiles.Items[I]); + lIndex.Delete(newRecord, Buffer); + end; + + // reset any dbf file error + ResetError; + + // if part of indexes committed -> always index error msg + // if error while rolling back index -> index error msg + case ErrorContext of + ecInsert: begin TIndexFile(FIndexFiles.Items[Count]).InsertError; exit; end; + ecWriteIndex: errorMsg := STRING_WRITE_INDEX_ERROR; + ecWriteDbf: errorMsg := STRING_WRITE_ERROR; + end; + raise EDbfWriteError.Create(errorMsg); + end; + +var + I: Integer; + error: TErrorContext; +begin + // get new record index + Result := 0; + newRecord := RecordCount+1; + // lock record so we can write data + while not LockPage(newRecord, false) do + Inc(newRecord); + // write autoinc value + ApplyAutoIncToBuffer(Buffer); + error := ecNone; + I := 0; + while I < FIndexFiles.Count do + begin + lIndex := TIndexFile(FIndexFiles.Items[I]); + if not lIndex.Insert(newRecord, Buffer) then + error := ecInsert; + if lIndex.WriteError then + error := ecWriteIndex; + if error <> ecNone then + begin + // if there's an index write error, I shouldn't + // try to write the dbf header and the new record, + // but raise an exception right away + UnlockPage(newRecord); + RollBackIndexesAndRaise(I, ecWriteIndex); + end; + Inc(I); + end; + + // indexes ok -> continue inserting + // update header record count + LockPage(0, true); + // read current header + ReadHeader; + // increase current record count + Inc(PDbfHdr(Header)^.RecordCount); + // write header to disk + WriteHeader; + // done with header + UnlockPage(0); + + if WriteError then + begin + // couldn't write header, so I shouldn't + // even try to write the record. + // + // At this point I should "roll back" + // the already written index records. + // if this fails, I'm in deep trouble! + UnlockPage(newRecord); + RollbackIndexesAndRaise(FIndexFiles.Count, ecWriteDbf); + end; + + // write locking info + if FLockField <> nil then + WriteLockInfo(Buffer); + // write buffer to disk + WriteRecord(newRecord, Buffer); + // done updating, unlock + UnlockPage(newRecord); + // error occurred while writing? + if WriteError then + begin + // -- Tobias -- + // The record couldn't be written, so + // the written index records and the + // change to the header have to be + // rolled back + LockPage(0, true); + ReadHeader; + Dec(PDbfHdr(Header)^.RecordCount); + WriteHeader; + UnlockPage(0); + // roll back indexes too + RollbackIndexesAndRaise(FIndexFiles.Count, ecWriteDbf); + end else + Result := newRecord; +end; + +procedure TDbfFile.WriteLockInfo(Buffer: TRecordBuffer); +// +// *) assumes FHasLockField = true +// +var + year, month, day, hour, minute, sec, msec: Word; + lockoffset: integer; +begin + // increase change count + lockoffset := FLockField.Offset; + Inc(PWord(Buffer+lockoffset)^); + // set time + DecodeDate(Now(), year, month, day); + DecodeTime(Now(), hour, minute, sec, msec); + Buffer[lockoffset+2] := TRecordBufferBaseType(hour); + Buffer[lockoffset+3] := TRecordBufferBaseType(minute); + Buffer[lockoffset+4] := TRecordBufferBaseType(sec); + // set date + Buffer[lockoffset+5] := TRecordBufferBaseType(year - 1900); + Buffer[lockoffset+6] := TRecordBufferBaseType(month); + Buffer[lockoffset+7] := TRecordBufferBaseType(day); + // set name + FillChar(Buffer[lockoffset+8], FLockField.Size-8, ' '); + Move(DbfGlobals.UserName[1], Buffer[lockoffset+8], FLockUserLen); +end; + +procedure TDbfFile.LockRecord(RecNo: Integer; Buffer: TRecordBuffer); +begin + if LockPage(RecNo, false) then + begin + // reread data + ReadRecord(RecNo, Buffer); + // store previous data for updating indexes + Move(Buffer^, FPrevBuffer^, RecordSize); + // lock succeeded, update lock info, if field present + if FLockField <> nil then + begin + // update buffer + WriteLockInfo(Buffer); + // write to disk + WriteRecord(RecNo, Buffer); + end; + end else + raise EDbfError.Create(STRING_RECORD_LOCKED); +end; + +procedure TDbfFile.UnlockRecord(RecNo: Integer; Buffer: TRecordBuffer); +var + I: Integer; + lIndex, lErrorIndex: TIndexFile; +begin + // update indexes, possible key violation + I := 0; + while I < FIndexFiles.Count do + begin + lIndex := TIndexFile(FIndexFiles.Items[I]); + if not lIndex.Update(RecNo, FPrevBuffer, Buffer) then + begin + // error -> rollback + lErrorIndex := lIndex; + while I > 0 do + begin + Dec(I); + lIndex := TIndexFile(FIndexFiles.Items[I]); + lIndex.Update(RecNo, Buffer, FPrevBuffer); + end; + lErrorIndex.InsertError; + end; + Inc(I); + end; + // write new record buffer, all keys ok + WriteRecord(RecNo, Buffer); + // done updating, unlock + UnlockPage(RecNo); +end; + +procedure TDbfFile.RecordDeleted(RecNo: Integer; Buffer: TRecordBuffer); +var + I: Integer; + lIndex: TIndexFile; +begin + // notify indexes: record deleted + for I := 0 to FIndexFiles.Count - 1 do + begin + lIndex := TIndexFile(FIndexFiles.Items[I]); + lIndex.RecordDeleted(RecNo, Buffer); + end; +end; + +procedure TDbfFile.RecordRecalled(RecNo: Integer; Buffer: TRecordBuffer); +var + I: Integer; + lIndex, lErrorIndex: TIndexFile; +begin + // notify indexes: record recalled + I := 0; + while I < FIndexFiles.Count do + begin + lIndex := TIndexFile(FIndexFiles.Items[I]); + if not lIndex.RecordRecalled(RecNo, Buffer) then + begin + lErrorIndex := lIndex; + while I > 0 do + begin + Dec(I); + lIndex.RecordDeleted(RecNo, Buffer); + end; + lErrorIndex.InsertError; + end; + Inc(I); + end; +end; + +procedure TDbfFile.SetRecordSize(NewSize: Integer); +begin + if NewSize <> RecordSize then + begin + if FPrevBuffer <> nil then + FreeMemAndNil(Pointer(FPrevBuffer)); + + if NewSize > 0 then + GetMem(FPrevBuffer, NewSize); + end; + inherited; +end; + +function TDbfFile.GetIndexByName(AIndexName: string): TIndexFile; +var + I: Integer; +begin + I := FIndexNames.IndexOf(AIndexName); + if I >= 0 then + Result := TIndexFile(FIndexNames.Objects[I]) + else + Result := nil; +end; + +//==================================================================== +// TDbfCursor +//==================================================================== +constructor TDbfCursor.Create(DbfFile: TDbfFile); +begin + inherited Create(DbfFile); +end; + +function TDbfCursor.Next: Boolean; +begin + if TDbfFile(PagedFile).IsRecordPresent(FPhysicalRecNo) then + begin + inc(FPhysicalRecNo); + Result := TDbfFile(PagedFile).IsRecordPresent(FPhysicalRecNo); + end else begin + FPhysicalRecNo := TDbfFile(PagedFile).CachedRecordCount + 1; + Result := false; + end; +end; + +function TDbfCursor.Prev: Boolean; +begin + if FPhysicalRecNo > 0 then + dec(FPhysicalRecNo) + else + FPhysicalRecNo := 0; + Result := FPhysicalRecNo > 0; +end; + +procedure TDbfCursor.First; +begin + FPhysicalRecNo := 0; +end; + +procedure TDbfCursor.Last; +var + max: Integer; +begin + max := TDbfFile(PagedFile).RecordCount; + if max = 0 then + FPhysicalRecNo := 0 + else + FPhysicalRecNo := max + 1; +end; + +function TDbfCursor.GetPhysicalRecNo: Integer; +begin + Result := FPhysicalRecNo; +end; + +procedure TDbfCursor.SetPhysicalRecNo(RecNo: Integer); +begin + FPhysicalRecNo := RecNo; +end; + +function TDbfCursor.GetSequentialRecordCount: Integer; +begin + Result := TDbfFile(PagedFile).RecordCount; +end; + +function TDbfCursor.GetSequentialRecNo: Integer; +begin + Result := FPhysicalRecNo; +end; + +procedure TDbfCursor.SetSequentialRecNo(RecNo: Integer); +begin + FPhysicalRecNo := RecNo; +end; + +// codepage enumeration procedure +var + TempCodePageList: TList; + +// LPTSTR = PChar ok? + +function CodePagesProc(CodePageString: PChar): Cardinal; stdcall; +begin + // add codepage to list + TempCodePageList.Add(Pointer(ptrint(GetIntFromStrLength(CodePageString, StrLen(CodePageString), -1)))); + + // continue enumeration + Result := 1; +end; + +//==================================================================== +// TDbfGlobals +//==================================================================== +constructor TDbfGlobals.Create; +begin + FCodePages := TList.Create; + FDefaultOpenCodePage := GetACP; + // the following sets FDefaultCreateLangId + DefaultCreateCodePage := GetACP; + FCurrencyAsBCD := true; + // determine which code pages are installed + TempCodePageList := FCodePages; + EnumSystemCodePages(@CodePagesProc, {CP_SUPPORTED} CP_INSTALLED); + TempCodePageList := nil; + InitUserName; +end; + +procedure TDbfGlobals.InitUserName; +{$ifdef FPC} +{$ifndef msWINDOWS} +var + TempName: UTSName; +{$endif} +{$endif} +begin +{$ifdef msWINDOWS} +{$ifdef wince} + FUserName:='cedevice'; + FUserNameLen:=Length(FUserName); +{$else} + FUserNameLen := MAX_COMPUTERNAME_LENGTH+1; + SetLength(FUserName, FUserNameLen); + Windows.GetComputerName(PChar(FUserName), + {$ifdef DELPHI_3}Windows.DWORD({$endif} + FUserNameLen + {$ifdef DELPHI_3}){$endif} + ); + SetLength(FUserName, FUserNameLen); +{$endif wince} +{$else} +{$ifdef FPC} + FpUname(TempName); + FUserName := TempName.machine; + FUserNameLen := Length(FUserName); +{$endif} +{$endif} +end; + +destructor TDbfGlobals.Destroy; {override;} +begin + FCodePages.Free; +end; + +function TDbfGlobals.GetDefaultCreateCodePage: Integer; +begin + Result := LangId_To_CodePage[FDefaultCreateLangId]; +end; + +procedure TDbfGlobals.SetDefaultCreateCodePage(NewCodePage: Integer); +begin + FDefaultCreateLangId := ConstructLangId(NewCodePage, GetUserDefaultLCID, false); +end; + +function TDbfGlobals.CodePageInstalled(ACodePage: Integer): Boolean; +begin + Result := FCodePages.IndexOf(Pointer(ptrint(ACodePage))) >= 0; +end; + +initialization +finalization + FreeAndNil(DbfGlobals); + + +(* + Stuffs non implemented yet + TFoxCDXHeader = Record + PointerRootNode : Integer; + PointerFreeList : Integer; + Reserved_8_11 : Cardinal; + KeyLength : Word; + IndexOption : Byte; + IndexSignature : Byte; + Reserved_Null : TFoxReservedNull; + SortOrder : Word; + TotalExpressionLen : Word; + ForExpressionLen : Word; + Reserved_506_507 : Word; + KeyExpressionLen : Word; + KeyForExpression : TKeyForExpression; + End; + PFoxCDXHeader = ^TFoxCDXHeader; + + TFoxCDXNodeCommon = Record + NodeAttributes : Word; + NumberOfKeys : Word; + PointerLeftNode : Integer; + PointerRightNode : Integer; + End; + + TFoxCDXNodeNonLeaf = Record + NodeCommon : TFoxCDXNodeCommon; + TempBlock : Array [12..511] of Byte; + End; + PFoxCDXNodeNonLeaf = ^TFoxCDXNodeNonLeaf; + + TFoxCDXNodeLeaf = Packed Record + NodeCommon : TFoxCDXNodeCommon; + BlockFreeSpace : Word; + RecordNumberMask : Integer; + DuplicateCountMask : Byte; + TrailByteCountMask : Byte; + RecNoBytes : Byte; + DuplicateCountBytes : Byte; + TrailByteCountBytes : Byte; + HoldingByteCount : Byte; + DataBlock : TDataBlock; + End; + PFoxCDXNodeLeaf = ^TFoxCDXNodeLeaf; + +*) + +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_fields.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_fields.pas new file mode 100644 index 0000000..0e934e8 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_fields.pas @@ -0,0 +1,597 @@ +unit dbf_fields; + +// Modified 2013 by Martin Schreiber + +interface + +{$I dbf_common.inc} + +uses + classes,mclasses, + SysUtils, + mdb, + dbf_common, + dbf_str; + +type + PDbfFieldDef = ^TDbfFieldDef; + + TDbfFieldDef = class(TCollectionItem) + private + FFieldName: string; + FFieldType: TFieldType; + FNativeFieldType: TDbfFieldType; + FDefaultBuf: PChar; + FMinBuf: PChar; + FMaxBuf: PChar; + FSize: Integer; + FPrecision: Integer; + FHasDefault: Boolean; + FHasMin: Boolean; + FHasMax: Boolean; + FAllocSize: Integer; + FCopyFrom: Integer; + FOffset: Integer; + FAutoInc: Cardinal; + FRequired: Boolean; + FIsLockField: Boolean; + FNullPosition: integer; + + function GetDbfVersion: TXBaseVersion; + procedure SetNativeFieldType(lFieldType: TDbfFieldType); + procedure SetFieldType(lFieldType: TFieldType); + procedure SetSize(lSize: Integer); + procedure SetPrecision(lPrecision: Integer); + procedure VCLToNative; + procedure NativeToVCL; + procedure FreeBuffers; + protected + function GetDisplayName: string; override; + procedure AssignTo(Dest: TPersistent); override; + + property DbfVersion: TXBaseVersion read GetDbfVersion; + public + constructor Create(ACollection: TCollection); override; + destructor Destroy; override; + + procedure Assign(Source: TPersistent); override; + procedure AssignDb(DbSource: TFieldDef); + + procedure CheckSizePrecision; + procedure SetDefaultSize; + procedure AllocBuffers; + function IsBlob: Boolean; + + property DefaultBuf: PChar read FDefaultBuf; + property MinBuf: PChar read FMinBuf; + property MaxBuf: PChar read FMaxBuf; + property HasDefault: Boolean read FHasDefault write FHasDefault; + property HasMin: Boolean read FHasMin write FHasMin; + property HasMax: Boolean read FHasMax write FHasMax; + property Offset: Integer read FOffset write FOffset; + property AutoInc: Cardinal read FAutoInc write FAutoInc; + property IsLockField: Boolean read FIsLockField write FIsLockField; + property CopyFrom: Integer read FCopyFrom write FCopyFrom; + published + property FieldName: string read FFieldName write FFieldName; + property FieldType: TFieldType read FFieldType write SetFieldType; + property NativeFieldType: TDbfFieldType read FNativeFieldType write SetNativeFieldType; + property NullPosition: integer read FNullPosition write FNullPosition; + property Size: Integer read FSize write SetSize; + property Precision: Integer read FPrecision write SetPrecision; + property Required: Boolean read FRequired write FRequired; + end; + + TDbfFieldDefs = class(TCollection) + private + FOwner: TPersistent; + FDbfVersion: TXBaseVersion; + + function GetItem(Idx: Integer): TDbfFieldDef; + protected + function GetOwner: TPersistent; override; + public + constructor Create(Owner: TPersistent); + +{$ifdef SUPPORT_DEFAULT_PARAMS} + procedure Add(const Name: string; DataType: TFieldType; Size: Integer = 0; Required: Boolean = False); +{$else} + procedure Add(const Name: string; DataType: TFieldType; Size: Integer; Required: Boolean); +{$endif} + function AddFieldDef: TDbfFieldDef; + + property Items[Idx: Integer]: TDbfFieldDef read GetItem; + property DbfVersion: TXBaseVersion read FDbfVersion write FDbfVersion; + end; + +implementation + +uses + dbf_dbffile; // for dbf header structures + +{$I dbf_struct.inc} + +// I keep changing that fields... +// Last time has been asked by Venelin Georgiev +// Is he going to be the last ? +const +(* +The theory until now was : + ftSmallint 16 bits = -32768 to 32767 + 123456 = 6 digit max theorically + DIGITS_SMALLINT = 6; + ftInteger 32 bits = -2147483648 to 2147483647 + 12345678901 = 11 digits max + DIGITS_INTEGER = 11; + ftLargeInt 64 bits = -9223372036854775808 to 9223372036854775807 + 12345678901234567890 = 20 digits max + DIGITS_LARGEINT = 20; + +But in fact if I accept 6 digits into a ftSmallInt then tDbf will not +being able to handles fields with 999999 (6 digits). + +So I now oversize the field type in order to accept anithing coming from the +database. + ftSmallint 16 bits = -32768 to 32767 + -999 to 9999 + 4 digits max theorically + DIGITS_SMALLINT = 4; + ftInteger 32 bits = -2147483648 to 2147483647 + -99999999 to 999999999 12345678901 = 11 digits max + DIGITS_INTEGER = 9; + ftLargeInt 64 bits = -9223372036854775808 to 9223372036854775807 + -99999999999999999 to 999999999999999999 + DIGITS_LARGEINT = 18; + *) + DIGITS_SMALLINT = 4; + DIGITS_INTEGER = 9; + DIGITS_LARGEINT = 18; + +//==================================================================== +// DbfFieldDefs +//==================================================================== +function TDbfFieldDefs.GetItem(Idx: Integer): TDbfFieldDef; +begin + Result := TDbfFieldDef(inherited GetItem(Idx)); +end; + +constructor TDbfFieldDefs.Create(Owner: TPersistent); +begin + inherited Create(TDbfFieldDef); + FOwner := Owner; +end; + +function TDbfFieldDefs.AddFieldDef: TDbfFieldDef; +begin + Result := TDbfFieldDef(inherited Add); +end; + +function TDbfFieldDefs.GetOwner: TPersistent; {override;} +begin + Result := FOwner; +end; + +procedure TDbfFieldDefs.Add(const Name: string; DataType: TFieldType; Size: Integer; Required: Boolean); +var + FieldDef: TDbfFieldDef; +begin + FieldDef := AddFieldDef; + FieldDef.FieldName := Name; + FieldDef.FieldType := DataType; + if Size <> 0 then + FieldDef.Size := Size; + FieldDef.Required := Required; +end; + +//==================================================================== +// DbfFieldDef +//==================================================================== +constructor TDbfFieldDef.Create(ACollection: TCollection); {virtual} +begin + inherited; + + FDefaultBuf := nil; + FMinBuf := nil; + FMaxBuf := nil; + FAllocSize := 0; + FCopyFrom := -1; + FPrecision := 0; + FHasDefault := false; + FHasMin := false; + FHasMax := false; + FNullPosition := -1; +end; + +destructor TDbfFieldDef.Destroy; {override} +begin + FreeBuffers; + inherited; +end; + +procedure TDbfFieldDef.Assign(Source: TPersistent); +var + DbfSource: TDbfFieldDef; +begin + if Source is TDbfFieldDef then + begin + // copy from another TDbfFieldDef + DbfSource := TDbfFieldDef(Source); + FFieldName := DbfSource.FieldName; + FFieldType := DbfSource.FieldType; + FNativeFieldType := DbfSource.NativeFieldType; + FSize := DbfSource.Size; + FPrecision := DbfSource.Precision; + FRequired := DbfSource.Required; + FCopyFrom := DbfSource.Index; + FIsLockField := DbfSource.IsLockField; + FNullPosition := DbfSource.NullPosition; + // copy default,min,max + AllocBuffers; + if DbfSource.DefaultBuf <> nil then + Move(DbfSource.DefaultBuf^, FDefaultBuf^, FAllocSize*3); + FHasDefault := DbfSource.HasDefault; + FHasMin := DbfSource.HasMin; + FHasMax := DbfSource.HasMax; + // do we need offsets? + FOffset := DbfSource.Offset; + FAutoInc := DbfSource.AutoInc; +{$ifdef SUPPORT_FIELDDEF_TPERSISTENT} + end else if Source is TFieldDef then begin + AssignDb(TFieldDef(Source)); +{$endif} + end else + inherited Assign(Source); +end; + +procedure TDbfFieldDef.AssignDb(DbSource: TFieldDef); +begin + // copy from Db.TFieldDef + FFieldName := DbSource.Name; + FFieldType := DbSource.DataType; + FSize := DbSource.Size; + FPrecision := DbSource.Precision; + FRequired := DbSource.Required; +{$ifdef SUPPORT_FIELDDEF_INDEX} + FCopyFrom := DbSource.Index; +{$endif} + FIsLockField := false; + // convert VCL fieldtypes to native DBF fieldtypes + VCLToNative; + // for integer / float fields try fill in size/precision + if FSize = 0 then + SetDefaultSize + else + CheckSizePrecision; + // VCL does not have default value support + AllocBuffers; + FHasDefault := false; + FHasMin := false; + FHasMax := false; + FOffset := 0; + FAutoInc := 0; +end; + +procedure TDbfFieldDef.AssignTo(Dest: TPersistent); +{$ifdef SUPPORT_FIELDDEF_TPERSISTENT} + {$ifdef SUPPORT_FIELDDEF_ATTRIBUTES} +var + DbDest: TFieldDef; + {$endif} +{$endif} +begin +{$ifdef SUPPORT_FIELDDEF_TPERSISTENT} + // copy to VCL fielddef? + if Dest is TFieldDef then + begin + // VCL TFieldDef does not know how to handle TDbfFieldDef! + // what a shame :-) +{$ifdef SUPPORT_FIELDDEF_ATTRIBUTES} + DbDest := TFieldDef(Dest); + DbDest.Attributes := []; + DbDest.ChildDefs.Clear; + DbDest.DataType := FFieldType; + DbDest.Required := FRequired; + DbDest.Size := FSize; + DbDest.Name := FFieldName; +{$endif} + end else +{$endif} + inherited AssignTo(Dest); +end; + +function TDbfFieldDef.GetDbfVersion: TXBaseVersion; +begin + Result := TDbfFieldDefs(Collection).DbfVersion; +end; + +procedure TDbfFieldDef.SetFieldType(lFieldType: tFieldType); +begin + FFieldType := lFieldType; + VCLToNative; + SetDefaultSize; +end; + +procedure TDbfFieldDef.SetNativeFieldType(lFieldType: tDbfFieldType); +begin + // get uppercase field type + if (lFieldType >= 'a') and (lFieldType <= 'z') then + lFieldType := Chr(Ord(lFieldType)-32); + FNativeFieldType := lFieldType; + NativeToVCL; + CheckSizePrecision; +end; + +procedure TDbfFieldDef.SetSize(lSize: Integer); +begin + FSize := lSize; + CheckSizePrecision; +end; + +procedure TDbfFieldDef.SetPrecision(lPrecision: Integer); +begin + FPrecision := lPrecision; + CheckSizePrecision; +end; + +procedure TDbfFieldDef.NativeToVCL; +begin + case FNativeFieldType of +// OH 2000-11-15 dBase7 support. +// Add the new fieldtypes + '+' : + if DbfVersion = xBaseVII then + FFieldType := ftAutoInc; + 'I' : FFieldType := ftInteger; + 'O' : FFieldType := ftFloat; + '@', 'T': + FFieldType := ftDateTime; + 'C', + #$91 {Russian 'C'} + : FFieldType := ftString; + 'L' : FFieldType := ftBoolean; + 'F', 'N': + begin + if (FPrecision = 0) then + begin + if FSize <= DIGITS_SMALLINT then + FFieldType := ftSmallInt + else + if FSize <= DIGITS_INTEGER then + FFieldType := ftInteger + else +{$ifdef SUPPORT_INT64} + FFieldType := ftLargeInt; +{$else} + FFieldType := ftFloat; +{$endif} + end else begin + FFieldType := ftFloat; + end; + end; + 'D' : FFieldType := ftDate; + 'M' : FFieldType := ftMemo; + 'B' : + if DbfVersion = xFoxPro then + FFieldType := ftFloat + else + FFieldType := ftBlob; + 'G' : FFieldType := ftDBaseOle; + 'Y' : + if DbfGlobals.CurrencyAsBCD then + FFieldType := ftBCD + else + FFieldType := ftCurrency; + '0' : FFieldType := ftBytes; { Visual FoxPro ``_NullFlags'' } + else + FNativeFieldType := #0; + FFieldType := ftUnknown; + end; //case +end; + +procedure TDbfFieldDef.VCLToNative; +begin + FNativeFieldType := #0; + case FFieldType of + ftAutoInc : FNativeFieldType := '+'; + ftDateTime : + if DbfVersion = xBaseVII then + FNativeFieldType := '@' + else + if DbfVersion = xFoxPro then + FNativeFieldType := 'T' + else + FNativeFieldType := 'D'; +{$ifdef SUPPORT_FIELDTYPES_V4} + ftFixedChar, + ftWideString, +{$endif} + ftString : FNativeFieldType := 'C'; + ftBoolean : FNativeFieldType := 'L'; + ftFloat, ftSmallInt, ftWord +{$ifdef SUPPORT_INT64} + , ftLargeInt +{$endif} + : FNativeFieldType := 'N'; + ftDate : FNativeFieldType := 'D'; + ftMemo : FNativeFieldType := 'M'; + ftBlob : FNativeFieldType := 'B'; + ftDBaseOle : FNativeFieldType := 'G'; + ftInteger : + if DbfVersion = xBaseVII then + FNativeFieldType := 'I' + else + FNativeFieldType := 'N'; + ftBCD, ftCurrency: + if DbfVersion = xFoxPro then + FNativeFieldType := 'Y'; + end; + if FNativeFieldType = #0 then + raise EDbfError.CreateFmt(STRING_INVALID_VCL_FIELD_TYPE, [GetDisplayName, Ord(FFieldType)]); +end; + +procedure TDbfFieldDef.SetDefaultSize; +begin + // choose default values for variable size fields + case FFieldType of + ftFloat: + begin + FSize := 18; + FPrecision := 8; + end; + ftCurrency, ftBCD: + begin + FSize := 8; + FPrecision := 4; + end; + ftSmallInt, ftWord: + begin + FSize := DIGITS_SMALLINT; + FPrecision := 0; + end; + ftInteger, ftAutoInc: + begin + if DbfVersion = xBaseVII then + FSize := 4 + else + FSize := DIGITS_INTEGER; + FPrecision := 0; + end; +{$ifdef SUPPORT_INT64} + ftLargeInt: + begin + FSize := DIGITS_LARGEINT; + FPrecision := 0; + end; +{$endif} + ftString {$ifdef SUPPORT_FIELDTYPES_V4}, ftFixedChar, ftWideString{$endif}: + begin + FSize := 30; + FPrecision := 0; + end; + end; // case fieldtype + + // set sizes for fields that are restricted to single size/precision + CheckSizePrecision; +end; + +procedure TDbfFieldDef.CheckSizePrecision; +begin + case FNativeFieldType of + 'C': + begin + if FSize < 0 then + FSize := 0; + if DbfVersion = xFoxPro then + begin + if FSize >= $FFFF then + FSize := $FFFF; + end else begin + if FSize >= $FF then + FSize := $FF; + end; + FPrecision := 0; + end; + 'L': + begin + FSize := 1; + FPrecision := 0; + end; + 'N','F': + begin + // floating point + if FSize < 1 then FSize := 1; + if FSize >= 20 then FSize := 20; + if FPrecision > FSize-2 then FPrecision := FSize-2; + if FPrecision < 0 then FPrecision := 0; + end; + 'D': + begin + FSize := 8; + FPrecision := 0; + end; + 'B': + begin + if DbfVersion <> xFoxPro then + begin + FSize := 10; + FPrecision := 0; + end; + end; + 'M','G': + begin + if DbfVersion = xFoxPro then + begin + if (FSize <> 4) and (FSize <> 10) then + FSize := 4; + end else + FSize := 10; + FPrecision := 0; + end; + '+','I': + begin + FSize := 4; + FPrecision := 0; + end; + '@', 'O': + begin + FSize := 8; + FPrecision := 0; + end; + 'T': + begin + if DbfVersion = xFoxPro then + FSize := 8 + else + FSize := 14; + FPrecision := 0; + end; + 'Y': + begin + FSize := 8; + FPrecision := 4; + end; + else + // Nothing + end; // case +end; + +function TDbfFieldDef.GetDisplayName: string; {override;} +begin + Result := FieldName; +end; + +function TDbfFieldDef.IsBlob: Boolean; {override;} +begin + Result := FNativeFieldType in ['M','G','B']; +end; + +procedure TDbfFieldDef.FreeBuffers; +begin + if FDefaultBuf <> nil then + begin + // one buffer for all + FreeMemAndNil(Pointer(FDefaultBuf)); + FMinBuf := nil; + FMaxBuf := nil; + end; + FAllocSize := 0; +end; + +procedure TDbfFieldDef.AllocBuffers; +begin + // size changed? + if FAllocSize <> FSize then + begin + // free old buffers + FreeBuffers; + // alloc new + GetMem(FDefaultBuf, FSize*3); + FMinBuf := FDefaultBuf + FSize; + FMaxBuf := FMinBuf + FSize; + // store allocated size + FAllocSize := FSize; + end; +end; + +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_idxcur.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_idxcur.pas new file mode 100644 index 0000000..3b46ae4 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_idxcur.pas @@ -0,0 +1,217 @@ +unit dbf_idxcur; + +// Modified 2013 by Martin Schreiber + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{$I dbf_common.inc} + +uses + SysUtils, + classes,mclasses, + mdb, + dbf_cursor, + dbf_idxfile, + mdbf_prsdef, +{$ifndef WINDOWS} + dbf_wtil, +{$endif} + dbf_common; + +type + +//==================================================================== +//=== Index support +//==================================================================== + TIndexCursor = class(TVirtualCursor) + private + FIndexFile: TIndexFile; + protected + function GetPhysicalRecNo: Integer; override; + function GetSequentialRecNo: Integer; override; + function GetSequentialRecordCount: Integer; override; + procedure SetPhysicalRecNo(RecNo: Integer); override; + procedure SetSequentialRecNo(RecNo: Integer); override; + + procedure VariantStrToBuffer(Key: Variant; ABuffer: TRecordBuffer); + public + constructor Create(DbfIndexFile: TIndexFile); + destructor Destroy; override; + + function Next: Boolean; override; + function Prev: Boolean; override; + procedure First; override; + procedure Last; override; + + procedure Insert(RecNo: Integer; Buffer: TRecordBuffer); + procedure Update(RecNo: Integer; PrevBuffer, NewBuffer: TRecordBuffer); + +{$ifdef SUPPORT_VARIANTS} + function VariantToBuffer(Key: Variant; ABuffer: TRecordBuffer): TExpressionType; +{$endif} + function CheckUserKey(Key: PChar; StringBuf: PChar): PChar; + + property IndexFile: TIndexFile read FIndexFile; + end; + +//==================================================================== +// TIndexCursor = class; +//==================================================================== + PIndexPosInfo = ^TIndexPage; + +//==================================================================== +implementation + +{$ifdef msWINDOWS} +uses + Windows; +{$endif} +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +//========================================================== +//============ TIndexCursor +//========================================================== +constructor TIndexCursor.Create(DbfIndexFile: TIndexFile); +begin + inherited Create(DbfIndexFile); + + FIndexFile := DbfIndexFile; +end; + +destructor TIndexCursor.Destroy; {override;} +begin + inherited Destroy; +end; + +procedure TIndexCursor.Insert(RecNo: Integer; Buffer: TRecordBuffer); +begin + TIndexFile(PagedFile).Insert(RecNo,Buffer); + // TODO SET RecNo and Key +end; + +procedure TIndexCursor.Update(RecNo: Integer; PrevBuffer, NewBuffer: TRecordBuffer); +begin + TIndexFile(PagedFile).Update(RecNo, PrevBuffer, NewBuffer); +end; + +procedure TIndexCursor.First; +begin + TIndexFile(PagedFile).First; +end; + +procedure TIndexCursor.Last; +begin + TIndexFile(PagedFile).Last; +end; + +function TIndexCursor.Prev: Boolean; +begin + Result := TIndexFile(PagedFile).Prev; +end; + +function TIndexCursor.Next: Boolean; +begin + Result := TIndexFile(PagedFile).Next; +end; + +function TIndexCursor.GetPhysicalRecNo: Integer; +begin + Result := TIndexFile(PagedFile).PhysicalRecNo; +end; + +procedure TIndexCursor.SetPhysicalRecNo(RecNo: Integer); +begin + TIndexFile(PagedFile).PhysicalRecNo := RecNo; +end; + +function TIndexCursor.GetSequentialRecordCount: Integer; +begin + Result := TIndexFile(PagedFile).SequentialRecordCount; +end; + +function TIndexCursor.GetSequentialRecNo: Integer; +begin + Result := TIndexFile(PagedFile).SequentialRecNo; +end; + +procedure TIndexCursor.SetSequentialRecNo(RecNo: Integer); +begin + TIndexFile(PagedFile).SequentialRecNo := RecNo; +end; + +{$ifdef SUPPORT_VARIANTS} + +procedure TIndexCursor.VariantStrToBuffer(Key: Variant; ABuffer: TRecordBuffer); +var + currLen: Integer; + StrKey: string; +begin + StrKey := Key; + currLen := TranslateString(GetACP, FIndexFile.CodePage, PAnsiChar(StrKey), PAnsiChar(ABuffer), -1); + // we have null-terminated string, pad with spaces if string too short + FillChar(ABuffer[currLen], TIndexFile(PagedFile).KeyLen-currLen, ' '); +end; + +function TIndexCursor.VariantToBuffer(Key: Variant; ABuffer: TRecordBuffer): TExpressionType; +// assumes ABuffer is large enough ie. at least max key size +begin + if (TIndexFile(PagedFile).KeyType='N') then + begin + PDouble(ABuffer)^ := Key; + if (TIndexFile(PagedFile).IndexVersion <> xBaseIII) then + begin + // make copy of userbcd to buffer + Move(TIndexFile(PagedFile).PrepareKey(ABuffer, etFloat)[0], ABuffer[0], 11); + end; + Result := etInteger; + end else begin + VariantStrToBuffer(Key, ABuffer); + Result := etString; + end; +end; + +{$endif} + +function TIndexCursor.CheckUserKey(Key: PChar; StringBuf: PChar): PChar; +var + keyLen, userLen: Integer; +begin + // default is to use key + Result := Key; + // if key is double, then no check + if (TIndexFile(PagedFile).KeyType = 'N') then + begin + // nothing needs to be done + end else begin + // check if string long enough then no copying needed + userLen := StrLen(Key); + keyLen := TIndexFile(PagedFile).KeyLen; + if userLen < keyLen then + begin + // copy string + Move(Key^, StringBuf[0], userLen); + // add spaces to searchstring + FillChar(StringBuf[userLen], keyLen - userLen, ' '); + // set buffer to temporary buffer + Result := StringBuf; + end; + end; +end; + +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_idxfile.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_idxfile.pas new file mode 100644 index 0000000..089cec8 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_idxfile.pas @@ -0,0 +1,4186 @@ +unit dbf_idxfile; + +// Modified 2013 by Martin Schreiber + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{$I dbf_common.inc} + +uses +{$ifdef msWINDOWS} + Windows, +{$else} +{$ifdef KYLIX} + Libc, +{$endif} + Types, dbf_wtil, +{$endif} + SysUtils, + classes,mclasses, + mdb, + dbf_pgfile, +{$ifdef USE_CACHE} + dbf_pgcfile, +{$endif} + dbf_parser, + mdbf_prsdef, + dbf_cursor, + dbf_collate, + dbf_common; + +{$ifdef _DEBUG} +{$define TDBF_INDEX_CHECK} +{$endif} +{$ifdef _ASSERTS} +{$define TDBF_INDEX_CHECK} +{$endif} + +const + MaxIndexes = 47; + +type + TIndexPage = class; + TIndexTag = class; + + TIndexUpdateMode = (umAll, umCurrent); + TLocaleError = (leNone, leUnknown, leTableIndexMismatch, leNotAvailable); + TLocaleSolution = (lsNotOpen, lsNoEdit, lsBinary); + TIndexUniqueType = (iuNormal, iuUnique, iuDistinct); + TIndexModifyMode = (mmNormal, mmDeleteRecall); + + TDbfLocaleErrorEvent = procedure(var Error: TLocaleError; var Solution: TLocaleSolution) of object; + TDbfCompareKeysEvent = function(Key1, Key2: PChar): Integer of object; + + PDouble = ^Double; + PInteger = ^Integer; + +//=========================================================================== + TDbfIndexDef = class; + TDbfIndexDef = class(TCollectionItem) + protected + FIndexName: string; + FExpression: string; + FOptions: TIndexOptions; + FTemporary: Boolean; // added at runtime + + procedure SetIndexName(NewName: string); + procedure SetExpression(NewField: string); + public + constructor Create(ACollection: TCollection); override; + destructor Destroy; override; + + procedure Assign(Source: TPersistent); override; + property Temporary: Boolean read FTemporary write FTemporary; + property Name: string read FIndexName write SetIndexName; + property Expression: string read FExpression write SetExpression; + published + property IndexFile: string read FIndexName write SetIndexName; + property SortField: string read FExpression write SetExpression; + property Options: TIndexOptions read FOptions write FOptions; + end; + + TDbfIndexParser = class(TDbfParser) + protected + FResultLen: Integer; + + procedure ValidateExpression(AExpression: string); override; + public + property ResultLen: Integer read FResultLen; + end; +//=========================================================================== + TIndexFile = class; + TIndexPageClass = class of TIndexPage; + + TIndexPage = class(TObject) + protected + FIndexFile: TIndexFile; + FLowerPage: TIndexPage; + FUpperPage: TIndexPage; + FPageBuffer: Pointer; + FEntry: Pointer; + FEntryNo: Integer; + FLockCount: Integer; + FModified: Boolean; + FPageNo: Integer; + FWeight: Integer; + + // bracket props + FLowBracket: Integer; // = FLowIndex if FPageNo = FLowPage + FLowIndex: Integer; + FLowPage: Integer; + FLowPageTemp: Integer; + FHighBracket: Integer; // = FHighIndex if FPageNo = FHighPage + FHighIndex: Integer; + FHighPage: Integer; + FHighPageTemp: Integer; + + procedure LocalInsert(RecNo: Integer; Buffer: PChar; LowerPageNo: Integer); + procedure LocalDelete; + procedure Delete; + + procedure SyncLowerPage; + procedure WritePage; + procedure Split; + procedure LockPage; + procedure UnlockPage; + + function RecurPrev: Boolean; + function RecurNext: Boolean; + procedure RecurFirst; + procedure RecurLast; + + procedure SetEntry(RecNo: Integer; AKey: PChar; LowerPageNo: Integer); + procedure SetEntryNo(value: Integer); + procedure SetPageNo(NewPageNo: Integer); + procedure SetLowPage(NewPage: Integer); + procedure SetHighPage(NewPage: Integer); + procedure SetUpperPage(NewPage: TIndexPage); + procedure UpdateBounds(IsInnerNode: Boolean); + + protected + function GetEntry(AEntryNo: Integer): Pointer; virtual; abstract; + function GetLowerPageNo: Integer; virtual; abstract; + function GetKeyData: PChar; virtual; abstract; + function GetNumEntries: Integer; virtual; abstract; + function GetKeyDataFromEntry(AEntry: Integer): PChar; virtual; abstract; + function GetRecNo: Integer; virtual; abstract; + function GetIsInnerNode: Boolean; virtual; abstract; + procedure IncNumEntries; virtual; abstract; + procedure SetNumEntries(NewNum: Integer); virtual; abstract; + procedure SetRecLowerPageNo(NewRecNo, NewPageNo: Integer); virtual; abstract; + procedure SetRecLowerPageNoOfEntry(AEntry, NewRecNo, NewPageNo: Integer); virtual; abstract; +{$ifdef TDBF_UPDATE_FIRST_LAST_NODE} + procedure SetPrevBlock(NewBlock: Integer); virtual; +{$endif} + + public + constructor Create(Parent: TIndexFile); + destructor Destroy; override; + + function FindNearest(ARecNo: Integer): Integer; + function PhysicalRecNo: Integer; + function MatchKey: Integer; + procedure GotoInsertEntry; + + procedure Clear; + procedure GetNewPage; + procedure Modified; + procedure RecalcWeight; + procedure UpdateWeight; + procedure Flush; + procedure SaveBracket; + procedure RestoreBracket; + + property Key: PChar read GetKeyData; + property Entry: Pointer read FEntry; + property EntryNo: Integer read FEntryNo write SetEntryNo; + property IndexFile: TIndexFile read FIndexFile; + property UpperPage: TIndexPage read FUpperPage write SetUpperPage; + property LowerPage: TIndexPage read FLowerPage; +// property LowerPageNo: Integer read GetLowerPageNo; // never used + property PageBuffer: Pointer read FPageBuffer; + property PageNo: Integer read FPageNo write SetPageNo; + property Weight: Integer read FWeight; + + property NumEntries: Integer read GetNumEntries; + property HighBracket: Integer read FHighBracket write FHighBracket; + property HighIndex: Integer read FHighIndex; + property HighPage: Integer read FHighPage write SetHighPage; + property LowBracket: Integer read FLowBracket write FLowBracket; + property LowIndex: Integer read FLowIndex; + property LowPage: Integer read FLowPage write SetLowPage; + end; +//=========================================================================== + TIndexTag = class(TObject) + private + FTag: Pointer; + protected + function GetHeaderPageNo: Integer; virtual; abstract; + function GetTagName: string; virtual; abstract; + function GetKeyFormat: Byte; virtual; abstract; + function GetForwardTag1: Byte; virtual; abstract; + function GetForwardTag2: Byte; virtual; abstract; + function GetBackwardTag: Byte; virtual; abstract; + function GetReserved: Byte; virtual; abstract; + function GetKeyType: Char; virtual; abstract; + procedure SetHeaderPageNo(NewPageNo: Integer); virtual; abstract; + procedure SetTagName(NewName: string); virtual; abstract; + procedure SetKeyFormat(NewFormat: Byte); virtual; abstract; + procedure SetForwardTag1(NewTag: Byte); virtual; abstract; + procedure SetForwardTag2(NewTag: Byte); virtual; abstract; + procedure SetBackwardTag(NewTag: Byte); virtual; abstract; + procedure SetReserved(NewReserved: Byte); virtual; abstract; + procedure SetKeyType(NewType: Char); virtual; abstract; + public + property HeaderPageNo: Integer read GetHeaderPageNo write SetHeaderPageNo; + property TagName: string read GetTagName write SetTagName; + property KeyFormat: Byte read GetKeyFormat write SetKeyFormat; + property ForwardTag1: Byte read GetForwardTag1 write SetForwardTag1; + property ForwardTag2: Byte read GetForwardTag2 write SetForwardTag2; + property BackwardTag: Byte read GetBackwardTag write SetBackwardTag; + property Reserved: Byte read GetReserved write SetReserved; + property KeyType: Char read GetKeyType write SetKeyType; + property Tag: Pointer read FTag write FTag; + end; +//=========================================================================== +{$ifdef USE_CACHE} + TIndexFile = class(TCachedFile) +{$else} + TIndexFile = class(TPagedFile) +{$endif} + protected + FIndexName: string; + FLastError: string; + FParsers: array[0..MaxIndexes-1] of TDbfIndexParser; + FIndexHeaders: array[0..MaxIndexes-1] of Pointer; + FIndexHeaderModified: array[0..MaxIndexes-1] of Boolean; + FIndexHeader: Pointer; + FIndexVersion: TXBaseVersion; + FRoots: array[0..MaxIndexes-1] of TIndexPage; + FLeaves: array[0..MaxIndexes-1] of TIndexPage; + FCurrentParser: TDbfIndexParser; + FRoot: TIndexPage; + FLeaf: TIndexPage; + FMdxTag: TIndexTag; + FTempMdxTag: TIndexTag; + FEntryHeaderSize: Integer; + FPageHeaderSize: Integer; + FTagSize: Integer; + FTagOffset: Integer; + FHeaderPageNo: Integer; + FSelectedIndex: Integer; + FRangeIndex: Integer; + FIsDescending: Boolean; + FUniqueMode: TIndexUniqueType; + FModifyMode: TIndexModifyMode; + FHeaderLocked: Integer; // used to remember which header page we have locked + FKeyBuffer: array[0..100] of Char; + FLowBuffer: array[0..100] of Char; + FHighBuffer: array[0..100] of Char; + FEntryBof: Pointer; + FEntryEof: Pointer; + FDbfFile: Pointer; + FCanEdit: Boolean; + FOpened: Boolean; + FRangeActive: Boolean; + FUpdateMode: TIndexUpdateMode; + FUserKey: PChar; // find / insert key + FUserRecNo: Integer; // find / insert recno + FUserBCD: array[0..10] of Byte; + FUserNumeric: Double; + FForceClose: Boolean; + FForceReadOnly: Boolean; + FCodePage: Integer; + FCollation: PCollationTable; + FCompareKeys: TDbfCompareKeysEvent; + FOnLocaleError: TDbfLocaleErrorEvent; + + function GetNewPageNo: Integer; + procedure TouchHeader(AHeader: Pointer); + function CreateTempFile(BaseName: string): TPagedFile; + procedure ConstructInsertErrorMsg; + procedure WriteIndexHeader(AIndex: Integer); + procedure SelectIndexVars(AIndex: Integer); + procedure CalcKeyProperties; + procedure UpdateIndexProperties; + procedure ClearRoots; + function CalcTagOffset(AIndex: Integer): Pointer; + + function FindKey(AInsert: boolean): Integer; + function InsertKey(Buffer: TRecordBuffer): Boolean; + procedure DeleteKey(Buffer: TRecordBuffer); + function InsertCurrent: Boolean; + procedure DeleteCurrent; + function UpdateCurrent(PrevBuffer, NewBuffer: TRecordBuffer): Boolean; + function UpdateIndex(Index: Integer; PrevBuffer, NewBuffer: TRecordBuffer): Boolean; + procedure ReadIndexes; + procedure Resync(Relative: boolean); + procedure ResyncRoot; + procedure ResyncTree; + procedure ResyncRange(KeepPosition: boolean); + procedure ResetRange; + procedure SetBracketLow; + procedure SetBracketHigh; + + procedure WalkFirst; + procedure WalkLast; + function WalkPrev: boolean; + function WalkNext: boolean; + + function CompareKeysNumericNDX(Key1, Key2: PChar): Integer; + function CompareKeysNumericMDX(Key1, Key2: PChar): Integer; + function CompareKeysString(Key1, Key2: PChar): Integer; + + // property functions + function GetName: string; + function GetDbfLanguageId: Byte; + function GetKeyLen: Integer; + function GetKeyType: Char; +// function GetIndexCount Integer; + function GetExpression: string; + function GetPhysicalRecNo: Integer; + function GetSequentialRecNo: Integer; + function GetSequentialRecordCount: Integer; + procedure SetSequentialRecNo(RecNo: Integer); + procedure SetPhysicalRecNo(RecNo: Integer); + procedure SetUpdateMode(NewMode: TIndexUpdateMode); + procedure SetIndexName(const AIndexName: string); + + public + constructor Create(ADbfFile: Pointer); + destructor Destroy; override; + + procedure Open; + procedure Close; + + procedure Clear; + procedure Flush; override; + procedure ClearIndex; + procedure AddNewLevel; + procedure UnlockHeader; + procedure InsertError; + function Insert(RecNo: Integer; Buffer:TRecordBuffer ): Boolean; + function Update(RecNo: Integer; PrevBuffer, NewBuffer: TRecordBuffer): Boolean; + procedure Delete(RecNo: Integer; Buffer: TRecordBuffer); + function CheckKeyViolation(Buffer: TRecordBuffer): Boolean; + procedure RecordDeleted(RecNo: Integer; Buffer: TRecordBuffer); + function RecordRecalled(RecNo: Integer; Buffer: TRecordBuffer): Boolean; + procedure DeleteIndex(const AIndexName: string); + procedure RepageFile; + procedure CompactFile; + procedure PrepareRename(NewFileName: string); + + procedure CreateIndex(FieldDesc, TagName: string; Options: TIndexOptions); + function ExtractKeyFromBuffer(Buffer: TRecordBuffer): PChar; + function SearchKey(Key: PChar; SearchType: TSearchKeyType): Boolean; + function Find(RecNo: Integer; Buffer: PChar): Integer; + function IndexOf(const AIndexName: string): Integer; + procedure DisableRange; + procedure EnableRange; + + procedure GetIndexNames(const AList: TStrings); + procedure GetIndexInfo(const AIndexName: string; IndexDef: TDbfIndexDef); + procedure WriteHeader; override; + procedure WriteFileHeader; + + procedure First; + procedure Last; + function Next: Boolean; + function Prev: Boolean; + + procedure SetRange(LowRange, HighRange: PChar); + procedure CancelRange; + function MatchKey(UserKey: PChar): Integer; + function CompareKey(Key: PChar): Integer; + function CompareKeys(Key1, Key2: PChar): Integer; + function PrepareKey(Buffer: TRecordBuffer; ResultType: TExpressionType): PChar; + + property KeyLen: Integer read GetKeyLen; + property IndexVersion: TXBaseVersion read FIndexVersion; + property EntryHeaderSize: Integer read FEntryHeaderSize; + property KeyType: Char read GetKeyType; + + property SequentialRecordCount: Integer read GetSequentialRecordCount; + property SequentialRecNo: Integer read GetSequentialRecNo write SetSequentialRecNo; + property PhysicalRecNo: Integer read GetPhysicalRecNo write SetPhysicalRecNo; + property HeaderPageNo: Integer read FHeaderPageNo; + + property IndexHeader: Pointer read FIndexHeader; + property EntryBof: Pointer read FEntryBof; + property EntryEof: Pointer read FEntryEof; + property UniqueMode: TIndexUniqueType read FUniqueMode; + property IsDescending: Boolean read FIsDescending; + + property UpdateMode: TIndexUpdateMode read FUpdateMode write SetUpdateMode; + property IndexName: string read FIndexName write SetIndexName; + property Expression: string read GetExpression; +// property Count: Integer read GetIndexCount; + + property ForceClose: Boolean read FForceClose; + property ForceReadOnly: Boolean read FForceReadOnly; + property CodePage: Integer read FCodePage write FCodePage; + + property OnLocaleError: TDbfLocaleErrorEvent read FOnLocaleError write FOnLocaleError; + end; + +//------------------------------------------------------------------------------ +implementation + +uses + dbf_dbffile, + dbf_fields, + dbf_str, + mdbf_prssupp, + mdbf_prscore, + dbf_lang; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + RecBOF = 0; + RecEOF = MaxInt; + + lcidBinary = $0A03; + + KeyFormat_Expression = $00; + KeyFormat_Data = $10; + + KeyFormat_Descending = $08; + KeyFormat_String = $10; + KeyFormat_Distinct = $20; + KeyFormat_Unique = $40; + + Unique_None = $00; + Unique_Unique = $01; + Unique_Distinct = $21; + +type + + TLCIDList = class(TList) + public + constructor Create; + + procedure Enumerate; + end; + + PMdxHdr = ^rMdxHdr; + rMdxHdr = record + MdxVersion : Byte; // 0 + Year : Byte; // 1 + Month : Byte; // 2 + Day : Byte; // 3 + FileName : array[0..15] of Char; // 4..19 + BlockSize : Word; // 20..21 + BlockAdder : Word; // 22..23 + ProdFlag : Byte; // 24 + NumTags : Byte; // 25 + TagSize : Byte; // 26 + Dummy1 : Byte; // 27 + TagsUsed : Word; // 28..29 + Dummy2 : Byte; // 30 + Language : Byte; // 31 + NumPages : Integer; // 32..35 + FreePage : Integer; // 36..39 + BlockFree : Integer; // 40..43 + UpdYear : Byte; // 44 + UpdMonth : Byte; // 45 + UpdDay : Byte; // 46 + Reserved : array[0..481] of Byte; // 47..528 + TagFlag : Byte; // 529 // dunno what this means but it ought to be 1 :-) + end; + + // Tags -> I don't know what to with them + // KeyType -> Variable position, db7 different from db4 + + PMdx4Tag = ^rMdx4Tag; + rMdx4Tag = record + HeaderPageNo : Integer; // 0..3 + TagName : array [0..10] of Char; // 4..14 of Byte + KeyFormat : Byte; // 15 00h: Calculated + // 10h: Data Field + ForwardTag1 : Byte; // 16 + ForwardTag2 : Byte; // 17 + BackwardTag : Byte; // 18 + Reserved : Byte; // 19 + KeyType : Char; // 20 C : Character + // N : Numerical + // D : Date + end; + + PMdx7Tag = ^rMdx7Tag; + rMdx7Tag = record + HeaderPageNo : Integer; // 0..3 + TagName : array [0..32] of Char; // 4..36 of Byte + KeyFormat : Byte; // 37 00h: Calculated + // 10h: Data Field + ForwardTag1 : Byte; // 38 + ForwardTag2 : Byte; // 39 + BackwardTag : Byte; // 40 + Reserved : Byte; // 41 + KeyType : Char; // 42 C : Character + // N : Numerical + // D : Date + end; + + PIndexHdr = ^rIndexHdr; + rIndexHdr = record + RootPage : Integer; // 0..3 + NumPages : Integer; // 4..7 + KeyFormat : Byte; // 8 00h: Right, Left, DTOC + // 08h: Descending order + // 10h: String + // 20h: Distinct + // 40h: Unique + KeyType : Char; // 9 C : Character + // N : Numerical + // D : Date + Dummy : Word; // 10..11 + KeyLen : Word; // 12..13 + NumKeys : Word; // 14..15 + sKeyType : Word; // 16..17 00h: DB4: C/N; DB3: C + // 01h: DB4: D ; DB3: N/D + KeyRecLen : Word; // 18..19 Length of key entry in page + Version : Word; // 20..21 + Dummy2 : Byte; // 22 + Unique : Byte; // 23 + KeyDesc : array [0..219] of Char; // 24..243 + Dummy3 : Byte; // 244 + ForExist : Byte; // 245 + KeyExist : Byte; // 246 + FirstNode : Longint; // 248..251 first node that contains data + LastNode : Longint; // 252..255 last node that contains data + // MDX Header has here a 506 byte block reserved + // and then the FILTER expression, which obviously doesn't + // fit in a NDX page, so we'll skip it + end; + + PMdxEntry = ^rMdxEntry; + rMdxEntry = record + RecBlockNo: Longint; // 0..3 either recno or blockno + KeyData : Char; // 4.. first byte of data, context => length + end; + + PMdxPage = ^rMdxPage; + rMdxPage = record + NumEntries : Integer; + PrevBlock : Integer; + FirstEntry : rMdxEntry; + end; + + PNdxEntry = ^rNdxEntry; + rNdxEntry = record + LowerPageNo: Integer; // 0..3 lower page + RecNo : Integer; // 4..7 recno + KeyData : Char; + end; + + PNdxPage = ^rNdxPage; + rNdxPage = record + NumEntries: Integer; // 0..3 + FirstEntry: rNdxEntry; + end; + +//--------------------------------------------------------------------------- + TMdxPage = class(TIndexPage) + protected + function GetEntry(AEntryNo: Integer): Pointer; override; + function GetLowerPageNo: Integer; override; + function GetKeyData: PChar; override; + function GetNumEntries: Integer; override; + function GetKeyDataFromEntry(AEntry: Integer): PChar; override; + function GetRecNo: Integer; override; + function GetIsInnerNode: Boolean; override; + procedure IncNumEntries; override; + procedure SetNumEntries(NewNum: Integer); override; + procedure SetRecLowerPageNo(NewRecNo, NewPageNo: Integer); override; + procedure SetRecLowerPageNoOfEntry(AEntry, NewRecNo, NewPageNo: Integer); override; +{$ifdef TDBF_UPDATE_FIRST_LAST_NODE} + procedure SetPrevBlock(NewBlock: Integer); override; +{$endif} + end; +//--------------------------------------------------------------------------- + TNdxPage = class(TIndexPage) + protected + function GetEntry(AEntryNo: Integer): Pointer; override; + function GetLowerPageNo: Integer; override; + function GetKeyData: PChar; override; + function GetNumEntries: Integer; override; + function GetKeyDataFromEntry(AEntry: Integer): PChar; override; + function GetRecNo: Integer; override; + function GetIsInnerNode: Boolean; override; + procedure IncNumEntries; override; + procedure SetNumEntries(NewNum: Integer); override; + procedure SetRecLowerPageNo(NewRecNo, NewPageNo: Integer); override; + procedure SetRecLowerPageNoOfEntry(AEntry, NewRecNo, NewPageNo: Integer); override; + end; +//--------------------------------------------------------------------------- + TMdx4Tag = class(TIndexTag) + protected + function GetHeaderPageNo: Integer; override; + function GetTagName: string; override; + function GetKeyFormat: Byte; override; + function GetForwardTag1: Byte; override; + function GetForwardTag2: Byte; override; + function GetBackwardTag: Byte; override; + function GetReserved: Byte; override; + function GetKeyType: Char; override; + procedure SetHeaderPageNo(NewPageNo: Integer); override; + procedure SetTagName(NewName: string); override; + procedure SetKeyFormat(NewFormat: Byte); override; + procedure SetForwardTag1(NewTag: Byte); override; + procedure SetForwardTag2(NewTag: Byte); override; + procedure SetBackwardTag(NewTag: Byte); override; + procedure SetReserved(NewReserved: Byte); override; + procedure SetKeyType(NewType: Char); override; + end; +//--------------------------------------------------------------------------- + TMdx7Tag = class(TIndexTag) + function GetHeaderPageNo: Integer; override; + function GetTagName: string; override; + function GetKeyFormat: Byte; override; + function GetForwardTag1: Byte; override; + function GetForwardTag2: Byte; override; + function GetBackwardTag: Byte; override; + function GetReserved: Byte; override; + function GetKeyType: Char; override; + procedure SetHeaderPageNo(NewPageNo: Integer); override; + procedure SetTagName(NewName: string); override; + procedure SetKeyFormat(NewFormat: Byte); override; + procedure SetForwardTag1(NewTag: Byte); override; + procedure SetForwardTag2(NewTag: Byte); override; + procedure SetBackwardTag(NewTag: Byte); override; + procedure SetReserved(NewReserved: Byte); override; + procedure SetKeyType(NewType: Char); override; + end; + +var + Entry_Mdx_BOF: rMdxEntry; //(RecBOF, #0); + Entry_Mdx_EOF: rMdxEntry; //(RecBOF, #0); + Entry_Ndx_BOF: rNdxEntry; //(0, RecBOF, #0); + Entry_Ndx_EOF: rNdxEntry; //(0, RecEOF, #0); + + LCIDList: TLCIDList; + +procedure IncWordLE(var AVariable: Word; Amount: Integer); +begin + AVariable := SwapWordLE(SwapWordLE(AVariable) + Amount); +end; + +procedure IncIntLE(var AVariable: Integer; Amount: Integer); +begin + AVariable := SwapIntLE(DWord(Integer(SwapIntLE(AVariable)) + Amount)); +end; + +//========================================================== +// Locale support for all versions of Delphi/C++Builder + +function LocaleCallBack(LocaleString: PChar): Integer; stdcall; +begin + LCIDList.Add(Pointer(ptrint(StrToInt('$'+LocaleString)))); + Result := 1; +end; + +constructor TLCIDList.Create; +begin + inherited; +end; + +procedure TLCIDList.Enumerate; +begin + Clear; + EnumSystemLocales(@LocaleCallBack, LCID_SUPPORTED); +end; + +{ TIndexPage } + +constructor TIndexPage.Create(Parent: TIndexFile); +begin + FIndexFile := Parent; + GetMem(FPageBuffer, FIndexFile.RecordSize); + FLowerPage := nil; + Clear; +end; + +destructor TIndexPage.Destroy; +begin + // no locks anymore? + assert(FLockCount = 0); + if (FLowerPage<>nil) then + LowerPage.Free; + WritePage; + FreeMemAndNil(FPageBuffer); + inherited Destroy; +end; + +procedure TIndexPage.Clear; +begin + FillChar(PChar(FPageBuffer)^, FIndexFile.RecordSize, 0); + FreeAndNil(FLowerPage); + FUpperPage := nil; + FPageNo := -1; + FEntryNo := -1; + FWeight := 1; + FModified := false; + FEntry := FIndexFile.EntryBof; + FLowPage := 0; + FHighPage := 0; + FLowIndex := 0; + FHighIndex := -1; + FLockCount := 0; +end; + +procedure TIndexPage.GetNewPage; +begin + FPageNo := FIndexFile.GetNewPageNo; +end; + +procedure TIndexPage.Modified; +begin + FModified := true; +end; + +procedure TIndexPage.LockPage; +begin + // already locked? + if FLockCount = 0 then + FIndexFile.LockPage(FPageNo, true); + // increase count + inc(FLockCount); +end; + +procedure TIndexPage.UnlockPage; +begin + // still in domain? + assert(FLockCount > 0); + dec(FLockCount); + // unlock? + if FLockCount = 0 then + begin + if FIndexFile.NeedLocks then + WritePage; + FIndexFile.UnlockPage(FPageNo); + end; +end; + +procedure TIndexPage.LocalInsert(RecNo: Integer; Buffer: PChar; LowerPageNo: Integer); + // *) assumes there is at least one entry free +var + source, dest: Pointer; + size, lNumEntries, numKeysAvail: Integer; +begin + // lock page if needed; wait if not available, anyone else updating? + LockPage; + // check assertions + lNumEntries := GetNumEntries; + // if this is inner node, we can only store one less than max entries + numKeysAvail := SwapWordLE(PIndexHdr(FIndexFile.IndexHeader)^.NumKeys) - lNumEntries; + if FLowerPage <> nil then + dec(numKeysAvail); + // check if free space + assert(numKeysAvail > 0); + // first free up some space + source := FEntry; + dest := GetEntry(FEntryNo + 1); + size := (lNumEntries - EntryNo) * SwapWordLE(PIndexHdr(FIndexFile.IndexHeader)^.KeyRecLen); + // if 'rightmost' entry, copy pageno too + if (FLowerPage <> nil) or (numKeysAvail > 1) then + size := size + FIndexFile.EntryHeaderSize; + Move(source^, dest^, size); + // one entry added + Inc(FHighIndex); + IncNumEntries; + // lNumEntries not valid from here + SetEntry(RecNo, Buffer, LowerPageNo); + // done! + UnlockPage; +end; + +procedure TIndexPage.LocalDelete; + + function IsOnlyEntry(Page: TIndexPage): boolean; + begin + Result := true; + repeat + if Page.HighIndex > 0 then + Result := false; + Page := Page.UpperPage; + until not Result or (Page = nil); + end; + +var + source, dest: Pointer; + size, lNumEntries: Integer; +begin + // get num entries + lNumEntries := GetNumEntries; + // is this last entry? if it's not move entries after current one + if EntryNo < FHighIndex then + begin + source := GetEntry(EntryNo + 1); + dest := FEntry; + size := (FHighIndex - EntryNo) * SwapWordLE(PIndexHdr(FIndexFile.IndexHeader)^.KeyRecLen); + Move(source^, dest^, size); + end else + // no need to update when we're about to remove the only entry + if (UpperPage <> nil) and (FHighIndex > FLowIndex) then + begin + // we are about to remove the last on this page, so update search + // key data of parent + EntryNo := FHighIndex - 1; + UpperPage.SetEntry(0, GetKeyData, FPageNo); + end; + // one entry less now + dec(lNumEntries); + dec(FHighIndex); + SetNumEntries(lNumEntries); + // zero last one out to not get confused about internal or leaf pages + // note: need to decrease lNumEntries and HighIndex first, otherwise + // check on page key consistency will fail + SetRecLowerPageNoOfEntry(FHighIndex+1, 0, 0); + // update bracket indexes + if FHighPage = FPageNo then + dec(FHighBracket); + // check if range violated + if EntryNo > FHighIndex then + EntryNo := FHighIndex; + // check if still entries left, otherwise remove page from parent + if FHighIndex = -1 then + begin + if UpperPage <> nil then + if not IsOnlyEntry(UpperPage) then + UpperPage.LocalDelete; + end; + // go to valid record in lowerpage + if FLowerPage <> nil then + SyncLowerPage; + // flag modified page + FModified := true; + // success! +end; + +function TIndexPage.MatchKey: Integer; + // assumes Buffer <> nil +var + keyData: PChar; +begin + // get key data + keyData := GetKeyData; + // use locale dependant compare + Result := FIndexFile.CompareKey(keyData); +end; + +function TIndexPage.FindNearest(ARecNo: Integer): Integer; + // pre: + // assumes Key <> nil + // assumes FLowIndex <= FHighIndex + 1 + // ARecNo = -2 -> search first key matching Key + // ARecNo = -3 -> search first key greater than Key + // ARecNo > 0 -> search key matching Key and its recno = ARecNo + // post: + // Result < 0 -> key,recno smaller than current entry + // Result = 0 -> key,recno found, FEntryNo = found key entryno + // Result > 0 -> key,recno larger than current entry +var + low, high, current: Integer; +begin + // implement binary search, keys are sorted + low := FLowIndex; + high := GetNumEntries; + // always true: Entry(FEntryNo) = FEntry + // FHighIndex >= 0 because no-entry cases in leaves have been filtered out + // entry HighIndex may not be bigger than rest (in inner node) + // ARecNo = -3 -> search last recno matching key + // need to have: low <= high + // define low - 1 = neg.inf. + // define high = pos.inf + // inv1: (ARecNo<>-3) -> Entry(low-1).Key < Key <= Entry(high).Key + // inv2: (ARecNo =-3) -> Entry(low-1).Key <= Key < Entry(high).Key + // vf: high + 1 - low + while low < high do + begin + current := (low + high) div 2; + FEntry := GetEntry(current); + // calc diff + Result := MatchKey; + // test if we need to go lower or higher + // result < 0 implies key smaller than tested entry + // result = 0 implies key equal to tested entry + // result > 0 implies key greater than tested entry + if (Result < 0) or ((ARecNo<>-3) and (Result=0)) then + high := current + else + low := current+1; + end; + // high will contain first greater-or-equal key + // ARecNo <> -3 -> Entry(high).Key will contain first key that matches -> go to high + // ARecNo = -3 -> Entry(high).Key will contain first key that is greater -> go to high + FEntryNo := -1; + EntryNo := high; + // calc end result: can't inspect high if lowerpage <> nil + // if this is a leaf, we need to find specific recno + if (LowerPage = nil) then + begin + if high > FHighIndex then + begin + Result := 1; + end else begin + Result := MatchKey; + // test if we need to find a specific recno + // result < 0 -> current key greater -> nothing found -> don't search + if (ARecNo > 0) then + begin + // BLS to RecNo + high := FHighIndex + 1; + low := FEntryNo; + // inv: FLowIndex <= FEntryNo <= high <= FHighIndex + 1 /\ + // (Ai: FLowIndex <= i < FEntryNo: Entry(i).RecNo <> ARecNo) + while FEntryNo <> high do + begin + // FEntryNo < high, get new entry + if low <> FEntryNo then + begin + FEntry := GetEntry(FEntryNo); + // check if entry key still ok + Result := MatchKey; + end; + // test if out of range or found recno + if (Result <> 0) or (GetRecNo = ARecNo) then + high := FEntryNo + else begin + // default to EOF + inc(FEntryNo); + Result := 1; + end; + end; + end; + end; + end else begin + // FLowerPage <> nil -> high contains entry, can not have empty range + Result := 0; + end; +end; + +procedure TIndexPage.GotoInsertEntry; + // assures we really can insert here +begin + if FEntry = FIndexFile.EntryEof then + FEntry := GetEntry(FEntryNo); +end; + +procedure TIndexPage.SetEntry(RecNo: Integer; AKey: PChar; LowerPageNo: Integer); +var + keyData: PChar; +{$ifdef TDBF_INDEX_CHECK} + prevKeyData, curKeyData, nextKeyData: PChar; +{$endif} +begin + // get num entries + keyData := GetKeyData; + // check valid entryno: we should be able to insert entries! + assert((EntryNo >= 0) and (EntryNo <= FHighIndex)); + if (UpperPage <> nil) and (FEntryNo = FHighIndex) then + UpperPage.SetEntry(0, AKey, FPageNo); +{ if PIndexHdr(FIndexFile.IndexHeader).KeyType = 'C' then } + if AKey <> nil then + Move(AKey^, keyData^, SwapWordLE(PIndexHdr(FIndexFile.IndexHeader)^.KeyLen)) + else + PChar(keyData)^ := #0; +{ + else + if AKey <> nil then + PDouble(keyData)^ := PDouble(AKey)^ + else + PDouble(keyData)^ := 0.0; +} + // set entry info + SetRecLowerPageNo(RecNo, LowerPageNo); + // flag we modified the page + FModified := true; + +{$ifdef TDBF_INDEX_CHECK} + + // check sorted entry sequence + prevKeyData := GetKeyDataFromEntry(FEntryNo-1); + curKeyData := GetKeyDataFromEntry(FEntryNo+0); + nextKeyData := GetKeyDataFromEntry(FEntryNo+1); + // check if prior entry not greater, 'rightmost' key does not have to match + if (FEntryNo > 0) and ((FLowerPage = nil) or (FEntryNo < FHighIndex)) then + begin + if FIndexFile.CompareKeys(prevKeyData, curKeyData) > 0 then + assert(false); + end; + // check if next entry not smaller + if ((FLowerPage = nil) and (FEntryNo < FHighIndex)) or + ((FLowerPage <> nil) and (FEntryNo < (FHighIndex - 1))) then + begin + if FIndexFile.CompareKeys(curKeyData, nextKeyData) > 0 then + assert(false); + end; + +{$endif} + +end; + +{$ifdef TDBF_UPDATE_FIRST_LAST_NODE} + +procedure TIndexPage.SetPrevBlock(NewBlock: Integer); +begin +end; + +{$endif} + +procedure TIndexPage.Split; + // *) assumes this page is `nearly' full +var + NewPage: TIndexPage; + source, dest: Pointer; + paKeyData: PChar; + size, oldEntryNo: Integer; + splitRight, lNumEntries, numEntriesNew: Integer; + saveLow, saveHigh: Integer; + newRoot: Boolean; +begin + // assure parent exists, if not -> create & lock, else lock it + newRoot := FUpperPage = nil; + if newRoot then + FIndexFile.AddNewLevel + else + FUpperPage.LockPage; + + // lock this page for updates + LockPage; + + // get num entries + lNumEntries := GetNumEntries; + + // calc split pos: split in half + splitRight := lNumEntries div 2; + if (FLowerPage <> nil) and (lNumEntries mod 2 = 1) then + inc(splitRight); + numEntriesNew := lNumEntries - splitRight; + // check if place to insert has least entries + if (numEntriesNew > splitRight) and (EntryNo > splitRight) then + begin + inc(splitRight); + dec(numEntriesNew); + end else if (numEntriesNew < splitRight) and (EntryNo < splitRight) then + begin + dec(splitRight); + inc(numEntriesNew); + end; + // save current entryno + oldEntryNo := EntryNo; + // check if we need to save high / low bound + if FLowPage = FPageNo then + saveLow := FLowIndex + else + saveLow := -1; + if FHighPage = FPageNo then + saveHigh := FHighIndex + else + saveHigh := -1; + + // create new page + NewPage := TIndexPageClass(ClassType).Create(FIndexFile); + try + // get page + NewPage.GetNewPage; +{$ifdef TDBF_UPDATE_FIRSTLAST_NODE} + NewPage.SetPrevBlock(NewPage.PageNo - FIndexFile.PagesPerRecord); +{$endif} + + // set modified + FModified := true; + NewPage.FModified := true; + + // compute source, dest + dest := NewPage.GetEntry(0); + source := GetEntry(splitRight); + size := numEntriesNew * SwapWordLE(PIndexHdr(FIndexFile.IndexHeader)^.KeyRecLen); + // if inner node, copy rightmost entry too + if FLowerPage <> nil then + size := size + FIndexFile.EntryHeaderSize; + // copy bytes + Move(source^, dest^, size); + // if not inner node, clear possible 'rightmost' entry + if (FLowerPage = nil) then + SetRecLowerPageNoOfEntry(splitRight, 0, 0); + + // calc new number of entries of this page + lNumEntries := lNumEntries - numEntriesNew; + // if lower level, then we need adjust for new 'rightmost' node + if FLowerPage <> nil then + begin + // right split, so we need 'new' rightmost node + dec(lNumEntries); + end; + // store new number of nodes + // new page is right page, so update parent to point to new right page + NewPage.SetNumEntries(numEntriesNew); + SetNumEntries(lNumEntries); + // update highindex + FHighIndex := lNumEntries; + if FLowerPage = nil then + dec(FHighIndex); + + // get data of last entry on this page + paKeyData := GetKeyDataFromEntry(splitRight - 1); + + // reinsert ourself into parent +// FUpperPage.RecurInsert(0, paKeyData, FPageNo); + // we can do this via a localinsert now: we know there is at least one entry + // free in this page and higher up + FUpperPage.LocalInsert(0, paKeyData, FPageNo); + + // new page is right page, so update parent to point to new right page + // we can't do this earlier: we will get lost in tree! + FUpperPage.SetRecLowerPageNoOfEntry(FUpperPage.EntryNo+1, 0, NewPage.PageNo); + + // NOTE: UpperPage.LowerPage = Self <= inserted FPageNo, not NewPage.PageNo + finally + NewPage.Free; + end; + + // done updating: unlock page + UnlockPage; + // save changes to parent + FUpperPage.UnlockPage; + + // unlock new root, unlock header too + FIndexFile.UnlockHeader; + + // go to entry we left on + if oldEntryNo >= splitRight then + begin + // sync upperpage with right page + FUpperPage.EntryNo := FUpperPage.EntryNo + 1; + FEntryNo := oldEntryNo - splitRight; + FEntry := GetEntry(FEntryNo); + end else begin + // in left page = this page + EntryNo := oldEntryNo; + end; + + // check if we have to save high / low bound + // seen the fact that FHighPage = FPageNo -> EntryNo <= FHighIndex, it can in + // theory not happen that page is advanced to right page and high bound remains + // on left page, but we won't check for that here + if saveLow >= splitRight then + begin + FLowPage := FPageNo; + FLowIndex := saveLow - splitRight; + end; + if saveHigh >= splitRight then + begin + FHighPage := FPageNo; + FHighIndex := saveHigh - splitRight; + end; +end; + +procedure TIndexPage.Delete; +begin + LocalDelete; +end; + +procedure TIndexPage.WritePage; +begin + // check if we modified current page + if FModified and (FPageNo > 0) then + begin + FIndexFile.WriteRecord(FPageNo, FPageBuffer); + FModified := false; + end; +end; + +procedure TIndexPage.Flush; +begin + WritePage; + if FLowerPage <> nil then + FLowerPage.Flush; +end; + +procedure TIndexPage.RecalcWeight; +begin + if FLowerPage <> nil then + begin + FWeight := FLowerPage.Weight * SwapWordLE(PIndexHdr(FIndexFile.IndexHeader)^.NumKeys); + end else begin + FWeight := 1; + end; + if FUpperPage <> nil then + FUpperPage.RecalcWeight; +end; + +procedure TIndexPage.UpdateWeight; +begin + if FLowerPage <> nil then + FLowerPage.UpdateWeight + else + RecalcWeight; +end; + +procedure TIndexPage.SetUpperPage(NewPage: TIndexPage); +begin + if FUpperPage <> NewPage then + begin + // root height changed: update weights + FUpperPage := NewPage; + UpdateWeight; + end; +end; + +procedure TIndexPage.SetLowPage(NewPage: Integer); +begin + if FLowPage <> NewPage then + begin + FLowPage := NewPage; + UpdateBounds(FLowerPage <> nil); + end; +end; + +procedure TIndexPage.SetHighPage(NewPage: Integer); +begin + if FHighPage <> NewPage then + begin + FHighPage := NewPage; + UpdateBounds(FLowerPage <> nil); + end; +end; + +procedure TIndexPage.UpdateBounds(IsInnerNode: Boolean); +begin + // update low / high index range + if FPageNo = FLowPage then + FLowIndex := FLowBracket + else + FLowIndex := 0; + if FPageNo = FHighPage then + FHighIndex := FHighBracket + else begin + FHighIndex := GetNumEntries; + if not IsInnerNode then + dec(FHighIndex); + end; +end; + +function TMdxPage.GetIsInnerNode: Boolean; +begin + Result := SwapIntLE(PMdxPage(FPageBuffer)^.NumEntries) < SwapWordLE(PIndexHdr(FIndexFile.IndexHeader)^.NumKeys); + // if there is still an entry after the last one, this has to be an inner node + if Result then + Result := PMdxEntry(GetEntry(PMdxPage(FPageBuffer)^.NumEntries))^.RecBlockNo <> 0; +end; + +function TNdxPage.GetIsInnerNode: Boolean; +begin + Result := PNdxEntry(GetEntry(0))^.LowerPageNo <> 0; +end; + +procedure TIndexPage.SetPageNo(NewPageNo: Integer); +var + isInnerNode: Boolean; +begin + if (NewPageNo <> FPageNo) or FIndexFile.NeedLocks then + begin + // save changes + WritePage; + // no locks + assert(FLockCount = 0); + + // goto new page + FPageNo := NewPageNo; + // remind ourselves we need to load new entry when page loaded + FEntryNo := -1; + if (NewPageNo > 0) and (NewPageNo <= FIndexFile.RecordCount) then + begin + // read page from disk + FIndexFile.ReadRecord(NewPageNo, FPageBuffer); + + // fixup descending tree + isInnerNode := GetIsInnerNode; + + // update low / high index range + UpdateBounds(isInnerNode); + + // read inner node if any + if isInnerNode then + begin + if FLowerPage = nil then + begin + FLowerPage := TIndexPageClass(ClassType).Create(FIndexFile); + FLowerPage.UpperPage := Self; + end; + // read first entry, don't do this sooner, not created lowerpage yet + // don't recursively resync all lower pages +{$ifdef TDBF_INDEX_CHECK} + end else if FLowerPage <> nil then + begin +// FLowerPage.Free; +// FLowerPage := nil; + assert(false); +{$endif} + end else begin + // we don't have to check autoresync here because we're already at lowest level + EntryNo := FLowIndex; + end; + end; + end; +end; + +procedure TIndexPage.SyncLowerPage; + // *) assumes FLowerPage <> nil! +begin + FLowerPage.PageNo := GetLowerPageNo; +end; + +procedure TIndexPage.SetEntryNo(value: Integer); +begin + // do not bother if no change + if value <> FEntryNo then + begin + // check if out of range + if (value < FLowIndex) then + begin + if FLowerPage = nil then + FEntryNo := FLowIndex - 1; + FEntry := FIndexFile.EntryBof; + end else if value > FHighIndex then begin + FEntryNo := FHighIndex + 1; + FEntry := FIndexFile.EntryEof; + end else begin + FEntryNo := value; + FEntry := GetEntry(value); + // sync lowerpage with entry + if (FLowerPage <> nil) then + SyncLowerPage; + end; + end; +end; + +function TIndexPage.PhysicalRecNo: Integer; +var + entryRec: Integer; +begin + // get num entries + entryRec := GetRecNo; + // check if in range + if (FEntryNo >= FLowIndex) and (FEntryNo <= FHighIndex) then + Result := entryRec + else + Result := -1; +end; + +function TIndexPage.RecurPrev: Boolean; +begin + EntryNo := EntryNo - 1; + Result := Entry <> FIndexFile.EntryBof; + if Result then + begin + if FLowerPage <> nil then + begin + FLowerPage.RecurLast; + end; + end else begin + if FUpperPage<>nil then + begin + Result := FUpperPage.RecurPrev; + end; + end; +end; + +function TIndexPage.RecurNext: Boolean; +begin + EntryNo := EntryNo + 1; + Result := Entry <> FIndexFile.EntryEof; + if Result then + begin + if FLowerPage <> nil then + begin + FLowerPage.RecurFirst; + end; + end else begin + if FUpperPage<>nil then + begin + Result := FUpperPage.RecurNext; + end; + end; +end; + +procedure TIndexPage.RecurFirst; +begin + EntryNo := FLowIndex; + if (FLowerPage<>nil) then + FLowerPage.RecurFirst; +end; + +procedure TIndexPage.RecurLast; +begin + EntryNo := FHighIndex; + if (FLowerPage<>nil) then + FLowerPage.RecurLast; +end; + +procedure TIndexPage.SaveBracket; +begin + FLowPageTemp := FLowPage; + FHighPageTemp := FHighPage; +end; + +procedure TIndexPage.RestoreBracket; +begin + FLowPage := FLowPageTemp; + FHighPage := FHighPageTemp; +end; + +//============================================================================== +//============ Mdx specific access routines +//============================================================================== + +function TMdxPage.GetEntry(AEntryNo: Integer): Pointer; +begin + // get base + offset + Result := PChar(@PMdxPage(PageBuffer)^.FirstEntry) + (SwapWordLE(PIndexHdr( + IndexFile.IndexHeader)^.KeyRecLen) * AEntryNo); +end; + +function TMdxPage.GetLowerPageNo: Integer; + // *) assumes LowerPage <> nil +begin +// if LowerPage = nil then +// Result := 0 +// else + Result := SwapIntLE(PMdxEntry(Entry)^.RecBlockNo); +end; + +function TMdxPage.GetKeyData: PChar; +begin + Result := @PMdxEntry(Entry)^.KeyData; +end; + +function TMdxPage.GetNumEntries: Integer; +begin + Result := SwapWordLE(PMdxPage(PageBuffer)^.NumEntries); +end; + +function TMdxPage.GetKeyDataFromEntry(AEntry: Integer): PChar; +begin + Result := @PMdxEntry(GetEntry(AEntry))^.KeyData; +end; + +function TMdxPage.GetRecNo: Integer; +begin + Result := SwapIntLE(PMdxEntry(Entry)^.RecBlockNo); +end; + +procedure TMdxPage.SetNumEntries(NewNum: Integer); +begin + PMdxPage(PageBuffer)^.NumEntries := SwapIntLE(NewNum); +end; + +procedure TMdxPage.IncNumEntries; +begin + IncIntLE(PMdxPage(PageBuffer)^.NumEntries, 1); +end; + +procedure TMdxPage.SetRecLowerPageNo(NewRecNo, NewPageNo: Integer); +begin + if FLowerPage = nil then + PMdxEntry(Entry)^.RecBlockNo := SwapIntLE(NewRecNo) + else + PMdxEntry(Entry)^.RecBlockNo := SwapIntLE(NewPageNo); +end; + +procedure TMdxPage.SetRecLowerPageNoOfEntry(AEntry, NewRecNo, NewPageNo: Integer); +begin + if FLowerPage = nil then + PMdxEntry(GetEntry(AEntry))^.RecBlockNo := SwapIntLE(NewRecNo) + else + PMdxEntry(GetEntry(AEntry))^.RecBlockNo := SwapIntLE(NewPageNo); +end; + +{$ifdef TDBF_UPDATE_FIRST_LAST_NODE} + +procedure TMdxPage.SetPrevBlock(NewBlock: Integer); +begin + PMdxPage(PageBuffer)^.PrevBlock := SwapIntLE(NewBlock); +end; + +{$endif} + +//============================================================================== +//============ Ndx specific access routines +//============================================================================== + +function TNdxPage.GetEntry(AEntryNo: Integer): Pointer; +begin + // get base + offset + Result := PChar(@PNdxPage(PageBuffer)^.FirstEntry) + + (SwapWordLE(PIndexHdr(FIndexFile.IndexHeader)^.KeyRecLen) * AEntryNo); +end; + +function TNdxPage.GetLowerPageNo: Integer; + // *) assumes LowerPage <> nil +begin +// if LowerPage = nil then +// Result := 0 +// else + Result := SwapIntLE(PNdxEntry(Entry)^.LowerPageNo) +end; + +function TNdxPage.GetRecNo: Integer; +begin + Result := SwapIntLE(PNdxEntry(Entry)^.RecNo); +end; + +function TNdxPage.GetKeyData: PChar; +begin + Result := @PNdxEntry(Entry)^.KeyData; +end; + +function TNdxPage.GetKeyDataFromEntry(AEntry: Integer): PChar; +begin + Result := @PNdxEntry(GetEntry(AEntry))^.KeyData; +end; + +function TNdxPage.GetNumEntries: Integer; +begin + Result := SwapIntLE(PNdxPage(PageBuffer)^.NumEntries); +end; + +procedure TNdxPage.IncNumEntries; +begin + IncIntLE(PNdxPage(PageBuffer)^.NumEntries, 1); +end; + +procedure TNdxPage.SetNumEntries(NewNum: Integer); +begin + PNdxPage(PageBuffer)^.NumEntries := SwapIntLE(NewNum); +end; + +procedure TNdxPage.SetRecLowerPageNo(NewRecNo, NewPageNo: Integer); +begin + PNdxEntry(Entry)^.RecNo := SwapIntLE(NewRecNo); + PNdxEntry(Entry)^.LowerPageNo := SwapIntLE(NewPageNo); +end; + +procedure TNdxPage.SetRecLowerPageNoOfEntry(AEntry, NewRecNo, NewPageNo: Integer); +begin + PNdxEntry(GetEntry(AEntry))^.RecNo := SwapIntLE(NewRecNo); + PNdxEntry(GetEntry(AEntry))^.LowerPageNo := SwapIntLE(NewPageNo); +end; + +//============================================================================== +//============ MDX version 4 header access routines +//============================================================================== + +function TMdx4Tag.GetHeaderPageNo: Integer; +begin + Result := SwapIntLE(PMdx4Tag(Tag)^.HeaderPageNo); +end; + +function TMdx4Tag.GetTagName: string; +begin + Result := PMdx4Tag(Tag)^.TagName; +end; + +function TMdx4Tag.GetKeyFormat: Byte; +begin + Result := PMdx4Tag(Tag)^.KeyFormat; +end; + +function TMdx4Tag.GetForwardTag1: Byte; +begin + Result := PMdx4Tag(Tag)^.ForwardTag1; +end; + +function TMdx4Tag.GetForwardTag2: Byte; +begin + Result := PMdx4Tag(Tag)^.ForwardTag2; +end; + +function TMdx4Tag.GetBackwardTag: Byte; +begin + Result := PMdx4Tag(Tag)^.BackwardTag; +end; + +function TMdx4Tag.GetReserved: Byte; +begin + Result := PMdx4Tag(Tag)^.Reserved; +end; + +function TMdx4Tag.GetKeyType: Char; +begin + Result := PMdx4Tag(Tag)^.KeyType; +end; + +procedure TMdx4Tag.SetHeaderPageNo(NewPageNo: Integer); +begin + PMdx4Tag(Tag)^.HeaderPageNo := SwapIntLE(NewPageNo); +end; + +procedure TMdx4Tag.SetTagName(NewName: string); +begin + StrPLCopy(PMdx4Tag(Tag)^.TagName, NewName, 10); + PMdx4Tag(Tag)^.TagName[10] := #0; +end; + +procedure TMdx4Tag.SetKeyFormat(NewFormat: Byte); +begin + PMdx4Tag(Tag)^.KeyFormat := NewFormat; +end; + +procedure TMdx4Tag.SetForwardTag1(NewTag: Byte); +begin + PMdx4Tag(Tag)^.ForwardTag1 := NewTag; +end; + +procedure TMdx4Tag.SetForwardTag2(NewTag: Byte); +begin + PMdx4Tag(Tag)^.ForwardTag2 := NewTag; +end; + +procedure TMdx4Tag.SetBackwardTag(NewTag: Byte); +begin + PMdx4Tag(Tag)^.BackwardTag := NewTag; +end; + +procedure TMdx4Tag.SetReserved(NewReserved: Byte); +begin + PMdx4Tag(Tag)^.Reserved := NewReserved; +end; + +procedure TMdx4Tag.SetKeyType(NewType: Char); +begin + PMdx4Tag(Tag)^.KeyType := NewType; +end; + +//============================================================================== +//============ MDX version 7 headertag access routines +//============================================================================== + +function TMdx7Tag.GetHeaderPageNo: Integer; +begin + Result := SwapIntLE(PMdx7Tag(Tag)^.HeaderPageNo); +end; + +function TMdx7Tag.GetTagName: string; +begin + Result := PMdx7Tag(Tag)^.TagName; +end; + +function TMdx7Tag.GetKeyFormat: Byte; +begin + Result := PMdx7Tag(Tag)^.KeyFormat; +end; + +function TMdx7Tag.GetForwardTag1: Byte; +begin + Result := PMdx7Tag(Tag)^.ForwardTag1; +end; + +function TMdx7Tag.GetForwardTag2: Byte; +begin + Result := PMdx7Tag(Tag)^.ForwardTag2; +end; + +function TMdx7Tag.GetBackwardTag: Byte; +begin + Result := PMdx7Tag(Tag)^.BackwardTag; +end; + +function TMdx7Tag.GetReserved: Byte; +begin + Result := PMdx7Tag(Tag)^.Reserved; +end; + +function TMdx7Tag.GetKeyType: Char; +begin + Result := PMdx7Tag(Tag)^.KeyType; +end; + +procedure TMdx7Tag.SetHeaderPageNo(NewPageNo: Integer); +begin + PMdx7Tag(Tag)^.HeaderPageNo := SwapIntLE(NewPageNo); +end; + +procedure TMdx7Tag.SetTagName(NewName: string); +begin + StrPLCopy(PMdx7Tag(Tag)^.TagName, NewName, 32); + PMdx7Tag(Tag)^.TagName[32] := #0; +end; + +procedure TMdx7Tag.SetKeyFormat(NewFormat: Byte); +begin + PMdx7Tag(Tag)^.KeyFormat := NewFormat; +end; + +procedure TMdx7Tag.SetForwardTag1(NewTag: Byte); +begin + PMdx7Tag(Tag)^.ForwardTag1 := NewTag; +end; + +procedure TMdx7Tag.SetForwardTag2(NewTag: Byte); +begin + PMdx7Tag(Tag)^.ForwardTag2 := NewTag; +end; + +procedure TMdx7Tag.SetBackwardTag(NewTag: Byte); +begin + PMdx7Tag(Tag)^.BackwardTag := NewTag; +end; + +procedure TMdx7Tag.SetReserved(NewReserved: Byte); +begin + PMdx7Tag(Tag)^.Reserved := NewReserved; +end; + +procedure TMdx7Tag.SetKeyType(NewType: Char); +begin + PMdx7Tag(Tag)^.KeyType := NewType; +end; + +{ TDbfIndexParser } + +procedure TDbfIndexParser.ValidateExpression(AExpression: string); +const + AnsiStrFuncs: array[0..13] of TExprFunc = (FuncUppercase, FuncLowercase, FuncStrI_EQ, + FuncStrIP_EQ, FuncStrI_NEQ, FuncStrI_LT, FuncStrI_GT, FuncStrI_LTE, FuncStrI_GTE, + FuncStrP_EQ, FuncStr_LT, FuncStr_GT, FuncStr_LTE, FuncStr_GTE); + AnsiFuncsToMode: array[boolean] of TStringFieldMode = (smRaw, smAnsi); +var + TempRec: PExpressionRec; + TempBuffer: TRecordBuffer; + I: integer; + hasAnsiFuncs: boolean; +begin + TempRec := CurrentRec; + hasAnsiFuncs := false; + while not hasAnsiFuncs and (TempRec <> nil) do + begin + for I := Low(AnsiStrFuncs) to High(AnsiStrFuncs) do + if @TempRec^.Oper = @AnsiStrFuncs[I] then + begin + hasAnsiFuncs := true; + break; + end; + TempRec := TempRec^.Next; + end; + + StringFieldMode := AnsiFuncsToMode[hasAnsiFuncs]; + + FResultLen := inherited ResultLen; + + if FResultLen = -1 then + begin + // make empty record + GetMem(TempBuffer, TDbfFile(DbfFile).RecordSize); + try + TDbfFile(DbfFile).InitRecord(TempBuffer); + FResultLen := StrLen(ExtractFromBuffer(TempBuffer)); + finally + FreeMem(TempBuffer); + end; + end; + + // check if expression not too long + if FResultLen > 100 then + raise EDbfError.CreateFmt(STRING_INDEX_EXPRESSION_TOO_LONG, [AExpression, FResultLen]); +end; + +//============================================================================== +//============ TIndexFile +//============================================================================== +constructor TIndexFile.Create(ADbfFile: Pointer); +var + I: Integer; +begin + inherited Create; + + // clear variables + FOpened := false; + FRangeActive := false; + FUpdateMode := umCurrent; + FModifyMode := mmNormal; + FTempMode := TDbfFile(ADbfFile).TempMode; + FRangeIndex := -1; + SelectIndexVars(-1); + for I := 0 to MaxIndexes - 1 do + begin + FParsers[I] := nil; + FRoots[I] := nil; + FLeaves[I] := nil; + FIndexHeaderModified[I] := false; + end; + + // store pointer to `parent' dbf file + FDbfFile := ADbfFile; +end; + +destructor TIndexFile.Destroy; +begin + // close file + Close; + + // call ancestor + inherited Destroy; +end; + +procedure TIndexFile.Open; +var + I: Integer; + ext: string; + localeError: TLocaleError; + localeSolution: TLocaleSolution; + DbfLangId: Byte; +begin + if not FOpened then + begin + // open physical file + OpenFile; + + // page offsets are not related to header length + PageOffsetByHeader := false; + // we need physical page locks + VirtualLocks := false; + + // not selected index expression => can't edit yet + FCanEdit := false; + FUserKey := nil; + FUserRecNo := -1; + FHeaderLocked := -1; + FHeaderPageNo := 0; + FForceClose := false; + FForceReadOnly := false; + FMdxTag := nil; + + // get index type + ext := UpperCase(ExtractFileExt(FileName)); + if (ext = '.MDX') then + begin + FEntryHeaderSize := 4; + FPageHeaderSize := 8; + FEntryBof := @Entry_Mdx_BOF; + FEntryEof := @Entry_Mdx_EOF; + HeaderSize := 2048; + RecordSize := 1024; + PageSize := 512; + if FileCreated then + begin + FIndexVersion := TDbfFile(FDbfFile).DbfVersion; + if FIndexVersion = xBaseIII then + FIndexVersion := xBaseIV; + end else begin + case PMdxHdr(Header)^.MdxVersion of + 3: FIndexVersion := xBaseVII; + else + FIndexVersion := xBaseIV; + end; + end; + case FIndexVersion of + xBaseVII: + begin + FMdxTag := TMdx7Tag.Create; + FTempMdxTag := TMdx7Tag.Create; + end; + else + FMdxTag := TMdx4Tag.Create; + FTempMdxTag := TMdx4Tag.Create; + end; + // get mem for all index headers..we're going to cache these + for I := 0 to MaxIndexes - 1 do + begin + GetMem(FIndexHeaders[I], RecordSize); + FillChar(FIndexHeaders[I]^, RecordSize, 0); + end; + // set pointers to first index + FIndexHeader := FIndexHeaders[0]; + end else begin + // don't waste memory on another header block: we can just use + // the pagedfile one, there is only one index in this file + FIndexVersion := xBaseIII; + FEntryHeaderSize := 8; + FPageHeaderSize := 4; + FEntryBof := @Entry_Ndx_BOF; + FEntryEof := @Entry_Ndx_EOF; + HeaderSize := 512; + RecordSize := 512; + // have to read header first before we can assign following vars + FIndexHeaders[0] := Header; + FIndexHeader := Header; + // create default root + FParsers[0] := TDbfIndexParser.Create(FDbfFile); + FRoots[0] := TNdxPage.Create(Self); + FCurrentParser := FParsers[0]; + FRoot := FRoots[0]; + FSelectedIndex := 0; + // parse index expression + FCurrentParser.ParseExpression(PIndexHdr(FIndexHeader)^.KeyDesc); + // set index locale + FCollation := BINARY_COLLATION; + end; + + // determine how to open file + if FileCreated then + begin + FillChar(Header^, HeaderSize, 0); + Clear; + end else begin + // determine locale type + localeError := leNone; + if (FIndexVersion >= xBaseIV) then + begin + // get parent language id + DbfLangId := GetDbfLanguageId; + // no ID? + if (DbfLangId = 0) { and (TDbfFile(FDbfFile).DbfVersion = xBaseIII)} then + begin + // if dbf is version 3, no language id, if no MDX language, use binary + if PMdxHdr(Header)^.Language = 0 then + FCollation := BINARY_COLLATION + else + FCollation := GetCollationTable(PMdxHdr(Header)^.Language); + end else begin + // check if MDX - DBF language id's match + if (PMdxHdr(Header)^.Language = 0) or (PMdxHdr(Header)^.Language = DbfLangId) then + FCollation := GetCollationTable(DbfLangId) + else + localeError := leTableIndexMismatch; + end; + // don't overwrite previous error + if (FCollation = UNKNOWN_COLLATION) and (localeError = leNone) then + localeError := leUnknown; + end else begin + // dbase III always binary? + FCollation := BINARY_COLLATION; + end; + // check if selected locale is available, binary is always available... + if (localeError <> leNone) and (FCollation <> BINARY_COLLATION) then + begin + if LCIDList.IndexOf(Pointer(FCollation)) < 0 then + localeError := leNotAvailable; + end; + // check if locale error detected + if localeError <> leNone then + begin + // provide solution, well, solution... + localeSolution := lsNotOpen; + // call error handler + if Assigned(FOnLocaleError) then + FOnLocaleError(localeError, localeSolution); + // act to solution + case localeSolution of + lsNotOpen: FForceClose := true; + lsNoEdit: FForceReadOnly := true; + else + { lsBinary } + FCollation := BINARY_COLLATION; + end; + end; + // now read info + if not ForceClose then + ReadIndexes; + end; + // default to update all + UpdateMode := umAll; + // flag open + FOpened := true; + end; +end; + +procedure TIndexFile.Close; +var + I: Integer; +begin + if FOpened then + begin + // save headers + Flush; + + // remove parser reference + FCurrentParser := nil; + + // free roots + if FIndexVersion >= xBaseIV then + begin + for I := 0 to MaxIndexes - 1 do + begin + FreeMemAndNil(FIndexHeaders[I]); + FreeAndNil(FParsers[I]); + FreeAndNil(FRoots[I]); + end; + end else begin + FreeAndNil(FRoot); + end; + + // free mem + FMdxTag.Free; + FTempMdxTag.Free; + + // close physical file + CloseFile; + + // not opened any more + FOpened := false; + end; +end; + +procedure TIndexFile.ClearRoots; + // + // *) assumes FIndexVersion >= xBaseIV + // +var + I, prevIndex: Integer; +begin + prevIndex := FSelectedIndex; + for I := 0 to MaxIndexes - 1 do + begin + SelectIndexVars(I); + if FRoot <> nil then + begin + // clear this entry + ClearIndex; + FLeaves[I] := FRoots[I]; + end; + end; + // reselect previously selected index + SelectIndexVars(prevIndex); + // deselect index +end; + +procedure WriteDBFileName(Header: PMdxHdr; HdrFileName: string); +var + HdrFileExt: string; + lPos, lenFileName: integer; +begin + HdrFileName := ExtractFileName(HdrFileName); + HdrFileExt := ExtractFileExt(HdrFileName); + if Length(HdrFileExt) > 0 then + begin + lPos := System.Pos(HdrFileExt, HdrFileName); + if lPos > 0 then + SetLength(HdrFileName, lPos - 1); + end; + if Length(HdrFileName) > 15 then + SetLength(HdrFileName, 15); + lenFileName := Length(HdrFileName); + Move(PChar(HdrFileName)^, PMdxHdr(Header)^.FileName[0], lenFileName); + FillChar(PMdxHdr(Header)^.FileName[lenFileName], 15-lenFileName, 0); +end; + +procedure TIndexFile.Clear; +var + year, month, day: Word; + pos, prevSelIndex, pageno: Integer; + DbfLangId: Byte; +begin + // flush cache to prevent reading corrupted data + Flush; + // completely erase index + if FIndexVersion >= xBaseIV then + begin + DecodeDate(Now, year, month, day); + if FIndexVersion = xBaseVII then + PMdxHdr(Header)^.MdxVersion := 3 + else + PMdxHdr(Header)^.MdxVersion := 2; + PMdxHdr(Header)^.Year := year - 1900; + PMdxHdr(Header)^.Month := month; + PMdxHdr(Header)^.Day := day; + WriteDBFileName(PMdxHdr(Header), FileName); + PMdxHdr(Header)^.BlockSize := SwapWordLE(2); + PMdxHdr(Header)^.BlockAdder := SwapWordLE(1024); + PMdxHdr(Header)^.ProdFlag := 1; + PMdxHdr(Header)^.NumTags := 48; + PMdxHdr(Header)^.TagSize := 32; + PMdxHdr(Header)^.Dummy2 := 0; + PMdxHdr(Header)^.Language := GetDbfLanguageID; + PMdxHdr(Header)^.NumPages := SwapIntLE(HeaderSize div PageSize); // = 4 + TouchHeader(Header); + PMdxHdr(Header)^.TagFlag := 1; + // use locale id of parent + DbfLangId := GetDbfLanguageId; + if DbfLangId = 0 then + FCollation := BINARY_COLLATION + else + FCollation := GetCollationTable(DbfLangId); + // write index headers + prevSelIndex := FSelectedIndex; + for pos := 0 to SwapWordLE(PMdxHdr(Header)^.TagsUsed) - 1 do + begin + SelectIndexVars(pos); + pageno := GetNewPageNo; + FMdxTag.HeaderPageNo := SwapIntLE(pageno); + WriteRecord(pageno, FIndexHeader); + end; + // reselect previously selected index + SelectIndexVars(prevSelIndex); + // file header done (tags are included in file header) + WriteFileHeader; + // clear roots + ClearRoots; + // init vars + FTagSize := 32; + FTagOffset := 544; + // clear entries + RecordCount := SwapIntLE(PMdxHdr(Header)^.NumPages); + end else begin + // clear single index entry + ClearIndex; + RecordCount := SwapIntLE(PIndexHdr(FIndexHeader)^.NumPages); + end; +end; + +procedure TIndexFile.ClearIndex; +var + prevHeaderLocked: Integer; + needHeaderLock: Boolean; +begin + // flush cache to prevent reading corrupted data + Flush; + // modifying header: lock page + needHeaderLock := FHeaderLocked <> 0; + prevHeaderLocked := FHeaderLocked; + if needHeaderLock then + begin + LockPage(0, true); + FHeaderLocked := 0; + end; + // initially, we have 1 page: header + PIndexHdr(FIndexHeader)^.NumPages := SwapIntLE(HeaderSize div PageSize); + // clear memory of root + FRoot.Clear; + // get new page for root + FRoot.GetNewPage; + // store new root page + PIndexHdr(FIndexHeader)^.RootPage := SwapIntLE(FRoot.PageNo); +{$ifdef TDBF_UPDATE_FIRSTLAST_NODE} + PIndexHdr(FIndexHeader)^.FirstNode := SwapIntLE(FRoot.PageNo); +{$endif} + // update leaf pointers + FLeaves[FSelectedIndex] := FRoot; + FLeaf := FRoot; + // write new header + WriteHeader; + FRoot.Modified; + FRoot.WritePage; + // done updating: unlock header + if needHeaderLock then + begin + UnlockPage(0); + FHeaderLocked := prevHeaderLocked; + end; +end; + +procedure TIndexFile.CalcKeyProperties; + // given KeyLen, this func calcs KeyRecLen and NumEntries +begin + // now adjust keylen to align on DWORD boundaries + PIndexHdr(FIndexHeader)^.KeyRecLen := SwapWordLE((SwapWordLE( + PIndexHdr(FIndexHeader)^.KeyLen) + FEntryHeaderSize + 3) and not 3); + PIndexHdr(FIndexHeader)^.NumKeys := SwapWordLE((RecordSize - FPageHeaderSize) div + SwapWordLE(PIndexHdr(FIndexHeader)^.KeyRecLen)); +end; + +function TIndexFile.GetName: string; +begin + // get suitable name of index: if tag name defined use that otherwise filename + if FIndexVersion >= xBaseIV then + Result := FIndexName + else + Result := FileName; +end; + +procedure TIndexFile.CreateIndex(FieldDesc, TagName: string; Options: TIndexOptions); +var + tagNo: Integer; + fieldType: Char; + TempParser: TDbfIndexParser; +begin + // check if we have exclusive access to table + TDbfFile(FDbfFile).CheckExclusiveAccess; + // parse index expression; if it cannot be parsed, why bother making index? + TempParser := TDbfIndexParser.Create(FDbfFile); + try + TempParser.ParseExpression(FieldDesc); + // check if result type is correct + fieldType := 'C'; + case TempParser.ResultType of + etString: ; { default set above to suppress delphi warning } + etInteger, etLargeInt, etFloat: fieldType := 'N'; + else + raise EDbfError.Create(STRING_INVALID_INDEX_TYPE); + end; + finally + TempParser.Free; + end; + // select empty index + if FIndexVersion >= xBaseIV then + begin + // get next entry no + tagNo := SwapWordLE(PMdxHdr(Header)^.TagsUsed); + // check if too many indexes + if tagNo = MaxIndexes then + raise EDbfError.Create(STRING_TOO_MANY_INDEXES); + // get memory for root + if FRoots[tagNo] = nil then + begin + FParsers[tagNo] := TDbfIndexParser.Create(FDbfFile); + FRoots[tagNo] := TMdxPage.Create(Self) + end else begin + FreeAndNil(FRoots[tagNo].FLowerPage); + end; + // set leaves pointer + FLeaves[tagNo] := FRoots[tagNo]; + // get pointer to index header + FIndexHeader := FIndexHeaders[tagNo]; + // load root + leaf + FCurrentParser := FParsers[tagNo]; + FRoot := FRoots[tagNo]; + FLeaf := FLeaves[tagNo]; + // create new tag + FTempMdxTag.Tag := CalcTagOffset(tagNo); + FTempMdxTag.TagName := UpperCase(TagName); + // if expression then calculate + FTempMdxTag.KeyFormat := KeyFormat_Data; + if ixExpression in Options then + FTempMdxTag.KeyFormat := KeyFormat_Expression; + // what use have these reference tags? + FTempMdxTag.ForwardTag1 := 0; + FTempMdxTag.ForwardTag2 := 0; + FTempMdxTag.BackwardTag := 0; + FTempMdxTag.Reserved := 2; + FTempMdxTag.KeyType := fieldType; + // save this part of tag, need to save before GetNewPageNo, + // it will reread header + WriteFileHeader; + // store selected index + FSelectedIndex := tagNo; + FIndexName := TagName; + // store new headerno + FHeaderPageNo := GetNewPageNo; + FTempMdxTag.HeaderPageNo := FHeaderPageNo; + // increase number of indexes active + IncWordLE(PMdxHdr(Header)^.TagsUsed, 1); + // update updatemode + UpdateMode := umAll; + // index header updated + WriteFileHeader; + end; + // clear index + ClearIndex; + + // parse expression, we know it's parseable, we've checked that + FCurrentParser.ParseExpression(FieldDesc); + + // looked up index expression: now we can edit +// FIsExpression := ixExpression in Options; + FCanEdit := not FForceReadOnly; + + // init key variables + PIndexHdr(FIndexHeader)^.KeyFormat := 0; + // descending + if ixDescending in Options then + PIndexHdr(FIndexHeader)^.KeyFormat := PIndexHdr(FIndexHeader)^.KeyFormat or KeyFormat_Descending; + // key type + if fieldType = 'C' then + PIndexHdr(FIndexHeader)^.KeyFormat := PIndexHdr(FIndexHeader)^.KeyFormat or KeyFormat_String; + PIndexHdr(FIndexHeader)^.KeyType := fieldType; + // uniqueness + PIndexHdr(FIndexHeader)^.Unique := Unique_None; + if ixPrimary in Options then + begin + PIndexHdr(FIndexHeader)^.KeyFormat := PIndexHdr(FIndexHeader)^.KeyFormat or KeyFormat_Distinct or KeyFormat_Unique; + PIndexHdr(FIndexHeader)^.Unique := Unique_Distinct; + end else if ixUnique in Options then + begin + PIndexHdr(FIndexHeader)^.KeyFormat := PIndexHdr(FIndexHeader)^.KeyFormat or KeyFormat_Unique; + PIndexHdr(FIndexHeader)^.Unique := Unique_Unique; + end; + // keylen is exact length of field + if fieldType = 'C' then + PIndexHdr(FIndexHeader)^.KeyLen := SwapWordLE(FCurrentParser.ResultLen) + else if FIndexVersion >= xBaseIV then + PIndexHdr(FIndexHeader)^.KeyLen := SwapWordLE(12) + else + PIndexHdr(FIndexHeader)^.KeyLen := SwapWordLE(8); + CalcKeyProperties; + // key desc + StrPLCopy(PIndexHdr(FIndexHeader)^.KeyDesc, FieldDesc, 219); + PIndexHdr(FIndexHeader)^.KeyDesc[219] := #0; + + // init various + if FIndexVersion >= xBaseIV then + PIndexHdr(FIndexHeader)^.Dummy := 0 // MDX -> language driver + else + PIndexHdr(FIndexHeader)^.Dummy := SwapWordLE($5800); // NDX -> same ??? + case fieldType of + 'C': + PIndexHdr(FIndexHeader)^.sKeyType := 0; + 'D': + PIndexHdr(FIndexHeader)^.sKeyType := SwapWordLE(1); + 'N', 'F': + if FIndexVersion >= xBaseIV then + PIndexHdr(FIndexHeader)^.sKeyType := 0 + else + PIndexHdr(FIndexHeader)^.sKeyType := SwapWordLE(1); + else + PIndexHdr(FIndexHeader)^.sKeyType := 0; + end; + + PIndexHdr(FIndexHeader)^.Version := SwapWordLE(2); // this is what DB4 writes into file + PIndexHdr(FIndexHeader)^.Dummy2 := 0; + PIndexHdr(FIndexHeader)^.Dummy3 := 0; + PIndexHdr(FIndexHeader)^.ForExist := 0; // false + PIndexHdr(FIndexHeader)^.KeyExist := 1; // true +{$ifndef TDBF_UPDATE_FIRSTLAST_NODE} + // if not defined, init to zero + PIndexHdr(FIndexHeader)^.FirstNode := 0; + PIndexHdr(FIndexHeader)^.LastNode := 0; +{$endif} + WriteHeader; + + // update internal properties + UpdateIndexProperties; + + // for searches / inserts / deletes + FKeyBuffer[SwapWordLE(PIndexHdr(FIndexHeader)^.KeyLen)] := #0; +end; + +procedure TIndexFile.ReadIndexes; +var + I: Integer; + + procedure CheckHeaderIntegrity; + begin + if integer(SwapWordLE(PIndexHdr(FIndexHeader)^.NumKeys) * + SwapWordLE(PIndexHdr(FIndexHeader)^.KeyRecLen)) > RecordSize then + begin + // adjust index header so that integrity is correct + // WARNING: we can't be sure this gives a correct result, but at + // least we won't AV (as easily). user will probably have to regenerate this index + if SwapWordLE(PIndexHdr(FIndexHeader)^.KeyLen) > 100 then + PIndexHdr(FIndexHeader)^.KeyLen := SwapWordLE(100); + CalcKeyProperties; + end; + end; + +begin + // force header reread + inherited ReadHeader; + // examine all indexes + if FIndexVersion >= xBaseIV then + begin + // clear all roots + ClearRoots; + // tags are extended at beginning? tagsize is byte sized + FTagSize := PMdxHdr(Header)^.TagSize; + FTagOffset := 544 + FTagSize - 32; + for I := 0 to SwapWordLE(PMdxHdr(Header)^.TagsUsed) - 1 do + begin + // read page header + FTempMdxTag.Tag := CalcTagOffset(I); + ReadRecord(FTempMdxTag.HeaderPageNo, FIndexHeaders[I]); + // select it + FIndexHeader := FIndexHeaders[I]; + // create root if needed + if FRoots[I] = nil then + begin + FParsers[I] := TDbfIndexParser.Create(FDbfFile); + FRoots[I] := TMdxPage.Create(Self); + end; + // check header integrity + CheckHeaderIntegrity; + // read tree + FRoots[I].PageNo := SwapIntLE(PIndexHdr(FIndexHeader)^.RootPage); + // go to first record + FRoots[I].RecurFirst; + // store leaf + FLeaves[I] := FRoots[I]; + while FLeaves[I].LowerPage <> nil do + FLeaves[I] := FLeaves[I].LowerPage; + // parse expression + FParsers[I].ParseExpression(PIndexHdr(FIndexHeader)^.KeyDesc); + end; + end else begin + // clear root + FRoot.Clear; + // check recordsize constraint + CheckHeaderIntegrity; + // just one index: read tree + FRoot.PageNo := SwapIntLE(PIndexHdr(FIndexHeader)^.RootPage); + // go to first valid record + FRoot.RecurFirst; + // get leaf page + FLeaf := FRoot; + while FLeaf.LowerPage <> nil do + FLeaf := FLeaf.LowerPage; + // write leaf pointer to first index + FLeaves[0] := FLeaf; + // get index properties -> internal props + UpdateIndexProperties; + end; +end; + +procedure TIndexFile.DeleteIndex(const AIndexName: string); +var + I, found, numTags, moveItems: Integer; + tempHeader: Pointer; + tempRoot, tempLeaf: TIndexPage; + tempParser: TDbfIndexParser; +begin + // check if we have exclusive access to table + TDbfFile(FDbfFile).CheckExclusiveAccess; + if FIndexVersion = xBaseIII then + begin + Close; + DeleteFile; + end else if FIndexVersion >= xBaseIV then + begin + // find index + found := IndexOf(AIndexName); + if found >= 0 then + begin + // just remove this tag by copying memory over it + numTags := SwapWordLE(PMdxHdr(Header)^.TagsUsed); + moveItems := numTags - found - 1; + // anything to move? + if moveItems > 0 then + begin + // move entries after found one + Move((Header + FTagOffset + (found+1) * FTagSize)^, + (Header + FTagOffset + found * FTagSize)^, moveItems * FTagSize); + // nullify last entry + FillChar((Header + FTagOffset + numTags * FTagSize)^, FTagSize, 0); + // index headers, roots, leaves + tempHeader := FIndexHeaders[found]; + tempParser := FParsers[found]; + tempRoot := FRoots[found]; + tempLeaf := FLeaves[found]; + for I := 0 to moveItems - 1 do + begin + FIndexHeaders[found + I] := FIndexHeaders[found + I + 1]; + FParsers[found + I] := FParsers[found + I + 1]; + FRoots[found + I] := FRoots[found + I + 1]; + FLeaves[found + I] := FLeaves[found + I + 1]; + FIndexHeaderModified[found + I] := true; + end; + FIndexHeaders[found + moveItems] := tempHeader; + FParsers[found + moveItems] := tempParser; + FRoots[found + moveItems] := tempRoot; + FLeaves[found + moveItems] := tempLeaf; + FIndexHeaderModified[found + moveItems] := false; // non-existant header + end; + // one entry less left + IncWordLE(PMdxHdr(Header)^.TagsUsed, -1); + // ---*** numTags not valid from here ***--- + // file header changed + WriteFileHeader; + // repage index to free space used by deleted index +// RepageFile; + end; + end; +end; + +procedure TIndexFile.TouchHeader(AHeader: Pointer); +var + year, month, day: Word; +begin + DecodeDate(Now, year, month, day); + PMdxHdr(AHeader)^.UpdYear := year - 1900; + PMdxHdr(AHeader)^.UpdMonth := month; + PMdxHdr(AHeader)^.UpdDay := day; +end; + +function TIndexFile.CreateTempFile(BaseName: string): TPagedFile; +var + lModifier: Integer; +begin + // create temporary in-memory index file + lModifier := 0; + FindNextName(BaseName, BaseName, lModifier); + Result := TPagedFile.Create; + Result.FileName := BaseName; + Result.Mode := pfExclusiveCreate; + Result.AutoCreate := true; + Result.OpenFile; + Result.HeaderSize := HeaderSize; + Result.RecordSize := RecordSize; + Result.PageSize := PageSize; + Result.PageOffsetByHeader := false; +end; + +procedure TIndexFile.RepageFile; +var + TempFile: TPagedFile; + TempIdxHeader: PIndexHdr; + I, newPageNo: Integer; + prevIndex: Integer; + + function AllocNewPageNo: Integer; + begin + Result := newPageNo; + Inc(newPageNo, PagesPerRecord); + if FIndexVersion >= xBaseIV then + IncIntLE(PMdxHdr(TempFile.Header)^.NumPages, PagesPerRecord); + IncIntLE(TempIdxHeader^.NumPages, PagesPerRecord); + end; + + function WriteTree(NewPage: TIndexPage): Integer; + var + J: Integer; + begin + // get us a page so that page no's are more logically ordered + Result := AllocNewPageNo; + // use postorder visiting, first do all children + if NewPage.LowerPage <> nil then + begin + for J := 0 to NewPage.HighIndex do + begin + NewPage.EntryNo := J; + WriteTree(NewPage.LowerPage); + end; + end; + // now create new page for ourselves and write + // update page pointer in parent + if NewPage.UpperPage <> nil then + begin + if FIndexVersion >= xBaseIV then + begin + PMdxEntry(NewPage.UpperPage.Entry)^.RecBlockNo := SwapIntLE(Result); +{$ifdef TDBF_UPDATE_FIRSTLAST_NODE} + // write previous node + if FRoot = NewPage then + PMdxPage(NewPage.PageBuffer)^.PrevBlock := 0 + else + PMdxPage(NewPage.PageBuffer)^.PrevBlock := SwapIntLE(Result - PagesPerRecord); +{$endif} + end else begin + PNdxEntry(NewPage.UpperPage.Entry)^.LowerPageNo := SwapIntLE(Result); + end; + end; + // store page + TempFile.WriteRecord(Result, NewPage.PageBuffer); + end; + + procedure CopySelectedIndex; + var + hdrPageNo: Integer; + begin + // copy current index settings + Move(FIndexHeader^, TempIdxHeader^, RecordSize); + // clear number of pages + TempIdxHeader^.NumPages := PagesPerRecord; + // allocate a page no for header + hdrPageNo := AllocNewPageNo; + // use recursive function to write all pages + TempIdxHeader^.RootPage := SwapIntLE(WriteTree(FRoot)); +{$ifdef TDBF_UPDATE_FIRSTLAST_NODE} + TempIdxHeader^.FirstNode := TempIdxHeader^.RootPage; +{$endif} + // write index header now we know the root page + TempFile.WriteRecord(hdrPageNo, TempIdxHeader); + if FIndexVersion >= xBaseIV then + begin + // calculate tag offset in tempfile header + FTempMdxTag.Tag := PChar(TempFile.Header) + (PChar(CalcTagOffset(I)) - Header); + FTempMdxTag.HeaderPageNo := hdrPageNo; + end; + end; + +begin + CheckExclusiveAccess; + + prevIndex := FSelectedIndex; + newPageNo := HeaderSize div PageSize; + TempFile := CreateTempFile(FileName); + if FIndexVersion >= xBaseIV then + begin + // copy header + Move(Header^, TempFile.Header^, HeaderSize); + TouchHeader(TempFile.Header); + // reset header + PMdxHdr(TempFile.Header)^.NumPages := SwapIntLE(HeaderSize div PageSize); + TempFile.WriteHeader; + GetMem(TempIdxHeader, RecordSize); + // now recreate indexes to that file + for I := 0 to SwapWordLE(PMdxHdr(Header)^.TagsUsed - 1) do + begin + // select this index + SelectIndexVars(I); + CopySelectedIndex; + end; + FreeMem(TempIdxHeader); + end else begin + // indexversion = xBaseIII + TempIdxHeader := PIndexHdr(TempFile.Header); + CopySelectedIndex; + end; + TempFile.WriteHeader; + TempFile.CloseFile; + CloseFile; + + // rename temporary file if all went successfull + if not TempFile.WriteError then + begin + SysUtils.DeleteFile(FileName); + SysUtils.RenameFile(TempFile.FileName, FileName); + end; + + TempFile.Free; + DisableForceCreate; + OpenFile; + ReadIndexes; + SelectIndexVars(prevIndex); +end; + +procedure TIndexFile.CompactFile; +var + TempFile: TPagedFile; + TempIdxHeader: PIndexHdr; + I, newPageNo: Integer; + prevIndex: Integer; + + function AllocNewPageNo: Integer; + begin + Result := newPageNo; + Inc(newPageNo, PagesPerRecord); + if FIndexVersion >= xBaseIV then + IncIntLE(PMdxHdr(TempFile.Header)^.NumPages, PagesPerRecord); + IncIntLE(TempIdxHeader^.NumPages, PagesPerRecord); + end; + + function CreateNewPage: TIndexPage; + begin + // create new page + space + if FIndexVersion >= xBaseIV then + Result := TMdxPage.Create(Self) + else + Result := TNdxPage.Create(Self); + Result.FPageNo := AllocNewPageNo; + + // set new page properties + Result.SetNumEntries(0); + end; + + procedure GetNewEntry(APage: TIndexPage); + // makes a new entry available and positions current 'pos' on it + // NOTES: uses TIndexPage *very* carefully + // - may not read from self (tindexfile) + // - page.FLowerPage is assigned -> SyncLowerPage may *not* be called + // - do not set PageNo (= SetPageNo) + // - do not set EntryNo + begin + if APage.HighIndex >= SwapWordLE(PIndexHdr(FIndexHeader)^.NumKeys)-1 then + begin + if APage.UpperPage = nil then + begin + // add new upperlevel to page + APage.FUpperPage := CreateNewPage; + APage.UpperPage.FLowerPage := APage; + APage.UpperPage.FEntryNo := 0; + APage.UpperPage.FEntry := EntryEof; + APage.UpperPage.GotoInsertEntry; + APage.UpperPage.LocalInsert(0, APage.Key, APage.PageNo); + // non-leaf pages need 'rightmost' key; numentries = real# - 1 + APage.UpperPage.SetNumEntries(0); + end; + + // page done, store + TempFile.WriteRecord(APage.FPageNo, APage.PageBuffer); + + // allocate new page + APage.FPageNo := AllocNewPageNo; + // clear + APage.SetNumEntries(0); + APage.FHighIndex := -1; + APage.FLowIndex := 0; + // clear 'right-most' blockno + APage.SetRecLowerPageNoOfEntry(0, 0, 0); + + // get new entry in upper page for current new apage + GetNewEntry(APage.UpperPage); + APage.UpperPage.LocalInsert(0, nil, 0); + // non-leaf pages need 'rightmost' key; numentries = real# - 1 + if APage.UpperPage.EntryNo = 0 then + APage.UpperPage.SetNumEntries(0); + end; + APage.FEntryNo := APage.HighIndex+1; + APage.FEntry := EntryEof; + APage.GotoInsertEntry; + end; + + procedure CopySelectedIndex; + var + APage: TIndexPage; + hdrPageNo: Integer; + begin + // copy current index settings + Move(FIndexHeader^, TempIdxHeader^, RecordSize); + // clear number of pages + TempIdxHeader^.NumPages := SwapIntLE(PagesPerRecord); + // allocate a page no for header + hdrPageNo := AllocNewPageNo; + + // copy all records + APage := CreateNewPage; + FLeaf.RecurFirst; + while not (FRoot.Entry = FEntryEof) do + begin + GetNewEntry(APage); + APage.LocalInsert(FLeaf.PhysicalRecNo, FLeaf.Key, 0); + FLeaf.RecurNext; + end; + + // flush remaining (partially filled) pages + repeat + TempFile.WriteRecord(APage.FPageNo, APage.PageBuffer); + if APage.UpperPage <> nil then + APage := APage.UpperPage + else break; + until false; + + // copy index header + root page + TempIdxHeader^.RootPage := SwapIntLE(APage.PageNo); +{$ifdef TDBF_UPDATE_FIRSTLAST_NODE} + TempIdxHeader^.FirstNode := SwapIntLE(APage.PageNo); +{$endif} + // write index header now we know the root page + TempFile.WriteRecord(hdrPageNo, TempIdxHeader); + if FIndexVersion >= xBaseIV then + begin + // calculate tag offset in tempfile header + FTempMdxTag.Tag := PChar(TempFile.Header) + (PChar(CalcTagOffset(I)) - Header); + FTempMdxTag.HeaderPageNo := hdrPageNo; + end; + end; + +begin + CheckExclusiveAccess; + + prevIndex := FSelectedIndex; + newPageNo := HeaderSize div PageSize; + TempFile := CreateTempFile(FileName); + if FIndexVersion >= xBaseIV then + begin + // copy header + Move(Header^, TempFile.Header^, HeaderSize); + TouchHeader(TempFile.Header); + // reset header + PMdxHdr(TempFile.Header)^.NumPages := SwapIntLE(HeaderSize div PageSize); + TempFile.WriteHeader; + GetMem(TempIdxHeader, RecordSize); + // now recreate indexes to that file + for I := 0 to SwapWordLE(PMdxHdr(Header)^.TagsUsed) - 1 do + begin + // select this index + SelectIndexVars(I); + CopySelectedIndex; + end; + FreeMem(TempIdxHeader); + end else begin + // indexversion = xBaseIII + TempIdxHeader := PIndexHdr(TempFile.Header); + CopySelectedIndex; + end; + TempFile.WriteHeader; + TempFile.CloseFile; + CloseFile; + + // rename temporary file if all went successfull + if not TempFile.WriteError then + begin + SysUtils.DeleteFile(FileName); + SysUtils.RenameFile(TempFile.FileName, FileName); + end; + + TempFile.Free; + DisableForceCreate; + OpenFile; + ReadIndexes; + SelectIndexVars(prevIndex); +end; + +procedure TIndexFile.PrepareRename(NewFileName: string); +begin + if FIndexVersion >= xBaseIV then + begin + WriteDBFileName(PMdxHdr(Header), NewFileName); + WriteFileHeader; + end; +end; + +function TIndexFile.GetNewPageNo: Integer; +var + needLockHeader: Boolean; +begin + // update header -> lock it if not already locked + needLockHeader := FHeaderLocked <> 0; + if needLockHeader then + begin + // lock header page + LockPage(0, true); + // someone else could be inserting records at the same moment + if NeedLocks then + inherited ReadHeader; + end; + if FIndexVersion >= xBaseIV then + begin + Result := SwapIntLE(PMdxHdr(Header)^.NumPages); + IncIntLE(PMdxHdr(Header)^.NumPages, PagesPerRecord); +{$ifdef TDBF_UPDATE_FIRSTLAST_NODE} + // adjust high page + PIndexHdr(FIndexHeader)^.LastNode := SwapIntLE(Result); +{$endif} + WriteFileHeader; + end else begin + Result := SwapIntLE(PIndexHdr(FIndexHeader)^.NumPages); + end; + IncIntLE(PIndexHdr(FIndexHeader)^.NumPages, PagesPerRecord); + WriteHeader; + // done updating header -> unlock if locked + if needLockHeader then + UnlockPage(0); +end; + +function TIndexFile.Insert(RecNo: Integer; Buffer: TRecordBuffer): Boolean; {override;} +var + I, curSel, count: Integer; +begin + // check if updating all or only current + FUserRecNo := RecNo; + if (FUpdateMode = umAll) or (FSelectedIndex = -1) then + begin + // remember currently selected index + curSel := FSelectedIndex; + Result := true; + I := 0; + count := SwapWordLE(PMdxHdr(Header)^.TagsUsed); + while I < count do + begin + SelectIndexVars(I); + Result := InsertKey(Buffer); + if not Result then + begin + while I > 0 do + begin + Dec(I); + DeleteKey(Buffer); + end; + break; + end; + Inc(I); + end; + // restore previous selected index + SelectIndexVars(curSel); + end else begin + Result := InsertKey(Buffer); + end; + + // check range, disabled by insert + ResyncRange(true); +end; + +function TIndexFile.CheckKeyViolation(Buffer: TRecordBuffer): Boolean; +var + I, curSel: Integer; +begin + Result := false; + FUserRecNo := -2; + if FIndexVersion = xBaseIV then + begin + curSel := FSelectedIndex; + for I := 0 to SwapWordLE(PMdxHdr(Header)^.TagsUsed) - 1 do + begin + SelectIndexVars(I); + if FUniqueMode = iuDistinct then + begin + FUserKey := ExtractKeyFromBuffer(Buffer); + Result := FindKey(false) = 0; + if Result then + break; + end; + end; + SelectIndexVars(curSel); + end else begin + if FUniqueMode = iuDistinct then + begin + FUserKey := ExtractKeyFromBuffer(Buffer); + Result := FindKey(false) = 0; + end; + end; +end; + +function TIndexFile.PrepareKey(Buffer: TRecordBuffer; ResultType: TExpressionType): PChar; +var + FloatRec: TFloatRec; + I, IntSrc, NumDecimals: Integer; + ExtValue: Extended; + BCDdigit: Byte; +{$ifdef SUPPORT_INT64} + Int64Src: Int64; +{$endif} + +begin + floatrec.exponent:= 0; + // need to convert numeric? + Result := PChar(Buffer); + if PIndexHdr(FIndexHeader)^.KeyType in ['N', 'F'] then + begin + if FIndexVersion = xBaseIII then + begin + // DB3 -> index always 8 byte float, if original integer, convert to double + case ResultType of + etInteger: + begin + FUserNumeric := PInteger(Result)^; + Result := PChar(@FUserNumeric); + end; +{$ifdef SUPPORT_INT64} + etLargeInt: + begin + FUserNumeric := PLargeInt(Result)^; + Result := PChar(@FUserNumeric); + end; +{$endif} + end; + end else begin + // DB4 MDX + NumDecimals := 0; + case ResultType of + etInteger: + begin + IntSrc := PInteger(Result)^; + // handle zero differently: no decimals + if IntSrc <> 0 then + NumDecimals := GetStrFromInt(IntSrc, @FloatRec.Digits[0]) + else + NumDecimals := 0; + FloatRec.Negative := IntSrc < 0; + end; +{$ifdef SUPPORT_INT64} + etLargeInt: + begin + Int64Src := PLargeInt(Result)^; + if Int64Src <> 0 then + NumDecimals := GetStrFromInt64(Int64Src, @FloatRec.Digits[0]) + else + NumDecimals := 0; + FloatRec.Negative := Int64Src < 0; + end; +{$endif} + etFloat: + begin + ExtValue := PDouble(Result)^; + FloatToDecimal(FloatRec, ExtValue, {$ifndef FPC_VERSION}fvExtended,{$endif} 9999, 15); + if ExtValue <> 0.0 then + NumDecimals := StrLen(@FloatRec.Digits[0]) + else + NumDecimals := 0; + // maximum number of decimals possible to encode in BCD is 16 + if NumDecimals > 16 then + NumDecimals := 16; + end; + end; + + case ResultType of + etInteger {$ifdef SUPPORT_INT64}, etLargeInt{$endif}: + begin + FloatRec.Exponent := NumDecimals; + // MDX-BCD does not count ending zeroes as `data' space length + while (NumDecimals > 0) and (FloatRec.Digits[NumDecimals-1] = '0') do + Dec(NumDecimals); + // null-terminate string + FloatRec.Digits[NumDecimals] := #0; + end; + end; + + // write 'header', contains number of digits before decimal separator + FUserBCD[0] := $34 + FloatRec.Exponent; + // clear rest of BCD + FillChar(FUserBCD[1], SizeOf(FUserBCD)-1, 0); + // store number of bytes used (in number of bits + 1) + FUserBCD[1] := (((NumDecimals+1) div 2) * 8) + 1; + // where to store decimal dot position? now implicitly in first byte + // store negative sign + if FloatRec.Negative then + FUserBCD[1] := FUserBCD[1] or $80; + // convert string to BCD + I := 0; + while I < NumDecimals do + begin + // only one byte left? + if FloatRec.Digits[I+1] = #0 then + BCDdigit := 0 + else + BCDdigit := Byte(FloatRec.Digits[I+1]) - Byte('0'); + // pack two bytes into bcd + FUserBCD[2+(I div 2)] := ((Byte(FloatRec.Digits[I]) - Byte('0')) shl 4) or BCDdigit; + // goto next 2 bytes + Inc(I, 2); + end; + + // set result pointer to BCD + Result := PChar(@FUserBCD[0]); + end; + end; +end; + +function TIndexFile.ExtractKeyFromBuffer(Buffer: TRecordBuffer): PChar; +begin + // execute expression to get key + Result := PrepareKey(TRecordBuffer(FCurrentParser.ExtractFromBuffer(Buffer)), FCurrentParser.ResultType); + if FCurrentParser.StringFieldMode <> smRaw then + TranslateString(GetACP, FCodePage, Result, Result, KeyLen); +end; + +function TIndexFile.InsertKey(Buffer: TRecordBuffer): boolean; +begin + Result := true; + // ignore deleted records + if (FModifyMode = mmNormal) and (FUniqueMode = iuDistinct) and (AnsiChar(Buffer^) = '*') then + exit; + // check proper index and modifiability + if FCanEdit and (PIndexHdr(FIndexHeader)^.KeyLen <> 0) then + begin + // get key from buffer + FUserKey := ExtractKeyFromBuffer(Buffer); + // patch through + Result := InsertCurrent; + end; +end; + +function TIndexFile.InsertCurrent: boolean; + // insert in current index + // assumes: FUserKey is an OEM key +begin + // only insert if not recalling or mode = distinct + // modify = mmDeleteRecall /\ unique <> distinct -> key already present + Result := true; + if (FModifyMode <> mmDeleteRecall) or (FUniqueMode = iuDistinct) then + begin + // temporarily remove range to find correct location of key + ResetRange; + // find this record as closely as possible + // if result = 0 then key already exists + // if unique index, then don't insert key if already present + if (FindKey(true) <> 0) or (FUniqueMode = iuNormal) then + begin + // if we found eof, write to pagebuffer + FLeaf.GotoInsertEntry; + // insert requested entry, we know there is an entry available + FLeaf.LocalInsert(FUserRecNo, FUserKey, 0); + end else begin + // key already exists -> test possible key violation + if FUniqueMode = iuDistinct then + begin + // raising -> reset modify mode + FModifyMode := mmNormal; + ConstructInsertErrorMsg; + Result := false; + end; + end; + end; +end; + +procedure TIndexFile.ConstructInsertErrorMsg; +var + InfoKey: string; +begin + if Length(FLastError) > 0 then exit; + InfoKey := FUserKey; + SetLength(InfoKey, KeyLen); + FLastError := Format(STRING_KEY_VIOLATION, [GetName, + PhysicalRecNo, TrimRight(InfoKey)]); +end; + +procedure TIndexFile.InsertError; +var + errorStr: string; +begin + errorStr := FLastError; + FLastError := ''; + raise EDbfError.Create(errorStr); +end; + +procedure TIndexFile.Delete(RecNo: Integer; Buffer: TRecordBuffer); +var + I, curSel: Integer; +begin + // check if updating all or only current + FUserRecNo := RecNo; + if (FUpdateMode = umAll) or (FSelectedIndex = -1) then + begin + // remember currently selected index + curSel := FSelectedIndex; + for I := 0 to SwapWordLE(PMdxHdr(Header)^.TagsUsed) - 1 do + begin + SelectIndexVars(I); + DeleteKey(Buffer); + end; + // restore previous selected index + SelectIndexVars(curSel); + end else begin + DeleteKey(Buffer); + end; + // range may be changed + ResyncRange(true); +end; + +procedure TIndexFile.DeleteKey(Buffer: TRecordBuffer); +begin + if FCanEdit and (PIndexHdr(FIndexHeader)^.KeyLen <> 0) then + begin + // get key from record buffer + FUserKey := ExtractKeyFromBuffer(Buffer); + // call function + DeleteCurrent; + end; +end; + +procedure TIndexFile.DeleteCurrent; + // deletes from current index +begin + // only delete if not delete record or mode = distinct + // modify = mmDeleteRecall /\ unique = distinct -> key needs to be deleted from index + if (FModifyMode <> mmDeleteRecall) or (FUniqueMode = iuDistinct) then + begin + // prevent "confined" view of index while deleting + ResetRange; + // search correct entry to delete + if FLeaf.PhysicalRecNo <> FUserRecNo then + begin + FindKey(false); + end; + // delete selected entry + FLeaf.Delete; + end; +end; + +function TIndexFile.UpdateIndex(Index: Integer; PrevBuffer, NewBuffer: TRecordBuffer): Boolean; +begin + SelectIndexVars(Index); + Result := UpdateCurrent(PrevBuffer, NewBuffer); +end; + +function TIndexFile.Update(RecNo: Integer; PrevBuffer, NewBuffer: TRecordBuffer): Boolean; +var + I, curSel, count: Integer; +begin + // check if updating all or only current + FUserRecNo := RecNo; + if (FUpdateMode = umAll) or (FSelectedIndex = -1) then + begin + // remember currently selected index + curSel := FSelectedIndex; + Result := true; + I := 0; + count := SwapWordLE(PMdxHdr(Header)^.TagsUsed); + while I < count do + begin + Result := UpdateIndex(I, PrevBuffer, NewBuffer); + if not Result then + begin + // rollback updates to previous indexes + while I > 0 do + begin + Dec(I); + UpdateIndex(I, NewBuffer, PrevBuffer); + end; + break; + end; + Inc(I); + end; + // restore previous selected index + SelectIndexVars(curSel); + end else begin + Result := UpdateCurrent(PrevBuffer, NewBuffer); + end; + // check range, disabled by delete/insert + if (FRoot.LowPage = 0) and (FRoot.HighPage = 0) then + ResyncRange(true); +end; + +function TIndexFile.UpdateCurrent(PrevBuffer, NewBuffer: TRecordBuffer): boolean; +var + InsertKey, DeleteKey: PChar; + TempBuffer: array [0..100] of Char; +begin + Result := true; + if FCanEdit and (PIndexHdr(FIndexHeader)^.KeyLen <> 0) then + begin + DeleteKey := ExtractKeyFromBuffer(PrevBuffer); + Move(DeleteKey^, TempBuffer, SwapWordLE(PIndexHdr(FIndexHeader)^.KeyLen)); + DeleteKey := @TempBuffer[0]; + InsertKey := ExtractKeyFromBuffer(NewBuffer); + + // compare to see if anything changed + if CompareKeys(DeleteKey, InsertKey) <> 0 then + begin + FUserKey := DeleteKey; + DeleteCurrent; + FUserKey := InsertKey; + Result := InsertCurrent; + if not Result then + begin + FUserKey := DeleteKey; + InsertCurrent; + FUserKey := InsertKey; + end; + end; + end; +end; + +procedure TIndexFile.AddNewLevel; +var + lNewPage: TIndexPage; + pKeyData: PChar; +begin + // create new page + space + if FIndexVersion >= xBaseIV then + lNewPage := TMdxPage.Create(Self) + else + lNewPage := TNdxPage.Create(Self); + lNewPage.GetNewPage; + + // lock this new page; will be unlocked by caller + lNewPage.LockPage; + // lock index header; will be unlocked by caller + LockPage(FHeaderPageNo, true); + FHeaderLocked := FHeaderPageNo; + + // modify header + PIndexHdr(FIndexHeader)^.RootPage := SwapIntLE(lNewPage.PageNo); + + // set new page properties + lNewPage.SetNumEntries(0); + lNewPage.EntryNo := 0; + lNewPage.GotoInsertEntry; +{$ifdef TDBF_UPDATE_FIRST_LAST_NODE} + lNewPage.SetPrevBlock(lNewPage.PageNo - PagesPerRecord); +{$endif} + pKeyData := FRoot.GetKeyDataFromEntry(0); + lNewPage.FLowerPage := FRoot; + lNewPage.FHighIndex := 0; + lNewPage.SetEntry(0, pKeyData, FRoot.PageNo); + + // update root pointer + FRoot.UpperPage := lNewPage; + FRoots[FSelectedIndex] := lNewPage; + FRoot := lNewPage; + + // write new header + WriteRecord(FHeaderPageNo, FIndexHeader); +end; + +procedure TIndexFile.UnlockHeader; +begin + if FHeaderLocked <> -1 then + begin + UnlockPage(FHeaderLocked); + FHeaderLocked := -1; + end; +end; + +procedure TIndexFile.ResyncRoot; +begin + if FIndexVersion >= xBaseIV then + begin + // read header page + inherited ReadRecord(FHeaderPageNo, FIndexHeader); + end else + inherited ReadHeader; + // reread tree + FRoot.PageNo := SwapIntLE(PIndexHdr(FIndexHeader)^.RootPage); +end; + +function TIndexFile.SearchKey(Key: PChar; SearchType: TSearchKeyType): Boolean; +var + findres, currRecNo: Integer; +begin + // save current position + currRecNo := SequentialRecNo; + // search, these are always from the root: no need for first + findres := Find(-2, Key); + // test result + case SearchType of + stEqual: + Result := findres = 0; + stGreaterEqual: + Result := findres <= 0; + stGreater: + begin + if findres = 0 then + begin + // find next record that is greater + // NOTE: MatchKey assumes key to search for is already specified + // in FUserKey, it is because we have called Find + repeat + Result := WalkNext; + until not Result or (MatchKey(Key) <> 0); + end else + Result := findres < 0; + end; + else + Result := false; + end; + // search failed -> restore previous position + if not Result then + SequentialRecNo := currRecNo; +end; + +function TIndexFile.Find(RecNo: Integer; Buffer: PChar): Integer; +begin + // execute find + FUserRecNo := RecNo; + FUserKey := Buffer; + Result := FindKey(false); +end; + +function TIndexFile.FindKey(AInsert: boolean): Integer; +// +// if you set Insert = true, you need to re-enable range after insert!! +// +var + TempPage, NextPage: TIndexPage; + numEntries, numKeysAvail, done, searchRecNo: Integer; +begin + // reread index header (to discover whether root page changed) + if NeedLocks then + ResyncRoot; + // if distinct or unique index -> every entry only occurs once -> + // does not matter which recno we search -> search recno = -2 -> + // extra info = recno + if (FUniqueMode = iuNormal) then + begin + // if inserting, search last entry matching key + if AInsert then + searchRecNo := -3 + else + searchRecNo := FUserRecNo + end else begin + searchRecNo := -2; + end; + // start from root + TempPage := FRoot; + repeat + // find key + done := 0; + Result := TempPage.FindNearest(searchRecNo); + if TempPage.LowerPage = nil then + begin + // if key greater than last, try next leaf + if (Result > 0) and (searchRecNo > 0) then + begin + // find first parent in tree so we can advance to next item + NextPage := TempPage; + repeat + NextPage := NextPage.UpperPage; + until (NextPage = nil) or (NextPage.EntryNo < NextPage.HighIndex); + // found page? + if NextPage <> nil then + begin + // go to parent + TempPage := NextPage; + TempPage.EntryNo := TempPage.EntryNo + 1; + // resync rest of tree + TempPage.LowerPage.RecurFirst; + // go to lower page to continue search + TempPage := TempPage.LowerPage; + // check if still more lowerpages + if TempPage.LowerPage <> nil then + begin + // flag we need to traverse down further + done := 2; + end else begin + // this is next child, we don't know if found + done := 1; + end; + end; + end; + end else begin + // need to traverse lower down + done := 2; + end; + + // check if we need to split page + // done = 1 -> not found entry on insert path yet + if AInsert and (done <> 1) then + begin + // now we are on our path to destination where entry is to be inserted + // check if this page is full, then split it + numEntries := TempPage.NumEntries; + // if this is inner node, we can only store one less than max entries + numKeysAvail := SwapWordLE(PIndexHdr(FIndexHeader)^.NumKeys) - numEntries; + if TempPage.LowerPage <> nil then + dec(numKeysAvail); + // too few available -> split + if numKeysAvail = 0 then + TempPage.Split; + end; + + // do we need to go lower down? + if done = 2 then + TempPage := TempPage.LowerPage; + until done = 0; +end; + +function TIndexFile.MatchKey(UserKey: PChar): Integer; +begin + // BOF and EOF always false + if FLeaf.Entry = FEntryBof then + Result := 1 + else + if FLeaf.Entry = FEntryEof then + Result := -1 + else begin + FUserKey := UserKey; + Result := FLeaf.MatchKey; + end; +end; + +procedure TIndexFile.SetRange(LowRange, HighRange: PChar); +begin + Move(LowRange^, FLowBuffer[0], KeyLen); + Move(HighRange^, FHighBuffer[0], KeyLen); + FRangeActive := true; + ResyncRange(true); +end; + +procedure TIndexFile.RecordDeleted(RecNo: Integer; Buffer: TRecordBuffer); +begin + // are we distinct -> then delete record from index + FModifyMode := mmDeleteRecall; + Delete(RecNo, Buffer); + FModifyMode := mmNormal; +end; + +function TIndexFile.RecordRecalled(RecNo: Integer; Buffer: TRecordBuffer): Boolean; +begin + // are we distinct -> then reinsert record in index + FModifyMode := mmDeleteRecall; + Result := Insert(RecNo, Buffer); + FModifyMode := mmNormal; +end; + +procedure TIndexFile.SetPhysicalRecNo(RecNo: Integer); +begin + // check if already at specified recno + if FLeaf.PhysicalRecNo = RecNo then + exit; + + // check record actually exists + if TDbfFile(FDbfFile).IsRecordPresent(RecNo) then + begin + // read buffer of this RecNo + TDbfFile(FDbfFile).ReadRecord(RecNo, TDbfFile(FDbfFile).PrevBuffer); + // extract key + FUserKey := ExtractKeyFromBuffer(TDbfFile(FDbfFile).PrevBuffer); + // find this key + FUserRecNo := RecNo; + FindKey(false); + end; +end; + +procedure TIndexFile.SetUpdateMode(NewMode: TIndexUpdateMode); +begin + // if there is only one index, don't waste time and just set single + if (FIndexVersion = xBaseIII) or (SwapWordLE(PMdxHdr(Header)^.TagsUsed) <= 1) then + FUpdateMode := umCurrent + else + FUpdateMode := NewMode; +end; + +procedure TIndexFile.WalkFirst; +begin + // search first node + FRoot.RecurFirst; + // out of index - BOF + FLeaf.EntryNo := FLeaf.EntryNo - 1; +end; + +procedure TIndexFile.WalkLast; +begin + // search last node + FRoot.RecurLast; + // out of index - EOF + // we need to skip two entries to go out-of-bound + FLeaf.EntryNo := FLeaf.EntryNo + 2; +end; + +procedure TIndexFile.First; +begin + // resync tree + Resync(false); + WalkFirst; +end; + +procedure TIndexFile.Last; +begin + // resync tree + Resync(false); + WalkLast; +end; + +procedure TIndexFile.ResyncRange(KeepPosition: boolean); +var + Result: Boolean; + currRecNo: integer; +begin + if not FRangeActive then + exit; + + // disable current range if any + // init to 0 to suppress delphi warning + currRecNo := 0; + if KeepPosition then + currRecNo := SequentialRecNo; + ResetRange; + // search lower bound + Result := SearchKey(FLowBuffer, stGreaterEqual); + if not Result then + begin + // not found? -> make empty range + WalkLast; + end; + // set lower bound + SetBracketLow; + // search upper bound + Result := SearchKey(FHighBuffer, stGreater); + // if result true, then need to get previous item <=> + // last of equal/lower than key + if Result then + begin + Result := WalkPrev; + if not Result then + begin + // cannot go prev -> empty range + WalkFirst; + end; + end else begin + // not found -> EOF found, go EOF, then to last record + WalkLast; + WalkPrev; + end; + // set upper bound + SetBracketHigh; + if KeepPosition then + SequentialRecNo := currRecNo; +end; + +procedure TIndexFile.Resync(Relative: boolean); +begin + if NeedLocks then + begin + if not Relative then + begin + ResyncRoot; + ResyncRange(false); + end else begin + // resyncing tree implies resyncing range + ResyncTree; + end; + end; +end; + +procedure TIndexFile.ResyncTree; +var + action, recno: integer; +begin + // if at BOF or EOF, then we need to resync by first or last + // remember where the cursor was + // init to 0 to suppress delphi warning + recno := 0; + if FLeaf.Entry = FEntryBof then + begin + action := 0; + end else if FLeaf.Entry = FEntryEof then begin + action := 1; + end else begin + // read current key into buffer + Move(FLeaf.Key^, FKeyBuffer, SwapWordLE(PIndexHdr(FIndexHeader)^.KeyLen)); + recno := FLeaf.PhysicalRecNo; + action := 2; + end; + + // we now know cursor position, resync possible range + ResyncRange(false); + + // go to cursor position + case action of + 0: WalkFirst; + 1: WalkLast; + 2: + begin + // search current in-mem key on disk + if (Find(recno, FKeyBuffer) <> 0) then + begin + // houston, we've got a problem! + // our `current' record has gone. we need to find it + // find it by using physical recno + PhysicalRecNo := recno; + end; + end; + end; +end; + +function TIndexFile.WalkPrev: boolean; +var + curRecNo: Integer; +begin + // save current recno, find different next! + curRecNo := FLeaf.PhysicalRecNo; + repeat + // return false if we are at first entry + Result := FLeaf.RecurPrev; + until not Result or (curRecNo <> FLeaf.PhysicalRecNo); +end; + +function TIndexFile.WalkNext: boolean; +var + curRecNo: Integer; +begin + // save current recno, find different prev! + curRecNo := FLeaf.PhysicalRecNo; + repeat + // return false if we are at last entry + Result := FLeaf.RecurNext; + until not Result or (curRecNo <> FLeaf.PhysicalRecNo); +end; + +function TIndexFile.Prev: Boolean; +begin + // resync in-mem tree with tree on disk + Resync(true); + Result := WalkPrev; +end; + +function TIndexFile.Next: Boolean; +begin + // resync in-mem tree with tree on disk + Resync(true); + Result := WalkNext; +end; + +function TIndexFile.GetKeyLen: Integer; +begin + Result := SwapWordLE(PIndexHdr(FIndexHeader)^.KeyLen); +end; + +function TIndexFile.GetKeyType: Char; +begin + Result := PIndexHdr(FIndexHeader)^.KeyType; +end; + +function TIndexFile.GetPhysicalRecNo: Integer; +begin + Result := FLeaf.PhysicalRecNo; +end; + +function TIndexFile.GetSequentialRecordCount: Integer; +begin + Result := FRoot.Weight * (FRoot.HighIndex + 1); +end; + +function TIndexFile.GetSequentialRecNo: Integer; +var + TempPage: TIndexPage; +begin + // check if at BOF or EOF, special values + if FLeaf.EntryNo < FLeaf.LowIndex then begin + Result := RecBOF; + end else if FLeaf.EntryNo > FLeaf.HighIndex then begin + Result := RecEOF; + end else begin + // first record is record 1 + Result := 1; + TempPage := FRoot; + repeat + inc(Result, TempPage.EntryNo * TempPage.Weight); + TempPage := TempPage.LowerPage; + until TempPage = nil; + end; +end; + +procedure TIndexFile.SetSequentialRecNo(RecNo: Integer); +var + TempPage: TIndexPage; + gotoEntry: Integer; +begin + // use our weighting system to quickly go to a seq recno + // recno starts at 1, entries at zero + Dec(RecNo); + TempPage := FRoot; + repeat + // don't div by zero + assert(TempPage.Weight > 0); + gotoEntry := RecNo div TempPage.Weight; + RecNo := RecNo mod TempPage.Weight; + // do we have this much entries? + if (TempPage.HighIndex < gotoEntry) then + begin + // goto next entry in upper page if not + // if recurnext fails, we have come at the end of the index + if (TempPage.UpperPage <> nil) and TempPage.UpperPage.RecurNext then + begin + // lower recno to get because we skipped an entry + TempPage.EntryNo := TempPage.LowIndex; + RecNo := 0; + end else begin + // this can only happen if too big RecNo was entered, go to last + TempPage.RecurLast; + // terminate immediately + TempPage := FLeaf; + end; + end else begin + TempPage.EntryNo := gotoEntry; + end; + // get lower node + TempPage := TempPage.LowerPage; + until TempPage = nil; +end; + +procedure TIndexFile.SetBracketLow; +var + TempPage: TIndexPage; +begin + // set current record as lower bound + TempPage := FRoot; + repeat + TempPage.LowBracket := TempPage.EntryNo; + TempPage.LowPage := TempPage.PageNo; + TempPage := TempPage.LowerPage; + until TempPage = nil; +end; + +procedure TIndexFile.SetBracketHigh; +var + TempPage: TIndexPage; +begin + // set current record as lower bound + TempPage := FRoot; + repeat + TempPage.HighBracket := TempPage.EntryNo; + TempPage.HighPage := TempPage.PageNo; + TempPage := TempPage.LowerPage; + until TempPage = nil; +end; + +procedure TIndexFile.CancelRange; +begin + FRangeActive := false; + ResetRange; +end; + +procedure TIndexFile.ResetRange; +var + TempPage: TIndexPage; +begin + // disable lower + upper bound + TempPage := FRoot; + repeat + // set a page the index should never reach + TempPage.LowPage := 0; + TempPage.HighPage := 0; + TempPage := TempPage.LowerPage; + until TempPage = nil; +end; + +procedure TIndexFile.DisableRange; +var + TempPage: TIndexPage; +begin + TempPage := FRoot; + repeat + TempPage.SaveBracket; + TempPage := TempPage.LowerPage; + until TempPage = nil; + CancelRange; +end; + +procedure TIndexFile.EnableRange; +var + TempPage: TIndexPage; +begin + TempPage := FRoot; + repeat + TempPage.RestoreBracket; + TempPage := TempPage.LowerPage; + until TempPage = nil; + FRangeActive := true; +end; + +function MemComp(P1, P2: Pointer; const Length: Integer): Integer; +var + I: Integer; +begin + for I := 0 to Length - 1 do + begin + // still equal? + if PByte(P1)^ <> PByte(P2)^ then + begin + Result := Integer(PByte(P1)^) - Integer(PByte(P2)^); + exit; + end; + // go to next byte + Inc(PChar(P1)); + Inc(PChar(P2)); + end; + + // memory equal + Result := 0; +end; + +function TIndexFile.CompareKeys(Key1, Key2: PChar): Integer; +begin + // call compare routine + Result := FCompareKeys(Key1, Key2); + + // if descending then reverse order + if FIsDescending then + Result := -Result; +end; + +function TIndexFile.CompareKeysNumericNDX(Key1, Key2: PChar): Integer; +var + v1,v2: Double; +begin + v1 := PDouble(Key1)^; + v2 := PDouble(Key2)^; + if v1 > v2 then Result := 1 + else if v1 < v2 then Result := -1 + else Result := 0; +end; + +function TIndexFile.CompareKeysNumericMDX(Key1, Key2: PChar): Integer; +var + neg1, neg2: Boolean; +begin + // first byte - $34 contains dot position + neg1 := (Byte(Key1[1]) and $80) <> 0; + neg2 := (Byte(Key2[1]) and $80) <> 0; + // check if both negative or both positive + if neg1 = neg2 then + begin + // check alignment + if Key1[0] = Key2[0] then + begin + // no alignment needed -> have same alignment + Result := MemComp(Key1+2, Key2+2, 10-2); + end else begin + // greater 10-power implies bigger number except for zero + if (Byte(Key1[0]) = $01) and (Byte(Key1[1]) = $34) then + Result := -1 + else + if (Byte(Key2[0]) = $01) and (Byte(Key2[1]) = $34) then + Result := 1 + else + Result := Byte(Key1[0]) - Byte(Key2[0]); + end; + // negate result if both negative + if neg1 and neg2 then + Result := -Result; + end else if neg1 {-> not neg2} then + Result := -1 + else { not neg1 and neg2 } + Result := 1; +end; + +function TIndexFile.CompareKeysString(Key1, Key2: PChar): Integer; +begin + Result := DbfCompareString(FCollation, Key1, KeyLen, Key2, KeyLen); + if Result > 0 then + Dec(Result, 2); +end; + +function TIndexFile.CompareKey(Key: PChar): Integer; +begin + Result := CompareKeys(FUserKey, Key); +end; + +function TIndexFile.IndexOf(const AIndexName: string): Integer; + // *) assumes FIndexVersion >= xBaseIV +var + I: Integer; +begin + // get index of this index :-) + Result := -1; + for I := 0 to SwapWordLE(PMdxHdr(Header)^.TagsUsed) - 1 do + begin + FTempMdxTag.Tag := CalcTagOffset(I); + if AnsiCompareText(AIndexName, FTempMdxTag.TagName) = 0 then + begin + Result := I; + break; + end; + end; +end; + +procedure TIndexFile.SetIndexName(const AIndexName: string); +var + found: Integer; +begin + // we can only select a different index if we are MDX + if FIndexVersion >= xBaseIV then + begin + // find index + found := IndexOf(AIndexName); + end else + found := 0; + // if changing index, range is N/A anymore + if FRangeActive and (found <> FSelectedIndex) then + begin + FRangeIndex := FSelectedIndex; + DisableRange; + end; + // we can now select by index + if found >= 0 then + begin + SelectIndexVars(found); + if found = FRangeIndex then + begin + EnableRange; + FRangeIndex := -1; + end; + end; +end; + +function TIndexFile.CalcTagOffset(AIndex: Integer): Pointer; +begin + Result := PChar(Header) + FTagOffset + AIndex * FTagSize; +end; + +procedure TIndexFile.SelectIndexVars(AIndex: Integer); + // *) assumes index is in range +begin + if AIndex >= 0 then + begin + // get pointer to index header + FIndexHeader := FIndexHeaders[AIndex]; + // load root + leaf + FCurrentParser := FParsers[AIndex]; + FRoot := FRoots[AIndex]; + FLeaf := FLeaves[AIndex]; + // if xBaseIV then we need to store where pageno of current header + if FIndexVersion >= xBaseIV then + begin + FMdxTag.Tag := CalcTagOffset(AIndex); + FIndexName := FMdxTag.TagName; + FHeaderPageNo := FMdxTag.HeaderPageNo; + // does dBase actually use this flag? +// FIsExpression := FMdxTag.KeyFormat = KeyFormat_Expression; + end else begin + // how does dBase III store whether it is expression? +// FIsExpression := true; + end; + // retrieve properties + UpdateIndexProperties; + end else begin + // not a valid index + FIndexName := EmptyStr; + end; + // store selected index + FSelectedIndex := AIndex; + FCanEdit := not FForceReadOnly; +end; + +procedure TIndexFile.UpdateIndexProperties; +begin + // get properties + FIsDescending := (PIndexHdr(FIndexHeader)^.KeyFormat and KeyFormat_Descending) <> 0; + FUniqueMode := iuNormal; + if (PIndexHdr(FIndexHeader)^.KeyFormat and KeyFormat_Unique) <> 0 then + FUniqueMode := iuUnique; + if (PIndexHdr(FIndexHeader)^.KeyFormat and KeyFormat_Distinct) <> 0 then + FUniqueMode := iuDistinct; + // select key compare routine + if PIndexHdr(FIndexHeader)^.KeyType = 'C' then + FCompareKeys := CompareKeysString + else + if FIndexVersion >= xBaseIV then + FCompareKeys := CompareKeysNumericMDX + else + FCompareKeys := CompareKeysNumericNDX; +end; + +procedure TIndexFile.Flush; +var + I: Integer; +begin + // save changes to pages + if FIndexVersion >= xBaseIV then + begin + for I := 0 to MaxIndexes - 1 do + begin + if FIndexHeaderModified[I] then + WriteIndexHeader(I); + if FRoots[I] <> nil then + FRoots[I].Flush + end; + end else begin + if FRoot <> nil then + FRoot.Flush; + end; + + // save changes to header + FlushHeader; + + inherited; +end; + +(* + +function TIndexFile.GetIndexCount: Integer; +begin + if FIndexVersion = xBaseIII then + Result := 1 + else + if FIndexVersion = xBaseIV then + Result := PMdxHdr(Header).TagsUsed; + else + Result := 0; +end; + +*) + +procedure TIndexFile.GetIndexNames(const AList: TStrings); +var + I: Integer; +begin + // only applicable to MDX files + if FIndexVersion >= xBaseIV then + begin + for I := 0 to SwapWordLE(PMdxHdr(Header)^.TagsUsed) - 1 do + begin + FTempMdxTag.Tag := CalcTagOffset(I); + AList.AddObject(FTempMdxTag.TagName, Self); + end; + end; +end; + +procedure TIndexFile.GetIndexInfo(const AIndexName: string; IndexDef: TDbfIndexDef); +var + SaveIndexName: string; +begin + // remember current index + SaveIndexName := IndexName; + // select index + IndexName := AIndexName; + // copy properties + IndexDef.IndexFile := AIndexName; + IndexDef.Expression := PIndexHdr(FIndexHeader)^.KeyDesc; + IndexDef.Options := []; + IndexDef.Temporary := true; + if FIsDescending then + IndexDef.Options := IndexDef.Options + [ixDescending]; + IndexDef.Options := IndexDef.Options + [ixExpression]; + case FUniqueMode of + iuUnique: IndexDef.Options := IndexDef.Options + [ixUnique]; + iuDistinct: IndexDef.Options := IndexDef.Options + [ixPrimary]; + end; + // reselect previous index + IndexName := SaveIndexName; +end; + +function TIndexFile.GetExpression: string; +begin + if FCurrentParser <> nil then + Result := FCurrentParser.Expression + else + Result := EmptyStr; +end; + +function TIndexFile.GetDbfLanguageId: Byte; +begin + // check if parent DBF version 7, get language id + if (TDbfFile(FDbfFile).DbfVersion = xBaseVII) then + begin + // get language id of parent dbf + Result := GetLangId_From_LangName(TDbfFile(FDbfFile).LanguageStr); + end else begin + // dBase IV has language id in header + Result := TDbfFile(FDbfFile).LanguageID; + end; +end; + +procedure TIndexFile.WriteHeader; {override;} +begin + // if NDX, then this means file header + if FIndexVersion >= xBaseIV then + if NeedLocks then + WriteIndexHeader(FSelectedIndex) + else + FIndexHeaderModified[FSelectedIndex] := true + else + WriteFileHeader; +end; + +procedure TIndexFile.WriteFileHeader; +begin + inherited WriteHeader; +end; + +procedure TIndexFile.WriteIndexHeader(AIndex: Integer); +begin + FTempMdxTag.Tag := CalcTagOffset(AIndex); + WriteRecord(FTempMdxTag.HeaderPageNo, FIndexHeaders[AIndex]); + FIndexHeaderModified[AIndex] := false; +end; + +//========================================================== +//============ TDbfIndexDef +//========================================================== + +constructor TDbfIndexDef.Create(ACollection: TCollection); {override;} +begin + inherited Create(ACollection); + FTemporary := false; +end; + +destructor TDbfIndexDef.Destroy; {override;} +begin + inherited Destroy; +end; + +procedure TDbfIndexDef.Assign(Source: TPersistent); +begin + // we can't do anything with it if not a TDbfIndexDef + if Source is TDbfIndexDef then + begin + FIndexName := TDbfIndexDef(Source).IndexFile; + FExpression := TDbfIndexDef(Source).Expression; + FOptions := TDbfIndexDef(Source).Options; + end else + inherited; +end; + +procedure TDbfIndexDef.SetIndexName(NewName: string); +begin + FIndexName := AnsiUpperCase(Trim(NewName)); +end; + +procedure TDbfIndexDef.SetExpression(NewField: string); +begin + FExpression := AnsiUpperCase(Trim(NewField)); +end; + +initialization + +{ + Entry_Mdx_BOF.RecBlockNo := RecBOF; + Entry_Mdx_BOF.KeyData := #0; + + Entry_Mdx_EOF.RecBlockNo := RecEOF; + Entry_Mdx_EOF.KeyData := #0; + + Entry_Ndx_BOF.LowerPageNo := 0; + Entry_Ndx_BOF.RecNo := RecBOF; + Entry_Ndx_BOF.KeyData := #0; + + Entry_Ndx_EOF.LowerPageNo := 0; + Entry_Ndx_EOF.RecNo := RecEOF; + Entry_Ndx_EOF.KeyData := #0; +} + + LCIDList := TLCIDList.Create; + LCIDList.Enumerate; + +finalization + + LCIDList.Free; + +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_lang.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_lang.pas new file mode 100644 index 0000000..83151da --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_lang.pas @@ -0,0 +1,655 @@ +unit dbf_lang; + +{$I dbf_common.inc} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses +{$ifdef msWINDOWS} + Windows; +{$else} +{$ifdef KYLIX} + Libc, +{$endif} + Types, dbf_wtil; +{$endif} + +const + +//*************************************************************************// +// DB3/DB4/FoxPro Lang ID consts, for readable code +//*************************************************************************// + +// ... + FoxLangId_ENU_437 = $01; + FoxLangId_Intl_850 = $02; + FoxLangId_Windows_1252 = $03; + FoxLangId_Mac_10000 = $04; +// ... + DbfLangId_DAN_865 = $08; + DbfLangId_NLD_437 = $09; + DbfLangId_NLD_850 = $0A; + DbfLangId_FIN_437 = $0B; + DbfLangId_FIN_850 = $0C; // is it used? does not exist in BDE + DbfLangId_FRA_437 = $0D; + DbfLangId_FRA_850 = $0E; + DbfLangId_DEU_437 = $0F; + DbfLangId_DEU_850 = $10; + DbfLangId_ITA_437 = $11; + DbfLangId_ITA_850 = $12; + DbfLangId_JPN_932 = $13; + DbfLangId_ESP_850 = $14; + DbfLangId_SVE_437 = $15; + DbfLangId_SVE_850 = $16; + DbfLangId_NOR_865 = $17; + DbfLangId_ESP_437 = $18; + DbfLangId_ENG_437 = $19; + DbfLangId_ENG_850 = $1A; + DbfLangId_ENU_437 = $1B; + DbfLangId_FRC_863 = $1C; + DbfLangId_FRC_850 = $1D; +// ... + DbfLangId_CSY_852 = $1F; + DbfLangId_CSY_867 = $20; +// ... + DbfLangId_HUN_852 = $22; + DbfLangId_PLK_852 = $23; + DbfLangId_PTG_860 = $24; + DbfLangId_PTB_850 = $25; + DbfLangId_RUS_866 = $26; +// ... + DbfLangId_ENU_850 = $37; +// ... + DbfLangId_CHS_936 = $4D; + DbfLangId_KOR_949 = $4E; + DbfLangId_CHT_950 = $4F; + DbfLangId_THA_874 = $50; +// ... + DbfLangId_JPN_DIC_932 = $56; + DbfLangId_Ascii_1252 = $57; + DbfLangId_WEurope_1252 = $58; + DbfLangId_Spanish_1252 = $59; +// ... + FoxLangId_German_437 = $5E; + FoxLangId_Nordic_437 = $5F; + FoxLangId_Nordic_850 = $60; + FoxLangId_German_1252 = $61; + FoxLangId_Nordic_1252 = $62; +// ... + FoxLangId_EEurope_852 = $64; + FoxLangId_Russia_866 = $65; + FoxLangId_Nordic_865 = $66; + FoxLangId_Iceland_861 = $67; + FoxLangId_Czech_895 = $68; +// ... + DbfLangId_POL_620 = $69; +// ... + FoxLangId_Greek_737 = $6A; + FoxLangId_Turkish_857 = $6B; +// ... + FoxLangId_Taiwan_950 = $78; + FoxLangId_Korean_949 = $79; + FoxLangId_Chinese_936 = $7A; + FoxLangId_Japan_932 = $7B; + FoxLangId_Thai_874 = $7C; + FoxLangId_Hebrew_1255 = $7D; + FoxLangId_Arabic_1256 = $7E; +// ... + DbfLangId_Hebrew = $85; + DbfLangId_ELL_437 = $86; // greek, code page 737 (?) + DbfLangId_SLO_852 = $87; + DbfLangId_TRK_857 = $88; +// ... + DbfLangId_BUL_868 = $8E; +// ... + FoxLangId_Russia_10007 = $96; + FoxLangId_EEurope_10029 = $97; + FoxLangId_Greek_10006 = $98; +// ... + FoxLangId_Czech_1250 = $9B; + FoxLangId_Czech_850 = $9C; // DOS +// ... + FoxLangId_EEurope_1250 = $C8; + FoxLangId_Russia_1251 = $C9; + FoxLangId_Turkish_1254 = $CA; + FoxLangId_Greek_1253 = $CB; + + +// special constants + + DbfLocale_NotFound = $010000; + DbfLocale_Bul868 = $020000; + +//*************************************************************************// +// DB3/DB4/FoxPro Language ID to CodePage convert table +//*************************************************************************// + + LangId_To_CodePage: array[Byte] of Word = +// | 0| 1| 2| 3| 4| 5| 6| 7| +// | 8| 9| A| B| C| D| E| F| +// | | | | | | | | | +{00} ( 0, 437, 850, 1252,10000, 0, 0, 0, +{08} 865, 437, 850, 437, 850, 437, 850, 437, +{10} 850, 437, 850, 932, 850, 437, 850, 865, +{18} 437, 437, 850, 437, 863, 850, 0, 852, +{20} 867, 0, 852, 852, 860, 850, 866, 0, +{28} 0, 0, 0, 0, 0, 0, 0, 0, +{30} 0, 0, 0, 0, 0, 0, 0, 850, +{38} 0, 0, 0, 0, 0, 0, 0, 0, +{40} 0, 0, 0, 0, 0, 0, 0, 0, +{48} 0, 0, 0, 0, 0, 936, 949, 950, +{50} 874, 0, 0, 0, 0, 0, 932, 1252, +{58} 1252, 1252, 0, 0, 0, 0, 437, 437, +{60} 850, 1252, 1252, 0, 852, 866, 865, 861, +{68} 895, 620, 737, 857, 0, 0, 0, 0, +{70} 0, 0, 0, 0, 0, 0, 0, 0, +{78} 950, 949, 936, 932, 874, 1255, 1256, 0, +{80} 0, 0, 0, 0, 0, 862, 437, 852, +{88} 857, 0, 0, 0, 0, 0, 868, 0, +{90} 0, 0, 0, 0, 0, 0,10007,10029, +{98} 10006, 0, 0, 1250, 850, 0, 0, 0, +{A0} 0, 0, 0, 0, 0, 0, 0, 0, +{A8} 0, 0, 0, 0, 0, 0, 0, 0, +{B0} 0, 0, 0, 0, 0, 0, 0, 0, +{B8} 0, 0, 0, 0, 0, 0, 0, 0, +{C0} 0, 0, 0, 0, 0, 0, 0, 0, +{C8} 1250, 1251, 1254, 1253, 0, 0, 0, 0, +{D0} 0, 0, 0, 0, 0, 0, 0, 0, +{D8} 0, 0, 0, 0, 0, 0, 0, 0, +{E0} 0, 0, 0, 0, 0, 0, 0, 0, +{E8} 0, 0, 0, 0, 0, 0, 0, 0, +{F0} 0, 0, 0, 0, 0, 0, 0, 0, +{F8} 0, 0, 0, 0, 0, 0, 0, 0); + +{$ifdef FPC_VERSION} +{$ifdef VER1_0} + LANG_ARABIC = $01; + LANG_HEBREW = $0d; + LANG_THAI = $1e; + SUBLANG_KOREAN = $01; { Korean (Extended Wansung) } + SORT_CHINESE_PRC = $2; { PRC Chinese Stroke Count order } +{$endif} +{$endif} + +//*************************************************************************// +// DB3/DB4/FoxPro Language ID to Locale convert table +//*************************************************************************// + +// table + + LangId_To_Locale: array[Byte] of LCID = + ( + DbfLocale_NotFound, +{01} LANG_ENGLISH or (SUBLANG_ENGLISH_US shl 10) or (SORT_DEFAULT shl 16), + LANG_ENGLISH or (SUBLANG_ENGLISH_UK shl 10) or (SORT_DEFAULT shl 16), {international ??} + LANG_ENGLISH or (SUBLANG_ENGLISH_UK shl 10) or (SORT_DEFAULT shl 16), {windows ??} + LANG_ENGLISH or (SUBLANG_ENGLISH_UK shl 10) or (SORT_DEFAULT shl 16), {macintosh ??} + 0,0,0, +{08} LANG_DANISH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_DUTCH or (SUBLANG_DUTCH shl 10) or (SORT_DEFAULT shl 16), + LANG_DUTCH or (SUBLANG_DUTCH shl 10) or (SORT_DEFAULT shl 16), + LANG_FINNISH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_FINNISH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_FRENCH or (SUBLANG_FRENCH shl 10) or (SORT_DEFAULT shl 16), + LANG_FRENCH or (SUBLANG_FRENCH shl 10) or (SORT_DEFAULT shl 16), + LANG_GERMAN or (SUBLANG_GERMAN shl 10) or (SORT_DEFAULT shl 16), + LANG_GERMAN or (SUBLANG_GERMAN shl 10) or (SORT_DEFAULT shl 16), + LANG_ITALIAN or (SUBLANG_ITALIAN shl 10) or (SORT_DEFAULT shl 16), + LANG_ITALIAN or (SUBLANG_ITALIAN shl 10) or (SORT_DEFAULT shl 16), + LANG_JAPANESE or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_SPANISH or (SUBLANG_SPANISH shl 10) or (SORT_DEFAULT shl 16), + LANG_SWEDISH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_SWEDISH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_NORWEGIAN or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_SPANISH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_ENGLISH or (SUBLANG_ENGLISH_UK shl 10) or (SORT_DEFAULT shl 16), + LANG_ENGLISH or (SUBLANG_ENGLISH_UK shl 10) or (SORT_DEFAULT shl 16), + LANG_ENGLISH or (SUBLANG_ENGLISH_US shl 10) or (SORT_DEFAULT shl 16), + LANG_FRENCH or (SUBLANG_FRENCH_CANADIAN shl 10) or (SORT_DEFAULT shl 16), + LANG_FRENCH or (SUBLANG_FRENCH_CANADIAN shl 10) or (SORT_DEFAULT shl 16), +{1E} 0, +{1F} LANG_CZECH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_CZECH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), +{21} 0, +{22} LANG_HUNGARIAN or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_POLISH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_PORTUGUESE or (SUBLANG_PORTUGUESE_BRAZILIAN shl 10) or (SORT_DEFAULT shl 16), + LANG_PORTUGUESE or (SUBLANG_PORTUGUESE_BRAZILIAN shl 10) or (SORT_DEFAULT shl 16), + LANG_RUSSIAN or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), +{27} 0,0,0,0,0,0,0,0,0, +{30} 0,0,0,0,0,0,0, +{37} LANG_ENGLISH or (SUBLANG_ENGLISH_US shl 10) or (SORT_DEFAULT shl 16), +{38} 0,0,0,0,0,0,0,0, +{40} 0,0,0,0,0,0,0,0,0,0,0,0,0, +{4D} LANG_CHINESE or (SUBLANG_CHINESE_SIMPLIFIED shl 10) or (SORT_DEFAULT shl 16), + LANG_KOREAN or (SUBLANG_KOREAN shl 10) or (SORT_DEFAULT shl 16), + LANG_CHINESE or (SUBLANG_CHINESE_TRADITIONAL shl 10) or (SORT_DEFAULT shl 16), + LANG_THAI or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), +{51} 0,0,0,0,0, +{56} LANG_JAPANESE or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), // JPN: Dic932 ?? + 0, // Ascii: Binary + LANG_ENGLISH or (SUBLANG_ENGLISH_UK shl 10) or (SORT_DEFAULT shl 16), // Western Europe ?? + LANG_SPANISH or (SUBLANG_SPANISH shl 10) or (SORT_DEFAULT shl 16), +{5A} 0,0,0,0, +// FoxPro +{5E} LANG_GERMAN or (SUBLANG_GERMAN shl 10) or (SORT_DEFAULT shl 16), + LANG_NORWEGIAN or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_NORWEGIAN or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_GERMAN or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_NORWEGIAN or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), +{63} 0, +{64} LANG_CZECH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), // Eastern Europe ?? + LANG_RUSSIAN or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_NORWEGIAN or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_ICELANDIC or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_CZECH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_POLISH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_GREEK or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_TURKISH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), +{6C} 0,0,0,0, +{70} 0,0,0,0,0,0,0,0, +{78} LANG_CHINESE or (SUBLANG_CHINESE_HONGKONG shl 10) or (SORT_DEFAULT shl 16), + LANG_KOREAN or (SUBLANG_KOREAN shl 10) or (SORT_DEFAULT shl 16), + LANG_CHINESE or (SUBLANG_CHINESE_SINGAPORE shl 10) or (SORT_CHINESE_PRC shl 16), + LANG_JAPANESE or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), // JPN: Dic932 ?? + LANG_THAI or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_HEBREW or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_ARABIC or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + 0, +{80} 0,0,0,0,0, +// dBase +{85} LANG_HEBREW or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_GREEK or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_SLOVAK or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_TURKISH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), +{89} 0,0,0,0,0, +{8E} LANG_BULGARIAN or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), +{8F} 0,0,0,0,0,0,0, +{96} LANG_RUSSIAN or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_CZECH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), // Eastern Europe ?? + LANG_GREEK or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + 0,0, +// FoxPro +{9B} LANG_CZECH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_CZECH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), +{9D} 0,0,0, +{A0} 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +{B0} 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +{C0} 0,0,0,0,0,0,0,0, +{C8} LANG_CZECH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), // Eastern Europe ?? + LANG_RUSSIAN or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_TURKISH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + LANG_GREEK or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), +{CC} 0,0,0,0, +{D0} 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +{E0} 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +{F0} 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ); + +//*************************************************************************// +// DB7 LangID Locale substrings +//*************************************************************************// + +// convert table + + LangId_To_LocaleStr: array[Byte] of Cardinal = + ( + DbfLocale_NotFound, +{01} Ord('U') or (Ord('S') shl 8) or (Ord('0') shl 16), + Ord('U') or (Ord('K') shl 8) or (Ord('0') shl 16), + Ord('U') or (Ord('K') shl 8) or (Ord('0') shl 16), + Ord('U') or (Ord('K') shl 8) or (Ord('0') shl 16), + 0,0,0, +{08} Ord('D') or (Ord('A') shl 8) or (Ord('0') shl 16), + Ord('N') or (Ord('L') shl 8) or (Ord('0') shl 16), + Ord('N') or (Ord('L') shl 8) or (Ord('0') shl 16), + Ord('F') or (Ord('I') shl 8) or (Ord('0') shl 16), + Ord('F') or (Ord('I') shl 8) or (Ord('0') shl 16), + Ord('F') or (Ord('R') shl 8) or (Ord('0') shl 16), + Ord('F') or (Ord('R') shl 8) or (Ord('0') shl 16), + Ord('D') or (Ord('E') shl 8) or (Ord('0') shl 16), + Ord('D') or (Ord('E') shl 8) or (Ord('0') shl 16), + Ord('I') or (Ord('T') shl 8) or (Ord('0') shl 16), + Ord('I') or (Ord('T') shl 8) or (Ord('1') shl 16), + Ord('J') or (Ord('P') shl 8) or (Ord('0') shl 16), + Ord('E') or (Ord('S') shl 8) or (Ord('0') shl 16), + Ord('S') or (Ord('V') shl 8) or (Ord('0') shl 16), + Ord('S') or (Ord('V') shl 8) or (Ord('1') shl 16), + Ord('N') or (Ord('O') shl 8) or (Ord('0') shl 16), + Ord('E') or (Ord('S') shl 8) or (Ord('1') shl 16), + Ord('U') or (Ord('K') shl 8) or (Ord('0') shl 16), + Ord('U') or (Ord('K') shl 8) or (Ord('0') shl 16), + Ord('U') or (Ord('S') shl 8) or (Ord('0') shl 16), + Ord('C') or (Ord('F') shl 8) or (Ord('1') shl 16), + Ord('C') or (Ord('F') shl 8) or (Ord('1') shl 16), +{1E} 0, +{1F} Ord('C') or (Ord('Z') shl 8) or (Ord('0') shl 16), + Ord('C') or (Ord('Z') shl 8) or (Ord('0') shl 16), +{21} 0, +{22} Ord('H') or (Ord('D') shl 8) or (Ord('C') shl 16), + Ord('P') or (Ord('O') shl 8) or (Ord('0') shl 16), + Ord('P') or (Ord('T') shl 8) or (Ord('0') shl 16), + Ord('P') or (Ord('T') shl 8) or (Ord('0') shl 16), + Ord('R') or (Ord('U') shl 8) or (Ord('0') shl 16), +{27} 0,0,0,0,0,0,0,0,0, +{30} 0,0,0,0,0,0,0, +{37} Ord('U') or (Ord('S') shl 8) or (Ord('0') shl 16), +{38} 0,0,0,0,0,0,0,0, +{40} 0,0,0,0,0,0,0,0,0,0,0,0,0, +{4D} Ord('C') or (Ord('N') shl 8) or (Ord('0') shl 16), + Ord('K') or (Ord('O') shl 8) or (Ord('0') shl 16), + Ord('T') or (Ord('W') shl 8) or (Ord('0') shl 16), + Ord('T') or (Ord('H') shl 8) or (Ord('0') shl 16), +{51} 0,0,0,0,0, +{56} Ord('J') or (Ord('P') shl 8) or (Ord('1') shl 16), + Ord('U') or (Ord('S') shl 8) or (Ord('0') shl 16), + Ord('W') or (Ord('E') shl 8) or (Ord('0') shl 16), + Ord('E') or (Ord('S') shl 8) or (Ord('0') shl 16), +{5A} 0,0,0,0, +// FoxPro +{5E} Ord('D') or (Ord('E') shl 8), + Ord('N') or (Ord('O') shl 8), + Ord('N') or (Ord('O') shl 8), + Ord('D') or (Ord('E') shl 8), + Ord('N') or (Ord('O') shl 8), +{63} 0, +{64} Ord('C') or (Ord('Z') shl 8) or (Ord('0') shl 16), + Ord('R') or (Ord('U') shl 8) or (Ord('0') shl 16), + Ord('N') or (Ord('O') shl 8), + Ord('I') or (Ord('C') shl 8) or (Ord('0') shl 16), // made this one up: iceland + Ord('C') or (Ord('Z') shl 8) or (Ord('0') shl 16), +{69} Ord('P') or (Ord('O') shl 8) or (Ord('1') shl 16), + Ord('G') or (Ord('R') shl 8) or (Ord('0') shl 16), + Ord('T') or (Ord('R') shl 8) or (Ord('0') shl 16), +{6C} 0,0,0,0, +{70} 0,0,0,0,0,0,0,0, +{78} Ord('C') or (Ord('H') shl 8) or (Ord('0') shl 16), // made this one up: chinese hongkong + Ord('K') or (Ord('O') shl 8) or (Ord('0') shl 16), + Ord('C') or (Ord('S') shl 8) or (Ord('0') shl 16), // made this one up: chinese singapore + Ord('J') or (Ord('P') shl 8) or (Ord('0') shl 16), + Ord('T') or (Ord('H') shl 8) or (Ord('0') shl 16), + Ord('R') or (Ord('E') shl 8) or (Ord('W') shl 16), + Ord('A') or (Ord('R') shl 8) or (Ord('0') shl 16), // made this one up: arabic (default) +{7F} 0, +{80} 0,0,0,0,0, +// dBase +{85} Ord('R') or (Ord('E') shl 8) or (Ord('W') shl 16), + Ord('G') or (Ord('R') shl 8) or (Ord('0') shl 16), + Ord('S') or (Ord('L') shl 8) or (Ord('0') shl 16), + Ord('T') or (Ord('R') shl 8) or (Ord('0') shl 16), +{89} 0,0,0,0,0, +{8E} DbfLocale_Bul868, +{8F} 0,0,0,0,0,0,0, +{96} Ord('R') or (Ord('U') shl 8) or (Ord('0') shl 16), + Ord('C') or (Ord('Z') shl 8) or (Ord('0') shl 16), + Ord('G') or (Ord('R') shl 8) or (Ord('0') shl 16), +{99} 0,0, +// FoxPro +{9B} 0, //LANG_CZECH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), + 0, //LANG_CZECH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), +{9D} 0,0,0, +{A0} 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +{B0} 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +{C0} 0,0,0,0,0,0,0,0, +{C8} Ord('C') or (Ord('Z') shl 8) or (Ord('0') shl 16), + Ord('R') or (Ord('U') shl 8) or (Ord('0') shl 16), + Ord('T') or (Ord('R') shl 8) or (Ord('0') shl 16), + Ord('G') or (Ord('R') shl 8) or (Ord('0') shl 16), +{CC} 0,0,0,0, +{D0} 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +{E0} 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +{F0} 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ); + +{ + DbfLocaleId_DAN_865 = Ord('D') or (Ord('A') shl 8) or (Ord('0') shl 16); + DbfLocaleId_NLD_437 = Ord('N') or (Ord('L') shl 8) or (Ord('0') shl 16); + DbfLocaleId_NLD_850 = Ord('N') or (Ord('L') shl 8) or (Ord('0') shl 16); + DbfLocaleId_FIN_437 = Ord('F') or (Ord('I') shl 8) or (Ord('0') shl 16); + DbfLocaleId_FIN_850 = Ord('F') or (Ord('I') shl 8) or (Ord('0') shl 16); + DbfLocaleId_FRA_437 = Ord('F') or (Ord('R') shl 8) or (Ord('0') shl 16); + DbfLocaleId_FRA_850 = Ord('F') or (Ord('R') shl 8) or (Ord('0') shl 16); + DbfLocaleId_DEU_437 = Ord('D') or (Ord('E') shl 8) or (Ord('0') shl 16); + DbfLocaleId_DEU_850 = Ord('D') or (Ord('E') shl 8) or (Ord('0') shl 16); + DbfLocaleId_ITA_437 = Ord('I') or (Ord('T') shl 8) or (Ord('0') shl 16); + DbfLocaleId_ITA_850 = Ord('I') or (Ord('T') shl 8) or (Ord('1') shl 16); + DbfLocaleId_JPN_932 = Ord('J') or (Ord('P') shl 8) or (Ord('0') shl 16); + DbfLocaleId_ESP_850 = Ord('E') or (Ord('S') shl 8) or (Ord('0') shl 16); + DbfLocaleId_SVE_437 = Ord('S') or (Ord('V') shl 8) or (Ord('0') shl 16); + DbfLocaleId_SVE_850 = Ord('S') or (Ord('V') shl 8) or (Ord('1') shl 16); + DbfLocaleId_NOR_865 = Ord('N') or (Ord('O') shl 8) or (Ord('0') shl 16); + DbfLocaleId_ESP_437 = Ord('E') or (Ord('S') shl 8) or (Ord('1') shl 16); + DbfLocaleId_ENG_437 = Ord('U') or (Ord('K') shl 8) or (Ord('0') shl 16); + DbfLocaleId_ENG_850 = Ord('U') or (Ord('K') shl 8) or (Ord('0') shl 16); + DbfLocaleId_ENU_437 = Ord('U') or (Ord('S') shl 8) or (Ord('0') shl 16); + DbfLocaleId_FRC_863 = Ord('C') or (Ord('F') shl 8) or (Ord('1') shl 16); + DbfLocaleId_FRC_850 = Ord('C') or (Ord('F') shl 8) or (Ord('1') shl 16); +// ... + DbfLocaleId_CSY_852 = Ord('C') or (Ord('Z') shl 8) or (Ord('0') shl 16); + DbfLocaleId_CSY_867 = Ord('C') or (Ord('Z') shl 8) or (Ord('0') shl 16); +// ... + DbfLocaleId_HUN_852 = Ord('H') or (Ord('D') shl 8) or (Ord('C') shl 16); + DbfLocaleId_PLK_852 = Ord('P') or (Ord('O') shl 8) or (Ord('0') shl 16); + DbfLocaleId_PTG_860 = Ord('P') or (Ord('T') shl 8) or (Ord('0') shl 16); + DbfLocaleId_PTB_850 = Ord('P') or (Ord('T') shl 8) or (Ord('0') shl 16); + DbfLocaleId_RUS_866 = Ord('R') or (Ord('U') shl 8) or (Ord('0') shl 16); +// ... + DbfLocaleId_ENU_850 = Ord('U') or (Ord('S') shl 8) or (Ord('0') shl 16); +// ... + DbfLocaleId_CHS_936 = Ord('C') or (Ord('N') shl 8) or (Ord('0') shl 16); + DbfLocaleId_KOR_949 = Ord('K') or (Ord('O') shl 8) or (Ord('0') shl 16); + DbfLocaleId_CHT_950 = Ord('T') or (Ord('W') shl 8) or (Ord('0') shl 16); + DbfLocaleId_THA_874 = Ord('T') or (Ord('H') shl 8) or (Ord('0') shl 16); +// ... + DbfLocaleId_JPN_DIC_932 = Ord('J') or (Ord('P') shl 8) or (Ord('1') shl 16); + DbfLocaleId_Ascii_Ansi = Ord('U') or (Ord('S') shl 8) or (Ord('0') shl 16); + DbfLocaleId_WEurope_Ansi = Ord('W') or (Ord('E') shl 8) or (Ord('0') shl 16); + DbfLocaleId_Spanish_Ansi = Ord('E') or (Ord('S') shl 8) or (Ord('0') shl 16); +// ... + DbfLocaleId_Hebrew = Ord('R') or (Ord('E') shl 8) or (Ord('W') shl 16); + DbfLocaleId_ELL_437 = Ord('G') or (Ord('R') shl 8) or (Ord('0') shl 16); + DbfLocaleId_SLO_852 = Ord('S') or (Ord('L') shl 8) or (Ord('0') shl 16); + DbfLocaleId_TRK_857 = Ord('T') or (Ord('R') shl 8) or (Ord('0') shl 16); +// ... + DbfLocaleId_BUL_868 = 'BGDB868'; +} + +// VdBase 7 Language strings +// 'DBWIN...' -> Charset 1252 (ansi) +// 'DB999...' -> Code page 999, 9 any digit +// 'DBHEBREW' -> Code page 1255 ?? +// 'FOX..999' -> Code page 999, 9 any digit +// 'FOX..WIN' -> Charset 1252 (ansi) + +//*************************************************************************// +// reverse convert routines +//*************************************************************************// + +function ConstructLangName(CodePage: Integer; Locale: LCID; IsFoxPro: Boolean): string; + +function ConstructLangId(CodePage: Integer; Locale: LCID; IsFoxPro: Boolean): Byte; + +function GetLangId_From_LangName(LocaleStr: string): Byte; + +implementation + +uses + SysUtils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + PCardinal = ^Cardinal; + +function ConstructLangName(CodePage: Integer; Locale: LCID; IsFoxPro: Boolean): string; +var + SubType: Cardinal; +begin + // ANSI? + SubType := LangId_To_LocaleStr[ConstructLangId(CodePage, Locale, IsFoxPro)]; + // found? + if SubType <> DbfLocale_NotFound then + begin + // foxpro or dbase? + if IsFoxPro then + begin + Result := 'FOX' + PChar(@SubType); + if CodePage = 1252 then + Result := Result + 'WIN' + else + Result := Result + IntToStr(CodePage); + end else begin + if SubType = DbfLocale_Bul868 then + begin + // special case + Result := 'BGDB868'; + end else begin + // start with DB + Result := 'DB'; + // add codepage + if CodePage = 1252 then + Result := Result + 'WIN' + else + Result := Result + IntToStr(CodePage); + // add subtype + Result := Result + PChar(@SubType); + end; + end; + end; +end; + +const + // range of Dbase / FoxPro locale; these are INCLUSIVE + + dBase_RegionCount = 4; + dBase_Regions: array[0..dBase_RegionCount*2-1] of Byte = + ($00, $00, + $05, $5D, + $69, $69, // a lonely dbf entry :-) + $80, $90); + +function FindLangId(CodePage, Info2: Cardinal; Info2Table: PCardinal; IsFoxPro: Boolean): Byte; +var + I, Region, FoxRes, DbfRes: Integer; +begin + Region := 0; + DbfRes := 0; + FoxRes := 0; + // scan + for I := 0 to $FF do + begin + // check if need to advance to next region + if Region + 2 < dBase_RegionCount then + if I >= dBase_Regions[Region + 2] then + Inc(Region, 2); + // it seems delphi does not properly understand pointers? + // what a mess :-( + if ((LangId_To_CodePage[I] = CodePage) or (CodePage = 0)) and (PCardinal(PChar(Info2Table)+(I*4))^ = Info2) then + if I <= dBase_Regions[Region+1] then + DbfRes := Byte(I) + else + FoxRes := Byte(I); + end; + // if we can find langid in other set, use it + if (DbfRes <> 0) and (not IsFoxPro or (FoxRes = 0)) then + Result := DbfRes + else {(DbfRes = 0) or (IsFoxPro and (FoxRes <> 0)} + if (FoxRes <> 0) {and (IsFoxPro or (DbfRes = 0)} then + Result := FoxRes + else + Result := 0; +end; + +{ +function FindLangId(CodePage, Info2: Cardinal; Info2Table: PCardinal; IsFoxPro: Boolean): Byte; +var + I, Region, lEnd: Integer; + EndReached: Boolean; +begin + Region := 0; + Result := 0; + repeat + // determine region to scan + if IsFoxPro then + begin + // foxpro, in between dbase regions + I := dBase_Regions[Region+1] + 1; + lEnd := dBase_Regions[Region+2] - 1; + EndReached := Region = dBase_RegionCount*2-4; + end else begin + // dBase, select regions + I := dBase_Regions[Region]; + lEnd := dBase_Regions[Region+1]; + EndReached := Region = dBase_RegionCount*2-2; + end; + // scan + repeat + // it seems delphi does not properly understand pointers? + // what a mess :-( + if (LangId_To_CodePage[I] = CodePage) and (PCardinal(PChar(Info2Table)+(I*4))^ = Info2) then + Result := Byte(I); + Inc(I); + // lEnd is included in range + until (Result <> 0) or (I > lEnd); + // goto next region + if (Result = 0) then + Inc(Region, 2); + // found or end? + until (Result <> 0) or EndReached; +end; +} + +function ConstructLangId(CodePage: Integer; Locale: LCID; IsFoxPro: Boolean): Byte; +begin + // locale: lower 16bits only + Locale := (Locale and $FFFF) or (SORT_DEFAULT shl 16); + Result := FindLangId(CodePage, Locale, @LangId_To_Locale[0], IsFoxPro); + // not found? try any codepage + if Result = 0 then + Result := FindLangId(0, Locale, @LangId_To_Locale[0], IsFoxPro); +end; + +function GetLangId_From_LangName(LocaleStr: string): Byte; +var + CodePage, SubType: Integer; + IsFoxPro: Boolean; + CodePageStr: string; +begin + // determine foxpro/dbase + IsFoxPro := CompareMem(PChar('FOX'), PChar(LocaleStr), 3); + // get codepage/locale subtype + if IsFoxPro then + begin + CodePageStr := Copy(LocaleStr, 6, 3); + SubType := Integer(LocaleStr[4]) or (Integer(LocaleStr[5]) shl 8); + end else begin + CodePageStr := Copy(LocaleStr, 3, 3); + SubType := Integer(LocaleStr[6]) or (Integer(LocaleStr[7]) shl 8) or (Integer(LocaleStr[8]) shl 16); + end; + // convert codepage string to codepage id + if CodePageStr = 'WIN' then + CodePage := 1252 + else if CodePageStr = 'REW' then // hebrew + CodePage := 1255 + else + CodePage := StrToInt(CodePageStr); + // find lang id + Result := FindLangId(CodePage, SubType, @LangId_To_LocaleStr[0], IsFoxPro); +end; + +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_memo.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_memo.pas new file mode 100644 index 0000000..ebdae59 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_memo.pas @@ -0,0 +1,556 @@ +unit dbf_memo; + +interface + +{$I dbf_common.inc} + +uses + classes,mclasses, + dbf_pgfile, + dbf_common; + +type + +//==================================================================== + TMemoFile = class(TPagedFile) + protected + FDbfFile: pointer; + FDbfVersion: TXBaseVersion; + FMemoRecordSize: Integer; + FOpened: Boolean; + FBuffer: PChar; + protected + function GetBlockLen: Integer; virtual; abstract; + function GetMemoSize: Integer; virtual; abstract; + function GetNextFreeBlock: Integer; virtual; abstract; + procedure SetNextFreeBlock(BlockNo: Integer); virtual; abstract; + procedure SetBlockLen(BlockLen: Integer); virtual; abstract; + public + constructor Create(ADbfFile: pointer); + destructor Destroy; override; + + procedure Open; + procedure Close; + + procedure ReadMemo(BlockNo: Integer; DestStream: TStream); + procedure WriteMemo(var BlockNo: Integer; ReadSize: Integer; Src: TStream); + + property DbfVersion: TXBaseVersion read FDbfVersion write FDbfVersion; + property MemoRecordSize: Integer read FMemoRecordSize write FMemoRecordSize; + end; + + TFoxProMemoFile = class(TMemoFile) + protected + function GetBlockLen: Integer; override; + function GetMemoSize: Integer; override; + function GetNextFreeBlock: Integer; override; + procedure SetNextFreeBlock(BlockNo: Integer); override; + procedure SetBlockLen(BlockLen: Integer); override; + end; + + TDbaseMemoFile = class(TMemoFile) + protected + function GetBlockLen: Integer; override; + function GetMemoSize: Integer; override; + function GetNextFreeBlock: Integer; override; + procedure SetNextFreeBlock(BlockNo: Integer); override; + procedure SetBlockLen(BlockLen: Integer); override; + end; + + { TNullMemoFile, a kind /dev/null memofile ;-) } + { - inv: FHeaderModified == false!! (otherwise will try to write FStream) } + { - inv: FHeaderSize == 0 } + { - inv: FNeedLocks == false } + { - WriteTo must NOT be used } + { - WriteChar must NOT be used } + + TNullMemoFile = class(TMemoFile) + protected + procedure SetHeaderOffset(NewValue: Integer); override; + procedure SetRecordSize(NewValue: Integer); override; + procedure SetHeaderSize(NewValue: Integer); override; + + function LockSection(const Offset, Length: Cardinal; const Wait: Boolean): Boolean; override; + function UnlockSection(const Offset, Length: Cardinal): Boolean; override; + + function GetBlockLen: Integer; override; + function GetMemoSize: Integer; override; + function GetNextFreeBlock: Integer; override; + procedure SetNextFreeBlock(BlockNo: Integer); override; + procedure SetBlockLen(BlockLen: Integer); override; + + public + constructor Create(ADbfFile: pointer); + + procedure CloseFile; override; + procedure OpenFile; override; + + function ReadRecord(IntRecNum: Integer; Buffer: Pointer): Integer; override; + procedure WriteRecord(IntRecNum: Integer; Buffer: Pointer); override; + end; + + PInteger = ^Integer; + TMemoFileClass = class of TMemoFile; + +implementation + +uses + SysUtils, dbf_dbffile; + +//==================================================================== +//=== Memo and binary fields support +//==================================================================== +type + + PDbtHdr = ^rDbtHdr; + rDbtHdr = record + NextBlock : dword; + Dummy : array [4..7] of Byte; + DbfFile : array [0..7] of Byte; // 8..15 + bVer : Byte; // 16 + Dummy2 : array [17..19] of Byte; + BlockLen : Word; // 20..21 + Dummy3 : array [22..511] of Byte; + end; + + PFptHdr = ^rFptHdr; + rFptHdr = record + NextBlock : dword; + Dummy : array [4..5] of Byte; + BlockLen : Word; // 20..21 + Dummy3 : array [8..511] of Byte; + end; + + PBlockHdr = ^rBlockHdr; + rBlockHdr = record + MemoType : Cardinal; + MemoSize : Cardinal; + end; + + +//========================================================== +//============ Dbtfile +//========================================================== +constructor TMemoFile.Create(ADbfFile: pointer); +begin + // init vars + FBuffer := nil; + FOpened := false; + + // call inherited + inherited Create; + + FDbfFile := ADbfFile; + FTempMode := TDbfFile(ADbfFile).TempMode; +end; + +destructor TMemoFile.Destroy; +begin + // close file + Close; + + // call ancestor + inherited; +end; + +procedure TMemoFile.Open; +begin + if not FOpened then + begin + // memo pages count start from begining of file! + PageOffsetByHeader := false; + + // open physical file + OpenFile; + + // read header + HeaderSize := 512; + + // determine version + if FDbfVersion = xBaseIII then + PDbtHdr(Header)^.bVer := 3; + VirtualLocks := false; + + if FileCreated or (HeaderSize = 0) then + begin + if (FMemoRecordSize = 0) or (FMemoRecordSize > HeaderSize) then + SetNextFreeBlock(1) + else + SetNextFreeBlock(HeaderSize div FMemoRecordSize); + SetBlockLen(FMemoRecordSize); + WriteHeader; + end; + + RecordSize := GetBlockLen; + // checking for right blocksize not needed for foxpro? + // mod 128 <> 0 <-> and 0x7F <> 0 + if (RecordSize = 0) and ((FDbfVersion = xFoxPro) or ((RecordSize and $7F) <> 0)) then + begin + SetBlockLen(512); + RecordSize := 512; + WriteHeader; + end; + + // get memory for temporary buffer + GetMem(FBuffer, RecordSize+2); + FBuffer[RecordSize] := #0; + FBuffer[RecordSize+1] := #0; + + // now open + FOpened := true; + end; +end; + +procedure TMemoFile.Close; +begin + if FOpened then + begin + // close physical file + CloseFile; + + // free mem + if FBuffer <> nil then + FreeMemAndNil(Pointer(FBuffer)); + + // now closed + FOpened := false; + end; +end; + +procedure TMemoFile.ReadMemo(BlockNo: Integer; DestStream: TStream); +var + bytesLeft,numBytes,dataStart: Integer; + done: Boolean; + lastc: char; + endMemo: PChar; +begin + // clear dest + DestStream.Position := 0; + DestStream.Size := 0; + // no block to read? + if (BlockNo<=0) or (RecordSize=0) then + exit; + // read first block + numBytes := ReadRecord(BlockNo, @FBuffer[0]); + if numBytes = 0 then + begin + // EOF reached? + exit; + end else + if numBytes < RecordSize then + FillChar(FBuffer[numBytes], RecordSize-numBytes, #0); + + bytesLeft := GetMemoSize; + // bytesLeft <> -1 -> memo size is known (FoxPro, dBase4) + // bytesLeft = -1 -> memo size unknown (dBase3) + if bytesLeft <> -1 then + begin + dataStart := 8; + DestStream.Size := bytesLeft; + while bytesLeft > 0 do + begin + // get number of bytes to be read + numBytes := bytesLeft; + // too much for this block? + if numBytes > RecordSize - dataStart then + numBytes := RecordSize - dataStart; + // read block to stream + DestStream.Write(FBuffer[dataStart], numBytes); + // numBytes done + dec(bytesLeft, numBytes); + // still need to read bytes? + if bytesLeft > 0 then + begin + // read next block + inc(BlockNo); + dataStart := 0; + ReadRecord(BlockNo, @FBuffer[0]); + end; + end; + end else begin + // dbase III memo + done := false; + repeat + // scan for EOF + endMemo := MemScan(FBuffer, $1A, RecordSize); + // EOF found? + if endMemo <> nil then + begin + // really EOF? + if (endMemo-FBuffer < RecordSize - 1) and ((endMemo[1] = #$1A) or (endMemo[1] = #0)) then + begin + // yes, EOF found + done := true; + numBytes := endMemo - FBuffer; + end else begin + // no, fake + numBytes := RecordSize; + end; + end else begin + numBytes := RecordSize; + end; + // write to stream + DestStream.Write(FBuffer[0], numBytes); +{ + for i := 0 to RecordSize-2 do + begin + if (FBuffer[i]=#$1A) and (FBuffer[i+1]=#$1A) then + begin + if i>0 then + DestStream.Write(FBuffer[0], i); + done := true; + break; + end; + end; +} + if not done then + begin +{ + DestStream.Write(FBuffer[0], 512); +} + lastc := FBuffer[RecordSize-1]; + inc(BlockNo); + if ReadRecord(BlockNo, @FBuffer[0]) > 0 then + begin + // check if immediate terminator at begin of block + done := (lastc = #$1A) and ((FBuffer[0] = #$1A) or (FBuffer[0] = #0)); + // if so, written one character too much + if done then + DestStream.Size := DestStream.Size - 1; + end else begin + // error while reading, stop + done := true; + end; + end; + until done; + end; +end; + +procedure TMemoFile.WriteMemo(var BlockNo: Integer; ReadSize: Integer; Src: TStream); +var + bytesBefore: Integer; + bytesAfter: Integer; + totsize: Integer; + readBytes: Integer; + append: Boolean; + tmpRecNo: Integer; +begin + // if no data to write, then don't create new block + if Src.Size = 0 then + begin + BlockNo := 0; + end else begin + if FDbfVersion >= xBaseIV then // dBase4 or FoxPro type + begin + bytesBefore := SizeOf(rBlockHdr); + bytesAfter := 0; + end else begin // dBase3 type + bytesBefore := 0; + bytesAfter := 2; + end; +// if ((bytesBefore + Src.Size + bytesAfter + PDbtHdr(Header).BlockLen-1) div PDbtHdr(Header).BlockLen) +// <= ((ReadSize + PDbtHdr(Header).BlockLen-1) div PDbtHdr(Header).BlockLen) then + if ((bytesBefore + Src.Size + bytesAfter + RecordSize-1) div RecordSize) + <= ((ReadSize + RecordSize-1) div RecordSize) then + begin + append := false; + end else begin + append := true; + // modifying header -> lock memo header + LockPage(0, true); + BlockNo := GetNextFreeBlock; + if BlockNo = 0 then + begin + SetNextFreeBlock(1); + BlockNo := 1; + end; + end; + tmpRecNo := BlockNo; + Src.Position := 0; + FillChar(FBuffer[0], RecordSize, ' '); + if bytesBefore=8 then + begin + totsize := Src.Size + bytesBefore + bytesAfter; + if FDbfVersion <> xFoxPro then + begin + PBlockHdr(FBuffer)^.MemoType := SwapIntLE($0008FFFF); + PBlockHdr(FBuffer)^.MemoSize := SwapIntLE(totsize); + end else begin + PBlockHdr(FBuffer)^.MemoType := SwapIntLE($01000000); + PBlockHdr(FBuffer)^.MemoSize := SwapIntBE(Src.Size); + end; + end; + repeat + // read bytes, don't overwrite header + readBytes := Src.Read(FBuffer[bytesBefore], RecordSize{PDbtHdr(Header).BlockLen}-bytesBefore); + // end of input data reached ? check if need to write block terminators + while (readBytes < RecordSize - bytesBefore) and (bytesAfter > 0) do + begin + FBuffer[readBytes] := #$1A; + Inc(readBytes); + Dec(bytesAfter); + end; + // have we read anything that is to be written? + if readBytes > 0 then + begin + // clear any unused space + FillChar(FBuffer[bytesBefore+readBytes], RecordSize-readBytes-bytesBefore, ' '); + // write to disk + WriteRecord(tmpRecNo, @FBuffer[0]); + Inc(tmpRecNo); + end else break; + // first block read, second block can start at beginning + bytesBefore := 0; + until false; + + if append then + begin + SetNextFreeBlock(tmpRecNo); + WriteHeader; + UnlockPage(0); + end; + end; +end; + +// ------------------------------------------------------------------ +// dBase specific helper routines +// ------------------------------------------------------------------ + +function TDbaseMemoFile.GetBlockLen: Integer; +begin + // Can you tell me why the header of dbase3 memo contains 1024 and is 512 ? + // answer: it is not a valid field in memo db3 header + if FDbfVersion = xBaseIII then + Result := 512 + else + Result := SwapWordLE(PDbtHdr(Header)^.BlockLen); +end; + +function TDbaseMemoFile.GetMemoSize: Integer; +begin + // dBase4 memofiles contain small 'header' + if PInteger(@FBuffer[0])^ = Integer(SwapIntLE($0008FFFF)) then + Result := SwapIntLE(PBlockHdr(FBuffer)^.MemoSize)-8 + else + Result := -1; +end; + +function TDbaseMemoFile.GetNextFreeBlock: Integer; +begin + Result := SwapIntLE(PDbtHdr(Header)^.NextBlock); +end; + +procedure TDbaseMemoFile.SetNextFreeBlock(BlockNo: Integer); +begin + PDbtHdr(Header)^.NextBlock := SwapIntLE(BlockNo); +end; + +procedure TDbaseMemoFile.SetBlockLen(BlockLen: Integer); +begin + PDbtHdr(Header)^.BlockLen := SwapWordLE(BlockLen); +end; + +// ------------------------------------------------------------------ +// FoxPro specific helper routines +// ------------------------------------------------------------------ + +function TFoxProMemoFile.GetBlockLen: Integer; +begin + Result := SwapWordBE(PFptHdr(Header)^.BlockLen); +end; + +function TFoxProMemoFile.GetMemoSize: Integer; +begin + Result := SwapIntBE(PBlockHdr(FBuffer)^.MemoSize); +end; + +function TFoxProMemoFile.GetNextFreeBlock: Integer; +begin + Result := SwapIntBE(PFptHdr(Header)^.NextBlock); +end; + +procedure TFoxProMemoFile.SetNextFreeBlock(BlockNo: Integer); +begin + PFptHdr(Header)^.NextBlock := SwapIntBE(dword(BlockNo)); +end; + +procedure TFoxProMemoFile.SetBlockLen(BlockLen: Integer); +begin + PFptHdr(Header)^.BlockLen := SwapWordBE(dword(BlockLen)); +end; + +// ------------------------------------------------------------------ +// NULL file (no file) specific helper routines +// ------------------------------------------------------------------ + +constructor TNullMemoFile.Create(ADbfFile: pointer); +begin + inherited; +end; + +procedure TNullMemoFile.OpenFile; +begin +end; + +procedure TNullMemoFile.CloseFile; +begin +end; + +procedure TNullMemoFile.SetHeaderOffset(NewValue: Integer); +begin + inherited SetHeaderOffset(0); +end; + +procedure TNullMemoFile.SetRecordSize(NewValue: Integer); +begin + inherited SetRecordSize(0); +end; + +procedure TNullMemoFile.SetHeaderSize(NewValue: Integer); +begin + inherited SetHeaderSize(0); +end; + +function TNullMemoFile.LockSection(const Offset, Length: Cardinal; const Wait: Boolean): Boolean; +begin + Result := true; +end; + +function TNullMemoFile.UnlockSection(const Offset, Length: Cardinal): Boolean; +begin + Result := true; +end; + +function TNullMemoFile.GetBlockLen: Integer; +begin + Result := 0; +end; + +function TNullMemoFile.GetMemoSize: Integer; +begin + Result := 0; +end; + +function TNullMemoFile.GetNextFreeBlock: Integer; +begin + Result := 0; +end; + +procedure TNullMemoFile.SetNextFreeBlock(BlockNo: Integer); +begin +end; + +procedure TNullMemoFile.SetBlockLen(BlockLen: Integer); +begin +end; + +function TNullMemoFile.ReadRecord(IntRecNum: Integer; Buffer: Pointer): Integer; +begin + Result := 0; +end; + +procedure TNullMemoFile.WriteRecord(IntRecNum: Integer; Buffer: Pointer); +begin +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_parser.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_parser.pas new file mode 100644 index 0000000..56e9483 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_parser.pas @@ -0,0 +1,604 @@ +unit dbf_parser; + +// Modified 2013 by Martin Schreiber + +interface + +{$I dbf_common.inc} + +uses + SysUtils, + classes,mclasses, +{$ifdef KYLIX} + Libc, +{$endif} +{$ifndef WINDOWS} + dbf_wtil, +{$endif} + mdb, + mdbf_prscore, + dbf_common, + dbf_fields, + mdbf_prsdef, + mdbf_prssupp; + +type + + TStringFieldMode = (smRaw, smAnsi, smAnsiTrim); + + TDbfParser = class(TCustomExpressionParser) + private + FDbfFile: Pointer; + FFieldVarList: TStringList; + FIsExpression: Boolean; // expression or simple field? + FFieldType: TExpressionType; + FCaseInsensitive: Boolean; + FStringFieldMode: TStringFieldMode; + FPartialMatch: boolean; + + protected + FCurrentExpression: string; + + procedure FillExpressList; override; + procedure HandleUnknownVariable(VarName: string); override; + function GetVariableInfo(VarName: string): TDbfFieldDef; + function CurrentExpression: string; override; + procedure ValidateExpression(AExpression: string); virtual; + function GetResultType: TExpressionType; override; + function GetResultLen: Integer; + + procedure SetCaseInsensitive(NewInsensitive: Boolean); + procedure SetStringFieldMode(NewMode: TStringFieldMode); + procedure SetPartialMatch(NewPartialMatch: boolean); + public + constructor Create(ADbfFile: Pointer); + destructor Destroy; override; + + procedure ClearExpressions; override; + + procedure ParseExpression(AExpression: string); virtual; + function ExtractFromBuffer(Buffer: TRecordBuffer): PChar; virtual; + + property DbfFile: Pointer read FDbfFile write FDbfFile; + property Expression: string read FCurrentExpression; + property ResultLen: Integer read GetResultLen; + + property CaseInsensitive: Boolean read FCaseInsensitive write SetCaseInsensitive; + property StringFieldMode: TStringFieldMode read FStringFieldMode write SetStringFieldMode; + property PartialMatch: boolean read FPartialMatch write SetPartialMatch; + end; + +implementation + +uses + mdbf, + dbf_dbffile, + dbf_str +{$ifdef WINDOWS} + ,Windows +{$endif} + ; + +type +// TFieldVar aids in retrieving field values from records +// in their proper type + + TFieldVar = class(TObject) + private + FFieldDef: TDbfFieldDef; + FDbfFile: TDbfFile; + FFieldName: string; + FExprWord: TExprWord; + protected + function GetFieldVal: Pointer; virtual; abstract; + function GetFieldType: TExpressionType; virtual; abstract; + procedure SetExprWord(NewExprWord: TExprWord); virtual; + + property ExprWord: TExprWord read FExprWord write SetExprWord; + public + constructor Create(UseFieldDef: TDbfFieldDef; ADbfFile: TDbfFile); + + procedure Refresh(Buffer: TRecordBuffer); virtual; abstract; + + property FieldVal: Pointer read GetFieldVal; + property FieldDef: TDbfFieldDef read FFieldDef; + property FieldType: TExpressionType read GetFieldType; + property DbfFile: TDbfFile read FDbfFile; + property FieldName: string read FFieldName; + end; + + TStringFieldVar = class(TFieldVar) + protected + FFieldVal: PChar; + FMode: TStringFieldMode; + + function GetFieldVal: Pointer; override; + function GetFieldType: TExpressionType; override; + procedure SetExprWord(NewExprWord: TExprWord); override; + procedure SetMode(NewMode: TStringFieldMode); + procedure UpdateExprWord; + public + destructor Destroy; override; + + procedure Refresh(Buffer: TRecordBuffer); override; + + property Mode: TStringFieldMode read FMode write SetMode; + end; + + TFloatFieldVar = class(TFieldVar) + private + FFieldVal: Double; + protected + function GetFieldVal: Pointer; override; + function GetFieldType: TExpressionType; override; + public + procedure Refresh(Buffer: TRecordBuffer); override; + end; + + TIntegerFieldVar = class(TFieldVar) + private + FFieldVal: Integer; + protected + function GetFieldVal: Pointer; override; + function GetFieldType: TExpressionType; override; + public + procedure Refresh(Buffer: TRecordBuffer); override; + end; + +{$ifdef SUPPORT_INT64} + TLargeIntFieldVar = class(TFieldVar) + private + FFieldVal: Int64; + protected + function GetFieldVal: Pointer; override; + function GetFieldType: TExpressionType; override; + public + procedure Refresh(Buffer: TRecordBuffer); override; + end; +{$endif} + + TDateTimeFieldVar = class(TFieldVar) + private + FFieldVal: TDateTimeRec; + protected + function GetFieldType: TExpressionType; override; + function GetFieldVal: Pointer; override; + public + procedure Refresh(Buffer: TRecordBuffer); override; + end; + + TBooleanFieldVar = class(TFieldVar) + private + FFieldVal: boolean; + protected + function GetFieldType: TExpressionType; override; + function GetFieldVal: Pointer; override; + public + procedure Refresh(Buffer: TRecordBuffer); override; + end; + +{ TFieldVar } + +constructor TFieldVar.Create(UseFieldDef: TDbfFieldDef; ADbfFile: TDbfFile); +begin + inherited Create; + + // store field + FFieldDef := UseFieldDef; + FDbfFile := ADbfFile; + FFieldName := UseFieldDef.FieldName; +end; + +procedure TFieldVar.SetExprWord(NewExprWord: TExprWord); +begin + FExprWord := NewExprWord; +end; + +{ TStringFieldVar } + +destructor TStringFieldVar.Destroy; +begin + if FMode <> smRaw then + FreeMem(FFieldVal); + + inherited; +end; + +function TStringFieldVar.GetFieldVal: Pointer; +begin + Result := @FFieldVal; +end; + +function TStringFieldVar.GetFieldType: TExpressionType; +begin + Result := etString; +end; + +procedure TStringFieldVar.Refresh(Buffer: TRecordBuffer); +var + Len: Integer; + Src: TRecordBuffer; +begin + Src := Buffer+FieldDef.Offset; + if FMode <> smRaw then + begin + // copy field data + Len := FieldDef.Size; + if FMode = smAnsiTrim then + while (Len >= 1) and (Src[Len-1] = TRecordbufferbasetype(' ')) do Dec(Len); + // translate to ANSI + Len := TranslateString(DbfFile.UseCodePage, GetACP, pansichar(Src), FFieldVal, Len); + FFieldVal[Len] := #0; + end else + FFieldVal := pansichar(Src); +end; + +procedure TStringFieldVar.SetExprWord(NewExprWord: TExprWord); +begin + inherited; + UpdateExprWord; +end; + +procedure TStringFieldVar.UpdateExprWord; +begin + if FMode <> smAnsiTrim then + FExprWord.FixedLen := FieldDef.Size + else + FExprWord.FixedLen := -1; +end; + +procedure TStringFieldVar.SetMode(NewMode: TStringFieldMode); +begin + if NewMode = FMode then exit; + FMode := NewMode; + if NewMode = smRaw then + begin + FreeMem(FFieldVal); + FFieldVal := nil; + end else + GetMem(FFieldVal, FieldDef.Size*3+1); + UpdateExprWord; +end; + +//--TFloatFieldVar----------------------------------------------------------- +function TFloatFieldVar.GetFieldVal: Pointer; +begin + Result := @FFieldVal; +end; + +function TFloatFieldVar.GetFieldType: TExpressionType; +begin + Result := etFloat; +end; + +procedure TFloatFieldVar.Refresh(Buffer: TRecordBuffer); +begin + // database width is default 64-bit double + if not FDbfFile.GetFieldDataFromDef(FieldDef, FieldDef.FieldType, Buffer, @FFieldVal, false) then + FFieldVal := 0.0; +end; + +//--TIntegerFieldVar---------------------------------------------------------- +function TIntegerFieldVar.GetFieldVal: Pointer; +begin + Result := @FFieldVal; +end; + +function TIntegerFieldVar.GetFieldType: TExpressionType; +begin + Result := etInteger; +end; + +procedure TIntegerFieldVar.Refresh(Buffer: TRecordBuffer); +begin + FFieldVal := 0; + FDbfFile.GetFieldDataFromDef(FieldDef, FieldDef.FieldType, Buffer, @FFieldVal, false); +end; + +{$ifdef SUPPORT_INT64} + +//--TLargeIntFieldVar---------------------------------------------------------- +function TLargeIntFieldVar.GetFieldVal: Pointer; +begin + Result := @FFieldVal; +end; + +function TLargeIntFieldVar.GetFieldType: TExpressionType; +begin + Result := etLargeInt; +end; + +procedure TLargeIntFieldVar.Refresh(Buffer: TRecordBuffer); +begin + if not FDbfFile.GetFieldDataFromDef(FieldDef, FieldDef.FieldType, Buffer, @FFieldVal, false) then + FFieldVal := 0; +end; + +{$endif} + +//--TDateTimeFieldVar--------------------------------------------------------- +function TDateTimeFieldVar.GetFieldVal: Pointer; +begin + Result := @FFieldVal; +end; + +function TDateTimeFieldVar.GetFieldType: TExpressionType; +begin + Result := etDateTime; +end; + +procedure TDateTimeFieldVar.Refresh(Buffer: TRecordBuffer); +begin + if not FDbfFile.GetFieldDataFromDef(FieldDef, ftDateTime, Buffer, @FFieldVal, false) then + FFieldVal.DateTime := 0.0; +end; + +//--TBooleanFieldVar--------------------------------------------------------- +function TBooleanFieldVar.GetFieldVal: Pointer; +begin + Result := @FFieldVal; +end; + +function TBooleanFieldVar.GetFieldType: TExpressionType; +begin + Result := etBoolean; +end; + +procedure TBooleanFieldVar.Refresh(Buffer: TRecordBuffer); +var + lFieldVal: word; +begin + if FDbfFile.GetFieldDataFromDef(FieldDef, ftBoolean, Buffer, @lFieldVal, false) then + FFieldVal := lFieldVal <> 0 + else + FFieldVal := false; +end; + +//--TDbfParser--------------------------------------------------------------- + +constructor TDbfParser.Create(ADbfFile: Pointer); +begin + FDbfFile := ADbfFile; + FFieldVarList := TStringList.Create; + FCaseInsensitive := true; + inherited Create; +end; + +destructor TDbfParser.Destroy; +begin + ClearExpressions; + inherited; + FreeAndNil(FFieldVarList); +end; + +function TDbfParser.GetResultType: TExpressionType; +begin + // if not a real expression, return type ourself + if FIsExpression then + Result := inherited GetResultType + else + Result := FFieldType; +end; + +function TDbfParser.GetResultLen: Integer; +begin + // set result len for fixed length expressions / fields + case ResultType of + etBoolean: Result := 1; + etInteger: Result := 4; + etFloat: Result := 8; + etDateTime: Result := 8; + etString: + begin + if not FIsExpression and (TStringFieldVar(FFieldVarList.Objects[0]).Mode <> smAnsiTrim) then + Result := TStringFieldVar(FFieldVarList.Objects[0]).FieldDef.Size + else + Result := -1; + end; + else + Result := -1; + end; +end; + +procedure TDbfParser.SetCaseInsensitive(NewInsensitive: Boolean); +begin + if FCaseInsensitive <> NewInsensitive then + begin + // clear and regenerate functions + FCaseInsensitive := NewInsensitive; + FillExpressList; + end; +end; + +procedure TDbfParser.SetPartialMatch(NewPartialMatch: boolean); +begin + if FPartialMatch <> NewPartialMatch then + begin + // refill function list + FPartialMatch := NewPartialMatch; + FillExpressList; + end; +end; + +procedure TDbfParser.SetStringFieldMode(NewMode: TStringFieldMode); +var + I: integer; +begin + if FStringFieldMode <> NewMode then + begin + // clear and regenerate functions, custom fields will be deleted too + FStringFieldMode := NewMode; + for I := 0 to FFieldVarList.Count - 1 do + if FFieldVarList.Objects[I] is TStringFieldVar then + TStringFieldVar(FFieldVarList.Objects[I]).Mode := NewMode; + end; +end; + +procedure TDbfParser.FillExpressList; +var + lExpression: string; +begin + lExpression := FCurrentExpression; + ClearExpressions; + FWordsList.FreeAll; + FWordsList.AddList(DbfWordsGeneralList, 0, DbfWordsGeneralList.Count - 1); + if FCaseInsensitive then + begin + FWordsList.AddList(DbfWordsInsensGeneralList, 0, DbfWordsInsensGeneralList.Count - 1); + if FPartialMatch then + begin + FWordsList.AddList(DbfWordsInsensPartialList, 0, DbfWordsInsensPartialList.Count - 1); + end else begin + FWordsList.AddList(DbfWordsInsensNoPartialList, 0, DbfWordsInsensNoPartialList.Count - 1); + end; + end else begin + FWordsList.AddList(DbfWordsSensGeneralList, 0, DbfWordsSensGeneralList.Count - 1); + if FPartialMatch then + begin + FWordsList.AddList(DbfWordsSensPartialList, 0, DbfWordsSensPartialList.Count - 1); + end else begin + FWordsList.AddList(DbfWordsSensNoPartialList, 0, DbfWordsSensNoPartialList.Count - 1); + end; + end; + if Length(lExpression) > 0 then + ParseExpression(lExpression); +end; + +function TDbfParser.GetVariableInfo(VarName: string): TDbfFieldDef; +begin + Result := TDbfFile(FDbfFile).GetFieldInfo(VarName); +end; + +procedure TDbfParser.HandleUnknownVariable(VarName: string); +var + FieldInfo: TDbfFieldDef; + TempFieldVar: TFieldVar; +begin + // is this variable a fieldname? + FieldInfo := GetVariableInfo(VarName); + if FieldInfo = nil then + raise EDbfError.CreateFmt(STRING_INDEX_BASED_ON_UNKNOWN_FIELD, [VarName]); + + // define field in parser + case FieldInfo.FieldType of + ftString: + begin + TempFieldVar := TStringFieldVar.Create(FieldInfo, TDbfFile(FDbfFile)); + TempFieldVar.ExprWord := DefineStringVariable(VarName, TempFieldVar.FieldVal); + TStringFieldVar(TempFieldVar).Mode := FStringFieldMode; + end; + ftBoolean: + begin + TempFieldVar := TBooleanFieldVar.Create(FieldInfo, TDbfFile(FDbfFile)); + TempFieldVar.ExprWord := DefineBooleanVariable(VarName, TempFieldVar.FieldVal); + end; + ftFloat: + begin + TempFieldVar := TFloatFieldVar.Create(FieldInfo, TDbfFile(FDbfFile)); + TempFieldVar.ExprWord := DefineFloatVariable(VarName, TempFieldVar.FieldVal); + end; + ftAutoInc, ftInteger, ftSmallInt: + begin + TempFieldVar := TIntegerFieldVar.Create(FieldInfo, TDbfFile(FDbfFile)); + TempFieldVar.ExprWord := DefineIntegerVariable(VarName, TempFieldVar.FieldVal); + end; +{$ifdef SUPPORT_INT64} + ftLargeInt: + begin + TempFieldVar := TLargeIntFieldVar.Create(FieldInfo, TDbfFile(FDbfFile)); + TempFieldVar.ExprWord := DefineLargeIntVariable(VarName, TempFieldVar.FieldVal); + end; +{$endif} + ftDate, ftDateTime: + begin + TempFieldVar := TDateTimeFieldVar.Create(FieldInfo, TDbfFile(FDbfFile)); + TempFieldVar.ExprWord := DefineDateTimeVariable(VarName, TempFieldVar.FieldVal); + end; + else + raise EDbfError.CreateFmt(STRING_INDEX_BASED_ON_INVALID_FIELD, [VarName]); + end; + + // add to our own list + FFieldVarList.AddObject(VarName, TempFieldVar); +end; + +function TDbfParser.CurrentExpression: string; +begin + Result := FCurrentExpression; +end; + +procedure TDbfParser.ClearExpressions; +var + I: Integer; +begin + inherited; + + // test if already freed + if FFieldVarList <> nil then + begin + // free field list + for I := 0 to FFieldVarList.Count - 1 do + begin + // replacing with nil = undefining variable + FWordsList.DoFree(TFieldVar(FFieldVarList.Objects[I]).FExprWord); + TFieldVar(FFieldVarList.Objects[I]).Free; + end; + FFieldVarList.Clear; + end; + + // clear expression + FCurrentExpression := EmptyStr; +end; + +procedure TDbfParser.ValidateExpression(AExpression: string); +begin +end; + +procedure TDbfParser.ParseExpression(AExpression: string); +begin + // clear any current expression + ClearExpressions; + + // is this a simple field or complex expression? + FIsExpression := GetVariableInfo(AExpression) = nil; + if FIsExpression then + begin + // parse requested + CompileExpression(AExpression); + end else begin + // simple field, create field variable for it + HandleUnknownVariable(AExpression); + FFieldType := TFieldVar(FFieldVarList.Objects[0]).FieldType; + end; + + ValidateExpression(AExpression); + + // if no errors, assign current expression + FCurrentExpression := AExpression; +end; + +function TDbfParser.ExtractFromBuffer(Buffer: TRecordBuffer): PChar; +var + I: Integer; +begin + // prepare all field variables + for I := 0 to FFieldVarList.Count - 1 do + TFieldVar(FFieldVarList.Objects[I]).Refresh(Buffer); + + // complex expression? + if FIsExpression then + begin + // execute expression + EvaluateCurrent; + Result := ExpResult; + end else begin + // simple field, get field result + Result := TFieldVar(FFieldVarList.Objects[0]).FieldVal; + // if string then dereference + if FFieldType = etString then + Result := PPChar(Result)^; + end; +end; + +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_pgcfile.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_pgcfile.pas new file mode 100644 index 0000000..01aa02a --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_pgcfile.pas @@ -0,0 +1,232 @@ +unit dbf_pgcfile; + +// paged, cached file + +interface + +{$I dbf_common.inc} + +{$ifdef USE_CACHE} + +uses + classes,mclasses + SysUtils, + dbf_common, + dbf_avl, + dbf_pgfile; + +type + + PPageInfo = ^TPageInfo; + TPageInfo = record + TimeStamp: Cardinal; + Modified: Boolean; + Data: Char; + end; + + TCachedFile = class(TPagedFile) + private + FPageTree: TAvlTree; + FUseTree: TAvlTree; + FTimeStamp: Cardinal; + FPageInfoSize: Integer; + FCacheSize: Integer; + FMaxPages: Cardinal; + + function GetTimeStamp: Cardinal; + procedure UpdateTimeStamp(RecNo: Integer; Data: PPageInfo); + procedure PageDeleted(Sender: TAvlTree; Data: PData); + procedure UpdateMaxPages; + function AddToCache(RecNo: Integer; Buffer: Pointer): PPageInfo; + protected + procedure SetRecordSize(NewValue: Integer); override; + procedure SetCacheSize(NewSize: Integer); + public + constructor Create; + destructor Destroy; override; + + procedure CloseFile; override; + procedure Flush; override; + + function ReadRecord(RecNo: Integer; Buffer: Pointer): Integer; override; + procedure WriteRecord(RecNo: Integer; Buffer: Pointer); override; + + property CacheSize: Integer read FCacheSize write SetCacheSize; + end; + +{$endif} + +implementation + +{$ifdef USE_CACHE} + +constructor TCachedFile.Create; +begin + inherited; + + FPageTree := TAvlTree.Create; + FPageTree.OnDelete := PageDeleted; + FUseTree := TAvlTree.Create; + FPageInfoSize := 0; + FTimeStamp := 0; + FCacheSize := 256 * 1024; +end; + +destructor TCachedFile.Destroy; +begin + Flush; + + FPageTree.Free; + FUseTree.Free; + FPageTree := nil; + FUseTree := nil; + + inherited; +end; + +procedure TCachedFile.Flush; +begin + if FPageTree <> nil then + begin + FPageTree.Clear; + FUseTree.Clear; + end; + FTimeStamp := 0; +end; + +procedure TCachedFile.CloseFile; +begin + // flush modified pages to disk + Flush; + + // now we can safely close + inherited; +end; + +procedure TCachedFile.SetRecordSize(NewValue: Integer); +begin + inherited; + + // first flush all pages, restart caching with new parameters + Flush; + + // calculate size of extra data of pagetree + FPageInfoSize := SizeOf(TPageInfo) - SizeOf(Char) + RecordSize; + UpdateMaxPages; +end; + +procedure TCachedFile.SetCacheSize(NewSize: Integer); +begin + if FCacheSize <> NewSize then + begin + FCacheSize := NewSize; + UpdateMaxPages; + end; +end; + +procedure TCachedFile.UpdateMaxPages; +begin + if RecordSize = 0 then + FMaxPages := 0 + else + FMaxPages := FCacheSize div RecordSize; +end; + +function TCachedFile.GetTimeStamp: Cardinal; +begin + Result := FTimeStamp; + Inc(FTimeStamp); +end; + +procedure TCachedFile.PageDeleted(Sender: TAvlTree; Data: PData); +begin + // data modified? write to disk + if PPageInfo(Data^.ExtraData)^.Modified then + inherited WriteRecord(Data^.ID, @PPageInfo(Data^.ExtraData)^.Data); + + // free cached page mem + FreeMem(Data^.ExtraData); +end; + +function TCachedFile.AddToCache(RecNo: Integer; Buffer: Pointer): PPageInfo; +var + oldData: PData; +begin + // make sure there is a free page in the cache + while FPageTree.Count >= FMaxPages do + begin + // no free space, find oldest page + oldData := FUseTree.Lowest; + // remove from cache + FPageTree.Delete(Integer(oldData^.ExtraData)); + FUseTree.Delete(oldData^.ID); + end; + // add to cache + GetMem(Result, FPageInfoSize); + Result^.TimeStamp := GetTimeStamp; + Result^.Modified := false; + Move(Buffer^, Result^.Data, RecordSize); + FPageTree.Insert(RecNo, Result); + FUseTree.Insert(Result^.TimeStamp, Pointer(RecNo)); +end; + +procedure TCachedFile.UpdateTimeStamp(RecNo: Integer; Data: PPageInfo); +begin + // update time used + FUseTree.Delete(Data^.TimeStamp); + Data^.TimeStamp := GetTimeStamp; + FUseTree.Insert(Data^.TimeStamp, Pointer(RecNo)); +end; + +function TCachedFile.ReadRecord(RecNo: Integer; Buffer: Pointer): Integer; +var + Data: PPageInfo; +begin + // only cache when we do not need locking + if NeedLocks then + begin Result := inherited ReadRecord(RecNo, Buffer) end else begin + // do we have this page in cache? + Data := PPageInfo(FPageTree.Find(RecNo)); + if Data <> nil then + begin + // copy from cache + Move(Data^.Data, Buffer^, RecordSize); + UpdateTimeStamp(RecNo, Data); + Result := RecordSize; + end else begin + // not yet in cache + Result := inherited ReadRecord(RecNo, Buffer); + // add + if Result > 0 then + AddToCache(RecNo, Buffer); + end; + end; +end; + +procedure TCachedFile.WriteRecord(RecNo: Integer; Buffer: Pointer); +var + Data: PPageInfo; +begin + // only cache when we do not need locking + if NeedLocks then + begin inherited end else begin + // do we have this page in cache? + Data := PPageInfo(FPageTree.Find(RecNo)); + if Data <> nil then + begin + // copy to cache + Move(Buffer^, Data^.Data, RecordSize); + UpdateTimeStamp(RecNo, Data); + end else begin + // add + Data := AddToCache(RecNo, Buffer); + // notify we've added a page + UpdateCachedSize(CalcPageOffset(RecNo+PagesPerRecord)); + end; + Data^.Modified := true; + end; +end; + +{$endif} // USE_CACHE + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_pgfile.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_pgfile.pas new file mode 100644 index 0000000..fa0c480 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_pgfile.pas @@ -0,0 +1,927 @@ +unit dbf_pgfile; + +interface + +{$I dbf_common.inc} + +uses + classes,mclasses, + SysUtils, + dbf_common; + +//const +// MaxHeaders = 256; + +type + EPagedFile = Exception; + + TPagedFileMode = (pfNone, pfMemoryCreate, pfMemoryOpen, pfExclusiveCreate, + pfExclusiveOpen, pfReadWriteCreate, pfReadWriteOpen, pfReadOnly); + + // access levels: + // + // - memory create + // - exclusive create/open + // - read/write create/open + // - readonly open + // + // - memory -*-share: N/A -*-locks: disabled -*-indexes: read/write + // - exclusive_create -*-share: deny write -*-locks: disabled -*-indexes: read/write + // - exclusive_open -*-share: deny write -*-locks: disabled -*-indexes: read/write + // - readwrite_create -*-share: deny none -*-locks: enabled -*-indexes: read/write + // - readwrite_open -*-share: deny none -*-locks: enabled -*-indexes: read/write + // - readonly -*-share: deny none -*-locks: disabled -*-indexes: readonly + + TPagedFile = class(TObject) + protected + FStream: TStream; + FHeaderOffset: Integer; + FHeaderSize: Integer; + FRecordSize: Integer; + FPageSize: Integer; { need for MDX, where recordsize <> pagesize } + FRecordCount: Integer; { actually FPageCount, but we want to keep existing code } + FPagesPerRecord: Integer; + FCachedSize: Integer; + FCachedRecordCount: Integer; + FHeader: PChar; + FActive: Boolean; + FNeedRecalc: Boolean; + FHeaderModified: Boolean; + FPageOffsetByHeader: Boolean; { do pages start after header or just at BOF? } + FMode: TPagedFileMode; + FTempMode: TPagedFileMode; + FUserMode: TPagedFileMode; + FAutoCreate: Boolean; + FNeedLocks: Boolean; + FVirtualLocks: Boolean; + FFileLocked: Boolean; + FFileName: string; + FBufferPtr: Pointer; + FBufferAhead: Boolean; + FBufferPage: Integer; + FBufferOffset: Integer; + FBufferSize: Integer; + FBufferReadSize: Integer; + FBufferMaxSize: Integer; + FBufferModified: Boolean; + FWriteError: Boolean; + protected + procedure SetHeaderOffset(NewValue: Integer); virtual; + procedure SetRecordSize(NewValue: Integer); virtual; + procedure SetHeaderSize(NewValue: Integer); virtual; + procedure SetPageSize(NewValue: Integer); + procedure SetPageOffsetByHeader(NewValue: Boolean); virtual; + procedure SetRecordCount(NewValue: Integer); + procedure SetBufferAhead(NewValue: Boolean); + procedure SetFileName(NewName: string); + procedure SetStream(NewStream: TStream); + function LockSection(const Offset, Length: Cardinal; const Wait: Boolean): Boolean; virtual; + function UnlockSection(const Offset, Length: Cardinal): Boolean; virtual; + procedure UpdateBufferSize; + procedure RecalcPagesPerRecord; + procedure ReadHeader; + procedure FlushHeader; + procedure FlushBuffer; + function ReadChar: Byte; + procedure WriteChar(c: Byte); + procedure CheckCachedSize(const APosition: Integer); + procedure SynchronizeBuffer(IntRecNum: Integer); + function Read(Buffer: Pointer; ASize: Integer): Integer; + function ReadBlock(const BlockPtr: Pointer; const ASize, APosition: Integer): Integer; + function SingleReadRecord(IntRecNum: Integer; Buffer: Pointer): Integer; + procedure WriteBlock(const BlockPtr: Pointer; const ASize, APosition: Integer); + procedure SingleWriteRecord(IntRecNum: Integer; Buffer: Pointer); + function GetRecordCount: Integer; + procedure UpdateCachedSize(CurrPos: Integer); + + property VirtualLocks: Boolean read FVirtualLocks write FVirtualLocks; + public + constructor Create; + destructor Destroy; override; + + procedure CloseFile; virtual; + procedure OpenFile; virtual; + procedure DeleteFile; + procedure TryExclusive; virtual; + procedure EndExclusive; virtual; + procedure CheckExclusiveAccess; + procedure DisableForceCreate; + function CalcPageOffset(const PageNo: Integer): Integer; + function IsRecordPresent(IntRecNum: Integer): boolean; + function ReadRecord(IntRecNum: Integer; Buffer: Pointer): Integer; virtual; + procedure WriteRecord(IntRecNum: Integer; Buffer: Pointer); virtual; + procedure WriteHeader; virtual; + function FileCreated: Boolean; + function IsSharedAccess: Boolean; + procedure ResetError; + + function LockPage(const PageNo: Integer; const Wait: Boolean): Boolean; + function LockAllPages(const Wait: Boolean): Boolean; + procedure UnlockPage(const PageNo: Integer); + procedure UnlockAllPages; + + procedure Flush; virtual; + + property Active: Boolean read FActive; + property AutoCreate: Boolean read FAutoCreate write FAutoCreate; // only write when closed! + property Mode: TPagedFileMode read FMode write FMode; // only write when closed! + property TempMode: TPagedFileMode read FTempMode; + property NeedLocks: Boolean read FNeedLocks; + property HeaderOffset: Integer read FHeaderOffset write SetHeaderOffset; + property HeaderSize: Integer read FHeaderSize write SetHeaderSize; + property RecordSize: Integer read FRecordSize write SetRecordSize; + property PageSize: Integer read FPageSize write SetPageSize; + property PagesPerRecord: Integer read FPagesPerRecord; + property RecordCount: Integer read GetRecordCount write SetRecordCount; + property CachedRecordCount: Integer read FCachedRecordCount; + property PageOffsetByHeader: Boolean read FPageOffsetbyHeader write SetPageOffsetByHeader; + property FileLocked: Boolean read FFileLocked; + property Header: PChar read FHeader; + property FileName: string read FFileName write SetFileName; + property Stream: TStream read FStream write SetStream; + property BufferAhead: Boolean read FBufferAhead write SetBufferAhead; + property WriteError: Boolean read FWriteError; + end; + +implementation + +uses +{$ifdef WINDOWS} + Windows, +{$else} +{$ifdef KYLIX} + Libc, +{$endif} + Types, dbf_wtil, +{$endif} + dbf_str; + +//==================================================================== +// TPagedFile +//==================================================================== +constructor TPagedFile.Create; +begin + FFileName := EmptyStr; + FHeaderOffset := 0; + FHeaderSize := 0; + FRecordSize := 0; + FRecordCount := 0; + FPageSize := 0; + FPagesPerRecord := 0; + FActive := false; + FHeaderModified := false; + FPageOffsetByHeader := true; + FNeedLocks := false; + FMode := pfReadOnly; + FTempMode := pfNone; + FAutoCreate := false; + FVirtualLocks := true; + FFileLocked := false; + FHeader := nil; + FBufferPtr := nil; + FBufferAhead := false; + FBufferModified := false; + FBufferSize := 0; + FBufferMaxSize := 0; + FBufferOffset := 0; + FWriteError := false; + + inherited; +end; + +destructor TPagedFile.Destroy; +begin + // close physical file + if FFileLocked then UnlockAllPages; + CloseFile; + FFileLocked := false; + + // free mem + if FHeader <> nil then + FreeMem(FHeader); + + inherited; +end; + +procedure TPagedFile.OpenFile; +var + fileOpenMode: Word; +begin + if FActive then exit; + + // store user specified mode + FUserMode := FMode; + if not (FMode in [pfMemoryCreate, pfMemoryOpen]) then + begin + // test if file exists + if not FileExists(FFileName) then + begin + // if auto-creating, adjust mode + if FAutoCreate then case FMode of + pfExclusiveOpen: FMode := pfExclusiveCreate; + pfReadWriteOpen, pfReadOnly: FMode := pfReadWriteCreate; + end; + // it seems the VCL cannot share a file that is created? + // create file first, then open it in requested mode + // filecreated means 'to be created' in this context ;-) + if FileCreated then + FileClose(FileCreate(FFileName)) + else + raise EPagedFile.CreateFmt(STRING_FILE_NOT_FOUND,[FFileName]); + end; + // specify open mode + case FMode of + pfExclusiveCreate: fileOpenMode := fmOpenReadWrite or fmShareDenyWrite; + pfExclusiveOpen: fileOpenMode := fmOpenReadWrite or fmShareDenyWrite; + pfReadWriteCreate: fileOpenMode := fmOpenReadWrite or fmShareDenyNone; + pfReadWriteOpen: fileOpenMode := fmOpenReadWrite or fmShareDenyNone; + else // => readonly + fileOpenMode := fmOpenRead or fmShareDenyNone; + end; + // open file + FStream := TFileStream.Create(FFileName, fileOpenMode); + // if creating, then empty file + if FileCreated then + FStream.Size := 0; + end else begin + if FStream = nil then + begin + FMode := pfMemoryCreate; + FStream := TMemoryStream.Create; + end; + end; + // init size var + FCachedSize := Stream.Size; + // update whether we need locking +{$ifdef _DEBUG} + FNeedLocks := true; +{$else} + FNeedLocks := IsSharedAccess; +{$endif} + FActive := true; + // allocate memory for bufferahead + UpdateBufferSize; +end; + +procedure TPagedFile.CloseFile; +begin + if FActive then + begin + FlushHeader; + FlushBuffer; + // don't free the user's stream + if not (FMode in [pfMemoryOpen, pfMemoryCreate]) then + FreeAndNil(FStream); + // free bufferahead buffer + FreeMemAndNil(FBufferPtr); + + // mode possibly overridden in case of auto-created file + FMode := FUserMode; + FActive := false; + FCachedRecordCount := 0; + end; +end; + +procedure TPagedFile.DeleteFile; +begin + // opened -> we can not delete + if not FActive then + SysUtils.DeleteFile(FileName); +end; + +function TPagedFile.FileCreated: Boolean; +const + CreationModes: array [pfNone..pfReadOnly] of Boolean = + (false, true, false, true, false, true, false, false); +// node, memcr, memop, excr, exopn, rwcr, rwopn, rdonly +begin + Result := CreationModes[FMode]; +end; + +function TPagedFile.IsSharedAccess: Boolean; +const + SharedAccessModes: array [pfNone..pfReadOnly] of Boolean = + (false, false, false, false, false, true, true, true); +// node, memcr, memop, excr, exopn, rwcr, rwopn, rdonly +begin + Result := SharedAccessModes[FMode]; +end; + +procedure TPagedFile.CheckExclusiveAccess; +begin + // in-memory => exclusive access! + if IsSharedAccess then + raise EDbfError.Create(STRING_NEED_EXCLUSIVE_ACCESS); +end; + +function TPagedFile.CalcPageOffset(const PageNo: Integer): Integer; +begin + if not FPageOffsetByHeader then + Result := FPageSize * PageNo + else if PageNo = 0 then + Result := 0 + else + Result := FHeaderOffset + FHeaderSize + (FPageSize * (PageNo - 1)) +end; + +procedure TPagedFile.CheckCachedSize(const APosition: Integer); +begin + // file expanded? + if APosition > FCachedSize then + begin + FCachedSize := APosition; + FNeedRecalc := true; + end; +end; + +function TPagedFile.Read(Buffer: Pointer; ASize: Integer): Integer; +begin + // if we cannot read due to a lock, then wait a bit + repeat + Result := FStream.Read(Buffer^, ASize); + if Result = 0 then + begin + // translation to linux??? + if GetLastError = ERROR_LOCK_VIOLATION then + begin + // wait a bit until block becomes available + Sleep(1); + end else begin + // return empty block + exit; + end; + end else + exit; + until false; +end; + +procedure TPagedFile.UpdateCachedSize(CurrPos: Integer); +begin + // have we added a record? + if CurrPos > FCachedSize then + begin + // update cached size, always at end + repeat + Inc(FCachedSize, FRecordSize); + Inc(FRecordCount, PagesPerRecord); + until FCachedSize >= CurrPos; + end; +end; + +procedure TPagedFile.FlushBuffer; +begin + if FBufferAhead and FBufferModified then + begin + WriteBlock(FBufferPtr, FBufferSize, FBufferOffset); + FBufferModified := false; + end; +end; + +function TPagedFile.SingleReadRecord(IntRecNum: Integer; Buffer: Pointer): Integer; +begin + Result := ReadBlock(Buffer, RecordSize, CalcPageOffset(IntRecNum)); +end; + +procedure TPagedFile.SingleWriteRecord(IntRecNum: Integer; Buffer: Pointer); +begin + WriteBlock(Buffer, RecordSize, CalcPageOffset(IntRecNum)); +end; + +procedure TPagedFile.SynchronizeBuffer(IntRecNum: Integer); +begin + // record outside buffer, flush previous buffer + FlushBuffer; + // read new set of records + FBufferPage := IntRecNum; + FBufferOffset := CalcPageOffset(IntRecNum); + if FBufferOffset + FBufferMaxSize > FCachedSize then + FBufferReadSize := FCachedSize - FBufferOffset + else + FBufferReadSize := FBufferMaxSize; + FBufferSize := FBufferReadSize; + FBufferReadSize := ReadBlock(FBufferPtr, FBufferReadSize, FBufferOffset); +end; + +function TPagedFile.IsRecordPresent(IntRecNum: Integer): boolean; +begin + // if in shared mode, recordcount can only increase, check if recordno + // in range for cached recordcount + if not IsSharedAccess or (IntRecNum > FCachedRecordCount) then + FCachedRecordCount := RecordCount; + Result := (0 <= IntRecNum) and (IntRecNum <= FCachedRecordCount); +end; + +function TPagedFile.ReadRecord(IntRecNum: Integer; Buffer: Pointer): Integer; +var + Offset: Integer; +begin + if FBufferAhead then + begin + Offset := (IntRecNum - FBufferPage) * PageSize; + if (FBufferPage <> -1) and (FBufferPage <= IntRecNum) and + (Offset+RecordSize <= FBufferReadSize) then + begin + // have record in buffer, nothing to do here + end else begin + // need to update buffer + SynchronizeBuffer(IntRecNum); + // check if enough bytes read + if RecordSize > FBufferReadSize then + begin + Result := 0; + exit; + end; + // reset offset into buffer + Offset := 0; + end; + // now we have this record in buffer + Move(PChar(FBufferPtr)[Offset], Buffer^, RecordSize); + // successful + Result := RecordSize; + end else begin + // no buffering + Result := SingleReadRecord(IntRecNum, Buffer); + end; +end; + +procedure TPagedFile.WriteRecord(IntRecNum: Integer; Buffer: Pointer); +var + RecEnd: Integer; +begin + if FBufferAhead then + begin + RecEnd := (IntRecNum - FBufferPage + PagesPerRecord) * PageSize; + if (FBufferPage <> -1) and (FBufferPage <= IntRecNum) and + (RecEnd <= FBufferMaxSize) then + begin + // extend buffer? + if RecEnd > FBufferSize then + FBufferSize := RecEnd; + end else begin + // record outside buffer, need to synchronize first + SynchronizeBuffer(IntRecNum); + RecEnd := PagesPerRecord * PageSize; + end; + // we can write this record to buffer + Move(Buffer^, PChar(FBufferPtr)[RecEnd-RecordSize], RecordSize); + FBufferModified := true; + // update cached size + UpdateCachedSize(FBufferOffset+RecEnd); + end else begin + // no buffering + SingleWriteRecord(IntRecNum, Buffer); + // update cached size + UpdateCachedSize(FStream.Position); + end; +end; + +procedure TPagedFile.SetBufferAhead(NewValue: Boolean); +begin + if FBufferAhead <> NewValue then + begin + FlushBuffer; + FBufferAhead := NewValue; + UpdateBufferSize; + end; +end; + +procedure TPagedFile.SetStream(NewStream: TStream); +begin + if not FActive then + FStream := NewStream; +end; + +procedure TPagedFile.SetFileName(NewName: string); +begin + if not FActive then + FFileName := NewName; +end; + +procedure TPagedFile.UpdateBufferSize; +begin + if FBufferAhead then + begin + FBufferMaxSize := 65536; + if RecordSize <> 0 then + Dec(FBufferMaxSize, FBufferMaxSize mod PageSize); + end else begin + FBufferMaxSize := 0; + end; + + if FBufferPtr <> nil then + FreeMem(FBufferPtr); + if FBufferAhead and (FBufferMaxSize <> 0) then + GetMem(FBufferPtr, FBufferMaxSize) + else + FBufferPtr := nil; + FBufferPage := -1; + FBufferOffset := -1; + FBufferModified := false; +end; + +procedure TPagedFile.WriteHeader; +begin + FHeaderModified := true; + if FNeedLocks then + FlushHeader; +end; + +procedure TPagedFile.FlushHeader; +begin + if FHeaderModified then + begin + FStream.Position := FHeaderOffset; + FWriteError := (FStream.Write(FHeader^, FHeaderSize) = 0) or FWriteError; + // test if written new header + if FStream.Position > FCachedSize then + begin + // new header -> record count unknown + FCachedSize := FStream.Position; + FNeedRecalc := true; + end; + FHeaderModified := false; + end; +end; + +procedure TPagedFile.ReadHeader; + { assumes header is large enough } +var + size: Integer; +begin + // save changes before reading new header + FlushHeader; + // check if header length zero + if FHeaderSize <> 0 then + begin + // get size left in file for header + size := FStream.Size - FHeaderOffset; + // header start before EOF? + if size >= 0 then + begin + // go to header start + FStream.Position := FHeaderOffset; + // whole header in file? + if size >= FHeaderSize then + begin + // read header, nothing to be cleared + Read(FHeader, FHeaderSize); + size := FHeaderSize; + end else begin + // read what we can, clear rest + Read(FHeader, size); + end; + end else begin + // header start before EOF, clear header + size := 0; + end; + FillChar(FHeader[size], FHeaderSize-size, 0); + end; +end; + +procedure TPagedFile.TryExclusive; +const NewTempMode: array[pfReadWriteCreate..pfReadOnly] of TPagedFileMode = + (pfReadWriteOpen, pfReadWriteOpen, pfReadOnly); +begin + // already in temporary exclusive mode? + if (FTempMode = pfNone) and IsSharedAccess then + begin + // save temporary mode, if now creating, then reopen non-create + FTempMode := NewTempMode[FMode]; + // try exclusive mode + CloseFile; + FMode := pfExclusiveOpen; + try + OpenFile; + except + on EFOpenError do + begin + // we failed, reopen normally + EndExclusive; + end; + end; + end; +end; + +procedure TPagedFile.EndExclusive; +begin + // are we in temporary file mode? + if FTempMode <> pfNone then + begin + CloseFile; + FMode := FTempMode; + FTempMode := pfNone; + OpenFile; + end; +end; + +procedure TPagedFile.DisableForceCreate; +begin + case FMode of + pfExclusiveCreate: FMode := pfExclusiveOpen; + pfReadWriteCreate: FMode := pfReadWriteOpen; + end; +end; + +procedure TPagedFile.SetHeaderOffset(NewValue: Integer); +// +// *) assumes is called right before SetHeaderSize +// +begin + if FHeaderOffset <> NewValue then + begin + FlushHeader; + FHeaderOffset := NewValue; + end; +end; + +procedure TPagedFile.SetHeaderSize(NewValue: Integer); +begin + if FHeaderSize <> NewValue then + begin + FlushHeader; + if (FHeader <> nil) and (NewValue <> 0) then + FreeMem(FHeader); + FHeaderSize := NewValue; + if FHeaderSize <> 0 then + GetMem(FHeader, FHeaderSize); + FNeedRecalc := true; + ReadHeader; + end; +end; + +procedure TPagedFile.SetRecordSize(NewValue: Integer); +begin + if FRecordSize <> NewValue then + begin + FRecordSize := NewValue; + FPageSize := NewValue; + FNeedRecalc := true; + RecalcPagesPerRecord; + end; +end; + +procedure TPagedFile.SetPageSize(NewValue: Integer); +begin + if FPageSize <> NewValue then + begin + FPageSize := NewValue; + FNeedRecalc := true; + RecalcPagesPerRecord; + UpdateBufferSize; + end; +end; + +procedure TPagedFile.RecalcPagesPerRecord; +begin + if FPageSize = 0 then + FPagesPerRecord := 0 + else + FPagesPerRecord := FRecordSize div FPageSize; +end; + +function TPagedFile.GetRecordCount: Integer; +var + currSize: Integer; +begin + // file size changed? + if FNeedLocks then + begin + currSize := FStream.Size; + if currSize <> FCachedSize then + begin + FCachedSize := currSize; + FNeedRecalc := true; + end; + end; + + // try to optimize speed + if FNeedRecalc then + begin + // no file? test flags + if (FPageSize = 0) or not FActive then + FRecordCount := 0 + else + if FPageOffsetByHeader then + FRecordCount := (FCachedSize - FHeaderSize - FHeaderOffset) div FPageSize + else + FRecordCount := FCachedSize div FPageSize; + if FRecordCount < 0 then + FRecordCount := 0; + + // count updated + FNeedRecalc := false; + end; + Result := FRecordCount; +end; + +procedure TPagedFile.SetRecordCount(NewValue: Integer); +begin + if RecordCount <> NewValue then + begin + if FPageOffsetByHeader then + FCachedSize := FHeaderSize + FHeaderOffset + FPageSize * NewValue + else + FCachedSize := FPageSize * NewValue; +// FCachedSize := CalcPageOffset(NewValue); + FRecordCount := NewValue; + FStream.Size := FCachedSize; + end; +end; + +procedure TPagedFile.SetPageOffsetByHeader(NewValue: Boolean); +begin + if FPageOffsetByHeader <> NewValue then + begin + FPageOffsetByHeader := NewValue; + FNeedRecalc := true; + end; +end; + +procedure TPagedFile.WriteChar(c: Byte); +begin + FWriteError := (FStream.Write(c, 1) = 0) or FWriteError; +end; + +function TPagedFile.ReadChar: Byte; +begin + Read(@Result, 1); +end; + +procedure TPagedFile.Flush; +begin +end; + +function TPagedFile.ReadBlock(const BlockPtr: Pointer; const ASize, APosition: Integer): Integer; +begin + FStream.Position := APosition; + CheckCachedSize(APosition); + Result := Read(BlockPtr, ASize); +end; + +procedure TPagedFile.WriteBlock(const BlockPtr: Pointer; const ASize, APosition: Integer); + // assumes a lock is held if necessary prior to calling this function +begin + FStream.Position := APosition; + CheckCachedSize(APosition); + FWriteError := (FStream.Write(BlockPtr^, ASize) = 0) or FWriteError; +end; + +procedure TPagedFile.ResetError; +begin + FWriteError := false; +end; + +// BDE compatible lock offset found! +const +{$ifdef WINDOWS} + LockOffset = $EFFFFFFE; // BDE compatible + FileLockSize = 2; +{$else} + LockOffset = $7FFFFFFF; + FileLockSize = 1; +{$endif} + +// dBase supports maximum of a billion records + LockStart = LockOffset - 1000000000; + +function TPagedFile.LockSection(const Offset, Length: Cardinal; const Wait: Boolean): Boolean; +{$ifndef wince} + // assumes FNeedLock = true +var + Failed: Boolean; +{$endif wince} +begin +{$ifdef wince} + Result := True; +{$else} + // FNeedLocks => FStream is of type TFileStream + Failed := false; + repeat + Result := LockFile(TFileStream(FStream).Handle, Offset, 0, Length, 0); + // test if lock violation, then wait a bit and try again + if not Result and Wait then + begin + if (GetLastError = ERROR_LOCK_VIOLATION) then + Sleep(10) + else + Failed := true; + end; + until Result or not Wait or Failed; +{$endif wince} +end; + +function TPagedFile.UnlockSection(const Offset, Length: Cardinal): Boolean; +begin +{$ifdef wince} + Result := True; +{$else} + Result := UnlockFile(TFileStream(FStream).Handle, Offset, 0, Length, 0); +{$endif wince} +end; + +function TPagedFile.LockAllPages(const Wait: Boolean): Boolean; +var + Offset: Cardinal; + Length: Cardinal; +begin + // do we need locking? + if FNeedLocks and not FFileLocked then + begin + if FVirtualLocks then + begin +{$ifdef SUPPORT_UINT32_CARDINAL} + Offset := LockStart; + Length := LockOffset - LockStart + FileLockSize; +{$else} + // delphi 3 has strange types: + // cardinal 0..2 GIG ?? does it produce correct code? + Offset := Cardinal(LockStart); + Length := Cardinal(LockOffset) - Cardinal(LockStart) + FileLockSize; +{$endif} + end else begin + Offset := 0; + Length := $7FFFFFFF; + end; + // lock requested section + Result := LockSection(Offset, Length, Wait); + FFileLocked := Result; + end else + Result := true; +end; + +procedure TPagedFile.UnlockAllPages; +var + Offset: Cardinal; + Length: Cardinal; +begin + // do we need locking? + if FNeedLocks and FFileLocked then + begin + if FVirtualLocks then + begin +{$ifdef SUPPORT_UINT32_CARDINAL} + Offset := LockStart; + Length := LockOffset - LockStart + FileLockSize; +{$else} + // delphi 3 has strange types: + // cardinal 0..2 GIG ?? does it produce correct code? + Offset := Cardinal(LockStart); + Length := Cardinal(LockOffset) - Cardinal(LockStart) + FileLockSize; +{$endif} + end else begin + Offset := 0; + Length := $7FFFFFFF; + end; + // unlock requested section + // FNeedLocks => FStream is of type TFileStream + FFileLocked := not UnlockSection(Offset, Length); + end; +end; + +function TPagedFile.LockPage(const PageNo: Integer; const Wait: Boolean): Boolean; +var + Offset: Cardinal; + Length: Cardinal; +begin + // do we need locking? + if FNeedLocks and not FFileLocked then + begin + if FVirtualLocks then + begin + Offset := LockOffset - Cardinal(PageNo); + Length := 1; + end else begin + Offset := CalcPageOffset(PageNo); + Length := RecordSize; + end; + // lock requested section + Result := LockSection(Offset, Length, Wait); + end else + Result := true; +end; + +procedure TPagedFile.UnlockPage(const PageNo: Integer); +var + Offset: Cardinal; + Length: Cardinal; +begin + // do we need locking? + if FNeedLocks and not FFileLocked then + begin + // calc offset + length + if FVirtualLocks then + begin + Offset := LockOffset - Cardinal(PageNo); + Length := 1; + end else begin + Offset := CalcPageOffset(PageNo); + Length := RecordSize; + end; + // unlock requested section + // FNeedLocks => FStream is of type TFileStream + UnlockSection(Offset, Length); + end; +end; + +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_reg.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_reg.pas new file mode 100644 index 0000000..f4d6e0a --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_reg.pas @@ -0,0 +1,366 @@ +unit dbf_reg; + +{=============================================================================== +|| TDbf Component || http://tdbf.sf.net || +===============================================================================} +(* + tDBF is supplied "AS IS". The author disclaims all warranties, + expressed or implied, including, without limitation, the warranties of + merchantability and or fitness for any purpose. The author assumes no + liability for damages, direct or consequential, which may result from the + use of TDBF. + + TDbf is licensed under the LGPL (lesser general public license). + + You are allowed to use this component in any project free of charge. + You are + - NOT allowed to claim that you have created this component. You are + - NOT allowed to copy this component's code into your own component and + claim that the code is your idea. + +*) + +interface + +{$I dbf_common.inc} + +procedure Register; + +implementation + +{$ifndef FPC} +{$R dbf.dcr} +{$endif} + +uses + SysUtils, + classes,mclasses, +{$ifdef KYLIX} + QGraphics, + QControls, + QForms, + QDialogs, +{$else} + Controls, + Forms, + Dialogs, +{$endif} + dbf, + dbf_dbffile, + dbf_idxfile, + dbf_fields, + dbf_common, + dbf_str +{$ifndef FPC} + ,ExptIntf +{$endif} +{$ifdef DELPHI_6} + ,DesignIntf,DesignEditors +{$else} +{$ifndef FPC} + ,DsgnIntf +{$else} + ,PropEdits + ,LazarusPackageIntf + ,LResources + {,ComponentEditors} +{$endif} +{$endif} + ; + +//========================================================== +//============ DESIGNONLY ================================== +//========================================================== +(* +//========================================================== +//============ TFilePathProperty +//========================================================== +type + TFilePathProperty = class(TStringProperty) + public + function GetValue: string; override; + end; + +function TFilePathProperty.GetValue: string; +begin + Result := inherited GetValue; + if Result = EmptyStr then + begin + SetValue(ExtractFilePath(ToolServices.GetProjectName)); + Result := inherited GetValue; + end; +end; +*) + +//========================================================== +//============ TTableNameProperty +//========================================================== +type + TTableNameProperty = class(TStringProperty) + public + procedure Edit; override; + function GetAttributes: TPropertyAttributes; override; + end; + +procedure TTableNameProperty.Edit; {override;} +var + FileOpen: TOpenDialog; + Dbf: TDbf; +begin + FileOpen := TOpenDialog.Create(Application); + try + with fileopen do begin + Dbf := GetComponent(0) as TDbf; +{$ifndef FPC} + if Dbf.FilePath = EmptyStr then + FileOpen.InitialDir := ExtractFilePath(ToolServices.GetProjectName) + else +{$endif} + FileOpen.InitialDir := Dbf.AbsolutePath; + Filename := GetValue; + Filter := 'Dbf table|*.dbf'; + if Execute then begin + SetValue(Filename); + end; + end; + finally + Fileopen.free; + end; +end; + +function TTableNameProperty.GetAttributes: TPropertyAttributes; {override;} +begin + Result := [paDialog, paRevertable]; +end; + +//========================================================== +//============ TIndexFileNameProperty +//========================================================== + +type + TIndexFileNameProperty = class(TStringProperty) + public + procedure Edit; override; + function GetAttributes: TPropertyAttributes; override; + end; + +procedure TIndexFileNameProperty.Edit; {override;} +var + FileOpen: TOpenDialog; + IndexDef: TDbfIndexDef; + Indexes: TDbfIndexDefs; + Dbf: TDbf; +begin + FileOpen := TOpenDialog.Create(Application); + try + with fileopen do begin + IndexDef := GetComponent(0) as TDbfIndexDef; + Indexes := TDbfIndexDefs(IndexDef.Collection); + Dbf := TDbf(Indexes.FOwner); + FileOpen.InitialDir := Dbf.AbsolutePath; + Filename := GetValue; + Filter := 'Simple index (ndx)|*.ndx'{|Multiple index (mdx)|*.mdx'}; + if Execute then begin + SetValue(ExtractFileName(Filename)); + end; + end; + finally + Fileopen.free; + end; +end; + +function TIndexFileNameProperty.GetAttributes: TPropertyAttributes; {override;} +begin + Result := [paDialog, paRevertable]; +end; + +//========================================================== +//============ TSortFieldProperty +//========================================================== + +type + TSortFieldProperty = class(TStringProperty) + public + function GetAttributes: TPropertyAttributes; override; + procedure GetValues(Proc: TGetStrProc); override; + end; + + +function TSortFieldProperty.GetAttributes: TPropertyAttributes; {override;} +begin + Result := [paValueList, paSortList, paRevertable]; +end; + +procedure TSortFieldProperty.GetValues(Proc: TGetStrProc); +var + IndexDef: TDbfIndexDef; + Indexes: TDbfIndexDefs; + Dbf: TDbf; + I: integer; +begin + IndexDef := GetComponent(0) as TDbfIndexDef; + Indexes := TDbfIndexDefs(IndexDef.Collection); + Dbf := TDbf(Indexes.FOwner); + for I := 0 to Dbf.FieldCount-1 do + begin + Proc(Dbf.Fields[i].FieldName); + end; +end; + +//========================================================== +//============ TIndexNameProperty +//========================================================== + +type + TIndexNameProperty = class(TStringProperty) + public + function GetAttributes: TPropertyAttributes; override; + procedure GetValues(Proc: TGetStrProc); override; + procedure SetValue(const Value: string); override; + function GetValue: string; override; + end; + +function TIndexNameProperty.GetAttributes: TPropertyAttributes; {override;} +begin + Result := [paValueList, paRevertable]; +end; + +procedure TIndexNameProperty.GetValues(Proc: TGetStrProc); +var + Dbf: TDbf; + I: Integer; +begin + Dbf := GetComponent(0) as TDbf; + Dbf.UpdateIndexDefs; + for I := 0 to Dbf.Indexes.Count - 1 do + Proc(Dbf.Indexes[I].IndexFile); +end; + +procedure TIndexNameProperty.SetValue(const Value: string); {override} +var + Dbf: TDbf; +begin + Dbf := GetComponent(0) as TDbf; + Dbf.IndexName := Value; +end; + +function TIndexNameProperty.GetValue: string; {override;} +var + Dbf: TDbf; +begin + Dbf := GetComponent(0) as TDbf; + Result := Dbf.IndexName; +end; + +//========================================================== +//============ TVersionProperty +//========================================================== +type + TVersionProperty = class(TStringProperty) + public + procedure Edit; override; + function GetAttributes: TPropertyAttributes; override; + end; + +procedure TVersionProperty.Edit; {override;} +begin + ShowMessage( + Format(STRING_VERSION,[TDBF_MAJOR_VERSION, TDBF_MINOR_VERSION]) + + ' : a dBase component'+#13+ + 'for Delphi and c++ builder with no BDE.'+#13+ + #13 + + 'To get the latest version, please visit'+#13+ + 'the website: http://www.tdbf.net'+#13+ + 'or SourceForge: http://tdbf.sf.net'); +end; + +function TVersionProperty.GetAttributes: TPropertyAttributes; {override;} +begin + Result := [paDialog, paReadOnly, paRevertable]; +end; + +//========================================================== +//============ TNativeFieldTypeProperty +//========================================================== +type + TNativeFieldTypeProperty = class(TCharProperty) + public + function GetAttributes: TPropertyAttributes; override; + procedure GetValues(Proc: TGetStrProc); override; + procedure SetValue(const Value: string); override; + end; + +procedure TNativeFieldTypeProperty.SetValue(const Value: string); +var + L: Longint; +begin + if Length(Value) = 0 then L := 0 else + if Value[1] = '#' then L := StrToInt(Copy(Value, 2, Maxint)) + else L := Ord(Value[1]); + SetOrdValue(L); +end; + +function TNativeFieldTypeProperty.GetAttributes: TPropertyAttributes; {override;} +begin + result := [paRevertable,paValueList]; +end; + +procedure TNativeFieldTypeProperty.GetValues(Proc: TGetStrProc); +begin + Proc('C Character'); + Proc('N Numeric'); + Proc('D Date'); + Proc('L Logical'); + Proc('M Memo'); + Proc('B Blob'); + Proc('F Float'); + Proc('O Double'); + Proc('I Integer'); + Proc('G Graphic'); + Proc('+ AutoIncrement'); + Proc('@ DateTime'); +end; + +//========================================================== +//============ initialization +//========================================================== +function IDE_DbfDefaultPath:string; +begin +{$ifndef FPC} + if ToolServices<>nil then + Result := ExtractFilePath(ToolServices.GetProjectName) + else +{$endif} + Result := GetCurrentDir +end; + +{$ifdef FPC} +procedure RegisterUnitDbf; +{$else} +procedure Register; +{$endif} +begin + Dbf.DbfBasePath := IDE_DbfDefaultPath; + RegisterComponents('Data Access', [TDbf]); +// RegisterPropertyEditor(TypeInfo(string), TDbf, 'FilePath', TFilePathProperty); + RegisterPropertyEditor(TypeInfo(string), TDbf, 'TableName', TTableNameProperty); + RegisterPropertyEditor(TypeInfo(string), TDbf, 'Version', TVersionProperty); + RegisterPropertyEditor(TypeInfo(string), TDbf, 'IndexName', TIndexNameProperty); + RegisterPropertyEditor(TypeInfo(string), TDbfIndexDef, 'IndexFile', TIndexFileNameProperty); + RegisterPropertyEditor(TypeInfo(string), TDbfIndexDef, 'SortField', TSortFieldProperty); + RegisterPropertyEditor(TypeInfo(char), TDbfFieldDef, 'NativeFieldType', TNativeFieldTypeProperty); +end; + +{$ifdef FPC} +procedure Register; +begin + RegisterUnit('Dbf', @RegisterUnitDbf); +end; +{$endif} + +{$ifdef FPC} +initialization + {$i tdbf.lrs} +{$endif} + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_str.inc b/mseide-msegui/lib/common/fpccompatibility/dbf_str.inc new file mode 100644 index 0000000..3dbc719 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_str.inc @@ -0,0 +1,24 @@ +var + STRING_FILE_NOT_FOUND: string; + STRING_VERSION: string; + + STRING_RECORD_LOCKED: string; + STRING_WRITE_ERROR: string; + STRING_WRITE_INDEX_ERROR: string; + STRING_KEY_VIOLATION: string; + + STRING_INVALID_DBF_FILE: string; + STRING_FIELD_TOO_LONG: string; + STRING_INVALID_FIELD_COUNT: string; + STRING_INVALID_FIELD_TYPE: string; + STRING_INVALID_VCL_FIELD_TYPE: string; + + STRING_INDEX_BASED_ON_UNKNOWN_FIELD: string; + STRING_INDEX_BASED_ON_INVALID_FIELD: string; + STRING_INDEX_EXPRESSION_TOO_LONG: string; + STRING_INVALID_INDEX_TYPE: string; + STRING_CANNOT_OPEN_INDEX: string; + STRING_TOO_MANY_INDEXES: string; + STRING_INDEX_NOT_EXIST: string; + STRING_NEED_EXCLUSIVE_ACCESS: string; + diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_str.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_str.pas new file mode 100644 index 0000000..23fda49 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_str.pas @@ -0,0 +1,36 @@ +unit dbf_str; + +interface + +{$I dbf_common.inc} +{$I dbf_str.inc} + +implementation + +initialization + + STRING_FILE_NOT_FOUND := 'Open: file not found: "%s".'; + STRING_VERSION := 'TDbf V%d.%d'; + + STRING_RECORD_LOCKED := 'Record locked.'; + STRING_WRITE_ERROR := 'Error while writing occurred. (Disk full?)'; + STRING_WRITE_INDEX_ERROR := 'Error while writing occurred; indexes probably corrupted. (Disk full?)'; + STRING_KEY_VIOLATION := 'Key violation. (Key already present in file).'+#13+#10+ + 'Index: %s'+#13+#10+'Record=%d Key=''%s''.'; + + STRING_INVALID_DBF_FILE := 'Invalid DBF file.'; + STRING_FIELD_TOO_LONG := 'Value is too long: %d characters (it can''t be more than %d).'; + STRING_INVALID_FIELD_COUNT := 'Invalid field count: %d (must be between 1 and 4095).'; + STRING_INVALID_FIELD_TYPE := 'Invalid field type ''%s'' for field ''%s''.'; + STRING_INVALID_VCL_FIELD_TYPE := 'Cannot create field "%s", VCL field type %x not supported by DBF.'; + + STRING_INDEX_BASED_ON_UNKNOWN_FIELD := 'Index based on unknown field "%s".'; + STRING_INDEX_BASED_ON_INVALID_FIELD := 'Field "%s" is an invalid field type to base index on.'; + STRING_INDEX_EXPRESSION_TOO_LONG := 'Index result for "%s" too long, >100 characters (%d).'; + STRING_INVALID_INDEX_TYPE := 'Invalid index type: can only be string or float.'; + STRING_CANNOT_OPEN_INDEX := 'Cannot open index: "%s".'; + STRING_TOO_MANY_INDEXES := 'Can not create index: too many indexes in file.'; + STRING_INDEX_NOT_EXIST := 'Index "%s" does not exist.'; + STRING_NEED_EXCLUSIVE_ACCESS := 'Exclusive access is required for this operation.'; +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_str_es.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_str_es.pas new file mode 100644 index 0000000..63f74eb --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_str_es.pas @@ -0,0 +1,36 @@ +unit dbf_str; + +interface + +{$I dbf_common.inc} +{$I dbf_str.inc} + +implementation + +initialization + + STRING_FILE_NOT_FOUND := 'Apertura: archivo no encontrado: "%s".'; + STRING_VERSION := 'TDbf V%d.%d'; + + STRING_RECORD_LOCKED := 'Registro bloqueado.'; + STRING_WRITE_ERROR := 'Error de escritura. (Disco lleno?)'; + STRING_WRITE_INDEX_ERROR := 'Error de escritura; índices probablemente corruptos. (Disco lleno?)'; + STRING_KEY_VIOLATION := 'Violación de clave. (Clave ya presente en archivo).'+#13+#10+ + 'Indice: %s'+#13+#10+'Registro=%d Clave=''%s''.'; + + STRING_INVALID_DBF_FILE := 'Archivo DBF inválido.'; + STRING_FIELD_TOO_LONG := 'Valor demasiado largo: %d caracteres (no puede ser mayor de %d).'; + STRING_INVALID_FIELD_COUNT := 'Cantidad de campos inválida: %d (debe estar entre 1 y 4095).'; + STRING_INVALID_FIELD_TYPE := 'Tipo de campo inválido ''%s'' para el campo ''%s''.'; + STRING_INVALID_VCL_FIELD_TYPE := 'No se puede crear el campo "%s", campo VCL tipo %x no soportado por DBF.'; + + STRING_INDEX_BASED_ON_UNKNOWN_FIELD := 'Indice basado en campo desconocido "%s".'; + STRING_INDEX_BASED_ON_INVALID_FIELD := 'Campo "%s" inválido para crear un índice.'; + STRING_INDEX_EXPRESSION_TOO_LONG := 'Resultado de índice para "%s" demasiado largo, >100 caracteres (%d).'; + STRING_INVALID_INDEX_TYPE := 'Tipo de índice invalido: solo puede ser string o float.'; + STRING_CANNOT_OPEN_INDEX := 'No se puede abrir el índice: "%s".'; + STRING_TOO_MANY_INDEXES := 'No se puede crear el índice: demasiados indices en el archivo.'; + STRING_INDEX_NOT_EXIST := 'Indice "%s" no existe.'; + STRING_NEED_EXCLUSIVE_ACCESS := 'Acceso Exclusivo requirido para esta operación.'; +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_str_fr.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_str_fr.pas new file mode 100644 index 0000000..51ecb45 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_str_fr.pas @@ -0,0 +1,54 @@ +unit dbf_str; + +interface + +{$I dbf_common.inc} + +var + STRING_FILE_NOT_FOUND: string; + STRING_VERSION: string; + + STRING_RECORD_LOCKED: string; + STRING_KEY_VIOLATION: string; + + STRING_INVALID_DBF_FILE: string; + STRING_FIELD_TOO_LONG: string; + STRING_INVALID_FIELD_COUNT: string; + STRING_INVALID_FIELD_TYPE: string; + + STRING_INDEX_BASED_ON_UNKNOWN_FIELD: string; + STRING_INDEX_BASED_ON_INVALID_FIELD: string; + STRING_INDEX_EXPRESSION_TOO_LONG: string; + STRING_INVALID_INDEX_TYPE: string; + STRING_CANNOT_OPEN_INDEX: string; + STRING_TOO_MANY_INDEXES: string; + STRING_INDEX_NOT_EXIST: string; + STRING_NEED_EXCLUSIVE_ACCESS: string; + +implementation + +initialization + + STRING_FILE_NOT_FOUND := 'Ouverture: fichier non trouvé: "%s"'; + STRING_VERSION := 'TDbf V%d.%d'; + + STRING_RECORD_LOCKED := 'Enregistrement verrouillé.'; + STRING_KEY_VIOLATION := 'Violation de clé. (doublon dans un index).'+#13+#10+ + 'Index: %s'+#13+#10+'Enregistrement=%d Cle=''%s'''; + + STRING_INVALID_DBF_FILE := 'Fichier DBF invalide.'; + STRING_FIELD_TOO_LONG := 'Valeur trop longue: %d caractères (ne peut dépasser %d).'; + STRING_INVALID_FIELD_COUNT := 'Nombre de champs non valide: %d (doit être entre 1 et 4095).'; + STRING_INVALID_FIELD_TYPE := 'Type de champ ''%s'' invalide pour le champ %s.'; + STRING_INVALID_VCL_FIELD_TYPE := 'Impossible de créer le champ "%s", champ type %x VCL non supporté par DBF'; + + STRING_INDEX_BASED_ON_UNKNOWN_FIELD := 'Index basé sur un champ inconnu %s'; + STRING_INDEX_BASED_ON_INVALID_FIELD := 'Impossible de contruire un index sur ce type de champ "%s"'; + STRING_INDEX_EXPRESSION_TOO_LONG := 'Résultat d''Index trop long pour "%s", >100 caractères (%d).'; + STRING_INVALID_INDEX_TYPE := 'Type d''index non valide: doit être string ou float'; + STRING_CANNOT_OPEN_INDEX := 'Impossible d''ouvrir l''index: "%s"'; + STRING_TOO_MANY_INDEXES := 'Impossible de créer l''index: trop d''index dans le fichier.'; + STRING_INDEX_NOT_EXIST := 'L''index "%s" n''existe pas.'; + STRING_NEED_EXCLUSIVE_ACCESS := 'Access exclusif requis pour cette opération.'; +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_str_ita.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_str_ita.pas new file mode 100644 index 0000000..ec4c598 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_str_ita.pas @@ -0,0 +1,29 @@ +unit dbf_str; + +interface + +{$I dbf_common.inc} +{$I dbf_str.inc} + + +implementation + +initialization + + STRING_FILE_NOT_FOUND := 'Apertura: file non trovato: "%s"'; + STRING_VERSION := 'TDbf V%d.%d'; + + STRING_RECORD_LOCKED := 'Record già in uso.'; + + STRING_INVALID_DBF_FILE := 'File DBF non valido.'; + STRING_FIELD_TOO_LONG := 'Valore troppo elevato: %d caratteri (esso non può essere più di %d).'; + STRING_INVALID_FIELD_COUNT := 'Campo non valido (count): %d (deve essere tra 1 e 4095).'; + + STRING_INDEX_BASED_ON_UNKNOWN_FIELD := 'Indice basato su un campo sconosciuto "%s"'; + STRING_INDEX_BASED_ON_INVALID_FIELD := 'Campo "%s" è di tipo non valido per un indice'; + STRING_INVALID_INDEX_TYPE := 'Tipo indice non valido: Può essere solo string o float'; + STRING_CANNOT_OPEN_INDEX := 'Non è possibile aprire indice : "%s"'; + STRING_TOO_MANY_INDEXES := 'Non è possibile creare indice: Troppi indici aperti.'; + STRING_INDEX_NOT_EXIST := 'Indice "%s" non esiste.'; + STRING_NEED_EXCLUSIVE_ACCESS := 'L''Accesso in esclusiva è richiesto per questa operazione.'; +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_str_nl.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_str_nl.pas new file mode 100644 index 0000000..105564d --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_str_nl.pas @@ -0,0 +1,35 @@ +unit dbf_str; + +interface + +{$I dbf_common.inc} +{$I dbf_str.inc} + +implementation + +initialization + + STRING_FILE_NOT_FOUND := 'Openen: bestand niet gevonden: "%s"'; + STRING_VERSION := 'TDbf V%d.%d'; + + STRING_RECORD_LOCKED := 'Record in gebruik.'; + STRING_WRITE_ERROR := 'Error tijdens schrijven. (Disk vol?)'; + STRING_KEY_VIOLATION := 'Indexsleutel bestond al in bestand.'+#13+#10+ + 'Index: %s'+#13+#10+'Record=%d Sleutel=''%s'''; + + STRING_INVALID_DBF_FILE := 'Ongeldig DBF bestand.'; + STRING_FIELD_TOO_LONG := 'Waarde is te lang: %d karakters (maximum is %d).'; + STRING_INVALID_FIELD_COUNT := 'Ongeldig aantal velden: %d (moet tussen 1 en 4095).'; + STRING_INVALID_FIELD_TYPE := 'Veldtype ''%s'' is ongeldig voor veld ''%s''.'; + STRING_INVALID_VCL_FIELD_TYPE := 'Veld "%s": VCL veldtype %x wordt niet ondersteund door DBF.'; + + STRING_INDEX_BASED_ON_UNKNOWN_FIELD := 'Index gebaseerd op onbekend veld "%s".'; + STRING_INDEX_BASED_ON_INVALID_FIELD := 'Veld "%s" heeft een ongeldig veldtype om index op te baseren.'; + STRING_INDEX_EXPRESSION_TOO_LONG := 'Index expressie resultaat "%s" is te lang, >100 karakters (%d).'; + STRING_INVALID_INDEX_TYPE := 'Ongeldig index type: kan alleen karakter of numeriek.'; + STRING_CANNOT_OPEN_INDEX := 'Openen index gefaald: "%s".'; + STRING_TOO_MANY_INDEXES := 'Toevoegen index onmogenlijk: te veel indexen in bestand.'; + STRING_INDEX_NOT_EXIST := 'Index "%s" bestaat niet.'; + STRING_NEED_EXCLUSIVE_ACCESS := 'Exclusieve toegang is vereist voor deze actie.'; +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_str_pl.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_str_pl.pas new file mode 100644 index 0000000..52e5378 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_str_pl.pas @@ -0,0 +1,36 @@ +unit dbf_str; + +interface + +{$I dbf_common.inc} +{$I dbf_str.inc} + +implementation + +initialization + + STRING_FILE_NOT_FOUND := 'Open: brak pliku: "%s"'; + STRING_VERSION := 'TDbf V%d.%d'; + + STRING_RECORD_LOCKED := 'Rekord zablokowany.'; + STRING_WRITE_ERROR := 'Niezapisano(Brak miejsca na dysku?)'; + STRING_KEY_VIOLATION := 'Konflikt klucza. (Klucz obecny w pliku).'+#13+#10+ + 'Indeks: %s'+#13+#10+'Rekord=%d Klucz=''%s'''; + + STRING_INVALID_DBF_FILE := 'Uszkodzony plik bazy.'; + STRING_FIELD_TOO_LONG := 'Dana za d³uga : %d znaków (dopuszczalne do %d).'; + STRING_INVALID_FIELD_COUNT := 'Z³a liczba pól: %d (dozwolone 1 do 4095).'; + STRING_INVALID_FIELD_TYPE := 'B³êdny typ pola ''%c'' dla pola ''%s''.'; + STRING_INVALID_VCL_FIELD_TYPE := 'Nie mogê tworzyæ pola "%s", typ pola VCL %x nie wspierany przez DBF.'; + + + STRING_INDEX_BASED_ON_UNKNOWN_FIELD := 'Kluczowe pole indeksu "%s" nie istnieje'; + STRING_INDEX_BASED_ON_INVALID_FIELD := 'Typ pola "%s" niedozwolony dla indeksów'; + STRING_INDEX_EXPRESSION_TOO_LONG := 'Zbyt d³ugi wynik "%s", >100 znaków (%d).'; + STRING_INVALID_INDEX_TYPE := 'Z³y typ indeksu: tylko string lub float'; + STRING_CANNOT_OPEN_INDEX := 'Nie mogê otworzyæ indeksu: "%s"'; + STRING_TOO_MANY_INDEXES := 'Nie mogê stworzyæ indeksu: za du¿o w pliku.'; + STRING_INDEX_NOT_EXIST := 'Brak indeksu "%s".'; + STRING_NEED_EXCLUSIVE_ACCESS := 'Operacja wymaga dostêpu w trybie Exclusive.'; +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_str_pt.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_str_pt.pas new file mode 100644 index 0000000..37e9a97 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_str_pt.pas @@ -0,0 +1,37 @@ +unit dbf_str; + +{ note this is Brazilian Portuguese } + +interface + +{$I dbf_common.inc} +{$I dbf_str.inc} + +implementation + +initialization + + STRING_FILE_NOT_FOUND := 'Abertura: arquivo não encontrado: "%s".'; + STRING_VERSION := 'TDbf V%d.%d'; + + STRING_RECORD_LOCKED := 'Registro bloqueado.'; + STRING_WRITE_ERROR := 'Erro de escrita. (Disco cheio?)'; + STRING_WRITE_INDEX_ERROR := 'Erro de escrita; índices provavelmente corrompidos. (Disco cheio?)'; + STRING_KEY_VIOLATION := 'Violação de chave. (Chave já presente no archivo).'+#13+#10+ + 'Índice: %s'+#13+#10+'Registro=%d Chave=''%s''.'; + + STRING_INVALID_DBF_FILE := 'Arquivo DBF inválido.'; + STRING_FIELD_TOO_LONG := 'Valor muito grande: %d caracteres (não pode ser maior que %d).'; + STRING_INVALID_FIELD_COUNT := 'Quantidade de campos inválida: %d (deve estar entre 1 e 4095).'; + STRING_INVALID_FIELD_TYPE := 'Tipo de campo inválido ''%s'' para o campo ''%s''.'; + STRING_INVALID_VCL_FIELD_TYPE := 'Não se pode criar o campo "%s", campo VCL tipo %x não suportado por DBF.'; + + STRING_INDEX_BASED_ON_UNKNOWN_FIELD := 'Índice baseado em campo desconhecido "%s".'; + STRING_INDEX_BASED_ON_INVALID_FIELD := 'Campo "%s" inválido para criar um índice.'; + STRING_INDEX_EXPRESSION_TOO_LONG := 'Resultado de índice para "%s" demasiado grande, >100 caracteres (%d).'; + STRING_INVALID_INDEX_TYPE := 'Tipo de índice inválido: só pode ser string ou float.'; + STRING_CANNOT_OPEN_INDEX := 'Não se pode abrir o índice: "%s".'; + STRING_TOO_MANY_INDEXES := 'Não se pode criar o índice: demasiados índices no archivo.'; + STRING_INDEX_NOT_EXIST := 'Ìndice "%s" não existe.'; + STRING_NEED_EXCLUSIVE_ACCESS := 'Acesso Exclusivo requerido para esta operação.'; +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_str_ru.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_str_ru.pas new file mode 100644 index 0000000..c7fe929 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_str_ru.pas @@ -0,0 +1,40 @@ +unit dbf_str_ru; + +// file is encoded in Windows-1251 encoding +// for using with Linux/Kylix must be re-coded to KOI8-R +// for use with DOS & OS/2 (if it will be possible with FreePascal or VirtualPascal) +// file should be recoded to cp866 + +interface + +{$I dbf_common.inc} +{$I dbf_str.inc} + +implementation + +initialization + + STRING_FILE_NOT_FOUND := 'Ôàéë "%s" íå ñóùåñòâóåò. Îòêðûòü íåâîçìîæíî.'; + STRING_VERSION := 'TDbf V%d.%d'; + + STRING_RECORD_LOCKED := 'Çàïèñü (ñòðîêà òàáëèöû) çàáëîêèðîâàíà.'; + STRING_WRITE_ERROR := 'Îøèáêà çàïèñè íà äèñê (Äèñê çàïîëíåí?)'; + STRING_KEY_VIOLATION := 'Êëþ÷åâîå çíà÷åíèå íå äîëæíî ïîâòîðÿòüñÿ!.'+#13+#10+ + 'Èíäåêñ: %s'+#13+#10+'Çàïèñü (ñòðîêà)=%d Êëþ÷="%s".'; + + STRING_INVALID_DBF_FILE := 'Ôàéë DBF ïîâðåæäåí èëè åãî ñòðóêòóðà íå DBF.'; + STRING_FIELD_TOO_LONG := 'Äëèíà çíà÷åíèÿ - %d ñèìâîëîâ, ýòî áîëüøå ìàêñèìóìà - %d.'; + STRING_INVALID_FIELD_COUNT := 'Êîëè÷åñòâî ïîëåé â òàáëèöå (%d) íåâîçìîæíî. Äîïóñòèìî îò 1 äî 4095.'; + STRING_INVALID_FIELD_TYPE := 'Òèï çíà÷åíèÿ "%s", çàòðåáîâàííûé ïîëåì "%s" íåâîçìîæåí.'; + STRING_INVALID_VCL_FIELD_TYPE := 'Íåâîçìîæíî ñîçäàòü ïîëå "%s", Òèï äàííûõ VCL[%x] íå ìîæåò áûòü çàïèñàí â DBF.'; + + STRING_INDEX_BASED_ON_UNKNOWN_FIELD := 'Èíäåêñ ññûëàåòñÿ íà íåñóùåñòâóþùåå ïîëå "%s".'; + STRING_INDEX_BASED_ON_INVALID_FIELD := 'Ïîëå "%s" íå ìîæåò áûòü èíäåêñèðîâàííî. Èíäåêñû íå ïîääåðæèâàþò òàêîé òèï ïîëÿ.'; + STRING_INDEX_EXPRESSION_TOO_LONG := '%s: Ñëèøêîì äëèííîå çíà÷åíèå äëÿ èíäåêñà (%d). Äîëæíî áûòü íå áîëüøå 100 ñèìâîëîâ.'; + STRING_INVALID_INDEX_TYPE := 'Íåâîçìîæíûé òèï èíäåêñà: èíäåêñàöèÿ âîçìîæíî òîëüêî ïî ÷èñëó èëè ñòðîêå'; + STRING_CANNOT_OPEN_INDEX := 'Íåâîçìîæíî îòêðûòü èíäåêñ "%s".'; + STRING_TOO_MANY_INDEXES := 'Íåâîçìîæíî ñîçäàòü åùå îäèí èíäåêñ. Ôàéë ïîëîí.'; + STRING_INDEX_NOT_EXIST := 'Èíäåêñ "%s" íå ñóùåñòâóåò.'; + STRING_NEED_EXCLUSIVE_ACCESS := 'Íåâîçìîæíî âûïîëíèòü - ñíà÷àëà íóæíî ïîëó÷èòü ìîíîïîëüíûé äîñòóï.'; +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_struct.inc b/mseide-msegui/lib/common/fpccompatibility/dbf_struct.inc new file mode 100644 index 0000000..68d3ae3 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_struct.inc @@ -0,0 +1,145 @@ + +const + +//==================================================================== + FieldPropType_Required = $01; + FieldPropType_Min = $02; + FieldPropType_Max = $03; + FieldPropType_Default = $04; + FieldPropType_Constraint = $06; + + FieldDescVII_AutoIncOffset = 42; + +//==================================================================== +// File structures +//==================================================================== + +type + + PDbfHdr = ^rDbfHdr; + rDbfHdr = packed record + VerDBF : Byte; // 0 + Year : Byte; // 1 + Month : Byte; // 2 + Day : Byte; // 3 + RecordCount : Integer; // 4-7 + FullHdrSize : Word; // 8-9 + RecordSize : Word; // 10-11 + Dummy1 : Word; // 12-13 + IncTrans : Byte; // 14 + Encrypt : Byte; // 15 + MultiUse : Integer; // 16-19 + LastUserID : Integer; // 20-23 + Dummy2 : array[24..27] of Byte; + MDXFlag : Byte; // 28 + Language : Byte; // 29 + Dummy3 : Word; // 30-31 + end; +//==================================================================== + PAfterHdrIII = ^rAfterHdrIII; + rAfterHdrIII = packed record // Empty + end; +//==================================================================== + PAfterHdrVII = ^rAfterHdrVII; + rAfterHdrVII = packed record + LanguageDriverName : array[32..63] of Char; + Dummy : array[64..67] of Byte; + end; +//==================================================================== + PFieldDescIII = ^rFieldDescIII; + rFieldDescIII = packed record + FieldName : array[0..10] of Char; + FieldType : Char; // 11 + FieldOffset : Integer; // 12..15 only applicable to foxpro databases + FieldSize : Byte; // 16 + FieldPrecision : Byte; // 17 + FoxProFlags : Byte; // 18 + Dummy2 : array[19..31] of Byte; + end; +//==================================================================== +// OH 2000-11-15 dBase7 support. Header Update (add fields like Next AutoInc Value) + rFieldDescVII = packed record + FieldName : array [0..31] of Char; + FieldType : Char; // 32 + FieldSize : Byte; // 33 + FieldPrecision : Byte; // 34 + Reserved1 : Word; // 35-36 + MDXFlag : Byte; // 37 + // NOTE: the docs say Reserved2 is 2 bytes, and Reserved3 is 4 bytes + // but testing shows BDE has them the other way around + // be BDE compatible :S + Reserved2 : Cardinal; // 38-41 + NextAutoInc : Cardinal; // 42-45 + Reserved3 : Word; // 46-47 + end; +//==================================================================== + PFieldPropsHdr = ^rFieldPropsHdr; + rFieldPropsHdr = packed record + NumStdProps : Word; // 0..1 + StartStdProps : Word; // 2..3 + NumCustomProps : Word; // 4..5 + StartCustomProps : Word; // 6..7 + NumRIProps : Word; // 8..9 + StartRIProps : Word; // 10..11 + StartData : Word; // 12..13 ; this points past the Descriptor arrays to data used by the arrays - for example Custom property names are stored here. + Size : Word; // 14..15 ; Actual size of structure, including data + end; +//==================================================================== + PStdPropEntry = ^rStdPropEntry; + rStdPropEntry = packed record + GenNumber : Word; // 0..1 ; Generational number. More than one value may exist for a property. The current value is the value with the highest generational number. + FieldOffset : Word; // 2..3 ; Table field offset - base one. 01 for the first field in the table, 02 for the second field, etc. Note: this will be 0 in the case of a constraint. + PropType : Byte; // 4 ; Which property is described in this record: + // 01 Required + // 02 Min + // 03 Max + // 04 Default + // 06 Database constraint + FieldType : Byte; // 5 ; Field Type: + // 00 No type - constraint + // 01 Char + // 02 Numeric + // 03 Memo + // 04 Logical + // 05 Date + // 06 Float + // 08 OLE + // 09 Binary + // 11 Long + // 12 Timestamp + // 13 Double + // 14 AutoIncrement (not settable from the Inspector) + IsConstraint : Byte; // 6 ; 0x00 if the array element is a constraint, 0x02 otherwise. + Reserved : array[7..10] of Char; + DataOffset : Word; // 11..12 ; Offset from the start of this structure to the data for the property. The Required property has no data associated with it, so it is always 0. + DataSize : Word; // 13..14 ; Width of database field associated with the property, and hence size of the data (includes 0 terminator in the case of a constraint). + end; +//==================================================================== + PCustomPropEntry = ^rCustomPropEntry; + rCustomPropEntry = packed record + GenNumber : Word; // 0..1 ; same as standard + FieldOffset : Word; // 2..3 ; same as standard + FieldType : Byte; // 4 ; same as standard + Reserved : Byte; // 5 + NameOffset : Word; // 6..7 ; Offset from the start of this structure to the Custom property name. + NameLength : Word; // 8..9 ; Length of the Custom property name. + DataOffset : Word; // 10..11 ; Offset from the start of this structure to the Custom property data. + DataLength : Word; // 12..13 ; Length of the Custom property data (does not include null terminator). + end; +//==================================================================== + PRIPropEntry = ^rRIPropEntry; + rRIPropEntry = packed record + RelationType : Byte; // 0 ; 0x07 if Master (parent), 0x08 if Dependent (child). + Number : Word; // 1..2 ; Sequential number, 1 based counting. If this number is 0, this RI rule has been dropped. + NameOffset : Word; // 3..4 ; Offset of the RI rule name - 0 terminated. + NameSize : Word; // 5..6 ; Size of ... + ForeignOffset : Word; // 7..8 ; Offset of the name of the Foreign Table - 0 terminated. + ForeignSize : Word; // 9..10 ; Size of ... + UpdateType : Byte; // 11 ; Update & delete behaviour: Update Cascade=0x10, Delete Cascade=0x01 + NumFieldsKey : Word; // 12..13 ; Number of fields in the linking key. + LocalTagOffset : Word; // 14..15 ; Offset of the Local Table tag name - 0 terminated. + LocalTagSize : Word; // 16..17 ; Size of ... + ForeignTagOffset: Word; // 18..19 ; Offset of the Foreign Table tag name - 0 terminated. + ForeignTagSize : Word; // 20..21 ; Size of ... + end; + diff --git a/mseide-msegui/lib/common/fpccompatibility/dbf_wtil.pas b/mseide-msegui/lib/common/fpccompatibility/dbf_wtil.pas new file mode 100644 index 0000000..cfe8b31 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/dbf_wtil.pas @@ -0,0 +1,670 @@ +unit dbf_wtil; + +{$I dbf_common.inc} + +interface + +{$ifndef WINDOWS} +uses +{$ifdef FPC} + BaseUnix, +{$else} + Libc, +{$endif} + Types, SysUtils, Classes; + +const + LCID_INSTALLED = $00000001; { installed locale ids } + LCID_SUPPORTED = $00000002; { supported locale ids } + CP_INSTALLED = $00000001; { installed code page ids } + CP_SUPPORTED = $00000002; { supported code page ids } +(* + * Language IDs. + * + * The following two combinations of primary language ID and + * sublanguage ID have special semantics: + * + * Primary Language ID Sublanguage ID Result + * ------------------- --------------- ------------------------ + * LANG_NEUTRAL SUBLANG_NEUTRAL Language neutral + * LANG_NEUTRAL SUBLANG_DEFAULT User default language + * LANG_NEUTRAL SUBLANG_SYS_DEFAULT System default language + *) +{ Primary language IDs. } + LANG_NEUTRAL = $00; + LANG_AFRIKAANS = $36; + LANG_ALBANIAN = $1c; + LANG_ARABIC = $01; + LANG_BASQUE = $2d; + LANG_BELARUSIAN = $23; + LANG_BULGARIAN = $02; + LANG_CATALAN = $03; + LANG_CHINESE = $04; + LANG_CROATIAN = $1a; + LANG_CZECH = $05; + LANG_DANISH = $06; + LANG_DUTCH = $13; + LANG_ENGLISH = $09; + LANG_ESTONIAN = $25; + LANG_FAEROESE = $38; + LANG_FARSI = $29; + LANG_FINNISH = $0b; + LANG_FRENCH = $0c; + LANG_GERMAN = $07; + LANG_GREEK = $08; + LANG_HEBREW = $0d; + LANG_HUNGARIAN = $0e; + LANG_ICELANDIC = $0f; + LANG_INDONESIAN = $21; + LANG_ITALIAN = $10; + LANG_JAPANESE = $11; + LANG_KOREAN = $12; + LANG_LATVIAN = $26; + LANG_LITHUANIAN = $27; + LANG_NORWEGIAN = $14; + LANG_POLISH = $15; + LANG_PORTUGUESE = $16; + LANG_ROMANIAN = $18; + LANG_RUSSIAN = $19; + LANG_SERBIAN = $1a; + LANG_SLOVAK = $1b; + LANG_SLOVENIAN = $24; + LANG_SPANISH = $0a; + LANG_SWEDISH = $1d; + LANG_THAI = $1e; + LANG_TURKISH = $1f; + LANG_UKRAINIAN = $22; + LANG_VIETNAMESE = $2a; +{ Sublanguage IDs. } + { The name immediately following SUBLANG_ dictates which primary + language ID that sublanguage ID can be combined with to form a + valid language ID. + } + SUBLANG_NEUTRAL = $00; { language neutral } + SUBLANG_DEFAULT = $01; { user default } + SUBLANG_SYS_DEFAULT = $02; { system default } + SUBLANG_ARABIC_SAUDI_ARABIA = $01; { Arabic (Saudi Arabia) } + SUBLANG_ARABIC_IRAQ = $02; { Arabic (Iraq) } + SUBLANG_ARABIC_EGYPT = $03; { Arabic (Egypt) } + SUBLANG_ARABIC_LIBYA = $04; { Arabic (Libya) } + SUBLANG_ARABIC_ALGERIA = $05; { Arabic (Algeria) } + SUBLANG_ARABIC_MOROCCO = $06; { Arabic (Morocco) } + SUBLANG_ARABIC_TUNISIA = $07; { Arabic (Tunisia) } + SUBLANG_ARABIC_OMAN = $08; { Arabic (Oman) } + SUBLANG_ARABIC_YEMEN = $09; { Arabic (Yemen) } + SUBLANG_ARABIC_SYRIA = $0a; { Arabic (Syria) } + SUBLANG_ARABIC_JORDAN = $0b; { Arabic (Jordan) } + SUBLANG_ARABIC_LEBANON = $0c; { Arabic (Lebanon) } + SUBLANG_ARABIC_KUWAIT = $0d; { Arabic (Kuwait) } + SUBLANG_ARABIC_UAE = $0e; { Arabic (U.A.E) } + SUBLANG_ARABIC_BAHRAIN = $0f; { Arabic (Bahrain) } + SUBLANG_ARABIC_QATAR = $10; { Arabic (Qatar) } + SUBLANG_CHINESE_TRADITIONAL = $01; { Chinese (Taiwan) } + SUBLANG_CHINESE_SIMPLIFIED = $02; { Chinese (PR China) } + SUBLANG_CHINESE_HONGKONG = $03; { Chinese (Hong Kong) } + SUBLANG_CHINESE_SINGAPORE = $04; { Chinese (Singapore) } + SUBLANG_DUTCH = $01; { Dutch } + SUBLANG_DUTCH_BELGIAN = $02; { Dutch (Belgian) } + SUBLANG_ENGLISH_US = $01; { English (USA) } + SUBLANG_ENGLISH_UK = $02; { English (UK) } + SUBLANG_ENGLISH_AUS = $03; { English (Australian) } + SUBLANG_ENGLISH_CAN = $04; { English (Canadian) } + SUBLANG_ENGLISH_NZ = $05; { English (New Zealand) } + SUBLANG_ENGLISH_EIRE = $06; { English (Irish) } + SUBLANG_ENGLISH_SOUTH_AFRICA = $07; { English (South Africa) } + SUBLANG_ENGLISH_JAMAICA = $08; { English (Jamaica) } + SUBLANG_ENGLISH_CARIBBEAN = $09; { English (Caribbean) } + SUBLANG_ENGLISH_BELIZE = $0a; { English (Belize) } + SUBLANG_ENGLISH_TRINIDAD = $0b; { English (Trinidad) } + SUBLANG_FRENCH = $01; { French } + SUBLANG_FRENCH_BELGIAN = $02; { French (Belgian) } + SUBLANG_FRENCH_CANADIAN = $03; { French (Canadian) } + SUBLANG_FRENCH_SWISS = $04; { French (Swiss) } + SUBLANG_FRENCH_LUXEMBOURG = $05; { French (Luxembourg) } + SUBLANG_GERMAN = $01; { German } + SUBLANG_GERMAN_SWISS = $02; { German (Swiss) } + SUBLANG_GERMAN_AUSTRIAN = $03; { German (Austrian) } + SUBLANG_GERMAN_LUXEMBOURG = $04; { German (Luxembourg) } + SUBLANG_GERMAN_LIECHTENSTEIN = $05; { German (Liechtenstein) } + SUBLANG_ITALIAN = $01; { Italian } + SUBLANG_ITALIAN_SWISS = $02; { Italian (Swiss) } + SUBLANG_KOREAN = $01; { Korean (Extended Wansung) } + SUBLANG_KOREAN_JOHAB = $02; { Korean (Johab) } + SUBLANG_NORWEGIAN_BOKMAL = $01; { Norwegian (Bokmal) } + SUBLANG_NORWEGIAN_NYNORSK = $02; { Norwegian (Nynorsk) } + SUBLANG_PORTUGUESE = $02; { Portuguese } + SUBLANG_PORTUGUESE_BRAZILIAN = $01; { Portuguese (Brazilian) } + SUBLANG_SERBIAN_LATIN = $02; { Serbian (Latin) } + SUBLANG_SERBIAN_CYRILLIC = $03; { Serbian (Cyrillic) } + SUBLANG_SPANISH = $01; { Spanish (Castilian) } + SUBLANG_SPANISH_MEXICAN = $02; { Spanish (Mexican) } + SUBLANG_SPANISH_MODERN = $03; { Spanish (Modern) } + SUBLANG_SPANISH_GUATEMALA = $04; { Spanish (Guatemala) } + SUBLANG_SPANISH_COSTA_RICA = $05; { Spanish (Costa Rica) } + SUBLANG_SPANISH_PANAMA = $06; { Spanish (Panama) } + SUBLANG_SPANISH_DOMINICAN_REPUBLIC = $07; { Spanish (Dominican Republic) } + SUBLANG_SPANISH_VENEZUELA = $08; { Spanish (Venezuela) } + SUBLANG_SPANISH_COLOMBIA = $09; { Spanish (Colombia) } + SUBLANG_SPANISH_PERU = $0a; { Spanish (Peru) } + SUBLANG_SPANISH_ARGENTINA = $0b; { Spanish (Argentina) } + SUBLANG_SPANISH_ECUADOR = $0c; { Spanish (Ecuador) } + SUBLANG_SPANISH_CHILE = $0d; { Spanish (Chile) } + SUBLANG_SPANISH_URUGUAY = $0e; { Spanish (Uruguay) } + SUBLANG_SPANISH_PARAGUAY = $0f; { Spanish (Paraguay) } + SUBLANG_SPANISH_BOLIVIA = $10; { Spanish (Bolivia) } + SUBLANG_SPANISH_EL_SALVADOR = $11; { Spanish (El Salvador) } + SUBLANG_SPANISH_HONDURAS = $12; { Spanish (Honduras) } + SUBLANG_SPANISH_NICARAGUA = $13; { Spanish (Nicaragua) } + SUBLANG_SPANISH_PUERTO_RICO = $14; { Spanish (Puerto Rico) } + SUBLANG_SWEDISH = $01; { Swedish } + SUBLANG_SWEDISH_FINLAND = $02; { Swedish (Finland) } +{ Sorting IDs. } + SORT_DEFAULT = $0; { sorting default } + SORT_JAPANESE_XJIS = $0; { Japanese XJIS order } + SORT_JAPANESE_UNICODE = $1; { Japanese Unicode order } + SORT_CHINESE_BIG5 = $0; { Chinese BIG5 order } + SORT_CHINESE_PRCP = $0; { PRC Chinese Phonetic order } + SORT_CHINESE_UNICODE = $1; { Chinese Unicode order } + SORT_CHINESE_PRC = $2; { PRC Chinese Stroke Count order } + SORT_KOREAN_KSC = $0; { Korean KSC order } + SORT_KOREAN_UNICODE = $1; { Korean Unicode order } + SORT_GERMAN_PHONE_BOOK = $1; { German Phone Book order } +(* + * A language ID is a 16 bit value which is the combination of a + * primary language ID and a secondary language ID. The bits are + * allocated as follows: + * + * +-----------------------+-------------------------+ + * | Sublanguage ID | Primary Language ID | + * +-----------------------+-------------------------+ + * 15 10 9 0 bit + * + * + * + * A locale ID is a 32 bit value which is the combination of a + * language ID, a sort ID, and a reserved area. The bits are + * allocated as follows: + * + * +-------------+---------+-------------------------+ + * | Reserved | Sort ID | Language ID | + * +-------------+---------+-------------------------+ + * 31 20 19 16 15 0 bit + * + *) +{ Default System and User IDs for language and locale. } + LANG_SYSTEM_DEFAULT = (SUBLANG_SYS_DEFAULT shl 10) or LANG_NEUTRAL; + LANG_USER_DEFAULT = (SUBLANG_DEFAULT shl 10) or LANG_NEUTRAL; + LOCALE_SYSTEM_DEFAULT = (SORT_DEFAULT shl 16) or LANG_SYSTEM_DEFAULT; + LOCALE_USER_DEFAULT = (SORT_DEFAULT shl 16) or LANG_USER_DEFAULT; + +(* + Error const of File Locking +*) +{$ifdef FPC} + ERROR_LOCK_VIOLATION = ESysEACCES; +{$else} + ERROR_LOCK_VIOLATION = EACCES; +{$endif} + +{ MBCS and Unicode Translation Flags. } + MB_PRECOMPOSED = 1; { use precomposed chars } + MB_COMPOSITE = 2; { use composite chars } + MB_USEGLYPHCHARS = 4; { use glyph chars, not ctrl chars } + +type + LCID = DWORD; + BOOL = LongBool; + PBOOL = ^BOOL; + WCHAR = WideChar; + PWChar = PWideChar; + LPSTR = PAnsiChar; + PLPSTR = ^LPSTR; + LPCSTR = PAnsiChar; + LPCTSTR = PAnsiChar; { should be PWideChar if UNICODE } + LPTSTR = PAnsiChar; { should be PWideChar if UNICODE } + LPWSTR = PWideChar; + PLPWSTR = ^LPWSTR; + LPCWSTR = PWideChar; + + { System time is represented with the following structure: } + PSystemTime = ^TSystemTime; + TSystemTime = record + wYear: Word; + wMonth: Word; + wDayOfWeek: Word; + wDay: Word; + wHour: Word; + wMinute: Word; + wSecond: Word; + wMilliseconds: Word; + end; + + TFarProc = Pointer; + TFNLocaleEnumProc = TFarProc; + TFNCodepageEnumProc = TFarProc; + TFNDateFmtEnumProc = TFarProc; + TFNTimeFmtEnumProc = TFarProc; + TFNCalInfoEnumProc = TFarProc; + +function LockFile(hFile: THandle; dwFileOffsetLow, dwFileOffsetHigh: DWORD; nNumberOfBytesToLockLow, nNumberOfBytesToLockHigh: DWORD): BOOL; +function UnlockFile(hFile: THandle; dwFileOffsetLow, dwFileOffsetHigh: DWORD; nNumberOfBytesToUnlockLow, nNumberOfBytesToUnlockHigh: DWORD): BOOL; +procedure GetLocalTime(var lpSystemTime: TSystemTime); +function GetOEMCP: Cardinal; +function GetACP: Cardinal; +function OemToChar(lpszSrc: PChar; lpszDst: PChar): BOOL; +function CharToOem(lpszSrc: PChar; lpszDst: PChar): BOOL; +function OemToCharBuff(lpszSrc: PChar; lpszDst: PChar; cchDstLength: DWORD): BOOL; +function CharToOemBuff(lpszSrc: PChar; lpszDst: PChar; cchDstLength: DWORD): BOOL; +function MultiByteToWideChar(CodePage: DWORD; dwFlags: DWORD; const lpMultiByteStr: LPCSTR; cchMultiByte: Integer; lpWideCharStr: LPWSTR; cchWideChar: Integer): Integer; +function WideCharToMultiByte(CodePage: DWORD; dwFlags: DWORD; lpWideCharStr: LPWSTR; cchWideChar: Integer; lpMultiByteStr: LPSTR; cchMultiByte: Integer; lpDefaultChar: LPCSTR; lpUsedDefaultChar: PBOOL): Integer; +function CompareString(Locale: LCID; dwCmpFlags: DWORD; lpString1: PChar; cchCount1: Integer; lpString2: PChar; cchCount2: Integer): Integer; +function EnumSystemCodePages(lpCodePageEnumProc: TFNCodepageEnumProc; dwFlags: DWORD): BOOL; +function EnumSystemLocales(lpLocaleEnumProc: TFNLocaleEnumProc; dwFlags: DWORD): BOOL; +function GetUserDefaultLCID: LCID; + +{$ifdef FPC} +function GetLastError: Integer; +procedure SetLastError(Value: Integer); +{$endif} +{$endif} + +implementation + +{$ifndef WINDOWS} +{$ifdef FPC} +uses + unix; +{$endif} + +(* +NAME + fcntl - manipulate file descriptor + +SYNOPSIS + #include + #include + + int fcntl(int fd, int cmd); + int fcntl(int fd, int cmd, long arg); + int fcntl(int fd, int cmd, struct flock * lock); + +DESCRIPTION + fcntl performs one of various miscellaneous operations on + fd. The operation in question is determined by cmd: + + F_GETLK, F_SETLK and F_SETLKW are used to manage discreð + tionary file locks. The third argument lock is a pointer + to a struct flock (that may be overwritten by this call). + + F_GETLK + Return the flock structure that prevents us from + obtaining the lock, or set the l_type field of the + lock to F_UNLCK if there is no obstruction. + + F_SETLK + The lock is set (when l_type is F_RDLCK or F_WRLCK) + or cleared (when it is F_UNLCK). If the lock is + held by someone else, this call returns -1 and sets + errno to EACCES or EAGAIN. + + F_SETLKW + Like F_SETLK, but instead of returning an error we + wait for the lock to be released. If a signal that + is to be caught is received while fcntl is waiting, + it is interrupted and (after the signal handler has + returned) returns immediately (with return value -1 + and errno set to EINTR). + + Using these mechanisms, a program can implement fully + asynchronous I/O without using select(2) or poll(2) most + of the time. + + The use of O_ASYNC, F_GETOWN, F_SETOWN is specific to BSD + and Linux. F_GETSIG and F_SETSIG are Linux-specific. + POSIX has asynchronous I/O and the aio_sigevent structure + to achieve similar things; these are also available in + Linux as part of the GNU C Library (Glibc). + +RETURN VALUE + For a successful call, the return value depends on the + operation: + + F_GETFD Value of flag. + + F_GETFL Value of flags. + + F_GETOWN Value of descriptor owner. + + F_GETSIG Value of signal sent when read or write becomes + possible, or zero for traditional SIGIO + behaviour. + + All other commands + Zero. + + On error, -1 is returned, and errno is set appropriately. + +ERRORS + EACCES Operation is prohibited by locks held by other + processes. + + EAGAIN Operation is prohibited because the file has been + memory-mapped by another process. + + EBADF fd is not an open file descriptor. + + EDEADLK It was detected that the specified F_SETLKW comð + mand would cause a deadlock. + + EFAULT lock is outside your accessible address space. + + EINTR For F_SETLKW, the command was interrupted by a + signal. For F_GETLK and F_SETLK, the command was + interrupted by a signal before the lock was + checked or acquired. Most likely when locking a + remote file (e.g. locking over NFS), but can + sometimes happen locally. + + EINVAL For F_DUPFD, arg is negative or is greater than + the maximum allowable value. For F_SETSIG, arg + is not an allowable signal number. + + EMFILE For F_DUPFD, the process already has the maximum + number of file descriptors open. + + ENOLCK Too many segment locks open, lock table is full, + or a remote locking protocol failed (e.g. locking + over NFS). + + EPERM Attempted to clear the O_APPEND flag on a file + that has the append-only attribute set. + +typedef long __kernel_off_t; +typedef int __kernel_pid_t; + +struct flock { + short l_type; + short l_whence; + off_t l_start; + off_t l_len; + pid_t l_pid; +}; + +whence: +-------- +const + SEEK_SET = 0; { Seek from beginning of file. } + SEEK_CUR = 1; { Seek from current position. } + SEEK_END = 2; { Seek from end of file. } + +{ Old BSD names for the same constants; just for compatibility. } + L_SET = SEEK_SET; + L_INCR = SEEK_CUR; + L_XTND = SEEK_END; +*) + + +{$ifdef FPC} +const + F_RDLCK = 0; + F_WRLCK = 1; + F_UNLCK = 2; + F_EXLCK = 4; + F_SHLCK = 8; + + LOCK_SH = 1; + LOCK_EX = 2; + LOCK_NB = 4; + LOCK_UN = 8; + + LOCK_MAND = 32; + LOCK_READ = 64; + LOCK_WRITE = 128; + LOCK_RW = 192; + + EACCES = ESysEACCES; + EAGAIN = ESysEAGAIN; +{$endif} + +function LockFile(hFile: THandle; dwFileOffsetLow, dwFileOffsetHigh: DWORD; nNumberOfBytesToLockLow, nNumberOfBytesToLockHigh: DWORD): BOOL; +var + FLockInfo: {$ifdef FPC}BaseUnix.FLock{$else}TFLock{$endif}; + FLastError: Cardinal; +begin + FLockInfo.l_type := F_WRLCK; + FLockInfo.l_whence := SEEK_SET; + FLockInfo.l_start := dwFileOffsetLow; + FLockInfo.l_len := nNumberOfBytesToLockLow; + FLockInfo.l_pid := {$ifdef FPC}fpgetpid{$else}getpid{$endif}(); + Result := {$ifdef FPC}fpfcntl{$else}fcntl{$endif}(hFile, F_SETLK, FLockInfo) <> -1; + if not Result then + begin + FLastError := GetLastError(); + if (FLastError = EACCES) or (FLastError = EAGAIN) then + SetLastError(ERROR_LOCK_VIOLATION) + else + Result := True; // If errno is ENOLCK or EINVAL + end; +end; + +function UnlockFile(hFile: THandle; dwFileOffsetLow, dwFileOffsetHigh: DWORD; nNumberOfBytesToUnlockLow, nNumberOfBytesToUnlockHigh: DWORD): BOOL; +var + FLockInfo: {$ifdef FPC}BaseUnix.FLock{$else}TFLock{$endif}; +begin + FLockInfo.l_type := F_UNLCK; + FLockInfo.l_whence := SEEK_SET; + FLockInfo.l_start := dwFileOffsetLow; + FLockInfo.l_len := nNumberOfBytesToUnLockLow; + FLockInfo.l_pid := {$ifdef FPC}fpgetpid{$else}getpid{$endif}(); + Result := {$ifdef FPC}fpfcntl{$else}fcntl{$endif}(hFile, F_SETLK, FLockInfo) <> -1; +end; + +procedure DateTimeToSystemTime(const DateTime: TDateTime; var SystemTime: TSystemTime); +begin + with SystemTime do + begin + DecodeDateFully(DateTime, wYear, wMonth, wDay, wDayOfWeek); + Dec(wDayOfWeek); + DecodeTime(DateTime, wHour, wMinute, wSecond, wMilliseconds); + end; +end; + +function SystemTimeToDateTime(const SystemTime: TSystemTime): TDateTime; +begin + with SystemTime do + begin + Result := EncodeDate(wYear, wMonth, wDay); + if Result >= 0 then + Result := Result + EncodeTime(wHour, wMinute, wSecond, wMilliSeconds) + else + Result := Result - EncodeTime(wHour, wMinute, wSecond, wMilliSeconds); + end; +end; + +procedure GetLocalTime(var lpSystemTime: TSystemTime); +begin + DateTimeToSystemTime(NOW, lpSystemTime); +end; + +function GetOEMCP: Cardinal; +begin +{$ifdef HUNGARIAN} + Result := 852; +{$else} + Result := $FFFFFFFF; +{$endif} +end; + +function GetACP: Cardinal; +begin +{$ifdef HUNGARIAN} + Result := 1250; +{$else} + Result := 1252; +{$endif} +end; + +{$ifdef HUNGARIAN} + +procedure OemHunHun(AnsiDst: PChar; cchDstLength: DWORD); +var + Count: DWORD; +begin + if Assigned(AnsiDst) and (cchDstLength<>0) then + begin + for Count:=0 to Pred(cchDstLength) do + begin + case AnsiDst^ of + #160: AnsiDst^:= #225; {á} + #143,#181: AnsiDst^:= #193; {Á} + #130: AnsiDst^:= #233; {é} + #144: AnsiDst^:= #201; {É} + #161: AnsiDst^:= #237; {í} + #141,#214: AnsiDst^:= #205; {Í} + #162: AnsiDst^:= #243; {ó} + #149,#224: AnsiDst^:= #211; {Ó} + #148: AnsiDst^:= #246; {ö} + #153: AnsiDst^:= #214; {Ö} + #147,#139: AnsiDst^:= #245; {õ} + #167,#138: AnsiDst^:= #213; {Õ} + #163: AnsiDst^:= #250; {ú} + #151,#233: AnsiDst^:= #218; {Ú} + #129: AnsiDst^:= #252; {ü} + #154: AnsiDst^:= #220; {Ü} + #150,#251: AnsiDst^:= #251; {û} + #152,#235: AnsiDst^:= #219; {Û} + end; + Inc(AnsiDst); + end; + end; +end; + +procedure AnsiHunHun(AnsiDst: PChar; cchDstLength: DWORD); +var + Count: DWORD; +begin + if Assigned(AnsiDst) and (cchDstLength<>0) then + begin + for Count:=0 to Pred(cchDstLength) do + begin + case AnsiDst^ of + #225: AnsiDst^:= #160; {á} + #193: AnsiDst^:= #181; {Á} + #233: AnsiDst^:= #130; {é} + #201: AnsiDst^:= #144; {É} + #237: AnsiDst^:= #161; {í} + #205: AnsiDst^:= #214; {Í} + #243: AnsiDst^:= #162; {ó} + #211: AnsiDst^:= #224; {Ó} + #246: AnsiDst^:= #148; {ö} + #214: AnsiDst^:= #153; {Ö} + #245: AnsiDst^:= #139; {õ} + #213: AnsiDst^:= #138; {Õ} + #250: AnsiDst^:= #163; {ú} + #218: AnsiDst^:= #233; {Ú} + #252: AnsiDst^:= #129; {ü} + #220: AnsiDst^:= #154; {Ü} + #251: AnsiDst^:= #251; {û} + #219: AnsiDst^:= #235; {Û} + end; + Inc(AnsiDst); + end; + end; +end; + +{$endif} + +function OemToChar(lpszSrc: PChar; lpszDst: PChar): BOOL; +begin + if lpszDst <> lpszSrc then + StrCopy(lpszDst, lpszSrc); + Result := true; +end; + +function CharToOem(lpszSrc: PChar; lpszDst: PChar): BOOL; +begin + if lpszDst <> lpszSrc then + StrCopy(lpszDst, lpszSrc); + Result := true; +end; + +function OemToCharBuff(lpszSrc: PChar; lpszDst: PChar; cchDstLength: DWORD): BOOL; +begin + if lpszDst <> lpszSrc then + StrLCopy(lpszDst, lpszSrc, cchDstLength); +{$ifdef HUNGARIAN} + OemHunHun(lpszDst, cchDstLength); +{$endif} + Result := true; +end; + +function CharToOemBuff(lpszSrc: PChar; lpszDst: PChar; cchDstLength: DWORD): BOOL; +begin + if lpszDst <> lpszSrc then + StrLCopy(lpszDst, lpszSrc, cchDstLength); +{$ifdef HUNGARIAN} + AnsiHunHun(lpszDst, cchDstLength); +{$endif} + Result := true; +end; + +function MultiByteToWideChar(CodePage: DWORD; dwFlags: DWORD; const lpMultiByteStr: LPCSTR; cchMultiByte: Integer; lpWideCharStr: LPWSTR; cchWideChar: Integer): Integer; +var + TempA: AnsiString; + TempW: WideString; +begin + TempA := String(lpMultiByteStr^); + TempW := TempA; + Result := Length(TempW); + System.Move(TempW, lpWideCharStr^, Result); +end; + +function WideCharToMultiByte(CodePage: DWORD; dwFlags: DWORD; lpWideCharStr: LPWSTR; cchWideChar: Integer; lpMultiByteStr: LPSTR; cchMultiByte: Integer; lpDefaultChar: LPCSTR; lpUsedDefaultChar: PBOOL): Integer; +var + TempA: AnsiString; + TempW: WideString; +begin + TempW := WideString(lpWideCharStr^); + TempA := TempW; + Result := Length(TempA); + System.Move(TempA, lpMultiByteStr^, Result); +end; + +function CompareString(Locale: LCID; dwCmpFlags: DWORD; lpString1: PChar; cchCount1: Integer; lpString2: PChar; cchCount2: Integer): Integer; +begin + Result := StrLComp(lpString1, lpString2, cchCount1) + 2; + if Result > 2 then Result := 3; + if Result < 2 then Result := 1; +end; + +function EnumSystemCodePages(lpCodePageEnumProc: TFNCodepageEnumProc; dwFlags: DWORD): BOOL; +begin + Result := True; +end; + +function EnumSystemLocales(lpLocaleEnumProc: TFNLocaleEnumProc; dwFlags: DWORD): BOOL; +begin + Result := True; +end; + +function GetUserDefaultLCID: LCID; +begin + Result := LANG_ENGLISH or (SUBLANG_ENGLISH_UK shl 10); +end; + +{$ifdef FPC} + +function GetLastError: Integer; +begin + Result := FpGetErrno; +end; + +procedure SetLastError(Value: Integer); +begin + FpSetErrno(Value); +end; + +{$endif} +{$endif} + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/formatfunc.pas b/mseide-msegui/lib/common/fpccompatibility/formatfunc.pas new file mode 100644 index 0000000..66ced7a --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/formatfunc.pas @@ -0,0 +1,470 @@ +{ + ********************************************************************* + Copyright (C) 1997, 1998 Gertjan Schouten + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + ********************************************************************** + + System Utilities For Free Pascal +} + +unit formatfunc; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + mseformatstr,msetypes; + +function unicodeformat (const fmt : unicodestring; const args : array of const; + const formatsettings: tformatsettingsmse) : msestring; + +implementation +uses + sysutils,sysconst,msefloattostr; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +Const + feInvalidFormat = 1; + feMissingArgument = 2; + feInvalidArgIndex = 3; + +Procedure DoFormatError (ErrCode : Longint;const fmt:ansistring); +Var + S : String; +begin + //!! must be changed to contain format string... + S:=fmt; + Case ErrCode of + feInvalidFormat : raise EConvertError.Createfmt(SInvalidFormat,[s]); + feMissingArgument : raise EConvertError.Createfmt(SArgumentMissing,[s]); + feInvalidArgIndex : raise EConvertError.Createfmt(SInvalidArgIndex,[s]); + end; +end; + +function floattostrf(value: double; format: tfloatformat; + precision, digits: integer; + const formatsettings: tformatsettingsmse): msestring; + //todo: digits, currency format and the like +var + m1: floatstringmodety; + sep1: msechar; +begin + sep1:= #0; + m1:= fsm_default; + case format of + ffExponent: begin + m1:= fsm_sci; + end; + ffFixed: begin + m1:= fsm_fix; + end; + ffNumber,ffCurrency: begin + m1:= fsm_fix; + sep1:= formatsettings.thousandseparator; + end; + end; + result:= doubletostring(value,precision,m1,formatsettings.decimalseparator, + sep1); +end; + +{$macro on} +{$define INWIDEFORMAT} +{$define TFormatString:=unicodestring} +{$define TFormatChar:=unicodechar} + +Function UnicodeFormat (Const Fmt : UnicodeString; const Args : Array of const; + Const FormatSettings: TFormatSettingsmse) : UnicodeString; + +Var ChPos,OldPos,ArgPos,DoArg,Len : SizeInt; + Hs,ToAdd : TFormatString; + Index : SizeInt; + Width,Prec : Longint; + Left : Boolean; + Fchar : char; + vq : qword; + + { + ReadFormat reads the format string. It returns the type character in + uppercase, and sets index, Width, Prec to their correct values, + or -1 if not set. It sets Left to true if left alignment was requested. + In case of an error, DoFormatError is called. + } + + Function ReadFormat : Char; + + Var Value : longint; + + Procedure ReadInteger; + + var + Code: Word; + ArgN: SizeInt; + begin + If Value<>-1 then exit; // Was already read. + OldPos:=ChPos; + While (ChPos<=Len) and + (Fmt[ChPos]<='9') and (Fmt[ChPos]>='0') do inc(ChPos); + If ChPos>len then + DoFormatError(feInvalidFormat,ansistring(Fmt)); + If Fmt[ChPos]='*' then + begin + + if Index=-1 then + ArgN:=Argpos + else + begin + ArgN:=Index; + Inc(Index); + end; + + If (ChPos>OldPos) or (ArgN>High(Args)) then + DoFormatError(feInvalidFormat,ansistring(Fmt)); + + ArgPos:=ArgN+1; + + case Args[ArgN].Vtype of + vtInteger: Value := Args[ArgN].VInteger; + vtInt64: Value := Args[ArgN].VInt64^; + vtQWord: Value := Args[ArgN].VQWord^; + else + DoFormatError(feInvalidFormat,ansistring(Fmt)); + end; + Inc(ChPos); + end + else + begin + If (OldPos0 then DoFormatError (feInvalidFormat,ansistring(Fmt)); + end + else + Value:=-1; + end; + end; + + Procedure ReadIndex; + + begin + If Fmt[ChPos]<>':' then + ReadInteger + else + value:=0; // Delphi undocumented behaviour, assume 0, #11099 + If Fmt[ChPos]=':' then + begin + If Value=-1 then DoFormatError(feMissingArgument,ansistring(Fmt)); + Index:=Value; + Value:=-1; + Inc(ChPos); + end; +{$ifdef fmtdebug} + Log ('Read index'); +{$endif} + end; + + Procedure ReadLeft; + + begin + If Fmt[ChPos]='-' then + begin + left:=True; + Inc(ChPos); + end + else + Left:=False; +{$ifdef fmtdebug} + Log ('Read Left'); +{$endif} + end; + + Procedure ReadWidth; + + begin + ReadInteger; + If Value<>-1 then + begin + Width:=Value; + Value:=-1; + end; +{$ifdef fmtdebug} + Log ('Read width'); +{$endif} + end; + + Procedure ReadPrec; + + begin + If Fmt[ChPos]='.' then + begin + inc(ChPos); + ReadInteger; + If Value=-1 then + Value:=0; + prec:=Value; + end; +{$ifdef fmtdebug} + Log ('Read precision'); +{$endif} + end; + +{$ifdef INWIDEFORMAT} + var + FormatChar : TFormatChar; +{$endif INWIDEFORMAT} + + begin +{$ifdef fmtdebug} + Log ('Start format'); +{$endif} + Index:=-1; + Width:=-1; + Prec:=-1; + Value:=-1; + inc(ChPos); + If Fmt[ChPos]='%' then + begin + Result:='%'; + exit; // VP fix + end; + ReadIndex; + ReadLeft; + ReadWidth; + ReadPrec; +{$ifdef INWIDEFORMAT} + FormatChar:=UpCase(UnicodeChar(Fmt[ChPos])); + if word(FormatChar)>255 then + ReadFormat:=#255 + else + ReadFormat:=FormatChar; +{$else INWIDEFORMAT} + ReadFormat:=Upcase(Fmt[ChPos]); +{$endif INWIDEFORMAT} +{$ifdef fmtdebug} + Log ('End format'); +{$endif} +end; + + +{$ifdef fmtdebug} +Procedure DumpFormat (C : char); +begin + Write ('Fmt : ',fmt:10); + Write (' Index : ',Index:3); + Write (' Left : ',left:5); + Write (' Width : ',Width:3); + Write (' Prec : ',prec:3); + Writeln (' Type : ',C); +end; +{$endif} + + +function Checkarg (AT : SizeInt;err:boolean):boolean; +{ + Check if argument INDEX is of correct type (AT) + If Index=-1, ArgPos is used, and argpos is augmented with 1 + DoArg is set to the argument that must be used. +} +begin + result:=false; + if Index=-1 then + DoArg:=Argpos + else + DoArg:=Index; + ArgPos:=DoArg+1; + If (Doarg>High(Args)) or (Args[Doarg].Vtype<>AT) then + begin + if err then + DoFormatError(feInvalidArgindex,ansistring(Fmt)); + dec(ArgPos); + exit; + end; + result:=true; +end; + +begin + Result:=''; + Len:=Length(Fmt); + ChPos:=1; + OldPos:=1; + ArgPos:=0; + While ChPos<=len do + begin + While (ChPos<=Len) and (Fmt[ChPos]<>'%') do + inc(ChPos); + If ChPos>OldPos Then + Result:=Result+Copy(Fmt,OldPos,ChPos-Oldpos); + If ChPos'-' then + ToAdd:=TFormatString(StringOfChar('0',Index))+ToAdd + else + // + 1 to accomodate for - sign in length !! + Insert(TFormatString(StringOfChar('0',Index+1)),toadd,2); + end; + 'U' : begin + if Checkarg(vtinteger,false) then + Str(cardinal(Args[Doarg].VInteger),ToAdd) + else if CheckArg(vtInt64,false) then + Str(qword(Args[DoArg].VInt64^),toadd) + else if CheckArg(vtQWord,true) then + Str(Args[DoArg].VQWord^,toadd); + Width:=Abs(width); + Index:=Prec-Length(ToAdd); + ToAdd:=TFormatString(StringOfChar('0',Index))+ToAdd + end; +{$ifndef FPUNONE} + 'E' : begin + if CheckArg(vtCurrency,false) then + ToAdd:=TFormatString(FloatToStrF(Args[doarg].VCurrency^,ffexponent,Prec,3,FormatSettings)) + else if CheckArg(vtExtended,true) then + ToAdd:=TFormatString(FloatToStrF(Args[doarg].VExtended^,ffexponent,Prec,3,FormatSettings)); + end; + 'F' : begin + if CheckArg(vtCurrency,false) then + ToAdd:=TFormatString(FloatToStrF(Args[doarg].VCurrency^,ffFixed,9999,Prec,FormatSettings)) + else if CheckArg(vtExtended,true) then + ToAdd:=TFormatString(FloatToStrF(Args[doarg].VExtended^,ffFixed,9999,Prec,FormatSettings)); + end; + 'G' : begin + if CheckArg(vtCurrency,false) then + ToAdd:=TFormatString(FloatToStrF(Args[doarg].VCurrency^,ffGeneral,Prec,3,FormatSettings)) + else if CheckArg(vtExtended,true) then + ToAdd:=TFormatString(FloatToStrF(Args[doarg].VExtended^,ffGeneral,Prec,3,FormatSettings)); + end; + 'N' : begin + if CheckArg(vtCurrency,false) then + ToAdd:=TFormatString(FloatToStrF(Args[doarg].VCurrency^,ffNumber,9999,Prec,FormatSettings)) + else if CheckArg(vtExtended,true) then + ToAdd:=TFormatString(FloatToStrF(Args[doarg].VExtended^,ffNumber,9999,Prec,FormatSettings)); + end; + 'M' : begin + if CheckArg(vtExtended,false) then + ToAdd:=TFormatString(FloatToStrF(Args[doarg].VExtended^,ffCurrency,9999,Prec,FormatSettings)) + else if CheckArg(vtCurrency,true) then + ToAdd:=TFormatString(FloatToStrF(Args[doarg].VCurrency^,ffCurrency,9999,Prec,FormatSettings)); + end; +{$else} + 'E','F','G','N','M': + RunError(207); +{$endif} + 'S' : begin + if CheckArg(vtString,false) then + hs:=TFormatString(Args[doarg].VString^) + else + if CheckArg(vtChar,false) then + hs:=TFormatString(Args[doarg].VChar) + else + if CheckArg(vtPChar,false) then + hs:=TFormatString(Args[doarg].VPChar) + else + if CheckArg(vtPWideChar,false) then + hs:=TFormatString(WideString(Args[doarg].VPWideChar)) + else + if CheckArg(vtWideChar,false) then + hs:=TFormatString(WideString(Args[doarg].VWideChar)) + else + if CheckArg(vtWidestring,false) then + hs:=TFormatString(WideString(Args[doarg].VWideString)) + else + if CheckArg(vtAnsiString,false) then + hs:=TFormatString(ansistring(Args[doarg].VAnsiString)) + else + if CheckArg(vtUnicodeString,false) then + hs:=TFormatString(UnicodeString(Args[doarg].VUnicodeString)) + else + if CheckArg(vtVariant,true) then + hs:=Args[doarg].VVariant^; + Index:=Length(hs); + If (Prec<>-1) and (Index>Prec) then + Index:=Prec; + ToAdd:=Copy(hs,1,Index); + end; + 'P' : Begin + CheckArg(vtpointer,true); + ToAdd:=TFormatString(HexStr(ptruint(Args[DoArg].VPointer),sizeof(Ptruint)*2)); + // Insert ':'. Is this needed in 32 bit ? No it isn't. + // Insert(':',ToAdd,5); + end; + 'X' : begin + if Checkarg(vtinteger,false) then + begin + vq:=Cardinal(Args[Doarg].VInteger); + index:=16; + end + else + if CheckArg(vtQWord, false) then + begin + vq:=Qword(Args[DoArg].VQWord^); + index:=31; + end + else + begin + CheckArg(vtInt64,true); + vq:=Qword(Args[DoArg].VInt64^); + index:=31; + end; + If Prec>index then + ToAdd:=TFormatString(HexStr(int64(vq),index)) + else + begin + // determine minimum needed number of hex digits. + Index:=1; + While (qWord(1) shl (Index*4)<=vq) and (index<16) do + inc(Index); + If Index>Prec then + Prec:=Index; + ToAdd:=TFormatString(HexStr(int64(vq),Prec)); + end; + end; + '%': ToAdd:='%'; + end; + If Width<>-1 then + If Length(ToAdd) $ffff then + result := $ffff + else + result := temp; +end; + +(* +type + TColorBits = array [0..3] of TColorData; + // 0:alpha, 1:red, 2:green, 3:blue + TShiftBits = array [0..3] of shortint; + +const + ColorBits : array[cfRGB15..cfABGR64] of TColorBits = ( + // alpha red green blue + {cfRGB15} ($00000000, $00007C00, $000003E0, $0000001F), + {cfRGB16} ($00000000, $00007C00, $000003E0, $0000001F), + {cfRGB24} ($00000000, $00FF0000, $0000FF00, $000000FF), + {cfRGB32} ($00000000, $00FF0000, $0000FF00, $000000FF), + {cfRGB48} ($00000000, $FFFF0000, $FFFF0000, $0000FFFF), + // shl 16 + {cfRGBA8} ($00000003, $000000C0, $00000030, $0000000C), + {cfRGBA16}($0000000F, $0000F000, $00000F00, $000000F0), + {cfRGBA32}($000000FF, $FF000000, $00FF0000, $0000FF00), + {cfRGBA64}($0000FFFF, $FFFF0000, $FFFF0000, $FFFF0000), + // shl 32 shl 16 + {cfBGR15} ($00000000, $0000001F, $000003E0, $00007C00), + {cfBGR16} ($00000000, $0000001F, $000003E0, $00007C00), + {cfBGR24} ($00000000, $000000FF, $0000FF00, $00FF0000), + {cfBGR32} ($00000000, $000000FF, $0000FF00, $00FF0000), + {cfBGR48} ($00000000, $0000FFFF, $FFFF0000, $FFFF0000), + // shl 16 + {cfABGR8} ($000000C0, $00000003, $0000000C, $00000030), + {cfABGR16}($0000F000, $0000000F, $000000F0, $00000F00), + {cfABGR32}($FF000000, $000000FF, $0000FF00, $00FF0000), + {cfABGR64}($FFFF0000, $0000FFFF, $FFFF0000, $FFFF0000) + // shl 32 shl 16 + ); + ShiftBits : array[cfRGB15..cfABGR64] of TShiftBits = ( // <0:shl, >0:shr + {cfRGB15} ( 0, -1, -6, -11), + {cfRGB16} ( 0, -1, -6, -11), + {cfRGB24} ( 0, 8, 0, -8), + {cfRGB32} ( 0, 8, 0, -8), + {cfRGB48} ( 0, 32, 16, 0), + {cfRGBA8} (-14, -8, -10, -12), + {cfRGBA16}(-12, 0, -4, -8), + {cfRGBA32}( -8, 16, 8, 0), + {cfRGBA64}( 0, 48, 32, 16), + {cfBGR15} ( 0, -11, -6, -1), + {cfBGR16} ( 0, -11, -6, -1), + {cfBGR24} ( 0, -8, 0, 8), + {cfBGR32} ( 0, -8, 0, 8), + {cfBGR48} ( 0, 0, 16, 32), + {cfBGRA8} ( -8, -14, -12, -10), + {cfBGRA16}( 0, -12, -8, -4), + {cfBGRA32}( 16, -8, 0, 8), + {cfBGRA64}( 48, 0, 16, 32) + ); + Bitdepths : array[cfRGB15..cfABGR64] of byte= + (5,5,8,8,16, 2,4,8,16, 5,5,8,8,16, 2,4,8,16); + +function EnlargeColor (data:TColorData;CFmt:TColorFormat;component:byte):word; +var w : word; + i : TColorData; + s : shortint; +begin + i := data and ColorBits[CFmt,component]; + s := ShiftBits[CFmt,component]; + if s = 0 then + w := i + else if s < 0 then + w := i shl -s + else + w := i shr s; + result := FillOtherBits (w ,BitDepths[CFmt]); +end; + +function ConvertColor (const From : TColorData; FromFmt:TColorFormat) : TFPColor; + function SetGrayScale (value : word) : TFPColor; + begin + with result do + begin + red := Value; + green := value; + blue := Value; + end; + end; + function SetGrayScaleA (value : word) : TFPColor; + begin + result := SetGrayScale (value); + result.alpha := alphaOpaque; + end; +var m : qword; +begin + case FromFmt of + cfMono : result := SetGrayScaleA (ShiftAndFill(From,1)); + cfGray2 : result := SetGrayScaleA (ShiftAndFill(From,2)); + cfGray4 : result := SetGrayScaleA (ShiftAndFill(From,4)); + cfGray8 : result := SetGrayScaleA (ShiftAndFill(From,8)); + cfGray16 : result := SetGrayScaleA (From); + cfGray24 : result := SetGrayScaleA ((From and $00FFFF00) shr 8); + cfGrayA8 : + begin + result := SetGrayScale (FillOtherBits((From and $000000F0) shl 8,4)); + result.alpha := ShiftAndFill((From and $0000000F),4); + end; + cfGrayA16 : + begin + result := SetGrayScale (FillOtherBits((From and $0000FF00),8)); + result.alpha := ShiftAndFill((From and $000000FF),8); + end; + cfGrayA32 : + begin + result := SetGrayScale ((From and $FFFF0000) shr 16); + result.alpha := (From and $0000FFFF); + end; + cfRGB15,cfRGB16,cfRGB24,cfRGB32,cfRGB48, + cfBGR15,cfBGR16,cfBGR24,cfBGR32,cfBGR48 : + begin + result.alpha := AlphaOpaque; + result.red := EnlargeColor(From, FromFmt, 1); + result.green := EnlargeColor(From, FromFmt, 2); + result.blue := EnlargeColor(From, FromFmt, 3); + end; + cfRGBA8,cfRGBA16,cfRGBA32,cfRGBA64, + cfABGR8,cfABGR16,cfABGR32,cfABGR64 : + begin + result.alpha := EnlargeColor(From, FromFmt, 0); + result.red := EnlargeColor(From, FromFmt, 1); + result.green := EnlargeColor(From, FromFmt, 2); + result.blue := EnlargeColor(From, FromFmt, 3); + end; + end; +end; + +function ConvertColor (const From : TDeviceColor) : TFPColor; +begin + result := ConvertColor (From.data, From.Fmt) +end; + +const BitMasks : array[1..32] of longword = + ($8000000, $C000000, $E000000, $F000000, + $F800000, $FC00000, $FE00000, $FF00000, + $FF80000, $FFC0000, $FFE0000, $FFF0000, + $FFF8000, $FFFC000, $FFFE000, $FFFF000, + $FFFF800, $FFFFC00, $FFFFE00, $FFFFF00, + $FFFFF80, $FFFFFC0, $FFFFFE0, $FFFFFF0, + $FFFFFF8, $FFFFFFC, $FFFFFFE, $FFFFFFF, + $FFFFFFF, $FFFFFFF, $FFFFFFF, $FFFFFFF); + +procedure PrepareBitMasks; +{ Putting the correct bits in the array (problem with constants in compiler 1.0)} +var r : integer; +begin + for r := 1 to 32 do + BitMasks[r] := BitMasks[r] shl 4; + inc (BitMasks[29], $8); + inc (BitMasks[30], $C); + inc (BitMasks[31], $E); + inc (BitMasks[32], $F); +end; + +function CalculateGray (const c : TFPcolor; Bits:byte) : TColorData; +var temp : longword; +begin + with GrayConvMatrix do + temp := round(red*c.red + green*c.green + blue*c.blue); + result := temp; + //temp := temp + (result shl 16); + //result := temp and BitMasks[Bits]; + {if not (c = colBlack) then + with c do + //writeln ('red:',red,' - green:',green,' - blue:',blue, ' : result=',result); + writeln (format('red:%4x - green:%4x - blue:%4x => result:%4x',[integer(red), + integer(green),integer(blue),integer(result)]));} +end; + +function CalculateGrayA (const c : TFPcolor; Bits:byte) : TColorData; +var r : longword; + d : byte; +begin + d := bits div 2; + r := CalculateGray (c, d); + result := r shl d; + r := c.alpha shr (16-d); + result := result or r; +end; + +function ConvertColorToData (const From : TFPColor; Fmt : TColorFormat) : TColorData; +var sb : TShiftBits; + cb : TColorBits; + function MakeSample (Value:word; ToShift:shortint; ToUse:TColorData) : TColorData; + var sh : word; + begin + result := Value; + if ToShift >= 0 then + begin + sh := ToShift; // if not converting first to word, there will be a + result := result shl Sh; // color shift + end + else + begin + sh := -ToShift; + result := result shr Sh; + end; + result := result and ToUse; + end; +begin + case Fmt of + cfMono : result := CalculateGray (From,1); + cfGray2 : result := CalculateGray (From,2); + cfGray4 : result := CalculateGray (From,4); + cfGray8 : result := CalculateGray (From,8); + cfGray16 : result := CalculateGray (From,16); + cfGray24 : result := CalculateGray (From,24); + cfGrayA8 : result := CalculateGrayA (From, 8); + cfGrayA16 : result := CalculateGrayA (From, 16); + cfGrayA32 : result := CalculateGrayA (From, 32); + cfRGB15,cfRGB16,cfRGB24,cfRGB32,cfRGB48, + cfBGR15,cfBGR16,cfBGR24,cfBGR32,cfBGR48 : + begin + sb := ShiftBits[Fmt]; + cb := ColorBits[Fmt]; + result := MakeSample(From.blue, sb[3], cb[3]) or + MakeSample(From.red, sb[1], cb[1]) or + MakeSample(From.green, sb[2], cb[2]); + {$ifdef FPC_Debug_Image} + with From do + writeln (red,',',green,',',blue,',',result); + end; + {$endif} + cfRGBA8,cfRGBA16,cfRGBA32,cfRGBA64, + cfABGR8,cfABGR16,cfABGR32,cfABGR64 : + begin + sb := ShiftBits[Fmt]; + cb := ColorBits[Fmt]; + result := MakeSample(From.alpha, sb[0], cb[0]) or + MakeSample(From.red, sb[1], cb[1]) or + MakeSample(From.green, sb[2], cb[2]) or + MakeSample(From.blue, sb[3], cb[3]); + end; + end; +end; + +function ConvertColor (const From : TFPColor; Fmt : TColorFormat) : TDeviceColor; +begin + result.Fmt := Fmt; + result.data := convertColorToData(From, Fmt); +end; + +function ConvertColorToData (const From : TDeviceColor; Fmt : TColorFormat) : TColorData; +var c : TFPColor; +begin + c := ConvertColor (From); + result := ConvertColorToData (c, Fmt); +end; + +function ConvertColor (const From : TDeviceColor; Fmt : TColorFormat) : TDeviceColor; +begin + result.Fmt := Fmt; + result.data := ConvertColorToData (From, Fmt); +end; +*) + +function AlphaBlend(color1, color2: TFPColor): TFPColor; +var + factor: single; +begin + if color2.alpha = $ffff then + Result := color2 + else + begin + factor := (color1.alpha / $ffff) * (1 - color2.alpha / $ffff); + + Result.red := Round(color1.red * factor + color2.red * color2.alpha / $ffff); + Result.green := Round(color1.green * factor + color2.green * color2.alpha / $ffff); + Result.blue := Round(color1.blue * factor + color2.blue * color2.alpha / $ffff); + Result.alpha := Round(factor * $ffff + color2.alpha); + end; +end; + +function CompareColors(const Color1, Color2: TFPColor): integer; +begin + Result:=integer(Color1.Red)-integer(Color2.Red); + if Result<>0 then exit; + Result:=integer(Color1.Green)-integer(Color2.Green); + if Result<>0 then exit; + Result:=integer(Color1.Blue)-integer(Color2.Blue); + if Result<>0 then exit; + Result:=integer(Color1.Alpha)-integer(Color2.Alpha); +end; + diff --git a/mseide-msegui/lib/common/fpccompatibility/fpcolors.inc b/mseide-msegui/lib/common/fpccompatibility/fpcolors.inc new file mode 100644 index 0000000..eb4a1d1 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpcolors.inc @@ -0,0 +1,49 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 2003 by the Free Pascal development team + + Color definitions and functions. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + **********************************************************************} +const + BytesNeeded : array[TColorFormat] of byte = + (1,1,1,1,2,3,1,2,4,2,2,3,4,6,1,2,4,8,2,2,3,4,6,1,2,4,8); + + alphaTransparent = $0000; + alphaOpaque = $FFFF; + colTransparent: TFPColor = (Red: $0000; Green: $0000; Blue: $0000; Alpha: alphaTransparent); + colBlack : TFPColor = (Red: $0000; Green: $0000; Blue: $0000; Alpha: alphaOpaque); + colBlue : TFPColor = (Red: $0000; Green: $0000; Blue: $ffff; Alpha: alphaOpaque); + colGreen : TFPColor = (Red: $0000; Green: $ffff; Blue: $0000; Alpha: alphaOpaque); + colCyan : TFPColor = (Red: $0000; Green: $ffff; Blue: $ffff; Alpha: alphaOpaque); + colRed : TFPColor = (Red: $ffff; Green: $0000; Blue: $0000; Alpha: alphaOpaque); + colMagenta : TFPColor = (Red: $ffff; Green: $0000; Blue: $ffff; Alpha: alphaOpaque); + colYellow : TFPColor = (Red: $ffff; Green: $ffff; Blue: $0000; Alpha: alphaOpaque); + colWhite : TFPColor = (Red: $ffff; Green: $ffff; Blue: $ffff; Alpha: alphaOpaque); + colGray : TFPColor = (Red: $8000; Green: $8000; Blue: $8000; Alpha: alphaOpaque); + colLtGray : TFPColor = (Red: $c000; Green: $c000; Blue: $c000; Alpha: alphaOpaque); + colDkGray : TFPColor = (Red: $4000; Green: $4000; Blue: $4000; Alpha: alphaOpaque); + colDkBlue : TFPColor = (Red: $0000; Green: $0000; Blue: $8000; Alpha: alphaOpaque); + colDkGreen : TFPColor = (Red: $0000; Green: $8000; Blue: $0000; Alpha: alphaOpaque); + colDkCyan : TFPColor = (Red: $0000; Green: $8000; Blue: $8000; Alpha: alphaOpaque); + colDkRed : TFPColor = (Red: $8000; Green: $0000; Blue: $0000; Alpha: alphaOpaque); + colDkMagenta : TFPColor = (Red: $8000; Green: $0000; Blue: $8000; Alpha: alphaOpaque); + colDkYellow : TFPColor = (Red: $8000; Green: $8000; Blue: $0000; Alpha: alphaOpaque); + colMaroon : TFPColor = (Red: $8000; Green: $0000; Blue: $0000; Alpha: alphaOpaque); + colLtGreen : TFPColor = (Red: $0000; Green: $8000; Blue: $0000; Alpha: alphaOpaque); + colOlive : TFPColor = (Red: $8000; Green: $8000; Blue: $0000; Alpha: alphaOpaque); + colNavy : TFPColor = (Red: $0000; Green: $0000; Blue: $8000; Alpha: alphaOpaque); + colPurple : TFPColor = (Red: $8000; Green: $0000; Blue: $8000; Alpha: alphaOpaque); + colTeal : TFPColor = (Red: $0000; Green: $8000; Blue: $8000; Alpha: alphaOpaque); + colSilver : TFPColor = (Red: $c000; Green: $c000; Blue: $c000; Alpha: alphaOpaque); + colLime : TFPColor = (Red: $0000; Green: $ffff; Blue: $0000; Alpha: alphaOpaque); + colFuchsia : TFPColor = (Red: $ffff; Green: $0000; Blue: $ffff; Alpha: alphaOpaque); + colAqua : TFPColor = (Red: $0000; Green: $ffff; Blue: $ffff; Alpha: alphaOpaque); + diff --git a/mseide-msegui/lib/common/fpccompatibility/fpcompactimg.inc b/mseide-msegui/lib/common/fpccompatibility/fpcompactimg.inc new file mode 100644 index 0000000..ec0b81b --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpcompactimg.inc @@ -0,0 +1,602 @@ +{%MainUnit fpimage.pp} +{ + This file is part of the Free Pascal run time library. + Copyright (c) 2012 by the Free Pascal development team + + Compact images (images with less than 64-bit depth) support, by Mattias Gaertner + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + **********************************************************************} +//modified 2013 by MArtin Schreiber + +function GetFPCompactImgDesc(Gray: boolean; Depth: word; HasAlpha: boolean + ): TFPCompactImgDesc; +begin + Result.Gray:=Gray; + Result.Depth:=Depth; + Result.HasAlpha:=HasAlpha; +end; + +function GetFPCompactImgClass(const Desc: TFPCompactImgDesc): TFPCompactImgBaseClass; +begin + if Desc.Gray then begin + if Desc.HasAlpha then begin + // gray, alpha + if Desc.Depth<=8 then + Result:=TFPCompactImgGrayAlpha8Bit + else + Result:=TFPCompactImgGrayAlpha16Bit; + end else begin + // gray, no alpha + if Desc.Depth<=8 then + Result:=TFPCompactImgGray8Bit + else + Result:=TFPCompactImgGray16Bit; + end; + end else begin + // RGB + if Desc.HasAlpha then begin + // RGB, alpha + if Desc.Depth<=8 then + Result:=TFPCompactImgRGBA8Bit + else + Result:=TFPCompactImgRGBA16Bit; + end else begin + // RGB, no alpha + if Desc.Depth<=8 then + Result:=TFPCompactImgRGB8Bit + else + Result:=TFPCompactImgRGB16Bit; + end; + end; +end; + +function CreateFPCompactImg(const Desc: TFPCompactImgDesc; Width, Height: integer + ): TFPCustomImage; +var + ImgClass: TFPCompactImgBaseClass; +begin + ImgClass:=GetFPCompactImgClass(Desc); + Result:=ImgClass.Create(Width,Height); +end; + +function CreateCompatibleFPCompactImg(Img: TFPCustomImage; Width, Height: integer + ): TFPCustomImage; +begin + if Img is TFPCompactImgBase then + Result:=CreateFPCompactImg(TFPCompactImgBase(Img).Desc,Width,Height) + else + Result:=CreateFPCompactImg(GetMinimumPTDesc(Img),Width,Height); +end; + +function CreateCompatibleFPCompactImgWithAlpha(Img: TFPCustomImage; Width, + Height: integer): TFPCustomImage; +var + Desc: TFPCompactImgDesc; +begin + if Img is TFPCompactImgBase then + Desc:=TFPCompactImgBase(Img).Desc + else + Desc:=GetMinimumPTDesc(Img); + Desc.HasAlpha:=true; + Result:=CreateFPCompactImg(Desc,Width,Height); +end; + +function GetMinimumPTDesc(Img: TFPCustomImage; FuzzyDepth: word = 4): TFPCompactImgDesc; +var + AllLoEqualsHi, AllLoAre0: Boolean; + FuzzyMaskLoHi: Word; + + procedure Need16Bit(c: word); {$ifdef FPC}inline;{$endif} + var + l: Byte; + begin + c:=c and FuzzyMaskLoHi; + l:=Lo(c); + AllLoAre0:=AllLoAre0 and (l=0); + AllLoEqualsHi:=AllLoEqualsHi and (l=Hi(c)); + end; + +var + TestGray: Boolean; + TestAlpha: Boolean; + Test16Bit: Boolean; + BaseImg: TFPCompactImgBase; + ImgDesc: TFPCompactImgDesc; + y: Integer; + x: Integer; + col: TFPColor; + FuzzyMaskWord: Word; + FuzzyOpaque: Word; +begin + TestGray:=true; + TestAlpha:=true; + Test16Bit:=FuzzyDepth<8; + Result.HasAlpha:=false; + Result.Gray:=true; + Result.Depth:=8; + if Img is TFPCompactImgBase then begin + BaseImg:=TFPCompactImgBase(Img); + ImgDesc:=BaseImg.Desc; + if ImgDesc.Depth<=8 then Test16Bit:=false; + if ImgDesc.Gray then TestGray:=false; + if not ImgDesc.HasAlpha then TestAlpha:=false; + end; + + if (not TestGray) and (not TestAlpha) and (not Test16Bit) then exit; + + FuzzyMaskWord:=Word($ffff) shl FuzzyDepth; + FuzzyOpaque:=alphaOpaque and FuzzyMaskWord; + FuzzyMaskLoHi:=Word(lo(FuzzyMaskWord))+(Word(lo(FuzzyMaskWord)) shl 8); + AllLoAre0:=true; + AllLoEqualsHi:=true; + for y:=0 to Img.Height-1 do begin + for x:=0 to Img.Width-1 do begin + col:=Img.Colors[x,y]; + if TestAlpha and ((col.alpha and FuzzyMaskWord)<>FuzzyOpaque) then begin + TestAlpha:=false; + Result.HasAlpha:=true; + if (not TestGray) and (not Test16Bit) then break; + end; + if TestGray + and ((col.red and FuzzyMaskWord)<>(col.green and FuzzyMaskWord)) + or ((col.red and FuzzyMaskWord)<>(col.blue and FuzzyMaskWord)) then begin + TestGray:=false; + Result.Gray:=false; + if (not TestAlpha) and (not Test16Bit) then break; + end; +{$warnings off} + if Test16Bit then begin + Need16Bit(col.red); + Need16Bit(col.green); + Need16Bit(col.blue); + Need16Bit(col.alpha); + if (not AllLoAre0) and (not AllLoEqualsHi) then begin + Test16Bit:=false; + Result.Depth:=16; + if (not TestAlpha) and (not TestGray) then break; + end; + end; + end; + end; +end; +{$warnings on} + +function GetMinimumFPCompactImg(Img: TFPCustomImage; FreeImg: boolean; + FuzzyDepth: word = 4): TFPCustomImage; +var + Desc: TFPCompactImgDesc; + ImgClass: TFPCompactImgBaseClass; + y: Integer; + x: Integer; +begin + Desc:=GetMinimumPTDesc(Img,FuzzyDepth); + ImgClass:=GetFPCompactImgClass(Desc); + if Img.ClassType=ImgClass then begin + result:= img; + exit; + end; + Result:=CreateFPCompactImg(Desc,Img.Width,Img.Height); + for y:=0 to Img.Height-1 do + for x:=0 to Img.Width-1 do + Result.Colors[x,y]:=Img.Colors[x,y]; + if FreeImg then + Img.Free; +end; + +function ColorRound (c : double) : word; +begin + if c > $FFFF then + result := $FFFF + else if c < 0.0 then + result := 0 + else + result := round(c); +end; + +{ TFPCompactImgGrayAlpha16Bit } + +function TFPCompactImgGrayAlpha16Bit.GetInternalColor(x, y: integer): TFPColor; +var + v: TFPCompactImgGrayAlpha16BitValue; +begin + v:= pFPCompactImgGrayAlpha16BitValueaty(FData)^[x+y*Width]; + Result.red:=v.g; + Result.green:=Result.red; + Result.blue:=Result.red; + Result.alpha:=v.a; +end; + +function TFPCompactImgGrayAlpha16Bit.GetInternalPixel(x, y: integer): integer; +begin + Result:=0; +end; + +procedure TFPCompactImgGrayAlpha16Bit.SetInternalColor(x, y: integer; + const Value: TFPColor); +var + v: TFPCompactImgGrayAlpha16BitValue; +begin + v.g:=Value.red; + v.a:=Value.alpha; + pFPCompactImgGrayAlpha16BitValueaty(FData)^[x+y*Width]:=v; +end; + +procedure TFPCompactImgGrayAlpha16Bit.SetInternalPixel(x, y: integer; Value: integer + ); +begin + +end; + +constructor TFPCompactImgGrayAlpha16Bit.Create(AWidth, AHeight: integer); +begin + FDesc:=GetFPCompactImgDesc(true,16,true); + inherited Create(AWidth, AHeight); +end; + +destructor TFPCompactImgGrayAlpha16Bit.Destroy; +begin + ReAllocMem(FData,0); + inherited Destroy; +end; + +procedure TFPCompactImgGrayAlpha16Bit.SetSize(AWidth, AHeight: integer); +begin + if (AWidth=Width) and (AHeight=Height) then exit; + ReAllocMem(FData,SizeOf(TFPCompactImgGrayAlpha16BitValue)*AWidth*AHeight); + inherited SetSize(AWidth, AHeight); +end; + +{ TFPCompactImgGrayAlpha8Bit } + +function TFPCompactImgGrayAlpha8Bit.GetInternalColor(x, y: integer): TFPColor; +var + v: TFPCompactImgGrayAlpha8BitValue; +begin + v:= pFPCompactImgGrayAlpha8BitValueaty(FData)^[x+y*Width]; + Result.red:=(v.g shl 8)+v.g; + Result.green:=Result.red; + Result.blue:=Result.red; + Result.alpha:=(v.a shl 8)+v.a; +end; + +function TFPCompactImgGrayAlpha8Bit.GetInternalPixel(x, y: integer): integer; +begin + Result:=0; +end; + +procedure TFPCompactImgGrayAlpha8Bit.SetInternalColor(x, y: integer; + const Value: TFPColor); +var + v: TFPCompactImgGrayAlpha8BitValue; +begin + v.g:=Value.red shr 8; + v.a:=Value.alpha shr 8; + pFPCompactImgGrayAlpha8BitValueaty(FData)^[x+y*Width]:=v; +end; + +procedure TFPCompactImgGrayAlpha8Bit.SetInternalPixel(x, y: integer; Value: integer + ); +begin + +end; + +constructor TFPCompactImgGrayAlpha8Bit.Create(AWidth, AHeight: integer); +begin + FDesc:=GetFPCompactImgDesc(true,8,true); + inherited Create(AWidth, AHeight); +end; + +destructor TFPCompactImgGrayAlpha8Bit.Destroy; +begin + ReAllocMem(FData,0); + inherited Destroy; +end; + +procedure TFPCompactImgGrayAlpha8Bit.SetSize(AWidth, AHeight: integer); +begin + if (AWidth=Width) and (AHeight=Height) then exit; + ReAllocMem(FData,SizeOf(TFPCompactImgGrayAlpha8BitValue)*AWidth*AHeight); + inherited SetSize(AWidth, AHeight); +end; + +{ TFPCompactImgGray16Bit } + +function TFPCompactImgGray16Bit.GetInternalColor(x, y: integer): TFPColor; +begin + Result.red:= pwordaty(FData)^[x+y*Width]; + Result.green:=Result.red; + Result.blue:=Result.red; + Result.alpha:=alphaOpaque; +end; + +function TFPCompactImgGray16Bit.GetInternalPixel(x, y: integer): integer; +begin + Result:=0; +end; + +procedure TFPCompactImgGray16Bit.SetInternalColor(x, y: integer; + const Value: TFPColor); +begin + pwordaty(FData)^[x+y*Width]:=Value.red; +end; + +procedure TFPCompactImgGray16Bit.SetInternalPixel(x, y: integer; Value: integer); +begin + +end; + +constructor TFPCompactImgGray16Bit.Create(AWidth, AHeight: integer); +begin + FDesc:=GetFPCompactImgDesc(true,16,false); + inherited Create(AWidth, AHeight); +end; + +destructor TFPCompactImgGray16Bit.Destroy; +begin + ReAllocMem(FData,0); + inherited Destroy; +end; + +procedure TFPCompactImgGray16Bit.SetSize(AWidth, AHeight: integer); +begin + if (AWidth=Width) and (AHeight=Height) then exit; + ReAllocMem(FData,SizeOf(Word)*AWidth*AHeight); + inherited SetSize(AWidth,AHeight); +end; + +{ TFPCompactImgGray8Bit } + +function TFPCompactImgGray8Bit.GetInternalColor(x, y: integer): TFPColor; +begin + Result.red:=pbyteaty(FData)^[x+y*Width]; + Result.red:=(Word(Result.red) shl 8)+Result.red; + Result.green:=Result.red; + Result.blue:=Result.red; + Result.alpha:=alphaOpaque; +end; + +function TFPCompactImgGray8Bit.GetInternalPixel(x, y: integer): integer; +begin + Result:=0; +end; + +procedure TFPCompactImgGray8Bit.SetInternalColor(x, y: integer; + const Value: TFPColor); +begin + pbyteaty(FData)^[x+y*Width]:=Value.red shr 8; +end; + +procedure TFPCompactImgGray8Bit.SetInternalPixel(x, y: integer; Value: integer); +begin + +end; + +constructor TFPCompactImgGray8Bit.Create(AWidth, AHeight: integer); +begin + FDesc:=GetFPCompactImgDesc(true,8,false); + inherited Create(AWidth, AHeight); +end; + +destructor TFPCompactImgGray8Bit.Destroy; +begin + ReAllocMem(FData,0); + inherited Destroy; +end; + +procedure TFPCompactImgGray8Bit.SetSize(AWidth, AHeight: integer); +begin + if (AWidth=Width) and (AHeight=Height) then exit; + ReAllocMem(FData,SizeOf(Byte)*AWidth*AHeight); + inherited SetSize(AWidth,AHeight); +end; + +{ TFPCompactImgRGBA8Bit } + +function TFPCompactImgRGBA8Bit.GetInternalColor(x, y: integer): TFPColor; +var + v: TFPCompactImgRGBA8BitValue; +begin + v:= pFPCompactImgRGBA8BitValueaty(FData)^[x+y*Width]; + Result.red:=(v.r shl 8)+v.r; + Result.green:=(v.g shl 8)+v.g; + Result.blue:=(v.b shl 8)+v.b; + Result.alpha:=(v.a shl 8)+v.a; +end; + +function TFPCompactImgRGBA8Bit.GetInternalPixel(x, y: integer): integer; +begin + Result:=0; +end; + +procedure TFPCompactImgRGBA8Bit.SetInternalColor(x, y: integer; + const Value: TFPColor); +var + v: TFPCompactImgRGBA8BitValue; +begin + v.r:=Value.red shr 8; + v.g:=Value.green shr 8; + v.b:=Value.blue shr 8; + v.a:=Value.alpha shr 8; + pFPCompactImgRGBA8BitValueaty(FData)^[x+y*Width]:=v; +end; + +procedure TFPCompactImgRGBA8Bit.SetInternalPixel(x, y: integer; Value: integer); +begin + +end; + +constructor TFPCompactImgRGBA8Bit.Create(AWidth, AHeight: integer); +begin + FDesc:=GetFPCompactImgDesc(false,8,true); + inherited Create(AWidth, AHeight); +end; + +destructor TFPCompactImgRGBA8Bit.Destroy; +begin + ReAllocMem(FData,0); + inherited Destroy; +end; + +procedure TFPCompactImgRGBA8Bit.SetSize(AWidth, AHeight: integer); +begin + if (AWidth=Width) and (AHeight=Height) then exit; + ReAllocMem(FData,SizeOf(TFPCompactImgRGBA8BitValue)*AWidth*AHeight); + inherited SetSize(AWidth,AHeight); +end; + +{ TFPCompactImgRGB8Bit } + +function TFPCompactImgRGB8Bit.GetInternalColor(x, y: integer): TFPColor; +var + v: TFPCompactImgRGB8BitValue; +begin + v:= pFPCompactImgRGB8BitValueaty(FData)^[x+y*Width]; + Result.red:=(v.r shl 8)+v.r; + Result.green:=(v.g shl 8)+v.g; + Result.blue:=(v.b shl 8)+v.b; + Result.alpha:=alphaOpaque; +end; + +function TFPCompactImgRGB8Bit.GetInternalPixel(x, y: integer): integer; +begin + Result:=0; +end; + +procedure TFPCompactImgRGB8Bit.SetInternalColor(x, y: integer; const Value: TFPColor + ); +var + v: TFPCompactImgRGB8BitValue; +begin + v.r:=Value.red shr 8; + v.g:=Value.green shr 8; + v.b:=Value.blue shr 8; + pFPCompactImgRGB8BitValueaty(FData)^[x+y*Width]:=v; +end; + +procedure TFPCompactImgRGB8Bit.SetInternalPixel(x, y: integer; Value: integer); +begin + +end; + +constructor TFPCompactImgRGB8Bit.Create(AWidth, AHeight: integer); +begin + FDesc:=GetFPCompactImgDesc(false,8,false); + inherited Create(AWidth, AHeight); +end; + +destructor TFPCompactImgRGB8Bit.Destroy; +begin + ReAllocMem(FData,0); + inherited Destroy; +end; + +procedure TFPCompactImgRGB8Bit.SetSize(AWidth, AHeight: integer); +begin + if (AWidth=Width) and (AHeight=Height) then exit; + ReAllocMem(FData,SizeOf(TFPCompactImgRGB8BitValue)*AWidth*AHeight); + inherited SetSize(AWidth,AHeight); +end; + +{ TFPCompactImgRGB16Bit } + +function TFPCompactImgRGB16Bit.GetInternalColor(x, y: integer): TFPColor; +var + v: TFPCompactImgRGB16BitValue; +begin + v:=pFPCompactImgRGB16BitValueaty(FData)^[x+y*Width]; + Result.red:=v.r; + Result.green:=v.g; + Result.blue:=v.b; + Result.alpha:=alphaOpaque; +end; + +function TFPCompactImgRGB16Bit.GetInternalPixel(x, y: integer): integer; +begin + Result:=0; +end; + +procedure TFPCompactImgRGB16Bit.SetInternalColor(x, y: integer; + const Value: TFPColor); +var + v: TFPCompactImgRGB16BitValue; +begin + v.r:=Value.red; + v.g:=Value.green; + v.b:=Value.blue; + pFPCompactImgRGB16BitValueaty(FData)^[x+y*Width]:=v; +end; + +procedure TFPCompactImgRGB16Bit.SetInternalPixel(x, y: integer; Value: integer); +begin + +end; + +constructor TFPCompactImgRGB16Bit.Create(AWidth, AHeight: integer); +begin + FDesc:=GetFPCompactImgDesc(false,16,false); + inherited Create(AWidth, AHeight); +end; + +destructor TFPCompactImgRGB16Bit.Destroy; +begin + ReAllocMem(FData,0); + inherited Destroy; +end; + +procedure TFPCompactImgRGB16Bit.SetSize(AWidth, AHeight: integer); +begin + if (AWidth=Width) and (AHeight=Height) then exit; + ReAllocMem(FData,SizeOf(TFPCompactImgRGB16BitValue)*AWidth*AHeight); + inherited SetSize(AWidth,AHeight); +end; + +{ TFPCompactImgRGBA16Bit } + +function TFPCompactImgRGBA16Bit.GetInternalColor(x, y: integer): TFPColor; +begin + Result:= pFPColoraty(FData)^[x+y*Width]; +end; + +function TFPCompactImgRGBA16Bit.GetInternalPixel(x, y: integer): integer; +begin + Result:=0; +end; + +procedure TFPCompactImgRGBA16Bit.SetInternalColor(x, y: integer; + const Value: TFPColor); +begin + pFPColoraty(FData)^[x+y*Width]:=Value; +end; + +procedure TFPCompactImgRGBA16Bit.SetInternalPixel(x, y: integer; Value: integer); +begin + +end; + +constructor TFPCompactImgRGBA16Bit.Create(AWidth, AHeight: integer); +begin + FDesc:=GetFPCompactImgDesc(false,16,true); + inherited Create(AWidth, AHeight); +end; + +destructor TFPCompactImgRGBA16Bit.Destroy; +begin + ReAllocMem(FData,0); + inherited Destroy; +end; + +procedure TFPCompactImgRGBA16Bit.SetSize(AWidth, AHeight: integer); +begin + if (AWidth=Width) and (AHeight=Height) then exit; + ReAllocMem(FData,SizeOf(TFPColor)*AWidth*AHeight); + inherited SetSize(AWidth,AHeight); +end; + + diff --git a/mseide-msegui/lib/common/fpccompatibility/fphandler.inc b/mseide-msegui/lib/common/fpccompatibility/fphandler.inc new file mode 100644 index 0000000..5e3a881 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fphandler.inc @@ -0,0 +1,275 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 2003 by the Free Pascal development team + + TImageHandlers implementations + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + **********************************************************************} +{ TImageHandlersManager } + +constructor TImageHandlersManager.Create; +begin + inherited create; + FData := Tlist.Create; +end; + +destructor TImageHandlersManager.Destroy; +var r : integer; +begin + for r := FData.count-1 downto 0 do + TIHData(FData[r]).Free; + FData.Free; + inherited Destroy; +end; + +function CalcDefExt (TheExtentions:string) : string; +var p : integer; +begin + p := pos (';',TheExtentions); + if p = 0 then + result := TheExtentions + else + result := copy(TheExtentions, 1, p-1); +end; + +procedure TImageHandlersManager.RegisterImageHandlers (const ATypeName,TheExtentions:string; + AReader:TFPCustomImageReaderClass; AWriter:TFPCustomImageWriterClass); +var ih : TIHData; +begin + ih := GetData (ATypeName); + if assigned (ih) then + FPImgError (StrTypeAlreadyExist,[ATypeName]); + ih := TIHData.Create; + with ih do + begin + FTypeName := ATypeName; + FExtention := lowercase(TheExtentions); + FDefaultExt := CalcDefExt (TheExtentions); + FReader := AReader; + FWriter := AWriter; + end; + FData.Add (ih); +end; + +procedure TImageHandlersManager.RegisterImageReader (const ATypeName,TheExtentions:string; + AReader:TFPCustomImageReaderClass); +var ih : TIHData; +begin + ih := GetData (ATypeName); + if assigned (ih) then + begin + if assigned (ih.FReader) then + FPImgError (StrTypeReaderAlreadyExist,[ATypeName]) + else + ih.FReader := AReader; + end + else + begin + ih := TIHData.Create; + with ih do + begin + FTypeName := ATypeName; + FExtention := Lowercase(TheExtentions); + FDefaultExt := CalcDefExt (TheExtentions); + FReader := AReader; + FWriter := nil; + end; + FData.Add (ih); + end; +end; + +procedure TImageHandlersManager.RegisterImageWriter (const ATypeName,TheExtentions:string; + AWriter:TFPCustomImageWriterClass); +var ih : TIHData; +begin + ih := GetData (ATypeName); + if assigned (ih) then + begin + if assigned (ih.FWriter) then + FPImgError (StrTypeWriterAlreadyExist,[ATypeName]) + else + ih.FWriter := AWriter; + end + else + begin + ih := TIHData.Create; + with ih do + begin + FTypeName := ATypeName; + FExtention := lowercase(TheExtentions); + FDefaultExt := CalcDefExt (TheExtentions); + FReader := nil; + FWriter := AWriter; + end; + FData.Add (ih); + end; +end; + +function TImageHandlersManager.GetCount : integer; +begin + result := FData.Count; +end; + +function TImageHandlersManager.GetData (const ATypeName:string) : TIHData; +var r : integer; +begin + r := FData.count; + repeat + dec (r); + until (r < 0) or (compareText (TIHData(FData[r]).FTypeName, ATypeName) = 0); + if r >= 0 then + result := TIHData(FData[r]) + else + result := nil; +end; + +function TImageHandlersManager.GetData (index:integer) : TIHData; +begin + if (index >= 0) and (index < FData.count) then + result := TIHData (FData[index]) + else + result := nil; +end; + +function TImageHandlersManager.GetTypeName (index:integer) : string; +var ih : TIHData; +begin + ih := TIHData (FData[index]); + result := ih.FTypeName; +end; + +function TImageHandlersManager.GetReader (const TypeName:string) : TFPCustomImageReaderClass; +var ih : TIHData; +begin + ih := GetData (TypeName); + if assigned(ih) then + result := ih.FReader + else + result := nil; +end; + +function TImageHandlersManager.GetWriter (const TypeName:string) : TFPCustomImageWriterClass; +var ih : TIHData; +begin + ih := GetData (TypeName); + if assigned(ih) then + result := ih.FWriter + else + result := nil; +end; + +function TImageHandlersManager.GetExt (const TypeName:string) : string; +var ih : TIHData; +begin + ih := GetData (TypeName); + if assigned(ih) then + result := ih.FExtention + else + result := ''; +end; + +function TImageHandlersManager.GetDefExt (const TypeName:string) : string; +var ih : TIHData; +begin + ih := GetData (TypeName); + if assigned(ih) then + result := ih.FDefaultExt + else + result := ''; +end; + +{ TFPCustomImageHandler } + +constructor TFPCustomImageHandler.create; +begin + inherited create; +end; + +procedure TFPCustomImageHandler.Progress(Stage: TProgressStage; + PercentDone: Byte; RedrawNow: Boolean; const R: TRect; + const Msg: AnsiString; var Continue: Boolean); + +begin + If Assigned(FOnProgress) then + FOnProgress(Self,Stage,PercentDone,RedrawNow,R,Msg,Continue) + else If Assigned(FImage) then + // It is debatable whether we should pass ourselves or the image ? + FImage.Progress(Self,Stage,PercentDone,RedrawNow,R,Msg,Continue); +end; + +{ TFPCustomImageReader } + +constructor TFPCustomImageReader.Create; +begin + inherited create; + FDefImageClass := TFPMemoryImage; +end; + +function TFPCustomImageReader.ImageRead (Str:TStream; Img:TFPCustomImage) : TFPCustomImage; +begin + try + if not assigned(Str) then + raise FPImageException.Create(ErrorText[StrNoStream]); + FStream := Str; + if not assigned(img) then + result := FDefImageClass.Create(0,0) + else + result := Img; + FImage := result; + if FImage.UsePalette then + FImage.Palette.Clear; + if CheckContents (Str) then + begin + InternalRead (Str, result) + end + else + raise FPImageException.Create ('Wrong image format'); + finally + FStream := nil; + FImage := nil; + end; +end; + +function TFPCustomImageReader.CheckContents (Str:TStream) : boolean; +var InRead : boolean; +begin + InRead := assigned(FStream); + if not assigned(Str) then + raise FPImageException.Create(ErrorText[StrNoStream]); + try + FSTream := Str; + result := InternalCheck (Str); + finally + if not InRead then + FStream := nil; + end; +end; + +{ TFPCustomImageWriter } + +procedure TFPCustomImageWriter.ImageWrite (Str:TStream; Img:TFPCustomImage); +begin + if not assigned(img) then + raise FPImageException.Create(ErrorText[StrNoImageToWrite]); + if not assigned(Str) then + raise FPImageException.Create(ErrorText[StrNoStream]); + try + FStream := str; + FImage := img; + Str.position := 0; + Str.Size := 0; + InternalWrite(Str, Img); + finally + FStream := nil; + FImage := nil; + end; +end; + + diff --git a/mseide-msegui/lib/common/fpccompatibility/fpimage.inc b/mseide-msegui/lib/common/fpccompatibility/fpimage.inc new file mode 100644 index 0000000..ae78e39 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpimage.inc @@ -0,0 +1,558 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 2003 by the Free Pascal development team + + TFPCustomImage implementation. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + **********************************************************************} +{ TFPCustomImage } + +constructor TFPCustomImage.create (AWidth,AHeight:integer); +begin + inherited create; + FExtra := TStringList.Create; + FWidth := 0; + FHeight := 0; + FPalette := nil; + SetSize (AWidth,AHeight); +end; + +destructor TFPCustomImage.destroy; +begin + FExtra.Free; + if assigned (FPalette) then + FPalette.Free; + inherited; +end; + +procedure TFPCustomImage.LoadFromStream (Str:TStream; Handler:TFPCustomImagereader); +begin + Handler.ImageRead (Str, self); +end; + +procedure TFPCustomImage.LoadFromFile (const filename:String; Handler:TFPCustomImageReader); +var + fs : TStream; +begin + if FileExists (filename) then + begin + fs := TFileStream.Create (filename, fmOpenRead); + try + LoadFromStream (fs, handler); + finally + fs.Free; + end; + end + else + FPImgError (StrNoFile, [filename]); +end; + +procedure TFPCustomImage.SaveToStream (Str:TStream; Handler:TFPCustomImageWriter); +begin + Handler.ImageWrite (Str, Self); +end; + +procedure TFPCustomImage.SaveToFile (const filename:String; Handler:TFPCustomImageWriter); +var + fs : TStream; +begin + fs := TFileStream.Create (filename, fmCreate); + try + SaveToStream (fs, handler); + finally + fs.Free; + end +end; + +procedure TFPCustomImage.SaveToFile (const filename:String); + +var e,s : string; + r : integer; +// f : TFileStream; + h : TFPCustomImageWriterClass; + Writer : TFPCustomImageWriter; + d : TIHData; + Msg : string; + +begin + e := lowercase (ExtractFileExt(filename)); + if (e <> '') and (e[1] = '.') then + delete (e,1,1); + with ImageHandlers do + begin + r := count-1; + s := e + ';'; + while (r >= 0) do + begin + d := GetData(r); + if (pos(s,d.Fextention+';') <> 0) then + try + h := d.FWriter; + if assigned (h) then + begin + Writer := h.Create; + try + SaveTofile (filename, Writer); + finally + Writer.Free; + end; + break; + end; + except + on e : exception do + Msg := e.message; + end; + dec (r); + end + end; + if (Msg<>'') then + FPImgError (StrWriteWithError, [Msg]); +end; + + +procedure TFPCustomImage.LoadFromStream (Str:TStream); +var r : integer; + h : TFPCustomImageReaderClass; + reader : TFPCustomImageReader; + msg : string; + d : TIHData; +begin + with ImageHandlers do + try + r := count-1; + while (r >= 0) do + begin + d := GetData(r); + if assigned (d) then + h := d.FReader; + if assigned (h) then + begin + reader := h.Create; + with reader do + try + if CheckContents (str) then + try + FStream := str; + FImage := self; + InternalRead (str, self); + break; + except + on e : exception do + msg := e.message; + end; + finally + Free; + str.seek (soFromBeginning, 0); + end; + end; + dec (r); + end; + except + on e : exception do + FPImgError (StrCantDetermineType, [e.message]); + end; + if r < 0 then + if msg = '' then + FPImgError (StrNoCorrectReaderFound) + else + FPImgError (StrReadWithError, [Msg]); +end; + +procedure TFPCustomImage.LoadFromFile (const filename:String); +var e,s : string; + r : integer; + f : TFileStream; + h : TFPCustomImageReaderClass; + reader : TFPCustomImageReader; + d : TIHData; + Msg : string; +begin + e := lowercase (ExtractFileExt(filename)); + if (e <> '') and (e[1] = '.') then + delete (e,1,1); + with ImageHandlers do + begin + r := count-1; + s := e + ';'; + while (r >= 0) do + begin + d := GetData(r); + if (pos(s,d.Fextention+';') <> 0) then + try + h := d.FReader; + if assigned (h) then + begin + reader := h.Create; + try + loadfromfile (filename, reader); + finally + Reader.Free; + end; + break; + end; + except + on e : exception do + Msg := e.message; + end; + dec (r); + end + end; + if Msg = '' then + begin + if r < 0 then + begin + f := TFileStream.Create (filename, fmOpenRead); + try + LoadFromStream (f); + finally + f.Free; + end; + end; + end + else + FPImgError (StrReadWithError, [Msg]); +end; + +procedure TFPCustomImage.SetHeight (Value : integer); +begin + if Value <> FHeight then + SetSize (FWidth, Value); +end; + +procedure TFPCustomImage.SetWidth (Value : integer); +begin + if Value <> FWidth then + SetSize (Value, FHeight); +end; + +procedure TFPCustomImage.SetSize (AWidth, AHeight : integer); +begin + FWidth := AWidth; + FHeight := AHeight; +end; + +procedure TFPCustomImage.SetExtraValue (index:integer; const AValue:string); +var s : string; + p : integer; +begin + s := FExtra[index]; + p := pos ('=', s); + if p > 0 then + FExtra[index] := copy(s, 1, p) + AValue + else + FPImgError (StrInvalidIndex,[ErrorText[StrImageExtra],index]); +end; + +function TFPCustomImage.GetExtraValue (index:integer) : string; +var s : string; + p : integer; +begin + s := FExtra[index]; + p := pos ('=', s); + if p > 0 then + result := copy(s, p+1, maxint) + else + result := ''; +end; + +procedure TFPCustomImage.SetExtraKey (index:integer; const AValue:string); +var s : string; + p : integer; +begin + s := FExtra[index]; + p := pos('=',s); + if p > 0 then + s := AValue + copy(s,p,maxint) + else + s := AValue; + FExtra[index] := s; +end; + +function TFPCustomImage.GetExtraKey (index:integer) : string; +begin + result := FExtra.Names[index]; +end; + +procedure TFPCustomImage.SetExtra (const key:String; const AValue:string); +begin + FExtra.values[key] := AValue; +end; + +function TFPCustomImage.GetExtra (const key:String) : string; +begin + result := FExtra.values[key]; +end; + +function TFPCustomImage.ExtraCount : integer; +begin + result := FExtra.count; +end; + +procedure TFPCustomImage.RemoveExtra (const key:string); +var p : integer; +begin + p := FExtra.IndexOfName(key); + if p >= 0 then + FExtra.Delete (p); +end; + +procedure TFPCustomImage.SetPixel (x,y:integer; Value:integer); +begin + CheckPaletteIndex (Value); + CheckIndex (x,y); + SetInternalPixel (x,y,Value); +end; + +function TFPCustomImage.GetPixel (x,y:integer) : integer; +begin + CheckIndex (x,y); + result := GetInternalPixel(x,y); +end; + +procedure TFPCustomImage.SetColor (x,y:integer; const Value:TFPColor); +begin + CheckIndex (x,y); + SetInternalColor (x,y,Value); +end; + +function TFPCustomImage.GetColor (x,y:integer) : TFPColor; +begin + CheckIndex (x,y); + result := GetInternalColor(x,y); +end; + +procedure TFPCustomImage.SetInternalColor (x,y:integer; const Value:TFPColor); +var i : integer; +begin + i := FPalette.IndexOf (Value); + SetInternalPixel (x,y,i); +end; + +function TFPCustomImage.GetInternalColor (x,y:integer) : TFPColor; +begin + result := FPalette.Color[GetInternalPixel(x,y)]; +end; + +function TFPCustomImage.GetUsePalette : boolean; +begin + result := assigned(FPalette); +end; + +procedure TFPCustomImage.SetUsePalette(Value:boolean); +begin + if Value <> assigned(FPalette) + then + if Value + then + begin + FPalette := TFPPalette.Create (0); + // FPalette.Add (colTransparent); + end + else + begin + FPalette.Free; + FPalette := nil; + end; +end; + +procedure TFPCustomImage.CheckPaletteIndex (PalIndex:integer); +begin + if UsePalette then + begin + if (PalIndex < -1) or (PalIndex >= FPalette.Count) then + FPImgError (StrInvalidIndex,[ErrorText[StrPalette],PalIndex]); + end + else + FPImgError (StrNoPaletteAvailable); +end; + +procedure TFPCustomImage.CheckIndex (x,y:integer); +begin + if (x < 0) or (x >= FWidth) then + FPImgError (StrInvalidIndex,[ErrorText[StrImageX],x]); + if (y < 0) or (y >= FHeight) then + FPImgError (StrInvalidIndex,[ErrorText[StrImageY],y]); +end; + +Procedure TFPCustomImage.Progress(Sender: TObject; Stage: TProgressStage; + PercentDone: Byte; RedrawNow: Boolean; const R: TRect; + const Msg: AnsiString; var Continue: Boolean); +begin + If Assigned(FOnProgress) then + FonProgress(Sender,Stage,PercentDone,RedrawNow,R,Msg,Continue); +end; + +Procedure TFPCustomImage.Assign(Source: TPersistent); + +Var + Src : TFPCustomImage; + X,Y : Integer; + +begin + If Source is TFPCustomImage then + begin + Src:=TFPCustomImage(Source); + // Copy extra info + FExtra.Assign(Src.Fextra); + // Copy palette if needed. + SetSize(0,0); { avoid side-effects in descendant classes } + UsePalette:=Src.UsePalette; + If UsePalette then + begin + Palette.Count:=0; + Palette.Merge(Src.Palette); + end; + // Copy image. + SetSize(Src.Width,Src.height); + If UsePalette then + For x:=0 to Src.Width-1 do + For y:=0 to src.Height-1 do + pixels[X,Y]:=src.pixels[X,Y] + else + For x:=0 to Src.Width-1 do + For y:=0 to src.Height-1 do + self[X,Y]:=src[X,Y]; + end + else + Inherited Assign(Source); +end; + +{ TFPMemoryImage } + +constructor TFPMemoryImage.Create (AWidth,AHeight:integer); +begin + Fdata := nil; + inherited create (AWidth,AHeight); + SetUsePalette(False); +end; + +destructor TFPMemoryImage.Destroy; +begin + // MG: missing if + if FData<>nil then + FreeMem (FData); + inherited Destroy; +end; + +function TFPMemoryImage.GetInternalColor(x,y:integer):TFPColor; + begin + if Assigned(FPalette) + then + Result:=inherited GetInternalColor(x,y) + else + Result:=PFPColorArray(FData)^[y*FWidth+x]; + end; + +function TFPMemoryImage.GetInternalPixel (x,y:integer) : integer; +begin + result := FData^[y*FWidth+x]; +end; + +procedure TFPMemoryImage.SetInternalColor (x,y:integer; const Value:TFPColor); + begin + if Assigned(FPalette) + then + inherited SetInternalColor(x,y,Value) + else + PFPColorArray(FData)^[y*FWidth+x]:=Value; + end; + +procedure TFPMemoryImage.SetInternalPixel (x,y:integer; Value:integer); +begin + FData^[y*FWidth+x] := Value; +end; + +function Lowest (a,b : integer) : integer; +begin + if a <= b then + result := a + else + result := b; +end; + +procedure TFPMemoryImage.SetSize (AWidth, AHeight : integer); +var w, h, r, old : integer; + NewData : PFPIntegerArray; +begin + if (AWidth <> Width) or (AHeight <> Height) then + begin + old := Height * Width; + r:=AWidth*AHeight; + if Assigned(FPalette) + then + r:=SizeOf(integer)*r + else + r:=SizeOf(TFPColor)*r; + if r = 0 then + NewData := nil + else + begin + GetMem (NewData, r); + {$ifdef FPC} + FillWord (Newdata^[0], r div sizeof(word), 0); + {$else} + Fillchar (Newdata^[0], r, 0); + {$endif} + end; + // MG: missing "and (NewData<>nil)" + if (old <> 0) and assigned(FData) and (NewData<>nil) then + begin + if r <> 0 then + begin + w := Lowest(Width, AWidth); + h := Lowest(Height, AHeight); + for r := 0 to h-1 do + move (FData^[r*Width], NewData^[r*AWidth], w); + end; + end; + if Assigned(FData) then FreeMem(FData); + FData := NewData; + inherited; + end; +end; + +procedure TFPMemoryImage.SetUsePalette(Value:boolean); +var + OldColors:PFPColorArray; + OldPixels:PFPIntegerArray; + r,c:Integer; +begin + if Value<>assigned(FPalette) + then + if Value + then + begin + FPalette:=TFPPalette.Create(0); + //FPalette.Add(colTransparent); + if assigned(FData) then + begin + OldColors:=PFPColorArray(FData); + GetMem(FData,FWidth*FHeight*SizeOf(Integer)); + for r:=0 to FHeight-1 do + for c:=0 to FWidth-1 do + Colors[c,r]:=OldColors^[r*FWidth+c]; + FreeMem(OldColors); + end; + end + else + begin + if Assigned(FData) then + begin + OldPixels:=PFPIntegerArray(FData); + GetMem(FData,FWidth*FHeight*SizeOf(TFPColor)); + for r:=0 to FHeight-1 do + for c:=0 to FWidth-1 do + Colors[c,r]:=FPalette.Color[OldPixels^[r*FWidth+c]]; + FreeMem(OldPixels); + end; + FPalette.Free; + FPalette:=nil; + end; +end; diff --git a/mseide-msegui/lib/common/fpccompatibility/fpimage.pas b/mseide-msegui/lib/common/fpccompatibility/fpimage.pas new file mode 100644 index 0000000..93a76b2 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpimage.pas @@ -0,0 +1,701 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 2003 by the Free Pascal development team + + fpImage base definitions. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + **********************************************************************} +//modified 2013 by Martin Schreiber + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +unit fpimage; + +interface + +uses + sysutils,classes,mclasses,msetypes{$ifndef FPC},classes_del,types{$endif}; + +type + + TFPCustomImageReader = class; + TFPCustomImageWriter = class; + TFPCustomImage = class; + + FPImageException = class (exception); + + TFPColor = record + red,green,blue,alpha : word; + end; + PFPColor = ^TFPColor; + FPColoraty = array[0..0] of TFPColor; + pFPColoraty = ^FPColoraty; + + TColorFormat = (cfMono,cfGray2,cfGray4,cfGray8,cfGray16,cfGray24, + cfGrayA8,cfGrayA16,cfGrayA32, + cfRGB15,cfRGB16,cfRGB24,cfRGB32,cfRGB48, + cfRGBA8,cfRGBA16,cfRGBA32,cfRGBA64, + cfBGR15,cfBGR16,cfBGR24,cfBGR32,cfBGR48, + cfABGR8,cfABGR16,cfABGR32,cfABGR64); + TColorData = qword; + PColorData = ^TColorData; + + TDeviceColor = record + Fmt : TColorFormat; + Data : TColorData; + end; + +{$ifdef CPU68K} + { 1.0 m68k cpu compiler does not allow + types larger than 32k.... + if we remove range checking all should be fine PM } + TFPColorArray = array [0..0] of TFPColor; +{$R-} +{$else not CPU68K} + TFPColorArray = array [0..(maxint-1) div sizeof(TFPColor)-1] of TFPColor; +{$endif CPU68K} + PFPColorArray = ^TFPColorArray; + + TFPImgProgressStage = (psStarting, psRunning, psEnding); + TFPImgProgressEvent = procedure (Sender: TObject; Stage: TFPImgProgressStage; + PercentDone: Byte; RedrawNow: Boolean; const R: TRect; + const Msg: AnsiString; var Continue : Boolean) of object; + // Delphi compatibility + TProgressStage = TFPImgProgressStage; + TProgressEvent = TFPImgProgressEvent; + + TFPPalette = class + protected + FData : PFPColorArray; + FCount, FCapacity : integer; + procedure SetCount (Value:integer); virtual; + function GetCount : integer; + procedure SetColor (index:integer; const Value:TFPColor); virtual; + function GetColor (index:integer) : TFPColor; + procedure SetCapacity (ind : Integer); + procedure CheckIndex (index:integer); virtual; + procedure EnlargeData; virtual; + public + constructor Create (ACount : integer); + destructor Destroy; override; + procedure Build (Img : TFPCustomImage); virtual; + procedure Copy (APalette: TFPPalette); virtual; + procedure Merge (pal : TFPPalette); virtual; + function IndexOf (const AColor: TFPColor) : integer; virtual; + function Add (const Value: TFPColor) : integer; virtual; + procedure Clear; virtual; + property Color [Index : integer] : TFPColor read GetColor write SetColor; default; + property Count : integer read GetCount write SetCount; + property Capacity : integer read FCapacity write SetCapacity; + end; + + TFPCustomImage = class(TPersistent) + private + FOnProgress : TFPImgProgressEvent; + FExtra : TStringlist; + FPalette : TFPPalette; + FHeight, FWidth : integer; + procedure SetHeight (Value : integer); + procedure SetWidth (Value : integer); + procedure SetExtra (const key:String; const AValue:string); + function GetExtra (const key:String) : string; + procedure SetExtraValue (index:integer; const AValue:string); + function GetExtraValue (index:integer) : string; + procedure SetExtraKey (index:integer; const AValue:string); + function GetExtraKey (index:integer) : string; + procedure CheckIndex (x,y:integer); + procedure CheckPaletteIndex (PalIndex:integer); + procedure SetColor (x,y:integer; const Value:TFPColor); + function GetColor (x,y:integer) : TFPColor; + procedure SetPixel (x,y:integer; Value:integer); + function GetPixel (x,y:integer) : integer; + function GetUsePalette : boolean; + protected + // Procedures to store the data. Implemented in descendants + procedure SetInternalColor (x,y:integer; const Value:TFPColor); virtual; + function GetInternalColor (x,y:integer) : TFPColor; virtual; + procedure SetInternalPixel (x,y:integer; Value:integer); virtual; abstract; + function GetInternalPixel (x,y:integer) : integer; virtual; abstract; + procedure SetUsePalette (Value:boolean);virtual; + procedure Progress(Sender: TObject; Stage: TProgressStage; + PercentDone: Byte; RedrawNow: Boolean; const R: TRect; + const Msg: AnsiString; var Continue: Boolean); Virtual; + public + constructor create (AWidth,AHeight:integer); virtual; + destructor destroy; override; + procedure Assign(Source: TPersistent); override; + // Saving and loading + procedure LoadFromStream (Str:TStream; + Handler:TFPCustomImageReader); overload; + procedure LoadFromStream (Str:TStream); overload; + procedure LoadFromFile (const filename:String; + Handler:TFPCustomImageReader); overload; + procedure LoadFromFile (const filename:String); overload; + procedure SaveToStream (Str:TStream; Handler:TFPCustomImageWriter); + procedure SaveToFile (const filename:String; + Handler:TFPCustomImageWriter); overload; + procedure SaveToFile (const filename:String); overload; + // Size and data + procedure SetSize (AWidth, AHeight : integer); virtual; + property Height : integer read FHeight write SetHeight; + property Width : integer read FWidth write SetWidth; + property Colors [x,y:integer] : TFPColor read GetColor write SetColor; default; + // Use of palette for colors + property UsePalette : boolean read GetUsePalette write SetUsePalette; + property Palette : TFPPalette read FPalette; + property Pixels [x,y:integer] : integer read GetPixel write SetPixel; + // Info unrelated with the image representation + property Extra [const key:string] : string read GetExtra write SetExtra; + property ExtraValue [index:integer] : string read GetExtraValue write SetExtraValue; + property ExtraKey [index:integer] : string read GetExtraKey write SetExtraKey; + procedure RemoveExtra (const key:string); + function ExtraCount : integer; + property OnProgress: TFPImgProgressEvent read FOnProgress write FOnProgress; + end; + TFPCustomImageClass = class of TFPCustomImage; + +{$ifdef CPU68K} + { 1.0 m68k cpu compiler does not allow + types larger than 32k.... + if we remove range checking all should be fine PM } + TFPIntegerArray = array [0..0] of integer; +{$R-} +{$else not CPU68K} + TFPIntegerArray = array [0..(maxint-1) div sizeof(integer)-1] of integer; +{$endif CPU68K} + PFPIntegerArray = ^TFPIntegerArray; + + TFPMemoryImage = class (TFPCustomImage) + private + protected + FData : PFPIntegerArray; + function GetInternalColor(x,y:integer):TFPColor;override; + procedure SetInternalColor (x,y:integer; const Value:TFPColor);override; + procedure SetUsePalette (Value:boolean);override; + procedure SetInternalPixel (x,y:integer; Value:integer); override; + function GetInternalPixel (x,y:integer) : integer; override; + public + constructor create (AWidth,AHeight:integer); override; + destructor destroy; override; + procedure SetSize (AWidth, AHeight : integer); override; + end; + + TFPCustomImageHandler = class + private + FOnProgress : TFPImgProgressEvent; + FStream : TStream; + FImage : TFPCustomImage; + protected + procedure Progress(Stage: TProgressStage; PercentDone: Byte; RedrawNow: Boolean; const R: TRect; + const Msg: AnsiString; var Continue: Boolean); Virtual; + property TheStream : TStream read FStream; + property TheImage : TFPCustomImage read FImage; + public + constructor Create; virtual; + Property OnProgress : TFPImgProgressEvent Read FOnProgress Write FOnProgress; + end; + + TFPCustomImageReader = class (TFPCustomImageHandler) + private + FDefImageClass:TFPCustomImageClass; + protected + procedure InternalRead (Str:TStream; Img:TFPCustomImage); virtual; abstract; + function InternalCheck (Str:TStream) : boolean; virtual; abstract; + public + constructor Create; override; + function ImageRead (Str:TStream; Img:TFPCustomImage) : TFPCustomImage; + // reads image + function CheckContents (Str:TStream) : boolean; + // Gives True if contents is readable + property DefaultImageClass : TFPCustomImageClass read FDefImageClass write FDefImageClass; + // Image Class to create when no img is given for reading + end; + TFPCustomImageReaderClass = class of TFPCustomImageReader; + + TFPCustomImageWriter = class (TFPCustomImageHandler) + protected + procedure InternalWrite (Str:TStream; Img:TFPCustomImage); virtual; abstract; + public + procedure ImageWrite (Str:TStream; Img:TFPCustomImage); + // writes given image to stream + end; + TFPCustomImageWriterClass = class of TFPCustomImageWriter; + + TIHData = class + private + FExtention, FTypeName, FDefaultExt : string; + FReader : TFPCustomImageReaderClass; + FWriter : TFPCustomImageWriterClass; + end; + + TImageHandlersManager = class + private + FData : TList; + function GetReader (const TypeName:string) : TFPCustomImageReaderClass; + function GetWriter (const TypeName:string) : TFPCustomImageWriterClass; + function GetExt (const TypeName:string) : string; + function GetDefExt (const TypeName:string) : string; + function GetTypeName (index:integer) : string; + function GetData (const ATypeName:string) : TIHData; overload; + function GetData (index : integer) : TIHData; overload; + function GetCount : integer; + public + constructor Create; + destructor Destroy; override; + procedure RegisterImageHandlers (const ATypeName,TheExtentions:string; + AReader:TFPCustomImageReaderClass; AWriter:TFPCustomImageWriterClass); + procedure RegisterImageReader (const ATypeName,TheExtentions:string; + AReader:TFPCustomImageReaderClass); + procedure RegisterImageWriter (const ATypeName,TheExtentions:string; + AWriter:TFPCustomImageWriterClass); + property Count : integer read GetCount; + property ImageReader [const TypeName:string] : TFPCustomImageReaderClass read GetReader; + property ImageWriter [const TypeName:string] : TFPCustomImageWriterClass read GetWriter; + property Extentions [const TypeName:string] : string read GetExt; + property DefaultExtention [const TypeName:string] : string read GetDefExt; + property TypeNames [index:integer] : string read GetTypeName; + end; + +{function ShiftAndFill (initial:word; CorrectBits:byte):word; +function FillOtherBits (initial:word;CorrectBits:byte):word; +} +function CalculateGray (const From : TFPColor) : word; +(* +function ConvertColor (const From : TDeviceColor) : TFPColor; +function ConvertColor (const From : TColorData; FromFmt:TColorFormat) : TFPColor; +function ConvertColorToData (const From : TFPColor; Fmt : TColorFormat) : TColorData; +function ConvertColorToData (const From : TDeviceColor; Fmt : TColorFormat) : TColorData; +function ConvertColor (const From : TFPColor; Fmt : TColorFormat) : TDeviceColor; +function ConvertColor (const From : TDeviceColor; Fmt : TColorFormat) : TDeviceColor; +*) + +function AlphaBlend(color1, color2: TFPColor): TFPColor; + +function FPColor (r,g,b,a:word) : TFPColor; overload; +function FPColor (r,g,b:word) : TFPColor; overload; +{$ifdef debug}function MakeHex (n:TColordata;nr:byte): string;{$endif} + +{$ifdef FPC} +operator = (const c,d:TFPColor) : boolean; +operator or (const c,d:TFPColor) : TFPColor; +operator and (const c,d:TFPColor) : TFPColor; +operator xor (const c,d:TFPColor) : TFPColor; +{$else} +function col_equ(const c,d:TFPColor) : boolean; +function col_or (const c,d:TFPColor) : TFPColor; +function col_and (const c,d:TFPColor) : TFPColor; +function col_xor (const c,d:TFPColor) : TFPColor; +{$endif} + +function CompareColors(const Color1, Color2: TFPColor): integer; + +var ImageHandlers : TImageHandlersManager; + +type + TErrorTextIndices = ( + StrInvalidIndex, + StrNoImageToWrite, + StrNoFile, + StrNoStream, + StrPalette, + StrImageX, + StrImageY, + StrImageExtra, + StrTypeAlreadyExist, + StrTypeReaderAlreadyExist, + StrTypeWriterAlreadyExist, + StrCantDetermineType, + StrNoCorrectReaderFound, + StrReadWithError, + StrWriteWithError, + StrNoPaletteAvailable + ); + +const + // MG: ToDo: move to implementation and add a function to map to resourcestrings + ErrorText : array[TErrorTextIndices] of string = + ('Invalid %s index %d', + 'No image to write', + 'File "%s" does not exist', + 'No stream to write to', + 'palette', + 'horizontal pixel', + 'vertical pixel', + 'extra', + 'Image type "%s" already exists', + 'Image type "%s" already has a reader class', + 'Image type "%s" already has a writer class', + 'Error while determining image type of stream: %s', + 'Can''t determine image type of stream', + 'Error while reading stream: %s', + 'Error while writing stream: %s', + 'No palette available' + ); + +{$i fpcolors.inc} + +type + TGrayConvMatrix = record + red, green, blue : single; + end; + +var + GrayConvMatrix : TGrayConvMatrix; + +const + GCM_NTSC : TGrayConvMatrix = (red:0.299; green:0.587; blue:0.114); + GCM_JPEG : TGrayConvMatrix = (red:0.299; green:0.587; blue:0.114); + GCM_Mathematical : TGrayConvMatrix = (red:0.334; green:0.333; blue:0.333); + GCM_Photoshop : TGrayConvMatrix = (red:0.213; green:0.715; blue:0.072); + +function CreateBlackAndWhitePalette : TFPPalette; +function CreateWebSafePalette : TFPPalette; +function CreateGrayScalePalette : TFPPalette; +function CreateVGAPalette : TFPPalette; + +Type + TFPCompactImgDesc = record + Gray: boolean; // true = red=green=blue, false: a RGB image + Depth: word; // 8 or 16 bit + HasAlpha: boolean; // has alpha channel + end; + + { TFPCompactImgBase } + + TFPCompactImgBase = class(TFPCustomImage) + private + FDesc: TFPCompactImgDesc; + public + property Desc: TFPCompactImgDesc read FDesc; + end; + TFPCompactImgBaseClass = class of TFPCompactImgBase; + + { TFPCompactImgGray16Bit } + + TFPCompactImgGray16Bit = class(TFPCompactImgBase) + protected + FData: PWord; + function GetInternalColor(x, y: integer): TFPColor; override; + function GetInternalPixel({%H-}x, {%H-}y: integer): integer; override; + procedure SetInternalColor (x, y: integer; const Value: TFPColor); override; + procedure SetInternalPixel({%H-}x, {%H-}y: integer; {%H-}Value: integer); override; + public + constructor Create(AWidth, AHeight: integer); override; + destructor Destroy; override; + procedure SetSize(AWidth, AHeight: integer); override; + end; + + TFPCompactImgGrayAlpha16BitValue = packed record + g,a: word; + end; + PFPCompactImgGrayAlpha16BitValue = ^TFPCompactImgGrayAlpha16BitValue; + FPCompactImgGrayAlpha16BitValueaty = + array[0..0] of TFPCompactImgGrayAlpha16BitValue; + pFPCompactImgGrayAlpha16BitValueaty = ^FPCompactImgGrayAlpha16BitValueaty; + + { TFPCompactImgGrayAlpha16Bit } + + TFPCompactImgGrayAlpha16Bit = class(TFPCompactImgBase) + protected + FData: PFPCompactImgGrayAlpha16BitValue; + function GetInternalColor(x, y: integer): TFPColor; override; + function GetInternalPixel({%H-}x, {%H-}y: integer): integer; override; + procedure SetInternalColor (x, y: integer; const Value: TFPColor); override; + procedure SetInternalPixel({%H-}x, {%H-}y: integer; {%H-}Value: integer); override; + public + constructor Create(AWidth, AHeight: integer); override; + destructor Destroy; override; + procedure SetSize(AWidth, AHeight: integer); override; + end; + + { TFPCompactImgGray8Bit } + + TFPCompactImgGray8Bit = class(TFPCompactImgBase) + protected + FData: PByte; + function GetInternalColor(x, y: integer): TFPColor; override; + function GetInternalPixel({%H-}x, {%H-}y: integer): integer; override; + procedure SetInternalColor (x, y: integer; const Value: TFPColor); override; + procedure SetInternalPixel({%H-}x, {%H-}y: integer; {%H-}Value: integer); override; + public + constructor Create(AWidth, AHeight: integer); override; + destructor Destroy; override; + procedure SetSize(AWidth, AHeight: integer); override; + end; + + TFPCompactImgGrayAlpha8BitValue = packed record + g,a: byte; + end; + PFPCompactImgGrayAlpha8BitValue = ^TFPCompactImgGrayAlpha8BitValue; + FPCompactImgGrayAlpha8BitValueaty = + array[0..0] of TFPCompactImgGrayAlpha8BitValue; + pFPCompactImgGrayAlpha8BitValueaty = ^FPCompactImgGrayAlpha8BitValueaty; + + { TFPCompactImgGrayAlpha8Bit } + + TFPCompactImgGrayAlpha8Bit = class(TFPCompactImgBase) + protected + FData: PFPCompactImgGrayAlpha8BitValue; + function GetInternalColor(x, y: integer): TFPColor; override; + function GetInternalPixel({%H-}x, {%H-}y: integer): integer; override; + procedure SetInternalColor (x, y: integer; const Value: TFPColor); override; + procedure SetInternalPixel({%H-}x, {%H-}y: integer; {%H-}Value: integer); override; + public + constructor Create(AWidth, AHeight: integer); override; + destructor Destroy; override; + procedure SetSize(AWidth, AHeight: integer); override; + end; + + TFPCompactImgRGBA8BitValue = packed record + r,g,b,a: byte; + end; + PFPCompactImgRGBA8BitValue = ^TFPCompactImgRGBA8BitValue; + FPCompactImgRGBA8BitValueaty = array of TFPCompactImgRGBA8BitValue; + pFPCompactImgRGBA8BitValueaty = ^FPCompactImgRGBA8BitValueaty; + + { TFPCompactImgRGBA8Bit } + + TFPCompactImgRGBA8Bit = class(TFPCompactImgBase) + protected + FData: PFPCompactImgRGBA8BitValue; + function GetInternalColor(x, y: integer): TFPColor; override; + function GetInternalPixel({%H-}x, {%H-}y: integer): integer; override; + procedure SetInternalColor (x, y: integer; const Value: TFPColor); override; + procedure SetInternalPixel({%H-}x, {%H-}y: integer; {%H-}Value: integer); override; + public + constructor Create(AWidth, AHeight: integer); override; + destructor Destroy; override; + procedure SetSize(AWidth, AHeight: integer); override; + end; + + TFPCompactImgRGB8BitValue = packed record + r,g,b: byte; + end; + PFPCompactImgRGB8BitValue = ^TFPCompactImgRGB8BitValue; + FPCompactImgRGB8BitValueaty = array[0..0] of TFPCompactImgRGB8BitValue; + pFPCompactImgRGB8BitValueaty = ^FPCompactImgRGB8BitValueaty; + + { TFPCompactImgRGB8Bit } + + TFPCompactImgRGB8Bit = class(TFPCompactImgBase) + protected + FData: PFPCompactImgRGB8BitValue; + function GetInternalColor(x, y: integer): TFPColor; override; + function GetInternalPixel({%H-}x, {%H-}y: integer): integer; override; + procedure SetInternalColor (x, y: integer; const Value: TFPColor); override; + procedure SetInternalPixel({%H-}x, {%H-}y: integer; {%H-}Value: integer); override; + public + constructor Create(AWidth, AHeight: integer); override; + destructor Destroy; override; + procedure SetSize(AWidth, AHeight: integer); override; + end; + + TFPCompactImgRGB16BitValue = packed record + r,g,b: word; + end; + PFPCompactImgRGB16BitValue = ^TFPCompactImgRGB16BitValue; + FPCompactImgRGB16BitValueaty = array[0..0] of TFPCompactImgRGB16BitValue; + pFPCompactImgRGB16BitValueaty = ^FPCompactImgRGB16BitValueaty; + + { TFPCompactImgRGB16Bit } + + TFPCompactImgRGB16Bit = class(TFPCompactImgBase) + protected + FData: PFPCompactImgRGB16BitValue; + function GetInternalColor(x, y: integer): TFPColor; override; + function GetInternalPixel({%H-}x, {%H-}y: integer): integer; override; + procedure SetInternalColor (x, y: integer; const Value: TFPColor); override; + procedure SetInternalPixel({%H-}x, {%H-}y: integer; {%H-}Value: integer); override; + public + constructor Create(AWidth, AHeight: integer); override; + destructor Destroy; override; + procedure SetSize(AWidth, AHeight: integer); override; + end; + + { TFPCompactImgRGBA16Bit } + + TFPCompactImgRGBA16Bit = class(TFPCompactImgBase) + protected + FData: PFPColor; + function GetInternalColor(x, y: integer): TFPColor; override; + function GetInternalPixel({%H-}x, {%H-}y: integer): integer; override; + procedure SetInternalColor (x, y: integer; const Value: TFPColor); override; + procedure SetInternalPixel({%H-}x, {%H-}y: integer; {%H-}Value: integer); override; + public + constructor Create(AWidth, AHeight: integer); override; + destructor Destroy; override; + procedure SetSize(AWidth, AHeight: integer); override; + end; + +{ Create a descriptor to select a CompactImg class } +function GetFPCompactImgDesc(Gray: boolean; Depth: word; HasAlpha: boolean): TFPCompactImgDesc; + +{ Returns a CompactImg class that fits the descriptor } +function GetFPCompactImgClass(const Desc: TFPCompactImgDesc): TFPCompactImgBaseClass; + +{ Create a CompactImg with the descriptor } +function CreateFPCompactImg(const Desc: TFPCompactImgDesc; Width, Height: integer): TFPCustomImage; + +{ Create a CompactImg with the same features as Img. +If Img is a TFPCompactImgBaseClass it will create that. +Otherwise it returns a CompactImg that fits the Img using GetMinimumPTDesc. } +function CreateCompatibleFPCompactImg(Img: TFPCustomImage; Width, Height: integer +): TFPCustomImage; + +{ As CreateCompatibleFPCompactImg, but the image has always an alpha channel. } +function CreateCompatibleFPCompactImgWithAlpha(Img: TFPCustomImage; +Width, Height: integer): TFPCustomImage; + +{ Returns the smallest descriptor that allows to store the Img. +It returns HasAlpha=false if all pixel are opaque. +It returns Gray=true if all red=green=blue. +It returns Depth=8 if all lo byte equals the hi byte or all lo bytes are 0. +To ignore rounding errors you can pass a FuzzyDepth. For example a FuzzyDepth +of 3 ignores the lower 3 bits when comparing. } +function GetMinimumPTDesc(Img: TFPCustomImage; FuzzyDepth: word = 4): TFPCompactImgDesc; + +{ Create a smaller CompactImg with the same information as Img. +Pass FreeImg=true to call Img.Free } +function GetMinimumFPCompactImg(Img: TFPCustomImage; FreeImg: boolean; +FuzzyDepth: word = 4): TFPCustomImage; + + + +implementation + +procedure FPImgError (Fmt:TErrorTextIndices; data : array of const); overload; +begin + raise FPImageException.CreateFmt (ErrorText[Fmt],data); +end; + +procedure FPImgError (Fmt:TErrorTextIndices); overload; +begin + raise FPImageException.Create (ErrorText[Fmt]); +end; + +{$i fpimage.inc} +{$i fphandler.inc} +{$i fppalette.inc} +{$i fpcolcnv.inc} +{$i fpcompactimg.inc} + +function FPColor (r,g,b:word) : TFPColor; +begin + with result do + begin + red := r; + green := g; + blue := b; + alpha := alphaOpaque; + end; +end; + +function FPColor (r,g,b,a:word) : TFPColor; +begin + with result do + begin + red := r; + green := g; + blue := b; + alpha := a; + end; +end; + +{$ifdef FPC} +operator = (const c,d:TFPColor) : boolean; +begin + result := (c.Red = d.Red) and + (c.Green = d.Green) and + (c.Blue = d.Blue) and + (c.Alpha = d.Alpha); +end; +{$else} +function col_equ(const c,d:TFPColor) : boolean; +begin + result := (c.Red = d.Red) and + (c.Green = d.Green) and + (c.Blue = d.Blue) and + (c.Alpha = d.Alpha); +end; +{$endif} + +function GetFullColorData (color:TFPColor) : TColorData; +begin + result := PColorData(@color)^; +end; + +function SetFullColorData (color:TColorData) : TFPColor; +begin + result := PFPColor (@color)^; +end; + +{$ifdef FPC} +operator or (const c,d:TFPColor) : TFPColor; +begin + result := SetFullColorData(GetFullColorData(c) OR GetFullColorData(d)); +end; + +operator and (const c,d:TFPColor) : TFPColor; +begin + result := SetFullColorData(GetFullColorData(c) AND GetFullColorData(d)); +end; + +operator xor (const c,d:TFPColor) : TFPColor; +begin + result := SetFullColorData(GetFullColorData(c) XOR GetFullColorData(d)); +end; +{$else} +function col_or(const c,d:TFPColor) : TFPColor; +begin + result := SetFullColorData(GetFullColorData(c) OR GetFullColorData(d)); +end; + +function col_and(const c,d:TFPColor) : TFPColor; +begin + result := SetFullColorData(GetFullColorData(c) AND GetFullColorData(d)); +end; +function col_xor(const c,d:TFPColor) : TFPColor; +begin + result := SetFullColorData(GetFullColorData(c) XOR GetFullColorData(d)); +end; +{$endif} + +{$ifdef debug} +function MakeHex (n:TColordata;nr:byte): string; +const hexnums : array[0..15] of char = + ('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'); +var r : integer; +begin + result := ''; + for r := 0 to nr-1 do + begin + result := hexnums[n and $F] + result; + n := n shr 4; + if ((r+1) mod 4) = 0 then + result := ' ' + result; + end; +end; +{$endif} + +initialization + ImageHandlers := TImageHandlersManager.Create; + GrayConvMatrix := GCM_JPEG; + // Following lines are here because the compiler 1.0 can't work with int64 constants +(* ColorBits [cfRGB48,1] := ColorBits [cfRGB48,1] shl 16; + ColorBits [cfRGBA64,1] := ColorBits [cfRGBA64,1] shl 32; + ColorBits [cfRGBA64,2] := ColorBits [cfRGBA64,2] shl 16; + ColorBits [cfABGR64,0] := ColorBits [cfABGR64,0] shl 32; + ColorBits [cfABGR64,3] := ColorBits [cfABGR64,3] shl 16; + ColorBits [cfBGR48,3] := ColorBits [cfBGR48,3] shl 16; + PrepareBitMasks;*) + +finalization + ImageHandlers.Free; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/fppalette.inc b/mseide-msegui/lib/common/fpccompatibility/fppalette.inc new file mode 100644 index 0000000..0ff3608 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fppalette.inc @@ -0,0 +1,265 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 2003 by the Free Pascal development team + + TFPPalette implementation. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + **********************************************************************} +{ TFPPalette } + +constructor TFPPalette.create (ACount : integer); +begin + inherited create; + if aCount > 0 then + getmem (FData, sizeof(TFPColor)*ACount) + else + FData := nil; + FCapacity := ACount; + SetCount (0); +end; + +destructor TFPPalette.destroy; +begin + if FCapacity > 0 then + freemem (FData); + inherited; +end; + +procedure TFPPalette.Build (Img : TFPCustomImage); +var x,y : integer; +begin + if (Img.Palette <> self) then + begin + Count := 0; + for x := 0 to img.width-1 do + for y := 0 to img.height-1 do + IndexOf(img[x,y]); + end; +end; + +procedure TFPPalette.Copy(APalette: TFPPalette); +var + x: integer; +begin + if (APalette <> Self) then + begin + Self.Clear; + for x := 0 to APalette.Count - 1 do + Add(APalette.Color[x]) + end; +end; + +procedure TFPPalette.Merge (pal : TFPPalette); +var r : integer; +begin + for r := 0 to pal.count-1 do + IndexOf (pal[r]); +end; + +procedure TFPPalette.CheckIndex (index:integer); +begin + if (index >= FCount) or (index < 0) then + FPImgError (StrInvalidIndex,[ErrorText[StrPalette],index]); +end; + +function TFPPalette.Add (const Value:TFPColor) : integer; +begin + result := FCount; + inc (FCount); + if FCount > FCapacity then + EnlargeData; + FData^[result] := Value; +end; + +procedure TFPPalette.SetColor (index:integer; const Value:TFPColor); +begin + if index = FCount then + Add (Value) + else + begin + CheckIndex (index); + FData^[index] := Value; + end; +end; + +function TFPPalette.GetColor (index:integer) : TFPColor; +begin + CheckIndex (index); + result := FData^[index]; +end; + +function TFPPalette.GetCount : integer; +begin + result := FCount; +end; + +procedure TFPPalette.EnlargeData; +var old : integer; + NewData : PFPColorArray; +begin + old := FCapacity; + if FCapacity <= 16 then + FCapacity := 32 + else if FCapacity <= 128 then + FCapacity := 256 + else + // MG: changed to exponential growth + inc (FCapacity, FCapacity); + GetMem (NewData, sizeof(TFPColor)*FCapacity); + if old > 0 then + begin + move (FData^[0], NewData^[0], sizeof(TFPColor)*FCount); + FreeMem (FData); + end; + FData := NewData; +end; + +procedure TFPPalette.SetCount (Value:integer); +var + O : integer; +begin + if Value <> FCount then + begin + if Value > FCapacity then + begin + FCapacity := Value+8; + Reallocmem(FData,sizeof(TFPColor)*FCapacity); + end; + for o := FCount to Value-1 do + FData^[o] := colBlack; + FCount := Value; + end; +end; + +procedure TFPPalette.SetCapacity (ind : Integer); +var o : Integer; +begin + if indfcapacity then + begin + fcapacity:=ind; + Reallocmem(FData,sizeof(TFPColor)*FCapacity); + end; + if ind>count then + begin + for o := FCount to ind-1 do + FData^[o] := colBlack; + end; +end; + +function TFPPalette.IndexOf (const AColor:TFPColor) : integer; +begin + result := FCount; + repeat + dec (result); + {$ifdef FPC} + until (result < 0) or (FData^[result]=AColor); + {$else} + until (result < 0) or col_equ(FData^[result],AColor); + {$endif} + if result < 0 then + result := Add (AColor); +end; + +procedure TFPPalette.Clear; +begin + SetCount (0); +end; + + +{ Functions to create standard palettes, by Giulio Bernardi 2005 } + +{ A simple 1 bit black and white palette } +function CreateBlackAndWhitePalette : TFPPalette; +var fppal : TFPPalette; + Col : TFPColor; +begin + fppal:=TFPPalette.Create(2); + Col.Alpha:=AlphaOpaque; + Col.Red:=$FFFF; Col.Green:=$FFFF; Col.Blue:=$FFFF; + fppal.Color[0]:=Col; + Col.Red:=$0000; Col.Green:=$0000; Col.Blue:=$0000; + fppal.Color[1]:=Col; + Result:=fppal; +end; + +{ The "standard" netscape 216-color palette (aka: web safe palette) } +function CreateWebSafePalette : TFPPalette; +var Col : TFPColor; + i : integer; + fppal : TFPPalette; +begin + fppal:=TFPPalette.Create(216); + Col.Alpha:=AlphaOpaque; + i:=0; + Col.Red:=$FFFF; + while true do + begin + Col.Green:=$FFFF; + while true do + begin + Col.Blue:=$FFFF; + while true do + begin + fppal.Color[i]:=Col; + if Col.Blue=0 then break; + dec(Col.Blue,$3333); + end; + if Col.Green=0 then break; + dec(Col.Green,$3333); + end; + if Col.Red=0 then break; + dec(Col.Red,$3333); + end; + Result:=fppal; +end; + +{ A grayscale palette. Not very useful. } +function CreateGrayScalePalette : TFPPalette; +var Col : TFPColor; + i : integer; + fppal : TFPPalette; +begin + fppal:=TFPPalette.Create(256); + Col.Alpha:=AlphaOpaque; + for i:=0 to $FF do + begin + Col.Red:=i; + Col.Red:=(Col.Red shl 8) + Col.Red; + Col.Green:=Col.Red; + Col.Blue:=Col.Red; + fppal.Color[i]:=Col; + end; + Result:=fppal; +end; + +{ Standard VGA 16 color palette. } +function CreateVGAPalette : TFPPalette; +var fppal : TFPPalette; +begin + fppal:=TFPPalette.Create(16); + fppal.Color[0]:=colBlack; + fppal.Color[1]:=colNavy; + fppal.Color[2]:=colBlue; + fppal.Color[3]:=colMaroon; + fppal.Color[4]:=colPurple; + fppal.Color[5]:=colDkGreen; + fppal.Color[6]:=colRed; + fppal.Color[7]:=colTeal; + fppal.Color[8]:=colFuchsia; + fppal.Color[9]:=colOlive; + fppal.Color[10]:=colGray; + fppal.Color[11]:=colLime; + fppal.Color[12]:=colAqua; + fppal.Color[13]:=colSilver; + fppal.Color[14]:=colYellow; + fppal.Color[15]:=colWhite; + Result:=fppal; +end; diff --git a/mseide-msegui/lib/common/fpccompatibility/fpreadbmp.pas b/mseide-msegui/lib/common/fpccompatibility/fpreadbmp.pas new file mode 100644 index 0000000..1c05b01 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpreadbmp.pas @@ -0,0 +1,520 @@ +{*****************************************************************************} +{ + This file is part of the Free Pascal's "Free Components Library". + Copyright (c) 2003 by Mazen NEIFER of the Free Pascal development team + + BMP reader implementation. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +{*****************************************************************************} +{ 08/2005 by Giulio Bernardi: + - Added support for 16 and 15 bpp bitmaps. + - If we have bpp <= 8 make an indexed image instead of converting it to RGB + - Support for RLE4 and RLE8 decoding + - Support for top-down bitmaps +} +//modified 2013 by Martin Schreiber + +{$mode objfpc} +{$h+} + +unit fpreadbmp; + +interface + +uses fpimage, classes, mclasses, sysutils, bmpcomn; + +type + TFPReaderBMP = class (TFPCustomImageReader) + Private + DeltaX, DeltaY : integer; // Used for the never-used delta option in RLE + TopDown : boolean; // If set, bitmap is stored top down instead of bottom up + continue : boolean; // needed for onprogress event + percent : byte; + percentinterval : longword; + percentacc : longword; + Rect : TRect; + Procedure FreeBufs; // Free (and nil) buffers. + protected + ReadSize : Integer; // Size (in bytes) of 1 scanline. + BFI : TBitMapInfoHeader; // The header as read from the stream. + FPalette : PFPcolor; // Buffer with Palette entries. (useless now) + LineBuf : PByte; // Buffer for 1 scanline. Can be Byte, Word, TColorRGB or TColorRGBA + RedMask, GreenMask, BlueMask : longword; //Used if Compression=bi_bitfields + RedShift, GreenShift, BlueShift : shortint; + // SetupRead will allocate the needed buffers, and read the colormap if needed. + procedure SetupRead(nPalette, nRowBits: Integer; Stream : TStream); virtual; + function CountBits(Value : byte) : shortint; + function ShiftCount(Mask : longword) : shortint; + function ExpandColor(value : longword) : TFPColor; + procedure ExpandRLE8ScanLine(Row : Integer; Stream : TStream); + procedure ExpandRLE4ScanLine(Row : Integer; Stream : TStream); + procedure ReadScanLine(Row : Integer; Stream : TStream); virtual; + procedure WriteScanLine(Row : Integer; Img : TFPCustomImage); virtual; + // required by TFPCustomImageReader + procedure InternalRead (Stream:TStream; Img:TFPCustomImage); override; + function InternalCheck (Stream:TStream) : boolean; override; + public + constructor Create; override; + destructor Destroy; override; + end; + +implementation + + +function RGBAToFPColor(Const RGBA: TColorRGBA) : TFPcolor; + +begin + with Result, RGBA do + begin + Red :=(R shl 8) or R; + Green :=(G shl 8) or G; + Blue :=(B shl 8) or B; + Alpha :=255-A; + Alpha :=(Alpha shl 8) or Alpha + end; +end; + +Function RGBToFPColor(Const RGB : TColorRGB) : TFPColor; + +begin + with Result,RGB do + begin {Use only the high byte to convert the color} + Red := (R shl 8) + R; + Green := (G shl 8) + G; + Blue := (B shl 8) + B; + Alpha := AlphaOpaque; + end; +end; + +Constructor TFPReaderBMP.create; + +begin + inherited create; +end; + +Destructor TFPReaderBMP.Destroy; + +begin + FreeBufs; + inherited destroy; +end; + +Procedure TFPReaderBMP.FreeBufs; + +begin + If (LineBuf<>Nil) then + begin + FreeMem(LineBuf); + LineBuf:=Nil; + end; + If (FPalette<>Nil) then + begin + FreeMem(FPalette); + FPalette:=Nil; + end; +end; + +{ Counts how many bits are set } +function TFPReaderBMP.CountBits(Value : byte) : shortint; +var i,bits : shortint; +begin + bits:=0; + for i:=0 to 7 do + begin + if (value mod 2)<>0 then inc(bits); + value:=value shr 1; + end; + Result:=bits; +end; + +{ If compression is bi_bitfields, there could be arbitrary masks for colors. + Although this is not compatible with windows9x it's better to know how to read these bitmaps + We must determine how to switch the value once masked + Example: 0000 0111 1110 0000, if we shr 5 we have 00XX XXXX for the color, but these bits must be the + highest in the color, so we must shr (5-(8-6))=3, and we have XXXX XX00. + A negative value means "shift left" } +function TFPReaderBMP.ShiftCount(Mask : longword) : shortint; +var tmp : shortint; +begin + tmp:=0; + if Mask=0 then + begin + Result:=0; + exit; + end; + + while (Mask mod 2)=0 do { rightmost bit is 0 } + begin + inc(tmp); + Mask:= Mask shr 1; + end; + tmp:=tmp-(8-CountBits(Mask and $FF)); + Result:=tmp; +end; + +function TFPReaderBMP.ExpandColor(value : longword) : TFPColor; +var tmpr, tmpg, tmpb : longword; + col : TColorRGB; +begin + {$IFDEF ENDIAN_BIG} + value:=swap(value); + {$ENDIF} + tmpr:=value and RedMask; + tmpg:=value and GreenMask; + tmpb:=value and BlueMask; + if RedShift < 0 then col.R:=byte(tmpr shl (-RedShift)) + else col.R:=byte(tmpr shr RedShift); + if GreenShift < 0 then col.G:=byte(tmpg shl (-GreenShift)) + else col.G:=byte(tmpg shr GreenShift); + if BlueShift < 0 then col.B:=byte(tmpb shl (-BlueShift)) + else col.B:=byte(tmpb shr BlueShift); + Result:=RGBToFPColor(col); +end; + +procedure TFPReaderBMP.SetupRead(nPalette, nRowBits: Integer; Stream : TStream); + +var + ColInfo: ARRAY OF TColorRGBA; + i: Integer; + +begin + if ((BFI.Compression=BI_RGB) and (BFI.BitCount=16)) then { 5 bits per channel, fixed mask } + begin + RedMask:=$7C00; RedShift:=7; + GreenMask:=$03E0; GreenShift:=2; + BlueMask:=$001F; BlueShift:=-3; + end + else if ((BFI.Compression=BI_BITFIELDS) and (BFI.BitCount in [16,32])) then { arbitrary mask } + begin + Stream.Read(RedMask,4); + Stream.Read(GreenMask,4); + Stream.Read(BlueMask,4); + {$IFDEF ENDIAN_BIG} + RedMask:=swap(RedMask); + GreenMask:=swap(GreenMask); + BlueMask:=swap(BlueMask); + {$ENDIF} + RedShift:=ShiftCount(RedMask); + GreenShift:=ShiftCount(GreenMask); + BlueShift:=ShiftCount(BlueMask); + end + else if nPalette>0 then + begin + GetMem(FPalette, nPalette*SizeOf(TFPColor)); + SetLength(ColInfo, nPalette); + if BFI.ClrUsed>0 then + Stream.Read(ColInfo[0],BFI.ClrUsed*SizeOf(TColorRGBA)) + else // Seems to me that this is dangerous. + Stream.Read(ColInfo[0],nPalette*SizeOf(TColorRGBA)); + for i := 0 to High(ColInfo) do + FPalette[i] := RGBAToFPColor(ColInfo[i]); + end + else if BFI.ClrUsed>0 then { Skip palette } + Stream.Position := Stream.Position + BFI.ClrUsed*SizeOf(TColorRGBA); + ReadSize:=((nRowBits + 31) div 32) shl 2; + GetMem(LineBuf,ReadSize); +end; + +procedure TFPReaderBMP.InternalRead(Stream:TStream; Img:TFPCustomImage); + +Var + Row, i, pallen : Integer; + BadCompression : boolean; +begin + Rect.Left:=0; Rect.Top:=0; Rect.Right:=0; Rect.Bottom:=0; + continue:=true; + Progress(psStarting,0,false,Rect,'',continue); + if not continue then exit; + Stream.Read(BFI,SizeOf(BFI)); + {$IFDEF ENDIAN_BIG} + SwapBMPInfoHeader(BFI); + {$ENDIF} + { This will move past any junk after the BFI header } + Stream.Position:=Stream.Position-SizeOf(BFI)+BFI.Size; + with BFI do + begin + BadCompression:=false; + if ((Compression=BI_RLE4) and (BitCount<>4)) then BadCompression:=true; + if ((Compression=BI_RLE8) and (BitCount<>8)) then BadCompression:=true; + if ((Compression=BI_BITFIELDS) and (not (BitCount in [16,32]))) then BadCompression:=true; + if not (Compression in [BI_RGB..BI_BITFIELDS]) then BadCompression:=true; + if BadCompression then + raise FPImageException.Create('Bad BMP compression mode'); + TopDown:=(Height<0); + Height:=abs(Height); + if (TopDown and (not (Compression in [BI_RGB,BI_BITFIELDS]))) then + raise FPImageException.Create('Top-down bitmaps cannot be compressed'); + Img.SetSize(0,0); + if BitCount<=8 then + begin + Img.UsePalette:=true; + Img.Palette.Clear; + end + else Img.UsePalette:=false; + Case BFI.BitCount of + 1 : { Monochrome } + SetupRead(2,Width,Stream); + 4 : + SetupRead(16,Width*4,Stream); + 8 : + SetupRead(256,Width*8,Stream); + 16 : + SetupRead(0,Width*8*2,Stream); + 24: + SetupRead(0,Width*8*3,Stream); + 32: + SetupRead(0,Width*8*4,Stream); + end; + end; + Try + { Note: it would be better to Fill the image palette in setupread instead of creating FPalette. + FPalette is indeed useless but we cannot remove it since it's not private :\ } + pallen:=0; + if BFI.BitCount<=8 then + if BFI.ClrUsed>0 then pallen:=BFI.ClrUsed + else pallen:=(1 shl BFI.BitCount); + if pallen>0 then + begin + Img.Palette.Count:=pallen; + for i:=0 to pallen-1 do + Img.Palette.Color[i]:=FPalette[i]; + end; + Img.SetSize(BFI.Width,BFI.Height); + + percent:=0; + percentinterval:=(Img.Height*4) div 100; + if percentinterval=0 then percentinterval:=$FFFFFFFF; + percentacc:=0; + + DeltaX:=-1; DeltaY:=-1; + if TopDown then + for Row:=0 to Img.Height-1 do { A rare case of top-down bitmap! } + begin + ReadScanLine(Row,Stream); // Scanline in LineBuf with Size ReadSize. + WriteScanLine(Row,Img); + if not continue then exit; + end + else + for Row:=Img.Height-1 downto 0 do + begin + ReadScanLine(Row,Stream); // Scanline in LineBuf with Size ReadSize. + WriteScanLine(Row,Img); + if not continue then exit; + end; + Progress(psEnding,100,false,Rect,'',continue); + finally + FreeBufs; + end; +end; + +procedure TFPReaderBMP.ExpandRLE8ScanLine(Row : Integer; Stream : TStream); +var i,j : integer; + b0, b1 : byte; +begin + i:=0; + while true do + begin + { let's see if we must skip pixels because of delta... } + if DeltaY<>-1 then + begin + if Row=DeltaY then j:=DeltaX { If we are on the same line, skip till DeltaX } + else j:=ReadSize; { else skip up to the end of this line } + while (i0 then { number of repetitions } + begin + if b0+i>ReadSize then + raise FPImageException.Create('Bad BMP RLE chunk at row '+inttostr(row)+', col '+inttostr(i)+', file offset $'+inttohex(Stream.Position,16) ); + j:=i+b0; + while (iReadSize then + raise FPImageException.Create('Bad BMP RLE chunk at row '+inttostr(row)+', col '+inttostr(i)+', file offset $'+inttohex(Stream.Position,16) ); + Stream.Read(LineBuf[i],b1); + inc(i,b1); + { aligned on 2 bytes boundary: every group starts on a 2 bytes boundary, but absolute group + could end on odd address if there is a odd number of elements, so we pad it } + if (b1 mod 2)<>0 then Stream.Seek(1,soFromCurrent); + end; + end; + end; +end; + +procedure TFPReaderBMP.ExpandRLE4ScanLine(Row : Integer; Stream : TStream); +var i,j,tmpsize : integer; + b0, b1 : byte; + nibline : pbyte; { temporary array of nibbles } + even : boolean; +begin + tmpsize:=ReadSize*2; { ReadSize is in bytes, while nibline is made of nibbles, so it's 2*readsize long } + getmem(nibline,tmpsize); + if nibline=nil then + raise FPImageException.Create('Out of memory'); + try + i:=0; + while true do + begin + { let's see if we must skip pixels because of delta... } + if DeltaY<>-1 then + begin + if Row=DeltaY then j:=DeltaX { If we are on the same line, skip till DeltaX } + else j:=tmpsize; { else skip up to the end of this line } + while (i0 then { number of repetitions } + begin + if b0+i>tmpsize then + raise FPImageException.Create('Bad BMP RLE chunk at row '+inttostr(row)+', col '+inttostr(i)+', file offset $'+inttohex(Stream.Position,16) ); + even:=true; + j:=i+b0; + while (itmpsize then + raise FPImageException.Create('Bad BMP RLE chunk at row '+inttostr(row)+', col '+inttostr(i)+', file offset $'+inttohex(Stream.Position,16) ); + j:=i+b1; + even:=true; + while (i0 then Stream.Seek(1,soFromCurrent); + end; + end; + end; + { pack the nibline into the linebuf } + for i:=0 to ReadSize-1 do + LineBuf[i]:=(NibLine[i*2] shl 4) or NibLine[i*2+1]; + finally + FreeMem(nibline) + end; +end; + +procedure TFPReaderBMP.ReadScanLine(Row : Integer; Stream : TStream); +begin + if BFI.Compression=BI_RLE8 then ExpandRLE8ScanLine(Row,Stream) + else if BFI.Compression=BI_RLE4 then ExpandRLE4ScanLine(Row,Stream) + else Stream.Read(LineBuf[0],ReadSize); +end; + +procedure TFPReaderBMP.WriteScanLine(Row : Integer; Img : TFPCustomImage); + +Var + Column : Integer; + +begin + Case BFI.BitCount of + 1 : + for Column:=0 to Img.Width-1 do + if ((LineBuf[Column div 8] shr (7-(Column and 7)) ) and 1) <> 0 then + img.Pixels[Column,Row]:=1 + else + img.Pixels[Column,Row]:=0; + 4 : + for Column:=0 to img.Width-1 do + img.Pixels[Column,Row]:=(LineBuf[Column div 2] shr (((Column+1) and 1)*4)) and $0f; + 8 : + for Column:=0 to img.Width-1 do + img.Pixels[Column,Row]:=LineBuf[Column]; + 16 : + for Column:=0 to img.Width-1 do + img.colors[Column,Row]:=ExpandColor(PWord(LineBuf)[Column]); + 24 : + for Column:=0 to img.Width-1 do + img.colors[Column,Row]:=RGBToFPColor(PColorRGB(LineBuf)[Column]); + 32 : + for Column:=0 to img.Width-1 do + if BFI.Compression=BI_BITFIELDS then + img.colors[Column,Row]:=ExpandColor(PLongWord(LineBuf)[Column]) + else + img.colors[Column,Row]:=RGBAToFPColor(PColorRGBA(LineBuf)[Column]); + end; + + inc(percentacc,4); + if percentacc>=percentinterval then + begin + percent:=percent+(percentacc div percentinterval); + percentacc:=percentacc mod percentinterval; + Progress(psRunning,percent,false,Rect,'',continue); + end; +end; + +function TFPReaderBMP.InternalCheck (Stream:TStream) : boolean; + +var + BFH:TBitMapFileHeader; +begin + stream.Read(BFH,SizeOf(BFH)); + {$IFDEF ENDIAN_BIG} + SwapBMPFileHeader(BFH); + {$ENDIF} + With BFH do + Result:=(bfType=BMmagic); // Just check magic number +end; + +initialization + ImageHandlers.RegisterImageReader ('BMP Format', 'bmp', TFPReaderBMP); +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/fpreadgif.pas b/mseide-msegui/lib/common/fpccompatibility/fpreadgif.pas new file mode 100644 index 0000000..0b86789 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpreadgif.pas @@ -0,0 +1,544 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 2008 by the Free Pascal development team + + GIF reader for fpImage. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + ********************************************************************** + + ToDo: read further images +} +unit FPReadGif; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, FPimage; + +type + TGifRGB = packed record + Red, Green, Blue : Byte; + end; + + TGIFHeader = packed record + Signature:array[0..2] of Char; //* Header Signature (always "GIF") */ + Version:array[0..2] of Char; //* GIF format version("87a" or "89a") */ + // Logical Screen Descriptor + ScreenWidth:word; //* Width of Display Screen in Pixels */ + ScreenHeight:word; //* Height of Display Screen in Pixels */ + Packedbit, //* Screen and Color Map Information */ + BackgroundColor, //* Background Color Index */ + AspectRatio:byte; //* Pixel Aspect Ratio */ + end; + + TGifImageDescriptor = packed record + Left, //* X position of image on the display */ + Top, //* Y position of image on the display */ + Width, //* Width of the image in pixels */ + Height:word; //* Height of the image in pixels */ + Packedbit:byte; //* Image and Color Table Data Information */ + end; + + TGifGraphicsControlExtension = packed record + BlockSize, //* Size of remaining fields (always 04h) */ + Packedbit:byte; //* Method of graphics disposal to use */ + DelayTime:word; //* Hundredths of seconds to wait */ + ColorIndex, //* Transparent Color Index */ + Terminator:byte; //* Block Terminator (always 0) */ + end; + + TFPReaderGif = class; + + TGifCreateCompatibleImgEvent = procedure(Sender: TFPReaderGif; + var NewImage: TFPCustomImage) of object; + + { TFPReaderGif } + + TFPReaderGif = class(TFPCustomImageReader) + protected + FHeader: TGIFHeader; + FDescriptor: TGifImageDescriptor; + FGraphicsCtrlExt: TGifGraphicsControlExtension; + FTransparent: Boolean; + FGraphCtrlExt: Boolean; + FScanLine: PByte; + FLineSize: Integer; + FPalette: TFPPalette; + FWidth: integer; + FHeight: Integer; + FInterlace: boolean; + FBitsPerPixel: byte; + FBackground: byte; + FResolution: byte; + FOnCreateImage: TGifCreateCompatibleImgEvent; + procedure ReadPalette(Stream: TStream; Size: integer); + function AnalyzeHeader: Boolean; + procedure InternalRead(Stream: TStream; Img: TFPCustomImage); override; + function ReadScanLine(Stream: TStream): boolean; virtual; + function WriteScanLine(Img: TFPCustomImage): Boolean; virtual; + function InternalCheck (Stream: TStream) : boolean; override; + function SkipBlock(Stream: TStream): byte; + public + constructor Create; override; + destructor Destroy; override; + property Header: TGIFHeader read FHeader; + property Descriptor: TGifImageDescriptor read FDescriptor; + property GraphCtrlExt: Boolean read FGraphCtrlExt; + property GraphicsCtrlExt: TGifGraphicsControlExtension read FGraphicsCtrlExt; + property Transparent: Boolean read FTransparent; + property Palette: TFPPalette read FPalette; + property Width: integer read FWidth; + property Height: Integer read FHeight; + property Interlace: boolean read FInterlace; + property BitsPerPixel: byte read FBitsPerPixel; + property Background: byte read FBackground; + property Resolution: byte read FResolution; + property OnCreateImage: TGifCreateCompatibleImgEvent read FOnCreateImage write FOnCreateImage; + end; + +implementation + +{ TFPReaderGif } + +procedure TFPReaderGif.ReadPalette(Stream: TStream; Size: integer); +Var + RGBEntry : TGifRGB; + I : Integer; + c : TFPColor; +begin + FPalette.count := 0; + For I:=0 To Size-1 Do + Begin + Stream.Read(RGBEntry, SizeOf(RGBEntry)); + With c do + begin + Red:=RGBEntry.Red or (RGBEntry.Red shl 8); + Green:=RGBEntry.Green or (RGBEntry.Green shl 8); + Blue:=RGBEntry.Blue or (RGBEntry.Blue shl 8); + Alpha:=alphaOpaque; + end; + FPalette.Add(C); + End; +end; + +function TFPReaderGif.AnalyzeHeader: Boolean; +var + C : TFPColor; +begin + Result:=false; + With FHeader do + begin + if (Signature = 'GIF') and + ((Version = '87a') or + (Version = '89a')) then + else + Raise Exception.Create('Unknown/Unsupported GIF image type'); + + FResolution := Packedbit and $70 shr 5 + 1; + FBitsPerPixel:=Packedbit and 7 + 1; + FBackground := BackgroundColor; + + With FDescriptor do + begin + fWidth:=Width; + fHeight:=Height; + FInterlace := (Packedbit and $40 = $40); + end; + FTransparent:= FBackground <> 0; + if FGraphCtrlExt then + begin + FTransparent:=(FGraphicsCtrlExt.Packedbit and $01)<>0; + If FTransparent then + FBackground:=FGraphicsCtrlExt.ColorIndex; + end; + FLineSize:=FWidth*(FHeight+1); + GetMem(FScanLine,FLineSize); + If FTransparent then + begin + C:=FPalette.Color[FBackground]; + C.alpha:=alphaTransparent; + FPalette.Color[FBackground]:=C; + end; + end; + Result:=true; +end; + +procedure TFPReaderGif.InternalRead(Stream: TStream; Img: TFPCustomImage); +var + Introducer:byte; + ColorTableSize :Integer; + ContProgress: Boolean; +begin + FPalette:=nil; + FScanLine:=nil; + try + ContProgress:=true; + Progress(psStarting, 0, False, Rect(0,0,0,0), '', ContProgress); + if not ContProgress then exit; + + FPalette := TFPPalette.Create(0); + + Stream.Position:=0; + // header + Stream.Read(FHeader,SizeOf(FHeader)); + Progress(psRunning, trunc(100.0 * (Stream.position / Stream.size)), False, Rect(0,0,0,0), '', ContProgress); + if not ContProgress then exit; + + // Endian Fix Mantis 8541. Gif is always little endian + {$IFDEF ENDIAN_BIG} + with FHeader do + begin + ScreenWidth := LEtoN(ScreenWidth); + ScreenHeight := LEtoN(ScreenHeight); + end; + {$ENDIF} + // global palette + if (FHeader.Packedbit and $80) <> 0 then + begin + ColorTableSize := FHeader.Packedbit and 7 + 1; + ReadPalette(stream, 1 shl ColorTableSize); + end; + + // skip extensions + Repeat + Introducer:=SkipBlock(Stream); + until (Introducer = $2C) or (Introducer = $3B); + + // descriptor + Stream.Read(FDescriptor, SizeOf(FDescriptor)); + {$IFDEF ENDIAN_BIG} + with FDescriptor do + begin + Left := LEtoN(Left); + Top := LEtoN(Top); + Width := LEtoN(Width); + Height := LEtoN(Height); + end; + {$ENDIF} + // local palette + if (FDescriptor.Packedbit and $80) <> 0 then + begin + ColorTableSize := FDescriptor.Packedbit and 7 + 1; + ReadPalette(stream, 1 shl ColorTableSize); + end; + + // parse header + if not AnalyzeHeader then exit; + + // create image + if Assigned(OnCreateImage) then + OnCreateImage(Self,Img); + Img.SetSize(FWidth,FHeight); + + // read pixels + if not ReadScanLine(Stream) then exit; + if not WriteScanLine(Img) then exit; + + // ToDo: read further images + finally + FreeAndNil(FPalette); + ReAllocMem(FScanLine,0); + end; + Progress(FPimage.psEnding, 100, false, Rect(0,0,FWidth,FHeight), '', ContProgress); +end; + +function TFPReaderGif.ReadScanLine(Stream: TStream): Boolean; +var + OldPos, + UnpackedSize, + PackedSize:longint; + I: Integer; + Data, + Bits, + Code: Cardinal; + SourcePtr: PByte; + InCode: Cardinal; + + CodeSize: Cardinal; + CodeMask: Cardinal; + FreeCode: Cardinal; + OldCode: Cardinal; + Prefix: array[0..4095] of Cardinal; + Suffix, + Stack: array [0..4095] of Byte; + StackPointer: PByte; + DataComp, + Target: PByte; + B, + FInitialCodeSize, + FirstChar: Byte; + ClearCode, + EOICode: Word; + ContProgress: Boolean; + +begin + DataComp:=nil; + ContProgress:=true; + try + // read dictionary size + Stream.read(FInitialCodeSize, 1); + + // search end of compressor table + OldPos:=Stream.Position; + PackedSize := 0; + Repeat + Stream.read(B, 1); + if B > 0 then + begin + inc(PackedSize, B); + Stream.Seek(B, soFromCurrent); + CodeMask := (1 shl CodeSize) - 1; + end; + until B = 0; + + Progress(psRunning, trunc(100.0 * (Stream.position / Stream.size)), + False, Rect(0,0,0,0), '', ContProgress); + if not ContProgress then exit(false); + + Getmem(DataComp, PackedSize); + // read compressor table + SourcePtr:=DataComp; + Stream.Position:=OldPos; + Repeat + Stream.read(B, 1); + if B > 0 then + begin + Stream.ReadBuffer(SourcePtr^, B); + Inc(SourcePtr,B); + end; + until B = 0; + + Progress(psRunning, trunc(100.0 * (Stream.position / Stream.size)), + False, Rect(0,0,0,0), '', ContProgress); + if not ContProgress then exit(false); + + SourcePtr:=DataComp; + Target := FScanLine; + CodeSize := FInitialCodeSize + 1; + ClearCode := 1 shl FInitialCodeSize; + EOICode := ClearCode + 1; + FreeCode := ClearCode + 2; + OldCode := 4096; + CodeMask := (1 shl CodeSize) - 1; + UnpackedSize:=FWidth * FHeight; + for I := 0 to ClearCode - 1 do + begin + Prefix[I] := 4096; + Suffix[I] := I; + end; + StackPointer := @Stack; + FirstChar := 0; + Data := 0; + Bits := 0; + // LZW decompression gif + while (UnpackedSize > 0) and (PackedSize > 0) do + begin + Inc(Data, SourcePtr^ shl Bits); + Inc(Bits, 8); + while Bits >= CodeSize do + begin + Code := Data and CodeMask; + Data := Data shr CodeSize; + Dec(Bits, CodeSize); + if Code = EOICode then Break; + if Code = ClearCode then + begin + CodeSize := FInitialCodeSize + 1; + CodeMask := (1 shl CodeSize) - 1; + FreeCode := ClearCode + 2; + OldCode := 4096; + Continue; + end; + if Code > FreeCode then Break; + if OldCode = 4096 then + begin + FirstChar := Suffix[Code]; + Target^ := FirstChar; + Inc(Target); + Dec(UnpackedSize); + OldCode := Code; + Continue; + end; + InCode := Code; + if Code = FreeCode then + begin + StackPointer^ := FirstChar; + Inc(StackPointer); + Code := OldCode; + end; + while Code > ClearCode do + begin + StackPointer^ := Suffix[Code]; + Inc(StackPointer); + Code := Prefix[Code]; + end; + FirstChar := Suffix[Code]; + StackPointer^ := FirstChar; + Inc(StackPointer); + Prefix[FreeCode] := OldCode; + Suffix[FreeCode] := FirstChar; + if (FreeCode = CodeMask) and + (CodeSize < 12) then + begin + Inc(CodeSize); + CodeMask := (1 shl CodeSize) - 1; + end; + if FreeCode < 4095 then Inc(FreeCode); + OldCode := InCode; + repeat + Dec(StackPointer); + Target^ := StackPointer^; + Inc(Target); + Dec(UnpackedSize); + until StackPointer = @Stack; + end; + Inc(SourcePtr); + Dec(PackedSize); + end; + Progress(psRunning, trunc(100.0 * (Stream.position / Stream.size)), + False, Rect(0,0,0,0), '', ContProgress); + if not ContProgress then exit(false); + finally + if DataComp<>nil then + FreeMem(DataComp); + end; + Result:=true; +end; + +function TFPReaderGif.WriteScanLine(Img: TFPCustomImage): Boolean; +Var + Row, Col : Integer; + Pass, Every : byte; + P : PByte; + function IsMultiple(NumberA, NumberB: Integer): Boolean; + begin + Result := (NumberA >= NumberB) and + (NumberB > 0) and + (NumberA mod NumberB = 0); + end; +begin + Result:=false; + P:=FScanLine; + If FInterlace then + begin + For Pass := 1 to 4 do + begin + Case Pass of + 1 : begin + Row := 0; + Every := 8; + end; + 2 : begin + Row := 4; + Every := 8; + end; + 3 : begin + Row := 2; + Every := 4; + end; + 4 : begin + Row := 1; + Every := 2; + end; + end; + Repeat + for Col:=0 to Img.Width-1 do + begin + Img.Colors[Col,Row]:=FPalette[P^]; + Inc(P); + end; + Inc(Row, Every); + until Row >= Img.Height; + end; + end + else + begin + for Row:=0 to Img.Height-1 do + for Col:=0 to Img.Width-1 do + begin + Img.Colors[Col,Row]:=FPalette[P^]; + Inc(P); + end; + end; + Result:=true; +end; + +function TFPReaderGif.InternalCheck(Stream: TStream): boolean; +var + OldPos: Int64; +begin + try + OldPos:=Stream.Position; + Stream.Read(FHeader,SizeOf(FHeader)); + Result:=(FHeader.Signature = 'GIF') and + ((FHeader.Version = '87a') or (FHeader.Version = '89a')); + Stream.Position:=OldPos; + except + Result:=False; + end; +end; + +function TFPReaderGif.SkipBlock(Stream: TStream): byte; +var + Introducer, + Labels, + SkipByte : byte; +begin + Stream.read(Introducer,1); + if Introducer = $21 then + begin + Stream.read(Labels,1); + Case Labels of + $FE, $FF : // Comment Extension block or Application Extension block + while true do + begin + Stream.Read(SkipByte, 1); + if SkipByte = 0 then Break; + Stream.Seek(SkipByte, soFromCurrent); + end; + $F9 : // Graphics Control Extension block + begin + Stream.Read(FGraphicsCtrlExt, SizeOf(FGraphicsCtrlExt)); + FGraphCtrlExt:=True; + end; + $01 : // Plain Text Extension block + begin + Stream.Read(SkipByte, 1); + Stream.Seek(SkipByte, soFromCurrent); + while true do + begin + Stream.Read(SkipByte, 1); + if SkipByte = 0 then Break; + Stream.Seek(SkipByte, soFromCurrent); + end; + end; + end; + end; + Result:=Introducer; +end; + +constructor TFPReaderGif.Create; +begin + inherited Create; + +end; + +destructor TFPReaderGif.Destroy; +begin + + inherited Destroy; +end; + +initialization + ImageHandlers.RegisterImageReader ('GIF Graphics', 'gif', TFPReaderGif); +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/fpreadjpeg.pas b/mseide-msegui/lib/common/fpccompatibility/fpreadjpeg.pas new file mode 100644 index 0000000..1948b4c --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpreadjpeg.pas @@ -0,0 +1,482 @@ +{ Copyright (C) 2003 Mattias Gaertner + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License + for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + ToDo: + - palette + + Modified 2013 by Martin Schreiber + +} +unit fpreadjpeg; +{$ifdef FPC}{$mode objfpc}{$H+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses, sysutils,fpimage, +// {$ifdef FPC} +// jpeglib, jdapimin,jdatasrc, jdapistd, jmorecfg +// {$else} + jpeglib_del, jdapimin_del,jdatasrc_del, jdapistd_del, jmorecfg_del +// {$endif}; +; +type + { TFPReaderJPEG } + { This is a FPImage reader for jpeg images. } + + TFPReaderJPEG = class; + + PFPJPEGProgressManager = ^TFPJPEGProgressManager; + TFPJPEGProgressManager = record + pub : jpeg_progress_mgr; + instance: TObject; + last_pass: Integer; + last_pct: Integer; + last_time: Integer; + last_scanline: Integer; + end; + + TJPEGScale = (jsFullSize, jsHalf, jsQuarter, jsEighth); + TJPEGReadPerformance = (jpBestQuality, jpBestSpeed); + + TFPReaderJPEG = class(TFPCustomImageReader) + private + FSmoothing: boolean; + FMinHeight:integer; + FMinWidth:integer; + FWidth: Integer; + FHeight: Integer; + FGrayscale: boolean; + FProgressiveEncoding: boolean; + FError: jpeg_error_mgr; + FProgressMgr: TFPJPEGProgressManager; + FInfo: jpeg_decompress_struct; + FScale: TJPEGScale; + FPerformance: TJPEGReadPerformance; + procedure SetPerformance(const AValue: TJPEGReadPerformance); + procedure SetSmoothing(const AValue: boolean); + protected + procedure InternalRead(Str: TStream; Img: TFPCustomImage); override; + function InternalCheck(Str: TStream): boolean; override; + public + constructor Create; override; + destructor Destroy; override; + property GrayScale: boolean read FGrayscale; + property ProgressiveEncoding: boolean read FProgressiveEncoding; + property Smoothing: boolean read FSmoothing write SetSmoothing; + property Performance: TJPEGReadPerformance read FPerformance write SetPerformance; + property Scale: TJPEGScale read FScale write FScale; + property MinWidth:integer read FMinWidth write FMinWidth; + property MinHeight:integer read FMinHeight write FMinHeight; + end; + +implementation +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +procedure ReadCompleteStreamToStream(SrcStream, DestStream: TStream; + StartSize: integer); +var + NewLength: Integer; + ReadLen: Integer; + Buffer: string; +begin + if (SrcStream is TMemoryStream) or (SrcStream is TFileStream) + or (SrcStream is TStringStream) + then begin + // read as one block + DestStream.CopyFrom(SrcStream,SrcStream.Size-SrcStream.Position); + end else begin + // read exponential + if StartSize<=0 then StartSize:=1024; + SetLength(Buffer,StartSize); + NewLength:=0; + repeat + ReadLen:=SrcStream.Read(Buffer[NewLength+1],length(Buffer)-NewLength); + inc(NewLength,ReadLen); + if NewLength0 then + DestStream.Write(Buffer[1],NewLength); + end; +end; + +procedure JPEGError(CurInfo: j_common_ptr); +begin + if CurInfo=nil then exit; + raise Exception.CreateFmt('JPEG error',[CurInfo^.err^.msg_code]); +end; + +procedure EmitMessage(CurInfo: j_common_ptr; msg_level: Integer); +begin + if CurInfo=nil then exit; + if msg_level=0 then ; +end; + +procedure OutputMessage(CurInfo: j_common_ptr); +begin + if CurInfo=nil then exit; +end; + +procedure FormatMessage(CurInfo: j_common_ptr; var buffer: string); +begin + if CurInfo=nil then exit; + {$ifdef FPC_Debug_Image} + writeln('FormatMessage ',buffer); + {$endif} +end; + +procedure ResetErrorMgr(CurInfo: j_common_ptr); +begin + if CurInfo=nil then exit; + CurInfo^.err^.num_warnings := 0; + CurInfo^.err^.msg_code := 0; +end; + + +var + jpeg_std_error: jpeg_error_mgr; + +procedure ProgressCallback(CurInfo: j_common_ptr); +begin + if CurInfo=nil then exit; + // ToDo +end; + +{ TFPReaderJPEG } + +procedure TFPReaderJPEG.SetSmoothing(const AValue: boolean); +begin + if FSmoothing=AValue then exit; + FSmoothing:=AValue; +end; + +procedure TFPReaderJPEG.SetPerformance(const AValue: TJPEGReadPerformance); +begin + if FPerformance=AValue then exit; + FPerformance:=AValue; +end; + +procedure TFPReaderJPEG.InternalRead(Str: TStream; Img: TFPCustomImage); +var + MemStream: TMemoryStream; + + procedure SetSource; + begin + MemStream.Position:=0; + jpeg_stdio_src(@FInfo, @MemStream); + end; + + procedure ReadHeader; + begin + jpeg_read_header(@FInfo, TRUE); + FWidth := FInfo.image_width; + FHeight := FInfo.image_height; + FGrayscale := FInfo.jpeg_color_space = JCS_GRAYSCALE; + FProgressiveEncoding := jpeg_has_multiple_scans(@FInfo); + end; + + procedure InitReadingPixels; + var d1,d2:integer; + + function DToScale(inp:integer):TJPEGScale; + begin + if inp>7 then Result:=jsEighth else + if inp>3 then Result:=jsQuarter else + if inp>1 then Result:=jsHalf else + Result:=jsFullSize; + end; + + begin + FInfo.scale_num := 1; + + if (FMinWidth>0) and (FMinHeight>0) then + if (FInfo.image_width>FMinWidth) or (FInfo.image_height>FMinHeight) then + begin + d1:=Round((FInfo.image_width / FMinWidth)-0.5); + d2:=Round((FInfo.image_height / FMinHeight)-0.5); + if d1>d2 then fScale:=DToScale(d2) else fScale:=DtoScale(d1); + end; + + FInfo.scale_denom :=1 shl Byte(FScale); //1 + FInfo.do_block_smoothing := FSmoothing; + + if FGrayscale then FInfo.out_color_space := JCS_GRAYSCALE; + if (FInfo.out_color_space = JCS_GRAYSCALE) then + begin + FInfo.quantize_colors := True; + FInfo.desired_number_of_colors := 236; + end; + + if FPerformance = jpBestSpeed then + begin + FInfo.dct_method := JDCT_IFAST; + FInfo.two_pass_quantize := False; + FInfo.dither_mode := JDITHER_ORDERED; + // FInfo.do_fancy_upsampling := False; can create an AV inside jpeglib + end; + + if FProgressiveEncoding then + begin + FInfo.enable_2pass_quant := FInfo.two_pass_quantize; + FInfo.buffered_image := True; + end; + end; + + function CorrectCMYK(const C: TFPColor): TFPColor; + var + MinColor: word; + begin + if C.red$FF then MinColor:=$FF-C.alpha; + Result.red:=(C.red-MinColor) shl 8; + Result.green:=(C.green-MinColor) shl 8; + Result.blue:=(C.blue-MinColor) shl 8; + Result.alpha:=alphaOpaque; + end; + procedure ReadPixels; + var + Continue: Boolean; + SampArray: JSAMPARRAY; + SampRow: JSAMPROW; + Color: TFPColor; + LinesRead: Cardinal; +// x: Integer; + y: Integer; + c: word; + Status,Scan: integer; + ReturnValue,RestartLoop: Boolean; + procedure OutputScanLines(); + var + x: integer; + begin + Color.Alpha:=alphaOpaque; + y:=0; + while (FInfo.output_scanline < FInfo.output_height) do begin + // read one line per call + LinesRead := jpeg_read_scanlines(@FInfo, SampArray, 1); + if LinesRead<1 then begin + ReturnValue:=false; + break; + end; + if (FInfo.jpeg_color_space = JCS_CMYK) then + for x:=0 to FInfo.output_width-1 do begin + Color.Red:=SampRow^[x*4+0]; + Color.Green:=SampRow^[x*4+1]; + Color.Blue:=SampRow^[x*4+2]; + Color.alpha:=SampRow^[x*4+3]; + Img.Colors[x,y]:=CorrectCMYK(Color); + end + else + if fgrayscale then begin + for x:=0 to FInfo.output_width-1 do begin + c:= SampRow^[x] shl 8; + Color.Red:=c; + Color.Green:=c; + Color.Blue:=c; + Img.Colors[x,y]:=Color; + end; + end + else begin + for x:=0 to FInfo.output_width-1 do begin + Color.Red:=SampRow^[x*3+0] shl 8; + Color.Green:=SampRow^[x*3+1] shl 8; + Color.Blue:=SampRow^[x*3+2] shl 8; + Img.Colors[x,y]:=Color; + end; + end; + inc(y); + end; + end; + begin + InitReadingPixels; + + Continue:=true; + Progress(psStarting, 0, False, Rect(0,0,0,0), '', Continue); + if not Continue then exit; + + jpeg_start_decompress(@FInfo); + + Img.SetSize(FInfo.output_width,FInfo.output_height); + + GetMem(SampArray,SizeOf(JSAMPROW)); + GetMem(SampRow,FInfo.output_width*FInfo.output_components); + SampArray^[0]:=SampRow; + try + case FProgressiveEncoding of + false: + begin + ReturnValue:=true; + OutputScanLines(); + if FInfo.buffered_image then jpeg_finish_output(@FInfo); + end; + true: + begin + while true do begin + (* The RestartLoop variable drops a placeholder for suspension + mode, or partial jpeg decode, return and continue. In case + of support this suspension, the RestartLoop:=True should be + changed by an Exit and in the routine enter detects that it + is being called from a suspended state to not + reinitialize some buffer *) + RestartLoop:=false; + repeat + status := jpeg_consume_input(@FInfo); + until (status=JPEG_SUSPENDED) or (status=JPEG_REACHED_EOI); + ReturnValue:=true; + if FInfo.output_scanline = 0 then begin + Scan := FInfo.input_scan_number; + (* if we haven't displayed anything yet (output_scan_number==0) + and we have enough data for a complete scan, force output + of the last full scan *) + if (FInfo.output_scan_number = 0) and (Scan > 1) and + (status <> JPEG_REACHED_EOI) then Dec(Scan); + + if not jpeg_start_output(@FInfo, Scan) then begin + RestartLoop:=true; (* I/O suspension *) + end; + end; + + if not RestartLoop then begin + if (FInfo.output_scanline = $ffffff) then + FInfo.output_scanline := 0; + + OutputScanLines(); + + if ReturnValue=false then begin + if (FInfo.output_scanline = 0) then begin + (* didn't manage to read any lines - flag so we don't call + jpeg_start_output() multiple times for the same scan *) + FInfo.output_scanline := $ffffff; + end; + RestartLoop:=true; (* I/O suspension *) + end; + + if not RestartLoop then begin + if (FInfo.output_scanline = FInfo.output_height) then begin + if not jpeg_finish_output(@FInfo) then begin + RestartLoop:=true; (* I/O suspension *) + end; + + if not RestartLoop then begin + if (jpeg_input_complete(@FInfo) and + (FInfo.input_scan_number = FInfo.output_scan_number)) then + break; + + FInfo.output_scanline := 0; + end; + end; + end; + end; + if RestartLoop then begin + (* Suspension mode, but as not supported by this implementation + it will simple break the loop to avoid endless looping. *) + break; + end; + end; + end; + end; + finally + FreeMem(SampRow); + FreeMem(SampArray); + end; + + jpeg_finish_decompress(@FInfo); + + Progress(psEnding, 100, false, Rect(0,0,0,0), '', Continue); + end; + +begin + FWidth:=0; + FHeight:=0; + MemStream:=nil; + FillChar(FInfo,SizeOf(FInfo),0); + try + if Str is TMemoryStream then + MemStream:=TMemoryStream(Str) + else begin + MemStream:=TMemoryStream.Create; + ReadCompleteStreamToStream(Str,MemStream,1024); + MemStream.Position:=0; + end; + if MemStream.Size > 0 then begin + FError:=jpeg_std_error; + FInfo.err := @FError; + jpeg_CreateDecompress(@FInfo, JPEG_LIB_VERSION, SizeOf(FInfo)); + try + FProgressMgr.pub.progress_monitor := @ProgressCallback; + FProgressMgr.instance := Self; + FInfo.progress := @FProgressMgr.pub; + SetSource; + ReadHeader; + ReadPixels; + finally + jpeg_Destroy_Decompress(@FInfo); + end; + end; + finally + if (MemStream<>nil) and (MemStream<>Str) then + MemStream.Free; + end; +end; + +function TFPReaderJPEG.InternalCheck(Str: TStream): boolean; +begin + // ToDo: read header and check + Result:=false; + if Str=nil then exit; + Result:=true; +end; + +constructor TFPReaderJPEG.Create; +begin + FScale:=jsFullSize; + FPerformance:=jpBestSpeed; + inherited Create; +end; + +destructor TFPReaderJPEG.Destroy; +begin + inherited Destroy; +end; + +initialization + with jpeg_std_error do begin + error_exit:=@JPEGError; + emit_message:=@EmitMessage; + output_message:=@OutputMessage; + format_message:=@FormatMessage; + reset_error_mgr:=@ResetErrorMgr; + end; + ImageHandlers.RegisterImageReader ('JPEG Graphics', 'jpg;jpeg', TFPReaderJPEG); +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/fpreadpcx.pas b/mseide-msegui/lib/common/fpccompatibility/fpreadpcx.pas new file mode 100644 index 0000000..f6c5bc1 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpreadpcx.pas @@ -0,0 +1,310 @@ +{ Copyright (C) 2007 Laurent Jacques + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License + for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Load all format compressed or not +} + +unit FPReadPCX; + +{$mode objfpc}{$H+} + +interface + +uses FPImage, Classes, SysUtils, pcxcomn; + +type + + { TFPReaderPCX } + + TFPReaderPCX = class(TFPCustomImageReader) + private + FCompressed: boolean; + protected + Header: TPCXHeader; + BytesPerPixel: byte; + FScanLine: PByte; + FLineSize: integer; + TotalWrite: longint; + procedure CreateGrayPalette(Img: TFPCustomImage); + procedure CreateBWPalette(Img: TFPCustomImage); + procedure CreatePalette16(Img: TFPCustomImage); + procedure ReadPalette(Stream: TStream; Img: TFPCustomImage); + procedure AnalyzeHeader(Img: TFPCustomImage); + function InternalCheck(Stream: TStream): boolean; override; + procedure InternalRead(Stream: TStream; Img: TFPCustomImage); override; + procedure ReadScanLine(Row: integer; Stream: TStream); virtual; + procedure UpdateProgress(percent: longint); + procedure WriteScanLine(Row: integer; Img: TFPCustomImage); virtual; + public + property Compressed: boolean Read FCompressed; + end; + +implementation + + +procedure TFPReaderPCX.CreatePalette16(Img: TFPCustomImage); +var + I: integer; + c: TFPColor; +begin + Img.UsePalette := True; + Img.Palette.Clear; + for I := 0 to 15 do + begin + with c, header do + begin + Red := ColorMap[I].red shl 8; + Green := ColorMap[I].Green shl 8; + Blue := ColorMap[I].Blue shl 8; + Alpha := alphaOpaque; + end; + Img.Palette.Add(c); + end; +end; + +procedure TFPReaderPCX.CreateGrayPalette(Img: TFPCustomImage); +var + I: integer; + c: TFPColor; +begin + Img.UsePalette := True; + Img.Palette.Clear; + for I := 0 to 255 do + begin + with c do + begin + Red := I * 255; + Green := I * 255; + Blue := I * 255; + Alpha := alphaOpaque; + end; + Img.Palette.Add(c); + end; +end; + +procedure TFPReaderPCX.CreateBWPalette(Img: TFPCustomImage); +begin + Img.UsePalette := True; + Img.Palette.Clear; + Img.Palette.Add(colBlack); + Img.Palette.Add(colWhite); +end; + +procedure TFPReaderPCX.ReadPalette(Stream: TStream; Img: TFPCustomImage); +var + RGBEntry: TRGB; + I: integer; + c: TFPColor; + OldPos: integer; +begin + Img.UsePalette := True; + Img.Palette.Clear; + OldPos := Stream.Position; + Stream.Position := Stream.Size - 768; + for I := 0 to 255 do + begin + Stream.Read(RGBEntry, SizeOf(RGBEntry)); + with c do + begin + Red := RGBEntry.Red shl 8; + Green := RGBEntry.Green shl 8; + Blue := RGBEntry.Blue shl 8; + Alpha := alphaOpaque; + end; + Img.Palette.Add(C); + end; + Stream.Position := OldPos; +end; + +procedure TFPReaderPCX.AnalyzeHeader(Img: TFPCustomImage); +begin + with Header do + begin + if not ((FileID in [$0A, $0C]) and (ColorPlanes in [1, 3, 4]) and + (Version in [0, 2, 3, 5]) and (PaletteType in [1, 2])) then + raise Exception.Create('Unknown/Unsupported PCX image type'); + BytesPerPixel := BitsPerPixel * ColorPlanes; + FCompressed := Encoding = 1; + Img.Width := XMax - XMin + 1; + Img.Height := YMax - YMin + 1; + FLineSize := (BytesPerLine * ColorPlanes); + GetMem(FScanLine, FLineSize); + end; +end; + +procedure TFPReaderPCX.ReadScanLine(Row: integer; Stream: TStream); +var + P: PByte; + B: byte; + bytes, Count: integer; +begin + P := FScanLine; + bytes := FLineSize; + Count := 0; + if Compressed then + begin + while bytes > 0 do + begin + if (Count = 0) then + begin + Stream.ReadBuffer(B, 1); + if (B < $c0) then + Count := 1 + else + begin + Count := B - $c0; + Stream.ReadBuffer(B, 1); + end; + end; + Dec(Count); + P[0] := B; + Inc(P); + Dec(bytes); + end; + end + else + Stream.ReadBuffer(FScanLine^, FLineSize); +end; + +procedure TFPReaderPCX.UpdateProgress(percent: longint); +var + continue: boolean; + Rect: TRect; +begin + Rect.Left := 0; + Rect.Top := 0; + Rect.Right := 0; + Rect.Bottom := 0; + continue := True; + Progress(psRunning, 0, False, Rect, '', continue); +end; + +procedure TFPReaderPCX.InternalRead(Stream: TStream; Img: TFPCustomImage); +var + H, Row: integer; + continue: boolean; + Rect: TRect; +begin + TotalWrite := 0; + Rect.Left := 0; + Rect.Top := 0; + Rect.Right := 0; + Rect.Bottom := 0; + continue := True; + Progress(psStarting, 0, False, Rect, '', continue); + Stream.Read(Header, SizeOf(Header)); + AnalyzeHeader(Img); + case BytesPerPixel of + 1: CreateBWPalette(Img); + 4: CreatePalette16(Img); + 8: ReadPalette(stream, Img); + else + if (Header.PaletteType = 2) then + CreateGrayPalette(Img); + end; + H := Img.Height; + TotalWrite := Img.Height * Img.Width; + for Row := 0 to H - 1 do + begin + ReadScanLine(Row, Stream); + WriteScanLine(Row, Img); + end; + Progress(psEnding, 100, False, Rect, '', continue); + freemem(FScanLine); +end; + +procedure TFPReaderPCX.WriteScanLine(Row: integer; Img: TFPCustomImage); +var + Col: integer; + C: TFPColor; + P, P1, P2, P3: PByte; + Z2: word; + color: byte; +begin + C.Alpha := AlphaOpaque; + P := FScanLine; + Z2 := Header.BytesPerLine; + begin + case BytesPerPixel of + 1: + begin + for Col := 0 to Img.Width - 1 do + begin + if (P[col div 8] and (128 shr (col mod 8))) <> 0 then + Img.Colors[Col, Row] := Img.Palette[1] + else + Img.Colors[Col, Row] := Img.Palette[0]; + UpdateProgress(trunc(100.0 * (Row * Col / TotalWrite))); + end; + end; + 4: + begin + P1 := P; + Inc(P1, Z2); + P2 := P; + Inc(P2, Z2 * 2); + P3 := P; + Inc(P3, Z2 * 3); + for Col := 0 to Img.Width - 1 do + begin + color := 0; + if (P[col div 8] and (128 shr (col mod 8))) <> 0 then + Inc(color, 1); + if (P1[col div 8] and (128 shr (col mod 8))) <> 0 then + Inc(color, 1 shl 1); + if (P2[col div 8] and (128 shr (col mod 8))) <> 0 then + Inc(color, 1 shl 2); + if (P3[col div 8] and (128 shr (col mod 8))) <> 0 then + Inc(color, 1 shl 3); + Img.Colors[Col, Row] := Img.Palette[color]; + UpdateProgress(trunc(100.0 * (Row * Col / TotalWrite))); + end; + end; + 8: + begin + for Col := 0 to Img.Width - 1 do + begin + Img.Colors[Col, Row] := Img.Palette[P[Col]]; + UpdateProgress(trunc(100.0 * (Row * Col / TotalWrite))); + end; + end; + 24: + begin + for Col := 0 to Img.Width - 1 do + begin + with C do + begin + Red := P[col] or (P[col] shl 8); + Blue := P[col + Z2 * 2] or (P[col + Z2 * 2] shl 8); + Green := P[col + Z2] or (P[col + Z2] shl 8); + Alpha := alphaOpaque; + end; + Img[col, row] := C; + UpdateProgress(trunc(100.0 * (Row * Col / TotalWrite))); + end; + end; + end; + end; +end; + +function TFPReaderPCX.InternalCheck(Stream: TStream): boolean; +begin + Result := True; +end; + +initialization + ImageHandlers.RegisterImageReader('PCX Format', 'pcx', TFPReaderPCX); +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/fpreadpng.pas b/mseide-msegui/lib/common/fpccompatibility/fpreadpng.pas new file mode 100644 index 0000000..b676a55 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpreadpng.pas @@ -0,0 +1,870 @@ +{ + $Id: fpreadpng.pp,v 1.10 2003/10/19 21:09:51 luk Exp $ + This file is part of the Free Pascal run time library. + Copyright (c) 2003 by the Free Pascal development team + + PNG reader implementation + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + **********************************************************************} +//modified 2013 by Martin Schreiber + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +unit fpreadpng; + +interface + +uses + sysutils,classes,mclasses, fpimage,zstream, + {$ifdef FPC} + fpimgcmn, pngcomn + {$else} + fpimgcmn_del, pngcomn_del + {$endif}; + +Type + + TSetPixelProc = procedure (x,y:integer; CD : TColordata) of object; + TConvertColorProc = function (CD:TColorData) : TFPColor of object; + + TFPReaderPNG = class (TFPCustomImageReader) + private + + FHeader : THeaderChunk; + ZData : TMemoryStream; // holds compressed data until all blocks are read + Decompress : TDeCompressionStream; // decompresses the data + FPltte : boolean; // if palette is used + FCountScanlines : EightLong; //Number of scanlines to process for each pass + FScanLineLength : EightLong; //Length of scanline for each pass + FCurrentPass : byte; + ByteWidth : byte; // number of bytes to read for pixel information + BitsUsed : EightLong; // bitmasks to use to split a byte into smaller parts + BitShift : byte; // shift right to do of the bits extracted with BitsUsed for 1 element + CountBitsUsed : byte; // number of bit groups (1 pixel) per byte (when bytewidth = 1) + //CFmt : TColorFormat; // format of the colors to convert from + StartX,StartY, DeltaX,DeltaY, StartPass,EndPass : integer; // number and format of passes + FSwitchLine, FCurrentLine, FPreviousLine : pByteArray; + FPalette : TFPPalette; + FSetPixel : TSetPixelProc; + FConvertColor : TConvertColorProc; + procedure ReadChunk; + procedure HandleData; + procedure HandleUnknown; + function ColorGray1 (CD:TColorData) : TFPColor; + function ColorGray2 (CD:TColorData) : TFPColor; + function ColorGray4 (CD:TColorData) : TFPColor; + function ColorGray8 (CD:TColorData) : TFPColor; + function ColorGray16 (CD:TColorData) : TFPColor; + function ColorGrayAlpha8 (CD:TColorData) : TFPColor; + function ColorGrayAlpha16 (CD:TColorData) : TFPColor; + function ColorColor8 (CD:TColorData) : TFPColor; + function ColorColor16 (CD:TColorData) : TFPColor; + function ColorColorAlpha8 (CD:TColorData) : TFPColor; + function ColorColorAlpha16 (CD:TColorData) : TFPColor; + protected + Chunk : TChunk; + UseTransparent, EndOfFile : boolean; + TransparentDataValue : TColorData; + UsingBitGroup : byte; + DataIndex : longword; + DataBytes : TColorData; + function CurrentLine(x:longword) : byte; + function PrevSample (x:longword): byte; + function PreviousLine (x:longword) : byte; + function PrevLinePrevSample (x:longword): byte; + procedure HandleChunk; virtual; + procedure HandlePalette; virtual; + procedure HandleAlpha; virtual; + function CalcX (relX:integer) : integer; + function CalcY (relY:integer) : integer; + function CalcColor: TColorData; + procedure HandleScanLine (const y : integer; const ScanLine : PByteArray); virtual; + procedure DoDecompress; virtual; + function DoFilter(LineFilter:byte;index:longword; b:byte) : byte; virtual; + procedure SetPalettePixel (x,y:integer; CD : TColordata); + procedure SetPalColPixel (x,y:integer; CD : TColordata); + procedure SetColorPixel (x,y:integer; CD : TColordata); + procedure SetColorTrPixel (x,y:integer; CD : TColordata); + function DecideSetPixel : TSetPixelProc; virtual; + procedure InternalRead (Str:TStream; Img:TFPCustomImage); override; + function InternalCheck (Str:TStream) : boolean; override; + //property ColorFormat : TColorformat read CFmt; + property ConvertColor : TConvertColorProc read FConvertColor; + property CurrentPass : byte read FCurrentPass; + property Pltte : boolean read FPltte; + property ThePalette : TFPPalette read FPalette; + property Header : THeaderChunk read FHeader; + property CountScanlines : EightLong read FCountScanlines; + property ScanLineLength : EightLong read FScanLineLength; + public + constructor create; override; + destructor destroy; override; + end; + +implementation + + + +const StartPoints : array[0..7, 0..1] of word = + ((0,0),(0,0),(4,0),(0,4),(2,0),(0,2),(1,0),(0,1)); + Delta : array[0..7,0..1] of word = + ((1,1),(8,8),(8,8),(4,8),(4,4),(2,4),(2,2),(1,2)); + BitsUsed1Depth : EightLong = ($80,$40,$20,$10,$08,$04,$02,$01); + BitsUsed2Depth : EightLong = ($C0,$30,$0C,$03,0,0,0,0); + BitsUsed4Depth : EightLong = ($F0,$0F,0,0,0,0,0,0); + +constructor TFPReaderPNG.create; +begin + inherited; + chunk.acapacity := 0; + chunk.data := nil; + UseTransparent := False; +end; + +destructor TFPReaderPNG.destroy; +begin + with chunk do + if acapacity > 0 then + freemem (data); + inherited; +end; + +procedure TFPReaderPNG.ReadChunk; + +var ChunkHeader : TChunkHeader; + readCRC : longword; + l : longword; +begin + TheStream.Read (ChunkHeader,sizeof(ChunkHeader)); + with chunk do + begin + // chunk header + with ChunkHeader do + begin + {$IFDEF ENDIAN_LITTLE} + alength := swap(CLength); + {$ELSE} + alength := CLength; + {$ENDIF} + ReadType := CType; + end; + aType := low(TChunkTypes); + while (aType < high(TChunkTypes)) and (ChunkTypes[aType] <> ReadType) do + inc (aType); + if alength > MaxChunkLength then + raise PNGImageException.Create ('Invalid chunklength'); + if alength > acapacity then + begin + if acapacity > 0 then + freemem (data); + GetMem (data, alength); + acapacity := alength; + end; + l := TheStream.read (data^, alength); + if l <> alength then + raise PNGImageException.Create ('Chunk length exceeds stream length'); + TheStream.Read (readCRC, sizeof(ReadCRC)); + l := CalculateCRC (All1Bits, ReadType, sizeOf(ReadType)); + l := CalculateCRC (l, data^, alength); + {$IFDEF ENDIAN_LITTLE} + l := swap(l xor All1Bits); + {$ELSE} + l := l xor All1Bits; + {$ENDIF} + if ReadCRC <> l then + raise PNGImageException.Create ('CRC check failed'); + end; +end; + +procedure TFPReaderPNG.HandleData; +var OldSize : longword; +begin + OldSize := ZData.size; + ZData.Size := OldSize + Chunk.aLength; + ZData.Write (chunk.Data^, chunk.aLength); +end; + +procedure TFPReaderPNG.HandleAlpha; + procedure PaletteAlpha; + var r : integer; + a : word; + c : TFPColor; + begin + with chunk do + begin + if alength > longword(ThePalette.count) then + raise PNGImageException.create ('To much alpha values for palette'); + for r := 0 to alength-1 do + begin + c := ThePalette[r]; + a := data^[r]; + c.alpha := (a shl 8) + a; + ThePalette[r] := c; + end; + end; + end; + procedure TransparentGray; + var a : word; + begin + move (chunk.data^[0], a, 2); + {$IFDEF ENDIAN_LITTLE} + a := swap (a); + {$ENDIF} + TransparentDataValue := a; + UseTransparent := True; + end; + procedure TransparentColor; + var d : byte; + r,g,b : word; + a : TColorData; + begin + with chunk do + begin + move (data^[0], r, 2); + move (data^[2], g, 2); + move (data^[4], b, 2); + end; + {$IFDEF ENDIAN_LITTLE} + r := swap (r); + g := swap (g); + b := swap (b); + {$ENDIF} + d := header.bitdepth; + a := (TColorData(b) shl d) shl d; + a := a + (TColorData(g) shl d) + r; + TransparentDataValue := a; + UseTransparent := True; + end; +begin + case header.ColorType of + 3 : PaletteAlpha; + 0 : TransparentGray; + 2 : TransparentColor; + end; +end; + +procedure TFPReaderPNG.HandlePalette; +var r : longword; + c : TFPColor; + t : word; +begin + if header.colortype = 3 then + with chunk do + begin + if TheImage.UsePalette then + FPalette := TheImage.Palette + else + FPalette := TFPPalette.Create(0); + c.Alpha := AlphaOpaque; + if (aLength mod 3) > 0 then + raise PNGImageException.Create ('Impossible length for PLTE-chunk'); + r := 0; + ThePalette.count := 0; + while r < alength do + begin + t := data^[r]; + c.red := t + (t shl 8); + inc (r); + t := data^[r]; + c.green := t + (t shl 8); + inc (r); + t := data^[r]; + c.blue := t + (t shl 8); + inc (r); + ThePalette.Add (c); + end; + end; +end; + +procedure TFPReaderPNG.SetPalettePixel (x,y:integer; CD : TColordata); +begin // both PNG and palette have palette + TheImage.Pixels[x,y] := CD; +end; + +procedure TFPReaderPNG.SetPalColPixel (x,y:integer; CD : TColordata); +begin // PNG with palette, Img without + TheImage.Colors[x,y] := ThePalette[CD]; +end; + +procedure TFPReaderPNG.SetColorPixel (x,y:integer; CD : TColordata); +var c : TFPColor; +begin // both PNG and Img work without palette, and no transparency colordata + // c := ConvertColor (CD,CFmt); + c := ConvertColor (CD); + TheImage.Colors[x,y] := c; +end; + +procedure TFPReaderPNG.SetColorTrPixel (x,y:integer; CD : TColordata); +var c : TFPColor; +begin // both PNG and Img work without palette, and there is a transparency colordata + //c := ConvertColor (CD,CFmt); + c := ConvertColor (CD); + if TransparentDataValue = CD then + c.alpha := alphaTransparent; + TheImage.Colors[x,y] := c; +end; + +function TFPReaderPNG.CurrentLine(x:longword):byte; +begin + result := FCurrentLine^[x]; +end; + +function TFPReaderPNG.PrevSample (x:longword): byte; +begin + if x < byteWidth then + result := 0 + else + result := FCurrentLine^[x - bytewidth]; +end; + +function TFPReaderPNG.PreviousLine (x:longword) : byte; +begin + result := FPreviousline^[x]; +end; + +function TFPReaderPNG.PrevLinePrevSample (x:longword): byte; +begin + if x < byteWidth then + result := 0 + else + result := FPreviousLine^[x - bytewidth]; +end; + +function TFPReaderPNG.DoFilter(LineFilter:byte;index:longword; b:byte) : byte; +var diff : byte; + procedure FilterSub; + begin + diff := PrevSample(index); + end; + procedure FilterUp; + begin + diff := PreviousLine(index); + end; + procedure FilterAverage; + var l, p : word; + begin + l := PrevSample(index); + p := PreviousLine(index); + diff := (l + p) div 2; + end; + procedure FilterPaeth; + var dl, dp, dlp : word; // index for previous and distances for: + l, p, lp : byte; // r:predictor, Left, Previous, LeftPrevious + r : integer; + begin + l := PrevSample(index); + lp := PrevLinePrevSample(index); + p := PreviousLine(index); + r := l + p - lp; + dl := abs (r - l); + dlp := abs (r - lp); + dp := abs (r - p); + if (dl <= dp) and (dl <= dlp) then + diff := l + else if dp <= dlp then + diff := p + else + diff := lp; + end; +begin + diff:= 0; + case LineFilter of + 0 : diff := 0; + 1 : FilterSub; + 2 : FilterUp; + 3 : FilterAverage; + 4 : FilterPaeth; + end; + result := (b + diff) mod $100; +end; + +function TFPReaderPNG.DecideSetPixel : TSetPixelProc; +begin + if Pltte then + if TheImage.UsePalette then + result := {$ifdef FPC}@{$endif}SetPalettePixel + else + result := {$ifdef FPC}@{$endif}SetPalColPixel + else + if UseTransparent then + result := {$ifdef FPC}@{$endif}SetColorTrPixel + else + result := {$ifdef FPC}@{$endif}SetColorPixel; +end; + +function TFPReaderPNG.CalcX (relX:integer) : integer; +begin + result := StartX + (relX * deltaX); +end; + +function TFPReaderPNG.CalcY (relY:integer) : integer; +begin + result := StartY + (relY * deltaY); +end; + +function TFPReaderPNG.CalcColor: TColorData; +var cd : longword; + r : word; +// b : byte; + tmp : pbytearray; +begin + if UsingBitGroup = 0 then + begin + Databytes := 0; + if Header.BitDepth = 16 then + begin + getmem(tmp, bytewidth); + fillchar(tmp^, bytewidth, 0); + for r:=0 to bytewidth-2 do + tmp^[r+1]:=FCurrentLine^[Dataindex+r]; + move (tmp^[0], Databytes, bytewidth); + freemem(tmp); + end + else move (FCurrentLine^[DataIndex], Databytes, bytewidth); + {$IFDEF ENDIAN_BIG} + Databytes:=swap(Databytes); + {$ENDIF} + inc (DataIndex,bytewidth); + end; + if bytewidth = 1 then + begin + cd := (Databytes and BitsUsed[UsingBitGroup]); + result := cd shr ((CountBitsUsed-UsingBitGroup-1) * BitShift); + inc (UsingBitgroup); + if UsingBitGroup >= CountBitsUsed then + UsingBitGroup := 0; + end + else + result := Databytes; +end; + +procedure TFPReaderPNG.HandleScanLine (const y : integer; const ScanLine : PByteArray); +var x, rx : integer; + c : TColorData; +begin + UsingBitGroup := 0; + DataIndex := 0; + for rx := 0 to ScanlineLength[CurrentPass]-1 do + begin + X := CalcX(rx); + c := CalcColor; + FSetPixel (x,y,c); + end +end; + +function TFPReaderPNG.ColorGray1 (CD:TColorDAta) : TFPColor; +begin + if CD = 0 then + result := colBlack + else + result := colWhite; +end; + +function TFPReaderPNG.ColorGray2 (CD:TColorDAta) : TFPColor; +var c : word; +begin + c := CD and 3; + c := c + (c shl 2); + c := c + (c shl 4); + c := c + (c shl 8); + with result do + begin + red := c; + green := c; + blue := c; + alpha := alphaOpaque; + end; +end; + +function TFPReaderPNG.ColorGray4 (CD:TColorDAta) : TFPColor; +var c : word; +begin + c := CD and $F; + c := c + (c shl 4); + c := c + (c shl 8); + with result do + begin + red := c; + green := c; + blue := c; + alpha := alphaOpaque; + end; +end; + +function TFPReaderPNG.ColorGray8 (CD:TColorDAta) : TFPColor; +var c : word; +begin + c := CD and $FF; + c := c + (c shl 8); + with result do + begin + red := c; + green := c; + blue := c; + alpha := alphaOpaque; + end; +end; + +function TFPReaderPNG.ColorGray16 (CD:TColorDAta) : TFPColor; +var c : word; +begin + c := CD and $FFFF; + with result do + begin + red := c; + green := c; + blue := c; + alpha := alphaOpaque; + end; +end; + +function TFPReaderPNG.ColorGrayAlpha8 (CD:TColorData) : TFPColor; +var c : word; +begin + c := CD and $00FF; + c := c + (c shl 8); + with result do + begin + red := c; + green := c; + blue := c; + c := CD and $FF00; + alpha := c + (c shr 8); + end; +end; + +function TFPReaderPNG.ColorGrayAlpha16 (CD:TColorData) : TFPColor; +var c : word; +begin + c := (CD shr 16) and $FFFF; + with result do + begin + red := c; + green := c; + blue := c; + alpha := CD and $FFFF; + end; +end; + +function TFPReaderPNG.ColorColor8 (CD:TColorData) : TFPColor; +var c : word; +begin + with result do + begin + c := CD and $FF; + red := c + (c shl 8); + CD:=CD shr 8; + c := CD and $FF; + green := c + (c shl 8); + CD:=CD shr 8; + c := CD and $FF; + blue := c + (c shl 8); + alpha := alphaOpaque; + end; +end; + +function TFPReaderPNG.ColorColor16 (CD:TColorData) : TFPColor; +begin + with result do + begin + red := CD and $FFFF; + CD:=CD shr 16; + green := CD and $FFFF; + CD:=CD shr 16; + blue := CD and $FFFF; + alpha := alphaOpaque; + end; +end; + +function TFPReaderPNG.ColorColorAlpha8 (CD:TColorData) : TFPColor; +var c : word; +begin + with result do + begin + c := CD and $FF; + red := c + (c shl 8); + CD:=CD shr 8; + c := CD and $FF; + green := c + (c shl 8); + CD:=CD shr 8; + c := CD and $FF; + blue := c + (c shl 8); + CD:=CD shr 8; + c := CD and $FF; + alpha := c + (c shl 8); + end; +end; + +function TFPReaderPNG.ColorColorAlpha16 (CD:TColorData) : TFPColor; +begin + with result do + begin + red := CD and $FFFF; + CD:=CD shr 16; + green := CD and $FFFF; + CD:=CD shr 16; + blue := CD and $FFFF; + CD:=CD shr 16; + alpha := CD and $FFFF; + end; +end; + +procedure TFPReaderPNG.DoDecompress; + + procedure initVars; + var r,d : integer; + begin + with Header do + begin + if interlace=0 then + begin + StartPass := 0; + EndPass := 0; + FCountScanlines[0] := Height; + FScanLineLength[0] := Width; + end + else + begin + StartPass := 1; + EndPass := 7; + for r := 1 to 7 do + begin + d := Height div delta[r,1]; + if (height mod delta[r,1]) > startpoints[r,1] then + inc (d); + FCountScanlines[r] := d; + d := width div delta[r,0]; + if (width mod delta[r,0]) > startpoints[r,0] then + inc (d); + FScanLineLength[r] := d; + end; + end; + Fpltte := (ColorType = 3); + case colortype of + 0 : case Bitdepth of + 1 : begin + FConvertColor := {$ifdef FPC}@{$endif}ColorGray1; //CFmt := cfMono; + ByteWidth := 1; + end; + 2 : begin + FConvertColor := {$ifdef FPC}@{$endif}ColorGray2; //CFmt := cfGray2; + ByteWidth := 1; + end; + 4 : begin + FConvertColor := {$ifdef FPC}@{$endif}ColorGray4; //CFmt := cfGray4; + ByteWidth := 1; + end; + 8 : begin + FConvertColor := {$ifdef FPC}@{$endif}ColorGray8; //CFmt := cfGray8; + ByteWidth := 1; + end; + 16 : begin + FConvertColor := {$ifdef FPC}@{$endif}ColorGray16; //CFmt := cfGray16; + ByteWidth := 2; + end; + end; + 2 : if BitDepth = 8 then + begin + FConvertColor := {$ifdef FPC}@{$endif}ColorColor8; //CFmt := cfBGR24 + ByteWidth := 3; + end + else + begin + FConvertColor := {$ifdef FPC}@{$endif}ColorColor16; //CFmt := cfBGR48; + ByteWidth := 6; + end; + 3 : if BitDepth = 16 then + ByteWidth := 2 + else + ByteWidth := 1; + 4 : if BitDepth = 8 then + begin + FConvertColor := {$ifdef FPC}@{$endif}ColorGrayAlpha8; //CFmt := cfGrayA16 + ByteWidth := 2; + end + else + begin + FConvertColor := {$ifdef FPC}@{$endif}ColorGrayAlpha16; //CFmt := cfGrayA32; + ByteWidth := 4; + end; + 6 : if BitDepth = 8 then + begin + FConvertColor := {$ifdef FPC}@{$endif}ColorColorAlpha8; //CFmt := cfABGR32 + ByteWidth := 4; + end + else + begin + FConvertColor := {$ifdef FPC}@{$endif}ColorColorAlpha16; //CFmt := cfABGR64; + ByteWidth := 8; + end; + end; + //ByteWidth := BytesNeeded[CFmt]; + case BitDepth of + 1 : begin + CountBitsUsed := 8; + BitShift := 1; + BitsUsed := BitsUsed1Depth; + end; + 2 : begin + CountBitsUsed := 4; + BitShift := 2; + BitsUsed := BitsUsed2Depth; + end; + 4 : begin + CountBitsUsed := 2; + BitShift := 4; + BitsUsed := BitsUsed4Depth; + end; + 8 : begin + CountBitsUsed := 1; + BitShift := 0; + BitsUsed[0] := $FF; + end; + end; + end; + end; + + procedure Decode; + var y, rp, ry, rx, l : integer; + lf : byte; + begin + FSetPixel := DecideSetPixel(); + for rp := StartPass to EndPass do + begin + FCurrentPass := rp; + StartX := StartPoints[rp,0]; + StartY := StartPoints[rp,1]; + DeltaX := Delta[rp,0]; + DeltaY := Delta[rp,1]; + if bytewidth = 1 then + begin + l := (ScanLineLength[rp] div CountBitsUsed); + if (ScanLineLength[rp] mod CountBitsUsed) > 0 then + inc (l); + end + else + l := ScanLineLength[rp]*ByteWidth; + if (l>0) then + begin + GetMem (FPreviousLine, l); + GetMem (FCurrentLine, l); + fillchar (FCurrentLine^,l,0); + try + for ry := 0 to CountScanlines[rp]-1 do + begin + FSwitchLine := FCurrentLine; + FCurrentLine := FPreviousLine; + FPreviousLine := FSwitchLine; + Y := CalcY(ry); + Decompress.Read (lf, sizeof(lf)); + Decompress.Read (FCurrentLine^, l); + if lf <> 0 then // Do nothing when there is no filter used + for rx := 0 to l-1 do + FCurrentLine^[rx] := DoFilter (lf, rx, FCurrentLine^[rx]); + HandleScanLine (y, FCurrentLine); + end; + finally + freemem (FPreviousLine); + freemem (FCurrentLine); + end; + end; + end; + end; + +begin + InitVars; + DeCode; +end; + +procedure TFPReaderPNG.HandleChunk; +begin + case chunk.AType of + ctIHDR : raise PNGImageException.Create ('Second IHDR chunk found'); + ctPLTE : HandlePalette; + ctIDAT : HandleData; + ctIEND : EndOfFile := True; + cttRNS : HandleAlpha; + else HandleUnknown; + end; +end; + +procedure TFPReaderPNG.HandleUnknown; +begin + if (chunk.readtype[0] in ['A'..'Z']) then + raise PNGImageException.Create('Critical chunk '+chunk.readtype+' not recognized'); +end; + +procedure TFPReaderPNG.InternalRead (Str:TStream; Img:TFPCustomImage); +begin + {$ifdef FPC_Debug_Image} + if Str<>TheStream then + writeln('WARNING: TFPReaderPNG.InternalRead Str<>TheStream'); + {$endif} + with Header do + Img.SetSize (Width, Height); + ZData := TMemoryStream.Create; + try + EndOfFile := false; + while not EndOfFile do + begin + ReadChunk; + HandleChunk; + end; + ZData.position:=0; + Decompress := TDecompressionStream.Create (ZData); + try + DoDecompress; + finally + Decompress.Free; + end; + finally + ZData.Free; + if not img.UsePalette and assigned(FPalette) then + begin + FPalette.Free; + end; + end; +end; + +function TFPReaderPNG.InternalCheck (Str:TStream) : boolean; +var SigCheck : array[0..7] of byte; + r : integer; +begin + try + // Check Signature + Str.Read(SigCheck, SizeOf(SigCheck)); + for r := 0 to 7 do + begin + If SigCheck[r] <> Signature[r] then begin + result:= false; + exit; + end; +// raise PNGImageException.Create('This is not PNG-data'); + end; + // Check IHDR + ReadChunk; + move (chunk.data^, FHeader, sizeof(Header)); + with header do + begin + {$IFDEF ENDIAN_LITTLE} + Width := swap(width); + height := swap (height); + {$ENDIF} + result := (width > 0) and (height > 0) and (compression = 0) + and (filter = 0) and (Interlace in [0,1]); + end; + except + result := false; + end; +end; + +initialization + ImageHandlers.RegisterImageReader ('Portable Network Graphics', 'png', TFPReaderPNG); +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/fpreadpnm.pp b/mseide-msegui/lib/common/fpccompatibility/fpreadpnm.pp new file mode 100644 index 0000000..7e45f79 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpreadpnm.pp @@ -0,0 +1,350 @@ +{*****************************************************************************} +{ + This file is part of the Free Pascal's "Free Components Library". + Copyright (c) 2003 by Mazen NEIFER of the Free Pascal development team + + PNM writer implementation. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +{*****************************************************************************} + +{ +The PNM (Portable aNyMaps) is a generic name for : + PBM : Portable BitMaps, + PGM : Portable GrayMaps, + PPM : Portable PixMaps. +There is normally no file format associated with PNM itself.} + +{$mode objfpc}{$h+} +unit FPReadPNM; + +interface + +uses FPImage, classes,mclasses, sysutils; + +type + TFPReaderPNM=class (TFPCustomImageReader) + private + FBitMapType : Integer; + FWidth : Integer; + FHeight : Integer; + protected + FMaxVal : Cardinal; + FBitPP : Byte; + FScanLineSize : Integer; + FScanLine : PByte; + procedure ReadHeader(Stream : TStream); + function InternalCheck (Stream:TStream):boolean;override; + procedure InternalRead(Stream:TStream;Img:TFPCustomImage);override; + procedure ReadScanLine(Row : Integer; Stream:TStream); + procedure WriteScanLine(Row : Integer; Img : TFPCustomImage); + end; + +implementation + +function TFPReaderPNM.InternalCheck(Stream:TStream):boolean; + +begin + InternalCheck:=True; +end; + +const + WhiteSpaces=[#9,#10,#13,#32]; {Whitespace (TABs, CRs, LFs, blanks) are separators in the PNM Headers} + +function DropWhiteSpaces(Stream : TStream) :Char; + +begin + result:= #0; + with Stream do + begin + repeat + ReadBuffer(DropWhiteSpaces,1); +{If we encounter comment then eate line} + if DropWhiteSpaces='#' then + repeat + ReadBuffer(DropWhiteSpaces,1); + until DropWhiteSpaces=#10; + until not(DropWhiteSpaces in WhiteSpaces); + end; +end; + +function ReadInteger(Stream : TStream) :Integer; + +var + s:String[7]; + +begin + s:=''; + s[1]:=DropWhiteSpaces(Stream); + with Stream do + repeat + Inc(s[0]); + ReadBuffer(s[Length(s)+1],1) + until (s[0]=#7) or (s[Length(s)+1] in WhiteSpaces); + Result:=StrToInt(s); +end; + +procedure TFPReaderPNM.ReadHeader(Stream : TStream); + +Var + C : Char; + +begin + Stream.ReadBuffer(C,1); + If (C<>'P') then + Raise Exception.Create('Not a valid PNM image.'); + Stream.ReadBuffer(C,1); + FBitmapType:=Ord(C)-Ord('0'); + If Not (FBitmapType in [1..6]) then + Raise Exception.CreateFmt('Unknown PNM subtype : %s',[C]); + FWidth:=ReadInteger(Stream); + FHeight:=ReadInteger(Stream); + if FBitMapType in [1,4] + then + FMaxVal:=1 + else + FMaxVal:=ReadInteger(Stream); + If (FWidth<=0) or (FHeight<=0) or (FMaxVal<=0) then + Raise Exception.Create('Invalid PNM header data'); + case FBitMapType of + 1: FBitPP := 1; // 1bit PP (text) + 2: FBitPP := 8 * SizeOf(Word); // Grayscale (text) + 3: FBitPP := 8 * SizeOf(Word)*3; // RGB (text) + 4: FBitPP := 1; // 1bit PP (raw) + 5: If (FMaxval>255) then // Grayscale (raw); + FBitPP:= 8 * 2 + else + FBitPP:= 8; + 6: if (FMaxVal>255) then // RGB (raw) + FBitPP:= 8 * 6 + else + FBitPP:= 8 * 3 + end; +// Writeln(FWidth,'x',Fheight,' Maxval: ',FMaxVal,' BitPP: ',FBitPP); +end; + +procedure TFPReaderPNM.InternalRead(Stream:TStream;Img:TFPCustomImage); + +var + Row:Integer; + +begin + ReadHeader(Stream); + Img.SetSize(FWidth,FHeight); + FScanLineSize:=FBitPP*((FWidth+7)shr 3); + GetMem(FScanLine,FScanLineSize); + try + for Row:=0 to img.Height-1 do + begin + ReadScanLine(Row,Stream); + WriteScanLine(Row,Img); + end; + finally + FreeMem(FScanLine); + end; +end; + +procedure TFPReaderPNM.ReadScanLine(Row : Integer; Stream:TStream); + +Var + P : PWord; + I,j,bitsLeft : Integer; + PB: PByte; + +begin + Case FBitmapType of + 1 : begin + PB:=FScanLine; + For I:=0 to ((FWidth+7)shr 3)-1 do + begin + PB^:=0; + bitsLeft := FWidth-(I shl 3)-1; + if bitsLeft > 7 then bitsLeft := 7; + for j:=0 to bitsLeft do + PB^:=PB^ or (ReadInteger(Stream) shl (7-j)); + Inc(PB); + end; + end; + 2 : begin + P:=PWord(FScanLine); + For I:=0 to FWidth-1 do + begin + P^:=ReadInteger(Stream); + Inc(P); + end; + end; + 3 : begin + P:=PWord(FScanLine); + For I:=0 to FWidth-1 do + begin + P^:=ReadInteger(Stream); // Red + Inc(P); + P^:=ReadInteger(Stream); // Green + Inc(P); + P^:=ReadInteger(Stream); // Blue; + Inc(P) + end; + end; + 4,5,6 : Stream.ReadBuffer(FScanLine^,FScanLineSize); + end; +end; + + +procedure TFPReaderPNM.WriteScanLine(Row : Integer; Img : TFPCustomImage); + +Var + C : TFPColor; + L : Cardinal; + Scale: Cardinal; + + function ScaleByte(B: Byte):Word; + begin + if FMaxVal = 255 then + Result := (B shl 8) or B { As used for reading .BMP files } + else { Mimic the above with multiplications } + Result := (B*(FMaxVal+1) + B) * 65535 div Scale; + end; + + function ScaleWord(W: Word):Word; + begin + if FMaxVal = 65535 then + Result := W + else { Mimic the above with multiplications } + Result := Int64(W*(FMaxVal+1) + W) * 65535 div Scale; + end; + + Procedure ByteBnWScanLine; + + Var + P : PByte; + I,j,x,bitsLeft : Integer; + + begin + P:=PByte(FScanLine); + For I:=0 to ((FWidth+7)shr 3)-1 do + begin + L:=P^; + x := I shl 3; + bitsLeft := FWidth-x-1; + if bitsLeft > 7 then bitsLeft := 7; + for j:=0 to bitsLeft do + begin + if L and $80 <> 0 then + Img.Colors[x,Row]:=colBlack + else + Img.Colors[x,Row]:=colWhite; + L:=L shl 1; + inc(x); + end; + Inc(P); + end; + end; + + Procedure WordGrayScanLine; + + Var + P : PWord; + I : Integer; + + begin + P:=PWord(FScanLine); + For I:=0 to FWidth-1 do + begin + L:=ScaleWord(P^); + C.Red:=L; + C.Green:=L; + C.Blue:=L; + Img.Colors[I,Row]:=C; + Inc(P); + end; + end; + + Procedure WordRGBScanLine; + + Var + P : PWord; + I : Integer; + + begin + P:=PWord(FScanLine); + For I:=0 to FWidth-1 do + begin + C.Red:=ScaleWord(P^); + Inc(P); + C.Green:=ScaleWord(P^); + Inc(P); + C.Blue:=ScaleWord(P^); + Img.Colors[I,Row]:=C; + Inc(P); + end; + end; + + Procedure ByteGrayScanLine; + + Var + P : PByte; + I : Integer; + + begin + P:=PByte(FScanLine); + For I:=0 to FWidth-1 do + begin + L:=ScaleByte(P^); + C.Red:=L; + C.Green:=L; + C.Blue:=L; + Img.Colors[I,Row]:=C; + Inc(P); + end; + end; + + Procedure ByteRGBScanLine; + + Var + P : PByte; + I : Integer; + + begin + P:=PByte(FScanLine); + For I:=0 to FWidth-1 do + begin + C.Red:=ScaleByte(P^); + Inc(P); + C.Green:=ScaleByte(P^); + Inc(P); + C.Blue:=ScaleByte(P^); + Img.Colors[I,Row]:=C; + Inc(P); + end; + end; + +begin + C.Alpha:=AlphaOpaque; + Scale := FMaxVal*(FMaxVal+1) + FMaxVal; + Case FBitmapType of + 1 : ByteBnWScanLine; + 2 : WordGrayScanline; + 3 : WordRGBScanline; + 4 : ByteBnWScanLine; + 5 : If FBitPP=8 then + ByteGrayScanLine + else + WordGrayScanLine; + 6 : If FBitPP=24 then + ByteRGBScanLine + else + WordRGBScanLine; + end; +end; + +initialization + + ImageHandlers.RegisterImageReader ('Netpbm format', 'PNM;PGM;PBM;PPM', TFPReaderPNM); + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/fpreadpsd.pas b/mseide-msegui/lib/common/fpccompatibility/fpreadpsd.pas new file mode 100644 index 0000000..42a6e82 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpreadpsd.pas @@ -0,0 +1,612 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 2008 by the Free Pascal development team + + Tiff reader for fpImage. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + ********************************************************************** + + ToDo: read further images +} +unit FPReadPSD; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, FPimage; + +type + TRGB = packed record + Red, Green, Blue : Byte; + end; + + TLab = record + L, a, b: byte; + end; + + + TPSDHeader = packed record + Signature : array[0..3] of Char; // File IDs '8BPS' + Version : word; // Version number, always 1 + Reserved : array[0..5] of Byte; // Reserved, must be zeroed + Channels : Word; // Number of color channels (1-24) including alpha channels + Rows : Cardinal; // Height of image in pixels (1-30000) + Columns : Cardinal; // Width of image in pixels (1-30000) + Depth : Word; // Number of bits per channel (1, 8, and 16) + Mode: Word; // Color mode + end; + { + Mode Description + 0 Bitmap (monochrome) + 1 Gray-scale + 2 Indexed color (palette color) + 3 RGB color + 4 CMYK color + 7 Multichannel color + 8 Duotone (halftone) + 9 Lab color + } + + TColorModeDataBlock = packed record + Types : array[0..3] of Char; // Always "8BIM" + ID:word; // (See table below) + Name:byte; // Even-length Pascal-format string, 2 bytes or longer + Size : Cardinal; // Length of resource data following, in bytes + Data:byte; // Resource data, padded to even length + end; + { + ID Data Format Description + 03e8 WORD[5] Channels, rows, columns, depth, and mode + 03e9 Optional Macintosh print manager information + 03eb Indexed color table + 03ed (See below) Resolution information + "TResolutionInfo" + 03ee BYTE[] Alpha channel names (Pascal-format strings) + 03ef (See below) Display information for each channel + "TDisplayInfo" + 03f0 BYTE[] Optional Pascal-format caption string + 03f1 LONG, WORD Fixed-point border width, border units (see below) + 03f2 Background color + 03f3 BYTE[8] Print flags (see below) + 03f4 Gray-scale and halftoning information + 03f5 Color halftoning information + 03f6 Duotone halftoning information + 03f7 Gray-scale and multichannel transfer function + 03f8 Color transfer functions + 03f9 Duotone transfer functions + 03fa Duotone image information + 03fb BYTE[2] Effective black and white value for dot range + 03fc + 03fd EPS options + 03fe WORD, BYTE Quick Mask channel ID, flag for mask initially empty + 03ff + 0400 WORD Index of target layer (0=bottom) + 0401 Working path + 0402 WORD[] Layers group info, group ID for dragging groups + 0403 + 0404 IPTC-NAA record + 0405 Image mode for raw-format files + 0406 JPEG quality (Adobe internal) + 07d0 + 0bb6 Saved path information + 0bb7 Clipping pathname + 2710 (See below) Print flags information + } + TResolutionInfo = record + hRes:Cardinal; // Fixed-point number: pixels per inch + hResUnit:word; // 1=pixels per inch, 2=pixels per centimeter + WidthUnit:word; // 1=in, 2=cm, 3=pt, 4=picas, 5=columns + vRes:Cardinal; // Fixed-point number: pixels per inch + vResUnit:word; // 1=pixels per inch, 2=pixels per centimeter + HeightUnit:word; // 1=in, 2=cm, 3=pt, 4=picas, 5=columns + end; + + TDisplayInfo = record + ColorSpace:word; + Color:array[0..3] of word; + Opacity:word; // 0-100 + Kind:byte; // 0=selected, 1=protected + Padding:byte; // Always zero + end; + + TFPReaderPSD = class; + + TPSDCreateCompatibleImgEvent = procedure(Sender: TFPReaderPSD; + var NewImage: TFPCustomImage) of object; + + { TFPReaderPSD } + + TFPReaderPSD = class(TFPCustomImageReader) + private + FCompressed: boolean; + FOnCreateImage: TPSDCreateCompatibleImgEvent; + protected + FHeader : TPSDHeader; + FColorDataBlock: TColorModeDataBlock; + FBytesPerPixel : Byte; + FScanLine : PByte; + FLineSize : PtrInt; + FPalette : TFPPalette; + FWidth : integer; + FHeight : Integer; + FBlockCount : word; + FChannelCount : word; + FLengthOfLine : array of Word; + FByteRead : PtrInt; + procedure CreateGrayPalette; + procedure CreateBWPalette; + function ReadPalette(Stream: TStream): boolean; + procedure AnalyzeHeader; + procedure InternalRead(Stream: TStream; Img: TFPCustomImage); override; + function ReadScanLine(Stream: TStream): boolean; virtual; + procedure WriteScanLine(Img: TFPCustomImage); virtual; + function InternalCheck(Stream: TStream) : boolean; override; + public + constructor Create; override; + property Compressed: Boolean read FCompressed; + property ThePalette: TFPPalette read FPalette; + property Width: integer read FWidth; + property Height: integer read FHeight; + property BytesPerPixel: Byte read FBytesPerPixel; + property BlockCount: word read FBlockCount; + property ChannelCount: word read FChannelCount; + property Header: TPSDHeader read FHeader; + property OnCreateImage: TPSDCreateCompatibleImgEvent read FOnCreateImage write FOnCreateImage; + end; + +implementation + +function CorrectCMYK(const C : TFPColor): TFPColor; +var + MinColor: word; +begin + if C.red$FFFF then MinColor:=$FFFF-C.alpha; + Result.red:=C.red-MinColor; + Result.green:=C.green-MinColor; + Result.blue:=C.blue-MinColor; + Result.alpha:=C.alpha+MinColor; +end; + +function CMYKtoRGB ( C : TFPColor): TFPColor; +begin + C:=CorrectCMYK(C); + if (C.red + C.Alpha)<$FFFF then + Result.Red:=$FFFF-(C.red+C.Alpha) else Result.Red:=0; + if (C.Green+C.Alpha)<$FFFF then + Result.Green:=$FFFF-(C.Green+C.Alpha) else Result.Green:=0; + if (C.blue+C.Alpha)<$FFFF then + Result.blue:=$FFFF-(C.blue+C.Alpha) else Result.blue:=0; + Result.alpha:=alphaOpaque; +end; + +function XYZToRGB(const X, Y, Z :double):TFPColor; +begin + // ToDo + Result:=colBlack; +end; + +function LabToRGB(const L:TLab):TFPColor; +begin + // ToDo + Result:=colBlack; +end; + +{ TFPReaderPSD } + +procedure TFPReaderPSD.CreateGrayPalette; +Var + I : Integer; + c : TFPColor; +Begin + ThePalette.count := 0; + For I:=0 To 255 Do + Begin + With c do + begin + Red:=I*255; + Green:=I*255; + Blue:=I*255; + Alpha:=alphaOpaque; + end; + ThePalette.Add (c); + End; +end; + +procedure TFPReaderPSD.CreateBWPalette; +begin + ThePalette.count := 0; + ThePalette.Add (colBlack); + ThePalette.Add (colWhite); +end; + +function TFPReaderPSD.ReadPalette(Stream: TStream): boolean; +Var + I : Integer; + c : TFPColor; + OldPos: Integer; + BufSize:Longint; + PalBuf: array[0..767] of Byte; + ContProgress: Boolean; +begin + Result:=false; + ThePalette.count := 0; + OldPos := Stream.Position; + BufSize:=0; + Stream.Read(BufSize, SizeOf(BufSize)); + BufSize:=BEtoN(BufSize); + Stream.Read(PalBuf, BufSize); + ContProgress:=true; + Progress(FPimage.psRunning, trunc(100.0 * (Stream.position / Stream.size)), + False, Rect(0,0,0,0), '', ContProgress); + if not ContProgress then exit; + For I:=0 To BufSize div 3 Do + Begin + With c do + begin + Red:=PalBuf[I] shl 8; + Green:=PalBuf[I+(BufSize div 3)] shl 8; + Blue:=PalBuf[I+(BufSize div 3)* 2] shl 8; + Alpha:=alphaOpaque; + end; + ThePalette.Add(C); + End; + Stream.Position := OldPos; + Result:=true; +end; + +procedure TFPReaderPSD.AnalyzeHeader; +begin + With FHeader do + begin + Depth:=BEtoN(Depth); + if (Signature <> '8BPS') then + Raise Exception.Create('Unknown/Unsupported PSD image type'); + Channels:=BEtoN(Channels); + if Channels > 4 then + FBytesPerPixel:=Depth*4 + else + FBytesPerPixel:=Depth*Channels; + Mode:=BEtoN(Mode); + FWidth:=BEtoN(Columns); + FHeight:=BEtoN(Rows); + FChannelCount:=Channels; + FLineSize:=PtrInt(FHeight)*FWidth*Depth div 8; + FLineSize:=FLineSize*Channels; + GetMem(FScanLine,FLineSize); + end; +end; + +procedure TFPReaderPSD.InternalRead(Stream: TStream; Img: TFPCustomImage); +var + H: Integer; + BufSize:Cardinal; + Encoding:word; + ContProgress: Boolean; +begin + FScanLine:=nil; + FPalette:=nil; + try + Stream.Position:=0; + ContProgress:=true; + Progress(FPimage.psStarting, 0, False, Rect(0,0,0,0), '', ContProgress); + if not ContProgress then exit; + // read header + Stream.Read(FHeader, SizeOf(FHeader)); + Progress(FPimage.psRunning, trunc(100.0 * (Stream.position / Stream.size)), False, Rect(0,0,0,0), '', ContProgress); + if not ContProgress then exit; + AnalyzeHeader; + Case FHeader.Mode of + 0:begin // Bitmap (monochrome) + FPalette := TFPPalette.Create(0); + CreateBWPalette; + end; + 1, 8:begin // Gray-scale + FPalette := TFPPalette.Create(0); + CreateGrayPalette; + end; + 2:begin // Indexed color (palette color) + FPalette := TFPPalette.Create(0); + if not ReadPalette(stream) then exit; + end; + end; + + if Assigned(OnCreateImage) then + OnCreateImage(Self,Img); + Img.SetSize(FWidth,FHeight); + + // color palette + BufSize:=0; + Stream.Read(BufSize, SizeOf(BufSize)); + BufSize:=BEtoN(BufSize); + Stream.Seek(BufSize, soCurrent); + // color data block + Stream.Read(BufSize, SizeOf(BufSize)); + BufSize:=BEtoN(BufSize); + Stream.Read(FColorDataBlock, SizeOf(FColorDataBlock)); + Stream.Seek(BufSize-SizeOf(FColorDataBlock), soCurrent); + // mask + Stream.Read(BufSize, SizeOf(BufSize)); + BufSize:=BEtoN(BufSize); + Stream.Seek(BufSize, soCurrent); + // compression type + Encoding:=0; + Stream.Read(Encoding, SizeOf(Encoding)); + FCompressed:=BEtoN(Encoding) = 1; + if BEtoN(Encoding)>1 then + Raise Exception.Create('Unknown compression type'); + If FCompressed then + begin + SetLength(FLengthOfLine, FHeight * FChannelCount); + Stream.ReadBuffer(FLengthOfLine[0], 2 * Length(FLengthOfLine)); + FByteRead:=0; + Progress(FPimage.psRunning, trunc(100.0 * (Stream.position / Stream.size)), False, Rect(0,0,0,0), '', ContProgress); + if not ContProgress then exit; + for H := 0 to High(FLengthOfLine) do + Inc(FByteRead, BEtoN(FLengthOfLine[H])); + if not FHeader.Mode in [ 0, 2] then + FByteRead := FByteRead * FHeader.Depth div 8; + end else + FByteRead:= FLineSize; + + ReadScanLine(Stream); + Progress(FPimage.psRunning, trunc(100.0 * (Stream.position / Stream.size)), False, Rect(0,0,0,0), '', ContProgress); + if not ContProgress then exit; + WriteScanLine(Img); + + {$ifdef FPC_Debug_Image} + WriteLn('TFPReaderPSD.InternalRead AAA1 ',Stream.position,' ',Stream.size); + {$endif} + finally + FreeAndNil(FPalette); + ReAllocMem(FScanLine,0); + end; + Progress(FPimage.psEnding, 100, false, Rect(0,0,FWidth,FHeight), '', ContProgress); +end; + +function TFPReaderPSD.ReadScanLine(Stream: TStream): boolean; +Var + P : PByte; + B : Byte; + I : PtrInt; + J : integer; + N : Shortint; + Count:integer; + ContProgress: Boolean; +begin + Result:=false; + ContProgress:=true; + If Not Compressed then + Stream.ReadBuffer(FScanLine^,FLineSize) + else + begin + P:=FScanLine; + i:=FByteRead; + repeat + Count:=0; + N:=0; + Stream.ReadBuffer(N,1); + Progress(FPimage.psRunning, trunc(100.0 * (Stream.position / Stream.size)), False, Rect(0,0,0,0), '', ContProgress); + if not ContProgress then exit; + dec(i); + If N = -128 then + else + if N < 0 then + begin + Count:=-N+1; + B:=0; + Stream.ReadBuffer(B,1); + dec(i); + For j := 0 to Count-1 do + begin + P[0]:=B; + inc(p); + end; + end + else + begin + Count:=N+1; + For j := 0 to Count-1 do + begin + Stream.ReadBuffer(B,1); + P[0]:=B; + inc(p); + dec(i); + end; + end; + until (i <= 0); + end; + Result:=true; +end; + +procedure TFPReaderPSD.WriteScanLine(Img: TFPCustomImage); +Var + Col : Integer; + C : TFPColor; + P, P1, P2, P3 : PByte; + Z2 : Longint; + Row : Integer; + Lab : TLab; +begin + C.Alpha:=AlphaOpaque; + P:=FScanLine; + Z2:=FHeader.Depth div 8; + Z2:=Z2 *FHeight*FWidth; + begin + case FBytesPerPixel of + 1 : begin + for Row:=0 to Img.Height-1 do + begin + for Col:=0 to Img.Width-1 do + if (P[col div 8] and (128 shr (col mod 8))) <> 0 then + Img.Colors[Col,Row]:=ThePalette[0] + else + Img.Colors[Col,Row]:=ThePalette[1]; + inc(P, Img.Width div 8); + end; + end; + 8 : begin + for Row:=0 to Img.Height-1 do + for Col:=0 to Img.Width-1 do + begin + Img.Colors[Col,Row]:=ThePalette[P[0]]; + inc(p); + end; + end; + 16 : begin + for Row:=0 to Img.Height-1 do + for Col:=0 to Img.Width-1 do + begin + Img.Colors[Col,Row]:=ThePalette[BEtoN(PWord(P)^)]; + inc(p,2); + end; + end; + 24 :begin + P1:=P; + inc(P1,Z2); + P2:=P; + inc(P2,Z2*2); + for Row:=0 to Img.Height-1 do + for Col:=0 to Img.Width-1 do + begin + if (FHeader.Mode =9) then + begin + Lab.L:=(P[0]); + Lab.a:=(P1[0]); + Lab.b:=(P2[0]); + C:=LabToRGB(Lab); + end + else + With C do + begin + Red:=P[0] or (P[0] shl 8); + green:=P1[0] or (P1[0] shl 8); + blue:=P2[0] or (P2[0] shl 8); + alpha:=alphaOpaque; + end; + Inc(P); + Inc(P1); + Inc(P2); +// if (Header.Mode =9) then C:=XYZtoRGB(C); // Lab color + Img[col, row] := C; + end; + end; + 32 :begin + P1:=P; + inc(P1,Z2); + P2:=P; + inc(P2,Z2*2); + P3:=P; + inc(P3,Z2*3); + for Row:=0 to Img.Height-1 do + for Col:=0 to Img.Width-1 do + begin + if (FHeader.Mode =4) then + begin + P^ := 255 - P^; + P1^ := 255 - P1^; + P2^ := 255 - P2^; + P3^ := 255 - P3^; + end; + C.Red:=P[0] or (P[0] shl 8); + C.green:=P1[0] or (P1[0] shl 8); + C.blue:=P2[0] or (P2[0] shl 8); + C.alpha:=P3[0] or (P3[0] shl 8); + if (FHeader.Mode =4) then C:=CMYKtoRGB(C); // CMYK to RGB + Img[col, row] := C; + Inc(P); + Inc(P1); + Inc(P2); + Inc(P3); + end; + end; + 48 :begin + P1:=P; + inc(P1,Z2); + P2:=P; + inc(P2,Z2*2); + C.alpha:=alphaOpaque; + for Row:=0 to Img.Height-1 do + for Col:=0 to Img.Width-1 do + begin + With C do + begin + Red:=BEtoN(PWord(P)^); + green:=BEtoN(PWord(P1)^); + blue:=BEtoN(PWord(P2)^); + end; + Inc(P,2); + Inc(P1,2); + Inc(P2,2); + Img[col, row] := C; + end; + end; + 64 :begin + P1:=P; + inc(P1,Z2); + P2:=P; + inc(P2,Z2*2); + P3:=P; + inc(P3,Z2*3); + for Row:=0 to Img.Height-1 do + for Col:=0 to Img.Width-1 do + begin + C.Red:=BEtoN(PWord(P)^); + C.green:=BEtoN(PWord(P1)^); + C.blue:=BEtoN(PWord(P2)^); + C.alpha:=BEtoN(PWord(P3)^); + if (FHeader.Mode =4) then + begin + C.red:=$ffff-C.red; + C.green:=$ffff-C.green; + C.blue:=$ffff-C.blue; + C.alpha:=$ffff-C.alpha; + end; + if (FHeader.Mode =4) then C:=CMYKtoRGB(C); // CMYK to RGB + Img[col, row] := C; + Inc(P,2); + Inc(P1,2); + Inc(P2,2); + Inc(P3,2); + end; + end; + end; + end; +end; + +function TFPReaderPSD.InternalCheck(Stream: TStream): boolean; +var + OldPos: Int64; +begin + try + OldPos:=Stream.Position; + Stream.Read(FHeader,SizeOf(FHeader)); + Result:=(FHeader.Signature = '8BPS'); + Stream.Position:=OldPos; + except + Result:=False; + end; +end; + +constructor TFPReaderPSD.Create; +begin + inherited Create; +end; + +initialization + ImageHandlers.RegisterImageReader ('PSD Format', 'PSD', TFPReaderPSD); + ImageHandlers.RegisterImageReader ('PDD Format', 'PDD', TFPReaderPSD); + +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/fpreadtga.pp b/mseide-msegui/lib/common/fpccompatibility/fpreadtga.pp new file mode 100644 index 0000000..18855a1 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpreadtga.pp @@ -0,0 +1,345 @@ +{*****************************************************************************} +{ + This file is part of the Free Pascal's "Free Components Library". + Copyright (c) 2003 by Mazen NEIFER of the Free Pascal development team + + BMP writer implementation. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +{*****************************************************************************} + +{ - 22/11/2007 Modified by Laurent Jacques for support all format } + +{$mode objfpc} +{$h+} + +unit FPReadTGA; + +interface + +uses FPImage, classes,mclasses, sysutils, targacmn; + +const + TARGA_EMPTY_IMAGE = 0; + TARGA_INDEXED_IMAGE = 1; + TARGA_TRUECOLOR_IMAGE = 2; + TARGA_GRAY_IMAGE = 3; + +type + + { TFPReaderTarga } + + TFPReaderTarga = class (TFPCustomImageReader) + Private + Procedure FreeBuffers; // Free (and nil) buffers. + protected + Header : TTargaHeader; + AlphaBits : Byte; + Identification : ShortString; + Compressed, + BottomUp : Boolean; + BytesPerPixel : Byte; + FPalette : PFPColor; + FScanLine : PByte; + FLineSize : Integer; + FPaletteSize : Integer; + FBlockCount : Integer; + FPixelCount : Integer; + FLastPixel : Packed Array[0..3] of byte; + // AnalyzeHeader will allocate the needed buffers. + Procedure AnalyzeHeader(Img : TFPCustomImage); + procedure CreateGrayPalette; + Procedure ReadPalette(Stream : TStream); + procedure ReadScanLine(Row : Integer; Stream : TStream); virtual; + procedure WriteScanLine(Row : Integer; Img : TFPCustomImage); virtual; + // required by TFPCustomImageReader + procedure InternalRead (Stream:TStream; Img:TFPCustomImage); override; + function InternalCheck (Stream:TStream) : boolean; override; + public + constructor Create; override; + destructor Destroy; override; + end; + +Implementation + +Constructor TFPReaderTarga.Create; + +begin +end; + +Destructor TFPReaderTarga.Destroy; + +begin + FreeBuffers; + Inherited; +end; + +Procedure TFPReaderTarga.FreeBuffers; + +begin + If (FScanLine<>Nil) then + begin + FreeMem(FScanLine); + FScanLine:=Nil; + end; + If (FPalette<>Nil) then + begin + FreeMem(FPalette); + FScanLine:=Nil; + end; +end; + +Procedure TFPReaderTarga.AnalyzeHeader(Img : TFPCustomImage); + +begin + With Header do + begin + if not (ImgType in [1, 2, 3, 9, 10, 11]) and + not (PixelSize in [8, 16, 24, 32]) then + Raise Exception.Create('Unknown/Unsupported Targa image type'); + BottomUp:=(Flags and $20) <>0; + AlphaBits := Flags and $0F; + BytesPerPixel:=PixelSize; + Compressed:=ImgType>8; + If Compressed then + ImgType:=ImgType-8; + FLineSize:=(BytesPerPixel div 8)*ToWord(Width); + GetMem(FScanLine,FLineSize); + + if ImgType = TARGA_GRAY_IMAGE then + FPaletteSize:=SizeOf(TFPColor)*255 + else + FPaletteSize:=SizeOf(TFPColor)*ToWord(MapLength); + GetMem(FPalette,FPaletteSize); + Img.Width:=ToWord(Width); + Img.Height:=ToWord(Height); + end; +end; + +Procedure TFPReaderTarga.CreateGrayPalette; + +Var + I : Integer; + +Begin + For I:=0 To 255 Do + Begin + With FPalette[I] do + begin + Red:=I*255; + Green:=I*255; + Blue:=I*255; + Alpha:=AlphaOpaque; + end; + end; +End; + +Procedure TFPReaderTarga.ReadPalette(Stream : TStream); + +Var + BGREntry : TBGREntry; + BGRAEntry : TBGRAEntry; + I : Integer; + +begin + Case Header.MapEntrySize Of + 16, 24: + For I:=0 to ToWord(Header.MapLength)-1 do + begin + Stream.ReadBuffer(BGREntry, SizeOf(BGREntry)); + With FPalette[I] do + begin + Red:=BGREntry.Red shl 8; + Green:=BGREntry.Green shl 8; + Blue:=BGREntry.Blue shl 8; + Alpha:=alphaOpaque; + end; + end; + 32: + For I:=0 to ToWord(Header.MapLength)-1 do + begin + Stream.ReadBuffer(BGRAEntry,SizeOf(BGRAEntry)); + With FPalette[I] do + begin + Red:=BGRAEntry.Red shl 8; + Green:=BGRAEntry.Green shl 8; + Blue:=BGRAEntry.Blue shl 8; + if alphaBits = 8 then + if (BGRAEntry.Alpha and $80) <> 0 then + Alpha:=alphaTransparent + else + Alpha:=AlphaOpaque; + end; + end; + end; +end; + + +Procedure TFPReaderTarga.InternalRead (Stream:TStream; Img:TFPCustomImage); + +var + H,Row : Integer; + +begin + Stream.Read(Header,SizeOf(Header)); + AnalyzeHeader(Img); + If Header.IdLen>0 then + begin + SetLength(Identification,Header.IDLen); + Stream.Read(Identification[1],Header.Idlen); + If Length(Identification)<>0 then + Img.Extra[KeyIdentification]:=Identification; + end; + + If Header.MapType<>0 then + ReadPalette(Stream); + if Header.ImgType = TARGA_GRAY_IMAGE then + CreateGrayPalette; + + H:=Img.height; + If BottomUp then + For Row:=0 to H-1 do + begin + ReadScanLine(Row,Stream); + WriteScanLine(Row,Img); + end + else + For Row:=H-1 downto 0 do + begin + ReadScanLine(Row,Stream); + WriteScanLine(Row,Img); + end; +end; + +Procedure TFPReaderTarga.ReadScanLine(Row : Integer; Stream : TStream); + +Var + P : PByte; + B : Byte; + I,J : Integer; + +begin + If Not Compressed then + Stream.ReadBuffer(FScanLine^,FLineSize) + else + begin + P:=FScanLine; + For I:=0 to ToWord(Header.Width)-1 do + begin + If (FPixelCount>0) then + Dec(FPixelCount) + else + begin + Dec(FBlockCount); + If (FBlockCount<0) then + begin + Stream.ReadBuffer(B,1); + If (B and $80)<>0 then + begin + FPixelCount:=B and $7F; + FblockCount:=0; + end + else + FBlockCount:=B and $7F + end; + Stream.ReadBuffer(FlastPixel,BytesPerPixel shr 3); + end; + For J:=0 to (BytesPerPixel shr 3)-1 do + begin + P[0]:=FLastPixel[j]; + Inc(P); + end; + end; + end; +end; + +Procedure TFPReaderTarga.WriteScanLine(Row : Integer; Img : TFPCustomImage); + +Var + Col : Integer; + C : TFPColor; + W : Word; + P : PByte; + +begin + C.Alpha:=AlphaOpaque; + P:=FScanLine; + Case Header.ImgType of + TARGA_INDEXED_IMAGE + : for Col:=0 to Img.width-1 do + Img.Colors[Col,Row]:=FPalette[P[Col]]; + TARGA_TRUECOLOR_IMAGE + : for Col:=0 to Img.Width-1 do + begin + // Fill C depending on number of pixels. + case BytesPerPixel of + 8,16 : begin + W:=P[0]; + inc(P); + W:=W or (P[0] shl 8); + With C do + begin + Red:=((W)shr 10) shl 11; + Green:=((w)shr 5) shl 11; + Blue:=((w)) shl 11; + end; + end; + 24,32 : With C do + begin + Blue:=P[0] or (P[0] shl 8); + Inc(P); + Green:=P[0] or (P[0] shl 8); + Inc(P); + Red:=P[0] or (P[0] shl 8); + If bytesPerPixel=32 then + begin + Inc(P); + Alpha:=AlphaOpaque; + if alphaBits = 8 then + if (P[0] and $80) = 0 then + Alpha:=alphaTransparent; + end; + end; + end; // Case BytesPerPixel; + Img[Col,Row]:=C; + Inc(P); + end; + TARGA_GRAY_IMAGE + : case BytesPerPixel of + 8 : for Col:=0 to Img.width-1 do + Img.Colors[Col,Row]:=FPalette[P[Col]]; + 16 : for Col:=0 to Img.width-1 do + begin + With C do + begin + Blue:=FPalette[P^].blue; + Green:=FPalette[P^].green; + Red:=FPalette[P^].red; + Inc(P); + Alpha:=AlphaOpaque; + if alphaBits = 8 then + if (P[0] and $80) = 0 then + Alpha:=alphaTransparent; + Inc(P); + end; + Img[Col,Row]:=C; + end; + end; + end; +end; + +function TFPReaderTarga.InternalCheck (Stream:TStream) : boolean; + +begin + Result:=True; +end; + +initialization + ImageHandlers.RegisterImageReader ('TARGA Format', 'tga', TFPReaderTarga); +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/fpreadtiff.pas b/mseide-msegui/lib/common/fpccompatibility/fpreadtiff.pas new file mode 100644 index 0000000..c0980c8 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpreadtiff.pas @@ -0,0 +1,2400 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 2012 by the Free Pascal development team + + Tiff reader for fpImage. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + ********************************************************************** + + Working: + Grayscale 8,16bit (optional alpha), + RGB 8,16bit (optional alpha), + Orientation, + skipping Thumbnail to read first image, + compression: packbits, LZW, deflate + endian + multiple images + strips and tiles + + ToDo: + Compression: jpeg, ... + PlanarConfiguration 2 + ColorMap + separate mask + fillorder - not needed by baseline tiff reader + bigtiff 64bit offsets + XMP tag 700 + ICC profile tag 34675 + orientation with rotation +} +//modified 2013 by Martin Schreiber + +unit fpreadtiff; +{$ifdef FPC}{$mode objfpc}{$H+}{$inline on}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + math, classes, mclasses, sysutils, msectypes, + {$ifdef FPC}zinflate,zbase,{$else}zinflate_del,zbase_del,classes_del,{$endif} + msetypes, fpimage, fptiffcmn; + +type + TFPReaderTiff = class; + + TTiffCreateCompatibleImgEvent = procedure(Sender: TFPReaderTiff; + ImgFileDir: TTiffIFD) of object; + + TTiffCheckIFDOrder = ( + tcioSmart, + tcioAlways, + tcioNever + ); + + { TFPReaderTiff } + + TFPReaderTiff = class(TFPCustomImageReader) + private + FCheckIFDOrder: TTiffCheckIFDOrder; + FFirstIFDStart: DWord; + FOnCreateImage: TTiffCreateCompatibleImgEvent; + FReverserEndian: boolean; + IFD: TTiffIFD; + {$ifdef FPC_Debug_Image} + FDebug: boolean; + {$endif} + fIFDStarts: TFPList; + FReverseEndian: Boolean; + fStartPos: int64; + s: TStream; + function GetImages(Index: integer): TTiffIFD; + procedure TiffError(Msg: string); + procedure SetStreamPos(p: DWord); + function ReadTiffHeader(QuickTest: boolean; out IFDStart: DWord): boolean; // returns IFD: offset to first IFD + function ReadIFD(Start: DWord): DWord;// Image File Directory + procedure ReadDirectoryEntry(var EntryTag: Word); + function ReadEntryUnsigned: DWord; + function ReadEntrySigned: Cint32; + function ReadEntryRational: TTiffRational; + function ReadEntryString: string; + function ReadByte: Byte; + function ReadWord: Word; + function ReadDWord: DWord; + procedure ReadValues(StreamPos: DWord; + out EntryType: word; out EntryCount: DWord; + out Buffer: Pointer; out ByteCount: PtrUInt); + procedure ReadShortOrLongValues(StreamPos: DWord; + out Buffer: PDWord; out Count: DWord); + procedure ReadShortValues(StreamPos: DWord; + out Buffer: PWord; out Count: DWord); + procedure ReadImageProperties( + out RedBits, GreenBits, BlueBits, GrayBits, AlphaBits: Word; + out ExtraSamples: PWord; out ExtraSampleCnt: DWord; + out SampleBits: PWord; out SampleBitsPerPixel: DWord); + procedure ReadImgValue(BitCount: Word; var Run: Pointer; x: dword; + Predictor: word; var LastValue: word; out Value: Word); + {$ifdef FPC}inline;{$endif} + function FixEndian(w: Word): Word; {$ifdef FPC}inline;{$endif} overload; + function FixEndian(d: DWord): DWord; {$ifdef FPC}inline;{$endif} overload; + procedure SetFPImgExtras(CurImg: TFPCustomImage); + procedure DecodePackBits(var Buffer: Pointer; var Count: PtrInt); + procedure DecodeLZW(var Buffer: Pointer; var Count: PtrInt); + procedure DecodeDeflate(var Buffer: Pointer; var Count: PtrInt; ExpectedCount: PtrInt); + protected + procedure InternalRead(Str: TStream; AnImage: TFPCustomImage); override; + function InternalCheck(Str: TStream): boolean; override; + procedure DoCreateImage(ImgFileDir: TTiffIFD); virtual; + public + ImageList: TFPList; // list of TTiffIFD + constructor Create; override; + destructor Destroy; override; + procedure Clear; + procedure LoadFromStream(aStream: TStream; AutoClear: boolean = true); + procedure LoadHeaderFromStream(aStream: TStream); + procedure LoadIFDsFromStream; // requires LoadHeaderFromStream, creates Images + procedure LoadImageFromStream(Index: integer); // requires LoadIFDsFromStream + {$ifdef FPC_Debug_Image} + property Debug: boolean read FDebug write FDebug; + {$endif} + property StartPos: int64 read fStartPos; + property ReverserEndian: boolean read FReverserEndian; + property TheStream: TStream read s; + property OnCreateImage: TTiffCreateCompatibleImgEvent read FOnCreateImage + write FOnCreateImage; + property CheckIFDOrder: TTiffCheckIFDOrder read FCheckIFDOrder write FCheckIFDOrder; + function FirstImg: TTiffIFD; + function GetBiggestImage: TTiffIFD; + function ImageCount: integer; + property Images[Index: integer]: TTiffIFD read GetImages; default; + property FirstIFDStart: DWord read FFirstIFDStart; + end; + +procedure DecompressPackBits(Buffer: Pointer; Count: PtrInt; + out NewBuffer: Pointer; out NewCount: PtrInt); +procedure DecompressLZW(Buffer: Pointer; Count: PtrInt; + out NewBuffer: PByte; out NewCount: PtrInt); +function DecompressDeflate(Compressed: PByte; CompressedCount: cardinal; + out Decompressed: PByte; var DecompressedCount: cardinal; + ErrorMsg: PAnsiString = nil): boolean; + +implementation +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +function CMYKToFPColor(C,M,Y,K: Word): TFPColor; +var R, G, B : LongWord; +begin + R := $ffff - ((LongWord(C)*($ffff-LongWord(K))) shr 16) - LongWord(K) ; + G := $ffff - ((LongWord(M)*($ffff-LongWord(K))) shr 16) - LongWord(K) ; + B := $ffff - ((LongWord(Y)*($ffff-LongWord(K))) shr 16) - LongWord(K) ; + Result := FPColor(R and $ffff,G and $ffff,B and $ffff); +end ; + +procedure TFPReaderTiff.TiffError(Msg: string); +begin + Msg:=Msg+' at position '+IntToStr(s.Position); + if fStartPos>0 then + Msg:=Msg+' (TiffPosition='+IntToStr(fStartPos)+')'; + raise Exception.Create(Msg); +end; + +function TFPReaderTiff.GetImages(Index: integer): TTiffIFD; +begin + Result:=TTiffIFD(ImageList[Index]); +end; + +type + worda4ty = array[0..3] of word; + pworda4ty = ^worda4ty; +{$warnings off} +procedure TFPReaderTiff.ReadImageProperties(out RedBits, GreenBits, BlueBits, + GrayBits, AlphaBits: Word; out ExtraSamples: PWord; out + ExtraSampleCnt: DWord; out SampleBits: PWord; out SampleBitsPerPixel: DWord); +var + BytesPerPixel: Word; + SampleCnt: DWord; + i: Integer; +begin + ReadShortValues(IFD.BitsPerSample, SampleBits, SampleCnt); + if SampleCnt<>IFD.SamplesPerPixel then + TiffError('Samples='+IntToStr(SampleCnt)+' <> SamplesPerPixel='+IntToStr(IFD + .SamplesPerPixel)); + if IFD.ExtraSamples>0 then + ReadShortValues(IFD.ExtraSamples, ExtraSamples, ExtraSampleCnt); + if ExtraSampleCnt>=SampleCnt then + TiffError('Samples='+IntToStr(SampleCnt)+' ExtraSampleCnt='+IntToStr( + ExtraSampleCnt)); + case IFD.PhotoMetricInterpretation of + 0, 1: if SampleCnt-ExtraSampleCnt<>1 then + TiffError('gray images expect one sample per pixel, but found '+IntToStr( + SampleCnt)); + 2: if SampleCnt-ExtraSampleCnt<>3 then + TiffError('rgb images expect three samples per pixel, but found '+IntToStr( + SampleCnt)); + 3: if SampleCnt-ExtraSampleCnt<>1 then + TiffError('palette images expect one sample per pixel, but found '+IntToStr( + SampleCnt)); + 4: if SampleCnt-ExtraSampleCnt<>1 then + TiffError('mask images expect one sample per pixel, but found '+IntToStr( + SampleCnt)); + 5: if SampleCnt-ExtraSampleCnt<>4 then + TiffError('cmyk images expect four samples per pixel, but found '+IntToStr( + SampleCnt)); + end; + + GrayBits:=0; + RedBits:=0; + GreenBits:=0; + BlueBits:=0; + AlphaBits:=0; + BytesPerPixel:=0; + SampleBitsPerPixel:=0; + for i:=0 to SampleCnt-1 do begin + if pwordaty(SampleBits)^[i]>64 then + TiffError('Samples bigger than 64 bit not supported'); + if not (pwordaty(SampleBits)^[i] in [8, 16]) then + TiffError('Only samples of 8 and 16 bit are supported'); + inc(SampleBitsPerPixel, pwordaty(SampleBits)^[i]); + end; + case IFD.PhotoMetricInterpretation of + 0, 1: + begin + GrayBits:=pwordaty(SampleBits)^[0]; + IFD.GrayBits:=GrayBits; + for i:=0 to ExtraSampleCnt-1 do begin + if pwordaty(ExtraSamples)^[i] in [1, 2] then begin + AlphaBits:= pwordaty(SampleBits)^[1+i]; + IFD.AlphaBits:=AlphaBits; + end; + end; + if not (GrayBits in [8, 16]) then + TiffError('gray image only supported with gray BitsPerSample 8 or 16'); + if not (AlphaBits in [0, 8, 16]) then + TiffError('gray image only supported with alpha BitsPerSample 8 or 16'); + end; + 2: + begin + RedBits:= pworda4ty(SampleBits)^[0]; + GreenBits:= pworda4ty(SampleBits)^[1]; + BlueBits:= pworda4ty(SampleBits)^[2]; + IFD.RedBits:=RedBits; + IFD.GreenBits:=GreenBits; + IFD.BlueBits:=BlueBits; + IFD.AlphaBits:=0; + for i:=0 to ExtraSampleCnt-1 do begin + //writeln(' ',i,'/',ExtraSampleCnt,' Type=',ExtraSamples[i],' Count=',SampleBits[3+i]); + if pwordaty(ExtraSamples)^[i] in [1, 2] then begin + AlphaBits:= pwordaty(SampleBits)^[3+i]; + IFD.AlphaBits:=AlphaBits; + end; + end; + if not (RedBits in [8, 16]) then + TiffError('RGB image only supported with red BitsPerSample 8 or 16'); + if not (GreenBits in [8, 16]) then + TiffError('RGB image only supported with green BitsPerSample 8 or 16'); + if not (BlueBits in [8, 16]) then + TiffError('RGB image only supported with blue BitsPerSample 8 or 16'); + if not (AlphaBits in [0, 8, 16]) then + TiffError('RGB image only supported with alpha BitsPerSample 8 or 16'); + end; + 5: + begin + RedBits:= pworda4ty(SampleBits)^[0]; + GreenBits:= pworda4ty(SampleBits)^[1]; + BlueBits:= pworda4ty(SampleBits)^[2]; + GrayBits:= pworda4ty(SampleBits)^[3]; + IFD.RedBits:=RedBits; + IFD.GreenBits:=GreenBits; + IFD.BlueBits:=BlueBits; + IFD.GrayBits:=GrayBits; + IFD.AlphaBits:=0; + for i:=0 to ExtraSampleCnt-1 do begin + if pwordaty(ExtraSamples)^[i] in [1, 2] then begin + AlphaBits:= pwordaty(SampleBits)^[4+i]; + IFD.AlphaBits:=AlphaBits; + end; + end; + if not (RedBits in [8, 16]) then + TiffError('CMYK image only supported with cyan BitsPerSample 8 or 16'); + if not (GreenBits in [8, 16]) then + TiffError('CMYK image only supported with magenta BitsPerSample 8 or 16' + ); + if not (BlueBits in [8, 16]) then + TiffError('CMYK image only supported with yellow BitsPerSample 8 or 16' + ); + if not (GrayBits in [8, 16]) then + TiffError('CMYK image only supported with black BitsPerSample 8 or 16'); + if not (AlphaBits in [0, 8, 16]) then + TiffError('CMYK image only supported with alpha BitsPerSample 8 or 16'); + end; + end; + BytesPerPixel:=(GrayBits+RedBits+GreenBits+BlueBits+AlphaBits) div 8; + IFD.BytesPerPixel:=BytesPerPixel; + {$ifdef FPC_Debug_Image} + if Debug then + writeln('BytesPerPixel=', BytesPerPixel); + {$endif} + + if not (IFD.FillOrder in [0, 1]) then + TiffError('FillOrder unsupported: '+IntToStr(IFD.FillOrder)); +end; +{$warnings on} + +procedure TFPReaderTiff.SetFPImgExtras(CurImg: TFPCustomImage); +begin + ClearTiffExtras(CurImg); + // set Tiff extra attributes + CurImg.Extra[TiffPhotoMetric]:=IntToStr(IFD.PhotoMetricInterpretation); + //writeln('TFPReaderTiff.SetFPImgExtras PhotoMetric=',CurImg.Extra[TiffPhotoMetric]); + if IFD.Artist<>'' then + CurImg.Extra[TiffArtist]:=IFD.Artist; + if IFD.Copyright<>'' then + CurImg.Extra[TiffCopyright]:=IFD.Copyright; + if IFD.DocumentName<>'' then + CurImg.Extra[TiffDocumentName]:=IFD.DocumentName; + if IFD.DateAndTime<>'' then + CurImg.Extra[TiffDateTime]:=IFD.DateAndTime; + if IFD.HostComputer<>'' then + CurImg.Extra[TiffHostComputer]:=IFD.HostComputer; + if IFD.ImageDescription<>'' then + CurImg.Extra[TiffImageDescription]:=IFD.ImageDescription; + if IFD.Make_ScannerManufacturer<>'' then + CurImg.Extra[TiffMake_ScannerManufacturer]:=IFD.Make_ScannerManufacturer; + if IFD.Model_Scanner<>'' then + CurImg.Extra[TiffModel_Scanner]:=IFD.Model_Scanner; + if IFD.Software<>'' then + CurImg.Extra[TiffSoftware]:=IFD.Software; + if not (IFD.Orientation in [1..8]) then + IFD.Orientation:=1; + CurImg.Extra[TiffOrientation]:=IntToStr(IFD.Orientation); + if IFD.ResolutionUnit<>0 then + CurImg.Extra[TiffResolutionUnit]:=IntToStr(IFD.ResolutionUnit); + if (IFD.XResolution.Numerator<>0) or (IFD.XResolution.Denominator<>0) then + CurImg.Extra[TiffXResolution]:=TiffRationalToStr(IFD.XResolution); + if (IFD.YResolution.Numerator<>0) or (IFD.YResolution.Denominator<>0) then + CurImg.Extra[TiffYResolution]:=TiffRationalToStr(IFD.YResolution); + CurImg.Extra[TiffRedBits]:=IntToStr(IFD.RedBits); + CurImg.Extra[TiffGreenBits]:=IntToStr(IFD.GreenBits); + CurImg.Extra[TiffBlueBits]:=IntToStr(IFD.BlueBits); + CurImg.Extra[TiffGrayBits]:=IntToStr(IFD.GrayBits); + CurImg.Extra[TiffAlphaBits]:=IntToStr(IFD.AlphaBits); + if IFD.PageCount>0 then begin + CurImg.Extra[TiffPageNumber]:=IntToStr(IFD.PageNumber); + CurImg.Extra[TiffPageCount]:=IntToStr(IFD.PageCount); + end; + if IFD.PageName<>'' then + CurImg.Extra[TiffPageName]:=IFD.PageName; + if IFD.ImageIsThumbNail then + CurImg.Extra[TiffIsThumbnail]:='1'; + if IFD.ImageIsMask then + CurImg.Extra[TiffIsMask]:='1'; + if IFD.Compression<>TiffCompressionNone then + CurImg.Extra[TiffCompression]:=IntToStr(IFD.Compression); + + {$ifdef FPC_Debug_Image} + if Debug then + WriteTiffExtras('SetFPImgExtras', CurImg); + {$endif} +end; + +procedure TFPReaderTiff.ReadImgValue(BitCount: Word; var Run: Pointer; x: dword; + Predictor: word; var LastValue: word; out Value: Word); + {$ifdef FPC}inline;{$endif} +begin + if BitCount=8 then begin + Value:=PCUInt8(Run)^; + if Predictor=2 then begin + // horizontal difference + if x>0 then + Value:=(Value+LastValue) and $ff; + LastValue:=Value; + end; + Value:=Value shl 8+Value; + inc(pchar(Run)); + end else if BitCount=16 then begin + Value:=FixEndian(PCUInt16(Run)^); + if Predictor=2 then begin + // horizontal difference + if x>0 then + Value:=(Value+LastValue) and $ffff; + LastValue:=Value; + end; + inc(pchar(Run),2); + end; +end; + +procedure TFPReaderTiff.SetStreamPos(p: DWord); +var + NewPosition: int64; +begin + NewPosition:=Int64(p)+fStartPos; + if NewPosition>s.Size then + TiffError('Offset outside of stream'); + s.Position:=NewPosition; +end; + +procedure TFPReaderTiff.LoadFromStream(aStream: TStream; AutoClear: boolean); +var + IFDStart: DWord; + i: Integer; + aContinue: Boolean; +begin + if AutoClear then + Clear; + aContinue:=true; + Progress(psStarting, 0, False, Rect(0,0,0,0), '', aContinue); + if not aContinue then exit; + LoadHeaderFromStream(aStream); + try + IFDStart:=FirstIFDStart; + i:=0; + while IFDStart>0 do begin + if i=ImageCount then + ImageList.Add(TTiffIFD.Create); + IFD:=Images[i]; + IFDStart:=ReadIFD(IFDStart); + LoadImageFromStream(i); + inc(i); + end; + finally + IFD:=nil; + end; + Progress(psEnding, 100, False, Rect(0,0,0,0), '', aContinue); +end; + +procedure TFPReaderTiff.LoadHeaderFromStream(aStream: TStream); +begin + FFirstIFDStart:=0; + s:=aStream; + fStartPos:=s.Position; + ReadTiffHeader(false,FFirstIFDStart); +end; + +procedure TFPReaderTiff.LoadIFDsFromStream; +var + i: Integer; + IFDStart: DWord; +begin + try + IFDStart:=FirstIFDStart; + i:=0; + while IFDStart>0 do begin + if ImageCount=i then + ImageList.Add(TTiffIFD.Create); + IFD:=Images[i]; + IFDStart:=ReadIFD(IFDStart); + inc(i); + end; + finally + IFD:=nil; + end; +end; + +function TFPReaderTiff.FirstImg: TTiffIFD; +begin + Result:=nil; + if (ImageList=nil) or (ImageList.Count=0) then exit; + Result:=TTiffIFD(ImageList[0]); +end; + +function TFPReaderTiff.GetBiggestImage: TTiffIFD; +var + Size: Int64; + Img: TTiffIFD; + CurSize: int64; + i: Integer; +begin + Result:=nil; + Size:=0; + for i:=0 to ImageCount-1 do begin + Img:=Images[i]; + CurSize:=Int64(Img.ImageWidth)*Img.ImageHeight; + if CurSize2 then begin + {$ifdef FPC_Debug_Image} + if Debug then begin + write('TFPReaderTiff.ReadDirectoryEntry Tag 297: PageNumber/Count: '); + for i:=0 to Count-1 do + write(IntToStr(WordBuffer[i]),' '); + writeln; + end; + {$endif} + TiffError('PageNumber Count=2 expected, but found '+IntToStr(Count)); + end; + IFD.PageNumber:= pworda4ty(WordBuffer)^[0]; + IFD.PageCount:= pworda4ty(WordBuffer)^[1]; + if IFD.PageNumber>=IFD.PageCount then begin + // broken order => repair + UValue:=IFD.PageNumber; + IFD.PageNumber:=IFD.PageCount; + IFD.PageCount:=UValue; + end; + finally + ReAllocMem(WordBuffer,0); + end; + {$ifdef FPC_Debug_Image} + if Debug then begin + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 297: PageNumber=',IFD.PageNumber,'/',IFD.PageCount); + end; + {$endif} + end; + 305: + begin + // Software + IFD.Software:=ReadEntryString; + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 305: Software="',IFD.Software,'"'); + {$endif} + end; + 306: + begin + // DateAndTime + IFD.DateAndTime:=ReadEntryString; + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 306: DateAndTime="',IFD.DateAndTime,'"'); + {$endif} + end; + 315: + begin + // Artist + IFD.Artist:=ReadEntryString; + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 315: Artist="',IFD.Artist,'"'); + {$endif} + end; + 316: + begin + // HostComputer + IFD.HostComputer:=ReadEntryString; + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 316: HostComputer="',IFD.HostComputer,'"'); + {$endif} + end; + 317: + begin + // Predictor + UValue:=word(ReadEntryUnsigned); + case UValue of + 1: ; + 2: ; + else TiffError('expected Predictor, but found '+IntToStr(UValue)); + end; + IFD.Predictor:=UValue; + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 317: Predictor="',IFD.Predictor,'"'); + {$endif} + end; + 320: + begin + // ColorMap: N = 3*2^BitsPerSample + IFD.ColorMap:=GetPos; + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 320: skipping ColorMap'); + {$endif} + end; + 322: + begin + // TileWidth + IFD.TileWidth:=ReadEntryUnsigned; + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 322: TileWidth=',IFD.TileWidth); + {$endif} + if IFD.TileWidth=0 then + TiffError('TileWidth=0'); + end; + 323: + begin + // TileLength = TileHeight + IFD.TileLength:=ReadEntryUnsigned; + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 323: TileLength=',IFD.TileLength); + {$endif} + if IFD.TileLength=0 then + TiffError('TileLength=0'); + end; + 324: + begin + // TileOffsets + IFD.TileOffsets:=GetPos; + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 324: TileOffsets=',IFD.TileOffsets); + {$endif} + if IFD.TileOffsets=0 then + TiffError('TileOffsets=0'); + end; + 325: + begin + // TileByteCounts + IFD.TileByteCounts:=GetPos; + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 325: TileByteCounts=',IFD.TileByteCounts); + {$endif} + if IFD.TileByteCounts=0 then + TiffError('TileByteCounts=0'); + end; + 338: + begin + // ExtraSamples: if SamplesPerPixel is bigger than PhotometricInterpretation + // then ExtraSamples is an array defining the extra samples + // 0=unspecified + // 1=alpha (premultiplied) + // 2=alpha (unassociated) + IFD.ExtraSamples:=GetPos; + {$ifdef FPC_Debug_Image} + if Debug then begin + ReadShortValues(IFD.ExtraSamples,WordBuffer,Count); + write('TFPReaderTiff.ReadDirectoryEntry Tag 338: ExtraSamples: '); + for i:=0 to Count-1 do + write(IntToStr(WordBuffer[i]),' '); + writeln; + ReAllocMem(WordBuffer,0); + end; + {$endif} + end; + 347: + begin + // ToDo: JPEGTables + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 347: skipping JPEG Tables'); + {$endif} + end; + 512: + begin + // ToDo: JPEGProc + // short + // 1 = baseline sequential + // 14 = lossless process with Huffman encoding + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 512: skipping JPEGProc'); + {$endif} + end; + 513: + begin + // ToDo: JPEGInterchangeFormat + // long + // non zero: start of start of image SOI marker + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 513: skipping JPEGInterchangeFormat'); + {$endif} + end; + 514: + begin + // ToDo: JPEGInterchangeFormatLength + // long + // length in bytes of 513 + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 514: skipping JPEGInterchangeFormatLength'); + {$endif} + end; + 515: + begin + // ToDo: JPEGRestartInterval + // short + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 515: skipping JPEGRestartInterval'); + {$endif} + end; + 517: + begin + // ToDo: JPEGLosslessPredictor + // short + // Count: SamplesPerPixels + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 517: skipping JPEGLosslessPredictor'); + {$endif} + end; + 518: + begin + // ToDo: JPEGPointTransforms + // short + // Count: SamplesPerPixels + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 518: skipping JPEGPointTransforms'); + {$endif} + end; + 519: + begin + // ToDo: JPEGQTables + // long + // Count: SamplesPerPixels + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 519: skipping JPEGQTables'); + {$endif} + end; + 520: + begin + // ToDo: JPEGDCTables + // long + // Count: SamplesPerPixels + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 520: skipping JPEGDCTables'); + {$endif} + end; + 521: + begin + // ToDo: JPEGACTables + // long + // Count: SamplesPerPixels + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 521: skipping JPEGACTables'); + {$endif} + end; + 530: + begin + // ToDo: YCbCrSubSampling alias ChromaSubSampling + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 530: skipping YCbCrSubSampling alias ChromaSubSampling'); + {$endif} + end; + 700: + begin + // ToDo: XMP + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 700: skipping XMP'); + {$endif} + end; + 33432: + begin + // Copyright + IFD.Copyright:=ReadEntryString; + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 33432: Copyright="',IFD.Copyright,'"'); + {$endif} + end; + 34675: + begin + // ToDo: ICC Profile + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag 34675: skipping ICC profile'); + {$endif} + end; + else + begin + EntryType:=ReadWord; + EntryCount:=ReadDWord; + EntryStart:=ReadDWord; + if (EntryType=0) and (EntryCount=0) and (EntryStart=0) then ; + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.ReadDirectoryEntry Tag=',EntryTag,' Type=',EntryType,' Count=',EntryCount,' ValuesStart=',EntryStart); + {$endif} + end; + end; +end; + +function TFPReaderTiff.ReadEntryUnsigned: DWord; +var + EntryCount: LongWord; + EntryType: Word; +begin + Result:=0; + EntryType:=ReadWord; + EntryCount:=ReadDWord; + if EntryCount<>1 then + TiffError('EntryCount=1 expected, but found '+IntToStr(EntryCount)); + //writeln('TFPReaderTiff.ReadEntryUnsigned Tag=',EntryTag,' Type=',EntryType,' Count=',EntryCount,' ValuesStart=',EntryStart]); + case EntryType of + 1: begin + // byte: 8bit unsigned + Result:=ReadByte; + end; + 3: begin + // short: 16bit unsigned + Result:=ReadWord; + end; + 4: begin + // long: 32bit unsigned long + Result:=ReadDWord; + end; + else + TiffError('expected single unsigned value, but found type='+IntToStr(EntryType)); + end; +end; + +function TFPReaderTiff.ReadEntrySigned: Cint32; +var + EntryCount: LongWord; + EntryType: Word; +begin + Result:=0; + EntryType:=ReadWord; + EntryCount:=ReadDWord; + if EntryCount<>1 then + TiffError('EntryCount+1 expected, but found '+IntToStr(EntryCount)); + //writeln('TFPReaderTiff.ReadEntrySigned Tag=',EntryTag,' Type=',EntryType,' Count=',EntryCount,' ValuesStart=',EntryStart]); + case EntryType of + 1: begin + // byte: 8bit unsigned + Result:=cint8(ReadByte); + end; + 3: begin + // short: 16bit unsigned + Result:=cint16(ReadWord); + end; + 4: begin + // long: 32bit unsigned long + Result:=cint32(ReadDWord); + end; + 6: begin + // sbyte: 8bit signed + Result:=cint8(ReadByte); + end; + 8: begin + // sshort: 16bit signed + Result:=cint16(ReadWord); + end; + 9: begin + // slong: 32bit signed long + Result:=cint32(ReadDWord); + end; + else + TiffError('expected single signed value, but found type='+IntToStr(EntryType)); + end; +end; + +function TFPReaderTiff.ReadEntryRational: TTiffRational; +var + EntryCount: LongWord; + EntryStart: LongWord; + EntryType: Word; +begin + Result:=TiffRational0; + EntryType:=ReadWord; + EntryCount:=ReadDWord; + if EntryCount<>1 then + TiffError('EntryCount+1 expected, but found '+IntToStr(EntryCount)); + //writeln('TFPReaderTiff.ReadEntryUnsigned Tag=',EntryTag,' Type=',EntryType,' Count=',EntryCount,' ValuesStart=',EntryStart]); + case EntryType of + 1: begin + // byte: 8bit unsigned + Result.Numerator:=ReadByte; + end; + 3: begin + // short: 16bit unsigned + Result.Numerator:=ReadWord; + end; + 4: begin + // long: 32bit unsigned long + Result.Numerator:=ReadDWord; + end; + 5: begin + // rational: Two longs: numerator + denominator + // this does not fit into 4 bytes + EntryStart:=ReadDWord; + SetStreamPos(EntryStart); + Result.Numerator:=ReadDWord; + Result.Denominator:=ReadDWord; + end; + else + TiffError('expected rational unsigned value, but found type='+IntToStr(EntryType)); + end; +end; + +function TFPReaderTiff.ReadEntryString: string; +var + EntryType: Word; + EntryCount: LongWord; + EntryStart: LongWord; +begin + Result:=''; + EntryType:=ReadWord; + if EntryType<>2 then + TiffError('asciiz expected, but found '+IntToStr(EntryType)); + EntryCount:=ReadDWord; + EntryStart:=ReadDWord; + SetStreamPos(EntryStart); + SetLength(Result,EntryCount-1); + if EntryCount>1 then + s.Read(Result[1],EntryCount-1); +end; + +function TFPReaderTiff.ReadByte: Byte; +begin + Result:=s.ReadByte; +end; + +function TFPReaderTiff.ReadWord: Word; +begin + Result:=FixEndian(s.ReadWord); +end; + +function TFPReaderTiff.ReadDWord: DWord; +begin + Result:=FixEndian(s.ReadDWord); +end; + +procedure TFPReaderTiff.ReadValues(StreamPos: DWord; + out EntryType: word; out EntryCount: DWord; + out Buffer: Pointer; out ByteCount: PtrUint); +var + EntryStart: DWord; +begin + Buffer:=nil; + ByteCount:=0; + EntryType:=0; + EntryCount:=0; + SetStreamPos(StreamPos); + ReadWord; // skip tag + EntryType:=ReadWord; + EntryCount:=ReadDWord; + if EntryCount=0 then exit; + case EntryType of + 1,6,7: ByteCount:=EntryCount; // byte + 2: ByteCount:=EntryCount; // asciiz + 3,8: ByteCount:=2*EntryCount; // short + 4,9: ByteCount:=4*EntryCount; // long + 5,10: ByteCount:=8*EntryCount; // rational + 11: ByteCount:=4*EntryCount; // single + 12: ByteCount:=8*EntryCount; // double + else + TiffError('invalid EntryType '+IntToStr(EntryType)); + end; + if ByteCount>4 then begin + EntryStart:=ReadDWord; + SetStreamPos(EntryStart); + end; + GetMem(Buffer,ByteCount); + s.Read(Buffer^,ByteCount); +end; + +procedure TFPReaderTiff.ReadShortOrLongValues(StreamPos: DWord; out + Buffer: PDWord; out Count: DWord); +var + p: Pointer; + ByteCount: PtrUInt; + EntryType: word; + i: DWord; +begin + Buffer:=nil; + Count:=0; + p:=nil; + try + ReadValues(StreamPos,EntryType,Count,p,ByteCount); + if Count=0 then exit; + if EntryType=3 then begin + // short + GetMem(Buffer,SizeOf(DWord)*Count); + for i:=0 to Count-1 do + plongwordaty(Buffer)^[i]:=FixEndian(pwordaty(PWord(p))^[i]); + end else if EntryType=4 then begin + // long + Buffer:=p; + p:=nil; + if FReverseEndian then + for i:=0 to Count-1 do + plongwordaty(Buffer)^[i]:= + FixEndian(plongwordaty(PDWord(Buffer))^[i]); + end else + TiffError('only short or long allowed'); + finally + if p<>nil then FreeMem(p); + end; +end; + +procedure TFPReaderTiff.ReadShortValues(StreamPos: DWord; out Buffer: PWord; + out Count: DWord); +var + p: Pointer; + ByteCount: PtrUInt; + EntryType: word; + i: DWord; +begin + Buffer:=nil; + Count:=0; + p:=nil; + try + ReadValues(StreamPos,EntryType,Count,p,ByteCount); + //writeln('ReadShortValues ',FReverseEndian,' ',EntryType,' Count=',Count,' ByteCount=',ByteCount); + if Count=0 then exit; + if EntryType=3 then begin + // short + Buffer:=p; + p:=nil; + if FReverseEndian then + for i:=0 to Count-1 do + pwordaty(Buffer)^[i]:=FixEndian(pwordaty(Buffer)^[i]); + //for i:=0 to Count-1 do writeln(i,' ',Buffer[i]); + end else + TiffError('only short allowed, but found '+IntToStr(EntryType)); + finally + if p<>nil then FreeMem(p); + end; +end; + +procedure TFPReaderTiff.LoadImageFromStream(Index: integer); +var + ChunkOffsets: PDWord; + ChunkByteCounts: PDWord; + Chunk: PByte; + ChunkCount: DWord; + ChunkIndex: Dword; + CurCount: DWord; + CurOffset: DWord; + CurByteCnt: PtrInt; + Run: PByte; + x, y, cx, cy, dx, dy, sx: integer; + SampleBits: PWord; + SampleBitsPerPixel: DWord; + ExtraSamples: PWord; + ExtraSampleCnt: DWord; + GrayBits, GrayValue, LastGrayValue: Word; + RedBits, RedValue, LastRedValue: Word; + GreenBits, GreenValue, LastGreenValue: Word; + BlueBits, BlueValue, LastBlueValue: Word; + AlphaBits, AlphaValue, LastAlphaValue: Word; + Col: TFPColor; + i: Integer; + CurFPImg: TFPCustomImage; + aContinue: Boolean; + ExpectedChunkLength: PtrInt; + ChunkType: TTiffChunkType; + TilesAcross, TilesDown: DWord; + ChunkLeft, ChunkTop, ChunkWidth, ChunkHeight: DWord; + CurImg: TTiffIFD; + ChunkBytesPerLine: DWord; +begin + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.LoadImageFromStream Index=',Index); + {$endif} + IFD:=Images[Index]; + + if IFD.PhotoMetricInterpretation=High(IFD.PhotoMetricInterpretation) then + TiffError('missing PhotometricInterpretation'); + if IFD.BitsPerSample=0 then + TiffError('missing BitsPerSample'); + if IFD.TileWidth>0 then begin + ChunkType:=tctTile; + if IFD.TileLength=0 then + TiffError('missing TileLength'); + if IFD.TileOffsets=0 then + TiffError('missing TileOffsets'); + if IFD.TileByteCounts=0 then + TiffError('missing TileByteCounts'); + end else begin + ChunkType:=tctStrip; + if IFD.RowsPerStrip=0 then + TiffError('missing RowsPerStrip'); + if IFD.StripOffsets=0 then + TiffError('missing StripOffsets'); + if IFD.StripByteCounts=0 then + TiffError('missing StripByteCounts'); + end; + + if (IFD.ImageWidth=0) or (IFD.ImageHeight=0) then + exit; + + if Index=ImageCount then + ImageList.Add(TTiffIFD.Create); + CurImg:=Images[Index]; + + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.LoadImageFromStream reading ...'); + {$endif} + + ChunkOffsets:=nil; + ChunkByteCounts:=nil; + Chunk:=nil; + ExtraSamples:=nil; + SampleBits:=nil; + ExtraSampleCnt:=0; + try + // read chunk starts and sizes + if ChunkType=tctTile then begin + TilesAcross:=(IFD.ImageWidth+IFD.TileWidth-1) div IFD.TileWidth; + TilesDown:=(IFD.ImageHeight+IFD.TileLength-1) div IFD.TileLength; + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.LoadImageFromStream TilesAcross=',TilesAcross,' TilesDown=',TilesDown); + {$endif} + ChunkCount := TilesAcross * TilesDown; + ReadShortOrLongValues(IFD.TileOffsets,ChunkOffsets,CurCount); + if CurCount<>ChunkCount then + TiffError('number of TileCounts is wrong'); + ReadShortOrLongValues(IFD.TileByteCounts,ChunkByteCounts,CurCount); + if CurCount<>ChunkCount then + TiffError('number of TileByteCounts is wrong'); + end else begin + ChunkCount:=((IFD.ImageHeight-1) div IFD.RowsPerStrip)+1; + ReadShortOrLongValues(IFD.StripOffsets,ChunkOffsets,CurCount); + if CurCount<>ChunkCount then + TiffError('number of StripCounts is wrong'); + ReadShortOrLongValues(IFD.StripByteCounts,ChunkByteCounts,CurCount); + if CurCount<>ChunkCount then + TiffError('number of StripByteCounts is wrong'); + end; + + // read image structure + ReadImageProperties(RedBits, GreenBits, BlueBits, GrayBits, AlphaBits, + ExtraSamples, ExtraSampleCnt, SampleBits, SampleBitsPerPixel); + CurImg.Assign(IFD); + + // create FPimage + DoCreateImage(CurImg); + CurFPImg:=CurImg.Img; + if CurFPImg=nil then exit; + + SetFPImgExtras(CurFPImg); + + case IFD.Orientation of + 0,1..4: CurFPImg.SetSize(IFD.ImageWidth,IFD.ImageHeight); + 5..8: CurFPImg.SetSize(IFD.ImageHeight,IFD.ImageWidth); + end; + + {$ifdef FPC_Debug_Image} + if Debug then + writeln('TFPReaderTiff.LoadImageFromStream SampleBitsPerPixel=',SampleBitsPerPixel); + {$endif} + + // read chunks + for ChunkIndex:=0 to ChunkCount-1 do begin + CurOffset:= plongwordaty(ChunkOffsets)^[ChunkIndex]; + CurByteCnt:= plongwordaty(ChunkByteCounts)^[ChunkIndex]; + //writeln('TFPReaderTiff.LoadImageFromStream CurOffset=',CurOffset,' CurByteCnt=',CurByteCnt); + if CurByteCnt<=0 then continue; + ReAllocMem(Chunk,CurByteCnt); + SetStreamPos(CurOffset); + s.Read(Chunk^,CurByteCnt); + + // decompress + if ChunkType=tctTile then + ExpectedChunkLength:=(SampleBitsPerPixel*IFD.TileWidth+7) div 8*IFD.TileLength + else + ExpectedChunkLength:=((SampleBitsPerPixel*IFD.ImageWidth+7) div 8)*IFD.RowsPerStrip; + case IFD.Compression of + TiffCompressionNone: ; + TiffCompressionPackBits: DecodePackBits(pointer(Chunk),CurByteCnt); + TiffCompressionLZW: DecodeLZW(pointer(Chunk),CurByteCnt); + TiffCompressionDeflateAdobe, + TiffCompressionDeflateZLib: DecodeDeflate(pointer(Chunk),CurByteCnt,ExpectedChunkLength); + else + TiffError('compression '+TiffCompressionName(IFD.Compression)+' not supported yet'); + end; + if CurByteCnt<=0 then continue; + + // compute current chunk area + if ChunkType=tctTile then begin + ChunkLeft:=(ChunkIndex mod TilesAcross)*IFD.TileWidth; + ChunkTop:=(ChunkIndex div TilesAcross)*IFD.TileLength; + ChunkWidth:=Min(IFD.TileWidth,IFD.ImageWidth-ChunkLeft); + ChunkHeight:=Min(IFD.TileLength,IFD.ImageHeight-ChunkTop); + ChunkBytesPerLine:=(SampleBitsPerPixel*ChunkWidth+7) div 8; + ExpectedChunkLength:=ChunkBytesPerLine*ChunkHeight; + if CurByteCnt=0 then begin + Img:=Images[Best]; + Img.Img:=AnImage; + LoadImageFromStream(Best); + end; + // end + Progress(psEnding, 100, False, Rect(0,0,0,0), '', aContinue); +end; + +function TFPReaderTiff.InternalCheck(Str: TStream): boolean; +var + IFDStart: DWord; +begin + try + s:=Str; + fStartPos:=s.Position; + Result:=ReadTiffHeader(true,IFDStart) and (IFDStart<>0); + s.Position:=fStartPos; + except + Result:=false; + end; +end; + +procedure TFPReaderTiff.DoCreateImage(ImgFileDir: TTiffIFD); +begin + if Assigned(OnCreateImage) then + OnCreateImage(Self,ImgFileDir); +end; + +constructor TFPReaderTiff.Create; +begin + ImageList:=TFPList.Create; +end; + +destructor TFPReaderTiff.Destroy; +begin + Clear; + FreeAndNil(ImageList); + inherited Destroy; +end; + +procedure TFPReaderTiff.Clear; +var + i: Integer; + Img: TTiffIFD; +begin + for i:=ImageCount-1 downto 0 do begin + Img:=Images[i]; + ImageList.Delete(i); + if IFD=Img then IFD:=nil; + Img.Free; + end; + FReverseEndian:=false; + FreeAndNil(fIFDStarts); +end; + +procedure DecompressPackBits(Buffer: Pointer; Count: PtrInt; out + NewBuffer: Pointer; out NewCount: PtrInt); +{ Algorithm: + while not got the expected number of bytes + read one byte n + if n in 0..127 copy the next n+1 bytes + else if n in -127..-1 then copy the next byte 1-n times + else continue + end +} +var + p: Pcint8; + n: cint8; + d: pcint8; + i,j: integer; + EndP: Pcint8; +begin + // compute NewCount + NewCount:=0; + NewBuffer:=nil; + if Count=0 then exit; + p:=Pcint8(Buffer); + EndP:= pointer(pchar(p)+Count); + while pchar(p) < pchar(EndP) do begin + n:=p^; + case n of + 0..127: begin inc(NewCount,n+1); inc(p,n+2); end; // copy the next n+1 bytes + -127..-1: begin inc(NewCount,1-n); inc(p,2); end; // copy the next byte 1-n times + else inc(p); // noop + end; + end; + + // decompress + if NewCount=0 then exit; + GetMem(NewBuffer,NewCount); + p:=Pcint8(Buffer); + d:=Pcint8(NewBuffer); + while pchar(p) < pchar(EndP) do begin + n:=p^; + case n of + 0..127: + begin + // copy the next n+1 bytes + i:=n+1; + inc(NewCount,i); + inc(p); + System.Move(p^,d^,i); + inc(p,i); + inc(d,i); + end; + -127..-1: + begin + // copy the next byte 1-n times + i:=1-n; + inc(NewCount,i); + inc(p); + n:=p^; + for j:=0 to i-1 do + pbyteaty(d)^[j]:=n; + inc(d,i); + inc(p); + end; + else inc(p); // noop + end; + end; +end; + +{$warnings off} + +procedure DecompressLZW(Buffer: Pointer; Count: PtrInt; out NewBuffer: PByte; + out NewCount: PtrInt); +type + TLZWString = packed record + Count: integer; + Data: PByte; + end; + PLZWString = ^TLZWString; +const + ClearCode = 256; // clear table, start with 9bit codes + EoiCode = 257; // end of input +var + NewCapacity: PtrInt; + SrcPos: PtrInt; + SrcPosBit: integer; + CurBitLength: integer; + Code: Word; + Table: PLZWString; + TableCapacity: integer; + TableCount: integer; + OldCode: Word; + + procedure Error(const Msg: string); + begin + raise Exception.Create(Msg); + end; + + function GetNextCode: Word; + var + v: Integer; + begin + Result:=0; + // CurBitLength can be 9 to 12 + //writeln('GetNextCode CurBitLength=',CurBitLength,' SrcPos=',SrcPos,' SrcPosBit=',SrcPosBit,' ',hexstr(PByte(Buffer)[SrcPos],2),' ',hexstr(PByte(Buffer)[SrcPos+1],2),' ',hexstr(PByte(Buffer)[SrcPos+2],2)); + // read two or three bytes + if CurBitLength+SrcPosBit>16 then begin + // read from three bytes + if SrcPos+3>Count then Error('LZW stream overrun'); + v:= pbyteaty(PByte(Buffer))^[SrcPos]; + inc(SrcPos); + v:=(v shl 8)+ pbyteaty(PByte(Buffer))^[SrcPos]; + inc(SrcPos); + v:=(v shl 8)+ pbyteaty(PByte(Buffer))^[SrcPos]; + v:=v shr (24-CurBitLength-SrcPosBit); + end else begin + // read from two bytes + if SrcPos+2>Count then Error('LZW stream overrun'); + v:= pbyteaty(PByte(Buffer))^[SrcPos]; + inc(SrcPos); + v:=(v shl 8)+ pbyteaty(PByte(Buffer))^[SrcPos]; + if CurBitLength+SrcPosBit=16 then + inc(SrcPos); + v:=v shr (16-CurBitLength-SrcPosBit); + end; + Result:=v and ((1 shl CurBitLength)-1); + SrcPosBit:=(SrcPosBit+CurBitLength) and 7; + //writeln('GetNextCode END SrcPos=',SrcPos,' SrcPosBit=',SrcPosBit,' Result=',Result,' Result=',hexstr(Result,4)); + end; + + procedure ClearTable; + var + i: Integer; + begin + for i:=0 to TableCount-1 do + ReAllocMem(plzwstring(ppointeraty(Table)^[i])^.Data,0); + TableCount:=0; + end; + + procedure InitializeTable; + begin + CurBitLength:=9; + ClearTable; + end; + + function IsInTable(Code: word): boolean; + begin + Result:=Code<258+TableCount; + end; + + procedure WriteStringFromCode(Code: integer; AddFirstChar: boolean = false); + var + s: TLZWString; + b: byte; + begin + //WriteLn('WriteStringFromCode Code=',Code,' AddFirstChar=',AddFirstChar,' x=',(NewCount div 4) mod IFD.ImageWidth,' y=',(NewCount div 4) div IFD.ImageWidth,' PixelByte=',NewCount mod 4); + if Code<256 then begin + // write byte + b:=Code; + s.Data:=@b; + s.Count:=1; + end else if Code>=258 then begin + // write string + if Code-258>=TableCount then + Error('LZW code out of bounds'); + s:= plzwstring(ppointeraty(Table)^[Code-258])^; + end else + Error('LZW code out of bounds'); + if NewCount+s.Count+1>NewCapacity then begin + NewCapacity:=NewCapacity*2+8; + ReAllocMem(NewBuffer,NewCapacity); + end; + System.Move(s.Data^,pbyteaty(NewBuffer)^[NewCount],s.Count); + //for i:=0 to s.Count-1 do write(HexStr(NewBuffer[NewCount+i],2)); // debug + inc(NewCount,s.Count); + if AddFirstChar then begin + pbyteaty(NewBuffer)^[NewCount]:= s.Data^; + //write(HexStr(NewBuffer[NewCount],2)); // debug + inc(NewCount); + end; + //writeln(',WriteStringFromCode'); // debug + end; + + procedure AddStringToTable(Code, AddFirstCharFromCode: integer); + // add string from code plus first character of string from code as new string + var + b1, b2: byte; + s1, s2: TLZWString; + p: PByte; + begin + //WriteLn('AddStringToTable Code=',Code,' FCFCode=',AddFirstCharFromCode,' TableCount=',TableCount,' TableCapacity=',TableCapacity); + if TableCount=4096-259 then + Error('LZW too many codes'); + // grow table + if TableCount>=TableCapacity then begin + TableCapacity:=TableCapacity*2+128; + ReAllocMem(Table,TableCapacity*SizeOf(TLZWString)); + end; + // find string 1 + if Code<256 then begin + // string is byte + b1:=Code; + s1.Data:=@b1; + s1.Count:=1; + end else if Code>=258 then begin + // normal string + if Code-258>=TableCount then + Error('LZW code out of bounds'); + s1:= plzwstring(ppointeraty(Table)^[Code-258])^; + end else + Error('LZW code out of bounds'); + // find string 2 + if AddFirstCharFromCode<256 then begin + // string is byte + b2:=AddFirstCharFromCode; + s2.Data:=@b2; + s2.Count:=1; + end else begin + // normal string + if AddFirstCharFromCode-258>=TableCount then + Error('LZW code out of bounds'); + s2:= plzwstring(ppointeraty(Table)^[AddFirstCharFromCode-258])^; + end; + // set new table entry + plzwstring(ppointeraty(Table)^[TableCount])^.Count:= s1.Count+1; + p:=nil; + GetMem(p,s1.Count+1); + plzwstring(ppointeraty(Table)^[TableCount])^.Data:=p; + System.Move(s1.Data^,p^,s1.Count); + // add first character from string 2 + pbyteaty(p)^[s1.Count]:= s2.Data^; + // increase TableCount + inc(TableCount); + case TableCount+259 of + 512,1024,2048: inc(CurBitLength); + end; + end; + +begin + NewBuffer:=nil; + NewCount:=0; + if Count=0 then exit; + //WriteLn('DecompressLZW START Count=',Count); + //for SrcPos:=0 to 19 do + // write(HexStr(PByte(Buffer)[SrcPos],2)); + //writeln(); + + NewCapacity:=Count*2; + ReAllocMem(NewBuffer,NewCapacity); + + SrcPos:=0; + SrcPosBit:=0; + CurBitLength:=9; + Table:=nil; + TableCount:=0; + TableCapacity:=0; + try + repeat + Code:=GetNextCode; + //WriteLn('DecompressLZW Code=',Code); + if Code=EoiCode then break; + if Code=ClearCode then begin + InitializeTable; + Code:=GetNextCode; + //WriteLn('DecompressLZW after clear Code=',Code); + if Code=EoiCode then break; + if Code=ClearCode then + Error('LZW code out of bounds'); + WriteStringFromCode(Code); + OldCode:=Code; + end else begin + if Code Z_OK then begin + if ErrorMsg<>nil then + ErrorMsg^:='inflateInit failed'; + exit; + end; + + // set input = compressed data + stream.avail_in := CompressedCount; + stream.next_in := Compressed; + + // set output = decompressed data + if DecompressedCount=0 then + DecompressedCount:=CompressedCount; + Getmem(Decompressed,DecompressedCount); + stream.avail_out := DecompressedCount; + stream.next_out := Decompressed; + + // Finish the stream + while TRUE do begin + //writeln('run: total_in=',stream.total_in,' avail_in=',stream.avail_in,' total_out=',stream.total_out,' avail_out=',stream.avail_out); + if (stream.avail_out=0) then begin + // need more space + if DecompressedCount<128 then + DecompressedCount:=DecompressedCount+128 + else if DecompressedCount>High(DecompressedCount)-1024 then begin + if ErrorMsg<>nil then + ErrorMsg^:='inflate decompression failed, because not enough space'; + exit; + end else + DecompressedCount:=DecompressedCount*2; + ReAllocMem(Decompressed,DecompressedCount); + stream.next_out:= pointer(pchar(Decompressed)+stream.total_out); + stream.avail_out:= DecompressedCount-stream.total_out; + end; + err := inflate(stream, Z_NO_FLUSH); + if err = Z_STREAM_END then + break; + if err<>Z_OK then begin + if ErrorMsg<>nil then + ErrorMsg^:='inflate finish failed'; + exit; + end; + end; + + //writeln('decompressed: total_in=',stream.total_in,' total_out=',stream.total_out); + DecompressedCount:=stream.total_out; + ReAllocMem(Decompressed,DecompressedCount); + + err := inflateEnd(stream); + if err<>Z_OK then begin + if ErrorMsg<>nil then + ErrorMsg^:='inflateEnd failed'; + exit; + end; + Result:=true; +end; + +initialization + if ImageHandlers.ImageReader[TiffHandlerName]=nil then + ImageHandlers.RegisterImageReader (TiffHandlerName, 'tif;tiff', TFPReaderTiff); +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/fpreadxpm.pp b/mseide-msegui/lib/common/fpccompatibility/fpreadxpm.pp new file mode 100644 index 0000000..0acb712 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpreadxpm.pp @@ -0,0 +1,328 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 2003 by the Free Pascal development team + + XPM reader class. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + **********************************************************************} +{$mode objfpc}{$h+} +unit FPReadXPM; + +interface + +uses FPImage, classes,mclasses, sysutils; + +type + TFPReaderXPM = class (TFPCustomImageReader) + private + width, height, ncols, cpp, xhot, yhot : integer; + xpmext : boolean; + palette : TStringList; + function HexToColor(s : string) : TFPColor; + function NameToColor(s : string) : TFPColor; + function DiminishWhiteSpace (s : string) : string; + protected + procedure InternalRead (Str:TStream; Img:TFPCustomImage); override; + function InternalCheck (Str:TStream) : boolean; override; + public + constructor Create; override; + destructor Destroy; override; + end; + +implementation + +const + WhiteSpace = ' '#8#10#13; + +constructor TFPReaderXPM.create; +begin + inherited create; + palette := TStringList.Create; +end; + +destructor TFPReaderXPM.Destroy; +begin + Palette.Free; + inherited destroy; +end; + +function TFPReaderXPM.HexToColor(s : string) : TFPColor; +var l : integer; + function CharConv (c : char) : longword; + begin + if (c >= 'A') and (c <= 'F') then + result := ord (c) - ord('A') + 10 + else if (c >= '0') and (c <= '9') then + result := ord (c) - ord('0') + else + raise exception.CreateFmt ('Wrong character (%s) in hexadecimal number', [c]); + end; + function convert (n : string) : word; + var t,r: integer; + begin + result := 0; + t := length(n); + if t > 4 then + raise exception.CreateFmt ('Too many bytes for color (%s)',[s]); + for r := 1 to length(n) do + result := (result shl 4) or CharConv(n[r]); + // fill missing bits + case t of + 1: result:=result or (result shl 4) or (result shl 8) or (result shl 12); + 2: result:=result or (result shl 8); + 3: result:=result or (result shl 12); + end; + end; +begin + s := uppercase (s); + l := length(s) div 3; + result.red := (Convert(copy(s,1,l))); + result.green := (Convert(copy(s,l+1,l))); + result.blue := Convert(copy(s,l+l+1,l)); + result.alpha := AlphaOpaque; +end; + +function TFPReaderXPM.NameToColor(s : string) : TFPColor; +begin + s := lowercase (s); + if s = 'transparent' then + result := colTransparent + else if s = 'none' then + result := colTransparent + else if s = 'black' then + result := colBlack + else if s = 'blue' then + result := colBlue + else if s = 'green' then + result := colGreen + else if s = 'cyan' then + result := colCyan + else if s = 'red' then + result := colRed + else if s = 'magenta' then + result := colMagenta + else if s = 'yellow' then + result := colYellow + else if s = 'white' then + result := colWhite + else if s = 'gray' then + result := colGray + else if s = 'ltgray' then + result := colLtGray + else if s = 'dkblue' then + result := colDkBlue + else if s = 'dkgreen' then + result := colDkGreen + else if s = 'dkcyan' then + result := colDkCyan + else if s = 'dkred' then + result := colDkRed + else if s = 'dkmagenta' then + result := colDkMagenta + else if s = 'dkyellow' then + result := colDkYellow + else if s = 'maroon' then + result := colMaroon + else if s = 'ltgreen' then + result := colLtGreen + else if s = 'olive' then + result := colOlive + else if s = 'navy' then + result := colNavy + else if s = 'purple' then + result := colPurple + else if s = 'teal' then + result := colTeal + else if s = 'silver' then + result := colSilver + else if s = 'lime' then + result := colLime + else if s = 'fuchsia' then + result := colFuchsia + else if s = 'aqua' then + result := colAqua + else + result := colTransparent; +end; + +function TFPReaderXPM.DiminishWhiteSpace (s : string) : string; +var r : integer; + Doit : boolean; +begin + Doit := true; + result := ''; + for r := 1 to length(s) do + if pos(s[r],WhiteSpace)>0 then + begin + if DoIt then + result := result + ' '; + DoIt := false; + end + else + begin + DoIt := True; + result := result + s[r]; + end; +end; + +procedure TFPReaderXPM.InternalRead (Str:TStream; Img:TFPCustomImage); +var l : TStringList; + + procedure TakeInteger (var s : string; var i : integer); + var r : integer; + begin + r := pos (' ', s); + if r = 0 then + begin + i := StrToInt(s); + s := ''; + end + else + begin + i := StrToInt(copy(s,1,r-1)); + delete (s, 1, r); + end; + end; + + procedure ParseFirstLine; + var s : string; + begin + s := l[0]; + // diminish all whitespace to 1 blank + s := DiminishWhiteSpace (trim(s)); + Takeinteger (s, width); + Takeinteger (s, height); + Takeinteger (s, ncols); + Takeinteger (s, cpp); + if s <> '' then + begin + Takeinteger (s, xhot); + Takeinteger (s, yhot); + xpmext := (comparetext(s, 'XPMEXT') = 0); + if (s <> '') and not xpmext then + Raise Exception.Create ('Wrong word for XPMEXT tag'); + end; + end; + + procedure AddPalette (const code:string;const Acolor:TFPColor); + var r : integer; + begin + r := Palette.Add(code); + img.palette.Color[r] := Acolor; + end; + + procedure AddToPalette(s : string); + var code : string; + c : TFPColor; + p : integer; + begin + code := copy(s,1,cpp); + s := trim(diminishWhiteSpace (copy(s,cpp+1,maxint))); + // Search for c-key in the color values + if s[1] = 'c' then + delete (s, 1, 2) + else + begin + p := pos (' c ',s); + if p = 0 then + s := '' + else + delete (s, 1, p+2); + end; + // c color value is first word, remove the rest of the line + p := pos(' ', s); + if p > 0 then + delete (s, p, maxint); + // check if exists + if s = '' then + raise exception.Create ('Only c-key is used for colors'); + // convert #hexadecimal value to integer and place in palette + if s[1] = '#' then + c := HexToColor(copy(s,2,maxint)) + else + c := NameToColor(s); + AddPalette(code,c); + end; + + procedure ReadPalette; + var r : integer; + begin + Palette.Clear; + Img.Palette.Count := ncols; + for r := 1 to ncols do + AddToPalette (l[r]); + end; + + procedure ReadLine (const s : string; imgindex : integer); + var color, r, p : integer; + code : string; + begin + p := 1; + for r := 1 to width do + begin + code := copy(s, p, cpp); + inc(p,cpp); + for color := 0 to Palette.Count-1 do + { Can't use indexof, as compare must be case sensitive } + if code = Palette[color] then begin + img.pixels[r-1,imgindex] := color; + Break; + end; + end; + end; + + procedure ReadData; + var r : integer; + begin + for r := 1 to height do + ReadLine (l[ncols+r], r-1); + end; + +var p, r : integer; +begin + l := TStringList.Create; + try + l.LoadFromStream (Str); + for r := l.count-1 downto 0 do + begin + p := pos ('"', l[r]); + if p > 0 then + l[r] := copy(l[r], p+1, lastdelimiter('"',l[r])-p-1) + else + l.delete(r); + end; + ParseFirstLine; + Img.SetSize (width, height); + ReadPalette; + ReadData; + finally + l.Free; + end; +end; + +function TFPReaderXPM.InternalCheck (Str:TStream) : boolean; +var s : string[9]; + l : integer; +begin + try + l := str.Read (s[1],9); + s[0] := char(l); + if l <> 9 then + result := False + else + result := (s = '/* XPM */'); + except + result := false; + end; +end; + +initialization + ImageHandlers.RegisterImageReader ('XPM Format', 'xpm', TFPReaderXPM); +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/fpreadxwd.pas b/mseide-msegui/lib/common/fpccompatibility/fpreadxwd.pas new file mode 100644 index 0000000..d3b0308 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpreadxwd.pas @@ -0,0 +1,297 @@ +{*****************************************************************************} +{ + This file is part of the Free Pascal's "Free Components Library". + Copyright (c) 2003 by Mazen NEIFER of the Free Pascal development team + + BMP reader implementation. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +{*****************************************************************************} +{ 08/2005 by Giulio Bernardi: + - Added support for 16 and 15 bpp bitmaps. + - If we have bpp <= 8 make an indexed image instead of converting it to RGB + - Support for RLE4 and RLE8 decoding + - Support for top-down bitmaps +} + +{$mode objfpc} +{$h+} + +unit FPReadXWD; + +interface + +uses FPImage, classes, sysutils, xwdfile; + +type + TXWDColors = array of TXWDColor; + + { TFPReaderXWD } + + TFPReaderXWD = class (TFPCustomImageReader) + private + continue: boolean; // needed for onprogress event + percent: byte; + percentinterval : longword; + percentacc : longword; + Rect : TRect; + procedure SwapXWDFileHeader(var Header: TXWDFileHeader); + procedure SwapXWDColor(var Color: TXWDColor); + procedure WriteScanLine(Row: Integer; Img: TFPCustomImage); + protected + XWDFileHeader: TXWDFileHeader; // The header, as read from the file + WindowName: array of Char; + XWDColors: TXWDColors; + LineBuf: PByte; // Buffer for 1 line + + // required by TFPCustomImageReader + procedure InternalRead (Stream:TStream; Img:TFPCustomImage); override; + function InternalCheck (Stream:TStream) : boolean; override; + public + constructor Create; override; + destructor Destroy; override; + end; + +implementation + +//============================================================================== +// Endian utils +// +// Copied from LCLProc unit +//============================================================================== +{$R-} +function BEtoN(const AValue: DWord): DWord; +begin + {$IFDEF ENDIAN_BIG} + Result := AValue; + {$ELSE} + Result := (AValue shl 24) + or ((AValue and $0000FF00) shl 8) + or ((AValue and $00FF0000) shr 8) + or (AValue shr 24); + {$ENDIF} +end; +{$R+} + +constructor TFPReaderXWD.create; +begin + inherited create; + +end; + +destructor TFPReaderXWD.Destroy; +begin + If (LineBuf<>Nil) then + begin + FreeMem(LineBuf); + LineBuf:=Nil; + end; + + SetLength(WindowName, 0); + + SetLength(XWDColors, 0); + + inherited destroy; +end; + +procedure TFPReaderXWD.SwapXWDColor(var Color: TXWDColor); +begin + Color.pixel := BEtoN(Color.pixel); + + Color.red := swap(Color.red); + Color.green := swap(Color.green); + Color.blue := swap(Color.blue); +end; + +procedure TFPReaderXWD.SwapXWDFileHeader(var Header: TXWDFileHeader); +begin + Header.header_size := BEtoN(Header.header_size); + Header.file_version := BEtoN(Header.file_version); + Header.pixmap_format := BEtoN(Header.pixmap_format); + Header.pixmap_depth := BEtoN(Header.pixmap_depth); + Header.pixmap_width := BEtoN(Header.pixmap_width); + Header.pixmap_height := BEtoN(Header.pixmap_height); + Header.xoffset := BEtoN(Header.xoffset); + Header.byte_order := BEtoN(Header.byte_order); + Header.bitmap_unit := BEtoN(Header.bitmap_unit); + Header.bitmap_unit := BEtoN(Header.bitmap_bit_order); + Header.bitmap_pad := BEtoN(Header.bitmap_pad); + Header.bits_per_pixel := BEtoN(Header.bits_per_pixel); + Header.bytes_per_line := BEtoN(Header.bytes_per_line); + Header.visual_class := BEtoN(Header.visual_class); + Header.red_mask := BEtoN(Header.red_mask); + Header.green_mask := BEtoN(Header.green_mask); + Header.blue_mask := BEtoN(Header.blue_mask); + Header.bits_per_rgb := BEtoN(Header.bits_per_rgb); + Header.colormap_entries := BEtoN(Header.colormap_entries); + Header.ncolors := BEtoN(Header.ncolors); + Header.window_width := BEtoN(Header.window_width); + Header.window_height := BEtoN(Header.window_height); + Header.window_x := BEtoN(Header.window_x); + Header.window_y := BEtoN(Header.window_y); + Header.window_bdrwidth := BEtoN(Header.window_bdrwidth); +end; + +procedure TFPReaderXWD.WriteScanLine(Row : Integer; Img : TFPCustomImage); +var + Column: Integer; + buffer: Cardinal; + MyColor: TFPColor; +begin + MyColor.alpha := 0; + + case XWDFileHeader.bits_per_pixel of + 1 : + for Column:=0 to Img.Width-1 do + if ((LineBuf[Column div 8] shr (7-(Column and 7)) ) and 1) <> 0 then + img.Pixels[Column,Row]:=1 + else + img.Pixels[Column,Row]:=0; + 4 : + for Column:=0 to img.Width-1 do + img.Pixels[Column,Row]:=(LineBuf[Column div 2] shr (((Column+1) and 1)*4)) and $0f; + 8 : + for Column:=0 to img.Width-1 do + img.Pixels[Column,Row]:=LineBuf[Column]; + 16 : + for Column:=0 to img.Width-1 do + img.Pixels[Column,Row]:=LineBuf[Column]; + 24 : + for Column:=0 to img.Width-1 do + img.Pixels[Column,Row]:=LineBuf[Column]; + 32 : + for Column:=0 to img.Width-1 do + begin + Move(LineBuf[Column * 4], buffer, 4); +// WriteLn(IntToHex(buffer, 8)); + +{ buffer := buffer mod (256 * 256 * 256); + MyColor.red := Word((buffer div 256 * 256) * 256); + buffer := buffer mod (256 * 256); + MyColor.green := Word((buffer div 256) * 256); + buffer := buffer mod 256; + MyColor.blue := Word((buffer) * 256);} + + buffer := buffer mod (256 * 256 * 256); + MyColor.blue := Word((buffer div 256 * 256) * 256); + buffer := buffer mod (256 * 256); + MyColor.green := Word((buffer div 256) * 256); + buffer := buffer mod 256; + MyColor.red := Word((buffer) * 256); + + img.Colors[Column,Row] := MyColor; + end; + end; + +{ inc(percentacc,4); + if percentacc>=percentinterval then + begin + percent:=percent+(percentacc div percentinterval); + percentacc:=percentacc mod percentinterval; + Progress(psRunning,percent,false,Rect,'',continue); + end;} +end; + +procedure TFPReaderXWD.InternalRead(Stream: TStream; Img: TFPCustomImage); +var + Color: TFPColor; + Size, Row, i, Index: Integer; +begin + {**************************************************************************** + Initialization + ****************************************************************************} + Rect.Left:=0; Rect.Top:=0; Rect.Right:=0; Rect.Bottom:=0; + continue:=true; + Progress(psStarting,0,false,Rect,'',continue); + if not continue then exit; + + Img.UsePalette := True; +// Img.Palette.Clear; + Color.alpha := 0; + + {**************************************************************************** + The file is on big-endian format, so it needs to be swaped on little-endian CPUs + ****************************************************************************} + Stream.Position := 0; //* Causes error if removed, but should be + + Stream.Read(XWDFileHeader, SizeOf(TXWDFileHeader)); + +{$ifdef ENDIAN_LITTLE} + SwapXWDFileHeader(XWDFileHeader); +{$endif} + + {**************************************************************************** + Now reads the window name + ****************************************************************************} + Size := XWDFileHeader.header_size - SizeOf(TXWDFileHeader); + + // Avoids allocating too much space for the string + if Size > 256 then raise Exception.Create('Window name string too big. The file might be corrupted.'); + + SetLength(WindowName, Size); + + Stream.Read(WindowName[0], Size); + + {**************************************************************************** + Fills the palette + ****************************************************************************} + SetLength(XWDColors, XWDFileHeader.ncolors); + + Img.Palette.Count := 256; + + for i := 1 to XWDFileHeader.ncolors do + begin + Stream.Read(XWDColors[i - 1], SizeOf(TXWDColor)); + + {$ifdef ENDIAN_LITTLE} + SwapXWDColor(XWDColors[i - 1]); + {$endif} + + Color.red := XWDColors[i - 1].red; + Color.green := XWDColors[i - 1].green; + Color.blue := XWDColors[i - 1].blue; + + Index := XWDColors[i - 1].pixel mod 256; +// WriteLn(IntToHex(Index, 8)); + Img.Palette.Color[Index] := Color; + end; + + {**************************************************************************** + Reads the matrix of colors + ****************************************************************************} + Img.SetSize(XWDFileHeader.pixmap_width, XWDFileHeader.pixmap_height); + + GetMem(LineBuf, XWDFileHeader.bytes_per_line); + + for Row := 0 to Img.Height - 1 do + begin + Stream.Read(LineBuf[0], XWDFileHeader.bytes_per_line); + WriteScanLine(Row, Img); + if not continue then exit; + end; + + Progress(psEnding,100,false,Rect,'',continue); +end; + +function TFPReaderXWD.InternalCheck (Stream:TStream): boolean; +var + Header: TXWDFileHeader; +begin + stream.Read(Header, SizeOf(Header)); + {$IFDEF ENDIAN_LITTLE} + SwapXWDFileHeader(Header); + {$ENDIF} + Result := Header.file_version = XWD_FILE_VERSION; // Just check magic number +end; + +initialization + + ImageHandlers.RegisterImageReader ('XWD Format', 'xwd', TFPReaderXWD); + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/fptiffcmn.pas b/mseide-msegui/lib/common/fpccompatibility/fptiffcmn.pas new file mode 100644 index 0000000..a6dc308 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fptiffcmn.pas @@ -0,0 +1,420 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 2012 by the Free Pascal development team + + Common stuff for Tiff image format. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + ********************************************************************** +} +//modified 2013 by Martin Schreiber +unit fptiffcmn; + +{$ifdef FPC}{$mode objfpc}{$H+}{$endif} + +interface + +uses + classes, sysutils, fpimage,msetypes; + +type + TTiffRational = packed record + Numerator, Denominator: DWord; + end; + +const + TiffHandlerName = 'Tagged Image File Format'; + + TiffRational0: TTiffRational = (Numerator: 0; Denominator: 0); + TiffRational72: TTiffRational = (Numerator: 72; Denominator: 1); + + // TFPCustomImage.Extra properties used by TFPReaderTiff and TFPWriterTiff + TiffExtraPrefix = 'Tiff'; + TiffPhotoMetric = TiffExtraPrefix+'PhotoMetricInterpretation'; + TiffGrayBits = TiffExtraPrefix+'GrayBits'; // CMYK: key plate + TiffRedBits = TiffExtraPrefix+'RedBits'; // CMYK: cyan + TiffGreenBits = TiffExtraPrefix+'GreenBits'; // CMYK: magenta + TiffBlueBits = TiffExtraPrefix+'BlueBits'; // CMYK: yellow + TiffAlphaBits = TiffExtraPrefix+'AlphaBits'; + TiffArtist = TiffExtraPrefix+'Artist'; + TiffCopyright = TiffExtraPrefix+'Copyright'; + TiffDocumentName = TiffExtraPrefix+'DocumentName'; + TiffDateTime = TiffExtraPrefix+'DateTime'; + TiffImageDescription = TiffExtraPrefix+'ImageDescription'; + TiffHostComputer = TiffExtraPrefix+'HostComputer'; + TiffMake_ScannerManufacturer = TiffExtraPrefix+'Make_ScannerManufacturer'; + TiffModel_Scanner = TiffExtraPrefix+'Model_Scanner'; + TiffOrientation = TiffExtraPrefix+'Orientation'; + TiffResolutionUnit = TiffExtraPrefix+'ResolutionUnit'; + TiffSoftware = TiffExtraPrefix+'Software'; + TiffXResolution = TiffExtraPrefix+'XResolution'; + TiffYResolution = TiffExtraPrefix+'YResolution'; + TiffPageNumber = TiffExtraPrefix+'PageNumber'; // starting at 0 + TiffPageCount = TiffExtraPrefix+'PageCount'; // if >0 the image is a page + TiffPageName = TiffExtraPrefix+'PageName'; + TiffIsThumbnail = TiffExtraPrefix+'IsThumbnail'; + TiffIsMask = TiffExtraPrefix+'IsMask'; + TiffTileWidth = TiffExtraPrefix+'TileWidth'; + TiffTileLength = TiffExtraPrefix+'TileLength'; + TiffCompression = TiffExtraPrefix+'Compression'; // number + + TiffCompressionNone = 1; { No Compression, but pack data into bytes as tightly as possible, + leaving no unused bits (except at the end of a row). The component + values are stored as an array of type BYTE. Each scan line (row) + is padded to the next BYTE boundary. } + TiffCompressionCCITTRLE = 2; { CCITT Group 3 1-Dimensional Modified Huffman run length encoding. } + TiffCompressionCCITTFAX3 = 3; { CCITT Group 3 fax encoding } + TiffCompressionCCITTFAX4 = 4; { CCITT Group 4 fax encoding } + TiffCompressionLZW = 5; { LZW } + TiffCompressionOldJPEG = 6; { JPEG old style} + TiffCompressionJPEG = 7; { JPEG new style } + TiffCompressionDeflateAdobe = 8; { Deflate Adobe style } + TiffCompressionJBIGBW = 9; { RFC2301 JBIG black/white } + TiffCompressionJBIGCol = 10; { RFC2301 JBIG color } + TiffCompressionNeXT = 32766; { Next } + TiffCompressionCCITTRLEW = 32771; { CCITTRLEW } + TiffCompressionPackBits = 32773; { PackBits Compression, a simple byte-oriented run length scheme. + See the PackBits section for details. Data Compression applies + only to raster image data. All other TIFF fields are unaffected. } + TiffCompressionThunderScan = 32809; { THUNDERSCAN } + TiffCompressionIT8CTPAD = 32895; { IT8CTPAD } + TiffCompressionIT8LW = 32896; { IT8LW } + TiffCompressionIT8MP = 32897; { IT8MP } + TiffCompressionIT8BL = 32898; { IT8BL } + TiffCompressionPixarFilm = 32908; { PIXARFILM } + TiffCompressionPixarLog = 32909; { PIXARLOG } + TiffCompressionDeflateZLib = 32946; { DeflatePKZip } + TiffCompressionDCS = 32947; { DCS } + TiffCompressionJBIG = 34661; { JBIG } + TiffCompressionSGILog = 34676; { SGILOG } + TiffCompressionSGILog24 = 34677; { SGILOG24 } + TiffCompressionJPEG2000 = 34712; { JP2000 } +type + TTiffChunkType = ( + tctStrip, + tctTile + ); + + { TTiffIFD - Image File Directory } + + TTiffIFD = class + public + IFDStart: DWord; // tiff position + IFDNext: DWord; // tiff position + Artist: String; + BitsPerSample: DWord; // tiff position of entry + BitsPerSampleArray: array of Word; + CellLength: DWord; + CellWidth: DWord; + ColorMap: DWord;// tiff position of entry + Compression: DWord; + Predictor: Word; + Copyright: string; + DateAndTime: string; + DocumentName: string; + ExtraSamples: DWord;// tiff position of entry + FillOrder: DWord; + HostComputer: string; + ImageDescription: string; + ImageHeight: DWord; + ImageIsMask: Boolean; + ImageIsPage: Boolean; + ImageIsThumbNail: Boolean; + ImageWidth: DWord; + Make_ScannerManufacturer: string; + Model_Scanner: string; + Orientation: DWord; + PageNumber: word; // the page number starting at 0, the total number of pages is PageCount + PageCount: word; // see PageNumber + PageName: string; + PhotoMetricInterpretation: DWord; + PlanarConfiguration: DWord; + ResolutionUnit: DWord; + RowsPerStrip: DWord; + SamplesPerPixel: DWord; + Software: string; + StripByteCounts: DWord;// tiff position of entry + StripOffsets: DWord; // tiff position of entry + TileWidth: DWord; + TileLength: DWord; // = Height + TileOffsets: DWord; // tiff position of entry + TileByteCounts: DWord; // tiff position of entry + Tresholding: DWord; + XResolution: TTiffRational; + YResolution: TTiffRational; + // image + Img: TFPCustomImage; + FreeImg: boolean; + RedBits: word; + GreenBits: word; + BlueBits: word; + GrayBits: word; + AlphaBits: word; + BytesPerPixel: Word; + procedure Clear; + procedure Assign(IFD: TTiffIFD); + procedure ReadFPImgExtras(Src: TFPCustomImage); + function ImageLength: DWord; {$ifdef FPC}inline;{$endif} + destructor Destroy; override; + end; + +function TiffRationalToStr(const r: TTiffRational): string; +function StrToTiffRationalDef(const s: string; const Def: TTiffRational): TTiffRational; +procedure ClearTiffExtras(Img: TFPCustomImage); +procedure CopyTiffExtras(SrcImg, DestImg: TFPCustomImage); +procedure WriteTiffExtras(Msg: string; Img: TFPCustomImage); +function TiffCompressionName(c: Word): string; + +implementation + +function TiffRationalToStr(const r: TTiffRational): string; +begin + Result:=IntToStr(r.Numerator)+'/'+IntToStr(r.Denominator); +end; + +function StrToTiffRationalDef(const s: string; const Def: TTiffRational + ): TTiffRational; +var + p: LongInt; +begin + Result:=Def; + p:=System.Pos('/',s); + if p<1 then exit; + Result.Numerator:=StrToIntDef(copy(s,1,p-1),TiffRational0.Numerator); + Result.Denominator:=StrToIntDef(copy(s,p+1,length(s)),TiffRational0.Denominator); +end; + +procedure ClearTiffExtras(Img: TFPCustomImage); +var + i: Integer; +begin + for i:=Img.ExtraCount-1 downto 0 do + if SysUtils.CompareText(copy(Img.ExtraKey[i],1,4),'Tiff')=0 then + Img.RemoveExtra(Img.ExtraKey[i]); +end; + +procedure CopyTiffExtras(SrcImg, DestImg: TFPCustomImage); +var + i: Integer; +begin + ClearTiffExtras(DestImg); + for i:=SrcImg.ExtraCount-1 downto 0 do + if SysUtils.CompareText(copy(SrcImg.ExtraKey[i],1,4),'Tiff')=0 then + DestImg.Extra[SrcImg.ExtraKey[i]]:=SrcImg.ExtraValue[i]; +end; + +procedure WriteTiffExtras(Msg: string; Img: TFPCustomImage); +var + i: Integer; +begin + writeln('WriteTiffExtras ',Msg); + for i:=0 to Img.ExtraCount-1 do + //if SysUtils.CompareText(copy(Img.ExtraKey[i],1,4),'Tiff')=0 then + writeln(' ',i,' ',Img.ExtraKey[i],'=',Img.ExtraValue[i]); +end; + +function TiffCompressionName(c: Word): string; +begin + case c of + 1: Result:='no compression'; + 2: Result:='CCITT Group 3 1-Dimensional Modified Huffman run length encoding'; + 3: Result:='CCITT Group 3 fax encoding'; + 4: Result:='CCITT Group 4 fax encoding'; + 5: Result:='LZW'; + 6: Result:='JPEG old style'; + 7: Result:='JPEG'; + 8: Result:='Deflate Adobe style'; + 9: Result:='RFC2301 JBIG white/black'; + 10: Result:='RFC2301 JBIG color'; + 32766: Result:='NeXT'; + 32771: Result:='CCITTRLEW'; + 32773: Result:='PackBits'; + 32809: Result:='THUNDERSCAN'; + 32895: Result:='IT8CTPAD'; + 32896: Result:='IT8LW'; + 32897: Result:='IT8MP'; + 32898: Result:='IT8BL'; + 32908: Result:='PIXARFILM'; + 32909: Result:='PIXARLOG'; + 32946: Result:='Deflate ZLib'; + 32947: Result:='DCS'; + 34661: Result:='JBIG'; + 34676: Result:='SGILOG'; + 34677: Result:='SGILOG24'; + 34712: Result:='JP2000'; + else Result:='unknown('+IntToStr(c)+')'; + end; +end; + +{ TTiffIFD } + +procedure TTiffIFD.Clear; +begin + IFDStart:=0; + IFDNext:=0; + PhotoMetricInterpretation:=High(PhotoMetricInterpretation); + PlanarConfiguration:=0; + Compression:=TiffCompressionNone; + Predictor:=1; + ImageHeight:=0; + ImageWidth:=0; + ImageIsThumbNail:=false; + ImageIsPage:=false; + ImageIsMask:=false; + BitsPerSample:=0; + SetLength(BitsPerSampleArray,0); + ResolutionUnit:=0; + XResolution:=TiffRational0; + YResolution:=TiffRational0; + RowsPerStrip:=0; + StripOffsets:=0; + StripByteCounts:=0; + SamplesPerPixel:=0; + Artist:=''; + HostComputer:=''; + ImageDescription:=''; + Make_ScannerManufacturer:=''; + Model_Scanner:=''; + Copyright:=''; + DateAndTime:=''; + Software:=''; + CellWidth:=0; + CellLength:=0; + FillOrder:=0; + Orientation:=0; + PageNumber:=0; + PageCount:=0; + PageName:=''; + + // tiles + TileWidth:=0; + TileLength:=0; + TileOffsets:=0; + TileByteCounts:=0; + + Tresholding:=0; + + RedBits:=0; + GreenBits:=0; + BlueBits:=0; + GrayBits:=0; + AlphaBits:=0; + BytesPerPixel:=0; + + if FreeImg then begin + FreeImg:=false; + FreeAndNil(Img); + end; +end; + +procedure TTiffIFD.Assign(IFD: TTiffIFD); +begin + IFDStart:=IFD.IFDStart; + IFDNext:=IFD.IFDNext; + + PhotoMetricInterpretation:=IFD.PhotoMetricInterpretation; + PlanarConfiguration:=IFD.PlanarConfiguration; + Compression:=IFD.Compression; + Predictor:=IFD.Predictor; + ImageHeight:=IFD.ImageHeight; + ImageWidth:=IFD.ImageWidth; + ImageIsThumbNail:=IFD.ImageIsThumbNail; + ImageIsPage:=IFD.ImageIsPage; + ImageIsMask:=IFD.ImageIsMask; + BitsPerSample:=IFD.BitsPerSample; + BitsPerSampleArray:=IFD.BitsPerSampleArray; + ResolutionUnit:=IFD.ResolutionUnit; + XResolution:=IFD.XResolution; + YResolution:=IFD.YResolution; + RowsPerStrip:=IFD.RowsPerStrip; + StripOffsets:=IFD.StripOffsets; + StripByteCounts:=IFD.StripByteCounts; + SamplesPerPixel:=IFD.SamplesPerPixel; + Artist:=IFD.Artist; + HostComputer:=IFD.HostComputer; + ImageDescription:=IFD.ImageDescription; + Make_ScannerManufacturer:=IFD.Make_ScannerManufacturer; + Model_Scanner:=IFD.Model_Scanner; + Copyright:=IFD.Copyright; + DateAndTime:=IFD.DateAndTime; + Software:=IFD.Software; + CellWidth:=IFD.CellWidth; + CellLength:=IFD.CellLength; + FillOrder:=IFD.FillOrder; + Orientation:=IFD.Orientation; + PageNumber:=IFD.PageNumber; + PageCount:=IFD.PageCount; + PageName:=IFD.PageName; + + // tiles + TileWidth:=IFD.TileWidth; + TileLength:=IFD.TileLength; + TileOffsets:=IFD.TileOffsets; + TileByteCounts:=IFD.TileByteCounts; + + Tresholding:=IFD.Tresholding; + + RedBits:=IFD.RedBits; + GreenBits:=IFD.GreenBits; + BlueBits:=IFD.BlueBits; + GrayBits:=IFD.GrayBits; + AlphaBits:=IFD.AlphaBits; + if (Img<>nil) and (IFD.Img<>nil) then + Img.Assign(IFD.Img); +end; + +procedure TTiffIFD.ReadFPImgExtras(Src: TFPCustomImage); +begin + Clear; + PhotoMetricInterpretation:=2; + if Src.Extra[TiffPhotoMetric]<>'' then + PhotoMetricInterpretation:= + StrToInt64Def(Src.Extra[TiffPhotoMetric],High(PhotoMetricInterpretation)); + Artist:=Src.Extra[TiffArtist]; + Copyright:=Src.Extra[TiffCopyright]; + DocumentName:=Src.Extra[TiffDocumentName]; + DateAndTime:=Src.Extra[TiffDateTime]; + HostComputer:=Src.Extra[TiffHostComputer]; + Make_ScannerManufacturer:=Src.Extra[TiffMake_ScannerManufacturer]; + Model_Scanner:=Src.Extra[TiffModel_Scanner]; + ImageDescription:=Src.Extra[TiffImageDescription]; + Software:=Src.Extra[TiffSoftware]; + Orientation:=StrToIntDef(Src.Extra[TiffOrientation],1); + if not (Orientation in [1..8]) then + Orientation:=1; + ResolutionUnit:=StrToIntDef(Src.Extra[TiffResolutionUnit],2); + if not (ResolutionUnit in [1..3]) then + ResolutionUnit:=2; + XResolution:=StrToTiffRationalDef(Src.Extra[TiffXResolution],TiffRational72); + YResolution:=StrToTiffRationalDef(Src.Extra[TiffYResolution],TiffRational72); + PageNumber:=StrToIntDef(Src.Extra[TiffPageNumber],0); + PageCount:=StrToIntDef(Src.Extra[TiffPageCount],0); + PageName:=Src.Extra[TiffPageName]; + ImageIsPage:=PageCount>0; + ImageIsThumbNail:=Src.Extra[TiffIsThumbnail]<>''; + ImageIsMask:=Src.Extra[TiffIsMask]<>''; + TileWidth:=StrToIntDef(Src.Extra[TiffTileWidth],0); + TileLength:=StrToIntDef(Src.Extra[TiffTileLength],0); + Compression:=StrToIntDef(Src.Extra[TiffCompression],TiffCompressionNone); +end; + +function TTiffIFD.ImageLength: DWord; +begin + Result:=ImageHeight; +end; + +destructor TTiffIFD.Destroy; +begin + if FreeImg then + FreeAndNil(Img); + inherited Destroy; +end; + +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/fpwritebmp.pas b/mseide-msegui/lib/common/fpccompatibility/fpwritebmp.pas new file mode 100644 index 0000000..d9eca54 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpwritebmp.pas @@ -0,0 +1,732 @@ +{*****************************************************************************} +{ + This file is part of the Free Pascal's "Free Components Library". + Copyright (c) 2003 by Mazen NEIFER of the Free Pascal development team + + BMP writer implementation. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +{*****************************************************************************} +{ 08/2005 by Giulio Bernardi: + - Removed FBytesPerPixel, BytesPerPixel property is now deprecated, use BitsPerPixel instead. + - Rewritten a large part of the file, so we can handle all bmp color depths + - Support for RLE4 and RLE8 encoding +} + +{$mode objfpc}{$h+} +unit FPWriteBMP; + +interface + +uses FPImage, classes, sysutils, BMPComn; + +type + + TFPWriterBMP = class (TFPCustomImageWriter) + private + StartPosition : int64; { save start of bitmap in the stream, if we must go back and fix something } + FBpp : byte; + FRLECompress : boolean; + BFH : TBitMapFileHeader; + BFI : TBitMapInfoHeader; + Colinfo : array of TColorRGBA; + procedure SetColorSize (AValue : Byte); + function GetColorSize : byte; + procedure SetBpp (const abpp : byte); + procedure FillColorMap(Img : TFPCustomImage); + procedure Setup16bpp; + function PackWord555(const col : TFPColor) : word; + function PackWord565(const col : TFPColor) : word; + function Pack4bpp(const img : TFPCustomImage; var Col : integer; const Row : integer) : byte; + function Pack1bpp(const img : TFPCustomImage; var Col : integer; const Row : integer) : byte; + procedure CompressScanLineRLE8(ALine : pbyte; const Row, Width : Integer; Stream : TStream); + procedure CompressScanLineRLE4(ALine : pbyte; const Row, Width : Integer; Stream : TStream); + protected + function SaveHeader(Stream:TStream; Img: TFPCustomImage):boolean; virtual; + procedure InternalWrite (Stream:TStream; Img: TFPCustomImage); override; + public + constructor Create; override; + property BitsPerPixel : byte read FBpp write SetBpp; + property RLECompress : boolean read FRleCompress write FRleCompress; + Property BytesPerPixel : Byte Read GetColorSize Write SetColorSize; deprecated; + end; + + +implementation + +Function FPColorToRGB(Const Color : TFPColor) : TColorRGB; + +begin + With Result,Color do + begin + R:=(Red and $FF00) shr 8; + G:=(Green and $FF00) shr 8; + B:=(Blue and $FF00) shr 8; + end; +end; + +Function FPColorToRGBA(Const Color : TFPColor) : TColorRGBA; + +begin + With Result,Color do + begin + R:=(Red and $FF00) shr 8; + G:=(Green and $FF00) shr 8; + B:=(Blue and $FF00) shr 8; + A:=(Alpha and $FF00) shr 8; + end; +end; + +constructor TFPWriterBMP.create; +begin + inherited create; + FBpp:=24; + FRleCompress:=false; +end; + +{ Only for compatibility, BytesPerPixel should be removed } +{ ******************************************************* } +procedure TFPWriterBMP.SetColorSize (AValue : byte); +begin + SetBpp(AValue*8); +end; + +function TFPWriterBMP.GetColorSize : byte; +begin + if FBpp<>15 then Result:=FBpp div 8 + else Result:=2; +end; +{ ******************************************************* } + +procedure TFPWriterBMP.SetBpp (const abpp : byte); +begin + if not (abpp in [1,4,8,15,16,24,32]) then + raise FPImageException.Create('Invalid color depth'); + FBpp:=abpp; +end; + +procedure TFPWriterBMP.FillColorMap(Img : TFPCustomImage); +var BadPalette : boolean; + i : integer; +begin + BadPalette:=false; + if not Img.UsePalette then BadPalette:=true + else if Img.Palette.Count>(1 shl FBpp) then BadPalette:=true; + if BadPalette then + raise FPImageException.Create('Image palette is too big or absent'); + setlength(ColInfo,Img.Palette.Count); + BFI.ClrUsed:=Img.Palette.Count; + for i:=0 to BFI.ClrUsed-1 do + begin + ColInfo[i]:=FPColorToRGBA(Img.Palette.Color[i]); + ColInfo[i].A:=0; + end; +end; + +{ True 16 bit color is 5 bits red, 6 bits green and 5 bits blue. + Compression must be set to BI_BITFIELDS and we must specify masks for red, green and blue. + 16 bit without compression and masks is 5 bits per channel, so it's 15 bit even if in the header we + must write 16. + It's possible to provide custom masks but this is not compatible with windows9x, so we use 555 for 15 bit + and 565 for 16 bit. + Masks are longwords stored in the palette instead of palette entries (which are 4 bytes long too, with + components stored in following order: B G R A. Since we must write a low-endian longword, B is LSB and A + is the MSB). + We must write first red mask, then green and then blue. + + This sounds terribly confusing, if you don't understand take a look at + http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_1rw2.asp + } +procedure TFPWriterBMP.Setup16bpp; +var col : TColorRGBA; +begin + BFI.Compression:=BI_BITFIELDS; + setlength(ColInfo,3); + { A R G B + r := $0000F800 + g := $000007E0 + b := $0000001F + } + col.A:=0; Col.R:=0; { These are 0 for all the three masks} + { Red Mask } + Col.G:=$F8; Col.B:=0; + ColInfo[0]:=Col; + { Green Mask } + Col.G:=$07; Col.B:=$E0; + ColInfo[1]:=Col; + { Blue Mask } + Col.G:=$00; Col.B:=$1F; + ColInfo[2]:=Col; +end; + +{ 16 bit bpp with 555 packing (that is, 15 bit color) + This is bit dislocation: + 0RRR RRGG GGGB BBBB } + +function TFPWriterBMP.PackWord555(const col : TFPColor) : word; +var tmpcol : TColorRGB; + tmpr, tmpg, tmpb : word; +begin + tmpcol:=FPColorToRGB(col); + tmpb:=tmpcol.b shr 3; + tmpg:=tmpcol.g and $F8; tmpg:= tmpg shl 2; + tmpr:=tmpcol.r and $F8; tmpr:= tmpr shl 7; + tmpb:= tmpr or tmpg or tmpb; + {$IFDEF ENDIAN_BIG} + tmpb:=swap(tmpb); + {$ENDIF} + Result:=tmpb; +end; + +{ 16 bit bpp with 565 packing ) + This is bit dislocation: + RRRR RGGG GGGB BBBB } + +function TFPWriterBMP.PackWord565(const col : TFPColor) : word; +var tmpcol : TColorRGB; + tmpr, tmpg, tmpb : word; +begin + tmpcol:=FPColorToRGB(col); + tmpb:=tmpcol.b shr 3; + tmpg:=tmpcol.g and $FC; tmpg:= tmpg shl 3; + tmpr:=tmpcol.r and $F8; tmpr:= tmpr shl 8; + tmpb:= tmpr or tmpg or tmpb; + {$IFDEF ENDIAN_BIG} + tmpb:=swap(tmpb); + {$ENDIF} + Result:=tmpb; +end; + +{ First pixel in the most significant nibble, second one in LSN. If we are at the end of the line, + pad with zero } +function TFPWriterBMP.Pack4bpp(const img : TFPCustomImage; var Col : integer; const Row : integer) : byte; +var b : byte; +begin + b:=(img.Pixels[Col,Row] and $F) shl 4; + if Col=0)) do + begin + if img.Pixels[Col,Row]<>0 then { set this bit } + b:=b+(1 shl sh); + dec(sh); + inc(Col); + end; + Result:=b; +end; + +function TFPWriterBMP.SaveHeader(Stream:TStream; Img : TFPCustomImage):boolean; +begin + Result:=False; + with BFI do + begin + Size:=sizeof(TBitMapInfoHeader); + Width:=Img.Width; + Height:=Img.Height; + Planes:=1; + if FBpp=15 then BitCount:=16 + else BitCount:=FBpp; + XPelsPerMeter:=100; + YPelsPerMeter:=100; + ClrImportant:=0; + end; + with BFH do + begin + bfType:=BMmagic;//'BM' + bfOffset:=sizeof(TBitMapFileHeader)+sizeof(TBitMapInfoHeader)+length(ColInfo)*4; + bfReserved:=0; + bfSize:=bfOffset+BFI.SizeImage; + end; + {$IFDEF ENDIAN_BIG} + SwapBMPFileHeader(BFH); + SwapBMPInfoHeader(BFI); + {$ENDIF} + StartPosition:=Stream.Position; + Stream.Write(bfh,sizeof(TBitMapFileHeader)); + Stream.Write(bfi,sizeof(TBitMapInfoHeader)); + {$IFDEF ENDIAN_BIG} + SwapBMPFileHeader(BFH); + SwapBMPInfoHeader(BFI); + {$ENDIF} + Result:=true; +end; + +{ This code is rather ugly and difficult to read, but compresses better than gimp. + Brief explanation: + A repetition is good if it's made of 3 elements at least: we have 2 bytes instead of 1. Let's call this a + "repetition" or "true repetition". + So we start finding the first repetition from current position. + Once found, we must decide how to handle elements between current position (i) and the repetition position (j) + if j-i = 0 we are on the repetition, so we encode it + if j-i = 1 there is only one pixel. We can't do anything but encode it as a repetition of 1 element. + if j-i = 2 we have two pixels. These can be a couple (a repetition of 2 elements) or 2 singles + (2 repetitions of 1 element) + if j-i > 2 we have two choices. In fact, we must consider that absolute mode is 2 bytes + length of chunk. + A repetition is always 2 bytes, so for 1 element we leak 1 byte, while for 2 elements we don't leak + any byte. + So if we have at most 1 single this means that everything else is made up of couples: it's best to + use repetitions so that we leak 0 to 1 byte. + If we have 2 singles or more it's better to use absolute mode, since we leak 2 bytes always, + without regard to the size of chunk. } + +procedure TFPWriterBMP.CompressScanLineRLE8(ALine : pbyte; const Row, Width : Integer; Stream : TStream); +var i, j, k, couples, singles : integer; + prev,tmp : byte; +begin + i:=0; + while (i=3 } + prev:=Aline[i]; + j:=i+1; + while ((jprev then break; + inc(j); + end; + tmp:=j-i; + Stream.Write(tmp,1); + Stream.Write(prev,1); + end; + 1 : begin { single value: we write a repetition of 1 } + tmp:=1; + Stream.Write(tmp,1); + Stream.Write(Aline[i],1); + end; + 2 : begin + if couples=1 then { a couple: we write a repetition of 2 } + begin + tmp:=2; + Stream.Write(tmp,1); + Stream.Write(Aline[i],1); + end + else { two singles: we write two repetitions of 1 each } + begin + tmp:=1; + Stream.Write(tmp,1); + Stream.Write(Aline[i],1); + Stream.Write(tmp,1); + Stream.Write(Aline[i+1],1); + end; + end; + else { here we have two choices } + begin + if singles>1 then { it's cheaper to use absolute mode } + begin + tmp:=0; Stream.Write(tmp,1); { escape } + tmp:=j-i; Stream.Write(tmp,1); { number of pixels in absolute mode } + Stream.Write(Aline[i],j-i); { write these pixels... } + if ((tmp mod 2)<>0) then { we must end on a 2-byte boundary } + begin + tmp:=0; Stream.Write(tmp,1); { so pad with an additional zero } + end; + end + else { they're nearly all couples, don't use absolute mode } + begin + k:=i; + while (k E + 0316 => 161. + A repetition is good if it's made of five elements at least (2 bytes instead of 3). + In rle4 we consider "single" either a single nibble or 2 (a byte), while a couple is a repetition of 3 or 4 + elements. } + +procedure TFPWriterBMP.CompressScanLineRLE4(ALine : pbyte; const Row, Width : Integer; Stream : TStream); +var i, j, k, couples, singles, lastsingle : integer; + prev1, prev2, prev : word; + tmp : byte; + nibline : pbyte; { temporary array of nibbles } + even : boolean; +begin + getmem(nibline,width); + try + k:=(Width div 2) + (Width mod 2); + i:=0; + while (i(j-1) then + begin + inc(singles); { this is a single if next isn't a couple } + lastsingle:=j; + end; + prev:=nibline[j]; + end; + prev1:=prev2; + prev2:=prev; + even:=not even; + inc(j); + end; + if j>Width then j:=Width; { if j was Width-1 loop was skipped and j is Width+1, so we fix it } + + { ok, now that we know more about byte disposition we write data } + case (j-i) of + 0 : begin { there is a repetition with count>=5 } + even:=true; + prev1:=nibline[i]; + prev2:=nibline[i+1]; + j:=i+2; + while ((jprev1 then break; + if not even then if nibline[j]<>prev2 then break; + even:=not even; + inc(j); + end; + tmp:=j-i; + Stream.Write(tmp,1); + prev:=(prev1 shl 4) + (prev2 and $F); + tmp:=prev; + Stream.Write(tmp,1); + end; + 1 : begin { single value: we write a repetition of 1 } + tmp:=1; + Stream.Write(tmp,1); + tmp:=nibline[i] shl 4; + Stream.Write(tmp,1); + end; + 2 : begin { 2 singles in the same byte: we write a repetition of 2 } + tmp:=2; + Stream.Write(tmp,1); + tmp:=(nibline[i] shl 4) + (nibline[i+1] and $F); + Stream.Write(tmp,1); + end; + 3 : begin + if couples=1 then { a couple: we write a repetition of 3 } + begin + tmp:=3; + Stream.Write(tmp,1); + tmp:=(nibline[i] shl 4) + (nibline[i+1] and $F); + Stream.Write(tmp,1); + end + else + begin { 2 singles, 2 repetitions of 2 and 1 respectively } + tmp:=2; + Stream.Write(tmp,1); + tmp:=(nibline[i] shl 4) + (nibline[i+1] and $F); + Stream.Write(tmp,1); + tmp:=1; + Stream.Write(tmp,1); + tmp:=nibline[i+2] shl 4; + Stream.Write(tmp,1); + end; + end; + 4 : begin + if singles=0 then { a couple: we write a repetition of 4 } + begin + tmp:=4; + Stream.Write(tmp,1); + tmp:=(nibline[i] shl 4) + (nibline[i+1] and $F); + Stream.Write(tmp,1); + end + else + begin { 2 singles, 2 repetitions of 2 each } + tmp:=2; + Stream.Write(tmp,1); + tmp:=(nibline[i] shl 4) + (nibline[i+1] and $F); + Stream.Write(tmp,1); + tmp:=2; + Stream.Write(tmp,1); + tmp:=(nibline[i+2] shl 4) + (nibline[i+3] and $F); + Stream.Write(tmp,1); + end; + end; + else { here we have two choices } + begin + if singles>1 then { it's cheaper to use absolute mode } + begin + tmp:=0; Stream.Write(tmp,1); { escape } + tmp:=j-i; Stream.Write(tmp,1); { number of pixels in absolute mode } + k:=i; + while (k0 then { we must end on a 2-byte boundary } + begin + tmp:=0; Stream.Write(tmp,1); { so pad with an additional zero } + end; + end + else { they're nearly all couples, don't use absolute mode } + begin + k:=i; + while (k=j) then tmp:=1 + else if ((k+31 then tmp:=tmp+(nibline[k+1] and $F); + Stream.Write(tmp,1); + inc(k,prev); + end; + end; + end; + end; + i:=j; + end; + tmp:=0; Stream.Write(tmp,1); { escape } + if Row=0 then { last line, end of file } + tmp:=1; + Stream.Write(tmp,1); + finally + FreeMem(nibline); + end; +end; + +procedure TFPWriterBMP.InternalWrite (Stream:TStream; Img:TFPCustomImage); +var + Row,Col,RowSize:Integer; + PadCount : byte; + aLine: PByte; + i : Integer; + tmppos : int64; + continue : boolean; + percent : byte; + percentinterval : longword; + percentacc : longword; + Rect : TRect; +begin + Rect.Left:=0; Rect.Top:=0; Rect.Right:=0; Rect.Bottom:=0; + continue:=true; + percent:=0; + percentinterval:=(Img.Height*4) div 100; + if percentinterval=0 then percentinterval:=$FFFFFFFF; + percentacc:=0; + Progress(psStarting,0,false,Rect,'',continue); + if not continue then exit; + if (FRLECompress and (not (FBpp in [4,8]))) then + raise FPImageException.Create('Can''t use RLE compression with '+IntToStr(FBpp)+' bits per pixel'); + if FRLECompress and (FBpp=4) then BFI.Compression:=BI_RLE4 + else if FRLECompress and (FBpp=8) then BFI.Compression:=BI_RLE8 + else BFI.Compression:=BI_RGB; + BFI.ClrUsed:=0; + try + if FBpp<=8 then FillColorMap(Img); { sets colormap and ClrUsed} + if FBpp=16 then Setup16bpp; { sets colormap with masks and Compression } + RowSize:=0; { just to keep the compiler quiet. } + case FBpp of + 1 : begin + RowSize:=Img.Width div 8; + if (Img.Width mod 8)<>0 then + inc(RowSize); + end; + 4 : begin + RowSize:=Img.Width div 2; + if (Img.Width mod 2)<>0 then + inc(RowSize); + end; + 8 : RowSize:=Img.Width; + 15 : RowSize:=Img.Width*2; + 16 : RowSize:=Img.Width*2; + 24 : RowSize:=Img.Width*3; + 32 : RowSize:=Img.Width*4; + end; + PadCount:=(4-(RowSize mod 4)) mod 4; { every row must end on 4 byte boundary } + inc(RowSize,PadCount); + BFI.SizeImage:=RowSize*Img.Height; + + SaveHeader(Stream,Img); { write the headers } + for i:=0 to length(ColInfo)-1 do { write the palette (or the masks in 16bpp case) } + Stream.Write(ColInfo[i],sizeof(TColorRGBA)); + + GetMem(aLine,RowSize); + try + for Row:=Img.Height-1 downto 0 do + begin + i:=0; Col:=0; + case FBpp of + 1 : while(Col=percentinterval then + begin + percent:=percent+(percentacc div percentinterval); + percentacc:=percentacc mod percentinterval; + Progress(psRunning,percent,false,Rect,'',continue); + if not continue then exit; + end; + end; + { If image is compressed we must fix the headers since we now know the size of the image } + if BFI.Compression in [BI_RLE4,BI_RLE8] then + begin + tmppos:=Stream.Position-StartPosition-BFH.bfOffset; + BFI.SizeImage:=tmppos; { set size of the image } + tmppos:=Stream.Position; { remember where we are } + Stream.Position:=StartPosition; { rewind to the beginning } + SaveHeader(Stream,Img); { rewrite headers (this will update BFH.Size too) } + Stream.Position:=tmppos; { restore our position } + end; + Progress(psEnding,100,false,Rect,'',continue); + finally + FreeMem(aLine); + end; + finally + setlength(ColInfo,0); + end; +end; + +initialization + ImageHandlers.RegisterImageWriter ('BMP Format', 'bmp', TFPWriterBMP); +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/fpwritebmp.pp b/mseide-msegui/lib/common/fpccompatibility/fpwritebmp.pp new file mode 100644 index 0000000..11ee57c --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpwritebmp.pp @@ -0,0 +1,734 @@ +{*****************************************************************************} +{ + This file is part of the Free Pascal's "Free Components Library". + Copyright (c) 2003 by Mazen NEIFER of the Free Pascal development team + + BMP writer implementation. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +{*****************************************************************************} +{ 08/2005 by Giulio Bernardi: + - Removed FBytesPerPixel, BytesPerPixel property is now deprecated, use BitsPerPixel instead. + - Rewritten a large part of the file, so we can handle all bmp color depths + - Support for RLE4 and RLE8 encoding +} +//modified 2013 by Martin Schreiber + +{$mode objfpc}{$h+} +unit fpwritebmp; + +interface + +uses fpimage, classes, mclasses, sysutils, bmpcomn; + +type + + TFPWriterBMP = class (TFPCustomImageWriter) + private + StartPosition : int64; { save start of bitmap in the stream, if we must go back and fix something } + FBpp : byte; + FRLECompress : boolean; + BFH : TBitMapFileHeader; + BFI : TBitMapInfoHeader; + Colinfo : array of TColorRGBA; + procedure SetColorSize (AValue : Byte); + function GetColorSize : byte; + procedure SetBpp (const abpp : byte); + procedure FillColorMap(Img : TFPCustomImage); + procedure Setup16bpp; + function PackWord555(const col : TFPColor) : word; + function PackWord565(const col : TFPColor) : word; + function Pack4bpp(const img : TFPCustomImage; var Col : integer; const Row : integer) : byte; + function Pack1bpp(const img : TFPCustomImage; var Col : integer; const Row : integer) : byte; + procedure CompressScanLineRLE8(ALine : pbyte; const Row, Width : Integer; Stream : TStream); + procedure CompressScanLineRLE4(ALine : pbyte; const Row, Width : Integer; Stream : TStream); + protected + function SaveHeader(Stream:TStream; Img: TFPCustomImage):boolean; virtual; + procedure InternalWrite (Stream:TStream; Img: TFPCustomImage); override; + public + constructor Create; override; + property BitsPerPixel : byte read FBpp write SetBpp; + property RLECompress : boolean read FRleCompress write FRleCompress; + Property BytesPerPixel : Byte Read GetColorSize Write SetColorSize; deprecated; + end; + + +implementation + +Function FPColorToRGB(Const Color : TFPColor) : TColorRGB; + +begin + With Result,Color do + begin + R:=(Red and $FF00) shr 8; + G:=(Green and $FF00) shr 8; + B:=(Blue and $FF00) shr 8; + end; +end; + +Function FPColorToRGBA(Const Color : TFPColor) : TColorRGBA; + +begin + With Result,Color do + begin + R:=(Red and $FF00) shr 8; + G:=(Green and $FF00) shr 8; + B:=(Blue and $FF00) shr 8; + A:=(Alpha and $FF00) shr 8; + end; +end; + +constructor TFPWriterBMP.create; +begin + inherited create; + FBpp:=24; + FRleCompress:=false; +end; + +{ Only for compatibility, BytesPerPixel should be removed } +{ ******************************************************* } +procedure TFPWriterBMP.SetColorSize (AValue : byte); +begin + SetBpp(AValue*8); +end; + +function TFPWriterBMP.GetColorSize : byte; +begin + if FBpp<>15 then Result:=FBpp div 8 + else Result:=2; +end; +{ ******************************************************* } + +procedure TFPWriterBMP.SetBpp (const abpp : byte); +begin + if not (abpp in [1,4,8,15,16,24,32]) then + raise FPImageException.Create('Invalid color depth'); + FBpp:=abpp; +end; + +procedure TFPWriterBMP.FillColorMap(Img : TFPCustomImage); +var BadPalette : boolean; + i : integer; +begin + BadPalette:=false; + if not Img.UsePalette then BadPalette:=true + else if Img.Palette.Count>(1 shl FBpp) then BadPalette:=true; + if BadPalette then + raise FPImageException.Create('Image palette is too big or absent'); + setlength(ColInfo,Img.Palette.Count); + BFI.ClrUsed:=Img.Palette.Count; + for i:=0 to BFI.ClrUsed-1 do + begin + ColInfo[i]:=FPColorToRGBA(Img.Palette.Color[i]); + ColInfo[i].A:=0; + end; +end; + +{ True 16 bit color is 5 bits red, 6 bits green and 5 bits blue. + Compression must be set to BI_BITFIELDS and we must specify masks for red, green and blue. + 16 bit without compression and masks is 5 bits per channel, so it's 15 bit even if in the header we + must write 16. + It's possible to provide custom masks but this is not compatible with windows9x, so we use 555 for 15 bit + and 565 for 16 bit. + Masks are longwords stored in the palette instead of palette entries (which are 4 bytes long too, with + components stored in following order: B G R A. Since we must write a low-endian longword, B is LSB and A + is the MSB). + We must write first red mask, then green and then blue. + + This sounds terribly confusing, if you don't understand take a look at + http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_1rw2.asp + } +procedure TFPWriterBMP.Setup16bpp; +var col : TColorRGBA; +begin + BFI.Compression:=BI_BITFIELDS; + setlength(ColInfo,3); + { A R G B + r := $0000F800 + g := $000007E0 + b := $0000001F + } + col.A:=0; Col.R:=0; { These are 0 for all the three masks} + { Red Mask } + Col.G:=$F8; Col.B:=0; + ColInfo[0]:=Col; + { Green Mask } + Col.G:=$07; Col.B:=$E0; + ColInfo[1]:=Col; + { Blue Mask } + Col.G:=$00; Col.B:=$1F; + ColInfo[2]:=Col; +end; + +{ 16 bit bpp with 555 packing (that is, 15 bit color) + This is bit dislocation: + 0RRR RRGG GGGB BBBB } + +function TFPWriterBMP.PackWord555(const col : TFPColor) : word; +var tmpcol : TColorRGB; + tmpr, tmpg, tmpb : word; +begin + tmpcol:=FPColorToRGB(col); + tmpb:=tmpcol.b shr 3; + tmpg:=tmpcol.g and $F8; tmpg:= tmpg shl 2; + tmpr:=tmpcol.r and $F8; tmpr:= tmpr shl 7; + tmpb:= tmpr or tmpg or tmpb; + {$IFDEF ENDIAN_BIG} + tmpb:=swap(tmpb); + {$ENDIF} + Result:=tmpb; +end; + +{ 16 bit bpp with 565 packing ) + This is bit dislocation: + RRRR RGGG GGGB BBBB } + +function TFPWriterBMP.PackWord565(const col : TFPColor) : word; +var tmpcol : TColorRGB; + tmpr, tmpg, tmpb : word; +begin + tmpcol:=FPColorToRGB(col); + tmpb:=tmpcol.b shr 3; + tmpg:=tmpcol.g and $FC; tmpg:= tmpg shl 3; + tmpr:=tmpcol.r and $F8; tmpr:= tmpr shl 8; + tmpb:= tmpr or tmpg or tmpb; + {$IFDEF ENDIAN_BIG} + tmpb:=swap(tmpb); + {$ENDIF} + Result:=tmpb; +end; + +{ First pixel in the most significant nibble, second one in LSN. If we are at the end of the line, + pad with zero } +function TFPWriterBMP.Pack4bpp(const img : TFPCustomImage; var Col : integer; const Row : integer) : byte; +var b : byte; +begin + b:=(img.Pixels[Col,Row] and $F) shl 4; + if Col=0)) do + begin + if img.Pixels[Col,Row]<>0 then { set this bit } + b:=b+(1 shl sh); + dec(sh); + inc(Col); + end; + Result:=b; +end; + +function TFPWriterBMP.SaveHeader(Stream:TStream; Img : TFPCustomImage):boolean; +begin + Result:=False; + with BFI do + begin + Size:=sizeof(TBitMapInfoHeader); + Width:=Img.Width; + Height:=Img.Height; + Planes:=1; + if FBpp=15 then BitCount:=16 + else BitCount:=FBpp; + XPelsPerMeter:=100; + YPelsPerMeter:=100; + ClrImportant:=0; + end; + with BFH do + begin + bfType:=BMmagic;//'BM' + bfOffset:=sizeof(TBitMapFileHeader)+sizeof(TBitMapInfoHeader)+length(ColInfo)*4; + bfReserved:=0; + bfSize:=bfOffset+BFI.SizeImage; + end; + {$IFDEF ENDIAN_BIG} + SwapBMPFileHeader(BFH); + SwapBMPInfoHeader(BFI); + {$ENDIF} + StartPosition:=Stream.Position; + Stream.Write(bfh,sizeof(TBitMapFileHeader)); + Stream.Write(bfi,sizeof(TBitMapInfoHeader)); + {$IFDEF ENDIAN_BIG} + SwapBMPFileHeader(BFH); + SwapBMPInfoHeader(BFI); + {$ENDIF} + Result:=true; +end; + +{ This code is rather ugly and difficult to read, but compresses better than gimp. + Brief explanation: + A repetition is good if it's made of 3 elements at least: we have 2 bytes instead of 1. Let's call this a + "repetition" or "true repetition". + So we start finding the first repetition from current position. + Once found, we must decide how to handle elements between current position (i) and the repetition position (j) + if j-i = 0 we are on the repetition, so we encode it + if j-i = 1 there is only one pixel. We can't do anything but encode it as a repetition of 1 element. + if j-i = 2 we have two pixels. These can be a couple (a repetition of 2 elements) or 2 singles + (2 repetitions of 1 element) + if j-i > 2 we have two choices. In fact, we must consider that absolute mode is 2 bytes + length of chunk. + A repetition is always 2 bytes, so for 1 element we leak 1 byte, while for 2 elements we don't leak + any byte. + So if we have at most 1 single this means that everything else is made up of couples: it's best to + use repetitions so that we leak 0 to 1 byte. + If we have 2 singles or more it's better to use absolute mode, since we leak 2 bytes always, + without regard to the size of chunk. } + +procedure TFPWriterBMP.CompressScanLineRLE8(ALine : pbyte; const Row, Width : Integer; Stream : TStream); +var i, j, k, couples, singles : integer; + prev,tmp : byte; +begin + i:=0; + while (i=3 } + prev:=Aline[i]; + j:=i+1; + while ((jprev then break; + inc(j); + end; + tmp:=j-i; + Stream.Write(tmp,1); + Stream.Write(prev,1); + end; + 1 : begin { single value: we write a repetition of 1 } + tmp:=1; + Stream.Write(tmp,1); + Stream.Write(Aline[i],1); + end; + 2 : begin + if couples=1 then { a couple: we write a repetition of 2 } + begin + tmp:=2; + Stream.Write(tmp,1); + Stream.Write(Aline[i],1); + end + else { two singles: we write two repetitions of 1 each } + begin + tmp:=1; + Stream.Write(tmp,1); + Stream.Write(Aline[i],1); + Stream.Write(tmp,1); + Stream.Write(Aline[i+1],1); + end; + end; + else { here we have two choices } + begin + if singles>1 then { it's cheaper to use absolute mode } + begin + tmp:=0; Stream.Write(tmp,1); { escape } + tmp:=j-i; Stream.Write(tmp,1); { number of pixels in absolute mode } + Stream.Write(Aline[i],j-i); { write these pixels... } + if ((tmp mod 2)<>0) then { we must end on a 2-byte boundary } + begin + tmp:=0; Stream.Write(tmp,1); { so pad with an additional zero } + end; + end + else { they're nearly all couples, don't use absolute mode } + begin + k:=i; + while (k E + 0316 => 161. + A repetition is good if it's made of five elements at least (2 bytes instead of 3). + In rle4 we consider "single" either a single nibble or 2 (a byte), while a couple is a repetition of 3 or 4 + elements. } + +procedure TFPWriterBMP.CompressScanLineRLE4(ALine : pbyte; const Row, Width : Integer; Stream : TStream); +var i, j, k, couples, singles, lastsingle : integer; + prev1, prev2, prev : word; + tmp : byte; + nibline : pbyte; { temporary array of nibbles } + even : boolean; +begin + getmem(nibline,width); + try + k:=(Width div 2) + (Width mod 2); + i:=0; + while (i(j-1) then + begin + inc(singles); { this is a single if next isn't a couple } + lastsingle:=j; + end; + prev:=nibline[j]; + end; + prev1:=prev2; + prev2:=prev; + even:=not even; + inc(j); + end; + if j>Width then j:=Width; { if j was Width-1 loop was skipped and j is Width+1, so we fix it } + + { ok, now that we know more about byte disposition we write data } + case (j-i) of + 0 : begin { there is a repetition with count>=5 } + even:=true; + prev1:=nibline[i]; + prev2:=nibline[i+1]; + j:=i+2; + while ((jprev1 then break; + if not even then if nibline[j]<>prev2 then break; + even:=not even; + inc(j); + end; + tmp:=j-i; + Stream.Write(tmp,1); + prev:=(prev1 shl 4) + (prev2 and $F); + tmp:=prev; + Stream.Write(tmp,1); + end; + 1 : begin { single value: we write a repetition of 1 } + tmp:=1; + Stream.Write(tmp,1); + tmp:=nibline[i] shl 4; + Stream.Write(tmp,1); + end; + 2 : begin { 2 singles in the same byte: we write a repetition of 2 } + tmp:=2; + Stream.Write(tmp,1); + tmp:=(nibline[i] shl 4) + (nibline[i+1] and $F); + Stream.Write(tmp,1); + end; + 3 : begin + if couples=1 then { a couple: we write a repetition of 3 } + begin + tmp:=3; + Stream.Write(tmp,1); + tmp:=(nibline[i] shl 4) + (nibline[i+1] and $F); + Stream.Write(tmp,1); + end + else + begin { 2 singles, 2 repetitions of 2 and 1 respectively } + tmp:=2; + Stream.Write(tmp,1); + tmp:=(nibline[i] shl 4) + (nibline[i+1] and $F); + Stream.Write(tmp,1); + tmp:=1; + Stream.Write(tmp,1); + tmp:=nibline[i+2] shl 4; + Stream.Write(tmp,1); + end; + end; + 4 : begin + if singles=0 then { a couple: we write a repetition of 4 } + begin + tmp:=4; + Stream.Write(tmp,1); + tmp:=(nibline[i] shl 4) + (nibline[i+1] and $F); + Stream.Write(tmp,1); + end + else + begin { 2 singles, 2 repetitions of 2 each } + tmp:=2; + Stream.Write(tmp,1); + tmp:=(nibline[i] shl 4) + (nibline[i+1] and $F); + Stream.Write(tmp,1); + tmp:=2; + Stream.Write(tmp,1); + tmp:=(nibline[i+2] shl 4) + (nibline[i+3] and $F); + Stream.Write(tmp,1); + end; + end; + else { here we have two choices } + begin + if singles>1 then { it's cheaper to use absolute mode } + begin + tmp:=0; Stream.Write(tmp,1); { escape } + tmp:=j-i; Stream.Write(tmp,1); { number of pixels in absolute mode } + k:=i; + while (k0 then { we must end on a 2-byte boundary } + begin + tmp:=0; Stream.Write(tmp,1); { so pad with an additional zero } + end; + end + else { they're nearly all couples, don't use absolute mode } + begin + k:=i; + while (k=j) then tmp:=1 + else if ((k+31 then tmp:=tmp+(nibline[k+1] and $F); + Stream.Write(tmp,1); + inc(k,prev); + end; + end; + end; + end; + i:=j; + end; + tmp:=0; Stream.Write(tmp,1); { escape } + if Row=0 then { last line, end of file } + tmp:=1; + Stream.Write(tmp,1); + finally + FreeMem(nibline); + end; +end; + +procedure TFPWriterBMP.InternalWrite (Stream:TStream; Img:TFPCustomImage); +var + Row,Col,RowSize:Integer; + PadCount : byte; + aLine: PByte; + i : Integer; + tmppos : int64; + continue : boolean; + percent : byte; + percentinterval : longword; + percentacc : longword; + Rect : TRect; +begin + Rect.Left:=0; Rect.Top:=0; Rect.Right:=0; Rect.Bottom:=0; + continue:=true; + percent:=0; + percentinterval:=(Img.Height*4) div 100; + if percentinterval=0 then percentinterval:=$FFFFFFFF; + percentacc:=0; + Progress(psStarting,0,false,Rect,'',continue); + if not continue then exit; + if (FRLECompress and (not (FBpp in [4,8]))) then + raise FPImageException.Create('Can''t use RLE compression with '+IntToStr(FBpp)+' bits per pixel'); + if FRLECompress and (FBpp=4) then BFI.Compression:=BI_RLE4 + else if FRLECompress and (FBpp=8) then BFI.Compression:=BI_RLE8 + else BFI.Compression:=BI_RGB; + BFI.ClrUsed:=0; + try + if FBpp<=8 then FillColorMap(Img); { sets colormap and ClrUsed} + if FBpp=16 then Setup16bpp; { sets colormap with masks and Compression } + RowSize:=0; { just to keep the compiler quiet. } + case FBpp of + 1 : begin + RowSize:=Img.Width div 8; + if (Img.Width mod 8)<>0 then + inc(RowSize); + end; + 4 : begin + RowSize:=Img.Width div 2; + if (Img.Width mod 2)<>0 then + inc(RowSize); + end; + 8 : RowSize:=Img.Width; + 15 : RowSize:=Img.Width*2; + 16 : RowSize:=Img.Width*2; + 24 : RowSize:=Img.Width*3; + 32 : RowSize:=Img.Width*4; + end; + PadCount:=(4-(RowSize mod 4)) mod 4; { every row must end on 4 byte boundary } + inc(RowSize,PadCount); + BFI.SizeImage:=RowSize*Img.Height; + + SaveHeader(Stream,Img); { write the headers } + for i:=0 to length(ColInfo)-1 do { write the palette (or the masks in 16bpp case) } + Stream.Write(ColInfo[i],sizeof(TColorRGBA)); + + GetMem(aLine,RowSize); + try + for Row:=Img.Height-1 downto 0 do + begin + i:=0; Col:=0; + case FBpp of + 1 : while(Col=percentinterval then + begin + percent:=percent+(percentacc div percentinterval); + percentacc:=percentacc mod percentinterval; + Progress(psRunning,percent,false,Rect,'',continue); + if not continue then exit; + end; + end; + { If image is compressed we must fix the headers since we now know the size of the image } + if BFI.Compression in [BI_RLE4,BI_RLE8] then + begin + tmppos:=Stream.Position-StartPosition-BFH.bfOffset; + BFI.SizeImage:=tmppos; { set size of the image } + tmppos:=Stream.Position; { remember where we are } + Stream.Position:=StartPosition; { rewind to the beginning } + SaveHeader(Stream,Img); { rewrite headers (this will update BFH.Size too) } + Stream.Position:=tmppos; { restore our position } + end; + Progress(psEnding,100,false,Rect,'',continue); + finally + FreeMem(aLine); + end; + finally + setlength(ColInfo,0); + end; +end; + +initialization + ImageHandlers.RegisterImageWriter ('BMP Format', 'bmp', TFPWriterBMP); +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/fpwritejpeg.pas b/mseide-msegui/lib/common/fpccompatibility/fpwritejpeg.pas new file mode 100644 index 0000000..f09c61d --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpwritejpeg.pas @@ -0,0 +1,226 @@ +{ Copyright (C) 2003 Mattias Gaertner + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License + for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +} + +//modified 2013 by Martin Schreiber + +unit FPWriteJPEG; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, mclasses,SysUtils, FPImage, JPEGLib_del, FPReadJPEG, + JcAPIstd_del, JcAPImin_del, JDataDst_del, JcParam_del, JError_del; + +type + { TFPWriterJPEG } + + TFPJPEGCompressionQuality = 1..100; // 100 = best quality, 25 = pretty awful + + TFPWriterJPEG = class(TFPCustomImageWriter) + private + FGrayscale: boolean; + FInfo: jpeg_compress_struct; + FError: jpeg_error_mgr; + FProgressiveEncoding: boolean; + FQuality: TFPJPEGCompressionQuality; + FProgressMgr: TFPJPEGProgressManager; + protected + procedure InternalWrite(Str: TStream; Img: TFPCustomImage); override; + public + constructor Create; override; + destructor Destroy; override; + property CompressionQuality: TFPJPEGCompressionQuality read FQuality write FQuality; + property ProgressiveEncoding: boolean read FProgressiveEncoding write FProgressiveEncoding; + property GrayScale: boolean read FGrayscale; + end; + +implementation + +procedure JPEGError(CurInfo: j_common_ptr); +begin + if CurInfo=nil then exit; + {$ifdef FPC_Debug_Image} + writeln('JPEGError ',CurInfo^.err^.msg_code,' '); + {$endif} + raise Exception.CreateFmt('JPEG error',[CurInfo^.err^.msg_code]); +end; + +procedure EmitMessage(CurInfo: j_common_ptr; msg_level: Integer); +begin + if CurInfo=nil then exit; + if msg_level=0 then ; +end; + +procedure OutputMessage(CurInfo: j_common_ptr); +begin + if CurInfo=nil then exit; +end; + +procedure FormatMessage(CurInfo: j_common_ptr; var buffer: string); +begin + if CurInfo=nil then exit; + {$ifdef FPC_Debug_Image} + writeln('FormatMessage ',buffer); + {$endif} +end; + +procedure ResetErrorMgr(CurInfo: j_common_ptr); +begin + if CurInfo=nil then exit; + CurInfo^.err^.num_warnings := 0; + CurInfo^.err^.msg_code := 0; +end; + +var + jpeg_std_error: jpeg_error_mgr; + +procedure ProgressCallback(CurInfo: j_common_ptr); +begin + if CurInfo=nil then exit; + // ToDo +end; + +{ TFPWriterJPEG } + +procedure TFPWriterJPEG.InternalWrite(Str: TStream; Img: TFPCustomImage); +var + MemStream: TMemoryStream; + Continue: Boolean; + + procedure InitWriting; + begin + FillChar(FInfo, sizeof(FInfo), 0); + FError := jpeg_std_error; + FInfo.err := jerror_del.jpeg_std_error(FError); + + jpeg_create_compress(@FInfo); + FProgressMgr.pub.progress_monitor := @ProgressCallback; + FProgressMgr.instance := Self; + FInfo.progress := @FProgressMgr.pub; + end; + + procedure SetDestination; + begin + if Str is TMemoryStream then + MemStream:=TMemoryStream(Str) + else + MemStream := TMemoryStream.Create; + jpeg_stdio_dest(@FInfo, @MemStream); + end; + + procedure WriteHeader; + begin + FInfo.image_width := Img.Width; + FInfo.image_height := Img.Height; + FInfo.input_components := 3; // RGB has 3 components + FInfo.in_color_space := JCS_RGB; + if FGrayscale then + jpeg_set_colorspace(@FInfo, JCS_GRAYSCALE); + + jpeg_set_defaults(@FInfo); + jpeg_set_quality(@FInfo, FQuality, True); + + if ProgressiveEncoding then + jpeg_simple_progression(@FInfo); + end; + + procedure WritePixels; + var + LinesWritten: Cardinal; + SampArray: JSAMPARRAY; + SampRow: JSAMPROW; + Color: TFPColor; + x: Integer; + y: Integer; + begin + Progress(psStarting, 0, False, Rect(0,0,0,0), '', Continue); + if not Continue then exit; + jpeg_start_compress(@FInfo, True); + + // write one line per call + GetMem(SampArray,SizeOf(JSAMPROW)); + GetMem(SampRow,FInfo.image_width*FInfo.input_components); + SampArray^[0]:=SampRow; + try + y:=0; + while (FInfo.next_scanline < FInfo.image_height) do begin + for x:=0 to FInfo.image_width-1 do begin + Color:=Img.Colors[x,y]; + SampRow^[x*3+0]:=Color.Red shr 8; + SampRow^[x*3+1]:=Color.Green shr 8; + SampRow^[x*3+2]:=Color.Blue shr 8; + end; + LinesWritten := jpeg_write_scanlines(@FInfo, SampArray, 1); + if LinesWritten<1 then break; + inc(y); + end; + finally + FreeMem(SampRow); + FreeMem(SampArray); + end; + + jpeg_finish_compress(@FInfo); + Progress(psEnding, 100, False, Rect(0,0,0,0), '', Continue); + end; + + procedure EndWriting; + begin + jpeg_destroy_compress(@FInfo); + end; + +begin + Continue := true; + MemStream:=nil; + try + InitWriting; + SetDestination; + WriteHeader; + WritePixels; + if MemStream<>Str then begin + MemStream.Position:=0; + Str.CopyFrom(MemStream,MemStream.Size); + end; + finally + EndWriting; + if MemStream<>Str then + MemStream.Free; + end; +end; + +constructor TFPWriterJPEG.Create; +begin + inherited Create; + FQuality:=75; +end; + +destructor TFPWriterJPEG.Destroy; +begin + inherited Destroy; +end; + +initialization + with jpeg_std_error do begin + error_exit:=@JPEGError; + emit_message:=@EmitMessage; + output_message:=@OutputMessage; + format_message:=@FormatMessage; + reset_error_mgr:=@ResetErrorMgr; + end; + ImageHandlers.RegisterImageWriter ('JPEG graphics', 'jpg;jpeg', TFPWriterJPEG); +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/fpwritepcx.pas b/mseide-msegui/lib/common/fpccompatibility/fpwritepcx.pas new file mode 100644 index 0000000..7d8d38b --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpwritepcx.pas @@ -0,0 +1,156 @@ +{ Copyright (C) 2007 Laurent Jacques + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License + for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Save in format 24 bits compressed or not +} + +unit FPWritePCX; + +{$mode objfpc}{$H+} + +interface + +uses FPImage, Classes, SysUtils; + +type + + TFPWriterPCX = class(TFPCustomImageWriter) + private + FCompressed: boolean; + protected + function SaveHeader(Stream: TStream; Img: TFPCustomImage): boolean; virtual; + procedure InternalWrite(Stream: TStream; Img: TFPCustomImage); override; + procedure writeline(Stream: TStream; buffer: PByte; bytes: integer); + public + property Compressed: boolean Read FCompressed Write FCompressed; + end; + +implementation + +uses pcxcomn; + +function TFPWriterPCX.SaveHeader(Stream: TStream; Img: TFPCustomImage): boolean; +var + Header: TPCXHeader; +begin + Result := False; + FillChar(Header, SizeOf(Header), 0); + with Header do + begin + FileID := $0a; + Version := 5; + if Compressed then + Encoding := 1 + else + Encoding := 0; + BitsPerPixel := 8; + XMin := 0; + YMin := 0; + XMax := Img.Width - 1; + YMax := Img.Height - 1; + HRes := 300; + VRes := 300; + ColorPlanes := 3; + BytesPerLine := Img.Width; + PaletteType := 1; + end; + Stream.WriteBuffer(Header, SizeOf(Header)); + Result := True; +end; + +procedure TFPWriterPCX.writeline(Stream: TStream; buffer: PByte; bytes: integer); +var + Value, Count: byte; + tmp: byte; + P: PByte; +begin + P := Buffer; + while bytes > 0 do + begin + Value := P[0]; + Inc(P); + Dec(bytes); + Count := 1; + while (bytes < 0) and (Count < 63) and (P[0] = Value) do + begin + Inc(Count); + Inc(P); + Dec(bytes); + end; + if (Value < $c0) and (Count = 1) then + begin + Stream.Write(Value, 1); + end + else + begin + tmp := $c0 + Count; + Stream.Write(tmp, 1); + Stream.Write(Value, 1); + end; + end; +end; + +procedure TFPWriterPCX.InternalWrite(Stream: TStream; Img: TFPCustomImage); +var + Row, Col, WriteSize: integer; + Aline, P: PByte; + C: TFPColor; + Totalwrite: longint; + continue: boolean; + Rect: TRect; +begin + Rect.Left := 0; + Rect.Top := 0; + Rect.Right := 0; + Rect.Bottom := 0; + continue := True; + TotalWrite := 0; + Progress(psStarting, 0, False, Rect, '', continue); + SaveHeader(Stream, Img); + WriteSize := (Img.Width * 3); + GetMem(aLine, WriteSize); + TotalWrite := Img.Height * Img.Width; + try + for Row := 0 to Img.Height - 1 do + begin + P := ALine; + for Col := 0 to Img.Width - 1 do + begin + C := Img.Colors[Col, Row]; + P[Col + Img.Width * 2] := C.Blue shr 8; + P[Col + Img.Width] := C.Green shr 8; + P[Col] := C.Red shr 8; + Progress(psRunning, trunc(100.0 * (Row * Col / TotalWrite)), + False, Rect, '', continue); + if not continue then + exit; + end; + if Compressed then + writeline(Stream, aLine, WriteSize) + else + Stream.Write(aLine[0], WriteSize); + end; + Progress(psEnding, 100, False, Rect, '', continue); + finally + FreeMem(aLine); + end; +end; + +{ end TFPWriterPCX} + +initialization + ImageHandlers.RegisterImageWriter('PCX Format', 'pcx', TFPWriterPCX); +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/fpwritepng.pp b/mseide-msegui/lib/common/fpccompatibility/fpwritepng.pp new file mode 100644 index 0000000..58ca209 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpwritepng.pp @@ -0,0 +1,757 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 2003 by the Free Pascal development team + + XPM writer class. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + **********************************************************************} +{$mode objfpc}{$h+} +unit FPWritePNG; + +interface + +uses sysutils, classes, mclasses, FPImage, FPImgCmn, PNGComn, ZStream; + +type + + TGetPixelFunc = function (x,y : LongWord) : TColorData of object; + + TColorFormatFunction = function (color:TFPColor) : TColorData of object; + + TFPWriterPNG = class (TFPCustomImageWriter) + private + FUsetRNS, FCompressedText, FWordSized, FIndexed, + FUseAlpha, FGrayScale : boolean; + FByteWidth : byte; + FChunk : TChunk; + CFmt : TColorFormat; // format of the colors to convert from + FFmtColor : TColorFormatFunction; + FTransparentColor : TFPColor; + FSwitchLine, FCurrentLine, FPreviousLine : pByteArray; + FPalette : TFPPalette; + OwnsPalette : boolean; + FHeader : THeaderChunk; + FGetPixel : TGetPixelFunc; + FDatalineLength : longword; + ZData : TMemoryStream; // holds uncompressed data until all blocks are written + Compressor : TCompressionStream; // compresses the data + FCompressionLevel : TCompressionLevel; + procedure WriteChunk; + function GetColorPixel (x,y:longword) : TColorData; + function GetPalettePixel (x,y:longword) : TColorData; + function GetColPalPixel (x,y:longword) : TColorData; + procedure InitWriteIDAT; + procedure Gatherdata; + procedure WriteCompressedData; + procedure FinalWriteIDAT; + protected + property Header : THeaderChunk read FHeader; + procedure InternalWrite (Str:TStream; Img:TFPCustomImage); override; + procedure WriteIHDR; virtual; + procedure WritePLTE; virtual; + procedure WritetRNS; virtual; + procedure WriteIDAT; virtual; + procedure WriteTexts; virtual; + procedure WriteIEND; virtual; + function CurrentLine (x:longword) : byte; + function PrevSample (x:longword): byte; + function PreviousLine (x:longword) : byte; + function PrevLinePrevSample (x:longword): byte; + function DoFilter (LineFilter:byte;index:longword; b:byte) : byte; virtual; + procedure SetChunkLength (aValue : longword); + procedure SetChunkType (ct : TChunkTypes); + procedure SetChunkType (ct : TChunkCode); + function DecideGetPixel : TGetPixelFunc; virtual; + procedure DetermineHeader (var AHeader : THeaderChunk); virtual; + function DetermineFilter (Current, Previous:PByteArray; linelength:longword):byte; virtual; + procedure FillScanLine (y : integer; ScanLine : pByteArray); virtual; + function ColorDataGrayB(color:TFPColor) : TColorData; + function ColorDataColorB(color:TFPColor) : TColorData; + function ColorDataGrayW(color:TFPColor) : TColorData; + function ColorDataColorW(color:TFPColor) : TColorData; + function ColorDataGrayAB(color:TFPColor) : TColorData; + function ColorDataColorAB(color:TFPColor) : TColorData; + function ColorDataGrayAW(color:TFPColor) : TColorData; + function ColorDataColorAW(color:TFPColor) : TColorData; + property ChunkDataBuffer : pByteArray read FChunk.data; + property UsetRNS : boolean read FUsetRNS; + property SingleTransparentColor : TFPColor read FTransparentColor; + property ThePalette : TFPPalette read FPalette; + property ColorFormat : TColorformat read CFmt; + property ColorFormatFunc : TColorFormatFunction read FFmtColor; + property byteWidth : byte read FByteWidth; + property DatalineLength : longword read FDatalineLength; + public + constructor create; override; + destructor destroy; override; + property GrayScale : boolean read FGrayscale write FGrayScale; + property Indexed : boolean read FIndexed write FIndexed; + property CompressedText : boolean read FCompressedText write FCompressedText; + property WordSized : boolean read FWordSized write FWordSized; + property UseAlpha : boolean read FUseAlpha write FUseAlpha; + property CompressionLevel : TCompressionLevel read FCompressionLevel write FCompressionLevel; + end; + +implementation + +constructor TFPWriterPNG.create; +begin + inherited; + Fchunk.acapacity := 0; + Fchunk.data := nil; + FGrayScale := False; + FIndexed := False; + FCompressedText := True; + FWordSized := True; + FUseAlpha := False; + FCompressionLevel:=clDefault; +end; + +destructor TFPWriterPNG.destroy; +begin + if OwnsPalette then FreeAndNil(FPalette); + with Fchunk do + if acapacity > 0 then + freemem (data); + inherited; +end; + +procedure TFPWriterPNG.WriteChunk; +var chead : TChunkHeader; + c : longword; +begin + with FChunk do + begin + {$IFDEF ENDIAN_LITTLE} + chead.CLength := swap (alength); + {$ELSE} + chead.CLength := alength; + {$ENDIF} + if (ReadType = '') then + if atype <> ctUnknown then + chead.CType := ChunkTypes[aType] + else + raise PNGImageException.create ('Doesn''t have a chunktype to write') + else + chead.CType := ReadType; + c := CalculateCRC (All1Bits, ReadType, sizeOf(ReadType)); + c := CalculateCRC (c, data^, alength); + {$IFDEF ENDIAN_LITTLE} + crc := swap(c xor All1Bits); + {$ELSE} + crc := c xor All1Bits; + {$ENDIF} + with TheStream do + begin + Write (chead, sizeof(chead)); + Write (data^[0], alength); + Write (crc, sizeof(crc)); + end; + end; +end; + +procedure TFPWriterPNG.SetChunkLength(aValue : longword); +begin + with Fchunk do + begin + alength := aValue; + if aValue > acapacity then + begin + if acapacity > 0 then + freemem (data); + GetMem (data, alength); + acapacity := alength; + end; + end; +end; + +procedure TFPWriterPNG.SetChunkType (ct : TChunkTypes); +begin + with Fchunk do + begin + aType := ct; + ReadType := ChunkTypes[ct]; + end; +end; + +procedure TFPWriterPNG.SetChunkType (ct : TChunkCode); +begin + with FChunk do + begin + ReadType := ct; + aType := low(TChunkTypes); + while (aType < high(TChunkTypes)) and (ChunkTypes[aType] <> ct) do + inc (aType); + end; +end; + +function TFPWriterPNG.CurrentLine(x:longword):byte; +begin + result := FCurrentLine^[x]; +end; + +function TFPWriterPNG.PrevSample (x:longword): byte; +begin + if x < byteWidth then + result := 0 + else + result := FCurrentLine^[x - bytewidth]; +end; + +function TFPWriterPNG.PreviousLine (x:longword) : byte; +begin + result := FPreviousline^[x]; +end; + +function TFPWriterPNG.PrevLinePrevSample (x:longword): byte; +begin + if x < byteWidth then + result := 0 + else + result := FPreviousLine^[x - bytewidth]; +end; + +function TFPWriterPNG.DoFilter(LineFilter:byte;index:longword; b:byte) : byte; +var diff : byte; + procedure FilterSub; + begin + diff := PrevSample(index); + end; + procedure FilterUp; + begin + diff := PreviousLine(index); + end; + procedure FilterAverage; + var l, p : word; + begin + l := PrevSample(index); + p := PreviousLine(index); + Diff := (l + p) div 2; + end; + procedure FilterPaeth; + var dl, dp, dlp : word; // index for previous and distances for: + l, p, lp : byte; // r:predictor, Left, Previous, LeftPrevious + r : integer; + begin + l := PrevSample(index); + lp := PrevLinePrevSample(index); + p := PreviousLine(index); + r := l + p - lp; + dl := abs (r - l); + dlp := abs (r - lp); + dp := abs (r - p); + if (dl <= dp) and (dl <= dlp) then + diff := l + else if dp <= dlp then + diff := p + else + diff := lp; + end; +begin + case LineFilter of + 0 : diff := 0; + 1 : FilterSub; + 2 : FilterUp; + 3 : FilterAverage; + 4 : FilterPaeth; + end; + if diff > b then + result := (b + $100 - diff) + else + result := b - diff; +end; + +procedure TFPWriterPNG.DetermineHeader (var AHeader : THeaderChunk); +var c : integer; + function CountAlphas : integer; + var none, half : boolean; + x,y : longint; // warning, checks on <0 ! + p : integer; + c : TFPColor; + a : word; + begin + half := false; + none := false; + with TheImage do + if UsePalette then + with Palette do + begin + p := count-1; + FTransparentColor.alpha := alphaOpaque; + while (p >= 0) do + begin + c := color[p]; + a := c.Alpha; + if a = alphaTransparent then + begin + none := true; + FTransparentColor := c; + end + else if a <> alphaOpaque then + begin + half := true; + if FtransparentColor.alpha < a then + FtransparentColor := c; + end; + dec (p); + end; + end + else + begin + x := width-1; + y := height-1; + FTransparentColor.alpha := alphaOpaque; + while (y >= 0) and not (half and none) do + begin + c := colors[x,y]; + a := c.Alpha; + if a = alphaTransparent then + begin + none := true; + FTransparentColor := c; + end + else if a <> alphaOpaque then + begin + half := true; + if FtransparentColor.alpha < a then + FtransparentColor := c; + end; + dec (x); + if (x < 0) then + begin + dec (y); + x := width-1; + end; + end; + end; + result := 1; + if none then + inc (result); + if half then + inc (result); + end; + procedure DetermineColorFormat; + begin + with AHeader do + case colortype of + 0 : if FWordSized then + begin + FFmtColor := @ColorDataGrayW; + FByteWidth := 2; + //CFmt := cfGray16 + end + else + begin + FFmtColor := @ColorDataGrayB; + FByteWidth := 1; + //CFmt := cfGray8; + end; + 2 : if FWordSized then + begin + FFmtColor := @ColorDataColorW; + FByteWidth := 6; + //CFmt := cfBGR48 + end + else + begin + FFmtColor := @ColorDataColorB; + FByteWidth := 3; + //CFmt := cfBGR24; + end; + 4 : if FWordSized then + begin + FFmtColor := @ColorDataGrayAW; + FByteWidth := 4; + //CFmt := cfGrayA32 + end + else + begin + FFmtColor := @ColorDataGrayAB; + FByteWidth := 2; + //CFmt := cfGrayA16; + end; + 6 : if FWordSized then + begin + FFmtColor := @ColorDataColorAW; + FByteWidth := 8; + //CFmt := cfABGR64 + end + else + begin + FFmtColor := @ColorDataColorAB; + FByteWidth := 4; + //CFmt := cfABGR32; + end; + end; + end; +begin + with AHeader do + begin + {$IFDEF ENDIAN_LITTLE} + // problem: TheImage has integer width, PNG header longword width. + // Integer Swap can give negative value + Width := swap (longword(TheImage.Width)); + height := swap (longword(TheImage.Height)); + {$ELSE} + Width := TheImage.Width; + height := TheImage.Height; + {$ENDIF} + if FUseAlpha then + c := CountAlphas + else + c := 0; + if FIndexed then + begin + if OwnsPalette then FreeAndNil(FPalette); + OwnsPalette := not TheImage.UsePalette; + if OwnsPalette then + begin + FPalette := TFPPalette.Create (16); + FPalette.Build (TheImage); + end + else + FPalette := TheImage.Palette; + if ThePalette.count > 256 then + raise PNGImageException.Create ('Too many colors to use indexed PNG color type'); + ColorType := 3; + FUsetRNS := C > 1; + BitDepth := 8; + FByteWidth := 1; + end + else + begin + if c = 3 then + ColorType := 4; + FUsetRNS := (c = 2); + if not FGrayScale then + ColorType := ColorType + 2; + if FWordSized then + BitDepth := 16 + else + BitDepth := 8; + DetermineColorFormat; + end; + Compression := 0; + Filter := 0; + Interlace := 0; + end; +end; + +procedure TFPWriterPNG.WriteIHDR; +begin + // signature for PNG + TheStream.writeBuffer(Signature,sizeof(Signature)); + // Determine all settings for filling the header + fillchar(fheader,sizeof(fheader),#0); + DetermineHeader (FHeader); + // write the header chunk + SetChunkLength (13); // (sizeof(FHeader)); gives 14 and is wrong !! + move (FHeader, ChunkDataBuffer^, 13); // sizeof(FHeader)); + SetChunkType (ctIHDR); + WriteChunk; +end; + +{ Color convertions } + +function TFPWriterPNG.ColorDataGrayB(color:TFPColor) : TColorData; +var t : word; +begin + t := CalculateGray (color); + result := hi(t); +end; + +function TFPWriterPNG.ColorDataGrayW(color:TFPColor) : TColorData; +begin + result := CalculateGray (color); +end; + +function TFPWriterPNG.ColorDataGrayAB(color:TFPColor) : TColorData; +begin + result := ColorDataGrayB (color); + result := (result shl 8) and hi(color.Alpha); +end; + +function TFPWriterPNG.ColorDataGrayAW(color:TFPColor) : TColorData; +begin + result := ColorDataGrayW (color); + result := (result shl 16) and color.Alpha; +end; + +function TFPWriterPNG.ColorDataColorB(color:TFPColor) : TColorData; +begin + with color do + result := hi(red) + (green and $FF00) + (hi(blue) shl 16); +end; + +function TFPWriterPNG.ColorDataColorW(color:TFPColor) : TColorData; +begin + with color do + result := red + (green shl 16) + (qword(blue) shl 32); +end; + +function TFPWriterPNG.ColorDataColorAB(color:TFPColor) : TColorData; +begin + with color do + result := hi(red) + (green and $FF00) + (hi(blue) shl 16) + (hi(alpha) shl 24); +end; + +function TFPWriterPNG.ColorDataColorAW(color:TFPColor) : TColorData; +begin + with color do + result := red + (green shl 16) + (qword(blue) shl 32) + (qword(alpha) shl 48); +end; + +{ Data making routines } + +function TFPWriterPNG.GetColorPixel (x,y:longword) : TColorData; +begin + result := FFmtColor (TheImage[x,y]); + //result := ConvertColorToData(TheImage.Colors[x,y],CFmt); +end; + +function TFPWriterPNG.GetPalettePixel (x,y:longword) : TColorData; +begin + result := TheImage.Pixels[x,y]; +end; + +function TFPWriterPNG.GetColPalPixel (x,y:longword) : TColorData; +begin + result := ThePalette.IndexOf (TheImage.Colors[x,y]); +end; + +function TFPWriterPNG.DecideGetPixel : TGetPixelFunc; +begin + case Fheader.colortype of + 3 : if TheImage.UsePalette then + begin + result := @GetPalettePixel; + end + else + begin + result := @GetColPalPixel; + end; + else begin + result := @GetColorPixel; + end + end; +end; + +procedure TFPWriterPNG.WritePLTE; +var r,t : integer; + c : TFPColor; +begin + with ThePalette do + begin + SetChunkLength (count*3); + SetChunkType (ctPLTE); + t := 0; + For r := 0 to count-1 do + begin + c := Color[r]; + ChunkdataBuffer^[t] := c.red div 256; + inc (t); + ChunkdataBuffer^[t] := c.green div 256; + inc (t); + ChunkdataBuffer^[t] := c.blue div 256; + inc (t); + end; + end; + WriteChunk; +end; + +procedure TFPWriterPNG.InitWriteIDAT; +begin + FDatalineLength := TheImage.Width*ByteWidth; + GetMem (FPreviousLine, FDatalineLength); + GetMem (FCurrentLine, FDatalineLength); + fillchar (FCurrentLine^,FDatalineLength,0); + ZData := TMemoryStream.Create; + Compressor := TCompressionStream.Create (FCompressionLevel,ZData); + FGetPixel := DecideGetPixel; +end; + +procedure TFPWriterPNG.FinalWriteIDAT; +begin + ZData.Free; + FreeMem (FPreviousLine); + FreeMem (FCurrentLine); +end; + +function TFPWriterPNG.DetermineFilter (Current, Previous:PByteArray; linelength:longword) : byte; +begin + result := 0; +end; + +procedure TFPWriterPNG.FillScanLine (y : integer; ScanLine : pByteArray); +var r, x : integer; + cd : TColorData; + index : longword; + b : byte; +begin + index := 0; + for x := 0 to pred(TheImage.Width) do + begin + cd := FGetPixel (x,y); + {$IFDEF ENDIAN_BIG} + cd:=swap(cd); + {$ENDIF} + move (cd, ScanLine^[index], FBytewidth); + if WordSized then + begin + r := 1; + while (r < FByteWidth) do + begin + b := Scanline^[index+r]; + Scanline^[index+r] := Scanline^[index+r-1]; + Scanline^[index+r-1] := b; + inc (r,2); + end; + end; + inc (index, FByteWidth); + end; +end; + +procedure TFPWriterPNG.GatherData; +var x,y : integer; + lf : byte; +begin + for y := 0 to pred(TheImage.height) do + begin + FSwitchLine := FCurrentLine; + FCurrentLine := FPreviousLine; + FPreviousLine := FSwitchLine; + FillScanLine (y, FCurrentLine); + lf := DetermineFilter (FCurrentLine, FpreviousLine, FDataLineLength); + for x := 0 to FDatalineLength-1 do + FCurrentLine^[x] := DoFilter (lf, x, FCurrentLine^[x]); + Compressor.Write (lf, sizeof(lf)); + Compressor.Write (FCurrentLine^, FDataLineLength); + end; +end; + +procedure TFPWriterPNG.WriteCompressedData; +var l : longword; +begin + Compressor.Free; // Close compression and finish the writing in ZData + l := ZData.position; + ZData.position := 0; + SetChunkLength(l); + SetChunkType (ctIDAT); + ZData.Read (ChunkdataBuffer^, l); + WriteChunk; +end; + +procedure TFPWriterPNG.WriteIDAT; +begin + InitWriteIDAT; + GatherData; + WriteCompressedData; + FinalWriteIDAT; +end; + +procedure TFPWriterPNG.WritetRNS; + procedure PaletteAlpha; + var r : integer; + begin + with TheImage.palette do + begin + // search last palette entry with transparency + r := count; + repeat + dec (r); + until (r < 0) or (color[r].alpha <> alphaOpaque); + if r >= 0 then // there is at least 1 transparent color + begin + // from this color we go to the first palette entry + SetChunkLength (r+1); + repeat + chunkdatabuffer^[r] := (color[r].alpha shr 8); + dec (r); + until (r < 0); + end; + writechunk; + end; + end; + procedure GrayAlpha; + var g : word; + begin + SetChunkLength(2); + if WordSized then + g := CalculateGray (SingleTransparentColor) + else + g := hi (CalculateGray(SingleTransparentColor)); + {$IFDEF ENDIAN_LITTLE} + g := swap (g); + {$ENDIF} + move (g,ChunkDataBuffer^[0],2); + WriteChunk; + end; + procedure ColorAlpha; + var g : TFPColor; + begin + SetChunkLength(6); + g := SingleTransparentColor; + with g do + if WordSized then + begin + {$IFDEF ENDIAN_LITTLE} + red := swap (red); + green := swap (green); + blue := swap (blue); + {$ENDIF} + move (g, ChunkDatabuffer^[0], 6); + end + else + begin + ChunkDataBuffer^[0] := 0; + ChunkDataBuffer^[1] := red shr 8; + ChunkDataBuffer^[2] := 0; + ChunkDataBuffer^[3] := green shr 8; + ChunkDataBuffer^[4] := 0; + ChunkDataBuffer^[5] := blue shr 8; + end; + WriteChunk; + end; +begin + SetChunkType (cttRNS); + case fheader.colortype of + 6,4 : raise PNGImageException.create ('tRNS chunk forbidden for full alpha channels'); + 3 : PaletteAlpha; + 2 : ColorAlpha; + 0 : GrayAlpha; + end; +end; + +procedure TFPWriterPNG.WriteTexts; +begin +end; + +procedure TFPWriterPNG.WriteIEND; +begin + SetChunkLength(0); + SetChunkType (ctIEND); + WriteChunk; +end; + +procedure TFPWriterPNG.InternalWrite (Str:TStream; Img:TFPCustomImage); +begin + WriteIHDR; + if Fheader.colorType = 3 then + WritePLTE; + if FUsetRNS then + WritetRNS; + WriteIDAT; + WriteTexts; + WriteIEND; +end; + +initialization + ImageHandlers.RegisterImageWriter ('Portable Network Graphics', 'png', TFPWriterPNG); +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/fpwritepnm.pp b/mseide-msegui/lib/common/fpccompatibility/fpwritepnm.pp new file mode 100644 index 0000000..35137f4 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpwritepnm.pp @@ -0,0 +1,283 @@ +{*****************************************************************************} +{ + This file is part of the Free Pascal's "Free Components Library". + Copyright (c) 2003 by Mazen NEIFER of the Free Pascal development team + + PNM writer implementation. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +{*****************************************************************************} +{Support for writing PNM (Portable aNyMap) formats added : + * PBM (P1,P4) : Portable BitMap format : 1 bit per pixel + * PGM (P2,P5) : Portable GrayMap format : 8 bits per pixel + * PPM (P5,P6) : Portable PixelMap foramt : 24 bits per pixel} +{$mode objfpc}{$h+} +unit FPWritePNM; + +interface + +uses FPImage, classes, sysutils; + +type + TPNMColorDepth = (pcdAuto,pcdBlackWhite, pcdGrayscale, pcdRGB); + + { TFPWriterPNM } + + TFPWriterPNM = class(TFPCustomImageWriter) + protected + procedure InternalWrite(Stream:TStream;Img:TFPCustomImage);override; + public + ColorDepth: TPNMColorDepth; + BinaryFormat: boolean; + function GuessColorDepthOfImage(Img: TFPCustomImage): TPNMColorDepth; + function GetColorDepthOfExtension(AExtension: string): TPNMColorDepth; + function GetFileExtension(AColorDepth: TPNMColorDepth): string; + constructor Create; override; + end; + + { TFPWriterPBM } + + TFPWriterPBM = class(TFPWriterPNM) + constructor Create; override; + end; + + { TFPWriterPGM } + + TFPWriterPGM = class(TFPWriterPNM) + constructor Create; override; + end; + + { TFPWriterPPM } + + TFPWriterPPM = class(TFPWriterPNM) + constructor Create; override; + end; + +procedure SaveImageToPNMFile(Img: TFPCustomImage; filename: string; UseBinaryFormat: boolean = true); + +implementation + +procedure SaveImageToPNMFile(Img: TFPCustomImage; filename: string; UseBinaryFormat: boolean = true); +var writer: TFPWriterPNM; + curExt: string; +begin + writer := TFPWriterPNM.Create; + writer.BinaryFormat := UseBinaryFormat; + curExt := Lowercase(ExtractFileExt(filename)); + if (curExt='.pnm') or (curExt='') then + begin + writer.ColorDepth := writer.GuessColorDepthOfImage(Img); + filename := ChangeFileExt(filename,'.'+writer.GetFileExtension(writer.ColorDepth)); + end else + writer.ColorDepth := writer.GetColorDepthOfExtension(curExt); + Img.SaveToFile(filename,writer); + writer.Free; +end; + +{ TFPWriterPPM } + +constructor TFPWriterPPM.Create; +begin + inherited Create; + ColorDepth := pcdRGB; +end; + +{ TFPWriterPGM } + +constructor TFPWriterPGM.Create; +begin + inherited Create; + ColorDepth := pcdGrayscale; +end; + +{ TFPWriterPBM } + +constructor TFPWriterPBM.Create; +begin + inherited Create; + ColorDepth:= pcdBlackWhite; +end; + +{ TFPWriterPNM } + +constructor TFPWriterPNM.Create; +begin + inherited Create; + ColorDepth := pcdAuto; + BinaryFormat := True; +end; + +procedure TFPWriterPNM.InternalWrite(Stream:TStream;Img:TFPCustomImage); +var useBitMapType: integer; + + function SaveHeader(stream:TStream):boolean; + const + MagicWords:Array[1..6]OF String[2]=('P1','P2','P3','P4','P5','P6'); + var + PNMInfo:String; + strWidth,StrHeight:String[15]; + begin + SaveHeader:=false; + with Img do + begin + Str(Img.Width,StrWidth); + Str(Img.Height,StrHeight); + end; + PNMInfo:=Concat(MagicWords[useBitMapType],#10,StrWidth,#32,StrHeight,#10); + if useBitMapType in [2,3,5,6] + then + PNMInfo:=Concat(PNMInfo,'255'#10); + stream.seek(0,soFromBeginning); + stream.Write(PNMInfo[1],Length(PNMInfo)); + SaveHeader := true; + end; + var + Row,Coulumn,nBpLine,i:Integer; + aColor:TFPColor; + aLine:PByte; + strCol:String[3]; + LinuxEndOfLine: char; + UseColorDepth: TPNMColorDepth; + + begin + LinuxEndOfLine := #10; + + //determine color depth + if ColorDepth = pcdAuto then + UseColorDepth := GuessColorDepthOfImage(Img) else + UseColorDepth := ColorDepth; + + //determine file format number (1-6) + case UseColorDepth of + pcdBlackWhite: useBitMapType := 1; + pcdGrayscale: useBitMapType := 2; + pcdRGB: useBitMapType := 3; + end; + if BinaryFormat then inc(useBitMapType,3); + + SaveHeader(Stream); + case useBitMapType of + 1:nBpLine:=Img.Width*2;{p p p} + 2:nBpLine:=Img.Width*4;{lll lll lll} + 3:nBpLine:=Img.Width*3*4;{rrr ggg bbb rrr ggg bbb} + 4:nBpLine:=(Img.Width+7) SHR 3; + 5:nBpLine:=Img.Width; + 6:nBpLine:=Img.Width*3; + end; + GetMem(aLine,nBpLine);//3 extra byte for BMP 4Bytes alignement. + for Row:=0 to img.Height-1 do + begin + FillChar(aLine^,nBpLine,0); + for Coulumn:=0 to img.Width-1 do + begin + aColor:=img.Colors[Coulumn,Row]; + with aColor do + case useBitMapType of + 1:begin + if(Red<=$2F00)or(Green<=$2F00)or(Blue<=$2F00) + then + aLine[2*Coulumn]:=Ord('1') + else + aLine[2*Coulumn]:=Ord('0'); + aLine[2*Coulumn+1]:=32; + end; + 2:begin + Str(Hi(Word(Round(Red*0.299+Green*0.587+Blue*0.114))),strCol); + for i:=0 to Length(StrCol)-1 do + aLine[4*Coulumn+i]:=Ord(StrCol[i+1]); + for i:=Length(StrCol) to 4 do + aLine[4*Coulumn+i]:=32; + end; + 3:begin + Str(Hi(Red),strCol); + for i:=0 to Length(StrCol)-1 do + aLine[4*(3*Coulumn)+i]:=Ord(StrCol[i+1]); + for i:=Length(StrCol) to 4 do + aLine[4*(3*Coulumn)+i]:=32; + Str(Hi(Green),strCol); + for i:=0 to Length(StrCol)-1 do + aLine[4*(3*Coulumn+1)+i]:=Ord(StrCol[i+1]); + for i:=Length(StrCol) to 4 do + aLine[4*(3*Coulumn+1)+i]:=32; + Str(Hi(Blue),strCol); + for i:=0 to Length(StrCol)-1 do + aLine[4*(3*Coulumn+2)+i]:=Ord(StrCol[i+1]); + for i:=Length(StrCol) to 4 do + aLine[4*(3*Coulumn+2)+i]:=32; + end; + 4:if(Red<=$2F00)or(Green<=$2F00)or(Blue<=$2F00) + then + aLine[Coulumn shr 3]:=aLine[Coulumn shr 3] or ($80 shr (Coulumn and $07)); + 5:aLine[Coulumn]:=Hi(Word(Round(Red*0.299+Green*0.587+Blue*0.114))); + 6:begin + aLine[3*Coulumn]:=Hi(Red); + aLine[3*Coulumn+1]:=Hi(Green); + aLine[3*Coulumn+2]:=Hi(Blue); + end; + end; + end; + Stream.Write(aLine^,nBpLine); + if useBitMapType in[1..3] then Stream.Write(LinuxEndOfLine,1); + end; + FreeMem(aLine,nBpLine); + end; + +function TFPWriterPNM.GetColorDepthOfExtension(AExtension: string + ): TPNMColorDepth; +begin + if (length(AExtension) > 0) and (AExtension[1]='.') then + delete(AExtension,1,1); + AExtension := LowerCase(AExtension); + if AExtension='pbm' then result := pcdBlackWhite else + if AExtension='pgm' then result := pcdGrayscale else + if AExtension='ppm' then result := pcdRGB else + result := pcdAuto; +end; + +function TFPWriterPNM.GuessColorDepthOfImage(Img: TFPCustomImage): TPNMColorDepth; +var Row, Col: integer; + aColor: TFPColor; +begin + result := pcdBlackWhite; + for Row:=0 to img.Height-1 do + for Col:=0 to img.Width-1 do + begin + aColor:=img.Colors[Col,Row]; + if (AColor.red >= 256) and (AColor.green >= 256) and (AColor.blue >= 256) and + (AColor.red < $FF00) and (AColor.green < $FF00) and (AColor.blue < $FF00) then + begin + if (AColor.red shr 8 <> AColor.Green shr 8) or + (AColor.blue shr 8 <> AColor.Green shr 8) or + (AColor.red shr 8 <> AColor.blue shr 8) then + begin + result := pcdRGB; + exit; + end else + result := pcdGrayscale; + end; + end; +end; + +function TFPWriterPNM.GetFileExtension(AColorDepth: TPNMColorDepth): string; +begin + case AColorDepth of + pcdBlackWhite: result := 'pbm'; + pcdGrayscale: result := 'pgm'; + pcdRGB: result := 'ppm'; + else + result := 'pnm'; + end; +end; + +initialization + ImageHandlers.RegisterImageWriter ('Netpbm Portable aNyMap', 'pnm', TFPWriterPNM); + ImageHandlers.RegisterImageWriter ('Netpbm Portable BitMap', 'pbm', TFPWriterPBM); + ImageHandlers.RegisterImageWriter ('Netpbm Portable GrayMap', 'pgm', TFPWriterPGM); + ImageHandlers.RegisterImageWriter ('Netpbm Portable PixelMap', 'ppm', TFPWriterPPM); +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/fpwritetga.pp b/mseide-msegui/lib/common/fpccompatibility/fpwritetga.pp new file mode 100644 index 0000000..5de3f61 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpwritetga.pp @@ -0,0 +1,101 @@ +{*****************************************************************************} +{ + This file is part of the Free Pascal's "Free Components Library". + Copyright (c) 2003 by Michael Van Canneyt of the Free Pascal development team + + TARGA writer implementation. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +{*****************************************************************************} +{$mode objfpc}{$h+} +unit FPWriteTGA; + +interface + +uses FPImage, classes, sysutils; + +type + + TFPWriterTarga = class (TFPCustomImageWriter) + protected + function SaveHeader(Stream:TStream; Img: TFPCustomImage):boolean; virtual; + procedure InternalWrite (Stream:TStream; Img: TFPCustomImage); override; + end; + + +implementation + +uses targacmn; + +function TFPWriterTarga.SaveHeader(Stream:TStream; Img : TFPCustomImage):boolean; + +var + Header : TTargaHeader; + ID : ShortString; + +begin + Result:=False; + ID:=Img.Extra[KeyIdentification]; + FillChar(Header,SizeOf(Header),0); + With Header do + begin + IDLen:=Length(ID); + MapType:=0; // No colormap. Uncompressed RGB Only. + ImgType:=2; // Uncompressed RGB + MapStart:=FromWord(0); // No data + MapLength:=FromWord(0); // No colormap yet. + MapEntrySize:=0; // No colormap yet. + OriginX:= FromWord(0); + OriginY:=FromWord(0); + Width:=FromWord(Img.Width); + Height:=FromWord(Img.Height); + PixelSize:=24; // BGR data. + Flags:=$20; // Top-town, non interlaced. + end; + Stream.WriteBuffer(Header,SizeOf(Header)); + If Header.IDlen>0 then + Stream.WriteBuffer(Id[1],Header.IDLen); + Result:=true; +end; + +procedure TFPWriterTarga.InternalWrite (Stream:TStream; Img:TFPCustomImage); + +var + Row,Col,WriteSize:Integer; + Aline,P: PByte; + C : TFPColor; + +begin + SaveHeader(Stream,Img); + WriteSize:=Img.Width*3; + GetMem(aLine,WriteSize); + Try + for Row:=0 to Img.Height-1 do + begin + P:=ALine; + For Col:=0 to Img.width-1 do + begin + C:=Img.Colors[Col,Row]; + P^:=C.Blue shr 8; + Inc(P); + P^:=C.Green shr 8; + Inc(P); + P^:=C.Red shr 8; + Inc(P); + end; + Stream.Write(aLine[0],WriteSize); + end; + Finally + FreeMem(aLine); + end; +end; + +initialization + ImageHandlers.RegisterImageWriter ('TARGA Format', 'tga', TFPWriterTarga); +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/fpwritetiff.pas b/mseide-msegui/lib/common/fpccompatibility/fpwritetiff.pas new file mode 100644 index 0000000..b85aa09 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpwritetiff.pas @@ -0,0 +1,903 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 2012 by the Free Pascal development team + + Tiff writer for fpImage. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + ********************************************************************** + + Working: + Grayscale 8,16bit (optional alpha), + RGB 8,16bit (optional alpha), + Orientation, + multiple images, pages + thumbnail + Compression: deflate + + ToDo: + Compression: LZW, packbits, jpeg, ... + Planar + ColorMap + separate mask + fillorder - not needed by baseline tiff reader + bigtiff 64bit offsets + endian - currently using system endianess + orientation with rotation +} +//modified 2013 by Martin Schreiber + +unit fpwritetiff; + +{$ifdef FPC}{$mode objfpc}{$H+}{$endif} + +interface + +uses + math, classes, mclasses, sysutils, fpimage, fptiffcmn,msetypes, + {$ifdef FPC} + zbase, zdeflate + {$else} + zbase_del,zdeflate_del,classes_del + {$endif}; + +type + + { TTiffWriterEntry } + + TTiffWriterEntry = class + public + Tag: Word; + EntryType: Word; + Count: DWord; + Data: Pointer; + DataPos: DWord; + Bytes: DWord; + destructor Destroy; override; + end; + + TTiffWriterChunk = record + Data: Pointer; + Bytes: DWord; + end; + PTiffWriterChunk = ^TTiffWriterChunk; + TiffWriterChunkaty = array[0..0] of TTiffWriterChunk; + pTiffWriterChunkaty = ^TiffWriterChunkaty; + + { TTiffWriterChunkOffsets } + + TTiffWriterChunkOffsets = class(TTiffWriterEntry) + public + Chunks: PTiffWriterChunk; + ChunkByteCounts: TTiffWriterEntry; + constructor Create(ChunkType: TTiffChunkType); + destructor Destroy; override; + procedure SetCount(NewCount: DWord); + end; + + { TFPWriterTiff } + + TFPWriterTiff = class(TFPCustomImageWriter) + private + FSaveCMYKAsRGB: boolean; + fStartPos: Int64; + FEntries: TFPList; // list of TFPList of TTiffWriterEntry + fStream: TStream; + fPosition: DWord; + procedure ClearEntries; + procedure WriteTiff; + procedure WriteHeader; + procedure WriteIFDs; + procedure WriteEntry(Entry: TTiffWriterEntry); + procedure WriteData; + procedure WriteEntryData(Entry: TTiffWriterEntry); + procedure WriteBuf(var Buf; Count: DWord); + procedure WriteWord(w: Word); + procedure WriteDWord(d: DWord); + protected + procedure InternalWrite(Stream: TStream; Img: TFPCustomImage); override; + procedure AddEntryString(Tag: word; const s: string); + procedure AddEntryShort(Tag: word; Value: Word); + procedure AddEntryLong(Tag: word; Value: DWord); + procedure AddEntryShortOrLong(Tag: word; Value: DWord); + procedure AddEntryRational(Tag: word; const Value: TTiffRational); + procedure AddEntry(Tag: Word; EntryType: Word; EntryCount: DWord; + Data: Pointer; Bytes: DWord; + CopyData: boolean = true); overload; + procedure AddEntry(Entry: TTiffWriterEntry); overload; + procedure TiffError(Msg: string); + procedure EncodeDeflate(var Buffer: Pointer; var Count: DWord); + public + constructor Create; override; + destructor Destroy; override; + procedure Clear; + procedure AddImage(Img: TFPCustomImage); + procedure SaveToStream(Stream: TStream); + property SaveCMYKAsRGB: boolean read FSaveCMYKAsRGB write FSaveCMYKAsRGB; + end; + +function CompareTiffWriteEntries(Entry1, Entry2: Pointer): integer; + +function CompressDeflate(InputData: PByte; InputCount: cardinal; + out Compressed: PByte; var CompressedCount: cardinal; + ErrorMsg: PAnsiString = nil): boolean; + +implementation + +function CompareTiffWriteEntries(Entry1, Entry2: Pointer): integer; +begin + Result:=integer(TTiffWriterEntry(Entry1).Tag)-integer(TTiffWriterEntry(Entry2).Tag); +end; + +function CompressDeflate(InputData: PByte; InputCount: cardinal; out + Compressed: PByte; var CompressedCount: cardinal; ErrorMsg: PAnsiString + ): boolean; +var + stream : z_stream; + err : integer; +begin + Result:=false; + //writeln('CompressDeflate START'); + Compressed:=nil; + if InputCount=0 then begin + CompressedCount:=0; + result:= true; + exit; + end; + + err := deflateInit(stream{%H-}, Z_DEFAULT_COMPRESSION); + if err <> Z_OK then begin + if ErrorMsg<>nil then + ErrorMsg^:='deflateInit failed'; + exit; + end; + + // set input = InputData data + stream.avail_in := InputCount; + stream.next_in := InputData; + + // set output = compressed data + if CompressedCount=0 then + CompressedCount:=InputCount; + GetMem(Compressed,CompressedCount); + stream.avail_out := CompressedCount; + stream.next_out := Compressed; + + err := deflate(stream, Z_NO_FLUSH); + if err<>Z_OK then begin + if ErrorMsg<>nil then + ErrorMsg^:='deflate failed'; + exit; + end; + + while TRUE do begin + //writeln('run: total_in=',stream.total_in,' avail_in=',stream.avail_in,' total_out=',stream.total_out,' avail_out=',stream.avail_out); + if (stream.avail_out=0) then begin + // need more space + if CompressedCount<128 then + CompressedCount:=CompressedCount+128 + else if CompressedCount>High(CompressedCount)-1024 then begin + if ErrorMsg<>nil then + ErrorMsg^:='deflate compression failed, because not enough space'; + exit; + end else + CompressedCount:=CompressedCount+1024; + ReAllocMem(Compressed,CompressedCount); + stream.next_out:= pointer(pchar(Compressed)+stream.total_out); + stream.avail_out:= CompressedCount-stream.total_out; + end; + err := deflate(stream, Z_FINISH); + if err = Z_STREAM_END then + break; + if err<>Z_OK then begin + if ErrorMsg<>nil then + ErrorMsg^:='deflate finish failed'; + exit; + end; + end; + + //writeln('compressed: total_in=',stream.total_in,' total_out=',stream.total_out); + CompressedCount:=stream.total_out; + ReAllocMem(Compressed,CompressedCount); + + err := deflateEnd(stream); + if err<>Z_OK then begin + if ErrorMsg<>nil then + ErrorMsg^:='deflateEnd failed'; + exit; + end; + Result:=true; +end; + +{ TFPWriterTiff } + +procedure TFPWriterTiff.WriteWord(w: Word); +begin + if fStream<>nil then + fStream.WriteWord(w); + inc(fPosition,2); +end; + +procedure TFPWriterTiff.WriteDWord(d: DWord); +begin + if fStream<>nil then + fStream.WriteDWord(d); + inc(fPosition,4); +end; + +procedure TFPWriterTiff.ClearEntries; +var + i: Integer; + List: TFPList; + j: Integer; +begin + for i:=FEntries.Count-1 downto 0 do begin + List:=TFPList(FEntries[i]); + for j:=List.Count-1 downto 0 do + TObject(List[j]).Free; + List.Free; + end; + FEntries.Clear; +end; + +procedure TFPWriterTiff.WriteTiff; +begin + {$IFDEF FPC_Debug_Image} + writeln('TFPWriterTiff.WriteTiff fStream=',fStream<>nil); + {$ENDIF} + fPosition:=0; + WriteHeader; + WriteIFDs; + WriteData; +end; + +procedure TFPWriterTiff.WriteHeader; +var + EndianMark: String; +begin + EndianMark:={$IFDEF FPC_BIG_ENDIAN}'MM'{$ELSE}'II'{$ENDIF}; + WriteBuf(EndianMark[1],2); + WriteWord(42); + WriteDWord(8); +end; + +procedure TFPWriterTiff.WriteIFDs; +var + i: Integer; + List: TFPList; + j: Integer; + Entry: TTiffWriterEntry; + NextIFDPos: DWord; +begin + for i:=0 to FEntries.Count-1 do begin + List:=TFPList(FEntries[i]); + // write count + {$IFDEF FPC_Debug_Image} + writeln('TFPWriterTiff.WriteIFDs List=',i,' Count=',List.Count); + {$ENDIF} + WriteWord(List.Count); + // write array of entries + for j:=0 to List.Count-1 do begin + Entry:=TTiffWriterEntry(List[j]); + WriteEntry(Entry); + end; + // write position of next IFD + if i0 then begin + BitsPerSample[SamplesPerPixel]:=AlphaBits; + inc(SamplesPerPixel); + end; + + ImgWidth:=Img.Width; + ImgHeight:=Img.Height; + Compression:=IFD.Compression; + case Compression of + TiffCompressionNone, + TiffCompressionDeflateZLib: ; + else + {$ifdef FPC_DEBUG_IMAGE} + writeln('TFPWriterTiff.AddImage unsupported compression '+TiffCompressionName(Compression)+', using deflate instead.'); + {$endif} + Compression:=TiffCompressionDeflateZLib; + end; + + if IFD.Orientation in [1..4] then begin + OrientedWidth:=ImgWidth; + OrientedHeight:=ImgHeight; + end else begin + // rotated + OrientedWidth:=ImgHeight; + OrientedHeight:=ImgWidth; + end; + + {$IFDEF FPC_Debug_Image} + writeln('TFPWriterTiff.AddImage PhotoMetricInterpretation=',IFD.PhotoMetricInterpretation); + writeln('TFPWriterTiff.AddImage ImageWidth=',ImgWidth,' ImageHeight=',ImgHeight); + writeln('TFPWriterTiff.AddImage Orientation=',IFD.Orientation); + writeln('TFPWriterTiff.AddImage ResolutionUnit=',IFD.ResolutionUnit); + writeln('TFPWriterTiff.AddImage XResolution=',TiffRationalToStr(IFD.XResolution)); + writeln('TFPWriterTiff.AddImage YResolution=',TiffRationalToStr(IFD.YResolution)); + writeln('TFPWriterTiff.AddImage GrayBits=',GrayBits,' RedBits=',RedBits,' GreenBits=',GreenBits,' BlueBits=',BlueBits,' AlphaBits=',AlphaBits); + writeln('TFPWriterTiff.AddImage Compression=',TiffCompressionName(Compression)); + writeln('TFPWriterTiff.AddImage Page=',IFD.PageNumber,'/',IFD.PageCount); + {$ENDIF} + + // required meta entries + AddEntryShortOrLong(256,ImgWidth); + AddEntryShortOrLong(257,ImgHeight); + AddEntryShort(259,Compression); + AddEntryShort(262,IFD.PhotoMetricInterpretation); + AddEntryShort(274,IFD.Orientation); + AddEntryShort(296,IFD.ResolutionUnit); + AddEntryRational(282,IFD.XResolution); + AddEntryRational(283,IFD.YResolution); + if AlphaBits>0 then begin + // ExtraSamples + AddEntryShort(338,2);// 2=unassociated alpha + end; + // BitsPerSample (required) + AddEntry(258,3,SamplesPerPixel,@BitsPerSample[0],SamplesPerPixel*2); + AddEntryShort(277,SamplesPerPixel); + + // BitsPerPixel, BytesPerLine + BitsPerPixel:=0; + for i:=0 to SamplesPerPixel-1 do + inc(BitsPerPixel,BitsPerSample[i]); + BytesPerLine:=(BitsPerPixel*OrientedWidth+7) div 8; + + // optional entries + NewSubFileType:=0; + if IFD.ImageIsThumbNail then inc(NewSubFileType,1); + if IFD.ImageIsPage then inc(NewSubFileType,2); + if IFD.ImageIsMask then inc(NewSubFileType,4); + if NewSubFileType>0 then + AddEntryLong(254,NewSubFileType); + if IFD.DocumentName<>'' then + AddEntryString(269,IFD.DocumentName); + if IFD.ImageDescription<>'' then + AddEntryString(270,IFD.ImageDescription); + if IFD.Make_ScannerManufacturer<>'' then + AddEntryString(271,IFD.Make_ScannerManufacturer); + if IFD.Model_Scanner<>'' then + AddEntryString(272,IFD.Model_Scanner); + if IFD.Software<>'' then + AddEntryString(305,IFD.Software); + if IFD.DateAndTime<>'' then + AddEntryString(306,IFD.DateAndTime); + if IFD.Artist<>'' then + AddEntryString(315,IFD.Artist); + if IFD.HostComputer<>'' then + AddEntryString(316,IFD.HostComputer); + if IFD.PageCount>0 then begin + Shorts[0]:=IFD.PageNumber; + Shorts[1]:=IFD.PageCount; + AddEntry(297,3,2,@Shorts[0],2*SizeOf(Word)); + end; + if IFD.PageName<>'' then + AddEntryString(285,IFD.PageName); + if IFD.Copyright<>'' then + AddEntryString(33432,IFD.Copyright); + + // chunks + ChunkType:=tctStrip; + if IFD.TileWidth>0 then begin + AddEntryShortOrLong(322,IFD.TileWidth); + AddEntryShortOrLong(323,IFD.TileLength); + ChunkType:=tctTile; + end else begin + // RowsPerStrip (required) + if OrientedWidth=0 then + IFD.RowsPerStrip:=8 + else + IFD.RowsPerStrip:=8192 div BytesPerLine; + if IFD.RowsPerStrip<1 then + IFD.RowsPerStrip:=1; + {$IFDEF FPC_Debug_Image} + writeln('TFPWriterTiff.AddImage BitsPerPixel=',BitsPerPixel,' OrientedWidth=',OrientedWidth,' BytesPerLine=',BytesPerLine,' RowsPerStrip=',IFD.RowsPerStrip); + {$ENDIF} + AddEntryShortOrLong(278,IFD.RowsPerStrip); + end; + + // tags for Offsets and ByteCounts + ChunkOffsets:=TTiffWriterChunkOffsets.Create(ChunkType); + AddEntry(ChunkOffsets); + AddEntry(ChunkOffsets.ChunkByteCounts); + if (OrientedHeight>0) and (OrientedWidth>0) then begin + if ChunkType=tctTile then begin + TilesAcross:=(OrientedWidth+IFD.TileWidth{%H-}-1) div IFD.TileWidth; + TilesDown:=(OrientedHeight+IFD.TileLength{%H-}-1) div IFD.TileLength; + ChunkCount:=TilesAcross*TilesDown; + {$IFDEF FPC_Debug_Image} + writeln('TFPWriterTiff.AddImage BitsPerPixel=',BitsPerPixel,' OrientedWidth=',OrientedWidth,' OrientedHeight=',OrientedHeight,' TileWidth=',IFD.TileWidth,' TileLength=',IFD.TileLength,' TilesAcross=',TilesAcross,' TilesDown=',TilesDown,' ChunkCount=',ChunkCount); + {$ENDIF} + end else begin + ChunkCount:=(OrientedHeight+IFD.RowsPerStrip{%H-}-1) div IFD.RowsPerStrip; + end; + ChunkOffsets.SetCount(ChunkCount); + // create chunks + for ChunkIndex:=0 to ChunkCount-1 do begin + if ChunkType=tctTile then begin + ChunkLeft:=(ChunkIndex mod TilesAcross)*IFD.TileWidth; + ChunkTop:=(ChunkIndex div TilesAcross)*IFD.TileLength; + ChunkWidth:=Min(IFD.TileWidth,OrientedWidth-ChunkLeft); + ChunkHeight:=Min(IFD.TileLength,OrientedHeight-ChunkTop); + // boundary tiles are padded to a full tile + // the padding is filled with 0 and compression will get rid of it + ChunkBytesPerLine:=(BitsPerPixel*IFD.TileWidth+7) div 8; + ChunkBytes:=ChunkBytesPerLine*IFD.TileLength; + end else begin + ChunkLeft:=0; + ChunkTop:=IFD.RowsPerStrip*ChunkIndex; + ChunkWidth:=OrientedWidth; + ChunkHeight:=Min(IFD.RowsPerStrip,OrientedHeight-ChunkTop); + ChunkBytesPerLine:=BytesPerLine; + ChunkBytes:=ChunkBytesPerLine*ChunkHeight; + end; + GetMem(Chunk,ChunkBytes); + {$ifdef FPC} + FillByte(Chunk^,ChunkBytes,0); // fill unused bytes with 0 to help compression + {$else} + Fillchar(Chunk^,ChunkBytes,0); // fill unused bytes with 0 to help compression + {$endif} + // Orientation + if IFD.Orientation in [1..4] then begin + x:=ChunkLeft; y:=ChunkTop; + case IFD.Orientation of + 1: begin dx:=1; dy:=1; end;// 0,0 is left, top + 2: begin x:=OrientedWidth-x-1; dx:=-1; dy:=1; end;// 0,0 is right, top + 3: begin x:=OrientedWidth-x-1; dx:=-1; y:=OrientedHeight-y-1; dy:=-1; end;// 0,0 is right, bottom + 4: begin dx:=1; y:=OrientedHeight-y-1; dy:=-1; end;// 0,0 is left, bottom + end; + end else begin + // rotated + x:=ChunkTop; y:=ChunkLeft; + case IFD.Orientation of + 5: begin dx:=1; dy:=1; end;// 0,0 is top, left (rotated) + 6: begin dx:=1; y:=OrientedWidth-y-1; dy:=-1; end;// 0,0 is top, right (rotated) + 7: begin x:=OrientedHeight-x-1; dx:=-1; y:=OrientedWidth-y-1; dy:=-1; end;// 0,0 is bottom, right (rotated) + 8: begin x:=OrientedHeight-x-1; dx:=-1; dy:=1; end;// 0,0 is bottom, left (rotated) + end; + end; + //writeln('TFPWriterTiff.AddImage Chunk=',ChunkIndex,'/',ChunkCount,' ChunkBytes=',ChunkBytes,' ChunkRect=',ChunkLeft,',',ChunkTop,',',ChunkWidth,'x',ChunkHeight,' x=',x,' y=',y,' dx=',dx,' dy=',dy); + sx:=x; // save start x + for cy:=0 to ChunkHeight-1 do begin + x:=sx; + Run:= pointer(pchar(Chunk)+cy*ChunkBytesPerLine); + for cx:=0 to ChunkWidth-1 do begin + Col:=Img.Colors[x,y]; + case IFD.PhotoMetricInterpretation of + 0,1: + begin + // grayscale + Value:=(DWord(Col.red)+Col.green+Col.blue) div 3; + if IFD.PhotoMetricInterpretation=0 then + Value:=$ffff-Value;// 0 is white + if GrayBits=8 then begin + Run^:=Value shr 8; + inc(Run); + end else if GrayBits=16 then begin + PWord(Run)^:=Value; + inc(Run,2); + end; + if AlphaBits=8 then begin + Run^:=Col.alpha shr 8; + inc(Run); + end else if AlphaBits=16 then begin + PWord(Run)^:=Col.alpha; + inc(Run,2); + end; + end; + 2: + begin + // RGB + if RedBits=8 then begin + Run^:=Col.red shr 8; + inc(Run); + end else if RedBits=16 then begin + PWord(Run)^:=Col.red; + inc(Run,2); + end; + if GreenBits=8 then begin + Run^:=Col.green shr 8; + inc(Run); + end else if GreenBits=16 then begin + PWord(Run)^:=Col.green; + inc(Run,2); + end; + if BlueBits=8 then begin + Run^:=Col.blue shr 8; + inc(Run); + end else if BlueBits=16 then begin + PWord(Run)^:=Col.blue; + inc(Run,2); + end; + if AlphaBits=8 then begin + Run^:=Col.alpha shr 8; + inc(Run); + end else if AlphaBits=16 then begin + PWord(Run)^:=Col.alpha; + inc(Run,2); + end; + end; + end; + // next x + inc(x,dx); + end; + // next y + inc(y,dy); + end; + + // compress + case Compression of + TiffCompressionDeflateZLib: EncodeDeflate(pointer(Chunk),ChunkBytes); + end; + + pTiffWriterChunkaty(ChunkOffsets.Chunks)^[ChunkIndex].Data:=Chunk; + pTiffWriterChunkaty(ChunkOffsets.Chunks)^[ChunkIndex].Bytes:=ChunkBytes; + // next chunk + end; + // created chunks + end; + + CurEntries.Sort(@CompareTiffWriteEntries); + finally + IFD.Free; + end; +end; + +procedure TFPWriterTiff.SaveToStream(Stream: TStream); +begin + fStartPos:=Stream.Position; + // simulate write to compute offsets + fStream:=nil; + WriteTiff; + // write to stream + fStream:=Stream; + WriteTiff; + fStream:=nil; +end; + +procedure TFPWriterTiff.InternalWrite(Stream: TStream; Img: TFPCustomImage); +begin + AddImage(Img); + SaveToStream(Stream); +end; + +procedure TFPWriterTiff.AddEntryString(Tag: word; const s: string); +begin + if s<>'' then + AddEntry(Tag,2,length(s)+1,@s[1],length(s)+1) + else + AddEntry(Tag,2,0,nil,0); +end; + +procedure TFPWriterTiff.AddEntryShort(Tag: word; Value: Word); +begin + AddEntry(Tag,3,1,@Value,2); +end; + +procedure TFPWriterTiff.AddEntryLong(Tag: word; Value: DWord); +begin + AddEntry(Tag,4,1,@Value,4); +end; + +procedure TFPWriterTiff.AddEntryShortOrLong(Tag: word; Value: DWord); +begin + if Value<=High(Word) then + AddEntryShort(Tag,Value) + else + AddEntryLong(Tag,Value); +end; + +procedure TFPWriterTiff.AddEntryRational(Tag: word; const Value: TTiffRational + ); +begin + AddEntry(Tag,5,1,@Value,8); +end; + +procedure TFPWriterTiff.AddEntry(Tag: Word; EntryType: Word; EntryCount: DWord; + Data: Pointer; Bytes: DWord; CopyData: boolean); +var + Entry: TTiffWriterEntry; +begin + Entry:=TTiffWriterEntry.Create; + Entry.Tag:=Tag; + Entry.EntryType:=EntryType; + Entry.Count:=EntryCount; + if CopyData then begin + if Bytes>0 then begin + GetMem(Entry.Data,Bytes); + System.Move(Data^,Entry.Data^,Bytes); + end else begin + Entry.Data:=nil; + end; + end else + Entry.Data:=Data; + Entry.Bytes:=Bytes; + AddEntry(Entry); +end; + +procedure TFPWriterTiff.AddEntry(Entry: TTiffWriterEntry); +var + List: TFPList; +begin + List:=TFPList(FEntries[FEntries.Count-1]); + List.Add(Entry); +end; + +procedure TFPWriterTiff.TiffError(Msg: string); +begin + raise Exception.Create('TFPWriterTiff.TiffError: '+Msg); +end; + +procedure TFPWriterTiff.EncodeDeflate(var Buffer: Pointer; var Count: DWord); +var + NewBuffer: PByte; + NewCount: cardinal; + ErrorMsg: String; +begin + ErrorMsg:=''; + NewBuffer:=nil; + try + NewCount:=Count; + if not CompressDeflate(Buffer,Count,NewBuffer,NewCount,@ErrorMsg) then + TiffError(ErrorMsg); + FreeMem(Buffer); + Buffer:=NewBuffer; + Count:=NewCount; + NewBuffer:=nil; + finally + ReAllocMem(NewBuffer,0); + end; +end; + +constructor TFPWriterTiff.Create; +begin + inherited Create; + FEntries:=TFPList.Create; + FSaveCMYKAsRGB:=true; +end; + +destructor TFPWriterTiff.Destroy; +begin + Clear; + FreeAndNil(FEntries); + inherited Destroy; +end; + +procedure TFPWriterTiff.Clear; +begin + ClearEntries; +end; + +{ TTiffWriterEntry } + +destructor TTiffWriterEntry.Destroy; +begin + ReAllocMem(Data,0); + inherited Destroy; +end; + +{ TTiffWriterChunkOffsets } + +constructor TTiffWriterChunkOffsets.Create(ChunkType: TTiffChunkType); +begin + EntryType:=4; // long + ChunkByteCounts:=TTiffWriterEntry.Create; + ChunkByteCounts.EntryType:=4; // long + if ChunkType=tctTile then begin + Tag:=324; // TileOffsets + ChunkByteCounts.Tag:=325; // TileByteCounts + end else begin + Tag:=273; // StripOffsets + ChunkByteCounts.Tag:=279; // StripByteCounts + end; +end; + +destructor TTiffWriterChunkOffsets.Destroy; +var + i: Integer; +begin + if Chunks<>nil then begin + for i:=0 to Count-1 do + ReAllocMem(pTiffWriterChunkaty(Chunks)^[i].Data,0); + ReAllocMem(Chunks,0); + end; + inherited Destroy; +end; + +procedure TTiffWriterChunkOffsets.SetCount(NewCount: DWord); +var + Size: DWord; +begin + {$IFDEF FPC_Debug_Image} + writeln('TTiffWriteStripOffsets.SetCount OldCount=',Count,' NewCount=',NewCount); + {$ENDIF} + Count:=NewCount; + Size:=Count*SizeOf(TTiffWriterChunk); + ReAllocMem(Chunks,Size); + {$ifdef FPC} + if Size>0 then FillByte(Chunks^,Size,0); + {$else} + if Size>0 then Fillchar(Chunks^,Size,0); + {$endif} + Size:=Count*SizeOf(DWord); + // Offsets + ReAllocMem(Data,Size); + {$ifdef FPC} + if Size>0 then FillByte(Data^,Size,0); + {$else} + if Size>0 then Fillchar(Data^,Size,0); + {$endif} + Bytes:=Size; + // ByteCounts + ReAllocMem(ChunkByteCounts.Data,Size); + {$ifdef FPC} + if Size>0 then FillByte(ChunkByteCounts.Data^,Size,0); + {$else} + if Size>0 then Fillchar(ChunkByteCounts.Data^,Size,0); + {$endif} + ChunkByteCounts.Count:=Count; + ChunkByteCounts.Bytes:=Size; +end; + +initialization + if ImageHandlers.ImageWriter[TiffHandlerName]=nil then + ImageHandlers.RegisterImageWriter (TiffHandlerName, 'tif;tiff', TFPWriterTiff); +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/fpwritexpm.pp b/mseide-msegui/lib/common/fpccompatibility/fpwritexpm.pp new file mode 100644 index 0000000..2935535 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/fpwritexpm.pp @@ -0,0 +1,173 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 2003 by the Free Pascal development team + + XPM writer implementation. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + **********************************************************************} +{$mode objfpc}{$h+} +unit FPWriteXPM; + +interface + +uses FPImage, classes, sysutils; + +type + + TFPWriterXPM = class (TFPCustomImageWriter) + private + FPalChars : string; + FColorFormat : string; + FColorShift : word; + FColorSize : byte; + procedure SetColorSize (AValue : byte); + function ColorToHex (c:TFPColor) : string; + protected + procedure InternalWrite (Str:TStream; Img:TFPCustomImage); override; + public + constructor Create; override; + property PalChars : string read FPalChars write FPalChars; + property ColorCharSize : byte read FColorSize write SetColorSize; + // number of characters to use for 1 colorcomponent + end; + + +implementation + +const + DefPalChars = '.,-*abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@#;:=+%$()[]'; + +constructor TFPWriterXPM.create; +begin + inherited create; + PalChars := DefPalChars; + FColorSize := 4; +end; + +procedure TFPWriterXPM.SetColorSize (AValue : byte); +begin + if AValue > 3 then + FColorSize := 4 + else if AValue = 0 then + FColorSize := 1 + else + FColorSize := AValue; +end; + +function TFPWriterXPM.ColorToHex (c:TFPColor) : string; +var r,g,b : word; +begin + with c do + begin + r := red shr FColorShift; + g := green shr FColorShift; + b := blue shr FColorShift; + end; + result := format(FColorFormat,[r,g,b]); +end; + +procedure TFPWriterXPM.InternalWrite (Str:TStream; Img:TFPCustomImage); +var p, l : TStringList; + c, len, r, t : integer; + TmpPalette, Palette: TFPPalette; + procedure BuildPaletteStrings; + var r,c,e : integer; + procedure MakeCodes (const head:string; charplace:integer); + var r : integer; + begin + r := 1; + dec (charplace); + while (r <= e) and (c >= 0) do + begin + if Charplace > 0 then + MakeCodes (head+PalChars[r],charplace) + else begin + p.Add (head+PalChars[r]); + dec(c); + end; + inc (r); + end; + end; + begin + // Calculate length of codes + len := 1; + e := length(PalChars); + r := e; + c := Palette.count; + while (r <= c) do + begin + inc (len); + r := r * e; + end; + MakeCodes ('',len); + end; + procedure InitConsts; + var fmt : string; + begin + fmt := inttostr(FColorSize); + fmt := '%'+fmt+'.'+fmt+'x'; + FColorFormat := fmt+fmt+fmt; + case FColorSize of + 1 : FColorShift := 12; + 2 : FColorShift := 8; + 3 : FColorShift := 4; + else FColorShift := 0; + end; + end; +var s : string; +begin + l := TStringList.Create; + p := TStringList.Create; + TmpPalette := nil; + try + l.Add ('/* XPM */'); + l.Add ('static char *graphic[] = {'); + Palette := img.palette; + if not Assigned(Palette) then begin + TmpPalette := TFPPalette.Create(0); + TmpPalette.Build(Img); + Palette := TmpPalette; + end; + c := Palette.count; + BuildPaletteStrings; + l.add (format('"%d %d %d %d",',[img.width,img.height,c,len])); + InitConsts; + for r := 0 to c-1 do + begin + if Palette[r] <> colTransparent then + l.Add (format('"%s c #%s",',[p[r],ColorToHex(Palette.color[r])])) + else + l.Add (format('"%s c None",',[p[r]])); + end; + for r := 0 to img.Height-1 do + begin + s := ''; + for t := 0 to img.Width-1 do + if Assigned(TmpPalette) then + s := s + p[TmpPalette.IndexOf(img.Colors[t,r])] + else + s := s + p[img.pixels[t,r]]; + s := '"'+s+'"'; + if r < img.Height-1 then + s := s + ','; + l.Add (s); + end; + l.Add ('};'); + finally + TmpPalette.Free; + l.SaveToStream (Str); + p.Free; + l.Free; + end; +end; + +initialization + ImageHandlers.RegisterImageWriter ('XPM Format', 'xpm', TFPWriterXPM); +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/getstrfromint.inc b/mseide-msegui/lib/common/fpccompatibility/getstrfromint.inc new file mode 100644 index 0000000..4e3dc79 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/getstrfromint.inc @@ -0,0 +1,38 @@ + if Width <= 0 then + exit; + + NegSign := Val < 0; + Val := Abs(Val); + // we'll have to store characters backwards first + I := 0; + repeat + Temp[I] := Chr((Val mod 10) + Ord('0')); + Val := Val div 10; + Inc(I); + until (Val = 0) or (I = Width); + // add spaces + J := Width - I; + FillChar(Dst^, J, PadChar); + // add sign + if NegSign then + begin + if PadChar = '0' then + begin + Dst[0] := '-'; + end else begin + if J = 0 then + begin + // need one character for sign, shorten + Inc(J); + Dec(I); + end; + Dst[J - 1] := '-'; + end; + end; + // copy value, stored backwards + repeat + Dec(I); + Dst[J] := Temp[I]; + Inc(J); + until I = 0; + // done! diff --git a/mseide-msegui/lib/common/fpccompatibility/jcapimin_del.pas b/mseide-msegui/lib/common/fpccompatibility/jcapimin_del.pas new file mode 100644 index 0000000..9043f2a --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jcapimin_del.pas @@ -0,0 +1,402 @@ +Unit jcapimin_del; +//{$N+} +{ This file contains application interface code for the compression half + of the JPEG library. These are the "minimum" API routines that may be + needed in either the normal full-compression case or the transcoding-only + case. + + Most of the routines intended to be called directly by an application + are in this file or in jcapistd.c. But also see jcparam.c for + parameter-setup helper routines, jcomapi.c for routines shared by + compression and decompression, and jctrans.c for the transcoding case. } + +{ jcapimin.c ; Copyright (C) 1994-1998, Thomas G. Lane. } + +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jdeferr_del, + jerror_del, + jpeglib_del, + jcomapi_del, + jmemmgr_del, + jcmarker_del; + +{ Initialization of JPEG compression objects. + Nomssi: This is a macro in the original code. + + jpeg_create_compress() and jpeg_create_decompress() are the exported + names that applications should call. These expand to calls on + jpeg_CreateCompress and jpeg_CreateDecompress with additional information + passed for version mismatch checking. + NB: you must set up the error-manager BEFORE calling jpeg_create_xxx. } + +procedure jpeg_create_compress(cinfo : j_compress_ptr); + + +{ Initialization of a JPEG compression object. + The error manager must already be set up (in case memory manager fails). } + +{GLOBAL} +procedure jpeg_CreateCompress (cinfo : j_compress_ptr; + version : int; + structsize : size_t); + +{ Destruction of a JPEG compression object } + +{GLOBAL} +procedure jpeg_destroy_compress (cinfo : j_compress_ptr); + + +{ Abort processing of a JPEG compression operation, + but don't destroy the object itself. } + +{GLOBAL} +procedure jpeg_abort_compress (cinfo : j_compress_ptr); + + +{ Forcibly suppress or un-suppress all quantization and Huffman tables. + Marks all currently defined tables as already written (if suppress) + or not written (if !suppress). This will control whether they get emitted + by a subsequent jpeg_start_compress call. + + This routine is exported for use by applications that want to produce + abbreviated JPEG datastreams. It logically belongs in jcparam.c, but + since it is called by jpeg_start_compress, we put it here --- otherwise + jcparam.o would be linked whether the application used it or not. } + +{GLOBAL} +procedure jpeg_suppress_tables (cinfo : j_compress_ptr; + suppress : boolean); + + +{ Finish JPEG compression. + + If a multipass operating mode was selected, this may do a great deal of + work including most of the actual output. } + +{GLOBAL} +procedure jpeg_finish_compress (cinfo : j_compress_ptr); + +{ Write a special marker. + This is only recommended for writing COM or APPn markers. + Must be called after jpeg_start_compress() and before + first call to jpeg_write_scanlines() or jpeg_write_raw_data(). } + +{GLOBAL} +procedure jpeg_write_marker (cinfo : j_compress_ptr; + marker : int; + dataptr : JOCTETptr; + datalen : uInt); + +{GLOBAL} +procedure jpeg_write_m_header (cinfo : j_compress_ptr; + marker : int; + datalen : uint); +{GLOBAL} +procedure jpeg_write_m_byte (cinfo : j_compress_ptr; val : int); + +{ Alternate compression function: just write an abbreviated table file. + Before calling this, all parameters and a data destination must be set up. + + To produce a pair of files containing abbreviated tables and abbreviated + image data, one would proceed as follows: + + initialize JPEG object + set JPEG parameters + set destination to table file + jpeg_write_tables(cinfo); + set destination to image file + jpeg_start_compress(cinfo, FALSE); + write data... + jpeg_finish_compress(cinfo); + + jpeg_write_tables has the side effect of marking all tables written + (same as jpeg_suppress_tables(..., TRUE)). Thus a subsequent start_compress + will not re-emit the tables unless it is passed write_all_tables=TRUE. } + + + +{GLOBAL} +procedure jpeg_write_tables (cinfo : j_compress_ptr); + +implementation + +procedure jpeg_create_compress(cinfo : j_compress_ptr); +begin + jpeg_CreateCompress(cinfo, JPEG_LIB_VERSION, + size_t(sizeof(jpeg_compress_struct))); +end; + +{ Initialization of a JPEG compression object. + The error manager must already be set up (in case memory manager fails). } + +{GLOBAL} +procedure jpeg_CreateCompress (cinfo : j_compress_ptr; + version : int; + structsize : size_t); +var + i : int; +var + err : jpeg_error_mgr_ptr; +// client_data : voidp; +begin + + { Guard against version mismatches between library and caller. } + cinfo^.mem := NIL; { so jpeg_destroy knows mem mgr not called } + if (version <> JPEG_LIB_VERSION) then + ERREXIT2(j_common_ptr(cinfo), JERR_BAD_LIB_VERSION, JPEG_LIB_VERSION, version); + if (structsize <> SIZEOF(jpeg_compress_struct)) then + ERREXIT2(j_common_ptr(cinfo), JERR_BAD_STRUCT_SIZE, + int(SIZEOF(jpeg_compress_struct)), int(structsize)); + + { For debugging purposes, we zero the whole master structure. + But the application has already set the err pointer, and may have set + client_data, so we have to save and restore those fields. + Note: if application hasn't set client_data, tools like Purify may + complain here. } + + err := cinfo^.err; +// client_data := cinfo^.client_data; { ignore Purify complaint here } + MEMZERO(cinfo, SIZEOF(jpeg_compress_struct)); + cinfo^.err := err; + cinfo^.is_decompressor := FALSE; + + { Initialize a memory manager instance for this object } + jinit_memory_mgr(j_common_ptr(cinfo)); + + { Zero out pointers to permanent structures. } + cinfo^.progress := NIL; + cinfo^.dest := NIL; + + cinfo^.comp_info := NIL; + + for i := 0 to pred(NUM_QUANT_TBLS) do + cinfo^.quant_tbl_ptrs[i] := NIL; + + for i := 0 to pred(NUM_HUFF_TBLS) do + begin + cinfo^.dc_huff_tbl_ptrs[i] := NIL; + cinfo^.ac_huff_tbl_ptrs[i] := NIL; + end; + + cinfo^.script_space := NIL; + + cinfo^.input_gamma := 1.0; { in case application forgets } + + { OK, I'm ready } + cinfo^.global_state := CSTATE_START; +end; + + +{ Destruction of a JPEG compression object } + +{GLOBAL} +procedure jpeg_destroy_compress (cinfo : j_compress_ptr); +begin + jpeg_destroy(j_common_ptr(cinfo)); { use common routine } +end; + + +{ Abort processing of a JPEG compression operation, + but don't destroy the object itself. } + +{GLOBAL} +procedure jpeg_abort_compress (cinfo : j_compress_ptr); +begin + jpeg_abort(j_common_ptr(cinfo)); { use common routine } +end; + + +{ Forcibly suppress or un-suppress all quantization and Huffman tables. + Marks all currently defined tables as already written (if suppress) + or not written (if !suppress). This will control whether they get emitted + by a subsequent jpeg_start_compress call. + + This routine is exported for use by applications that want to produce + abbreviated JPEG datastreams. It logically belongs in jcparam.c, but + since it is called by jpeg_start_compress, we put it here --- otherwise + jcparam.o would be linked whether the application used it or not. } + +{GLOBAL} +procedure jpeg_suppress_tables (cinfo : j_compress_ptr; + suppress : boolean); +var + i : int; + qtbl : JQUANT_TBL_PTR; + htbl : JHUFF_TBL_PTR; +begin + for i := 0 to pred(NUM_QUANT_TBLS) do + begin + qtbl := cinfo^.quant_tbl_ptrs[i]; + if (qtbl <> NIL) then + qtbl^.sent_table := suppress; + end; + + for i := 0 to pred(NUM_HUFF_TBLS) do + begin + htbl := cinfo^.dc_huff_tbl_ptrs[i]; + if (htbl <> NIL) then + htbl^.sent_table := suppress; + htbl := cinfo^.ac_huff_tbl_ptrs[i]; + if (htbl <> NIL) then + htbl^.sent_table := suppress; + end; +end; + + +{ Finish JPEG compression. + + If a multipass operating mode was selected, this may do a great deal of + work including most of the actual output. } + +{GLOBAL} +procedure jpeg_finish_compress (cinfo : j_compress_ptr); +var + iMCU_row : JDIMENSION; +begin + if (cinfo^.global_state = CSTATE_SCANNING) or + (cinfo^.global_state = CSTATE_RAW_OK) then + begin + { Terminate first pass } + if (cinfo^.next_scanline < cinfo^.image_height) then + ERREXIT(j_common_ptr(cinfo), JERR_TOO_LITTLE_DATA); + cinfo^.master^.finish_pass (cinfo); + end + else + if (cinfo^.global_state <> CSTATE_WRCOEFS) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + { Perform any remaining passes } + while (not cinfo^.master^.is_last_pass) do + begin + cinfo^.master^.prepare_for_pass (cinfo); + for iMCU_row := 0 to pred(cinfo^.total_iMCU_rows) do + begin + if (cinfo^.progress <> NIL) then + begin + cinfo^.progress^.pass_counter := long (iMCU_row); + cinfo^.progress^.pass_limit := long (cinfo^.total_iMCU_rows); + cinfo^.progress^.progress_monitor (j_common_ptr(cinfo)); + end; + { We bypass the main controller and invoke coef controller directly; + all work is being done from the coefficient buffer. } + + if (not cinfo^.coef^.compress_data (cinfo, JSAMPIMAGE(NIL))) then + ERREXIT(j_common_ptr(cinfo), JERR_CANT_SUSPEND); + end; + cinfo^.master^.finish_pass (cinfo); + end; + { Write EOI, do final cleanup } + cinfo^.marker^.write_file_trailer (cinfo); + cinfo^.dest^.term_destination (cinfo); + { We can use jpeg_abort to release memory and reset global_state } + jpeg_abort(j_common_ptr(cinfo)); +end; + + +{ Write a special marker. + This is only recommended for writing COM or APPn markers. + Must be called after jpeg_start_compress() and before + first call to jpeg_write_scanlines() or jpeg_write_raw_data(). } + +{GLOBAL} +procedure jpeg_write_marker (cinfo : j_compress_ptr; + marker : int; + dataptr : JOCTETptr; + datalen : uInt); +var + write_marker_byte : procedure(info : j_compress_ptr; val : int); +begin + if (cinfo^.next_scanline <> 0) or + ((cinfo^.global_state <> CSTATE_SCANNING) and + (cinfo^.global_state <> CSTATE_RAW_OK) and + (cinfo^.global_state <> CSTATE_WRCOEFS)) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + + cinfo^.marker^.write_marker_header (cinfo, marker, datalen); + write_marker_byte := cinfo^.marker^.write_marker_byte; { copy for speed } + while (datalen <> 0) do + begin + Dec(datalen); + write_marker_byte (cinfo, dataptr^); + Inc(dataptr); + end; +end; + +{ Same, but piecemeal. } + +{GLOBAL} +procedure jpeg_write_m_header (cinfo : j_compress_ptr; + marker : int; + datalen : uint); +begin + if (cinfo^.next_scanline <> 0) or + ((cinfo^.global_state <> CSTATE_SCANNING) and + (cinfo^.global_state <> CSTATE_RAW_OK) and + (cinfo^.global_state <> CSTATE_WRCOEFS)) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + + cinfo^.marker^.write_marker_header (cinfo, marker, datalen); +end; + +{GLOBAL} +procedure jpeg_write_m_byte (cinfo : j_compress_ptr; val : int); +begin + cinfo^.marker^.write_marker_byte (cinfo, val); +end; + + +{ Alternate compression function: just write an abbreviated table file. + Before calling this, all parameters and a data destination must be set up. + + To produce a pair of files containing abbreviated tables and abbreviated + image data, one would proceed as follows: + + initialize JPEG object + set JPEG parameters + set destination to table file + jpeg_write_tables(cinfo); + set destination to image file + jpeg_start_compress(cinfo, FALSE); + write data... + jpeg_finish_compress(cinfo); + + jpeg_write_tables has the side effect of marking all tables written + (same as jpeg_suppress_tables(..., TRUE)). Thus a subsequent start_compress + will not re-emit the tables unless it is passed write_all_tables=TRUE. } + +{GLOBAL} +procedure jpeg_write_tables (cinfo : j_compress_ptr); +begin + if (cinfo^.global_state <> CSTATE_START) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + + { (Re)initialize error mgr and destination modules } + cinfo^.err^.reset_error_mgr (j_common_ptr(cinfo)); + cinfo^.dest^.init_destination (cinfo); + { Initialize the marker writer ... bit of a crock to do it here. } + jinit_marker_writer(cinfo); + { Write them tables! } + cinfo^.marker^.write_tables_only (cinfo); + { And clean up. } + cinfo^.dest^.term_destination (cinfo); + + { In library releases up through v6a, we called jpeg_abort() here to free + any working memory allocated by the destination manager and marker + writer. Some applications had a problem with that: they allocated space + of their own from the library memory manager, and didn't want it to go + away during write_tables. So now we do nothing. This will cause a + memory leak if an app calls write_tables repeatedly without doing a full + compression cycle or otherwise resetting the JPEG object. However, that + seems less bad than unexpectedly freeing memory in the normal case. + An app that prefers the old behavior can call jpeg_abort for itself after + each call to jpeg_write_tables(). } +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jcapistd_del.pas b/mseide-msegui/lib/common/fpccompatibility/jcapistd_del.pas new file mode 100644 index 0000000..2b16875 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jcapistd_del.pas @@ -0,0 +1,224 @@ +Unit jcapistd_del; + +{ Original : jcapistd.c ; Copyright (C) 1994-1996, Thomas G. Lane. } + +{ This file is part of the Independent JPEG Group's software. + For conditions of distribution and use, see the accompanying README file. + + This file contains application interface code for the compression half + of the JPEG library. These are the "standard" API routines that are + used in the normal full-compression case. They are not used by a + transcoding-only application. Note that if an application links in + jpeg_start_compress, it will end up linking in the entire compressor. + We thus must separate this file from jcapimin.c to avoid linking the + whole compression library into a transcoder. } + +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jdeferr_del, + jerror_del, + jpeglib_del, + jcapimin_del, jcinit_del; + + + +{ Compression initialization. + Before calling this, all parameters and a data destination must be set up. + + We require a write_all_tables parameter as a failsafe check when writing + multiple datastreams from the same compression object. Since prior runs + will have left all the tables marked sent_table=TRUE, a subsequent run + would emit an abbreviated stream (no tables) by default. This may be what + is wanted, but for safety's sake it should not be the default behavior: + programmers should have to make a deliberate choice to emit abbreviated + images. Therefore the documentation and examples should encourage people + to pass write_all_tables=TRUE; then it will take active thought to do the + wrong thing. } + +{GLOBAL} +procedure jpeg_start_compress (cinfo : j_compress_ptr; + write_all_tables : boolean); + + +{ Write some scanlines of data to the JPEG compressor. + + The return value will be the number of lines actually written. + This should be less than the supplied num_lines only in case that + the data destination module has requested suspension of the compressor, + or if more than image_height scanlines are passed in. + + Note: we warn about excess calls to jpeg_write_scanlines() since + this likely signals an application programmer error. However, + excess scanlines passed in the last valid call are *silently* ignored, + so that the application need not adjust num_lines for end-of-image + when using a multiple-scanline buffer. } + +{GLOBAL} +function jpeg_write_scanlines (cinfo : j_compress_ptr; + scanlines : JSAMPARRAY; + num_lines : JDIMENSION) : JDIMENSION; + +{ Alternate entry point to write raw data. + Processes exactly one iMCU row per call, unless suspended. } + +{GLOBAL} +function jpeg_write_raw_data (cinfo : j_compress_ptr; + data : JSAMPIMAGE; + num_lines : JDIMENSION) : JDIMENSION; + +implementation + +{ Compression initialization. + Before calling this, all parameters and a data destination must be set up. + + We require a write_all_tables parameter as a failsafe check when writing + multiple datastreams from the same compression object. Since prior runs + will have left all the tables marked sent_table=TRUE, a subsequent run + would emit an abbreviated stream (no tables) by default. This may be what + is wanted, but for safety's sake it should not be the default behavior: + programmers should have to make a deliberate choice to emit abbreviated + images. Therefore the documentation and examples should encourage people + to pass write_all_tables=TRUE; then it will take active thought to do the + wrong thing. } + +{GLOBAL} +procedure jpeg_start_compress (cinfo : j_compress_ptr; + write_all_tables : boolean); +begin + if (cinfo^.global_state <> CSTATE_START) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + + if (write_all_tables) then + jpeg_suppress_tables(cinfo, FALSE); { mark all tables to be written } + + { (Re)initialize error mgr and destination modules } + cinfo^.err^.reset_error_mgr (j_common_ptr(cinfo)); + cinfo^.dest^.init_destination (cinfo); + { Perform master selection of active modules } + jinit_compress_master(cinfo); + { Set up for the first pass } + cinfo^.master^.prepare_for_pass (cinfo); + { Ready for application to drive first pass through jpeg_write_scanlines + or jpeg_write_raw_data. } + + cinfo^.next_scanline := 0; + if cinfo^.raw_data_in then + cinfo^.global_state := CSTATE_RAW_OK + else + cinfo^.global_state := CSTATE_SCANNING; +end; + + +{ Write some scanlines of data to the JPEG compressor. + + The return value will be the number of lines actually written. + This should be less than the supplied num_lines only in case that + the data destination module has requested suspension of the compressor, + or if more than image_height scanlines are passed in. + + Note: we warn about excess calls to jpeg_write_scanlines() since + this likely signals an application programmer error. However, + excess scanlines passed in the last valid call are *silently* ignored, + so that the application need not adjust num_lines for end-of-image + when using a multiple-scanline buffer. } + +{GLOBAL} +function jpeg_write_scanlines (cinfo : j_compress_ptr; + scanlines : JSAMPARRAY; + num_lines : JDIMENSION) : JDIMENSION; +var + row_ctr, rows_left : JDIMENSION; +begin + if (cinfo^.global_state <> CSTATE_SCANNING) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + if (cinfo^.next_scanline >= cinfo^.image_height) then + WARNMS(j_common_ptr(cinfo), JWRN_TOO_MUCH_DATA); + + { Call progress monitor hook if present } + if (cinfo^.progress <> NIL) then + begin + cinfo^.progress^.pass_counter := long (cinfo^.next_scanline); + cinfo^.progress^.pass_limit := long (cinfo^.image_height); + cinfo^.progress^.progress_monitor (j_common_ptr(cinfo)); + end; + + { Give master control module another chance if this is first call to + jpeg_write_scanlines. This lets output of the frame/scan headers be + delayed so that application can write COM, etc, markers between + jpeg_start_compress and jpeg_write_scanlines. } + if (cinfo^.master^.call_pass_startup) then + cinfo^.master^.pass_startup (cinfo); + + { Ignore any extra scanlines at bottom of image. } + rows_left := cinfo^.image_height - cinfo^.next_scanline; + if (num_lines > rows_left) then + num_lines := rows_left; + + row_ctr := 0; + cinfo^.main^.process_data (cinfo, scanlines, {var}row_ctr, num_lines); + Inc(cinfo^.next_scanline, row_ctr); + jpeg_write_scanlines := row_ctr; +end; + + +{ Alternate entry point to write raw data. + Processes exactly one iMCU row per call, unless suspended. } + +{GLOBAL} +function jpeg_write_raw_data (cinfo : j_compress_ptr; + data : JSAMPIMAGE; + num_lines : JDIMENSION) : JDIMENSION; +var + lines_per_iMCU_row : JDIMENSION; +begin + if (cinfo^.global_state <> CSTATE_RAW_OK) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + if (cinfo^.next_scanline >= cinfo^.image_height) then + begin + WARNMS(j_common_ptr(cinfo), JWRN_TOO_MUCH_DATA); + jpeg_write_raw_data := 0; + exit; + end; + + { Call progress monitor hook if present } + if (cinfo^.progress <> NIL) then + begin + cinfo^.progress^.pass_counter := long(cinfo^.next_scanline); + cinfo^.progress^.pass_limit := long(cinfo^.image_height); + cinfo^.progress^.progress_monitor (j_common_ptr(cinfo)); + end; + + { Give master control module another chance if this is first call to + jpeg_write_raw_data. This lets output of the frame/scan headers be + delayed so that application can write COM, etc, markers between + jpeg_start_compress and jpeg_write_raw_data. } + + if (cinfo^.master^.call_pass_startup) then + cinfo^.master^.pass_startup (cinfo); + + { Verify that at least one iMCU row has been passed. } + lines_per_iMCU_row := cinfo^.max_v_samp_factor * DCTSIZE; + if (num_lines < lines_per_iMCU_row) then + ERREXIT(j_common_ptr(cinfo), JERR_BUFFER_SIZE); + + { Directly compress the row. } + if (not cinfo^.coef^.compress_data (cinfo, data)) then + begin + { If compressor did not consume the whole row, suspend processing. } + jpeg_write_raw_data := 0; + exit; + end; + + { OK, we processed one iMCU row. } + Inc(cinfo^.next_scanline, lines_per_iMCU_row); + jpeg_write_raw_data := lines_per_iMCU_row; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jccoefct_del.pas b/mseide-msegui/lib/common/fpccompatibility/jccoefct_del.pas new file mode 100644 index 0000000..839e7de --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jccoefct_del.pas @@ -0,0 +1,524 @@ +Unit jccoefct_del; + +{ This file contains the coefficient buffer controller for compression. + This controller is the top level of the JPEG compressor proper. + The coefficient buffer lies between forward-DCT and entropy encoding steps.} + +{ Original: jccoefct.c; Copyright (C) 1994-1997, Thomas G. Lane. } + +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jerror_del, + jdeferr_del, + jutils_del, + jpeglib_del; + + +{ We use a full-image coefficient buffer when doing Huffman optimization, + and also for writing multiple-scan JPEG files. In all cases, the DCT + step is run during the first pass, and subsequent passes need only read + the buffered coefficients. } +{$ifdef ENTROPY_OPT_SUPPORTED} + {$define FULL_COEF_BUFFER_SUPPORTED} +{$else} + {$ifdef C_MULTISCAN_FILES_SUPPORTED} + {$define FULL_COEF_BUFFER_SUPPORTED} + {$endif} +{$endif} + +{ Initialize coefficient buffer controller. } + +{GLOBAL} +procedure jinit_c_coef_controller (cinfo : j_compress_ptr; + need_full_buffer : boolean); + +implementation + +{ Private buffer controller object } + +type + my_coef_ptr = ^my_coef_controller; + my_coef_controller = record + pub : jpeg_c_coef_controller; { public fields } + + iMCU_row_num : JDIMENSION; { iMCU row # within image } + mcu_ctr : JDIMENSION; { counts MCUs processed in current row } + MCU_vert_offset : int; { counts MCU rows within iMCU row } + MCU_rows_per_iMCU_row : int; { number of such rows needed } + + { For single-pass compression, it's sufficient to buffer just one MCU + (although this may prove a bit slow in practice). We allocate a + workspace of C_MAX_BLOCKS_IN_MCU coefficient blocks, and reuse it for each + MCU constructed and sent. (On 80x86, the workspace is FAR even though + it's not really very big; this is to keep the module interfaces unchanged + when a large coefficient buffer is necessary.) + In multi-pass modes, this array points to the current MCU's blocks + within the virtual arrays. } + + MCU_buffer : array[0..C_MAX_BLOCKS_IN_MCU-1] of JBLOCKROW; + + { In multi-pass modes, we need a virtual block array for each component. } + whole_image : array[0..MAX_COMPONENTS-1] of jvirt_barray_ptr; + end; + + +{ Forward declarations } +{METHODDEF} +function compress_data(cinfo : j_compress_ptr; + input_buf : JSAMPIMAGE) : boolean; forward; +{$ifdef FULL_COEF_BUFFER_SUPPORTED +{METHODDEF} +function compress_first_pass(cinfo : j_compress_ptr; + input_buf : JSAMPIMAGE) : boolean; forward; +{METHODDEF} +function compress_output(cinfo : j_compress_ptr; + input_buf : JSAMPIMAGE) : boolean; forward; +{$endif} + + +{LOCAL} +procedure start_iMCU_row (cinfo : j_compress_ptr); +{ Reset within-iMCU-row counters for a new row } +var + coef : my_coef_ptr; +begin + coef := my_coef_ptr (cinfo^.coef); + + { In an interleaved scan, an MCU row is the same as an iMCU row. + In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows. + But at the bottom of the image, process only what's left. } + if (cinfo^.comps_in_scan > 1) then + begin + coef^.MCU_rows_per_iMCU_row := 1; + end + else + begin + if (coef^.iMCU_row_num < (cinfo^.total_iMCU_rows-1)) then + coef^.MCU_rows_per_iMCU_row := cinfo^.cur_comp_info[0]^.v_samp_factor + else + coef^.MCU_rows_per_iMCU_row := cinfo^.cur_comp_info[0]^.last_row_height; + end; + + coef^.mcu_ctr := 0; + coef^.MCU_vert_offset := 0; +end; + + +{ Initialize for a processing pass. } + +{METHODDEF} +procedure start_pass_coef (cinfo : j_compress_ptr; + pass_mode : J_BUF_MODE); +var + coef : my_coef_ptr; +begin + coef := my_coef_ptr (cinfo^.coef); + + coef^.iMCU_row_num := 0; + start_iMCU_row(cinfo); + + case (pass_mode) of + JBUF_PASS_THRU: + begin + if (coef^.whole_image[0] <> NIL) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE); + coef^.pub.compress_data := compress_data; + end; +{$ifdef FULL_COEF_BUFFER_SUPPORTED} + JBUF_SAVE_AND_PASS: + begin + if (coef^.whole_image[0] = NIL) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE); + coef^.pub.compress_data := compress_first_pass; + end; + JBUF_CRANK_DEST: + begin + if (coef^.whole_image[0] = NIL) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE); + coef^.pub.compress_data := compress_output; + end; +{$endif} + else + ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE); + end; +end; + + +{ Process some data in the single-pass case. + We process the equivalent of one fully interleaved MCU row ("iMCU" row) + per call, ie, v_samp_factor block rows for each component in the image. + Returns TRUE if the iMCU row is completed, FALSE if suspended. + + NB: input_buf contains a plane for each component in image, + which we index according to the component's SOF position. } + + +{METHODDEF} +function compress_data (cinfo : j_compress_ptr; + input_buf : JSAMPIMAGE) : boolean; +var + coef : my_coef_ptr; + MCU_col_num : JDIMENSION; { index of current MCU within row } + last_MCU_col : JDIMENSION; + last_iMCU_row : JDIMENSION; + blkn, bi, ci, yindex, yoffset, blockcnt : int; + ypos, xpos : JDIMENSION; + compptr : jpeg_component_info_ptr; +begin + coef := my_coef_ptr (cinfo^.coef); + last_MCU_col := cinfo^.MCUs_per_row - 1; + last_iMCU_row := cinfo^.total_iMCU_rows - 1; + + { Loop to write as much as one whole iMCU row } + for yoffset := coef^.MCU_vert_offset to pred(coef^.MCU_rows_per_iMCU_row) do + begin + for MCU_col_num := coef^.mcu_ctr to last_MCU_col do + begin + { Determine where data comes from in input_buf and do the DCT thing. + Each call on forward_DCT processes a horizontal row of DCT blocks + as wide as an MCU; we rely on having allocated the MCU_buffer[] blocks + sequentially. Dummy blocks at the right or bottom edge are filled in + specially. The data in them does not matter for image reconstruction, + so we fill them with values that will encode to the smallest amount of + data, viz: all zeroes in the AC entries, DC entries equal to previous + block's DC value. (Thanks to Thomas Kinsman for this idea.) } + + blkn := 0; + for ci := 0 to pred(cinfo^.comps_in_scan) do + begin + compptr := cinfo^.cur_comp_info[ci]; + if (MCU_col_num < last_MCU_col) then + blockcnt := compptr^.MCU_width + else + blockcnt := compptr^.last_col_width; + xpos := MCU_col_num * compptr^.MCU_sample_width; + ypos := yoffset * DCTSIZE; { ypos = (yoffset+yindex) * DCTSIZE } + for yindex := 0 to pred(compptr^.MCU_height) do + begin + if (coef^.iMCU_row_num < last_iMCU_row) or + (yoffset+yindex < compptr^.last_row_height) then + begin + cinfo^.fdct^.forward_DCT (cinfo, compptr, + input_buf^[compptr^.component_index], + coef^.MCU_buffer[blkn], + ypos, xpos, JDIMENSION (blockcnt)); + + if (blockcnt < compptr^.MCU_width) then + begin + { Create some dummy blocks at the right edge of the image. } + jzero_far({FAR}pointer(coef^.MCU_buffer[blkn + blockcnt]), + (compptr^.MCU_width - blockcnt) * SIZEOF(JBLOCK)); + for bi := blockcnt to pred(compptr^.MCU_width) do + begin + coef^.MCU_buffer[blkn+bi]^[0][0] := coef^.MCU_buffer[blkn+bi-1]^[0][0]; + end; + end; + end + else + begin + { Create a row of dummy blocks at the bottom of the image. } + jzero_far({FAR}pointer(coef^.MCU_buffer[blkn]), + compptr^.MCU_width * SIZEOF(JBLOCK)); + for bi := 0 to pred(compptr^.MCU_width) do + begin + coef^.MCU_buffer[blkn+bi]^[0][0] := coef^.MCU_buffer[blkn-1]^[0][0]; + end; + end; + Inc(blkn, compptr^.MCU_width); + Inc(ypos, DCTSIZE); + end; + end; + { Try to write the MCU. In event of a suspension failure, we will + re-DCT the MCU on restart (a bit inefficient, could be fixed...) } + + if (not cinfo^.entropy^.encode_mcu (cinfo, JBLOCKARRAY(@coef^.MCU_buffer)^)) then + begin + { Suspension forced; update state counters and exit } + coef^.MCU_vert_offset := yoffset; + coef^.mcu_ctr := MCU_col_num; + compress_data := FALSE; + exit; + end; + end; + { Completed an MCU row, but perhaps not an iMCU row } + coef^.mcu_ctr := 0; + end; + { Completed the iMCU row, advance counters for next one } + Inc(coef^.iMCU_row_num); + start_iMCU_row(cinfo); + compress_data := TRUE; +end; + + +{$ifdef FULL_COEF_BUFFER_SUPPORTED} + +{ Process some data in the first pass of a multi-pass case. + We process the equivalent of one fully interleaved MCU row ("iMCU" row) + per call, ie, v_samp_factor block rows for each component in the image. + This amount of data is read from the source buffer, DCT'd and quantized, + and saved into the virtual arrays. We also generate suitable dummy blocks + as needed at the right and lower edges. (The dummy blocks are constructed + in the virtual arrays, which have been padded appropriately.) This makes + it possible for subsequent passes not to worry about real vs. dummy blocks. + + We must also emit the data to the entropy encoder. This is conveniently + done by calling compress_output() after we've loaded the current strip + of the virtual arrays. + + NB: input_buf contains a plane for each component in image. All + components are DCT'd and loaded into the virtual arrays in this pass. + However, it may be that only a subset of the components are emitted to + the entropy encoder during this first pass; be careful about looking + at the scan-dependent variables (MCU dimensions, etc). } + +{METHODDEF} +function compress_first_pass (cinfo : j_compress_ptr; + input_buf : JSAMPIMAGE) : boolean; +var + coef : my_coef_ptr; + last_iMCU_row : JDIMENSION; + blocks_across, MCUs_across, MCUindex : JDIMENSION; + bi, ci, h_samp_factor, block_row, block_rows, ndummy : int; + lastDC : JCOEF; + compptr : jpeg_component_info_ptr; + buffer : JBLOCKARRAY; + thisblockrow, lastblockrow : JBLOCKROW; +begin + coef := my_coef_ptr (cinfo^.coef); + last_iMCU_row := cinfo^.total_iMCU_rows - 1; + + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + { Align the virtual buffer for this component. } + buffer := cinfo^.mem^.access_virt_barray + (j_common_ptr(cinfo), coef^.whole_image[ci], + coef^.iMCU_row_num * compptr^.v_samp_factor, + JDIMENSION (compptr^.v_samp_factor), TRUE); + { Count non-dummy DCT block rows in this iMCU row. } + if (coef^.iMCU_row_num < last_iMCU_row) then + block_rows := compptr^.v_samp_factor + else + begin + { NB: can't use last_row_height here, since may not be set! } + block_rows := int (compptr^.height_in_blocks mod compptr^.v_samp_factor); + if (block_rows = 0) then + block_rows := compptr^.v_samp_factor; + end; + blocks_across := compptr^.width_in_blocks; + h_samp_factor := compptr^.h_samp_factor; + { Count number of dummy blocks to be added at the right margin. } + ndummy := int (blocks_across mod h_samp_factor); + if (ndummy > 0) then + ndummy := h_samp_factor - ndummy; + { Perform DCT for all non-dummy blocks in this iMCU row. Each call + on forward_DCT processes a complete horizontal row of DCT blocks. } + + for block_row := 0 to pred(block_rows) do + begin + thisblockrow := buffer^[block_row]; + cinfo^.fdct^.forward_DCT (cinfo, compptr, + input_buf^[ci], + thisblockrow, + JDIMENSION (block_row * DCTSIZE), + JDIMENSION (0), + blocks_across); + if (ndummy > 0) then + begin + { Create dummy blocks at the right edge of the image. } + Inc(JBLOCK_PTR(thisblockrow), blocks_across); { => first dummy block } + jzero_far({FAR}pointer(thisblockrow), ndummy * SIZEOF(JBLOCK)); + {lastDC := thisblockrow^[-1][0];} + { work around Range Checking } + Dec(JBLOCK_PTR(thisblockrow)); + lastDC := thisblockrow^[0][0]; + Inc(JBLOCK_PTR(thisblockrow)); + + for bi := 0 to pred(ndummy) do + begin + thisblockrow^[bi][0] := lastDC; + end; + end; + end; + { If at end of image, create dummy block rows as needed. + The tricky part here is that within each MCU, we want the DC values + of the dummy blocks to match the last real block's DC value. + This squeezes a few more bytes out of the resulting file... } + + if (coef^.iMCU_row_num = last_iMCU_row) then + begin + Inc(blocks_across, ndummy); { include lower right corner } + MCUs_across := blocks_across div h_samp_factor; + for block_row := block_rows to pred(compptr^.v_samp_factor) do + begin + thisblockrow := buffer^[block_row]; + lastblockrow := buffer^[block_row-1]; + jzero_far({FAR} pointer(thisblockrow), + size_t(blocks_across * SIZEOF(JBLOCK))); + for MCUindex := 0 to pred(MCUs_across) do + begin + lastDC := lastblockrow^[h_samp_factor-1][0]; + for bi := 0 to pred(h_samp_factor) do + begin + thisblockrow^[bi][0] := lastDC; + end; + Inc(JBLOCK_PTR(thisblockrow), h_samp_factor); { advance to next MCU in row } + Inc(JBLOCK_PTR(lastblockrow), h_samp_factor); + end; + end; + end; + Inc(compptr); + end; + { NB: compress_output will increment iMCU_row_num if successful. + A suspension return will result in redoing all the work above next time.} + + + { Emit data to the entropy encoder, sharing code with subsequent passes } + compress_first_pass := compress_output(cinfo, input_buf); +end; + + +{ Process some data in subsequent passes of a multi-pass case. + We process the equivalent of one fully interleaved MCU row ("iMCU" row) + per call, ie, v_samp_factor block rows for each component in the scan. + The data is obtained from the virtual arrays and fed to the entropy coder. + Returns TRUE if the iMCU row is completed, FALSE if suspended. + + NB: input_buf is ignored; it is likely to be a NIL pointer. } + +{METHODDEF} +function compress_output (cinfo : j_compress_ptr; + input_buf : JSAMPIMAGE) : boolean; +var + coef : my_coef_ptr; + MCU_col_num : JDIMENSION; { index of current MCU within row } + blkn, ci, xindex, yindex, yoffset : int; + start_col : JDIMENSION; + buffer : array[0..MAX_COMPS_IN_SCAN-1] of JBLOCKARRAY; + buffer_ptr : JBLOCKROW; + compptr : jpeg_component_info_ptr; +begin + coef := my_coef_ptr (cinfo^.coef); + + { Align the virtual buffers for the components used in this scan. + NB: during first pass, this is safe only because the buffers will + already be aligned properly, so jmemmgr.c won't need to do any I/O. } + + for ci := 0 to pred(cinfo^.comps_in_scan) do + begin + compptr := cinfo^.cur_comp_info[ci]; + buffer[ci] := cinfo^.mem^.access_virt_barray ( + j_common_ptr(cinfo), coef^.whole_image[compptr^.component_index], + coef^.iMCU_row_num * compptr^.v_samp_factor, + JDIMENSION (compptr^.v_samp_factor), FALSE); + end; + + { Loop to process one whole iMCU row } + for yoffset := coef^.MCU_vert_offset to pred(coef^.MCU_rows_per_iMCU_row) do + begin + for MCU_col_num := coef^.mcu_ctr to pred(cinfo^.MCUs_per_row) do + begin + { Construct list of pointers to DCT blocks belonging to this MCU } + blkn := 0; { index of current DCT block within MCU } + for ci := 0 to pred(cinfo^.comps_in_scan) do + begin + compptr := cinfo^.cur_comp_info[ci]; + start_col := MCU_col_num * compptr^.MCU_width; + for yindex := 0 to pred(compptr^.MCU_height) do + begin + buffer_ptr := JBLOCKROW(@ buffer[ci]^[yindex+yoffset]^[start_col]); + for xindex := 0 to pred(compptr^.MCU_width) do + begin + coef^.MCU_buffer[blkn] := buffer_ptr; + Inc(blkn); + Inc(JBLOCK_PTR(buffer_ptr)); + end; + end; + end; + { Try to write the MCU. } + if (not cinfo^.entropy^.encode_mcu (cinfo, coef^.MCU_buffer)) then + begin + { Suspension forced; update state counters and exit } + coef^.MCU_vert_offset := yoffset; + coef^.mcu_ctr := MCU_col_num; + compress_output := FALSE; + exit; + end; + end; + { Completed an MCU row, but perhaps not an iMCU row } + coef^.mcu_ctr := 0; + end; + { Completed the iMCU row, advance counters for next one } + Inc(coef^.iMCU_row_num); + start_iMCU_row(cinfo); + compress_output := TRUE; +end; + +{$endif} { FULL_COEF_BUFFER_SUPPORTED } + + +{ Initialize coefficient buffer controller. } + +{GLOBAL} +procedure jinit_c_coef_controller (cinfo : j_compress_ptr; + need_full_buffer : boolean); +var + coef : my_coef_ptr; +var + buffer : JBLOCKROW; + i : int; +var + ci : int; + compptr : jpeg_component_info_ptr; +begin + coef := my_coef_ptr ( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(my_coef_controller)) ); + cinfo^.coef := jpeg_c_coef_controller_ptr(coef); + coef^.pub.start_pass := start_pass_coef; + + { Create the coefficient buffer. } + if (need_full_buffer) then + begin +{$ifdef FULL_COEF_BUFFER_SUPPORTED} + { Allocate a full-image virtual array for each component, } + { padded to a multiple of samp_factor DCT blocks in each direction. } + + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + coef^.whole_image[ci] := cinfo^.mem^.request_virt_barray + (j_common_ptr(cinfo), JPOOL_IMAGE, FALSE, + JDIMENSION (jround_up( long (compptr^.width_in_blocks), + long (compptr^.h_samp_factor) )), + JDIMENSION (jround_up(long (compptr^.height_in_blocks), + long (compptr^.v_samp_factor))), + JDIMENSION (compptr^.v_samp_factor)); + Inc(compptr); + end; +{$else} + ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE); +{$endif} + end + else + begin + { We only need a single-MCU buffer. } + buffer := JBLOCKROW ( + cinfo^.mem^.alloc_large (j_common_ptr(cinfo), JPOOL_IMAGE, + C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)) ); + for i := 0 to pred(C_MAX_BLOCKS_IN_MCU) do + begin + coef^.MCU_buffer[i] := JBLOCKROW(@ buffer^[i]); + end; + coef^.whole_image[0] := NIL; { flag for no virtual arrays } + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jccolor_del.pas b/mseide-msegui/lib/common/fpccompatibility/jccolor_del.pas new file mode 100644 index 0000000..f3f3ebc --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jccolor_del.pas @@ -0,0 +1,531 @@ +Unit jccolor_del; + +{ This file contains input colorspace conversion routines. } + +{ Original : jccolor.c ; Copyright (C) 1991-1996, Thomas G. Lane. } + +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jdeferr_del, + jerror_del, + jpeglib_del; + +{ Module initialization routine for input colorspace conversion. } + +{GLOBAL} +procedure jinit_color_converter (cinfo : j_compress_ptr); + +implementation + +{ Private subobject } +type + jTInt32 = 0..Pred(MaxInt div SizeOf(INT32)); + INT32_FIELD = array[jTInt32] of INT32; + INT32_FIELD_PTR = ^INT32_FIELD; + +type + my_cconvert_ptr = ^my_color_converter; + my_color_converter = record + pub : jpeg_color_converter; { public fields } + + { Private state for RGB -> YCC conversion } + rgb_ycc_tab : INT32_FIELD_PTR; { => table for RGB to YCbCr conversion } + end; {my_color_converter;} + + +{*************** RGB -> YCbCr conversion: most common case *************} + +{ + YCbCr is defined per CCIR 601-1, except that Cb and Cr are + normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5. + The conversion equations to be implemented are therefore + Y = 0.29900 * R + 0.58700 * G + 0.11400 * B + Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + CENTERJSAMPLE + Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + CENTERJSAMPLE + (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.) + Note: older versions of the IJG code used a zero offset of MAXJSAMPLE/2, + rather than CENTERJSAMPLE, for Cb and Cr. This gave equal positive and + negative swings for Cb/Cr, but meant that grayscale values (Cb=Cr=0) + were not represented exactly. Now we sacrifice exact representation of + maximum red and maximum blue in order to get exact grayscales. + + To avoid floating-point arithmetic, we represent the fractional constants + as integers scaled up by 2^16 (about 4 digits precision); we have to divide + the products by 2^16, with appropriate rounding, to get the correct answer. + + For even more speed, we avoid doing any multiplications in the inner loop + by precalculating the constants times R,G,B for all possible values. + For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table); + for 12-bit samples it is still acceptable. It's not very reasonable for + 16-bit samples, but if you want lossless storage you shouldn't be changing + colorspace anyway. + The CENTERJSAMPLE offsets and the rounding fudge-factor of 0.5 are included + in the tables to save adding them separately in the inner loop. } +const + SCALEBITS = 16; { speediest right-shift on some machines } + CBCR_OFFSET = INT32(CENTERJSAMPLE shl SCALEBITS); + ONE_HALF = INT32(1) shl (SCALEBITS-1); + + +{ We allocate one big table and divide it up into eight parts, instead of + doing eight alloc_small requests. This lets us use a single table base + address, which can be held in a register in the inner loops on many + machines (more than can hold all eight addresses, anyway). } + + R_Y_OFF = 0; { offset to R => Y section } + G_Y_OFF = 1*(MAXJSAMPLE+1); { offset to G => Y section } + B_Y_OFF = 2*(MAXJSAMPLE+1); { etc. } + R_CB_OFF = 3*(MAXJSAMPLE+1); + G_CB_OFF = 4*(MAXJSAMPLE+1); + B_CB_OFF = 5*(MAXJSAMPLE+1); + R_CR_OFF = B_CB_OFF; { B=>Cb, R=>Cr are the same } + G_CR_OFF = 6*(MAXJSAMPLE+1); + B_CR_OFF = 7*(MAXJSAMPLE+1); + TABLE_SIZE = 8*(MAXJSAMPLE+1); + + +{ Initialize for RGB->YCC colorspace conversion. } + +{METHODDEF} +procedure rgb_ycc_start (cinfo : j_compress_ptr); +const + FIX_0_29900 = INT32(Round (0.29900 * (1 shl SCALEBITS)) ); + FIX_0_58700 = INT32(Round (0.58700 * (1 shl SCALEBITS)) ); + FIX_0_11400 = INT32(Round (0.11400 * (1 shl SCALEBITS)) ); + FIX_0_16874 = INT32(Round (0.16874 * (1 shl SCALEBITS)) ); + FIX_0_33126 = INT32(Round (0.33126 * (1 shl SCALEBITS)) ); + FIX_0_50000 = INT32(Round (0.50000 * (1 shl SCALEBITS)) ); + FIX_0_41869 = INT32(Round (0.41869 * (1 shl SCALEBITS)) ); + FIX_0_08131 = INT32(Round (0.08131 * (1 shl SCALEBITS)) ); +var + cconvert : my_cconvert_ptr; + rgb_ycc_tab : INT32_FIELD_PTR; + i : INT32; +begin + cconvert := my_cconvert_ptr (cinfo^.cconvert); + + { Allocate and fill in the conversion tables. } + rgb_ycc_tab := INT32_FIELD_PTR( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + (TABLE_SIZE * SIZEOF(INT32))) ); + cconvert^.rgb_ycc_tab := rgb_ycc_tab; + + for i := 0 to MAXJSAMPLE do + begin + rgb_ycc_tab^[i+R_Y_OFF] := FIX_0_29900 * i; + rgb_ycc_tab^[i+G_Y_OFF] := FIX_0_58700 * i; + rgb_ycc_tab^[i+B_Y_OFF] := FIX_0_11400 * i + ONE_HALF; + rgb_ycc_tab^[i+R_CB_OFF] := (-FIX_0_16874) * i; + rgb_ycc_tab^[i+G_CB_OFF] := (-FIX_0_33126) * i; + { We use a rounding fudge-factor of 0.5-epsilon for Cb and Cr. + This ensures that the maximum output will round to MAXJSAMPLE + not MAXJSAMPLE+1, and thus that we don't have to range-limit. } + + rgb_ycc_tab^[i+B_CB_OFF] := FIX_0_50000 * i + CBCR_OFFSET + ONE_HALF-1; +{ B=>Cb and R=>Cr tables are the same + rgb_ycc_tab^[i+R_CR_OFF] := FIX_0_50000 * i + CBCR_OFFSET + ONE_HALF-1; +} + rgb_ycc_tab^[i+G_CR_OFF] := (-FIX_0_41869) * i; + rgb_ycc_tab^[i+B_CR_OFF] := (-FIX_0_08131) * i; + end; +end; + + +{ Convert some rows of samples to the JPEG colorspace. + + Note that we change from the application's interleaved-pixel format + to our internal noninterleaved, one-plane-per-component format. + The input buffer is therefore three times as wide as the output buffer. + + A starting row offset is provided only for the output buffer. The caller + can easily adjust the passed input_buf value to accommodate any row + offset required on that side. } + +{METHODDEF} +procedure rgb_ycc_convert (cinfo : j_compress_ptr; + input_buf : JSAMPARRAY; + output_buf : JSAMPIMAGE; + output_row : JDIMENSION; + num_rows : int); +var + cconvert : my_cconvert_ptr; + {register} r, g, b : int; + {register} ctab : INT32_FIELD_PTR; + {register} inptr : JSAMPROW; + {register} outptr0, outptr1, outptr2 : JSAMPROW; + {register} col : JDIMENSION; + num_cols : JDIMENSION; +begin + cconvert := my_cconvert_ptr (cinfo^.cconvert); + ctab := cconvert^.rgb_ycc_tab; + num_cols := cinfo^.image_width; + + while (num_rows > 0) do + begin + Dec(num_rows); + inptr := input_buf^[0]; + Inc(JSAMPROW_PTR(input_buf)); + outptr0 := output_buf^[0]^[output_row]; + outptr1 := output_buf^[1]^[output_row]; + outptr2 := output_buf^[2]^[output_row]; + Inc(output_row); + for col := 0 to pred(num_cols) do + begin + r := GETJSAMPLE(inptr^[RGB_RED]); + g := GETJSAMPLE(inptr^[RGB_GREEN]); + b := GETJSAMPLE(inptr^[RGB_BLUE]); + Inc(JSAMPLE_PTR(inptr), RGB_PIXELSIZE); + { If the inputs are 0..MAXJSAMPLE, the outputs of these equations + must be too; we do not need an explicit range-limiting operation. + Hence the value being shifted is never negative, and we don't + need the general RIGHT_SHIFT macro. } + + { Y } + outptr0^[col] := JSAMPLE( + ((ctab^[r+R_Y_OFF] + ctab^[g+G_Y_OFF] + ctab^[b+B_Y_OFF]) + shr SCALEBITS) ); + { Cb } + outptr1^[col] := JSAMPLE( + ((ctab^[r+R_CB_OFF] + ctab^[g+G_CB_OFF] + ctab^[b+B_CB_OFF]) + shr SCALEBITS) ); + { Cr } + outptr2^[col] := JSAMPLE( + ((ctab^[r+R_CR_OFF] + ctab^[g+G_CR_OFF] + ctab^[b+B_CR_OFF]) + shr SCALEBITS) ); + end; + end; +end; + + +{*************** Cases other than RGB -> YCbCr *************} + + +{ Convert some rows of samples to the JPEG colorspace. + This version handles RGB -> grayscale conversion, which is the same + as the RGB -> Y portion of RGB -> YCbCr. + We assume rgb_ycc_start has been called (we only use the Y tables). } + +{METHODDEF} +procedure rgb_gray_convert (cinfo : j_compress_ptr; + input_buf : JSAMPARRAY; + output_buf : JSAMPIMAGE; + output_row : JDIMENSION; + num_rows : int); +var + cconvert : my_cconvert_ptr; + {register} r, g, b : int; + {register} ctab :INT32_FIELD_PTR; + {register} inptr : JSAMPROW; + {register} outptr : JSAMPROW; + {register} col : JDIMENSION; + num_cols : JDIMENSION; +begin + cconvert := my_cconvert_ptr (cinfo^.cconvert); + ctab := cconvert^.rgb_ycc_tab; + num_cols := cinfo^.image_width; + + while (num_rows > 0) do + begin + Dec(num_rows); + inptr := input_buf^[0]; + Inc(JSAMPROW_PTR(input_buf)); + outptr := output_buf^[0]^[output_row]; + Inc(output_row); + for col := 0 to pred(num_cols) do + begin + r := GETJSAMPLE(inptr^[RGB_RED]); + g := GETJSAMPLE(inptr^[RGB_GREEN]); + b := GETJSAMPLE(inptr^[RGB_BLUE]); + Inc(JSAMPLE_PTR(inptr), RGB_PIXELSIZE); + { Y } + outptr^[col] := JSAMPLE ( + ((ctab^[r+R_Y_OFF] + ctab^[g+G_Y_OFF] + ctab^[b+B_Y_OFF]) + shr SCALEBITS) ); + end; + end; +end; + + +{ Convert some rows of samples to the JPEG colorspace. + This version handles Adobe-style CMYK -> YCCK conversion, + where we convert R=1-C, G=1-M, and B=1-Y to YCbCr using the same + conversion as above, while passing K (black) unchanged. + We assume rgb_ycc_start has been called. } + +{METHODDEF} +procedure cmyk_ycck_convert (cinfo : j_compress_ptr; + input_buf : JSAMPARRAY; + output_buf : JSAMPIMAGE; + output_row : JDIMENSION; + num_rows : int); +var + cconvert : my_cconvert_ptr; + {register} r, g, b : int; + {register} ctab : INT32_FIELD_PTR; + {register} inptr : JSAMPROW; + {register} outptr0, outptr1, outptr2, outptr3 : JSAMPROW; + {register} col : JDIMENSION; + num_cols : JDIMENSION; +begin + cconvert := my_cconvert_ptr (cinfo^.cconvert); + ctab := cconvert^.rgb_ycc_tab; + num_cols := cinfo^.image_width; + + while (num_rows > 0) do + begin + Dec(num_rows); + inptr := input_buf^[0]; + Inc(JSAMPROW_PTR(input_buf)); + outptr0 := output_buf^[0]^[output_row]; + outptr1 := output_buf^[1]^[output_row]; + outptr2 := output_buf^[2]^[output_row]; + outptr3 := output_buf^[3]^[output_row]; + Inc(output_row); + for col := 0 to pred(num_cols) do + begin + r := MAXJSAMPLE - GETJSAMPLE(inptr^[0]); + g := MAXJSAMPLE - GETJSAMPLE(inptr^[1]); + b := MAXJSAMPLE - GETJSAMPLE(inptr^[2]); + { K passes through as-is } + outptr3^[col] := inptr^[3]; { don't need GETJSAMPLE here } + Inc(JSAMPLE_PTR(inptr), 4); + { If the inputs are 0..MAXJSAMPLE, the outputs of these equations + must be too; we do not need an explicit range-limiting operation. + Hence the value being shifted is never negative, and we don't + need the general RIGHT_SHIFT macro. } + + { Y } + outptr0^[col] := JSAMPLE ( + ((ctab^[r+R_Y_OFF] + ctab^[g+G_Y_OFF] + ctab^[b+B_Y_OFF]) + shr SCALEBITS) ); + { Cb } + outptr1^[col] := JSAMPLE( + ((ctab^[r+R_CB_OFF] + ctab^[g+G_CB_OFF] + ctab^[b+B_CB_OFF]) + shr SCALEBITS) ); + { Cr } + outptr2^[col] := JSAMPLE ( + ((ctab^[r+R_CR_OFF] + ctab^[g+G_CR_OFF] + ctab^[b+B_CR_OFF]) + shr SCALEBITS) ); + end; + end; +end; + + +{ Convert some rows of samples to the JPEG colorspace. + This version handles grayscale output with no conversion. + The source can be either plain grayscale or YCbCr (since Y = gray). } + +{METHODDEF} +procedure grayscale_convert (cinfo : j_compress_ptr; + input_buf : JSAMPARRAY; + output_buf : JSAMPIMAGE; + output_row : JDIMENSION; + num_rows: int); +var + {register} inptr : JSAMPROW; + {register} outptr : JSAMPROW; + {register} col : JDIMENSION; + num_cols :JDIMENSION; + instride : int; +begin + num_cols := cinfo^.image_width; + instride := cinfo^.input_components; + + while (num_rows > 0) do + begin + Dec(num_rows); + inptr := input_buf^[0]; + Inc(JSAMPROW_PTR(input_buf)); + outptr := output_buf^[0]^[output_row]; + Inc(output_row); + for col := 0 to pred(num_cols) do + begin + outptr^[col] := inptr^[0]; { don't need GETJSAMPLE() here } + Inc(JSAMPLE_PTR(inptr), instride); + end; + end; +end; + + +{ Convert some rows of samples to the JPEG colorspace. + This version handles multi-component colorspaces without conversion. + We assume input_components = num_components. } + +{METHODDEF} +procedure null_convert (cinfo : j_compress_ptr; + input_buf : JSAMPARRAY; + output_buf : JSAMPIMAGE; + output_row : JDIMENSION; + num_rows : int); +var + {register} inptr : JSAMPROW; + {register} outptr : JSAMPROW; + {register} col : JDIMENSION; + {register} ci : int; + nc : int; + num_cols : JDIMENSION; +begin + nc := cinfo^.num_components; + num_cols := cinfo^.image_width; + + while (num_rows > 0) do + begin + Dec(num_rows); + { It seems fastest to make a separate pass for each component. } + for ci := 0 to pred(nc) do + begin + inptr := input_buf^[0]; + outptr := output_buf^[ci]^[output_row]; + for col := 0 to pred(num_cols) do + begin + outptr^[col] := inptr^[ci]; { don't need GETJSAMPLE() here } + Inc(JSAMPLE_PTR(inptr), nc); + end; + end; + Inc(JSAMPROW_PTR(input_buf)); + Inc(output_row); + end; +end; + + +{ Empty method for start_pass. } + +{METHODDEF} +procedure null_method (cinfo : j_compress_ptr); +begin + { no work needed } +end; + + +{ Module initialization routine for input colorspace conversion. } + +{GLOBAL} +procedure jinit_color_converter (cinfo : j_compress_ptr); +var + cconvert : my_cconvert_ptr; +begin + cconvert := my_cconvert_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(my_color_converter)) ); + cinfo^.cconvert := jpeg_color_converter_ptr(cconvert); + { set start_pass to null method until we find out differently } + cconvert^.pub.start_pass := null_method; + + { Make sure input_components agrees with in_color_space } + case (cinfo^.in_color_space) of + JCS_GRAYSCALE: + if (cinfo^.input_components <> 1) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_IN_COLORSPACE); + +{$ifdef RGB_PIXELSIZE <> 3} + JCS_RGB: + if (cinfo^.input_components <> RGB_PIXELSIZE) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_IN_COLORSPACE); +{$else} { share code with YCbCr } + JCS_RGB, +{$endif} + JCS_YCbCr: + if (cinfo^.input_components <> 3) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_IN_COLORSPACE); + + JCS_CMYK, + JCS_YCCK: + if (cinfo^.input_components <> 4) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_IN_COLORSPACE); + + else { JCS_UNKNOWN can be anything } + if (cinfo^.input_components < 1) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_IN_COLORSPACE); + end; + + { Check num_components, set conversion method based on requested space } + case (cinfo^.jpeg_color_space) of + JCS_GRAYSCALE: + begin + if (cinfo^.num_components <> 1) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_J_COLORSPACE); + if (cinfo^.in_color_space = JCS_GRAYSCALE) then + cconvert^.pub.color_convert := grayscale_convert + else + if (cinfo^.in_color_space = JCS_RGB) then + begin + cconvert^.pub.start_pass := rgb_ycc_start; + cconvert^.pub.color_convert := rgb_gray_convert; + end + else + if (cinfo^.in_color_space = JCS_YCbCr) then + cconvert^.pub.color_convert := grayscale_convert + else + ERREXIT(j_common_ptr(cinfo), JERR_CONVERSION_NOTIMPL); + end; + + JCS_RGB: + begin + if (cinfo^.num_components <> 3) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_J_COLORSPACE); + if (cinfo^.in_color_space = JCS_RGB) and (RGB_PIXELSIZE = 3) then + cconvert^.pub.color_convert := null_convert + else + ERREXIT(j_common_ptr(cinfo), JERR_CONVERSION_NOTIMPL); + end; + + JCS_YCbCr: + begin + if (cinfo^.num_components <> 3) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_J_COLORSPACE); + if (cinfo^.in_color_space = JCS_RGB) then + begin + cconvert^.pub.start_pass := rgb_ycc_start; + cconvert^.pub.color_convert := rgb_ycc_convert; + end + else + if (cinfo^.in_color_space = JCS_YCbCr) then + cconvert^.pub.color_convert := null_convert + else + ERREXIT(j_common_ptr(cinfo), JERR_CONVERSION_NOTIMPL); + end; + + JCS_CMYK: + begin + if (cinfo^.num_components <> 4) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_J_COLORSPACE); + if (cinfo^.in_color_space = JCS_CMYK) then + cconvert^.pub.color_convert := null_convert + else + ERREXIT(j_common_ptr(cinfo), JERR_CONVERSION_NOTIMPL); + end; + + JCS_YCCK: + begin + if (cinfo^.num_components <> 4) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_J_COLORSPACE); + if (cinfo^.in_color_space = JCS_CMYK) then + begin + cconvert^.pub.start_pass := rgb_ycc_start; + cconvert^.pub.color_convert := cmyk_ycck_convert; + end + else + if (cinfo^.in_color_space = JCS_YCCK) then + cconvert^.pub.color_convert := null_convert + else + ERREXIT(j_common_ptr(cinfo), JERR_CONVERSION_NOTIMPL); + end; + + else { allow null conversion of JCS_UNKNOWN } + begin + if (cinfo^.jpeg_color_space <> cinfo^.in_color_space) or + (cinfo^.num_components <> cinfo^.input_components) then + ERREXIT(j_common_ptr(cinfo), JERR_CONVERSION_NOTIMPL); + cconvert^.pub.color_convert := null_convert; + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jcdctmgr_del.pas b/mseide-msegui/lib/common/fpccompatibility/jcdctmgr_del.pas new file mode 100644 index 0000000..7305a6e --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jcdctmgr_del.pas @@ -0,0 +1,516 @@ +Unit jcdctmgr_del; + +{ Original : jcdctmgr.c ; Copyright (C) 1994-1996, Thomas G. Lane. } + +{ This file is part of the Independent JPEG Group's software. + For conditions of distribution and use, see the accompanying README file. + + This file contains the forward-DCT management logic. + This code selects a particular DCT implementation to be used, + and it performs related housekeeping chores including coefficient + quantization. } + +//modified 2013 by Martin Schreiber + +interface + +//{$N+} +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jdeferr_del, + jerror_del, + jpeglib_del, + jdct_del, { Private declarations for DCT subsystem } + jfdctint_del, jfdctfst_del, jfdctflt_del; + +{ Initialize FDCT manager. } + +{GLOBAL} +procedure jinit_forward_dct (cinfo : j_compress_ptr); + +implementation + + +{ Private subobject for this module } + +type + my_fdct_ptr = ^my_fdct_controller; + my_fdct_controller = record + pub : jpeg_forward_dct; { public fields } + + { Pointer to the DCT routine actually in use } + do_dct : forward_DCT_method_ptr; + + { The actual post-DCT divisors --- not identical to the quant table + entries, because of scaling (especially for an unnormalized DCT). + Each table is given in normal array order. } + + divisors : array[0..NUM_QUANT_TBLS-1] of DCTELEM_FIELD_PTR; + + {$ifdef DCT_FLOAT_SUPPORTED} + { Same as above for the floating-point case. } + do_float_dct : float_DCT_method_ptr; + float_divisors : array[0..NUM_QUANT_TBLS-1] of FAST_FLOAT_FIELD_PTR; + {$endif} + end; + + +{ Initialize for a processing pass. + Verify that all referenced Q-tables are present, and set up + the divisor table for each one. + In the current implementation, DCT of all components is done during + the first pass, even if only some components will be output in the + first scan. Hence all components should be examined here. } + +{METHODDEF} +procedure start_pass_fdctmgr (cinfo : j_compress_ptr); +var + fdct : my_fdct_ptr; + ci, qtblno, i : int; + compptr : jpeg_component_info_ptr; + qtbl : JQUANT_TBL_PTR; + dtbl : DCTELEM_FIELD_PTR; +{$ifdef DCT_IFAST_SUPPORTED} +const + CONST_BITS = 14; + aanscales : array[0..DCTSIZE2-1] of INT16 = + ({ precomputed values scaled up by 14 bits } + 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, + 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270, + 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906, + 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315, + 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, + 12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552, + 8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446, + 4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247); + {SHIFT_TEMPS} + + { Descale and correctly round an INT32 value that's scaled by N bits. + We assume RIGHT_SHIFT rounds towards minus infinity, so adding + the fudge factor is correct for either sign of X. } + + function DESCALE(x : INT32; n : int) : INT32; + var + shift_temp : INT32; + begin + shift_temp := x + (INT32(1) shl (n-1)); + {$ifdef RIGHT_SHIFT_IS_UNSIGNED} + if shift_temp < 0 then + Descale := (shift_temp shr n) or ((not INT32(0)) shl (32-n)) + else + {$endif} + Descale := (shift_temp shr n); + end; + +{$endif} +{$ifdef DCT_FLOAT_SUPPORTED} +var + fdtbl : FAST_FLOAT_FIELD_PTR; + row, col : int; +const + aanscalefactor : array[0..DCTSIZE-1] of double = + (1.0, 1.387039845, 1.306562965, 1.175875602, + 1.0, 0.785694958, 0.541196100, 0.275899379); +{$endif} +begin + fdct := my_fdct_ptr (cinfo^.fdct); + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + qtblno := compptr^.quant_tbl_no; + { Make sure specified quantization table is present } + if (qtblno < 0) or (qtblno >= NUM_QUANT_TBLS) or + (cinfo^.quant_tbl_ptrs[qtblno] = NIL) then + ERREXIT1(j_common_ptr(cinfo), JERR_NO_QUANT_TABLE, qtblno); + qtbl := cinfo^.quant_tbl_ptrs[qtblno]; + { Compute divisors for this quant table } + { We may do this more than once for same table, but it's not a big deal } + case (cinfo^.dct_method) of +{$ifdef DCT_ISLOW_SUPPORTED} + JDCT_ISLOW: + begin + { For LL&M IDCT method, divisors are equal to raw quantization + coefficients multiplied by 8 (to counteract scaling). } + + if (fdct^.divisors[qtblno] = NIL) then + begin + fdct^.divisors[qtblno] := DCTELEM_FIELD_PTR( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + DCTSIZE2 * SIZEOF(DCTELEM)) ); + end; + dtbl := fdct^.divisors[qtblno]; + for i := 0 to pred(DCTSIZE2) do + begin + dtbl^[i] := (DCTELEM(qtbl^.quantval[i])) shl 3; + end; + end; +{$endif} +{$ifdef DCT_IFAST_SUPPORTED} + JDCT_IFAST: + begin + { For AA&N IDCT method, divisors are equal to quantization + coefficients scaled by scalefactor[row]*scalefactor[col], where + scalefactor[0] := 1 + scalefactor[k] := cos(k*PI/16) * sqrt(2) for k=1..7 + We apply a further scale factor of 8. } + + + if (fdct^.divisors[qtblno] = NIL) then + begin + fdct^.divisors[qtblno] := DCTELEM_FIELD_PTR( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + DCTSIZE2 * SIZEOF(DCTELEM)) ); + end; + dtbl := fdct^.divisors[qtblno]; + for i := 0 to pred(DCTSIZE2) do + begin + dtbl^[i] := DCTELEM( + {MULTIPLY16V16} + DESCALE( INT32(qtbl^.quantval[i]) * INT32 (aanscales[i]), + CONST_BITS-3) ); + end; + end; +{$endif} +{$ifdef DCT_FLOAT_SUPPORTED} + + JDCT_FLOAT: + begin + { For float AA&N IDCT method, divisors are equal to quantization + coefficients scaled by scalefactor[row]*scalefactor[col], where + scalefactor[0] := 1 + scalefactor[k] := cos(k*PI/16) * sqrt(2) for k=1..7 + We apply a further scale factor of 8. + What's actually stored is 1/divisor so that the inner loop can + use a multiplication rather than a division. } + + if (fdct^.float_divisors[qtblno] = NIL) then + begin + fdct^.float_divisors[qtblno] := FAST_FLOAT_FIELD_PTR( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + DCTSIZE2 * SIZEOF(FAST_FLOAT)) ); + end; + fdtbl := fdct^.float_divisors[qtblno]; + i := 0; + for row := 0 to pred(DCTSIZE) do + begin + for col := 0 to pred(DCTSIZE) do + begin + fdtbl^[i] := {FAST_FLOAT} + (1.0 / (( {double}(qtbl^.quantval[i]) * + aanscalefactor[row] * aanscalefactor[col] * 8.0))); + Inc(i); + end; + end; + end; +{$endif} + else + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); + end; + Inc(compptr); + end; +end; + + +{ Perform forward DCT on one or more blocks of a component. + + The input samples are taken from the sample_data[] array starting at + position start_row/start_col, and moving to the right for any additional + blocks. The quantized coefficients are returned in coef_blocks[]. } + +{METHODDEF} +procedure forward_DCT (cinfo : j_compress_ptr; + compptr : jpeg_component_info_ptr; + sample_data : JSAMPARRAY; + coef_blocks : JBLOCKROW; + start_row : JDIMENSION; + start_col : JDIMENSION; + num_blocks : JDIMENSION); +{ This version is used for integer DCT implementations. } +var + { This routine is heavily used, so it's worth coding it tightly. } + fdct : my_fdct_ptr; + do_dct : forward_DCT_method_ptr; + divisors : DCTELEM_FIELD_PTR; + workspace : array[0..DCTSIZE2-1] of DCTELEM; { work area for FDCT subroutine } + bi : JDIMENSION; +var + {register} workspaceptr : DCTELEMPTR; + {register} elemptr : JSAMPLE_PTR; + {register} elemr : int; +{$ifndef DCTSIZE_IS_8} +var + {register} elemc : int; +{$endif} +var + {register} temp, qval : DCTELEM; + {register} i : int; + {register} output_ptr : JCOEFPTR; +begin + fdct := my_fdct_ptr (cinfo^.fdct); + do_dct := fdct^.do_dct; + divisors := fdct^.divisors[compptr^.quant_tbl_no]; + + Inc(JSAMPROW_PTR(sample_data), start_row); { fold in the vertical offset once } + + for bi := 0 to pred(num_blocks) do + begin + + { Load data into workspace, applying unsigned->signed conversion } + + workspaceptr := @workspace[0]; + for elemr := 0 to pred(DCTSIZE) do + begin + elemptr := @sample_data^[elemr]^[start_col]; +{$ifdef DCTSIZE_IS_8} { unroll the inner loop } + workspaceptr^ := GETJSAMPLE(elemptr^) - CENTERJSAMPLE; + Inc(workspaceptr); + Inc(elemptr); + workspaceptr^ := GETJSAMPLE(elemptr^) - CENTERJSAMPLE; + Inc(workspaceptr); + Inc(elemptr); + workspaceptr^ := GETJSAMPLE(elemptr^) - CENTERJSAMPLE; + Inc(workspaceptr); + Inc(elemptr); + workspaceptr^ := GETJSAMPLE(elemptr^) - CENTERJSAMPLE; + Inc(workspaceptr); + Inc(elemptr); + workspaceptr^ := GETJSAMPLE(elemptr^) - CENTERJSAMPLE; + Inc(workspaceptr); + Inc(elemptr); + workspaceptr^ := GETJSAMPLE(elemptr^) - CENTERJSAMPLE; + Inc(workspaceptr); + Inc(elemptr); + workspaceptr^ := GETJSAMPLE(elemptr^) - CENTERJSAMPLE; + Inc(workspaceptr); + Inc(elemptr); + workspaceptr^ := GETJSAMPLE(elemptr^) - CENTERJSAMPLE; + Inc(workspaceptr); + {Inc(elemptr); - Value never used } +{$else} + for elemc := pred(DCTSIZE) downto 0 do + begin + workspaceptr^ := GETJSAMPLE(elemptr^) - CENTERJSAMPLE; + Inc(workspaceptr); + Inc(elemptr); + end; +{$endif} + end; + + { Perform the DCT } + do_dct (workspace); + + { Quantize/descale the coefficients, and store into coef_blocks[] } + + output_ptr := JCOEFPTR(@coef_blocks^[bi]); + for i := 0 to pred(DCTSIZE2) do + begin + qval := divisors^[i]; + temp := workspace[i]; + { Divide the coefficient value by qval, ensuring proper rounding. + Since C does not specify the direction of rounding for negative + quotients, we have to force the dividend positive for portability. + + In most files, at least half of the output values will be zero + (at default quantization settings, more like three-quarters...) + so we should ensure that this case is fast. On many machines, + a comparison is enough cheaper than a divide to make a special test + a win. Since both inputs will be nonnegative, we need only test + for a < b to discover whether a/b is 0. + If your machine's division is fast enough, define FAST_DIVIDE. } + + if (temp < 0) then + begin + temp := -temp; + Inc(temp, qval shr 1); { for rounding } + {DIVIDE_BY(temp, qval);} + {$ifdef FAST_DIVIDE} + temp := temp div qval; + {$else} + if (temp >= qval) then + temp := temp div qval + else + temp := 0; + {$endif} + temp := -temp; + end + else + begin + Inc(temp, qval shr 1); { for rounding } + {DIVIDE_BY(temp, qval);} + {$ifdef FAST_DIVIDE} + temp := temp div qval; + {$else} + if (temp >= qval) then + temp := temp div qval + else + temp := 0; + {$endif} + end; + output_ptr^[i] := JCOEF (temp); + end; + Inc(start_col, DCTSIZE); + end; +end; + + +{$ifdef DCT_FLOAT_SUPPORTED} + +{METHODDEF} +procedure forward_DCT_float (cinfo : j_compress_ptr; + compptr : jpeg_component_info_ptr; + sample_data : JSAMPARRAY; + coef_blocks : JBLOCKROW; + start_row : JDIMENSION; + start_col : JDIMENSION; + num_blocks : JDIMENSION); +{ This version is used for floating-point DCT implementations. } +var + { This routine is heavily used, so it's worth coding it tightly. } + fdct : my_fdct_ptr; + do_dct : float_DCT_method_ptr; + divisors : FAST_FLOAT_FIELD_PTR; + workspace : array[0..DCTSIZE2-1] of FAST_FLOAT; { work area for FDCT subroutine } + bi : JDIMENSION; +var + {register} workspaceptr : FAST_FLOAT_PTR; + {register} elemptr : JSAMPLE_PTR; + {register} elemr : int; +{$ifndef DCTSIZE_IS_8} +var + {register} elemc : int; +{$endif} +var + {register} temp : FAST_FLOAT; + {register} i : int; + {register} output_ptr : JCOEFPTR; +begin + fdct := my_fdct_ptr (cinfo^.fdct); + do_dct := fdct^.do_float_dct; + divisors := fdct^.float_divisors[compptr^.quant_tbl_no]; + + Inc(JSAMPROW_PTR(sample_data), start_row); { fold in the vertical offset once } + + for bi := 0 to pred(num_blocks) do + begin + { Load data into workspace, applying unsigned->signed conversion } + + workspaceptr := @workspace[0]; + for elemr := 0 to pred(DCTSIZE) do + begin + elemptr := @(sample_data^[elemr]^[start_col]); +{$ifdef DCTSIZE_IS_8} { unroll the inner loop } + workspaceptr^ := {FAST_FLOAT}(GETJSAMPLE(elemptr^) - CENTERJSAMPLE); + Inc(workspaceptr); + Inc(elemptr); + workspaceptr^ := {FAST_FLOAT}(GETJSAMPLE(elemptr^) - CENTERJSAMPLE); + Inc(workspaceptr); + Inc(elemptr); + workspaceptr^ := {FAST_FLOAT}(GETJSAMPLE(elemptr^) - CENTERJSAMPLE); + Inc(workspaceptr); + Inc(elemptr); + workspaceptr^ := {FAST_FLOAT}(GETJSAMPLE(elemptr^) - CENTERJSAMPLE); + Inc(workspaceptr); + Inc(elemptr); + workspaceptr^ := {FAST_FLOAT}(GETJSAMPLE(elemptr^) - CENTERJSAMPLE); + Inc(workspaceptr); + Inc(elemptr); + workspaceptr^ := {FAST_FLOAT}(GETJSAMPLE(elemptr^) - CENTERJSAMPLE); + Inc(workspaceptr); + Inc(elemptr); + workspaceptr^ := {FAST_FLOAT}(GETJSAMPLE(elemptr^) - CENTERJSAMPLE); + Inc(workspaceptr); + Inc(elemptr); + workspaceptr^ := {FAST_FLOAT}(GETJSAMPLE(elemptr^) - CENTERJSAMPLE); + Inc(workspaceptr); + {Inc(elemptr); - value never used } +{$else} + for elemc := pred(DCTSIZE) downto 0 do + begin + workspaceptr^ := {FAST_FLOAT}( + (GETJSAMPLE(elemptr^) - CENTERJSAMPLE) ); + Inc(workspaceptr); + Inc(elemptr); + end; +{$endif} + end; + + + { Perform the DCT } + do_dct (workspace); + + { Quantize/descale the coefficients, and store into coef_blocks[] } + + output_ptr := JCOEFPTR(@(coef_blocks^[bi])); + + for i := 0 to pred(DCTSIZE2) do + begin + { Apply the quantization and scaling factor } + temp := workspace[i] * divisors^[i]; + { Round to nearest integer. + Since C does not specify the direction of rounding for negative + quotients, we have to force the dividend positive for portability. + The maximum coefficient size is +-16K (for 12-bit data), so this + code should work for either 16-bit or 32-bit ints. } + output_ptr^[i] := JCOEF ( int(Trunc (temp + {FAST_FLOAT}(16384.5))) - 16384); + end; + Inc(start_col, DCTSIZE); + end; +end; + +{$endif} { DCT_FLOAT_SUPPORTED } + + +{ Initialize FDCT manager. } + +{GLOBAL} +procedure jinit_forward_dct (cinfo : j_compress_ptr); +var + fdct : my_fdct_ptr; + i : int; +begin + fdct := my_fdct_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(my_fdct_controller)) ); + cinfo^.fdct := jpeg_forward_dct_ptr (fdct); + fdct^.pub.start_pass := start_pass_fdctmgr; + + case (cinfo^.dct_method) of +{$ifdef DCT_ISLOW_SUPPORTED} + JDCT_ISLOW: + begin + fdct^.pub.forward_DCT := forward_DCT; + fdct^.do_dct := jpeg_fdct_islow; + end; +{$endif} +{$ifdef DCT_IFAST_SUPPORTED} + JDCT_IFAST: + begin + fdct^.pub.forward_DCT := forward_DCT; + fdct^.do_dct := jpeg_fdct_ifast; + end; +{$endif} +{$ifdef DCT_FLOAT_SUPPORTED} + JDCT_FLOAT: + begin + fdct^.pub.forward_DCT := forward_DCT_float; + fdct^.do_float_dct := jpeg_fdct_float; + end; +{$endif} + else + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); + end; + + { Mark divisor tables unallocated } + for i := 0 to pred(NUM_QUANT_TBLS) do + begin + fdct^.divisors[i] := NIL; +{$ifdef DCT_FLOAT_SUPPORTED} + fdct^.float_divisors[i] := NIL; +{$endif} + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jchuff_del.pas b/mseide-msegui/lib/common/fpccompatibility/jchuff_del.pas new file mode 100644 index 0000000..163dd14 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jchuff_del.pas @@ -0,0 +1,1118 @@ +Unit jchuff_del; + +{ This file contains Huffman entropy encoding routines. + + Much of the complexity here has to do with supporting output suspension. + If the data destination module demands suspension, we want to be able to + back up to the start of the current MCU. To do this, we copy state + variables into local working storage, and update them back to the + permanent JPEG objects only upon successful completion of an MCU. } + +{ Original: jchuff.c; Copyright (C) 1991-1997, Thomas G. Lane. } + +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, { longptr definition missing } + jpeglib_del, + jdeferr_del, + jerror_del, + jutils_del, + jinclude_del, + jcomapi_del; + +{ The legal range of a DCT coefficient is + -1024 .. +1023 for 8-bit data; + -16384 .. +16383 for 12-bit data. + Hence the magnitude should always fit in 10 or 14 bits respectively. } + + +{$ifdef BITS_IN_JSAMPLE_IS_8} +const + MAX_COEF_BITS = 10; +{$else} +const + MAX_COEF_BITS = 14; +{$endif} + +{ Derived data constructed for each Huffman table } +{ Declarations shared with jcphuff.c } +type + c_derived_tbl_ptr = ^c_derived_tbl; + c_derived_tbl = record + ehufco : array[0..256-1] of uInt; { code for each symbol } + ehufsi : array[0..256-1] of byte; { length of code for each symbol } + { If no code has been allocated for a symbol S, ehufsi[S] contains 0 } + end; +{ for JCHUFF und JCPHUFF } +type + TLongTable = array[0..256] of long; + TLongTablePtr = ^TLongTable; + +{ Compute the derived values for a Huffman table. + Note this is also used by jcphuff.c. } + +{GLOBAL} +procedure jpeg_make_c_derived_tbl (cinfo : j_compress_ptr; + isDC : boolean; + tblno : int; + var pdtbl : c_derived_tbl_ptr); + +{ Generate the optimal coding for the given counts, fill htbl. + Note this is also used by jcphuff.c. } + +{GLOBAL} +procedure jpeg_gen_optimal_table (cinfo : j_compress_ptr; + htbl : JHUFF_TBL_PTR; + var freq : TLongTable); { Nomssi } + +{ Module initialization routine for Huffman entropy encoding. } + +{GLOBAL} +procedure jinit_huff_encoder (cinfo : j_compress_ptr); + +implementation + +{ Expanded entropy encoder object for Huffman encoding. + + The savable_state subrecord contains fields that change within an MCU, + but must not be updated permanently until we complete the MCU. } + +type + savable_state = record + put_buffer : INT32; { current bit-accumulation buffer } + put_bits : int; { # of bits now in it } + last_dc_val : array[0..MAX_COMPS_IN_SCAN-1] of int; + { last DC coef for each component } + end; + + +type + huff_entropy_ptr = ^huff_entropy_encoder; + huff_entropy_encoder = record + pub : jpeg_entropy_encoder; { public fields } + + saved : savable_state; { Bit buffer & DC state at start of MCU } + + { These fields are NOT loaded into local working state. } + restarts_to_go : uInt; { MCUs left in this restart interval } + next_restart_num : int; { next restart number to write (0-7) } + + { Pointers to derived tables (these workspaces have image lifespan) } + dc_derived_tbls : array[0..NUM_HUFF_TBLS-1] of c_derived_tbl_ptr; + ac_derived_tbls : array[0..NUM_HUFF_TBLS-1] of c_derived_tbl_ptr; + + {$ifdef ENTROPY_OPT_SUPPORTED} { Statistics tables for optimization } + dc_count_ptrs : array[0..NUM_HUFF_TBLS-1] of TLongTablePtr; + ac_count_ptrs : array[0..NUM_HUFF_TBLS-1] of TLongTablePtr; + {$endif} + end; + + + +{ Working state while writing an MCU. + This struct contains all the fields that are needed by subroutines. } + +type + working_state = record + next_output_byte : JOCTETptr; { => next byte to write in buffer } + free_in_buffer : size_t; { # of byte spaces remaining in buffer } + cur : savable_state; { Current bit buffer & DC state } + cinfo : j_compress_ptr; { dump_buffer needs access to this } + end; + + +{ Forward declarations } +{METHODDEF} +function encode_mcu_huff (cinfo : j_compress_ptr; + const MCU_data : array of JBLOCKROW) : boolean; + forward; +{METHODDEF} +procedure finish_pass_huff (cinfo : j_compress_ptr); forward; +{$ifdef ENTROPY_OPT_SUPPORTED} +{METHODDEF} +function encode_mcu_gather (cinfo : j_compress_ptr; + const MCU_data: array of JBLOCKROW) : boolean; + forward; + +{METHODDEF} +procedure finish_pass_gather (cinfo : j_compress_ptr); forward; +{$endif} + + +{ Initialize for a Huffman-compressed scan. + If gather_statistics is TRUE, we do not output anything during the scan, + just count the Huffman symbols used and generate Huffman code tables. } + +{METHODDEF} +procedure start_pass_huff (cinfo : j_compress_ptr; + gather_statistics : boolean); +var + entropy : huff_entropy_ptr; + ci, dctbl, actbl : int; + compptr : jpeg_component_info_ptr; +begin + entropy := huff_entropy_ptr (cinfo^.entropy); + + if (gather_statistics) then + begin +{$ifdef ENTROPY_OPT_SUPPORTED} + entropy^.pub.encode_mcu := encode_mcu_gather; + entropy^.pub.finish_pass := finish_pass_gather; +{$else} + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); +{$endif} + end + else + begin + entropy^.pub.encode_mcu := encode_mcu_huff; + entropy^.pub.finish_pass := finish_pass_huff; + end; + + for ci := 0 to pred(cinfo^.comps_in_scan) do + begin + compptr := cinfo^.cur_comp_info[ci]; + dctbl := compptr^.dc_tbl_no; + actbl := compptr^.ac_tbl_no; + if (gather_statistics) then + begin +{$ifdef ENTROPY_OPT_SUPPORTED} + { Check for invalid table indexes } + { (make_c_derived_tbl does this in the other path) } + if (dctbl < 0) or (dctbl >= NUM_HUFF_TBLS) then + ERREXIT1(j_common_ptr(cinfo), JERR_NO_HUFF_TABLE, dctbl); + if (actbl < 0) or (actbl >= NUM_HUFF_TBLS) then + ERREXIT1(j_common_ptr(cinfo), JERR_NO_HUFF_TABLE, actbl); + { Allocate and zero the statistics tables } + { Note that jpeg_gen_optimal_table expects 257 entries in each table! } + if (entropy^.dc_count_ptrs[dctbl] = NIL) then + entropy^.dc_count_ptrs[dctbl] := TLongTablePtr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + 257 * SIZEOF(long)) ); + MEMZERO(entropy^.dc_count_ptrs[dctbl], 257 * SIZEOF(long)); + if (entropy^.ac_count_ptrs[actbl] = NIL) then + entropy^.ac_count_ptrs[actbl] := TLongTablePtr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + 257 * SIZEOF(long)) ); + MEMZERO(entropy^.ac_count_ptrs[actbl], 257 * SIZEOF(long)); +{$endif} + end + else + begin + { Compute derived values for Huffman tables } + { We may do this more than once for a table, but it's not expensive } + jpeg_make_c_derived_tbl(cinfo, TRUE, dctbl, + entropy^.dc_derived_tbls[dctbl]); + jpeg_make_c_derived_tbl(cinfo, FALSE, actbl, + entropy^.ac_derived_tbls[actbl]); + end; + { Initialize DC predictions to 0 } + entropy^.saved.last_dc_val[ci] := 0; + end; + + { Initialize bit buffer to empty } + entropy^.saved.put_buffer := 0; + entropy^.saved.put_bits := 0; + + { Initialize restart stuff } + entropy^.restarts_to_go := cinfo^.restart_interval; + entropy^.next_restart_num := 0; +end; + + +{ Compute the derived values for a Huffman table. + This routine also performs some validation checks on the table. + + Note this is also used by jcphuff.c. } + +{GLOBAL} +procedure jpeg_make_c_derived_tbl (cinfo : j_compress_ptr; + isDC : boolean; + tblno : int; + var pdtbl : c_derived_tbl_ptr); +var + htbl : JHUFF_TBL_PTR; + dtbl : c_derived_tbl_ptr; + p, i, l, lastp, si, maxsymbol : int; + huffsize : array[0..257-1] of byte; + huffcode : array[0..257-1] of uInt; + code : uInt; +begin + { Note that huffsize[] and huffcode[] are filled in code-length order, + paralleling the order of the symbols themselves in htbl->huffval[]. } + + { Find the input Huffman table } + if (tblno < 0) or (tblno >= NUM_HUFF_TBLS) then + ERREXIT1(j_common_ptr(cinfo), JERR_NO_HUFF_TABLE, tblno); + if isDC then + htbl := cinfo^.dc_huff_tbl_ptrs[tblno] + else + htbl := cinfo^.ac_huff_tbl_ptrs[tblno]; + if (htbl = NIL) then + ERREXIT1(j_common_ptr(cinfo), JERR_NO_HUFF_TABLE, tblno); + + { Allocate a workspace if we haven't already done so. } + if (pdtbl = NIL) then + pdtbl := c_derived_tbl_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(c_derived_tbl)) ); + dtbl := pdtbl; + + { Figure C.1: make table of Huffman code length for each symbol } + + p := 0; + for l := 1 to 16 do + begin + i := int(htbl^.bits[l]); + if (i < 0) and (p + i > 256) then { protect against table overrun } + ERREXIT(j_common_ptr(cinfo), JERR_BAD_HUFF_TABLE); + while (i > 0) do + begin + huffsize[p] := byte(l); + Inc(p); + Dec(i); + end; + end; + huffsize[p] := 0; + lastp := p; + + { Figure C.2: generate the codes themselves } + { We also validate that the counts represent a legal Huffman code tree. } + + code := 0; + si := huffsize[0]; + p := 0; + while (huffsize[p] <> 0) do + begin + while (( int(huffsize[p]) ) = si) do + begin + huffcode[p] := code; + Inc(p); + Inc(code); + end; + { code is now 1 more than the last code used for codelength si; but + it must still fit in si bits, since no code is allowed to be all ones. } + + if (INT32(code) >= (INT32(1) shl si)) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_HUFF_TABLE); + code := code shl 1; + Inc(si); + end; + + { Figure C.3: generate encoding tables } + { These are code and size indexed by symbol value } + + { Set all codeless symbols to have code length 0; + this lets us detect duplicate VAL entries here, and later + allows emit_bits to detect any attempt to emit such symbols. } + + MEMZERO(@dtbl^.ehufsi, SIZEOF(dtbl^.ehufsi)); + + { This is also a convenient place to check for out-of-range + and duplicated VAL entries. We allow 0..255 for AC symbols + but only 0..15 for DC. (We could constrain them further + based on data depth and mode, but this seems enough.) } + + if isDC then + maxsymbol := 15 + else + maxsymbol := 255; + + for p := 0 to pred(lastp) do + begin + i := htbl^.huffval[p]; + if (i < 0) or (i > maxsymbol) or (dtbl^.ehufsi[i] <> 0) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_HUFF_TABLE); + dtbl^.ehufco[i] := huffcode[p]; + dtbl^.ehufsi[i] := huffsize[p]; + end; +end; + + +{ Outputting bytes to the file } + + +{LOCAL} +function dump_buffer (var state : working_state) : boolean; +{ Empty the output buffer; return TRUE if successful, FALSE if must suspend } +var + dest : jpeg_destination_mgr_ptr; +begin + dest := state.cinfo^.dest; + + if (not dest^.empty_output_buffer (state.cinfo)) then + begin + dump_buffer := FALSE; + exit; + end; + { After a successful buffer dump, must reset buffer pointers } + state.next_output_byte := dest^.next_output_byte; + state.free_in_buffer := dest^.free_in_buffer; + dump_buffer := TRUE; +end; + + +{ Outputting bits to the file } + +{ Only the right 24 bits of put_buffer are used; the valid bits are + left-justified in this part. At most 16 bits can be passed to emit_bits + in one call, and we never retain more than 7 bits in put_buffer + between calls, so 24 bits are sufficient. } + + +{LOCAL} +function emit_bits (var state : working_state; + code : uInt; + size : int) : boolean; {INLINE} +{ Emit some bits; return TRUE if successful, FALSE if must suspend } +var + { This routine is heavily used, so it's worth coding tightly. } + {register} put_buffer : INT32; + {register} put_bits : int; +var + c : int; +begin + put_buffer := INT32 (code); + put_bits := state.cur.put_bits; + + { if size is 0, caller used an invalid Huffman table entry } + if (size = 0) then + ERREXIT(j_common_ptr(state.cinfo), JERR_HUFF_MISSING_CODE); + + put_buffer := put_buffer and pred(INT32(1) shl size); + { mask off any extra bits in code } + + Inc(put_bits, size); { new number of bits in buffer } + + put_buffer := put_buffer shl (24 - put_bits); + { align incoming bits } + put_buffer := put_buffer or state.cur.put_buffer; + { and merge with old buffer contents } + while (put_bits >= 8) do + begin + c := int ((put_buffer shr 16) and $FF); + + {emit_byte(state, c, return FALSE);} + { Emit a byte, return FALSE if must suspend. } + state.next_output_byte^ := JOCTET (c); + Inc(state.next_output_byte); + Dec(state.free_in_buffer); + if (state.free_in_buffer = 0) then + if not dump_buffer(state) then + begin + emit_bits := FALSE; + exit; + end; + + if (c = $FF) then { need to stuff a zero byte? } + begin + {emit_byte(state, 0, return FALSE);} + state.next_output_byte^ := JOCTET (0); + Inc(state.next_output_byte); + Dec(state.free_in_buffer); + if (state.free_in_buffer = 0) then + if not dump_buffer(state) then + begin + emit_bits := FALSE; + exit; + end; + + end; + put_buffer := put_buffer shl 8; + Dec(put_bits, 8); + end; + + state.cur.put_buffer := put_buffer; { update state variables } + state.cur.put_bits := put_bits; + + emit_bits := TRUE; +end; + + +{LOCAL} +function flush_bits (var state : working_state) : boolean; +begin + if (not emit_bits(state, $7F, 7)) then { fill any partial byte with ones } + begin + flush_bits := FALSE; + exit; + end; + state.cur.put_buffer := 0; { and reset bit-buffer to empty } + state.cur.put_bits := 0; + flush_bits := TRUE; +end; + + +{ Encode a single block's worth of coefficients } + +{LOCAL} +function encode_one_block (var state : working_state; + const block : JBLOCK; + last_dc_val : int; + dctbl : c_derived_tbl_ptr; + actbl : c_derived_tbl_ptr) : boolean; +var + {register} temp, temp2 : int; + {register} nbits : int; + {register} k, r, i : int; +begin + { Encode the DC coefficient difference per section F.1.2.1 } + + temp2 := block[0] - last_dc_val; + temp := temp2; + + if (temp < 0) then + begin + temp := -temp; { temp is abs value of input } + { For a negative input, want temp2 := bitwise complement of abs(input) } + { This code assumes we are on a two's complement machine } + Dec(temp2); + end; + + { Find the number of bits needed for the magnitude of the coefficient } + nbits := 0; + while (temp <> 0) do + begin + Inc(nbits); + temp := temp shr 1; + end; + + { Check for out-of-range coefficient values. + Since we're encoding a difference, the range limit is twice as much. } + + if (nbits > MAX_COEF_BITS+1) then + ERREXIT(j_common_ptr(state.cinfo), JERR_BAD_DCT_COEF); + + { Emit the Huffman-coded symbol for the number of bits } + if not emit_bits(state, dctbl^.ehufco[nbits], dctbl^.ehufsi[nbits]) then + begin + encode_one_block := FALSE; + exit; + end; + + { Emit that number of bits of the value, if positive, } + { or the complement of its magnitude, if negative. } + if (nbits <> 0) then { emit_bits rejects calls with size 0 } + if not emit_bits(state, uInt(temp2), nbits) then + begin + encode_one_block := FALSE; + exit; + end; + + { Encode the AC coefficients per section F.1.2.2 } + + r := 0; { r := run length of zeros } + + for k := 1 to pred(DCTSIZE2) do + begin + temp := block[jpeg_natural_order[k]]; + if (temp = 0) then + begin + Inc(r); + end + else + begin + { if run length > 15, must emit special run-length-16 codes ($F0) } + while (r > 15) do + begin + if not emit_bits(state, actbl^.ehufco[$F0], actbl^.ehufsi[$F0]) then + begin + encode_one_block := FALSE; + exit; + end; + Dec(r, 16); + end; + + temp2 := temp; + if (temp < 0) then + begin + temp := -temp; { temp is abs value of input } + { This code assumes we are on a two's complement machine } + Dec(temp2); + end; + + { Find the number of bits needed for the magnitude of the coefficient } + nbits := 0; { there must be at least one 1 bit } + repeat + Inc(nbits); + temp := temp shr 1; + until (temp = 0); + + { Check for out-of-range coefficient values } + if (nbits > MAX_COEF_BITS) then + ERREXIT(j_common_ptr(state.cinfo), JERR_BAD_DCT_COEF); + + { Emit Huffman symbol for run length / number of bits } + i := (r shl 4) + nbits; + if not emit_bits(state, actbl^.ehufco[i], actbl^.ehufsi[i]) then + begin + encode_one_block := FALSE; + exit; + end; + + { Emit that number of bits of the value, if positive, } + { or the complement of its magnitude, if negative. } + if not emit_bits(state, uInt(temp2), nbits) then + begin + encode_one_block := FALSE; + exit; + end; + + r := 0; + end; + end; + + { If the last coef(s) were zero, emit an end-of-block code } + if (r > 0) then + if not emit_bits(state, actbl^.ehufco[0], actbl^.ehufsi[0]) then + begin + encode_one_block := FALSE; + exit; + end; + + encode_one_block := TRUE; +end; + + +{ Emit a restart marker & resynchronize predictions. } + +{LOCAL} +function emit_restart (var state : working_state; + restart_num : int) : boolean; +var + ci : int; +begin + if (not flush_bits(state)) then + begin + emit_restart := FALSE; + exit; + end; + + {emit_byte(state, $FF, return FALSE);} + { Emit a byte, return FALSE if must suspend. } + state.next_output_byte^ := JOCTET ($FF); + Inc(state.next_output_byte); + Dec(state.free_in_buffer); + if (state.free_in_buffer = 0) then + if not dump_buffer(state) then + begin + emit_restart := FALSE; + exit; + end; + + {emit_byte(state, JPEG_RST0 + restart_num, return FALSE);} + { Emit a byte, return FALSE if must suspend. } + state.next_output_byte^ := JOCTET (JPEG_RST0 + restart_num); + Inc(state.next_output_byte); + Dec(state.free_in_buffer); + if (state.free_in_buffer = 0) then + if not dump_buffer(state) then + begin + emit_restart := FALSE; + exit; + end; + + { Re-initialize DC predictions to 0 } + for ci := 0 to pred(state.cinfo^.comps_in_scan) do + state.cur.last_dc_val[ci] := 0; + + { The restart counter is not updated until we successfully write the MCU. } + + emit_restart := TRUE; +end; + + +{ Encode and output one MCU's worth of Huffman-compressed coefficients. } + +{METHODDEF} +function encode_mcu_huff (cinfo : j_compress_ptr; + const MCU_data: array of JBLOCKROW) : boolean; +var + entropy : huff_entropy_ptr; + state : working_state; + blkn, ci : int; + compptr : jpeg_component_info_ptr; +begin + entropy := huff_entropy_ptr (cinfo^.entropy); + { Load up working state } + state.next_output_byte := cinfo^.dest^.next_output_byte; + state.free_in_buffer := cinfo^.dest^.free_in_buffer; + {ASSIGN_STATE(state.cur, entropy^.saved);} + state.cur := entropy^.saved; + state.cinfo := cinfo; + + { Emit restart marker if needed } + if (cinfo^.restart_interval <> 0) then + begin + if (entropy^.restarts_to_go = 0) then + if not emit_restart(state, entropy^.next_restart_num) then + begin + encode_mcu_huff := FALSE; + exit; + end; + end; + + { Encode the MCU data blocks } + for blkn := 0 to pred(cinfo^.blocks_in_MCU) do + begin + ci := cinfo^.MCU_membership[blkn]; + compptr := cinfo^.cur_comp_info[ci]; + if not encode_one_block(state, + MCU_data[blkn]^[0], + state.cur.last_dc_val[ci], + entropy^.dc_derived_tbls[compptr^.dc_tbl_no], + entropy^.ac_derived_tbls[compptr^.ac_tbl_no]) then + begin + encode_mcu_huff := FALSE; + exit; + end; + { Update last_dc_val } + state.cur.last_dc_val[ci] := MCU_data[blkn]^[0][0]; + end; + + { Completed MCU, so update state } + cinfo^.dest^.next_output_byte := state.next_output_byte; + cinfo^.dest^.free_in_buffer := state.free_in_buffer; + {ASSIGN_STATE(entropy^.saved, state.cur);} + entropy^.saved := state.cur; + + { Update restart-interval state too } + if (cinfo^.restart_interval <> 0) then + begin + if (entropy^.restarts_to_go = 0) then + begin + entropy^.restarts_to_go := cinfo^.restart_interval; + Inc(entropy^.next_restart_num); + with entropy^ do + next_restart_num := next_restart_num and 7; + end; + Dec(entropy^.restarts_to_go); + end; + + encode_mcu_huff := TRUE; +end; + + +{ Finish up at the end of a Huffman-compressed scan. } + +{METHODDEF} +procedure finish_pass_huff (cinfo : j_compress_ptr); +var + entropy : huff_entropy_ptr; + state : working_state; +begin + entropy := huff_entropy_ptr (cinfo^.entropy); + + { Load up working state ... flush_bits needs it } + state.next_output_byte := cinfo^.dest^.next_output_byte; + state.free_in_buffer := cinfo^.dest^.free_in_buffer; + {ASSIGN_STATE(state.cur, entropy^.saved);} + state.cur := entropy^.saved; + state.cinfo := cinfo; + + { Flush out the last data } + if not flush_bits(state) then + ERREXIT(j_common_ptr(cinfo), JERR_CANT_SUSPEND); + + { Update state } + cinfo^.dest^.next_output_byte := state.next_output_byte; + cinfo^.dest^.free_in_buffer := state.free_in_buffer; + {ASSIGN_STATE(entropy^.saved, state.cur);} + entropy^.saved := state.cur; +end; + + +{ Huffman coding optimization. + + We first scan the supplied data and count the number of uses of each symbol + that is to be Huffman-coded. (This process MUST agree with the code above.) + Then we build a Huffman coding tree for the observed counts. + Symbols which are not needed at all for the particular image are not + assigned any code, which saves space in the DHT marker as well as in + the compressed data. } + +{$ifdef ENTROPY_OPT_SUPPORTED} + + +{ Process a single block's worth of coefficients } + +{LOCAL} +procedure htest_one_block (cinfo : j_compress_ptr; + const block : JBLOCK; + last_dc_val : int; + dc_counts : TLongTablePtr; + ac_counts : TLongTablePtr); + +var + {register} temp : int; + {register} nbits : int; + {register} k, r : int; +begin + { Encode the DC coefficient difference per section F.1.2.1 } + temp := block[0] - last_dc_val; + if (temp < 0) then + temp := -temp; + + { Find the number of bits needed for the magnitude of the coefficient } + nbits := 0; + while (temp <> 0) do + begin + Inc(nbits); + temp := temp shr 1; + end; + + { Check for out-of-range coefficient values. + Since we're encoding a difference, the range limit is twice as much. } + + if (nbits > MAX_COEF_BITS+1) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_DCT_COEF); + + { Count the Huffman symbol for the number of bits } + Inc(dc_counts^[nbits]); + + { Encode the AC coefficients per section F.1.2.2 } + + r := 0; { r := run length of zeros } + + for k := 1 to pred(DCTSIZE2) do + begin + temp := block[jpeg_natural_order[k]]; + if (temp = 0) then + begin + Inc(r); + end + else + begin + { if run length > 15, must emit special run-length-16 codes ($F0) } + while (r > 15) do + begin + Inc(ac_counts^[$F0]); + Dec(r, 16); + end; + + { Find the number of bits needed for the magnitude of the coefficient } + if (temp < 0) then + temp := -temp; + + { Find the number of bits needed for the magnitude of the coefficient } + nbits := 0; { there must be at least one 1 bit } + repeat + Inc(nbits); + temp := temp shr 1; + until (temp = 0); + + + { Count Huffman symbol for run length / number of bits } + Inc(ac_counts^[(r shl 4) + nbits]); + + r := 0; + end; + end; + + { If the last coef(s) were zero, emit an end-of-block code } + if (r > 0) then + Inc(ac_counts^[0]); +end; + + +{ Trial-encode one MCU's worth of Huffman-compressed coefficients. + No data is actually output, so no suspension return is possible. } + +{METHODDEF} +function encode_mcu_gather (cinfo : j_compress_ptr; + const MCU_data: array of JBLOCKROW) : boolean; +var + entropy : huff_entropy_ptr; + blkn, ci : int; + compptr : jpeg_component_info_ptr; +begin + entropy := huff_entropy_ptr (cinfo^.entropy); + { Take care of restart intervals if needed } + if (cinfo^.restart_interval <> 0) then + begin + if (entropy^.restarts_to_go = 0) then + begin + { Re-initialize DC predictions to 0 } + for ci := 0 to pred(cinfo^.comps_in_scan) do + entropy^.saved.last_dc_val[ci] := 0; + { Update restart state } + entropy^.restarts_to_go := cinfo^.restart_interval; + end; + Dec(entropy^.restarts_to_go); + end; + + for blkn := 0 to pred(cinfo^.blocks_in_MCU) do + begin + ci := cinfo^.MCU_membership[blkn]; + compptr := cinfo^.cur_comp_info[ci]; + htest_one_block(cinfo, MCU_data[blkn]^[0], + entropy^.saved.last_dc_val[ci], + entropy^.dc_count_ptrs[compptr^.dc_tbl_no], + entropy^.ac_count_ptrs[compptr^.ac_tbl_no]); + entropy^.saved.last_dc_val[ci] := MCU_data[blkn]^[0][0]; + end; + + encode_mcu_gather := TRUE; +end; + + +{ Generate the best Huffman code table for the given counts, fill htbl. + Note this is also used by jcphuff.c. + + The JPEG standard requires that no symbol be assigned a codeword of all + one bits (so that padding bits added at the end of a compressed segment + can't look like a valid code). Because of the canonical ordering of + codewords, this just means that there must be an unused slot in the + longest codeword length category. Section K.2 of the JPEG spec suggests + reserving such a slot by pretending that symbol 256 is a valid symbol + with count 1. In theory that's not optimal; giving it count zero but + including it in the symbol set anyway should give a better Huffman code. + But the theoretically better code actually seems to come out worse in + practice, because it produces more all-ones bytes (which incur stuffed + zero bytes in the final file). In any case the difference is tiny. + + The JPEG standard requires Huffman codes to be no more than 16 bits long. + If some symbols have a very small but nonzero probability, the Huffman tree + must be adjusted to meet the code length restriction. We currently use + the adjustment method suggested in JPEG section K.2. This method is *not* + optimal; it may not choose the best possible limited-length code. But + typically only very-low-frequency symbols will be given less-than-optimal + lengths, so the code is almost optimal. Experimental comparisons against + an optimal limited-length-code algorithm indicate that the difference is + microscopic --- usually less than a hundredth of a percent of total size. + So the extra complexity of an optimal algorithm doesn't seem worthwhile. } + + +{GLOBAL} +procedure jpeg_gen_optimal_table (cinfo : j_compress_ptr; + htbl : JHUFF_TBL_PTR; + var freq : TLongTable); +const + MAX_CLEN = 32; { assumed maximum initial code length } +var + bits : array[0..MAX_CLEN+1-1] of UINT8; { bits[k] := # of symbols with code length k } + codesize : array[0..257-1] of int; { codesize[k] := code length of symbol k } + others : array[0..257-1] of int; { next symbol in current branch of tree } + c1, c2 : int; + p, i, j : int; + v : long; +begin + { This algorithm is explained in section K.2 of the JPEG standard } + + MEMZERO(@bits, SIZEOF(bits)); + MEMZERO(@codesize, SIZEOF(codesize)); + for i := 0 to 256 do + others[i] := -1; { init links to empty } + + freq[256] := 1; { make sure 256 has a nonzero count } + { Including the pseudo-symbol 256 in the Huffman procedure guarantees + that no real symbol is given code-value of all ones, because 256 + will be placed last in the largest codeword category. } + + { Huffman's basic algorithm to assign optimal code lengths to symbols } + + while TRUE do + begin + { Find the smallest nonzero frequency, set c1 := its symbol } + { In case of ties, take the larger symbol number } + c1 := -1; + v := long(1000000000); + for i := 0 to 256 do + begin + if (freq[i] <> 0) and (freq[i] <= v) then + begin + v := freq[i]; + c1 := i; + end; + end; + + { Find the next smallest nonzero frequency, set c2 := its symbol } + { In case of ties, take the larger symbol number } + c2 := -1; + v := long(1000000000); + for i := 0 to 256 do + begin + if (freq[i] <> 0) and (freq[i] <= v) and (i <> c1) then + begin + v := freq[i]; + c2 := i; + end; + end; + + { Done if we've merged everything into one frequency } + if (c2 < 0) then + break; + + { Else merge the two counts/trees } + Inc(freq[c1], freq[c2]); + freq[c2] := 0; + + { Increment the codesize of everything in c1's tree branch } + Inc(codesize[c1]); + while (others[c1] >= 0) do + begin + c1 := others[c1]; + Inc(codesize[c1]); + end; + + others[c1] := c2; { chain c2 onto c1's tree branch } + + { Increment the codesize of everything in c2's tree branch } + Inc(codesize[c2]); + while (others[c2] >= 0) do + begin + c2 := others[c2]; + Inc(codesize[c2]); + end; + end; + + { Now count the number of symbols of each code length } + for i := 0 to 256 do + begin + if (codesize[i]<>0) then + begin + { The JPEG standard seems to think that this can't happen, } + { but I'm paranoid... } + if (codesize[i] > MAX_CLEN) then + ERREXIT(j_common_ptr(cinfo), JERR_HUFF_CLEN_OVERFLOW); + + Inc(bits[codesize[i]]); + end; + end; + + { JPEG doesn't allow symbols with code lengths over 16 bits, so if the pure + Huffman procedure assigned any such lengths, we must adjust the coding. + Here is what the JPEG spec says about how this next bit works: + Since symbols are paired for the longest Huffman code, the symbols are + removed from this length category two at a time. The prefix for the pair + (which is one bit shorter) is allocated to one of the pair; then, + skipping the BITS entry for that prefix length, a code word from the next + shortest nonzero BITS entry is converted into a prefix for two code words + one bit longer. } + + for i := MAX_CLEN downto 17 do + begin + while (bits[i] > 0) do + begin + j := i - 2; { find length of new prefix to be used } + while (bits[j] = 0) do + Dec(j); + + Dec(bits[i], 2); { remove two symbols } + Inc(bits[i-1]); { one goes in this length } + Inc(bits[j+1], 2); { two new symbols in this length } + Dec(bits[j]); { symbol of this length is now a prefix } + end; + end; + + { Delphi 2: FOR-loop variable 'i' may be undefined after loop } + i := 16; { Nomssi: work around } + + { Remove the count for the pseudo-symbol 256 from the largest codelength } + while (bits[i] = 0) do { find largest codelength still in use } + Dec(i); + Dec(bits[i]); + + { Return final symbol counts (only for lengths 0..16) } + MEMCOPY(@htbl^.bits, @bits, SIZEOF(htbl^.bits)); + + { Return a list of the symbols sorted by code length } + { It's not real clear to me why we don't need to consider the codelength + changes made above, but the JPEG spec seems to think this works. } + + p := 0; + for i := 1 to MAX_CLEN do + begin + for j := 0 to 255 do + begin + if (codesize[j] = i) then + begin + htbl^.huffval[p] := UINT8 (j); + Inc(p); + end; + end; + end; + + { Set sent_table FALSE so updated table will be written to JPEG file. } + htbl^.sent_table := FALSE; +end; + + +{ Finish up a statistics-gathering pass and create the new Huffman tables. } + +{METHODDEF} +procedure finish_pass_gather (cinfo : j_compress_ptr); +var + entropy : huff_entropy_ptr; + ci, dctbl, actbl : int; + compptr : jpeg_component_info_ptr; + htblptr : ^JHUFF_TBL_PTR; + did_dc : array[0..NUM_HUFF_TBLS-1] of boolean; + did_ac : array[0..NUM_HUFF_TBLS-1] of boolean; +begin + entropy := huff_entropy_ptr (cinfo^.entropy); + + { It's important not to apply jpeg_gen_optimal_table more than once + per table, because it clobbers the input frequency counts! } + + MEMZERO(@did_dc, SIZEOF(did_dc)); + MEMZERO(@did_ac, SIZEOF(did_ac)); + + for ci := 0 to pred(cinfo^.comps_in_scan) do + begin + compptr := cinfo^.cur_comp_info[ci]; + dctbl := compptr^.dc_tbl_no; + actbl := compptr^.ac_tbl_no; + if (not did_dc[dctbl]) then + begin + htblptr := @(cinfo^.dc_huff_tbl_ptrs[dctbl]); + if ( htblptr^ = NIL) then + htblptr^ := jpeg_alloc_huff_table(j_common_ptr(cinfo)); + jpeg_gen_optimal_table(cinfo, htblptr^, entropy^.dc_count_ptrs[dctbl]^); + did_dc[dctbl] := TRUE; + end; + if (not did_ac[actbl]) then + begin + htblptr := @(cinfo^.ac_huff_tbl_ptrs[actbl]); + if ( htblptr^ = NIL) then + htblptr^ := jpeg_alloc_huff_table(j_common_ptr(cinfo)); + jpeg_gen_optimal_table(cinfo, htblptr^, entropy^.ac_count_ptrs[actbl]^); + did_ac[actbl] := TRUE; + end; + end; +end; + +{$endif} { ENTROPY_OPT_SUPPORTED } + + +{ Module initialization routine for Huffman entropy encoding. } + +{GLOBAL} +procedure jinit_huff_encoder (cinfo : j_compress_ptr); +var + entropy : huff_entropy_ptr; + i : int; +begin + entropy := huff_entropy_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(huff_entropy_encoder)) ); + cinfo^.entropy := jpeg_entropy_encoder_ptr (entropy); + entropy^.pub.start_pass := start_pass_huff; + + { Mark tables unallocated } + for i := 0 to pred(NUM_HUFF_TBLS) do + begin + entropy^.ac_derived_tbls[i] := NIL; + entropy^.dc_derived_tbls[i] := NIL; +{$ifdef ENTROPY_OPT_SUPPORTED} + entropy^.ac_count_ptrs[i] := NIL; + entropy^.dc_count_ptrs[i] := NIL; +{$endif} + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jcinit_del.pas b/mseide-msegui/lib/common/fpccompatibility/jcinit_del.pas new file mode 100644 index 0000000..a3f2673 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jcinit_del.pas @@ -0,0 +1,97 @@ +Unit jcinit_del; + +{ Original: jcinit.c ; Copyright (C) 1991-1997, Thomas G. Lane. } + +{ This file contains initialization logic for the JPEG compressor. + This routine is in charge of selecting the modules to be executed and + making an initialization call to each one. + + Logically, this code belongs in jcmaster.c. It's split out because + linking this routine implies linking the entire compression library. + For a transcoding-only application, we want to be able to use jcmaster.c + without linking in the whole library. } + +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jinclude_del, + jdeferr_del, + jerror_del, + jpeglib_del, +{$ifdef C_PROGRESSIVE_SUPPORTED} + jcphuff_del, +{$endif} + JcHuff_del, JcMaster_del, JcColor_del, JcSample_del, JcPrepCt_del, + JcDCTMgr_del, JcCoefCT_del, JcMainCT_del, JcMarker_del; + +{ Master selection of compression modules. + This is done once at the start of processing an image. We determine + which modules will be used and give them appropriate initialization calls. } + +{GLOBAL} +procedure jinit_compress_master (cinfo : j_compress_ptr); + +implementation + + + +{ Master selection of compression modules. + This is done once at the start of processing an image. We determine + which modules will be used and give them appropriate initialization calls. } + +{GLOBAL} +procedure jinit_compress_master (cinfo : j_compress_ptr); +begin + { Initialize master control (includes parameter checking/processing) } + jinit_c_master_control(cinfo, FALSE { full compression }); + + { Preprocessing } + if (not cinfo^.raw_data_in) then + begin + jinit_color_converter(cinfo); + jinit_downsampler(cinfo); + jinit_c_prep_controller(cinfo, FALSE { never need full buffer here }); + end; + { Forward DCT } + jinit_forward_dct(cinfo); + { Entropy encoding: either Huffman or arithmetic coding. } + if (cinfo^.arith_code) then + begin + ERREXIT(j_common_ptr(cinfo), JERR_ARITH_NOTIMPL); + end + else + begin + if (cinfo^.progressive_mode) then + begin +{$ifdef C_PROGRESSIVE_SUPPORTED} + jinit_phuff_encoder(cinfo); +{$else} + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); +{$endif} + end + else + jinit_huff_encoder(cinfo); + end; + + { Need a full-image coefficient buffer in any multi-pass mode. } + jinit_c_coef_controller(cinfo, + (cinfo^.num_scans > 1) or (cinfo^.optimize_coding)); + jinit_c_main_controller(cinfo, FALSE { never need full buffer here }); + + jinit_marker_writer(cinfo); + + { We can now tell the memory manager to allocate virtual arrays. } + cinfo^.mem^.realize_virt_arrays (j_common_ptr(cinfo)); + + { Write the datastream header (SOI) immediately. + Frame and scan headers are postponed till later. + This lets application insert special markers after the SOI. } + + cinfo^.marker^.write_file_header (cinfo); +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jcmainct_del.pas b/mseide-msegui/lib/common/fpccompatibility/jcmainct_del.pas new file mode 100644 index 0000000..405156d --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jcmainct_del.pas @@ -0,0 +1,345 @@ +Unit jcmainct_del; + +{ This file contains the main buffer controller for compression. + The main buffer lies between the pre-processor and the JPEG + compressor proper; it holds downsampled data in the JPEG colorspace. } + +{ Original : jcmainct.c ; Copyright (C) 1994-1996, Thomas G. Lane. } + +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +{ Note: currently, there is no operating mode in which a full-image buffer + is needed at this step. If there were, that mode could not be used with + "raw data" input, since this module is bypassed in that case. However, + we've left the code here for possible use in special applications. } + +{$undef FULL_MAIN_BUFFER_SUPPORTED} + +uses + jmorecfg_del, + jinclude_del, + jdeferr_del, + jerror_del, +{$ifdef FULL_MAIN_BUFFER_SUPPORTED} + jutils_del, +{$endif} + jpeglib_del; + +{ Initialize main buffer controller. } + +{GLOBAL} +procedure jinit_c_main_controller (cinfo : j_compress_ptr; + need_full_buffer : boolean); + +implementation + + +{ Private buffer controller object } + +type + my_main_ptr = ^my_main_controller; + my_main_controller = record + pub : jpeg_c_main_controller; { public fields } + + cur_iMCU_row : JDIMENSION; { number of current iMCU row } + rowgroup_ctr : JDIMENSION; { counts row groups received in iMCU row } + suspended : boolean; { remember if we suspended output } + pass_mode : J_BUF_MODE; { current operating mode } + + { If using just a strip buffer, this points to the entire set of buffers + (we allocate one for each component). In the full-image case, this + points to the currently accessible strips of the virtual arrays. } + + buffer : array[0..MAX_COMPONENTS-1] of JSAMPARRAY; + + {$ifdef FULL_MAIN_BUFFER_SUPPORTED} + { If using full-image storage, this array holds pointers to virtual-array + control blocks for each component. Unused if not full-image storage. } + + whole_image : array[0..MAX_COMPONENTS-1] of jvirt_sarray_ptr; + {$endif} + end; {my_main_controller} + + +{ Forward declarations } +{METHODDEF} +procedure process_data_simple_main(cinfo : j_compress_ptr; + input_buf : JSAMPARRAY; + var in_row_ctr: JDIMENSION; + in_rows_avail : JDIMENSION); forward; + +{$ifdef FULL_MAIN_BUFFER_SUPPORTED} +{METHODDEF} +procedure process_data_buffer_main(cinfo : j_compress_ptr; + input_buf : JSAMPARRAY; + var in_row_ctr : JDIMENSION; + in_rows_avail : JDIMENSION); forward; +{$endif} + + +{ Initialize for a processing pass. } + +{METHODDEF} +procedure start_pass_main (cinfo : j_compress_ptr; + pass_mode : J_BUF_MODE); +var + main : my_main_ptr; +begin + main := my_main_ptr (cinfo^.main); + + { Do nothing in raw-data mode. } + if (cinfo^.raw_data_in) then + exit; + + main^.cur_iMCU_row := 0; { initialize counters } + main^.rowgroup_ctr := 0; + main^.suspended := FALSE; + main^.pass_mode := pass_mode; { save mode for use by process_data } + + case (pass_mode) of + JBUF_PASS_THRU: + begin +{$ifdef FULL_MAIN_BUFFER_SUPPORTED} + if (main^.whole_image[0] <> NIL) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE); +{$endif} + main^.pub.process_data := process_data_simple_main; + end; +{$ifdef FULL_MAIN_BUFFER_SUPPORTED} + JBUF_SAVE_SOURCE, + JBUF_CRANK_DEST, + JBUF_SAVE_AND_PASS: + begin + if (main^.whole_image[0] = NIL) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE); + main^.pub.process_data := process_data_buffer_main; + end; +{$endif} + else + ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE); + end; +end; + + +{ Process some data. + This routine handles the simple pass-through mode, + where we have only a strip buffer. } + +{METHODDEF} +procedure process_data_simple_main (cinfo : j_compress_ptr; + input_buf : JSAMPARRAY; + var in_row_ctr : JDIMENSION; + in_rows_avail : JDIMENSION); +var + main : my_main_ptr; +begin + main := my_main_ptr (cinfo^.main); + + while (main^.cur_iMCU_row < cinfo^.total_iMCU_rows) do + begin + { Read input data if we haven't filled the main buffer yet } + if (main^.rowgroup_ctr < DCTSIZE) then + cinfo^.prep^.pre_process_data (cinfo, + input_buf, + in_row_ctr, + in_rows_avail, + JSAMPIMAGE(@main^.buffer), + main^.rowgroup_ctr, + JDIMENSION(DCTSIZE)); + + { If we don't have a full iMCU row buffered, return to application for + more data. Note that preprocessor will always pad to fill the iMCU row + at the bottom of the image. } + if (main^.rowgroup_ctr <> DCTSIZE) then + exit; + + { Send the completed row to the compressor } + if (not cinfo^.coef^.compress_data (cinfo, JSAMPIMAGE(@main^.buffer))) then + begin + { If compressor did not consume the whole row, then we must need to + suspend processing and return to the application. In this situation + we pretend we didn't yet consume the last input row; otherwise, if + it happened to be the last row of the image, the application would + think we were done. } + + if (not main^.suspended) then + begin + Dec(in_row_ctr); + main^.suspended := TRUE; + end; + exit; + end; + { We did finish the row. Undo our little suspension hack if a previous + call suspended; then mark the main buffer empty. } + + if (main^.suspended) then + begin + Inc(in_row_ctr); + main^.suspended := FALSE; + end; + main^.rowgroup_ctr := 0; + Inc(main^.cur_iMCU_row); + end; +end; + + +{$ifdef FULL_MAIN_BUFFER_SUPPORTED} + +{ Process some data. + This routine handles all of the modes that use a full-size buffer. } + +{METHODDEF} +procedure process_data_buffer_main (cinfo : j_compress_ptr; + input_buf : JSAMPARRAY; + var in_row_ctr : JDIMENSION; + in_rows_avail : JDIMENSION); +var + main : my_main_ptr; + ci : int; + compptr : jpeg_component_info_ptr; + writing : boolean; +begin + main := my_main_ptr (cinfo^.main); + writing := (main^.pass_mode <> JBUF_CRANK_DEST); + + while (main^.cur_iMCU_row < cinfo^.total_iMCU_rows) do + begin + { Realign the virtual buffers if at the start of an iMCU row. } + if (main^.rowgroup_ctr = 0) then + begin + compptr := cinfo^.comp_info; + for ci := 0 to pred(cinfo^.num_components) do + begin + main^.buffer[ci] := cinfo^.mem^.access_virt_sarray + (j_common_ptr (cinfo), main^.whole_image[ci], + main^.cur_iMCU_row * (compptr^.v_samp_factor * DCTSIZE), + JDIMENSION (compptr^.v_samp_factor * DCTSIZE), writing); + Inc(compptr); + end; + { In a read pass, pretend we just read some source data. } + if (not writing) then + begin + Inc(in_row_ctr, cinfo^.max_v_samp_factor * DCTSIZE); + main^.rowgroup_ctr := DCTSIZE; + end; + end; + + { If a write pass, read input data until the current iMCU row is full. } + { Note: preprocessor will pad if necessary to fill the last iMCU row. } + if (writing) then + begin + cinfo^.prep^.pre_process_data (cinfo, + input_buf, in_row_ctr, in_rows_avail, + JSAMPIMAGE(@main^.buffer), + main^.rowgroup_ctr, + JDIMENSION (DCTSIZE)); + + { Return to application if we need more data to fill the iMCU row. } + if (main^.rowgroup_ctr < DCTSIZE) then + exit; + end; + + { Emit data, unless this is a sink-only pass. } + if (main^.pass_mode <> JBUF_SAVE_SOURCE) then + begin + if (not cinfo^.coef^.compress_data (cinfo, + JSAMPIMAGE(@main^.buffer))) then + begin + { If compressor did not consume the whole row, then we must need to + suspend processing and return to the application. In this situation + we pretend we didn't yet consume the last input row; otherwise, if + it happened to be the last row of the image, the application would + think we were done. } + + if (not main^.suspended) then + begin + Dec(in_row_ctr); + main^.suspended := TRUE; + end; + exit; + end; + { We did finish the row. Undo our little suspension hack if a previous + call suspended; then mark the main buffer empty. } + + if (main^.suspended) then + begin + Inc(in_row_ctr); + main^.suspended := FALSE; + end; + end; + + { If get here, we are done with this iMCU row. Mark buffer empty. } + main^.rowgroup_ctr := 0; + Inc(main^.cur_iMCU_row); + end; +end; + +{$endif} { FULL_MAIN_BUFFER_SUPPORTED } + + +{ Initialize main buffer controller. } + +{GLOBAL} +procedure jinit_c_main_controller (cinfo : j_compress_ptr; + need_full_buffer : boolean); +var + main : my_main_ptr; + ci : int; + compptr : jpeg_component_info_ptr; +begin + main := my_main_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(my_main_controller)) ); + cinfo^.main := jpeg_c_main_controller_ptr(main); + main^.pub.start_pass := start_pass_main; + + { We don't need to create a buffer in raw-data mode. } + if (cinfo^.raw_data_in) then + exit; + + { Create the buffer. It holds downsampled data, so each component + may be of a different size. } + + if (need_full_buffer) then + begin +{$ifdef FULL_MAIN_BUFFER_SUPPORTED} + { Allocate a full-image virtual array for each component } + { Note we pad the bottom to a multiple of the iMCU height } + compptr := cinfo^.comp_info; + for ci := 0 to pred(cinfo^.num_components) do + begin + main^.whole_image[ci] := cinfo^.mem^.request_virt_sarray + (j_common_ptr(cinfo), JPOOL_IMAGE, FALSE, + compptr^.width_in_blocks * DCTSIZE, + JDIMENSION (jround_up( long (compptr^.height_in_blocks), + long (compptr^.v_samp_factor)) * DCTSIZE), + JDIMENSION (compptr^.v_samp_factor * DCTSIZE)); + Inc(compptr); + end; +{$else} + ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE); +{$endif} + end + else + begin +{$ifdef FULL_MAIN_BUFFER_SUPPORTED} + main^.whole_image[0] := NIL; { flag for no virtual arrays } +{$endif} + { Allocate a strip buffer for each component } + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + main^.buffer[ci] := cinfo^.mem^.alloc_sarray + (j_common_ptr(cinfo), JPOOL_IMAGE, + compptr^.width_in_blocks * DCTSIZE, + JDIMENSION (compptr^.v_samp_factor * DCTSIZE)); + Inc(compptr); + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jcmarker_del.pas b/mseide-msegui/lib/common/fpccompatibility/jcmarker_del.pas new file mode 100644 index 0000000..ae80025 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jcmarker_del.pas @@ -0,0 +1,726 @@ +Unit jcmarker_del; + +{ This file contains routines to write JPEG datastream markers. } + +{ Original: jcmarker.c; Copyright (C) 1991-1998, Thomas G. Lane. } + +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jinclude_del, jmorecfg_del, jerror_del, + jdeferr_del, jpeglib_del, jutils_del; + + +const + { JPEG marker codes } + M_SOF0 = $c0; + M_SOF1 = $c1; + M_SOF2 = $c2; + M_SOF3 = $c3; + + M_SOF5 = $c5; + M_SOF6 = $c6; + M_SOF7 = $c7; + + M_JPG = $c8; + M_SOF9 = $c9; + M_SOF10 = $ca; + M_SOF11 = $cb; + + M_SOF13 = $cd; + M_SOF14 = $ce; + M_SOF15 = $cf; + + M_DHT = $c4; + + M_DAC = $cc; + + M_RST0 = $d0; + M_RST1 = $d1; + M_RST2 = $d2; + M_RST3 = $d3; + M_RST4 = $d4; + M_RST5 = $d5; + M_RST6 = $d6; + M_RST7 = $d7; + + M_SOI = $d8; + M_EOI = $d9; + M_SOS = $da; + M_DQT = $db; + M_DNL = $dc; + M_DRI = $dd; + M_DHP = $de; + M_EXP = $df; + + M_APP0 = $e0; + M_APP1 = $e1; + M_APP2 = $e2; + M_APP3 = $e3; + M_APP4 = $e4; + M_APP5 = $e5; + M_APP6 = $e6; + M_APP7 = $e7; + M_APP8 = $e8; + M_APP9 = $e9; + M_APP10 = $ea; + M_APP11 = $eb; + M_APP12 = $ec; + M_APP13 = $ed; + M_APP14 = $ee; + M_APP15 = $ef; + + M_JPG0 = $f0; + M_JPG13 = $fd; + M_COM = $fe; + + M_TEM = $01; + + M_ERROR = $100; + +type + JPEG_MARKER = Word; + +{ Private state } + +type + my_marker_ptr = ^my_marker_writer; + my_marker_writer = record + pub : jpeg_marker_writer; { public fields } + + last_restart_interval : uint; { last DRI value emitted; 0 after SOI } + end; + + + + +{GLOBAL} +procedure jinit_marker_writer (cinfo : j_compress_ptr); + +implementation + +{ Basic output routines. + + Note that we do not support suspension while writing a marker. + Therefore, an application using suspension must ensure that there is + enough buffer space for the initial markers (typ. 600-700 bytes) before + calling jpeg_start_compress, and enough space to write the trailing EOI + (a few bytes) before calling jpeg_finish_compress. Multipass compression + modes are not supported at all with suspension, so those two are the only + points where markers will be written. } + + +{LOCAL} +procedure emit_byte (cinfo : j_compress_ptr; val : int); +{ Emit a byte } +var + dest : jpeg_destination_mgr_ptr; +begin + dest := cinfo^.dest; + + dest^.next_output_byte^ := JOCTET(val); + Inc(dest^.next_output_byte); + + Dec(dest^.free_in_buffer); + if (dest^.free_in_buffer = 0) then + begin + if not dest^.empty_output_buffer(cinfo) then + ERREXIT(j_common_ptr(cinfo), JERR_CANT_SUSPEND); + end; +end; + + +{LOCAL} +procedure emit_marker(cinfo : j_compress_ptr; mark : JPEG_MARKER); +{ Emit a marker code } +begin + emit_byte(cinfo, $FF); + emit_byte(cinfo, int(mark)); +end; + + +{LOCAL} +procedure emit_2bytes (cinfo : j_compress_ptr; value : int); +{ Emit a 2-byte integer; these are always MSB first in JPEG files } +begin + emit_byte(cinfo, (value shr 8) and $FF); + emit_byte(cinfo, value and $FF); +end; + + +{ Routines to write specific marker types. } + +{LOCAL} +function emit_dqt (cinfo : j_compress_ptr; index : int) : int; +{ Emit a DQT marker } +{ Returns the precision used (0 = 8bits, 1 = 16bits) for baseline checking } +var + qtbl : JQUANT_TBL_PTR; + prec : int; + i : int; +var + qval : uint; +begin + qtbl := cinfo^.quant_tbl_ptrs[index]; + if (qtbl = NIL) then + ERREXIT1(j_common_ptr(cinfo), JERR_NO_QUANT_TABLE, index); + + prec := 0; + for i := 0 to Pred(DCTSIZE2) do + begin + if (qtbl^.quantval[i] > 255) then + prec := 1; + end; + + if not qtbl^.sent_table then + begin + emit_marker(cinfo, M_DQT); + + if (prec <> 0) then + emit_2bytes(cinfo, DCTSIZE2*2 + 1 + 2) + else + emit_2bytes(cinfo, DCTSIZE2 + 1 + 2); + + emit_byte(cinfo, index + (prec shl 4)); + + for i := 0 to Pred(DCTSIZE2) do + begin + { The table entries must be emitted in zigzag order. } + qval := qtbl^.quantval[jpeg_natural_order[i]]; + if (prec <> 0) then + emit_byte(cinfo, int(qval shr 8)); + emit_byte(cinfo, int(qval and $FF)); + end; + + qtbl^.sent_table := TRUE; + end; + + emit_dqt := prec; +end; + + +{LOCAL} +procedure emit_dht (cinfo : j_compress_ptr; index : int; is_ac : boolean); +{ Emit a DHT marker } +var + htbl : JHUFF_TBL_PTR; + length, i : int; +begin + if (is_ac) then + begin + htbl := cinfo^.ac_huff_tbl_ptrs[index]; + index := index + $10; { output index has AC bit set } + end + else + begin + htbl := cinfo^.dc_huff_tbl_ptrs[index]; + end; + + if (htbl = NIL) then + ERREXIT1(j_common_ptr(cinfo), JERR_NO_HUFF_TABLE, index); + + if not htbl^.sent_table then + begin + emit_marker(cinfo, M_DHT); + + length := 0; + for i := 1 to 16 do + length := length + htbl^.bits[i]; + + emit_2bytes(cinfo, length + 2 + 1 + 16); + emit_byte(cinfo, index); + + for i := 1 to 16 do + emit_byte(cinfo, htbl^.bits[i]); + + for i := 0 to Pred(length) do + emit_byte(cinfo, htbl^.huffval[i]); + + htbl^.sent_table := TRUE; + end; +end; + + +{LOCAL} +procedure emit_dac (cinfo : j_compress_ptr); +{ Emit a DAC marker } +{ Since the useful info is so small, we want to emit all the tables in } +{ one DAC marker. Therefore this routine does its own scan of the table. } +{$ifdef C_ARITH_CODING_SUPPORTED} +var + dc_in_use : array[0..NUM_ARITH_TBLS] of byte; + ac_in_use : array[0..NUM_ARITH_TBLS] of byte; + length, i : int; + compptr : jpeg_component_info_ptr; +begin + for i := 0 to pred(NUM_ARITH_TBLS) do + begin + dc_in_use[i] := 0; + ac_in_use[i] := 0; + end; + + for i := 0 to pred(cinfo^.comps_in_scan) do + begin + compptr := cinfo^.cur_comp_info[i]; + dc_in_use[compptr^.dc_tbl_no] := 1; + ac_in_use[compptr^.ac_tbl_no] := 1; + end; + + length := 0; + for i := 0 to pred(NUM_ARITH_TBLS) do + Inc(length, dc_in_use[i] + ac_in_use[i]); + + emit_marker(cinfo, M_DAC); + + emit_2bytes(cinfo, length*2 + 2); + + for i := 0 to pred(NUM_ARITH_TBLS) do + begin + if (dc_in_use[i] <> 0) then + begin + emit_byte(cinfo, i); + emit_byte(cinfo, cinfo^.arith_dc_L[i] + (cinfo^.arith_dc_U[i] shl 4)); + end; + if (ac_in_use[i] <> 0) then + begin + emit_byte(cinfo, i + $10); + emit_byte(cinfo, cinfo^.arith_ac_K[i]); + end; + end; +end; +{$else} +begin +end; +{$endif} {C_ARITH_CODING_SUPPORTED} + + +{LOCAL} +procedure emit_dri (cinfo : j_compress_ptr); +{ Emit a DRI marker } +begin + emit_marker(cinfo, M_DRI); + + emit_2bytes(cinfo, 4); { fixed length } + + emit_2bytes(cinfo, int(cinfo^.restart_interval)); +end; + + +{LOCAL} +procedure emit_sof (cinfo : j_compress_ptr; code : JPEG_MARKER); +{ Emit a SOF marker } +var + ci : int; + compptr : jpeg_component_info_ptr; +begin + emit_marker(cinfo, code); + + emit_2bytes(cinfo, 3 * cinfo^.num_components + 2 + 5 + 1); { length } + + { Make sure image isn't bigger than SOF field can handle } + if (long(cinfo^.image_height) > long(65535)) or + (long(cinfo^.image_width) > long(65535)) then + ERREXIT1(j_common_ptr(cinfo), JERR_IMAGE_TOO_BIG, uInt(65535)); + + emit_byte(cinfo, cinfo^.data_precision); + emit_2bytes(cinfo, int(cinfo^.image_height)); + emit_2bytes(cinfo, int(cinfo^.image_width)); + + emit_byte(cinfo, cinfo^.num_components); + + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to Pred(cinfo^.num_components) do + begin + emit_byte(cinfo, compptr^.component_id); + emit_byte(cinfo, (compptr^.h_samp_factor shl 4) + compptr^.v_samp_factor); + emit_byte(cinfo, compptr^.quant_tbl_no); + Inc(compptr); + end; +end; + + +{LOCAL} +procedure emit_sos (cinfo : j_compress_ptr); +{ Emit a SOS marker } +var + i, td, ta : int; + compptr : jpeg_component_info_ptr; +begin + emit_marker(cinfo, M_SOS); + + emit_2bytes(cinfo, 2 * cinfo^.comps_in_scan + 2 + 1 + 3); { length } + + emit_byte(cinfo, cinfo^.comps_in_scan); + + for i := 0 to Pred(cinfo^.comps_in_scan) do + begin + compptr := cinfo^.cur_comp_info[i]; + emit_byte(cinfo, compptr^.component_id); + td := compptr^.dc_tbl_no; + ta := compptr^.ac_tbl_no; + if (cinfo^.progressive_mode) then + begin + { Progressive mode: only DC or only AC tables are used in one scan; + furthermore, Huffman coding of DC refinement uses no table at all. + We emit 0 for unused field(s); this is recommended by the P&M text + but does not seem to be specified in the standard. } + + if (cinfo^.Ss = 0) then + begin + ta := 0; { DC scan } + if (cinfo^.Ah <> 0) and not cinfo^.arith_code then + td := 0; { no DC table either } + end + else + begin + td := 0; { AC scan } + end; + end; + emit_byte(cinfo, (td shl 4) + ta); + end; + + emit_byte(cinfo, cinfo^.Ss); + emit_byte(cinfo, cinfo^.Se); + emit_byte(cinfo, (cinfo^.Ah shl 4) + cinfo^.Al); +end; + + +{LOCAL} +procedure emit_jfif_app0 (cinfo : j_compress_ptr); +{ Emit a JFIF-compliant APP0 marker } +{ + Length of APP0 block (2 bytes) + Block ID (4 bytes - ASCII "JFIF") + Zero byte (1 byte to terminate the ID string) + Version Major, Minor (2 bytes - major first) + Units (1 byte - $00 = none, $01 = inch, $02 = cm) + Xdpu (2 bytes - dots per unit horizontal) + Ydpu (2 bytes - dots per unit vertical) + Thumbnail X size (1 byte) + Thumbnail Y size (1 byte) +} +begin + emit_marker(cinfo, M_APP0); + + emit_2bytes(cinfo, 2 + 4 + 1 + 2 + 1 + 2 + 2 + 1 + 1); { length } + + emit_byte(cinfo, $4A); { Identifier: ASCII "JFIF" } + emit_byte(cinfo, $46); + emit_byte(cinfo, $49); + emit_byte(cinfo, $46); + emit_byte(cinfo, 0); + emit_byte(cinfo, cinfo^.JFIF_major_version); { Version fields } + emit_byte(cinfo, cinfo^.JFIF_minor_version); + emit_byte(cinfo, cinfo^.density_unit); { Pixel size information } + emit_2bytes(cinfo, int(cinfo^.X_density)); + emit_2bytes(cinfo, int(cinfo^.Y_density)); + emit_byte(cinfo, 0); { No thumbnail image } + emit_byte(cinfo, 0); +end; + + +{LOCAL} +procedure emit_adobe_app14 (cinfo : j_compress_ptr); +{ Emit an Adobe APP14 marker } +{ + Length of APP14 block (2 bytes) + Block ID (5 bytes - ASCII "Adobe") + Version Number (2 bytes - currently 100) + Flags0 (2 bytes - currently 0) + Flags1 (2 bytes - currently 0) + Color transform (1 byte) + + Although Adobe TN 5116 mentions Version = 101, all the Adobe files + now in circulation seem to use Version = 100, so that's what we write. + + We write the color transform byte as 1 if the JPEG color space is + YCbCr, 2 if it's YCCK, 0 otherwise. Adobe's definition has to do with + whether the encoder performed a transformation, which is pretty useless. +} +begin + emit_marker(cinfo, M_APP14); + + emit_2bytes(cinfo, 2 + 5 + 2 + 2 + 2 + 1); { length } + + emit_byte(cinfo, $41); { Identifier: ASCII "Adobe" } + emit_byte(cinfo, $64); + emit_byte(cinfo, $6F); + emit_byte(cinfo, $62); + emit_byte(cinfo, $65); + emit_2bytes(cinfo, 100); { Version } + emit_2bytes(cinfo, 0); { Flags0 } + emit_2bytes(cinfo, 0); { Flags1 } + case (cinfo^.jpeg_color_space) of + JCS_YCbCr: + emit_byte(cinfo, 1); { Color transform = 1 } + JCS_YCCK: + emit_byte(cinfo, 2); { Color transform = 2 } + else + emit_byte(cinfo, 0); { Color transform = 0 } + end; +end; + + +{ These routines allow writing an arbitrary marker with parameters. + The only intended use is to emit COM or APPn markers after calling + write_file_header and before calling write_frame_header. + Other uses are not guaranteed to produce desirable results. + Counting the parameter bytes properly is the caller's responsibility. } + +{METHODDEF} +procedure write_marker_header (cinfo : j_compress_ptr; + marker : int; + datalen : uint); +{ Emit an arbitrary marker header } +begin + if (datalen > uint(65533)) then { safety check } + ERREXIT(j_common_ptr(cinfo), JERR_BAD_LENGTH); + + emit_marker(cinfo, JPEG_MARKER(marker)); + + emit_2bytes(cinfo, int(datalen + 2)); { total length } +end; + +{METHODDEF} +procedure write_marker_byte (cinfo : j_compress_ptr; val : int); +{ Emit one byte of marker parameters following write_marker_header } +begin + emit_byte(cinfo, val); +end; + +{ Write datastream header. + This consists of an SOI and optional APPn markers. + We recommend use of the JFIF marker, but not the Adobe marker, + when using YCbCr or grayscale data. The JFIF marker should NOT + be used for any other JPEG colorspace. The Adobe marker is helpful + to distinguish RGB, CMYK, and YCCK colorspaces. + Note that an application can write additional header markers after + jpeg_start_compress returns. } + + +{METHODDEF} +procedure write_file_header (cinfo : j_compress_ptr); +var + marker : my_marker_ptr; +begin + marker := my_marker_ptr(cinfo^.marker); + + emit_marker(cinfo, M_SOI); { first the SOI } + + { SOI is defined to reset restart interval to 0 } + marker^.last_restart_interval := 0; + + if (cinfo^.write_JFIF_header) then { next an optional JFIF APP0 } + emit_jfif_app0(cinfo); + if (cinfo^.write_Adobe_marker) then { next an optional Adobe APP14 } + emit_adobe_app14(cinfo); +end; + + +{ Write frame header. + This consists of DQT and SOFn markers. + Note that we do not emit the SOF until we have emitted the DQT(s). + This avoids compatibility problems with incorrect implementations that + try to error-check the quant table numbers as soon as they see the SOF. } + + +{METHODDEF} +procedure write_frame_header (cinfo : j_compress_ptr); +var + ci, prec : int; + is_baseline : boolean; + compptr : jpeg_component_info_ptr; +begin + { Emit DQT for each quantization table. + Note that emit_dqt() suppresses any duplicate tables. } + + prec := 0; + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to Pred(cinfo^.num_components) do + begin + prec := prec + emit_dqt(cinfo, compptr^.quant_tbl_no); + Inc(compptr); + end; + { now prec is nonzero iff there are any 16-bit quant tables. } + + { Check for a non-baseline specification. + Note we assume that Huffman table numbers won't be changed later. } + + if (cinfo^.arith_code) or (cinfo^.progressive_mode) + or (cinfo^.data_precision <> 8) then + begin + is_baseline := FALSE; + end + else + begin + is_baseline := TRUE; + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to Pred(cinfo^.num_components) do + begin + if (compptr^.dc_tbl_no > 1) or (compptr^.ac_tbl_no > 1) then + is_baseline := FALSE; + Inc(compptr); + end; + if (prec <> 0) and (is_baseline) then + begin + is_baseline := FALSE; + { If it's baseline except for quantizer size, warn the user } + {$IFDEF DEBUG} + TRACEMS(j_common_ptr(cinfo), 0, JTRC_16BIT_TABLES); + {$ENDIF} + end; + end; + + { Emit the proper SOF marker } + if (cinfo^.arith_code) then + begin + emit_sof(cinfo, M_SOF9); { SOF code for arithmetic coding } + end + else + begin + if (cinfo^.progressive_mode) then + emit_sof(cinfo, M_SOF2) { SOF code for progressive Huffman } + else if (is_baseline) then + emit_sof(cinfo, M_SOF0) { SOF code for baseline implementation } + else + emit_sof(cinfo, M_SOF1); { SOF code for non-baseline Huffman file } + end; +end; + + +{ Write scan header. + This consists of DHT or DAC markers, optional DRI, and SOS. + Compressed data will be written following the SOS. } + +{METHODDEF} +procedure write_scan_header (cinfo : j_compress_ptr); +var + marker : my_marker_ptr; + i : int; + compptr : jpeg_component_info_ptr; +begin + marker := my_marker_ptr(cinfo^.marker); + if (cinfo^.arith_code) then + begin + { Emit arith conditioning info. We may have some duplication + if the file has multiple scans, but it's so small it's hardly + worth worrying about. } + emit_dac(cinfo); + end + else + begin + { Emit Huffman tables. + Note that emit_dht() suppresses any duplicate tables. } + for i := 0 to Pred(cinfo^.comps_in_scan) do + begin + compptr := cinfo^.cur_comp_info[i]; + if (cinfo^.progressive_mode) then + begin + { Progressive mode: only DC or only AC tables are used in one scan } + if (cinfo^.Ss = 0) then + begin + if (cinfo^.Ah = 0) then { DC needs no table for refinement scan } + emit_dht(cinfo, compptr^.dc_tbl_no, FALSE); + end + else + begin + emit_dht(cinfo, compptr^.ac_tbl_no, TRUE); + end; + end + else + begin + { Sequential mode: need both DC and AC tables } + emit_dht(cinfo, compptr^.dc_tbl_no, FALSE); + emit_dht(cinfo, compptr^.ac_tbl_no, TRUE); + end; + end; + end; + + { Emit DRI if required --- note that DRI value could change for each scan. + We avoid wasting space with unnecessary DRIs, however. } + + if (cinfo^.restart_interval <> marker^.last_restart_interval) then + begin + emit_dri(cinfo); + marker^.last_restart_interval := cinfo^.restart_interval; + end; + + emit_sos(cinfo); +end; + + + +{ Write datastream trailer. } + + +{METHODDEF} +procedure write_file_trailer (cinfo : j_compress_ptr); +begin + emit_marker(cinfo, M_EOI); +end; + + +{ Write an abbreviated table-specification datastream. + This consists of SOI, DQT and DHT tables, and EOI. + Any table that is defined and not marked sent_table = TRUE will be + emitted. Note that all tables will be marked sent_table = TRUE at exit. } + + +{METHODDEF} +procedure write_tables_only (cinfo : j_compress_ptr); +var + i : int; +begin + emit_marker(cinfo, M_SOI); + + for i := 0 to Pred(NUM_QUANT_TBLS) do + begin + if (cinfo^.quant_tbl_ptrs[i] <> NIL) then + emit_dqt(cinfo, i); { dummy := ... } + end; + + if (not cinfo^.arith_code) then + begin + for i := 0 to Pred(NUM_HUFF_TBLS) do + begin + if (cinfo^.dc_huff_tbl_ptrs[i] <> NIL) then + emit_dht(cinfo, i, FALSE); + if (cinfo^.ac_huff_tbl_ptrs[i] <> NIL) then + emit_dht(cinfo, i, TRUE); + end; + end; + + emit_marker(cinfo, M_EOI); +end; + + +{ Initialize the marker writer module. } + +{GLOBAL} +procedure jinit_marker_writer (cinfo : j_compress_ptr); +var + marker : my_marker_ptr; +begin + { Create the subobject } + marker := my_marker_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(my_marker_writer)) ); + cinfo^.marker := jpeg_marker_writer_ptr(marker); + { Initialize method pointers } + marker^.pub.write_file_header := write_file_header; + marker^.pub.write_frame_header := write_frame_header; + marker^.pub.write_scan_header := write_scan_header; + marker^.pub.write_file_trailer := write_file_trailer; + marker^.pub.write_tables_only := write_tables_only; + marker^.pub.write_marker_header := write_marker_header; + marker^.pub.write_marker_byte := write_marker_byte; + { Initialize private state } + marker^.last_restart_interval := 0; +end; + + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jcmaster_del.pas b/mseide-msegui/lib/common/fpccompatibility/jcmaster_del.pas new file mode 100644 index 0000000..8ec37fe --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jcmaster_del.pas @@ -0,0 +1,704 @@ +Unit jcmaster_del; + +{ This file contains master control logic for the JPEG compressor. + These routines are concerned with parameter validation, initial setup, + and inter-pass control (determining the number of passes and the work + to be done in each pass). } + +{ Original: jcmaster.c ; Copyright (C) 1991-1997, Thomas G. Lane. } + +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jdeferr_del, + jerror_del, + jutils_del, + jpeglib_del; + + +{ Initialize master compression control. } + +{GLOBAL} +procedure jinit_c_master_control (cinfo : j_compress_ptr; + transcode_only : boolean); + +implementation + +{ Private state } + +type + c_pass_type = ( + main_pass, { input data, also do first output step } + huff_opt_pass, { Huffman code optimization pass } + output_pass { data output pass } + ); + +type + my_master_ptr = ^my_comp_master; + my_comp_master = record + pub : jpeg_comp_master; { public fields } + + pass_type : c_pass_type; { the type of the current pass } + + pass_number : int; { # of passes completed } + total_passes : int; { total # of passes needed } + + scan_number : int; { current index in scan_info[] } + end; + + +{ Support routines that do various essential calculations. } + +{LOCAL} +procedure initial_setup (cinfo : j_compress_ptr); +{ Do computations that are needed before master selection phase } +var + ci : int; + compptr : jpeg_component_info_ptr; + samplesperrow : long; + jd_samplesperrow : JDIMENSION; +begin + + { Sanity check on image dimensions } + if (cinfo^.image_height <= 0) or (cinfo^.image_width <= 0) or + (cinfo^.num_components <= 0) or (cinfo^.input_components <= 0) then + ERREXIT(j_common_ptr(cinfo), JERR_EMPTY_IMAGE); + + { Make sure image isn't bigger than I can handle } + if ( long(cinfo^.image_height) > long(JPEG_MAX_DIMENSION)) or + ( long(cinfo^.image_width) > long(JPEG_MAX_DIMENSION)) then + ERREXIT1(j_common_ptr(cinfo), JERR_IMAGE_TOO_BIG, + uInt(JPEG_MAX_DIMENSION)); + + { Width of an input scanline must be representable as JDIMENSION. } + samplesperrow := long (cinfo^.image_width) * long (cinfo^.input_components); + jd_samplesperrow := JDIMENSION (samplesperrow); + if ( long(jd_samplesperrow) <> samplesperrow) then + ERREXIT(j_common_ptr(cinfo), JERR_WIDTH_OVERFLOW); + + { For now, precision must match compiled-in value... } + if (cinfo^.data_precision <> BITS_IN_JSAMPLE) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_PRECISION, cinfo^.data_precision); + + { Check that number of components won't exceed internal array sizes } + if (cinfo^.num_components > MAX_COMPONENTS) then + ERREXIT2(j_common_ptr(cinfo), JERR_COMPONENT_COUNT, cinfo^.num_components, + MAX_COMPONENTS); + + { Compute maximum sampling factors; check factor validity } + cinfo^.max_h_samp_factor := 1; + cinfo^.max_v_samp_factor := 1; + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + if (compptr^.h_samp_factor<=0) or (compptr^.h_samp_factor>MAX_SAMP_FACTOR) + or (compptr^.v_samp_factor<=0) or (compptr^.v_samp_factor>MAX_SAMP_FACTOR) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_SAMPLING); + { MAX } + if cinfo^.max_h_samp_factor > compptr^.h_samp_factor then + cinfo^.max_h_samp_factor := cinfo^.max_h_samp_factor + else + cinfo^.max_h_samp_factor := compptr^.h_samp_factor; + { MAX } + if cinfo^.max_v_samp_factor > compptr^.v_samp_factor then + cinfo^.max_v_samp_factor := cinfo^.max_v_samp_factor + else + cinfo^.max_v_samp_factor := compptr^.v_samp_factor; + Inc(compptr); + end; + + { Compute dimensions of components } + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + { Fill in the correct component_index value; don't rely on application } + compptr^.component_index := ci; + { For compression, we never do DCT scaling. } + compptr^.DCT_scaled_size := DCTSIZE; + { Size in DCT blocks } + compptr^.width_in_blocks := JDIMENSION ( + jdiv_round_up(long (cinfo^.image_width) * long (compptr^.h_samp_factor), + long (cinfo^.max_h_samp_factor * DCTSIZE)) ); + compptr^.height_in_blocks := JDIMENSION ( + jdiv_round_up(long (cinfo^.image_height) * long (compptr^.v_samp_factor), + long (cinfo^.max_v_samp_factor * DCTSIZE)) ); + { Size in samples } + compptr^.downsampled_width := JDIMENSION ( + jdiv_round_up(long(cinfo^.image_width) * long(compptr^.h_samp_factor), + long(cinfo^.max_h_samp_factor)) ); + compptr^.downsampled_height := JDIMENSION ( + jdiv_round_up(long (cinfo^.image_height) * long(compptr^.v_samp_factor), + long (cinfo^.max_v_samp_factor)) ); + { Mark component needed (this flag isn't actually used for compression) } + compptr^.component_needed := TRUE; + Inc(compptr); + end; + + { Compute number of fully interleaved MCU rows (number of times that + main controller will call coefficient controller). } + + cinfo^.total_iMCU_rows := JDIMENSION ( + jdiv_round_up(long (cinfo^.image_height), + long (cinfo^.max_v_samp_factor*DCTSIZE)) ); +end; + + +{$ifdef C_MULTISCAN_FILES_SUPPORTED} + +{LOCAL} +procedure validate_script (cinfo : j_compress_ptr); +{ Verify that the scan script in cinfo^.scan_info[] is valid; also + determine whether it uses progressive JPEG, and set cinfo^.progressive_mode. } +type + IntRow = array[0..DCTSIZE2-1] of int; + introw_ptr = ^IntRow; +var + {const}scanptr : jpeg_scan_info_ptr; + scanno, ncomps, ci, coefi, thisi : int; + Ss, Se, Ah, Al : int; + component_sent : array[0..MAX_COMPONENTS-1] of boolean; +{$ifdef C_PROGRESSIVE_SUPPORTED} + last_bitpos_int_ptr : int_ptr; + last_bitpos_ptr : introw_ptr; + last_bitpos : array[0..MAX_COMPONENTS-1] of IntRow; + { -1 until that coefficient has been seen; then last Al for it } + { The JPEG spec simply gives the ranges 0..13 for Ah and Al, but that + seems wrong: the upper bound ought to depend on data precision. + Perhaps they really meant 0..N+1 for N-bit precision. + Here we allow 0..10 for 8-bit data; Al larger than 10 results in + out-of-range reconstructed DC values during the first DC scan, + which might cause problems for some decoders. } +{$ifdef BITS_IN_JSAMPLE_IS_8} +const + MAX_AH_AL = 10; +{$else} +const + MAX_AH_AL = 13; +{$endif} +{$endif} +begin + + if (cinfo^.num_scans <= 0) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_SCAN_SCRIPT, 0); + + { For sequential JPEG, all scans must have Ss=0, Se=DCTSIZE2-1; + for progressive JPEG, no scan can have this. } + + scanptr := cinfo^.scan_info; + if (scanptr^.Ss <> 0) or (scanptr^.Se <> DCTSIZE2-1) then + begin +{$ifdef C_PROGRESSIVE_SUPPORTED} + cinfo^.progressive_mode := TRUE; + last_bitpos_int_ptr := @(last_bitpos[0][0]); + for ci := 0 to pred(cinfo^.num_components) do + for coefi := 0 to pred(DCTSIZE2) do + begin + last_bitpos_int_ptr^ := -1; + Inc(last_bitpos_int_ptr); + end; +{$else} + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); +{$endif} + end + else + begin + cinfo^.progressive_mode := FALSE; + for ci := 0 to pred(cinfo^.num_components) do + component_sent[ci] := FALSE; + end; + + for scanno := 1 to cinfo^.num_scans do + begin + { Validate component indexes } + ncomps := scanptr^.comps_in_scan; + if (ncomps <= 0) or (ncomps > MAX_COMPS_IN_SCAN) then + ERREXIT2(j_common_ptr(cinfo), JERR_COMPONENT_COUNT, ncomps, MAX_COMPS_IN_SCAN); + for ci := 0 to pred(ncomps) do + begin + thisi := scanptr^.component_index[ci]; + if (thisi < 0) or (thisi >= cinfo^.num_components) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_SCAN_SCRIPT, scanno); + { Components must appear in SOF order within each scan } + if (ci > 0) and (thisi <= scanptr^.component_index[ci-1]) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_SCAN_SCRIPT, scanno); + end; + { Validate progression parameters } + Ss := scanptr^.Ss; + Se := scanptr^.Se; + Ah := scanptr^.Ah; + Al := scanptr^.Al; + if (cinfo^.progressive_mode) then + begin +{$ifdef C_PROGRESSIVE_SUPPORTED} + if (Ss < 0) or (Ss >= DCTSIZE2) or (Se < Ss) or (Se >= DCTSIZE2) or + (Ah < 0) or (Ah > MAX_AH_AL) or (Al < 0) or (Al > MAX_AH_AL) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_PROG_SCRIPT, scanno); + + if (Ss < 0) or (Ss >= DCTSIZE2) or (Se < Ss) or (Se >= DCTSIZE2) + or (Ah < 0) or (Ah > MAX_AH_AL) or (Al < 0) or (Al > MAX_AH_AL) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_PROG_SCRIPT, scanno); + if (Ss = 0) then + begin + if (Se <> 0) then { DC and AC together not OK } + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_PROG_SCRIPT, scanno); + end + else + begin + if (ncomps <> 1) then { AC scans must be for only one component } + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_PROG_SCRIPT, scanno); + end; + for ci := 0 to pred(ncomps) do + begin + last_bitpos_ptr := @( last_bitpos[scanptr^.component_index[ci]]); + if (Ss <> 0) and (last_bitpos_ptr^[0] < 0) then { AC without prior DC scan } + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_PROG_SCRIPT, scanno); + for coefi := Ss to Se do + begin + if (last_bitpos_ptr^[coefi] < 0) then + begin + { first scan of this coefficient } + if (Ah <> 0) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_PROG_SCRIPT, scanno); + end + else + begin + { not first scan } + if (Ah <> last_bitpos_ptr^[coefi]) or (Al <> Ah-1) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_PROG_SCRIPT, scanno); + end; + last_bitpos_ptr^[coefi] := Al; + end; + end; +{$endif} + end + else + begin + { For sequential JPEG, all progression parameters must be these: } + if (Ss <> 0) or (Se <> DCTSIZE2-1) or (Ah <> 0) or (Al <> 0) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_PROG_SCRIPT, scanno); + { Make sure components are not sent twice } + for ci := 0 to pred(ncomps) do + begin + thisi := scanptr^.component_index[ci]; + if (component_sent[thisi]) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_SCAN_SCRIPT, scanno); + component_sent[thisi] := TRUE; + end; + end; + Inc(scanptr); + end; + + { Now verify that everything got sent. } + if (cinfo^.progressive_mode) then + begin +{$ifdef C_PROGRESSIVE_SUPPORTED + { For progressive mode, we only check that at least some DC data + got sent for each component; the spec does not require that all bits + of all coefficients be transmitted. Would it be wiser to enforce + transmission of all coefficient bits?? } + + for ci := 0 to pred(cinfo^.num_components) do + begin + if (last_bitpos[ci][0] < 0) then + ERREXIT(j_common_ptr(cinfo), JERR_MISSING_DATA); + end; +{$endif} + end + else + begin + for ci := 0 to pred(cinfo^.num_components) do + begin + if (not component_sent[ci]) then + ERREXIT(j_common_ptr(cinfo), JERR_MISSING_DATA); + end; + end; +end; + +{$endif} { C_MULTISCAN_FILES_SUPPORTED } + + +{LOCAL} +procedure select_scan_parameters (cinfo : j_compress_ptr); +{ Set up the scan parameters for the current scan } +var + master : my_master_ptr; + {const} scanptr : jpeg_scan_info_ptr; + ci : int; +var + comp_infos : jpeg_component_info_list_ptr; +begin +{$ifdef C_MULTISCAN_FILES_SUPPORTED} + if (cinfo^.scan_info <> NIL) then + begin + { Prepare for current scan --- the script is already validated } + master := my_master_ptr (cinfo^.master); + scanptr := cinfo^.scan_info; + Inc(scanptr, master^.scan_number); + + cinfo^.comps_in_scan := scanptr^.comps_in_scan; + comp_infos := cinfo^.comp_info; + for ci := 0 to pred(scanptr^.comps_in_scan) do + begin + cinfo^.cur_comp_info[ci] := + @(comp_infos^[scanptr^.component_index[ci]]); + end; + cinfo^.Ss := scanptr^.Ss; + cinfo^.Se := scanptr^.Se; + cinfo^.Ah := scanptr^.Ah; + cinfo^.Al := scanptr^.Al; + end + else +{$endif} + begin + { Prepare for single sequential-JPEG scan containing all components } + if (cinfo^.num_components > MAX_COMPS_IN_SCAN) then + ERREXIT2(j_common_ptr(cinfo), JERR_COMPONENT_COUNT, cinfo^.num_components, + MAX_COMPS_IN_SCAN); + cinfo^.comps_in_scan := cinfo^.num_components; + comp_infos := cinfo^.comp_info; + for ci := 0 to pred(cinfo^.num_components) do + begin + cinfo^.cur_comp_info[ci] := @(comp_infos^[ci]); + end; + cinfo^.Ss := 0; + cinfo^.Se := DCTSIZE2-1; + cinfo^.Ah := 0; + cinfo^.Al := 0; + end; +end; + + +{LOCAL} +procedure per_scan_setup (cinfo : j_compress_ptr); +{ Do computations that are needed before processing a JPEG scan } +{ cinfo^.comps_in_scan and cinfo^.cur_comp_info[] are already set } +var + ci, mcublks, tmp : int; + compptr : jpeg_component_info_ptr; + nominal : long; +begin + if (cinfo^.comps_in_scan = 1) then + begin + + { Noninterleaved (single-component) scan } + compptr := cinfo^.cur_comp_info[0]; + + { Overall image size in MCUs } + cinfo^.MCUs_per_row := compptr^.width_in_blocks; + cinfo^.MCU_rows_in_scan := compptr^.height_in_blocks; + + { For noninterleaved scan, always one block per MCU } + compptr^.MCU_width := 1; + compptr^.MCU_height := 1; + compptr^.MCU_blocks := 1; + compptr^.MCU_sample_width := DCTSIZE; + compptr^.last_col_width := 1; + { For noninterleaved scans, it is convenient to define last_row_height + as the number of block rows present in the last iMCU row. } + + tmp := int (compptr^.height_in_blocks mod compptr^.v_samp_factor); + if (tmp = 0) then + tmp := compptr^.v_samp_factor; + compptr^.last_row_height := tmp; + + { Prepare array describing MCU composition } + cinfo^.blocks_in_MCU := 1; + cinfo^.MCU_membership[0] := 0; + + end + else + begin + + { Interleaved (multi-component) scan } + if (cinfo^.comps_in_scan <= 0) or + (cinfo^.comps_in_scan > MAX_COMPS_IN_SCAN) then + ERREXIT2(j_common_ptr(cinfo), JERR_COMPONENT_COUNT, + cinfo^.comps_in_scan, MAX_COMPS_IN_SCAN); + + { Overall image size in MCUs } + cinfo^.MCUs_per_row := JDIMENSION ( + jdiv_round_up( long (cinfo^.image_width), + long (cinfo^.max_h_samp_factor*DCTSIZE)) ); + cinfo^.MCU_rows_in_scan := JDIMENSION ( + jdiv_round_up( long (cinfo^.image_height), + long (cinfo^.max_v_samp_factor*DCTSIZE)) ); + + cinfo^.blocks_in_MCU := 0; + + for ci := 0 to pred(cinfo^.comps_in_scan) do + begin + compptr := cinfo^.cur_comp_info[ci]; + { Sampling factors give # of blocks of component in each MCU } + compptr^.MCU_width := compptr^.h_samp_factor; + compptr^.MCU_height := compptr^.v_samp_factor; + compptr^.MCU_blocks := compptr^.MCU_width * compptr^.MCU_height; + compptr^.MCU_sample_width := compptr^.MCU_width * DCTSIZE; + { Figure number of non-dummy blocks in last MCU column & row } + tmp := int (compptr^.width_in_blocks mod compptr^.MCU_width); + if (tmp = 0) then + tmp := compptr^.MCU_width; + compptr^.last_col_width := tmp; + tmp := int (compptr^.height_in_blocks mod compptr^.MCU_height); + if (tmp = 0) then + tmp := compptr^.MCU_height; + compptr^.last_row_height := tmp; + { Prepare array describing MCU composition } + mcublks := compptr^.MCU_blocks; + if (cinfo^.blocks_in_MCU + mcublks > C_MAX_BLOCKS_IN_MCU) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_MCU_SIZE); + while (mcublks > 0) do + begin + Dec(mcublks); + cinfo^.MCU_membership[cinfo^.blocks_in_MCU] := ci; + Inc(cinfo^.blocks_in_MCU); + end; + end; + + end; + + { Convert restart specified in rows to actual MCU count. } + { Note that count must fit in 16 bits, so we provide limiting. } + if (cinfo^.restart_in_rows > 0) then + begin + nominal := long(cinfo^.restart_in_rows) * long(cinfo^.MCUs_per_row); + if nominal < long(65535) then + cinfo^.restart_interval := uInt (nominal) + else + cinfo^.restart_interval := long(65535); + end; +end; + + +{ Per-pass setup. + This is called at the beginning of each pass. We determine which modules + will be active during this pass and give them appropriate start_pass calls. + We also set is_last_pass to indicate whether any more passes will be + required. } + +{METHODDEF} +procedure prepare_for_pass (cinfo : j_compress_ptr); +var + master : my_master_ptr; +var + fallthrough : boolean; +begin + master := my_master_ptr (cinfo^.master); + fallthrough := true; + + case (master^.pass_type) of + main_pass: + begin + { Initial pass: will collect input data, and do either Huffman + optimization or data output for the first scan. } + select_scan_parameters(cinfo); + per_scan_setup(cinfo); + if (not cinfo^.raw_data_in) then + begin + cinfo^.cconvert^.start_pass (cinfo); + cinfo^.downsample^.start_pass (cinfo); + cinfo^.prep^.start_pass (cinfo, JBUF_PASS_THRU); + end; + cinfo^.fdct^.start_pass (cinfo); + cinfo^.entropy^.start_pass (cinfo, cinfo^.optimize_coding); + if master^.total_passes > 1 then + cinfo^.coef^.start_pass (cinfo, JBUF_SAVE_AND_PASS) + else + cinfo^.coef^.start_pass (cinfo, JBUF_PASS_THRU); + cinfo^.main^.start_pass (cinfo, JBUF_PASS_THRU); + if (cinfo^.optimize_coding) then + begin + { No immediate data output; postpone writing frame/scan headers } + master^.pub.call_pass_startup := FALSE; + end + else + begin + { Will write frame/scan headers at first jpeg_write_scanlines call } + master^.pub.call_pass_startup := TRUE; + end; + end; +{$ifdef ENTROPY_OPT_SUPPORTED} + huff_opt_pass, + output_pass: + begin + if (master^.pass_type = huff_opt_pass) then + begin + { Do Huffman optimization for a scan after the first one. } + select_scan_parameters(cinfo); + per_scan_setup(cinfo); + if (cinfo^.Ss <> 0) or (cinfo^.Ah = 0) or (cinfo^.arith_code) then + begin + cinfo^.entropy^.start_pass (cinfo, TRUE); + cinfo^.coef^.start_pass (cinfo, JBUF_CRANK_DEST); + master^.pub.call_pass_startup := FALSE; + fallthrough := false; + end; + { Special case: Huffman DC refinement scans need no Huffman table + and therefore we can skip the optimization pass for them. } + if fallthrough then + begin + master^.pass_type := output_pass; + Inc(master^.pass_number); + {FALLTHROUGH} + end; + end; +{$else} + output_pass: + begin +{$endif} + if fallthrough then + begin + { Do a data-output pass. } + { We need not repeat per-scan setup if prior optimization pass did it. } + if (not cinfo^.optimize_coding) then + begin + select_scan_parameters(cinfo); + per_scan_setup(cinfo); + end; + cinfo^.entropy^.start_pass (cinfo, FALSE); + cinfo^.coef^.start_pass (cinfo, JBUF_CRANK_DEST); + { We emit frame/scan headers now } + if (master^.scan_number = 0) then + cinfo^.marker^.write_frame_header (cinfo); + cinfo^.marker^.write_scan_header (cinfo); + master^.pub.call_pass_startup := FALSE; + end; + end; + else + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); + end; + + master^.pub.is_last_pass := (master^.pass_number = master^.total_passes-1); + + { Set up progress monitor's pass info if present } + if (cinfo^.progress <> NIL) then + begin + cinfo^.progress^.completed_passes := master^.pass_number; + cinfo^.progress^.total_passes := master^.total_passes; + end; +end; + + +{ Special start-of-pass hook. + This is called by jpeg_write_scanlines if call_pass_startup is TRUE. + In single-pass processing, we need this hook because we don't want to + write frame/scan headers during jpeg_start_compress; we want to let the + application write COM markers etc. between jpeg_start_compress and the + jpeg_write_scanlines loop. + In multi-pass processing, this routine is not used. } + +{METHODDEF} +procedure pass_startup (cinfo : j_compress_ptr); +begin + cinfo^.master^.call_pass_startup := FALSE; { reset flag so call only once } + + cinfo^.marker^.write_frame_header (cinfo); + cinfo^.marker^.write_scan_header (cinfo); +end; + + +{ Finish up at end of pass. } + +{METHODDEF} +procedure finish_pass_master (cinfo : j_compress_ptr); +var + master : my_master_ptr; +begin + master := my_master_ptr (cinfo^.master); + + { The entropy coder always needs an end-of-pass call, + either to analyze statistics or to flush its output buffer. } + cinfo^.entropy^.finish_pass (cinfo); + + { Update state for next pass } + case (master^.pass_type) of + main_pass: + begin + { next pass is either output of scan 0 (after optimization) + or output of scan 1 (if no optimization). } + + master^.pass_type := output_pass; + if (not cinfo^.optimize_coding) then + Inc(master^.scan_number); + end; + huff_opt_pass: + { next pass is always output of current scan } + master^.pass_type := output_pass; + output_pass: + begin + { next pass is either optimization or output of next scan } + if (cinfo^.optimize_coding) then + master^.pass_type := huff_opt_pass; + Inc(master^.scan_number); + end; + end; + + Inc(master^.pass_number); +end; + + +{ Initialize master compression control. } + +{GLOBAL} +procedure jinit_c_master_control (cinfo : j_compress_ptr; + transcode_only : boolean); +var + master : my_master_ptr; +begin + master := my_master_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(my_comp_master)) ); + cinfo^.master := jpeg_comp_master_ptr(master); + master^.pub.prepare_for_pass := prepare_for_pass; + master^.pub.pass_startup := pass_startup; + master^.pub.finish_pass := finish_pass_master; + master^.pub.is_last_pass := FALSE; + + { Validate parameters, determine derived values } + initial_setup(cinfo); + + if (cinfo^.scan_info <> NIL) then + begin +{$ifdef C_MULTISCAN_FILES_SUPPORTED} + validate_script(cinfo); +{$else} + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); +{$endif} + end + else + begin + cinfo^.progressive_mode := FALSE; + cinfo^.num_scans := 1; + end; + + if (cinfo^.progressive_mode) then { TEMPORARY HACK ??? } + cinfo^.optimize_coding := TRUE; { assume default tables no good for progressive mode } + + { Initialize my private state } + if (transcode_only) then + begin + { no main pass in transcoding } + if (cinfo^.optimize_coding) then + master^.pass_type := huff_opt_pass + else + master^.pass_type := output_pass; + end + else + begin + { for normal compression, first pass is always this type: } + master^.pass_type := main_pass; + end; + master^.scan_number := 0; + master^.pass_number := 0; + if (cinfo^.optimize_coding) then + master^.total_passes := cinfo^.num_scans * 2 + else + master^.total_passes := cinfo^.num_scans; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jcomapi_del.pas b/mseide-msegui/lib/common/fpccompatibility/jcomapi_del.pas new file mode 100644 index 0000000..ce4ce52 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jcomapi_del.pas @@ -0,0 +1,131 @@ +unit jcomapi_del; + +{ This file contains application interface routines that are used for both + compression and decompression. } + +{ Original: jcomapi.c; Copyright (C) 1994-1997, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jpeglib_del; + +{ Abort processing of a JPEG compression or decompression operation, + but don't destroy the object itself. } + +{GLOBAL} +procedure jpeg_abort (cinfo : j_common_ptr); + + +{ Destruction of a JPEG object. } + +{GLOBAL} +procedure jpeg_destroy (cinfo : j_common_ptr); + +{GLOBAL} +function jpeg_alloc_quant_table (cinfo : j_common_ptr) : JQUANT_TBL_PTR; + +{GLOBAL} +function jpeg_alloc_huff_table (cinfo : j_common_ptr) : JHUFF_TBL_PTR; + +implementation + +{ Abort processing of a JPEG compression or decompression operation, + but don't destroy the object itself. + + For this, we merely clean up all the nonpermanent memory pools. + Note that temp files (virtual arrays) are not allowed to belong to + the permanent pool, so we will be able to close all temp files here. + Closing a data source or destination, if necessary, is the application's + responsibility. } + + +{GLOBAL} +procedure jpeg_abort (cinfo : j_common_ptr); +var + pool : int; +begin + { Do nothing if called on a not-initialized or destroyed JPEG object. } + if (cinfo^.mem = NIL) then + exit; + + { Releasing pools in reverse order might help avoid fragmentation + with some (brain-damaged) malloc libraries. } + + for pool := JPOOL_NUMPOOLS-1 downto JPOOL_PERMANENT+1 do + begin + cinfo^.mem^.free_pool (cinfo, pool); + end; + + { Reset overall state for possible reuse of object } + if (cinfo^.is_decompressor) then + begin + cinfo^.global_state := DSTATE_START; + { Try to keep application from accessing now-deleted marker list. + A bit kludgy to do it here, but this is the most central place. } + j_decompress_ptr(cinfo)^.marker_list := NIL; + end + else + begin + cinfo^.global_state := CSTATE_START; + end; +end; + + +{ Destruction of a JPEG object. + + Everything gets deallocated except the master jpeg_compress_struct itself + and the error manager struct. Both of these are supplied by the application + and must be freed, if necessary, by the application. (Often they are on + the stack and so don't need to be freed anyway.) + Closing a data source or destination, if necessary, is the application's + responsibility. } + + +{GLOBAL} +procedure jpeg_destroy (cinfo : j_common_ptr); +begin + { We need only tell the memory manager to release everything. } + { NB: mem pointer is NIL if memory mgr failed to initialize. } + if (cinfo^.mem <> NIL) then + cinfo^.mem^.self_destruct (cinfo); + cinfo^.mem := NIL; { be safe if jpeg_destroy is called twice } + cinfo^.global_state := 0; { mark it destroyed } +end; + + +{ Convenience routines for allocating quantization and Huffman tables. + (Would jutils.c be a more reasonable place to put these?) } + + +{GLOBAL} +function jpeg_alloc_quant_table (cinfo : j_common_ptr) : JQUANT_TBL_PTR; +var + tbl : JQUANT_TBL_PTR; +begin + tbl := JQUANT_TBL_PTR( + cinfo^.mem^.alloc_small (cinfo, JPOOL_PERMANENT, SIZEOF(JQUANT_TBL)) + ); + tbl^.sent_table := FALSE; { make sure this is false in any new table } + jpeg_alloc_quant_table := tbl; +end; + + +{GLOBAL} +function jpeg_alloc_huff_table (cinfo : j_common_ptr) : JHUFF_TBL_PTR; +var + tbl : JHUFF_TBL_PTR; +begin + tbl := JHUFF_TBL_PTR( + cinfo^.mem^.alloc_small (cinfo, JPOOL_PERMANENT, SIZEOF(JHUFF_TBL)) + ); + tbl^.sent_table := FALSE; { make sure this is false in any new table } + jpeg_alloc_huff_table := tbl; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jconfig_del.inc b/mseide-msegui/lib/common/fpccompatibility/jconfig_del.inc new file mode 100644 index 0000000..3d10c93 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jconfig_del.inc @@ -0,0 +1,118 @@ +{ ----------------------- JPEG_INTERNAL_OPTIONS ---------------------- } + + +{ These defines indicate whether to include various optional functions. + Undefining some of these symbols will produce a smaller but less capable + library. Note that you can leave certain source files out of the + compilation/linking process if you've #undef'd the corresponding symbols. + (You may HAVE to do that if your compiler doesn't like null source files.)} + + +{ Arithmetic coding is unsupported for legal reasons. Complaints to IBM. } + +{ Capability options common to encoder and decoder: } + +{$define DCT_ISLOW_SUPPORTED} { slow but accurate integer algorithm } +{$define DCT_IFAST_SUPPORTED} { faster, less accurate integer method } +{$define DCT_FLOAT_SUPPORTED} { floating-point: accurate, fast on fast HW } + +{ Encoder capability options: } + +{$undef C_ARITH_CODING_SUPPORTED} { Arithmetic coding back end? } +{$define C_MULTISCAN_FILES_SUPPORTED} { Multiple-scan JPEG files? } +{$define C_PROGRESSIVE_SUPPORTED} { Progressive JPEG? (Requires MULTISCAN)} +{$define ENTROPY_OPT_SUPPORTED} { Optimization of entropy coding parms? } +{ Note: if you selected 12-bit data precision, it is dangerous to turn off + ENTROPY_OPT_SUPPORTED. The standard Huffman tables are only good for 8-bit + precision, so jchuff.c normally uses entropy optimization to compute + usable tables for higher precision. If you don't want to do optimization, + you'll have to supply different default Huffman tables. + The exact same statements apply for progressive JPEG: the default tables + don't work for progressive mode. (This may get fixed, however.) } + +{$define INPUT_SMOOTHING_SUPPORTED} { Input image smoothing option? } + +{ Decoder capability options: } + +{$undef D_ARITH_CODING_SUPPORTED} { Arithmetic coding back end? } +{$define D_MULTISCAN_FILES_SUPPORTED} { Multiple-scan JPEG files? } +{$define D_PROGRESSIVE_SUPPORTED} { Progressive JPEG? (Requires MULTISCAN)} +{$define SAVE_MARKERS_SUPPORTED} { jpeg_save_markers() needed? } +{$define BLOCK_SMOOTHING_SUPPORTED} { Block smoothing? (Progressive only) } +{$define IDCT_SCALING_SUPPORTED} { Output rescaling via IDCT? } +{$undef UPSAMPLE_SCALING_SUPPORTED} { Output rescaling at upsample stage? } +{$define UPSAMPLE_MERGING_SUPPORTED} { Fast path for sloppy upsampling? } +{$define QUANT_1PASS_SUPPORTED} { 1-pass color quantization? } +{$define QUANT_2PASS_SUPPORTED} { 2-pass color quantization? } + +{ If you happen not to want the image transform support, disable it here } +{$define TRANSFORMS_SUPPORTED} + +{ more capability options later, no doubt } + +{$ifopt I+} {$define IOcheck} {$endif} + +{ ------------------------------------------------------------------------ } + +{$define USE_FMEM} { Borland has _fmemcpy() and _fmemset() } + +{$define FMEMCOPY} +{$define FMEMZERO} + +{$define DCTSIZE_IS_8} { e.g. unroll the inner loop } +{$define RIGHT_SHIFT_IS_UNSIGNED} +{$undef AVOID_TABLES} +{$undef FAST_DIVIDE} + +{$define BITS_IN_JSAMPLE_IS_8} + +{----------------------------------------------------------------} +{ for test of 12 bit JPEG code only. !! } +{-- $undef BITS_IN_JSAMPLE_IS_8} +{----------------------------------------------------------------} + +{$define RGB_PIXELSIZE_IS_3} +{$define SLOW_SHIFT_32} +{$define RGB_RED_IS_0} { RGB byte order in JQUANT2 } + +{$undef NO_ZERO_ROW_TEST} + +{$define USE_MSDOS_MEMMGR} { Define this if you use jmemdos.c } +{$define XMS_SUPPORTED} +{$define EMS_SUPPORTED} + +{$undef MEM_STATS} { Write out memory usage } +{$define AM_MEMORY_MANAGER} { we define jvirt_Xarray_control structs } + +{$undef FULL_MAIN_BUFFER_SUPPORTED} + +{$define PROGRESS_REPORT} +{$define TWO_FILE_COMMANDLINE} +{$define BMP_SUPPORTED} +{$define PPM_SUPPORTED} +{$undef GIF_SUPPORTED} +{$undef RLE_SUPPORTED} +{$define TARGA_SUPPORTED} +{$define EXT_SWITCH} + +{$ifndef BITS_IN_JSAMPLE_IS_8} { for 12 bit samples } +{$undef BMP_SUPPORTED} +{$undef RLE_SUPPORTED} +{$undef TARGA_SUPPORTED} +{$endif} + +{$undef BASM16} { for TP7 - use BASM for fast multiply } +{$ifdef Win32} + {$ifndef FPC} + {$define BASM} { jidctint with BASM for Delphi 2/3 } + {$undef RGB_RED_IS_0} { BGR byte order in JQUANT2 } + {$endif} +{$endif} + +{$IFDEF FPC} +{$MODE DELPHI} +{$GOTO ON} +{$DEFINE DELPHI_STREAM} +{$else} +{$DEFINE DELPHI_STREAM} +{$ENDIF} diff --git a/mseide-msegui/lib/common/fpccompatibility/jconsts_del.pas b/mseide-msegui/lib/common/fpccompatibility/jconsts_del.pas new file mode 100644 index 0000000..b7339e4 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jconsts_del.pas @@ -0,0 +1,11 @@ +unit jconsts; + +interface + +resourcestring + sChangeJPGSize = 'Cannot change the size of a JPEG image'; + sJPEGError = 'JPEG error #%d'; + +implementation + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jcparam_del.pas b/mseide-msegui/lib/common/fpccompatibility/jcparam_del.pas new file mode 100644 index 0000000..a59c0a2 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jcparam_del.pas @@ -0,0 +1,700 @@ +Unit JcParam_del; + +{ This file contains optional default-setting code for the JPEG compressor. + Applications do not have to use this file, but those that don't use it + must know a lot more about the innards of the JPEG code. } + +{ Original: jcparam.c ; Copyright (C) 1991-1998, Thomas G. Lane. } + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jdeferr_del, + jerror_del, + jcomapi_del, + jpeglib_del; + +{ Quantization table setup routines } + +{GLOBAL} +procedure jpeg_add_quant_table (cinfo : j_compress_ptr; + which_tbl : int; + const basic_table : array of uInt; + scale_factor : int; + force_baseline : boolean); + +{GLOBAL} +procedure jpeg_set_linear_quality (cinfo : j_compress_ptr; + scale_factor : int; + force_baseline : boolean); +{ Set or change the 'quality' (quantization) setting, using default tables + and a straight percentage-scaling quality scale. In most cases it's better + to use jpeg_set_quality (below); this entry point is provided for + applications that insist on a linear percentage scaling. } + +{GLOBAL} +function jpeg_quality_scaling (quality : int) : int; +{ Convert a user-specified quality rating to a percentage scaling factor + for an underlying quantization table, using our recommended scaling curve. + The input 'quality' factor should be 0 (terrible) to 100 (very good). } + +{GLOBAL} +procedure jpeg_set_quality (cinfo : j_compress_ptr; + quality : int; + force_baseline : boolean); +{ Set or change the 'quality' (quantization) setting, using default tables. + This is the standard quality-adjusting entry point for typical user + interfaces; only those who want detailed control over quantization tables + would use the preceding three routines directly. } + +{GLOBAL} +procedure jpeg_set_defaults (cinfo : j_compress_ptr); + +{ Create a recommended progressive-JPEG script. + cinfo^.num_components and cinfo^.jpeg_color_space must be correct. } + +{ Set the JPEG colorspace, and choose colorspace-dependent default values. } + +{GLOBAL} +procedure jpeg_set_colorspace (cinfo : j_compress_ptr; + colorspace : J_COLOR_SPACE); + +{ Select an appropriate JPEG colorspace for in_color_space. } + +{GLOBAL} +procedure jpeg_default_colorspace (cinfo : j_compress_ptr); + +{GLOBAL} +procedure jpeg_simple_progression (cinfo : j_compress_ptr); + + +implementation + +{ Quantization table setup routines } + +{GLOBAL} +procedure jpeg_add_quant_table (cinfo : j_compress_ptr; + which_tbl : int; + const basic_table : array of uInt; + scale_factor : int; + force_baseline : boolean); +{ Define a quantization table equal to the basic_table times + a scale factor (given as a percentage). + If force_baseline is TRUE, the computed quantization table entries + are limited to 1..255 for JPEG baseline compatibility. } +var + qtblptr :^JQUANT_TBL_PTR; + i : int; + temp : long; +begin + { Safety check to ensure start_compress not called yet. } + if (cinfo^.global_state <> CSTATE_START) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + + if (which_tbl < 0) or (which_tbl >= NUM_QUANT_TBLS) then + ERREXIT1(j_common_ptr(cinfo), JERR_DQT_INDEX, which_tbl); + + qtblptr := @(cinfo^.quant_tbl_ptrs[which_tbl]); + + if (qtblptr^ = NIL) then + qtblptr^ := jpeg_alloc_quant_table(j_common_ptr(cinfo)); + + for i := 0 to pred(DCTSIZE2) do + begin + temp := (long(basic_table[i] * scale_factor) + long(50)) div long(100); + { limit the values to the valid range } + if (temp <= long(0)) then + temp := long(1); + if (temp > long(32767)) then + temp := long(32767); { max quantizer needed for 12 bits } + if (force_baseline) and (temp > long(255)) then + temp := long(255); { limit to baseline range if requested } + (qtblptr^)^.quantval[i] := UINT16 (temp); + end; + + { Initialize sent_table FALSE so table will be written to JPEG file. } + (qtblptr^)^.sent_table := FALSE; +end; + + +{GLOBAL} +procedure jpeg_set_linear_quality (cinfo : j_compress_ptr; + scale_factor : int; + force_baseline : boolean); +{ Set or change the 'quality' (quantization) setting, using default tables + and a straight percentage-scaling quality scale. In most cases it's better + to use jpeg_set_quality (below); this entry point is provided for + applications that insist on a linear percentage scaling. } + +{ These are the sample quantization tables given in JPEG spec section K.1. + The spec says that the values given produce "good" quality, and + when divided by 2, "very good" quality. } + +const + std_luminance_quant_tbl : array[0..DCTSIZE2-1] of uInt = + (16, 11, 10, 16, 24, 40, 51, 61, + 12, 12, 14, 19, 26, 58, 60, 55, + 14, 13, 16, 24, 40, 57, 69, 56, + 14, 17, 22, 29, 51, 87, 80, 62, + 18, 22, 37, 56, 68, 109, 103, 77, + 24, 35, 55, 64, 81, 104, 113, 92, + 49, 64, 78, 87, 103, 121, 120, 101, + 72, 92, 95, 98, 112, 100, 103, 99); + +const + std_chrominance_quant_tbl : array[0..DCTSIZE2-1] of uInt = + (17, 18, 24, 47, 99, 99, 99, 99, + 18, 21, 26, 66, 99, 99, 99, 99, + 24, 26, 56, 99, 99, 99, 99, 99, + 47, 66, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99); +begin + { Set up two quantization tables using the specified scaling } + jpeg_add_quant_table(cinfo, 0, std_luminance_quant_tbl, + scale_factor, force_baseline); + jpeg_add_quant_table(cinfo, 1, std_chrominance_quant_tbl, + scale_factor, force_baseline); +end; + + +{GLOBAL} +function jpeg_quality_scaling (quality : int) : int; +{ Convert a user-specified quality rating to a percentage scaling factor + for an underlying quantization table, using our recommended scaling curve. + The input 'quality' factor should be 0 (terrible) to 100 (very good). } +begin + { Safety limit on quality factor. Convert 0 to 1 to avoid zero divide. } + if (quality <= 0) then + quality := 1; + if (quality > 100) then + quality := 100; + + { The basic table is used as-is (scaling 100) for a quality of 50. + Qualities 50..100 are converted to scaling percentage 200 - 2*Q; + note that at Q=100 the scaling is 0, which will cause jpeg_add_quant_table + to make all the table entries 1 (hence, minimum quantization loss). + Qualities 1..50 are converted to scaling percentage 5000/Q. } + if (quality < 50) then + quality := 5000 div quality + else + quality := 200 - quality*2; + + jpeg_quality_scaling := quality; +end; + + +{GLOBAL} +procedure jpeg_set_quality (cinfo : j_compress_ptr; + quality : int; + force_baseline : boolean); +{ Set or change the 'quality' (quantization) setting, using default tables. + This is the standard quality-adjusting entry point for typical user + interfaces; only those who want detailed control over quantization tables + would use the preceding three routines directly. } +begin + { Convert user 0-100 rating to percentage scaling } + quality := jpeg_quality_scaling(quality); + + { Set up standard quality tables } + jpeg_set_linear_quality(cinfo, quality, force_baseline); +end; + + +{ Huffman table setup routines } + +{LOCAL} +procedure add_huff_table (cinfo : j_compress_ptr; + var htblptr : JHUFF_TBL_PTR; + var bits : array of UINT8; + var val : array of UINT8); +{ Define a Huffman table } +var + nsymbols, len : int; +begin + if (htblptr = NIL) then + htblptr := jpeg_alloc_huff_table(j_common_ptr(cinfo)); + + { Copy the number-of-symbols-of-each-code-length counts } + MEMCOPY(@htblptr^.bits, @bits, SIZEOF(htblptr^.bits)); + + + { Validate the counts. We do this here mainly so we can copy the right + number of symbols from the val[] array, without risking marching off + the end of memory. jchuff.c will do a more thorough test later. } + + nsymbols := 0; + for len := 1 to 16 do + Inc(nsymbols, bits[len]); + if (nsymbols < 1) or (nsymbols > 256) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_HUFF_TABLE); + + MEMCOPY(@htblptr^.huffval, @val, nsymbols * SIZEOF(UINT8)); + + { Initialize sent_table FALSE so table will be written to JPEG file. } + (htblptr)^.sent_table := FALSE; +end; + + +{LOCAL} +procedure std_huff_tables (cinfo : j_compress_ptr); +{ Set up the standard Huffman tables (cf. JPEG standard section K.3) } +{ IMPORTANT: these are only valid for 8-bit data precision! } + const bits_dc_luminance : array[0..17-1] of UINT8 = + ({ 0-base } 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0); + const val_dc_luminance : array[0..11] of UINT8 = + (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11); + + const bits_dc_chrominance : array[0..17-1] of UINT8 = + ( { 0-base } 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 ); + const val_dc_chrominance : array[0..11] of UINT8 = + ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ); + + const bits_ac_luminance : array[0..17-1] of UINT8 = + ( { 0-base } 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, $7d ); + const val_ac_luminance : array[0..161] of UINT8 = + ( $01, $02, $03, $00, $04, $11, $05, $12, + $21, $31, $41, $06, $13, $51, $61, $07, + $22, $71, $14, $32, $81, $91, $a1, $08, + $23, $42, $b1, $c1, $15, $52, $d1, $f0, + $24, $33, $62, $72, $82, $09, $0a, $16, + $17, $18, $19, $1a, $25, $26, $27, $28, + $29, $2a, $34, $35, $36, $37, $38, $39, + $3a, $43, $44, $45, $46, $47, $48, $49, + $4a, $53, $54, $55, $56, $57, $58, $59, + $5a, $63, $64, $65, $66, $67, $68, $69, + $6a, $73, $74, $75, $76, $77, $78, $79, + $7a, $83, $84, $85, $86, $87, $88, $89, + $8a, $92, $93, $94, $95, $96, $97, $98, + $99, $9a, $a2, $a3, $a4, $a5, $a6, $a7, + $a8, $a9, $aa, $b2, $b3, $b4, $b5, $b6, + $b7, $b8, $b9, $ba, $c2, $c3, $c4, $c5, + $c6, $c7, $c8, $c9, $ca, $d2, $d3, $d4, + $d5, $d6, $d7, $d8, $d9, $da, $e1, $e2, + $e3, $e4, $e5, $e6, $e7, $e8, $e9, $ea, + $f1, $f2, $f3, $f4, $f5, $f6, $f7, $f8, + $f9, $fa ); + + const bits_ac_chrominance : array[0..17-1] of UINT8 = + ( { 0-base } 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, $77 ); + const val_ac_chrominance : array[0..161] of UINT8 = + ( $00, $01, $02, $03, $11, $04, $05, $21, + $31, $06, $12, $41, $51, $07, $61, $71, + $13, $22, $32, $81, $08, $14, $42, $91, + $a1, $b1, $c1, $09, $23, $33, $52, $f0, + $15, $62, $72, $d1, $0a, $16, $24, $34, + $e1, $25, $f1, $17, $18, $19, $1a, $26, + $27, $28, $29, $2a, $35, $36, $37, $38, + $39, $3a, $43, $44, $45, $46, $47, $48, + $49, $4a, $53, $54, $55, $56, $57, $58, + $59, $5a, $63, $64, $65, $66, $67, $68, + $69, $6a, $73, $74, $75, $76, $77, $78, + $79, $7a, $82, $83, $84, $85, $86, $87, + $88, $89, $8a, $92, $93, $94, $95, $96, + $97, $98, $99, $9a, $a2, $a3, $a4, $a5, + $a6, $a7, $a8, $a9, $aa, $b2, $b3, $b4, + $b5, $b6, $b7, $b8, $b9, $ba, $c2, $c3, + $c4, $c5, $c6, $c7, $c8, $c9, $ca, $d2, + $d3, $d4, $d5, $d6, $d7, $d8, $d9, $da, + $e2, $e3, $e4, $e5, $e6, $e7, $e8, $e9, + $ea, $f2, $f3, $f4, $f5, $f6, $f7, $f8, + $f9, $fa ); +begin + add_huff_table(cinfo, cinfo^.dc_huff_tbl_ptrs[0], + bits_dc_luminance, val_dc_luminance); + add_huff_table(cinfo, cinfo^.ac_huff_tbl_ptrs[0], + bits_ac_luminance, val_ac_luminance); + add_huff_table(cinfo, cinfo^.dc_huff_tbl_ptrs[1], + bits_dc_chrominance, val_dc_chrominance); + add_huff_table(cinfo, cinfo^.ac_huff_tbl_ptrs[1], + bits_ac_chrominance, val_ac_chrominance); +end; + + +{ Default parameter setup for compression. + + Applications that don't choose to use this routine must do their + own setup of all these parameters. Alternately, you can call this + to establish defaults and then alter parameters selectively. This + is the recommended approach since, if we add any new parameters, + your code will still work (they'll be set to reasonable defaults). } + +{GLOBAL} +procedure jpeg_set_defaults (cinfo : j_compress_ptr); +var + i : int; +begin + { Safety check to ensure start_compress not called yet. } + if (cinfo^.global_state <> CSTATE_START) then + ERREXIT1(J_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + + { Allocate comp_info array large enough for maximum component count. + Array is made permanent in case application wants to compress + multiple images at same param settings. } + + if (cinfo^.comp_info = NIL) then + cinfo^.comp_info := jpeg_component_info_list_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_PERMANENT, + MAX_COMPONENTS * SIZEOF(jpeg_component_info)) ); + + { Initialize everything not dependent on the color space } + + cinfo^.data_precision := BITS_IN_JSAMPLE; + { Set up two quantization tables using default quality of 75 } + jpeg_set_quality(cinfo, 75, TRUE); + { Set up two Huffman tables } + std_huff_tables(cinfo); + + { Initialize default arithmetic coding conditioning } + for i := 0 to pred(NUM_ARITH_TBLS) do + begin + cinfo^.arith_dc_L[i] := 0; + cinfo^.arith_dc_U[i] := 1; + cinfo^.arith_ac_K[i] := 5; + end; + + { Default is no multiple-scan output } + cinfo^.scan_info := NIL; + cinfo^.num_scans := 0; + + { Expect normal source image, not raw downsampled data } + cinfo^.raw_data_in := FALSE; + + { Use Huffman coding, not arithmetic coding, by default } + cinfo^.arith_code := FALSE; + + { By default, don't do extra passes to optimize entropy coding } + cinfo^.optimize_coding := FALSE; + { The standard Huffman tables are only valid for 8-bit data precision. + If the precision is higher, force optimization on so that usable + tables will be computed. This test can be removed if default tables + are supplied that are valid for the desired precision. } + + if (cinfo^.data_precision > 8) then + cinfo^.optimize_coding := TRUE; + + { By default, use the simpler non-cosited sampling alignment } + cinfo^.CCIR601_sampling := FALSE; + + { No input smoothing } + cinfo^.smoothing_factor := 0; + + { DCT algorithm preference } + cinfo^.dct_method := JDCT_DEFAULT; + + { No restart markers } + cinfo^.restart_interval := 0; + cinfo^.restart_in_rows := 0; + + { Fill in default JFIF marker parameters. Note that whether the marker + will actually be written is determined by jpeg_set_colorspace. + + By default, the library emits JFIF version code 1.01. + An application that wants to emit JFIF 1.02 extension markers should set + JFIF_minor_version to 2. We could probably get away with just defaulting + to 1.02, but there may still be some decoders in use that will complain + about that; saying 1.01 should minimize compatibility problems. } + + cinfo^.JFIF_major_version := 1; { Default JFIF version = 1.01 } + cinfo^.JFIF_minor_version := 1; + cinfo^.density_unit := 0; { Pixel size is unknown by default } + cinfo^.X_density := 1; { Pixel aspect ratio is square by default } + cinfo^.Y_density := 1; + + { Choose JPEG colorspace based on input space, set defaults accordingly } + + jpeg_default_colorspace(cinfo); +end; + + +{ Select an appropriate JPEG colorspace for in_color_space. } + +{GLOBAL} +procedure jpeg_default_colorspace (cinfo : j_compress_ptr); +begin + case (cinfo^.in_color_space) of + JCS_GRAYSCALE: + jpeg_set_colorspace(cinfo, JCS_GRAYSCALE); + JCS_RGB: + jpeg_set_colorspace(cinfo, JCS_YCbCr); + JCS_YCbCr: + jpeg_set_colorspace(cinfo, JCS_YCbCr); + JCS_CMYK: + jpeg_set_colorspace(cinfo, JCS_CMYK); { By default, no translation } + JCS_YCCK: + jpeg_set_colorspace(cinfo, JCS_YCCK); + JCS_UNKNOWN: + jpeg_set_colorspace(cinfo, JCS_UNKNOWN); + else + ERREXIT(j_common_ptr(cinfo), JERR_BAD_IN_COLORSPACE); + end; +end; + + +{ Set the JPEG colorspace, and choose colorspace-dependent default values. } + +{GLOBAL} +procedure jpeg_set_colorspace (cinfo : j_compress_ptr; + colorspace : J_COLOR_SPACE); + { macro } + procedure SET_COMP(index,id,hsamp,vsamp,quant,dctbl,actbl : int); + begin + with cinfo^.comp_info^[index] do + begin + component_id := (id); + h_samp_factor := (hsamp); + v_samp_factor := (vsamp); + quant_tbl_no := (quant); + dc_tbl_no := (dctbl); + ac_tbl_no := (actbl); + end; + end; + +var + ci : int; +begin + { Safety check to ensure start_compress not called yet. } + if (cinfo^.global_state <> CSTATE_START) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + + { For all colorspaces, we use Q and Huff tables 0 for luminance components, + tables 1 for chrominance components. } + + cinfo^.jpeg_color_space := colorspace; + + cinfo^.write_JFIF_header := FALSE; { No marker for non-JFIF colorspaces } + cinfo^.write_Adobe_marker := FALSE; { write no Adobe marker by default } + + case (colorspace) of + JCS_GRAYSCALE: + begin + cinfo^.write_JFIF_header := TRUE; { Write a JFIF marker } + cinfo^.num_components := 1; + { JFIF specifies component ID 1 } + SET_COMP(0, 1, 1,1, 0, 0,0); + end; + JCS_RGB: + begin + cinfo^.write_Adobe_marker := TRUE; { write Adobe marker to flag RGB } + cinfo^.num_components := 3; + SET_COMP(0, $52 { 'R' }, 1,1, 0, 0,0); + SET_COMP(1, $47 { 'G' }, 1,1, 0, 0,0); + SET_COMP(2, $42 { 'B' }, 1,1, 0, 0,0); + end; + JCS_YCbCr: + begin + cinfo^.write_JFIF_header := TRUE; { Write a JFIF marker } + cinfo^.num_components := 3; + { JFIF specifies component IDs 1,2,3 } + { We default to 2x2 subsamples of chrominance } + SET_COMP(0, 1, 2,2, 0, 0,0); + SET_COMP(1, 2, 1,1, 1, 1,1); + SET_COMP(2, 3, 1,1, 1, 1,1); + end; + JCS_CMYK: + begin + cinfo^.write_Adobe_marker := TRUE; { write Adobe marker to flag CMYK } + cinfo^.num_components := 4; + SET_COMP(0, $43 { 'C' }, 1,1, 0, 0,0); + SET_COMP(1, $4D { 'M' }, 1,1, 0, 0,0); + SET_COMP(2, $59 { 'Y' }, 1,1, 0, 0,0); + SET_COMP(3, $4B { 'K' }, 1,1, 0, 0,0); + end; + JCS_YCCK: + begin + cinfo^.write_Adobe_marker := TRUE; { write Adobe marker to flag YCCK } + cinfo^.num_components := 4; + SET_COMP(0, 1, 2,2, 0, 0,0); + SET_COMP(1, 2, 1,1, 1, 1,1); + SET_COMP(2, 3, 1,1, 1, 1,1); + SET_COMP(3, 4, 2,2, 0, 0,0); + end; + JCS_UNKNOWN: + begin + cinfo^.num_components := cinfo^.input_components; + if (cinfo^.num_components < 1) + or (cinfo^.num_components > MAX_COMPONENTS) then + ERREXIT2(j_common_ptr(cinfo), JERR_COMPONENT_COUNT, + cinfo^.num_components, MAX_COMPONENTS); + for ci := 0 to pred(cinfo^.num_components) do + begin + SET_COMP(ci, ci, 1,1, 0, 0,0); + end; + end; + else + ERREXIT(j_common_ptr(cinfo), JERR_BAD_J_COLORSPACE); + end; +end; + + +{$ifdef C_PROGRESSIVE_SUPPORTED} + +{LOCAL} +function fill_a_scan (scanptr : jpeg_scan_info_ptr; + ci : int; Ss : int; + Se : int; Ah : int; + Al : int) : jpeg_scan_info_ptr; +{ Support routine: generate one scan for specified component } +begin + scanptr^.comps_in_scan := 1; + scanptr^.component_index[0] := ci; + scanptr^.Ss := Ss; + scanptr^.Se := Se; + scanptr^.Ah := Ah; + scanptr^.Al := Al; + Inc(scanptr); + fill_a_scan := scanptr; +end; + +{LOCAL} +function fill_scans (scanptr : jpeg_scan_info_ptr; + ncomps : int; + Ss : int; Se : int; + Ah : int; Al : int) : jpeg_scan_info_ptr; +{ Support routine: generate one scan for each component } +var + ci : int; +begin + + for ci := 0 to pred(ncomps) do + begin + scanptr^.comps_in_scan := 1; + scanptr^.component_index[0] := ci; + scanptr^.Ss := Ss; + scanptr^.Se := Se; + scanptr^.Ah := Ah; + scanptr^.Al := Al; + Inc(scanptr); + end; + fill_scans := scanptr; +end; + +{LOCAL} +function fill_dc_scans (scanptr : jpeg_scan_info_ptr; + ncomps : int; + Ah : int; Al : int) : jpeg_scan_info_ptr; +{ Support routine: generate interleaved DC scan if possible, else N scans } +var + ci : int; +begin + + if (ncomps <= MAX_COMPS_IN_SCAN) then + begin + { Single interleaved DC scan } + scanptr^.comps_in_scan := ncomps; + for ci := 0 to pred(ncomps) do + scanptr^.component_index[ci] := ci; + scanptr^.Ss := 0; + scanptr^.Se := 0; + scanptr^.Ah := Ah; + scanptr^.Al := Al; + Inc(scanptr); + end + else + begin + { Noninterleaved DC scan for each component } + scanptr := fill_scans(scanptr, ncomps, 0, 0, Ah, Al); + end; + fill_dc_scans := scanptr; +end; + + +{ Create a recommended progressive-JPEG script. + cinfo^.num_components and cinfo^.jpeg_color_space must be correct. } + +{GLOBAL} +procedure jpeg_simple_progression (cinfo : j_compress_ptr); +var + ncomps : int; + nscans : int; + scanptr : jpeg_scan_info_ptr; +begin + ncomps := cinfo^.num_components; + + { Safety check to ensure start_compress not called yet. } + if (cinfo^.global_state <> CSTATE_START) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + + { Figure space needed for script. Calculation must match code below! } + if (ncomps = 3) and (cinfo^.jpeg_color_space = JCS_YCbCr) then + begin + { Custom script for YCbCr color images. } + nscans := 10; + end + else + begin + { All-purpose script for other color spaces. } + if (ncomps > MAX_COMPS_IN_SCAN) then + nscans := 6 * ncomps { 2 DC + 4 AC scans per component } + else + nscans := 2 + 4 * ncomps; { 2 DC scans; 4 AC scans per component } + end; + + { Allocate space for script. + We need to put it in the permanent pool in case the application performs + multiple compressions without changing the settings. To avoid a memory + leak if jpeg_simple_progression is called repeatedly for the same JPEG + object, we try to re-use previously allocated space, and we allocate + enough space to handle YCbCr even if initially asked for grayscale. } + + if (cinfo^.script_space = NIL) or (cinfo^.script_space_size < nscans) then + begin + if nscans > 10 then + cinfo^.script_space_size := nscans + else + cinfo^.script_space_size := 10; + + cinfo^.script_space := jpeg_scan_info_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_PERMANENT, + cinfo^.script_space_size * SIZEOF(jpeg_scan_info)) ); + end; + scanptr := cinfo^.script_space; + + cinfo^.scan_info := scanptr; + cinfo^.num_scans := nscans; + + if (ncomps = 3) and (cinfo^.jpeg_color_space = JCS_YCbCr) then + begin + { Custom script for YCbCr color images. } + { Initial DC scan } + scanptr := fill_dc_scans(scanptr, ncomps, 0, 1); + { Initial AC scan: get some luma data out in a hurry } + scanptr := fill_a_scan(scanptr, 0, 1, 5, 0, 2); + { Chroma data is too small to be worth expending many scans on } + scanptr := fill_a_scan(scanptr, 2, 1, 63, 0, 1); + scanptr := fill_a_scan(scanptr, 1, 1, 63, 0, 1); + { Complete spectral selection for luma AC } + scanptr := fill_a_scan(scanptr, 0, 6, 63, 0, 2); + { Refine next bit of luma AC } + scanptr := fill_a_scan(scanptr, 0, 1, 63, 2, 1); + { Finish DC successive approximation } + scanptr := fill_dc_scans(scanptr, ncomps, 1, 0); + { Finish AC successive approximation } + scanptr := fill_a_scan(scanptr, 2, 1, 63, 1, 0); + scanptr := fill_a_scan(scanptr, 1, 1, 63, 1, 0); + { Luma bottom bit comes last since it's usually largest scan } + scanptr := fill_a_scan(scanptr, 0, 1, 63, 1, 0); + end + else + begin + { All-purpose script for other color spaces. } + { Successive approximation first pass } + scanptr := fill_dc_scans(scanptr, ncomps, 0, 1); + scanptr := fill_scans(scanptr, ncomps, 1, 5, 0, 2); + scanptr := fill_scans(scanptr, ncomps, 6, 63, 0, 2); + { Successive approximation second pass } + scanptr := fill_scans(scanptr, ncomps, 1, 63, 2, 1); + { Successive approximation final pass } + scanptr := fill_dc_scans(scanptr, ncomps, 1, 0); + scanptr := fill_scans(scanptr, ncomps, 1, 63, 1, 0); + end; +end; + +{$endif} +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jcphuff_del.pas b/mseide-msegui/lib/common/fpccompatibility/jcphuff_del.pas new file mode 100644 index 0000000..f816608 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jcphuff_del.pas @@ -0,0 +1,962 @@ +Unit jcphuff_del; + +{ This file contains Huffman entropy encoding routines for progressive JPEG. + + We do not support output suspension in this module, since the library + currently does not allow multiple-scan files to be written with output + suspension. } + +{ Original: jcphuff.c; Copyright (C) 1995-1997, Thomas G. Lane. } + +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} +uses + jmorecfg_del, + jinclude_del, + jpeglib_del, + jdeferr_del, + jerror_del, + jutils_del, + jcomapi_del, + jchuff_del; { Declarations shared with jchuff.c } + + +{ Module initialization routine for progressive Huffman entropy encoding. } + +{GLOBAL} +procedure jinit_phuff_encoder (cinfo : j_compress_ptr); + +implementation + +{ Expanded entropy encoder object for progressive Huffman encoding. } +type + phuff_entropy_ptr = ^phuff_entropy_encoder; + phuff_entropy_encoder = record + pub : jpeg_entropy_encoder; { public fields } + + { Mode flag: TRUE for optimization, FALSE for actual data output } + gather_statistics : boolean; + + { Bit-level coding status. + next_output_byte/free_in_buffer are local copies of cinfo^.dest fields.} + + next_output_byte : JOCTETptr; { => next byte to write in buffer } + free_in_buffer : size_t; { # of byte spaces remaining in buffer } + put_buffer : INT32; { current bit-accumulation buffer } + put_bits : int; { # of bits now in it } + cinfo : j_compress_ptr; { link to cinfo (needed for dump_buffer) } + + { Coding status for DC components } + last_dc_val : array[0..MAX_COMPS_IN_SCAN-1] of int; + { last DC coef for each component } + + { Coding status for AC components } + ac_tbl_no : int; { the table number of the single component } + EOBRUN : uInt; { run length of EOBs } + BE : uInt; { # of buffered correction bits before MCU } + bit_buffer : JBytePtr; { buffer for correction bits (1 per char) } + { packing correction bits tightly would save some space but cost time... } + + restarts_to_go : uInt; { MCUs left in this restart interval } + next_restart_num : int; { next restart number to write (0-7) } + + { Pointers to derived tables (these workspaces have image lifespan). + Since any one scan codes only DC or only AC, we only need one set + of tables, not one for DC and one for AC. } + + derived_tbls : array[0..NUM_HUFF_TBLS-1] of c_derived_tbl_ptr; + + { Statistics tables for optimization; again, one set is enough } + count_ptrs : array[0..NUM_HUFF_TBLS-1] of TLongTablePtr; + end; + + +{ MAX_CORR_BITS is the number of bits the AC refinement correction-bit + buffer can hold. Larger sizes may slightly improve compression, but + 1000 is already well into the realm of overkill. + The minimum safe size is 64 bits. } + +const + MAX_CORR_BITS = 1000; { Max # of correction bits I can buffer } + + +{ Forward declarations } +{METHODDEF} +function encode_mcu_DC_first (cinfo : j_compress_ptr; + const MCU_data: array of JBLOCKROW) : boolean; + forward; +{METHODDEF} +function encode_mcu_AC_first (cinfo : j_compress_ptr; + const MCU_data: array of JBLOCKROW) : boolean; + forward; +{METHODDEF} +function encode_mcu_DC_refine (cinfo : j_compress_ptr; + const MCU_data: array of JBLOCKROW) : boolean; + forward; +{METHODDEF} +function encode_mcu_AC_refine (cinfo : j_compress_ptr; + const MCU_data: array of JBLOCKROW) : boolean; + forward; + +{METHODDEF} +procedure finish_pass_phuff (cinfo : j_compress_ptr); forward; + +{METHODDEF} +procedure finish_pass_gather_phuff (cinfo : j_compress_ptr); forward; + + +{ Initialize for a Huffman-compressed scan using progressive JPEG. } + +{METHODDEF} +procedure start_pass_phuff (cinfo : j_compress_ptr; + gather_statistics : boolean); +var + entropy : phuff_entropy_ptr; + is_DC_band : boolean; + ci, tbl : int; + compptr : jpeg_component_info_ptr; +begin + entropy := phuff_entropy_ptr (cinfo^.entropy); + + entropy^.cinfo := cinfo; + entropy^.gather_statistics := gather_statistics; + + is_DC_band := (cinfo^.Ss = 0); + + { We assume jcmaster.c already validated the scan parameters. } + + { Select execution routines } + if (cinfo^.Ah = 0) then + begin + if (is_DC_band) then + entropy^.pub.encode_mcu := encode_mcu_DC_first + else + entropy^.pub.encode_mcu := encode_mcu_AC_first; + end + else + begin + if (is_DC_band) then + entropy^.pub.encode_mcu := encode_mcu_DC_refine + else + begin + entropy^.pub.encode_mcu := encode_mcu_AC_refine; + { AC refinement needs a correction bit buffer } + if (entropy^.bit_buffer = NIL) then + entropy^.bit_buffer := JBytePtr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + MAX_CORR_BITS * SIZEOF(byte)) ); + end; + end; + if (gather_statistics) then + entropy^.pub.finish_pass := finish_pass_gather_phuff + else + entropy^.pub.finish_pass := finish_pass_phuff; + + { Only DC coefficients may be interleaved, so cinfo^.comps_in_scan = 1 + for AC coefficients. } + + for ci := 0 to pred(cinfo^.comps_in_scan) do + begin + compptr := cinfo^.cur_comp_info[ci]; + { Initialize DC predictions to 0 } + entropy^.last_dc_val[ci] := 0; + { Get table index } + if (is_DC_band) then + begin + if (cinfo^.Ah <> 0) then { DC refinement needs no table } + continue; + tbl := compptr^.dc_tbl_no; + end + else + begin + tbl := compptr^.ac_tbl_no; + entropy^.ac_tbl_no := tbl; + end; + if (gather_statistics) then + begin + { Check for invalid table index } + { (make_c_derived_tbl does this in the other path) } + if (tbl < 0) or (tbl >= NUM_HUFF_TBLS) then + ERREXIT1(j_common_ptr(cinfo), JERR_NO_HUFF_TABLE, tbl); + { Allocate and zero the statistics tables } + { Note that jpeg_gen_optimal_table expects 257 entries in each table! } + if (entropy^.count_ptrs[tbl] = NIL) then + entropy^.count_ptrs[tbl] := TLongTablePtr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + 257 * SIZEOF(long)) ); + MEMZERO(entropy^.count_ptrs[tbl], 257 * SIZEOF(long)); + end else + begin + { Compute derived values for Huffman table } + { We may do this more than once for a table, but it's not expensive } + jpeg_make_c_derived_tbl(cinfo, is_DC_band, tbl, + entropy^.derived_tbls[tbl]); + end; + end; + + { Initialize AC stuff } + entropy^.EOBRUN := 0; + entropy^.BE := 0; + + { Initialize bit buffer to empty } + entropy^.put_buffer := 0; + entropy^.put_bits := 0; + + { Initialize restart stuff } + entropy^.restarts_to_go := cinfo^.restart_interval; + entropy^.next_restart_num := 0; +end; + + + + +{LOCAL} +procedure dump_buffer (entropy : phuff_entropy_ptr); +{ Empty the output buffer; we do not support suspension in this module. } +var + dest : jpeg_destination_mgr_ptr; +begin + dest := entropy^.cinfo^.dest; + + if (not dest^.empty_output_buffer (entropy^.cinfo)) then + ERREXIT(j_common_ptr(entropy^.cinfo), JERR_CANT_SUSPEND); + { After a successful buffer dump, must reset buffer pointers } + entropy^.next_output_byte := dest^.next_output_byte; + entropy^.free_in_buffer := dest^.free_in_buffer; +end; + + +{ Outputting bits to the file } + +{ Only the right 24 bits of put_buffer are used; the valid bits are + left-justified in this part. At most 16 bits can be passed to emit_bits + in one call, and we never retain more than 7 bits in put_buffer + between calls, so 24 bits are sufficient. } + + +{LOCAL} +procedure emit_bits (entropy : phuff_entropy_ptr; + code : uInt; + size : int); {INLINE} +{ Emit some bits, unless we are in gather mode } +var + {register} put_buffer : INT32; + {register} put_bits : int; +var + c : int; +begin + { This routine is heavily used, so it's worth coding tightly. } + put_buffer := INT32 (code); + put_bits := entropy^.put_bits; + + { if size is 0, caller used an invalid Huffman table entry } + if (size = 0) then + ERREXIT(j_common_ptr(entropy^.cinfo), JERR_HUFF_MISSING_CODE); + + if (entropy^.gather_statistics) then + exit; { do nothing if we're only getting stats } + + put_buffer := put_buffer and ((INT32(1) shl size) - 1); + { mask off any extra bits in code } + + Inc(put_bits, size); { new number of bits in buffer } + + put_buffer := put_buffer shl (24 - put_bits); { align incoming bits } + + put_buffer := put_buffer or entropy^.put_buffer; + { and merge with old buffer contents } + + while (put_bits >= 8) do + begin + c := int ((put_buffer shr 16) and $FF); + + {emit_byte(entropy, c);} + { Outputting bytes to the file. + NB: these must be called only when actually outputting, + that is, entropy^.gather_statistics = FALSE. } + { Emit a byte } + entropy^.next_output_byte^ := JOCTET(c); + Inc(entropy^.next_output_byte); + Dec(entropy^.free_in_buffer); + if (entropy^.free_in_buffer = 0) then + dump_buffer(entropy); + + if (c = $FF) then + begin { need to stuff a zero byte? } + {emit_byte(entropy, 0);} + entropy^.next_output_byte^ := JOCTET(0); + Inc(entropy^.next_output_byte); + Dec(entropy^.free_in_buffer); + if (entropy^.free_in_buffer = 0) then + dump_buffer(entropy); + end; + put_buffer := put_buffer shl 8; + Dec(put_bits, 8); + end; + + entropy^.put_buffer := put_buffer; { update variables } + entropy^.put_bits := put_bits; +end; + + +{LOCAL} +procedure flush_bits (entropy : phuff_entropy_ptr); +begin + emit_bits(entropy, $7F, 7); { fill any partial byte with ones } + entropy^.put_buffer := 0; { and reset bit-buffer to empty } + entropy^.put_bits := 0; +end; + +{ Emit (or just count) a Huffman symbol. } + + +{LOCAL} +procedure emit_symbol (entropy : phuff_entropy_ptr; + tbl_no : int; + symbol : int); {INLINE} +var + tbl : c_derived_tbl_ptr; +begin + if (entropy^.gather_statistics) then + Inc(entropy^.count_ptrs[tbl_no]^[symbol]) + else + begin + tbl := entropy^.derived_tbls[tbl_no]; + emit_bits(entropy, tbl^.ehufco[symbol], tbl^.ehufsi[symbol]); + end; +end; + + +{ Emit bits from a correction bit buffer. } + +{LOCAL} +procedure emit_buffered_bits (entropy : phuff_entropy_ptr; + bufstart : JBytePtr; + nbits : uInt); +var + bufptr : byteptr; +begin + if (entropy^.gather_statistics) then + exit; { no real work } + + bufptr := byteptr(bufstart); + while (nbits > 0) do + begin + emit_bits(entropy, uInt(bufptr^), 1); + Inc(bufptr); + Dec(nbits); + end; +end; + + +{ Emit any pending EOBRUN symbol. } + +{LOCAL} +procedure emit_eobrun (entropy : phuff_entropy_ptr); +var + {register} temp, nbits : int; +begin + if (entropy^.EOBRUN > 0) then + begin { if there is any pending EOBRUN } + temp := entropy^.EOBRUN; + nbits := 0; + temp := temp shr 1; + while (temp <> 0) do + begin + Inc(nbits); + temp := temp shr 1; + end; + + { safety check: shouldn't happen given limited correction-bit buffer } + if (nbits > 14) then + ERREXIT(j_common_ptr(entropy^.cinfo), JERR_HUFF_MISSING_CODE); + + emit_symbol(entropy, entropy^.ac_tbl_no, nbits shl 4); + if (nbits <> 0) then + emit_bits(entropy, entropy^.EOBRUN, nbits); + + entropy^.EOBRUN := 0; + + { Emit any buffered correction bits } + emit_buffered_bits(entropy, entropy^.bit_buffer, entropy^.BE); + entropy^.BE := 0; + end; +end; + + +{ Emit a restart marker & resynchronize predictions. } + +{LOCAL} +procedure emit_restart (entropy : phuff_entropy_ptr; + restart_num : int); +var + ci : int; +begin + emit_eobrun(entropy); + + if (not entropy^.gather_statistics) then + begin + flush_bits(entropy); + {emit_byte(entropy, $FF);} + { Outputting bytes to the file. + NB: these must be called only when actually outputting, + that is, entropy^.gather_statistics = FALSE. } + + entropy^.next_output_byte^ := JOCTET($FF); + Inc(entropy^.next_output_byte); + Dec(entropy^.free_in_buffer); + if (entropy^.free_in_buffer = 0) then + dump_buffer(entropy); + + {emit_byte(entropy, JPEG_RST0 + restart_num);} + entropy^.next_output_byte^ := JOCTET(JPEG_RST0 + restart_num); + Inc(entropy^.next_output_byte); + Dec(entropy^.free_in_buffer); + if (entropy^.free_in_buffer = 0) then + dump_buffer(entropy); + end; + + if (entropy^.cinfo^.Ss = 0) then + begin + { Re-initialize DC predictions to 0 } + for ci := 0 to pred(entropy^.cinfo^.comps_in_scan) do + entropy^.last_dc_val[ci] := 0; + end + else + begin + { Re-initialize all AC-related fields to 0 } + entropy^.EOBRUN := 0; + entropy^.BE := 0; + end; +end; + + +{ MCU encoding for DC initial scan (either spectral selection, + or first pass of successive approximation). } + +{METHODDEF} +function encode_mcu_DC_first (cinfo : j_compress_ptr; + const MCU_data: array of JBLOCKROW) : boolean; +var + entropy : phuff_entropy_ptr; + {register} temp, temp2 : int; + {register} nbits : int; + blkn, ci : int; + Al : int; + block : JBLOCK_PTR; + compptr : jpeg_component_info_ptr; + ishift_temp : int; +begin + entropy := phuff_entropy_ptr (cinfo^.entropy); + Al := cinfo^.Al; + + entropy^.next_output_byte := cinfo^.dest^.next_output_byte; + entropy^.free_in_buffer := cinfo^.dest^.free_in_buffer; + + { Emit restart marker if needed } + if (cinfo^.restart_interval <> 0) then + if (entropy^.restarts_to_go = 0) then + emit_restart(entropy, entropy^.next_restart_num); + + { Encode the MCU data blocks } + for blkn := 0 to pred(cinfo^.blocks_in_MCU) do + begin + block := JBLOCK_PTR(MCU_data[blkn]); + ci := cinfo^.MCU_membership[blkn]; + compptr := cinfo^.cur_comp_info[ci]; + + { Compute the DC value after the required point transform by Al. + This is simply an arithmetic right shift. } + + {temp2 := IRIGHT_SHIFT( int(block^[0]), Al);} + {IRIGHT_SHIFT_IS_UNSIGNED} + ishift_temp := int(block^[0]); + if ishift_temp < 0 then + temp2 := (ishift_temp shr Al) or ((not 0) shl (16-Al)) + else + temp2 := ishift_temp shr Al; + + + { DC differences are figured on the point-transformed values. } + temp := temp2 - entropy^.last_dc_val[ci]; + entropy^.last_dc_val[ci] := temp2; + + { Encode the DC coefficient difference per section G.1.2.1 } + temp2 := temp; + if (temp < 0) then + begin + temp := -temp; { temp is abs value of input } + { For a negative input, want temp2 := bitwise complement of abs(input) } + { This code assumes we are on a two's complement machine } + Dec(temp2); + end; + + { Find the number of bits needed for the magnitude of the coefficient } + nbits := 0; + while (temp <> 0) do + begin + Inc(nbits); + temp := temp shr 1; + end; + + { Check for out-of-range coefficient values. + Since we're encoding a difference, the range limit is twice as much. } + + if (nbits > MAX_COEF_BITS+1) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_DCT_COEF); + + { Count/emit the Huffman-coded symbol for the number of bits } + emit_symbol(entropy, compptr^.dc_tbl_no, nbits); + + { Emit that number of bits of the value, if positive, } + { or the complement of its magnitude, if negative. } + if (nbits <> 0) then { emit_bits rejects calls with size 0 } + emit_bits(entropy, uInt(temp2), nbits); + end; + + cinfo^.dest^.next_output_byte := entropy^.next_output_byte; + cinfo^.dest^.free_in_buffer := entropy^.free_in_buffer; + + { Update restart-interval state too } + if (cinfo^.restart_interval <> 0) then + begin + if (entropy^.restarts_to_go = 0) then + begin + entropy^.restarts_to_go := cinfo^.restart_interval; + Inc(entropy^.next_restart_num); + with entropy^ do + next_restart_num := next_restart_num and 7; + end; + Dec(entropy^.restarts_to_go); + end; + + encode_mcu_DC_first := TRUE; +end; + + +{ MCU encoding for AC initial scan (either spectral selection, + or first pass of successive approximation). } + +{METHODDEF} +function encode_mcu_AC_first (cinfo : j_compress_ptr; + const MCU_data: array of JBLOCKROW) : boolean; +var + entropy : phuff_entropy_ptr; + {register} temp, temp2 : int; + {register} nbits : int; + {register} r, k : int; + Se : int; + Al : int; + block : JBLOCK_PTR; +begin + entropy := phuff_entropy_ptr (cinfo^.entropy); + Se := cinfo^.Se; + Al := cinfo^.Al; + + entropy^.next_output_byte := cinfo^.dest^.next_output_byte; + entropy^.free_in_buffer := cinfo^.dest^.free_in_buffer; + + { Emit restart marker if needed } + if (cinfo^.restart_interval <> 0) then + if (entropy^.restarts_to_go = 0) then + emit_restart(entropy, entropy^.next_restart_num); + + { Encode the MCU data block } + block := JBLOCK_PTR(MCU_data[0]); + + { Encode the AC coefficients per section G.1.2.2, fig. G.3 } + + r := 0; { r := run length of zeros } + + for k := cinfo^.Ss to Se do + begin + temp := (block^[jpeg_natural_order[k]]); + if (temp = 0) then + begin + Inc(r); + continue; + end; + { We must apply the point transform by Al. For AC coefficients this + is an integer division with rounding towards 0. To do this portably + in C, we shift after obtaining the absolute value; so the code is + interwoven with finding the abs value (temp) and output bits (temp2). } + + if (temp < 0) then + begin + temp := -temp; { temp is abs value of input } + temp := temp shr Al; { apply the point transform } + { For a negative coef, want temp2 := bitwise complement of abs(coef) } + temp2 := not temp; + end + else + begin + temp := temp shr Al; { apply the point transform } + temp2 := temp; + end; + { Watch out for case that nonzero coef is zero after point transform } + if (temp = 0) then + begin + Inc(r); + continue; + end; + + { Emit any pending EOBRUN } + if (entropy^.EOBRUN > 0) then + emit_eobrun(entropy); + { if run length > 15, must emit special run-length-16 codes ($F0) } + while (r > 15) do + begin + emit_symbol(entropy, entropy^.ac_tbl_no, $F0); + Dec(r, 16); + end; + + { Find the number of bits needed for the magnitude of the coefficient } + nbits := 0; { there must be at least one 1 bit } + repeat + Inc(nbits); + temp := temp shr 1; + until (temp = 0); + + { Check for out-of-range coefficient values } + if (nbits > MAX_COEF_BITS) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_DCT_COEF); + + { Count/emit Huffman symbol for run length / number of bits } + emit_symbol(entropy, entropy^.ac_tbl_no, (r shl 4) + nbits); + + { Emit that number of bits of the value, if positive, } + { or the complement of its magnitude, if negative. } + emit_bits(entropy, uInt(temp2), nbits); + + r := 0; { reset zero run length } + end; + + if (r > 0) then + begin { If there are trailing zeroes, } + Inc(entropy^.EOBRUN); { count an EOB } + if (entropy^.EOBRUN = $7FFF) then + emit_eobrun(entropy); { force it out to avoid overflow } + end; + + cinfo^.dest^.next_output_byte := entropy^.next_output_byte; + cinfo^.dest^.free_in_buffer := entropy^.free_in_buffer; + + { Update restart-interval state too } + if (cinfo^.restart_interval <> 0) then + begin + if (entropy^.restarts_to_go = 0) then + begin + entropy^.restarts_to_go := cinfo^.restart_interval; + Inc(entropy^.next_restart_num); + with entropy^ do + next_restart_num := next_restart_num and 7; + end; + Dec(entropy^.restarts_to_go); + end; + + encode_mcu_AC_first := TRUE; +end; + + +{ MCU encoding for DC successive approximation refinement scan. + Note: we assume such scans can be multi-component, although the spec + is not very clear on the point. } + +{METHODDEF} +function encode_mcu_DC_refine (cinfo : j_compress_ptr; + const MCU_data: array of JBLOCKROW) : boolean; +var + entropy : phuff_entropy_ptr; + {register} temp : int; + blkn : int; + Al : int; + block : JBLOCK_PTR; +begin + entropy := phuff_entropy_ptr (cinfo^.entropy); + Al := cinfo^.Al; + + entropy^.next_output_byte := cinfo^.dest^.next_output_byte; + entropy^.free_in_buffer := cinfo^.dest^.free_in_buffer; + + { Emit restart marker if needed } + if (cinfo^.restart_interval <> 0) then + if (entropy^.restarts_to_go = 0) then + emit_restart(entropy, entropy^.next_restart_num); + + { Encode the MCU data blocks } + for blkn := 0 to pred(cinfo^.blocks_in_MCU) do + begin + block := JBLOCK_PTR(MCU_data[blkn]); + + { We simply emit the Al'th bit of the DC coefficient value. } + temp := block^[0]; + emit_bits(entropy, uInt(temp shr Al), 1); + end; + + cinfo^.dest^.next_output_byte := entropy^.next_output_byte; + cinfo^.dest^.free_in_buffer := entropy^.free_in_buffer; + + { Update restart-interval state too } + if (cinfo^.restart_interval <> 0) then + begin + if (entropy^.restarts_to_go = 0) then + begin + entropy^.restarts_to_go := cinfo^.restart_interval; + Inc(entropy^.next_restart_num); + with entropy^ do + next_restart_num := next_restart_num and 7; + end; + Dec(entropy^.restarts_to_go); + end; + + encode_mcu_DC_refine := TRUE; +end; + + +{ MCU encoding for AC successive approximation refinement scan. } + +{METHODDEF} +function encode_mcu_AC_refine (cinfo : j_compress_ptr; + const MCU_data: array of JBLOCKROW) : boolean; + +var + entropy : phuff_entropy_ptr; + {register} temp : int; + {register} r, k : int; + EOB : int; + BR_buffer : JBytePtr; + BR : uInt; + Se : int; + Al : int; + block : JBLOCK_PTR; + absvalues : array[0..DCTSIZE2-1] of int; +begin + entropy := phuff_entropy_ptr(cinfo^.entropy); + Se := cinfo^.Se; + Al := cinfo^.Al; + + entropy^.next_output_byte := cinfo^.dest^.next_output_byte; + entropy^.free_in_buffer := cinfo^.dest^.free_in_buffer; + + { Emit restart marker if needed } + if (cinfo^.restart_interval <> 0) then + if (entropy^.restarts_to_go = 0) then + emit_restart(entropy, entropy^.next_restart_num); + + { Encode the MCU data block } + block := JBLOCK_PTR(MCU_data[0]); + + { It is convenient to make a pre-pass to determine the transformed + coefficients' absolute values and the EOB position. } + + EOB := 0; + for k := cinfo^.Ss to Se do + begin + temp := block^[jpeg_natural_order[k]]; + { We must apply the point transform by Al. For AC coefficients this + is an integer division with rounding towards 0. To do this portably + in C, we shift after obtaining the absolute value. } + + if (temp < 0) then + temp := -temp; { temp is abs value of input } + temp := temp shr Al; { apply the point transform } + absvalues[k] := temp; { save abs value for main pass } + if (temp = 1) then + EOB := k; { EOB := index of last newly-nonzero coef } + end; + + { Encode the AC coefficients per section G.1.2.3, fig. G.7 } + + r := 0; { r := run length of zeros } + BR := 0; { BR := count of buffered bits added now } + BR_buffer := JBytePtr(@(entropy^.bit_buffer^[entropy^.BE])); + { Append bits to buffer } + + for k := cinfo^.Ss to Se do + begin + temp := absvalues[k]; + if (temp = 0) then + begin + Inc(r); + continue; + end; + + { Emit any required ZRLs, but not if they can be folded into EOB } + while (r > 15) and (k <= EOB) do + begin + { emit any pending EOBRUN and the BE correction bits } + emit_eobrun(entropy); + { Emit ZRL } + emit_symbol(entropy, entropy^.ac_tbl_no, $F0); + Dec(r, 16); + { Emit buffered correction bits that must be associated with ZRL } + emit_buffered_bits(entropy, BR_buffer, BR); + BR_buffer := entropy^.bit_buffer; { BE bits are gone now } + BR := 0; + end; + + { If the coef was previously nonzero, it only needs a correction bit. + NOTE: a straight translation of the spec's figure G.7 would suggest + that we also need to test r > 15. But if r > 15, we can only get here + if k > EOB, which implies that this coefficient is not 1. } + if (temp > 1) then + begin + { The correction bit is the next bit of the absolute value. } + BR_buffer^[BR] := byte (temp and 1); + Inc(BR); + continue; + end; + + { Emit any pending EOBRUN and the BE correction bits } + emit_eobrun(entropy); + + { Count/emit Huffman symbol for run length / number of bits } + emit_symbol(entropy, entropy^.ac_tbl_no, (r shl 4) + 1); + + { Emit output bit for newly-nonzero coef } + if (block^[jpeg_natural_order[k]] < 0) then + temp := 0 + else + temp := 1; + emit_bits(entropy, uInt(temp), 1); + + { Emit buffered correction bits that must be associated with this code } + emit_buffered_bits(entropy, BR_buffer, BR); + BR_buffer := entropy^.bit_buffer; { BE bits are gone now } + BR := 0; + r := 0; { reset zero run length } + end; + + if (r > 0) or (BR > 0) then + begin { If there are trailing zeroes, } + Inc(entropy^.EOBRUN); { count an EOB } + Inc(entropy^.BE, BR); { concat my correction bits to older ones } + { We force out the EOB if we risk either: + 1. overflow of the EOB counter; + 2. overflow of the correction bit buffer during the next MCU. } + + if (entropy^.EOBRUN = $7FFF) or + (entropy^.BE > (MAX_CORR_BITS-DCTSIZE2+1)) then + emit_eobrun(entropy); + end; + + cinfo^.dest^.next_output_byte := entropy^.next_output_byte; + cinfo^.dest^.free_in_buffer := entropy^.free_in_buffer; + + { Update restart-interval state too } + if (cinfo^.restart_interval <> 0) then + begin + if (entropy^.restarts_to_go = 0) then + begin + entropy^.restarts_to_go := cinfo^.restart_interval; + Inc(entropy^.next_restart_num); + with entropy^ do + next_restart_num := next_restart_num and 7; + end; + Dec(entropy^.restarts_to_go); + end; + + encode_mcu_AC_refine := TRUE; +end; + + +{ Finish up at the end of a Huffman-compressed progressive scan. } + +{METHODDEF} +procedure finish_pass_phuff (cinfo : j_compress_ptr); +var + entropy : phuff_entropy_ptr; +begin + entropy := phuff_entropy_ptr (cinfo^.entropy); + + entropy^.next_output_byte := cinfo^.dest^.next_output_byte; + entropy^.free_in_buffer := cinfo^.dest^.free_in_buffer; + + { Flush out any buffered data } + emit_eobrun(entropy); + flush_bits(entropy); + + cinfo^.dest^.next_output_byte := entropy^.next_output_byte; + cinfo^.dest^.free_in_buffer := entropy^.free_in_buffer; +end; + + +{ Finish up a statistics-gathering pass and create the new Huffman tables. } + +{METHODDEF} +procedure finish_pass_gather_phuff (cinfo : j_compress_ptr); +var + entropy : phuff_entropy_ptr; + is_DC_band : boolean; + ci, tbl : int; + compptr : jpeg_component_info_ptr; + htblptr : ^JHUFF_TBL_PTR; + did : array[0..NUM_HUFF_TBLS-1] of boolean; +begin + entropy := phuff_entropy_ptr (cinfo^.entropy); + + { Flush out buffered data (all we care about is counting the EOB symbol) } + emit_eobrun(entropy); + + is_DC_band := (cinfo^.Ss = 0); + + { It's important not to apply jpeg_gen_optimal_table more than once + per table, because it clobbers the input frequency counts! } + + MEMZERO(@did, SIZEOF(did)); + + for ci := 0 to pred(cinfo^.comps_in_scan) do + begin + compptr := cinfo^.cur_comp_info[ci]; + if (is_DC_band) then + begin + if (cinfo^.Ah <> 0) then { DC refinement needs no table } + continue; + tbl := compptr^.dc_tbl_no; + end + else + begin + tbl := compptr^.ac_tbl_no; + end; + if (not did[tbl]) then + begin + if (is_DC_band) then + htblptr := @(cinfo^.dc_huff_tbl_ptrs[tbl]) + else + htblptr := @(cinfo^.ac_huff_tbl_ptrs[tbl]); + if (htblptr^ = NIL) then + htblptr^ := jpeg_alloc_huff_table(j_common_ptr(cinfo)); + jpeg_gen_optimal_table(cinfo, htblptr^, entropy^.count_ptrs[tbl]^); + did[tbl] := TRUE; + end; + end; +end; + + +{ Module initialization routine for progressive Huffman entropy encoding. } + +{GLOBAL} +procedure jinit_phuff_encoder (cinfo : j_compress_ptr); +var + entropy : phuff_entropy_ptr; + i : int; +begin + entropy := phuff_entropy_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(phuff_entropy_encoder)) ); + cinfo^.entropy := jpeg_entropy_encoder_ptr(entropy); + entropy^.pub.start_pass := start_pass_phuff; + + { Mark tables unallocated } + for i := 0 to pred(NUM_HUFF_TBLS) do + begin + entropy^.derived_tbls[i] := NIL; + entropy^.count_ptrs[i] := NIL; + end; + entropy^.bit_buffer := NIL; { needed only in AC refinement scan } +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jcprepct_del.pas b/mseide-msegui/lib/common/fpccompatibility/jcprepct_del.pas new file mode 100644 index 0000000..67ec625 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jcprepct_del.pas @@ -0,0 +1,408 @@ +Unit jcprepct_del; + +{ Original : jcprepct.c ; Copyright (C) 1994-1996, Thomas G. Lane. } + +{ This file contains the compression preprocessing controller. + This controller manages the color conversion, downsampling, + and edge expansion steps. + + Most of the complexity here is associated with buffering input rows + as required by the downsampler. See the comments at the head of + jcsample.c for the downsampler's needs. } + +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jpeglib_del, + jdeferr_del, + jerror_del, + jinclude_del, + jutils_del; + +{GLOBAL} +procedure jinit_c_prep_controller (cinfo : j_compress_ptr; + need_full_buffer : boolean); + +implementation + + +{ At present, jcsample.c can request context rows only for smoothing. + In the future, we might also need context rows for CCIR601 sampling + or other more-complex downsampling procedures. The code to support + context rows should be compiled only if needed. } + +{$ifdef INPUT_SMOOTHING_SUPPORTED} + {$define CONTEXT_ROWS_SUPPORTED} +{$endif} + + +{ For the simple (no-context-row) case, we just need to buffer one + row group's worth of pixels for the downsampling step. At the bottom of + the image, we pad to a full row group by replicating the last pixel row. + The downsampler's last output row is then replicated if needed to pad + out to a full iMCU row. + + When providing context rows, we must buffer three row groups' worth of + pixels. Three row groups are physically allocated, but the row pointer + arrays are made five row groups high, with the extra pointers above and + below "wrapping around" to point to the last and first real row groups. + This allows the downsampler to access the proper context rows. + At the top and bottom of the image, we create dummy context rows by + copying the first or last real pixel row. This copying could be avoided + by pointer hacking as is done in jdmainct.c, but it doesn't seem worth the + trouble on the compression side. } + + +{ Private buffer controller object } + +type + my_prep_ptr = ^my_prep_controller; + my_prep_controller = record + pub : jpeg_c_prep_controller; { public fields } + + { Downsampling input buffer. This buffer holds color-converted data + until we have enough to do a downsample step. } + + color_buf : array[0..MAX_COMPONENTS-1] of JSAMPARRAY; + + rows_to_go : JDIMENSION; { counts rows remaining in source image } + next_buf_row : int; { index of next row to store in color_buf } + + {$ifdef CONTEXT_ROWS_SUPPORTED} { only needed for context case } + this_row_group : int; { starting row index of group to process } + next_buf_stop : int; { downsample when we reach this index } + {$endif} + end; {my_prep_controller;} + + +{ Initialize for a processing pass. } + +{METHODDEF} +procedure start_pass_prep (cinfo : j_compress_ptr; + pass_mode : J_BUF_MODE ); +var + prep : my_prep_ptr; +begin + prep := my_prep_ptr (cinfo^.prep); + + if (pass_mode <> JBUF_PASS_THRU) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE); + + { Initialize total-height counter for detecting bottom of image } + prep^.rows_to_go := cinfo^.image_height; + { Mark the conversion buffer empty } + prep^.next_buf_row := 0; +{$ifdef CONTEXT_ROWS_SUPPORTED} + { Preset additional state variables for context mode. + These aren't used in non-context mode, so we needn't test which mode. } + prep^.this_row_group := 0; + { Set next_buf_stop to stop after two row groups have been read in. } + prep^.next_buf_stop := 2 * cinfo^.max_v_samp_factor; +{$endif} +end; + + +{ Expand an image vertically from height input_rows to height output_rows, + by duplicating the bottom row. } + +{LOCAL} +procedure expand_bottom_edge (image_data : JSAMPARRAY; + num_cols : JDIMENSION; + input_rows : int; + output_rows : int); +var + {register} row : int; +begin + for row := input_rows to pred(output_rows) do + begin + jcopy_sample_rows(image_data, input_rows-1, image_data, row, + 1, num_cols); + end; +end; + + +{ Process some data in the simple no-context case. + + Preprocessor output data is counted in "row groups". A row group + is defined to be v_samp_factor sample rows of each component. + Downsampling will produce this much data from each max_v_samp_factor + input rows. } + +{METHODDEF} +procedure pre_process_data (cinfo : j_compress_ptr; + input_buf : JSAMPARRAY; + var in_row_ctr : JDIMENSION; + in_rows_avail : JDIMENSION; + output_buf : JSAMPIMAGE; + var out_row_group_ctr : JDIMENSION; + out_row_groups_avail : JDIMENSION); +var + prep : my_prep_ptr; + numrows, ci : int; + inrows : JDIMENSION; + compptr : jpeg_component_info_ptr; +var + local_input_buf : JSAMPARRAY; +begin + prep := my_prep_ptr (cinfo^.prep); + + while (in_row_ctr < in_rows_avail) and + (out_row_group_ctr < out_row_groups_avail) do + begin + { Do color conversion to fill the conversion buffer. } + inrows := in_rows_avail - in_row_ctr; + numrows := cinfo^.max_v_samp_factor - prep^.next_buf_row; + {numrows := int( MIN(JDIMENSION(numrows), inrows) );} + if inrows < JDIMENSION(numrows) then + numrows := int(inrows); + local_input_buf := JSAMPARRAY(@(input_buf^[in_row_ctr])); + cinfo^.cconvert^.color_convert (cinfo, local_input_buf, + JSAMPIMAGE(@prep^.color_buf), + JDIMENSION(prep^.next_buf_row), + numrows); + Inc(in_row_ctr, numrows); + Inc(prep^.next_buf_row, numrows); + Dec(prep^.rows_to_go, numrows); + { If at bottom of image, pad to fill the conversion buffer. } + if (prep^.rows_to_go = 0) and + (prep^.next_buf_row < cinfo^.max_v_samp_factor) then + begin + for ci := 0 to pred(cinfo^.num_components) do + begin + expand_bottom_edge(prep^.color_buf[ci], cinfo^.image_width, + prep^.next_buf_row, cinfo^.max_v_samp_factor); + end; + prep^.next_buf_row := cinfo^.max_v_samp_factor; + end; + { If we've filled the conversion buffer, empty it. } + if (prep^.next_buf_row = cinfo^.max_v_samp_factor) then + begin + cinfo^.downsample^.downsample (cinfo, + JSAMPIMAGE(@prep^.color_buf), + JDIMENSION (0), + output_buf, + out_row_group_ctr); + prep^.next_buf_row := 0; + Inc(out_row_group_ctr);; + end; + { If at bottom of image, pad the output to a full iMCU height. + Note we assume the caller is providing a one-iMCU-height output buffer! } + if (prep^.rows_to_go = 0) and + (out_row_group_ctr < out_row_groups_avail) then + begin + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + expand_bottom_edge(output_buf^[ci], + compptr^.width_in_blocks * DCTSIZE, + int (out_row_group_ctr * compptr^.v_samp_factor), + int (out_row_groups_avail * compptr^.v_samp_factor)); + Inc(compptr); + end; + out_row_group_ctr := out_row_groups_avail; + break; { can exit outer loop without test } + end; + end; +end; + + +{$ifdef CONTEXT_ROWS_SUPPORTED} + +{ Process some data in the context case. } + +{METHODDEF} +procedure pre_process_context (cinfo : j_compress_ptr; + input_buf : JSAMPARRAY; + var in_row_ctr : JDIMENSION; + in_rows_avail : JDIMENSION; + output_buf : JSAMPIMAGE; + var out_row_group_ctr : JDIMENSION; + out_row_groups_avail : JDIMENSION); +var + prep : my_prep_ptr; + numrows, ci : int; + buf_height : int; + inrows : JDIMENSION; +var + row : int; + +begin + prep := my_prep_ptr (cinfo^.prep); + buf_height := cinfo^.max_v_samp_factor * 3; + + while (out_row_group_ctr < out_row_groups_avail) do + begin + if (in_row_ctr < in_rows_avail) then + begin + { Do color conversion to fill the conversion buffer. } + inrows := in_rows_avail - in_row_ctr; + numrows := prep^.next_buf_stop - prep^.next_buf_row; + {numrows := int ( MIN( JDIMENSION(numrows), inrows) );} + if inrows < JDIMENSION(numrows) then + numrows := int(inrows); + cinfo^.cconvert^.color_convert (cinfo, + JSAMPARRAY(@input_buf^[in_row_ctr]), + JSAMPIMAGE(@prep^.color_buf), + JDIMENSION (prep^.next_buf_row), + numrows); + { Pad at top of image, if first time through } + if (prep^.rows_to_go = cinfo^.image_height) then + begin + for ci := 0 to pred(cinfo^.num_components) do + begin + for row := 1 to cinfo^.max_v_samp_factor do + begin + jcopy_sample_rows(prep^.color_buf[ci], 0, + prep^.color_buf[ci], -row, + 1, cinfo^.image_width); + end; + end; + end; + Inc(in_row_ctr, numrows); + Inc(prep^.next_buf_row, numrows); + Dec(prep^.rows_to_go, numrows); + end + else + begin + { Return for more data, unless we are at the bottom of the image. } + if (prep^.rows_to_go <> 0) then + break; + { When at bottom of image, pad to fill the conversion buffer. } + if (prep^.next_buf_row < prep^.next_buf_stop) then + begin + for ci := 0 to pred(cinfo^.num_components) do + begin + expand_bottom_edge(prep^.color_buf[ci], cinfo^.image_width, + prep^.next_buf_row, prep^.next_buf_stop); + end; + prep^.next_buf_row := prep^.next_buf_stop; + end; + end; + { If we've gotten enough data, downsample a row group. } + if (prep^.next_buf_row = prep^.next_buf_stop) then + begin + cinfo^.downsample^.downsample (cinfo, + JSAMPIMAGE(@prep^.color_buf), + JDIMENSION(prep^.this_row_group), + output_buf, + out_row_group_ctr); + Inc(out_row_group_ctr); + { Advance pointers with wraparound as necessary. } + Inc(prep^.this_row_group, cinfo^.max_v_samp_factor); + if (prep^.this_row_group >= buf_height) then + prep^.this_row_group := 0; + if (prep^.next_buf_row >= buf_height) then + prep^.next_buf_row := 0; + prep^.next_buf_stop := prep^.next_buf_row + cinfo^.max_v_samp_factor; + end; + end; +end; + + +{ Create the wrapped-around downsampling input buffer needed for context mode. } + +{LOCAL} +procedure create_context_buffer (cinfo : j_compress_ptr); +var + prep : my_prep_ptr; + rgroup_height : int; + ci, i : int; + compptr : jpeg_component_info_ptr; + true_buffer, fake_buffer : JSAMPARRAY; +begin + prep := my_prep_ptr (cinfo^.prep); + rgroup_height := cinfo^.max_v_samp_factor; + { Grab enough space for fake row pointers for all the components; + we need five row groups' worth of pointers for each component. } + + fake_buffer := JSAMPARRAY( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + (cinfo^.num_components * 5 * rgroup_height) * + SIZEOF(JSAMPROW)) ); + + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + { Allocate the actual buffer space (3 row groups) for this component. + We make the buffer wide enough to allow the downsampler to edge-expand + horizontally within the buffer, if it so chooses. } + true_buffer := cinfo^.mem^.alloc_sarray + (j_common_ptr(cinfo), JPOOL_IMAGE, + JDIMENSION (( long(compptr^.width_in_blocks) * DCTSIZE * + cinfo^.max_h_samp_factor) div compptr^.h_samp_factor), + JDIMENSION (3 * rgroup_height)); + { Copy true buffer row pointers into the middle of the fake row array } + MEMCOPY(JSAMPARRAY(@ fake_buffer^[rgroup_height]), true_buffer, + 3 * rgroup_height * SIZEOF(JSAMPROW)); + { Fill in the above and below wraparound pointers } + for i := 0 to pred(rgroup_height) do + begin + fake_buffer^[i] := true_buffer^[2 * rgroup_height + i]; + fake_buffer^[4 * rgroup_height + i] := true_buffer^[i]; + end; + prep^.color_buf[ci] := JSAMPARRAY(@ fake_buffer^[rgroup_height]); + Inc(JSAMPROW_PTR(fake_buffer), 5 * rgroup_height); { point to space for next component } + Inc(compptr); + end; +end; + +{$endif} { CONTEXT_ROWS_SUPPORTED } + + +{ Initialize preprocessing controller. } + +{GLOBAL} +procedure jinit_c_prep_controller (cinfo : j_compress_ptr; + need_full_buffer : boolean); +var + prep : my_prep_ptr; + ci : int; + compptr : jpeg_component_info_ptr; +begin + + if (need_full_buffer) then { safety check } + ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE); + + prep := my_prep_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(my_prep_controller)) ); + cinfo^.prep := jpeg_c_prep_controller_ptr(prep); + prep^.pub.start_pass := start_pass_prep; + + { Allocate the color conversion buffer. + We make the buffer wide enough to allow the downsampler to edge-expand + horizontally within the buffer, if it so chooses. } + + if (cinfo^.downsample^.need_context_rows) then + begin + { Set up to provide context rows } +{$ifdef CONTEXT_ROWS_SUPPORTED} + prep^.pub.pre_process_data := pre_process_context; + create_context_buffer(cinfo); +{$else} + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); +{$endif} + end + else + begin + { No context, just make it tall enough for one row group } + prep^.pub.pre_process_data := pre_process_data; + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + prep^.color_buf[ci] := cinfo^.mem^.alloc_sarray + (j_common_ptr(cinfo), JPOOL_IMAGE, + JDIMENSION (( long(compptr^.width_in_blocks) * DCTSIZE * + cinfo^.max_h_samp_factor) div compptr^.h_samp_factor), + JDIMENSION(cinfo^.max_v_samp_factor) ); + Inc(compptr); + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jcsample_del.pas b/mseide-msegui/lib/common/fpccompatibility/jcsample_del.pas new file mode 100644 index 0000000..1ae9b6c --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jcsample_del.pas @@ -0,0 +1,632 @@ +Unit jcsample_del; + +{ This file contains downsampling routines. + + Downsampling input data is counted in "row groups". A row group + is defined to be max_v_samp_factor pixel rows of each component, + from which the downsampler produces v_samp_factor sample rows. + A single row group is processed in each call to the downsampler module. + + The downsampler is responsible for edge-expansion of its output data + to fill an integral number of DCT blocks horizontally. The source buffer + may be modified if it is helpful for this purpose (the source buffer is + allocated wide enough to correspond to the desired output width). + The caller (the prep controller) is responsible for vertical padding. + + The downsampler may request "context rows" by setting need_context_rows + during startup. In this case, the input arrays will contain at least + one row group's worth of pixels above and below the passed-in data; + the caller will create dummy rows at image top and bottom by replicating + the first or last real pixel row. + + An excellent reference for image resampling is + Digital Image Warping, George Wolberg, 1990. + Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7. + + The downsampling algorithm used here is a simple average of the source + pixels covered by the output pixel. The hi-falutin sampling literature + refers to this as a "box filter". In general the characteristics of a box + filter are not very good, but for the specific cases we normally use (1:1 + and 2:1 ratios) the box is equivalent to a "triangle filter" which is not + nearly so bad. If you intend to use other sampling ratios, you'd be well + advised to improve this code. + + A simple input-smoothing capability is provided. This is mainly intended + for cleaning up color-dithered GIF input files (if you find it inadequate, + we suggest using an external filtering program such as pnmconvol). When + enabled, each input pixel P is replaced by a weighted sum of itself and its + eight neighbors. P's weight is 1-8*SF and each neighbor's weight is SF, + where SF := (smoothing_factor / 1024). + Currently, smoothing is only supported for 2h2v sampling factors. } + +{ Original: jcsample.c ; Copyright (C) 1991-1996, Thomas G. Lane. } + +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jutils_del, + jdeferr_del, + jerror_del, + jpeglib_del; + + +{ Module initialization routine for downsampling. + Note that we must select a routine for each component. } + +{GLOBAL} +procedure jinit_downsampler (cinfo : j_compress_ptr); + +implementation + +{ Pointer to routine to downsample a single component } +type + downsample1_ptr = procedure(cinfo : j_compress_ptr; + compptr : jpeg_component_info_ptr; + input_data : JSAMPARRAY; + output_data : JSAMPARRAY); + +{ Private subobject } + +type + my_downsample_ptr = ^my_downsampler; + my_downsampler = record + pub : jpeg_downsampler; { public fields } + + { Downsampling method pointers, one per component } + methods : array[0..MAX_COMPONENTS-1] of downsample1_ptr; + end; + +{ Initialize for a downsampling pass. } + +{METHODDEF} +procedure start_pass_downsample (cinfo : j_compress_ptr); +begin + { no work for now } +end; + + +{ Expand a component horizontally from width input_cols to width output_cols, + by duplicating the rightmost samples. } + +{LOCAL} +procedure expand_right_edge (image_data : JSAMPARRAY; + num_rows : int; + input_cols : JDIMENSION; + output_cols : JDIMENSION); +var + {register} ptr : JSAMPLE_PTR; + {register} pixval : JSAMPLE; + {register} count : int; + row : int; + numcols : int; +begin + numcols := int (output_cols - input_cols); + + if (numcols > 0) then + begin + for row := 0 to pred(num_rows) do + begin + ptr := JSAMPLE_PTR(@(image_data^[row]^[input_cols-1])); + pixval := ptr^; { don't need GETJSAMPLE() here } + for count := pred(numcols) downto 0 do + begin + Inc(ptr); + ptr^ := pixval; + end; + end; + end; +end; + + +{ Do downsampling for a whole row group (all components). + + In this version we simply downsample each component independently. } + +{METHODDEF} +procedure sep_downsample (cinfo : j_compress_ptr; + input_buf : JSAMPIMAGE; + in_row_index : JDIMENSION; + output_buf : JSAMPIMAGE; + out_row_group_index : JDIMENSION); +var + downsample : my_downsample_ptr; + ci : int; + compptr : jpeg_component_info_ptr; + in_ptr, out_ptr : JSAMPARRAY; +begin + downsample := my_downsample_ptr (cinfo^.downsample); + + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + in_ptr := JSAMPARRAY(@ input_buf^[ci]^[in_row_index]); + out_ptr := JSAMPARRAY(@ output_buf^[ci]^ + [out_row_group_index * compptr^.v_samp_factor]); + downsample^.methods[ci] (cinfo, compptr, in_ptr, out_ptr); + Inc(compptr); + end; +end; + + +{ Downsample pixel values of a single component. + One row group is processed per call. + This version handles arbitrary integral sampling ratios, without smoothing. + Note that this version is not actually used for customary sampling ratios. } + +{METHODDEF} +procedure int_downsample (cinfo : j_compress_ptr; + compptr : jpeg_component_info_ptr; + input_data : JSAMPARRAY; + output_data : JSAMPARRAY); +var + inrow, outrow, h_expand, v_expand, numpix, numpix2, h, v : int; + outcol, outcol_h : JDIMENSION; { outcol_h = outcol*h_expand } + output_cols : JDIMENSION; + inptr, + outptr : JSAMPLE_PTR; + outvalue : INT32; +begin + output_cols := compptr^.width_in_blocks * DCTSIZE; + + h_expand := cinfo^.max_h_samp_factor div compptr^.h_samp_factor; + v_expand := cinfo^.max_v_samp_factor div compptr^.v_samp_factor; + numpix := h_expand * v_expand; + numpix2 := numpix div 2; + + { Expand input data enough to let all the output samples be generated + by the standard loop. Special-casing padded output would be more + efficient. } + + expand_right_edge(input_data, cinfo^.max_v_samp_factor, + cinfo^.image_width, output_cols * h_expand); + + inrow := 0; + for outrow := 0 to pred(compptr^.v_samp_factor) do + begin + outptr := JSAMPLE_PTR(output_data^[outrow]); + outcol_h := 0; + for outcol := 0 to pred(output_cols) do + begin + outvalue := 0; + for v := 0 to pred(v_expand) do + begin + inptr := @(input_data^[inrow+v]^[outcol_h]); + for h := 0 to pred(h_expand) do + begin + Inc(outvalue, INT32 (GETJSAMPLE(inptr^)) ); + Inc(inptr); + end; + end; + outptr^ := JSAMPLE ((outvalue + numpix2) div numpix); + Inc(outptr); + Inc(outcol_h, h_expand); + end; + Inc(inrow, v_expand); + end; +end; + + +{ Downsample pixel values of a single component. + This version handles the special case of a full-size component, + without smoothing. } + +{METHODDEF} +procedure fullsize_downsample (cinfo : j_compress_ptr; + compptr : jpeg_component_info_ptr; + input_data : JSAMPARRAY; + output_data : JSAMPARRAY); +begin + { Copy the data } + jcopy_sample_rows(input_data, 0, output_data, 0, + cinfo^.max_v_samp_factor, cinfo^.image_width); + { Edge-expand } + expand_right_edge(output_data, cinfo^.max_v_samp_factor, + cinfo^.image_width, compptr^.width_in_blocks * DCTSIZE); +end; + + +{ Downsample pixel values of a single component. + This version handles the common case of 2:1 horizontal and 1:1 vertical, + without smoothing. + + A note about the "bias" calculations: when rounding fractional values to + integer, we do not want to always round 0.5 up to the next integer. + If we did that, we'd introduce a noticeable bias towards larger values. + Instead, this code is arranged so that 0.5 will be rounded up or down at + alternate pixel locations (a simple ordered dither pattern). } + +{METHODDEF} +procedure h2v1_downsample (cinfo : j_compress_ptr; + compptr : jpeg_component_info_ptr; + input_data : JSAMPARRAY; + output_data : JSAMPARRAY); +var + outrow : int; + outcol : JDIMENSION; + output_cols : JDIMENSION; + {register} inptr, outptr : JSAMPLE_PTR; + {register} bias : int; +begin + output_cols := compptr^.width_in_blocks * DCTSIZE; + + { Expand input data enough to let all the output samples be generated + by the standard loop. Special-casing padded output would be more + efficient. } + + expand_right_edge(input_data, cinfo^.max_v_samp_factor, + cinfo^.image_width, output_cols * 2); + + for outrow := 0 to pred(compptr^.v_samp_factor) do + begin + outptr := JSAMPLE_PTR(output_data^[outrow]); + inptr := JSAMPLE_PTR(input_data^[outrow]); + bias := 0; { bias := 0,1,0,1,... for successive samples } + for outcol := 0 to pred(output_cols) do + begin + outptr^ := JSAMPLE ((GETJSAMPLE(inptr^) + + GETJSAMPLE(JSAMPROW(inptr)^[1]) + bias) shr 1); + Inc(outptr); + bias := bias xor 1; { 0=>1, 1=>0 } + Inc(inptr, 2); + end; + end; +end; + + +{ Downsample pixel values of a single component. + This version handles the standard case of 2:1 horizontal and 2:1 vertical, + without smoothing. } + +{METHODDEF} +procedure h2v2_downsample (cinfo : j_compress_ptr; + compptr : jpeg_component_info_ptr; + input_data : JSAMPARRAY; + output_data : JSAMPARRAY); +var + inrow, outrow : int; + outcol : JDIMENSION; + output_cols : JDIMENSION; + {register} inptr0, inptr1, outptr : JSAMPLE_PTR; + {register} bias : int; +begin + output_cols := compptr^.width_in_blocks * DCTSIZE; + + { Expand input data enough to let all the output samples be generated + by the standard loop. Special-casing padded output would be more + efficient. } + + expand_right_edge(input_data, cinfo^.max_v_samp_factor, + cinfo^.image_width, output_cols * 2); + + inrow := 0; + for outrow := 0 to pred(compptr^.v_samp_factor) do + begin + outptr := JSAMPLE_PTR(output_data^[outrow]); + inptr0 := JSAMPLE_PTR(input_data^[inrow]); + inptr1 := JSAMPLE_PTR(input_data^[inrow+1]); + bias := 1; { bias := 1,2,1,2,... for successive samples } + for outcol := 0 to pred(output_cols) do + begin + outptr^ := JSAMPLE ((GETJSAMPLE(inptr0^) + + GETJSAMPLE(JSAMPROW(inptr0)^[1]) + + GETJSAMPLE(inptr1^) + + GETJSAMPLE(JSAMPROW(inptr1)^[1]) + bias) shr 2); + Inc(outptr); + bias := bias xor 3; { 1=>2, 2=>1 } + Inc(inptr0, 2); + Inc(inptr1, 2); + end; + Inc(inrow, 2); + end; +end; + + +{$ifdef INPUT_SMOOTHING_SUPPORTED} + +{ Downsample pixel values of a single component. + This version handles the standard case of 2:1 horizontal and 2:1 vertical, + with smoothing. One row of context is required. } + +{METHODDEF} +procedure h2v2_smooth_downsample (cinfo : j_compress_ptr; + compptr : jpeg_component_info_ptr; + input_data : JSAMPARRAY; + output_data : JSAMPARRAY); +var + inrow, outrow : int; + colctr : JDIMENSION; + output_cols : JDIMENSION; + {register} inptr0, inptr1, above_ptr, below_ptr, outptr : JSAMPLE_PTR; + membersum, neighsum, memberscale, neighscale : INT32; +var + prev_input_data : JSAMPARRAY; + prev_inptr0, prev_inptr1, prev_above_ptr, prev_below_ptr : JSAMPLE_PTR; +begin + output_cols := compptr^.width_in_blocks * DCTSIZE; + + { Expand input data enough to let all the output samples be generated + by the standard loop. Special-casing padded output would be more + efficient. } + + prev_input_data := input_data; + Dec(JSAMPROW_PTR(prev_input_data)); + expand_right_edge(prev_input_data, cinfo^.max_v_samp_factor + 2, + cinfo^.image_width, output_cols * 2); + + { We don't bother to form the individual "smoothed" input pixel values; + we can directly compute the output which is the average of the four + smoothed values. Each of the four member pixels contributes a fraction + (1-8*SF) to its own smoothed image and a fraction SF to each of the three + other smoothed pixels, therefore a total fraction (1-5*SF)/4 to the final + output. The four corner-adjacent neighbor pixels contribute a fraction + SF to just one smoothed pixel, or SF/4 to the final output; while the + eight edge-adjacent neighbors contribute SF to each of two smoothed + pixels, or SF/2 overall. In order to use integer arithmetic, these + factors are scaled by 2^16 := 65536. + Also recall that SF := smoothing_factor / 1024. } + + memberscale := 16384 - cinfo^.smoothing_factor * 80; { scaled (1-5*SF)/4 } + neighscale := cinfo^.smoothing_factor * 16; { scaled SF/4 } + + inrow := 0; + for outrow := 0 to pred(compptr^.v_samp_factor) do + begin + outptr := JSAMPLE_PTR(output_data^[outrow]); + inptr0 := JSAMPLE_PTR(input_data^[inrow]); + inptr1 := JSAMPLE_PTR(input_data^[inrow+1]); + above_ptr := JSAMPLE_PTR(input_data^[inrow-1]); + below_ptr := JSAMPLE_PTR(input_data^[inrow+2]); + + { Special case for first column: pretend column -1 is same as column 0 } + membersum := GETJSAMPLE(inptr0^) + GETJSAMPLE(JSAMPROW(inptr0)^[1]) + + GETJSAMPLE(inptr1^) + GETJSAMPLE(JSAMPROW(inptr1)^[1]); + neighsum := GETJSAMPLE(above_ptr^) + GETJSAMPLE(JSAMPROW(above_ptr)^[1]) + + GETJSAMPLE(below_ptr^) + GETJSAMPLE(JSAMPROW(below_ptr)^[1]) + + GETJSAMPLE(inptr0^) + GETJSAMPLE(JSAMPROW(inptr0)^[2]) + + GETJSAMPLE(inptr1^) + GETJSAMPLE(JSAMPROW(inptr1)^[2]); + Inc(neighsum, neighsum); + Inc(neighsum, GETJSAMPLE(above_ptr^) + + GETJSAMPLE(JSAMPROW(above_ptr)^[2]) + + GETJSAMPLE(below_ptr^) + + GETJSAMPLE(JSAMPROW(below_ptr)^[2]) ); + membersum := membersum * memberscale + neighsum * neighscale; + outptr^ := JSAMPLE ((membersum + 32768) shr 16); + Inc(outptr); + prev_inptr0 := inptr0; + prev_inptr1 := inptr1; + Inc(prev_inptr0); + Inc(prev_inptr1); + Inc(inptr0, 2); + Inc(inptr1, 2); + prev_above_ptr := above_ptr; + prev_below_ptr := below_ptr; + Inc(above_ptr, 2); + Inc(below_ptr, 2); + Inc(prev_above_ptr, 1); + Inc(prev_below_ptr, 1); + + for colctr := pred(output_cols - 2) downto 0 do + begin + { sum of pixels directly mapped to this output element } + membersum := GETJSAMPLE(inptr0^) + GETJSAMPLE(JSAMPROW(inptr0)^[1]) + + GETJSAMPLE(inptr1^) + GETJSAMPLE(JSAMPROW(inptr1)^[1]); + { sum of edge-neighbor pixels } + neighsum := GETJSAMPLE(above_ptr^) + GETJSAMPLE(JSAMPROW(above_ptr)^[1]) + + GETJSAMPLE(below_ptr^) + GETJSAMPLE(JSAMPROW(below_ptr)^[1]) + + GETJSAMPLE(prev_inptr0^) + GETJSAMPLE(JSAMPROW(inptr0)^[2]) + + GETJSAMPLE(prev_inptr1^) + GETJSAMPLE(JSAMPROW(inptr1)^[2]); + { The edge-neighbors count twice as much as corner-neighbors } + Inc(neighsum, neighsum); + { Add in the corner-neighbors } + Inc(neighsum, GETJSAMPLE(prev_above_ptr^) + + GETJSAMPLE(JSAMPROW(above_ptr)^[2]) + + GETJSAMPLE(prev_below_ptr^) + + GETJSAMPLE(JSAMPROW(below_ptr)^[2]) ); + { form final output scaled up by 2^16 } + membersum := membersum * memberscale + neighsum * neighscale; + { round, descale and output it } + outptr^ := JSAMPLE ((membersum + 32768) shr 16); + Inc(outptr); + Inc(inptr0, 2); + Inc(inptr1, 2); + Inc(prev_inptr0, 2); + Inc(prev_inptr1, 2); + Inc(above_ptr, 2); + Inc(below_ptr, 2); + Inc(prev_above_ptr, 2); + Inc(prev_below_ptr, 2); + end; + + { Special case for last column } + membersum := GETJSAMPLE(inptr0^) + GETJSAMPLE(JSAMPROW(inptr0)^[1]) + + GETJSAMPLE(inptr1^) + GETJSAMPLE(JSAMPROW(inptr1)^[1]); + neighsum := GETJSAMPLE(above_ptr^) + GETJSAMPLE(JSAMPROW(above_ptr)^[1]) + + GETJSAMPLE(below_ptr^) + GETJSAMPLE(JSAMPROW(below_ptr)^[1]) + + GETJSAMPLE(prev_inptr0^) + GETJSAMPLE(JSAMPROW(inptr0)^[1]) + + GETJSAMPLE(prev_inptr1^) + GETJSAMPLE(JSAMPROW(inptr1)^[1]); + Inc(neighsum, neighsum); + Inc(neighsum, GETJSAMPLE(prev_above_ptr^) + + GETJSAMPLE(JSAMPROW(above_ptr)^[1]) + + GETJSAMPLE(prev_below_ptr^) + + GETJSAMPLE(JSAMPROW(below_ptr)^[1]) ); + membersum := membersum * memberscale + neighsum * neighscale; + outptr^ := JSAMPLE ((membersum + 32768) shr 16); + + Inc(inrow, 2); + end; +end; + + +{ Downsample pixel values of a single component. + This version handles the special case of a full-size component, + with smoothing. One row of context is required. } + +{METHODDEF} +procedure fullsize_smooth_downsample (cinfo : j_compress_ptr; + compptr : jpeg_component_info_ptr; + input_data : JSAMPARRAY; + output_data : JSAMPARRAY); +var + outrow : int; + colctr : JDIMENSION; + output_cols : JDIMENSION; + {register} inptr, above_ptr, below_ptr, outptr : JSAMPLE_PTR; + membersum, neighsum, memberscale, neighscale : INT32; + colsum, lastcolsum, nextcolsum : int; +var + prev_input_data : JSAMPARRAY; +begin + output_cols := compptr^.width_in_blocks * DCTSIZE; + + { Expand input data enough to let all the output samples be generated + by the standard loop. Special-casing padded output would be more + efficient. } + + prev_input_data := input_data; + Dec(JSAMPROW_PTR(prev_input_data)); + expand_right_edge(prev_input_data, cinfo^.max_v_samp_factor + 2, + cinfo^.image_width, output_cols); + + { Each of the eight neighbor pixels contributes a fraction SF to the + smoothed pixel, while the main pixel contributes (1-8*SF). In order + to use integer arithmetic, these factors are multiplied by 2^16 := 65536. + Also recall that SF := smoothing_factor / 1024. } + + memberscale := long(65536) - cinfo^.smoothing_factor * long(512); { scaled 1-8*SF } + neighscale := cinfo^.smoothing_factor * 64; { scaled SF } + + for outrow := 0 to pred(compptr^.v_samp_factor) do + begin + outptr := JSAMPLE_PTR(output_data^[outrow]); + inptr := JSAMPLE_PTR(input_data^[outrow]); + above_ptr := JSAMPLE_PTR(input_data^[outrow-1]); + below_ptr := JSAMPLE_PTR(input_data^[outrow+1]); + + { Special case for first column } + colsum := GETJSAMPLE(above_ptr^) + GETJSAMPLE(below_ptr^) + + GETJSAMPLE(inptr^); + Inc(above_ptr); + Inc(below_ptr); + membersum := GETJSAMPLE(inptr^); + Inc(inptr); + nextcolsum := GETJSAMPLE(above_ptr^) + GETJSAMPLE(below_ptr^) + + GETJSAMPLE(inptr^); + neighsum := colsum + (colsum - membersum) + nextcolsum; + membersum := membersum * memberscale + neighsum * neighscale; + outptr^ := JSAMPLE ((membersum + 32768) shr 16); + Inc(outptr); + lastcolsum := colsum; colsum := nextcolsum; + + for colctr := pred(output_cols - 2) downto 0 do + begin + membersum := GETJSAMPLE(inptr^); + Inc(inptr); + Inc(above_ptr); + Inc(below_ptr); + nextcolsum := GETJSAMPLE(above_ptr^) + GETJSAMPLE(below_ptr^) + + GETJSAMPLE(inptr^); + neighsum := lastcolsum + (colsum - membersum) + nextcolsum; + membersum := membersum * memberscale + neighsum * neighscale; + outptr^ := JSAMPLE ((membersum + 32768) shr 16); + Inc(outptr); + lastcolsum := colsum; colsum := nextcolsum; + end; + + { Special case for last column } + membersum := GETJSAMPLE(inptr^); + neighsum := lastcolsum + (colsum - membersum) + colsum; + membersum := membersum * memberscale + neighsum * neighscale; + outptr^ := JSAMPLE ((membersum + 32768) shr 16); + end; +end; + +{$endif} { INPUT_SMOOTHING_SUPPORTED } + + +{ Module initialization routine for downsampling. + Note that we must select a routine for each component. } + +{GLOBAL} +procedure jinit_downsampler (cinfo : j_compress_ptr); +var + downsample : my_downsample_ptr; + ci : int; + compptr : jpeg_component_info_ptr; + smoothok : boolean; +begin + smoothok := TRUE; + + downsample := my_downsample_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(my_downsampler)) ); + cinfo^.downsample := jpeg_downsampler_ptr (downsample); + downsample^.pub.start_pass := start_pass_downsample; + downsample^.pub.downsample := sep_downsample; + downsample^.pub.need_context_rows := FALSE; + + if (cinfo^.CCIR601_sampling) then + ERREXIT(j_common_ptr(cinfo), JERR_CCIR601_NOTIMPL); + + { Verify we can handle the sampling factors, and set up method pointers } + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + if (compptr^.h_samp_factor = cinfo^.max_h_samp_factor) and + (compptr^.v_samp_factor = cinfo^.max_v_samp_factor) then + begin +{$ifdef INPUT_SMOOTHING_SUPPORTED} + if (cinfo^.smoothing_factor <> 0) then + begin + downsample^.methods[ci] := fullsize_smooth_downsample; + downsample^.pub.need_context_rows := TRUE; + end + else +{$endif} + downsample^.methods[ci] := fullsize_downsample; + end + else + if (compptr^.h_samp_factor * 2 = cinfo^.max_h_samp_factor) and + (compptr^.v_samp_factor = cinfo^.max_v_samp_factor) then + begin + smoothok := FALSE; + downsample^.methods[ci] := h2v1_downsample; + end + else + if (compptr^.h_samp_factor * 2 = cinfo^.max_h_samp_factor) and + (compptr^.v_samp_factor * 2 = cinfo^.max_v_samp_factor) then + begin + {$ifdef INPUT_SMOOTHING_SUPPORTED} + if (cinfo^.smoothing_factor <> 0) then + begin + downsample^.methods[ci] := h2v2_smooth_downsample; + downsample^.pub.need_context_rows := TRUE; + end + else + {$endif} + downsample^.methods[ci] := h2v2_downsample; + end + else + if ((cinfo^.max_h_samp_factor mod compptr^.h_samp_factor) = 0) and + ((cinfo^.max_v_samp_factor mod compptr^.v_samp_factor) = 0) then + begin + smoothok := FALSE; + downsample^.methods[ci] := int_downsample; + end + else + ERREXIT(j_common_ptr(cinfo), JERR_FRACT_SAMPLE_NOTIMPL); + Inc(compptr); + end; + +{$ifdef INPUT_SMOOTHING_SUPPORTED} + if (cinfo^.smoothing_factor <> 0) and (not smoothok) then + TRACEMS(j_common_ptr(cinfo), 0, JTRC_SMOOTH_NOTIMPL); +{$endif} +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jctrans_del.pas b/mseide-msegui/lib/common/fpccompatibility/jctrans_del.pas new file mode 100644 index 0000000..217649f --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jctrans_del.pas @@ -0,0 +1,459 @@ +Unit JcTrans; + +{ This file contains library routines for transcoding compression, + that is, writing raw DCT coefficient arrays to an output JPEG file. + The routines in jcapimin.c will also be needed by a transcoder. } + +{ Original : jctrans.c - Copyright (C) 1995-1998, Thomas G. Lane. } + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg, + jinclude, + jdeferr, + jerror, + jutils, + jpeglib, + jcapimin, jcparam, jcomapi, jcmaster, jchuff, jcphuff, jcmarker; + +{ Compression initialization for writing raw-coefficient data. + Before calling this, all parameters and a data destination must be set up. + Call jpeg_finish_compress() to actually write the data. + + The number of passed virtual arrays must match cinfo^.num_components. + Note that the virtual arrays need not be filled or even realized at + the time write_coefficients is called; indeed, if the virtual arrays + were requested from this compression object's memory manager, they + typically will be realized during this routine and filled afterwards. } + +{GLOBAL} +procedure jpeg_write_coefficients (cinfo : j_compress_ptr; + coef_arrays : jvirt_barray_tbl_ptr); + +{ Initialize the compression object with default parameters, + then copy from the source object all parameters needed for lossless + transcoding. Parameters that can be varied without loss (such as + scan script and Huffman optimization) are left in their default states. } + +{GLOBAL} +procedure jpeg_copy_critical_parameters (srcinfo : j_decompress_ptr; + dstinfo : j_compress_ptr); + + +implementation + +{ Forward declarations } +{LOCAL} +procedure transencode_master_selection(cinfo : j_compress_ptr; + coef_arrays : jvirt_barray_tbl_ptr); + forward; +{LOCAL} +procedure transencode_coef_controller(cinfo : j_compress_ptr; + coef_arrays : jvirt_barray_tbl_ptr); + forward; + + +{ Compression initialization for writing raw-coefficient data. + Before calling this, all parameters and a data destination must be set up. + Call jpeg_finish_compress() to actually write the data. + + The number of passed virtual arrays must match cinfo^.num_components. + Note that the virtual arrays need not be filled or even realized at + the time write_coefficients is called; indeed, if the virtual arrays + were requested from this compression object's memory manager, they + typically will be realized during this routine and filled afterwards. } + +{GLOBAL} +procedure jpeg_write_coefficients (cinfo : j_compress_ptr; + coef_arrays : jvirt_barray_tbl_ptr); +begin + if (cinfo^.global_state <> CSTATE_START) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + { Mark all tables to be written } + jpeg_suppress_tables(cinfo, FALSE); + { (Re)initialize error mgr and destination modules } + cinfo^.err^.reset_error_mgr (j_common_ptr(cinfo)); + cinfo^.dest^.init_destination (cinfo); + { Perform master selection of active modules } + transencode_master_selection(cinfo, coef_arrays); + { Wait for jpeg_finish_compress() call } + cinfo^.next_scanline := 0; { so jpeg_write_marker works } + cinfo^.global_state := CSTATE_WRCOEFS; +end; + + +{ Initialize the compression object with default parameters, + then copy from the source object all parameters needed for lossless + transcoding. Parameters that can be varied without loss (such as + scan script and Huffman optimization) are left in their default states. } + +{GLOBAL} +procedure jpeg_copy_critical_parameters (srcinfo : j_decompress_ptr; + dstinfo : j_compress_ptr); +var + qtblptr : ^JQUANT_TBL_PTR; + incomp, outcomp : jpeg_component_info_ptr; + c_quant, slot_quant : JQUANT_TBL_PTR; + tblno, ci, coefi : int; +begin + + { Safety check to ensure start_compress not called yet. } + if (dstinfo^.global_state <> CSTATE_START) then + ERREXIT1(j_common_ptr(dstinfo), JERR_BAD_STATE, dstinfo^.global_state); + { Copy fundamental image dimensions } + dstinfo^.image_width := srcinfo^.image_width; + dstinfo^.image_height := srcinfo^.image_height; + dstinfo^.input_components := srcinfo^.num_components; + dstinfo^.in_color_space := srcinfo^.jpeg_color_space; + { Initialize all parameters to default values } + jpeg_set_defaults(dstinfo); + { jpeg_set_defaults may choose wrong colorspace, eg YCbCr if input is RGB. + Fix it to get the right header markers for the image colorspace. } + + jpeg_set_colorspace(dstinfo, srcinfo^.jpeg_color_space); + dstinfo^.data_precision := srcinfo^.data_precision; + dstinfo^.CCIR601_sampling := srcinfo^.CCIR601_sampling; + { Copy the source's quantization tables. } + for tblno := 0 to pred(NUM_QUANT_TBLS) do + begin + if (srcinfo^.quant_tbl_ptrs[tblno] <> NIL) then + begin + qtblptr := @dstinfo^.quant_tbl_ptrs[tblno]; + if (qtblptr^ = NIL) then + qtblptr^ := jpeg_alloc_quant_table(j_common_ptr(dstinfo)); + MEMCOPY(@(qtblptr^)^.quantval, + @srcinfo^.quant_tbl_ptrs[tblno]^.quantval, + SIZEOF((qtblptr^)^.quantval)); + (qtblptr^)^.sent_table := FALSE; + end; + end; + { Copy the source's per-component info. + Note we assume jpeg_set_defaults has allocated the dest comp_info array. } + + dstinfo^.num_components := srcinfo^.num_components; + if (dstinfo^.num_components < 1) or + (dstinfo^.num_components > MAX_COMPONENTS) then + ERREXIT2(j_common_ptr(dstinfo), JERR_COMPONENT_COUNT, + dstinfo^.num_components, MAX_COMPONENTS); + incomp := jpeg_component_info_ptr(srcinfo^.comp_info); + outcomp := jpeg_component_info_ptr(dstinfo^.comp_info); + for ci := 0 to pred(dstinfo^.num_components) do + begin + + outcomp^.component_id := incomp^.component_id; + outcomp^.h_samp_factor := incomp^.h_samp_factor; + outcomp^.v_samp_factor := incomp^.v_samp_factor; + outcomp^.quant_tbl_no := incomp^.quant_tbl_no; + { Make sure saved quantization table for component matches the qtable + slot. If not, the input file re-used this qtable slot. + IJG encoder currently cannot duplicate this. } + + tblno := outcomp^.quant_tbl_no; + if (tblno < 0) or (tblno >= NUM_QUANT_TBLS) or + (srcinfo^.quant_tbl_ptrs[tblno] = NIL) then + ERREXIT1(j_common_ptr(dstinfo), JERR_NO_QUANT_TABLE, tblno); + slot_quant := srcinfo^.quant_tbl_ptrs[tblno]; + c_quant := incomp^.quant_table; + if (c_quant <> NIL) then + begin + for coefi := 0 to pred(DCTSIZE2) do + begin + if (c_quant^.quantval[coefi] <> slot_quant^.quantval[coefi]) then + ERREXIT1(j_common_ptr(dstinfo), JERR_MISMATCHED_QUANT_TABLE, tblno); + end; + end; + { Note: we do not copy the source's Huffman table assignments; + instead we rely on jpeg_set_colorspace to have made a suitable choice. } + Inc(incomp); + Inc(outcomp); + end; + { Also copy JFIF version and resolution information, if available. + Strictly speaking this isn't "critical" info, but it's nearly + always appropriate to copy it if available. In particular, + if the application chooses to copy JFIF 1.02 extension markers from + the source file, we need to copy the version to make sure we don't + emit a file that has 1.02 extensions but a claimed version of 1.01. + We will *not*, however, copy version info from mislabeled "2.01" files. } + + if (srcinfo^.saw_JFIF_marker) then + begin + if (srcinfo^.JFIF_major_version = 1) then + begin + dstinfo^.JFIF_major_version := srcinfo^.JFIF_major_version; + dstinfo^.JFIF_minor_version := srcinfo^.JFIF_minor_version; + end; + dstinfo^.density_unit := srcinfo^.density_unit; + dstinfo^.X_density := srcinfo^.X_density; + dstinfo^.Y_density := srcinfo^.Y_density; + end; +end; + + +{ Master selection of compression modules for transcoding. + This substitutes for jcinit.c's initialization of the full compressor. } + +{LOCAL} +procedure transencode_master_selection (cinfo : j_compress_ptr; + coef_arrays : jvirt_barray_tbl_ptr); +begin + { Although we don't actually use input_components for transcoding, + jcmaster.c's initial_setup will complain if input_components is 0. } + + cinfo^.input_components := 1; + { Initialize master control (includes parameter checking/processing) } + jinit_c_master_control(cinfo, TRUE { transcode only }); + + { Entropy encoding: either Huffman or arithmetic coding. } + if (cinfo^.arith_code) then + begin + ERREXIT(j_common_ptr(cinfo), JERR_ARITH_NOTIMPL); + end + else + begin + if (cinfo^.progressive_mode) then + begin +{$ifdef C_PROGRESSIVE_SUPPORTED} + jinit_phuff_encoder(cinfo); +{$else} + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); +{$endif} + end + else + jinit_huff_encoder(cinfo); + end; + + { We need a special coefficient buffer controller. } + transencode_coef_controller(cinfo, coef_arrays); + + jinit_marker_writer(cinfo); + + { We can now tell the memory manager to allocate virtual arrays. } + cinfo^.mem^.realize_virt_arrays (j_common_ptr(cinfo)); + + { Write the datastream header (SOI, JFIF) immediately. + Frame and scan headers are postponed till later. + This lets application insert special markers after the SOI. } + + cinfo^.marker^.write_file_header (cinfo); +end; + + +{ The rest of this file is a special implementation of the coefficient + buffer controller. This is similar to jccoefct.c, but it handles only + output from presupplied virtual arrays. Furthermore, we generate any + dummy padding blocks on-the-fly rather than expecting them to be present + in the arrays. } + +{ Private buffer controller object } + +type + my_coef_ptr = ^my_coef_controller; + my_coef_controller = record + pub : jpeg_c_coef_controller; { public fields } + + iMCU_row_num : JDIMENSION; { iMCU row # within image } + mcu_ctr : JDIMENSION; { counts MCUs processed in current row } + MCU_vert_offset : int; { counts MCU rows within iMCU row } + MCU_rows_per_iMCU_row : int; { number of such rows needed } + + { Virtual block array for each component. } + whole_image : jvirt_barray_tbl_ptr; + + { Workspace for constructing dummy blocks at right/bottom edges. } + dummy_buffer : array[0..C_MAX_BLOCKS_IN_MCU-1] of JBLOCKROW; + end; {my_coef_controller;} + + +{LOCAL} +procedure start_iMCU_row (cinfo : j_compress_ptr); +{ Reset within-iMCU-row counters for a new row } +var + coef : my_coef_ptr; +begin + coef := my_coef_ptr (cinfo^.coef); + + { In an interleaved scan, an MCU row is the same as an iMCU row. + In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows. + But at the bottom of the image, process only what's left. } + + if (cinfo^.comps_in_scan > 1) then + begin + coef^.MCU_rows_per_iMCU_row := 1; + end + else + begin + if (coef^.iMCU_row_num < (cinfo^.total_iMCU_rows-1)) then + coef^.MCU_rows_per_iMCU_row := cinfo^.cur_comp_info[0]^.v_samp_factor + else + coef^.MCU_rows_per_iMCU_row := cinfo^.cur_comp_info[0]^.last_row_height; + end; + + coef^.mcu_ctr := 0; + coef^.MCU_vert_offset := 0; +end; + + +{ Initialize for a processing pass. } + +{METHODDEF} +procedure start_pass_coef (cinfo : j_compress_ptr; + pass_mode : J_BUF_MODE); +var + coef : my_coef_ptr; +begin + coef := my_coef_ptr (cinfo^.coef); + + if (pass_mode <> JBUF_CRANK_DEST) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE); + + coef^.iMCU_row_num := 0; + start_iMCU_row(cinfo); +end; + + +{ Process some data. + We process the equivalent of one fully interleaved MCU row ("iMCU" row) + per call, ie, v_samp_factor block rows for each component in the scan. + The data is obtained from the virtual arrays and fed to the entropy coder. + Returns TRUE if the iMCU row is completed, FALSE if suspended. + + NB: input_buf is ignored; it is likely to be a NIL pointer. } + +{METHODDEF} +function compress_output (cinfo : j_compress_ptr; + input_buf : JSAMPIMAGE) : boolean; +var + coef : my_coef_ptr; + MCU_col_num : JDIMENSION; { index of current MCU within row } + last_MCU_col : JDIMENSION; + last_iMCU_row : JDIMENSION; + blkn, ci, xindex, yindex, yoffset, blockcnt : int; + start_col : JDIMENSION; + buffer : array[0..MAX_COMPS_IN_SCAN-1] of JBLOCKARRAY; + MCU_buffer : array[0..C_MAX_BLOCKS_IN_MCU-1] of JBLOCKROW; + buffer_ptr : JBLOCKROW; + compptr : jpeg_component_info_ptr; +begin + coef := my_coef_ptr (cinfo^.coef); + last_MCU_col := cinfo^.MCUs_per_row - 1; + last_iMCU_row := cinfo^.total_iMCU_rows - 1; + + { Align the virtual buffers for the components used in this scan. } + for ci := 0 to pred(cinfo^.comps_in_scan) do + begin + compptr := cinfo^.cur_comp_info[ci]; + buffer[ci] := cinfo^.mem^.access_virt_barray + (j_common_ptr(cinfo), coef^.whole_image^[compptr^.component_index], + coef^.iMCU_row_num * compptr^.v_samp_factor, + JDIMENSION(compptr^.v_samp_factor), FALSE); + end; + + { Loop to process one whole iMCU row } + for yoffset := coef^.MCU_vert_offset to pred(coef^.MCU_rows_per_iMCU_row) do + begin + for MCU_col_num := coef^.mcu_ctr to pred(cinfo^.MCUs_per_row) do + begin + { Construct list of pointers to DCT blocks belonging to this MCU } + blkn := 0; { index of current DCT block within MCU } + for ci := 0 to pred(cinfo^.comps_in_scan) do + begin + compptr := cinfo^.cur_comp_info[ci]; + start_col := MCU_col_num * compptr^.MCU_width; + if (MCU_col_num < last_MCU_col) then + blockcnt := compptr^.MCU_width + else + blockcnt := compptr^.last_col_width; + for yindex := 0 to pred(compptr^.MCU_height) do + begin + if (coef^.iMCU_row_num < last_iMCU_row) or + (yindex+yoffset < compptr^.last_row_height) then + begin + { Fill in pointers to real blocks in this row } + buffer_ptr := JBLOCKROW(@ buffer[ci]^[yindex+yoffset]^[start_col]); + for xindex := 0 to pred(blockcnt) do + begin + MCU_buffer[blkn] := buffer_ptr; + Inc(blkn); + Inc(JBLOCK_PTR(buffer_ptr)); + end; + xindex := blockcnt; + end + else + begin + { At bottom of image, need a whole row of dummy blocks } + xindex := 0; + end; + { Fill in any dummy blocks needed in this row. + Dummy blocks are filled in the same way as in jccoefct.c: + all zeroes in the AC entries, DC entries equal to previous + block's DC value. The init routine has already zeroed the + AC entries, so we need only set the DC entries correctly. } + + while (xindex < compptr^.MCU_width) do + begin + MCU_buffer[blkn] := coef^.dummy_buffer[blkn]; + MCU_buffer[blkn]^[0][0] := MCU_buffer[blkn-1]^[0][0]; + Inc(xindex); + Inc(blkn); + end; + end; + end; + { Try to write the MCU. } + if (not cinfo^.entropy^.encode_mcu (cinfo, MCU_buffer)) then + begin + { Suspension forced; update state counters and exit } + coef^.MCU_vert_offset := yoffset; + coef^.mcu_ctr := MCU_col_num; + compress_output := FALSE; + exit; + end; + end; + { Completed an MCU row, but perhaps not an iMCU row } + coef^.mcu_ctr := 0; + end; + { Completed the iMCU row, advance counters for next one } + Inc(coef^.iMCU_row_num); + start_iMCU_row(cinfo); + compress_output := TRUE; +end; + + +{ Initialize coefficient buffer controller. + + Each passed coefficient array must be the right size for that + coefficient: width_in_blocks wide and height_in_blocks high, + with unitheight at least v_samp_factor. } + +{LOCAL} +procedure transencode_coef_controller (cinfo : j_compress_ptr; + coef_arrays : jvirt_barray_tbl_ptr); +var + coef : my_coef_ptr; + buffer : JBLOCKROW; + i : int; +begin + coef := my_coef_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(my_coef_controller))); + cinfo^.coef := jpeg_c_coef_controller_ptr (coef); + coef^.pub.start_pass := start_pass_coef; + coef^.pub.compress_data := compress_output; + + { Save pointer to virtual arrays } + coef^.whole_image := coef_arrays; + + { Allocate and pre-zero space for dummy DCT blocks. } + buffer := JBLOCKROW( + cinfo^.mem^.alloc_large (j_common_ptr(cinfo), JPOOL_IMAGE, + C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)) ); + jzero_far({FAR} voidp(buffer), C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)); + for i := 0 to pred(C_MAX_BLOCKS_IN_MCU) do + begin + coef^.dummy_buffer[i] := JBLOCKROW(@ buffer^[i]); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jdapimin_del.pas b/mseide-msegui/lib/common/fpccompatibility/jdapimin_del.pas new file mode 100644 index 0000000..42d907b --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jdapimin_del.pas @@ -0,0 +1,506 @@ +unit jdapimin_del; + +//{$N+} { Nomssi: cinfo^.output_gamma } + +{ This file contains application interface code for the decompression half + of the JPEG library. These are the "minimum" API routines that may be + needed in either the normal full-decompression case or the + transcoding-only case. + + Most of the routines intended to be called directly by an application + are in this file or in jdapistd.c. But also see jcomapi.c for routines + shared by compression and decompression, and jdtrans.c for the transcoding + case. } + +{ Original : jdapimin.c ; Copyright (C) 1994-1998, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jdeferr_del, + jerror_del, + jpeglib_del, + jmemmgr_del, jdmarker_del, jdinput_del, jcomapi_del; + +{ Nomssi } +procedure jpeg_create_decompress(cinfo : j_decompress_ptr); + +{ Initialization of a JPEG decompression object. + The error manager must already be set up (in case memory manager fails). } + +{GLOBAL} +procedure jpeg_CreateDecompress (cinfo : j_decompress_ptr; + version : int; + structsize : size_t); + +{ Destruction of a JPEG decompression object } + +{GLOBAL} +procedure jpeg_destroy_decompress (cinfo : j_decompress_ptr); + + +{ Decompression startup: read start of JPEG datastream to see what's there. + Need only initialize JPEG object and supply a data source before calling. + + This routine will read as far as the first SOS marker (ie, actual start of + compressed data), and will save all tables and parameters in the JPEG + object. It will also initialize the decompression parameters to default + values, and finally return JPEG_HEADER_OK. On return, the application may + adjust the decompression parameters and then call jpeg_start_decompress. + (Or, if the application only wanted to determine the image parameters, + the data need not be decompressed. In that case, call jpeg_abort or + jpeg_destroy to release any temporary space.) + If an abbreviated (tables only) datastream is presented, the routine will + return JPEG_HEADER_TABLES_ONLY upon reaching EOI. The application may then + re-use the JPEG object to read the abbreviated image datastream(s). + It is unnecessary (but OK) to call jpeg_abort in this case. + The JPEG_SUSPENDED return code only occurs if the data source module + requests suspension of the decompressor. In this case the application + should load more source data and then re-call jpeg_read_header to resume + processing. + If a non-suspending data source is used and require_image is TRUE, then the + return code need not be inspected since only JPEG_HEADER_OK is possible. + + This routine is now just a front end to jpeg_consume_input, with some + extra error checking. } + +{GLOBAL} +function jpeg_read_header (cinfo : j_decompress_ptr; + require_image : boolean) : int; + +{ Consume data in advance of what the decompressor requires. + This can be called at any time once the decompressor object has + been created and a data source has been set up. + + This routine is essentially a state machine that handles a couple + of critical state-transition actions, namely initial setup and + transition from header scanning to ready-for-start_decompress. + All the actual input is done via the input controller's consume_input + method. } + +{GLOBAL} +function jpeg_consume_input (cinfo : j_decompress_ptr) : int; + +{ Have we finished reading the input file? } + +{GLOBAL} +function jpeg_input_complete (cinfo : j_decompress_ptr) : boolean; + +{ Is there more than one scan? } + +{GLOBAL} +function jpeg_has_multiple_scans (cinfo : j_decompress_ptr) : boolean; + + +{ Finish JPEG decompression. + + This will normally just verify the file trailer and release temp storage. + + Returns FALSE if suspended. The return value need be inspected only if + a suspending data source is used. } + +{GLOBAL} +function jpeg_finish_decompress (cinfo : j_decompress_ptr) : boolean; + +implementation + +procedure jpeg_create_decompress(cinfo : j_decompress_ptr); +begin + jpeg_CreateDecompress(cinfo, JPEG_LIB_VERSION, + size_t(sizeof(jpeg_decompress_struct))); +end; + +{ Initialization of a JPEG decompression object. + The error manager must already be set up (in case memory manager fails). } + +{GLOBAL} +procedure jpeg_CreateDecompress (cinfo : j_decompress_ptr; + version : int; + structsize : size_t); +var + i : int; +var + err : jpeg_error_mgr_ptr; + client_data : voidp; +begin + { Guard against version mismatches between library and caller. } + cinfo^.mem := NIL; { so jpeg_destroy knows mem mgr not called } + if (version <> JPEG_LIB_VERSION) then + ERREXIT2(j_common_ptr(cinfo), JERR_BAD_LIB_VERSION, JPEG_LIB_VERSION, version); + if (structsize <> SIZEOF(jpeg_decompress_struct)) then + ERREXIT2(j_common_ptr(cinfo), JERR_BAD_STRUCT_SIZE, + int(SIZEOF(jpeg_decompress_struct)), int(structsize)); + + { For debugging purposes, we zero the whole master structure. + But the application has already set the err pointer, and may have set + client_data, so we have to save and restore those fields. + Note: if application hasn't set client_data, tools like Purify may + complain here. } + begin + err := cinfo^.err; + client_data := cinfo^.client_data; { ignore Purify complaint here } + MEMZERO(j_common_ptr(cinfo), SIZEOF(jpeg_decompress_struct)); + cinfo^.err := err; + cinfo^.client_data := client_data; + end; + cinfo^.is_decompressor := TRUE; + + { Initialize a memory manager instance for this object } + jinit_memory_mgr(j_common_ptr(cinfo)); + + { Zero out pointers to permanent structures. } + cinfo^.progress := NIL; + cinfo^.src := NIL; + + for i := 0 to pred(NUM_QUANT_TBLS) do + cinfo^.quant_tbl_ptrs[i] := NIL; + + for i := 0 to pred(NUM_HUFF_TBLS) do + begin + cinfo^.dc_huff_tbl_ptrs[i] := NIL; + cinfo^.ac_huff_tbl_ptrs[i] := NIL; + end; + + { Initialize marker processor so application can override methods + for COM, APPn markers before calling jpeg_read_header. } + cinfo^.marker_list := NIL; + jinit_marker_reader(cinfo); + + { And initialize the overall input controller. } + jinit_input_controller(cinfo); + + { OK, I'm ready } + cinfo^.global_state := DSTATE_START; +end; + + +{ Destruction of a JPEG decompression object } + +{GLOBAL} +procedure jpeg_destroy_decompress (cinfo : j_decompress_ptr); +begin + jpeg_destroy(j_common_ptr(cinfo)); { use common routine } +end; + + +{ Abort processing of a JPEG decompression operation, + but don't destroy the object itself. } + +{GLOBAL} +procedure jpeg_abort_decompress (cinfo : j_decompress_ptr); +begin + jpeg_abort(j_common_ptr(cinfo)); { use common routine } +end; + + +{ Set default decompression parameters. } + +{LOCAL} +procedure default_decompress_parms (cinfo : j_decompress_ptr); +var + cid0 : int; + cid1 : int; + cid2 : int; +begin + { Guess the input colorspace, and set output colorspace accordingly. } + { (Wish JPEG committee had provided a real way to specify this...) } + { Note application may override our guesses. } + case (cinfo^.num_components) of + 1: begin + cinfo^.jpeg_color_space := JCS_GRAYSCALE; + cinfo^.out_color_space := JCS_GRAYSCALE; + end; + + 3: begin + if (cinfo^.saw_JFIF_marker) then + begin + cinfo^.jpeg_color_space := JCS_YCbCr; { JFIF implies YCbCr } + end + else + if (cinfo^.saw_Adobe_marker) then + begin + case (cinfo^.Adobe_transform) of + 0: cinfo^.jpeg_color_space := JCS_RGB; + 1: cinfo^.jpeg_color_space := JCS_YCbCr; + else + begin + WARNMS1(j_common_ptr(cinfo), JWRN_ADOBE_XFORM, cinfo^.Adobe_transform); + cinfo^.jpeg_color_space := JCS_YCbCr; { assume it's YCbCr } + end; + end; + end + else + begin + { Saw no special markers, try to guess from the component IDs } + cid0 := cinfo^.comp_info^[0].component_id; + cid1 := cinfo^.comp_info^[1].component_id; + cid2 := cinfo^.comp_info^[2].component_id; + + if (cid0 = 1) and (cid1 = 2) and (cid2 = 3) then + cinfo^.jpeg_color_space := JCS_YCbCr { assume JFIF w/out marker } + else + if (cid0 = 82) and (cid1 = 71) and (cid2 = 66) then + cinfo^.jpeg_color_space := JCS_RGB { ASCII 'R', 'G', 'B' } + else + begin + {$IFDEF DEBUG} + TRACEMS3(j_common_ptr(cinfo), 1, JTRC_UNKNOWN_IDS, cid0, cid1, cid2); + {$ENDIF} + cinfo^.jpeg_color_space := JCS_YCbCr; { assume it's YCbCr } + end; + end; + { Always guess RGB is proper output colorspace. } + cinfo^.out_color_space := JCS_RGB; + end; + + 4: begin + if (cinfo^.saw_Adobe_marker) then + begin + case (cinfo^.Adobe_transform) of + 0: cinfo^.jpeg_color_space := JCS_CMYK; + 2: cinfo^.jpeg_color_space := JCS_YCCK; + else + begin + WARNMS1(j_common_ptr(cinfo), JWRN_ADOBE_XFORM, cinfo^.Adobe_transform); + cinfo^.jpeg_color_space := JCS_YCCK; { assume it's YCCK } + end; + end; + end + else + begin + { No special markers, assume straight CMYK. } + cinfo^.jpeg_color_space := JCS_CMYK; + end; + cinfo^.out_color_space := JCS_CMYK; + end; + + else + begin + cinfo^.jpeg_color_space := JCS_UNKNOWN; + cinfo^.out_color_space := JCS_UNKNOWN; + end; + end; + + { Set defaults for other decompression parameters. } + cinfo^.scale_num := 1; { 1:1 scaling } + cinfo^.scale_denom := 1; + cinfo^.output_gamma := 1.0; + cinfo^.buffered_image := FALSE; + cinfo^.raw_data_out := FALSE; + cinfo^.dct_method := JDCT_DEFAULT; + cinfo^.do_fancy_upsampling := TRUE; + cinfo^.do_block_smoothing := TRUE; + cinfo^.quantize_colors := FALSE; + { We set these in case application only sets quantize_colors. } + cinfo^.dither_mode := JDITHER_FS; +{$ifdef QUANT_2PASS_SUPPORTED} + cinfo^.two_pass_quantize := TRUE; +{$else} + cinfo^.two_pass_quantize := FALSE; +{$endif} + cinfo^.desired_number_of_colors := 256; + cinfo^.colormap := NIL; + { Initialize for no mode change in buffered-image mode. } + cinfo^.enable_1pass_quant := FALSE; + cinfo^.enable_external_quant := FALSE; + cinfo^.enable_2pass_quant := FALSE; +end; + + +{ Decompression startup: read start of JPEG datastream to see what's there. + Need only initialize JPEG object and supply a data source before calling. + + This routine will read as far as the first SOS marker (ie, actual start of + compressed data), and will save all tables and parameters in the JPEG + object. It will also initialize the decompression parameters to default + values, and finally return JPEG_HEADER_OK. On return, the application may + adjust the decompression parameters and then call jpeg_start_decompress. + (Or, if the application only wanted to determine the image parameters, + the data need not be decompressed. In that case, call jpeg_abort or + jpeg_destroy to release any temporary space.) + If an abbreviated (tables only) datastream is presented, the routine will + return JPEG_HEADER_TABLES_ONLY upon reaching EOI. The application may then + re-use the JPEG object to read the abbreviated image datastream(s). + It is unnecessary (but OK) to call jpeg_abort in this case. + The JPEG_SUSPENDED return code only occurs if the data source module + requests suspension of the decompressor. In this case the application + should load more source data and then re-call jpeg_read_header to resume + processing. + If a non-suspending data source is used and require_image is TRUE, then the + return code need not be inspected since only JPEG_HEADER_OK is possible. + + This routine is now just a front end to jpeg_consume_input, with some + extra error checking. } + +{GLOBAL} +function jpeg_read_header (cinfo : j_decompress_ptr; + require_image : boolean) : int; +var + retcode : int; +begin + if (cinfo^.global_state <> DSTATE_START) and + (cinfo^.global_state <> DSTATE_INHEADER) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + + retcode := jpeg_consume_input(cinfo); + + case (retcode) of + JPEG_REACHED_SOS: + retcode := JPEG_HEADER_OK; + JPEG_REACHED_EOI: + begin + if (require_image) then { Complain if application wanted an image } + ERREXIT(j_common_ptr(cinfo), JERR_NO_IMAGE); + { Reset to start state; it would be safer to require the application to + call jpeg_abort, but we can't change it now for compatibility reasons. + A side effect is to free any temporary memory (there shouldn't be any). } + + jpeg_abort(j_common_ptr(cinfo)); { sets state := DSTATE_START } + retcode := JPEG_HEADER_TABLES_ONLY; + end; + JPEG_SUSPENDED: ; { no work } + end; + + jpeg_read_header := retcode; +end; + + +{ Consume data in advance of what the decompressor requires. + This can be called at any time once the decompressor object has + been created and a data source has been set up. + + This routine is essentially a state machine that handles a couple + of critical state-transition actions, namely initial setup and + transition from header scanning to ready-for-start_decompress. + All the actual input is done via the input controller's consume_input + method. } + +{GLOBAL} +function jpeg_consume_input (cinfo : j_decompress_ptr) : int; +var + retcode : int; +begin + retcode := JPEG_SUSPENDED; + + { NB: every possible DSTATE value should be listed in this switch } + + if (cinfo^.global_state) = DSTATE_START then + begin {work around the FALLTHROUGH} + { Start-of-datastream actions: reset appropriate modules } + cinfo^.inputctl^.reset_input_controller (cinfo); + { Initialize application's data source module } + cinfo^.src^.init_source (cinfo); + cinfo^.global_state := DSTATE_INHEADER; + end; + + case (cinfo^.global_state) of + DSTATE_START, + DSTATE_INHEADER: + begin + retcode := cinfo^.inputctl^.consume_input (cinfo); + if (retcode = JPEG_REACHED_SOS) then + begin { Found SOS, prepare to decompress } + { Set up default parameters based on header data } + default_decompress_parms(cinfo); + { Set global state: ready for start_decompress } + cinfo^.global_state := DSTATE_READY; + end; + end; + DSTATE_READY: + { Can't advance past first SOS until start_decompress is called } + retcode := JPEG_REACHED_SOS; + + DSTATE_PRELOAD, + DSTATE_PRESCAN, + DSTATE_SCANNING, + DSTATE_RAW_OK, + DSTATE_BUFIMAGE, + DSTATE_BUFPOST, + DSTATE_STOPPING: + retcode := cinfo^.inputctl^.consume_input (cinfo); + else + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + end; + jpeg_consume_input := retcode; +end; + + +{ Have we finished reading the input file? } + +{GLOBAL} +function jpeg_input_complete (cinfo : j_decompress_ptr) : boolean; +begin + { Check for valid jpeg object } + if (cinfo^.global_state < DSTATE_START) or + (cinfo^.global_state > DSTATE_STOPPING) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + jpeg_input_complete := cinfo^.inputctl^.eoi_reached; +end; + + +{ Is there more than one scan? } + +{GLOBAL} +function jpeg_has_multiple_scans (cinfo : j_decompress_ptr) : boolean; +begin + { Only valid after jpeg_read_header completes } + if (cinfo^.global_state < DSTATE_READY) or + (cinfo^.global_state > DSTATE_STOPPING) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + jpeg_has_multiple_scans := cinfo^.inputctl^.has_multiple_scans; +end; + + +{ Finish JPEG decompression. + + This will normally just verify the file trailer and release temp storage. + + Returns FALSE if suspended. The return value need be inspected only if + a suspending data source is used. } + +{GLOBAL} +function jpeg_finish_decompress (cinfo : j_decompress_ptr) : boolean; +begin + if ((cinfo^.global_state = DSTATE_SCANNING) or + (cinfo^.global_state = DSTATE_RAW_OK) and (not cinfo^.buffered_image)) then + begin + { Terminate final pass of non-buffered mode } + if (cinfo^.output_scanline < cinfo^.output_height) then + ERREXIT(j_common_ptr(cinfo), JERR_TOO_LITTLE_DATA); + cinfo^.master^.finish_output_pass (cinfo); + cinfo^.global_state := DSTATE_STOPPING; + end + else + if (cinfo^.global_state = DSTATE_BUFIMAGE) then + begin + { Finishing after a buffered-image operation } + cinfo^.global_state := DSTATE_STOPPING; + end + else + if (cinfo^.global_state <> DSTATE_STOPPING) then + begin + { STOPPING := repeat call after a suspension, anything else is error } + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + end; + { Read until EOI } + while (not cinfo^.inputctl^.eoi_reached) do + begin + if (cinfo^.inputctl^.consume_input (cinfo) = JPEG_SUSPENDED) then + begin + jpeg_finish_decompress := FALSE; { Suspend, come back later } + exit; + end; + end; + { Do final cleanup } + cinfo^.src^.term_source (cinfo); + { We can use jpeg_abort to release memory and reset global_state } + jpeg_abort(j_common_ptr(cinfo)); + jpeg_finish_decompress := TRUE; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jdapistd_del.pas b/mseide-msegui/lib/common/fpccompatibility/jdapistd_del.pas new file mode 100644 index 0000000..2d291b4 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jdapistd_del.pas @@ -0,0 +1,377 @@ +unit jdapistd_del; + +{ Original : jdapistd.c ; Copyright (C) 1994-1996, Thomas G. Lane. } + +{ This file is part of the Independent JPEG Group's software. + For conditions of distribution and use, see the accompanying README file. + + This file contains application interface code for the decompression half + of the JPEG library. These are the "standard" API routines that are + used in the normal full-decompression case. They are not used by a + transcoding-only application. Note that if an application links in + jpeg_start_decompress, it will end up linking in the entire decompressor. + We thus must separate this file from jdapimin.c to avoid linking the + whole decompression library into a transcoder. } +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jdeferr_del, + jerror_del, + jpeglib_del, + jdmaster_del; + +{ Read some scanlines of data from the JPEG decompressor. + + The return value will be the number of lines actually read. + This may be less than the number requested in several cases, + including bottom of image, data source suspension, and operating + modes that emit multiple scanlines at a time. + + Note: we warn about excess calls to jpeg_read_scanlines() since + this likely signals an application programmer error. However, + an oversize buffer (max_lines > scanlines remaining) is not an error. } + +{GLOBAL} +function jpeg_read_scanlines (cinfo : j_decompress_ptr; + scanlines : JSAMPARRAY; + max_lines : JDIMENSION) : JDIMENSION; + + +{ Alternate entry point to read raw data. + Processes exactly one iMCU row per call, unless suspended. } + +{GLOBAL} +function jpeg_read_raw_data (cinfo : j_decompress_ptr; + data : JSAMPIMAGE; + max_lines : JDIMENSION) : JDIMENSION; + +{$ifdef D_MULTISCAN_FILES_SUPPORTED} + +{ Initialize for an output pass in buffered-image mode. } + +{GLOBAL} +function jpeg_start_output (cinfo : j_decompress_ptr; + scan_number : int) : boolean; + +{ Finish up after an output pass in buffered-image mode. + + Returns FALSE if suspended. The return value need be inspected only if + a suspending data source is used. } + +{GLOBAL} +function jpeg_finish_output (cinfo : j_decompress_ptr) : boolean; + +{$endif} { D_MULTISCAN_FILES_SUPPORTED } + +{ Decompression initialization. + jpeg_read_header must be completed before calling this. + + If a multipass operating mode was selected, this will do all but the + last pass, and thus may take a great deal of time. + + Returns FALSE if suspended. The return value need be inspected only if + a suspending data source is used. } + +{GLOBAL} +function jpeg_start_decompress (cinfo : j_decompress_ptr) : boolean; + + +implementation + +{ Forward declarations } +{LOCAL} +function output_pass_setup (cinfo : j_decompress_ptr) : boolean; forward; + +{ Decompression initialization. + jpeg_read_header must be completed before calling this. + + If a multipass operating mode was selected, this will do all but the + last pass, and thus may take a great deal of time. + + Returns FALSE if suspended. The return value need be inspected only if + a suspending data source is used. } + +{GLOBAL} +function jpeg_start_decompress (cinfo : j_decompress_ptr) : boolean; +var + retcode : int; +begin + if (cinfo^.global_state = DSTATE_READY) then + begin + { First call: initialize master control, select active modules } + jinit_master_decompress(cinfo); + if (cinfo^.buffered_image) then + begin + { No more work here; expecting jpeg_start_output next } + cinfo^.global_state := DSTATE_BUFIMAGE; + jpeg_start_decompress := TRUE; + exit; + end; + cinfo^.global_state := DSTATE_PRELOAD; + end; + if (cinfo^.global_state = DSTATE_PRELOAD) then + begin + { If file has multiple scans, absorb them all into the coef buffer } + if (cinfo^.inputctl^.has_multiple_scans) then + begin +{$ifdef D_MULTISCAN_FILES_SUPPORTED} + while TRUE do + begin + + { Call progress monitor hook if present } + if (cinfo^.progress <> NIL) then + cinfo^.progress^.progress_monitor (j_common_ptr(cinfo)); + { Absorb some more input } + retcode := cinfo^.inputctl^.consume_input (cinfo); + if (retcode = JPEG_SUSPENDED) then + begin + jpeg_start_decompress := FALSE; + exit; + end; + if (retcode = JPEG_REACHED_EOI) then + break; + { Advance progress counter if appropriate } + if (cinfo^.progress <> NIL) and + ((retcode = JPEG_ROW_COMPLETED) or (retcode = JPEG_REACHED_SOS)) then + begin + Inc(cinfo^.progress^.pass_counter); + if (cinfo^.progress^.pass_counter >= cinfo^.progress^.pass_limit) then + begin + { jdmaster underestimated number of scans; ratchet up one scan } + Inc(cinfo^.progress^.pass_limit, long(cinfo^.total_iMCU_rows)); + end; + end; + end; +{$else} + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); +{$endif} { D_MULTISCAN_FILES_SUPPORTED } + end; + cinfo^.output_scan_number := cinfo^.input_scan_number; + end + else + if (cinfo^.global_state <> DSTATE_PRESCAN) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + { Perform any dummy output passes, and set up for the final pass } + jpeg_start_decompress := output_pass_setup(cinfo); +end; + + +{ Set up for an output pass, and perform any dummy pass(es) needed. + Common subroutine for jpeg_start_decompress and jpeg_start_output. + Entry: global_state := DSTATE_PRESCAN only if previously suspended. + Exit: If done, returns TRUE and sets global_state for proper output mode. + If suspended, returns FALSE and sets global_state := DSTATE_PRESCAN. } + +{LOCAL} +function output_pass_setup (cinfo : j_decompress_ptr) : boolean; +var + last_scanline : JDIMENSION; +begin + if (cinfo^.global_state <> DSTATE_PRESCAN) then + begin + { First call: do pass setup } + cinfo^.master^.prepare_for_output_pass (cinfo); + cinfo^.output_scanline := 0; + cinfo^.global_state := DSTATE_PRESCAN; + end; + { Loop over any required dummy passes } + while (cinfo^.master^.is_dummy_pass) do + begin +{$ifdef QUANT_2PASS_SUPPORTED} + { Crank through the dummy pass } + while (cinfo^.output_scanline < cinfo^.output_height) do + begin + { Call progress monitor hook if present } + if (cinfo^.progress <> NIL) then + begin + cinfo^.progress^.pass_counter := long (cinfo^.output_scanline); + cinfo^.progress^.pass_limit := long (cinfo^.output_height); + cinfo^.progress^.progress_monitor (j_common_ptr(cinfo)); + end; + { Process some data } + last_scanline := cinfo^.output_scanline; + cinfo^.main^.process_data (cinfo, JSAMPARRAY(NIL), + cinfo^.output_scanline, {var} + JDIMENSION(0)); + if (cinfo^.output_scanline = last_scanline) then + begin + output_pass_setup := FALSE; { No progress made, must suspend } + exit; + end; + end; + { Finish up dummy pass, and set up for another one } + cinfo^.master^.finish_output_pass (cinfo); + cinfo^.master^.prepare_for_output_pass (cinfo); + cinfo^.output_scanline := 0; +{$else} + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); +{$endif} { QUANT_2PASS_SUPPORTED } + end; + { Ready for application to drive output pass through + jpeg_read_scanlines or jpeg_read_raw_data. } + if cinfo^.raw_data_out then + cinfo^.global_state := DSTATE_RAW_OK + else + cinfo^.global_state := DSTATE_SCANNING; + output_pass_setup := TRUE; +end; + + +{ Read some scanlines of data from the JPEG decompressor. + + The return value will be the number of lines actually read. + This may be less than the number requested in several cases, + including bottom of image, data source suspension, and operating + modes that emit multiple scanlines at a time. + + Note: we warn about excess calls to jpeg_read_scanlines() since + this likely signals an application programmer error. However, + an oversize buffer (max_lines > scanlines remaining) is not an error. } + +{GLOBAL} +function jpeg_read_scanlines (cinfo : j_decompress_ptr; + scanlines : JSAMPARRAY; + max_lines : JDIMENSION) : JDIMENSION; +var + row_ctr : JDIMENSION; +begin + if (cinfo^.global_state <> DSTATE_SCANNING) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + if (cinfo^.output_scanline >= cinfo^.output_height) then + begin + WARNMS(j_common_ptr(cinfo), JWRN_TOO_MUCH_DATA); + jpeg_read_scanlines := 0; + exit; + end; + + { Call progress monitor hook if present } + if (cinfo^.progress <> NIL) then + begin + cinfo^.progress^.pass_counter := long (cinfo^.output_scanline); + cinfo^.progress^.pass_limit := long (cinfo^.output_height); + cinfo^.progress^.progress_monitor (j_common_ptr(cinfo)); + end; + + { Process some data } + row_ctr := 0; + cinfo^.main^.process_data (cinfo, scanlines, {var}row_ctr, max_lines); + Inc(cinfo^.output_scanline, row_ctr); + jpeg_read_scanlines := row_ctr; +end; + + +{ Alternate entry point to read raw data. + Processes exactly one iMCU row per call, unless suspended. } + +{GLOBAL} +function jpeg_read_raw_data (cinfo : j_decompress_ptr; + data : JSAMPIMAGE; + max_lines : JDIMENSION) : JDIMENSION; +var + lines_per_iMCU_row : JDIMENSION; +begin + if (cinfo^.global_state <> DSTATE_RAW_OK) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + if (cinfo^.output_scanline >= cinfo^.output_height) then + begin + WARNMS(j_common_ptr(cinfo), JWRN_TOO_MUCH_DATA); + jpeg_read_raw_data := 0; + exit; + end; + + { Call progress monitor hook if present } + if (cinfo^.progress <> NIL) then + begin + cinfo^.progress^.pass_counter := long (cinfo^.output_scanline); + cinfo^.progress^.pass_limit := long (cinfo^.output_height); + cinfo^.progress^.progress_monitor (j_common_ptr(cinfo)); + end; + + { Verify that at least one iMCU row can be returned. } + lines_per_iMCU_row := cinfo^.max_v_samp_factor * cinfo^.min_DCT_scaled_size; + if (max_lines < lines_per_iMCU_row) then + ERREXIT(j_common_ptr(cinfo), JERR_BUFFER_SIZE); + + { Decompress directly into user's buffer. } + if (cinfo^.coef^.decompress_data (cinfo, data) = 0) then + begin + jpeg_read_raw_data := 0; { suspension forced, can do nothing more } + exit; + end; + + { OK, we processed one iMCU row. } + Inc(cinfo^.output_scanline, lines_per_iMCU_row); + jpeg_read_raw_data := lines_per_iMCU_row; +end; + + +{ Additional entry points for buffered-image mode. } + +{$ifdef D_MULTISCAN_FILES_SUPPORTED} + +{ Initialize for an output pass in buffered-image mode. } + +{GLOBAL} +function jpeg_start_output (cinfo : j_decompress_ptr; + scan_number : int) : boolean; +begin + if (cinfo^.global_state <> DSTATE_BUFIMAGE) and + (cinfo^.global_state <> DSTATE_PRESCAN) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + { Limit scan number to valid range } + if (scan_number <= 0) then + scan_number := 1; + if (cinfo^.inputctl^.eoi_reached) and + (scan_number > cinfo^.input_scan_number) then + scan_number := cinfo^.input_scan_number; + cinfo^.output_scan_number := scan_number; + { Perform any dummy output passes, and set up for the real pass } + jpeg_start_output := output_pass_setup(cinfo); +end; + + +{ Finish up after an output pass in buffered-image mode. + + Returns FALSE if suspended. The return value need be inspected only if + a suspending data source is used. } + +{GLOBAL} +function jpeg_finish_output (cinfo : j_decompress_ptr) : boolean; +begin + if ((cinfo^.global_state = DSTATE_SCANNING) or + (cinfo^.global_state = DSTATE_RAW_OK) and cinfo^.buffered_image) then + begin + { Terminate this pass. } + { We do not require the whole pass to have been completed. } + cinfo^.master^.finish_output_pass (cinfo); + cinfo^.global_state := DSTATE_BUFPOST; + end + else + if (cinfo^.global_state <> DSTATE_BUFPOST) then + begin + { BUFPOST := repeat call after a suspension, anything else is error } + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + end; + { Read markers looking for SOS or EOI } + while (cinfo^.input_scan_number <= cinfo^.output_scan_number) and + (not cinfo^.inputctl^.eoi_reached) do + begin + if (cinfo^.inputctl^.consume_input (cinfo) = JPEG_SUSPENDED) then + begin + jpeg_finish_output := FALSE; { Suspend, come back later } + exit; + end; + end; + cinfo^.global_state := DSTATE_BUFIMAGE; + jpeg_finish_output := TRUE; +end; + +{$endif} { D_MULTISCAN_FILES_SUPPORTED } + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jdatadst_del.pas b/mseide-msegui/lib/common/fpccompatibility/jdatadst_del.pas new file mode 100644 index 0000000..ba10154 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jdatadst_del.pas @@ -0,0 +1,172 @@ +Unit jdatadst_del; + +{ This file contains compression data destination routines for the case of + emitting JPEG data to a file (or any stdio stream). While these routines + are sufficient for most applications, some will want to use a different + destination manager. + IMPORTANT: we assume that fwrite() will correctly transcribe an array of + JOCTETs into 8-bit-wide elements on external storage. If char is wider + than 8 bits on your machine, you may need to do some tweaking. } + +{ Original : jdatadst.c ; Copyright (C) 1994-1996, Thomas G. Lane. } + +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +{ this is not a core library module, so it doesn't define JPEG_INTERNALS } +uses + jmorecfg_del, + jpeglib_del, + jinclude_del, + jdeferr_del, + jerror_del; + +{ Prepare for output to a stdio stream. + The caller must have already opened the stream, and is responsible + for closing it after finishing compression. } + +{GLOBAL} +procedure jpeg_stdio_dest (cinfo : j_compress_ptr; outfile : FILEptr); + +implementation + +{ Expanded data destination object for stdio output } + +type + my_dest_ptr = ^my_destination_mgr; + my_destination_mgr = record + pub : jpeg_destination_mgr; { public fields } + + outfile : FILEPTR; { target stream } + buffer : JOCTET_FIELD_PTR; { start of buffer } + end; {my_destination_mgr;} + + +const + OUTPUT_BUF_SIZE = 4096; { choose an efficiently fwrite'able size } + + +{ Initialize destination --- called by jpeg_start_compress + before any data is actually written. } + +{METHODDEF} +procedure init_destination (cinfo : j_compress_ptr); +var + dest : my_dest_ptr; +begin + dest := my_dest_ptr(cinfo^.dest); + + { Allocate the output buffer --- it will be released when done with image } + dest^.buffer := JOCTET_FIELD_PTR( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + OUTPUT_BUF_SIZE * SIZEOF(JOCTET)) ); + + dest^.pub.next_output_byte := JOCTETptr(dest^.buffer); + dest^.pub.free_in_buffer := OUTPUT_BUF_SIZE; +end; + + +{ Empty the output buffer --- called whenever buffer fills up. + + In typical applications, this should write the entire output buffer + (ignoring the current state of next_output_byte & free_in_buffer), + reset the pointer & count to the start of the buffer, and return TRUE + indicating that the buffer has been dumped. + + In applications that need to be able to suspend compression due to output + overrun, a FALSE return indicates that the buffer cannot be emptied now. + In this situation, the compressor will return to its caller (possibly with + an indication that it has not accepted all the supplied scanlines). The + application should resume compression after it has made more room in the + output buffer. Note that there are substantial restrictions on the use of + suspension --- see the documentation. + + When suspending, the compressor will back up to a convenient restart point + (typically the start of the current MCU). next_output_byte & free_in_buffer + indicate where the restart point will be if the current call returns FALSE. + Data beyond this point will be regenerated after resumption, so do not + write it out when emptying the buffer externally. } + +{METHODDEF} +function empty_output_buffer (cinfo : j_compress_ptr) : boolean; +var + dest : my_dest_ptr; +begin + dest := my_dest_ptr(cinfo^.dest); + + if (JFWRITE(dest^.outfile, dest^.buffer, OUTPUT_BUF_SIZE) <> + size_t(OUTPUT_BUF_SIZE)) then + ERREXIT(j_common_ptr(cinfo), JERR_FILE_WRITE); + + dest^.pub.next_output_byte := JOCTETptr(dest^.buffer); + dest^.pub.free_in_buffer := OUTPUT_BUF_SIZE; + + empty_output_buffer := TRUE; +end; + + +{ Terminate destination --- called by jpeg_finish_compress + after all data has been written. Usually needs to flush buffer. + + NB: *not* called by jpeg_abort or jpeg_destroy; surrounding + application must deal with any cleanup that should happen even + for error exit. } + +{METHODDEF} +procedure term_destination (cinfo : j_compress_ptr); +var + dest : my_dest_ptr; + datacount : size_t; +begin + dest := my_dest_ptr (cinfo^.dest); + datacount := OUTPUT_BUF_SIZE - dest^.pub.free_in_buffer; + + { Write any data remaining in the buffer } + if (datacount > 0) then + begin + if (JFWRITE(dest^.outfile, dest^.buffer, datacount) <> datacount) then + ERREXIT(j_common_ptr(cinfo), JERR_FILE_WRITE); + end; + {fflush(dest^.outfile^);} + + { Make sure we wrote the output file OK } + {if (ferror(dest^.outfile)) + ERREXIT(cinfo, JERR_FILE_WRITE);} + if IOresult <> 0 then + ERREXIT(j_common_ptr(cinfo), JERR_FILE_WRITE); +end; + + +{ Prepare for output to a stdio stream. + The caller must have already opened the stream, and is responsible + for closing it after finishing compression. } + +{GLOBAL} +procedure jpeg_stdio_dest (cinfo : j_compress_ptr; outfile : FILEptr); +var + dest : my_dest_ptr; +begin + { The destination object is made permanent so that multiple JPEG images + can be written to the same file without re-executing jpeg_stdio_dest. + This makes it dangerous to use this manager and a different destination + manager serially with the same JPEG object, because their private object + sizes may be different. Caveat programmer. } + + if (cinfo^.dest = NIL) then + begin { first time for this JPEG object? } + cinfo^.dest := jpeg_destination_mgr_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_PERMANENT, + SIZEOF(my_destination_mgr)) ); + end; + + dest := my_dest_ptr (cinfo^.dest); + dest^.pub.init_destination := init_destination; + dest^.pub.empty_output_buffer := empty_output_buffer; + dest^.pub.term_destination := term_destination; + dest^.outfile := outfile; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jdatasrc_del.pas b/mseide-msegui/lib/common/fpccompatibility/jdatasrc_del.pas new file mode 100644 index 0000000..fe41bea --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jdatasrc_del.pas @@ -0,0 +1,225 @@ +unit jdatasrc_del; + +{ This file contains decompression data source routines for the case of + reading JPEG data from a file (or any stdio stream). While these routines + are sufficient for most applications, some will want to use a different + source manager. + IMPORTANT: we assume that fread() will correctly transcribe an array of + JOCTETs from 8-bit-wide elements on external storage. If char is wider + than 8 bits on your machine, you may need to do some tweaking. } + +{ jdatasrc.c ; Copyright (C) 1994-1996, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +{ this is not a core library module, so it doesn't define JPEG_INTERNALS } +uses + jmorecfg_del, + jinclude_del, + jpeglib_del, + jdmarker_del, + jdeferr_del, + jerror_del; + + +{ Prepare for input from a stdio stream. + The caller must have already opened the stream, and is responsible + for closing it after finishing decompression. } + +{GLOBAL} +procedure jpeg_stdio_src (cinfo : j_decompress_ptr; infile : FILEptr); + +implementation + +{ Expanded data source object for stdio input } + +type + my_src_ptr = ^my_source_mgr; + my_source_mgr = record + pub : jpeg_source_mgr; { public fields } + + infile : FILEPTR; { source stream } + buffer : JOCTET_FIELD_PTR; { start of buffer } + start_of_file : boolean; { have we gotten any data yet? } + end; {my_source_mgr;} + +const + INPUT_BUF_SIZE = 4096; { choose an efficiently fread'able size } + + +{ Initialize source --- called by jpeg_read_header + before any data is actually read. } + +{METHODDEF} +procedure init_source (cinfo : j_decompress_ptr); +var + src : my_src_ptr; +begin + src := my_src_ptr (cinfo^.src); + + { We reset the empty-input-file flag for each image, + but we don't clear the input buffer. + This is correct behavior for reading a series of images from one source. } + src^.start_of_file := TRUE; +end; + + +{ Fill the input buffer --- called whenever buffer is emptied. + + In typical applications, this should read fresh data into the buffer + (ignoring the current state of next_input_byte & bytes_in_buffer), + reset the pointer & count to the start of the buffer, and return TRUE + indicating that the buffer has been reloaded. It is not necessary to + fill the buffer entirely, only to obtain at least one more byte. + + There is no such thing as an EOF return. If the end of the file has been + reached, the routine has a choice of ERREXIT() or inserting fake data into + the buffer. In most cases, generating a warning message and inserting a + fake EOI marker is the best course of action --- this will allow the + decompressor to output however much of the image is there. However, + the resulting error message is misleading if the real problem is an empty + input file, so we handle that case specially. + + In applications that need to be able to suspend compression due to input + not being available yet, a FALSE return indicates that no more data can be + obtained right now, but more may be forthcoming later. In this situation, + the decompressor will return to its caller (with an indication of the + number of scanlines it has read, if any). The application should resume + decompression after it has loaded more data into the input buffer. Note + that there are substantial restrictions on the use of suspension --- see + the documentation. + + When suspending, the decompressor will back up to a convenient restart point + (typically the start of the current MCU). next_input_byte & bytes_in_buffer + indicate where the restart point will be if the current call returns FALSE. + Data beyond this point must be rescanned after resumption, so move it to + the front of the buffer rather than discarding it. } + +{METHODDEF} +function fill_input_buffer (cinfo : j_decompress_ptr) : boolean; +var + src : my_src_ptr; + nbytes : size_t; +begin + src := my_src_ptr(cinfo^.src); + nbytes := JFREAD(src^.infile, src^.buffer, INPUT_BUF_SIZE); + + if (nbytes <= 0) then + begin + if (src^.start_of_file) then { Treat empty input file as fatal error } + ERREXIT(j_common_ptr(cinfo), JERR_INPUT_EMPTY); + WARNMS(j_common_ptr(cinfo), JWRN_JPEG_EOF); + { Insert a fake EOI marker } + src^.buffer^[0] := JOCTET ($FF); + src^.buffer^[1] := JOCTET (JPEG_EOI); + nbytes := 2; + end; + + src^.pub.next_input_byte := JOCTETptr(src^.buffer); + src^.pub.bytes_in_buffer := nbytes; + src^.start_of_file := FALSE; + + fill_input_buffer := TRUE; +end; + + +{ Skip data --- used to skip over a potentially large amount of + uninteresting data (such as an APPn marker). + + Writers of suspendable-input applications must note that skip_input_data + is not granted the right to give a suspension return. If the skip extends + beyond the data currently in the buffer, the buffer can be marked empty so + that the next read will cause a fill_input_buffer call that can suspend. + Arranging for additional bytes to be discarded before reloading the input + buffer is the application writer's problem. } + +{METHODDEF} +procedure skip_input_data (cinfo : j_decompress_ptr; + num_bytes : long); +var + src : my_src_ptr; +begin + src := my_src_ptr (cinfo^.src); + + { Just a dumb implementation for now. Could use fseek() except + it doesn't work on pipes. Not clear that being smart is worth + any trouble anyway --- large skips are infrequent. } + + if (num_bytes > 0) then + begin + while (num_bytes > long(src^.pub.bytes_in_buffer)) do + begin + Dec(num_bytes, long(src^.pub.bytes_in_buffer)); + {void} fill_input_buffer(cinfo); + { note we assume that fill_input_buffer will never return FALSE, + so suspension need not be handled. } + end; + Inc( src^.pub.next_input_byte, size_t(num_bytes) ); + Dec( src^.pub.bytes_in_buffer, size_t(num_bytes) ); + end; +end; + + +{ An additional method that can be provided by data source modules is the + resync_to_restart method for error recovery in the presence of RST markers. + For the moment, this source module just uses the default resync method + provided by the JPEG library. That method assumes that no backtracking + is possible. } + + +{ Terminate source --- called by jpeg_finish_decompress + after all data has been read. Often a no-op. + + NB: *not* called by jpeg_abort or jpeg_destroy; surrounding + application must deal with any cleanup that should happen even + for error exit. } + +{METHODDEF} +procedure term_source (cinfo : j_decompress_ptr); +begin + { no work necessary here } +end; + + +{ Prepare for input from a stdio stream. + The caller must have already opened the stream, and is responsible + for closing it after finishing decompression. } + +{GLOBAL} +procedure jpeg_stdio_src (cinfo : j_decompress_ptr; infile : FILEptr); +var + src : my_src_ptr; +begin + { The source object and input buffer are made permanent so that a series + of JPEG images can be read from the same file by calling jpeg_stdio_src + only before the first one. (If we discarded the buffer at the end of + one image, we'd likely lose the start of the next one.) + This makes it unsafe to use this manager and a different source + manager serially with the same JPEG object. Caveat programmer. } + + if (cinfo^.src = NIL) then + begin { first time for this JPEG object? } + cinfo^.src := jpeg_source_mgr_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_PERMANENT, + SIZEOF(my_source_mgr)) ); + src := my_src_ptr (cinfo^.src); + src^.buffer := JOCTET_FIELD_PTR( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_PERMANENT, + INPUT_BUF_SIZE * SIZEOF(JOCTET)) ); + end; + + src := my_src_ptr (cinfo^.src); + src^.pub.init_source := init_source; + src^.pub.fill_input_buffer := fill_input_buffer; + src^.pub.skip_input_data := skip_input_data; + src^.pub.resync_to_restart := jpeg_resync_to_restart; { use default method } + src^.pub.term_source := term_source; + src^.infile := infile; + src^.pub.bytes_in_buffer := 0; { forces fill_input_buffer on first read } + src^.pub.next_input_byte := NIL; { until buffer loaded } +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jdcoefct_del.pas b/mseide-msegui/lib/common/fpccompatibility/jdcoefct_del.pas new file mode 100644 index 0000000..e8acba3 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jdcoefct_del.pas @@ -0,0 +1,898 @@ +unit jdcoefct_del; + +{ This file contains the coefficient buffer controller for decompression. + This controller is the top level of the JPEG decompressor proper. + The coefficient buffer lies between entropy decoding and inverse-DCT steps. + + In buffered-image mode, this controller is the interface between + input-oriented processing and output-oriented processing. + Also, the input side (only) is used when reading a file for transcoding. } + +{ Original: jdcoefct.c ; Copyright (C) 1994-1997, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +{$I jconfig_del.inc} + +interface + +uses + jmorecfg_del, + jinclude_del, + jdeferr_del, + jerror_del, + jutils_del, + jpeglib_del; + + +{GLOBAL} +procedure jinit_d_coef_controller (cinfo : j_decompress_ptr; + need_full_buffer : boolean); + + +implementation + + +{ Block smoothing is only applicable for progressive JPEG, so: } +{$ifndef D_PROGRESSIVE_SUPPORTED} +{$undef BLOCK_SMOOTHING_SUPPORTED} +{$endif} + +{ Private buffer controller object } + +{$ifdef BLOCK_SMOOTHING_SUPPORTED} +const + SAVED_COEFS = 6; { we save coef_bits[0..5] } +type + Latch = array[0..SAVED_COEFS-1] of int; + Latch_ptr = ^Latch; +{$endif} + +type + my_coef_ptr = ^my_coef_controller; + my_coef_controller = record + pub : jpeg_d_coef_controller; { public fields } + + { These variables keep track of the current location of the input side. } + { cinfo^.input_iMCU_row is also used for this. } + MCU_ctr : JDIMENSION; { counts MCUs processed in current row } + MCU_vert_offset : int; { counts MCU rows within iMCU row } + MCU_rows_per_iMCU_row : int; { number of such rows needed } + + { The output side's location is represented by cinfo^.output_iMCU_row. } + + { In single-pass modes, it's sufficient to buffer just one MCU. + We allocate a workspace of D_MAX_BLOCKS_IN_MCU coefficient blocks, + and let the entropy decoder write into that workspace each time. + (On 80x86, the workspace is FAR even though it's not really very big; + this is to keep the module interfaces unchanged when a large coefficient + buffer is necessary.) + In multi-pass modes, this array points to the current MCU's blocks + within the virtual arrays; it is used only by the input side. } + + MCU_buffer : array[0..D_MAX_BLOCKS_IN_MCU-1] of JBLOCKROW; + + {$ifdef D_MULTISCAN_FILES_SUPPORTED} + { In multi-pass modes, we need a virtual block array for each component. } + whole_image : jvirt_barray_tbl; + {$endif} + + {$ifdef BLOCK_SMOOTHING_SUPPORTED} + { When doing block smoothing, we latch coefficient Al values here } + coef_bits_latch : Latch_Ptr; + {$endif} + end; + +{ Forward declarations } +{METHODDEF} +function decompress_onepass (cinfo : j_decompress_ptr; + output_buf : JSAMPIMAGE) : int; forward; +{$ifdef D_MULTISCAN_FILES_SUPPORTED} +{METHODDEF} +function decompress_data (cinfo : j_decompress_ptr; + output_buf : JSAMPIMAGE) : int; forward; +{$endif} +{$ifdef BLOCK_SMOOTHING_SUPPORTED} +{LOCAL} +function smoothing_ok (cinfo : j_decompress_ptr) : boolean; forward; + +{METHODDEF} +function decompress_smooth_data (cinfo : j_decompress_ptr; + output_buf : JSAMPIMAGE) : int; forward; +{$endif} + + +{LOCAL} +procedure start_iMCU_row (cinfo : j_decompress_ptr); +{ Reset within-iMCU-row counters for a new row (input side) } +var + coef : my_coef_ptr; +begin + coef := my_coef_ptr (cinfo^.coef); + + { In an interleaved scan, an MCU row is the same as an iMCU row. + In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows. + But at the bottom of the image, process only what's left. } + + if (cinfo^.comps_in_scan > 1) then + begin + coef^.MCU_rows_per_iMCU_row := 1; + end + else + begin + if (cinfo^.input_iMCU_row < (cinfo^.total_iMCU_rows-1)) then + coef^.MCU_rows_per_iMCU_row := cinfo^.cur_comp_info[0]^.v_samp_factor + else + coef^.MCU_rows_per_iMCU_row := cinfo^.cur_comp_info[0]^.last_row_height; + end; + + coef^.MCU_ctr := 0; + coef^.MCU_vert_offset := 0; +end; + + +{ Initialize for an input processing pass. } + +{METHODDEF} +procedure start_input_pass (cinfo : j_decompress_ptr); +begin + cinfo^.input_iMCU_row := 0; + start_iMCU_row(cinfo); +end; + + +{ Initialize for an output processing pass. } + +{METHODDEF} +procedure start_output_pass (cinfo : j_decompress_ptr); +var + coef : my_coef_ptr; +begin +{$ifdef BLOCK_SMOOTHING_SUPPORTED} + coef := my_coef_ptr (cinfo^.coef); + + { If multipass, check to see whether to use block smoothing on this pass } + if (coef^.pub.coef_arrays <> NIL) then + begin + if (cinfo^.do_block_smoothing) and smoothing_ok(cinfo) then + coef^.pub.decompress_data := decompress_smooth_data + else + coef^.pub.decompress_data := decompress_data; + end; +{$endif} + cinfo^.output_iMCU_row := 0; +end; + + +{ Decompress and return some data in the single-pass case. + Always attempts to emit one fully interleaved MCU row ("iMCU" row). + Input and output must run in lockstep since we have only a one-MCU buffer. + Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED. + + NB: output_buf contains a plane for each component in image, + which we index according to the component's SOF position.} + +{METHODDEF} +function decompress_onepass (cinfo : j_decompress_ptr; + output_buf : JSAMPIMAGE) : int; +var + coef : my_coef_ptr; + MCU_col_num : JDIMENSION; { index of current MCU within row } + last_MCU_col : JDIMENSION; + last_iMCU_row : JDIMENSION; + blkn, ci, xindex, yindex, yoffset, useful_width : int; + output_ptr : JSAMPARRAY; + start_col, output_col : JDIMENSION; + compptr : jpeg_component_info_ptr; + inverse_DCT : inverse_DCT_method_ptr; +begin + coef := my_coef_ptr (cinfo^.coef); + last_MCU_col := cinfo^.MCUs_per_row - 1; + last_iMCU_row := cinfo^.total_iMCU_rows - 1; + + { Loop to process as much as one whole iMCU row } + for yoffset := coef^.MCU_vert_offset to pred(coef^.MCU_rows_per_iMCU_row) do + begin + for MCU_col_num := coef^.MCU_ctr to last_MCU_col do + begin + { Try to fetch an MCU. Entropy decoder expects buffer to be zeroed. } + jzero_far( coef^.MCU_buffer[0], + size_t (cinfo^.blocks_in_MCU * SIZEOF(JBLOCK))); + if (not cinfo^.entropy^.decode_mcu (cinfo, coef^.MCU_buffer)) then + begin + { Suspension forced; update state counters and exit } + coef^.MCU_vert_offset := yoffset; + coef^.MCU_ctr := MCU_col_num; + decompress_onepass := JPEG_SUSPENDED; + exit; + end; + { Determine where data should go in output_buf and do the IDCT thing. + We skip dummy blocks at the right and bottom edges (but blkn gets + incremented past them!). Note the inner loop relies on having + allocated the MCU_buffer[] blocks sequentially. } + + blkn := 0; { index of current DCT block within MCU } + for ci := 0 to pred(cinfo^.comps_in_scan) do + begin + compptr := cinfo^.cur_comp_info[ci]; + { Don't bother to IDCT an uninteresting component. } + if (not compptr^.component_needed) then + begin + Inc(blkn, compptr^.MCU_blocks); + continue; + end; + inverse_DCT := cinfo^.idct^.inverse_DCT[compptr^.component_index]; + if (MCU_col_num < last_MCU_col) then + useful_width := compptr^.MCU_width + else + useful_width := compptr^.last_col_width; + + output_ptr := JSAMPARRAY(@ output_buf^[compptr^.component_index]^ + [yoffset * compptr^.DCT_scaled_size]); + start_col := MCU_col_num * compptr^.MCU_sample_width; + for yindex := 0 to pred(compptr^.MCU_height) do + begin + if (cinfo^.input_iMCU_row < last_iMCU_row) or + (yoffset+yindex < compptr^.last_row_height) then + begin + output_col := start_col; + for xindex := 0 to pred(useful_width) do + begin + inverse_DCT (cinfo, compptr, + JCOEFPTR(coef^.MCU_buffer[blkn+xindex]), + output_ptr, output_col); + Inc(output_col, compptr^.DCT_scaled_size); + end; + end; + Inc(blkn, compptr^.MCU_width); + Inc(JSAMPROW_PTR(output_ptr), compptr^.DCT_scaled_size); + end; + end; + end; + { Completed an MCU row, but perhaps not an iMCU row } + coef^.MCU_ctr := 0; + end; + { Completed the iMCU row, advance counters for next one } + Inc(cinfo^.output_iMCU_row); + + Inc(cinfo^.input_iMCU_row); + if (cinfo^.input_iMCU_row < cinfo^.total_iMCU_rows) then + begin + start_iMCU_row(cinfo); + decompress_onepass := JPEG_ROW_COMPLETED; + exit; + end; + { Completed the scan } + cinfo^.inputctl^.finish_input_pass (cinfo); + decompress_onepass := JPEG_SCAN_COMPLETED; +end; + +{ Dummy consume-input routine for single-pass operation. } + +{METHODDEF} +function dummy_consume_data (cinfo : j_decompress_ptr) : int; +begin + dummy_consume_data := JPEG_SUSPENDED; { Always indicate nothing was done } +end; + + +{$ifdef D_MULTISCAN_FILES_SUPPORTED} + +{ Consume input data and store it in the full-image coefficient buffer. + We read as much as one fully interleaved MCU row ("iMCU" row) per call, + ie, v_samp_factor block rows for each component in the scan. + Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.} + +{METHODDEF} +function consume_data (cinfo : j_decompress_ptr) : int; +var + coef : my_coef_ptr; + MCU_col_num : JDIMENSION; { index of current MCU within row } + blkn, ci, xindex, yindex, yoffset : int; + start_col : JDIMENSION; + buffer : array[0..MAX_COMPS_IN_SCAN-1] of JBLOCKARRAY; + buffer_ptr : JBLOCKROW; + compptr : jpeg_component_info_ptr; +begin + coef := my_coef_ptr (cinfo^.coef); + + { Align the virtual buffers for the components used in this scan. } + for ci := 0 to pred(cinfo^.comps_in_scan) do + begin + compptr := cinfo^.cur_comp_info[ci]; + buffer[ci] := cinfo^.mem^.access_virt_barray + (j_common_ptr (cinfo), coef^.whole_image[compptr^.component_index], + cinfo^.input_iMCU_row * compptr^.v_samp_factor, + JDIMENSION (compptr^.v_samp_factor), TRUE); + { Note: entropy decoder expects buffer to be zeroed, + but this is handled automatically by the memory manager + because we requested a pre-zeroed array. } + + end; + + { Loop to process one whole iMCU row } + for yoffset := coef^.MCU_vert_offset to pred(coef^.MCU_rows_per_iMCU_row) do + begin + for MCU_col_num := coef^.MCU_ctr to pred(cinfo^.MCUs_per_row) do + begin + { Construct list of pointers to DCT blocks belonging to this MCU } + blkn := 0; { index of current DCT block within MCU } + for ci := 0 to pred(cinfo^.comps_in_scan) do + begin + compptr := cinfo^.cur_comp_info[ci]; + start_col := MCU_col_num * compptr^.MCU_width; + for yindex := 0 to pred(compptr^.MCU_height) do + begin +{$warnings off} + buffer_ptr := JBLOCKROW(@ buffer[ci]^[yindex+yoffset]^[start_col]); + for xindex := 0 to pred(compptr^.MCU_width) do + begin + coef^.MCU_buffer[blkn] := buffer_ptr; + Inc(blkn); + Inc(JBLOCK_PTR(buffer_ptr)); + end; + end; + end; + { Try to fetch the MCU. } + if (not cinfo^.entropy^.decode_mcu (cinfo, coef^.MCU_buffer)) then + begin + { Suspension forced; update state counters and exit } + coef^.MCU_vert_offset := yoffset; + coef^.MCU_ctr := MCU_col_num; + consume_data := JPEG_SUSPENDED; + exit; + end; + end; + { Completed an MCU row, but perhaps not an iMCU row } + coef^.MCU_ctr := 0; + end; + { Completed the iMCU row, advance counters for next one } + Inc(cinfo^.input_iMCU_row); + if (cinfo^.input_iMCU_row < cinfo^.total_iMCU_rows) then + begin + start_iMCU_row(cinfo); + consume_data := JPEG_ROW_COMPLETED; + exit; + end; + { Completed the scan } + cinfo^.inputctl^.finish_input_pass (cinfo); + consume_data := JPEG_SCAN_COMPLETED; +end; +{$warnings on} + +{ Decompress and return some data in the multi-pass case. + Always attempts to emit one fully interleaved MCU row ("iMCU" row). + Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED. + + NB: output_buf contains a plane for each component in image. } + +{METHODDEF} +function decompress_data (cinfo : j_decompress_ptr; + output_buf : JSAMPIMAGE) : int; +var + coef : my_coef_ptr; + last_iMCU_row : JDIMENSION; + block_num : JDIMENSION; + ci, block_row, block_rows : int; + buffer : JBLOCKARRAY; + buffer_ptr : JBLOCKROW; + output_ptr : JSAMPARRAY; + output_col : JDIMENSION; + compptr : jpeg_component_info_ptr; + inverse_DCT : inverse_DCT_method_ptr; +begin + coef := my_coef_ptr (cinfo^.coef); + last_iMCU_row := cinfo^.total_iMCU_rows - 1; + + { Force some input to be done if we are getting ahead of the input. } + while (cinfo^.input_scan_number < cinfo^.output_scan_number) or + ((cinfo^.input_scan_number = cinfo^.output_scan_number) and + (cinfo^.input_iMCU_row <= cinfo^.output_iMCU_row)) do + begin + if (cinfo^.inputctl^.consume_input(cinfo) = JPEG_SUSPENDED) then + begin + decompress_data := JPEG_SUSPENDED; + exit; + end; + end; + + { OK, output from the virtual arrays. } + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + { Don't bother to IDCT an uninteresting component. } + if (not compptr^.component_needed) then + continue; + { Align the virtual buffer for this component. } + buffer := cinfo^.mem^.access_virt_barray + (j_common_ptr (cinfo), coef^.whole_image[ci], + cinfo^.output_iMCU_row * compptr^.v_samp_factor, + JDIMENSION (compptr^.v_samp_factor), FALSE); + { Count non-dummy DCT block rows in this iMCU row. } + if (cinfo^.output_iMCU_row < last_iMCU_row) then + block_rows := compptr^.v_samp_factor + else + begin + { NB: can't use last_row_height here; it is input-side-dependent! } + block_rows := int(compptr^.height_in_blocks mod compptr^.v_samp_factor); + if (block_rows = 0) then + block_rows := compptr^.v_samp_factor; + end; + inverse_DCT := cinfo^.idct^.inverse_DCT[ci]; + output_ptr := output_buf^[ci]; + { Loop over all DCT blocks to be processed. } + for block_row := 0 to pred(block_rows) do + begin + buffer_ptr := buffer^[block_row]; + output_col := 0; + for block_num := 0 to pred(compptr^.width_in_blocks) do + begin + inverse_DCT (cinfo, compptr, JCOEFPTR (buffer_ptr), + output_ptr, output_col); + Inc(JBLOCK_PTR(buffer_ptr)); + Inc(output_col, compptr^.DCT_scaled_size); + end; + Inc(JSAMPROW_PTR(output_ptr), compptr^.DCT_scaled_size); + end; + Inc(compptr); + end; + + Inc(cinfo^.output_iMCU_row); + if (cinfo^.output_iMCU_row < cinfo^.total_iMCU_rows) then + begin + decompress_data := JPEG_ROW_COMPLETED; + exit; + end; + decompress_data := JPEG_SCAN_COMPLETED; +end; + +{$endif} { D_MULTISCAN_FILES_SUPPORTED } + + +{$ifdef BLOCK_SMOOTHING_SUPPORTED} + +{ This code applies interblock smoothing as described by section K.8 + of the JPEG standard: the first 5 AC coefficients are estimated from + the DC values of a DCT block and its 8 neighboring blocks. + We apply smoothing only for progressive JPEG decoding, and only if + the coefficients it can estimate are not yet known to full precision. } + +{ Natural-order array positions of the first 5 zigzag-order coefficients } +const + Q01_POS = 1; + Q10_POS = 8; + Q20_POS = 16; + Q11_POS = 9; + Q02_POS = 2; + +{ Determine whether block smoothing is applicable and safe. + We also latch the current states of the coef_bits[] entries for the + AC coefficients; otherwise, if the input side of the decompressor + advances into a new scan, we might think the coefficients are known + more accurately than they really are. } + +{LOCAL} +function smoothing_ok (cinfo : j_decompress_ptr) : boolean; +var + coef : my_coef_ptr; + smoothing_useful : boolean; + ci, coefi : int; + compptr : jpeg_component_info_ptr; + qtable : JQUANT_TBL_PTR; + coef_bits : coef_bits_ptr; + coef_bits_latch : Latch_Ptr; +begin + coef := my_coef_ptr (cinfo^.coef); + smoothing_useful := FALSE; + + if (not cinfo^.progressive_mode) or (cinfo^.coef_bits = NIL) then + begin + smoothing_ok := FALSE; + exit; + end; + + { Allocate latch area if not already done } + if (coef^.coef_bits_latch = NIL) then + coef^.coef_bits_latch := Latch_Ptr( + cinfo^.mem^.alloc_small (j_common_ptr (cinfo), JPOOL_IMAGE, + cinfo^.num_components * + (SAVED_COEFS * SIZEOF(int))) ); + coef_bits_latch := (coef^.coef_bits_latch); + + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + { All components' quantization values must already be latched. } + qtable := compptr^.quant_table; + if (qtable = NIL) then + begin + smoothing_ok := FALSE; + exit; + end; + { Verify DC & first 5 AC quantizers are nonzero to avoid zero-divide. } + if (qtable^.quantval[0] = 0) or + (qtable^.quantval[Q01_POS] = 0) or + (qtable^.quantval[Q10_POS] = 0) or + (qtable^.quantval[Q20_POS] = 0) or + (qtable^.quantval[Q11_POS] = 0) or + (qtable^.quantval[Q02_POS] = 0) then + begin + smoothing_ok := FALSE; + exit; + end; + { DC values must be at least partly known for all components. } + coef_bits := @cinfo^.coef_bits^[ci]; { Nomssi } + if (coef_bits^[0] < 0) then + begin + smoothing_ok := FALSE; + exit; + end; + { Block smoothing is helpful if some AC coefficients remain inaccurate. } + for coefi := 1 to 5 do + begin + coef_bits_latch^[coefi] := coef_bits^[coefi]; + if (coef_bits^[coefi] <> 0) then + smoothing_useful := TRUE; + end; + Inc(coef_bits_latch {SAVED_COEFS}); + Inc(compptr); + end; + + smoothing_ok := smoothing_useful; +end; + + +{ Variant of decompress_data for use when doing block smoothing. } + +{METHODDEF} +function decompress_smooth_data (cinfo : j_decompress_ptr; + output_buf : JSAMPIMAGE) : int; +var + coef : my_coef_ptr; + last_iMCU_row : JDIMENSION; + block_num, last_block_column : JDIMENSION; + ci, block_row, block_rows, access_rows : int; + buffer : JBLOCKARRAY; + buffer_ptr, prev_block_row, next_block_row : JBLOCKROW; + output_ptr : JSAMPARRAY; + output_col : JDIMENSION; + compptr : jpeg_component_info_ptr; + inverse_DCT : inverse_DCT_method_ptr; + first_row, last_row : boolean; + workspace : JBLOCK; + coef_bits : Latch_Ptr; { coef_bits_ptr; } + quanttbl : JQUANT_TBL_PTR; + Q00,Q01,Q02,Q10,Q11,Q20, num : INT32; + DC1,DC2,DC3,DC4,DC5,DC6,DC7,DC8,DC9 : int; + Al, pred : int; +var + delta : JDIMENSION; +begin + coef := my_coef_ptr (cinfo^.coef); + last_iMCU_row := cinfo^.total_iMCU_rows - 1; + + { Force some input to be done if we are getting ahead of the input. } + while (cinfo^.input_scan_number <= cinfo^.output_scan_number) and + (not cinfo^.inputctl^.eoi_reached) do + begin + if (cinfo^.input_scan_number = cinfo^.output_scan_number) then + begin + { If input is working on current scan, we ordinarily want it to + have completed the current row. But if input scan is DC, + we want it to keep one row ahead so that next block row's DC + values are up to date. } + + if (cinfo^.Ss = 0) then + delta := 1 + else + delta := 0; + if (cinfo^.input_iMCU_row > cinfo^.output_iMCU_row+delta) then + break; + end; + if (cinfo^.inputctl^.consume_input(cinfo) = JPEG_SUSPENDED) then + begin + decompress_smooth_data := JPEG_SUSPENDED; + exit; + end; + end; + + { OK, output from the virtual arrays. } + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to (cinfo^.num_components-1) do + begin + { Don't bother to IDCT an uninteresting component. } + if (not compptr^.component_needed) then + continue; + { Count non-dummy DCT block rows in this iMCU row. } + if (cinfo^.output_iMCU_row < last_iMCU_row) then + begin + block_rows := compptr^.v_samp_factor; + access_rows := block_rows * 2; { this and next iMCU row } + last_row := FALSE; + end + else + begin + { NB: can't use last_row_height here; it is input-side-dependent! } + block_rows := int (compptr^.height_in_blocks mod compptr^.v_samp_factor); + if (block_rows = 0) then + block_rows := compptr^.v_samp_factor; + access_rows := block_rows; { this iMCU row only } + last_row := TRUE; + end; + { Align the virtual buffer for this component. } + if (cinfo^.output_iMCU_row > 0) then + begin + Inc(access_rows, compptr^.v_samp_factor); { prior iMCU row too } + buffer := cinfo^.mem^.access_virt_barray + (j_common_ptr (cinfo), coef^.whole_image[ci], + (cinfo^.output_iMCU_row - 1) * compptr^.v_samp_factor, + JDIMENSION (access_rows), FALSE); + Inc(JBLOCKROW_PTR(buffer), compptr^.v_samp_factor); { point to current iMCU row } + first_row := FALSE; + end + else + begin + buffer := cinfo^.mem^.access_virt_barray + (j_common_ptr (cinfo), coef^.whole_image[ci], + JDIMENSION (0), JDIMENSION (access_rows), FALSE); + first_row := TRUE; + end; + { Fetch component-dependent info } + coef_bits := coef^.coef_bits_latch; + Inc(coef_bits, ci); { ci * SAVED_COEFS} + quanttbl := compptr^.quant_table; + Q00 := quanttbl^.quantval[0]; + Q01 := quanttbl^.quantval[Q01_POS]; + Q10 := quanttbl^.quantval[Q10_POS]; + Q20 := quanttbl^.quantval[Q20_POS]; + Q11 := quanttbl^.quantval[Q11_POS]; + Q02 := quanttbl^.quantval[Q02_POS]; + inverse_DCT := cinfo^.idct^.inverse_DCT[ci]; + output_ptr := output_buf^[ci]; + { Loop over all DCT blocks to be processed. } + for block_row := 0 to (block_rows-1) do + begin + buffer_ptr := buffer^[block_row]; + if (first_row) and (block_row = 0) then + prev_block_row := buffer_ptr + else + prev_block_row := buffer^[block_row-1]; + if (last_row) and (block_row = block_rows-1) then + next_block_row := buffer_ptr + else + next_block_row := buffer^[block_row+1]; + { We fetch the surrounding DC values using a sliding-register approach. + Initialize all nine here so as to do the right thing on narrow pics.} + + DC3 := int(prev_block_row^[0][0]); + DC2 := DC3; + DC1 := DC2; + DC6 := int(buffer_ptr^[0][0]); + DC5 := DC6; + DC4 := DC5; + DC9 := int(next_block_row^[0][0]); + DC8 := DC9; + DC7 := DC8 ; + output_col := 0; + last_block_column := compptr^.width_in_blocks - 1; + for block_num := 0 to last_block_column do + begin + { Fetch current DCT block into workspace so we can modify it. } + jcopy_block_row(buffer_ptr, JBLOCKROW (@workspace), JDIMENSION(1)); + { Update DC values } + if (block_num < last_block_column) then + begin + DC3 := int (prev_block_row^[1][0]); + DC6 := int (buffer_ptr^[1][0]); + DC9 := int (next_block_row^[1][0]); + end; + { Compute coefficient estimates per K.8. + An estimate is applied only if coefficient is still zero, + and is not known to be fully accurate. } + + { AC01 } + Al := coef_bits^[1]; + if (Al <> 0) and (workspace[1] = 0) then + begin + num := 36 * Q00 * (DC4 - DC6); + if (num >= 0) then + begin + pred := int (((Q01 shl 7) + num) div (Q01 shl 8)); + if (Al > 0) and (pred >= (1 shl Al)) then + pred := (1 shl Al)-1; + end + else + begin + pred := int (((Q01 shl 7) - num) div (Q01 shl 8)); + if (Al > 0) and (pred >= (1 shl Al)) then + pred := (1 shl Al)-1; + pred := -pred; + end; + workspace[1] := JCOEF (pred); + end; + { AC10 } + Al := coef_bits^[2]; + if (Al <> 0) and (workspace[8] = 0) then + begin + num := 36 * Q00 * (DC2 - DC8); + if (num >= 0) then + begin + pred := int (((Q10 shl 7) + num) div (Q10 shl 8)); + if (Al > 0) and (pred >= (1 shl Al)) then + pred := (1 shl Al)-1; + end + else + begin + pred := int (((Q10 shl 7) - num) div (Q10 shl 8)); + if (Al > 0) and (pred >= (1 shl Al)) then + pred := (1 shl Al)-1; + pred := -pred; + end; + workspace[8] := JCOEF (pred); + end; + { AC20 } + Al := coef_bits^[3]; + if (Al <> 0) and (workspace[16] = 0) then + begin + num := 9 * Q00 * (DC2 + DC8 - 2*DC5); + if (num >= 0) then + begin + pred := int (((Q20 shl 7) + num) div (Q20 shl 8)); + if (Al > 0) and (pred >= (1 shl Al)) then + pred := (1 shl Al)-1; + end + else + begin + pred := int (((Q20 shl 7) - num) div (Q20 shl 8)); + if (Al > 0) and (pred >= (1 shl Al)) then + pred := (1 shl Al)-1; + pred := -pred; + end; + workspace[16] := JCOEF (pred); + end; + { AC11 } + Al := coef_bits^[4]; + if (Al <> 0) and (workspace[9] = 0) then + begin + num := 5 * Q00 * (DC1 - DC3 - DC7 + DC9); + if (num >= 0) then + begin + pred := int (((Q11 shl 7) + num) div (Q11 shl 8)); + if (Al > 0) and (pred >= (1 shl Al)) then + pred := (1 shl Al)-1; + end + else + begin + pred := int (((Q11 shl 7) - num) div (Q11 shl 8)); + if (Al > 0) and (pred >= (1 shl Al)) then + pred := (1 shl Al)-1; + pred := -pred; + end; + workspace[9] := JCOEF (pred); + end; + { AC02 } + Al := coef_bits^[5]; + if (Al <> 0) and (workspace[2] = 0) then + begin + num := 9 * Q00 * (DC4 + DC6 - 2*DC5); + if (num >= 0) then + begin + pred := int (((Q02 shl 7) + num) div (Q02 shl 8)); + if (Al > 0) and (pred >= (1 shl Al)) then + pred := (1 shl Al)-1; + end + else + begin + pred := int (((Q02 shl 7) - num) div (Q02 shl 8)); + if (Al > 0) and (pred >= (1 shl Al)) then + pred := (1 shl Al)-1; + pred := -pred; + end; + workspace[2] := JCOEF (pred); + end; + { OK, do the IDCT } + inverse_DCT (cinfo, compptr, JCOEFPTR (@workspace), + output_ptr, output_col); + { Advance for next column } + DC1 := DC2; DC2 := DC3; + DC4 := DC5; DC5 := DC6; + DC7 := DC8; DC8 := DC9; + Inc(JBLOCK_PTR(buffer_ptr)); + Inc(JBLOCK_PTR(prev_block_row)); + Inc(JBLOCK_PTR(next_block_row)); + Inc(output_col, compptr^.DCT_scaled_size); + end; + Inc(JSAMPROW_PTR(output_ptr), compptr^.DCT_scaled_size); + end; + Inc(compptr); + end; + + Inc(cinfo^.output_iMCU_row); + if (cinfo^.output_iMCU_row < cinfo^.total_iMCU_rows) then + begin + decompress_smooth_data := JPEG_ROW_COMPLETED; + exit; + end; + decompress_smooth_data := JPEG_SCAN_COMPLETED; +end; + +{$endif} { BLOCK_SMOOTHING_SUPPORTED } + + +{ Initialize coefficient buffer controller. } + +{GLOBAL} +procedure jinit_d_coef_controller (cinfo : j_decompress_ptr; + need_full_buffer : boolean); +var + coef : my_coef_ptr; +{$ifdef D_MULTISCAN_FILES_SUPPORTED} +var + ci, access_rows : int; + compptr : jpeg_component_info_ptr; +{$endif} +var + buffer : JBLOCK_PTR; + i : int; +begin + coef := my_coef_ptr( + cinfo^.mem^.alloc_small (j_common_ptr (cinfo), JPOOL_IMAGE, + SIZEOF(my_coef_controller)) ); + cinfo^.coef := jpeg_d_coef_controller_ptr(coef); + coef^.pub.start_input_pass := start_input_pass; + coef^.pub.start_output_pass := start_output_pass; +{$ifdef BLOCK_SMOOTHING_SUPPORTED} + coef^.coef_bits_latch := NIL; +{$endif} + + { Create the coefficient buffer. } + if (need_full_buffer) then + begin +{$ifdef D_MULTISCAN_FILES_SUPPORTED} + { Allocate a full-image virtual array for each component, } + { padded to a multiple of samp_factor DCT blocks in each direction. } + { Note we ask for a pre-zeroed array. } + + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + access_rows := compptr^.v_samp_factor; +{$ifdef BLOCK_SMOOTHING_SUPPORTED} + { If block smoothing could be used, need a bigger window } + if (cinfo^.progressive_mode) then + access_rows := access_rows * 3; +{$endif} + coef^.whole_image[ci] := cinfo^.mem^.request_virt_barray + (j_common_ptr (cinfo), JPOOL_IMAGE, TRUE, + JDIMENSION (jround_up( long(compptr^.width_in_blocks), + long(compptr^.h_samp_factor) )), + JDIMENSION (jround_up( long(compptr^.height_in_blocks), + long(compptr^.v_samp_factor) )), + JDIMENSION (access_rows)); + Inc(compptr); + end; + coef^.pub.consume_data := consume_data; + coef^.pub.decompress_data := decompress_data; + coef^.pub.coef_arrays := @(coef^.whole_image); + { link to virtual arrays } +{$else} + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); +{$endif} + end + else + begin + { We only need a single-MCU buffer. } + buffer := JBLOCK_PTR ( + cinfo^.mem^.alloc_large (j_common_ptr (cinfo), JPOOL_IMAGE, + D_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)) ); + for i := 0 to pred(D_MAX_BLOCKS_IN_MCU) do + begin + coef^.MCU_buffer[i] := JBLOCKROW(buffer); + Inc(buffer); + end; + coef^.pub.consume_data := dummy_consume_data; + coef^.pub.decompress_data := decompress_onepass; + coef^.pub.coef_arrays := NIL; { flag for no virtual arrays } + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jdcolor_del.pas b/mseide-msegui/lib/common/fpccompatibility/jdcolor_del.pas new file mode 100644 index 0000000..6896f90 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jdcolor_del.pas @@ -0,0 +1,502 @@ +unit jdcolor_del; + +{ This file contains output colorspace conversion routines. } + +{ Original: jdcolor.c ; Copyright (C) 1991-1997, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jutils_del, + jdeferr_del, + jerror_del, + jpeglib_del; + +{ Module initialization routine for output colorspace conversion. } + +{GLOBAL} +procedure jinit_color_deconverter (cinfo : j_decompress_ptr); + +implementation + +{ Private subobject } +type + int_Color_Table = array[0..MAXJSAMPLE+1-1] of int; + int_table_ptr = ^int_Color_Table; + INT32_Color_Table = array[0..MAXJSAMPLE+1-1] of INT32; + INT32_table_ptr = ^INT32_Color_Table; +type + my_cconvert_ptr = ^my_color_deconverter; + my_color_deconverter = record + pub : jpeg_color_deconverter; { public fields } + + { Private state for YCC^.RGB conversion } + Cr_r_tab : int_table_ptr; { => table for Cr to R conversion } + Cb_b_tab : int_table_ptr; { => table for Cb to B conversion } + Cr_g_tab : INT32_table_ptr; { => table for Cr to G conversion } + Cb_g_tab : INT32_table_ptr; { => table for Cb to G conversion } + end; + + + + +{*************** YCbCr ^. RGB conversion: most common case *************} + +{ YCbCr is defined per CCIR 601-1, except that Cb and Cr are + normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5. + The conversion equations to be implemented are therefore + R = Y + 1.40200 * Cr + G = Y - 0.34414 * Cb - 0.71414 * Cr + B = Y + 1.77200 * Cb + where Cb and Cr represent the incoming values less CENTERJSAMPLE. + (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.) + + To avoid floating-point arithmetic, we represent the fractional constants + as integers scaled up by 2^16 (about 4 digits precision); we have to divide + the products by 2^16, with appropriate rounding, to get the correct answer. + Notice that Y, being an integral input, does not contribute any fraction + so it need not participate in the rounding. + + For even more speed, we avoid doing any multiplications in the inner loop + by precalculating the constants times Cb and Cr for all possible values. + For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table); + for 12-bit samples it is still acceptable. It's not very reasonable for + 16-bit samples, but if you want lossless storage you shouldn't be changing + colorspace anyway. + The Cr=>R and Cb=>B values can be rounded to integers in advance; the + values for the G calculation are left scaled up, since we must add them + together before rounding. } + +const + SCALEBITS = 16; { speediest right-shift on some machines } + ONE_HALF = (INT32(1) shl (SCALEBITS-1)); + + +{ Initialize tables for YCC->RGB colorspace conversion. } + +{LOCAL} +procedure build_ycc_rgb_table (cinfo : j_decompress_ptr); +const + FIX_1_40200 = INT32(Round( 1.40200 * (1 shl SCALEBITS))); + FIX_1_77200 = INT32(Round( 1.77200 * (1 shl SCALEBITS))); + FIX_0_71414 = INT32(Round( 0.71414 * (1 shl SCALEBITS))); + FIX_0_34414 = INT32(Round( 0.34414 * (1 shl SCALEBITS))); + +var + cconvert : my_cconvert_ptr; + i : int; + x : INT32; +var + shift_temp : INT32; +begin + cconvert := my_cconvert_ptr (cinfo^.cconvert); + + + cconvert^.Cr_r_tab := int_table_ptr( + cinfo^.mem^.alloc_small ( j_common_ptr(cinfo), JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(int)) ); + cconvert^.Cb_b_tab := int_table_ptr ( + cinfo^.mem^.alloc_small ( j_common_ptr(cinfo), JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(int)) ); + cconvert^.Cr_g_tab := INT32_table_ptr ( + cinfo^.mem^.alloc_small ( j_common_ptr(cinfo), JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(INT32)) ); + cconvert^.Cb_g_tab := INT32_table_ptr ( + cinfo^.mem^.alloc_small ( j_common_ptr(cinfo), JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(INT32)) ); + + + x := -CENTERJSAMPLE; + for i := 0 to MAXJSAMPLE do + begin + { i is the actual input pixel value, in the range 0..MAXJSAMPLE } + { The Cb or Cr value we are thinking of is x := i - CENTERJSAMPLE } + { Cr=>R value is nearest int to 1.40200 * x } + + shift_temp := FIX_1_40200 * x + ONE_HALF; + if shift_temp < 0 then { SHIFT arithmetic RIGHT } + cconvert^.Cr_r_tab^[i] := int((shift_temp shr SCALEBITS) + or ( (not INT32(0)) shl (32-SCALEBITS))) + else + cconvert^.Cr_r_tab^[i] := int(shift_temp shr SCALEBITS); + + { Cb=>B value is nearest int to 1.77200 * x } + shift_temp := FIX_1_77200 * x + ONE_HALF; + if shift_temp < 0 then { SHIFT arithmetic RIGHT } + cconvert^.Cb_b_tab^[i] := int((shift_temp shr SCALEBITS) + or ( (not INT32(0)) shl (32-SCALEBITS))) + else + cconvert^.Cb_b_tab^[i] := int(shift_temp shr SCALEBITS); + + { Cr=>G value is scaled-up -0.71414 * x } + cconvert^.Cr_g_tab^[i] := (- FIX_0_71414 ) * x; + { Cb=>G value is scaled-up -0.34414 * x } + { We also add in ONE_HALF so that need not do it in inner loop } + cconvert^.Cb_g_tab^[i] := (- FIX_0_34414 ) * x + ONE_HALF; + Inc(x); + end; +end; + + +{ Convert some rows of samples to the output colorspace. + + Note that we change from noninterleaved, one-plane-per-component format + to interleaved-pixel format. The output buffer is therefore three times + as wide as the input buffer. + A starting row offset is provided only for the input buffer. The caller + can easily adjust the passed output_buf value to accommodate any row + offset required on that side. } + +{METHODDEF} +procedure ycc_rgb_convert (cinfo : j_decompress_ptr; + input_buf : JSAMPIMAGE; + input_row : JDIMENSION; + output_buf : JSAMPARRAY; + num_rows : int); +var + cconvert : my_cconvert_ptr; + {register} y, cb, cr : int; + {register} outptr : JSAMPROW; + {register} inptr0, inptr1, inptr2 : JSAMPROW; + {register} col : JDIMENSION; + num_cols : JDIMENSION; + { copy these pointers into registers if possible } + {register} range_limit : range_limit_table_ptr; + {register} Crrtab : int_table_ptr; + {register} Cbbtab : int_table_ptr; + {register} Crgtab : INT32_table_ptr; + {register} Cbgtab : INT32_table_ptr; +var + shift_temp : INT32; +begin + cconvert := my_cconvert_ptr (cinfo^.cconvert); + num_cols := cinfo^.output_width; + range_limit := cinfo^.sample_range_limit; + Crrtab := cconvert^.Cr_r_tab; + Cbbtab := cconvert^.Cb_b_tab; + Crgtab := cconvert^.Cr_g_tab; + Cbgtab := cconvert^.Cb_g_tab; + + while (num_rows > 0) do + begin + Dec(num_rows); + inptr0 := input_buf^[0]^[input_row]; + inptr1 := input_buf^[1]^[input_row]; + inptr2 := input_buf^[2]^[input_row]; + Inc(input_row); + outptr := output_buf^[0]; + Inc(JSAMPROW_PTR(output_buf)); + for col := 0 to pred(num_cols) do + begin + y := GETJSAMPLE(inptr0^[col]); + cb := GETJSAMPLE(inptr1^[col]); + cr := GETJSAMPLE(inptr2^[col]); + { Range-limiting is essential due to noise introduced by DCT losses. } + outptr^[RGB_RED] := range_limit^[y + Crrtab^[cr]]; + shift_temp := Cbgtab^[cb] + Crgtab^[cr]; + if shift_temp < 0 then { SHIFT arithmetic RIGHT } + outptr^[RGB_GREEN] := range_limit^[y + int((shift_temp shr SCALEBITS) + or ( (not INT32(0)) shl (32-SCALEBITS)))] + else + outptr^[RGB_GREEN] := range_limit^[y + int(shift_temp shr SCALEBITS)]; + + outptr^[RGB_BLUE] := range_limit^[y + Cbbtab^[cb]]; + Inc(JSAMPLE_PTR(outptr), RGB_PIXELSIZE); + end; + end; +end; + + +{*************** Cases other than YCbCr -> RGB *************} + + +{ Color conversion for no colorspace change: just copy the data, + converting from separate-planes to interleaved representation. } + +{METHODDEF} +procedure null_convert (cinfo : j_decompress_ptr; + input_buf : JSAMPIMAGE; + input_row : JDIMENSION; + output_buf : JSAMPARRAY; + num_rows : int); +var + {register} inptr, + outptr : JSAMPLE_PTR; + {register} count : JDIMENSION; + {register} num_components : int; + num_cols : JDIMENSION; + ci : int; +begin + num_components := cinfo^.num_components; + num_cols := cinfo^.output_width; + + while (num_rows > 0) do + begin + Dec(num_rows); + for ci := 0 to pred(num_components) do + begin + inptr := JSAMPLE_PTR(input_buf^[ci]^[input_row]); + outptr := JSAMPLE_PTR(@(output_buf^[0]^[ci])); + + for count := pred(num_cols) downto 0 do + begin + outptr^ := inptr^; { needn't bother with GETJSAMPLE() here } + Inc(inptr); + Inc(outptr, num_components); + end; + end; + Inc(input_row); + Inc(JSAMPROW_PTR(output_buf)); + end; +end; + + +{ Color conversion for grayscale: just copy the data. + This also works for YCbCr -> grayscale conversion, in which + we just copy the Y (luminance) component and ignore chrominance. } + +{METHODDEF} +procedure grayscale_convert (cinfo : j_decompress_ptr; + input_buf : JSAMPIMAGE; + input_row : JDIMENSION; + output_buf : JSAMPARRAY; + num_rows : int); +begin + jcopy_sample_rows(input_buf^[0], int(input_row), output_buf, 0, + num_rows, cinfo^.output_width); +end; + +{ Convert grayscale to RGB: just duplicate the graylevel three times. + This is provided to support applications that don't want to cope + with grayscale as a separate case. } + +{METHODDEF} +procedure gray_rgb_convert (cinfo : j_decompress_ptr; + input_buf : JSAMPIMAGE; + input_row : JDIMENSION; + output_buf : JSAMPARRAY; + num_rows : int); +var + {register} inptr, outptr : JSAMPLE_PTR; + {register} col : JDIMENSION; + num_cols : JDIMENSION; +begin + num_cols := cinfo^.output_width; + while (num_rows > 0) do + begin + inptr := JSAMPLE_PTR(input_buf^[0]^[input_row]); + Inc(input_row); + outptr := JSAMPLE_PTR(@output_buf^[0]); + Inc(JSAMPROW_PTR(output_buf)); + for col := 0 to pred(num_cols) do + begin + { We can dispense with GETJSAMPLE() here } + JSAMPROW(outptr)^[RGB_RED] := inptr^; + JSAMPROW(outptr)^[RGB_GREEN] := inptr^; + JSAMPROW(outptr)^[RGB_BLUE] := inptr^; + Inc(inptr); + Inc(outptr, RGB_PIXELSIZE); + end; + Dec(num_rows); + end; +end; + + +{ Adobe-style YCCK -> CMYK conversion. + We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same + conversion as above, while passing K (black) unchanged. + We assume build_ycc_rgb_table has been called. } + +{METHODDEF} +procedure ycck_cmyk_convert (cinfo : j_decompress_ptr; + input_buf : JSAMPIMAGE; + input_row : JDIMENSION; + output_buf : JSAMPARRAY; + num_rows : int); +var + cconvert : my_cconvert_ptr; + {register} y, cb, cr : int; + {register} outptr : JSAMPROW; + {register} inptr0, inptr1, inptr2, inptr3 : JSAMPROW; + {register} col : JDIMENSION; + num_cols : JDIMENSION; + { copy these pointers into registers if possible } + {register} range_limit : range_limit_table_ptr; + {register} Crrtab : int_table_ptr; + {register} Cbbtab : int_table_ptr; + {register} Crgtab : INT32_table_ptr; + {register} Cbgtab : INT32_table_ptr; +var + shift_temp : INT32; +begin + cconvert := my_cconvert_ptr (cinfo^.cconvert); + num_cols := cinfo^.output_width; + { copy these pointers into registers if possible } + range_limit := cinfo^.sample_range_limit; + Crrtab := cconvert^.Cr_r_tab; + Cbbtab := cconvert^.Cb_b_tab; + Crgtab := cconvert^.Cr_g_tab; + Cbgtab := cconvert^.Cb_g_tab; + + while (num_rows > 0) do + begin + Dec(num_rows); + inptr0 := input_buf^[0]^[input_row]; + inptr1 := input_buf^[1]^[input_row]; + inptr2 := input_buf^[2]^[input_row]; + inptr3 := input_buf^[3]^[input_row]; + Inc(input_row); + outptr := output_buf^[0]; + Inc(JSAMPROW_PTR(output_buf)); + for col := 0 to pred(num_cols) do + begin + y := GETJSAMPLE(inptr0^[col]); + cb := GETJSAMPLE(inptr1^[col]); + cr := GETJSAMPLE(inptr2^[col]); + { Range-limiting is essential due to noise introduced by DCT losses. } + outptr^[0] := range_limit^[MAXJSAMPLE - (y + Crrtab^[cr])]; { red } + shift_temp := Cbgtab^[cb] + Crgtab^[cr]; + if shift_temp < 0 then + outptr^[1] := range_limit^[MAXJSAMPLE - (y + int( + (shift_temp shr SCALEBITS) or ((not INT32(0)) shl (32-SCALEBITS)) + ) )] + else + outptr^[1] := range_limit^[MAXJSAMPLE - { green } + (y + int(shift_temp shr SCALEBITS) )]; + outptr^[2] := range_limit^[MAXJSAMPLE - (y + Cbbtab^[cb])]; { blue } + { K passes through unchanged } + outptr^[3] := inptr3^[col]; { don't need GETJSAMPLE here } + Inc(JSAMPLE_PTR(outptr), 4); + end; + end; +end; + + +{ Empty method for start_pass. } + +{METHODDEF} +procedure start_pass_dcolor (cinfo : j_decompress_ptr); +begin + { no work needed } +end; + + +{ Module initialization routine for output colorspace conversion. } + +{GLOBAL} +procedure jinit_color_deconverter (cinfo : j_decompress_ptr); +var + cconvert : my_cconvert_ptr; + ci : int; +begin + cconvert := my_cconvert_ptr ( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(my_color_deconverter)) ); + cinfo^.cconvert := jpeg_color_deconverter_ptr (cconvert); + cconvert^.pub.start_pass := start_pass_dcolor; + + { Make sure num_components agrees with jpeg_color_space } + case (cinfo^.jpeg_color_space) of + JCS_GRAYSCALE: + if (cinfo^.num_components <> 1) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_J_COLORSPACE); + + JCS_RGB, + JCS_YCbCr: + if (cinfo^.num_components <> 3) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_J_COLORSPACE); + + JCS_CMYK, + JCS_YCCK: + if (cinfo^.num_components <> 4) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_J_COLORSPACE); + + else { JCS_UNKNOWN can be anything } + if (cinfo^.num_components < 1) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_J_COLORSPACE); + end; + + { Set out_color_components and conversion method based on requested space. + Also clear the component_needed flags for any unused components, + so that earlier pipeline stages can avoid useless computation. } + + case (cinfo^.out_color_space) of + JCS_GRAYSCALE: + begin + cinfo^.out_color_components := 1; + if (cinfo^.jpeg_color_space = JCS_GRAYSCALE) + or (cinfo^.jpeg_color_space = JCS_YCbCr) then + begin + cconvert^.pub.color_convert := grayscale_convert; + { For color -> grayscale conversion, only the + Y (0) component is needed } + for ci := 1 to pred(cinfo^.num_components) do + cinfo^.comp_info^[ci].component_needed := FALSE; + end + else + ERREXIT(j_common_ptr(cinfo), JERR_CONVERSION_NOTIMPL); + end; + + JCS_RGB: + begin + cinfo^.out_color_components := RGB_PIXELSIZE; + if (cinfo^.jpeg_color_space = JCS_YCbCr) then + begin + cconvert^.pub.color_convert := ycc_rgb_convert; + build_ycc_rgb_table(cinfo); + end + else + if (cinfo^.jpeg_color_space = JCS_GRAYSCALE) then + begin + cconvert^.pub.color_convert := gray_rgb_convert; + end + else + if (cinfo^.jpeg_color_space = JCS_RGB) and (RGB_PIXELSIZE = 3) then + begin + cconvert^.pub.color_convert := null_convert; + end + else + ERREXIT(j_common_ptr(cinfo), JERR_CONVERSION_NOTIMPL); + end; + + JCS_CMYK: + begin + cinfo^.out_color_components := 4; + if (cinfo^.jpeg_color_space = JCS_YCCK) then + begin + cconvert^.pub.color_convert := ycck_cmyk_convert; + build_ycc_rgb_table(cinfo); + end + else + if (cinfo^.jpeg_color_space = JCS_CMYK) then + begin + cconvert^.pub.color_convert := null_convert; + end + else + ERREXIT(j_common_ptr(cinfo), JERR_CONVERSION_NOTIMPL); + end; + + else + begin { Permit null conversion to same output space } + if (cinfo^.out_color_space = cinfo^.jpeg_color_space) then + begin + cinfo^.out_color_components := cinfo^.num_components; + cconvert^.pub.color_convert := null_convert; + end + else { unsupported non-null conversion } + ERREXIT(j_common_ptr(cinfo), JERR_CONVERSION_NOTIMPL); + end; + end; + + if (cinfo^.quantize_colors) then + cinfo^.output_components := 1 { single colormapped output component } + else + cinfo^.output_components := cinfo^.out_color_components; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jdct_del.pas b/mseide-msegui/lib/common/fpccompatibility/jdct_del.pas new file mode 100644 index 0000000..04e92b8 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jdct_del.pas @@ -0,0 +1,110 @@ +unit jdct_del; + +{ Orignal: jdct.h; Copyright (C) 1994-1996, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +{ This include file contains common declarations for the forward and + inverse DCT modules. These declarations are private to the DCT managers + (jcdctmgr.c, jddctmgr.c) and the individual DCT algorithms. + The individual DCT algorithms are kept in separate files to ease + machine-dependent tuning (e.g., assembly coding). } + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del; + + +{ A forward DCT routine is given a pointer to a work area of type DCTELEM[]; + the DCT is to be performed in-place in that buffer. Type DCTELEM is int + for 8-bit samples, INT32 for 12-bit samples. (NOTE: Floating-point DCT + implementations use an array of type FAST_FLOAT, instead.) + The DCT inputs are expected to be signed (range +-CENTERJSAMPLE). + The DCT outputs are returned scaled up by a factor of 8; they therefore + have a range of +-8K for 8-bit data, +-128K for 12-bit data. This + convention improves accuracy in integer implementations and saves some + work in floating-point ones. + Quantization of the output coefficients is done by jcdctmgr.c. } + + +{$ifdef BITS_IN_JSAMPLE_IS_8} +type + DCTELEM = int; { 16 or 32 bits is fine } +{$else} +type { must have 32 bits } + DCTELEM = INT32; +{$endif} +type + jTDctElem = 0..(MaxInt div SizeOf(DCTELEM))-1; + DCTELEM_FIELD = array[jTDctElem] of DCTELEM; + DCTELEM_FIELD_PTR = ^DCTELEM_FIELD; + DCTELEMPTR = ^DCTELEM; + +type + forward_DCT_method_ptr = procedure(var data : array of DCTELEM); + float_DCT_method_ptr = procedure(var data : array of FAST_FLOAT); + + +{ An inverse DCT routine is given a pointer to the input JBLOCK and a pointer + to an output sample array. The routine must dequantize the input data as + well as perform the IDCT; for dequantization, it uses the multiplier table + pointed to by compptr->dct_table. The output data is to be placed into the + sample array starting at a specified column. (Any row offset needed will + be applied to the array pointer before it is passed to the IDCT code.) + Note that the number of samples emitted by the IDCT routine is + DCT_scaled_size * DCT_scaled_size. } + + +{ typedef inverse_DCT_method_ptr is declared in jpegint.h } + + +{ Each IDCT routine has its own ideas about the best dct_table element type. } + + +type + ISLOW_MULT_TYPE = MULTIPLIER; { short or int, whichever is faster } + +{$ifdef BITS_IN_JSAMPLE_IS_8} +type + IFAST_MULT_TYPE = MULTIPLIER; { 16 bits is OK, use short if faster } +const + IFAST_SCALE_BITS = 2; { fractional bits in scale factors } +{$else} +type + IFAST_MULT_TYPE = INT32; { need 32 bits for scaled quantizers } +const + IFAST_SCALE_BITS = 13; { fractional bits in scale factors } +{$endif} +type + FLOAT_MULT_TYPE = FAST_FLOAT; { preferred floating type } + +const + RANGE_MASK = (MAXJSAMPLE * 4 + 3); { 2 bits wider than legal samples } + +type + jTMultType = 0..(MaxInt div SizeOf(ISLOW_MULT_TYPE))-1; + ISLOW_MULT_TYPE_FIELD = array[jTMultType] of ISLOW_MULT_TYPE; + ISLOW_MULT_TYPE_FIELD_PTR = ^ISLOW_MULT_TYPE_FIELD; + ISLOW_MULT_TYPE_PTR = ^ISLOW_MULT_TYPE; + + jTFloatType = 0..(MaxInt div SizeOf(FLOAT_MULT_TYPE))-1; + FLOAT_MULT_TYPE_FIELD = array[jTFloatType] of FLOAT_MULT_TYPE; + FLOAT_MULT_TYPE_FIELD_PTR = ^FLOAT_MULT_TYPE_FIELD; + FLOAT_MULT_TYPE_PTR = ^FLOAT_MULT_TYPE; + + jTFastType = 0..(MaxInt div SizeOf(IFAST_MULT_TYPE))-1; + IFAST_MULT_TYPE_FIELD = array[jTFastType] of IFAST_MULT_TYPE; + IFAST_MULT_TYPE_FIELD_PTR = ^IFAST_MULT_TYPE_FIELD; + IFAST_MULT_TYPE_PTR = ^IFAST_MULT_TYPE; + +type + jTFastFloat = 0..(MaxInt div SizeOf(FAST_FLOAT))-1; + FAST_FLOAT_FIELD = array[jTFastFloat] of FAST_FLOAT; + FAST_FLOAT_FIELD_PTR = ^FAST_FLOAT_FIELD; + FAST_FLOAT_PTR = ^FAST_FLOAT; + +implementation + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jddctmgr_del.pas b/mseide-msegui/lib/common/fpccompatibility/jddctmgr_del.pas new file mode 100644 index 0000000..0535cbf --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jddctmgr_del.pas @@ -0,0 +1,330 @@ +unit jddctmgr_del; + +{ Original : jddctmgr.c ; Copyright (C) 1994-1996, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +{ This file contains the inverse-DCT management logic. + This code selects a particular IDCT implementation to be used, + and it performs related housekeeping chores. No code in this file + is executed per IDCT step, only during output pass setup. + + Note that the IDCT routines are responsible for performing coefficient + dequantization as well as the IDCT proper. This module sets up the + dequantization multiplier table needed by the IDCT routine. } + +interface + +{$I jconfig_del.inc} + +//{$N+} + +uses + jmorecfg_del, + jinclude_del, + jdeferr_del, + jerror_del, + jpeglib_del, + jdct_del, { Private declarations for DCT subsystem } + jidctfst_del, + {$IFDEF BASM} + jidctasm_del, + {$ELSE} + jidctint_del, + {$ENDIF} + jidctflt_del, jidctred_del; + + + +{ Initialize IDCT manager. } + +{GLOBAL} +procedure jinit_inverse_dct (cinfo : j_decompress_ptr); + + +implementation + +{ The decompressor input side (jdinput.c) saves away the appropriate + quantization table for each component at the start of the first scan + involving that component. (This is necessary in order to correctly + decode files that reuse Q-table slots.) + When we are ready to make an output pass, the saved Q-table is converted + to a multiplier table that will actually be used by the IDCT routine. + The multiplier table contents are IDCT-method-dependent. To support + application changes in IDCT method between scans, we can remake the + multiplier tables if necessary. + In buffered-image mode, the first output pass may occur before any data + has been seen for some components, and thus before their Q-tables have + been saved away. To handle this case, multiplier tables are preset + to zeroes; the result of the IDCT will be a neutral gray level. } + + +{ Private subobject for this module } + +type + my_idct_ptr = ^my_idct_controller; + my_idct_controller = record + pub : jpeg_inverse_dct; { public fields } + + { This array contains the IDCT method code that each multiplier table + is currently set up for, or -1 if it's not yet set up. + The actual multiplier tables are pointed to by dct_table in the + per-component comp_info structures. } + + cur_method : array[0..MAX_COMPONENTS-1] of int; + end; {my_idct_controller;} + + +{ Allocated multiplier tables: big enough for any supported variant } + +type + multiplier_table = record + case byte of + 0:(islow_array : array[0..DCTSIZE2-1] of ISLOW_MULT_TYPE); + {$ifdef DCT_IFAST_SUPPORTED} + 1:(ifast_array : array[0..DCTSIZE2-1] of IFAST_MULT_TYPE); + {$endif} + {$ifdef DCT_FLOAT_SUPPORTED} + 2:(float_array : array[0..DCTSIZE2-1] of FLOAT_MULT_TYPE); + {$endif} + end; + + +{ The current scaled-IDCT routines require ISLOW-style multiplier tables, + so be sure to compile that code if either ISLOW or SCALING is requested. } + +{$ifdef DCT_ISLOW_SUPPORTED} + {$define PROVIDE_ISLOW_TABLES} +{$else} + {$ifdef IDCT_SCALING_SUPPORTED} + {$define PROVIDE_ISLOW_TABLES} + {$endif} +{$endif} + + +{ Prepare for an output pass. + Here we select the proper IDCT routine for each component and build + a matching multiplier table. } + +{METHODDEF} +procedure start_pass (cinfo : j_decompress_ptr); +var + idct : my_idct_ptr; + ci, i : int; + compptr : jpeg_component_info_ptr; + method : J_DCT_METHOD; + method_ptr : inverse_DCT_method_ptr; + qtbl : JQUANT_TBL_PTR; +{$ifdef PROVIDE_ISLOW_TABLES} +var + ismtbl : ISLOW_MULT_TYPE_FIELD_PTR; +{$endif} +{$ifdef DCT_IFAST_SUPPORTED} +const + CONST_BITS = 14; +const + aanscales : array[0..DCTSIZE2-1] of INT16 = + ({ precomputed values scaled up by 14 bits } + 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, + 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270, + 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906, + 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315, + 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, + 12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552, + 8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446, + 4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247); +var + ifmtbl : IFAST_MULT_TYPE_FIELD_PTR; + {SHIFT_TEMPS} + + { Descale and correctly round an INT32 value that's scaled by N bits. + We assume RIGHT_SHIFT rounds towards minus infinity, so adding + the fudge factor is correct for either sign of X. } + + function DESCALE(x : INT32; n : int) : INT32; + var + shift_temp : INT32; + begin + {$ifdef RIGHT_SHIFT_IS_UNSIGNED} + shift_temp := x + (INT32(1) shl (n-1)); + if shift_temp < 0 then + Descale := (shift_temp shr n) or ((not INT32(0)) shl (32-n)) + else + Descale := (shift_temp shr n); + {$else} + Descale := (x + (INT32(1) shl (n-1)) shr n; + {$endif} + end; + +{$endif} +{$ifdef DCT_FLOAT_SUPPORTED} +const + aanscalefactor : array[0..DCTSIZE-1] of double = + (1.0, 1.387039845, 1.306562965, 1.175875602, + 1.0, 0.785694958, 0.541196100, 0.275899379); +var + fmtbl : FLOAT_MULT_TYPE_FIELD_PTR; + row, col : int; +{$endif} +begin + idct := my_idct_ptr (cinfo^.idct); + method := J_DCT_METHOD(0); + method_ptr := NIL; + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + + for ci := 0 to pred(cinfo^.num_components) do + begin + { Select the proper IDCT routine for this component's scaling } + case (compptr^.DCT_scaled_size) of +{$ifdef IDCT_SCALING_SUPPORTED} + 1:begin + method_ptr := jpeg_idct_1x1; + method := JDCT_ISLOW; { jidctred uses islow-style table } + end; + 2:begin + method_ptr := jpeg_idct_2x2; + method := JDCT_ISLOW; { jidctred uses islow-style table } + end; + 4:begin + method_ptr := jpeg_idct_4x4; + method := JDCT_ISLOW; { jidctred uses islow-style table } + end; +{$endif} + DCTSIZE: + case (cinfo^.dct_method) of +{$ifdef DCT_ISLOW_SUPPORTED} + JDCT_ISLOW: + begin + method_ptr := jpeg_idct_islow; + method := JDCT_ISLOW; + end; +{$endif} +{$ifdef DCT_IFAST_SUPPORTED} + JDCT_IFAST: + begin + method_ptr := jpeg_idct_ifast; + method := JDCT_IFAST; + end; +{$endif} +{$ifdef DCT_FLOAT_SUPPORTED} + JDCT_FLOAT: + begin + method_ptr := jpeg_idct_float; + method := JDCT_FLOAT; + end; +{$endif} + else + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); + end; + else + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_DCTSIZE, compptr^.DCT_scaled_size); + end; + idct^.pub.inverse_DCT[ci] := method_ptr; + { Create multiplier table from quant table. + However, we can skip this if the component is uninteresting + or if we already built the table. Also, if no quant table + has yet been saved for the component, we leave the + multiplier table all-zero; we'll be reading zeroes from the + coefficient controller's buffer anyway. } + + if (not compptr^.component_needed) or (idct^.cur_method[ci] = int(method)) then + continue; + qtbl := compptr^.quant_table; + if (qtbl = NIL) then { happens if no data yet for component } + continue; + idct^.cur_method[ci] := int(method); + case (method) of +{$ifdef PROVIDE_ISLOW_TABLES} + JDCT_ISLOW: + begin + { For LL&M IDCT method, multipliers are equal to raw quantization + coefficients, but are stored as ints to ensure access efficiency. } + + ismtbl := ISLOW_MULT_TYPE_FIELD_PTR (compptr^.dct_table); + for i := 0 to pred(DCTSIZE2) do + begin + ismtbl^[i] := ISLOW_MULT_TYPE (qtbl^.quantval[i]); + end; + end; +{$endif} +{$ifdef DCT_IFAST_SUPPORTED} + JDCT_IFAST: + begin + { For AA&N IDCT method, multipliers are equal to quantization + coefficients scaled by scalefactor[row]*scalefactor[col], where + scalefactor[0] := 1 + scalefactor[k] := cos(k*PI/16) * sqrt(2) for k=1..7 + For integer operation, the multiplier table is to be scaled by + IFAST_SCALE_BITS. } + + ifmtbl := IFAST_MULT_TYPE_FIELD_PTR (compptr^.dct_table); + + for i := 0 to pred(DCTSIZE2) do + begin + ifmtbl^[i] := IFAST_MULT_TYPE( + DESCALE( INT32 (qtbl^.quantval[i]) * INT32 (aanscales[i]), + CONST_BITS-IFAST_SCALE_BITS) ); + end; + end; +{$endif} +{$ifdef DCT_FLOAT_SUPPORTED} + JDCT_FLOAT: + begin + { For float AA&N IDCT method, multipliers are equal to quantization + coefficients scaled by scalefactor[row]*scalefactor[col], where + scalefactor[0] := 1 + scalefactor[k] := cos(k*PI/16) * sqrt(2) for k=1..7 } + + fmtbl := FLOAT_MULT_TYPE_FIELD_PTR(compptr^.dct_table); + + i := 0; + for row := 0 to pred(DCTSIZE) do + begin + for col := 0 to pred(DCTSIZE) do + begin + fmtbl^[i] := {FLOAT_MULT_TYPE} ( + {double} qtbl^.quantval[i] * + aanscalefactor[row] * aanscalefactor[col] ); + Inc(i); + end; + end; + end; +{$endif} + else + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); + break; + end; + Inc(compptr); + end; +end; + + +{ Initialize IDCT manager. } + +{GLOBAL} +procedure jinit_inverse_dct (cinfo : j_decompress_ptr); +var + idct : my_idct_ptr; + ci : int; + compptr : jpeg_component_info_ptr; +begin + idct := my_idct_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(my_idct_controller)) ); + cinfo^.idct := jpeg_inverse_dct_ptr (idct); + idct^.pub.start_pass := start_pass; + + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + { Allocate and pre-zero a multiplier table for each component } + compptr^.dct_table := + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(multiplier_table)); + MEMZERO(compptr^.dct_table, SIZEOF(multiplier_table)); + { Mark multiplier table not yet set up for any method } + idct^.cur_method[ci] := -1; + Inc(compptr); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jdeferr_del.pas b/mseide-msegui/lib/common/fpccompatibility/jdeferr_del.pas new file mode 100644 index 0000000..02dfa91 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jdeferr_del.pas @@ -0,0 +1,498 @@ +unit jdeferr_del; + +{ This file defines the error and message codes for the cjpeg/djpeg + applications. These strings are not needed as part of the JPEG library + proper. + Edit this file to add new codes, or to translate the message strings to + some other language. } + +{ Original cderror.h ; Copyright (C) 1994, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +{ To define the enum list of message codes, include this file without + defining macro JMESSAGE. To create a message string table, include it + again with a suitable JMESSAGE definition (see jerror.c for an example). } + + +{ Original: jversion.h ; Copyright (C) 1991-1996, Thomas G. Lane. } +{ This file contains software version identification. } + +const + JVERSION = '6a 7-Feb-96'; + + JCOPYRIGHT = 'Copyright (C) 1996, Thomas G. Lane'; + + JNOTICE = 'Pascal Translation, Copyright (C) 1996, Jacques Nomssi Nzali'; + +{ Create the message string table. + We do this from the master message list in jerror.h by re-reading + jerror.h with a suitable definition for macro JMESSAGE. + The message table is made an external symbol just in case any applications + want to refer to it directly. } + +type + J_MESSAGE_CODE =( + JMSG_NOMESSAGE, + JERR_ARITH_NOTIMPL, + JERR_BAD_ALIGN_TYPE, + JERR_BAD_ALLOC_CHUNK, + JERR_BAD_BUFFER_MODE, + JERR_BAD_COMPONENT_ID, + JERR_BAD_DCT_COEF, + JERR_BAD_DCTSIZE, + JERR_BAD_HUFF_TABLE, + JERR_BAD_IN_COLORSPACE, + JERR_BAD_J_COLORSPACE, + JERR_BAD_LENGTH, + JERR_BAD_LIB_VERSION, + JERR_BAD_MCU_SIZE, + JERR_BAD_POOL_ID, + JERR_BAD_PRECISION, + JERR_BAD_PROGRESSION, + JERR_BAD_PROG_SCRIPT, + JERR_BAD_SAMPLING, + JERR_BAD_SCAN_SCRIPT, + JERR_BAD_STATE, + JERR_BAD_STRUCT_SIZE, + JERR_BAD_VIRTUAL_ACCESS, + JERR_BUFFER_SIZE, + JERR_CANT_SUSPEND, + JERR_CCIR601_NOTIMPL, + JERR_COMPONENT_COUNT, + JERR_CONVERSION_NOTIMPL, + JERR_DAC_INDEX, + JERR_DAC_VALUE, + JERR_DHT_COUNTS, + JERR_DHT_INDEX, + JERR_DQT_INDEX, + JERR_EMPTY_IMAGE, + JERR_EMS_READ, + JERR_EMS_WRITE, + JERR_EOI_EXPECTED, + JERR_FILE_READ, + JERR_FILE_WRITE, + JERR_FRACT_SAMPLE_NOTIMPL, + JERR_HUFF_CLEN_OVERFLOW, + JERR_HUFF_MISSING_CODE, + JERR_IMAGE_TOO_BIG, + JERR_INPUT_EMPTY, + JERR_INPUT_EOF, + JERR_MISMATCHED_QUANT_TABLE, + JERR_MISSING_DATA, + JERR_MODE_CHANGE, + JERR_NOTIMPL, + JERR_NOT_COMPILED, + JERR_NO_BACKING_STORE, + JERR_NO_HUFF_TABLE, + JERR_NO_IMAGE, + JERR_NO_QUANT_TABLE, + JERR_NO_SOI, + JERR_OUT_OF_MEMORY, + JERR_QUANT_COMPONENTS, + JERR_QUANT_FEW_COLORS, + JERR_QUANT_MANY_COLORS, + JERR_SOF_DUPLICATE, + JERR_SOF_NO_SOS, + JERR_SOF_UNSUPPORTED, + JERR_SOI_DUPLICATE, + JERR_SOS_NO_SOF, + JERR_TFILE_CREATE, + JERR_TFILE_READ, + JERR_TFILE_SEEK, + JERR_TFILE_WRITE, + JERR_TOO_LITTLE_DATA, + JERR_UNKNOWN_MARKER, + JERR_VIRTUAL_BUG, + JERR_WIDTH_OVERFLOW, + JERR_XMS_READ, + JERR_XMS_WRITE, + JMSG_COPYRIGHT, + JMSG_VERSION, + JTRC_16BIT_TABLES, + JTRC_ADOBE, + JTRC_APP0, + JTRC_APP14, + JTRC_DAC, + JTRC_DHT, + JTRC_DQT, + JTRC_DRI, + JTRC_EMS_CLOSE, + JTRC_EMS_OPEN, + JTRC_EOI, + JTRC_HUFFBITS, + JTRC_JFIF, + JTRC_JFIF_BADTHUMBNAILSIZE, + JTRC_JFIF_EXTENSION, + JTRC_JFIF_THUMBNAIL, + JTRC_MISC_MARKER, + JTRC_PARMLESS_MARKER, + JTRC_QUANTVALS, + JTRC_QUANT_3_NCOLORS, + JTRC_QUANT_NCOLORS, + JTRC_QUANT_SELECTED, + JTRC_RECOVERY_ACTION, + JTRC_RST, + JTRC_SMOOTH_NOTIMPL, + JTRC_SOF, + JTRC_SOF_COMPONENT, + JTRC_SOI, + JTRC_SOS, + JTRC_SOS_COMPONENT, + JTRC_SOS_PARAMS, + JTRC_TFILE_CLOSE, + JTRC_TFILE_OPEN, + JTRC_THUMB_JPEG, + JTRC_THUMB_PALETTE, + JTRC_THUMB_RGB, + JTRC_UNKNOWN_IDS, + JTRC_XMS_CLOSE, + JTRC_XMS_OPEN, + JWRN_ADOBE_XFORM, + JWRN_BOGUS_PROGRESSION, + JWRN_EXTRANEOUS_DATA, + JWRN_HIT_MARKER, + JWRN_HUFF_BAD_CODE, + JWRN_JFIF_MAJOR, + JWRN_JPEG_EOF, + JWRN_MUST_RESYNC, + JWRN_NOT_SEQUENTIAL, + JWRN_TOO_MUCH_DATA, + + + JMSG_FIRSTADDONCODE, { Must be first entry! } + + {$ifdef BMP_SUPPORTED} + JERR_BMP_BADCMAP, { Unsupported BMP colormap format } + JERR_BMP_BADDEPTH, { Only 8- and 24-bit BMP files are supported } + JERR_BMP_BADHEADER, { Invalid BMP file: bad header length } + JERR_BMP_BADPLANES, { Invalid BMP file: biPlanes not equal to 1 } + JERR_BMP_COLORSPACE, { BMP output must be grayscale or RGB } + JERR_BMP_COMPRESSED, { Sorry, compressed BMPs not yet supported } + JERR_BMP_NOT, { Not a BMP file - does not start with BM } + JTRC_BMP, { %dx%d 24-bit BMP image } + JTRC_BMP_MAPPED, { %dx%d 8-bit colormapped BMP image } + JTRC_BMP_OS2, { %dx%d 24-bit OS2 BMP image } + JTRC_BMP_OS2_MAPPED, { %dx%d 8-bit colormapped OS2 BMP image } + {$endif} { BMP_SUPPORTED } + + {$ifdef GIF_SUPPORTED} + JERR_GIF_BUG, { GIF output got confused } + JERR_GIF_CODESIZE, { Bogus GIF codesize %d } + JERR_GIF_COLORSPACE, { GIF output must be grayscale or RGB } + JERR_GIF_IMAGENOTFOUND, { Too few images in GIF file } + JERR_GIF_NOT, { Not a GIF file } + JTRC_GIF, { %dx%dx%d GIF image } + JTRC_GIF_BADVERSION, + { Warning: unexpected GIF version number '%c%c%c' } + JTRC_GIF_EXTENSION, { Ignoring GIF extension block of type 0x%02x } + JTRC_GIF_NONSQUARE, { Caution: nonsquare pixels in input } + JWRN_GIF_BADDATA, { Corrupt data in GIF file } + JWRN_GIF_CHAR, { Bogus char 0x%02x in GIF file, ignoring } + JWRN_GIF_ENDCODE, { Premature end of GIF image } + JWRN_GIF_NOMOREDATA, { Ran out of GIF bits } + {$endif} { GIF_SUPPORTED } + + {$ifdef PPM_SUPPORTED} + JERR_PPM_COLORSPACE, { PPM output must be grayscale or RGB } + JERR_PPM_NONNUMERIC, { Nonnumeric data in PPM file } + JERR_PPM_NOT, { Not a PPM file } + JTRC_PGM, { %dx%d PGM image } + JTRC_PGM_TEXT, { %dx%d text PGM image } + JTRC_PPM, { %dx%d PPM image } + JTRC_PPM_TEXT, { %dx%d text PPM image } + {$endif} { PPM_SUPPORTED } + + {$ifdef RLE_SUPPORTED} + JERR_RLE_BADERROR, { Bogus error code from RLE library } + JERR_RLE_COLORSPACE, { RLE output must be grayscale or RGB } + JERR_RLE_DIMENSIONS, { Image dimensions (%dx%d) too large for RLE } + JERR_RLE_EMPTY, { Empty RLE file } + JERR_RLE_EOF, { Premature EOF in RLE header } + JERR_RLE_MEM, { Insufficient memory for RLE header } + JERR_RLE_NOT, { Not an RLE file } + JERR_RLE_TOOMANYCHANNELS, { Cannot handle %d output channels for RLE } + JERR_RLE_UNSUPPORTED, { Cannot handle this RLE setup } + JTRC_RLE, { %dx%d full-color RLE file } + JTRC_RLE_FULLMAP, { %dx%d full-color RLE file with map of length %d } + JTRC_RLE_GRAY, { %dx%d grayscale RLE file } + JTRC_RLE_MAPGRAY, { %dx%d grayscale RLE file with map of length %d } + JTRC_RLE_MAPPED, { %dx%d colormapped RLE file with map of length %d } + {$endif} { RLE_SUPPORTED } + + {$ifdef TARGA_SUPPORTED} + JERR_TGA_BADCMAP, { Unsupported Targa colormap format } + JERR_TGA_BADPARMS, { Invalid or unsupported Targa file } + JERR_TGA_COLORSPACE, { Targa output must be grayscale or RGB } + JTRC_TGA, { %dx%d RGB Targa image } + JTRC_TGA_GRAY, { %dx%d grayscale Targa image } + JTRC_TGA_MAPPED, { %dx%d colormapped Targa image } + {$else} + JERR_TGA_NOTCOMP, { Targa support was not compiled } + {$endif} { TARGA_SUPPORTED } + + JERR_BAD_CMAP_FILE, + { Color map file is invalid or of unsupported format } + JERR_TOO_MANY_COLORS, + { Output file format cannot handle %d colormap entries } + JERR_UNGETC_FAILED, { ungetc failed } + {$ifdef TARGA_SUPPORTED} + JERR_UNKNOWN_FORMAT, + { Unrecognized input file format --- perhaps you need -targa } + {$else} + JERR_UNKNOWN_FORMAT, { Unrecognized input file format } + {$endif} + JERR_UNSUPPORTED_FORMAT, { Unsupported output file format } + + JMSG_LASTADDONCODE + ); + + +const + JMSG_LASTMSGCODE : J_MESSAGE_CODE = JMSG_LASTADDONCODE; + +type + msg_table = Array[J_MESSAGE_CODE] of string[80]; +const + jpeg_std_message_table : msg_table = ( + + { JMSG_NOMESSAGE } 'Bogus message code %d', { Must be first entry! } + +{ For maintenance convenience, list is alphabetical by message code name } + { JERR_ARITH_NOTIMPL } + 'Sorry, there are legal restrictions on arithmetic coding', + { JERR_BAD_ALIGN_TYPE } 'ALIGN_TYPE is wrong, please fix', + { JERR_BAD_ALLOC_CHUNK } 'MAX_ALLOC_CHUNK is wrong, please fix', + { JERR_BAD_BUFFER_MODE } 'Bogus buffer control mode', + { JERR_BAD_COMPONENT_ID } 'Invalid component ID %d in SOS', + { JERR_BAD_DCT_COEF } 'DCT coefficient out of range', + { JERR_BAD_DCTSIZE } 'IDCT output block size %d not supported', + { JERR_BAD_HUFF_TABLE } 'Bogus Huffman table definition', + { JERR_BAD_IN_COLORSPACE } 'Bogus input colorspace', + { JERR_BAD_J_COLORSPACE } 'Bogus JPEG colorspace', + { JERR_BAD_LENGTH } 'Bogus marker length', + { JERR_BAD_LIB_VERSION } + 'Wrong JPEG library version: library is %d, caller expects %d', + { JERR_BAD_MCU_SIZE } 'Sampling factors too large for interleaved scan', + { JERR_BAD_POOL_ID } 'Invalid memory pool code %d', + { JERR_BAD_PRECISION } 'Unsupported JPEG data precision %d', + { JERR_BAD_PROGRESSION } + 'Invalid progressive parameters Ss=%d Se=%d Ah=%d Al=%d', + { JERR_BAD_PROG_SCRIPT } + 'Invalid progressive parameters at scan script entry %d', + { JERR_BAD_SAMPLING } 'Bogus sampling factors', + { JERR_BAD_SCAN_SCRIPT } 'Invalid scan script at entry %d', + { JERR_BAD_STATE } 'Improper call to JPEG library in state %d', + { JERR_BAD_STRUCT_SIZE } + 'JPEG parameter struct mismatch: library thinks size is %d, caller expects %d', + { JERR_BAD_VIRTUAL_ACCESS } 'Bogus virtual array access', + { JERR_BUFFER_SIZE } 'Buffer passed to JPEG library is too small', + { JERR_CANT_SUSPEND } 'Suspension not allowed here', + { JERR_CCIR601_NOTIMPL } 'CCIR601 sampling not implemented yet', + { JERR_COMPONENT_COUNT } 'Too many color components: %d, max %d', + { JERR_CONVERSION_NOTIMPL } 'Unsupported color conversion request', + { JERR_DAC_INDEX } 'Bogus DAC index %d', + { JERR_DAC_VALUE } 'Bogus DAC value $%x', + { JERR_DHT_COUNTS } 'Bogus DHT counts', + { JERR_DHT_INDEX } 'Bogus DHT index %d', + { JERR_DQT_INDEX } 'Bogus DQT index %d', + { JERR_EMPTY_IMAGE } 'Empty JPEG image (DNL not supported)', + { JERR_EMS_READ } 'Read from EMS failed', + { JERR_EMS_WRITE } 'Write to EMS failed', + { JERR_EOI_EXPECTED } 'Didn''t expect more than one scan', + { JERR_FILE_READ } 'Input file read error', + { JERR_FILE_WRITE } 'Output file write error --- out of disk space?', + { JERR_FRACT_SAMPLE_NOTIMPL } 'Fractional sampling not implemented yet', + { JERR_HUFF_CLEN_OVERFLOW } 'Huffman code size table overflow', + { JERR_HUFF_MISSING_CODE } 'Missing Huffman code table entry', + { JERR_IMAGE_TOO_BIG } 'Maximum supported image dimension is %d pixels', + { JERR_INPUT_EMPTY } 'Empty input file', + { JERR_INPUT_EOF } 'Premature end of input file', + { JERR_MISMATCHED_QUANT_TABLE } + 'Cannot transcode due to multiple use of quantization table %d', + { JERR_MISSING_DATA } 'Scan script does not transmit all data', + { JERR_MODE_CHANGE } 'Invalid color quantization mode change', + { JERR_NOTIMPL } 'Not implemented yet', + { JERR_NOT_COMPILED } 'Requested feature was omitted at compile time', + { JERR_NO_BACKING_STORE } 'Backing store not supported', + { JERR_NO_HUFF_TABLE } 'Huffman table $%02x was not defined', + { JERR_NO_IMAGE } 'JPEG datastream contains no image', + { JERR_NO_QUANT_TABLE } 'Quantization table $%02x was not defined', + { JERR_NO_SOI } 'Not a JPEG file: starts with $%02x $%02x', + { JERR_OUT_OF_MEMORY } 'Insufficient memory (case %d)', + { JERR_QUANT_COMPONENTS } + 'Cannot quantize more than %d color components', + { JERR_QUANT_FEW_COLORS } 'Cannot quantize to fewer than %d colors', + { JERR_QUANT_MANY_COLORS } 'Cannot quantize to more than %d colors', + { JERR_SOF_DUPLICATE } 'Invalid JPEG file structure: two SOF markers', + { JERR_SOF_NO_SOS } 'Invalid JPEG file structure: missing SOS marker', + { JERR_SOF_UNSUPPORTED } 'Unsupported JPEG process: SOF type $%02x', + { JERR_SOI_DUPLICATE } 'Invalid JPEG file structure: two SOI markers', + { JERR_SOS_NO_SOF } 'Invalid JPEG file structure: SOS before SOF', + { JERR_TFILE_CREATE } 'Failed to create temporary file %s', + { JERR_TFILE_READ } 'Read failed on temporary file', + { JERR_TFILE_SEEK } 'Seek failed on temporary file', + { JERR_TFILE_WRITE } + 'Write failed on temporary file --- out of disk space?', + { JERR_TOO_LITTLE_DATA } 'Application transferred too few scanlines', + { JERR_UNKNOWN_MARKER } 'Unsupported marker type $%02x', + { JERR_VIRTUAL_BUG } 'Virtual array controller messed up', + { JERR_WIDTH_OVERFLOW } 'Image too wide for this implementation', + { JERR_XMS_READ } 'Read from XMS failed', + { JERR_XMS_WRITE } 'Write to XMS failed', + { JMSG_COPYRIGHT } JCOPYRIGHT, + { JMSG_VERSION } JVERSION, + { JTRC_16BIT_TABLES } + 'Caution: quantization tables are too coarse for baseline JPEG', + { JTRC_ADOBE } + 'Adobe APP14 marker: version %d, flags $%04x $%04x, transform %d', + { JTRC_APP0 } 'Unknown APP0 marker (not JFIF), length %d', + { JTRC_APP14 } 'Unknown APP14 marker (not Adobe), length %d', + { JTRC_DAC } 'Define Arithmetic Table $%02x: $%02x', + { JTRC_DHT } 'Define Huffman Table $%02x', + { JTRC_DQT } 'Define Quantization Table %d precision %d', + { JTRC_DRI } 'Define Restart Interval %d', + { JTRC_EMS_CLOSE } 'Freed EMS handle %d', + { JTRC_EMS_OPEN } 'Obtained EMS handle %d', + { JTRC_EOI } 'End Of Image', + { JTRC_HUFFBITS } ' %3d %3d %3d %3d %3d %3d %3d %3d', + { JTRC_JFIF } 'JFIF APP0 marker, density %dx%d %d', + { JTRC_JFIF_BADTHUMBNAILSIZE } + 'Warning: thumbnail image size does not match data length %d', + { JTRC_JFIF_EXTENSION } 'JFIF extension marker: type 0x%02x, length %u', + { JTRC_JFIF_THUMBNAIL } ' with %d x %d thumbnail image', + { JTRC_MISC_MARKER } 'Skipping marker $%02x, length %d', + { JTRC_PARMLESS_MARKER } 'Unexpected marker $%02x', + { JTRC_QUANTVALS } ' %4d %4d %4d %4d %4d %4d %4d %4d', + { JTRC_QUANT_3_NCOLORS } 'Quantizing to %d = %d*%d*%d colors', + { JTRC_QUANT_NCOLORS } 'Quantizing to %d colors', + { JTRC_QUANT_SELECTED } 'Selected %d colors for quantization', + { JTRC_RECOVERY_ACTION } 'At marker $%02x, recovery action %d', + { JTRC_RST } 'RST%d', + { JTRC_SMOOTH_NOTIMPL } + 'Smoothing not supported with nonstandard sampling ratios', + { JTRC_SOF } 'Start Of Frame $%02x: width=%d, height=%d, components=%d', + { JTRC_SOF_COMPONENT } ' Component %d: %dhx%dv q=%d', + { JTRC_SOI } 'Start of Image', + { JTRC_SOS } 'Start Of Scan: %d components', + { JTRC_SOS_COMPONENT } ' Component %d: dc=%d ac=%d', + { JTRC_SOS_PARAMS } ' Ss=%d, Se=%d, Ah=%d, Al=%d', + { JTRC_TFILE_CLOSE } 'Closed temporary file %s', + { JTRC_TFILE_OPEN } 'Opened temporary file %s', + { JTRC_THUMB_JPEG } + 'JFIF extension marker: JPEG-compressed thumbnail image, length %u', + { JMESSAGE(JTRC_THUMB_PALETTE } + 'JFIF extension marker: palette thumbnail image, length %u', + { JMESSAGE(JTRC_THUMB_RGB } + 'JFIF extension marker: RGB thumbnail image, length %u', + { JTRC_UNKNOWN_IDS } + 'Unrecognized component IDs %d %d %d, assuming YCbCr', + { JTRC_XMS_CLOSE } 'Freed XMS handle %d', + { JTRC_XMS_OPEN } 'Obtained XMS handle %d', + { JWRN_ADOBE_XFORM } 'Unknown Adobe color transform code %d', + { JWRN_BOGUS_PROGRESSION } + 'Inconsistent progression sequence for component %d coefficient %d', + { JWRN_EXTRANEOUS_DATA } + 'Corrupt JPEG data: %d extraneous bytes before marker $%02x', + { JWRN_HIT_MARKER } 'Corrupt JPEG data: premature end of data segment', + { JWRN_HUFF_BAD_CODE } 'Corrupt JPEG data: bad Huffman code', + { JWRN_JFIF_MAJOR } 'Warning: unknown JFIF revision number %d.%02d', + { JWRN_JPEG_EOF } 'Premature end of JPEG file', + { JWRN_MUST_RESYNC } + 'Corrupt JPEG data: found marker $%02x instead of RST%d', + { JWRN_NOT_SEQUENTIAL } 'Invalid SOS parameters for sequential JPEG', + { JWRN_TOO_MUCH_DATA } 'Application transferred too many scanlines', + + { JMSG_FIRSTADDONCODE } '', { Must be first entry! } + +{$ifdef BMP_SUPPORTED} + { JERR_BMP_BADCMAP } 'Unsupported BMP colormap format', + { JERR_BMP_BADDEPTH } 'Only 8- and 24-bit BMP files are supported', + { JERR_BMP_BADHEADER } 'Invalid BMP file: bad header length', + { JERR_BMP_BADPLANES } 'Invalid BMP file: biPlanes not equal to 1', + { JERR_BMP_COLORSPACE } 'BMP output must be grayscale or RGB', + { JERR_BMP_COMPRESSED } 'Sorry, compressed BMPs not yet supported', + { JERR_BMP_NOT } 'Not a BMP file - does not start with BM', + { JTRC_BMP } '%dx%d 24-bit BMP image', + { JTRC_BMP_MAPPED } '%dx%d 8-bit colormapped BMP image', + { JTRC_BMP_OS2 } '%dx%d 24-bit OS2 BMP image', + { JTRC_BMP_OS2_MAPPED } '%dx%d 8-bit colormapped OS2 BMP image', +{$endif} { BMP_SUPPORTED } + +{$ifdef GIF_SUPPORTED} + { JERR_GIF_BUG } 'GIF output got confused', + { JERR_GIF_CODESIZE } 'Bogus GIF codesize %d', + { JERR_GIF_COLORSPACE } 'GIF output must be grayscale or RGB', + { JERR_GIF_IMAGENOTFOUND } 'Too few images in GIF file', + { JERR_GIF_NOT } 'Not a GIF file', + { JTRC_GIF } '%dx%dx%d GIF image', + { JTRC_GIF_BADVERSION } + 'Warning: unexpected GIF version number "%c%c%c"', + { JTRC_GIF_EXTENSION } 'Ignoring GIF extension block of type 0x%02x', + { JTRC_GIF_NONSQUARE } 'Caution: nonsquare pixels in input', + { JWRN_GIF_BADDATA } 'Corrupt data in GIF file', + { JWRN_GIF_CHAR } 'Bogus char 0x%02x in GIF file, ignoring', + { JWRN_GIF_ENDCODE } 'Premature end of GIF image', + { JWRN_GIF_NOMOREDATA } 'Ran out of GIF bits', +{$endif} { GIF_SUPPORTED } + +{$ifdef PPM_SUPPORTED} + { JERR_PPM_COLORSPACE } 'PPM output must be grayscale or RGB', + { JERR_PPM_NONNUMERIC } 'Nonnumeric data in PPM file', + { JERR_PPM_NOT } 'Not a PPM file', + { JTRC_PGM } '%dx%d PGM image', + { JTRC_PGM_TEXT } '%dx%d text PGM image', + { JTRC_PPM } '%dx%d PPM image', + { JTRC_PPM_TEXT } '%dx%d text PPM image', +{$endif} { PPM_SUPPORTED } + +{$ifdef RLE_SUPPORTED} + { JERR_RLE_BADERROR } 'Bogus error code from RLE library', + { JERR_RLE_COLORSPACE } 'RLE output must be grayscale or RGB', + { JERR_RLE_DIMENSIONS } 'Image dimensions (%dx%d) too large for RLE', + { JERR_RLE_EMPTY } 'Empty RLE file', + { JERR_RLE_EOF } 'Premature EOF in RLE header', + { JERR_RLE_MEM } 'Insufficient memory for RLE header', + { JERR_RLE_NOT } 'Not an RLE file', + { JERR_RLE_TOOMANYCHANNELS } 'Cannot handle %d output channels for RLE', + { JERR_RLE_UNSUPPORTED } 'Cannot handle this RLE setup', + { JTRC_RLE } '%dx%d full-color RLE file', + { JTRC_RLE_FULLMAP } '%dx%d full-color RLE file with map of length %d', + { JTRC_RLE_GRAY } '%dx%d grayscale RLE file', + { JTRC_RLE_MAPGRAY } '%dx%d grayscale RLE file with map of length %d', + { JTRC_RLE_MAPPED } '%dx%d colormapped RLE file with map of length %d', +{$endif} { RLE_SUPPORTED } + +{$ifdef TARGA_SUPPORTED} + { JERR_TGA_BADCMAP } 'Unsupported Targa colormap format', + { JERR_TGA_BADPARMS } 'Invalid or unsupported Targa file', + { JERR_TGA_COLORSPACE } 'Targa output must be grayscale or RGB', + { JTRC_TGA } '%dx%d RGB Targa image', + { JTRC_TGA_GRAY } '%dx%d grayscale Targa image', + { JTRC_TGA_MAPPED } '%dx%d colormapped Targa image', +{$else} + { JERR_TGA_NOTCOMP } 'Targa support was not compiled', +{$endif} { TARGA_SUPPORTED } + + { JERR_BAD_CMAP_FILE } + 'Color map file is invalid or of unsupported format', + { JERR_TOO_MANY_COLORS } + 'Output file format cannot handle %d colormap entries', + { JERR_UNGETC_FAILED } 'ungetc failed', +{$ifdef TARGA_SUPPORTED} + { JERR_UNKNOWN_FORMAT } + 'Unrecognized input file format --- perhaps you need -targa', +{$else} + { JERR_UNKNOWN_FORMAT } 'Unrecognized input file format', +{$endif} + { JERR_UNSUPPORTED_FORMAT } 'Unsupported output file format', + + + { JMSG_LASTADDONCODE } ''); + +implementation + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jdhuff_del.pas b/mseide-msegui/lib/common/fpccompatibility/jdhuff_del.pas new file mode 100644 index 0000000..05b0425 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jdhuff_del.pas @@ -0,0 +1,1205 @@ +unit jdhuff_del; + +{ This file contains declarations for Huffman entropy decoding routines + that are shared between the sequential decoder (jdhuff.c) and the + progressive decoder (jdphuff.c). No other modules need to see these. } + +{ This file contains Huffman entropy decoding routines. + + Much of the complexity here has to do with supporting input suspension. + If the data source module demands suspension, we want to be able to back + up to the start of the current MCU. To do this, we copy state variables + into local working storage, and update them back to the permanent + storage only upon successful completion of an MCU. } + +{ Original: jdhuff.h+jdhuff.c; Copyright (C) 1991-1997, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + + + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jdeferr_del, + jerror_del, + jutils_del, + jpeglib_del; + + +{ Declarations shared with jdphuff.c } + + + +{ Derived data constructed for each Huffman table } + +const + HUFF_LOOKAHEAD = 8; { # of bits of lookahead } + +type + d_derived_tbl_ptr = ^d_derived_tbl; + d_derived_tbl = record + { Basic tables: (element [0] of each array is unused) } + maxcode : array[0..18-1] of INT32; { largest code of length k (-1 if none) } + { (maxcode[17] is a sentinel to ensure jpeg_huff_decode terminates) } + valoffset : array[0..17-1] of INT32; { huffval[] offset for codes of length k } + { valoffset[k] = huffval[] index of 1st symbol of code length k, less + the smallest code of length k; so given a code of length k, the + corresponding symbol is huffval[code + valoffset[k]] } + + { Link to public Huffman table (needed only in jpeg_huff_decode) } + pub : JHUFF_TBL_PTR; + + { Lookahead tables: indexed by the next HUFF_LOOKAHEAD bits of + the input data stream. If the next Huffman code is no more + than HUFF_LOOKAHEAD bits long, we can obtain its length and + the corresponding symbol directly from these tables. } + + look_nbits : array[0..(1 shl HUFF_LOOKAHEAD)-1] of int; + { # bits, or 0 if too long } + look_sym : array[0..(1 shl HUFF_LOOKAHEAD)-1] of UINT8; + { symbol, or unused } + end; + +{ Fetching the next N bits from the input stream is a time-critical operation + for the Huffman decoders. We implement it with a combination of inline + macros and out-of-line subroutines. Note that N (the number of bits + demanded at one time) never exceeds 15 for JPEG use. + + We read source bytes into get_buffer and dole out bits as needed. + If get_buffer already contains enough bits, they are fetched in-line + by the macros CHECK_BIT_BUFFER and GET_BITS. When there aren't enough + bits, jpeg_fill_bit_buffer is called; it will attempt to fill get_buffer + as full as possible (not just to the number of bits needed; this + prefetching reduces the overhead cost of calling jpeg_fill_bit_buffer). + Note that jpeg_fill_bit_buffer may return FALSE to indicate suspension. + On TRUE return, jpeg_fill_bit_buffer guarantees that get_buffer contains + at least the requested number of bits --- dummy zeroes are inserted if + necessary. } + + +type + bit_buf_type = INT32 ; { type of bit-extraction buffer } +const + BIT_BUF_SIZE = 32; { size of buffer in bits } + +{ If long is > 32 bits on your machine, and shifting/masking longs is + reasonably fast, making bit_buf_type be long and setting BIT_BUF_SIZE + appropriately should be a win. Unfortunately we can't define the size + with something like #define BIT_BUF_SIZE (sizeof(bit_buf_type)*8) + because not all machines measure sizeof in 8-bit bytes. } + +type + bitread_perm_state = record { Bitreading state saved across MCUs } + get_buffer : bit_buf_type; { current bit-extraction buffer } + bits_left : int; { # of unused bits in it } + end; + +type + bitread_working_state = record + { Bitreading working state within an MCU } + { current data source location } + { We need a copy, rather than munging the original, in case of suspension } + next_input_byte : JOCTETptr; { => next byte to read from source } + bytes_in_buffer : size_t; { # of bytes remaining in source buffer } + { Bit input buffer --- note these values are kept in register variables, + not in this struct, inside the inner loops. } + + get_buffer : bit_buf_type; { current bit-extraction buffer } + bits_left : int; { # of unused bits in it } + { Pointer needed by jpeg_fill_bit_buffer } + cinfo : j_decompress_ptr; { back link to decompress master record } + end; + +{ Module initialization routine for Huffman entropy decoding. } + +{GLOBAL} +procedure jinit_huff_decoder (cinfo : j_decompress_ptr); + +{GLOBAL} +function jpeg_huff_decode(var state : bitread_working_state; + get_buffer : bit_buf_type; {register} + bits_left : int; {register} + htbl : d_derived_tbl_ptr; + min_bits : int) : int; + +{ Compute the derived values for a Huffman table. + Note this is also used by jdphuff.c. } + +{GLOBAL} +procedure jpeg_make_d_derived_tbl (cinfo : j_decompress_ptr; + isDC : boolean; + tblno : int; + var pdtbl : d_derived_tbl_ptr); + +{ Load up the bit buffer to a depth of at least nbits } + +function jpeg_fill_bit_buffer (var state : bitread_working_state; + get_buffer : bit_buf_type; {register} + bits_left : int; {register} + nbits : int) : boolean; + +implementation + +{$IFDEF MACRO} + +{ Macros to declare and load/save bitread local variables. } +{$define BITREAD_STATE_VARS} + get_buffer : bit_buf_type ; {register} + bits_left : int; {register} + br_state : bitread_working_state; + +{$define BITREAD_LOAD_STATE(cinfop,permstate)} + br_state.cinfo := cinfop; + br_state.next_input_byte := cinfop^.src^.next_input_byte; + br_state.bytes_in_buffer := cinfop^.src^.bytes_in_buffer; + get_buffer := permstate.get_buffer; + bits_left := permstate.bits_left; + +{$define BITREAD_SAVE_STATE(cinfop,permstate) } + cinfop^.src^.next_input_byte := br_state.next_input_byte; + cinfop^.src^.bytes_in_buffer := br_state.bytes_in_buffer; + permstate.get_buffer := get_buffer; + permstate.bits_left := bits_left; + + +{ These macros provide the in-line portion of bit fetching. + Use CHECK_BIT_BUFFER to ensure there are N bits in get_buffer + before using GET_BITS, PEEK_BITS, or DROP_BITS. + The variables get_buffer and bits_left are assumed to be locals, + but the state struct might not be (jpeg_huff_decode needs this). + CHECK_BIT_BUFFER(state,n,action); + Ensure there are N bits in get_buffer; if suspend, take action. + val = GET_BITS(n); + Fetch next N bits. + val = PEEK_BITS(n); + Fetch next N bits without removing them from the buffer. + DROP_BITS(n); + Discard next N bits. + The value N should be a simple variable, not an expression, because it + is evaluated multiple times. } + + +{$define CHECK_BIT_BUFFER(state,nbits,action)} + if (bits_left < (nbits)) then + begin + if (not jpeg_fill_bit_buffer(&(state),get_buffer,bits_left,nbits)) then + begin + action; + exit; + end; + get_buffer := state.get_buffer; + bits_left := state.bits_left; + end; + + +{$define GET_BITS(nbits)} + Dec(bits_left, (nbits)); + ( (int(get_buffer shr bits_left)) and ( pred(1 shl (nbits)) ) ) + +{$define PEEK_BITS(nbits)} + int(get_buffer shr (bits_left - (nbits))) and pred(1 shl (nbits)) + +{$define DROP_BITS(nbits)} + Dec(bits_left, nbits); + + + + +{ Code for extracting next Huffman-coded symbol from input bit stream. + Again, this is time-critical and we make the main paths be macros. + + We use a lookahead table to process codes of up to HUFF_LOOKAHEAD bits + without looping. Usually, more than 95% of the Huffman codes will be 8 + or fewer bits long. The few overlength codes are handled with a loop, + which need not be inline code. + + Notes about the HUFF_DECODE macro: + 1. Near the end of the data segment, we may fail to get enough bits + for a lookahead. In that case, we do it the hard way. + 2. If the lookahead table contains no entry, the next code must be + more than HUFF_LOOKAHEAD bits long. + 3. jpeg_huff_decode returns -1 if forced to suspend. } + + + + +macro HUFF_DECODE(s,br_state,htbl,return FALSE,slowlabel); +label showlabel; +var + nb, look : int; {register} +begin + if (bits_left < HUFF_LOOKAHEAD) then + begin + if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left, 0)) then + begin + decode_mcu := FALSE; + exit; + end; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + if (bits_left < HUFF_LOOKAHEAD) then + begin + nb := 1; + goto slowlabel; + end; + end; + {look := PEEK_BITS(HUFF_LOOKAHEAD);} + look := int(get_buffer shr (bits_left - HUFF_LOOKAHEAD)) and + pred(1 shl HUFF_LOOKAHEAD); + + nb := htbl^.look_nbits[look]; + if (nb <> 0) then + begin + {DROP_BITS(nb);} + Dec(bits_left, nb); + + s := htbl^.look_sym[look]; + end + else + begin + nb := HUFF_LOOKAHEAD+1; +slowlabel: + s := jpeg_huff_decode(br_state,get_buffer,bits_left,htbl,nb)); + if (s < 0) then + begin + result := FALSE; + exit; + end; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + end; +end; + + +{$ENDIF} {MACRO} + +{ Expanded entropy decoder object for Huffman decoding. + + The savable_state subrecord contains fields that change within an MCU, + but must not be updated permanently until we complete the MCU. } + +type + savable_state = record + last_dc_val : array[0..MAX_COMPS_IN_SCAN-1] of int; { last DC coef for each component } + end; + + +type + huff_entropy_ptr = ^huff_entropy_decoder; + huff_entropy_decoder = record + pub : jpeg_entropy_decoder; { public fields } + + { These fields are loaded into local variables at start of each MCU. + In case of suspension, we exit WITHOUT updating them. } + + bitstate : bitread_perm_state; { Bit buffer at start of MCU } + saved : savable_state; { Other state at start of MCU } + + { These fields are NOT loaded into local working state. } + restarts_to_go : uInt; { MCUs left in this restart interval } + + { Pointers to derived tables (these workspaces have image lifespan) } + dc_derived_tbls : array[0..NUM_HUFF_TBLS] of d_derived_tbl_ptr; + ac_derived_tbls : array[0..NUM_HUFF_TBLS] of d_derived_tbl_ptr; + + { Precalculated info set up by start_pass for use in decode_mcu: } + + { Pointers to derived tables to be used for each block within an MCU } + dc_cur_tbls : array[0..D_MAX_BLOCKS_IN_MCU-1] of d_derived_tbl_ptr; + ac_cur_tbls : array[0..D_MAX_BLOCKS_IN_MCU-1] of d_derived_tbl_ptr; + { Whether we care about the DC and AC coefficient values for each block } + dc_needed : array[0..D_MAX_BLOCKS_IN_MCU-1] of boolean; + ac_needed : array[0..D_MAX_BLOCKS_IN_MCU-1] of boolean; + end; + + + +{ Initialize for a Huffman-compressed scan. } + +{METHODDEF} +procedure start_pass_huff_decoder (cinfo : j_decompress_ptr); +var + entropy : huff_entropy_ptr; + ci, blkn, dctbl, actbl : int; + compptr : jpeg_component_info_ptr; +begin + entropy := huff_entropy_ptr (cinfo^.entropy); + + { Check that the scan parameters Ss, Se, Ah/Al are OK for sequential JPEG. + This ought to be an error condition, but we make it a warning because + there are some baseline files out there with all zeroes in these bytes. } + + if (cinfo^.Ss <> 0) or (cinfo^.Se <> DCTSIZE2-1) or + (cinfo^.Ah <> 0) or (cinfo^.Al <> 0) then + WARNMS(j_common_ptr(cinfo), JWRN_NOT_SEQUENTIAL); + + for ci := 0 to pred(cinfo^.comps_in_scan) do + begin + compptr := cinfo^.cur_comp_info[ci]; + dctbl := compptr^.dc_tbl_no; + actbl := compptr^.ac_tbl_no; + { Compute derived values for Huffman tables } + { We may do this more than once for a table, but it's not expensive } + jpeg_make_d_derived_tbl(cinfo, TRUE, dctbl, + entropy^.dc_derived_tbls[dctbl]); + jpeg_make_d_derived_tbl(cinfo, FALSE, actbl, + entropy^.ac_derived_tbls[actbl]); + { Initialize DC predictions to 0 } + entropy^.saved.last_dc_val[ci] := 0; + end; + + { Precalculate decoding info for each block in an MCU of this scan } + for blkn := 0 to pred(cinfo^.blocks_in_MCU) do + begin + ci := cinfo^.MCU_membership[blkn]; + compptr := cinfo^.cur_comp_info[ci]; + { Precalculate which table to use for each block } + entropy^.dc_cur_tbls[blkn] := entropy^.dc_derived_tbls[compptr^.dc_tbl_no]; + entropy^.ac_cur_tbls[blkn] := entropy^.ac_derived_tbls[compptr^.ac_tbl_no]; + { Decide whether we really care about the coefficient values } + if (compptr^.component_needed) then + begin + entropy^.dc_needed[blkn] := TRUE; + { we don't need the ACs if producing a 1/8th-size image } + entropy^.ac_needed[blkn] := (compptr^.DCT_scaled_size > 1); + end + else + begin + entropy^.ac_needed[blkn] := FALSE; + entropy^.dc_needed[blkn] := FALSE; + end; + end; + + { Initialize bitread state variables } + entropy^.bitstate.bits_left := 0; + entropy^.bitstate.get_buffer := 0; { unnecessary, but keeps Purify quiet } + entropy^.pub.insufficient_data := FALSE; + + { Initialize restart counter } + entropy^.restarts_to_go := cinfo^.restart_interval; +end; + + +{ Compute the derived values for a Huffman table. + This routine also performs some validation checks on the table. + + Note this is also used by jdphuff.c. } + +{GLOBAL} +procedure jpeg_make_d_derived_tbl (cinfo : j_decompress_ptr; + isDC : boolean; + tblno : int; + var pdtbl : d_derived_tbl_ptr); +var + htbl : JHUFF_TBL_PTR; + dtbl : d_derived_tbl_ptr; + p, i, l, si, numsymbols : int; + lookbits, ctr : int; + huffsize : array[0..257-1] of byte; + huffcode : array[0..257-1] of uInt; + code : uInt; +var + sym : int; +begin + { Note that huffsize[] and huffcode[] are filled in code-length order, + paralleling the order of the symbols themselves in htbl^.huffval[]. } + + { Find the input Huffman table } + if (tblno < 0) or (tblno >= NUM_HUFF_TBLS) then + ERREXIT1(j_common_ptr(cinfo), JERR_NO_HUFF_TABLE, tblno); + if isDC then + htbl := cinfo^.dc_huff_tbl_ptrs[tblno] + else + htbl := cinfo^.ac_huff_tbl_ptrs[tblno]; + if (htbl = NIL) then + ERREXIT1(j_common_ptr(cinfo), JERR_NO_HUFF_TABLE, tblno); + + { Allocate a workspace if we haven't already done so. } + if (pdtbl = NIL) then + pdtbl := d_derived_tbl_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(d_derived_tbl)) ); + dtbl := pdtbl; + dtbl^.pub := htbl; { fill in back link } + + { Figure C.1: make table of Huffman code length for each symbol } + + p := 0; + for l := 1 to 16 do + begin + i := int(htbl^.bits[l]); + if (i < 0) or (p + i > 256) then { protect against table overrun } + ERREXIT(j_common_ptr(cinfo), JERR_BAD_HUFF_TABLE); + while (i > 0) do + begin + huffsize[p] := byte(l); + Inc(p); + Dec(i); + end; + end; + huffsize[p] := 0; + numsymbols := p; + + { Figure C.2: generate the codes themselves } + { We also validate that the counts represent a legal Huffman code tree. } + + code := 0; + si := huffsize[0]; + p := 0; + while (huffsize[p] <> 0) do + begin + while (( int (huffsize[p]) ) = si) do + begin + huffcode[p] := code; + Inc(p); + Inc(code); + end; + { code is now 1 more than the last code used for codelength si; but + it must still fit in si bits, since no code is allowed to be all ones. } + + if (INT32(code) >= (INT32(1) shl si)) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_HUFF_TABLE); + + code := code shl 1; + Inc(si); + end; + + { Figure F.15: generate decoding tables for bit-sequential decoding } + + p := 0; + for l := 1 to 16 do + begin + if (htbl^.bits[l] <> 0) then + begin + { valoffset[l] = huffval[] index of 1st symbol of code length l, + minus the minimum code of length l } + + dtbl^.valoffset[l] := INT32(p) - INT32(huffcode[p]); + Inc(p, htbl^.bits[l]); + dtbl^.maxcode[l] := huffcode[p-1]; { maximum code of length l } + end + else + begin + dtbl^.maxcode[l] := -1; { -1 if no codes of this length } + end; + end; + dtbl^.maxcode[17] := long($FFFFF); { ensures jpeg_huff_decode terminates } + + { Compute lookahead tables to speed up decoding. + First we set all the table entries to 0, indicating "too long"; + then we iterate through the Huffman codes that are short enough and + fill in all the entries that correspond to bit sequences starting + with that code. } + + MEMZERO(@dtbl^.look_nbits, SIZEOF(dtbl^.look_nbits)); + + p := 0; + for l := 1 to HUFF_LOOKAHEAD do + begin + for i := 1 to int (htbl^.bits[l]) do + begin + { l := current code's length, p := its index in huffcode[] & huffval[]. } + { Generate left-justified code followed by all possible bit sequences } + lookbits := huffcode[p] shl (HUFF_LOOKAHEAD-l); + for ctr := pred(1 shl (HUFF_LOOKAHEAD-l)) downto 0 do + begin + dtbl^.look_nbits[lookbits] := l; + dtbl^.look_sym[lookbits] := htbl^.huffval[p]; + Inc(lookbits); + end; + Inc(p); + end; + end; + + { Validate symbols as being reasonable. + For AC tables, we make no check, but accept all byte values 0..255. + For DC tables, we require the symbols to be in range 0..15. + (Tighter bounds could be applied depending on the data depth and mode, + but this is sufficient to ensure safe decoding.) } + + if (isDC) then + begin + for i := 0 to pred(numsymbols) do + begin + sym := htbl^.huffval[i]; + if (sym < 0) or (sym > 15) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_HUFF_TABLE); + end; + end; +end; + + +{ Out-of-line code for bit fetching (shared with jdphuff.c). + See jdhuff.h for info about usage. + Note: current values of get_buffer and bits_left are passed as parameters, + but are returned in the corresponding fields of the state struct. + + On most machines MIN_GET_BITS should be 25 to allow the full 32-bit width + of get_buffer to be used. (On machines with wider words, an even larger + buffer could be used.) However, on some machines 32-bit shifts are + quite slow and take time proportional to the number of places shifted. + (This is true with most PC compilers, for instance.) In this case it may + be a win to set MIN_GET_BITS to the minimum value of 15. This reduces the + average shift distance at the cost of more calls to jpeg_fill_bit_buffer. } + +{$ifdef SLOW_SHIFT_32} +const + MIN_GET_BITS = 15; { minimum allowable value } +{$else} +const + MIN_GET_BITS = (BIT_BUF_SIZE-7); +{$endif} + + +{GLOBAL} +function jpeg_fill_bit_buffer (var state : bitread_working_state; + {register} get_buffer : bit_buf_type; + {register} bits_left : int; + nbits : int) : boolean; +label + no_more_bytes; +{ Load up the bit buffer to a depth of at least nbits } +var + { Copy heavily used state fields into locals (hopefully registers) } + {register} next_input_byte : {const} JOCTETptr; + {register} bytes_in_buffer : size_t; +var + {register} c : int; +var + cinfo : j_decompress_ptr; +begin + next_input_byte := state.next_input_byte; + bytes_in_buffer := state.bytes_in_buffer; + cinfo := state.cinfo; + + { Attempt to load at least MIN_GET_BITS bits into get_buffer. } + { (It is assumed that no request will be for more than that many bits.) } + { We fail to do so only if we hit a marker or are forced to suspend. } + + if (cinfo^.unread_marker = 0) then { cannot advance past a marker } + begin + while (bits_left < MIN_GET_BITS) do + begin + { Attempt to read a byte } + if (bytes_in_buffer = 0) then + begin + if not cinfo^.src^.fill_input_buffer(cinfo) then + begin + jpeg_fill_bit_buffer := FALSE; + exit; + end; + next_input_byte := cinfo^.src^.next_input_byte; + bytes_in_buffer := cinfo^.src^.bytes_in_buffer; + end; + Dec(bytes_in_buffer); + c := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + + + { If it's $FF, check and discard stuffed zero byte } + if (c = $FF) then + begin + { Loop here to discard any padding FF's on terminating marker, + so that we can save a valid unread_marker value. NOTE: we will + accept multiple FF's followed by a 0 as meaning a single FF data + byte. This data pattern is not valid according to the standard. } + + repeat + if (bytes_in_buffer = 0) then + begin + if (not state.cinfo^.src^.fill_input_buffer (state.cinfo)) then + begin + jpeg_fill_bit_buffer := FALSE; + exit; + end; + next_input_byte := state.cinfo^.src^.next_input_byte; + bytes_in_buffer := state.cinfo^.src^.bytes_in_buffer; + end; + Dec(bytes_in_buffer); + c := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + Until (c <> $FF); + + if (c = 0) then + begin + { Found FF/00, which represents an FF data byte } + c := $FF; + end + else + begin + { Oops, it's actually a marker indicating end of compressed data. + Save the marker code for later use. + Fine point: it might appear that we should save the marker into + bitread working state, not straight into permanent state. But + once we have hit a marker, we cannot need to suspend within the + current MCU, because we will read no more bytes from the data + source. So it is OK to update permanent state right away. } + + cinfo^.unread_marker := c; + { See if we need to insert some fake zero bits. } + goto no_more_bytes; + end; + end; + + { OK, load c into get_buffer } + get_buffer := (get_buffer shl 8) or c; + Inc(bits_left, 8); + end { end while } + end + else + begin + no_more_bytes: + { We get here if we've read the marker that terminates the compressed + data segment. There should be enough bits in the buffer register + to satisfy the request; if so, no problem. } + + if (nbits > bits_left) then + begin + { Uh-oh. Report corrupted data to user and stuff zeroes into + the data stream, so that we can produce some kind of image. + We use a nonvolatile flag to ensure that only one warning message + appears per data segment. } + + if not cinfo^.entropy^.insufficient_data then + begin + WARNMS(j_common_ptr(cinfo), JWRN_HIT_MARKER); + cinfo^.entropy^.insufficient_data := TRUE; + end; + { Fill the buffer with zero bits } + get_buffer := get_buffer shl (MIN_GET_BITS - bits_left); + bits_left := MIN_GET_BITS; + end; + end; + + { Unload the local registers } + state.next_input_byte := next_input_byte; + state.bytes_in_buffer := bytes_in_buffer; + state.get_buffer := get_buffer; + state.bits_left := bits_left; + + jpeg_fill_bit_buffer := TRUE; +end; + + +{ Out-of-line code for Huffman code decoding. + See jdhuff.h for info about usage. } + +{GLOBAL} +function jpeg_huff_decode (var state : bitread_working_state; + {register} get_buffer : bit_buf_type; + {register} bits_left : int; + htbl : d_derived_tbl_ptr; + min_bits : int) : int; +var + {register} l : int; + {register} code : INT32; +begin + l := min_bits; + + { HUFF_DECODE has determined that the code is at least min_bits } + { bits long, so fetch that many bits in one swoop. } + + {CHECK_BIT_BUFFER(state, l, return -1);} + if (bits_left < l) then + begin + if (not jpeg_fill_bit_buffer(state, get_buffer, bits_left, l)) then + begin + jpeg_huff_decode := -1; + exit; + end; + get_buffer := state.get_buffer; + bits_left := state.bits_left; + end; + + {code := GET_BITS(l);} + Dec(bits_left, l); + code := (int(get_buffer shr bits_left)) and ( pred(1 shl l) ); + + { Collect the rest of the Huffman code one bit at a time. } + { This is per Figure F.16 in the JPEG spec. } + + while (code > htbl^.maxcode[l]) do + begin + code := code shl 1; + {CHECK_BIT_BUFFER(state, 1, return -1);} + if (bits_left < 1) then + begin + if (not jpeg_fill_bit_buffer(state, get_buffer, bits_left, 1)) then + begin + jpeg_huff_decode := -1; + exit; + end; + get_buffer := state.get_buffer; + bits_left := state.bits_left; + end; + + {code := code or GET_BITS(1);} + Dec(bits_left); + code := code or ( (int(get_buffer shr bits_left)) and pred(1 shl 1) ); + + Inc(l); + end; + + { Unload the local registers } + state.get_buffer := get_buffer; + state.bits_left := bits_left; + + { With garbage input we may reach the sentinel value l := 17. } + + if (l > 16) then + begin + WARNMS(j_common_ptr(state.cinfo), JWRN_HUFF_BAD_CODE); + jpeg_huff_decode := 0; { fake a zero as the safest result } + exit; + end; + + jpeg_huff_decode := htbl^.pub^.huffval[ int (code + htbl^.valoffset[l]) ]; +end; + + +{ Figure F.12: extend sign bit. + On some machines, a shift and add will be faster than a table lookup. } + +{$ifdef AVOID_TABLES} + +#define HUFF_EXTEND(x,s) ((x) < (1<<((s)-1)) ? (x) + (((-1)<<(s)) + 1) : (x)) + +{$else} + +{$define HUFF_EXTEND(x,s) + if (x < extend_test[s]) then + := x + extend_offset[s] + else + x;} + +const + extend_test : array[0..16-1] of int = { entry n is 2**(n-1) } + ($0000, $0001, $0002, $0004, $0008, $0010, $0020, $0040, + $0080, $0100, $0200, $0400, $0800, $1000, $2000, $4000); + +const + extend_offset : array[0..16-1] of int = { entry n is (-1 << n) + 1 } +(0, ((-1) shl 1) + 1, ((-1) shl 2) + 1, ((-1) shl 3) + 1, ((-1) shl 4) + 1, + ((-1) shl 5) + 1, ((-1) shl 6) + 1, ((-1) shl 7) + 1, ((-1) shl 8) + 1, + ((-1) shl 9) + 1, ((-1) shl 10) + 1, ((-1) shl 11) + 1,((-1) shl 12) + 1, + ((-1) shl 13) + 1, ((-1) shl 14) + 1, ((-1) shl 15) + 1); + +{$endif} { AVOID_TABLES } + + +{ Check for a restart marker & resynchronize decoder. + Returns FALSE if must suspend. } + +{LOCAL} +function process_restart (cinfo : j_decompress_ptr) : boolean; +var + entropy : huff_entropy_ptr; + ci : int; +begin + entropy := huff_entropy_ptr (cinfo^.entropy); + + { Throw away any unused bits remaining in bit buffer; } + { include any full bytes in next_marker's count of discarded bytes } + Inc(cinfo^.marker^.discarded_bytes, entropy^.bitstate.bits_left div 8); + entropy^.bitstate.bits_left := 0; + + { Advance past the RSTn marker } + if (not cinfo^.marker^.read_restart_marker (cinfo)) then + begin + process_restart := FALSE; + exit; + end; + + { Re-initialize DC predictions to 0 } + for ci := 0 to pred(cinfo^.comps_in_scan) do + entropy^.saved.last_dc_val[ci] := 0; + + { Reset restart counter } + entropy^.restarts_to_go := cinfo^.restart_interval; + + { Reset out-of-data flag, unless read_restart_marker left us smack up + against a marker. In that case we will end up treating the next data + segment as empty, and we can avoid producing bogus output pixels by + leaving the flag set. } + + if (cinfo^.unread_marker = 0) then + entropy^.pub.insufficient_data := FALSE; + + process_restart := TRUE; +end; + + +{ Decode and return one MCU's worth of Huffman-compressed coefficients. + The coefficients are reordered from zigzag order into natural array order, + but are not dequantized. + + The i'th block of the MCU is stored into the block pointed to by + MCU_data[i]. WE ASSUME THIS AREA HAS BEEN ZEROED BY THE CALLER. + (Wholesale zeroing is usually a little faster than retail...) + + Returns FALSE if data source requested suspension. In that case no + changes have been made to permanent state. (Exception: some output + coefficients may already have been assigned. This is harmless for + this module, since we'll just re-assign them on the next call.) } + +{METHODDEF} +function decode_mcu (cinfo : j_decompress_ptr; + var MCU_data : array of JBLOCKROW) : boolean; +label + label1, label2, label3; +var + entropy : huff_entropy_ptr; + {register} s, k, r : int; + blkn, ci : int; + block : JBLOCK_PTR; + {BITREAD_STATE_VARS} + get_buffer : bit_buf_type ; {register} + bits_left : int; {register} + br_state : bitread_working_state; + + state : savable_state; + dctbl : d_derived_tbl_ptr; + actbl : d_derived_tbl_ptr; +var + nb, look : int; {register} +begin + entropy := huff_entropy_ptr (cinfo^.entropy); + + { Process restart marker if needed; may have to suspend } + if (cinfo^.restart_interval <> 0) then + begin + if (entropy^.restarts_to_go = 0) then + if (not process_restart(cinfo)) then + begin + decode_mcu := FALSE; + exit; + end; + end; + + { If we've run out of data, just leave the MCU set to zeroes. + This way, we return uniform gray for the remainder of the segment. } + + if not entropy^.pub.insufficient_data then + begin + + { Load up working state } + {BITREAD_LOAD_STATE(cinfo,entropy^.bitstate);} + br_state.cinfo := cinfo; + br_state.next_input_byte := cinfo^.src^.next_input_byte; + br_state.bytes_in_buffer := cinfo^.src^.bytes_in_buffer; + get_buffer := entropy^.bitstate.get_buffer; + bits_left := entropy^.bitstate.bits_left; + + {ASSIGN_STATE(state, entropy^.saved);} + state := entropy^.saved; + + { Outer loop handles each block in the MCU } + + for blkn := 0 to pred(cinfo^.blocks_in_MCU) do + begin + block := JBLOCK_PTR(MCU_data[blkn]); + dctbl := entropy^.dc_cur_tbls[blkn]; + actbl := entropy^.ac_cur_tbls[blkn]; + + { Decode a single block's worth of coefficients } + + { Section F.2.2.1: decode the DC coefficient difference } + {HUFF_DECODE(s, br_state, dctbl, return FALSE, label1);} + if (bits_left < HUFF_LOOKAHEAD) then + begin + if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left, 0)) then + begin + decode_mcu := False; + exit; + end; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + if (bits_left < HUFF_LOOKAHEAD) then + begin + nb := 1; + goto label1; + end; + end; + {look := PEEK_BITS(HUFF_LOOKAHEAD);} + look := int(get_buffer shr (bits_left - HUFF_LOOKAHEAD)) and + pred(1 shl HUFF_LOOKAHEAD); + + nb := dctbl^.look_nbits[look]; + if (nb <> 0) then + begin + {DROP_BITS(nb);} + Dec(bits_left, nb); + + s := dctbl^.look_sym[look]; + end + else + begin + nb := HUFF_LOOKAHEAD+1; + label1: + s := jpeg_huff_decode(br_state,get_buffer,bits_left,dctbl,nb); + if (s < 0) then + begin + decode_mcu := FALSE; + exit; + end; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + end; + + if (s <> 0) then + begin + {CHECK_BIT_BUFFER(br_state, s, return FALSE);} + if (bits_left < s) then + begin + if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left,s)) then + begin + decode_mcu := FALSE; + exit; + end; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + end; + + {r := GET_BITS(s);} + Dec(bits_left, s); + r := ( int(get_buffer shr bits_left)) and ( pred(1 shl s) ); + + {s := HUFF_EXTEND(r, s);} + if (r < extend_test[s]) then + s := r + extend_offset[s] + else + s := r; + end; + + if (entropy^.dc_needed[blkn]) then + begin + { Convert DC difference to actual value, update last_dc_val } + ci := cinfo^.MCU_membership[blkn]; + Inc(s, state.last_dc_val[ci]); + state.last_dc_val[ci] := s; + { Output the DC coefficient (assumes jpeg_natural_order[0] := 0) } + block^[0] := JCOEF (s); + end; + + if (entropy^.ac_needed[blkn]) then + begin + + { Section F.2.2.2: decode the AC coefficients } + { Since zeroes are skipped, output area must be cleared beforehand } + k := 1; + while (k < DCTSIZE2) do { Nomssi: k is incr. in the loop } + begin + {HUFF_DECODE(s, br_state, actbl, return FALSE, label2);} + if (bits_left < HUFF_LOOKAHEAD) then + begin + if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left, 0)) then + begin + decode_mcu := False; + exit; + end; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + if (bits_left < HUFF_LOOKAHEAD) then + begin + nb := 1; + goto label2; + end; + end; + {look := PEEK_BITS(HUFF_LOOKAHEAD);} + look := int(get_buffer shr (bits_left - HUFF_LOOKAHEAD)) and + pred(1 shl HUFF_LOOKAHEAD); + + nb := actbl^.look_nbits[look]; + if (nb <> 0) then + begin + {DROP_BITS(nb);} + Dec(bits_left, nb); + + s := actbl^.look_sym[look]; + end + else + begin + nb := HUFF_LOOKAHEAD+1; + label2: + s := jpeg_huff_decode(br_state,get_buffer,bits_left,actbl,nb); + if (s < 0) then + begin + decode_mcu := FALSE; + exit; + end; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + end; + + r := s shr 4; + s := s and 15; + + if (s <> 0) then + begin + Inc(k, r); + {CHECK_BIT_BUFFER(br_state, s, return FALSE);} + if (bits_left < s) then + begin + if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left,s)) then + begin + decode_mcu := FALSE; + exit; + end; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + end; + + {r := GET_BITS(s);} + Dec(bits_left, s); + r := (int(get_buffer shr bits_left)) and ( pred(1 shl s) ); + + {s := HUFF_EXTEND(r, s);} + if (r < extend_test[s]) then + s := r + extend_offset[s] + else + s := r; + { Output coefficient in natural (dezigzagged) order. + Note: the extra entries in jpeg_natural_order[] will save us + if k >= DCTSIZE2, which could happen if the data is corrupted. } + + block^[jpeg_natural_order[k]] := JCOEF (s); + end + else + begin + if (r <> 15) then + break; + Inc(k, 15); + end; + Inc(k); + end; + end + else + begin + + { Section F.2.2.2: decode the AC coefficients } + { In this path we just discard the values } + k := 1; + while (k < DCTSIZE2) do + begin + {HUFF_DECODE(s, br_state, actbl, return FALSE, label3);} + if (bits_left < HUFF_LOOKAHEAD) then + begin + if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left, 0)) then + begin + decode_mcu := False; + exit; + end; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + if (bits_left < HUFF_LOOKAHEAD) then + begin + nb := 1; + goto label3; + end; + end; + {look := PEEK_BITS(HUFF_LOOKAHEAD);} + look := int(get_buffer shr (bits_left - HUFF_LOOKAHEAD)) and + pred(1 shl HUFF_LOOKAHEAD); + + nb := actbl^.look_nbits[look]; + if (nb <> 0) then + begin + {DROP_BITS(nb);} + Dec(bits_left, nb); + + s := actbl^.look_sym[look]; + end + else + begin + nb := HUFF_LOOKAHEAD+1; + label3: + s := jpeg_huff_decode(br_state,get_buffer,bits_left,actbl,nb); + if (s < 0) then + begin + decode_mcu := FALSE; + exit; + end; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + end; + + r := s shr 4; + s := s and 15; + + if (s <> 0) then + begin + Inc(k, r); + {CHECK_BIT_BUFFER(br_state, s, return FALSE);} + if (bits_left < s) then + begin + if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left,s)) then + begin + decode_mcu := FALSE; + exit; + end; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + end; + + {DROP_BITS(s);} + Dec(bits_left, s); + end + else + begin + if (r <> 15) then + break; + Inc(k, 15); + end; + Inc(k); + end; + + end; + end; + + { Completed MCU, so update state } + {BITREAD_SAVE_STATE(cinfo,entropy^.bitstate);} + cinfo^.src^.next_input_byte := br_state.next_input_byte; + cinfo^.src^.bytes_in_buffer := br_state.bytes_in_buffer; + entropy^.bitstate.get_buffer := get_buffer; + entropy^.bitstate.bits_left := bits_left; + + {ASSIGN_STATE(entropy^.saved, state);} + entropy^.saved := state; + + end; + + { Account for restart interval (no-op if not using restarts) } + Dec(entropy^.restarts_to_go); + + decode_mcu := TRUE; +end; + + +{ Module initialization routine for Huffman entropy decoding. } + +{GLOBAL} +procedure jinit_huff_decoder (cinfo : j_decompress_ptr); +var + entropy : huff_entropy_ptr; + i : int; +begin + entropy := huff_entropy_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(huff_entropy_decoder)) ); + cinfo^.entropy := jpeg_entropy_decoder_ptr (entropy); + entropy^.pub.start_pass := start_pass_huff_decoder; + entropy^.pub.decode_mcu := decode_mcu; + + { Mark tables unallocated } + for i := 0 to pred(NUM_HUFF_TBLS) do + begin + entropy^.dc_derived_tbls[i] := NIL; + entropy^.ac_derived_tbls[i] := NIL; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jdinput_del.pas b/mseide-msegui/lib/common/fpccompatibility/jdinput_del.pas new file mode 100644 index 0000000..304379a --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jdinput_del.pas @@ -0,0 +1,417 @@ +unit jdinput_del; + +{ Original: jdinput.c ; Copyright (C) 1991-1997, Thomas G. Lane. } + +{ This file is part of the Independent JPEG Group's software. + For conditions of distribution and use, see the accompanying README file. + + This file contains input control logic for the JPEG decompressor. + These routines are concerned with controlling the decompressor's input + processing (marker reading and coefficient decoding). The actual input + reading is done in jdmarker.c, jdhuff.c, and jdphuff.c. } +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jpeglib_del, + jdeferr_del, + jerror_del, + jinclude_del, jutils_del; + +{ Initialize the input controller module. + This is called only once, when the decompression object is created. } + +{GLOBAL} +procedure jinit_input_controller (cinfo : j_decompress_ptr); + +implementation + +{ Private state } + +type + my_inputctl_ptr = ^my_input_controller; + my_input_controller = record + pub : jpeg_input_controller; { public fields } + + inheaders : boolean; { TRUE until first SOS is reached } + end; {my_input_controller;} + + + +{ Forward declarations } +{METHODDEF} +function consume_markers (cinfo : j_decompress_ptr) : int; forward; + + +{ Routines to calculate various quantities related to the size of the image. } + +{LOCAL} +procedure initial_setup (cinfo : j_decompress_ptr); +{ Called once, when first SOS marker is reached } +var + ci : int; + compptr : jpeg_component_info_ptr; +begin + { Make sure image isn't bigger than I can handle } + if (long(cinfo^.image_height) > long (JPEG_MAX_DIMENSION)) or + (long(cinfo^.image_width) > long(JPEG_MAX_DIMENSION)) then + ERREXIT1(j_common_ptr(cinfo), JERR_IMAGE_TOO_BIG, uInt(JPEG_MAX_DIMENSION)); + + { For now, precision must match compiled-in value... } + if (cinfo^.data_precision <> BITS_IN_JSAMPLE) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_PRECISION, cinfo^.data_precision); + + { Check that number of components won't exceed internal array sizes } + if (cinfo^.num_components > MAX_COMPONENTS) then + ERREXIT2(j_common_ptr(cinfo), JERR_COMPONENT_COUNT, cinfo^.num_components, + MAX_COMPONENTS); + + { Compute maximum sampling factors; check factor validity } + cinfo^.max_h_samp_factor := 1; + cinfo^.max_v_samp_factor := 1; + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + if (compptr^.h_samp_factor<=0) or (compptr^.h_samp_factor>MAX_SAMP_FACTOR) or + (compptr^.v_samp_factor<=0) or (compptr^.v_samp_factor>MAX_SAMP_FACTOR) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_SAMPLING); + {cinfo^.max_h_samp_factor := MAX(cinfo^.max_h_samp_factor, + compptr^.h_samp_factor); + cinfo^.max_v_samp_factor := MAX(cinfo^.max_v_samp_factor, + compptr^.v_samp_factor);} + if cinfo^.max_h_samp_factor < compptr^.h_samp_factor then + cinfo^.max_h_samp_factor := compptr^.h_samp_factor; + if cinfo^.max_v_samp_factor < compptr^.v_samp_factor then + cinfo^.max_v_samp_factor := compptr^.v_samp_factor; + Inc(compptr); + end; + + { We initialize DCT_scaled_size and min_DCT_scaled_size to DCTSIZE. + In the full decompressor, this will be overridden by jdmaster.c; + but in the transcoder, jdmaster.c is not used, so we must do it here. } + + cinfo^.min_DCT_scaled_size := DCTSIZE; + + { Compute dimensions of components } + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + compptr^.DCT_scaled_size := DCTSIZE; + { Size in DCT blocks } + compptr^.width_in_blocks := JDIMENSION( + jdiv_round_up( long(cinfo^.image_width) * long(compptr^.h_samp_factor), + long(cinfo^.max_h_samp_factor * DCTSIZE)) ); + compptr^.height_in_blocks := JDIMENSION ( + jdiv_round_up(long (cinfo^.image_height) * long(compptr^.v_samp_factor), + long (cinfo^.max_v_samp_factor * DCTSIZE)) ); + { downsampled_width and downsampled_height will also be overridden by + jdmaster.c if we are doing full decompression. The transcoder library + doesn't use these values, but the calling application might. } + + { Size in samples } + compptr^.downsampled_width := JDIMENSION ( + jdiv_round_up(long (cinfo^.image_width) * long(compptr^.h_samp_factor), + long (cinfo^.max_h_samp_factor)) ); + compptr^.downsampled_height := JDIMENSION ( + jdiv_round_up(long (cinfo^.image_height) * long(compptr^.v_samp_factor), + long (cinfo^.max_v_samp_factor)) ); + { Mark component needed, until color conversion says otherwise } + compptr^.component_needed := TRUE; + { Mark no quantization table yet saved for component } + compptr^.quant_table := NIL; + Inc(compptr); + end; + + { Compute number of fully interleaved MCU rows. } + cinfo^.total_iMCU_rows := JDIMENSION( + jdiv_round_up(long(cinfo^.image_height), + long(cinfo^.max_v_samp_factor*DCTSIZE)) ); + + { Decide whether file contains multiple scans } + if (cinfo^.comps_in_scan < cinfo^.num_components) or + (cinfo^.progressive_mode) then + cinfo^.inputctl^.has_multiple_scans := TRUE + else + cinfo^.inputctl^.has_multiple_scans := FALSE; +end; + + +{LOCAL} +procedure per_scan_setup (cinfo : j_decompress_ptr); +{ Do computations that are needed before processing a JPEG scan } +{ cinfo^.comps_in_scan and cinfo^.cur_comp_info[] were set from SOS marker } +var + ci, mcublks, tmp : int; + compptr : jpeg_component_info_ptr; +begin + if (cinfo^.comps_in_scan = 1) then + begin + { Noninterleaved (single-component) scan } + compptr := cinfo^.cur_comp_info[0]; + + { Overall image size in MCUs } + cinfo^.MCUs_per_row := compptr^.width_in_blocks; + cinfo^.MCU_rows_in_scan := compptr^.height_in_blocks; + + { For noninterleaved scan, always one block per MCU } + compptr^.MCU_width := 1; + compptr^.MCU_height := 1; + compptr^.MCU_blocks := 1; + compptr^.MCU_sample_width := compptr^.DCT_scaled_size; + compptr^.last_col_width := 1; + { For noninterleaved scans, it is convenient to define last_row_height + as the number of block rows present in the last iMCU row. } + + tmp := int (compptr^.height_in_blocks mod compptr^.v_samp_factor); + if (tmp = 0) then + tmp := compptr^.v_samp_factor; + compptr^.last_row_height := tmp; + + { Prepare array describing MCU composition } + cinfo^.blocks_in_MCU := 1; + cinfo^.MCU_membership[0] := 0; + + end + else + begin + + { Interleaved (multi-component) scan } + if (cinfo^.comps_in_scan <= 0) or (cinfo^.comps_in_scan > MAX_COMPS_IN_SCAN) then + ERREXIT2(j_common_ptr(cinfo), JERR_COMPONENT_COUNT, cinfo^.comps_in_scan, + MAX_COMPS_IN_SCAN); + + { Overall image size in MCUs } + cinfo^.MCUs_per_row := JDIMENSION ( + jdiv_round_up(long (cinfo^.image_width), + long (cinfo^.max_h_samp_factor*DCTSIZE)) ); + cinfo^.MCU_rows_in_scan := JDIMENSION ( + jdiv_round_up(long (cinfo^.image_height), + long (cinfo^.max_v_samp_factor*DCTSIZE)) ); + + cinfo^.blocks_in_MCU := 0; + + for ci := 0 to pred(cinfo^.comps_in_scan) do + begin + compptr := cinfo^.cur_comp_info[ci]; + { Sampling factors give # of blocks of component in each MCU } + compptr^.MCU_width := compptr^.h_samp_factor; + compptr^.MCU_height := compptr^.v_samp_factor; + compptr^.MCU_blocks := compptr^.MCU_width * compptr^.MCU_height; + compptr^.MCU_sample_width := compptr^.MCU_width * compptr^.DCT_scaled_size; + { Figure number of non-dummy blocks in last MCU column & row } + tmp := int (compptr^.width_in_blocks mod compptr^.MCU_width); + if (tmp = 0) then + tmp := compptr^.MCU_width; + compptr^.last_col_width := tmp; + tmp := int (compptr^.height_in_blocks mod compptr^.MCU_height); + if (tmp = 0) then + tmp := compptr^.MCU_height; + compptr^.last_row_height := tmp; + { Prepare array describing MCU composition } + mcublks := compptr^.MCU_blocks; + if (cinfo^.blocks_in_MCU + mcublks > D_MAX_BLOCKS_IN_MCU) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_MCU_SIZE); + while (mcublks > 0) do + begin + Dec(mcublks); + cinfo^.MCU_membership[cinfo^.blocks_in_MCU] := ci; + Inc(cinfo^.blocks_in_MCU); + end; + end; + + end; +end; + + +{ Save away a copy of the Q-table referenced by each component present + in the current scan, unless already saved during a prior scan. + + In a multiple-scan JPEG file, the encoder could assign different components + the same Q-table slot number, but change table definitions between scans + so that each component uses a different Q-table. (The IJG encoder is not + currently capable of doing this, but other encoders might.) Since we want + to be able to dequantize all the components at the end of the file, this + means that we have to save away the table actually used for each component. + We do this by copying the table at the start of the first scan containing + the component. + The JPEG spec prohibits the encoder from changing the contents of a Q-table + slot between scans of a component using that slot. If the encoder does so + anyway, this decoder will simply use the Q-table values that were current + at the start of the first scan for the component. + + The decompressor output side looks only at the saved quant tables, + not at the current Q-table slots. } + +{LOCAL} +procedure latch_quant_tables (cinfo : j_decompress_ptr); +var + ci, qtblno : int; + compptr : jpeg_component_info_ptr; + qtbl : JQUANT_TBL_PTR; +begin + for ci := 0 to pred(cinfo^.comps_in_scan) do + begin + compptr := cinfo^.cur_comp_info[ci]; + { No work if we already saved Q-table for this component } + if (compptr^.quant_table <> NIL) then + continue; + { Make sure specified quantization table is present } + qtblno := compptr^.quant_tbl_no; + if (qtblno < 0) or (qtblno >= NUM_QUANT_TBLS) or + (cinfo^.quant_tbl_ptrs[qtblno] = NIL) then + ERREXIT1(j_common_ptr(cinfo), JERR_NO_QUANT_TABLE, qtblno); + { OK, save away the quantization table } + qtbl := JQUANT_TBL_PTR( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(JQUANT_TBL)) ); + MEMCOPY(qtbl, cinfo^.quant_tbl_ptrs[qtblno], SIZEOF(JQUANT_TBL)); + compptr^.quant_table := qtbl; + end; +end; + + +{ Initialize the input modules to read a scan of compressed data. + The first call to this is done by jdmaster.c after initializing + the entire decompressor (during jpeg_start_decompress). + Subsequent calls come from consume_markers, below. } + +{METHODDEF} +procedure start_input_pass (cinfo : j_decompress_ptr); +begin + per_scan_setup(cinfo); + latch_quant_tables(cinfo); + cinfo^.entropy^.start_pass (cinfo); + cinfo^.coef^.start_input_pass (cinfo); + cinfo^.inputctl^.consume_input := cinfo^.coef^.consume_data; +end; + + +{ Finish up after inputting a compressed-data scan. + This is called by the coefficient controller after it's read all + the expected data of the scan. } + +{METHODDEF} +procedure finish_input_pass (cinfo : j_decompress_ptr); +begin + cinfo^.inputctl^.consume_input := consume_markers; +end; + + +{ Read JPEG markers before, between, or after compressed-data scans. + Change state as necessary when a new scan is reached. + Return value is JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI. + + The consume_input method pointer points either here or to the + coefficient controller's consume_data routine, depending on whether + we are reading a compressed data segment or inter-segment markers. } + +{METHODDEF} +function consume_markers (cinfo : j_decompress_ptr) : int; +var + val : int; + inputctl : my_inputctl_ptr; +begin + inputctl := my_inputctl_ptr (cinfo^.inputctl); + + if (inputctl^.pub.eoi_reached) then { After hitting EOI, read no further } + begin + consume_markers := JPEG_REACHED_EOI; + exit; + end; + + val := cinfo^.marker^.read_markers (cinfo); + + case (val) of + JPEG_REACHED_SOS: { Found SOS } + begin + if (inputctl^.inheaders) then + begin { 1st SOS } + initial_setup(cinfo); + inputctl^.inheaders := FALSE; + { Note: start_input_pass must be called by jdmaster.c + before any more input can be consumed. jdapimin.c is + responsible for enforcing this sequencing. } + end + else + begin { 2nd or later SOS marker } + if (not inputctl^.pub.has_multiple_scans) then + ERREXIT(j_common_ptr(cinfo), JERR_EOI_EXPECTED); { Oops, I wasn't expecting this! } + start_input_pass(cinfo); + end; + end; + JPEG_REACHED_EOI: { Found EOI } + begin + inputctl^.pub.eoi_reached := TRUE; + if (inputctl^.inheaders) then + begin { Tables-only datastream, apparently } + if (cinfo^.marker^.saw_SOF) then + ERREXIT(j_common_ptr(cinfo), JERR_SOF_NO_SOS); + end + else + begin + { Prevent infinite loop in coef ctlr's decompress_data routine + if user set output_scan_number larger than number of scans. } + + if (cinfo^.output_scan_number > cinfo^.input_scan_number) then + cinfo^.output_scan_number := cinfo^.input_scan_number; + end; + end; + JPEG_SUSPENDED:; + end; + + consume_markers := val; +end; + + +{ Reset state to begin a fresh datastream. } + +{METHODDEF} +procedure reset_input_controller (cinfo : j_decompress_ptr); +var + inputctl : my_inputctl_ptr; +begin + inputctl := my_inputctl_ptr (cinfo^.inputctl); + + inputctl^.pub.consume_input := consume_markers; + inputctl^.pub.has_multiple_scans := FALSE; { "unknown" would be better } + inputctl^.pub.eoi_reached := FALSE; + inputctl^.inheaders := TRUE; + { Reset other modules } + cinfo^.err^.reset_error_mgr (j_common_ptr(cinfo)); + cinfo^.marker^.reset_marker_reader (cinfo); + { Reset progression state -- would be cleaner if entropy decoder did this } + cinfo^.coef_bits := NIL; +end; + + +{ Initialize the input controller module. + This is called only once, when the decompression object is created. } + +{GLOBAL} +procedure jinit_input_controller (cinfo : j_decompress_ptr); +var + inputctl : my_inputctl_ptr; +begin + { Create subobject in permanent pool } + inputctl := my_inputctl_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_PERMANENT, + SIZEOF(my_input_controller)) ); + cinfo^.inputctl := jpeg_input_controller_ptr(inputctl); + { Initialize method pointers } + inputctl^.pub.consume_input := consume_markers; + inputctl^.pub.reset_input_controller := reset_input_controller; + inputctl^.pub.start_input_pass := start_input_pass; + inputctl^.pub.finish_input_pass := finish_input_pass; + { Initialize state: can't use reset_input_controller since we don't + want to try to reset other modules yet. } + + inputctl^.pub.has_multiple_scans := FALSE; { "unknown" would be better } + inputctl^.pub.eoi_reached := FALSE; + inputctl^.inheaders := TRUE; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jdmainct_del.pas b/mseide-msegui/lib/common/fpccompatibility/jdmainct_del.pas new file mode 100644 index 0000000..3a0f65c --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jdmainct_del.pas @@ -0,0 +1,611 @@ +unit jdmainct_del; + + +{ This file is part of the Independent JPEG Group's software. + For conditions of distribution and use, see the accompanying README file. + + This file contains the main buffer controller for decompression. + The main buffer lies between the JPEG decompressor proper and the + post-processor; it holds downsampled data in the JPEG colorspace. + + Note that this code is bypassed in raw-data mode, since the application + supplies the equivalent of the main buffer in that case. } + +{ Original: jdmainct.c ; Copyright (C) 1994-1996, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + + +{ In the current system design, the main buffer need never be a full-image + buffer; any full-height buffers will be found inside the coefficient or + postprocessing controllers. Nonetheless, the main controller is not + trivial. Its responsibility is to provide context rows for upsampling/ + rescaling, and doing this in an efficient fashion is a bit tricky. + + Postprocessor input data is counted in "row groups". A row group + is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size) + sample rows of each component. (We require DCT_scaled_size values to be + chosen such that these numbers are integers. In practice DCT_scaled_size + values will likely be powers of two, so we actually have the stronger + condition that DCT_scaled_size / min_DCT_scaled_size is an integer.) + Upsampling will typically produce max_v_samp_factor pixel rows from each + row group (times any additional scale factor that the upsampler is + applying). + + The coefficient controller will deliver data to us one iMCU row at a time; + each iMCU row contains v_samp_factor * DCT_scaled_size sample rows, or + exactly min_DCT_scaled_size row groups. (This amount of data corresponds + to one row of MCUs when the image is fully interleaved.) Note that the + number of sample rows varies across components, but the number of row + groups does not. Some garbage sample rows may be included in the last iMCU + row at the bottom of the image. + + Depending on the vertical scaling algorithm used, the upsampler may need + access to the sample row(s) above and below its current input row group. + The upsampler is required to set need_context_rows TRUE at global + selection + time if so. When need_context_rows is FALSE, this controller can simply + obtain one iMCU row at a time from the coefficient controller and dole it + out as row groups to the postprocessor. + + When need_context_rows is TRUE, this controller guarantees that the buffer + passed to postprocessing contains at least one row group's worth of samples + above and below the row group(s) being processed. Note that the context + rows "above" the first passed row group appear at negative row offsets in + the passed buffer. At the top and bottom of the image, the required + context rows are manufactured by duplicating the first or last real sample + row; this avoids having special cases in the upsampling inner loops. + + The amount of context is fixed at one row group just because that's a + convenient number for this controller to work with. The existing + upsamplers really only need one sample row of context. An upsampler + supporting arbitrary output rescaling might wish for more than one row + group of context when shrinking the image; tough, we don't handle that. + (This is justified by the assumption that downsizing will be handled mostly + by adjusting the DCT_scaled_size values, so that the actual scale factor at + the upsample step needn't be much less than one.) + + To provide the desired context, we have to retain the last two row groups + of one iMCU row while reading in the next iMCU row. (The last row group + can't be processed until we have another row group for its below-context, + and so we have to save the next-to-last group too for its above-context.) + We could do this most simply by copying data around in our buffer, but + that'd be very slow. We can avoid copying any data by creating a rather + strange pointer structure. Here's how it works. We allocate a workspace + consisting of M+2 row groups (where M = min_DCT_scaled_size is the number + of row groups per iMCU row). We create two sets of redundant pointers to + the workspace. Labeling the physical row groups 0 to M+1, the synthesized + pointer lists look like this: + M+1 M-1 + master pointer --> 0 master pointer --> 0 + 1 1 + ... ... + M-3 M-3 + M-2 M + M-1 M+1 + M M-2 + M+1 M-1 + 0 0 + We read alternate iMCU rows using each master pointer; thus the last two + row groups of the previous iMCU row remain un-overwritten in the workspace. + The pointer lists are set up so that the required context rows appear to + be adjacent to the proper places when we pass the pointer lists to the + upsampler. + + The above pictures describe the normal state of the pointer lists. + At top and bottom of the image, we diddle the pointer lists to duplicate + the first or last sample row as necessary (this is cheaper than copying + sample rows around). + + This scheme breaks down if M < 2, ie, min_DCT_scaled_size is 1. In that + situation each iMCU row provides only one row group so the buffering logic + must be different (eg, we must read two iMCU rows before we can emit the + first row group). For now, we simply do not support providing context + rows when min_DCT_scaled_size is 1. That combination seems unlikely to + be worth providing --- if someone wants a 1/8th-size preview, they probably + want it quick and dirty, so a context-free upsampler is sufficient. } + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, +{$ifdef QUANT_2PASS_SUPPORTED} + jquant2_del, +{$endif} + jdeferr_del, + jerror_del, + jpeglib_del; + + +{GLOBAL} +procedure jinit_d_main_controller (cinfo : j_decompress_ptr; + need_full_buffer : boolean); + + +implementation + +{ Private buffer controller object } + +type + my_main_ptr = ^my_main_controller; + my_main_controller = record + pub : jpeg_d_main_controller; { public fields } + + { Pointer to allocated workspace (M or M+2 row groups). } + buffer : array[0..MAX_COMPONENTS-1] of JSAMPARRAY; + + buffer_full : boolean; { Have we gotten an iMCU row from decoder? } + rowgroup_ctr : JDIMENSION ; { counts row groups output to postprocessor } + + { Remaining fields are only used in the context case. } + + { These are the master pointers to the funny-order pointer lists. } + xbuffer : array[0..2-1] of JSAMPIMAGE; { pointers to weird pointer lists } + + whichptr : int; { indicates which pointer set is now in use } + context_state : int; { process_data state machine status } + rowgroups_avail : JDIMENSION; { row groups available to postprocessor } + iMCU_row_ctr : JDIMENSION; { counts iMCU rows to detect image top/bot } + end; { my_main_controller; } + + +{ context_state values: } +const + CTX_PREPARE_FOR_IMCU = 0; { need to prepare for MCU row } + CTX_PROCESS_IMCU = 1; { feeding iMCU to postprocessor } + CTX_POSTPONED_ROW = 2; { feeding postponed row group } + + +{ Forward declarations } +{METHODDEF} +procedure process_data_simple_main(cinfo : j_decompress_ptr; + output_buf : JSAMPARRAY; + var out_row_ctr : JDIMENSION; + out_rows_avail : JDIMENSION); forward; +{METHODDEF} +procedure process_data_context_main (cinfo : j_decompress_ptr; + output_buf : JSAMPARRAY; + var out_row_ctr : JDIMENSION; + out_rows_avail : JDIMENSION); forward; + +{$ifdef QUANT_2PASS_SUPPORTED} +{METHODDEF} +procedure process_data_crank_post (cinfo : j_decompress_ptr; + output_buf : JSAMPARRAY; + var out_row_ctr : JDIMENSION; + out_rows_avail : JDIMENSION); forward; +{$endif} + + +{LOCAL} +procedure alloc_funny_pointers (cinfo : j_decompress_ptr); +{ Allocate space for the funny pointer lists. + This is done only once, not once per pass. } +var + main : my_main_ptr; + ci, rgroup : int; + M : int; + compptr : jpeg_component_info_ptr; + xbuf : JSAMPARRAY; +begin + main := my_main_ptr (cinfo^.main); + M := cinfo^.min_DCT_scaled_size; + + { Get top-level space for component array pointers. + We alloc both arrays with one call to save a few cycles. } + + main^.xbuffer[0] := JSAMPIMAGE ( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + cinfo^.num_components * 2 * SIZEOF(JSAMPARRAY)) ); + main^.xbuffer[1] := JSAMPIMAGE(@( main^.xbuffer[0]^[cinfo^.num_components] )); + + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + rgroup := (compptr^.v_samp_factor * compptr^.DCT_scaled_size) div + cinfo^.min_DCT_scaled_size; { height of a row group of component } + { Get space for pointer lists --- M+4 row groups in each list. + We alloc both pointer lists with one call to save a few cycles. } + + xbuf := JSAMPARRAY ( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + 2 * (rgroup * (M + 4)) * SIZEOF(JSAMPROW)) ); + Inc(JSAMPROW_PTR(xbuf), rgroup); { want one row group at negative offsets } + main^.xbuffer[0]^[ci] := xbuf; + Inc(JSAMPROW_PTR(xbuf), rgroup * (M + 4)); + main^.xbuffer[1]^[ci] := xbuf; + Inc(compptr); + end; +end; + +{LOCAL} +procedure make_funny_pointers (cinfo : j_decompress_ptr); +{ Create the funny pointer lists discussed in the comments above. + The actual workspace is already allocated (in main^.buffer), + and the space for the pointer lists is allocated too. + This routine just fills in the curiously ordered lists. + This will be repeated at the beginning of each pass. } +var + main : my_main_ptr; + ci, i, rgroup : int; + M : int; + compptr : jpeg_component_info_ptr; + buf, xbuf0, xbuf1 : JSAMPARRAY; +var + help_xbuf0 : JSAMPARRAY; { work around negative offsets } +begin + main := my_main_ptr (cinfo^.main); + M := cinfo^.min_DCT_scaled_size; + + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + rgroup := (compptr^.v_samp_factor * compptr^.DCT_scaled_size) div + cinfo^.min_DCT_scaled_size; { height of a row group of component } + xbuf0 := main^.xbuffer[0]^[ci]; + xbuf1 := main^.xbuffer[1]^[ci]; + { First copy the workspace pointers as-is } + buf := main^.buffer[ci]; + for i := 0 to pred(rgroup * (M + 2)) do + begin + xbuf0^[i] := buf^[i]; + xbuf1^[i] := buf^[i]; + end; + { In the second list, put the last four row groups in swapped order } + for i := 0 to pred(rgroup * 2) do + begin + xbuf1^[rgroup*(M-2) + i] := buf^[rgroup*M + i]; + xbuf1^[rgroup*M + i] := buf^[rgroup*(M-2) + i]; + end; + { The wraparound pointers at top and bottom will be filled later + (see set_wraparound_pointers, below). Initially we want the "above" + pointers to duplicate the first actual data line. This only needs + to happen in xbuffer[0]. } + + help_xbuf0 := xbuf0; + Dec(JSAMPROW_PTR(help_xbuf0), rgroup); + + for i := 0 to pred(rgroup) do + begin + {xbuf0^[i - rgroup] := xbuf0^[0];} + help_xbuf0^[i] := xbuf0^[0]; + end; + Inc(compptr); + end; +end; + + +{LOCAL} +procedure set_wraparound_pointers (cinfo : j_decompress_ptr); +{ Set up the "wraparound" pointers at top and bottom of the pointer lists. + This changes the pointer list state from top-of-image to the normal state. } +var + main : my_main_ptr; + ci, i, rgroup : int; + M : int; + compptr : jpeg_component_info_ptr; + xbuf0, xbuf1 : JSAMPARRAY; +var + help_xbuf0, + help_xbuf1 : JSAMPARRAY; { work around negative offsets } +begin + main := my_main_ptr (cinfo^.main); + M := cinfo^.min_DCT_scaled_size; + + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + rgroup := (compptr^.v_samp_factor * compptr^.DCT_scaled_size) div + cinfo^.min_DCT_scaled_size; { height of a row group of component } + xbuf0 := main^.xbuffer[0]^[ci]; + xbuf1 := main^.xbuffer[1]^[ci]; + + help_xbuf0 := xbuf0; + Dec(JSAMPROW_PTR(help_xbuf0), rgroup); + help_xbuf1 := xbuf1; + Dec(JSAMPROW_PTR(help_xbuf1), rgroup); + + for i := 0 to pred(rgroup) do + begin + {xbuf0^[i - rgroup] := xbuf0^[rgroup*(M+1) + i]; + xbuf1^[i - rgroup] := xbuf1^[rgroup*(M+1) + i];} + + help_xbuf0^[i] := xbuf0^[rgroup*(M+1) + i]; + help_xbuf1^[i] := xbuf1^[rgroup*(M+1) + i]; + + xbuf0^[rgroup*(M+2) + i] := xbuf0^[i]; + xbuf1^[rgroup*(M+2) + i] := xbuf1^[i]; + end; + Inc(compptr); + end; +end; + + +{LOCAL} +procedure set_bottom_pointers (cinfo : j_decompress_ptr); +{ Change the pointer lists to duplicate the last sample row at the bottom + of the image. whichptr indicates which xbuffer holds the final iMCU row. + Also sets rowgroups_avail to indicate number of nondummy row groups in row. } +var + main : my_main_ptr; + ci, i, rgroup, iMCUheight, rows_left : int; + compptr : jpeg_component_info_ptr; + xbuf : JSAMPARRAY; +begin + main := my_main_ptr (cinfo^.main); + + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + { Count sample rows in one iMCU row and in one row group } + iMCUheight := compptr^.v_samp_factor * compptr^.DCT_scaled_size; + rgroup := iMCUheight div cinfo^.min_DCT_scaled_size; + { Count nondummy sample rows remaining for this component } + rows_left := int (compptr^.downsampled_height mod JDIMENSION (iMCUheight)); + if (rows_left = 0) then + rows_left := iMCUheight; + { Count nondummy row groups. Should get same answer for each component, + so we need only do it once. } + if (ci = 0) then + begin + main^.rowgroups_avail := JDIMENSION ((rows_left-1) div rgroup + 1); + end; + { Duplicate the last real sample row rgroup*2 times; this pads out the + last partial rowgroup and ensures at least one full rowgroup of context. } + + xbuf := main^.xbuffer[main^.whichptr]^[ci]; + for i := 0 to pred(rgroup * 2) do + begin + xbuf^[rows_left + i] := xbuf^[rows_left-1]; + end; + Inc(compptr); + end; +end; + + +{ Initialize for a processing pass. } + +{METHODDEF} +procedure start_pass_main (cinfo : j_decompress_ptr; + pass_mode : J_BUF_MODE); +var + main : my_main_ptr; +begin + main := my_main_ptr (cinfo^.main); + + case (pass_mode) of + JBUF_PASS_THRU: + begin + if (cinfo^.upsample^.need_context_rows) then + begin + main^.pub.process_data := process_data_context_main; + make_funny_pointers(cinfo); { Create the xbuffer[] lists } + main^.whichptr := 0; { Read first iMCU row into xbuffer[0] } + main^.context_state := CTX_PREPARE_FOR_IMCU; + main^.iMCU_row_ctr := 0; + end + else + begin + { Simple case with no context needed } + main^.pub.process_data := process_data_simple_main; + end; + main^.buffer_full := FALSE; { Mark buffer empty } + main^.rowgroup_ctr := 0; + end; +{$ifdef QUANT_2PASS_SUPPORTED} + JBUF_CRANK_DEST: + { For last pass of 2-pass quantization, just crank the postprocessor } + main^.pub.process_data := process_data_crank_post; +{$endif} + else + ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE); + end; +end; + + +{ Process some data. + This handles the simple case where no context is required. } + +{METHODDEF} +procedure process_data_simple_main (cinfo : j_decompress_ptr; + output_buf : JSAMPARRAY; + var out_row_ctr : JDIMENSION; + out_rows_avail : JDIMENSION); +var + main : my_main_ptr; + rowgroups_avail : JDIMENSION; +var + main_buffer_ptr : JSAMPIMAGE; +begin + main := my_main_ptr (cinfo^.main); + main_buffer_ptr := JSAMPIMAGE(@(main^.buffer)); + + { Read input data if we haven't filled the main buffer yet } + if (not main^.buffer_full) then + begin + if (cinfo^.coef^.decompress_data (cinfo, main_buffer_ptr)=0) then + exit; { suspension forced, can do nothing more } + main^.buffer_full := TRUE; { OK, we have an iMCU row to work with } + end; + + { There are always min_DCT_scaled_size row groups in an iMCU row. } + rowgroups_avail := JDIMENSION (cinfo^.min_DCT_scaled_size); + { Note: at the bottom of the image, we may pass extra garbage row groups + to the postprocessor. The postprocessor has to check for bottom + of image anyway (at row resolution), so no point in us doing it too. } + + { Feed the postprocessor } + cinfo^.post^.post_process_data (cinfo, main_buffer_ptr, + main^.rowgroup_ctr, rowgroups_avail, + output_buf, out_row_ctr, out_rows_avail); + + { Has postprocessor consumed all the data yet? If so, mark buffer empty } + if (main^.rowgroup_ctr >= rowgroups_avail) then + begin + main^.buffer_full := FALSE; + main^.rowgroup_ctr := 0; + end; +end; + + +{ Process some data. + This handles the case where context rows must be provided. } + +{METHODDEF} +procedure process_data_context_main (cinfo : j_decompress_ptr; + output_buf : JSAMPARRAY; + var out_row_ctr : JDIMENSION; + out_rows_avail : JDIMENSION); +var + main : my_main_ptr; +begin + main := my_main_ptr (cinfo^.main); + + { Read input data if we haven't filled the main buffer yet } + if (not main^.buffer_full) then + begin + if (cinfo^.coef^.decompress_data (cinfo, + main^.xbuffer[main^.whichptr])=0) then + exit; { suspension forced, can do nothing more } + main^.buffer_full := TRUE; { OK, we have an iMCU row to work with } + Inc(main^.iMCU_row_ctr); { count rows received } + end; + + { Postprocessor typically will not swallow all the input data it is handed + in one call (due to filling the output buffer first). Must be prepared + to exit and restart. This switch lets us keep track of how far we got. + Note that each case falls through to the next on successful completion. } + + case (main^.context_state) of + CTX_POSTPONED_ROW: + begin + { Call postprocessor using previously set pointers for postponed row } + cinfo^.post^.post_process_data (cinfo, main^.xbuffer[main^.whichptr], + main^.rowgroup_ctr, main^.rowgroups_avail, + output_buf, out_row_ctr, out_rows_avail); + if (main^.rowgroup_ctr < main^.rowgroups_avail) then + exit; { Need to suspend } + main^.context_state := CTX_PREPARE_FOR_IMCU; + if (out_row_ctr >= out_rows_avail) then + exit; { Postprocessor exactly filled output buf } + end; + end; + case (main^.context_state) of + CTX_POSTPONED_ROW, + CTX_PREPARE_FOR_IMCU: {FALLTHROUGH} + begin + { Prepare to process first M-1 row groups of this iMCU row } + main^.rowgroup_ctr := 0; + main^.rowgroups_avail := JDIMENSION (cinfo^.min_DCT_scaled_size - 1); + { Check for bottom of image: if so, tweak pointers to "duplicate" + the last sample row, and adjust rowgroups_avail to ignore padding rows. } + + if (main^.iMCU_row_ctr = cinfo^.total_iMCU_rows) then + set_bottom_pointers(cinfo); + main^.context_state := CTX_PROCESS_IMCU; + + end; + end; + case (main^.context_state) of + CTX_POSTPONED_ROW, + CTX_PREPARE_FOR_IMCU, {FALLTHROUGH} + CTX_PROCESS_IMCU: + begin + { Call postprocessor using previously set pointers } + cinfo^.post^.post_process_data (cinfo, main^.xbuffer[main^.whichptr], + main^.rowgroup_ctr, main^.rowgroups_avail, + output_buf, out_row_ctr, out_rows_avail); + if (main^.rowgroup_ctr < main^.rowgroups_avail) then + exit; { Need to suspend } + { After the first iMCU, change wraparound pointers to normal state } + if (main^.iMCU_row_ctr = 1) then + set_wraparound_pointers(cinfo); + { Prepare to load new iMCU row using other xbuffer list } + main^.whichptr := main^.whichptr xor 1; { 0=>1 or 1=>0 } + main^.buffer_full := FALSE; + { Still need to process last row group of this iMCU row, } + { which is saved at index M+1 of the other xbuffer } + main^.rowgroup_ctr := JDIMENSION (cinfo^.min_DCT_scaled_size + 1); + main^.rowgroups_avail := JDIMENSION (cinfo^.min_DCT_scaled_size + 2); + main^.context_state := CTX_POSTPONED_ROW; + end; + end; +end; + + +{ Process some data. + Final pass of two-pass quantization: just call the postprocessor. + Source data will be the postprocessor controller's internal buffer. } + +{$ifdef QUANT_2PASS_SUPPORTED} + +{METHODDEF} +procedure process_data_crank_post (cinfo : j_decompress_ptr; + output_buf : JSAMPARRAY; + var out_row_ctr : JDIMENSION; + out_rows_avail : JDIMENSION); +var + in_row_group_ctr : JDIMENSION; +begin + in_row_group_ctr := 0; + cinfo^.post^.post_process_data (cinfo, JSAMPIMAGE (NIL), + in_row_group_ctr, + JDIMENSION(0), + output_buf, + out_row_ctr, + out_rows_avail); +end; + +{$endif} { QUANT_2PASS_SUPPORTED } + + +{ Initialize main buffer controller. } + +{GLOBAL} +procedure jinit_d_main_controller (cinfo : j_decompress_ptr; + need_full_buffer : boolean); +var + main : my_main_ptr; + ci, rgroup, ngroups : int; + compptr : jpeg_component_info_ptr; +begin + main := my_main_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(my_main_controller)) ); + cinfo^.main := jpeg_d_main_controller_ptr(main); + main^.pub.start_pass := start_pass_main; + + if (need_full_buffer) then { shouldn't happen } + ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE); + + { Allocate the workspace. + ngroups is the number of row groups we need.} + + if (cinfo^.upsample^.need_context_rows) then + begin + if (cinfo^.min_DCT_scaled_size < 2) then { unsupported, see comments above } + ERREXIT(j_common_ptr(cinfo), JERR_NOTIMPL); + alloc_funny_pointers(cinfo); { Alloc space for xbuffer[] lists } + ngroups := cinfo^.min_DCT_scaled_size + 2; + end + else + begin + ngroups := cinfo^.min_DCT_scaled_size; + end; + + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + rgroup := (compptr^.v_samp_factor * compptr^.DCT_scaled_size) div + cinfo^.min_DCT_scaled_size; { height of a row group of component } + main^.buffer[ci] := cinfo^.mem^.alloc_sarray + (j_common_ptr(cinfo), JPOOL_IMAGE, + compptr^.width_in_blocks * compptr^.DCT_scaled_size, + JDIMENSION (rgroup * ngroups)); + Inc(compptr); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jdmarker_del.pas b/mseide-msegui/lib/common/fpccompatibility/jdmarker_del.pas new file mode 100644 index 0000000..f8930db --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jdmarker_del.pas @@ -0,0 +1,2658 @@ +unit jdmarker_del; + +{ This file contains routines to decode JPEG datastream markers. + Most of the complexity arises from our desire to support input + suspension: if not all of the data for a marker is available; + we must exit back to the application. On resumption; we reprocess + the marker. } + +{ Original: jdmarker.c; Copyright (C) 1991-1998; Thomas G. Lane. } +{ History + 9.7.96 Conversion to pascal started jnn + 22.3.98 updated to 6b jnn } +//modified 2013 by Martin Schreiber + + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jdeferr_del, + jerror_del, + jcomapi_del, + jpeglib_del; + +const { JPEG marker codes } + M_SOF0 = $c0; + M_SOF1 = $c1; + M_SOF2 = $c2; + M_SOF3 = $c3; + + M_SOF5 = $c5; + M_SOF6 = $c6; + M_SOF7 = $c7; + + M_JPG = $c8; + M_SOF9 = $c9; + M_SOF10 = $ca; + M_SOF11 = $cb; + + M_SOF13 = $cd; + M_SOF14 = $ce; + M_SOF15 = $cf; + + M_DHT = $c4; + + M_DAC = $cc; + + M_RST0 = $d0; + M_RST1 = $d1; + M_RST2 = $d2; + M_RST3 = $d3; + M_RST4 = $d4; + M_RST5 = $d5; + M_RST6 = $d6; + M_RST7 = $d7; + + M_SOI = $d8; + M_EOI = $d9; + M_SOS = $da; + M_DQT = $db; + M_DNL = $dc; + M_DRI = $dd; + M_DHP = $de; + M_EXP = $df; + + M_APP0 = $e0; + M_APP1 = $e1; + M_APP2 = $e2; + M_APP3 = $e3; + M_APP4 = $e4; + M_APP5 = $e5; + M_APP6 = $e6; + M_APP7 = $e7; + M_APP8 = $e8; + M_APP9 = $e9; + M_APP10 = $ea; + M_APP11 = $eb; + M_APP12 = $ec; + M_APP13 = $ed; + M_APP14 = $ee; + M_APP15 = $ef; + + M_JPG0 = $f0; + M_JPG13 = $fd; + M_COM = $fe; + + M_TEM = $01; + + M_ERROR = $100; + +type + JPEG_MARKER = uint; { JPEG marker codes } + +{ Private state } + +type + my_marker_ptr = ^my_marker_reader; + my_marker_reader = record + pub : jpeg_marker_reader; { public fields } + + { Application-overridable marker processing methods } + process_COM : jpeg_marker_parser_method; + process_APPn : array[0..16-1] of jpeg_marker_parser_method; + + { Limit on marker data length to save for each marker type } + length_limit_COM : uint; + length_limit_APPn : array[0..16-1] of uint; + + { Status of COM/APPn marker saving } + cur_marker : jpeg_saved_marker_ptr; { NIL if not processing a marker } + bytes_read : uint; { data bytes read so far in marker } + { Note: cur_marker is not linked into marker_list until it's all read. } + end; + +{GLOBAL} +function jpeg_resync_to_restart(cinfo : j_decompress_ptr; + desired : int) : boolean; +{GLOBAL} +procedure jinit_marker_reader (cinfo : j_decompress_ptr); + +{$ifdef SAVE_MARKERS_SUPPORTED} + +{GLOBAL} +procedure jpeg_save_markers (cinfo : j_decompress_ptr; + marker_code : int; + length_limit : uint); +{$ENDIF} + +{GLOBAL} +procedure jpeg_set_marker_processor (cinfo : j_decompress_ptr; + marker_code : int; + routine : jpeg_marker_parser_method); +Var + on_unknown_marker : function (cinfo : j_decompress_ptr) : int; + +implementation + +uses + jutils_del; + +{ At all times, cinfo1.src.next_input_byte and .bytes_in_buffer reflect + the current restart point; we update them only when we have reached a + suitable place to restart if a suspension occurs. } + + +{ Routines to process JPEG markers. + + Entry condition: JPEG marker itself has been read and its code saved + in cinfo^.unread_marker; input restart point is just after the marker. + + Exit: if return TRUE, have read and processed any parameters, and have + updated the restart point to point after the parameters. + If return FALSE, was forced to suspend before reaching end of + marker parameters; restart point has not been moved. Same routine + will be called again after application supplies more input data. + + This approach to suspension assumes that all of a marker's parameters + can fit into a single input bufferload. This should hold for "normal" + markers. Some COM/APPn markers might have large parameter segments + that might not fit. If we are simply dropping such a marker, we use + skip_input_data to get past it, and thereby put the problem on the + source manager's shoulders. If we are saving the marker's contents + into memory, we use a slightly different convention: when forced to + suspend, the marker processor updates the restart point to the end of + what it's consumed (ie, the end of the buffer) before returning FALSE. + On resumption, cinfo->unread_marker still contains the marker code, + but the data source will point to the next chunk of marker data. + The marker processor must retain internal state to deal with this. + + Note that we don't bother to avoid duplicate trace messages if a + suspension occurs within marker parameters. Other side effects + require more care. } + +{LOCAL} +function get_soi (cinfo : j_decompress_ptr) : boolean; +{ Process an SOI marker } +var + i : int; +begin + {$IFDEF DEBUG} + TRACEMS(j_common_ptr(cinfo), 1, JTRC_SOI); + {$ENDIF} + + if (cinfo^.marker^.saw_SOI) then + ERREXIT(j_common_ptr(cinfo), JERR_SOI_DUPLICATE); + + { Reset all parameters that are defined to be reset by SOI } + + for i := 0 to Pred(NUM_ARITH_TBLS) do + with cinfo^ do + begin + arith_dc_L[i] := 0; + arith_dc_U[i] := 1; + arith_ac_K[i] := 5; + end; + cinfo^.restart_interval := 0; + + { Set initial assumptions for colorspace etc } + + with cinfo^ do + begin + jpeg_color_space := JCS_UNKNOWN; + CCIR601_sampling := FALSE; { Assume non-CCIR sampling??? } + + saw_JFIF_marker := FALSE; + JFIF_major_version := 1; { set default JFIF APP0 values } + JFIF_minor_version := 1; + density_unit := 0; + X_density := 1; + Y_density := 1; + saw_Adobe_marker := FALSE; + Adobe_transform := 0; + + marker^.saw_SOI := TRUE; + end; + get_soi := TRUE; +end; { get_soi } + + +{LOCAL} +function get_sof(cinfo : j_decompress_ptr; + is_prog : boolean; + is_arith : boolean) : boolean; +{ Process a SOFn marker } +var + length : INT32; + c, ci : int; + compptr : jpeg_component_info_ptr; +{ Declare and initialize local copies of input pointer/count } +var + datasrc : jpeg_source_mgr_ptr; + next_input_byte : JOCTETptr; + bytes_in_buffer : size_t; +begin + datasrc := cinfo^.src; + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; +{} + cinfo^.progressive_mode := is_prog; + cinfo^.arith_code := is_arith; + +{ Read two bytes interpreted as an unsigned 16-bit integer. + length should be declared unsigned int or perhaps INT32. } + +{ make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_sof := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + length := (uint( GETJOCTET(next_input_byte^)) shl 8); + Inc( next_input_byte ); + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_sof := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + Inc( length, GETJOCTET( next_input_byte^)); + Inc( next_input_byte ); + + + { Read a byte into variable cinfo^.data_precision. + If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_sof := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + cinfo^.data_precision := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + +{ Read two bytes interpreted as an unsigned 16-bit integer. + cinfo^.image_height should be declared unsigned int or perhaps INT32. } + +{ make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_sof := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + cinfo^.image_height := (uint( GETJOCTET(next_input_byte^)) shl 8); + Inc( next_input_byte ); + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_sof := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + Inc( cinfo^.image_height, GETJOCTET( next_input_byte^)); + Inc( next_input_byte ); + +{ Read two bytes interpreted as an unsigned 16-bit integer. + cinfo^.image_width should be declared unsigned int or perhaps INT32. } + +{ make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_sof := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + cinfo^.image_width := (uint( GETJOCTET(next_input_byte^)) shl 8); + Inc( next_input_byte ); + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_sof := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + Inc( cinfo^.image_width, GETJOCTET( next_input_byte^)); + Inc( next_input_byte ); + + { Read a byte into variable cinfo^.num_components. + If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_sof := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + cinfo^.num_components := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + + Dec(length, 8); + + {$IFDEF DEBUG} + TRACEMS4(j_common_ptr(cinfo), 1, JTRC_SOF, cinfo^.unread_marker, + int(cinfo^.image_width), int(cinfo^.image_height), + cinfo^.num_components); + {$ENDIF} + + if (cinfo^.marker^.saw_SOF) then + ERREXIT(j_common_ptr(cinfo), JERR_SOF_DUPLICATE); + + { We don't support files in which the image height is initially specified } + { as 0 and is later redefined by DNL. As long as we have to check that, } + { might as well have a general sanity check. } + if (cinfo^.image_height <= 0) or (cinfo^.image_width <= 0) + or (cinfo^.num_components <= 0) then + ERREXIT(j_common_ptr(cinfo), JERR_EMPTY_IMAGE); + + if (length <> (cinfo^.num_components * 3)) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_LENGTH); + + if (cinfo^.comp_info = NIL) then { do only once, even if suspend } + cinfo^.comp_info := jpeg_component_info_list_ptr( + cinfo^.mem^.alloc_small(j_common_ptr(cinfo), JPOOL_IMAGE, + cinfo^.num_components * SIZEOF(jpeg_component_info))); + + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + compptr^.component_index := ci; + + { Read a byte into variable compptr^.component_id. + If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_sof := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + compptr^.component_id := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + + { Read a byte into variable c. If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_sof := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + c := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + + compptr^.h_samp_factor := (c shr 4) and 15; + compptr^.v_samp_factor := (c ) and 15; + + { Read a byte into variable compptr^.quant_tbl_no. + If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_sof := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + compptr^.quant_tbl_no := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + + {$IFDEF DEBUG} + TRACEMS4(j_common_ptr(cinfo), 1, JTRC_SOF_COMPONENT, + compptr^.component_id, compptr^.h_samp_factor, + compptr^.v_samp_factor, compptr^.quant_tbl_no); + {$ENDIF} + + Inc(compptr); + end; + + cinfo^.marker^.saw_SOF := TRUE; + + { Unload the local copies --- do this only at a restart boundary } + datasrc^.next_input_byte := next_input_byte; + datasrc^.bytes_in_buffer := bytes_in_buffer; + + get_sof := TRUE; +end; { get_sof } + + +{LOCAL} +function get_sos (cinfo : j_decompress_ptr) : boolean; +{ Process a SOS marker } +label + id_found; +var + length : INT32; + i, ci, n, c, cc : int; + compptr : jpeg_component_info_ptr; +{ Declare and initialize local copies of input pointer/count } +var + datasrc : jpeg_source_mgr_ptr; + next_input_byte : JOCTETptr; { Array[] of JOCTET; } + bytes_in_buffer : size_t; +begin + datasrc := cinfo^.src; + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + +{} + + if not cinfo^.marker^.saw_SOF then + ERREXIT(j_common_ptr(cinfo), JERR_SOS_NO_SOF); + +{ Read two bytes interpreted as an unsigned 16-bit integer. + length should be declared unsigned int or perhaps INT32. } + +{ make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_sos := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + length := (uint( GETJOCTET(next_input_byte^)) shl 8); + Inc( next_input_byte ); + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_sos := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + Inc( length, GETJOCTET( next_input_byte^)); + Inc( next_input_byte ); + + + { Read a byte into variable n (Number of components). + If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_sos := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + n := GETJOCTET(next_input_byte^); { Number of components } + Inc(next_input_byte); + + {$IFDEF DEBUG} + TRACEMS1(j_common_ptr(cinfo), 1, JTRC_SOS, n); + {$ENDIF} + + if ((length <> (n * 2 + 6)) or (n < 1) or (n > MAX_COMPS_IN_SCAN)) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_LENGTH); + + cinfo^.comps_in_scan := n; + + { Collect the component-spec parameters } + + for i := 0 to Pred(n) do + begin + { Read a byte into variable cc. If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_sos := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + cc := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + + { Read a byte into variable c. If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_sos := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + c := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to Pred(cinfo^.num_components) do + begin + if (cc = compptr^.component_id) then + goto id_found; + Inc(compptr); + end; + + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_COMPONENT_ID, cc); + + id_found: + + cinfo^.cur_comp_info[i] := compptr; + compptr^.dc_tbl_no := (c shr 4) and 15; + compptr^.ac_tbl_no := (c ) and 15; + + {$IFDEF DEBUG} + TRACEMS3(j_common_ptr(cinfo), 1, JTRC_SOS_COMPONENT, cc, + compptr^.dc_tbl_no, compptr^.ac_tbl_no); + {$ENDIF} + end; + + { Collect the additional scan parameters Ss, Se, Ah/Al. } + { Read a byte into variable c. If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_sos := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + c := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + + cinfo^.Ss := c; + + { Read a byte into variable c. If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_sos := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + c := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + + cinfo^.Se := c; + + { Read a byte into variable c. If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_sos := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + c := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + + cinfo^.Ah := (c shr 4) and 15; + cinfo^.Al := (c ) and 15; + + {$IFDEF DEBUG} + TRACEMS4(j_common_ptr(cinfo), 1, JTRC_SOS_PARAMS, cinfo^.Ss, cinfo^.Se, + cinfo^.Ah, cinfo^.Al); + {$ENDIF} + + { Prepare to scan data & restart markers } + cinfo^.marker^.next_restart_num := 0; + + { Count another SOS marker } + Inc( cinfo^.input_scan_number ); + + { Unload the local copies --- do this only at a restart boundary } + datasrc^.next_input_byte := next_input_byte; + datasrc^.bytes_in_buffer := bytes_in_buffer; + + get_sos := TRUE; +end; { get_sos } + + +{METHODDEF} +function skip_variable (cinfo : j_decompress_ptr) : boolean; +{ Skip over an unknown or uninteresting variable-length marker } +var + length : INT32; +var + datasrc : jpeg_source_mgr_ptr; + next_input_byte : JOCTETptr; { Array[] of JOCTET; } + bytes_in_buffer : size_t; +begin + datasrc := cinfo^.src; + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + +{ Read two bytes interpreted as an unsigned 16-bit integer. + length should be declared unsigned int or perhaps INT32. } + +{ make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + skip_variable := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + length := uint(GETJOCTET(next_input_byte^)) shl 8; + Inc( next_input_byte ); + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + skip_variable := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + Inc( length, GETJOCTET(next_input_byte^)); + Inc( next_input_byte ); + + Dec(length, 2); + + {$IFDEF DEBUG} + TRACEMS2(j_common_ptr(cinfo), 1, JTRC_MISC_MARKER, + cinfo^.unread_marker, int(length)); + {$ENDIF} + + { Unload the local copies --- do this only at a restart boundary } + { do before skip_input_data } + datasrc^.next_input_byte := next_input_byte; + datasrc^.bytes_in_buffer := bytes_in_buffer; + + if (length > 0) then + cinfo^.src^.skip_input_data(cinfo, long(length)); + + skip_variable := TRUE; +end; { skip_variable } + + +{$IFDEF D_ARITH_CODING_SUPPORTED} + +{LOCAL} +function get_dac (cinfo : j_decompress_ptr) : boolean; +{ Process a DAC marker } +var + length : INT32; + index, val : int; +var + datasrc : jpeg_source_mgr_ptr; + next_input_byte : JOCTETptr; + bytes_in_buffer : size_t; +begin + datasrc := cinfo^.src; + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + +{ Read two bytes interpreted as an unsigned 16-bit integer. + length should be declared unsigned int or perhaps INT32. } + +{ make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_dac := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + length := (uint( GETJOCTET(next_input_byte^)) shl 8); + Inc( next_input_byte ); + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_dac := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + Inc( length, GETJOCTET( next_input_byte^)); + Inc( next_input_byte ); + + Dec(length, 2); + + while (length > 0) do + begin + { Read a byte into variable index. If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_dac := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + index := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + + { Read a byte into variable val. If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_dac := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + val := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + + Dec( length, 2); + + {$IFDEF DEBUG} + TRACEMS2(j_common_ptr(cinfo), 1, JTRC_DAC, index, val); + {$ENDIF} + + if (index < 0) or (index >= (2*NUM_ARITH_TBLS)) then + ERREXIT1(j_common_ptr(cinfo) , JERR_DAC_INDEX, index); + + if (index >= NUM_ARITH_TBLS) then + begin { define AC table } + cinfo^.arith_ac_K[index-NUM_ARITH_TBLS] := UINT8(val); + end + else + begin { define DC table } + cinfo^.arith_dc_L[index] := UINT8(val and $0F); + cinfo^.arith_dc_U[index] := UINT8(val shr 4); + if (cinfo^.arith_dc_L[index] > cinfo^.arith_dc_U[index]) then + ERREXIT1(j_common_ptr(cinfo) , JERR_DAC_VALUE, val); + end; + end; + + if (length <> 0) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_LENGTH); + + { Unload the local copies --- do this only at a restart boundary } + datasrc^.next_input_byte := next_input_byte; + datasrc^.bytes_in_buffer := bytes_in_buffer; + + get_dac := TRUE; +end; { get_dac } + +{$ELSE} + +{LOCAL} +function get_dac (cinfo : j_decompress_ptr) : boolean; +begin + get_dac := skip_variable(cinfo); +end; + +{$ENDIF} + +{LOCAL} +function get_dht (cinfo : j_decompress_ptr) : boolean; +{ Process a DHT marker } +var + length : INT32; + bits : Array[0..17-1] of UINT8; + huffval : Array[0..256-1] of UINT8; + i, index, count : int; + htblptr : ^JHUFF_TBL_PTR; +var + datasrc : jpeg_source_mgr_ptr; + next_input_byte : JOCTETptr; + bytes_in_buffer : size_t; +begin + datasrc := cinfo^.src; + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + +{ Read two bytes interpreted as an unsigned 16-bit integer. + length should be declared unsigned int or perhaps INT32. } + +{ make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_dht := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + length := (uint( GETJOCTET(next_input_byte^)) shl 8); + Inc( next_input_byte ); + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_dht := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + Inc( length, GETJOCTET( next_input_byte^)); + Inc( next_input_byte ); + + Dec(length, 2); + + while (length > 16) do + begin + { Read a byte into variable index. If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_dht := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + index := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + + {$IFDEF DEBUG} + TRACEMS1(j_common_ptr(cinfo), 1, JTRC_DHT, index); + {$ENDIF} + + bits[0] := 0; + count := 0; + for i := 1 to 16 do + begin + { Read a byte into variable bits[i]. If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_dht := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + bits[i] := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + + Inc( count, bits[i] ); + end; + + Dec( length, (1 + 16) ); + + {$IFDEF DEBUG} + TRACEMS8(j_common_ptr(cinfo), 2, JTRC_HUFFBITS, + bits[1], bits[2], bits[3], bits[4], + bits[5], bits[6], bits[7], bits[8]); + TRACEMS8(j_common_ptr(cinfo), 2, JTRC_HUFFBITS, + bits[9], bits[10], bits[11], bits[12], + bits[13], bits[14], bits[15], bits[16]); + {$ENDIF} + + { Here we just do minimal validation of the counts to avoid walking + off the end of our table space. jdhuff.c will check more carefully. } + + if (count > 256) or (INT32(count) > length) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_HUFF_TABLE); + + for i := 0 to Pred(count) do + begin + { Read a byte into variable huffval[i]. If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_dht := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + huffval[i] := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + end; + + Dec( length, count ); + + if (index and $10)<>0 then + begin { AC table definition } + Dec( index, $10 ); + htblptr := @cinfo^.ac_huff_tbl_ptrs[index]; + end + else + begin { DC table definition } + htblptr := @cinfo^.dc_huff_tbl_ptrs[index]; + end; + + if (index < 0) or (index >= NUM_HUFF_TBLS) then + ERREXIT1(j_common_ptr(cinfo), JERR_DHT_INDEX, index); + + if (htblptr^ = NIL) then + htblptr^ := jpeg_alloc_huff_table(j_common_ptr(cinfo)); + + MEMCOPY(@(htblptr^)^.bits, @bits, SIZEOF((htblptr^)^.bits)); + MEMCOPY(@(htblptr^)^.huffval, @huffval, SIZEOF((htblptr^)^.huffval)); + end; + + if (length <> 0) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_LENGTH); + + { Unload the local copies --- do this only at a restart boundary } + datasrc^.next_input_byte := next_input_byte; + datasrc^.bytes_in_buffer := bytes_in_buffer; + + get_dht := TRUE; +end; { get_dht } + + +{LOCAL} +function get_dqt (cinfo : j_decompress_ptr) : boolean; +{ Process a DQT marker } +var + length : INT32; + n, i, prec : int; + tmp : uint; + quant_ptr : JQUANT_TBL_PTR; +var + datasrc : jpeg_source_mgr_ptr; + next_input_byte : JOCTETptr; + bytes_in_buffer : size_t; +begin + datasrc := cinfo^.src; + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + +{ Read two bytes interpreted as an unsigned 16-bit integer. + length should be declared unsigned int or perhaps INT32. } + +{ make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_dqt := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + length := (uint( GETJOCTET(next_input_byte^)) shl 8); + Inc( next_input_byte ); + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_dqt := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + Inc( length, GETJOCTET( next_input_byte^)); + Inc( next_input_byte ); + + Dec( length, 2 ); + + while (length > 0) do + begin + { Read a byte into variable n. If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_dqt := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + n := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + + prec := n shr 4; + n := n and $0F; + + {$IFDEF DEBUG} + TRACEMS2(j_common_ptr(cinfo), 1, JTRC_DQT, n, prec); + {$ENDIF} + + if (n >= NUM_QUANT_TBLS) then + ERREXIT1(j_common_ptr(cinfo) , JERR_DQT_INDEX, n); + + if (cinfo^.quant_tbl_ptrs[n] = NIL) then + cinfo^.quant_tbl_ptrs[n] := jpeg_alloc_quant_table(j_common_ptr(cinfo)); + quant_ptr := cinfo^.quant_tbl_ptrs[n]; + + for i := 0 to Pred(DCTSIZE2) do + begin + if (prec <> 0) then + begin + { Read two bytes interpreted as an unsigned 16-bit integer. + tmp should be declared unsigned int or perhaps INT32. } + + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_dqt := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + tmp := (uint( GETJOCTET(next_input_byte^)) shl 8); + Inc( next_input_byte ); + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_dqt := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + Inc( tmp, GETJOCTET( next_input_byte^)); + Inc( next_input_byte ); + + end + else + begin + { Read a byte into variable tmp. If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_dqt := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + tmp := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + end; + + { We convert the zigzag-order table to natural array order. } + quant_ptr^.quantval[jpeg_natural_order[i]] := UINT16(tmp); + end; + + if (cinfo^.err^.trace_level >= 2) then + begin + i := 0; + while i < Pred(DCTSIZE2) do + begin + {$IFDEF DEBUG} + TRACEMS8(j_common_ptr(cinfo), 2, JTRC_QUANTVALS, + quant_ptr^.quantval[i], quant_ptr^.quantval[i+1], + quant_ptr^.quantval[i+2], quant_ptr^.quantval[i+3], + quant_ptr^.quantval[i+4], quant_ptr^.quantval[i+5], + quant_ptr^.quantval[i+6], quant_ptr^.quantval[i+7]); + {$ENDIF} + Inc(i, 8); + end; + end; + + Dec( length, DCTSIZE2+1 ); + if (prec <> 0) then + Dec( length, DCTSIZE2 ); + end; + + if (length <> 0) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_LENGTH); + + { Unload the local copies --- do this only at a restart boundary } + datasrc^.next_input_byte := next_input_byte; + datasrc^.bytes_in_buffer := bytes_in_buffer; + + get_dqt := TRUE; +end; { get_dqt } + + +{LOCAL} +function get_dri (cinfo : j_decompress_ptr) : boolean; +{ Process a DRI marker } +var + length : INT32; + tmp : uint; +var + datasrc : jpeg_source_mgr_ptr; + next_input_byte : JOCTETptr; + bytes_in_buffer : size_t; +begin + datasrc := cinfo^.src; + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + +{ Read two bytes interpreted as an unsigned 16-bit integer. + length should be declared unsigned int or perhaps INT32. } + +{ make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_dri := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + length := (uint( GETJOCTET(next_input_byte^)) shl 8); + Inc( next_input_byte ); + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_dri := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + Inc( length, GETJOCTET( next_input_byte^)); + Inc( next_input_byte ); + + if (length <> 4) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_LENGTH); + +{ Read two bytes interpreted as an unsigned 16-bit integer. + tmp should be declared unsigned int or perhaps INT32. } + +{ make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_dri := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + tmp := (uint( GETJOCTET(next_input_byte^)) shl 8); + Inc( next_input_byte ); + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_dri := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + Inc( tmp, GETJOCTET( next_input_byte^)); + Inc( next_input_byte ); + + {$IFDEF DEBUG} + TRACEMS1(j_common_ptr(cinfo), 1, JTRC_DRI, tmp); + {$ENDIF} + + cinfo^.restart_interval := tmp; + + { Unload the local copies --- do this only at a restart boundary } + datasrc^.next_input_byte := next_input_byte; + datasrc^.bytes_in_buffer := bytes_in_buffer; + + get_dri := TRUE; +end; { get_dri } + + +{ Routines for processing APPn and COM markers. + These are either saved in memory or discarded, per application request. + APP0 and APP14 are specially checked to see if they are + JFIF and Adobe markers, respectively. } + +const + APP0_DATA_LEN = 14; { Length of interesting data in APP0 } + APP14_DATA_LEN = 12; { Length of interesting data in APP14 } + APPN_DATA_LEN = 14; { Must be the largest of the above!! } + + +{LOCAL} +procedure examine_app0 (cinfo : j_decompress_ptr; + var data : array of JOCTET; + datalen : uint; + remaining : INT32); + +{ Examine first few bytes from an APP0. + Take appropriate action if it is a JFIF marker. + datalen is # of bytes at data[], remaining is length of rest of marker data. +} +{$IFDEF DEBUG} +var + totallen : INT32; +{$ENDIF} +begin + {$IFDEF DEBUG} + totallen := INT32(datalen) + remaining; + {$ENDIF} + if (datalen >= APP0_DATA_LEN) and + (GETJOCTET(data[0]) = $4A) and + (GETJOCTET(data[1]) = $46) and + (GETJOCTET(data[2]) = $49) and + (GETJOCTET(data[3]) = $46) and + (GETJOCTET(data[4]) = 0) then + begin + { Found JFIF APP0 marker: save info } + cinfo^.saw_JFIF_marker := TRUE; + cinfo^.JFIF_major_version := GETJOCTET(data[5]); + cinfo^.JFIF_minor_version := GETJOCTET(data[6]); + cinfo^.density_unit := GETJOCTET(data[7]); + cinfo^.X_density := (GETJOCTET(data[8]) shl 8) + GETJOCTET(data[9]); + cinfo^.Y_density := (GETJOCTET(data[10]) shl 8) + GETJOCTET(data[11]); + { Check version. + Major version must be 1, anything else signals an incompatible change. + (We used to treat this as an error, but now it's a nonfatal warning, + because some bozo at Hijaak couldn't read the spec.) + Minor version should be 0..2, but process anyway if newer. } + + if (cinfo^.JFIF_major_version <> 1) then + WARNMS2(j_common_ptr(cinfo), JWRN_JFIF_MAJOR, + cinfo^.JFIF_major_version, cinfo^.JFIF_minor_version); + { Generate trace messages } + {$IFDEF DEBUG} + TRACEMS5(j_common_ptr(cinfo), 1, JTRC_JFIF, + cinfo^.JFIF_major_version, cinfo^.JFIF_minor_version, + cinfo^.X_density, cinfo^.Y_density, cinfo^.density_unit); + { Validate thumbnail dimensions and issue appropriate messages } + if (GETJOCTET(data[12]) or GETJOCTET(data[13])) <> 0 then + TRACEMS2(j_common_ptr(cinfo), 1, JTRC_JFIF_THUMBNAIL, + GETJOCTET(data[12]), GETJOCTET(data[13])); + Dec(totallen, APP0_DATA_LEN); + if (totallen <> + ( INT32(GETJOCTET(data[12])) * INT32(GETJOCTET(data[13])) * INT32(3) )) then + TRACEMS1(j_common_ptr(cinfo), 1, JTRC_JFIF_BADTHUMBNAILSIZE, int(totallen)); + {$ENDIF} + end + else + if (datalen >= 6) and + (GETJOCTET(data[0]) = $4A) and + (GETJOCTET(data[1]) = $46) and + (GETJOCTET(data[2]) = $58) and + (GETJOCTET(data[3]) = $58) and + (GETJOCTET(data[4]) = 0) then + begin + { Found JFIF "JFXX" extension APP0 marker } + { The library doesn't actually do anything with these, + but we try to produce a helpful trace message. } + {$IFDEF DEBUG} + case (GETJOCTET(data[5])) of + $10: + TRACEMS1(j_common_ptr(cinfo), 1, JTRC_THUMB_JPEG, int(totallen)); + $11: + TRACEMS1(j_common_ptr(cinfo), 1, JTRC_THUMB_PALETTE, int(totallen)); + $13: + TRACEMS1(j_common_ptr(cinfo), 1, JTRC_THUMB_RGB, int(totallen)); + else + TRACEMS2(j_common_ptr(cinfo), 1, JTRC_JFIF_EXTENSION, + GETJOCTET(data[5]), int(totallen)); + end; + {$ENDIF} + end + else + begin + { Start of APP0 does not match "JFIF" or "JFXX", or too short } + {$IFDEF DEBUG} + TRACEMS1(j_common_ptr(cinfo), 1, JTRC_APP0, int(totallen)); + {$ENDIF} + end; +end; + + +{LOCAL} +procedure examine_app14 (cinfo : j_decompress_ptr; + var data : array of JOCTET; + datalen : uint; + remaining : INT32); +{ Examine first few bytes from an APP14. + Take appropriate action if it is an Adobe marker. + datalen is # of bytes at data[], remaining is length of rest of marker data. + } +var + {$IFDEF DEBUG} + version, flags0, flags1, + {$ENDIF} + transform : uint; +begin + if (datalen >= APP14_DATA_LEN) and + (GETJOCTET(data[0]) = $41) and + (GETJOCTET(data[1]) = $64) and + (GETJOCTET(data[2]) = $6F) and + (GETJOCTET(data[3]) = $62) and + (GETJOCTET(data[4]) = $65) then + begin + { Found Adobe APP14 marker } + {$IFDEF DEBUG} + version := (GETJOCTET(data[5]) shl 8) + GETJOCTET(data[6]); + flags0 := (GETJOCTET(data[7]) shl 8) + GETJOCTET(data[8]); + flags1 := (GETJOCTET(data[9]) shl 8) + GETJOCTET(data[10]); + {$ENDIF} + transform := GETJOCTET(data[11]); + {$IFDEF DEBUG} + TRACEMS4(j_common_ptr(cinfo), 1, JTRC_ADOBE, version, flags0, flags1, transform); + {$ENDIF} + cinfo^.saw_Adobe_marker := TRUE; + cinfo^.Adobe_transform := UINT8 (transform); + end + else + begin + { Start of APP14 does not match "Adobe", or too short } + {$IFDEF DEBUG} + TRACEMS1(j_common_ptr(cinfo), 1, JTRC_APP14, int (datalen + remaining)); + {$ENDIF} + end; +end; + + +{METHODDEF} +function get_interesting_appn (cinfo : j_decompress_ptr) : boolean; +{ Process an APP0 or APP14 marker without saving it } +var + length : INT32; + b : array[0..APPN_DATA_LEN-1] of JOCTET; + i, numtoread : uint; +var + datasrc : jpeg_source_mgr_ptr; + next_input_byte : JOCTETptr; + bytes_in_buffer : size_t; +begin + datasrc := cinfo^.src; + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + +{ Read two bytes interpreted as an unsigned 16-bit integer. + length should be declared unsigned int or perhaps INT32. } + + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_interesting_appn := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + length := (uint( GETJOCTET(next_input_byte^)) shl 8); + Inc( next_input_byte ); + + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_interesting_appn := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + Inc( length, GETJOCTET(next_input_byte^)); + Inc( next_input_byte ); + + Dec(length, 2); + + { get the interesting part of the marker data } + if (length >= APPN_DATA_LEN) then + numtoread := APPN_DATA_LEN + else + if (length > 0) then + numtoread := uint(length) + else + numtoread := 0; + + if numtoread > 0 then + begin + for i := 0 to numtoread-1 do + begin + { Read a byte into b[i]. If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + get_interesting_appn := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + b[i] := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + end; + end; + + Dec(length, numtoread); + + { process it } + case (cinfo^.unread_marker) of + M_APP0: + examine_app0(cinfo, b, numtoread, length); + M_APP14: + examine_app14(cinfo, b, numtoread, length); + else + { can't get here unless jpeg_save_markers chooses wrong processor } + ERREXIT1(j_common_ptr(cinfo), JERR_UNKNOWN_MARKER, cinfo^.unread_marker); + end; + + { skip any remaining data -- could be lots } + + { Unload the local copies --- do this only at a restart boundary } + datasrc^.next_input_byte := next_input_byte; + datasrc^.bytes_in_buffer := bytes_in_buffer; + + if (length > 0) then + cinfo^.src^.skip_input_data(cinfo, long(length)); + + get_interesting_appn := TRUE; +end; + +{$ifdef SAVE_MARKERS_SUPPORTED} + +{METHODDEF} +function save_marker (cinfo : j_decompress_ptr) : boolean; +{ Save an APPn or COM marker into the marker list } +var + marker : my_marker_ptr; + cur_marker : jpeg_saved_marker_ptr; + bytes_read, data_length : uint; + data : JOCTET_FIELD_PTR; + length : INT32; +var + datasrc : jpeg_source_mgr_ptr; + next_input_byte : JOCTETptr; + bytes_in_buffer : size_t; +var + limit : uint; +var + prev : jpeg_saved_marker_ptr; +begin + { local copies of input pointer/count } + datasrc := cinfo^.src; + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + + marker := my_marker_ptr(cinfo^.marker); + cur_marker := marker^.cur_marker; + length := 0; + + if (cur_marker = NIL) then + begin + { begin reading a marker } + { Read two bytes interpreted as an unsigned 16-bit integer. } + + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + save_marker := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + length := (uint( GETJOCTET(next_input_byte^)) shl 8); + Inc( next_input_byte ); + + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + save_marker := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + Inc( length, GETJOCTET(next_input_byte^)); + Inc( next_input_byte ); + + Dec(length, 2); + if (length >= 0) then + begin { watch out for bogus length word } + { figure out how much we want to save } + + if (cinfo^.unread_marker = int(M_COM)) then + limit := marker^.length_limit_COM + else + limit := marker^.length_limit_APPn[cinfo^.unread_marker - int(M_APP0)]; + if (uint(length) < limit) then + limit := uint(length); + { allocate and initialize the marker item } + cur_marker := jpeg_saved_marker_ptr( + cinfo^.mem^.alloc_large (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(jpeg_marker_struct) + limit) ); + cur_marker^.next := NIL; + cur_marker^.marker := UINT8 (cinfo^.unread_marker); + cur_marker^.original_length := uint(length); + cur_marker^.data_length := limit; + { data area is just beyond the jpeg_marker_struct } + cur_marker^.data := JOCTET_FIELD_PTR(cur_marker); + Inc(jpeg_saved_marker_ptr(cur_marker^.data)); + data := cur_marker^.data; + + marker^.cur_marker := cur_marker; + marker^.bytes_read := 0; + bytes_read := 0; + data_length := limit; + end + else + begin + { deal with bogus length word } + data_length := 0; + bytes_read := 0; + data := NIL; + end + end + else + begin + { resume reading a marker } + bytes_read := marker^.bytes_read; + data_length := cur_marker^.data_length; + data := cur_marker^.data; + Inc(data, bytes_read); + end; + + while (bytes_read < data_length) do + begin + { move the restart point to here } + datasrc^.next_input_byte := next_input_byte; + datasrc^.bytes_in_buffer := bytes_in_buffer; + + marker^.bytes_read := bytes_read; + { If there's not at least one byte in buffer, suspend } + if (bytes_in_buffer = 0) then + begin + if not datasrc^.fill_input_buffer (cinfo) then + begin + save_marker := FALSE; + exit; + end; + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + + { Copy bytes with reasonable rapidity } + while (bytes_read < data_length) and (bytes_in_buffer > 0) do + begin + JOCTETPTR(data)^ := next_input_byte^; + Inc(JOCTETPTR(data)); + Inc(next_input_byte); + Dec(bytes_in_buffer); + Inc(bytes_read); + end; + end; + + { Done reading what we want to read } + if (cur_marker <> NIL) then + begin { will be NIL if bogus length word } + { Add new marker to end of list } + if (cinfo^.marker_list = NIL) then + begin + cinfo^.marker_list := cur_marker + end + else + begin + prev := cinfo^.marker_list; + while (prev^.next <> NIL) do + prev := prev^.next; + prev^.next := cur_marker; + end; + { Reset pointer & calc remaining data length } + data := cur_marker^.data; + length := cur_marker^.original_length - data_length; + end; + { Reset to initial state for next marker } + marker^.cur_marker := NIL; + + { Process the marker if interesting; else just make a generic trace msg } + case (cinfo^.unread_marker) of + M_APP0: + examine_app0(cinfo, data^, data_length, length); + M_APP14: + examine_app14(cinfo, data^, data_length, length); + else + {$IFDEF DEBUG} + TRACEMS2(j_common_ptr(cinfo), 1, JTRC_MISC_MARKER, cinfo^.unread_marker, + int(data_length + length)); + {$ENDIF} + end; + + { skip any remaining data -- could be lots } + { do before skip_input_data } + datasrc^.next_input_byte := next_input_byte; + datasrc^.bytes_in_buffer := bytes_in_buffer; + + if (length > 0) then + cinfo^.src^.skip_input_data (cinfo, long(length) ); + + save_marker := TRUE; +end; + +{$endif} { SAVE_MARKERS_SUPPORTED } + + +{ Find the next JPEG marker, save it in cinfo^.unread_marker. + Returns FALSE if had to suspend before reaching a marker; + in that case cinfo^.unread_marker is unchanged. + + Note that the result might not be a valid marker code, + but it will never be 0 or FF. } + +{LOCAL} +function next_marker (cinfo : j_decompress_ptr) : boolean; +var + c : int; +var + datasrc : jpeg_source_mgr_ptr; + next_input_byte : JOCTETptr; + bytes_in_buffer : size_t; +begin + datasrc := cinfo^.src; + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + + {while TRUE do} + repeat + { Read a byte into variable c. If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + next_marker := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + c := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + + { Skip any non-FF bytes. + This may look a bit inefficient, but it will not occur in a valid file. + We sync after each discarded byte so that a suspending data source + can discard the byte from its buffer. } + + while (c <> $FF) do + begin + Inc(cinfo^.marker^.discarded_bytes); + { Unload the local copies --- do this only at a restart boundary } + datasrc^.next_input_byte := next_input_byte; + datasrc^.bytes_in_buffer := bytes_in_buffer; + + { Read a byte into variable c. If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + next_marker := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + c := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + + end; + { This loop swallows any duplicate FF bytes. Extra FFs are legal as + pad bytes, so don't count them in discarded_bytes. We assume there + will not be so many consecutive FF bytes as to overflow a suspending + data source's input buffer. } + + repeat + { Read a byte into variable c. If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + next_marker := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + c := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + Until (c <> $FF); + if (c <> 0) then + break; { found a valid marker, exit loop } + { Reach here if we found a stuffed-zero data sequence (FF/00). + Discard it and loop back to try again. } + + Inc(cinfo^.marker^.discarded_bytes, 2); + { Unload the local copies --- do this only at a restart boundary } + datasrc^.next_input_byte := next_input_byte; + datasrc^.bytes_in_buffer := bytes_in_buffer; + Until False; + + if (cinfo^.marker^.discarded_bytes <> 0) then + begin + WARNMS2(j_common_ptr(cinfo), JWRN_EXTRANEOUS_DATA, + cinfo^.marker^.discarded_bytes, c); + cinfo^.marker^.discarded_bytes := 0; + end; + + cinfo^.unread_marker := c; + + { Unload the local copies --- do this only at a restart boundary } + datasrc^.next_input_byte := next_input_byte; + datasrc^.bytes_in_buffer := bytes_in_buffer; + + next_marker := TRUE; +end; { next_marker } + + +{LOCAL} +function first_marker (cinfo : j_decompress_ptr) : boolean; +{ Like next_marker, but used to obtain the initial SOI marker. } +{ For this marker, we do not allow preceding garbage or fill; otherwise, + we might well scan an entire input file before realizing it ain't JPEG. + If an application wants to process non-JFIF files, it must seek to the + SOI before calling the JPEG library. } +var + c, c2 : int; +var + datasrc : jpeg_source_mgr_ptr; + next_input_byte : JOCTETptr; + bytes_in_buffer : size_t; +begin + datasrc := cinfo^.src; + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + + { Read a byte into variable c. If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + first_marker := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + c := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + + { Read a byte into variable c2. If must suspend, return FALSE. } + { make a byte available. + Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + but we must reload the local copies after a successful fill. } + if (bytes_in_buffer = 0) then + begin + if (not datasrc^.fill_input_buffer(cinfo)) then + begin + first_marker := FALSE; + exit; + end; + { Reload the local copies } + next_input_byte := datasrc^.next_input_byte; + bytes_in_buffer := datasrc^.bytes_in_buffer; + end; + Dec( bytes_in_buffer ); + + c2 := GETJOCTET(next_input_byte^); + Inc(next_input_byte); + + if (c <> $FF) or (c2 <> int(M_SOI)) then + ERREXIT2(j_common_ptr(cinfo), JERR_NO_SOI, c, c2); + + cinfo^.unread_marker := c2; + + { Unload the local copies --- do this only at a restart boundary } + datasrc^.next_input_byte := next_input_byte; + datasrc^.bytes_in_buffer := bytes_in_buffer; + + first_marker := TRUE; +end; { first_marker } + + +{ Read markers until SOS or EOI. + + Returns same codes as are defined for jpeg_consume_input: + JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI. } + +{METHODDEF} +function read_markers (cinfo : j_decompress_ptr) : int; +begin + { Outer loop repeats once for each marker. } + repeat + { Collect the marker proper, unless we already did. } + { NB: first_marker() enforces the requirement that SOI appear first. } + if (cinfo^.unread_marker = 0) then + begin + if not cinfo^.marker^.saw_SOI then + begin + if not first_marker(cinfo) then + begin + read_markers := JPEG_SUSPENDED; + exit; + end; + end + else + begin + if not next_marker(cinfo) then + begin + read_markers := JPEG_SUSPENDED; + exit; + end; + end; + end; + { At this point cinfo^.unread_marker contains the marker code and the + input point is just past the marker proper, but before any parameters. + A suspension will cause us to return with this state still true. } + + case (cinfo^.unread_marker) of + M_SOI: + if not get_soi(cinfo) then + begin + read_markers := JPEG_SUSPENDED; + exit; + end; + + M_SOF0, { Baseline } + M_SOF1: { Extended sequential, Huffman } + if not get_sof(cinfo, FALSE, FALSE) then + begin + read_markers := JPEG_SUSPENDED; + exit; + end; + M_SOF2: { Progressive, Huffman } + if not get_sof(cinfo, TRUE, FALSE) then + begin + read_markers := JPEG_SUSPENDED; + exit; + end; + + M_SOF9: { Extended sequential, arithmetic } + if not get_sof(cinfo, FALSE, TRUE) then + begin + read_markers := JPEG_SUSPENDED; + exit; + end; + + M_SOF10: { Progressive, arithmetic } + if not get_sof(cinfo, TRUE, TRUE) then + begin + read_markers := JPEG_SUSPENDED; + exit; + end; + + { Currently unsupported SOFn types } + M_SOF3, { Lossless, Huffman } + M_SOF5, { Differential sequential, Huffman } + M_SOF6, { Differential progressive, Huffman } + M_SOF7, { Differential lossless, Huffman } + M_JPG, { Reserved for JPEG extensions } + M_SOF11, { Lossless, arithmetic } + M_SOF13, { Differential sequential, arithmetic } + M_SOF14, { Differential progressive, arithmetic } + M_SOF15: { Differential lossless, arithmetic } + ERREXIT1(j_common_ptr(cinfo), JERR_SOF_UNSUPPORTED, cinfo^.unread_marker); + + M_SOS: + begin + if not get_sos(cinfo) then + begin + read_markers := JPEG_SUSPENDED; + exit; + end; + cinfo^.unread_marker := 0; { processed the marker } + read_markers := JPEG_REACHED_SOS; + exit; + end; + + M_EOI: + begin + {$IFDEF DEBUG} + TRACEMS(j_common_ptr(cinfo), 1, JTRC_EOI); + {$ENDIF} + cinfo^.unread_marker := 0; { processed the marker } + read_markers := JPEG_REACHED_EOI; + exit; + end; + + M_DAC: + if not get_dac(cinfo) then + begin + read_markers := JPEG_SUSPENDED; + exit; + end; + + M_DHT: + if not get_dht(cinfo) then + begin + read_markers := JPEG_SUSPENDED; + exit; + end; + + M_DQT: + if not get_dqt(cinfo) then + begin + read_markers := JPEG_SUSPENDED; + exit; + end; + + M_DRI: + if not get_dri(cinfo) then + begin + read_markers := JPEG_SUSPENDED; + exit; + end; + + M_APP0, + M_APP1, + M_APP2, + M_APP3, + M_APP4, + M_APP5, + M_APP6, + M_APP7, + M_APP8, + M_APP9, + M_APP10, + M_APP11, + M_APP12, + M_APP13, + M_APP14, + M_APP15: + if not my_marker_ptr(cinfo^.marker)^. + process_APPn[cinfo^.unread_marker - int(M_APP0)](cinfo) then + begin + read_markers := JPEG_SUSPENDED; + exit; + end; + + M_COM: + if not my_marker_ptr(cinfo^.marker)^.process_COM (cinfo) then + begin + read_markers := JPEG_SUSPENDED; + exit; + end; + + M_RST0, { these are all parameterless } + M_RST1, + M_RST2, + M_RST3, + M_RST4, + M_RST5, + M_RST6, + M_RST7, + M_TEM: + {$IFDEF DEBUG} + TRACEMS1(j_common_ptr(cinfo), 1, JTRC_PARMLESS_MARKER, + cinfo^.unread_marker) + {$ENDIF} + ; + + M_DNL: { Ignore DNL ... perhaps the wrong thing } + if not skip_variable(cinfo) then + begin + read_markers := JPEG_SUSPENDED; + exit; + end; + + else { must be DHP, EXP, JPGn, or RESn } + if (@on_unknown_marker<>nil) then + begin + read_markers:=on_unknown_marker(cinfo); + exit; + end + else if not skip_variable(cinfo) then + begin + read_markers := JPEG_SUSPENDED; + exit; + end; + { // This is the previous code. + ERREXIT1(j_common_ptr(cinfo) , JERR_UNKNOWN_MARKER,cinfo^.unread_marker); + } + end; { end of case } + { Successfully processed marker, so reset state variable } + cinfo^.unread_marker := 0; + Until false; +end; { read_markers } + + +{ Read a restart marker, which is expected to appear next in the datastream; + if the marker is not there, take appropriate recovery action. + Returns FALSE if suspension is required. + + This is called by the entropy decoder after it has read an appropriate + number of MCUs. cinfo^.unread_marker may be nonzero if the entropy decoder + has already read a marker from the data source. Under normal conditions + cinfo^.unread_marker will be reset to 0 before returning; if not reset, + it holds a marker which the decoder will be unable to read past. } + +{METHODDEF} +function read_restart_marker (cinfo : j_decompress_ptr) :boolean; +begin + { Obtain a marker unless we already did. } + { Note that next_marker will complain if it skips any data. } + if (cinfo^.unread_marker = 0) then + begin + if not next_marker(cinfo) then + begin + read_restart_marker := FALSE; + exit; + end; + end; + + if (cinfo^.unread_marker = (int(M_RST0) + cinfo^.marker^.next_restart_num)) then + begin + { Normal case --- swallow the marker and let entropy decoder continue } + {$IFDEF DEBUG} + TRACEMS1(j_common_ptr(cinfo), 3, JTRC_RST, + cinfo^.marker^.next_restart_num); + {$ENDIF} + cinfo^.unread_marker := 0; + end + else + begin + { Uh-oh, the restart markers have been messed up. } + { Let the data source manager determine how to resync. } + if not cinfo^.src^.resync_to_restart(cinfo, + cinfo^.marker^.next_restart_num) then + begin + read_restart_marker := FALSE; + exit; + end; + end; + + { Update next-restart state } + with cinfo^.marker^ do + next_restart_num := (next_restart_num + 1) and 7; + + read_restart_marker := TRUE; +end; { read_restart_marker } + + +{ This is the default resync_to_restart method for data source managers + to use if they don't have any better approach. Some data source managers + may be able to back up, or may have additional knowledge about the data + which permits a more intelligent recovery strategy; such managers would + presumably supply their own resync method. + + read_restart_marker calls resync_to_restart if it finds a marker other than + the restart marker it was expecting. (This code is *not* used unless + a nonzero restart interval has been declared.) cinfo^.unread_marker is + the marker code actually found (might be anything, except 0 or FF). + The desired restart marker number (0..7) is passed as a parameter. + This routine is supposed to apply whatever error recovery strategy seems + appropriate in order to position the input stream to the next data segment. + Note that cinfo^.unread_marker is treated as a marker appearing before + the current data-source input point; usually it should be reset to zero + before returning. + Returns FALSE if suspension is required. + + This implementation is substantially constrained by wanting to treat the + input as a data stream; this means we can't back up. Therefore, we have + only the following actions to work with: + 1. Simply discard the marker and let the entropy decoder resume at next + byte of file. + 2. Read forward until we find another marker, discarding intervening + data. (In theory we could look ahead within the current bufferload, + without having to discard data if we don't find the desired marker. + This idea is not implemented here, in part because it makes behavior + dependent on buffer size and chance buffer-boundary positions.) + 3. Leave the marker unread (by failing to zero cinfo^.unread_marker). + This will cause the entropy decoder to process an empty data segment, + inserting dummy zeroes, and then we will reprocess the marker. + + #2 is appropriate if we think the desired marker lies ahead, while #3 is + appropriate if the found marker is a future restart marker (indicating + that we have missed the desired restart marker, probably because it got + corrupted). + We apply #2 or #3 if the found marker is a restart marker no more than + two counts behind or ahead of the expected one. We also apply #2 if the + found marker is not a legal JPEG marker code (it's certainly bogus data). + If the found marker is a restart marker more than 2 counts away, we do #1 + (too much risk that the marker is erroneous; with luck we will be able to + resync at some future point). + For any valid non-restart JPEG marker, we apply #3. This keeps us from + overrunning the end of a scan. An implementation limited to single-scan + files might find it better to apply #2 for markers other than EOI, since + any other marker would have to be bogus data in that case. } + + +{GLOBAL} +function jpeg_resync_to_restart(cinfo : j_decompress_ptr; + desired : int) : boolean; +var + marker : int; + action : int; +begin + marker := cinfo^.unread_marker; + action := 1; { never used } + { Always put up a warning. } + WARNMS2(j_common_ptr(cinfo), JWRN_MUST_RESYNC, marker, desired); + + { Outer loop handles repeated decision after scanning forward. } + repeat + if (marker < int(M_SOF0)) then + action := 2 { invalid marker } + else + if (marker < int(M_RST0)) or (marker > int(M_RST7)) then + action := 3 { valid non-restart marker } + else + begin + if (marker = (int(M_RST0) + ((desired+1) and 7))) or + (marker = (int(M_RST0) + ((desired+2) and 7))) then + action := 3 { one of the next two expected restarts } + else + if (marker = (int(M_RST0) + ((desired-1) and 7))) or + (marker = (int(M_RST0) + ((desired-2) and 7))) then + action := 2 { a prior restart, so advance } + else + action := 1; { desired restart or too far away } + end; + + {$IFDEF DEBUG} + TRACEMS2(j_common_ptr(cinfo), 4, JTRC_RECOVERY_ACTION, marker, action); + {$ENDIF} + case action of + 1: + { Discard marker and let entropy decoder resume processing. } + begin + cinfo^.unread_marker := 0; + jpeg_resync_to_restart := TRUE; + exit; + end; + 2: + { Scan to the next marker, and repeat the decision loop. } + begin + if not next_marker(cinfo) then + begin + jpeg_resync_to_restart := FALSE; + exit; + end; + marker := cinfo^.unread_marker; + end; + 3: + { Return without advancing past this marker. } + { Entropy decoder will be forced to process an empty segment. } + begin + jpeg_resync_to_restart := TRUE; + exit; + end; + end; { case } + Until false; { end loop } +end; { jpeg_resync_to_restart } + + +{ Reset marker processing state to begin a fresh datastream. } + +{METHODDEF} +procedure reset_marker_reader (cinfo : j_decompress_ptr); +var + marker : my_marker_ptr; +begin + marker := my_marker_ptr (cinfo^.marker); + with cinfo^ do + begin + comp_info := NIL; { until allocated by get_sof } + input_scan_number := 0; { no SOS seen yet } + unread_marker := 0; { no pending marker } + end; + marker^.pub.saw_SOI := FALSE; { set internal state too } + marker^.pub.saw_SOF := FALSE; + marker^.pub.discarded_bytes := 0; + marker^.cur_marker := NIL; +end; { reset_marker_reader } + + +{ Initialize the marker reader module. + This is called only once, when the decompression object is created. } + +{GLOBAL} +procedure jinit_marker_reader (cinfo : j_decompress_ptr); +var + marker : my_marker_ptr; + i : int; +begin + { Create subobject in permanent pool } + marker := my_marker_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_PERMANENT, + SIZEOF(my_marker_reader)) + ); + cinfo^.marker := jpeg_marker_reader_ptr(marker); + { Initialize method pointers } + marker^.pub.reset_marker_reader := reset_marker_reader; + marker^.pub.read_markers := read_markers; + marker^.pub.read_restart_marker := read_restart_marker; + { Initialize COM/APPn processing. + By default, we examine and then discard APP0 and APP14, + but simply discard COM and all other APPn. } + + marker^.process_COM := skip_variable; + marker^.length_limit_COM := 0; + for i := 0 to 16-1 do + begin + marker^.process_APPn[i] := skip_variable; + marker^.length_limit_APPn[i] := 0; + end; + marker^.process_APPn[0] := get_interesting_appn; + marker^.process_APPn[14] := get_interesting_appn; + { Reset marker processing state } + reset_marker_reader(cinfo); +end; { jinit_marker_reader } + + +{ Control saving of COM and APPn markers into marker_list. } + + +{$ifdef SAVE_MARKERS_SUPPORTED} + +{GLOBAL} +procedure jpeg_save_markers (cinfo : j_decompress_ptr; + marker_code : int; + length_limit : uint); +var + marker : my_marker_ptr; + maxlength : long; + processor : jpeg_marker_parser_method; +begin + marker := my_marker_ptr (cinfo^.marker); + + { Length limit mustn't be larger than what we can allocate + (should only be a concern in a 16-bit environment). } + + maxlength := cinfo^.mem^.max_alloc_chunk - SIZEOF(jpeg_marker_struct); + if (long(length_limit) > maxlength) then + length_limit := uint(maxlength); + + { Choose processor routine to use. + APP0/APP14 have special requirements. } + + if (length_limit <> 0) then + begin + processor := save_marker; + { If saving APP0/APP14, save at least enough for our internal use. } + if (marker_code = int(M_APP0)) and (length_limit < APP0_DATA_LEN) then + length_limit := APP0_DATA_LEN + else + if (marker_code = int(M_APP14)) and (length_limit < APP14_DATA_LEN) then + length_limit := APP14_DATA_LEN; + end + else + begin + processor := skip_variable; + { If discarding APP0/APP14, use our regular on-the-fly processor. } + if (marker_code = int(M_APP0)) or (marker_code = int(M_APP14)) then + processor := get_interesting_appn; + end; + + if (marker_code = int(M_COM)) then + begin + marker^.process_COM := processor; + marker^.length_limit_COM := length_limit; + end + else + if (marker_code >= int(M_APP0)) and (marker_code <= int(M_APP15)) then + begin + marker^.process_APPn[marker_code - int(M_APP0)] := processor; + marker^.length_limit_APPn[marker_code - int(M_APP0)] := length_limit; + end + else + ERREXIT1(j_common_ptr(cinfo), JERR_UNKNOWN_MARKER, marker_code); +end; + +{$endif} { SAVE_MARKERS_SUPPORTED } + +{ Install a special processing method for COM or APPn markers. } + +{GLOBAL} + +procedure jpeg_set_marker_processor (cinfo : j_decompress_ptr; + marker_code : int; + routine : jpeg_marker_parser_method); +var + marker : my_marker_ptr; +begin + marker := my_marker_ptr (cinfo^.marker); + if (marker_code = int(M_COM)) then + marker^.process_COM := routine + else + if (marker_code >= int(M_APP0)) and (marker_code <= int(M_APP15)) then + marker^.process_APPn[marker_code - int(M_APP0)] := routine + else + ERREXIT1(j_common_ptr(cinfo), JERR_UNKNOWN_MARKER, marker_code); +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jdmaster_del.pas b/mseide-msegui/lib/common/fpccompatibility/jdmaster_del.pas new file mode 100644 index 0000000..248a976 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jdmaster_del.pas @@ -0,0 +1,680 @@ +unit jdmaster_del; + +{ This file contains master control logic for the JPEG decompressor. + These routines are concerned with selecting the modules to be executed + and with determining the number of passes and the work to be done in each + pass. } + +{ Original: jdmaster.c ; Copyright (C) 1991-1998, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jutils_del, + jerror_del, + jdeferr_del, + jdcolor_del, jdsample_del, jdpostct_del, jddctmgr_del, jdphuff_del, + jdhuff_del, jdcoefct_del, jdmainct_del, +{$ifdef QUANT_1PASS_SUPPORTED} + jquant1_del, +{$endif} +{$ifdef QUANT_2PASS_SUPPORTED} + jquant2_del, +{$endif} +{$ifdef UPSAMPLE_MERGING_SUPPORTED} + jdmerge_del, +{$endif} + jpeglib_del; + + +{ Compute output image dimensions and related values. + NOTE: this is exported for possible use by application. + Hence it mustn't do anything that can't be done twice. + Also note that it may be called before the master module is initialized! } + +{GLOBAL} +procedure jpeg_calc_output_dimensions (cinfo : j_decompress_ptr); +{ Do computations that are needed before master selection phase } + + +{$ifdef D_MULTISCAN_FILES_SUPPORTED} + +{GLOBAL} +procedure jpeg_new_colormap (cinfo : j_decompress_ptr); + +{$endif} + +{ Initialize master decompression control and select active modules. + This is performed at the start of jpeg_start_decompress. } + +{GLOBAL} +procedure jinit_master_decompress (cinfo : j_decompress_ptr); + +implementation + +{ Private state } + +type + my_master_ptr = ^my_decomp_master; + my_decomp_master = record + pub : jpeg_decomp_master; { public fields } + + pass_number : int; { # of passes completed } + + using_merged_upsample : boolean; { TRUE if using merged upsample/cconvert } + + { Saved references to initialized quantizer modules, + in case we need to switch modes. } + + quantizer_1pass : jpeg_color_quantizer_ptr; + quantizer_2pass : jpeg_color_quantizer_ptr; + end; + +{ Determine whether merged upsample/color conversion should be used. + CRUCIAL: this must match the actual capabilities of jdmerge.c! } + +{LOCAL} +function use_merged_upsample (cinfo : j_decompress_ptr) : boolean; +var + compptr : jpeg_component_info_list_ptr; +begin + compptr := cinfo^.comp_info; + +{$ifdef UPSAMPLE_MERGING_SUPPORTED} + { Merging is the equivalent of plain box-filter upsampling } + if (cinfo^.do_fancy_upsampling) or (cinfo^.CCIR601_sampling) then + begin + use_merged_upsample := FALSE; + exit; + end; + { jdmerge.c only supports YCC=>RGB color conversion } + if (cinfo^.jpeg_color_space <> JCS_YCbCr) or (cinfo^.num_components <> 3) + or (cinfo^.out_color_space <> JCS_RGB) + or (cinfo^.out_color_components <> RGB_PIXELSIZE) then + begin + use_merged_upsample := FALSE; + exit; + end; + + { and it only handles 2h1v or 2h2v sampling ratios } + if (compptr^[0].h_samp_factor <> 2) or + (compptr^[1].h_samp_factor <> 1) or + (compptr^[2].h_samp_factor <> 1) or + (compptr^[0].v_samp_factor > 2) or + (compptr^[1].v_samp_factor <> 1) or + (compptr^[2].v_samp_factor <> 1) then + begin + use_merged_upsample := FALSE; + exit; + end; + { furthermore, it doesn't work if we've scaled the IDCTs differently } + if (compptr^[0].DCT_scaled_size <> cinfo^.min_DCT_scaled_size) or + (compptr^[1].DCT_scaled_size <> cinfo^.min_DCT_scaled_size) or + (compptr^[2].DCT_scaled_size <> cinfo^.min_DCT_scaled_size) then + begin + use_merged_upsample := FALSE; + exit; + end; + { ??? also need to test for upsample-time rescaling, when & if supported } + use_merged_upsample := TRUE; { by golly, it'll work... } +{$else} + use_merged_upsample := FALSE; +{$endif} +end; + + +{ Compute output image dimensions and related values. + NOTE: this is exported for possible use by application. + Hence it mustn't do anything that can't be done twice. + Also note that it may be called before the master module is initialized! } + +{GLOBAL} +procedure jpeg_calc_output_dimensions (cinfo : j_decompress_ptr); +{ Do computations that are needed before master selection phase } +{$ifdef IDCT_SCALING_SUPPORTED} +var + ci : int; + compptr : jpeg_component_info_ptr; +{$endif} +var + ssize : int; +begin + { Prevent application from calling me at wrong times } + if (cinfo^.global_state <> DSTATE_READY) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + +{$ifdef IDCT_SCALING_SUPPORTED} + + { Compute actual output image dimensions and DCT scaling choices. } + if (cinfo^.scale_num * 8 <= cinfo^.scale_denom) then + begin + { Provide 1/8 scaling } + cinfo^.output_width := JDIMENSION ( + jdiv_round_up( long(cinfo^.image_width), long(8)) ); + cinfo^.output_height := JDIMENSION ( + jdiv_round_up( long(cinfo^.image_height), long(8)) ); + cinfo^.min_DCT_scaled_size := 1; + end + else + if (cinfo^.scale_num * 4 <= cinfo^.scale_denom) then + begin + { Provide 1/4 scaling } + cinfo^.output_width := JDIMENSION ( + jdiv_round_up( long (cinfo^.image_width), long(4)) ); + cinfo^.output_height := JDIMENSION ( + jdiv_round_up( long (cinfo^.image_height), long(4)) ); + cinfo^.min_DCT_scaled_size := 2; + end + else + if (cinfo^.scale_num * 2 <= cinfo^.scale_denom) then + begin + { Provide 1/2 scaling } + cinfo^.output_width := JDIMENSION ( + jdiv_round_up( long(cinfo^.image_width), long(2)) ); + cinfo^.output_height := JDIMENSION ( + jdiv_round_up( long(cinfo^.image_height), long(2)) ); + cinfo^.min_DCT_scaled_size := 4; + end + else + begin + { Provide 1/1 scaling } + cinfo^.output_width := cinfo^.image_width; + cinfo^.output_height := cinfo^.image_height; + cinfo^.min_DCT_scaled_size := DCTSIZE; + end; + { In selecting the actual DCT scaling for each component, we try to + scale up the chroma components via IDCT scaling rather than upsampling. + This saves time if the upsampler gets to use 1:1 scaling. + Note this code assumes that the supported DCT scalings are powers of 2. } + + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + ssize := cinfo^.min_DCT_scaled_size; + while (ssize < DCTSIZE) and + ((compptr^.h_samp_factor * ssize * 2 <= + cinfo^.max_h_samp_factor * cinfo^.min_DCT_scaled_size) and + (compptr^.v_samp_factor * ssize * 2 <= + cinfo^.max_v_samp_factor * cinfo^.min_DCT_scaled_size)) do + begin + ssize := ssize * 2; + end; + compptr^.DCT_scaled_size := ssize; + Inc(compptr); + end; + + { Recompute downsampled dimensions of components; + application needs to know these if using raw downsampled data. } + + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + { Size in samples, after IDCT scaling } + compptr^.downsampled_width := JDIMENSION ( + jdiv_round_up(long (cinfo^.image_width) * + long (compptr^.h_samp_factor * compptr^.DCT_scaled_size), + long (cinfo^.max_h_samp_factor * DCTSIZE)) ); + compptr^.downsampled_height := JDIMENSION ( + jdiv_round_up(long (cinfo^.image_height) * + long (compptr^.v_samp_factor * compptr^.DCT_scaled_size), + long (cinfo^.max_v_samp_factor * DCTSIZE)) ); + Inc(compptr); + end; + +{$else} { !IDCT_SCALING_SUPPORTED } + + { Hardwire it to "no scaling" } + cinfo^.output_width := cinfo^.image_width; + cinfo^.output_height := cinfo^.image_height; + { jdinput.c has already initialized DCT_scaled_size to DCTSIZE, + and has computed unscaled downsampled_width and downsampled_height. } + +{$endif} { IDCT_SCALING_SUPPORTED } + + { Report number of components in selected colorspace. } + { Probably this should be in the color conversion module... } + case (cinfo^.out_color_space) of + JCS_GRAYSCALE: + cinfo^.out_color_components := 1; +{$ifndef RGB_PIXELSIZE_IS_3} + JCS_RGB: + cinfo^.out_color_components := RGB_PIXELSIZE; +{$else} + JCS_RGB, +{$endif} { else share code with YCbCr } + JCS_YCbCr: + cinfo^.out_color_components := 3; + JCS_CMYK, + JCS_YCCK: + cinfo^.out_color_components := 4; + else { else must be same colorspace as in file } + cinfo^.out_color_components := cinfo^.num_components; + end; + if (cinfo^.quantize_colors) then + cinfo^.output_components := 1 + else + cinfo^.output_components := cinfo^.out_color_components; + + { See if upsampler will want to emit more than one row at a time } + if (use_merged_upsample(cinfo)) then + cinfo^.rec_outbuf_height := cinfo^.max_v_samp_factor + else + cinfo^.rec_outbuf_height := 1; +end; + + +{ Several decompression processes need to range-limit values to the range + 0..MAXJSAMPLE; the input value may fall somewhat outside this range + due to noise introduced by quantization, roundoff error, etc. These + processes are inner loops and need to be as fast as possible. On most + machines, particularly CPUs with pipelines or instruction prefetch, + a (subscript-check-less) C table lookup + x := sample_range_limit[x]; + is faster than explicit tests + if (x < 0) x := 0; + else if (x > MAXJSAMPLE) x := MAXJSAMPLE; + These processes all use a common table prepared by the routine below. + + For most steps we can mathematically guarantee that the initial value + of x is within MAXJSAMPLE+1 of the legal range, so a table running from + -(MAXJSAMPLE+1) to 2*MAXJSAMPLE+1 is sufficient. But for the initial + limiting step (just after the IDCT), a wildly out-of-range value is + possible if the input data is corrupt. To avoid any chance of indexing + off the end of memory and getting a bad-pointer trap, we perform the + post-IDCT limiting thus: + x := range_limit[x & MASK]; + where MASK is 2 bits wider than legal sample data, ie 10 bits for 8-bit + samples. Under normal circumstances this is more than enough range and + a correct output will be generated; with bogus input data the mask will + cause wraparound, and we will safely generate a bogus-but-in-range output. + For the post-IDCT step, we want to convert the data from signed to unsigned + representation by adding CENTERJSAMPLE at the same time that we limit it. + So the post-IDCT limiting table ends up looking like this: + CENTERJSAMPLE,CENTERJSAMPLE+1,...,MAXJSAMPLE, + MAXJSAMPLE (repeat 2*(MAXJSAMPLE+1)-CENTERJSAMPLE times), + 0 (repeat 2*(MAXJSAMPLE+1)-CENTERJSAMPLE times), + 0,1,...,CENTERJSAMPLE-1 + Negative inputs select values from the upper half of the table after + masking. + + We can save some space by overlapping the start of the post-IDCT table + with the simpler range limiting table. The post-IDCT table begins at + sample_range_limit + CENTERJSAMPLE. + + Note that the table is allocated in near data space on PCs; it's small + enough and used often enough to justify this. } + +{LOCAL} +procedure prepare_range_limit_table (cinfo : j_decompress_ptr); +{ Allocate and fill in the sample_range_limit table } +var + table : range_limit_table_ptr; + idct_table : JSAMPROW; + i : int; +begin + table := range_limit_table_ptr ( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + (5 * (MAXJSAMPLE+1) + CENTERJSAMPLE) * SIZEOF(JSAMPLE)) ); + + { First segment of "simple" table: limit[x] := 0 for x < 0 } + MEMZERO(table, (MAXJSAMPLE+1) * SIZEOF(JSAMPLE)); + + cinfo^.sample_range_limit := (table); + { allow negative subscripts of simple table } + { is noop, handled via type definition (Nomssi) } + { Main part of "simple" table: limit[x] := x } + for i := 0 to MAXJSAMPLE do + table^[i] := JSAMPLE (i); + idct_table := JSAMPROW(@ table^[CENTERJSAMPLE]); + { Point to where post-IDCT table starts } + { End of simple table, rest of first half of post-IDCT table } + for i := CENTERJSAMPLE to pred(2*(MAXJSAMPLE+1)) do + idct_table^[i] := MAXJSAMPLE; + { Second half of post-IDCT table } + MEMZERO(@(idct_table^[2 * (MAXJSAMPLE+1)]), + (2 * (MAXJSAMPLE+1) - CENTERJSAMPLE) * SIZEOF(JSAMPLE)); + MEMCOPY(@(idct_table^[(4 * (MAXJSAMPLE+1) - CENTERJSAMPLE)]), + @cinfo^.sample_range_limit^[0], CENTERJSAMPLE * SIZEOF(JSAMPLE)); + +end; + + +{ Master selection of decompression modules. + This is done once at jpeg_start_decompress time. We determine + which modules will be used and give them appropriate initialization calls. + We also initialize the decompressor input side to begin consuming data. + + Since jpeg_read_header has finished, we know what is in the SOF + and (first) SOS markers. We also have all the application parameter + settings. } + +{LOCAL} +procedure master_selection (cinfo : j_decompress_ptr); +var + master : my_master_ptr; + use_c_buffer : boolean; + samplesperrow : long; + jd_samplesperrow : JDIMENSION; +var + nscans : int; +begin + master := my_master_ptr (cinfo^.master); + + { Initialize dimensions and other stuff } + jpeg_calc_output_dimensions(cinfo); + prepare_range_limit_table(cinfo); + + { Width of an output scanline must be representable as JDIMENSION. } + samplesperrow := long(cinfo^.output_width) * long (cinfo^.out_color_components); + jd_samplesperrow := JDIMENSION (samplesperrow); + if (long(jd_samplesperrow) <> samplesperrow) then + ERREXIT(j_common_ptr(cinfo), JERR_WIDTH_OVERFLOW); + + { Initialize my private state } + master^.pass_number := 0; + master^.using_merged_upsample := use_merged_upsample(cinfo); + + { Color quantizer selection } + master^.quantizer_1pass := NIL; + master^.quantizer_2pass := NIL; + { No mode changes if not using buffered-image mode. } + if (not cinfo^.quantize_colors) or (not cinfo^.buffered_image) then + begin + cinfo^.enable_1pass_quant := FALSE; + cinfo^.enable_external_quant := FALSE; + cinfo^.enable_2pass_quant := FALSE; + end; + if (cinfo^.quantize_colors) then + begin + if (cinfo^.raw_data_out) then + ERREXIT(j_common_ptr(cinfo), JERR_NOTIMPL); + { 2-pass quantizer only works in 3-component color space. } + if (cinfo^.out_color_components <> 3) then + begin + cinfo^.enable_1pass_quant := TRUE; + cinfo^.enable_external_quant := FALSE; + cinfo^.enable_2pass_quant := FALSE; + cinfo^.colormap := NIL; + end + else + if (cinfo^.colormap <> NIL) then + begin + cinfo^.enable_external_quant := TRUE; + end + else + if (cinfo^.two_pass_quantize) then + begin + cinfo^.enable_2pass_quant := TRUE; + end + else + begin + cinfo^.enable_1pass_quant := TRUE; + end; + + if (cinfo^.enable_1pass_quant) then + begin +{$ifdef QUANT_1PASS_SUPPORTED} + jinit_1pass_quantizer(cinfo); + master^.quantizer_1pass := cinfo^.cquantize; +{$else} + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); +{$endif} + end; + + { We use the 2-pass code to map to external colormaps. } + if (cinfo^.enable_2pass_quant) or (cinfo^.enable_external_quant) then + begin +{$ifdef QUANT_2PASS_SUPPORTED} + jinit_2pass_quantizer(cinfo); + master^.quantizer_2pass := cinfo^.cquantize; +{$else} + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); +{$endif} + end; + { If both quantizers are initialized, the 2-pass one is left active; + this is necessary for starting with quantization to an external map. } + end; + + { Post-processing: in particular, color conversion first } + if (not cinfo^.raw_data_out) then + begin + if (master^.using_merged_upsample) then + begin +{$ifdef UPSAMPLE_MERGING_SUPPORTED} + jinit_merged_upsampler(cinfo); { does color conversion too } +{$else} + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); +{$endif} + end + else + begin + jinit_color_deconverter(cinfo); + jinit_upsampler(cinfo); + end; + jinit_d_post_controller(cinfo, cinfo^.enable_2pass_quant); + end; + { Inverse DCT } + jinit_inverse_dct(cinfo); + { Entropy decoding: either Huffman or arithmetic coding. } + if (cinfo^.arith_code) then + begin + ERREXIT(j_common_ptr(cinfo), JERR_ARITH_NOTIMPL); + end + else + begin + if (cinfo^.progressive_mode) then + begin +{$ifdef D_PROGRESSIVE_SUPPORTED} + jinit_phuff_decoder(cinfo); +{$else} + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); +{$endif} + end + else + jinit_huff_decoder(cinfo); + end; + + { Initialize principal buffer controllers. } + use_c_buffer := cinfo^.inputctl^.has_multiple_scans or cinfo^.buffered_image; + jinit_d_coef_controller(cinfo, use_c_buffer); + + if (not cinfo^.raw_data_out) then + jinit_d_main_controller(cinfo, FALSE { never need full buffer here }); + + { We can now tell the memory manager to allocate virtual arrays. } + cinfo^.mem^.realize_virt_arrays (j_common_ptr(cinfo)); + + { Initialize input side of decompressor to consume first scan. } + cinfo^.inputctl^.start_input_pass (cinfo); + +{$ifdef D_MULTISCAN_FILES_SUPPORTED} + { If jpeg_start_decompress will read the whole file, initialize + progress monitoring appropriately. The input step is counted + as one pass. } + + if (cinfo^.progress <> NIL) and (not cinfo^.buffered_image) and + (cinfo^.inputctl^.has_multiple_scans) then + begin + + { Estimate number of scans to set pass_limit. } + if (cinfo^.progressive_mode) then + begin + { Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. } + nscans := 2 + 3 * cinfo^.num_components; + end + else + begin + { For a nonprogressive multiscan file, estimate 1 scan per component. } + nscans := cinfo^.num_components; + end; + cinfo^.progress^.pass_counter := Long(0); + cinfo^.progress^.pass_limit := long (cinfo^.total_iMCU_rows) * nscans; + cinfo^.progress^.completed_passes := 0; + if cinfo^.enable_2pass_quant then + cinfo^.progress^.total_passes := 3 + else + cinfo^.progress^.total_passes := 2; + { Count the input pass as done } + Inc(master^.pass_number); + end; +{$endif} { D_MULTISCAN_FILES_SUPPORTED } +end; + + +{ Per-pass setup. + This is called at the beginning of each output pass. We determine which + modules will be active during this pass and give them appropriate + start_pass calls. We also set is_dummy_pass to indicate whether this + is a "real" output pass or a dummy pass for color quantization. + (In the latter case, jdapistd.c will crank the pass to completion.) } + +{METHODDEF} +procedure prepare_for_output_pass (cinfo : j_decompress_ptr); +var + master : my_master_ptr; +begin + master := my_master_ptr (cinfo^.master); + + if (master^.pub.is_dummy_pass) then + begin +{$ifdef QUANT_2PASS_SUPPORTED} + { Final pass of 2-pass quantization } + master^.pub.is_dummy_pass := FALSE; + cinfo^.cquantize^.start_pass (cinfo, FALSE); + cinfo^.post^.start_pass (cinfo, JBUF_CRANK_DEST); + cinfo^.main^.start_pass (cinfo, JBUF_CRANK_DEST); +{$else} + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); +{$endif} { QUANT_2PASS_SUPPORTED } + end + else + begin + if (cinfo^.quantize_colors) and (cinfo^.colormap = NIL) then + begin + { Select new quantization method } + if (cinfo^.two_pass_quantize) and (cinfo^.enable_2pass_quant) then + begin + cinfo^.cquantize := master^.quantizer_2pass; + master^.pub.is_dummy_pass := TRUE; + end + else + if (cinfo^.enable_1pass_quant) then + begin + cinfo^.cquantize := master^.quantizer_1pass; + end + else + begin + ERREXIT(j_common_ptr(cinfo), JERR_MODE_CHANGE); + end; + end; + cinfo^.idct^.start_pass (cinfo); + cinfo^.coef^.start_output_pass (cinfo); + if (not cinfo^.raw_data_out) then + begin + if (not master^.using_merged_upsample) then + cinfo^.cconvert^.start_pass (cinfo); + cinfo^.upsample^.start_pass (cinfo); + if (cinfo^.quantize_colors) then + cinfo^.cquantize^.start_pass (cinfo, master^.pub.is_dummy_pass); + if master^.pub.is_dummy_pass then + cinfo^.post^.start_pass (cinfo, JBUF_SAVE_AND_PASS) + else + cinfo^.post^.start_pass (cinfo, JBUF_PASS_THRU); + cinfo^.main^.start_pass (cinfo, JBUF_PASS_THRU); + end; + end; + + { Set up progress monitor's pass info if present } + if (cinfo^.progress <> NIL) then + begin + cinfo^.progress^.completed_passes := master^.pass_number; + if master^.pub.is_dummy_pass then + cinfo^.progress^.total_passes := master^.pass_number + 2 + else + cinfo^.progress^.total_passes := master^.pass_number + 1; + { In buffered-image mode, we assume one more output pass if EOI not + yet reached, but no more passes if EOI has been reached. } + + if (cinfo^.buffered_image) and (not cinfo^.inputctl^.eoi_reached) then + begin + if cinfo^.enable_2pass_quant then + Inc(cinfo^.progress^.total_passes, 2) + else + Inc(cinfo^.progress^.total_passes, 1); + end; + end; +end; + + +{ Finish up at end of an output pass. } + +{METHODDEF} +procedure finish_output_pass (cinfo : j_decompress_ptr); +var + master : my_master_ptr; +begin + master := my_master_ptr (cinfo^.master); + + if (cinfo^.quantize_colors) then + cinfo^.cquantize^.finish_pass (cinfo); + Inc(master^.pass_number); +end; + + +{$ifdef D_MULTISCAN_FILES_SUPPORTED} + +{ Switch to a new external colormap between output passes. } + +{GLOBAL} +procedure jpeg_new_colormap (cinfo : j_decompress_ptr); +var + master : my_master_ptr; +begin + master := my_master_ptr (cinfo^.master); + + { Prevent application from calling me at wrong times } + if (cinfo^.global_state <> DSTATE_BUFIMAGE) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + + if (cinfo^.quantize_colors) and (cinfo^.enable_external_quant) and + (cinfo^.colormap <> NIL) then + begin + { Select 2-pass quantizer for external colormap use } + cinfo^.cquantize := master^.quantizer_2pass; + { Notify quantizer of colormap change } + cinfo^.cquantize^.new_color_map (cinfo); + master^.pub.is_dummy_pass := FALSE; { just in case } + end + else + ERREXIT(j_common_ptr(cinfo), JERR_MODE_CHANGE); +end; + +{$endif} { D_MULTISCAN_FILES_SUPPORTED } + + +{ Initialize master decompression control and select active modules. + This is performed at the start of jpeg_start_decompress. } + +{GLOBAL} +procedure jinit_master_decompress (cinfo : j_decompress_ptr); +var + master : my_master_ptr; +begin + master := my_master_ptr ( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(my_decomp_master)) ); + cinfo^.master := jpeg_decomp_master_ptr(master); + master^.pub.prepare_for_output_pass := prepare_for_output_pass; + master^.pub.finish_output_pass := finish_output_pass; + + master^.pub.is_dummy_pass := FALSE; + + master_selection(cinfo); +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jdmerge_del.pas b/mseide-msegui/lib/common/fpccompatibility/jdmerge_del.pas new file mode 100644 index 0000000..0c9cd5a --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jdmerge_del.pas @@ -0,0 +1,515 @@ +unit jdmerge_del; + +{ This file contains code for merged upsampling/color conversion. + + This file combines functions from jdsample.c and jdcolor.c; + read those files first to understand what's going on. + + When the chroma components are to be upsampled by simple replication + (ie, box filtering), we can save some work in color conversion by + calculating all the output pixels corresponding to a pair of chroma + samples at one time. In the conversion equations + R := Y + K1 * Cr + G := Y + K2 * Cb + K3 * Cr + B := Y + K4 * Cb + only the Y term varies among the group of pixels corresponding to a pair + of chroma samples, so the rest of the terms can be calculated just once. + At typical sampling ratios, this eliminates half or three-quarters of the + multiplications needed for color conversion. + + This file currently provides implementations for the following cases: + YCbCr => RGB color conversion only. + Sampling ratios of 2h1v or 2h2v. + No scaling needed at upsample time. + Corner-aligned (non-CCIR601) sampling alignment. + Other special cases could be added, but in most applications these are + the only common cases. (For uncommon cases we fall back on the more + general code in jdsample.c and jdcolor.c.) } + +{ Original: jdmerge.c ; Copyright (C) 1994-1996, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jpeglib_del, + jutils_del; + +{ Module initialization routine for merged upsampling/color conversion. + + NB: this is called under the conditions determined by use_merged_upsample() + in jdmaster.c. That routine MUST correspond to the actual capabilities + of this module; no safety checks are made here. } + +{GLOBAL} +procedure jinit_merged_upsampler (cinfo : j_decompress_ptr); + +implementation + + +{ Private subobject } + +type { the same definition as in JdColor } + int_Color_Table = array[0..MAXJSAMPLE+1-1] of int; + int_CConvertPtr = ^int_Color_Table; + INT32_Color_Table = array[0..MAXJSAMPLE+1-1] of INT32; + INT32_CConvertPtr = ^INT32_Color_Table; + +type + my_upsample_ptr = ^my_upsampler; + my_upsampler = record + pub : jpeg_upsampler; { public fields } + + { Pointer to routine to do actual upsampling/conversion of one row group } + upmethod : procedure (cinfo : j_decompress_ptr; + input_buf : JSAMPIMAGE; + in_row_group_ctr : JDIMENSION; + output_buf : JSAMPARRAY); + + { Private state for YCC->RGB conversion } + Cr_r_tab : int_CConvertPtr; { => table for Cr to R conversion } + Cb_b_tab : int_CConvertPtr; { => table for Cb to B conversion } + Cr_g_tab : INT32_CConvertPtr; { => table for Cr to G conversion } + Cb_g_tab : INT32_CConvertPtr; { => table for Cb to G conversion } + + { For 2:1 vertical sampling, we produce two output rows at a time. + We need a "spare" row buffer to hold the second output row if the + application provides just a one-row buffer; we also use the spare + to discard the dummy last row if the image height is odd. } + + spare_row : JSAMPROW; + spare_full : boolean; { TRUE if spare buffer is occupied } + + out_row_width : JDIMENSION; { samples per output row } + rows_to_go : JDIMENSION; { counts rows remaining in image } + end; {my_upsampler;} + + +const + SCALEBITS = 16; { speediest right-shift on some machines } + ONE_HALF = (INT32(1) shl (SCALEBITS-1)); + + +{ Initialize tables for YCC->RGB colorspace conversion. + This is taken directly from jdcolor.c; see that file for more info. } + +{LOCAL} +procedure build_ycc_rgb_table (cinfo : j_decompress_ptr); +const + FIX_1_40200 = INT32( Round(1.40200 * (INT32(1) shl SCALEBITS)) ); + FIX_1_77200 = INT32( Round(1.77200 * (INT32(1) shl SCALEBITS)) ); + FIX_0_71414 = INT32( Round(0.71414 * (INT32(1) shl SCALEBITS)) ); + FIX_0_34414 = INT32( Round(0.34414 * (INT32(1) shl SCALEBITS)) ); +var + upsample : my_upsample_ptr; + i : int; + x : INT32; +var + shift_temp : INT32; +begin + upsample := my_upsample_ptr (cinfo^.upsample); + + upsample^.Cr_r_tab := int_CConvertPtr ( + cinfo^.mem^.alloc_small (j_common_ptr (cinfo), JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(int)) ); + upsample^.Cb_b_tab := int_CConvertPtr ( + cinfo^.mem^.alloc_small (j_common_ptr (cinfo), JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(int)) ); + upsample^.Cr_g_tab := INT32_CConvertPtr ( + cinfo^.mem^.alloc_small (j_common_ptr (cinfo), JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(INT32)) ); + upsample^.Cb_g_tab := INT32_CConvertPtr ( + cinfo^.mem^.alloc_small (j_common_ptr (cinfo), JPOOL_IMAGE, + (MAXJSAMPLE+1) * SIZEOF(INT32)) ); + + x := -CENTERJSAMPLE; + for i := 0 to pred(MAXJSAMPLE) do + begin + { i is the actual input pixel value, in the range 0..MAXJSAMPLE } + { The Cb or Cr value we are thinking of is x := i - CENTERJSAMPLE } + { Cr=>R value is nearest int to 1.40200 * x } + {upsample^.Cr_r_tab^[i] := int( + RIGHT_SHIFT(FIX_1_40200 * x + ONE_HALF, SCALEBITS) );} + shift_temp := FIX_1_40200 * x + ONE_HALF; + if shift_temp < 0 then { SHIFT arithmetic RIGHT } + upsample^.Cr_r_tab^[i] := int((shift_temp shr SCALEBITS) + or ( (not INT32(0)) shl (32-SCALEBITS))) + else + upsample^.Cr_r_tab^[i] := int(shift_temp shr SCALEBITS); + + + { Cb=>B value is nearest int to 1.77200 * x } + {upsample^.Cb_b_tab^[i] := int( + RIGHT_SHIFT(FIX_1_77200 * x + ONE_HALF, SCALEBITS) );} + shift_temp := FIX_1_77200 * x + ONE_HALF; + if shift_temp < 0 then { SHIFT arithmetic RIGHT } + upsample^.Cb_b_tab^[i] := int((shift_temp shr SCALEBITS) + or ( (not INT32(0)) shl (32-SCALEBITS))) + else + upsample^.Cb_b_tab^[i] := int(shift_temp shr SCALEBITS); + + { Cr=>G value is scaled-up -0.71414 * x } + upsample^.Cr_g_tab^[i] := (- FIX_0_71414) * x; + { Cb=>G value is scaled-up -0.34414 * x } + { We also add in ONE_HALF so that need not do it in inner loop } + upsample^.Cb_g_tab^[i] := (- FIX_0_34414) * x + ONE_HALF; + Inc(x); + end; +end; + + +{ Initialize for an upsampling pass. } + +{METHODDEF} +procedure start_pass_merged_upsample (cinfo : j_decompress_ptr); +var + upsample : my_upsample_ptr; +begin + upsample := my_upsample_ptr (cinfo^.upsample); + + { Mark the spare buffer empty } + upsample^.spare_full := FALSE; + { Initialize total-height counter for detecting bottom of image } + upsample^.rows_to_go := cinfo^.output_height; +end; + + +{ Control routine to do upsampling (and color conversion). + + The control routine just handles the row buffering considerations. } + +{METHODDEF} +procedure merged_2v_upsample (cinfo : j_decompress_ptr; + input_buf : JSAMPIMAGE; + var in_row_group_ctr : JDIMENSION; + in_row_groups_avail : JDIMENSION; + output_buf : JSAMPARRAY; + var out_row_ctr : JDIMENSION; + out_rows_avail : JDIMENSION); +{ 2:1 vertical sampling case: may need a spare row. } +var + upsample : my_upsample_ptr; + work_ptrs : array[0..2-1] of JSAMPROW; + num_rows : JDIMENSION; { number of rows returned to caller } +begin + upsample := my_upsample_ptr (cinfo^.upsample); + + if (upsample^.spare_full) then + begin + { If we have a spare row saved from a previous cycle, just return it. } + jcopy_sample_rows(JSAMPARRAY(@upsample^.spare_row), + 0, + JSAMPARRAY(@ output_buf^[out_row_ctr]), + 0, 1, upsample^.out_row_width); + num_rows := 1; + upsample^.spare_full := FALSE; + end + else + begin + { Figure number of rows to return to caller. } + num_rows := 2; + { Not more than the distance to the end of the image. } + if (num_rows > upsample^.rows_to_go) then + num_rows := upsample^.rows_to_go; + { And not more than what the client can accept: } + Dec(out_rows_avail, {var} out_row_ctr); + if (num_rows > out_rows_avail) then + num_rows := out_rows_avail; + { Create output pointer array for upsampler. } + work_ptrs[0] := output_buf^[out_row_ctr]; + if (num_rows > 1) then + begin + work_ptrs[1] := output_buf^[out_row_ctr + 1]; + end + else + begin + work_ptrs[1] := upsample^.spare_row; + upsample^.spare_full := TRUE; + end; + { Now do the upsampling. } + upsample^.upmethod (cinfo, input_buf, {var}in_row_group_ctr, + JSAMPARRAY(@work_ptrs)); + end; + + { Adjust counts } + Inc(out_row_ctr, num_rows); + Dec(upsample^.rows_to_go, num_rows); + { When the buffer is emptied, declare this input row group consumed } + if (not upsample^.spare_full) then + Inc(in_row_group_ctr); +end; + + +{METHODDEF} +procedure merged_1v_upsample (cinfo : j_decompress_ptr; + input_buf : JSAMPIMAGE; + var in_row_group_ctr : JDIMENSION; + in_row_groups_avail : JDIMENSION; + output_buf : JSAMPARRAY; + var out_row_ctr : JDIMENSION; + out_rows_avail : JDIMENSION); +{ 1:1 vertical sampling case: much easier, never need a spare row. } +var + upsample : my_upsample_ptr; +begin + upsample := my_upsample_ptr (cinfo^.upsample); + + { Just do the upsampling. } + upsample^.upmethod (cinfo, input_buf, in_row_group_ctr, + JSAMPARRAY(@ output_buf^[out_row_ctr])); + { Adjust counts } + Inc(out_row_ctr); + Inc(in_row_group_ctr); +end; + + +{ These are the routines invoked by the control routines to do + the actual upsampling/conversion. One row group is processed per call. + + Note: since we may be writing directly into application-supplied buffers, + we have to be honest about the output width; we can't assume the buffer + has been rounded up to an even width. } + + +{ Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical. } + +{METHODDEF} +procedure h2v1_merged_upsample (cinfo : j_decompress_ptr; + input_buf : JSAMPIMAGE; + in_row_group_ctr : JDIMENSION; + output_buf : JSAMPARRAY); +var + upsample : my_upsample_ptr; + {register} y, cred, cgreen, cblue : int; + cb, cr : int; + {register} outptr : JSAMPROW; + inptr0, inptr1, inptr2 : JSAMPLE_PTR; + col : JDIMENSION; + { copy these pointers into registers if possible } + {register} range_limit : range_limit_table_ptr; + Crrtab : int_CConvertPtr; + Cbbtab : int_CConvertPtr; + Crgtab : INT32_CConvertPtr; + Cbgtab : INT32_CConvertPtr; +var + shift_temp : INT32; +begin + upsample := my_upsample_ptr (cinfo^.upsample); + range_limit := cinfo^.sample_range_limit; + Crrtab := upsample^.Cr_r_tab; + Cbbtab := upsample^.Cb_b_tab; + Crgtab := upsample^.Cr_g_tab; + Cbgtab := upsample^.Cb_g_tab; + + inptr0 := JSAMPLE_PTR(input_buf^[0]^[in_row_group_ctr]); + inptr1 := JSAMPLE_PTR(input_buf^[1]^[in_row_group_ctr]); + inptr2 := JSAMPLE_PTR(input_buf^[2]^[in_row_group_ctr]); + outptr := output_buf^[0]; + { Loop for each pair of output pixels } + for col := pred(cinfo^.output_width shr 1) downto 0 do + begin + { Do the chroma part of the calculation } + cb := GETJSAMPLE(inptr1^); + Inc(inptr1); + cr := GETJSAMPLE(inptr2^); + Inc(inptr2); + cred := Crrtab^[cr]; + {cgreen := int( RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS) );} + shift_temp := Cbgtab^[cb] + Crgtab^[cr]; + if shift_temp < 0 then { SHIFT arithmetic RIGHT } + cgreen := int((shift_temp shr SCALEBITS) + or ( (not INT32(0)) shl (32-SCALEBITS))) + else + cgreen := int(shift_temp shr SCALEBITS); + + cblue := Cbbtab^[cb]; + { Fetch 2 Y values and emit 2 pixels } + y := GETJSAMPLE(inptr0^); + Inc(inptr0); + outptr^[RGB_RED] := range_limit^[y + cred]; + outptr^[RGB_GREEN] := range_limit^[y + cgreen]; + outptr^[RGB_BLUE] := range_limit^[y + cblue]; + Inc(JSAMPLE_PTR(outptr), RGB_PIXELSIZE); + y := GETJSAMPLE(inptr0^); + Inc(inptr0); + outptr^[RGB_RED] := range_limit^[y + cred]; + outptr^[RGB_GREEN] := range_limit^[y + cgreen]; + outptr^[RGB_BLUE] := range_limit^[y + cblue]; + Inc(JSAMPLE_PTR(outptr), RGB_PIXELSIZE); + end; + { If image width is odd, do the last output column separately } + if Odd(cinfo^.output_width) then + begin + cb := GETJSAMPLE(inptr1^); + cr := GETJSAMPLE(inptr2^); + cred := Crrtab^[cr]; + {cgreen := int ( RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS) );} + shift_temp := Cbgtab^[cb] + Crgtab^[cr]; + if shift_temp < 0 then { SHIFT arithmetic RIGHT } + cgreen := int((shift_temp shr SCALEBITS) + or ( (not INT32(0)) shl (32-SCALEBITS))) + else + cgreen := int(shift_temp shr SCALEBITS); + + cblue := Cbbtab^[cb]; + y := GETJSAMPLE(inptr0^); + outptr^[RGB_RED] := range_limit^[y + cred]; + outptr^[RGB_GREEN] := range_limit^[y + cgreen]; + outptr^[RGB_BLUE] := range_limit^[y + cblue]; + end; +end; + + +{ Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical. } + +{METHODDEF} +procedure h2v2_merged_upsample (cinfo : j_decompress_ptr; + input_buf : JSAMPIMAGE; + in_row_group_ctr : JDIMENSION; + output_buf : JSAMPARRAY); +var + upsample : my_upsample_ptr; + {register} y, cred, cgreen, cblue : int; + cb, cr : int; + {register} outptr0, outptr1 : JSAMPROW; + inptr00, inptr01, inptr1, inptr2 : JSAMPLE_PTR; + col : JDIMENSION; + { copy these pointers into registers if possible } + {register} range_limit : range_limit_table_ptr; + Crrtab : int_CConvertPtr; + Cbbtab : int_CConvertPtr; + Crgtab : INT32_CConvertPtr; + Cbgtab : INT32_CConvertPtr; +var + shift_temp : INT32; +begin + upsample := my_upsample_ptr (cinfo^.upsample); + range_limit := cinfo^.sample_range_limit; + Crrtab := upsample^.Cr_r_tab; + Cbbtab := upsample^.Cb_b_tab; + Crgtab := upsample^.Cr_g_tab; + Cbgtab := upsample^.Cb_g_tab; + + inptr00 := JSAMPLE_PTR(input_buf^[0]^[in_row_group_ctr*2]); + inptr01 := JSAMPLE_PTR(input_buf^[0]^[in_row_group_ctr*2 + 1]); + inptr1 := JSAMPLE_PTR(input_buf^[1]^[in_row_group_ctr]); + inptr2 := JSAMPLE_PTR(input_buf^[2]^[in_row_group_ctr]); + outptr0 := output_buf^[0]; + outptr1 := output_buf^[1]; + { Loop for each group of output pixels } + for col := pred(cinfo^.output_width shr 1) downto 0 do + begin + { Do the chroma part of the calculation } + cb := GETJSAMPLE(inptr1^); + Inc(inptr1); + cr := GETJSAMPLE(inptr2^); + Inc(inptr2); + cred := Crrtab^[cr]; + {cgreen := int( RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS) );} + shift_temp := Cbgtab^[cb] + Crgtab^[cr]; + if shift_temp < 0 then { SHIFT arithmetic RIGHT } + cgreen := int((shift_temp shr SCALEBITS) + or ( (not INT32(0)) shl (32-SCALEBITS))) + else + cgreen := int(shift_temp shr SCALEBITS); + + cblue := Cbbtab^[cb]; + { Fetch 4 Y values and emit 4 pixels } + y := GETJSAMPLE(inptr00^); + Inc(inptr00); + outptr0^[RGB_RED] := range_limit^[y + cred]; + outptr0^[RGB_GREEN] := range_limit^[y + cgreen]; + outptr0^[RGB_BLUE] := range_limit^[y + cblue]; + Inc(JSAMPLE_PTR(outptr0), RGB_PIXELSIZE); + y := GETJSAMPLE(inptr00^); + Inc(inptr00); + outptr0^[RGB_RED] := range_limit^[y + cred]; + outptr0^[RGB_GREEN] := range_limit^[y + cgreen]; + outptr0^[RGB_BLUE] := range_limit^[y + cblue]; + Inc(JSAMPLE_PTR(outptr0), RGB_PIXELSIZE); + y := GETJSAMPLE(inptr01^); + Inc(inptr01); + outptr1^[RGB_RED] := range_limit^[y + cred]; + outptr1^[RGB_GREEN] := range_limit^[y + cgreen]; + outptr1^[RGB_BLUE] := range_limit^[y + cblue]; + Inc(JSAMPLE_PTR(outptr1), RGB_PIXELSIZE); + y := GETJSAMPLE(inptr01^); + Inc(inptr01); + outptr1^[RGB_RED] := range_limit^[y + cred]; + outptr1^[RGB_GREEN] := range_limit^[y + cgreen]; + outptr1^[RGB_BLUE] := range_limit^[y + cblue]; + Inc(JSAMPLE_PTR(outptr1), RGB_PIXELSIZE); + end; + { If image width is odd, do the last output column separately } + if Odd(cinfo^.output_width) then + begin + cb := GETJSAMPLE(inptr1^); + cr := GETJSAMPLE(inptr2^); + cred := Crrtab^[cr]; + {cgreen := int (RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS));} + shift_temp := Cbgtab^[cb] + Crgtab^[cr]; + if shift_temp < 0 then { SHIFT arithmetic RIGHT } + cgreen := int((shift_temp shr SCALEBITS) + or ( (not INT32(0)) shl (32-SCALEBITS))) + else + cgreen := int(shift_temp shr SCALEBITS); + + cblue := Cbbtab^[cb]; + y := GETJSAMPLE(inptr00^); + outptr0^[RGB_RED] := range_limit^[y + cred]; + outptr0^[RGB_GREEN] := range_limit^[y + cgreen]; + outptr0^[RGB_BLUE] := range_limit^[y + cblue]; + y := GETJSAMPLE(inptr01^); + outptr1^[RGB_RED] := range_limit^[y + cred]; + outptr1^[RGB_GREEN] := range_limit^[y + cgreen]; + outptr1^[RGB_BLUE] := range_limit^[y + cblue]; + end; +end; + + +{ Module initialization routine for merged upsampling/color conversion. + + NB: this is called under the conditions determined by use_merged_upsample() + in jdmaster.c. That routine MUST correspond to the actual capabilities + of this module; no safety checks are made here. } + + +{GLOBAL} +procedure jinit_merged_upsampler (cinfo : j_decompress_ptr); +var + upsample : my_upsample_ptr; +begin + upsample := my_upsample_ptr ( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(my_upsampler)) ); + cinfo^.upsample := jpeg_upsampler_ptr (upsample); + upsample^.pub.start_pass := start_pass_merged_upsample; + upsample^.pub.need_context_rows := FALSE; + + upsample^.out_row_width := cinfo^.output_width * cinfo^.out_color_components; + + if (cinfo^.max_v_samp_factor = 2) then + begin + upsample^.pub.upsample := merged_2v_upsample; + upsample^.upmethod := h2v2_merged_upsample; + { Allocate a spare row buffer } + upsample^.spare_row := JSAMPROW( + cinfo^.mem^.alloc_large ( j_common_ptr(cinfo), JPOOL_IMAGE, + size_t (upsample^.out_row_width * SIZEOF(JSAMPLE))) ); + end + else + begin + upsample^.pub.upsample := merged_1v_upsample; + upsample^.upmethod := h2v1_merged_upsample; + { No spare row needed } + upsample^.spare_row := NIL; + end; + + build_ycc_rgb_table(cinfo); +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jdphuff_del.pas b/mseide-msegui/lib/common/fpccompatibility/jdphuff_del.pas new file mode 100644 index 0000000..97446d7 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jdphuff_del.pas @@ -0,0 +1,1060 @@ +unit jdphuff_del; + +{ This file contains Huffman entropy decoding routines for progressive JPEG. + + Much of the complexity here has to do with supporting input suspension. + If the data source module demands suspension, we want to be able to back + up to the start of the current MCU. To do this, we copy state variables + into local working storage, and update them back to the permanent + storage only upon successful completion of an MCU. } + +{ Original: jdphuff.c ; Copyright (C) 1995-1997, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jpeglib_del, + jdeferr_del, + jerror_del, + jutils_del, + jdhuff_del; { Declarations shared with jdhuff.c } + + +{GLOBAL} +procedure jinit_phuff_decoder (cinfo : j_decompress_ptr); + +implementation + +{ Expanded entropy decoder object for progressive Huffman decoding. + + The savable_state subrecord contains fields that change within an MCU, + but must not be updated permanently until we complete the MCU. } + +type + savable_state = record + EOBRUN : uInt; { remaining EOBs in EOBRUN } + last_dc_val : array[00..MAX_COMPS_IN_SCAN-1] of int; + { last DC coef for each component } + end; + + +type + phuff_entropy_ptr = ^phuff_entropy_decoder; + phuff_entropy_decoder = record + pub : jpeg_entropy_decoder; { public fields } + + { These fields are loaded into local variables at start of each MCU. + In case of suspension, we exit WITHOUT updating them. } + + bitstate : bitread_perm_state; { Bit buffer at start of MCU } + saved : savable_state; { Other state at start of MCU } + + { These fields are NOT loaded into local working state. } + restarts_to_go : uInt; { MCUs left in this restart interval } + + { Pointers to derived tables (these workspaces have image lifespan) } + derived_tbls : array[0..NUM_HUFF_TBLS-1] of d_derived_tbl_ptr; + + ac_derived_tbl : d_derived_tbl_ptr; { active table during an AC scan } + end; + + + +{ Forward declarations } +{METHODDEF} +function decode_mcu_DC_first (cinfo : j_decompress_ptr; + var MCU_data : array of JBLOCKROW) : boolean; + forward; +{METHODDEF} +function decode_mcu_AC_first (cinfo : j_decompress_ptr; + var MCU_data : array of JBLOCKROW) : boolean; + forward; +{METHODDEF} +function decode_mcu_DC_refine (cinfo : j_decompress_ptr; + var MCU_data : array of JBLOCKROW) : boolean; + forward; +{METHODDEF} +function decode_mcu_AC_refine (cinfo : j_decompress_ptr; + var MCU_data : array of JBLOCKROW) : boolean; + forward; + +{ Initialize for a Huffman-compressed scan. } + +{METHODDEF} +procedure start_pass_phuff_decoder (cinfo : j_decompress_ptr); +var + entropy : phuff_entropy_ptr; + is_DC_band, bad : boolean; + ci, coefi, tbl : int; + coef_bit_ptr : coef_bits_ptr; + compptr : jpeg_component_info_ptr; +var + cindex : int; + expected : int; +begin + entropy := phuff_entropy_ptr (cinfo^.entropy); + + is_DC_band := (cinfo^.Ss = 0); + + { Validate scan parameters } + bad := FALSE; + if (is_DC_band) then + begin + if (cinfo^.Se <> 0) then + bad := TRUE; + end + else + begin + { need not check Ss/Se < 0 since they came from unsigned bytes } + if (cinfo^.Ss > cinfo^.Se) or (cinfo^.Se >= DCTSIZE2) then + bad := TRUE; + { AC scans may have only one component } + if (cinfo^.comps_in_scan <> 1) then + bad := TRUE; + end; + if (cinfo^.Ah <> 0) then + begin + { Successive approximation refinement scan: must have Al = Ah-1. } + if (cinfo^.Al <> cinfo^.Ah-1) then + bad := TRUE; + end; + if (cinfo^.Al > 13) then { need not check for < 0 } + bad := TRUE; + { Arguably the maximum Al value should be less than 13 for 8-bit precision, + but the spec doesn't say so, and we try to be liberal about what we + accept. Note: large Al values could result in out-of-range DC + coefficients during early scans, leading to bizarre displays due to + overflows in the IDCT math. But we won't crash. } + + if (bad) then + ERREXIT4(j_common_ptr(cinfo), JERR_BAD_PROGRESSION, + cinfo^.Ss, cinfo^.Se, cinfo^.Ah, cinfo^.Al); + { Update progression status, and verify that scan order is legal. + Note that inter-scan inconsistencies are treated as warnings + not fatal errors ... not clear if this is right way to behave. } + + for ci := 0 to pred(cinfo^.comps_in_scan) do + begin + cindex := cinfo^.cur_comp_info[ci]^.component_index; + coef_bit_ptr := coef_bits_ptr(@(cinfo^.coef_bits^[cindex])); {^[0] ??? + Nomssi } + if (not is_DC_band) and (coef_bit_ptr^[0] < 0) then + { AC without prior DC scan } + WARNMS2(j_common_ptr(cinfo), JWRN_BOGUS_PROGRESSION, cindex, 0); + for coefi := cinfo^.Ss to cinfo^.Se do + begin + if (coef_bit_ptr^[coefi] < 0) then + expected := 0 + else + expected := coef_bit_ptr^[coefi]; + if (cinfo^.Ah <> expected) then + WARNMS2(j_common_ptr(cinfo), JWRN_BOGUS_PROGRESSION, cindex, coefi); + coef_bit_ptr^[coefi] := cinfo^.Al; + end; + end; + + { Select MCU decoding routine } + if (cinfo^.Ah = 0) then + begin + if (is_DC_band) then + entropy^.pub.decode_mcu := decode_mcu_DC_first + else + entropy^.pub.decode_mcu := decode_mcu_AC_first; + end + else + begin + if (is_DC_band) then + entropy^.pub.decode_mcu := decode_mcu_DC_refine + else + entropy^.pub.decode_mcu := decode_mcu_AC_refine; + end; + + for ci := 0 to pred(cinfo^.comps_in_scan) do + begin + compptr := cinfo^.cur_comp_info[ci]; + { Make sure requested tables are present, and compute derived tables. + We may build same derived table more than once, but it's not expensive. } + + if (is_DC_band) then + begin + if (cinfo^.Ah = 0) then + begin { DC refinement needs no table } + tbl := compptr^.dc_tbl_no; + jpeg_make_d_derived_tbl(cinfo, TRUE, tbl, + entropy^.derived_tbls[tbl]); + end; + end + else + begin + tbl := compptr^.ac_tbl_no; + jpeg_make_d_derived_tbl(cinfo, FALSE, tbl, + entropy^.derived_tbls[tbl]); + { remember the single active table } + entropy^.ac_derived_tbl := entropy^.derived_tbls[tbl]; + end; + { Initialize DC predictions to 0 } + entropy^.saved.last_dc_val[ci] := 0; + end; + + { Initialize bitread state variables } + entropy^.bitstate.bits_left := 0; + entropy^.bitstate.get_buffer := 0; { unnecessary, but keeps Purify quiet } + entropy^.pub.insufficient_data := FALSE; + + { Initialize private state variables } + entropy^.saved.EOBRUN := 0; + + { Initialize restart counter } + entropy^.restarts_to_go := cinfo^.restart_interval; +end; + + +{ Figure F.12: extend sign bit. + On some machines, a shift and add will be faster than a table lookup. } + +{$ifdef AVOID_TABLES} + +#define HUFF_EXTEND(x,s) + ((x) < (1shl((s)-1)) ? (x) + (((-1)shl(s)) + 1) : (x)) + +{$else} + +{ #define HUFF_EXTEND(x,s) + if (x) < extend_test[s] then + (x) + extend_offset[s] + else + (x)} + +const + extend_test : Array[0..16-1] of int = { entry n is 2**(n-1) } + ($0000, $0001, $0002, $0004, $0008, $0010, $0020, $0040, + $0080, $0100, $0200, $0400, $0800, $1000, $2000, $4000); + +const + extend_offset : array[0..16-1] of int = { entry n is (-1 shl n) + 1 } + ( 0, ((-1) shl 1) + 1, ((-1) shl 2) + 1, ((-1) shl 3) + 1, ((-1) shl 4) + 1, + ((-1) shl 5) + 1, ((-1) shl 6) + 1, ((-1) shl 7) + 1, ((-1) shl 8) + 1, + ((-1) shl 9) + 1, ((-1) shl 10) + 1, ((-1) shl 11) + 1, ((-1) shl 12) + 1, + ((-1) shl 13) + 1, ((-1) shl 14) + 1, ((-1) shl 15) + 1 ); + +{$endif} { AVOID_TABLES } + + +{ Check for a restart marker & resynchronize decoder. + return:=s FALSE if must suspend. } + +{LOCAL} +function process_restart (cinfo : j_decompress_ptr) : boolean; +var + entropy : phuff_entropy_ptr; + ci : int; +begin + entropy := phuff_entropy_ptr (cinfo^.entropy); + + { Throw away any unused bits remaining in bit buffer; } + { include any full bytes in next_marker's count of discarded bytes } + Inc(cinfo^.marker^.discarded_bytes, entropy^.bitstate.bits_left div 8); + entropy^.bitstate.bits_left := 0; + + { Advance past the RSTn marker } + if (not cinfo^.marker^.read_restart_marker (cinfo)) then + begin + process_restart := FALSE; + exit; + end; + + { Re-initialize DC predictions to 0 } + for ci := 0 to pred(cinfo^.comps_in_scan) do + entropy^.saved.last_dc_val[ci] := 0; + { Re-init EOB run count, too } + entropy^.saved.EOBRUN := 0; + + { Reset restart counter } + entropy^.restarts_to_go := cinfo^.restart_interval; + + { Reset out-of-data flag, unless read_restart_marker left us smack up + against a marker. In that case we will end up treating the next data + segment as empty, and we can avoid producing bogus output pixels by + leaving the flag set. } + if (cinfo^.unread_marker = 0) then + entropy^.pub.insufficient_data := FALSE; + + process_restart := TRUE; +end; + + +{ Huffman MCU decoding. + Each of these routines decodes and returns one MCU's worth of + Huffman-compressed coefficients. + The coefficients are reordered from zigzag order into natural array order, + but are not dequantized. + + The i'th block of the MCU is stored into the block pointed to by + MCU_data[i]. WE ASSUME THIS AREA IS INITIALLY ZEROED BY THE CALLER. + + We return FALSE if data source requested suspension. In that case no + changes have been made to permanent state. (Exception: some output + coefficients may already have been assigned. This is harmless for + spectral selection, since we'll just re-assign them on the next call. + Successive approximation AC refinement has to be more careful, however.) } + + +{ MCU decoding for DC initial scan (either spectral selection, + or first pass of successive approximation). } + +{METHODDEF} +function decode_mcu_DC_first (cinfo : j_decompress_ptr; + var MCU_data : array of JBLOCKROW) : boolean; +label + label1; +var + entropy : phuff_entropy_ptr; + Al : int; + {register} s, r : int; + blkn, ci : int; + block : JBLOCK_PTR; + {BITREAD_STATE_VARS;} + get_buffer : bit_buf_type ; {register} + bits_left : int; {register} + br_state : bitread_working_state; + + state : savable_state; + tbl : d_derived_tbl_ptr; + compptr : jpeg_component_info_ptr; +var + nb, look : int; {register} +begin + entropy := phuff_entropy_ptr (cinfo^.entropy); + Al := cinfo^.Al; + + { Process restart marker if needed; may have to suspend } + if (cinfo^.restart_interval <> 0) then + begin + if (entropy^.restarts_to_go = 0) then + if (not process_restart(cinfo)) then + begin + decode_mcu_DC_first := FALSE; + exit; + end; + end; + + { If we've run out of data, just leave the MCU set to zeroes. + This way, we return uniform gray for the remainder of the segment. } + + if not entropy^.pub.insufficient_data then + begin + + { Load up working state } + {BITREAD_LOAD_STATE(cinfo,entropy^.bitstate);} + br_state.cinfo := cinfo; + br_state.next_input_byte := cinfo^.src^.next_input_byte; + br_state.bytes_in_buffer := cinfo^.src^.bytes_in_buffer; + get_buffer := entropy^.bitstate.get_buffer; + bits_left := entropy^.bitstate.bits_left; + + {ASSIGN_STATE(state, entropy^.saved);} + state := entropy^.saved; + + { Outer loop handles each block in the MCU } + + for blkn := 0 to pred(cinfo^.blocks_in_MCU) do + begin + block := JBLOCK_PTR(MCU_data[blkn]); + ci := cinfo^.MCU_membership[blkn]; + compptr := cinfo^.cur_comp_info[ci]; + tbl := entropy^.derived_tbls[compptr^.dc_tbl_no]; + + { Decode a single block's worth of coefficients } + + { Section F.2.2.1: decode the DC coefficient difference } + {HUFF_DECODE(s, br_state, tbl, return FALSE, label1);} + if (bits_left < HUFF_LOOKAHEAD) then + begin + if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left, 0)) then + begin + decode_mcu_DC_first := FALSE; + exit; + end; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + if (bits_left < HUFF_LOOKAHEAD) then + begin + nb := 1; + goto label1; + end; + end; + {look := PEEK_BITS(HUFF_LOOKAHEAD);} + look := int(get_buffer shr (bits_left - HUFF_LOOKAHEAD)) and + pred(1 shl HUFF_LOOKAHEAD); + + nb := tbl^.look_nbits[look]; + if (nb <> 0) then + begin + {DROP_BITS(nb);} + Dec(bits_left, nb); + + s := tbl^.look_sym[look]; + end + else + begin + nb := HUFF_LOOKAHEAD+1; + label1: + s := jpeg_huff_decode(br_state,get_buffer,bits_left,tbl,nb); + if (s < 0) then + begin + decode_mcu_DC_first := FALSE; + exit; + end; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + end; + + if (s <> 0) then + begin + {CHECK_BIT_BUFFER(br_state, s, return FALSE);} + if (bits_left < s) then + begin + if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left,s)) then + begin + decode_mcu_DC_first := FALSE; + exit; + end; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + end; + + {r := GET_BITS(s);} + Dec(bits_left, s); + r := (int(get_buffer shr bits_left)) and ( pred(1 shl s) ); + + {s := HUFF_EXTEND(r, s);} + if (r < extend_test[s]) then + s := r + extend_offset[s] + else + s := r; + end; + + { Convert DC difference to actual value, update last_dc_val } + Inc(s, state.last_dc_val[ci]); + state.last_dc_val[ci] := s; + { Scale and output the DC coefficient (assumes jpeg_natural_order[0]=0) } + block^[0] := JCOEF (s shl Al); + end; + + { Completed MCU, so update state } + {BITREAD_SAVE_STATE(cinfo,entropy^.bitstate);} + cinfo^.src^.next_input_byte := br_state.next_input_byte; + cinfo^.src^.bytes_in_buffer := br_state.bytes_in_buffer; + entropy^.bitstate.get_buffer := get_buffer; + entropy^.bitstate.bits_left := bits_left; + + {ASSIGN_STATE(entropy^.saved, state);} + entropy^.saved := state; + end; + + { Account for restart interval (no-op if not using restarts) } + Dec(entropy^.restarts_to_go); + + decode_mcu_DC_first := TRUE; +end; + + +{ MCU decoding for AC initial scan (either spectral selection, + or first pass of successive approximation). } + +{METHODDEF} +function decode_mcu_AC_first (cinfo : j_decompress_ptr; + var MCU_data : array of JBLOCKROW) : boolean; +label + label2; +var + entropy : phuff_entropy_ptr; + Se : int; + Al : int; + {register} s, k, r : int; + EOBRUN : uInt; + block : JBLOCK_PTR; + {BITREAD_STATE_VARS;} + get_buffer : bit_buf_type ; {register} + bits_left : int; {register} + br_state : bitread_working_state; + + tbl : d_derived_tbl_ptr; +var + nb, look : int; {register} +begin + entropy := phuff_entropy_ptr (cinfo^.entropy); + Se := cinfo^.Se; + Al := cinfo^.Al; + + { Process restart marker if needed; may have to suspend } + if (cinfo^.restart_interval <> 0) then + begin + if (entropy^.restarts_to_go = 0) then + if (not process_restart(cinfo)) then + begin + decode_mcu_AC_first := FALSE; + exit; + end; + end; + + { If we've run out of data, just leave the MCU set to zeroes. + This way, we return uniform gray for the remainder of the segment. } + if not entropy^.pub.insufficient_data then + begin + + { Load up working state. + We can avoid loading/saving bitread state if in an EOB run. } + + EOBRUN := entropy^.saved.EOBRUN; { only part of saved state we care about } + + { There is always only one block per MCU } + + if (EOBRUN > 0) then { if it's a band of zeroes... } + Dec(EOBRUN) { ...process it now (we do nothing) } + else + begin + {BITREAD_LOAD_STATE(cinfo,entropy^.bitstate);} + br_state.cinfo := cinfo; + br_state.next_input_byte := cinfo^.src^.next_input_byte; + br_state.bytes_in_buffer := cinfo^.src^.bytes_in_buffer; + get_buffer := entropy^.bitstate.get_buffer; + bits_left := entropy^.bitstate.bits_left; + + block := JBLOCK_PTR(MCU_data[0]); + tbl := entropy^.ac_derived_tbl; + + k := cinfo^.Ss; + while (k <= Se) do + begin + {HUFF_DECODE(s, br_state, tbl, return FALSE, label2);} + if (bits_left < HUFF_LOOKAHEAD) then + begin + if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left, 0)) then + begin + decode_mcu_AC_first := FALSE; + exit; + end; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + if (bits_left < HUFF_LOOKAHEAD) then + begin + nb := 1; + goto label2; + end; + end; + {look := PEEK_BITS(HUFF_LOOKAHEAD);} + look := int(get_buffer shr (bits_left - HUFF_LOOKAHEAD)) and + pred(1 shl HUFF_LOOKAHEAD); + + nb := tbl^.look_nbits[look]; + if (nb <> 0) then + begin + {DROP_BITS(nb);} + Dec(bits_left, nb); + + s := tbl^.look_sym[look]; + end + else + begin + nb := HUFF_LOOKAHEAD+1; + label2: + s := jpeg_huff_decode(br_state,get_buffer,bits_left,tbl,nb); + if (s < 0) then + begin + decode_mcu_AC_first := FALSE; + exit; + end; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + end; + + r := s shr 4; + s := s and 15; + if (s <> 0) then + begin + Inc(k, r); + {CHECK_BIT_BUFFER(br_state, s, return FALSE);} + if (bits_left < s) then + begin + if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left,s)) then + begin + decode_mcu_AC_first := FALSE; + exit; + end; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + end; + + {r := GET_BITS(s);} + Dec(bits_left, s); + r := (int(get_buffer shr bits_left)) and ( pred(1 shl s) ); + + {s := HUFF_EXTEND(r, s);} + if (r < extend_test[s]) then + s := r + extend_offset[s] + else + s := r; + + { Scale and output coefficient in natural (dezigzagged) order } + block^[jpeg_natural_order[k]] := JCOEF (s shl Al); + end + else + begin + if (r = 15) then + begin { ZRL } + Inc(k, 15); { skip 15 zeroes in band } + end + else + begin { EOBr, run length is 2^r + appended bits } + EOBRUN := 1 shl r; + if (r <> 0) then + begin { EOBr, r > 0 } + {CHECK_BIT_BUFFER(br_state, r, return FALSE);} + if (bits_left < r) then + begin + if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left,r)) then + begin + decode_mcu_AC_first := FALSE; + exit; + end; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + end; + + {r := GET_BITS(r);} + Dec(bits_left, r); + r := (int(get_buffer shr bits_left)) and ( pred(1 shl r) ); + + Inc(EOBRUN, r); + end; + Dec(EOBRUN); { this band is processed at this moment } + break; { force end-of-band } + end; + end; + Inc(k); + end; + + {BITREAD_SAVE_STATE(cinfo,entropy^.bitstate);} + cinfo^.src^.next_input_byte := br_state.next_input_byte; + cinfo^.src^.bytes_in_buffer := br_state.bytes_in_buffer; + entropy^.bitstate.get_buffer := get_buffer; + entropy^.bitstate.bits_left := bits_left; + end; + + { Completed MCU, so update state } + entropy^.saved.EOBRUN := EOBRUN; { only part of saved state we care about } + end; + + { Account for restart interval (no-op if not using restarts) } + Dec(entropy^.restarts_to_go); + + decode_mcu_AC_first := TRUE; +end; + + +{ MCU decoding for DC successive approximation refinement scan. + Note: we assume such scans can be multi-component, although the spec + is not very clear on the point. } + +{METHODDEF} +function decode_mcu_DC_refine (cinfo : j_decompress_ptr; + var MCU_data : array of JBLOCKROW) : boolean; + +var + entropy : phuff_entropy_ptr; + p1 : int; { 1 in the bit position being coded } + blkn : int; + block : JBLOCK_PTR; + {BITREAD_STATE_VARS;} + get_buffer : bit_buf_type ; {register} + bits_left : int; {register} + br_state : bitread_working_state; +begin + entropy := phuff_entropy_ptr (cinfo^.entropy); + p1 := 1 shl cinfo^.Al; + + { Process restart marker if needed; may have to suspend } + if (cinfo^.restart_interval <> 0) then + begin + if (entropy^.restarts_to_go = 0) then + if (not process_restart(cinfo)) then + begin + decode_mcu_DC_refine := FALSE; + exit; + end; + end; + + { Not worth the cycles to check insufficient_data here, + since we will not change the data anyway if we read zeroes. } + + { Load up working state } + {BITREAD_LOAD_STATE(cinfo,entropy^.bitstate);} + br_state.cinfo := cinfo; + br_state.next_input_byte := cinfo^.src^.next_input_byte; + br_state.bytes_in_buffer := cinfo^.src^.bytes_in_buffer; + get_buffer := entropy^.bitstate.get_buffer; + bits_left := entropy^.bitstate.bits_left; + + { Outer loop handles each block in the MCU } + + for blkn := 0 to pred(cinfo^.blocks_in_MCU) do + begin + block := JBLOCK_PTR(MCU_data[blkn]); + + { Encoded data is simply the next bit of the two's-complement DC value } + {CHECK_BIT_BUFFER(br_state, 1, return FALSE);} + if (bits_left < 1) then + begin + if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left,1)) then + begin + decode_mcu_DC_refine := FALSE; + exit; + end; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + end; + + {if (GET_BITS(1)) then} + Dec(bits_left); + if (int(get_buffer shr bits_left)) and ( pred(1 shl 1) ) <> 0 then + block^[0] := block^[0] or p1; + { Note: since we use OR, repeating the assignment later is safe } + end; + + { Completed MCU, so update state } + {BITREAD_SAVE_STATE(cinfo,entropy^.bitstate);} + cinfo^.src^.next_input_byte := br_state.next_input_byte; + cinfo^.src^.bytes_in_buffer := br_state.bytes_in_buffer; + entropy^.bitstate.get_buffer := get_buffer; + entropy^.bitstate.bits_left := bits_left; + + { Account for restart interval (no-op if not using restarts) } + Dec(entropy^.restarts_to_go); + + decode_mcu_DC_refine := TRUE; +end; + + +{ MCU decoding for AC successive approximation refinement scan. } + +{METHODDEF} +function decode_mcu_AC_refine (cinfo : j_decompress_ptr; + var MCU_data : array of JBLOCKROW) : boolean; +label + undoit, label3; +var + entropy : phuff_entropy_ptr; + Se : int; + p1 : int; { 1 in the bit position being coded } + m1 : int; { -1 in the bit position being coded } + {register} s, k, r : int; + EOBRUN : uInt; + block : JBLOCK_PTR; + thiscoef : JCOEF_PTR; + {BITREAD_STATE_VARS;} + get_buffer : bit_buf_type ; {register} + bits_left : int; {register} + br_state : bitread_working_state; + + tbl : d_derived_tbl_ptr; + num_newnz : int; + newnz_pos : array[0..DCTSIZE2-1] of int; +var + pos : int; +var + nb, look : int; {register} +begin + entropy := phuff_entropy_ptr (cinfo^.entropy); + Se := cinfo^.Se; + p1 := 1 shl cinfo^.Al; { 1 in the bit position being coded } + m1 := (-1) shl cinfo^.Al; { -1 in the bit position being coded } + + { Process restart marker if needed; may have to suspend } + if (cinfo^.restart_interval <> 0) then + begin + if (entropy^.restarts_to_go = 0) then + if (not process_restart(cinfo)) then + begin + decode_mcu_AC_refine := FALSE; + exit; + end; + end; + + { If we've run out of data, don't modify the MCU. } + if not entropy^.pub.insufficient_data then + begin + + { Load up working state } + {BITREAD_LOAD_STATE(cinfo,entropy^.bitstate);} + br_state.cinfo := cinfo; + br_state.next_input_byte := cinfo^.src^.next_input_byte; + br_state.bytes_in_buffer := cinfo^.src^.bytes_in_buffer; + get_buffer := entropy^.bitstate.get_buffer; + bits_left := entropy^.bitstate.bits_left; + + EOBRUN := entropy^.saved.EOBRUN; { only part of saved state we care about } + + { There is always only one block per MCU } + block := JBLOCK_PTR(MCU_data[0]); + tbl := entropy^.ac_derived_tbl; + + { If we are forced to suspend, we must undo the assignments to any newly + nonzero coefficients in the block, because otherwise we'd get confused + next time about which coefficients were already nonzero. + But we need not undo addition of bits to already-nonzero coefficients; + instead, we can test the current bit position to see if we already did it.} + + num_newnz := 0; + + { initialize coefficient loop counter to start of band } + k := cinfo^.Ss; + + if (EOBRUN = 0) then + begin + while (k <= Se) do + begin + {HUFF_DECODE(s, br_state, tbl, goto undoit, label3);} + if (bits_left < HUFF_LOOKAHEAD) then + begin + if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left, 0)) then + goto undoit; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + if (bits_left < HUFF_LOOKAHEAD) then + begin + nb := 1; + goto label3; + end; + end; + {look := PEEK_BITS(HUFF_LOOKAHEAD);} + look := int(get_buffer shr (bits_left - HUFF_LOOKAHEAD)) and + pred(1 shl HUFF_LOOKAHEAD); + + nb := tbl^.look_nbits[look]; + if (nb <> 0) then + begin + {DROP_BITS(nb);} + Dec(bits_left, nb); + + s := tbl^.look_sym[look]; + end + else + begin + nb := HUFF_LOOKAHEAD+1; + label3: + s := jpeg_huff_decode(br_state,get_buffer,bits_left,tbl,nb); + if (s < 0) then + goto undoit; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + end; + + r := s shr 4; + s := s and 15; + if (s <> 0) then + begin + if (s <> 1) then { size of new coef should always be 1 } + WARNMS(j_common_ptr(cinfo), JWRN_HUFF_BAD_CODE); + {CHECK_BIT_BUFFER(br_state, 1, goto undoit);} + if (bits_left < 1) then + begin + if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left,1)) then + goto undoit; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + end; + + {if (GET_BITS(1)) then} + Dec(bits_left); + if (int(get_buffer shr bits_left)) and ( pred(1 shl 1) )<>0 then + s := p1 { newly nonzero coef is positive } + else + s := m1; { newly nonzero coef is negative } + end + else + begin + if (r <> 15) then + begin + EOBRUN := 1 shl r; { EOBr, run length is 2^r + appended bits } + if (r <> 0) then + begin + {CHECK_BIT_BUFFER(br_state, r, goto undoit);} + if (bits_left < r) then + begin + if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left,r)) then + goto undoit; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + end; + + {r := GET_BITS(r);} + Dec(bits_left, r); + r := (int(get_buffer shr bits_left)) and ( pred(1 shl r) ); + + Inc(EOBRUN, r); + end; + break; { rest of block is handled by EOB logic } + end; + { note s := 0 for processing ZRL } + end; + { Advance over already-nonzero coefs and r still-zero coefs, + appending correction bits to the nonzeroes. A correction bit is 1 + if the absolute value of the coefficient must be increased. } + + repeat + thiscoef :=@(block^[jpeg_natural_order[k]]); + if (thiscoef^ <> 0) then + begin + {CHECK_BIT_BUFFER(br_state, 1, goto undoit);} + if (bits_left < 1) then + begin + if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left,1)) then + goto undoit; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + end; + + {if (GET_BITS(1)) then} + Dec(bits_left); + if (int(get_buffer shr bits_left)) and ( pred(1 shl 1) )<>0 then + begin + if ((thiscoef^ and p1) = 0) then + begin { do nothing if already set it } + if (thiscoef^ >= 0) then + Inc(thiscoef^, p1) + else + Inc(thiscoef^, m1); + end; + end; + end + else + begin + Dec(r); + if (r < 0) then + break; { reached target zero coefficient } + end; + Inc(k); + until (k > Se); + if (s <> 0) then + begin + pos := jpeg_natural_order[k]; + { Output newly nonzero coefficient } + block^[pos] := JCOEF (s); + { Remember its position in case we have to suspend } + newnz_pos[num_newnz] := pos; + Inc(num_newnz); + end; + Inc(k); + end; + end; + + if (EOBRUN > 0) then + begin + { Scan any remaining coefficient positions after the end-of-band + (the last newly nonzero coefficient, if any). Append a correction + bit to each already-nonzero coefficient. A correction bit is 1 + if the absolute value of the coefficient must be increased. } + + while (k <= Se) do + begin + thiscoef := @(block^[jpeg_natural_order[k]]); + if (thiscoef^ <> 0) then + begin + {CHECK_BIT_BUFFER(br_state, 1, goto undoit);} + if (bits_left < 1) then + begin + if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left,1)) then + goto undoit; + get_buffer := br_state.get_buffer; + bits_left := br_state.bits_left; + end; + + {if (GET_BITS(1)) then} + Dec(bits_left); + if (int(get_buffer shr bits_left)) and ( pred(1 shl 1) )<>0 then + begin + if ((thiscoef^ and p1) = 0) then + begin { do nothing if already changed it } + if (thiscoef^ >= 0) then + Inc(thiscoef^, p1) + else + Inc(thiscoef^, m1); + end; + end; + end; + Inc(k); + end; + { Count one block completed in EOB run } + Dec(EOBRUN); + end; + + { Completed MCU, so update state } + {BITREAD_SAVE_STATE(cinfo,entropy^.bitstate);} + cinfo^.src^.next_input_byte := br_state.next_input_byte; + cinfo^.src^.bytes_in_buffer := br_state.bytes_in_buffer; + entropy^.bitstate.get_buffer := get_buffer; + entropy^.bitstate.bits_left := bits_left; + + entropy^.saved.EOBRUN := EOBRUN; { only part of saved state we care about } + end; + + { Account for restart interval (no-op if not using restarts) } + Dec(entropy^.restarts_to_go); + + decode_mcu_AC_refine := TRUE; + exit; + +undoit: + { Re-zero any output coefficients that we made newly nonzero } + while (num_newnz > 0) do + begin + Dec(num_newnz); +{$warnings off} + block^[newnz_pos[num_newnz]] := 0; + end; + + decode_mcu_AC_refine := FALSE; +end; +{$warnings on} + +{ Module initialization routine for progressive Huffman entropy decoding. } + +{GLOBAL} +procedure jinit_phuff_decoder (cinfo : j_decompress_ptr); +var + entropy : phuff_entropy_ptr; + coef_bit_ptr : int_ptr; + ci, i : int; +begin + entropy := phuff_entropy_ptr( + cinfo^.mem^.alloc_small (j_common_ptr (cinfo), JPOOL_IMAGE, + SIZEOF(phuff_entropy_decoder)) ); + cinfo^.entropy := jpeg_entropy_decoder_ptr (entropy); + entropy^.pub.start_pass := start_pass_phuff_decoder; + + { Mark derived tables unallocated } + for i := 0 to pred(NUM_HUFF_TBLS) do + begin + entropy^.derived_tbls[i] := NIL; + end; + + { Create progression status table } + cinfo^.coef_bits := coef_bits_ptrrow ( + cinfo^.mem^.alloc_small ( j_common_ptr (cinfo), JPOOL_IMAGE, + cinfo^.num_components*DCTSIZE2*SIZEOF(int)) ); + coef_bit_ptr := @cinfo^.coef_bits^[0][0]; + for ci := 0 to pred(cinfo^.num_components) do + for i := 0 to pred(DCTSIZE2) do + begin + coef_bit_ptr^ := -1; + Inc(coef_bit_ptr); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jdpostct_del.pas b/mseide-msegui/lib/common/fpccompatibility/jdpostct_del.pas new file mode 100644 index 0000000..338479c --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jdpostct_del.pas @@ -0,0 +1,343 @@ +unit jdpostct_del; + +{ Original: jdpostct.c ; Copyright (C) 1994-1996, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +{ This file contains the decompression postprocessing controller. + This controller manages the upsampling, color conversion, and color + quantization/reduction steps; specifically, it controls the buffering + between upsample/color conversion and color quantization/reduction. + + If no color quantization/reduction is required, then this module has no + work to do, and it just hands off to the upsample/color conversion code. + An integrated upsample/convert/quantize process would replace this module + entirely. } + +{$I jconfig_del.inc} + +interface + +uses + jmorecfg_del, + jinclude_del, + jdeferr_del, + jerror_del, + jutils_del, + jpeglib_del; + + +{ Initialize postprocessing controller. } + +{GLOBAL} +procedure jinit_d_post_controller (cinfo : j_decompress_ptr; + need_full_buffer : boolean); +implementation + + +{ Private buffer controller object } + +type + my_post_ptr = ^my_post_controller; + my_post_controller = record + pub : jpeg_d_post_controller; { public fields } + + { Color quantization source buffer: this holds output data from + the upsample/color conversion step to be passed to the quantizer. + For two-pass color quantization, we need a full-image buffer; + for one-pass operation, a strip buffer is sufficient. } + + whole_image : jvirt_sarray_ptr; { virtual array, or NIL if one-pass } + buffer : JSAMPARRAY; { strip buffer, or current strip of virtual } + strip_height : JDIMENSION; { buffer size in rows } + { for two-pass mode only: } + starting_row : JDIMENSION; { row # of first row in current strip } + next_row : JDIMENSION; { index of next row to fill/empty in strip } + end; + +{ Forward declarations } +{METHODDEF} +procedure post_process_1pass(cinfo : j_decompress_ptr; + input_buf : JSAMPIMAGE; + var in_row_group_ctr : JDIMENSION; + in_row_groups_avail : JDIMENSION; + output_buf : JSAMPARRAY; + var out_row_ctr : JDIMENSION; + out_rows_avail : JDIMENSION); forward; +{$ifdef QUANT_2PASS_SUPPORTED} +{METHODDEF} +procedure post_process_prepass(cinfo : j_decompress_ptr; + input_buf : JSAMPIMAGE; + var in_row_group_ctr : JDIMENSION; + in_row_groups_avail : JDIMENSION; + output_buf : JSAMPARRAY; + var out_row_ctr : JDIMENSION; + out_rows_avail : JDIMENSION); forward; +{METHODDEF} +procedure post_process_2pass(cinfo : j_decompress_ptr; + input_buf : JSAMPIMAGE; + var in_row_group_ctr : JDIMENSION; + in_row_groups_avail : JDIMENSION; + output_buf : JSAMPARRAY; + var out_row_ctr : JDIMENSION; + out_rows_avail : JDIMENSION); forward; +{$endif} + + +{ Initialize for a processing pass. } + +{METHODDEF} +procedure start_pass_dpost (cinfo : j_decompress_ptr; + pass_mode : J_BUF_MODE); +var + post : my_post_ptr; +begin + post := my_post_ptr(cinfo^.post); + + case (pass_mode) of + JBUF_PASS_THRU: + if (cinfo^.quantize_colors) then + begin + { Single-pass processing with color quantization. } + post^.pub.post_process_data := post_process_1pass; + { We could be doing buffered-image output before starting a 2-pass + color quantization; in that case, jinit_d_post_controller did not + allocate a strip buffer. Use the virtual-array buffer as workspace. } + if (post^.buffer = NIL) then + begin + post^.buffer := cinfo^.mem^.access_virt_sarray + (j_common_ptr(cinfo), post^.whole_image, + JDIMENSION(0), post^.strip_height, TRUE); + end; + end + else + begin + { For single-pass processing without color quantization, + I have no work to do; just call the upsampler directly. } + + post^.pub.post_process_data := cinfo^.upsample^.upsample; + end; + +{$ifdef QUANT_2PASS_SUPPORTED} + JBUF_SAVE_AND_PASS: + begin + { First pass of 2-pass quantization } + if (post^.whole_image = NIL) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE); + post^.pub.post_process_data := post_process_prepass; + end; + JBUF_CRANK_DEST: + begin + { Second pass of 2-pass quantization } + if (post^.whole_image = NIL) then + ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE); + post^.pub.post_process_data := post_process_2pass; + end; +{$endif} { QUANT_2PASS_SUPPORTED } + else + ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE); + end; + post^.next_row := 0; + post^.starting_row := 0; +end; + + +{ Process some data in the one-pass (strip buffer) case. + This is used for color precision reduction as well as one-pass quantization. } + +{METHODDEF} +procedure post_process_1pass (cinfo : j_decompress_ptr; + input_buf : JSAMPIMAGE; + var in_row_group_ctr : JDIMENSION; + in_row_groups_avail : JDIMENSION; + output_buf : JSAMPARRAY; + var out_row_ctr : JDIMENSION; + out_rows_avail : JDIMENSION); +var + post : my_post_ptr; + num_rows, max_rows : JDIMENSION; +begin + post := my_post_ptr (cinfo^.post); + + { Fill the buffer, but not more than what we can dump out in one go. } + { Note we rely on the upsampler to detect bottom of image. } + max_rows := out_rows_avail - out_row_ctr; + if (max_rows > post^.strip_height) then + max_rows := post^.strip_height; + num_rows := 0; + cinfo^.upsample^.upsample (cinfo, + input_buf, + in_row_group_ctr, + in_row_groups_avail, + post^.buffer, + num_rows, { var } + max_rows); + { Quantize and emit data. } + + cinfo^.cquantize^.color_quantize (cinfo, + post^.buffer, + JSAMPARRAY(@ output_buf^[out_row_ctr]), + int(num_rows)); + + Inc(out_row_ctr, num_rows); +end; + + +{$ifdef QUANT_2PASS_SUPPORTED} + +{ Process some data in the first pass of 2-pass quantization. } + +{METHODDEF} +procedure post_process_prepass (cinfo : j_decompress_ptr; + input_buf : JSAMPIMAGE; + var in_row_group_ctr : JDIMENSION; + in_row_groups_avail : JDIMENSION; + output_buf : JSAMPARRAY; + var out_row_ctr : JDIMENSION; + out_rows_avail:JDIMENSION); +var + post : my_post_ptr; + old_next_row, num_rows : JDIMENSION; +begin + post := my_post_ptr(cinfo^.post); + + { Reposition virtual buffer if at start of strip. } + if (post^.next_row = 0) then + begin + post^.buffer := cinfo^.mem^.access_virt_sarray + (j_common_ptr(cinfo), post^.whole_image, + post^.starting_row, post^.strip_height, TRUE); + end; + + { Upsample some data (up to a strip height's worth). } + old_next_row := post^.next_row; + cinfo^.upsample^.upsample (cinfo, + input_buf, in_row_group_ctr, in_row_groups_avail, + post^.buffer, post^.next_row, post^.strip_height); + + { Allow quantizer to scan new data. No data is emitted, } + { but we advance out_row_ctr so outer loop can tell when we're done. } + if (post^.next_row > old_next_row) then + begin + num_rows := post^.next_row - old_next_row; + + + cinfo^.cquantize^.color_quantize (cinfo, + JSAMPARRAY(@ post^.buffer^[old_next_row]), + JSAMPARRAY(NIL), + int(num_rows)); + Inc(out_row_ctr, num_rows); + end; + + { Advance if we filled the strip. } + if (post^.next_row >= post^.strip_height) then + begin + Inc(post^.starting_row, post^.strip_height); + post^.next_row := 0; + end; +end; + + +{ Process some data in the second pass of 2-pass quantization. } + +{METHODDEF} +procedure post_process_2pass (cinfo : j_decompress_ptr; + input_buf : JSAMPIMAGE; + var in_row_group_ctr : JDIMENSION; + in_row_groups_avail : JDIMENSION; + output_buf : JSAMPARRAY; + var out_row_ctr : JDIMENSION; + out_rows_avail : JDIMENSION); +var + post : my_post_ptr; + num_rows, max_rows : JDIMENSION; +begin + post := my_post_ptr(cinfo^.post); + + { Reposition virtual buffer if at start of strip. } + if (post^.next_row = 0) then + begin + post^.buffer := cinfo^.mem^.access_virt_sarray + (j_common_ptr(cinfo), post^.whole_image, + post^.starting_row, post^.strip_height, FALSE); + end; + + { Determine number of rows to emit. } + num_rows := post^.strip_height - post^.next_row; { available in strip } + max_rows := out_rows_avail - out_row_ctr; { available in output area } + if (num_rows > max_rows) then + num_rows := max_rows; + { We have to check bottom of image here, can't depend on upsampler. } + max_rows := cinfo^.output_height - post^.starting_row; + if (num_rows > max_rows) then + num_rows := max_rows; + + { Quantize and emit data. } + cinfo^.cquantize^.color_quantize (cinfo, + JSAMPARRAY(@ post^.buffer^[post^.next_row]), + JSAMPARRAY(@ output_buf^[out_row_ctr]), + int(num_rows)); + Inc(out_row_ctr, num_rows); + + { Advance if we filled the strip. } + Inc(post^.next_row, num_rows); + if (post^.next_row >= post^.strip_height) then + begin + Inc(post^.starting_row, post^.strip_height); + post^.next_row := 0; + end; +end; + +{$endif} { QUANT_2PASS_SUPPORTED } + + +{ Initialize postprocessing controller. } + +{GLOBAL} +procedure jinit_d_post_controller (cinfo : j_decompress_ptr; + need_full_buffer : boolean); +var + post : my_post_ptr; +begin + post := my_post_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(my_post_controller)) ); + cinfo^.post := jpeg_d_post_controller_ptr (post); + post^.pub.start_pass := start_pass_dpost; + post^.whole_image := NIL; { flag for no virtual arrays } + post^.buffer := NIL; { flag for no strip buffer } + + { Create the quantization buffer, if needed } + if (cinfo^.quantize_colors) then + begin + { The buffer strip height is max_v_samp_factor, which is typically + an efficient number of rows for upsampling to return. + (In the presence of output rescaling, we might want to be smarter?) } + + post^.strip_height := JDIMENSION (cinfo^.max_v_samp_factor); + if (need_full_buffer) then + begin + { Two-pass color quantization: need full-image storage. } + { We round up the number of rows to a multiple of the strip height. } +{$ifdef QUANT_2PASS_SUPPORTED} + post^.whole_image := cinfo^.mem^.request_virt_sarray + (j_common_ptr(cinfo), JPOOL_IMAGE, FALSE, + cinfo^.output_width * cinfo^.out_color_components, + JDIMENSION (jround_up( long(cinfo^.output_height), + long(post^.strip_height)) ), + post^.strip_height); +{$else} + ERREXIT(j_common_ptr(cinfo), JERR_BAD_BUFFER_MODE); +{$endif} { QUANT_2PASS_SUPPORTED } + end + else + begin + { One-pass color quantization: just make a strip buffer. } + post^.buffer := cinfo^.mem^.alloc_sarray + (j_common_ptr (cinfo), JPOOL_IMAGE, + cinfo^.output_width * cinfo^.out_color_components, + post^.strip_height); + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jdsample_del.pas b/mseide-msegui/lib/common/fpccompatibility/jdsample_del.pas new file mode 100644 index 0000000..f6bbc6b --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jdsample_del.pas @@ -0,0 +1,593 @@ +unit jdsample_del; + +{ Original: jdsample.c; Copyright (C) 1991-1996, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +{ This file contains upsampling routines. + + Upsampling input data is counted in "row groups". A row group + is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size) + sample rows of each component. Upsampling will normally produce + max_v_samp_factor pixel rows from each row group (but this could vary + if the upsampler is applying a scale factor of its own). + + An excellent reference for image resampling is + Digital Image Warping, George Wolberg, 1990. + Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7.} + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jutils_del, + jpeglib_del, + jdeferr_del, + jerror_del; + + +{ Pointer to routine to upsample a single component } +type + upsample1_ptr = procedure (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + input_data : JSAMPARRAY; + var output_data_ptr : JSAMPARRAY); + +{ Module initialization routine for upsampling. } + +{GLOBAL} +procedure jinit_upsampler (cinfo : j_decompress_ptr); + +implementation + +{ Private subobject } + +type + my_upsample_ptr = ^my_upsampler; + my_upsampler = record + pub : jpeg_upsampler; { public fields } + + { Color conversion buffer. When using separate upsampling and color + conversion steps, this buffer holds one upsampled row group until it + has been color converted and output. + Note: we do not allocate any storage for component(s) which are full-size, + ie do not need rescaling. The corresponding entry of color_buf[] is + simply set to point to the input data array, thereby avoiding copying.} + + color_buf : array[0..MAX_COMPONENTS-1] of JSAMPARRAY; + + { Per-component upsampling method pointers } + methods : array[0..MAX_COMPONENTS-1] of upsample1_ptr; + + next_row_out : int; { counts rows emitted from color_buf } + rows_to_go : JDIMENSION; { counts rows remaining in image } + + { Height of an input row group for each component. } + rowgroup_height : array[0..MAX_COMPONENTS-1] of int; + + { These arrays save pixel expansion factors so that int_expand need not + recompute them each time. They are unused for other upsampling methods.} + h_expand : array[0..MAX_COMPONENTS-1] of UINT8 ; + v_expand : array[0..MAX_COMPONENTS-1] of UINT8 ; + end; + + +{ Initialize for an upsampling pass. } + +{METHODDEF} +procedure start_pass_upsample (cinfo : j_decompress_ptr); +var + upsample : my_upsample_ptr; +begin + upsample := my_upsample_ptr (cinfo^.upsample); + + { Mark the conversion buffer empty } + upsample^.next_row_out := cinfo^.max_v_samp_factor; + { Initialize total-height counter for detecting bottom of image } + upsample^.rows_to_go := cinfo^.output_height; +end; + + +{ Control routine to do upsampling (and color conversion). + + In this version we upsample each component independently. + We upsample one row group into the conversion buffer, then apply + color conversion a row at a time. } + +{METHODDEF} +procedure sep_upsample (cinfo : j_decompress_ptr; + input_buf : JSAMPIMAGE; + var in_row_group_ctr : JDIMENSION; + in_row_groups_avail : JDIMENSION; + output_buf : JSAMPARRAY; + var out_row_ctr : JDIMENSION; + out_rows_avail : JDIMENSION); +var + upsample : my_upsample_ptr; + ci : int; + compptr : jpeg_component_info_ptr; + num_rows : JDIMENSION; +begin + upsample := my_upsample_ptr (cinfo^.upsample); + + { Fill the conversion buffer, if it's empty } + if (upsample^.next_row_out >= cinfo^.max_v_samp_factor) then + begin + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + { Invoke per-component upsample method. Notice we pass a POINTER + to color_buf[ci], so that fullsize_upsample can change it. } + + upsample^.methods[ci] (cinfo, compptr, + JSAMPARRAY(@ input_buf^[ci]^ + [in_row_group_ctr * upsample^.rowgroup_height[ci]]), + upsample^.color_buf[ci]); + + Inc(compptr); + end; + upsample^.next_row_out := 0; + end; + + { Color-convert and emit rows } + + { How many we have in the buffer: } + num_rows := JDIMENSION (cinfo^.max_v_samp_factor - upsample^.next_row_out); + { Not more than the distance to the end of the image. Need this test + in case the image height is not a multiple of max_v_samp_factor: } + + if (num_rows > upsample^.rows_to_go) then + num_rows := upsample^.rows_to_go; + { And not more than what the client can accept: } + Dec(out_rows_avail, out_row_ctr); + if (num_rows > out_rows_avail) then + num_rows := out_rows_avail; + + cinfo^.cconvert^.color_convert (cinfo, + JSAMPIMAGE(@(upsample^.color_buf)), + JDIMENSION (upsample^.next_row_out), + JSAMPARRAY(@(output_buf^[out_row_ctr])), + int (num_rows)); + + { Adjust counts } + Inc(out_row_ctr, num_rows); + Dec(upsample^.rows_to_go, num_rows); + Inc(upsample^.next_row_out, num_rows); + { When the buffer is emptied, declare this input row group consumed } + if (upsample^.next_row_out >= cinfo^.max_v_samp_factor) then + Inc(in_row_group_ctr); +end; + + +{ These are the routines invoked by sep_upsample to upsample pixel values + of a single component. One row group is processed per call. } + + +{ For full-size components, we just make color_buf[ci] point at the + input buffer, and thus avoid copying any data. Note that this is + safe only because sep_upsample doesn't declare the input row group + "consumed" until we are done color converting and emitting it. } + +{METHODDEF} +procedure fullsize_upsample (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + input_data : JSAMPARRAY; + var output_data_ptr : JSAMPARRAY); +begin + output_data_ptr := input_data; +end; + + +{ This is a no-op version used for "uninteresting" components. + These components will not be referenced by color conversion. } + +{METHODDEF} +procedure noop_upsample (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + input_data : JSAMPARRAY; + var output_data_ptr : JSAMPARRAY); +begin + output_data_ptr := NIL; { safety check } +end; + + +{ This version handles any integral sampling ratios. + This is not used for typical JPEG files, so it need not be fast. + Nor, for that matter, is it particularly accurate: the algorithm is + simple replication of the input pixel onto the corresponding output + pixels. The hi-falutin sampling literature refers to this as a + "box filter". A box filter tends to introduce visible artifacts, + so if you are actually going to use 3:1 or 4:1 sampling ratios + you would be well advised to improve this code. } + +{METHODDEF} +procedure int_upsample (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + input_data : JSAMPARRAY; + var output_data_ptr : JSAMPARRAY); +var + upsample : my_upsample_ptr; + output_data : JSAMPARRAY; + {register} inptr, outptr : JSAMPLE_PTR; + {register} invalue : JSAMPLE; + {register} h : int; + {outend} + h_expand, v_expand : int; + inrow, outrow : int; +var + outcount : int; { Nomssi: avoid pointer arithmetic } +begin + upsample := my_upsample_ptr (cinfo^.upsample); + output_data := output_data_ptr; + + h_expand := upsample^.h_expand[compptr^.component_index]; + v_expand := upsample^.v_expand[compptr^.component_index]; + + inrow := 0; + outrow := 0; + while (outrow < cinfo^.max_v_samp_factor) do + begin + { Generate one output row with proper horizontal expansion } + inptr := JSAMPLE_PTR(input_data^[inrow]); + outptr := JSAMPLE_PTR(output_data^[outrow]); + outcount := cinfo^.output_width; + while (outcount > 0) do { Nomssi } + begin + invalue := inptr^; { don't need GETJSAMPLE() here } + Inc(inptr); + for h := pred(h_expand) downto 0 do + begin + outptr^ := invalue; + inc(outptr); { <-- fix: this was left out in PasJpeg 1.0 } + Dec(outcount); { thanks to Jannie Gerber for the report } + end; + end; + + { Generate any additional output rows by duplicating the first one } + if (v_expand > 1) then + begin + jcopy_sample_rows(output_data, outrow, output_data, outrow+1, + v_expand-1, cinfo^.output_width); + end; + Inc(inrow); + Inc(outrow, v_expand); + end; +end; + + +{ Fast processing for the common case of 2:1 horizontal and 1:1 vertical. + It's still a box filter. } + +{METHODDEF} +procedure h2v1_upsample (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + input_data : JSAMPARRAY; + var output_data_ptr : JSAMPARRAY); +var + output_data : JSAMPARRAY; + {register} inptr, outptr : JSAMPLE_PTR; + {register} invalue : JSAMPLE; + {outend : JSAMPROW;} + outcount : int; + inrow : int; +begin + output_data := output_data_ptr; + + for inrow := 0 to pred(cinfo^.max_v_samp_factor) do + begin + inptr := JSAMPLE_PTR(input_data^[inrow]); + outptr := JSAMPLE_PTR(output_data^[inrow]); + {outend := outptr + cinfo^.output_width;} + outcount := cinfo^.output_width; + while (outcount > 0) do + begin + invalue := inptr^; { don't need GETJSAMPLE() here } + Inc(inptr); + outptr^ := invalue; + Inc(outptr); + outptr^ := invalue; + Inc(outptr); + Dec(outcount, 2); { Nomssi: to avoid pointer arithmetic } + end; + end; +end; + + +{ Fast processing for the common case of 2:1 horizontal and 2:1 vertical. + It's still a box filter. } + +{METHODDEF} +procedure h2v2_upsample (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + input_data : JSAMPARRAY; + var output_data_ptr : JSAMPARRAY); +var + output_data : JSAMPARRAY; + {register} inptr, outptr : JSAMPLE_PTR; + {register} invalue : JSAMPLE; + {outend : JSAMPROW;} + outcount : int; + inrow, outrow : int; +begin + output_data := output_data_ptr; + + inrow := 0; + outrow := 0; + while (outrow < cinfo^.max_v_samp_factor) do + begin + inptr := JSAMPLE_PTR(input_data^[inrow]); + outptr := JSAMPLE_PTR(output_data^[outrow]); + {outend := outptr + cinfo^.output_width;} + outcount := cinfo^.output_width; + while (outcount > 0) do + begin + invalue := inptr^; { don't need GETJSAMPLE() here } + Inc(inptr); + outptr^ := invalue; + Inc(outptr); + outptr^ := invalue; + Inc(outptr); + Dec(outcount, 2); + end; + jcopy_sample_rows(output_data, outrow, output_data, outrow+1, + 1, cinfo^.output_width); + Inc(inrow); + Inc(outrow, 2); + end; +end; + + +{ Fancy processing for the common case of 2:1 horizontal and 1:1 vertical. + + The upsampling algorithm is linear interpolation between pixel centers, + also known as a "triangle filter". This is a good compromise between + speed and visual quality. The centers of the output pixels are 1/4 and 3/4 + of the way between input pixel centers. + + A note about the "bias" calculations: when rounding fractional values to + integer, we do not want to always round 0.5 up to the next integer. + If we did that, we'd introduce a noticeable bias towards larger values. + Instead, this code is arranged so that 0.5 will be rounded up or down at + alternate pixel locations (a simple ordered dither pattern). } + +{METHODDEF} +procedure h2v1_fancy_upsample (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + input_data : JSAMPARRAY; + var output_data_ptr : JSAMPARRAY); +var + output_data : JSAMPARRAY; + {register} pre_inptr, inptr, outptr : JSAMPLE_PTR; + {register} invalue : int; + {register} colctr : JDIMENSION; + inrow : int; +begin + output_data := output_data_ptr; + + for inrow := 0 to pred(cinfo^.max_v_samp_factor) do + begin + inptr := JSAMPLE_PTR(input_data^[inrow]); + outptr := JSAMPLE_PTR(output_data^[inrow]); + { Special case for first column } + pre_inptr := inptr; + invalue := GETJSAMPLE(inptr^); + Inc(inptr); + outptr^ := JSAMPLE (invalue); + Inc(outptr); + outptr^ := JSAMPLE ((invalue * 3 + GETJSAMPLE(inptr^) + 2) shr 2); + Inc(outptr); + + for colctr := pred(compptr^.downsampled_width - 2) downto 0 do + begin + { General case: 3/4 * nearer pixel + 1/4 * further pixel } + invalue := GETJSAMPLE(inptr^) * 3; + Inc(inptr); + outptr^ := JSAMPLE ((invalue + GETJSAMPLE(pre_inptr^) + 1) shr 2); + Inc(pre_inptr); + Inc(outptr); + outptr^ := JSAMPLE ((invalue + GETJSAMPLE(inptr^) + 2) shr 2); + Inc(outptr); + end; + + { Special case for last column } + invalue := GETJSAMPLE(inptr^); + outptr^ := JSAMPLE ((invalue * 3 + GETJSAMPLE(pre_inptr^) + 1) shr 2); + Inc(outptr); + outptr^ := JSAMPLE (invalue); + {Inc(outptr); - value never used } + end; +end; + + +{ Fancy processing for the common case of 2:1 horizontal and 2:1 vertical. + Again a triangle filter; see comments for h2v1 case, above. + + It is OK for us to reference the adjacent input rows because we demanded + context from the main buffer controller (see initialization code). } + +{METHODDEF} +procedure h2v2_fancy_upsample (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + input_data : JSAMPARRAY; + var output_data_ptr : JSAMPARRAY); +var + output_data : JSAMPARRAY; + {register} inptr0, inptr1, outptr : JSAMPLE_PTR; +{$ifdef BITS_IN_JSAMPLE_IS_8} + {register} thiscolsum, lastcolsum, nextcolsum : int; +{$else} + {register} thiscolsum, lastcolsum, nextcolsum : INT32; +{$endif} + {register} colctr : JDIMENSION; + inrow, outrow, v : int; +var + prev_input_data : JSAMPARRAY; { Nomssi work around } +begin + output_data := output_data_ptr; + + outrow := 0; + inrow := 0; + while (outrow < cinfo^.max_v_samp_factor) do + begin + for v := 0 to pred(2) do + begin + { inptr0 points to nearest input row, inptr1 points to next nearest } + inptr0 := JSAMPLE_PTR(input_data^[inrow]); + if (v = 0) then { next nearest is row above } + begin + {inptr1 := JSAMPLE_PTR(input_data^[inrow-1]);} + prev_input_data := input_data; { work around } + Dec(JSAMPROW_PTR(prev_input_data)); { negative offsets } + inptr1 := JSAMPLE_PTR(prev_input_data^[inrow]); + end + else { next nearest is row below } + inptr1 := JSAMPLE_PTR(input_data^[inrow+1]); + outptr := JSAMPLE_PTR(output_data^[outrow]); + Inc(outrow); + + { Special case for first column } + thiscolsum := GETJSAMPLE(inptr0^) * 3 + GETJSAMPLE(inptr1^); + Inc(inptr0); + Inc(inptr1); + nextcolsum := GETJSAMPLE(inptr0^) * 3 + GETJSAMPLE(inptr1^); + Inc(inptr0); + Inc(inptr1); + + outptr^ := JSAMPLE ((thiscolsum * 4 + 8) shr 4); + Inc(outptr); + outptr^ := JSAMPLE ((thiscolsum * 3 + nextcolsum + 7) shr 4); + Inc(outptr); + lastcolsum := thiscolsum; thiscolsum := nextcolsum; + + for colctr := pred(compptr^.downsampled_width - 2) downto 0 do + begin + { General case: 3/4 * nearer pixel + 1/4 * further pixel in each } + { dimension, thus 9/16, 3/16, 3/16, 1/16 overall } + nextcolsum := GETJSAMPLE(inptr0^) * 3 + GETJSAMPLE(inptr1^); + Inc(inptr0); + Inc(inptr1); + outptr^ := JSAMPLE ((thiscolsum * 3 + lastcolsum + 8) shr 4); + Inc(outptr); + outptr^ := JSAMPLE ((thiscolsum * 3 + nextcolsum + 7) shr 4); + Inc(outptr); + lastcolsum := thiscolsum; + thiscolsum := nextcolsum; + end; + + { Special case for last column } + outptr^ := JSAMPLE ((thiscolsum * 3 + lastcolsum + 8) shr 4); + Inc(outptr); + outptr^ := JSAMPLE ((thiscolsum * 4 + 7) shr 4); + {Inc(outptr); - value never used } + end; + Inc(inrow); + end; +end; + + +{ Module initialization routine for upsampling. } + +{GLOBAL} +procedure jinit_upsampler (cinfo : j_decompress_ptr); +var + upsample : my_upsample_ptr; + ci : int; + compptr : jpeg_component_info_ptr; + need_buffer, do_fancy : boolean; + h_in_group, v_in_group, h_out_group, v_out_group : int; +begin + upsample := my_upsample_ptr ( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(my_upsampler)) ); + cinfo^.upsample := jpeg_upsampler_ptr (upsample); + upsample^.pub.start_pass := start_pass_upsample; + upsample^.pub.upsample := sep_upsample; + upsample^.pub.need_context_rows := FALSE; { until we find out differently } + + if (cinfo^.CCIR601_sampling) then { this isn't supported } + ERREXIT(j_common_ptr(cinfo), JERR_CCIR601_NOTIMPL); + + { jdmainct.c doesn't support context rows when min_DCT_scaled_size := 1, + so don't ask for it. } + + do_fancy := cinfo^.do_fancy_upsampling and (cinfo^.min_DCT_scaled_size > 1); + + { Verify we can handle the sampling factors, select per-component methods, + and create storage as needed. } + + compptr := jpeg_component_info_ptr(cinfo^.comp_info); + for ci := 0 to pred(cinfo^.num_components) do + begin + { Compute size of an "input group" after IDCT scaling. This many samples + are to be converted to max_h_samp_factor * max_v_samp_factor pixels. } + + h_in_group := (compptr^.h_samp_factor * compptr^.DCT_scaled_size) div + cinfo^.min_DCT_scaled_size; + v_in_group := (compptr^.v_samp_factor * compptr^.DCT_scaled_size) div + cinfo^.min_DCT_scaled_size; + h_out_group := cinfo^.max_h_samp_factor; + v_out_group := cinfo^.max_v_samp_factor; + upsample^.rowgroup_height[ci] := v_in_group; { save for use later } + need_buffer := TRUE; + if (not compptr^.component_needed) then + begin + { Don't bother to upsample an uninteresting component. } + upsample^.methods[ci] := noop_upsample; + need_buffer := FALSE; + end + else + if (h_in_group = h_out_group) and (v_in_group = v_out_group) then + begin + { Fullsize components can be processed without any work. } + upsample^.methods[ci] := fullsize_upsample; + need_buffer := FALSE; + end + else + if (h_in_group * 2 = h_out_group) and + (v_in_group = v_out_group) then + begin + { Special cases for 2h1v upsampling } + if (do_fancy) and (compptr^.downsampled_width > 2) then + upsample^.methods[ci] := h2v1_fancy_upsample + else + upsample^.methods[ci] := h2v1_upsample; + end + else + if (h_in_group * 2 = h_out_group) and + (v_in_group * 2 = v_out_group) then + begin + { Special cases for 2h2v upsampling } + if (do_fancy) and (compptr^.downsampled_width > 2) then + begin + upsample^.methods[ci] := h2v2_fancy_upsample; + upsample^.pub.need_context_rows := TRUE; + end + else + upsample^.methods[ci] := h2v2_upsample; + end + else + if ((h_out_group mod h_in_group) = 0) and + ((v_out_group mod v_in_group) = 0) then + begin + { Generic integral-factors upsampling method } + upsample^.methods[ci] := int_upsample; + upsample^.h_expand[ci] := UINT8 (h_out_group div h_in_group); + upsample^.v_expand[ci] := UINT8 (v_out_group div v_in_group); + end + else + ERREXIT(j_common_ptr(cinfo), JERR_FRACT_SAMPLE_NOTIMPL); + if (need_buffer) then + begin + upsample^.color_buf[ci] := cinfo^.mem^.alloc_sarray + (j_common_ptr(cinfo), JPOOL_IMAGE, + JDIMENSION (jround_up( long (cinfo^.output_width), + long (cinfo^.max_h_samp_factor))), + JDIMENSION (cinfo^.max_v_samp_factor)); + end; + Inc(compptr); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jdtrans_del.pas b/mseide-msegui/lib/common/fpccompatibility/jdtrans_del.pas new file mode 100644 index 0000000..a265257 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jdtrans_del.pas @@ -0,0 +1,192 @@ +Unit JdTrans; + +{ This file contains library routines for transcoding decompression, + that is, reading raw DCT coefficient arrays from an input JPEG file. + The routines in jdapimin.c will also be needed by a transcoder. } + +{ Original : jdtrans.c ; Copyright (C) 1995-1997, Thomas G. Lane. } + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg, + jinclude, + jdeferr, + jerror, + jpeglib, + jdhuff, jdphuff, jdcoefct; + +{ Read the coefficient arrays from a JPEG file. + jpeg_read_header must be completed before calling this. + + The entire image is read into a set of virtual coefficient-block arrays, + one per component. The return value is a pointer to the array of + virtual-array descriptors. These can be manipulated directly via the + JPEG memory manager, or handed off to jpeg_write_coefficients(). + To release the memory occupied by the virtual arrays, call + jpeg_finish_decompress() when done with the data. + + An alternative usage is to simply obtain access to the coefficient arrays + during a buffered-image-mode decompression operation. This is allowed + after any jpeg_finish_output() call. The arrays can be accessed until + jpeg_finish_decompress() is called. (Note that any call to the library + may reposition the arrays, so don't rely on access_virt_barray() results + to stay valid across library calls.) + + Returns NIL if suspended. This case need be checked only if + a suspending data source is used. } + +{GLOBAL} +function jpeg_read_coefficients + (cinfo : j_decompress_ptr) : jvirt_barray_tbl_ptr; + +implementation + + +{ Forward declarations } +{LOCAL} +procedure transdecode_master_selection (cinfo : j_decompress_ptr); forward; + + +{ Read the coefficient arrays from a JPEG file. + jpeg_read_header must be completed before calling this. + + The entire image is read into a set of virtual coefficient-block arrays, + one per component. The return value is a pointer to the array of + virtual-array descriptors. These can be manipulated directly via the + JPEG memory manager, or handed off to jpeg_write_coefficients(). + To release the memory occupied by the virtual arrays, call + jpeg_finish_decompress() when done with the data. + + Returns NIL if suspended. This case need be checked only if + a suspending data source is used. } + +{GLOBAL} +function jpeg_read_coefficients + (cinfo : j_decompress_ptr) : jvirt_barray_tbl_ptr; +var + retcode : int; +begin + if (cinfo^.global_state = DSTATE_READY) then + begin + { First call: initialize active modules } + transdecode_master_selection(cinfo); + cinfo^.global_state := DSTATE_RDCOEFS; + end; + + if (cinfo^.global_state = DSTATE_RDCOEFS) then + begin + { Absorb whole file into the coef buffer } + while TRUE do + begin + { Call progress monitor hook if present } + if (cinfo^.progress <> NIL) then + cinfo^.progress^.progress_monitor (j_common_ptr(cinfo)); + { Absorb some more input } + retcode := cinfo^.inputctl^.consume_input (cinfo); + if (retcode = JPEG_SUSPENDED) then + begin + jpeg_read_coefficients := NIL; + exit; + end; + if (retcode = JPEG_REACHED_EOI) then + break; + { Advance progress counter if appropriate } + if (cinfo^.progress <> NIL) and + ((retcode = JPEG_ROW_COMPLETED) or (retcode = JPEG_REACHED_SOS)) then + begin + Inc(cinfo^.progress^.pass_counter); + if (cinfo^.progress^.pass_counter >= cinfo^.progress^.pass_limit) then + begin + { startup underestimated number of scans; ratchet up one scan } + Inc(cinfo^.progress^.pass_limit, long(cinfo^.total_iMCU_rows)); + end; + end; + end; + { Set state so that jpeg_finish_decompress does the right thing } + cinfo^.global_state := DSTATE_STOPPING; + end; + { At this point we should be in state DSTATE_STOPPING if being used + standalone, or in state DSTATE_BUFIMAGE if being invoked to get access + to the coefficients during a full buffered-image-mode decompression. } + + if ((cinfo^.global_state = DSTATE_STOPPING) or + (cinfo^.global_state = DSTATE_BUFIMAGE)) and (cinfo^.buffered_image) then + begin + jpeg_read_coefficients := cinfo^.coef^.coef_arrays; + exit; + end; + { Oops, improper usage } + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); + jpeg_read_coefficients := NIL; { keep compiler happy } +end; + + +{ Master selection of decompression modules for transcoding. + This substitutes for jdmaster.c's initialization of the full decompressor. } + +{LOCAL} +procedure transdecode_master_selection (cinfo : j_decompress_ptr); +var + nscans : int; +begin + { This is effectively a buffered-image operation. } + cinfo^.buffered_image := TRUE; + + { Entropy decoding: either Huffman or arithmetic coding. } + if (cinfo^.arith_code) then + begin + ERREXIT(j_common_ptr(cinfo), JERR_ARITH_NOTIMPL); + end + else + begin + if (cinfo^.progressive_mode) then + begin +{$ifdef D_PROGRESSIVE_SUPPORTED} + jinit_phuff_decoder(cinfo); +{$else} + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); +{$endif} + end + else + jinit_huff_decoder(cinfo); + end; + + { Always get a full-image coefficient buffer. } + jinit_d_coef_controller(cinfo, TRUE); + + { We can now tell the memory manager to allocate virtual arrays. } + cinfo^.mem^.realize_virt_arrays (j_common_ptr(cinfo)); + + { Initialize input side of decompressor to consume first scan. } + cinfo^.inputctl^.start_input_pass (cinfo); + + { Initialize progress monitoring. } + if (cinfo^.progress <> NIL) then + begin + { Estimate number of scans to set pass_limit. } + if (cinfo^.progressive_mode) then + begin + { Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. } + nscans := 2 + 3 * cinfo^.num_components; + end + else + if (cinfo^.inputctl^.has_multiple_scans) then + begin + { For a nonprogressive multiscan file, estimate 1 scan per component. } + nscans := cinfo^.num_components; + end + else + begin + nscans := 1; + end; + cinfo^.progress^.pass_counter := long(0); + cinfo^.progress^.pass_limit := long(cinfo^.total_iMCU_rows * nscans); + cinfo^.progress^.completed_passes := 0; + cinfo^.progress^.total_passes := 1; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jerror_del.pas b/mseide-msegui/lib/common/fpccompatibility/jerror_del.pas new file mode 100644 index 0000000..4715ea4 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jerror_del.pas @@ -0,0 +1,463 @@ +unit jerror_del; + +{ This file contains simple error-reporting and trace-message routines. + These are suitable for Unix-like systems and others where writing to + stderr is the right thing to do. Many applications will want to replace + some or all of these routines. + + These routines are used by both the compression and decompression code. } + +{ Source: jerror.c; Copyright (C) 1991-1996, Thomas G. Lane. } +{ note: format_message still contains a hack } +//modified 2013 by Martin Schreiber + +{$i jconfig_del.inc} +interface + +uses + jmorecfg_del, + jdeferr_del, + jpeglib_del; +{ + jversion; +} + +const + EXIT_FAILURE = 1; { define halt() codes if not provided } + +{GLOBAL} +function jpeg_std_error (var err : jpeg_error_mgr) : jpeg_error_mgr_ptr; + + + +procedure ERREXIT(cinfo : j_common_ptr; code : J_MESSAGE_CODE); + +procedure ERREXIT1(cinfo : j_common_ptr; code : J_MESSAGE_CODE; p1 : uInt); + +procedure ERREXIT2(cinfo : j_common_ptr; code : J_MESSAGE_CODE; p1 : int; p2 : int); + +procedure ERREXIT3(cinfo : j_common_ptr; code : J_MESSAGE_CODE; + p1 : int; p2 : int; p3 : int); + +procedure ERREXIT4(cinfo : j_common_ptr; code : J_MESSAGE_CODE; + p1 : int; p2 : int; p3 : int; p4 : int); + +procedure ERREXITS(cinfo : j_common_ptr;code : J_MESSAGE_CODE; + str : string); +{ Nonfatal errors (we can keep going, but the data is probably corrupt) } + +procedure WARNMS(cinfo : j_common_ptr; code : J_MESSAGE_CODE); + +procedure WARNMS1(cinfo : j_common_ptr;code : J_MESSAGE_CODE; p1 : int); + +procedure WARNMS2(cinfo : j_common_ptr; code : J_MESSAGE_CODE; + p1 : int; p2 : int); + +{ Informational/debugging messages } +procedure TRACEMS(cinfo : j_common_ptr; lvl : int; code : J_MESSAGE_CODE); + +procedure TRACEMS1(cinfo : j_common_ptr; lvl : int; + code : J_MESSAGE_CODE; p1 : long); + +procedure TRACEMS2(cinfo : j_common_ptr; lvl : int; code : J_MESSAGE_CODE; + p1 : int; + p2 : int); + +procedure TRACEMS3(cinfo : j_common_ptr; + lvl : int; + code : J_MESSAGE_CODE; + p1 : int; p2 : int; p3 : int); + +procedure TRACEMS4(cinfo : j_common_ptr; lvl : int; code : J_MESSAGE_CODE; + p1 : int; p2 : int; p3 : int; p4 : int); + +procedure TRACEMS5(cinfo : j_common_ptr; lvl : int; code : J_MESSAGE_CODE; + p1 : int; p2 : int; p3 : int; p4 : int; p5 : int); + +procedure TRACEMS8(cinfo : j_common_ptr; lvl : int; code : J_MESSAGE_CODE; + p1 : int; p2 : int; p3 : int; p4 : int; + p5 : int; p6 : int; p7 : int; p8 : int); + +procedure TRACEMSS(cinfo : j_common_ptr; lvl : int; + code : J_MESSAGE_CODE; str : string); + +implementation + + +{ How to format a message string, in format_message() ? } + +{$IFDEF OS2} + {$DEFINE NO_FORMAT} +{$ENDIF} +{$IFDEF FPC} + {.$DEFINE NO_FORMAT} +{$ENDIF} + +uses +{$IFNDEF NO_FORMAT} + {$IFDEF VER70} + drivers, { Turbo Vision unit with FormatStr } + {$ELSE} + sysutils, { Delphi Unit with Format() } + {$ENDIF} +{$ENDIF} + jcomapi_del; + +{ Error exit handler: must not return to caller. + + Applications may override this if they want to get control back after + an error. Typically one would longjmp somewhere instead of exiting. + The setjmp buffer can be made a private field within an expanded error + handler object. Note that the info needed to generate an error message + is stored in the error object, so you can generate the message now or + later, at your convenience. + You should make sure that the JPEG object is cleaned up (with jpeg_abort + or jpeg_destroy) at some point. } + + +{METHODDEF} +procedure error_exit (cinfo : j_common_ptr); +begin + { Always display the message } + cinfo^.err^.output_message(cinfo); + + { Let the memory manager delete any temp files before we die } + jpeg_destroy(cinfo); + + halt(EXIT_FAILURE); +end; + + +{ Actual output of an error or trace message. + Applications may override this method to send JPEG messages somewhere + other than stderr. } + +{ Macros to simplify using the error and trace message stuff } +{ The first parameter is either type of cinfo pointer } + +{ Fatal errors (print message and exit) } +procedure ERREXIT(cinfo : j_common_ptr; code : J_MESSAGE_CODE); +begin + cinfo^.err^.msg_code := ord(code); + cinfo^.err^.error_exit(cinfo); +end; + +procedure ERREXIT1(cinfo : j_common_ptr; code : J_MESSAGE_CODE; p1 : uInt); +begin + cinfo^.err^.msg_code := ord(code); + cinfo^.err^.msg_parm.i[0] := p1; + cinfo^.err^.error_exit (cinfo); +end; + +procedure ERREXIT2(cinfo : j_common_ptr; code : J_MESSAGE_CODE; + p1 : int; p2 : int); +begin + cinfo^.err^.msg_code := ord(code); + cinfo^.err^.msg_parm.i[0] := p1; + cinfo^.err^.msg_parm.i[1] := p2; + cinfo^.err^.error_exit (cinfo); +end; + +procedure ERREXIT3(cinfo : j_common_ptr; code : J_MESSAGE_CODE; + p1 : int; p2 : int; p3 : int); +begin + cinfo^.err^.msg_code := ord(code); + cinfo^.err^.msg_parm.i[0] := p1; + cinfo^.err^.msg_parm.i[1] := p2; + cinfo^.err^.msg_parm.i[2] := p3; + cinfo^.err^.error_exit (cinfo); +end; + +procedure ERREXIT4(cinfo : j_common_ptr; code : J_MESSAGE_CODE; + p1 : int; p2 : int; p3 : int; p4 : int); +begin + cinfo^.err^.msg_code := ord(code); + cinfo^.err^.msg_parm.i[0] := p1; + cinfo^.err^.msg_parm.i[1] := p2; + cinfo^.err^.msg_parm.i[2] := p3; + cinfo^.err^.msg_parm.i[3] := p4; + cinfo^.err^.error_exit (cinfo); +end; + +procedure ERREXITS(cinfo : j_common_ptr;code : J_MESSAGE_CODE; + str : string); +begin + cinfo^.err^.msg_code := ord(code); + cinfo^.err^.msg_parm.s := str; { string[JMSG_STR_PARM_MAX] } + cinfo^.err^.error_exit (cinfo); +end; + +{ Nonfatal errors (we can keep going, but the data is probably corrupt) } + +procedure WARNMS(cinfo : j_common_ptr; code : J_MESSAGE_CODE); +begin + cinfo^.err^.msg_code := ord(code); + cinfo^.err^.emit_message(cinfo, -1); +end; + +procedure WARNMS1(cinfo : j_common_ptr;code : J_MESSAGE_CODE; p1 : int); +begin + cinfo^.err^.msg_code := ord(code); + cinfo^.err^.msg_parm.i[0] := p1; + cinfo^.err^.emit_message (cinfo, -1); +end; + +procedure WARNMS2(cinfo : j_common_ptr; code : J_MESSAGE_CODE; + p1 : int; p2 : int); +begin + cinfo^.err^.msg_code := ord(code); + cinfo^.err^.msg_parm.i[0] := p1; + cinfo^.err^.msg_parm.i[1] := p2; + cinfo^.err^.emit_message (cinfo, -1); +end; + +{ Informational/debugging messages } +procedure TRACEMS(cinfo : j_common_ptr; lvl : int; code : J_MESSAGE_CODE); +begin + cinfo^.err^.msg_code := ord(code); + cinfo^.err^.emit_message(cinfo, lvl); +end; + +procedure TRACEMS1(cinfo : j_common_ptr; lvl : int; + code : J_MESSAGE_CODE; p1 : long); +begin + cinfo^.err^.msg_code := ord(code); + cinfo^.err^.msg_parm.i[0] := p1; + cinfo^.err^.emit_message (cinfo, lvl); +end; + +procedure TRACEMS2(cinfo : j_common_ptr; lvl : int; code : J_MESSAGE_CODE; + p1 : int; + p2 : int); +begin + cinfo^.err^.msg_code := ord(code); + cinfo^.err^.msg_parm.i[0] := p1; + cinfo^.err^.msg_parm.i[1] := p2; + cinfo^.err^.emit_message (cinfo, lvl); +end; + +procedure TRACEMS3(cinfo : j_common_ptr; + lvl : int; + code : J_MESSAGE_CODE; + p1 : int; p2 : int; p3 : int); +var + _mp : int8array; +begin + _mp[0] := p1; _mp[1] := p2; _mp[2] := p3; + cinfo^.err^.msg_parm.i := _mp; + cinfo^.err^.msg_code := ord(code); + cinfo^.err^.emit_message (cinfo, lvl); +end; + + +procedure TRACEMS4(cinfo : j_common_ptr; lvl : int; code : J_MESSAGE_CODE; + p1 : int; p2 : int; p3 : int; p4 : int); +var + _mp : int8array; +begin + _mp[0] := p1; _mp[1] := p2; _mp[2] := p3; _mp[3] := p4; + cinfo^.err^.msg_parm.i := _mp; + cinfo^.err^.msg_code := ord(code); + cinfo^.err^.emit_message (cinfo, lvl); +end; + +procedure TRACEMS5(cinfo : j_common_ptr; lvl : int; code : J_MESSAGE_CODE; + p1 : int; p2 : int; p3 : int; p4 : int; p5 : int); +var + _mp : ^int8array; +begin + _mp := @cinfo^.err^.msg_parm.i; + _mp^[0] := p1; _mp^[1] := p2; _mp^[2] := p3; + _mp^[3] := p4; _mp^[5] := p5; + cinfo^.err^.msg_code := ord(code); + cinfo^.err^.emit_message (cinfo, lvl); +end; + +procedure TRACEMS8(cinfo : j_common_ptr; lvl : int; code : J_MESSAGE_CODE; + p1 : int; p2 : int; p3 : int; p4 : int; + p5 : int; p6 : int; p7 : int; p8 : int); +var + _mp : int8array; +begin + _mp[0] := p1; _mp[1] := p2; _mp[2] := p3; _mp[3] := p4; + _mp[4] := p5; _mp[5] := p6; _mp[6] := p7; _mp[7] := p8; + cinfo^.err^.msg_parm.i := _mp; + cinfo^.err^.msg_code := ord(code); + cinfo^.err^.emit_message (cinfo, lvl); +end; + +procedure TRACEMSS(cinfo : j_common_ptr; lvl : int; + code : J_MESSAGE_CODE; str : string); +begin + cinfo^.err^.msg_code := ord(code); + cinfo^.err^.msg_parm.s := str; { string JMSG_STR_PARM_MAX } + cinfo^.err^.emit_message (cinfo, lvl); +end; + +{METHODDEF} +procedure output_message (cinfo : j_common_ptr); +var + buffer : string; {[JMSG_LENGTH_MAX];} +begin + { Create the message } + cinfo^.err^.format_message (cinfo, buffer); + + { Send it to stderr, adding a newline } + WriteLn(output, buffer); +end; + + + +{ Decide whether to emit a trace or warning message. + msg_level is one of: + -1: recoverable corrupt-data warning, may want to abort. + 0: important advisory messages (always display to user). + 1: first level of tracing detail. + 2,3,...: successively more detailed tracing messages. + An application might override this method if it wanted to abort on warnings + or change the policy about which messages to display. } + + +{METHODDEF} +procedure emit_message (cinfo : j_common_ptr; msg_level : int); +var + err : jpeg_error_mgr_ptr; +begin + err := cinfo^.err; + if (msg_level < 0) then + begin + { It's a warning message. Since corrupt files may generate many warnings, + the policy implemented here is to show only the first warning, + unless trace_level >= 3. } + + if (err^.num_warnings = 0) or (err^.trace_level >= 3) then + err^.output_message(cinfo); + { Always count warnings in num_warnings. } + Inc( err^.num_warnings ); + end + else + begin + { It's a trace message. Show it if trace_level >= msg_level. } + if (err^.trace_level >= msg_level) then + err^.output_message (cinfo); + end; +end; + + +{ Format a message string for the most recent JPEG error or message. + The message is stored into buffer, which should be at least JMSG_LENGTH_MAX + characters. Note that no '\n' character is added to the string. + Few applications should need to override this method. } + + +{METHODDEF} +procedure format_message (cinfo : j_common_ptr; var buffer : string); +var + err : jpeg_error_mgr_ptr; + msg_code : J_MESSAGE_CODE; + msgtext : string; + isstring : boolean; +begin + err := cinfo^.err; + msg_code := J_MESSAGE_CODE(err^.msg_code); + msgtext := ''; + + { Look up message string in proper table } + if (msg_code > JMSG_NOMESSAGE) + and (msg_code <= J_MESSAGE_CODE(err^.last_jpeg_message)) then + begin + msgtext := err^.jpeg_message_table^[msg_code]; + end + else + if (err^.addon_message_table <> NIL) and + (msg_code >= err^.first_addon_message) and + (msg_code <= err^.last_addon_message) then + begin + msgtext := err^.addon_message_table^[J_MESSAGE_CODE + (ord(msg_code) - ord(err^.first_addon_message))]; + end; + + { Defend against bogus message number } + if (msgtext = '') then + begin + err^.msg_parm.i[0] := int(msg_code); + msgtext := err^.jpeg_message_table^[JMSG_NOMESSAGE]; + end; + + { Check for string parameter, as indicated by %s in the message text } + isstring := Pos('%s', msgtext) > 0; + + { Format the message into the passed buffer } + if (isstring) then + buffer := Concat(msgtext, err^.msg_parm.s) + else + begin + {$IFDEF VER70} + FormatStr(buffer, msgtext, err^.msg_parm.i); + {$ELSE} + {$IFDEF NO_FORMAT} + buffer := msgtext; + {$ELSE} + buffer := Format(msgtext, [ + err^.msg_parm.i[0], err^.msg_parm.i[1], + err^.msg_parm.i[2], err^.msg_parm.i[3], + err^.msg_parm.i[4], err^.msg_parm.i[5], + err^.msg_parm.i[6], err^.msg_parm.i[7] ]); + {$ENDIF} + {$ENDIF} + end; +end; + + + +{ Reset error state variables at start of a new image. + This is called during compression startup to reset trace/error + processing to default state, without losing any application-specific + method pointers. An application might possibly want to override + this method if it has additional error processing state. } + + +{METHODDEF} +procedure reset_error_mgr (cinfo : j_common_ptr); +begin + cinfo^.err^.num_warnings := 0; + { trace_level is not reset since it is an application-supplied parameter } + cinfo^.err^.msg_code := 0; { may be useful as a flag for "no error" } +end; + + +{ Fill in the standard error-handling methods in a jpeg_error_mgr object. + Typical call is: + cinfo : jpeg_compress_struct; + err : jpeg_error_mgr; + + cinfo.err := jpeg_std_error(@err); + after which the application may override some of the methods. } + + +{GLOBAL} +function jpeg_std_error (var err : jpeg_error_mgr) : jpeg_error_mgr_ptr; +begin + err.error_exit := error_exit; + err.emit_message := emit_message; + err.output_message := output_message; + err.format_message := format_message; + err.reset_error_mgr := reset_error_mgr; + + err.trace_level := 0; { default := no tracing } + err.num_warnings := 0; { no warnings emitted yet } + err.msg_code := 0; { may be useful as a flag for "no error" } + + { Initialize message table pointers } + err.jpeg_message_table := @jpeg_std_message_table; + err.last_jpeg_message := pred(JMSG_LASTMSGCODE); + + err.addon_message_table := NIL; + err.first_addon_message := JMSG_NOMESSAGE; { for safety } + err.last_addon_message := JMSG_NOMESSAGE; + + jpeg_std_error := @err; +end; + + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jfdctflt_del.pas b/mseide-msegui/lib/common/fpccompatibility/jfdctflt_del.pas new file mode 100644 index 0000000..c1728b4 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jfdctflt_del.pas @@ -0,0 +1,178 @@ +Unit jfdctflt_del; + +//{$N+} +{ This file contains a floating-point implementation of the + forward DCT (Discrete Cosine Transform). + + This implementation should be more accurate than either of the integer + DCT implementations. However, it may not give the same results on all + machines because of differences in roundoff behavior. Speed will depend + on the hardware's floating point capacity. + + A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT + on each column. Direct algorithms are also available, but they are + much more complex and seem not to be any faster when reduced to code. + + This implementation is based on Arai, Agui, and Nakajima's algorithm for + scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in + Japanese, but the algorithm is described in the Pennebaker & Mitchell + JPEG textbook (see REFERENCES section in file README). The following code + is based directly on figure 4-8 in P&M. + While an 8-point DCT cannot be done in less than 11 multiplies, it is + possible to arrange the computation so that many of the multiplies are + simple scalings of the final outputs. These multiplies can then be + folded into the multiplications or divisions by the JPEG quantization + table entries. The AA&N method leaves only 5 multiplies and 29 adds + to be done in the DCT itself. + The primary disadvantage of this method is that with a fixed-point + implementation, accuracy is lost due to imprecise representation of the + scaled quantization values. However, that problem does not arise if + we use floating point arithmetic. } + +{ Original : jfdctflt.c ; Copyright (C) 1994-1996, Thomas G. Lane. } + +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jpeglib_del, + jdct_del; { Private declarations for DCT subsystem } + + +{ Perform the forward DCT on one block of samples.} + +{GLOBAL} +procedure jpeg_fdct_float (var data : array of FAST_FLOAT); + +implementation + +{ This module is specialized to the case DCTSIZE = 8. } + +{$ifndef DCTSIZE_IS_8} + Sorry, this code only copes with 8x8 DCTs. { deliberate syntax err } +{$endif} + + +{ Perform the forward DCT on one block of samples.} + +{GLOBAL} +procedure jpeg_fdct_float (var data : array of FAST_FLOAT); +type + PWorkspace = ^TWorkspace; + TWorkspace = array [0..DCTSIZE2-1] of FAST_FLOAT; +var + tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7 : FAST_FLOAT; + tmp10, tmp11, tmp12, tmp13 : FAST_FLOAT; + z1, z2, z3, z4, z5, z11, z13 : FAST_FLOAT; + dataptr : PWorkspace; + ctr : int; +begin + { Pass 1: process rows. } + + dataptr := PWorkspace(@data); + for ctr := DCTSIZE-1 downto 0 do + begin + tmp0 := dataptr^[0] + dataptr^[7]; + tmp7 := dataptr^[0] - dataptr^[7]; + tmp1 := dataptr^[1] + dataptr^[6]; + tmp6 := dataptr^[1] - dataptr^[6]; + tmp2 := dataptr^[2] + dataptr^[5]; + tmp5 := dataptr^[2] - dataptr^[5]; + tmp3 := dataptr^[3] + dataptr^[4]; + tmp4 := dataptr^[3] - dataptr^[4]; + + { Even part } + + tmp10 := tmp0 + tmp3; { phase 2 } + tmp13 := tmp0 - tmp3; + tmp11 := tmp1 + tmp2; + tmp12 := tmp1 - tmp2; + + dataptr^[0] := tmp10 + tmp11; { phase 3 } + dataptr^[4] := tmp10 - tmp11; + + z1 := (tmp12 + tmp13) * ({FAST_FLOAT}(0.707106781)); { c4 } + dataptr^[2] := tmp13 + z1; { phase 5 } + dataptr^[6] := tmp13 - z1; + + { Odd part } + + tmp10 := tmp4 + tmp5; { phase 2 } + tmp11 := tmp5 + tmp6; + tmp12 := tmp6 + tmp7; + + { The rotator is modified from fig 4-8 to avoid extra negations. } + z5 := (tmp10 - tmp12) * ( {FAST_FLOAT}(0.382683433)); { c6 } + z2 := {FAST_FLOAT}(0.541196100) * tmp10 + z5; { c2-c6 } + z4 := {FAST_FLOAT}(1.306562965) * tmp12 + z5; { c2+c6 } + z3 := tmp11 * {FAST_FLOAT} (0.707106781); { c4 } + + z11 := tmp7 + z3; { phase 5 } + z13 := tmp7 - z3; + + dataptr^[5] := z13 + z2; { phase 6 } + dataptr^[3] := z13 - z2; + dataptr^[1] := z11 + z4; + dataptr^[7] := z11 - z4; + + Inc(FAST_FLOAT_PTR(dataptr), DCTSIZE); { advance pointer to next row } + end; + + { Pass 2: process columns. } + + dataptr := PWorkspace(@data); + for ctr := DCTSIZE-1 downto 0 do + begin + tmp0 := dataptr^[DCTSIZE*0] + dataptr^[DCTSIZE*7]; + tmp7 := dataptr^[DCTSIZE*0] - dataptr^[DCTSIZE*7]; + tmp1 := dataptr^[DCTSIZE*1] + dataptr^[DCTSIZE*6]; + tmp6 := dataptr^[DCTSIZE*1] - dataptr^[DCTSIZE*6]; + tmp2 := dataptr^[DCTSIZE*2] + dataptr^[DCTSIZE*5]; + tmp5 := dataptr^[DCTSIZE*2] - dataptr^[DCTSIZE*5]; + tmp3 := dataptr^[DCTSIZE*3] + dataptr^[DCTSIZE*4]; + tmp4 := dataptr^[DCTSIZE*3] - dataptr^[DCTSIZE*4]; + + { Even part } + + tmp10 := tmp0 + tmp3; { phase 2 } + tmp13 := tmp0 - tmp3; + tmp11 := tmp1 + tmp2; + tmp12 := tmp1 - tmp2; + + dataptr^[DCTSIZE*0] := tmp10 + tmp11; { phase 3 } + dataptr^[DCTSIZE*4] := tmp10 - tmp11; + + z1 := (tmp12 + tmp13) * {FAST_FLOAT} (0.707106781); { c4 } + dataptr^[DCTSIZE*2] := tmp13 + z1; { phase 5 } + dataptr^[DCTSIZE*6] := tmp13 - z1; + + { Odd part } + + tmp10 := tmp4 + tmp5; { phase 2 } + tmp11 := tmp5 + tmp6; + tmp12 := tmp6 + tmp7; + + { The rotator is modified from fig 4-8 to avoid extra negations. } + z5 := (tmp10 - tmp12) * {FAST_FLOAT} (0.382683433); { c6 } + z2 := {FAST_FLOAT} (0.541196100) * tmp10 + z5; { c2-c6 } + z4 := {FAST_FLOAT} (1.306562965) * tmp12 + z5; { c2+c6 } + z3 := tmp11 * {FAST_FLOAT} (0.707106781); { c4 } + + z11 := tmp7 + z3; { phase 5 } + z13 := tmp7 - z3; + + dataptr^[DCTSIZE*5] := z13 + z2; { phase 6 } + dataptr^[DCTSIZE*3] := z13 - z2; + dataptr^[DCTSIZE*1] := z11 + z4; + dataptr^[DCTSIZE*7] := z11 - z4; + + Inc(FAST_FLOAT_PTR(dataptr)); { advance pointer to next column } + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jfdctfst_del.pas b/mseide-msegui/lib/common/fpccompatibility/jfdctfst_del.pas new file mode 100644 index 0000000..d74e32a --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jfdctfst_del.pas @@ -0,0 +1,239 @@ +Unit jfdctfst_del; + +{ This file contains a fast, not so accurate integer implementation of the + forward DCT (Discrete Cosine Transform). + + A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT + on each column. Direct algorithms are also available, but they are + much more complex and seem not to be any faster when reduced to code. + + This implementation is based on Arai, Agui, and Nakajima's algorithm for + scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in + Japanese, but the algorithm is described in the Pennebaker & Mitchell + JPEG textbook (see REFERENCES section in file README). The following code + is based directly on figure 4-8 in P&M. + While an 8-point DCT cannot be done in less than 11 multiplies, it is + possible to arrange the computation so that many of the multiplies are + simple scalings of the final outputs. These multiplies can then be + folded into the multiplications or divisions by the JPEG quantization + table entries. The AA&N method leaves only 5 multiplies and 29 adds + to be done in the DCT itself. + The primary disadvantage of this method is that with fixed-point math, + accuracy is lost due to imprecise representation of the scaled + quantization values. The smaller the quantization table entry, the less + precise the scaled value, so this implementation does worse with high- + quality-setting files than with low-quality ones. } + +{ Original: jfdctfst.c ; Copyright (C) 1994-1996, Thomas G. Lane. } + + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jpeglib_del, + jdct_del; { Private declarations for DCT subsystem } + + +{ Perform the forward DCT on one block of samples. } + +{GLOBAL} +procedure jpeg_fdct_ifast (var data : array of DCTELEM); + +implementation + +{ This module is specialized to the case DCTSIZE = 8. } + +{$ifndef DCTSIZE_IS_8} + Sorry, this code only copes with 8x8 DCTs. { deliberate syntax err } +{$endif} + + +{ Scaling decisions are generally the same as in the LL&M algorithm; + see jfdctint.c for more details. However, we choose to descale + (right shift) multiplication products as soon as they are formed, + rather than carrying additional fractional bits into subsequent additions. + This compromises accuracy slightly, but it lets us save a few shifts. + More importantly, 16-bit arithmetic is then adequate (for 8-bit samples) + everywhere except in the multiplications proper; this saves a good deal + of work on 16-bit-int machines. + + Again to save a few shifts, the intermediate results between pass 1 and + pass 2 are not upscaled, but are represented only to integral precision. + + A final compromise is to represent the multiplicative constants to only + 8 fractional bits, rather than 13. This saves some shifting work on some + machines, and may also reduce the cost of multiplication (since there + are fewer one-bits in the constants). } + +//modified 2013 by Martin Schreiber + +const + CONST_BITS = 8; +const + CONST_SCALE = (INT32(1) shl CONST_BITS); + + +const + FIX_0_382683433 = INT32(Round(CONST_SCALE * 0.382683433)); {98} + FIX_0_541196100 = INT32(Round(CONST_SCALE * 0.541196100)); {139} + FIX_0_707106781 = INT32(Round(CONST_SCALE * 0.707106781)); {181} + FIX_1_306562965 = INT32(Round(CONST_SCALE * 1.306562965)); {334} + +{ Descale and correctly round an INT32 value that's scaled by N bits. + We assume RIGHT_SHIFT rounds towards minus infinity, so adding + the fudge factor is correct for either sign of X. } + +function DESCALE(x : INT32; n : int) : INT32; +var + shift_temp : INT32; +begin +{ We can gain a little more speed, with a further compromise in accuracy, + by omitting the addition in a descaling shift. This yields an incorrectly + rounded result half the time... } +{$ifndef USE_ACCURATE_ROUNDING} + shift_temp := x; +{$else} + shift_temp := x + (INT32(1) shl (n-1)); +{$endif} + +{$ifdef RIGHT_SHIFT_IS_UNSIGNED} + if shift_temp < 0 then + Descale := (shift_temp shr n) or ((not INT32(0)) shl (32-n)) + else +{$endif} + Descale := (shift_temp shr n); +end; + +{ Multiply a DCTELEM variable by an INT32 constant, and immediately + descale to yield a DCTELEM result. } + + + function MULTIPLY(X : DCTELEM; Y: INT32): DCTELEM; + begin + Multiply := DeScale((X) * (Y), CONST_BITS); + end; + + +{ Perform the forward DCT on one block of samples. } + +{GLOBAL} +procedure jpeg_fdct_ifast (var data : array of DCTELEM); +type + PWorkspace = ^TWorkspace; + TWorkspace = array [0..DCTSIZE2-1] of DCTELEM; +var + tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7 : DCTELEM; + tmp10, tmp11, tmp12, tmp13 : DCTELEM; + z1, z2, z3, z4, z5, z11, z13 : DCTELEM; + dataptr : PWorkspace; + ctr : int; + {SHIFT_TEMPS} +begin + { Pass 1: process rows. } + + dataptr := PWorkspace(@data); + for ctr := DCTSIZE-1 downto 0 do + begin + tmp0 := dataptr^[0] + dataptr^[7]; + tmp7 := dataptr^[0] - dataptr^[7]; + tmp1 := dataptr^[1] + dataptr^[6]; + tmp6 := dataptr^[1] - dataptr^[6]; + tmp2 := dataptr^[2] + dataptr^[5]; + tmp5 := dataptr^[2] - dataptr^[5]; + tmp3 := dataptr^[3] + dataptr^[4]; + tmp4 := dataptr^[3] - dataptr^[4]; + + { Even part } + + tmp10 := tmp0 + tmp3; { phase 2 } + tmp13 := tmp0 - tmp3; + tmp11 := tmp1 + tmp2; + tmp12 := tmp1 - tmp2; + + dataptr^[0] := tmp10 + tmp11; { phase 3 } + dataptr^[4] := tmp10 - tmp11; + + z1 := MULTIPLY(tmp12 + tmp13, FIX_0_707106781); { c4 } + dataptr^[2] := tmp13 + z1; { phase 5 } + dataptr^[6] := tmp13 - z1; + + { Odd part } + + tmp10 := tmp4 + tmp5; { phase 2 } + tmp11 := tmp5 + tmp6; + tmp12 := tmp6 + tmp7; + + { The rotator is modified from fig 4-8 to avoid extra negations. } + z5 := MULTIPLY(tmp10 - tmp12, FIX_0_382683433); { c6 } + z2 := MULTIPLY(tmp10, FIX_0_541196100) + z5; { c2-c6 } + z4 := MULTIPLY(tmp12, FIX_1_306562965) + z5; { c2+c6 } + z3 := MULTIPLY(tmp11, FIX_0_707106781); { c4 } + + z11 := tmp7 + z3; { phase 5 } + z13 := tmp7 - z3; + + dataptr^[5] := z13 + z2; { phase 6 } + dataptr^[3] := z13 - z2; + dataptr^[1] := z11 + z4; + dataptr^[7] := z11 - z4; + + Inc(DCTELEMPTR(dataptr), DCTSIZE); { advance pointer to next row } + end; + + { Pass 2: process columns. } + + dataptr := PWorkspace(@data); + for ctr := DCTSIZE-1 downto 0 do + begin + tmp0 := dataptr^[DCTSIZE*0] + dataptr^[DCTSIZE*7]; + tmp7 := dataptr^[DCTSIZE*0] - dataptr^[DCTSIZE*7]; + tmp1 := dataptr^[DCTSIZE*1] + dataptr^[DCTSIZE*6]; + tmp6 := dataptr^[DCTSIZE*1] - dataptr^[DCTSIZE*6]; + tmp2 := dataptr^[DCTSIZE*2] + dataptr^[DCTSIZE*5]; + tmp5 := dataptr^[DCTSIZE*2] - dataptr^[DCTSIZE*5]; + tmp3 := dataptr^[DCTSIZE*3] + dataptr^[DCTSIZE*4]; + tmp4 := dataptr^[DCTSIZE*3] - dataptr^[DCTSIZE*4]; + + { Even part } + + tmp10 := tmp0 + tmp3; { phase 2 } + tmp13 := tmp0 - tmp3; + tmp11 := tmp1 + tmp2; + tmp12 := tmp1 - tmp2; + + dataptr^[DCTSIZE*0] := tmp10 + tmp11; { phase 3 } + dataptr^[DCTSIZE*4] := tmp10 - tmp11; + + z1 := MULTIPLY(tmp12 + tmp13, FIX_0_707106781); { c4 } + dataptr^[DCTSIZE*2] := tmp13 + z1; { phase 5 } + dataptr^[DCTSIZE*6] := tmp13 - z1; + + { Odd part } + + tmp10 := tmp4 + tmp5; { phase 2 } + tmp11 := tmp5 + tmp6; + tmp12 := tmp6 + tmp7; + + { The rotator is modified from fig 4-8 to avoid extra negations. } + z5 := MULTIPLY(tmp10 - tmp12, FIX_0_382683433); { c6 } + z2 := MULTIPLY(tmp10, FIX_0_541196100) + z5; { c2-c6 } + z4 := MULTIPLY(tmp12, FIX_1_306562965) + z5; { c2+c6 } + z3 := MULTIPLY(tmp11, FIX_0_707106781); { c4 } + + z11 := tmp7 + z3; { phase 5 } + z13 := tmp7 - z3; + + dataptr^[DCTSIZE*5] := z13 + z2; { phase 6 } + dataptr^[DCTSIZE*3] := z13 - z2; + dataptr^[DCTSIZE*1] := z11 + z4; + dataptr^[DCTSIZE*7] := z11 - z4; + + Inc(DCTELEMPTR(dataptr)); { advance pointer to next column } + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jfdctint_del.pas b/mseide-msegui/lib/common/fpccompatibility/jfdctint_del.pas new file mode 100644 index 0000000..f2ad5db --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jfdctint_del.pas @@ -0,0 +1,299 @@ +Unit jfdctint_del; + + +{ This file contains a slow-but-accurate integer implementation of the + forward DCT (Discrete Cosine Transform). + + A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT + on each column. Direct algorithms are also available, but they are + much more complex and seem not to be any faster when reduced to code. + + This implementation is based on an algorithm described in + C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT + Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics, + Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991. + The primary algorithm described there uses 11 multiplies and 29 adds. + We use their alternate method with 12 multiplies and 32 adds. + The advantage of this method is that no data path contains more than one + multiplication; this allows a very simple and accurate implementation in + scaled fixed-point arithmetic, with a minimal number of shifts. } + +{ Original : jfdctint.c ; Copyright (C) 1991-1996, Thomas G. Lane. } + +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jutils_del, + jpeglib_del, + jdct_del; { Private declarations for DCT subsystem } + + +{ Perform the forward DCT on one block of samples. } + +{GLOBAL} +procedure jpeg_fdct_islow (var data : array of DCTELEM); + +implementation + +{ This module is specialized to the case DCTSIZE = 8. } + +{$ifndef DCTSIZE_IS_8} + Sorry, this code only copes with 8x8 DCTs. { deliberate syntax err } +{$endif} + + +{ The poop on this scaling stuff is as follows: + + Each 1-D DCT step produces outputs which are a factor of sqrt(N) + larger than the true DCT outputs. The final outputs are therefore + a factor of N larger than desired; since N=8 this can be cured by + a simple right shift at the end of the algorithm. The advantage of + this arrangement is that we save two multiplications per 1-D DCT, + because the y0 and y4 outputs need not be divided by sqrt(N). + In the IJG code, this factor of 8 is removed by the quantization step + (in jcdctmgr.c), NOT in this module. + + We have to do addition and subtraction of the integer inputs, which + is no problem, and multiplication by fractional constants, which is + a problem to do in integer arithmetic. We multiply all the constants + by CONST_SCALE and convert them to integer constants (thus retaining + CONST_BITS bits of precision in the constants). After doing a + multiplication we have to divide the product by CONST_SCALE, with proper + rounding, to produce the correct output. This division can be done + cheaply as a right shift of CONST_BITS bits. We postpone shifting + as long as possible so that partial sums can be added together with + full fractional precision. + + The outputs of the first pass are scaled up by PASS1_BITS bits so that + they are represented to better-than-integral precision. These outputs + require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word + with the recommended scaling. (For 12-bit sample data, the intermediate + array is INT32 anyway.) + + To avoid overflow of the 32-bit intermediate results in pass 2, we must + have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26. Error analysis + shows that the values given below are the most effective. } + +{$ifdef BITS_IN_JSAMPLE_IS_8} +const + CONST_BITS = 13; + PASS1_BITS = 2; +{$else} +const + CONST_BITS = 13; + PASS1_BITS = 1; { lose a little precision to avoid overflow } +{$endif} + +const + CONST_SCALE = (INT32(1) shl CONST_BITS); + +const + FIX_0_298631336 = INT32(Round(CONST_SCALE * 0.298631336)); {2446} + FIX_0_390180644 = INT32(Round(CONST_SCALE * 0.390180644)); {3196} + FIX_0_541196100 = INT32(Round(CONST_SCALE * 0.541196100)); {4433} + FIX_0_765366865 = INT32(Round(CONST_SCALE * 0.765366865)); {6270} + FIX_0_899976223 = INT32(Round(CONST_SCALE * 0.899976223)); {7373} + FIX_1_175875602 = INT32(Round(CONST_SCALE * 1.175875602)); {9633} + FIX_1_501321110 = INT32(Round(CONST_SCALE * 1.501321110)); {12299} + FIX_1_847759065 = INT32(Round(CONST_SCALE * 1.847759065)); {15137} + FIX_1_961570560 = INT32(Round(CONST_SCALE * 1.961570560)); {16069} + FIX_2_053119869 = INT32(Round(CONST_SCALE * 2.053119869)); {16819} + FIX_2_562915447 = INT32(Round(CONST_SCALE * 2.562915447)); {20995} + FIX_3_072711026 = INT32(Round(CONST_SCALE * 3.072711026)); {25172} + + +{ Multiply an INT32 variable by an INT32 constant to yield an INT32 result. + For 8-bit samples with the recommended scaling, all the variable + and constant values involved are no more than 16 bits wide, so a + 16x16->32 bit multiply can be used instead of a full 32x32 multiply. + For 12-bit samples, a full 32-bit multiplication will be needed. } + +{$ifdef BITS_IN_JSAMPLE_IS_8} + + {MULTIPLY16C16(var,const)} + function Multiply(X, Y: int): INT32; + begin + Multiply := int(X) * INT32(Y); + end; + +{$else} + function Multiply(X, Y: INT32): INT32; + begin + Multiply := X * Y; + end; +{$endif} + +{ Descale and correctly round an INT32 value that's scaled by N bits. + We assume RIGHT_SHIFT rounds towards minus infinity, so adding + the fudge factor is correct for either sign of X. } + +function DESCALE(x : INT32; n : int) : INT32; +var + shift_temp : INT32; +begin +{$ifdef RIGHT_SHIFT_IS_UNSIGNED} + shift_temp := x + (INT32(1) shl (n-1)); + if shift_temp < 0 then + Descale := (shift_temp shr n) or ((not INT32(0)) shl (32-n)) + else + Descale := (shift_temp shr n); +{$else} + Descale := (x + (INT32(1) shl (n-1)) shr n; +{$endif} +end; + + +{ Perform the forward DCT on one block of samples. } + +{GLOBAL} +procedure jpeg_fdct_islow (var data : array of DCTELEM); +type + PWorkspace = ^TWorkspace; + TWorkspace = array [0..DCTSIZE2-1] of DCTELEM; +var + tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7 : INT32; + tmp10, tmp11, tmp12, tmp13 : INT32; + z1, z2, z3, z4, z5 : INT32; + dataptr : PWorkspace; + ctr : int; + {SHIFT_TEMPS} +begin + + { Pass 1: process rows. } + { Note results are scaled up by sqrt(8) compared to a true DCT; } + { furthermore, we scale the results by 2**PASS1_BITS. } + + dataptr := PWorkspace(@data); + for ctr := DCTSIZE-1 downto 0 do + begin + tmp0 := dataptr^[0] + dataptr^[7]; + tmp7 := dataptr^[0] - dataptr^[7]; + tmp1 := dataptr^[1] + dataptr^[6]; + tmp6 := dataptr^[1] - dataptr^[6]; + tmp2 := dataptr^[2] + dataptr^[5]; + tmp5 := dataptr^[2] - dataptr^[5]; + tmp3 := dataptr^[3] + dataptr^[4]; + tmp4 := dataptr^[3] - dataptr^[4]; + + { Even part per LL&M figure 1 --- note that published figure is faulty; + rotator "sqrt(2)*c1" should be "sqrt(2)*c6". } + + tmp10 := tmp0 + tmp3; + tmp13 := tmp0 - tmp3; + tmp11 := tmp1 + tmp2; + tmp12 := tmp1 - tmp2; + + dataptr^[0] := DCTELEM ((tmp10 + tmp11) shl PASS1_BITS); + dataptr^[4] := DCTELEM ((tmp10 - tmp11) shl PASS1_BITS); + + z1 := MULTIPLY(tmp12 + tmp13, FIX_0_541196100); + dataptr^[2] := DCTELEM (DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865), + CONST_BITS-PASS1_BITS)); + dataptr^[6] := DCTELEM (DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065), + CONST_BITS-PASS1_BITS)); + + { Odd part per figure 8 --- note paper omits factor of sqrt(2). + cK represents cos(K*pi/16). + i0..i3 in the paper are tmp4..tmp7 here. } + + z1 := tmp4 + tmp7; + z2 := tmp5 + tmp6; + z3 := tmp4 + tmp6; + z4 := tmp5 + tmp7; + z5 := MULTIPLY(z3 + z4, FIX_1_175875602); { sqrt(2) * c3 } + + tmp4 := MULTIPLY(tmp4, FIX_0_298631336); { sqrt(2) * (-c1+c3+c5-c7) } + tmp5 := MULTIPLY(tmp5, FIX_2_053119869); { sqrt(2) * ( c1+c3-c5+c7) } + tmp6 := MULTIPLY(tmp6, FIX_3_072711026); { sqrt(2) * ( c1+c3+c5-c7) } + tmp7 := MULTIPLY(tmp7, FIX_1_501321110); { sqrt(2) * ( c1+c3-c5-c7) } + z1 := MULTIPLY(z1, - FIX_0_899976223); { sqrt(2) * (c7-c3) } + z2 := MULTIPLY(z2, - FIX_2_562915447); { sqrt(2) * (-c1-c3) } + z3 := MULTIPLY(z3, - FIX_1_961570560); { sqrt(2) * (-c3-c5) } + z4 := MULTIPLY(z4, - FIX_0_390180644); { sqrt(2) * (c5-c3) } + + Inc(z3, z5); + Inc(z4, z5); + + dataptr^[7] := DCTELEM(DESCALE(tmp4 + z1 + z3, CONST_BITS-PASS1_BITS)); + dataptr^[5] := DCTELEM(DESCALE(tmp5 + z2 + z4, CONST_BITS-PASS1_BITS)); + dataptr^[3] := DCTELEM(DESCALE(tmp6 + z2 + z3, CONST_BITS-PASS1_BITS)); + dataptr^[1] := DCTELEM(DESCALE(tmp7 + z1 + z4, CONST_BITS-PASS1_BITS)); + + Inc(DCTELEMPTR(dataptr), DCTSIZE); { advance pointer to next row } + end; + + { Pass 2: process columns. + We remove the PASS1_BITS scaling, but leave the results scaled up + by an overall factor of 8. } + + dataptr := PWorkspace(@data); + for ctr := DCTSIZE-1 downto 0 do + begin + tmp0 := dataptr^[DCTSIZE*0] + dataptr^[DCTSIZE*7]; + tmp7 := dataptr^[DCTSIZE*0] - dataptr^[DCTSIZE*7]; + tmp1 := dataptr^[DCTSIZE*1] + dataptr^[DCTSIZE*6]; + tmp6 := dataptr^[DCTSIZE*1] - dataptr^[DCTSIZE*6]; + tmp2 := dataptr^[DCTSIZE*2] + dataptr^[DCTSIZE*5]; + tmp5 := dataptr^[DCTSIZE*2] - dataptr^[DCTSIZE*5]; + tmp3 := dataptr^[DCTSIZE*3] + dataptr^[DCTSIZE*4]; + tmp4 := dataptr^[DCTSIZE*3] - dataptr^[DCTSIZE*4]; + + { Even part per LL&M figure 1 --- note that published figure is faulty; + rotator "sqrt(2)*c1" should be "sqrt(2)*c6". } + + tmp10 := tmp0 + tmp3; + tmp13 := tmp0 - tmp3; + tmp11 := tmp1 + tmp2; + tmp12 := tmp1 - tmp2; + + dataptr^[DCTSIZE*0] := DCTELEM (DESCALE(tmp10 + tmp11, PASS1_BITS)); + dataptr^[DCTSIZE*4] := DCTELEM (DESCALE(tmp10 - tmp11, PASS1_BITS)); + + z1 := MULTIPLY(tmp12 + tmp13, FIX_0_541196100); + dataptr^[DCTSIZE*2] := DCTELEM (DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865), + CONST_BITS+PASS1_BITS)); + dataptr^[DCTSIZE*6] := DCTELEM (DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065), + CONST_BITS+PASS1_BITS)); + + { Odd part per figure 8 --- note paper omits factor of sqrt(2). + cK represents cos(K*pi/16). + i0..i3 in the paper are tmp4..tmp7 here. } + + z1 := tmp4 + tmp7; + z2 := tmp5 + tmp6; + z3 := tmp4 + tmp6; + z4 := tmp5 + tmp7; + z5 := MULTIPLY(z3 + z4, FIX_1_175875602); { sqrt(2) * c3 } + + tmp4 := MULTIPLY(tmp4, FIX_0_298631336); { sqrt(2) * (-c1+c3+c5-c7) } + tmp5 := MULTIPLY(tmp5, FIX_2_053119869); { sqrt(2) * ( c1+c3-c5+c7) } + tmp6 := MULTIPLY(tmp6, FIX_3_072711026); { sqrt(2) * ( c1+c3+c5-c7) } + tmp7 := MULTIPLY(tmp7, FIX_1_501321110); { sqrt(2) * ( c1+c3-c5-c7) } + z1 := MULTIPLY(z1, - FIX_0_899976223); { sqrt(2) * (c7-c3) } + z2 := MULTIPLY(z2, - FIX_2_562915447); { sqrt(2) * (-c1-c3) } + z3 := MULTIPLY(z3, - FIX_1_961570560); { sqrt(2) * (-c3-c5) } + z4 := MULTIPLY(z4, - FIX_0_390180644); { sqrt(2) * (c5-c3) } + + Inc(z3, z5); + Inc(z4, z5); + + dataptr^[DCTSIZE*7] := DCTELEM (DESCALE(tmp4 + z1 + z3, + CONST_BITS+PASS1_BITS)); + dataptr^[DCTSIZE*5] := DCTELEM (DESCALE(tmp5 + z2 + z4, + CONST_BITS+PASS1_BITS)); + dataptr^[DCTSIZE*3] := DCTELEM (DESCALE(tmp6 + z2 + z3, + CONST_BITS+PASS1_BITS)); + dataptr^[DCTSIZE*1] := DCTELEM (DESCALE(tmp7 + z1 + z4, + CONST_BITS+PASS1_BITS)); + + Inc(DCTELEMPTR(dataptr)); { advance pointer to next column } + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jidct2d_del.pas b/mseide-msegui/lib/common/fpccompatibility/jidct2d_del.pas new file mode 100644 index 0000000..68933f3 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jidct2d_del.pas @@ -0,0 +1,1048 @@ +Unit JIDct2D; + +{ This file contains a fast, not so accurate integer implementation of the + inverse DCT (Discrete Cosine Transform). In the IJG code, this routine + must also perform dequantization of the input coefficients. + + + A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT + on each row (or vice versa, but it's more convenient to emit a row at + a time). Direct algorithms are also available, but they are much more + complex and seem not to be any faster when reduced to code. + + The Feig direct 2D scaled Discrete Cosine Transform extends Arai, Agui + and Nakajima fast scaled DCT to 2D (464 adds and 80 mult.) with further + computational saving (462 adds, 54 mults and 6 shits). + + The forward DCT is described with flow diagrams from the Pennebaker& + Mitchell JPEG book. The inverse DCT flow diagrams are obtained + from the inverse matrices. Scaling must be done accordingly. + + Jacques NOMSSI NZALI, May 16th 1995 } + + +interface + +uses + jmorecfg, + jinclude, + jpeglib, + jdct; { Private declarations for DCT subsystem } + +{$I jconfig_del.inc} + +{ Perform dequantization and inverse DCT on one block of coefficients. } + +{GLOBAL} +procedure jpeg_idct_i2d (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + coef_block : JCOEFPTR; + output_buf : JSAMPARRAY; + output_col : JDIMENSION); + +implementation + +{ This module is specialized to the case DCTSIZE = 8. } + +{$ifndef DCTSIZE_IS_8} + Sorry, this code only copes with 8x8 DCTs. { deliberate syntax err } +{$endif} + +{ Scaling decisions are generally the same as in the LL&M algorithm; + see jidctint.c for more details. However, we choose to descale + (right shift) multiplication products as soon as they are formed, + rather than carrying additional fractional bits into subsequent additions. + This compromises accuracy slightly, but it lets us save a few shifts. + More importantly, 16-bit arithmetic is then adequate (for 8-bit samples) + everywhere except in the multiplications proper; this saves a good deal + of work on 16-bit-int machines. + + The dequantized coefficients are not integers because the AA&N scaling + factors have been incorporated. We represent them scaled up by PASS1_BITS, + so that the first and second IDCT rounds have the same input scaling. + For 8-bit JSAMPLEs, we choose IFAST_SCALE_BITS = PASS1_BITS so as to + avoid a descaling shift; this compromises accuracy rather drastically + for small quantization table entries, but it saves a lot of shifts. + For 12-bit JSAMPLEs, there's no hope of using 16x16 multiplies anyway, + so we use a much larger scaling factor to preserve accuracy. + + A final compromise is to represent the multiplicative constants to only + 8 fractional bits, rather than 13. This saves some shifting work on some + machines, and may also reduce the cost of multiplication (since there + are fewer one-bits in the constants). } + +{$ifdef BITS_IN_JSAMPLE_IS_8} +const + CONST_BITS = 8; + PASS1_BITS = 2; +{$else} + CONST_BITS = 8; + PASS1_BITS = 1; { lose a little precision to avoid overflow } +{$endif} + + +{ Convert a positive real constant to an integer scaled by CONST_SCALE. } +const + CONST_SCALE = (INT32(1) shl CONST_BITS); +const + FIX_1_082392200 = INT32(Round(CONST_SCALE*1.082392200)); {277} + FIX_1_414213562 = INT32(Round(CONST_SCALE*1.414213562)); {362} + FIX_1_847759065 = INT32(Round(CONST_SCALE*1.847759065)); {473} + FIX_2_613125930 = INT32(Round(CONST_SCALE*2.613125930)); {669} + + +{ Descale and correctly round an INT32 value that's scaled by N bits. + We assume RIGHT_SHIFT rounds towards minus infinity, so adding + the fudge factor is correct for either sign of X. } + +function DESCALE(x : INT32; n : int) : INT32; +var + shift_temp : INT32; +begin +{$ifdef USE_ACCURATE_ROUNDING} + shift_temp := x + (INT32(1) shl (n-1)); +{$else} +{ We can gain a little more speed, with a further compromise in accuracy, + by omitting the addition in a descaling shift. This yields an incorrectly + rounded result half the time... } + shift_temp := x; +{$endif} + +{$ifdef RIGHT_SHIFT_IS_UNSIGNED} + if shift_temp < 0 then + Descale := (shift_temp shr n) or ((not INT32(0)) shl (32-n)) + else +{$endif} + Descale := (shift_temp shr n); + +end; + + +{ Multiply a DCTELEM variable by an INT32 constant, and immediately + descale to yield a DCTELEM result. } + + {(DCTELEM( DESCALE((var) * (const), CONST_BITS))} + function Multiply(Avar, Aconst: Integer): DCTELEM; + begin + Multiply := DCTELEM( Avar*INT32(Aconst) div CONST_SCALE); + end; + + + +{ Dequantize a coefficient by multiplying it by the multiplier-table + entry; produce a DCTELEM result. For 8-bit data a 16x16->16 + multiplication will do. For 12-bit data, the multiplier table is + declared INT32, so a 32-bit multiply will be used. } + +{$ifdef BITS_IN_JSAMPLE_IS_8} + function DEQUANTIZE(coef,quantval : int) : int; + begin + Dequantize := ( IFAST_MULT_TYPE(coef) * quantval); + end; + +{$else} +#define DEQUANTIZE(coef,quantval) \ + DESCALE((coef)*(quantval), IFAST_SCALE_BITS-PASS1_BITS) +{$endif} + + +{ Like DESCALE, but applies to a DCTELEM and produces an int. + We assume that int right shift is unsigned if INT32 right shift is. } + +function IDESCALE(x : DCTELEM; n : int) : int; +{$ifdef BITS_IN_JSAMPLE_IS_8} +const + DCTELEMBITS = 16; { DCTELEM may be 16 or 32 bits } +{$else} +const + DCTELEMBITS = 32; { DCTELEM must be 32 bits } +{$endif} +var + ishift_temp : DCTELEM; +begin +{$ifndef USE_ACCURATE_ROUNDING} + ishift_temp := x + (INT32(1) shl (n-1)); +{$else} +{ We can gain a little more speed, with a further compromise in accuracy, + by omitting the addition in a descaling shift. This yields an incorrectly + rounded result half the time... } + ishift_temp := x; +{$endif} + +{$ifdef RIGHT_SHIFT_IS_UNSIGNED} + if ishift_temp < 0 then + IDescale := (ishift_temp shr n) + or ((not DCTELEM(0)) shl (DCTELEMBITS-n)) + else +{$endif} + IDescale := (ishift_temp shr n); +end; + + + +{ Perform dequantization and inverse DCT on one block of coefficients. } + +{GLOBAL} +procedure jpeg_idct_i2d (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + coef_block : JCOEFPTR; + output_buf : JSAMPARRAY; + output_col : JDIMENSION); +Const + CONST_IC4 = 1.414213562; { 1/0.707106781; } + FP_IC4 = FIX_1_414213562; + FP_I_C4_2 = FP_IC4; + +type + PWorkspace = ^TWorkspace; + TWorkspace = coef_bits_field; { buffers data between passes } + + Procedure N1(var x, y : integer); { rotator 1 } + Const + FP_a5 = FIX_1_847759065; + FP_a4 = FIX_2_613125930; + FP_a2 = FIX_1_082392200; + var + z5, tmp : integer; + begin + tmp := x; + + z5 := Multiply(tmp + y, FP_a5); { c6 } + x := Multiply(y, FP_a2) - z5; { c2-c6 } + y := Multiply(tmp, -FP_a4) + z5; { c2+c6 } + end; + + Procedure N2(var x, y : integer); { N1 scaled by c4 } + Const + FP_b5 = Integer(Round(CONST_SCALE*1.847759065*CONST_IC4)); + FP_b4 = Integer(Round(CONST_SCALE*2.613125930*CONST_IC4)); + FP_b2 = Integer(Round(CONST_SCALE*1.082392200*CONST_IC4)); + var + z5, tmp : integer; + begin + tmp := x; + + z5 := Multiply(tmp + y, FP_b5); + x := Multiply(y, FP_b2) - z5; + y := Multiply(tmp,-FP_b4) + z5; + end; + +var + column, row : byte; + +var + tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7 : DCTELEM; + tmp10, tmp11, tmp12, tmp13 : DCTELEM; + z10, z11, z12, z13 : DCTELEM; + inptr : JCOEFPTR; + + quantptr : IFAST_MULT_TYPE_FIELD_PTR; + wsptr : PWorkspace; + outptr : JSAMPROW; + range_limit : JSAMPROW; + ctr : int; + workspace : TWorkspace; { buffers data between passes } + {SHIFT_TEMPS { for DESCALE } + {ISHIFT_TEMPS { for IDESCALE } +var + dcval : int; +var + dcval_ : JSAMPLE; +begin +{ Each IDCT routine is responsible for range-limiting its results and + converting them to unsigned form (0..MAXJSAMPLE). The raw outputs could + be quite far out of range if the input data is corrupt, so a bulletproof + range-limiting step is required. We use a mask-and-table-lookup method + to do the combined operations quickly. See the comments with + prepare_range_limit_table (in jdmaster.c) for more info. } + + range_limit := JSAMPROW(@(cinfo^.sample_range_limit^[CENTERJSAMPLE])); + { Pass 1: process columns from input, store into work array. } + + inptr := coef_block; + quantptr := IFAST_MULT_TYPE_FIELD_PTR(compptr^.dct_table); + wsptr := @workspace; + for ctr := pred(DCTSIZE) downto 0 do + begin + { short-circuiting is not easily done here } + // bbo := @outptr; + for num := 0 to Pred(count) do + begin + { R1 x R1 } + for column := 7 downto 0 do + BEGIN + tmp5 := inptr^[1*RowSize + column]; + + inptr^[1*RowSize + column] := inptr^[4*RowSize + column]; + + tmp7 := inptr^[3*RowSize + column]; + + a := inptr^[2*RowSize + column]; + b := inptr^[6*RowSize + column]; + inptr^[2*RowSize + column] := a - b; + inptr^[3*RowSize + column] := a + b; + + a := inptr^[5*RowSize + column]; + inptr^[4*RowSize + column] := a - tmp7; + z13 := a + tmp7; + + b := inptr^[7*RowSize + column]; + inptr^[6*RowSize + column] := tmp5 - b; + z11 := tmp5 + b; + + inptr^[5*RowSize + column] := z11 - z13; + inptr^[7*RowSize + column] := z11 + z13; + END; + + { Even part } + + tmp0 := DEQUANTIZE(inptr^[DCTSIZE*0], quantptr^[DCTSIZE*0]); + tmp1 := DEQUANTIZE(inptr^[DCTSIZE*2], quantptr^[DCTSIZE*2]); + tmp2 := DEQUANTIZE(inptr^[DCTSIZE*4], quantptr^[DCTSIZE*4]); + tmp3 := DEQUANTIZE(inptr^[DCTSIZE*6], quantptr^[DCTSIZE*6]); + + tmp10 := tmp0 + tmp2; { phase 3 } + tmp11 := tmp0 - tmp2; + + tmp13 := tmp1 + tmp3; { phases 5-3 } + tmp12 := MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; { 2*c4 } + + tmp0 := tmp10 + tmp13; { phase 2 } + tmp3 := tmp10 - tmp13; + tmp1 := tmp11 + tmp12; + tmp2 := tmp11 - tmp12; + + { Odd part } + + tmp4 := DEQUANTIZE(inptr^[DCTSIZE*1], quantptr^[DCTSIZE*1]); + tmp5 := DEQUANTIZE(inptr^[DCTSIZE*3], quantptr^[DCTSIZE*3]); + tmp6 := DEQUANTIZE(inptr^[DCTSIZE*5], quantptr^[DCTSIZE*5]); + tmp7 := DEQUANTIZE(inptr^[DCTSIZE*7], quantptr^[DCTSIZE*7]); + + z13 := tmp6 + tmp5; { phase 6 } + z10 := tmp6 - tmp5; + z11 := tmp4 + tmp7; + z12 := tmp4 - tmp7; + + tmp7 := z11 + z13; { phase 5 } + tmp11 := MULTIPLY(z11 - z13, FIX_1_414213562); { 2*c4 } + + z5 := MULTIPLY(z10 + z12, FIX_1_847759065); { 2*c2 } + tmp10 := MULTIPLY(z12, FIX_1_082392200) - z5; { 2*(c2-c6) } + tmp12 := MULTIPLY(z10, - FIX_2_613125930) + z5; { -2*(c2+c6) } + + tmp6 := tmp12 - tmp7; { phase 2 } + tmp5 := tmp11 - tmp6; + tmp4 := tmp10 + tmp5; + + wsptr^[DCTSIZE*0] := int (tmp0 + tmp7); + wsptr^[DCTSIZE*7] := int (tmp0 - tmp7); + wsptr^[DCTSIZE*1] := int (tmp1 + tmp6); + wsptr^[DCTSIZE*6] := int (tmp1 - tmp6); + wsptr^[DCTSIZE*2] := int (tmp2 + tmp5); + wsptr^[DCTSIZE*5] := int (tmp2 - tmp5); + wsptr^[DCTSIZE*4] := int (tmp3 + tmp4); + wsptr^[DCTSIZE*3] := int (tmp3 - tmp4); + + Inc(JCOEF_PTR(inptr)); { advance pointers to next column } + Inc(IFAST_MULT_TYPE_PTR(quantptr)); + Inc(int_ptr(wsptr)); + end; + + { Pass 2: process rows from work array, store into output array. } + { Note that we must descale the results by a factor of 8 == 2**3, } + { and also undo the PASS1_BITS scaling. } + + wsptr := @workspace; + for ctr := 0 to pred(DCTSIZE) do + begin + outptr := JSAMPROW(@output_buf^[ctr]^[output_col]); + { Rows of zeroes can be exploited in the same way as we did with columns. + However, the column calculation has created many nonzero AC terms, so + the simplification applies less often (typically 5% to 10% of the time). + On machines with very fast multiplication, it's possible that the + test takes more time than it's worth. In that case this section + may be commented out. } + +{$ifndef NO_ZERO_ROW_TEST} + if ((wsptr^[1]) or (wsptr^[2]) or (wsptr^[3]) or (wsptr^[4]) or (wsptr^[5]) or + (wsptr^[6]) or (wsptr^[7]) = 0) then + begin + { AC terms all zero } + JSAMPLE(dcval_) := range_limit^[IDESCALE(wsptr^[0], PASS1_BITS+3) + and RANGE_MASK]; + + outptr^[0] := dcval_; + outptr^[1] := dcval_; + outptr^[2] := dcval_; + outptr^[3] := dcval_; + outptr^[4] := dcval_; + outptr^[5] := dcval_; + outptr^[6] := dcval_; + outptr^[7] := dcval_; + + Inc(int_ptr(wsptr), DCTSIZE); { advance pointer to next row } + continue; + end; +{$endif} + + { Even part } + + tmp10 := (DCTELEM(wsptr^[0]) + DCTELEM(wsptr^[4])); + tmp11 := (DCTELEM(wsptr^[0]) - DCTELEM(wsptr^[4])); + + tmp13 := (DCTELEM(wsptr^[2]) + DCTELEM(wsptr^[6])); + tmp12 := MULTIPLY(DCTELEM(wsptr^[2]) - DCTELEM(wsptr^[6]), FIX_1_414213562) + - tmp13; + + tmp0 := tmp10 + tmp13; + tmp3 := tmp10 - tmp13; + tmp1 := tmp11 + tmp12; + tmp2 := tmp11 - tmp12; + + { Odd part } + + z13 := DCTELEM(wsptr^[5]) + DCTELEM(wsptr^[3]); + z10 := DCTELEM(wsptr^[5]) - DCTELEM(wsptr^[3]); + z11 := DCTELEM(wsptr^[1]) + DCTELEM(wsptr^[7]); + z12 := DCTELEM(wsptr^[1]) - DCTELEM(wsptr^[7]); + + tmp7 := z11 + z13; { phase 5 } + tmp11 := MULTIPLY(z11 - z13, FIX_1_414213562); { 2*c4 } + + z5 := MULTIPLY(z10 + z12, FIX_1_847759065); { 2*c2 } + tmp10 := MULTIPLY(z12, FIX_1_082392200) - z5; { 2*(c2-c6) } + tmp12 := MULTIPLY(z10, - FIX_2_613125930) + z5; { -2*(c2+c6) } + + tmp6 := tmp12 - tmp7; { phase 2 } + tmp5 := tmp11 - tmp6; + tmp4 := tmp10 + tmp5; + + { Final output stage: scale down by a factor of 8 and range-limit } + + outptr^[0] := range_limit^[IDESCALE(tmp0 + tmp7, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[7] := range_limit^[IDESCALE(tmp0 - tmp7, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[1] := range_limit^[IDESCALE(tmp1 + tmp6, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[6] := range_limit^[IDESCALE(tmp1 - tmp6, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[2] := range_limit^[IDESCALE(tmp2 + tmp5, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[5] := range_limit^[IDESCALE(tmp2 - tmp5, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[4] := range_limit^[IDESCALE(tmp3 + tmp4, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[3] := range_limit^[IDESCALE(tmp3 - tmp4, PASS1_BITS+3) + and RANGE_MASK]; + + Inc(int_ptr(wsptr), DCTSIZE); { advance pointer to next row } + end; +end; + +end. +---------------------------------------------------------- +type + matasm = array[0..DCTSIZE2-1] of integer; + bmatrix = array[0..DCTSIZE2-1] of byte; + bmatrixptr = ^bmatrix; +procedure ANN_IDCT(var coef_block :matasm; + var outptr :bmatrix); + + var coeffs :matasm; = coef_block + var outptr :bmatrix); output_buf + +Const + CONST_IC4 = 1.414213562; { 1/0.707106781; } + FP_IC4 = FIX_1_414213562; + FP_I_C4_2 = FP_IC4; + + Function Descale(x : integer):byte; + var y : integer; + begin + y := (x + (1 shl (16-1))+ (4 shl PASS_BITS)) div (8 shl PASS_BITS); + { DeScale := x sar (3 + PASS_BITS); + Borland Pascal SHR is unsigned } + if y < 0 then + descale := 0 + else + if y > $ff then + descale := $ff + else + descale := y; + end; + + function Multiply(X, Y: Integer): integer; assembler; + asm + mov ax, X + imul Y + mov al, ah + mov ah, dl + end; + + +Const + RowSize = 8; +var + a, b : integer; + + inptr : JCOEFPTR; + + outptr : bmatrixptr; + + num : integer; +begin +{ Each IDCT routine is responsible for range-limiting its results and + converting them to unsigned form (0..MAXJSAMPLE). The raw outputs could + be quite far out of range if the input data is corrupt, so a bulletproof + range-limiting step is required. We use a mask-and-table-lookup method + to do the combined operations quickly. See the comments with + prepare_range_limit_table (in jdmaster.c) for more info. } + + range_limit := JSAMPROW(@(cinfo^.sample_range_limit^[CENTERJSAMPLE])); + { Pass 1: process columns from input, store into work array. } + + inptr := @coef_block; + ctr*RowSize + quantptr := IFAST_MULT_TYPE_FIELD_PTR(compptr^.dct_table); + + for ctr := pred(DCTSIZE) downto 0 do + BEGIN + tmp5 := inptr^[1]; + + inptr^[1] := inptr^[4]; + + tmp7 := inptr^[3]; + + a := inptr^[2]; + b := inptr^[6]; + inptr^[2] := a - b; + inptr^[3] := a + b; + + a := inptr^[5]; + inptr^[+ 4] := a - tmp7; + z13 := a + tmp7; + + b := inptr^[7]; + inptr^[6] := tmp5 - b; + z11 := tmp5 + b; + + inptr^[5] := z11 - z13; + inptr^[7] := z11 + z13; + END; + + { M x M tensor } + for row := 0 to 7 do + Case row of + 0,1,3,7: { M1 } + begin + inptr^[row*RowSize + 2] := Multiply(inptr^[row*RowSize + 2], FP_IC4); { 2/c4 } + inptr^[row*RowSize + 5] := Multiply(inptr^[row*RowSize + 5], FP_IC4); { 2/c4 } + + N1(inptr^[row*RowSize + 4], inptr^[row*RowSize + 6]); + end; + 2,5: { M2 } + begin + inptr^[row*RowSize + 0] := Multiply(inptr^[row*RowSize + 0], FP_IC4); + inptr^[row*RowSize + 1] := Multiply(inptr^[row*RowSize + 1], FP_IC4); + inptr^[row*RowSize + 3] := Multiply(inptr^[row*RowSize + 3], FP_IC4); + inptr^[row*RowSize + 7] := Multiply(inptr^[row*RowSize + 7], FP_IC4); + + inptr^[row*RowSize + 2] := inptr^[row*RowSize + 2] * 2; { shift } + inptr^[row*RowSize + 5] := inptr^[row*RowSize + 5] * 2; + + N2(inptr^[row*RowSize + 4], inptr^[row*RowSize + 6]); + end; + end; { Case } + + { M x N tensor } + { rows 4,6 } + begin + N1(inptr^[4*RowSize + 0], inptr^[6*RowSize + 0]); + N1(inptr^[4*RowSize + 1], inptr^[6*RowSize + 1]); + N1(inptr^[4*RowSize + 3], inptr^[6*RowSize + 3]); + N1(inptr^[4*RowSize + 7], inptr^[6*RowSize + 7]); + + N2(inptr^[4*RowSize + 2], inptr^[6*RowSize + 2]); + N2(inptr^[4*RowSize + 5], inptr^[6*RowSize + 5]); + + { N3 } + { two inverse matrices => same as FDCT } + tmp0 := inptr^[4*RowSize + 4]; + tmp3 := inptr^[6*RowSize + 6]; + tmp12 := (tmp0 + tmp3) * 2; + z10 := tmp0 - tmp3; + + tmp1 := inptr^[6*RowSize + 4]; + tmp2 := inptr^[4*RowSize + 6]; + tmp13 :=-(tmp1 - tmp2)*2; + z11 := tmp1 + tmp2; + + tmp0 := Multiply(z10 + z11, FP_I_C4_2); + tmp1 := Multiply(z10 - z11, FP_I_C4_2); + + + inptr^[4*RowSize + 4] := tmp12 + tmp0; + inptr^[6*RowSize + 4] := tmp1 + tmp13; + + inptr^[4*RowSize + 6] := tmp1 - tmp13; + inptr^[6*RowSize + 6] := tmp12 - tmp0; + end; + + { R2 x R2 } + + for row := 0 to 7 do + BEGIN + { Odd part } + tmp7 := inptr^[row*RowSize + 7]; + tmp6 := inptr^[row*RowSize + 6] - tmp7; + tmp5 := inptr^[row*RowSize + 5] - tmp6; + tmp4 :=-inptr^[row*RowSize + 4] - tmp5; + + { even part } + tmp0 := inptr^[row*RowSize + 0]; + tmp1 := inptr^[row*RowSize + 1]; + tmp10 := tmp0 + tmp1; + tmp11 := tmp0 - tmp1; + + tmp2 := inptr^[row*RowSize + 2]; + tmp13 := inptr^[row*RowSize + 3]; + tmp12 := tmp2 - tmp13; + + tmp0 := tmp10 + tmp13; + tmp3 := tmp10 - tmp13; + inptr^[row*RowSize + 0] := (tmp0 + tmp7); + inptr^[row*RowSize + 7] := (tmp0 - tmp7); + + inptr^[row*RowSize + 3] := (tmp3 + tmp4); + inptr^[row*RowSize + 4] := (tmp3 - tmp4); + + tmp1 := tmp11 + tmp12; + tmp2 := tmp11 - tmp12; + + inptr^[row*RowSize + 1] := (tmp1 + tmp6); + inptr^[row*RowSize + 6] := (tmp1 - tmp6); + + inptr^[row*RowSize + 2] := (tmp2 + tmp5); + inptr^[row*RowSize + 5] := (tmp2 - tmp5); + END; + + for ctr := 0 to pred(DCTSIZE) do + BEGIN + outptr := JSAMPROW(@output_buf^[ctr]^[output_col]); + { even part } + tmp0 := inptr^[0*RowSize + ctr]; + tmp1 := inptr^[1*RowSize + ctr]; + tmp2 := inptr^[2*RowSize + ctr]; + tmp3 := inptr^[3*RowSize + ctr]; + + tmp10 := tmp0 + tmp1; + tmp11 := tmp0 - tmp1; + + tmp13 := tmp3; + tmp12 := tmp2 - tmp3; + + tmp0 := tmp10 + tmp13; + tmp3 := tmp10 - tmp13; + + tmp1 := tmp11 + tmp12; + tmp2 := tmp11 - tmp12; + + { Odd part } + tmp4 := inptr^[4*RowSize + ctr]; + tmp5 := inptr^[5*RowSize + ctr]; + tmp6 := inptr^[6*RowSize + ctr]; + tmp7 := inptr^[7*RowSize + ctr]; + + tmp6 := tmp6 - tmp7; + tmp5 := tmp5 - tmp6; + tmp4 :=-tmp4 - tmp5; + + outptr^[0*RowSize + ctr] := DeScale(tmp0 + tmp7); + outptr^[7*RowSize + ctr] := DeScale(tmp0 - tmp7); + + outptr^[1*RowSize + ctr] := DeScale(tmp1 + tmp6); + outptr^[6*RowSize + ctr] := DeScale(tmp1 - tmp6); + + outptr^[2*RowSize + ctr] := DeScale(tmp2 + tmp5); + outptr^[5*RowSize + ctr] := DeScale(tmp2 - tmp5); + + outptr^[3*RowSize + ctr] := DeScale(tmp3 + tmp4); + outptr^[4*RowSize + ctr] := DeScale(tmp3 - tmp4); + + + { Final output stage: scale down by a factor of 8 and range-limit } + + outptr^[0] := range_limit^[IDESCALE(tmp0 + tmp7, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[7] := range_limit^[IDESCALE(tmp0 - tmp7, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[1] := range_limit^[IDESCALE(tmp1 + tmp6, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[6] := range_limit^[IDESCALE(tmp1 - tmp6, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[2] := range_limit^[IDESCALE(tmp2 + tmp5, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[5] := range_limit^[IDESCALE(tmp2 - tmp5, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[4] := range_limit^[IDESCALE(tmp3 + tmp4, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[3] := range_limit^[IDESCALE(tmp3 - tmp4, PASS1_BITS+3) + and RANGE_MASK]; + END; + + Inc(bbo); + Inc(inptr); + End; +End; {----------------------------------------} + + +{GLOBAL} +procedure jpeg_idct_i2d (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + coef_block : JCOEFPTR; + output_buf : JSAMPARRAY; + output_col : JDIMENSION); + +procedure Feig_2D_IDCT(coef_block :imatrix; + output_buf : JSAMPARRAY); +Const + CONST_IC4 = 1.414213562; { 1/0.707106781; } + FP_IC4 = Integer(Round(IFX_CONST*CONST_IC4)); + FP_I_C4_2 = FP_IC4; + + Function Descale(x : integer):integer; + begin + DeScale := (x+ (4 shl PASS_BITS)) div (8 shl PASS_BITS); + { DeScale := x sar (3 + PASS_BITS); + Borland Pascal SHR is unsigned } + end; + { + function Multiply(X, Y: Integer): integer; + begin + Multiply := Integer( X*LongInt(Y) div IFX_CONST); + end; + } + function Multiply(X, Y: Integer): integer; assembler; + asm + mov ax, X + imul Y + mov al, ah + mov ah, dl + end; + + +var + z10, z11, z12, z13, + tmp0,tmp1,tmp2,tmp3, + tmp4,tmp5,tmp6,tmp7, + tmp10,tmp11, + tmp12,tmp13 : integer; + column, row : byte; + + Procedure N1(var x, y : integer); { rotator 1 } + Const + FP_a5 = Integer(Round(IFX_CONST*1.847759065)); + FP_a4 = Integer(Round(IFX_CONST*2.613125930)); + FP_a2 = Integer(Round(IFX_CONST*1.082392200)); + var + z5, tmp : integer; + begin + tmp := x; + + z5 := Multiply(tmp + y, FP_a5); { c6 } + x := Multiply(y, FP_a2) - z5; { c2-c6 } + y := Multiply(tmp, -FP_a4) + z5; { c2+c6 } + end; + + Procedure N2(var x, y : integer); { N1 scaled by c4 } + Const + FP_b5 = Integer(Round(IFX_CONST*1.847759065*CONST_IC4)); + FP_b4 = Integer(Round(IFX_CONST*2.613125930*CONST_IC4)); + FP_b2 = Integer(Round(IFX_CONST*1.082392200*CONST_IC4)); + var + z5, tmp : integer; + begin + tmp := x; + + z5 := Multiply(tmp + y, FP_b5); + x := Multiply(y, FP_b2) - z5; + y := Multiply(tmp,-FP_b4) + z5; + end; + +var + tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7 : DCTELEM; + tmp10, tmp11, tmp12, tmp13 : DCTELEM; + z10, z11, z12, z13 : DCTELEM; + inptr : JCOEFPTR; + + quantptr : IFAST_MULT_TYPE_FIELD_PTR; + wsptr : PWorkspace; + outptr : JSAMPROW; + range_limit : JSAMPROW; + ctr : int; + workspace : TWorkspace; { buffers data between passes } + {SHIFT_TEMPS { for DESCALE } + {ISHIFT_TEMPS { for IDESCALE } +var + dcval : int; +var + dcval_ : JSAMPLE; +begin +{ Each IDCT routine is responsible for range-limiting its results and + converting them to unsigned form (0..MAXJSAMPLE). The raw outputs could + be quite far out of range if the input data is corrupt, so a bulletproof + range-limiting step is required. We use a mask-and-table-lookup method + to do the combined operations quickly. See the comments with + prepare_range_limit_table (in jdmaster.c) for more info. } + + range_limit := JSAMPROW(@(cinfo^.sample_range_limit^[CENTERJSAMPLE])); + { Pass 1: process columns from input, store into work array. } + + inptr := coef_block; + quantptr := IFAST_MULT_TYPE_FIELD_PTR(compptr^.dct_table); + wsptr := @workspace; + + { R1 x R1 } + for ctr := pred(DCTSIZE) downto 0 do + BEGIN + { even part } + tmp1 := DEQUANTIZE(inptr^[DCTSIZE*2], quantptr^[DCTSIZE*2]); + tmp3 := DEQUANTIZE(inptr^[DCTSIZE*6], quantptr^[DCTSIZE*6]); + + wsptr^[DCTSIZE*0] := int (DEQUANTIZE(inptr^[DCTSIZE*0], quantptr^[DCTSIZE*0])); + wsptr^[DCTSIZE*1] := int (DEQUANTIZE(inptr^[DCTSIZE*4], quantptr^[DCTSIZE*4]); + + { Odd part } + + tmp6 := DEQUANTIZE(inptr^[DCTSIZE*5], quantptr^[DCTSIZE*5]); + tmp4 := DEQUANTIZE(inptr^[DCTSIZE*1], quantptr^[DCTSIZE*1]); + tmp7 := DEQUANTIZE(inptr^[DCTSIZE*7], quantptr^[DCTSIZE*7]); + tmp5 := DEQUANTIZE(inptr^[DCTSIZE*3], quantptr^[DCTSIZE*3]); + + + z13 := tmp6 + tmp5; + wsptr^[DCTSIZE*4] := int (tmp6 - tmp5); + + z11 := tmp4 + tmp7; + wsptr^[DCTSIZE*6] := int (tmp4 - tmp7); + + wsptr^[DCTSIZE*7] := int (z11 + z13); + wsptr^[DCTSIZE*5] := int (z11 - z13); + + wsptr^[DCTSIZE*3] := int (tmp1 + tmp3); + wsptr^[DCTSIZE*2] := int (tmp1 - tmp3); + + Inc(JCOEF_PTR(inptr)); { advance pointers to next column } + Inc(IFAST_MULT_TYPE_PTR(quantptr)); + Inc(int_ptr(wsptr)); + END; + + wsptr := @workspace[DCTSIZE*pred(DCTSIZE)]; + for row := pred(DCTSIZE) downto 0 do + BEGIN + { Odd part } + tmp5 := DCTELEM(wsptr^[1]); + tmp7 := DCTELEM(wsptr^[3]); + + { even part } + + {noop: + tmp0 := DCTELEM(wsptr^[0]); + wsptr^[0] := DCTELEM(tmp0);} + + {tmp2 := DCTELEM(wsptr^[4]);} + wsptr^[1] := wsptr^[4]; + + tmp1 := DCTELEM(wsptr^[2]); + tmp3 := DCTELEM(wsptr^[6]); + + wsptr^[2] := DCTELEM(tmp1 - tmp3); + wsptr^[3] := DCTELEM(tmp1 + tmp3); + + { Odd part } + tmp4 := DCTELEM(wsptr^[5]); + tmp6 := DCTELEM(wsptr^[7]); + + z13 := tmp4 + tmp7; + wsptr^[4] := DCTELEM(tmp4 - tmp7); + + z11 := tmp5 + tmp6; + wsptr^[6] := DCTELEM(tmp5 - tmp6); + + wsptr^[7] := DCTELEM(z11 + z13); + wsptr^[5] := DCTELEM(z11 - z13); + Dec(int_ptr(wsptr), DCTSIZE); { advance pointer to previous row } + END; + + { M x M tensor } + wsptr := @workspace[DCTSIZE*0]; + for row := 0 to pred(DCTSIZE) do + begin + Case row of + 0,1,3,7: { M1 } + begin + wsptr^[2] := Multiply(wsptr^[2], FP_IC4); { 2/c4 } + wsptr^[5] := Multiply(wsptr^[5], FP_IC4); { 2/c4 } + + N1(wsptr^[ 4], wsptr^[ 6]); + end; + 2,5: { M2 } + begin + wsptr^[0] := Multiply(wsptr^[0], FP_IC4); + wsptr^[1] := Multiply(wsptr^[1], FP_IC4); + wsptr^[3] := Multiply(wsptr^[3], FP_IC4); + wsptr^[7] := Multiply(wsptr^[7], FP_IC4); + + wsptr^[2] := wsptr^[2] * 2; { shift } + wsptr^[5] := wsptr^[5] * 2; + + N2(wsptr^[4], wsptr^[6]); + end; + end; { Case } + Inc(int_ptr(wsptr), DCTSIZE); { advance pointer to next row } + end; + + { M x N tensor } + { rows 4,6 } + begin + N1(workspace[DCTSIZE*4+0], workspace[DCTSIZE*6+0]); + N1(workspace[DCTSIZE*4+1], workspace[DCTSIZE*6+1]); + N1(workspace[DCTSIZE*4+3], workspace[DCTSIZE*6+3]); + N1(workspace[DCTSIZE*4+7], workspace[DCTSIZE*6+7]); + + N2(workspace[DCTSIZE*4+2], workspace[DCTSIZE*6+2]); + N2(workspace[DCTSIZE*4+5], workspace[DCTSIZE*6+5]); + + { N3 } + tmp0 := workspace[DCTSIZE*4,4]; + tmp1 := workspace[DCTSIZE*6,4]; + tmp2 := workspace[DCTSIZE*4,6]; + tmp3 := workspace[DCTSIZE*6,6]; + + { two inverse matrices => same as FDCT } + z10 := tmp0 - tmp3; + z11 := tmp1 + tmp2; + + z12 := tmp0 + tmp3; + z13 := tmp1 - tmp2; + + tmp0 := Multiply(z10 + z11, FP_I_C4_2); + tmp1 := Multiply(z10 - z11, FP_I_C4_2); + + tmp2 := z12 * 2; { shifts } + tmp3 := z13 * (-2); + + + workspace[DCTSIZE*4,4] := tmp2 + tmp0; + workspace[DCTSIZE*6,4] := tmp1 + tmp3; + + workspace[DCTSIZE*4,6] := tmp1 - tmp3; + workspace[DCTSIZE*6,6] := tmp2 - tmp0; + end; + + { R2 x R2 } + + wsptr := @workspace; + for row := 0 to pred(DCTSIZE) do + BEGIN + { even part } + tmp0 := wsptr^[0]; + tmp2 := wsptr^[1]; + tmp1 := wsptr^[2]; + tmp3 := wsptr^[3]; + + tmp10 := tmp0 + tmp2; + tmp11 := tmp0 - tmp2; + + tmp12 := tmp1 - tmp3; + tmp13 := tmp3; + + tmp0 := tmp10 + tmp13; + tmp3 := tmp10 - tmp13; + + tmp2 := tmp11 + tmp12; + tmp1 := tmp11 - tmp12; + + { Odd part } + tmp4 := wsptr^[4]; + tmp5 := wsptr^[5]; + tmp6 := wsptr^[6]; + tmp7 := wsptr^[7]; + + tmp6 := tmp6 - tmp7; + tmp5 := tmp5 - tmp6; + tmp4 :=-tmp4 - tmp5; + + wsptr^[0] := (tmp0 + tmp7); + wsptr^[7] := (tmp0 - tmp7); + + wsptr^[1] := (tmp2 + tmp6); + wsptr^[6] := (tmp2 - tmp6); + + wsptr^[2] := (tmp1 + tmp5); + wsptr^[5] := (tmp1 - tmp5); + + wsptr^[3] := (tmp3 + tmp4); + wsptr^[4] := (tmp3 - tmp4); + + Inc(int_ptr(wsptr), DCTSIZE); { advance pointer to next row } + END; + + wsptr := @workspace; + for ctr := 0 to pred(DCTSIZE) do + BEGIN + outptr := JSAMPROW(@output_buf^[ctr]^[output_col]); + { even part } + tmp0 := wsptr[0]; + tmp1 := wsptr[1]; + tmp2 := wsptr[2]; + tmp3 := wsptr[3]; + + tmp10 := tmp0 + tmp1; + tmp11 := tmp0 - tmp1; + + tmp13 := tmp3; + tmp12 := tmp2 - tmp3; + + tmp0 := tmp10 + tmp13; + tmp3 := tmp10 - tmp13; + + tmp1 := tmp11 + tmp12; + tmp2 := tmp11 - tmp12; + + { Odd part } + tmp4 := wsptr[4]; + tmp5 := wsptr[5]; + tmp6 := wsptr[6]; + tmp7 := wsptr[7]; + + tmp6 := tmp6 - tmp7; + tmp5 := tmp5 - tmp6; + tmp4 :=-tmp4 - tmp5; + + { Final output stage: scale down by a factor of 8 and range-limit } + + outptr^[0] := range_limit^[IDESCALE(tmp0 + tmp7, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[7] := range_limit^[IDESCALE(tmp0 - tmp7, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[1] := range_limit^[IDESCALE(tmp1 + tmp6, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[6] := range_limit^[IDESCALE(tmp1 - tmp6, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[2] := range_limit^[IDESCALE(tmp2 + tmp5, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[5] := range_limit^[IDESCALE(tmp2 - tmp5, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[4] := range_limit^[IDESCALE(tmp3 + tmp4, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[3] := range_limit^[IDESCALE(tmp3 - tmp4, PASS1_BITS+3) + and RANGE_MASK]; + Inc(int_ptr(wsptr)); + END; +End; {----------------------------------------} + + +{----------------------------------------------------------------------} + diff --git a/mseide-msegui/lib/common/fpccompatibility/jidctasm_del.pas b/mseide-msegui/lib/common/fpccompatibility/jidctasm_del.pas new file mode 100644 index 0000000..a88e08f --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jidctasm_del.pas @@ -0,0 +1,793 @@ +Unit JIDctAsm; + +{ This file contains a slow-but-accurate integer implementation of the + inverse DCT (Discrete Cosine Transform). In the IJG code, this routine + must also perform dequantization of the input coefficients. + + A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT + on each row (or vice versa, but it's more convenient to emit a row at + a time). Direct algorithms are also available, but they are much more + complex and seem not to be any faster when reduced to code. + + This implementation is based on an algorithm described in + C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT + Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics, + Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991. + The primary algorithm described there uses 11 multiplies and 29 adds. + We use their alternate method with 12 multiplies and 32 adds. + The advantage of this method is that no data path contains more than one + multiplication; this allows a very simple and accurate implementation in + scaled fixed-point arithmetic, with a minimal number of shifts. } + +{ Original : jidctint.c ; Copyright (C) 1991-1996, Thomas G. Lane. } +{ ;------------------------------------------------------------------------- + ; JIDCTINT.ASM + ; 80386 protected mode assembly translation of JIDCTINT.C + ; **** Optimized to all hell by Jason M. Felice (jasonf@apk.net) **** + ; **** E-mail welcome **** + ; + ; ** This code does not make O/S calls -- use it for OS/2, Win95, WinNT, + ; ** DOS prot. mode., Linux, whatever... have fun. + ; + ; ** Note, this code is dependant on the structure member order in the .h + ; ** files for the following structures: + ; -- amazingly NOT j_decompress_struct... cool. + ; -- jpeg_component_info (dependant on position of dct_table element) + ; + ; Originally created with the /Fa option of MSVC 4.0 (why work when you + ; don't have to?) + ; + ; (this code, when compiled is 1K bytes smaller than the optimized MSVC + ; release build, not to mention 120-130 ms faster in my profile test with 1 + ; small color and and 1 medium black-and-white jpeg: stats using TASM 4.0 + ; and MSVC 4.0 to create a non-console app; jpeg_idct_islow accumulated + ; 5,760 hits on all trials) + ; + ; TASM -t -ml -os jidctint.asm, jidctint.obj + ;------------------------------------------------------------------------- + Converted to Delphi 2.0 BASM for PasJPEG + by Jacques NOMSSI NZALI + October 13th 1996 + * assumes Delphi "register" calling convention + first 3 parameter are in EAX,EDX,ECX + * register allocation revised +} + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg, + jinclude, + jpeglib, + jdct; { Private declarations for DCT subsystem } + +{ Perform dequantization and inverse DCT on one block of coefficients. } + +{GLOBAL} +procedure jpeg_idct_islow (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + coef_block : JCOEFPTR; + output_buf : JSAMPARRAY; + output_col : JDIMENSION); + +implementation + +{ This module is specialized to the case DCTSIZE = 8. } + +{$ifndef DCTSIZE_IS_8} + Sorry, this code only copes with 8x8 DCTs. { deliberate syntax err } +{$endif} + +{ The poop on this scaling stuff is as follows: + + Each 1-D IDCT step produces outputs which are a factor of sqrt(N) + larger than the true IDCT outputs. The final outputs are therefore + a factor of N larger than desired; since N=8 this can be cured by + a simple right shift at the end of the algorithm. The advantage of + this arrangement is that we save two multiplications per 1-D IDCT, + because the y0 and y4 inputs need not be divided by sqrt(N). + + We have to do addition and subtraction of the integer inputs, which + is no problem, and multiplication by fractional constants, which is + a problem to do in integer arithmetic. We multiply all the constants + by CONST_SCALE and convert them to integer constants (thus retaining + CONST_BITS bits of precision in the constants). After doing a + multiplication we have to divide the product by CONST_SCALE, with proper + rounding, to produce the correct output. This division can be done + cheaply as a right shift of CONST_BITS bits. We postpone shifting + as long as possible so that partial sums can be added together with + full fractional precision. + + The outputs of the first pass are scaled up by PASS1_BITS bits so that + they are represented to better-than-integral precision. These outputs + require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word + with the recommended scaling. (To scale up 12-bit sample data further, an + intermediate INT32 array would be needed.) + + To avoid overflow of the 32-bit intermediate results in pass 2, we must + have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26. Error analysis + shows that the values given below are the most effective. } + +const + CONST_BITS = 13; + +{$ifdef BITS_IN_JSAMPLE_IS_8} +const + PASS1_BITS = 2; +{$else} +const + PASS1_BITS = 1; { lose a little precision to avoid overflow } +{$endif} + +const + CONST_SCALE = (INT32(1) shl CONST_BITS); + +const + FIX_0_298631336 = INT32(Round(CONST_SCALE * 0.298631336)); {2446} + FIX_0_390180644 = INT32(Round(CONST_SCALE * 0.390180644)); {3196} + FIX_0_541196100 = INT32(Round(CONST_SCALE * 0.541196100)); {4433} + FIX_0_765366865 = INT32(Round(CONST_SCALE * 0.765366865)); {6270} + FIX_0_899976223 = INT32(Round(CONST_SCALE * 0.899976223)); {7373} + FIX_1_175875602 = INT32(Round(CONST_SCALE * 1.175875602)); {9633} + FIX_1_501321110 = INT32(Round(CONST_SCALE * 1.501321110)); {12299} + FIX_1_847759065 = INT32(Round(CONST_SCALE * 1.847759065)); {15137} + FIX_1_961570560 = INT32(Round(CONST_SCALE * 1.961570560)); {16069} + FIX_2_053119869 = INT32(Round(CONST_SCALE * 2.053119869)); {16819} + FIX_2_562915447 = INT32(Round(CONST_SCALE * 2.562915447)); {20995} + FIX_3_072711026 = INT32(Round(CONST_SCALE * 3.072711026)); {25172} + + +{ for DESCALE } +const + ROUND_CONST = (INT32(1) shl (CONST_BITS-PASS1_BITS-1)); +const + ROUND_CONST_2 = (INT32(1) shl (CONST_BITS+PASS1_BITS+3-1)); + +{ Perform dequantization and inverse DCT on one block of coefficients. } + +{GLOBAL} +procedure jpeg_idct_islow (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + coef_block : JCOEFPTR; + output_buf : JSAMPARRAY; + output_col : JDIMENSION); +type + PWorkspace = ^TWorkspace; + TWorkspace = coef_bits_field; { buffers data between passes } +const + coefDCTSIZE = DCTSIZE*SizeOf(JCOEF); + wrkDCTSIZE = DCTSIZE*SizeOf(int); +var + tmp0, tmp1, tmp2, tmp3 : INT32; + tmp10, tmp11, tmp12, tmp13 : INT32; + z1, z2, z3, z4, z5 : INT32; +var + inptr : JCOEFPTR; + quantptr : ISLOW_MULT_TYPE_FIELD_PTR; + wsptr : PWorkspace; + outptr : JSAMPROW; +var + range_limit : JSAMPROW; + ctr : int; + workspace : TWorkspace; +var + dcval : int; +var + dcval_ : JSAMPLE; +asm + push edi + push esi + push ebx + + cld { The only direction we use, might as well set it now, as opposed } + { to inside 2 loops. } + +{ Each IDCT routine is responsible for range-limiting its results and + converting them to unsigned form (0..MAXJSAMPLE). The raw outputs could + be quite far out of range if the input data is corrupt, so a bulletproof + range-limiting step is required. We use a mask-and-table-lookup method + to do the combined operations quickly. See the comments with + prepare_range_limit_table (in jdmaster.c) for more info. } + + {range_limit := JSAMPROW(@(cinfo^.sample_range_limit^[CENTERJSAMPLE]));} + mov eax, [eax].jpeg_decompress_struct.sample_range_limit {eax=cinfo} + add eax, (MAXJSAMPLE+1 + CENTERJSAMPLE)*(Type JSAMPLE) + mov range_limit, eax + + { Pass 1: process columns from input, store into work array. } + { Note results are scaled up by sqrt(8) compared to a true IDCT; } + { furthermore, we scale the results by 2**PASS1_BITS. } + + {inptr := coef_block;} + mov esi, ecx { ecx=coef_block } + {quantptr := ISLOW_MULT_TYPE_FIELD_PTR (compptr^.dct_table);} + mov edi, [edx].jpeg_component_info.dct_table { edx=compptr } + + {wsptr := PWorkspace(@workspace);} + lea ecx, workspace + + {for ctr := pred(DCTSIZE) downto 0 do + begin} + mov ctr, DCTSIZE +@loop518: + { Due to quantization, we will usually find that many of the input + coefficients are zero, especially the AC terms. We can exploit this + by short-circuiting the IDCT calculation for any column in which all + the AC terms are zero. In that case each output is equal to the + DC coefficient (with scale factor as needed). + With typical images and quantization tables, half or more of the + column DCT calculations can be simplified this way. } + + {if ((inptr^[DCTSIZE*1]) or (inptr^[DCTSIZE*2]) or (inptr^[DCTSIZE*3]) or + (inptr^[DCTSIZE*4]) or (inptr^[DCTSIZE*5]) or (inptr^[DCTSIZE*6]) or + (inptr^[DCTSIZE*7]) = 0) then + begin} + mov eax, DWORD PTR [esi+coefDCTSIZE*1] + or eax, DWORD PTR [esi+coefDCTSIZE*2] + or eax, DWORD PTR [esi+coefDCTSIZE*3] + mov edx, DWORD PTR [esi+coefDCTSIZE*4] + or eax, edx + or eax, DWORD PTR [esi+coefDCTSIZE*5] + or eax, DWORD PTR [esi+coefDCTSIZE*6] + or eax, DWORD PTR [esi+coefDCTSIZE*7] + jne @loop520 + + { AC terms all zero } + {dcval := ISLOW_MULT_TYPE(inptr^[DCTSIZE*0]) * + (quantptr^[DCTSIZE*0]) shl PASS1_BITS;} + mov eax, DWORD PTR [esi+coefDCTSIZE*0] + imul eax, DWORD PTR [edi+wrkDCTSIZE*0] + shl eax, PASS1_BITS + + {wsptr^[DCTSIZE*0] := dcval; + wsptr^[DCTSIZE*1] := dcval; + wsptr^[DCTSIZE*2] := dcval; + wsptr^[DCTSIZE*3] := dcval; + wsptr^[DCTSIZE*4] := dcval; + wsptr^[DCTSIZE*5] := dcval; + wsptr^[DCTSIZE*6] := dcval; + wsptr^[DCTSIZE*7] := dcval;} + + mov DWORD PTR [ecx+ wrkDCTSIZE*0], eax + mov DWORD PTR [ecx+ wrkDCTSIZE*1], eax + mov DWORD PTR [ecx+ wrkDCTSIZE*2], eax + mov DWORD PTR [ecx+ wrkDCTSIZE*3], eax + mov DWORD PTR [ecx+ wrkDCTSIZE*4], eax + mov DWORD PTR [ecx+ wrkDCTSIZE*5], eax + mov DWORD PTR [ecx+ wrkDCTSIZE*6], eax + mov DWORD PTR [ecx+ wrkDCTSIZE*7], eax + + {Inc(JCOEF_PTR(inptr)); { advance pointers to next column } + {Inc(ISLOW_MULT_TYPE_PTR(quantptr)); + Inc(int_ptr(wsptr)); + continue;} + dec ctr + je @loop519 + + add esi, Type JCOEF + add edi, Type ISLOW_MULT_TYPE + add ecx, Type int { int_ptr } + jmp @loop518 + +@loop520: + + {end;} + + { Even part: reverse the even part of the forward DCT. } + { The rotator is sqrt(2)*c(-6). } + + {z2 := ISLOW_MULT_TYPE(inptr^[DCTSIZE*2]) * quantptr^[DCTSIZE*2]; + z3 := ISLOW_MULT_TYPE(inptr^[DCTSIZE*6]) * quantptr^[DCTSIZE*6]; + + z1 := (z2 + z3) * INT32(FIX_0_541196100); + tmp2 := z1 + INT32(z3) * INT32(- FIX_1_847759065); + tmp3 := z1 + INT32(z2) * INT32(FIX_0_765366865);} + + mov edx, DWORD PTR [esi+coefDCTSIZE*2] + imul edx, DWORD PTR [edi+wrkDCTSIZE*2] {z2} + + mov eax, DWORD PTR [esi+coefDCTSIZE*6] + imul eax, DWORD PTR [edi+wrkDCTSIZE*6] {z3} + + lea ebx, [eax+edx] + imul ebx, FIX_0_541196100 {z1} + + imul eax, (-FIX_1_847759065) + add eax, ebx + mov tmp2, eax + + imul edx, FIX_0_765366865 + add edx, ebx + mov tmp3, edx + + {z2 := ISLOW_MULT_TYPE(inptr^[DCTSIZE*0]) * quantptr^[DCTSIZE*0]; + z3 := ISLOW_MULT_TYPE(inptr^[DCTSIZE*4]) * quantptr^[DCTSIZE*4];} + + mov edx, DWORD PTR [esi+coefDCTSIZE*4] + imul edx, DWORD PTR [edi+wrkDCTSIZE*4] { z3 = edx } + + mov eax, DWORD PTR [esi+coefDCTSIZE*0] + imul eax, DWORD PTR [edi+wrkDCTSIZE*0] { z2 = eax } + + {tmp0 := (z2 + z3) shl CONST_BITS; + tmp1 := (z2 - z3) shl CONST_BITS;} + lea ebx,[eax+edx] + sub eax, edx + shl ebx, CONST_BITS { tmp0 = ebx } + shl eax, CONST_BITS { tmp1 = eax } + + {tmp10 := tmp0 + tmp3; + tmp13 := tmp0 - tmp3;} + mov edx, tmp3 + sub ebx, edx + mov tmp13, ebx + add edx, edx + add ebx, edx + mov tmp10, ebx + + {tmp11 := tmp1 + tmp2; + tmp12 := tmp1 - tmp2;} + mov ebx, tmp2 + sub eax, ebx + mov tmp12, eax + add ebx, ebx + add eax, ebx + mov tmp11, eax + + { Odd part per figure 8; the matrix is unitary and hence its + transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. } + + {tmp0 := ISLOW_MULT_TYPE(inptr^[DCTSIZE*7]) * quantptr^[DCTSIZE*7];} + mov eax, DWORD PTR [esi+coefDCTSIZE*7] + imul eax, DWORD PTR [edi+wrkDCTSIZE*7] + mov edx, eax { edx = tmp0 } + {tmp0 := (tmp0) * INT32(FIX_0_298631336); { sqrt(2) * (-c1+c3+c5-c7) } + imul eax, FIX_0_298631336 + mov tmp0, eax + + {tmp3 := ISLOW_MULT_TYPE(inptr^[DCTSIZE*1]) * quantptr^[DCTSIZE*1];} + mov eax, DWORD PTR [esi+coefDCTSIZE*1] + imul eax, DWORD PTR [edi+wrkDCTSIZE*1] + mov tmp3, eax + + {z1 := tmp0 + tmp3;} + {z1 := (z1) * INT32(- FIX_0_899976223); { sqrt(2) * (c7-c3) } + add eax, edx + imul eax, (-FIX_0_899976223) + mov z1, eax + + {tmp1 := ISLOW_MULT_TYPE(inptr^[DCTSIZE*5]) * quantptr^[DCTSIZE*5];} + mov eax, DWORD PTR [esi+coefDCTSIZE*5] + imul eax, DWORD PTR [edi+wrkDCTSIZE*5] + mov ebx, eax { ebx = tmp1 } + {tmp1 := (tmp1) * INT32(FIX_2_053119869); { sqrt(2) * ( c1+c3-c5+c7) } + imul eax, FIX_2_053119869 + mov tmp1, eax + + {tmp2 := ISLOW_MULT_TYPE(inptr^[DCTSIZE*3]) * quantptr^[DCTSIZE*3];} + mov eax, DWORD PTR [esi+coefDCTSIZE*3] + imul eax, DWORD PTR [edi+wrkDCTSIZE*3] + mov tmp2, eax + + {z3 := tmp0 + tmp2;} + add edx, eax { edx = z3 } + + {z2 := tmp1 + tmp2;} + {z2 := (z2) * INT32(- FIX_2_562915447); { sqrt(2) * (-c1-c3) } + add eax, ebx + imul eax, (-FIX_2_562915447) + mov z2, eax + + {z4 := tmp1 + tmp3;} + add ebx, tmp3 { ebx = z4 } + + {z5 := INT32(z3 + z4) * INT32(FIX_1_175875602); { sqrt(2) * c3 } + lea eax, [edx+ebx] + imul eax, FIX_1_175875602 { eax = z5 } + + {z4 := (z4) * INT32(- FIX_0_390180644); { sqrt(2) * (c5-c3) } + {Inc(z4, z5);} + imul ebx, (-FIX_0_390180644) + add ebx, eax + mov z4, ebx + + {z3 := (z3) * INT32(- FIX_1_961570560); { sqrt(2) * (-c3-c5) } + {Inc(z3, z5);} + imul edx, (-FIX_1_961570560) + add eax, edx { z3 = eax } + + {Inc(tmp0, z1 + z3);} + mov ebx, z1 + add ebx, eax + add tmp0, ebx + + {tmp2 := (tmp2) * INT32(FIX_3_072711026); { sqrt(2) * ( c1+c3+c5-c7) } + {Inc(tmp2, z2 + z3);} + mov ebx, tmp2 + imul ebx, FIX_3_072711026 + mov edx, z2 { z2 = edx } + add ebx, edx + add eax, ebx + mov tmp2, eax + + {Inc(tmp1, z2 + z4);} + mov eax, z4 { z4 = eax } + add edx, eax + add tmp1, edx + + {tmp3 := (tmp3) * INT32(FIX_1_501321110); { sqrt(2) * ( c1+c3-c5-c7) } + {Inc(tmp3, z1 + z4);} + mov edx, tmp3 + imul edx, FIX_1_501321110 + + add edx, eax + add edx, z1 { tmp3 = edx } + + { Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 } + + {wsptr^[DCTSIZE*0] := int (DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS));} + {wsptr^[DCTSIZE*7] := int (DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS));} + mov eax, tmp10 + add eax, ROUND_CONST + lea ebx, [eax+edx] + sar ebx, CONST_BITS-PASS1_BITS + mov DWORD PTR [ecx+wrkDCTSIZE*0], ebx + + sub eax, edx + sar eax, CONST_BITS-PASS1_BITS + mov DWORD PTR [ecx+wrkDCTSIZE*7], eax + + {wsptr^[DCTSIZE*1] := int (DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS));} + {wsptr^[DCTSIZE*6] := int (DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS));} + mov eax, tmp11 + add eax, ROUND_CONST + mov edx, tmp2 + lea ebx, [eax+edx] + sar ebx, CONST_BITS-PASS1_BITS + mov DWORD PTR [ecx+wrkDCTSIZE*1], ebx + + sub eax, edx + sar eax, CONST_BITS-PASS1_BITS + mov DWORD PTR [ecx+wrkDCTSIZE*6], eax + + {wsptr^[DCTSIZE*2] := int (DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS));} + {wsptr^[DCTSIZE*5] := int (DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS));} + mov eax, tmp12 + add eax, ROUND_CONST + mov edx, tmp1 + lea ebx, [eax+edx] + sar ebx, CONST_BITS-PASS1_BITS + mov DWORD PTR [ecx+wrkDCTSIZE*2], ebx + + sub eax, edx + sar eax, CONST_BITS-PASS1_BITS + mov DWORD PTR [ecx+wrkDCTSIZE*5], eax + + {wsptr^[DCTSIZE*3] := int (DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS));} + {wsptr^[DCTSIZE*4] := int (DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS));} + mov eax, tmp13 + add eax, ROUND_CONST + mov edx, tmp0 + lea ebx, [eax+edx] + sar ebx, CONST_BITS-PASS1_BITS + mov DWORD PTR [ecx+wrkDCTSIZE*3], ebx + + sub eax, edx + sar eax, CONST_BITS-PASS1_BITS + mov DWORD PTR [ecx+wrkDCTSIZE*4], eax + + {Inc(JCOEF_PTR(inptr)); { advance pointers to next column } + {Inc(ISLOW_MULT_TYPE_PTR(quantptr)); + Inc(int_ptr(wsptr));} + dec ctr + je @loop519 + + add esi, Type JCOEF + add edi, Type ISLOW_MULT_TYPE + add ecx, Type int { int_ptr } + {end;} + jmp @loop518 +@loop519: + { Save to memory what we've registerized for the preceding loop. } + + { Pass 2: process rows from work array, store into output array. } + { Note that we must descale the results by a factor of 8 == 2**3, } + { and also undo the PASS1_BITS scaling. } + + {wsptr := @workspace;} + lea esi, workspace + + {for ctr := 0 to pred(DCTSIZE) do + begin} + mov ctr, 0 +@loop523: + + {outptr := output_buf^[ctr];} + mov eax, ctr + mov ebx, output_buf + mov edi, DWORD PTR [ebx+eax*4] { 4 = SizeOf(pointer) } + + {Inc(JSAMPLE_PTR(outptr), output_col);} + add edi, output_col + + { Rows of zeroes can be exploited in the same way as we did with columns. + However, the column calculation has created many nonzero AC terms, so + the simplification applies less often (typically 5% to 10% of the time). + On machines with very fast multiplication, it's possible that the + test takes more time than it's worth. In that case this section + may be commented out. } + +{$ifndef NO_ZERO_ROW_TEST} + {if ((wsptr^[1]) or (wsptr^[2]) or (wsptr^[3]) or (wsptr^[4]) or + (wsptr^[5]) or (wsptr^[6]) or (wsptr^[7]) = 0) then + begin} + mov eax, DWORD PTR [esi+4*1] + or eax, DWORD PTR [esi+4*2] + or eax, DWORD PTR [esi+4*3] + jne @loop525 { Nomssi: early exit path may help } + or eax, DWORD PTR [esi+4*4] + or eax, DWORD PTR [esi+4*5] + or eax, DWORD PTR [esi+4*6] + or eax, DWORD PTR [esi+4*7] + jne @loop525 + + { AC terms all zero } + {JSAMPLE(dcval_) := range_limit^[int(DESCALE(INT32(wsptr^[0]), + PASS1_BITS+3)) and RANGE_MASK];} + mov eax, DWORD PTR [esi+4*0] + add eax, (INT32(1) shl (PASS1_BITS+3-1)) + sar eax, PASS1_BITS+3 + and eax, RANGE_MASK + mov ebx, range_limit + mov al, BYTE PTR [ebx+eax] + mov ah, al + + {outptr^[0] := dcval_; + outptr^[1] := dcval_; + outptr^[2] := dcval_; + outptr^[3] := dcval_; + outptr^[4] := dcval_; + outptr^[5] := dcval_; + outptr^[6] := dcval_; + outptr^[7] := dcval_;} + + stosw + stosw + stosw + stosw + + {Inc(int_ptr(wsptr), DCTSIZE); { advance pointer to next row } + {continue;} + add esi, wrkDCTSIZE + inc ctr + cmp ctr, DCTSIZE + jl @loop523 + jmp @loop524 + {end;} +@loop525: +{$endif} + + + { Even part: reverse the even part of the forward DCT. } + { The rotator is sqrt(2)*c(-6). } + + {z2 := INT32 (wsptr^[2]);} + mov edx, DWORD PTR [esi+4*2] { z2 = edx } + + {z3 := INT32 (wsptr^[6]);} + mov ecx, DWORD PTR [esi+4*6] { z3 = ecx } + + {z1 := (z2 + z3) * INT32(FIX_0_541196100);} + lea eax, [edx+ecx] + imul eax, FIX_0_541196100 + mov ebx, eax { z1 = ebx } + + {tmp2 := z1 + (z3) * INT32(- FIX_1_847759065);} + imul ecx, (-FIX_1_847759065) + add ecx, ebx { tmp2 = ecx } + + {tmp3 := z1 + (z2) * INT32(FIX_0_765366865);} + imul edx, FIX_0_765366865 + add ebx, edx { tmp3 = ebx } + + {tmp0 := (INT32(wsptr^[0]) + INT32(wsptr^[4])) shl CONST_BITS;} + {tmp1 := (INT32(wsptr^[0]) - INT32(wsptr^[4])) shl CONST_BITS;} + mov edx, DWORD PTR [esi+4*4] + mov eax, DWORD PTR [esi+4*0] + sub eax, edx + add edx, edx + add edx, eax + shl edx, CONST_BITS { tmp0 = edx } + shl eax, CONST_BITS { tmp1 = eax } + + {tmp10 := tmp0 + tmp3;} + {tmp13 := tmp0 - tmp3;} + sub edx, ebx + mov tmp13, edx + add ebx, ebx + add edx, ebx + mov tmp10, edx + + {tmp11 := tmp1 + tmp2;} + {tmp12 := tmp1 - tmp2;} + lea ebx, [ecx+eax] + mov tmp11, ebx + sub eax, ecx + mov tmp12, eax + + { Odd part per figure 8; the matrix is unitary and hence its + transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. } + +{ The following lines no longer produce code, since wsptr has been + optimized to esi, it is more efficient to access these values + directly. + tmp0 := INT32(wsptr^[7]); + tmp1 := INT32(wsptr^[5]); + tmp2 := INT32(wsptr^[3]); + tmp3 := INT32(wsptr^[1]); } + + {z2 := tmp1 + tmp2;} + {z2 := (z2) * INT32(- FIX_2_562915447); { sqrt(2) * (-c1-c3) } + mov ebx, DWORD PTR [esi+4*3] { tmp2 } + mov ecx, DWORD PTR [esi+4*5] { tmp1 } + lea eax, [ebx+ecx] + imul eax, (-FIX_2_562915447) + mov z2, eax + + {z3 := tmp0 + tmp2;} + mov edx, DWORD PTR [esi+4*7] { tmp0 } + add ebx, edx { old z3 = ebx } + mov eax, ebx + {z3 := (z3) * INT32(- FIX_1_961570560); { sqrt(2) * (-c3-c5) } + imul eax, (-FIX_1_961570560) + mov z3, eax + + {z1 := tmp0 + tmp3;} + {z1 := (z1) * INT32(- FIX_0_899976223); { sqrt(2) * (c7-c3) } + mov eax, DWORD PTR [esi+4*1] { tmp3 } + add edx, eax + imul edx, (-FIX_0_899976223) { z1 = edx } + + {z4 := tmp1 + tmp3;} + add eax, ecx { +tmp1 } + add ebx, eax { z3 + z4 = ebx } + {z4 := (z4) * INT32(- FIX_0_390180644); { sqrt(2) * (c5-c3) } + imul eax, (-FIX_0_390180644) { z4 = eax } + + {z5 := (z3 + z4) * INT32(FIX_1_175875602); { sqrt(2) * c3 } + {Inc(z3, z5);} + imul ebx, FIX_1_175875602 + mov ecx, z3 + add ecx, ebx { ecx = z3 } + + {Inc(z4, z5);} + add ebx, eax { z4 = ebx } + + {tmp0 := (tmp0) * INT32(FIX_0_298631336); { sqrt(2) * (-c1+c3+c5-c7) } + {Inc(tmp0, z1 + z3);} + mov eax, DWORD PTR [esi+4*7] + imul eax, FIX_0_298631336 + add eax, edx + add eax, ecx + mov tmp0, eax + + {tmp1 := (tmp1) * INT32(FIX_2_053119869); { sqrt(2) * ( c1+c3-c5+c7) } + {Inc(tmp1, z2 + z4);} + mov eax, DWORD PTR [esi+4*5] + imul eax, FIX_2_053119869 + add eax, z2 + add eax, ebx + mov tmp1, eax + + {tmp2 := (tmp2) * INT32(FIX_3_072711026); { sqrt(2) * ( c1+c3+c5-c7) } + {Inc(tmp2, z2 + z3);} + mov eax, DWORD PTR [esi+4*3] + imul eax, FIX_3_072711026 + add eax, z2 + add ecx, eax { ecx = tmp2 } + + {tmp3 := (tmp3) * INT32(FIX_1_501321110); { sqrt(2) * ( c1+c3-c5-c7) } + {Inc(tmp3, z1 + z4);} + mov eax, DWORD PTR [esi+4*1] + imul eax, FIX_1_501321110 + add eax, edx + add ebx, eax { ebx = tmp3 } + + { Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 } + + {outptr^[0] := range_limit^[ int(DESCALE(tmp10 + tmp3, + CONST_BITS+PASS1_BITS+3)) and RANGE_MASK]; } + {outptr^[7] := range_limit^[ int(DESCALE(tmp10 - tmp3, + CONST_BITS+PASS1_BITS+3)) and RANGE_MASK];} + + mov edx, tmp10 + add edx, ROUND_CONST_2 + lea eax, [ebx+edx] + sub edx, ebx + + shr eax, CONST_BITS+PASS1_BITS+3 + and eax, RANGE_MASK + mov ebx, range_limit { once for all } + mov al, BYTE PTR [ebx+eax] + mov [edi+0], al + + shr edx, CONST_BITS+PASS1_BITS+3 + and edx, RANGE_MASK + mov al, BYTE PTR [ebx+edx] + mov [edi+7], al + + {outptr^[1] := range_limit^[ int(DESCALE(tmp11 + tmp2, + CONST_BITS+PASS1_BITS+3)) and RANGE_MASK];} + mov eax, tmp11 + add eax, ROUND_CONST_2 + lea edx, [eax+ecx] + shr edx, CONST_BITS+PASS1_BITS+3 + and edx, RANGE_MASK + mov dl, BYTE PTR [ebx+edx] + mov [edi+1], dl + + {outptr^[6] := range_limit^[ int(DESCALE(tmp11 - tmp2, + CONST_BITS+PASS1_BITS+3)) and RANGE_MASK];} + sub eax, ecx + shr eax, CONST_BITS+PASS1_BITS+3 + and eax, RANGE_MASK + mov al, BYTE PTR [ebx+eax] + mov [edi+6], al + + {outptr^[2] := range_limit^[ int(DESCALE(tmp12 + tmp1, + CONST_BITS+PASS1_BITS+3)) and RANGE_MASK];} + mov eax, tmp12 + add eax, ROUND_CONST_2 + mov ecx, tmp1 + lea edx, [eax+ecx] + shr edx, CONST_BITS+PASS1_BITS+3 + and edx, RANGE_MASK + mov dl, BYTE PTR [ebx+edx] + mov [edi+2], dl + + {outptr^[5] := range_limit^[ int(DESCALE(tmp12 - tmp1, + CONST_BITS+PASS1_BITS+3)) and RANGE_MASK];} + sub eax, ecx + shr eax, CONST_BITS+PASS1_BITS+3 + and eax, RANGE_MASK + mov al, BYTE PTR [ebx+eax] + mov [edi+5], al + + {outptr^[3] := range_limit^[ int(DESCALE(tmp13 + tmp0, + CONST_BITS+PASS1_BITS+3)) and RANGE_MASK];} + mov eax, tmp13 + add eax, ROUND_CONST_2 + mov ecx, tmp0 + lea edx, [eax+ecx] + shr edx, CONST_BITS+PASS1_BITS+3 + and edx, RANGE_MASK + mov dl, BYTE PTR [ebx+edx] + mov [edi+3], dl + + {outptr^[4] := range_limit^[ int(DESCALE(tmp13 - tmp0, + CONST_BITS+PASS1_BITS+3)) and RANGE_MASK];} + sub eax, ecx + shr eax, CONST_BITS+PASS1_BITS+3 + and eax, RANGE_MASK + mov al, BYTE PTR [ebx+eax] + mov [edi+4], al + + {Inc(int_ptr(wsptr), DCTSIZE); { advance pointer to next row } + add esi, wrkDCTSIZE + add edi, DCTSIZE + + {end;} + inc ctr + cmp ctr, DCTSIZE + jl @loop523 + +@loop524: +@loop496: + pop ebx + pop esi + pop edi +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jidctflt_del.pas b/mseide-msegui/lib/common/fpccompatibility/jidctflt_del.pas new file mode 100644 index 0000000..8c8ca3c --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jidctflt_del.pas @@ -0,0 +1,287 @@ +unit jidctflt_del; + +//{$N+} +{ This file contains a floating-point implementation of the + inverse DCT (Discrete Cosine Transform). In the IJG code, this routine + must also perform dequantization of the input coefficients. + + This implementation should be more accurate than either of the integer + IDCT implementations. However, it may not give the same results on all + machines because of differences in roundoff behavior. Speed will depend + on the hardware's floating point capacity. + + A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT + on each row (or vice versa, but it's more convenient to emit a row at + a time). Direct algorithms are also available, but they are much more + complex and seem not to be any faster when reduced to code. + + This implementation is based on Arai, Agui, and Nakajima's algorithm for + scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in + Japanese, but the algorithm is described in the Pennebaker & Mitchell + JPEG textbook (see REFERENCES section in file README). The following code + is based directly on figure 4-8 in P&M. + While an 8-point DCT cannot be done in less than 11 multiplies, it is + possible to arrange the computation so that many of the multiplies are + simple scalings of the final outputs. These multiplies can then be + folded into the multiplications or divisions by the JPEG quantization + table entries. The AA&N method leaves only 5 multiplies and 29 adds + to be done in the DCT itself. + The primary disadvantage of this method is that with a fixed-point + implementation, accuracy is lost due to imprecise representation of the + scaled quantization values. However, that problem does not arise if + we use floating point arithmetic. } + +{ Original: jidctflt.c ; Copyright (C) 1994-1996, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jpeglib_del, + jdct_del; { Private declarations for DCT subsystem } + +{ Perform dequantization and inverse DCT on one block of coefficients. } + +{GLOBAL} +procedure jpeg_idct_float (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + coef_block : JCOEFPTR; + output_buf : JSAMPARRAY; + output_col : JDIMENSION); + +implementation + +{ This module is specialized to the case DCTSIZE = 8. } + +{$ifndef DCTSIZE_IS_8} + Sorry, this code only copes with 8x8 DCTs. { deliberate syntax err } +{$endif} + + +{ Dequantize a coefficient by multiplying it by the multiplier-table + entry; produce a float result. } + +function DEQUANTIZE(coef : int; quantval : FAST_FLOAT) : FAST_FLOAT; +begin + Dequantize := ( (coef) * quantval); +end; + +{ Descale and correctly round an INT32 value that's scaled by N bits. + We assume RIGHT_SHIFT rounds towards minus infinity, so adding + the fudge factor is correct for either sign of X. } + +function DESCALE(x : INT32; n : int) : INT32; +var + shift_temp : INT32; +begin +{$ifdef RIGHT_SHIFT_IS_UNSIGNED} + shift_temp := x + (INT32(1) shl (n-1)); + if shift_temp < 0 then + Descale := (shift_temp shr n) or ((not INT32(0)) shl (32-n)) + else + Descale := (shift_temp shr n); +{$else} + Descale := (x + (INT32(1) shl (n-1)) shr n; +{$endif} +end; + + +{ Perform dequantization and inverse DCT on one block of coefficients. } + +{GLOBAL} +procedure jpeg_idct_float (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + coef_block : JCOEFPTR; + output_buf : JSAMPARRAY; + output_col : JDIMENSION); +type + PWorkspace = ^TWorkspace; + TWorkspace = array[0..DCTSIZE2-1] of FAST_FLOAT; +var + tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7 : FAST_FLOAT; + tmp10, tmp11, tmp12, tmp13 : FAST_FLOAT; + z5, z10, z11, z12, z13 : FAST_FLOAT; + inptr : JCOEFPTR; + quantptr : FLOAT_MULT_TYPE_FIELD_PTR; + wsptr : PWorkSpace; + outptr : JSAMPROW; + range_limit : JSAMPROW; + ctr : int; + workspace : TWorkspace; { buffers data between passes } + {SHIFT_TEMPS} +var + dcval : FAST_FLOAT; +begin +{ Each IDCT routine is responsible for range-limiting its results and + converting them to unsigned form (0..MAXJSAMPLE). The raw outputs could + be quite far out of range if the input data is corrupt, so a bulletproof + range-limiting step is required. We use a mask-and-table-lookup method + to do the combined operations quickly. See the comments with + prepare_range_limit_table (in jdmaster.c) for more info. } + + range_limit := JSAMPROW(@(cinfo^.sample_range_limit^[CENTERJSAMPLE])); + + { Pass 1: process columns from input, store into work array. } + + inptr := coef_block; + quantptr := FLOAT_MULT_TYPE_FIELD_PTR (compptr^.dct_table); + wsptr := @workspace; + for ctr := pred(DCTSIZE) downto 0 do + begin + { Due to quantization, we will usually find that many of the input + coefficients are zero, especially the AC terms. We can exploit this + by short-circuiting the IDCT calculation for any column in which all + the AC terms are zero. In that case each output is equal to the + DC coefficient (with scale factor as needed). + With typical images and quantization tables, half or more of the + column DCT calculations can be simplified this way. } + + if (inptr^[DCTSIZE*1]=0) and (inptr^[DCTSIZE*2]=0) and + (inptr^[DCTSIZE*3]=0) and (inptr^[DCTSIZE*4]=0) and + (inptr^[DCTSIZE*5]=0) and (inptr^[DCTSIZE*6]=0) and + (inptr^[DCTSIZE*7]=0) then + begin + { AC terms all zero } + FAST_FLOAT(dcval) := DEQUANTIZE(inptr^[DCTSIZE*0], quantptr^[DCTSIZE*0]); + + wsptr^[DCTSIZE*0] := dcval; + wsptr^[DCTSIZE*1] := dcval; + wsptr^[DCTSIZE*2] := dcval; + wsptr^[DCTSIZE*3] := dcval; + wsptr^[DCTSIZE*4] := dcval; + wsptr^[DCTSIZE*5] := dcval; + wsptr^[DCTSIZE*6] := dcval; + wsptr^[DCTSIZE*7] := dcval; + + Inc(JCOEF_PTR(inptr)); { advance pointers to next column } + Inc(FLOAT_MULT_TYPE_PTR(quantptr)); + Inc(FAST_FLOAT_PTR(wsptr)); + continue; + end; + + { Even part } + + tmp0 := DEQUANTIZE(inptr^[DCTSIZE*0], quantptr^[DCTSIZE*0]); + tmp1 := DEQUANTIZE(inptr^[DCTSIZE*2], quantptr^[DCTSIZE*2]); + tmp2 := DEQUANTIZE(inptr^[DCTSIZE*4], quantptr^[DCTSIZE*4]); + tmp3 := DEQUANTIZE(inptr^[DCTSIZE*6], quantptr^[DCTSIZE*6]); + + tmp10 := tmp0 + tmp2; { phase 3 } + tmp11 := tmp0 - tmp2; + + tmp13 := tmp1 + tmp3; { phases 5-3 } + tmp12 := (tmp1 - tmp3) * ({FAST_FLOAT}(1.414213562)) - tmp13; { 2*c4 } + + tmp0 := tmp10 + tmp13; { phase 2 } + tmp3 := tmp10 - tmp13; + tmp1 := tmp11 + tmp12; + tmp2 := tmp11 - tmp12; + + { Odd part } + + tmp4 := DEQUANTIZE(inptr^[DCTSIZE*1], quantptr^[DCTSIZE*1]); + tmp5 := DEQUANTIZE(inptr^[DCTSIZE*3], quantptr^[DCTSIZE*3]); + tmp6 := DEQUANTIZE(inptr^[DCTSIZE*5], quantptr^[DCTSIZE*5]); + tmp7 := DEQUANTIZE(inptr^[DCTSIZE*7], quantptr^[DCTSIZE*7]); + + z13 := tmp6 + tmp5; { phase 6 } + z10 := tmp6 - tmp5; + z11 := tmp4 + tmp7; + z12 := tmp4 - tmp7; + + tmp7 := z11 + z13; { phase 5 } + tmp11 := (z11 - z13) * ({FAST_FLOAT}(1.414213562)); { 2*c4 } + + z5 := (z10 + z12) * ({FAST_FLOAT}(1.847759065)); { 2*c2 } + tmp10 := ({FAST_FLOAT}(1.082392200)) * z12 - z5; { 2*(c2-c6) } + tmp12 := ({FAST_FLOAT}(-2.613125930)) * z10 + z5; { -2*(c2+c6) } + + tmp6 := tmp12 - tmp7; { phase 2 } + tmp5 := tmp11 - tmp6; + tmp4 := tmp10 + tmp5; + + wsptr^[DCTSIZE*0] := tmp0 + tmp7; + wsptr^[DCTSIZE*7] := tmp0 - tmp7; + wsptr^[DCTSIZE*1] := tmp1 + tmp6; + wsptr^[DCTSIZE*6] := tmp1 - tmp6; + wsptr^[DCTSIZE*2] := tmp2 + tmp5; + wsptr^[DCTSIZE*5] := tmp2 - tmp5; + wsptr^[DCTSIZE*4] := tmp3 + tmp4; + wsptr^[DCTSIZE*3] := tmp3 - tmp4; + + Inc(JCOEF_PTR(inptr)); { advance pointers to next column } + Inc(FLOAT_MULT_TYPE_PTR(quantptr)); + Inc(FAST_FLOAT_PTR(wsptr)); + end; + + { Pass 2: process rows from work array, store into output array. } + { Note that we must descale the results by a factor of 8 = 2**3. } + + wsptr := @workspace; + for ctr := 0 to pred(DCTSIZE) do + begin + outptr := JSAMPROW(@(output_buf^[ctr]^[output_col])); + { Rows of zeroes can be exploited in the same way as we did with columns. + However, the column calculation has created many nonzero AC terms, so + the simplification applies less often (typically 5% to 10% of the time). + And testing floats for zero is relatively expensive, so we don't bother. } + + { Even part } + + tmp10 := wsptr^[0] + wsptr^[4]; + tmp11 := wsptr^[0] - wsptr^[4]; + + tmp13 := wsptr^[2] + wsptr^[6]; + tmp12 := (wsptr^[2] - wsptr^[6]) * ({FAST_FLOAT}(1.414213562)) - tmp13; + + tmp0 := tmp10 + tmp13; + tmp3 := tmp10 - tmp13; + tmp1 := tmp11 + tmp12; + tmp2 := tmp11 - tmp12; + + { Odd part } + + z13 := wsptr^[5] + wsptr^[3]; + z10 := wsptr^[5] - wsptr^[3]; + z11 := wsptr^[1] + wsptr^[7]; + z12 := wsptr^[1] - wsptr^[7]; + + tmp7 := z11 + z13; + tmp11 := (z11 - z13) * ({FAST_FLOAT}(1.414213562)); + + z5 := (z10 + z12) * ({FAST_FLOAT}(1.847759065)); { 2*c2 } + tmp10 := ({FAST_FLOAT}(1.082392200)) * z12 - z5; { 2*(c2-c6) } + tmp12 := ({FAST_FLOAT}(-2.613125930)) * z10 + z5; { -2*(c2+c6) } + + tmp6 := tmp12 - tmp7; + tmp5 := tmp11 - tmp6; + tmp4 := tmp10 + tmp5; + + { Final output stage: scale down by a factor of 8 and range-limit } + + outptr^[0] := range_limit^[ int(DESCALE( INT32(Round((tmp0 + tmp7))), 3)) + and RANGE_MASK]; + outptr^[7] := range_limit^[ int(DESCALE( INT32(Round((tmp0 - tmp7))), 3)) + and RANGE_MASK]; + outptr^[1] := range_limit^[ int(DESCALE( INT32(Round((tmp1 + tmp6))), 3)) + and RANGE_MASK]; + outptr^[6] := range_limit^[ int(DESCALE( INT32(Round((tmp1 - tmp6))), 3)) + and RANGE_MASK]; + outptr^[2] := range_limit^[ int(DESCALE( INT32(Round((tmp2 + tmp5))), 3)) + and RANGE_MASK]; + outptr^[5] := range_limit^[ int(DESCALE( INT32(Round((tmp2 - tmp5))), 3)) + and RANGE_MASK]; + outptr^[4] := range_limit^[ int(DESCALE( INT32(Round((tmp3 + tmp4))), 3)) + and RANGE_MASK]; + outptr^[3] := range_limit^[ int(DESCALE( INT32(Round((tmp3 - tmp4))), 3)) + and RANGE_MASK]; + + Inc(FAST_FLOAT_PTR(wsptr), DCTSIZE); { advance pointer to next row } + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jidctfst_del.pas b/mseide-msegui/lib/common/fpccompatibility/jidctfst_del.pas new file mode 100644 index 0000000..9b3d390 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jidctfst_del.pas @@ -0,0 +1,411 @@ +unit jidctfst_del; + +{ This file contains a fast, not so accurate integer implementation of the + inverse DCT (Discrete Cosine Transform). In the IJG code, this routine + must also perform dequantization of the input coefficients. + + A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT + on each row (or vice versa, but it's more convenient to emit a row at + a time). Direct algorithms are also available, but they are much more + complex and seem not to be any faster when reduced to code. + + This implementation is based on Arai, Agui, and Nakajima's algorithm for + scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in + Japanese, but the algorithm is described in the Pennebaker & Mitchell + JPEG textbook (see REFERENCES section in file README). The following code + is based directly on figure 4-8 in P&M. + While an 8-point DCT cannot be done in less than 11 multiplies, it is + possible to arrange the computation so that many of the multiplies are + simple scalings of the final outputs. These multiplies can then be + folded into the multiplications or divisions by the JPEG quantization + table entries. The AA&N method leaves only 5 multiplies and 29 adds + to be done in the DCT itself. + The primary disadvantage of this method is that with fixed-point math, + accuracy is lost due to imprecise representation of the scaled + quantization values. The smaller the quantization table entry, the less + precise the scaled value, so this implementation does worse with high- + quality-setting files than with low-quality ones. } + +{ Original : jidctfst.c ; Copyright (C) 1994-1996, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jpeglib_del, + jdct_del; { Private declarations for DCT subsystem } + + +{ Perform dequantization and inverse DCT on one block of coefficients. } + +{GLOBAL} +procedure jpeg_idct_ifast (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + coef_block : JCOEFPTR; + output_buf : JSAMPARRAY; + output_col : JDIMENSION); + +implementation + +{ This module is specialized to the case DCTSIZE = 8. } + +{$ifndef DCTSIZE_IS_8} + Sorry, this code only copes with 8x8 DCTs. { deliberate syntax err } +{$endif} + +{ Scaling decisions are generally the same as in the LL&M algorithm; + see jidctint.c for more details. However, we choose to descale + (right shift) multiplication products as soon as they are formed, + rather than carrying additional fractional bits into subsequent additions. + This compromises accuracy slightly, but it lets us save a few shifts. + More importantly, 16-bit arithmetic is then adequate (for 8-bit samples) + everywhere except in the multiplications proper; this saves a good deal + of work on 16-bit-int machines. + + The dequantized coefficients are not integers because the AA&N scaling + factors have been incorporated. We represent them scaled up by PASS1_BITS, + so that the first and second IDCT rounds have the same input scaling. + For 8-bit JSAMPLEs, we choose IFAST_SCALE_BITS = PASS1_BITS so as to + avoid a descaling shift; this compromises accuracy rather drastically + for small quantization table entries, but it saves a lot of shifts. + For 12-bit JSAMPLEs, there's no hope of using 16x16 multiplies anyway, + so we use a much larger scaling factor to preserve accuracy. + + A final compromise is to represent the multiplicative constants to only + 8 fractional bits, rather than 13. This saves some shifting work on some + machines, and may also reduce the cost of multiplication (since there + are fewer one-bits in the constants). } + +{$ifdef BITS_IN_JSAMPLE_IS_8} +const + CONST_BITS = 8; + PASS1_BITS = 2; +{$else} +const + CONST_BITS = 8; + PASS1_BITS = 1; { lose a little precision to avoid overflow } +{$endif} + + +const + FIX_1_082392200 = INT32(Round((INT32(1) shl CONST_BITS)*1.082392200)); {277} + FIX_1_414213562 = INT32(Round((INT32(1) shl CONST_BITS)*1.414213562)); {362} + FIX_1_847759065 = INT32(Round((INT32(1) shl CONST_BITS)*1.847759065)); {473} + FIX_2_613125930 = INT32(Round((INT32(1) shl CONST_BITS)*2.613125930)); {669} + + +{ Descale and correctly round an INT32 value that's scaled by N bits. + We assume RIGHT_SHIFT rounds towards minus infinity, so adding + the fudge factor is correct for either sign of X. } + +function DESCALE(x : INT32; n : int) : INT32; +var + shift_temp : INT32; +begin +{$ifdef USE_ACCURATE_ROUNDING} + shift_temp := x + (INT32(1) shl (n-1)); +{$else} +{ We can gain a little more speed, with a further compromise in accuracy, + by omitting the addition in a descaling shift. This yields an incorrectly + rounded result half the time... } + shift_temp := x; +{$endif} + +{$ifdef RIGHT_SHIFT_IS_UNSIGNED} + if shift_temp < 0 then + Descale := (shift_temp shr n) or ((not INT32(0)) shl (32-n)) + else +{$endif} + Descale := (shift_temp shr n); +end; + + +{ Multiply a DCTELEM variable by an INT32 constant, and immediately + descale to yield a DCTELEM result. } + + {(DCTELEM( DESCALE((var) * (const), CONST_BITS))} + function Multiply(Avar, Aconst: Integer): DCTELEM; + begin + Multiply := DCTELEM( Avar*INT32(Aconst) div (INT32(1) shl CONST_BITS)); + end; + + +{ Dequantize a coefficient by multiplying it by the multiplier-table + entry; produce a DCTELEM result. For 8-bit data a 16x16->16 + multiplication will do. For 12-bit data, the multiplier table is + declared INT32, so a 32-bit multiply will be used. } + +{$ifdef BITS_IN_JSAMPLE_IS_8} + function DEQUANTIZE(coef,quantval : int) : int; + begin + Dequantize := ( IFAST_MULT_TYPE(coef) * quantval); + end; +{$else} + function DEQUANTIZE(coef,quantval : INT32) : int; + begin + Dequantize := DESCALE((coef)*(quantval), IFAST_SCALE_BITS-PASS1_BITS); + end; +{$endif} + + +{ Like DESCALE, but applies to a DCTELEM and produces an int. + We assume that int right shift is unsigned if INT32 right shift is. } + +function IDESCALE(x : DCTELEM; n : int) : int; +{$ifdef BITS_IN_JSAMPLE_IS_8} +const + DCTELEMBITS = 16; { DCTELEM may be 16 or 32 bits } +{$else} +const + DCTELEMBITS = 32; { DCTELEM must be 32 bits } +{$endif} +var + ishift_temp : DCTELEM; +begin +{$ifndef USE_ACCURATE_ROUNDING} + ishift_temp := x + (INT32(1) shl (n-1)); +{$else} +{ We can gain a little more speed, with a further compromise in accuracy, + by omitting the addition in a descaling shift. This yields an incorrectly + rounded result half the time... } + ishift_temp := x; +{$endif} + +{$ifdef RIGHT_SHIFT_IS_UNSIGNED} + if ishift_temp < 0 then + IDescale := (ishift_temp shr n) + or ((not DCTELEM(0)) shl (DCTELEMBITS-n)) + else +{$endif} + IDescale := (ishift_temp shr n); +end; + + + +{ Perform dequantization and inverse DCT on one block of coefficients. } + +{GLOBAL} +procedure jpeg_idct_ifast (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + coef_block : JCOEFPTR; + output_buf : JSAMPARRAY; + output_col : JDIMENSION); +type + PWorkspace = ^TWorkspace; + TWorkspace = coef_bits_field; { buffers data between passes } +var + tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7 : DCTELEM; + tmp10, tmp11, tmp12, tmp13 : DCTELEM; + z5, z10, z11, z12, z13 : DCTELEM; + inptr : JCOEFPTR; + quantptr : IFAST_MULT_TYPE_FIELD_PTR; + wsptr : PWorkspace; + outptr : JSAMPROW; + range_limit : JSAMPROW; + ctr : int; + workspace : TWorkspace; { buffers data between passes } + {SHIFT_TEMPS} { for DESCALE } + {ISHIFT_TEMPS} { for IDESCALE } +var + dcval : int; +var + dcval_ : JSAMPLE; +begin +{ Each IDCT routine is responsible for range-limiting its results and + converting them to unsigned form (0..MAXJSAMPLE). The raw outputs could + be quite far out of range if the input data is corrupt, so a bulletproof + range-limiting step is required. We use a mask-and-table-lookup method + to do the combined operations quickly. See the comments with + prepare_range_limit_table (in jdmaster.c) for more info. } + + range_limit := JSAMPROW(@(cinfo^.sample_range_limit^[CENTERJSAMPLE])); + { Pass 1: process columns from input, store into work array. } + + inptr := coef_block; + quantptr := IFAST_MULT_TYPE_FIELD_PTR(compptr^.dct_table); + wsptr := @workspace; + for ctr := pred(DCTSIZE) downto 0 do + begin + { Due to quantization, we will usually find that many of the input + coefficients are zero, especially the AC terms. We can exploit this + by short-circuiting the IDCT calculation for any column in which all + the AC terms are zero. In that case each output is equal to the + DC coefficient (with scale factor as needed). + With typical images and quantization tables, half or more of the + column DCT calculations can be simplified this way. } + + if (inptr^[DCTSIZE*1]=0) and (inptr^[DCTSIZE*2]=0) and (inptr^[DCTSIZE*3]=0) and + (inptr^[DCTSIZE*4]=0) and (inptr^[DCTSIZE*5]=0) and (inptr^[DCTSIZE*6]=0) and + (inptr^[DCTSIZE*7]=0) then + begin + { AC terms all zero } + dcval := int(DEQUANTIZE(inptr^[DCTSIZE*0], quantptr^[DCTSIZE*0])); + + wsptr^[DCTSIZE*0] := dcval; + wsptr^[DCTSIZE*1] := dcval; + wsptr^[DCTSIZE*2] := dcval; + wsptr^[DCTSIZE*3] := dcval; + wsptr^[DCTSIZE*4] := dcval; + wsptr^[DCTSIZE*5] := dcval; + wsptr^[DCTSIZE*6] := dcval; + wsptr^[DCTSIZE*7] := dcval; + + Inc(JCOEF_PTR(inptr)); { advance pointers to next column } + Inc(IFAST_MULT_TYPE_PTR(quantptr)); + Inc(int_ptr(wsptr)); + continue; + end; + + { Even part } + + tmp0 := DEQUANTIZE(inptr^[DCTSIZE*0], quantptr^[DCTSIZE*0]); + tmp1 := DEQUANTIZE(inptr^[DCTSIZE*2], quantptr^[DCTSIZE*2]); + tmp2 := DEQUANTIZE(inptr^[DCTSIZE*4], quantptr^[DCTSIZE*4]); + tmp3 := DEQUANTIZE(inptr^[DCTSIZE*6], quantptr^[DCTSIZE*6]); + + tmp10 := tmp0 + tmp2; { phase 3 } + tmp11 := tmp0 - tmp2; + + tmp13 := tmp1 + tmp3; { phases 5-3 } + tmp12 := MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; { 2*c4 } + + tmp0 := tmp10 + tmp13; { phase 2 } + tmp3 := tmp10 - tmp13; + tmp1 := tmp11 + tmp12; + tmp2 := tmp11 - tmp12; + + { Odd part } + + tmp4 := DEQUANTIZE(inptr^[DCTSIZE*1], quantptr^[DCTSIZE*1]); + tmp5 := DEQUANTIZE(inptr^[DCTSIZE*3], quantptr^[DCTSIZE*3]); + tmp6 := DEQUANTIZE(inptr^[DCTSIZE*5], quantptr^[DCTSIZE*5]); + tmp7 := DEQUANTIZE(inptr^[DCTSIZE*7], quantptr^[DCTSIZE*7]); + + z13 := tmp6 + tmp5; { phase 6 } + z10 := tmp6 - tmp5; + z11 := tmp4 + tmp7; + z12 := tmp4 - tmp7; + + tmp7 := z11 + z13; { phase 5 } + tmp11 := MULTIPLY(z11 - z13, FIX_1_414213562); { 2*c4 } + + z5 := MULTIPLY(z10 + z12, FIX_1_847759065); { 2*c2 } + tmp10 := MULTIPLY(z12, FIX_1_082392200) - z5; { 2*(c2-c6) } + tmp12 := MULTIPLY(z10, - FIX_2_613125930) + z5; { -2*(c2+c6) } + + tmp6 := tmp12 - tmp7; { phase 2 } + tmp5 := tmp11 - tmp6; + tmp4 := tmp10 + tmp5; + + wsptr^[DCTSIZE*0] := int (tmp0 + tmp7); + wsptr^[DCTSIZE*7] := int (tmp0 - tmp7); + wsptr^[DCTSIZE*1] := int (tmp1 + tmp6); + wsptr^[DCTSIZE*6] := int (tmp1 - tmp6); + wsptr^[DCTSIZE*2] := int (tmp2 + tmp5); + wsptr^[DCTSIZE*5] := int (tmp2 - tmp5); + wsptr^[DCTSIZE*4] := int (tmp3 + tmp4); + wsptr^[DCTSIZE*3] := int (tmp3 - tmp4); + + Inc(JCOEF_PTR(inptr)); { advance pointers to next column } + Inc(IFAST_MULT_TYPE_PTR(quantptr)); + Inc(int_ptr(wsptr)); + end; + + { Pass 2: process rows from work array, store into output array. } + { Note that we must descale the results by a factor of 8 == 2**3, } + { and also undo the PASS1_BITS scaling. } + + wsptr := @workspace; + for ctr := 0 to pred(DCTSIZE) do + begin + outptr := JSAMPROW(@output_buf^[ctr]^[output_col]); + { Rows of zeroes can be exploited in the same way as we did with columns. + However, the column calculation has created many nonzero AC terms, so + the simplification applies less often (typically 5% to 10% of the time). + On machines with very fast multiplication, it's possible that the + test takes more time than it's worth. In that case this section + may be commented out. } + +{$ifndef NO_ZERO_ROW_TEST} + if (wsptr^[1]=0) and (wsptr^[2]=0) and (wsptr^[3]=0) and (wsptr^[4]=0) and + (wsptr^[5]=0) and (wsptr^[6]=0) and (wsptr^[7]=0) then + begin + { AC terms all zero } + dcval_ := range_limit^[IDESCALE(wsptr^[0], PASS1_BITS+3) + and RANGE_MASK]; + + outptr^[0] := dcval_; + outptr^[1] := dcval_; + outptr^[2] := dcval_; + outptr^[3] := dcval_; + outptr^[4] := dcval_; + outptr^[5] := dcval_; + outptr^[6] := dcval_; + outptr^[7] := dcval_; + + Inc(int_ptr(wsptr), DCTSIZE); { advance pointer to next row } + continue; + end; +{$endif} + + { Even part } + + tmp10 := (DCTELEM(wsptr^[0]) + DCTELEM(wsptr^[4])); + tmp11 := (DCTELEM(wsptr^[0]) - DCTELEM(wsptr^[4])); + + tmp13 := (DCTELEM(wsptr^[2]) + DCTELEM(wsptr^[6])); + tmp12 := MULTIPLY(DCTELEM(wsptr^[2]) - DCTELEM(wsptr^[6]), FIX_1_414213562) + - tmp13; + + tmp0 := tmp10 + tmp13; + tmp3 := tmp10 - tmp13; + tmp1 := tmp11 + tmp12; + tmp2 := tmp11 - tmp12; + + { Odd part } + + z13 := DCTELEM(wsptr^[5]) + DCTELEM(wsptr^[3]); + z10 := DCTELEM(wsptr^[5]) - DCTELEM(wsptr^[3]); + z11 := DCTELEM(wsptr^[1]) + DCTELEM(wsptr^[7]); + z12 := DCTELEM(wsptr^[1]) - DCTELEM(wsptr^[7]); + + tmp7 := z11 + z13; { phase 5 } + tmp11 := MULTIPLY(z11 - z13, FIX_1_414213562); { 2*c4 } + + z5 := MULTIPLY(z10 + z12, FIX_1_847759065); { 2*c2 } + tmp10 := MULTIPLY(z12, FIX_1_082392200) - z5; { 2*(c2-c6) } + tmp12 := MULTIPLY(z10, - FIX_2_613125930) + z5; { -2*(c2+c6) } + + tmp6 := tmp12 - tmp7; { phase 2 } + tmp5 := tmp11 - tmp6; + tmp4 := tmp10 + tmp5; + + { Final output stage: scale down by a factor of 8 and range-limit } + + outptr^[0] := range_limit^[IDESCALE(tmp0 + tmp7, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[7] := range_limit^[IDESCALE(tmp0 - tmp7, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[1] := range_limit^[IDESCALE(tmp1 + tmp6, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[6] := range_limit^[IDESCALE(tmp1 - tmp6, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[2] := range_limit^[IDESCALE(tmp2 + tmp5, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[5] := range_limit^[IDESCALE(tmp2 - tmp5, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[4] := range_limit^[IDESCALE(tmp3 + tmp4, PASS1_BITS+3) + and RANGE_MASK]; + outptr^[3] := range_limit^[IDESCALE(tmp3 - tmp4, PASS1_BITS+3) + and RANGE_MASK]; + + Inc(int_ptr(wsptr), DCTSIZE); { advance pointer to next row } + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jidctint_del.pas b/mseide-msegui/lib/common/fpccompatibility/jidctint_del.pas new file mode 100644 index 0000000..a019540 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jidctint_del.pas @@ -0,0 +1,441 @@ +unit jidctint_del; +{$Q+} + +{ This file contains a slow-but-accurate integer implementation of the + inverse DCT (Discrete Cosine Transform). In the IJG code, this routine + must also perform dequantization of the input coefficients. + + A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT + on each row (or vice versa, but it's more convenient to emit a row at + a time). Direct algorithms are also available, but they are much more + complex and seem not to be any faster when reduced to code. + + This implementation is based on an algorithm described in + C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT + Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics, + Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991. + The primary algorithm described there uses 11 multiplies and 29 adds. + We use their alternate method with 12 multiplies and 32 adds. + The advantage of this method is that no data path contains more than one + multiplication; this allows a very simple and accurate implementation in + scaled fixed-point arithmetic, with a minimal number of shifts. } + +{ Original : jidctint.c ; Copyright (C) 1991-1998, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jpeglib_del, + jdct_del; { Private declarations for DCT subsystem } + +{ Perform dequantization and inverse DCT on one block of coefficients. } + +{GLOBAL} +procedure jpeg_idct_islow (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + coef_block : JCOEFPTR; + output_buf : JSAMPARRAY; + output_col : JDIMENSION); + +implementation + +{ This module is specialized to the case DCTSIZE = 8. } + +{$ifndef DCTSIZE_IS_8} + Sorry, this code only copes with 8x8 DCTs. { deliberate syntax err } +{$endif} + +{ The poop on this scaling stuff is as follows: + + Each 1-D IDCT step produces outputs which are a factor of sqrt(N) + larger than the true IDCT outputs. The final outputs are therefore + a factor of N larger than desired; since N=8 this can be cured by + a simple right shift at the end of the algorithm. The advantage of + this arrangement is that we save two multiplications per 1-D IDCT, + because the y0 and y4 inputs need not be divided by sqrt(N). + + We have to do addition and subtraction of the integer inputs, which + is no problem, and multiplication by fractional constants, which is + a problem to do in integer arithmetic. We multiply all the constants + by CONST_SCALE and convert them to integer constants (thus retaining + CONST_BITS bits of precision in the constants). After doing a + multiplication we have to divide the product by CONST_SCALE, with proper + rounding, to produce the correct output. This division can be done + cheaply as a right shift of CONST_BITS bits. We postpone shifting + as long as possible so that partial sums can be added together with + full fractional precision. + + The outputs of the first pass are scaled up by PASS1_BITS bits so that + they are represented to better-than-integral precision. These outputs + require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word + with the recommended scaling. (To scale up 12-bit sample data further, an + intermediate INT32 array would be needed.) + + To avoid overflow of the 32-bit intermediate results in pass 2, we must + have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26. Error analysis + shows that the values given below are the most effective. } + +{$ifdef BITS_IN_JSAMPLE_IS_8} +const + CONST_BITS = 13; + PASS1_BITS = 2; +{$else} +const + CONST_BITS = 13; + PASS1_BITS = 1; { lose a little precision to avoid overflow } +{$endif} + +const + CONST_SCALE = (INT32(1) shl CONST_BITS); + +const + FIX_0_298631336 = INT32(Round(CONST_SCALE * 0.298631336)); {2446} + FIX_0_390180644 = INT32(Round(CONST_SCALE * 0.390180644)); {3196} + FIX_0_541196100 = INT32(Round(CONST_SCALE * 0.541196100)); {4433} + FIX_0_765366865 = INT32(Round(CONST_SCALE * 0.765366865)); {6270} + FIX_0_899976223 = INT32(Round(CONST_SCALE * 0.899976223)); {7373} + FIX_1_175875602 = INT32(Round(CONST_SCALE * 1.175875602)); {9633} + FIX_1_501321110 = INT32(Round(CONST_SCALE * 1.501321110)); {12299} + FIX_1_847759065 = INT32(Round(CONST_SCALE * 1.847759065)); {15137} + FIX_1_961570560 = INT32(Round(CONST_SCALE * 1.961570560)); {16069} + FIX_2_053119869 = INT32(Round(CONST_SCALE * 2.053119869)); {16819} + FIX_2_562915447 = INT32(Round(CONST_SCALE * 2.562915447)); {20995} + FIX_3_072711026 = INT32(Round(CONST_SCALE * 3.072711026)); {25172} + + + +{ Multiply an INT32 variable by an INT32 constant to yield an INT32 result. + For 8-bit samples with the recommended scaling, all the variable + and constant values involved are no more than 16 bits wide, so a + 16x16->32 bit multiply can be used instead of a full 32x32 multiply. + For 12-bit samples, a full 32-bit multiplication will be needed. } + +{$ifdef BITS_IN_JSAMPLE_IS_8} + + {$IFDEF BASM16} + {$IFNDEF WIN32} + {MULTIPLY16C16(var,const)} + function Multiply(X, Y: Integer): integer; assembler; + asm + mov ax, X + imul Y + mov al, ah + mov ah, dl + end; + {$ENDIF} + {$ENDIF} + + function Multiply(X, Y: INT32): INT32; + begin + Multiply := INT32(X) * INT32(Y); + end; + + +{$else} + {#define MULTIPLY(var,const) ((var) * (const))} + function Multiply(X, Y: INT32): INT32; + begin + Multiply := INT32(X) * INT32(Y); + end; +{$endif} + + +{ Dequantize a coefficient by multiplying it by the multiplier-table + entry; produce an int result. In this module, both inputs and result + are 16 bits or less, so either int or short multiply will work. } + +function DEQUANTIZE(coef,quantval : int) : int; +begin + Dequantize := ( ISLOW_MULT_TYPE(coef) * quantval); +end; + +{ Descale and correctly round an INT32 value that's scaled by N bits. + We assume RIGHT_SHIFT rounds towards minus infinity, so adding + the fudge factor is correct for either sign of X. } + +function DESCALE(x : INT32; n : int) : INT32; +var + shift_temp : INT32; +begin +{$ifdef RIGHT_SHIFT_IS_UNSIGNED} + shift_temp := x + (INT32(1) shl (n-1)); + if shift_temp < 0 then + Descale := (shift_temp shr n) or ((not INT32(0)) shl (32-n)) + else + Descale := (shift_temp shr n); +{$else} + Descale := (x + (INT32(1) shl (n-1)) shr n; +{$endif} +end; + +{ Perform dequantization and inverse DCT on one block of coefficients. } + +{GLOBAL} +procedure jpeg_idct_islow (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + coef_block : JCOEFPTR; + output_buf : JSAMPARRAY; + output_col : JDIMENSION); +type + PWorkspace = ^TWorkspace; + TWorkspace = coef_bits_field; { buffers data between passes } +var + tmp0, tmp1, tmp2, tmp3 : INT32; + tmp10, tmp11, tmp12, tmp13 : INT32; + z1, z2, z3, z4, z5 : INT32; + inptr : JCOEFPTR; + quantptr : ISLOW_MULT_TYPE_FIELD_PTR; + wsptr : PWorkspace; + outptr : JSAMPROW; + range_limit : JSAMPROW; + ctr : int; + workspace : TWorkspace; + {SHIFT_TEMPS} +var + dcval : int; +var + dcval_ : JSAMPLE; +begin +{ Each IDCT routine is responsible for range-limiting its results and + converting them to unsigned form (0..MAXJSAMPLE). The raw outputs could + be quite far out of range if the input data is corrupt, so a bulletproof + range-limiting step is required. We use a mask-and-table-lookup method + to do the combined operations quickly. See the comments with + prepare_range_limit_table (in jdmaster.c) for more info. } + + range_limit := JSAMPROW(@(cinfo^.sample_range_limit^[CENTERJSAMPLE])); + + + { Pass 1: process columns from input, store into work array. } + { Note results are scaled up by sqrt(8) compared to a true IDCT; } + { furthermore, we scale the results by 2**PASS1_BITS. } + + inptr := coef_block; + quantptr := ISLOW_MULT_TYPE_FIELD_PTR (compptr^.dct_table); + wsptr := PWorkspace(@workspace); + for ctr := pred(DCTSIZE) downto 0 do + begin + { Due to quantization, we will usually find that many of the input + coefficients are zero, especially the AC terms. We can exploit this + by short-circuiting the IDCT calculation for any column in which all + the AC terms are zero. In that case each output is equal to the + DC coefficient (with scale factor as needed). + With typical images and quantization tables, half or more of the + column DCT calculations can be simplified this way. } + + if ((inptr^[DCTSIZE*1]=0) and (inptr^[DCTSIZE*2]=0) and + (inptr^[DCTSIZE*3]=0) and (inptr^[DCTSIZE*4]=0) and + (inptr^[DCTSIZE*5]=0) and (inptr^[DCTSIZE*6]=0) and + (inptr^[DCTSIZE*7]=0)) then + begin + { AC terms all zero } + dcval := DEQUANTIZE(inptr^[DCTSIZE*0], quantptr^[DCTSIZE*0]) shl PASS1_BITS; + + wsptr^[DCTSIZE*0] := dcval; + wsptr^[DCTSIZE*1] := dcval; + wsptr^[DCTSIZE*2] := dcval; + wsptr^[DCTSIZE*3] := dcval; + wsptr^[DCTSIZE*4] := dcval; + wsptr^[DCTSIZE*5] := dcval; + wsptr^[DCTSIZE*6] := dcval; + wsptr^[DCTSIZE*7] := dcval; + + Inc(JCOEF_PTR(inptr)); { advance pointers to next column } + Inc(ISLOW_MULT_TYPE_PTR(quantptr)); + Inc(int_ptr(wsptr)); + continue; + end; + + { Even part: reverse the even part of the forward DCT. } + { The rotator is sqrt(2)*c(-6). } + + z2 := DEQUANTIZE(inptr^[DCTSIZE*2], quantptr^[DCTSIZE*2]); + z3 := DEQUANTIZE(inptr^[DCTSIZE*6], quantptr^[DCTSIZE*6]); + + z1 := MULTIPLY(z2 + z3, FIX_0_541196100); + tmp2 := z1 + MULTIPLY(z3, - FIX_1_847759065); + tmp3 := z1 + MULTIPLY(z2, FIX_0_765366865); + + z2 := DEQUANTIZE(inptr^[DCTSIZE*0], quantptr^[DCTSIZE*0]); + z3 := DEQUANTIZE(inptr^[DCTSIZE*4], quantptr^[DCTSIZE*4]); + + tmp0 := (z2 + z3) shl CONST_BITS; + tmp1 := (z2 - z3) shl CONST_BITS; + + tmp10 := tmp0 + tmp3; + tmp13 := tmp0 - tmp3; + tmp11 := tmp1 + tmp2; + tmp12 := tmp1 - tmp2; + + { Odd part per figure 8; the matrix is unitary and hence its + transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. } + + tmp0 := DEQUANTIZE(inptr^[DCTSIZE*7], quantptr^[DCTSIZE*7]); + tmp1 := DEQUANTIZE(inptr^[DCTSIZE*5], quantptr^[DCTSIZE*5]); + tmp2 := DEQUANTIZE(inptr^[DCTSIZE*3], quantptr^[DCTSIZE*3]); + tmp3 := DEQUANTIZE(inptr^[DCTSIZE*1], quantptr^[DCTSIZE*1]); + + z1 := tmp0 + tmp3; + z2 := tmp1 + tmp2; + z3 := tmp0 + tmp2; + z4 := tmp1 + tmp3; + z5 := MULTIPLY(z3 + z4, FIX_1_175875602); { sqrt(2) * c3 } + + tmp0 := MULTIPLY(tmp0, FIX_0_298631336); { sqrt(2) * (-c1+c3+c5-c7) } + tmp1 := MULTIPLY(tmp1, FIX_2_053119869); { sqrt(2) * ( c1+c3-c5+c7) } + tmp2 := MULTIPLY(tmp2, FIX_3_072711026); { sqrt(2) * ( c1+c3+c5-c7) } + tmp3 := MULTIPLY(tmp3, FIX_1_501321110); { sqrt(2) * ( c1+c3-c5-c7) } + z1 := MULTIPLY(z1, - FIX_0_899976223); { sqrt(2) * (c7-c3) } + z2 := MULTIPLY(z2, - FIX_2_562915447); { sqrt(2) * (-c1-c3) } + z3 := MULTIPLY(z3, - FIX_1_961570560); { sqrt(2) * (-c3-c5) } + z4 := MULTIPLY(z4, - FIX_0_390180644); { sqrt(2) * (c5-c3) } + + Inc(z3, z5); + Inc(z4, z5); + + Inc(tmp0, z1 + z3); + Inc(tmp1, z2 + z4); + Inc(tmp2, z2 + z3); + Inc(tmp3, z1 + z4); + + { Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 } + + wsptr^[DCTSIZE*0] := int (DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS)); + wsptr^[DCTSIZE*7] := int (DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS)); + wsptr^[DCTSIZE*1] := int (DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS)); + wsptr^[DCTSIZE*6] := int (DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS)); + wsptr^[DCTSIZE*2] := int (DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS)); + wsptr^[DCTSIZE*5] := int (DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS)); + wsptr^[DCTSIZE*3] := int (DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS)); + wsptr^[DCTSIZE*4] := int (DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS)); + + Inc(JCOEF_PTR(inptr)); { advance pointers to next column } + Inc(ISLOW_MULT_TYPE_PTR(quantptr)); + Inc(int_ptr(wsptr)); + end; + + { Pass 2: process rows from work array, store into output array. } + { Note that we must descale the results by a factor of 8 == 2**3, } + { and also undo the PASS1_BITS scaling. } + + wsptr := @workspace; + for ctr := 0 to pred(DCTSIZE) do + begin + outptr := output_buf^[ctr]; + Inc(JSAMPLE_PTR(outptr), output_col); + { Rows of zeroes can be exploited in the same way as we did with columns. + However, the column calculation has created many nonzero AC terms, so + the simplification applies less often (typically 5% to 10% of the time). + On machines with very fast multiplication, it's possible that the + test takes more time than it's worth. In that case this section + may be commented out. } + +{$ifndef NO_ZERO_ROW_TEST} + if ((wsptr^[1]=0) and (wsptr^[2]=0) and (wsptr^[3]=0) and (wsptr^[4]=0) + and (wsptr^[5]=0) and (wsptr^[6]=0) and (wsptr^[7]=0)) then + begin + { AC terms all zero } + JSAMPLE(dcval_) := range_limit^[int(DESCALE(INT32(wsptr^[0]), + PASS1_BITS+3)) and RANGE_MASK]; + + outptr^[0] := dcval_; + outptr^[1] := dcval_; + outptr^[2] := dcval_; + outptr^[3] := dcval_; + outptr^[4] := dcval_; + outptr^[5] := dcval_; + outptr^[6] := dcval_; + outptr^[7] := dcval_; + + Inc(int_ptr(wsptr), DCTSIZE); { advance pointer to next row } + continue; + end; +{$endif} + + { Even part: reverse the even part of the forward DCT. } + { The rotator is sqrt(2)*c(-6). } + + z2 := INT32 (wsptr^[2]); + z3 := INT32 (wsptr^[6]); + + z1 := MULTIPLY(z2 + z3, FIX_0_541196100); + tmp2 := z1 + MULTIPLY(z3, - FIX_1_847759065); + tmp3 := z1 + MULTIPLY(z2, FIX_0_765366865); + + tmp0 := (INT32(wsptr^[0]) + INT32(wsptr^[4])) shl CONST_BITS; + tmp1 := (INT32(wsptr^[0]) - INT32(wsptr^[4])) shl CONST_BITS; + + tmp10 := tmp0 + tmp3; + tmp13 := tmp0 - tmp3; + tmp11 := tmp1 + tmp2; + tmp12 := tmp1 - tmp2; + + { Odd part per figure 8; the matrix is unitary and hence its + transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. } + + tmp0 := INT32(wsptr^[7]); + tmp1 := INT32(wsptr^[5]); + tmp2 := INT32(wsptr^[3]); + tmp3 := INT32(wsptr^[1]); + + z1 := tmp0 + tmp3; + z2 := tmp1 + tmp2; + z3 := tmp0 + tmp2; + z4 := tmp1 + tmp3; + z5 := MULTIPLY(z3 + z4, FIX_1_175875602); { sqrt(2) * c3 } + + tmp0 := MULTIPLY(tmp0, FIX_0_298631336); { sqrt(2) * (-c1+c3+c5-c7) } + tmp1 := MULTIPLY(tmp1, FIX_2_053119869); { sqrt(2) * ( c1+c3-c5+c7) } + tmp2 := MULTIPLY(tmp2, FIX_3_072711026); { sqrt(2) * ( c1+c3+c5-c7) } + tmp3 := MULTIPLY(tmp3, FIX_1_501321110); { sqrt(2) * ( c1+c3-c5-c7) } + z1 := MULTIPLY(z1, - FIX_0_899976223); { sqrt(2) * (c7-c3) } + z2 := MULTIPLY(z2, - FIX_2_562915447); { sqrt(2) * (-c1-c3) } + z3 := MULTIPLY(z3, - FIX_1_961570560); { sqrt(2) * (-c3-c5) } + z4 := MULTIPLY(z4, - FIX_0_390180644); { sqrt(2) * (c5-c3) } + + Inc(z3, z5); + Inc(z4, z5); + + Inc(tmp0, z1 + z3); + Inc(tmp1, z2 + z4); + Inc(tmp2, z2 + z3); + Inc(tmp3, z1 + z4); + + { Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 } + + outptr^[0] := range_limit^[ int(DESCALE(tmp10 + tmp3, + CONST_BITS+PASS1_BITS+3)) + and RANGE_MASK]; + outptr^[7] := range_limit^[ int(DESCALE(tmp10 - tmp3, + CONST_BITS+PASS1_BITS+3)) + and RANGE_MASK]; + outptr^[1] := range_limit^[ int(DESCALE(tmp11 + tmp2, + CONST_BITS+PASS1_BITS+3)) + and RANGE_MASK]; + outptr^[6] := range_limit^[ int(DESCALE(tmp11 - tmp2, + CONST_BITS+PASS1_BITS+3)) + and RANGE_MASK]; + outptr^[2] := range_limit^[ int(DESCALE(tmp12 + tmp1, + CONST_BITS+PASS1_BITS+3)) + and RANGE_MASK]; + outptr^[5] := range_limit^[ int(DESCALE(tmp12 - tmp1, + CONST_BITS+PASS1_BITS+3)) + and RANGE_MASK]; + outptr^[3] := range_limit^[ int(DESCALE(tmp13 + tmp0, + CONST_BITS+PASS1_BITS+3)) + and RANGE_MASK]; + outptr^[4] := range_limit^[ int(DESCALE(tmp13 - tmp0, + CONST_BITS+PASS1_BITS+3)) + and RANGE_MASK]; + + Inc(int_ptr(wsptr), DCTSIZE); { advance pointer to next row } + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jidctred_del.pas b/mseide-msegui/lib/common/fpccompatibility/jidctred_del.pas new file mode 100644 index 0000000..612ce51 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jidctred_del.pas @@ -0,0 +1,526 @@ +unit jidctred_del; + + +{ This file contains inverse-DCT routines that produce reduced-size output: + either 4x4, 2x2, or 1x1 pixels from an 8x8 DCT block. + + The implementation is based on the Loeffler, Ligtenberg and Moschytz (LL&M) + algorithm used in jidctint.c. We simply replace each 8-to-8 1-D IDCT step + with an 8-to-4 step that produces the four averages of two adjacent outputs + (or an 8-to-2 step producing two averages of four outputs, for 2x2 output). + These steps were derived by computing the corresponding values at the end + of the normal LL&M code, then simplifying as much as possible. + + 1x1 is trivial: just take the DC coefficient divided by 8. + + See jidctint.c for additional comments. } + + +{ Original : jidctred.c ; Copyright (C) 1994-1998, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jpeglib_del, + jdct_del; { Private declarations for DCT subsystem } + +{ Perform dequantization and inverse DCT on one block of coefficients, + producing a reduced-size 1x1 output block. } + +{GLOBAL} +procedure jpeg_idct_1x1 (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + coef_block : JCOEFPTR; + output_buf : JSAMPARRAY; + output_col : JDIMENSION); + +{ Perform dequantization and inverse DCT on one block of coefficients, + producing a reduced-size 2x2 output block. } + +{GLOBAL} +procedure jpeg_idct_2x2 (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + coef_block : JCOEFPTR; + output_buf : JSAMPARRAY; + output_col : JDIMENSION); + +{ Perform dequantization and inverse DCT on one block of coefficients, + producing a reduced-size 4x4 output block. } + +{GLOBAL} +procedure jpeg_idct_4x4 (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + coef_block : JCOEFPTR; + output_buf : JSAMPARRAY; + output_col : JDIMENSION); + +implementation + +{ This module is specialized to the case DCTSIZE = 8. } + +{$ifndef DCTSIZE_IS_8} + Sorry, this code only copes with 8x8 DCTs. { deliberate syntax err } +{$endif} + + +{ Scaling is the same as in jidctint.c. } + +{$ifdef BITS_IN_JSAMPLE_IS_8} +const + CONST_BITS = 13; + PASS1_BITS = 2; +{$else} +const + CONST_BITS = 13; + PASS1_BITS = 1; { lose a little precision to avoid overflow } +{$endif} + +const + FIX_0_211164243 = INT32(Round((INT32(1) shl CONST_BITS) * 0.211164243)); {1730} + FIX_0_509795579 = INT32(Round((INT32(1) shl CONST_BITS) * 0.509795579)); {4176} + FIX_0_601344887 = INT32(Round((INT32(1) shl CONST_BITS) * 0.601344887)); {4926} + FIX_0_720959822 = INT32(Round((INT32(1) shl CONST_BITS) * 0.720959822)); {5906} + FIX_0_765366865 = INT32(Round((INT32(1) shl CONST_BITS) * 0.765366865)); {6270} + FIX_0_850430095 = INT32(Round((INT32(1) shl CONST_BITS) * 0.850430095)); {6967} + FIX_0_899976223 = INT32(Round((INT32(1) shl CONST_BITS) * 0.899976223)); {7373} + FIX_1_061594337 = INT32(Round((INT32(1) shl CONST_BITS) * 1.061594337)); {8697} + FIX_1_272758580 = INT32(Round((INT32(1) shl CONST_BITS) * 1.272758580)); {10426} + FIX_1_451774981 = INT32(Round((INT32(1) shl CONST_BITS) * 1.451774981)); {11893} + FIX_1_847759065 = INT32(Round((INT32(1) shl CONST_BITS) * 1.847759065)); {15137} + FIX_2_172734803 = INT32(Round((INT32(1) shl CONST_BITS) * 2.172734803)); {17799} + FIX_2_562915447 = INT32(Round((INT32(1) shl CONST_BITS) * 2.562915447)); {20995} + FIX_3_624509785 = INT32(Round((INT32(1) shl CONST_BITS) * 3.624509785)); {29692} + + +{ Multiply an INT32 variable by an INT32 constant to yield an INT32 result. + For 8-bit samples with the recommended scaling, all the variable + and constant values involved are no more than 16 bits wide, so a + 16x16->32 bit multiply can be used instead of a full 32x32 multiply. + For 12-bit samples, a full 32-bit multiplication will be needed. } + +{$ifdef BITS_IN_JSAMPLE_IS_8} + + {function Multiply(X, Y: Integer): integer; assembler; + asm + mov ax, X + imul Y + mov al, ah + mov ah, dl + end;} + + {MULTIPLY16C16(var,const)} + function Multiply(X, Y: Integer): INT32; + begin + Multiply := X*INT32(Y); + end; + + +{$else} + function Multiply(X, Y: INT32): INT32; + begin + Multiply := X*Y; + end; +{$endif} + + +{ Dequantize a coefficient by multiplying it by the multiplier-table + entry; produce an int result. In this module, both inputs and result + are 16 bits or less, so either int or short multiply will work. } + +function DEQUANTIZE(coef,quantval : int) : int; +begin + Dequantize := ( ISLOW_MULT_TYPE(coef) * quantval); +end; + + +{ Descale and correctly round an INT32 value that's scaled by N bits. + We assume RIGHT_SHIFT rounds towards minus infinity, so adding + the fudge factor is correct for either sign of X. } + +function DESCALE(x : INT32; n : int) : INT32; +var + shift_temp : INT32; +begin +{$ifdef RIGHT_SHIFT_IS_UNSIGNED} + shift_temp := x + (INT32(1) shl (n-1)); + if shift_temp < 0 then + Descale := (shift_temp shr n) or ((not INT32(0)) shl (32-n)) + else + Descale := (shift_temp shr n); +{$else} + Descale := (x + (INT32(1) shl (n-1)) shr n; +{$endif} +end; + +{ Perform dequantization and inverse DCT on one block of coefficients, + producing a reduced-size 4x4 output block. } + +{GLOBAL} +procedure jpeg_idct_4x4 (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + coef_block : JCOEFPTR; + output_buf : JSAMPARRAY; + output_col : JDIMENSION); +type + PWorkspace = ^TWorkspace; + TWorkspace = array[0..(DCTSIZE*4)-1] of int; { buffers data between passes } +var + tmp0, tmp2, tmp10, tmp12 : INT32; + z1, z2, z3, z4 : INT32; + inptr : JCOEFPTR; + quantptr : ISLOW_MULT_TYPE_FIELD_PTR; + wsptr : PWorkspace; + outptr : JSAMPROW; + range_limit : JSAMPROW; + ctr : int; + workspace : TWorkspace; { buffers data between passes } + {SHIFT_TEMPS} +var + dcval : int; +var + dcval_ : JSAMPLE; +begin +{ Each IDCT routine is responsible for range-limiting its results and + converting them to unsigned form (0..MAXJSAMPLE). The raw outputs could + be quite far out of range if the input data is corrupt, so a bulletproof + range-limiting step is required. We use a mask-and-table-lookup method + to do the combined operations quickly. See the comments with + prepare_range_limit_table (in jdmaster.c) for more info. } + + range_limit := JSAMPROW(@(cinfo^.sample_range_limit^[CENTERJSAMPLE])); + + { Pass 1: process columns from input, store into work array. } + + inptr := coef_block; + quantptr := ISLOW_MULT_TYPE_FIELD_PTR (compptr^.dct_table); + wsptr := @workspace; + for ctr := DCTSIZE downto 1 do + begin + { Don't bother to process column 4, because second pass won't use it } + if (ctr = DCTSIZE-4) then + begin + Inc(JCOEF_PTR(inptr)); + Inc(ISLOW_MULT_TYPE_PTR(quantptr)); + Inc(int_ptr(wsptr)); + + continue; + end; + if (inptr^[DCTSIZE*1]=0) and (inptr^[DCTSIZE*2]=0) and (inptr^[DCTSIZE*3]=0) and + (inptr^[DCTSIZE*5]=0) and (inptr^[DCTSIZE*6]=0) and (inptr^[DCTSIZE*7]=0) then + begin + { AC terms all zero; we need not examine term 4 for 4x4 output } + dcval := (ISLOW_MULT_TYPE(inptr^[DCTSIZE*0]) * + quantptr^[DCTSIZE*0]) shl PASS1_BITS; + + wsptr^[DCTSIZE*0] := dcval; + wsptr^[DCTSIZE*1] := dcval; + wsptr^[DCTSIZE*2] := dcval; + wsptr^[DCTSIZE*3] := dcval; + + Inc(JCOEF_PTR(inptr)); + Inc(ISLOW_MULT_TYPE_PTR(quantptr)); + Inc(int_ptr(wsptr)); + + continue; + end; + + { Even part } + + tmp0 := (ISLOW_MULT_TYPE(inptr^[DCTSIZE*0]) * quantptr^[DCTSIZE*0]); + + tmp0 := tmp0 shl (CONST_BITS+1); + + z2 := (ISLOW_MULT_TYPE(inptr^[DCTSIZE*2]) * quantptr^[DCTSIZE*2]); + z3 := (ISLOW_MULT_TYPE(inptr^[DCTSIZE*6]) * quantptr^[DCTSIZE*6]); + + tmp2 := MULTIPLY(z2, FIX_1_847759065) + MULTIPLY(z3, - FIX_0_765366865); + + tmp10 := tmp0 + tmp2; + tmp12 := tmp0 - tmp2; + + { Odd part } + + z1 := ISLOW_MULT_TYPE(inptr^[DCTSIZE*7]) * quantptr^[DCTSIZE*7]; + z2 := ISLOW_MULT_TYPE(inptr^[DCTSIZE*5]) * quantptr^[DCTSIZE*5]; + z3 := ISLOW_MULT_TYPE(inptr^[DCTSIZE*3]) * quantptr^[DCTSIZE*3]; + z4 := ISLOW_MULT_TYPE(inptr^[DCTSIZE*1]) * quantptr^[DCTSIZE*1]; + + tmp0 := MULTIPLY(z1, - FIX_0_211164243) { sqrt(2) * (c3-c1) } + + MULTIPLY(z2, FIX_1_451774981) { sqrt(2) * (c3+c7) } + + MULTIPLY(z3, - FIX_2_172734803) { sqrt(2) * (-c1-c5) } + + MULTIPLY(z4, FIX_1_061594337); { sqrt(2) * (c5+c7) } + + tmp2 := MULTIPLY(z1, - FIX_0_509795579) { sqrt(2) * (c7-c5) } + + MULTIPLY(z2, - FIX_0_601344887) { sqrt(2) * (c5-c1) } + + MULTIPLY(z3, FIX_0_899976223) { sqrt(2) * (c3-c7) } + + MULTIPLY(z4, FIX_2_562915447); { sqrt(2) * (c1+c3) } + + { Final output stage } + + wsptr^[DCTSIZE*0] := int(DESCALE(tmp10 + tmp2, CONST_BITS-PASS1_BITS+1)); + wsptr^[DCTSIZE*3] := int(DESCALE(tmp10 - tmp2, CONST_BITS-PASS1_BITS+1)); + wsptr^[DCTSIZE*1] := int(DESCALE(tmp12 + tmp0, CONST_BITS-PASS1_BITS+1)); + wsptr^[DCTSIZE*2] := int(DESCALE(tmp12 - tmp0, CONST_BITS-PASS1_BITS+1)); + + Inc(JCOEF_PTR(inptr)); + Inc(ISLOW_MULT_TYPE_PTR(quantptr)); + Inc(int_ptr(wsptr)); + end; + + { Pass 2: process 4 rows from work array, store into output array. } + + wsptr := @workspace; + for ctr := 0 to pred(4) do + begin + outptr := JSAMPROW(@ output_buf^[ctr]^[output_col]); + { It's not clear whether a zero row test is worthwhile here ... } + +{$ifndef NO_ZERO_ROW_TEST} + if (wsptr^[1]=0) and (wsptr^[2]=0) and (wsptr^[3]=0) and + (wsptr^[5]=0) and (wsptr^[6]=0) and (wsptr^[7]=0) then + begin + { AC terms all zero } + dcval_ := range_limit^[int(DESCALE(INT32(wsptr^[0]), PASS1_BITS+3)) + and RANGE_MASK]; + + outptr^[0] := dcval_; + outptr^[1] := dcval_; + outptr^[2] := dcval_; + outptr^[3] := dcval_; + + Inc(int_ptr(wsptr), DCTSIZE); { advance pointer to next row } + continue; + end; +{$endif} + + { Even part } + + tmp0 := (INT32(wsptr^[0])) shl (CONST_BITS+1); + + tmp2 := MULTIPLY(INT32(wsptr^[2]), FIX_1_847759065) + + MULTIPLY(INT32(wsptr^[6]), - FIX_0_765366865); + + tmp10 := tmp0 + tmp2; + tmp12 := tmp0 - tmp2; + + { Odd part } + + z1 := INT32(wsptr^[7]); + z2 := INT32(wsptr^[5]); + z3 := INT32(wsptr^[3]); + z4 := INT32(wsptr^[1]); + + tmp0 := MULTIPLY(z1, - FIX_0_211164243) { sqrt(2) * (c3-c1) } + + MULTIPLY(z2, FIX_1_451774981) { sqrt(2) * (c3+c7) } + + MULTIPLY(z3, - FIX_2_172734803) { sqrt(2) * (-c1-c5) } + + MULTIPLY(z4, FIX_1_061594337); { sqrt(2) * (c5+c7) } + + tmp2 := MULTIPLY(z1, - FIX_0_509795579) { sqrt(2) * (c7-c5) } + + MULTIPLY(z2, - FIX_0_601344887) { sqrt(2) * (c5-c1) } + + MULTIPLY(z3, FIX_0_899976223) { sqrt(2) * (c3-c7) } + + MULTIPLY(z4, FIX_2_562915447); { sqrt(2) * (c1+c3) } + + { Final output stage } + + outptr^[0] := range_limit^[ int(DESCALE(tmp10 + tmp2, + CONST_BITS+PASS1_BITS+3+1)) + and RANGE_MASK]; + outptr^[3] := range_limit^[ int(DESCALE(tmp10 - tmp2, + CONST_BITS+PASS1_BITS+3+1)) + and RANGE_MASK]; + outptr^[1] := range_limit^[ int(DESCALE(tmp12 + tmp0, + CONST_BITS+PASS1_BITS+3+1)) + and RANGE_MASK]; + outptr^[2] := range_limit^[ int(DESCALE(tmp12 - tmp0, + CONST_BITS+PASS1_BITS+3+1)) + and RANGE_MASK]; + + Inc(int_ptr(wsptr), DCTSIZE); { advance pointer to next row } + end; +end; + + +{ Perform dequantization and inverse DCT on one block of coefficients, + producing a reduced-size 2x2 output block. } + +{GLOBAL} +procedure jpeg_idct_2x2 (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + coef_block : JCOEFPTR; + output_buf : JSAMPARRAY; + output_col : JDIMENSION); +type + PWorkspace = ^TWorkspace; + TWorkspace = array[0..(DCTSIZE*2)-1] of int; { buffers data between passes } +var + tmp0, tmp10, z1 : INT32; + inptr : JCOEFPTR; + quantptr : ISLOW_MULT_TYPE_FIELD_PTR; + wsptr : PWorkspace; + outptr : JSAMPROW; + range_limit : JSAMPROW; + ctr : int; + workspace : TWorkspace; { buffers data between passes } + {SHIFT_TEMPS} +var + dcval : int; +var + dcval_ : JSAMPLE; +begin +{ Each IDCT routine is responsible for range-limiting its results and + converting them to unsigned form (0..MAXJSAMPLE). The raw outputs could + be quite far out of range if the input data is corrupt, so a bulletproof + range-limiting step is required. We use a mask-and-table-lookup method + to do the combined operations quickly. See the comments with + prepare_range_limit_table (in jdmaster.c) for more info. } + + range_limit := JSAMPROW(@(cinfo^.sample_range_limit^[CENTERJSAMPLE])); + { Pass 1: process columns from input, store into work array. } + + inptr := coef_block; + quantptr := ISLOW_MULT_TYPE_FIELD_PTR (compptr^.dct_table); + wsptr := @workspace; + for ctr := DCTSIZE downto 1 do + begin + { Don't bother to process columns 2,4,6 } + if (ctr = DCTSIZE-2) or (ctr = DCTSIZE-4) or (ctr = DCTSIZE-6) then + begin + Inc(JCOEF_PTR(inptr)); + Inc(ISLOW_MULT_TYPE_PTR(quantptr)); + Inc(int_ptr(wsptr)); + + continue; + end; + if (inptr^[DCTSIZE*1]=0) and (inptr^[DCTSIZE*3]=0) and + (inptr^[DCTSIZE*5]=0) and (inptr^[DCTSIZE*7]=0) then + begin + { AC terms all zero; we need not examine terms 2,4,6 for 2x2 output } + dcval := (ISLOW_MULT_TYPE(inptr^[DCTSIZE*0]) * + quantptr^[DCTSIZE*0]) shl PASS1_BITS; + + wsptr^[DCTSIZE*0] := dcval; + wsptr^[DCTSIZE*1] := dcval; + + Inc(JCOEF_PTR(inptr)); + Inc(ISLOW_MULT_TYPE_PTR(quantptr)); + Inc(int_ptr(wsptr)); + + continue; + end; + + { Even part } + + z1 := (ISLOW_MULT_TYPE(inptr^[DCTSIZE*0]) * quantptr^[DCTSIZE*0]); + + tmp10 := z1 shl (CONST_BITS+2); + + { Odd part } + + z1 := (ISLOW_MULT_TYPE(inptr^[DCTSIZE*7]) * quantptr^[DCTSIZE*7]); + tmp0 := MULTIPLY(z1, - FIX_0_720959822); { sqrt(2) * (c7-c5+c3-c1) } + z1 := (ISLOW_MULT_TYPE(inptr^[DCTSIZE*5]) * quantptr^[DCTSIZE*5]); + Inc(tmp0, MULTIPLY(z1, FIX_0_850430095)); { sqrt(2) * (-c1+c3+c5+c7) } + z1 := (ISLOW_MULT_TYPE(inptr^[DCTSIZE*3]) * quantptr^[DCTSIZE*3]); + Inc(tmp0, MULTIPLY(z1, - FIX_1_272758580)); { sqrt(2) * (-c1+c3-c5-c7) } + z1 := (ISLOW_MULT_TYPE(inptr^[DCTSIZE*1]) * quantptr^[DCTSIZE*1]); + Inc(tmp0, MULTIPLY(z1, FIX_3_624509785)); { sqrt(2) * (c1+c3+c5+c7) } + + { Final output stage } + + wsptr^[DCTSIZE*0] := int (DESCALE(tmp10 + tmp0, CONST_BITS-PASS1_BITS+2)); + wsptr^[DCTSIZE*1] := int (DESCALE(tmp10 - tmp0, CONST_BITS-PASS1_BITS+2)); + + Inc(JCOEF_PTR(inptr)); + Inc(ISLOW_MULT_TYPE_PTR(quantptr)); + Inc(int_ptr(wsptr)); + end; + + { Pass 2: process 2 rows from work array, store into output array. } + + wsptr := @workspace; + for ctr := 0 to pred(2) do + begin + outptr := JSAMPROW(@ output_buf^[ctr]^[output_col]); + { It's not clear whether a zero row test is worthwhile here ... } + +{$ifndef NO_ZERO_ROW_TEST} + if (wsptr^[1]=0) and (wsptr^[3]=0) and (wsptr^[5]=0) and (wsptr^[7]= 0) then + begin + { AC terms all zero } + dcval_ := range_limit^[ int(DESCALE(INT32(wsptr^[0]), PASS1_BITS+3)) + and RANGE_MASK]; + + outptr^[0] := dcval_; + outptr^[1] := dcval_; + + Inc(int_ptr(wsptr), DCTSIZE); { advance pointer to next row } + continue; + end; +{$endif} + + { Even part } + + tmp10 := (INT32 (wsptr^[0])) shl (CONST_BITS+2); + + { Odd part } + + tmp0 := MULTIPLY( INT32(wsptr^[7]), - FIX_0_720959822) { sqrt(2) * (c7-c5+c3-c1) } + + MULTIPLY( INT32(wsptr^[5]), FIX_0_850430095) { sqrt(2) * (-c1+c3+c5+c7) } + + MULTIPLY( INT32(wsptr^[3]), - FIX_1_272758580) { sqrt(2) * (-c1+c3-c5-c7) } + + MULTIPLY( INT32(wsptr^[1]), FIX_3_624509785); { sqrt(2) * (c1+c3+c5+c7) } + + { Final output stage } + + outptr^[0] := range_limit^[ int(DESCALE(tmp10 + tmp0, + CONST_BITS+PASS1_BITS+3+2)) + and RANGE_MASK]; + outptr^[1] := range_limit^[ int(DESCALE(tmp10 - tmp0, + CONST_BITS+PASS1_BITS+3+2)) + and RANGE_MASK]; + + Inc(int_ptr(wsptr), DCTSIZE); { advance pointer to next row } + end; +end; + + +{ Perform dequantization and inverse DCT on one block of coefficients, + producing a reduced-size 1x1 output block. } + +{GLOBAL} +procedure jpeg_idct_1x1 (cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + coef_block : JCOEFPTR; + output_buf : JSAMPARRAY; + output_col : JDIMENSION); +var + dcval : int; + quantptr : ISLOW_MULT_TYPE_FIELD_PTR; + range_limit : JSAMPROW; + {SHIFT_TEMPS} +begin +{ Each IDCT routine is responsible for range-limiting its results and + converting them to unsigned form (0..MAXJSAMPLE). The raw outputs could + be quite far out of range if the input data is corrupt, so a bulletproof + range-limiting step is required. We use a mask-and-table-lookup method + to do the combined operations quickly. See the comments with + prepare_range_limit_table (in jdmaster.c) for more info. } + + range_limit := JSAMPROW(@(cinfo^.sample_range_limit^[CENTERJSAMPLE])); + { Pass 1: process columns from input, store into work array. } + + { We hardly need an inverse DCT routine for this: just take the + average pixel value, which is one-eighth of the DC coefficient. } + + quantptr := ISLOW_MULT_TYPE_FIELD_PTR (compptr^.dct_table); + dcval := (ISLOW_MULT_TYPE(coef_block^[0]) * quantptr^[0]); + dcval := int (DESCALE( INT32(dcval), 3)); + + output_buf^[0]^[output_col] := range_limit^[dcval and RANGE_MASK]; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jinclude_del.pas b/mseide-msegui/lib/common/fpccompatibility/jinclude_del.pas new file mode 100644 index 0000000..1a88663 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jinclude_del.pas @@ -0,0 +1,127 @@ +Unit jinclude_del; + +{ This file exists to provide a single place to fix any problems with + including the wrong system include files. (Common problems are taken + care of by the standard jconfig symbols, but on really weird systems + you may have to edit this file.) + + NOTE: this file is NOT intended to be included by applications using the + JPEG library. Most applications need only include jpeglib.h. } + +{ Original: jinclude.h Copyright (C) 1991-1994, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +{ Include auto-config file to find out which system include files we need. } + +uses +{$ifdef Delphi_Stream} + classes, mclasses, +{$endif} + jmorecfg_del; + +{ Nomssi: + To write a dest/source manager that handle streams rather than files, + you can edit the FILEptr definition and the JFREAD() and JFWRITE() + functions in this unit, you don't need to change the default managers + JDATASRC and JDATADST. } + +{$ifdef Delphi_Stream} +type + FILEptr = ^TStream; +{$else} + {$ifdef Delphi_Jpeg} + type + FILEptr = TCustomMemoryStream; + {$else} + type + FILEptr = ^File; + {$endif} +{$endif} + +{ We need the NULL macro and size_t typedef. + On an ANSI-conforming system it is sufficient to include . + Otherwise, we get them from or ; we may have to + pull in as well. + Note that the core JPEG library does not require ; + only the default error handler and data source/destination modules do. + But we must pull it in because of the references to FILE in jpeglib.h. + You can remove those references if you want to compile without .} + + + +{ We need memory copying and zeroing functions, plus strncpy(). + ANSI and System V implementations declare these in . + BSD doesn't have the mem() functions, but it does have bcopy()/bzero(). + Some systems may declare memset and memcpy in . + + NOTE: we assume the size parameters to these functions are of type size_t. + Change the casts in these macros if not! } + +procedure MEMZERO(target : pointer; size : size_t); + +procedure MEMCOPY(dest, src : pointer; size : size_t); + +{function SIZEOF(object) : size_t;} + +function JFREAD(fp : FILEptr; buf : pointer; sizeofbuf : size_t) : size_t; + +function JFWRITE(fp : FILEptr; buf : pointer; sizeofbuf : size_t) : size_t; + +implementation + +procedure MEMZERO(target : pointer; size : size_t); +begin + FillChar(target^, size, 0); +end; + +procedure MEMCOPY(dest, src : pointer; size : size_t); +begin + Move(src^, dest^, size); +end; + +{ In ANSI C, and indeed any rational implementation, size_t is also the + type returned by sizeof(). However, it seems there are some irrational + implementations out there, in which sizeof() returns an int even though + size_t is defined as long or unsigned long. To ensure consistent results + we always use this SIZEOF() macro in place of using sizeof() directly. } + + +{#define + SIZEOF(object) (size_t(sizeof(object))} + + +{ The modules that use fread() and fwrite() always invoke them through + these macros. On some systems you may need to twiddle the argument casts. + CAUTION: argument order is different from underlying functions! } + + +function JFREAD(fp : FILEptr; buf : pointer; sizeofbuf : size_t) : size_t; +var + count : uint; +begin + {$ifdef Delphi_Stream} + count := fp^.Read(buf^, sizeofbuf); + {$else} + blockread(fp^, buf^, sizeofbuf, count); + {$endif} + JFREAD := size_t(count); +end; + +function JFWRITE(fp : FILEptr; buf : pointer; sizeofbuf : size_t) : size_t; +var + count : uint; +begin + {$ifdef Delphi_Stream} + count := fp^.Write(buf^, sizeofbuf); + {$else} + blockwrite(fp^, buf^, sizeofbuf, count); + {$endif} + JFWRITE := size_t(count); +end; + + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jmemdos_del.pas b/mseide-msegui/lib/common/fpccompatibility/jmemdos_del.pas new file mode 100644 index 0000000..f48835d --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jmemdos_del.pas @@ -0,0 +1,780 @@ +Unit JmemDos; + + +{ This file provides an MS-DOS-compatible implementation of the system- + dependent portion of the JPEG memory manager. Temporary data can be + stored in extended or expanded memory as well as in regular DOS files. + + If you use this file, you must be sure that NEED_FAR_POINTERS is defined + if you compile in a small-data memory model; it should NOT be defined if + you use a large-data memory model. This file is not recommended if you + are using a flat-memory-space 386 environment such as DJGCC or Watcom C. + Also, this code will NOT work if struct fields are aligned on greater than + 2-byte boundaries. + + Based on code contributed by Ge' Weijers. } + +{ Original: jmemdos.c; Copyright (C) 1992-1996, Thomas G. Lane. } + + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg, + jpeglib; + +{ If you have both extended and expanded memory, you may want to change the + order in which they are tried in jopen_backing_store. On a 286 machine + expanded memory is usually faster, since extended memory access involves + an expensive protected-mode-and-back switch. On 386 and better, extended + memory is usually faster. As distributed, the code tries extended memory + first (what? not everyone has a 386? :-). + + You can disable use of extended/expanded memory entirely by altering these + definitions or overriding them from the Makefile (eg, -DEMS_SUPPORTED=0).} + +{GLOBAL} +procedure jpeg_open_backing_store (cinfo : j_common_ptr; + info : backing_store_ptr; + total_bytes_needed : long); + +{ These routines take care of any system-dependent initialization and + cleanup required. } + +{GLOBAL} +function jpeg_mem_init (cinfo : j_common_ptr) : long; + +{GLOBAL} +procedure jpeg_mem_term (cinfo : j_common_ptr); + +{ These two functions are used to allocate and release small chunks of + memory. (Typically the total amount requested through jpeg_get_small is + no more than 20K or so; this will be requested in chunks of a few K each.) + Behavior should be the same as for the standard library functions malloc + and free; in particular, jpeg_get_small must return NIL on failure. + On most systems, these ARE malloc and free. jpeg_free_small is passed the + size of the object being freed, just in case it's needed. + On an 80x86 machine using small-data memory model, these manage near heap. } + + +{ Near-memory allocation and freeing are controlled by the regular library + routines malloc() and free(). } + +{GLOBAL} +function jpeg_get_small (cinfo : j_common_ptr; + sizeofobject : size_t) : pointer; + +{GLOBAL} +{object is a reserved word in Borland Pascal } +procedure jpeg_free_small (cinfo : j_common_ptr; + an_object : pointer; + sizeofobject : size_t); + +{ These two functions are used to allocate and release large chunks of + memory (up to the total free space designated by jpeg_mem_available). + The interface is the same as above, except that on an 80x86 machine, + far pointers are used. On most other machines these are identical to + the jpeg_get/free_small routines; but we keep them separate anyway, + in case a different allocation strategy is desirable for large chunks. } + + +{ "Large" objects are allocated in far memory, if possible } + + +{GLOBAL} +function jpeg_get_large (cinfo : j_common_ptr; + sizeofobject : size_t) : voidp; {far} + +{GLOBAL} +procedure jpeg_free_large (cinfo : j_common_ptr; + {var?} an_object : voidp; {FAR} + sizeofobject : size_t); + +{ This routine computes the total memory space available for allocation. + It's impossible to do this in a portable way; our current solution is + to make the user tell us (with a default value set at compile time). + If you can actually get the available space, it's a good idea to subtract + a slop factor of 5% or so. } + +{GLOBAL} +function jpeg_mem_available (cinfo : j_common_ptr; + min_bytes_needed : long; + max_bytes_needed : long; + already_allocated : long) : long; + + +{ The macro MAX_ALLOC_CHUNK designates the maximum number of bytes that may + be requested in a single call to jpeg_get_large (and jpeg_get_small for that + matter, but that case should never come into play). This macro is needed + to model the 64Kb-segment-size limit of far addressing on 80x86 machines. + On those machines, we expect that jconfig.h will provide a proper value. + On machines with 32-bit flat address spaces, any large constant may be used. + + NB: jmemmgr.c expects that MAX_ALLOC_CHUNK will be representable as type + size_t and will be a multiple of sizeof(align_type). } + + +{$ifdef USE_MSDOS_MEMMGR} { Define this if you use jmemdos.c } +const + MAX_ALLOC_CHUNK = long(32752); {65520} { Maximum request to malloc() } + { MAX_ALLOC_CHUNK should be less than 64K. } +{$else} +const + MAX_ALLOC_CHUNK = long(1000000000); +{$endif} + +implementation + +uses + dos, + jmemdosa, + jdeferr, + jerror; + + + +{ Selection of a file name for a temporary file. + This is highly system-dependent, and you may want to customize it. } + +var + next_file_num : int; { to distinguish among several temp files } + +{LOCAL} +procedure select_file_name (var fname : TEMP_STRING); +var + env : string; + suffix, + prefix : TEMP_STRING; + tfile : FILE; + l : byte; +begin + { Keep generating file names till we find one that's not in use } + while TRUE do + begin + { Get temp directory name from environment TMP or TEMP variable; + if none, use "." } + env := getenv('TMP'); + if (env = '') then + begin + env := getenv('TEMP'); + if (env = '') then { null string means "." } + env := '.'; + end; + prefix := env; { copy name to fname } + { length(fname) > 0 !! } + if (prefix[length(prefix)] <> '\') + and (prefix[length(prefix)] <> '/') then + prefix := prefix + '\'; { append backslash if not in env variable } + { Append a suitable file name } + Inc(next_file_num); { advance counter } + + Str(next_file_num, suffix); + for l := Length(suffix)+1 to 3 do + suffix := '0' + suffix; + fname := prefix + 'JPG' + suffix + '.TMP'; + { Probe to see if file name is already in use } + system.assign(tfile, fname); + {$ifdef IoCheck} {$I-} {$endif} + system.reset(tfile, 1); + {$ifdef IoCheck} {$I+} {$endif} + if (IOresult <> 0) then + begin + fname := fname + #0; + break; + end; + system.close(tfile); { oops, it's there; close tfile & try again } + end; +end; + +{ These two functions are used to allocate and release small chunks of + memory. (Typically the total amount requested through jpeg_get_small is + no more than 20K or so; this will be requested in chunks of a few K each.) + Behavior should be the same as for the standard library functions malloc + and free; in particular, jpeg_get_small must return NIL on failure. + On most systems, these ARE malloc and free. jpeg_free_small is passed the + size of the object being freed, just in case it's needed. + On an 80x86 machine using small-data memory model, these manage near heap. } + + +{ Near-memory allocation and freeing are controlled by the regular library + routines malloc() and free(). } + +{GLOBAL} +function jpeg_get_small (cinfo : j_common_ptr; + sizeofobject : size_t) : pointer; +var + p : pointer; +begin + getmem(p, sizeofobject); + jpeg_get_small := p; +end; + +{GLOBAL} +{object is a reserved word in Borland Pascal } +procedure jpeg_free_small (cinfo : j_common_ptr; + an_object : pointer; + sizeofobject : size_t); +begin + freemem(an_object, sizeofobject); +end; + +{ These two functions are used to allocate and release large chunks of + memory (up to the total free space designated by jpeg_mem_available). + The interface is the same as above, except that on an 80x86 machine, + far pointers are used. On most other machines these are identical to + the jpeg_get/free_small routines; but we keep them separate anyway, + in case a different allocation strategy is desirable for large chunks. } + + +{GLOBAL} +function jpeg_get_large (cinfo : j_common_ptr; + sizeofobject : size_t) : voidp; {far} +var + p : voidp; {FAR} +begin + {far_malloc;} + getmem(p, sizeofobject); + jpeg_get_large := p; +end; + +{GLOBAL} +procedure jpeg_free_large (cinfo : j_common_ptr; + {var?} an_object : voidp; {FAR} + sizeofobject : size_t); +begin + {far_free(an_object);} + FreeMem(an_object, sizeofobject); +end; + +{ This routine computes the total space still available for allocation by + jpeg_get_large. If more space than this is needed, backing store will be + used. NOTE: any memory already allocated must not be counted. + + There is a minimum space requirement, corresponding to the minimum + feasible buffer sizes; jmemmgr.c will request that much space even if + jpeg_mem_available returns zero. The maximum space needed, enough to hold + all working storage in memory, is also passed in case it is useful. + Finally, the total space already allocated is passed. If no better + method is available, cinfo->mem->max_memory_to_use - already_allocated + is often a suitable calculation. + + It is OK for jpeg_mem_available to underestimate the space available + (that'll just lead to more backing-store access than is really necessary). + However, an overestimate will lead to failure. Hence it's wise to subtract + a slop factor from the true available space. 5% should be enough. + + On machines with lots of virtual memory, any large constant may be returned. + Conversely, zero may be returned to always use the minimum amount of memory.} + + + +{ This routine computes the total memory space available for allocation. + It's impossible to do this in a portable way; our current solution is + to make the user tell us (with a default value set at compile time). + If you can actually get the available space, it's a good idea to subtract + a slop factor of 5% or so. } + +const + DEFAULT_MAX_MEM = long(300000); { for total usage about 450K } + +{GLOBAL} +function jpeg_mem_available (cinfo : j_common_ptr; + min_bytes_needed : long; + max_bytes_needed : long; + already_allocated : long) : long; +begin + {jpeg_mem_available := cinfo^.mem^.max_memory_to_use - already_allocated;} + jpeg_mem_available := MaxAvail*95 div 100; { 95% } + + { Nomssi: limit the available memory for test purpose } + {jpeg_mem_available := 30000;} +end; + + +{ Backing store (temporary file) management. + Backing store objects are only used when the value returned by + jpeg_mem_available is less than the total space needed. You can dispense + with these routines if you have plenty of virtual memory; see jmemnobs.c. } + + +{ For MS-DOS we support three types of backing storage: + 1. Conventional DOS files. We access these by direct DOS calls rather + than via the stdio package. This provides a bit better performance, + but the real reason is that the buffers to be read or written are FAR. + The stdio library for small-data memory models can't cope with that. + 2. Extended memory, accessed per the XMS V2.0 specification. + 3. Expanded memory, accessed per the LIM/EMS 4.0 specification. + You'll need copies of those specs to make sense of the related code. + The specs are available by Internet FTP from the SIMTEL archives + (oak.oakland.edu and its various mirror sites). See files + pub/msdos/microsoft/xms20.arc and pub/msdos/info/limems41.zip. } + + + +{ Access methods for a DOS file. } + + +{METHODDEF} +procedure read_file_store (cinfo : j_common_ptr; + info : backing_store_ptr; + buffer_address : pointer; {FAR} + file_offset : long; + byte_count : long); +begin + if jdos_seek(info^.handle.file_handle, file_offset) <> 0 then + ERREXIT(cinfo, JERR_TFILE_SEEK); + { Since MAX_ALLOC_CHUNK is less than 64K, byte_count will be too. } + if (byte_count > long(65535)) then { safety check } + ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK); + if jdos_read(info^.handle.file_handle, buffer_address, + ushort(byte_count)) <> 0 then + ERREXIT(cinfo, JERR_TFILE_READ); +end; + + +{METHODDEF} +procedure write_file_store (cinfo : j_common_ptr; + info : backing_store_ptr; + buffer_address : pointer; {FAR} + file_offset : long; + byte_count : long); +begin + if (jdos_seek(info^.handle.file_handle, file_offset)) <> 0 then + ERREXIT(cinfo, JERR_TFILE_SEEK); + { Since MAX_ALLOC_CHUNK is less than 64K, byte_count will be too. } + if (byte_count > long(65535)) then { safety check } + ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK); + if jdos_write(info^.handle.file_handle, buffer_address, + ushort(byte_count)) <> 0 then + ERREXIT(cinfo, JERR_TFILE_WRITE); +end; + + +{METHODDEF} +procedure close_file_store (cinfo : j_common_ptr; + info : backing_store_ptr); +var + f : FILE; +begin + jdos_close(info^.handle.file_handle); { close the file } + + system.assign(f, info^.temp_name); + system.erase(f); { delete the file } +{ If your system doesn't have remove(), try unlink() instead. + remove() is the ANSI-standard name for this function, but + unlink() was more common in pre-ANSI systems. } + + TRACEMSS(cinfo, 1, JTRC_TFILE_CLOSE, info^.temp_name); +end; + + +{LOCAL} +function open_file_store (cinfo : j_common_ptr; + info : backing_store_ptr; + total_bytes_needed : long): boolean; +var + handle : short; +begin + select_file_name(info^.temp_name); + if jdos_open(handle, info^.temp_name[1]) <> 0 then + begin + { might as well exit since jpeg_open_backing_store will fail anyway } + ERREXITS(cinfo, JERR_TFILE_CREATE, info^.temp_name); + open_file_store := FALSE; + exit; + end; + info^.handle.file_handle := handle; + info^.read_backing_store := read_file_store; + info^.write_backing_store := write_file_store; + info^.close_backing_store := close_file_store; + TRACEMSS(cinfo, 1, JTRC_TFILE_OPEN, info^.temp_name); + open_file_store := TRUE; { succeeded } +end; + + +{ Access methods for extended memory. } + +{$ifdef XMS_SUPPORTED} + +var + xms_driver : XMSDRIVER; { saved address of XMS driver } + +type + XMSPTR = record { either long offset or real-mode pointer } + case byte of + 0:(offset : long); + 1:(ptr : pointer {FAR}); + end; + +type + XMSspec = record { XMS move specification structure } + length : long; + src_handle : XMSH; + src : XMSPTR; + dst_handle : XMSH; + dst : XMSPTR; + end; +type + TByteArray = Array[0..MAX_ALLOC_CHUNK-1] of byte; + +{METHODDEF} +procedure read_xms_store (cinfo : j_common_ptr; + info : backing_store_ptr; + buffer_address : pointer; {FAR} + file_offset : long; + byte_count : long); +var + ctx : XMScontext; + spec : XMSspec; + endbuffer : packed array[0..1] of byte; +begin + { The XMS driver can't cope with an odd length, so handle the last byte + specially if byte_count is odd. We don't expect this to be common. } + + + spec.length := byte_count and (not long(1)); + spec.src_handle := info^.handle.xms_handle; + spec.src.offset := file_offset; + spec.dst_handle := 0; + spec.dst.ptr := buffer_address; + + ctx.ds_si := addr(spec); + ctx.ax := $0b00; { EMB move } + jxms_calldriver(xms_driver, ctx); + if (ctx.ax <> 1) then + ERREXIT(cinfo, JERR_XMS_READ); + + if odd(byte_count) then + begin + read_xms_store(cinfo, info, pointer(@endbuffer) {FAR}, + file_offset + byte_count - long(1), long(2)); + TByteArray(buffer_address^)[byte_count - long(1)] := endbuffer[0]; + end; +end; + + +{METHODDEF} +procedure write_xms_store (cinfo : j_common_ptr; + info : backing_store_ptr; + buffer_address : pointer; {FAR} + file_offset : long; + byte_count : long); +var + ctx : XMScontext; + spec : XMSspec; + endbuffer : packed array[0..1] of byte; +begin + { The XMS driver can't cope with an odd length, so handle the last byte + specially if byte_count is odd. We don't expect this to be common. } + + spec.length := byte_count and (not long(1)); + spec.src_handle := 0; + spec.src.ptr := buffer_address; + spec.dst_handle := info^.handle.xms_handle; + spec.dst.offset := file_offset; + + ctx.ds_si := addr(spec); + ctx.ax := $0b00; { EMB move } + jxms_calldriver(xms_driver, ctx); + if (ctx.ax <> 1) then + ERREXIT(cinfo, JERR_XMS_WRITE); + + if odd(byte_count) then + begin + read_xms_store(cinfo, info, pointer(@endbuffer) {FAR}, + file_offset + byte_count - long(1), long(2)); + endbuffer[0] := TByteArray(buffer_address^)[byte_count - long(1)]; + write_xms_store(cinfo, info, pointer(@endbuffer) {FAR}, + file_offset + byte_count - long(1), long(2)); + end; +end; + + +{METHODDEF} +procedure close_xms_store (cinfo : j_common_ptr; + info : backing_store_ptr); +var + ctx : XMScontext; +begin + ctx.dx := info^.handle.xms_handle; + ctx.ax := $0a00; + jxms_calldriver(xms_driver, ctx); + TRACEMS1(cinfo, 1, JTRC_XMS_CLOSE, info^.handle.xms_handle); + { we ignore any error return from the driver } +end; + + +{LOCAL} +function open_xms_store (cinfo : j_common_ptr; + info : backing_store_ptr; + total_bytes_needed : long) : boolean; +var + ctx : XMScontext; +begin + { Get address of XMS driver } + jxms_getdriver(xms_driver); + if (xms_driver = NIL) then + begin + open_xms_store := FALSE; { no driver to be had } + exit; + end; + + { Get version number, must be >= 2.00 } + ctx.ax := $0000; + jxms_calldriver(xms_driver, ctx); + if (ctx.ax < ushort($0200)) then + begin + open_xms_store := FALSE; + exit; + end; + + { Try to get space (expressed in kilobytes) } + ctx.dx := ushort ((total_bytes_needed + long(1023)) shr 10); + ctx.ax := $0900; + jxms_calldriver(xms_driver, ctx); + if (ctx.ax <> 1) then + begin + open_xms_store := FALSE; + exit; + end; + + { Succeeded, save the handle and away we go } + info^.handle.xms_handle := ctx.dx; + info^.read_backing_store := read_xms_store; + info^.write_backing_store := write_xms_store; + info^.close_backing_store := close_xms_store; + TRACEMS1(cinfo, 1, JTRC_XMS_OPEN, ctx.dx); + open_xms_store := TRUE; { succeeded } +end; + +{$endif} { XMS_SUPPORTED } + + +{ Access methods for expanded memory. } + +{$ifdef EMS_SUPPORTED} + +{ The EMS move specification structure requires word and long fields aligned + at odd byte boundaries. Some compilers will align struct fields at even + byte boundaries. While it's usually possible to force byte alignment, + that causes an overall performance penalty and may pose problems in merging + JPEG into a larger application. Instead we accept some rather dirty code + here. Note this code would fail if the hardware did not allow odd-byte + word & long accesses, but all 80x86 CPUs do. } + + +type + EMSPTR = pointer; {FAR} + + +{ types for accessing misaligned fields } +type + EMSAddrStruct = packed record {Size } + MemType : byte; { emsConventional, emsExpanded } { 1 } + Handle : word; { TEMSHandle; } { 2 } + case integer of {union} + 0 : (Offs : word; { 2 } + Page : word); { 2 } + 1 : (Ptr : pointer); {or 4 } + end; + { EMS move specification structure } + EMSspec = packed record + length : longint; { 4 } + src : EMSAddrStruct; { 7 } + dst : EMSAddrStruct; { 7 } + end; + + +const + EMSPAGESIZE = long(16384); { gospel, see the EMS specs } + + +{METHODDEF} +procedure read_ems_store (cinfo : j_common_ptr; + info : backing_store_ptr; + buffer_address : pointer; {FAR} + file_offset : long; + byte_count : long); +var + ctx : EMScontext; + spec : EMSspec; +begin + spec.length := byte_count; + spec.src.memtype := 1; + spec.src.handle := info^.handle.ems_handle; + spec.src.page := ushort (file_offset div EMSPAGESIZE); + spec.src.offs := ushort (file_offset mod EMSPAGESIZE); + spec.dst.memtype := 0; + spec.dst.handle := 0; + spec.dst.ptr := buffer_address; + + ctx.ds_si := addr(spec); + ctx.ax := $5700; { move memory region } + jems_calldriver(ctx); + if (hi(ctx.ax) <> 0) then + ERREXIT(cinfo, JERR_EMS_READ); +end; + + +{METHODDEF} +procedure write_ems_store (cinfo : j_common_ptr; + info : backing_store_ptr; + buffer_address : pointer; {FAR} + file_offset : long; + byte_count : long); +var + ctx : EMScontext; + spec : EMSspec; +begin + spec.length := byte_count; + spec.src.memtype := 0; + spec.src.handle := 0; + spec.src.ptr := buffer_address; + spec.dst.memtype := 1; + spec.dst.handle := info^.handle.ems_handle; + spec.dst.page := ushort (file_offset div EMSPAGESIZE); + spec.dst.offs := ushort (file_offset mod EMSPAGESIZE); + + ctx.ds_si := addr(spec); + ctx.ax := $5700; { move memory region } + jems_calldriver(ctx); + if (hi(ctx.ax) <> 0) then + ERREXIT(cinfo, JERR_EMS_WRITE); +end; + + +{METHODDEF} +procedure close_ems_store (cinfo : j_common_ptr; + info : backing_store_ptr); +var + ctx : EMScontext; +begin + ctx.ax := $4500; + ctx.dx := info^.handle.ems_handle; + jems_calldriver(ctx); + TRACEMS1(cinfo, 1, JTRC_EMS_CLOSE, info^.handle.ems_handle); + { we ignore any error return from the driver } +end; + + +{LOCAL} +function open_ems_store (cinfo : j_common_ptr; + info : backing_store_ptr; + total_bytes_needed : long) : boolean; +var + ctx : EMScontext; +begin + { Is EMS driver there? } + if (jems_available = 0) then + begin + open_ems_store := FALSE; + exit; + end; + + { Get status, make sure EMS is OK } + ctx.ax := $4000; + jems_calldriver(ctx); + if (hi(ctx.ax) <> 0) then + begin + open_ems_store := FALSE; + exit; + end; + + { Get version, must be >= 4.0 } + ctx.ax := $4600; + jems_calldriver(ctx); + if (hi(ctx.ax) <> 0) or (lo(ctx.ax) < $40) then + begin + open_ems_store := FALSE; + exit; + end; + + { Try to allocate requested space } + ctx.ax := $4300; + ctx.bx := ushort ((total_bytes_needed + + EMSPAGESIZE-long(1)) div EMSPAGESIZE); + jems_calldriver(ctx); + if (hi(ctx.ax) <> 0) then + begin + open_ems_store := FALSE; + exit; + end; + + { Succeeded, save the handle and away we go } + info^.handle.ems_handle := ctx.dx; + info^.read_backing_store := read_ems_store; + info^.write_backing_store := write_ems_store; + info^.close_backing_store := close_ems_store; + TRACEMS1(cinfo, 1, JTRC_EMS_OPEN, ctx.dx); + open_ems_store := TRUE; { succeeded } +end; + +{$endif} { EMS_SUPPORTED } + +{ Initial opening of a backing-store object. This must fill in the + read/write/close pointers in the object. The read/write routines + may take an error exit if the specified maximum file size is exceeded. + (If jpeg_mem_available always returns a large value, this routine can + just take an error exit.) } + + + + +{ Initial opening of a backing-store object. } + +{GLOBAL} +procedure jpeg_open_backing_store (cinfo : j_common_ptr; + info : backing_store_ptr; + total_bytes_needed : long); +begin + { Try extended memory, then expanded memory, then regular file. } +{$ifdef XMS_SUPPORTED} + if (open_xms_store(cinfo, info, total_bytes_needed)) then + exit; +{$endif} +{$ifdef EMS_SUPPORTED} + if (open_ems_store(cinfo, info, total_bytes_needed)) then + exit; +{$endif} + if (open_file_store(cinfo, info, total_bytes_needed)) then + exit; + ERREXITS(cinfo, JERR_TFILE_CREATE, ''); +end; + +{ These routines take care of any system-dependent initialization and + cleanup required. jpeg_mem_init will be called before anything is + allocated (and, therefore, nothing in cinfo is of use except the error + manager pointer). It should return a suitable default value for + max_memory_to_use; this may subsequently be overridden by the surrounding + application. (Note that max_memory_to_use is only important if + jpeg_mem_available chooses to consult it ... no one else will.) + jpeg_mem_term may assume that all requested memory has been freed and that + all opened backing-store objects have been closed. } + + +{ These routines take care of any system-dependent initialization and + cleanup required. } + + +{GLOBAL} +function jpeg_mem_init (cinfo : j_common_ptr) : long; +begin + next_file_num := 0; { initialize temp file name generator } + jpeg_mem_init := DEFAULT_MAX_MEM; { default for max_memory_to_use } +end; + +{GLOBAL} +procedure jpeg_mem_term (cinfo : j_common_ptr); +begin + { Microsoft C, at least in v6.00A, will not successfully reclaim freed + blocks of size > 32Kbytes unless we give it a kick in the rear, + like so: } + +{$ifdef NEED_FHEAPMIN} + _fheapmin(); +{$endif} +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jmemdosa_del.pas b/mseide-msegui/lib/common/fpccompatibility/jmemdosa_del.pas new file mode 100644 index 0000000..593d409 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jmemdosa_del.pas @@ -0,0 +1,365 @@ +Unit jmemdosa; + +{$G+} {enable 286/287 instructions } + +{ Original: jmemdosa.asm ; Copyright (C) 1992, Thomas G. Lane. + Based on code contributed by Ge' Weijers. } + +{ This file contains low-level interface routines to support the MS-DOS + backing store manager (jmemdos.c). Routines are provided to access disk + files through direct DOS calls, and to access XMS and EMS drivers. } + +interface + +uses + jmorecfg; + +type + XMSDRIVER = pointer; {far} { actually a pointer to code } +type + XMScontext = packed record { registers for calling XMS driver } + ax, dx, bx : ushort; + ds_si : pointer; {far} + end; +type + EMScontext = packed record { registers for calling EMS driver } + ax, dx, bx : ushort; + ds_si : pointer; {far} + end; +{ offset is a reserved word in BASM } + +function jdos_open (var handle : short {far}; const filename {: PChar}) : short; + +function jdos_close (handle : short) : short; + +function jdos_seek (handle : short; offs : long) : short; + +function jdos_read (handle : short; buffer : pointer; {FAR} + count : ushort) : short; +function jdos_write (handle : short; buffer : pointer; {FAR} + count : ushort) : short; + +procedure jxms_getdriver (var driver : XMSDRIVER); + +procedure jxms_calldriver (driver : XMSDRIVER; + var ctx : XMScontext); +function jems_available : short; + +procedure jems_calldriver (var ctx : EMScontext); + + +implementation + + +function jdos_open (var handle : short {far}; + const filename {: PChar}) : short; assembler; +{ Create and open a temporary file } +label + open_err; +asm + push si { save all registers for safety } + push di + push bx + push cx + push dx + push es + push ds + mov cx,0 { normal file attributes } + lds dx, filename { get filename pointer } + mov ah,3ch { create file } + int 21h + jc open_err { if failed, return error code } + lds bx, handle { get handle pointer } + mov word ptr [bx],ax { save the handle } + xor ax,ax { return zero for OK } +open_err: + pop ds { restore registers and exit } + pop es + pop dx + pop cx + pop bx + pop di + pop si +end; { jdos_open } + + +function jdos_close (handle : short) : short; assembler; +{ Close the file handle } +label + close_err; +asm + push si { save all registers for safety } + push di + push bx + push cx + push dx + push es + push ds + mov bx, handle { file handle } + mov ah,3eh { close file } + int 21h + jc close_err { if failed, return error code } + xor ax,ax { return zero for OK } +close_err: + pop ds { restore registers and exit } + pop es + pop dx + pop cx + pop bx + pop di + pop si +end; { jdos_close } + + + +function jdos_seek (handle : short; offs : long) : short; assembler; +{ Set file position } +label + seek_err; +asm + push si { save all registers for safety } + push di + push bx + push cx + push dx + push es + push ds + mov bx, handle { file handle } + mov dx, offs.word { LS offset } + mov cx, offs.word[2] { MS offset } + mov ax,4200h { absolute seek } + int 21h + jc seek_err { if failed, return error code } + xor ax,ax { return zero for OK } +seek_err: + pop ds { restore registers and exit } + pop es + pop dx + pop cx + pop bx + pop di + pop si +end; { jdos_seek } + + +function jdos_read (handle : short; buffer : pointer; {FAR} + count : ushort) : short; assembler; +{ Read from file } +label + read_ok, read_err; +asm + push si { save all registers for safety } + push di + push bx + push cx + push dx + push es + push ds + mov bx, handle { file handle } + lds dx, buffer { buffer address } + mov cx, count { number of bytes } + mov ah,3fh { read file } + int 21h + jc read_err { if failed, return error code } + cmp ax, count { make sure all bytes were read } + je read_ok + mov ax,1 { else return 1 for not OK } + jmp read_err +read_ok: + xor ax,ax { return zero for OK } +read_err: + pop ds { restore registers and exit } + pop es + pop dx + pop cx + pop bx + pop di + pop si +end; { jdos_read } + + + +function jdos_write (handle : short; buffer : pointer; {FAR} + count : ushort) : short; assembler; +{ Write to file } +label + write_ok, write_err; +asm + push si { save all registers for safety } + push di + push bx + push cx + push dx + push es + push ds + mov bx, handle { file handle } + lds dx, buffer { buffer address } + mov cx, count { number of bytes } + mov ah,40h { write file } + int 21h + jc write_err { if failed, return error code } + cmp ax, count { make sure all bytes written } + je write_ok + mov ax,1 { else return 1 for not OK } + jmp write_err +write_ok: + xor ax,ax { return zero for OK } +write_err: + pop ds { restore registers and exit } + pop es + pop dx + pop cx + pop bx + pop di + pop si +end; { jdos_write } + + + +procedure jxms_getdriver (var driver : XMSDRIVER); assembler; +{ Get the address of the XMS driver, or NIL if not available } +label + xmsavail, xmsavail_done; +asm + push si { save all registers for safety } + push di + push bx + push cx + push dx + push es + push ds + mov ax,4300h { call multiplex interrupt with } + int 2fh { a magic cookie, hex 4300 } + cmp al,80h { AL should contain hex 80 } + je xmsavail + xor dx,dx { no XMS driver available } + xor ax,ax { return a nil pointer } + jmp xmsavail_done +xmsavail: + mov ax,4310h { fetch driver address with } + int 2fh { another magic cookie } + mov dx,es { copy address to dx:ax } + mov ax,bx +xmsavail_done: + les bx,dword ptr [bp+6] { get pointer to return value } + mov word ptr es:[bx],ax + mov word ptr es:[bx+2],dx + pop ds { restore registers and exit } + pop es + pop dx + pop cx + pop bx + pop di + pop si +end; { jxms_getdriver } + +procedure jxms_calldriver (driver : XMSDRIVER; + var ctx : XMScontext); assembler; +{ The XMScontext structure contains values for the AX,DX,BX,SI,DS registers.} +{ These are loaded, the XMS call is performed, and the new values of the } +{ AX,DX,BX registers are written back to the context structure. } +asm + push si { save all registers for safety } + push di + push bx + push cx + push dx + push es + push ds + les bx, ctx { get XMScontext pointer } + mov ax,word ptr es:[bx] { load registers } + mov dx,word ptr es:[bx+2] + mov si,word ptr es:[bx+6] + mov ds,word ptr es:[bx+8] + mov bx,word ptr es:[bx+4] + call dword ptr driver { call the driver } + mov cx,bx { save returned BX for a sec } + les bx, ctx { get XMScontext pointer } + mov word ptr es:[bx],ax { put back ax,dx,bx } + mov word ptr es:[bx+2],dx + mov word ptr es:[bx+4],cx + pop ds { restore registers and exit } + pop es + pop dx + pop cx + pop bx + pop di + pop si +end; { jxms_calldriver } + + + +function jems_available : short; assembler; +{ Have we got an EMS driver? (this comes straight from the EMS 4.0 specs)} +label + no_ems, avail_done; +const + ASCII_device_name : packed array[0..7] of char = 'EMMXXXX0'; +asm + push si { save all registers for safety } + push di + push bx + push cx + push dx + push es + push ds + mov ax,3567h { get interrupt vector 67h } + int 21h + push cs + pop ds + mov di,000ah { check offs 10 in returned seg } + lea si, ASCII_device_name { against literal string } + mov cx,8 + cld + repe cmpsb + jne no_ems + mov ax,1 { match, it's there } + jmp avail_done +no_ems: xor ax,ax { it's not there } +avail_done: + pop ds { restore registers and exit } + pop es + pop dx + pop cx + pop bx + pop di + pop si +end; { jems_available } + + +procedure jems_calldriver (var ctx : EMScontext); assembler; +{ The EMScontext structure contains values for the AX,DX,BX,SI,DS registers. } +{ These are loaded, the EMS trap is performed, and the new values of the } +{ AX,DX,BX registers are written back to the context structure. } +asm + push si { save all registers for safety } + push di + push bx + push cx + push dx + push es + push ds + + les bx, ctx { get EMScontext pointer } + mov ax, es:[bx].EMScontext.&ax { load registers } + mov dx, es:[bx].EMScontext.&dx + mov si, es:[bx].EMScontext.&ds_si.word + mov ds, es:[bx].EMScontext.&ds_si.word[2] + mov bx, es:[bx].EMScontext.&bx + int 67h { call the EMS driver } + mov cx,bx { save returned BX for a sec } + les bx, ctx { get EMScontext pointer } + mov es:[bx].EMScontext.&ax, ax { put back ax,dx,bx } + mov es:[bx].EMScontext.&dx, dx + mov es:[bx].EMScontext.&bx, cx + + pop ds { restore registers and exit } + pop es + pop dx + pop cx + pop bx + pop di + pop si +end; { jems_calldriver } + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jmemmgr_del.pas b/mseide-msegui/lib/common/fpccompatibility/jmemmgr_del.pas new file mode 100644 index 0000000..78039a7 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jmemmgr_del.pas @@ -0,0 +1,1285 @@ +unit jmemmgr_del; + +{ This file contains the JPEG system-independent memory management + routines. This code is usable across a wide variety of machines; most + of the system dependencies have been isolated in a separate file. + The major functions provided here are: + * pool-based allocation and freeing of memory; + * policy decisions about how to divide available memory among the + virtual arrays; + * control logic for swapping virtual arrays between main memory and + backing storage. + The separate system-dependent file provides the actual backing-storage + access code, and it contains the policy decision about how much total + main memory to use. + This file is system-dependent in the sense that some of its functions + are unnecessary in some systems. For example, if there is enough virtual + memory so that backing storage will never be used, much of the virtual + array control logic could be removed. (Of course, if you have that much + memory then you shouldn't care about a little bit of unused code...) } + +{ Original : jmemmgr.c ; Copyright (C) 1991-1997, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jdeferr_del, + jerror_del, + jpeglib_del, + jutils_del, +{$IFDEF VER70} +{$ifndef NO_GETENV} + Dos, { DOS unit should declare getenv() } + { function GetEnv(name : string) : string; } +{$endif} + jmemdos; { import the system-dependent declarations } +{$ELSE} + jmemnobs_del; + {$DEFINE NO_GETENV} +{$ENDIF} + +{ Memory manager initialization. + When this is called, only the error manager pointer is valid in cinfo! } + +{GLOBAL} +procedure jinit_memory_mgr (cinfo : j_common_ptr); + +implementation + + +{ Some important notes: + The allocation routines provided here must never return NIL. + They should exit to error_exit if unsuccessful. + + It's not a good idea to try to merge the sarray and barray routines, + even though they are textually almost the same, because samples are + usually stored as bytes while coefficients are shorts or ints. Thus, + in machines where byte pointers have a different representation from + word pointers, the resulting machine code could not be the same. } + + +{ Many machines require storage alignment: longs must start on 4-byte + boundaries, doubles on 8-byte boundaries, etc. On such machines, malloc() + always returns pointers that are multiples of the worst-case alignment + requirement, and we had better do so too. + There isn't any really portable way to determine the worst-case alignment + requirement. This module assumes that the alignment requirement is + multiples of sizeof(ALIGN_TYPE). + By default, we define ALIGN_TYPE as double. This is necessary on some + workstations (where doubles really do need 8-byte alignment) and will work + fine on nearly everything. If your machine has lesser alignment needs, + you can save a few bytes by making ALIGN_TYPE smaller. + The only place I know of where this will NOT work is certain Macintosh + 680x0 compilers that define double as a 10-byte IEEE extended float. + Doing 10-byte alignment is counterproductive because longwords won't be + aligned well. Put "#define ALIGN_TYPE long" in jconfig.h if you have + such a compiler. } + +{$ifndef ALIGN_TYPE} { so can override from jconfig.h } +type + ALIGN_TYPE = double; +{$endif} + + +{ We allocate objects from "pools", where each pool is gotten with a single + request to jpeg_get_small() or jpeg_get_large(). There is no per-object + overhead within a pool, except for alignment padding. Each pool has a + header with a link to the next pool of the same class. + Small and large pool headers are identical except that the latter's + link pointer must be FAR on 80x86 machines. + Notice that the "real" header fields are union'ed with a dummy ALIGN_TYPE + field. This forces the compiler to make SIZEOF(small_pool_hdr) a multiple + of the alignment requirement of ALIGN_TYPE. } + +type + small_pool_ptr = ^small_pool_hdr; + small_pool_hdr = record + case byte of + 0:(hdr : record + next : small_pool_ptr; { next in list of pools } + bytes_used : size_t; { how many bytes already used within pool } + bytes_left : size_t; { bytes still available in this pool } + end); + 1:(dummy : ALIGN_TYPE); { included in union to ensure alignment } + end; {small_pool_hdr;} + +type + large_pool_ptr = ^large_pool_hdr; {FAR} + large_pool_hdr = record + case byte of + 0:(hdr : record + next : large_pool_ptr; { next in list of pools } + bytes_used : size_t; { how many bytes already used within pool } + bytes_left : size_t; { bytes still available in this pool } + end); + 1:(dummy : ALIGN_TYPE); { included in union to ensure alignment } + end; {large_pool_hdr;} + + +{ Here is the full definition of a memory manager object. } + +type + my_mem_ptr = ^my_memory_mgr; + my_memory_mgr = record + pub : jpeg_memory_mgr; { public fields } + + { Each pool identifier (lifetime class) names a linked list of pools. } + small_list : array[0..JPOOL_NUMPOOLS-1] of small_pool_ptr ; + large_list : array[0..JPOOL_NUMPOOLS-1] of large_pool_ptr ; + + { Since we only have one lifetime class of virtual arrays, only one + linked list is necessary (for each datatype). Note that the virtual + array control blocks being linked together are actually stored somewhere + in the small-pool list. } + + virt_sarray_list : jvirt_sarray_ptr; + virt_barray_list : jvirt_barray_ptr; + + { This counts total space obtained from jpeg_get_small/large } + total_space_allocated : long; + + { alloc_sarray and alloc_barray set this value for use by virtual + array routines. } + + last_rowsperchunk : JDIMENSION; { from most recent alloc_sarray/barray } + end; {my_memory_mgr;} + + {$ifndef AM_MEMORY_MANAGER} { only jmemmgr.c defines these } + +{ The control blocks for virtual arrays. + Note that these blocks are allocated in the "small" pool area. + System-dependent info for the associated backing store (if any) is hidden + inside the backing_store_info struct. } +type + jvirt_sarray_control = record + mem_buffer : JSAMPARRAY; { => the in-memory buffer } + rows_in_array : JDIMENSION; { total virtual array height } + samplesperrow : JDIMENSION; { width of array (and of memory buffer) } + maxaccess : JDIMENSION; { max rows accessed by access_virt_sarray } + rows_in_mem : JDIMENSION; { height of memory buffer } + rowsperchunk : JDIMENSION; { allocation chunk size in mem_buffer } + cur_start_row : JDIMENSION; { first logical row # in the buffer } + first_undef_row : JDIMENSION; { row # of first uninitialized row } + pre_zero : boolean; { pre-zero mode requested? } + dirty : boolean; { do current buffer contents need written? } + b_s_open : boolean; { is backing-store data valid? } + next : jvirt_sarray_ptr; { link to next virtual sarray control block } + b_s_info : backing_store_info; { System-dependent control info } + end; + + jvirt_barray_control = record + mem_buffer : JBLOCKARRAY; { => the in-memory buffer } + rows_in_array : JDIMENSION; { total virtual array height } + blocksperrow : JDIMENSION; { width of array (and of memory buffer) } + maxaccess : JDIMENSION; { max rows accessed by access_virt_barray } + rows_in_mem : JDIMENSION; { height of memory buffer } + rowsperchunk : JDIMENSION; { allocation chunk size in mem_buffer } + cur_start_row : JDIMENSION; { first logical row # in the buffer } + first_undef_row : JDIMENSION; { row # of first uninitialized row } + pre_zero : boolean; { pre-zero mode requested? } + dirty : boolean; { do current buffer contents need written? } + b_s_open : boolean; { is backing-store data valid? } + next : jvirt_barray_ptr; { link to next virtual barray control block } + b_s_info : backing_store_info; { System-dependent control info } + end; + {$endif} { AM_MEMORY_MANAGER} + +{$ifdef MEM_STATS} { optional extra stuff for statistics } + +{LOCAL} +procedure print_mem_stats (cinfo : j_common_ptr; pool_id : int); +var + mem : my_mem_ptr; + shdr_ptr : small_pool_ptr; + lhdr_ptr : large_pool_ptr; +begin + mem := my_mem_ptr (cinfo^.mem); + + { Since this is only a debugging stub, we can cheat a little by using + fprintf directly rather than going through the trace message code. + This is helpful because message parm array can't handle longs. } + + WriteLn(output, 'Freeing pool ', pool_id,', total space := ', + mem^.total_space_allocated); + + lhdr_ptr := mem^.large_list[pool_id]; + while (lhdr_ptr <> NIL) do + begin + WriteLn(output, ' Large chunk used ', + long (lhdr_ptr^.hdr.bytes_used)); + lhdr_ptr := lhdr_ptr^.hdr.next; + end; + + shdr_ptr := mem^.small_list[pool_id]; + + while (shdr_ptr <> NIL) do + begin + WriteLn(output, ' Small chunk used ', + long (shdr_ptr^.hdr.bytes_used), ' free ', + long (shdr_ptr^.hdr.bytes_left) ); + shdr_ptr := shdr_ptr^.hdr.next; + end; +end; + +{$endif} { MEM_STATS } + + +{LOCAL} +procedure out_of_memory (cinfo : j_common_ptr; which : int); +{ Report an out-of-memory error and stop execution } +{ If we compiled MEM_STATS support, report alloc requests before dying } +begin +{$ifdef MEM_STATS} + cinfo^.err^.trace_level := 2; { force self_destruct to report stats } +{$endif} + ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, which); +end; + + +{ Allocation of "small" objects. + + For these, we use pooled storage. When a new pool must be created, + we try to get enough space for the current request plus a "slop" factor, + where the slop will be the amount of leftover space in the new pool. + The speed vs. space tradeoff is largely determined by the slop values. + A different slop value is provided for each pool class (lifetime), + and we also distinguish the first pool of a class from later ones. + NOTE: the values given work fairly well on both 16- and 32-bit-int + machines, but may be too small if longs are 64 bits or more. } + +const + first_pool_slop : array[0..JPOOL_NUMPOOLS-1] of size_t = + (1600, { first PERMANENT pool } + 16000); { first IMAGE pool } + +const + extra_pool_slop : array[0..JPOOL_NUMPOOLS-1] of size_t = + (0, { additional PERMANENT pools } + 5000); { additional IMAGE pools } + +const + MIN_SLOP = 50; { greater than 0 to avoid futile looping } + + +{METHODDEF} +function alloc_small (cinfo : j_common_ptr; + pool_id : int; + sizeofobject : size_t) : pointer; +type + byteptr = ^byte; +{ Allocate a "small" object } +var + mem : my_mem_ptr; + hdr_ptr, prev_hdr_ptr : small_pool_ptr; + data_ptr : byteptr; + odd_bytes, min_request, slop : size_t; +begin + mem := my_mem_ptr (cinfo^.mem); + + { Check for unsatisfiable request (do now to ensure no overflow below) } + if (sizeofobject > size_t(MAX_ALLOC_CHUNK-SIZEOF(small_pool_hdr))) then + out_of_memory(cinfo, 1); { request exceeds malloc's ability } + + { Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) } + odd_bytes := sizeofobject mod SIZEOF(ALIGN_TYPE); + if (odd_bytes > 0) then + Inc(sizeofobject, SIZEOF(ALIGN_TYPE) - odd_bytes); + + { See if space is available in any existing pool } + if (pool_id < 0) or (pool_id >= JPOOL_NUMPOOLS) then + ERREXIT1(j_common_ptr(cinfo), JERR_BAD_POOL_ID, pool_id); { safety check } + prev_hdr_ptr := NIL; + hdr_ptr := mem^.small_list[pool_id]; + while (hdr_ptr <> NIL) do + begin + if (hdr_ptr^.hdr.bytes_left >= sizeofobject) then + break; { found pool with enough space } + prev_hdr_ptr := hdr_ptr; + hdr_ptr := hdr_ptr^.hdr.next; + end; + + { Time to make a new pool? } + if (hdr_ptr = NIL) then + begin + { min_request is what we need now, slop is what will be leftover } + min_request := sizeofobject + SIZEOF(small_pool_hdr); + if (prev_hdr_ptr = NIL) then { first pool in class? } + slop := first_pool_slop[pool_id] + else + slop := extra_pool_slop[pool_id]; + { Don't ask for more than MAX_ALLOC_CHUNK } + if (slop > size_t (MAX_ALLOC_CHUNK-min_request)) then + slop := size_t (MAX_ALLOC_CHUNK-min_request); + { Try to get space, if fail reduce slop and try again } + while TRUE do + begin + hdr_ptr := small_pool_ptr(jpeg_get_small(cinfo, min_request + slop)); + if (hdr_ptr <> NIL) then + break; + slop := slop div 2; + if (slop < MIN_SLOP) then { give up when it gets real small } + out_of_memory(cinfo, 2); { jpeg_get_small failed } + end; + Inc(mem^.total_space_allocated, min_request + slop); + { Success, initialize the new pool header and add to end of list } + hdr_ptr^.hdr.next := NIL; + hdr_ptr^.hdr.bytes_used := 0; + hdr_ptr^.hdr.bytes_left := sizeofobject + slop; + if (prev_hdr_ptr = NIL) then { first pool in class? } + mem^.small_list[pool_id] := hdr_ptr + else + prev_hdr_ptr^.hdr.next := hdr_ptr; + end; + + { OK, allocate the object from the current pool } + data_ptr := byteptr (hdr_ptr); + Inc(small_pool_ptr(data_ptr)); { point to first data byte in pool } + Inc(data_ptr, hdr_ptr^.hdr.bytes_used); { point to place for object } + Inc(hdr_ptr^.hdr.bytes_used, sizeofobject); + Dec(hdr_ptr^.hdr.bytes_left, sizeofobject); + + alloc_small := pointer(data_ptr); +end; + + +{ Allocation of "large" objects. + + The external semantics of these are the same as "small" objects, + except that FAR pointers are used on 80x86. However the pool + management heuristics are quite different. We assume that each + request is large enough that it may as well be passed directly to + jpeg_get_large; the pool management just links everything together + so that we can free it all on demand. + Note: the major use of "large" objects is in JSAMPARRAY and JBLOCKARRAY + structures. The routines that create these structures (see below) + deliberately bunch rows together to ensure a large request size. } + +{METHODDEF} +function alloc_large (cinfo : j_common_ptr; + pool_id : int; + sizeofobject : size_t) : pointer; +{ Allocate a "large" object } +var + mem : my_mem_ptr; + hdr_ptr : large_pool_ptr; + odd_bytes : size_t; +var + dest_ptr : large_pool_ptr; +begin + mem := my_mem_ptr (cinfo^.mem); + + { Check for unsatisfiable request (do now to ensure no overflow below) } + if (sizeofobject > size_t (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr))) then + out_of_memory(cinfo, 3); { request exceeds malloc's ability } + + { Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) } + odd_bytes := sizeofobject mod SIZEOF(ALIGN_TYPE); + if (odd_bytes > 0) then + Inc(sizeofobject, SIZEOF(ALIGN_TYPE) - odd_bytes); + + { Always make a new pool } + if (pool_id < 0) or (pool_id >= JPOOL_NUMPOOLS) then + ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); { safety check } + + hdr_ptr := large_pool_ptr (jpeg_get_large(cinfo, sizeofobject + + SIZEOF(large_pool_hdr))); + if (hdr_ptr = NIL) then + out_of_memory(cinfo, 4); { jpeg_get_large failed } + Inc(mem^.total_space_allocated, sizeofobject + SIZEOF(large_pool_hdr)); + + { Success, initialize the new pool header and add to list } + hdr_ptr^.hdr.next := mem^.large_list[pool_id]; + { We maintain space counts in each pool header for statistical purposes, + even though they are not needed for allocation. } + + hdr_ptr^.hdr.bytes_used := sizeofobject; + hdr_ptr^.hdr.bytes_left := 0; + mem^.large_list[pool_id] := hdr_ptr; + + {alloc_large := pointerFAR (hdr_ptr + 1); - point to first data byte in pool } + dest_ptr := hdr_ptr; + Inc(large_pool_ptr(dest_ptr)); + alloc_large := dest_ptr; +end; + + +{ Creation of 2-D sample arrays. + The pointers are in near heap, the samples themselves in FAR heap. + + To minimize allocation overhead and to allow I/O of large contiguous + blocks, we allocate the sample rows in groups of as many rows as possible + without exceeding MAX_ALLOC_CHUNK total bytes per allocation request. + NB: the virtual array control routines, later in this file, know about + this chunking of rows. The rowsperchunk value is left in the mem manager + object so that it can be saved away if this sarray is the workspace for + a virtual array. } + +{METHODDEF} +function alloc_sarray (cinfo : j_common_ptr; + pool_id : int; + samplesperrow : JDIMENSION; + numrows : JDIMENSION) : JSAMPARRAY; +{ Allocate a 2-D sample array } +var + mem : my_mem_ptr; + the_result : JSAMPARRAY; + workspace : JSAMPROW; + rowsperchunk, currow, i : JDIMENSION; + ltemp : long; +begin + mem := my_mem_ptr(cinfo^.mem); + + { Calculate max # of rows allowed in one allocation chunk } + ltemp := (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) div + (long(samplesperrow) * SIZEOF(JSAMPLE)); + if (ltemp <= 0) then + ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); + if (ltemp < long(numrows)) then + rowsperchunk := JDIMENSION (ltemp) + else + rowsperchunk := numrows; + mem^.last_rowsperchunk := rowsperchunk; + + { Get space for row pointers (small object) } + the_result := JSAMPARRAY (alloc_small(cinfo, pool_id, + size_t (numrows * SIZEOF(JSAMPROW)))); + + { Get the rows themselves (large objects) } + currow := 0; + while (currow < numrows) do + begin + {rowsperchunk := MIN(rowsperchunk, numrows - currow);} + if rowsperchunk > numrows - currow then + rowsperchunk := numrows - currow; + + workspace := JSAMPROW (alloc_large(cinfo, pool_id, + size_t (size_t(rowsperchunk) * size_t(samplesperrow) + * SIZEOF(JSAMPLE))) ); + for i := pred(rowsperchunk) downto 0 do + begin + the_result^[currow] := workspace; + Inc(currow); + Inc(JSAMPLE_PTR(workspace), samplesperrow); + end; + end; + + alloc_sarray := the_result; +end; + + +{ Creation of 2-D coefficient-block arrays. + This is essentially the same as the code for sample arrays, above. } + +{METHODDEF} +function alloc_barray (cinfo : j_common_ptr; + pool_id : int; + blocksperrow : JDIMENSION; + numrows : JDIMENSION) : JBLOCKARRAY; +{ Allocate a 2-D coefficient-block array } +var + mem : my_mem_ptr; + the_result : JBLOCKARRAY; + workspace : JBLOCKROW; + rowsperchunk, currow, i : JDIMENSION; + ltemp : long; +begin + mem := my_mem_ptr(cinfo^.mem); + + { Calculate max # of rows allowed in one allocation chunk } + ltemp := (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) div + (long(blocksperrow) * SIZEOF(JBLOCK)); + if (ltemp <= 0) then + ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); + if (ltemp < long(numrows)) then + rowsperchunk := JDIMENSION (ltemp) + else + rowsperchunk := numrows; + mem^.last_rowsperchunk := rowsperchunk; + + { Get space for row pointers (small object) } + the_result := JBLOCKARRAY (alloc_small(cinfo, pool_id, + size_t (numrows * SIZEOF(JBLOCKROW))) ); + + { Get the rows themselves (large objects) } + currow := 0; + while (currow < numrows) do + begin + {rowsperchunk := MIN(rowsperchunk, numrows - currow);} + if rowsperchunk > numrows - currow then + rowsperchunk := numrows - currow; + + workspace := JBLOCKROW (alloc_large(cinfo, pool_id, + size_t (size_t(rowsperchunk) * size_t(blocksperrow) + * SIZEOF(JBLOCK))) ); + for i := rowsperchunk downto 1 do + begin + the_result^[currow] := workspace; + Inc(currow); + Inc(JBLOCK_PTR(workspace), blocksperrow); + end; + end; + + alloc_barray := the_result; +end; + + +{ About virtual array management: + + The above "normal" array routines are only used to allocate strip buffers + (as wide as the image, but just a few rows high). Full-image-sized buffers + are handled as "virtual" arrays. The array is still accessed a strip at a + time, but the memory manager must save the whole array for repeated + accesses. The intended implementation is that there is a strip buffer in + memory (as high as is possible given the desired memory limit), plus a + backing file that holds the rest of the array. + + The request_virt_array routines are told the total size of the image and + the maximum number of rows that will be accessed at once. The in-memory + buffer must be at least as large as the maxaccess value. + + The request routines create control blocks but not the in-memory buffers. + That is postponed until realize_virt_arrays is called. At that time the + total amount of space needed is known (approximately, anyway), so free + memory can be divided up fairly. + + The access_virt_array routines are responsible for making a specific strip + area accessible (after reading or writing the backing file, if necessary). + Note that the access routines are told whether the caller intends to modify + the accessed strip; during a read-only pass this saves having to rewrite + data to disk. The access routines are also responsible for pre-zeroing + any newly accessed rows, if pre-zeroing was requested. + + In current usage, the access requests are usually for nonoverlapping + strips; that is, successive access start_row numbers differ by exactly + num_rows := maxaccess. This means we can get good performance with simple + buffer dump/reload logic, by making the in-memory buffer be a multiple + of the access height; then there will never be accesses across bufferload + boundaries. The code will still work with overlapping access requests, + but it doesn't handle bufferload overlaps very efficiently. } + + +{METHODDEF} +function request_virt_sarray (cinfo : j_common_ptr; + pool_id : int; + pre_zero : boolean; + samplesperrow : JDIMENSION; + numrows : JDIMENSION; + maxaccess : JDIMENSION) : jvirt_sarray_ptr; +{ Request a virtual 2-D sample array } +var + mem : my_mem_ptr; + the_result : jvirt_sarray_ptr; +begin + mem := my_mem_ptr (cinfo^.mem); + + { Only IMAGE-lifetime virtual arrays are currently supported } + if (pool_id <> JPOOL_IMAGE) then + ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); { safety check } + + { get control block } + the_result := jvirt_sarray_ptr (alloc_small(cinfo, pool_id, + SIZEOF(jvirt_sarray_control)) ); + + the_result^.mem_buffer := NIL; { marks array not yet realized } + the_result^.rows_in_array := numrows; + the_result^.samplesperrow := samplesperrow; + the_result^.maxaccess := maxaccess; + the_result^.pre_zero := pre_zero; + the_result^.b_s_open := FALSE; { no associated backing-store object } + the_result^.next := mem^.virt_sarray_list; { add to list of virtual arrays } + mem^.virt_sarray_list := the_result; + + request_virt_sarray := the_result; +end; + + +{METHODDEF} +function request_virt_barray (cinfo : j_common_ptr; + pool_id : int; + pre_zero : boolean; + blocksperrow : JDIMENSION; + numrows : JDIMENSION; + maxaccess : JDIMENSION) : jvirt_barray_ptr; +{ Request a virtual 2-D coefficient-block array } +var + mem : my_mem_ptr; + the_result : jvirt_barray_ptr; +begin + mem := my_mem_ptr(cinfo^.mem); + + { Only IMAGE-lifetime virtual arrays are currently supported } + if (pool_id <> JPOOL_IMAGE) then + ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); { safety check } + + { get control block } + the_result := jvirt_barray_ptr(alloc_small(cinfo, pool_id, + SIZEOF(jvirt_barray_control)) ); + + the_result^.mem_buffer := NIL; { marks array not yet realized } + the_result^.rows_in_array := numrows; + the_result^.blocksperrow := blocksperrow; + the_result^.maxaccess := maxaccess; + the_result^.pre_zero := pre_zero; + the_result^.b_s_open := FALSE; { no associated backing-store object } + the_result^.next := mem^.virt_barray_list; { add to list of virtual arrays } + mem^.virt_barray_list := the_result; + + request_virt_barray := the_result; +end; + + +{METHODDEF} +procedure realize_virt_arrays (cinfo : j_common_ptr); +{ Allocate the in-memory buffers for any unrealized virtual arrays } +var + mem : my_mem_ptr; + space_per_minheight, maximum_space, avail_mem : long; + minheights, max_minheights : long; + sptr : jvirt_sarray_ptr; + bptr : jvirt_barray_ptr; +begin + mem := my_mem_ptr (cinfo^.mem); + { Compute the minimum space needed (maxaccess rows in each buffer) + and the maximum space needed (full image height in each buffer). + These may be of use to the system-dependent jpeg_mem_available routine. } + + space_per_minheight := 0; + maximum_space := 0; + sptr := mem^.virt_sarray_list; + while (sptr <> NIL) do + begin + if (sptr^.mem_buffer = NIL) then + begin { if not realized yet } + Inc(space_per_minheight, long(sptr^.maxaccess) * + long(sptr^.samplesperrow) * SIZEOF(JSAMPLE)); + Inc(maximum_space, long(sptr^.rows_in_array) * + long(sptr^.samplesperrow) * SIZEOF(JSAMPLE)); + end; + sptr := sptr^.next; + end; + bptr := mem^.virt_barray_list; + while (bptr <> NIL) do + begin + if (bptr^.mem_buffer = NIL) then + begin { if not realized yet } + Inc(space_per_minheight, long(bptr^.maxaccess) * + long(bptr^.blocksperrow) * SIZEOF(JBLOCK)); + Inc(maximum_space, long(bptr^.rows_in_array) * + long(bptr^.blocksperrow) * SIZEOF(JBLOCK)); + end; + bptr := bptr^.next; + end; + + if (space_per_minheight <= 0) then + exit; { no unrealized arrays, no work } + + { Determine amount of memory to actually use; this is system-dependent. } + avail_mem := jpeg_mem_available(cinfo, space_per_minheight, maximum_space, + mem^.total_space_allocated); + + { If the maximum space needed is available, make all the buffers full + height; otherwise parcel it out with the same number of minheights + in each buffer. } + + if (avail_mem >= maximum_space) then + max_minheights := long(1000000000) + else + begin + max_minheights := avail_mem div space_per_minheight; + { If there doesn't seem to be enough space, try to get the minimum + anyway. This allows a "stub" implementation of jpeg_mem_available(). } + if (max_minheights <= 0) then + max_minheights := 1; + end; + + { Allocate the in-memory buffers and initialize backing store as needed. } + + sptr := mem^.virt_sarray_list; + while (sptr <> NIL) do + begin + if (sptr^.mem_buffer = NIL) then + begin { if not realized yet } + minheights := (long(sptr^.rows_in_array) - long(1)) div sptr^.maxaccess + long(1); + if (minheights <= max_minheights) then + begin + { This buffer fits in memory } + sptr^.rows_in_mem := sptr^.rows_in_array; + end + else + begin + { It doesn't fit in memory, create backing store. } + sptr^.rows_in_mem := JDIMENSION (max_minheights * sptr^.maxaccess); + jpeg_open_backing_store(cinfo, + @sptr^.b_s_info, + long(sptr^.rows_in_array) * + long(sptr^.samplesperrow) * + long(SIZEOF(JSAMPLE))); + sptr^.b_s_open := TRUE; + end; + sptr^.mem_buffer := alloc_sarray(cinfo, JPOOL_IMAGE, + sptr^.samplesperrow, sptr^.rows_in_mem); + sptr^.rowsperchunk := mem^.last_rowsperchunk; + sptr^.cur_start_row := 0; + sptr^.first_undef_row := 0; + sptr^.dirty := FALSE; + end; + sptr := sptr^.next; + end; + + bptr := mem^.virt_barray_list; + while (bptr <> NIL) do + begin + if (bptr^.mem_buffer = NIL) then + begin { if not realized yet } + minheights := (long(bptr^.rows_in_array) - long(1)) div bptr^.maxaccess + long(1); + if (minheights <= max_minheights) then + begin + { This buffer fits in memory } + bptr^.rows_in_mem := bptr^.rows_in_array; + end + else + begin + { It doesn't fit in memory, create backing store. } + bptr^.rows_in_mem := JDIMENSION (max_minheights * bptr^.maxaccess); + jpeg_open_backing_store(cinfo, + @bptr^.b_s_info, + long(bptr^.rows_in_array) * + long(bptr^.blocksperrow) * + long(SIZEOF(JBLOCK))); + bptr^.b_s_open := TRUE; + end; + bptr^.mem_buffer := alloc_barray(cinfo, JPOOL_IMAGE, + bptr^.blocksperrow, bptr^.rows_in_mem); + bptr^.rowsperchunk := mem^.last_rowsperchunk; + bptr^.cur_start_row := 0; + bptr^.first_undef_row := 0; + bptr^.dirty := FALSE; + end; + bptr := bptr^.next; + end; +end; + + +{LOCAL} +procedure do_sarray_io (cinfo : j_common_ptr; + ptr : jvirt_sarray_ptr; + writing : boolean); +{ Do backing store read or write of a virtual sample array } +var + bytesperrow, file_offset, byte_count, rows, thisrow, i : long; +begin + + bytesperrow := long(ptr^.samplesperrow * SIZEOF(JSAMPLE)); + file_offset := ptr^.cur_start_row * bytesperrow; + { Loop to read or write each allocation chunk in mem_buffer } + i := 0; + while i < long(ptr^.rows_in_mem) do + begin + + { One chunk, but check for short chunk at end of buffer } + {rows := MIN(long(ptr^.rowsperchunk), long(ptr^.rows_in_mem - i));} + rows := long(ptr^.rowsperchunk); + if rows > long(ptr^.rows_in_mem - i) then + rows := long(ptr^.rows_in_mem - i); + { Transfer no more than is currently defined } + thisrow := long (ptr^.cur_start_row) + i; + {rows := MIN(rows, long(ptr^.first_undef_row) - thisrow);} + if (rows > long(ptr^.first_undef_row) - thisrow) then + rows := long(ptr^.first_undef_row) - thisrow; + { Transfer no more than fits in file } + {rows := MIN(rows, long(ptr^.rows_in_array) - thisrow);} + if (rows > long(ptr^.rows_in_array) - thisrow) then + rows := long(ptr^.rows_in_array) - thisrow; + + if (rows <= 0) then { this chunk might be past end of file! } + break; + byte_count := rows * bytesperrow; + if (writing) then + ptr^.b_s_info.write_backing_store (cinfo, + @ptr^.b_s_info, + pointer {FAR} (ptr^.mem_buffer^[i]), + file_offset, byte_count) + else + ptr^.b_s_info.read_backing_store (cinfo, + @ptr^.b_s_info, + pointer {FAR} (ptr^.mem_buffer^[i]), + file_offset, byte_count); + Inc(file_offset, byte_count); + Inc(i, ptr^.rowsperchunk); + end; +end; + + +{LOCAL} +procedure do_barray_io (cinfo : j_common_ptr; + ptr : jvirt_barray_ptr; + writing : boolean); +{ Do backing store read or write of a virtual coefficient-block array } +var + bytesperrow, file_offset, byte_count, rows, thisrow, i : long; +begin + bytesperrow := long (ptr^.blocksperrow) * SIZEOF(JBLOCK); + file_offset := ptr^.cur_start_row * bytesperrow; + { Loop to read or write each allocation chunk in mem_buffer } + i := 0; + while (i < long(ptr^.rows_in_mem)) do + begin + { One chunk, but check for short chunk at end of buffer } + {rows := MIN(long(ptr^.rowsperchunk), long(ptr^.rows_in_mem - i));} + rows := long(ptr^.rowsperchunk); + if rows >long(ptr^.rows_in_mem - i) then + rows := long(ptr^.rows_in_mem - i); + { Transfer no more than is currently defined } + thisrow := long (ptr^.cur_start_row) + i; + {rows := MIN(rows, long(ptr^.first_undef_row - thisrow));} + if rows > long(ptr^.first_undef_row - thisrow) then + rows := long(ptr^.first_undef_row - thisrow); + { Transfer no more than fits in file } + {rows := MIN(rows, long (ptr^.rows_in_array - thisrow));} + if (rows > long (ptr^.rows_in_array - thisrow)) then + rows := long (ptr^.rows_in_array - thisrow); + + if (rows <= 0) then { this chunk might be past end of file! } + break; + byte_count := rows * bytesperrow; + if (writing) then + ptr^.b_s_info.write_backing_store (cinfo, + @ptr^.b_s_info, + {FAR} pointer(ptr^.mem_buffer^[i]), + file_offset, byte_count) + else + ptr^.b_s_info.read_backing_store (cinfo, + @ptr^.b_s_info, + {FAR} pointer(ptr^.mem_buffer^[i]), + file_offset, byte_count); + Inc(file_offset, byte_count); + Inc(i, ptr^.rowsperchunk); + end; +end; + + +{METHODDEF} +function access_virt_sarray (cinfo : j_common_ptr; + ptr : jvirt_sarray_ptr; + start_row : JDIMENSION; + num_rows : JDIMENSION; + writable : boolean ) : JSAMPARRAY; +{ Access the part of a virtual sample array starting at start_row } +{ and extending for num_rows rows. writable is true if } +{ caller intends to modify the accessed area. } +var + end_row : JDIMENSION; + undef_row : JDIMENSION; +var + bytesperrow : size_t; +var + ltemp : long; +begin + end_row := start_row + num_rows; + { debugging check } + if (end_row > ptr^.rows_in_array) or (num_rows > ptr^.maxaccess) or + (ptr^.mem_buffer = NIL) then + ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + + { Make the desired part of the virtual array accessible } + if (start_row < ptr^.cur_start_row) or + (end_row > ptr^.cur_start_row+ptr^.rows_in_mem) then + begin + if (not ptr^.b_s_open) then + ERREXIT(cinfo, JERR_VIRTUAL_BUG); + { Flush old buffer contents if necessary } + if (ptr^.dirty) then + begin + do_sarray_io(cinfo, ptr, TRUE); + ptr^.dirty := FALSE; + end; + { Decide what part of virtual array to access. + Algorithm: if target address > current window, assume forward scan, + load starting at target address. If target address < current window, + assume backward scan, load so that target area is top of window. + Note that when switching from forward write to forward read, will have + start_row := 0, so the limiting case applies and we load from 0 anyway. } + if (start_row > ptr^.cur_start_row) then + begin + ptr^.cur_start_row := start_row; + end + else + begin + { use long arithmetic here to avoid overflow & unsigned problems } + + + ltemp := long(end_row) - long(ptr^.rows_in_mem); + if (ltemp < 0) then + ltemp := 0; { don't fall off front end of file } + ptr^.cur_start_row := JDIMENSION(ltemp); + end; + { Read in the selected part of the array. + During the initial write pass, we will do no actual read + because the selected part is all undefined. } + + do_sarray_io(cinfo, ptr, FALSE); + end; + { Ensure the accessed part of the array is defined; prezero if needed. + To improve locality of access, we only prezero the part of the array + that the caller is about to access, not the entire in-memory array. } + if (ptr^.first_undef_row < end_row) then + begin + if (ptr^.first_undef_row < start_row) then + begin + if (writable) then { writer skipped over a section of array } + ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + undef_row := start_row; { but reader is allowed to read ahead } + end + else + begin + undef_row := ptr^.first_undef_row; + end; + if (writable) then + ptr^.first_undef_row := end_row; + if (ptr^.pre_zero) then + begin + bytesperrow := size_t(ptr^.samplesperrow) * SIZEOF(JSAMPLE); + Dec(undef_row, ptr^.cur_start_row); { make indexes relative to buffer } + Dec(end_row, ptr^.cur_start_row); + while (undef_row < end_row) do + begin + jzero_far({FAR} pointer(ptr^.mem_buffer^[undef_row]), bytesperrow); + Inc(undef_row); + end; + end + else + begin + if (not writable) then { reader looking at undefined data } + ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + end; + end; + { Flag the buffer dirty if caller will write in it } + if (writable) then + ptr^.dirty := TRUE; + { Return address of proper part of the buffer } + access_virt_sarray := JSAMPARRAY(@ ptr^.mem_buffer^[start_row - ptr^.cur_start_row]); +end; + + +{METHODDEF} +function access_virt_barray (cinfo : j_common_ptr; + ptr : jvirt_barray_ptr; + start_row : JDIMENSION; + num_rows : JDIMENSION; + writable : boolean) : JBLOCKARRAY; +{ Access the part of a virtual block array starting at start_row } +{ and extending for num_rows rows. writable is true if } +{ caller intends to modify the accessed area. } +var + end_row : JDIMENSION; + undef_row : JDIMENSION; + ltemp : long; +var + bytesperrow : size_t; +begin + end_row := start_row + num_rows; + + { debugging check } + if (end_row > ptr^.rows_in_array) or (num_rows > ptr^.maxaccess) or + (ptr^.mem_buffer = NIL) then + ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + + { Make the desired part of the virtual array accessible } + if (start_row < ptr^.cur_start_row) or + (end_row > ptr^.cur_start_row+ptr^.rows_in_mem) then + begin + if (not ptr^.b_s_open) then + ERREXIT(cinfo, JERR_VIRTUAL_BUG); + { Flush old buffer contents if necessary } + if (ptr^.dirty) then + begin + do_barray_io(cinfo, ptr, TRUE); + ptr^.dirty := FALSE; + end; + { Decide what part of virtual array to access. + Algorithm: if target address > current window, assume forward scan, + load starting at target address. If target address < current window, + assume backward scan, load so that target area is top of window. + Note that when switching from forward write to forward read, will have + start_row := 0, so the limiting case applies and we load from 0 anyway. } + + if (start_row > ptr^.cur_start_row) then + begin + ptr^.cur_start_row := start_row; + end + else + begin + { use long arithmetic here to avoid overflow & unsigned problems } + + ltemp := long(end_row) - long(ptr^.rows_in_mem); + if (ltemp < 0) then + ltemp := 0; { don't fall off front end of file } + ptr^.cur_start_row := JDIMENSION (ltemp); + end; + { Read in the selected part of the array. + During the initial write pass, we will do no actual read + because the selected part is all undefined. } + + do_barray_io(cinfo, ptr, FALSE); + end; + { Ensure the accessed part of the array is defined; prezero if needed. + To improve locality of access, we only prezero the part of the array + that the caller is about to access, not the entire in-memory array. } + + if (ptr^.first_undef_row < end_row) then + begin + if (ptr^.first_undef_row < start_row) then + begin + if (writable) then { writer skipped over a section of array } + ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + undef_row := start_row; { but reader is allowed to read ahead } + end + else + begin + undef_row := ptr^.first_undef_row; + end; + if (writable) then + ptr^.first_undef_row := end_row; + if (ptr^.pre_zero) then + begin + bytesperrow := size_t (ptr^.blocksperrow) * SIZEOF(JBLOCK); + Dec(undef_row, ptr^.cur_start_row); { make indexes relative to buffer } + Dec(end_row, ptr^.cur_start_row); + while (undef_row < end_row) do + begin + jzero_far({FAR}pointer(ptr^.mem_buffer^[undef_row]), bytesperrow); + Inc(undef_row); + end; + end + else + begin + if (not writable) then { reader looking at undefined data } + ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + end; + end; + { Flag the buffer dirty if caller will write in it } + if (writable) then + ptr^.dirty := TRUE; + { Return address of proper part of the buffer } + access_virt_barray := JBLOCKARRAY(@ ptr^.mem_buffer^[start_row - ptr^.cur_start_row]); +end; + + +{ Release all objects belonging to a specified pool. } + +{METHODDEF} +procedure free_pool (cinfo : j_common_ptr; pool_id : int); +var + mem : my_mem_ptr; + shdr_ptr : small_pool_ptr; + lhdr_ptr : large_pool_ptr; + space_freed : size_t; +var + sptr : jvirt_sarray_ptr; + bptr : jvirt_barray_ptr; +var + next_lhdr_ptr : large_pool_ptr; + next_shdr_ptr : small_pool_ptr; +begin + mem := my_mem_ptr(cinfo^.mem); + + if (pool_id < 0) or (pool_id >= JPOOL_NUMPOOLS) then + ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); { safety check } + +{$ifdef MEM_STATS} + if (cinfo^.err^.trace_level > 1) then + print_mem_stats(cinfo, pool_id); { print pool's memory usage statistics } +{$endif} + + { If freeing IMAGE pool, close any virtual arrays first } + if (pool_id = JPOOL_IMAGE) then + begin + sptr := mem^.virt_sarray_list; + while (sptr <> NIL) do + begin + if (sptr^.b_s_open) then + begin { there may be no backing store } + sptr^.b_s_open := FALSE; { prevent recursive close if error } + sptr^.b_s_info.close_backing_store (cinfo, @sptr^.b_s_info); + end; + sptr := sptr^.next; + end; + mem^.virt_sarray_list := NIL; + bptr := mem^.virt_barray_list; + while (bptr <> NIL) do + begin + if (bptr^.b_s_open) then + begin { there may be no backing store } + bptr^.b_s_open := FALSE; { prevent recursive close if error } + bptr^.b_s_info.close_backing_store (cinfo, @bptr^.b_s_info); + end; + bptr := bptr^.next; + end; + mem^.virt_barray_list := NIL; + end; + + { Release large objects } + lhdr_ptr := mem^.large_list[pool_id]; + mem^.large_list[pool_id] := NIL; + + while (lhdr_ptr <> NIL) do + begin + next_lhdr_ptr := lhdr_ptr^.hdr.next; + space_freed := lhdr_ptr^.hdr.bytes_used + + lhdr_ptr^.hdr.bytes_left + + SIZEOF(large_pool_hdr); + jpeg_free_large(cinfo, {FAR} pointer(lhdr_ptr), space_freed); + Dec(mem^.total_space_allocated, space_freed); + lhdr_ptr := next_lhdr_ptr; + end; + + { Release small objects } + shdr_ptr := mem^.small_list[pool_id]; + mem^.small_list[pool_id] := NIL; + + while (shdr_ptr <> NIL) do + begin + next_shdr_ptr := shdr_ptr^.hdr.next; + space_freed := shdr_ptr^.hdr.bytes_used + + shdr_ptr^.hdr.bytes_left + + SIZEOF(small_pool_hdr); + jpeg_free_small(cinfo, pointer(shdr_ptr), space_freed); + Dec(mem^.total_space_allocated, space_freed); + shdr_ptr := next_shdr_ptr; + end; +end; + + +{ Close up shop entirely. + Note that this cannot be called unless cinfo^.mem is non-NIL. } + +{METHODDEF} +procedure self_destruct (cinfo : j_common_ptr); +var + pool : int; +begin + { Close all backing store, release all memory. + Releasing pools in reverse order might help avoid fragmentation + with some (brain-damaged) malloc libraries. } + + for pool := JPOOL_NUMPOOLS-1 downto JPOOL_PERMANENT do + begin + free_pool(cinfo, pool); + end; + + { Release the memory manager control block too. } + jpeg_free_small(cinfo, pointer(cinfo^.mem), SIZEOF(my_memory_mgr)); + cinfo^.mem := NIL; { ensures I will be called only once } + + jpeg_mem_term(cinfo); { system-dependent cleanup } +end; + + +{ Memory manager initialization. + When this is called, only the error manager pointer is valid in cinfo! } + +{GLOBAL} +procedure jinit_memory_mgr (cinfo : j_common_ptr); +var + mem : my_mem_ptr; + max_to_use : long; + pool : int; + test_mac : size_t; +{$ifndef NO_GETENV} +var + memenv : string; + code : integer; +{$endif} +begin + cinfo^.mem := NIL; { for safety if init fails } + + { Check for configuration errors. + SIZEOF(ALIGN_TYPE) should be a power of 2; otherwise, it probably + doesn't reflect any real hardware alignment requirement. + The test is a little tricky: for X>0, X and X-1 have no one-bits + in common if and only if X is a power of 2, ie has only one one-bit. + Some compilers may give an "unreachable code" warning here; ignore it. } + {$push}{$warnings off} + if ((SIZEOF(ALIGN_TYPE) and (SIZEOF(ALIGN_TYPE)-1)) <> 0) then + ERREXIT(cinfo, JERR_BAD_ALIGN_TYPE); + {$pop} + { MAX_ALLOC_CHUNK must be representable as type size_t, and must be + a multiple of SIZEOF(ALIGN_TYPE). + Again, an "unreachable code" warning may be ignored here. + But a "constant too large" warning means you need to fix MAX_ALLOC_CHUNK. } + + test_mac := size_t (MAX_ALLOC_CHUNK); + if (long (test_mac) <> MAX_ALLOC_CHUNK) or + ((MAX_ALLOC_CHUNK mod SIZEOF(ALIGN_TYPE)) <> 0) then + ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK); + + max_to_use := jpeg_mem_init(cinfo); { system-dependent initialization } + + { Attempt to allocate memory manager's control block } + mem := my_mem_ptr (jpeg_get_small(cinfo, SIZEOF(my_memory_mgr))); + + if (mem = NIL) then + begin + jpeg_mem_term(cinfo); { system-dependent cleanup } + ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 0); + end; + + { OK, fill in the method pointers } + mem^.pub.alloc_small := alloc_small; + mem^.pub.alloc_large := alloc_large; + mem^.pub.alloc_sarray := alloc_sarray; + mem^.pub.alloc_barray := alloc_barray; + mem^.pub.request_virt_sarray := request_virt_sarray; + mem^.pub.request_virt_barray := request_virt_barray; + mem^.pub.realize_virt_arrays := realize_virt_arrays; + mem^.pub.access_virt_sarray := access_virt_sarray; + mem^.pub.access_virt_barray := access_virt_barray; + mem^.pub.free_pool := free_pool; + mem^.pub.self_destruct := self_destruct; + + { Make MAX_ALLOC_CHUNK accessible to other modules } + mem^.pub.max_alloc_chunk := MAX_ALLOC_CHUNK; + + { Initialize working state } + mem^.pub.max_memory_to_use := max_to_use; + + for pool := JPOOL_NUMPOOLS-1 downto JPOOL_PERMANENT do + begin + mem^.small_list[pool] := NIL; + mem^.large_list[pool] := NIL; + end; + mem^.virt_sarray_list := NIL; + mem^.virt_barray_list := NIL; + + mem^.total_space_allocated := SIZEOF(my_memory_mgr); + + { Declare ourselves open for business } + cinfo^.mem := @mem^.pub; + + { Check for an environment variable JPEGMEM; if found, override the + default max_memory setting from jpeg_mem_init. Note that the + surrounding application may again override this value. + If your system doesn't support getenv(), define NO_GETENV to disable + this feature. } + +{$ifndef NO_GETENV} + memenv := getenv('JPEGMEM'); + if (memenv <> '') then + begin + Val(memenv, max_to_use, code); + if (Code = 0) then + begin + max_to_use := max_to_use * long(1000); + mem^.pub.max_memory_to_use := max_to_use * long(1000); + end; + end; +{$endif} + +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jmemnobs_del.pas b/mseide-msegui/lib/common/fpccompatibility/jmemnobs_del.pas new file mode 100644 index 0000000..6d8279d --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jmemnobs_del.pas @@ -0,0 +1,265 @@ +Unit jmemnobs_del; +{ Delphi3 -- > jmemnobs from jmemwin } +{ This file provides an Win32-compatible implementation of the system- + dependent portion of the JPEG memory manager. } + +{ Check jmemnobs.c } +{ Copyright (C) 1996, Jacques Nomssi Nzali } +//modified 2013 by Martin Schreiber + + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jdeferr_del, + jerror_del, + jpeglib_del; + +{ The macro MAX_ALLOC_CHUNK designates the maximum number of bytes that may + be requested in a single call to jpeg_get_large (and jpeg_get_small for that + matter, but that case should never come into play). This macro is needed + to model the 64Kb-segment-size limit of far addressing on 80x86 machines. + On those machines, we expect that jconfig.h will provide a proper value. + On machines with 32-bit flat address spaces, any large constant may be used. + + NB: jmemmgr.c expects that MAX_ALLOC_CHUNK will be representable as type + size_t and will be a multiple of sizeof(align_type). } + +{$IFDEF CPU16} +const + MAX_ALLOC_CHUNK = long(32752); +{$ELSE} +const + MAX_ALLOC_CHUNK = long(1000000000); +{$ENDIF} + +{GLOBAL} +procedure jpeg_open_backing_store (cinfo : j_common_ptr; + info : backing_store_ptr; + total_bytes_needed : long); + +{ These routines take care of any system-dependent initialization and + cleanup required. } + +{GLOBAL} +function jpeg_mem_init (cinfo : j_common_ptr) : long; + +{GLOBAL} +procedure jpeg_mem_term (cinfo : j_common_ptr); + +{ These two functions are used to allocate and release small chunks of + memory. (Typically the total amount requested through jpeg_get_small is + no more than 20K or so; this will be requested in chunks of a few K each.) + Behavior should be the same as for the standard library functions malloc + and free; in particular, jpeg_get_small must return NIL on failure. + On most systems, these ARE malloc and free. jpeg_free_small is passed the + size of the object being freed, just in case it's needed. + On an 80x86 machine using small-data memory model, these manage near heap. } + + +{ Near-memory allocation and freeing are controlled by the regular library + routines malloc() and free(). } + +{GLOBAL} +function jpeg_get_small (cinfo : j_common_ptr; + sizeofobject : size_t) : pointer; + +{GLOBAL} +{object is a reserved word in Borland Pascal } +procedure jpeg_free_small (cinfo : j_common_ptr; + an_object : pointer; + sizeofobject : size_t); + +{ These two functions are used to allocate and release large chunks of + memory (up to the total free space designated by jpeg_mem_available). + The interface is the same as above, except that on an 80x86 machine, + far pointers are used. On most other machines these are identical to + the jpeg_get/free_small routines; but we keep them separate anyway, + in case a different allocation strategy is desirable for large chunks. } + + +{ "Large" objects are allocated in far memory, if possible } + + +{GLOBAL} +function jpeg_get_large (cinfo : j_common_ptr; + sizeofobject : size_t) : voidp; {far} + +{GLOBAL} +procedure jpeg_free_large (cinfo : j_common_ptr; + {var?} an_object : voidp; {FAR} + sizeofobject : size_t); + +{ This routine computes the total memory space available for allocation. + It's impossible to do this in a portable way; our current solution is + to make the user tell us (with a default value set at compile time). + If you can actually get the available space, it's a good idea to subtract + a slop factor of 5% or so. } + +{GLOBAL} +function jpeg_mem_available (cinfo : j_common_ptr; + min_bytes_needed : long; + max_bytes_needed : long; + already_allocated : long) : long; + + +implementation + +{ This structure holds whatever state is needed to access a single + backing-store object. The read/write/close method pointers are called + by jmemmgr.c to manipulate the backing-store object; all other fields + are private to the system-dependent backing store routines. } + + + +{ These two functions are used to allocate and release small chunks of + memory. (Typically the total amount requested through jpeg_get_small is + no more than 20K or so; this will be requested in chunks of a few K each.) + Behavior should be the same as for the standard library functions malloc + and free; in particular, jpeg_get_small must return NIL on failure. + On most systems, these ARE malloc and free. jpeg_free_small is passed the + size of the object being freed, just in case it's needed. + On an 80x86 machine using small-data memory model, these manage near heap. } + + +{ Near-memory allocation and freeing are controlled by the regular library + routines malloc() and free(). } + +{GLOBAL} +function jpeg_get_small (cinfo : j_common_ptr; + sizeofobject : size_t) : pointer; +var + p : pointer; +begin + GetMem(p, sizeofobject); + jpeg_get_small := p; +end; + +{GLOBAL} +{object is a reserved word in Object Pascal } +procedure jpeg_free_small (cinfo : j_common_ptr; + an_object : pointer; + sizeofobject : size_t); +begin + FreeMem(an_object, sizeofobject); +end; + +{ These two functions are used to allocate and release large chunks of + memory (up to the total free space designated by jpeg_mem_available). + The interface is the same as above, except that on an 80x86 machine, + far pointers are used. On most other machines these are identical to + the jpeg_get/free_small routines; but we keep them separate anyway, + in case a different allocation strategy is desirable for large chunks. } + + + +{GLOBAL} +function jpeg_get_large (cinfo : j_common_ptr; + sizeofobject : size_t) : voidp; {far} +var + p : pointer; +begin + GetMem(p, sizeofobject); + jpeg_get_large := p; +end; + +{GLOBAL} +procedure jpeg_free_large (cinfo : j_common_ptr; + {var?} an_object : voidp; {FAR} + sizeofobject : size_t); +begin + Freemem(an_object, sizeofobject); +end; + +{ This routine computes the total space still available for allocation by + jpeg_get_large. If more space than this is needed, backing store will be + used. NOTE: any memory already allocated must not be counted. + + There is a minimum space requirement, corresponding to the minimum + feasible buffer sizes; jmemmgr.c will request that much space even if + jpeg_mem_available returns zero. The maximum space needed, enough to hold + all working storage in memory, is also passed in case it is useful. + Finally, the total space already allocated is passed. If no better + method is available, cinfo^.mem^.max_memory_to_use - already_allocated + is often a suitable calculation. + + It is OK for jpeg_mem_available to underestimate the space available + (that'll just lead to more backing-store access than is really necessary). + However, an overestimate will lead to failure. Hence it's wise to subtract + a slop factor from the true available space. 5% should be enough. + + On machines with lots of virtual memory, any large constant may be returned. + Conversely, zero may be returned to always use the minimum amount of memory.} + + + +{ This routine computes the total memory space available for allocation. + It's impossible to do this in a portable way; our current solution is + to make the user tell us (with a default value set at compile time). + If you can actually get the available space, it's a good idea to subtract + a slop factor of 5% or so. } + +const + DEFAULT_MAX_MEM = long(300000); { for total usage about 450K } + +{GLOBAL} +function jpeg_mem_available (cinfo : j_common_ptr; + min_bytes_needed : long; + max_bytes_needed : long; + already_allocated : long) : long; +begin + {jpeg_mem_available := cinfo^.mem^.max_memory_to_use - already_allocated;} + jpeg_mem_available := max_bytes_needed; +end; + + +{ Initial opening of a backing-store object. This must fill in the + read/write/close pointers in the object. The read/write routines + may take an error exit if the specified maximum file size is exceeded. + (If jpeg_mem_available always returns a large value, this routine can + just take an error exit.) } + + + +{ Initial opening of a backing-store object. } + +{GLOBAL} +procedure jpeg_open_backing_store (cinfo : j_common_ptr; + info : backing_store_ptr; + total_bytes_needed : long); +begin + ERREXIT(cinfo, JERR_NO_BACKING_STORE); +end; + +{ These routines take care of any system-dependent initialization and + cleanup required. jpeg_mem_init will be called before anything is + allocated (and, therefore, nothing in cinfo is of use except the error + manager pointer). It should return a suitable default value for + max_memory_to_use; this may subsequently be overridden by the surrounding + application. (Note that max_memory_to_use is only important if + jpeg_mem_available chooses to consult it ... no one else will.) + jpeg_mem_term may assume that all requested memory has been freed and that + all opened backing-store objects have been closed. } + + +{ These routines take care of any system-dependent initialization and + cleanup required. } + + +{GLOBAL} +function jpeg_mem_init (cinfo : j_common_ptr) : long; +begin + jpeg_mem_init := DEFAULT_MAX_MEM; { default for max_memory_to_use } +end; + +{GLOBAL} +procedure jpeg_mem_term (cinfo : j_common_ptr); +begin + +end; + + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jmemsys_del.pas b/mseide-msegui/lib/common/fpccompatibility/jmemsys_del.pas new file mode 100644 index 0000000..1218561 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jmemsys_del.pas @@ -0,0 +1,177 @@ +Unit jmemsys; + +{ This is a skeleton you need to create a working system-dependent + JPEG memory manager. + No other modules need include it. (The system-independent portion is + jmemmgr.c; there are several different versions of the system-dependent + portion.) + + This code will not compile - Check JMEMDOS.PAS for an example } + +{ Original: jmemsys.h; Copyright (C) 1992-1996, Thomas G. Lane. } + +interface + +uses + jmorecfg, + jpeglib; + +{ The macro MAX_ALLOC_CHUNK designates the maximum number of bytes that may + be requested in a single call to jpeg_get_large (and jpeg_get_small for that + matter, but that case should never come into play). This macro is needed + to model the 64Kb-segment-size limit of far addressing on 80x86 machines. + On those machines, we expect that jconfig.h will provide a proper value. + On machines with 32-bit flat address spaces, any large constant may be used. + + NB: jmemmgr.c expects that MAX_ALLOC_CHUNK will be representable as type + size_t and will be a multiple of sizeof(align_type). } + +{$ifdef USE_MSDOS_MEMMGR} { Define this if you use jmemdos.c } +const + MAX_ALLOC_CHUNK = long(65520); { Maximum request to malloc() } +{$else} +const + MAX_ALLOC_CHUNK = long(1000000000); +{$endif} + + + +{ Initial opening of a backing-store object. This must fill in the + read/write/close pointers in the object. The read/write routines + may take an error exit if the specified maximum file size is exceeded. + (If jpeg_mem_available always returns a large value, this routine can + just take an error exit.) } + + +EXTERN procedure jpeg_open_backing_store (cinfo : j_common_ptr; + info : backing_store_ptr; + total_bytes_needed : long); + + +{ These routines take care of any system-dependent initialization and + cleanup required. jpeg_mem_init will be called before anything is + allocated (and, therefore, nothing in cinfo is of use except the error + manager pointer). It should return a suitable default value for + max_memory_to_use; this may subsequently be overridden by the surrounding + application. (Note that max_memory_to_use is only important if + jpeg_mem_available chooses to consult it ... no one else will.) + jpeg_mem_term may assume that all requested memory has been freed and that + all opened backing-store objects have been closed. } + + +EXTERN function jpeg_mem_init (cinfo : j_common_ptr) : long; +EXTERN procedure jpeg_mem_term (cinfo : j_common_ptr); + + +implementation + +{ This structure holds whatever state is needed to access a single + backing-store object. The read/write/close method pointers are called + by jmemmgr.c to manipulate the backing-store object; all other fields + are private to the system-dependent backing store routines. } + + +const + TEMP_NAME_LENGTH = 64; { max length of a temporary file's name } + +{$ifdef USE_MSDOS_MEMMGR} { DOS-specific junk } +type + XMSH = ushort; { type of extended-memory handles } + EMSH = ushort; { type of expanded-memory handles } + + handle_union = record + case byte of + 0:(file_handle : short); { DOS file handle if it's a temp file } + 1:(xms_handle : XMSH); { handle if it's a chunk of XMS } + 2:(ems_handle : EMSH); { handle if it's a chunk of EMS } + end; +{$endif - USE_MSDOS_MEMMGR } + +type + backing_store_ptr = ^backing_store_info; + backing_store_info = record + { Methods for reading/writing/closing this backing-store object } + read_backing_store : procedure (cinfo : j_common_ptr; + info : backing_store_ptr; + buffer_address : pointer; {far} + file_offset : long; + byte_count : long); + write_backing_store : procedure (cinfo : j_common_ptr; + info : backing_store_ptr; + buffer_address : pointer; {far} + file_offset : long; + byte_count : long); + + close_backing_store : procedure (cinfo : j_common_ptr; + info : backing_store_ptr); + + { Private fields for system-dependent backing-store management } + {$ifdef USE_MSDOS_MEMMGR} + { For the MS-DOS manager (jmemdos.c), we need: } + handle : handle_union; { reference to backing-store storage object } + temp_name : string[TEMP_NAME_LENGTH]; { name if it's a file } + {$else} + { For a typical implementation with temp files, we need: } + temp_file : FILE; { stdio reference to temp file } + temp_name : string[TEMP_NAME_LENGTH]; { name of temp file } + {$endif} + end; + +{ These two functions are used to allocate and release small chunks of + memory. (Typically the total amount requested through jpeg_get_small is + no more than 20K or so; this will be requested in chunks of a few K each.) + Behavior should be the same as for the standard library functions malloc + and free; in particular, jpeg_get_small must return NIL on failure. + On most systems, these ARE malloc and free. jpeg_free_small is passed the + size of the object being freed, just in case it's needed. + On an 80x86 machine using small-data memory model, these manage near heap. } + +EXTERN function jpeg_get_small (cinfo : j_common_ptr; + sizeofobject : size_t) : pointer; +EXTERN procedure jpeg_free_small (cinfo : j_common_ptr; + object : pointer; + sizeofobject : size_t); + +{ These two functions are used to allocate and release large chunks of + memory (up to the total free space designated by jpeg_mem_available). + The interface is the same as above, except that on an 80x86 machine, + far pointers are used. On most other machines these are identical to + the jpeg_get/free_small routines; but we keep them separate anyway, + in case a different allocation strategy is desirable for large chunks. } + +EXTERN function jpeg_get_large (cinfo : j_common_ptr cinfo; + sizeofobject : size_t) : pointer; {far} + +EXTERN procedure jpeg_free_large (cinfo : j_common_ptr; + object : pointer; {far} + sizeofobject : size_t); + + +{ This routine computes the total space still available for allocation by + jpeg_get_large. If more space than this is needed, backing store will be + used. NOTE: any memory already allocated must not be counted. + + There is a minimum space requirement, corresponding to the minimum + feasible buffer sizes; jmemmgr.c will request that much space even if + jpeg_mem_available returns zero. The maximum space needed, enough to hold + all working storage in memory, is also passed in case it is useful. + Finally, the total space already allocated is passed. If no better + method is available, cinfo->mem->max_memory_to_use - already_allocated + is often a suitable calculation. + + It is OK for jpeg_mem_available to underestimate the space available + (that'll just lead to more backing-store access than is really necessary). + However, an overestimate will lead to failure. Hence it's wise to subtract + a slop factor from the true available space. 5% should be enough. + + On machines with lots of virtual memory, any large constant may be returned. + Conversely, zero may be returned to always use the minimum amount of memory.} + + +EXTERN function jpeg_mem_available (cinfo : j_common_ptr; + min_bytes_needed : long; + max_bytes_needed : long; + already_allocated : long) : long; + + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jmorecfg_del.pas b/mseide-msegui/lib/common/fpccompatibility/jmorecfg_del.pas new file mode 100644 index 0000000..b611f3a --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jmorecfg_del.pas @@ -0,0 +1,250 @@ +unit jmorecfg_del; + +{ This file contains additional configuration options that customize the + JPEG software for special applications or support machine-dependent + optimizations. Most users will not need to touch this file. } + +{ Source: jmorecfg.h; Copyright (C) 1991-1996, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +//{$IFDEF FPC} { Free Pascal Compiler } + type + int = longint; + uInt = Cardinal; { unsigned int } + short = Integer; + ushort = Word; + long = longint; +(* +{$ELSE} +{$IFDEF WIN32} + { Delphi 2.0 } + type + int = Integer; + uInt = Cardinal; + short = SmallInt; + ushort = Word; + long = longint; + {$ELSE} + {$IFDEF VIRTUALPASCAL} + type + int = longint; + uInt = longint; { unsigned int } + short = system.Integer; + ushort = system.Word; + long = longint; + {$ELSE} + type + int = Integer; + uInt = Word; { unsigned int } + short = Integer; + ushort = Word; + long = longint; + {$ENDIF} +{$ENDIF} +{$ENDIF} +*) +type + voidp = pointer; + +type + int_ptr = ^int; + size_t = int; + +{ Define BITS_IN_JSAMPLE as either + 8 for 8-bit sample values (the usual setting) + 12 for 12-bit sample values + Only 8 and 12 are legal data precisions for lossy JPEG according to the + JPEG standard, and the IJG code does not support anything else! + We do not support run-time selection of data precision, sorry. } + +{$ifdef BITS_IN_JSAMPLE_IS_8} { use 8 or 12 } +const + BITS_IN_JSAMPLE = 8; +{$else} +const + BITS_IN_JSAMPLE = 12; +{$endif} + + + + +{ Maximum number of components (color channels) allowed in JPEG image. + To meet the letter of the JPEG spec, set this to 255. However, darn + few applications need more than 4 channels (maybe 5 for CMYK + alpha + mask). We recommend 10 as a reasonable compromise; use 4 if you are + really short on memory. (Each allowed component costs a hundred or so + bytes of storage, whether actually used in an image or not.) } + + +const + MAX_COMPONENTS = 10; { maximum number of image components } + + +{ Basic data types. + You may need to change these if you have a machine with unusual data + type sizes; for example, "char" not 8 bits, "short" not 16 bits, + or "long" not 32 bits. We don't care whether "int" is 16 or 32 bits, + but it had better be at least 16. } + + +{ Representation of a single sample (pixel element value). + We frequently allocate large arrays of these, so it's important to keep + them small. But if you have memory to burn and access to char or short + arrays is very slow on your hardware, you might want to change these. } + + +{$ifdef BITS_IN_JSAMPLE_IS_8} +{ JSAMPLE should be the smallest type that will hold the values 0..255. + You can use a signed char by having GETJSAMPLE mask it with $FF. } + +{ CHAR_IS_UNSIGNED } +type + JSAMPLE = byte; { Pascal unsigned char } + GETJSAMPLE = int; + +const + MAXJSAMPLE = 255; + CENTERJSAMPLE = 128; + +{$endif} + +{$ifndef BITS_IN_JSAMPLE_IS_8} +{ JSAMPLE should be the smallest type that will hold the values 0..4095. + On nearly all machines "short" will do nicely. } + +type + JSAMPLE = short; + GETJSAMPLE = int; + +const + MAXJSAMPLE = 4095; + CENTERJSAMPLE = 2048; + +{$endif} { BITS_IN_JSAMPLE = 12 } + + +{ Representation of a DCT frequency coefficient. + This should be a signed value of at least 16 bits; "short" is usually OK. + Again, we allocate large arrays of these, but you can change to int + if you have memory to burn and "short" is really slow. } +type + JCOEF = int; + JCOEF_PTR = ^JCOEF; + + +{ Compressed datastreams are represented as arrays of JOCTET. + These must be EXACTLY 8 bits wide, at least once they are written to + external storage. Note that when using the stdio data source/destination + managers, this is also the data type passed to fread/fwrite. } + + +type + JOCTET = Byte; + jTOctet = 0..(MaxInt div SizeOf(JOCTET))-1; + JOCTET_FIELD = array[jTOctet] of JOCTET; + JOCTET_FIELD_PTR = ^JOCTET_FIELD; + JOCTETPTR = ^JOCTET; + + GETJOCTET = JOCTET; { A work around } + + +{ These typedefs are used for various table entries and so forth. + They must be at least as wide as specified; but making them too big + won't cost a huge amount of memory, so we don't provide special + extraction code like we did for JSAMPLE. (In other words, these + typedefs live at a different point on the speed/space tradeoff curve.) } + + +{ UINT8 must hold at least the values 0..255. } + +type + UINT8 = byte; + +{ UINT16 must hold at least the values 0..65535. } + + UINT16 = Word; + +{ INT16 must hold at least the values -32768..32767. } + + INT16 = int; + +{ INT32 must hold at least signed 32-bit values. } + + INT32 = longint; +type + INT32PTR = ^INT32; + +{ Datatype used for image dimensions. The JPEG standard only supports + images up to 64K*64K due to 16-bit fields in SOF markers. Therefore + "unsigned int" is sufficient on all machines. However, if you need to + handle larger images and you don't mind deviating from the spec, you + can change this datatype. } + +type + JDIMENSION = uInt; + +const + JPEG_MAX_DIMENSION = 65500; { a tad under 64K to prevent overflows } + + +{ Ordering of RGB data in scanlines passed to or from the application. + If your application wants to deal with data in the order B,G,R, just + change these macros. You can also deal with formats such as R,G,B,X + (one extra byte per pixel) by changing RGB_PIXELSIZE. Note that changing + the offsets will also change the order in which colormap data is organized. + RESTRICTIONS: + 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats. + 2. These macros only affect RGB<=>YCbCr color conversion, so they are not + useful if you are using JPEG color spaces other than YCbCr or grayscale. + 3. The color quantizer modules will not behave desirably if RGB_PIXELSIZE + is not 3 (they don't understand about dummy color components!). So you + can't use color quantization if you change that value. } + +{$ifdef RGB_RED_IS_0} +const + RGB_RED = 0; { Offset of Red in an RGB scanline element } + RGB_GREEN = 1; { Offset of Green } + RGB_BLUE = 2; { Offset of Blue } +{$else} +const + RGB_RED = 2; { Offset of Red in an RGB scanline element } + RGB_GREEN = 1; { Offset of Green } + RGB_BLUE = 0; { Offset of Blue } +{$endif} + +{$ifdef RGB_PIXELSIZE_IS_3} +const + RGB_PIXELSIZE = 3; { JSAMPLEs per RGB scanline element } +{$else} +const + RGB_PIXELSIZE = ??; { Nomssi: deliberate syntax error. Set this value } +{$endif} + +{ Definitions for speed-related optimizations. } + +{ On some machines (notably 68000 series) "int" is 32 bits, but multiplying + two 16-bit shorts is faster than multiplying two ints. Define MULTIPLIER + as short on such a machine. MULTIPLIER must be at least 16 bits wide. } +type + MULTIPLIER = int; { type for fastest integer multiply } + + +{ FAST_FLOAT should be either float or double, whichever is done faster + by your compiler. (Note that this type is only used in the floating point + DCT routines, so it only matters if you've defined DCT_FLOAT_SUPPORTED.) + Typically, float is faster in ANSI C compilers, while double is faster in + pre-ANSI compilers (because they insist on converting to double anyway). + The code below therefore chooses float if we have ANSI-style prototypes. } + +type + FAST_FLOAT = double; {float} + + +implementation + + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jpeglib_del.pas b/mseide-msegui/lib/common/fpccompatibility/jpeglib_del.pas new file mode 100644 index 0000000..e7b17aa --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jpeglib_del.pas @@ -0,0 +1,1301 @@ +unit jpeglib_del; + +{ This file defines the application interface for the JPEG library. + Most applications using the library need only include this file, + and perhaps jerror.h if they want to know the exact error codes. } + +{ Source:jpeglib.h+jpegint.h; Copyright (C) 1991-1998, Thomas G. Lane. } + +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +{ First we include the configuration files that record how this + installation of the JPEG library is set up. jconfig.h can be + generated automatically for many systems. jmorecfg.h contains + manual configuration options that most people need not worry about. } + +uses + jdeferr_del, + jmorecfg_del; { seldom changed options } + +{ Version ID for the JPEG library. + Might be useful for tests like "#if JPEG_LIB_VERSION >= 60". } + + +Const + JPEG_LIB_VERSION = 62; { Version 6b } + + +{ These marker codes are exported since applications and data source modules + are likely to want to use them. } + +const + JPEG_RST0 = $D0; { RST0 marker code } + JPEG_EOI = $D9; { EOI marker code } + JPEG_APP0 = $E0; { APP0 marker code } + JPEG_COM = $FE; { COM marker code } + + +{ Various constants determining the sizes of things. + All of these are specified by the JPEG standard, so don't change them + if you want to be compatible. } + +const + DCTSIZE = 8; { The basic DCT block is 8x8 samples } + DCTSIZE2 = 64; { DCTSIZE squared; # of elements in a block } + NUM_QUANT_TBLS = 4; { Quantization tables are numbered 0..3 } + NUM_HUFF_TBLS = 4; { Huffman tables are numbered 0..3 } + NUM_ARITH_TBLS = 16; { Arith-coding tables are numbered 0..15 } + MAX_COMPS_IN_SCAN = 4; { JPEG limit on # of components in one scan } + MAX_SAMP_FACTOR = 4; { JPEG limit on sampling factors } +{ Unfortunately, some bozo at Adobe saw no reason to be bound by the standard; + the PostScript DCT filter can emit files with many more than 10 blocks/MCU. + If you happen to run across such a file, you can up D_MAX_BLOCKS_IN_MCU + to handle it. We even let you do this from the jconfig.h file. However, + we strongly discourage changing C_MAX_BLOCKS_IN_MCU; just because Adobe + sometimes emits noncompliant files doesn't mean you should too. } + C_MAX_BLOCKS_IN_MCU = 10; { compressor's limit on blocks per MCU } + D_MAX_BLOCKS_IN_MCU = 10; { decompressor's limit on blocks per MCU } + + +{ Data structures for images (arrays of samples and of DCT coefficients). + On 80x86 machines, the image arrays are too big for near pointers, + but the pointer arrays can fit in near memory. } + +type +{ for typecasting } + JSAMPLE_PTR = ^JSAMPLE; + JSAMPROW_PTR = ^JSAMPROW; + JBLOCKROW_PTR = ^JBLOCKROW; + + jTSample = 0..(MaxInt div SIZEOF(JSAMPLE))-1; + JSAMPLE_ARRAY = Array[jTSample] of JSAMPLE; {far} + JSAMPROW = ^JSAMPLE_ARRAY; { ptr to one image row of pixel samples. } + + jTRow = 0..(MaxInt div SIZEOF(JSAMPROW))-1; + JSAMPROW_ARRAY = Array[jTRow] of JSAMPROW; + JSAMPARRAY = ^JSAMPROW_ARRAY; { ptr to some rows (a 2-D sample array) } + + jTArray = 0..(MaxInt div SIZEOF(JSAMPARRAY))-1; + JSAMP_ARRAY = Array[jTArray] of JSAMPARRAY; + JSAMPIMAGE = ^JSAMP_ARRAY; { a 3-D sample array: top index is color } + + JBLOCK = Array[0..DCTSIZE2-1] of JCOEF; { one block of coefficients } + JBLOCK_PTR = ^JBLOCK; + + jTBlockRow = 0..(MaxInt div SIZEOF(JBLOCK))-1; + JBLOCK_ROWS = Array[jTBlockRow] of JBLOCK; + JBLOCKROW = ^JBLOCK_ROWS; {far} { pointer to one row of coefficient blocks } + + + jTBlockArray = 0..(MaxInt div SIZEOF(JBLOCKROW))-1; + JBLOCK_ARRAY = Array[jTBlockArray] of JBLOCKROW; + JBLOCKARRAY = ^JBLOCK_ARRAY; { a 2-D array of coefficient blocks } + + jTBlockImage = 0..(MaxInt div SIZEOF(JBLOCKARRAY))-1; + JBLOCK_IMAGE = Array[jTBlockImage] of JBLOCKARRAY; + JBLOCKIMAGE = ^JBLOCK_IMAGE; { a 3-D array of coefficient blocks } + + jTCoef = 0..(MaxInt div SIZEOF(JCOEF))-1; + JCOEF_ROW = Array[jTCoef] of JCOEF; + JCOEFPTR = ^JCOEF_ROW; {far} { useful in a couple of places } + + +type + jTByte = 0..(MaxInt div SIZEOF(byte))-1; + JByteArray = Array[jTByte] of byte; + JBytePtr = ^JByteArray; +type + byteptr = ^byte; + +{ Types for JPEG compression parameters and working tables. } + + +{ DCT coefficient quantization tables. } + +type + JQUANT_TBL_PTR = ^JQUANT_TBL; + JQUANT_TBL = record + { This array gives the coefficient quantizers in natural array order + (not the zigzag order in which they are stored in a JPEG DQT marker). + CAUTION: IJG versions prior to v6a kept this array in zigzag order. } + quantval : Array[0..DCTSIZE2-1] of UINT16; + { quantization step for each coefficient } + { This field is used only during compression. It's initialized FALSE when + the table is created, and set TRUE when it's been output to the file. + You could suppress output of a table by setting this to TRUE. + (See jpeg_suppress_tables for an example.) } + sent_table : boolean; { TRUE when table has been output } + end; + JQUANT_TBL_FIELD = Array[0..(MaxInt div SizeOf(JQUANT_TBL))-1] of JQUANT_TBL; + +{ Huffman coding tables. } + +type + JHUFF_TBL_PTR = ^JHUFF_TBL; + JHUFF_TBL = record + { These two fields directly represent the contents of a JPEG DHT marker } + bits : Array[0..17-1] of UINT8; { bits[k] = # of symbols with codes of } + { length k bits; bits[0] is unused } + huffval : Array[0..256-1] of UINT8; + { The symbols, in order of incr code length } + { This field is used only during compression. It's initialized FALSE when + the table is created, and set TRUE when it's been output to the file. + You could suppress output of a table by setting this to TRUE. + (See jpeg_suppress_tables for an example.) } + sent_table : boolean; { TRUE when table has been output } + end; + JHUFF_TBL_FIELD = Array[0..(MaxInt div SizeOf(JHUFF_TBL))-1] of JHUFF_TBL; + +{ Declarations for both compression & decompression } + +type + J_BUF_MODE = ( { Operating modes for buffer controllers } + JBUF_PASS_THRU, { Plain stripwise operation } + { Remaining modes require a full-image buffer to have been created } + JBUF_SAVE_SOURCE, { Run source subobject only, save output } + JBUF_CRANK_DEST, { Run dest subobject only, using saved data } + JBUF_SAVE_AND_PASS { Run both subobjects, save output } + ); + +{ Values of global_state field (jdapi.c has some dependencies on ordering!) } +const + CSTATE_START = 100; { after create_compress } + CSTATE_SCANNING = 101; { start_compress done, write_scanlines OK } + CSTATE_RAW_OK = 102; { start_compress done, write_raw_data OK } + CSTATE_WRCOEFS = 103; { jpeg_write_coefficients done } + DSTATE_START = 200; { after create_decompress } + DSTATE_INHEADER = 201; { reading header markers, no SOS yet } + DSTATE_READY = 202; { found SOS, ready for start_decompress } + DSTATE_PRELOAD = 203; { reading multiscan file in start_decompress} + DSTATE_PRESCAN = 204; { performing dummy pass for 2-pass quant } + DSTATE_SCANNING = 205; { start_decompress done, read_scanlines OK } + DSTATE_RAW_OK = 206; { start_decompress done, read_raw_data OK } + DSTATE_BUFIMAGE = 207; { expecting jpeg_start_output } + DSTATE_BUFPOST = 208; { looking for SOS/EOI in jpeg_finish_output } + DSTATE_RDCOEFS = 209; { reading file in jpeg_read_coefficients } + DSTATE_STOPPING = 210; { looking for EOI in jpeg_finish_decompress } + + + +{ Basic info about one component (color channel). } + +type + jpeg_component_info_ptr = ^jpeg_component_info; + jpeg_component_info = record + { These values are fixed over the whole image. } + { For compression, they must be supplied by parameter setup; } + { for decompression, they are read from the SOF marker. } + component_id : int; { identifier for this component (0..255) } + component_index : int; { its index in SOF or cinfo^.comp_info[] } + h_samp_factor : int; { horizontal sampling factor (1..4) } + v_samp_factor : int; { vertical sampling factor (1..4) } + quant_tbl_no : int; { quantization table selector (0..3) } + { These values may vary between scans. } + { For compression, they must be supplied by parameter setup; } + { for decompression, they are read from the SOS marker. } + { The decompressor output side may not use these variables. } + dc_tbl_no : int; { DC entropy table selector (0..3) } + ac_tbl_no : int; { AC entropy table selector (0..3) } + + { Remaining fields should be treated as private by applications. } + + { These values are computed during compression or decompression startup: } + { Component's size in DCT blocks. + Any dummy blocks added to complete an MCU are not counted; therefore + these values do not depend on whether a scan is interleaved or not. } + width_in_blocks : JDIMENSION; + height_in_blocks : JDIMENSION; + { Size of a DCT block in samples. Always DCTSIZE for compression. + For decompression this is the size of the output from one DCT block, + reflecting any scaling we choose to apply during the IDCT step. + Values of 1,2,4,8 are likely to be supported. Note that different + components may receive different IDCT scalings. } + + DCT_scaled_size : int; + { The downsampled dimensions are the component's actual, unpadded number + of samples at the main buffer (preprocessing/compression interface), thus + downsampled_width = ceil(image_width * Hi/Hmax) + and similarly for height. For decompression, IDCT scaling is included, so + downsampled_width = ceil(image_width * Hi/Hmax * DCT_scaled_size/DCTSIZE)} + + downsampled_width : JDIMENSION; { actual width in samples } + downsampled_height : JDIMENSION; { actual height in samples } + { This flag is used only for decompression. In cases where some of the + components will be ignored (eg grayscale output from YCbCr image), + we can skip most computations for the unused components. } + + component_needed : boolean; { do we need the value of this component? } + + { These values are computed before starting a scan of the component. } + { The decompressor output side may not use these variables. } + MCU_width : int; { number of blocks per MCU, horizontally } + MCU_height : int; { number of blocks per MCU, vertically } + MCU_blocks : int; { MCU_width * MCU_height } + MCU_sample_width : int; { MCU width in samples, MCU_width*DCT_scaled_size } + last_col_width : int; { # of non-dummy blocks across in last MCU } + last_row_height : int; { # of non-dummy blocks down in last MCU } + + { Saved quantization table for component; NIL if none yet saved. + See jdinput.c comments about the need for this information. + This field is currently used only for decompression. } + + quant_table : JQUANT_TBL_PTR; + + { Private per-component storage for DCT or IDCT subsystem. } + dct_table : pointer; + end; { record jpeg_component_info } + + jTCinfo = 0..(MaxInt div SizeOf(jpeg_component_info))-1; + jpeg_component_info_array = array[jTCinfo] of jpeg_component_info; + jpeg_component_info_list_ptr = ^jpeg_component_info_array; + + +{ The script for encoding a multiple-scan file is an array of these: } + +type + jpeg_scan_info_ptr = ^jpeg_scan_info; + jpeg_scan_info = record + comps_in_scan : int; { number of components encoded in this scan } + component_index : Array[0..MAX_COMPS_IN_SCAN-1] of int; + { their SOF/comp_info[] indexes } + Ss, Se : int; { progressive JPEG spectral selection parms } + Ah, Al : int; { progressive JPEG successive approx. parms } + end; + +{ The decompressor can save APPn and COM markers in a list of these: } + +type + jpeg_saved_marker_ptr = ^jpeg_marker_struct; + jpeg_marker_struct = record + next : jpeg_saved_marker_ptr; { next in list, or NULL } + marker : UINT8; { marker code: JPEG_COM, or JPEG_APP0+n } + original_length : uint; { # bytes of data in the file } + data_length : uint; { # bytes of data saved at data[] } + data : JOCTET_FIELD_PTR; { the data contained in the marker } + { the marker length word is not counted in data_length or original_length } + end; + +{ Known color spaces. } + +type + J_COLOR_SPACE = ( + JCS_UNKNOWN, { error/unspecified } + JCS_GRAYSCALE, { monochrome } + JCS_RGB, { red/green/blue } + JCS_YCbCr, { Y/Cb/Cr (also known as YUV) } + JCS_CMYK, { C/M/Y/K } + JCS_YCCK { Y/Cb/Cr/K } + ); + +{ DCT/IDCT algorithm options. } + +type + J_DCT_METHOD = ( + JDCT_ISLOW, { slow but accurate integer algorithm } + JDCT_IFAST, { faster, less accurate integer method } + JDCT_FLOAT { floating-point: accurate, fast on fast HW } + ); + +const + JDCT_DEFAULT = JDCT_ISLOW; + JDCT_FASTEST = JDCT_IFAST; + +{ Dithering options for decompression. } + +type + J_DITHER_MODE = ( + JDITHER_NONE, { no dithering } + JDITHER_ORDERED, { simple ordered dither } + JDITHER_FS { Floyd-Steinberg error diffusion dither } + ); + + +const + JPOOL_PERMANENT = 0; { lasts until master record is destroyed } + JPOOL_IMAGE = 1; { lasts until done with image/datastream } + JPOOL_NUMPOOLS = 2; + + +{ "Object" declarations for JPEG modules that may be supplied or called + directly by the surrounding application. + As with all objects in the JPEG library, these structs only define the + publicly visible methods and state variables of a module. Additional + private fields may exist after the public ones. } + + +{ Error handler object } + +const + JMSG_LENGTH_MAX = 200; { recommended size of format_message buffer } + JMSG_STR_PARM_MAX = 80; + +const + TEMP_NAME_LENGTH = 64; { max length of a temporary file's name } +type + TEMP_STRING = string[TEMP_NAME_LENGTH]; + +{$ifdef USE_MSDOS_MEMMGR} { DOS-specific junk } +type + XMSH = ushort; { type of extended-memory handles } + EMSH = ushort; { type of expanded-memory handles } + + handle_union = record + case byte of + 0:(file_handle : short); { DOS file handle if it's a temp file } + 1:(xms_handle : XMSH); { handle if it's a chunk of XMS } + 2:(ems_handle : EMSH); { handle if it's a chunk of EMS } + end; +{$endif} { USE_MSDOS_MEMMGR } + +type + jpeg_error_mgr_ptr = ^jpeg_error_mgr; + jpeg_memory_mgr_ptr = ^jpeg_memory_mgr; + jpeg_progress_mgr_ptr = ^jpeg_progress_mgr; + + +{$ifdef common} +{ Common fields between JPEG compression and decompression master structs. } + err : jpeg_error_mgr_ptr; { Error handler module } + mem : jpeg_memory_mgr_ptr; { Memory manager module } + progress : jpeg_progress_mgr_ptr; { Progress monitor, or NIL if none } + client_data : voidp; { Available for use by application } + is_decompressor : boolean; { so common code can tell which is which } + global_state : int; { for checking call sequence validity } +{$endif} + + j_common_ptr = ^jpeg_common_struct; + j_compress_ptr = ^jpeg_compress_struct; + j_decompress_ptr = ^jpeg_decompress_struct; + + {$ifdef AM_MEMORY_MANAGER} { only jmemmgr.c defines these } + +{ This structure holds whatever state is needed to access a single + backing-store object. The read/write/close method pointers are called + by jmemmgr.c to manipulate the backing-store object; all other fields + are private to the system-dependent backing store routines. } + + + backing_store_ptr = ^backing_store_info; + backing_store_info = record + { Methods for reading/writing/closing this backing-store object } + read_backing_store : procedure (cinfo : j_common_ptr; + info : backing_store_ptr; + buffer_address : pointer; {far} + file_offset : long; + byte_count : long); + write_backing_store : procedure (cinfo : j_common_ptr; + info : backing_store_ptr; + buffer_address : pointer; {far} + file_offset : long; + byte_count : long); + + close_backing_store : procedure (cinfo : j_common_ptr; + info : backing_store_ptr); + + { Private fields for system-dependent backing-store management } + {$ifdef USE_MSDOS_MEMMGR} + { For the MS-DOS manager (jmemdos.c), we need: } + handle : handle_union; { reference to backing-store storage object } + temp_name : TEMP_STRING; { name if it's a file } + {$else} + { For a typical implementation with temp files, we need: } + temp_file : file; { stdio reference to temp file } + temp_name : TEMP_STRING; { name of temp file } + {$endif} + end; + + +{ The control blocks for virtual arrays. + Note that these blocks are allocated in the "small" pool area. + System-dependent info for the associated backing store (if any) is hidden + inside the backing_store_info struct. } + + jvirt_sarray_ptr = ^jvirt_sarray_control; + jvirt_sarray_control = record + mem_buffer : JSAMPARRAY; { => the in-memory buffer } + rows_in_array : JDIMENSION; { total virtual array height } + samplesperrow : JDIMENSION; { width of array (and of memory buffer) } + maxaccess : JDIMENSION; { max rows accessed by access_virt_sarray } + rows_in_mem : JDIMENSION; { height of memory buffer } + rowsperchunk : JDIMENSION; { allocation chunk size in mem_buffer } + cur_start_row : JDIMENSION; { first logical row # in the buffer } + first_undef_row : JDIMENSION; { row # of first uninitialized row } + pre_zero : boolean; { pre-zero mode requested? } + dirty : boolean; { do current buffer contents need written? } + b_s_open : boolean; { is backing-store data valid? } + next : jvirt_sarray_ptr; { link to next virtual sarray control block } + b_s_info : backing_store_info; { System-dependent control info } + end; + + jvirt_barray_ptr = ^jvirt_barray_control; + jvirt_barray_control = record + mem_buffer : JBLOCKARRAY; { => the in-memory buffer } + rows_in_array : JDIMENSION; { total virtual array height } + blocksperrow : JDIMENSION; { width of array (and of memory buffer) } + maxaccess : JDIMENSION; { max rows accessed by access_virt_barray } + rows_in_mem : JDIMENSION; { height of memory buffer } + rowsperchunk : JDIMENSION; { allocation chunk size in mem_buffer } + cur_start_row : JDIMENSION; { first logical row # in the buffer } + first_undef_row : JDIMENSION; { row # of first uninitialized row } + pre_zero : boolean; { pre-zero mode requested? } + dirty : boolean; { do current buffer contents need written? } + b_s_open : boolean; { is backing-store data valid? } + next : jvirt_barray_ptr; { link to next virtual barray control block } + b_s_info : backing_store_info; { System-dependent control info } + end; + + {$endif} { AM_MEMORY_MANAGER } + +{ Declarations for compression modules } + +{ Master control module } + jpeg_comp_master_ptr = ^jpeg_comp_master; + jpeg_comp_master = record + prepare_for_pass : procedure(cinfo : j_compress_ptr); + pass_startup : procedure(cinfo : j_compress_ptr); + finish_pass : procedure(cinfo : j_compress_ptr); + + { State variables made visible to other modules } + call_pass_startup : Boolean; { True if pass_startup must be called } + is_last_pass : Boolean; { True during last pass } + end; + +{ Main buffer control (downsampled-data buffer) } + jpeg_c_main_controller_ptr = ^jpeg_c_main_controller; + jpeg_c_main_controller = record + start_pass : procedure(cinfo : j_compress_ptr; pass_mode : J_BUF_MODE); + process_data : procedure(cinfo : j_compress_ptr; + input_buf : JSAMPARRAY; + var in_row_ctr : JDIMENSION; + in_rows_avail : JDIMENSION); + end; + +{ Compression preprocessing (downsampling input buffer control) } + jpeg_c_prep_controller_ptr = ^jpeg_c_prep_controller; + jpeg_c_prep_controller = record + start_pass : procedure(cinfo : j_compress_ptr; pass_mode : J_BUF_MODE); + pre_process_data : procedure(cinfo : j_compress_ptr; + input_buf : JSAMPARRAY; + var in_row_ctr : JDIMENSION; + in_rows_avail : JDIMENSION; + output_buf : JSAMPIMAGE; + var out_row_group_ctr : JDIMENSION; + out_row_groups_avail : JDIMENSION); + end; + +{ Coefficient buffer control } + jpeg_c_coef_controller_ptr = ^jpeg_c_coef_controller; + jpeg_c_coef_controller = record + start_pass : procedure(cinfo : j_compress_ptr; pass_mode : J_BUF_MODE); + compress_data : function(cinfo : j_compress_ptr; + input_buf : JSAMPIMAGE) : boolean; + end; + +{ Colorspace conversion } + jpeg_color_converter_ptr = ^jpeg_color_converter; + jpeg_color_converter = record + start_pass : procedure(cinfo : j_compress_ptr); + color_convert : procedure(cinfo : j_compress_ptr; + input_buf : JSAMPARRAY; + output_buf : JSAMPIMAGE; + output_row : JDIMENSION; + num_rows : int); + end; + +{ Downsampling } + jpeg_downsampler_ptr = ^jpeg_downsampler; + jpeg_downsampler = record + start_pass : procedure(cinfo : j_compress_ptr); + downsample : procedure(cinfo : j_compress_ptr; + input_buf : JSAMPIMAGE; + in_row_index : JDIMENSION; + output_buf : JSAMPIMAGE; + out_row_group_index: JDIMENSION); + need_context_rows : Boolean; { TRUE if need rows above & below } + end; + +{ Forward DCT (also controls coefficient quantization) } + jpeg_forward_dct_ptr = ^jpeg_forward_dct; + jpeg_forward_dct = record + start_pass : procedure(cinfo : j_compress_ptr); + { perhaps this should be an array??? } + forward_DCT : procedure(cinfo : j_compress_ptr; + compptr : jpeg_component_info_ptr; + sample_data : JSAMPARRAY; + coef_blocks : JBLOCKROW; + start_row : JDIMENSION; + start_col : JDIMENSION; + num_blocks : JDIMENSION); + end; + +{ Entropy encoding } + + jpeg_entropy_encoder_ptr = ^jpeg_entropy_encoder; + jpeg_entropy_encoder = record + start_pass : procedure(cinfo : j_compress_ptr; gather_statistics : boolean); + encode_mcu : function(cinfo : j_compress_ptr; + const MCU_data: array of JBLOCKROW) : boolean; + finish_pass : procedure(cinfo : j_compress_ptr); + end; + +{ Marker writing } + jpeg_marker_writer_ptr = ^jpeg_marker_writer; + jpeg_marker_writer = record + write_file_header : procedure(cinfo : j_compress_ptr); + write_frame_header : procedure(cinfo : j_compress_ptr); + write_scan_header : procedure(cinfo : j_compress_ptr); + write_file_trailer : procedure(cinfo : j_compress_ptr); + write_tables_only : procedure(cinfo : j_compress_ptr); + { These routines are exported to allow insertion of extra markers } + { Probably only COM and APPn markers should be written this way } + write_marker_header : procedure (cinfo : j_compress_ptr; + marker : int; + datalen : uint); + write_marker_byte : procedure (cinfo : j_compress_ptr; val : int); + end; + +{ Declarations for decompression modules } + +{ Master control module } + jpeg_decomp_master_ptr = ^jpeg_decomp_master; + jpeg_decomp_master = record + prepare_for_output_pass : procedure( cinfo : j_decompress_ptr); + finish_output_pass : procedure(cinfo : j_decompress_ptr); + + { State variables made visible to other modules } + is_dummy_pass : Boolean; { True during 1st pass for 2-pass quant } + end; + +{ Input control module } + jpeg_input_controller_ptr = ^jpeg_input_controller; + jpeg_input_controller = record + consume_input : function (cinfo : j_decompress_ptr) : int; + reset_input_controller : procedure(cinfo : j_decompress_ptr); + start_input_pass : procedure(cinfo : j_decompress_ptr); + finish_input_pass : procedure(cinfo : j_decompress_ptr); + + { State variables made visible to other modules } + has_multiple_scans : Boolean; { True if file has multiple scans } + eoi_reached : Boolean; { True when EOI has been consumed } + end; + +{ Main buffer control (downsampled-data buffer) } + + jpeg_d_main_controller_ptr = ^jpeg_d_main_controller; + jpeg_d_main_controller = record + start_pass : procedure(cinfo : j_decompress_ptr; pass_mode : J_BUF_MODE); + process_data : procedure(cinfo : j_decompress_ptr; + output_buf : JSAMPARRAY; + var out_row_ctr : JDIMENSION; + out_rows_avail : JDIMENSION); + end; + +{ Coefficient buffer control } + jvirt_barray_tbl = array[0..MAX_COMPONENTS-1] of jvirt_barray_ptr; + jvirt_barray_tbl_ptr = ^jvirt_barray_tbl; + jpeg_d_coef_controller_ptr = ^jpeg_d_coef_controller; + jpeg_d_coef_controller = record + start_input_pass : procedure(cinfo : j_decompress_ptr); + consume_data : function (cinfo : j_decompress_ptr) : int; + start_output_pass : procedure(cinfo : j_decompress_ptr); + decompress_data : function (cinfo : j_decompress_ptr; + output_buf : JSAMPIMAGE) : int; + { Pointer to array of coefficient virtual arrays, or NIL if none } + coef_arrays : jvirt_barray_tbl_ptr; + end; + +{ Decompression postprocessing (color quantization buffer control) } + jpeg_d_post_controller_ptr = ^jpeg_d_post_controller; + jpeg_d_post_controller = record + start_pass : procedure(cinfo : j_decompress_ptr; + pass_mode : J_BUF_MODE); + post_process_data : procedure(cinfo : j_decompress_ptr; + input_buf : JSAMPIMAGE; + var in_row_group_ctr : JDIMENSION; + in_row_groups_avail : JDIMENSION; + output_buf : JSAMPARRAY; + var out_row_ctr : JDIMENSION; + out_rows_avail : JDIMENSION); + end; + + +{ Routine signature for application-supplied marker processing methods. + Need not pass marker code since it is stored in cinfo^.unread_marker. } + + jpeg_marker_parser_method = function(cinfo : j_decompress_ptr) : boolean; + +{ Marker reading & parsing } + jpeg_marker_reader_ptr = ^jpeg_marker_reader; + jpeg_marker_reader = record + reset_marker_reader : procedure(cinfo : j_decompress_ptr); + { Read markers until SOS or EOI. + Returns same codes as are defined for jpeg_consume_input: + JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI. } + + read_markers : function (cinfo : j_decompress_ptr) : int; + { Read a restart marker --- exported for use by entropy decoder only } + read_restart_marker : jpeg_marker_parser_method; + + { State of marker reader --- nominally internal, but applications + supplying COM or APPn handlers might like to know the state. } + + saw_SOI : boolean; { found SOI? } + saw_SOF : boolean; { found SOF? } + next_restart_num : int; { next restart number expected (0-7) } + discarded_bytes : uint; { # of bytes skipped looking for a marker } + end; + +{ Entropy decoding } + jpeg_entropy_decoder_ptr = ^jpeg_entropy_decoder; + jpeg_entropy_decoder = record + start_pass : procedure(cinfo : j_decompress_ptr); + decode_mcu : function(cinfo : j_decompress_ptr; + var MCU_data : array of JBLOCKROW) : boolean; + { This is here to share code between baseline and progressive decoders; } + { other modules probably should not use it } + insufficient_data : BOOLEAN; { set TRUE after emitting warning } + end; + +{ Inverse DCT (also performs dequantization) } + inverse_DCT_method_ptr = procedure(cinfo : j_decompress_ptr; + compptr : jpeg_component_info_ptr; + coef_block : JCOEFPTR; + output_buf : JSAMPARRAY; output_col : JDIMENSION); + + jpeg_inverse_dct_ptr = ^jpeg_inverse_dct; + jpeg_inverse_dct = record + start_pass : procedure(cinfo : j_decompress_ptr); + { It is useful to allow each component to have a separate IDCT method. } + inverse_DCT : Array[0..MAX_COMPONENTS-1] of inverse_DCT_method_ptr; + end; + +{ Upsampling (note that upsampler must also call color converter) } + jpeg_upsampler_ptr = ^jpeg_upsampler; + jpeg_upsampler = record + start_pass : procedure(cinfo : j_decompress_ptr); + upsample : procedure(cinfo : j_decompress_ptr; + input_buf : JSAMPIMAGE; + var in_row_group_ctr : JDIMENSION; { array of } + in_row_groups_avail : JDIMENSION; + output_buf : JSAMPARRAY; + var out_row_ctr : JDIMENSION; + out_rows_avail : JDIMENSION); + + need_context_rows : boolean; { TRUE if need rows above & below } + end; + +{ Colorspace conversion } + jpeg_color_deconverter_ptr = ^jpeg_color_deconverter; + jpeg_color_deconverter = record + start_pass : procedure(cinfo: j_decompress_ptr); + color_convert : procedure(cinfo : j_decompress_ptr; + input_buf : JSAMPIMAGE; + input_row : JDIMENSION; + output_buf : JSAMPARRAY; + num_rows : int); + end; + +{ Color quantization or color precision reduction } + jpeg_color_quantizer_ptr = ^jpeg_color_quantizer; + jpeg_color_quantizer = record + start_pass : procedure(cinfo : j_decompress_ptr; is_pre_scan : boolean); + color_quantize : procedure(cinfo : j_decompress_ptr; + input_buf : JSAMPARRAY; + output_buf : JSAMPARRAY; + num_rows : int); + + finish_pass : procedure(cinfo : j_decompress_ptr); + new_color_map : procedure(cinfo : j_decompress_ptr); + end; + + {int8array = Array[0..8-1] of int;} + int8array = Array[0..8-1] of longint; { for TP FormatStr } + + jpeg_error_mgr = record + { Error exit handler: does not return to caller } + error_exit : procedure (cinfo : j_common_ptr); + { Conditionally emit a trace or warning message } + emit_message : procedure (cinfo : j_common_ptr; msg_level : int); + { Routine that actually outputs a trace or error message } + output_message : procedure (cinfo : j_common_ptr); + { Format a message string for the most recent JPEG error or message } + format_message : procedure (cinfo : j_common_ptr; var buffer : string); + + { Reset error state variables at start of a new image } + reset_error_mgr : procedure (cinfo : j_common_ptr); + + { The message ID code and any parameters are saved here. + A message can have one string parameter or up to 8 int parameters. } + + msg_code : int; + + msg_parm : record + case byte of + 0:(i : int8array); + 1:(s : string[JMSG_STR_PARM_MAX]); + end; + + { Standard state variables for error facility } + + trace_level : int; { max msg_level that will be displayed } + + { For recoverable corrupt-data errors, we emit a warning message, + but keep going unless emit_message chooses to abort. emit_message + should count warnings in num_warnings. The surrounding application + can check for bad data by seeing if num_warnings is nonzero at the + end of processing. } + + num_warnings : long; { number of corrupt-data warnings } + + { These fields point to the table(s) of error message strings. + An application can change the table pointer to switch to a different + message list (typically, to change the language in which errors are + reported). Some applications may wish to add additional error codes + that will be handled by the JPEG library error mechanism; the second + table pointer is used for this purpose. + + First table includes all errors generated by JPEG library itself. + Error code 0 is reserved for a "no such error string" message. } + + {const char * const * jpeg_message_table; } + jpeg_message_table : ^msg_table; { Library errors } + + last_jpeg_message : J_MESSAGE_CODE; + { Table contains strings 0..last_jpeg_message } + { Second table can be added by application (see cjpeg/djpeg for example). + It contains strings numbered first_addon_message..last_addon_message. } + + {const char * const * addon_message_table; } + addon_message_table : ^msg_table; { Non-library errors } + + first_addon_message : J_MESSAGE_CODE; { code for first string in addon table } + last_addon_message : J_MESSAGE_CODE; { code for last string in addon table } + end; + + +{ Progress monitor object } + + jpeg_progress_mgr = record + progress_monitor : procedure(cinfo : j_common_ptr); + + pass_counter : long; { work units completed in this pass } + pass_limit : long; { total number of work units in this pass } + completed_passes : int; { passes completed so far } + total_passes : int; { total number of passes expected } + end; + + +{ Data destination object for compression } + jpeg_destination_mgr_ptr = ^jpeg_destination_mgr; + jpeg_destination_mgr = record + next_output_byte : JOCTETptr; { => next byte to write in buffer } + free_in_buffer : size_t; { # of byte spaces remaining in buffer } + + init_destination : procedure (cinfo : j_compress_ptr); + empty_output_buffer : function (cinfo : j_compress_ptr) : boolean; + term_destination : procedure (cinfo : j_compress_ptr); + end; + + +{ Data source object for decompression } + + jpeg_source_mgr_ptr = ^jpeg_source_mgr; + jpeg_source_mgr = record + {const JOCTET * next_input_byte;} + next_input_byte : JOCTETptr; { => next byte to read from buffer } + bytes_in_buffer : size_t; { # of bytes remaining in buffer } + + init_source : procedure (cinfo : j_decompress_ptr); + fill_input_buffer : function (cinfo : j_decompress_ptr) : boolean; + skip_input_data : procedure (cinfo : j_decompress_ptr; num_bytes : long); + resync_to_restart : function (cinfo : j_decompress_ptr; + desired : int) : boolean; + term_source : procedure (cinfo : j_decompress_ptr); + end; + + +{ Memory manager object. + Allocates "small" objects (a few K total), "large" objects (tens of K), + and "really big" objects (virtual arrays with backing store if needed). + The memory manager does not allow individual objects to be freed; rather, + each created object is assigned to a pool, and whole pools can be freed + at once. This is faster and more convenient than remembering exactly what + to free, especially where malloc()/free() are not too speedy. + NB: alloc routines never return NIL. They exit to error_exit if not + successful. } + + + jpeg_memory_mgr = record + { Method pointers } + alloc_small : function (cinfo : j_common_ptr; pool_id : int; + sizeofobject : size_t) : pointer; + alloc_large : function (cinfo : j_common_ptr; pool_id : int; + sizeofobject : size_t) : pointer; {far} + alloc_sarray : function (cinfo : j_common_ptr; pool_id : int; + samplesperrow : JDIMENSION; + numrows : JDIMENSION) : JSAMPARRAY; + + alloc_barray : function (cinfo : j_common_ptr; pool_id : int; + blocksperrow : JDIMENSION; + numrows : JDIMENSION) : JBLOCKARRAY; + + request_virt_sarray : function(cinfo : j_common_ptr; + pool_id : int; + pre_zero : boolean; + samplesperrow : JDIMENSION; + numrows : JDIMENSION; + maxaccess : JDIMENSION) : jvirt_sarray_ptr; + + request_virt_barray : function(cinfo : j_common_ptr; + pool_id : int; + pre_zero : boolean; + blocksperrow : JDIMENSION; + numrows : JDIMENSION; + maxaccess : JDIMENSION) : jvirt_barray_ptr; + + realize_virt_arrays : procedure (cinfo : j_common_ptr); + + access_virt_sarray : function (cinfo : j_common_ptr; + ptr : jvirt_sarray_ptr; + start_row : JDIMENSION; + num_rows : JDIMENSION; + writable : boolean) : JSAMPARRAY; + + access_virt_barray : function (cinfo : j_common_ptr; + ptr : jvirt_barray_ptr; + start_row : JDIMENSION; + num_rows : JDIMENSION; + writable : boolean) : JBLOCKARRAY; + + free_pool : procedure (cinfo : j_common_ptr; pool_id : int); + self_destruct : procedure (cinfo : j_common_ptr); + + { Limit on memory allocation for this JPEG object. (Note that this is + merely advisory, not a guaranteed maximum; it only affects the space + used for virtual-array buffers.) May be changed by outer application + after creating the JPEG object. } + max_memory_to_use : long; + + { Maximum allocation request accepted by alloc_large. } + max_alloc_chunk : long; + end; + +{ Routines that are to be used by both halves of the library are declared + to receive a pointer to this structure. There are no actual instances of + jpeg_common_struct, only of jpeg_compress_struct and jpeg_decompress_struct.} + jpeg_common_struct = record + { Fields common to both master struct types } + err : jpeg_error_mgr_ptr; { Error handler module } + mem : jpeg_memory_mgr_ptr; { Memory manager module } + progress : jpeg_progress_mgr_ptr; { Progress monitor, or NIL if none } + client_data : voidp; { Available for use by application } + is_decompressor : boolean; { so common code can tell which is which } + global_state : int; { for checking call sequence validity } + + { Additional fields follow in an actual jpeg_compress_struct or + jpeg_decompress_struct. All three structs must agree on these + initial fields! (This would be a lot cleaner in C++.) } + end; + + +{ Master record for a compression instance } + + jpeg_compress_struct = record + { Fields shared with jpeg_decompress_struct } + err : jpeg_error_mgr_ptr; { Error handler module } + mem : jpeg_memory_mgr_ptr; { Memory manager module } + progress : jpeg_progress_mgr_ptr; { Progress monitor, or NIL if none } + client_data : voidp; { Available for use by application } + is_decompressor : boolean; { so common code can tell which is which } + global_state : int; { for checking call sequence validity } + + { Destination for compressed data } + dest : jpeg_destination_mgr_ptr; + + { Description of source image --- these fields must be filled in by + outer application before starting compression. in_color_space must + be correct before you can even call jpeg_set_defaults(). } + + + image_width : JDIMENSION; { input image width } + image_height : JDIMENSION; { input image height } + input_components : int; { # of color components in input image } + in_color_space : J_COLOR_SPACE; { colorspace of input image } + + input_gamma : double; { image gamma of input image } + + { Compression parameters --- these fields must be set before calling + jpeg_start_compress(). We recommend calling jpeg_set_defaults() to + initialize everything to reasonable defaults, then changing anything + the application specifically wants to change. That way you won't get + burnt when new parameters are added. Also note that there are several + helper routines to simplify changing parameters. } + + data_precision : int; { bits of precision in image data } + + num_components : int; { # of color components in JPEG image } + jpeg_color_space : J_COLOR_SPACE; { colorspace of JPEG image } + + comp_info : jpeg_component_info_list_ptr; + { comp_info^[i] describes component that appears i'th in SOF } + + quant_tbl_ptrs: Array[0..NUM_QUANT_TBLS-1] of JQUANT_TBL_PTR; + { ptrs to coefficient quantization tables, or NIL if not defined } + + dc_huff_tbl_ptrs : Array[0..NUM_HUFF_TBLS-1] of JHUFF_TBL_PTR; + ac_huff_tbl_ptrs : Array[0..NUM_HUFF_TBLS-1] of JHUFF_TBL_PTR; + { ptrs to Huffman coding tables, or NIL if not defined } + + arith_dc_L : Array[0..NUM_ARITH_TBLS-1] of UINT8; { L values for DC arith-coding tables } + arith_dc_U : Array[0..NUM_ARITH_TBLS-1] of UINT8; { U values for DC arith-coding tables } + arith_ac_K : Array[0..NUM_ARITH_TBLS-1] of UINT8; { Kx values for AC arith-coding tables } + + num_scans : int; { # of entries in scan_info array } + scan_info : jpeg_scan_info_ptr; { script for multi-scan file, or NIL } + { The default value of scan_info is NIL, which causes a single-scan + sequential JPEG file to be emitted. To create a multi-scan file, + set num_scans and scan_info to point to an array of scan definitions. } + + raw_data_in : boolean; { TRUE=caller supplies downsampled data } + arith_code : boolean; { TRUE=arithmetic coding, FALSE=Huffman } + optimize_coding : boolean; { TRUE=optimize entropy encoding parms } + CCIR601_sampling : boolean; { TRUE=first samples are cosited } + smoothing_factor : int; { 1..100, or 0 for no input smoothing } + dct_method : J_DCT_METHOD; { DCT algorithm selector } + + { The restart interval can be specified in absolute MCUs by setting + restart_interval, or in MCU rows by setting restart_in_rows + (in which case the correct restart_interval will be figured + for each scan). } + + restart_interval : uint; { MCUs per restart, or 0 for no restart } + restart_in_rows : int; { if > 0, MCU rows per restart interval } + + { Parameters controlling emission of special markers. } + + write_JFIF_header : boolean; { should a JFIF marker be written? } + JFIF_major_version : UINT8; { What to write for the JFIF version number } + JFIF_minor_version : UINT8; + { These three values are not used by the JPEG code, merely copied } + { into the JFIF APP0 marker. density_unit can be 0 for unknown, } + { 1 for dots/inch, or 2 for dots/cm. Note that the pixel aspect } + { ratio is defined by X_density/Y_density even when density_unit=0. } + density_unit : UINT8; { JFIF code for pixel size units } + X_density : UINT16; { Horizontal pixel density } + Y_density : UINT16; { Vertical pixel density } + write_Adobe_marker : boolean; { should an Adobe marker be written? } + + { State variable: index of next scanline to be written to + jpeg_write_scanlines(). Application may use this to control its + processing loop, e.g., "while (next_scanline < image_height)". } + + next_scanline : JDIMENSION; { 0 .. image_height-1 } + + { Remaining fields are known throughout compressor, but generally + should not be touched by a surrounding application. } + + { These fields are computed during compression startup } + progressive_mode : boolean; { TRUE if scan script uses progressive mode } + max_h_samp_factor : int; { largest h_samp_factor } + max_v_samp_factor : int; { largest v_samp_factor } + + total_iMCU_rows : JDIMENSION; { # of iMCU rows to be input to coef ctlr } + { The coefficient controller receives data in units of MCU rows as defined + for fully interleaved scans (whether the JPEG file is interleaved or not). + There are v_samp_factor * DCTSIZE sample rows of each component in an + "iMCU" (interleaved MCU) row. } + + { These fields are valid during any one scan. + They describe the components and MCUs actually appearing in the scan. } + + comps_in_scan : int; { # of JPEG components in this scan } + cur_comp_info : Array[0..MAX_COMPS_IN_SCAN-1] of jpeg_component_info_ptr; + { cur_comp_info[i]^ describes component that appears i'th in SOS } + + MCUs_per_row : JDIMENSION; { # of MCUs across the image } + MCU_rows_in_scan : JDIMENSION;{ # of MCU rows in the image } + + blocks_in_MCU : int; { # of DCT blocks per MCU } + MCU_membership : Array[0..C_MAX_BLOCKS_IN_MCU-1] of int; + { MCU_membership[i] is index in cur_comp_info of component owning } + { i'th block in an MCU } + + Ss, Se, Ah, Al : int; { progressive JPEG parameters for scan } + + { Links to compression subobjects (methods and private variables of modules) } + master : jpeg_comp_master_ptr; + main : jpeg_c_main_controller_ptr; + prep : jpeg_c_prep_controller_ptr; + coef : jpeg_c_coef_controller_ptr; + marker : jpeg_marker_writer_ptr; + cconvert : jpeg_color_converter_ptr; + downsample : jpeg_downsampler_ptr; + fdct : jpeg_forward_dct_ptr; + entropy : jpeg_entropy_encoder_ptr; + script_space : jpeg_scan_info_ptr; { workspace for jpeg_simple_progression } + script_space_size : int; + end; + + +{ Master record for a decompression instance } + + coef_bits_field = Array[0..DCTSIZE2-1] of int; + coef_bits_ptr = ^coef_bits_field; + coef_bits_ptrfield = Array[0..MAX_COMPS_IN_SCAN-1] of coef_bits_field; + coef_bits_ptrrow = ^coef_bits_ptrfield; + + range_limit_table = array[-(MAXJSAMPLE+1)..4*(MAXJSAMPLE+1) + + CENTERJSAMPLE -1] of JSAMPLE; + range_limit_table_ptr = ^range_limit_table; + + jpeg_decompress_struct = record + { Fields shared with jpeg_compress_struct } + err : jpeg_error_mgr_ptr; { Error handler module } + mem : jpeg_memory_mgr_ptr; { Memory manager module } + progress : jpeg_progress_mgr_ptr; { Progress monitor, or NIL if none } + client_data : voidp; { Available for use by application } + is_decompressor : boolean; { so common code can tell which is which } + global_state : int; { for checking call sequence validity } + + { Source of compressed data } + src : jpeg_source_mgr_ptr; + + { Basic description of image --- filled in by jpeg_read_header(). } + { Application may inspect these values to decide how to process image. } + + image_width : JDIMENSION; { nominal image width (from SOF marker) } + image_height : JDIMENSION; { nominal image height } + num_components : int; { # of color components in JPEG image } + jpeg_color_space : J_COLOR_SPACE; { colorspace of JPEG image } + + { Decompression processing parameters --- these fields must be set before + calling jpeg_start_decompress(). Note that jpeg_read_header() + initializes them to default values. } + + out_color_space : J_COLOR_SPACE; { colorspace for output } + + scale_num, scale_denom : uint ; { fraction by which to scale image } + + output_gamma : double; { image gamma wanted in output } + + buffered_image : boolean; { TRUE=multiple output passes } + raw_data_out : boolean; { TRUE=downsampled data wanted } + + dct_method : J_DCT_METHOD; { IDCT algorithm selector } + do_fancy_upsampling : boolean; { TRUE=apply fancy upsampling } + do_block_smoothing : boolean; { TRUE=apply interblock smoothing } + + quantize_colors : boolean; { TRUE=colormapped output wanted } + { the following are ignored if not quantize_colors: } + dither_mode : J_DITHER_MODE; { type of color dithering to use } + two_pass_quantize : boolean; { TRUE=use two-pass color quantization } + desired_number_of_colors : int; { max # colors to use in created colormap } + { these are significant only in buffered-image mode: } + enable_1pass_quant : boolean; { enable future use of 1-pass quantizer } + enable_external_quant : boolean; { enable future use of external colormap } + enable_2pass_quant : boolean; { enable future use of 2-pass quantizer } + + { Description of actual output image that will be returned to application. + These fields are computed by jpeg_start_decompress(). + You can also use jpeg_calc_output_dimensions() to determine these values + in advance of calling jpeg_start_decompress(). } + + output_width : JDIMENSION; { scaled image width } + output_height: JDIMENSION; { scaled image height } + out_color_components : int; { # of color components in out_color_space } + output_components : int; { # of color components returned } + { output_components is 1 (a colormap index) when quantizing colors; + otherwise it equals out_color_components. } + + rec_outbuf_height : int; { min recommended height of scanline buffer } + { If the buffer passed to jpeg_read_scanlines() is less than this many + rows high, space and time will be wasted due to unnecessary data + copying. Usually rec_outbuf_height will be 1 or 2, at most 4. } + + { When quantizing colors, the output colormap is described by these + fields. The application can supply a colormap by setting colormap + non-NIL before calling jpeg_start_decompress; otherwise a colormap + is created during jpeg_start_decompress or jpeg_start_output. The map + has out_color_components rows and actual_number_of_colors columns. } + + actual_number_of_colors : int; { number of entries in use } + colormap : JSAMPARRAY; { The color map as a 2-D pixel array } + + { State variables: these variables indicate the progress of decompression. + The application may examine these but must not modify them. } + + { Row index of next scanline to be read from jpeg_read_scanlines(). + Application may use this to control its processing loop, e.g., + "while (output_scanline < output_height)". } + + output_scanline : JDIMENSION; { 0 .. output_height-1 } + + { Current input scan number and number of iMCU rows completed in scan. + These indicate the progress of the decompressor input side. } + + input_scan_number : int; { Number of SOS markers seen so far } + input_iMCU_row : JDIMENSION; { Number of iMCU rows completed } + + { The "output scan number" is the notional scan being displayed by the + output side. The decompressor will not allow output scan/row number + to get ahead of input scan/row, but it can fall arbitrarily far behind.} + + output_scan_number : int; { Nominal scan number being displayed } + output_iMCU_row : int; { Number of iMCU rows read } + + { Current progression status. coef_bits[c][i] indicates the precision + with which component c's DCT coefficient i (in zigzag order) is known. + It is -1 when no data has yet been received, otherwise it is the point + transform (shift) value for the most recent scan of the coefficient + (thus, 0 at completion of the progression). + This pointer is NIL when reading a non-progressive file. } + + coef_bits : coef_bits_ptrrow; + { -1 or current Al value for each coef } + + { Internal JPEG parameters --- the application usually need not look at + these fields. Note that the decompressor output side may not use + any parameters that can change between scans. } + + { Quantization and Huffman tables are carried forward across input + datastreams when processing abbreviated JPEG datastreams. } + + quant_tbl_ptrs : Array[0..NUM_QUANT_TBLS-1] of JQUANT_TBL_PTR; + { ptrs to coefficient quantization tables, or NIL if not defined } + + dc_huff_tbl_ptrs : Array[0..NUM_HUFF_TBLS-1] of JHUFF_TBL_PTR; + ac_huff_tbl_ptrs : Array[0..NUM_HUFF_TBLS-1] of JHUFF_TBL_PTR; + { ptrs to Huffman coding tables, or NIL if not defined } + + { These parameters are never carried across datastreams, since they + are given in SOF/SOS markers or defined to be reset by SOI. } + + data_precision : int; { bits of precision in image data } + + comp_info : jpeg_component_info_list_ptr; + { comp_info^[i] describes component that appears i'th in SOF } + + progressive_mode : boolean; { TRUE if SOFn specifies progressive mode } + arith_code : boolean; { TRUE=arithmetic coding, FALSE=Huffman } + + arith_dc_L : Array[0..NUM_ARITH_TBLS-1] of UINT8; { L values for DC arith-coding tables } + arith_dc_U : Array[0..NUM_ARITH_TBLS-1] of UINT8; { U values for DC arith-coding tables } + arith_ac_K : Array[0..NUM_ARITH_TBLS-1] of UINT8; { Kx values for AC arith-coding tables } + + restart_interval : uint; { MCUs per restart interval, or 0 for no restart } + + { These fields record data obtained from optional markers recognized by + the JPEG library. } + + saw_JFIF_marker : boolean; { TRUE iff a JFIF APP0 marker was found } + { Data copied from JFIF marker; only valid if saw_JFIF_marker is TRUE: } + JFIF_major_version : UINT8; { JFIF version number } + JFIF_minor_version : UINT8; + density_unit : UINT8; { JFIF code for pixel size units } + X_density : UINT16; { Horizontal pixel density } + Y_density : UINT16; { Vertical pixel density } + saw_Adobe_marker : boolean; { TRUE iff an Adobe APP14 marker was found } + Adobe_transform : UINT8; { Color transform code from Adobe marker } + + CCIR601_sampling : boolean; { TRUE=first samples are cosited } + + { Aside from the specific data retained from APPn markers known to the + library, the uninterpreted contents of any or all APPn and COM markers + can be saved in a list for examination by the application. } + + marker_list : jpeg_saved_marker_ptr; { Head of list of saved markers } + + { Remaining fields are known throughout decompressor, but generally + should not be touched by a surrounding application. } + + + { These fields are computed during decompression startup } + + max_h_samp_factor : int; { largest h_samp_factor } + max_v_samp_factor : int; { largest v_samp_factor } + + min_DCT_scaled_size : int; { smallest DCT_scaled_size of any component } + + total_iMCU_rows : JDIMENSION; { # of iMCU rows in image } + { The coefficient controller's input and output progress is measured in + units of "iMCU" (interleaved MCU) rows. These are the same as MCU rows + in fully interleaved JPEG scans, but are used whether the scan is + interleaved or not. We define an iMCU row as v_samp_factor DCT block + rows of each component. Therefore, the IDCT output contains + v_samp_factor*DCT_scaled_size sample rows of a component per iMCU row.} + + sample_range_limit : range_limit_table_ptr; { table for fast range-limiting } + + + { These fields are valid during any one scan. + They describe the components and MCUs actually appearing in the scan. + Note that the decompressor output side must not use these fields. } + + comps_in_scan : int; { # of JPEG components in this scan } + cur_comp_info : Array[0..MAX_COMPS_IN_SCAN-1] of jpeg_component_info_ptr; + { cur_comp_info[i]^ describes component that appears i'th in SOS } + + MCUs_per_row : JDIMENSION; { # of MCUs across the image } + MCU_rows_in_scan : JDIMENSION; { # of MCU rows in the image } + + blocks_in_MCU : JDIMENSION; { # of DCT blocks per MCU } + MCU_membership : Array[0..D_MAX_BLOCKS_IN_MCU-1] of int; + { MCU_membership[i] is index in cur_comp_info of component owning } + { i'th block in an MCU } + + Ss, Se, Ah, Al : int; { progressive JPEG parameters for scan } + + { This field is shared between entropy decoder and marker parser. + It is either zero or the code of a JPEG marker that has been + read from the data source, but has not yet been processed. } + + unread_marker : int; + + { Links to decompression subobjects + (methods, private variables of modules) } + + master : jpeg_decomp_master_ptr; + main : jpeg_d_main_controller_ptr; + coef : jpeg_d_coef_controller_ptr; + post : jpeg_d_post_controller_ptr; + inputctl : jpeg_input_controller_ptr; + marker : jpeg_marker_reader_ptr; + entropy : jpeg_entropy_decoder_ptr; + idct : jpeg_inverse_dct_ptr; + upsample : jpeg_upsampler_ptr; + cconvert : jpeg_color_deconverter_ptr; + cquantize : jpeg_color_quantizer_ptr; + end; + +{ Decompression startup: read start of JPEG datastream to see what's there + function jpeg_read_header (cinfo : j_decompress_ptr; + require_image : boolean) : int; + Return value is one of: } +const + JPEG_SUSPENDED = 0; { Suspended due to lack of input data } + JPEG_HEADER_OK = 1; { Found valid image datastream } + JPEG_HEADER_TABLES_ONLY = 2; { Found valid table-specs-only datastream } +{ If you pass require_image = TRUE (normal case), you need not check for + a TABLES_ONLY return code; an abbreviated file will cause an error exit. + JPEG_SUSPENDED is only possible if you use a data source module that can + give a suspension return (the stdio source module doesn't). } + + +{ function jpeg_consume_input (cinfo : j_decompress_ptr) : int; + Return value is one of: } + + JPEG_REACHED_SOS = 1; { Reached start of new scan } + JPEG_REACHED_EOI = 2; { Reached end of image } + JPEG_ROW_COMPLETED = 3; { Completed one iMCU row } + JPEG_SCAN_COMPLETED = 4; { Completed last iMCU row of a scan } + + + + +implementation + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jquant1_del.pas b/mseide-msegui/lib/common/fpccompatibility/jquant1_del.pas new file mode 100644 index 0000000..bd5db7f --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jquant1_del.pas @@ -0,0 +1,1011 @@ +unit jquant1_del; + +{ This file contains 1-pass color quantization (color mapping) routines. + These routines provide mapping to a fixed color map using equally spaced + color values. Optional Floyd-Steinberg or ordered dithering is available. } + +{ Original: jquant1.c; Copyright (C) 1991-1996, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jpeglib_del; + + +{GLOBAL} +procedure jinit_1pass_quantizer (cinfo : j_decompress_ptr); + +implementation + +uses + jmorecfg_del, + jdeferr_del, + jerror_del, + jutils_del; + +{ The main purpose of 1-pass quantization is to provide a fast, if not very + high quality, colormapped output capability. A 2-pass quantizer usually + gives better visual quality; however, for quantized grayscale output this + quantizer is perfectly adequate. Dithering is highly recommended with this + quantizer, though you can turn it off if you really want to. + + In 1-pass quantization the colormap must be chosen in advance of seeing the + image. We use a map consisting of all combinations of Ncolors[i] color + values for the i'th component. The Ncolors[] values are chosen so that + their product, the total number of colors, is no more than that requested. + (In most cases, the product will be somewhat less.) + + Since the colormap is orthogonal, the representative value for each color + component can be determined without considering the other components; + then these indexes can be combined into a colormap index by a standard + N-dimensional-array-subscript calculation. Most of the arithmetic involved + can be precalculated and stored in the lookup table colorindex[]. + colorindex[i][j] maps pixel value j in component i to the nearest + representative value (grid plane) for that component; this index is + multiplied by the array stride for component i, so that the + index of the colormap entry closest to a given pixel value is just + sum( colorindex[component-number][pixel-component-value] ) + Aside from being fast, this scheme allows for variable spacing between + representative values with no additional lookup cost. + + If gamma correction has been applied in color conversion, it might be wise + to adjust the color grid spacing so that the representative colors are + equidistant in linear space. At this writing, gamma correction is not + implemented by jdcolor, so nothing is done here. } + + +{ Declarations for ordered dithering. + + We use a standard 16x16 ordered dither array. The basic concept of ordered + dithering is described in many references, for instance Dale Schumacher's + chapter II.2 of Graphics Gems II (James Arvo, ed. Academic Press, 1991). + In place of Schumacher's comparisons against a "threshold" value, we add a + "dither" value to the input pixel and then round the result to the nearest + output value. The dither value is equivalent to (0.5 - threshold) times + the distance between output values. For ordered dithering, we assume that + the output colors are equally spaced; if not, results will probably be + worse, since the dither may be too much or too little at a given point. + + The normal calculation would be to form pixel value + dither, range-limit + this to 0..MAXJSAMPLE, and then index into the colorindex table as usual. + We can skip the separate range-limiting step by extending the colorindex + table in both directions. } + + +const + ODITHER_SIZE = 16; { dimension of dither matrix } +{ NB: if ODITHER_SIZE is not a power of 2, ODITHER_MASK uses will break } + ODITHER_CELLS = (ODITHER_SIZE*ODITHER_SIZE); { # cells in matrix } + ODITHER_MASK = (ODITHER_SIZE-1); { mask for wrapping around counters } + +type + ODITHER_vector = Array[0..ODITHER_SIZE-1] of int; + ODITHER_MATRIX = Array[0..ODITHER_SIZE-1] of ODITHER_vector; + {ODITHER_MATRIX_PTR = ^array[0..ODITHER_SIZE-1] of int;} + ODITHER_MATRIX_PTR = ^ODITHER_MATRIX; + +const + base_dither_matrix : Array[0..ODITHER_SIZE-1,0..ODITHER_SIZE-1] of UINT8 + = ( + { Bayer's order-4 dither array. Generated by the code given in + Stephen Hawley's article "Ordered Dithering" in Graphics Gems I. + The values in this array must range from 0 to ODITHER_CELLS-1. } + + ( 0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255 ), + ( 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 ), + ( 32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 ), + ( 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 ), + ( 8,200, 56,248, 4,196, 52,244, 11,203, 59,251, 7,199, 55,247 ), + ( 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 ), + ( 40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 ), + ( 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 ), + ( 2,194, 50,242, 14,206, 62,254, 1,193, 49,241, 13,205, 61,253 ), + ( 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 ), + ( 34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 ), + ( 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 ), + ( 10,202, 58,250, 6,198, 54,246, 9,201, 57,249, 5,197, 53,245 ), + ( 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 ), + ( 42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 ), + ( 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 ) + ); + + +{ Declarations for Floyd-Steinberg dithering. + + Errors are accumulated into the array fserrors[], at a resolution of + 1/16th of a pixel count. The error at a given pixel is propagated + to its not-yet-processed neighbors using the standard F-S fractions, + ... (here) 7/16 + 3/16 5/16 1/16 + We work left-to-right on even rows, right-to-left on odd rows. + + We can get away with a single array (holding one row's worth of errors) + by using it to store the current row's errors at pixel columns not yet + processed, but the next row's errors at columns already processed. We + need only a few extra variables to hold the errors immediately around the + current column. (If we are lucky, those variables are in registers, but + even if not, they're probably cheaper to access than array elements are.) + + The fserrors[] array is indexed [component#][position]. + We provide (#columns + 2) entries per component; the extra entry at each + end saves us from special-casing the first and last pixels. + + Note: on a wide image, we might not have enough room in a PC's near data + segment to hold the error array; so it is allocated with alloc_large. } + +{$ifdef BITS_IN_JSAMPLE_IS_8} +type + FSERROR = INT16; { 16 bits should be enough } + LOCFSERROR = int; { use 'int' for calculation temps } +{$else} +type + FSERROR = INT32; { may need more than 16 bits } + LOCFSERROR = INT32; { be sure calculation temps are big enough } +{$endif} + +type + jFSError = 0..(MaxInt div SIZEOF(FSERROR))-1; + FS_ERROR_FIELD = array[jFSError] of FSERROR; + FS_ERROR_FIELD_PTR = ^FS_ERROR_FIELD;{far} + { pointer to error array (in FAR storage!) } + FSERRORPTR = ^FSERROR; + + +{ Private subobject } + +const + MAX_Q_COMPS = 4; { max components I can handle } + +type + my_cquantize_ptr = ^my_cquantizer; + my_cquantizer = record + pub : jpeg_color_quantizer; { public fields } + + { Initially allocated colormap is saved here } + sv_colormap : JSAMPARRAY; { The color map as a 2-D pixel array } + sv_actual : int; { number of entries in use } + + colorindex : JSAMPARRAY; { Precomputed mapping for speed } + { colorindex[i][j] = index of color closest to pixel value j in component i, + premultiplied as described above. Since colormap indexes must fit into + JSAMPLEs, the entries of this array will too. } + + is_padded : boolean; { is the colorindex padded for odither? } + + Ncolors : array[0..MAX_Q_COMPS-1] of int; + { # of values alloced to each component } + + { Variables for ordered dithering } + row_index : int; { cur row's vertical index in dither matrix } + odither : array[0..MAX_Q_COMPS-1] of ODITHER_MATRIX_PTR; + { one dither array per component } + { Variables for Floyd-Steinberg dithering } + fserrors : array[0..MAX_Q_COMPS-1] of FS_ERROR_FIELD_PTR; + { accumulated errors } + on_odd_row : boolean; { flag to remember which row we are on } + end; + + +{ Policy-making subroutines for create_colormap and create_colorindex. + These routines determine the colormap to be used. The rest of the module + only assumes that the colormap is orthogonal. + + * select_ncolors decides how to divvy up the available colors + among the components. + * output_value defines the set of representative values for a component. + * largest_input_value defines the mapping from input values to + representative values for a component. + Note that the latter two routines may impose different policies for + different components, though this is not currently done. } + + + +{LOCAL} +function select_ncolors (cinfo : j_decompress_ptr; + var Ncolors : array of int) : int; +{ Determine allocation of desired colors to components, } +{ and fill in Ncolors[] array to indicate choice. } +{ Return value is total number of colors (product of Ncolors[] values). } +var + nc : int; + max_colors : int; + total_colors, iroot, i, j : int; + changed : boolean; + temp : long; +const + RGB_order:array[0..2] of int = (RGB_GREEN, RGB_RED, RGB_BLUE); +begin + nc := cinfo^.out_color_components; { number of color components } + max_colors := cinfo^.desired_number_of_colors; + + { We can allocate at least the nc'th root of max_colors per component. } + { Compute floor(nc'th root of max_colors). } + iroot := 1; + repeat + Inc(iroot); + temp := iroot; { set temp = iroot ** nc } + for i := 1 to pred(nc) do + temp := temp * iroot; + until (temp > long(max_colors)); { repeat till iroot exceeds root } + Dec(iroot); { now iroot = floor(root) } + + { Must have at least 2 color values per component } + if (iroot < 2) then + ERREXIT1(j_common_ptr(cinfo), JERR_QUANT_FEW_COLORS, int(temp)); + + { Initialize to iroot color values for each component } + total_colors := 1; + for i := 0 to pred(nc) do + begin + Ncolors[i] := iroot; + total_colors := total_colors * iroot; + end; + + { We may be able to increment the count for one or more components without + exceeding max_colors, though we know not all can be incremented. + Sometimes, the first component can be incremented more than once! + (Example: for 16 colors, we start at 2*2*2, go to 3*2*2, then 4*2*2.) + In RGB colorspace, try to increment G first, then R, then B. } + + repeat + changed := FALSE; + for i := 0 to pred(nc) do + begin + if cinfo^.out_color_space = JCS_RGB then + j := RGB_order[i] + else + j := i; + { calculate new total_colors if Ncolors[j] is incremented } + temp := total_colors div Ncolors[j]; + temp := temp * (Ncolors[j]+1); { done in long arith to avoid oflo } + if (temp > long(max_colors)) then + break; { won't fit, done with this pass } + Inc(Ncolors[j]); { OK, apply the increment } + total_colors := int(temp); + changed := TRUE; + end; + until not changed; + + select_ncolors := total_colors; +end; + + +{LOCAL} +function output_value (cinfo : j_decompress_ptr; + ci : int; j : int; maxj : int) : int; +{ Return j'th output value, where j will range from 0 to maxj } +{ The output values must fall in 0..MAXJSAMPLE in increasing order } +begin + { We always provide values 0 and MAXJSAMPLE for each component; + any additional values are equally spaced between these limits. + (Forcing the upper and lower values to the limits ensures that + dithering can't produce a color outside the selected gamut.) } + + output_value := int (( INT32(j) * MAXJSAMPLE + maxj div 2) div maxj); +end; + + +{LOCAL} +function largest_input_value (cinfo : j_decompress_ptr; + ci : int; j : int; maxj : int) : int; +{ Return largest input value that should map to j'th output value } +{ Must have largest(j=0) >= 0, and largest(j=maxj) >= MAXJSAMPLE } +begin + { Breakpoints are halfway between values returned by output_value } + largest_input_value := int (( INT32(2*j + 1) * MAXJSAMPLE + + maxj) div (2*maxj)); +end; + + +{ Create the colormap. } + +{LOCAL} +procedure create_colormap (cinfo : j_decompress_ptr); +var + cquantize : my_cquantize_ptr; + colormap : JSAMPARRAY; { Created colormap } + + total_colors : int; { Number of distinct output colors } + i,j,k, nci, blksize, blkdist, ptr, val : int; +begin + cquantize := my_cquantize_ptr (cinfo^.cquantize); + + { Select number of colors for each component } + total_colors := select_ncolors(cinfo, cquantize^.Ncolors); + + { Report selected color counts } + {$IFDEF DEBUG} + if (cinfo^.out_color_components = 3) then + TRACEMS4(j_common_ptr(cinfo), 1, JTRC_QUANT_3_NCOLORS, + total_colors, cquantize^.Ncolors[0], + cquantize^.Ncolors[1], cquantize^.Ncolors[2]) + else + TRACEMS1(j_common_ptr(cinfo), 1, JTRC_QUANT_NCOLORS, total_colors); + {$ENDIF} + + { Allocate and fill in the colormap. } + { The colors are ordered in the map in standard row-major order, } + { i.e. rightmost (highest-indexed) color changes most rapidly. } + + colormap := cinfo^.mem^.alloc_sarray( + j_common_ptr(cinfo), JPOOL_IMAGE, + JDIMENSION(total_colors), JDIMENSION(cinfo^.out_color_components)); + + { blksize is number of adjacent repeated entries for a component } + { blkdist is distance between groups of identical entries for a component } + blkdist := total_colors; + + for i := 0 to pred(cinfo^.out_color_components) do + begin + { fill in colormap entries for i'th color component } + nci := cquantize^.Ncolors[i]; { # of distinct values for this color } + blksize := blkdist div nci; + for j := 0 to pred(nci) do + begin + { Compute j'th output value (out of nci) for component } + val := output_value(cinfo, i, j, nci-1); + { Fill in all colormap entries that have this value of this component } + ptr := j * blksize; + while (ptr < total_colors) do + begin + { fill in blksize entries beginning at ptr } + for k := 0 to pred(blksize) do + colormap^[i]^[ptr+k] := JSAMPLE(val); + + Inc(ptr, blkdist); + end; + end; + blkdist := blksize; { blksize of this color is blkdist of next } + end; + + { Save the colormap in private storage, + where it will survive color quantization mode changes. } + + cquantize^.sv_colormap := colormap; + cquantize^.sv_actual := total_colors; +end; + +{ Create the color index table. } + +{LOCAL} +procedure create_colorindex (cinfo : j_decompress_ptr); +var + cquantize : my_cquantize_ptr; + indexptr, + help_indexptr : JSAMPROW; { for negative offsets } + i,j,k, nci, blksize, val, pad : int; +begin + cquantize := my_cquantize_ptr (cinfo^.cquantize); + { For ordered dither, we pad the color index tables by MAXJSAMPLE in + each direction (input index values can be -MAXJSAMPLE .. 2*MAXJSAMPLE). + This is not necessary in the other dithering modes. However, we + flag whether it was done in case user changes dithering mode. } + + if (cinfo^.dither_mode = JDITHER_ORDERED) then + begin + pad := MAXJSAMPLE*2; + cquantize^.is_padded := TRUE; + end + else + begin + pad := 0; + cquantize^.is_padded := FALSE; + end; + + cquantize^.colorindex := cinfo^.mem^.alloc_sarray + (j_common_ptr(cinfo), JPOOL_IMAGE, + JDIMENSION(MAXJSAMPLE+1 + pad), + JDIMENSION(cinfo^.out_color_components)); + + { blksize is number of adjacent repeated entries for a component } + blksize := cquantize^.sv_actual; + + for i := 0 to pred(cinfo^.out_color_components) do + begin + { fill in colorindex entries for i'th color component } + nci := cquantize^.Ncolors[i]; { # of distinct values for this color } + blksize := blksize div nci; + + { adjust colorindex pointers to provide padding at negative indexes. } + if (pad <> 0) then + Inc(JSAMPLE_PTR(cquantize^.colorindex^[i]), MAXJSAMPLE); + + { in loop, val = index of current output value, } + { and k = largest j that maps to current val } + indexptr := cquantize^.colorindex^[i]; + val := 0; + k := largest_input_value(cinfo, i, 0, nci-1); + for j := 0 to MAXJSAMPLE do + begin + while (j > k) do { advance val if past boundary } + begin + Inc(val); + k := largest_input_value(cinfo, i, val, nci-1); + end; + { premultiply so that no multiplication needed in main processing } + indexptr^[j] := JSAMPLE (val * blksize); + end; + { Pad at both ends if necessary } + if (pad <> 0) then + begin + help_indexptr := indexptr; + { adjust the help pointer to avoid negative offsets } + Dec(JSAMPLE_PTR(help_indexptr), MAXJSAMPLE); + + for j := 1 to MAXJSAMPLE do + begin + {indexptr^[-j] := indexptr^[0];} + help_indexptr^[MAXJSAMPLE-j] := indexptr^[0]; + indexptr^[MAXJSAMPLE+j] := indexptr^[MAXJSAMPLE]; + end; + end; + end; +end; + + +{ Create an ordered-dither array for a component having ncolors + distinct output values. } + +{LOCAL} +function make_odither_array (cinfo : j_decompress_ptr; + ncolors : int) : ODITHER_MATRIX_PTR; +var + odither : ODITHER_MATRIX_PTR; + j, k : int; + num, den : INT32; +begin + odither := ODITHER_MATRIX_PTR ( + cinfo^.mem^.alloc_small(j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(ODITHER_MATRIX))); + { The inter-value distance for this color is MAXJSAMPLE/(ncolors-1). + Hence the dither value for the matrix cell with fill order f + (f=0..N-1) should be (N-1-2*f)/(2*N) * MAXJSAMPLE/(ncolors-1). + On 16-bit-int machine, be careful to avoid overflow. } + + den := 2 * ODITHER_CELLS * ( INT32(ncolors - 1)); + for j := 0 to pred(ODITHER_SIZE) do + begin + for k := 0 to pred(ODITHER_SIZE) do + begin + num := ( INT32(ODITHER_CELLS-1 - 2*( int(base_dither_matrix[j][k])))) + * MAXJSAMPLE; + { Ensure round towards zero despite C's lack of consistency + about rounding negative values in integer division... } + + if num<0 then + odither^[j][k] := int (-((-num) div den)) + else + odither^[j][k] := int (num div den); + end; + end; + make_odither_array := odither; +end; + + +{ Create the ordered-dither tables. + Components having the same number of representative colors may + share a dither table. } + +{LOCAL} +procedure create_odither_tables (cinfo : j_decompress_ptr); +var + cquantize : my_cquantize_ptr; + odither : ODITHER_MATRIX_PTR; + i, j, nci : int; +begin + cquantize := my_cquantize_ptr (cinfo^.cquantize); + + for i := 0 to pred(cinfo^.out_color_components) do + begin + nci := cquantize^.Ncolors[i]; { # of distinct values for this color } + odither := NIL; { search for matching prior component } + for j := 0 to pred(i) do + begin + if (nci = cquantize^.Ncolors[j]) then + begin + odither := cquantize^.odither[j]; + break; + end; + end; + if (odither = NIL) then { need a new table? } + odither := make_odither_array(cinfo, nci); + cquantize^.odither[i] := odither; + end; +end; + + +{ Map some rows of pixels to the output colormapped representation. } + +{METHODDEF} +procedure color_quantize (cinfo : j_decompress_ptr; + input_buf : JSAMPARRAY; + output_buf : JSAMPARRAY; + num_rows : int); +{ General case, no dithering } +var + cquantize : my_cquantize_ptr; + colorindex : JSAMPARRAY; + pixcode, ci : int; {register} + ptrin, ptrout : JSAMPLE_PTR; {register} + row : int; + col : JDIMENSION; + width : JDIMENSION; + nc : int; {register} +begin + cquantize := my_cquantize_ptr (cinfo^.cquantize); + colorindex := cquantize^.colorindex; + width := cinfo^.output_width; + nc := cinfo^.out_color_components; + + for row := 0 to pred(num_rows) do + begin + ptrin := JSAMPLE_PTR(input_buf^[row]); + ptrout := JSAMPLE_PTR(output_buf^[row]); + for col := pred(width) downto 0 do + begin + pixcode := 0; + for ci := 0 to pred(nc) do + begin + Inc(pixcode, GETJSAMPLE(colorindex^[ci]^[GETJSAMPLE(ptrin^)]) ); + Inc(ptrin); + end; + ptrout^ := JSAMPLE (pixcode); + Inc(ptrout); + end; + end; +end; + + +{METHODDEF} +procedure color_quantize3 (cinfo : j_decompress_ptr; + input_buf : JSAMPARRAY; + output_buf : JSAMPARRAY; + num_rows : int); +{ Fast path for out_color_components=3, no dithering } +var + cquantize : my_cquantize_ptr; + pixcode : int; {register} + ptrin, ptrout : JSAMPLE_PTR; {register} + colorindex0 : JSAMPROW; + colorindex1 : JSAMPROW; + colorindex2 : JSAMPROW; + row : int; + col : JDIMENSION; + width : JDIMENSION; +begin + cquantize := my_cquantize_ptr (cinfo^.cquantize); + colorindex0 := (cquantize^.colorindex)^[0]; + colorindex1 := (cquantize^.colorindex)^[1]; + colorindex2 := (cquantize^.colorindex)^[2]; + width := cinfo^.output_width; + + for row := 0 to pred(num_rows) do + begin + ptrin := JSAMPLE_PTR(input_buf^[row]); + ptrout := JSAMPLE_PTR(output_buf^[row]); + for col := pred(width) downto 0 do + begin + pixcode := GETJSAMPLE((colorindex0)^[GETJSAMPLE(ptrin^)]); + Inc(ptrin); + Inc( pixcode, GETJSAMPLE((colorindex1)^[GETJSAMPLE(ptrin^)]) ); + Inc(ptrin); + Inc( pixcode, GETJSAMPLE((colorindex2)^[GETJSAMPLE(ptrin^)]) ); + Inc(ptrin); + ptrout^ := JSAMPLE (pixcode); + Inc(ptrout); + end; + end; +end; + + +{METHODDEF} +procedure quantize_ord_dither (cinfo : j_decompress_ptr; + input_buf : JSAMPARRAY; + output_buf : JSAMPARRAY; + num_rows : int); +{ General case, with ordered dithering } +var + cquantize : my_cquantize_ptr; + input_ptr, {register} + output_ptr : JSAMPLE_PTR; {register} + colorindex_ci : JSAMPROW; + dither : ^ODITHER_vector; { points to active row of dither matrix } + row_index, col_index : int; { current indexes into dither matrix } + nc : int; + ci : int; + row : int; + col : JDIMENSION; + width : JDIMENSION; +var + pad_offset : int; +begin + cquantize := my_cquantize_ptr (cinfo^.cquantize); + nc := cinfo^.out_color_components; + width := cinfo^.output_width; + + { Nomssi: work around negative offset } + if my_cquantize_ptr (cinfo^.cquantize)^.is_padded then + pad_offset := MAXJSAMPLE + else + pad_offset := 0; + + for row := 0 to pred(num_rows) do + begin + { Initialize output values to 0 so can process components separately } + jzero_far( {far} pointer(output_buf^[row]), + size_t(width * SIZEOF(JSAMPLE))); + row_index := cquantize^.row_index; + for ci := 0 to pred(nc) do + begin + input_ptr := JSAMPLE_PTR(@ input_buf^[row]^[ci]); + output_ptr := JSAMPLE_PTR(output_buf^[row]); + colorindex_ci := cquantize^.colorindex^[ci]; + { Nomssi } + Dec(JSAMPLE_PTR(colorindex_ci), pad_offset); + + dither := @(cquantize^.odither[ci]^[row_index]); + col_index := 0; + + for col := pred(width) downto 0 do + begin + { Form pixel value + dither, range-limit to 0..MAXJSAMPLE, + select output value, accumulate into output code for this pixel. + Range-limiting need not be done explicitly, as we have extended + the colorindex table to produce the right answers for out-of-range + inputs. The maximum dither is +- MAXJSAMPLE; this sets the + required amount of padding. } + + Inc(output_ptr^, + colorindex_ci^[GETJSAMPLE(input_ptr^)+ pad_offset + + dither^[col_index]]); + Inc(output_ptr); + Inc(input_ptr, nc); + col_index := (col_index + 1) and ODITHER_MASK; + end; + end; + { Advance row index for next row } + row_index := (row_index + 1) and ODITHER_MASK; + cquantize^.row_index := row_index; + end; +end; + +{METHODDEF} +procedure quantize3_ord_dither (cinfo : j_decompress_ptr; + input_buf : JSAMPARRAY; + output_buf : JSAMPARRAY; + num_rows : int); +{ Fast path for out_color_components=3, with ordered dithering } +var + cquantize : my_cquantize_ptr; + pixcode : int; {register} + input_ptr : JSAMPLE_PTR; {register} + output_ptr : JSAMPLE_PTR; {register} + colorindex0 : JSAMPROW; + colorindex1 : JSAMPROW; + colorindex2 : JSAMPROW; + dither0 : ^ODITHER_vector; { points to active row of dither matrix } + dither1 : ^ODITHER_vector; + dither2 : ^ODITHER_vector; + row_index, col_index : int; { current indexes into dither matrix } + row : int; + col : JDIMENSION; + width : JDIMENSION; +var + pad_offset : int; +begin + cquantize := my_cquantize_ptr (cinfo^.cquantize); + colorindex0 := (cquantize^.colorindex)^[0]; + colorindex1 := (cquantize^.colorindex)^[1]; + colorindex2 := (cquantize^.colorindex)^[2]; + width := cinfo^.output_width; + + { Nomssi: work around negative offset } + if my_cquantize_ptr (cinfo^.cquantize)^.is_padded then + pad_offset := MAXJSAMPLE + else + pad_offset := 0; + + Dec(JSAMPLE_PTR(colorindex0), pad_offset); + Dec(JSAMPLE_PTR(colorindex1), pad_offset); + Dec(JSAMPLE_PTR(colorindex2), pad_offset); + + for row := 0 to pred(num_rows) do + begin + row_index := cquantize^.row_index; + input_ptr := JSAMPLE_PTR(input_buf^[row]); + output_ptr := JSAMPLE_PTR(output_buf^[row]); + dither0 := @(cquantize^.odither[0]^[row_index]); + dither1 := @(cquantize^.odither[1]^[row_index]); + dither2 := @(cquantize^.odither[2]^[row_index]); + col_index := 0; + + + for col := pred(width) downto 0 do + begin + pixcode := GETJSAMPLE(colorindex0^[GETJSAMPLE(input_ptr^) + pad_offset + + dither0^[col_index]]); + Inc(input_ptr); + Inc(pixcode, GETJSAMPLE(colorindex1^[GETJSAMPLE(input_ptr^) + pad_offset + + dither1^[col_index]])); + Inc(input_ptr); + Inc(pixcode, GETJSAMPLE(colorindex2^[GETJSAMPLE(input_ptr^) + pad_offset + + dither2^[col_index]])); + Inc(input_ptr); + output_ptr^ := JSAMPLE (pixcode); + Inc(output_ptr); + col_index := (col_index + 1) and ODITHER_MASK; + end; + row_index := (row_index + 1) and ODITHER_MASK; + cquantize^.row_index := row_index; + end; +end; + + +{METHODDEF} +procedure quantize_fs_dither (cinfo : j_decompress_ptr; + input_buf : JSAMPARRAY; + output_buf : JSAMPARRAY; + num_rows : int); +{ General case, with Floyd-Steinberg dithering } +var + cquantize : my_cquantize_ptr; + cur : LOCFSERROR; {register} { current error or pixel value } + belowerr : LOCFSERROR; { error for pixel below cur } + bpreverr : LOCFSERROR; { error for below/prev col } + bnexterr : LOCFSERROR; { error for below/next col } + delta : LOCFSERROR; + prev_errorptr, + errorptr : FSERRORPTR; {register} { => fserrors[] at column before current } + input_ptr, {register} + output_ptr : JSAMPLE_PTR; {register} + colorindex_ci : JSAMPROW; + colormap_ci : JSAMPROW; + pixcode : int; + nc : int; + dir : int; { 1 for left-to-right, -1 for right-to-left } + dirnc : int; { dir * nc } + ci : int; + row : int; + col : JDIMENSION; + width : JDIMENSION; + range_limit : range_limit_table_ptr; +begin + cquantize := my_cquantize_ptr (cinfo^.cquantize); + nc := cinfo^.out_color_components; + width := cinfo^.output_width; + range_limit := cinfo^.sample_range_limit; + + for row := 0 to pred(num_rows) do + begin + { Initialize output values to 0 so can process components separately } + jzero_far( (output_buf)^[row], + size_t(width * SIZEOF(JSAMPLE))); + for ci := 0 to pred(nc) do + begin + input_ptr := JSAMPLE_PTR(@ input_buf^[row]^[ci]); + output_ptr := JSAMPLE_PTR(output_buf^[row]); + errorptr := FSERRORPTR(cquantize^.fserrors[ci]); { => entry before first column } + if (cquantize^.on_odd_row) then + begin + { work right to left in this row } + Inc(input_ptr, (width-1) * nc); { so point to rightmost pixel } + Inc(output_ptr, width-1); + dir := -1; + dirnc := -nc; + Inc(errorptr, (width+1)); { => entry after last column } + end + else + begin + { work left to right in this row } + dir := 1; + dirnc := nc; + {errorptr := cquantize^.fserrors[ci];} + end; + + colorindex_ci := cquantize^.colorindex^[ci]; + + colormap_ci := (cquantize^.sv_colormap)^[ci]; + { Preset error values: no error propagated to first pixel from left } + cur := 0; + { and no error propagated to row below yet } + belowerr := 0; + bpreverr := 0; + + for col := pred(width) downto 0 do + begin + prev_errorptr := errorptr; + Inc(errorptr, dir); { advance errorptr to current column } + + { cur holds the error propagated from the previous pixel on the + current line. Add the error propagated from the previous line + to form the complete error correction term for this pixel, and + round the error term (which is expressed * 16) to an integer. + RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct + for either sign of the error value. + Note: errorptr points to *previous* column's array entry. } + + cur := (cur + errorptr^ + 8) div 16; + + { Form pixel value + error, and range-limit to 0..MAXJSAMPLE. + The maximum error is +- MAXJSAMPLE; this sets the required size + of the range_limit array. } + + Inc( cur, GETJSAMPLE(input_ptr^)); + cur := GETJSAMPLE(range_limit^[cur]); + { Select output value, accumulate into output code for this pixel } + pixcode := GETJSAMPLE(colorindex_ci^[cur]); + Inc(output_ptr^, JSAMPLE (pixcode)); + { Compute actual representation error at this pixel } + { Note: we can do this even though we don't have the final } + { pixel code, because the colormap is orthogonal. } + Dec(cur, GETJSAMPLE(colormap_ci^[pixcode])); + { Compute error fractions to be propagated to adjacent pixels. + Add these into the running sums, and simultaneously shift the + next-line error sums left by 1 column. } + + bnexterr := cur; + delta := cur * 2; + Inc(cur, delta); { form error * 3 } + prev_errorptr^ := FSERROR (bpreverr + cur); + Inc(cur, delta); { form error * 5 } + bpreverr := belowerr + cur; + belowerr := bnexterr; + Inc(cur, delta); { form error * 7 } + { At this point cur contains the 7/16 error value to be propagated + to the next pixel on the current line, and all the errors for the + next line have been shifted over. We are therefore ready to move on. } + + Inc(input_ptr, dirnc); { advance input ptr to next column } + Inc(output_ptr, dir); { advance output ptr to next column } + + end; + { Post-loop cleanup: we must unload the final error value into the + final fserrors[] entry. Note we need not unload belowerr because + it is for the dummy column before or after the actual array. } + + errorptr^ := FSERROR (bpreverr); { unload prev err into array } + { Nomssi : ?? } + end; + cquantize^.on_odd_row := not cquantize^.on_odd_row; + end; +end; + + +{ Allocate workspace for Floyd-Steinberg errors. } + +{LOCAL} +procedure alloc_fs_workspace (cinfo : j_decompress_ptr); +var + cquantize : my_cquantize_ptr; + arraysize : size_t; + i : int; +begin + cquantize := my_cquantize_ptr (cinfo^.cquantize); + arraysize := size_t ((cinfo^.output_width + 2) * SIZEOF(FSERROR)); + for i := 0 to pred(cinfo^.out_color_components) do + begin + cquantize^.fserrors[i] := FS_ERROR_FIELD_PTR( + cinfo^.mem^.alloc_large(j_common_ptr(cinfo), JPOOL_IMAGE, arraysize)); + end; +end; + + +{ Initialize for one-pass color quantization. } + +{METHODDEF} +procedure start_pass_1_quant (cinfo : j_decompress_ptr; + is_pre_scan : boolean); +var + cquantize : my_cquantize_ptr; + arraysize : size_t; + i : int; +begin + cquantize := my_cquantize_ptr (cinfo^.cquantize); + { Install my colormap. } + cinfo^.colormap := cquantize^.sv_colormap; + cinfo^.actual_number_of_colors := cquantize^.sv_actual; + + { Initialize for desired dithering mode. } + case (cinfo^.dither_mode) of + JDITHER_NONE: + if (cinfo^.out_color_components = 3) then + cquantize^.pub.color_quantize := color_quantize3 + else + cquantize^.pub.color_quantize := color_quantize; + JDITHER_ORDERED: + begin + if (cinfo^.out_color_components = 3) then + cquantize^.pub.color_quantize := quantize3_ord_dither + else + cquantize^.pub.color_quantize := quantize_ord_dither; + cquantize^.row_index := 0; { initialize state for ordered dither } + { If user changed to ordered dither from another mode, + we must recreate the color index table with padding. + This will cost extra space, but probably isn't very likely. } + + if (not cquantize^.is_padded) then + create_colorindex(cinfo); + { Create ordered-dither tables if we didn't already. } + if (cquantize^.odither[0] = NIL) then + create_odither_tables(cinfo); + end; + JDITHER_FS: + begin + cquantize^.pub.color_quantize := quantize_fs_dither; + cquantize^.on_odd_row := FALSE; { initialize state for F-S dither } + { Allocate Floyd-Steinberg workspace if didn't already. } + if (cquantize^.fserrors[0] = NIL) then + alloc_fs_workspace(cinfo); + { Initialize the propagated errors to zero. } + arraysize := size_t ((cinfo^.output_width + 2) * SIZEOF(FSERROR)); + for i := 0 to pred(cinfo^.out_color_components) do + jzero_far({far} pointer( cquantize^.fserrors[i] ), arraysize); + end; + else + ERREXIT(j_common_ptr(cinfo), JERR_NOT_COMPILED); + end; +end; + + +{ Finish up at the end of the pass. } + +{METHODDEF} +procedure finish_pass_1_quant (cinfo : j_decompress_ptr); +begin + { no work in 1-pass case } +end; + + +{ Switch to a new external colormap between output passes. + Shouldn't get to this module! } + +{METHODDEF} +procedure new_color_map_1_quant (cinfo : j_decompress_ptr); +begin + ERREXIT(j_common_ptr(cinfo), JERR_MODE_CHANGE); +end; + + +{ Module initialization routine for 1-pass color quantization. } + +{GLOBAL} +procedure jinit_1pass_quantizer (cinfo : j_decompress_ptr); +var + cquantize : my_cquantize_ptr; +begin + cquantize := my_cquantize_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(my_cquantizer))); + cinfo^.cquantize := jpeg_color_quantizer_ptr(cquantize); + cquantize^.pub.start_pass := start_pass_1_quant; + cquantize^.pub.finish_pass := finish_pass_1_quant; + cquantize^.pub.new_color_map := new_color_map_1_quant; + cquantize^.fserrors[0] := NIL; { Flag FS workspace not allocated } + cquantize^.odither[0] := NIL; { Also flag odither arrays not allocated } + + { Make sure my internal arrays won't overflow } + if (cinfo^.out_color_components > MAX_Q_COMPS) then + ERREXIT1(j_common_ptr(cinfo), JERR_QUANT_COMPONENTS, MAX_Q_COMPS); + { Make sure colormap indexes can be represented by JSAMPLEs } + if (cinfo^.desired_number_of_colors > (MAXJSAMPLE+1)) then + ERREXIT1(j_common_ptr(cinfo), JERR_QUANT_MANY_COLORS, MAXJSAMPLE+1); + + { Create the colormap and color index table. } + create_colormap(cinfo); + create_colorindex(cinfo); + + { Allocate Floyd-Steinberg workspace now if requested. + We do this now since it is FAR storage and may affect the memory + manager's space calculations. If the user changes to FS dither + mode in a later pass, we will allocate the space then, and will + possibly overrun the max_memory_to_use setting. } + + if (cinfo^.dither_mode = JDITHER_FS) then + alloc_fs_workspace(cinfo); +end; + + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/jquant2_del.pas b/mseide-msegui/lib/common/fpccompatibility/jquant2_del.pas new file mode 100644 index 0000000..099d805 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jquant2_del.pas @@ -0,0 +1,1553 @@ +unit jquant2_del; + + +{ This file contains 2-pass color quantization (color mapping) routines. + These routines provide selection of a custom color map for an image, + followed by mapping of the image to that color map, with optional + Floyd-Steinberg dithering. + It is also possible to use just the second pass to map to an arbitrary + externally-given color map. + + Note: ordered dithering is not supported, since there isn't any fast + way to compute intercolor distances; it's unclear that ordered dither's + fundamental assumptions even hold with an irregularly spaced color map. } + +{ Original: jquant2.c; Copyright (C) 1991-1996, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jdeferr_del, + jerror_del, + jutils_del, + jpeglib_del; + +{ Module initialization routine for 2-pass color quantization. } + + +{GLOBAL} +procedure jinit_2pass_quantizer (cinfo : j_decompress_ptr); + +implementation + +{ This module implements the well-known Heckbert paradigm for color + quantization. Most of the ideas used here can be traced back to + Heckbert's seminal paper + Heckbert, Paul. "Color Image Quantization for Frame Buffer Display", + Proc. SIGGRAPH '82, Computer Graphics v.16 #3 (July 1982), pp 297-304. + + In the first pass over the image, we accumulate a histogram showing the + usage count of each possible color. To keep the histogram to a reasonable + size, we reduce the precision of the input; typical practice is to retain + 5 or 6 bits per color, so that 8 or 4 different input values are counted + in the same histogram cell. + + Next, the color-selection step begins with a box representing the whole + color space, and repeatedly splits the "largest" remaining box until we + have as many boxes as desired colors. Then the mean color in each + remaining box becomes one of the possible output colors. + + The second pass over the image maps each input pixel to the closest output + color (optionally after applying a Floyd-Steinberg dithering correction). + This mapping is logically trivial, but making it go fast enough requires + considerable care. + + Heckbert-style quantizers vary a good deal in their policies for choosing + the "largest" box and deciding where to cut it. The particular policies + used here have proved out well in experimental comparisons, but better ones + may yet be found. + + In earlier versions of the IJG code, this module quantized in YCbCr color + space, processing the raw upsampled data without a color conversion step. + This allowed the color conversion math to be done only once per colormap + entry, not once per pixel. However, that optimization precluded other + useful optimizations (such as merging color conversion with upsampling) + and it also interfered with desired capabilities such as quantizing to an + externally-supplied colormap. We have therefore abandoned that approach. + The present code works in the post-conversion color space, typically RGB. + + To improve the visual quality of the results, we actually work in scaled + RGB space, giving G distances more weight than R, and R in turn more than + B. To do everything in integer math, we must use integer scale factors. + The 2/3/1 scale factors used here correspond loosely to the relative + weights of the colors in the NTSC grayscale equation. + If you want to use this code to quantize a non-RGB color space, you'll + probably need to change these scale factors. } + +const + R_SCALE = 2; { scale R distances by this much } + G_SCALE = 3; { scale G distances by this much } + B_SCALE = 1; { and B by this much } + +{ Relabel R/G/B as components 0/1/2, respecting the RGB ordering defined + in jmorecfg.h. As the code stands, it will do the right thing for R,G,B + and B,G,R orders. If you define some other weird order in jmorecfg.h, + you'll get compile errors until you extend this logic. In that case + you'll probably want to tweak the histogram sizes too. } + +{$ifdef RGB_RED_IS_0} +const + C0_SCALE = R_SCALE; + C1_SCALE = G_SCALE; + C2_SCALE = B_SCALE; +{$else} +const + C0_SCALE = B_SCALE; + C1_SCALE = G_SCALE; + C2_SCALE = R_SCALE; +{$endif} + + +{ First we have the histogram data structure and routines for creating it. + + The number of bits of precision can be adjusted by changing these symbols. + We recommend keeping 6 bits for G and 5 each for R and B. + If you have plenty of memory and cycles, 6 bits all around gives marginally + better results; if you are short of memory, 5 bits all around will save + some space but degrade the results. + To maintain a fully accurate histogram, we'd need to allocate a "long" + (preferably unsigned long) for each cell. In practice this is overkill; + we can get by with 16 bits per cell. Few of the cell counts will overflow, + and clamping those that do overflow to the maximum value will give close- + enough results. This reduces the recommended histogram size from 256Kb + to 128Kb, which is a useful savings on PC-class machines. + (In the second pass the histogram space is re-used for pixel mapping data; + in that capacity, each cell must be able to store zero to the number of + desired colors. 16 bits/cell is plenty for that too.) + Since the JPEG code is intended to run in small memory model on 80x86 + machines, we can't just allocate the histogram in one chunk. Instead + of a true 3-D array, we use a row of pointers to 2-D arrays. Each + pointer corresponds to a C0 value (typically 2^5 = 32 pointers) and + each 2-D array has 2^6*2^5 = 2048 or 2^6*2^6 = 4096 entries. Note that + on 80x86 machines, the pointer row is in near memory but the actual + arrays are in far memory (same arrangement as we use for image arrays). } + + +const + MAXNUMCOLORS = (MAXJSAMPLE+1); { maximum size of colormap } + +{ These will do the right thing for either R,G,B or B,G,R color order, + but you may not like the results for other color orders. } + +const + HIST_C0_BITS = 5; { bits of precision in R/B histogram } + HIST_C1_BITS = 6; { bits of precision in G histogram } + HIST_C2_BITS = 5; { bits of precision in B/R histogram } + +{ Number of elements along histogram axes. } +const + HIST_C0_ELEMS = (1 shl HIST_C0_BITS); + HIST_C1_ELEMS = (1 shl HIST_C1_BITS); + HIST_C2_ELEMS = (1 shl HIST_C2_BITS); + +{ These are the amounts to shift an input value to get a histogram index. } +const + C0_SHIFT = (BITS_IN_JSAMPLE-HIST_C0_BITS); + C1_SHIFT = (BITS_IN_JSAMPLE-HIST_C1_BITS); + C2_SHIFT = (BITS_IN_JSAMPLE-HIST_C2_BITS); + + +type { Nomssi } + RGBptr = ^RGBtype; + RGBtype = packed record + r,g,b : JSAMPLE; + end; +type + histcell = UINT16; { histogram cell; prefer an unsigned type } + +type + histptr = ^histcell {FAR}; { for pointers to histogram cells } + +type + hist1d = array[0..HIST_C2_ELEMS-1] of histcell; { typedefs for the array } + {hist1d_ptr = ^hist1d;} + hist1d_field = array[0..HIST_C1_ELEMS-1] of hist1d; + { type for the 2nd-level pointers } + hist2d = ^hist1d_field; + hist2d_field = array[0..HIST_C0_ELEMS-1] of hist2d; + hist3d = ^hist2d_field; { type for top-level pointer } + + +{ Declarations for Floyd-Steinberg dithering. + + Errors are accumulated into the array fserrors[], at a resolution of + 1/16th of a pixel count. The error at a given pixel is propagated + to its not-yet-processed neighbors using the standard F-S fractions, + ... (here) 7/16 + 3/16 5/16 1/16 + We work left-to-right on even rows, right-to-left on odd rows. + + We can get away with a single array (holding one row's worth of errors) + by using it to store the current row's errors at pixel columns not yet + processed, but the next row's errors at columns already processed. We + need only a few extra variables to hold the errors immediately around the + current column. (If we are lucky, those variables are in registers, but + even if not, they're probably cheaper to access than array elements are.) + + The fserrors[] array has (#columns + 2) entries; the extra entry at + each end saves us from special-casing the first and last pixels. + Each entry is three values long, one value for each color component. + + Note: on a wide image, we might not have enough room in a PC's near data + segment to hold the error array; so it is allocated with alloc_large. } + + +{$ifdef BITS_IN_JSAMPLE_IS_8} +type + FSERROR = INT16; { 16 bits should be enough } + LOCFSERROR = int; { use 'int' for calculation temps } +{$else} +type + FSERROR = INT32; { may need more than 16 bits } + LOCFSERROR = INT32; { be sure calculation temps are big enough } +{$endif} +type { Nomssi } + RGB_FSERROR_PTR = ^RGB_FSERROR; + RGB_FSERROR = packed record + r,g,b : FSERROR; + end; + LOCRGB_FSERROR = packed record + r,g,b : LOCFSERROR; + end; + +type + FSERROR_PTR = ^FSERROR; + jFSError = 0..(MaxInt div SIZEOF(RGB_FSERROR))-1; + FS_ERROR_FIELD = array[jFSError] of RGB_FSERROR; + FS_ERROR_FIELD_PTR = ^FS_ERROR_FIELD;{far} + { pointer to error array (in FAR storage!) } + +type + error_limit_array = array[-MAXJSAMPLE..MAXJSAMPLE] of int; + { table for clamping the applied error } + error_limit_ptr = ^error_limit_array; + +{ Private subobject } +type + my_cquantize_ptr = ^my_cquantizer; + my_cquantizer = record + pub : jpeg_color_quantizer; { public fields } + + { Space for the eventually created colormap is stashed here } + sv_colormap : JSAMPARRAY; { colormap allocated at init time } + desired : int; { desired # of colors = size of colormap } + + { Variables for accumulating image statistics } + histogram : hist3d; { pointer to the histogram } + + needs_zeroed : boolean; { TRUE if next pass must zero histogram } + + { Variables for Floyd-Steinberg dithering } + fserrors : FS_ERROR_FIELD_PTR; { accumulated errors } + on_odd_row : boolean; { flag to remember which row we are on } + error_limiter : error_limit_ptr; { table for clamping the applied error } + end; + + + +{ Prescan some rows of pixels. + In this module the prescan simply updates the histogram, which has been + initialized to zeroes by start_pass. + An output_buf parameter is required by the method signature, but no data + is actually output (in fact the buffer controller is probably passing a + NIL pointer). } + +{METHODDEF} +procedure prescan_quantize (cinfo : j_decompress_ptr; + input_buf : JSAMPARRAY; + output_buf : JSAMPARRAY; + num_rows : int); +var + cquantize : my_cquantize_ptr; + {register} ptr : RGBptr; + {register} histp : histptr; + {register} histogram : hist3d; + row : int; + col : JDIMENSION; + width : JDIMENSION; +begin + cquantize := my_cquantize_ptr(cinfo^.cquantize); + histogram := cquantize^.histogram; + width := cinfo^.output_width; + + for row := 0 to pred(num_rows) do + begin + ptr := RGBptr(input_buf^[row]); + for col := pred(width) downto 0 do + begin + { get pixel value and index into the histogram } + histp := @(histogram^[GETJSAMPLE(ptr^.r) shr C0_SHIFT]^ + [GETJSAMPLE(ptr^.g) shr C1_SHIFT] + [GETJSAMPLE(ptr^.b) shr C2_SHIFT]); + { increment, check for overflow and undo increment if so. } + Inc(histp^); + if (histp^ <= 0) then + Dec(histp^); + Inc(ptr); + end; + end; +end; + +{ Next we have the really interesting routines: selection of a colormap + given the completed histogram. + These routines work with a list of "boxes", each representing a rectangular + subset of the input color space (to histogram precision). } + +type + box = record + { The bounds of the box (inclusive); expressed as histogram indexes } + c0min, c0max : int; + c1min, c1max : int; + c2min, c2max : int; + { The volume (actually 2-norm) of the box } + volume : INT32; + { The number of nonzero histogram cells within this box } + colorcount : long; + end; + +type + jBoxList = 0..(MaxInt div SizeOf(box))-1; + box_field = array[jBoxlist] of box; + boxlistptr = ^box_field; + boxptr = ^box; + +{LOCAL} +function find_biggest_color_pop (boxlist : boxlistptr; numboxes : int) : boxptr; +{ Find the splittable box with the largest color population } +{ Returns NIL if no splittable boxes remain } +var + boxp : boxptr ; {register} + i : int; {register} + maxc : long; {register} + which : boxptr; +begin + which := NIL; + boxp := @(boxlist^[0]); + maxc := 0; + for i := 0 to pred(numboxes) do + begin + if (boxp^.colorcount > maxc) and (boxp^.volume > 0) then + begin + which := boxp; + maxc := boxp^.colorcount; + end; + Inc(boxp); + end; + find_biggest_color_pop := which; +end; + + +{LOCAL} +function find_biggest_volume (boxlist : boxlistptr; numboxes : int) : boxptr; +{ Find the splittable box with the largest (scaled) volume } +{ Returns NULL if no splittable boxes remain } +var + {register} boxp : boxptr; + {register} i : int; + {register} maxv : INT32; + which : boxptr; +begin + maxv := 0; + which := NIL; + boxp := @(boxlist^[0]); + for i := 0 to pred(numboxes) do + begin + if (boxp^.volume > maxv) then + begin + which := boxp; + maxv := boxp^.volume; + end; + Inc(boxp); + end; + find_biggest_volume := which; +end; + + +{LOCAL} +procedure update_box (cinfo : j_decompress_ptr; var boxp : box); +label + have_c0min, have_c0max, + have_c1min, have_c1max, + have_c2min, have_c2max; +{ Shrink the min/max bounds of a box to enclose only nonzero elements, } +{ and recompute its volume and population } +var + cquantize : my_cquantize_ptr; + histogram : hist3d; + histp : histptr; + c0,c1,c2 : int; + c0min,c0max,c1min,c1max,c2min,c2max : int; + dist0,dist1,dist2 : INT32; + ccount : long; +begin + cquantize := my_cquantize_ptr(cinfo^.cquantize); + histogram := cquantize^.histogram; + + c0min := boxp.c0min; c0max := boxp.c0max; + c1min := boxp.c1min; c1max := boxp.c1max; + c2min := boxp.c2min; c2max := boxp.c2max; + + if (c0max > c0min) then + for c0 := c0min to c0max do + for c1 := c1min to c1max do + begin + histp := @(histogram^[c0]^[c1][c2min]); + for c2 := c2min to c2max do + begin + if (histp^ <> 0) then + begin + c0min := c0; + boxp.c0min := c0min; + goto have_c0min; + end; + Inc(histp); + end; + end; + have_c0min: + if (c0max > c0min) then + for c0 := c0max downto c0min do + for c1 := c1min to c1max do + begin + histp := @(histogram^[c0]^[c1][c2min]); + for c2 := c2min to c2max do + begin + if ( histp^ <> 0) then + begin + c0max := c0; + boxp.c0max := c0; + goto have_c0max; + end; + Inc(histp); + end; + end; + have_c0max: + if (c1max > c1min) then + for c1 := c1min to c1max do + for c0 := c0min to c0max do + begin + histp := @(histogram^[c0]^[c1][c2min]); + for c2 := c2min to c2max do + begin + if (histp^ <> 0) then + begin + c1min := c1; + boxp.c1min := c1; + goto have_c1min; + end; + Inc(histp); + end; + end; + have_c1min: + if (c1max > c1min) then + for c1 := c1max downto c1min do + for c0 := c0min to c0max do + begin + histp := @(histogram^[c0]^[c1][c2min]); + for c2 := c2min to c2max do + begin + if (histp^ <> 0) then + begin + c1max := c1; + boxp.c1max := c1; + goto have_c1max; + end; + Inc(histp); + end; + end; + have_c1max: + if (c2max > c2min) then + for c2 := c2min to c2max do + for c0 := c0min to c0max do + begin + histp := @(histogram^[c0]^[c1min][c2]); + for c1 := c1min to c1max do + begin + if (histp^ <> 0) then + begin + c2min := c2; + boxp.c2min := c2min; + goto have_c2min; + end; + Inc(histp, HIST_C2_ELEMS); + end; + end; + have_c2min: + if (c2max > c2min) then + for c2 := c2max downto c2min do + for c0 := c0min to c0max do + begin + histp := @(histogram^[c0]^[c1min][c2]); + for c1 := c1min to c1max do + begin + if (histp^ <> 0) then + begin + c2max := c2; + boxp.c2max := c2max; + goto have_c2max; + end; + Inc(histp, HIST_C2_ELEMS); + end; + end; + have_c2max: + + { Update box volume. + We use 2-norm rather than real volume here; this biases the method + against making long narrow boxes, and it has the side benefit that + a box is splittable iff norm > 0. + Since the differences are expressed in histogram-cell units, + we have to shift back to JSAMPLE units to get consistent distances; + after which, we scale according to the selected distance scale factors.} + + dist0 := ((c0max - c0min) shl C0_SHIFT) * C0_SCALE; + dist1 := ((c1max - c1min) shl C1_SHIFT) * C1_SCALE; + dist2 := ((c2max - c2min) shl C2_SHIFT) * C2_SCALE; + boxp.volume := dist0*dist0 + dist1*dist1 + dist2*dist2; + + { Now scan remaining volume of box and compute population } + ccount := 0; + for c0 := c0min to c0max do + for c1 := c1min to c1max do + begin + histp := @(histogram^[c0]^[c1][c2min]); + for c2 := c2min to c2max do + begin + if (histp^ <> 0) then + Inc(ccount); + Inc(histp); + end; + end; + boxp.colorcount := ccount; +end; + + +{LOCAL} +function median_cut (cinfo : j_decompress_ptr; boxlist : boxlistptr; + numboxes : int; desired_colors : int) : int; +{ Repeatedly select and split the largest box until we have enough boxes } +var + n,lb : int; + c0,c1,c2,cmax : int; + {register} b1,b2 : boxptr; +begin + while (numboxes < desired_colors) do + begin + { Select box to split. + Current algorithm: by population for first half, then by volume. } + + if (numboxes*2 <= desired_colors) then + b1 := find_biggest_color_pop(boxlist, numboxes) + else + b1 := find_biggest_volume(boxlist, numboxes); + + if (b1 = NIL) then { no splittable boxes left! } + break; + b2 := @(boxlist^[numboxes]); { where new box will go } + { Copy the color bounds to the new box. } + b2^.c0max := b1^.c0max; b2^.c1max := b1^.c1max; b2^.c2max := b1^.c2max; + b2^.c0min := b1^.c0min; b2^.c1min := b1^.c1min; b2^.c2min := b1^.c2min; + { Choose which axis to split the box on. + Current algorithm: longest scaled axis. + See notes in update_box about scaling distances. } + + c0 := ((b1^.c0max - b1^.c0min) shl C0_SHIFT) * C0_SCALE; + c1 := ((b1^.c1max - b1^.c1min) shl C1_SHIFT) * C1_SCALE; + c2 := ((b1^.c2max - b1^.c2min) shl C2_SHIFT) * C2_SCALE; + { We want to break any ties in favor of green, then red, blue last. + This code does the right thing for R,G,B or B,G,R color orders only. } + +{$ifdef RGB_RED_IS_0} + cmax := c1; n := 1; + if (c0 > cmax) then + begin + cmax := c0; + n := 0; + end; + if (c2 > cmax) then + n := 2; +{$else} + cmax := c1; + n := 1; + if (c2 > cmax) then + begin + cmax := c2; + n := 2; + end; + if (c0 > cmax) then + n := 0; +{$endif} + { Choose split point along selected axis, and update box bounds. + Current algorithm: split at halfway point. + (Since the box has been shrunk to minimum volume, + any split will produce two nonempty subboxes.) + Note that lb value is max for lower box, so must be < old max. } + + case n of + 0:begin + lb := (b1^.c0max + b1^.c0min) div 2; + b1^.c0max := lb; + b2^.c0min := lb+1; + end; + 1:begin + lb := (b1^.c1max + b1^.c1min) div 2; + b1^.c1max := lb; + b2^.c1min := lb+1; + end; + 2:begin + lb := (b1^.c2max + b1^.c2min) div 2; + b1^.c2max := lb; + b2^.c2min := lb+1; + end; + end; + { Update stats for boxes } + update_box(cinfo, b1^); + update_box(cinfo, b2^); + Inc(numboxes); + end; + median_cut := numboxes; +end; + + +{LOCAL} +procedure compute_color (cinfo : j_decompress_ptr; + const boxp : box; icolor : int); +{ Compute representative color for a box, put it in colormap[icolor] } +var + { Current algorithm: mean weighted by pixels (not colors) } + { Note it is important to get the rounding correct! } + cquantize : my_cquantize_ptr; + histogram : hist3d; + histp : histptr; + c0,c1,c2 : int; + c0min,c0max,c1min,c1max,c2min,c2max : int; + count : long; + total : long; + c0total : long; + c1total : long; + c2total : long; +begin + cquantize := my_cquantize_ptr(cinfo^.cquantize); + histogram := cquantize^.histogram; + total := 0; + c0total := 0; + c1total := 0; + c2total := 0; + + c0min := boxp.c0min; c0max := boxp.c0max; + c1min := boxp.c1min; c1max := boxp.c1max; + c2min := boxp.c2min; c2max := boxp.c2max; + + for c0 := c0min to c0max do + for c1 := c1min to c1max do + begin + histp := @(histogram^[c0]^[c1][c2min]); + for c2 := c2min to c2max do + begin + count := histp^; + Inc(histp); + if (count <> 0) then + begin + Inc(total, count); + Inc(c0total, ((c0 shl C0_SHIFT) + ((1 shl C0_SHIFT) shr 1)) * count); + Inc(c1total, ((c1 shl C1_SHIFT) + ((1 shl C1_SHIFT) shr 1)) * count); + Inc(c2total, ((c2 shl C2_SHIFT) + ((1 shl C2_SHIFT) shr 1)) * count); + end; + end; + end; + + cinfo^.colormap^[0]^[icolor] := JSAMPLE ((c0total + (total shr 1)) div total); + cinfo^.colormap^[1]^[icolor] := JSAMPLE ((c1total + (total shr 1)) div total); + cinfo^.colormap^[2]^[icolor] := JSAMPLE ((c2total + (total shr 1)) div total); +end; + + +{LOCAL} +procedure select_colors (cinfo : j_decompress_ptr; desired_colors : int); +{ Master routine for color selection } +var + boxlist : boxlistptr; + numboxes : int; + i : int; +begin + { Allocate workspace for box list } + boxlist := boxlistptr(cinfo^.mem^.alloc_small( + j_common_ptr(cinfo), JPOOL_IMAGE, desired_colors * SIZEOF(box))); + { Initialize one box containing whole space } + numboxes := 1; + boxlist^[0].c0min := 0; + boxlist^[0].c0max := MAXJSAMPLE shr C0_SHIFT; + boxlist^[0].c1min := 0; + boxlist^[0].c1max := MAXJSAMPLE shr C1_SHIFT; + boxlist^[0].c2min := 0; + boxlist^[0].c2max := MAXJSAMPLE shr C2_SHIFT; + { Shrink it to actually-used volume and set its statistics } + update_box(cinfo, boxlist^[0]); + { Perform median-cut to produce final box list } + numboxes := median_cut(cinfo, boxlist, numboxes, desired_colors); + { Compute the representative color for each box, fill colormap } + for i := 0 to pred(numboxes) do + compute_color(cinfo, boxlist^[i], i); + cinfo^.actual_number_of_colors := numboxes; + {$IFDEF DEBUG} + TRACEMS1(j_common_ptr(cinfo), 1, JTRC_QUANT_SELECTED, numboxes); + {$ENDIF} +end; + + +{ These routines are concerned with the time-critical task of mapping input + colors to the nearest color in the selected colormap. + + We re-use the histogram space as an "inverse color map", essentially a + cache for the results of nearest-color searches. All colors within a + histogram cell will be mapped to the same colormap entry, namely the one + closest to the cell's center. This may not be quite the closest entry to + the actual input color, but it's almost as good. A zero in the cache + indicates we haven't found the nearest color for that cell yet; the array + is cleared to zeroes before starting the mapping pass. When we find the + nearest color for a cell, its colormap index plus one is recorded in the + cache for future use. The pass2 scanning routines call fill_inverse_cmap + when they need to use an unfilled entry in the cache. + + Our method of efficiently finding nearest colors is based on the "locally + sorted search" idea described by Heckbert and on the incremental distance + calculation described by Spencer W. Thomas in chapter III.1 of Graphics + Gems II (James Arvo, ed. Academic Press, 1991). Thomas points out that + the distances from a given colormap entry to each cell of the histogram can + be computed quickly using an incremental method: the differences between + distances to adjacent cells themselves differ by a constant. This allows a + fairly fast implementation of the "brute force" approach of computing the + distance from every colormap entry to every histogram cell. Unfortunately, + it needs a work array to hold the best-distance-so-far for each histogram + cell (because the inner loop has to be over cells, not colormap entries). + The work array elements have to be INT32s, so the work array would need + 256Kb at our recommended precision. This is not feasible in DOS machines. + + To get around these problems, we apply Thomas' method to compute the + nearest colors for only the cells within a small subbox of the histogram. + The work array need be only as big as the subbox, so the memory usage + problem is solved. Furthermore, we need not fill subboxes that are never + referenced in pass2; many images use only part of the color gamut, so a + fair amount of work is saved. An additional advantage of this + approach is that we can apply Heckbert's locality criterion to quickly + eliminate colormap entries that are far away from the subbox; typically + three-fourths of the colormap entries are rejected by Heckbert's criterion, + and we need not compute their distances to individual cells in the subbox. + The speed of this approach is heavily influenced by the subbox size: too + small means too much overhead, too big loses because Heckbert's criterion + can't eliminate as many colormap entries. Empirically the best subbox + size seems to be about 1/512th of the histogram (1/8th in each direction). + + Thomas' article also describes a refined method which is asymptotically + faster than the brute-force method, but it is also far more complex and + cannot efficiently be applied to small subboxes. It is therefore not + useful for programs intended to be portable to DOS machines. On machines + with plenty of memory, filling the whole histogram in one shot with Thomas' + refined method might be faster than the present code --- but then again, + it might not be any faster, and it's certainly more complicated. } + + + +{ log2(histogram cells in update box) for each axis; this can be adjusted } +const + BOX_C0_LOG = (HIST_C0_BITS-3); + BOX_C1_LOG = (HIST_C1_BITS-3); + BOX_C2_LOG = (HIST_C2_BITS-3); + + BOX_C0_ELEMS = (1 shl BOX_C0_LOG); { # of hist cells in update box } + BOX_C1_ELEMS = (1 shl BOX_C1_LOG); + BOX_C2_ELEMS = (1 shl BOX_C2_LOG); + + BOX_C0_SHIFT = (C0_SHIFT + BOX_C0_LOG); + BOX_C1_SHIFT = (C1_SHIFT + BOX_C1_LOG); + BOX_C2_SHIFT = (C2_SHIFT + BOX_C2_LOG); + + +{ The next three routines implement inverse colormap filling. They could + all be folded into one big routine, but splitting them up this way saves + some stack space (the mindist[] and bestdist[] arrays need not coexist) + and may allow some compilers to produce better code by registerizing more + inner-loop variables. } + +{LOCAL} +function find_nearby_colors (cinfo : j_decompress_ptr; + minc0 : int; minc1 : int; minc2 : int; + var colorlist : array of JSAMPLE) : int; +{ Locate the colormap entries close enough to an update box to be candidates + for the nearest entry to some cell(s) in the update box. The update box + is specified by the center coordinates of its first cell. The number of + candidate colormap entries is returned, and their colormap indexes are + placed in colorlist[]. + This routine uses Heckbert's "locally sorted search" criterion to select + the colors that need further consideration. } + +var + numcolors : int; + maxc0, maxc1, maxc2 : int; + centerc0, centerc1, centerc2 : int; + i, x, ncolors : int; + minmaxdist, min_dist, max_dist, tdist : INT32; + mindist : array[0..MAXNUMCOLORS-1] of INT32; + { min distance to colormap entry i } +begin + numcolors := cinfo^.actual_number_of_colors; + + { Compute true coordinates of update box's upper corner and center. + Actually we compute the coordinates of the center of the upper-corner + histogram cell, which are the upper bounds of the volume we care about. + Note that since ">>" rounds down, the "center" values may be closer to + min than to max; hence comparisons to them must be "<=", not "<". } + + maxc0 := minc0 + ((1 shl BOX_C0_SHIFT) - (1 shl C0_SHIFT)); + centerc0 := (minc0 + maxc0) shr 1; + maxc1 := minc1 + ((1 shl BOX_C1_SHIFT) - (1 shl C1_SHIFT)); + centerc1 := (minc1 + maxc1) shr 1; + maxc2 := minc2 + ((1 shl BOX_C2_SHIFT) - (1 shl C2_SHIFT)); + centerc2 := (minc2 + maxc2) shr 1; + + { For each color in colormap, find: + 1. its minimum squared-distance to any point in the update box + (zero if color is within update box); + 2. its maximum squared-distance to any point in the update box. + Both of these can be found by considering only the corners of the box. + We save the minimum distance for each color in mindist[]; + only the smallest maximum distance is of interest. } + + minmaxdist := long($7FFFFFFF); + + for i := 0 to pred(numcolors) do + begin + { We compute the squared-c0-distance term, then add in the other two. } + x := GETJSAMPLE(cinfo^.colormap^[0]^[i]); + if (x < minc0) then + begin + tdist := (x - minc0) * C0_SCALE; + min_dist := tdist*tdist; + tdist := (x - maxc0) * C0_SCALE; + max_dist := tdist*tdist; + end + else + if (x > maxc0) then + begin + tdist := (x - maxc0) * C0_SCALE; + min_dist := tdist*tdist; + tdist := (x - minc0) * C0_SCALE; + max_dist := tdist*tdist; + end + else + begin + { within cell range so no contribution to min_dist } + min_dist := 0; + if (x <= centerc0) then + begin + tdist := (x - maxc0) * C0_SCALE; + max_dist := tdist*tdist; + end + else + begin + tdist := (x - minc0) * C0_SCALE; + max_dist := tdist*tdist; + end; + end; + + x := GETJSAMPLE(cinfo^.colormap^[1]^[i]); + if (x < minc1) then + begin + tdist := (x - minc1) * C1_SCALE; + Inc(min_dist, tdist*tdist); + tdist := (x - maxc1) * C1_SCALE; + Inc(max_dist, tdist*tdist); + end + else + if (x > maxc1) then + begin + tdist := (x - maxc1) * C1_SCALE; + Inc(min_dist, tdist*tdist); + tdist := (x - minc1) * C1_SCALE; + Inc(max_dist, tdist*tdist); + end + else + begin + { within cell range so no contribution to min_dist } + if (x <= centerc1) then + begin + tdist := (x - maxc1) * C1_SCALE; + Inc(max_dist, tdist*tdist); + end + else + begin + tdist := (x - minc1) * C1_SCALE; + Inc(max_dist, tdist*tdist); + end + end; + + x := GETJSAMPLE(cinfo^.colormap^[2]^[i]); + if (x < minc2) then + begin + tdist := (x - minc2) * C2_SCALE; + Inc(min_dist, tdist*tdist); + tdist := (x - maxc2) * C2_SCALE; + Inc(max_dist, tdist*tdist); + end + else + if (x > maxc2) then + begin + tdist := (x - maxc2) * C2_SCALE; + Inc(min_dist, tdist*tdist); + tdist := (x - minc2) * C2_SCALE; + Inc(max_dist, tdist*tdist); + end + else + begin + { within cell range so no contribution to min_dist } + if (x <= centerc2) then + begin + tdist := (x - maxc2) * C2_SCALE; + Inc(max_dist, tdist*tdist); + end + else + begin + tdist := (x - minc2) * C2_SCALE; + Inc(max_dist, tdist*tdist); + end; + end; + + mindist[i] := min_dist; { save away the results } + if (max_dist < minmaxdist) then + minmaxdist := max_dist; + end; + + { Now we know that no cell in the update box is more than minmaxdist + away from some colormap entry. Therefore, only colors that are + within minmaxdist of some part of the box need be considered. } + + ncolors := 0; + for i := 0 to pred(numcolors) do + begin +{$warnings off} + if (mindist[i] <= minmaxdist) then + begin + colorlist[ncolors] := JSAMPLE(i); + Inc(ncolors); + end; + end; + find_nearby_colors := ncolors; +end; +{$warnings on} + +{LOCAL} +procedure find_best_colors (cinfo : j_decompress_ptr; + minc0 : int; minc1 : int; minc2 : int; + numcolors : int; + var colorlist : array of JSAMPLE; + var bestcolor : array of JSAMPLE); +{ Find the closest colormap entry for each cell in the update box, + given the list of candidate colors prepared by find_nearby_colors. + Return the indexes of the closest entries in the bestcolor[] array. + This routine uses Thomas' incremental distance calculation method to + find the distance from a colormap entry to successive cells in the box. } +const + { Nominal steps between cell centers ("x" in Thomas article) } + STEP_C0 = ((1 shl C0_SHIFT) * C0_SCALE); + STEP_C1 = ((1 shl C1_SHIFT) * C1_SCALE); + STEP_C2 = ((1 shl C2_SHIFT) * C2_SCALE); +var + ic0, ic1, ic2 : int; + i, icolor : int; + {register} bptr : INT32PTR; { pointer into bestdist[] array } + cptr : JSAMPLE_PTR; { pointer into bestcolor[] array } + dist0, dist1 : INT32; { initial distance values } + {register} dist2 : INT32; { current distance in inner loop } + xx0, xx1 : INT32; { distance increments } + {register} xx2 : INT32; + inc0, inc1, inc2 : INT32; { initial values for increments } + { This array holds the distance to the nearest-so-far color for each cell } + bestdist : array[0..BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS-1] of INT32; +begin + { Initialize best-distance for each cell of the update box } + for i := BOX_C0_ELEMS*BOX_C1_ELEMS*BOX_C2_ELEMS-1 downto 0 do + bestdist[i] := $7FFFFFFF; + + { For each color selected by find_nearby_colors, + compute its distance to the center of each cell in the box. + If that's less than best-so-far, update best distance and color number. } + + + + for i := 0 to pred(numcolors) do + begin + icolor := GETJSAMPLE(colorlist[i]); + { Compute (square of) distance from minc0/c1/c2 to this color } + inc0 := (minc0 - GETJSAMPLE(cinfo^.colormap^[0]^[icolor])) * C0_SCALE; + dist0 := inc0*inc0; + inc1 := (minc1 - GETJSAMPLE(cinfo^.colormap^[1]^[icolor])) * C1_SCALE; + Inc(dist0, inc1*inc1); + inc2 := (minc2 - GETJSAMPLE(cinfo^.colormap^[2]^[icolor])) * C2_SCALE; + Inc(dist0, inc2*inc2); + { Form the initial difference increments } + inc0 := inc0 * (2 * STEP_C0) + STEP_C0 * STEP_C0; + inc1 := inc1 * (2 * STEP_C1) + STEP_C1 * STEP_C1; + inc2 := inc2 * (2 * STEP_C2) + STEP_C2 * STEP_C2; + { Now loop over all cells in box, updating distance per Thomas method } + bptr := @bestdist[0]; + cptr := @bestcolor[0]; + xx0 := inc0; + for ic0 := BOX_C0_ELEMS-1 downto 0 do + begin + dist1 := dist0; + xx1 := inc1; + for ic1 := BOX_C1_ELEMS-1 downto 0 do + begin + dist2 := dist1; + xx2 := inc2; + for ic2 := BOX_C2_ELEMS-1 downto 0 do + begin + if (dist2 < bptr^) then + begin + bptr^ := dist2; + cptr^ := JSAMPLE (icolor); + end; + Inc(dist2, xx2); + Inc(xx2, 2 * STEP_C2 * STEP_C2); + Inc(bptr); + Inc(cptr); + end; + Inc(dist1, xx1); + Inc(xx1, 2 * STEP_C1 * STEP_C1); + end; + Inc(dist0, xx0); + Inc(xx0, 2 * STEP_C0 * STEP_C0); + end; + end; +end; + + +{LOCAL} +procedure fill_inverse_cmap (cinfo : j_decompress_ptr; + c0 : int; c1 : int; c2 : int); +{ Fill the inverse-colormap entries in the update box that contains } +{ histogram cell c0/c1/c2. (Only that one cell MUST be filled, but } +{ we can fill as many others as we wish.) } +var + cquantize : my_cquantize_ptr; + histogram : hist3d; + minc0, minc1, minc2 : int; { lower left corner of update box } + ic0, ic1, ic2 : int; + {register} cptr : JSAMPLE_PTR; { pointer into bestcolor[] array } + {register} cachep : histptr; { pointer into main cache array } + { This array lists the candidate colormap indexes. } + colorlist : array[0..MAXNUMCOLORS-1] of JSAMPLE; + numcolors : int; { number of candidate colors } + { This array holds the actually closest colormap index for each cell. } + bestcolor : array[0..BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS-1] of JSAMPLE; +begin + cquantize := my_cquantize_ptr (cinfo^.cquantize); + histogram := cquantize^.histogram; + + { Convert cell coordinates to update box ID } + c0 := c0 shr BOX_C0_LOG; + c1 := c1 shr BOX_C1_LOG; + c2 := c2 shr BOX_C2_LOG; + + { Compute true coordinates of update box's origin corner. + Actually we compute the coordinates of the center of the corner + histogram cell, which are the lower bounds of the volume we care about.} + + minc0 := (c0 shl BOX_C0_SHIFT) + ((1 shl C0_SHIFT) shr 1); + minc1 := (c1 shl BOX_C1_SHIFT) + ((1 shl C1_SHIFT) shr 1); + minc2 := (c2 shl BOX_C2_SHIFT) + ((1 shl C2_SHIFT) shr 1); + + { Determine which colormap entries are close enough to be candidates + for the nearest entry to some cell in the update box. } + + numcolors := find_nearby_colors(cinfo, minc0, minc1, minc2, colorlist); + + { Determine the actually nearest colors. } + find_best_colors(cinfo, minc0, minc1, minc2, numcolors, colorlist, + bestcolor); + + { Save the best color numbers (plus 1) in the main cache array } + c0 := c0 shl BOX_C0_LOG; { convert ID back to base cell indexes } + c1 := c1 shl BOX_C1_LOG; + c2 := c2 shl BOX_C2_LOG; + cptr := @(bestcolor[0]); + for ic0 := 0 to pred(BOX_C0_ELEMS) do + for ic1 := 0 to pred(BOX_C1_ELEMS) do + begin + cachep := @(histogram^[c0+ic0]^[c1+ic1][c2]); + for ic2 := 0 to pred(BOX_C2_ELEMS) do + begin + cachep^ := histcell (GETJSAMPLE(cptr^) + 1); + Inc(cachep); + Inc(cptr); + end; + end; +end; + + +{ Map some rows of pixels to the output colormapped representation. } + +{METHODDEF} +procedure pass2_no_dither (cinfo : j_decompress_ptr; + input_buf : JSAMPARRAY; + output_buf : JSAMPARRAY; + num_rows : int); +{ This version performs no dithering } +var + cquantize : my_cquantize_ptr; + histogram : hist3d; + {register} inptr : RGBptr; + outptr : JSAMPLE_PTR; + {register} cachep : histptr; + {register} c0, c1, c2 : int; + row : int; + col : JDIMENSION; + width : JDIMENSION; +begin + cquantize := my_cquantize_ptr (cinfo^.cquantize); + histogram := cquantize^.histogram; + width := cinfo^.output_width; + + for row := 0 to pred(num_rows) do + begin + inptr := RGBptr(input_buf^[row]); + outptr := JSAMPLE_PTR(output_buf^[row]); + for col := pred(width) downto 0 do + begin + { get pixel value and index into the cache } + c0 := GETJSAMPLE(inptr^.r) shr C0_SHIFT; + c1 := GETJSAMPLE(inptr^.g) shr C1_SHIFT; + c2 := GETJSAMPLE(inptr^.b) shr C2_SHIFT; + Inc(inptr); + cachep := @(histogram^[c0]^[c1][c2]); + { If we have not seen this color before, find nearest colormap entry } + { and update the cache } + if (cachep^ = 0) then + fill_inverse_cmap(cinfo, c0,c1,c2); + { Now emit the colormap index for this cell } + outptr^ := JSAMPLE (cachep^ - 1); + Inc(outptr); + end; + end; +end; + + +{METHODDEF} +procedure pass2_fs_dither (cinfo : j_decompress_ptr; + input_buf : JSAMPARRAY; + output_buf : JSAMPARRAY; + num_rows : int); +{ This version performs Floyd-Steinberg dithering } +var + cquantize : my_cquantize_ptr; + histogram : hist3d; + {register} cur : LOCRGB_FSERROR; { current error or pixel value } + belowerr : LOCRGB_FSERROR; { error for pixel below cur } + bpreverr : LOCRGB_FSERROR; { error for below/prev col } + prev_errorptr, + {register} errorptr : RGB_FSERROR_PTR; { => fserrors[] at column before current } + inptr : RGBptr; { => current input pixel } + outptr : JSAMPLE_PTR; { => current output pixel } + cachep : histptr; + dir : int; { +1 or -1 depending on direction } + row : int; + col : JDIMENSION; + width : JDIMENSION; + range_limit : range_limit_table_ptr; + error_limit : error_limit_ptr; + colormap0 : JSAMPROW; + colormap1 : JSAMPROW; + colormap2 : JSAMPROW; + {register} pixcode : int; + {register} bnexterr, delta : LOCFSERROR; +begin + cquantize := my_cquantize_ptr (cinfo^.cquantize); + histogram := cquantize^.histogram; + width := cinfo^.output_width; + range_limit := cinfo^.sample_range_limit; + error_limit := cquantize^.error_limiter; + colormap0 := cinfo^.colormap^[0]; + colormap1 := cinfo^.colormap^[1]; + colormap2 := cinfo^.colormap^[2]; + + for row := 0 to pred(num_rows) do + begin + inptr := RGBptr(input_buf^[row]); + outptr := JSAMPLE_PTR(output_buf^[row]); + errorptr := RGB_FSERROR_PTR(cquantize^.fserrors); { => entry before first real column } + if (cquantize^.on_odd_row) then + begin + { work right to left in this row } + Inc(inptr, (width-1)); { so point to rightmost pixel } + Inc(outptr, width-1); + dir := -1; + Inc(errorptr, (width+1)); { => entry after last column } + cquantize^.on_odd_row := FALSE; { flip for next time } + end + else + begin + { work left to right in this row } + dir := 1; + cquantize^.on_odd_row := TRUE; { flip for next time } + end; + + { Preset error values: no error propagated to first pixel from left } + cur.r := 0; + cur.g := 0; + cur.b := 0; + { and no error propagated to row below yet } + belowerr.r := 0; + belowerr.g := 0; + belowerr.b := 0; + bpreverr.r := 0; + bpreverr.g := 0; + bpreverr.b := 0; + + for col := pred(width) downto 0 do + begin + prev_errorptr := errorptr; + Inc(errorptr, dir); { advance errorptr to current column } + + { curN holds the error propagated from the previous pixel on the + current line. Add the error propagated from the previous line + to form the complete error correction term for this pixel, and + round the error term (which is expressed * 16) to an integer. + RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct + for either sign of the error value. + Note: prev_errorptr points to *previous* column's array entry. } + + { Nomssi Note: Borland Pascal SHR is unsigned } + cur.r := (cur.r + errorptr^.r + 8) div 16; + cur.g := (cur.g + errorptr^.g + 8) div 16; + cur.b := (cur.b + errorptr^.b + 8) div 16; + { Limit the error using transfer function set by init_error_limit. + See comments with init_error_limit for rationale. } + + cur.r := error_limit^[cur.r]; + cur.g := error_limit^[cur.g]; + cur.b := error_limit^[cur.b]; + { Form pixel value + error, and range-limit to 0..MAXJSAMPLE. + The maximum error is +- MAXJSAMPLE (or less with error limiting); + this sets the required size of the range_limit array. } + + Inc(cur.r, GETJSAMPLE(inptr^.r)); + Inc(cur.g, GETJSAMPLE(inptr^.g)); + Inc(cur.b, GETJSAMPLE(inptr^.b)); + + cur.r := GETJSAMPLE(range_limit^[cur.r]); + cur.g := GETJSAMPLE(range_limit^[cur.g]); + cur.b := GETJSAMPLE(range_limit^[cur.b]); + { Index into the cache with adjusted pixel value } + cachep := @(histogram^[cur.r shr C0_SHIFT]^ + [cur.g shr C1_SHIFT][cur.b shr C2_SHIFT]); + { If we have not seen this color before, find nearest colormap } + { entry and update the cache } + if (cachep^ = 0) then + fill_inverse_cmap(cinfo, cur.r shr C0_SHIFT, + cur.g shr C1_SHIFT, + cur.b shr C2_SHIFT); + { Now emit the colormap index for this cell } + + pixcode := cachep^ - 1; + outptr^ := JSAMPLE (pixcode); + + { Compute representation error for this pixel } + Dec(cur.r, GETJSAMPLE(colormap0^[pixcode])); + Dec(cur.g, GETJSAMPLE(colormap1^[pixcode])); + Dec(cur.b, GETJSAMPLE(colormap2^[pixcode])); + + { Compute error fractions to be propagated to adjacent pixels. + Add these into the running sums, and simultaneously shift the + next-line error sums left by 1 column. } + + bnexterr := cur.r; { Process component 0 } + delta := cur.r * 2; + Inc(cur.r, delta); { form error * 3 } + prev_errorptr^.r := FSERROR (bpreverr.r + cur.r); + Inc(cur.r, delta); { form error * 5 } + bpreverr.r := belowerr.r + cur.r; + belowerr.r := bnexterr; + Inc(cur.r, delta); { form error * 7 } + bnexterr := cur.g; { Process component 1 } + delta := cur.g * 2; + Inc(cur.g, delta); { form error * 3 } + prev_errorptr^.g := FSERROR (bpreverr.g + cur.g); + Inc(cur.g, delta); { form error * 5 } + bpreverr.g := belowerr.g + cur.g; + belowerr.g := bnexterr; + Inc(cur.g, delta); { form error * 7 } + bnexterr := cur.b; { Process component 2 } + delta := cur.b * 2; + Inc(cur.b, delta); { form error * 3 } + prev_errorptr^.b := FSERROR (bpreverr.b + cur.b); + Inc(cur.b, delta); { form error * 5 } + bpreverr.b := belowerr.b + cur.b; + belowerr.b := bnexterr; + Inc(cur.b, delta); { form error * 7 } + + { At this point curN contains the 7/16 error value to be propagated + to the next pixel on the current line, and all the errors for the + next line have been shifted over. We are therefore ready to move on.} + + Inc(inptr, dir); { Advance pixel pointers to next column } + Inc(outptr, dir); + end; + { Post-loop cleanup: we must unload the final error values into the + final fserrors[] entry. Note we need not unload belowerrN because + it is for the dummy column before or after the actual array. } + + errorptr^.r := FSERROR (bpreverr.r); { unload prev errs into array } + errorptr^.g := FSERROR (bpreverr.g); + errorptr^.b := FSERROR (bpreverr.b); + end; +end; + + +{ Initialize the error-limiting transfer function (lookup table). + The raw F-S error computation can potentially compute error values of up to + +- MAXJSAMPLE. But we want the maximum correction applied to a pixel to be + much less, otherwise obviously wrong pixels will be created. (Typical + effects include weird fringes at color-area boundaries, isolated bright + pixels in a dark area, etc.) The standard advice for avoiding this problem + is to ensure that the "corners" of the color cube are allocated as output + colors; then repeated errors in the same direction cannot cause cascading + error buildup. However, that only prevents the error from getting + completely out of hand; Aaron Giles reports that error limiting improves + the results even with corner colors allocated. + A simple clamping of the error values to about +- MAXJSAMPLE/8 works pretty + well, but the smoother transfer function used below is even better. Thanks + to Aaron Giles for this idea. } + +{LOCAL} +procedure init_error_limit (cinfo : j_decompress_ptr); +const + STEPSIZE = ((MAXJSAMPLE+1) div 16); +{ Allocate and fill in the error_limiter table } +var + cquantize : my_cquantize_ptr; + table : error_limit_ptr; + inp, out : int; +begin + cquantize := my_cquantize_ptr (cinfo^.cquantize); + table := error_limit_ptr (cinfo^.mem^.alloc_small + (j_common_ptr (cinfo), JPOOL_IMAGE, (MAXJSAMPLE*2+1) * SIZEOF(int))); + { not needed: Inc(table, MAXJSAMPLE); + so can index -MAXJSAMPLE .. +MAXJSAMPLE } + cquantize^.error_limiter := table; + { Map errors 1:1 up to +- MAXJSAMPLE/16 } + out := 0; + for inp := 0 to pred(STEPSIZE) do + begin + table^[inp] := out; + table^[-inp] := -out; + Inc(out); + end; + { Map errors 1:2 up to +- 3*MAXJSAMPLE/16 } + inp := STEPSIZE; { Nomssi: avoid problems with Delphi2 optimizer } + while (inp < STEPSIZE*3) do + begin + table^[inp] := out; + table^[-inp] := -out; + Inc(inp); + if Odd(inp) then + Inc(out); + end; + { Clamp the rest to final out value (which is (MAXJSAMPLE+1)/8) } + inp := STEPSIZE*3; { Nomssi: avoid problems with Delphi 2 optimizer } + while inp <= MAXJSAMPLE do + begin + table^[inp] := out; + table^[-inp] := -out; + Inc(inp); + end; +end; + +{ Finish up at the end of each pass. } + +{METHODDEF} +procedure finish_pass1 (cinfo : j_decompress_ptr); +var + cquantize : my_cquantize_ptr; +begin + cquantize := my_cquantize_ptr (cinfo^.cquantize); + + { Select the representative colors and fill in cinfo^.colormap } + cinfo^.colormap := cquantize^.sv_colormap; + select_colors(cinfo, cquantize^.desired); + { Force next pass to zero the color index table } + cquantize^.needs_zeroed := TRUE; +end; + + +{METHODDEF} +procedure finish_pass2 (cinfo : j_decompress_ptr); +begin + { no work } +end; + + +{ Initialize for each processing pass. } + +{METHODDEF} +procedure start_pass_2_quant (cinfo : j_decompress_ptr; + is_pre_scan : boolean); +var + cquantize : my_cquantize_ptr; + histogram : hist3d; + i : int; +var + arraysize : size_t; +begin + cquantize := my_cquantize_ptr (cinfo^.cquantize); + histogram := cquantize^.histogram; + { Only F-S dithering or no dithering is supported. } + { If user asks for ordered dither, give him F-S. } + if (cinfo^.dither_mode <> JDITHER_NONE) then + cinfo^.dither_mode := JDITHER_FS; + + if (is_pre_scan) then + begin + { Set up method pointers } + cquantize^.pub.color_quantize := prescan_quantize; + cquantize^.pub.finish_pass := finish_pass1; + cquantize^.needs_zeroed := TRUE; { Always zero histogram } + end + else + begin + { Set up method pointers } + if (cinfo^.dither_mode = JDITHER_FS) then + cquantize^.pub.color_quantize := pass2_fs_dither + else + cquantize^.pub.color_quantize := pass2_no_dither; + cquantize^.pub.finish_pass := finish_pass2; + + { Make sure color count is acceptable } + i := cinfo^.actual_number_of_colors; + if (i < 1) then + ERREXIT1(j_common_ptr(cinfo), JERR_QUANT_FEW_COLORS, 1); + if (i > MAXNUMCOLORS) then + ERREXIT1(j_common_ptr(cinfo), JERR_QUANT_MANY_COLORS, MAXNUMCOLORS); + + if (cinfo^.dither_mode = JDITHER_FS) then + begin + arraysize := size_t ((cinfo^.output_width + 2) * + (3 * SIZEOF(FSERROR))); + { Allocate Floyd-Steinberg workspace if we didn't already. } + if (cquantize^.fserrors = NIL) then + cquantize^.fserrors := FS_ERROR_FIELD_PTR (cinfo^.mem^.alloc_large + (j_common_ptr(cinfo), JPOOL_IMAGE, arraysize)); + { Initialize the propagated errors to zero. } + jzero_far(cquantize^.fserrors, arraysize); + { Make the error-limit table if we didn't already. } + if (cquantize^.error_limiter = NIL) then + init_error_limit(cinfo); + cquantize^.on_odd_row := FALSE; + end; + + end; + { Zero the histogram or inverse color map, if necessary } + if (cquantize^.needs_zeroed) then + begin + for i := 0 to pred(HIST_C0_ELEMS) do + begin + jzero_far( histogram^[i], + HIST_C1_ELEMS*HIST_C2_ELEMS * SIZEOF(histcell)); + end; + cquantize^.needs_zeroed := FALSE; + end; +end; + + +{ Switch to a new external colormap between output passes. } + +{METHODDEF} +procedure new_color_map_2_quant (cinfo : j_decompress_ptr); +var + cquantize : my_cquantize_ptr; +begin + cquantize := my_cquantize_ptr (cinfo^.cquantize); + + { Reset the inverse color map } + cquantize^.needs_zeroed := TRUE; +end; + + +{ Module initialization routine for 2-pass color quantization. } + + +{GLOBAL} +procedure jinit_2pass_quantizer (cinfo : j_decompress_ptr); +var + cquantize : my_cquantize_ptr; + i : int; +var + desired : int; +begin + cquantize := my_cquantize_ptr( + cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE, + SIZEOF(my_cquantizer))); + cinfo^.cquantize := jpeg_color_quantizer_ptr(cquantize); + cquantize^.pub.start_pass := start_pass_2_quant; + cquantize^.pub.new_color_map := new_color_map_2_quant; + cquantize^.fserrors := NIL; { flag optional arrays not allocated } + cquantize^.error_limiter := NIL; + + { Make sure jdmaster didn't give me a case I can't handle } + if (cinfo^.out_color_components <> 3) then + ERREXIT(j_common_ptr(cinfo), JERR_NOTIMPL); + + { Allocate the histogram/inverse colormap storage } + cquantize^.histogram := hist3d (cinfo^.mem^.alloc_small + (j_common_ptr (cinfo), JPOOL_IMAGE, HIST_C0_ELEMS * SIZEOF(hist2d))); + for i := 0 to pred(HIST_C0_ELEMS) do + begin + cquantize^.histogram^[i] := hist2d (cinfo^.mem^.alloc_large + (j_common_ptr (cinfo), JPOOL_IMAGE, + HIST_C1_ELEMS*HIST_C2_ELEMS * SIZEOF(histcell))); + end; + cquantize^.needs_zeroed := TRUE; { histogram is garbage now } + + { Allocate storage for the completed colormap, if required. + We do this now since it is FAR storage and may affect + the memory manager's space calculations. } + + if (cinfo^.enable_2pass_quant) then + begin + { Make sure color count is acceptable } + desired := cinfo^.desired_number_of_colors; + { Lower bound on # of colors ... somewhat arbitrary as long as > 0 } + if (desired < 8) then + ERREXIT1(j_common_ptr (cinfo), JERR_QUANT_FEW_COLORS, 8); + { Make sure colormap indexes can be represented by JSAMPLEs } + if (desired > MAXNUMCOLORS) then + ERREXIT1(j_common_ptr (cinfo), JERR_QUANT_MANY_COLORS, MAXNUMCOLORS); + cquantize^.sv_colormap := cinfo^.mem^.alloc_sarray + (j_common_ptr (cinfo),JPOOL_IMAGE, JDIMENSION(desired), JDIMENSION(3)); + cquantize^.desired := desired; + end + else + cquantize^.sv_colormap := NIL; + + { Only F-S dithering or no dithering is supported. } + { If user asks for ordered dither, give him F-S. } + if (cinfo^.dither_mode <> JDITHER_NONE) then + cinfo^.dither_mode := JDITHER_FS; + + { Allocate Floyd-Steinberg workspace if necessary. + This isn't really needed until pass 2, but again it is FAR storage. + Although we will cope with a later change in dither_mode, + we do not promise to honor max_memory_to_use if dither_mode changes. } + + if (cinfo^.dither_mode = JDITHER_FS) then + begin + cquantize^.fserrors := FS_ERROR_FIELD_PTR (cinfo^.mem^.alloc_large + (j_common_ptr(cinfo), JPOOL_IMAGE, + size_t ((cinfo^.output_width + 2) * (3 * SIZEOF(FSERROR))) ) ); + { Might as well create the error-limiting table too. } + init_error_limit(cinfo); + end; +end; + +end. { QUANT_2PASS_SUPPORTED } diff --git a/mseide-msegui/lib/common/fpccompatibility/jutils_del.pas b/mseide-msegui/lib/common/fpccompatibility/jutils_del.pas new file mode 100644 index 0000000..e999d4c --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/jutils_del.pas @@ -0,0 +1,233 @@ +Unit jutils_del; + +{ This file contains tables and miscellaneous utility routines needed + for both compression and decompression. + Note we prefix all global names with "j" to minimize conflicts with + a surrounding application. } + +{ Source: jutils.c; Copyright (C) 1991-1996, Thomas G. Lane. } +//modified 2013 by Martin Schreiber + +interface + +{$I jconfig_del.inc} + +uses + jmorecfg_del, + jinclude_del, + jpeglib_del; + + +{ jpeg_zigzag_order[i] is the zigzag-order position of the i'th element + of a DCT block read in natural order (left to right, top to bottom). } + + +{$ifdef FALSE} { This table is not actually needed in v6a } + +const + jpeg_zigzag_order : array[0..DCTSIZE2] of int = + (0, 1, 5, 6, 14, 15, 27, 28, + 2, 4, 7, 13, 16, 26, 29, 42, + 3, 8, 12, 17, 25, 30, 41, 43, + 9, 11, 18, 24, 31, 40, 44, 53, + 10, 19, 23, 32, 39, 45, 52, 54, + 20, 22, 33, 38, 46, 51, 55, 60, + 21, 34, 37, 47, 50, 56, 59, 61, + 35, 36, 48, 49, 57, 58, 62, 63); + +{$endif} + + +{ jpeg_natural_order[i] is the natural-order position of the i'th element + of zigzag order. + + When reading corrupted data, the Huffman decoders could attempt + to reference an entry beyond the end of this array (if the decoded + zero run length reaches past the end of the block). To prevent + wild stores without adding an inner-loop test, we put some extra + "63"s after the real entries. This will cause the extra coefficient + to be stored in location 63 of the block, not somewhere random. + The worst case would be a run-length of 15, which means we need 16 + fake entries. } + + +const + jpeg_natural_order : array[0..DCTSIZE2+16-1] of int = + (0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, + 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63, + 63, 63, 63, 63, 63, 63, 63, 63, { extra entries for safety in decoder } + 63, 63, 63, 63, 63, 63, 63, 63); + + + +{ Arithmetic utilities } + +{GLOBAL} +function jdiv_round_up (a : long; b : long) : long; + +{GLOBAL} +function jround_up (a : long; b : long) : long; + +{GLOBAL} +procedure jcopy_sample_rows (input_array : JSAMPARRAY; + source_row : int; + output_array : JSAMPARRAY; dest_row : int; + num_rows : int; num_cols : JDIMENSION); + +{GLOBAL} +procedure jcopy_block_row (input_row : JBLOCKROW; + output_row : JBLOCKROW; + num_blocks : JDIMENSION); + +{GLOBAL} +procedure jzero_far (target : pointer;{far} bytestozero : size_t); + +procedure FMEMZERO(target : pointer; size : size_t); + +procedure FMEMCOPY(dest,src : pointer; size : size_t); + +implementation + +{GLOBAL} +function jdiv_round_up (a : long; b : long) : long; +{ Compute a/b rounded up to next integer, ie, ceil(a/b) } +{ Assumes a >= 0, b > 0 } +begin + jdiv_round_up := (a + b - long(1)) div b; +end; + + +{GLOBAL} +function jround_up (a : long; b : long) : long; +{ Compute a rounded up to next multiple of b, ie, ceil(a/b)*b } +{ Assumes a >= 0, b > 0 } +begin + Inc(a, b - long(1)); + jround_up := a - (a mod b); +end; + +{ On normal machines we can apply MEMCOPY() and MEMZERO() to sample arrays + and coefficient-block arrays. This won't work on 80x86 because the arrays + are FAR and we're assuming a small-pointer memory model. However, some + DOS compilers provide far-pointer versions of memcpy() and memset() even + in the small-model libraries. These will be used if USE_FMEM is defined. + Otherwise, the routines below do it the hard way. (The performance cost + is not all that great, because these routines aren't very heavily used.) } + + +{$ifndef NEED_FAR_POINTERS} { normal case, same as regular macros } +procedure FMEMZERO(target : pointer; size : size_t); +begin + FillChar(target^, size, 0); +end; + +procedure FMEMCOPY(dest,src : pointer; size : size_t); +begin + Move(src^, dest^, size); +end; + + +{$else} { 80x86 case, define if we can } + {$ifdef USE_FMEM} + FMEMCOPY(dest,src,size) _fmemcpy((void FAR *)(dest), (const void FAR *)(src), (size_t)(size)) + FMEMZERO(target,size) _fmemset((void FAR *)(target), 0, (size_t)(size)) + {$endif} +{$endif} + + +{GLOBAL} +procedure jcopy_sample_rows (input_array : JSAMPARRAY; source_row : int; + output_array : JSAMPARRAY; dest_row : int; + num_rows : int; num_cols : JDIMENSION); +{ Copy some rows of samples from one place to another. + num_rows rows are copied from input_array[source_row++] + to output_array[dest_row++]; these areas may overlap for duplication. + The source and destination arrays must be at least as wide as num_cols. } +var + inptr, outptr : JSAMPLE_PTR; {register} +{$ifdef FMEMCOPY} + count : size_t; {register} +{$else} + count : JDIMENSION; {register} +{$endif} + row : int; {register} +begin +{$ifdef FMEMCOPY} + count := size_t(num_cols * SIZEOF(JSAMPLE)); +{$endif} + Inc(JSAMPROW_PTR(input_array), source_row); + Inc(JSAMPROW_PTR(output_array), dest_row); + + for row := pred(num_rows) downto 0 do + begin + inptr := JSAMPLE_PTR(input_array^[0]); + Inc(JSAMPROW_PTR(input_array)); + outptr := JSAMPLE_PTR(output_array^[0]); + Inc(JSAMPROW_PTR(output_array)); +{$ifdef FMEMCOPY} + FMEMCOPY(outptr, inptr, count); +{$else} + for count := pred(num_cols) downto 0 do + begin + outptr^ := inptr^; { needn't bother with GETJSAMPLE() here } + Inc(inptr); + Inc(outptr); + end; +{$endif} + end; +end; + + +{GLOBAL} +procedure jcopy_block_row (input_row : JBLOCKROW; + output_row : JBLOCKROW; + num_blocks : JDIMENSION); +{ Copy a row of coefficient blocks from one place to another. } +{$ifdef FMEMCOPY} +begin + FMEMCOPY(output_row, input_row, num_blocks * (DCTSIZE2 * SIZEOF(JCOEF))); +{$else} +var + inptr, outptr : JCOEFPTR; {register} + count : long; {register} +begin + inptr := JCOEFPTR (input_row); + outptr := JCOEFPTR (output_row); + for count := long(num_blocks) * DCTSIZE2 -1 downto 0 do + begin + outptr^ := inptr^; + Inc(outptr); + Inc(inptr); + end; +{$endif} +end; + + +{GLOBAL} +procedure jzero_far (target : pointer;{far} bytestozero : size_t); +{ Zero out a chunk of FAR memory. } +{ This might be sample-array data, block-array data, or alloc_large data. } +{$ifdef FMEMZERO} +begin + FMEMZERO(target, bytestozero); +{$else} +var + ptr : byteptr; + count : size_t; {register} +begin + ptr := target; + for count := bytestozero-1 downto 0 do + begin + ptr^ := 0; + Inc(ptr); + end; +{$endif} +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/mclasses.pas b/mseide-msegui/lib/common/fpccompatibility/mclasses.pas new file mode 100644 index 0000000..84be990 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/mclasses.pas @@ -0,0 +1,9349 @@ +{ + This file is part of the Free Component Library (FCL) + Copyright (c) 1999-2000 by Michael Van Canneyt and Florian Klaempfl + + Classes unit for linux + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Modified 2013-2016 by Martin Schreiber + + **********************************************************************} + +unit mclasses; +{$ifdef FPC} + {$mode objfpc} + {$h+} + { determine the type of the resource/form file } + {$define Win16Res} + {$define classesinline} + + {$INLINE ON} +{$endif} + +{$if defined(FPC) and (fpc_fullversion >= 020601)} + {$define mse_fpc_2_6_2} +{$ifend} +{$if fpc_fullversion >= 030000} {$define mse_fpc_3} {$endif} +{$if FPC_FULLVERSION >= 030100} {$define mse_fpc_3_2} {$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,typinfo,sysutils,msetypes,msesystypes {$ifndef FPC},classes_del{$endif}; + +type + ar8ty = array[0..7] of byte; +{$ifndef FPC} + TTextLineBreakStyle = (tlbsLF,tlbsCRLF,tlbsCR); + TValueType = (vaNull, vaList, vaInt8, vaInt16, vaInt32, vaExtended, + vaString, vaIdent, vaFalse, vaTrue, vaBinary, vaSet, vaLString, + vaNil, vaCollection, vaSingle, vaCurrency, vaDate, vaWString, vaInt64, + vaUTF8String, vaUString, vaQWord); +const + feInvalidHandle : THandle = THandle(-1); //return value on FileOpen error +type +{$endif} +{$ifndef mse_fpc_2_6_2} + tbytes = array of byte; +{$endif} +{$ifndef mse_fpc_3} + RawByteString = ansistring; +{$endif} + tstrings = class; + tstringlist = class; + tfiler = class; + treader = class; + twriter = class; + tcomponent = class; + tstream = class; + tfilestream = class; + tmemorystream = class; + + + TReaderProc = procedure(Reader: treader) of object; + TWriterProc = procedure(Writer: twriter) of object; + TStreamProc = procedure(Stream: TStream) of object; + +{$M+} + + tpersistent = class(TObject{,IFPObserved}) + private +// FObservers : TFPList; + procedure AssignError(Source: tpersistent); + protected + {$ifndef FPC} + function Equals(Obj: TObject) : boolean;virtual; + { IUnknown } + function QueryInterface(const IID: TGUID;out Obj): Hresult; stdcall; + function _AddRef: Integer; stdcall; + function _Release: Integer; stdcall; + {$endif} + procedure AssignTo(Dest: tpersistent); virtual; + procedure DefineProperties(Filer: tfiler); virtual; + function GetOwner: tpersistent; dynamic; +// Procedure FPOAttachObserver(AObserver : TObject); +// Procedure FPODetachObserver(AObserver : TObject); +// Procedure FPONotifyObservers(ASender : TObject; AOperation : TFPObservedOperation; Data : Pointer); + public + Destructor Destroy; override; + procedure Assign(Source: tpersistent); virtual; + function GetNamePath: string; virtual; {dynamic;} + end; + +{$M-} + + TPersistentClass = class of TPersistent; + + TGetChildProc = procedure (Child: TComponent) of object; + + TComponentClass = class of TComponent; + + tcomponent = class(tpersistent{,IUnknown,IInterfaceComponentReference}) + private + FOwner: tcomponent; + FName: TComponentName; + FTag: Ptrint; + FDesignInfo: Longint; + FVCLComObject: Pointer; + FComponentStyle: TComponentStyle; + ftagpo: pointer; +// function GetComObject: IUnknown; + function GetComponent(AIndex: Integer): tcomponent; + function GetComponentCount: Integer; + function GetComponentIndex: Integer; + procedure Insert(AComponent: tcomponent); + procedure ReadLeft(Reader: treader); + procedure ReadTop(Reader: treader); + procedure Remove(AComponent: tcomponent); + procedure RemoveNotification(AComponent: tcomponent); + procedure SetComponentIndex(Value: Integer); + procedure SetReference(Enable: Boolean); + procedure WriteLeft(Writer: twriter); + procedure WriteTop(Writer: twriter); + protected + FComponents: TFpList; + FFreeNotifies: TFpList; + FComponentState: TComponentState; + procedure ChangeName(const NewName: TComponentName); + procedure DefineProperties(Filer: tfiler); override; + procedure GetChildren(Proc: TGetChildProc; Root: tcomponent); dynamic; + function GetChildOwner: tcomponent; dynamic; + function GetChildParent: tcomponent; dynamic; + function GetOwner: tpersistent; override; + procedure Loaded; virtual; + procedure Loading; virtual; + procedure Notification(AComponent: tcomponent; + Operation: TOperation); virtual; + procedure PaletteCreated; dynamic; + procedure ReadState(Reader: treader); virtual; + procedure SetAncestor(Value: Boolean); + procedure SetDesigning(Value: Boolean; + SetChildren : Boolean = True); virtual; + procedure SetDesignInstance(Value: Boolean); + procedure SetInline(Value: Boolean); + procedure SetName(const NewName: TComponentName); virtual; + procedure SetChildOrder(Child: tcomponent; Order: Integer); dynamic; + procedure SetParentComponent(Value: tcomponent); dynamic; + procedure Updating; dynamic; + procedure Updated; dynamic; + class procedure UpdateRegistry(Register: Boolean; const ClassID, ProgID: string); dynamic; + procedure ValidateRename(AComponent: tcomponent; + const CurName, NewName: string); virtual; + procedure ValidateContainer(AComponent: tcomponent); dynamic; + procedure ValidateInsert(AComponent: tcomponent); dynamic; + {$ifdef FPC} + { IUnknown } + function QueryInterface( + {$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} IID: TGUID; + out Obj): Hresult; virtual; {$IFNDEF msWINDOWS}cdecl{$ELSE}stdcall{$ENDIF}; + function _AddRef: Integer; {$IFNDEF msWINDOWS}cdecl{$ELSE}stdcall{$ENDIF}; + function _Release: Integer; {$IFNDEF msWINDOWS}cdecl{$ELSE}stdcall{$ENDIF}; + {$endif} + function iicrGetComponent: tcomponent; + { IDispatch } + function GetTypeInfoCount(out Count: Integer): HResult; stdcall; + function GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HResult; stdcall; + function GetIDsOfNames(const IID: TGUID; Names: Pointer; + NameCount, LocaleID: Integer; DispIDs: Pointer): HResult; stdcall; + function Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer; + Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult; stdcall; + public + //!! Moved temporary + // fpdoc doesn't handle this yet :( +{$ifndef fpdocsystem} +// function IInterfaceComponentReference.GetComponent=iicrgetcomponent; +{$endif} + procedure WriteState(Writer: twriter); virtual; + constructor Create(AOwner: tcomponent); virtual; + destructor Destroy; override; + procedure BeforeDestruction; override; + procedure DestroyComponents; + procedure Destroying; + function ExecuteAction(Action: TBasicAction): Boolean; dynamic; + function FindComponent(const AName: string): tcomponent; + function findtagcomponent(const atag: int32; + const aclass: tcomponentclass): tcomponent; + //returns first matching desecendent + procedure FreeNotification(AComponent: tcomponent); + procedure RemoveFreeNotification(AComponent: tcomponent); + procedure FreeOnRelease; +// function GetEnumerator: TComponentEnumerator; + function GetNamePath: string; override; + function GetParentComponent: tcomponent; dynamic; + function HasParent: Boolean; dynamic; + procedure InsertComponent(AComponent: tcomponent); + procedure RemoveComponent(AComponent: tcomponent); + function SafeCallException(ExceptObject: TObject; + ExceptAddr: Pointer): HResult; override; + procedure SetSubComponent(ASubComponent: Boolean); + function UpdateAction(Action: TBasicAction): Boolean; dynamic; +// property ComObject: IUnknown read GetComObject; +// function IsImplementorOf (const Intf:IInterface):boolean; +// procedure ReferenceInterface(const intf:IInterface;op:TOperation); + property Components[Index: Integer]: tcomponent read GetComponent; + property ComponentCount: Integer read GetComponentCount; + property ComponentIndex: Integer read GetComponentIndex write SetComponentIndex; + property ComponentState: TComponentState read FComponentState; + property ComponentStyle: TComponentStyle read FComponentStyle; + property DesignInfo: Longint read FDesignInfo write FDesignInfo; + property Owner: tcomponent read FOwner; + property VCLComObject: Pointer read FVCLComObject write FVCLComObject; + property tagpo: pointer read ftagpo write ftagpo; + published + property Name: TComponentName read FName write SetName stored False; + property Tag: PtrInt read FTag write FTag default 0; + end; + pcomponent = ^tcomponent; + + tcollection = class; + + TCollectionItem = class(TPersistent) + private + FCollection: TCollection; + FID: Integer; + FUpdateCount: Integer; + function GetIndex: Integer; + protected + procedure SetCollection(Value: TCollection);virtual; + procedure Changed(AllItems: Boolean); + function GetOwner: TPersistent; override; + function GetDisplayName: string; virtual; + procedure SetIndex(Value: Integer); virtual; + procedure SetDisplayName(const Value: string); virtual; + property UpdateCount: Integer read FUpdateCount; + public + constructor Create(ACollection: TCollection); virtual; + destructor Destroy; override; + function GetNamePath: string; override; + property Collection: TCollection read FCollection write SetCollection; + property ID: Integer read FID; + property Index: Integer read GetIndex write SetIndex; + property DisplayName: string read GetDisplayName write SetDisplayName; + end; + + TCollectionEnumerator = class + private + FCollection: TCollection; + FPosition: Integer; + public + constructor Create(ACollection: TCollection); + function GetCurrent: TCollectionItem; + function MoveNext: Boolean; + property Current: TCollectionItem read GetCurrent; + end; + + TCollectionItemClass = class of TCollectionItem; + TCollectionSortCompare = function (Item1, Item2: TCollectionItem): Integer; + + TCollection = class(TPersistent) + private + FItems: TFpList; + FUpdateCount: Integer; + FNextID: Integer; + FPropName: string; + function GetCount: Integer; + function GetPropName: string; + procedure InsertItem(Item: TCollectionItem); + procedure RemoveItem(Item: TCollectionItem); + procedure DoClear; + protected + FItemClass: TCollectionItemClass; + { Design-time editor support } + function GetAttrCount: Integer; dynamic; + function GetAttr(Index: Integer): string; dynamic; + function GetItemAttr(Index, ItemIndex: Integer): string; dynamic; + procedure Changed; + function GetItem(Index: Integer): TCollectionItem; + procedure SetItem(Index: Integer; Value: TCollectionItem); + procedure SetItemName(Item: TCollectionItem); virtual; + procedure SetPropName; virtual; + procedure Update(Item: TCollectionItem); virtual; + procedure Notify(Item: TCollectionItem;Action: TCollectionNotification); virtual; + property PropName: string read GetPropName write FPropName; + property UpdateCount: Integer read FUpdateCount; + public + constructor Create(AItemClass: TCollectionItemClass); + destructor Destroy; override; + function Owner: TPersistent; + function Add: TCollectionItem; + procedure Assign(Source: TPersistent); override; + procedure BeginUpdate; virtual; + procedure Clear; + procedure EndUpdate; virtual; + procedure Delete(Index: Integer); + function GetEnumerator: TCollectionEnumerator; + function GetNamePath: string; override; + function Insert(Index: Integer): TCollectionItem; + function FindItemID(ID: Integer): TCollectionItem; + procedure Exchange(Const Index1, index2: integer); + procedure Sort(Const Compare : TCollectionSortCompare); + property Count: Integer read GetCount; + property ItemClass: TCollectionItemClass read FItemClass; + property Items[Index: Integer]: TCollectionItem read GetItem write SetItem; + end; + + TOwnedCollection = class(TCollection) + private + FOwner: TPersistent; + protected + Function GetOwner: TPersistent; override; + public + Constructor Create(AOwner: TPersistent;AItemClass: TCollectionItemClass); + end; + + + TFindMethodEvent = procedure(Reader: TReader; const MethodName: string; + var Address: Pointer; var Error: Boolean) of object; + TSetMethodPropertyEvent = procedure(Reader: TReader; Instance: TPersistent; + PropInfo: PPropInfo; const TheMethodName: string; + var Handled: boolean) of object; + TSetNameEvent = procedure(Reader: TReader; Component: TComponent; + var Name: string) of object; + TReferenceNameEvent = procedure(Reader: TReader; var Name: string) of object; + TAncestorNotFoundEvent = procedure(Reader: TReader; const ComponentName: string; + ComponentClass: TPersistentClass; var Component: TComponent) of object; + TReadComponentsProc = procedure(Component: TComponent) of object; + TReaderError = procedure(Reader: TReader; const Message: string; + var Handled: Boolean) of object; + TPropertyNotFoundEvent = procedure(Reader: TReader; Instance: TPersistent; + var PropName: string; IsPath: boolean; var Handled, Skip: Boolean) of object; + TFindComponentClassEvent = procedure(Reader: TReader; const ClassName: string; + var ComponentClass: TComponentClass) of object; + TCreateComponentEvent = procedure(Reader: TReader; + ComponentClass: TComponentClass; var Component: TComponent) of object; + + TReadWriteStringPropertyEvent = procedure(Sender:TObject; + const Instance: TPersistent; PropInfo: PPropInfo; + var Content:string) of object; + + + TFindAncestorEvent = procedure (Writer: TWriter; Component: TComponent; + const Name: string; var Ancestor, RootAncestor: TComponent) of object; + TWriteMethodPropertyEvent = procedure (Writer: TWriter; Instance: TPersistent; + PropInfo: PPropInfo; + const MethodValue, DefMethodValue: TMethod; + var Handled: boolean) of object; + + tfiler = class(TObject) + private + FIgnoreChildren: Boolean; + protected + FRoot: tcomponent; + FLookupRoot: tcomponent; + FAncestor: tpersistent; + procedure SetRoot(ARoot: tcomponent); virtual; + public + procedure DefineProperty(const Name: string; + ReadData: TReaderProc; WriteData: TWriterProc; + HasData: Boolean); virtual; abstract; + procedure DefineBinaryProperty(const Name: string; + ReadData, WriteData: TStreamProc; + HasData: Boolean); virtual; abstract; + property Root: tcomponent read FRoot write SetRoot; + property LookupRoot: tcomponent read FLookupRoot; + property Ancestor: tpersistent read FAncestor write FAncestor; + property IgnoreChildren: Boolean read FIgnoreChildren write FIgnoreChildren; + end; + + TAbstractObjectReader = class + protected + freader: treader; + public + function NextValue: TValueType; virtual; abstract; + function ReadValue: TValueType; virtual; abstract; + procedure BeginRootComponent; virtual; abstract; + procedure BeginComponent(var Flags: TFilerFlags; var AChildPos: Integer; + var CompClassName, CompName: String); virtual; abstract; + function BeginProperty: String; virtual; abstract; + + //Please don't use read, better use ReadBinary whenever possible + procedure Read(var Buf; Count: LongInt); virtual; abstract; + { All ReadXXX methods are called _after_ the value type has been read! } + procedure ReadBinary(const DestData: TMemoryStream); virtual; abstract; +{$ifndef FPUNONE} + function ReadFloat: Extended; virtual; abstract; + function ReadSingle: Single; virtual; abstract; + function ReadDate: TDateTime; virtual; abstract; +{$endif} + function ReadCurrency: Currency; virtual; abstract; + function ReadIdent(ValueType: TValueType): String; virtual; abstract; + function ReadInt8: ShortInt; virtual; abstract; + function ReadInt16: SmallInt; virtual; abstract; + function ReadInt32: LongInt; virtual; abstract; + function ReadInt64: Int64; virtual; abstract; + function ReadSet(EnumType: ptypeinfo): Integer; virtual; abstract; + function ReadStr: String; virtual; abstract; + function ReadString(StringType: TValueType): String; virtual; abstract; + function Readutf8String(StringType: TValueType): utf8String; + virtual; abstract; + function ReadWideString: WideString;virtual;abstract; + function ReadUnicodeString: UnicodeString;virtual;abstract; + procedure SkipComponent(SkipComponentInfos: Boolean); virtual; abstract; + procedure SkipValue; virtual; abstract; + end; + + TBinaryObjectReader = class(TAbstractObjectReader) + protected + FStream: TStream; + FBuffer: Pointer; + FBufSize: Integer; + FBufPos: Integer; + FBufEnd: Integer; + + function ReadWord : word; + {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} + function ReadDWord : longword; + {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} + function ReadQWord : qword; + {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} +{$ifndef FPUNONE} + function ReadExtended : extended; + {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} +{$endif} + procedure SkipProperty; + procedure SkipSetBody; + public + constructor Create(Stream: TStream; BufSize: Integer); + destructor Destroy; override; + + function NextValue: TValueType; override; + function ReadValue: TValueType; override; + procedure BeginRootComponent; override; + procedure BeginComponent(var Flags: TFilerFlags; var AChildPos: Integer; + var CompClassName, CompName: String); override; + function BeginProperty: String; override; + + //Please don't use read, better use ReadBinary whenever possible + procedure Read(var Buf; Count: LongInt); override; + procedure ReadBinary(const DestData: TMemoryStream); override; +{$ifndef FPUNONE} + function ReadFloat: Extended; override; + function ReadSingle: Single; override; + function ReadDate: TDateTime; override; +{$endif} + function ReadCurrency: Currency; override; + function ReadIdent(ValueType: TValueType): String; override; + function ReadInt8: ShortInt; override; + function ReadInt16: SmallInt; override; + function ReadInt32: LongInt; override; + function ReadInt64: Int64; override; + function ReadSet(EnumType: ptypeinfo): Integer; override; + function ReadStr: String; override; + function ReadString(StringType: TValueType): String; override; + function Readutf8String(StringType: TValueType): utf8String; override; + function ReadWideString: WideString;override; + function ReadUnicodeString: UnicodeString;override; + procedure SkipComponent(SkipComponentInfos: Boolean); override; + procedure SkipValue; override; + end; + + enumerroreventty = procedure (const reader: treader; + const atype: ptypeinfo; const aenumname: string; + var avalue: longword) of object; + seterroreventty = procedure (const reader: treader; + const atype: ptypeinfo; const aitemname: string; + var avalue: integer) of object; + + treader = class(tfiler) + private + FDriver: TAbstractObjectReader; + FOwner: tcomponent; + FParent: tcomponent; + FFixups: TObject; + FOnFindMethod: TFindMethodEvent; + FOnSetMethodProperty: TSetMethodPropertyEvent; + FOnSetName: TSetNameEvent; + FOnReferenceName: TReferenceNameEvent; + FOnAncestorNotFound: TAncestorNotFoundEvent; + FOnError: TReaderError; + FOnPropertyNotFound: TPropertyNotFoundEvent; + FOnFindComponentClass: TFindComponentClassEvent; + FOnCreateComponent: TCreateComponentEvent; + FPropName: string; + FCanHandleExcepts: Boolean; + FOnReadStringProperty:TReadWriteStringPropertyEvent; + fonseterror: seterroreventty; + fonenumerror: enumerroreventty; + procedure DoFixupReferences; + function FindComponentClass(const AClassName: string; + const aflags: tfilerflags): TComponentClass; + protected + FLoaded: TFpList; + function Error(const Message: string): Boolean; virtual; + function FindMethod(ARoot: tcomponent; const AMethodName: string): Pointer; virtual; + procedure ReadProperty(AInstance: tpersistent); + procedure ReadPropValue(Instance: tpersistent; PropInfo: Pointer); + procedure PropertyError; + procedure ReadData(Instance: tcomponent); + property PropName: string read FPropName; + property CanHandleExceptions: Boolean read FCanHandleExcepts; + function CreateDriver(Stream: TStream; BufSize: Integer): TAbstractObjectReader; virtual; + public + constructor Create(Stream: TStream; BufSize: Integer); + destructor Destroy; override; + procedure BeginReferences; + procedure CheckValue(Value: TValueType); + procedure DefineProperty(const Name: string; + AReadData: TReaderProc; WriteData: TWriterProc; + HasData: Boolean); override; + procedure DefineBinaryProperty(const Name: string; + AReadData, WriteData: TStreamProc; + HasData: Boolean); override; + function beginoflist(): boolean; + function EndOfList: Boolean; + procedure EndReferences; + procedure FixupReferences; + function NextValue: TValueType; + //Please don't use read, better use ReadBinary whenever possible + //uuups, ReadBinary is protected .. + procedure Read(var Buf; Count: LongInt); virtual; + + function ReadBoolean: Boolean; + function ReadChar: Char; + function ReadWideChar: WideChar; + function ReadUnicodeChar: UnicodeChar; + procedure ReadCollection(Collection: TCollection); + function ReadComponent(Component: tcomponent): tcomponent; + procedure ReadComponents(AOwner, AParent: tcomponent; + Proc: TReadComponentsProc); +{$ifndef FPUNONE} + function ReadFloat: Extended; + function ReadSingle: Single; + function ReadDate: TDateTime; +{$endif} + function ReadCurrency: Currency; + function ReadIdent: string; + function ReadInteger: Longint; + function ReadInt64: Int64; + function readset(settype: ptypeinfo): longword; + function readenum(const enumtype: ptypeinfo): longword; + procedure ReadListBegin; + procedure ReadListEnd; + function ReadRootComponent(ARoot: tcomponent): tcomponent; + function ReadVariant: Variant; + function ReadString: string; + function Readutf8String: utf8string; + function ReadWideString: WideString; + function ReadUnicodeString: UnicodeString; + + function ReadValue: TValueType; + procedure CopyValue(Writer: twriter); + property Driver: TAbstractObjectReader read FDriver; + property Owner: tcomponent read FOwner write FOwner; + property Parent: tcomponent read FParent write FParent; + property OnError: TReaderError read FOnError write FOnError; + property OnPropertyNotFound: TPropertyNotFoundEvent + read FOnPropertyNotFound write FOnPropertyNotFound; + property OnFindMethod: TFindMethodEvent read FOnFindMethod + write FOnFindMethod; + property OnSetMethodProperty: TSetMethodPropertyEvent + read FOnSetMethodProperty write FOnSetMethodProperty; + property OnSetName: TSetNameEvent read FOnSetName write FOnSetName; + property OnReferenceName: TReferenceNameEvent read FOnReferenceName + write FOnReferenceName; + property OnAncestorNotFound: TAncestorNotFoundEvent + read FOnAncestorNotFound write FOnAncestorNotFound; + property OnCreateComponent: TCreateComponentEvent + read FOnCreateComponent write FOnCreateComponent; + property OnFindComponentClass: TFindComponentClassEvent + read FOnFindComponentClass write FOnFindComponentClass; + property OnReadStringProperty: TReadWriteStringPropertyEvent + read FOnReadStringProperty write FOnReadStringProperty; + property onenumerror: enumerroreventty read fonenumerror write fonenumerror; + property onseterror: seterroreventty read fonseterror write fonseterror; + end; + + TAbstractObjectWriter = class + protected + fwriter: twriter; + public + { Begin/End markers. Those ones who don't have an end indicator, use + "EndList", after the occurrence named in the comment. Note that this + only counts for "EndList" calls on the same level; each BeginXXX call + increases the current level. } + procedure BeginCollection; virtual; abstract; { Ends with the next "EndList" } + procedure BeginComponent(Component: TComponent; Flags: TFilerFlags; + ChildPos: Integer); virtual; abstract; { Ends after the second "EndList" } + procedure BeginList; virtual; abstract; + procedure EndList; virtual; abstract; + procedure BeginProperty(const PropName: String); virtual; abstract; + procedure EndProperty; virtual; abstract; + //Please don't use write, better use WriteBinary whenever possible + procedure Write(const Buffer; Count: Longint); virtual;abstract; + + procedure WriteBinary(const Buffer; Count: Longint); virtual; abstract; + procedure WriteBoolean(Value: Boolean); virtual; abstract; + // procedure WriteChar(Value: Char); +{$ifndef FPUNONE} + procedure WriteFloat(const Value: Extended); virtual; abstract; + procedure WriteSingle(const Value: Single); virtual; abstract; + procedure WriteDate(const Value: TDateTime); virtual; abstract; +{$endif} + procedure WriteCurrency(const Value: Currency); virtual; abstract; + procedure WriteIdent(const Ident: string); virtual; abstract; + procedure WriteInteger(Value: Int64); virtual; abstract; + procedure WriteUInt64(Value: QWord); virtual; abstract; + procedure WriteVariant(const Value: Variant); virtual; abstract; + procedure WriteMethodName(const Name: String); virtual; abstract; + procedure WriteSet(Value: LongInt; SetType: Pointer); virtual; abstract; + procedure WriteString(const Value: String); virtual; abstract; + procedure Writeutf8String(const Value: utf8String); virtual; abstract; + procedure WriteWideString(const Value: WideString);virtual;abstract; + procedure WriteUnicodeString(const Value: UnicodeString);virtual;abstract; + end; + + TBinaryObjectWriter = class(TAbstractObjectWriter) + protected + FStream: TStream; + FBuffer: Pointer; + FBufSize: Integer; + FBufPos: Integer; + FBufEnd: Integer; + FSignatureWritten: Boolean; + + procedure WriteWord(w : word); {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} + procedure WriteDWord(lw : longword); {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} + procedure WriteQWord(qw : qword); {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} +{$ifndef FPUNONE} + procedure WriteExtended(e : extended); {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} +{$endif} + procedure FlushBuffer; + procedure WriteValue(Value: TValueType); + public + constructor Create(Stream: TStream; BufSize: Integer); + destructor Destroy; override; + + procedure BeginCollection; override; + procedure BeginComponent(Component: TComponent; Flags: TFilerFlags; + ChildPos: Integer); override; + procedure BeginList; override; + procedure EndList; override; + procedure BeginProperty(const PropName: String); override; + procedure EndProperty; override; + + //Please don't use write, better use WriteBinary whenever possible + procedure Write(const Buffer; Count: Longint); override; + procedure WriteBinary(const Buffer; Count: LongInt); override; + procedure WriteBoolean(Value: Boolean); override; +{$ifndef FPUNONE} + procedure WriteFloat(const Value: Extended); override; + procedure WriteSingle(const Value: Single); override; + procedure WriteDate(const Value: TDateTime); override; +{$endif} + procedure WriteCurrency(const Value: Currency); override; + procedure WriteIdent(const Ident: string); override; + procedure WriteInteger(Value: Int64); override; + procedure WriteUInt64(Value: QWord); override; + procedure WriteMethodName(const Name: String); override; + procedure WriteSet(Value: LongInt; SetType: Pointer); override; + procedure WriteStr(const Value: String); + procedure WriteString(const Value: String); override; + procedure Writeutf8String(const Value: utf8String); override; + procedure WriteWideString(const Value: WideString); override; + procedure WriteUnicodeString(const Value: UnicodeString); override; + procedure WriteVariant(const VarValue: Variant);override; + end; + + twriter = class(tfiler) + private + FDestroyDriver: Boolean; + FOnWriteMethodProperty: TWriteMethodPropertyEvent; + FOnWriteStringProperty:TReadWriteStringPropertyEvent; + procedure AddToAncestorList(Component: tcomponent); + procedure WriteComponentData(Instance: tcomponent); + Procedure DetermineAncestor(Component: tcomponent); + procedure DoFindAncestor(Component : tcomponent); + protected + FPropPath: String; + FAncestors: tstringlist; + FAncestorPos: Integer; + FRootAncestor: tcomponent; + FOnFindAncestor: TFindAncestorEvent; + FDriver: TAbstractObjectWriter; + FCurrentPos: Integer; + procedure SetRoot(ARoot: tcomponent); override; + procedure WriteBinary(AWriteData: TStreamProc); + procedure WriteProperty(Instance: tpersistent; PropInfo: Pointer); + procedure WriteProperties(Instance: tpersistent); + procedure WriteChildren(Component: tcomponent); + function CreateDriver(Stream: TStream; + BufSize: Integer): TAbstractObjectWriter; virtual; + function getclassname(const aobj: tobject): shortstring; virtual; + public + constructor Create(ADriver: TAbstractObjectWriter); overload; + constructor Create(Stream: TStream; BufSize: Integer); overload; + destructor Destroy; override; + procedure DefineProperty(const Name: string; + ReadData: TReaderProc; AWriteData: TWriterProc; + HasData: Boolean); override; + procedure DefineBinaryProperty(const Name: string; + ReadData, AWriteData: TStreamProc; + HasData: Boolean); override; + //Please don't use write, better use WriteBinary whenever possible + //uuups, WriteBinary is protected .. + procedure Write(const Buffer; Count: Longint); virtual; + procedure WriteBoolean(Value: Boolean); + procedure WriteCollection(Value: TCollection); + procedure WriteComponent(Component: tcomponent); + procedure WriteChar(Value: Char); + procedure WriteWideChar(Value: WideChar); + procedure WriteDescendent(ARoot: tcomponent; AAncestor: tcomponent); +{$ifndef FPUNONE} + procedure WriteFloat(const Value: Extended); + procedure WriteSingle(const Value: Single); + procedure WriteDate(const Value: TDateTime); +{$endif} + procedure WriteCurrency(const Value: Currency); + procedure WriteIdent(const Ident: string); + procedure WriteInteger(Value: Longint); overload; + procedure WriteInteger(Value: Int64); overload; + procedure writeset(value: longword; settype: ptypeinfo); + procedure writeenum(value: longint; enumtype: ptypeinfo); + procedure WriteListBegin; + procedure WriteListEnd; + procedure WriteRootComponent(ARoot: tcomponent); + procedure WriteString(const Value: string); + procedure Writeutf8String(const Value: utf8string); + procedure WriteWideString(const Value: WideString); + procedure WriteUnicodeString(const Value: UnicodeString); + procedure WriteVariant(const VarValue: Variant); + property RootAncestor: tcomponent read FRootAncestor write FRootAncestor; + property OnFindAncestor: TFindAncestorEvent read FOnFindAncestor write FOnFindAncestor; + property OnWriteMethodProperty: TWriteMethodPropertyEvent read FOnWriteMethodProperty write FOnWriteMethodProperty; + property OnWriteStringProperty: TReadWriteStringPropertyEvent read FOnWriteStringProperty write FOnWriteStringProperty; + + property Driver: TAbstractObjectWriter read FDriver; + property PropertyPath: string read FPropPath; + end; + +TStringsEnumerator = class + private + FStrings: TStrings; + FPosition: Integer; + public + constructor Create(AStrings: TStrings); + function GetCurrent: String; + function MoveNext: Boolean; + property Current: String read GetCurrent; + end; + +{ tstrings class } + + tstrings = class(tpersistent) + private + FSpecialCharsInited : boolean; + FQuoteChar : Char; + FDelimiter : Char; + FNameValueSeparator : Char; + FUpdateCount: Integer; + FAdapter: IStringsAdapter; + FLBS : TTextLineBreakStyle; + FStrictDelimiter : Boolean; + function GetCommaText: string; + function GetName(Index: Integer): string; + function GetValue(const Name: string): string; + Function GetLBS : TTextLineBreakStyle; + Procedure SetLBS (AValue : TTextLineBreakStyle); + procedure ReadData(Reader: TReader); + procedure SetCommaText(const Value: string); + procedure SetStringsAdapter(const Value: IStringsAdapter); + procedure SetValue(const Name, Value: string); + procedure SetDelimiter(c:Char); + procedure SetQuoteChar(c:Char); + procedure SetNameValueSeparator(c:Char); + procedure WriteData(Writer: TWriter); + protected + procedure DefineProperties(Filer: tfiler); override; + procedure Error(const Msg: string; Data: Integer); overload; + procedure Error(const Msg: pstring; Data: Integer); overload; + function Get(Index: Integer): string; virtual; abstract; + function GetCapacity: Integer; virtual; + function GetCount: Integer; virtual; abstract; + function GetObject(Index: Integer): TObject; virtual; + function GetTextStr: string; virtual; + procedure Put(Index: Integer; const S: string); virtual; + procedure PutObject(Index: Integer; AObject: TObject); virtual; + procedure SetCapacity(NewCapacity: Integer); virtual; + procedure SetTextStr(const Value: string); virtual; + procedure SetUpdateState(Updating: Boolean); virtual; + property UpdateCount: Integer read FUpdateCount; + Function DoCompareText(const s1,s2 : string) : PtrInt; virtual; + Function GetDelimitedText: string; + Procedure SetDelimitedText(Const AValue: string); + Function GetValueFromIndex(Index: Integer): string; + Procedure SetValueFromIndex(Index: Integer; const Value: string); + Procedure CheckSpecialChars; + public + destructor Destroy; override; + function Add(const S: string): Integer; virtual; + function AddObject(const S: string; AObject: TObject): Integer; virtual; + procedure Append(const S: string); + procedure AddStrings(TheStrings: tstrings); overload; virtual; + procedure AddStrings(const TheStrings: array of string); overload; virtual; + procedure Assign(Source: tpersistent); override; + procedure BeginUpdate; + procedure Clear; virtual; abstract; + procedure Delete(Index: Integer); virtual; abstract; + procedure EndUpdate; + function Equals(Obj: TObject): Boolean; overload; override; + function Equals(TheStrings: tstrings): Boolean; reintroduce; overload; + procedure Exchange(Index1, Index2: Integer); virtual; + function GetEnumerator: TStringsEnumerator; + function GetText: PChar; virtual; + function IndexOf(const S: string): Integer; virtual; + function IndexOfName(const Name: string): Integer; virtual; + function IndexOfObject(AObject: TObject): Integer; virtual; + procedure Insert(Index: Integer; const S: string); virtual; abstract; + procedure InsertObject(Index: Integer; const S: string; + AObject: TObject); + procedure LoadFromFile(const FileName: string); virtual; + procedure LoadFromStream(Stream: TStream); virtual; + procedure Move(CurIndex, NewIndex: Integer); virtual; + procedure SaveToFile(const FileName: string); virtual; + procedure SaveToStream(Stream: TStream); virtual; + procedure SetText(TheText: PChar); virtual; + procedure GetNameValue(Index : Integer; Out AName,AValue : String); + function ExtractName(Const S:String):String; + Property TextLineBreakStyle : TTextLineBreakStyle Read GetLBS Write SetLBS; + property Delimiter: Char read FDelimiter write SetDelimiter; + property DelimitedText: string read GetDelimitedText write SetDelimitedText; + Property StrictDelimiter : Boolean Read FStrictDelimiter Write FStrictDelimiter; + property QuoteChar: Char read FQuoteChar write SetQuoteChar; + Property NameValueSeparator : Char Read FNameValueSeparator Write SetNameValueSeparator; + property ValueFromIndex[Index: Integer]: string read GetValueFromIndex write SetValueFromIndex; + property Capacity: Integer read GetCapacity write SetCapacity; + property CommaText: string read GetCommaText write SetCommaText; + property Count: Integer read GetCount; + property Names[Index: Integer]: string read GetName; + property Objects[Index: Integer]: TObject read GetObject write PutObject; + property Values[const Name: string]: string read GetValue write SetValue; + property Strings[Index: Integer]: string read Get write Put; default; + property Text: string read GetTextStr write SetTextStr; + property StringsAdapter: IStringsAdapter read FAdapter write SetStringsAdapter; + end; + + TStringListSortCompare = function(List: tstringlist; Index1, Index2: Integer): Integer; + + tstringlist = class(tstrings) + private + FList: PStringItemList; + FCount: Integer; + FCapacity: Integer; + FOnChange: TNotifyEvent; + FOnChanging: TNotifyEvent; + FDuplicates: TDuplicates; + FCaseSensitive : Boolean; + FSorted: Boolean; + FOwnsObjects : Boolean; + procedure ExchangeItems(Index1, Index2: Integer); + procedure Grow; + procedure InternalClear; + procedure QuickSort(L, R: Integer; CompareFn: TStringListSortCompare); + procedure SetSorted(Value: Boolean); + procedure SetCaseSensitive(b : boolean); + protected + procedure Changed; virtual; + procedure Changing; virtual; + function Get(Index: Integer): string; override; + function GetCapacity: Integer; override; + function GetCount: Integer; override; + function GetObject(Index: Integer): TObject; override; + procedure Put(Index: Integer; const S: string); override; + procedure PutObject(Index: Integer; AObject: TObject); override; + procedure SetCapacity(NewCapacity: Integer); override; + procedure SetUpdateState(Updating: Boolean); override; + procedure InsertItem(Index: Integer; const S: string); overload; virtual; + procedure InsertItem(Index: Integer; const S: string; O: TObject); + overload; virtual; + Function DoCompareText(const s1,s2 : string) : PtrInt; override; + + public + destructor Destroy; override; + function Add(const S: string): Integer; override; + procedure Clear; override; + procedure Delete(Index: Integer); override; + procedure Exchange(Index1, Index2: Integer); override; + function Find(const S: string; Out Index: Integer): Boolean; virtual; + function IndexOf(const S: string): Integer; override; + procedure Insert(Index: Integer; const S: string); override; + procedure Sort; virtual; + procedure CustomSort(CompareFn: TStringListSortCompare); virtual; + property Duplicates: TDuplicates read FDuplicates write FDuplicates; + property Sorted: Boolean read FSorted write SetSorted; + property CaseSensitive: Boolean read FCaseSensitive write SetCaseSensitive; + property OnChange: TNotifyEvent read FOnChange write FOnChange; + property OnChanging: TNotifyEvent read FOnChanging write FOnChanging; + property OwnsObjects : boolean read FOwnsObjects write FOwnsObjects; + end; + + TStream = class(TObject) + private + protected + procedure InvalidSeek; virtual; + procedure Discard(const Count: Int64); + procedure DiscardLarge(Count: int64; const MaxBufferSize: Longint); + procedure FakeSeekForward(Offset: Int64; const Origin: TSeekOrigin; const Pos: Int64); + function GetPosition: Int64; virtual; + procedure SetPosition(const Pos: Int64); virtual; + function GetSize: Int64; virtual; + procedure SetSize64(const NewSize: Int64); virtual; + procedure SetSize(NewSize: Longint); overload; virtual; + procedure SetSize(const NewSize: Int64); overload; virtual; + procedure ReadNotImplemented; + procedure WriteNotImplemented; + function getmemory: pointer; virtual; + public + function Read(var Buffer; Count: Longint): Longint; virtual; overload; + function Write(const Buffer; Count: Longint): Longint; virtual; overload; + function read(var buffer; const count: longint; + out acount: longint): syserrorty; virtual; overload; + function write(const buffer; const count: longint; + out acount: longint): syserrorty; virtual; overload; + function Seek(Offset: Longint; Origin: Word): Longint; overload; virtual; + function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; + overload; virtual; + function seek(const offset: int64; const origin: tseekorigin; + out newpos: int64): syserrorty; overload; virtual; + procedure ReadBuffer(var Buffer; Count: Longint); + function tryreadbuffer(var buffer; count: longint): syserrorty; + procedure WriteBuffer(const Buffer; Count: Longint); + function trywritebuffer(const buffer; count: longint): syserrorty; + function readdatastring: string; virtual; + //read available data + procedure writedatastring(const value: rawbytestring); virtual; + function CopyFrom(Source: TStream; Count: Int64): Int64; + function ReadComponent(Instance: TComponent): TComponent; + function ReadComponentRes(Instance: TComponent): TComponent; + procedure WriteComponent(Instance: TComponent); + procedure WriteComponentRes(const ResName: string; Instance: TComponent); + procedure WriteDescendent(Instance, Ancestor: TComponent); + procedure WriteDescendentRes(const ResName: string; Instance, Ancestor: TComponent); + procedure WriteResourceHeader(const ResName: string; {!!!:out} var FixupInfo: Integer); + procedure FixupResourceHeader(FixupInfo: Integer); + procedure ReadResHeader; + function ReadByte : Byte; + function ReadWord : Word; + function ReadDWord : Cardinal; + function ReadQWord : QWord; + function ReadAnsiString : String; + procedure WriteByte(b : Byte); + procedure WriteWord(w : Word); + procedure WriteDWord(d : Cardinal); + procedure WriteQWord(q : QWord); + Procedure WriteAnsiString (const S : String); + property Position: Int64 read GetPosition write SetPosition; + property Size: Int64 read GetSize write SetSize64; + property memory: pointer read getmemory; //nil if not suported + end; + + THandleStream = class(TStream) + private + protected + FHandle: filehandlety; + procedure SetSize(NewSize: Longint); override; + procedure SetSize(const NewSize: Int64); override; + public + constructor Create(AHandle: THandle); + function Read(var Buffer; Count: Longint): Longint; override; + function Write(const Buffer; Count: Longint): Longint; override; + function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override; + property Handle: filehandlety read FHandle; + function releasehandle(): filehandlety virtual; + end; + + TFileStream = class(THandleStream) + Private + FFileName : String; + public + constructor Create(const AFileName: string; Mode: Word); overload; + constructor Create(const AFileName: string; Mode: Word; Rights: Cardinal); + overload; + destructor Destroy; override; + property FileName : String Read FFilename; + end; + + TCustomMemoryStream = class(TStream) + private + protected + FMemory: Pointer; + FSize, FPosition: PtrInt; + Function GetSize : Int64; Override; + function GetPosition: Int64; Override; + procedure SetPointer(Ptr: Pointer; ASize: PtrInt); + function getmemory: pointer; override; + public + function Read(var Buffer; Count: LongInt): LongInt; override; + function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override; + procedure SaveToStream(Stream: TStream); + procedure SaveToFile(const FileName: string); + property memory: Pointer read getmemory; + property position1: ptrint read fposition; + property size1: ptrint read fsize; + end; + + TMemoryStream = class(TCustomMemoryStream) + private + FCapacity: PtrInt; + protected + procedure SetCapacity(NewCapacity: PtrInt) virtual; + function getcapacity: ptrint virtual; + function Realloc(var NewCapacity: PtrInt): Pointer; virtual; + public + destructor Destroy; override; + procedure Clear; + procedure LoadFromStream(Stream: TStream); + procedure LoadFromFile(const FileName: string); + procedure SetSize({$ifdef CPU64}const{$endif CPU64} NewSize: PtrInt); override; + function Write(const Buffer; Count: LongInt): LongInt; override; + property Capacity: PtrInt read getcapacity write SetCapacity; + end; + + TStringStream = class(TStream) + private + FDataString: string; + FPosition: Integer; + protected + Function GetSize : Int64; Override; + function GetPosition: Int64; Override; + procedure SetSize(NewSize: Longint); override; + function getmemory: pointer; override; + public + constructor Create(const AString: string); + function Read(var Buffer; Count: Longint): Longint; override; + function ReadString(Count: Longint): string; + function Seek(Offset: Longint; Origin: Word): Longint; override; + function Write(const Buffer; Count: Longint): Longint; override; + procedure WriteString(const AString: string); + property DataString: string read FDataString; + end; +{$ifdef FPC} +{$ifdef UNICODE} + TResourceStream = class(TCustomMemoryStream) + private + Res: TFPResourceHandle; + Handle: TFPResourceHGLOBAL; + procedure Initialize(Instance: TFPResourceHMODULE; Name, ResType: PWideChar; NameIsID: Boolean); + public + constructor Create(Instance: TFPResourceHMODULE; const ResName: WideString; ResType: PWideChar); + constructor CreateFromID(Instance: TFPResourceHMODULE; ResID: Integer; ResType: PWideChar); + destructor Destroy; override; + end; +{$else} + TResourceStream = class(TCustomMemoryStream) + private + Res: TFPResourceHandle; + Handle: TFPResourceHGLOBAL; + procedure Initialize(Instance: TFPResourceHMODULE; Name, ResType: PChar; NameIsID: Boolean); + public + constructor Create(Instance: TFPResourceHMODULE; const ResName: string; ResType: PChar); + constructor CreateFromID(Instance: TFPResourceHMODULE; ResID: Integer; ResType: PChar); + destructor Destroy; override; + end; +{$endif UNICODE} +{$endif} + + TOwnerStream = Class(TStream) + private + Protected + FOwner : Boolean; + FSource : TStream; + Public + Constructor Create(ASource : TStream); + Destructor Destroy; override; + Property Source : TStream Read FSource; + Property SourceOwner : Boolean Read Fowner Write FOwner; + end; + + TFindGlobalComponent = function(const Name: string): TComponent; + TInitComponentHandler = function(Instance: TComponent; RootAncestor : TClass): boolean; + +procedure RegisterFindGlobalComponentProc(AFindGlobalComponent: TFindGlobalComponent); +procedure UnregisterFindGlobalComponentProc(AFindGlobalComponent: TFindGlobalComponent); +function FindGlobalComponent(const Name: string): TComponent; + +function InitInheritedComponent(Instance: TComponent; RootAncestor: TClass): Boolean; +function InitComponentRes(const ResName: string; Instance: TComponent): Boolean; +function ReadComponentRes(const ResName: string; Instance: TComponent): TComponent; +function ReadComponentResEx(HInstance: THandle; const ResName: string): TComponent; +function ReadComponentResFile(const FileName: string; Instance: TComponent): TComponent; +procedure WriteComponentResFile(const FileName: string; Instance: TComponent); +procedure RegisterInitComponentHandler(ComponentClass: TComponentClass; Handler: TInitComponentHandler); + +procedure GlobalFixupReferences; +procedure GetFixupReferenceNames(Root: TComponent; Names: TStrings); +procedure GetFixupInstanceNames(Root: TComponent; + const ReferenceRootName: string; Names: TStrings); +procedure RedirectFixupReferences(Root: TComponent; const OldRootName, + NewRootName: string); +procedure RemoveFixupReferences(Root: TComponent; const RootName: string); +procedure RemoveFixups(Instance: TPersistent); +Function FindNestedComponent(Root : TComponent; APath : String; CStyle : Boolean = True) : TComponent; + +procedure BeginGlobalLoading; +procedure NotifyGlobalLoading; +procedure EndGlobalLoading; +procedure beginsuspendgloballoading; +procedure endsuspendgloballoading; + +function CollectionsEqual(C1, C2: TCollection): Boolean; overload; +function CollectionsEqual(C1, C2: TCollection; Owner1, + Owner2: TComponent): Boolean; overload; + +procedure RegisterClass(AClass: TPersistentClass); +procedure RegisterClasses(AClasses: array of TPersistentClass); +procedure RegisterClassAlias(AClass: TPersistentClass; const Alias: string); +procedure UnRegisterClass(AClass: TPersistentClass); +procedure UnRegisterClasses(AClasses: array of TPersistentClass); +procedure UnRegisterModuleClasses(Module: HMODULE); +function FindClass(const AClassName: string): TPersistentClass; +function GetClass(const AClassName: string): TPersistentClass; + +function ExtractStrings(Separators, WhiteSpace: TSysCharSet; Content: PChar; Strings: TStrings): Integer; + +{$ifndef FPUNONE} +{$IFNDEF FPC_HAS_TYPE_EXTENDED} +function ExtendedToDouble(e : pointer) : double; +procedure DoubleToExtended(d : double; e : pointer); +{$endif} +{$endif} + +{$ifndef FPC} +resourcestring + SStreamNoReading = 'Reading from %s is not supported'; + SStreamNoWriting = 'Writing to %s is not supported'; + SRangeError = 'Range error'; + SStreamInvalidSeek = 'Invalid stream operation %s.Seek'; + SEmptyStreamIllegalReader = 'Illegal Nil stream for TReader constructor'; + SEmptyStreamIllegalWriter = 'Illegal Nil stream for TWriter constructor'; + SErrNoVariantSupport = 'No variant support for properties. Please use the variants unit in your project and recompile'; + SUnsupportedPropertyVariantType = 'Unsupported property variant type %d'; + SUnknownPropertyType = 'Unknown property type %d'; + +Const + FilerSignature : Array[1..4] of char = 'TPF0'; +{$endif} + +implementation +uses + {$ifdef MSWINDOWS}windows,{$endif}rtlconsts,msesysintf,msesys; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{$ifndef FPC} +{$define endian_little} +{$define FPC_HAS_TYPE_EXTENDED} +{$endif} + +Const + // Ratio of Pointer and Word Size. + WordRatio = SizeOf(Pointer) Div SizeOf(Word); + +Type + TLinkedListItem = Class + Public + Next : TLinkedListItem; + end; + TLinkedListItemClass = Class of TLinkedListItem; + + { TLinkedListVisitor } + + TLinkedListVisitor = Class + Function Visit(Item : TLinkedListItem) : Boolean; virtual; abstract; + end; + { TLinkedList } + + TLinkedList = Class + private + FItemClass: TLinkedListItemClass; + FRoot: TLinkedListItem; + function GetCount: Integer; + Public + Constructor Create(AnItemClass : TLinkedListItemClass); virtual; + Destructor Destroy; override; + Procedure Clear; + Function Add : TLinkedListItem; + Procedure ForEach(Visitor: TLinkedListVisitor); + Procedure RemoveItem(Item : TLinkedListItem; FreeItem : Boolean = False); + Property Root : TLinkedListItem Read FRoot; + Property ItemClass : TLinkedListItemClass Read FItemClass; + Property Count : Integer Read GetCount; + end; + +{ TLinkedList } + +function TLinkedList.GetCount: Integer; + +Var + I : TLinkedListItem; + +begin + I:=FRoot; + Result:=0; + While I<>Nil do + begin + I:=I.Next; + Inc(Result); + end; +end; + +constructor TLinkedList.Create(AnItemClass: TLinkedListItemClass); +begin + FItemClass:=AnItemClass; +end; + +destructor TLinkedList.Destroy; +begin + Clear; + inherited Destroy; +end; + +procedure TLinkedList.Clear; + +Var + I : TLinkedListItem; + +begin + // Can't use visitor, because it'd kill the next pointer... + I:=FRoot; + While I<>Nil do + begin + FRoot:=I; + I:=I.Next; + FRoot.Next:=Nil; + FreeAndNil(FRoot); + end; +end; + +function TLinkedList.Add: TLinkedListItem; +begin + Result:=FItemClass.Create; + Result.Next:=FRoot; + FRoot:=Result; +end; + +procedure TLinkedList.ForEach(Visitor : TLinkedListVisitor); + +Var + I : TLinkedListItem; + +begin + I:=FRoot; + While (I<>Nil) and Visitor.Visit(I) do + I:=I.Next; +end; + +procedure TLinkedList.RemoveItem(Item: TLinkedListItem; FreeItem : Boolean = False); + +Var + I : TLinkedListItem; + +begin + If (Item<>Nil) and (FRoot<>Nil) then + begin + If (Item=FRoot) then + FRoot:=Item.Next + else + begin + I:=FRoot; + While (I.Next<>Nil) and (I.Next<>Item) do + I:=I.Next; + If (I.Next=Item) then + I.Next:=Item.Next; + end; + If FreeItem Then + Item.Free; + end; +end; + + +{****************************************************************************} +{* TPersistent *} +{****************************************************************************} + +{$ifndef FPC} +function tpersistent.Equals(Obj: TObject) : boolean; +begin + result:= Obj = Self; +end; + +function tpersistent.QueryInterface(const IID: TGUID; + out Obj): HResult; stdcall; +begin + if GetInterface(IID, Obj) then + Result := S_OK + else + Result := E_NOINTERFACE; +end; + +function tpersistent._AddRef: Integer; stdcall; +begin + Result := -1; +end; + +function tpersistent._Release: Integer; stdcall; +begin + Result := -1; +end; +{$endif} + +procedure TPersistent.AssignError(Source: TPersistent); + +Var SourceName : String; + +begin + If Source<>Nil then + SourceName:=Source.ClassName + else + SourceName:='Nil'; + raise EConvertError.CreateFmt (SAssignError,[SourceName,ClassName]); +end; + + + +procedure TPersistent.AssignTo(Dest: TPersistent); + + +begin + Dest.AssignError(Self); +end; + + +procedure TPersistent.DefineProperties(Filer: TFiler); + +begin +end; + + +function TPersistent.GetOwner: TPersistent; + +begin + Result:=Nil; +end; + +destructor TPersistent.Destroy; +begin +// If Assigned(FObservers) then +// begin +// FPONotifyObservers(Self,ooFree,Nil); +// FreeAndNil(FObservers); +// end; + inherited Destroy; +end; +{ +procedure TPersistent.FPOAttachObserver(AObserver: TObject); +Var + I : IFPObserver; + +begin + If Not AObserver.GetInterface(SGUIDObserver,I) then + Raise EObserver.CreateFmt(SErrNotObserver,[AObserver.ClassName]); + If not Assigned(FObservers) then + FObservers:=TFPList.Create; + FObservers.Add(AObserver); +end; + +procedure TPersistent.FPODetachObserver(AObserver: TObject); +Var + I : IFPObserver; + +begin + If Not AObserver.GetInterface(SGUIDObserver,I) then + Raise EObserver.CreateFmt(SErrNotObserver,[AObserver.ClassName]); + If Assigned(FObservers) then + begin + FObservers.Remove(AObserver); + If (FObservers.Count=0) then + FreeAndNil(FObservers); + end; +end; + +procedure TPersistent.FPONotifyObservers(ASender: TObject; + AOperation: TFPObservedOperation; Data : Pointer); +Var + O : TObject; + I : Integer; + Obs : IFPObserver; + +begin + If Assigned(FObservers) then + For I:=FObservers.Count-1 downto 0 do + begin + O:=TObject(FObservers[i]); + If O.GetInterface(SGUIDObserver,Obs) then + Obs.FPOObservedChanged(Self,AOperation,Data); + end; +end; +} +procedure TPersistent.Assign(Source: TPersistent); + +begin + If Source<>Nil then + Source.AssignTo(Self) + else + AssignError(Nil); +end; + +function TPersistent.GetNamePath: string; + +Var OwnerName :String; + TheOwner: TPersistent; + +begin + Result:=ClassName; + TheOwner:=GetOwner; + If TheOwner<>Nil then + begin + OwnerName:=TheOwner.GetNamePath; + If OwnerName<>'' then Result:=OwnerName+'.'+Result; + end; +end; + +{****************************************************************************} +{* TComponent *} +{****************************************************************************} +(* +function TComponent.GetComObject: IUnknown; +begin + { Check if VCLComObject is not assigned - we need to create it by } + { the call to CreateVCLComObject routine. If in the end we are still } + { have no valid VCLComObject pointer we need to raise an exception } + if not Assigned(VCLComObject) then + begin + if Assigned(CreateVCLComObjectProc) then + CreateVCLComObjectProc(Self); + if not Assigned(VCLComObject) then + raise EComponentError.CreateFmt(SNoComSupport,[Name]); + end; + { VCLComObject is IVCComObject but we need to return IUnknown } + IVCLComObject(VCLComObject).QueryInterface(IUnknown, Result); +end; +*) +Function TComponent.GetComponent(AIndex: Integer): TComponent; + +begin + If not assigned(FComponents) then + Result:=Nil + else + Result:=TComponent(FComponents.Items[Aindex]); +end; +{ +function TComponent.IsImplementorOf (const Intf:IInterface):boolean; +var ref : IInterfaceComponentReference; +begin + result:=assigned(intf) and supports(intf,IInterfaceComponentReference,ref); + if result then + result:=ref.getcomponent=self; +end; + +procedure TComponent.ReferenceInterface(const intf:IInterface;op:TOperation); +var ref : IInterfaceComponentReference; + comp : TComponent; +begin + if assigned(intf) and supports(intf,IInterfaceComponentReference,ref) then + begin + comp:=ref.getcomponent; + if op = opInsert then + comp.FreeNotification(Self) + else + comp.RemoveFreeNotification(Self); + end; +end; +} +Function TComponent.GetComponentCount: Integer; + +begin + If not assigned(FComponents) then + result:=0 + else + Result:=FComponents.Count; +end; + + +Function TComponent.GetComponentIndex: Integer; + +begin + If Assigned(FOwner) and Assigned(FOwner.FComponents) then + Result:=FOWner.FComponents.IndexOf(Self) + else + Result:=-1; +end; + + +Procedure TComponent.Insert(AComponent: TComponent); + +begin + If not assigned(FComponents) then + FComponents:=TFpList.Create; + FComponents.Add(AComponent); + AComponent.FOwner:=Self; +end; + + +procedure tcomponent.readleft(reader: treader); + +var + int1: integer; +begin + int1:= reader.readinteger; + if (int1 < 0) or (int1 > $7fff) then begin + int1:= 0; //limit to positive values + end; + longrec(fdesigninfo).lo:= int1; +end; + + +procedure tcomponent.readtop(reader: treader); +var + int1: integer; +begin + int1:= reader.readinteger; + if (int1 < 0) or (int1 > $7fff) then begin + int1:= 0; //limit to positive values + end; + longrec(fdesigninfo).hi:= int1; +end; + + +Procedure TComponent.Remove(AComponent: TComponent); + +begin + AComponent.FOwner:=Nil; + If assigned(FCOmponents) then + begin + FComponents.Remove(AComponent); + IF FComponents.Count=0 then + begin + FComponents.Free; + FComponents:=Nil; + end; + end; +end; + + +Procedure TComponent.RemoveNotification(AComponent: TComponent); + +begin + if FFreeNotifies<>nil then + begin + FFreeNotifies.Remove(AComponent); + if FFreeNotifies.Count=0 then + begin + FFreeNotifies.Free; + FFreeNotifies:=nil; + Exclude(FComponentState,csFreeNotification); + end; + end; +end; + + +Procedure TComponent.SetComponentIndex(Value: Integer); + +Var Temp,Count : longint; + +begin + If Not assigned(Fowner) then exit; + Temp:=getcomponentindex; + If temp<0 then exit; + If value<0 then value:=0; + Count:=Fowner.FComponents.Count; + If Value>=Count then value:=count-1; + If Value<>Temp then + begin + FOWner.FComponents.Delete(Temp); + FOwner.FComponents.Insert(Value,Self); + end; +end; + + +Procedure TComponent.SetReference(Enable: Boolean); + +var + Field: ^TComponent; +begin + if Assigned(Owner) then + begin + Field := Owner.FieldAddress(Name); + if Assigned(Field) then + if Enable then + Field^ := Self + else + Field^ := nil; + end; +end; + + +Procedure TComponent.WriteLeft(Writer: TWriter); + +begin + Writer.WriteInteger(smallint(LongRec(FDesignInfo).Lo)); +end; + + +Procedure TComponent.WriteTop(Writer: TWriter); + +begin + Writer.WriteInteger(smallint(LongRec(FDesignInfo).Hi)); +end; + + +Procedure TComponent.ChangeName(const NewName: TComponentName); + +begin + FName:=NewName; +end; + + +Procedure TComponent.DefineProperties(Filer: TFiler); + +Var Ancestor : TComponent; + Temp : longint; + +begin + Temp:=0; + Ancestor:=TComponent(Filer.Ancestor); + If Assigned(Ancestor) then Temp:=Ancestor.FDesignInfo; + Filer.Defineproperty('left',{$ifdef FPC}@{$endif}readleft, + {$ifdef FPC}@{$endif}writeleft, + (longrec(FDesignInfo).Lo<>Longrec(temp).Lo)); + Filer.Defineproperty('top',{$ifdef FPC}@{$endif}readtop, + {$ifdef FPC}@{$endif}writetop, + (longrec(FDesignInfo).Hi<>Longrec(temp).Hi)); +end; + + +Procedure TComponent.GetChildren(Proc: TGetChildProc; Root: TComponent); + +begin + // Does nothing. +end; + + +Function TComponent.GetChildOwner: TComponent; + +begin + Result:=Nil; +end; + + +Function TComponent.GetChildParent: TComponent; + +begin + Result:=Self; +end; + +{ +Function TComponent.GetEnumerator: TComponentEnumerator; + +begin + Result:=TComponentEnumerator.Create(Self); +end; +} +Function TComponent.GetNamePath: string; + +begin + Result:=FName; +end; + + +Function TComponent.GetOwner: TPersistent; + +begin + Result:=FOwner; +end; + + +Procedure TComponent.Loaded; + +begin + Exclude(FComponentState,csLoading); +end; + +Procedure TComponent.Loading; + +begin + Include(FComponentState,csLoading); +end; + + +Procedure TComponent.Notification(AComponent: TComponent; + Operation: TOperation); + +Var Runner : Longint; + +begin + If (Operation=opRemove) and Assigned(FFreeNotifies) then + begin + FFreeNotifies.Remove(AComponent); + If FFreeNotifies.Count=0 then + begin + FFreeNotifies.Free; + FFreenotifies:=Nil; + end; + end; + If assigned(FComponents) then + For Runner:=0 To FComponents.Count-1 do + TComponent(FComponents.Items[Runner]).Notification(AComponent,Operation); +end; + + +procedure TComponent.PaletteCreated; + begin + end; + + +Procedure TComponent.ReadState(Reader: TReader); + +begin + Reader.ReadData(Self); +end; + + +Procedure TComponent.SetAncestor(Value: Boolean); + +Var Runner : Longint; + +begin + If Value then + Include(FComponentState,csAncestor) + else + Exclude(FCOmponentState,csAncestor); + if Assigned(FComponents) then + For Runner:=0 To FComponents.Count-1 do + TComponent(FComponents.Items[Runner]).SetAncestor(Value); +end; + + +Procedure TComponent.SetDesigning(Value: Boolean; SetChildren : Boolean = True); + +Var Runner : Longint; + +begin + If Value then + Include(FComponentState,csDesigning) + else + Exclude(FComponentState,csDesigning); + if Assigned(FComponents) and SetChildren then + For Runner:=0 To FComponents.Count - 1 do + TComponent(FComponents.items[Runner]).SetDesigning(Value); +end; + +Procedure TComponent.SetDesignInstance(Value: Boolean); + +begin + If Value then + Include(FComponentState,csDesignInstance) + else + Exclude(FComponentState,csDesignInstance); +end; + +Procedure TComponent.SetInline(Value: Boolean); + +begin + If Value then + Include(FComponentState,csInline) + else + Exclude(FComponentState,csInline); +end; + + +Procedure TComponent.SetName(const NewName: TComponentName); + +begin + If FName=NewName then exit; + If (NewName<>'') and not IsValidIdent(NewName) then + Raise EComponentError.CreateFmt(SInvalidName,[NewName]); + If Assigned(FOwner) Then + FOwner.ValidateRename(Self,FName,NewName) + else + ValidateRename(Nil,FName,NewName); + SetReference(False); + ChangeName(NewName); + Setreference(True); +end; + + +Procedure TComponent.SetChildOrder(Child: TComponent; Order: Integer); + +begin + // does nothing +end; + + +Procedure TComponent.SetParentComponent(Value: TComponent); + +begin + // Does nothing +end; + + +Procedure TComponent.Updating; + +begin + Include (FComponentState,csUpdating); +end; + + +Procedure TComponent.Updated; + +begin + Exclude(FComponentState,csUpdating); +end; + + +class Procedure TComponent.UpdateRegistry(Register: Boolean; const ClassID, ProgID: string); + +begin + // For compatibility only. +end; + + +Procedure TComponent.ValidateRename(AComponent: TComponent; + const CurName, NewName: string); + +begin +//!! This contradicts the Delphi manual. + If (AComponent<>Nil) and (CompareText(CurName,NewName)<>0) and (AComponent.Owner = Self) and + (FindComponent(NewName)<>Nil) then + raise EComponentError.Createfmt(SDuplicateName,[newname]); + If (csDesigning in FComponentState) and (FOwner<>Nil) then + FOwner.ValidateRename(AComponent,Curname,Newname); +end; + + +Procedure TComponent.ValidateContainer(AComponent: TComponent); + +begin + AComponent.ValidateInsert(Self); +end; + + +Procedure TComponent.ValidateInsert(AComponent: TComponent); + +begin + // Does nothing. +end; + + +Procedure TComponent.WriteState(Writer: TWriter); + +begin + Writer.WriteComponentData(Self); +end; + + +Constructor TComponent.Create(AOwner: TComponent); + +begin + FComponentStyle:=[csInheritable]; + If Assigned(AOwner) then AOwner.InsertComponent(Self); +end; + + +Destructor TComponent.Destroy; + +Var + I : Integer; + C : TComponent; + +begin + Destroying; + If Assigned(FFreeNotifies) then + begin + I:=FFreeNotifies.Count-1; + While (I>=0) do + begin + C:=TComponent(FFreeNotifies.Items[I]); + // Delete, so one component is not notified twice, if it is owned. + FFreeNotifies.Delete(I); + C.Notification (self,opRemove); + If (FFreeNotifies=Nil) then + I:=0 + else if (I>FFreeNotifies.Count) then + I:=FFreeNotifies.Count; + dec(i); + end; + FreeAndNil(FFreeNotifies); + end; + DestroyComponents; + If FOwner<>Nil Then FOwner.RemoveComponent(Self); + inherited destroy; +end; + + +Procedure TComponent.BeforeDestruction; +begin + if not(csDestroying in FComponentstate) then + Destroying; +end; + + +Procedure TComponent.DestroyComponents; + +Var acomponent: TComponent; + +begin + While assigned(FComponents) do + begin + aComponent:=TComponent(FComponents.Last); + Remove(aComponent); + Acomponent.Destroy; + end; +end; + + +Procedure TComponent.Destroying; + +Var Runner : longint; + +begin + If csDestroying in FComponentstate Then Exit; + include (FComponentState,csDestroying); + If Assigned(FComponents) then + for Runner:=0 to FComponents.Count-1 do + TComponent(FComponents.Items[Runner]).Destroying; +end; + + +function TComponent.ExecuteAction(Action: TBasicAction): Boolean; +begin + if Action.HandlesTarget(Self) then + begin + Action.ExecuteTarget(Self); + Result := True; + end + else + Result := False; +end; + + +Function TComponent.FindComponent(const AName: string): TComponent; + +Var I : longint; + +begin + Result:=Nil; + If (AName='') or Not assigned(FComponents) then exit; + For i:=0 to FComponents.Count-1 do + if (CompareText(TComponent(FComponents[I]).Name,AName)=0) then + begin + Result:=TComponent(FComponents.Items[I]); + exit; + end; +end; + +function tcomponent.findtagcomponent(const atag: int32; + const aclass: tcomponentclass): tcomponent; +var + i1: integer; + comp1: tcomponent; +begin + result:= nil; + for i1:= 0 to componentcount - 1 do begin + comp1:= components[i1]; + if (comp1.tag = atag) and + ((aclass = nil) or (comp1 is aclass)) then begin + result:= comp1; + exit; + end; + end; + if result = nil then begin + for i1:= 0 to componentcount - 1 do begin + result:= components[i1].findtagcomponent(atag,aclass); + if result <> nil then begin + exit; + end; + end; + end; +end; + +Procedure TComponent.FreeNotification(AComponent: TComponent); + +begin + If (Owner<>Nil) and (AComponent=Owner) then exit; + If not (Assigned(FFreeNotifies)) then + FFreeNotifies:=TFpList.Create; + If FFreeNotifies.IndexOf(AComponent)=-1 then + begin + FFreeNotifies.Add(AComponent); + AComponent.FreeNotification (self); + end; +end; + + +procedure TComponent.RemoveFreeNotification(AComponent: TComponent); +begin + RemoveNotification(AComponent); + AComponent.RemoveNotification (self); +end; + + +Procedure TComponent.FreeOnRelease; +begin + if Assigned(VCLComObject) then + IVCLComObject(VCLComObject).FreeOnRelease; +end; + + +Function TComponent.GetParentComponent: TComponent; + +begin + Result:=Nil; +end; + + +Function TComponent.HasParent: Boolean; + +begin + Result:=False; +end; + + +Procedure TComponent.InsertComponent(AComponent: TComponent); + +begin + AComponent.ValidateContainer(Self); + ValidateRename(AComponent,'',AComponent.FName); + Insert(AComponent); + AComponent.SetReference(True); + If csDesigning in FComponentState then + AComponent.SetDesigning(true); + Notification(AComponent,opInsert); +end; + + +Procedure TComponent.RemoveComponent(AComponent: TComponent); + +begin + Notification(AComponent,opRemove); + AComponent.SetReference(False); + Remove(AComponent); + Acomponent.Setdesigning(False); + ValidateRename(AComponent,AComponent.FName,''); +end; + + +Function TComponent.SafeCallException(ExceptObject: TObject; + ExceptAddr: Pointer): HResult; +begin + if Assigned(VCLComObject) then + Result := IVCLComObject(VCLComObject).SafeCallException(ExceptObject, ExceptAddr) + else + Result := inherited SafeCallException(ExceptObject, ExceptAddr); +end; + +procedure TComponent.SetSubComponent(ASubComponent: Boolean); +begin + if ASubComponent then + Include(FComponentStyle, csSubComponent) + else + Exclude(FComponentStyle, csSubComponent); +end; + + +function TComponent.UpdateAction(Action: TBasicAction): Boolean; +begin + if Action.HandlesTarget(Self) then + begin + Action.UpdateTarget(Self); + Result := True; + end + else + Result := False; +end; + +{$ifdef FPC} +function TComponent.QueryInterface( +{$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} IID: TGUID; + out Obj): HResult;{$IFNDEF msWINDOWS}cdecl{$ELSE}stdcall{$ENDIF}; +begin + if Assigned(VCLComObject) then + Result := IVCLComObject(VCLComObject).QueryInterface(IID, Obj) + else + if GetInterface(IID, Obj) then + Result := S_OK + else + Result := E_NOINTERFACE; +end; + +function TComponent._AddRef: Integer;{$IFNDEF msWINDOWS}cdecl{$ELSE}stdcall{$ENDIF}; +begin + if Assigned(VCLComObject) then + Result := IVCLComObject(VCLComObject)._AddRef + else + Result := -1; +end; + +function TComponent._Release: Integer;{$IFNDEF msWINDOWS}cdecl{$ELSE}stdcall{$ENDIF}; +begin + if Assigned(VCLComObject) then + Result := IVCLComObject(VCLComObject)._Release + else + Result := -1; +end; +{$endif} + +function TComponent.iicrGetComponent: TComponent; + +begin + result:=self; +end; + +function TComponent.GetTypeInfoCount(out Count: Integer): HResult; stdcall; +begin + if Assigned(VCLComObject) then + Result := IVCLComObject(VCLComObject).GetTypeInfoCount(Count) + else + Result := E_NOTIMPL; +end; + +function TComponent.GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HResult; stdcall; +begin + if Assigned(VCLComObject) then + Result := IVCLComObject(VCLComObject).GetTypeInfo(Index, LocaleID, TypeInfo) + else + Result := E_NOTIMPL; +end; + +function TComponent.GetIDsOfNames(const IID: TGUID; Names: Pointer; NameCount, + LocaleID: Integer; DispIDs: Pointer): HResult; stdcall; +begin + if Assigned(VCLComObject) then + Result := IVCLComObject(VCLComObject).GetIDsOfNames(IID, Names, NameCount, LocaleID, DispIDs) + else + Result := E_NOTIMPL; +end; + +function TComponent.Invoke(DispID: Integer; const IID: TGUID; + LocaleID: Integer; Flags: Word; var Params; VarResult, ExcepInfo, + ArgErr: Pointer): HResult; stdcall; +begin + if Assigned(VCLComObject) then + Result := IVCLComObject(VCLComObject).Invoke(DispID, IID, LocaleID, Flags, Params, + VarResult, ExcepInfo, ArgErr) + else + Result := E_NOTIMPL; +end; + +{****************************************************************************} +{* TStringsEnumerator *} +{****************************************************************************} + +constructor TStringsEnumerator.Create(AStrings: TStrings); +begin + inherited Create; + FStrings := AStrings; + FPosition := -1; +end; + +function TStringsEnumerator.GetCurrent: String; +begin + Result := FStrings[FPosition]; +end; + +function TStringsEnumerator.MoveNext: Boolean; +begin + Inc(FPosition); + Result := FPosition < FStrings.Count; +end; + +{****************************************************************************} +{* TStrings *} +{****************************************************************************} + +// Function to quote text. Should move maybe to sysutils !! +// Also, it is not clear at this point what exactly should be done. + +{ //!! is used to mark unsupported things. } + +Function QuoteString (Const S : String; Quote : String) : String; +Var + I,J : Integer; +begin + J:=0; + Result:=S; + for i:=1to length(s) do + begin + inc(j); + if S[i]=Quote then + begin + System.Insert(Quote,Result,J); + inc(j); + end; + end; + Result:=Quote+Result+Quote; +end; + +{ + For compatibility we can't add a Constructor to TSTrings to initialize + the special characters. Therefore we add a routine which is called whenever + the special chars are needed. +} + +Procedure Tstrings.CheckSpecialChars; + +begin + If Not FSpecialCharsInited then + begin + FQuoteChar:='"'; + FDelimiter:=','; + FNameValueSeparator:='='; + FSpecialCharsInited:=true; + FLBS:= ttextlinebreakstyle(DefaultTextLineBreakStyle); + end; +end; + +Function TStrings.GetLBS : TTextLineBreakStyle; +begin + CheckSpecialChars; + Result:=FLBS; +end; + +Procedure TStrings.SetLBS (AValue : TTextLineBreakStyle); +begin + CheckSpecialChars; + FLBS:=AValue; +end; + +procedure TStrings.SetDelimiter(c:Char); +begin + CheckSpecialChars; + FDelimiter:=c; +end; + + +procedure TStrings.SetQuoteChar(c:Char); +begin + CheckSpecialChars; + FQuoteChar:=c; +end; + +procedure TStrings.SetNameValueSeparator(c:Char); +begin + CheckSpecialChars; + FNameValueSeparator:=c; +end; + + +function TStrings.GetCommaText: string; + +Var + C1,C2 : Char; + FSD : Boolean; + +begin + CheckSpecialChars; + FSD:=StrictDelimiter; + C1:=Delimiter; + C2:=QuoteChar; + Delimiter:=','; + QuoteChar:='"'; + StrictDelimiter:=False; + Try + Result:=GetDelimitedText; + Finally + Delimiter:=C1; + QuoteChar:=C2; + StrictDelimiter:=FSD; + end; +end; + + +Function TStrings.GetDelimitedText: string; + +Var + I : integer; + p : pchar; + c : set of char; + S : String; + +begin + CheckSpecialChars; + result:=''; + if StrictDelimiter then + c:=[#0,Delimiter] + else + c:=[#0..' ',QuoteChar,Delimiter]; + For i:=0 to count-1 do + begin + S:=Strings[i]; + p:=pchar(S); + while not(p^ in c) do + inc(p); +// strings in list may contain #0 + if (p<>pchar(S)+length(S)) and not StrictDelimiter then + Result:=Result+QuoteString(S,QuoteChar) + else + Result:=Result+S; + if I0 then + begin + AName:=Copy(AValue,1,L-1); + System.Delete(AValue,1,L); + end + else + AName:=''; +end; + +function TStrings.ExtractName(const s:String):String; +var + L: Longint; +begin + CheckSpecialChars; + L:=Pos(FNameValueSeparator,S); + If L<>0 then + Result:=Copy(S,1,L-1) + else + Result:=''; +end; + +function TStrings.GetName(Index: Integer): string; + +Var + V : String; + +begin + GetNameValue(Index,Result,V); +end; + +Function TStrings.GetValue(const Name: string): string; + +Var + L : longint; + N : String; + +begin + Result:=''; + L:=IndexOfName(Name); + If L<>-1 then + GetNameValue(L,N,Result); +end; + +Function TStrings.GetValueFromIndex(Index: Integer): string; + +Var + N : String; + +begin + GetNameValue(Index,N,Result); +end; + +Procedure TStrings.SetValueFromIndex(Index: Integer; const Value: string); + +begin + If (Value='') then + Delete(Index) + else + begin + If (Index<0) then + Index:=Add(''); + CheckSpecialChars; + Strings[Index]:=GetName(Index)+FNameValueSeparator+Value; + end; +end; + +procedure TStrings.ReadData(Reader: TReader); +begin + Reader.ReadListBegin; + BeginUpdate; + try + Clear; + while not Reader.EndOfList do + Add(Reader.ReadString); + finally + EndUpdate; + end; + Reader.ReadListEnd; +end; + + +Procedure TStrings.SetDelimitedText(const AValue: string); +var i,j:integer; + aNotFirst:boolean; +begin + CheckSpecialChars; + BeginUpdate; + + i:=1; + j:=1; + aNotFirst:=false; + + try + Clear; + If StrictDelimiter then + begin + // Easier, faster loop. + While I<=Length(AValue) do + begin + If (AValue[I] in [FDelimiter,#0]) then + begin + Add(Copy(AValue,J,I-J)); + J:=I+1; + end; + Inc(i); + end; + If (Length(AValue)>0) then + Add(Copy(AValue,J,I-J)); + end + else + begin + while i<=length(AValue) do begin + // skip delimiter + if aNotFirst and (i<=length(AValue)) and (AValue[i]=FDelimiter) then inc(i); + + // skip spaces + while (i<=length(AValue)) and (Ord(AValue[i])<=Ord(' ')) do inc(i); + + // read next string + if i<=length(AValue) then begin + if AValue[i]=FQuoteChar then begin + // next string is quoted + j:=i+1; + while (j<=length(AValue)) and + ( (AValue[j]<>FQuoteChar) or + ( (j+1<=length(AValue)) and (AValue[j+1]=FQuoteChar) ) ) do begin + if (j<=length(AValue)) and (AValue[j]=FQuoteChar) then inc(j,2) + else inc(j); + end; + // j is position of closing quote + Add( StringReplace (Copy(AValue,i+1,j-i-1), + FQuoteChar+FQuoteChar,FQuoteChar, [rfReplaceAll])); + i:=j+1; + end else begin + // next string is not quoted + j:=i; + while (j<=length(AValue)) and + (Ord(AValue[j])>Ord(' ')) and + (AValue[j]<>FDelimiter) do inc(j); + Add( Copy(AValue,i,j-i)); + i:=j; + end; + end else begin + if aNotFirst then Add(''); + end; + + // skip spaces + while (i<=length(AValue)) and (Ord(AValue[i])<=Ord(' ')) do inc(i); + + aNotFirst:=true; + end; + end; + finally + EndUpdate; + end; +end; + +Procedure TStrings.SetCommaText(const Value: string); + +Var + C1,C2 : Char; + +begin + CheckSpecialChars; + C1:=Delimiter; + C2:=QuoteChar; + Delimiter:=','; + QuoteChar:='"'; + Try + SetDelimitedText(Value); + Finally + Delimiter:=C1; + QuoteChar:=C2; + end; +end; + + +Procedure TStrings.SetStringsAdapter(const Value: IStringsAdapter); + +begin +end; + + + +Procedure TStrings.SetValue(const Name, Value: string); + +Var L : longint; + +begin + CheckSpecialChars; + L:=IndexOfName(Name); + if L=-1 then + Add (Name+FNameValueSeparator+Value) + else + Strings[L]:=Name+FNameValueSeparator+value; +end; + + + +procedure TStrings.WriteData(Writer: TWriter); +var + i: Integer; +begin + Writer.WriteListBegin; + for i := 0 to Count - 1 do + Writer.WriteString(Strings[i]); + Writer.WriteListEnd; +end; + + + +procedure TStrings.DefineProperties(Filer: TFiler); +var + HasData: Boolean; +begin + if Assigned(Filer.Ancestor) then + // Only serialize if string list is different from ancestor + if Filer.Ancestor.InheritsFrom(TStrings) then + HasData := not Equals(TStrings(Filer.Ancestor)) + else + HasData := True + else + HasData := Count > 0; + Filer.DefineProperty('Strings', {$ifdef FPC}@{$endif}ReadData, + {$ifdef FPC}@{$endif}WriteData, HasData); +end; + + +Procedure TStrings.Error(const Msg: string; Data: Integer); +begin + Raise EStringListError.CreateFmt(Msg,[Data]) + {$ifdef FPC} at get_caller_addr(get_frame){$endif}; +end; + + +Procedure TStrings.Error(const Msg: pstring; Data: Integer); +begin + Raise EStringListError.CreateFmt(Msg^,[Data]) + {$ifdef FPC} at get_caller_addr(get_frame){$endif}; +end; + + +Function TStrings.GetCapacity: Integer; + +begin + Result:=Count; +end; + + + +Function TStrings.GetObject(Index: Integer): TObject; + +begin + Result:=Nil; +end; + + + +Function TStrings.GetTextStr: string; + +Var P : Pchar; + I,L,NLS : Longint; + S,NL : String; + +begin + nl:= ''; + CheckSpecialChars; + // Determine needed place + Case FLBS of + tlbsLF : NL:=#10; + tlbsCRLF : NL:=#13#10; + tlbsCR : NL:=#13; + end; + L:=0; + NLS:=Length(NL); + For I:=0 to count-1 do + L:=L+Length(Strings[I])+NLS; + Setlength(Result,L); + P:=Pointer(Result); + For i:=0 To count-1 do + begin + S:=Strings[I]; + L:=Length(S); + if L<>0 then + System.Move(Pointer(S)^,P^,L); + P:=P+L; + For L:=1 to NLS do + begin + P^:=NL[L]; + inc(P); + end; + end; +end; + + + +Procedure TStrings.Put(Index: Integer; const S: string); + +Var Obj : TObject; + +begin + Obj:=Objects[Index]; + Delete(Index); + InsertObject(Index,S,Obj); +end; + + + +Procedure TStrings.PutObject(Index: Integer; AObject: TObject); + +begin + // Empty. +end; + + + +Procedure TStrings.SetCapacity(NewCapacity: Integer); + +begin + // Empty. +end; + +Function GetNextLine (Const Value : String; Var S : String; Var P : Integer) : Boolean; + +Var + PS : PChar; + IP,L : Integer; + +begin + L:=Length(Value); + S:=''; + Result:=False; + If ((L-P)<0) then + exit; + if ((L-P)=0) and (not (value[P] in [#10,#13])) Then + Begin + s:=value[P]; + inc(P); + result:= true; + Exit; + End; + PS:=PChar(Value)+P-1; + IP:=P; + While ((L-P)>=0) and (not (PS^ in [#10,#13])) do + begin + P:=P+1; + Inc(PS); + end; + SetLength (S,P-IP); + System.Move (Value[IP],Pointer(S)^,P-IP); + If (P<=L) and (Value[P]=#13) then + Inc(P); + If (P<=L) and (Value[P]=#10) then + Inc(P); // Point to character after #10(#13) + Result:=True; +end; + +Procedure TStrings.SetTextStr(const Value: string); + +Var + S : String; + P : Integer; + +begin + Try + beginUpdate; + Clear; + P:=1; + While GetNextLine (Value,S,P) do + Add(S); + finally + EndUpdate; + end; +end; + +Procedure TStrings.SetUpdateState(Updating: Boolean); + +begin +// FPONotifyObservers(Self,ooChange,Nil); +end; + +destructor TSTrings.Destroy; + +begin + inherited destroy; +end; + + + +Function TStrings.Add(const S: string): Integer; + +begin + Result:=Count; + Insert (Count,S); +end; + + + +Function TStrings.AddObject(const S: string; AObject: TObject): Integer; + +begin + Result:=Add(S); + Objects[result]:=AObject; +end; + + + +Procedure TStrings.Append(const S: string); + +begin + Add (S); +end; + + + +Procedure TStrings.AddStrings(TheStrings: TStrings); + +Var Runner : longint; + +begin + try + beginupdate; + For Runner:=0 to TheStrings.Count-1 do + self.AddObject (Thestrings[Runner],TheStrings.Objects[Runner]); + finally + EndUpdate; + end; +end; + +Procedure TStrings.AddStrings(const TheStrings: array of string); + +Var Runner : longint; + +begin + try + beginupdate; + if Count + High(TheStrings)+1 > Capacity then + Capacity := Count + High(TheStrings)+1; + For Runner:=Low(TheStrings) to High(TheStrings) do + self.Add(Thestrings[Runner]); + finally + EndUpdate; + end; +end; + +Procedure TStrings.Assign(Source: TPersistent); + +Var + S : TStrings; + +begin + If Source is TStrings then + begin + S:=TStrings(Source); + BeginUpdate; + Try + clear; + FSpecialCharsInited:=S.FSpecialCharsInited; + FQuoteChar:=S.FQuoteChar; + FDelimiter:=S.FDelimiter; + FNameValueSeparator:=S.FNameValueSeparator; + FLBS:=S.FLBS; + AddStrings(S); + finally + EndUpdate; + end; + end + else + Inherited Assign(Source); +end; + + + +Procedure TStrings.BeginUpdate; + +begin + if FUpdateCount = 0 then SetUpdateState(true); + inc(FUpdateCount); +end; + + + +Procedure TStrings.EndUpdate; + +begin + If FUpdateCount>0 then + Dec(FUpdateCount); + if FUpdateCount=0 then + SetUpdateState(False); +end; + + + +Function TStrings.Equals(Obj: TObject): Boolean; + +begin + if Obj is TStrings then + Result := Equals(TStrings(Obj)) + else + Result := inherited Equals(Obj); +end; + + + +Function TStrings.Equals(TheStrings: TStrings): Boolean; + +Var Runner,Nr : Longint; + +begin + Result:=False; + Nr:=Self.Count; + if Nr<>TheStrings.Count then exit; + For Runner:=0 to Nr-1 do + If Strings[Runner]<>TheStrings[Runner] then exit; + Result:=True; +end; + + + +Procedure TStrings.Exchange(Index1, Index2: Integer); + +Var + Obj : TObject; + Str : String; + +begin + Try + beginUpdate; + Obj:=Objects[Index1]; + Str:=Strings[Index1]; + Objects[Index1]:=Objects[Index2]; + Strings[Index1]:=Strings[Index2]; + Objects[Index2]:=Obj; + Strings[Index2]:=Str; + finally + EndUpdate; + end; +end; + + +function TStrings.GetEnumerator: TStringsEnumerator; +begin + Result:=TStringsEnumerator.Create(Self); +end; + + +Function TStrings.GetText: PChar; +begin + Result:=StrNew(Pchar(Self.Text)); +end; + + +Function TStrings.DoCompareText(const s1,s2 : string) : PtrInt; + begin + result:=CompareText(s1,s2); + end; + + +Function TStrings.IndexOf(const S: string): Integer; +begin + Result:=0; + While (Result0) do Result:=Result+1; + if Result=Count then Result:=-1; +end; + + +Function TStrings.IndexOfName(const Name: string): Integer; +Var + len : longint; + S : String; +begin + CheckSpecialChars; + Result:=0; + while (Result0) and (DoCompareText(Name,Copy(S,1,Len))=0) then + exit; + inc(result); + end; + result:=-1; +end; + + +Function TStrings.IndexOfObject(AObject: TObject): Integer; +begin + Result:=0; + While (ResultAObject) do Result:=Result+1; + If Result=Count then Result:=-1; +end; + + +Procedure TStrings.InsertObject(Index: Integer; const S: string; + AObject: TObject); + +begin + Insert (Index,S); + Objects[Index]:=AObject; +end; + + + +Procedure TStrings.LoadFromFile(const FileName: string); +Var + TheStream : TFileStream; +begin + TheStream:=TFileStream.Create(FileName,fmOpenRead or fmShareDenyWrite); + try + LoadFromStream(TheStream); + finally + TheStream.Free; + end; +end; + + + +Procedure TStrings.LoadFromStream(Stream: TStream); +{ + Borlands method is no good, since a pipe for + instance doesn't have a size. + So we must do it the hard way. +} +Const + BufSize = 1024; + MaxGrow = 1 shl 29; + +Var + Buffer : AnsiString; + BytesRead, + BufLen, + I,BufDelta : Longint; +begin + // reread into a buffer + try + beginupdate; + Buffer:=''; + BufLen:=0; + I:=1; + Repeat + BufDelta:=BufSize*I; + SetLength(Buffer,BufLen+BufDelta); + BytesRead:=Stream.Read(Buffer[BufLen+1],BufDelta); + inc(BufLen,BufDelta); + If IBufDelta; + SetLength(Buffer, BufLen-BufDelta+BytesRead); + SetTextStr(Buffer); + SetLength(Buffer,0); + finally + EndUpdate; + end; +end; + + +Procedure TStrings.Move(CurIndex, NewIndex: Integer); +Var + Obj : TObject; + Str : String; +begin + BeginUpdate; + Obj:=Objects[CurIndex]; + Str:=Strings[CurIndex]; + Delete(Curindex); + InsertObject(NewIndex,Str,Obj); + EndUpdate; +end; + + + +Procedure TStrings.SaveToFile(const FileName: string); + +Var TheStream : TFileStream; + +begin + TheStream:=TFileStream.Create(FileName,fmCreate); + try + SaveToStream(TheStream); + finally + TheStream.Free; + end; +end; + + + +Procedure TStrings.SaveToStream(Stream: TStream); +Var + S : String; +begin + S:=Text; + if S = '' then Exit; + Stream.WriteBuffer(Pointer(S)^,Length(S)); +end; + + + + +Procedure TStrings.SetText(TheText: PChar); + +Var S : String; + +begin + If TheText<>Nil then + S:=StrPas(TheText) + else + S:=''; + SetTextStr(S); +end; + + +{****************************************************************************} +{* TStringList *} +{****************************************************************************} + + +Procedure TStringList.ExchangeItems(Index1, Index2: Integer); + +Var P1,P2 : Pointer; + +begin + P1:=Pointer(Flist^[Index1].FString); + P2:=Pointer(Flist^[Index1].FObject); + Pointer(Flist^[Index1].Fstring):=Pointer(Flist^[Index2].Fstring); + Pointer(Flist^[Index1].FObject):=Pointer(Flist^[Index2].FObject); + Pointer(Flist^[Index2].Fstring):=P1; + Pointer(Flist^[Index2].FObject):=P2; +end; + + + +Procedure TStringList.Grow; + +Var + NC : Integer; + +begin + NC:=FCapacity; + If NC>=256 then + NC:=NC+(NC Div 4) + else if NC=0 then + NC:=4 + else + NC:=NC*4; + SetCapacity(NC); +end; + +Procedure TStringList.InternalClear; + +Var + I: Integer; + +begin + if FOwnsObjects then + begin + For I:=0 to FCount-1 do + begin + Flist^[I].FString:=''; + freeandnil(Flist^[i].FObject); + end; + end + else + begin + For I:=0 to FCount-1 do + Flist^[I].FString:=''; + end; + FCount:=0; + SetCapacity(0); +end; + +Procedure TStringList.QuickSort(L, R: Integer; CompareFn: TStringListSortCompare); +var + Pivot, vL, vR: Integer; +begin + if R - L <= 1 then begin // a little bit of time saver + if L < R then + if CompareFn(Self, L, R) > 0 then + ExchangeItems(L, R); + + Exit; + end; + + vL := L; + vR := R; + + Pivot := L + Random(R - L); // they say random is best + + while vL < vR do begin + while (vL < Pivot) and (CompareFn(Self, vL, Pivot) <= 0) do + Inc(vL); + + while (vR > Pivot) and (CompareFn(Self, vR, Pivot) > 0) do + Dec(vR); + + ExchangeItems(vL, vR); + + if Pivot = vL then // swap pivot if we just hit it from one side + Pivot := vR + else if Pivot = vR then + Pivot := vL; + end; + + if Pivot - 1 >= L then + QuickSort(L, Pivot - 1, CompareFn); + if Pivot + 1 <= R then + QuickSort(Pivot + 1, R, CompareFn); +end; + + +Procedure TStringList.InsertItem(Index: Integer; const S: string); +begin + Changing; + If FCount=Fcapacity then Grow; + If IndexValue then + begin + If Value then sort; + FSorted:=VAlue + end; +end; + + + +Procedure TStringList.Changed; + +begin + If (FUpdateCount=0) Then + begin + If Assigned(FOnChange) then + FOnchange(Self); +// FPONotifyObservers(Self,ooChange,Nil); + end; +end; + + + +Procedure TStringList.Changing; + +begin + If FUpdateCount=0 then + if Assigned(FOnChanging) then + FOnchanging(Self); +end; + + + +Function TStringList.Get(Index: Integer): string; + +begin + If (Index<0) or (INdex>=Fcount) then + Error (SListIndexError,Index); + Result:=Flist^[Index].FString; +end; + + + +Function TStringList.GetCapacity: Integer; + +begin + Result:=FCapacity; +end; + + + +Function TStringList.GetCount: Integer; + +begin + Result:=FCount; +end; + + + +Function TStringList.GetObject(Index: Integer): TObject; + +begin + If (Index<0) or (INdex>=Fcount) then + Error (SListIndexError,Index); + Result:=Flist^[Index].FObject; +end; + + + +Procedure TStringList.Put(Index: Integer; const S: string); + +begin + If Sorted then + Error(SSortedListError,0); + If (Index<0) or (INdex>=Fcount) then + Error (SListIndexError,Index); + Changing; + Flist^[Index].FString:=S; + Changed; +end; + + + +Procedure TStringList.PutObject(Index: Integer; AObject: TObject); + +begin + If (Index<0) or (INdex>=Fcount) then + Error (SListIndexError,Index); + Changing; + Flist^[Index].FObject:=AObject; + Changed; +end; + + + +Procedure TStringList.SetCapacity(NewCapacity: Integer); + +Var NewList : Pointer; + MSize : Longint; + +begin + If (NewCapacity<0) then + Error (SListCapacityError,NewCapacity); + If NewCapacity>FCapacity then + begin + GetMem (NewList,NewCapacity*SizeOf(TStringItem)); + If NewList=Nil then + Error (SListCapacityError,NewCapacity); + If Assigned(FList) then + begin + MSize:=FCapacity*Sizeof(TStringItem); + System.Move (FList^,NewList^,MSize); + {$ifdef FPC} + FillWord (Pchar(NewList)[MSize],(NewCapacity-FCapacity)*WordRatio, 0); + {$else} + Fillchar(Pchar(NewList)[MSize],(NewCapacity-FCapacity)*sizeof(pointer),0); + {$endif} + FreeMem (Flist,MSize); + end; + Flist:=NewList; + FCapacity:=NewCapacity; + end + else if NewCapacity=FCount) then + Error(SlistINdexError,Index); + Changing; + Flist^[Index].FString:=''; + if FOwnsObjects then + FreeAndNil(Flist^[Index].FObject); + Dec(FCount); + If Index=FCount) then + Error(SListIndexError,Index1); + If (Index2<0) or (Index2>=FCount) then + Error(SListIndexError,Index2); + Changing; + ExchangeItems(Index1,Index2); + changed; +end; + + +procedure TStringList.SetCaseSensitive(b : boolean); + begin + if b<>FCaseSensitive then + begin + FCaseSensitive:=b; + if FSorted then + sort; + end; + end; + + +Function TStringList.DoCompareText(const s1,s2 : string) : PtrInt; + begin + if FCaseSensitive then + result:=AnsiCompareStr(s1,s2) + else + result:=AnsiCompareText(s1,s2); + end; + + +Function TStringList.Find(const S: string; Out Index: Integer): Boolean; + +var + L, R, I: Integer; + CompareRes: PtrInt; +begin + Result := false; + // Use binary search. + L := 0; + R := Count - 1; + while (L<=R) do + begin + I := L + (R - L) div 2; + CompareRes := DoCompareText(S, Flist^[I].FString); + if (CompareRes>0) then + L := I+1 + else begin + R := I-1; + if (CompareRes=0) then begin + Result := true; + if (Duplicates<>dupAccept) then + L := I; // forces end of while loop + end; + end; + end; + Index := L; +end; + + + +Function TStringList.IndexOf(const S: string): Integer; + +begin + If Not Sorted then + Result:=Inherited indexOf(S) + else + // faster using binary search... + If Not Find (S,Result) then + Result:=-1; +end; + + + +Procedure TStringList.Insert(Index: Integer; const S: string); + +begin + If Sorted then + Error (SSortedListError,0) + else + If (Index<0) or (Index>FCount) then + Error (SListIndexError,Index) + else + InsertItem (Index,S); +end; + + +Procedure TStringList.CustomSort(CompareFn: TStringListSortCompare); + +begin + If Not Sorted and (FCount>1) then + begin + Changing; + QuickSort(0,FCount-1, CompareFn); + Changed; + end; +end; + +function StringListAnsiCompare(List: TStringList; Index1, Index: Integer): Integer; + +begin + Result := List.DoCompareText(List.FList^[Index1].FString, + List.FList^[Index].FString); +end; + +Procedure TStringList.Sort; + +begin + CustomSort(@StringListAnsiCompare); +end; + +{****************************************************************************} +{* TStream *} +{****************************************************************************} + +procedure TStream.ReadNotImplemented; +begin + raise EStreamError.CreateFmt(SStreamNoReading, [ClassName]) + {$ifdef FPC} at get_caller_addr(get_frame){$endif}; +end; + +procedure TStream.WriteNotImplemented; +begin + raise EStreamError.CreateFmt(SStreamNoWriting, [ClassName]) + {$ifdef FPC} at get_caller_addr(get_frame){$endif}; +end; + +function TStream.Read(var Buffer; Count: Longint): Longint; +begin + ReadNotImplemented; + Result := 0; +end; + +function TStream.Write(const Buffer; Count: Longint): Longint; +begin + WriteNotImplemented; + Result := 0; +end; + + + function TStream.GetPosition: Int64; + + begin + Result:=Seek(0,soCurrent); + end; + + procedure TStream.SetPosition(const Pos: Int64); + + begin + Seek(pos,soBeginning); + end; + + procedure TStream.SetSize64(const NewSize: Int64); + + begin + // Required because can't use overloaded functions in properties + SetSize(NewSize); + end; + + function TStream.GetSize: Int64; + + var + p : int64; + + begin + p:=Seek(0,soCurrent); + GetSize:=Seek(0,soEnd); + Seek(p,soBeginning); + end; + + procedure TStream.SetSize(NewSize: Longint); + + begin + // We do nothing. Pipe streams don't support this + // As wel as possible read-ony streams !! + end; + + procedure TStream.SetSize(const NewSize: Int64); + + begin + // Backwards compatibility that calls the longint SetSize + if (NewSizeHigh(longint)) then + raise ERangeError.Create(SRangeError); + SetSize(longint(NewSize)); + end; + + function TStream.Seek(Offset: Longint; Origin: Word): Longint; + + type + TSeek64 = function(const offset:Int64;Origin:TSeekorigin):Int64 of object; + var + CurrSeek, + TStreamSeek : TSeek64; + CurrClass : TClass; + begin + // Redirect calls to 64bit Seek, but we can't call the 64bit Seek + // from TStream, because then we end up in an infinite loop + CurrSeek:=nil; + CurrClass:=Classtype; + while (CurrClass<>nil) and + (CurrClass<>TStream) do + CurrClass:=CurrClass.Classparent; + if CurrClass<>nil then + begin + CurrSeek:= {$ifdef FPC}@{$endif}Self.Seek; + TStreamSeek:={$ifdef FPC}@{$endif}TStream(@CurrClass).Seek; + if TMethod(TStreamSeek).Code=TMethod(CurrSeek).Code then + CurrSeek:=nil; + end; + if {$ifndef FPC}@{$endif}CurrSeek <> nil then + Result:=Seek(Int64(offset),TSeekOrigin(origin)) + else + raise EStreamError.CreateFmt(SSeekNotImplemented,[ClassName]); + end; + + procedure TStream.Discard(const Count: Int64); + + const + CSmallSize =255; + CLargeMaxBuffer =32*1024; // 32 KiB + var + Buffer: array[1..CSmallSize] of Byte; + + begin + if Count=0 then + Exit; + if Count<=SizeOf(Buffer) then + ReadBuffer(Buffer,Count) + else + DiscardLarge(Count,CLargeMaxBuffer); + end; + + procedure TStream.DiscardLarge(Count: int64; const MaxBufferSize: Longint); + + var + Buffer: array of Byte; + + begin + if Count=0 then + Exit; + if Count>MaxBufferSize then + SetLength(Buffer,MaxBufferSize) + else + SetLength(Buffer,Count); + while (Count>=Length(Buffer)) do + begin + ReadBuffer(Buffer[0],Length(Buffer)); + Dec(Count,Length(Buffer)); + end; + if Count>0 then + ReadBuffer(Buffer[0],Count); + end; + + procedure TStream.InvalidSeek; + + begin + raise EStreamError.CreateFmt(SStreamInvalidSeek, [ClassName]) + {$ifdef FPC} at get_caller_addr(get_frame){$endif}; + end; + + procedure TStream.FakeSeekForward(Offset: Int64; const Origin: TSeekOrigin; const Pos: Int64); + +// var +// Buffer: Pointer; +// BufferSize, i: LongInt; + + begin + if Origin=soBeginning then + Dec(Offset,Pos); + if (Offset<0) or (Origin=soEnd) then + InvalidSeek; + if Offset>0 then + Discard(Offset); + end; + + function TStream.Seek(const Offset: Int64; Origin: TSeekorigin): Int64; + + begin + // Backwards compatibility that calls the longint Seek + if (OffsetHigh(longint)) then + raise ERangeError.Create(SRangeError); + Result:=Seek(longint(Offset),ord(Origin)); + end; + +function tstream.seek(const offset: int64; const origin: tseekorigin; + out newpos: int64): syserrorty; +begin + newpos:= seek(offset,origin); + result:= sye_ok; + if newpos < 0 then begin + result:= sye_lasterror; + end; +end; + +function TStream.read(var buffer; const count: longint; + out acount: longint): syserrorty; +var + po1: pbyte; + int1,int2: integer; +begin + result:= sye_ok; + int2:= count; + po1:= @buffer; + repeat + int1:= read(po1^,int2); + if int1 <= 0 then begin + break; + end; + int2:= int2 - int1; + inc(po1,int1); + until int2 <= 0; + acount:= count - int2; + if int1 < 0 then begin + result:= syelasterror; + end + else begin + if (int2 > 0) then begin + result:= sye_read; + end; + end; +end; + +function TStream.tryreadbuffer(var buffer; count: longint): syserrorty; +var + int1: integer; +begin + result:= read(buffer,count,int1); +end; + +procedure TStream.ReadBuffer(var Buffer; Count: Longint); +begin + if tryreadbuffer(buffer,count) <> sye_ok then begin + Raise EReadError.Create(SReadError); + end; +end; + +function TStream.write(const buffer; const count: longint; + out acount: longint): syserrorty; +var + po1: pbyte; + int1,int2: integer; +begin + result:= sye_ok; + int2:= count; + po1:= @buffer; + repeat + int1:= write(po1^,int2); + if int1 <= 0 then begin + break; + end; + int2:= int2 - int1; + inc(po1,int1); + until int2 <= 0; + acount:= count - int2; + if int1 < 0 then begin + result:= syelasterror; + end + else begin + if (int2 > 0) then begin + result:= sye_write; + end; + end; +end; + +function TStream.trywritebuffer(const buffer; count: longint): syserrorty; +var + int1: integer; +begin + result:= write(buffer,count,int1); +end; + +procedure TStream.WriteBuffer(const Buffer; Count: Longint); +begin + if trywritebuffer(buffer,count) <> sye_ok then begin + Raise EWriteError.Create(SWriteError); + end; +end; + + function TStream.CopyFrom(Source: TStream; Count: Int64): Int64; + + var + Buffer: Pointer; + BufferSize, i: LongInt; + + const + MaxSize = $20000; + begin + + Result:=0; + if Count=0 then + Source.Position:=0; // This WILL fail for non-seekable streams... + BufferSize:=MaxSize; + if (Count>0) and (Count0 then + WriteBuffer(buffer^,i); + Inc(Result,i); + until i0 do + begin + if Count>BufferSize then + i:=BufferSize + else + i:=Count; + Source.ReadBuffer(buffer^,i); + WriteBuffer(buffer^,i); + Dec(count,i); + Inc(Result,i); + end; + finally + FreeMem(Buffer); + end; + + end; + +function TStream.readdatastring: string; +begin + setlength(result,size-position); + setlength(result,read(pointer(result)^,length(result))); +end; + +procedure TStream.writedatastring(const value: rawbytestring); +begin + if value <> '' then begin + writebuffer(pointer(value)^,length(value)); + end; +end; + + function TStream.ReadComponent(Instance: TComponent): TComponent; + + var + Reader: TReader; + + begin + + Reader := TReader.Create(Self, 4096); + try + Result := Reader.ReadRootComponent(Instance); + finally + Reader.Free; + end; + + end; + + function TStream.ReadComponentRes(Instance: TComponent): TComponent; + + begin + + ReadResHeader; + Result := ReadComponent(Instance); + + end; + + procedure TStream.WriteComponent(Instance: TComponent); + + begin + + WriteDescendent(Instance, nil); + + end; + + procedure TStream.WriteComponentRes(const ResName: string; Instance: TComponent); + + begin + + WriteDescendentRes(ResName, Instance, nil); + + end; + + procedure TStream.WriteDescendent(Instance, Ancestor: TComponent); + + var + Driver : TAbstractObjectWriter; + Writer : TWriter; + + begin + + Driver := TBinaryObjectWriter.Create(Self, 4096); + Try + Writer := TWriter.Create(Driver); + Try + Writer.WriteDescendent(Instance, Ancestor); + Finally + Writer.Destroy; + end; + Finally + Driver.Free; + end; + + end; + + procedure TStream.WriteDescendentRes(const ResName: string; Instance, Ancestor: TComponent); + + var + FixupInfo: Integer; + + begin + + { Write a resource header } + WriteResourceHeader(ResName, FixupInfo); + { Write the instance itself } + WriteDescendent(Instance, Ancestor); + { Insert the correct resource size into the resource header } + FixupResourceHeader(FixupInfo); + + end; + + procedure TStream.WriteResourceHeader(const ResName: string; {!!!: out} var FixupInfo: Integer); + var + ResType, Flags : word; + begin + ResType:=NtoLE(word($000A)); + Flags:=NtoLE(word($1030)); + { Note: This is a Windows 16 bit resource } + { Numeric resource type } + WriteByte($ff); + { Application defined data } + WriteWord(ResType); + { write the name as asciiz } + WriteBuffer(ResName[1],length(ResName)); + WriteByte(0); + { Movable, Pure and Discardable } + WriteWord(Flags); + { Placeholder for the resource size } + WriteDWord(0); + { Return current stream position so that the resource size can be + inserted later } + FixupInfo := Position; + end; + + procedure TStream.FixupResourceHeader(FixupInfo: Integer); + + var + ResSize,TmpResSize : Integer; + + begin + + ResSize := Position - FixupInfo; + TmpResSize := NtoLE(longword(ResSize)); + + { Insert the correct resource size into the placeholder written by + WriteResourceHeader } + Position := FixupInfo - 4; + WriteDWord(TmpResSize); + { Seek back to the end of the resource } + Position := FixupInfo + ResSize; + + end; + + procedure TStream.ReadResHeader; + var + ResType, Flags : word; + begin + try + { Note: This is a Windows 16 bit resource } + { application specific resource ? } + if ReadByte<>$ff then + raise EInvalidImage.Create(SInvalidImage); + ResType:=LEtoN(ReadWord); + if ResType<>$000a then + raise EInvalidImage.Create(SInvalidImage); + { read name } + while ReadByte<>0 do + ; + { check the access specifier } + Flags:=LEtoN(ReadWord); + if Flags<>$1030 then + raise EInvalidImage.Create(SInvalidImage); + { ignore the size } + ReadDWord; + except + on EInvalidImage do + raise; + else + raise EInvalidImage.create(SInvalidImage); + end; + end; + + function TStream.ReadByte : Byte; + + var + b : Byte; + + begin + ReadBuffer(b,1); + ReadByte:=b; + end; + + function TStream.ReadWord : Word; + + var + w : Word; + + begin + ReadBuffer(w,2); + ReadWord:=w; + end; + + function TStream.ReadDWord : Cardinal; + + var + d : Cardinal; + + begin + ReadBuffer(d,4); + ReadDWord:=d; + end; + + function TStream.ReadQWord: QWord; + var + q: QWord; + begin + ReadBuffer(q,8); + ReadQWord:=q; + + end; + + Function TStream.ReadAnsiString : String; + + Var + TheSize : Longint; + P : PByte ; + begin + ReadBuffer (TheSize,SizeOf(TheSize)); + SetLength(Result,TheSize); + // Illegal typecast if no AnsiStrings defined. + if TheSize>0 then + begin + ReadBuffer (Pointer(Result)^,TheSize); + P:= pointer(pchar(Pointer(Result))+TheSize); + p^:=0; + end; + end; + + Procedure TStream.WriteAnsiString (const S : String); + + Var L : Longint; + + begin + L:=Length(S); + WriteBuffer (L,SizeOf(L)); + WriteBuffer (Pointer(S)^,L); + end; + + procedure TStream.WriteByte(b : Byte); + + begin + WriteBuffer(b,1); + end; + + procedure TStream.WriteWord(w : Word); + + begin + WriteBuffer(w,2); + end; + + procedure TStream.WriteDWord(d : Cardinal); + + begin + WriteBuffer(d,4); + end; + + procedure TStream.WriteQWord(q: QWord); + begin + WriteBuffer(q,8); + end; + +function TStream.getmemory: pointer; +begin + result:= nil; +end; + + +{****************************************************************************} +{* TCustomMemoryStream *} +{****************************************************************************} + +procedure TCustomMemoryStream.SetPointer(Ptr: Pointer; ASize: PtrInt); + +begin + FMemory:=Ptr; + FSize:=ASize; +end; + + +function TCustomMemoryStream.GetSize: Int64; + +begin + Result:=FSize; +end; + +function TCustomMemoryStream.GetPosition: Int64; +begin + Result:=FPosition; +end; + + +function TCustomMemoryStream.Read(var Buffer; Count: LongInt): LongInt; + +begin + Result:=0; + If (FSize>0) and (FPosition=0) then + begin + Result:=FSize-FPosition; + If Result>Count then Result:=Count; + Move ((pchar(FMemory)+FPosition)^,Buffer,Result); + FPosition:=Fposition+Result; + end; +end; + + +function TCustomMemoryStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; + +begin + Case Word(Origin) of + soFromBeginning : FPosition:=Offset; + soFromEnd : FPosition:=FSize+Offset; + soFromCurrent : FPosition:=FPosition+Offset; + end; + Result:=FPosition; + {$IFDEF DEBUG} + if Result < 0 then + raise Exception.Create('TCustomMemoryStream'); + {$ENDIF} +end; + + +procedure TCustomMemoryStream.SaveToStream(Stream: TStream); + +begin + if FSize>0 then Stream.WriteBuffer (FMemory^,FSize); +end; + + +procedure TCustomMemoryStream.SaveToFile(const FileName: string); + +Var S : TFileStream; + +begin + S:=TFileStream.Create (FileName,fmCreate); + Try + SaveToStream(S); + finally + S.free; + end; +end; + +function TCustomMemoryStream.getmemory: pointer; +begin + result:= fmemory; +end; + +{****************************************************************************} +{* TMemoryStream *} +{****************************************************************************} + + +Const TMSGrow = 4096; { Use 4k blocks. } + +procedure TMemoryStream.SetCapacity(NewCapacity: PtrInt); + +begin + SetPointer (Realloc(NewCapacity),Fsize); + FCapacity:=NewCapacity; +end; + +function TMemoryStream.getcapacity: ptrint; +begin + result:= fcapacity; +end; + +function tmemorystream.Realloc(var NewCapacity: PtrInt): Pointer; +var + i1: ptrint; +begin + If NewCapacity < 0 Then begin + NewCapacity:=0 + end + else begin + if newcapacity > fcapacity then begin + if newcapacity > tmsgrow then begin + // if growing, grow at least a quarter + i1:= FCapacity + fcapacity div 4; + if NewCapacity < i1 then begin + NewCapacity:= i1; // round off to block size. + end; + NewCapacity := (NewCapacity + (TMSGrow-1)) and not (TMSGROW-1); + end + else begin + newcapacity:= newcapacity * 2 + 32; + end; + end; + end; + // Only now check ! + If NewCapacity = FCapacity then begin + Result:= FMemory + end + else begin + Result:= Reallocmem(FMemory,Newcapacity); + If (Result = Nil) and (Newcapacity > 0) then begin + Raise EStreamError.Create(SMemoryStreamError); + end; + end; +end; + +(* +function TMemoryStream.Realloc(var NewCapacity: PtrInt): Pointer; + +begin + If NewCapacity<0 Then + NewCapacity:=0 + else + begin + // if growing, grow at least a quarter + if (NewCapacity>FCapacity) and (NewCapacity < (5*FCapacity) div 4) then + NewCapacity := (5*FCapacity) div 4; + // round off to block size. + NewCapacity := (NewCapacity + (TMSGrow-1)) and not (TMSGROW-1); + end; + // Only now check ! + If NewCapacity=FCapacity then + Result:=FMemory + else + begin + {$ifdef FPC} + Result:= Reallocmem(FMemory,Newcapacity); + {$else} + Reallocmem(FMemory,Newcapacity); + result:= fmemory; + {$endif} + If (Result=Nil) and (Newcapacity>0) then + Raise EStreamError.Create(SMemoryStreamError); + end; +end; +*) + +destructor TMemoryStream.Destroy; + +begin + Clear; + Inherited Destroy; +end; + + +procedure TMemoryStream.Clear; + +begin + FSize:=0; + FPosition:=0; + SetCapacity (0); +end; + + +procedure TMemoryStream.LoadFromStream(Stream: TStream); + +begin + Stream.Position:=0; + SetSize(Stream.Size); + If FSize>0 then Stream.ReadBuffer(FMemory^,FSize); +end; + + +procedure TMemoryStream.LoadFromFile(const FileName: string); + +Var S : TFileStream; + +begin + S:=TFileStream.Create (FileName,fmOpenRead or fmShareDenyWrite); + Try + LoadFromStream(S); + finally + S.free; + end; +end; + + +procedure TMemoryStream.SetSize({$ifdef CPU64}const{$endif CPU64} NewSize: PtrInt); + +begin + SetCapacity (NewSize); + FSize:=NewSize; + IF FPosition>FSize then + FPosition:=FSize; +end; + +function TMemoryStream.Write(const Buffer; Count: LongInt): LongInt; + +Var NewPos : PtrInt; + +begin + If (Count=0) or (FPosition<0) then begin + result:= 0; + exit; + end; + NewPos:=FPosition+Count; + If NewPos>Fsize then + begin + IF NewPos>FCapacity then + SetCapacity (NewPos); + FSize:=Newpos; + end; + System.Move (Buffer,(pchar(FMemory)+FPosition)^,Count); + FPosition:=NewPos; + Result:=Count; +end; + +{****************************************************************************} +{* TBinaryObjectReader *} +{****************************************************************************} + +{$ifndef FPUNONE} +{$IFNDEF FPC_HAS_TYPE_EXTENDED} +function ExtendedToDouble(e : pointer) : double; +var mant : qword; + exp : smallint; + sign : boolean; + d : qword; +begin + move(pbyte(e)[0],mant,8); //mantissa : bytes 0..7 + move(pbyte(e)[8],exp,2); //exponent and sign: bytes 8..9 + mant:=LEtoN(mant); + exp:=LEtoN(word(exp)); + sign:=(exp and $8000)<>0; + if sign then begin + exp:=exp and $7FFF; + end; + case exp of + 0: begin + mant:= 0; //if denormalized, value is too small for double, + //so it's always zero + end; + $7FFF: begin + exp:=2047; //either infinity or NaN + if mant and $3fffffffffffffff = 0 then begin + mant:= 0; //infinity + end; + end + else begin + dec(exp,16383-1023); + if (exp>=-51) and (exp<=0) then begin //can be denormalized + mant:=mant shr (-exp); + exp:=0; + end + else begin + if (exp<-51) or (exp>2046) then begin //exponent too large. + Result:=0; + exit; + end + else begin //normalized value + mant:=mant shl 1; //hide most significant bit + end; + end; + end; + end; + d:=word(exp); + d:=d shl 52; + + mant:=mant shr 12; + d:=d or mant; + if sign then d:=d or $8000000000000000; + Result:=pdouble(@d)^; +end; +{$ENDIF} +{$endif} + +function TBinaryObjectReader.ReadWord : word; {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} +begin + Read(Result,2); + Result:=LEtoN(Result); +end; + +function TBinaryObjectReader.ReadDWord : longword; {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} +begin + Read(Result,4); + Result:=LEtoN(Result); +end; + +function TBinaryObjectReader.ReadQWord : qword; {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} +begin + Read(Result,8); + {$ifdef FPC} + Result:=LEtoN(Result); + {$endif} +end; + +{$IFDEF FPC_DOUBLE_HILO_SWAPPED} +procedure SwapDoubleHiLo(var avalue: double); {$ifdef CLASSESINLINE}inline{$endif CLASSESINLINE} +var dwo1 : dword; +type tdoublerec = array[0..1] of dword; +begin + dwo1:= tdoublerec(avalue)[0]; + tdoublerec(avalue)[0]:=tdoublerec(avalue)[1]; + tdoublerec(avalue)[1]:=dwo1; +end; +{$ENDIF FPC_DOUBLE_HILO_SWAPPED} + +{$ifndef FPUNONE} +function TBinaryObjectReader.ReadExtended : extended; + {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} +{$IFNDEF FPC_HAS_TYPE_EXTENDED} +var ext : array[0..9] of byte; +{$ENDIF} +begin + {$IFNDEF FPC_HAS_TYPE_EXTENDED} + Read(ext[0],10); + Result:=ExtendedToDouble(@(ext[0])); + {$IFDEF FPC_DOUBLE_HILO_SWAPPED} + SwapDoubleHiLo(result); + {$ENDIF} + {$ELSE} + Read(Result,sizeof(Result)); + {$ENDIF} +end; +{$endif} + +constructor TBinaryObjectReader.Create(Stream: TStream; BufSize: Integer); +begin + inherited Create; + If (Stream=Nil) then + Raise EReadError.Create(SEmptyStreamIllegalReader); + FStream := Stream; + FBufSize := BufSize; + GetMem(FBuffer, BufSize); +end; + +destructor TBinaryObjectReader.Destroy; +begin + { Seek back the amount of bytes that we didn't process until now: } + FStream.Seek(Integer(FBufPos) - Integer(FBufEnd), soFromCurrent); + + if Assigned(FBuffer) then + FreeMem(FBuffer, FBufSize); + + inherited Destroy; +end; + +function TBinaryObjectReader.ReadValue: TValueType; +var + b: byte; +begin + Read(b, 1); + Result := TValueType(b); +end; + +function TBinaryObjectReader.NextValue: TValueType; +begin + Result := ReadValue; + { We only 'peek' at the next value, so seek back to unget the read value: } + Dec(FBufPos); +end; + +procedure TBinaryObjectReader.BeginRootComponent; +var + Signature: LongInt; +begin + { Read filer signature } + Read(Signature, 4); + {$ifdef FPC} + if Signature <> LongInt(unaligned(FilerSignature)) then + {$else} + if Signature <> LongInt(FilerSignature) then + {$endif} + raise EReadError.Create(SInvalidImage); +end; + +procedure TBinaryObjectReader.BeginComponent(var Flags: TFilerFlags; + var AChildPos: Integer; var CompClassName, CompName: String); +var + Prefix: Byte; + ValueType: TValueType; +begin + { Every component can start with a special prefix: } + Flags := []; + if (Byte(NextValue) and $f0) = $f0 then + begin + Prefix := Byte(ReadValue); + Flags := TFilerFlags({$ifdef FPC}longword{$else}byte{$endif}(Prefix and $0f)); + if ffChildPos in Flags then + begin + ValueType := ReadValue; + case ValueType of + vaInt8: + AChildPos := ReadInt8; + vaInt16: + AChildPos := ReadInt16; + vaInt32: + AChildPos := ReadInt32; + else + raise EReadError.Create(SInvalidPropertyValue); + end; + end; + end; + + CompClassName := ReadStr; + CompName := ReadStr; +end; + +function TBinaryObjectReader.BeginProperty: String; +begin + Result := ReadStr; +end; + +procedure TBinaryObjectReader.ReadBinary(const DestData: TMemoryStream); +var + BinSize: LongInt; +begin + BinSize:=LongInt(ReadDWord); + DestData.Size := BinSize; + Read(DestData.Memory^, BinSize); +end; + +{$ifndef FPUNONE} +function TBinaryObjectReader.ReadFloat: Extended; +begin + Result:= ReadExtended; +end; + +function TBinaryObjectReader.ReadSingle: Single; +begin +{$ifdef FPC} + Result:= single(ReadDWord); +{$else} + Result:= single(ar4ty(ReadDWord())); +{$endif} +end; +{$endif} + +function TBinaryObjectReader.ReadCurrency: Currency; +begin + {$ifdef FPC} + Result:=currency(ReadQWord); + {$else} + Result:=currency(ar8ty(ReadQWord())); + {$endif} +end; + +{$ifndef FPUNONE} +function TBinaryObjectReader.ReadDate: TDateTime; +begin + {$ifdef FPC} + Result:= TDateTime(ReadQWord); + {$else} + Result:= TDateTime(ar8ty(ReadQWord())); + {$endif} +end; +{$endif} + +function TBinaryObjectReader.ReadIdent(ValueType: TValueType): String; +var + i: Byte; +begin + result:= ''; + case ValueType of + vaIdent: + begin + Read(i, 1); + SetLength(Result, i); + Read(Pointer(@Result[1])^, i); + end; + vaNil: + Result := 'nil'; + vaFalse: + Result := 'False'; + vaTrue: + Result := 'True'; + vaNull: + Result := 'Null'; + end; +end; + +function TBinaryObjectReader.ReadInt8: ShortInt; +begin + Read(Result, 1); +end; + +function TBinaryObjectReader.ReadInt16: SmallInt; +begin + Result:=SmallInt(ReadWord); +end; + +function TBinaryObjectReader.ReadInt32: LongInt; +begin + Result:=LongInt(ReadDWord); +end; + +function TBinaryObjectReader.ReadInt64: Int64; +begin + Result:=Int64(ReadQWord); +end; + +function TBinaryObjectReader.ReadSet(EnumType: ptypeinfo): Integer; +type + tset = set of 0..31; +var + Name: String; + Value: Integer; +begin + try + Result := 0; + while True do + begin + Name := ReadStr; + if Length(Name) = 0 then + break; + Value := GetEnumValue(PTypeInfo(EnumType), Name); + if Value = -1 then begin + if (freader <> nil) and assigned(freader.fonseterror) then begin + freader.fonseterror(freader,enumtype,name,value); + end; + if value = -1 then begin + raise EReadError.Create(SInvalidPropertyValue); + end + else begin + if value = -2 then begin + continue; //skip + end; + end; + end; + include(tset(result),Value); + end; + except + SkipSetBody; + raise; + end; +end; + +function TBinaryObjectReader.ReadStr: String; +var + i: Byte; +begin + Read(i, 1); + SetLength(Result, i); + if i > 0 then + Read(Pointer(@Result[1])^, i); +end; + +function TBinaryObjectReader.ReadString(StringType: TValueType): String; +var + b: Byte; + i: Integer; +begin + case StringType of + vaLString, vaUTF8String: + i:=ReadDWord; + else + //vaString: + begin + Read(b, 1); + i := b; + end; + end; + SetLength(Result, i); + if i > 0 then + Read(Pointer(@Result[1])^, i); +end; + +function TBinaryObjectReader.Readutf8String(StringType: TValueType): utf8String; +var + b: Byte; + i: Integer; +begin + case StringType of + vaLString, vaUTF8String: + i:=ReadDWord; + else + //vaString: + begin + Read(b, 1); + i := b; + end; + end; + SetLength(Result, i); + if i > 0 then + Read(Pointer(@Result[1])^, i); +end; + + +function TBinaryObjectReader.ReadWideString: WideString; +var + len: DWord; +{$IFDEF ENDIAN_BIG} + i : integer; +{$ENDIF} +begin + len := ReadDWord; + SetLength(Result, len); + if (len > 0) then + begin + Read(Pointer(@Result[1])^, len*2); + {$IFDEF ENDIAN_BIG} + for i:=1 to len do + Result[i]:=widechar(SwapEndian(word(Result[i]))); + {$ENDIF} + end; +end; + +function TBinaryObjectReader.ReadUnicodeString: UnicodeString; +var + len: DWord; +{$IFDEF ENDIAN_BIG} + i : integer; +{$ENDIF} +begin + len := ReadDWord; + SetLength(Result, len); + if (len > 0) then + begin + Read(Pointer(@Result[1])^, len*2); + {$IFDEF ENDIAN_BIG} + for i:=1 to len do + Result[i]:=UnicodeChar(SwapEndian(word(Result[i]))); + {$ENDIF} + end; +end; + +procedure TBinaryObjectReader.SkipComponent(SkipComponentInfos: Boolean); +var + Flags: TFilerFlags; + Dummy: Integer; + CompClassName, CompName: String; +begin + if SkipComponentInfos then + { Skip prefix, component class name and component object name } + BeginComponent(Flags, Dummy, CompClassName, CompName); + + { Skip properties } + while NextValue <> vaNull do + SkipProperty; + ReadValue; + + { Skip children } + while NextValue <> vaNull do + SkipComponent(True); + ReadValue; +end; + +procedure TBinaryObjectReader.SkipValue; + + procedure SkipBytes(Count: LongInt); + var + Dummy: array[0..1023] of Byte; + SkipNow: Integer; + begin + while Count > 0 do + begin + if Count > 1024 then + SkipNow := 1024 + else + SkipNow := Count; + Read(Dummy, SkipNow); + Dec(Count, SkipNow); + end; + end; + +var + Count: LongInt; +begin + case ReadValue of + vaNull, vaFalse, vaTrue, vaNil: ; + vaList: + begin + while NextValue <> vaNull do + SkipValue; + ReadValue; + end; + vaInt8: + SkipBytes(1); + vaInt16: + SkipBytes(2); + vaInt32: + SkipBytes(4); + vaExtended: + SkipBytes(10); + vaString, vaIdent: + ReadStr; + vaBinary, vaLString,vautf8string: + begin + Count:=LongInt(ReadDWord); + SkipBytes(Count); + end; + vaWString: + begin + Count:=LongInt(ReadDWord); + SkipBytes(Count*sizeof(widechar)); + end; +{$ifdef FPC} + vaUString: + begin + Count:=LongInt(ReadDWord); + SkipBytes(Count*sizeof(widechar)); + end; +{$endif} + vaSet: + SkipSetBody; + vaCollection: + begin + while NextValue <> vaNull do + begin + { Skip the order value if present } + if NextValue in [vaInt8, vaInt16, vaInt32] then + SkipValue; + SkipBytes(1); + while NextValue <> vaNull do + SkipProperty; + ReadValue; + end; + ReadValue; + end; + vaSingle: +{$ifndef FPUNONE} + SkipBytes(Sizeof(Single)); +{$else} + SkipBytes(4); +{$endif} + {!!!: vaCurrency: + SkipBytes(SizeOf(Currency));} + vaDate, vaInt64: + SkipBytes(8); + end; +end; + +{ private methods } + +procedure TBinaryObjectReader.Read(var Buf; Count: LongInt); +var + CopyNow: LongInt; + Dest: Pointer; +begin + Dest := @Buf; + while Count > 0 do + begin + if FBufPos >= FBufEnd then + begin + FBufEnd := FStream.Read(FBuffer^, FBufSize); + if FBufEnd = 0 then + raise EReadError.Create(SReadError); + FBufPos := 0; + end; + CopyNow := FBufEnd - FBufPos; + if CopyNow > Count then + CopyNow := Count; + Move(PChar(FBuffer)[FBufPos], Dest^, CopyNow); + Inc(FBufPos, CopyNow); + Inc(pchar(Dest), CopyNow); + Dec(Count, CopyNow); + end; +end; + +procedure TBinaryObjectReader.SkipProperty; +begin + { Skip property name, then the property value } + ReadStr; + SkipValue; +end; + +procedure TBinaryObjectReader.SkipSetBody; +begin + while Length(ReadStr) > 0 do; +end; + +{ Object filing routines } + +var + IntConstList: TThreadList; + +type + TIntConst = class + IntegerType: PTypeInfo; // The integer type RTTI pointer + IdentToIntFn: TIdentToInt; // Identifier to Integer conversion + IntToIdentFn: TIntToIdent; // Integer to Identifier conversion + constructor Create(AIntegerType: PTypeInfo; AIdentToInt: TIdentToInt; + AIntToIdent: TIntToIdent); + end; + +constructor TIntConst.Create(AIntegerType: PTypeInfo; AIdentToInt: TIdentToInt; + AIntToIdent: TIntToIdent); +begin + IntegerType := AIntegerType; + IdentToIntFn := AIdentToInt; + IntToIdentFn := AIntToIdent; +end; + +procedure RegisterIntegerConsts(IntegerType: Pointer; IdentToIntFn: TIdentToInt; + IntToIdentFn: TIntToIdent); +begin + IntConstList.Add(TIntConst.Create(IntegerType, IdentToIntFn, IntToIdentFn)); +end; + +function FindIntToIdent(AIntegerType: Pointer): TIntToIdent; +var + i: Integer; +begin + with IntConstList.LockList do + try + for i := 0 to Count - 1 do + if TIntConst(Items[i]).IntegerType = AIntegerType then begin + result:= TIntConst(Items[i]).IntToIdentFn; + exit; + end; + Result := nil; + finally + IntConstList.UnlockList; + end; +end; + +function FindIdentToInt(AIntegerType: Pointer): TIdentToInt; +var + i: Integer; +begin + with IntConstList.LockList do + try + for i := 0 to Count - 1 do + with TIntConst(Items[I]) do + if TIntConst(Items[I]).IntegerType = AIntegerType then begin + result:= IdentToIntFn; + exit; + end; + Result := nil; + finally + IntConstList.UnlockList; + end; +end; + +function IdentToInt(const Ident: String; var Int: LongInt; + const Map: array of TIdentMapEntry): Boolean; +var + i: Integer; +begin + for i := Low(Map) to High(Map) do + if CompareText(Map[i].Name, Ident) = 0 then + begin + Int := Map[i].Value; + result:= true; + exit; + end; + Result := False; +end; + +function IntToIdent(Int: LongInt; var Ident: String; + const Map: array of TIdentMapEntry): Boolean; +var + i: Integer; +begin + for i := Low(Map) to High(Map) do + if Map[i].Value = Int then + begin + Ident := Map[i].Name; + result:= true; + exit; + end; + Result := False; +end; + +function GlobalIdentToInt(const Ident: String; var Int: LongInt):boolean; +var + i : Integer; +begin + with IntConstList.LockList do + try + for i := 0 to Count - 1 do + if TIntConst(Items[I]).IdentToIntFn(Ident, Int) then begin + result:= true; + Exit; + end; + Result := false; + finally + IntConstList.UnlockList; + end; +end; + +Var + InitHandlerList : TList; + FindGlobalComponentList : TList; + +Type + TInitHandler = Class(TObject) + AHandler : TInitComponentHandler; + AClass : TComponentClass; + end; +{$ifdef FPC} +function CreateComponentfromRes(const res : string;Inst : THandle;var Component : TComponent) : Boolean; + var + ResStream : TResourceStream; + begin + result:=true; + + if Inst=0 then + Inst:=HInstance; + + try + ResStream:=TResourceStream.Create(Inst,res,RT_RCDATA); + try + Component:=ResStream.ReadComponent(Component); + finally + ResStream.Free; + end; + except + on EResNotFound do + result:=false; + end; + end; +{$endif} + +function DefaultInitHandler(Instance: TComponent; RootAncestor: TClass): Boolean; + + function doinit(_class : TClass) : boolean; + begin + result:=false; + if (_class{.ClassType}=TComponent) or (_class{.ClassType}=RootAncestor) then + exit; + result:=doinit(_class.ClassParent); + {$ifdef FPC} + result:=CreateComponentfromRes(_class.ClassName,0,Instance) or result; + {$endif} + end; + + begin + GlobalNameSpace.BeginWrite; + try + result:=doinit(Instance.ClassType); + finally + GlobalNameSpace.EndWrite; + end; + end; + +function InitInheritedComponent(Instance: TComponent; RootAncestor: TClass): Boolean; +Var + I : Integer; +begin + I:=0; + if not Assigned(InitHandlerList) then begin + Result := True; + Exit; + end; + Result:=False; + With InitHandlerList do + begin + I:=0; + // Instance is the normally the lowest one, so that one should be used when searching. + While Not result and (INil); + If Result then + begin + C:=FindNestedComponent(C,FRelative); + Result:=C<>Nil; + If Result then + SetObjectProp(Instance, FPropInfo,C); + end; +end; + +Function TUnresolvedReference.RootMatches(ARoot : TComponent) : Boolean; {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE} + +begin + Result:=(ARoot=Nil) or (ARoot=FRoot); +end; + +Function TUnResolvedReference.NextRef : TUnresolvedReference; + +begin + Result:=TUnresolvedReference(Next); +end; + +{ tfixups } + +constructor tfixups.create; +begin + inherited create(TUnresolvedReference); +end; + +function tfixups.newreference(const aprop: ppropinfo): TUnResolvedReference; +begin + result:= tunresolvedreference(root); + while result <> nil do begin + if (result.fpropinfo = aprop) then begin + exit; + end; + result:= tunresolvedreference(result.next); + end; + result:= tunresolvedreference(add); +end; + +{ tlocalfixups } + +constructor tlocalfixups.create; +begin + inherited create(TLocalUnresolvedReference); +end; + +function tlocalfixups.newreference(const ainstance: tpersistent; + const aprop: ppropinfo): TLocalUnResolvedReference; +begin + result:= tlocalunresolvedreference(root); + while result <> nil do begin + if ((result.finstance) = ainstance) and (result.fpropinfo = aprop) then begin + exit; + end; + result:= tlocalunresolvedreference(result.next); + end; + result:= tlocalunresolvedreference(add); +end; + +{ TUnResolvedInstance } + +destructor TUnResolvedInstance.Destroy; +begin + FUnresolved.Free; + inherited Destroy; +end; + +function TUnResolvedInstance.AddReference(ARoot: TComponent; + APropInfo: PPropInfo; AGlobal, ARelative: String): TUnresolvedReference; +begin + If (FUnResolved = Nil) then begin + FUnResolved:= tfixups.create; + end; + Result:= FUnResolved.newreference(apropinfo); + Result.FGlobal:=AGLobal; + Result.FRelative:=ARelative; + Result.FPropInfo:=APropInfo; + Result.FRoot:=ARoot; +end; + +Function TUnResolvedInstance.RootUnresolved : TUnresolvedReference; + +begin + Result:=Nil; + If Assigned(FUnResolved) then + Result:=TUnresolvedReference(FUnResolved.Root); +end; + +Function TUnResolvedInstance.ResolveReferences:Boolean; + +Var + R,RN : TUnresolvedReference; + +begin + R:=RootUnResolved; + While (R<>Nil) do + begin + RN:=R.NextRef; + If R.Resolve(Self.Instance) then + FUnresolved.RemoveItem(R,True); + R:=RN; + end; + Result:=RootUnResolved=Nil; +end; + +{ TReferenceNamesVisitor } + +Constructor TReferenceNamesVisitor.Create(ARoot : TComponent;AList : TStrings); + +begin + FRoot:=ARoot; + FList:=AList; +end; + +Function TReferenceNamesVisitor.Visit(Item : TLinkedListItem) : Boolean; + +Var + R : TUnresolvedReference; + +begin + R:=TUnResolvedInstance(Item).RootUnresolved; + While (R<>Nil) do + begin + If R.RootMatches(FRoot) then + If (FList.IndexOf(R.FGlobal)=-1) then + FList.Add(R.FGlobal); + R:=R.NextRef; + end; + Result:=True; +end; + +{ TReferenceInstancesVisitor } + +Constructor TReferenceInstancesVisitor.Create(ARoot : TComponent; Const ARef : String;AList : TStrings); + +begin + FRoot:=ARoot; + FRef:=UpperCase(ARef); + FList:=AList; +end; + +Function TReferenceInstancesVisitor.Visit(Item : TLinkedListItem) : Boolean; + +Var + R : TUnresolvedReference; + +begin + R:=TUnResolvedInstance(Item).RootUnresolved; + While (R<>Nil) do + begin + If (FRoot=R.FRoot) and (FRef=UpperCase(R.FGLobal)) Then + If Flist.IndexOf(R.FRelative)=-1 then + Flist.Add(R.FRelative); + R:=R.NextRef; + end; + Result:=True; +end; + +{ TRedirectReferenceVisitor } + +Constructor TRedirectReferenceVisitor.Create(ARoot : TComponent; Const AOld,ANew : String); + +begin + FRoot:=ARoot; + FOld:=UpperCase(AOld); + FNew:=ANew; +end; + +Function TRedirectReferenceVisitor.Visit(Item : TLinkedListItem) : Boolean; + +Var + R : TUnresolvedReference; + +begin + R:=TUnResolvedInstance(Item).RootUnresolved; + While (R<>Nil) do + begin + If R.RootMatches(FRoot) and (FOld=UpperCase(R.FGLobal)) Then + R.FGlobal:=FNew; + R:=R.NextRef; + end; + Result:=True; +end; + +{ TRemoveReferenceVisitor } + +Constructor TRemoveReferenceVisitor.Create(ARoot : TComponent; Const ARef : String); + +begin + FRoot:=ARoot; + FRef:=UpperCase(ARef); +end; + +Function TRemoveReferenceVisitor.Visit(Item : TLinkedListItem) : Boolean; + +Var + I : Integer; + UI : TUnResolvedInstance; + R : TUnresolvedReference; + L : TFPList; + +begin + UI:=TUnResolvedInstance(Item); + R:=UI.RootUnresolved; + L:=Nil; + Try + // Collect all matches. + While (R<>Nil) do + begin + If R.RootMatches(FRoot) and ((FRef = '') or (FRef=UpperCase(R.FGLobal))) Then + begin + If Not Assigned(L) then + L:=TFPList.Create; + L.Add(R); + end; + R:=R.NextRef; + end; + // Remove all matches. + IF Assigned(L) then + begin + For I:=0 to L.Count-1 do + UI.FUnresolved.RemoveItem(TLinkedListitem(L[i]),True); + end; + // If any references are left, leave them. + If UI.FUnResolved.Root=Nil then + begin + If List=Nil then + List:=TFPList.Create; + List.Add(UI); + end; + Finally + L.Free; + end; + Result:=True; +end; + +{ TBuildListVisitor } + +Procedure TBuildListVisitor.Add(Item : TlinkedListItem); + +begin + If (List=Nil) then + List:=TFPList.Create; + List.Add(Item); +end; + +Destructor TBuildListVisitor.Destroy; + +Var + I : Integer; + +begin + If Assigned(List) then + For I:=0 to List.Count-1 do + NeedResolving.RemoveItem(TLinkedListItem(List[I]),True); + FreeAndNil(List); + Inherited; +end; + +{ TResolveReferenceVisitor } + +Function TResolveReferenceVisitor.Visit(Item : TLinkedListItem) : Boolean; + +begin + If TUnResolvedInstance(Item).ResolveReferences then + Add(Item); + Result:=True; +end; + +// Add an instance to the global list of instances which need resolving. +Function FindUnresolvedInstance(AInstance: TPersistent) : TUnResolvedInstance; + +begin + Result:=Nil; + EnterCriticalSection(ResolveSection); + Try + If Assigned(NeedResolving) then + begin + Result:=TUnResolvedInstance(NeedResolving.Root); + While (Result<>Nil) and (Result.Instance<>AInstance) do + Result:=TUnResolvedInstance(Result.Next); + end; + finally + LeaveCriticalSection(ResolveSection); + end; +end; + +Function AddtoResolveList(AInstance: TPersistent) : TUnResolvedInstance; + +begin + Result:=FindUnresolvedInstance(AInstance); + If (Result=Nil) then + begin + EnterCriticalSection(ResolveSection); + Try + If not Assigned(NeedResolving) then + NeedResolving:=TLinkedList.Create(TUnResolvedInstance); + Result:=NeedResolving.Add as TUnResolvedInstance; + Result.Instance:=AInstance; + finally + LeaveCriticalSection(ResolveSection); + end; + end; +end; + +// Walk through the global list of instances to be resolved. + +Procedure VisitResolveList(V : TLinkedListVisitor); + +begin + EnterCriticalSection(ResolveSection); + Try + try + NeedResolving.Foreach(V); + Finally + FreeAndNil(V); + end; + Finally + LeaveCriticalSection(ResolveSection); + end; +end; + +procedure GlobalFixupReferences; + +begin + If (NeedResolving=Nil) then + Exit; + GlobalNameSpace.BeginWrite; + try + VisitResolveList(TResolveReferenceVisitor.Create); + finally + GlobalNameSpace.EndWrite; + end; +end; + +procedure GetFixupReferenceNames(Root: TComponent; Names: TStrings); + +begin + If (NeedResolving=Nil) then + Exit; + VisitResolveList(TReferenceNamesVisitor.Create(Root,Names)); +end; + +procedure GetFixupInstanceNames(Root: TComponent; const ReferenceRootName: string; Names: TStrings); + +begin + If (NeedResolving=Nil) then + Exit; + VisitResolveList(TReferenceInstancesVisitor.Create(Root,ReferenceRootName,Names)); +end; + +procedure RedirectFixupReferences(Root: TComponent; const OldRootName, NewRootName: string); + +begin + If (NeedResolving=Nil) then + Exit; + VisitResolveList(TRedirectReferenceVisitor.Create(Root,OldRootName,NewRootName)); +end; + +procedure RemoveFixupReferences(Root: TComponent; const RootName: string); + +begin + If (NeedResolving=Nil) then + Exit; + VisitResolveList(TRemoveReferenceVisitor.Create(Root,RootName)); +end; + +procedure RemoveFixups(Instance: TPersistent); + +begin + // This needs work. +{ + if not Assigned(GlobalFixupList) then + exit; + + with GlobalFixupList.LockList do + try + for i := Count - 1 downto 0 do + begin + CurFixup := TPropFixup(Items[i]); + if (CurFixup.FInstance = Instance) then + begin + Delete(i); + CurFixup.Free; + end; + end; + finally + GlobalFixupList.UnlockList; + end; +} +end; + +Function FindNestedComponent(Root : TComponent; APath : String; CStyle : Boolean = True) : TComponent; + + Function GetNextName : String; {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE} + + Var + P : Integer; + CM : Boolean; + + begin + P:=Pos('.',APath); + CM:=False; + If (P=0) then + begin + If CStyle then + begin + P:=Pos('->',APath); + CM:=P<>0; + end; + If (P=0) Then + P:=Length(APath)+1; + end; + Result:=Copy(APath,1,P-1); + Delete(APath,1,P+Ord(CM)); + end; + +Var + C : TComponent; + S : String; +begin + If (APath='') then + Result:=Nil + else + begin + Result:=Root; + While (APath<>'') And (Result<>Nil) do + begin + C:=Result; + S:=Uppercase(GetNextName); + Result:=C.FindComponent(S); + If (Result=Nil) And (S='OWNER') then + Result:=C; + end; + end; +end; + +type + tglobloadlist = class(tfplist) + protected + fsuspended: integer; + public + procedure beginsuspend; + procedure endsuspend; + end; + +threadvar + GlobalLoaded: tglobloadlist; + GlobalLists: TFpList; + +{ tglobloadlist } + +procedure tglobloadlist.beginsuspend; +begin + inc(fsuspended); +end; + +procedure tglobloadlist.endsuspend; +begin + dec(fsuspended); +end; + +procedure beginsuspendgloballoading; +begin + if globalloaded <> nil then begin + globalloaded.beginsuspend; + end; +end; + +procedure endsuspendgloballoading; +begin + if globalloaded <> nil then begin + globalloaded.endsuspend; + end; +end; + +procedure BeginGlobalLoading; + +begin + if not Assigned(GlobalLists) then + GlobalLists := TFpList.Create; + GlobalLists.Add(GlobalLoaded); + GlobalLoaded := tglobloadlist.Create; +end; + +procedure NotifyGlobalLoading; +var + i: Integer; +begin + for i := 0 to GlobalLoaded.Count - 1 do + TComponent(GlobalLoaded[i]).Loaded; +end; + +procedure EndGlobalLoading; +begin + { Free the memory occupied by BeginGlobalLoading } + GlobalLoaded.Free; + GlobalLoaded := tglobloadlist(GlobalLists.Last); + GlobalLists.Delete(GlobalLists.Count - 1); + if GlobalLists.Count = 0 then + begin + GlobalLists.Free; + GlobalLists := nil; + end; +end; + +function CollectionsEqual(C1, C2: TCollection): Boolean; +begin + // !!!: Implement this + CollectionsEqual:=false; +end; + +function CollectionsEqual(C1, C2: TCollection; Owner1, Owner2: TComponent): Boolean; + + procedure stream_collection(s : tstream;c : tcollection;o : tcomponent); + var + w : twriter; + begin + w:=twriter.create(s,4096); + try + w.root:=o; + w.flookuproot:=o; + w.writecollection(c); + finally + w.free; + end; + end; + + var + s1,s2 : tmemorystream; + begin + result:=false; + if (c1.classtype<>c2.classtype) or + (c1.count<>c2.count) then + exit; + if c1.count = 0 then + begin + result:= true; + exit; + end; + s1:=tmemorystream.create; + try + s2:=tmemorystream.create; + try + stream_collection(s1,c1,owner1); + stream_collection(s2,c2,owner2); + result:=(s1.size=s2.size) and + {$ifdef FPC} + (CompareChar(s1.memory^,s2.memory^,s1.size) = 0); + {$else} + Comparemem(s1.memory,s2.memory,s1.size); + {$endif} + finally + s2.free; + end; + finally + s1.free; + end; + end; + + +{ ********************************************************************* + * TFiler * + *********************************************************************} + +procedure TFiler.SetRoot(ARoot: TComponent); +begin + FRoot := ARoot; +end; + +{****************************************************************************} +{* TREADER *} +{****************************************************************************} + +type + TFieldInfo = packed record + FieldOffset: LongWord; + ClassTypeIndex: Word; + Name: ShortString; + end; + + PFieldClassTable = ^TFieldClassTable; + TFieldClassTable = +{$ifndef FPC_REQUIRES_PROPER_ALIGNMENT} + packed +{$endif FPC_REQUIRES_PROPER_ALIGNMENT} + record + Count: Word; + {$ifdef FPC} + {$ifdef mse_fpc_3_2} + Entries: array[Word] of ^TPersistentClass; + {$else} + Entries: array[Word] of TPersistentClass; + {$endif} + {$else} + Entries: array[Word] of ^TPersistentClass; + {$endif} + end; + + PFieldTable = ^TFieldTable; + TFieldTable = +{$ifndef FPC_REQUIRES_PROPER_ALIGNMENT} + packed +{$endif FPC_REQUIRES_PROPER_ALIGNMENT} + record + FieldCount: Word; + ClassTable: PFieldClassTable; + // Fields: array[Word] of TFieldInfo; Elements have variant size! + end; + +function getfieldclasstable(const aclass: tclass): pfieldclasstable; +begin + pointer(result):= ppointer(pchar(pointer(aclass))+vmtFieldTable)^; + if result <> nil then begin + result:= pfieldtable(pointer(result))^.classtable; + end; +end; + +function GetFieldClass(Instance: TObject; const ClassName: string): TPersistentClass; +var + UClassName: String; + ClassType: TClass; + ClassTable: PFieldClassTable; + i: Integer; +begin + // At first, try to locate the class in the class tables + UClassName := UpperCase(ClassName); + ClassType := Instance.ClassType; + while ClassType <> TPersistent do + begin + classtable:= getfieldclasstable(classtype); + if Assigned(ClassTable) then + for i := 0 to ClassTable^.Count - 1 do + begin + {$ifdef FPC} + {$ifdef mse_fpc_3_2} + Result := ClassTable^.Entries[i]^; + {$else} + Result := ClassTable^.Entries[i]; + {$endif} + {$else} + Result := ClassTable^.Entries[i]^; + {$endif} + if UpperCase(Result.ClassName) = UClassName then + exit; + end; + // Try again with the parent class type + ClassType := ClassType.ClassParent; + end; + Result := GetClass(ClassName); +end; + + +constructor TReader.Create(Stream: TStream; BufSize: Integer); +begin + inherited Create; + If (Stream=Nil) then + Raise EReadError.Create(SEmptyStreamIllegalReader); + FDriver := CreateDriver(Stream, BufSize); + fdriver.freader:= self; +end; + +destructor TReader.Destroy; +begin + FDriver.Free; + inherited Destroy; +end; + +function TReader.CreateDriver(Stream: TStream; BufSize: Integer): TAbstractObjectReader; +begin + Result := TBinaryObjectReader.Create(Stream, BufSize); +end; + +procedure TReader.BeginReferences; +begin + FLoaded := TFpList.Create; +end; + +procedure TReader.CheckValue(Value: TValueType); +begin + if FDriver.NextValue <> Value then + raise EReadError.Create(SInvalidPropertyValue) + else + FDriver.ReadValue; +end; + +procedure TReader.DefineProperty(const Name: String; AReadData: TReaderProc; + WriteData: TWriterProc; HasData: Boolean); +begin + if Assigned(AReadData) and (UpperCase(Name) = UpperCase(FPropName)) then + begin + AReadData(Self); + SetLength(FPropName, 0); + end; +end; + +procedure TReader.DefineBinaryProperty(const Name: String; + AReadData, WriteData: TStreamProc; HasData: Boolean); +var + MemBuffer: TMemoryStream; +begin + if Assigned(AReadData) and (UpperCase(Name) = UpperCase(FPropName)) then + begin + { Check if the next property really is a binary property} + if FDriver.NextValue <> vaBinary then + begin + FDriver.SkipValue; + FCanHandleExcepts := True; + raise EReadError.Create(SInvalidPropertyValue); + end else + FDriver.ReadValue; + + MemBuffer := TMemoryStream.Create; + try + FDriver.ReadBinary(MemBuffer); + FCanHandleExcepts := True; + AReadData(MemBuffer); + finally + MemBuffer.Free; + end; + SetLength(FPropName, 0); + end; +end; + +function treader.beginoflist(): boolean; +begin + result:= fdriver.nextvalue = valist; +end; + +function TReader.EndOfList: Boolean; +begin + Result := FDriver.NextValue = vaNull; +end; + +procedure TReader.EndReferences; +begin + FLoaded.Free; + FLoaded := nil; +end; + +function TReader.Error(const Message: String): Boolean; +begin + Result := False; + if Assigned(FOnError) then + FOnError(Self, Message, Result); +end; + +function TReader.FindMethod(ARoot: TComponent; const AMethodName: String): Pointer; +var + ErrorResult: Boolean; +begin + Result := ARoot.MethodAddress(AMethodName); + ErrorResult := Result = nil; + + { always give the OnFindMethod callback a chance to locate the method } + if Assigned(FOnFindMethod) then + FOnFindMethod(Self, AMethodName, Result, ErrorResult); + + if ErrorResult then + raise EReadError.Create(SInvalidPropertyValue); +end; + +procedure TReader.DoFixupReferences; + +Var + R,RN : TLocalUnresolvedReference; + G : TUnresolvedInstance; + Ref : String; + C : TComponent; + P : integer; + L : TLinkedList; + +begin + If Assigned(FFixups) then + begin + L:=TLinkedList(FFixups); + R:=TLocalUnresolvedReference(L.Root); + While (R<>Nil) do + begin + RN:=TLocalUnresolvedReference(R.Next); + Ref:=R.FRelative; + If Assigned(FOnReferenceName) then + FOnReferenceName(Self,Ref); + C:=FindNestedComponent(R.FRoot,Ref); + If Assigned(C) then + SetObjectProp(R.FInstance,R.FPropInfo,C) + else begin + P:=Pos('.',R.FRelative); + If (P<>0) then begin + G:= AddToResolveList(R.FInstance); + G.Addreference(R.FRoot,R.FPropInfo,Copy(R.FRelative,1,P-1),Copy(R.FRelative,P+1,Length(R.FRelative)-P)); + end; + end; + L.RemoveItem(R,True); + R:=RN; + end; + FreeAndNil(FFixups); + end; +end; + +procedure TReader.FixupReferences; +var + i: Integer; +begin + DoFixupReferences; + GlobalFixupReferences; + for i := 0 to FLoaded.Count - 1 do + TComponent(FLoaded[I]).Loaded; +end; + + +function TReader.NextValue: TValueType; +begin + Result := FDriver.NextValue; +end; + +procedure TReader.Read(var Buf; Count: LongInt); +begin + //This should give an exception if read is not implemented (i.e. TTextObjectReader) + //but should work with TBinaryObjectReader. + Driver.Read(Buf, Count); +end; + +procedure TReader.PropertyError; +begin + FDriver.SkipValue; + raise EReadError.CreateFmt(SUnknownProperty,[FPropName]); +end; + +function TReader.ReadBoolean: Boolean; +var + ValueType: TValueType; +begin + ValueType := FDriver.ReadValue; + if ValueType = vaTrue then + Result := True + else if ValueType = vaFalse then + Result := False + else + raise EReadError.Create(SInvalidPropertyValue); +end; + +function TReader.ReadChar: Char; +var + s: String; +begin + s := ReadString; + if Length(s) = 1 then + Result := s[1] + else + raise EReadError.Create(SInvalidPropertyValue); +end; + +function TReader.ReadWideChar: WideChar; + +var + W: WideString; + +begin + W := ReadWideString; + if Length(W) = 1 then + Result := W[1] + else + raise EReadError.Create(SInvalidPropertyValue); +end; + +function TReader.ReadUnicodeChar: UnicodeChar; + +var + U: UnicodeString; + +begin + U := ReadUnicodeString; + if Length(U) = 1 then + Result := U[1] + else + raise EReadError.Create(SInvalidPropertyValue); +end; + +procedure TReader.ReadCollection(Collection: TCollection); +var + Item: TCollectionItem; +begin + Collection.BeginUpdate; + if not EndOfList then + Collection.Clear; + while not EndOfList do begin + ReadListBegin; + Item := Collection.Add; + while NextValue<>vaNull do + ReadProperty(Item); + ReadListEnd; + end; + Collection.EndUpdate; + ReadListEnd; +end; + +function TReader.ReadComponent(Component: TComponent): TComponent; +var + Flags: TFilerFlags; + + function Recover(var Component: TComponent): Boolean; + begin + Result := False; + if ExceptObject.InheritsFrom(Exception) then + begin + if not ((ffInherited in Flags) or Assigned(Component)) then + Component.Free; + Component := nil; + FDriver.SkipComponent(False); + Result := Error(Exception(ExceptObject).Message); + end; + end; + +var + CompClassName, Name: String; + n, ChildPos: Integer; + SavedParent, SavedLookupRoot: TComponent; + ComponentClass: TComponentClass; + C, NewComponent: TComponent; + SubComponents: TList; +begin + FDriver.BeginComponent(Flags, ChildPos, CompClassName, Name); + SavedParent := Parent; + SavedLookupRoot := FLookupRoot; + SubComponents := nil; + try + Result := Component; + if not Assigned(Result) then + try + if ffInherited in Flags then + begin + { Try to locate the existing ancestor component } + + if Assigned(FLookupRoot) then + Result := FLookupRoot.FindComponent(Name) + else + Result := nil; + + if not Assigned(Result) then + begin + if Assigned(FOnAncestorNotFound) then + FOnAncestorNotFound(Self, Name, + FindComponentClass(CompClassName,flags), Result); + if not Assigned(Result) then + raise EReadError.CreateFmt(SAncestorNotFound, [Name]); + end; + + Parent := Result.GetParentComponent; + if not Assigned(Parent) then + Parent := Root; + end else + begin + Result := nil; + ComponentClass := FindComponentClass(CompClassName,flags); + if Assigned(FOnCreateComponent) then + FOnCreateComponent(Self, ComponentClass, Result); + if not Assigned(Result) then + begin + NewComponent := TComponent(ComponentClass.NewInstance); + if ffInline in Flags then + NewComponent.FComponentState := + NewComponent.FComponentState + [csLoading, csInline]; + NewComponent.Create(Owner); + + { Don't set Result earlier because else we would come in trouble + with the exception recover mechanism! (Result should be NIL if + an error occured) } + Result := NewComponent; + end; + Include(Result.FComponentState, csLoading); + end; + except + if not Recover(Result) then + raise; + end; + + if Assigned(Result) then + try + Include(Result.FComponentState, csLoading); + + { create list of subcomponents and set loading} + SubComponents := TList.Create; + for n := 0 to Result.ComponentCount - 1 do + begin + C := Result.Components[n]; + if csSubcomponent in C.ComponentStyle + then begin + SubComponents.Add(C); + Include(C.FComponentState, csLoading); + end; + end; + + if not (ffInherited in Flags) then + try + Result.SetParentComponent(Parent); + if Assigned(FOnSetName) then + FOnSetName(Self, Result, Name); + Result.Name := Name; + if FindGlobalComponent(Name) = Result then + Include(Result.FComponentState, csInline); + except + if not Recover(Result) then + raise; + end; + if not Assigned(Result) then + exit; + if csInline in Result.ComponentState then + FLookupRoot := Result; + + { Read the component state } + Include(Result.FComponentState, csReading); + for n := 0 to Subcomponents.Count - 1 do + Include(TComponent(Subcomponents[n]).FComponentState, csReading); + + Result.ReadState(Self); + + Exclude(Result.FComponentState, csReading); + for n := 0 to Subcomponents.Count - 1 do + Exclude(TComponent(Subcomponents[n]).FComponentState, csReading); + + if ffChildPos in Flags then + Parent.SetChildOrder(Result, ChildPos); + + { Add component to list of loaded components, if necessary } + if (not ((ffInherited in Flags) or (csInline in Result.ComponentState))) or + (FLoaded.IndexOf(Result) < 0) + then begin + for n := 0 to Subcomponents.Count - 1 do + FLoaded.Add(Subcomponents[n]); + FLoaded.Add(Result); + end; + except + if ((ffInherited in Flags) or Assigned(Component)) then + Result.Free; + raise; + end; + finally + Parent := SavedParent; + FLookupRoot := SavedLookupRoot; + Subcomponents.Free; + end; +end; + +procedure TReader.ReadData(Instance: TComponent); +var + SavedOwner, SavedParent: TComponent; + +begin + { Read properties } + while not EndOfList do + ReadProperty(Instance); + ReadListEnd; + + { Read children } + SavedOwner := Owner; + SavedParent := Parent; + try + Owner := Instance.GetChildOwner; + if not Assigned(Owner) then + Owner := Root; + Parent := Instance.GetChildParent; + + while not EndOfList do + ReadComponent(nil); + ReadListEnd; + finally + Owner := SavedOwner; + Parent := SavedParent; + end; + + { Fixup references if necessary (normally only if this is the root) } + If (Instance=FRoot) then + DoFixupReferences; +end; + +{$ifndef FPUNONE} +function TReader.ReadFloat: Extended; +begin + if FDriver.NextValue = vaExtended then + begin + ReadValue; + Result := FDriver.ReadFloat + end else + Result := ReadInteger; +end; + +function TReader.ReadSingle: Single; +begin + if FDriver.NextValue = vaSingle then + begin + FDriver.ReadValue; + Result := FDriver.ReadSingle; + end else + Result := ReadInteger; +end; +{$endif} + +function TReader.ReadCurrency: Currency; +begin + if FDriver.NextValue = vaCurrency then + begin + FDriver.ReadValue; + Result := FDriver.ReadCurrency; + end else + Result := ReadInteger; +end; + +{$ifndef FPUNONE} +function TReader.ReadDate: TDateTime; +begin + if FDriver.NextValue = vaDate then + begin + FDriver.ReadValue; + Result := FDriver.ReadDate; + end else + Result := ReadInteger; +end; +{$endif} + +function TReader.ReadIdent: String; +var + ValueType: TValueType; +begin + ValueType := FDriver.ReadValue; + if ValueType in [vaIdent, vaNil, vaFalse, vaTrue, vaNull] then + Result := FDriver.ReadIdent(ValueType) + else + raise EReadError.Create(SInvalidPropertyValue); +end; + + +function TReader.ReadInteger: LongInt; +begin + case FDriver.ReadValue of + vaInt8: + Result := FDriver.ReadInt8; + vaInt16: + Result := FDriver.ReadInt16; + vaInt32: + Result := FDriver.ReadInt32; + else + raise EReadError.Create(SInvalidPropertyValue); + end; +end; + +function TReader.ReadInt64: Int64; +begin + if FDriver.NextValue = vaInt64 then + begin + FDriver.ReadValue; + Result := FDriver.ReadInt64; + end else + Result := ReadInteger; +end; + +function treader.readset(settype: ptypeinfo): longword; +begin + if fdriver.nextvalue = vaset then begin + fdriver.readvalue; + result:= fdriver.readset( + gettypedata(settype)^.comptype{$ifndef FPC}^{$endif}); + end + else begin + result:= readinteger; + end; +end; + +procedure TReader.ReadListBegin; +begin + CheckValue(vaList); +end; + +procedure TReader.ReadListEnd; +begin + CheckValue(vaNull); +end; + +function TReader.ReadVariant: variant; +var + nv: TValueType; +begin +{$ifdef FPC} + { Ensure that a Variant manager is installed } + if not Assigned(VarClearProc) then + raise EReadError.Create(SErrNoVariantSupport); +{$endif} + FillChar(Result,sizeof(Result),0); + + nv:=NextValue; + case nv of + vaNil: + begin + Result:= {$ifdef FPC}system.{$endif}unassigned; + readvalue; + end; + vaNull: + begin + Result:= {$ifdef FPC}system.{$endif}null; + readvalue; + end; + { all integer sizes must be split for big endian systems } + vaInt8,vaInt16,vaInt32: + begin + Result:=ReadInteger; + end; + vaInt64: + begin + Result:=ReadInt64; + end; + vaQWord: + begin + Result:=QWord(ReadInt64); + end; + vaFalse,vaTrue: + begin + Result:=(nv<>vaFalse); + end; + vaCurrency: + begin + Result:=ReadCurrency; + end; +{$ifndef fpunone} + vaSingle: + begin + Result:=ReadSingle; + end; + vaExtended: + begin + Result:=ReadFloat; + end; + vaDate: + begin + Result:=ReadDate; + end; +{$endif fpunone} + vaWString,vaUTF8String: + begin + Result:=ReadWideString; + end; + vaString: + begin + Result:=ReadString; + end; + vaUString: + begin + Result:=ReadUnicodeString; + end; + else + raise EReadError.CreateFmt(SUnsupportedPropertyVariantType, [Ord(nv)]); + end; +end; + +procedure TReader.ReadProperty(AInstance: TPersistent); +var + Path: String; + Instance: TPersistent; + DotPos, NextPos: PChar; + PropInfo: PPropInfo; + Obj: TObject; + Name: String; + Skip: Boolean; + Handled: Boolean; + OldPropName: String; + + function HandleMissingProperty(IsPath: Boolean): boolean; + begin + Result:=true; + if Assigned(OnPropertyNotFound) then begin + // user defined property error handling + OldPropName:=FPropName; + Handled:=false; + Skip:=false; + OnPropertyNotFound(Self,Instance,FPropName,IsPath,Handled,Skip); + if Handled and (not Skip) and (OldPropName<>FPropName) then + // try alias property + PropInfo := GetPropInfo(Instance.ClassInfo, FPropName); + if Skip then begin + FDriver.SkipValue; + Result:=false; + exit; + end; + end; + end; + +begin + try + Path := FDriver.BeginProperty; + try + Instance := AInstance; + FCanHandleExcepts := True; + DotPos := PChar(Path); + while True do + begin + NextPos := StrScan(DotPos, '.'); + if Assigned(NextPos) then + FPropName := Copy(String(DotPos), 1, Integer(NextPos - DotPos)) + else + begin + FPropName := DotPos; + break; + end; + DotPos := NextPos + 1; + + PropInfo := GetPropInfo(Instance.ClassInfo, FPropName); + if not Assigned(PropInfo) then begin + if not HandleMissingProperty(true) then exit; + if not Assigned(PropInfo) then + PropertyError; + end; + + if PropInfo^.PropType^.Kind = tkClass then + Obj := TObject(GetObjectProp(Instance, PropInfo)) + else + Obj := nil; + + if not (Obj is TPersistent) then + begin + { All path elements must be persistent objects! } + FDriver.SkipValue; + raise EReadError.Create(SInvalidPropertyPath); + end; + Instance := TPersistent(Obj); + end; + + PropInfo := GetPropInfo(Instance.ClassInfo, FPropName); + if Assigned(PropInfo) then + ReadPropValue(Instance, PropInfo) + else + begin + FCanHandleExcepts := False; + Instance.DefineProperties(Self); + FCanHandleExcepts := True; + if Length(FPropName) > 0 then begin + if not HandleMissingProperty(false) then exit; + if not Assigned(PropInfo) then + PropertyError; + end; + end; + except + on e: Exception do + begin + SetLength(Name, 0); + if AInstance.InheritsFrom(TComponent) then + Name := TComponent(AInstance).Name; + if Length(Name) = 0 then + Name := AInstance.ClassName; + raise EReadError.CreateFmt(SPropertyException, + [Name, DotSep, Path, e.Message]); + end; + end; + except + on e: Exception do + if not FCanHandleExcepts or not Error(E.Message) then + raise; + end; +end; + +procedure TReader.ReadPropValue(Instance: TPersistent; PropInfo: Pointer); +const + NullMethod: TMethod = (Code: nil; Data: nil); +var + PropType: PTypeInfo; + Value: LongInt; +{ IdentToIntFn: TIdentToInt; } + Ident: String; + Method: TMethod; + Handled: Boolean; + TmpStr: String; + TmpStr8: utf8String; +begin + if not Assigned(PPropInfo(PropInfo)^.SetProc) then + raise EReadError.Create(SReadOnlyProperty); + +{$ifdef FPC} + PropType := PPropInfo(PropInfo)^.PropType; +{$else} + PropType := PPropInfo(PropInfo)^.PropType^; +{$endif} + case PropType^.Kind of + tkInteger: + if FDriver.NextValue = vaIdent then + begin + Ident := ReadIdent; + if GlobalIdentToInt(Ident,Value) then + SetOrdProp(Instance, PropInfo, Value) + else + raise EReadError.Create(SInvalidPropertyValue); + end else + SetOrdProp(Instance, PropInfo, ReadInteger); +{$ifdef FPC} + tkBool: + SetOrdProp(Instance, PropInfo, Ord(ReadBoolean)); +{$endif} + tkChar: + SetOrdProp(Instance, PropInfo, Ord(ReadChar)); + tkWChar{$ifdef FPC},tkUChar{$endif}: + SetOrdProp(Instance, PropInfo, Ord(ReadWideChar)); + tkEnumeration: + begin + ident:= ReadIdent; + Value := GetEnumValue(PropType, ident); + if Value = -1 then begin + if assigned(fonenumerror) then begin + fonenumerror(self,proptype,ident,value); + end; + end; + if Value = -1 then begin + raise EReadError.Create(SInvalidPropertyValue); + end; + SetOrdProp(Instance, PropInfo, Value); + end; +{$ifndef FPUNONE} + tkFloat: + SetFloatProp(Instance, PropInfo, ReadFloat); +{$endif} + tkSet: + begin + CheckValue(vaSet); + SetOrdProp(Instance, PropInfo, + {$ifdef FPC} + FDriver.ReadSet(GetTypeData(PropType)^.CompType)); + {$else} + FDriver.ReadSet(GetTypeData(PropType)^.CompType^)); + {$endif} + end; + tkMethod: + if FDriver.NextValue = vaNil then + begin + FDriver.ReadValue; + SetMethodProp(Instance, PropInfo, NullMethod); + end else + begin + Handled:=false; + Ident:=ReadIdent; + if Assigned(OnSetMethodProperty) then + OnSetMethodProperty(Self,Instance,PPropInfo(PropInfo),Ident, + Handled); + if not Handled then begin + Method.Code := FindMethod(Root, Ident); + Method.Data := Root; + if Assigned(Method.Code) then + SetMethodProp(Instance, PropInfo, Method); + end; + end; + {$ifdef FPC} + tkSString, tkLString, tkAString: + {$else} + tkString, tkLString: + {$endif} + begin + if proptype = typeinfo(utf8string) then begin + TmpStr8:=Readutf8String; + if Assigned(FOnReadStringProperty) then begin + tmpstr:= tmpstr8; + FOnReadStringProperty(Self,Instance,PropInfo,TmpStr); + tmpstr8:= tmpstr; + end; + SetStrProp(Instance, PropInfo, TmpStr8); + end + else begin + TmpStr:=ReadString; + if Assigned(FOnReadStringProperty) then + FOnReadStringProperty(Self,Instance,PropInfo,TmpStr); + SetStrProp(Instance, PropInfo, TmpStr); + end; + end; + {$ifdef FPC} + tkUstring: + SetUnicodeStrProp(Instance,PropInfo,ReadUnicodeString); + {$endif} + tkWString: + SetWideStrProp(Instance,PropInfo,ReadWideString); + tkVariant: + begin + SetVariantProp(Instance,PropInfo,ReadVariant); + end; + tkClass: + case FDriver.NextValue of + vaNil: + begin + FDriver.ReadValue; + SetOrdProp(Instance, PropInfo, 0) + end; + vaCollection: + begin + FDriver.ReadValue; + ReadCollection(TCollection(GetObjectProp(Instance, PropInfo))); + end + else begin + If Not Assigned(FFixups) then begin +// FFixups:=TLinkedList.Create(TLocalUnresolvedReference); + FFixups:= tlocalfixups.create; + end; +// With tfixups(FFixups).newreference(instance,propinfo) do begin + With TLocalUnresolvedReference(tlocalfixups(FFixups).add) do begin + FInstance:= Instance; + FRoot:= Root; + FPropInfo:= PropInfo; + FRelative:= ReadIdent; + end; + end; + end; + tkInt64{$ifdef FPC}, tkQWord{$endif}: + SetInt64Prop(Instance, PropInfo, ReadInt64); + else + raise EReadError.CreateFmt(SUnknownPropertyType, [Ord(PropType^.Kind)]); + end; +end; + +function TReader.ReadRootComponent(ARoot: TComponent): TComponent; +var + Dummy, i: Integer; + Flags: TFilerFlags; + CompClassName, CompName, ResultName: String; + localloaded: boolean; +begin + FDriver.BeginRootComponent; + Result := nil; + {!!!: GlobalNameSpace.BeginWrite; // Loading from stream adds to name space + try} + try + FDriver.BeginComponent(Flags, Dummy, CompClassName, CompName); + if not Assigned(ARoot) then + begin + { Read the class name and the object name and create a new object: } + Result := TComponentClass(FindClass(CompClassName)).Create(nil); + Result.Name := CompName; + end else + begin + Result := ARoot; + + if not (csDesigning in Result.ComponentState) then + begin + Result.FComponentState := + Result.FComponentState + [csLoading, csReading]; + + { We need an unique name } + i := 0; + { Don't use Result.Name directly, as this would influence + FindGlobalComponent in successive loop runs } + ResultName := CompName; + while Assigned(FindGlobalComponent(ResultName)) do + begin + Inc(i); + ResultName := CompName + '_' + IntToStr(i); + end; + Result.Name := ResultName; + end; + end; + + FRoot := Result; + FLookupRoot := Result; + localloaded:= not (Assigned(GlobalLoaded) and + (globalloaded.fsuspended <= 0)); + if localloaded then begin + FLoaded:= TFpList.Create; + end + else begin + FLoaded:= GlobalLoaded; + end; + try + if FLoaded.IndexOf(FRoot) < 0 then begin + FLoaded.Add(FRoot); + end; + FOwner := FRoot; + FRoot.FComponentState := FRoot.FComponentState + [csLoading, csReading]; + FRoot.ReadState(Self); + Exclude(FRoot.FComponentState, csReading); + + GlobalFixupReferences(); + + if localloaded then begin + for i := 0 to FLoaded.Count - 1 do begin + TComponent(FLoaded[i]).Loaded; + end; + end; + + finally + if localloaded then begin + FLoaded.Free; + end; + FLoaded := nil; + end; +// GlobalFixupReferences; + except + RemoveFixupReferences(ARoot, ''); + if not Assigned(ARoot) then + Result.Free; + raise; + end; + {finally + GlobalNameSpace.EndWrite; + end;} +end; + +procedure TReader.ReadComponents(AOwner, AParent: TComponent; + Proc: TReadComponentsProc); +var + Component: TComponent; +begin + Root := AOwner; + Owner := AOwner; + Parent := AParent; + BeginReferences; + try + while not EndOfList do + begin + FDriver.BeginRootComponent; + Component := ReadComponent(nil); + if Assigned(Proc) then + Proc(Component); + end; + ReadListEnd; + FixupReferences; + finally + EndReferences; + end; +end; + +function TReader.ReadString: String; +var + StringType: TValueType; +begin + StringType := FDriver.ReadValue; + if StringType in [vaString, vaLString,vaUTF8String] then + begin + Result := FDriver.ReadString(StringType); + if (StringType=vaUTF8String) then + Result:= ansistring(utf8Decode(Result)); + end + else if StringType in [vaWString] then + Result:= ansistring(FDriver.ReadWidestring) + else if StringType in [vaUString] then + Result:= ansistring(FDriver.ReadUnicodeString) + else + raise EReadError.Create(SInvalidPropertyValue); +end; + +function TReader.Readutf8String: utf8String; +var + StringType: TValueType; +begin + StringType := FDriver.ReadValue; + if StringType in [vaUTF8String] then + Result := FDriver.Readutf8String(StringType) + else if StringType in [vaString, vaLString] then + begin + Result := FDriver.ReadString(StringType); + end + else if StringType in [vaWString] then + Result:= ansistring(FDriver.ReadWidestring) + else if StringType in [vaUString] then + Result:= ansistring(FDriver.ReadUnicodeString) + else + raise EReadError.Create(SInvalidPropertyValue); +end; + +function TReader.ReadWideString: WideString; +var + s: String; + i: Integer; + vt:TValueType; +begin + if NextValue in [vaWString,vaUString,vaUTF8String] then + //vaUTF8String needs conversion? 2008-09-06 mse, YES!! AntonK + begin + vt:=ReadValue; + if vt=vaUTF8String then + Result := utf8decode(fDriver.ReadString(vaLString)) + else + Result := FDriver.ReadWideString + end + else + begin + //data probable from ObjectTextToBinary + s := ReadString; + setlength(result,length(s)); + for i:= 1 to length(s) do begin + result[i]:= widechar(ord(s[i])); //no code conversion + end; + end; +end; + + +function TReader.ReadUnicodeString: UnicodeString; +var + s: String; + i: Integer; + vt:TValueType; +begin + if NextValue in [vaWString,vaUString,vaUTF8String] then + //vaUTF8String needs conversion? 2008-09-06 mse, YES!! AntonK + begin + vt:=ReadValue; + if vt=vaUTF8String then + Result := utf8decode(fDriver.ReadString(vaLString)) + else + Result := FDriver.ReadWideString + end + else + begin + //data probable from ObjectTextToBinary + s := ReadString; + setlength(result,length(s)); + for i:= 1 to length(s) do begin + result[i]:= UnicodeChar(ord(s[i])); //no code conversion + end; + end; +end; + + +function TReader.ReadValue: TValueType; +begin + Result := FDriver.ReadValue; +end; + +procedure TReader.CopyValue(Writer: TWriter); + + procedure CopyBytes(Count: Integer); +{ var + Buffer: array[0..1023] of Byte; } + begin +{!!!: while Count > 1024 do + begin + FDriver.Read(Buffer, 1024); + Writer.Driver.Write(Buffer, 1024); + Dec(Count, 1024); + end; + if Count > 0 then + begin + FDriver.Read(Buffer, Count); + Writer.Driver.Write(Buffer, Count); + end;} + end; + +{var + s: String; + Count: LongInt; } +begin + case FDriver.NextValue of + vaNull: + Writer.WriteIdent('NULL'); + vaFalse: + Writer.WriteIdent('FALSE'); + vaTrue: + Writer.WriteIdent('TRUE'); + vaNil: + Writer.WriteIdent('NIL'); + {!!!: vaList, vaCollection: + begin + Writer.WriteValue(FDriver.ReadValue); + while not EndOfList do + CopyValue(Writer); + ReadListEnd; + Writer.WriteListEnd; + end;} + vaInt8, vaInt16, vaInt32: + Writer.WriteInteger(ReadInteger); +{$ifndef FPUNONE} + vaExtended: + Writer.WriteFloat(ReadFloat); +{$endif} + {!!!: vaString: + Writer.WriteStr(ReadStr);} + vaIdent: + Writer.WriteIdent(ReadIdent); + {!!!: vaBinary, vaLString, vaWString: + begin + Writer.WriteValue(FDriver.ReadValue); + FDriver.Read(Count, SizeOf(Count)); + Writer.Driver.Write(Count, SizeOf(Count)); + CopyBytes(Count); + end;} + {!!!: vaSet: + Writer.WriteSet(ReadSet);} +{$ifndef FPUNONE} + vaSingle: + Writer.WriteSingle(ReadSingle); +{$endif} + {!!!: vaCurrency: + Writer.WriteCurrency(ReadCurrency);} +{$ifndef FPUNONE} + vaDate: + Writer.WriteDate(ReadDate); +{$endif} + vaInt64: + Writer.WriteInteger(ReadInt64); + end; +end; + +function TReader.FindComponentClass(const AClassName: String; + const aflags: tfilerflags): TComponentClass; + +var + PersistentClass: TPersistentClass; + UClassName: shortstring; + + procedure FindInFieldTable(RootComponent: TComponent); + var + FieldClassTable: PFieldClassTable; + Entry: TPersistentClass; + i: Integer; + ComponentClassType: TClass; + begin + ComponentClassType:= RootComponent.ClassType; + // it is not necessary to look in the FieldTable of TComponent, + // because TComponent doesn't have published properties that are + // descendants of TComponent + while ComponentClassType <> TComponent do begin + fieldclasstable:= getfieldclasstable(componentclasstype); + if assigned(FieldClassTable) then begin + for i:= 0 to FieldClassTable^.Count -1 do begin + {$ifdef FPC} + {$ifdef mse_fpc_3_2} + Entry:= FieldClassTable^.Entries[i]^; + {$else} + Entry:= FieldClassTable^.Entries[i]; + {$endif} + {$else} + Entry:= FieldClassTable^.Entries[i]^; + {$endif} + //writeln(format('Looking for %s in field table of class %s. Found %s', + //[AClassName, ComponentClassType.ClassName, Entry.ClassName])); + if (UpperCase(Entry.ClassName) = UClassName) and + Entry.InheritsFrom(TComponent) then begin + Result:= TComponentClass(Entry); + Exit; + end; + end; + end; + // look in parent class + ComponentClassType:= ComponentClassType.ClassParent; + end; + end; + +begin + Result := nil; + if not (csdesigning in root.fcomponentstate) or + not (ffinline in aflags) then begin + UClassName:=UpperCase(AClassName); + FindInFieldTable(Root); + + if (Result=nil) and assigned(LookupRoot) and (LookupRoot<>Root) then + FindInFieldTable(LookupRoot); + + if (Result=nil) then begin + PersistentClass := GetClass(AClassName); + if {$ifndef FPC}(persistentclass <> nil) and{$endif} + PersistentClass.InheritsFrom(TComponent) then + Result := TComponentClass(PersistentClass); + end; + end; + if (Result=nil) and assigned(OnFindComponentClass) then + OnFindComponentClass(Self, AClassName, Result); + + if (Result=nil) or (not Result.InheritsFrom(TComponent)) then + raise EClassNotFound.CreateFmt(SClassNotFound, [AClassName]); +end; + +function treader.readenum(const enumtype: ptypeinfo): longword; +var + str1: string; +begin + str1:= ReadIdent; + result:= GetEnumValue(enumtype, str1); + if integer(result) = -1 then begin + if assigned(fonenumerror) then begin + fonenumerror(self,enumtype,str1,result); + end; + end; + if integer(result) = -1 then begin + raise EReadError.Create(SInvalidPropertyValue); + end; +end; + +{****************************************************************************} +{* TWriter *} +{****************************************************************************} + + +constructor TWriter.Create(ADriver: TAbstractObjectWriter); +begin + inherited Create; + FDriver := ADriver; +end; + +constructor TWriter.Create(Stream: TStream; BufSize: Integer); +begin + inherited Create; + If (Stream=Nil) then + Raise EWriteError.Create(SEmptyStreamIllegalWriter); + FDriver := CreateDriver(Stream, BufSize); + fdriver.fwriter:= self; + FDestroyDriver := True; +end; + +destructor TWriter.Destroy; +begin + if FDestroyDriver then + FDriver.Free; + inherited Destroy; +end; + +function TWriter.CreateDriver(Stream: TStream; BufSize: Integer): TAbstractObjectWriter; +begin + Result := TBinaryObjectWriter.Create(Stream, BufSize); +end; + +Type + TPosComponent = Class(TObject) + FPos : Integer; + FComponent : TComponent; + Constructor Create(APos : Integer; AComponent : TComponent); + end; + +Constructor TPosComponent.Create(APos : Integer; AComponent : TComponent); + +begin + FPos:=APos; + FComponent:=AComponent; +end; + +// Used as argument for calls to TComponent.GetChildren: +procedure TWriter.AddToAncestorList(Component: TComponent); +begin + FAncestors.AddObject(Component.Name,TPosComponent.Create(FAncestors.Count,Component)); +end; + +procedure TWriter.DefineProperty(const Name: String; + ReadData: TReaderProc; AWriteData: TWriterProc; HasData: Boolean); +begin + if HasData and Assigned(AWriteData) then + begin + // Write the property name and then the data itself + Driver.BeginProperty(FPropPath + Name); + AWriteData(Self); + Driver.EndProperty; + end; +end; + +procedure TWriter.DefineBinaryProperty(const Name: String; + ReadData, AWriteData: TStreamProc; HasData: Boolean); +begin + if HasData and Assigned(AWriteData) then + begin + // Write the property name and then the data itself + Driver.BeginProperty(FPropPath + Name); + WriteBinary(AWriteData); + Driver.EndProperty; + end; +end; + +procedure TWriter.Write(const Buffer; Count: Longint); +begin + //This should give an exception if write is not implemented (i.e. TTextObjectWriter) + //but should work with TBinaryObjectWriter. + Driver.Write(Buffer, Count); +end; + +procedure TWriter.SetRoot(ARoot: TComponent); +begin + inherited SetRoot(ARoot); + // Use the new root as lookup root too + FLookupRoot := ARoot; +end; + +procedure TWriter.WriteBinary(AWriteData: TStreamProc); +var + MemBuffer: TMemoryStream; + BufferSize: Longint; +begin + { First write the binary data into a memory stream, then copy this buffered + stream into the writing destination. This is necessary as we have to know + the size of the binary data in advance (we're assuming that seeking within + the writer stream is not possible) } + MemBuffer := TMemoryStream.Create; + try + AWriteData(MemBuffer); + BufferSize := MemBuffer.Size; + Driver.WriteBinary(MemBuffer.Memory^, BufferSize); + finally + MemBuffer.Free; + end; +end; + +procedure TWriter.WriteBoolean(Value: Boolean); +begin + Driver.WriteBoolean(Value); +end; + +procedure TWriter.WriteChar(Value: Char); +begin + WriteString(Value); +end; + +procedure TWriter.WriteWideChar(Value: WideChar); +begin + WriteWideString(Value); +end; + +procedure TWriter.WriteCollection(Value: TCollection); +var + i: Integer; +begin + Driver.BeginCollection; + if Assigned(Value) then + for i := 0 to Value.Count - 1 do + begin + { Each collection item needs its own ListBegin/ListEnd tag, or else the + reader wouldn't be able to know where an item ends and where the next + one starts } + WriteListBegin; + WriteProperties(Value.Items[i]); + WriteListEnd; + end; + WriteListEnd; +end; + +procedure TWriter.DetermineAncestor(Component : TComponent); + +Var + I : Integer; + +begin + // Should be set only when we write an inherited with children. + if Not Assigned(FAncestors) then + exit; + I:=FAncestors.IndexOf(Component.Name); + If (I=-1) then + begin + FAncestor:=Nil; + FAncestorPos:=-1; + end + else + With TPosComponent(FAncestors.Objects[i]) do + begin + FAncestor:=FComponent; + FAncestorPos:=FPos; + end; +end; + +procedure TWriter.DoFindAncestor(Component : TComponent); + +Var + C : TComponent; + +begin + if Assigned(FOnFindAncestor) then + if (Ancestor=Nil) or (Ancestor is TComponent) then + begin + C:=TComponent(Ancestor); + FOnFindAncestor(Self,Component,Component.Name,C,FRootAncestor); + Ancestor:=C; + end; +end; + +procedure TWriter.WriteComponent(Component: TComponent); + +var + SA : TPersistent; + SR, SRA : TComponent; +begin + SR:=FRoot; + SA:=FAncestor; + SRA:=FRootAncestor; + Try + Component.FComponentState:=Component.FComponentState+[csWriting]; + Try + // Possibly set ancestor. + DetermineAncestor(Component); + DoFindAncestor(Component); // Mainly for IDE when a parent form had an ancestor renamed... + // Will call WriteComponentData. + Component.WriteState(Self); + FDriver.EndList; + Finally + Component.FComponentState:=Component.FComponentState-[csWriting]; + end; + Finally + FAncestor:=SA; + FRoot:=SR; + FRootAncestor:=SRA; + end; +end; + +procedure TWriter.WriteChildren(Component : TComponent); + +Var + SRoot, SRootA : TComponent; + SList : TStringList; + SPos : Integer; + I : Integer; + +begin + // Write children list. + // While writing children, the ancestor environment must be saved + // This is recursive... + SRoot:=FRoot; + SRootA:=FRootAncestor; + SList:=FAncestors; + SPos:=FCurrentPos; + try + FAncestors:=Nil; + FCurrentPos:=0; + FAncestorPos:=-1; + if csInline in Component.ComponentState then + FRoot:=Component; + if (FAncestor is TComponent) then + begin + FAncestors:=TStringList.Create; + if csInline in TComponent(FAncestor).ComponentState then + FRootAncestor := TComponent(FAncestor); + TComponent(FAncestor).GetChildren( + {$ifdef FPC}@{$endif}AddToAncestorList,FRootAncestor); + FAncestors.Sorted:=True; + end; + try + Component.GetChildren({$ifdef FPC}@{$endif}WriteComponent, FRoot); + Finally + If Assigned(Fancestors) then + For I:=0 to FAncestors.Count-1 do + FAncestors.Objects[i].Free; + FreeAndNil(FAncestors); + end; + finally + FAncestors:=Slist; + FRoot:=SRoot; + FRootAncestor:=SRootA; + FCurrentPos:=SPos; + FAncestorPos:=Spos; + end; +end; + +procedure TWriter.WriteComponentData(Instance: TComponent); +var + Flags: TFilerFlags; +begin + Flags := []; + If (Assigned(FAncestor)) and //has ancestor + (not (csInline in Instance.ComponentState) or // no inline component + // .. or the inline component is inherited + (csAncestor in Instance.Componentstate) and (FAncestors <> nil)) then + Flags:=[ffInherited] + else If csInline in Instance.ComponentState then + Flags:=[ffInline]; + If (FAncestors<>Nil) and ((FCurrentPos<>FAncestorPos) or (FAncestor=Nil)) then + Include(Flags,ffChildPos); + FDriver.BeginComponent(Instance,Flags,FCurrentPos); + If (FAncestors<>Nil) then + Inc(FCurrentPos); + WriteProperties(Instance); + WriteListEnd; + // Needs special handling of ancestor. + If not IgnoreChildren then + WriteChildren(Instance); +end; + +procedure TWriter.WriteDescendent(ARoot: TComponent; AAncestor: TComponent); +begin + FRoot := ARoot; + FAncestor := AAncestor; + FRootAncestor := AAncestor; + FLookupRoot := ARoot; + + WriteComponent(ARoot); +end; + +{$ifndef FPUNONE} +procedure TWriter.WriteFloat(const Value: Extended); +begin + Driver.WriteFloat(Value); +end; + +procedure TWriter.WriteSingle(const Value: Single); +begin + Driver.WriteSingle(Value); +end; +{$endif} + +procedure TWriter.WriteCurrency(const Value: Currency); +begin + Driver.WriteCurrency(Value); +end; + +{$ifndef FPUNONE} +procedure TWriter.WriteDate(const Value: TDateTime); +begin + Driver.WriteDate(Value); +end; +{$endif} + +procedure TWriter.WriteIdent(const Ident: string); +begin + Driver.WriteIdent(Ident); +end; + +procedure TWriter.WriteInteger(Value: LongInt); +begin + Driver.WriteInteger(Value); +end; + +procedure TWriter.WriteInteger(Value: Int64); +begin + Driver.WriteInteger(Value); +end; + +procedure twriter.writeset(value: longword; settype: ptypeinfo); + +begin + driver.writeset(value, + gettypedata(settype)^.comptype{$ifndef FPC}^{$endif}); +end; + +procedure twriter.writeenum(value: longint; enumtype: ptypeinfo); + +begin + driver.writeident(getenumname(enumtype,value)); +end; + +procedure TWriter.WriteVariant(const VarValue: Variant); +begin + Driver.WriteVariant(VarValue); +end; + +procedure TWriter.WriteListBegin; +begin + Driver.BeginList; +end; + +procedure TWriter.WriteListEnd; +begin + Driver.EndList; +end; + +procedure TWriter.WriteProperties(Instance: TPersistent); +var PropCount,i : integer; + PropList : PPropList; +begin + PropCount:=GetPropList(Instance,PropList); + if PropCount>0 then + try + for i := 0 to PropCount-1 do + if IsStoredProp(Instance,PropList^[i]) then + WriteProperty(Instance,PropList^[i]); + Finally + Freemem(PropList); + end; + Instance.DefineProperties(Self); +end; + + +procedure TWriter.WriteProperty(Instance: TPersistent; PropInfo: Pointer); +var + HasAncestor: Boolean; + PropType: PTypeInfo; + Value, DefValue: LongInt; + Ident: String; + IntToIdentFn: TIntToIdent; +{$ifndef FPUNONE} + FloatValue, DefFloatValue: Extended; +{$endif} + MethodValue: TMethod; + DefMethodValue: TMethod; + WStrValue, WDefStrValue: WideString; + StrValue, DefStrValue: String; + UStrValue, UDefStrValue: UnicodeString; + AncestorObj: TObject; + C,Component: TComponent; + ObjValue: TObject; + SavedAncestor: TPersistent; + SavedPropPath, Name: String; + Int64Value, DefInt64Value: Int64; + VarValue, DefVarValue : tvardata; + BoolValue, DefBoolValue: boolean; + Handled: Boolean; + +begin + // do not stream properties without getter + if not Assigned(PPropInfo(PropInfo)^.GetProc) then + exit; + // properties without setter are only allowed, if they are subcomponents + PropType := PPropInfo(PropInfo)^.PropType{$ifndef FPC}^{$endif}; + if not Assigned(PPropInfo(PropInfo)^.SetProc) then begin + if PropType^.Kind<>tkClass then + exit; + ObjValue := TObject(GetObjectProp(Instance, PropInfo)); + if not ObjValue.InheritsFrom(TComponent) or + not (csSubComponent in TComponent(ObjValue).ComponentStyle) then + exit; + end; + + { Check if the ancestor can be used } + HasAncestor := Assigned(Ancestor) and ((Instance = Root) or + (Instance.ClassType = Ancestor.ClassType)); + //writeln('TWriter.WriteProperty Name=',PropType^.Name,' Kind=',GetEnumName(TypeInfo(TTypeKind),ord(PropType^.Kind)),' HasAncestor=',HasAncestor); + + case PropType^.Kind of + tkInteger, tkChar, tkEnumeration, tkSet, tkWChar: + begin + Value := GetOrdProp(Instance, PropInfo); + if HasAncestor then + DefValue := GetOrdProp(Ancestor, PropInfo) + else + DefValue := PPropInfo(PropInfo)^.Default; + // writeln(PPropInfo(PropInfo)^.Name, ', HasAncestor=', ord(HasAncestor), ', Value=', Value, ', Default=', DefValue); + if (Value <> DefValue) or (DefValue=longint($80000000)) then + begin + Driver.BeginProperty(FPropPath + PPropInfo(PropInfo)^.Name); + case PropType^.Kind of + tkInteger: + begin + // Check if this integer has a string identifier + IntToIdentFn := FindIntToIdent(PPropInfo(PropInfo)^.PropType); + if Assigned(IntToIdentFn) and IntToIdentFn(Value, Ident) then + // Integer can be written a human-readable identifier + WriteIdent(Ident) + else + // Integer has to be written just as number + WriteInteger(Value); + end; + tkChar: + WriteChar(Chr(Value)); + tkWChar: + WriteWideChar(WideChar(Value)); + tkSet: + Driver.WriteSet(Value, GetTypeData(PropType)^.CompType); + tkEnumeration: + WriteIdent(GetEnumName(PropType, Value)); + end; + Driver.EndProperty; + end; + end; +{$ifndef FPUNONE} + tkFloat: + begin + FloatValue := GetFloatProp(Instance, PropInfo); + if HasAncestor then + DefFloatValue := GetFloatProp(Ancestor, PropInfo) + else + begin + DefValue :=PPropInfo(PropInfo)^.Default; + DefFloatValue:=PSingle(@PPropInfo(PropInfo)^.Default)^; + end; + if (FloatValue<>DefFloatValue) or (DefValue=longint($80000000)) then + begin + Driver.BeginProperty(FPropPath + PPropInfo(PropInfo)^.Name); + WriteFloat(FloatValue); + Driver.EndProperty; + end; + end; +{$endif} + tkMethod: + begin + MethodValue := GetMethodProp(Instance, PropInfo); + if HasAncestor then + DefMethodValue := GetMethodProp(Ancestor, PropInfo) + else begin + DefMethodValue.Data := nil; + DefMethodValue.Code := nil; + end; + + Handled:=false; + if Assigned(OnWriteMethodProperty) then + OnWriteMethodProperty(Self,Instance,PPropInfo(PropInfo),MethodValue, + DefMethodValue,Handled); + if (not Handled) and + (MethodValue.Code <> DefMethodValue.Code) and + ((not Assigned(MethodValue.Code)) or + ((Length(FLookupRoot.MethodName(MethodValue.Code)) > 0))) then + begin + Driver.BeginProperty(FPropPath + PPropInfo(PropInfo)^.Name); + if Assigned(MethodValue.Code) then + Driver.WriteMethodName(FLookupRoot.MethodName(MethodValue.Code)) + else + Driver.WriteMethodName(''); + Driver.EndProperty; + end; + end; +{$ifdef FPC} + tkSString, tkLString, tkAString: +{$else} + tkString, tkLString: +{$endif} + begin + StrValue := GetStrProp(Instance, PropInfo); + if HasAncestor then + DefStrValue := GetStrProp(Ancestor, PropInfo) + else + SetLength(DefStrValue, 0); + + if StrValue <> DefStrValue then + begin + Driver.BeginProperty(FPropPath + PPropInfo(PropInfo)^.Name); + if Assigned(FOnWriteStringProperty) then + FOnWriteStringProperty(Self,Instance,PropInfo,StrValue); + if proptype = typeinfo(utf8string) then begin + writeutf8string(strvalue); + end + else begin + WriteString(StrValue); + end; + Driver.EndProperty; + end; + end; + tkWString: + begin + WStrValue := GetWideStrProp(Instance, PropInfo); + if HasAncestor then + WDefStrValue := GetWideStrProp(Ancestor, PropInfo) + else + SetLength(WDefStrValue, 0); + + if WStrValue <> WDefStrValue then + begin + Driver.BeginProperty(FPropPath + PPropInfo(PropInfo)^.Name); + WriteWideString(WStrValue); + Driver.EndProperty; + end; + end; +{$ifdef FPC} + tkUString: + begin + UStrValue := GetUnicodeStrProp(Instance, PropInfo); + if HasAncestor then + UDefStrValue := GetUnicodeStrProp(Ancestor, PropInfo) + else + SetLength(UDefStrValue, 0); + + if UStrValue <> UDefStrValue then + begin + Driver.BeginProperty(FPropPath + PPropInfo(PropInfo)^.Name); + WriteUnicodeString(UStrValue); + Driver.EndProperty; + end; + end; +{$endif} + tkVariant: + begin + { Ensure that a Variant manager is installed } + {$ifdef FPC} + if not assigned(VarClearProc) then + raise EWriteError.Create(SErrNoVariantSupport); + {$endif} + VarValue := tvardata(GetVariantProp(Instance, PropInfo)); + if HasAncestor then + DefVarValue := tvardata(GetVariantProp(Ancestor, PropInfo)) + else + FillChar(DefVarValue,sizeof(DefVarValue),0); +{$ifdef FPC} + if (CompareByte(VarValue,DefVarValue,sizeof(VarValue)) <> 0) then +{$else} + if Comparemem(@VarValue,@DefVarValue,sizeof(VarValue)) then +{$endif} + begin + Driver.BeginProperty(FPropPath + PPropInfo(PropInfo)^.Name); + { can't use variant() typecast, pulls in variants unit } + WriteVariant(pvariant(@VarValue)^); + Driver.EndProperty; + end; + end; + tkClass: + begin + ObjValue := TObject(GetObjectProp(Instance, PropInfo)); + if HasAncestor then + begin + AncestorObj := TObject(GetObjectProp(Ancestor, PropInfo)); + if (AncestorObj is TComponent) and + (ObjValue is TComponent) then + begin + //writeln('TWriter.WriteProperty AncestorObj=',TComponent(AncestorObj).Name,' OwnerFit=',TComponent(AncestorObj).Owner = FRootAncestor,' ',TComponent(ObjValue).Name,' OwnerFit=',TComponent(ObjValue).Owner = Root); + if (AncestorObj<> ObjValue) and + (TComponent(AncestorObj).Owner = FRootAncestor) and + (TComponent(ObjValue).Owner = Root) and + (UpperCase(TComponent(AncestorObj).Name) = UpperCase(TComponent(ObjValue).Name)) then + begin + // different components, but with the same name + // treat it like an override + AncestorObj := ObjValue; + end; + end; + end else + AncestorObj := nil; + + if not Assigned(ObjValue) then + begin + if ObjValue <> AncestorObj then + begin + Driver.BeginProperty(FPropPath + PPropInfo(PropInfo)^.Name); + Driver.WriteIdent('NIL'); + Driver.EndProperty; + end + end + else if ObjValue.InheritsFrom(TPersistent) then + begin + { Subcomponents are streamed the same way as persistents } + if ObjValue.InheritsFrom(TComponent) + and ((not (csSubComponent in TComponent(ObjValue).ComponentStyle)) + or ((TComponent(ObjValue).Owner<>Instance) and + (TComponent(ObjValue).Owner<>Nil))) then + begin + Component := TComponent(ObjValue); + if (ObjValue <> AncestorObj) + and not (csTransient in Component.ComponentStyle) then + begin + Name:= ''; + C:= Component; + While (C<>Nil) and (C.Name<>'') do + begin + If (Name<>'') Then + Name:='.'+Name; + if C.Owner = LookupRoot then + begin + Name := C.Name+Name; + break; + end + else if C = LookupRoot then + begin + Name := 'Owner' + Name; + break; + end; + Name:=C.Name + Name; + C:= C.Owner; + end; + if (C=nil) and (Component.Owner=nil) then + if (Name<>'') then //foreign root + Name:=Name+'.Owner'; + if Length(Name) > 0 then + begin + Driver.BeginProperty(FPropPath + PPropInfo(PropInfo)^.Name); + WriteIdent(Name); + Driver.EndProperty; + end; // length Name>0 + end; //(ObjValue <> AncestorObj) + end // ObjValue.InheritsFrom(TComponent) + else if ObjValue.InheritsFrom(TCollection) then + begin + if (not HasAncestor) or (not CollectionsEqual(TCollection(ObjValue), + TCollection(GetObjectProp(Ancestor, PropInfo)),root,rootancestor)) then + begin + Driver.BeginProperty(FPropPath + PPropInfo(PropInfo)^.Name); + SavedPropPath := FPropPath; + try + SetLength(FPropPath, 0); + WriteCollection(TCollection(ObjValue)); + finally + FPropPath := SavedPropPath; + Driver.EndProperty; + end; + end; + end // Tcollection + else + begin + SavedAncestor := Ancestor; + SavedPropPath := FPropPath; + try + FPropPath := FPropPath + PPropInfo(PropInfo)^.Name + '.'; + if HasAncestor then + Ancestor := TPersistent(GetObjectProp(Ancestor, PropInfo)); + WriteProperties(TPersistent(ObjValue)); + finally + Ancestor := SavedAncestor; + FPropPath := SavedPropPath; + end; + end; + end; // Inheritsfrom(TPersistent) + end; + tkInt64 {$ifdef FPC}, tkQWord{$endif}: + begin + Int64Value := GetInt64Prop(Instance, PropInfo); + if HasAncestor then + DefInt64Value := GetInt64Prop(Ancestor, PropInfo) + else + DefInt64Value := 0; + if Int64Value <> DefInt64Value then + begin + Driver.BeginProperty(FPropPath + PPropInfo(PropInfo)^.Name); + WriteInteger(Int64Value); + Driver.EndProperty; + end; + end; +{$ifdef FPC} + tkBool: + begin + BoolValue := GetOrdProp(Instance, PropInfo)<>0; + if HasAncestor then + DefBoolValue := GetOrdProp(Ancestor, PropInfo)<>0 + else + begin + DefBoolValue := PPropInfo(PropInfo)^.Default<>0; + DefValue:=PPropInfo(PropInfo)^.Default; + end; + // writeln(PPropInfo(PropInfo)^.Name, ', HasAncestor=', ord(HasAncestor), ', Value=', Value, ', Default=', DefBoolValue); + if (BoolValue<>DefBoolValue) or (DefValue=longint($80000000)) then + begin + Driver.BeginProperty(FPropPath + PPropInfo(PropInfo)^.Name); + WriteBoolean(BoolValue); + Driver.EndProperty; + end; + end; +{$endif} + end; +end; + +procedure TWriter.WriteRootComponent(ARoot: TComponent); +begin + WriteDescendent(ARoot, nil); +end; + +procedure TWriter.WriteString(const Value: String); +begin + Driver.WriteString(Value); +end; + +procedure twriter.Writeutf8String(const Value: utf8string); +begin + Driver.Writeutf8String(Value); +end; + +procedure TWriter.WriteWideString(const Value: WideString); +begin + Driver.WriteWideString(Value); +end; + +procedure TWriter.WriteUnicodeString(const Value: UnicodeString); +begin + Driver.WriteUnicodeString(Value); +end; + +function twriter.getclassname(const aobj: tobject): shortstring; +begin + result:= aobj.classname; +end; + +{****************************************************************************} +{* TBinaryObjectWriter *} +{****************************************************************************} + +{$ifndef FPUNONE} +{$IFNDEF FPC_HAS_TYPE_EXTENDED} +procedure DoubleToExtended(d : double; e : pointer); +var mant : qword; + exp : smallint; + sign : boolean; +begin + mant:= (qword(d) and $000FFFFFFFFFFFFF) shl 12; + exp := (qword(d) shr 52) and $7FF; + sign:= (qword(d) and $8000000000000000) <> 0; + case exp of + 0: begin + if mant <> 0 then begin //denormalized value: hidden bit is 0. normalize it + exp:=16383-1022; + while (mant and $8000000000000000) = 0 do begin + dec(exp); + mant:= mant shl 1; + end; + dec(exp); //don't shift, most significant bit is not hidden in extended + end; + end; + 2047: begin + exp:= $7FFF; //either infinity or NaN + mant:= qword(d) and $000FFFFFFFFFFFFF or $8000000000000000; + end; + else begin + inc(exp,16383-1023); + mant:= (mant shr 1) or $8000000000000000; //unhide hidden bit + end; + end; + if sign then exp:=exp or $8000; + mant:=NtoLE(mant); + exp:=NtoLE(word(exp)); + move(mant,pbyte(e)[0],8); //mantissa : bytes 0..7 + move(exp,pbyte(e)[8],2); //exponent and sign: bytes 8..9 +end; +{$ENDIF} +{$endif} + +procedure TBinaryObjectWriter.WriteWord(w : word); + {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} +begin + w:=NtoLE(w); + Write(w,2); +end; + +procedure TBinaryObjectWriter.WriteDWord(lw : longword); {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} +begin + lw:=NtoLE(lw); + Write(lw,4); +end; + +procedure TBinaryObjectWriter.WriteQWord(qw : qword); {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} +begin +{$ifdef FPC} + qw:=NtoLE(qw); +{$endif} + Write(qw,8); +end; + +{$ifndef FPUNONE} +procedure TBinaryObjectWriter.WriteExtended(e : extended); {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} +{$IFNDEF FPC_HAS_TYPE_EXTENDED} +var ext : array[0..9] of byte; +{$ENDIF} +begin +{$IFNDEF FPC_HAS_TYPE_EXTENDED} + {$IFDEF FPC_DOUBLE_HILO_SWAPPED} + { SwapDoubleHiLo defined in reader.inc } + SwapDoubleHiLo(e); + {$ENDIF FPC_DOUBLE_HILO_SWAPPED} + DoubleToExtended(e,@(ext[0])); + Write(ext[0],10); +{$ELSE} + Write(e,sizeof(e)); +{$ENDIF} +end; +{$endif} + +constructor TBinaryObjectWriter.Create(Stream: TStream; BufSize: Integer); +begin + inherited Create; + If (Stream=Nil) then + Raise EWriteError.Create(SEmptyStreamIllegalWriter); + FStream := Stream; + FBufSize := BufSize; + GetMem(FBuffer, BufSize); +end; + +destructor TBinaryObjectWriter.Destroy; +begin + // Flush all data which hasn't been written yet + FlushBuffer; + + if Assigned(FBuffer) then + FreeMem(FBuffer, FBufSize); + + inherited Destroy; +end; + +procedure TBinaryObjectWriter.BeginCollection; +begin + WriteValue(vaCollection); +end; + +procedure TBinaryObjectWriter.BeginComponent(Component: TComponent; + Flags: TFilerFlags; ChildPos: Integer); +var + Prefix: Byte; +begin + if not FSignatureWritten then + begin + Write(FilerSignature, SizeOf(FilerSignature)); + FSignatureWritten := True; + end; + + { Only write the flags if they are needed! } + if Flags <> [] then + begin + Prefix := {$ifdef FPC}longword{$else}byte{$endif}(Flags) or $f0; + Write(Prefix, 1); + if ffChildPos in Flags then + WriteInteger(ChildPos); + end; + if fwriter <> nil then begin + WriteStr(fwriter.getclassname(Component)); + end + else begin + WriteStr(Component.ClassName); + end; + WriteStr(Component.Name); +end; + +procedure TBinaryObjectWriter.BeginList; +begin + WriteValue(vaList); +end; + +procedure TBinaryObjectWriter.EndList; +begin + WriteValue(vaNull); +end; + +procedure TBinaryObjectWriter.BeginProperty(const PropName: String); +begin + WriteStr(PropName); +end; + +procedure TBinaryObjectWriter.EndProperty; +begin +end; + +procedure TBinaryObjectWriter.WriteBinary(const Buffer; Count: LongInt); +begin + WriteValue(vaBinary); + WriteDWord(longword(Count)); + Write(Buffer, Count); +end; + +procedure TBinaryObjectWriter.WriteBoolean(Value: Boolean); +begin + if Value then + WriteValue(vaTrue) + else + WriteValue(vaFalse); +end; + +{$ifndef FPUNONE} +procedure TBinaryObjectWriter.WriteFloat(const Value: Extended); +begin + WriteValue(vaExtended); + WriteExtended(Value); +end; + +procedure TBinaryObjectWriter.WriteSingle(const Value: Single); +begin + WriteValue(vaSingle); +{$ifdef FPC} + WriteDWord(longword(Value)); +{$else} + WriteDWord(longword(ar4ty(Value))); +{$endif} +end; +{$endif} + +procedure TBinaryObjectWriter.WriteCurrency(const Value: Currency); +begin + WriteValue(vaCurrency); +{$ifdef FPC} + WriteQWord(qword(Value)); +{$else} + WriteQWord(qword(ar8ty(Value))); +{$endif} +end; + + +{$ifndef FPUNONE} +procedure TBinaryObjectWriter.WriteDate(const Value: TDateTime); +begin + WriteValue(vaDate); +{$ifdef FPC} + WriteQWord(qword(Value)); +{$else} + WriteQWord(qword(ar8ty(Value))); +{$endif} +end; +{$endif} + +procedure TBinaryObjectWriter.WriteIdent(const Ident: string); +begin + { Check if Ident is a special identifier before trying to just write + Ident directly } + if UpperCase(Ident) = 'NIL' then + WriteValue(vaNil) + else if UpperCase(Ident) = 'FALSE' then + WriteValue(vaFalse) + else if UpperCase(Ident) = 'TRUE' then + WriteValue(vaTrue) + else if UpperCase(Ident) = 'NULL' then + WriteValue(vaNull) else + begin + WriteValue(vaIdent); + WriteStr(Ident); + end; +end; + +procedure TBinaryObjectWriter.WriteInteger(Value: Int64); +var + s: ShortInt; + i: SmallInt; + l: Longint; +begin + { Use the smallest possible integer type for the given value: } + if (Value >= -128) and (Value <= 127) then + begin + WriteValue(vaInt8); + s := Value; + Write(s, 1); + end else if (Value >= -32768) and (Value <= 32767) then + begin + WriteValue(vaInt16); + i := Value; + WriteWord(word(i)); +{$ifdef FPC} + end else if (Value >= -$80000000) and (Value <= $7fffffff) then +{$else} + end else if (Value >= $80000000) and (Value <= $7fffffff) then +{$endif} + begin + WriteValue(vaInt32); + l := Value; + WriteDWord(longword(l)); + end else + begin + WriteValue(vaInt64); + WriteQWord(qword(Value)); + end; +end; + +procedure TBinaryObjectWriter.WriteUInt64(Value: QWord); +var + s: ShortInt; + i: SmallInt; + l: Longint; +begin + { Use the smallest possible integer type for the given value: } + if (Value <= 127) then + begin + WriteValue(vaInt8); + s := Value; + Write(s, 1); + end else if (Value <= 32767) then + begin + WriteValue(vaInt16); + i := Value; + WriteWord(word(i)); + end else if (Value <= $7fffffff) then + begin + WriteValue(vaInt32); + l := Value; + WriteDWord(longword(l)); + end else + begin +{$ifdef FPC} + WriteValue(vaQWord); +{$else} + WriteValue(vaint64); +{$endif} + WriteQWord(Value); + end; +end; + + +procedure TBinaryObjectWriter.WriteMethodName(const Name: String); +begin + if Length(Name) > 0 then + begin + WriteValue(vaIdent); + WriteStr(Name); + end else + WriteValue(vaNil); +end; + +procedure TBinaryObjectWriter.WriteSet(Value: LongInt; SetType: Pointer); +type + tset = set of 0..31; +var + i: Integer; +begin + WriteValue(vaSet); + for i := 0 to 31 do + begin + if (i in tset(Value)) then + WriteStr(GetEnumName(PTypeInfo(SetType), i)); + end; + WriteStr(''); +end; + +procedure TBinaryObjectWriter.WriteString(const Value: String); +var + i: Integer; + b: byte; +begin + i := Length(Value); + if i <= 255 then + begin + WriteValue(vaString); + b := i; + Write(b, 1); + end else + begin + WriteValue(vaLString); + WriteDWord(longword(i)); + end; + if i > 0 then + Write(Value[1], i); +end; + +procedure TBinaryObjectWriter.Writeutf8String(const Value: utf8String); +var + i: Integer; +begin + i := Length(Value); + WriteValue(vautf8String); + WriteDWord(longword(i)); + if i > 0 then + Write(Value[1], i); +end; + +procedure TBinaryObjectWriter.WriteWideString(const Value: WideString); +var len : longword; +{$IFDEF ENDIAN_BIG} + i : integer; + ws : widestring; +{$ENDIF} +begin + WriteValue(vaWString); + len:=Length(Value); + WriteDWord(len); + if len > 0 then + begin + {$IFDEF ENDIAN_BIG} + setlength(ws,len); + for i:=1 to len do + ws[i]:=widechar(SwapEndian(word(Value[i]))); + Write(ws[1], len*sizeof(widechar)); + {$ELSE} + Write(Value[1], len*sizeof(widechar)); + {$ENDIF} + end; +end; + +procedure TBinaryObjectWriter.WriteUnicodeString(const Value: UnicodeString); +var len : longword; +{$IFDEF ENDIAN_BIG} + i : integer; + us : UnicodeString; +{$ENDIF} +begin + WriteValue(vaUString); + len:=Length(Value); + WriteDWord(len); + if len > 0 then + begin + {$IFDEF ENDIAN_BIG} + setlength(us,len); + for i:=1 to len do + us[i]:=widechar(SwapEndian(word(Value[i]))); + Write(us[1], len*sizeof(UnicodeChar)); + {$ELSE} + Write(Value[1], len*sizeof(UnicodeChar)); + {$ENDIF} + end; +end; + +procedure TBinaryObjectWriter.WriteVariant(const VarValue: variant); +begin + { The variant manager will handle varbyref and vararray transparently for us + } + case (tvardata(VarValue).vtype and varTypeMask) of + varEmpty: + begin + WriteValue(vaNil); + end; + varNull: + begin + WriteValue(vaNull); + end; + { all integer sizes must be split for big endian systems } + varShortInt,varSmallInt,varInteger,varInt64: + begin + WriteInteger(VarValue); + end; +{$ifdef FPC} + varQWord: + begin + WriteUInt64(VarValue); + end; +{$endif} + varBoolean: + begin + WriteBoolean(VarValue); + end; + varCurrency: + begin + WriteCurrency(VarValue); + end; +{$ifndef fpunone} + varSingle: + begin + WriteSingle(VarValue); + end; + varDouble: + begin + WriteFloat(VarValue); + end; + varDate: + begin + WriteDate(VarValue); + end; +{$endif fpunone} + varOleStr,varString: + begin + WriteWideString(VarValue); + end; + else + raise EWriteError.CreateFmt(SUnsupportedPropertyVariantType, [Ord(tvardata(VarValue).vtype)]); + end; +end; + + +procedure TBinaryObjectWriter.FlushBuffer; +begin + FStream.WriteBuffer(FBuffer^, FBufPos); + FBufPos := 0; +end; + +procedure TBinaryObjectWriter.Write(const Buffer; Count: LongInt); +var + CopyNow: LongInt; + SourceBuf: PChar; +begin + SourceBuf:=@Buffer; + while Count > 0 do + begin + CopyNow := Count; + if CopyNow > FBufSize - FBufPos then + CopyNow := FBufSize - FBufPos; + Move(SourceBuf^, PChar(FBuffer)[FBufPos], CopyNow); + Dec(Count, CopyNow); + Inc(FBufPos, CopyNow); + inc(SourceBuf, CopyNow); + if FBufPos = FBufSize then + FlushBuffer; + end; +end; + +procedure TBinaryObjectWriter.WriteValue(Value: TValueType); +var + b: byte; +begin + b := byte(Value); + Write(b, 1); +end; + +procedure TBinaryObjectWriter.WriteStr(const Value: String); +var + i: integer; + b: byte; +begin + i := Length(Value); + if i > 255 then + i := 255; + b := i; + Write(b, 1); + if i > 0 then + Write(Value[1], i); +end; + +var + ClassList : TThreadlist; + ClassAliasList : TStringList; + +procedure commoninit(); forward; + +procedure RegisterClass(AClass: TPersistentClass); +var +aClassname : String; +begin + //Classlist is created during initialization. + if classlist = nil then begin + commoninit(); //initialization order sometimes wrong in FPC + end; + { + if classlist = nil then begin + classlist:= tthreadlist.create; + //initialization order sometimes wrong in FPC + end; + if classaliaslist = nil then begin + classaliaslist:= tstringlist.create; + //initialization order sometimes wrong in FPC + end; + } + with Classlist.Locklist do + try + while Indexof(AClass) = -1 do + begin + aClassname := AClass.ClassName; + if GetClass(aClassName) <> nil then //class alread registered! + Begin + //raise an error + exit; + end; + Add(AClass); + if AClass = TPersistent then break; + AClass := TPersistentClass(AClass.ClassParent); + end; + finally + ClassList.UnlockList; + end; +end; + +procedure RegisterClasses(AClasses: array of TPersistentClass); +var +I : Integer; +begin +for I := low(aClasses) to high(aClasses) do + RegisterClass(aClasses[I]); +end; + +procedure RegisterClassAlias(AClass: TPersistentClass; const Alias: string); + var + I : integer; + begin + i := ClassAliasList.IndexOf(Alias); + if I = -1 then + ClassAliasList.AddObject( Alias, TObject(AClass) ); + end; + +procedure UnRegisterClass(AClass: TPersistentClass); +begin + //dummy +end; + +procedure UnRegisterClasses(AClasses: array of TPersistentClass); +begin + //dummy +end; + +procedure UnRegisterModuleClasses(Module: HMODULE); +begin + //dummy +end; + +function FindClass(const AClassName: string): TPersistentClass; + +begin + Result := GetClass(AClassName); + if not Assigned(Result) then + raise EClassNotFound.CreateFmt(SClassNotFound, [AClassName]); +end; + +function GetClass(const AClassName: string): TPersistentClass; +var +I : Integer; +begin + with ClassList.LockList do + try + for I := 0 to Count-1 do + begin + Result := TPersistentClass(Items[I]); + if Result.ClassNameIs(AClassName) then Exit; + end; + I := ClassAliasList.Indexof(AClassName); + if I >= 0 then //found + Begin + Result := TPersistentClass(ClassAliasList.Objects[i]); + exit; + end; + Result := nil; + finally + ClassList.Unlocklist; + end; +end; + +{****************************************************************************} +{* TFileStream *} +{****************************************************************************} + +constructor TFileStream.Create(const AFileName: string; Mode: Word); + +begin + Create(AFileName,Mode,438); +end; + + +constructor TFileStream.Create(const AFileName: string; Mode: Word; Rights: Cardinal); + +begin + FFileName:=AFileName; + If (Mode and fmCreate) > 0 then +{$ifdef FPC} + FHandle:=FileCreate(AFileName,Mode,Rights) +{$else} + FHandle:=FileCreate(AFileName,Rights) +{$endif} + else + FHAndle:=FileOpen(AFileName,Mode); + + If (THandle(FHandle) = feInvalidHandle) then + If Mode=fmcreate then + raise EFCreateError.createfmt(SFCreateError,[AFileName]) + else + raise EFOpenError.Createfmt(SFOpenError,[AFilename]); +end; + + +destructor TFileStream.Destroy; + +begin + FileClose(FHandle); +end; + +{****************************************************************************} +{* THandleStream *} +{****************************************************************************} + +Constructor THandleStream.Create(AHandle: THandle); + +begin + Inherited Create; + FHandle:=AHandle; +end; + + +function THandleStream.Read(var Buffer; Count: Longint): Longint; + +begin + Result:=FileRead(FHandle,Buffer,Count); + If Result=-1 then Result:=0; +end; + + +function THandleStream.Write(const Buffer; Count: Longint): Longint; + +begin + Result:=FileWrite (FHandle,Buffer,Count); + If Result=-1 then Result:=0; +end; + +Procedure THandleStream.SetSize(NewSize: Longint); + +begin + SetSize(Int64(NewSize)); +end; + + +Procedure THandleStream.SetSize(const NewSize: Int64); + +begin + syserror(sys_truncatefile(FHandle,NewSize)); +end; + + +function THandleStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; + +begin + Result:=FileSeek(FHandle,Offset,ord(Origin)); +end; + +function THandleStream.releasehandle(): filehandlety; +begin + result:= fhandle; + fhandle:= invalidfilehandle; +end; + +{****************************************************************************} +{* TStringStream *} +{****************************************************************************} + +function TStringStream.GetSize: Int64; +begin + Result:=Length(FDataString); +end; + +function TStringStream.GetPosition: Int64; +begin + Result:=FPosition; +end; + +procedure TStringStream.SetSize(NewSize: Longint); + +begin + Setlength(FDataString,NewSize); + If FPosition>NewSize then FPosition:=NewSize; +end; + + +constructor TStringStream.Create(const AString: string); + +begin + Inherited create; + FDataString:=AString; +end; + + +function TStringStream.Read(var Buffer; Count: Longint): Longint; + +begin + Result:=Length(FDataString)-FPosition; + If Result>Count then Result:=Count; + // This supposes FDataString to be of type AnsiString ! + Move (Pchar(FDataString)[FPosition],Buffer,Result); + FPosition:=FPosition+Result; +end; + + +function TStringStream.ReadString(Count: Longint): string; + +Var NewLen : Longint; + +begin + NewLen:=Length(FDataString)-FPosition; + If NewLen>Count then NewLen:=Count; + SetLength(Result,NewLen); + Read (Pointer(Result)^,NewLen); +end; + + +function TStringStream.Seek(Offset: Longint; Origin: Word): Longint; + +begin + Case Origin of + soFromBeginning : FPosition:=Offset; + soFromEnd : FPosition:=Length(FDataString)+Offset; + soFromCurrent : FPosition:=FPosition+Offset; + end; + If FPosition>Length(FDataString) then + FPosition:=Length(FDataString) + else If FPosition<0 then + FPosition:=0; + Result:=FPosition; +end; + + +function TStringStream.Write(const Buffer; Count: Longint): Longint; + +begin + Result:=Count; + SetSize(FPosition+Count); + // This supposes that FDataString is of type AnsiString) + Move (Buffer,PChar(FDataString)[Fposition],Count); + FPosition:=FPosition+Count; +end; + + +procedure TStringStream.WriteString(const AString: string); + +begin + Write (PChar(Astring)[0],Length(AString)); +end; + +function TStringStream.getmemory: pointer; +begin + result:= pointer(fdatastring); +end; + +{$ifdef FPC} +{****************************************************************************} +{* TResourceStream *} +{****************************************************************************} + +{$ifdef UNICODE} +procedure TResourceStream.Initialize(Instance: TFPResourceHMODULE; Name, ResType: PWideChar; NameIsID: Boolean); + begin + Res:=FindResource(Instance, Name, ResType); + if Res=0 then + if NameIsID then + raise EResNotFound.CreateFmt(SResNotFound,[IntToStr(PtrInt(Name))]) + else + raise EResNotFound.CreateFmt(SResNotFound,[Name]); + Handle:=LoadResource(Instance,Res); + if Handle=0 then + if NameIsID then + raise EResNotFound.CreateFmt(SResNotFound,[IntToStr(PtrInt(Name))]) + else + raise EResNotFound.CreateFmt(SResNotFound,[Name]); + SetPointer(LockResource(Handle),SizeOfResource(Instance,Res)); + end; + +constructor TResourceStream.Create(Instance: TFPResourceHMODULE; const ResName: WideString; ResType: PWideChar); + begin + inherited create; + Initialize(Instance,PWideChar(ResName),ResType,False); + end; +constructor TResourceStream.CreateFromID(Instance: TFPResourceHMODULE; ResID: Integer; ResType: PWideChar); + begin + inherited create; + Initialize(Instance,PWideChar(ResID),ResType,True); + end; +{$else UNICODE} + +procedure TResourceStream.Initialize(Instance: TFPResourceHMODULE; Name, ResType: PChar; NameIsID: Boolean); + begin + Res:=FindResource(Instance, Name, ResType); + if Res=0 then + if NameIsID then + raise EResNotFound.CreateFmt(SResNotFound,[IntToStr(PtrInt(Name))]) + else + raise EResNotFound.CreateFmt(SResNotFound,[Name]); + Handle:=LoadResource(Instance,Res); + if Handle=0 then + if NameIsID then + raise EResNotFound.CreateFmt(SResNotFound,[IntToStr(PtrInt(Name))]) + else + raise EResNotFound.CreateFmt(SResNotFound,[Name]); + SetPointer(LockResource(Handle),SizeOfResource(Instance,Res)); + end; + +constructor TResourceStream.Create(Instance: TFPResourceHMODULE; const ResName: string; ResType: PChar); + begin + inherited create; + Initialize(Instance,pchar(ResName),ResType,False); + end; +constructor TResourceStream.CreateFromID(Instance: TFPResourceHMODULE; ResID: Integer; ResType: PChar); + begin + inherited create; + Initialize(Instance,pchar(PtrInt(ResID)),ResType,True); + end; +{$endif UNICODE} + + +destructor TResourceStream.Destroy; + begin + UnlockResource(Handle); + FreeResource(Handle); + inherited destroy; + end; +{$endif} + +{****************************************************************************} +{* TOwnerStream *} +{****************************************************************************} + +constructor TOwnerStream.Create(ASource: TStream); +begin + FSource:=ASource; +end; + +destructor TOwnerStream.Destroy; +begin + If FOwner then + FreeAndNil(FSource); + inherited Destroy; +end; + +{****************************************************************************} +{* TCollectionItem *} +{****************************************************************************} + + +function TCollectionItem.GetIndex: Integer; + +begin + if FCollection<>nil then + Result:=FCollection.FItems.IndexOf(Pointer(Self)) + else + Result:=-1; +end; + + + +procedure TCollectionItem.SetCollection(Value: TCollection); + +begin + IF Value<>FCollection then + begin + If FCollection<>Nil then FCollection.RemoveItem(Self); + if Value<>Nil then Value.InsertItem(Self); + FCollection:=Value; + end; +end; + + + +procedure TCollectionItem.Changed(AllItems: Boolean); + +begin + If (FCollection<>Nil) and (FCollection.UpdateCount=0) then + begin + If AllItems then + FCollection.Update(Nil) + else + FCollection.Update(Self); + end; +end; + + + +function TCollectionItem.GetNamePath: string; + +begin + If FCollection<>Nil then + Result:=FCollection.GetNamePath+'['+IntToStr(Index)+']' + else + Result:=ClassName; +end; + + +function TCollectionItem.GetOwner: TPersistent; + +begin + Result:=FCollection; +end; + + + +function TCollectionItem.GetDisplayName: string; + +begin + Result:=ClassName; +end; + + + +procedure TCollectionItem.SetIndex(Value: Integer); + +Var Temp : Longint; + +begin + Temp:=GetIndex; + If (Temp>-1) and (Temp<>Value) then + begin + FCollection.FItems.Move(Temp,Value); + Changed(True); + end; +end; + + +procedure TCollectionItem.SetDisplayName(const Value: string); + +begin + Changed(False); +end; + + + +constructor TCollectionItem.Create(ACollection: TCollection); + +begin + Inherited Create; + SetCollection(ACollection); +end; + + + +destructor TCollectionItem.Destroy; + +begin + SetCollection(Nil); + Inherited Destroy; +end; + +{****************************************************************************} +{* TCollectionEnumerator *} +{****************************************************************************} + +constructor TCollectionEnumerator.Create(ACollection: TCollection); +begin + inherited Create; + FCollection := ACollection; + FPosition := -1; +end; + +function TCollectionEnumerator.GetCurrent: TCollectionItem; +begin + Result := FCollection.Items[FPosition]; +end; + +function TCollectionEnumerator.MoveNext: Boolean; +begin + Inc(FPosition); + Result := FPosition < FCollection.Count; +end; + +{****************************************************************************} +{* TCollection *} +{****************************************************************************} + +function TCollection.Owner: TPersistent; +begin + result:=getowner; +end; + + +function TCollection.GetCount: Integer; + +begin + Result:=FItems.Count; +end; + + +Procedure TCollection.SetPropName; + +Var + TheOwner : TPersistent; + PropList : PPropList; + I, PropCount : Integer; + +begin + FPropName:=''; + TheOwner:=GetOwner; + if (TheOwner=Nil) Or (TheOwner.Classinfo=Nil) Then Exit; + // get information from the owner RTTI + PropCount:=GetPropList(TheOwner, PropList); + Try + For I:=0 To PropCount-1 Do + If (PropList^[i]^.PropType^.Kind=tkClass) And + (GetObjectProp(TheOwner, PropList^[i], ClassType)=Self) Then + Begin + FPropName:=PropList^[i]^.Name; + Exit; + End; + Finally + FreeMem(PropList); + End; +end; + + +function TCollection.GetPropName: string; + +Var + TheOwner : TPersistent; + +begin + Result:=FPropNAme; + TheOwner:=GetOwner; + If (Result<>'') or (TheOwner=Nil) Or (TheOwner.Classinfo=Nil) then exit; + SetPropName; + Result:=FPropName; +end; + + +procedure TCollection.InsertItem(Item: TCollectionItem); +begin + If Not(Item Is FitemClass) then + exit; + FItems.add(Pointer(Item)); + Item.FID:=FNextID; + inc(FNextID); + SetItemName(Item); + Notify(Item,cnAdded); + Changed; +end; + + +{$ifdef mse_fpc_2_6_2} +procedure TCollection.RemoveItem(Item: TCollectionItem); +Var + I : Integer; +begin + Notify(Item,cnExtracting); + I:=FItems.IndexOfItem(Item,fromEnd); + If (I<>-1) then + FItems.Delete(I); + Item.FCollection:=Nil; + Changed; +end; + +{$else} + +procedure TCollection.RemoveItem(Item: TCollectionItem); +begin +Notify(Item,cnExtracting); +FItems.Remove(Pointer(Item)); +Item.FCollection:=Nil; +Changed; +end; +{$endif} + +function TCollection.GetAttrCount: Integer; +begin + Result:=0; +end; + + +function TCollection.GetAttr(Index: Integer): string; +begin + Result:=''; +end; + + +function TCollection.GetItemAttr(Index, ItemIndex: Integer): string; +begin + Result:=TCollectionItem(FItems.Items[ItemIndex]).DisplayName; +end; + + +function TCollection.GetEnumerator: TCollectionEnumerator; +begin + Result := TCollectionEnumerator.Create(Self); +end; + + +function TCollection.GetNamePath: string; +var o : TPersistent; +begin + o:=getowner; + if assigned(o) and (propname<>'') then + result:=o.getnamepath+'.'+propname + else + result:=classname; +end; + + +procedure TCollection.Changed; +begin + if FUpdateCount=0 then + Update(Nil); +end; + + +function TCollection.GetItem(Index: Integer): TCollectionItem; +begin + Result:=TCollectionItem(FItems.Items[Index]); +end; + + +procedure TCollection.SetItem(Index: Integer; Value: TCollectionItem); +begin + TCollectionItem(FItems.items[Index]).Assign(Value); +end; + + +procedure TCollection.SetItemName(Item: TCollectionItem); +begin +end; + + + +procedure TCollection.Update(Item: TCollectionItem); +begin +// FPONotifyObservers(Self,ooChange,Pointer(Item)); +end; + + +constructor TCollection.Create(AItemClass: TCollectionItemClass); +begin + inherited create; + FItemClass:=AItemClass; + FItems:=TFpList.Create; +end; + + +destructor TCollection.Destroy; +begin + BeginUpdate; // Prevent OnChange + DoClear; + FItems.Free; + Inherited Destroy; +end; + + +function TCollection.Add: TCollectionItem; +begin + Result:=FItemClass.Create(Self); +end; + + +procedure TCollection.Assign(Source: TPersistent); +Var I : Longint; +begin + If Source is TCollection then + begin + Clear; + For I:=0 To TCollection(Source).Count-1 do + Add.Assign(TCollection(Source).Items[I]); + exit; + end + else + Inherited Assign(Source); +end; + + +procedure TCollection.BeginUpdate; +begin + inc(FUpdateCount); +end; + + +procedure TCollection.Clear; +begin + if FItems.Count=0 then + exit; // Prevent Changed + BeginUpdate; + try + DoClear; + finally + EndUpdate; + end; +end; + + +procedure TCollection.DoClear; +begin + While FItems.Count>0 do TCollectionItem(FItems.Last).Free; +end; + + +procedure TCollection.EndUpdate; +begin + dec(FUpdateCount); + if FUpdateCount=0 then + Changed; +end; + + +function TCollection.FindItemID(ID: Integer): TCollectionItem; +Var + I : Longint; +begin + For I:=0 to Fitems.Count-1 do + begin + Result:=TCollectionItem(FItems.items[I]); + If Result.Id=Id then + exit; + end; + Result:=Nil; +end; + + +procedure TCollection.Delete(Index: Integer); +Var + Item : TCollectionItem; +begin + Item:=TCollectionItem(FItems[Index]); + Notify(Item,cnDeleting); + Item.Free; +end; + + +function TCollection.Insert(Index: Integer): TCollectionItem; +begin + Result:=Add; + Result.Index:=Index; +end; + + +procedure TCollection.Notify(Item: TCollectionItem;Action: TCollectionNotification); +begin +{ + if Assigned(FObservers) then + Case Action of + cnAdded : FPONotifyObservers(Self,ooAddItem,Pointer(Item)); + cnExtracting : FPONotifyObservers(Self,ooDeleteItem,Pointer(Item)); + cnDeleting : FPONotifyObservers(Self,ooDeleteItem,Pointer(Item)); + end; +} +end; + +procedure TCollection.Sort(Const Compare : TCollectionSortCompare); + +begin + BeginUpdate; + try + FItems.Sort(TListSortCompare(Compare)); + Finally + EndUpdate; + end; +end; + +procedure TCollection.Exchange(Const Index1, index2: integer); + +begin + FItems.Exchange(Index1,Index2); +// FPONotifyObservers(Self,ooChange,Nil); +end; + +{****************************************************************************} +{* TOwnedCollection *} +{****************************************************************************} + + + +Constructor TOwnedCollection.Create(AOwner: TPersistent; AItemClass: TCollectionItemClass); + +Begin + FOwner := AOwner; + inherited Create(AItemClass); +end; + + + +Function TOwnedCollection.GetOwner: TPersistent; + +begin + Result:=FOwner; +end; + +function ExtractStrings(Separators, WhiteSpace: TSysCharSet; Content: PChar; Strings: TStrings): Integer; +var + b, c : pchar; + + procedure SkipWhitespace; + begin + while (c^ in Whitespace) do + inc (c); + end; + + procedure AddString; + var + l : integer; + s : string; + begin + l := c-b; + if l > 0 then + begin + if assigned(Strings) then + begin + setlength(s, l); + move (b^, s[1],l); + Strings.Add (s); + end; + inc (result); + end; + end; + +var + quoted : char; +begin + result := 0; + c := Content; + Quoted := #0; + Separators := Separators + [#13, #10] - ['''','"']; + SkipWhitespace; + b := c; + while (c^ <> #0) do + begin + if (c^ = Quoted) then + begin + if ((c+1)^ = Quoted) then + inc (c) + else + Quoted := #0 + end + else if (Quoted = #0) and (c^ in ['''','"']) then + Quoted := c^; + if (Quoted = #0) and (c^ in Separators) then + begin + AddString; + inc (c); + SkipWhitespace; + b := c; + end + else + inc (c); + end; + if (c <> b) then + AddString; +end; + +var + inited: boolean; + +procedure CommonInit; +begin + if inited then begin + exit; + end; + inited:= true; +// InitCriticalSection(SynchronizeCritSect); +// ExecuteEvent:=RtlEventCreate; +// SynchronizeTimeoutEvent:=RtlEventCreate; +// DoSynchronizeMethod:=false; +// MainThreadID:=GetCurrentThreadID; +{$ifdef FPC} + InitCriticalsection(ResolveSection); +{$else} + InitializeCriticalsection(ResolveSection); +{$endif} +// InitHandlerList:=Nil; +// FindGlobalComponentList:=nil; + IntConstList := TThreadList.Create; +// if classlist = nil then begin + ClassList := TThreadList.Create; +// end; +// if classaliaslist = nil then begin + ClassAliasList := TStringList.Create; +// end; + { on unix this maps to a simple rw synchornizer } + GlobalNameSpace := TMultiReadExclusiveWriteSynchronizer.Create; + RegisterInitComponentHandler(TComponent,@DefaultInitHandler); +end; + + +procedure CommonCleanup; +var + i: Integer; +begin + GlobalNameSpace.BeginWrite; + with IntConstList.LockList do + try + for i := 0 to Count - 1 do + TIntConst(Items[I]).Free; + finally + IntConstList.UnlockList; + end; + IntConstList.Free; + ClassList.Free; + ClassAliasList.Free; + RemoveFixupReferences(nil, ''); +{$ifdef FPC} + DoneCriticalsection(ResolveSection); +{$else} + DeleteCriticalsection(ResolveSection); +{$endif} + GlobalLists.Free; + // ComponentPages.Free; + FreeAndNil(NeedResolving); + globalnamespace.endwrite; + + { GlobalNameSpace is an interface so this is enough } +// GlobalNameSpace:=nil; + + if (InitHandlerList<>Nil) then + for i := 0 to InitHandlerList.Count - 1 do + TInitHandler(InitHandlerList.Items[I]).Free; + InitHandlerList.Free; + InitHandlerList:=Nil; + FindGlobalComponentList.Free; + FindGlobalComponentList:=nil; +// DoneCriticalSection(SynchronizeCritSect); +// RtlEventDestroy(ExecuteEvent); +// RtlEventDestroy(SynchronizeTimeoutEvent); +end; + +initialization + commoninit; +finalization + commoncleanup; +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/mdb.pas b/mseide-msegui/lib/common/fpccompatibility/mdb.pas new file mode 100644 index 0000000..d962c13 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/mdb.pas @@ -0,0 +1,11557 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 1999-2000 by Michael Van Canneyt, member of the + Free Pascal development team + + + DB header file with interface section. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Modified 2013-2018 by Martin Schreiber + + **********************************************************************} +unit mdb; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,sysutils,variants,fmtbcd,maskutils,msetypes,mseifiglob, + msestrings + {$ifndef FPC},classes_del{$endif}; + +const + + dsMaxBufferCount = MAXINT div 8; + dsMaxStringSize = 8192; + + // Used in AsBoolean for string fields to determine + // whether it's true or false. + YesNoChars : Array[Boolean] of char = ('N', 'Y'); + + SQLDelimiterCharacters = [';',',',' ','(',')',#13,#10,#9]; + +type + +{LargeInt} + LargeInt = Int64; + PLargeInt= ^LargeInt; + +{ Auxiliary type } + TStringFieldBuffer = Array[0..dsMaxStringSize] of Char; + +{ Misc Dataset types } + + TDataSetState = (dsInactive, dsBrowse, dsEdit, dsInsert, dsSetKey, + dsCalcFields, dsFilter, dsNewValue, dsOldValue, dsCurValue, dsBlockRead, + dsInternalCalc, dsOpening); + + TDataEvent = (deFieldChange, deRecordChange, deDataSetChange, + deDataSetScroll, deLayoutChange, deUpdateRecord, deUpdateState, + deCheckBrowseMode, dePropertyChange, deFieldListChange, deFocusControl, + deParentScroll,deConnectChange,deReconcileError,deDisabledStateChange); + + TUpdateStatus = (usUnmodified, usModified, usInserted, usDeleted); + TUpdateStatusSet = SET OF TUpdateStatus; + + TUpdateMode = (upWhereAll, upWhereChanged, upWhereKeyOnly); + TResolverResponse = (rrSkip, rrAbort, rrMerge, rrApply, rrIgnore); + +// providerflag1ty = (pf1_refreshinsert,pf1_refreshupdate,pf1_nocopyrecord); +// providerflags1ty = set of providerflag1ty; +// defaultproviderflags = [pfInInsert,pfInUpdate,pfInWhere]; + +{ Forward declarations } + + TFieldDef = class; + TFieldDefs = class; + TField = class; + TFields = Class; + TDataSet = class; + TDataBase = Class; + TDatasource = Class; + TDatalink = Class; + TDBTransaction = Class; + +{ Exception classes } + + EDatabaseError = class(Exception) + public + constructor create(const msg: string; const comp: tcomponent); overload; + end; + + EUpdateError = class(EDatabaseError) + private + FContext : String; + FErrorCode : integer; + FOriginalException : Exception; + FPreviousError : Integer; + public + constructor Create(NativeError, Context : String; + ErrCode, PrevError : integer; E: Exception); + Destructor Destroy; override; + property Context : String read FContext; + property ErrorCode : integer read FErrorcode; + property OriginalException : Exception read FOriginalException; + property PreviousError : Integer read FPreviousError; + end; + + +{ TFieldDef } + + TFieldClass = class of TField; + +{ + TFieldType = (ftUnknown, ftString, ftSmallint, ftInteger, ftWord, + ftBoolean, ftFloat, ftDate, ftTime, ftDateTime, + ftBytes, ftVarBytes, ftAutoInc, ftBlob, ftMemo, ftGraphic, + ftFmtMemo, ftParadoxOle, ftDBaseOle, ftTypedBinary, ftCursor); +} + + TFieldType = (ftUnknown, ftString, ftSmallint, ftInteger, ftWord, + ftBoolean, ftFloat, ftCurrency, ftBCD, ftDate, ftTime, ftDateTime, + ftBytes, ftVarBytes, ftAutoInc, ftBlob, ftMemo, ftGraphic, ftFmtMemo, + ftParadoxOle, ftDBaseOle, ftTypedBinary, ftCursor, ftFixedChar, + ftWideString, ftLargeint, ftADT, ftArray, ftReference, + ftDataSet, ftOraBlob, ftOraClob, ftVariant, ftInterface, + ftIDispatch, ftGuid, ftTimeStamp, ftFMTBcd, ftFixedWideChar, ftWideMemo); + +{ Part of DBCommon, but temporary defined here (bug 8206) } + + TFieldMap = array[TFieldType] of Byte; + +{ TDateTimeRec } + + TDateTimeAlias = type TDateTime; + PDateTimeRec = ^TdateTimeRec; + TDateTimeRec = record + case TFieldType of + ftDate: (Date: Longint); + ftTime: (Time: Longint); + ftDateTime: (DateTime: TDateTimeAlias); + end; + + TFieldAttribute = (faHiddenCol, faReadonly, faRequired, faLink, faUnNamed, faFixed); + TFieldAttributes = set of TFieldAttribute; + + { TNamedItem } + + TNamedItem = class(TCollectionItem) + private + FName: string; + protected + function GetDisplayName: string; override; + procedure SetDisplayName(const AValue: string); override; + Public + property DisplayName : string read GetDisplayName write SetDisplayName; + published + property Name : string read FName write SetDisplayName; + end; + + { TDefCollection } + + TDefCollection = class(TOwnedCollection) + private + FDataset: TDataset; + FUpdated: boolean; + protected + procedure SetItemName(AItem: TCollectionItem); override; + public + constructor create(ADataset: TDataset; AOwner: TPersistent; AClass: TCollectionItemClass); + function Find(const AName: string): TNamedItem; + procedure GetItemNames(List: TStrings); + function IndexOf(const AName: string): Longint; + property Dataset: TDataset read FDataset; + property Updated: boolean read FUpdated write FUpdated; + end; + + { TFieldDef } + + TFieldDef = class(TNamedItem) + Private + FDataType : TFieldType; + FInternalCalcField : Boolean; + FPrecision : Longint; + FRequired : Boolean; + FSize : Integer; + FAttributes : TFieldAttributes; + Function GetFieldClass : TFieldClass; + procedure SetAttributes(AValue: TFieldAttributes); + procedure SetDataType(AValue: TFieldType); + procedure SetPrecision(const AValue: Longint); + procedure SetSize(const AValue: Integer); + procedure SetRequired(const AValue: Boolean); + protected + FFieldNo : Longint; + public + constructor create(ACollection : TCollection); overload; override; + constructor Create(AOwner: TFieldDefs; const AName: string; + ADataType: TFieldType; ASize: Integer; ARequired: Boolean; + AFieldNo: Longint); overload; + destructor Destroy; override; + procedure Assign(APersistent: TPersistent); override; + function CreateField(AOwner: TComponent): TField; + property FieldClass: TFieldClass read GetFieldClass; + property FieldNo: Longint read FFieldNo; + property InternalCalcField: Boolean read FInternalCalcField write FInternalCalcField; + property Required: Boolean read FRequired write SetRequired; + Published + property Attributes: TFieldAttributes read FAttributes write SetAttributes default []; + property DataType: TFieldType read FDataType write SetDataType; + property Precision: Longint read FPrecision write SetPrecision default -1; + property Size: Integer read FSize write SetSize default 0; + end; + +{ TFieldDefs } + + TFieldDefs = class(TDefCollection) + private + FHiddenFields : Boolean; + function GetItem(Index: Longint): TFieldDef; + procedure SetItem(Index: Longint; const AValue: TFieldDef); + public + constructor Create(ADataSet: TDataSet); +// destructor Destroy; override; + procedure Add(const AName: string; ADataType: TFieldType; ASize: Word; ARequired: Boolean); overload; + procedure Add(const AName: string; ADataType: TFieldType; ASize: Word); overload; + procedure Add(const AName: string; ADataType: TFieldType); overload; + Function AddFieldDef : TFieldDef; + procedure Assign(FieldDefs: TFieldDefs); overload; + function Find(const AName: string): TFieldDef; +// procedure Clear; +// procedure Delete(Index: Longint); + procedure Update; overload; + Function MakeNameUnique(const AName : String) : string; virtual; + Property HiddenFields : Boolean Read FHiddenFields Write FHiddenFields; + property Items[Index: Longint]: TFieldDef read GetItem write SetItem; default; + end; + +{ TField } + + TFieldKind = (fkData, fkCalculated, fkLookup, fkInternalCalc); + TFieldKinds = Set of TFieldKind; + + TProviderFlag = (pfInUpdate, pfInWhere, pfInKey, pfHidden) deprecated; +{$push}{$warnings off} + TProviderFlags = set of TProviderFlag deprecated; +{$pop} + + optionfieldty = (of_readonly,of_required,of_visible, + of_filter,of_filtermin,of_filtermax,of_find, + of_initinsert,of_initcopy,of_nocopyrecord,of_nomodified, + of_ininsert,of_inupdate,of_inwhere,of_inkey,of_hidden, + of_refreshinsert,of_refreshupdate, + of_user0,of_user1,of_user2,of_user3, + of_user4,of_user5,of_user6,of_user7); + optionsfieldty = set of optionfieldty; +const + defaultoptionsfield = [of_visible,of_ininsert,of_inupdate,of_inwhere]; + +type + TFieldNotifyEvent = procedure(Sender: TField) of object; + TFieldGetTextEvent = procedure(Sender: TField; var aText: string; + DisplayText: Boolean) of object; + TFieldSetTextEvent = procedure(Sender: TField; const aText: string) of object; + TFieldRef = ^TField; + TFieldChars = set of Char; + + PLookupListRec = ^TLookupListRec; + TLookupListRec = record + Key: Variant; + Value: Variant; + end; + + { TLookupList } + + TLookupList = class(TObject) + private + FList: TFPList; + public + constructor Create; + destructor Destroy; override; + procedure Add(const AKey, AValue: Variant); + procedure Clear; + function FirstKeyByValue(const AValue: Variant): Variant; + function ValueOfKey(const AKey: Variant): Variant; + procedure ValuesToStrings(AStrings: TStrings); + end; + + { TField } + + fielddataenteredeventty = procedure(const sender: tfield; + const editobj: tobject) of object; + integerfieldsetvalueeventty = procedure(const sender: tfield; + const editobj: tobject; + var avalue: int32; var accept: boolean) of object; + int64fieldsetvalueeventty = procedure(const sender: tfield; + const editobj: tobject; + var avalue: int64; var accept: boolean) of object; + bcdfieldsetvalueeventty = procedure(const sender: tfield; + const editobj: tobject; + var avalue: currency; var accept: boolean) of object; + floatfieldsetvalueeventty = procedure(const sender: tfield; + const editobj: tobject; + var avalue: flo64; var accept: boolean) of object; + datetimefieldsetvalueeventty = procedure(const sender: tfield; + const editobj: tobject; + var avalue: tdatetime; var accept: boolean) of object; + + booleanfieldsetvalueeventty = procedure(const sender: tfield; + const editobj: tobject; + var avalue: boolean; var accept: boolean) of object; + msestringfieldsetvalueeventty = procedure(const sender: tfield; + const editobj: tobject; + var avalue: msestring; var accept: boolean) of object; + ansistringfieldsetvalueeventty = procedure(const sender: tfield; + const editobj: tobject; + var avalue: ansistring; var accept: boolean) of object; + TField = class(TComponent) + private + FAlignment : TAlignment; + FAttributeSet : String; + FCalculated : Boolean; + FConstraintErrorMessage : String; + FCustomConstraint : String; + FDataSet : TDataSet; +// FDataSize : Word; + FDataType : TFieldType; + FDefaultExpression : String; + FDisplayLabel : utf8String; + FDisplayWidth : Longint; + FEditMask: TEditMask; + FFieldKind : TFieldKind; + FFieldName : String; + FFields : TFields; + FHasConstraints : Boolean; + FImportedConstraint : String; + FIsIndexField : Boolean; + FKeyFields : String; + FLookupCache : Boolean; + FLookupDataSet : TDataSet; + FLookupKeyfields : String; + FLookupresultField : String; + FLookupList: TLookupList; + FOnChange : TFieldNotifyEvent; + FOnGetText: TFieldGetTextEvent; + FOnSetText: TFieldSetTextEvent; + FOnValidate: TFieldNotifyEvent; + FOrigin : String; +// FReadOnly : Boolean; +// FRequired : Boolean; + FSize : integer; + FValidChars : TFieldChars; +// FVisible : Boolean; +// FProviderFlags : TProviderFlags; + foptionsfield: optionsfieldty; + fondataentered: fielddataenteredeventty; + function GetIndex : longint; + function GetLookup: Boolean; + procedure SetAlignment(const AValue: TAlignMent); + procedure SetIndex(const AValue: Integer); + function GetDisplayText: String; + function GetEditText: String; + procedure SetEditText(const AValue: string); + function getdisplaylabel(): utf8string; + procedure SetDisplayLabel(const AValue: utf8string); + procedure SetDisplayWidth(const AValue: Longint); + function GetDisplayWidth: integer; + procedure SetLookup(const AValue: Boolean); + procedure SetReadOnly(const AValue: Boolean); + procedure SetVisible(const AValue: Boolean); + function IsDisplayStored : Boolean; + function GetLookupList: TLookupList; + procedure CalcLookupValue; + function getProviderFlags: TProviderFlags; + procedure setProviderFlags(const avalue: TProviderFlags); + function getReadOnly: Boolean; + function getRequired: Boolean; + procedure setRequired(const avalue: Boolean); + function getVisible: Boolean; + procedure readproviderflags(reader: treader); + procedure readproviderflags1(reader: treader); + procedure readrequired(reader: treader); + procedure readvisible(reader: treader); + procedure readreadonly(reader: treader); + procedure setoptionsfield(const avalue: optionsfieldty); + procedure setlookupdataset(const avalue: tdataset); + function getbuffervalue: variant; + function getasid: int64; + procedure setasid(const avalue: int64); + protected + FValidating : Boolean; + FValueBuffer : Pointer; + FOffset : Word; + FFieldNo : Longint; + function AccessError(const TypeName: string): EDatabaseError; + procedure CheckInactive; + class procedure CheckTypeSize(AValue: Longint); virtual; + procedure Change; virtual; + procedure DataChanged; + procedure FreeBuffers; virtual; + function GetAsBCD: TBCD; virtual; + function GetAsBoolean: Boolean; virtual; + function GetAsBytes: TBytes; virtual; + function GetAsCurrency: Currency; virtual; + function GetAsLargeInt: LargeInt; virtual; + function GetAsDateTime: TDateTime; virtual; + function getasdate: tdatetime; virtual; + function getastime: tdatetime; virtual; + function GetAsFloat: Double; virtual; + function GetAsLongint: Longint; virtual; + function GetAsInteger: Longint; virtual; + function GetAsVariant: variant; virtual; + function GetOldValue: variant; virtual; + function GetAsString: string; virtual; + function GetAsWideString: WideString; virtual; + function getasunicodestring: unicodestring; virtual; + procedure setasunicodestring(const avalue: unicodestring); virtual; + function GetCanModify: Boolean; virtual; + function GetClassDesc: String; virtual; + function GetDataSize: Integer; virtual; + function GetDefaultWidth: Longint; virtual; + function GetDisplayName : String; + function GetCurValue: Variant; virtual; + function GetNewValue: Variant; virtual; + function GetIsNull: Boolean; virtual; + procedure GetText(var AText: string; ADisplayText: Boolean); virtual; + procedure Notification(AComponent: TComponent; + Operation: TOperation); override; + procedure PropertyChanged(LayoutAffected: Boolean); + procedure ReadState(Reader: TReader); override; + procedure SetAsBCD(const AValue: TBCD); virtual; + procedure SetAsBoolean(AValue: Boolean); virtual; + procedure SetAsBytes(const AValue: TBytes); virtual; + procedure SetAsCurrency(AValue: Currency); virtual; + procedure SetAsDateTime(AValue: TDateTime); virtual; + procedure setasdate(avalue: tdatetime); virtual; + procedure setastime(avalue: tdatetime); virtual; + procedure SetAsFloat(AValue: Double); virtual; + procedure SetAsLongint(AValue: Longint); virtual; + procedure SetAsInteger(AValue: Integer); virtual; + procedure SetAsLargeint(AValue: Largeint); virtual; + procedure SetAsVariant(const AValue: variant); virtual; + procedure SetAsString(const AValue: string); virtual; + procedure SetAsWideString(const aValue: WideString); virtual; + procedure SetDataset(AValue : TDataset); virtual; + procedure SetDataType(AValue: TFieldType); + procedure SetNewValue(const AValue: Variant); + procedure SetSize(AValue: Integer); virtual; + procedure SetParentComponent(AParent: TComponent); override; + procedure SetText(const AValue: string); virtual; + procedure SetVarValue(const AValue: Variant); virtual; + function getasguid: tguid; virtual; + procedure setasguid(const avalue: tguid); virtual; + procedure defineproperties(filer: tfiler); override; + procedure dosetvalue(const sender: tobject; var avalue: int32; + var accept: boolean) virtual; + procedure dosetvalue(const sender: tobject; var avalue: int64; + var accept: boolean) virtual; + procedure dosetvalue(const sender: tobject; var avalue: currency; + var accept: boolean) virtual; + procedure dosetvalue(const sender: tobject; var avalue: flo64; + var accept: boolean) virtual; + procedure dosetvalue(const sender: tobject; var avalue: msestring; + var accept: boolean) virtual; + procedure dosetvalue(const sender: tobject; var avalue: ansistring; + var accept: boolean) virtual; + procedure dodataentered(const sender: tobject) virtual; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + procedure Assign(Source: TPersistent); override; + procedure AssignValue(const AValue: TVarRec); + function GetParentComponent: TComponent; override; + function HasParent: Boolean; override; + procedure Clear; virtual; + procedure FocusControl; + function GetData(Buffer: Pointer): Boolean; overload; + function GetData(Buffer: Pointer; + NativeFormat : Boolean): Boolean; overload; + class function IsBlob: Boolean; virtual; + function IsValidChar(InputChar: Char): Boolean; virtual; + procedure RefreshLookupList; + procedure SetData(Buffer: Pointer); overload; + procedure SetData(Buffer: Pointer; NativeFormat : Boolean); overload; + procedure SetFieldType(AValue: TFieldType); virtual; + procedure Validate(Buffer: Pointer); + property AsBCD: TBCD read GetAsBCD write SetAsBCD; + property AsBoolean: Boolean read GetAsBoolean write SetAsBoolean; + property AsBytes: TBytes read GetAsBytes write SetAsBytes; + property AsCurrency: Currency read GetAsCurrency write SetAsCurrency; + property AsDateTime: TDateTime read GetAsDateTime write SetAsDateTime; + property asdate: tdatetime read getasdate write setasdate; + property astime: tdatetime read getastime write setastime; + property AsFloat: Double read GetAsFloat write SetAsFloat; + property asguid: tguid read getasguid write setasguid; + property AsLongint: Longint read GetAsLongint write SetAsLongint; + property AsLargeInt: LargeInt read GetAsLargeInt write SetAsLargeInt; + property asid: int64 read getasid write setasid; //-1 -> NULL + property AsInteger: Integer read GetAsInteger write SetAsInteger; + property AsString: string read GetAsString write SetAsString; + property AsWideString: WideString read GetAsWideString + write SetAsWideString; + property asunicodestring: unicodestring read getasunicodestring + write setasunicodestring; + property asmsestring: msestring read getasunicodestring + write setasunicodestring; + property AsVariant: variant read GetAsVariant write SetAsVariant; + property AttributeSet: string read FAttributeSet write FAttributeSet; + property Calculated: Boolean read FCalculated write FCalculated; + property CanModify: Boolean read GetCanModify; + property CurValue: Variant read GetCurValue; + property DataSet: TDataSet read FDataSet write SetDataSet; + property DataSize: Integer read GetDataSize; + property DataType: TFieldType read FDataType; + property DisplayName: String Read GetDisplayName; + property DisplayText: String read GetDisplayText; + property EditMask: TEditMask read FEditMask write FEditMask; + property EditMaskPtr: TEditMask read FEditMask; + property FieldNo: Longint read FFieldNo; + property IsIndexField: Boolean read FIsIndexField; + property IsNull: Boolean read GetIsNull; + property Lookup: Boolean read GetLookup write SetLookup; + property NewValue: Variant read GetNewValue write SetNewValue; + property Offset: word read FOffset; + property Size: Integer read FSize write SetSize; + property Text: string read GetEditText write SetEditText; + property ValidChars : TFieldChars read FValidChars write FValidChars; + property Value: variant read GetAsVariant write SetAsVariant; + property buffervalue: variant read getbuffervalue; + //returns current value in editbuffer, can be used in OnValidate + property OldValue: variant read GetOldValue; + property LookupList: TLookupList read GetLookupList; +{$push}{$warnings off} + property ProviderFlags : TProviderFlags read getProviderFlags + write setProviderFlags; deprecated; +{$pop} + property ReadOnly: Boolean read getReadOnly write SetReadOnly; + property Required: Boolean read getRequired write setRequired; + property Visible: Boolean read getVisible write SetVisible default True; + published + property Alignment : TAlignment read FAlignment write SetAlignment + default taLeftJustify; + property CustomConstraint: string read FCustomConstraint + write FCustomConstraint; + property ConstraintErrorMessage: string read FConstraintErrorMessage + write FConstraintErrorMessage; + property DefaultExpression: string read FDefaultExpression + write FDefaultExpression; + property DisplayLabel : utf8string read GetDisplaylabel + write SetDisplayLabel stored IsDisplayStored; + property DisplayWidth: Longint read GetDisplayWidth write SetDisplayWidth; + property FieldKind: TFieldKind read FFieldKind write FFieldKind; + property FieldName: string read FFieldName write FFieldName; + property HasConstraints: Boolean read FHasConstraints; + property Index: Longint read GetIndex write SetIndex; + property ImportedConstraint: string read FImportedConstraint + write FImportedConstraint; + property KeyFields: string read FKeyFields write FKeyFields; + property LookupCache: Boolean read FLookupCache write FLookupCache; + property LookupDataSet: TDataSet read FLookupDataSet write setLookupDataSet; + property LookupKeyFields: string read FLookupKeyFields + write FLookupKeyFields; + property LookupResultField: string read FLookupResultField + write FLookupResultField; + property Origin: string read FOrigin write FOrigin; + property optionsfield: optionsfieldty read foptionsfield + write setoptionsfield default defaultoptionsfield; + + property OnChange: TFieldNotifyEvent read FOnChange write FOnChange; + property OnGetText: TFieldGetTextEvent read FOnGetText write FOnGetText; + property OnSetText: TFieldSetTextEvent read FOnSetText write FOnSetText; + property OnValidate: TFieldNotifyEvent read FOnValidate write FOnValidate; + property ondataentered: fielddataenteredeventty read fondataentered write + fondataentered; + end; + +{ TStringField } + + TStringField = class(TField) + private + FFixedChar : boolean; + FTransliterate : Boolean; + fonsetvalue: ansistringfieldsetvalueeventty; + protected + class procedure CheckTypeSize(AValue: Longint); override; + function GetAsBoolean: Boolean; override; + function GetAsDateTime: TDateTime; override; + function GetAsFloat: Double; override; + function GetAsLongint: Longint; override; + function GetAsString: string; override; + function GetAsVariant: variant; override; + function GetDataSize: Integer; override; + function GetDefaultWidth: Longint; override; + procedure GetText(var AText: string; ADisplayText: Boolean); override; + function GetValue(var AValue: string): Boolean; + procedure SetAsBoolean(AValue: Boolean); override; + procedure SetAsDateTime(AValue: TDateTime); override; + procedure SetAsFloat(AValue: Double); override; + procedure SetAsLongint(AValue: Longint); override; + procedure SetAsString(const AValue: string); override; + procedure SetVarValue(const AValue: Variant); override; + procedure dosetvalue(const sender: tobject; var avalue: ansistring; + var accept: boolean) override; + public + constructor Create(AOwner: TComponent); override; + procedure SetFieldType(AValue: TFieldType); override; + property FixedChar : Boolean read FFixedChar write FFixedChar; + property Transliterate: Boolean read FTransliterate write FTransliterate; + property Value: String read GetAsString write SetAsString; + published + property EditMask; + property Size default 20; + property onsetvalue: ansistringfieldsetvalueeventty + read fonsetvalue write fonsetvalue; + end; + +{ TWideStringField } + + TWideStringField = class(TStringField) + protected + class procedure CheckTypeSize(aValue: Integer); override; + + function GetValue(var aValue: WideString): Boolean; + + function GetAsString: string; override; + procedure SetAsString(const aValue: string); override; + function getasunicodestring: unicodestring; override; + procedure setasunicodestring(const avalue: unicodestring); override; + + function GetAsVariant: Variant; override; + procedure SetVarValue(const aValue: Variant); override; + + function GetAsWideString: WideString; override; + procedure SetAsWideString(const aValue: WideString); override; + + function GetDataSize: Integer; override; + public + constructor Create(aOwner: TComponent); override; + procedure SetFieldType(AValue: TFieldType); override; + property Value: WideString read GetAsWideString write SetAsWideString; + end; + + +{ TNumericField } + TNumericField = class(TField) + Private + FDisplayFormat : utf8String; + FEditFormat : utf8String; + protected + class procedure CheckTypeSize(AValue: Longint); override; + procedure RangeError(AValue, Min, Max: Double); + procedure SetDisplayFormat(const AValue: utf8string); + procedure SetEditFormat(const AValue: utf8string); + function GetAsBoolean: Boolean; override; + Procedure SetAsBoolean(AValue: Boolean); override; + public + constructor Create(AOwner: TComponent); override; + published + property Alignment default taRightJustify; + property DisplayFormat: utf8string read FDisplayFormat write SetDisplayFormat; + property EditFormat: utf8string read FEditFormat write SetEditFormat; + end; + +{ TLongintField } + + TLongintField = class(TNumericField) + private + FMinValue, + FMaxValue, + FMinRange, + FMAxRange : Longint; + fonsetvalue: integerfieldsetvalueeventty; + Procedure SetMinValue (AValue : longint); + Procedure SetMaxValue (AValue : longint); + protected + function GetAsFloat: Double; override; + function GetAsLongint: Longint; override; + function GetAsString: string; override; + function GetAsVariant: variant; override; + function GetDataSize: Integer; override; + procedure GetText(var AText: string; ADisplayText: Boolean); override; + function GetValue(var AValue: Longint): Boolean; + procedure SetAsFloat(AValue: Double); override; + procedure SetAsLongint(AValue: Longint); override; + procedure SetAsString(const AValue: string); override; + procedure SetVarValue(const AValue: Variant); override; + function GetAsLargeint: Largeint; override; + procedure SetAsLargeint(AValue: Largeint); override; + procedure dosetvalue(const sender: tobject; var avalue: int32; + var accept: boolean) override; + public + constructor Create(AOwner: TComponent); override; + Function CheckRange(AValue : longint) : Boolean; + property Value: Longint read GetAsLongint write SetAsLongint; + published + property MaxValue: Longint read FMaxValue write SetMaxValue default 0; + property MinValue: Longint read FMinValue write SetMinValue default 0; + property onsetvalue: integerfieldsetvalueeventty + read fonsetvalue write fonsetvalue; + end; + TIntegerField = Class(TLongintField); + +{ TLargeintField } + + TLargeintField = class(TNumericField) + private + FMinValue, + FMaxValue, + FMinRange, + FMAxRange : Largeint; + fonsetvalue: int64fieldsetvalueeventty; + Procedure SetMinValue (AValue : Largeint); + Procedure SetMaxValue (AValue : Largeint); + protected + function GetAsFloat: Double; override; + function GetAsLongint: Longint; override; + function GetAsLargeint: Largeint; override; + function GetAsString: string; override; + function GetAsVariant: variant; override; + function GetDataSize: Integer; override; + procedure GetText(var AText: string; ADisplayText: Boolean); override; + function GetValue(var AValue: Largeint): Boolean; + procedure SetAsFloat(AValue: Double); override; + procedure SetAsLongint(AValue: Longint); override; + procedure SetAsLargeint(AValue: Largeint); override; + procedure SetAsString(const AValue: string); override; + procedure SetVarValue(const AValue: Variant); override; + procedure dosetvalue(const sender: tobject; var avalue: int64; + var accept: boolean) override; + public + constructor Create(AOwner: TComponent); override; + Function CheckRange(AValue : largeint) : Boolean; + property Value: Largeint read GetAsLargeint write SetAsLargeint; + published + property MaxValue: Largeint read FMaxValue write SetMaxValue default 0; + property MinValue: Largeint read FMinValue write SetMinValue default 0; + property onsetvalue: int64fieldsetvalueeventty + read fonsetvalue write fonsetvalue; + end; + +{ TSmallintField } + + TSmallintField = class(TLongintField) + protected + function GetDataSize: Integer; override; + public + constructor Create(AOwner: TComponent); override; + end; + +{ TWordField } + + TWordField = class(TLongintField) + protected + function GetDataSize: Integer; override; + public + constructor Create(AOwner: TComponent); override; + end; + +{ TAutoIncField } + + TAutoIncField = class(TLongintField) + Protected + Procedure SetAsLongInt(AValue : Longint); override; + public + constructor Create(AOwner: TComponent); override; + end; + +{ TFloatField } + + TFloatField = class(TNumericField) + private + FCurrency: Boolean; + FMaxValue : Double; + FMinValue : Double; + FPrecision : Longint; + fonsetvalue: floatfieldsetvalueeventty; + procedure SetCurrency(const AValue: Boolean); + procedure SetPrecision(const AValue: Longint); + protected + function GetAsFloat: Double; override; + function GetAsLongint: Longint; override; + function GetAsVariant: variant; override; + function GetAsString: string; override; + function GetDataSize: Integer; override; + procedure GetText(var theText: string; ADisplayText: Boolean); override; + procedure SetAsFloat(AValue: Double); override; + procedure SetAsLongint(AValue: Longint); override; + procedure SetAsString(const AValue: string); override; + procedure SetVarValue(const AValue: Variant); override; + procedure dosetvalue(const sender: tobject; var avalue: flo64; + var accept: boolean) override; + public + constructor Create(AOwner: TComponent); override; + Function CheckRange(AValue : Double) : Boolean; + property Value: Double read GetAsFloat write SetAsFloat; + + published + property Currency: Boolean read FCurrency write SetCurrency default False; + property MaxValue: Double read FMaxValue write FMaxValue; + property MinValue: Double read FMinValue write FMinValue; + property Precision: Longint read FPrecision write SetPrecision default 15; // min 2 instellen, delphi compat + property onsetvalue: floatfieldsetvalueeventty + read fonsetvalue write fonsetvalue; + end; + +{ TCurrencyField } + + TCurrencyField = class(TFloatField) + public + constructor Create(AOwner: TComponent); override; + published + property Currency default True; + end; + +{ TBooleanField } + + TBooleanField = class(TField) + private + FDisplayValues : String; + // First byte indicates uppercase or not. + FDisplays : Array[Boolean,Boolean] of string; + fonsetvalue: booleanfieldsetvalueeventty; + Procedure SetDisplayValues(const AValue : String); + protected + procedure dosetvalue(const sender: tobject; var avalue: int32; + var accept: boolean) override; + function GetAsBoolean: Boolean; override; + function GetAsString: string; override; + function GetAsVariant: variant; override; + function GetAsInteger: Longint; override; + function GetDataSize: Integer; override; + function GetDefaultWidth: Longint; override; + procedure SetAsBoolean(AValue: Boolean); override; + procedure SetAsString(const AValue: string); override; + procedure SetAsInteger(AValue: Integer); override; + procedure SetVarValue(const AValue: Variant); override; + public + constructor Create(AOwner: TComponent); override; + property Value: Boolean read GetAsBoolean write SetAsBoolean; + published + property DisplayValues: string read FDisplayValues write SetDisplayValues; + property onsetvalue: booleanfieldsetvalueeventty + read fonsetvalue write fonsetvalue; + end; + +{ TDateTimeField } + + TDateTimeField = class(TField) + private + FDisplayFormat : String; + fonsetvalue: datetimefieldsetvalueeventty; + procedure SetDisplayFormat(const AValue: string); + protected + function GetAsDateTime: TDateTime; override; + function getasdate: tdatetime; override; + function getastime: tdatetime; override; + function GetAsFloat: Double; override; + function GetAsString: string; override; + function GetAsVariant: variant; override; + function GetDataSize: Integer; override; + procedure GetText(var theText: string; ADisplayText: Boolean); override; + procedure SetAsDateTime(AValue: TDateTime); override; + procedure setasdate(avalue: tdatetime); override; + procedure setastime(avalue: tdatetime); override; + procedure SetAsFloat(AValue: Double); override; + procedure SetAsString(const AValue: string); override; + procedure SetVarValue(const AValue: Variant); override; + procedure dosetvalue(const sender: tobject; var avalue: flo64; + var accept: boolean) override; + public + constructor Create(AOwner: TComponent); override; + property Value: TDateTime read GetAsDateTime write SetAsDateTime; + published + property DisplayFormat: string read FDisplayFormat write SetDisplayFormat; + property EditMask; + property onsetvalue: datetimefieldsetvalueeventty + read fonsetvalue write fonsetvalue; + end; + +{ TDateField } + + TDateField = class(TDateTimeField) + public + constructor Create(AOwner: TComponent); override; + end; + +{ TTimeField } + + TTimeField = class(TDateTimeField) + protected + procedure SetAsString(const AValue: string); override; + public + constructor Create(AOwner: TComponent); override; + end; + +{ TBinaryField } + + TBinaryField = class(TField) + protected + class procedure CheckTypeSize(AValue: Longint); override; + function GetAsBytes: TBytes; override; + function GetAsString: string; override; + function GetAsVariant: Variant; override; + procedure GetText(var TheText: string; ADisplayText: Boolean); override; + procedure SetAsBytes(const AValue: TBytes); override; + procedure SetAsString(const AValue: string); override; + procedure SetText(const AValue: string); override; + procedure SetVarValue(const AValue: Variant); override; + public + constructor Create(AOwner: TComponent); override; + published + property Size default 16; + end; + +{ TBytesField } + + TBytesField = class(TBinaryField) + protected + function GetDataSize: Integer; override; + public + constructor Create(AOwner: TComponent); override; + end; + +{ TVarBytesField } + + TVarBytesField = class(TBytesField) + protected + function GetDataSize: Integer; override; + public + constructor Create(AOwner: TComponent); override; + end; + +{ TBCDField } + + TBCDField = class(TNumericField) + private + FMinValue, + FMaxValue : currency; + FPrecision : Longint; + FCurrency : boolean; + fonsetvalue: bcdfieldsetvalueeventty; + protected + class procedure CheckTypeSize(AValue: Longint); override; + function GetAsCurrency: Currency; override; + function GetAsFloat: Double; override; + function GetAsLongint: Longint; override; + function GetAsString: string; override; + function GetValue(var AValue: Currency): Boolean; + function GetAsVariant: variant; override; + function GetDataSize: Integer; override; + function GetDefaultWidth: Longint; override; + procedure GetText(var TheText: string; ADisplayText: Boolean); override; + procedure SetAsFloat(AValue: Double); override; + procedure SetAsLongint(AValue: Longint); override; + procedure SetAsString(const AValue: string); override; + procedure SetAsCurrency(AValue: Currency); override; + procedure SetVarValue(const AValue: Variant); override; + procedure dosetvalue(const sender: tobject; var avalue: flo64; + var accept: boolean) override; + public + constructor Create(AOwner: TComponent); override; + Function CheckRange(AValue : Currency) : Boolean; + property Value: Currency read GetAscurrency write SetAscurrency; + published + property Precision: Longint read FPrecision write FPrecision; + property Currency: Boolean read FCurrency write FCurrency; + property MaxValue: Currency read FMaxValue write FMaxValue; + property MinValue: Currency read FMinValue write FMinValue; + property Size default 4; + property onsetvalue: bcdfieldsetvalueeventty + read fonsetvalue write fonsetvalue; + end; + +{ TFMTBCDField } + + TFMTBCDField = class(TNumericField) + private + FMinValue, + FMaxValue : TBCD; + FPrecision : Longint; + FCurrency : boolean; + function GetMaxValue: string; + function GetMinValue: string; + procedure SetMaxValue(const AValue: string); + procedure SetMinValue(const AValue: string); + protected + class procedure CheckTypeSize(AValue: Longint); override; + function GetAsBCD: TBCD; override; + function GetAsCurrency: Currency; override; + function GetAsFloat: Double; override; + function GetAsLongint: Longint; override; + function GetAsString: string; override; + function GetAsVariant: variant; override; + function GetDataSize: Integer; override; + function GetDefaultWidth: Longint; override; + procedure GetText(var TheText: string; ADisplayText: Boolean); override; + procedure SetAsBCD(const AValue: TBCD); override; + procedure SetAsFloat(AValue: Double); override; + procedure SetAsLongint(AValue: Longint); override; + procedure SetAsString(const AValue: string); override; + procedure SetAsCurrency(AValue: Currency); override; + procedure SetVarValue(const AValue: Variant); override; + public + constructor Create(AOwner: TComponent); override; + function CheckRange(AValue : TBCD) : Boolean; + property Value: TBCD read GetAsBCD write SetAsBCD; + published + property Precision: Longint read FPrecision write FPrecision default 15; + property Currency: Boolean read FCurrency write FCurrency; + property MaxValue: string read GetMaxValue write SetMaxValue; + property MinValue: string read GetMinValue write SetMinValue; + property Size default 4; + end; + + +{ TBlobField } + TBlobStreamMode = (bmRead, bmWrite, bmReadWrite); + TBlobType = ftBlob..ftWideMemo; + + TBlobField = class(TField) + private + FBlobType : TBlobType; + FModified : Boolean; + FTransliterate : Boolean; + Function GetBlobStream (Mode : TBlobStreamMode) : TStream; + protected + procedure FreeBuffers; override; + function GetAsString: string; override; + function GetAsVariant: Variant; override; + function GetBlobSize: Longint; virtual; + function GetIsNull: Boolean; override; + procedure GetText(var TheText: string; ADisplayText: Boolean); override; + procedure SetAsString(const AValue: string); override; + procedure SetText(const AValue: string); override; + procedure SetVarValue(const AValue: Variant); override; + function GetAsWideString: WideString; override; + procedure SetAsWideString(const aValue: WideString); override; + public + constructor Create(AOwner: TComponent); override; + procedure Clear; override; + class function IsBlob: Boolean; override; + procedure LoadFromFile(const FileName: string); + procedure LoadFromStream(Stream: TStream); + procedure SaveToFile(const FileName: string); + procedure SaveToStream(Stream: TStream); + procedure SetFieldType(AValue: TFieldType); override; + property BlobSize: Longint read GetBlobSize; + property Modified: Boolean read FModified write FModified; + property Value: string read GetAsString write SetAsString; + property Transliterate: Boolean read FTransliterate write FTransliterate; + published + property BlobType: TBlobType read FBlobType write FBlobType; + property Size default 0; + end; + +{ TMemoField } + + TMemoField = class(TBlobField) + protected + function GetAsWideString: WideString; override; + procedure SetAsWideString(const aValue: WideString); override; + public + constructor Create(AOwner: TComponent); override; + published + property Transliterate default True; + end; + +{ TWideMemoField } + + TWideMemoField = class(TBlobField) + protected + function GetAsVariant: Variant; override; + procedure SetVarValue(const AValue: Variant); override; + + function GetAsString: string; override; + procedure SetAsString(const aValue: string); override; + public + constructor Create(aOwner: TComponent); override; + property Value: WideString read GetAsWideString write SetAsWideString; + published + end; + + +{ TGraphicField } + + TGraphicField = class(TBlobField) + public + constructor Create(AOwner: TComponent); override; + end; + +{ TVariantField } + + TVariantField = class(TField) + protected + class procedure CheckTypeSize(aValue: Integer); override; + + function GetAsBoolean: Boolean; override; + procedure SetAsBoolean(aValue: Boolean); override; + + function GetAsDateTime: TDateTime; override; + procedure SetAsDateTime(aValue: TDateTime); override; + + function GetAsFloat: Double; override; + procedure SetAsFloat(aValue: Double); override; + + function GetAsInteger: Longint; override; + procedure SetAsInteger(aValue: Longint); override; + + function GetAsString: string; override; + procedure SetAsString(const aValue: string); override; + + function GetAsWideString: WideString; override; + procedure SetAsWideString(const aValue: WideString); override; + function getasunicodestring: unicodestring; override; + procedure setasunicodestring(const avalue: unicodestring); override; + + function GetAsVariant: Variant; override; + procedure SetVarValue(const aValue: Variant); override; + + function GetDefaultWidth: Integer; override; + public + constructor Create(AOwner: TComponent); override; + end; + +{ TGuidField } + + TGuidField = class(TStringField) + protected + class procedure CheckTypeSize(AValue: Longint); override; + function GetDefaultWidth: Longint; override; + + function GetAsGuid: TGUID; override; + procedure SetAsGuid(const aValue: TGUID); override; + public + constructor Create(AOwner: TComponent); override; +// property AsGuid: TGUID read GetAsGuid write SetAsGuid; + end; + +{ TIndexDef } + + TIndexDefs = class; + + TIndexOption = (ixPrimary, ixUnique, ixDescending, ixCaseInsensitive, + ixExpression, ixNonMaintained); + TIndexOptions = set of TIndexOption; + + TIndexDef = class(TNamedItem) + Private + FCaseinsFields: string; + FDescFields: string; + FExpression : String; + FFields : String; + FOptions : TIndexOptions; + FSource : String; + protected + function GetExpression: string; + procedure SetCaseInsFields(const AValue: string); virtual; + procedure SetDescFields(const AValue: string); + procedure SetExpression(const AValue: string); + public + constructor Create(Owner: TIndexDefs; const AName, TheFields: string; + TheOptions: TIndexOptions); overload; + procedure Assign(Source: TPersistent); override; + property Expression: string read GetExpression write SetExpression; + property Fields: string read FFields write FFields; + property CaseInsFields: string read FCaseinsFields write SetCaseInsFields; + property DescFields: string read FDescFields write SetDescFields; + property Options: TIndexOptions read FOptions write FOptions; + property Source: string read FSource write FSource; + end; + +{ TIndexDefs } + + TIndexDefs = class(TDefCollection) + Private + Function GetItem(Index: Integer): TIndexDef; + Procedure SetItem(Index: Integer; Value: TIndexDef); + public + constructor Create(ADataSet: TDataSet); overload; virtual; + procedure Add(const Name, Fields: string; Options: TIndexOptions); + Function AddIndexDef: TIndexDef; + function Find(const IndexName: string): TIndexDef; + function FindIndexForFields(const Fields: string): TIndexDef; + function GetIndexForFields(const Fields: string; + CaseInsensitive: Boolean): TIndexDef; + procedure Update; overload; virtual; + Property Items[Index: Integer] : TIndexDef read GetItem write SetItem; default; + end; + +{ TCheckConstraint } + + TCheckConstraint = class(TCollectionItem) + Private + FCustomConstraint : String; + FErrorMessage : String; + FFromDictionary : Boolean; + FImportedConstraint : String; + public + procedure Assign(Source: TPersistent); override; + // function GetDisplayName: string; override; + published + property CustomConstraint: string read FCustomConstraint write FCustomConstraint; + property ErrorMessage: string read FErrorMessage write FErrorMessage; + property FromDictionary: Boolean read FFromDictionary write FFromDictionary; + property ImportedConstraint: string read FImportedConstraint write FImportedConstraint; + end; + +{ TCheckConstraints } + + TCheckConstraints = class(TCollection) + Private + Function GetItem(Index : Longint) : TCheckConstraint; + Procedure SetItem(index : Longint; Value : TCheckConstraint); + protected + function GetOwner: TPersistent; override; + public + constructor Create(AOwner: TPersistent); + function Add: TCheckConstraint; + property Items[Index: Longint]: TCheckConstraint read GetItem write SetItem; default; + end; + + { TFieldsEnumerator } + + TFieldsEnumerator = class + private + FPosition: Integer; + FFields: TFields; + function GetCurrent: TField; + public + constructor Create(AFields: TFields); + function MoveNext: Boolean; + property Current: TField read GetCurrent; + end; + +{ TFields } + + Tfields = Class(TObject) + Private + FDataset : TDataset; + FFieldList : TFpList; + FOnChange : TNotifyEvent; + FValidFieldKinds : TFieldKinds; + Protected + Procedure Changed; + Procedure CheckfieldKind(Fieldkind : TFieldKind; Field : TField); + Function GetCount : Longint; + Function GetField (Index : longint) : TField; + Procedure SetField(Index: Integer; Value: TField); + Procedure SetFieldIndex (Field : TField;Value : Integer); + Property OnChange : TNotifyEvent Read FOnChange Write FOnChange; + Property ValidFieldKinds : TFieldKinds Read FValidFieldKinds; + Public + Constructor Create(ADataset : TDataset); + Destructor Destroy;override; + Procedure Add(Field : TField); + Procedure CheckFieldName (Const Value : String); + Procedure CheckFieldNames (Const Value : String); + Procedure Clear; + Function FindField (Const Value : String) : TField; + Function FieldByName (Const Value : String) : TField; + Function FieldByNumber(FieldNo : Integer) : TField; + Function GetEnumerator: TFieldsEnumerator; + Procedure GetFieldNames (Values : TStrings); + Function IndexOf(Field : TField) : Longint; + procedure Remove(Value : TField); + Property Count : Integer Read GetCount; + Property Dataset : TDataset Read FDataset; + Property Fields [Index : Integer] : TField Read GetField Write SetField; default; + end; + + + { TParam } + + TBlobData = AnsiString; // Delphi defines it as alias to TBytes + + TParamBinding = array of integer; + + TParamType = (ptUnknown, ptInput, ptOutput, ptInputOutput, ptResult); + TParamTypes = set of TParamType; + + TParamStyle = (psInterbase,psPostgreSQL,psSimulated); + blobkindty = (bk_none,bk_binary,bk_text); + TParams = class; + + TParam = class(TCollectionItem) + private + FNativeStr: string; + FValue: Variant; + FPrecision: Integer; + FNumericScale: Integer; + FName: string; + FDataType: TFieldType; + FParamType: TParamType; + FSize: Integer; + fblobkind: blobkindty; + Function GetDataSet: TDataSet; + Function IsParamStored: Boolean; + protected + FBound: Boolean; + Procedure AssignParam(Param: TParam); + Procedure AssignTo(Dest: TPersistent); override; + Function GetAsBoolean: Boolean; + Function GetAsCurrency: Currency; + Function GetAsDateTime: TDateTime; + Function GetAsFloat: Double; + Function GetAsInteger: Longint; + Function GetAsLargeInt: LargeInt; + Function GetAsMemo: string; + Function GetAsString: string; + Function GetAsVariant: Variant; + Function GetAsFMTBCD: TBCD; + Function GetDisplayName: string; override; + Function GetIsNull: Boolean; + Function IsEqual(AValue: TParam): Boolean; + Procedure SetAsBlob(const AValue: TBlobData); + Procedure SetAsBoolean(AValue: Boolean); + Procedure SetAsCurrency(const AValue: Currency); + Procedure SetAsDate(const AValue: TDateTime); + Procedure SetAsDateTime(const AValue: TDateTime); + Procedure SetAsFloat(const AValue: Double); + Procedure SetAsInteger(AValue: Longint); + Procedure SetAsLargeInt(AValue: LargeInt); + Procedure SetAsMemo(const AValue: string); + Procedure SetAsSmallInt(AValue: LongInt); + Procedure SetAsString(const AValue: string); + Procedure SetAsTime(const AValue: TDateTime); + Procedure SetAsVariant(const AValue: Variant); + Procedure SetAsWord(AValue: LongInt); + Procedure SetAsFMTBCD(const AValue: TBCD); + Procedure SetDataType(AValue: TFieldType); + Procedure SetText(const AValue: string); + function GetAsWideString: WideString; + procedure SetAsWideString(const aValue: WideString); + function getasunicodestring: unicodestring; + procedure setasunicodestring(const avalue: unicodestring); + function getasnullmsestring: msestring; + procedure setasnullmsestring(const avalue: msestring); + function getasid: int64; + procedure setasid(const avalue: int64); + public + constructor Create(ACollection: TCollection); overload; override; + constructor Create(AParams: TParams; AParamType: TParamType); reintroduce; overload; + Procedure Assign(Source: TPersistent); override; + Procedure AssignField(Field: TField); + Procedure AssignToField(Field: TField); + Procedure AssignFieldValue(Field: TField; const AValue: Variant); + procedure AssignFromField(Field : TField); + Procedure Clear; + Procedure GetData(Buffer: Pointer); + Function GetDataSize: Integer; + Procedure LoadFromFile(const FileName: string; BlobType: TBlobType); + Procedure LoadFromStream(Stream: TStream; BlobType: TBlobType); + Procedure SetBlobData(Buffer: Pointer; ASize: Integer); + Procedure SetData(Buffer: Pointer); + Property AsBlob : TBlobData read GetAsString write SetAsBlob; + Property AsBoolean : Boolean read GetAsBoolean write SetAsBoolean; + Property AsCurrency : Currency read GetAsCurrency write SetAsCurrency; + Property AsDate : TDateTime read GetAsDateTime write SetAsDate; + Property AsDateTime : TDateTime read GetAsDateTime write SetAsDateTime; + Property AsFloat : Double read GetAsFloat write SetAsFloat; + Property AsInteger : LongInt read GetAsInteger write SetAsInteger; + Property AsLargeInt : LargeInt read GetAsLargeInt write SetAsLargeInt; + Property AsMemo : string read GetAsMemo write SetAsMemo; + Property AsSmallInt : LongInt read GetAsInteger write SetAsSmallInt; + Property AsString : string read GetAsString write SetAsString; + Property AsTime : TDateTime read GetAsDateTime write SetAsTime; + Property AsWord : LongInt read GetAsInteger write SetAsWord; + Property AsFMTBCD: TBCD read GetAsFMTBCD write SetAsFMTBCD; + Property Bound : Boolean read FBound write FBound; + Property Dataset : TDataset Read GetDataset; + Property IsNull : Boolean read GetIsNull; + Property NativeStr : string read FNativeStr write FNativeStr; + Property Text : string read GetAsString write SetText; + Property Value : Variant read GetAsVariant write SetAsVariant stored IsParamStored; + property AsWideString: WideString read GetAsWideString write SetAsWideString; + property asunicodestring: unicodestring read getasunicodestring + write setasunicodestring; + property asmsestring: msestring read getasunicodestring + write setasunicodestring; + property asnullmsestring: msestring read getasnullmsestring + write setasnullmsestring; + //'' -> null + property asid: int64 read getasid write setasid; //-1 -> null + property blobkind: blobkindty read fblobkind + write fblobkind default bk_none; + //for blobid + published + Property DataType : TFieldType read FDataType write SetDataType; + Property Name : string read FName write FName; + Property NumericScale : Integer read FNumericScale write FNumericScale default 0; + Property ParamType : TParamType read FParamType write FParamType; + Property Precision : Integer read FPrecision write FPrecision default 0; + Property Size : Integer read FSize write FSize default 0; + end; + + + { TParams } + + TParams = class(TCollection) + private + FOwner: TPersistent; + Function GetItem(Index: Integer): TParam; + Function GetParamValue(const ParamName: string): Variant; + Procedure SetItem(Index: Integer; Value: TParam); + Procedure SetParamValue(const ParamName: string; const Value: Variant); + protected + Procedure AssignTo(Dest: TPersistent); override; + Function GetDataSet: TDataSet; + Function GetOwner: TPersistent; override; + public + Constructor Create(AOwner: TPersistent); overload; + Constructor Create; overload; + Procedure AddParam(Value: TParam); + Procedure AssignValues(Value: TParams); + Function CreateParam(FldType: TFieldType; const ParamName: string; ParamType: TParamType): TParam; + Function FindParam(const Value: string): TParam; + Procedure GetParamList(List: TList; const ParamNames: string); + Function IsEqual(Value: TParams): Boolean; + Function ParamByName(const Value: string): TParam; + Function ParseSQL(SQL: String; DoCreate: Boolean): String; overload; + Function ParseSQL(SQL: String; DoCreate, EscapeSlash, EscapeRepeat : Boolean; ParameterStyle : TParamStyle): String; overload; + Function ParseSQL(SQL: String; DoCreate, EscapeSlash, EscapeRepeat : Boolean; ParameterStyle : TParamStyle; var ParamBinding: TParambinding): String; overload; + Function ParseSQL(SQL: String; DoCreate, EscapeSlash, EscapeRepeat : Boolean; ParameterStyle : TParamStyle; var ParamBinding: TParambinding; var ReplaceString : string): String; overload; + Procedure RemoveParam(Value: TParam); + Procedure CopyParamValuesFromDataset(ADataset : TDataset; CopyBound : Boolean); + Property Dataset : TDataset Read GetDataset; + Property Items[Index: Integer] : TParam read GetItem write SetItem; default; + Property ParamValues[const ParamName: string] : Variant read GetParamValue write SetParamValue; + end; + +{ TDataSet } + + TBookmark = Pointer; + TBookmarkStr = string; + + PBookmarkFlag = ^TBookmarkFlag; + TBookmarkFlag = (bfCurrent, bfBOF, bfEOF, bfInserted); + +{ These types are used by Delphi/Unicode to replace the ambiguous "pchar" buffer types. + For now, they are just aliases to PAnsiChar, but in Delphi/Unicode it is pbyte. This will + be changed later (2.8?), to allow a grace period for descendents to catch up. + + Testing with TRecordBuffer=PByte will turn up typing problems. TRecordBuffer=pansichar is backwards + compatible, even if overriden with "pchar" variants. +} + TRecordBufferBaseType = AnsiChar; // must match TRecordBuffer. + TRecordBuffer = PAnsiChar; + PBufferList = ^TBufferList; + TBufferList = array[0..dsMaxBufferCount - 1] of TRecordBuffer; // Dynamic array in Delphi. + TBufferArray = ^TRecordBuffer; + bufferaty = array[0..1] of trecordbuffer; + pbufferaty = ^bufferaty; + + TGetMode = (gmCurrent, gmNext, gmPrior); + + TGetResult = (grOK, grBOF, grEOF, grError); + + TResyncMode = set of (rmExact, rmCenter); + + TDataAction = (daFail, daAbort, daRetry); + + TUpdateAction = (uaFail, uaAbort, uaSkip, uaRetry, uaApplied); + + TUpdateKind = (ukModify, ukInsert, ukDelete); + + + TLocateOption = (loCaseInsensitive, loPartialKey); + TLocateOptions = set of TLocateOption; + + TDataOperation = procedure of object; + + TDataSetNotifyEvent = procedure(DataSet: TDataSet) of object; + TDataSetErrorEvent = procedure(DataSet: TDataSet; E: EDatabaseError; + var DataAction: TDataAction) of object; + + TFilterOption = (foCaseInsensitive, foNoPartialCompare); + TFilterOptions = set of TFilterOption; + + TFilterRecordEvent = procedure(DataSet: TDataSet; + var Accept: Boolean) of object; + + TDatasetClass = Class of TDataset; + + +{------------------------------------------------------------------------------} +{IProviderSupport interface} + + TPSCommandType = ( + ctUnknown, + ctQuery, + ctTable, + ctStoredProc, + ctSelect, + ctInsert, + ctUpdate, + ctDelete, + ctDDL + ); + + IProviderSupport = interface + procedure PSEndTransaction(ACommit: Boolean); + procedure PSExecute; + function PSExecuteStatement(const ASQL: string; AParams: TParams; + ResultSet: Pointer = nil): Integer; + procedure PSGetAttributes(List: TList); + function PSGetCommandText: string; + function PSGetCommandType: TPSCommandType; + function PSGetDefaultOrder: TIndexDef; + function PSGetIndexDefs(IndexTypes: TIndexOptions = [ixPrimary..ixNonMaintained]) + : TIndexDefs; + function PSGetKeyFields: string; + function PSGetParams: TParams; + function PSGetQuoteChar: string; + function PSGetTableName: string; + function PSGetUpdateException(E: Exception; Prev: EUpdateError): EUpdateError; + function PSInTransaction: Boolean; + function PSIsSQLBased: Boolean; + function PSIsSQLSupported: Boolean; + procedure PSReset; + procedure PSSetCommandText(const CommandText: string); + procedure PSSetParams(AParams: TParams); + procedure PSStartTransaction; + function PSUpdateRecord(UpdateKind: TUpdateKind; Delta: TDataSet): Boolean; + end; +{------------------------------------------------------------------------------} + + datasetinternalstatety = (dsis_checkingbrowsemode,dsis_refreshing, + dsis_recordcopy); + datasetinternalstatesty = set of datasetinternalstatety; + + TDataSet = class(TComponent) + Private + Procedure DoInsertAppend(DoAppend : Boolean); + Procedure DoInternalOpen; + Function GetBuffer (Index : longint) : TRecordBuffer; + Function GetField (Index : Longint) : TField; + Procedure RegisterDataSource(ADatasource : TDataSource); + Procedure RemoveField (Field : TField); + procedure SetConstraints(Value: TCheckConstraints); + Procedure SetField (Index : Longint;Value : TField); + Procedure ShiftBuffersForward; + Procedure ShiftBuffersBackward; + Function TryDoing (P : TDataOperation; Ev : TDatasetErrorEvent) : Boolean; + Procedure UnRegisterDataSource(ADatasource : TDatasource); + Procedure UpdateFieldDefs; + procedure SetBlockReadSize(AValue: Integer); virtual; + Procedure SetFieldDefs(AFieldDefs: TFieldDefs); + procedure DoInsertAppendRecord(const Values: array of const; DoAppend : boolean); + protected + FOpenAfterRead : boolean; + FActiveRecord: Longint; + FAfterCancel: TDataSetNotifyEvent; + FAfterClose: TDataSetNotifyEvent; + FAfterDelete: TDataSetNotifyEvent; + FAfterEdit: TDataSetNotifyEvent; + FAfterInsert: TDataSetNotifyEvent; + FAfterOpen: TDataSetNotifyEvent; + FAfterPost: TDataSetNotifyEvent; + FAfterRefresh: TDataSetNotifyEvent; + FAfterScroll: TDataSetNotifyEvent; + FAutoCalcFields: Boolean; + FBOF: Boolean; + FBeforeCancel: TDataSetNotifyEvent; + FBeforeClose: TDataSetNotifyEvent; + FBeforeDelete: TDataSetNotifyEvent; + FBeforeEdit: TDataSetNotifyEvent; + FBeforeInsert: TDataSetNotifyEvent; + FBeforeOpen: TDataSetNotifyEvent; + FBeforePost: TDataSetNotifyEvent; + FBeforeRefresh: TDataSetNotifyEvent; + FBeforeScroll: TDataSetNotifyEvent; + FBlobFieldCount: Longint; + FBlockReadSize: Integer; + FBookmarkSize: Longint; + FBuffers : TBufferArray; + FBufferCount: Longint; + FCalcBuffer: TRecordBuffer; + FCalcFieldsSize: Longint; + FConstraints: TCheckConstraints; + FDisableControlsCount : Integer; + FDisableControlsState : TDatasetState; + FCurrentRecord: Longint; + FDataSources : TList; + FDefaultFields: Boolean; + FEOF: Boolean; + FEnableControlsEvent : TDataEvent; + FFieldList : TFields; + FFieldDefs: TFieldDefs; + FFilterOptions: TFilterOptions; + FFilterText: string; + FFiltered: Boolean; + FFound: Boolean; + FInternalCalcFields: Boolean; + FModified: Boolean; + FOnCalcFields: TDataSetNotifyEvent; + FOnDeleteError: TDataSetErrorEvent; + FOnEditError: TDataSetErrorEvent; + FOnFilterRecord: TFilterRecordEvent; + FOnNewRecord: TDataSetNotifyEvent; + FOnPostError: TDataSetErrorEvent; + fonmodified: tdatasetnotifyevent; + FRecordCount: Longint; + FIsUniDirectional: Boolean; + FState : TDataSetState; + finternalstate: datasetinternalstatesty; + FInternalOpenComplete: Boolean; + Function GetActive : boolean; + procedure RecalcBufListSize; + procedure ActivateBuffers; virtual; + procedure BindFields(Binding: Boolean); + procedure BlockReadNext; virtual; + function BookmarkAvailable: Boolean; + procedure CalculateFields(Buffer: TRecordBuffer); virtual; + procedure CheckActive; virtual; + procedure CheckInactive; virtual; + procedure CheckBiDirectional; + procedure Loaded; override; + procedure ClearBuffers; virtual; + procedure ClearCalcFields(Buffer: TRecordBuffer); virtual; + procedure CloseBlob(Field: TField); virtual; + procedure CloseCursor; virtual; + procedure CreateFields; virtual; + procedure DataEvent(Event: TDataEvent; Info: Ptrint); virtual; + procedure DestroyFields; virtual; + procedure DoAfterCancel; virtual; + procedure DoAfterClose; virtual; + procedure DoAfterDelete; virtual; + procedure DoAfterEdit; virtual; + procedure DoAfterInsert; virtual; + procedure DoAfterOpen; virtual; + procedure DoAfterPost; virtual; + procedure DoAfterScroll; virtual; + procedure DoAfterRefresh; virtual; + procedure DoBeforeCancel; virtual; + procedure DoBeforeClose; virtual; + procedure DoBeforeDelete; virtual; + procedure DoBeforeEdit; virtual; + procedure DoBeforeInsert; virtual; + procedure DoBeforeOpen; virtual; + procedure DoBeforePost; virtual; + procedure DoBeforeScroll; virtual; + procedure DoBeforeRefresh; virtual; + procedure DoOnCalcFields; virtual; + procedure DoOnNewRecord; virtual; + procedure domodified virtual; + function FieldByNumber(FieldNo: Longint): TField; + function FindRecord(Restart, GoForward: Boolean): Boolean; virtual; + procedure FreeFieldBuffers; virtual; + function GetBookmarkStr: TBookmarkStr; virtual; + procedure GetCalcFields(Buffer: TRecordBuffer); virtual; + function GetCanModify: Boolean; virtual; + procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override; + function GetFieldClass(FieldType: TFieldType): TFieldClass; virtual; + Function GetfieldCount : Integer; + function GetFieldValues(const fieldname : string) : Variant; virtual; + function GetIsIndexField(Field: TField): Boolean; virtual; + function GetIndexDefs(IndexDefs : TIndexDefs; IndexTypes : TIndexOptions) : TIndexDefs; + function GetNextRecords: Longint; virtual; + function GetNextRecord: Boolean; virtual; + function GetPriorRecords: Longint; virtual; + function GetPriorRecord: Boolean; virtual; + function GetRecordCount: Longint; virtual; + function GetRecNo: Longint; virtual; + procedure InitFieldDefs; virtual; + procedure InitFieldDefsFromfields; + procedure InitRecord(Buffer: TRecordBuffer); virtual; + procedure InternalCancel; virtual; + procedure InternalEdit; virtual; + procedure InternalInsert; virtual; + procedure InternalRefresh; virtual; + procedure OpenCursor(InfoQuery: Boolean); virtual; + procedure OpenCursorcomplete; virtual; + procedure RefreshInternalCalcFields(Buffer: TRecordBuffer); virtual; + procedure RestoreState(const Value: TDataSetState); + procedure sortdatasources(); + Procedure SetActive (Value : Boolean); virtual; + procedure SetBookmarkStr(const Value: TBookmarkStr); virtual; + procedure SetBufListSize(Value: Longint); virtual; + procedure SetChildOrder(Component: TComponent; Order: Longint); override; + procedure SetCurrentRecord(Index: Longint); virtual; + procedure SetDefaultFields(const Value: Boolean); + procedure SetFiltered(Value: Boolean); virtual; + procedure SetFilterOptions(Value: TFilterOptions); virtual; + procedure SetFilterText(const Value: string); virtual; + procedure SetFieldValues(const fieldname: string; Value: Variant); virtual; + procedure SetFound(const Value: Boolean); virtual; + procedure SetModified(Value: Boolean); + procedure SetName(const Value: TComponentName); override; + procedure SetOnFilterRecord(const Value: TFilterRecordEvent); virtual; + procedure SetRecNo(Value: Longint); virtual; + procedure SetState(Value: TDataSetState); + function SetTempState(const Value: TDataSetState): TDataSetState; + Function Tempbuffer: TRecordBuffer; + procedure UpdateIndexDefs; virtual; + property ActiveRecord: Longint read FActiveRecord; + property CurrentRecord: Longint read FCurrentRecord; + property BlobFieldCount: Longint read FBlobFieldCount; + property BookmarkSize: Longint read FBookmarkSize write FBookmarkSize; + property Buffers[Index: Longint]: TRecordBuffer read GetBuffer; + property BufferCount: Longint read FBufferCount; + property CalcBuffer: TRecordBuffer read FCalcBuffer; + property CalcFieldsSize: Longint read FCalcFieldsSize; + property InternalCalcFields: Boolean read FInternalCalcFields; + property Constraints: TCheckConstraints read FConstraints write SetConstraints; + function AllocRecordBuffer: TRecordBuffer; virtual; + procedure FreeRecordBuffer(var Buffer: TRecordBuffer); virtual; + procedure GetBookmarkData(Buffer: TRecordBuffer; Data: Pointer); virtual; + function GetBookmarkFlag(Buffer: TRecordBuffer): TBookmarkFlag; virtual; + function GetDataSource: TDataSource; virtual; + function GetRecordSize: Word; virtual; + procedure InternalAddRecord(Buffer: Pointer; AAppend: Boolean); virtual; + procedure InternalDelete; virtual; + procedure InternalFirst; virtual; + procedure InternalGotoBookmark(ABookmark: Pointer); virtual; + procedure InternalHandleException; virtual; + procedure InternalInitRecord(Buffer: TRecordBuffer); virtual; + procedure InternalLast; virtual; + procedure InternalPost; virtual; + procedure InternalSetToRecord(Buffer: TRecordBuffer); virtual; + procedure SetBookmarkFlag(Buffer: TRecordBuffer; Value: TBookmarkFlag); virtual; + procedure SetBookmarkData(Buffer: TRecordBuffer; Data: Pointer); virtual; + procedure SetUniDirectional(const Value: Boolean); + protected { abstract methods } + function GetRecord(Buffer: TRecordBuffer; GetMode: TGetMode; DoCheck: Boolean): TGetResult; virtual; abstract; + procedure InternalClose; virtual; abstract; + procedure InternalOpen; virtual; abstract; + procedure InternalInitFieldDefs; virtual; abstract; + function IsCursorOpen: Boolean; virtual; abstract; + protected { IProviderSupport methods } + procedure PSEndTransaction(Commit: Boolean); virtual; + procedure PSExecute; virtual; + function PSExecuteStatement(const ASQL: string; AParams: TParams; + ResultSet: Pointer = nil): Integer; virtual; + procedure PSGetAttributes(List: TList); virtual; + function PSGetCommandText: string; virtual; + function PSGetCommandType: TPSCommandType; virtual; + function PSGetDefaultOrder: TIndexDef; virtual; + function PSGetIndexDefs(IndexTypes: TIndexOptions = [ixPrimary..ixNonMaintained]) + : TIndexDefs; virtual; + function PSGetKeyFields: string; virtual; + function PSGetParams: TParams; virtual; + function PSGetQuoteChar: string; virtual; + function PSGetTableName: string; virtual; + function PSGetUpdateException(E: Exception; Prev: EUpdateError) + : EUpdateError; virtual; + function PSInTransaction: Boolean; virtual; + function PSIsSQLBased: Boolean; virtual; + function PSIsSQLSupported: Boolean; virtual; + procedure PSReset; virtual; + procedure PSSetCommandText(const CommandText: string); virtual; + procedure PSSetParams(AParams: TParams); virtual; + procedure PSStartTransaction; virtual; + function PSUpdateRecord(UpdateKind: TUpdateKind; Delta: TDataSet) + : Boolean; virtual; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + function ActiveBuffer: TRecordBuffer; + function GetFieldData(Field: TField; Buffer: Pointer): Boolean; overload; virtual; + function GetFieldData(Field: TField; Buffer: Pointer; NativeFormat: Boolean): Boolean; overload; virtual; + procedure SetFieldData(Field: TField; Buffer: Pointer); overload; virtual; + procedure SetFieldData(Field: TField; Buffer: Pointer; NativeFormat: Boolean); overload; virtual; + procedure Append; + procedure AppendRecord(const Values: array of const); + function BookmarkValid(ABookmark: TBookmark): Boolean; virtual; + procedure Cancel; virtual; + procedure CheckBrowseMode; + procedure ClearFields; + procedure Close; + function ControlsDisabled: Boolean; + function CompareBookmarks(Bookmark1, Bookmark2: TBookmark): Longint; virtual; + function CreateBlobStream(Field: TField; Mode: TBlobStreamMode): TStream; virtual; + procedure CursorPosChanged; + procedure DataConvert(aField: TField; aSource, aDest: Pointer; aToNative: Boolean); virtual; + procedure Delete; virtual; + procedure DisableControls; + procedure Edit; + procedure EnableControls; virtual; + function FieldByName(const FieldName: string): TField; + function FindField(const FieldName: string): TField; + function FindFirst: Boolean; virtual; + function FindLast: Boolean; virtual; + function FindNext: Boolean; virtual; + function FindPrior: Boolean; virtual; + procedure First; + procedure FreeBookmark(ABookmark: TBookmark); virtual; + function GetBookmark: TBookmark; virtual; + function GetCurrentRecord(Buffer: TRecordBuffer): Boolean; virtual; + procedure GetFieldList(List: TList; const FieldNames: string); + procedure GetFieldNames(List: TStrings); + procedure GotoBookmark(ABookmark: TBookmark); + procedure Insert; virtual; + procedure InsertRecord(const Values: array of const); + function IsEmpty: Boolean; + function IsLinkedTo(ADataSource: TDataSource): Boolean; + function IsSequenced: Boolean; virtual; + procedure Last; + function Locate(const keyfields: string; const keyvalues: Variant; options: TLocateOptions) : boolean; virtual; + function Lookup(const KeyFields: string; const KeyValues: Variant; const ResultFields: string): Variant; virtual; + function MoveBy(Distance: Longint): Longint; + procedure Next; + procedure Open; + procedure Post; virtual; + procedure Prior; + procedure Refresh; + function refreshing: boolean; + procedure Resync(Mode: TResyncMode); virtual; + procedure SetFields(const Values: array of const); + function Translate(Src, Dest: PChar; ToOem: Boolean): Integer; virtual; + procedure UpdateCursorPos; + procedure UpdateRecord; virtual; + function UpdateStatus: TUpdateStatus; virtual; + property BlockReadSize: Integer read FBlockReadSize write SetBlockReadSize; + property BOF: Boolean read FBOF; + property Bookmark: TBookmarkStr read GetBookmarkStr write SetBookmarkStr; + property CanModify: Boolean read GetCanModify; + property DataSource: TDataSource read GetDataSource; + property DefaultFields: Boolean read FDefaultFields; + property EOF: Boolean read FEOF; + property FieldCount: Longint read GetFieldCount; + property FieldDefs: TFieldDefs read FFieldDefs write SetFieldDefs; +// property Fields[Index: Longint]: TField read GetField write SetField; + property Found: Boolean read FFound; + property Modified: Boolean read FModified; + procedure modify(const callmodified: boolean = true); //set modified flag + procedure resetmodified(); //clears modified flag + property IsUniDirectional: Boolean read FIsUniDirectional default False; + property RecordCount: Longint read GetRecordCount; + property RecNo: Longint read GetRecNo write SetRecNo; + property RecordSize: Word read GetRecordSize; + property State: TDataSetState read FState; + property Fields : TFields read FFieldList; + property FieldValues[const fieldname: string] : Variant read GetFieldValues + write SetFieldValues; default; + property Filter: string read FFilterText write SetFilterText; + property Filtered: Boolean read FFiltered write SetFiltered default False; + property FilterOptions: TFilterOptions read FFilterOptions write SetFilterOptions; + property Active: Boolean read GetActive write SetActive default False; + property AutoCalcFields: Boolean read FAutoCalcFields write FAutoCalcFields default true; + property BeforeOpen: TDataSetNotifyEvent read FBeforeOpen write FBeforeOpen; + property AfterOpen: TDataSetNotifyEvent read FAfterOpen write FAfterOpen; + property BeforeClose: TDataSetNotifyEvent read FBeforeClose write FBeforeClose; + property AfterClose: TDataSetNotifyEvent read FAfterClose write FAfterClose; + property BeforeInsert: TDataSetNotifyEvent read FBeforeInsert write FBeforeInsert; + property AfterInsert: TDataSetNotifyEvent read FAfterInsert write FAfterInsert; + property BeforeEdit: TDataSetNotifyEvent read FBeforeEdit write FBeforeEdit; + property AfterEdit: TDataSetNotifyEvent read FAfterEdit write FAfterEdit; + property BeforePost: TDataSetNotifyEvent read FBeforePost write FBeforePost; + property AfterPost: TDataSetNotifyEvent read FAfterPost write FAfterPost; + property BeforeCancel: TDataSetNotifyEvent read FBeforeCancel write FBeforeCancel; + property AfterCancel: TDataSetNotifyEvent read FAfterCancel write FAfterCancel; + property BeforeDelete: TDataSetNotifyEvent read FBeforeDelete write FBeforeDelete; + property AfterDelete: TDataSetNotifyEvent read FAfterDelete write FAfterDelete; + property BeforeScroll: TDataSetNotifyEvent read FBeforeScroll write FBeforeScroll; + property AfterScroll: TDataSetNotifyEvent read FAfterScroll write FAfterScroll; + property BeforeRefresh: TDataSetNotifyEvent read FBeforeRefresh write FBeforeRefresh; + property AfterRefresh: TDataSetNotifyEvent read FAfterRefresh write FAfterRefresh; + property OnCalcFields: TDataSetNotifyEvent read FOnCalcFields write FOnCalcFields; + property OnDeleteError: TDataSetErrorEvent read FOnDeleteError write FOnDeleteError; + property OnEditError: TDataSetErrorEvent read FOnEditError write FOnEditError; + property OnFilterRecord: TFilterRecordEvent read FOnFilterRecord write SetOnFilterRecord; + property OnNewRecord: TDataSetNotifyEvent read FOnNewRecord write FOnNewRecord; + property OnPostError: TDataSetErrorEvent read FOnPostError write FOnPostError; + property onmodified: tdatasetnotifyevent read fonmodified write fonmodified; + end; + + TDataLink = class(TPersistent) + private + FFirstRecord, + FBufferCount : Integer; + FActive, + FDataSourceFixed, + FEditing, + FReadOnly, + FUpdatingRecord, + FVisualControl : Boolean; + FDataSource : TDataSource; + Function CalcFirstRecord(Index : Integer) : Integer; + Procedure CalcRange; + Procedure CheckActiveAndEditing; + Function GetDataset : TDataset; + procedure SetActive(AActive: Boolean); + procedure SetDataSource(Value: TDataSource); + Procedure SetReadOnly(Value : Boolean); + function getreadonly: Boolean; + function getactive: Boolean; + protected + function datasourcereadonly(): boolean virtual; + procedure updateactive(); + procedure ActiveChanged; virtual; + procedure CheckBrowseMode; virtual; + procedure DataEvent(Event: TDataEvent; Info: Ptrint); virtual; + procedure DataSetChanged; virtual; + procedure DataSetScrolled(Distance: Integer); virtual; + procedure EditingChanged; virtual; + procedure FocusControl(Field: TFieldRef); virtual; + function GetActiveRecord: Integer; virtual; + function GetBOF: Boolean; virtual; + function GetBufferCount: Integer; virtual; + function GetEOF: Boolean; virtual; + function GetRecordCount: Integer; virtual; + procedure LayoutChanged; virtual; + function MoveBy(Distance: Integer): Integer; virtual; + procedure RecordChanged(Field: TField); virtual; + procedure SetActiveRecord(Value: Integer); virtual; + procedure SetBufferCount(Value: Integer); virtual; + procedure UpdateData; virtual; + property VisualControl: Boolean read FVisualControl write FVisualControl; + property FirstRecord: Integer read FFirstRecord write FFirstRecord; +// procedure doenter(const aobject: tobject); +// procedure doexit(const aobject: tobject); + public + constructor Create; + destructor Destroy; override; + function Edit: Boolean; + procedure UpdateRecord; + function ExecuteAction(Action: TBasicAction): Boolean; virtual; + function UpdateAction(Action: TBasicAction): Boolean; virtual; + property Active: Boolean read getactive; + property ActiveRecord: Integer read GetActiveRecord write SetActiveRecord; + property BOF: Boolean read GetBOF; + property BufferCount: Integer read GetBufferCount write SetBufferCount; + property DataSet: TDataSet read GetDataSet; + property DataSource: TDataSource read FDataSource write SetDataSource; + property DataSourceFixed: Boolean read FDataSourceFixed write FDataSourceFixed; + property Editing: Boolean read FEditing; + property Eof: Boolean read GetEOF; + property ReadOnly: Boolean read getreadonly write SetReadOnly; + property RecordCount: Integer read GetRecordCount; + end; + +{ TDetailDataLink } + + TDetailDataLink = class(TDataLink) + protected + function GetDetailDataSet: TDataSet; virtual; + public + property DetailDataSet: TDataSet read GetDetailDataSet; + end; + +{ TMasterDataLink } + + TMasterDataLink = class(TDetailDataLink) + private + FDetailDataSet: TDataSet; + FFieldNames: string; + FFields: TList; + FOnMasterChange: TNotifyEvent; + FOnMasterDisable: TNotifyEvent; + procedure SetFieldNames(const Value: string); + protected + procedure ActiveChanged; override; + procedure CheckBrowseMode; override; + function GetDetailDataSet: TDataSet; override; + procedure LayoutChanged; override; + procedure RecordChanged(Field: TField); override; + Procedure DoMasterDisable; virtual; + Procedure DoMasterChange; virtual; + public + constructor Create(ADataSet: TDataSet);virtual; + destructor Destroy; override; + property FieldNames: string read FFieldNames write SetFieldNames; + property Fields: TList read FFields; + property OnMasterChange: TNotifyEvent read FOnMasterChange write FOnMasterChange; + property OnMasterDisable: TNotifyEvent read FOnMasterDisable write FOnMasterDisable; + end; + +{ TDataSource } + + TDataChangeEvent = procedure(Sender: TObject; Field: TField) of object; + + ifistatechangedeventty = procedure(const sender: tdatasource; + const alink: tdatalink; const aclient: iificlient; + const astate: ifiwidgetstatesty) of object; + + TDataSource = class(TComponent) + private + FDataSet: TDataSet; + FDataLinks: TList; + FEnabled: Boolean; + FAutoEdit: Boolean; + FState: TDataSetState; + FOnStateChange: TNotifyEvent; + FOnDataChange: TDataChangeEvent; + FOnUpdateData: TNotifyEvent; +// fonenter: datasourcelinkobjecteventty; +// fonexit: datasourcelinkobjecteventty; + fonifistatechanged: ifistatechangedeventty; + freadonly: boolean; + fpriority: int32; + fonenabledchange: tnotifyevent; + procedure DistributeEvent(Event: TDataEvent; Info: Ptrint); + procedure RegisterDataLink(DataLink: TDataLink); + Procedure ProcessEvent(Event : TDataEvent; Info : Ptrint); + procedure SetDataSet(ADataSet: TDataSet); + procedure SetEnabled(Value: Boolean); + procedure UnregisterDataLink(DataLink: TDataLink); + procedure setreadonly(const avalue: boolean); + function getactive: boolean; + protected + function caneventdistribute: boolean; + Procedure DoDataChange (Info : Pointer);virtual; + Procedure DoStateChange; virtual; + procedure doenabledchange; virtual; + Procedure DoUpdateData; + property DataLinks: TList read FDataLinks; + procedure ifistatechanged(const sender: tdatalink; + const aclient: iificlient; + const astate: ifiwidgetstatesty); virtual; +// procedure doenter(const alink: tdatalink; const aobject: tobject); +// procedure doexit(const alink: tdatalink; const aobject: tobject); + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + procedure Edit; + procedure updaterecord(); + function IsLinkedTo(ADataSet: TDataSet): Boolean; + property State: TDataSetState read FState; + property active: boolean read getactive; + published + property AutoEdit: Boolean read FAutoEdit write FAutoEdit default True; + property DataSet: TDataSet read FDataSet write SetDataSet; + property Enabled: Boolean read FEnabled write SetEnabled default True; + property readonly: boolean read freadonly write setreadonly default false; + property priority: int32 read fpriority write fpriority default 0; + //highest priority handled first by dataset + property OnStateChange: TNotifyEvent read FOnStateChange + write FOnStateChange; + property onenabledchange: tnotifyevent read fonenabledchange + write fonenabledchange; + property OnDataChange: TDataChangeEvent read FOnDataChange + write FOnDataChange; + property OnUpdateData: TNotifyEvent read FOnUpdateData write FOnUpdateData; + property onifistatechanged: ifistatechangedeventty + read fonifistatechanged write fonifistatechanged; +// property onenter: datasourcelinkobjecteventty read fonenter write fonenter; +// property onexit: datasourcelinkobjecteventty read fonexit write fonexit; + end; + + { TDBDataset } + + TDBDatasetClass = Class of TDBDataset; + TDBDataset = Class(TDataset) + Private + FDatabase : TDatabase; + FTransaction : TDBTransaction; + Protected + Procedure SetDatabase (Value : TDatabase); virtual; + Procedure SetTransaction(Value : TDBTransaction); virtual; + Procedure CheckDatabase; + Public + Destructor destroy; override; + Property DataBase : TDatabase Read FDatabase Write SetDatabase; + Property Transaction : TDBTransaction Read FTransaction Write SetTransaction; + end; + + { TDBTransaction } + + TDBTransactionClass = Class of TDBTransaction; + TDBTransaction = Class(TComponent) + Private + FActive : boolean; + FDatabase : TDatabase; + FDataSets : TList; + FOpenAfterRead : boolean; + Function GetDataSetCount : Longint; + Function GetDataset(Index : longint) : TDBDataset; + procedure RegisterDataset (DS : TDBDataset); + procedure UnRegisterDataset (DS : TDBDataset); + procedure RemoveDataSets; + procedure SetActive(Value : boolean); + Protected + Procedure SetDatabase (Value : TDatabase); virtual; + procedure CloseTrans; + procedure openTrans; + Procedure CheckDatabase; + Procedure CheckActive; + Procedure CheckInactive; + procedure EndTransaction; virtual; abstract; + procedure StartTransaction; virtual; abstract; + procedure InternalHandleException; virtual; + procedure Loaded; override; + Public + constructor Create(AOwner: TComponent); override; + Destructor destroy; override; + procedure CloseDataSets; + Property DataBase : TDatabase Read FDatabase Write SetDatabase; + published + property Active : boolean read FActive write setactive; + end; + + { TCustomConnection } + + TLoginEvent = procedure(Sender: TObject; Username, Password: string) of object; + + TCustomConnection = class(TComponent) + private + FAfterConnect: TNotifyEvent; + FAfterDisconnect: TNotifyEvent; + FBeforeConnect: TNotifyEvent; + FBeforeDisconnect: TNotifyEvent; + FLoginPrompt: Boolean; + FOnLogin: TLoginEvent; + FStreamedConnected: Boolean; + procedure SetAfterConnect(const AValue: TNotifyEvent); + procedure SetAfterDisconnect(const AValue: TNotifyEvent); + procedure SetBeforeConnect(const AValue: TNotifyEvent); + procedure SetBeforeDisconnect(const AValue: TNotifyEvent); + protected + procedure DoConnect; virtual; + procedure DoDisconnect; virtual; + function GetConnected : boolean; virtual; + Function GetDataset(Index : longint) : TDataset; virtual; + Function GetDataSetCount : Longint; virtual; + procedure InternalHandleException; virtual; + procedure Loaded; override; + procedure SetConnected (Value : boolean); virtual; + property Streamedconnected: Boolean read FStreamedConnected write FStreamedConnected; + public + procedure Close; + destructor Destroy; override; + procedure Open; + property DataSetCount: Longint read GetDataSetCount; + property DataSets[Index: Longint]: TDataSet read GetDataSet; + published + property Connected: Boolean read GetConnected write SetConnected; + property LoginPrompt: Boolean read FLoginPrompt write FLoginPrompt; + + property AfterConnect : TNotifyEvent read FAfterConnect write SetAfterConnect; + property AfterDisconnect : TNotifyEvent read FAfterDisconnect write SetAfterDisconnect; + property BeforeConnect : TNotifyEvent read FBeforeConnect write SetBeforeConnect; + property BeforeDisconnect : TNotifyEvent read FBeforeDisconnect write SetBeforeDisconnect; + property OnLogin: TLoginEvent read FOnLogin write FOnLogin; + end; + + + { TDatabase } + + TDatabaseClass = Class Of TDatabase; + + TDatabase = class(TCustomConnection) + private + FConnected : Boolean; + FDataBaseName : String; + FDataSets : TList; + FTransactions : TList; + FDirectory : String; + FKeepConnection : Boolean; + FParams : TStrings; + FSQLBased : Boolean; + FOpenAfterRead : boolean; + Function GetTransactionCount : Longint; + Function GetTransaction(Index : longint) : TDBTransaction; + procedure RegisterDataset (DS : TDBDataset); + procedure RegisterTransaction (TA : TDBTransaction); + procedure UnRegisterDataset (DS : TDBDataset); + procedure UnRegisterTransaction(TA : TDBTransaction); + procedure RemoveDataSets; + procedure RemoveTransactions; + procedure SetParams(AValue: TStrings); + protected + Procedure CheckConnected; + Procedure CheckDisConnected; + procedure DoConnect; override; + procedure DoDisconnect; override; + function GetConnected : boolean; override; + Function GetDataset(Index : longint) : TDataset; override; + Function GetDataSetCount : Longint; override; + Procedure DoInternalConnect; Virtual;Abstract; + Procedure DoInternalDisConnect; Virtual;Abstract; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + procedure CloseDataSets; + procedure CloseTransactions; +// procedure ApplyUpdates; + procedure StartTransaction; virtual; abstract; + procedure EndTransaction; virtual; abstract; + property TransactionCount: Longint read GetTransactionCount; + property Transactions[Index: Longint]: TDBTransaction read GetTransaction; + property Directory: string read FDirectory write FDirectory; + property IsSQLBased: Boolean read FSQLBased; + published + property Connected: Boolean read FConnected write SetConnected; + property DatabaseName: string read FDatabaseName write FDatabaseName; + property KeepConnection: Boolean read FKeepConnection write FKeepConnection; + property Params : TStrings read FParams Write SetParams; + end; + + + TMasterParamsDataLink = Class(TMasterDataLink) + Private + FParams : TParams; + Procedure SetParams(AVAlue : TParams); + Protected + Procedure DoMasterDisable; override; + Procedure DoMasterChange; override; + Public + constructor Create(ADataSet: TDataSet); override; + Procedure RefreshParamNames; virtual; + Procedure CopyParamsFromMaster(CopyBound : Boolean); virtual; + Property Params : TParams Read FParams Write SetParams; + end; + +const + FieldTypetoVariantMap : array[TFieldType] of Integer = (varError, varOleStr, varSmallint, + varInteger, varSmallint, varBoolean, varDouble, varCurrency, varCurrency, + varDate, varDate, varDate, varOleStr, varOleStr, varInteger, varOleStr, + varOleStr, varOleStr, varOleStr, varOleStr, varOleStr, varOleStr, varError, + varOleStr, varOleStr, varError, varError, varError, varError, varError, + varOleStr, varOleStr, varVariant, varUnknown, varDispatch, varOleStr, + varOleStr, varDouble, varOleStr,varOleStr); + + +Const + Fieldtypenames : Array [TFieldType] of String[15] = + ( + 'Unknown', + 'String', + 'Smallint', + 'Integer', + 'Word', + 'Boolean', + 'Float', + 'Currency', + 'BCD', + 'Date', + 'Time', + 'DateTime', + 'Bytes', + 'VarBytes', + 'AutoInc', + 'Blob', + 'Memo', + 'Graphic', + 'FmtMemo', + 'ParadoxOle', + 'DBaseOle', + 'TypedBinary', + 'Cursor', + 'FixedChar', + 'WideString', + 'Largeint', + 'ADT', + 'Array', + 'Reference', + 'DataSet', + 'OraBlob', + 'OraClob', + 'Variant', + 'Interface', + 'IDispatch', + 'Guid', + 'TimeStamp', + 'FMTBcd', + 'FixedWideChar', + 'WideMemo' + ); + { 'Unknown', + 'String', + 'Smallint', + 'Integer', + 'Word', + 'Boolean', + 'Float', + 'Date', + 'Time', + 'DateTime', + 'Bytes', + 'VarBytes', + 'AutoInc', + 'Blob', + 'Memo', + 'Graphic', + 'FmtMemo', + 'ParadoxOle', + 'DBaseOle', + 'TypedBinary', + 'Cursor' + );} + +const + DefaultFieldClasses : Array [TFieldType] of TFieldClass = + ( { ftUnknown} Tfield, + { ftString} TStringField, + { ftSmallint} TSmallIntField, + { ftInteger} TLongintField, + { ftWord} TWordField, + { ftBoolean} TBooleanField, + { ftFloat} TFloatField, + { ftCurrency} TCurrencyField, + { ftBCD} TBCDField, + { ftDate} TDateField, + { ftTime} TTimeField, + { ftDateTime} TDateTimeField, + { ftBytes} TBytesField, + { ftVarBytes} TVarBytesField, + { ftAutoInc} TAutoIncField, + { ftBlob} TBlobField, + { ftMemo} TMemoField, + { ftGraphic} TGraphicField, + { ftFmtMemo} TBlobField, + { ftParadoxOle} TBlobField, + { ftDBaseOle} TBlobField, + { ftTypedBinary} TBlobField, + { ftCursor} Nil, + { ftFixedChar} TStringField, + { ftWideString} TWideStringField, + { ftLargeint} TLargeIntField, + { ftADT} Nil, + { ftArray} Nil, + { ftReference} Nil, + { ftDataSet} Nil, + { ftOraBlob} TBlobField, + { ftOraClob} TMemoField, + { ftVariant} TVariantField, + { ftInterface} Nil, + { ftIDispatch} Nil, + { ftGuid} TGuidField, + { ftTimeStamp} Nil, + { ftFMTBcd} TFMTBCDField, + { ftFixedWideString} TWideStringField, + { ftWideMemo} TWideMemoField + ); + + dsEditModes = [dsEdit, dsInsert, dsSetKey]; + dsWriteModes = [dsEdit, dsInsert, dsSetKey, dsCalcFields, dsFilter, + dsNewValue, dsInternalCalc]; + +{ Auxiliary functions } + +Procedure DatabaseError (Const Msg : String); overload; +Procedure DatabaseError (Const Msg : String; Comp : TComponent); overload; +Procedure DatabaseErrorFmt (Const Fmt : String; Args : Array Of Const); overload; +Procedure DatabaseErrorFmt (Const Fmt : String; Args : Array Of const; Comp : TComponent); overload; +Function ExtractFieldName(Const Fields: String; var Pos: Integer): String; +Function DateTimeRecToDateTime(DT: TFieldType; Data: TDateTimeRec): TDateTime; +Function DateTimeToDateTimeRec(DT: TFieldType; Data: TDateTime): TDateTimeRec; + +procedure DisposeMem(var Buffer; Size: Integer); +function BuffersEqual(Buf1, Buf2: Pointer; Size: Integer): Boolean; + +function SkipComments(var p: PChar; EscapeSlash, EscapeRepeat : Boolean) : boolean; + +implementation +uses + {$ifdef FPC}dbconst{$else}dbconst_del{$endif},typinfo,msearrayutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +resourcestring + sassigndate = 'Can not assign a date value to field "%s"'; + sassigntime = 'Can not assign a time value to field "%s"'; + +{ --------------------------------------------------------------------- + Auxiliary functions + ---------------------------------------------------------------------} + +Procedure DatabaseError (Const Msg : String); + +begin + Raise EDataBaseError.Create(Msg); +end; + +Procedure DatabaseError (Const Msg : String; Comp : TComponent); + +begin + raise edatabaseerror.create(msg,comp); +end; + +Procedure DatabaseErrorFmt (Const Fmt : String; Args : Array Of Const); + +begin + Raise EDatabaseError.CreateFmt(Fmt,Args); +end; + +Procedure DatabaseErrorFmt (Const Fmt : String; Args : Array Of const; + Comp : TComponent); +begin + if assigned(comp) then + Raise EDatabaseError.CreateFmt(Format('%s : %s',[Comp.Name,Fmt]),Args) + else + DatabaseErrorFmt(Fmt, Args); +end; + +function ExtractFieldName(const Fields: string; var Pos: Integer): string; +var + i: Integer; + FieldsLength: Integer; +begin + i:=Pos; + FieldsLength:=Length(Fields); + while (i<=FieldsLength) and (Fields[i]<>';') do Inc(i); + Result:=Trim(Copy(Fields,Pos,i-Pos)); + if (i<=FieldsLength) and (Fields[i]=';') then Inc(i); + Pos:=i; +end; + +{ EUpdateError } +constructor EUpdateError.Create(NativeError, Context : String; + ErrCode, PrevError : integer; E: Exception); + +begin + Inherited CreateFmt(NativeError,[Context]); + FContext := Context; + FErrorCode := ErrCode; + FPreviousError := PrevError; + FOriginalException := E; +end; + +Destructor EUpdateError.Destroy; + +begin + FOriginalException.Free; + Inherited; +end; + +{ TNamedItem } + +function TNamedItem.GetDisplayName: string; +begin + Result := FName; +end; + +procedure TNamedItem.SetDisplayName(const AValue: string); +Var TmpInd : Integer; +begin + if FName=AValue then exit; + if (AValue <> '') and (Collection is TFieldDefs) then + begin + TmpInd := (TDefCollection(Collection).IndexOf(AValue)); + if (TmpInd >= 0) and (TmpInd <> Index) then + DatabaseErrorFmt(SDuplicateName, [AValue, Collection.ClassName]); + end; + FName:=AValue; + inherited SetDisplayName(AValue); +end; + +{ TDefCollection } + +procedure TDefCollection.SetItemName(AItem: TCollectionItem); +begin + with AItem as TNamedItem do + if Name = '' then + begin + if assigned(Dataset) then + Name := Dataset.Name + Copy(ClassName, 2, 5) + IntToStr(ID+1) + else + Name := Copy(ClassName, 2, 5) + IntToStr(ID+1); + end + else inherited SetItemName(AItem); +end; + +constructor TDefCollection.create(ADataset: TDataset; AOwner: TPersistent; + AClass: TCollectionItemClass); +begin + inherited Create(AOwner,AClass); + FDataset := ADataset; +end; + +function TDefCollection.Find(const AName: string): TNamedItem; +var i: integer; +begin + Result := Nil; + for i := 0 to Count - 1 do if AnsiSameText(TNamedItem(Items[i]).Name, AName) then + begin + Result := TNamedItem(Items[i]); + Break; + end; +end; + +procedure TDefCollection.GetItemNames(List: TStrings); +var i: LongInt; +begin + for i := 0 to Count - 1 do + List.Add(TNamedItem(Items[i]).Name); +end; + +function TDefCollection.IndexOf(const AName: string): Longint; +var i: LongInt; +begin + Result := -1; + for i := 0 to Count - 1 do + if AnsiSameText(TNamedItem(Items[i]).Name, AName) then + begin + Result := i; + Break; + end; +end; + +{ TIndexDef } + +procedure TIndexDef.SetDescFields(const AValue: string); +begin + if FDescFields=AValue then exit; + if AValue <> '' then FOptions:=FOptions + [ixDescending]; + FDescFields:=AValue; +end; + +procedure TIndexDef.Assign(Source: TPersistent); +var idef : TIndexDef; +begin + idef := nil; + if Source is TIndexDef then idef := Source as TIndexDef; + if Assigned(idef) then + begin + FName := idef.Name; + FFields := idef.Fields; + FOptions := idef.Options; + FCaseinsFields := idef.CaseInsFields; + FDescFields := idef.DescFields; + FSource := idef.Source; + FExpression := idef.Expression; + end + else + inherited Assign(Source); +end; + +function TIndexDef.GetExpression: string; +begin + Result := FExpression; +end; + +procedure TIndexDef.SetExpression(const AValue: string); +begin + FExpression := AValue; +end; + +procedure TIndexDef.SetCaseInsFields(const AValue: string); +begin + if FCaseinsFields=AValue then exit; + if AValue <> '' then FOptions:=FOptions + [ixCaseInsensitive]; + FCaseinsFields:=AValue; +end; + +constructor TIndexDef.Create(Owner: TIndexDefs; const AName, TheFields: string; + TheOptions: TIndexOptions); + +begin + FName := aname; + inherited create(Owner); + FFields := TheFields; + FOptions := TheOptions; +end; + + +{ TIndexDefs } + +Function TIndexDefs.GetItem (Index : integer) : TIndexDef; + +begin + Result:=(Inherited GetItem(Index)) as TIndexDef; +end; + +Procedure TIndexDefs.SetItem(Index: Integer; Value: TIndexDef); +begin + Inherited SetItem(Index,Value); +end; + +constructor TIndexDefs.Create(ADataSet: TDataSet); + +begin + inherited create(ADataset, Owner, TIndexDef); +end; + + +Function TIndexDefs.AddIndexDef: TIndexDef; + +begin +// Result := inherited add as TIndexDef; + Result:=TIndexDef.Create(Self,'','',[]); +end; + +procedure TIndexDefs.Add(const Name, Fields: string; Options: TIndexOptions); + +begin + TIndexDef.Create(Self,Name,Fields,Options); +end; + +function TIndexDefs.Find(const IndexName: string): TIndexDef; +begin + Result := (inherited Find(IndexName)) as TIndexDef; + if (Result=Nil) Then + DatabaseErrorFmt(SIndexNotFound, [IndexName], FDataSet); +end; + +function TIndexDefs.FindIndexForFields(const Fields: string): TIndexDef; + +begin + result:= nil; + //!! To be implemented +end; + + +function TIndexDefs.GetIndexForFields(const Fields: string; + CaseInsensitive: Boolean): TIndexDef; + +var + i, FieldsLen: integer; + Last: TIndexDef; +begin + Last := nil; + FieldsLen := Length(Fields); + for i := 0 to Count - 1 do + begin + Result := Items[I]; + if (Result.Options * [ixDescending, ixExpression] = []) and + (not CaseInsensitive or (ixCaseInsensitive in Result.Options)) and + AnsiSameText(Fields, Result.Fields) then + begin + Exit; + end else + if AnsiSameText(Fields, Copy(Result.Fields, 1, FieldsLen)) and + ((Length(Result.Fields) = FieldsLen) or + (Result.Fields[FieldsLen + 1] = ';')) then + begin + if (Last = nil) or + ((Last <> nil) And (Length(Last.Fields) > Length(Result.Fields))) then + Last := Result; + end; + end; + Result := Last; +end; + +procedure TIndexDefs.Update; + +begin + if (not updated) and assigned(Dataset) then + begin + Dataset.UpdateIndexDefs; + updated := True; + end; +end; + +{ TCheckConstraint } + +procedure TCheckConstraint.Assign(Source: TPersistent); + +begin + //!! To be implemented +end; + + + +{ TCheckConstraints } + +Function TCheckConstraints.GetItem(Index : Longint) : TCheckConstraint; + +begin + //!! To be implemented + Result := nil; +end; + + +Procedure TCheckConstraints.SetItem(index : Longint; Value : TCheckConstraint); + +begin + //!! To be implemented +end; + + +function TCheckConstraints.GetOwner: TPersistent; + +begin + //!! To be implemented + Result := nil; +end; + + +constructor TCheckConstraints.Create(AOwner: TPersistent); + +begin + //!! To be implemented + inherited Create(TCheckConstraint); +end; + + +function TCheckConstraints.Add: TCheckConstraint; + +begin + //!! To be implemented + Result := nil; +end; + +{ TLookupList } + +constructor TLookupList.Create; + +begin + FList := TFPList.Create; +end; + +destructor TLookupList.Destroy; + +begin + Clear; + FList.Destroy; + inherited Destroy; +end; + +procedure TLookupList.Add(const AKey, AValue: Variant); + +var LookupRec: PLookupListRec; +begin + New(LookupRec); + LookupRec^.Key := AKey; + LookupRec^.Value := AValue; + FList.Add(LookupRec); +end; + +procedure TLookupList.Clear; +var i: integer; +begin + for i := 0 to FList.Count - 1 do Dispose(PLookupListRec(FList[i])); + FList.Clear; +end; + +function TLookupList.FirstKeyByValue(const AValue: Variant): Variant; +var + i: Integer; +begin + for i := 0 to FList.Count - 1 do + with PLookupListRec(FList[i])^ do + if Value = AValue then + begin + Result := Key; + exit; + end; + Result := Null; +end; + +function TLookupList.ValueOfKey(const AKey: Variant): Variant; + + Function VarArraySameValues(VarArray1,VarArray2 : Variant) : Boolean; + // This only works for one-dimensional vararrays with a lower bound of 0 + // and equal higher bounds wich only contains variants. + // The vararrays returned by GetFieldValues do apply. + var i : integer; + begin + Result := True; + if (VarArrayHighBound(VarArray1,1))<> (VarArrayHighBound(VarArray2,1)) then exit; + for i := 0 to VarArrayHighBound(VarArray1,1) do + begin + if VarArray1[i]<>VarArray2[i] then + begin + Result := false; + Exit; + end; + end; + end; + +var I: Integer; +begin + Result := Null; + if VarIsNull(AKey) then Exit; + i := FList.Count - 1; + if VarIsArray(AKey) then + while (i >= 0) And not VarArraySameValues(PLookupListRec(FList.Items[I])^.Key,AKey) do Dec(i) + else + while (i >= 0) And (PLookupListRec(FList.Items[I])^.Key <> AKey) do Dec(i); + if i >= 0 then Result := PLookupListRec(FList.Items[I])^.Value; +end; + +procedure TLookupList.ValuesToStrings(AStrings: TStrings); +var + i: Integer; + p: PLookupListRec; +begin + AStrings.Clear; + for i := 0 to FList.Count - 1 do + begin + p := PLookupListRec(FList[i]); + AStrings.AddObject(p^.Value, TObject(p)); + end; +end; + +procedure DisposeMem(var Buffer; Size: Integer); +begin + if Pointer(Buffer) <> nil then + begin + FreeMem(Pointer(Buffer), Size); + Pointer(Buffer) := nil; + end; +end; + +function BuffersEqual(Buf1, Buf2: Pointer; Size: Integer): Boolean; + +begin + {$ifdef FPC} + Result:= CompareByte(Buf1,Buf2,Size) = 0; + {$else} + Result:= Comparemem(Buf1,Buf2,Size); + {$endif} +end; + +{ --------------------------------------------------------------------- + TDataSet + ---------------------------------------------------------------------} + +Const + DefaultBufferCount = 10; + +constructor TDataSet.Create(AOwner: TComponent); + +begin + Inherited Create(AOwner); + FFieldDefs:=TFieldDefs.Create(Self); + FFieldList:=TFields.Create(Self); + FDataSources:=TList.Create; + FConstraints:=TCheckConstraints.Create(Self); + +// FBuffer must be allocated on create, to make Activebuffer return nil + ReAllocMem(FBuffers,SizeOf(TRecordBuffer)); +// pointer(FBuffers^) := nil; + pbufferaty(FBuffers)^[0] := nil; + FActiveRecord := 0; + FBufferCount := -1; + FEOF := True; + FBOF := True; + FIsUniDirectional := False; + FAutoCalcFields := True; +end; + + + +destructor TDataSet.Destroy; + +var + i: Integer; + +begin + Active:=False; + FFieldDefs.Free; + FFieldList.Free; + With FDatasources do + begin + While Count>0 do + TDatasource(Items[Count - 1]).DataSet:=Nil; + Free; + end; + for i := 0 to FBufferCount do + FreeRecordBuffer(pbufferaty(FBuffers)^[i]); + FConstraints.Free; + FreeMem(FBuffers); + Inherited Destroy; +end; + +// This procedure must be called when the first record is made/read +Procedure TDataset.ActivateBuffers; + +begin + FBOF:=False; + FEOF:=False; + FActiveRecord:=0; +end; + +Procedure TDataset.UpdateFieldDefs; + +begin + //!! To be implemented +end; + +Procedure TDataset.BindFields(Binding: Boolean); + +var i, FieldIndex: Integer; + FieldDef: TFieldDef; +begin + { FieldNo is set to -1 for calculated/lookup fields, to 0 for unbound field + and for bound fields it is set to FieldDef.FieldNo } + FCalcFieldsSize := 0; + FBlobFieldCount := 0; + for i := 0 to Fields.Count - 1 do + with Fields[i] do begin + if Binding then begin + if FieldKind in [fkCalculated, fkLookup] then begin + FFieldNo := -1; + FOffset := FCalcFieldsSize; + Inc(FCalcFieldsSize, DataSize + 1); + if FieldKind in [fkLookup] then begin + if ((FLookupDataSet = nil) or (FLookupKeyFields = '') or + (FLookupResultField = '') or (FKeyFields = '')) then + DatabaseErrorFmt(SLookupInfoError, [DisplayName]); + FFields.CheckFieldNames(FKeyFields); + FLookupDataSet.Open; + FLookupDataSet.Fields.CheckFieldNames(FLookupKeyFields); + FLookupDataSet.FieldByName(FLookupResultField); + if FLookupCache then RefreshLookupList; + end + end else begin + FieldDef := nil; + FieldIndex := FieldDefs.IndexOf(Fields[i].FieldName); + if FieldIndex <> -1 then begin + FieldDef := FieldDefs[FieldIndex]; + FFieldNo := FieldDef.FieldNo; + if FieldDef.InternalCalcField then FInternalCalcFields := True; + if IsBlob then begin + FSize := FieldDef.Size; + FOffset := FBlobFieldCount; + Inc(FBlobFieldCount); + end; + end else FFieldNo := 0; + end; + end else FFieldNo := 0; + end; +end; + +Function TDataset.BookmarkAvailable: Boolean; + +Const BookmarkStates = [dsBrowse,dsEdit,dsInsert]; + +begin + Result:=(Not IsEmpty) and not FIsUniDirectional and (State in BookmarkStates) + and (getBookMarkFlag(ActiveBuffer)=bfCurrent); +end; + +Procedure TDataset.CalculateFields(Buffer: TRecordBuffer); +var + i: Integer; + OldState: TDatasetState; +begin + FCalcBuffer := Buffer; + if not IsUniDirectional and (FState <> dsInternalCalc) then + begin + OldState := FState; + FState := dsCalcFields; + try + ClearCalcFields(FCalcBuffer); + for i := 0 to FFieldList.Count - 1 do + if FFieldList[i].FieldKind = fkLookup then + FFieldList[i].CalcLookupValue; + finally + DoOnCalcFields; + FState := OldState; + end; + end; +end; + +Procedure TDataset.CheckActive; + +begin + If Not Active then + DataBaseError(SInactiveDataset); +end; + +Procedure TDataset.CheckInactive; + +begin + If Active then + DataBaseError(SActiveDataset); +end; + +Procedure TDataset.ClearBuffers; + +begin + FRecordCount:=0; + FactiveRecord:=0; + FCurrentRecord:=-1; + FBOF:=True; + FEOF:=True; +end; + +Procedure TDataset.ClearCalcFields(Buffer: TRecordBuffer); + +begin + // Empty +end; + +Procedure TDataset.CloseBlob(Field: TField); + +begin + //!! To be implemented +end; + +Procedure TDataset.CloseCursor; + +begin + FreeFieldBuffers; + ClearBuffers; + SetBufListSize(0); + InternalClose; + FInternalOpenComplete := False; +end; + +Procedure TDataset.CreateFields; + +Var I : longint; + +begin +{$ifdef DSDebug} + Writeln ('Creating fields'); + Writeln ('Count : ',fielddefs.Count); + For I:=0 to FieldDefs.Count-1 do + Writeln('Def ',I,' : ',Fielddefs.items[i].Name,'(',Fielddefs.items[i].FieldNo,')'); +{$endif} + For I:=0 to fielddefs.Count-1 do + With Fielddefs.Items[I] do + If DataType<>ftUnknown then + begin + {$ifdef DSDebug} + Writeln('About to create field',FieldDefs.Items[i].Name); + {$endif} + CreateField(self); + end; +end; + +Procedure TDataset.DataEvent(Event: TDataEvent; Info: Ptrint); + + procedure HandleFieldChange(aField: TField); + begin + if aField.FieldKind in [fkData, fkInternalCalc] then + SetModified(True); + + if State <> dsSetKey then begin + if aField.FieldKind = fkData then begin + if FInternalCalcFields then + RefreshInternalCalcFields(ActiveBuffer) + else if FAutoCalcFields and (FCalcFieldsSize <> 0) then + CalculateFields(ActiveBuffer); + end; + + aField.Change; + end; + end; + + procedure HandleScrollOrChange; + begin + if State <> dsInsert then + UpdateCursorPos; + end; + +var + i: Integer; +begin + case Event of + deFieldChange : HandleFieldChange(TField(Info)); + deDataSetChange, + deDataSetScroll : HandleScrollOrChange; + deLayoutChange : FEnableControlsEvent:=deLayoutChange; + end; + if not ControlsDisabled and (FState <> dsBlockRead) then begin + for i := 0 to FDataSources.Count - 1 do + TDataSource(FDataSources[i]).ProcessEvent(Event, Info); + end; +end; + +Procedure TDataset.DestroyFields; + +begin + FFieldList.Clear; +end; + +Procedure TDataset.DoAfterCancel; + +begin + If assigned(FAfterCancel) then + FAfterCancel(Self); +end; + +Procedure TDataset.DoAfterClose; + +begin + If assigned(FAfterClose) and not (csDestroying in ComponentState) then + FAfterClose(Self); +end; + +Procedure TDataset.DoAfterDelete; + +begin + If assigned(FAfterDelete) then + FAfterDelete(Self); +end; + +Procedure TDataset.DoAfterEdit; + +begin + If assigned(FAfterEdit) then + FAfterEdit(Self); +end; + +Procedure TDataset.DoAfterInsert; + +begin + If assigned(FAfterInsert) then + FAfterInsert(Self); +end; + +Procedure TDataset.DoAfterOpen; + +begin + If assigned(FAfterOpen) then + FAfterOpen(Self); +end; + +Procedure TDataset.DoAfterPost; + +begin + If assigned(FAfterPost) then + FAfterPost(Self); +end; + +Procedure TDataset.DoAfterScroll; + +begin + If assigned(FAfterScroll) then + FAfterScroll(Self); +end; + +Procedure TDataset.DoAfterRefresh; + +begin + If assigned(FAfterRefresh) then + FAfterRefresh(Self); +end; + +Procedure TDataset.DoBeforeCancel; + +begin + If assigned(FBeforeCancel) then + FBeforeCancel(Self); +end; + +Procedure TDataset.DoBeforeClose; + +begin + If assigned(FBeforeClose) and not (csDestroying in ComponentState) then + FBeforeClose(Self); +end; + +Procedure TDataset.DoBeforeDelete; + +begin + If assigned(FBeforeDelete) then + FBeforeDelete(Self); +end; + +Procedure TDataset.DoBeforeEdit; + +begin + If assigned(FBeforeEdit) then + FBeforeEdit(Self); +end; + +Procedure TDataset.DoBeforeInsert; + +begin + If assigned(FBeforeInsert) then + FBeforeInsert(Self); +end; + +Procedure TDataset.DoBeforeOpen; + +begin + If assigned(FBeforeOpen) then + FBeforeOpen(Self); +end; + +Procedure TDataset.DoBeforePost; + +begin + If assigned(FBeforePost) then + FBeforePost(Self); +end; + +Procedure TDataset.DoBeforeScroll; + +begin + If assigned(FBeforeScroll) then + FBeforeScroll(Self); +end; + +Procedure TDataset.DoBeforeRefresh; + +begin + If assigned(FBeforeRefresh) then + FBeforeRefresh(Self); +end; + +Procedure TDataset.DoInternalOpen; + +begin + InternalOpen; + FInternalOpenComplete := True; +{$ifdef dsdebug} + Writeln ('Calling internal open'); +{$endif} +{$ifdef dsdebug} + Writeln ('Calling RecalcBufListSize'); +{$endif} + FRecordcount := 0; + RecalcBufListSize; + FBOF:=True; + FEOF := (FRecordcount = 0); +end; + +Procedure TDataset.DoOnCalcFields; + +begin + If Assigned(FOnCalcfields) then + FOnCalcFields(Self); +end; + +Procedure TDataset.DoOnNewRecord; +var + int1: integer; + po1: ppointer; +begin + po1:= pointer(fields.ffieldlist.list); + for int1:= 0 to fields.count -1 do begin + with tfield(po1^) do begin + if dsis_recordcopy in finternalstate then begin + if of_initcopy in foptionsfield then begin + asstring:= defaultexpression; + end; + end + else begin + if of_initinsert in foptionsfield then begin + asstring:= defaultexpression; + end; + end; + end; + inc(po1); + end; + If assigned(FOnNewRecord) then + FOnNewRecord(Self); +end; + +procedure TDataSet.domodified; +begin + if assigned(fonmodified) then begin + fonmodified(self); + end; +end; + +Function TDataset.FieldByNumber(FieldNo: Longint): TField; + +begin + Result:=FFieldList.FieldByNumber(FieldNo); +end; + +Function TDataset.FindRecord(Restart, GoForward: Boolean): Boolean; + +begin + result:= false; + //!! To be implemented +end; + +Procedure TDataset.FreeFieldBuffers; + +Var I : longint; + +begin + For I:=0 to FFieldList.Count-1 do + FFieldList[i].FreeBuffers; +end; + +Function TDataset.GetBookmarkStr: TBookmarkStr; + +begin + Result:=''; + If BookMarkAvailable then + begin + SetLength(Result,FBookMarkSize); + GetBookMarkData(ActiveBuffer,Pointer(Result)); + end +end; + +Function TDataset.GetBuffer (Index : longint) : TRecordBuffer; + +begin + Result:= pbufferaty(FBuffers)^[Index]; +end; + +Procedure TDataset.GetCalcFields(Buffer: TRecordBuffer); + +begin + if (FCalcFieldsSize > 0) or FInternalCalcFields then + CalculateFields(Buffer); +end; + +Function TDataset.GetCanModify: Boolean; + +begin + Result:= not FIsUnidirectional; +end; + +Procedure TDataset.GetChildren(Proc: TGetChildProc; Root: TComponent); + +var + I: Integer; + Field: TField; + +begin + for I := 0 to Fields.Count - 1 do begin + Field := Fields[I]; + if (Field.Owner = Root) then + Proc(Field); + end; +end; + +Function TDataset.GetDataSource: TDataSource; +begin + Result:=nil; +end; + +function TDataSet.GetRecordSize: Word; +begin + Result := 0; +end; + +procedure TDataSet.InternalAddRecord(Buffer: Pointer; AAppend: Boolean); +begin + // empty stub +end; + +procedure TDataSet.InternalDelete; +begin + // empty stub +end; + +procedure TDataSet.InternalFirst; +begin + // empty stub +end; + +procedure TDataSet.InternalGotoBookmark(ABookmark: Pointer); +begin + // empty stub +end; + +function TDataSet.GetFieldData(Field: TField; Buffer: Pointer): Boolean; + +begin + Result := False; +end; + +procedure TDataSet.DataConvert(aField: TField; aSource, aDest: Pointer; + aToNative: Boolean); + + // There seems to be no WStrCopy defined, this is a copy of + // the generic StrCopy function, adapted for WideChar. + Function WStrCopy(Dest, Source:PWideChar): PWideChar; + var + counter : SizeInt; + Begin + counter := 0; + while Source[counter] <> #0 do + begin +// Dest[counter] := char(Source[counter]); + Dest[counter] := Source[counter]; + Inc(counter); + end; + { terminate the string } + Dest[counter] := #0; + WStrCopy := Dest; + end; + +var + DT : TFieldType; + +begin + DT := aField.DataType; + if aToNative then + begin + case DT of + ftDate, ftTime, ftDateTime: TDateTimeRec(aDest^) := DateTimeToDateTimeRec(DT, TDateTime(aSource^)); + ftTimeStamp : TTimeStamp(aDest^) := TTimeStamp(aSource^); +{$ifdef FPC} + ftBCD : TBCD(aDest^) := CurrToBCD(Currency(aSource^)); +{$else} + ftBCD : CurrToBCD(Currency(aSource^),TBCD(aDest^)); +{$endif} + ftFMTBCD : TBcd(aDest^) := TBcd(aSource^); + // See notes from mantis bug-report 8204 for more information + // ftBytes : ; + // ftVarBytes : ; + ftWideString : WStrCopy(PWideChar(aDest), PWideChar(aSource)); + end + end + else + begin + case DT of + ftDate, ftTime, ftDateTime: TDateTime(aDest^) := DateTimeRecToDateTime(DT, TDateTimeRec(aSource^)); + ftTimeStamp : TTimeStamp(aDest^) := TTimeStamp(aSource^); + ftBCD : BCDToCurr(TBCD(aSource^),Currency(aDest^)); + ftFMTBCD : TBcd(aDest^) := TBcd(aSource^); + // ftBytes : ; + // ftVarBytes : ; + ftWideString : WStrCopy(PWideChar(aDest), PWideChar(aSource)); + end + end +end; + +function TDataSet.GetFieldData(Field: TField; Buffer: Pointer; + NativeFormat: Boolean): Boolean; + +Var + AStatBuffer : Array[0..dsMaxStringSize] of Char; + ADynBuffer : pchar; + +begin + If NativeFormat then + Result:=GetFieldData(Field, Buffer) + else + begin + if Field.DataSize <= dsMaxStringSize then + begin + Result := GetfieldData(Field, @AStatBuffer); + if Result then DataConvert(Field,@AStatBuffer,Buffer,False); + end + else + begin + GetMem(ADynBuffer,Field.DataSize); + try + Result := GetfieldData(Field, ADynBuffer); + if Result then DataConvert(Field,ADynBuffer,Buffer,False); + finally + FreeMem(ADynBuffer); + end; + end; + end; +end; + +Function DateTimeRecToDateTime(DT: TFieldType; Data: TDateTimeRec): TDateTime; + +var + TS: TTimeStamp; + +begin + TS.Date:=0; + TS.Time:=0; + case DT of + ftDate: TS.Date := Data.Date; + ftTime: With TS do + begin + Time := Data.Time; + Date := DateDelta; + end; + else + try + TS:=MSecsToTimeStamp(trunc(Data.DateTime)); + except + end; + end; + Result:=TimeStampToDateTime(TS); +end; + +Function DateTimeToDateTimeRec(DT: TFieldType; Data: TDateTime): TDateTimeRec; + +var + TS : TTimeStamp; + +begin + TS:=DateTimeToTimeStamp(Data); + With Result do + case DT of + ftDate: + Date:=TS.Date; + ftTime: + Time:=TS.Time; + else + DateTime:=TimeStampToMSecs(TS); + end; +end; + +procedure TDataSet.SetFieldData(Field: TField; Buffer: Pointer); + +begin +// empty procedure +end; + +procedure TDataSet.SetFieldData(Field: TField; Buffer: Pointer; + NativeFormat: Boolean); + +Var + AStatBuffer : Array[0..dsMaxStringSize] of Char; + ADynBuffer : pchar; + +begin + if NativeFormat then + SetFieldData(Field, Buffer) + else + begin + if Field.DataSize <= dsMaxStringSize then + begin + DataConvert(Field,Buffer,@AStatBuffer,True); + SetfieldData(Field, @AStatBuffer); + end + else + begin + GetMem(ADynBuffer,Field.DataSize); + try + DataConvert(Field,Buffer,@AStatBuffer,True); + SetfieldData(Field, @AStatBuffer); + finally + FreeMem(ADynBuffer); + end; + end; + end; +end; + +Function TDataset.GetField (Index : Longint) : TField; + +begin + Result:=FFIeldList[index]; +end; + +Function TDataset.GetFieldClass(FieldType: TFieldType): TFieldClass; + +begin + Result := DefaultFieldClasses[FieldType]; +end; + +Function TDataset.GetIsIndexField(Field: TField): Boolean; + +begin + Result:=False; +end; + +function TDataSet.GetIndexDefs(IndexDefs: TIndexDefs; IndexTypes: TIndexOptions + ): TIndexDefs; + +var i,f : integer; + IndexFields : TStrings; + +begin + IndexDefs.Update; + Result := TIndexDefs.Create(Self); + Result.Assign(IndexDefs); + i := 0; + IndexFields := TStringList.Create; + while i < result.Count do + begin + if (not ((IndexTypes = []) and (result[i].Options = []))) and + ((IndexTypes * result[i].Options) = []) then + begin + result.Delete(i); + dec(i); + end + else + begin + ExtractStrings([';'],[' '],pchar(result[i].Fields),Indexfields); + for f := 0 to IndexFields.Count-1 do if FindField(Indexfields[f]) = nil then + begin + result.Delete(i); + dec(i); + break; + end; + end; + inc(i); + end; + IndexFields.Free; +end; + +Function TDataset.GetNextRecord: Boolean; + + procedure ExchangeBuffers(var buf1,buf2 : trecordbuffer); + + var tempbuf : pointer; + + begin + tempbuf := buf1; + buf1 := buf2; + buf2 := tempbuf; + end; + +begin +{$ifdef dsdebug} + Writeln ('Getting next record. Internal RecordCount : ',FRecordCount); +{$endif} + If FRecordCount>0 Then SetCurrentRecord(FRecordCount-1); + Result:=GetRecord(pbufferaty(FBuffers)^[FBuffercount],gmNext,True)=grOK; + + if result then + begin + If FRecordCount=0 then ActivateBuffers; + if FRecordcount=FBuffercount then + shiftbuffersbackward + else + begin + inc(FRecordCount); + FCurrentRecord:=FRecordCount - 1; + ExchangeBuffers(pbufferaty(FBuffers)^[FCurrentRecord], + pbufferaty(FBuffers)^[FBuffercount]); + end; + end + else + cursorposchanged; +{$ifdef dsdebug} + Writeln ('Result getting next record : ',Result); +{$endif} +end; + +Function TDataset.GetNextRecords: Longint; + +begin + Result:=0; +{$ifdef dsdebug} + Writeln ('Getting next record(s), need :',FBufferCount); +{$endif} + While (FRecordCount0 Then SetCurrentRecord(0); + Result:=GetRecord(pbufferaty(FBuffers)^[FBuffercount],gmPrior,True)=grOK; + if result then + begin + If FRecordCount=0 then ActivateBuffers; + shiftbuffersforward; + + if FRecordcount 0 then + begin + CheckActive; + SetState(dsBlockRead); + end + else + begin + //update state only when in dsBlockRead + if FState = dsBlockRead then + SetState(dsBrowse); + end; +end; + +Procedure TDataSet.SetFieldDefs(AFieldDefs: TFieldDefs); + +begin + FFieldDefs.Assign(AFieldDefs); +end; + +procedure TDataSet.DoInsertAppendRecord(const Values: array of const; DoAppend : boolean); +var i : integer; + ValuesSize : integer; +begin + ValuesSize:=Length(Values); + if ValuesSize>FieldCount then DatabaseError(STooManyFields,self); + if DoAppend then + Append + else + Insert; + + for i := 0 to ValuesSize-1 do with values[i] do + fields[i].AssignValue(values[i]); + Post; + +end; + +procedure TDataSet.InitFieldDefsFromfields; +var i : integer; +begin + if FieldDefs.count = 0 then + begin + FieldDefs.BeginUpdate; + try + for i := 0 to Fields.Count-1 do with fields[i] do + if not (FieldKind in [fkCalculated,fkLookup]) then // Do not add fielddefs for calculated/lookup fields. + begin + with TFieldDef.Create(FieldDefs,FieldName,DataType,Size,Required,FieldDefs.Count+1) do + begin + if Required then Attributes := attributes + [faRequired]; + if ReadOnly then Attributes := attributes + [faReadOnly]; + if DataType = ftBCD then precision := (fields[i] as TBCDField).Precision + else if DataType = ftFMTBcd then precision := (fields[i] as TFMTBCDField).Precision; + end; + end; + finally + FieldDefs.EndUpdate; + end; + end; +end; + +Procedure TDataset.InitRecord(Buffer: TRecordBuffer); + +begin + InternalInitRecord(Buffer); + ClearCalcFields(Buffer); +end; + +Procedure TDataset.InternalCancel; + +begin + //!! To be implemented +end; + +Procedure TDataset.InternalEdit; + +begin + //!! To be implemented +end; + +Procedure TDataset.InternalRefresh; + +begin + //!! To be implemented +end; + +Procedure TDataset.OpenCursor(InfoQuery: Boolean); + +begin + if InfoQuery then + InternalInitfieldDefs + else if state <> dsOpening then + DoInternalOpen; +end; + +procedure TDataSet.OpenCursorcomplete; +begin + try + if FState = dsOpening then DoInternalOpen + finally + if FInternalOpenComplete then + begin + SetState(dsBrowse); + DoAfterOpen; + if not IsEmpty then + DoAfterScroll; + end + else + begin + SetState(dsInactive); + CloseCursor; + end; + end; +end; + +Procedure TDataset.RefreshInternalCalcFields(Buffer: TRecordBuffer); + +begin + //!! To be implemented +end; + +Function TDataset.SetTempState(const Value: TDataSetState): TDataSetState; + +begin + result := FState; + FState := value; + inc(FDisableControlsCount); +end; + +Procedure TDataset.RestoreState(const Value: TDataSetState); + +begin + FState := value; + dec(FDisableControlsCount); +end; + +function TDataset.GetActive : boolean; + +begin + result := (FState <> dsInactive) and (FState <> dsOpening); +end; + +Procedure TDataset.InternalHandleException; + +begin + if assigned(classes.ApplicationHandleException) then + classes.ApplicationHandleException(self) + else + ShowException(ExceptObject,ExceptAddr); +end; + +procedure TDataSet.InternalInitRecord(Buffer: TRecordBuffer); +begin + // empty stub +end; + +procedure TDataSet.InternalLast; +begin + // empty stub +end; + +procedure TDataSet.InternalPost; + + Procedure Checkrequired; + + Var I : longint; + + begin + For I:=0 to FFieldList.Count-1 do + With FFieldList[i] do + // Required fields that are NOT autoinc !! Autoinc cannot be set !! + if Required and not ReadOnly and + (FieldKind=fkData) and Not (DataType=ftAutoInc) and IsNull then + DatabaseErrorFmt(SNeedField,[DisplayName],Self); + end; + +begin + Checkrequired; +end; + +procedure TDataSet.InternalSetToRecord(Buffer: TRecordBuffer); +begin + // empty stub +end; + +procedure TDataSet.SetBookmarkFlag(Buffer: TRecordBuffer; Value: TBookmarkFlag); +begin + // empty stub +end; + +procedure TDataSet.SetBookmarkData(Buffer: TRecordBuffer; Data: Pointer); +begin + // empty stub +end; + +procedure TDataSet.SetUniDirectional(const Value: Boolean); +begin + FIsUniDirectional := Value; +end; + +function compdatasource(item1, item2: pointer): integer; +begin + result:= tdatasource(item2).priority - tdatasource(item1).priority; +end; + +procedure tdataset.sortdatasources(); +begin + quicksortpointer(fdatasources.list^,fdatasources.count,@compdatasource); + //position stable sort +end; + +Procedure TDataset.SetActive (Value : Boolean); + +begin + if value and (Fstate = dsInactive) then begin + if csLoading in ComponentState then begin + FOpenAfterRead := true; + exit; + end + else begin + sortdatasources(); + DoBeforeOpen; + FEnableControlsEvent:=deLayoutChange; + FInternalCalcFields:=False; + try + FDefaultFields:=FieldCount=0; + OpenCursor(False); + finally + if FState <> dsOpening then OpenCursorComplete; + end; + end; + FModified:=False; + end + else if not value and (Fstate <> dsinactive) then + begin + DoBeforeClose; + SetState(dsInactive); + CloseCursor; + DoAfterClose; + FModified:=False; + end +end; + +procedure TDataset.Loaded; + +begin + inherited; + try + if FOpenAfterRead then SetActive(true); + except + if csDesigning in Componentstate then + InternalHandleException + else + raise; + end; +end; + + +procedure TDataSet.RecalcBufListSize; + +var + i, j, ABufferCount: Integer; + DataLink: TDataLink; + +begin +{$ifdef dsdebug} + Writeln('Recalculating buffer list size - check cursor'); +{$endif} + If Not IsCursorOpen Then + Exit; +{$ifdef dsdebug} + Writeln('Recalculating buffer list size'); +{$endif} + ABufferCount := DefaultBufferCount; + for i := 0 to FDataSources.Count - 1 do + for j := 0 to TDataSource(FDataSources[i]).DataLinks.Count - 1 do + begin + DataLink:=TDataLink(TDataSource(FDataSources[i]).DataLinks[j]); + if DataLink.BufferCount>ABufferCount then + ABufferCount:=DataLink.BufferCount; + end; + + If (FBufferCount=ABufferCount) Then + exit; + +{$ifdef dsdebug} + Writeln('Setting buffer list size'); +{$endif} + + SetBufListSize(ABufferCount); +{$ifdef dsdebug} + Writeln('Getting next buffers'); +{$endif} + GetNextRecords; + if (FRecordCount < FBufferCount) and not IsUniDirectional then + begin + FActiveRecord := FActiveRecord + GetPriorRecords; + CursorPosChanged; + end; +{$Ifdef dsDebug} + WriteLn( + 'SetBufferCount: FActiveRecord=',FActiveRecord, + ' FCurrentRecord=',FCurrentRecord, + ' FBufferCount= ',FBufferCount, + ' FRecordCount=',FRecordCount); +{$Endif} +end; + +Procedure TDataset.SetBookmarkStr(const Value: TBookmarkStr); + +begin + GotoBookMark(Pointer(Value)) +end; + +Procedure TDataset.SetBufListSize(Value: Longint); + +Var I : longint; + +begin + if Value = 0 then Value := -1; +{$ifdef dsdebug} + Writeln ('SetBufListSize: ',Value); +{$endif} + If Value=FBufferCount Then + exit; + If Value>FBufferCount then + begin +{$ifdef dsdebug} + Writeln (' Reallocating memory :',(Value+1)*SizeOf(TRecordBuffer)); +{$endif} + ReAllocMem(FBuffers,(Value+1)*SizeOf(PChar)); +{$ifdef dsdebug} + Writeln (' Filling memory :',(Value+1-FBufferCount)*SizeOf(TRecordBuffer)); +{$endif} + inc(FBufferCount); // Cause FBuffers[FBufferCount] is already allocated + FillChar(pbufferaty(FBuffers)^[FBufferCount],(Value+1-FBufferCount)*SizeOF(TRecordBuffer),#0); +{$ifdef dsdebug} + Writeln (' Filled memory :'); +{$endif} + Try +{$ifdef dsdebug} + Writeln (' Assigning buffers :',(Value)*SizeOf(TRecordBuffer)); +{$endif} + For I:=FBufferCount to Value do + pbufferaty(FBuffers)^[i]:=AllocRecordBuffer; +{$ifdef dsdebug} + Writeln (' Assigned buffers ',FBufferCount,' :',(Value)*SizeOf(TRecordBuffer)); +{$endif} + except + I:=FBufferCount; + While (I<(Value+1)) do + begin + FreeRecordBuffer(pbufferaty(FBuffers)^[i]); + Inc(i); + end; + raise; + end; + end + else + begin +{$ifdef dsdebug} + Writeln (' Freeing buffers :',FBufferCount-Value); +{$endif} + if (value > -1) and (FActiveRecord>Value-1) then + begin + for i := 0 to (FActiveRecord-Value) do + shiftbuffersbackward; + FActiverecord := Value -1; + end; + + If Assigned(FBuffers) then + begin + For I:=Value+1 to FBufferCount do + FreeRecordBuffer(pbufferaty(FBuffers)^[i]); + // FBuffer must stay allocated, to make sure that Activebuffer returns nil + if Value = -1 then + begin + ReAllocMem(FBuffers,SizeOf(TRecordBuffer)); + pbufferaty(FBuffers)^[0] := nil; + end + else + ReAllocMem(FBuffers,(Value+1)*SizeOf(TRecordBuffer)); + end; + end; + FBufferCount:=Value; + If Value=-1 then + Value:=0; + if FRecordcount > Value then FRecordcount := Value; +{$ifdef dsdebug} + Writeln (' SetBufListSize: Final FBufferCount=',FBufferCount); +{$endif} +end; + +Procedure TDataset.SetChildOrder(Component: TComponent; Order: Longint); + +var + Field: TField; +begin + Field := Component as TField; + if Fields.IndexOf(Field) >= 0 then + Field.Index := Order; +end; + +Procedure TDataset.SetCurrentRecord(Index: Longint); + +begin + If FCurrentRecord<>Index then + begin +{$ifdef DSdebug} + Writeln ('Setting current record to',index); +{$endif} + if not FIsUniDirectional then Case GetBookMarkFlag(pbufferaty(FBuffers)^[Index]) of + bfCurrent : InternalSetToRecord(pbufferaty(FBuffers)^[Index]); + bfBOF : InternalFirst; + bfEOF : InternalLast; + end; + FCurrentRecord:=index; + end; +end; + +procedure TDataSet.SetDefaultFields(const Value: Boolean); +begin + FDefaultFields := Value; +end; + +Procedure TDataset.SetField (Index : Longint;Value : TField); + +begin + //!! To be implemented +end; + +Procedure TDataset.CheckBiDirectional; + +begin + if FIsUniDirectional then DataBaseError(SUniDirectional); +end; + +Procedure TDataset.SetFilterOptions(Value: TFilterOptions); + +begin + CheckBiDirectional; + FFilterOptions := Value; +end; + +Procedure TDataset.SetFilterText(const Value: string); + +begin + FFilterText := value; +end; + +Procedure TDataset.SetFiltered(Value: Boolean); + +begin + if Value then CheckBiDirectional; + FFiltered := value; +end; + +procedure TDataSet.SetFound(const Value: Boolean); +begin + FFound := Value; +end; + +Procedure TDataset.SetModified(Value: Boolean); + +begin + FModified := value; + if value and (fstate in [dsinsert,dsedit]) then begin + domodified(); + end; +end; + +Procedure TDataset.SetName(const Value: TComponentName); + +function CheckName(const FieldName: string): string; +var i,j: integer; +begin + Result := FieldName; + i := 0; + j := 0; + while (i < Fields.Count) do begin + if Result = Fields[i].FieldName then begin + inc(j); + Result := FieldName + IntToStr(j); + end else Inc(i); + end; +end; +var i: integer; + nm: string; + old: string; +begin + if Self.Name = Value then Exit; + old := Self.Name; + inherited SetName(Value); + if (csDesigning in ComponentState) and (old <> '') then begin + for i := 0 to Fields.Count - 1 do begin + nm := old + Fields[i].FieldName; + if Copy(Fields[i].Name, 1, Length(nm)) = nm then begin + Fields[i].Name := CheckName(Value + Fields[i].FieldName); + end; + end; + end; +end; + +Procedure TDataset.SetOnFilterRecord(const Value: TFilterRecordEvent); + +begin + CheckBiDirectional; + FOnFilterRecord := Value; +end; + +Procedure TDataset.SetRecNo(Value: Longint); + +begin + //!! To be implemented +end; + +Procedure TDataset.SetState(Value: TDataSetState); + +begin + If Value<>FState then + begin + FState:=Value; + if Value=dsBrowse then + FModified:=false; + DataEvent(deUpdateState,0); + end; +end; + +Function TDataset.Tempbuffer: TRecordBuffer; + +begin + Result := pbufferaty(FBuffers)^[FRecordCount]; +end; + +Procedure TDataset.UpdateIndexDefs; + +begin + // Empty Abstract +end; + +function TDataSet.AllocRecordBuffer: TRecordBuffer; +begin + Result := nil; +end; + +procedure TDataSet.FreeRecordBuffer(var Buffer: TRecordBuffer); +begin + // empty stub +end; + +procedure TDataSet.GetBookmarkData(Buffer: TRecordBuffer; Data: Pointer); +begin + // empty stub +end; + +function TDataSet.GetBookmarkFlag(Buffer: TRecordBuffer): TBookmarkFlag; +begin + Result := bfCurrent; +end; + +Function TDataset.ControlsDisabled: Boolean; + +begin + Result := (FDisableControlsCount > 0); +end; + +Function TDataset.ActiveBuffer: TRecordBuffer; + +begin +{$ifdef dsdebug} + Writeln ('Active buffer requested. Returning:',ActiveRecord); +{$endif} + Result:=pbufferaty(FBuffers)^[FActiveRecord]; +end; + +Procedure TDataset.Append; + +begin + DoInsertAppend(True); +end; + +Procedure TDataset.InternalInsert; + +begin + //!! To be implemented +end; + +Procedure TDataset.AppendRecord(const Values: array of const); + +begin + DoInsertAppendRecord(Values,True); +end; + +Function TDataset.BookmarkValid(ABookmark: TBookmark): Boolean; +{ + Should be overridden by descendant objects. +} +begin + Result:=False +end; + +Procedure TDataset.Cancel; + +begin + If State in [dsEdit,dsInsert] then + begin + DataEvent(deCheckBrowseMode,0); + DoBeforeCancel; + UpdateCursorPos; + InternalCancel; + FreeFieldBuffers; + if (state = dsInsert) and (FRecordcount = 1) then + begin + FEOF := true; + FBOF := true; + FRecordcount := 0; + InitRecord(ActiveBuffer); + SetState(dsBrowse); + DataEvent(deDatasetChange,0); + end + else + begin + SetState(dsBrowse); + SetCurrentRecord(FActiverecord); + resync([]); + end; + DoAfterCancel; + end; +end; + +Procedure TDataset.CheckBrowseMode; + +begin + if not (dsis_checkingbrowsemode in finternalstate) then begin + include(finternalstate,dsis_checkingbrowsemode); + try + CheckActive; + DataEvent(deCheckBrowseMode,0); + Case State of + dsedit,dsinsert: begin + UpdateRecord; + If Modified then Post else Cancel; + end; + dsSetKey: Post; + end; + finally + exclude(finternalstate,dsis_checkingbrowsemode); + end; + end; +end; + +Procedure TDataset.ClearFields; + + +begin + DataEvent(deCheckBrowseMode, 0); + FreeFieldBuffers; + InternalInitRecord(ActiveBuffer); + if State <> dsSetKey then GetCalcFields(ActiveBuffer); + DataEvent(deRecordChange, 0); +end; + +Procedure TDataset.Close; + +begin + Active:=False; +end; + +Function TDataset.CompareBookmarks(Bookmark1, Bookmark2: TBookmark): Longint; + +begin + Result:=0; +end; + +Function TDataset.CreateBlobStream(Field: TField; Mode: TBlobStreamMode): TStream; + + +begin + Result:=Nil; +end; + +Procedure TDataset.CursorPosChanged; + + +begin + FCurrentRecord:=-1; +end; + +Procedure TDataset.Delete; + +begin + If Not CanModify then + DatabaseError(SDatasetReadOnly,Self); + If IsEmpty then + DatabaseError(SDatasetEmpty,Self); + if State in [dsInsert] then + begin + Cancel; + end else begin + DataEvent(deCheckBrowseMode,0); +{$ifdef dsdebug} + writeln ('Delete: checking required fields'); +{$endif} + DoBeforeDelete; + DoBeforeScroll; + If Not TryDoing({$ifdef FPC}@{$endif}InternalDelete,OnPostError) then exit; +{$ifdef dsdebug} + writeln ('Delete: Internaldelete succeeded'); +{$endif} + FreeFieldBuffers; + SetState(dsBrowse); +{$ifdef dsdebug} + writeln ('Delete: Browse mode set'); +{$endif} + SetCurrentRecord(FActiverecord); + Resync([]); + DoAfterDelete; + DoAfterScroll; + end; +end; + +Procedure TDataset.DisableControls; + + +begin + If FDisableControlsCount=0 then + begin + { Save current state, + needed to detect change of state when enabling controls. + } + FDisableControlsState:=FState; + FEnableControlsEvent:=deDatasetChange; + end; + Inc(FDisableControlsCount); +end; + +Procedure TDataset.DoInsertAppend(DoAppend : Boolean); + + + procedure DoInsert(DoAppend : Boolean); + + Var BookBeforeInsert : TBookmarkStr; + TempBuf : pointer; + + begin + bookbeforeinsert:= ''; + // need to scroll up al buffers after current one, + // but copy current bookmark to insert buffer. + If FRecordcount > 0 then + BookBeforeInsert:=Bookmark; + + if not DoAppend then + begin + if FRecordCount > 0 then + begin + TempBuf := pbufferaty(FBuffers)^[FBuffercount]; + move(pbufferaty(FBuffers)^[FActiveRecord], + pbufferaty(FBuffers)^[FActiveRecord+1], + (Fbuffercount-FActiveRecord)*sizeof(pbufferaty(FBuffers)^[0])); + pbufferaty(FBuffers)^[FActiveRecord]:=TempBuf; + end; + end + else if FRecordcount=FBuffercount then + shiftbuffersbackward + else + begin + if FRecordCount>0 then + inc(FActiveRecord); + end; + + // Active buffer is now edit buffer. Initialize. + InitRecord(pbufferaty(FBuffers)^[FActiveRecord]); + cursorposchanged; + + // Put bookmark in edit buffer. + if FRecordCount=0 then + SetBookmarkFlag(ActiveBuffer,bfEOF) + else + begin + fBOF := false; + // 29:01:05, JvdS: Why is this here?!? It can result in records with the same bookmark-data? + // I would say that the 'internalinsert' should do this. But I don't know how Tdbf handles it + + // 1-apr-06, JvdS: It just sets the bookmark of the newly inserted record to the place + // where the record should be inserted. So it is ok. + if FRecordcount > 0 then + SetBookMarkData(ActiveBuffer,pointer(BookBeforeInsert)); + end; + + InternalInsert; + + // update buffer count. + If FRecordCount dsbrowse then begin + exit; //posting canceled + end; + If Not CanModify then + DatabaseError(SDatasetReadOnly,Self); + DoBeforeInsert; + DoBeforeScroll; + If Not DoAppend then + begin +{$ifdef dsdebug} + Writeln ('going to insert mode'); +{$endif} + DoInsert(false); + end + else + begin +{$ifdef dsdebug} + Writeln ('going to append mode'); +{$endif} + ClearBuffers; + InternalLast; + GetPriorRecords; + if FRecordCount>0 then + FActiveRecord:=FRecordCount-1; + DoInsert(True); + SetBookmarkFlag(ActiveBuffer,bfEOF); + FBOF :=False; + FEOF := true; + end; + SetState(dsInsert); + try + DoOnNewRecord; + except + SetCurrentRecord(FActiverecord); + resync([]); + raise; + end; + // mark as not modified. + FModified:=False; + // Final events. + DataEvent(deDatasetChange,0); + DoAfterInsert; + DoAfterScroll; +{$ifdef dsdebug} + Writeln ('Done with append'); +{$endif} +end; + +Procedure TDataset.Edit; + +begin + If State in [dsedit,dsinsert] then exit; + CheckBrowseMode; + If Not CanModify then + DatabaseError(SDatasetReadOnly,Self); + If FRecordCount = 0 then + begin + Append; + Exit; + end; + DoBeforeEdit; + If Not TryDoing({$ifdef FPC}@{$endif}InternalEdit,OnEditError) then exit; + GetCalcFields(ActiveBuffer); + SetState(dsedit); + DataEvent(deRecordChange,0); + DoAfterEdit; +end; + +Procedure TDataset.EnableControls; + + +begin + if FDisableControlsCount > 0 then + Dec(FDisableControlsCount); + + if FDisableControlsCount = 0 then begin + if FState <> FDisableControlsState then + DataEvent(deUpdateState, 0); + + if (FState <> dsInactive) and (FDisableControlsState <> dsInactive) then + DataEvent(FEnableControlsEvent, 0); + end; +end; + +Function TDataset.FieldByName(const FieldName: string): TField; + + +begin + Result:=FindField(FieldName); + If Result=Nil then + DatabaseErrorFmt(SFieldNotFound,[FieldName],Self); +end; + +Function TDataset.FindField(const FieldName: string): TField; + + +begin + Result:=FFieldList.FindField(FieldName); +end; + +Function TDataset.FindFirst: Boolean; + + +begin + Result:=False; +end; + +Function TDataset.FindLast: Boolean; + + +begin + Result:=False; +end; + +Function TDataset.FindNext: Boolean; + + +begin + Result:=False; +end; + +Function TDataset.FindPrior: Boolean; + + +begin + Result:=False; +end; + +Procedure TDataset.First; + + +begin + CheckBrowseMode; + if fstate <> dsbrowse then begin + exit; //posting canceled + end; + DoBeforeScroll; + if not FIsUniDirectional then + ClearBuffers + else if not FBof then + begin + Active := False; + Active := True; + end; + try + InternalFirst; + if not FIsUniDirectional then GetNextRecords; + finally + FBOF:=True; + DataEvent(deDatasetChange,0); + DoAfterScroll; + end; +end; + +Procedure TDataset.FreeBookmark(ABookmark: TBookmark); + + +begin + FreeMem(ABookMark,FBookMarkSize); +end; + +Function TDataset.GetBookmark: TBookmark; + + +begin + if BookmarkAvailable then + begin + GetMem (Result,FBookMarkSize); + GetBookMarkdata(ActiveBuffer,Result); + end + else + Result:=Nil; +end; + +Function TDataset.GetCurrentRecord(Buffer: TRecordBuffer): Boolean; + + +begin + Result:=False; +end; + +Procedure TDataset.GetFieldList(List: TList; const FieldNames: string); + +var + F: TField; + N: String; + StrPos: Integer; + +begin + if (FieldNames = '') or (List = nil) then + Exit; + StrPos := 1; + repeat + N := ExtractFieldName(FieldNames, StrPos); + F := FieldByName(N); + List.Add(F); + until StrPos > Length(FieldNames); +end; + +Procedure TDataset.GetFieldNames(List: TStrings); + + +begin + FFieldList.GetFieldNames(List); +end; + +Procedure TDataset.GotoBookmark(ABookmark: TBookmark); + + +begin + If Assigned(ABookMark) then + begin + CheckBrowseMode; + DoBeforeScroll; + InternalGotoBookMark(ABookMark); + Resync([rmExact,rmCenter]); + DoAfterScroll; + end; +end; + +Procedure TDataset.Insert; + +begin + DoInsertAppend(False); +end; + +Procedure TDataset.InsertRecord(const Values: array of const); + +begin + DoInsertAppendRecord(Values,False); +end; + +Function TDataset.IsEmpty: Boolean; + +begin + Result:=(fBof and fEof) and + (not (state = dsinsert)); // After an insert on an empty dataset, both fBof and fEof are true +end; + +Function TDataset.IsLinkedTo(ADataSource: TDataSource): Boolean; + +begin +//!! Not tested, I never used nested DS + if (ADataSource = nil) or (ADataSource.Dataset = nil) then begin + Result := False + end else if ADataSource.Dataset = Self then begin + Result := True; + end else begin + Result := ADataSource.Dataset.IsLinkedTo(ADataSource.Dataset.DataSource); + end; +//!! DataSetField not implemented +end; + +Function TDataset.IsSequenced: Boolean; + +begin + Result := True; +end; + +Procedure TDataset.Last; + +begin + CheckBiDirectional; + CheckBrowseMode; + if fstate <> dsbrowse then begin + exit; //posting canceled + end; + DoBeforeScroll; + ClearBuffers; + try + InternalLast; + GetPriorRecords; + if FRecordCount>0 then + FActiveRecord:=FRecordCount-1 + finally + FEOF:=true; + DataEvent(deDataSetChange, 0); + DoAfterScroll; + end; +end; + +Function TDataset.MoveBy(Distance: Longint): Longint; +Var + TheResult: Integer; + + Function Scrollforward : Integer; + + begin + Result:=0; +{$ifdef dsdebug} + Writeln('Scrolling forward :',Distance); + Writeln('Active buffer : ',FActiveRecord); + Writeln('RecordCount : ',FRecordCount); + WriteLn('BufferCount : ',FBufferCount); +{$endif} + FBOF:=False; + While (Distance>0) and not FEOF do + begin + If FActiveRecord0 then + begin + Dec(FActiveRecord); + Inc(Distance); + Dec(TheResult); //Dec(Result); + end + else + begin + {$ifdef dsdebug} + Writeln('Moveby : need next record'); + {$endif} + If GetPriorRecord then + begin + Inc(Distance); + Inc(Result); + Dec(TheResult); //Dec(Result); + end + else + FBOF:=true; + end; + end + end; + +Var + Scrolled : Integer; + +begin + CheckBrowseMode; + Result:=0; + if fstate <> dsbrowse then begin + exit; //posting canceled + end; + TheResult:=0; + DoBeforeScroll; + If (Distance = 0) or + ((Distance>0) and FEOF) or + ((Distance<0) and FBOF) then + exit; + Try + Scrolled := 0; + If Distance>0 then + Scrolled:=ScrollForward + else + Scrolled:=ScrollBackward; + finally +{$ifdef dsdebug} + WriteLn('ActiveRecord=', FActiveRecord,' FEOF=',FEOF,' FBOF=',FBOF); +{$Endif} + DataEvent(deDatasetScroll,Scrolled); + DoAfterScroll; + Result:=TheResult; + end; +end; + +Procedure TDataset.Next; + +begin + if BlockReadSize>0 then + BlockReadNext + else + MoveBy(1); +end; + +Procedure TDataset.BlockReadNext; +begin + MoveBy(1); +end; + +Procedure TDataset.Open; + +begin + Active:=True; +end; + +Procedure TDataset.Post; + +begin + if State in [dsEdit,dsInsert] then + begin + DataEvent(deUpdateRecord,0); + DataEvent(deCheckBrowseMode,0); +{$ifdef dsdebug} + writeln ('Post: checking required fields'); +{$endif} + DoBeforePost; + If Not TryDoing({$ifdef FPC}@{$endif}InternalPost,OnPostError) then exit; + cursorposchanged; +{$ifdef dsdebug} + writeln ('Post: Internalpost succeeded'); +{$endif} + FreeFieldBuffers; +// First set the state to dsBrowse, then the Resync, to prevent the calling of +// the deDatasetChange event, while the state is still 'editable', while the db isn't + SetState(dsBrowse); + Resync([]); +{$ifdef dsdebug} + writeln ('Post: Browse mode set'); +{$endif} + DoAfterPost; + end + else + DatabaseErrorFmt(SNotEditing, [Name], Self); +end; + +Procedure TDataset.Prior; + +begin + MoveBy(-1); +end; + +Procedure TDataset.Refresh; + +begin + include(finternalstate,dsis_refreshing); + try + CheckbrowseMode; + DoBeforeRefresh; + UpdateCursorPos; + InternalRefresh; +{ SetCurrentRecord is called by UpdateCursorPos already, so as long as + InternalRefresh doesn't do strange things this should be ok. } +// SetCurrentRecord(FActiverecord); + Resync([]); + DoAfterRefresh; + finally + exclude(finternalstate,dsis_refreshing); + end; +end; + +function TDataSet.refreshing: boolean; +begin + result:= dsis_refreshing in finternalstate; +end; + +Procedure TDataset.RegisterDataSource(ADatasource : TDataSource); + +begin + FDatasources.Add(ADataSource); + if fstate <> dsinactive then begin + sortdatasources(); + end; + RecalcBufListSize; +end; + + +Procedure TDataset.Resync(Mode: TResyncMode); + +var i,count : integer; + +begin + // See if we can find the requested record. +{$ifdef dsdebug} + Writeln ('Resync called'); +{$endif} + if FIsUnidirectional then Exit; +// place the cursor of the underlying dataset to the active record +// SetCurrentRecord(FActiverecord); + +// Now look if the data on the current cursor of the underlying dataset is still available + If GetRecord(pbufferaty(FBuffers)^[0],gmcurrent,False)<>grOk Then +// If that fails and rmExact is set, then raise an exception + If rmExact in Mode then + DatabaseError(SNoSuchRecord,Self) +// else, if rmexact is not set, try to fetch the next or prior record in the underlying dataset + else if (GetRecord(pbufferaty(FBuffers)^[0],gmnext,True)<>grOk) and + (GetRecord(pbufferaty(FBuffers)^[0],gmprior,True)<>grOk) then + begin +{$ifdef dsdebug} + Writeln ('Resync: fuzzy resync'); +{$endif} + // nothing found, invalidate buffer and bail out. + ClearBuffers; + // Make sure that the active record is 'empty', ie: that all fields are null + InternalInitRecord(ActiveBuffer); + DataEvent(deDatasetChange,0); + exit; + end; + FCurrentRecord := 0; + FEOF := false; + FBOF := false; + +// If we've arrived here, FBuffer[0] is the current record + If (rmCenter in Mode) then + count := (FRecordCount div 2) + else + count := FActiveRecord; + i := 0; + FRecordcount := 1; + FActiveRecord := 0; + +// Fill the buffers before the active record + while (i < count) and GetPriorRecord do + inc(i); + FActiveRecord := i; +// Fill the rest of the buffer + getnextrecords; +// If the buffer is not full yet, try to fetch some more prior records + if FRecordcount < FBuffercount then inc(FActiverecord,getpriorrecords); +// That's all folks! + DataEvent(deDatasetChange,0); +end; + +Procedure TDataset.SetFields(const Values: array of const); + +Var I : longint; +begin + For I:=0 to high(Values) do + Fields[I].AssignValue(Values[I]); +end; + +Function TDataset.Translate(Src, Dest: PChar; ToOem: Boolean): Integer; + +begin + strcopy(dest,src); + Result:=StrLen(dest); +end; + +Function Tdataset.TryDoing (P : TDataOperation; Ev : TDatasetErrorEvent) : Boolean; + +Var Retry : TDataAction; + +begin +{$ifdef dsdebug} + Writeln ('Trying to do'); + If P=Nil then writeln ('Procedure to call is nil !!!'); +{$endif dsdebug} + Result:=True; + Retry:=daRetry; + while Retry=daRetry do + Try +{$ifdef dsdebug} + Writeln ('Trying : updatecursorpos'); +{$endif dsdebug} + UpdateCursorPos; +{$ifdef dsdebug} + Writeln ('Trying to do it'); +{$endif dsdebug} + P; + exit; + except + On E : EDatabaseError do + begin + retry:=daFail; + If Assigned(Ev) then + Ev(Self,E,Retry); + Case Retry of + daFail : Raise; + daAbort : Result:=False; + end; + end; + else + Raise; + end; +{$ifdef dsdebug} + Writeln ('Exit Trying to do'); +{$endif dsdebug} +end; + +Procedure TDataset.UpdateCursorPos; + +begin + If FRecordCount>0 then + SetCurrentRecord(FactiveRecord); +end; + +Procedure TDataset.UpdateRecord; + +begin + if not (State in dsEditModes) then + DatabaseErrorFmt(SNotEditing, [Name], Self); + DataEvent(deUpdateRecord, 0); +end; + +Function TDataSet.UpdateStatus: TUpdateStatus; + +begin + Result:=usUnmodified; +end; + +procedure TDataSet.modify(const callmodified: boolean = true); +begin + if fstate in [dsedit,dsinsert] then begin + if callmodified then begin + setmodified(true); + end + else begin + fmodified:= true; + end; + end; +end; + +procedure TDataSet.resetmodified(); +begin + setmodified(false); +end; + +Procedure TDataset.RemoveField (Field : TField); + +begin + //!! To be implemented +end; + +procedure TDataSet.SetConstraints(Value: TCheckConstraints); +begin + FConstraints.Assign(Value); +end; + +Function TDataset.Getfieldcount : Longint; + +begin + Result:=FFieldList.Count; +end; + +Procedure TDataset.ShiftBuffersBackward; + +var TempBuf : pointer; + +begin + TempBuf := pbufferaty(FBuffers)^[0]; + move(pbufferaty(FBuffers)^[1],pbufferaty(FBuffers)^[0], + (fbuffercount)*sizeof(pbufferaty(FBuffers)^[0])); + pbufferaty(FBuffers)^[buffercount]:=TempBuf; +end; + +Procedure TDataset.ShiftBuffersForward; + +var TempBuf : pointer; + +begin + TempBuf := pbufferaty(FBuffers)^[FBufferCount]; + move(pbufferaty(FBuffers)^[0],pbufferaty(FBuffers)^[1], + (fbuffercount)*sizeof(pbufferaty(FBuffers)^[0])); + pbufferaty(FBuffers)^[0]:=TempBuf; +end; + +function TDataset.GetFieldValues(const Fieldname: string): Variant; + +var i: Integer; + FieldList: TList; +begin + FieldList := TList.Create; + try + GetFieldList(FieldList, FieldName); + if FieldList.Count>1 then begin + Result := VarArrayCreate([0, FieldList.Count - 1], varVariant); + for i := 0 to FieldList.Count - 1 do + Result[i] := TField(FieldList[i]).Value; + end else + Result := FieldByName(FieldName).Value; + finally + FieldList.Free; + end; +end; + +procedure TDataset.SetFieldValues(const Fieldname: string; Value: Variant); + +var + i : Integer; + FieldList: TList; +begin + if VarIsArray(Value) then begin + FieldList := TList.Create; + try + GetFieldList(FieldList, FieldName); + for i := 0 to FieldList.Count -1 do + TField(FieldList[i]).Value := Value[i]; + finally + FieldList.Free; + end; + end else + FieldByName(Fieldname).Value := Value; +end; + +Function TDataset.Locate(const keyfields: string; const keyvalues: Variant; options: TLocateOptions) : boolean; + +begin + CheckBiDirectional; + Result := False; +end; + +Function TDataset.Lookup(const KeyFields: string; const KeyValues: Variant; const ResultFields: string): Variant; + +begin + CheckBiDirectional; + Result := Null; +end; + + +Procedure TDataset.UnRegisterDataSource(ADatasource : TDatasource); + +begin + FDataSources.Remove(ADataSource); +end; + +{------------------------------------------------------------------------------} +{ IProviderSupport methods} + +procedure TDataset.PSEndTransaction(Commit: Boolean); +begin + DatabaseError('Provider support not available', Self); +end; + +procedure TDataset.PSExecute; +begin + DatabaseError('Provider support not available', Self); +end; + +function TDataset.PSExecuteStatement(const ASQL: string; AParams: TParams; + ResultSet: Pointer): Integer; +begin + Result := 0; + DatabaseError('Provider support not available', Self); +end; + +procedure TDataset.PSGetAttributes(List: TList); +begin + DatabaseError('Provider support not available', Self); +end; + +function TDataset.PSGetCommandText: string; +begin + Result := ''; + DatabaseError('Provider support not available', Self); +end; + +function TDataset.PSGetCommandType: TPSCommandType; +begin + Result := ctUnknown; + DatabaseError('Provider support not available', Self); +end; + +function TDataset.PSGetDefaultOrder: TIndexDef; +begin + Result := nil; + //DatabaseError('Provider support not available', Self); +end; + +function TDataset.PSGetIndexDefs(IndexTypes: TIndexOptions): TIndexDefs; +begin + Result := nil; + DatabaseError('Provider support not available', Self); +end; + +function TDataset.PSGetKeyFields: string; +begin + Result := ''; + DatabaseError('Provider support not available', Self); +end; + +function TDataset.PSGetParams: TParams; +begin + Result := nil; + DatabaseError('Provider support not available', Self); +end; + +function TDataset.PSGetQuoteChar: string; +begin + Result := ''; + DatabaseError('Provider support not available', Self); +end; + +function TDataset.PSGetTableName: string; +begin + Result := ''; + DatabaseError('Provider support not available', Self); +end; + +function TDataset.PSGetUpdateException(E: Exception; Prev: EUpdateError + ): EUpdateError; +begin + if Prev <> nil then + Result := EUpdateError.Create(E.Message, '', 0, Prev.ErrorCode, E) + else + Result := EUpdateError.Create(E.Message, '', 0, 0, E) +end; + +function TDataset.PSInTransaction: Boolean; +begin + Result := False; + DatabaseError('Provider support not available', Self); +end; + +function TDataset.PSIsSQLBased: Boolean; +begin + Result := False; + DatabaseError('Provider support not available', Self); +end; + +function TDataset.PSIsSQLSupported: Boolean; +begin + Result := False; + DatabaseError('Provider support not available', Self); +end; + +procedure TDataset.PSReset; +begin + //DatabaseError('Provider support not available', Self); +end; + +procedure TDataset.PSSetCommandText(const CommandText: string); +begin + DatabaseError('Provider support not available', Self); +end; + +procedure TDataset.PSSetParams(AParams: TParams); +begin + DatabaseError('Provider support not available', Self); +end; + +procedure TDataset.PSStartTransaction; +begin + DatabaseError('Provider support not available', Self); +end; + +function TDataset.PSUpdateRecord(UpdateKind: TUpdateKind; Delta: TDataSet + ): Boolean; +begin + Result := False; + DatabaseError('Provider support not available', Self); +end; + +{------------------------------------------------------------------------------} + + +{ --------------------------------------------------------------------- + TFieldDef + ---------------------------------------------------------------------} + +Constructor TFieldDef.Create(ACollection : TCollection); + +begin + FPrecision:=-1; + Inherited create(ACollection); + FFieldNo:=Index+1; +end; + +Constructor TFieldDef.Create(AOwner: TFieldDefs; const AName: string; + ADataType: TFieldType; ASize: Integer; ARequired: Boolean; AFieldNo: Longint); + +begin +{$ifdef dsdebug } + Writeln('TFieldDef.Create : ',Aname,'(',AFieldNo,')'); +{$endif} + Inherited Create(AOwner); + Name:=Aname; + FDatatype:=ADatatype; + FSize:=ASize; + FRequired:=ARequired; + FPrecision:=-1; + FFieldNo:=AFieldNo; +end; + +Destructor TFieldDef.Destroy; + +begin + Inherited destroy; +end; + +procedure TFieldDef.Assign(APersistent: TPersistent); +var fd: TFieldDef; +begin + fd := nil; + if APersistent is TFieldDef then + fd := APersistent as TFieldDef; + if Assigned(fd) then begin + Collection.BeginUpdate; + try + Name := fd.Name; + DataType := fd.DataType; + Size := fd.Size; + Precision := fd.Precision; + FRequired := fd.Required; + finally + Collection.EndUpdate; + end; + end else + inherited Assign(APersistent); +end; + +Function TFieldDef.CreateField(AOwner: TComponent): TField; + +Var TheField : TFieldClass; + +begin +{$ifdef dsdebug} + Writeln ('Creating field '+FNAME); +{$endif dsdebug} + TheField:=GetFieldClass; + if TheField=Nil then + DatabaseErrorFmt(SUnknownFieldType,[FName]); + Result:=Thefield.Create(AOwner); + Try + Result.Size:=FSize; + Result.Required:=FRequired; + Result.FFieldName:=FName; + Result.FDisplayLabel:=DisplayName; + Result.FFieldNo:=Self.FieldNo; + Result.SetFieldType(DataType); + Result.ReadOnly:= (faReadOnly in Attributes); +{$ifdef dsdebug} + Writeln ('TFieldDef.CReateField : Trying to set dataset'); +{$endif dsdebug} +{$ifdef dsdebug} + Writeln ('TFieldDef.CReateField : Result Fieldno : ',Result.FieldNo,' Self : ',FieldNo); +{$endif dsdebug} + Result.Dataset:=TFieldDefs(Collection).Dataset; + If (Result is TFloatField) then + TFloatField(Result).Precision:=FPrecision; + if (Result is TBCDField) then + TBCDField(Result).Precision:=FPrecision; + if (Result is TFmtBCDField) then + TFmtBCDField(Result).Precision:=FPrecision; + except + Result.Free; + Raise; + end; + +end; + +procedure TFieldDef.SetAttributes(AValue: TFieldAttributes); +begin + FAttributes := AValue; + Changed(False); +end; + +procedure TFieldDef.SetDataType(AValue: TFieldType); +begin + FDataType := AValue; + Changed(False); +end; + +procedure TFieldDef.SetPrecision(const AValue: Longint); +begin + FPrecision := AValue; + Changed(False); +end; + +procedure TFieldDef.SetSize(const AValue: Integer); +begin + FSize := AValue; + Changed(False); +end; + +procedure TFieldDef.SetRequired(const AValue: Boolean); +begin + FRequired := AValue; + Changed(False); +end; + +Function TFieldDef.GetFieldClass : TFieldClass; + +begin + //!! Should be owner as tdataset but that doesn't work ?? + + If Assigned(Collection) And + (Collection is TFieldDefs) And + Assigned(TFieldDefs(Collection).Dataset) then + Result:=TFieldDefs(Collection).Dataset.GetFieldClass(FDataType) + else + Result:=Nil; +end; + +{ --------------------------------------------------------------------- + TFieldDefs + ---------------------------------------------------------------------} + +{ +destructor TFieldDefs.Destroy; + +begin + FItems.Free; + // This will destroy all fielddefs since we own them... + Inherited Destroy; +end; +} + +procedure TFieldDefs.Add(const AName: string; ADataType: TFieldType); + +begin + Add(AName,ADatatype,0,False); +end; + +procedure TFieldDefs.Add(const AName: string; ADataType: TFieldType; ASize : Word); + +begin + Add(AName,ADatatype,ASize,False); +end; + +procedure TFieldDefs.Add(const AName: string; ADataType: TFieldType; ASize: Word; + ARequired: Boolean); + +begin + If Length(AName)=0 Then + DatabaseError(SNeedFieldName); + // the fielddef will register itself here as a owned component. + // fieldno is 1 based ! + BeginUpdate; + try + TFieldDef.Create(Self,AName,ADataType,ASize,Arequired,Count+1); + finally + EndUpdate; + end; +end; + +function TFieldDefs.GetItem(Index: Longint): TFieldDef; + +begin + Result := TFieldDef(inherited Items[Index]); +end; + +procedure TFieldDefs.SetItem(Index: Longint; const AValue: TFieldDef); +begin + inherited Items[Index] := AValue; +end; + +constructor TFieldDefs.Create(ADataset: TDataset); +begin + Inherited Create(ADataset, Owner, TFieldDef); +end; + +procedure TFieldDefs.Assign(FieldDefs: TFieldDefs); + +Var I : longint; + +begin + Clear; + For i:=0 to FieldDefs.Count-1 do + With FieldDefs[i] do + Add(Name,DataType,Size,Required); +end; + +function TFieldDefs.Find(const AName: string): TFieldDef; +begin + Result := (Inherited Find(AName)) as TFieldDef; + if Result=nil then DatabaseErrorFmt(SFieldNotFound,[AName],FDataset); +end; + +{ +procedure TFieldDefs.Clear; + +Var I : longint; + +begin + For I:=FItems.Count-1 downto 0 do + TFieldDef(Fitems[i]).Free; + FItems.Clear; +end; +} + +procedure TFieldDefs.Update; + +begin + if not Updated then + begin + If Assigned(Dataset) then + DataSet.InitFieldDefs; + Updated := True; + end; +end; + +function TFieldDefs.MakeNameUnique(const AName: String): string; +var DblFieldCount : integer; +begin + DblFieldCount := 0; + Result := AName; + while assigned(inherited Find(Result)) do + begin + inc(DblFieldCount); + Result := AName + '_' + IntToStr(DblFieldCount); + end; +end; + +Function TFieldDefs.AddFieldDef : TFieldDef; + +begin + Result:=TFieldDef.Create(Self,'',ftUnknown,0,False,Count+1); +end; + +{ --------------------------------------------------------------------- + TField + ---------------------------------------------------------------------} + +Const + SBCD = 'BCD'; + SBoolean = 'Boolean'; + SDateTime = 'TDateTime'; + SFloat = 'Float'; + SInteger = 'Integer'; + SLargeInt = 'LargeInt'; + SVariant = 'Variant'; + SString = 'String'; + SBytes = 'Bytes'; + +constructor TField.Create(AOwner: TComponent); + +begin + Inherited Create(AOwner); + foptionsfield:= defaultoptionsfield; +// FVisible:=True; + FValidChars:=[#0..#255]; + +// FProviderFlags := [pfInInsert,pfInUpdate,pfInWhere]; +end; + +destructor TField.Destroy; + +begin + IF Assigned(FDataSet) then + begin + FDataSet.Active:=False; + if Assigned(FFields) then + FFields.Remove(Self); + end; + FLookupList.Free; + Inherited Destroy; +end; + +function TField.AccessError(const TypeName: string): EDatabaseError; + +begin + Result:=EDatabaseError.CreateFmt(SinvalidTypeConversion,[TypeName,FFieldName]); +end; + +procedure TField.Assign(Source: TPersistent); + +begin + if Source = nil then Clear + else if Source is TField then begin + Value := TField(Source).Value; + end else + inherited Assign(Source); +end; + +procedure TField.AssignValue(const AValue: TVarRec); + procedure Error; + begin + DatabaseErrorFmt(SFieldValueError, [DisplayName]); + end; + +begin + with AValue do + case VType of + vtInteger: + AsInteger := VInteger; + vtBoolean: + AsBoolean := VBoolean; + vtChar: + AsString := VChar; + vtExtended: + AsFloat := VExtended^; + vtString: + AsString := VString^; + vtPointer: + if VPointer <> nil then Error; + vtPChar: + AsString := VPChar; + vtObject: + if (VObject = nil) or (VObject is TPersistent) then + Assign(TPersistent(VObject)) + else + Error; + vtAnsiString: + AsString := string(VAnsiString); + vtCurrency: + AsCurrency := VCurrency^; + vtVariant: + if not VarIsClear(VVariant^) then Self.Value := VVariant^; + vtWideString: + AsWideString := WideString(VWideString); + vtInt64: + AsLargeInt := VInt64^; + else + Error; + end; +end; + +procedure TField.Change; + +begin + If Assigned(FOnChange) Then + FOnChange(Self); +end; + +procedure TField.CheckInactive; + +begin + If Assigned(FDataSet) then + FDataset.CheckInactive; +end; + +procedure TField.Clear; + +begin + if FieldKind in [fkData, fkInternalCalc] then + SetData(Nil); +end; + +procedure TField.DataChanged; + +begin + FDataset.DataEvent(deFieldChange,ptrint(Self)); +end; + +procedure TField.FocusControl; +var + Field1: TField; +begin + Field1 := Self; + FDataSet.DataEvent(deFocusControl,ptrint(@Field1)); +end; + +procedure TField.FreeBuffers; + +begin + // Empty. Provided for backward compatibiliy; + // TDataset manages the buffers. +end; + +function TField.GetAsBCD: TBCD; +begin + raise AccessError(SBCD); +{$ifdef FPC} + result:= 0; //compiler warning +{$endif} +end; + +function TField.GetAsBoolean: Boolean; +begin + raise AccessError(SBoolean); + result:= false; //compiler warning +end; + +function TField.GetAsBytes: TBytes; +begin + SetLength(Result, DataSize); + if assigned(result) and not GetData(@Result[0], False) then + Result := nil; +end; + +function TField.GetAsDateTime: TDateTime; + +begin + raise AccessError(SdateTime); + result:= 0; //compiler warning +end; + +function TField.GetAsFloat: Double; + +begin + raise AccessError(SDateTime); + result:= 0; //compiler warning +end; + +function TField.GetAsLongint: Longint; + +begin + raise AccessError(SInteger); + result:= 0; //compiler warning +end; + +function TField.GetAsVariant: Variant; + +begin + raise AccessError(SVariant); + result:= 0; //compiler warning +end; + + +function TField.GetAsInteger: Integer; + +begin + Result:=GetAsLongint; +end; + +function TField.GetAsString: string; + +begin + Result := GetClassDesc; +end; + +function TField.GetAsWideString: WideString; +begin + Result := widestring(GetAsString); +end; + +function TField.GetOldValue: Variant; + +var SaveState : TDatasetState; + +begin + SaveState := FDataset.State; + try + FDataset.SetTempState(dsOldValue); + Result := GetAsVariant; + finally + FDataset.RestoreState(SaveState); + end; +end; + +function TField.GetNewValue: Variant; + +var SaveState : TDatasetState; + +begin + SaveState := FDataset.State; + try + FDataset.SetTempState(dsNewValue); + Result := GetAsVariant; + finally + FDataset.RestoreState(SaveState); + end; +end; + +procedure TField.SetNewValue(const AValue: Variant); + +var SaveState : TDatasetState; + +begin + SaveState := FDataset.State; + try + FDataset.SetTempState(dsNewValue); + SetAsVariant(AValue); + finally + FDataset.RestoreState(SaveState); + end; +end; + +function TField.GetCurValue: Variant; + +var SaveState : TDatasetState; + +begin + SaveState := FDataset.State; + try + FDataset.SetTempState(dsCurValue); + Result := GetAsVariant; + finally + FDataset.RestoreState(SaveState); + end; +end; + +function TField.GetCanModify: Boolean; + +begin + Result:=Not ReadOnly; + If Result then + begin + Result := FieldKind in [fkData, fkInternalCalc]; + if Result then + begin + Result:=Assigned(DataSet) and Dataset.Active; + If Result then + Result:= DataSet.CanModify; + end; + end; +end; + +function TField.GetClassDesc: String; +var ClassN : string; +begin + ClassN := copy(ClassName,2,pos('Field',ClassName)-2); + if isNull then + result := '(' + LowerCase(ClassN) + ')' + else + result := '(' + UpperCase(ClassN) + ')'; +end; + +function TField.GetData(Buffer: Pointer): Boolean; + +begin + Result:=GetData(Buffer,True); +end; + +function TField.GetData(Buffer: Pointer; NativeFormat : Boolean): Boolean; + +begin + IF FDataset=Nil then + DatabaseErrorFmt(SNoDataset,[FieldName]); + If FVAlidating then + begin + result:=assigned(FValueBuffer); + If Result and assigned(Buffer) then + Move (FValueBuffer^,Buffer^ ,DataSize); + end + else + Result:=FDataset.GetFieldData(Self,Buffer,NativeFormat); +end; + +function TField.GetDataSize: Integer; + +begin + Result:=0; +end; + +function TField.GetDefaultWidth: Longint; + +begin + Result:=10; +end; + +function TField.GetDisplayName : String; + +begin + If FDisplayLabel<>'' then + result:=FDisplayLabel + else + Result:=FFieldName; +end; + +Function TField.IsDisplayStored : Boolean; + +begin + Result:=(DisplayLabel<>FieldName); +end; + +function TField.GetLookupList: TLookupList; +begin + if not Assigned(FLookupList) then + FLookupList := TLookupList.Create; + Result := FLookupList; +end; + +procedure TField.CalcLookupValue; +begin + if FLookupCache then + Value := LookupList.ValueOfKey(FDataSet.FieldValues[FKeyFields]) + else if Assigned(FLookupDataSet) and FDataSet.Active then + Value := FLookupDataSet.Lookup(FLookupKeyfields, FDataSet.FieldValues[FKeyFields], FLookupresultField); +end; + +function TField.getIndex : longint; + +begin + If Assigned(FDataset) then + Result:=FDataset.FFieldList.IndexOf(Self) + else + Result:=-1; +end; + +function TField.GetLookup: Boolean; +begin + Result := FieldKind = fkLookup; +end; + +function TField.GetAsLargeInt: LargeInt; +begin + Raise AccessError(SLargeInt); + result:= 0; //compiler warning +end; + +function TField.GetAsCurrency: Currency; +begin + Result := GetAsFloat; +end; + +procedure TField.SetAlignment(const AValue: TAlignMent); +begin + if FAlignment <> AValue then + begin + FAlignment := Avalue; + PropertyChanged(false); + end; +end; + +procedure TField.SetIndex(const AValue: Integer); +begin + if FFields <> nil then FFields.SetFieldIndex(Self, AValue) +end; + +procedure TField.SetAsCurrency(AValue: Currency); +begin + SetAsFloat(AValue); +end; + +function TField.GetIsNull: Boolean; + +begin + Result:=Not(GetData (Nil)); +end; + +function TField.GetParentComponent: TComponent; + +begin + Result := DataSet; +end; + +procedure TField.GetText(var AText: string; ADisplayText: Boolean); + +begin + AText:=GetAsString; +end; + +function TField.HasParent: Boolean; + +begin + HasParent:=True; +end; + +function TField.IsValidChar(InputChar: Char): Boolean; + +begin + // FValidChars must be set in Create. + Result:=InputChar in FValidChars; +end; + +procedure TField.RefreshLookupList; +var + tmpActive: Boolean; +begin + if not Assigned(FLookupDataSet) or (Length(FLookupKeyfields) = 0) + or (Length(FLookupresultField) = 0) or (Length(FKeyFields) = 0) then + Exit; + + tmpActive := FLookupDataSet.Active; + try + FLookupDataSet.Active := True; + FFields.CheckFieldNames(FKeyFields); + FLookupDataSet.Fields.CheckFieldNames(FLookupKeyFields); + FLookupDataset.FieldByName(FLookupResultField); // I presume that if it doesn't exist it throws exception, and that a field with null value is still valid + LookupList.Clear; // have to be F-less because we might be creating it here with getter! + + FLookupDataSet.DisableControls; + try + FLookupDataSet.First; + while not FLookupDataSet.Eof do + begin + FLookupList.Add(FLookupDataSet.FieldValues[FLookupKeyfields], FLookupDataSet.FieldValues[FLookupResultField]); + FLookupDataSet.Next; + end; + finally + FLookupDataSet.EnableControls; + end; + finally + FLookupDataSet.Active := tmpActive; + end; +end; + +procedure TField.Notification(AComponent: TComponent; Operation: TOperation); + +begin + Inherited Notification(AComponent,Operation); + if (Operation = opRemove) and (AComponent = FLookupDataSet) then + FLookupDataSet := nil; +end; + +procedure TField.PropertyChanged(LayoutAffected: Boolean); + +begin + If (FDataset<>Nil) and (FDataset.Active) then + If LayoutAffected then + FDataset.DataEvent(deLayoutChange,0) + else + FDataset.DataEvent(deDatasetchange,0); +end; + +procedure TField.ReadState(Reader: TReader); + +begin + inherited ReadState(Reader); + if Reader.Parent is TDataSet then + DataSet := TDataSet(Reader.Parent); +end; + +procedure TField.SetAsBCD(const AValue: TBCD); +begin + Raise AccessError(SBCD); +end; + +procedure TField.SetAsBytes(const AValue: TBytes); +begin + raise AccessError(SBytes); +end; + +procedure TField.SetAsBoolean(AValue: Boolean); + +begin + Raise AccessError(SBoolean); +end; + +procedure TField.SetAsDateTime(AValue: TDateTime); + +begin + Raise AccessError(SDateTime); +end; + +function TField.getasdate: tdatetime; +begin + raise accesserror(sdatetime); + result:= 0; //compiler warning +end; + +function TField.getastime: tdatetime; +begin + raise accesserror(sdatetime); + result:= 0; //compiler warning +end; + +procedure TField.setasdate(avalue: tdatetime); +begin + raise accesserror(sdatetime); +end; + +procedure TField.setastime(avalue: tdatetime); +begin + raise accesserror(sdatetime); +end; + +procedure TField.SetAsFloat(AValue: Double); + +begin + Raise AccessError(SFloat); +end; + +procedure TField.SetAsVariant(const AValue: Variant); + +begin + if VarIsNull(AValue) then + Clear + else + try + SetVarValue(AValue); + except + on EVariantError do DatabaseErrorFmt(SFieldValueError, [DisplayName]); + end; +end; + + +procedure TField.SetAsLongint(AValue: Longint); + +begin + Raise AccessError(SInteger); +end; + +procedure TField.SetAsInteger(AValue: Integer); + +begin + SetAsLongint(AValue); +end; + +procedure TField.SetAsLargeint(AValue: Largeint); +begin + Raise AccessError(SLargeInt); +end; + +procedure TField.SetAsString(const AValue: string); + +begin + Raise AccessError(SString); +end; + +procedure TField.SetAsWideString(const aValue: WideString); +begin + SetAsString(ansistring(aValue)); +end; + +function TField.getasguid: tguid; +begin + result:= stringtoguid(asstring); +end; + +procedure TField.setasguid(const avalue: tguid); +begin + asstring:= guidtostring(avalue); +end; + +procedure TField.SetData(Buffer: Pointer); + +begin + SetData(Buffer,True); +end; + +procedure TField.SetData(Buffer: Pointer; NativeFormat : Boolean); + +begin + If Not Assigned(FDataset) then + DatabaseErrorFmt(SNoDataset,[FieldName]); + FDataSet.SetFieldData(Self,Buffer, NativeFormat); +end; + +Procedure TField.SetDataset (AValue : TDataset); + +begin +{$ifdef dsdebug} + Writeln ('Setting dataset'); +{$endif} + If AValue=FDataset then exit; + If Assigned(FDataset) Then + begin + FDataset.CheckInactive; + FDataset.FFieldList.Remove(Self); + end; + If Assigned(AValue) then + begin + AValue.CheckInactive; + AValue.FFieldList.Add(Self); + end; + FDataset:=AValue; +end; + +procedure TField.SetDataType(AValue: TFieldType); + +begin + FDataType := AValue; +end; + +procedure TField.SetFieldType(AValue: TFieldType); + +begin + { empty } +end; + +procedure TField.SetParentComponent(AParent: TComponent); + +begin + if not (csLoading in ComponentState) then + DataSet := AParent as TDataSet; +end; + +procedure TField.SetSize(AValue: Integer); + +begin + CheckInactive; + CheckTypeSize(AValue); + FSize:=AValue; +end; + +procedure TField.SetText(const AValue: string); + +begin + AsString:=AValue; +end; + +procedure TField.SetVarValue(const AValue: Variant); +begin + Raise AccessError(SVariant); +end; + +procedure TField.Validate(Buffer: Pointer); + +begin + If assigned(OnValidate) Then + begin + FValueBuffer:=Buffer; + FValidating:=True; + Try + OnValidate(Self); + finally + FValidating:=False; + end; + end; +end; + +class function Tfield.IsBlob: Boolean; + +begin + Result:=False; +end; + +class procedure TField.CheckTypeSize(AValue: Longint); + +begin + If (AValue<>0) and Not IsBlob Then + DatabaseErrorFmt(SInvalidFieldSize,[AValue]); +end; + +// TField private methods + +procedure TField.SetEditText(const AValue: string); +begin + if Assigned(OnSetText) then + OnSetText(Self, AValue) + else + SetText(AValue); +end; + +function TField.getdisplaylabel(): utf8string; +begin + result:= getdisplayname(); +end; + +function TField.GetEditText: String; +begin + SetLength(Result, 0); + if Assigned(OnGetText) then + OnGetText(Self, Result, False) + else + GetText(Result, False); +end; + +function TField.GetDisplayText: String; +begin + SetLength(Result, 0); + if Assigned(OnGetText) then + OnGetText(Self, Result, True) + else + GetText(Result, True); +end; + +procedure TField.SetDisplayLabel(const AValue: utf8string); +begin + if FDisplayLabel<>Avalue then + begin + FDisplayLabel:=Avalue; + PropertyChanged(true); + end; +end; + +procedure TField.SetDisplayWidth(const AValue: Longint); +begin + if FDisplayWidth<>AValue then + begin + FDisplayWidth:=AValue; + PropertyChanged(True); + end; +end; + +function TField.GetDisplayWidth: integer; +begin + if FDisplayWidth=0 then + result:=GetDefaultWidth + else + result:=FDisplayWidth; +end; + +procedure TField.SetLookup(const AValue: Boolean); +const + ValueToLookupMap: array[Boolean] of TFieldKind = (fkData, fkLookup); +begin + FieldKind := ValueToLookupMap[AValue]; +end; + +function TField.getasunicodestring: unicodestring; +begin + result:= unicodestring(getasstring); +end; + +procedure TField.setasunicodestring(const avalue: unicodestring); +begin + setasstring(ansistring(avalue)); +end; + +const + allproviderflags = [pfInUpdate, pfInWhere, pfInKey, pfHidden]; + allprovideroptions = [of_ininsert,of_InUpdate, of_InWhere, of_InKey, + of_Hidden]; + providerflagsshift = ord(of_inupdate); + +function TField.getProviderFlags: TProviderFlags; +begin +{$push}{$warnings off} + result:= tproviderflags(integer(foptionsfield) shr providerflagsshift) * + allproviderflags; +{$pop} +end; + +procedure TField.setoptionsfield(const avalue: optionsfieldty); +var + optcha: optionsfieldty; +begin + optcha:= (foptionsfield >< avalue) * [of_readonly,of_visible]; + foptionsfield:= avalue; + if optcha <> [] then begin + PropertyChanged(True); + end; +end; + +procedure TField.setlookupdataset(const avalue: tdataset); +begin + if flookupdataset <> nil then begin + flookupdataset.removefreenotification(self); + end; + flookupdataset:= avalue; + if flookupdataset <> nil then begin + flookupdataset.freenotification(self); + end; +end; + +function TField.getbuffervalue: variant; +var + bo1: boolean; +begin + bo1:= fvalidating; + try + fvalidating:= false; + result:= getasvariant(); + finally + fvalidating:= bo1; + end; +end; + +function tfield.getasid: int64; +begin + if isnull then begin + result:= -1; + end + else begin + result:= aslargeint; + end; +end; + +procedure tfield.setasid(const avalue: int64); +begin + if avalue = -1 then begin + clear; + end + else begin + aslargeint:= avalue; + end; +end; + +procedure TField.setProviderFlags(const avalue: TProviderFlags); +begin + foptionsfield:= (foptionsfield - allprovideroptions) + + optionsfieldty(integer(avalue) shl providerflagsshift); + if pfinupdate in avalue then begin + include(foptionsfield,of_ininsert); + end + else begin + exclude(foptionsfield,of_ininsert); + end; +end; + +function TField.getReadOnly: Boolean; +begin + result:= of_readonly in foptionsfield; +end; + +procedure TField.SetReadOnly(const AValue: Boolean); +begin + if avalue then begin + optionsfield:= optionsfield + [of_readonly]; + end + else begin + optionsfield:= optionsfield - [of_readonly]; + end; +end; + +function TField.getRequired: Boolean; +begin + result:= of_required in foptionsfield; +end; + +procedure TField.setRequired(const avalue: Boolean); +begin + if avalue then begin + include(foptionsfield,of_required); + end + else begin + exclude(foptionsfield,of_required); + end; +end; + +function TField.getVisible: Boolean; +begin + result:= of_visible in foptionsfield; +end; + +procedure TField.SetVisible(const AValue: Boolean); +begin + if avalue then begin + optionsfield:= optionsfield + [of_visible]; + end + else begin + optionsfield:= optionsfield - [of_visible]; + end; +end; + +procedure TField.readproviderflags(reader: treader); +begin +{$push}{$warnings off} + providerflags:= tproviderflags(reader.readset(typeinfo(tproviderflags))); +{$pop} +end; + +type + providerflag1ty = (pf1_refreshinsert,pf1_refreshupdate,pf1_nocopyrecord); + providerflags1ty = set of providerflag1ty; + +procedure TField.readproviderflags1(reader: treader); +var + flags: providerflags1ty; +begin + flags:= providerflags1ty(reader.readset(typeinfo(providerflags1ty))); + foptionsfield:= foptionsfield - + [of_refreshinsert,of_refreshupdate,of_nocopyrecord]; + if pf1_refreshinsert in flags then begin + include(foptionsfield,of_refreshinsert); + end; + if pf1_refreshupdate in flags then begin + include(foptionsfield,of_refreshupdate); + end; + if pf1_nocopyrecord in flags then begin + include(foptionsfield,of_nocopyrecord); + end; +end; + +procedure TField.readrequired(reader: treader); +begin + required:= reader.readboolean(); +end; + +procedure TField.readvisible(reader: treader); +begin + visible:= reader.readboolean(); +end; + +procedure TField.readreadonly(reader: treader); +begin + readonly:= reader.readboolean(); +end; + +procedure TField.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('Required',@readrequired,nil,false); + filer.defineproperty('Visible',@readvisible,nil,false); + filer.defineproperty('ReadOnly',@readreadonly,nil,false); + filer.defineproperty('ProviderFlags',@readproviderflags,nil,false); + filer.defineproperty('providerflags1',@readproviderflags1,nil,false); +end; + +procedure TField.dosetvalue(const sender: tobject; var avalue: int32; + var accept: boolean); +begin + //dummy +end; + +procedure TField.dosetvalue(const sender: tobject; var avalue: int64; + var accept: boolean); +begin + //dummy +end; + +procedure TField.dosetvalue(const sender: tobject; var avalue: currency; + var accept: boolean); +begin + //dummy +end; + +procedure TField.dosetvalue(const sender: tobject; var avalue: flo64; + var accept: boolean); +begin + //dummy +end; + +procedure TField.dosetvalue(const sender: tobject; var avalue: msestring; + var accept: boolean); +begin + //dummy +end; + +procedure TField.dosetvalue(const sender: tobject; var avalue: ansistring; + var accept: boolean); +begin + //dummy +end; + +procedure TField.dodataentered(const sender: tobject); +begin + if assigned(fondataentered) then begin + fondataentered(self,sender); + end; +end; + +{ --------------------------------------------------------------------- + TStringField + ---------------------------------------------------------------------} + + +constructor TStringField.Create(AOwner: TComponent); + +begin + Inherited Create(AOwner); + SetDataType(ftString); + FFixedChar := False; + FTransliterate := False; + FSize:=20; +end; + +procedure TStringField.SetFieldType(AValue: TFieldType); +begin + if avalue in [ftString, ftFixedChar] then + SetDataType(AValue); +end; + +class procedure TStringField.CheckTypeSize(AValue: Longint); + +begin +// A size of 0 is allowed, since for example Firebird allows +// a query like: 'select '' as fieldname from table' which +// results in a string with size 0. + If (AValue<0) Then + databaseErrorFmt(SInvalidFieldSize,[AValue]) +end; + +function TStringField.GetAsBoolean: Boolean; + +Var S : String; + +begin + S:=GetAsString; + result := (Length(S)>0) and (Upcase(S[1]) in ['T',YesNoChars[True]]); +end; + +function TStringField.GetAsDateTime: TDateTime; + +begin + Result:=StrToDateTime(GetAsString); +end; + +function TStringField.GetAsFloat: Double; + +begin + Result:=StrToFloat(GetAsString); +end; + +function TStringField.GetAsLongint: Longint; + +begin + Result:=StrToInt(GetAsString); +end; + +function TStringField.GetAsString: string; + +begin + If Not GetValue(Result) then + Result:=''; +end; + +function TStringField.GetAsVariant: Variant; + +Var s : string; + +begin + If GetValue(s) then + Result:=s + else + Result:=Null; +end; + + +function TStringField.GetDataSize: Integer; + +begin + Result:=Size+1; +end; + +function TStringField.GetDefaultWidth: Longint; + +begin + result:=Size; +end; + +Procedure TStringField.GetText(var AText: string; ADisplayText: Boolean); + +begin + AText:=GetAsString; +end; + +function TStringField.GetValue(var AValue: string): Boolean; + +Var Buf, TBuf : TStringFieldBuffer; + DynBuf, TDynBuf : Array of char; + +begin + if DataSize <= dsMaxStringSize then + begin + Result:=GetData(@Buf); + buf[Size]:=#0; //limit string to Size + If Result then + begin + if transliterate then + begin +{$warnings off} + DataSet.Translate(Buf,TBuf,False); + AValue:=TBuf; + end + else + AValue:=Buf + end + end + else + begin + SetLength(DynBuf,DataSize); + Result:=GetData(@DynBuf[0]); + Dynbuf[Size]:=#0; //limit string to Size + If Result then + begin + if transliterate then + begin + SetLength(TDynBuf,DataSize); + DataSet.Translate(@DynBuf[0],@TDynBuf[0],False); + AValue:=pchar(TDynBuf); + end + else + AValue:=pchar(DynBuf); + end + end; +end; +{$warnings on} + +procedure TStringField.SetAsBoolean(AValue: Boolean); + +begin + If AValue Then + SetAsString('T') + else + SetAsString('F'); +end; + +procedure TStringField.SetAsDateTime(AValue: TDateTime); + +begin + SetAsString(DateTimeToStr(AValue)); +end; + +procedure TStringField.SetAsFloat(AValue: Double); + +begin + SetAsString(FloatToStr(AValue)); +end; + +procedure TStringField.SetAsLongint(AValue: Longint); + +begin + SetAsString(intToStr(AValue)); +end; + +procedure TStringField.SetAsString(const AValue: string); + +var Buf : TStringFieldBuffer; + +begin + IF Length(AValue)=0 then + begin + Buf := #0; + SetData(@buf); + end + else if FTransliterate then + begin +{$warnings off} + DataSet.Translate(@AValue[1],Buf,True); + Buf[DataSize-1] := #0; + SetData(@buf); + end + else + begin + // The data is copied into the buffer, since some TDataset descendents copy + // the whole buffer-length in SetData. (See bug 8477) +{$ifdef FPC} + Buf := AValue; +{$else} + copycharbuf(avalue,sizeof(buf),buf); +{$endif} + // If length(AValue) > Datasize the buffer isn't terminated properly + Buf[DataSize-1] := #0; + SetData(@Buf); + end; +end; +{$warnings on} + +procedure TStringField.SetVarValue(const AValue: Variant); +begin + SetAsString(AValue); +end; + +procedure TStringField.dosetvalue(const sender: tobject; var avalue: ansistring; + var accept: boolean); +begin + if assigned(fonsetvalue) then begin + fonsetvalue(self,sender,avalue,accept); + end; +end; + +{ --------------------------------------------------------------------- + TWideStringField + ---------------------------------------------------------------------} + +class procedure TWideStringField.CheckTypeSize(aValue: Integer); +begin +// A size of 0 is allowed, since for example Firebird allows +// a query like: 'select '' as fieldname from table' which +// results in a string with size 0. + If (AValue<0) Then + databaseErrorFmt(SInvalidFieldSize,[AValue]); +end; + +constructor TWideStringField.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + SetDataType(ftWideString); +end; + +procedure TWideStringField.SetFieldType(AValue: TFieldType); +begin + if avalue in [ftWideString, ftFixedWideChar] then + SetDataType(AValue); +end; + +function TWideStringField.GetValue(var aValue: WideString): Boolean; +var + FixBuffer : array[0..dsMaxStringSize div 2] of WideChar; + DynBuffer : array of WideChar; + Buffer : PWideChar; +begin + if DataSize <= dsMaxStringSize then begin + Result := GetData(@FixBuffer, False); + FixBuffer[Size]:=#0; //limit string to Size + aValue := FixBuffer; + end else begin + SetLength(DynBuffer, Succ(Size)); + Buffer := PWideChar(DynBuffer); + Result := GetData(Buffer, False); + Buffer[Size]:=#0; //limit string to Size + if Result then + aValue := Buffer; + end; +end; + +function TWideStringField.GetAsString: string; +begin + Result := ansistring(GetAsWideString); +end; + +procedure TWideStringField.SetAsString(const aValue: string); +begin + SetAsWideString(widestring(aValue)); +end; + +function twidestringfield.getasunicodestring: unicodestring; +begin + result:= getaswidestring; +end; + +procedure twidestringfield.setasunicodestring(const avalue: unicodestring); +begin + setaswidestring(avalue); +end; + +function TWideStringField.GetAsVariant: Variant; +var + ws: WideString; +begin + if GetValue(ws) then + Result := ws + else + Result := Null; +end; + +procedure TWideStringField.SetVarValue(const aValue: Variant); +begin + SetAsWideString(aValue); +end; + +function TWideStringField.GetAsWideString: WideString; +begin + if not GetValue(Result) then + Result := ''; +end; + +procedure TWideStringField.SetAsWideString(const aValue: WideString); +const + NullWideChar : WideChar = #0; +var + Buffer : PWideChar; +begin + if Length(aValue)>0 then + Buffer := PWideChar(@aValue[1]) + else + Buffer := @NullWideChar; + SetData(Buffer, False); +end; + +function TWideStringField.GetDataSize: Integer; +begin + Result := + (Size + 1) * 2; +end; + + +{ --------------------------------------------------------------------- + TNumericField + ---------------------------------------------------------------------} + + +constructor TNumericField.Create(AOwner: TComponent); + +begin + Inherited Create(AOwner); + AlignMent:=taRightJustify; +end; + +class procedure TNumericField.CheckTypeSize(AValue: Longint); +begin + // This procedure is only added because some TDataset descendents have the + // but that they set the Size property as if it is the DataSize property. + // To avoid problems with those descendents, allow values <= 16. + If (AValue>16) Then + DatabaseErrorFmt(SInvalidFieldSize,[AValue]); +end; + +procedure TNumericField.RangeError(AValue, Min, Max: Double); + +begin + DatabaseErrorFMT(SRangeError,[AValue,Min,Max,FieldName]); +end; + +procedure TNumericField.SetDisplayFormat(const AValue: utf8string); + +begin + If FDisplayFormat<>AValue then + begin + FDisplayFormat:=AValue; + PropertyChanged(True); + end; +end; + +procedure TNumericField.SetEditFormat(const AValue: utf8string); + +begin + If FEDitFormat<>AValue then + begin + FEDitFormat:=AVAlue; + PropertyChanged(True); + end; +end; + +function TNumericField.GetAsBoolean: Boolean; +begin + Result:=GetAsInteger<>0; +end; + +procedure TNumericField.SetAsBoolean(AValue: Boolean); +begin + if AValue then + SetAsLongint(1) + else + SetAsLongint(0); +end; + +{ --------------------------------------------------------------------- + TLongintField + ---------------------------------------------------------------------} + + +constructor TLongintField.Create(AOwner: TComponent); + +begin + Inherited Create(AOwner); + SetDatatype(ftinteger); + FMinRange:=Low(LongInt); + FMaxRange:=High(LongInt); + FValidchars:=['+','-','0'..'9']; +end; + +function TLongintField.GetAsFloat: Double; + +begin + Result:=GetAsLongint; +end; + +function TLongintField.GetAsLargeint: Largeint; +begin + Result:=GetAsLongint; +end; + +function TLongintField.GetAsLongint: Longint; + +begin + If Not GetValue(Result) then + Result:=0; +end; + +function TLongintField.GetAsVariant: Variant; + +Var L : Longint; + +begin + If GetValue(L) then + Result:=L + else + Result:=Null; +end; + +function TLongintField.GetAsString: string; + +Var L : Longint; + +begin + If GetValue(L) then + Result:=IntTostr(L) + else + Result:=''; +end; + +function TLongintField.GetDataSize: Integer; + +begin + Result:=SizeOf(Longint); +end; + +procedure TLongintField.GetText(var AText: string; ADisplayText: Boolean); + +var l : longint; + fmt : string; + +begin + Atext:=''; + If Not GetValue(l) then exit; + If ADisplayText or (FEditFormat='') then + fmt:=FDisplayFormat + else + fmt:=FEditFormat; + If length(fmt)<>0 then + AText:=FormatFloat(fmt,L) + else + Str(L,AText); +end; + +function TLongintField.GetValue(var AValue: Longint): Boolean; + +Var L : Longint; + P : PLongint; + +begin + P:=@L; + Result:=GetData(P); + If Result then + Case Datatype of + ftInteger,ftautoinc : AValue:=Plongint(P)^; + ftword : Avalue:=Pword(P)^; + ftsmallint : AValue:=PSmallint(P)^; + end; +end; + +procedure TLongintField.SetAsLargeint(AValue: Largeint); +begin + if (AValue>=FMinRange) and (AValue<=FMaxRange) then + SetAsLongint(AValue) + else + RangeError(AValue,FMinRange,FMaxRange); +end; + +procedure TLongintField.dosetvalue(const sender: tobject; var avalue: int32; + var accept: boolean); +begin + if assigned(fonsetvalue) then begin + fonsetvalue(self,sender,avalue,accept); + end; +end; + +procedure TLongintField.SetAsFloat(AValue: Double); + +begin + SetAsLongint(Round(Avalue)); +end; + +procedure TLongintField.SetAsLongint(AValue: Longint); + +begin + If CheckRange(AValue) then + SetData(@AValue) + else + RangeError(Avalue,FMinrange,FMaxRange); +end; + +procedure TLongintField.SetVarValue(const AValue: Variant); +begin + SetAsLongint(AValue); +end; + +procedure TLongintField.SetAsString(const AValue: string); + +Var L,Code : longint; + +begin + If length(AValue)=0 then + Clear + else + begin + Val(AVAlue,L,Code); + If Code=0 then + SetAsLongint(L) + else + DatabaseErrorFMT(SNotAnInteger,[Avalue]); + end; +end; + +Function TLongintField.CheckRange(AValue : longint) : Boolean; + +begin + result := true; + if (FMaxValue=0) then + begin + if (AValue>FMaxRange) Then result := false; + end + else + if AValue>FMaxValue then result := false; + + if (FMinValue=0) then + begin + if (AValue=FMinRange) and (AValue<=FMaxRange) then + FMaxValue:=AValue + else + RangeError(AValue,FMinRange,FMaxRange); +end; + +Procedure TLongintField.SetMinValue (AValue : longint); + +begin + If (AValue>=FMinRange) and (AValue<=FMaxRange) then + FMinValue:=AValue + else + RangeError(AValue,FMinRange,FMaxRange); +end; + +{ --------------------------------------------------------------------- + TLargeintField + ---------------------------------------------------------------------} + + +constructor TLargeintField.Create(AOwner: TComponent); + +begin + Inherited Create(AOwner); + SetDatatype(ftLargeint); + FMinRange:=Low(Largeint); + FMaxRange:=High(Largeint); + FValidchars:=['+','-','0'..'9']; +end; + +function TLargeintField.GetAsFloat: Double; + +begin + Result:=GetAsLargeint; +end; + +function TLargeintField.GetAsLargeint: Largeint; + +begin + If Not GetValue(Result) then + Result:=0; +end; + +function TLargeIntField.GetAsVariant: Variant; + +Var L : Largeint; + +begin + If GetValue(L) then + Result:=L + else + Result:=Null; +end; + +function TLargeintField.GetAsLongint: Longint; + +begin + Result:=GetAsLargeint; +end; + +function TLargeintField.GetAsString: string; + +Var L : Largeint; + +begin + If GetValue(L) then + Result:=IntTostr(L) + else + Result:=''; +end; + +function TLargeintField.GetDataSize: Integer; + +begin + Result:=SizeOf(Largeint); +end; + +procedure TLargeintField.GetText(var AText: string; ADisplayText: Boolean); + +var l : largeint; + fmt : string; + +begin + Atext:=''; + If Not GetValue(l) then exit; + If ADisplayText or (FEditFormat='') then + fmt:=FDisplayFormat + else + fmt:=FEditFormat; + If length(fmt)<>0 then + AText:=FormatFloat(fmt,L) + else + Str(L,AText); +end; + +function TLargeintField.GetValue(var AValue: Largeint): Boolean; + +type + PLargeint = ^Largeint; + +Var P : PLargeint; + +begin + P:=@AValue; + Result:=GetData(P); +end; + +procedure TLargeintField.SetAsFloat(AValue: Double); + +begin + SetAsLargeint(Round(Avalue)); +end; + +procedure TLargeintField.SetAsLargeint(AValue: Largeint); + +begin + If CheckRange(AValue) then + SetData(@AValue) + else + RangeError(Avalue,FMinrange,FMaxRange); +end; + +procedure TLargeintField.SetAsLongint(AValue: Longint); + +begin + SetAsLargeint(Avalue); +end; + +procedure TLargeintField.SetAsString(const AValue: string); + +Var L : largeint; + code : longint; + +begin + If length(AValue)=0 then + Clear + else + begin + Val(AVAlue,L,Code); + If Code=0 then + SetAsLargeint(L) + else + DatabaseErrorFMT(SNotAnInteger,[Avalue]); + end; +end; + +procedure TLargeintField.SetVarValue(const AValue: Variant); +begin + SetAsLargeint(AValue); +end; + +procedure TLargeintField.dosetvalue(const sender: tobject; var avalue: int64; + var accept: boolean); +begin + if assigned(fonsetvalue) then begin + fonsetvalue(self,sender,avalue,accept); + end; +end; + +Function TLargeintField.CheckRange(AValue : largeint) : Boolean; + +begin + result := true; + if (FMaxValue=0) then + begin + if (AValue>FMaxRange) Then result := false; + end + else + if AValue>FMaxValue then result := false; + + if (FMinValue=0) then + begin + if (AValue=FMinRange) and (AValue<=FMaxRange) then + FMaxValue:=AValue + else + RangeError(AValue,FMinRange,FMaxRange); +end; + +Procedure TLargeintField.SetMinValue (AValue : largeint); + +begin + If (AValue>=FMinRange) and (AValue<=FMaxRange) then + FMinValue:=AValue + else + RangeError(AValue,FMinRange,FMaxRange); +end; + +{ TSmallintField } + +function TSmallintField.GetDataSize: Integer; + +begin + Result:=SizeOf(SmallInt); +end; + +constructor TSmallintField.Create(AOwner: TComponent); + +begin + inherited Create(AOwner); + SetDataType(ftSmallInt); + FMinRange:=-32768; + FMaxRange:=32767; +end; + + +{ TWordField } + +function TWordField.GetDataSize: Integer; + +begin + Result:=SizeOf(Word); +end; + +constructor TWordField.Create(AOwner: TComponent); + +begin + inherited Create(AOwner); + SetDataType(ftWord); + FMinRange:=0; + FMaxRange:=65535; + FValidchars:=['+','0'..'9']; +end; + +{ TAutoIncField } + +constructor TAutoIncField.Create(AOwner: TComponent); + +begin + Inherited Create(AOWner); + SetDataType(ftAutoInc); + foptionsfield:= (foptionsfield + [of_readonly]) - [of_ininsert,of_inupdate]; +// FReadOnly:=True; +// FProviderFlags:=FProviderFlags-[pfInUpdate]; +end; + +Procedure TAutoIncField.SetAsLongint(AValue : Longint); + +begin + // Some databases allows insertion of explicit values into identity columns + // (some of them also allows (some not) updating identity columns) + // So allow it at client side and leave check for server side + if not(FDataSet.State in [dsFilter,dsSetKey,dsInsert]) then + DataBaseError(SCantSetAutoIncFields); + inherited; +end; + +{ TFloatField } + +procedure TFloatField.SetCurrency(const AValue: Boolean); +begin + if FCurrency=AValue then exit; + FCurrency:=AValue; +end; + +procedure TFloatField.SetPrecision(const AValue: Longint); +begin + if (AValue = -1) or (AValue > 1) then + FPrecision := AValue + else + FPrecision := 2; +end; + +function TFloatField.GetAsFloat: Double; + +begin + If Not GetData(@Result) Then + Result:=0.0; +end; + +function TFloatField.GetAsVariant: Variant; + +Var f : Double; + +begin + If GetData(@f) then + Result := f + else + Result:=Null; +end; + +function TFloatField.GetAsLongint: Longint; + +begin + Result:=Round(GetAsFloat); +end; + +function TFloatField.GetAsString: string; + +Var R : Double; + +begin + If GetData(@R) then + Result:=FloatToStr(R) + else + Result:=''; +end; + +function TFloatField.GetDataSize: Integer; + +begin + Result:=SizeOf(Double); +end; + +procedure TFloatField.GetText(var TheText: string; ADisplayText: Boolean); + +Var + fmt : string; + E : Double; + Digits : integer; + ff: TFloatFormat; + +begin + TheText:=''; + If Not GetData(@E) then exit; + If ADisplayText or (Length(FEditFormat) = 0) Then + Fmt:=FDisplayFormat + else + Fmt:=FEditFormat; + + Digits := 0; + if not FCurrency then + ff := ffGeneral + else + begin + Digits := {$ifdef FPC}defaultformatsettings.{$endif}CurrencyDecimals; + if ADisplayText then + ff := ffCurrency + else + ff := ffFixed; + end; + + + If fmt<>'' then + TheText:=FormatFloat(fmt,E) + else + TheText:=FloatToStrF(E,ff,FPrecision,Digits); +end; + +procedure TFloatField.SetAsFloat(AValue: Double); + +begin + If CheckRange(AValue) then + SetData(@Avalue) + else + RangeError(AValue,FMinValue,FMaxValue); +end; + +procedure TFloatField.SetAsLongint(AValue: Longint); + +begin + SetAsFloat(Avalue); +end; + +procedure TFloatField.SetAsString(const AValue: string); + +Var R : Double; + +begin + If (AValue='') then + Clear + else + try + R := StrToFloat(AValue); + SetAsFloat(R); + except + DatabaseErrorFmt(SNotAFloat, [AValue]); + end; +end; + +procedure TFloatField.SetVarValue(const AValue: Variant); +begin + SetAsFloat(Avalue); +end; + +procedure TFloatField.dosetvalue(const sender: tobject; var avalue: flo64; + var accept: boolean); +begin + if assigned(fonsetvalue) then begin + fonsetvalue(self,sender,avalue,accept); + end; +end; + +constructor TFloatField.Create(AOwner: TComponent); + +begin + Inherited Create(AOwner); + SetDatatype(ftfloat); + FPrecision:=15; + FValidChars := [{$ifdef FPC}defaultformatsettings.{$endif}DecimalSeparator, + '+', '-', '0'..'9', 'E', 'e']; +end; + +Function TFloatField.CheckRange(AValue : Double) : Boolean; + +begin + If (FMinValue<>0) or (FmaxValue<>0) then + Result:=(AValue>=FMinValue) and (AVAlue<=FMAxValue) + else + Result:=True; +end; + +{ TCurrencyField } + +Constructor TCurrencyField.Create(AOwner: TComponent); + +begin + inherited Create(AOwner); + SetDataType(ftCurrency); + Currency := True; +end; + +{ TBooleanField } + +function TBooleanField.GetAsBoolean: Boolean; + +var b : wordbool; + +begin + If GetData(@b) then + result := b + else + Result:=False; +end; + +function TBooleanField.GetAsVariant: Variant; + +Var b : wordbool; + +begin + If GetData(@b) then + Result := b + else + Result:=Null; +end; + +function TBooleanField.GetAsString: string; + +Var B : wordbool; + +begin + If Getdata(@B) then + Result:=FDisplays[False,B] + else + result:=''; +end; + +function TBooleanField.GetDataSize: Integer; + +begin + Result:=SizeOf(wordBool); +end; + +function TBooleanField.GetDefaultWidth: Longint; + +begin + Result:=Length(FDisplays[false,false]); + If Result0); +end; + +procedure TBooleanField.SetAsBoolean(AValue: Boolean); + +var b : wordbool; + +begin + b := AValue; + SetData(@b); +end; + +procedure TBooleanField.SetAsString(const AValue: string); + +Var Temp : string; + +begin + Temp:=UpperCase(AValue); + if Temp='' then + Clear + else if pos(Temp, FDisplays[True,True])=1 then + SetAsBoolean(True) + else if pos(Temp, FDisplays[True,False])=1 then + SetAsBoolean(False) + else + DatabaseErrorFmt(SNotABoolean,[AValue]); +end; + +procedure TBooleanField.SetVarValue(const AValue: Variant); +begin + SetAsBoolean(AValue); +end; + +constructor TBooleanField.Create(AOwner: TComponent); + +begin + Inherited Create(AOwner); + SetDataType(ftBoolean); + DisplayValues:='True;False'; +end; + +Procedure TBooleanField.SetDisplayValues(const AValue : String); + +Var I : longint; + +begin + If FDisplayValues<>AValue then + begin + I:=Pos(';',AValue); + If (I<2) or (I=Length(AValue)) then + DatabaseErrorFmt(SInvalidDisplayValues,[AValue]); + FdisplayValues:=AValue; + // Store display values and their uppercase equivalents; + FDisplays[False,True]:=Copy(AValue,1,I-1); + FDisplays[True,True]:=UpperCase(FDisplays[False,True]); + FDisplays[False,False]:=Copy(AValue,I+1,Length(AValue)-i); + FDisplays[True,False]:=UpperCase(FDisplays[False,False]); + PropertyChanged(True); + end; +end; + +procedure TBooleanField.dosetvalue(const sender: tobject; var avalue: int32; + var accept: boolean); +var + bo1: boolean; +begin + if assigned(fonsetvalue) then begin + bo1:= avalue <> 0; + fonsetvalue(self,sender,bo1,accept); + if bo1 then begin + avalue:= 1; + end + else begin + avalue:= 0; + end; + end; +end; + +{ TDateTimeField } + +procedure TDateTimeField.SetDisplayFormat(const AValue: string); +begin + if FDisplayFormat<>AValue then begin + FDisplayFormat:=AValue; + PropertyChanged(True); + end; +end; + +function TDateTimeField.GetAsDateTime: TDateTime; + +begin + If Not GetData(@Result,False) then + Result:=0; +end; + +procedure TDateTimeField.SetVarValue(const AValue: Variant); +begin + SetAsDateTime(AValue); +end; + +procedure TDateTimeField.dosetvalue(const sender: tobject; var avalue: flo64; + var accept: boolean); +begin + if assigned(fonsetvalue) then begin + fonsetvalue(self,sender,tdatetime(avalue),accept); + end; +end; + +function TDateTimeField.GetAsVariant: Variant; + +Var d : tDateTime; + +begin + If Getdata(@d,False) then + Result := d + else + Result:=Null; +end; + +function TDateTimeField.GetAsFloat: Double; + +begin + Result:=GetAsdateTime; +end; + + +function TDateTimeField.GetAsString: string; + +begin + GetText(Result,False); +end; + + +function TDateTimeField.GetDataSize: Integer; + +begin + Result:=SizeOf(TDateTime); +end; + + +procedure TDateTimeField.GetText(var TheText: string; ADisplayText: Boolean); + +Var R : TDateTime; + F : String; + +begin + If Not Getdata(@R,False) then + TheText:='' + else + begin + If (ADisplayText) and (Length(FDisplayFormat)<>0) then + F:=FDisplayFormat + else + Case DataType of + ftTime : F:= {$ifdef FPC}defaultformatsettings.{$endif}LongTimeFormat; + ftDate : F:= {$ifdef FPC}defaultformatsettings.{$endif}ShortDateFormat; + else + F:='c' + end; + TheText:=FormatDateTime(F,R); + end; +end; + + +procedure TDateTimeField.SetAsDateTime(AValue: TDateTime); + +begin + SetData(@Avalue,False); +end; + + +procedure TDateTimeField.SetAsFloat(AValue: Double); + +begin + SetAsDateTime(AValue); +end; + + +procedure TDateTimeField.SetAsString(const AValue: string); + +Var R : TDateTime; + +begin + if AValue<>'' then + begin + R:=StrToDateTime(AVAlue); + SetData(@R,False); + end + else + SetData(Nil); +end; + + +constructor TDateTimeField.Create(AOwner: TComponent); + +begin + Inherited Create(AOwner); + SetDataType(ftDateTime); +end; + +function TDateTimeField.getasdate: tdatetime; +begin + result:= int(getasdatetime); +end; + +function TDateTimeField.getastime: tdatetime; +begin + result:= frac(getasdatetime); +end; + +procedure TDateTimeField.setasdate(avalue: tdatetime); +begin + if datatype = fttime then begin + databaseerrorfmt(sassigndate,[fieldname],dataset); + end; + setasdatetime(avalue); +end; + +procedure TDateTimeField.setastime(avalue: tdatetime); +begin + if datatype = ftdate then begin + databaseerrorfmt(sassigntime,[fieldname],dataset); + end; + setasdatetime(avalue); +end; + + +{ TDateField } + +constructor TDateField.Create(AOwner: TComponent); + +begin + Inherited Create(AOwner); + SetDataType(ftDate); +end; + + +{ TTimeField } + +constructor TTimeField.Create(AOwner: TComponent); + +begin + Inherited Create(AOwner); + SetDataType(ftTime); +end; + +procedure TTimeField.SetAsString(const AValue: string); +Var R : TDateTime; +begin + if AValue='' then + Clear // set to NULL + else + begin + R:=StrToTime(AVAlue); + SetData(@R,False); + end; +end; + + + +{ TBinaryField } + +class procedure TBinaryField.CheckTypeSize(AValue: Longint); + +begin + // Just check for really invalid stuff; actual size is + // dependent on the record... + If AValue<1 then + DatabaseErrorFmt(SInvalidFieldSize,[AValue]); +end; + +function TBinaryField.GetAsBytes: TBytes; +var B: TBytes; +begin + SetLength(B, DataSize); + if not assigned(B) or not GetData(Pointer(B), True) then + SetLength(Result, 0) + else if DataType = ftVarBytes then + begin + SetLength(Result, PWord(B)^); + Move(B[sizeof(Word)], Result[0], Length(Result)); + end + else // ftBytes + Result := B; +end; + + +function TBinaryField.GetAsString: string; +var + B: TBytes; +begin + B := GetAsBytes; + if length(B) = 0 then + Result := '' + else + SetString(Result, pchar(@B[0]), length(B) div SizeOf(Char)); +end; + + +function TBinaryField.GetAsVariant: Variant; +var B: TBytes; + P: Pointer; +begin + B := GetAsBytes; + Result := VarArrayCreate([0, length(B)-1], varByte); + P := VarArrayLock(Result); + try + Move(B[0], P^, length(B)); + finally + VarArrayUnlock(Result); + end; +end; + + +procedure TBinaryField.GetText(var TheText: string; ADisplayText: Boolean); + +begin + TheText:=GetAsString; +end; + + +procedure TBinaryField.SetAsBytes(const AValue: TBytes); +var Buf: array[0..dsMaxStringSize] of byte; + DynBuf: TBytes; + Len: Word; + P: PByte; +begin + Len := Length(AValue); + if Len >= DataSize then + P := @AValue[0] + else begin + if DataSize <= dsMaxStringSize then + P := @Buf[0] + else begin + SetLength(DynBuf, DataSize); + P := @DynBuf[0]; + end; + + if DataType = ftVarBytes then begin + PWord(P)^ := Len; + Move(AValue[0], pchar(P)[sizeof(Word)], Len); + end + else begin // ftBytes + Move(AValue[0], P^, Len); + FillChar(pchar(P)[Len], DataSize-Len, 0); // right pad with #0 + end; + end; + SetData(P, True) +end; + + +procedure TBinaryField.SetAsString(const AValue: string); +var B : TBytes; +begin + If Length(AValue) = DataSize then + SetData(PChar(AValue)) + else + begin + SetLength(B, Length(AValue) * SizeOf(Char)); + Move(AValue[1], B[0], Length(B)); + SetAsBytes(B); + end; +end; + + +procedure TBinaryField.SetText(const AValue: string); + +begin + SetAsString(Avalue); +end; + +procedure TBinaryField.SetVarValue(const AValue: Variant); +var P: Pointer; + B: TBytes; + Len: integer; +begin + if VarIsArray(AValue) then + begin + P := VarArrayLock(AValue); + try + Len := VarArrayHighBound(AValue, 1) + 1; + SetLength(B, Len); + Move(P^, B[0], Len); + finally + VarArrayUnlock(AValue); + end; + SetAsBytes(B); + end + else + SetAsString(AValue); +end; + + +constructor TBinaryField.Create(AOwner: TComponent); + +begin + Inherited Create(AOwner); +end; + + + +{ TBytesField } + +function TBytesField.GetDataSize: Integer; + +begin + Result:=Size; +end; + + +constructor TBytesField.Create(AOwner: TComponent); + +begin + Inherited Create(AOwner); + SetDataType(ftBytes); + Size:=16; +end; + + + +{ TVarBytesField } + +function TVarBytesField.GetDataSize: Integer; + +begin + Result:=Size+2; +end; + + +constructor TVarBytesField.Create(AOwner: TComponent); + +begin + INherited Create(AOwner); + SetDataType(ftvarbytes); + Size:=16; +end; + +{ TBCDField } + +class procedure TBCDField.CheckTypeSize(AValue: Longint); + +begin + If not (AValue in [0..4]) then + DatabaseErrorfmt(SInvalidFieldSize,[Avalue]); +end; + +function TBCDField.GetAsCurrency: Currency; + +begin + if not GetData(@Result) then + result := 0; +end; + +function TBCDField.GetAsVariant: Variant; + +Var c : system.Currency; + +begin + If GetData(@c) then + Result := c + else + Result:=Null; +end; + +function TBCDField.GetAsFloat: Double; + +begin + result := GetAsCurrency; +end; + + +function TBCDField.GetAsLongint: Longint; + +begin + result := round(GetAsCurrency); +end; + + +function TBCDField.GetAsString: string; + +var c : system.currency; + +begin + If GetData(@C) then + Result:=CurrToStr(C) + else + Result:=''; +end; + +function TBCDField.GetValue(var AValue: Currency): Boolean; + +begin + Result := GetData(@AValue); +end; + +function TBCDField.GetDataSize: Integer; + +begin + result := sizeof(system.currency); +end; + +function TBCDField.GetDefaultWidth: Longint; + +begin + if precision > 0 then result := precision + else result := 10; +end; + +procedure TBCDField.GetText(var TheText: string; ADisplayText: Boolean); +var + c : system.currency; + fmt: String; +begin + if GetData(@C) then begin + if aDisplayText or (FEditFormat='') then + fmt := FDisplayFormat + else + fmt := FEditFormat; + if fmt<>'' then + TheText := FormatFloat(fmt,C) + else if fCurrency then begin + if aDisplayText then + TheText := FloatToStrF(C, ffCurrency, FPrecision, 2{digits?}) + else + TheText := FloatToStrF(C, ffFixed, FPrecision, 2{digits?}); + end else + TheText := FloatToStrF(C, ffGeneral, FPrecision, 0{digits?}); + end else + TheText := ''; +end; + +procedure TBCDField.SetAsCurrency(AValue: Currency); + +begin + If CheckRange(AValue) then + setdata(@AValue) + else + RangeError(AValue,FMinValue,FMaxvalue); +end; + +procedure TBCDField.SetVarValue(const AValue: Variant); +begin + SetAsCurrency(AValue); +end; + +procedure TBCDField.dosetvalue(const sender: tobject; var avalue: flo64; + var accept: boolean); +var + val1: currency; +begin + if assigned(fonsetvalue) then begin + val1:= avalue; + fonsetvalue(self,sender,val1,accept); + value:= val1; + end; +end; + +Function TBCDField.CheckRange(AValue : Currency) : Boolean; + +begin + If (FMinValue<>0) or (FmaxValue<>0) then + Result:=(AValue>=FMinValue) and (AVAlue<=FMaxValue) + else + Result:=True; +end; + +procedure TBCDField.SetAsFloat(AValue: Double); + +begin + SetAsCurrency(AValue); +end; + + +procedure TBCDField.SetAsLongint(AValue: Longint); + +begin + SetAsCurrency(AValue); +end; + + +procedure TBCDField.SetAsString(const AValue: string); + +begin + if AValue='' then + Clear // set to NULL + else + SetAsCurrency(strtocurr(AValue)); +end; + +constructor TBCDField.Create(AOwner: TComponent); + +begin + Inherited Create(AOwner); + FMaxvalue := 0; + FMinvalue := 0; + FValidChars := [{$ifdef FPC}defaultformatsettings.{$endif}DecimalSeparator, + '+', '-', '0'..'9']; + SetDataType(ftBCD); + FPrecision := 15; + Size:=4; +end; + + +{ TFMTBCDField } + +class procedure TFMTBCDField.CheckTypeSize(AValue: Longint); +begin + If AValue > MAXFMTBcdFractionSize then + DatabaseErrorfmt(SInvalidFieldSize,[AValue]); +end; + +constructor TFMTBCDField.Create(AOwner: TComponent); +begin + Inherited Create(AOwner); + FMaxValue := nullbcd; + FMinValue := nullbcd; + FValidChars := [{$ifdef FPC}defaultformatsettings.{$endif}DecimalSeparator, + '+', '-', '0'..'9']; + SetDataType(ftFMTBCD); +// Max.precision for NUMERIC,DECIMAL datatypes supported by some databases: +// Firebird-18; Oracle,SqlServer-38; MySQL-65; PostgreSQL-1000 + Precision := 15; //default number of digits + Size:=4; //default number of digits after decimal place +end; + +function TFMTBCDField.GetDataSize: Integer; +begin + Result := sizeof(TBCD); +end; + +function TFMTBCDField.GetDefaultWidth: Longint; +begin + if Precision > 0 then Result := Precision+1 + else Result := inherited GetDefaultWidth; +end; + +function TFMTBCDField.GetAsBCD: TBCD; +begin + if not GetData(@Result) then + Result := NullBCD; +end; + +function TFMTBCDField.GetAsCurrency: Currency; +var bcd: TBCD; +begin + if GetData(@bcd) then + BCDToCurr(bcd, Result) + else + Result := 0; +end; + +function TFMTBCDField.GetAsVariant: Variant; +var bcd: TBCD; +begin + If GetData(@bcd) then + Result := VarFMTBcdCreate(bcd) + else + Result := Null; +end; + +function TFMTBCDField.GetAsFloat: Double; +var bcd: TBCD; +begin + If GetData(@bcd) then + Result := BCDToDouble(bcd) + else + Result := 0; +end; + +function TFMTBCDField.GetAsLongint: Longint; +begin + Result := round(GetAsFloat); +end; + +function TFMTBCDField.GetAsString: string; +var bcd: TBCD; +begin + If GetData(@bcd) then + Result:=BCDToStr(bcd) + else + Result:=''; +end; + +procedure TFMTBCDField.GetText(var TheText: string; ADisplayText: Boolean); +var + bcd: TBCD; + fmt: String; +begin + if GetData(@bcd) then begin + if aDisplayText or (FEditFormat='') then + fmt := FDisplayFormat + else + fmt := FEditFormat; + if fmt<>'' then + TheText := BCDToStr(bcd) + //TheText := FormatBCD(fmt,bcd) //uncomment when formatBCD in fmtbcd.pp will be implemented + else if fCurrency then begin + if aDisplayText then + TheText := BcdToStrF(bcd, ffCurrency, FPrecision, 2) + else + TheText := BcdToStrF(bcd, ffFixed, FPrecision, 2); + end else + TheText := BcdToStrF(bcd, ffGeneral, FPrecision, FSize); + end else + TheText := ''; +end; + +function TFMTBCDField.GetMaxValue: string; +begin + Result:=BCDToStr(FMaxValue); +end; + +function TFMTBCDField.GetMinValue: string; +begin + Result:=BCDToStr(FMinValue); +end; + +procedure TFMTBCDField.SetMaxValue(const AValue: string); +begin + FMaxValue:=StrToBCD(AValue); +end; + +procedure TFMTBCDField.SetMinValue(const AValue: string); +begin + FMinValue:=StrToBCD(AValue); +end; + +Function TFMTBCDField.CheckRange(AValue: TBCD) : Boolean; +begin + If (bcdcompare(FMinValue,nullbcd) <> 0) or + (bcdcompare(FMaxValue,nullbcd)<> 0) then + Result:= (bcdcompare(AValue,FMinValue) >= 0) and + (bcdcompare(AValue,FMaxValue) <= 0) + else + Result:=True; +end; + +procedure TFMTBCDField.SetAsBCD(const AValue: TBCD); +begin + if CheckRange(AValue) then + SetData(@AValue) + else + RangeError(bcdtodouble(AValue), BCDToDouble(FMinValue), + BCDToDouble(FMaxValue)); +end; + +procedure TFMTBCDField.SetAsCurrency(AValue: Currency); +var bcd: TBCD; +begin + if CurrToBCD(AValue, bcd, 32, Size) then + SetAsBCD(bcd); +end; + +procedure TFMTBCDField.SetVarValue(const AValue: Variant); +begin + SetAsBCD(VarToBCD(AValue)); +end; + +procedure TFMTBCDField.SetAsFloat(AValue: Double); +begin + SetAsBCD(DoubleToBCD(AValue)); +end; + + +procedure TFMTBCDField.SetAsLongint(AValue: Longint); +begin + SetAsBCD(IntegerToBCD(AValue)); +end; + + +procedure TFMTBCDField.SetAsString(const AValue: string); +begin + if AValue='' then + Clear // set to NULL + else + SetAsBCD(StrToBCD(AValue)); +end; + + +{ TBlobField } + +Function TBlobField.GetBlobStream(Mode : TBlobStreamMode) : TStream; + +begin + Result:=FDataset.CreateBlobStream(Self,Mode); +end; + +procedure TBlobField.FreeBuffers; + +begin +end; + + +function TBlobField.GetAsString: string; +var + Stream : TStream; + Len : Integer; +begin + Stream := GetBlobStream(bmRead); + if Stream <> nil then + With Stream do + try + Len := Size; + SetLength(Result, Len); + if Len > 0 then + ReadBuffer(Result[1], Len); + finally + Free + end + else + Result := ''; +end; + +function TBlobField.GetAsWideString: WideString; +var + Stream : TStream; + Len : Integer; +begin + Stream := GetBlobStream(bmRead); + if Stream <> nil then + With Stream do + try + Len := Size; + SetLength(Result,Len div 2); + if Len > 0 then + ReadBuffer(Result[1] ,Len); + finally + Free + end + else + Result := ''; +end; + +function TBlobField.GetAsVariant: Variant; + +Var s : string; + +begin + if not GetIsNull then + begin + s := GetAsString; + result := s; + end + else result := Null; +end; + + +function TBlobField.GetBlobSize: Longint; +var + Stream: TStream; +begin + Stream := GetBlobStream(bmread); + if Stream <> nil then + With Stream do + try + Result:=Size; + finally + Free; + end + else + result := 0; +end; + + +function TBlobField.GetIsNull: Boolean; + +begin + If Not Modified then + result:= inherited GetIsnull + else + With GetBlobStream(bmread) do + try + Result:=(Size=0); + Finally + Free; + end; +end; + + +procedure TBlobField.GetText(var TheText: string; ADisplayText: Boolean); + +begin + TheText:=inherited GetAsString; +end; + + +procedure TBlobField.SetAsString(const AValue: string); +var + Len : Integer; +begin + With GetBlobStream(bmwrite) do + try + Len := Length(Avalue); + if Len > 0 then + WriteBuffer(aValue[1], Len); + finally + Free; + end; +end; + + +procedure TBlobField.SetAsWideString(const AValue: WideString); +var + Len : Integer; +begin + With GetBlobStream(bmwrite) do + try + Len := Length(Avalue) * 2; + if Len > 0 then + WriteBuffer(aValue[1], Len); + finally + Free; + end; +end; + + +procedure TBlobField.SetText(const AValue: string); + +begin + SetAsString(AValue); +end; + +procedure TBlobField.SetVarValue(const AValue: Variant); +begin + SetAsString(AValue); +end; + + +constructor TBlobField.Create(AOwner: TComponent); + +begin + Inherited Create(AOWner); + SetDataType(ftBlob); +end; + + +procedure TBlobField.Clear; + +begin + GetBlobStream(bmWrite).free; +end; + + +class function TBlobField.IsBlob: Boolean; + +begin + Result:=True; +end; + + +procedure TBlobField.LoadFromFile(const FileName: string); + +Var S : TFileStream; + +begin + S:=TFileStream.Create(FileName,fmOpenRead); + try + LoadFromStream(S); + finally + S.Free; + end; +end; + + +procedure TBlobField.LoadFromStream(Stream: TStream); + +begin + With GetBlobStream(bmWrite) do + Try + CopyFrom(Stream,0); + finally + Free; + end; +end; + + +procedure TBlobField.SaveToFile(const FileName: string); + +Var S : TFileStream; + +begin + S:=TFileStream.Create(FileName,fmCreate); + try + SaveToStream(S); + finally + S.Free; + end; +end; + + +procedure TBlobField.SaveToStream(Stream: TStream); + +Var S : TStream; + +begin + S:=GetBlobStream(bmRead); + Try + If Assigned(S) then + Stream.CopyFrom(S,0); + finally + S.Free; + end; +end; + +procedure TBlobField.SetFieldType(AValue: TFieldType); + +begin + If AValue in [Low(TBlobType)..High(TBlobType)] then + SetDatatype(Avalue); +end; + +{ TMemoField } + +constructor TMemoField.Create(AOwner: TComponent); + +begin + Inherited Create(AOwner); + SetDataType(ftMemo); +end; + +function TMemoField.GetAsWideString: WideString; +begin + Result := widestring(GetAsString); +end; + +procedure TMemoField.SetAsWideString(const aValue: WideString); +begin + SetAsString(ansistring(aValue)); +end; + +{ TWideMemoField } + +constructor TWideMemoField.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + SetDataType(ftWideMemo); +end; + +function TWideMemoField.GetAsString: string; +begin + Result := ansistring(GetAsWideString); +end; + +procedure TWideMemoField.SetAsString(const aValue: string); +begin + SetAsWideString(widestring(aValue)); +end; + +function TWideMemoField.GetAsVariant: Variant; + +//Var s : string; + +begin + if not GetIsNull then + begin + result:= getaswidestring; + { + s := GetAsWideString; + result := s; + } + end + else result := Null; +end; + +procedure TWideMemoField.SetVarValue(const AValue: Variant); +begin + SetAsWideString(AValue); +end; + +{ TGraphicField } + +constructor TGraphicField.Create(AOwner: TComponent); + +begin + Inherited Create(AOwner); + SetDataType(ftGraphic); +end; + +{ TGuidField } + +constructor TGuidField.Create(AOwner: TComponent); +begin + Size := 38; + inherited Create(AOwner); + SetDataType(ftGuid); +end; + +class procedure TGuidField.CheckTypeSize(AValue: LongInt); +begin + if aValue <> 38 then + DatabaseErrorFmt(SInvalidFieldSize,[AValue]); +end; + +function TGuidField.GetAsGuid: TGUID; +const + nullguid: TGUID = '{00000000-0000-0000-0000-000000000000}'; +var + S: string; +begin + S := GetAsString; + if S = '' then + Result := nullguid + else + Result := StringToGuid(S); +end; + +function TGuidField.GetDefaultWidth: LongInt; +begin + Result := 38; +end; + +procedure TGuidField.SetAsGuid(const aValue: TGUID); +begin + SetAsString(GuidToString(aValue)); +end; + +function TVariantField.GetDefaultWidth: Integer; +begin + Result := 15; +end; + +{ TVariantField } + +constructor TVariantField.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + SetDataType(ftVariant); +end; + +class procedure TVariantField.CheckTypeSize(aValue: Integer); +begin + { empty } +end; + +function TVariantField.GetAsBoolean: Boolean; +begin + Result := GetAsVariant; +end; + +function TVariantField.GetAsDateTime: TDateTime; +begin + Result := GetAsVariant; +end; + +function TVariantField.GetAsFloat: Double; +begin + Result := GetAsVariant; +end; + +function TVariantField.GetAsInteger: Longint; +begin + Result := GetAsVariant; +end; + +function TVariantField.GetAsString: string; +begin + Result := VarToStr(GetAsVariant); +end; + +function TVariantField.GetAsWideString: WideString; +begin + Result := VarToWideStr(GetAsVariant); +end; + +procedure tvariantfield.setasunicodestring(const avalue: unicodestring); +begin + setvarvalue(avalue); +end; + +function tvariantfield.getasunicodestring: unicodestring; +begin + Result := VarTounicodeStr(GetAsVariant); + { + if isnull then begin + result:= ''; + end + else begin + result:= getasvariant; + end; + } +end; + + +function TVariantField.GetAsVariant: Variant; +begin + if not GetData(@Result) then + Result := Null; +end; + +procedure TVariantField.SetAsBoolean(aValue: Boolean); +begin + SetVarValue(aValue); +end; + +procedure TVariantField.SetAsDateTime(aValue: TDateTime); +begin + SetVarValue(aValue); +end; + +procedure TVariantField.SetAsFloat(aValue: Double); +begin + SetVarValue(aValue); +end; + +procedure TVariantField.SetAsInteger(aValue: Longint); +begin + SetVarValue(aValue); +end; + +procedure TVariantField.SetAsString(const aValue: string); +begin + SetVarValue(aValue); +end; + +procedure TVariantField.SetAsWideString(const aValue: WideString); +begin + SetVarValue(aValue); +end; + +procedure TVariantField.SetVarValue(const aValue: Variant); +begin + SetData(@aValue); +end; + +{ TFieldsEnumerator } + +function TFieldsEnumerator.GetCurrent: TField; +begin + Result := FFields[FPosition]; +end; + +constructor TFieldsEnumerator.Create(AFields: TFields); +begin + inherited Create; + FFields := AFields; + FPosition := -1; +end; + +function TFieldsEnumerator.MoveNext: Boolean; +begin + inc(FPosition); + Result := FPosition < FFields.Count; +end; + +{ TFields } + +Constructor TFields.Create(ADataset : TDataset); + +begin + FDataSet:=ADataset; + FFieldList:=TFpList.Create; + FValidFieldKinds:=[fkData..fkInternalcalc]; +end; + +Destructor TFields.Destroy; + +begin + if Assigned(FFieldList) then + Clear; + FreeAndNil(FFieldList); + inherited Destroy; +end; + +Procedure Tfields.Changed; + +begin + if (FDataSet <> nil) and not (csDestroying in FDataSet.ComponentState) and FDataset.Active then + FDataSet.DataEvent(deFieldListChange, 0); + If Assigned(FOnChange) then + FOnChange(Self); +end; + +Procedure TFields.CheckfieldKind(Fieldkind : TFieldKind; Field : TField); + +begin + If Not (FieldKind in ValidFieldKinds) Then + DatabaseErrorFmt(SInvalidFieldKind,[Field.FieldName]); +end; + +Function Tfields.GetCount : Longint; + +begin + Result:=FFieldList.Count; +end; + + +Function TFields.GetField (Index : longint) : TField; + +begin + Result:=Tfield(FFieldList[Index]); +end; + +procedure Tfields.SetField(Index: Integer; Value: TField); +begin + Fields[Index].Assign(Value); +end; + +Procedure TFields.SetFieldIndex (Field : TField;Value : Integer); + +Var Old : Longint; + +begin + Old := FFieldList.indexOf(Field); + If Old=-1 then + Exit; + // Check value + If Value<0 Then Value:=0; + If Value>=Count then Value:=Count-1; + If Value<>Old then + begin + FFieldList.Delete(Old); + FFieldList.Insert(Value,Field); + Field.PropertyChanged(True); + Changed; + end; +end; + +Procedure TFields.Add(Field : TField); + +begin + CheckFieldName(Field.FieldName); + FFieldList.Add(Field); + Field.FFields:=Self; + Changed; +end; + +Procedure TFields.CheckFieldName (Const Value : String); + +begin + If FindField(Value)<>Nil then + DataBaseErrorFmt(SDuplicateFieldName,[Value],FDataset); +end; + +Procedure TFields.CheckFieldNames (Const Value : String); + + +Var I : longint; + S,T : String; +begin + T:=Value; + Repeat + I:=Pos(';',T); + If I=0 Then I:=Length(T)+1; + S:=Copy(T,1,I-1); + Delete(T,1,I); + // Will raise an error if no such field... + FieldByName(S); + Until (T=''); +end; + +Procedure TFields.Clear; +var + AField: TField; +begin + while FFieldList.Count > 0 do + begin + AField := TField(FFieldList.Last); + AField.FDataSet := Nil; + AField.Free; + FFieldList.Delete(FFieldList.Count - 1); + end; + Changed; +end; + +Function TFields.FindField (Const Value : String) : TField; + +Var S : String; + I : longint; + +begin + Result:=Nil; + S:=UpperCase(Value); + For I:=0 To FFieldList.Count-1 do + If S=UpperCase(TField(FFieldList[i]).FieldName) Then + Begin + {$ifdef dsdebug} + Writeln ('Found field ',Value); + {$endif} + Result:=TField(FFieldList[I]); + Exit; + end; +end; + +Function TFields.FieldByName (Const Value : String) : TField; + +begin + Result:=FindField(Value); + If result=Nil then + DatabaseErrorFmt(SFieldNotFound,[Value],FDataset); +end; + +Function TFields.FieldByNumber(FieldNo : Integer) : TField; + +Var i : Longint; + +begin + Result:=Nil; + For I:=0 to FFieldList.Count-1 do + If FieldNo=TField(FFieldList[I]).FieldNo then + begin + Result:=TField(FFieldList[i]); + Exit; + end; +end; + +Function TFields.GetEnumerator: TFieldsEnumerator; + +begin + Result:=TFieldsEnumerator.Create(Self); +end; + +Procedure TFields.GetFieldNames (Values : TStrings); + +Var i : longint; + +begin + Values.Clear; + For I:=0 to FFieldList.Count-1 do + Values.Add(Tfield(FFieldList[I]).FieldName); +end; + +Function TFields.IndexOf(Field : TField) : Longint; + +begin + Result:=FFieldList.IndexOf(Field); +end; + +procedure TFields.Remove(Value : TField); + +begin + FFieldList.Remove(Value); + Value.FFields := nil; + Changed; +end; + + +{ --------------------------------------------------------------------- + TDatalink + ---------------------------------------------------------------------} + +Constructor TDataLink.Create; + +begin + Inherited Create; + FBufferCount:=1; + FFirstRecord := 0; + FDataSource := nil; + FDatasourceFixed:=False; +end; + + +Destructor TDataLink.Destroy; + +begin + Factive:=False; + FEditing:=False; + FDataSourceFixed:=False; + DataSource:=Nil; + Inherited Destroy; +end; + + +Procedure TDataLink.ActiveChanged; + +begin + FFirstRecord := 0; +end; + +Procedure TDataLink.CheckActiveAndEditing; + +Var + B : Boolean; + +begin + B:=Assigned(DataSource) and (DataSource.State<>dsInactive); + If B<>FActive then + begin + FActive:=B; + ActiveChanged; + end; + B:=Assigned(DataSource) and (DataSource.State in dsEditModes) and Not FReadOnly; + If B<>FEditing Then + begin + FEditing:=B; + EditingChanged; + end; +end; + + +Procedure TDataLink.CheckBrowseMode; + +begin +end; + + +Function TDataLink.CalcFirstRecord(Index : Integer) : Integer; +begin + if DataSource.DataSet.FActiveRecord > FFirstRecord + Index + FBufferCount - 1 then + Result := DataSource.DataSet.FActiveRecord - (FFirstRecord + Index + FBufferCount - 1) + else if DataSource.DataSet.FActiveRecord < FFirstRecord + Index then + Result := DataSource.DataSet.FActiveRecord - (FFirstRecord + Index) + else Result := 0; + + Inc(FFirstRecord, Index + Result); +end; + + +Procedure TDataLink.CalcRange; +var + aMax, aMin: integer; +begin + aMin:= DataSet.FActiveRecord - FBufferCount + 1; + If aMin < 0 Then aMin:= 0; + aMax:= Dataset.FBufferCount - FBufferCount; + If aMax < 0 then aMax:= 0; + + If aMax>DataSet.FActiveRecord Then aMax:=DataSet.FActiveRecord; + + If FFirstRecord < aMin Then FFirstRecord:= aMin; + If FFirstrecord > aMax Then FFirstRecord:= aMax; + + If (FfirstRecord<>0) And + (DataSet.FActiveRecord - FFirstRecord < FBufferCount -1) Then + Dec(FFirstRecord, 1); + +end; + + +Procedure TDataLink.DataEvent(Event: TDataEvent; Info: Ptrint); + + +begin + Case Event of + deFieldChange, deRecordChange: + If Not FUpdatingRecord then + RecordChanged(TField(Info)); + deDataSetChange: begin + SetActive(DataSource.DataSet.Active); + CalcRange; + CalcFirstRecord(Info); + DatasetChanged; + end; + deDataSetScroll: DatasetScrolled(CalcFirstRecord(Info)); + deLayoutChange: begin + CalcFirstRecord(Info); + LayoutChanged; + end; + deUpdateRecord: UpdateRecord; + deUpdateState: CheckActiveAndEditing; + deCheckBrowseMode: CheckBrowseMode; + deFocusControl: FocusControl(TFieldRef(Info)); + end; +end; + + +Procedure TDataLink.DataSetChanged; + +begin + RecordChanged(Nil); +end; + + +Procedure TDataLink.DataSetScrolled(Distance: Integer); + +begin + DataSetChanged; +end; + + +Procedure TDataLink.EditingChanged; + +begin +end; + + +Procedure TDataLink.FocusControl(Field: TFieldRef); + +begin +end; + + +Function TDataLink.GetActiveRecord: Integer; + +begin + Result:=Dataset.FActiveRecord - FFirstRecord; +end; + +Function TDatalink.GetDataSet : TDataset; + +begin + If Assigned(Datasource) then + Result:=DataSource.DataSet + else + Result:=Nil; +end; + + +Function TDataLink.GetBOF: Boolean; + +begin + Result:=DataSet.BOF +end; + + +Function TDataLink.GetBufferCount: Integer; + +begin + Result:=FBufferCount; +end; + + +Function TDataLink.GetEOF: Boolean; + +begin + Result:=DataSet.EOF +end; + + +Function TDataLink.GetRecordCount: Integer; + +begin + Result:=Dataset.FRecordCount; + If Result>BufferCount then + Result:=BufferCount; +end; + + +Procedure TDataLink.LayoutChanged; + +begin + DataSetChanged; +end; + + +Function TDataLink.MoveBy(Distance: Integer): Integer; + +begin + Result:=DataSet.MoveBy(Distance); +end; + + +Procedure TDataLink.RecordChanged(Field: TField); + +begin +end; + + +Procedure TDataLink.SetActiveRecord(Value: Integer); + +begin +{$ifdef dsdebug} + Writeln('Datalink. Setting active record to ',Value,' with firstrecord ',ffirstrecord); +{$endif} + Dataset.FActiveRecord:=Value + FFirstRecord; +end; + + +Procedure TDataLink.SetBufferCount(Value: Integer); + +begin + If FBufferCount<>Value then + begin + FBufferCount:=Value; + if Active then begin + DataSet.RecalcBufListSize; + CalcRange; + end; + end; +end; + +procedure TDataLink.SetActive(AActive: Boolean); +begin + if Active <> AActive then + begin + FActive := AActive; + // !!!: Set internal state + ActiveChanged; + end; +end; + +Procedure TDataLink.SetDataSource(Value : TDatasource); + +begin + if FDataSource = Value then + Exit; + if not FDataSourceFixed then + begin + if Assigned(DataSource) then + Begin + DataSource.UnregisterDatalink(Self); + FDataSource := nil; + CheckActiveAndEditing; + End; + FDataSource := Value; + if Assigned(DataSource) then + begin + DataSource.RegisterDatalink(Self); + CheckActiveAndEditing; + End; + end; +end; + +Procedure TDatalink.SetReadOnly(Value : Boolean); + +begin + If FReadOnly<>Value then + begin + FReadOnly:=Value; + CheckActiveAndEditing; + end; +end; + +Procedure TDataLink.UpdateData; + +begin +end; + + + +Function TDataLink.Edit: Boolean; + +begin + If Not FReadOnly then + DataSource.Edit; + // Triggered event will set FEditing + Result:=FEditing; +end; + + +Procedure TDataLink.UpdateRecord; + +begin + FUpdatingRecord:=True; + Try + UpdateData; + finally + FUpdatingRecord:=False; + end; +end; + +function TDataLink.ExecuteAction(Action: TBasicAction): Boolean; +begin + if Action.HandlesTarget(DataSource) then + begin + Action.ExecuteTarget(DataSource); + Result := True; + end + else Result := False; +end; + +function TDataLink.UpdateAction(Action: TBasicAction): Boolean; +begin + if Action.HandlesTarget(DataSource) then + begin + Action.UpdateTarget(DataSource); + Result := True; + end + else Result := False; +end; + +function tdatalink.datasourcereadonly(): boolean; +begin + result:= fdatasource.readonly; +end; + +function TDataLink.getreadonly: Boolean; +begin + result:= freadonly or (fdatasource <> nil) and datasourcereadonly(); +end; + +function TDataLink.getactive: Boolean; +begin + result:= factive and (fdatasource <> nil) and (fdatasource.enabled); +end; + +procedure TDataLink.updateactive(); +begin + setactive((fdatasource <> nil) and (fdatasource.fdataset <> nil) and + fdatasource.fdataset.active); +end; +{ +procedure TDataLink.doenter(const aobject: tobject); +begin + if fdatasource <> nil then begin + fdatasource.doenter(self,aobject); + end; +end; + +procedure TDataLink.doexit(const aobject: tobject); +begin + if fdatasource <> nil then begin + fdatasource.doexit(self,aobject); + end; +end; +} + +{ --------------------------------------------------------------------- + TDetailDataLink + ---------------------------------------------------------------------} + +Function TDetailDataLink.GetDetailDataSet: TDataSet; + +begin + Result := nil; +end; + + +{ --------------------------------------------------------------------- + TMasterDataLink + ---------------------------------------------------------------------} + +constructor TMasterDataLink.Create(ADataSet: TDataSet); + +begin + inherited Create; + FDetailDataSet:=ADataSet; + FFields:=TList.Create; +end; + + +destructor TMasterDataLink.Destroy; + +begin + FFields.Free; + inherited Destroy; +end; + + +Procedure TMasterDataLink.ActiveChanged; + +begin + FFields.Clear; + if Active then + try + DataSet.GetFieldList(FFields, FFieldNames); + except + FFields.Clear; + raise; + end; + if FDetailDataSet.Active and not (csDestroying in FDetailDataSet.ComponentState) then + if Active and (FFields.Count > 0) then + DoMasterChange + else + DoMasterDisable; +end; + + +Procedure TMasterDataLink.CheckBrowseMode; + +begin + if FDetailDataSet.Active then FDetailDataSet.CheckBrowseMode; +end; + + +Function TMasterDataLink.GetDetailDataSet: TDataSet; + +begin + Result := FDetailDataSet; +end; + + +Procedure TMasterDataLink.LayoutChanged; + +begin + ActiveChanged; +end; + + +Procedure TMasterDataLink.RecordChanged(Field: TField); + +begin + if (DataSource.State <> dsSetKey) and FDetailDataSet.Active and + (FFields.Count > 0) and ((Field = nil) or + (FFields.IndexOf(Field) >= 0)) then + DoMasterChange; +end; + +procedure TMasterDatalink.SetFieldNames(const Value: string); + +begin + if FFieldNames <> Value then + begin + FFieldNames := Value; + ActiveChanged; + end; +end; + +Procedure TMasterDataLink.DoMasterDisable; + +begin + if Assigned(FOnMasterDisable) then + FOnMasterDisable(Self); +end; + +Procedure TMasterDataLink.DoMasterChange; + +begin + If Assigned(FOnMasterChange) then + FOnMasterChange(Self); +end; + +{ --------------------------------------------------------------------- + TMasterDataLink + ---------------------------------------------------------------------} + +constructor TMasterParamsDataLink.Create(ADataSet: TDataSet); + +Var + P : TParams; + +begin + inherited Create(ADataset); + If (ADataset<>Nil) then + begin + P:=TParams(GetObjectProp(ADataset,'Params',TParams)); + if (P<>Nil) then + Params:=P; + end; +end; + + +Procedure TMasterParamsDataLink.SetParams(AVAlue : TParams); + +begin + FParams:=AValue; + If (AValue<>Nil) then + RefreshParamNames; +end; + +Procedure TMasterParamsDataLink.RefreshParamNames; + +Var + FN : String; + DS : TDataset; + F : TField; + I : Integer; + +begin + FN:=''; + DS:=Dataset; + If Assigned(FParams) then + begin + F:=Nil; + For I:=0 to FParams.Count-1 do + begin + If Assigned(DS) then + F:=DS.FindField(FParams[i].Name); + If (Not Assigned(DS)) or (not DS.Active) or (F<>Nil) then + begin + If (FN<>'') then + FN:=FN+';'; + FN:=FN+FParams[i].Name; + end; + end; + end; + FieldNames:=FN; +end; + +Procedure TMasterParamsDataLink.CopyParamsFromMaster(CopyBound : Boolean); + +begin + if Assigned(FParams) then + FParams.CopyParamValuesFromDataset(Dataset,CopyBound); +end; + +Procedure TMasterParamsDataLink.DoMasterDisable; + +begin + Inherited; + If Assigned(DetailDataset) and DetailDataset.Active then + DetailDataset.Close; +end; + +Procedure TMasterParamsDataLink.DoMasterChange; + +begin + Inherited; + if Assigned(Params) and Assigned(DetailDataset) and DetailDataset.Active then + begin + DetailDataSet.CheckBrowseMode; + DetailDataset.Close; + DetailDataset.Open; + end; +end; + +{ --------------------------------------------------------------------- + TDatasource + ---------------------------------------------------------------------} + +Constructor TDataSource.Create(AOwner: TComponent); + +begin + Inherited Create(AOwner); + FDatalinks := TList.Create; + FEnabled := True; + FAutoEdit := True; +end; + + +Destructor TDataSource.Destroy; + +begin + FOnStateCHange:=Nil; + Dataset:=Nil; + With FDataLinks do + While Count>0 do + TDatalink(Items[Count - 1]).DataSource:=Nil; + FDatalinks.Free; + inherited Destroy; +end; + + +Procedure TDatasource.Edit; + +begin + If (State=dsBrowse) and AutoEdit Then + Dataset.Edit; +end; + +Function TDataSource.IsLinkedTo(ADataSet: TDataSet): Boolean; + +begin + Result:=False; +end; + + +procedure TDatasource.DistributeEvent(Event: TDataEvent; Info: Ptrint); + + +Var + i : Longint; + +begin + With FDatalinks do + begin + For I:=0 to Count-1 do + With TDatalink(Items[i]) do + If Not VisualControl Then + DataEvent(Event,Info); + For I:=0 to Count-1 do + With TDatalink(Items[i]) do + If VisualControl Then + DataEvent(Event,Info); + end; +end; + +procedure TDatasource.RegisterDataLink(DataLink: TDataLink); + +begin + FDatalinks.Add(DataLink); + if Assigned(DataSet) then + DataSet.RecalcBufListSize; +end; + + +procedure TDatasource.SetDataSet(ADataSet: TDataSet); +begin + If FDataset<>Nil Then + Begin + FDataset.UnRegisterDataSource(Self); + FDataSet:=nil; + ProcessEvent(deUpdateState,0); + End; + If ADataset<>Nil Then + begin + ADataset.RegisterDatasource(Self); + FDataSet:=ADataset; + ProcessEvent(deUpdateState,0); + End; +end; + + +procedure TDatasource.SetEnabled(Value: Boolean); + +begin + if fenabled <> value then begin + FEnabled:=Value; + if caneventdistribute() then begin + processevent(dedisabledstatechange,0); + end; + end; +end; + + +Procedure TDatasource.DoDataChange (Info : Pointer); + +begin + If Assigned(OnDataChange) Then + OnDataChange(Self,TField(Info)); +end; + +Procedure TDatasource.DoStateChange; + +begin + If Assigned(OnStateChange) Then + OnStateChange(Self); +end; + +procedure tdatasource.doenabledchange(); + +begin + if assigned(fonenabledchange) then begin + onenabledchange(self); + end; +end; + + +Procedure TDatasource.DoUpdateData; + +begin + If Assigned(OnUpdateData) Then + OnUpdateData(Self); +end; + + +procedure TDatasource.UnregisterDataLink(DataLink: TDataLink); + +begin + FDatalinks.Remove(Datalink); + If Dataset<>Nil then + DataSet.RecalcBufListSize; + //Dataset.SetBufListSize(DataLink.BufferCount); +end; + + +procedure TDataSource.ProcessEvent(Event : TDataEvent; Info : Ptrint); + +Const + OnDataChangeEvents = [deRecordChange, deDataSetChange, deDataSetScroll, + deLayoutChange,deUpdateState,dedisabledstatechange]; + +Var + NeedDataChange : Boolean; + FLastState : TdataSetState; + +begin + if enabled or (event = dedisabledstatechange) then begin + + // Special UpdateState handling. + If Event=deUpdateState then + begin + NeedDataChange:=(FState=dsInactive); + FLastState:=FState; + If Assigned(Dataset) then + FState:=Dataset.State + else + FState:=dsInactive; + // Don't do events if nothing changed. + If FState=FlastState then + exit; + end + else + NeedDataChange:=True; + DistributeEvent(Event,Info); + if event = dedisabledstatechange then begin + distributeevent(dedatasetchange,0); + end; + // Extra handlers + If Not (csDestroying in ComponentState) then + begin + if event = dedisabledstatechange then begin + doenabledchange(); + end; + If (Event=deUpdateState) then + DoStateChange; + If (Event in OnDataChangeEvents) and + NeedDataChange Then + DoDataChange(Nil); + If (Event = deFieldChange) Then + DoDataCHange(Pointer(Info)); + If (Event=deUpdateRecord) then + DoUpdateData; + end; + end; +end; + +procedure TDataSource.updaterecord(); +begin + processevent(deupdaterecord,0); +end; + +procedure TDataSource.ifistatechanged(const sender: tdatalink; + const aclient: iificlient; const astate: ifiwidgetstatesty); +begin + if assigned(fonifistatechanged) and + (componentstate * [csloading,csdestroying] = []) then begin + fonifistatechanged(self,sender,aclient,astate); + end; +end; + +procedure TDataSource.setreadonly(const avalue: boolean); +begin + if freadonly <> avalue then begin + freadonly:= avalue; + if caneventdistribute and active then begin + processevent(dedisabledstatechange,0); + end; + end; +end; + +function TDataSource.getactive: boolean; +begin + result:= (fdataset <> nil) and (fdataset.active); +end; + +function TDataSource.caneventdistribute: boolean; +begin + result:= componentstate * [csloading,csreading,csdestroying] = []; +end; + +{ +procedure TDataSource.doenter(const alink: tdatalink; const aobject: tobject); +begin + if assigned(fonenter) and + (componentstate * [csloading,csdestroying] = []) then begin + fonenter(self,alink,aobject); + end; +end; + +procedure TDataSource.doexit(const alink: tdatalink; const aobject: tobject); +begin + if assigned(fonexit) and + (componentstate * [csloading,csdestroying] = []) then begin + fonexit(self,alink,aobject); + end; +end; +} +{ --------------------------------------------------------------------- + TDatabase + ---------------------------------------------------------------------} + +Procedure TDatabase.CheckConnected; + +begin + If Not Connected Then + DatabaseError(SNotConnected,Self); +end; + + +Procedure TDatabase.CheckDisConnected; +begin + If Connected Then + DatabaseError(SConnected,Self); +end; + +procedure TDatabase.DoConnect; +begin + DoInternalConnect; + FConnected := True; +end; + +procedure TDatabase.DoDisconnect; +begin + Closedatasets; + Closetransactions; + DoInternalDisConnect; + if csloading in ComponentState then + FOpenAfterRead := false; + FConnected := False; +end; + +function TDatabase.GetConnected: boolean; +begin + Result:= FConnected; +end; + +constructor TDatabase.Create(AOwner: TComponent); + +begin + Inherited Create(AOwner); + FParams:=TStringlist.Create; + FDatasets:=TList.Create; + FTransactions:=TList.Create; + FConnected:=False; +end; + +destructor TDatabase.Destroy; + +begin + Connected:=False; + RemoveDatasets; + RemoveTransactions; + FDatasets.Free; + FTransactions.Free; + FParams.Free; + Inherited Destroy; +end; + +procedure TDatabase.CloseDataSets; + +Var I : longint; + +begin + If Assigned(FDatasets) then + begin + For I:=FDatasets.Count-1 downto 0 do + TDataset(FDatasets[i]).Close; + end; +end; + +procedure TDatabase.CloseTransactions; + +Var I : longint; + +begin + If Assigned(FTransactions) then + begin + For I:=FTransactions.Count-1 downto 0 do + TDBTransaction(FTransactions[i]).EndTransaction; + end; +end; + +procedure TDatabase.RemoveDataSets; + +Var I : longint; + +begin + If Assigned(FDatasets) then + For I:=FDataSets.Count-1 downto 0 do + TDBDataset(FDataSets[i]).Database:=Nil; +end; + +procedure TDatabase.RemoveTransactions; + +Var I : longint; + +begin + If Assigned(FTransactions) then + For I:=FTransactions.Count-1 downto 0 do + TDBTransaction(FTransactions[i]).Database:=Nil; +end; + +procedure TDatabase.SetParams(AValue: TStrings); +begin + if AValue<>nil then + FParams.Assign(AValue); +end; + +Function TDatabase.GetDataSetCount : Longint; + +begin + If Assigned(FDatasets) Then + Result:=FDatasets.Count + else + Result:=0; +end; + +Function TDatabase.GetTransactionCount : Longint; + +begin + If Assigned(FTransactions) Then + Result:=FTransactions.Count + else + Result:=0; +end; + +Function TDatabase.GetDataset(Index : longint) : TDataset; + +begin + If Assigned(FDatasets) then + Result:=TDataset(FDatasets[Index]) + else + begin + result := nil; + DatabaseError(SNoDatasets); + end; +end; + +Function TDatabase.GetTransaction(Index : longint) : TDBtransaction; + +begin + If Assigned(FTransactions) then + Result:=TDBTransaction(FTransactions[Index]) + else + begin + result := nil; + DatabaseError(SNoTransactions); + end; +end; + +procedure TDatabase.RegisterDataset (DS : TDBDataset); + +Var I : longint; + +begin + I:=FDatasets.IndexOf(DS); + If I=-1 then + FDatasets.Add(DS) + else + DatabaseErrorFmt(SDatasetRegistered,[DS.Name]); +end; + +procedure TDatabase.RegisterTransaction (TA : TDBTransaction); + +Var I : longint; + +begin + I:=FTransactions.IndexOf(TA); + If I=-1 then + FTransactions.Add(TA) + else + DatabaseErrorFmt(STransactionRegistered,[TA.Name]); +end; + +procedure TDatabase.UnRegisterDataset (DS : TDBDataset); + +Var I : longint; + +begin + I:=FDatasets.IndexOf(DS); + If I<>-1 then + FDatasets.Delete(I) + else + DatabaseErrorFmt(SNoDatasetRegistered,[DS.Name]); +end; + +procedure TDatabase.UnRegisterTransaction (TA : TDBTransaction); + +Var I : longint; + +begin + I:=FTransactions.IndexOf(TA); + If I<>-1 then + FTransactions.Delete(I) + else + DatabaseErrorFmt(SNoTransactionRegistered,[TA.Name]); +end; + + +{ --------------------------------------------------------------------- + TDBdataset + ---------------------------------------------------------------------} + +Procedure TDBDataset.SetDatabase (Value : TDatabase); + +begin + If Value<>FDatabase then + begin + CheckInactive; + If Assigned(FDatabase) then + FDatabase.UnregisterDataset(Self); + If Value<>Nil Then + Value.RegisterDataset(Self); + FDatabase:=Value; + end; +end; + +Procedure TDBDataset.SetTransaction (Value : TDBTransaction); + +begin + CheckInactive; + If Value<>FTransaction then + begin + If Assigned(FTransaction) then + FTransaction.UnregisterDataset(Self); + If Value<>Nil Then + Value.RegisterDataset(Self); + FTransaction:=Value; + end; +end; + +Procedure TDBDataset.CheckDatabase; + +begin + If (FDatabase=Nil) then + DatabaseError(SErrNoDatabaseAvailable,Self) +end; + +Destructor TDBDataset.Destroy; + +begin + Database:=Nil; + Transaction:=Nil; + Inherited; +end; + +{ --------------------------------------------------------------------- + TDBTransaction + ---------------------------------------------------------------------} +procedure TDBTransaction.SetActive(Value : boolean); +begin + if FActive and (not Value) then + EndTransaction + else if (not FActive) and Value then + if csLoading in ComponentState then + begin + FOpenAfterRead := true; + exit; + end + else + StartTransaction; +end; + +procedure TDBTransaction.Loaded; + +begin + inherited; + try + if FOpenAfterRead then SetActive(true); + except + if csDesigning in Componentstate then + InternalHandleException + else + raise; + end; +end; + +Procedure TDBTransaction.InternalHandleException; + +begin + if assigned(classes.ApplicationHandleException) then + classes.ApplicationHandleException(self) + else + ShowException(ExceptObject,ExceptAddr); +end; + +Procedure TDBTransaction.CheckActive; + +begin + If not FActive Then + DatabaseError(STransNotActive,Self); +end; + +Procedure TDBTransaction.CheckInActive; + +begin + If FActive Then + DatabaseError(STransActive,Self); +end; + +Procedure TDBTransaction.CloseTrans; + +begin + FActive := false; +end; + +Procedure TDBTransaction.OpenTrans; + +begin + FActive := true; +end; + +Procedure TDBTransaction.SetDatabase (Value : TDatabase); + +begin + If Value<>FDatabase then + begin + CheckInactive; + If Assigned(FDatabase) then + FDatabase.UnregisterTransaction(Self); + If Value<>Nil Then + Value.RegisterTransaction(Self); + FDatabase:=Value; + end; +end; + +constructor TDBTransaction.create(AOwner : TComponent); + +begin + inherited create(AOwner); + FDatasets:=TList.Create; +end; + +Procedure TDBTransaction.CheckDatabase; + +begin + If (FDatabase=Nil) then + DatabaseError(SErrNoDatabaseAvailable,Self) +end; + +procedure TDBTransaction.CloseDataSets; + +Var I : longint; + +begin + If Assigned(FDatasets) then + begin + For I:=FDatasets.Count-1 downto 0 do + TDBDataset(FDatasets[i]).Close; + end; +end; + +Destructor TDBTransaction.Destroy; + +begin + Database:=Nil; + CloseDataSets; + RemoveDatasets; + FDatasets.Free; + Inherited; +end; + +procedure TDBTransaction.RemoveDataSets; + +Var I : longint; + +begin + If Assigned(FDatasets) then + For I:=FDataSets.Count-1 downto 0 do + TDBDataset(FDataSets[i]).Transaction:=Nil; +end; + +Function TDBTransaction.GetDataSetCount : Longint; + +begin + If Assigned(FDatasets) Then + Result:=FDatasets.Count + else + Result:=0; +end; + +procedure TDBTransaction.UnRegisterDataset (DS : TDBDataset); + +Var I : longint; + +begin + I:=FDatasets.IndexOf(DS); + If I<>-1 then + FDatasets.Delete(I) + else + DatabaseErrorFmt(SNoDatasetRegistered,[DS.Name]); +end; + +procedure TDBTransaction.RegisterDataset (DS : TDBDataset); + +Var I : longint; + +begin + I:=FDatasets.IndexOf(DS); + If I=-1 then + FDatasets.Add(DS) + else + DatabaseErrorFmt(SDatasetRegistered,[DS.Name]); +end; + +Function TDBTransaction.GetDataset(Index : longint) : TDBDataset; + +begin + If Assigned(FDatasets) then + Result:=TDBDataset(FDatasets[Index]) + else + begin + result := nil; + DatabaseError(SNoDatasets); + end; +end; + +{ --------------------------------------------------------------------- + TCustomConnection + ---------------------------------------------------------------------} + +procedure TCustomConnection.SetAfterConnect(const AValue: TNotifyEvent); +begin + FAfterConnect:=AValue; +end; + +function TCustomConnection.GetDataSet(Index: Longint): TDataSet; +begin + Result := nil; +end; + +function TCustomConnection.GetDataSetCount: Longint; +begin + Result := 0; +end; + +procedure TCustomConnection.InternalHandleException; +begin + if assigned(classes.ApplicationHandleException) then + classes.ApplicationHandleException(self) + else + ShowException(ExceptObject,ExceptAddr); +end; + +procedure TCustomConnection.SetAfterDisconnect(const AValue: TNotifyEvent); +begin + FAfterDisconnect:=AValue; +end; + +procedure TCustomConnection.SetBeforeConnect(const AValue: TNotifyEvent); +begin + FBeforeConnect:=AValue; +end; + +procedure TCustomConnection.SetConnected(Value: boolean); +begin + If Value<>Connected then + begin + If Value then + begin + if csReading in ComponentState then + begin + FStreamedConnected := true; + exit; + end + else + begin + if Assigned(BeforeConnect) then + BeforeConnect(self); + if FLoginPrompt then if assigned(FOnLogin) then + FOnLogin(self,'',''); + DoConnect; + if Assigned(AfterConnect) then + AfterConnect(self); + end; + end + else + begin + if Assigned(BeforeDisconnect) then + BeforeDisconnect(self); + DoDisconnect; + if Assigned(AfterDisconnect) then + AfterDisconnect(self); + end; + end; +end; + +procedure TCustomConnection.SetBeforeDisconnect(const AValue: TNotifyEvent); +begin + FBeforeDisconnect:=AValue; +end; + +procedure TCustomConnection.DoConnect; + +begin + // Do nothing yet +end; + +procedure TCustomConnection.DoDisconnect; + +begin + // Do nothing yet +end; + +function TCustomConnection.GetConnected: boolean; + +begin + Result := False; +end; + +procedure TCustomConnection.Loaded; +begin + inherited Loaded; + try + if FStreamedConnected then + SetConnected(true); + except + if csDesigning in Componentstate then + InternalHandleException + else + raise; + end; +end; + +procedure TCustomConnection.Close; +begin + Connected := False; +end; + +destructor TCustomConnection.Destroy; +begin + Connected:=False; + Inherited Destroy; +end; + +procedure TCustomConnection.Open; +begin + Connected := True; +end; + + +procedure SkipQuotesString(var p : pchar; QuoteChar : char; EscapeSlash, EscapeRepeat : Boolean); +var notRepeatEscaped : boolean; +begin + Inc(p); + repeat + notRepeatEscaped := True; + while not (p^ in [#0, QuoteChar]) do + begin + if EscapeSlash and (p^='\') and (p[1] <> #0) then Inc(p,2) // make sure we handle \' and \\ correct + else Inc(p); + end; + if p^=QuoteChar then + begin + Inc(p); // skip final ' + if (p^=QuoteChar) and EscapeRepeat then // Handle escaping by '' + begin + notRepeatEscaped := False; + inc(p); + end + end; + until notRepeatEscaped; +end; + +{ TParams } + +Function TParams.GetItem(Index: Integer): TParam; +begin + Result:=(Inherited GetItem(Index)) as TParam; +end; + +Function TParams.GetParamValue(const ParamName: string): Variant; +begin + Result:=ParamByName(ParamName).Value; +end; + +Procedure TParams.SetItem(Index: Integer; Value: TParam); +begin + Inherited SetItem(Index,Value); +end; + +Procedure TParams.SetParamValue(const ParamName: string; const Value: Variant); +begin + ParamByName(ParamName).Value:=Value; +end; + +Procedure TParams.AssignTo(Dest: TPersistent); +begin + if (Dest is TParams) then + TParams(Dest).Assign(Self) + else + inherited AssignTo(Dest); +end; + +Function TParams.GetDataSet: TDataSet; +begin + If (FOwner is TDataset) Then + Result:=TDataset(FOwner) + else + Result:=Nil; +end; + +Function TParams.GetOwner: TPersistent; +begin + Result:=FOwner; +end; + + +constructor TParams.Create(AOwner: TPersistent); +begin + Inherited Create(TParam); + Fowner:=AOwner; +end; + +constructor TParams.Create; +begin + Create(TPersistent(Nil)); +end; + +Procedure TParams.AddParam(Value: TParam); +begin + Value.Collection:=Self; +end; + +Procedure TParams.AssignValues(Value: TParams); + +Var + I : Integer; + P,PS : TParam; + +begin + For I:=0 to Value.Count-1 do + begin + PS:=Value[i]; + P:=FindParam(PS.Name); + If Assigned(P) then + P.Assign(PS); + end; +end; + +Function TParams.CreateParam(FldType: TFieldType; const ParamName: string; + ParamType: TParamType): TParam; + +begin + Result:=Add as TParam; + Result.Name:=ParamName; + Result.DataType:=FldType; + Result.ParamType:=ParamType; +end; + +Function TParams.FindParam(const Value: string): TParam; + +Var + I : Integer; + +begin + Result:=Nil; + I:=Count-1; + While (Result=Nil) and (I>=0) do + If (CompareText(Value,Items[i].Name)=0) then + Result:=Items[i] + else + Dec(i); +end; + +Procedure TParams.GetParamList(List: TList; const ParamNames: string); + +Var + P: TParam; + N: String; + StrPos: Integer; + +begin + if (ParamNames = '') or (List = nil) then + Exit; + StrPos := 1; + repeat + N := ExtractFieldName(ParamNames, StrPos); + P := ParamByName(N); + List.Add(P); + until StrPos > Length(ParamNames); +end; + +Function TParams.IsEqual(Value: TParams): Boolean; + +Var + I : Integer; + +begin + Result:=(Value.Count=Count); + I:=Count-1; + While Result and (I>=0) do + begin + Result:=Items[I].IsEqual(Value[i]); + Dec(I); + end; +end; + +Function TParams.ParamByName(const Value: string): TParam; +begin + Result:=FindParam(Value); + If (Result=Nil) then + DatabaseErrorFmt(SParameterNotFound,[Value],Dataset); +end; + +Function TParams.ParseSQL(SQL: String; DoCreate: Boolean): String; + +var pb : TParamBinding; + rs : string; + +begin + Result := ParseSQL(SQL,DoCreate,True,True,psInterbase, pb, rs); +end; + +Function TParams.ParseSQL(SQL: String; DoCreate, EscapeSlash, EscapeRepeat : Boolean; ParameterStyle : TParamStyle): String; + +var pb : TParamBinding; + rs : string; + +begin + Result := ParseSQL(SQL,DoCreate,EscapeSlash,EscapeRepeat,ParameterStyle,pb, rs); +end; + +Function TParams.ParseSQL(SQL: String; DoCreate, EscapeSlash, EscapeRepeat : Boolean; ParameterStyle : TParamStyle; var ParamBinding: TParambinding): String; + +var rs : string; + +begin + Result := ParseSQL(SQL,DoCreate,EscapeSlash, EscapeRepeat, ParameterStyle,ParamBinding, rs); +end; + +function SkipComments(var p: PChar; EscapeSlash, EscapeRepeat : Boolean) : Boolean; + +begin + result := false; + case p^ of + '''': + begin + SkipQuotesString(p,'''',EscapeSlash,EscapeRepeat); // single quote delimited string + Result := True; + end; + '"': + begin + SkipQuotesString(p,'"',EscapeSlash,EscapeRepeat); // double quote delimited string + Result := True; + end; + '-': // possible start of -- comment + begin + Inc(p); + if p^='-' then // -- comment + begin + Result := True; + repeat // skip until at end of line + Inc(p); + until p^ in [#10, #0]; + end; + if p^<>#0 then Inc(p); // newline is part of comment + end; + '/': // possible start of /* */ comment + begin + Inc(p); + if p^='*' then // /* */ comment + begin + Result := True; + repeat + Inc(p); + if p^='*' then // possible end of comment + begin + Inc(p); + if p^='/' then Break; // end of comment + end; + until p^=#0; + if p^='/' then Inc(p); // skip final / + end; + end; + end; {case} +end; + +Function TParams.ParseSQL(SQL: String; DoCreate, EscapeSlash, EscapeRepeat: Boolean; ParameterStyle : TParamStyle; var ParamBinding: TParambinding; var ReplaceString : string): String; + +type + // used for ParamPart + TStringPart = record + Start,Stop:integer; + end; + +const + ParamAllocStepSize = 8; + +var + IgnorePart:boolean; + p,ParamNameStart,BufStart:PChar; + ParamName:string; + QuestionMarkParamCount,ParameterIndex,NewLength:integer; + ParamCount:integer; // actual number of parameters encountered so far; + // always <= Length(ParamPart) = Length(Parambinding) + // Parambinding will have length ParamCount in the end + ParamPart:array of TStringPart; // describe which parts of buf are parameters + NewQueryLength:integer; + NewQuery:string; + NewQueryIndex,BufIndex,CopyLen,i:integer; // Parambinding will have length ParamCount in the end + b:integer; + tmpParam:TParam; + +begin + if DoCreate then Clear; + // Parse the SQL and build ParamBinding + ParamCount:=0; + paramname:= ''; + paramnamestart:= nil; + NewQueryLength:=Length(SQL); + SetLength(ParamPart,ParamAllocStepSize); + SetLength(Parambinding,ParamAllocStepSize); + QuestionMarkParamCount:=0; // number of ? params found in query so far + + ReplaceString := '$'; + if ParameterStyle = psSimulated then + while pos(ReplaceString,SQL) > 0 do ReplaceString := ReplaceString+'$'; + + p:=PChar(SQL); + BufStart:=p; // used to calculate ParamPart.Start values + repeat + SkipComments(p,EscapeSlash,EscapeRepeat); + case p^ of + ':','?': // parameter + begin + IgnorePart := False; + if p^=':' then + begin // find parameter name + Inc(p); + if p^ in [':','=',' '] then // ignore ::, since some databases uses this as a cast (wb 4813) + begin + IgnorePart := True; + Inc(p); + end + else + begin + if p^='"' then // Check if the parameter-name is between quotes + begin + ParamNameStart:=p; + SkipQuotesString(p,'"',EscapeSlash,EscapeRepeat); + // Do not include the quotes in ParamName, but they must be included + // when the parameter is replaced by some place-holder. + ParamName:=Copy(ParamNameStart+1,1,p-ParamNameStart-2); + end + else + begin + ParamNameStart:=p; + while not (p^ in (SQLDelimiterCharacters+[#0,'=','+','-','*','\','/','[',']','|'])) do + Inc(p); + ParamName:=Copy(ParamNameStart,1,p-ParamNameStart); + end; + end; + end + else + begin + Inc(p); + ParamNameStart:=p; + ParamName:=''; + end; + + if not IgnorePart then + begin + Inc(ParamCount); + if ParamCount>Length(ParamPart) then + begin + NewLength:=Length(ParamPart)+ParamAllocStepSize; + SetLength(ParamPart,NewLength); + SetLength(ParamBinding,NewLength); + end; + + if DoCreate then + begin + // Check if this is the first occurance of the parameter + tmpParam := FindParam(ParamName); + // If so, create the parameter and assign the Parameterindex + if not assigned(tmpParam) then + ParameterIndex := CreateParam(ftUnknown, ParamName, ptInput).Index + else // else only assign the ParameterIndex + ParameterIndex := tmpParam.Index; + end + // else find ParameterIndex + else + begin + if ParamName<>'' then + ParameterIndex:=ParamByName(ParamName).Index + else + begin + ParameterIndex:=QuestionMarkParamCount; + Inc(QuestionMarkParamCount); + end; + end; + if ParameterStyle in [psPostgreSQL,psSimulated] then + begin + i:=ParameterIndex+1; + repeat + inc(NewQueryLength); + i:=i div 10; + until i=0; + end; + + // store ParameterIndex in FParamIndex, ParamPart data + ParamBinding[ParamCount-1]:=ParameterIndex; + ParamPart[ParamCount-1].Start:=ParamNameStart-BufStart; + ParamPart[ParamCount-1].Stop:=p-BufStart+1; + + // update NewQueryLength + Dec(NewQueryLength,p-ParamNameStart); + end; + end; + #0:Break; + else + Inc(p); + end; + until false; + + SetLength(ParamPart,ParamCount); + SetLength(ParamBinding,ParamCount); + + if ParamCount>0 then + begin + // replace :ParamName by ? for interbase and by $x for postgresql/psSimulated + // (using ParamPart array and NewQueryLength) + if (ParameterStyle = psSimulated) and (length(ReplaceString) > 1) then + inc(NewQueryLength,(paramcount)*(length(ReplaceString)-1)); + + SetLength(NewQuery,NewQueryLength); + NewQueryIndex:=1; + BufIndex:=1; + for i:=0 to High(ParamPart) do + begin + CopyLen:=ParamPart[i].Start-BufIndex; + Move(SQL[BufIndex],NewQuery[NewQueryIndex],CopyLen); + Inc(NewQueryIndex,CopyLen); + case ParameterStyle of + psInterbase : begin + NewQuery[NewQueryIndex]:='?'; + Inc(NewQueryIndex); + end; + psPostgreSQL, + psSimulated : begin + ParamName := IntToStr(ParamBinding[i]+1); + for b := 1 to length(ReplaceString) do + begin + NewQuery[NewQueryIndex]:='$'; + Inc(NewQueryIndex); + end; + for b := 1 to length(ParamName) do + begin + NewQuery[NewQueryIndex]:=ParamName[b]; + Inc(NewQueryIndex); + end; + end; + end; + BufIndex:=ParamPart[i].Stop; + end; + CopyLen:=Length(SQL)+1-BufIndex; + if CopyLen > 0 then + Move(SQL[BufIndex],NewQuery[NewQueryIndex],CopyLen); + end + else + NewQuery:=SQL; + + Result := NewQuery; +end; + + +Procedure TParams.RemoveParam(Value: TParam); +begin + Value.Collection:=Nil; +end; + +{ TParam } + +Function TParam.GetDataSet: TDataSet; +begin + If Assigned(Collection) and (Collection is TParams) then + Result:=TParams(Collection).GetDataset + else + Result:=Nil; +end; + +Function TParam.IsParamStored: Boolean; +begin + Result:=Bound; +end; + +function TParam.getasnullmsestring: msestring; +begin + if isnull then begin + result:= ''; + end + else begin + result:= getasunicodestring(); + end; +end; + +procedure TParam.setasnullmsestring(const avalue: msestring); +begin + if avalue = '' then begin + clear; + end + else begin + setasunicodestring(avalue); + end; +end; + +Procedure TParam.AssignParam(Param: TParam); +begin + if Not Assigned(Param) then + begin + Clear; + FDataType:=ftunknown; + FParamType:=ptUnknown; + Name:=''; + Size:=0; + Precision:=0; + NumericScale:=0; + blobkind:= bk_none; + end + else + begin + FDataType:=Param.DataType; + if Param.IsNull then + Clear + else + FValue:=Param.FValue; + FBound:=Param.Bound; + Name:=Param.Name; + if (ParamType=ptUnknown) then + ParamType:=Param.ParamType; + Size:=Param.Size; + Precision:=Param.Precision; + NumericScale:=Param.NumericScale; + blobkind:=Param.blobkind; + end; +end; + +Procedure TParam.AssignTo(Dest: TPersistent); +begin + if (Dest is TField) then + AssignToField(TField(Dest)) + else + inherited AssignTo(Dest); +end; + +Function TParam.GetAsBoolean: Boolean; +begin + If IsNull then + Result:=False + else + Result:=FValue; +end; + +Function TParam.GetAsCurrency: Currency; +begin + If IsNull then + Result:=0.0 + else + Result:=FValue; +end; + +Function TParam.GetAsDateTime: TDateTime; +begin + If IsNull then + Result:=0.0 + else + Result:=FValue; +end; + +Function TParam.GetAsFloat: Double; +begin + If IsNull then + Result:=0.0 + else + Result:=FValue; +end; + +Function TParam.GetAsInteger: Longint; +begin + If IsNull then + Result:=0 + else + Result:=FValue; +end; + +Function TParam.GetAsLargeInt: LargeInt; +begin + If IsNull then + Result:=0 + else + Result:=FValue; +end; + + +Function TParam.GetAsMemo: string; +begin + If IsNull then + Result:='' + else + Result:=FValue; +end; + +Function TParam.GetAsString: string; +var P: Pointer; +begin + If IsNull then + Result:='' + else if (FDataType in [ftBytes, ftVarBytes]) and VarIsArray(FValue) then + begin + SetLength(Result, (VarArrayHighBound(FValue, 1) + 1) div SizeOf(Char)); + P := VarArrayLock(FValue); + try + Move(P^, Result[1], Length(Result) * SizeOf(Char)); + finally + VarArrayUnlock(FValue); + end; + end + else + Result:=FValue; +end; + +function TParam.GetAsWideString: WideString; +begin + if IsNull then + Result := '' + else + Result := FValue; +end; + + +Function TParam.GetAsVariant: Variant; +begin + if IsNull then + Result:=Null + else + Result:=FValue; +end; + +function TParam.GetAsFMTBCD: TBCD; +begin + If IsNull then + Result:= nullbcd + else + Result:=VarToBCD(FValue); +end; + +Function TParam.GetDisplayName: string; +begin + if (FName<>'') then + Result:=FName + else + Result:=inherited GetDisplayName +end; + +Function TParam.GetIsNull: Boolean; +begin + Result:= VarIsNull(FValue) or VarIsClear(FValue); +end; + +Function TParam.IsEqual(AValue: TParam): Boolean; +begin + Result:=(Name=AValue.Name) + and (IsNull=AValue.IsNull) + and (Bound=AValue.Bound) + and (DataType=AValue.DataType) + and (ParamType=AValue.ParamType) + and (VarType(FValue)=VarType(AValue.FValue)) + and (FValue=AValue.FValue); +end; + +Procedure TParam.SetAsBlob(const AValue: TBlobData); +begin + FDataType:=ftBlob; + Value:=AValue; +end; + +Procedure TParam.SetAsBoolean(AValue: Boolean); +begin + FDataType:=ftBoolean; + Value:=AValue; +end; + +Procedure TParam.SetAsCurrency(const AValue: Currency); +begin + FDataType:=ftCurrency; + Value:=Avalue; +end; + +Procedure TParam.SetAsDate(const AValue: TDateTime); +begin + FDataType:=ftDate; + Value:=Avalue; +end; + +Procedure TParam.SetAsDateTime(const AValue: TDateTime); +begin + FDataType:=ftDateTime; + Value:=AValue; +end; + +Procedure TParam.SetAsFloat(const AValue: Double); +begin + FDataType:=ftFloat; + Value:=AValue; +end; + +Procedure TParam.SetAsInteger(AValue: Longint); +begin + FDataType:=ftInteger; + Value:=AValue; +end; + +Procedure TParam.SetAsLargeInt(AValue: LargeInt); +begin + FDataType:=ftLargeint; + Value:=AValue; +end; + +Procedure TParam.SetAsMemo(const AValue: string); +begin + FDataType:=ftMemo; + Value:=AValue; +end; + + +Procedure TParam.SetAsSmallInt(AValue: LongInt); +begin + FDataType:=ftSmallInt; + Value:=AValue; +end; + +Procedure TParam.SetAsString(const AValue: string); +begin + if FDataType <> ftFixedChar then + FDataType := ftString; + Value:=AValue; +end; + +procedure TParam.SetAsWideString(const aValue: WideString); +begin + if FDataType <> ftFixedWideChar then + FDataType := ftWideString; + Value := aValue; +end; + +function TParam.getasunicodestring: unicodestring; +begin + if IsNull then + Result := '' + else + Result := FValue; +end; + +procedure TParam.setasunicodestring(const avalue: unicodestring); +begin + if FDataType <> ftFixedWideChar then + FDataType := ftWideString; + Value := aValue; +end; + +function tparam.getasid: int64; +begin + if isnull then begin + result:= -1; + end + else begin + result:= aslargeint; + end; +end; + +procedure tparam.setasid(const avalue: int64); +begin + if avalue = -1 then begin + clear; + end + else begin + aslargeint:= avalue; + end; +end; + + +Procedure TParam.SetAsTime(const AValue: TDateTime); +begin + FDataType:=ftTime; + Value:=AValue; +end; + +Procedure TParam.SetAsVariant(const AValue: Variant); +begin + FValue:=AValue; + FBound:=not VarIsClear(AValue); + if FDataType = ftUnknown then + case VarType(Value) of + varBoolean : FDataType:=ftBoolean; + varSmallint, + varShortInt, + varByte : FDataType:=ftSmallInt; + varWord, + varInteger : FDataType:=ftInteger; + varCurrency : FDataType:=ftCurrency; + varLongWord, + varSingle, + varDouble : FDataType:=ftFloat; + varDate : FDataType:=ftDateTime; + varString, + varOleStr : if (FDataType<>ftFixedChar) then + FDataType:=ftString; + varInt64 : FDataType:=ftLargeInt; + else + if VarIsFmtBCD(Value) then + FDataType:=ftFmtBCD + else if VarIsArray(AValue) and (VarType(AValue) and varTypeMask = varByte) then + FDataType:=ftBytes + else + FDataType:=ftUnknown; + end; +end; + +Procedure TParam.SetAsWord(AValue: LongInt); +begin + FDataType:=ftWord; + Value:=AValue; +end; + +procedure TParam.SetAsFMTBCD(const AValue: TBCD); +begin + FDataType:=ftFMTBcd; + FValue:=VarFmtBCDCreate(AValue); +end; + +Procedure TParam.SetDataType(AValue: TFieldType); + +Var + VT : Integer; + +begin + FDataType:=AValue; + VT:=FieldTypetoVariantMap[AValue]; + If (VT=varError) then + clear + else + if not VarIsEmpty(FValue) then + begin + Try + FValue:=VarAsType(FValue,VT) + except + Clear; + end { try } + end; +end; + +Procedure TParam.SetText(const AValue: string); +begin + Value:=AValue; +end; + +constructor TParam.Create(ACollection: TCollection); +begin + inherited Create(ACollection); + ParamType:=ptUnknown; + DataType:=ftUnknown; + FValue:=Unassigned; +end; + +constructor TParam.Create(AParams: TParams; AParamType: TParamType); +begin + Create(AParams); + ParamType:=AParamType; +end; + +Procedure TParam.Assign(Source: TPersistent); +begin + if (Source is TParam) then + AssignParam(TParam(Source)) + else if (Source is TField) then + AssignField(TField(Source)) + else if (source is TStrings) then + AsMemo:=TStrings(Source).Text + else + inherited Assign(Source); +end; + +Procedure TParam.AssignField(Field: TField); +begin + if Assigned(Field) then + begin + // Need TField.Value + AssignFieldValue(Field,Field.Value); + Name:=Field.FieldName; + end + else + begin + Clear; + Name:=''; + end +end; + +procedure TParam.AssignToField(Field : TField); + +begin + if Assigned(Field) then + case FDataType of + ftUnknown : DatabaseErrorFmt(SUnknownParamFieldType,[Name],DataSet); + // Need TField.AsSmallInt + ftSmallint : Field.AsInteger:=AsSmallInt; + // Need TField.AsWord + ftWord : Field.AsInteger:=AsWord; + ftInteger, + ftAutoInc : Field.AsInteger:=AsInteger; + ftCurrency : Field.AsCurrency:=AsCurrency; + ftFloat : Field.AsFloat:=AsFloat; + ftBoolean : Field.AsBoolean:=AsBoolean; + ftBlob, + ftGraphic..ftTypedBinary, + ftOraBlob, + ftOraClob, + ftString, + ftMemo, + ftAdt, + ftFixedChar: Field.AsString:=AsString; + ftTime, + ftDate, + ftDateTime : Field.AsDateTime:=AsDateTime; + ftBytes, + ftVarBytes : Field.AsVariant:=Value; + ftFmtBCD : Field.AsBCD:=AsFMTBCD; + else + If not (DataType in [ftCursor, ftArray, ftDataset,ftReference]) then + DatabaseErrorFmt(SBadParamFieldType, [Name], DataSet); + end; +end; + +procedure TParam.AssignFromField(Field : TField); + +begin + if Assigned(Field) then + begin + FDataType:=Field.DataType; + case Field.DataType of + ftUnknown : DatabaseErrorFmt(SUnknownParamFieldType,[Name],DataSet); + // Need TField.AsSmallInt + ftSmallint : AsSmallint:=Field.AsInteger; + // Need TField.AsWord + ftWord : AsWord:=Field.AsInteger; + ftInteger, + ftAutoInc : AsInteger:=Field.AsInteger; + ftBCD, + ftCurrency : AsCurrency:=Field.AsCurrency; + ftFloat : AsFloat:=Field.AsFloat; + ftBoolean : AsBoolean:=Field.AsBoolean; + ftBlob, + ftGraphic..ftTypedBinary, + ftOraBlob, + ftOraClob, + ftString, + ftMemo, + ftAdt, + ftFixedChar: AsString:=Field.AsString; + ftTime, + ftDate, + ftDateTime : AsDateTime:=Field.AsDateTime; + ftBytes, + ftVarBytes : Value:=Field.AsVariant; + ftFmtBCD : AsFMTBCD:=Field.AsBCD; + else + If not (DataType in [ftCursor, ftArray, ftDataset,ftReference]) then + DatabaseErrorFmt(SBadParamFieldType, [Name], DataSet); + end; + end; +end; + +Procedure TParam.AssignFieldValue(Field: TField; const AValue: Variant); + +begin + If Assigned(Field) then + begin + + if (Field.DataType = ftString) and TStringField(Field).FixedChar then + FDataType := ftFixedChar + else if (Field.DataType = ftMemo) and (Field.Size > 255) then + FDataType := ftString + else if (Field.DataType = ftWideString) and TWideStringField(Field).FixedChar then + FDataType := ftFixedWideChar + else if (Field.DataType = ftWideMemo) and (Field.Size > 255) then + FDataType := ftWideString + else + FDataType := Field.DataType; + + if VarIsNull(AValue) then + Clear + else + Value:=AValue; + + Size:=Field.DataSize; + FBound:=True; + + end; +end; + +Procedure TParam.Clear; +begin + FValue:=UnAssigned; + fblobkind:= bk_none; +end; + +Procedure TParam.GetData(Buffer: Pointer); + +Var + P : Pointer; + S : String; + ws : WideString; + l : Integer; +begin + case FDataType of + ftUnknown : DatabaseErrorFmt(SUnknownParamFieldType,[Name],DataSet); + ftSmallint : PSmallint(Buffer)^:=AsSmallInt; + ftWord : PWord(Buffer)^:=AsWord; + ftInteger, + ftAutoInc : PInteger(Buffer)^:=AsInteger; + ftCurrency : PDouble(Buffer)^:=AsCurrency; + ftFloat : PDouble(Buffer)^:=AsFloat; + ftBoolean : PWordBool(Buffer)^:=AsBoolean; + ftString, + ftMemo, + ftAdt, + ftFixedChar: + begin + S:=AsString; + StrMove(PChar(Buffer),Pchar(S),Length(S)+1); + end; + ftWideString, + ftWideMemo: begin + ws := GetAsWideString; + l := Length(ws); + if l > 0 then + Move(ws[1], Buffer, Succ(l)*2) + else + PWideChar(Buffer)^ := #0 + end; + ftTime : PInteger(Buffer)^:=DateTimeToTimeStamp(AsTime).Time; + ftDate : PInteger(Buffer)^:=DateTimeToTimeStamp(AsTime).Date; + ftDateTime : PDouble(Buffer)^:=TimeStampToMSecs(DateTimeToTimeStamp(AsDateTime)); + ftBlob, + ftGraphic..ftTypedBinary, + ftOraBlob, + ftOraClob : + begin + S:=GetAsString; + Move(PChar(S)^, Buffer^, Length(S)); + end; + ftBytes, ftVarBytes: + begin + if VarIsArray(FValue) then + begin + P:=VarArrayLock(FValue); + try + Move(P^, Buffer^, VarArrayHighBound(FValue, 1) + 1); + finally + VarArrayUnlock(FValue); + end; + end; + end; + ftFmtBCD : PBCD(Buffer)^:=AsFMTBCD; + else + If not (DataType in [ftCursor, ftArray, ftDataset,ftReference]) then + DatabaseErrorFmt(SBadParamFieldType, [Name], DataSet); + end; +end; + +Function TParam.GetDataSize: Integer; +begin + Result:=0; + case DataType of + ftUnknown : DatabaseErrorFmt(SUnknownParamFieldType,[Name],DataSet); + ftBoolean : Result:=SizeOf(WordBool); + ftInteger, + ftAutoInc : Result:=SizeOf(Integer); + ftSmallint : Result:=SizeOf(SmallInt); + ftWord : Result:=SizeOf(Word); + ftTime, + ftDate : Result:=SizeOf(Integer); + ftDateTime, + ftCurrency, + ftFloat : Result:=SizeOf(Double); + ftString, + ftFixedChar, + ftMemo, + ftADT : Result:=Length(AsString)+1; + ftBytes, + ftVarBytes : if VarIsArray(FValue) then + Result:=VarArrayHighBound(FValue,1)+1 + else + Result:=0; + ftBlob, + ftGraphic..ftTypedBinary, + ftOraClob, + ftOraBlob : Result:=Length(AsString); + ftArray, + ftDataSet, + ftReference, + ftCursor : Result:=0; + ftFmtBCD : Result:=SizeOf(TBCD); + else + DatabaseErrorFmt(SBadParamFieldType,[Name],DataSet); + end; + + +end; + +Procedure TParam.LoadFromFile(const FileName: string; BlobType: TBlobType); + +Var + S : TFileStream; + +begin + S:=TFileStream.Create(FileName,fmOpenRead); + Try + LoadFromStream(S,BlobType); + Finally + FreeAndNil(S); + end; +end; + +Procedure TParam.LoadFromStream(Stream: TStream; BlobType: TBlobType); + +Var + Temp : String; + +begin + FDataType:=BlobType; + With Stream do + begin + Position:=0; + SetLength(Temp,Size); + ReadBuffer(Pointer(Temp)^,Size); + FValue:=Temp; + end; +end; + +Procedure TParam.SetBlobData(Buffer: Pointer; ASize: Integer); + +Var + Temp : String; + +begin + SetLength(Temp,ASize); + Move(Buffer^,Temp,ASize); + AsBlob:=Temp; +end; + +Procedure TParam.SetData(Buffer: Pointer); + + Function FromTimeStamp(T,D : Integer) : TDateTime; + + Var TS : TTimeStamp; + + begin + TS.Time:=T; + TS.Date:=D; + Result:=TimeStampToDateTime(TS); + end; + +begin + case FDataType of + ftUnknown : DatabaseErrorFmt(SUnknownParamFieldType,[Name],DataSet); + ftSmallint : AsSmallInt:=PSmallint(Buffer)^; + ftWord : AsWord:=PWord(Buffer)^; + ftInteger, + ftAutoInc : AsInteger:=PInteger(Buffer)^; + ftCurrency : AsCurrency:= PDouble(Buffer)^; + ftFloat : AsFloat:=PDouble(Buffer)^; + ftBoolean : AsBoolean:=PWordBool(Buffer)^; + ftString, + ftFixedChar: AsString:=StrPas(Buffer); + ftMemo : AsMemo:=StrPas(Buffer); + ftTime : AsTime:=FromTimeStamp(PInteger(Buffer)^,DateDelta); + ftDate : Asdate:=FromTimeStamp(0,PInteger(Buffer)^); + ftDateTime : AsDateTime:=TimeStampToDateTime(MSecsToTimeStamp(trunc(PDouble(Buffer)^))); + ftCursor : FValue:=0; + ftBlob, + ftGraphic..ftTypedBinary, + ftOraBlob, + ftOraClob : SetBlobData(Buffer, StrLen(PChar(Buffer))); + ftFmtBCD : AsFMTBCD:=PBCD(Buffer)^; + else + DatabaseErrorFmt(SBadParamFieldType,[Name],DataSet); + end; +end; + +Procedure TParams.CopyParamValuesFromDataset(ADataset : TDataset; CopyBound : Boolean); + +Var + I : Integer; + P : TParam; + F : TField; + +begin + If (ADataSet<>Nil) then + For I:=0 to Count-1 do + begin + P:=Items[i]; + if CopyBound or (not P.Bound) then + begin + F:=ADataset.FieldByName(P.Name); + P.AssignField(F); + If Not CopyBound then + P.Bound:=False; + end; + end; +end; + +{ EDatabaseError } + +constructor EDatabaseError.create(const msg: string; const comp: tcomponent); +begin + if (comp <> nil) and (comp.name <> '') then begin + createfmt('%s : %s',[comp.Name,msg]); + end + else begin + inherited create(msg); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/mdbf.pas b/mseide-msegui/lib/common/fpccompatibility/mdbf.pas new file mode 100644 index 0000000..162455a --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/mdbf.pas @@ -0,0 +1,3065 @@ +unit mdbf; + +// Modified 2013 by Martin Schreiber + +{ design info in dbf_reg.pas } + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{$I dbf_common.inc} + +uses + classes,mclasses, + mdb, + dbf_common, + dbf_dbffile, + dbf_parser, + mdbf_prsdef, + dbf_cursor, + dbf_fields, + dbf_pgfile, + dbf_idxfile; +// If you got a compilation error here or asking for dsgnintf.pas, then just add +// this file in your project: +// dsgnintf.pas in 'C: \Program Files\Borland\Delphi5\Source\Toolsapi\dsgnintf.pas' + +type + +//==================================================================== + pBookmarkData = ^TBookmarkData; + TBookmarkData = record + PhysicalRecNo: Integer; + end; + + pDbfRecord = ^TDbfRecordHeader; + TDbfRecordHeader = record + BookmarkData: TBookmarkData; + BookmarkFlag: TBookmarkFlag; + SequentialRecNo: Integer; + DeletedFlag: Char; + end; +//==================================================================== + TDbf = class; +//==================================================================== + TDbfStorage = (stoMemory,stoFile); + TDbfOpenMode = (omNormal,omAutoCreate,omTemporary); + TDbfLanguageAction = (laReadOnly, laForceOEM, laForceANSI, laDefault); + TDbfTranslationMode = (tmNoneAvailable, tmNoneNeeded, tmSimple, tmAdvanced); + TDbfFileName = (dfDbf, dfMemo, dfIndex); +//==================================================================== + TDbfFileNames = set of TDbfFileName; +//==================================================================== + TCompareRecordEvent = procedure(Dbf: TDbf; var Accept: Boolean) of object; + TTranslateEvent = function(Dbf: TDbf; Src, Dest: PChar; ToOem: Boolean): Integer of object; + TLanguageWarningEvent = procedure(Dbf: TDbf; var Action: TDbfLanguageAction) of object; + TConvertFieldEvent = procedure(Dbf: TDbf; DstField, SrcField: TField) of object; + TBeforeAutoCreateEvent = procedure(Dbf: TDbf; var DoCreate: Boolean) of object; +//==================================================================== + // TDbfBlobStream keeps a reference count to number of references to + // this instance. Only if FRefCount reaches zero, then the object will be + // destructed. AddReference `clones' a reference. + // This allows the VCL to use Free on the object to `free' that + // particular reference. + + TDbfBlobStream = class(TMemoryStream) + private + FBlobField: TBlobField; + FMode: TBlobStreamMode; + FDirty: boolean; { has possibly modified data, needs to be written } + FMemoRecNo: Integer; + { -1 : invalid contents } + { 0 : clear, no contents } + { >0 : data from page x } + FReadSize: Integer; + FRefCount: Integer; + + function GetTransliterate: Boolean; + procedure Translate(ToOem: Boolean); + procedure SetMode(NewMode: TBlobStreamMode); + public + constructor Create(FieldVal: TField); + destructor Destroy; override; + + function AddReference: TDbfBlobStream; + procedure FreeInstance; override; + + procedure Cancel; + procedure Commit; + + property Dirty: boolean read FDirty; + property Transliterate: Boolean read GetTransliterate; + property MemoRecNo: Integer read FMemoRecNo write FMemoRecNo; + property ReadSize: Integer read FReadSize write FReadSize; + property Mode: TBlobStreamMode write SetMode; + property BlobField: TBlobField read FBlobField; + end; +//==================================================================== + TDbfIndexDefs = class(TCollection) + public + FOwner: TDbf; + private + function GetItem(N: Integer): TDbfIndexDef; + procedure SetItem(N: Integer; Value: TDbfIndexDef); + protected + function GetOwner: TPersistent; override; + public + constructor Create(AOwner: TDbf); + + function Add: TDbfIndexDef; + function GetIndexByName(const Name: string): TDbfIndexDef; + function GetIndexByField(const Name: string): TDbfIndexDef; + procedure Update; {$ifdef SUPPORT_REINTRODUCE} reintroduce; {$endif} + + property Items[N: Integer]: TDbfIndexDef read GetItem write SetItem; default; + end; +//==================================================================== + TDbfMasterLink = class(TDataLink) + private + FDetailDataSet: TDbf; + FParser: TDbfParser; + FFieldNames: string; + FValidExpression: Boolean; + FOnMasterChange: TNotifyEvent; + FOnMasterDisable: TNotifyEvent; + + function GetFieldsVal: TRecordBuffer; + + procedure SetFieldNames(const Value: string); + protected + procedure ActiveChanged; override; + procedure CheckBrowseMode; override; + procedure LayoutChanged; override; + procedure RecordChanged(Field: TField); override; + + public + constructor Create(ADataSet: TDbf); + destructor Destroy; override; + + property FieldNames: string read FFieldNames write SetFieldNames; + property ValidExpression: Boolean read FValidExpression write FValidExpression; + property FieldsVal: TRecordBuffer read GetFieldsVal; + property Parser: TDbfParser read FParser; + + property OnMasterChange: TNotifyEvent read FOnMasterChange write FOnMasterChange; + property OnMasterDisable: TNotifyEvent read FOnMasterDisable write FOnMasterDisable; + end; +//==================================================================== + PDbfBlobList = ^TDbfBlobList; + TDbfBlobList = array[0..MaxListSize-1] of TDbfBlobStream; +//==================================================================== + TDbf = class(TDataSet) + private + FDbfFile: TDbfFile; + FCursor: TVirtualCursor; + FOpenMode: TDbfOpenMode; + FStorage: TDbfStorage; + FMasterLink: TDbfMasterLink; + FParser: TDbfParser; + FBlobStreams: PDbfBlobList; + FUserStream: TStream; // user stream to open + FTableName: string; // table path and file name + FRelativePath: string; + FAbsolutePath: string; + FIndexName: string; + FReadOnly: Boolean; + FFilterBuffer: TRecordBuffer; + FTempBuffer: TRecordBuffer; + FEditingRecNo: Integer; +{$ifdef SUPPORT_VARIANTS} + FLocateRecNo: Integer; +{$endif} + FLanguageID: Byte; + FTableLevel: Integer; + FExclusive: Boolean; + FShowDeleted: Boolean; + FPosting: Boolean; + FDisableResyncOnPost: Boolean; + FTempExclusive: Boolean; + FInCopyFrom: Boolean; + FStoreDefs: Boolean; + FCopyDateTimeAsString: Boolean; + FFindRecordFilter: Boolean; + FIndexFile: TIndexFile; + FDateTimeHandling: TDateTimeHandling; + FTranslationMode: TDbfTranslationMode; + FIndexDefs: TDbfIndexDefs; + FBeforeAutoCreate: TBeforeAutoCreateEvent; + FOnTranslate: TTranslateEvent; + FOnLanguageWarning: TLanguageWarningEvent; + FOnLocaleError: TDbfLocaleErrorEvent; + FOnIndexMissing: TDbfIndexMissingEvent; + FOnCompareRecord: TNotifyEvent; + FOnCopyDateTimeAsString: TConvertFieldEvent; + + function GetIndexName: string; + function GetVersion: string; + function GetPhysicalRecNo: Integer; + function GetLanguageStr: string; + function GetCodePage: Cardinal; + function GetExactRecordCount: Integer; + function GetPhysicalRecordCount: Integer; + function GetKeySize: Integer; + function GetMasterFields: string; + function FieldDefsStored: Boolean; + + procedure SetIndexName(AIndexName: string); + procedure SetDbfIndexDefs(const Value: TDbfIndexDefs); + procedure SetFilePath(const Value: string); + procedure SetTableName(const S: string); + procedure SetVersion(const S: string); + procedure SetLanguageID(NewID: Byte); + procedure SetDataSource(Value: TDataSource); + procedure SetMasterFields(const Value: string); + procedure SetTableLevel(const NewLevel: Integer); + procedure SetPhysicalRecNo(const NewRecNo: Integer); + + procedure MasterChanged(Sender: TObject); + procedure MasterDisabled(Sender: TObject); + procedure DetermineTranslationMode; + procedure UpdateRange; + procedure SetShowDeleted(Value: Boolean); + procedure GetFieldDefsFromDbfFieldDefs; + procedure InitDbfFile(FileOpenMode: TPagedFileMode); + function ParseIndexName(const AIndexName: string): string; + procedure ParseFilter(const AFilter: string); + function GetDbfFieldDefs: TDbfFieldDefs; + function ReadCurrentRecord(Buffer: TRecordBuffer; var Acceptable: Boolean): TGetResult; + function SearchKeyBuffer(Buffer: PChar; SearchType: TSearchKeyType): Boolean; + procedure SetRangeBuffer(LowRange: PChar; HighRange: PChar); + + protected + { abstract methods } + function AllocRecordBuffer: TRecordBuffer; override; {virtual abstract} + procedure ClearCalcFields(Buffer: TRecordBuffer); override; + procedure FreeRecordBuffer(var Buffer: TRecordBuffer); override; {virtual abstract} + procedure GetBookmarkData(Buffer: TRecordBuffer; Data: Pointer); override; {virtual abstract} + function GetBookmarkFlag(Buffer: TRecordBuffer): TBookmarkFlag; override; {virtual abstract} + function GetRecord(Buffer: TRecordBuffer; GetMode: TGetMode; DoCheck: Boolean): TGetResult; override; {virtual abstract} + function GetRecordSize: Word; override; {virtual abstract} + procedure InternalAddRecord(Buffer: Pointer; AAppend: Boolean); override; {virtual abstract} + procedure InternalClose; override; {virtual abstract} + procedure InternalDelete; override; {virtual abstract} + procedure InternalFirst; override; {virtual abstract} + procedure InternalGotoBookmark(ABookmark: Pointer); override; {virtual abstract} + procedure InternalHandleException; override; {virtual abstract} + procedure InternalInitFieldDefs; override; {virtual abstract} + procedure InternalInitRecord(Buffer: TRecordBuffer); override; {virtual abstract} + procedure InternalLast; override; {virtual abstract} + procedure InternalOpen; override; {virtual abstract} + procedure InternalEdit; override; {virtual} + procedure InternalCancel; override; {virtual} +{$ifndef FPC} +{$ifndef DELPHI_3} + procedure InternalInsert; override; {virtual} +{$endif} +{$endif} + procedure InternalPost; override; {virtual abstract} + procedure InternalSetToRecord(Buffer: TRecordBuffer); override; {virtual abstract} + procedure InitFieldDefs; override; + function IsCursorOpen: Boolean; override; {virtual abstract} + procedure SetBookmarkFlag(Buffer: TRecordBuffer; Value: TBookmarkFlag); override; {virtual abstract} + procedure SetBookmarkData(Buffer: TRecordBuffer; Data: Pointer); override; {virtual abstract} + + { virtual methods (mostly optionnal) } + function GetDataSource: TDataSource; {$ifndef VER1_0}override;{$endif} + function GetRecordCount: Integer; override; {virtual} + function GetRecNo: Integer; override; {virtual} + function GetCanModify: Boolean; override; {virtual} + procedure SetRecNo(Value: Integer); override; {virual} + procedure SetFiltered(Value: Boolean); override; {virtual;} + procedure SetFilterText(const Value: String); override; {virtual;} +{$ifdef SUPPORT_DEFCHANGED} + procedure DefChanged(Sender: TObject); override; +{$endif} + function FindRecord(Restart, GoForward: Boolean): Boolean; override; + + function GetIndexFieldNames: string; {virtual;} + procedure SetIndexFieldNames(const Value: string); {virtual;} + +{$ifdef SUPPORT_VARIANTS} + function LocateRecordLinear(const KeyFields: String; const KeyValues: Variant; Options: TLocateOptions): Boolean; + function LocateRecordIndex(const KeyFields: String; const KeyValues: Variant; Options: TLocateOptions): Boolean; + function LocateRecord(const KeyFields: String; const KeyValues: Variant; Options: TLocateOptions): Boolean; +{$endif} + + procedure DoFilterRecord(var Acceptable: Boolean); + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + + { abstract methods } + procedure SetFieldData(Field: TField; Buffer: Pointer); + {$ifdef SUPPORT_OVERLOAD} overload; {$endif} override; {virtual abstract} + function GetFieldData(Field: TField; Buffer: Pointer): Boolean; + {$ifdef SUPPORT_OVERLOAD} overload; {$endif} override; {virtual abstract} + { virtual methods (mostly optionnal) } + procedure Resync(Mode: TResyncMode); override; + function CreateBlobStream(Field: TField; Mode: TBlobStreamMode): TStream; override; {virtual} +{$ifdef SUPPORT_NEW_TRANSLATE} + function Translate(Src, Dest: PChar; ToOem: Boolean): Integer; override; {virtual} +{$else} + procedure Translate(Src, Dest: PChar; ToOem: Boolean); override; {virtual} +{$endif} + +{$ifdef SUPPORT_OVERLOAD} + function GetFieldData(Field: TField; Buffer: Pointer; NativeFormat: Boolean): Boolean; + {$ifdef SUPPORT_BACKWARD_FIELDDATA} overload; override; {$else} reintroduce; overload; {$endif} + procedure SetFieldData(Field: TField; Buffer: Pointer; NativeFormat: Boolean); + {$ifdef SUPPORT_BACKWARD_FIELDDATA} overload; override; {$else} reintroduce; overload; {$endif} +{$endif} + + function CompareBookmarks(Bookmark1, Bookmark2: TBookmark): Integer; override; + procedure CheckDbfFieldDefs(ADbfFieldDefs: TDbfFieldDefs); + +{$ifdef VER1_0} + procedure DataEvent(Event: TDataEvent; Info: Longint); override; +{$endif} + + // my own methods and properties + // most look like ttable functions but they are not tdataset related + // I (try to) use the same syntax to facilitate the conversion between bde and TDbf + + // index support (use same syntax as ttable but is not related) +{$ifdef SUPPORT_DEFAULT_PARAMS} + procedure AddIndex(const AIndexName, AFields: String; Options: TIndexOptions; const DescFields: String=''); +{$else} + procedure AddIndex(const AIndexName, AFields: String; Options: TIndexOptions); +{$endif} + procedure RegenerateIndexes; + + procedure CancelRange; + procedure CheckMasterRange; +{$ifdef SUPPORT_VARIANTS} + function SearchKey(Key: Variant; SearchType: TSearchKeyType; KeyIsANSI: boolean + {$ifdef SUPPORT_DEFAULT_PARAMS}= false{$endif}): Boolean; + procedure SetRange(LowRange: Variant; HighRange: Variant; KeyIsANSI: boolean + {$ifdef SUPPORT_DEFAULT_PARAMS}= false{$endif}); +{$endif} + function PrepareKey(Buffer: Pointer; BufferType: TExpressionType): PChar; + function SearchKeyPChar(Key: PChar; SearchType: TSearchKeyType; KeyIsANSI: boolean + {$ifdef SUPPORT_DEFAULT_PARAMS}= false{$endif}): Boolean; + procedure SetRangePChar(LowRange: PChar; HighRange: PChar; KeyIsANSI: boolean + {$ifdef SUPPORT_DEFAULT_PARAMS}= false{$endif}); + function GetCurrentBuffer: TRecordBuffer; + procedure ExtractKey(KeyBuffer: PChar); + procedure UpdateIndexDefs; override; + procedure GetFileNames(Strings: TStrings; Files: TDbfFileNames); {$ifdef SUPPORT_DEFAULT_PARAMS} overload; {$endif} +{$ifdef SUPPORT_DEFAULT_PARAMS} + function GetFileNames(Files: TDbfFileNames = [dfDbf] ): string; overload; +{$else} + function GetFileNamesString(Files: TDbfFileNames (* = [dfDbf] *) ): string; +{$endif} + procedure GetIndexNames(Strings: TStrings); + procedure GetAllIndexFiles(Strings: TStrings); + + procedure TryExclusive; + procedure EndExclusive; + function LockTable(const Wait: Boolean): Boolean; + procedure UnlockTable; + procedure OpenIndexFile(IndexFile: string); + procedure DeleteIndex(const AIndexName: string); + procedure CloseIndexFile(const AIndexName: string); + procedure RepageIndexFile(const AIndexFile: string); + procedure CompactIndexFile(const AIndexFile: string); + +{$ifdef SUPPORT_VARIANTS} + function Lookup(const KeyFields: string; const KeyValues: Variant; const ResultFields: string): Variant; override; + function Locate(const KeyFields: string; const KeyValues: Variant; Options: TLocateOptions): Boolean; override; +{$endif} + + function IsDeleted: Boolean; + procedure Undelete; + + procedure CreateTable; + procedure CreateTableEx(ADbfFieldDefs: TDbfFieldDefs); + procedure CopyFrom(DataSet: TDataSet; FileName: string; DateTimeAsString: Boolean; Level: Integer); + procedure RestructureTable(ADbfFieldDefs: TDbfFieldDefs; Pack: Boolean); + procedure PackTable; + procedure EmptyTable; + procedure Zap; + +{$ifndef SUPPORT_INITDEFSFROMFIELDS} + procedure InitFieldDefsFromFields; +{$endif} + + property AbsolutePath: string read FAbsolutePath; + property DbfFieldDefs: TDbfFieldDefs read GetDbfFieldDefs; + property PhysicalRecNo: Integer read GetPhysicalRecNo write SetPhysicalRecNo; + property LanguageID: Byte read FLanguageID write SetLanguageID; + property LanguageStr: String read GetLanguageStr; + property CodePage: Cardinal read GetCodePage; + property ExactRecordCount: Integer read GetExactRecordCount; + property PhysicalRecordCount: Integer read GetPhysicalRecordCount; + property KeySize: Integer read GetKeySize; + property DbfFile: TDbfFile read FDbfFile; + property UserStream: TStream read FUserStream write FUserStream; + property DisableResyncOnPost: Boolean read FDisableResyncOnPost write FDisableResyncOnPost; + published + property DateTimeHandling: TDateTimeHandling + read FDateTimeHandling write FDateTimeHandling default dtBDETimeStamp; + property Exclusive: Boolean read FExclusive write FExclusive default false; + property FilePath: string read FRelativePath write SetFilePath; + property FilePathFull: string read FAbsolutePath write SetFilePath stored false; + property Indexes: TDbfIndexDefs read FIndexDefs write SetDbfIndexDefs stored false; + property IndexDefs: TDbfIndexDefs read FIndexDefs write SetDbfIndexDefs; + property IndexFieldNames: string read GetIndexFieldNames write SetIndexFieldNames stored false; + property IndexName: string read GetIndexName write SetIndexName; + property MasterFields: string read GetMasterFields write SetMasterFields; + property MasterSource: TDataSource read GetDataSource write SetDataSource; + property OpenMode: TDbfOpenMode read FOpenMode write FOpenMode default omNormal; + property ReadOnly: Boolean read FReadOnly write FReadonly default false; + property ShowDeleted: Boolean read FShowDeleted write SetShowDeleted default false; + property Storage: TDbfStorage read FStorage write FStorage default stoFile; + property StoreDefs: Boolean read FStoreDefs write FStoreDefs default False; + property TableName: string read FTableName write SetTableName; + property TableLevel: Integer read FTableLevel write SetTableLevel; + property Version: string read GetVersion write SetVersion stored false; + property BeforeAutoCreate: TBeforeAutoCreateEvent read FBeforeAutoCreate write FBeforeAutoCreate; + property OnCompareRecord: TNotifyEvent read FOnCompareRecord write FOnCompareRecord; + property OnLanguageWarning: TLanguageWarningEvent read FOnLanguageWarning write FOnLanguageWarning; + property OnLocaleError: TDbfLocaleErrorEvent read FOnLocaleError write FOnLocaleError; + property OnIndexMissing: TDbfIndexMissingEvent read FOnIndexMissing write FOnIndexMissing; + property OnCopyDateTimeAsString: TConvertFieldEvent read FOnCopyDateTimeAsString write FOnCopyDateTimeAsString; + property OnTranslate: TTranslateEvent read FOnTranslate write FOnTranslate; + + // redeclared data set properties + property Active; + property FieldDefs stored FieldDefsStored; + property Filter; + property Filtered; + property FilterOptions; + property BeforeOpen; + property AfterOpen; + property BeforeClose; + property AfterClose; + property BeforeInsert; + property AfterInsert; + property BeforeEdit; + property AfterEdit; + property BeforePost; + property AfterPost; + property BeforeCancel; + property AfterCancel; + property BeforeDelete; + property AfterDelete; +{$ifdef SUPPORT_REFRESHEVENTS} + property BeforeRefresh; + property AfterRefresh; +{$endif} + property BeforeScroll; + property AfterScroll; + property OnCalcFields; + property OnDeleteError; + property OnEditError; + property OnFilterRecord; + property OnNewRecord; + property OnPostError; + end; + + TDbf_GetBasePathFunction = function: string; + +var + DbfBasePath: TDbf_GetBasePathFunction; + +implementation + +uses + SysUtils, +{$ifndef FPC} + DBConsts, +{$endif} +{$ifdef WINDOWS} + Windows, +{$else} +{$ifdef KYLIX} + Libc, +{$endif} + Types, + dbf_wtil, +{$endif} +{$ifdef SUPPORT_SEPARATE_VARIANTS_UNIT} + Variants, +{$endif} + dbf_idxcur, + dbf_memo, + dbf_str; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{$ifdef FPC} +const + // TODO: move these to DBConsts + SNotEditing = 'Dataset not in edit or insert mode'; + SCircularDataLink = 'Circular datalinks are not allowed'; +{$endif} + +function TableLevelToDbfVersion(TableLevel: integer): TXBaseVersion; +begin + case TableLevel of + 3: Result := xBaseIII; + 7: Result := xBaseVII; + TDBF_TABLELEVEL_FOXPRO: Result := xFoxPro; + else + {4:} Result := xBaseIV; + end; +end; + +//========================================================== +//============ TDbfBlobStream +//========================================================== +constructor TDbfBlobStream.Create(FieldVal: TField); +begin + FBlobField := FieldVal as TBlobField; + FReadSize := 0; + FMemoRecNo := 0; + FRefCount := 1; + FDirty := false; +end; + +destructor TDbfBlobStream.Destroy; +begin + // only continue destroy if all references released + if FRefCount = 1 then + begin + // this is the last reference + inherited + end else begin + // fire event when dirty, and the last "user" is freeing it's reference + // tdbf always has the last reference + if FDirty and (FRefCount = 2) then + begin + // a second referer to instance has changed the data, remember modified +// TDbf(FBlobField.DataSet).SetModified(true); + // is following better? seems to provide notification for user (from VCL) + if not (FBlobField.DataSet.State in [dsCalcFields, dsFilter, dsNewValue]) then + TDbf(FBlobField.DataSet).DataEvent(deFieldChange, PtrInt(FBlobField)); + end; + end; + Dec(FRefCount); +end; + +procedure TDbfBlobStream.FreeInstance; +begin + // only continue freeing if all references released + if FRefCount = 0 then + inherited; +end; + +procedure TDbfBlobStream.SetMode(NewMode: TBlobStreamMode); +begin + FMode := NewMode; + FDirty := FDirty or (NewMode = bmWrite) or (NewMode = bmReadWrite); +end; + +procedure TDbfBlobStream.Cancel; +begin + FDirty := false; + FMemoRecNo := -1; +end; + +procedure TDbfBlobStream.Commit; +var + Dbf: TDbf; +begin + if FDirty then + begin + Size := Position; // Strange but it leave tailing trash bytes if I do not write that. + Dbf := TDbf(FBlobField.DataSet); + Translate(true); + Dbf.FDbfFile.MemoFile.WriteMemo(FMemoRecNo, FReadSize, Self); + Dbf.FDbfFile.SetFieldData(FBlobField.FieldNo-1, ftInteger, @FMemoRecNo, + @pDbfRecord(TDbf(FBlobField.DataSet).ActiveBuffer)^.DeletedFlag, false); + FDirty := false; + end; +end; + +function TDbfBlobStream.AddReference: TDbfBlobStream; +begin + Inc(FRefCount); + Result := Self; +end; + +function TDbfBlobStream.GetTransliterate: Boolean; +begin + Result := FBlobField.Transliterate; +end; + +procedure TDbfBlobStream.Translate(ToOem: Boolean); +var + bytesToDo, numBytes: Integer; + bufPos: PChar; + saveChar: Char; +begin + if (Transliterate) and (Size > 0) then + begin + // get number of bytes to be translated + bytesToDo := Size; + // make space for final null-terminator + Size := Size + 1; + bufPos := Memory; + repeat + // process blocks of 512 bytes + numBytes := bytesToDo; + if numBytes > 512 then + numBytes := 512; + // null-terminate memory + saveChar := bufPos[numBytes]; + bufPos[numBytes] := #0; + // translate memory + TDbf(FBlobField.DataSet).Translate(bufPos, bufPos, ToOem); + // restore char + bufPos[numBytes] := saveChar; + // numBytes bytes translated + Dec(bytesToDo, numBytes); + Inc(bufPos, numBytes); + until bytesToDo = 0; + // cut ending null-terminator + Size := Size - 1; + end; +end; + +//==================================================================== +// TDbf = TDataset Descendant. +//==================================================================== +constructor TDbf.Create(AOwner: TComponent); {override;} +begin + inherited; + + if DbfGlobals = nil then + DbfGlobals := TDbfGlobals.Create; + + BookmarkSize := sizeof(TBookmarkData); + FIndexDefs := TDbfIndexDefs.Create(Self); + FMasterLink := TDbfMasterLink.Create(Self); + FMasterLink.OnMasterChange := MasterChanged; + FMasterLink.OnMasterDisable := MasterDisabled; + FDateTimeHandling := dtBDETimeStamp; + FStorage := stoFile; + FOpenMode := omNormal; + FParser := nil; + FPosting := false; + FReadOnly := false; + FExclusive := false; + FDisableResyncOnPost := false; + FTempExclusive := false; + FCopyDateTimeAsString := false; + FInCopyFrom := false; + FFindRecordFilter := false; + FEditingRecNo := -1; + FTableLevel := 4; + FIndexName := EmptyStr; + FilePath := EmptyStr; + FTempBuffer := nil; + FFilterBuffer := nil; + FIndexFile := nil; + FOnTranslate := nil; + FOnCopyDateTimeAsString := nil; +end; + +destructor TDbf.Destroy; {override;} +var + I: Integer; +begin + inherited Destroy; + + if FIndexDefs <> nil then + begin + for I := FIndexDefs.Count - 1 downto 0 do + TDbfIndexDef(FIndexDefs.Items[I]).Free; + FIndexDefs.Free; + end; + FMasterLink.Free; +end; + +function TDbf.AllocRecordBuffer: TRecordBuffer; {override virtual abstract from TDataset} +begin + GetMem(Result, SizeOf(TDbfRecordHeader)+FDbfFile.RecordSize+CalcFieldsSize+1); +end; + +procedure TDbf.FreeRecordBuffer(var Buffer: TRecordBuffer); {override virtual abstract from TDataset} +begin + FreeMemAndNil(Pointer(Buffer)); +end; + +procedure TDbf.GetBookmarkData(Buffer: TRecordBuffer; Data: Pointer); {override virtual abstract from TDataset} +begin + pBookmarkData(Data)^ := pDbfRecord(Buffer)^.BookmarkData; +end; + +function TDbf.GetBookmarkFlag(Buffer: TRecordBuffer): TBookmarkFlag; {override virtual abstract from TDataset} +begin + Result := pDbfRecord(Buffer)^.BookmarkFlag; +end; + +function TDbf.GetCurrentBuffer: TRecordBuffer; +begin + case State of + dsFilter: Result := FFilterBuffer; + dsCalcFields: Result := CalcBuffer; +// dsSetKey: Result := FKeyBuffer; // TO BE Implemented + else + if IsEmpty then + begin + Result := nil; + end else begin + Result := ActiveBuffer; + end; + end; + if Result <> nil then + Result := @PDbfRecord(Result)^.DeletedFlag; +end; + +// we don't want converted data formats, we want native :-) +// it makes coding easier in TDbfFile.GetFieldData +// ftCurrency: +// Delphi 3,4: BCD array +// ftBCD: +// ftDateTime is more difficult though + +function TDbf.GetFieldData(Field: TField; Buffer: Pointer): Boolean; {override virtual abstract from TDataset} +{$ifdef SUPPORT_OVERLOAD} +begin + { calling through 'old' delphi 3 interface, use compatible/'native' format } + Result := GetFieldData(Field, Buffer, true); +end; + +function TDbf.GetFieldData(Field: TField; Buffer: Pointer; NativeFormat: Boolean): Boolean; {overload; override;} +{$else} +const + { no overload => delphi 3 => use compatible/'native' format } + NativeFormat = true; +{$endif} +var + Src: TRecordBuffer; +begin + Src := GetCurrentBuffer; + if Src = nil then + begin + Result := false; + exit; + end; + + if Field.FieldNo>0 then + begin + Result := FDbfFile.GetFieldData(Field.FieldNo-1, Field.DataType, Src, Buffer, NativeFormat); + end else begin { weird calculated fields voodoo (from dbtables).... } + Inc(PChar(Src), Field.Offset + GetRecordSize); + Result := Boolean(Src[0]); + if Result and (Buffer <> nil) then + Move(Src[1], Buffer^, Field.DataSize); + end; +end; + +procedure TDbf.SetFieldData(Field: TField; Buffer: Pointer); {override virtual abstract from TDataset} +{$ifdef SUPPORT_OVERLOAD} +begin + { calling through 'old' delphi 3 interface, use compatible/'native' format } + SetFieldData(Field, Buffer, true); +end; + +procedure TDbf.SetFieldData(Field: TField; Buffer: Pointer; NativeFormat: Boolean); {overload; override;} +{$else} +const + { no overload => delphi 3 => use compatible/'native' format } + NativeFormat = true; +{$endif} +var + Dst: PChar; +begin + if (Field.FieldNo >= 0) then + begin + if State in [dsEdit, dsInsert, dsNewValue] then + Field.Validate(Buffer); + Dst := @PDbfRecord(ActiveBuffer)^.DeletedFlag; + FDbfFile.SetFieldData(Field.FieldNo - 1, Field.DataType, Buffer, Dst, NativeFormat); + end else begin { ***** fkCalculated, fkLookup ***** } + Dst := @PDbfRecord(CalcBuffer)^.DeletedFlag; + Inc(PChar(Dst), RecordSize + Field.Offset); + Boolean(Dst[0]) := Buffer <> nil; + if Buffer <> nil then + Move(Buffer^, Dst[1], Field.DataSize) + end; { end of ***** fkCalculated, fkLookup ***** } + if not (State in [dsCalcFields, dsFilter, dsNewValue]) then begin + DataEvent(deFieldChange, PtrInt(Field)); + end; +end; + +procedure TDbf.DoFilterRecord(var Acceptable: Boolean); +begin + // check filtertext + if Length(Filter) > 0 then + begin +{$ifndef VER1_0} + Acceptable := Boolean((FParser.ExtractFromBuffer(GetCurrentBuffer))^); +{$else} + // strange problem + // dbf.pas(716,19) Error: Incompatible types: got "CHAR" expected "BOOLEAN" + Acceptable := not ((FParser.ExtractFromBuffer(GetCurrentBuffer))^ = #0); +{$endif} + end; + + // check user filter + if Acceptable and Assigned(OnFilterRecord) then + OnFilterRecord(Self, Acceptable); +end; + +function TDbf.ReadCurrentRecord(Buffer: TRecordBuffer; var Acceptable: Boolean): TGetResult; +var + lPhysicalRecNo: Integer; + pRecord: pDbfRecord; +begin + lPhysicalRecNo := FCursor.PhysicalRecNo; + if (lPhysicalRecNo = 0) or not FDbfFile.IsRecordPresent(lPhysicalRecNo) then + begin + Result := grError; + Acceptable := false; + end else begin + Result := grOK; + pRecord := pDbfRecord(Buffer); + FDbfFile.ReadRecord(lPhysicalRecNo, @pRecord^.DeletedFlag); + Acceptable := (FShowDeleted or (pRecord^.DeletedFlag <> '*')) + end; +end; + +function TDbf.GetRecord(Buffer: TRecordBuffer; GetMode: TGetMode; DoCheck: Boolean): TGetResult; {override virtual abstract from TDataset} +var + pRecord: pDbfRecord; + acceptable: Boolean; + SaveState: TDataSetState; +// s: string; +begin + if FCursor = nil then + begin + Result := grEOF; + exit; + end; + + pRecord := pDbfRecord(Buffer); + acceptable := false; + repeat + Result := grOK; + case GetMode of + gmNext : + begin + Acceptable := FCursor.Next; + if Acceptable then begin + Result := grOK; + end else begin + Result := grEOF + end; + end; + gmPrior : + begin + Acceptable := FCursor.Prev; + if Acceptable then begin + Result := grOK; + end else begin + Result := grBOF + end; + end; + end; + + if (Result = grOK) then + Result := ReadCurrentRecord(Buffer, acceptable); + + if (Result = grOK) and acceptable then + begin + pRecord^.BookmarkData.PhysicalRecNo := FCursor.PhysicalRecNo; + pRecord^.BookmarkFlag := bfCurrent; + pRecord^.SequentialRecNo := FCursor.SequentialRecNo; + GetCalcFields(Buffer); + + if Filtered or FFindRecordFilter then + begin + FFilterBuffer := Buffer; + SaveState := SetTempState(dsFilter); + DoFilterRecord(acceptable); + RestoreState(SaveState); + end; + end; + + if (GetMode = gmCurrent) and not acceptable then + Result := grError; + until (Result <> grOK) or acceptable; + + if Result <> grOK then + pRecord^.BookmarkData.PhysicalRecNo := -1; +end; + +function TDbf.GetRecordSize: Word; {override virtual abstract from TDataset} +begin + Result := FDbfFile.RecordSize; +end; + +procedure TDbf.InternalAddRecord(Buffer: Pointer; AAppend: Boolean); {override virtual abstract from TDataset} + // this function is called from TDataSet.InsertRecord and TDataSet.AppendRecord + // goal: add record with Edit...Set Fields...Post all in one step +var + pRecord: pDbfRecord; + newRecord: integer; +begin + // if InternalAddRecord is called, we know we are active + pRecord := Buffer; + + // we can not insert records in DBF files, only append + // ignore Append parameter + newRecord := FDbfFile.Insert(@pRecord^.DeletedFlag); + if newRecord > 0 then + FCursor.PhysicalRecNo := newRecord; + + // set flag that TDataSet is about to post...so we can disable resync + FPosting := true; +end; + +procedure TDbf.InternalClose; {override virtual abstract from TDataset} +var + lIndex: TDbfIndexDef; + I: Integer; +begin + // clear automatically added MDX index entries + I := 0; + while I < FIndexDefs.Count do + begin + // is this an MDX index? + lIndex := FIndexDefs.Items[I]; + if (Length(ExtractFileExt(lIndex.IndexFile)) = 0) and + TDbfIndexDef(FIndexDefs.Items[I]).Temporary then + begin +{$ifdef SUPPORT_DEF_DELETE} + // delete this entry + FIndexDefs.Delete(I); +{$else} + // does this work? I hope so :-) + FIndexDefs.Items[I].Free; +{$endif} + end else begin + // NDX entry -> goto next + Inc(I); + end; + end; + + // free blobs + if FBlobStreams <> nil then + begin + for I := 0 to Pred(FieldDefs.Count) do + FBlobStreams^[I].Free; + FreeMemAndNil(Pointer(FBlobStreams)); + end; + FreeRecordBuffer(FTempBuffer); + // disconnect field objects + BindFields(false); + // Destroy field object (if not persistent) + if DefaultFields then + DestroyFields; + + if FParser <> nil then + FreeAndNil(FParser); + FreeAndNil(FCursor); + if FDbfFile <> nil then + FreeAndNil(FDbfFile); +end; + +procedure TDbf.InternalCancel; +var + I: Integer; +begin + // cancel blobs + for I := 0 to Pred(FieldDefs.Count) do + if Assigned(FBlobStreams^[I]) then + FBlobStreams^[I].Cancel; + // if we have locked a record, unlock it + if FEditingRecNo >= 0 then + begin + FDbfFile.UnlockPage(FEditingRecNo); + FEditingRecNo := -1; + end; +end; + +procedure TDbf.InternalDelete; {override virtual abstract from TDataset} +var + lRecord: pDbfRecord; +begin + // start editing + InternalEdit; + SetState(dsEdit); + // get record pointer + lRecord := pDbfRecord(ActiveBuffer); + // flag we deleted this record + lRecord^.DeletedFlag := '*'; + // notify indexes this record is deleted + FDbfFile.RecordDeleted(FEditingRecNo, @lRecord^.DeletedFlag); + // done! + InternalPost; +end; + +procedure TDbf.InternalFirst; {override virtual abstract from TDataset} +begin + FCursor.First; +end; + +procedure TDbf.InternalGotoBookmark(ABookmark: Pointer); {override virtual abstract from TDataset} +begin + with PBookmarkData(ABookmark)^ do + begin + if (PhysicalRecNo = 0) then begin + First; + end else + if (PhysicalRecNo = MaxInt) then begin + Last; + end else begin + if FCursor.PhysicalRecNo <> PhysicalRecNo then + FCursor.PhysicalRecNo := PhysicalRecNo; + end; + end; +end; + +procedure TDbf.InternalHandleException; {override virtual abstract from TDataset} +begin + SysUtils.ShowException(ExceptObject, ExceptAddr); +end; + +procedure TDbf.GetFieldDefsFromDbfFieldDefs; +var + I, N: Integer; + TempFieldDef: TDbfFieldDef; + TempMdxFile: TIndexFile; + BaseName, lIndexName: string; +begin + FieldDefs.Clear; + + // get all fields + for I := 0 to FDbfFile.FieldDefs.Count - 1 do + begin + TempFieldDef := FDbfFile.FieldDefs.Items[I]; + // handle duplicate field names + N := 1; + BaseName := TempFieldDef.FieldName; + while FieldDefs.IndexOf(TempFieldDef.FieldName)>=0 do + begin + Inc(N); + TempFieldDef.FieldName:=BaseName+IntToStr(N); + end; + // add field + if TempFieldDef.FieldType in [ftString, ftBCD, ftBytes] then + FieldDefs.Add(TempFieldDef.FieldName, TempFieldDef.FieldType, TempFieldDef.Size, false) + else + FieldDefs.Add(TempFieldDef.FieldName, TempFieldDef.FieldType, 0, false); + + if TempFieldDef.FieldType = ftFloat then + begin + FieldDefs[I].Size := 0; // Size is not defined for float-fields + FieldDefs[I].Precision := TempFieldDef.Size; + end; + +{$ifdef SUPPORT_FIELDDEF_ATTRIBUTES} + // AutoInc fields are readonly + if TempFieldDef.FieldType = ftAutoInc then + FieldDefs[I].Attributes := [Db.faReadOnly]; + + // if table has dbase lock field, then hide it + if TempFieldDef.IsLockField then + FieldDefs[I].Attributes := [Db.faHiddenCol]; +{$endif} + end; + + // get all (new) MDX index defs + TempMdxFile := FDbfFile.MdxFile; + for I := 0 to FDbfFile.IndexNames.Count - 1 do + begin + // is this an MDX index? + lIndexName := FDbfFile.IndexNames.Strings[I]; + if FDbfFile.IndexNames.Objects[I] = TempMdxFile then + if FIndexDefs.GetIndexByName(lIndexName) = nil then + TempMdxFile.GetIndexInfo(lIndexName, FIndexDefs.Add); + end; +end; + +procedure TDbf.InitFieldDefs; +begin + InternalInitFieldDefs; +end; + +procedure TDbf.InitDbfFile(FileOpenMode: TPagedFileMode); +const + FileModeToMemMode: array[TPagedFileMode] of TPagedFileMode = + (pfNone, pfMemoryCreate, pfMemoryOpen, pfMemoryCreate, pfMemoryOpen, + pfMemoryCreate, pfMemoryOpen, pfMemoryOpen); +begin + FDbfFile := TDbfFile.Create; + if FStorage = stoMemory then + begin + FDbfFile.Stream := FUserStream; + FDbfFile.Mode := FileModeToMemMode[FileOpenMode]; + end else begin + FDbfFile.FileName := FAbsolutePath + FTableName; + FDbfFile.Mode := FileOpenMode; + end; + FDbfFile.AutoCreate := false; + FDbfFile.DateTimeHandling := FDateTimeHandling; + FDbfFile.OnLocaleError := FOnLocaleError; + FDbfFile.OnIndexMissing := FOnIndexMissing; +end; + +procedure TDbf.InternalInitFieldDefs; {override virtual abstract from TDataset} +var + MustReleaseDbfFile: Boolean; +begin + MustReleaseDbfFile := false; + with FieldDefs do + begin + if FDbfFile = nil then + begin + // do not AutoCreate file + InitDbfFile(pfReadOnly); + FDbfFile.Open; + MustReleaseDbfFile := true; + end; + GetFieldDefsFromDbfFieldDefs; + if MustReleaseDbfFile then + FreeAndNil(FDbfFile); + end; +end; + +procedure TDbf.InternalInitRecord(Buffer: TRecordBuffer); {override virtual abstract from TDataset} +var + pRecord: pDbfRecord; +begin + pRecord := pDbfRecord(Buffer); + pRecord^.BookmarkData.PhysicalRecNo := 0; + pRecord^.BookmarkFlag := bfCurrent; + pRecord^.SequentialRecNo := 0; +// Init Record with zero and set autoinc field with next value + FDbfFile.InitRecord(@pRecord^.DeletedFlag); +end; + +procedure TDbf.InternalLast; {override virtual abstract from TDataset} +begin + FCursor.Last; +end; + +procedure TDbf.DetermineTranslationMode; +var + lCodePage: Cardinal; +begin + lCodePage := FDbfFile.UseCodePage; + if lCodePage = GetACP then + FTranslationMode := tmNoneNeeded + else + if lCodePage = GetOEMCP then + FTranslationMode := tmSimple + // check if this code page, although non default, is installed + else + if DbfGlobals.CodePageInstalled(lCodePage) then + FTranslationMode := tmAdvanced + else + FTranslationMode := tmNoneAvailable; +end; + +procedure TDbf.InternalOpen; {override virtual abstract from TDataset} +const + DbfOpenMode: array[Boolean, Boolean] of TPagedFileMode = + ((pfReadWriteOpen, pfExclusiveOpen), (pfReadOnly, pfReadOnly)); +var + lIndex: TDbfIndexDef; + lIndexName: string; + LanguageAction: TDbfLanguageAction; + doCreate: Boolean; + I: Integer; +begin + // close current file + FreeAndNil(FDbfFile); + + // does file not exist? -> create + if ((FStorage = stoFile) and + not FileExists(FAbsolutePath + FTableName) and + (FOpenMode in [omAutoCreate, omTemporary])) or + ((FStorage = stoMemory) and (FUserStream = nil)) then + begin + doCreate := true; + if Assigned(FBeforeAutoCreate) then + FBeforeAutoCreate(Self, doCreate); + if doCreate then + CreateTable + else + exit; + end; + + // now we know for sure the file exists + InitDbfFile(DbfOpenMode[FReadOnly, FExclusive]); + FDbfFile.Open; + + // fail open? +{$ifndef FPC} + if FDbfFile.ForceClose then + Abort; +{$endif} + + // determine dbf version + case FDbfFile.DbfVersion of + xBaseIII: FTableLevel := 3; + xBaseIV: FTableLevel := 4; + xBaseVII: FTableLevel := 7; + xFoxPro: FTableLevel := TDBF_TABLELEVEL_FOXPRO; + end; + FLanguageID := FDbfFile.LanguageID; + + // build VCL fielddef list from native DBF FieldDefs +(* + if (FDbfFile.HeaderSize = 0) or (FDbfFile.FieldDefs.Count = 0) then + begin + if FieldDefs.Count > 0 then + begin + CreateTableFromFieldDefs; + end else begin + CreateTableFromFields; + end; + end else begin +*) +// GetFieldDefsFromDbfFieldDefs; +// end; + +{$ifdef SUPPORT_FIELDDEFS_UPDATED} + FieldDefs.Updated := False; + FieldDefs.Update; +{$else} + InternalInitFieldDefs; +{$endif} + + // create the fields dynamically + if DefaultFields then + CreateFields; // Create fields from fielddefs. + + BindFields(true); + + // create array of blobstreams to store memo's in. each field is a possible blob + FBlobStreams := AllocMem(FieldDefs.Count * SizeOf(TDbfBlobStream)); + + // check codepage settings + DetermineTranslationMode; + if FTranslationMode = tmNoneAvailable then + begin + // no codepage available? ask user + LanguageAction := laReadOnly; + if Assigned(FOnLanguageWarning) then + FOnLanguageWarning(Self, LanguageAction); + case LanguageAction of + laReadOnly: FTranslationMode := tmNoneAvailable; + laForceOEM: + begin + FDbfFile.UseCodePage := GetOEMCP; + FTranslationMode := tmSimple; + end; + laForceANSI: + begin + FDbfFile.UseCodePage := GetACP; + FTranslationMode := tmNoneNeeded; + end; + laDefault: + begin + FDbfFile.UseCodePage := DbfGlobals.DefaultOpenCodePage; + DetermineTranslationMode; + end; + end; + end; + + // allocate a record buffer for temporary data + FTempBuffer := AllocRecordBuffer; + + // open indexes + for I := 0 to FIndexDefs.Count - 1 do + begin + lIndex := FIndexDefs.Items[I]; + lIndexName := ParseIndexName(lIndex.IndexFile); + // if index does not exist -> create, if it does exist -> open only + FDbfFile.OpenIndex(lIndexName, lIndex.SortField, false, lIndex.Options); + end; + + // parse filter expression + try + ParseFilter(Filter); + except + // oops, a problem with parsing, clear filter for now + on E: EDbfError do Filter := EmptyStr; + end; + + SetIndexName(FIndexName); + +// SetIndexName will have made the cursor for us if no index selected :-) +// if FCursor = nil then FCursor := TDbfCursor.Create(FDbfFile); + + if FMasterLink.Active and Assigned(FIndexFile) then + CheckMasterRange; + InternalFirst; + +// FDbfFile.SetIndex(FIndexName); +// FDbfFile.FIsCursorOpen := true; +end; + +function TDbf.GetCodePage: Cardinal; +begin + if FDbfFile <> nil then + Result := FDbfFile.UseCodePage + else + Result := 0; +end; + +function TDbf.GetLanguageStr: String; +begin + result:= ''; + if FDbfFile <> nil then + Result := FDbfFile.LanguageStr; +end; + +function TDbf.LockTable(const Wait: Boolean): Boolean; +begin + CheckActive; + Result := FDbfFile.LockAllPages(Wait); +end; + +procedure TDbf.UnlockTable; +begin + CheckActive; + FDbfFile.UnlockAllPages; +end; + +procedure TDbf.InternalEdit; +var + I: Integer; +begin + // store recno we are editing + FEditingRecNo := FCursor.PhysicalRecNo; + // reread blobs, execute cancel -> clears remembered memo pageno, + // causing it to reread the memo contents + for I := 0 to Pred(FieldDefs.Count) do + if Assigned(FBlobStreams^[I]) then + FBlobStreams^[I].Cancel; + // try to lock this record + FDbfFile.LockRecord(FEditingRecNo, @pDbfRecord(ActiveBuffer)^.DeletedFlag); + // succeeded! +end; + +{$ifndef FPC} +{$ifndef DELPHI_3} + +procedure TDbf.InternalInsert; {override virtual from TDataset} +begin + CursorPosChanged; +end; + +{$endif} +{$endif} + +procedure TDbf.InternalPost; {override virtual abstract from TDataset} +var + pRecord: pDbfRecord; + I, newRecord: Integer; +begin + // if internalpost is called, we know we are active + pRecord := pDbfRecord(ActiveBuffer); + // commit blobs + for I := 0 to Pred(FieldDefs.Count) do + if Assigned(FBlobStreams^[I]) then + FBlobStreams^[I].Commit; + if State = dsEdit then + begin + // write changes + FDbfFile.UnlockRecord(FEditingRecNo, @pRecord^.DeletedFlag); + // not editing anymore + FEditingRecNo := -1; + end else begin + // insert + newRecord := FDbfFile.Insert(@pRecord^.DeletedFlag); + if newRecord > 0 then + FCursor.PhysicalRecNo := newRecord; + end; + // set flag that TDataSet is about to post...so we can disable resync + FPosting := true; +end; + +procedure TDbf.Resync(Mode: TResyncMode); +begin + // try to increase speed + if not FDisableResyncOnPost or not FPosting then + inherited; + // clear post flag + FPosting := false; +end; + + +{$ifndef SUPPORT_INITDEFSFROMFIELDS} + +procedure TDbf.InitFieldDefsFromFields; +var + I: Integer; + F: TField; +begin + { create fielddefs from persistent fields if needed } + for I := 0 to FieldCount - 1 do + begin + F := Fields[I]; + with F do + if FieldKind = fkData then begin + FieldDefs.Add(FieldName,DataType,Size,Required); + end; + end; +end; + +{$endif} + +procedure TDbf.CreateTable; +begin + CreateTableEx(nil); +end; + +procedure TDbf.CheckDbfFieldDefs(ADbfFieldDefs: TDbfFieldDefs); +var + I: Integer; + TempDef: TDbfFieldDef; + + function FieldTypeStr(const FieldType: char): string; + begin + if FieldType = #0 then + Result := 'NULL' + else if FieldType > #127 then + Result := 'ASCII '+IntToStr(Byte(FieldType)) + else + Result := ' "'+fieldType+'" '; + Result := ' ' + Result + '(#'+IntToHex(Byte(FieldType),SizeOf(FieldType))+') ' + end; + +begin + if ADbfFieldDefs = nil then exit; + + for I := 0 to ADbfFieldDefs.Count - 1 do + begin + // check dbffielddefs for errors + TempDef := ADbfFieldDefs.Items[I]; + if FTableLevel < 7 then + if not (TempDef.NativeFieldType in ['C', 'F', 'N', 'D', 'L', 'M']) then + raise EDbfError.CreateFmt(STRING_INVALID_FIELD_TYPE, + [FieldTypeStr(TempDef.NativeFieldType), TempDef.FieldName]); + end; +end; + +procedure TDbf.CreateTableEx(ADbfFieldDefs: TDbfFieldDefs); +var + I: Integer; + lIndex: TDbfIndexDef; + lIndexName: string; + tempFieldDefs: Boolean; +begin + CheckInactive; + tempFieldDefs := ADbfFieldDefs = nil; + try + try + if tempFieldDefs then + begin + ADbfFieldDefs := TDbfFieldDefs.Create(Self); + ADbfFieldDefs.DbfVersion := TableLevelToDbfVersion(FTableLevel); + + // get fields -> fielddefs if no fielddefs +{$ifndef FPC_VERSION} + if FieldDefs.Count = 0 then + InitFieldDefsFromFields; +{$endif} + + // fielddefs -> dbffielddefs + for I := 0 to FieldDefs.Count - 1 do + begin + with ADbfFieldDefs.AddFieldDef do + begin + FieldName := FieldDefs.Items[I].Name; + FieldType := FieldDefs.Items[I].DataType; + if FieldDefs.Items[I].Size > 0 then + begin + Size := FieldDefs.Items[I].Size; + Precision := FieldDefs.Items[I].Precision; + end else begin + SetDefaultSize; + end; + end; + end; + end; + + InitDbfFile(pfExclusiveCreate); + FDbfFile.CopyDateTimeAsString := FInCopyFrom and FCopyDateTimeAsString; + FDbfFile.DbfVersion := TableLevelToDbfVersion(FTableLevel); + FDbfFile.FileLangID := FLanguageID; + FDbfFile.Open; + FDbfFile.FinishCreate(ADbfFieldDefs, 512); + + // if creating memory table, copy stream pointer + if FStorage = stoMemory then + FUserStream := FDbfFile.Stream; + + // create all indexes + for I := 0 to FIndexDefs.Count-1 do + begin + lIndex := FIndexDefs.Items[I]; + lIndexName := ParseIndexName(lIndex.IndexFile); + FDbfFile.OpenIndex(lIndexName, lIndex.SortField, true, lIndex.Options); + end; + except + // dbf file created? + if (FDbfFile <> nil) and (FStorage = stoFile) then + begin + FreeAndNil(FDbfFile); + SysUtils.DeleteFile(FAbsolutePath+FTableName); + end; + raise; + end; + finally + // free temporary fielddefs + if tempFieldDefs and Assigned(ADbfFieldDefs) then + ADbfFieldDefs.Free; + FreeAndNil(FDbfFile); + end; +end; + +procedure TDbf.EmptyTable; +begin + Zap; +end; + +procedure TDbf.Zap; +begin + // are we active? + CheckActive; + FDbfFile.Zap; +end; + +procedure TDbf.RestructureTable(ADbfFieldDefs: TDbfFieldDefs; Pack: Boolean); +begin + CheckInactive; + + // check field defs for errors + CheckDbfFieldDefs(ADbfFieldDefs); + + // open dbf file + InitDbfFile(pfExclusiveOpen); + FDbfFile.Open; + + // do restructure + try + FDbfFile.RestructureTable(ADbfFieldDefs, Pack); + finally + // close file + FreeAndNil(FDbfFile); + end; +end; + +procedure TDbf.PackTable; +var + oldIndexName: string; +begin + CheckBrowseMode; + // deselect any index while packing + oldIndexName := IndexName; + IndexName := EmptyStr; + // pack + FDbfFile.RestructureTable(nil, true); + // reselect index + IndexName := oldIndexName; +end; + +procedure TDbf.CopyFrom(DataSet: TDataSet; FileName: string; DateTimeAsString: Boolean; Level: Integer); +var + lPhysFieldDefs, lFieldDefs: TDbfFieldDefs; + lSrcField, lDestField: TField; + I: integer; +begin + FInCopyFrom := true; + lFieldDefs := TDbfFieldDefs.Create(nil); + lPhysFieldDefs := TDbfFieldDefs.Create(nil); + try + if Active then + Close; + FilePath := ExtractFilePath(FileName); + TableName := ExtractFileName(FileName); + FCopyDateTimeAsString := DateTimeAsString; + TableLevel := Level; + if not DataSet.Active then + DataSet.Open; + DataSet.FieldDefs.Update; + // first get a list of physical field defintions + // we need it for numeric precision in case source is tdbf + if DataSet is TDbf then + begin + lPhysFieldDefs.Assign(TDbf(DataSet).DbfFieldDefs); + IndexDefs.Assign(TDbf(DataSet).IndexDefs); + end else begin +{$ifdef SUPPORT_FIELDDEF_TPERSISTENT} + lPhysFieldDefs.Assign(DataSet.FieldDefs); +{$endif} + IndexDefs.Clear; + end; + // convert list of tfields into a list of tdbffielddefs + // so that our tfields will correspond to the source tfields + for I := 0 to Pred(DataSet.FieldCount) do + begin + lSrcField := DataSet.Fields[I]; + with lFieldDefs.AddFieldDef do + begin + if Length(lSrcField.Name) > 0 then + FieldName := lSrcField.Name + else + FieldName := lSrcField.FieldName; + FieldType := lSrcField.DataType; + Required := lSrcField.Required; + if (1 <= lSrcField.FieldNo) + and (lSrcField.FieldNo <= lPhysFieldDefs.Count) then + begin + Size := lPhysFieldDefs.Items[lSrcField.FieldNo-1].Size; + Precision := lPhysFieldDefs.Items[lSrcField.FieldNo-1].Precision; + end; + end; + end; + + CreateTableEx(lFieldDefs); + Open; + DataSet.First; +{$ifdef USE_CACHE} + FDbfFile.BufferAhead := true; + if DataSet is TDbf then + TDbf(DataSet).DbfFile.BufferAhead := true; +{$endif} + while not DataSet.EOF do + begin + Append; + for I := 0 to Pred(FieldCount) do + begin + lSrcField := DataSet.Fields[I]; + lDestField := Fields[I]; + if not lSrcField.IsNull then + begin + if lSrcField.DataType = ftDateTime then + begin + if FCopyDateTimeAsString then + begin + lDestField.AsString := lSrcField.AsString; + if Assigned(FOnCopyDateTimeAsString) then + FOnCopyDateTimeAsString(Self, lDestField, lSrcField) + end else + lDestField.AsDateTime := lSrcField.AsDateTime; + end else + lDestField.Assign(lSrcField); + end; + end; + Post; + DataSet.Next; + end; + Close; + finally +{$ifdef USE_CACHE} + if (DataSet is TDbf) and (TDbf(DataSet).DbfFile <> nil) then + TDbf(DataSet).DbfFile.BufferAhead := false; +{$endif} + FInCopyFrom := false; + lFieldDefs.Free; + lPhysFieldDefs.Free; + end; +end; + +function TDbf.FindRecord(Restart, GoForward: Boolean): Boolean; +var + oldRecNo: Integer; +begin + CheckBrowseMode; + DoBeforeScroll; + Result := false; + UpdateCursorPos; + oldRecNo := RecNo; + try + FFindRecordFilter := true; + if GoForward then + begin + if Restart then FCursor.First; + Result := GetRecord(FTempBuffer, gmNext, false) = grOK; + end else begin + if Restart then FCursor.Last; + Result := GetRecord(FTempBuffer, gmPrior, false) = grOK; + end; + finally + FFindRecordFilter := false; + if not Result then + begin + RecNo := oldRecNo; + end else begin + CursorPosChanged; + Resync([]); + DoAfterScroll; + end; + end; +end; + +{$ifdef SUPPORT_VARIANTS} + +function TDbf.Lookup(const KeyFields: string; const KeyValues: Variant; + const ResultFields: string): Variant; +var +// OldState: TDataSetState; + saveRecNo: integer; + saveState: TDataSetState; +begin + Result := Null; + if (FCursor = nil) or VarIsNull(KeyValues) then exit; + + saveRecNo := FCursor.SequentialRecNo; + try + if LocateRecord(KeyFields, KeyValues, []) then + begin + // FFilterBuffer contains record buffer + saveState := SetTempState(dsCalcFields); + try + CalculateFields(FFilterBuffer); + if KeyValues = FieldValues[KeyFields] then + Result := FieldValues[ResultFields]; + finally + RestoreState(saveState); + end; + end; + finally + FCursor.SequentialRecNo := saveRecNo; + end; +end; + +function TDbf.Locate(const KeyFields: string; const KeyValues: Variant; Options: TLocateOptions): Boolean; +var + saveRecNo: integer; +begin + if FCursor = nil then + begin + CheckActive; + Result := false; + exit; + end; + + DoBeforeScroll; + saveRecNo := FCursor.SequentialRecNo; + FLocateRecNo := -1; + Result := LocateRecord(KeyFields, KeyValues, Options); + CursorPosChanged; + if Result then + begin + if FLocateRecNo <> -1 then + FCursor.PhysicalRecNo := FLocateRecNo; + Resync([]); + DoAfterScroll; + end else + FCursor.SequentialRecNo := saveRecNo; +end; + +function TDbf.LocateRecordLinear(const KeyFields: String; const KeyValues: Variant; + Options: TLocateOptions): Boolean; +var + lstKeys : TList; + iIndex : Integer; + Field : TField; + bMatchedData : Boolean; + bVarIsArray : Boolean; + varCompare : Variant; + + function CompareValues: Boolean; + var + sCompare: String; + begin + if (Field.DataType = ftString) then + begin + sCompare := VarToStr(varCompare); + if loCaseInsensitive in Options then + begin + Result := AnsiCompareText(Field.AsString,sCompare) = 0; + if not Result and (iIndex = lstKeys.Count - 1) and (loPartialKey in Options) and + (Length(sCompare) < Length(Field.AsString)) then + begin + if Length(sCompare) = 0 then + Result := true + else + Result := AnsiCompareText (Copy (Field.AsString,1,Length (sCompare)),sCompare) = 0; + end; + end else begin + Result := Field.AsString = sCompare; + if not Result and (iIndex = lstKeys.Count - 1) and (loPartialKey in Options) and + (Length (sCompare) < Length (Field.AsString)) then + begin + if Length (sCompare) = 0 then + Result := true + else + Result := Copy(Field.AsString, 1, Length(sCompare)) = sCompare; + end; + end; + end + else + Result := Field.Value = varCompare; + end; + +var + SaveState: TDataSetState; + lPhysRecNo: integer; +begin + Result := false; + bVarIsArray := false; + lstKeys := TList.Create; + FFilterBuffer := TempBuffer; + SaveState := SetTempState(dsFilter); + try + GetFieldList(lstKeys, KeyFields); + if VarArrayDimCount(KeyValues) = 0 then + bMatchedData := lstKeys.Count = 1 + else if VarArrayDimCount (KeyValues) = 1 then + begin + bMatchedData := VarArrayHighBound (KeyValues,1) + 1 = lstKeys.Count; + bVarIsArray := true; + end else + bMatchedData := false; + if bMatchedData then + begin + FCursor.First; + while not Result and FCursor.Next do + begin + lPhysRecNo := FCursor.PhysicalRecNo; + if (lPhysRecNo = 0) or not FDbfFile.IsRecordPresent(lPhysRecNo) then + break; + + FDbfFile.ReadRecord(lPhysRecNo, @PDbfRecord(FFilterBuffer)^.DeletedFlag); + Result := FShowDeleted or (PDbfRecord(FFilterBuffer)^.DeletedFlag <> '*'); + if Result and Filtered then + DoFilterRecord(Result); + + iIndex := 0; + while Result and (iIndex < lstKeys.Count) Do + begin + Field := TField (lstKeys [iIndex]); + if bVarIsArray then + varCompare := KeyValues [iIndex] + else + varCompare := KeyValues; + Result := CompareValues; + Inc(iIndex); + end; + end; + end; + finally + lstKeys.Free; + RestoreState(SaveState); + end; +end; + +function TDbf.LocateRecordIndex(const KeyFields: String; const KeyValues: Variant; + Options: TLocateOptions): Boolean; +var + searchFlag: TSearchKeyType; + matchRes: Integer; + lTempBuffer: array [0..100] of Char; + acceptable, checkmatch: boolean; +begin + if loPartialKey in Options then + searchFlag := stGreaterEqual + else + searchFlag := stEqual; + if TIndexCursor(FCursor).VariantToBuffer(KeyValues, @lTempBuffer[0]) = etString then + Translate(@lTempBuffer[0], @lTempBuffer[0], true); + Result := FIndexFile.SearchKey(@lTempBuffer[0], searchFlag); + if not Result then + exit; + + checkmatch := false; + repeat + if ReadCurrentRecord(TempBuffer, acceptable) = grError then + begin + Result := false; + exit; + end; + if acceptable then break; + checkmatch := true; + FCursor.Next; + until false; + + if checkmatch then + begin + matchRes := TIndexCursor(FCursor).IndexFile.MatchKey(@lTempBuffer[0]); + if loPartialKey in Options then + Result := matchRes <= 0 + else + Result := matchRes = 0; + end; + + FFilterBuffer := TempBuffer; +end; + +function TDbf.LocateRecord(const KeyFields: String; const KeyValues: Variant; + Options: TLocateOptions): Boolean; +var + lCursor, lSaveCursor: TVirtualCursor; + lSaveIndexName, lIndexName: string; + lIndexDef: TDbfIndexDef; + lIndexFile, lSaveIndexFile: TIndexFile; +begin + lsaveindexname:= ''; + lCursor := nil; + lSaveCursor := nil; + lIndexFile := nil; + lSaveIndexFile := FIndexFile; + if (FCursor is TIndexCursor) + and (TIndexCursor(FCursor).IndexFile.Expression = KeyFields) then + begin + lCursor := FCursor; + end else begin + lIndexDef := FIndexDefs.GetIndexByField(KeyFields); + if lIndexDef <> nil then + begin + lIndexName := ParseIndexName(lIndexDef.IndexFile); + lIndexFile := FDbfFile.GetIndexByName(lIndexName); + if lIndexFile <> nil then + begin + lSaveCursor := FCursor; + lCursor := TIndexCursor.Create(lIndexFile); + lSaveIndexName := lIndexFile.IndexName; + lIndexFile.IndexName := lIndexName; + FIndexFile := lIndexFile; + end; + end; + end; + if lCursor <> nil then + begin + FCursor := lCursor; + Result := LocateRecordIndex(KeyFields, KeyValues, Options); + if lSaveCursor <> nil then + begin + FCursor.Free; + FCursor := lSaveCursor; + end; + if lIndexFile <> nil then + begin + FLocateRecNo := FIndexFile.PhysicalRecNo; + lIndexFile.IndexName := lSaveIndexName; + FIndexFile := lSaveIndexFile; + end; + end else + Result := LocateRecordLinear(KeyFields, KeyValues, Options); +end; + +{$endif} + +procedure TDbf.TryExclusive; +begin + // are we active? + if Active then + begin + // already in exclusive mode? + FDbfFile.TryExclusive; + // update file mode + FExclusive := not FDbfFile.IsSharedAccess; + FReadOnly := FDbfFile.Mode = pfReadOnly; + end else begin + // just set exclusive to true + FExclusive := true; + FReadOnly := false; + end; +end; + +procedure TDbf.EndExclusive; +begin + if Active then + begin + // call file handler + FDbfFile.EndExclusive; + // update file mode + FExclusive := not FDbfFile.IsSharedAccess; + FReadOnly := FDbfFile.Mode = pfReadOnly; + end else begin + // just set exclusive to false + FExclusive := false; + end; +end; + +function TDbf.CreateBlobStream(Field: TField; Mode: TBlobStreamMode): TStream; {override virtual} +var + MemoPageNo: Integer; + MemoFieldNo: Integer; + lBlob: TDbfBlobStream; +begin + // check if in editing mode if user wants to write + if (Mode = bmWrite) or (Mode = bmReadWrite) then + if not (State in [dsEdit, dsInsert]) then +{$ifdef DELPHI_3} + DatabaseError(SNotEditing); +{$else} + DatabaseError(SNotEditing, Self); +{$endif} + // already created a `placeholder' blob for this field? + MemoFieldNo := Field.FieldNo - 1; + if FBlobStreams^[MemoFieldNo] = nil then + FBlobStreams^[MemoFieldNo] := TDbfBlobStream.Create(Field); + lBlob := FBlobStreams^[MemoFieldNo].AddReference; + // update pageno of blob <-> location where to read/write in memofile + if FDbfFile.GetFieldData(Field.FieldNo-1, ftInteger, GetCurrentBuffer, @MemoPageNo, false) then + begin + // read blob? different blob? + if (Mode = bmRead) or (Mode = bmReadWrite) then + begin + if MemoPageNo <> lBlob.MemoRecNo then + begin + FDbfFile.MemoFile.ReadMemo(MemoPageNo, lBlob); + lBlob.ReadSize := lBlob.Size; + lBlob.Translate(false); + end; + end else begin + lBlob.Size := 0; + lBlob.ReadSize := 0; + end; + lBlob.MemoRecNo := MemoPageNo; + end else + if not lBlob.Dirty or (Mode = bmWrite) then + begin + // reading and memo is empty and not written yet, or rewriting + lBlob.Size := 0; + lBlob.ReadSize := 0; + lBlob.MemoRecNo := 0; + end; + { this is a hack, we actually need to know per user who's modifying, and who is not } + { Mode is more like: the mode of the last "creation" } + { if create/free is nested, then everything will be alright, i think ;-) } + lBlob.Mode := Mode; + { this is a hack: we actually need to know per user what it's position is } + lBlob.Position := 0; + Result := lBlob; +end; + +{$ifdef SUPPORT_NEW_TRANSLATE} + +function TDbf.Translate(Src, Dest: PChar; ToOem: Boolean): Integer; {override virtual} +var + FromCP, ToCP: Cardinal; +begin + if (Src <> nil) and (Dest <> nil) then + begin + if Assigned(FOnTranslate) then + begin + Result := FOnTranslate(Self, Src, Dest, ToOem); + if Result = -1 then + Result := StrLen(Dest); + end else begin + if FTranslationMode <> tmNoneNeeded then + begin + if ToOem then + begin + FromCP := GetACP; + ToCP := FDbfFile.UseCodePage; + end else begin + FromCP := FDbfFile.UseCodePage; + ToCP := GetACP; + end; + end else begin + FromCP := GetACP; + ToCP := FromCP; + end; + Result := TranslateString(FromCP, ToCP, Src, Dest, -1); + end; + end else + Result := 0; +end; + +{$else} + +procedure TDbf.Translate(Src, Dest: PChar; ToOem: Boolean); {override virtual} +var + FromCP, ToCP: Cardinal; +begin + if (Src <> nil) and (Dest <> nil) then + begin + if Assigned(FOnTranslate) then + begin + FOnTranslate(Self, Src, Dest, ToOem); + end else begin + if FTranslationMode <> tmNoneNeeded then + begin + if ToOem then + begin + FromCP := GetACP; + ToCP := FDbfFile.UseCodePage; + end else begin + FromCP := FDbfFile.UseCodePage; + ToCP := GetACP; + end; + TranslateString(FromCP, ToCP, Src, Dest, -1); + end; + end; + end; +end; + +{$endif} + +procedure TDbf.ClearCalcFields(Buffer: TRecordBuffer); +var + lRealBuffer, lCalcBuffer: PChar; +begin + lRealBuffer := @pDbfRecord(Buffer)^.DeletedFlag; + lCalcBuffer := lRealBuffer + FDbfFile.RecordSize; + FillChar(lCalcBuffer^, CalcFieldsSize, 0); +end; + +procedure TDbf.InternalSetToRecord(Buffer: TRecordBuffer); {override virtual abstract from TDataset} +var + pRecord: pDbfRecord; +begin + if Buffer <> nil then + begin + pRecord := pDbfRecord(Buffer); + if pRecord^.BookmarkFlag = bfInserted then + begin + // do what ??? + end else begin + FCursor.SequentialRecNo := pRecord^.SequentialRecNo; + end; + end; +end; + +function TDbf.IsCursorOpen: Boolean; {override virtual abstract from TDataset} +begin + Result := FCursor <> nil; +end; + +function TDbf.FieldDefsStored: Boolean; +begin + Result := StoreDefs and (FieldDefs.Count > 0); +end; + +procedure TDbf.SetBookmarkFlag(Buffer: TRecordBuffer; Value: TBookmarkFlag); {override virtual abstract from TDataset} +begin + pDbfRecord(Buffer)^.BookmarkFlag := Value; +end; + +procedure TDbf.SetBookmarkData(Buffer: TRecordBuffer; Data: Pointer); {override virtual abstract from TDataset} +begin + pDbfRecord(Buffer)^.BookmarkData := pBookmarkData(Data)^; +end; + +// this function counts real number of records: skip deleted records, filter, etc. +// warning: is very slow, compared to GetRecordCount +function TDbf.GetExactRecordCount: Integer; +var + prevRecNo: Integer; + getRes: TGetResult; +begin + // init vars + Result := 0; + + // check if FCursor open + if FCursor = nil then + exit; + + // store current position + prevRecNo := FCursor.SequentialRecNo; + FCursor.First; + repeat + // repeatedly retrieve next record until eof encountered + getRes := GetRecord(FTempBuffer, gmNext, true); + if getRes = grOk then + inc(Result); + until getRes <> grOk; + // restore current position + FCursor.SequentialRecNo := prevRecNo; +end; + +// this functions returns the physical number of records present in file +function TDbf.GetPhysicalRecordCount: Integer; +begin + if FDbfFile <> nil then + Result := FDbfFile.RecordCount + else + Result := 0 +end; + +// this function is just for the grid scrollbars +// it doesn't have to be perfectly accurate, but fast. +function TDbf.GetRecordCount: Integer; {override virtual} +begin + if FCursor <> nil then + Result := FCursor.SequentialRecordCount + else + Result := 0 +end; + +// this function is just for the grid scrollbars +// it doesn't have to be perfectly accurate, but fast. +function TDbf.GetRecNo: Integer; {override virtual} +var + pBuffer: pointer; +begin + if FCursor <> nil then + begin + if State = dsCalcFields then + pBuffer := CalcBuffer + else + pBuffer := ActiveBuffer; + Result := pDbfRecord(pBuffer)^.SequentialRecNo; + end else + Result := 0; +end; + +procedure TDbf.SetRecNo(Value: Integer); {override virtual} +begin + CheckBrowseMode; + if Value = RecNo then + exit; + + DoBeforeScroll; + FCursor.SequentialRecNo := Value; + CursorPosChanged; + Resync([]); + DoAfterScroll; +end; + +function TDbf.GetCanModify: Boolean; {override;} +begin + if FReadOnly or (csDesigning in ComponentState) then + Result := false + else + Result := FTranslationMode > tmNoneAvailable; +end; + +{$ifdef SUPPORT_DEFCHANGED} + +procedure TDbf.DefChanged(Sender: TObject); +begin + StoreDefs := true; +end; + +{$endif} + +procedure TDbf.ParseFilter(const AFilter: string); +begin + // parser created? + if Length(AFilter) > 0 then + begin + if (FParser = nil) and (FDbfFile <> nil) then + begin + FParser := TDbfParser.Create(FDbfFile); + // we need truncated, translated (to ANSI) strings + FParser.StringFieldMode := smAnsiTrim; + end; + // have a parser now? + if FParser <> nil then + begin + // set options + FParser.PartialMatch := not (foNoPartialCompare in FilterOptions); + FParser.CaseInsensitive := foCaseInsensitive in FilterOptions; + // parse expression + FParser.ParseExpression(AFilter); + end; + end; +end; + +procedure TDbf.SetFilterText(const Value: String); +begin + if Value = Filter then + exit; + + // parse + ParseFilter(Value); + + // call dataset method + inherited; + + // refilter dataset if filtered + if (FDbfFile <> nil) and Filtered then Refresh; +end; + +procedure TDbf.SetFiltered(Value: Boolean); {override;} +begin + if Value = Filtered then + exit; + + // pass on to ancestor + inherited; + + // only refresh if active + if FCursor <> nil then + Refresh; +end; + +procedure TDbf.SetFilePath(const Value: string); +begin + CheckInactive; + + FRelativePath := Value; + if Length(FRelativePath) > 0 then + FRelativePath := IncludeTrailingPathDelimiter(FRelativePath); + + if IsFullFilePath(Value) then + begin + FAbsolutePath := IncludeTrailingPathDelimiter(Value); + end else begin + FAbsolutePath := GetCompletePath(DbfBasePath(), FRelativePath); + end; +end; + +procedure TDbf.SetTableName(const s: string); +var + lPath: string; +begin + FTableName := ExtractFileName(s); + lPath := ExtractFilePath(s); + if (Length(lPath) > 0) then + FilePath := lPath; + // force IDE to reread fielddefs when a different file is opened +{$ifdef SUPPORT_FIELDDEFS_UPDATED} + FieldDefs.Updated := false; +{$else} + // TODO ... ?? +{$endif} +end; + +procedure TDbf.SetDbfIndexDefs(const Value: TDbfIndexDefs); +begin + FIndexDefs.Assign(Value); +end; + +procedure TDbf.SetLanguageID(NewID: Byte); +begin + CheckInactive; + + FLanguageID := NewID; +end; + +procedure TDbf.SetTableLevel(const NewLevel: Integer); +begin + if NewLevel <> FTableLevel then + begin + // check validity + if not ((NewLevel = 3) or (NewLevel = 4) or (NewLevel = 7) or (NewLevel = 25)) then + exit; + + // can only assign tablelevel if table is closed + CheckInactive; + FTableLevel := NewLevel; + end; +end; + +function TDbf.GetIndexName: string; +begin + Result := FIndexName; +end; + +function TDbf.CompareBookmarks(Bookmark1, Bookmark2: TBookmark): Integer; +const + RetCodes: array[Boolean, Boolean] of ShortInt = ((2,-1),(1,0)); +var + b1,b2: Integer; +begin + // Check for uninitialized bookmarks + Result := RetCodes[Bookmark1 = nil, Bookmark2 = nil]; + if (Result = 2) then + begin + b1 := PInteger(Bookmark1)^; + b2 := PInteger(Bookmark2)^; + if b1 < b2 then Result := -1 + else if b1 > b2 then Result := 1 + else Result := 0; + end; +end; + +function TDbf.GetVersion: string; +begin + Result := Format('%d.%02d', [TDBF_MAJOR_VERSION, TDBF_MINOR_VERSION]); +end; + +procedure TDbf.SetVersion(const S: string); +begin + // What an idea... +end; + +function TDbf.ParseIndexName(const AIndexName: string): string; +begin + // if no ext, then it is a MDX tag, get complete only if it is a filename + // MDX: get first 10 characters only + if Length(ExtractFileExt(AIndexName)) > 0 then + Result := GetCompleteFileName(FAbsolutePath, AIndexName) + else + Result := AIndexName; +end; + +procedure TDbf.RegenerateIndexes; +begin + CheckBrowseMode; + FDbfFile.RegenerateIndexes; +end; + +{$ifdef SUPPORT_DEFAULT_PARAMS} +procedure TDbf.AddIndex(const AIndexName, AFields: String; Options: TIndexOptions; const DescFields: String=''); +{$else} +procedure TDbf.AddIndex(const AIndexName, AFields: String; Options: TIndexOptions); +{$endif} +var + lIndexFileName: string; +begin + CheckActive; + lIndexFileName := ParseIndexName(AIndexName); + FDbfFile.OpenIndex(lIndexFileName, AFields, true, Options); + + // refresh our indexdefs + InternalInitFieldDefs; +end; + +procedure TDbf.SetIndexName(AIndexName: string); +var + lRecNo: Integer; +begin + FIndexName := AIndexName; + if FDbfFile = nil then + exit; + + // get accompanying index file + AIndexName := ParseIndexName(Trim(AIndexName)); + FIndexFile := FDbfFile.GetIndexByName(AIndexName); + // store current lRecNo + if FCursor = nil then + begin + lRecNo := 1; + end else begin + UpdateCursorPos; + lRecNo := FCursor.PhysicalRecNo; + end; + // select new cursor + FreeAndNil(FCursor); + if FIndexFile <> nil then + begin + FCursor := TIndexCursor.Create(FIndexFile); + // select index + FIndexFile.IndexName := AIndexName; + // check if can activate master link + CheckMasterRange; + end else begin + FCursor := TDbfCursor.Create(FDbfFile); + FIndexName := EmptyStr; + end; + // reset previous lRecNo + FCursor.PhysicalRecNo := lRecNo; + // refresh records + if State = dsBrowse then + Resync([]); + // warn user if selecting non-existing index + if (FCursor = nil) and (AIndexName <> EmptyStr) then + raise EDbfError.CreateFmt(STRING_INDEX_NOT_EXIST, [AIndexName]); +end; + +function TDbf.GetIndexFieldNames: string; +var + lIndexDef: TDbfIndexDef; +begin + lIndexDef := FIndexDefs.GetIndexByName(IndexName); + if lIndexDef = nil then + Result := EmptyStr + else + Result := lIndexDef.SortField; +end; + +procedure TDbf.SetIndexFieldNames(const Value: string); +var + lIndexDef: TDbfIndexDef; +begin + // Exception if index not found? + lIndexDef := FIndexDefs.GetIndexByField(Value); + if lIndexDef = nil then + IndexName := EmptyStr + else + IndexName := lIndexDef.IndexFile; +end; + +procedure TDbf.DeleteIndex(const AIndexName: string); +var + lIndexFileName: string; +begin + // extract absolute path if NDX file + lIndexFileName := ParseIndexName(AIndexName); + // try to delete index + FDbfFile.DeleteIndex(lIndexFileName); + + // refresh index defs + InternalInitFieldDefs; +end; + +procedure TDbf.OpenIndexFile(IndexFile: string); +var + lIndexFileName: string; +begin + CheckActive; + // make absolute path + lIndexFileName := GetCompleteFileName(FAbsolutePath, IndexFile); + // open index + FDbfFile.OpenIndex(lIndexFileName, '', false, []); +end; + +procedure TDbf.CloseIndexFile(const AIndexName: string); +var + lIndexFileName: string; +begin + CheckActive; + // make absolute path + lIndexFileName := GetCompleteFileName(FAbsolutePath, AIndexName); + // close this index + FDbfFile.CloseIndex(lIndexFileName); +end; + +procedure TDbf.RepageIndexFile(const AIndexFile: string); +begin + if FDbfFile <> nil then + FDbfFile.RepageIndex(ParseIndexName(AIndexFile)); +end; + +procedure TDbf.CompactIndexFile(const AIndexFile: string); +begin + if FDbfFile <> nil then + FDbfFile.CompactIndex(ParseIndexName(AIndexFile)); +end; + +procedure TDbf.GetFileNames(Strings: TStrings; Files: TDbfFileNames); +var + I: Integer; +begin + Strings.Clear; + if FDbfFile <> nil then + begin + if dfDbf in Files then + Strings.Add(FDbfFile.FileName); + if (dfMemo in Files) and (FDbfFile.MemoFile <> nil) then + Strings.Add(FDbfFile.MemoFile.FileName); + if dfIndex in Files then + for I := 0 to Pred(FDbfFile.IndexFiles.Count) do + Strings.Add(TPagedFile(FDbfFile.IndexFiles.Items[I]).FileName); + end else + Strings.Add(IncludeTrailingPathDelimiter(FilePathFull) + TableName); +end; + +{$ifdef SUPPORT_DEFAULT_PARAMS} +function TDbf.GetFileNames(Files: TDbfFileNames (* = [dfDbf] *) ): string; +{$else} +function TDbf.GetFileNamesString(Files: TDbfFileNames ): string; +{$endif} +var + sl: TStrings; +begin + sl := TStringList.Create; + try + GetFileNames(sl, Files); + Result := sl.Text; + finally + sl.Free; + end; +end; + + + +procedure TDbf.GetIndexNames(Strings: TStrings); +begin + CheckActive; + Strings.Assign(DbfFile.IndexNames) +end; + +procedure TDbf.GetAllIndexFiles(Strings: TStrings); +var + SR: TSearchRec; +begin + CheckActive; + Strings.Clear; + if SysUtils.FindFirst(IncludeTrailingPathDelimiter(ExtractFilePath(FDbfFile.FileName)) + + '*.NDX', faAnyFile, SR) = 0 then + begin + repeat + Strings.Add(SR.Name); + until SysUtils.FindNext(SR)<>0; + SysUtils.FindClose(SR); + end; +end; + +function TDbf.GetPhysicalRecNo: Integer; +var + pBuffer: pointer; +begin + // check if active, test state: if inserting, then -1 + if (FCursor <> nil) and (State <> dsInsert) then + begin + if State = dsCalcFields then + pBuffer := CalcBuffer + else + pBuffer := ActiveBuffer; + Result := pDbfRecord(pBuffer)^.BookmarkData.PhysicalRecNo; + end else + Result := -1; +end; + +procedure TDbf.SetPhysicalRecNo(const NewRecNo: Integer); +begin + // editing? + CheckBrowseMode; + DoBeforeScroll; + FCursor.PhysicalRecNo := NewRecNo; + CursorPosChanged; + Resync([]); + DoAfterScroll; +end; + +function TDbf.GetDbfFieldDefs: TDbfFieldDefs; +begin + if FDbfFile <> nil then + Result := FDbfFile.FieldDefs + else + Result := nil; +end; + +procedure TDbf.SetShowDeleted(Value: Boolean); +begin + // test if changed + if Value <> FShowDeleted then + begin + // store new value + FShowDeleted := Value; + // refresh view only if active + if FCursor <> nil then + Refresh; + end; +end; + +function TDbf.IsDeleted: Boolean; +var + src: TRecordBuffer; +begin + src := GetCurrentBuffer; + IsDeleted := (src=nil) or (AnsiChar(src^) = '*') +end; + +procedure TDbf.Undelete; +var + src: TRecordBuffer; +begin + if State <> dsEdit then + inherited Edit; + // get active buffer + src := GetCurrentBuffer; + if (src <> nil) and (AnsiChar(src^) = '*') then + begin + // notify indexes record is about to be recalled + FDbfFile.RecordRecalled(FCursor.PhysicalRecNo, src); + // recall record + src^ := TRecordBufferBaseType(' '); + FDbfFile.WriteRecord(FCursor.PhysicalRecNo, src); + end; +end; + +procedure TDbf.CancelRange; +begin + if FIndexFile = nil then + exit; + + // disable current range if any + FIndexFile.CancelRange; + // reretrieve previous and next records + Refresh; +end; + +procedure TDbf.SetRangeBuffer(LowRange: PChar; HighRange: PChar); +begin + if FIndexFile = nil then + exit; + + FIndexFile.SetRange(LowRange, HighRange); + // go to first in this range + if Active then + inherited First; +end; + +{$ifdef SUPPORT_VARIANTS} + +procedure TDbf.SetRange(LowRange: Variant; HighRange: Variant; KeyIsANSI: boolean); +var + LowBuf, HighBuf: array[0..100] of Char; +begin + if (FIndexFile = nil) or VarIsNull(LowRange) or VarIsNull(HighRange) then + exit; + + // convert variants to index key type + if (TIndexCursor(FCursor).VariantToBuffer(LowRange, @LowBuf[0]) = etString) and KeyIsANSI then + Translate(@LowBuf[0], @LowBuf[0], true); + if (TIndexCursor(FCursor).VariantToBuffer(HighRange, @HighBuf[0]) = etString) and KeyIsANSI then + Translate(@HighBuf[0], @HighBuf[0], true); + SetRangeBuffer(@LowBuf[0], @HighBuf[0]); +end; + +{$endif} + +procedure TDbf.SetRangePChar(LowRange: PChar; HighRange: PChar; KeyIsANSI: boolean); +var + LowBuf, HighBuf: array [0..100] of Char; + LowPtr, HighPtr: PChar; +begin + if FIndexFile = nil then + exit; + + // convert to pchars + if KeyIsANSI then + begin + Translate(LowRange, @LowBuf[0], true); + Translate(HighRange, @HighBuf[0], true); + LowRange := @LowBuf[0]; + HighRange := @HighBuf[0]; + end; + LowPtr := TIndexCursor(FCursor).CheckUserKey(LowRange, @LowBuf[0]); + HighPtr := TIndexCursor(FCursor).CheckUserKey(HighRange, @HighBuf[0]); + SetRangeBuffer(LowPtr, HighPtr); +end; + +procedure TDbf.ExtractKey(KeyBuffer: PChar); +begin + if FIndexFile <> nil then + StrCopy(FIndexFile.ExtractKeyFromBuffer(GetCurrentBuffer), KeyBuffer) + else + KeyBuffer[0] := #0; +end; + +function TDbf.GetKeySize: Integer; +begin + if FCursor is TIndexCursor then + Result := TIndexCursor(FCursor).IndexFile.KeyLen + else + Result := 0; +end; + +{$ifdef SUPPORT_VARIANTS} + +function TDbf.SearchKey(Key: Variant; SearchType: TSearchKeyType; KeyIsANSI: boolean): Boolean; +var + TempBuffer: array [0..100] of Char; +begin + if (FIndexFile = nil) or VarIsNull(Key) then + begin + Result := false; + exit; + end; + + // FIndexFile <> nil -> FCursor as TIndexCursor <> nil + if (TIndexCursor(FCursor).VariantToBuffer(Key, @TempBuffer[0]) = etString) and KeyIsANSI then + Translate(@TempBuffer[0], @TempBuffer[0], true); + Result := SearchKeyBuffer(@TempBuffer[0], SearchType); +end; + +{$endif} + +function TDbf.PrepareKey(Buffer: Pointer; BufferType: TExpressionType): PChar; +begin + if FIndexFile = nil then + begin + Result := nil; + exit; + end; + + Result := TIndexCursor(FCursor).IndexFile.PrepareKey(Buffer, BufferType); +end; + +function TDbf.SearchKeyPChar(Key: PChar; SearchType: TSearchKeyType; KeyIsANSI: boolean): Boolean; +var + StringBuf: array [0..100] of Char; +begin + if FCursor = nil then + begin + Result := false; + exit; + end; + + if KeyIsANSI then + begin + Translate(Key, @StringBuf[0], true); + Key := @StringBuf[0]; + end; + Result := SearchKeyBuffer(TIndexCursor(FCursor).CheckUserKey(Key, @StringBuf[0]), SearchType); +end; + +function TDbf.SearchKeyBuffer(Buffer: PChar; SearchType: TSearchKeyType): Boolean; +var + matchRes: Integer; +begin + if FIndexFile = nil then + begin + Result := false; + exit; + end; + + CheckBrowseMode; + Result := FIndexFile.SearchKey(Buffer, SearchType); + { if found, then retrieve new current record } + if Result then + begin + CursorPosChanged; + Resync([]); + UpdateCursorPos; + { recno could have been changed due to deleted record, check if still matches } + matchRes := TIndexCursor(FCursor).IndexFile.MatchKey(Buffer); + case SearchType of + stEqual: Result := matchRes = 0; + stGreater: Result := (not Eof) and (matchRes < 0); + stGreaterEqual: Result := (not Eof) and (matchRes <= 0); + end; + end; +end; + +procedure TDbf.UpdateIndexDefs; +begin + FieldDefs.Update; +end; + +// A hack to upgrade method visibility, only necessary for FPC 1.0.x + +{$ifdef VER1_0} + +procedure TDbf.DataEvent(Event: TDataEvent; Info: Longint); +begin + inherited; +end; + +{$endif} + +{ Master / Detail } + +procedure TDbf.CheckMasterRange; +begin + if FMasterLink.Active and FMasterLink.ValidExpression and (FIndexFile <> nil) then + UpdateRange; +end; + +procedure TDbf.UpdateRange; +var + fieldsVal: TRecordBuffer; + tempBuffer: array[0..300] of char; +begin + fieldsVal := FMasterLink.FieldsVal; + if (TDbf(FMasterLink.DataSet).DbfFile.UseCodePage <> FDbfFile.UseCodePage) + and (FMasterLink.Parser.ResultType = etString) then + begin + FMasterLink.DataSet.Translate(pansichar(fieldsVal), @tempBuffer[0], false); + fieldsVal := @tempBuffer[0]; + Translate(pansichar(fieldsVal), pansichar(fieldsVal), true); + end; + // preparekey, setrangebuffer and updatekeyfrom* are functions which arguments + // are not entirely classified in pchar<>trecordbuffer terms. + // so we typecast for now. + fieldsVal := TRecordBuffer(TIndexCursor(FCursor).IndexFile.PrepareKey((fieldsVal), FMasterLink.Parser.ResultType)); + SetRangeBuffer(pansichar(fieldsVal), pansichar(fieldsVal)); +end; + +procedure TDbf.MasterChanged(Sender: TObject); +begin + CheckBrowseMode; + CheckMasterRange; +end; + +procedure TDbf.MasterDisabled(Sender: TObject); +begin + CancelRange; +end; + +function TDbf.GetDataSource: TDataSource; +begin + Result := FMasterLink.DataSource; +end; + +procedure TDbf.SetDataSource(Value: TDataSource); +begin +{$ifndef FPC} + if IsLinkedTo(Value) then + begin +{$ifdef DELPHI_4} + DatabaseError(SCircularDataLink, Self); +{$else} + DatabaseError(SCircularDataLink); +{$endif} + end; +{$endif} + FMasterLink.DataSource := Value; +end; + +function TDbf.GetMasterFields: string; +begin + Result := FMasterLink.FieldNames; +end; + +procedure TDbf.SetMasterFields(const Value: string); +begin + FMasterLink.FieldNames := Value; +end; + +//========================================================== +//============ TDbfIndexDefs +//========================================================== +constructor TDbfIndexDefs.Create(AOwner: TDbf); +begin + inherited Create(TDbfIndexDef); + FOwner := AOwner; +end; + +function TDbfIndexDefs.Add: TDbfIndexDef; +begin + Result := TDbfIndexDef(inherited Add); +end; + +procedure TDbfIndexDefs.SetItem(N: Integer; Value: TDbfIndexDef); +begin + inherited SetItem(N, Value); +end; + +function TDbfIndexDefs.GetItem(N: Integer): TDbfIndexDef; +begin + Result := TDbfIndexDef(inherited GetItem(N)); +end; + +function TDbfIndexDefs.GetOwner: tpersistent; +begin + Result := FOwner; +end; + +function TDbfIndexDefs.GetIndexByName(const Name: string): TDbfIndexDef; +var + I: Integer; + lIndex: TDbfIndexDef; +begin + for I := 0 to Count-1 do + begin + lIndex := Items[I]; + if lIndex.IndexFile = Name then + begin + Result := lIndex; + exit; + end + end; + Result := nil; +end; + +function TDbfIndexDefs.GetIndexByField(const Name: string): TDbfIndexDef; +var + lIndex: TDbfIndexDef; + searchStr: string; + i: integer; +begin + searchStr := AnsiUpperCase(Trim(Name)); + Result := nil; + if searchStr = EmptyStr then + exit; + + for I := 0 to Count-1 do + begin + lIndex := Items[I]; + if AnsiUpperCase(Trim(lIndex.SortField)) = searchStr then + begin + Result := lIndex; + exit; + end + end; +end; + +procedure TDbfIndexDefs.Update; +begin + if Assigned(FOwner) then + FOwner.UpdateIndexDefs; +end; + +//========================================================== +//============ TDbfMasterLink +//========================================================== + +constructor TDbfMasterLink.Create(ADataSet: TDbf); +begin + inherited Create; + + FDetailDataSet := ADataSet; + FParser := TDbfParser.Create(nil); + FValidExpression := false; +end; + +destructor TDbfMasterLink.Destroy; +begin + FParser.Free; + + inherited; +end; + +procedure TDbfMasterLink.ActiveChanged; +begin + if Active and (FFieldNames <> EmptyStr) then + begin + FValidExpression := false; + FParser.DbfFile := (DataSet as TDbf).DbfFile; + FParser.ParseExpression(FFieldNames); + FValidExpression := true; + end else begin + FParser.ClearExpressions; + FValidExpression := false; + end; + + if FDetailDataSet.Active and not (csDestroying in FDetailDataSet.ComponentState) then + if Active then + begin + if Assigned(FOnMasterChange) then FOnMasterChange(Self); + end else + if Assigned(FOnMasterDisable) then FOnMasterDisable(Self); +end; + +procedure TDbfMasterLink.CheckBrowseMode; +begin + if FDetailDataSet.Active then + FDetailDataSet.CheckBrowseMode; +end; + +procedure TDbfMasterLink.LayoutChanged; +begin + ActiveChanged; +end; + +procedure TDbfMasterLink.RecordChanged(Field: TField); +begin + if (DataSource.State <> dsSetKey) and FDetailDataSet.Active and Assigned(FOnMasterChange) then + FOnMasterChange(Self); +end; + +procedure TDbfMasterLink.SetFieldNames(const Value: string); +begin + if FFieldNames <> Value then + begin + FFieldNames := Value; + ActiveChanged; + end; +end; + +function TDbfMasterLink.GetFieldsVal: TRecordBuffer; +begin + Result := TRecordBuffer(FParser.ExtractFromBuffer(@pDbfRecord(TDbf(DataSet).ActiveBuffer)^.DeletedFlag)); +end; + +//////////////////////////////////////////////////////////////////////////// + +function ApplicationPath: string; +begin + Result := ExtractFilePath(ParamStr(0)); +end; + + +//////////////////////////////////////////////////////////////////////////// + +initialization + + DbfBasePath := ApplicationPath; + +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/mdbf_prscore.pas b/mseide-msegui/lib/common/fpccompatibility/mdbf_prscore.pas new file mode 100644 index 0000000..35b6b1f --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/mdbf_prscore.pas @@ -0,0 +1,2347 @@ +unit mdbf_prscore; + +{-------------------------------------------------------------- +| TCustomExpressionParser +| +| - contains core expression parser +| +| This code is based on code from: +| +| Original author: Egbert van Nes +| With contributions of: John Bultena and Ralf Junker +| Homepage: http://www.slm.wau.nl/wkao/parseexpr.html +| +| see also: http://www.datalog.ro/delphi/parser.html +| (Renate Schaaf (schaaf at math.usu.edu), 1993 +| Alin Flaider (aflaidar at datalog.ro), 1996 +| Version 9-10: Stefan Hoffmeister, 1996-1997) +| +| Modified 2013 by Martin Schreiber +| +|---------------------------------------------------------------} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{$I dbf_common.inc} + +uses + SysUtils, + classes,mclasses, + mdb, + mdbf_prssupp, + mdbf_prsdef; + +{$define ENG_NUMBERS} + +// ENG_NUMBERS will force the use of english style numbers 8.1 instead of 8,1 +// (if the comma is your decimal separator) +// the advantage is that arguments can be separated with a comma which is +// fairly common, otherwise there is ambuigity: what does 'var1,8,4,4,5' mean? +// if you don't define ENG_NUMBERS and DecimalSeparator is a comma then +// the argument separator will be a semicolon ';' + +type + + TCustomExpressionParser = class(TObject) + private + FHexChar: Char; + FArgSeparator: Char; + FDecimalSeparator: Char; + FOptimize: Boolean; + FConstantsList: TOCollection; + FLastRec: PExpressionRec; + FCurrentRec: PExpressionRec; + FExpResult: PChar; + FExpResultPos: PChar; + FExpResultSize: Integer; + + procedure ParseString(AnExpression: string; DestCollection: TExprCollection); + function MakeTree(Expr: TExprCollection; FirstItem, LastItem: Integer): PExpressionRec; + procedure MakeLinkedList(var ExprRec: PExpressionRec; Memory: PPChar; + MemoryPos: PPChar; MemSize: PInteger); + procedure Check(AnExprList: TExprCollection); + procedure CheckArguments(ExprRec: PExpressionRec); + procedure RemoveConstants(var ExprRec: PExpressionRec); + function ResultCanVary(ExprRec: PExpressionRec): Boolean; + protected + FWordsList: TSortedCollection; + + function MakeRec: PExpressionRec; virtual; + procedure FillExpressList; virtual; abstract; + procedure HandleUnknownVariable(VarName: string); virtual; abstract; + + procedure CompileExpression(AnExpression: string); + procedure EvaluateCurrent; + procedure DisposeList(ARec: PExpressionRec); + procedure DisposeTree(ExprRec: PExpressionRec); + function CurrentExpression: string; virtual; abstract; + function GetResultType: TExpressionType; virtual; + + property CurrentRec: PExpressionRec read FCurrentRec write FCurrentRec; + property LastRec: PExpressionRec read FLastRec write FLastRec; + property ExpResult: PChar read FExpResult; + property ExpResultPos: PChar read FExpResultPos write FExpResultPos; + + public + constructor Create; + destructor Destroy; override; + + function DefineFloatVariable(AVarName: string; AValue: PDouble): TExprWord; + function DefineIntegerVariable(AVarName: string; AValue: PInteger): TExprWord; +// procedure DefineSmallIntVariable(AVarName: string; AValue: PSmallInt); +{$ifdef SUPPORT_INT64} + function DefineLargeIntVariable(AVarName: string; AValue: PLargeInt): TExprWord; +{$endif} + function DefineDateTimeVariable(AVarName: string; AValue: PDateTimeRec): TExprWord; + function DefineBooleanVariable(AVarName: string; AValue: PBoolean): TExprWord; + function DefineStringVariable(AVarName: string; AValue: PPChar): TExprWord; + function DefineFunction(AFunctName, AShortName, ADescription, ATypeSpec: string; + AMinFunctionArg: Integer; AResultType: TExpressionType; AFuncAddress: TExprFunc): TExprWord; + procedure Evaluate(AnExpression: string); + function AddExpression(AnExpression: string): Integer; + procedure ClearExpressions; virtual; +// procedure GetGeneratedVars(AList: TList); + procedure GetFunctionNames(AList: TStrings); + function GetFunctionDescription(AFunction: string): string; + property HexChar: Char read FHexChar write FHexChar; + property ArgSeparator: Char read FArgSeparator write FArgSeparator; + property Optimize: Boolean read FOptimize write FOptimize; + property ResultType: TExpressionType read GetResultType; + + + //if optimize is selected, constant expressions are tried to remove + //such as: 4*4*x is evaluated as 16*x and exp(1)-4*x is repaced by 2.17 -4*x + end; + + +//--Expression functions----------------------------------------------------- + +procedure FuncFloatToStr(Param: PExpressionRec); +procedure FuncIntToStr_Gen(Param: PExpressionRec; Val: {$ifdef SUPPORT_INT64}Int64{$else}Integer{$endif}); +procedure FuncIntToStr(Param: PExpressionRec); +{$ifdef SUPPORT_INT64} +procedure FuncInt64ToStr(Param: PExpressionRec); +{$endif} +procedure FuncDateToStr(Param: PExpressionRec); +procedure FuncSubString(Param: PExpressionRec); +procedure FuncUppercase(Param: PExpressionRec); +procedure FuncLowercase(Param: PExpressionRec); +procedure FuncAdd_F_FF(Param: PExpressionRec); +procedure FuncAdd_F_FI(Param: PExpressionRec); +procedure FuncAdd_F_II(Param: PExpressionRec); +procedure FuncAdd_F_IF(Param: PExpressionRec); +{$ifdef SUPPORT_INT64} +procedure FuncAdd_F_FL(Param: PExpressionRec); +procedure FuncAdd_F_IL(Param: PExpressionRec); +procedure FuncAdd_F_LL(Param: PExpressionRec); +procedure FuncAdd_F_LF(Param: PExpressionRec); +procedure FuncAdd_F_LI(Param: PExpressionRec); +{$endif} +procedure FuncSub_F_FF(Param: PExpressionRec); +procedure FuncSub_F_FI(Param: PExpressionRec); +procedure FuncSub_F_II(Param: PExpressionRec); +procedure FuncSub_F_IF(Param: PExpressionRec); +{$ifdef SUPPORT_INT64} +procedure FuncSub_F_FL(Param: PExpressionRec); +procedure FuncSub_F_IL(Param: PExpressionRec); +procedure FuncSub_F_LL(Param: PExpressionRec); +procedure FuncSub_F_LF(Param: PExpressionRec); +procedure FuncSub_F_LI(Param: PExpressionRec); +{$endif} +procedure FuncMul_F_FF(Param: PExpressionRec); +procedure FuncMul_F_FI(Param: PExpressionRec); +procedure FuncMul_F_II(Param: PExpressionRec); +procedure FuncMul_F_IF(Param: PExpressionRec); +{$ifdef SUPPORT_INT64} +procedure FuncMul_F_FL(Param: PExpressionRec); +procedure FuncMul_F_IL(Param: PExpressionRec); +procedure FuncMul_F_LL(Param: PExpressionRec); +procedure FuncMul_F_LF(Param: PExpressionRec); +procedure FuncMul_F_LI(Param: PExpressionRec); +{$endif} +procedure FuncDiv_F_FF(Param: PExpressionRec); +procedure FuncDiv_F_FI(Param: PExpressionRec); +procedure FuncDiv_F_II(Param: PExpressionRec); +procedure FuncDiv_F_IF(Param: PExpressionRec); +{$ifdef SUPPORT_INT64} +procedure FuncDiv_F_FL(Param: PExpressionRec); +procedure FuncDiv_F_IL(Param: PExpressionRec); +procedure FuncDiv_F_LL(Param: PExpressionRec); +procedure FuncDiv_F_LF(Param: PExpressionRec); +procedure FuncDiv_F_LI(Param: PExpressionRec); +{$endif} +procedure FuncStrI_EQ(Param: PExpressionRec); +procedure FuncStrI_NEQ(Param: PExpressionRec); +procedure FuncStrI_LT(Param: PExpressionRec); +procedure FuncStrI_GT(Param: PExpressionRec); +procedure FuncStrI_LTE(Param: PExpressionRec); +procedure FuncStrI_GTE(Param: PExpressionRec); +procedure FuncStrIP_EQ(Param: PExpressionRec); +procedure FuncStrP_EQ(Param: PExpressionRec); +procedure FuncStr_EQ(Param: PExpressionRec); +procedure FuncStr_NEQ(Param: PExpressionRec); +procedure FuncStr_LT(Param: PExpressionRec); +procedure FuncStr_GT(Param: PExpressionRec); +procedure FuncStr_LTE(Param: PExpressionRec); +procedure FuncStr_GTE(Param: PExpressionRec); +procedure Func_FF_EQ(Param: PExpressionRec); +procedure Func_FF_NEQ(Param: PExpressionRec); +procedure Func_FF_LT(Param: PExpressionRec); +procedure Func_FF_GT(Param: PExpressionRec); +procedure Func_FF_LTE(Param: PExpressionRec); +procedure Func_FF_GTE(Param: PExpressionRec); +procedure Func_FI_EQ(Param: PExpressionRec); +procedure Func_FI_NEQ(Param: PExpressionRec); +procedure Func_FI_LT(Param: PExpressionRec); +procedure Func_FI_GT(Param: PExpressionRec); +procedure Func_FI_LTE(Param: PExpressionRec); +procedure Func_FI_GTE(Param: PExpressionRec); +procedure Func_II_EQ(Param: PExpressionRec); +procedure Func_II_NEQ(Param: PExpressionRec); +procedure Func_II_LT(Param: PExpressionRec); +procedure Func_II_GT(Param: PExpressionRec); +procedure Func_II_LTE(Param: PExpressionRec); +procedure Func_II_GTE(Param: PExpressionRec); +procedure Func_IF_EQ(Param: PExpressionRec); +procedure Func_IF_NEQ(Param: PExpressionRec); +procedure Func_IF_LT(Param: PExpressionRec); +procedure Func_IF_GT(Param: PExpressionRec); +procedure Func_IF_LTE(Param: PExpressionRec); +procedure Func_IF_GTE(Param: PExpressionRec); +{$ifdef SUPPORT_INT64} +procedure Func_LL_EQ(Param: PExpressionRec); +procedure Func_LL_NEQ(Param: PExpressionRec); +procedure Func_LL_LT(Param: PExpressionRec); +procedure Func_LL_GT(Param: PExpressionRec); +procedure Func_LL_LTE(Param: PExpressionRec); +procedure Func_LL_GTE(Param: PExpressionRec); +procedure Func_LF_EQ(Param: PExpressionRec); +procedure Func_LF_NEQ(Param: PExpressionRec); +procedure Func_LF_LT(Param: PExpressionRec); +procedure Func_LF_GT(Param: PExpressionRec); +procedure Func_LF_LTE(Param: PExpressionRec); +procedure Func_LF_GTE(Param: PExpressionRec); +procedure Func_FL_EQ(Param: PExpressionRec); +procedure Func_FL_NEQ(Param: PExpressionRec); +procedure Func_FL_LT(Param: PExpressionRec); +procedure Func_FL_GT(Param: PExpressionRec); +procedure Func_FL_LTE(Param: PExpressionRec); +procedure Func_FL_GTE(Param: PExpressionRec); +procedure Func_LI_EQ(Param: PExpressionRec); +procedure Func_LI_NEQ(Param: PExpressionRec); +procedure Func_LI_LT(Param: PExpressionRec); +procedure Func_LI_GT(Param: PExpressionRec); +procedure Func_LI_LTE(Param: PExpressionRec); +procedure Func_LI_GTE(Param: PExpressionRec); +procedure Func_IL_EQ(Param: PExpressionRec); +procedure Func_IL_NEQ(Param: PExpressionRec); +procedure Func_IL_LT(Param: PExpressionRec); +procedure Func_IL_GT(Param: PExpressionRec); +procedure Func_IL_LTE(Param: PExpressionRec); +procedure Func_IL_GTE(Param: PExpressionRec); +{$endif} +procedure Func_AND(Param: PExpressionRec); +procedure Func_OR(Param: PExpressionRec); +procedure Func_NOT(Param: PExpressionRec); + +var + DbfWordsSensGeneralList, DbfWordsInsensGeneralList: TExpressList; + DbfWordsSensPartialList, DbfWordsInsensPartialList: TExpressList; + DbfWordsSensNoPartialList, DbfWordsInsensNoPartialList: TExpressList; + DbfWordsGeneralList: TExpressList; + +implementation +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +procedure LinkVariable(ExprRec: PExpressionRec); +begin + with ExprRec^ do + begin + if ExprWord.IsVariable then + begin + // copy pointer to variable + Args[0] := ExprWord.AsPointer; + // store length as second parameter + Args[1] := PChar(ExprWord.LenAsPointer); + end; + end; +end; + +procedure LinkVariables(ExprRec: PExpressionRec); +var + I: integer; +begin + with ExprRec^ do + begin + I := 0; + while (I < MaxArg) and (ArgList[I] <> nil) do + begin + LinkVariables(ArgList[I]); + Inc(I); + end; + end; + LinkVariable(ExprRec); +end; + +{ TCustomExpressionParser } + +constructor TCustomExpressionParser.Create; +begin + inherited; + + FHexChar := '$'; +{$IFDEF ENG_NUMBERS} + FDecimalSeparator := '.'; + FArgSeparator := ','; +{$ELSE} + FDecimalSeparator := DecimalSeparator; + if DecimalSeparator = ',' then + FArgSeparator := ';' + else + FArgSeparator := ','; +{$ENDIF} + FConstantsList := TOCollection.Create; + FWordsList := TExpressList.Create; + GetMem(FExpResult, ArgAllocSize); + FExpResultPos := FExpResult; + FExpResultSize := ArgAllocSize; + FOptimize := true; + FillExpressList; +end; + +destructor TCustomExpressionParser.Destroy; +begin + ClearExpressions; + FreeMem(FExpResult); + FConstantsList.Free; + FWordsList.Free; + + inherited; +end; + +procedure TCustomExpressionParser.CompileExpression(AnExpression: string); +var + ExpColl: TExprCollection; + ExprTree: PExpressionRec; +begin + if Length(AnExpression) > 0 then + begin + ExprTree := nil; + ExpColl := TExprCollection.Create; + try + // FCurrentExpression := anExpression; + ParseString(AnExpression, ExpColl); + Check(ExpColl); + ExprTree := MakeTree(ExpColl, 0, ExpColl.Count - 1); + FCurrentRec := nil; + CheckArguments(ExprTree); + LinkVariables(ExprTree); + if Optimize then + RemoveConstants(ExprTree); + // all constant expressions are evaluated and replaced by variables + FCurrentRec := nil; + FExpResultPos := FExpResult; + MakeLinkedList(ExprTree, @FExpResult, @FExpResultPos, @FExpResultSize); + except + on E: Exception do + begin + DisposeTree(ExprTree); + ExpColl.Free; + raise; + end; + end; + ExpColl.Free; + end; +end; + +procedure TCustomExpressionParser.CheckArguments(ExprRec: PExpressionRec); +var + TempExprWord: TExprWord; + I, error, firstFuncIndex, funcIndex: Integer; + foundAltFunc: Boolean; + + procedure FindAlternate; + begin + // see if we can find another function + if funcIndex < 0 then + begin + firstFuncIndex := FWordsList.IndexOf(ExprRec^.ExprWord); + funcIndex := firstFuncIndex; + end; + // check if not last function + if (0 <= funcIndex) and (funcIndex < FWordsList.Count - 1) then + begin + inc(funcIndex); + TempExprWord := TExprWord(FWordsList.Items[funcIndex]); + if FWordsList.Compare(FWordsList.KeyOf(ExprRec^.ExprWord), FWordsList.KeyOf(TempExprWord)) = 0 then + begin + ExprRec^.ExprWord := TempExprWord; + ExprRec^.Oper := ExprRec^.ExprWord.ExprFunc; + foundAltFunc := true; + end; + end; + end; + + procedure InternalCheckArguments; + begin + I := 0; + error := 0; + foundAltFunc := false; + with ExprRec^ do + begin + if WantsFunction <> (ExprWord.IsFunction and not ExprWord.IsOperator) then + begin + error := 4; + exit; + end; + + while (I < ExprWord.MaxFunctionArg) and (ArgList[I] <> nil) and (error = 0) do + begin + // test subarguments first + CheckArguments(ArgList[I]); + + // test if correct type + if (ArgList[I]^.ExprWord.ResultType <> ExprCharToExprType(ExprWord.TypeSpec[I+1])) then + error := 2; + + // goto next argument + Inc(I); + end; + + // test if enough parameters passed; I = num args user passed + if (error = 0) and (I < ExprWord.MinFunctionArg) then + error := 1; + + // test if too many parameters passed + if (error = 0) and (I > ExprWord.MaxFunctionArg) then + error := 3; + end; + end; + +begin + funcIndex := -1; + repeat + InternalCheckArguments; + + // error occurred? + if error <> 0 then + FindAlternate; + until (error = 0) or not foundAltFunc; + + // maybe it's an undefined variable + if (error <> 0) and not ExprRec^.WantsFunction and (firstFuncIndex >= 0) then + begin + HandleUnknownVariable(ExprRec^.ExprWord.Name); + { must not add variable as first function in this set of duplicates, + otherwise following searches will not find it } + FWordsList.Exchange(firstFuncIndex, firstFuncIndex+1); + ExprRec^.ExprWord := TExprWord(FWordsList.Items[firstFuncIndex+1]); + ExprRec^.Oper := ExprRec^.ExprWord.ExprFunc; + InternalCheckArguments; + end; + + // fatal error? + case error of + 1: raise EParserException.Create('Function or operand has too few arguments'); + 2: raise EParserException.Create('Argument type mismatch'); + 3: raise EParserException.Create('Function or operand has too many arguments'); + 4: raise EParserException.Create('No function with this name, remove brackets for variable'); + end; +end; + +function TCustomExpressionParser.ResultCanVary(ExprRec: PExpressionRec): + Boolean; +var + I: Integer; +begin + with ExprRec^ do + begin + Result := ExprWord.CanVary; + if not Result then + for I := 0 to ExprWord.MaxFunctionArg - 1 do + if (ArgList[I] <> nil) and ResultCanVary(ArgList[I]) then + begin + Result := true; + Exit; + end + end; +end; + +procedure TCustomExpressionParser.RemoveConstants(var ExprRec: PExpressionRec); +var + I: Integer; +begin + if not ResultCanVary(ExprRec) then + begin + if not ExprRec^.ExprWord.IsVariable then + begin + // reset current record so that make list generates new + FCurrentRec := nil; + FExpResultPos := FExpResult; + MakeLinkedList(ExprRec, @FExpResult, @FExpResultPos, @FExpResultSize); + + try + // compute result + EvaluateCurrent; + + // make new record to store constant in + ExprRec := MakeRec; + + // check result type + with ExprRec^ do + begin + case ResultType of + etBoolean: ExprWord := TBooleanConstant.Create(EmptyStr, PBoolean(FExpResult)^); + etFloat: ExprWord := TFloatConstant.CreateAsDouble(EmptyStr, PDouble(FExpResult)^); + etString: ExprWord := TStringConstant.Create(FExpResult); + end; + + // fill in structure + Oper := ExprWord.ExprFunc; + Args[0] := ExprWord.AsPointer; + FConstantsList.Add(ExprWord); + end; + finally + DisposeList(FCurrentRec); + FCurrentRec := nil; + end; + end; + end else + with ExprRec^ do + begin + for I := 0 to ExprWord.MaxFunctionArg - 1 do + if ArgList[I] <> nil then + RemoveConstants(ArgList[I]); + end; +end; + +procedure TCustomExpressionParser.DisposeTree(ExprRec: PExpressionRec); +var + I: Integer; +begin + if ExprRec <> nil then + begin + with ExprRec^ do + begin + if ExprWord <> nil then + for I := 0 to ExprWord.MaxFunctionArg - 1 do + DisposeTree(ArgList[I]); + if Res <> nil then + Res.Free; + end; + Dispose(ExprRec); + end; +end; + +procedure TCustomExpressionParser.DisposeList(ARec: PExpressionRec); +var + TheNext: PExpressionRec; + I: Integer; +begin + if ARec <> nil then + repeat + TheNext := ARec^.Next; + if ARec^.Res <> nil then + ARec^.Res.Free; + I := 0; + while ARec^.ArgList[I] <> nil do + begin + FreeMem(ARec^.Args[I]); + Inc(I); + end; + Dispose(ARec); + ARec := TheNext; + until ARec = nil; +end; + +procedure TCustomExpressionParser.MakeLinkedList(var ExprRec: PExpressionRec; + Memory: PPChar; MemoryPos: PPChar; MemSize: PInteger); +var + I: Integer; +begin + // test function type + if @ExprRec^.ExprWord.ExprFunc = nil then + begin + // special 'no function' function + // indicates no function is present -> we can concatenate all instances + // we don't create new arguments...these 'fall' through + // use destination as we got it + I := 0; + while ExprRec^.ArgList[I] <> nil do + begin + // convert arguments to list + MakeLinkedList(ExprRec^.ArgList[I], Memory, MemoryPos, MemSize); + // goto next argument + Inc(I); + end; + // don't need this record anymore + Dispose(ExprRec); + ExprRec := nil; + end else begin + // inc memory pointer so we know if we are first + ExprRec^.ResetDest := MemoryPos^ = Memory^; + Inc(MemoryPos^); + // convert arguments to list + I := 0; + while ExprRec^.ArgList[I] <> nil do + begin + // save variable type for easy access + ExprRec^.ArgsType[I] := ExprRec^.ArgList[I]^.ExprWord.ResultType; + // check if we need to copy argument, variables in general do not + // need copying, except for fixed len strings which are not + // null-terminated +// if ExprRec^.ArgList[I].ExprWord.NeedsCopy then +// begin + // get memory for argument + GetMem(ExprRec^.Args[I], ArgAllocSize); + ExprRec^.ArgsPos[I] := ExprRec^.Args[I]; + ExprRec^.ArgsSize[I] := ArgAllocSize; + MakeLinkedList(ExprRec^.ArgList[I], @ExprRec^.Args[I], @ExprRec^.ArgsPos[I], + @ExprRec^.ArgsSize[I]); +// end else begin + // copy reference +// ExprRec^.Args[I] := ExprRec^.ArgList[I].Args[0]; +// ExprRec^.ArgsPos[I] := ExprRec^.Args[I]; +// ExprRec^.ArgsSize[I] := 0; +// FreeMem(ExprRec^.ArgList[I]); +// ExprRec^.ArgList[I] := nil; +// end; + + // goto next argument + Inc(I); + end; + + // link result to target argument + ExprRec^.Res := TDynamicType.Create(Memory, MemoryPos, MemSize); + + // link to next operation + if FCurrentRec = nil then + begin + FCurrentRec := ExprRec; + FLastRec := ExprRec; + end else begin + FLastRec^.Next := ExprRec; + FLastRec := ExprRec; + end; + end; +end; + +function TCustomExpressionParser.MakeTree(Expr: TExprCollection; + FirstItem, LastItem: Integer): PExpressionRec; + +{ +- This is the most complex routine, it breaks down the expression and makes + a linked tree which is used for fast function evaluations +- it is implemented recursively +} + +var + I, IArg, IStart, IEnd, lPrec, brCount: Integer; + ExprWord: TExprWord; +begin + // remove redundant brackets + brCount := 0; + while (FirstItem+brCount < LastItem) and (TExprWord( + Expr.Items[FirstItem+brCount]).ResultType = etLeftBracket) do + Inc(brCount); + I := LastItem; + while (I > FirstItem) and (TExprWord( + Expr.Items[I]).ResultType = etRightBracket) do + Dec(I); + // test max of start and ending brackets + if brCount > (LastItem-I) then + brCount := LastItem-I; + // count number of bracket pairs completely open from start to end + // IArg is min.brCount + I := FirstItem + brCount; + IArg := brCount; + while (I <= LastItem - brCount) and (brCount > 0) do + begin + case TExprWord(Expr.Items[I]).ResultType of + etLeftBracket: Inc(brCount); + etRightBracket: + begin + Dec(brCount); + if brCount < IArg then + IArg := brCount; + end; + end; + Inc(I); + end; + // useful pair bracket count, is in minimum, is IArg + brCount := IArg; + // check if subexpression closed within (bracket level will be zero) + if brCount > 0 then + begin + Inc(FirstItem, brCount); + Dec(LastItem, brCount); + end; + + // check for empty range + if LastItem < FirstItem then + begin + Result := nil; + exit; + end; + + // get new record + Result := MakeRec; + + // simple constant, variable or function? + if LastItem = FirstItem then + begin + Result^.ExprWord := TExprWord(Expr.Items[FirstItem]); + Result^.Oper := Result^.ExprWord.ExprFunc; + exit; + end; + + // no...more complex, find operator with lowest precedence + brCount := 0; + IArg := 0; + IEnd := FirstItem-1; + lPrec := -1; + for I := FirstItem to LastItem do + begin + ExprWord := TExprWord(Expr.Items[I]); + if (brCount = 0) and ExprWord.IsOperator and (TFunction(ExprWord).OperPrec > lPrec) then + begin + IEnd := I; + lPrec := TFunction(ExprWord).OperPrec; + end; + case ExprWord.ResultType of + etLeftBracket: Inc(brCount); + etRightBracket: Dec(brCount); + end; + end; + + // operator found ? + if IEnd >= FirstItem then + begin + // save operator + Result^.ExprWord := TExprWord(Expr.Items[IEnd]); + Result^.Oper := Result^.ExprWord.ExprFunc; + // recurse into left part if present + if IEnd > FirstItem then + begin + Result^.ArgList[IArg] := MakeTree(Expr, FirstItem, IEnd-1); + Inc(IArg); + end; + // recurse into right part if present + if IEnd < LastItem then + Result^.ArgList[IArg] := MakeTree(Expr, IEnd+1, LastItem); + end else + if TExprWord(Expr.Items[FirstItem]).IsFunction then + begin + // save function + Result^.ExprWord := TExprWord(Expr.Items[FirstItem]); + Result^.Oper := Result^.ExprWord.ExprFunc; + Result^.WantsFunction := true; + // parse function arguments + IEnd := FirstItem + 1; + IStart := IEnd; + brCount := 0; + if TExprWord(Expr.Items[IEnd]).ResultType = etLeftBracket then + begin + // opening bracket found, first argument expression starts at next index + Inc(brCount); + Inc(IStart); + while (IEnd < LastItem) and (brCount <> 0) do + begin + Inc(IEnd); + case TExprWord(Expr.Items[IEnd]).ResultType of + etLeftBracket: Inc(brCount); + etComma: + if brCount = 1 then + begin + // argument separation found, build tree of argument expression + Result^.ArgList[IArg] := MakeTree(Expr, IStart, IEnd-1); + Inc(IArg); + IStart := IEnd + 1; + end; + etRightBracket: Dec(brCount); + end; + end; + + // parse last argument + Result^.ArgList[IArg] := MakeTree(Expr, IStart, IEnd-1); + end; + end else + raise EParserException.Create('Operator/function missing'); +end; + +procedure TCustomExpressionParser.ParseString(AnExpression: string; DestCollection: TExprCollection); +var + isConstant: Boolean; + I, I1, I2, Len, DecSep: Integer; + W, S: string; + TempWord: TExprWord; + + procedure ReadConstant(AnExpr: string; isHex: Boolean); + begin + isConstant := true; + while (I2 <= Len) and ((AnExpr[I2] in ['0'..'9']) or + (isHex and (AnExpr[I2] in ['a'..'f', 'A'..'F']))) do + Inc(I2); + if I2 <= Len then + begin + if AnExpr[I2] = FDecimalSeparator then + begin + Inc(I2); + while (I2 <= Len) and (AnExpr[I2] in ['0'..'9']) do + Inc(I2); + end; + if (I2 <= Len) and (AnExpr[I2] = 'e') then + begin + Inc(I2); + if (I2 <= Len) and (AnExpr[I2] in ['+', '-']) then + Inc(I2); + while (I2 <= Len) and (AnExpr[I2] in ['0'..'9']) do + Inc(I2); + end; + end; + end; + + procedure ReadWord(AnExpr: string); + var + OldI2: Integer; + constChar: Char; + begin + isConstant := false; + I1 := I2; + while (I1 < Len) and (AnExpr[I1] = ' ') do + Inc(I1); + I2 := I1; + if I1 <= Len then + begin + if AnExpr[I2] = HexChar then + begin + Inc(I2); + OldI2 := I2; + ReadConstant(AnExpr, true); + if I2 = OldI2 then + begin + isConstant := false; + while (I2 <= Len) and (AnExpr[I2] in ['a'..'z', 'A'..'Z', '_', '0'..'9']) do + Inc(I2); + end; + end + else if AnExpr[I2] = FDecimalSeparator then + ReadConstant(AnExpr, false) + else + case AnExpr[I2] of + '''', '"': + begin + isConstant := true; + constChar := AnExpr[I2]; + Inc(I2); + while (I2 <= Len) and (AnExpr[I2] <> constChar) do + Inc(I2); + if I2 <= Len then + Inc(I2); + end; + 'a'..'z', 'A'..'Z', '_': + begin + while (I2 <= Len) and (AnExpr[I2] in ['a'..'z', 'A'..'Z', '_', '0'..'9']) do + Inc(I2); + end; + '>', '<': + begin + if (I2 <= Len) then + Inc(I2); + if AnExpr[I2] in ['=', '<', '>'] then + Inc(I2); + end; + '=': + begin + if (I2 <= Len) then + Inc(I2); + if AnExpr[I2] in ['<', '>', '='] then + Inc(I2); + end; + '&': + begin + if (I2 <= Len) then + Inc(I2); + if AnExpr[I2] in ['&'] then + Inc(I2); + end; + '|': + begin + if (I2 <= Len) then + Inc(I2); + if AnExpr[I2] in ['|'] then + Inc(I2); + end; + ':': + begin + if (I2 <= Len) then + Inc(I2); + if AnExpr[I2] = '=' then + Inc(I2); + end; + '!': + begin + if (I2 <= Len) then + Inc(I2); + if AnExpr[I2] = '=' then //support for != + Inc(I2); + end; + '+': + begin + Inc(I2); + if (AnExpr[I2] = '+') and FWordsList.Search(PChar('++'), I) then + Inc(I2); + end; + '-': + begin + Inc(I2); + if (AnExpr[I2] = '-') and FWordsList.Search(PChar('--'), I) then + Inc(I2); + end; + '^', '/', '\', '*', '(', ')', '%', '~', '$': + Inc(I2); + '0'..'9': + ReadConstant(AnExpr, false); + else + begin + Inc(I2); + end; + end; + end; + end; + +begin + I2 := 1; + S := Trim(AnExpression); + Len := Length(S); + repeat + ReadWord(S); + W := Trim(Copy(S, I1, I2 - I1)); + if isConstant then + begin + if W[1] = HexChar then + begin + // convert hexadecimal to decimal + W[1] := '$'; + W := IntToStr(StrToInt(W)); + end; + if (W[1] = '''') or (W[1] = '"') then + TempWord := TStringConstant.Create(W) + else begin + DecSep := Pos(FDecimalSeparator, W); + if (DecSep > 0) then + begin +{$IFDEF ENG_NUMBERS} + // we'll have to convert FDecimalSeparator into DecimalSeparator + // otherwise the OS will not understand what we mean + W[DecSep] := DefaultFormatSettings.DecimalSeparator; +{$ENDIF} + TempWord := TFloatConstant.Create(W, W) + end else begin + TempWord := TIntegerConstant.Create(StrToInt(W)); + end; + end; + DestCollection.Add(TempWord); + FConstantsList.Add(TempWord); + end + else if Length(W) > 0 then + if FWordsList.Search(PChar(W), I) then + begin + DestCollection.Add(FWordsList.Items[I]) + end else begin + // unknown variable -> fire event + HandleUnknownVariable(W); + // try to search again + if FWordsList.Search(PChar(W), I) then + begin + DestCollection.Add(FWordsList.Items[I]) + end else begin + raise EParserException.Create('Unknown variable '''+W+''' found.'); + end; + end; + until I2 > Len; +end; + +procedure TCustomExpressionParser.Check(AnExprList: TExprCollection); +var + I, J, K, L: Integer; +begin + AnExprList.Check; + with AnExprList do + begin + I := 0; + while I < Count do + begin + {----CHECK ON DOUBLE MINUS OR DOUBLE PLUS----} + if ((TExprWord(Items[I]).Name = '-') or + (TExprWord(Items[I]).Name = '+')) + and ((I = 0) or + (TExprWord(Items[I - 1]).ResultType = etComma) or + (TExprWord(Items[I - 1]).ResultType = etLeftBracket) or + (TExprWord(Items[I - 1]).IsOperator and (TExprWord(Items[I - 1]).MaxFunctionArg + = 2))) then + begin + {replace e.g. ----1 with +1} + if TExprWord(Items[I]).Name = '-' then + K := -1 + else + K := 1; + L := 1; + while (I + L < Count) and ((TExprWord(Items[I + L]).Name = '-') + or (TExprWord(Items[I + L]).Name = '+')) and ((I + L = 0) or + (TExprWord(Items[I + L - 1]).ResultType = etComma) or + (TExprWord(Items[I + L - 1]).ResultType = etLeftBracket) or + (TExprWord(Items[I + L - 1]).IsOperator and (TExprWord(Items[I + L - + 1]).MaxFunctionArg = 2))) do + begin + if TExprWord(Items[I + L]).Name = '-' then + K := -1 * K; + Inc(L); + end; + if L > 0 then + begin + Dec(L); + for J := I + 1 to Count - 1 - L do + Items[J] := Items[J + L]; + Count := Count - L; + end; + if K = -1 then + begin + if FWordsList.Search(pchar('-@'), J) then + Items[I] := FWordsList.Items[J]; + end + else if FWordsList.Search(pchar('+@'), J) then + Items[I] := FWordsList.Items[J]; + end; + {----CHECK ON DOUBLE NOT----} + if (TExprWord(Items[I]).Name = 'not') + and ((I = 0) or + (TExprWord(Items[I - 1]).ResultType = etLeftBracket) or + TExprWord(Items[I - 1]).IsOperator) then + begin + {replace e.g. not not 1 with 1} + K := -1; + L := 1; + while (I + L < Count) and (TExprWord(Items[I + L]).Name = 'not') and ((I + + L = 0) or + (TExprWord(Items[I + L - 1]).ResultType = etLeftBracket) or + TExprWord(Items[I + L - 1]).IsOperator) do + begin + K := -K; + Inc(L); + end; + if L > 0 then + begin + if K = 1 then + begin //remove all + for J := I to Count - 1 - L do + Items[J] := Items[J + L]; + Count := Count - L; + end + else + begin //keep one + Dec(L); + for J := I + 1 to Count - 1 - L do + Items[J] := Items[J + L]; + Count := Count - L; + end + end; + end; + {-----MISC CHECKS-----} + if (TExprWord(Items[I]).IsVariable) and ((I < Count - 1) and + (TExprWord(Items[I + 1]).IsVariable)) then + raise EParserException.Create('Missing operator between '''+TExprWord(Items[I]).Name+''' and '''+TExprWord(Items[I]).Name+''''); + if (TExprWord(Items[I]).ResultType = etLeftBracket) and (I >= Count - 1) then + raise EParserException.Create('Missing closing bracket'); + if (TExprWord(Items[I]).ResultType = etRightBracket) and ((I < Count - 1) and + (TExprWord(Items[I + 1]).ResultType = etLeftBracket)) then + raise EParserException.Create('Missing operator between )('); + if (TExprWord(Items[I]).ResultType = etRightBracket) and ((I < Count - 1) and + (TExprWord(Items[I + 1]).IsVariable)) then + raise EParserException.Create('Missing operator between ) and constant/variable'); + if (TExprWord(Items[I]).ResultType = etLeftBracket) and ((I > 0) and + (TExprWord(Items[I - 1]).IsVariable)) then + raise EParserException.Create('Missing operator between constant/variable and ('); + + {-----CHECK ON INTPOWER------} + if (TExprWord(Items[I]).Name = '^') and ((I < Count - 1) and + (TExprWord(Items[I + 1]).ClassType = TIntegerConstant)) then + if FWordsList.Search(PChar('^@'), J) then + Items[I] := FWordsList.Items[J]; //use the faster intPower if possible + Inc(I); + end; + end; +end; + +procedure TCustomExpressionParser.EvaluateCurrent; +var + TempRec: PExpressionRec; +begin + if FCurrentRec <> nil then + begin + // get current record + TempRec := FCurrentRec; + // execute list + repeat + with TempRec^ do + begin + // do we need to reset pointer? + if ResetDest then + Res.MemoryPos^ := Res.Memory^; + + Oper(TempRec); + + // goto next + TempRec := Next; + end; + until TempRec = nil; + end; +end; + +function TCustomExpressionParser.DefineFunction(AFunctName, AShortName, ADescription, ATypeSpec: string; + AMinFunctionArg: Integer; AResultType: TExpressionType; AFuncAddress: TExprFunc): TExprWord; +begin + Result := TFunction.Create(AFunctName, AShortName, ATypeSpec, AMinFunctionArg, AResultType, AFuncAddress, ADescription); + FWordsList.Add(Result); +end; + +function TCustomExpressionParser.DefineIntegerVariable(AVarName: string; AValue: PInteger): TExprWord; +begin + Result := TIntegerVariable.Create(AVarName, AValue); + FWordsList.Add(Result); +end; + +{$ifdef SUPPORT_INT64} + +function TCustomExpressionParser.DefineLargeIntVariable(AVarName: string; AValue: PLargeInt): TExprWord; +begin + Result := TLargeIntVariable.Create(AVarName, AValue); + FWordsList.Add(Result); +end; + +{$endif} + +function TCustomExpressionParser.DefineDateTimeVariable(AVarName: string; AValue: PDateTimeRec): TExprWord; +begin + Result := TDateTimeVariable.Create(AVarName, AValue); + FWordsList.Add(Result); +end; + +function TCustomExpressionParser.DefineBooleanVariable(AVarName: string; AValue: PBoolean): TExprWord; +begin + Result := TBooleanVariable.Create(AVarName, AValue); + FWordsList.Add(Result); +end; + +function TCustomExpressionParser.DefineFloatVariable(AVarName: string; AValue: PDouble): TExprWord; +begin + Result := TFloatVariable.Create(AVarName, AValue); + FWordsList.Add(Result); +end; + +function TCustomExpressionParser.DefineStringVariable(AVarName: string; AValue: PPChar): TExprWord; +begin + Result := TStringVariable.Create(AVarName, AValue); + FWordsList.Add(Result); +end; + +{ +procedure TCustomExpressionParser.GetGeneratedVars(AList: TList); +var + I: Integer; +begin + AList.Clear; + with FWordsList do + for I := 0 to Count - 1 do + begin + if TObject(Items[I]).ClassType = TGeneratedVariable then + AList.Add(Items[I]); + end; +end; +} + +function TCustomExpressionParser.GetResultType: TExpressionType; +begin + Result := etUnknown; + if FCurrentRec <> nil then + begin + //LAST operand should be boolean -otherwise If(,,) doesn't work + while (FLastRec^.Next <> nil) do + FLastRec := FLastRec^.Next; + if FLastRec^.ExprWord <> nil then + Result := FLastRec^.ExprWord.ResultType; + end; +end; + +function TCustomExpressionParser.MakeRec: PExpressionRec; +var + I: Integer; +begin + New(Result); + Result^.Oper := nil; + Result^.AuxData := nil; + Result^.WantsFunction := false; + for I := 0 to MaxArg - 1 do + begin + Result^.Args[I] := nil; + Result^.ArgsPos[I] := nil; + Result^.ArgsSize[I] := 0; + Result^.ArgsType[I] := etUnknown; + Result^.ArgList[I] := nil; + end; + Result^.Res := nil; + Result^.Next := nil; + Result^.ExprWord := nil; + Result^.ResetDest := false; +end; + +procedure TCustomExpressionParser.Evaluate(AnExpression: string); +begin + if Length(AnExpression) > 0 then + begin + AddExpression(AnExpression); + EvaluateCurrent; + end; +end; + +function TCustomExpressionParser.AddExpression(AnExpression: string): Integer; +begin + if Length(AnExpression) > 0 then + begin + Result := 0; + CompileExpression(AnExpression); + end else + Result := -1; + //CurrentIndex := Result; +end; + +procedure TCustomExpressionParser.ClearExpressions; +begin + DisposeList(FCurrentRec); + FCurrentRec := nil; + FLastRec := nil; +end; + +function TCustomExpressionParser.GetFunctionDescription(AFunction: string): + string; +var + S: string; + p, I: Integer; +begin + S := AFunction; + p := Pos('(', S); + if p > 0 then + S := Copy(S, 1, p - 1); + if FWordsList.Search(pchar(S), I) then + Result := TExprWord(FWordsList.Items[I]).Description + else + Result := EmptyStr; +end; + +procedure TCustomExpressionParser.GetFunctionNames(AList: TStrings); +var + I, J: Integer; + S: string; +begin + with FWordsList do + for I := 0 to Count - 1 do + with TExprWord(FWordsList.Items[I]) do + if Length(Description) > 0 then + begin + S := Name; + if MaxFunctionArg > 0 then + begin + S := S + '('; + for J := 0 to MaxFunctionArg - 2 do + S := S + ArgSeparator; + S := S + ')'; + end; + AList.Add(S); + end; +end; + + +//--Expression functions----------------------------------------------------- + +procedure FuncFloatToStr(Param: PExpressionRec); +var + width, numDigits, resWidth: Integer; + extVal: Extended; +begin + with Param^ do + begin + // get params; + numDigits := 0; + if Args[1] <> nil then + width := PInteger(Args[1])^ + else + width := 18; + if Args[2] <> nil then + numDigits := PInteger(Args[2])^; + // convert to string + Res.AssureSpace(width); + extVal := PDouble(Args[0])^; + resWidth := FloatToText(Res.MemoryPos^, extVal, {$ifndef FPC_VERSION}fvExtended,{$endif} ffFixed, 18, numDigits); + // always use dot as decimal separator + if numDigits > 0 then + Res.MemoryPos^[resWidth-numDigits-1] := '.'; + // result width smaller than requested width? -> add space to compensate + if (Args[1] <> nil) and (resWidth < width) then + begin + // move string so that it's right-aligned + Move(Res.MemoryPos^^, (Res.MemoryPos^)[width-resWidth], resWidth); + // fill gap with spaces + FillChar(Res.MemoryPos^^, width-resWidth, ' '); + // resWidth has been padded, update + resWidth := width; + end else if resWidth > width then begin + // result width more than requested width, cut + resWidth := width; + end; + // advance pointer + Inc(Res.MemoryPos^, resWidth); + // null-terminate + Res.MemoryPos^^ := #0; + end; +end; + +procedure FuncIntToStr_Gen(Param: PExpressionRec; Val: {$ifdef SUPPORT_INT64}Int64{$else}Integer{$endif}); +var + width: Integer; +begin + with Param^ do + begin + // width specified? + if Args[1] <> nil then + begin + // convert to string + width := PInteger(Args[1])^; +{$ifdef SUPPORT_INT64} + GetStrFromInt64_Width +{$else} + GetStrFromInt_Width +{$endif} + (Val, width, Res.MemoryPos^, #32); + // advance pointer + Inc(Res.MemoryPos^, width); + // need to add decimal? + if Args[2] <> nil then + begin + // get number of digits + width := PInteger(Args[2])^; + // add decimal dot + Res.MemoryPos^^ := '.'; + Inc(Res.MemoryPos^); + // add zeroes + FillChar(Res.MemoryPos^^, width, '0'); + // go to end + Inc(Res.MemoryPos^, width); + end; + end else begin + // convert to string + width := +{$ifdef SUPPORT_INT64} + GetStrFromInt64 +{$else} + GetStrFromInt +{$endif} + (Val, Res.MemoryPos^); + // advance pointer + Inc(Param^.Res.MemoryPos^, width); + end; + // null-terminate + Res.MemoryPos^^ := #0; + end; +end; + +procedure FuncIntToStr(Param: PExpressionRec); +begin + FuncIntToStr_Gen(Param, PInteger(Param^.Args[0])^); +end; + +{$ifdef SUPPORT_INT64} + +procedure FuncInt64ToStr(Param: PExpressionRec); +begin + FuncIntToStr_Gen(Param, PInt64(Param^.Args[0])^); +end; + +{$endif} + +procedure FuncDateToStr(Param: PExpressionRec); +var + TempStr: string; +begin + with Param^ do + begin + // create in temporary string + DateTimeToString(TempStr, 'yyyymmdd', PDateTimeRec(Args[0])^.DateTime); + // copy to buffer + Res.Append(PChar(TempStr), Length(TempStr)); + end; +end; + +procedure FuncSubString(Param: PExpressionRec); +var + srcLen, index, count: Integer; +begin + with Param^ do + begin + srcLen := StrLen(Args[0]); + index := PInteger(Args[1])^ - 1; + if Args[2] <> nil then + begin + count := PInteger(Args[2])^; + if index + count > srcLen then + count := srcLen - index; + end else + count := srcLen - index; + Res.Append(Args[0]+index, count) + end; +end; + +procedure FuncUppercase(Param: PExpressionRec); +var + dest: PChar; +begin + with Param^ do + begin + // first copy + dest := (Res.MemoryPos)^; + Res.Append(Args[0], StrLen(Args[0])); + // make uppercase + AnsiStrUpper(dest); + end; +end; + +procedure FuncLowercase(Param: PExpressionRec); +var + dest: PChar; +begin + with Param^ do + begin + // first copy + dest := (Res.MemoryPos)^; + Res.Append(Args[0], StrLen(Args[0])); + // make lowercase + AnsiStrLower(dest); + end; +end; + +procedure FuncAdd_F_FF(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ + PDouble(Args[1])^; +end; + +procedure FuncAdd_F_FI(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ + PInteger(Args[1])^; +end; + +procedure FuncAdd_F_II(Param: PExpressionRec); +begin + with Param^ do + PInteger(Res.MemoryPos^)^ := PInteger(Args[0])^ + PInteger(Args[1])^; +end; + +procedure FuncAdd_F_IF(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PInteger(Args[0])^ + PDouble(Args[1])^; +end; + +{$ifdef SUPPORT_INT64} + +procedure FuncAdd_F_FL(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ + PInt64(Args[1])^; +end; + +procedure FuncAdd_F_IL(Param: PExpressionRec); +begin + with Param^ do + PInt64(Res.MemoryPos^)^ := PInteger(Args[0])^ + PInt64(Args[1])^; +end; + +procedure FuncAdd_F_LL(Param: PExpressionRec); +begin + with Param^ do + PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ + PInt64(Args[1])^; +end; + +procedure FuncAdd_F_LF(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PInt64(Args[0])^ + PDouble(Args[1])^; +end; + +procedure FuncAdd_F_LI(Param: PExpressionRec); +begin + with Param^ do + PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ + PInteger(Args[1])^; +end; + +{$endif} + +procedure FuncSub_F_FF(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ - PDouble(Args[1])^; +end; + +procedure FuncSub_F_FI(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ - PInteger(Args[1])^; +end; + +procedure FuncSub_F_II(Param: PExpressionRec); +begin + with Param^ do + PInteger(Res.MemoryPos^)^ := PInteger(Args[0])^ - PInteger(Args[1])^; +end; + +procedure FuncSub_F_IF(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PInteger(Args[0])^ - PDouble(Args[1])^; +end; + +{$ifdef SUPPORT_INT64} + +procedure FuncSub_F_FL(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ - PInt64(Args[1])^; +end; + +procedure FuncSub_F_IL(Param: PExpressionRec); +begin + with Param^ do + PInt64(Res.MemoryPos^)^ := PInteger(Args[0])^ - PInt64(Args[1])^; +end; + +procedure FuncSub_F_LL(Param: PExpressionRec); +begin + with Param^ do + PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ - PInt64(Args[1])^; +end; + +procedure FuncSub_F_LF(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PInt64(Args[0])^ - PDouble(Args[1])^; +end; + +procedure FuncSub_F_LI(Param: PExpressionRec); +begin + with Param^ do + PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ - PInteger(Args[1])^; +end; + +{$endif} + +procedure FuncMul_F_FF(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ * PDouble(Args[1])^; +end; + +procedure FuncMul_F_FI(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ * PInteger(Args[1])^; +end; + +procedure FuncMul_F_II(Param: PExpressionRec); +begin + with Param^ do + PInteger(Res.MemoryPos^)^ := PInteger(Args[0])^ * PInteger(Args[1])^; +end; + +procedure FuncMul_F_IF(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PInteger(Args[0])^ * PDouble(Args[1])^; +end; + +{$ifdef SUPPORT_INT64} + +procedure FuncMul_F_FL(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ * PInt64(Args[1])^; +end; + +procedure FuncMul_F_IL(Param: PExpressionRec); +begin + with Param^ do + PInt64(Res.MemoryPos^)^ := PInteger(Args[0])^ * PInt64(Args[1])^; +end; + +procedure FuncMul_F_LL(Param: PExpressionRec); +begin + with Param^ do + PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ * PInt64(Args[1])^; +end; + +procedure FuncMul_F_LF(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PInt64(Args[0])^ * PDouble(Args[1])^; +end; + +procedure FuncMul_F_LI(Param: PExpressionRec); +begin + with Param^ do + PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ * PInteger(Args[1])^; +end; + +{$endif} + +procedure FuncDiv_F_FF(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ / PDouble(Args[1])^; +end; + +procedure FuncDiv_F_FI(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ / PInteger(Args[1])^; +end; + +procedure FuncDiv_F_II(Param: PExpressionRec); +begin + with Param^ do + PInteger(Res.MemoryPos^)^ := PInteger(Args[0])^ div PInteger(Args[1])^; +end; + +procedure FuncDiv_F_IF(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PInteger(Args[0])^ / PDouble(Args[1])^; +end; + +{$ifdef SUPPORT_INT64} + +procedure FuncDiv_F_FL(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ / PInt64(Args[1])^; +end; + +procedure FuncDiv_F_IL(Param: PExpressionRec); +begin + with Param^ do + PInt64(Res.MemoryPos^)^ := PInteger(Args[0])^ div PInt64(Args[1])^; +end; + +procedure FuncDiv_F_LL(Param: PExpressionRec); +begin + with Param^ do + PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ div PInt64(Args[1])^; +end; + +procedure FuncDiv_F_LF(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PInt64(Args[0])^ / PDouble(Args[1])^; +end; + +procedure FuncDiv_F_LI(Param: PExpressionRec); +begin + with Param^ do + PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ div PInteger(Args[1])^; +end; + +{$endif} + +procedure FuncStrI_EQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(AnsiStrIComp(Args[0], Args[1]) = 0); +end; + +procedure FuncStrIP_EQ(Param: PExpressionRec); +var + arg0len, arg1len: integer; + match: boolean; + str0, str1: string; +begin + with Param^ do + begin + arg1len := StrLen(Args[1]); + if Args[1][0] = '*' then + begin + if Args[1][arg1len-1] = '*' then + begin + str0 := AnsiStrUpper(Args[0]); + str1 := AnsiStrUpper(Args[1]+1); + setlength(str1, arg1len-2); + match := AnsiPos(str1, str0) <> 0; + end else begin + arg0len := StrLen(Args[0]); + // at least length without asterisk + match := arg0len >= arg1len - 1; + if match then + match := AnsiStrLIComp(Args[0]+(arg0len-arg1len+1), Args[1]+1, arg1len-1) = 0; + end; + end else + if Args[1][arg1len-1] = '*' then + begin + arg0len := StrLen(Args[0]); + match := arg0len >= arg1len - 1; + if match then + match := AnsiStrLIComp(Args[0], Args[1], arg1len-1) = 0; + end else begin + match := AnsiStrIComp(Args[0], Args[1]) = 0; + end; + Res.MemoryPos^^ := Char(match); + end; +end; + +procedure FuncStrI_NEQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(AnsiStrIComp(Args[0], Args[1]) <> 0); +end; + +procedure FuncStrI_LT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(AnsiStrIComp(Args[0], Args[1]) < 0); +end; + +procedure FuncStrI_GT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(AnsiStrIComp(Args[0], Args[1]) > 0); +end; + +procedure FuncStrI_LTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(AnsiStrIComp(Args[0], Args[1]) <= 0); +end; + +procedure FuncStrI_GTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(AnsiStrIComp(Args[0], Args[1]) >= 0); +end; + +procedure FuncStrP_EQ(Param: PExpressionRec); +var + arg0len, arg1len: integer; + match: boolean; +begin + with Param^ do + begin + arg1len := StrLen(Args[1]); + if Args[1][0] = '*' then + begin + if Args[1][arg1len-1] = '*' then + begin + Args[1][arg1len-1] := #0; + match := AnsiStrPos(Args[0], Args[1]+1) <> nil; + Args[1][arg1len-1] := '*'; + end else begin + arg0len := StrLen(Args[0]); + // at least length without asterisk + match := arg0len >= arg1len - 1; + if match then + match := AnsiStrLComp(Args[0]+(arg0len-arg1len+1), Args[1]+1, arg1len-1) = 0; + end; + end else + if Args[1][arg1len-1] = '*' then + begin + arg0len := StrLen(Args[0]); + match := arg0len >= arg1len - 1; + if match then + match := AnsiStrLComp(Args[0], Args[1], arg1len-1) = 0; + end else begin + match := AnsiStrComp(Args[0], Args[1]) = 0; + end; + Res.MemoryPos^^ := Char(match); + end; +end; + +procedure FuncStr_EQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(AnsiStrComp(Args[0], Args[1]) = 0); +end; + +procedure FuncStr_NEQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(AnsiStrComp(Args[0], Args[1]) <> 0); +end; + +procedure FuncStr_LT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(AnsiStrComp(Args[0], Args[1]) < 0); +end; + +procedure FuncStr_GT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(AnsiStrComp(Args[0], Args[1]) > 0); +end; + +procedure FuncStr_LTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(AnsiStrComp(Args[0], Args[1]) <= 0); +end; + +procedure FuncStr_GTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(AnsiStrComp(Args[0], Args[1]) >= 0); +end; + +procedure Func_FF_EQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ = PDouble(Args[1])^); +end; + +procedure Func_FF_NEQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ <> PDouble(Args[1])^); +end; + +procedure Func_FF_LT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ < PDouble(Args[1])^); +end; + +procedure Func_FF_GT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ > PDouble(Args[1])^); +end; + +procedure Func_FF_LTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ <= PDouble(Args[1])^); +end; + +procedure Func_FF_GTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ >= PDouble(Args[1])^); +end; + +procedure Func_FI_EQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ = PInteger(Args[1])^); +end; + +procedure Func_FI_NEQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ <> PInteger(Args[1])^); +end; + +procedure Func_FI_LT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ < PInteger(Args[1])^); +end; + +procedure Func_FI_GT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ > PInteger(Args[1])^); +end; + +procedure Func_FI_LTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ <= PInteger(Args[1])^); +end; + +procedure Func_FI_GTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ >= PInteger(Args[1])^); +end; + +procedure Func_II_EQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ = PInteger(Args[1])^); +end; + +procedure Func_II_NEQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ <> PInteger(Args[1])^); +end; + +procedure Func_II_LT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ < PInteger(Args[1])^); +end; + +procedure Func_II_GT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ > PInteger(Args[1])^); +end; + +procedure Func_II_LTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ <= PInteger(Args[1])^); +end; + +procedure Func_II_GTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ >= PInteger(Args[1])^); +end; + +procedure Func_IF_EQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ = PDouble(Args[1])^); +end; + +procedure Func_IF_NEQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ <> PDouble(Args[1])^); +end; + +procedure Func_IF_LT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ < PDouble(Args[1])^); +end; + +procedure Func_IF_GT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ > PDouble(Args[1])^); +end; + +procedure Func_IF_LTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ <= PDouble(Args[1])^); +end; + +procedure Func_IF_GTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ >= PDouble(Args[1])^); +end; + +{$ifdef SUPPORT_INT64} + +procedure Func_LL_EQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ = PInt64(Args[1])^); +end; + +procedure Func_LL_NEQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ <> PInt64(Args[1])^); +end; + +procedure Func_LL_LT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ < PInt64(Args[1])^); +end; + +procedure Func_LL_GT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ > PInt64(Args[1])^); +end; + +procedure Func_LL_LTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ <= PInt64(Args[1])^); +end; + +procedure Func_LL_GTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ >= PInt64(Args[1])^); +end; + +procedure Func_LF_EQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ = PDouble(Args[1])^); +end; + +procedure Func_LF_NEQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ <> PDouble(Args[1])^); +end; + +procedure Func_LF_LT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ < PDouble(Args[1])^); +end; + +procedure Func_LF_GT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ > PDouble(Args[1])^); +end; + +procedure Func_LF_LTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ <= PDouble(Args[1])^); +end; + +procedure Func_LF_GTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ >= PDouble(Args[1])^); +end; + +procedure Func_FL_EQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ = PInt64(Args[1])^); +end; + +procedure Func_FL_NEQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ <> PInt64(Args[1])^); +end; + +procedure Func_FL_LT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ < PInt64(Args[1])^); +end; + +procedure Func_FL_GT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ > PInt64(Args[1])^); +end; + +procedure Func_FL_LTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ <= PInt64(Args[1])^); +end; + +procedure Func_FL_GTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PDouble(Args[0])^ >= PInt64(Args[1])^); +end; + +procedure Func_LI_EQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ = PInteger(Args[1])^); +end; + +procedure Func_LI_NEQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ <> PInteger(Args[1])^); +end; + +procedure Func_LI_LT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ < PInteger(Args[1])^); +end; + +procedure Func_LI_GT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ > PInteger(Args[1])^); +end; + +procedure Func_LI_LTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ <= PInteger(Args[1])^); +end; + +procedure Func_LI_GTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInt64(Args[0])^ >= PInteger(Args[1])^); +end; + +procedure Func_IL_EQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ = PInt64(Args[1])^); +end; + +procedure Func_IL_NEQ(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ <> PInt64(Args[1])^); +end; + +procedure Func_IL_LT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ < PInt64(Args[1])^); +end; + +procedure Func_IL_GT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ > PInt64(Args[1])^); +end; + +procedure Func_IL_LTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ <= PInt64(Args[1])^); +end; + +procedure Func_IL_GTE(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(PInteger(Args[0])^ >= PInt64(Args[1])^); +end; + +{$endif} + +procedure Func_AND(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(Boolean(Args[0]^) and Boolean(Args[1]^)); +end; + +procedure Func_OR(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(Boolean(Args[0]^) or Boolean(Args[1]^)); +end; + +procedure Func_NOT(Param: PExpressionRec); +begin + with Param^ do + Res.MemoryPos^^ := Char(not Boolean(Args[0]^)); +end; + +initialization + + DbfWordsGeneralList := TExpressList.Create; + DbfWordsInsensGeneralList := TExpressList.Create; + DbfWordsInsensNoPartialList := TExpressList.Create; + DbfWordsInsensPartialList := TExpressList.Create; + DbfWordsSensGeneralList := TExpressList.Create; + DbfWordsSensNoPartialList := TExpressList.Create; + DbfWordsSensPartialList := TExpressList.Create; + + with DbfWordsGeneralList do + begin + // basic function functionality + Add(TLeftBracket.Create('(', nil)); + Add(TRightBracket.Create(')', nil)); + Add(TComma.Create(',', nil)); + + // operators - name, param types, result type, func addr, precedence + Add(TFunction.CreateOper('+', 'SS', etString, nil, 40)); + Add(TFunction.CreateOper('+', 'FF', etFloat, FuncAdd_F_FF, 40)); + Add(TFunction.CreateOper('+', 'FI', etFloat, FuncAdd_F_FI, 40)); + Add(TFunction.CreateOper('+', 'IF', etFloat, FuncAdd_F_IF, 40)); + Add(TFunction.CreateOper('+', 'II', etInteger, FuncAdd_F_II, 40)); +{$ifdef SUPPORT_INT64} + Add(TFunction.CreateOper('+', 'FL', etFloat, FuncAdd_F_FL, 40)); + Add(TFunction.CreateOper('+', 'IL', etLargeInt, FuncAdd_F_IL, 40)); + Add(TFunction.CreateOper('+', 'LF', etFloat, FuncAdd_F_LF, 40)); + Add(TFunction.CreateOper('+', 'LL', etLargeInt, FuncAdd_F_LI, 40)); + Add(TFunction.CreateOper('+', 'LI', etLargeInt, FuncAdd_F_LL, 40)); +{$endif} + Add(TFunction.CreateOper('-', 'FF', etFloat, FuncSub_F_FF, 40)); + Add(TFunction.CreateOper('-', 'FI', etFloat, FuncSub_F_FI, 40)); + Add(TFunction.CreateOper('-', 'IF', etFloat, FuncSub_F_IF, 40)); + Add(TFunction.CreateOper('-', 'II', etInteger, FuncSub_F_II, 40)); +{$ifdef SUPPORT_INT64} + Add(TFunction.CreateOper('-', 'FL', etFloat, FuncSub_F_FL, 40)); + Add(TFunction.CreateOper('-', 'IL', etLargeInt, FuncSub_F_IL, 40)); + Add(TFunction.CreateOper('-', 'LF', etFloat, FuncSub_F_LF, 40)); + Add(TFunction.CreateOper('-', 'LL', etLargeInt, FuncSub_F_LI, 40)); + Add(TFunction.CreateOper('-', 'LI', etLargeInt, FuncSub_F_LL, 40)); +{$endif} + Add(TFunction.CreateOper('*', 'FF', etFloat, FuncMul_F_FF, 40)); + Add(TFunction.CreateOper('*', 'FI', etFloat, FuncMul_F_FI, 40)); + Add(TFunction.CreateOper('*', 'IF', etFloat, FuncMul_F_IF, 40)); + Add(TFunction.CreateOper('*', 'II', etInteger, FuncMul_F_II, 40)); +{$ifdef SUPPORT_INT64} + Add(TFunction.CreateOper('*', 'FL', etFloat, FuncMul_F_FL, 40)); + Add(TFunction.CreateOper('*', 'IL', etLargeInt, FuncMul_F_IL, 40)); + Add(TFunction.CreateOper('*', 'LF', etFloat, FuncMul_F_LF, 40)); + Add(TFunction.CreateOper('*', 'LL', etLargeInt, FuncMul_F_LI, 40)); + Add(TFunction.CreateOper('*', 'LI', etLargeInt, FuncMul_F_LL, 40)); +{$endif} + Add(TFunction.CreateOper('/', 'FF', etFloat, FuncDiv_F_FF, 40)); + Add(TFunction.CreateOper('/', 'FI', etFloat, FuncDiv_F_FI, 40)); + Add(TFunction.CreateOper('/', 'IF', etFloat, FuncDiv_F_IF, 40)); + Add(TFunction.CreateOper('/', 'II', etInteger, FuncDiv_F_II, 40)); +{$ifdef SUPPORT_INT64} + Add(TFunction.CreateOper('/', 'FL', etFloat, FuncDiv_F_FL, 40)); + Add(TFunction.CreateOper('/', 'IL', etLargeInt, FuncDiv_F_IL, 40)); + Add(TFunction.CreateOper('/', 'LF', etFloat, FuncDiv_F_LF, 40)); + Add(TFunction.CreateOper('/', 'LL', etLargeInt, FuncDiv_F_LI, 40)); + Add(TFunction.CreateOper('/', 'LI', etLargeInt, FuncDiv_F_LL, 40)); +{$endif} + + Add(TFunction.CreateOper('=', 'FF', etBoolean, Func_FF_EQ , 80)); + Add(TFunction.CreateOper('<', 'FF', etBoolean, Func_FF_LT , 80)); + Add(TFunction.CreateOper('>', 'FF', etBoolean, Func_FF_GT , 80)); + Add(TFunction.CreateOper('<=','FF', etBoolean, Func_FF_LTE, 80)); + Add(TFunction.CreateOper('>=','FF', etBoolean, Func_FF_GTE, 80)); + Add(TFunction.CreateOper('<>','FF', etBoolean, Func_FF_NEQ, 80)); + Add(TFunction.CreateOper('=', 'FI', etBoolean, Func_FI_EQ , 80)); + Add(TFunction.CreateOper('<', 'FI', etBoolean, Func_FI_LT , 80)); + Add(TFunction.CreateOper('>', 'FI', etBoolean, Func_FI_GT , 80)); + Add(TFunction.CreateOper('<=','FI', etBoolean, Func_FI_LTE, 80)); + Add(TFunction.CreateOper('>=','FI', etBoolean, Func_FI_GTE, 80)); + Add(TFunction.CreateOper('<>','FI', etBoolean, Func_FI_NEQ, 80)); + Add(TFunction.CreateOper('=', 'II', etBoolean, Func_II_EQ , 80)); + Add(TFunction.CreateOper('<', 'II', etBoolean, Func_II_LT , 80)); + Add(TFunction.CreateOper('>', 'II', etBoolean, Func_II_GT , 80)); + Add(TFunction.CreateOper('<=','II', etBoolean, Func_II_LTE, 80)); + Add(TFunction.CreateOper('>=','II', etBoolean, Func_II_GTE, 80)); + Add(TFunction.CreateOper('<>','II', etBoolean, Func_II_NEQ, 80)); + Add(TFunction.CreateOper('=', 'IF', etBoolean, Func_IF_EQ , 80)); + Add(TFunction.CreateOper('<', 'IF', etBoolean, Func_IF_LT , 80)); + Add(TFunction.CreateOper('>', 'IF', etBoolean, Func_IF_GT , 80)); + Add(TFunction.CreateOper('<=','IF', etBoolean, Func_IF_LTE, 80)); + Add(TFunction.CreateOper('>=','IF', etBoolean, Func_IF_GTE, 80)); + Add(TFunction.CreateOper('<>','IF', etBoolean, Func_IF_NEQ, 80)); +{$ifdef SUPPORT_INT64} + Add(TFunction.CreateOper('=', 'LL', etBoolean, Func_LL_EQ , 80)); + Add(TFunction.CreateOper('<', 'LL', etBoolean, Func_LL_LT , 80)); + Add(TFunction.CreateOper('>', 'LL', etBoolean, Func_LL_GT , 80)); + Add(TFunction.CreateOper('<=','LL', etBoolean, Func_LL_LTE, 80)); + Add(TFunction.CreateOper('>=','LL', etBoolean, Func_LL_GTE, 80)); + Add(TFunction.CreateOper('<>','LL', etBoolean, Func_LL_NEQ, 80)); + Add(TFunction.CreateOper('=', 'LF', etBoolean, Func_LF_EQ , 80)); + Add(TFunction.CreateOper('<', 'LF', etBoolean, Func_LF_LT , 80)); + Add(TFunction.CreateOper('>', 'LF', etBoolean, Func_LF_GT , 80)); + Add(TFunction.CreateOper('<=','LF', etBoolean, Func_LF_LTE, 80)); + Add(TFunction.CreateOper('>=','LF', etBoolean, Func_LF_GTE, 80)); + Add(TFunction.CreateOper('<>','FI', etBoolean, Func_LF_NEQ, 80)); + Add(TFunction.CreateOper('=', 'LI', etBoolean, Func_LI_EQ , 80)); + Add(TFunction.CreateOper('<', 'LI', etBoolean, Func_LI_LT , 80)); + Add(TFunction.CreateOper('>', 'LI', etBoolean, Func_LI_GT , 80)); + Add(TFunction.CreateOper('<=','LI', etBoolean, Func_LI_LTE, 80)); + Add(TFunction.CreateOper('>=','LI', etBoolean, Func_LI_GTE, 80)); + Add(TFunction.CreateOper('<>','LI', etBoolean, Func_LI_NEQ, 80)); + Add(TFunction.CreateOper('=', 'FL', etBoolean, Func_FL_EQ , 80)); + Add(TFunction.CreateOper('<', 'FL', etBoolean, Func_FL_LT , 80)); + Add(TFunction.CreateOper('>', 'FL', etBoolean, Func_FL_GT , 80)); + Add(TFunction.CreateOper('<=','FL', etBoolean, Func_FL_LTE, 80)); + Add(TFunction.CreateOper('>=','FL', etBoolean, Func_FL_GTE, 80)); + Add(TFunction.CreateOper('<>','FL', etBoolean, Func_FL_NEQ, 80)); + Add(TFunction.CreateOper('=', 'IL', etBoolean, Func_IL_EQ , 80)); + Add(TFunction.CreateOper('<', 'IL', etBoolean, Func_IL_LT , 80)); + Add(TFunction.CreateOper('>', 'IL', etBoolean, Func_IL_GT , 80)); + Add(TFunction.CreateOper('<=','IL', etBoolean, Func_IL_LTE, 80)); + Add(TFunction.CreateOper('>=','IL', etBoolean, Func_IL_GTE, 80)); + Add(TFunction.CreateOper('<>','IL', etBoolean, Func_IL_NEQ, 80)); +{$endif} + + Add(TFunction.CreateOper('NOT', 'B', etBoolean, Func_NOT, 85)); + Add(TFunction.CreateOper('AND', 'BB', etBoolean, Func_AND, 90)); + Add(TFunction.CreateOper('OR', 'BB', etBoolean, Func_OR, 100)); + + // Functions - name, description, param types, min params, result type, Func addr + Add(TFunction.Create('STR', '', 'FII', 1, etString, FuncFloatToStr, '')); + Add(TFunction.Create('STR', '', 'III', 1, etString, FuncIntToStr, '')); + {$ifdef SUPPORT_INT64} + Add(TFunction.Create('STR', '', 'LII', 1, etString, FuncInt64ToStr, '')); + {$endif} + Add(TFunction.Create('DTOS', '', 'D', 1, etString, FuncDateToStr, '')); + Add(TFunction.Create('SUBSTR', 'SUBS', 'SII', 3, etString, FuncSubString, '')); + Add(TFunction.Create('UPPERCASE', 'UPPER', 'S', 1, etString, FuncUppercase, '')); + Add(TFunction.Create('LOWERCASE', 'LOWER', 'S', 1, etString, FuncLowercase, '')); + end; + + with DbfWordsInsensGeneralList do + begin + Add(TFunction.CreateOper('<', 'SS', etBoolean, FuncStrI_LT , 80)); + Add(TFunction.CreateOper('>', 'SS', etBoolean, FuncStrI_GT , 80)); + Add(TFunction.CreateOper('<=','SS', etBoolean, FuncStrI_LTE, 80)); + Add(TFunction.CreateOper('>=','SS', etBoolean, FuncStrI_GTE, 80)); + Add(TFunction.CreateOper('<>','SS', etBoolean, FuncStrI_NEQ, 80)); + end; + + with DbfWordsInsensNoPartialList do + Add(TFunction.CreateOper('=', 'SS', etBoolean, FuncStrI_EQ , 80)); + + with DbfWordsInsensPartialList do + Add(TFunction.CreateOper('=', 'SS', etBoolean, FuncStrIP_EQ, 80)); + + with DbfWordsSensGeneralList do + begin + Add(TFunction.CreateOper('<', 'SS', etBoolean, FuncStr_LT , 80)); + Add(TFunction.CreateOper('>', 'SS', etBoolean, FuncStr_GT , 80)); + Add(TFunction.CreateOper('<=','SS', etBoolean, FuncStr_LTE, 80)); + Add(TFunction.CreateOper('>=','SS', etBoolean, FuncStr_GTE, 80)); + Add(TFunction.CreateOper('<>','SS', etBoolean, FuncStr_NEQ, 80)); + end; + + with DbfWordsSensNoPartialList do + Add(TFunction.CreateOper('=', 'SS', etBoolean, FuncStr_EQ , 80)); + + with DbfWordsSensPartialList do + Add(TFunction.CreateOper('=', 'SS', etBoolean, FuncStrP_EQ , 80)); + +finalization + + DbfWordsGeneralList.Free; + DbfWordsInsensGeneralList.Free; + DbfWordsInsensNoPartialList.Free; + DbfWordsInsensPartialList.Free; + DbfWordsSensGeneralList.Free; + DbfWordsSensNoPartialList.Free; + DbfWordsSensPartialList.Free; +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/mdbf_prsdef.pas b/mseide-msegui/lib/common/fpccompatibility/mdbf_prsdef.pas new file mode 100644 index 0000000..050f38b --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/mdbf_prsdef.pas @@ -0,0 +1,1053 @@ +unit mdbf_prsdef; + +// Modified 2013 by Martin Schreiber + +interface + +{$I dbf_common.inc} + +uses + SysUtils, + classes,mclasses, + mdb, + mdbf_prssupp; + +const + MaxArg = 6; + ArgAllocSize = 32; + +type + TExpressionType = (etInteger, etString, etBoolean, etLargeInt, etFloat, etDateTime, + etLeftBracket, etRightBracket, etComma, etUnknown); + + EParserException = class(Exception); + PExpressionRec = ^TExpressionRec; + PDynamicType = ^TDynamicType; + PDateTimeRec = ^TDateTimeRec; +{$ifdef SUPPORT_INT64} + PLargeInt = ^Int64; +{$endif} + + TExprWord = class; + + TExprFunc = procedure(Expr: PExpressionRec); + +//----- + + TDynamicType = class(TObject) + private + FMemory: PPChar; + FMemoryPos: PPChar; + FSize: PInteger; + public + constructor Create(DestMem, DestPos: PPChar; ASize: PInteger); + + procedure AssureSpace(ASize: Integer); + procedure Resize(NewSize: Integer; Exact: Boolean); + procedure Rewind; + procedure Append(Source: PChar; Length: Integer); + procedure AppendInteger(Source: Integer); + + property Memory: PPChar read FMemory; + property MemoryPos: PPChar read FMemoryPos; + property Size: PInteger read FSize; + end; + + TExpressionRec = record + //used both as linked tree and linked list for maximum evaluation efficiency + Oper: TExprFunc; + Next: PExpressionRec; + Res: TDynamicType; + ExprWord: TExprWord; + AuxData: pointer; + ResetDest: boolean; + WantsFunction: boolean; + Args: array[0..MaxArg-1] of PChar; + ArgsPos: array[0..MaxArg-1] of PChar; + ArgsSize: array[0..MaxArg-1] of Integer; + ArgsType: array[0..MaxArg-1] of TExpressionType; + ArgList: array[0..MaxArg-1] of PExpressionRec; + end; + + TExprCollection = class(TNoOwnerCollection) + public + procedure Check; + procedure EraseExtraBrackets; + end; + + TExprWordRec = record + Name: PChar; + ShortName: PChar; + IsOperator: Boolean; + IsVariable: Boolean; + IsFunction: Boolean; + NeedsCopy: Boolean; + FixedLen: Boolean; + CanVary: Boolean; + ResultType: TExpressionType; + MinArg: Integer; + MaxArg: Integer; + TypeSpec: PChar; + Description: PChar; + ExprFunc: TExprFunc; + end; + + TExprWord = class(TObject) + private + FName: string; + FExprFunc: TExprFunc; + protected + FRefCount: Cardinal; + + function GetIsOperator: Boolean; virtual; + function GetIsVariable: Boolean; + function GetNeedsCopy: Boolean; + function GetFixedLen: Integer; virtual; + function GetCanVary: Boolean; virtual; + function GetResultType: TExpressionType; virtual; + function GetMinFunctionArg: Integer; virtual; + function GetMaxFunctionArg: Integer; virtual; + function GetDescription: string; virtual; + function GetTypeSpec: string; virtual; + function GetShortName: string; virtual; + procedure SetFixedLen(NewLen: integer); virtual; + public + constructor Create(AName: string; AExprFunc: TExprFunc); + + function LenAsPointer: PInteger; virtual; + function AsPointer: PChar; virtual; + function IsFunction: Boolean; virtual; + + property ExprFunc: TExprFunc read FExprFunc; + property IsOperator: Boolean read GetIsOperator; + property CanVary: Boolean read GetCanVary; + property IsVariable: Boolean read GetIsVariable; + property NeedsCopy: Boolean read GetNeedsCopy; + property FixedLen: Integer read GetFixedLen write SetFixedLen; + property ResultType: TExpressionType read GetResultType; + property MinFunctionArg: Integer read GetMinFunctionArg; + property MaxFunctionArg: Integer read GetMaxFunctionArg; + property Name: string read FName; + property ShortName: string read GetShortName; + property Description: string read GetDescription; + property TypeSpec: string read GetTypeSpec; + end; + + TExpressShortList = class(TSortedCollection) + public + function KeyOf(Item: Pointer): Pointer; override; + function Compare(Key1, Key2: Pointer): Integer; override; + procedure FreeItem(Item: Pointer); override; + end; + + TExpressList = class(TSortedCollection) + private + FShortList: TExpressShortList; + public + constructor Create; + destructor Destroy; override; + procedure Add(Item: Pointer); override; + function KeyOf(Item: Pointer): Pointer; override; + function Compare(Key1, Key2: Pointer): Integer; override; + function Search(Key: Pointer; var Index: Integer): Boolean; override; + procedure FreeItem(Item: Pointer); override; + end; + + TConstant = class(TExprWord) + private + FResultType: TExpressionType; + protected + function GetResultType: TExpressionType; override; + public + constructor Create(AName: string; AVarType: TExpressionType; AExprFunc: TExprFunc); + end; + + TFloatConstant = class(TConstant) + private + FValue: Double; + public + // not overloaded to support older Delphi versions + constructor Create(AName: string; AValue: string); + constructor CreateAsDouble(AName: string; AValue: Double); + + function AsPointer: PChar; override; + + property Value: Double read FValue write FValue; + end; + + TUserConstant = class(TFloatConstant) + private + FDescription: string; + protected + function GetDescription: string; override; + public + constructor CreateAsDouble(AName, Descr: string; AValue: Double); + end; + + TStringConstant = class(TConstant) + private + FValue: string; + public + constructor Create(AValue: string); + + function AsPointer: PChar; override; + end; + + TIntegerConstant = class(TConstant) + private + FValue: Integer; + public + constructor Create(AValue: Integer); + + function AsPointer: PChar; override; + end; + + TBooleanConstant = class(TConstant) + private + FValue: Boolean; + public + // not overloaded to support older Delphi versions + constructor Create(AName: string; AValue: Boolean); + + function AsPointer: PChar; override; + + property Value: Boolean read FValue write FValue; + end; + + TVariable = class(TExprWord) + private + FResultType: TExpressionType; + protected + function GetCanVary: Boolean; override; + function GetResultType: TExpressionType; override; + public + constructor Create(AName: string; AVarType: TExpressionType; AExprFunc: TExprFunc); + end; + + TFloatVariable = class(TVariable) + private + FValue: PDouble; + public + constructor Create(AName: string; AValue: PDouble); + + function AsPointer: PChar; override; + end; + + TStringVariable = class(TVariable) + private + FValue: PPChar; + FFixedLen: Integer; + protected + function GetFixedLen: Integer; override; + procedure SetFixedLen(NewLen: integer); override; + public + constructor Create(AName: string; AValue: PPChar); + + function LenAsPointer: PInteger; override; + function AsPointer: PChar; override; + + property FixedLen: Integer read FFixedLen; + end; + + TDateTimeVariable = class(TVariable) + private + FValue: PDateTimeRec; + public + constructor Create(AName: string; AValue: PDateTimeRec); + + function AsPointer: PChar; override; + end; + + TIntegerVariable = class(TVariable) + private + FValue: PInteger; + public + constructor Create(AName: string; AValue: PInteger); + + function AsPointer: PChar; override; + end; + +{$ifdef SUPPORT_INT64} + + TLargeIntVariable = class(TVariable) + private + FValue: PLargeInt; + public + constructor Create(AName: string; AValue: PLargeInt); + + function AsPointer: PChar; override; + end; + +{$endif} + + TBooleanVariable = class(TVariable) + private + FValue: PBoolean; + public + constructor Create(AName: string; AValue: PBoolean); + + function AsPointer: PChar; override; + end; + + TLeftBracket = class(TExprWord) + function GetResultType: TExpressionType; override; + end; + + TRightBracket = class(TExprWord) + protected + function GetResultType: TExpressionType; override; + end; + + TComma = class(TExprWord) + protected + function GetResultType: TExpressionType; override; + end; + + TFunction = class(TExprWord) + private + FIsOperator: Boolean; + FOperPrec: Integer; + FMinFunctionArg: Integer; + FMaxFunctionArg: Integer; + FDescription: string; + FTypeSpec: string; + FShortName: string; + FResultType: TExpressionType; + protected + function GetDescription: string; override; + function GetIsOperator: Boolean; override; + function GetMinFunctionArg: Integer; override; + function GetMaxFunctionArg: Integer; override; + function GetResultType: TExpressionType; override; + function GetTypeSpec: string; override; + function GetShortName: string; override; + + procedure InternalCreate(AName, ATypeSpec: string; AMinFuncArg: Integer; AResultType: TExpressionType; + AExprFunc: TExprFunc; AIsOperator: Boolean; AOperPrec: Integer); + public + constructor Create(AName, AShortName, ATypeSpec: string; AMinFuncArg: Integer; AResultType: TExpressionType; AExprFunc: TExprFunc; Descr: string); + constructor CreateOper(AName, ATypeSpec: string; AResultType: TExpressionType; AExprFunc: TExprFunc; AOperPrec: Integer); + + function IsFunction: Boolean; override; + + property OperPrec: Integer read FOperPrec; + property TypeSpec: string read FTypeSpec; + end; + + TVaryingFunction = class(TFunction) + // Functions that can vary for ex. random generators + // should be TVaryingFunction to be sure that they are + // always evaluated + protected + function GetCanVary: Boolean; override; + end; + +const + ListChar = ','; {the delimiter used with the 'in' operator: e.g., + ('a' in 'a,b') =True + ('c' in 'a,b') =False} + +function ExprCharToExprType(ExprChar: Char): TExpressionType; + +implementation + +function ExprCharToExprType(ExprChar: Char): TExpressionType; +begin + case ExprChar of + 'B': Result := etBoolean; + 'I': Result := etInteger; + 'L': Result := etLargeInt; + 'F': Result := etFloat; + 'D': Result := etDateTime; + 'S': Result := etString; + else + Result := etUnknown; + end; +end; + +procedure _FloatVariable(Param: PExpressionRec); +begin + with Param^ do + PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^; +end; + +procedure _BooleanVariable(Param: PExpressionRec); +begin + with Param^ do + PBoolean(Res.MemoryPos^)^ := PBoolean(Args[0])^; +end; + +procedure _StringConstant(Param: PExpressionRec); +begin + with Param^ do + Res.Append(Args[0], StrLen(Args[0])); +end; + +procedure _StringVariable(Param: PExpressionRec); +var + length: integer; +begin + with Param^ do + begin + length := PInteger(Args[1])^; + if length = -1 then + length := StrLen(PPChar(Args[0])^); + Res.Append(PPChar(Args[0])^, length); + end; +end; + +procedure _DateTimeVariable(Param: PExpressionRec); +begin + with Param^ do + PDateTimeRec(Res.MemoryPos^)^ := PDateTimeRec(Args[0])^; +end; + +procedure _IntegerVariable(Param: PExpressionRec); +begin + with Param^ do + PInteger(Res.MemoryPos^)^ := PInteger(Args[0])^; +end; + +{ +procedure _SmallIntVariable(Param: PExpressionRec); +begin + with Param^ do + PSmallInt(Res.MemoryPos^)^ := PSmallInt(Args[0])^; +end; +} + +{$ifdef SUPPORT_INT64} + +procedure _LargeIntVariable(Param: PExpressionRec); +begin + with Param^ do + PLargeInt(Res.MemoryPos^)^ := PLargeInt(Args[0])^; +end; + +{$endif} + +{ TExpressionWord } + +constructor TExprWord.Create(AName: string; AExprFunc: TExprFunc); +begin + FName := AName; + FExprFunc := AExprFunc; +end; + +function TExprWord.GetCanVary: Boolean; +begin + Result := False; +end; + +function TExprWord.GetDescription: string; +begin + Result := EmptyStr; +end; + +function TExprWord.GetShortName: string; +begin + Result := EmptyStr; +end; + +function TExprWord.GetIsOperator: Boolean; +begin + Result := False; +end; + +function TExprWord.GetIsVariable: Boolean; +begin + // delphi wants to call the function pointed to by the variable, use '@' + // fpc simply returns pointer to function, no '@' needed + Result := (@FExprFunc = @_StringVariable) or + (@FExprFunc = @_StringConstant) or + (@FExprFunc = @_FloatVariable) or + (@FExprFunc = @_IntegerVariable) or +// (FExprFunc = @_SmallIntVariable) or +{$ifdef SUPPORT_INT64} + (@FExprFunc = @_LargeIntVariable) or +{$endif} + (@FExprFunc = @_DateTimeVariable) or + (@FExprFunc = @_BooleanVariable); +end; + +function TExprWord.GetNeedsCopy: Boolean; +begin + Result := (@FExprFunc <> @_StringConstant) and +// (@FExprFunc <> @_StringVariable) and +// (@FExprFunc <> @_StringVariableFixedLen) and +// string variable cannot be used as normal parameter +// because it is indirectly referenced and possibly +// not null-terminated (fixed len) + (@FExprFunc <> @_FloatVariable) and + (@FExprFunc <> @_IntegerVariable) and +// (FExprFunc <> @_SmallIntVariable) and +{$ifdef SUPPORT_INT64} + (@FExprFunc <> @_LargeIntVariable) and +{$endif} + (@FExprFunc <> @_DateTimeVariable) and + (@FExprFunc <> @_BooleanVariable); +end; + +function TExprWord.GetFixedLen: Integer; +begin + // -1 means variable, non-fixed length + Result := -1; +end; + +function TExprWord.GetMinFunctionArg: Integer; +begin + Result := 0; +end; + +function TExprWord.GetMaxFunctionArg: Integer; +begin + Result := 0; +end; + +function TExprWord.GetResultType: TExpressionType; +begin + Result := etUnknown; +end; + +function TExprWord.GetTypeSpec: string; +begin + Result := EmptyStr; +end; + +function TExprWord.AsPointer: PChar; +begin + Result := nil; +end; + +function TExprWord.LenAsPointer: PInteger; +begin + Result := nil; +end; + +function TExprWord.IsFunction: Boolean; +begin + Result := False; +end; + +procedure TExprWord.SetFixedLen(NewLen: integer); +begin +end; + +{ TConstant } + +constructor TConstant.Create(AName: string; AVarType: TExpressionType; AExprFunc: TExprFunc); +begin + inherited Create(AName, AExprFunc); + + FResultType := AVarType; +end; + +function TConstant.GetResultType: TExpressionType; +begin + Result := FResultType; +end; + +{ TFloatConstant } + +constructor TFloatConstant.Create(AName, AValue: string); +begin + inherited Create(AName, etFloat, _FloatVariable); + + if Length(AValue) > 0 then + FValue := StrToFloat(AValue) + else + FValue := 0.0; +end; + +constructor TFloatConstant.CreateAsDouble(AName: string; AValue: Double); +begin + inherited Create(AName, etFloat, _FloatVariable); + + FValue := AValue; +end; + +function TFloatConstant.AsPointer: PChar; +begin + Result := PChar(@FValue); +end; + +{ TUserConstant } + +constructor TUserConstant.CreateAsDouble(AName, Descr: string; AValue: Double); +begin + FDescription := Descr; + + inherited CreateAsDouble(AName, AValue); +end; + +function TUserConstant.GetDescription: string; +begin + Result := FDescription; +end; + +{ TStringConstant } + +constructor TStringConstant.Create(AValue: string); +var + firstChar, lastChar: Char; +begin + inherited Create(AValue, etString, _StringConstant); + + firstChar := AValue[1]; + lastChar := AValue[Length(AValue)]; + if (firstChar = lastChar) and ((firstChar = '''') or (firstChar = '"')) then + FValue := Copy(AValue, 2, Length(AValue) - 2) + else + FValue := AValue; +end; + +function TStringConstant.AsPointer: PChar; +begin + Result := PChar(FValue); +end; + +{ TBooleanConstant } + +constructor TBooleanConstant.Create(AName: string; AValue: Boolean); +begin + inherited Create(AName, etBoolean, _BooleanVariable); + + FValue := AValue; +end; + +function TBooleanConstant.AsPointer: PChar; +begin + Result := PChar(@FValue); +end; + +{ TIntegerConstant } + +constructor TIntegerConstant.Create(AValue: Integer); +begin + inherited Create(IntToStr(AValue), etInteger, _IntegerVariable); + + FValue := AValue; +end; + +function TIntegerConstant.AsPointer: PChar; +begin + Result := PChar(@FValue); +end; + +{ TVariable } + +constructor TVariable.Create(AName: string; AVarType: TExpressionType; AExprFunc: TExprFunc); +begin + inherited Create(AName, AExprFunc); + + FResultType := AVarType; +end; + +function TVariable.GetCanVary: Boolean; +begin + Result := True; +end; + +function TVariable.GetResultType: TExpressionType; +begin + Result := FResultType; +end; + +{ TFloatVariable } + +constructor TFloatVariable.Create(AName: string; AValue: PDouble); +begin + inherited Create(AName, etFloat, _FloatVariable); + FValue := AValue; +end; + +function TFloatVariable.AsPointer: PChar; +begin + Result := PChar(FValue); +end; + +{ TStringVariable } + +constructor TStringVariable.Create(AName: string; AValue: PPChar); +begin + // variable or fixed length? + inherited Create(AName, etString, _StringVariable); + + // store pointer to string + FValue := AValue; + FFixedLen := -1; +end; + +function TStringVariable.AsPointer: PChar; +begin + Result := PChar(FValue); +end; + +function TStringVariable.GetFixedLen: Integer; +begin + Result := FFixedLen; +end; + +function TStringVariable.LenAsPointer: PInteger; +begin + Result := @FFixedLen; +end; + +procedure TStringVariable.SetFixedLen(NewLen: integer); +begin + FFixedLen := NewLen; +end; + +{ TDateTimeVariable } + +constructor TDateTimeVariable.Create(AName: string; AValue: PDateTimeRec); +begin + inherited Create(AName, etDateTime, _DateTimeVariable); + FValue := AValue; +end; + +function TDateTimeVariable.AsPointer: PChar; +begin + Result := PChar(FValue); +end; + +{ TIntegerVariable } + +constructor TIntegerVariable.Create(AName: string; AValue: PInteger); +begin + inherited Create(AName, etInteger, _IntegerVariable); + FValue := AValue; +end; + +function TIntegerVariable.AsPointer: PChar; +begin + Result := PChar(FValue); +end; + +{$ifdef SUPPORT_INT64} + +{ TLargeIntVariable } + +constructor TLargeIntVariable.Create(AName: string; AValue: PLargeInt); +begin + inherited Create(AName, etLargeInt, _LargeIntVariable); + FValue := AValue; +end; + +function TLargeIntVariable.AsPointer: PChar; +begin + Result := PChar(FValue); +end; + +{$endif} + +{ TBooleanVariable } + +constructor TBooleanVariable.Create(AName: string; AValue: PBoolean); +begin + inherited Create(AName, etBoolean, _BooleanVariable); + FValue := AValue; +end; + +function TBooleanVariable.AsPointer: PChar; +begin + Result := PChar(FValue); +end; + +{ TLeftBracket } + +function TLeftBracket.GetResultType: TExpressionType; +begin + Result := etLeftBracket; +end; + +{ TRightBracket } + +function TRightBracket.GetResultType: TExpressionType; +begin + Result := etRightBracket; +end; + +{ TComma } + +function TComma.GetResultType: TExpressionType; +begin + Result := etComma; +end; + +{ TExpressList } + +constructor TExpressList.Create; +begin + inherited; + + FShortList := TExpressShortList.Create; +end; + +destructor TExpressList.Destroy; +begin + inherited; + FShortList.Free; +end; + +procedure TExpressList.Add(Item: Pointer); +var + I: Integer; +begin + inherited; + + { remember we reference the object } + Inc(TExprWord(Item).FRefCount); + + { also add ShortName as reference } + if Length(TExprWord(Item).ShortName) > 0 then + begin + FShortList.Search(FShortList.KeyOf(Item), I); + FShortList.Insert(I, Item); + end; +end; + +function TExpressList.Compare(Key1, Key2: Pointer): Integer; +begin + Result := StrIComp(PChar(Key1), PChar(Key2)); +end; + +function TExpressList.KeyOf(Item: Pointer): Pointer; +begin + Result := PChar(TExprWord(Item).Name); +end; + +procedure TExpressList.FreeItem(Item: Pointer); +begin + Dec(TExprWord(Item).FRefCount); + FShortList.Remove(Item); + if TExprWord(Item).FRefCount = 0 then + inherited; +end; + +function TExpressList.Search(Key: Pointer; var Index: Integer): Boolean; +var + SecIndex: Integer; +begin + Result := inherited Search(Key, Index); + if not Result then + begin + Result := FShortList.Search(Key, SecIndex); + if Result then + Index := IndexOf(FShortList.Items[SecIndex]); + end; +end; + +function TExpressShortList.Compare(Key1, Key2: Pointer): Integer; +begin + Result := StrIComp(PChar(Key1), PChar(Key2)); +end; + +function TExpressShortList.KeyOf(Item: Pointer): Pointer; +begin + Result := PChar(TExprWord(Item).ShortName); +end; + +procedure TExpressShortList.FreeItem(Item: Pointer); +begin +end; + +{ TExprCollection } + +procedure TExprCollection.Check; +var + brCount, I: Integer; +begin + brCount := 0; + for I := 0 to Count - 1 do + begin + case TExprWord(Items[I]).ResultType of + etLeftBracket: Inc(brCount); + etRightBracket: Dec(brCount); + end; + end; + if brCount <> 0 then + raise EParserException.Create('Unequal brackets'); +end; + +procedure TExprCollection.EraseExtraBrackets; +var + I: Integer; + brCount: Integer; +begin + if (TExprWord(Items[0]).ResultType = etLeftBracket) then + begin + brCount := 1; + I := 1; + while (I < Count) and (brCount > 0) do + begin + case TExprWord(Items[I]).ResultType of + etLeftBracket: Inc(brCount); + etRightBracket: Dec(brCount); + end; + Inc(I); + end; + if (brCount = 0) and (I = Count) and (TExprWord(Items[I - 1]).ResultType = + etRightBracket) then + begin + for I := 0 to Count - 3 do + Items[I] := Items[I + 1]; + Count := Count - 2; + EraseExtraBrackets; //Check if there are still too many brackets + end; + end; +end; + +{ TFunction } + +constructor TFunction.Create(AName, AShortName, ATypeSpec: string; AMinFuncArg: Integer; AResultType: TExpressionType; + AExprFunc: TExprFunc; Descr: string); +begin + //to increase compatibility don't use default parameters + FDescription := Descr; + FShortName := AShortName; + InternalCreate(AName, ATypeSpec, AMinFuncArg, AResultType, AExprFunc, false, 0); +end; + +constructor TFunction.CreateOper(AName, ATypeSpec: string; AResultType: TExpressionType; + AExprFunc: TExprFunc; AOperPrec: Integer); +begin + InternalCreate(AName, ATypeSpec, -1, AResultType, AExprFunc, true, AOperPrec); +end; + +procedure TFunction.InternalCreate(AName, ATypeSpec: string; AMinFuncArg: Integer; AResultType: TExpressionType; + AExprFunc: TExprFunc; AIsOperator: Boolean; AOperPrec: Integer); +begin + inherited Create(AName, AExprFunc); + + FMaxFunctionArg := Length(ATypeSpec); + FMinFunctionArg := AMinFuncArg; + if AMinFuncArg = -1 then + FMinFunctionArg := FMaxFunctionArg; + FIsOperator := AIsOperator; + FOperPrec := AOperPrec; + FTypeSpec := ATypeSpec; + FResultType := AResultType; + + // check correctness + if FMaxFunctionArg > MaxArg then + raise EParserException.Create('Too many arguments'); +end; + +function TFunction.GetDescription: string; +begin + Result := FDescription; +end; + +function TFunction.GetIsOperator: Boolean; +begin + Result := FIsOperator; +end; + +function TFunction.GetMinFunctionArg: Integer; +begin + Result := FMinFunctionArg; +end; + +function TFunction.GetMaxFunctionArg: Integer; +begin + Result := FMaxFunctionArg; +end; + +function TFunction.GetResultType: TExpressionType; +begin + Result := FResultType; +end; + +function TFunction.GetShortName: string; +begin + Result := FShortName; +end; + +function TFunction.GetTypeSpec: string; +begin + Result := FTypeSpec; +end; + +function TFunction.IsFunction: Boolean; +begin + Result := True; +end; + +{ TVaryingFunction } + +function TVaryingFunction.GetCanVary: Boolean; +begin + Result := True; +end; + +{ TDynamicType } + +constructor TDynamicType.Create(DestMem, DestPos: PPChar; ASize: PInteger); +begin + inherited Create; + + FMemory := DestMem; + FMemoryPos := DestPos; + FSize := ASize; +end; + +procedure TDynamicType.Rewind; +begin + FMemoryPos^ := FMemory^; +end; + +procedure TDynamicType.AssureSpace(ASize: Integer); +begin + // need more memory? + if ((FMemoryPos^) - (FMemory^) + ASize) > (FSize^) then + Resize((FMemoryPos^) - (FMemory^) + ASize, False); +end; + +procedure TDynamicType.Resize(NewSize: Integer; Exact: Boolean); +var + tempBuf: PChar; + bytesCopy, pos: Integer; +begin + // if not exact requested make newlength a multiple of ArgAllocSize + if not Exact then + NewSize := NewSize div ArgAllocSize * ArgAllocSize + ArgAllocSize; + // create new buffer + GetMem(tempBuf, NewSize); + // copy memory + bytesCopy := FSize^; + if bytesCopy > NewSize then + bytesCopy := NewSize; + Move(FMemory^^, tempBuf^, bytesCopy); + // save position in string + pos := FMemoryPos^ - FMemory^; + // delete old mem + FreeMem(FMemory^); + // assign new + FMemory^ := tempBuf; + FSize^ := NewSize; + // assign position + FMemoryPos^ := FMemory^ + pos; +end; + +procedure TDynamicType.Append(Source: PChar; Length: Integer); +begin + // make room for string plus null-terminator + AssureSpace(Length+4); + // copy + Move(Source^, FMemoryPos^^, Length); + Inc(FMemoryPos^, Length); + // null-terminate + FMemoryPos^^ := #0; +end; + +procedure TDynamicType.AppendInteger(Source: Integer); +begin + // make room for number + AssureSpace(12); + Inc(FMemoryPos^, GetStrFromInt(Source, FMemoryPos^)); + FMemoryPos^^ := #0; +end; + +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/mdbf_prssupp.pas b/mseide-msegui/lib/common/fpccompatibility/mdbf_prssupp.pas new file mode 100644 index 0000000..2f798d8 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/mdbf_prssupp.pas @@ -0,0 +1,269 @@ +unit mdbf_prssupp; + +// parse support + +{$I dbf_common.inc} + +interface + +uses + Classes; + +type + + {TOCollection interfaces between OWL TCollection and VCL TList} + + TOCollection = class(TList) + public + procedure AtFree(Index: Integer); + procedure FreeAll; + procedure DoFree(Item: Pointer); + procedure FreeItem(Item: Pointer); virtual; + destructor Destroy; override; + end; + + TNoOwnerCollection = class(TOCollection) + public + procedure FreeItem(Item: Pointer); override; + end; + + { TSortedCollection object } + + TSortedCollection = class(TOCollection) + public + function Compare(Key1, Key2: Pointer): Integer; virtual; abstract; + function IndexOf(Item: Pointer): Integer; virtual; + procedure Add(Item: Pointer); virtual; + procedure AddReplace(Item: Pointer); virtual; + procedure AddList(Source: TList; FromIndex, ToIndex: Integer); + {if duplicate then replace the duplicate else add} + function KeyOf(Item: Pointer): Pointer; virtual; + function Search(Key: Pointer; var Index: Integer): Boolean; virtual; + end; + + { TStrCollection object } + + TStrCollection = class(TSortedCollection) + public + function Compare(Key1, Key2: Pointer): Integer; override; + procedure FreeItem(Item: Pointer); override; + end; + +function GetStrFromInt(Val: Integer; const Dst: PChar): Integer; +procedure GetStrFromInt_Width(Val: Integer; const Width: Integer; const Dst: PChar; const PadChar: Char); +{$ifdef SUPPORT_INT64} +function GetStrFromInt64(Val: Int64; const Dst: PChar): Integer; +procedure GetStrFromInt64_Width(Val: Int64; const Width: Integer; const Dst: PChar; const PadChar: Char); +{$endif} + +implementation + +uses SysUtils; + +destructor TOCollection.Destroy; +begin + FreeAll; + inherited Destroy; +end; + +procedure TOCollection.AtFree(Index: Integer); +var + Item: Pointer; +begin + Item := Items[Index]; + Delete(Index); + FreeItem(Item); +end; + + +procedure TOCollection.FreeAll; +var + I: Integer; +begin + try + for I := 0 to Count - 1 do + FreeItem(Items[I]); + finally + Count := 0; + end; +end; + +procedure TOCollection.DoFree(Item: Pointer); +begin + AtFree(IndexOf(Item)); +end; + +procedure TOCollection.FreeItem(Item: Pointer); +begin + if (Item <> nil) then + with TObject(Item) as TObject do + Free; +end; + +{----------------------------------------------------------------virtual; + Implementing TNoOwnerCollection + -----------------------------------------------------------------} + +procedure TNoOwnerCollection.FreeItem(Item: Pointer); +begin +end; + +{ TSortedCollection } + +function TSortedCollection.IndexOf(Item: Pointer): Integer; +var + I: Integer; +begin + IndexOf := -1; + if Search(KeyOf(Item), I) then + begin + while (I < Count) and (Item <> Items[I]) do + Inc(I); + if I < Count then IndexOf := I; + end; +end; + +procedure TSortedCollection.AddReplace(Item: Pointer); +var + Index: Integer; +begin + if Search(KeyOf(Item), Index) then + Delete(Index); + Add(Item); +end; + +procedure TSortedCollection.Add(Item: Pointer); +var + I: Integer; +begin + Search(KeyOf(Item), I); + Insert(I, Item); +end; + +procedure TSortedCollection.AddList(Source: TList; FromIndex, ToIndex: Integer); +var + I: Integer; +begin + for I := FromIndex to ToIndex do + Add(Source.Items[I]); +end; + +function TSortedCollection.KeyOf(Item: Pointer): Pointer; +begin + Result := Item; +end; + +function TSortedCollection.Search(Key: Pointer; var Index: Integer): Boolean; +var + L, H, I, C: Integer; +begin + Result := false; + L := 0; + H := Count - 1; + while L <= H do + begin + I := (L + H) div 2; + C := Compare(KeyOf(Items[I]), Key); + if C < 0 then + L := I + 1 + else begin + H := I - 1; + Result := C = 0; + end; + end; + Index := L; +end; + +{ TStrCollection } + +function TStrCollection.Compare(Key1, Key2: Pointer): Integer; +begin + Compare := StrComp(Key1, Key2); +end; + +procedure TStrCollection.FreeItem(Item: Pointer); +begin + StrDispose(Item); +end; + +// it seems there is no pascal function to convert an integer into a PChar??? +// NOTE: in dbf_dbffile.pas there is also a convert routine, but is slightly different + +function GetStrFromInt(Val: Integer; const Dst: PChar): Integer; +var + Temp: array[0..10] of Char; + I, J: Integer; +begin + Val := Abs(Val); + // we'll have to store characters backwards first + I := 0; + J := 0; + repeat + Temp[I] := Chr((Val mod 10) + Ord('0')); + Val := Val div 10; + Inc(I); + until Val = 0; + + // remember number of digits + Result := I; + // copy value, remember: stored backwards + repeat + Dst[J] := Temp[I-1]; + Inc(J); + Dec(I); + until I = 0; + // done! +end; + +// it seems there is no pascal function to convert an integer into a PChar??? + +procedure GetStrFromInt_Width(Val: Integer; const Width: Integer; const Dst: PChar; const PadChar: Char); +var + Temp: array[0..10] of Char; + I, J: Integer; + NegSign: boolean; +begin + {$I getstrfromint.inc} +end; + +{$ifdef SUPPORT_INT64} + +procedure GetStrFromInt64_Width(Val: Int64; const Width: Integer; const Dst: PChar; const PadChar: Char); +var + Temp: array[0..19] of Char; + I, J: Integer; + NegSign: boolean; +begin + {$I getstrfromint.inc} +end; + +function GetStrFromInt64(Val: Int64; const Dst: PChar): Integer; +var + Temp: array[0..19] of Char; + I, J: Integer; +begin + Val := Abs(Val); + // we'll have to store characters backwards first + I := 0; + J := 0; + repeat + Temp[I] := Chr((Val mod 10) + Ord('0')); + Val := Val div 10; + Inc(I); + until Val = 0; + + // remember number of digits + Result := I; + // copy value, remember: stored backwards + repeat + Dst[J] := Temp[I-1]; + inc(J); + dec(I); + until I = 0; + // done! +end; + +{$endif} + +end. + diff --git a/mseide-msegui/lib/common/fpccompatibility/msdfdata.pas b/mseide-msegui/lib/common/fpccompatibility/msdfdata.pas new file mode 100644 index 0000000..e4d3de4 --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/msdfdata.pas @@ -0,0 +1,1149 @@ +unit msdfdata; + +// +{$mode objfpc} +{$h+} + +//----------------------------------------------------------------------------- +{ Unit Name : SdfData Application : TSdfDataSet TFixedFormatDataSet Components + Version : 2.05 + Author : Orlando Arrocha email: oarrocha@hotmail.com + Purpose : This components are designed to access directly text files as + database tables. The files may be limited (SDF) or fixed size + columns. +--------------- +Modifications +--------------- +7/Jun/12 BigChimp: + Quote fields with delimiters or quotes to match Delphi SDF definition + (see e.g. help on TStrings.CommaText) +14/Jul/11 BigChimp: + Added AllowMultiLine property so user can use fields that have line endings + (Carriage Return and/or Line Feed) embedded in their fields (fields need to be + quoted). For now: output only (reading these fields does not work yet) +12/Mar/04 Lazarus version (Sergey Smirnov AKA SSY) + Locate and CheckString functions are removed because of Variant data type. + Many things are changed for FPC/Lazarus compatibility. +02/Jun/02 Version 2.05 (Doriano Biondelli) + TrimSpace property added for those cases where you need to retrieve the + field with spaces. +01/Jan/02 Version 2.04 (Orlando Arrocha) + FieldList is now populated. + Locate was changed to improve speed and some bug fixing too. Thanks for + asking and testing Marcelo Castro +16/Dec/01 Version 2.03 (Orlando Arrocha) + Fixed some bugs and added some recomentdations. Here is a list: + Quotations on the last field was not removed properly. Special thanks to + Daniel Nakasone for helping with the solution. + Appending first record to empty files was failing. Thanks again Daniel + Nakasone for the report + GetFieldData now trims the trailing spaces of the field, so users doesn't + needs to do it by themselves anymore. Thanks for the recomendation + Juergen Gehrke. + FieldDefs is now available from the designer. Recomended by Leslie Drewery. + ****** THANKS TO ALL & KEEP SENDING RECOMENDATIONS ***** +05/Oct/01 Version 2.02 (Ben Hay) + Locate function : implement the virtual tdataset method "Locate". + ****** THANKS BEN ***** +11/Sep/01 Version 2.01 (Leslie Drewery) + Added additional logic to handle Corrupt Data by making sure the + Quotes are closed and the delimiter// are the next + characters. + Altered buffer method to create on constructor and cleared when opened. + New Resource File. Nice Icons + SavetoStream method included + LoadFromStream method included + ****** THANKS LESLIE ***** +14/Ago/01 Version 2.00 (Orlando Arrocha) + John Dung Nguyen showed me how to make this compatible with C-Builder + and encouraged me to include a filter. + Dimitry V. Borko says that russian CSV files used other delimiters, + so now you can change it. + OnFilter and other events included. + Delimiter property added to TSdfDataSet. No more dependency on CommaText + methodology -- choose your own delimiter. + BufToStore/StoreToBuf methods lets you translate data records to and from + your propietary storage format. + TTextDataSet removed dependencies. + TBaseTextDataSet class removed. // TBaseTextDataSet = TFixedFormatDataSet; + ****** THANKS JOHN ****** ***** THANKS DIMMY ***** +19/Jul/01 Version 1.03 (Orlando Arrocha) + TBaseTextDataSet class introduced. + FileName property changed datatype to TFileName and removed the property + editor to segregate design-time code from runtime units. + *** To add file browsing functionality please install + *** TFileNamePropertyEditor -- also freeware. + ********** THANKS WAYNE ********* +18/Jun/01 Version 1.02 (Wayne Brantley) + Schema replaces SchemaFileName property. Same as SchemaFileName, except + you can define the schema inside the component. If you still need an + external file, just use Schema.LoadFromFile() + TFixedFormatDataSet class introduced. Use this class for a Fixed length + format file (instead of delimited). The full schema definition + (including lengths) is obviously required. + Bug Fixed - When FirstLineSchema is true and there were no records, it + would display garbage. + +30/Mar/01 Version 1.01 (Orlando Arrocha) + Ligia Maria Pimentel suggested to use the first line of the file to + define the field names. ****** THANKS LIGIA ****** + FileMustExist property. You must put this property to FALSE if you want to + create a new file. + FirstLineSchema property. You can define the field names on the first line + of your file. Fields have to be defined with this format + [= field_size1] , [= field_size2] ... + SchemaFileName property. (Changed to Schema by 1.02 Wayne) + Lets you define the fields attributes (only supports field name and + size). Have to be defined in this format (one field per line) : + [= field_size] + NOTE: fields that doesn't define the length get the record size. + RemoveBlankRecords procedure. Removes all the blank records from the file. + RemoveExtraColumns procedure. If the file have more columns than the + scheme or the field definition at design time, it remove the extra + values from the file. + SaveFileAs. Let you save the file to another filename. + NOTE: This component save changes on closing the table, so you can use + this to save data before that event. +Jan 2001 Version 1.0 TSdfDataSet introduced. +--------- +TERMS +--------- + This component is provided AS-IS without any warranty of any kind, either + express or implied. This component is freeware and can be used in any software + product. Credits on applications will be welcomed. + If you find it useful, improve it or have a wish list... please drop me a mail, + I'll be glad to hear your comments. +---------------- +How to Install +---------------- + 1. Copy this SDFDATA.PAS and the associated SDFDATA.DCR to the folder from + where you wish to install the component. This will probably be $(DELPHI)\lib + or a sub-folder. + 2. Install the TSdfDataSet and TFixedFormatDataSet components by choosing the + Component | Install Component menu option. + 3. Select the "Into exisiting package" page of the Install Components dialogue. + 4. Browse to the folder where you saved this file and select it. + 5. Ensure that the "Package file name" edit box contains $(DELPHI)\DCLUSR??.DPK + or the one you prefer for DB related objects. + 6. Accept that the package will be rebuilt. +} +//----------------------------------------------------------------------------- +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + mdb, classes,mclasses,SysUtils, DBConst; + +type +//----------------------------------------------------------------------------- +// TRecInfo + PRecInfo = ^TRecInfo; + TRecInfo = packed record + RecordNumber: PtrInt; + BookmarkFlag: TBookmarkFlag; + end; +//----------------------------------------------------------------------------- +// TBaseTextDataSet + TFixedFormatDataSet = class(TDataSet) + private + FSchema :TStringList; + FFileName :TFileName; + FFilterBuffer :TRecordBuffer; + FFileMustExist :Boolean; + FReadOnly :Boolean; + FLoadfromStream :Boolean; + FTrimSpace :Boolean; + procedure SetSchema(const Value: TStringList); + procedure SetFileName(Value : TFileName); + procedure SetFileMustExist(Value : Boolean); + procedure SetTrimSpace(Value : Boolean); + procedure SetReadOnly(Value : Boolean); + procedure RemoveWhiteLines(List : TStrings; IsFileRecord : Boolean); + procedure LoadFieldScheme(List : TStrings; MaxSize : Integer); + function GetActiveRecBuf(var RecBuf: TRecordBuffer): Boolean; + procedure SetFieldPos(var Buffer : TRecordBuffer; FieldNo : Integer); + protected + FData :TStringlist; + FCurRec :Integer; + FRecBufSize :Integer; + FRecordSize :Integer; + FLastBookmark :PtrInt; + FRecInfoOfs :Integer; + FBookmarkOfs :Integer; + FSaveChanges :Boolean; + FDefaultRecordLength:Cardinal; + FDataOffset : Integer; + protected + function AllocRecordBuffer: TRecordBuffer; override; + procedure FreeRecordBuffer(var Buffer: TRecordBuffer); override; + procedure InternalAddRecord(Buffer: Pointer; DoAppend: Boolean); override; + procedure InternalClose; override; + procedure InternalDelete; override; + procedure InternalFirst; override; + procedure InternalGotoBookmark(ABookmark: Pointer); override; + procedure InternalHandleException; override; + procedure InternalInitFieldDefs; override; + procedure InternalInitRecord(Buffer: TRecordBuffer); override; + procedure InternalLast; override; + procedure InternalOpen; override; + procedure InternalPost; override; + procedure InternalEdit; override; + procedure InternalSetToRecord(Buffer: TRecordBuffer); override; + function IsCursorOpen: Boolean; override; + procedure GetBookmarkData(Buffer: TRecordBuffer; Data: Pointer); override; + function GetBookmarkFlag(Buffer: TRecordBuffer): TBookmarkFlag; override; + function GetRecord(Buffer: TRecordBuffer; GetMode: TGetMode; DoCheck: Boolean): TGetResult; override; + function GetRecordSize: Word; override; + procedure SetBookmarkFlag(Buffer: TRecordBuffer; Value: TBookmarkFlag); override; + procedure SetBookmarkData(Buffer: TRecordBuffer; Data: Pointer); override; + procedure ClearCalcFields(Buffer: TRecordBuffer); override; + function GetRecordCount: Integer; override; + function GetRecNo: Integer; override; + procedure SetRecNo(Value: Integer); override; + function GetCanModify: boolean; override; + function TxtGetRecord(Buffer : TRecordBuffer; GetMode: TGetMode): TGetResult; + function RecordFilter(RecBuf: Pointer; ARecNo: Integer): Boolean; + function BufToStore(Buffer: TRecordBuffer): String; virtual; + function StoreToBuf(Source: String): String; virtual; + public + property DefaultRecordLength: Cardinal read FDefaultRecordLength + write FDefaultRecordLength default 250; + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + procedure SetFieldData(Field: TField; Buffer: Pointer); override; + function GetFieldData(Field: TField; Buffer: Pointer): Boolean; override; + procedure RemoveBlankRecords; dynamic; + procedure RemoveExtraColumns; dynamic; + procedure SaveFileAs(strFileName : String); dynamic; + property CanModify; + procedure LoadFromStream(Stream :TStream); + procedure SavetoStream(Stream :TStream); + published + property FileMustExist: Boolean read FFileMustExist write SetFileMustExist; + property ReadOnly: Boolean read FReadOnly write SetReadOnly; + property FileName : TFileName read FFileName write SetFileName; + property Schema: TStringList read FSchema write SetSchema; + property TrimSpace: Boolean read FTrimSpace write SetTrimSpace default True; + property FieldDefs; + property Active; + property AutoCalcFields; + property Filtered; + property BeforeOpen; + property AfterOpen; + property BeforeClose; + property AfterClose; + property BeforeInsert; + property AfterInsert; + property BeforeEdit; + property AfterEdit; + property BeforePost; + property AfterPost; + property BeforeCancel; + property AfterCancel; + property BeforeDelete; + property AfterDelete; + property BeforeScroll; + property AfterScroll; +// property BeforeRefresh; +// property AfterRefresh; + property OnCalcFields; + property OnDeleteError; + property OnEditError; + property OnFilterRecord; + property OnNewRecord; + property OnPostError; + property onmodified; + end; + +//----------------------------------------------------------------------------- +// TSdfDataSet + TSdfDataSet = class(TFixedFormatDataSet) + private + FDelimiter : Char; + FFirstLineAsSchema : Boolean; + FFMultiLine :Boolean; + procedure SetMultiLine(const Value: Boolean); + procedure SetFirstLineAsSchema(Value : Boolean); + procedure SetDelimiter(Value : Char); + protected + procedure InternalInitFieldDefs; override; + function GetRecord(Buffer: TRecordBuffer; GetMode: TGetMode; DoCheck: Boolean) + : TGetResult; override; + function BufToStore(Buffer: TRecordBuffer): String; override; + function StoreToBuf(Source: String): String; override; + public + constructor Create(AOwner: TComponent); override; + published + property AllowMultiLine: Boolean read FFMultiLine write SetMultiLine default True; //Whether or not to allow fields containing CR and/or LF + property Delimiter: Char read FDelimiter write SetDelimiter; + property FirstLineAsSchema: Boolean read FFirstLineAsSchema write SetFirstLineAsSchema; + end; +//procedure Register; + +implementation +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +//{$R *.Res} + +//----------------------------------------------------------------------------- +// TFixedFormatDataSet +//----------------------------------------------------------------------------- +constructor TFixedFormatDataSet.Create(AOwner : TComponent); +begin + FDefaultRecordLength := 250; + FFileMustExist := TRUE; + FLoadfromStream := False; + FRecordSize := 0; + FTrimSpace := TRUE; + FSchema := TStringList.Create; + FData := TStringList.Create; // Load the textfile into a stringlist + inherited Create(AOwner); +end; + +destructor TFixedFormatDataSet.Destroy; +begin + inherited Destroy; + FData.Free; + FSchema.Free; +end; + +procedure TFixedFormatDataSet.SetSchema(const Value: TStringList); +begin + CheckInactive; + FSchema.Assign(Value); +end; + +procedure TFixedFormatDataSet.SetFileMustExist(Value : Boolean); +begin + CheckInactive; + FFileMustExist := Value; +end; + +procedure TFixedFormatDataSet.SetTrimSpace(Value : Boolean); +begin + CheckInactive; + FTrimSpace := Value; +end; + +procedure TFixedFormatDataSet.SetReadOnly(Value : Boolean); +begin + CheckInactive; + FReadOnly := Value; +end; + +procedure TFixedFormatDataSet.SetFileName(Value : TFileName); +begin + CheckInactive; + FFileName := Value; +end; + +procedure TFixedFormatDataSet.InternalInitFieldDefs; +var + i, len, Maxlen :Integer; + LstFields :TStrings; +begin + if not Assigned(FData) then + exit; + FRecordSize := 0; + Maxlen := 0; + FieldDefs.Clear; + for i := FData.Count - 1 downto 0 do // Find out the longest record + begin + len := Length(FData[i]); + if len > Maxlen then + Maxlen := len; + FData.Objects[i] := TObject(Pointer(i+1)); // Fabricate Bookmarks + end; + if (Maxlen = 0) then + Maxlen := FDefaultRecordLength; + LstFields := TStringList.Create; + try + LoadFieldScheme(LstFields, Maxlen); + for i := 0 to LstFields.Count -1 do // Add fields + begin + len := StrToIntDef(LstFields.Values[LstFields.Names[i]], Maxlen); + FieldDefs.Add(Trim(LstFields.Names[i]), ftString, len, False); + Inc(FRecordSize, len); + end; + finally + LstFields.Free; + end; +end; + +procedure TFixedFormatDataSet.InternalOpen; +var + Stream : TStream; +begin + FCurRec := -1; + FSaveChanges := FALSE; + if not Assigned(FData) then + FData := TStringList.Create; + if (not FileMustExist) and (not FileExists(FileName)) then + begin + Stream := TFileStream.Create(FileName, fmCreate); + Stream.Free; + end; + if not FLoadfromStream then + FData.LoadFromFile(FileName); + FRecordSize := FDefaultRecordLength; + InternalInitFieldDefs; + if DefaultFields then + CreateFields; + BindFields(TRUE); + if FRecordSize = 0 then + FRecordSize := FDefaultRecordLength; + BookmarkSize := SizeOf(PtrInt); + FRecInfoOfs := FRecordSize + CalcFieldsSize; // Initialize the offset for TRecInfo in the buffer + FBookmarkOfs := FRecInfoOfs + SizeOf(TRecInfo); + FRecBufSize := FBookmarkOfs + BookmarkSize; + FLastBookmark := FData.Count; +end; + +procedure TFixedFormatDataSet.InternalClose; +begin + if (not FReadOnly) and (FSaveChanges) then // Write any edits to disk + FData.SaveToFile(FileName); + FLoadfromStream := False; + FData.Clear; + BindFields(FALSE); + if DefaultFields then // Destroy the TField + DestroyFields; + FCurRec := -1; // Reset these internal flags + FLastBookmark := 0; + FRecordSize := 0; +end; + +function TFixedFormatDataSet.IsCursorOpen: Boolean; +begin + Result := Assigned(FData) and (FRecordSize > 0); +end; + +procedure TFixedFormatDataSet.InternalHandleException; +begin +{$ifndef fpc} + Application.HandleException(Self); +{$else} + inherited; +{$endif} +end; + +// Loads Data from a stream. +procedure TFixedFormatDataSet.LoadFromStream(Stream: TStream); +begin + if assigned(stream) then + begin + Active := False; //Make sure the Dataset is Closed. + Stream.Position := 0; //Make sure you are at the top of the Stream. + FLoadfromStream := True; + if not Assigned(FData) then + raise Exception.Create('Data buffer unassigned'); + FData.LoadFromStream(Stream); + Active := True; + end + else + raise exception.Create('Invalid Stream Assigned (Load From Stream'); +end; + +// Saves Data as text to a stream. +procedure TFixedFormatDataSet.SavetoStream(Stream: TStream); +begin + if assigned(stream) then + FData.SaveToStream(Stream) + else + raise exception.Create('Invalid Stream Assigned (Save To Stream'); +end; + +// Record Functions +function TFixedFormatDataSet.AllocRecordBuffer: TRecordBuffer; +begin + if FRecBufSize > 0 then + Result := AllocMem(FRecBufSize) + else + Result := nil; +end; + +procedure TFixedFormatDataSet.FreeRecordBuffer(var Buffer: TRecordBuffer); +begin + if Buffer <> nil then + FreeMem(Buffer); +end; + +procedure TFixedFormatDataSet.InternalInitRecord(Buffer: TRecordBuffer); +begin + FillChar(Buffer[0], FRecordSize, 0); +end; + +procedure TFixedFormatDataSet.ClearCalcFields(Buffer: TRecordBuffer); +begin + FillChar(Buffer[RecordSize], CalcFieldsSize, 0); +end; + +function TFixedFormatDataSet.GetRecord(Buffer: TRecordBuffer; GetMode: TGetMode; + DoCheck: Boolean): TGetResult; +begin + if (FData.Count < (1+FDataOffset)) then + Result := grEOF + else + Result := TxtGetRecord(Buffer, GetMode); + if Result = grOK then + begin + if (CalcFieldsSize > 0) then + GetCalcFields(Buffer); + with PRecInfo(Buffer + FRecInfoOfs)^ do + begin + BookmarkFlag := bfCurrent; + RecordNumber := PtrInt(FData.Objects[FCurRec]); + end; + end + else + if (Result = grError) and DoCheck then + DatabaseError('No Records'); +end; + +function TFixedFormatDataSet.GetRecordCount: Longint; +begin + Result := FData.Count; +end; + +function TFixedFormatDataSet.GetRecNo: Longint; +var + BufPtr: TRecordBuffer; +begin + Result := -1; + if GetActiveRecBuf(BufPtr) then + Result := PRecInfo(BufPtr + FRecInfoOfs)^.RecordNumber; +end; + +procedure TFixedFormatDataSet.SetRecNo(Value: Integer); +begin + CheckBrowseMode; + if (Value >= 0) and (Value < FData.Count) and (Value <> RecNo) then + begin + DoBeforeScroll; + FCurRec := Value - 1; + Resync([]); + DoAfterScroll; + end; +end; + +function TFixedFormatDataSet.GetRecordSize: Word; +begin + Result := FRecordSize; +end; + +function TFixedFormatDataSet.GetActiveRecBuf(var RecBuf: TRecordBuffer): Boolean; +begin + case State of + dsBrowse: if IsEmpty then RecBuf := nil else RecBuf := ActiveBuffer; + dsEdit, dsInsert: RecBuf := ActiveBuffer; + dsCalcFields: RecBuf := CalcBuffer; + dsFilter: RecBuf := FFilterBuffer; + else + RecBuf := nil; + end; + Result := RecBuf <> nil; +end; + +function TFixedFormatDataSet.TxtGetRecord(Buffer : TRecordBuffer; GetMode: TGetMode): TGetResult; +var + Accepted : Boolean; +begin + Result := grOK; + repeat + Accepted := TRUE; + case GetMode of + gmNext: + if FCurRec >= RecordCount - 1 then + Result := grEOF + else + Inc(FCurRec); + gmPrior: + if FCurRec <= FDataOffset then + Result := grBOF + else + Dec(FCurRec); + gmCurrent: + if (FCurRec < FDataOffset) or (FCurRec >= RecordCount) then + Result := grError; + end; + if (Result = grOk) then + begin + Move(PChar(StoreToBuf(FData[FCurRec]))^, Buffer[0], FRecordSize); + if Filtered then + begin + Accepted := RecordFilter(Buffer, FCurRec +1); + if not Accepted and (GetMode = gmCurrent) then + Inc(FCurRec); + end; + end; + until Accepted; +end; + +function TFixedFormatDataSet.RecordFilter(RecBuf: Pointer; ARecNo: Integer): Boolean; +var + Accept: Boolean; + SaveState: TDataSetState; +begin // Returns true if accepted in the filter + SaveState := SetTempState(dsFilter); + FFilterBuffer := RecBuf; + PRecInfo(FFilterBuffer + FRecInfoOfs)^.RecordNumber := ARecNo; + Accept := TRUE; + if Accept and Assigned(OnFilterRecord) then + OnFilterRecord(Self, Accept); + RestoreState(SaveState); + Result := Accept; +end; + +function TFixedFormatDataSet.GetCanModify: boolean; +begin + Result := not FReadOnly; +end; + +// Field Related +procedure TFixedFormatDataSet.LoadFieldScheme(List : TStrings; MaxSize : Integer); +var + tmpFieldName : string; + tmpSchema : TStrings; + i : Integer; +begin + tmpSchema := TStringList.Create; + try // Load Schema Structure + if (Schema.Count > 0) then + begin + tmpSchema.Assign(Schema); + RemoveWhiteLines(tmpSchema, FALSE); + end + else + tmpSchema.Add('Line'); + for i := 0 to tmpSchema.Count -1 do // Interpret Schema + begin + tmpFieldName := tmpSchema.Names[i]; + if (tmpFieldName = '') then + tmpFieldName := Format('%s=%d', [tmpSchema[i], MaxSize]) + else + tmpFieldName := tmpSchema[i]; + List.Add(tmpFieldName); + end; + finally + tmpSchema.Free; + end; +end; + +function TFixedFormatDataSet.GetFieldData(Field: TField; Buffer: Pointer): Boolean; +var + TempPos, recbuf : PChar; +begin + Result := GetActiveRecBuf(TRecordBuffer(RecBuf)); + if Result then + begin + if Field.FieldNo > 0 then + begin + TempPos := RecBuf; + SetFieldPos(TRecordBuffer(RecBuf), Field.FieldNo); + Result := (RecBuf < StrEnd(TempPos)); + end + else + if (State in [dsBrowse, dsEdit, dsInsert, dsCalcFields]) then + begin + Inc(RecBuf, FRecordSize + Field.Offset); + Result := Boolean(Byte(RecBuf[0])); + end; + end; + if Result and (Buffer <> nil) then + begin + StrLCopy(Buffer, RecBuf, Field.Size); + if FTrimSpace then + begin + TempPos := StrEnd(Buffer); + repeat + Dec(TempPos); + if (TempPos[0] = ' ') then + TempPos[0]:= #0 + else + break; + until (TempPos = Buffer); + end; + end; +end; + +procedure TFixedFormatDataSet.SetFieldData(Field: TField; Buffer: Pointer); +var + RecBuf: PChar; + BufEnd: PChar; + p : Integer; +begin + if not (State in dsWriteModes) then + DatabaseError(SNotEditing, Self); + GetActiveRecBuf(TRecordBuffer(RecBuf)); + if Field.FieldNo > 0 then + begin + if State = dsCalcFields then + DatabaseError('Dataset not in edit or insert mode', Self); + if Field.ReadOnly and not (State in [dsSetKey, dsFilter]) then + DatabaseErrorFmt(SReadOnlyField, [Field.DisplayName]); + if State in [dsEdit, dsInsert, dsNewValue] then + Field.Validate(Buffer); + if Field.FieldKind <> fkInternalCalc then + begin + SetFieldPos(TRecordBuffer(RecBuf), Field.FieldNo); + BufEnd := StrEnd(pansichar(ActiveBuffer)); // Fill with blanks when necessary + if BufEnd > RecBuf then + BufEnd := RecBuf; + FillChar(BufEnd[0], Field.Size + PtruInt(RecBuf) - PtruInt(BufEnd), Ord(' ')); + p := StrLen(Buffer); + if p > Field.Size then + p := Field.Size; + Move(Buffer^, RecBuf[0], p); + end; + end + else // fkCalculated, fkLookup + begin + Inc(RecBuf, FRecordSize + Field.Offset); + Move(Buffer^, RecBuf[0], Field.Size); + end; + if not (State in [dsCalcFields, dsFilter, dsNewValue]) then + DataEvent(deFieldChange, Ptrint(Field)); +end; + +procedure TFixedFormatDataSet.SetFieldPos(var Buffer : TRecordBuffer; FieldNo : Integer); +var + i : Integer; +begin + i := 1; + while (i < FieldNo) and (i < FieldDefs.Count) do + begin + Inc(Buffer, FieldDefs.Items[i-1].Size); + Inc(i); + end; +end; + +// Navigation / Editing +procedure TFixedFormatDataSet.InternalFirst; +begin + FCurRec := -1; +end; + +procedure TFixedFormatDataSet.InternalLast; +begin + FCurRec := FData.Count; +end; + +procedure TFixedFormatDataSet.InternalPost; +begin + FSaveChanges := TRUE; + inherited UpdateRecord; + if (State = dsEdit) then // just update the data in the string list + begin + FData[FCurRec] := BufToStore(ActiveBuffer); + end + else + InternalAddRecord(ActiveBuffer, FALSE); +end; + +procedure TFixedFormatDataSet.InternalEdit; +begin + +end; + +procedure TFixedFormatDataSet.InternalDelete; +begin + FSaveChanges := TRUE; + FData.Delete(FCurRec); + if FCurRec >= FData.Count then + Dec(FCurRec); +end; + +procedure TFixedFormatDataSet.InternalAddRecord(Buffer: Pointer; DoAppend: Boolean); +begin + FSaveChanges := TRUE; + Inc(FLastBookmark); + if DoAppend then + InternalLast; + if (FCurRec >=0) then + FData.InsertObject(FCurRec, BufToStore(Buffer), TObject(Pointer(FLastBookmark))) + else + FData.AddObject(BufToStore(Buffer), TObject(Pointer(FLastBookmark))); +end; + +procedure TFixedFormatDataSet.InternalGotoBookmark(ABookmark: Pointer); +var + Index: Integer; +begin + Index := FData.IndexOfObject(TObject(PPtrInt(ABookmark)^)); + if Index <> -1 then + FCurRec := Index + else + DatabaseError('Bookmark not found'); +end; + +procedure TFixedFormatDataSet.InternalSetToRecord(Buffer: TRecordBuffer); +begin + if (State <> dsInsert) then + InternalGotoBookmark(@PRecInfo(Buffer + FRecInfoOfs)^.RecordNumber); +end; + +function TFixedFormatDataSet.GetBookmarkFlag(Buffer: TRecordBuffer): TBookmarkFlag; +begin + Result := PRecInfo(Buffer + FRecInfoOfs)^.BookmarkFlag; +end; + +procedure TFixedFormatDataSet.SetBookmarkFlag(Buffer: TRecordBuffer; Value: TBookmarkFlag); +begin + PRecInfo(Buffer + FRecInfoOfs)^.BookmarkFlag := Value; +end; + +procedure TFixedFormatDataSet.GetBookmarkData(Buffer: TRecordBuffer; Data: Pointer); +begin + Move(Buffer[FRecInfoOfs], Data^, BookmarkSize); +end; + +procedure TFixedFormatDataSet.SetBookmarkData(Buffer: TRecordBuffer; Data: Pointer); +begin + Move(Data^, Buffer[FRecInfoOfs], BookmarkSize); +end; + +procedure TFixedFormatDataSet.RemoveWhiteLines(List : TStrings; IsFileRecord : Boolean); +var + i : integer; +begin + for i := List.Count -1 downto 0 do + begin + if (Trim(List[i]) = '' ) then + if IsFileRecord then + begin + FCurRec := i; + InternalDelete; + end + else + List.Delete(i); + end; +end; + +procedure TFixedFormatDataSet.RemoveBlankRecords; +begin + RemoveWhiteLines(FData, TRUE); +end; + +procedure TFixedFormatDataSet.RemoveExtraColumns; +var + i : Integer; +begin + for i := FData.Count -1 downto 0 do + FData[i] := BufToStore(trecordbuffer(StoreToBuf(FData[i]))); + FData.SaveToFile(FileName); +end; + +procedure TFixedFormatDataSet.SaveFileAs(strFileName : String); +begin + FData.SaveToFile(strFileName); + FFileName := strFileName; + FSaveChanges := FALSE; +end; + +function TFixedFormatDataSet.StoreToBuf(Source: String): String; +begin + Result := Source; +end; + +function TFixedFormatDataSet.BufToStore(Buffer: TRecordBuffer): String; +begin + Result := Copy(pansichar(Buffer), 1, FRecordSize); +end; + +//----------------------------------------------------------------------------- +// TSdfDataSet +//----------------------------------------------------------------------------- +constructor TSdfDataSet.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + FDelimiter := ','; + FFirstLineAsSchema := FALSE; + FFMultiLine :=False; +end; + +procedure TSdfDataSet.InternalInitFieldDefs; +var + pStart, pEnd, len : Integer; +begin + if not IsCursorOpen then + exit; + if (FData.Count = 0) and (Schema.Count > 0) and FirstLineAsSchema then + begin + Schema.Delimiter := Delimiter; + FData.Append(Schema.DelimitedText); + end + else if (FData.Count = 0) or (Trim(FData[0]) = '') then + begin + FirstLineAsSchema := FALSE; + FDataOffset:=0; + end + else if (Schema.Count = 0) or (FirstLineAsSchema) then + begin + Schema.Clear; + len := Length(FData[0]); + pEnd := 1; + repeat + while (pEnd <= len) and (FData[0][pEnd] in [#1..' ']) do + Inc(pEnd); + + if (pEnd > len) then + break; + + pStart := pEnd; + + if (FData[0][pStart] = '"') then + begin + repeat + Inc(pEnd); + until (pEnd > len) or (FData[0][pEnd] = '"'); + + if (FData[0][pEnd] = '"') then + Inc(pStart); + end + else + while (pEnd <= len) and (FData[0][pEnd] <> Delimiter) do + Inc(pEnd); + + if (FirstLineAsSchema) then + Schema.Add(Copy(FData[0], pStart, pEnd - pStart)) + else + Schema.Add(Format('Field%d', [Schema.Count + 1])); + + if (FData[0][pEnd] = '"') then + while (pEnd <= len) and (FData[0][pEnd] <> Delimiter) do + Inc(pEnd); + + if (FData[0][pEnd] = Delimiter) then + Inc(pEnd); + + until (pEnd > len); + end; + inherited; +end; + +function TSdfDataSet.GetRecord(Buffer: TRecordBuffer; GetMode: TGetMode; + DoCheck: Boolean): TGetResult; +begin + if FirstLineAsSchema then + begin + if (FData.Count < 2) then + begin + if GetMode=gmPrior then + Result := grBOF + else + Result := grEOF + end + else + begin + If (FCurrec=-1) and (GetMode=gmNext) then + inc(FCurrec); + Result := inherited GetRecord(Buffer, GetMode, DoCheck); + end; + end + else + Result := inherited GetRecord(Buffer, GetMode, DoCheck); +end; + +function TSdfDataSet.StoreToBuf(Source: String): String; +const + CR :char = #13; + LF :char = #10; + Quote :char = #34; // Character that encloses field if quoted. Hard-coded to " +var + IsQuoted // Whether or not field starts with a quote + :Boolean; + FieldMaxSize, // Maximum fields size as defined in FieldDefs + i, // Field counter (0..) + p // Length of string in field + :Integer; + pDeQuoted, // Temporary buffer for dedoubling quotes + pRet, // Pointer to insertion point in return value + pStr, // Beginning of field + pStrEnd // End of field + :PChar; + Ret :String; +begin + SetLength(Ret, FRecordSize); + FillChar(PChar(Ret)^, FRecordSize, Ord(' ')); + + PStrEnd := PChar(Source); + pRet := PChar(Ret); + + for i := 0 to FieldDefs.Count - 1 do + begin + FieldMaxSize := FieldDefs[i].Size; + IsQuoted := false; + while Boolean(Byte(pStrEnd[0])) and (pStrEnd[0] in [#1..' ']) do + begin + if FFMultiLine then + begin + if ((pStrEnd[0]=CR) or (pStrEnd[0]=LF)) then + begin + //view this as text, not control characters, so do nothing + //todo: check if this is really necessary, probably revert + //to original code as quoted case is handled below + end; + end + else + begin + Inc(pStrEnd); + end; + end; + + if not Boolean(Byte(pStrEnd[0])) then + break; + + pStr := pStrEnd; + + if (pStr[0] = Quote) then + begin + IsQuoted := true; // See below: accept end of string without explicit quote + if FFMultiLine then + begin + repeat + Inc(pStrEnd); + until not Boolean(Byte(pStrEnd[0])) or + ((pStrEnd[0] = Quote) and ((pStrEnd + 1)[0] in [Delimiter,#0])); + end + else + begin + // No multiline, so treat cr/lf as end of record + repeat + Inc(pStrEnd); + until not Boolean(Byte(pStrEnd[0])) or + ((pStrEnd[0] = Quote) and ((pStrEnd + 1)[0] in [Delimiter,CR,LF,#0])); + end; + + if (pStrEnd[0] = Quote) then + Inc(pStr); //Skip final quote + end + else + while Boolean(Byte(pStrEnd[0])) and (pStrEnd[0] <> Delimiter) do + Inc(pStrEnd); + + // Copy over entire field (or at least up to field length): + p := pStrEnd - pStr; + if IsQuoted then + begin + pDeQuoted := pRet; //Needed to avoid changing insertion point + // Copy entire field but not more than maximum field length: + // (We can mess with pStr now; the next loop will reset it after + // pStrEnd): + while (pstr < pStrEnd) and (pDeQuoted-pRet <= FieldMaxSize) do + begin + if pStr^ = Quote then inc(pStr);// skip first quote + pDeQuoted^ := pStr^; + inc(pStr); + inc(pDeQuoted); + end; + end + else + begin + if (p > FieldMaxSize) then + p := FieldMaxSize; + Move(pStr[0], pRet[0], p); + end; + + Inc(pRet, FieldMaxSize); + + // Move the end of field position past quotes and delimiters + // ready for processing the next field + if (pStrEnd[0] = Quote) then + while Boolean(Byte(pStrEnd[0])) and (pStrEnd[0] <> Delimiter) do + Inc(pStrEnd); + + if (pStrEnd[0] = Delimiter) then + Inc(pStrEnd); + end; + + Result := ret; +end; + +function TSdfDataSet.BufToStore(Buffer: TRecordBuffer): String; +const + QuoteDelimiter='"'; +var + Str : String; + p, i : Integer; + QuoteMe: boolean; +begin + Result := ''; + p := 1; + for i := 0 to FieldDefs.Count - 1 do + begin + QuoteMe:=false; + Str := Trim(Copy(pansichar(Buffer), p, FieldDefs[i].Size)); + Inc(p, FieldDefs[i].Size); + if FFMultiLine then + begin + // If multiline enabled, quote whenever we find carriage return or linefeed + if (not QuoteMe) and (StrScan(PChar(Str), #10) <> nil) then QuoteMe:=true; + if (not QuoteMe) and (StrScan(PChar(Str), #13) <> nil) then QuoteMe:=true; + end + else + begin + // If we don't allow multiline, remove all CR and LF because they mess with the record ends: + Str := StringReplace(Str, #10, '', [rfReplaceAll]); + Str := StringReplace(Str, #13, '', [rfReplaceAll]); + end; + // Check for any delimiters or quotes occurring in field text + if (not QuoteMe) then + if (StrScan(PChar(Str), FDelimiter) <> nil) or + (StrScan(PChar(Str), QuoteDelimiter) <> nil) then QuoteMe:=true; + if (QuoteMe) then + begin + Str := Stringreplace(Str, QuoteDelimiter, QuoteDelimiter+QuoteDelimiter, [rfReplaceAll]); + Str := QuoteDelimiter + Str + QuoteDelimiter; + end; + Result := Result + Str + FDelimiter; + end; + p := Length(Result); + while (p > 0) and (Result[p] = FDelimiter) do + begin + System.Delete(Result, p, 1); + Dec(p); + end; +end; + +procedure TSdfDataSet.SetDelimiter(Value : Char); +begin + CheckInactive; + FDelimiter := Value; +end; + +procedure TSdfDataSet.SetFirstLineAsSchema(Value : Boolean); +begin + CheckInactive; + FFirstLineAsSchema := Value; + FDataOffset:=Ord(FFirstLineAsSchema); +end; + +procedure TSdfDataSet.SetMultiLine(const Value: Boolean); +begin + FFMultiLine:=Value; +end; +{ + +//----------------------------------------------------------------------------- +// This procedure is used to register this component on the component palette +//----------------------------------------------------------------------------- +procedure Register; +begin + RegisterComponents('Data Access', [TFixedFormatDataSet]); + RegisterComponents('Data Access', [TSdfDataSet]); +end; +} +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/pngcomn.pp b/mseide-msegui/lib/common/fpccompatibility/pngcomn.pp new file mode 100644 index 0000000..ec2f7ef --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/pngcomn.pp @@ -0,0 +1,88 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 2003 by the Free Pascal development team + + PNG reader/writer common code. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + **********************************************************************} +//modified 2013 by Martin Schreiber + +{$mode objfpc}{$h+} +unit PNGcomn; + +interface + +uses SysUtils, FPImage, FPImgCmn; + +type + + PNGImageException = class (FPImageException); + + TChunkTypes = ( + ctIHDR, ctcHRM, ctgAMA, ctsBIT, + ctPLTE, ctbKGD, cthIST, cttRNS, + ctoFFs, ctpHYs, ctIDAT, cttIME, + ctsCAL, cttEXt, ctzTXt, ctIEND, + ctsRGB, ctiCCP, ctiTXt, ctsPLT, + ctUnknown + ); + + EightLong = array[0..7] of longword; + TChunkCode = array[0..3] of char; + + TChunk = record + acapacity, alength, CRC : longword; + ReadType : TChunkCode; + data : PByteArray; + aType : TChunkTypes; + end; + + TChunkHeader = record + CLength : longword; + CType : TChunkCode; + end; + + THeaderChunk = record + Width, height : longword; + BitDepth, ColorType, Compression, Filter, Interlace : byte; + end; + +const + + Signature : Array[0..7] of Byte = ($89, $50, $4E, $47, $0D, $0A, $1A, $0A); + + MaxChunkLength = $7FFFFFFF; + All1Bits : longword = $FFFFFFFF; + + ChunkTypes : array[TChunkTypes] of TChunkCode = ( + 'IHDR', 'cHRM', 'gAMA', 'sBIT', + 'PLTE', 'bKGD', 'hIST', 'tRNS', + 'oFFs', 'pHYs', 'IDAT', 'tIME', + 'sCAL', 'tEXt', 'zTXt', 'IEND', + 'sRGB', 'iCCP', 'iTXt', 'sPLT', + 'Unkn' + ); + + ChunkAncillary = $10000000; + ChunkPrivate = $00100000; + ChunkReserved = $00001000; + ChunkSafeCopy = $00000010; + + + StartRow : Array[0..7] of Integer = (0, 0, 0, 4, 0, 2, 0, 1); + StartCol : Array[0..7] of Integer = (0, 0, 4, 0, 2, 0, 1, 0); + RowInc : Array[0..7] of Integer = (1, 8, 8, 8, 4, 4, 2, 2); + ColInc : Array[0..7] of Integer = (1, 8, 8, 4, 4, 2, 2, 1); + BlockHght : Array[0..7] of Integer = (1, 8, 8, 4, 4, 2, 2, 1); + BlockWdth : Array[0..7] of Integer = (1, 8, 4, 4, 2, 2, 1, 1); + +implementation + +end. diff --git a/mseide-msegui/lib/common/fpccompatibility/zstream.pas b/mseide-msegui/lib/common/fpccompatibility/zstream.pas new file mode 100644 index 0000000..48019fd --- /dev/null +++ b/mseide-msegui/lib/common/fpccompatibility/zstream.pas @@ -0,0 +1,428 @@ +unit zstream; + +{********************************************************************** + This file is part of the Free Pascal free component library. + + Copyright (c) 2007 by Daniel Mantione + member of the Free Pascal development team + + Implements a Tstream descendents that allow you to read and write + compressed data according to the Deflate algorithm described in + RFC1951. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + **********************************************************************} +//modified 2013 by Martin Schreiber + +{$ifdef FPC}{$mode objfpc}{$endif} + +{***************************************************************************} + interface +{***************************************************************************} + +uses classes,mclasses, + {$ifdef FPC}zbase,gzio{$else}zbase_del,gzio_del{$endif}; + +type + Tcompressionlevel=( + clnone, {Do not use compression, just copy data.} + clfastest, {Use fast (but less) compression.} + cldefault, {Use default compression} + clmax {Use maximum compression} + ); + + Tgzopenmode=( + gzopenread, {Open file for reading.} + gzopenwrite {Open file for writing.} + ); + + Tcustomzlibstream=class(Townerstream) + protected + Fstream:z_stream; + Fbuffer:pointer; + Fonprogress:Tnotifyevent; + procedure progress(sender:Tobject); + property onprogress:Tnotifyevent read Fonprogress write Fonprogress; + public + constructor create(stream:Tstream); + destructor destroy;override; + end; + + Tcompressionstream=class(Tcustomzlibstream) + protected + raw_written,compressed_written:longint; + public + constructor create(level:Tcompressionlevel; + dest:Tstream; + Askipheader:boolean=false); + destructor destroy;override; + function write(const buffer;count:longint):longint;override; + procedure flush; + function get_compressionrate:single; + property OnProgress; + end; + + Tdecompressionstream=class(Tcustomzlibstream) + protected + raw_read,compressed_read:longint; + skipheader:boolean; + procedure reset; + function GetPosition() : Int64; override; + public + constructor create(Asource:Tstream;Askipheader:boolean=false); + destructor destroy;override; + function read(var buffer;count:longint):longint;override; + function seek(offset:longint;origin:word):longint;override; + function get_compressionrate:single; + property OnProgress; + end; + + TGZFileStream = Class(TStream) + protected + Fgzfile:gzfile; + Ffilemode:Tgzopenmode; + public + constructor create(filename:ansistring;filemode:Tgzopenmode); + function read(var buffer;count:longint):longint;override; + function write(const buffer;count:longint):longint;override; + function seek(offset:longint;origin:word):longint;override; + destructor destroy;override; + end; + + Ezliberror=class(Estreamerror) + end; + + Egzfileerror=class(Ezliberror) + end; + + Ecompressionerror=class(Ezliberror) + end; + + Edecompressionerror=class(Ezliberror) + end; + +{***************************************************************************} + implementation +{***************************************************************************} + +uses {$ifdef FPC}zdeflate,zinflate{$else}zdeflate_del,zinflate_del{$endif}; + +const bufsize=16384; {Size of the buffer used for temporarily storing + data from the child stream.} + +resourcestring Sgz_open_error='Could not open gzip compressed file %s.'; + Sgz_read_only='Gzip compressed file was opened for reading.'; + Sgz_write_only='Gzip compressed file was opened for writing.'; + Sseek_failed='Seek in deflate compressed stream failed.'; + +constructor Tcustomzlibstream.create(stream:Tstream); + +begin + assert(stream<>nil); + inherited create(stream); + getmem(Fbuffer,bufsize); +end; + +procedure Tcustomzlibstream.progress(sender:Tobject); + +begin + if {$ifndef FPC}@{$endif}Fonprogress<>nil then + Fonprogress(sender); +end; + +destructor Tcustomzlibstream.destroy; + +begin + freemem(Fbuffer); + inherited destroy; +end; + +{***************************************************************************} + +constructor Tcompressionstream.create(level:Tcompressionlevel; + dest:Tstream; + Askipheader:boolean=false); + +var err,l:smallint; + +begin + l:= 0; + inherited create(dest); + Fstream.next_out:=Fbuffer; + Fstream.avail_out:=bufsize; + + case level of + clnone: + l:=Z_NO_COMPRESSION; + clfastest: + l:=Z_BEST_SPEED; + cldefault: + l:=Z_DEFAULT_COMPRESSION; + clmax: + l:=Z_BEST_COMPRESSION; + end; + + if Askipheader then + err:=deflateInit2(Fstream,l,Z_DEFLATED,-MAX_WBITS,DEF_MEM_LEVEL,0) + else + err:=deflateInit(Fstream,l); + if err<>Z_OK then + raise Ecompressionerror.create(zerror(err)); +end; + +function Tcompressionstream.write(const buffer;count:longint):longint; + +var err:smallint; + lastavail, + written:longint; + +begin + Fstream.next_in:=@buffer; + Fstream.avail_in:=count; + lastavail:=count; + while Fstream.avail_in<>0 do + begin + if Fstream.avail_out=0 then + begin + { Flush the buffer to the stream and update progress } + written:=source.write(Fbuffer^,bufsize); + inc(compressed_written,written); + inc(raw_written,lastavail-Fstream.avail_in); + lastavail:=Fstream.avail_in; + progress(self); + { reset output buffer } + Fstream.next_out:=Fbuffer; + Fstream.avail_out:=bufsize; + end; + err:=deflate(Fstream,Z_NO_FLUSH); + if err<>Z_OK then + raise Ecompressionerror.create(zerror(err)); + end; + inc(raw_written,lastavail-Fstream.avail_in); + write:=count; +end; + +function Tcompressionstream.get_compressionrate:single; + +begin + get_compressionrate:=100*compressed_written/raw_written; +end; + + +procedure Tcompressionstream.flush; + +var err:smallint; + written:longint; + +begin + {Compress remaining data still in internal zlib data buffers.} + repeat + if Fstream.avail_out=0 then + begin + { Flush the buffer to the stream and update progress } + written:=source.write(Fbuffer^,bufsize); + inc(compressed_written,written); + progress(self); + { reset output buffer } + Fstream.next_out:=Fbuffer; + Fstream.avail_out:=bufsize; + end; + err:=deflate(Fstream,Z_FINISH); + if err=Z_STREAM_END then + break; + if (err<>Z_OK) then + raise Ecompressionerror.create(zerror(err)); + until false; + if Fstream.avail_outZ_OK then + raise Ecompressionerror.create(zerror(err)); +end; + +function Tdecompressionstream.read(var buffer;count:longint):longint; + +var err:smallint; + lastavail:longint; + +begin + Fstream.next_out:=@buffer; + Fstream.avail_out:=count; + lastavail:=count; + while Fstream.avail_out<>0 do + begin + if Fstream.avail_in=0 then + begin + {Refill the buffer.} + Fstream.next_in:=Fbuffer; + Fstream.avail_in:=source.read(Fbuffer^,bufsize); + inc(compressed_read,Fstream.avail_in); + inc(raw_read,lastavail-Fstream.avail_out); + lastavail:=Fstream.avail_out; + progress(self); + end; + err:=inflate(Fstream,Z_NO_FLUSH); + if err=Z_STREAM_END then + break; + if err<>Z_OK then + raise Edecompressionerror.create(zerror(err)); + end; + if err=Z_STREAM_END then + dec(compressed_read,Fstream.avail_in); + inc(raw_read,lastavail-Fstream.avail_out); + read:=count-Fstream.avail_out; +end; + +procedure Tdecompressionstream.reset; + +var err:smallint; + +begin + source.seek(-compressed_read,sofromcurrent); + raw_read:=0; + compressed_read:=0; + inflateEnd(Fstream); + if skipheader then + err:=inflateInit2(Fstream,-MAX_WBITS) + else + err:=inflateInit(Fstream); + if err<>Z_OK then + raise Edecompressionerror.create(zerror(err)); +end; + +function Tdecompressionstream.GetPosition() : Int64; +begin + GetPosition := raw_read; +end; + +function Tdecompressionstream.seek(offset:longint;origin:word):longint; + +var c:longint; + +begin + if (origin=sofrombeginning) or + ((origin=sofromcurrent) and (offset+raw_read>=0)) then + begin + if origin = sofromcurrent then + seek := raw_read + offset + else + seek := offset; + + if origin=sofrombeginning then + dec(offset,raw_read); + if offset<0 then + begin + inc(offset,raw_read); + reset; + end; + while offset>0 do + begin + c:=offset; + if c>bufsize then + c:=bufsize; + c:=read(Fbuffer^,c); + dec(offset,c); + end; + end + else + raise Edecompressionerror.create(Sseek_failed); +end; + +function Tdecompressionstream.get_compressionrate:single; + +begin + get_compressionrate:=100*compressed_read/raw_read; +end; + + +destructor Tdecompressionstream.destroy; + +begin + inflateEnd(Fstream); + inherited destroy; +end; + + +{***************************************************************************} + +constructor Tgzfilestream.create(filename:ansistring;filemode:Tgzopenmode); + +begin + if filemode=gzopenread then + Fgzfile:=gzopen(filename,'rb') + else + Fgzfile:=gzopen(filename,'wb'); + Ffilemode:=filemode; + if Fgzfile=nil then + raise Egzfileerror.createfmt(Sgz_open_error,[filename]); +end; + +function Tgzfilestream.read(var buffer;count:longint):longint; + +begin + if Ffilemode=gzopenwrite then + raise Egzfileerror.create(Sgz_write_only); + read:=gzread(Fgzfile,@buffer,count); +end; + +function Tgzfilestream.write(const buffer;count:longint):longint; + +begin + if Ffilemode=gzopenread then + raise Egzfileerror.create(Sgz_write_only); + write:=gzwrite(Fgzfile,@buffer,count); +end; + +function Tgzfilestream.seek(offset:longint;origin:word):longint; + +begin + result:= gzseek(Fgzfile,offset,origin); + if result = -1 then + raise egzfileerror.create(Sseek_failed); +end; + +destructor Tgzfilestream.destroy; + +begin + gzclose(Fgzfile); + inherited destroy; +end; + +end. diff --git a/mseide-msegui/lib/common/graphics/msebitmap.pas b/mseide-msegui/lib/common/graphics/msebitmap.pas new file mode 100644 index 0000000..36d38cb --- /dev/null +++ b/mseide-msegui/lib/common/graphics/msebitmap.pas @@ -0,0 +1,3863 @@ +{ MSEgui Copyright (c) 1999-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msebitmap; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses,msegraphics,msetypes,msestrings,mseinterfaces, + msegraphutils,mseclasses,mseglob,sysutils,mseguiglob; + +const + defaultimagelistwidth = 16; + defaultimagelistheight = 16; + defaultimagelistsize: sizety = (cx: defaultimagelistwidth; + cy: defaultimagelistheight); + +type +{ + imagebufferinfoty = record + image: imagety; + mask: imagety; + end; +} + tbitmapcomp = class; + + tbitmap = class(tsimplebitmap) + private + fimage: imagety; + fonchange: notifyeventty; + falignment: alignmentsty; + fopacity: colorty; + fnochange: integer; + function getscanline(index: integer): pointer; + procedure checkimage(const bgr: boolean); + procedure getimage; + procedure putimage; + function getpixel(const index: pointty): colorty; + procedure setpixel(const index: pointty; const value: colorty); + function getpixels(const x,y: integer): colorty; + procedure setpixels(const x,y: integer; const value: colorty); + function checkindex(const index: pointty): integer; overload; + function checkindex(const x,y: integer): integer; overload; + //returns index in imagety pixels for bmk_mono and bmk_rgb, + //byte offset for bmk_gray + procedure setalignment(const Value: alignmentsty); + procedure setopacity(avalue: colorty); + procedure updatealignment(const dest,source: rectty; + var alignment: alignmentsty; out newdest,newsource: rectty; + out tileorigin: pointty); + //expand copy areas in order to avoid missing pixels by position rounding + + procedure setcolorbackground(const Value: colorty); + procedure setcolorforeground(const Value: colorty); + procedure readtransparency(reader: treader); + protected + procedure getcanvasimage(const bgr: boolean; + var aimage: maskedimagety); override; + procedure setsize(const Value: sizety); override; + function getasize: sizety; virtual; + procedure destroyhandle; override; + procedure createhandle(copyfrom: pixmapty); override; + function getsource: tbitmapcomp; virtual; + procedure assign1(const source: tsimplebitmap; const docopy: boolean); override; + //calls change + procedure dochange; virtual; + procedure defineproperties(filer: tfiler); override; + function getimageref(out aimage: imagety): boolean; + //true if buffer must be destroyed + procedure setkind(const avalue: bitmapkindty); override; + public +// constructor create(const amonochrome: boolean; +// const agdifuncs: pgdifunctionaty = nil); + //nil -> default + constructor create(const akind: bitmapkindty; + const agdifuncs: pgdifunctionaty = nil); + //nil -> default + + procedure savetoimage(out aimage: imagety); + procedure loadfromimage(const aimage: imagety); + procedure assign(source: tpersistent); override; + procedure change; + procedure beginupdate; + procedure endupdate; + procedure loaddata(const asize: sizety; const data: pbyte; + const msbitfirst: boolean = false; const dwordaligned: boolean = false; + const bottomup: boolean = false); virtual; //calls change + function hasimage: boolean; + procedure paint(const acanvas: tcanvas; const dest: rectty; + const asource: rectty; aalignment: alignmentsty = []; + const acolorforeground: colorty = cl_default; + const acolorbackground: colorty = cl_default; + //used for monochrome bitmaps, + //cl_default-> acanvas.color, acanvas.colorbackground + const aopacity: colorty = cl_default + //cl_default-> self.opacity + ); + overload; + procedure paint(const acanvas: tcanvas; const dest: pointty; + const acolorforeground: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default + ); overload; + //useses self.size and self.alignment + procedure paint(const acanvas: tcanvas; const dest: pointty; + const aalignment: alignmentsty; + const acolorforeground: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default); overload; + //useses self.size + procedure paint(const acanvas: tcanvas; const dest: rectty; + const acolorforeground: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default); overload; + //useses self.size and self.alignment + procedure paint(const acanvas: tcanvas; const dest: rectty; + const aalignment: alignmentsty; + const acolorforeground: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default); overload; + //useses self.size + + procedure init(const acolor: colorty); override; + function compressdata: longwordarty; + procedure decompressdata(const asize: sizety; const adata: longwordarty); + property pixel[const index: pointty]: colorty read getpixel write setpixel; + property pixels[const x,y: integer]: colorty read getpixels write setpixels; + property scanline[index: integer]: pointer read getscanline; + property scanhigh: integer read fscanhigh; + //max index in scanline[0] ??? + property scanlinestep: integer read fscanlinestep; //bytes + property colorforeground: colorty read fcolorforeground write setcolorforeground default cl_black; + //used for monochrome -> color conversion + property colorbackground: colorty read fcolorbackground write setcolorbackground default cl_white; + //used for monochrome -> color conversion, + //colorbackground for color -> monochrome conversion + property alignment: alignmentsty read falignment write setalignment default []; + property opacity: colorty read fopacity write setopacity default cl_none; + property onchange: notifyeventty read fonchange write fonchange; + end; + + imageformatty = (imfor_default); + imageinfoty = (iminf_monochrome,iminf_masked,iminf_colormask, + iminf_gray,iminf_graymask); + imageinfosty = set of imageinfoty; + imageheaderty = packed record + format: longword; //imageformatty; + info: longword; //imageinfosty; + width: integer; + height: integer; + datasize: integer; + reserve: array[0..7] of longword; + end; +{ + tbitmapcanvas = class(tcanvas) + protected + function getimage(const bgr: boolean): imagety; override; + public + constructor create(const user: tbitmap); + end; +} + bitmapoptionty = (bmo_monochrome,bmo_gray, + bmo_masked,bmo_graymask,bmo_colormask, + bmo_storeorigformat, //needs mseformat*read unit at runtime + //in uses + bmo_runtimeformatdata); //do not clear origformatdata after + //load at runtime + bitmapoptionsty = set of bitmapoptionty; +const + bmokindoptions = [bmo_monochrome,bmo_gray]; + bmomaskkindoptions = [bmo_graymask,bmo_colormask]; + +type + townedbitmap = class(tbitmap) + private + fowner: tbitmap; + protected + procedure dochange; override; + public + constructor create(const aowner: tbitmap; const akind: bitmapkindty; + const agdifuncs: pgdifunctionaty = nil); + end; + + tmaskedbitmap = class(tbitmap,iobjectlink) + private + ftransparentcolor: colorty; + fsource: tbitmapcomp; + fobjectlinker: tobjectlinker; + fmaskcolorforeground,fmaskcolorbackground: colorty; + forigformat: string; + forigformatdata: string; + fmask_source: tbitmapcomp; + procedure checkmask(); + procedure freemask(); + procedure settransparentcolor(const Value: colorty); + procedure setmask(const Value: tbitmap); + function getobjectlinker: tobjectlinker; + procedure setsource(const Value: tbitmapcomp); + function getmasked(): boolean; + procedure setmasked(const Value: boolean); + procedure readimage(stream: tstream); + procedure writeimage(stream: tstream); + procedure readimagedata(stream: tstream); + procedure writeimagedata(stream: tstream); + function getmask1(): tbitmap; + function getoptions: bitmapoptionsty; + procedure setoptions(const avalue: bitmapoptionsty); + function getcolormask(): boolean; + procedure setcolormask(const avalue: boolean); + procedure setorigformatdata(const avalue: string); + function getmaskkind(): bitmapkindty; + procedure setmaskkind(const avalue: bitmapkindty); + function getgraymask(): boolean; + procedure setgraymask(const avalue: boolean); + procedure setmask_source(const avalue: tbitmapcomp); + procedure setmaskpos(const avalue: pointty); + procedure setmask_x(const avalue: int32); + procedure setmask_y(const avalue: int32); + protected + foptions: bitmapoptionsty; + fmask: tbitmap; + fmask_pos: pointty; + procedure setkind(const avalue: bitmapkindty); override; + function gettranspcolor(): colorty; +// procedure setmonochrome(const avalue: boolean); override; + function getasize: sizety; override; + procedure createmask(const akind: bitmapkindty); virtual; + function getconverttomonochromecolorbackground: colorty; override; + procedure destroyhandle; override; + procedure setsize(const Value: sizety); override; + function writedata(const ancestor: tmaskedbitmap): boolean; + procedure defineproperties(filer: tfiler); override; + procedure objectevent(const sender: tobject; const event: objecteventty); + function getmask(out apos: pointty): tsimplebitmap; override; + function getsource: tbitmapcomp; override; + procedure assign1(const source: tsimplebitmap; const docopy: boolean); override; + procedure getcanvasimage(const bgr: boolean; + var aimage: maskedimagety); override; + //iobjectlink + procedure link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); + procedure unlink(const source,dest: iobjectlink; valuepo: pointer = nil); + procedure objevent(const sender: iobjectlink; const event: objecteventty); + function getinstance: tobject; + function doloadfromstream(const atry: boolean; + const stream: tstream; + const format: string; const params: array of const): string; + function doloadfromfile(const atry: boolean; + const filename: filenamety; + const format: string; const params: array of const): string; + function doloadfromstring(const atry: boolean; + const avalue: string; + const format: string; const params: array of const): string; + public + constructor create(const akind: bitmapkindty; + const agdifuncs: pgdifunctionaty = nil); + //nil -> default + destructor destroy; override; + procedure clear; override; +// class procedure freeimageinfo(var ainfo: maskedimagety); + procedure loadfrommaskedimage(const aimage: maskedimagety); + procedure savetomaskedimage(out aimage: maskedimagety); +// procedure loadfromimagebuffer(const abuffer: maskedimagety); +// procedure savetoimagebuffer(out abuffer: maskedimagety); + function bitmap: tmaskedbitmap; //self if source = nil + + procedure releasehandle; override; + procedure acquirehandle; override; + procedure initmask; + procedure stretch(const dest: tmaskedbitmap; + const aalignment: alignmentsty = + [al_stretchx,al_stretchy,al_intpol]); overload; + procedure stretch(const source: rectty; const dest: tmaskedbitmap; + const aalignment: alignmentsty = + [al_stretchx,al_stretchy,al_intpol]); overload; + procedure remask; //recalc mask + procedure automask; //transparentcolor is bottomright pixel + + + function loadfromstring(const avalue: string; const format: string; + //'' = any + const params: array of const): string; + //returns format name + function loadfromstring(const avalue: string): string; + //returns format name + function loadfromstream(const stream: tstream; const format: string; + //'' = any + const params: array of const): string; + //returns format name + function loadfromstream(const stream: tstream): string; + //returns format name + + function loadfromfile(const filename: filenamety; const format: string; + //'' = any + const params: array of const): string; + //returns format name + function loadfromfile(const filename: filenamety): string; + //returns format name + + function tryloadfromstring(const avalue: string; const format: string; + //'' = any + const params: array of const): string; + //returns format name, '' = unknown/not supported + //exception in case of read error + function tryloadfromstring(const avalue: string): string; + //returns format name, '' = unknown/not supported + //exception in case of read error + function tryloadfromstream(const stream: tstream; const format: string; + //'' = any + const params: array of const): string; + //returns format name, '' = unknown/not supported + //exception in case of read error + function tryloadfromstream(const stream: tstream): string; + //returns format name, '' = unknown/not supported + //exception in case of read error + function tryloadfromfile(const filename: filenamety; const format: string; + //'' = any + const params: array of const): string; + //returns format name, '' = unknown/not supported + //exception in case of read error + function tryloadfromfile(const filename: filenamety): string; + //returns format name, '' = unknown/not supported + //exception in case of read error + + procedure writetostring(out avalue: string; const format: string; + const params: array of const); overload; + function writetostring(const format: string; + const params: array of const): string; overload; + procedure writetostream(const stream: tstream; const format: string; + const params: array of const); + procedure writetofile(const filename: filenamety; const format: string; + const params: array of const); + property mask: tbitmap read getmask1 write setmask; + property maskkind: bitmapkindty read getmaskkind + write setmaskkind default bmk_mono; + property masked: boolean read getmasked write setmasked default false; + property graymask: boolean read getgraymask write setgraymask default false; + property colormask: boolean read getcolormask write setcolormask default false; + property maskcolorforeground: colorty read fmaskcolorforeground + write fmaskcolorforeground default $ffffff; + //used to init colormask + property maskcolorbackground: colorty read fmaskcolorbackground + write fmaskcolorbackground default $000000; //max transparent + //used to convert monchrome mask to colormask + property mask_pos: pointty read fmask_pos write setmaskpos; + property origformatdata: string read forigformatdata write setorigformatdata; + published + property transparentcolor: colorty read ftransparentcolor + write settransparentcolor default cl_default; + //cl_default ->bottom left pixel + property options: bitmapoptionsty read getoptions write setoptions default []; + property source: tbitmapcomp read fsource write setsource; + property mask_source: tbitmapcomp read fmask_source write setmask_source; + property mask_x: int32 read fmask_pos.x write setmask_x default 0; + property mask_y: int32 read fmask_pos.y write setmask_y default 0; + property origformat: string read forigformat write forigformat; + property colorforeground; + property colorbackground; + property alignment; + property opacity; + end; + + tcenteredbitmap = class(tmaskedbitmap) + public + constructor create(const akind: bitmapkindty; + const agdifuncs: pgdifunctionaty = nil); + published + property alignment default [al_xcentered,al_ycentered]; + end; + + tbitmapcomp = class(tmsecomponent) + private + fbitmap: tmaskedbitmap; + fonchange: notifyeventty; + procedure setbitmap(const Value: tmaskedbitmap); + procedure change(const sender: tobject); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property bitmap: tmaskedbitmap read fbitmap write setbitmap; + property onchange: notifyeventty read fonchange write fonchange; + end; + + timagelist = class(tmsecomponent) + private + fsize: sizety; + fcolcount,frowcount: integer; +// fbitmap: tmaskedbitmap; + fbitmaps: array of tmaskedbitmap; + fcount: integer; + fupdating: integer; + fonchange: notifyeventty; +// fkind: bitmapkindty; + findexlookup: msestring; +// fcornermask: msestring; + fcornermask_topleft: msestring; + fcornermask_bottomleft: msestring; + fcornermask_bottomright: msestring; + fcornermask_topright: msestring; + fneedscornermaskcheck: boolean; + fhascornermask: boolean; + procedure setsize(const avalue: sizety); +// function getmonochrome: boolean; +// procedure setmonochrome(const Value: boolean); + procedure setcount(const Value: integer); + function getmasked: boolean; + procedure setmasked(const Value: boolean); + function gettransparentcolor: colorty; + procedure settransparentcolor(avalue: colorty); + procedure setheight(const Value: integer); + procedure setwidth(const Value: integer); +// procedure setbitmap(const Value: tmaskedbitmap); + procedure copyimages(const image: tmaskedbitmap; const destindex: integer; + const aversion: int32); + function getcolormask: boolean; + procedure setcolormask(const avalue: boolean); + function getkind: bitmapkindty; + procedure setkind(const avalue: bitmapkindty); + procedure setmaskkind(const avalue: bitmapkindty); + function getmaskkind: bitmapkindty; + function getgraymask: boolean; + procedure setgraymask(const avalue: boolean); + procedure readmasked(reader: treader); + procedure readcolormask(reader: treader); + procedure readmonochrome(reader: treader); + procedure readcornermask(reader: treader); + function getoptions: bitmapoptionsty; + procedure setoptions(const avalue: bitmapoptionsty); + procedure setindexlookup(const avalue: msestring); + procedure setcornermask_topleft(const avalue: msestring); + procedure setcornermask_bottomleft(const avalue: msestring); + procedure setcornermask_bottomright(const avalue: msestring); + procedure setcornermask_topright(const avalue: msestring); + function getversioncount: int32; + procedure setversioncount(const avalue: int32); + function getbitmap: tmaskedbitmap; + procedure setversiondefault(avalue: int32); + function getbitmaps(aindex: int32): tmaskedbitmap; + protected + fversionhigh: int32; //versioncount - 1 + fversiondefault: int32; //use for painting + fcornermaskmaxtopleft: int32; //biggest value of cornermask + fcornermaskmaxbottomleft: int32; //biggest value of cornermask + fcornermaskmaxbottomright: int32; //biggest value of cornermask + fcornermaskmaxtopright: int32; //biggest value of cornermask + procedure updateversionindex(var aindex: int32); + function indextoorg(index: integer): pointty; + procedure change; + procedure defineproperties(filer: tfiler); override; + procedure cornermaskchanged(); + procedure loaded() override; + procedure writeimage(stream: tstream); + procedure readimage(stream: tstream); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + + procedure beginupdate; + procedure endupdate; + + procedure clear; + procedure deleteimage(const index: integer); + + //aimage-1 -> use versiondefault + + procedure moveimage(const fromindex: integer; const toindex: integer; + aversion: int32 = -1); + procedure setimage(index: integer; image: tmaskedbitmap; + const source: rectty; aalignment: alignmentsty = []; + aversion: int32 = -1); + procedure setimage(index: integer; image: tmaskedbitmap; + //nil -> empty item + const aalignment: alignmentsty = []; aversion: int32 = -1); + procedure getimage(const index: integer; const dest: tmaskedbitmap; + aversion: int32 = -1); + function addimage(const image: tmaskedbitmap; //nil -> empty item + const aalignment: alignmentsty = []{; + const aversion: int32 = 0}): integer; + + procedure clipcornermask(const canvas: tcanvas; + const arect: rectty; const ahiddenedges: edgesty); + procedure paint(const acanvas: tcanvas; const index: integer; + const dest: pointty; const acolor: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default; aversion: int32 = -1); + procedure paint(const acanvas: tcanvas; const index: integer; + const dest: rectty; const alignment: alignmentsty = []; + const acolor: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default; aversion: int32 = -1); + procedure paint(const acanvas: tcanvas; const index: integer; + const dest: rectty; source: rectty; + const alignment: alignmentsty = []; + const acolor: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default; aversion: int32 = -1); + procedure paintlookup(const acanvas: tcanvas; const index: integer; + const dest: pointty; const acolor: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default; aversion: int32 = -1); + procedure paintlookup(const acanvas: tcanvas; const index: integer; + const dest: rectty; const alignment: alignmentsty = []; + const acolor: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default; aversion: int32 = -1); + procedure paintlookup(const acanvas: tcanvas; const index: integer; + const dest: rectty; source: rectty; + const alignment: alignmentsty = []; + const acolor: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default; aversion: int32 = -1); + function lookup(const aindex: int32): int32; + + procedure assign(sender: tpersistent); override; + + property size: sizety read fsize write setsize; +// property bitmap: tmaskedbitmap read fbitmap write setbitmap; + property bitmap: tmaskedbitmap read getbitmap; + property bitmaps[const aindex: int32]: tmaskedbitmap read getbitmaps; + + property kind: bitmapkindty read getkind write setkind default bmk_rgb; + property maskkind: bitmapkindty read getmaskkind + write setmaskkind default bmk_mono; +{ + property monochrome: boolean read getmonochrome + write setmonochrome default false; +} + property masked: boolean read getmasked write setmasked default true; + property graymask: boolean read getgraymask write setgraymask default false; + property colormask: boolean read getcolormask + write setcolormask default false; + property hascornermask: boolean read fhascornermask; + published + property versioncount: int32 read getversioncount + write setversioncount default 1; //first! + property versiondefault: int32 read fversiondefault + write setversiondefault default 0; + property width: integer read fsize.cx + write setwidth default defaultimagelistwidth; + property height: integer read fsize.cy + write setheight default defaultimagelistheight; + property options: bitmapoptionsty read getoptions + write setoptions default [bmo_masked]; + property transparentcolor: colorty read gettransparentcolor + write settransparentcolor default cl_none; + property count: integer read fcount write setcount default 0; + //last! + property indexlookup: msestring read findexlookup write setindexlookup; + //array of int16 + property cornermask_topleft: msestring read fcornermask_topleft + write setcornermask_topleft; + property cornermask_bottomleft: msestring read fcornermask_bottomleft + write setcornermask_bottomleft; + property cornermask_bottomright: msestring read fcornermask_bottomright + write setcornermask_bottomright; + property cornermask_topright: msestring read fcornermask_topright + write setcornermask_topright; + //array of int16, used in tframe for clipping corners of client area + //cornermask[n] = number of clipped pixels from edge of row n. + property onchange: notifyeventty read fonchange write fonchange; + end; + + iimagelistinfo = interface(inullinterface)[miid_iimagelistinfo] + function getimagelist: timagelist; + end; + + tformatstream = class + private + fstream: tstream; + fformatname: string; + fseekpos: integer; + procedure setpos(const Value: integer); + public + constructor create(stream: tstream; formatname: string); + procedure formaterror; + procedure read(var dest; count: integer); + procedure seek(count: integer); + procedure resetpos(apos: integer = 0); + property pos: integer read fseekpos write setpos; + end; + +implementation +uses + mseguiintf,msebits,msestream,mseevent,msesys,msearrayutils,msegraphicstream, + rtlconsts + {$ifndef FPC},classes_del{$endif}; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tsimplebitmap1 = class(tsimplebitmap); + tcanvas1 = class(tcanvas); + twriter1 = class(twriter); +type + tbitmap1 = class(tbitmap); + +procedure freeimage(var aimage: imagety); +begin + if aimage.pixels <> nil then begin + gui_freeimagemem(aimage.pixels); + fillchar(aimage,sizeof(aimage),0); + end; +end; + +procedure freeimage(var aimage: maskedimagety); +begin + freeimage(aimage.image); + freeimage(aimage.mask); +end; + +{ tformatstream } + +constructor tformatstream.create(stream: tstream; formatname: string); +begin + fstream:= stream; + fformatname:= formatname; +end; + +procedure tformatstream.formaterror; +begin + raise egraphicformat.create('Invalid file format '+fformatname); +end; + +procedure tformatstream.read(var dest; count: integer); +begin + inc(fseekpos,count); + fstream.read(dest,count); +end; + +procedure tformatstream.resetpos(apos: integer); +begin + fseekpos:= apos; +end; + +procedure tformatstream.seek(count: integer); +begin + inc(fseekpos,count); + fstream.seek(count,sofromcurrent); +end; + +procedure tformatstream.setpos(const Value: integer); +begin + seek(value-fseekpos); +end; + +{ tbitmap } + +constructor tbitmap.create(const akind: bitmapkindty; + const agdifuncs: pgdifunctionaty = nil); +begin + fopacity:= cl_none; + inherited; +end; + +procedure tbitmap.assign1(const source: tsimplebitmap; const docopy: boolean); +var + bo1: boolean; +begin + if source is tbitmap then begin + bo1:= tbitmap(source).hasimage and (tbitmap(source).fimage.pixels = nil) and + (getgdiintf <> tbitmap(source).getgdiintf); + with tbitmap(source) do begin + if (fimage.pixels <> nil) or bo1 then begin + self.clear; + if bo1 then begin + savetoimage(self.fimage); + end + else begin + self.fimage:= fimage; + self.fimage.pixels:= gui_allocimagemem(fimage.length); + move(fimage.pixels^,self.fimage.pixels^,fimage.length*sizeof(longword)); + //get a copy + end; + self.fsize:= self.fimage.size; + self.fkind:= fkind; + self.updatescanline(); + { + if monochrome then begin + include(self.fstate,pms_monochrome); + end + else begin + exclude(self.fstate,pms_monochrome); + end; + } + end + else begin + inherited; + end; + end; + end + else begin + inherited; + end; + change; +end; + +procedure tbitmap.loaddata(const asize: sizety; const data: pbyte; + const msbitfirst: boolean = false; const dwordaligned: boolean = false; + const bottomup: boolean = false); +var + sourcerowstep,rowstep: integer; + ps,pd: pbyteaty; + int1,int2,int3: integer; +begin + if fkind <> bmk_mono then begin + gdierror(gde_notmonochrome,self); + end; + destroyhandle; + fsize:= asize; + if (asize.cx > 0) and (asize.cy > 0) then begin + allocimage(fimage,size,bmk_mono); + with fimage do begin +// monochrome:= true; +// size:= asize; +// rowstep:= (size.cx+31) div 32; //words +// length:= size.cy * rowstep; +// rowstep:= rowstep*4; //bytes + rowstep:= linebytes; +// pixels:= gui_allocimagemem(length); + if dwordaligned then begin + sourcerowstep:= rowstep; + end + else begin + sourcerowstep:= (asize.cx+7) div 8; + end; + int1:= asize.cy - 1; + int3:= sourcerowstep - 1; + if bottomup then begin + pd:= pointer(pchar(pixels) + int1*rowstep); + rowstep:= -rowstep; + end + else begin + pd:= pointer(pixels); + end; + ps:= pointer(data); + if msbitfirst then begin + for int1:= int1 downto 0 do begin + for int2:= int3 downto 0 do begin + pd^[int2]:= bitreverse[ps^[int2]]; + end; + inc(pbyte(ps),sourcerowstep); + inc(pbyte(pd),rowstep); + end; + end + else begin + for int1:= int1 downto 0 do begin + for int2:= int3 downto 0 do begin + pd^[int2]:= ps^[int2]; + end; + inc(pbyte(ps),sourcerowstep); + inc(pbyte(pd),rowstep); + end; + end; + end; + end; +// creategc; + change; +end; + +{ +procedure tbitmap.loaddata(const asize: sizety; data: pbyte; + msbitfirst: boolean = false; dwordaligned: boolean = false; + bottomup: boolean = false); +begin + if not monochrome then begin + gdierror(gde_notmonochrome,self); + end; + destroyhandle; + fsize:= asize; + gdi_lock; + fhandle:= gui_createbitmapfromdata(asize,data,msbitfirst,dwordaligned,bottomup); + gdi_unlock; + if fhandle = 0 then begin + gdierror(gde_pixmap); + end; + creategc; + change; +end; +} +procedure tbitmap.paint(const acanvas: tcanvas; const dest: rectty; + const asource: rectty; aalignment: alignmentsty = []; + const acolorforeground: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default); +var + bmp: tbitmap; + sourcebmp: tbitmapcomp; + amask: tsimplebitmap; + maskpos1: pointty; +// maskpx: pixmapty; +// maskgchandle: longword; + rect1,rect2: rectty; + po1: pointty; + col1,col2: colorty; + opa: colorty; + canvas2: tcanvas; + bmp1: tmaskedbitmap; + po2: prgbtripleaty; + int1,int2: integer; +begin + if aopacity = cl_default then begin + opa:= opacity; + end + else begin + opa:= aopacity; + end; + sourcebmp:= getsource; + amask:= getmask(maskpos1); + if sourcebmp <> nil then begin + bmp:= sourcebmp.fbitmap; +// if amask = nil then begin +// amask:= sourcebmp.fbitmap.getmask(maskpos1); +// end; + end + else begin + bmp:= self; + end; + with bmp do begin + if not isempty then begin + updatealignment(dest,asource,aalignment,rect1,rect2,po1); +// amask:= getmask(maskpos1); +// maskpx:= getmaskhandle(maskgchandle); + if (al_grayed in aalignment) and ((amask <> nil) or + (fkind = bmk_mono)) then begin + if (amask <> nil) and not (amask.kind = bmk_mono) then begin + //reduced contrast grayscale + bmp1:= tmaskedbitmap.create(bmk_rgb); + bmp1.colormask:= true; + bmp1.size:= rect2.size; + bmp1.canvas.copyarea(canvas,rect2,nullpoint); + bmp1.mask.canvas.copyarea(amask.canvas,rect2,nullpoint); + po2:= bmp1.scanline[0]; + for int1:= bmp1.scanhigh downto 0 do begin + with po2^[int1] do begin + int2:= (red+green+blue) div 8 + $80; + red:= int2; + green:= int2; + blue:= int2; + end; + end; + rect2.pos:= nullpoint; + tcanvas1(acanvas).internalcopyarea(bmp1.canvas,rect2, + rect1,acanvas.rasterop,cl_default,bmp1.mask,maskpos1, + aalignment,po1,opa); + bmp1.free; + end + else begin //shaddowed mask + if kind = bmk_mono then begin + canvas2:= canvas; + end + else begin + canvas2:= amask.canvas; + end; + with acanvas do begin + col1:= colorbackground; + col2:= color; + colorbackground:= cl_transparent; + color:= cl_white; + // copyarea(canvas2,rect2,addpoint(rect1.pos,makepoint(1,1)),acanvas.rasterop); + inc(rect1.x); + inc(rect1.y); + inc(po1.x); + inc(po1.y); + tcanvas1(acanvas).internalcopyarea(canvas2,rect2, + rect1,acanvas.rasterop,cl_default,amask,maskpos1, + aalignment,po1,opa); + color:= cl_dkgray; + // copyarea(canvas2,rect2,rect1.pos,acanvas.rasterop); + dec(rect1.x); + dec(rect1.y); + dec(po1.x); + dec(po1.y); + tcanvas1(acanvas).internalcopyarea(canvas2,rect2, + rect1,acanvas.rasterop,cl_default,amask,maskpos1, + aalignment,po1,opa); + color:= col2; + colorbackground:= col1; + end; + end; + end + else begin + if kind = bmk_mono then begin + col1:= acanvas.color; + col2:= acanvas.colorbackground; + if acolorforeground <> cl_default then begin + acanvas.color:= acolorforeground; + end + else begin + acanvas.color:= self.fcolorforeground; + end; + if acolorbackground <> cl_default then begin + acanvas.colorbackground:= acolorbackground; + end + else begin + acanvas.colorbackground:= self.fcolorbackground; + end; + tcanvas1(acanvas).internalcopyarea(bmp.canvas,rect2, + rect1,acanvas.rasterop,cl_default,amask,maskpos1, + aalignment,po1,opa); + acanvas.color:= col1; + acanvas.colorbackground:= col2; + end + else begin + tcanvas1(acanvas).internalcopyarea(bmp.canvas,rect2, + rect1,acanvas.rasterop,cl_default,amask,maskpos1, + aalignment,po1,opa); + end; + end; + end; + end; +end; + +procedure tbitmap.paint(const acanvas: tcanvas; const dest: rectty; + const acolorforeground: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default); +begin + with tcanvas1(canvas).fvaluepo^.origin do begin + paint(acanvas,dest,makerect(makepoint(-x,-y),getasize),falignment, + acolorforeground,acolorbackground,aopacity); + end; +end; + +procedure tbitmap.paint(const acanvas: tcanvas; const dest: rectty; + const aalignment: alignmentsty; + const acolorforeground: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default); +begin + with tcanvas1(canvas).fvaluepo^.origin do begin + paint(acanvas,dest,makerect(makepoint(-x,-y),getasize),aalignment, + acolorforeground,acolorbackground,aopacity); + end; +end; + +procedure tbitmap.paint(const acanvas: tcanvas; const dest: pointty; + const acolorforeground: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default); +begin + with tcanvas1(canvas).fvaluepo^.origin do begin + paint(acanvas,makerect(dest,fsize),makerect(makepoint(-x,-y),getasize), + falignment,acolorforeground,acolorbackground,aopacity); + end; +end; + +procedure tbitmap.paint(const acanvas: tcanvas; const dest: pointty; + const aalignment: alignmentsty; + const acolorforeground: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default); +begin + with tcanvas1(canvas).fvaluepo^.origin do begin + paint(acanvas,makerect(dest,getasize),makerect(makepoint(-x,-y),getasize), + aalignment,acolorforeground,acolorbackground,aopacity); + end; +end; + +procedure tbitmap.init(const acolor: colorty); +var + rgb: longword; + by1: byte; + int1: integer; +begin + if fimage.pixels = nil then begin + inherited; + end + else begin + rgb:= colortopixel(normalizeinitcolor(acolor)); + case fkind of + bmk_mono: begin + if odd(rgb xor colortopixel(cl_0)) then begin + by1:= $ff; + end + else begin + by1:= $00; + end; + fillchar(fimage.pixels^,fimage.length*sizeof(longword),by1); + end; + bmk_gray: begin + by1:= (integer(rgbtriplety(rgb).red)+integer(rgbtriplety(rgb).green)+ + integer(rgbtriplety(rgb).blue)) div 3; + fillchar(fimage.pixels^,fimage.length*sizeof(longword),by1); + end; + else begin + for int1:= 0 to fimage.length-1 do begin + fimage.pixels^[int1]:= rgb; + end; + end; + end; + end; + change; +end; +{ +procedure tbitmap.allocimagemem; +var + step: integer; +begin + if fimage.monochrome then begin + step:= (fsize.cx+31) div 32; + fimage.length:= step * fsize.cy; + end + else begin + step:= fsize.cx; + fimage.length:= fsize.cx * fsize.cy; + end; + if fimage.length > 0 then begin + fimage.pixels:= gui_allocimagemem(fimage.length); + end + else begin + fimage.pixels:= nil; + end; +end; +} +procedure tbitmap.getimage; +var + info1: drawinfoty; +begin + if fhandle <> 0 then begin + if fcanvas <> nil then begin + with tcanvas1(fcanvas),fdrawinfo.pixmapimage do begin + fillchar(image,sizeof(image),0); + pixmap:= fhandle; + gdi(gdf_pixmaptoimage); + fimage:= image; + end; + end + else begin + with info1,pixmapimage do begin + fillchar(image,sizeof(image),0); + gc.handle:= 0; + pixmap:= fhandle; + gdi_call(gdf_pixmaptoimage,info1,getgdiintf); + fimage:= image; + end; + end; + { + gdi_lock; + if fcanvas <> nil then begin + gdierrorlocked(gui_pixmaptoimage(fhandle,fimage, + tcanvas1(fcanvas).fdrawinfo.gc.handle)); + end + else begin + gdierrorlocked(gui_pixmaptoimage(fhandle,fimage,0)); + end; + } + end + else begin +// fimage.size:= fsize; +// fimage.monochrome:= monochrome; + allocimage(fimage,fsize,kind); + end; +end; + +procedure tbitmap.checkimage(const bgr: boolean); +begin + if fimage.pixels = nil then begin + getimage; + internaldestroyhandle; + end; + checkimagebgr(fimage,bgr); +end; + +procedure tbitmap.putimage; +var + info1: drawinfoty; +begin + checkimagebgr(fimage,false); + drawinfoinit(info1); + with info1,pixmapimage do begin + image:= fimage; + gc.handle:= 0; + gdi_call(gdf_imagetopixmap,info1,getgdiintf); + if error = gde_ok then begin + handle:= pixmap; +// fkind:= fimage.kind; //???necessary + { + if fimage.monochrome then begin + include(fstate,pms_monochrome); + end; + } + include(fstate,pms_ownshandle); + end; + end; +end; + +function tbitmap.checkindex(const index: pointty): integer; +begin + if (index.x < 0) or (index.y < 0) or + (index.x >= fsize.cx) or (index.y >= fsize.cy) then begin + gdierror(gde_invalidindex,self); + end; + result:= index.y*fscanlinewords; + case fkind of + bmk_mono: begin + result:= result + index.x div 32; + end; + bmk_gray: begin + result:= result*4 + index.x; + end; + else begin + result:= result + index.x; + end; + end; +end; + +function tbitmap.checkindex(const x,y: integer): integer; +begin + if (x < 0) or (y < 0) or + (x >= fsize.cx) or (y >= fsize.cy) then begin + gdierror(gde_invalidindex,self); + end; + result:= y*fscanlinewords; + case fkind of + bmk_mono: begin + result:= result + x div 32; + end; + bmk_gray: begin + result:= result*4 + x; + end; + else begin + result:= result + x; + end; + end; +end; + +function tbitmap.getscanline(index: integer): pointer; +begin + checkimage(false); + if fkind = bmk_gray then begin + result:= @pbyte(fimage.pixels)[checkindex(makepoint(0,index))]; //bytes + end + else begin + result:= @fimage.pixels[checkindex(makepoint(0,index))]; + end; +end; + +function tbitmap.getpixel(const index: pointty): colorty; +var + int1: integer; + lwo1: longword; +begin + int1:= checkindex(index); + checkimage(false); + case fkind of + bmk_mono: begin + if fimage.pixels^[int1] and bits[index.x and $1f] <> 0 then begin + result:= cl_1; + end + else begin + result:= cl_0; + end; + end; + bmk_gray: begin + lwo1:= pbyte(fimage.pixels)[int1]; + result:= lwo1 or (lwo1 shl 8) or (lwo1 shl 16); + end; + else begin + result:= fimage.pixels^[int1] and $ffffff; + end; + end; +end; + +procedure tbitmap.setpixel(const index: pointty; const value: colorty); +var + int1: integer; +begin + int1:= checkindex(index); + checkimage(false); + case kind of + bmk_mono: begin + if value = 0 then begin + fimage.pixels^[int1]:= fimage.pixels^[int1] and not bits[index.x and $1f]; + end + else begin + fimage.pixels^[int1]:= fimage.pixels^[int1] or bits[index.x and $1f]; + end; + end; + bmk_gray: begin + with rgbtriplety(value) do begin + pbyte(fimage.pixels)[int1]:= (word(red)+word(green)+word(blue)) div 3; + end; + end; + else begin + fimage.pixels^[int1]:= value and $ffffff; + end; + end; +end; + +function tbitmap.getpixels(const x,y: integer): colorty; +var + int1: integer; + lwo1: longword; +begin + int1:= checkindex(x,y); + checkimage(false); + case fkind of + bmk_mono: begin + if fimage.pixels^[int1] and bits[x and $1f] <> 0 then begin + result:= cl_1; + end + else begin + result:= cl_0; + end; + end; + bmk_gray: begin + lwo1:= pbyte(fimage.pixels)[int1]; + result:= lwo1 or (lwo1 shl 8) or (lwo1 shl 16); + end; + else begin + result:= fimage.pixels^[int1] and $ffffff; + end; + end; +end; + +procedure tbitmap.setpixels(const x,y: integer; const value: colorty); +var + int1: integer; +begin + int1:= checkindex(x,y); + checkimage(false); + case kind of + bmk_mono: begin + if value = 0 then begin + fimage.pixels^[int1]:= fimage.pixels^[int1] and not bits[x and $1f]; + end + else begin + fimage.pixels^[int1]:= fimage.pixels^[int1] or bits[x and $1f]; + end; + end; + bmk_gray: begin + with rgbtriplety(value) do begin + pbyte(fimage.pixels)[int1]:= (word(red)+word(green)+word(blue)) div 3; + end; + end; + else begin + fimage.pixels^[int1]:= value and $ffffff; + end; + end; +end; + +function tbitmap.getasize: sizety; +begin + result:= fsize; +end; + +procedure tbitmap.destroyhandle; +begin + if fimage.pixels <> nil then begin + gui_freeimagemem(fimage.pixels); + fimage.pixels:= nil; + end; + inherited; +end; + +procedure tbitmap.createhandle(copyfrom: pixmapty); +begin + if (fhandle = 0) and (fimage.pixels <> nil) then begin + putimage; + gui_freeimagemem(fimage.pixels); + fimage.pixels:= nil; + end + else begin + inherited; + end; +end; +{ +function tbitmap.getimagepo: pimagety; +begin + result:= @fimage; +end; +} +function tbitmap.getsource: tbitmapcomp; +begin + result:= nil; +end; + +procedure tbitmap.dochange; +begin + if assigned(fonchange) then begin + fonchange(self); + end; +end; + +procedure tbitmap.change; +begin + if (fnochange = 0) then begin + dochange; + end; +end; + +procedure tbitmap.setalignment(const Value: alignmentsty); +begin + if falignment <> value then begin + movealignment(value,falignment); + change; + end; +end; + +procedure tbitmap.setopacity(avalue: colorty); +begin + if avalue = cl_invalid then begin + avalue:= cl_none; + end; + if fopacity <> avalue then begin + fopacity:= avalue; + change; + end; +end; + +procedure tbitmap.updatealignment(const dest,source: rectty; + var alignment: alignmentsty; out newdest,newsource: rectty; + out tileorigin: pointty); + //expand copy areas in order to avoid missing pixels by position rounding +var + int1: integer; +begin + newdest:= dest; + newsource:= source; + if (al_fit in alignment) or (al_thumbnail in alignment) and + ((dest.cx < source.cx) or (dest.cy < source.cy)) then begin + exit; + end; + int1:= 0; + if al_xcentered in alignment then begin + if dest.cx < source.cx then begin + int1:= -1; + end; + newdest.x:= dest.x + (dest.cx - source.cx + int1) div 2 + end + else begin + if al_right in alignment then begin + newdest.x:= dest.x + dest.cx - source.cx; + end; + end; + if al_ycentered in alignment then begin + if dest.cy < source.cy then begin + int1:= -1; + end; + newdest.y:= dest.y + (dest.cy - source.cy + int1) div 2 + end + else begin + if al_bottom in alignment then begin + newdest.y:= dest.y + dest.cy - source.cy; + end; + end; + alignment:= alignment - [al_right,al_bottom,al_xcentered,al_ycentered]; + tileorigin:= newdest.pos; + if al_tiled in alignment then begin + newdest:= dest; + end + else begin + if al_stretchx in alignment then begin + newdest.x:= dest.x; + newdest.cx:= dest.cx; + end + else begin + int1:= newdest.x - dest.x; + if int1 < 0 then begin + dec(newdest.x,int1); + dec(newsource.x,int1); + inc(newsource.cx,int1); + end; + int1:= dest.x + dest.cx - (newdest.x + newsource.cx); + if int1 < 0 then begin + inc(newsource.cx,int1); + end; + newdest.cx:= newsource.cx; + end; + if al_stretchy in alignment then begin + newdest.y:= dest.y; + newdest.cy:= dest.cy; + end + else begin + int1:= newdest.y - dest.y; + if int1 < 0 then begin + dec(newdest.y,int1); + dec(newsource.y,int1); + inc(newsource.cy,int1); + end; + int1:= dest.y + dest.cy - (newdest.y + newsource.cy); + if int1 < 0 then begin + inc(newsource.cy,int1); + end; + newdest.cy:= newsource.cy; + end; + end; +end; + +procedure tbitmap.beginupdate; +begin + inc(fnochange); +end; + +procedure tbitmap.endupdate; +begin + dec(fnochange); + if fnochange = 0 then begin + dochange; + end; +end; + +procedure tbitmap.setcolorbackground(const Value: colorty); +begin + if fcolorbackground <> value then begin + fcolorbackground := Value; + change; + end; +end; + +procedure tbitmap.setcolorforeground(const Value: colorty); +begin + if fcolorforeground <> value then begin + fcolorforeground := Value; + change; + end; +end; + +function tbitmap.compressdata: longwordarty; +var + int1,int2,int3: integer; + po1: plongword; + ca1: longword; +begin + checkimage(false); + result:= nil; + allocuninitedarray(fimage.length,sizeof(longword),result); //max + case fkind of + bmk_mono,bmk_gray: begin + move(fimage.pixels^,result[0],fimage.length*sizeof(longword)); + end; + else begin + po1:= @fimage.pixels^[0]; + int2:= 0; //msb = run length + int1:= fimage.length; + while int1 > 0 do begin + ca1:= po1^ and $ffffff; + int3:= 0; + repeat + inc(po1); + inc(int3); + dec(int1); + until (po1^ and $ffffff <> ca1) or (int3 = 255) or (int1 = 0); + result[int2]:= ca1 or longword(int3 shl 24); + inc(int2); + end; + setlength(result,int2); + end; + end; +end; + +procedure tbitmap.decompressdata(const asize: sizety; const adata: longwordarty); +var + int1,int2,int3: integer; + po1: plongword; + ca1: longword; +begin + clear; + fsize:= asize; +// fimage.size:= fsize; +// fimage.monochrome:= monochrome; + allocimage(fimage,fsize,kind); + case kind of + bmk_mono,bmk_gray: begin + move(adata[0],fimage.pixels^,fimage.Length*sizeof(longword)); + end; + else begin + int2:= fimage.length; + if int2 > 0 then begin + po1:= @fimage.pixels^[0]; + for int1:= 0 to high(adata) do begin + ca1:= adata[int1] and $ffffff; + for int3:= (adata[int1] shr 24) - 1 downto 0 do begin + po1^:= ca1; + inc(po1); + dec(int2); + if int2 <= 0 then begin + break; + end; + end; + if int2 <= 0 then begin + break; + end; + end; + end; + end; + end; +end; + +procedure tbitmap.assign(source: tpersistent); +begin + if source is tbitmap then begin + with tbitmap(source) do begin + self.fcolorforeground:= colorforeground; + self.fcolorbackground:= colorbackground; + self.falignment:= alignment; + self.fopacity:= opacity; + end; + end; + inherited; +end; + +function tbitmap.hasimage: boolean; +var + bmp1: tbitmapcomp; +begin + bmp1:= getsource; + if bmp1 <> nil then begin + result:= not bmp1.bitmap.isempty; + end + else begin + result:= not isempty; + end; +end; + +procedure tbitmap.setsize(const Value: sizety); +begin + inherited; + change; +end; + +procedure tbitmap.savetoimage(out aimage: imagety); +begin + if hasimage then begin + if fimage.pixels = nil then begin + getimage; + aimage:= fimage; + fimage.pixels:= nil; + end + else begin + aimage:= fimage; + fimage.pixels:= gui_allocimagemem(fimage.length); +// allocimagemem; + move(aimage.pixels^,fimage.pixels^,fimage.length * sizeof(longword)); + //get a copy + end; + end + else begin + fillchar(aimage,sizeof(aimage),0); + end; +end; + +function tbitmap.getimageref(out aimage: imagety): boolean; + //true if buffer must be destroyed +begin + result:= fimage.pixels = nil; + if result then begin + savetoimage(aimage); + end + else begin + aimage:= fimage; + end; +end; + +procedure tbitmap.loadfromimage(const aimage: imagety); +begin + if aimage.pixels = nil then begin + clear; + end + else begin + size:= aimage.size; + { + if aimage.monochrome then begin + include(fstate,pms_monochrome); + end + else begin + exclude(fstate,pms_monochrome); + end; + } + fimage:= aimage; + fkind:= fimage.kind; + putimage; + fimage.pixels:= nil; //does not own image + end; +end; + +procedure tbitmap.getcanvasimage(const bgr: boolean; var aimage: maskedimagety); +begin + checkimage(bgr); + aimage.image:= fimage; +end; + +procedure tbitmap.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('transparency',@readtransparency,nil,false); +end; + +procedure tbitmap.readtransparency(reader: treader); +begin + opacity:= transparencytoopacity(colorty(reader.readinteger)); +end; + +procedure tbitmap.setkind(const avalue: bitmapkindty); +begin + if fkind <> avalue then begin + inherited; + if not isempty then begin + change; + end; + end; +end; + +{ tmaskedbitmap } + +constructor tmaskedbitmap.create(const akind: bitmapkindty; + const agdifuncs: pgdifunctionaty = nil); + //nil -> default +begin + ftransparentcolor:= cl_default; + fmaskcolorbackground:= $000000; //max transparent + fmaskcolorforeground:= $ffffff; + case akind of + bmk_mono: begin + include(foptions,bmo_monochrome); + end; + bmk_gray: begin + include(foptions,bmo_gray); + end; + end; + inherited; +end; + +destructor tmaskedbitmap.destroy; +begin + freemask; + inherited; + fobjectlinker.free; +end; + +procedure tmaskedbitmap.clear; +begin + forigformatdata:= ''; + inherited; +end; + +{ +class procedure tmaskedbitmap.freeimageinfo(var ainfo: imagebufferinfoty); +begin + with ainfo do begin + if image.pixels <> nil then begin + gui_freeimagemem(image.pixels); + image.pixels:= nil; + end; + if mask.pixels <> nil then begin + gui_freeimagemem(mask.pixels); + mask.pixels:= nil; + end; + end; +end; +} +procedure tmaskedbitmap.freemask; +begin + freeandnil(fmask); +end; + +function tmaskedbitmap.getasize: sizety; +begin + if fsource = nil then begin + result:= fsize; + end + else begin + result:= fsource.fbitmap.fsize; + end; +end; +{ +procedure tmaskedbitmap.createmask(const acolormask: boolean); +begin + if fmask = nil then begin + fmask:= tbitmap.create(true,fgdifuncs); + with fmask do begin + fcolorforeground:= fmaskcolorforeground; + fcolorbackground:= fmaskcolorbackground; + end; + end + else begin + fmask.clear; + end; + fmask.monochrome:= not acolormask; + exclude(fstate,pms_maskvalid); +end; +} +procedure tmaskedbitmap.createmask(const akind: bitmapkindty); +begin + if fmask = nil then begin + fmask:= townedbitmap.create(self,akind,fgdifuncs); + with fmask do begin + fcolorforeground:= fmaskcolorforeground; + fcolorbackground:= fmaskcolorbackground; + end; + end + else begin + fmask.clear; //todo: gray ??? + end; +// fmask.monochrome:= not acolormask; + exclude(fstate,pms_maskvalid); +end; + +procedure tmaskedbitmap.initmask; +var + bo1: boolean; +begin + if fmask <> nil then begin + bo1:= fmask.fcanvas = nil; + fmask.size:= fsize; + if not isnullsize(fsize) then begin + if fmask.kind = bmk_mono then begin + fmask.init(cl_1); + end + else begin + fmask.init(fmaskcolorforeground); + end; + end; + if bo1 then begin + fmask.freecanvas; + end; + include(fstate,pms_maskvalid); + end; +end; + +function tmaskedbitmap.gettranspcolor(): colorty; +begin + if (ftransparentcolor = cl_default) and not isempty then begin + result:= pixel[makepoint(0,fsize.cy-1)]; + end + else begin + result:= ftransparentcolor; + end; +end; + +function tmaskedbitmap.getconverttomonochromecolorbackground(): colorty; +begin + result:= gettranspcolor(); + if ftransparentcolor = cl_none then begin + result:= inherited getconverttomonochromecolorbackground; + end; +end; + +procedure tmaskedbitmap.checkmask(); +var + col1: colorty; + ki1,ki2: bitmapkindty; +begin + ki1:= bmk_mono; + if bmo_colormask in foptions then begin + ki1:= bmk_rgb; + end + else begin + if bmo_graymask in foptions then begin + ki1:= bmk_gray; + end; + end; + ki2:= ki1; + if not(pms_maskvalid in fstate) and not isempty() then begin + col1:= gettranspcolor(); + if (col1 <> cl_none) then begin + ki2:= bmk_mono; //create a stencil mask from transparent color + end; + end; + if fmask = nil then begin + createmask(ki2); +// createmask((ftransparentcolor = cl_none) and (bmo_colormask in foptions)); + end + else begin + if fmask.kind <> ki2 then begin + if not (pms_maskvalid in fstate) then begin + fmask.clear; + end; + fmask.kind:= ki2; + end; + end; + if not isempty and not (pms_maskvalid in fstate) then begin + fmask.size:= fsize; + if col1 <> cl_none then begin //get mono mask + if kind = bmk_mono then begin + if col1 = cl_0 then begin + fmask.canvas.copyarea(canvas,makerect(nullpoint,fsize),nullpoint,rop_copy); + end + else begin + fmask.canvas.copyarea(canvas,makerect(nullpoint,fsize),nullpoint,rop_notcopy); + end + end + else begin + fmask.canvas.copyarea(canvas,makerect(nullpoint,fsize), + nullpoint,rop_copy,col1); + end; + end + else begin + initmask; + end; + include(fstate,pms_maskvalid); + end; + fmask.kind:= ki1; +// fmask.monochrome:= not (bmo_colormask in foptions); +end; + +function tmaskedbitmap.getmask1(): tbitmap; +begin + checkmask; + result:= fmask; +end; + +procedure tmaskedbitmap.settransparentcolor(const Value: colorty); +begin + if ftransparentcolor <> value then begin + ftransparentcolor:= Value; + if value <> cl_none then begin + remask; + end; + end; +end; + +function tmaskedbitmap.getmasked: boolean; +begin + result:= fmask <> nil; +end; + +procedure tmaskedbitmap.setmasked(const Value: boolean); +begin + if getmasked <> value then begin + exclude(fstate,pms_maskvalid); + if value then begin + include(foptions,bmo_masked); + checkmask; + end + else begin + exclude(foptions,bmo_masked); + freemask; + end; + change; + end; +end; +{ +procedure tmaskedbitmap.setmonochrome(const avalue: boolean); +begin + inherited; + if avalue xor (bmo_monochrome in foptions) then begin + updatebit1(longword(foptions),ord(bmo_monochrome),avalue); + change; + end; +end; +} +function tmaskedbitmap.getcolormask: boolean; +begin + result:= bmo_colormask in foptions; +end; + +procedure tmaskedbitmap.setcolormask(const avalue: boolean); +begin + if avalue then begin + options:= foptions + [bmo_colormask]; + end + else begin + options:= foptions - [bmo_colormask]; + end; +end; + +function tmaskedbitmap.getgraymask(): boolean; +begin + result:= bmo_graymask in foptions; +end; + +procedure tmaskedbitmap.setgraymask(const avalue: boolean); +begin + if avalue then begin + options:= foptions + [bmo_graymask]; + end + else begin + options:= foptions - [bmo_graymask]; + end; +end; + +procedure tmaskedbitmap.setmask_source(const avalue: tbitmapcomp); +begin + if avalue <> fmask_source then begin + getobjectlinker.setlinkedvar(iobjectlink(self),avalue, + tmsecomponent(fmask_source)); + change(); + end; +end; + +procedure tmaskedbitmap.setmaskpos(const avalue: pointty); +begin + fmask_pos:= avalue; + change(); +end; + +procedure tmaskedbitmap.setmask_x(const avalue: int32); +begin + if fmask_pos.x <> avalue then begin + fmask_pos.x:= avalue; + change(); + end; +end; + +procedure tmaskedbitmap.setmask_y(const avalue: int32); +begin + if fmask_pos.y <> avalue then begin + fmask_pos.y:= avalue; + change(); + end; +end; + +function tmaskedbitmap.getoptions: bitmapoptionsty; +begin + result:= foptions; + (* + updatebit({$ifdef FPC}longword{$else}byte{$endif}(result),ord(bmo_monochrome), + monochrome); + updatebit({$ifdef FPC}longword{$else}byte{$endif}(result),ord(bmo_masked), + masked); + *) +end; + +procedure tmaskedbitmap.setoptions(const avalue: bitmapoptionsty); +//const +// mask1: bitmapoptionsty = [bmo_colormask]; +var + optbefore,opt2: bitmapoptionsty; + ki1: bitmapkindty; +begin + optbefore:= foptions; + foptions:= bitmapoptionsty(setsinglebit(longword(avalue),longword(foptions), + [longword([bmo_monochrome,bmo_gray]), + longword([bmo_colormask,bmo_graymask])])); + opt2:= foptions >< optbefore; + if opt2 <> [] then begin + beginupdate(); + try + if opt2 * bmokindoptions <> [] then begin + ki1:= bmk_rgb; + if bmo_monochrome in foptions then begin + ki1:= bmk_mono; + end + else begin + if bmo_gray in foptions then begin + ki1:= bmk_gray; + end; + end; + kind:= ki1; + end; + if (opt2 * bmomaskkindoptions <> []) and + (bmo_masked in foptions) and masked then begin + checkmask; + end; + masked:= bmo_masked in foptions; + finally + endupdate(); + end; + end; +(* + if (longword(foptions) xor longword(avalue)) and + {$ifdef FPC}longword{$else}byte{$endif}(mask1) <> 0 then begin + foptions:= avalue; + if fmask <> nil then begin + checkmask; + fmask.monochrome:= not (bmo_colormask in avalue); + change; + end; + end + else begin + foptions:= avalue; + end; +*) +// monochrome:= bmo_monochrome in foptions; +// masked:= bmo_masked in foptions; +end; + +function tmaskedbitmap.getmaskkind: bitmapkindty; +begin + result:= bmk_mono; + if bmo_graymask in foptions then begin + result:= bmk_gray; + end; + if bmo_colormask in foptions then begin + result:= bmk_rgb; + end; +end; + +procedure tmaskedbitmap.setmaskkind(const avalue: bitmapkindty); +var + opt1: bitmapoptionsty; +begin + opt1:= foptions - bmomaskkindoptions; + case avalue of + bmk_gray: begin + include(opt1,bmo_graymask); + end; + bmk_rgb: begin + include(opt1,bmo_colormask); + end; + end; + options:= opt1; +end; + +procedure tmaskedbitmap.remask; +begin + if fmask <> nil then begin + exclude(fstate,pms_maskvalid); + checkmask; + change; + end; +end; + +procedure tmaskedbitmap.automask; +begin + exclude(fstate,pms_maskvalid); + if not isempty then begin + transparentcolor:= pixel[makepoint(fsize.cx-1,fsize.cy-1)]; + end; + masked:= true; + checkmask; + change; +end; +{ +procedure tmaskedbitmap.savetomaskedimage(out aimage: maskedimagety); +begin + savetoimage(aimage.image); + if masked then begin + fmask.savetoimage(aimage.mask); + end + else begin + freeimage(aimage.mask); + end; +end; + +procedure tmaskedbitmap.loadfrommaskedimage(const aimage: maskedimagety); +begin + loadfromimage(aimage.image); + if aimage.mask.pixels <> nil then begin + if fmask = nil then begin + createmask(aimage.mask.kind); + end; + fmask.loadfromimage(aimage.mask); +// include(fstate,pms_maskvalid); + end + else begin + masked:= false; + end; +end; +} +procedure tmaskedbitmap.setmask(const Value: tbitmap); +var + ki1: bitmapkindty; +begin + if fmask <> value then begin + freemask; + if value <> nil then begin + ki1:= bmk_mono; + if bmo_colormask in foptions then begin + ki1:= bmk_rgb; + end + else begin + if bmo_graymask in foptions then begin + ki1:= bmk_gray; + end; + end; + createmask(ki1); + fmask.size:= fsize; + if sizeisequal(fsize,value.fsize) and + (value.kind = kind) then begin + fmask.handle:= value.handle; + end + else begin + case ki1 of + bmk_gray,bmk_rgb: begin + fmask.init(fmaskcolorbackground); + end; + else begin + fmask.init(cl_0); + end; + end; + fmask.copyarea(value,makerect(nullpoint,fsize),nullpoint,rop_copy,false, + fmaskcolorforeground,fmaskcolorbackground); + end; + include(fstate,pms_maskvalid); + end; + if masked then begin + change; + end; + end; +end; +{ +function tmaskedbitmap.getmaskhandle(var gchandle: longword): pixmapty; +begin + if fmask <> nil then begin + result:= tsimplebitmap1(fmask).handle; + if tsimplebitmap1(fmask).fcanvas <> nil then begin + gchandle:= tcanvas1(tsimplebitmap1(fmask).fcanvas).fdrawinfo.gc.handle; + end + else begin + gchandle:= 0; + end; + end + else begin + result:= 0; + end; +end; +} +function tmaskedbitmap.getmask(out apos: pointty): tsimplebitmap; +begin + if (fmask_source <> nil) then begin + result:= fmask_source.bitmap; + end + else begin + if fsource <> nil then begin + result:= fsource.bitmap.getmask(apos); //apos not used + if result = nil then begin + result:= fmask; + end; + end + else begin + result:= fmask; + end; + end; + apos:= fmask_pos; +end; + +procedure tmaskedbitmap.assign1(const source: tsimplebitmap; const docopy: boolean); +begin + beginupdate; + try + if source is tmaskedbitmap then begin + with tmaskedbitmap(source) do begin + if source <> nil then begin + self.source:= source; + end + else begin + inherited; + self.freemask; + replacebits1(longword(self.foptions),longword(foptions), + longword(bmomaskkindoptions+bmokindoptions)); + if fmask <> nil then begin + self.fmask:= tbitmap.create(fmask.kind,self.fgdifuncs); + with self,fmask do begin + fcolorforeground:= fmaskcolorforeground; + fcolorbackground:= fmaskcolorbackground; + end; +{$warnings off} + tsimplebitmap1(self.fmask).assign1(fmask,docopy); +{$warnings on} + include(self.fstate,pms_maskvalid); + include(self.foptions,bmo_masked); + end + else begin + if masked then begin + include(self.foptions,bmo_masked); + exclude(self.fstate,pms_maskvalid); + end + else begin + exclude(self.foptions,bmo_masked); + end; + end; + self.ftransparentcolor:= ftransparentcolor; + self.forigformat:= forigformat; + self.forigformatdata:= forigformatdata; + end; + end; + end + else begin + inherited; + freemask; + end; + finally + endupdate; + end; +end; + +procedure tmaskedbitmap.releasehandle; +begin + inherited; +// if fmask <> nil then begin +// tsimplebitmap1(fmask).releasehandle; +// end; +end; + +procedure tmaskedbitmap.acquirehandle; +begin + inherited; +// if fmask <> nil then begin +// tsimplebitmap1(fmask).acquirehandle; +// end; +end; + +procedure tmaskedbitmap.destroyhandle; +begin +// if fmask <> nil then begin +// tsimplebitmap1(fmask).destroyhandle; +// end; + inherited; +end; + +function tmaskedbitmap.getobjectlinker: tobjectlinker; +begin + if fobjectlinker = nil then begin + createobjectlinker(iobjectlink(self),{$ifdef FPC}@{$endif}objectevent,fobjectlinker); + end; + result:= fobjectlinker; +end; + +procedure tmaskedbitmap.setsource(const Value: tbitmapcomp); +var + bmpcomp1: tbitmapcomp; +begin + if fsource <> value then begin + bmpcomp1:= value; + while bmpcomp1 <> nil do begin + if bmpcomp1.bitmap = self then begin + raise exception.create('Recursive bitmap source.'); + end; + bmpcomp1:= bmpcomp1.bitmap.source; + end; + beginupdate; + try + clear; + getobjectlinker.setlinkedvar(iobjectlink(self),value,tmsecomponent(fsource)); + finally + endupdate; + end; + end; +end; + +procedure tmaskedbitmap.objectevent(const sender: tobject; const event: objecteventty); +begin + if sender = fsource then begin + case event of +// oe_destroyed: source:= nil; + oe_changed: change; + end; + end; +end; + +procedure tmaskedbitmap.link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); +begin + getobjectlinker.link(source,dest,valuepo,ainterfacetype,once); +end; + +procedure tmaskedbitmap.unlink(const source,dest: iobjectlink; valuepo: pointer = nil); +begin + getobjectlinker.unlink(source,dest,valuepo); +end; + +procedure tmaskedbitmap.objevent(const sender: iobjectlink; const event: objecteventty); +begin + getobjectlinker.objevent(sender,event); +end; + +function tmaskedbitmap.getinstance: tobject; +begin + result:= self; +end; + +function tmaskedbitmap.getsource: tbitmapcomp; +begin + result:= fsource; +end; + +procedure tmaskedbitmap.setsize(const Value: sizety); +begin + inherited; + initmask; +end; + +procedure tmaskedbitmap.stretch(const source: rectty; + const dest: tmaskedbitmap; + const aalignment: alignmentsty = + [al_stretchx,al_stretchy,al_intpol]); +const + tfo = bmokindoptions+bmomaskkindoptions+[bmo_masked]; +var + size1: sizety; + bo1: boolean; + destrect: rectty; +begin + dest.beginupdate; + try + size1:= dest.size; + dest.clear; + dest.options:= (dest.options - tfo) + (options*tfo); + { + dest.monochrome:= monochrome; + dest.colormask:= colormask; + dest.masked:= masked; + } + dest.size:= size1; + bo1:= (aalignment * [al_stretchx,al_stretchy] <> + [al_stretchx,al_stretchy]) and + not (al_tiled in aalignment) and + ((source.cx <> size1.cx) or (source.cy <> size1.cy)); + if bo1 then begin + dest.init(dest.colorbackground); + end; + destrect:= calcrectalignment(mr(nullpoint,size1),source,aalignment); + tcanvas1(dest.canvas).internalcopyarea(canvas,source,destrect, + rop_copy,cl_none,nil,nullpoint,aalignment, + nullpoint,cl_none); + + if masked then begin + if bo1 then begin + dest.mask.init(dest.mask.colorbackground); + end; + tcanvas1(dest.fmask.canvas).internalcopyarea(mask.canvas,source, + destrect,rop_copy,cl_none,nil,nullpoint,aalignment,nullpoint,cl_none); + include(dest.fstate,pms_maskvalid); + end; + finally + dest.endupdate; + end; +end; + +procedure tmaskedbitmap.stretch(const dest: tmaskedbitmap; + const aalignment: alignmentsty = [al_stretchx,al_stretchy,al_intpol]); +begin + stretch(mr(nullpoint,size),dest,aalignment); +end; + +function tmaskedbitmap.writedata(const ancestor: tmaskedbitmap): boolean; +begin + result:= (fsource = nil) and not isempty and not (pms_nosave in fstate); + if result and (ancestor <> nil) then begin + result:= ((options >< ancestor.options)* + (bmokindoptions+bmomaskkindoptions+[bmo_masked]) <> []) or + (size.cx <> ancestor.size.cx) or + (size.cy <> ancestor.size.cy) or + (bmo_storeorigformat in options) and + (origformatdata <> ancestor.origformatdata); + if not result then begin + if masked then begin + fmask.checkimage(false); + ancestor.fmask.checkimage(false); + zeropad(fmask.fimage); + zeropad(ancestor.fmask.fimage); + result:= (fmask.fimage.length <> ancestor.fmask.fimage.length) or + not comparemem(fmask.fimage.pixels,ancestor.fmask.fimage.pixels, + fmask.fimage.length * sizeof(longword)); + end; + if not result then begin + checkimage(false); + ancestor.checkimage(false); + result:= (fimage.length <> ancestor.fimage.length) or + not comparemem(fimage.pixels,ancestor.fimage.pixels, + fimage.length * sizeof(longword)); + end; + end; + end; +end; + +procedure tmaskedbitmap.defineproperties(filer: tfiler); +var + bo1: boolean; +begin + inherited; + bo1:= (forigformatdata <> '') and (bmo_storeorigformat in options); + filer.DefineBinaryProperty('image',{$ifdef FPC}@{$endif}readimage, + {$ifdef FPC}@{$endif}writeimage, + not bo1 and writedata(tmaskedbitmap(filer.ancestor))); + filer.DefineBinaryProperty('imagedata',{$ifdef FPC}@{$endif}readimagedata, + {$ifdef FPC}@{$endif}writeimagedata, + bo1 and writedata(tmaskedbitmap(filer.ancestor))); + if (filer is treader) and not(csdesigning in filer.root.componentstate) and + not(bmo_runtimeformatdata in options) then begin + forigformatdata:= ''; + end; +end; + +procedure tmaskedbitmap.writeimage(stream: tstream); +var + header: imageheaderty; + int1: integer; + ar1: longwordarty; +begin + fillchar(header,sizeof(header),0); + with header do begin + width:= fsize.cx; + height:= fsize.cy; + case fkind of + bmk_mono: begin + setbit1(info,ord(iminf_monochrome)); + end; + bmk_gray: begin + setbit1(info,ord(iminf_gray)); + end; + end; + if masked then begin + setbit1(info,ord(iminf_masked)); + case fmask.fkind of + bmk_gray: begin + setbit1(info,ord(iminf_graymask)); + end; + bmk_rgb: begin + setbit1(info,ord(iminf_colormask)); + end; + end; + end; + ar1:= compressdata; + datasize:= length(ar1)*4; + stream.Writebuffer(header,sizeof(header)); + stream.Writebuffer(ar1[0],datasize); + end; + if masked then begin + checkmask; + ar1:= fmask.compressdata; + int1:= length(ar1)*4; + if fmask.kind <> bmk_mono then begin + stream.WriteBuffer(int1,4); + end; + stream.WriteBuffer(ar1[0],int1); + end; +end; + +procedure tmaskedbitmap.readimage(stream: tstream); +var + header: imageheaderty; + int1: integer; + ar1: longwordarty; + ki1: bitmapkindty; + +begin + beginupdate; + try + clear; + stream.readbuffer(header,sizeof(header)); + fkind:= bmk_rgb; + with header do begin + if checkbit(info,ord(iminf_monochrome)) then begin + fkind:= bmk_mono; +// include(fstate,pms_monochrome); + end + else begin + if checkbit(info,ord(iminf_gray)) then begin + fkind:= bmk_gray; + end; +// exclude(fstate,pms_monochrome); + end; + if checkbit(info,ord(iminf_masked)) then begin +// ftransparentcolor:= cl_none; + ki1:= bmk_mono; + if checkbit(info,ord(iminf_colormask)) then begin + ki1:= bmk_rgb; + end + else begin + if checkbit(info,ord(iminf_graymask)) then begin + ki1:= bmk_gray; + end; + end; + createmask(ki1); +// createmask(checkbit(info,ord(iminf_colormask))); + end + else begin + freemask; + end; + allocuninitedarray(datasize div 4,4,ar1); +// setlength(ar1,datasize div 4); + stream.ReadBuffer(ar1[0],length(ar1)*4); + decompressdata(makesize(width,height),ar1); + if masked then begin + if fmask.kind = bmk_mono then begin + int1:= ((fsize.cx + 31) div 32) * fsize.cy; + end + else begin + stream.ReadBuffer(int1,sizeof(int1)); + int1:= int1 div 4; + end; + setlength(ar1,int1); + stream.readbuffer(ar1[0],int1*4); + fmask.decompressdata(fsize,ar1); + include(fstate,pms_maskvalid); + end; + end; + finally + endupdate; + end; +end; + +procedure tmaskedbitmap.readimagedata(stream: tstream); +var + lint1: int64; + str1: string; + optionsbefore: bitmapoptionsty; +begin + stream.readbuffer(lint1,sizeof(lint1)); +{$ifdef FPC} + lint1:= leton(lint1); +{$endif} + setlength(str1,lint1); + optionsbefore:= options; + stream.readbuffer(pchar(pointer(str1))^,lint1); + origformatdata:= str1; + options:= optionsbefore; // restore mask options +end; + +procedure tmaskedbitmap.writeimagedata(stream: tstream); +var + lint1: int64; +begin + lint1:= length(forigformatdata); +{$ifdef FPC} + stream.writebuffer(lint1,sizeof(ntole(lint1))); +{$else} + stream.writebuffer(lint1,sizeof(lint1)); +{$endif} + stream.writebuffer(pchar(pointer(forigformatdata))^,lint1); +end; + +function tmaskedbitmap.doloadfromstream(const atry: boolean; + const stream: tstream; + const format: string; const params: array of const): string; +var + int1,int2: integer; +begin + int1:= stream.position; + if atry then begin + result:= tryreadgraphic(stream,self,format,params); + end + else begin + result:= readgraphic(stream,self,format,params); + end; + int2:= stream.position; + if bmo_storeorigformat in options then begin + forigformat:= result; + int2:= int2-int1; + setlength(forigformatdata,int2); + stream.position:= int1; + stream.readbuffer(pchar(pointer(forigformatdata))^,int2); + end; +end; + +function tmaskedbitmap.doloadfromfile(const atry: boolean; + const filename: filenamety; + const format: string; const params: array of const): string; +var + stream: tmsefilestream; +begin + stream:= tmsefilestream.create(filename,fm_read); + try + result:= doloadfromstream(atry,stream,format,params); + finally + stream.free; + end; +end; + +function tmaskedbitmap.doloadfromstring(const atry: boolean; + const avalue: string; + const format: string; const params: array of const): string; +var + stream1: tstringcopystream; +begin + result:= ''; + if avalue = '' then begin + clear; + end + else begin + stream1:= tstringcopystream.create(avalue); + try + result:= doloadfromstream(atry,stream1,format,params); + finally + stream1.free; + end; + end; +end; + +function tmaskedbitmap.tryloadfromstream(const stream: tstream; + const format: string; const params: array of const): string; +begin + result:= doloadfromstream(true,stream,format,params); +end; + +function tmaskedbitmap.loadfromstream(const stream: tstream; + const format: string; const params: array of const): string; +begin + result:= doloadfromstream(false,stream,format,params); +end; + + +function tmaskedbitmap.loadfromfile(const filename: filenamety; + const format: string; const params: array of const): string; +begin + result:= doloadfromfile(false,filename,format,params); +end; + +function tmaskedbitmap.tryloadfromfile(const filename: filenamety; + const format: string; const params: array of const): string; +begin + result:= doloadfromfile(true,filename,format,params); +end; + +function tmaskedbitmap.loadfromstring(const avalue: string; + const format: string; const params: array of const): string; +begin + result:= doloadfromstring(false,avalue,format,params); +end; + +function tmaskedbitmap.tryloadfromstring(const avalue: string; + const format: string; const params: array of const): string; +begin + result:= doloadfromstring(true,avalue,format,params); +end; + +function tmaskedbitmap.loadfromstring(const avalue: string): string; +begin + result:= loadfromstring(avalue,'',[]); +end; + +function tmaskedbitmap.loadfromstream(const stream: tstream): string; +begin + result:= loadfromstream(stream,'',[]); +end; + +function tmaskedbitmap.loadfromfile(const filename: filenamety): string; +begin + result:= loadfromfile(filename,'',[]); +end; + +function tmaskedbitmap.tryloadfromstring(const avalue: string): string; +begin + result:= tryloadfromstring(avalue,'',[]); +end; + +function tmaskedbitmap.tryloadfromstream(const stream: tstream): string; +begin + result:= tryloadfromstream(stream,'',[]); +end; + +function tmaskedbitmap.tryloadfromfile(const filename: filenamety): string; +begin + result:= tryloadfromfile(filename,'',[]); +end; + +procedure tmaskedbitmap.writetostring(out avalue: string; const format: string; + const params: array of const); +var + stream1: tstringstream; +begin + stream1:= tstringstream.create(''); + try + writetostream(stream1,format,params); + avalue:= stream1.datastring; + finally + stream1.free; + end; +end; + +function tmaskedbitmap.writetostring(const format: string; + const params: array of const): string; +begin + writetostring(result,format,params); +end; + +procedure tmaskedbitmap.writetostream(const stream: tstream; const format: string; + const params: array of const); +begin + writegraphic(stream,self,format,params); +end; + +procedure tmaskedbitmap.writetofile(const filename: filenamety; const format: string; + const params: array of const); +var + stream1: tmsefilestream; +begin + stream1:= tmsefilestream.create(filename,fm_create); + try + writetostream(stream1,format,params) + finally + stream1.free; + end; +end; + +procedure tmaskedbitmap.loadfrommaskedimage(const aimage: maskedimagety); +begin + loadfromimage(aimage.image); + if aimage.mask.pixels <> nil then begin + include(foptions,bmo_masked); + createmask(aimage.mask.kind); + fmask.loadfromimage(aimage.mask); + foptions:= foptions - bmomaskkindoptions; + case aimage.mask.kind of + bmk_rgb: begin + include(foptions,bmo_colormask); + end; + bmk_gray: begin + include(foptions,bmo_graymask); + end; + end; +{ + if abuffer.mask.monochrome then begin + exclude(foptions,bmo_colormask); + end + else begin + include(foptions,bmo_colormask); + end; +} + include(fstate,pms_maskvalid); + end + else begin + freemask; + exclude(foptions,bmo_masked); + exclude(fstate,pms_maskvalid); + end; +end; + +procedure tmaskedbitmap.savetomaskedimage(out aimage: maskedimagety); +begin + savetoimage(aimage.image); + if fmask <> nil then begin + fmask.savetoimage(aimage.mask); + end + else begin + fillchar(aimage.mask,sizeof(aimage.mask),0); + end; +end; + +function tmaskedbitmap.bitmap: tmaskedbitmap; +begin + if fsource = nil then begin + result:= self; + end + else begin + result:= fsource.bitmap; + end; +end; + +procedure tmaskedbitmap.getcanvasimage(const bgr: boolean; + var aimage: maskedimagety); +begin + inherited; + if fmask <> nil then begin + fmask.checkimage(bgr); + aimage.mask:= fmask.fimage; + end; +end; + +procedure tmaskedbitmap.setorigformatdata(const avalue: string); +begin + forigformatdata:= avalue; + if avalue <> '' then begin + loadfromstring(avalue,forigformat,[]); + end; +end; + +procedure tmaskedbitmap.setkind(const avalue: bitmapkindty); +begin + foptions:= foptions - bmokindoptions; + case avalue of + bmk_gray: begin + include(foptions,bmo_gray); + end; + bmk_mono: begin + include(foptions,bmo_monochrome); + end; + end; + inherited; +end; + +{ +procedure tmaskedbitmap.loadfromresourcename(instance: longword; + const resname: string); +var + stream: tresourcestream; + formatstream: tformatstream; +begin + stream:= tresourcestream.Create(instance,uppercase(resname),RT_BITMAP); + formatstream:= tformatstream.create(stream,'bmp'); + try + readbmp(formatstream,0,self); + finally + formatstream.Free; + stream.Free; + end; +end; +} +{ +procedure tmaskedbitmap.readimagefile(const filename: filenamety); +var + stream: tmsefilestream; +begin + stream:= tmsefilestream.create(filename,fm_read); + try + msebitmap.readimage(stream,self); + finally + stream.Free; + end; + change; +end; +} +{ tbitmapcomp } + +constructor tbitmapcomp.create(aowner: tcomponent); +begin + inherited; + fbitmap:= tmaskedbitmap.create(bmk_rgb); + fbitmap.fonchange:= {$ifdef FPC}@{$endif}change; +end; + +destructor tbitmapcomp.destroy; +begin + inherited; + fbitmap.Free; +end; + +procedure tbitmapcomp.setbitmap(const Value: tmaskedbitmap); +begin + fbitmap.assign(value); +end; + +procedure tbitmapcomp.change(const sender: tobject); +begin + if fobjectlinker <> nil then begin + fobjectlinker.sendevent(oe_changed); + end; + if assigned(fonchange) then begin + fonchange(self); + end; +end; + +{ timagelist } + +constructor timagelist.create(aowner: tcomponent); +var + bmp1: tmaskedbitmap; +begin + fsize:= defaultimagelistsize; + inherited; + bmp1:= tmaskedbitmap.create(bmk_rgb); + bmp1.transparentcolor:= cl_none; + setlength(fbitmaps,1); + fbitmaps[0]:= bmp1; + masked:= true; +end; + +destructor timagelist.destroy; +begin + if fbitmaps <> nil then begin //otherwise exception in constructor + versioncount:= 1; + fbitmaps[0].Free; + end; + inherited; +end; + +function timagelist.getversioncount: int32; +begin + result:= fversionhigh + 1; +end; + +procedure timagelist.setversioncount(const avalue: int32); +var + i1,i2: int32; + bmp1,bmp2: tmaskedbitmap; +begin + i1:= avalue - 1; + if i1 < 0 then begin + i1:= 0; + end; + if i1 <> fversionhigh then begin + if i1 < fversionhigh then begin + for i2:= fversionhigh downto i1 + 1 do begin + fbitmaps[i2].destroy(); + end; + setlength(fbitmaps,i1+1); + end + else begin + bmp1:= fbitmaps[0]; + setlength(fbitmaps,avalue); + for i2:= fversionhigh + 1 to i1 do begin + bmp2:= tmaskedbitmap.create(bmp1.kind); + if not (csreading in componentstate) then begin + bmp2.assign(bmp1); + end + else begin + bmp2.transparentcolor:= bmp1.transparentcolor; + bmp2.options:= bmp1.options; + bmp2.size:= bmp1.size; + end; + fbitmaps[i2]:= bmp2; + end; + end; + fversionhigh:= i1; + if fversiondefault > i1 then begin + fversiondefault:= 0; + end; + end; +end; + +procedure timagelist.setversiondefault(avalue: int32); +begin + if (avalue < 0) or (avalue > fversionhigh) then begin + avalue:= 0; + end; + if fversiondefault <> avalue then begin + fversiondefault:= avalue; + change(); + end; +end; + +procedure timagelist.updateversionindex(var aindex: int32); +begin + if (aindex < 0) then begin + aindex:= fversiondefault; + end + else begin + if aindex > fversionhigh then begin + tlist.Error(SListIndexError, aIndex); + end; + end; +end; + +function timagelist.getbitmaps(aindex: int32): tmaskedbitmap; +begin + updateversionindex(aindex); + result:= fbitmaps[aindex]; +end; + +function timagelist.getbitmap: tmaskedbitmap; +begin + result:= fbitmaps[0]; +end; + +procedure timagelist.clear; +begin + count:= 0; +end; + +procedure timagelist.setsize(const avalue: sizety); +var + int1: integer; + bmp1,bmp2: tmaskedbitmap; + sizebefore: sizety; + countbefore: integer; + rect1,rect2: rectty; + i1: int32; +begin + if not sizeisequal(fsize,avalue) then begin + sizebefore:= fsize; + fsize:= avalue; + if fcount <> 0 then begin + beginupdate; + for i1:= 0 to fversionhigh do begin + bmp1:= tmaskedbitmap.create(bmk_rgb); + bmp1.assign(fbitmaps[i1]); + bmp2:= tmaskedbitmap.create(bmk_rgb); + bmp2.assign(fbitmaps[i1]); //get mask and color modes + bmp2.size:= sizebefore; + fbitmaps[i1].clear; + countbefore:= fcount; + count:= 0; + count:= countbefore; + rect1:= makerect(nullpoint,fsize); + rect2:= makerect(nullpoint,sizebefore); + centerinrect(rect1,rect2); + for int1:= 0 to count - 1 do begin + bmp2.canvas.copyarea(bmp1.canvas,rect2,nullpoint); + if bmp1.mask <> nil then begin + bmp2.mask.canvas.copyarea(bmp1.mask.canvas,rect2,nullpoint); + end; + setimage(int1,bmp2,rect1); + with rect2 do begin + inc(x,cx); + if x >= bmp1.fsize.cx then begin + x:= 0; + inc(y,cy); + end; + end; + end; + bmp1.free; + bmp2.free; + end; + endupdate; + end; + end; +end; + +function timagelist.indextoorg(index: integer): pointty; +begin + if (index < 0) or (index >= fcount) then begin + gdierror(gde_invalidindex); + end; + result.x:= (index mod fcolcount) * fsize.cx; + result.y:= (index div frowcount) * fsize.cy; +end; + +function timagelist.getmasked: boolean; +begin + result:= fbitmaps[0].masked; +end; + +procedure timagelist.setmasked(const Value: boolean); +var + i1: int32; +begin + for i1:= 0 to fversionhigh do begin + fbitmaps[i1].masked:= value; + end; +end; +{ +function timagelist.getmonochrome: boolean; +begin + result:= fbitmap.monochrome; +end; +} +function timagelist.getgraymask: boolean; +begin + result:= fbitmaps[0].graymask; +end; + +procedure timagelist.setgraymask(const avalue: boolean); +var + i1: int32; +begin + for i1:= 0 to fversionhigh do begin + fbitmaps[i1].graymask:= avalue; + end; +end; + +function timagelist.getcolormask: boolean; +begin + result:= fbitmaps[0].colormask; +end; + +procedure timagelist.setcolormask(const avalue: boolean); +var + i1: int32; +begin + for i1:= 0 to fversionhigh do begin + fbitmaps[i1].colormask:= avalue; + end; +end; +{ +procedure timagelist.setmonochrome(const Value: boolean); +begin + if fbitmap.monochrome <> value then begin + fbitmap.monochrome:= value; + change; + end; +end; +} +procedure timagelist.paint(const acanvas: tcanvas; const index: integer; + const dest: rectty; const alignment: alignmentsty = []; + const acolor: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default; + aversion: int32 = -1); +begin + if (index >= 0) and (index < count) then begin + updateversionindex(aversion); + fbitmaps[aversion].paint(acanvas,dest,makerect(indextoorg(index),fsize), + alignment,acolor, + acolorbackground,aopacity); + end; +end; + +procedure timagelist.paint(const acanvas: tcanvas; const index: integer; + const dest: rectty; source: rectty; + const alignment: alignmentsty = []; + const acolor: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default; + aversion: int32 = -1); + +begin + if (index >= 0) and (index < count) then begin + updateversionindex(aversion); + addpoint1(source.pos,indextoorg(index)); + fbitmaps[aversion].paint(acanvas,dest,source,alignment,acolor,acolorbackground, + aopacity); + end; +end; + +procedure timagelist.paintlookup(const acanvas: tcanvas; const index: integer; + const dest: pointty; const acolor: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default; aversion: int32 = -1); +begin + paint(acanvas,lookup(index),dest,acolor,acolorbackground,aopacity,aversion); +end; + +procedure timagelist.paintlookup(const acanvas: tcanvas; const index: integer; + const dest: rectty; const alignment: alignmentsty = []; + const acolor: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default; aversion: int32 = -1); +begin + paint(acanvas,lookup(index),dest,alignment,acolor,acolorbackground,aopacity, + aversion); +end; + +procedure timagelist.paintlookup(const acanvas: tcanvas; const index: integer; + const dest: rectty; source: rectty; + const alignment: alignmentsty = []; + const acolor: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default; aversion: int32 = -1); +begin + paint(acanvas,lookup(index),dest,alignment,acolor,acolorbackground,aopacity, + aversion); +end; + +procedure timagelist.clipcornermask(const canvas: tcanvas; + const arect: rectty; const ahiddenedges: edgesty); +var + rect2,rect3: rectty; + po1,ps,pe: pint16; + i1: int32; +begin + if hascornermask then begin + rect2.cy:= 1; + rect3:= arect; + if ahiddenedges * [edg_top,edg_left] = [] then begin + po1:= pointer(cornermask_topleft); + pe:= po1 + length(msestring(pointer(po1))); + rect2.pos:= rect3.pos; + ps:= po1; + while ps < pe do begin + rect2.cx:= ps^; + canvas.subcliprect(rect2); + inc(rect2.y); + inc(ps); + end; + end; + if ahiddenedges * [edg_left,edg_bottom] = [] then begin + po1:= pointer(cornermask_bottomleft); + pe:= po1 + length(msestring(pointer(po1))); + rect2.x:= rect3.x; + rect2.y:= rect3.y + rect3.cy - 1; + ps:= po1; + while ps < pe do begin + rect2.cx:= ps^; + canvas.subcliprect(rect2); + dec(rect2.y); + inc(ps); + end; + end; + if ahiddenedges * [edg_bottom,edg_right] = [] then begin + po1:= pointer(cornermask_bottomright); + pe:= po1 + length(msestring(pointer(po1))); + rect2.y:= rect3.y + rect3.cy - 1; + ps:= po1; + i1:= arect.x + arect.cx; + while ps < pe do begin + rect2.cx:= ps^; + rect2.x:= i1 - ps^; + canvas.subcliprect(rect2); + dec(rect2.y); + inc(ps); + end; + end; + if ahiddenedges * [edg_right,edg_top] = [] then begin + po1:= pointer(cornermask_topright); + pe:= po1 + length(msestring(pointer(po1))); + rect2.y:= rect3.y; + ps:= po1; + i1:= rect3.x + rect3.cx; + while ps < pe do begin + rect2.cx:= ps^; + rect2.x:= i1 - ps^; + canvas.subcliprect(rect2); + inc(rect2.y); + inc(ps); + end; + end; + end; +end; + +procedure timagelist.paint(const acanvas: tcanvas; const index: integer; + const dest: pointty; const acolor: colorty = cl_default; + const acolorbackground: colorty = cl_default; + const aopacity: colorty = cl_default; + aversion: int32 = -1); +begin + paint(acanvas,index,makerect(dest,size),[],acolor,acolorbackground, + aopacity,aversion); +end; + +function timagelist.gettransparentcolor: colorty; +begin + result:= fbitmaps[0].ftransparentcolor; +end; + +procedure timagelist.settransparentcolor(avalue: colorty); +var + i1: int32; +begin + if avalue = cl_invalid then begin + avalue:= cl_none; + end; + for i1:= 0 to fversionhigh do begin + fbitmaps[i1].transparentcolor:= avalue; + end; +end; + +procedure timagelist.setimage(index: integer; image: tmaskedbitmap; + const source: rectty; aalignment: alignmentsty = []; + aversion: int32 = -1); +var + rect1,rect2,destrect: rectty; + bo1: boolean; + ima1: tmaskedbitmap; + bmp1: tmaskedbitmap; +begin + if (al_thumbnail in aalignment) and + ((source.cx > fsize.cx) or (source.cy > fsize.cy)) then begin + include(aalignment,al_fit); + exclude(aalignment,al_thumbnail); + end; + rect2.pos:= indextoorg(index); + rect2.size:= fsize; + updateversionindex(aversion); + bmp1:= fbitmaps[aversion]; + if image = nil then begin + bmp1.canvas.fillrect(rect2, + bmp1.colorbackground); + if masked then begin + if bmp1.mask.kind = bmk_mono then begin + bmp1.mask.canvas.fillrect(rect2,cl_0); + end + else begin + bmp1.mask.canvas.fillrect( + rect2,bmp1.fmaskcolorbackground); + end; + end; + end + else begin + rect1:= source; + ima1:= image; + destrect:= calcrectalignment(rect2,source,aalignment); + with rect1 do begin + bo1:= (al_fit in aalignment) or + (x < 0) or (y < 0) or (x + cx > ima1.fsize.cx) or + (y + cy > ima1.fsize.cy) or + not(al_stretchx in aalignment) and (cx < fsize.cx) or + not(al_stretchy in aalignment) and (cy < fsize.cy); + if not (al_fit in aalignment) then begin + if not (al_stretchx in aalignment) and (cx > fsize.cx) then begin + cx:= fsize.cx; + end; + if not (al_stretchy in aalignment) and (cy > fsize.cy) then begin + cy:= fsize.cy; + end; + end; + end; + if masked then begin + bmp1.copyarea(ima1,rect1,rect2,aalignment,rop_copy,false); + if ima1.masked then begin + if bo1 then begin + if bmp1.mask.kind = bmk_mono then begin + bmp1.mask.canvas.fillrect(rect2,cl_0); + end + else begin + bmp1.mask.canvas.fillrect(rect2, + bmp1.fmaskcolorbackground); + end; + end; + bmp1.mask.copyarea( + ima1.mask,rect1,rect2,aalignment,rop_copy,false, + bmp1.fmaskcolorforeground, + bmp1.fmaskcolorbackground); + end + else begin + if bo1 then begin + if bmp1.mask.kind = bmk_mono then begin + bmp1.mask.canvas.fillrect(rect2,cl_0); + end + else begin + bmp1.mask.canvas.fillrect(rect2, + bmp1.fmaskcolorbackground); + end; + end; + if bmp1.mask.kind = bmk_mono then begin + bmp1.mask.canvas.fillrect(destrect,cl_1); + end + else begin + bmp1.mask.canvas.fillrect( + destrect,bmp1.fmaskcolorforeground); + end; + end; + end + else begin + if bo1 then begin + if kind = bmk_mono then begin + bmp1.canvas.fillrect(rect2,cl_0); + end + else begin + bmp1.canvas.fillrect(rect2,bmp1.fcolorbackground); + end; + end; + bmp1.copyarea(ima1,rect1,rect2,aalignment,rop_copy,false); + end; + end; + change; +end; + +procedure timagelist.getimage(const index: integer; const dest: tmaskedbitmap; + aversion: int32 = -1); +var + rect1: rectty; + bmp1: tmaskedbitmap; +begin + dest.clear; + if (index >= 0) or (index < fcount) then begin + updateversionindex(aversion); + bmp1:= fbitmaps[aversion]; + dest.beginupdate(); + dest.kind:= bmp1.kind; + dest.masked:= bmp1.masked; + if dest.masked then begin + dest.mask.kind:= bmp1.mask.kind; + end; + dest.transparentcolor:= bmp1.transparentcolor; + dest.colorforeground:= bmp1.colorforeground; + dest.colorbackground:= bmp1.colorbackground; + rect1.pos:= indextoorg(index); + rect1.size:= size; + dest.size:= size; + dest.copyarea(bmp1,rect1,nullpoint,rop_copy,false); + if dest.masked then begin + dest.mask.copyarea(bmp1.fmask,rect1,nullpoint,rop_copy,false); + end; + dest.endupdate(); + end; +end; + +procedure timagelist.setimage(index: integer; image: tmaskedbitmap; + const aalignment: alignmentsty = []; + aversion: int32 = -1); +begin + if image = nil then begin + setimage(index,nil,makerect(nullpoint,fsize),[],aversion); + end + else begin + setimage(index,image,makerect(nullpoint,image.fsize),aalignment,aversion); + end; +end; + +procedure timagelist.copyimages(const image: tmaskedbitmap; + const destindex: integer; + const aversion: int32); +var + rect1: rectty; + int1,int2: integer; +begin + with image.fsize do begin + if fsize.cx > cx then begin + int2:= -(fsize.cx - cx) div 2; + end + else begin + int2:= 0; + end; + if fsize.cy > cy then begin + rect1.y:= -(fsize.cy - cy) div 2; + end + else begin + rect1.y:= 0; + end; + rect1.cx:= cx - int2; + rect1.cy:= cy - rect1.y; + end; + int1:= destindex; + while rect1.y < image.fsize.cy do begin + rect1.x:= int2; + while rect1.x < image.fsize.cx do begin + if int1 >= fcount then begin + exit; + end; + setimage(int1,image,rect1,[],aversion); + inc(int1); + inc(rect1.x,fsize.cx); + end; + inc(rect1.y,fsize.cy); + end; +end; + +procedure timagelist.setcount(const Value: integer); + +var + int1,int2: integer; + buffer: tmaskedbitmap; + bo1: boolean; + i1: int32; + +begin + if fcount <> value then begin + fcount := Value; + if value = 0 then begin + for i1:= 0 to fversionhigh do begin + fbitmaps[i1].clear; + end; + frowcount:= 0; + fcolcount:= 0; + end + else begin + int1:= bits[highestbit(fcount) div 2 + 1]; + repeat + int2:= int1; + int1:= (int1 * 7) shr 3; //7/8 -> 0.875*0.875 -> 0.765 + if int1 = int2 then begin + dec(int1); + end; + until int1 * int1 < fcount; + bo1:= (frowcount <> int2) or (fcolcount <> int2); + frowcount:= int2; //square + fcolcount:= int2; + if bo1 then begin + for i1:= 0 to fversionhigh do begin + buffer:= tmaskedbitmap.create(kind); + buffer.assign1(fbitmaps[i1],false); + fbitmaps[i1].size:= makesize(int2*fsize.cx,int2*fsize.cy); + if not buffer.isempty then begin + copyimages(buffer,0,i1); + end; + buffer.Free; + end; + end; + end; + change; + end; +end; + +function timagelist.addimage(const image: tmaskedbitmap; + const aalignment: alignmentsty = []{; + const aversion: int32 = 0}): integer; +var + newcolcount,newrowcount,newcount: integer; + bmp1: tmaskedbitmap; + i1: int32; +begin +// checkversionindex(aversion); + result:= -1; + if image = nil then begin + result:= fcount; + count:= fcount+1; + for i1:= 0 to fversionhigh do begin + setimage(result,nil,[],i1); + end; + end + else begin + if not image.isempty then begin + result:= fcount; + beginupdate; + bmp1:= nil; + try + if (fsize.cx = 0) or (fsize.cy = 0) then begin + if image = nil then begin + exit; + end; + fsize:= image.fsize; + end; + if aalignment <> [] then begin + bmp1:= tmaskedbitmap.create(image.kind); + bmp1.size:= fsize; + image.stretch(bmp1,aalignment); + end + else begin + bmp1:= image; + end; + newcolcount:= (bmp1.size.cx + fsize.cx-1) div fsize.cx; + newrowcount:= (bmp1.size.cy + fsize.cy-1) div fsize.cy; + newcount:= newcolcount * newrowcount; + count:= fcount + newcount; + for i1:= 0 to fversionhigh do begin + copyimages(bmp1,result,i1); + end; + finally + if bmp1 <> image then begin + bmp1.free; + end; + endupdate; + end; + end; + end; +end; + +procedure timagelist.deleteimage(const index: integer); +var + i1: int32; +begin + for i1:= 0 to fversionhigh do begin + moveimage(index,count-1,i1); + end; + count:= fcount - 1; +end; + +procedure timagelist.moveimage(const fromindex: integer; const toindex: integer; + aversion: int32 = -1); +var + bmp1,bmp2: tmaskedbitmap; + int1: integer; +// i1,i2: int32; +begin + if fromindex <> toindex then begin + updateversionindex(aversion); + beginupdate; + try + bmp1:= tmaskedbitmap.create(kind); + bmp1.maskkind:= fbitmaps[0].maskkind; + bmp1.masked:= masked; + bmp2:= tmaskedbitmap.create(kind); + bmp2.maskkind:= fbitmaps[0].maskkind; + bmp2.masked:= masked; +// i2:= fversioncurrent; + try +// for i1:= 0 to fversionhigh do begin +// fversioncurrent:= i1; + getimage(fromindex,bmp1,aversion); + if fromindex < toindex then begin + for int1:= fromindex + 1 to toindex do begin + getimage(int1,bmp2,aversion); + setimage(int1-1,bmp2,[],aversion); + end; + end + else begin + for int1:= fromindex-1 downto toindex do begin + getimage(int1,bmp2,aversion); + setimage(int1+1,bmp2,[],aversion); + end; + end; + setimage(toindex,bmp1,[],aversion); +// end; + finally +// fversioncurrent:= i2; + bmp1.free; + bmp2.Free; + end; + finally + endupdate; + end; + end; +end; + +procedure timagelist.setheight(const Value: integer); +begin + setsize(makesize(fsize.cx,Value)); +end; + +procedure timagelist.setwidth(const Value: integer); +begin + setsize(makesize(value,fsize.cy)); +end; +{ +procedure timagelist.setbitmap(const Value: tmaskedbitmap); +begin + addimage(fbitmap); //??? +end; +} +procedure timagelist.beginupdate; +begin + inc(fupdating); +end; + +procedure timagelist.endupdate; +begin + dec(fupdating); + change; +end; + +procedure timagelist.change; +begin + if (fupdating = 0) then begin + if fobjectlinker <> nil then begin + fobjectlinker.sendevent(oe_changed); + end; + if canevent(tmethod(fonchange)) then begin + fonchange(self); + end; + end; +end; + +procedure timagelist.readmasked(reader: treader); +begin + masked:= reader.readboolean; +end; + +procedure timagelist.readcolormask(reader: treader); +begin + colormask:= reader.readboolean; +end; + +procedure timagelist.readmonochrome(reader: treader); +begin + if reader.readboolean then begin + kind:= bmk_mono; + end; +end; + +procedure timagelist.readcornermask(reader: treader); +begin + fcornermask_topleft:= reader.readunicodestring; + fcornermask_bottomleft:= fcornermask_topleft; + fcornermask_bottomright:= fcornermask_topleft; + fcornermask_topright:= fcornermask_topleft; + cornermaskchanged(); +end; + +procedure timagelist.writeimage(stream: tstream); +var + i1: int32; +begin + for i1:= 0 to fversionhigh do begin + fbitmaps[i1].writeimage(stream); + end; +end; + +procedure timagelist.readimage(stream: tstream); +var + i1: int32; +begin + for i1:= 0 to fversionhigh do begin + fbitmaps[i1].readimage(stream); + end; +end; + +procedure timagelist.defineproperties(filer: tfiler); + + function checkimage(): boolean; + var + i1: int32; + begin + with timagelist(filer.ancestor) do begin + result:= (self.count <> count) or (self.fversionhigh <> fversionhigh) or + (self.fsize.cx <> fsize.cx) or (self.fsize.cy <> fsize.cy) or + (self.fbitmaps[0].options <> fbitmaps[0].options); + if not result then begin + for i1:= 0 to fversionhigh do begin + if self.fbitmaps[i1].writedata(fbitmaps[i1]) then begin + result:= true; + break; + end; + end; + end; + end; + end; //checkimage + +var + ancestorbefore: tpersistent; +begin + inherited; + filer.defineproperty('monochrome',@readmonochrome,nil,false); + filer.defineproperty('masked',@readmasked,nil,false); + filer.defineproperty('colormask',@readcolormask,nil,false); + filer.defineproperty('cornermask',@readcornermask,nil,false); + if fversionhigh = 0 then begin + ancestorbefore:= filer.ancestor; + if (ancestorbefore <> nil) then begin + filer.ancestor:= timagelist(ancestorbefore).fbitmaps[0]; + end; + fbitmaps[0].defineproperties(filer); //imagedata + filer.ancestor:= ancestorbefore; + end + else begin + filer.definebinaryproperty('image',@readimage,@writeimage, + (filer.ancestor = nil) or checkimage()); + end; +end; + +function timagelist.lookup(const aindex: int32): int32; +begin + result:= aindex; + if findexlookup <> '' then begin + result:= -1; + if (aindex >= 0) and (aindex < length(findexlookup)) then begin + result:= pint16(findexlookup)[aindex]; + end; + end; +end; + +procedure timagelist.assign(sender: tpersistent); +var + i1: int32; +begin + if sender is timagelist then begin + count:= 0; + with timagelist(sender) do begin + self.versioncount:= versioncount; + self.fsize:= fsize; + self.fcolcount:= fcolcount; + self.frowcount:= frowcount; + self.fcount:= fcount; + for i1:= 0 to fversionhigh do begin + self.fbitmaps[i1].assign(fbitmaps[i1]); + end; + end; + change; + end + else begin + inherited; + end; +end; + +function timagelist.getkind: bitmapkindty; +begin + result:= fbitmaps[0].kind; +end; + +procedure timagelist.setkind(const avalue: bitmapkindty); +var + i1: int32; +begin + for i1:= 0 to fversionhigh do begin + fbitmaps[i1].kind:= avalue; + end; +end; + +function timagelist.getmaskkind: bitmapkindty; +begin + result:= fbitmaps[0].maskkind; +end; + +procedure timagelist.setmaskkind(const avalue: bitmapkindty); +var + i1: int32; +begin + for i1:= 0 to fversionhigh do begin + fbitmaps[i1].maskkind:= avalue; + end; +end; + +function timagelist.getoptions: bitmapoptionsty; +begin + result:= fbitmaps[0].options; +end; + +procedure timagelist.setoptions(const avalue: bitmapoptionsty); +var + i1: int32; +begin + for i1:= 0 to fversionhigh do begin + fbitmaps[i1].options:= avalue; + end; +end; + +procedure timagelist.setindexlookup(const avalue: msestring); +begin + findexlookup:= avalue; + change; +end; + +procedure timagelist.setcornermask_topleft(const avalue: msestring); +begin + fcornermask_topleft:= avalue; + cornermaskchanged(); +end; + +procedure timagelist.setcornermask_bottomleft(const avalue: msestring); +begin + fcornermask_bottomleft:= avalue; + cornermaskchanged(); +end; + +procedure timagelist.setcornermask_bottomright(const avalue: msestring); +begin + fcornermask_bottomright:= avalue; + cornermaskchanged(); +end; + +procedure timagelist.setcornermask_topright(const avalue: msestring); +begin + fcornermask_topright:= avalue; + cornermaskchanged(); +end; + +procedure timagelist.cornermaskchanged(); + + procedure check(const avalue: msestring; var maxwidth: int32); + var + po1,pe: pint16; + begin + maxwidth:= 0; + if avalue <> '' then begin + fhascornermask:= true; + po1:= pointer(avalue); + pe:= po1 + length(avalue); + while po1 < pe do begin + if po1^ > maxwidth then begin + maxwidth := po1^; + end; + inc(po1); + end; + end; + end; //check + +begin + if not (csloading in componentstate) then begin + fhascornermask:= false; + check(fcornermask_topleft,fcornermaskmaxtopleft); + check(fcornermask_bottomleft,fcornermaskmaxbottomleft); + check(fcornermask_bottomright,fcornermaskmaxbottomright); + check(fcornermask_topright,fcornermaskmaxtopright); + change; + end + else begin + fneedscornermaskcheck:= true; + end; +end; + +procedure timagelist.loaded(); +begin + inherited; + if fneedscornermaskcheck then begin + cornermaskchanged(); + fneedscornermaskcheck:= false; + end; +end; + +{ tcenteredbitmap } + +constructor tcenteredbitmap.create(const akind: bitmapkindty; + const agdifuncs: pgdifunctionaty = nil); +begin + inherited; + alignment:= [al_xcentered,al_ycentered]; +end; + +{ tbitmapcanvas } +{ +constructor tbitmapcanvas.create(const user: tbitmap); +begin + inherited create(user,icanvas(user)); +end; + +function tbitmapcanvas.getimage(const bgr: boolean): imagety; +begin + with tbitmap(fuser) do begin + checkimage(bgr); + result:= fimage; + end; +end; +} +{ townedbitmap } + +constructor townedbitmap.create(const aowner: tbitmap; + const akind: bitmapkindty; const agdifuncs: pgdifunctionaty = nil); +begin + fowner:= aowner; + inherited create(akind,agdifuncs); +end; + +procedure townedbitmap.dochange; +begin + inherited; + fowner.change(); +end; + +end. diff --git a/mseide-msegui/lib/common/graphics/msedrawtext.pas b/mseide-msegui/lib/common/graphics/msedrawtext.pas new file mode 100644 index 0000000..7d20786 --- /dev/null +++ b/mseide-msegui/lib/common/graphics/msedrawtext.pas @@ -0,0 +1,1859 @@ +{ MSEgui Copyright (c) 1999-2015 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msedrawtext; +{$ifdef FPC}{$mode objfpc}{$h+}{$GOTO ON}{$interfaces corba}{$endif} + +//todo: optimize speed + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,msegraphics,mserichstring, + msegraphutils, + msearrayprops,mseclasses,msestrings,msetypes,mseguiglob; + +const + defaulttabwidth = 20; //mm + textellipse = msestring('...'); + +type + textflagty = (tf_left,tf_xcentered,tf_right,tf_xjustify, + tf_top,tf_ycentered,tf_bottom, + //order fix, used in msepostscriptprinter + //tf_left and tf_right can be combined with tf_xcentered, + //tf_top and tf_bottom can be combined with tf_ycentered + //for limitting centering to avalable space + + tf_rotate90,tf_rotate180, +// tf_forcealignment, //do not use default alignment for buttons + tf_clipi,tf_clipo, + tf_grayed,tf_wordbreak,tf_softhyphen, + tf_noselect,tf_underlineselect, + tf_ellipseleft,{tf_ellipsemid,}tf_ellipseright, + tf_tabtospace,tf_showtabs,tf_glueimage, //used in button captions + tf_force); + textflagsty = set of textflagty; +const + ellipsemask: textflagsty = [tf_ellipseleft,{tf_ellipsemid,}tf_ellipseright]; + textalignments = [tf_left,tf_xcentered,tf_right,tf_xjustify, + tf_top,tf_ycentered,tf_bottom]; + +type + + tabulatorkindty = (tak_left,tak_right,tak_centered,tak_decimal); + tabulatorty = record + index: integer; + tabkind: tabulatorkindty; + linepos: integer; + textpos: integer; + width: integer; + cellwidth: integer; + end; + tabulatorarty = array of tabulatorty; + tabulatorstatety = (tas_editactive); + tabulatorstatesty = set of tabulatorstatety; + + ttabulatoritem = class(townedpersistent) + private + fkind: tabulatorkindty; + fpos: real; + procedure setkind(const avalue: tabulatorkindty); + procedure setdistleft(const avalue: real); + procedure setdistright(const avalue: real); + protected + fstate: tabulatorstatesty; + fdistleft: real; + fdistright: real; + function getenabled(): boolean virtual; + procedure setpos(const avalue: real); virtual; + property distleft: real read fdistleft write setdistleft; //mm + property distright: real read fdistright write setdistright; //mm + public + published + property kind: tabulatorkindty read fkind write setkind default tak_left; + property pos: real read fpos write setpos; //mm + end; + tabulatoritemclassty = class of ttabulatoritem; + + tcustomtabulators = class(townedpersistentarrayprop) + private + fppmm: real; + fuptodate: boolean; + fdefaultdist: real; + procedure setppmm(const avalue: real); + function gettabs: tabulatorarty; + function getitems(const index: integer): ttabulatoritem; + procedure setitems(const index: integer; const avalue: ttabulatoritem); + procedure setdefaultdist(const avalue: real); + function getpos(const index: integer): integer; + function getlinepos(const index: integer): integer; + procedure setlinepos(const index: integer; const avalue: integer); + protected + ftabs: tabulatorarty; + procedure checkuptodate; + procedure dochange(const index: integer); override; + procedure changed(const sender: ttabulatoritem); + class function getitemclass: tabulatoritemclassty; virtual; + public + constructor create; reintroduce; + class function getitemclasstype: persistentclassty; override; + procedure assign(source: tpersistent); override; + procedure add(const apos: real; const akind: tabulatorkindty); + procedure setdefaulttabs(const awidth: real = 20; const acount: integer = 20; + const akind: tabulatorkindty = tak_left); + property tabs: tabulatorarty read gettabs; + property ppmm: real read fppmm write setppmm; + //pixel per millimeter + property defaultdist: real read fdefaultdist write setdefaultdist; //0 -> none + property items[const index: integer]: ttabulatoritem read getitems + write setitems; default; + property pos[const index: integer]: integer read getpos; + property linepos[const index: integer]: integer read getlinepos write setlinepos; + end; + + ttabulators = class(tcustomtabulators) + published + property ppmm; + property defaultdist; + end; + + drawtextinfoty = record + text: richstringty; + dest,clip: rectty; + flags: textflagsty; + font: tfont; + tabulators: tcustomtabulators; + res: rectty; + end; + + tabinfoty = record + index: integer; + kind: tabulatorkindty; + linepos: integer; + end; + tabinfoarty = array of tabinfoty; + + textlineinfoty = record + liindex,licount: integer; + liy: integer; + listartx: integer; + liwidth: integer; + tabchars: tabinfoarty; + justifychars: tabinfoarty; + linebreak: boolean; //true if newline sequence detected + end; + textlineinfoarty = array of textlineinfoty; + + layoutinfoty = record + charwidths: integerarty; + lineinfos: textlineinfoarty; + ascent,descent,lineheight, + underline,strikeout: integer; + starty: integer; + height: integer; + xyswapped: boolean; + reversed: boolean; + end; + +function checktextflags(old,new: textflagsty): textflagsty; + +procedure drawtext(const canvas: tcanvas; var info: drawtextinfoty); overload; +procedure drawtext(const canvas: tcanvas; const text: richstringty; + const dest: rectty; flags: textflagsty = []; + font: tfont = nil; tabulators: tcustomtabulators = nil); overload; +procedure drawtext(const canvas: tcanvas; const text: richstringty; + const dest,clip: rectty; flags: textflagsty = []; + font: tfont = nil; tabulators: tcustomtabulators = nil); overload; +procedure drawtext(const canvas: tcanvas; const text: msestring; + const dest,clip: rectty; flags: textflagsty = []; + font: tfont = nil; tabulators: tcustomtabulators = nil); overload; +procedure drawtext(const canvas: tcanvas; const text: msestring; + const dest: rectty; flags: textflagsty = []; + font: tfont = nil; tabulators: tcustomtabulators = nil); overload; +procedure layouttext(const canvas: tcanvas; var info: drawtextinfoty; + out layoutinfo: layoutinfoty); overload; +function breaklines(const canvas: tcanvas; + var info: drawtextinfoty): richstringarty; overload; +function breaklines(const canvas: tcanvas; const text: richstringty; + const width: integer; font: tfont = nil): richstringarty; overload; +function breaklines(const canvas: tcanvas; const text: msestring; + const width: integer; font: tfont = nil): msestringarty; overload; + +procedure textrect(const canvas: tcanvas; var info: drawtextinfoty); overload; + //result in info.res +function textrect(const canvas: tcanvas; const text: richstringty; + const dest: rectty; flags: textflagsty = []; + font: tfont = nil; tabulators: tcustomtabulators = nil): rectty; overload; +function textrect(const canvas: tcanvas; const text: richstringty; + flags: textflagsty = []; font: tfont = nil; + tabulators: tcustomtabulators = nil): rectty; overload; +function textrect(const canvas: tcanvas; const text: msestring; + const dest: rectty; flags: textflagsty = []; + font: tfont = nil; tabulators: tcustomtabulators = nil): rectty; overload; +function textrect(const canvas: tcanvas; const text: msestring; + flags: textflagsty = []; font: tfont = nil; + tabulators: tcustomtabulators = nil): rectty; overload; +function textclipped(const canvas: tcanvas; var info: drawtextinfoty): boolean; + +function postotextindex(const canvas: tcanvas; var info: drawtextinfoty; + const pos: pointty; out aindex: integer): boolean; + //false if out of text +function textindextopos(const canvas: tcanvas; var info: drawtextinfoty; + aindex: integer): pointty; + +implementation +uses + mseguiintf,msebits,msearrayutils,{$ifdef FPC}math{$else}Math{$endif},msereal, + sysutils,msefont,mseformatstr; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tcanvas1 = class(tcanvas); + +function checktextflags(old,new: textflagsty): textflagsty; +const +// xmask: textflagsty = [tf_xcentered,tf_right]; + xmask: textflagsty = [tf_left,tf_right]; +// ymask: textflagsty = [tf_ycentered,tf_bottom]; + ymask: textflagsty = [tf_top,tf_bottom]; +begin + result:= new; + result:= textflagsty(setsinglebit({$ifdef FPC}longword{$else}longword{$endif}(result), + {$ifdef FPC}longword{$else}longword{$endif}(old), + {$ifdef FPC}longword{$else}longword{$endif}(ymask))); + result:= textflagsty(setsinglebit({$ifdef FPC}longword{$else}longword{$endif}(result), + {$ifdef FPC}longword{$else}longword{$endif}(old), + {$ifdef FPC}longword{$else}longword{$endif}(xmask))); + result:= textflagsty(setsinglebit({$ifdef FPC}longword{$else}longword{$endif}(result), + {$ifdef FPC}longword{$else}longword{$endif}(old), + {$ifdef FPC}longword{$else}longword{$endif}(ellipsemask))); +// if tf_default in result then begin +// result:= [tf_default]; +// end; +end; + +procedure additem(var dest: tabinfoarty; const value: integer); +begin + setlength(dest,high(dest)+2); + with dest[high(dest)] do begin + index:= value; + kind:= tabulatorkindty(-1); //invalid + end; +end; + +procedure addtabchar(var dest: tabinfoarty; const aindex: integer; + const akind: tabulatorkindty; const alinepos: integer); + procedure setdata(const ind: integer); + begin + with dest[ind] do begin + index:= aindex; + kind:= akind; + linepos:= alinepos; + end; + end; + +var + int1: integer; +begin + for int1:= 0 to high(dest) do begin + if dest[int1].index = aindex then begin + exit; + end; + if dest[int1].index > aindex then begin + setlength(dest,high(dest) + 2); + move(dest[aindex],dest[aindex+1],(high(dest)-aindex) * sizeof(dest[0])); + setdata(int1); + exit; + end; + end; + setlength(dest,high(dest) + 2); + setdata(high(dest)); +end; + +function comparetabinfo(const l,r): integer; +begin + result:= tabinfoty(l).index-tabinfoty(r).index; +end; + +function mergearray(const a,b: tabinfoarty): tabinfoarty; + //result is sorted without duplicates +var + int1,int2: integer; + ar1: integerarty; +begin + setlength(result,length(a)+length(b)); + if result <> nil then begin + move(a[0],result[0],length(a)*sizeof(result[0])); + move(b[0],result[length(a)],length(b)*sizeof(result[0])); + mergesortarray(result,sizeof(result[0]),length(result), + @comparetabinfo,ar1,true); + int2:= 0; + for int1:= 1 to high(result) do begin + if result[int2].index <> result[int1].index then begin + inc(int2); + result[int2]:= result[int1]; + end; + end; + setlength(result,int2+1); + end; +end; + +procedure layouttext(const canvas: tcanvas; var info: drawtextinfoty; + out layoutinfo: layoutinfoty); +var + drawinfo: drawinfoty; + awidth: integer; + resultpo1: pinteger; + text1: pmsechar; + highresfo: boolean; + + procedure getcharwidths(acount: integer); + var + fontmetrics1: fontmetricsty; + int1: integer; + begin + if acount <= 0 then begin + exit; + end; + if fs_blank in canvas.font.style then begin + for int1:= 0 to acount-1 do begin + {$ifdef FPC} + resultpo1[int1]:= 0; + {$else} + pinteger(pchar(pointer(resultpo1))+int1*sizeof(integer))^:= 0; + {$endif} + end; + end + else begin + with drawinfo.getchar16widths do begin + fontdata:= getfontdata(canvas.font.handle); + resultpo:= resultpo1; + text:= text1; + count:= acount; + if highresfo then begin + checkhighresfont(fontdata,tcanvas1(canvas).fdrawinfo); + end; + getchar16widths(drawinfo); + end; + if tf_tabtospace in info.flags then begin + with drawinfo.getfontmetrics do begin + fontdata:= drawinfo.getchar16widths.fontdata; + char:= ord(' '); + resultpo:= @fontmetrics1; + getfontmetrics({datapo,}drawinfo); + end; + for int1:= 0 to acount-1 do begin + if (text1+int1)^ = c_tab then begin + pintegeraty(resultpo1)^[int1]:= fontmetrics1.width; + end; + end; + end; + end; + inc(text1,acount); + inc(resultpo1,acount); + end; + + function checklinebreak(var aindex: integer): boolean; + var + ch1: msechar; + begin + ch1:= info.text.text[aindex]; + result:= (ch1 = c_return) or (ch1 = c_linefeed); + if result then begin + with layoutinfo do begin + with lineinfos[high(lineinfos)] do begin + licount:= aindex - liindex; + liwidth:= awidth; + linebreak:= true; + end; + inc(aindex); + if (ch1 = c_return) and (aindex <= length(info.text.text)) and + (info.text.text[aindex] = c_linefeed) then begin + inc(aindex); + end; + setlength(lineinfos,high(lineinfos) + 2); + with lineinfos[high(lineinfos)] do begin + liindex:= aindex; + end; + end; + end; + end; +//{$define mswindows} + function tabitemwidth(const charindex: integer; + const stopchar: msechar): integer; + var + po1: pinteger; + po2: pmsechar; + begin + result:= 0; + po1:= @{pointer}(layoutinfo.charwidths[charindex]); + po2:= @info.text.text[charindex+1]; + while true do begin + case po2^ of + ' ',c_tab,c_return,c_linefeed,#0: begin + break; + end; + else begin + if po2^ = stopchar then begin + break; + end; + result:= result + po1^; + inc(po1); + inc(po2); + end; + end; + end; + end; +var + int1,int2,int3,int4: integer; + textlen: integer; + style1: fontstylesty; + nexttab: integer; + rea1,rea2: real; + tabs: tabulatorarty; + po1: pmsecharaty; + bo1: boolean; + wch1: widechar; + + procedure checksofthyphen(const alineinfo: integer); + begin + if tf_softhyphen in info.flags then begin + with layoutinfo do begin + if (int2 > 0) and (info.text.text[int2] = c_softhyphen) then begin + charwidths[int2-1]:= 0; + additem(lineinfos[alineinfo].tabchars,int2); + end; + end; + end; + end; + +var + y1,orig1,int5: integer; + fontmetrics1: fontmetricsty; + hasitaliccomp: boolean; +{$ifdef mswindows} + italicsafetymargin: int32; +{$endif} + +begin + tabs:= nil; //compiler warning + if info.font <> nil then begin + canvas.font:= info.font; + end; + try + gdi_lock; + with info,tcanvas1(canvas),layoutinfo do begin + if tf_rotate90 in flags then begin + swapxy1(dest); + end; + checkgcstate([cs_gc]); + highresfo:= df_highresfont in fdrawinfo.gc.drawingflags; + canvas.initdrawinfo(drawinfo); + ascent:= font.ascent; + descent:= font.descent; + lineheight:= font.lineheight; + textlen:= length(text.text); + setlength(charwidths,textlen); + text1:= pointer(info.text.text); + resultpo1:= pointer(charwidths); + if text.format = nil then begin + getcharwidths(textlen); + end + else begin + int2:= 0; + style1:= font.style; + for int1:= 0 to high(text.format) do begin + with text.format[int1] do begin + if newinfos * fontlayoutflags <> [] then begin + if index > textlen then begin + getcharwidths(textlen-int2); + end + else begin + getcharwidths(index-int2); + end; + int2:= index; + font.style:= style.fontstyle; + end; + end; + end; + if int2 < length(text.text) then begin + getcharwidths(length(text.text)-int2); + end; + font.style:= style1; + end; + setlength(lineinfos,1); + lineinfos[0].liindex:= 1; + int1:= 1; + awidth:= 0; //textwidth + if tf_wordbreak in flags then begin + int2:= 0; + while int1 <= textlen do begin + int2:= 0; //index of last whitespace + int3:= 0; //textwidth of last whitespace + awidth:= 0; //textwidth + while int1 <= textlen do begin + wch1:= text.text[int1]; + if (wch1 = ' ') or + ((wch1 = '-') and (int1 > 1) and (text.text[int1-1] <> ' ') or + (wch1 = c_softhyphen)) and + (awidth + charwidths[int1-1] <= info.dest.cx) then begin + checksofthyphen(high(lineinfos)); + int2:= int1; + int3:= awidth; + end + else begin + if checklinebreak(int1) then begin + checksofthyphen(high(lineinfos)-1); + break; + end; + end; + if (wch1 <> c_softhyphen) or not (tf_softhyphen in flags) then begin + inc(awidth,charwidths[int1-1]); + end; + if (awidth > info.dest.cx) and (awidth > charwidths[int1-1]) then begin + //min one char on line + with lineinfos[high(lineinfos)] do begin + if (int2 > 0) then begin //use last whitespace for break + if text.text[int2] <> ' ' then begin + inc(int3,charwidths[int2-1]); //'-' + licount:= int2 - liindex + 1; + end + else begin + licount:= int2 - liindex; + end; + liwidth:= int3; + int1:= int2 + 1; + end + else begin + licount:= int1 - liindex; //no whitespace to break + liwidth:= awidth - charwidths[int1-1]; + end; + end; + setlength(lineinfos,high(lineinfos) + 2); + with lineinfos[high(lineinfos)] do begin + liindex:= int1; + end; + break; + end; + inc(int1); + end; + checksofthyphen(high(lineinfos)); + end; + with lineinfos[high(lineinfos)] do begin + if textlen > 0 then begin + licount:= textlen - liindex + 1; + end; + liwidth:= awidth; + end; + end + else begin //no linebreak + if (info.tabulators = nil) or + (info.tabulators.count = 0) and (info.tabulators.defaultdist = 0) or + (tf_tabtospace in flags) then begin + while int1 <= textlen do begin + if (tf_softhyphen in info.flags) and (info.text.text[int1] = c_softhyphen) then begin + charwidths[int1-1]:= 0; + additem(lineinfos[high(lineinfos)].tabchars,int1); + end; + if not checklinebreak(int1) then begin + inc(awidth,charwidths[int1-1]); + inc(int1); + end + else begin + awidth:= 0; + end; + end; + end + else begin //with tabulators + tabs:= info.tabulators.tabs; + rea1:= info.tabulators.defaultdist * info.tabulators.ppmm; + nexttab:= -1; + while int1 <= textlen do begin + if (tf_softhyphen in info.flags) and + (info.text.text[int1] = c_softhyphen) then begin + charwidths[int1-1]:= 0; + additem(lineinfos[high(lineinfos)].tabchars,int1); + end; + if not checklinebreak(int1) then begin + if info.text.text[int1] = c_tab then begin + if tabs <> nil then begin + inc(nexttab); + if nexttab < info.tabulators.count then begin + case tabs[nexttab].tabkind of + tak_right: begin + charwidths[int1-1]:= tabs[nexttab].textpos - awidth - + tabitemwidth(int1,#0); + end; + tak_centered: begin + charwidths[int1-1]:= tabs[nexttab].textpos - awidth - + tabitemwidth(int1,#0) div 2; + end; + tak_decimal: begin + charwidths[int1-1]:= tabs[nexttab].textpos - awidth - + tabitemwidth(int1, + defaultformatsettingsmse.decimalseparator); + end; + else begin //tak_left + charwidths[int1-1]:= tabs[nexttab].textpos - awidth; + end; + end; + with tabs[nexttab] do begin + addtabchar(lineinfos[high(lineinfos)].tabchars,int1,tabkind,linepos); + end; + end + else begin + if rea1 > 0 then begin + int5:= round(ceil(awidth / rea1)*rea1); + charwidths[int1-1]:= int5 - awidth; + addtabchar(lineinfos[high(lineinfos)].tabchars,int1,tak_left,int5); + end; + end; + end + else begin + if rea1 > 0 then begin + int5:= round(floor((awidth+rea1+0.1)/rea1)*rea1); + charwidths[int1-1]:= int5 - awidth; + addtabchar(lineinfos[high(lineinfos)].tabchars,int1,tak_left,int5); + end; + end; + end; + inc(awidth,charwidths[int1-1]); + inc(int1); + end + else begin + awidth:= 0; + nexttab:= -1; + end; + end; + end; + with lineinfos[high(lineinfos)] do begin + liwidth:= awidth; + licount:= int1-liindex; + end; + end; + if high(lineinfos) >= 0 then begin + height:= lineheight*high(lineinfos)+ascent+descent; + end + else begin + height:= 0; + end; + res.y:= info.dest.y; + if tf_ycentered in flags then begin + if info.dest.cy < height then begin + if tf_bottom in flags then begin + res.y:= res.y + info.dest.cy - height; + end + else begin + if not (tf_top in flags) then begin + res.y:= res.y + (info.dest.cy - height -1) div 2; + end; + end; + end + else begin + res.y:= res.y + (info.dest.cy - height) div 2; + end; + end + else begin + if tf_bottom in flags then begin + res.y:= res.y + info.dest.cy - height; + end; + end; + y1:= res.y + ascent; //layoutinfo + starty:= y1; + res.x:= bigint; + res.cy:= height; + res.cx:= 0; + hasitaliccomp:= (text.format = nil) and font.italic; + if hasitaliccomp then begin + with drawinfo.getfontmetrics do begin + fontdata:= getfontdata(canvas.font.handle); + resultpo:= @fontmetrics1; + {$ifdef mswindows} + italicsafetymargin:= (lineheight+10) div 20; + {$endif} + end; + end; + for int3:= 0 to high(lineinfos) do begin + with layoutinfo.lineinfos[int3] do begin + liy:= y1; + y1:= y1 + lineheight; + listartx:= info.dest.x; + if hasitaliccomp and (licount > 0) then begin + with drawinfo.getfontmetrics do begin + char:= getucs4char(text.text,liindex); + msefont.getfontmetrics({datapo,}drawinfo); + listartx:= listartx - fontmetrics1.leftbearing + {$ifdef mswindows} + 1{$endif}; + liwidth:= liwidth - fontmetrics1.leftbearing; + char:= getucs4char(text.text,liindex+licount-1); + msefont.getfontmetrics({datapo,}drawinfo); + liwidth:= liwidth-fontmetrics1.rightbearing + {$ifdef mswindows}+ 1 + italicsafetymargin{$endif}; + end; + end; + if tf_xcentered in flags then begin + if info.dest.cx < liwidth then begin + if tf_right in flags then begin + listartx:= listartx + info.dest.cx - liwidth; + end + else begin + if not (tf_left in flags) then begin + listartx:= listartx + (info.dest.cx - liwidth - 1) div 2; + end; + end; + end + else begin + listartx:= listartx + (info.dest.cx - liwidth) div 2; + end; + end + else begin + if tf_right in flags then begin + listartx:= listartx + info.dest.cx - liwidth; + end; + end; + if res.x > listartx then begin + res.x:= listartx; + end; + if res.cx < liwidth then begin + res.cx:= liwidth; + end; + end; + end; + if (tf_xjustify in flags) and (dest.cx > 0) then begin + po1:= pointer(info.text.text); + bo1:= false; + int3:= high(lineinfos); + if tf_wordbreak in flags then begin + dec(int3); + end; + for int3:= 0 to int3 do begin + with lineinfos[int3] do begin + if not linebreak then begin + bo1:= true; + int4:= 0; + setlength(justifychars,licount); //max + for int1:= liindex-1 to liindex + licount - 2 do begin + if po1^[int1] = ' ' then begin + with justifychars[int4] do begin + index:= int1+1; + end; + inc(int4); + end; + end; + setlength(justifychars,int4); + if (int4 > 0) and not (cs_internaldrawtext in fstate) then begin + rea1:= (dest.cx - liwidth) / int4; + rea2:= 0; + int2:= 0; + for int1:= 0 to high(justifychars) do begin + rea2:= rea2 + rea1; + int4:= round(rea2) - int2; + inc(charwidths[justifychars[int1].index-1],int4); + inc(int2,int4); + end; + listartx:= dest.x; + if tabchars <> nil then begin + tabchars:= mergearray(tabchars,justifychars); + end + else begin + tabchars:= justifychars; + end; + justifychars:= nil; + end; + end; + end; + end; + if bo1 then begin + if res.cx <= dest.cx then begin + res.x:= dest.x; + res.cx:= dest.cx; + end; + end; + end; + underline:= descent div 2 + 1; + if underline = 0 then begin + underline:= 1; + end; + if underline >= descent then begin + underline:= descent - 1; + end; + strikeout:= - (ascent div 3); + xyswapped:= false; + reversed:= false; + if flags * [tf_rotate90,tf_rotate180] <> [] then begin + if (tf_rotate90 in flags) xor (tf_rotate180 in flags) then begin //mirror x + orig1:= dest.x + dest.x + dest.cx; + res.x:= orig1 - res.x - res.cx; + for int1:= 0 to high(lineinfos) do begin + with lineinfos[int1] do begin + listartx:= orig1-listartx; + end; + end; + for int1:= 0 to high(charwidths) do begin + charwidths[int1]:= - charwidths[int1]; + end; + end; + reversed:= (tf_rotate180 in flags); + if reversed then begin //mirror y + ascent:= -ascent; + descent:= -descent; + lineheight:= -lineheight; + underline:= -underline; + strikeout:= -strikeout; + orig1:= dest.y + dest.y + dest.cy; + res.y:= orig1 - res.y - res.cy; + starty:= orig1 - starty; + for int1:= 0 to high(lineinfos) do begin + with lineinfos[int1] do begin + liy:= orig1-liy; + end; + end; + end; + xyswapped:= tf_rotate90 in flags; + if xyswapped then begin + swapxy1(dest); + swapxy1(res); + end; + end; + end; + finally + gdi_unlock; + end; +end; + +function breaklines(const canvas: tcanvas; + var info: drawtextinfoty): richstringarty; +var + la1: layoutinfoty; + int1: integer; +begin + layouttext(canvas,info,la1); + setlength(result,length(la1.lineinfos)); + for int1:= 0 to high(result) do begin + with la1.lineinfos[int1] do begin + result[int1]:= richcopy(info.text,liindex,licount); + end; + end; +end; + +function breaklines(const canvas: tcanvas; const text: richstringty; + const width: integer; font: tfont = nil): richstringarty; +var + info: drawtextinfoty; +begin + info.text:= text; + info.dest.pos:= nullpoint; + info.dest.cx:= width; + info.dest.cy:= bigint; + info.flags:= [tf_wordbreak]; + info.font:= font; + info.tabulators:= nil; + result:= breaklines(canvas,info); +end; + +function breaklines(const canvas: tcanvas; const text: msestring; + const width: integer; font: tfont = nil): msestringarty; +var + rstr1: richstringty; + ar1: richstringarty; + int1: integer; +begin + rstr1.format:= nil; + rstr1.text:= text; + ar1:= breaklines(canvas,rstr1,width,font); + setlength(result,length(ar1)); + for int1:= 0 to high(ar1) do begin + result[int1]:= ar1[int1].text; + end; +end; + +procedure adjustellipse(const acanvas: tcanvas; const info: drawtextinfoty; + const layoutinfo: layoutinfoty; + const line: integer; var startx: integer; + out startindex: integer; out endindex: integer); +var + ellipsewidth,ellipsewidthsum: integer; + int1: integer; +begin + with info,layoutinfo,lineinfos[line] do begin + startindex:= liindex; + endindex:= liindex + licount - 1; + if (liwidth > dest.cx) and (flags * ellipsemask <> []) then begin + ellipsewidth:= acanvas.getstringwidth(textellipse); + ellipsewidthsum:= liwidth + ellipsewidth; + if tf_ellipseleft in flags then begin + startindex:= licount; + for int1:= liindex-1 to liindex+licount-2 do begin + dec(ellipsewidthsum,charwidths[int1]); + if ellipsewidthsum < dest.cx then begin + startindex:= int1+2; + break; + end; + end; + startx:= startx + ellipsewidth; + end + else begin + for int1:= liindex+licount-2 downto liindex-1 do begin + dec(ellipsewidthsum,charwidths[int1]); + if ellipsewidthsum < dest.cx then begin + endindex:= int1; + break; + end; + end; + end; + if tf_right in flags then begin + startx:= startx + (liwidth-ellipsewidthsum); + end + else begin + if tf_xcentered in flags then begin + startx:= startx + (liwidth-ellipsewidthsum) div 2; + end; + end; + end; + end; +end; + +function postotextindex(const canvas: tcanvas; var info: drawtextinfoty; + const pos: pointty; out aindex: integer): boolean; + //false if out of text +var + layoutinfo: layoutinfoty; + int1,int2: integer; + startindex,endindex: integer; +begin + result:= true; + with info,canvas,layoutinfo do begin + if text.text = '' then begin + result:= false; + aindex:= 0; + exit; + end; + layouttext(canvas,info,layoutinfo); + if pos.y < res.y then begin + result:= false; + aindex:= 0; + end + else begin + if pos.y >= res.y + height then begin + aindex:= length(text.text); + result:= false; + end + else begin + int1:= (pos.y-starty+ascent) div lineheight; + if int1 > high(lineinfos) then begin + int1:= high(lineinfos); //last line is ascent+descent + end; + with lineinfos[int1] do begin + int2:= listartx; + adjustellipse(canvas,info,layoutinfo,int1,int2,startindex,endindex); +// int3:= liindex + licount - 1; + aindex:= endindex; + result:= false; +// for int1:= liindex-1 to liindex+licount-2 do begin + for int1:= startindex-1 to endindex-1 do begin + inc(int2,charwidths[int1]); + if int2 >= pos.x then begin + aindex:= int1; + result:= true; + break; + end; + end; + if aindex < endindex then begin + if int2 - pos.x < charwidths[aindex] div 2 then begin + inc(aindex); + end; + end; + end; + end; + end; + end; +end; + +function textindextopos(const canvas: tcanvas; var info: drawtextinfoty; + aindex: integer): pointty; +var + layoutinfo: layoutinfoty; + int1,int2,int3: integer; + startindex,endindex: integer; +begin + with info,layoutinfo do begin + layouttext(canvas,info,layoutinfo); + if aindex > length(text.text) then begin + aindex:= length(text.text); + end + else begin + if aindex < 0 then begin + aindex:= 0; + end; + end; + int3:= 0; //compiler warning + for int1:= 0 to high(lineinfos) do begin + with lineinfos[int1] do begin + if liindex + licount > aindex then begin + int3:= int1; + break; + end; + end; + end; + result.y:= starty + int3 * lineheight; + with lineinfos[int3] do begin + int2:= listartx; + adjustellipse(canvas,info,layoutinfo,int3,int2,startindex,endindex); +// for int1:= liindex-1 to aindex-1 do begin + for int1:= startindex-1 to aindex-1 do begin + inc(int2,charwidths[int1]); + end; + result.x:= int2; + end; + end; +end; + +procedure drawtext(const canvas: tcanvas; var info: drawtextinfoty); +const + stopmask = [ni_bold,ni_italic,ni_blank,ni_underline,ni_strikeout,ni_selected, + ni_fontcolor,ni_colorbackground]; + fonthandlemask = [ni_bold,ni_italic]; + fontstylemask = [ni_bold,ni_italic,ni_blank,ni_underline,ni_strikeout]; + +var + layoutinfo: layoutinfoty; + pos: pointty; + infoindexbefore,charindexbefore: integer; + last: boolean; + count: integer; + defaultcolor,defaultcolorbackground: colorty; + afontstyle,fontstylebefore,overridefontstyle: fontstylesty; + grayed: boolean; + formatactive: boolean; + endindex: integer; + ellipsewidthsum: integer; + rot: real; + + procedure drawsubstring(const row,astart,acount: integer); + var + int2,int3,int4,int5,int6: integer; + xbefore: integer; + x: integer; + co1: colorty; + begin + if acount > 0 then begin + if layoutinfo.xyswapped then begin + x:= pos.y; + end + else begin + x:= pos.x; + end; + xbefore:= x; + + with info,tcanvas1(canvas),layoutinfo,lineinfos[row] do begin + if tabchars = nil then begin + drawstring(@text.text[astart],acount,pos,nil,grayed,rot); + for int2:= astart - 1 to astart + acount - 2 do begin + inc(x,charwidths[int2]); + end; + end + else begin + int2:= astart - 1; + for int4:= 0 to high(tabchars) do begin + if (tabchars[int4].index >= astart) and + (tabchars[int4].index < astart + acount) then begin + drawstring(@text.text[int2+1],tabchars[int4].index - int2 - 1,pos,nil, + grayed,rot); + for int2:= int2 to tabchars[int4].index - 1 do begin + inc(x,charwidths[int2]); + end; + int3:= charwidths[tabchars[int4].index - 1]; + co1:= font.colorbackground; + if (co1 <> cl_transparent) and (co1 <> cl_default) then begin + if xyswapped then begin + if reversed then begin + fillrect(makerect(pos.x-font.descent,x - int3, + font.ascent+font.descent,int3),font.colorbackground); + end + else begin + fillrect(makerect(pos.x-font.ascent,x - int3 - 1, + font.ascent+font.descent,int3),font.colorbackground); + end; + end + else begin + if reversed then begin + fillrect(makerect(x - int3 - 1,pos.y-font.descent,int3, + font.ascent+font.descent),font.colorbackground); + end + else begin + fillrect(makerect(x - int3,pos.y-font.ascent,int3, + font.ascent+font.descent),font.colorbackground); + end; + end; + end; + with tabchars[int4] do begin + int2:= index; + int5:= pos.y - font.ascent div 2; + int6:= x - int3 div 2 + 1; + if (tf_showtabs in flags) and (kind <> tabulatorkindty(-1)) and + not xyswapped and not reversed then begin + drawline(mp(int6 - 3,int5),mp(int6,int5),font.color); + drawlines([mp(int6,int5-1),mp(int6+1,int5), + mp(int6,int5+1)],true,font.color); + { + case kind of + tak_left: begin + drawlines([mp(linepos,int5-2),mp(linepos,int5), + mp(linepos+2,int5)],false,font.color); + end; + tak_right: begin + drawlines([mp(linepos,int5-2),mp(linepos,int5), + mp(linepos-2,int5)],false,font.color); + end; + tak_centered,tak_decimal: begin + drawlinesegments([mg(mp(linepos,int5-2),mp(linepos,int5)), + mg(mp(linepos-2,int5),mp(linepos+2,int5))],font.color); + end; + end; + } + end; + end; + if xyswapped then begin + pos.y:= x; + end + else begin + pos.x:= x; + end; + end; + end; + int3:= acount - int2 + astart - 1; + drawstring(@text.text[int2+1],int3,pos,nil,grayed,rot); + for int2:= int2 to int2 + int3 - 1 do begin + inc(x,charwidths[int2]); + end; + end; + if not grayed then begin + if fs_underline in canvas.font.style then begin + if xyswapped then begin + drawfontline(makepoint(pos.x+underline,xbefore), + makepoint(pos.x+underline,x-1)); + end + else begin + drawfontline(makepoint(xbefore,pos.y+underline), + makepoint(x-1,pos.y+underline)); + end; + end; + if fs_strikeout in font.style then begin + if xyswapped then begin + drawfontline(makepoint(pos.x+layoutinfo.strikeout,xbefore), + makepoint(pos.x+layoutinfo.strikeout,x-1)); + end + else begin + drawfontline(makepoint(xbefore,pos.y+layoutinfo.strikeout), + makepoint(x-1,pos.y+layoutinfo.strikeout)); + end; + end; + end; + if layoutinfo.xyswapped then begin + pos.y:= x; + end + else begin + pos.x:= x; + end; + end; + end; + end; + + procedure adjustellipsepos(delta: integer); + begin + if tf_right in info.flags then begin + pos.x:= pos.x - delta; + end + else begin + if tf_xcentered in info.flags then begin + pos.x:= pos.x - delta div 2; + end; + end; + end; + + procedure updatefont(const aformat: formatinfoty); + begin + with aformat,info,canvas do begin + if newinfos * fontstylemask <> [] then begin + afontstyle:= afontstyle * fontstylesty( + not {$ifdef FPC}longword({$else}byte(word{$endif}(newinfos))) + + style.fontstyle; + font.style:= afontstyle + overridefontstyle; + end; + if (ni_selected in newinfos) and not (tf_noselect in flags)then begin + if tf_underlineselect in flags then begin + if not (fs_underline in style.fontstyle) then begin + if fs_selected in style.fontstyle then begin + font.style:= font.style + [fs_underline]; + end + else begin + font.style:= font.style - [fs_underline]; + end; + end; + end + else begin + if (fs_selected in style.fontstyle) then begin + if font.colorselect = cl_default then begin + font.color:= cl_selectedtext; + end + else begin + font.color:= font.colorselect; + end; + if font.colorselectbackground = cl_default then begin + font.colorbackground:= cl_selectedtextbackground; + end + else begin + font.colorbackground:= font.colorselectbackground; + end; + end + else begin + if style.fontcolor = 0 then begin + font.color:= defaultcolor; + end + else begin + font.color:= not style.fontcolor; + end; + if style.colorbackground = 0 then begin + font.colorbackground:= defaultcolorbackground; + end + else begin + font.colorbackground:= not style.colorbackground; + end; + end; + end; + end; + if not (fs_selected in style.fontstyle) or + (tf_underlineselect in flags) then begin + if ni_fontcolor in newinfos then begin + if style.fontcolor = 0 then begin + font.color:= defaultcolor; + end + else begin + font.color:= not style.fontcolor; + end; + end; + if ni_colorbackground in newinfos then begin + if style.colorbackground = 0 then begin + font.colorbackground:= defaultcolorbackground; + end + else begin + font.colorbackground:= not style.colorbackground; + end; + end; + end; + end; + end; + +var + row: integer; + ellipsewidth: integer; + int1,int3{,int4}: integer; + lastover: boolean; + textbackup: msestring; + formatbackup: formatinfoarty; + +label + endlab; + +begin //drawtext + with info,tcanvas1(canvas) do begin + if tf_rotate90 in flags then begin + if tf_rotate180 in flags then begin + rot:= 1.5*pi; + end + else begin + rot:= 0.5*pi; + end; + end + else begin + if tf_rotate180 in flags then begin + rot:= pi; + end + else begin + rot:= 0; + end; + end; + if tf_tabtospace in flags then begin + textbackup:= text.text; //backup + replacechar1(text.text,msechar(c_tab),msechar(' ')); + end; + if flags * ellipsemask <> [] then begin + formatbackup:= text.format; + text.format:= nil; //no format handling with ellipse + end; + try + if cs_internaldrawtext in fstate then begin + internaldrawtext(info); + exit; + end; + save; + if tf_clipi in flags then begin + intersectcliprect(dest); + end; + if tf_clipo in flags then begin + intersectcliprect(clip); + end; + if text.text = '' then begin + info.res:= nullrect; + goto endlab; + end; + layouttext(canvas,info,layoutinfo); + defaultcolor:= font.color; + defaultcolorbackground:= font.colorbackground; + fontstylebefore:= font.style; + afontstyle:= fontstylebefore; + overridefontstyle:= afontstyle * [fs_bold,fs_italic,fs_underline]; + grayed:= tf_grayed in flags; + if info.text.format <> nil then begin + infoindexbefore:= -1; + int1:= 0; //format index + row:= 0; //layoutinfo row index + lastover:= false; + while row <= high(layoutinfo.lineinfos) do begin + with layoutinfo.lineinfos[row] do begin + if layoutinfo.xyswapped then begin + pos.x:= liy; + pos.y:= listartx; + end + else begin + pos.y:= liy; + pos.x:= listartx; + end; + charindexbefore:= liindex-1; + endindex:= charindexbefore + licount; + end; + while true do begin + with text.format[int1] do begin + formatactive:= (index < endindex); + last:= (int1 >= high(text.format)) or not formatactive; + if last or (newinfos * stopmask <> []) then begin + if infoindexbefore >= 0 then begin + updatefont(text.format[infoindexbefore]); + end; + if formatactive and not lastover then begin + count:= text.format[int1].index - charindexbefore; + if count > 0 then begin + drawsubstring(row,charindexbefore+1,count); + inc(charindexbefore,count); + end; + infoindexbefore:= int1; + if last then begin + updatefont(text.format[int1]); + count:= endindex - charindexbefore; + drawsubstring(row,charindexbefore+1,count); + inc(charindexbefore,count); + lastover:= true; + break; + end; + end + else begin + drawsubstring(row,charindexbefore+1,endindex - charindexbefore); + break; + end; + end; + end; + inc(int1); + end; + inc(row); + end; + font.color:= defaultcolor; + font.colorbackground:= defaultcolorbackground; + font.style:= fontstylebefore; + end + else begin + for row:= 0 to high(layoutinfo.lineinfos) do begin + with layoutinfo.lineinfos[row] do begin + if layoutinfo.xyswapped then begin + pos.x:= liy; + pos.y:= listartx; + end + else begin + pos.y:= liy; + pos.x:= listartx; + end; + if (liwidth > dest.cx) and (flags * ellipsemask <> []) then begin + ellipsewidth:= getstringwidth(textellipse); + ellipsewidthsum:= liwidth + ellipsewidth; + int1:= liindex; + if tf_ellipseleft in flags then begin + int3:= liindex + licount; + while int1 < int3 do begin + dec(ellipsewidthsum,layoutinfo.charwidths[int1-1]); + inc(int1); + if ellipsewidthsum <= dest.cx then begin + break; + end; + end; + adjustellipsepos(ellipsewidthsum -liwidth); + drawstring(textellipse,pos,nil,tf_grayed in flags); + inc(pos.x,ellipsewidth); + dec(licount,int1-liindex); + liindex:= int1; + drawsubstring(row,liindex,licount); + end + else begin + if tf_ellipseright in flags then begin + int1:= int1 + licount; + while int1 > liindex do begin + dec(int1); + dec(ellipsewidthsum,layoutinfo.charwidths[int1-1]); + if ellipsewidthsum <= dest.cx then begin + break; + end; + end; + end; + licount:= int1 - liindex; + adjustellipsepos(ellipsewidthsum -liwidth); + drawsubstring(row,liindex,licount); + drawstring(textellipse,pos,nil,tf_grayed in flags); + end; + end + else begin + drawsubstring(row,liindex,licount); + end; + inc(pos.y,layoutinfo.lineheight); + end; + end; + end; +endlab: + restore; + finally + if tf_tabtospace in flags then begin + text.text:= textbackup; + end; + if flags * ellipsemask <> [] then begin + text.format:= formatbackup; + end; + end; + end; +end; + +procedure drawtext(const canvas: tcanvas; const text: richstringty; + const dest: rectty; flags: textflagsty = []; + font: tfont = nil; tabulators: tcustomtabulators = nil); +var + info: drawtextinfoty; +begin + info.text:= text; + info.dest:= dest; + info.flags:= flags - [tf_clipo]; + info.font:= font; + info.tabulators:= tabulators; + drawtext(canvas,info); +end; + +procedure drawtext(const canvas: tcanvas; const text: richstringty; + const dest,clip: rectty; flags: textflagsty = []; + font: tfont = nil; tabulators: tcustomtabulators = nil); +var + info: drawtextinfoty; +begin +// info.canvas:= canvas; + info.text:= text; + info.dest:= dest; + info.clip:= clip; + info.flags:= flags; + info.font:= font; + info.tabulators:= tabulators; + drawtext(canvas,info); +end; + +procedure drawtext(const canvas: tcanvas; const text: msestring; + const dest,clip: rectty; flags: textflagsty = []; + font: tfont = nil; tabulators: tcustomtabulators = nil); +var + info: drawtextinfoty; +begin +// info.canvas:= canvas; + info.text.format:= nil; + info.text.text:= text; + info.dest:= dest; + info.clip:= clip; + info.flags:= flags; + info.font:= font; + info.tabulators:= tabulators; + drawtext(canvas,info); +end; + +procedure drawtext(const canvas: tcanvas; const text: msestring; + const dest: rectty; flags: textflagsty = []; + font: tfont = nil; tabulators: tcustomtabulators = nil); +var + ristr1: richstringty; +begin + ristr1.text:= text; + ristr1.format:= nil; + drawtext(canvas,ristr1,dest,flags,font,tabulators); +end; + +procedure textrect(const canvas: tcanvas; var info: drawtextinfoty); +var + layoutinfo: layoutinfoty; +begin + layouttext(canvas,info,layoutinfo); +end; + +function textclipped(const canvas: tcanvas; var info: drawtextinfoty): boolean; +begin + textrect(canvas,info); + result:= not rectinrect(info.res,info.dest); +end; + +function textrect(const canvas: tcanvas; const text: richstringty; + const dest: rectty; flags: textflagsty = []; + font: tfont = nil; tabulators: tcustomtabulators = nil): rectty; +var + info: drawtextinfoty; +begin + info.text:= text; + info.dest:= dest; +// info.clip:= dest; + info.flags:= flags - [tf_clipo]; + info.font:= font; + info.tabulators:= tabulators; + textrect(canvas,info); + result:= info.res; +end; + +function textrect(const canvas: tcanvas; const text: richstringty; + flags: textflagsty = []; font: tfont = nil; + tabulators: tcustomtabulators = nil): rectty; overload; +begin + flags:= flags - [tf_right,tf_bottom,tf_xcentered,tf_ycentered]; + result:= textrect(canvas,text,makerect(0,0,bigint,bigint),flags,font,tabulators); +end; + +function textrect(const canvas: tcanvas; const text: msestring; + const dest: rectty; flags: textflagsty = []; + font: tfont = nil; tabulators: tcustomtabulators = nil): rectty; +var + str1: richstringty; +begin + str1.text:= text; + result:= textrect(canvas,str1,dest,flags,font,tabulators); +end; + +function textrect(const canvas: tcanvas; const text: msestring; + flags: textflagsty = []; font: tfont = nil; + tabulators: tcustomtabulators = nil): rectty; +var + str1: richstringty; +begin + str1.text:= text; + result:= textrect(canvas,str1,flags,font,tabulators); +end; + +{ ttabulatoritem } + +procedure ttabulatoritem.setkind(const avalue: tabulatorkindty); +begin + if fkind <> avalue then begin + fkind:= avalue; + tcustomtabulators(fowner).changed(self); + end; +end; + +procedure ttabulatoritem.setpos(const avalue: real); +begin + if fpos <> avalue then begin + fpos:= avalue; + tcustomtabulators(fowner).changed(self); + end; +end; + +procedure ttabulatoritem.setdistleft(const avalue: real); +begin + if fdistleft <> avalue then begin + fdistleft:= avalue; + tcustomtabulators(fowner).changed(self); + end; +end; + +procedure ttabulatoritem.setdistright(const avalue: real); +begin + if fdistright <> avalue then begin + fdistright:= avalue; + tcustomtabulators(fowner).changed(self); + end; +end; + +function ttabulatoritem.getenabled(): boolean; +begin + result:= true; +end; + +{ tcustomtabulators } + +constructor tcustomtabulators.create; +begin + fppmm:= defaultppmm; + inherited create(self,getitemclass); +end; + +class function tcustomtabulators.getitemclasstype: persistentclassty; +begin + result:= getitemclass; +end; + +procedure tcustomtabulators.assign(source: tpersistent); +var + int1: integer; +begin + if source is tcustomtabulators then begin + beginupdate; + with tcustomtabulators(source) do begin + self.count:= count; + for int1:= 0 to high(fitems) do begin + ttabulatoritem(self.fitems[int1]).fkind:= ttabulatoritem(fitems[int1]).fkind; + ttabulatoritem(self.fitems[int1]).fpos:= ttabulatoritem(fitems[int1]).fpos; + end; + self.fdefaultdist:= fdefaultdist; + end; + endupdate; + end + else begin + inherited; + end; +end; + +class function tcustomtabulators.getitemclass: tabulatoritemclassty; +begin + result:= ttabulatoritem; +end; + +procedure tcustomtabulators.changed(const sender: ttabulatoritem); +begin + dochange(-1); +end; + +procedure tcustomtabulators.dochange(const index: integer); +begin + fuptodate:= false; + inherited; +end; + +procedure tcustomtabulators.add(const apos: real; const akind: tabulatorkindty); +begin + beginupdate; + count:= count + 1; + with ttabulatoritem(fitems[high(fitems)]) do begin + fpos:= apos; + fkind:= akind; + end; + endupdate; +end; + +procedure tcustomtabulators.setdefaulttabs(const awidth: real; + const acount: integer; const akind: tabulatorkindty); +var + int1: integer; +begin + beginupdate; + count:= acount; + for int1:= 0 to high(fitems) do begin + with ttabulatoritem(fitems[int1]) do begin + fpos:= (int1+1)*awidth; + fkind:= akind; + end; + end; + endupdate; +end; + +procedure tcustomtabulators.setppmm(const avalue: real); +begin + if fppmm <> avalue then begin + fppmm:= avalue; + changed(nil); + end; +end; + +function cmptab(const l,r): integer; +begin + result:= tabulatorty(l).linepos - tabulatorty(r).linepos; +end; + +procedure tcustomtabulators.checkuptodate; +var + int1: integer; + prevtab,nexttab: int32; +begin + if not fuptodate then begin + setlength(ftabs,count); + for int1:= 0 to high(ftabs) do begin + with ftabs[int1] do begin + index:= int1; + with ttabulatoritem(fitems[int1]) do begin + tabkind:= fkind; + linepos:= round(fpos*fppmm); + case kind of + tak_left: begin + textpos:= round((fpos + fdistleft)*fppmm); + end; + tak_right{,tak_decimal}: begin + textpos:= round((fpos - fdistright)*fppmm); + end; + else begin //tak_center +// textpos:= round((fpos + (fdistleft - fdistright))*fppmm); + textpos:= linepos; + end; + end; + end; + end; + end; + sortarray(ftabs,sizeof(ftabs[0]),{$ifdef FPC}@{$endif}cmptab); + for int1:= 0 to high(ftabs) do begin + with ftabs[int1],ttabulatoritem(fitems[index]) do begin + prevtab:= int1-1; + while (prevtab >= 0) and + not ttabulatoritem(fitems[ftabs[prevtab].index]).getenabled do begin + dec(prevtab); + end; + nexttab:= int1+2; + while (nexttab <= high(fitems)) and + not ttabulatoritem(fitems[ftabs[nexttab].index]).getenabled do begin + inc(nexttab); + end; + if nexttab <= high(ftabs) then begin + cellwidth:= ftabs[nexttab].linepos - linepos; + end + else begin + cellwidth:= 0; + end; + case tabkind of + tak_right,tak_decimal: begin + width:= -round(fdistleft*fppmm); + if prevtab >= 0 then begin + width:= textpos - ftabs[prevtab].linepos + width; + end + else begin + width:= textpos + width; + end; + end; + tak_centered: begin + width:= -round((fdistright+fdistleft)*fppmm); + if (prevtab >= 0) and (nexttab <= high(ftabs)) then begin + width:= ftabs[nexttab].linepos - ftabs[prevtab].linepos + width; + end + else begin + width:= 2 * linepos + width; + end; + end; + else begin //tak_left + width:= -round((fdistright)*fppmm); + if nexttab <= high(ftabs) then begin + width:= ftabs[nexttab].linepos - textpos + width + end; + end; + end; + end; + end; + fuptodate:= true; + end; +end; + +function tcustomtabulators.gettabs: tabulatorarty; +begin + checkuptodate; + result:= ftabs; +end; + +function tcustomtabulators.getitems(const index: integer): ttabulatoritem; +begin + result:= ttabulatoritem(inherited getitems(index)); +end; + +procedure tcustomtabulators.setitems(const index: integer; const avalue: ttabulatoritem); +begin + getitems(index).assign(avalue); +end; + +procedure tcustomtabulators.setdefaultdist(const avalue: real); +begin + fdefaultdist:= avalue; + if fdefaultdist < 0 then begin + fdefaultdist:= 0; + end; + dochange(-1); +end; + +function tcustomtabulators.getpos(const index: integer): integer; +var + int1: integer; +begin + checkuptodate; + if index <= high(ftabs) then begin + result:= ftabs[index].textpos; + end + else begin + if length(ftabs) > 0 then begin + if fdefaultdist > 0 then begin + int1:= trunc(ftabs[high(ftabs)].linepos/fdefaultdist); + end + else begin + result:= ftabs[high(ftabs)].textpos; + exit; + end; + end + else begin + int1:= 0; + end; + result:= round((int1 + index - high(ftabs)) * fdefaultdist); + end; +end; + +function tcustomtabulators.getlinepos(const index: integer): integer; +var + int1: integer; +begin + checkuptodate; + if index <= high(ftabs) then begin + result:= ftabs[index].linepos; + end + else begin + if length(ftabs) > 0 then begin + if fdefaultdist > 0 then begin + int1:= trunc(ftabs[high(ftabs)].linepos/fdefaultdist); + end + else begin + result:= ftabs[high(ftabs)].linepos; + exit; + end; + end + else begin + int1:= 0; + end; + result:= round((int1 + index - high(ftabs)) * fdefaultdist); + end; +end; + +procedure tcustomtabulators.setlinepos(const index: integer; + const avalue: integer); +begin + checkuptodate; + checkindex(index); + ttabulatoritem(fitems[ftabs[index].index]).pos:= avalue / ppmm; +end; + +end. diff --git a/mseide-msegui/lib/common/graphics/mseellipsetria.pas b/mseide-msegui/lib/common/graphics/mseellipsetria.pas new file mode 100644 index 0000000..ac46493 --- /dev/null +++ b/mseide-msegui/lib/common/graphics/mseellipsetria.pas @@ -0,0 +1,522 @@ +{ MSEgui Copyright (c) 2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseellipsetria; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msegraphics,msegraphutils,msetriaglob; + +procedure fillellipsetria(var drawinfo: drawinfoty; out apoints: ppointty; + out apointcount: integer); + //returns trifan +procedure fillarctria(var drawinfo: drawinfoty; out apoints: ppointty; + out apointcount: integer); + //returns trifan +function arctria(var drawinfo: drawinfoty; out apoints: ppointty; + out apointcount: integer): boolean; + //true if triangles, tristrip otherwise +function ellipsetria(var drawinfo: drawinfoty; out apoints: ppointty; + out apointcount: integer): boolean; + //true if triangles, tristrip otherwise + + +implementation +uses + mselinetria; + +procedure adjustellipsecenter(const drawinfo: drawinfoty; + var center: pointty); +begin + with drawinfo,rect.rect^ do begin + center.x:= (x+origin.x) shl 16; + if not odd(cx) then begin + center.x:= center.x + $8000; + end + else begin + center.x:= center.x + $10000; + end; + center.y:= (y+origin.y) shl 16; + if not odd(cy) then begin + center.y:= center.y + $8000; + end + else begin + center.y:= center.y + $10000; + end; + end; +end; + +procedure fillellipsetria(var drawinfo: drawinfoty; out apoints: ppointty; + out apointcount: integer); +//todo: optimize +var + rea1,sx,sy,f,si,co: real; + x1,y1: integer; + q0,q1,q2,q3: ppointty; + npoints: integer; + int1: integer; + center: pointty; +begin + with drawinfo,drawinfo.rect.rect^ do begin + int1:= cx; + if cy > int1 then begin + int1:= cy; + end; + if int1 = 0 then begin + apointcount:= 0; + apoints:= nil; + exit; + end; + int1:= (int1+1) div 2; //samples per quadrant + rea1:= pi/(2*int1); + npoints:= 2+4*int1; //center + endpoint + allocbuffer(buffer,npoints*sizeof(pointty)); + si:= sin(rea1); + co:= cos(rea1); + adjustellipsecenter(drawinfo,center); + q0:= buffer.buffer; + q0^:= center; + inc(q0); + q1:= q0+int1; + q2:= q1+int1; + q3:= q2+int1; + if cx > cy then begin + f:= cy/cx; + sx:= cx*(65536/2); + sy:= 0; + for int1:= int1-1 downto 0 do begin + y1:= round(sy*f); + x1:= round(sx); + q0^.x:= center.x + x1; + q0^.y:= center.y - y1; + inc(q0); + q2^.x:= center.x - x1; + q2^.y:= center.y + y1; + inc(q2); + x1:= round(sx*f); + y1:= round(sy); + q1^.x:= center.x - y1; + q1^.y:= center.y - x1; + inc(q1); + q3^.x:= center.x + y1; + q3^.y:= center.y + x1; + inc(q3); + rea1:= sx; + sx:= co*sx-si*sy; + sy:= co*sy+si*rea1; + end; + end + else begin + f:= cx/cy; + sy:= cy*(65536/2); + sx:= 0; + for int1:= int1-1 downto 0 do begin + x1:= round(sx*f); + y1:= round(sy); + q0^.y:= center.y - y1; + q0^.x:= center.x + x1; + inc(q0); + q2^.y:= center.y + y1; + q2^.x:= center.x - x1; + inc(q2); + y1:= round(sy*f); + x1:= round(sx); + q1^.y:= center.y - x1; + q1^.x:= center.x - y1; + inc(q1); + q3^.y:= center.y + x1; + q3^.x:= center.x + y1; + inc(q3); + rea1:= sx; + sx:= co*sx-si*sy; + sy:= co*sy+si*rea1; + end; + end; + q3^:= (ppointty(buffer.buffer)+1)^; //endpoint + apoints:= buffer.buffer; + apointcount:= npoints; + end; +end; + +procedure fillarctria(var drawinfo: drawinfoty; out apoints: ppointty; + out apointcount: integer); + //returns trifan +var + rea1,sx,sy,cx1,cy1,si,co: real; + x1,y1: integer; + q0: ppointty; + npoints: integer; + int1: integer; + center: pointty; +begin + with drawinfo,triagcty(gc.platformdata).d,drawinfo.arc,rect^ do begin + int1:= cx; + if cy > int1 then begin + int1:= cy; + end; + if int1 = 0 then begin + apointcount:= 0; + apoints:= nil; + exit; + end; + int1:= round(int1*abs(extentang)/pi); //steps + adjustellipsecenter(drawinfo,center); + cx1:= cx * (65536 div 2); + cy1:= cy * (65536 div 2); + sx:= cos(startang); + sy:= sin(startang); + rea1:= extentang/int1; //step + si:= sin(rea1); + co:= cos(rea1); + npoints:= int1+2; //center + endpoint + allocbuffer(buffer,npoints*sizeof(pointty)); + q0:= ppointty(buffer.buffer)+1; + for int1:= int1 downto 0 do begin + x1:= round(cx1*sx); + y1:= round(cy1*sy); + q0^.x:= center.x + x1; + q0^.y:= center.y - y1; + inc(q0); + rea1:= sx; + sx:= co*sx-si*sy; + sy:= co*sy+si*rea1; + end; + if not pieslice then begin + dec(q0); + with (ppointty(buffer.buffer)+1)^ do begin + center.x:= (q0^.x + x) div 2; + center.y:= (q0^.y + y) div 2; + end; + end; + ppointty(buffer.buffer)^:= center; + apoints:= buffer.buffer; + apointcount:= npoints; + end; +end; + +function arctria(var drawinfo: drawinfoty; out apoints: ppointty; + out apointcount: integer): boolean; +var + rea1,sx,sy,w,cxw,cyw,cx1,cy1,cx2,cy2,{xdy,ydx,}si,co: real; + x1,y1,x2,y2,x3,y3,x4,y4: integer; + q0: ppointty; +// po1: ptrianglety; + npoints: integer; + int1: integer; + center: pointty; + circle,lineendings: boolean; + step,dashstep,dashsum: real; + dashindex: integer; + wasoff: boolean; + li: lineshiftinfoty; + shiftfact: integer; +begin + result:= false; + dashstep:= 0; + x2:= 0; + y2:= 0; + with drawinfo,drawinfo.arc,rect^,triagcty(gc.platformdata).d do begin + lineendings:= not (trf_capbutt in triaflags); + li.offsx:= 0; + li.offsy:= 0; + int1:= cx; + if cy > int1 then begin + int1:= cy; + end; + if int1 = 0 then begin + apoints:= nil; + apointcount:= 0; + exit; + end; + li.reverse:= extentang >= 0; + if li.reverse then begin + shiftfact:= -2; + end + else begin + shiftfact:= 2; + end; + int1:= round(int1*abs(extentang)/pi); //steps + if int1 = 0 then begin + int1:= 1; + end; + adjustellipsecenter(drawinfo,center); + cx1:= cx * (65536 div 2); + cx2:= cx1*cx1; + cy1:= cy * (65536 div 2); + cy2:= cy1*cy1; + w:= linewidth16 div 2; + cxw:= cx1*w; + cyw:= cy1*w; + sx:= cos(startang); + sy:= sin(startang); + if df_dashed in gc.drawingflags then begin + result:= true; + int1:= int1*4; //quarter pixel resolution + circle:= cx = cy; + step:= extentang/int1; //step + si:= sin(step); + co:= cos(step); + if not li.reverse then begin + step:= - step; + end; + if circle then begin + dashstep:= cx*step/2; //constant + end + else begin + step:= step / 65536; //variable dashstep + end; + dashsum:= -ord(xftdashes[1]); + dashindex:= 1; + wasoff:= true; + allocbuffer(buffer,(6*int1+12)*sizeof(pointty)); + //+ start dummy + endpoint, max + q0:= ppointty(buffer.buffer)+2; + for int1:= 0 to int1 do begin + x1:= round(cx1*sx); + y1:= round(cy1*sy); + rea1:= sqrt(cx2*sy*sy+cy2*sx*sx); + if odd(dashindex) then begin + if rea1 = 0 then begin + x2:= round(w); + y2:= 0; + end + else begin + x2:= round(cyw*sx/rea1); + y2:= round(cxw*sy/rea1); + end; + x3:= center.x + x1 + x2; + y3:= center.y - y1 - y2; + x4:= center.x + x1 - x2; + y4:= center.y - y1 + y2; + if not wasoff then begin + q0^.x:= x3; + q0^.y:= y3; + inc(q0); + q0^:= (q0-2)^; + inc(q0); + q0^.x:= x3; + q0^.y:= y3; + inc(q0); + q0^.x:= x4; + q0^.y:= y4; + inc(q0); + end; + q0^.x:= x3; + q0^.y:= y3; + inc(q0); + q0^.x:= x4; + q0^.y:= y4; + inc(q0); + if lineendings and wasoff then begin + li.v.shift.x:= shiftfact*x2; + li.v.shift.y:= shiftfact*y2; + li.dest:= q0; + updatestarttria(drawinfo,li); + q0:= li.dest; + end; + wasoff:= false; + end + else begin + if not wasoff then begin + wasoff:= true; + dec(q0,2); + if lineendings then begin + li.v.shift.x:= shiftfact*x2; + li.v.shift.y:= shiftfact*y2; + li.dest:= q0; + updateendtria(drawinfo,li); + q0:= li.dest; + end; + end; + end; + if not circle then begin + dashstep:= rea1*step; + end; + dashsum:= dashsum + dashstep; + if dashsum >= 0 then begin + inc(dashindex); + if dashindex > length(xftdashes) then begin + dashindex:= 1; + end; + dashsum:= dashsum-ord(xftdashes[dashindex]); + end; + rea1:= sx; + sx:= co*sx-si*sy; + sy:= co*sy+si*rea1; + end; + if odd(dashindex) then begin + dec(q0,2); + if lineendings then begin + li.v.shift.x:= shiftfact*x2; + li.v.shift.y:= shiftfact*y2; + li.dest:= q0; + updateendtria(drawinfo,li); + q0:= li.dest; + end; + end; + apoints:= ppointty(buffer.buffer)+2; + apointcount:= q0-apoints; + end + else begin + rea1:= extentang/int1; //step + si:= sin(rea1); + co:= cos(rea1); + npoints:= 2*(int1+linewidth1)+2; //+ endpoint + round caps + allocbuffer(buffer,npoints*sizeof(pointty)); + q0:= buffer.buffer; + for int1:= 0 to int1 do begin + x1:= round(cx1*sx); + y1:= round(cy1*sy); + rea1:= sqrt(cx2*sy*sy+cy2*sx*sx); + if rea1 = 0 then begin + x2:= round(w); + y2:= 0; + end + else begin + x2:= round(cyw*sx/rea1); + y2:= round(cxw*sy/rea1); + end; + q0^.x:= center.x + x1 + x2; + q0^.y:= center.y - y1 - y2; + inc(q0); + q0^.x:= center.x + x1 - x2; + q0^.y:= center.y - y1 + y2; + inc(q0); + if lineendings and (int1 = 0) then begin + li.v.shift.x:= shiftfact*x2; + li.v.shift.y:= shiftfact*y2; + li.dest:= q0; + updatestartstrip(drawinfo,li); + q0:= li.dest; + end; + rea1:= sx; + sx:= co*sx-si*sy; + sy:= co*sy+si*rea1; + end; + if lineendings then begin + li.v.shift.x:= shiftfact*x2; + li.v.shift.y:= shiftfact*y2; + li.dest:= q0; + updateendstrip(drawinfo,li); + q0:= li.dest; + end; + apoints:= buffer.buffer; + apointcount:= q0-apoints; + end; + end; +end; + +function ellipsetria(var drawinfo: drawinfoty; out apoints: ppointty; + out apointcount: integer): boolean; +var + rea1,sx,sy,w,cxw,cyw,cx1,cy1,cx2,cy2,{xdy,ydx,}si,co: real; + x1,y1,x2,y2: integer; + q0,q1,q2,q3: ppointty; + npoints: integer; + int1,int2: integer; + center: pointty; + circle: boolean; +begin + result:= false; + with drawinfo,rect.rect^,triagcty(gc.platformdata).d do begin + if df_dashed in gc.drawingflags then begin + arc.startang:= 0; + arc.extentang:= 2*pi; + result:= arctria(drawinfo,apoints,apointcount); + exit; + end; + circle:= cx = cy; + int1:= cx; + if cy > int1 then begin + int1:= cy; + end; + if int1 = 0 then begin + apoints:= nil; + apointcount:= 0; + exit; + end; + int1:= (int1+1) div 2; //samples per quadrant + rea1:= pi/(2*int1); + npoints:= 8*int1+2; //+ endpoint + allocbuffer(buffer,npoints*sizeof(pointty)); + si:= sin(rea1); + co:= cos(rea1); + adjustellipsecenter(drawinfo,center); + int2:= int1*2; + q0:= buffer.buffer; + q1:= q0+int2; + q2:= q1+int2; + q3:= q2+int2; + cx1:= cx * (65536 div 2); + cx2:= cx1*cx1; + cy1:= cy * (65536 div 2); + cy2:= cy1*cy1; + w:= linewidth16 div 2; + cxw:= cx1*w; + cyw:= cy1*w; + sx:= 1; + sy:= 0; + for int1:= int1-1 downto 0 do begin + x1:= round(cx1*sx); + y1:= round(cy1*sy); + rea1:= sqrt(cx2*sy*sy+cy2*sx*sx); + if rea1 = 0 then begin + x2:= round(w); + y2:= 0; + end + else begin + x2:= round(cyw*sx/rea1); + y2:= round(cxw*sy/rea1); + end; + q0^.x:= center.x + x1 + x2; + q0^.y:= center.y - y1 - y2; + inc(q0); + q0^.x:= center.x + x1 - x2; + q0^.y:= center.y - y1 + y2; + inc(q0); + q2^.x:= center.x - x1 - x2; + q2^.y:= center.y + y1 + y2; + inc(q2); + q2^.x:= center.x - x1 + x2; + q2^.y:= center.y + y1 - y2; + inc(q2); + if not circle then begin + x1:= round(cy1*sx); + y1:= round(cx1*sy); + rea1:= sqrt(cy2*sy*sy+cx2*sx*sx); + if rea1 <> 0 then begin + x2:= round(cxw*sx/rea1); + y2:= round(cyw*sy/rea1); + end; + end; + q1^.x:= center.x - y1 - y2; + q1^.y:= center.y - x1 - x2; + inc(q1); + q1^.x:= center.x - y1 + y2; + q1^.y:= center.y - x1 + x2; + inc(q1); + q3^.x:= center.x + y1 + y2; + q3^.y:= center.y + x1 + x2; + inc(q3); + q3^.x:= center.x + y1 - y2; + q3^.y:= center.y + x1 - x2; + inc(q3); + rea1:= sx; + sx:= co*sx-si*sy; + sy:= co*sy+si*rea1; + end; + q3^:= ppointty(buffer.buffer)^; //endpoint + inc(q3); + q3^:= (ppointty(buffer.buffer)+1)^; + apoints:= buffer.buffer; + apointcount:= npoints; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/graphics/msefcfontselect.pas b/mseide-msegui/lib/common/graphics/msefcfontselect.pas new file mode 100644 index 0000000..ed39775 --- /dev/null +++ b/mseide-msegui/lib/common/graphics/msefcfontselect.pas @@ -0,0 +1,309 @@ +{ MSEgui Copyright (c) 1999-2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msefcfontselect; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msegraphics,msetypes,msefontconfig; + +const + highresfontshift = 6; //64 + highresfontfakt = 1 shl highresfontshift; + highresfontmask = highresfontfakt - 1; + +type + fontnamety = ( + fn_foundry,fn_family_name,fn_weight_name,fn_slant,fn_setwidth_name, + fn_addstyle_name,fn_pixel_size,fn_point_size,fn_resolution_x, + fn_resolution_y,fn_spacing,fn_average_width,fn_charset_registry, + fn_encoding); + fontinfoty = array[fontnamety] of string; + +procedure setupfontinfo(const fontdata: fontdataty; var fontinfo: fontinfoty); +procedure setfontinfoname(const aname: string; var ainfo: fontinfoty); +function buildxftpat(const fontdata: fontdataty; + const fontinfo: fontinfoty; const highres: boolean): pfcpattern; +function getfcfontfile(const ainfo: getfontinfoty; out filename: string; + out index: integer; out height: integer): boolean; + +var + defaultfontinfo: fontinfoty; + simpledefaultfont: boolean; + hasdefaultfontarg: boolean;//true if -fn + noxft: boolean; + +implementation +uses + sysutils,msestrings,msegraphutils,msectypes; + +procedure setfontinfoname(const aname: string; var ainfo: fontinfoty); +var + ar1: stringarty; +begin + ar1:= splitstring(aname,':'); + if (high(ar1) = 1) and (ar1[0] <> '') and (ar1[1] <> '') then begin + ainfo[fn_foundry]:= ar1[0]; + ainfo[fn_family_name]:= ar1[1]; + end + else begin + ainfo[fn_family_name]:= aname; + end; +end; + +procedure setupfontinfo(const fontdata: fontdataty; var fontinfo: fontinfoty); +var + ar1: stringarty; + height1,width1: integer; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + ar1:= nil; //compiler warning; + fontinfo:= defaultfontinfo; + with pfontdataty(@fontdata)^ do begin + height1:= (h.d.height + fontsizeroundvalue) shr fontsizeshift; + width1:= (h.d.width + fontsizeroundvalue) shr fontsizeshift; + if height1 <> 0 then begin + fontinfo[fn_pixel_size]:= inttostr(height1); + end; + if width1 <> 0 then begin + fontinfo[fn_average_width]:= inttostr(width1); + end; + if h.charset <> '' then begin + ar1:= splitstring(h.charset,'-'); + fontinfo[fn_charset_registry]:= ar1[0]; + if high(ar1) > 0 then begin + fontinfo[fn_encoding]:= ar1[1]; + end; + end; + if h.name <> '' then begin + setfontinfoname(h.name,fontinfo); + end + else begin + end; + if fs_bold in h.d.style then begin + fontinfo[fn_weight_name]:= 'bold'; + end; + if fs_italic in h.d.style then begin + fontinfo[fn_slant]:= 'i'; + end; + end; +end; + +function buildxftpat(const fontdata: fontdataty; + const fontinfo: fontinfoty; const highres: boolean): pfcpattern; +var + int1: integer; +// str1: ansistring; + mat1: tfcmatrix; + rea1: real; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with fontdata do begin +// if fontinfo[fn_charset_registry] <> '*' then begin +// str1:= fontinfo[fn_charset_registry]; +// if fontinfo[fn_encoding] <> '*' then begin +// str1:= str1 +'-'+fontinfo[fn_encoding]; +// end; +// result:= fcnameparse(pansichar(str1)); +// end +// else begin + result:= fcpatterncreate(); +// end; + if fontinfo[fn_foundry] <> '*' then begin + fcpatternaddstring(result,fc_foundry,pansichar(fontinfo[fn_foundry])); + end; + if (h.d.familyoptions = []) then begin + if (h.d.pitchoptions = []) and (fontinfo[fn_family_name] <> '*') then begin + fcpatternaddstring(result,fc_family,pansichar(fontinfo[fn_family_name])); + end; + end + else begin + if foo_helvetica in h.d.familyoptions then begin + fcpatternaddstring(result,fc_family,'sans'); + end + else begin + if foo_roman in h.d.familyoptions then begin + fcpatternaddstring(result,fc_family,'serif'); + end + else begin + if foo_decorative in h.d.familyoptions then begin + end + else begin + if foo_script in h.d.familyoptions then begin + end; + end; + end; + end; + end; + if fs_bold in h.d.style then begin + fcpatternaddinteger(result,fc_weight,fc_weight_bold); + end; + if fs_italic in h.d.style then begin + fcpatternaddinteger(result,fc_slant,fc_slant_italic); + end; + if fontinfo[fn_pixel_size] <> '*' then begin + if trystrtofloat(fontinfo[fn_pixel_size],rea1) then begin + if highres then begin + rea1:= rea1 * highresfontfakt; + end; +// fcpatternadddouble(result,fc_pixel_size,rea1); + //double does not work on raspberry pi + fcpatternaddinteger(result,fc_pixel_size,round(rea1)); + end; + end; + if fontinfo[fn_average_width] <> '*' then begin + if trystrtoint(fontinfo[fn_average_width],int1) then begin + int1:= (int1 + 5) div 10; + fcpatternaddinteger(result,fc_char_width,int1); + end; + end; + if foo_fixed in h.d.pitchoptions then begin + fcpatternaddinteger(result,fc_spacing,fc_mono); + end; + if foo_proportional in h.d.pitchoptions then begin + fcpatternaddinteger(result,fc_spacing,fc_proportional); + end; + if [foo_antialiased,foo_antialiased2]*h.d.antialiasedoptions <> [] then begin + fcpatternaddbool(result,fc_antialias,true); + end; + if foo_nonantialiased in h.d.antialiasedoptions then begin + fcpatternaddbool(result,fc_antialias,false); + end; + if (h.d.xscale <> 1.0) or (h.d.rotation <> 0) then begin + fcmatrixinit(mat1); + mat1.xx:= h.d.xscale; + if h.d.rotation <> 0 then begin + fcmatrixrotate(@mat1,cos(h.d.rotation),sin(h.d.rotation)); + end; + fcpatternaddmatrix(result,fc_matrix,@mat1); + end; + { + if foo_xcore in xcoreoptions then begin + str1:= str1 + ':core=1'; + end; + if foo_noxcore in xcoreoptions then begin + str1:= str1 + ':core=0'; + end; + } + end; +end; + +function getfcfontfile(const ainfo: getfontinfoty; out filename: string; + out index: integer; out height: integer): boolean; +var + fontinfo: fontinfoty; + po1,po2: pfcpattern; + res1: tfcresult; + po3: pchar; + int1: integer; + do1: cdouble; +begin + result:= false; + filename:= ''; + index:= 0; + setupfontinfo(ainfo.fontdata^,fontinfo); + po1:= buildxftpat(ainfo.fontdata^,fontinfo,false); + fcconfigsubstitute(nil,po1,fcmatchpattern); + fcdefaultsubstitute(po1); + po2:= fcfontmatch(nil,po1,@res1); + if po2 <> nil then begin + if fcpatterngetstring(po2,'file',0,@po3) = fcresultmatch then begin + filename:= po3; + end; + if fcpatterngetinteger(po2,'index',0,@int1) = fcresultmatch then begin + index:= int1; + end; + if fcpatterngetdouble(po2,'pixelsize',0,@do1) = fcresultmatch then begin + height:= round(do1); + end + else begin + if fontinfo[fn_pixel_size] <> '' then begin + height:= strtoint(fontinfo[fn_pixel_size]); + end + else begin + height:= 14; + end; + end; + result:= true; + fcpatterndestroy(po2); + end; + fcpatterndestroy(po1); +end; + +procedure x11initdefaultfont; +var + int1,int2: integer; + str1: string; + av: pcharpoaty; + ac: pinteger; + ar1: stringarty; + en1: fontnamety; +begin + ar1:= nil; //compiler warning + simpledefaultfont:= false; + for en1:= low(fontnamety) to high(fontnamety) do begin + defaultfontinfo[en1]:= '*'; + end; + defaultfontinfo[fn_family_name]:= 'helvetica'; + defaultfontinfo[fn_weight_name]:= 'medium'; + defaultfontinfo[fn_slant]:= 'r'; + defaultfontinfo[fn_pixel_size]:= '12'; + defaultfontinfo[fn_charset_registry]:= 'iso10646'; + defaultfontinfo[fn_encoding]:= '1'; + ac:= {$ifdef FPC}@argc{$else}@argcount{$endif}; + av:= pcharpoaty({$ifdef FPC}argv{$else}argvalues{$endif}); + for int1:= ac^ - 1 downto 1 do begin + if (av^[int1] = '-fn') or (av^[int1] = '-font') then begin + hasdefaultfontarg:= true; + if int1 < ac^ - 1 then begin + str1:= av^[int1+1]; + if (length(str1) > 0) then begin + if str1[1] = '-' then begin + ar1:= splitstring(str1,'-'); + for int2:= 1 to high(ar1) do begin + str1:= trim(ar1[int2]); + if str1 <> '*' then begin + defaultfontinfo[fontnamety(int2-1)]:= str1; + end; + if int2 = ord(high(fontnamety)) then begin + break; + end; + end; + noxft:= + (high(ar1) > ord(high(fontnamety))+1) and + (ar1[ord(high(fontnamety))+2] ='noxft'); + end + else begin + setfontinfoname(str1,defaultfontinfo); +// defaultfontinfo[fn_family_name]:= str1; + simpledefaultfont:= true; + end; + dec(ac^,2); //remove font arguments + if int1 < ac^ then begin + move(av^[int1+2],av^[int1],(ac^-int1)*sizeof(av^[0])); + end; + av^[ac^]:= nil; + end; + end; + break; + end; + end; +end; + +initialization + x11initdefaultfont; +{$ifdef mswindows} +// defaultfontinfo[fn_family_name]:= 'Tahoma'; + defaultfontinfo[fn_family_name]:= 'Arial'; +{$endif} +end. diff --git a/mseide-msegui/lib/common/graphics/msefont.pas b/mseide-msegui/lib/common/graphics/msefont.pas new file mode 100644 index 0000000..220f40f --- /dev/null +++ b/mseide-msegui/lib/common/graphics/msefont.pas @@ -0,0 +1,814 @@ +{ MSEgui Copyright (c) 1999-2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msefont; +{$ifdef FPC}{$mode objfpc}{$h+}{$GOTO ON}{$interfaces corba}{$endif} + +interface +uses + mseguiglob,msegraphics,mseclasses; + +function getfontnum(const fontinfo: fontinfoty; var drawinfo: drawinfoty; + getfont: getfontfuncty; var atemplate: tfontcomp): fontnumty; +procedure addreffont(font: fontnumty); +procedure releasefont(font: fontnumty); + +procedure checkhighresfont(const afont: pfontdataty; var drawinfo: drawinfoty); +procedure getchar16widths(var drawinfo: drawinfoty); +procedure getfontmetrics(var drawinfo: drawinfoty); + +function getfontdata(font: fontnumty): pfontdataty; +function findfontdata(const afont: fontty): pfontdataty; +function registerfontalias(const alias,name: string; + mode: fontaliasmodety = fam_nooverwrite; + const height: integer = 0; const width: integer = 0; + const options: fontoptionsty = []; + const xscale: real = 1.0; + ancestor: string = defaultfontalias; + const template: tfontcomp = nil): boolean; + //true if registering ok +function unregisterfontalias(const alias: string): boolean; + //false if alias does not exist +procedure clearfontalias; //removes all alias which are not fam_fix +function fontaliascount: integer; +procedure setfontaliascount(const acount: integer); +function realfontname(const aliasname: string): string; +function getfontforglyph(const abasefont: fontty; + const glyph: unicharty): fontnumty; +function fontoptioncharstooptions(const astring: string): fontoptionsty; + +procedure init; +procedure deinit; + +const + defaultmaxfontcachecount = 64; +var + maxfontcachecount: integer = defaultmaxfontcachecount; + +implementation +uses + mselist,sysutils,mseguiintf,msegraphutils,msetypes,msesys, + msestrings,mseformatstr,msehash,mseglob; + +type + fontnumdataty = record + num: integer; + end; + fontnumhashdataty = record + header: hashheaderty; + data: fontnumdataty; + end; + pfontnumhashdataty = ^fontnumhashdataty; + + tfonthashlist = class(thashdatalist) + protected + function hashkey(const akey): hashvaluety; override; + function checkkey(const akey; const aitem: phashdataty): boolean override; + function getrecordsize(): int32 override; + public +// constructor create; + function find(const afont: fonthashdataty): integer; + procedure add(const afont: fontnumty); + procedure delete(const afont: fontnumty); + end; + + fontdatarecty = record + refcount: integer; + data: pfontdataty; + end; + fontdatarecpoty = ^fontdatarecty; + + fontaliasty = record + alias: string; + ancestor: string; + name: string; + mode: fontaliasmodety; + height: integer; + width: integer; + options: fontoptionsty; + xscale: real; + template: tfontcomp; + end; + pfontaliasty = ^fontaliasty; + fontaliasaty = array[0..0] of fontaliasty; + pfontaliasaty = ^fontaliasaty; + + tfontaliaslist = class(tlinkedrecordlist) + protected + procedure finalizerecord(var item); override; + procedure copyrecord(var item); override; + procedure updatefontdata(var info: fontdataty; var atemplate: tfontcomp); + function find(const alias: string): integer; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + public + constructor create; + function registeralias(const alias,name: string; + mode: fontaliasmodety = fam_nooverwrite; + const height: integer = 0; const width: integer = 0; + const options: fontoptionsty = []; + const xscale: real = 1.0; + const ancestor: string = ''; + const template: tfontcomp = nil): boolean; + //true if registering ok + end; + +var + fonts: array of fontdatarecty; + lastreusedfont: integer; + ffontaliaslist: tfontaliaslist; + ffonthashlist: tfonthashlist; + +function fontaliaslist: tfontaliaslist; +begin + if ffontaliaslist = nil then begin + ffontaliaslist:= tfontaliaslist.create; + end; + result:= ffontaliaslist; +end; + +function registerfontalias(const alias,name: string; + mode: fontaliasmodety = fam_nooverwrite; + const height: integer = 0; const width: integer = 0; + const options: fontoptionsty = []; + const xscale: real = 1.0; + ancestor: string = defaultfontalias; + const template: tfontcomp = nil): boolean; + //true if registering ok +begin + if (alias = defaultfontalias) and (ancestor = defaultfontalias) then begin + ancestor:= ''; + end; + result:= fontaliaslist.registeralias(alias,name,mode,height,width,options, + xscale,ancestor,template); +end; + +function realfontname(const aliasname: string): string; +var + int1: integer; + str1: string; +begin + result:= ''; + if ffontaliaslist <> nil then begin + str1:= aliasname; + while str1 <> '' do begin + int1:= ffontaliaslist.find(str1); + if int1 >= 0 then begin + with pfontaliasaty(ffontaliaslist.datapo)^[int1] do begin + if (result = '') and (name <> '') then begin + result:= name; + break; + end; + end; + end + else begin + break; + end; + end; + end; + if result = '' then begin + result:= aliasname; + end; +end; + +function unregisterfontalias(const alias: string): boolean; + //false if alias does not exist +var + int1: integer; +begin + result:= false; + if ffontaliaslist <> nil then begin + int1:= ffontaliaslist.find(alias); + if int1 >= 0 then begin + ffontaliaslist.delete(int1); + if ffontaliaslist.count = 0 then begin + freeandnil(ffontaliaslist); + end; + end; + end; +end; + +procedure clearfontalias; //removes all alias which are not fam_fix +var + int1: integer; +begin + if ffontaliaslist <> nil then begin + for int1:= ffontaliaslist.count - 1 downto 0 do begin + if pfontaliasty(ffontaliaslist.getitempo(int1))^.mode <> fam_fix then begin + ffontaliaslist.delete(int1); + end; + end; + end; +end; + +function fontaliascount: integer; +begin + result:= ffontaliaslist.count; +end; + +procedure setfontaliascount(const acount: integer); +begin + ffontaliaslist.count:= acount; +end; + +function getfontdata(font: fontnumty): pfontdataty; +begin + dec(font); + if font >= longword(length(fonts)) then begin + result:= nil; + end + else begin + result:= fonts[font].data; + end; +end; + +function findfontdata(const afont: fontty): pfontdataty; +var + int1: integer; +begin + result:= nil; + for int1:= 0 to high(fonts) do begin + with fonts[int1] do begin + if (refcount > 0) and (data^.font = afont) then begin + result:= fonts[int1].data; + break; + end; + end; + end; +end; + +procedure freefont(index: integer); +var + drawinfo: drawinfoty; +begin + ffonthashlist.delete(index); + with fonts[index] do begin + gdi_lock; + drawinfo.getfont.fontdata:= data; + freefontdata(drawinfo); + finalize(data^); + gdi_unlock; + refcount:= 0; + end; +end; + +type + fontmatrixmodety = (fmm_fix,fmm_linear,fmm_matrix); + x11fontdatadty = record + infopo: pointer; + matrixmode: fontmatrixmodety; + defaultwidth: integer; + xftascent,xftdescent: integer; + rowlength: word; + xftdirection: graphicdirectionty; + end; + px11fontdatadty = ^x11fontdatadty; + x11fontdataty = record + case integer of + 0: (d: x11fontdatadty;); + 1: (_bufferspace: fontdatapty;); + end; + +function registerfont(var fontdata: fontdataty): fontnumty; + + procedure reusefont(startindex: integer); + var + int1: integer; + begin + for int1:= startindex to high(fonts) do begin //reuse oldest + if fonts[int1].refcount <= 0 then begin + freefont(int1); + lastreusedfont:= int1; + result:= int1+1; + break; + end; + end; + end; +var + int1: integer; +begin //registerfont + result:= 0; + if length(fonts) > maxfontcachecount then begin + reusefont(lastreusedfont+1); + if result = 0 then begin + reusefont(0); + end; + end; + if result = 0 then begin + result:= length(fonts)+1; + setlength(fonts,result); + with fonts[high(fonts)] do begin + getmem(data,sizeof(fontdataty)); + fillchar(data^,sizeof(fontdataty),0); + end; + end; + int1:= result-1; + fonts[int1].data^:= fontdata; +// move(fontdata,fonts[int1].data^,sizeof(fontdata)); + fonts[int1].refcount:= 1; + ffonthashlist.add(int1); +end; + +procedure releasefont(font: fontnumty); +begin + dec(font); + if integer(font) < 0 then begin + exit; + end; + if integer(font) <= high(fonts) then begin + with fonts[font] do begin + if refcount > 0 then begin + dec(refcount); + end; + end; + end; +end; + +procedure addreffont(font: fontnumty); +begin + if font > 0 then begin + inc(fonts[font-1].refcount); + end; +end; + +procedure checkhighresfont(const afont: pfontdataty; var drawinfo: drawinfoty); +var + fontinfobefore: getfontinfoty; +begin + with afont^ do begin + if fonthighres = 0 then begin + fontinfobefore:= drawinfo.getfont; + with drawinfo.getfont do begin + fontdata:= afont; + basefont:= 0; + end; + gdi_lock; +// gdi_getfonthighres(drawinfo); + h.d.gdifuncs^[gdf_getfonthighres](drawinfo); + gdi_unlock; + drawinfo.getfont:= fontinfobefore; + end; + end; +end; + +procedure getchar16widths(var drawinfo: drawinfoty); +begin + with drawinfo.getchar16widths.fontdata^ do begin + h.d.gdifuncs^[gdf_getchar16widths](drawinfo); + end; +end; + +procedure getfontmetrics(var drawinfo: drawinfoty); +begin + with drawinfo.getfontmetrics.fontdata^ do begin + h.d.gdifuncs^[gdf_getfontmetrics](drawinfo); + end; +end; + +function comparefont(const s: fontinfoty; const d: fontdataty): boolean; +begin + result:= + (d.h.d.glyph = s.glyph) and //unicode substitutes + (d.h.d.gdifuncs = s.gdifuncs) and + (d.h.d.height = s.baseinfo.height) and + (d.h.d.width = s.baseinfo.width) and + (d.h.d.pitchoptions = s.baseinfo.options * fontpitchmask) and + (d.h.d.familyoptions = s.baseinfo.options * fontfamilymask) and + (d.h.d.antialiasedoptions = s.baseinfo.options * fontantialiasedmask) and + ({$ifdef FPC}longword{$else}byte{$endif}(d.h.d.style) xor + {$ifdef FPC}longword{$else}byte{$endif}(s.baseinfo.style) and + fontstylehandlemask = 0) and + (d.h.name = s.baseinfo.name) and + (d.h.charset = s.baseinfo.charset) and + (d.h.d.rotation = s.rotation) and + (d.h.d.xscale = s.baseinfo.xscale); + +end; + +{ tfonthashlist } +{ +constructor tfonthashlist.create; +begin + inherited create(sizeof(fontnumdataty)); +end; +} +function tfonthashlist.hashkey(const akey): hashvaluety; +begin + with fontdataty(akey) do begin + result:= stringhash(h.name) xor stringhash(h.charset) xor + datahash(h.d,sizeof(h.d)); + end; +end; + +function tfonthashlist.checkkey(const akey; const aitem: phashdataty): boolean; +var + po1: pfontdataty; +begin + po1:= fonts[pfontnumhashdataty(aitem)^.data.num].data; + with fontdataty(akey) do begin + result:= comparemem(@po1^.h.d,@h.d,sizeof(h.d)) and + (po1^.h.name = h.name) and (po1^.h.charset = h.charset); + end; +end; + +function tfonthashlist.getrecordsize(): int32; +begin + result:= sizeof(fontnumhashdataty); +end; + +function tfonthashlist.find(const afont: fonthashdataty): integer; +var + po1: pfontnumhashdataty; +begin + result:= -1; + po1:= pfontnumhashdataty(internalfind(afont)); + if po1 <> nil then begin + result:= po1^.data.num; + end; +end; + +procedure tfonthashlist.add(const afont: fontnumty); +var + po1: pfontnumhashdataty; +begin + po1:= pfontnumhashdataty(internaladd(fonts[afont].data^.h)); + po1^.data.num:= afont; +end; + +procedure tfonthashlist.delete(const afont: fontnumty); +begin + internaldeleteitem(internalfind(fonts[afont].data^.h)); +end; + +procedure getfontvalues(const s: fontinfoty; var d: fontdataty); +begin + fillchar(d.h.d,sizeof(d.h.d),0); + d.h.d.gdifuncs:= s.gdifuncs; + d.h.d.height:= s.baseinfo.height; + d.h.d.width:= s.baseinfo.width; + d.h.d.familyoptions:= s.baseinfo.options * fontfamilymask; + d.h.d.pitchoptions:= s.baseinfo.options * fontpitchmask; + d.h.d.antialiasedoptions:= s.baseinfo.options * fontantialiasedmask; + d.h.d.style:= fontstylesty({$ifdef FPC}longword{$else}byte{$endif} + (s.baseinfo.style) and fontstylehandlemask); + d.h.d.glyph:= s.glyph; + d.h.d.rotation:= s.rotation; + d.h.d.xscale:= s.baseinfo.xscale; + d.h.name:= s.baseinfo.name; + d.h.charset:= s.baseinfo.charset; +end; + +function getfontnum(const fontinfo: fontinfoty; var drawinfo: drawinfoty; + getfont: getfontfuncty; var atemplate: tfontcomp): fontnumty; +var + int1: integer; + data1: fontdataty; +begin + gdi_lock; + with fontinfo do begin + getfontvalues(fontinfo,data1); + int1:= ffonthashlist.find(data1.h); + if int1 >= 0 then begin + with fonts[int1] do begin + inc(refcount); + result:= int1 + 1; + end; + end + else begin //todo: do not load same substitute multiple times + finalize(data1); + fillchar(data1,sizeof(data1),0); + getfontvalues(fontinfo,data1); + if ffontaliaslist <> nil then begin + ffontaliaslist.updatefontdata(data1,atemplate); + end; + drawinfo.getfont.fontdata:= @data1; + drawinfo.getfont.basefont:= 0; + if getfont(drawinfo) then begin + data1.realfont:= data1.h; + if data1.realfont.d.height = 0 then begin + if data1.realheight = 0 then begin + data1.realheight:= data1.linespacing; + end; + data1.realfont.d.height:= data1.realheight shl fontsizeshift; + end; + getfontvalues(fontinfo,data1); + data1.basefont:= drawinfo.getfont.basefont; + result:= registerfont(data1); + end + else begin + result:= 0; + end; + end; + end; + gdi_unlock; +end; + +function getfontforglyph(const abasefont: fontty; const glyph: unicharty): fontnumty; +var + info: drawinfoty; + int1: integer; +begin + result:= 0; + info.fonthasglyph.unichar:= glyph; + gdi_lock; + for int1:= 0 to high(fonts) do begin + with fonts[int1],data^ do begin + if (refcount >= 0) and (basefont = abasefont) then begin + info.fonthasglyph.font:= font; + getdefaultgdifuncs^[gdf_fonthasglyph](info); + if info.fonthasglyph.hasglyph then begin + result:= int1 + 1; + end; + end; + end; + end; + gdi_unlock; +end; + +function fontoptioncharstooptions(const astring: string): fontoptionsty; +var + int1: integer; + option1: fontoptionty; +begin + result:= []; + for int1:= 1 to length(astring) do begin + for option1:= low(fontoptionty) to high(fontoptionty) do begin + if astring[int1] = fontaliasoptionchars[option1] then begin + include(result,option1); + end; + end; + end; +end; + +procedure initfontalias; +//format aliasdef: +//--FONTALIAS=,[,[,[,[,] +// [,]]] +const + paramname = '--FONTALIAS='; +var + ar1,ar2: msestringarty; + int1,{int2,}int3,int4{,int5}: integer; + ar3: array[0..1] of integer; + options1: fontoptionsty; + xscale1: real; + str1: string; + bo1: boolean; +begin + ar1:= getcommandlinearguments; + int3:= 1; + xscale1:= 1.0; + for int1:= 1 to high(ar1) do begin + if msestrlicomp(pmsechar(ar1[int1]),pmsechar(paramname), + length(paramname)) = 0 then begin + ar2:= nil; + splitstringquoted(copy(ar1[int1],length(paramname)+1,bigint),ar2,'"',','); + if (high(ar2) >= 1) and (high(ar2) <= 6) then begin + try + for int4:= 0 to high(ar3) do begin + if int4 + 2 > high(ar2) then begin + ar3[int4]:= 0; + end + else begin + if trim(ar2[int4+2]) <> '' then begin + ar3[int4]:= strtoint(ar2[int4+2]); + end + else begin + ar3[int4]:= 0; + end; + end; + end; + options1:= []; + if high(ar2) >= 4 then begin + options1:= fontoptioncharstooptions(ansistring(ar2[4])); + end; + if (high(ar2) >= 5) and (trim(ar2[5]) <> '') then begin + xscale1:= strtoreal(ar2[5]); + end; + bo1:= lowercase(ar2[0]) = defaultfontalias; + if bo1 and (ar2[1] = '') then begin + ar2[1]:= msestring(gui_getdefaultfontnames[stf_default]); + end; + if high(ar2) >= 6 then begin + str1:= ansistring(trim(ar2[6])); + end + else begin + if bo1 then begin + str1:= ''; + end + else begin + str1:= defaultfontalias; + end; + end; + + fontaliaslist.registeralias(ansistring(ar2[0]),ansistring(ar2[1]), + fam_overwrite,ar3[0],ar3[1],options1,xscale1,str1); + deletecommandlineargument(int3); + dec(int3); + except + end; + end; + end; + inc(int3); + end; +end; + +procedure init; +begin + ffonthashlist:= tfonthashlist.create; + initfontalias; +end; + +procedure deinit; +var + int1: integer; +begin + for int1:= 0 to high(fonts) do begin + with fonts[int1] do begin + refcount:= 1; + freefont(int1); + freemem(data); + end; + end; + freeandnil(ffontaliaslist); + freeandnil(ffonthashlist); +end; + +{ tfontaliaslist } + +constructor tfontaliaslist.create; +begin + inherited create(sizeof(fontaliasty),[rels_needsfinalize,rels_needscopy]); +end; + +procedure tfontaliaslist.finalizerecord(var item); +begin + finalize(fontaliasty(item)); +end; + +procedure tfontaliaslist.copyrecord(var item); +begin + with fontaliasty(item) do begin + stringaddref(alias); + stringaddref(name); + end; +end; + +function tfontaliaslist.find(const alias: string): integer; +var + str1: string; + po1: pfontaliasaty; + int1: integer; +begin + result:= -1; + str1:= struppercase(alias); + po1:= datapo; + for int1:= 0 to count-1 do begin + if po1^[int1].alias = str1 then begin + result:= int1; + break; + end; + end; +end; + +procedure tfontaliaslist.updatefontdata(var info: fontdataty; + var atemplate: tfontcomp); +var + int1: integer; + str1: string; + po1: pchar; +begin + str1:= info.h.name; + po1:= nil; + while str1 <> '' do begin + int1:= find(str1); + if int1 < 0 then begin + break; + end; + with pfontaliasty(getitempo(int1))^ do begin + str1:= ancestor; + if (name <> '') and (po1 = nil) then begin + po1:= pchar(name); + end; + if (height <> 0) and (info.h.d.height = 0) then begin + info.h.d.height:= height; + end; + if (width <> 0) and (info.h.d.width = 0) then begin + info.h.d.width:= width; + end; + if (xscale <> 1) and (info.h.d.xscale = 1) then begin + info.h.d.xscale:= xscale; + end; + if (options * fontpitchmask <> []) and + (info.h.d.pitchoptions * fontpitchmask = []) then begin + info.h.d.pitchoptions:= options * fontpitchmask; + end; + if (options * fontfamilymask <> []) and + (info.h.d.pitchoptions * fontfamilymask = []) then begin + info.h.d.familyoptions:= options * fontfamilymask; + end; + if (options * fontantialiasedmask <> []) and + (info.h.d.pitchoptions * fontantialiasedmask = []) then begin + info.h.d.antialiasedoptions:= options * fontantialiasedmask; + end; + if (template <> nil) and (atemplate = nil) then begin + atemplate:= template; + end; + end; + end; + if po1 <> nil then begin + info.h.name:= po1; + end; +end; + +function tfontaliaslist.registeralias(const alias,name: string; + mode: fontaliasmodety = fam_nooverwrite; + const height: integer = 0; const width: integer = 0; + const options: fontoptionsty = []; + const xscale: real = 1.0; + const ancestor: string = ''; + const template: tfontcomp = nil): boolean; + //true if registering ok +var + po1: pfontaliasty; + + procedure doupdate; + begin + po1^.name:= name; + po1^.mode:= mode; + po1^.height:= height shl fontsizeshift; + po1^.width:= width shl fontsizeshift; + po1^.options:= options; + po1^.xscale:= xscale; + po1^.ancestor:= ancestor; + if template <> po1^.template then begin + getobjectlinker.setlink(iobjectlink(self),template, + tmsecomponent(po1^.template)); + end; + end; + +var + int1: integer; + str1,str2: string; +begin + result:= false; + str1:= uppercase(alias); + str2:= uppercase(ancestor); + while str2 <> '' do begin + if str1 = str2 then begin + raise exception.create('Recursive fontalias "' + +alias+'" name "'+name+'" caller "'+str1+'".'); + end; + int1:= find(str2); + if int1 >= 0 then begin + str2:= uppercase(pfontaliasty(getitempo(int1))^.ancestor); + end + else begin + break; + end; + end; + int1:= find(alias); + if int1 >= 0 then begin + po1:= pfontaliasty(getitempo(int1)); + if not (mode in [fam_nooverwrite,fam_fixnooverwrite]) then begin + if po1^.mode <> fam_fix then begin + doupdate; + end; + end; + end + else begin + count:= count + 1; + po1:= getitempo(count-1); + po1^.alias:= struppercase(alias); + doupdate; + end; + if mode = fam_fixnooverwrite then begin + po1^.mode:= fam_fix; + end; +end; + +procedure tfontaliaslist.objectevent(const sender: tobject; + const event: objecteventty); +var + po1,pe: pfontaliasty; +begin + inherited; + if event = oe_destroyed then begin + po1:= datapo; + pe:= po1 + count; + while po1 < pe do begin + if po1^.template = sender then begin + po1^.template:= nil; + end; + inc(po1); + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/graphics/msefontcache.pas b/mseide-msegui/lib/common/graphics/msefontcache.pas new file mode 100644 index 0000000..aaaa4c2 --- /dev/null +++ b/mseide-msegui/lib/common/graphics/msefontcache.pas @@ -0,0 +1,210 @@ +{ MSEgui Copyright (c) 2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +// +//under construction +// +unit msefontcache; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msehash,msegraphics,mseguiglob; + +type + fontcachedataty = record +// h: fontcachehdataty; + keyname: string; + keyheight: integer; + refcount: integer; + + height: integer; + ascent: integer; + descent: integer; + linespacing: integer; + caretshift: integer; + + font: ptruint; +// handle: pcachefontty; + end; + pfontcachedataty = ^fontcachedataty; + fontcachehashdataty = record + header: hashheaderty; + data: fontcachedataty; + end; + pfontcachehashdataty = ^fontcachehashdataty; + + pfontcache = ^tfontcache; + + tfontcache = class(thashdatalist) + private + finstancepo: pfontcache; + protected + function hashkey(const akey): hashvaluety; override; + function checkkey(const akey; + const aitem: phashdataty): boolean; override; + procedure finalizeitem(const aitem: phashdataty); override; + function find(const afont: fontdataty): pfontcachehashdataty; + + procedure internalfreefont(const afont: ptruint); virtual; + function internalgetfont(const ainfo: getfontinfoty; + out aheight: integer): boolean; virtual; abstract; + procedure updatefontinfo(const adataoffset: hashoffsetty; + var adata: fontcachedataty); virtual; abstract; + function getdataoffsfont(const afont: fontty): hashoffsetty; virtual; abstract; + function getrecordsize(): int32 override; + public + constructor create(var ainstance: tfontcache); + procedure getfont(var drawinfo: drawinfoty); + procedure freefontdata(var drawinfo: drawinfoty); + procedure gettext16width(var drawinfo: drawinfoty); virtual; abstract; + procedure getchar16widths(var drawinfo: drawinfoty); virtual; abstract; + procedure getfontmetrics(var drawinfo: drawinfoty); virtual; abstract; + procedure drawstring16(var drawinfo: drawinfoty; + const afont: fontty); virtual; abstract; + end; + +implementation +uses + sysutils,msedynload; //release dynload needed in finalization + +{ tfontcache } + +constructor tfontcache.create(var ainstance: tfontcache); +begin + finstancepo:= @ainstance; + ainstance:= self; + inherited create(); + fstate:= fstate + [hls_needsnull,hls_needsfinalize]; +end; + +procedure tfontcache.finalizeitem(const aitem: phashdataty); +begin + finalize(pfontcachehashdataty(aitem)^.data); +end; + +function tfontcache.hashkey(const akey): hashvaluety; +begin + with fontdataty(akey) do begin + result:= stringhash(h.name) xor h.d.height; + end; +end; + +function tfontcache.checkkey(const akey; const aitem: phashdataty): boolean; +begin + with fontdataty(akey),pfontcachehashdataty(aitem)^.data do begin + result:= (h.name = keyname) and (h.d.height = keyheight); + end; +end; + +function tfontcache.find(const afont: fontdataty): pfontcachehashdataty; +begin + result:= pfontcachehashdataty(internalfind(afont)); +end; + +procedure tfontcache.getfont(var drawinfo: drawinfoty); +var + po1: pfontcachehashdataty; + h1: integer; +begin + with drawinfo.getfont do begin + ok:= true; + po1:= find(fontdata^); + with fontdata^ do begin + if po1 = nil then begin + if not internalgetfont(drawinfo.getfont,h1) then begin + font:= 0; + ok:= false; + exit; + end; + po1:= pfontcachehashdataty(internaladd(fontdata^)); + po1^.data.keyname:= fontdata^.h.name; + po1^.data.keyheight:= fontdata^.h.d.height; + po1^.data.font:= font; + po1^.data.height:= h1; + updatefontinfo(getdataoffs(@po1^.data),po1^.data); + end; + inc(po1^.data.refcount); + font:= po1^.data.font; + ascent:= po1^.data.ascent; + descent:= po1^.data.descent; + linespacing:= po1^.data.linespacing; + realheight:= po1^.data.height; + caretshift:= po1^.data.caretshift; + end; + end; +end; + +(* +procedure tfontcache.getfont(var drawinfo: drawinfoty); +var + po1: pfontcachedataty; + po2: pftglfont; +begin + with drawinfo.getfont do begin + ok:= true; + po1:= find(fontdata^); + with fontdata^ do begin + getmem(pointer(font),ffontdatasize); + with pftglfontty(font)^ do begin + if po1 = nil then begin + po2:= ftglcreatepixmapfont('/usr/share/fonts/truetype/arial.ttf'); + if po2 = nil then begin + freemem(pointer(font)); + pointer(font):= nil; + ok:= false; + exit; + end; + po1:= @((internaladd(fontdata^)^.data)); + po1^.h.name:= fontdata^.h.name; + po1^.h.height:= fontdata^.h.d.height; + po1^.handle:= pointer(po2); + ftglsetfontcharmap(po1^.handle,ft_encoding_unicode); + ftglsetfontfacesize(po1^.handle,20,72); + end; + inc(po1^.refcount); + handle:= po1^.handle; + ascent:= round(ftglgetfontascender(handle)); + descent:= -round(ftglgetfontdescender(handle)); + linespacing:= round(ftglgetfontlineheight(handle)); + caretshift:= 0; + end; + end; + end; +end; +*) +procedure tfontcache.internalfreefont(const afont: ptruint); +begin + //dummy +end; + +function tfontcache.getrecordsize(): int32; +begin + result:= sizeof(fontcachehashdataty); +end; + +procedure tfontcache.freefontdata(var drawinfo: drawinfoty); +var + po1: pfontcachehashdataty; +begin + with drawinfo.getfont.fontdata^ do begin + if font <> 0 then begin + po1:= getdatapo(getdataoffsfont(font)); + dec(po1^.data.refcount); + if po1^.data.refcount = 0 then begin + internalfreefont(font); + end; + internaldeleteitem(phashdataty(po1)); + end; + end; + if count = 0 then begin + freeandnil(finstancepo^); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/graphics/msefontconfig.pas b/mseide-msegui/lib/common/graphics/msefontconfig.pas new file mode 100644 index 0000000..d0c7379 --- /dev/null +++ b/mseide-msegui/lib/common/graphics/msefontconfig.pas @@ -0,0 +1,329 @@ +{ MSEgui Copyright (c) 2011-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msefontconfig; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msestrings,msectypes,msetypes; + +const + {$ifdef mswindows} + fontconfiglib: array[0..1] of filenamety = + ('libfontconfig-1.dll','fontconfig1.dll'); + {$else} + fontconfiglib: array[0..1] of filenamety = + ('libfontconfig.so.1','libfontconfig.so'); + {$endif} + FC_FAMILY = 'family'; //* String */ + FC_STYLE = 'style'; //* String */ + FC_SLANT = 'slant'; //* Int */ + FC_WEIGHT = 'weight'; //* Int */ + FC_SIZE = 'size'; //* Double */ + FC_ASPECT = 'aspect'; //* Double */ + FC_PIXEL_SIZE = 'pixelsize'; //* Double */ + FC_SPACING = 'spacing'; //* Int */ + FC_FOUNDRY = 'foundry'; //* String */ + FC_ANTIALIAS = 'antialias'; //* Bool (depends) */ + FC_HINTING = 'hinting'; //* Bool (true) */ + FC_VERTICAL_LAYOUT = 'verticallayout';//* Bool (false) */ + FC_AUTOHINT = 'autohint'; //* Bool (false) */ + FC_GLOBAL_ADVANCE = 'globaladvance'; //* Bool (true) */ + FC_FILE = 'file'; //* String */ + FC_INDEX = 'index'; //* Int */ + FC_FT_FACE = 'ftface'; //* FT_Face */ + FC_RASTERIZER = 'rasterizer'; //* String */ + FC_OUTLINE = 'outline'; //* Bool */ + FC_SCALABLE = 'scalable'; //* Bool */ + FC_SCALE = 'scale'; //* double */ + FC_DPI = 'dpi'; //* double */ + FC_RGBA = 'rgba'; //* Int */ + FC_MINSPACE = 'minspace'; //* Bool use minimum line spacing */ + FC_SOURCE = 'source'; //* String (X11, freetype) */ + FC_CHARSET = 'charset'; //* CharSet */ + FC_LANG = 'lang'; //* String RFC 3066 langs */ + FC_FONTVERSION = 'fontversion'; //* Int from 'head' table */ + + FC_MATRIX = 'matrix'; + FC_CHAR_WIDTH = 'charwidth'; + + FC_WEIGHT_BOLD = 200; + FC_SLANT_ITALIC = 100; + FC_PROPORTIONAL = 0; + FC_MONO = 100; + + +type + TFcChar8 = byte; + PFcChar8 = ^TFcChar8; + TFcChar16 = word; + PFcChar16 = ^TFcChar16; + TFcChar32 = dword; + PFcChar32 = ^TFcChar32; + TFcBool = longbool; //integer; + PFcBool = ^TFcBool; + TFcEndian = (FcEndianBig, FcEndianLittle); + TFcResult = (FcResultMatch, FcResultNoMatch, FcResultTypeMismatch, FcResultNoId); + PFcResult = ^TFcResult; + + TFcType = (FcTypeVoid,FcTypeInteger,FcTypeDouble, + FcTypeString,FcTypeBool,FcTypeMatrix, + FcTypeCharSet,FcTypeFTFace,FcTypeLangSet + ); + TFcMatchKind = (FcMatchPattern,FcMatchFont); + TFcMatrix = record + xx: cdouble; + xy: cdouble; + yx: cdouble; + yy: cdouble; + end; + PFcMatrix = ^TFcMatrix; + + TFcLangSet = record + //dummy + end; + PFcLangSet = ^TFcLangset; + + TFcStrList = record + //dummy + end; + PFcStrList = ^TFcStrList; + + TFcCharset = record + //dummy + end; + PFcCharset = ^TFcCharset; + PPFcCharset = ^PFcCharset; + + TFcPattern = record + //dummy + end; + PFcPattern = ^TFcPattern; + PPFcPattern = ^PFcPattern; + pfcpatternpoaty = array[0..0] of PFcPattern; + + TFcValue = record + _type: TFcType; + u: record + case longint of + 0 : ( s : ^TFcChar8 ); + 1 : ( i : longint ); + 2 : ( b : TFcBool ); + 3 : ( d : cdouble ); + 4 : ( m : ^TFcMatrix ); + 5 : ( c : ^TFcCharSet ); + 6 : ( f : pointer ); + 7 : ( p : ^TFcPattern ); + 8 : ( l : ^TFcLangSet ); + end; + end; + + TFcObjectSet = record + nobject: longint; + sobject: longint; + objects: ppchar; + end; + PFcObjectSet = ^TFcObjectSet; + + TFcConfig = record + //dummy + end; + PFcConfig = ^TFcConfig; + + TFcFontSet = record + nfont : integer; + sfont : integer; + fonts : PPFcPattern; + end; + PFcFontSet = ^TFcFontSet; + +var + FcInit: function: tfcbool;cdecl; + FcFini: procedure;cdecl; + FcConfigCreate: function: PFcConfig;cdecl; + FcConfigParseAndLoad: function(config: PFcConfig; afile: pchar; + complain: TFcBool): TFcBool;cdecl; + FcConfigGetCurrent: function: PFcConfig;cdecl; + FcConfigBuildFonts: function(config: PFcConfig): TFcBool;cdecl; + FcConfigGetConfigFiles: function(config: PFcConfig): PFcStrList;cdecl; + FcConfigGetFontDirs: function(config: PFcConfig): PFcStrList;cdecl; + FcConfigFilename: function(name: pchar): pchar;cdecl; + FcPatternDestroy: procedure(p:PFcPattern);cdecl; + FcFontSetDestroy: procedure(s:PFcFontSet);cdecl; + FcObjectSetCreate: function: PFcObjectSet;cdecl; + FcObjectSetAdd: function(os: PFcObjectSet; aobject:Pchar):TFcBool;cdecl; + FcObjectSetDestroy: procedure(os: PFcObjectSet);cdecl; + FcFontList: function(config: PFcConfig; p:PFcPattern; + os:PFcObjectSet): PFcFontSet;cdecl; + FcCharSetCreate: function: PFcCharSet;cdecl; + FcCharSetDestroy: procedure(fcs:PFcCharSet);cdecl; + FcCharSetAddChar: function(fcs:PFcCharSet; ucs4:TFcChar32):TFcBool;cdecl; + FcPatternAdd: function(p:PFcPattern; aobject:Pchar; value:TFcValue; + append:TFcBool):TFcBool;cdecl; + FcPatternCreate: function: PFcPattern;cdecl; + FcConfigSubstitute: function(config:PFcConfig; p:PFcPattern; + kind:TFcMatchKind):TFcBool;cdecl; + FcDefaultSubstitute: procedure (pattern:PFcPattern);cdecl; + FcFontSort: function (config:PFcConfig; p:PFcPattern; trim:TFcBool; + csp:PPFcCharSet; result:PFcResult): PFcFontSet;cdecl; + FcCharSetHasChar: function(fcs:PFcCharSet; ucs4:TFcChar32):TFcBool;cdecl; + FcPatternDuplicate: function (p:PFcPattern): PFcPattern;cdecl; + FcPatternGetCharSet: function (p:PFcPattern; aobject:Pchar; n:longint; + c:PPFcCharSet):TFcResult;cdecl; + FcFontRenderPrepare: function(config:PFcConfig; pat:PFcPattern; + font:PFcPattern): PFcPattern;cdecl; + FcFontMatch: function(config: PFcConfig; p: PFcPattern; + result: PFcResult): PFcPattern;cdecl; + FcMatrixRotate: procedure(m:PFcMatrix; c:cdouble; s:cdouble);cdecl; + FcMatrixScale: procedure(m:PFcMatrix; sx:cdouble; sy:cdouble);cdecl; + FcPatternAddInteger: function(p:PFcPattern; aobject:Pchar; i:longint):TFcBool; cdecl; + FcPatternAddDouble: function(p:PFcPattern; aobject:Pchar; d:cdouble):TFcBool; cdecl; + FcPatternAddString: function(p:PFcPattern; aobject:Pchar; s: pansichar):TFcBool; cdecl; + FcPatternAddMatrix: function(p:PFcPattern; aobject:Pchar; s:PFcMatrix):TFcBool; cdecl; + FcPatternAddCharSet: function(p:PFcPattern; + aobject:Pchar; c:PFcCharSet):TFcBool;cdecl; + FcPatternAddBool: function(p:PFcPattern; aobject:Pchar; b:TFcBool):TFcBool; cdecl; + FcPatternAddLangSet: function(p:PFcPattern; aobject:Pchar; + ls:PFcLangSet):TFcBool;cdecl; + + FcPatternGetString: function(p: PFcPattern; aobject: Pchar; n: integer; + s: ppchar): tfcresult; cdecl; + FcPatternGetInteger: function(p: PFcPattern; aobject: Pchar; n: integer; + i: pinteger): tfcresult; cdecl; + FcPatternGetDouble: function(p: PFcPattern; aobject: Pchar; n: integer; + i: pcdouble): tfcresult; cdecl; + FcNameParse: function(name: pchar): PFcPattern; cdecl; + FcStrListNext: function(list: PFcStrList): pchar; cdecl; + FcStrListDone: procedure(list: PFcStrList); cdecl; + +procedure FcMatrixInit(var m: TFcMatrix); + +procedure initializefontconfig(const sonames: array of filenamety); +procedure releasefontconfig; + +implementation + +uses + msesys,msedynload,sysutils; +var + libinfo: dynlibinfoty; + +procedure FcMatrixInit(var m: TFcMatrix); +begin + m.xx:= 1; + m.yy:= 1; + m.xy:= 0; + m.yx:= 0; +end; + +procedure init(const data: pointer); +{$ifdef mswindows} +var + li: pfcstrlist; + bo1: boolean; + str1: string; + conf1{,conf2}: pfcconfig; +{$endif} +begin + if not fcinit() then begin + raise exception.create( + 'Fontconfig: Can not read the default configuration file.'); + end; +{$ifdef mswindows} + li:= fcconfiggetconfigfiles(nil); + bo1:= fcstrlistnext(li) = nil; + fcstrlistdone(li); + if bo1 then begin + str1:= getenvironmentvariable('FC_CONFIG_FILE'); + if str1 = '' then begin + raise exception.create( + 'Fontconfig: No configuration file defined.'+lineend+ + 'Please set environment variable FC_CONFIG_FILE.'); + end; + conf1:= fcconfiggetcurrent(); + if not fcconfigparseandload(conf1,pchar(str1),false) then begin + raise exception.create( + 'Fontconfig: Can not read config file:'+lineend+str1); + end; + end; +{$endif} + if not fcconfigbuildfonts(nil) then begin + raise exception.create( + 'Fontconfig: Can not build default fonts.'); + end; +end; + +procedure deinit(const data: pointer); +begin +// fcfini; +end; + +procedure initializefontconfig(const sonames: array of filenamety); +const + funcs: array[0..42] of funcinfoty = ( + (n: 'FcPatternDestroy'; d: {$ifndef FPC}@{$endif}@FcPatternDestroy), //0 + (n: 'FcFontSetDestroy'; d: {$ifndef FPC}@{$endif}@FcFontSetDestroy), //1 + (n: 'FcObjectSetCreate'; d: {$ifndef FPC}@{$endif}@FcObjectSetCreate), //2 + (n: 'FcObjectSetAdd'; d: {$ifndef FPC}@{$endif}@FcObjectSetAdd), //3 + (n: 'FcObjectSetDestroy'; d: {$ifndef FPC}@{$endif}@FcObjectSetDestroy), //4 + (n: 'FcFontList'; d: {$ifndef FPC}@{$endif}@FcFontList), //5 + (n: 'FcCharSetCreate'; d: {$ifndef FPC}@{$endif}@FcCharSetCreate), //6 + (n: 'FcCharSetDestroy'; d: {$ifndef FPC}@{$endif}@FcCharSetDestroy), //7 + (n: 'FcCharSetAddChar'; d: {$ifndef FPC}@{$endif}@FcCharSetAddChar), //8 + (n: 'FcPatternAdd'; d: {$ifndef FPC}@{$endif}@FcPatternAdd), //9 + (n: 'FcPatternCreate'; d: {$ifndef FPC}@{$endif}@FcPatternCreate), //10 + (n: 'FcConfigSubstitute'; d: {$ifndef FPC}@{$endif}@FcConfigSubstitute), //11 + (n: 'FcDefaultSubstitute'; d: {$ifndef FPC}@{$endif}@FcDefaultSubstitute), //12 + (n: 'FcFontSort'; d: {$ifndef FPC}@{$endif}@FcFontSort), //13 + (n: 'FcCharSetHasChar'; d: {$ifndef FPC}@{$endif}@FcCharSetHasChar), //14 + (n: 'FcPatternDuplicate'; d: {$ifndef FPC}@{$endif}@FcPatternDuplicate), //15 + (n: 'FcPatternGetCharSet'; d: {$ifndef FPC}@{$endif}@FcPatternGetCharSet), //16 + (n: 'FcFontRenderPrepare'; d: {$ifndef FPC}@{$endif}@FcFontRenderPrepare), //17 + (n: 'FcMatrixRotate'; d: {$ifndef FPC}@{$endif}@FcMatrixRotate), //18 + (n: 'FcMatrixScale'; d: {$ifndef FPC}@{$endif}@FcMatrixScale), //19 + (n: 'FcPatternAddInteger'; d: {$ifndef FPC}@{$endif}@FcPatternAddInteger), //20 + (n: 'FcPatternAddDouble'; d: {$ifndef FPC}@{$endif}@FcPatternAddDouble), //21 + (n: 'FcPatternAddString'; d: {$ifndef FPC}@{$endif}@FcPatternAddString), //22 + (n: 'FcPatternAddMatrix'; d: {$ifndef FPC}@{$endif}@FcPatternAddMatrix), //23 + (n: 'FcPatternAddCharSet'; d: {$ifndef FPC}@{$endif}@FcPatternAddCharSet), //24 + (n: 'FcPatternAddBool'; d: {$ifndef FPC}@{$endif}@FcPatternAddBool), //25 + (n: 'FcPatternAddLangSet'; d: {$ifndef FPC}@{$endif}@FcPatternAddLangSet), //26 + (n: 'FcPatternGetString'; d: {$ifndef FPC}@{$endif}@FcPatternGetString), //27 + (n: 'FcInit'; d: {$ifndef FPC}@{$endif}@FcInit), //28 + (n: 'FcFini'; d: {$ifndef FPC}@{$endif}@FcFini), //29 + (n: 'FcNameParse'; d: {$ifndef FPC}@{$endif}@FcNameParse), //30 + (n: 'FcFontMatch'; d: {$ifndef FPC}@{$endif}@FcFontMatch), //31 + (n: 'FcPatternGetInteger'; d: {$ifndef FPC}@{$endif}@FcPatternGetInteger), //32 + (n: 'FcPatternGetDouble'; d: {$ifndef FPC}@{$endif}@FcPatternGetDouble), //33 + (n: 'FcConfigFilename'; d: {$ifndef FPC}@{$endif}@FcConfigFilename), //34 + (n: 'FcConfigCreate'; d: {$ifndef FPC}@{$endif}@FcConfigCreate), //35 + (n: 'FcConfigParseAndLoad'; d: {$ifndef FPC}@{$endif}@FcConfigParseAndLoad), //36 + (n: 'FcStrListNext'; d: {$ifndef FPC}@{$endif}@FcStrListNext), //37 + (n: 'FcStrListDone'; d: {$ifndef FPC}@{$endif}@FcStrListDone), //38 + (n: 'FcConfigGetConfigFiles'; d: {$ifndef FPC}@{$endif}@FcConfigGetConfigFiles),//39 + (n: 'FcConfigGetFontDirs'; d: {$ifndef FPC}@{$endif}@FcConfigGetFontDirs), //40 + (n: 'FcConfigBuildFonts'; d: {$ifndef FPC}@{$endif}@FcConfigBuildFonts), //41 + (n: 'FcConfigGetCurrent'; d: {$ifndef FPC}@{$endif}@FcConfigGetCurrent) //42 + ); + errormessage = 'Can not load FontConfig library. '; +begin + initializedynlib(libinfo,sonames,fontconfiglib,funcs,[],errormessage,@init); +end; + +procedure releasefontconfig; +begin + releasedynlib(libinfo,@deinit); +end; + + +initialization + initializelibinfo(libinfo); +finalization + finalizelibinfo(libinfo); +end. diff --git a/mseide-msegui/lib/common/graphics/msefreetype.pas b/mseide-msegui/lib/common/graphics/msefreetype.pas new file mode 100644 index 0000000..b971449 --- /dev/null +++ b/mseide-msegui/lib/common/graphics/msefreetype.pas @@ -0,0 +1,475 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 2003 by the Free Pascal development team + + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + modified 2011 by Martin Schreiber + + **********************************************************************} +{$mode objfpc} {$h+} +unit msefreetype; + +{ Note that these are not all the availlable calls from the dll yet. + This unit is used by TStringBitMaps and FTFont } + +interface +uses + msetypes,sysutils,msectypes; + +const + +{$ifdef FPC} + {$packrecords c} +{$else} + {$ALIGN 4} + {$MINENUMSIZE 4} +{$endif} + +{$ifdef mswindows} + freetypelib: array[0..2] of filenamety = + ('libfreetype-6.dll','freetype6.dll','freetype.dll'); +{$else} + freetypelib: array[0..1] of filenamety = ('libfreetype.so.6','libfreetype.so'); +{$endif} + +type + FT_Encoding = array[0..3] of char; + + efreetype = class(exception) + end; + +const + FT_FACE_FLAG_SCALABLE = 1 shl 0; + FT_FACE_FLAG_FIXED_SIZES = 1 shl 1; + FT_FACE_FLAG_FIXED_WIDTH = 1 shl 2; + FT_FACE_FLAG_SFNT = 1 shl 3; + FT_FACE_FLAG_HORIZONTAL = 1 shl 4; + FT_FACE_FLAG_VERTICAL = 1 shl 5; + FT_FACE_FLAG_KERNING = 1 shl 6; + FT_FACE_FLAG_FAST_GLYPHS = 1 shl 7; + FT_FACE_FLAG_MULTIPLE_MASTERS = 1 shl 8; + FT_FACE_FLAG_GLYPH_NAMES = 1 shl 9; + FT_FACE_FLAG_EXTERNAL_STREAM = 1 shl 10; + + FT_STYLE_FLAG_ITALIC = 1 shl 0; + FT_STYLE_FLAG_BOLD = 1 shl 1; + + FT_LOAD_DEFAULT = $0000; + FT_LOAD_NO_SCALE = $0001; + FT_LOAD_NO_HINTING = $0002; + FT_LOAD_RENDER = $0004; + FT_LOAD_NO_BITMAP = $0008; + FT_LOAD_VERTICAL_LAYOUT = $0010; + FT_LOAD_FORCE_AUTOHINT = $0020; + FT_LOAD_CROP_BITMAP = $0040; + FT_LOAD_PEDANTIC = $0080; + FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH = $0200; + FT_LOAD_NO_RECURSE = $0400; + FT_LOAD_IGNORE_TRANSFORM = $0800; + FT_LOAD_MONOCHROME = $1000; + FT_LOAD_LINEAR_DESIGN = $2000; + + ft_glyph_format_none = $00000000; + ft_glyph_format_composite = $636F6D70; //comp 099 111 109 112 + ft_glyph_format_bitmap = $62697473; //bits 098 105 116 115 + ft_glyph_format_outline = $6F75746C; //outl 111 117 116 108 + ft_glyph_format_plotter = $706C6F74; //plot 112 108 111 116 + + FT_ENCODING_MS_SYMBOL : FT_Encoding = 'symb'; + FT_ENCODING_UNICODE : FT_Encoding = 'unic'; + FT_ENCODING_MS_SJIS : FT_Encoding = 'sjis'; + FT_ENCODING_MS_GB2312 : FT_Encoding = 'gb '; + FT_ENCODING_MS_BIG5 : FT_Encoding = 'big5'; + FT_ENCODING_MS_WANSUNG : FT_Encoding = 'wans'; + FT_ENCODING_MS_JOHAB : FT_Encoding = 'joha'; + FT_ENCODING_ADOBE_STANDARD : FT_Encoding = 'ADOB'; + FT_ENCODING_ADOBE_EXPERT : FT_Encoding = 'ADBE'; + FT_ENCODING_ADOBE_CUSTOM : FT_Encoding = 'ADBC'; + FT_ENCODING_ADOBE_LATIN_1 : FT_Encoding = 'lat1'; + FT_ENCODING_OLD_LATIN_2 : FT_Encoding = 'lat2'; + FT_ENCODING_APPLE_ROMAN : FT_Encoding = 'armn'; + + ft_glyph_bbox_unscaled = 0; //* return unscaled font units */ + ft_glyph_bbox_subpixels = 0; //* return unfitted 26.6 coordinates */ + ft_glyph_bbox_gridfit = 1; //* return grid-fitted 26.6 coordinates */ + ft_glyph_bbox_truncate = 2; //* return coordinates in integer pixels */ + ft_glyph_bbox_pixels = 3; //* return grid-fitted pixel coordinates */ + + FT_KERNING_DEFAULT = 0; + FT_KERNING_UNFITTED = 1; + FT_KERNING_UNSCALED = 2; + + +type + + FT_Bool = cuchar; + FT_FWord = cshort; + FT_UFWord = cushort; + FT_Char = cchar; + FT_Byte = cuchar; + FT_Bytes = ^FT_Byte; + FT_String = cchar; + FT_Short = cshort; + FT_UShort = cushort; + FT_Int = cint; + FT_UInt = cuint; + FT_Long = clong; + FT_ULong = culong; + FT_Pos = clong; + FT_F2Dot14 = cshort; + FT_F26Dot6 = clong; + FT_Fixed = clong; + FT_Error = cint; + FT_Pointer = pointer; + //FT_Offset = size_t; + //FT_PtrDist = size_t; + + FT_Render_Mode = (FT_RENDER_MODE_NORMAL, FT_RENDER_MODE_LIGHT, + FT_RENDER_MODE_MONO, FT_RENDER_MODE_LCD, FT_RENDER_MODE_LCD_V, + FT_RENDER_MODE_MAX); + + FT_UnitVector_ = record + x : FT_F2Dot14; + y : FT_F2Dot14; + end; + FT_UnitVector = FT_UnitVector_; + + FT_Matrix = record + xx : FT_Fixed; + xy : FT_Fixed; + yx : FT_Fixed; + yy : FT_Fixed; + end; + PFT_Matrix = ^FT_Matrix; + + FT_Data = record + pointer : ^FT_Byte; + length : FT_Int; + end; + + FT_Generic_Finalizer = procedure (AnObject:pointer);cdecl; + + FT_Generic = record + data : pointer; + finalizer : FT_Generic_Finalizer; + end; + + FT_Glyph_Metrics = record + width : FT_Pos; + height : FT_Pos; + horiBearingX : FT_Pos; + horiBearingY : FT_Pos; + horiAdvance : FT_Pos; + vertBearingX : FT_Pos; + vertBearingY : FT_Pos; + vertAdvance : FT_Pos; + end; + + FT_Bitmap_Size = record + height : FT_Short; + width : FT_Short; + end; + AFT_Bitmap_Size = array [0..1023] of FT_Bitmap_Size; + PFT_Bitmap_Size = ^AFT_Bitmap_Size; + + FT_Vector = record + x : FT_Pos; + y : FT_Pos; + end; + PFT_Vector = ^FT_Vector; + + FT_BBox = record + xMin, yMin : FT_Pos; + xMax, yMax : FT_Pos; + end; + PFT_BBox = ^FT_BBox; + + FT_Bitmap = record + rows : cint; + width : cint; + pitch : cint; + buffer : pointer; + num_grays : ft_short; + pixel_mode : cchar; + palette_mode : cchar; + palette : pointer; + end; + + FT_Outline = record + n_contours, + n_points : smallint; + points : PFT_Vector; + tags : pchar; + contours : ^smallint; + flags : integer; + end; + PFT_Outline = ^FT_Outline; + + FT_Outline_MoveToFunc = function(const to_: PFT_Vector; user: Pointer): integer; + FT_Outline_LineToFunc = function(const to_: PFT_Vector; user: Pointer): integer; + FT_Outline_ConicToFunc = function(const control, to_: PFT_Vector; user: Pointer): integer; + FT_Outline_CubicToFunc = function(const control1, control2, to_: PFT_Vector; user: Pointer): integer; + + FT_Outline_Funcs = record + move_to: FT_Outline_MoveToFunc; + line_to: FT_Outline_LineToFunc; + conic_to: FT_Outline_ConicToFunc; + cubic_to: FT_Outline_CubicToFunc; + shift: integer; + delta: FT_Pos; + end; + PFT_Outline_Funcs = ^FT_Outline_Funcs; + + FT_Size_Metrics = record + x_ppem : FT_UShort; + y_ppem : FT_UShort; + x_scale : FT_Fixed; + y_scale : FT_Fixed; + ascender : FT_Pos; + descender : FT_Pos; + height : FT_Pos; + max_advance : FT_Pos; + end; + + + PFT_Library = ^TFT_Library; + //PPFT_Library = ^PFT_Library; + PFT_Face = ^TFT_Face; + //PPFT_Face = ^PFT_Face; + PFT_Charmap = ^TFT_Charmap; + PPFT_Charmap = ^PFT_Charmap; + PFT_GlyphSlot = ^TFT_GlyphSlot; + PFT_Subglyph = ^TFT_Subglyph; + PFT_Size = ^TFT_Size; + + PFT_Glyph = ^TFT_Glyph; + //PPFT_Glyph = ^PFT_Glyph; + PFT_BitmapGlyph = ^TFT_BitmapGlyph; + PFT_OutlineGlyph = ^TFT_OutlineGlyph; + + + TFT_Library = record + end; + + TFT_Charmap = record + face : PFT_Face; + encoding : FT_Encoding; + platform_id, encoding_id : FT_UShort; + end; + + TFT_Size = record + face : PFT_Face; + generic : FT_Generic; + metrics : FT_Size_Metrics; + //internal : FT_Size_Internal; + end; + + TFT_Subglyph = record // TODO + end; + + TFT_GlyphSlot = record + alibrary : PFT_Library; + face : PFT_Face; + next : PFT_GlyphSlot; + flags : FT_UInt; + generic : FT_Generic; + metrics : FT_Glyph_Metrics; + linearHoriAdvance : FT_Fixed; + linearVertAdvance : FT_Fixed; + advance : FT_Vector; + format : longword; + bitmap : FT_Bitmap; + bitmap_left : FT_Int; + bitmap_top : FT_Int; + outline : FT_Outline; + num_subglyphs : FT_UInt; + subglyphs : PFT_SubGlyph; + control_data : pointer; + control_len : longint; + other : pointer; + end; + + TFT_Face = record + num_faces : FT_Long; + face_index : FT_Long; + face_flags : FT_Long; + style_flags : FT_Long; + num_glyphs : FT_Long; + family_name : pchar; + style_name : pchar; + num_fixed_sizes : FT_Int; + available_sizes : PFT_Bitmap_Size; // is array + num_charmaps : FT_Int; + charmaps : PPFT_CharMap; // is array + generic : FT_Generic; + bbox : FT_BBox; + units_per_EM : FT_UShort; + ascender : FT_Short; + descender : FT_Short; + height : FT_Short; + max_advance_width : FT_Short; + max_advance_height : FT_Short; + underline_position : FT_Short; + underline_thickness : FT_Short; + glyph : PFT_GlyphSlot; + size : PFT_Size; + charmap : PFT_CharMap; + end; + + TFT_Glyph = record + FTlibrary : PFT_Library; + clazz : pointer; + aFormat : longword; + advance : FT_Vector; + end; + + TFT_BitmapGlyph = record + root : TFT_Glyph; + left, top : FT_Int; + bitmap : FT_Bitmap; + end; + + TFT_OutlineGlyph = record + root : TFT_Glyph; + outline : FT_Outline; + end; + + function FT_IS_SCALABLE(face: PFT_Face): boolean; + +var + ftlib: pft_library; +//Base Interface + FT_Done_Face: function(face: PFT_Face): integer; cdecl; + FT_Done_FreeType: function(alibrary: PFT_Library): integer; cdecl; + FT_Get_Char_Index: function(face: PFT_Face; charcode: FT_ULong): FT_UInt; cdecl; + FT_Get_Kerning: function(face: PFT_Face; left_glyph, right_glyph, + kern_mode: FT_UInt; out akerning: FT_Vector): integer; cdecl; + FT_Init_FreeType: function(var alibrary: PFT_Library): integer; cdecl; + FT_Load_Char: function(face: PFT_Face; charcode: FT_ULong; + load_flags: longint): integer; cdecl; + FT_Load_Glyph: function(face: PFT_Face; glyph_index: FT_UInt; + load_flags: longint): integer; cdecl; + FT_Render_Glyph: function(slot: PFT_GlyphSlot; + render_mode: FT_Render_Mode): integer; cdecl; + FT_New_Face: function(alibrary: PFT_Library; filepathname: PChar; + face_index: integer; var aface: PFT_Face): integer; cdecl; + FT_Set_Char_Size: function(face: PFT_Face; char_width, char_height: FT_F26dot6; + horz_res, vert_res: FT_UInt): integer; cdecl; + FT_Set_Pixel_Sizes: function(face: PFT_Face; + pixel_width, pixel_height: FT_UInt): integer; cdecl; + FT_Set_Transform: procedure(face: PFT_Face; matrix: PFT_Matrix; + delta: PFT_Vector); cdecl; + +//Outline Processing + FT_Outline_Decompose: function(outline: PFT_Outline; + const func_interface: PFT_Outline_Funcs; user: Pointer): integer; cdecl; + +//FreeType Version + FT_Library_Version: procedure(alibrary: PFT_Library; + var amajor, aminor, apatch: integer); cdecl; + +//Glyph Management + FT_Get_Glyph: function(slot: PFT_GlyphSlot; + out aglyph: PFT_Glyph): integer; cdecl; + FT_Glyph_Copy: function(Source: PFT_Glyph; + out target: PFT_Glyph): integer; cdecl; + FT_Glyph_To_Bitmap: function(var the_glyph: PFT_Glyph; + render_mode: FT_Render_Mode; origin: PFT_Vector; + Destroy: FT_Bool): integer; cdecl; + FT_Glyph_Transform: function(glyph: PFT_Glyph; matrix: PFT_Matrix; + delta: PFT_Vector): integer; cdecl; + FT_Done_Glyph: procedure(glyph: PFT_Glyph); cdecl; + FT_Glyph_Get_CBox: procedure(glyph: PFT_Glyph; bbox_mode: FT_UInt; + var acbox: FT_BBox); cdecl; + +procedure initializefreetype(const sonames: array of filenamety); +procedure releasefreetype; +procedure ftcheckerror(const aerror: ft_error; const amessage: msestring = ''); +function ftpostopixel(const apos: ft_pos): integer; inline; + +implementation + +uses + msesys,msedynload; +var + libinfo: dynlibinfoty; +const + ftposshift = 6; + ftposscale = 64; //2^6 + ftposhalf = (1 shl ftposshift) div 2; + +function ftpostopixel(const apos: ft_pos): integer; inline; +begin + result:= (apos + ftposhalf) div ftposscale; +end; + +function FT_IS_SCALABLE(face: PFT_Face): boolean; +begin + Result := (face^.face_flags and FT_FACE_FLAG_SCALABLE) = 1; +end; + +procedure ftcheckerror(const aerror: integer; const amessage: msestring); +begin + if aerror <> 0 then begin + raise efreetype.create('Freetype error '+inttostr(aerror)+':'+lineend+ + ansistring(amessage)); + end; +end; + +procedure initft(const data: pointer); +begin + ftcheckerror(ft_init_freetype(ftlib),'Init freetype library.'); +end; + +procedure deinitft(const data: pointer); +begin + ftcheckerror(ft_done_freetype(ftlib),'Deinit freetype library.'); + ftlib:= nil; +end; + +procedure initializefreetype(const sonames: array of filenamety); +const + funcs: array[0..19] of funcinfoty = ( + (n: 'FT_Done_Face'; d: @FT_Done_Face), //0 + (n: 'FT_Done_FreeType'; d: @FT_Done_FreeType), //1 + (n: 'FT_Get_Char_Index'; d: @FT_Get_Char_Index), //2 + (n: 'FT_Get_Kerning'; d: @FT_Get_Kerning), //3 + (n: 'FT_Init_FreeType'; d: @FT_Init_FreeType), //4 + (n: 'FT_Load_Char'; d: @FT_Load_Char), //5 + (n: 'FT_Load_Glyph'; d: @FT_Load_Glyph), //6 + (n: 'FT_New_Face'; d: @FT_New_Face), //7 + (n: 'FT_Set_Char_Size'; d: @FT_Set_Char_Size), //8 + (n: 'FT_Set_Pixel_Sizes'; d: @FT_Set_Pixel_Sizes), //9 + (n: 'FT_Set_Transform'; d: @FT_Set_Transform), //10 + (n: 'FT_Outline_Decompose'; d: @FT_Outline_Decompose),//11 + (n: 'FT_Library_Version'; d: @FT_Library_Version), //12 + (n: 'FT_Get_Glyph'; d: @FT_Get_Glyph), //13 + (n: 'FT_Glyph_Copy'; d: @FT_Glyph_Copy), //14 + (n: 'FT_Glyph_To_Bitmap'; d: @FT_Glyph_To_Bitmap), //15 + (n: 'FT_Glyph_Transform'; d: @FT_Glyph_Transform), //16 + (n: 'FT_Done_Glyph'; d: @FT_Done_Glyph), //17 + (n: 'FT_Glyph_Get_CBox'; d: @FT_Glyph_Get_CBox), //18 + (n: 'FT_Render_Glyph'; d: @FT_Render_Glyph) //19 + ); + errormessage = 'Can not load Freetype library. '; +begin + initializedynlib(libinfo,sonames,freetypelib,funcs,[],errormessage,@initft); +end; + +procedure releasefreetype; +begin + releasedynlib(libinfo,@deinitft); +end; + +initialization + initializelibinfo(libinfo); +finalization + finalizelibinfo(libinfo); +end. diff --git a/mseide-msegui/lib/common/graphics/mseftfontcache.pas b/mseide-msegui/lib/common/graphics/mseftfontcache.pas new file mode 100644 index 0000000..f082726 --- /dev/null +++ b/mseide-msegui/lib/common/graphics/mseftfontcache.pas @@ -0,0 +1,438 @@ +{ MSEgui Copyright (c) 2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +// +//under construction +// +unit mseftfontcache; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +//todo: limit buffer size + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + msefontcache,msegraphics,msestrings,msetypes,mseguiglob,msegraphutils,msehash; + +type + bitmapdataty = record + width: smallint; + height: smallint; + left: smallint; + top: smallint; + data: record + end; + end; + pbitmapdataty= ^bitmapdataty; + + tftfontcache = class(tfontcache) + protected + procedure internalfreefont(const afont: ptruint); override; + function internalgetfont(const ainfo: getfontinfoty; + out aheight: integer): boolean; override; + procedure updatefontinfo(const adataoffset: hashoffsetty; + var adata: fontcachedataty); override; + procedure drawglyph(var drawinfo: drawinfoty; const pos: pointty; + const bitmap: pbitmapdataty); virtual; abstract; + function getdataoffsfont(const afont: fontty): hashoffsetty; override; + function textbackgroundrect(const drawinfo: drawinfoty; + const afont: fontty; out arect: rectty): boolean; + public + constructor create(var ainstance: tftfontcache); + destructor destroy; override; + procedure gettext16width(var drawinfo: drawinfoty); override; + procedure getchar16widths(var drawinfo: drawinfoty); override; + procedure getfontmetrics(var drawinfo: drawinfoty); override; + procedure drawstring16(var drawinfo: drawinfoty; + const afont: fontty); override; + end; + +implementation +uses + msefreetype,msefontconfig,msefcfontselect,math; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + charcount = $10000; //UCS2 + bucketshift = 9; //charrowlength = 128 + charbucketcount = 1 shl bucketshift; + charrowlength = charcount div charbucketcount; + charrowmask = charrowlength - 1; + +type + glyphinfoty = record + width: smallint; + leftbearing: smallint; + rightbearing: smallint; + bitmap: longword; //buffer offset to bitmapdatatyty 0->not rendered yet + end; + + pglyphinfoty = ^glyphinfoty; + charrowty = array[0..charrowlength-1] of longword; //offset in buffer + pcharrowty = ^charrowty; + charbucketty = array[0..charbucketcount-1] of longword; + //offset to charrowty in buffer + tftface = class + private + fface: pft_face; + fbuckets: charbucketty; + fbuffer: pointer; + fsize: longword; + fcapacity: longword; + protected + fdataoffset: hashoffsetty; + fascent: integer; + fdescent: integer; + fglyphheight: integer; + flinespacing: integer; + function getbuffer(const asize: integer; const ainit: boolean): longword; + public + constructor create(const aface: pft_face); + destructor destroy; override; + function getglyph(const achar: msechar; out ainfo: pglyphinfoty; + const forceload: boolean): boolean; + //true if found + procedure renderglyph(var ainfo: pglyphinfoty); + end; + +{ tftfontcache } + +constructor tftfontcache.create(var ainstance: tftfontcache); +begin + initializefreetype([]); + initializefontconfig([]); + inherited create(tfontcache(ainstance)); +end; + +destructor tftfontcache.destroy; +begin + inherited; + releasefreetype; + releasefontconfig; +end; + +procedure tftfontcache.internalfreefont(const afont: ptruint); +begin + tftface(pointer(afont)).free; +end; + +function tftfontcache.internalgetfont(const ainfo: getfontinfoty; + out aheight: integer): boolean; +var + ftface: pft_face; + str1: string; + int1: integer; +begin + result:= false; + with ainfo do begin + if getfcfontfile(ainfo,str1,int1,aheight) then begin + if ft_new_face(ftlib,pchar(str1),int1,ftface) = 0 then begin + if ft_set_pixel_sizes(ftface,0,aheight) = 0 then begin + pointer(fontdata^.font):= tftface.create(ftface); + result:= true; + end; + end; + end; + end; +end; + +procedure tftfontcache.updatefontinfo(const adataoffset: hashoffsetty; + var adata: fontcachedataty); +var + scale: real; +begin + with tftface(pointer(adata.font)),fface^ do begin + fdataoffset:= adataoffset; + scale:= adata.height/units_per_em; + fascent:= round(ascender*scale); + fdescent:= -round(descender*scale); + fglyphheight:= fascent+fdescent; + flinespacing:= ceil(height*scale); + adata.ascent:= fascent; + adata.descent:= fdescent; + adata.height:= fglyphheight; + adata.linespacing:= flinespacing; + adata.caretshift:= 0; + end; +end; + +procedure tftfontcache.gettext16width(var drawinfo: drawinfoty); +var + po1: pmsecharaty; + po3: pglyphinfoty; + face1: tftface; + int1,int2: integer; +begin + with drawinfo.gettext16width do begin + face1:= tftface(pointer(fontdata^.font)); + po1:= pointer(text); + face1:= tftface(pointer(fontdata^.font)); + int2:= 0; + for int1:= count-1 downto 0 do begin + if face1.getglyph(po1^[int1],po3,false) then begin + int2:= int2 + po3^.width; + end + end; + result:= int2; + end; +end; + +procedure tftfontcache.getchar16widths(var drawinfo: drawinfoty); +var + int1: integer; + po1: pmsecharaty; + po2: pintegeraty; + po3: pglyphinfoty; + face1: tftface; +begin + with drawinfo.getchar16widths do begin + face1:= tftface(pointer(fontdata^.font)); + po1:= pointer(text); + po2:= pointer(resultpo); + for int1:= count-1 downto 0 do begin + if face1.getglyph(po1^[int1],po3,false) then begin + po2^[int1]:= po3^.width; + end + else begin + po2^[int1]:= 0; + end; + end; + end; +end; + +procedure tftfontcache.getfontmetrics(var drawinfo: drawinfoty); +var + face: tftface; + po1: pglyphinfoty; +begin + with drawinfo.getfontmetrics do begin + face:= tftface(pointer(fontdata^.font)); + if face.getglyph(msechar(char),po1,false) then begin //todo: 32bit + with resultpo^ do begin + width:= po1^.width; + leftbearing:= po1^.leftbearing; + rightbearing:= po1^.rightbearing; //correct??? + end; + end + else begin + with resultpo^ do begin + width:= 0; + leftbearing:= 0; + rightbearing:= 0; + end; + end; + end; +end; + +function tftfontcache.textbackgroundrect(const drawinfo: drawinfoty; + const afont: fontty; out arect: rectty): boolean; + +var + face: tftface; + po1: pglyphinfoty; + po2: pmsecharaty; + int1,int2: integer; +begin + result:= false; + with drawinfo,text16pos do begin + if count = 0 then begin + arect:= nullrect; + exit; + end; + face:= tftface(pointer(afont)); + po2:= pointer(text); + if face.getglyph(po2^[0],po1,false) then begin + with arect do begin + x:= text16pos.pos^.x {+ po1^.leftbearing}; + int2:= po1^.width {- po1^.leftbearing}; + for int1:= 1 to count - 1 do begin + if face.getglyph(po2^[int1],po1,false) then begin + int2:= int2+po1^.width; + end; + end; + cx:= int2 {+ po1^.rightbearing}; + y:= text16pos.pos^.y - face.fascent; + cy:= face.fglyphheight; + end; + result:= true; + end; + end; +end; + +procedure tftfontcache.drawstring16(var drawinfo: drawinfoty; + const afont: fontty); +var + face: tftface; + po1: pglyphinfoty; + po2: pmsecharaty; + po3: pbitmapdataty; + int1: integer; +// rect1: rectty; + pt1: pointty; + y1: integer; +begin + with drawinfo,text16pos do begin + if count = 0 then begin + exit; + end; + pt1.x:= pos^.x + origin.x; + y1:= pos^.y + origin.y - 1; + face:= tftface(pointer(afont)); + po2:= pointer(text); + for int1:= 0 to count-1 do begin + if face.getglyph(po2^[int1],po1,true) then begin + if po1^.bitmap = 0 then begin + face.renderglyph(po1); + end; + if po1^.bitmap <> 0 then begin //render error otherwise + po3:= pointer(pchar(face.fbuffer)+po1^.bitmap); + pt1.x:= pt1.x + po3^.left; + pt1.y:= y1 - po3^.top; + drawglyph(drawinfo,pt1,po3); + end; + pt1.x:= pt1.x - po3^.left + po1^.width; + end; + end; + end; +end; + +function tftfontcache.getdataoffsfont(const afont: fontty): hashoffsetty; +begin + result:= tftface(pointer(afont)).fdataoffset; +end; + +{ tftface } + +constructor tftface.create(const aface: pft_face); +begin + fface:= aface; + fsize:= sizeof(longword); //dummy + fcapacity:= 1024; + getmem(fbuffer,fcapacity); +end; + +destructor tftface.destroy; +begin + inherited; + freemem(fbuffer); + ft_done_face(fface); +end; + +function tftface.getbuffer(const asize: integer; + const ainit: boolean): longword; +begin + result:= fsize; + fsize:= (fsize + asize + 3) and not 3; //4 byte align + if fsize > fcapacity then begin + fcapacity:= fcapacity * 2 - fcapacity div 2; //* 1.5 + reallocmem(fbuffer,fcapacity); + end; + if ainit then begin + fillchar((pchar(fbuffer)+result)^,asize,0); + end; +end; + +procedure tftface.renderglyph(var ainfo: pglyphinfoty); + //must be called after getglyph +var + po1: pchar; + so,de: pbyteaty; + int1,int2,int3: integer; + bm1: pbitmapdataty; +begin + if ft_render_glyph(fface^.glyph,ft_render_mode_normal) = 0 then begin + with fface^.glyph^,bitmap do begin +//todo: check bitmap format + po1:= fbuffer; + int3:= getbuffer(sizeof(bitmapdataty) + width * rows,false); + ainfo:= pointer(pchar(ainfo) + + (pchar(fbuffer) - pchar(po1))); + ainfo^.bitmap:= int3; + bm1:= pointer(pchar(fbuffer)+int3); + bm1^.width:= width; + bm1^.height:= rows; + bm1^.left:= bitmap_left; + bm1^.top:= bitmap_top-rows; + de:= @bm1^.data; + if pitch < 0 then begin + so:= buffer; + end + else begin + so:= pointer(pchar(buffer)+(rows-1)*pitch); + end; + for int1:= rows - 1 downto 0 do begin + for int2:= width-1 downto 0 do begin + de[int2]:= so[int2]; + end; + de:= pointer(pchar(de)+width); + so:= pointer(pchar(so)-pitch); + end; + end; + end +end; + //todo: 32bit +function tftface.getglyph(const achar: msechar; out ainfo: pglyphinfoty; + const forceload: boolean): boolean; +var + int1,int2,int3: integer; + po1: pcharrowty; +begin + result:= true; + int1:= word(achar) shr bucketshift; + int2:= word(achar) and charrowmask; + if fbuckets[int1] = 0 then begin + fbuckets[int1]:= getbuffer(sizeof(charrowty),true); + end; + po1:= pcharrowty(pchar(fbuffer)+fbuckets[int1]); + int3:= po1^[int2]; + if int3 = 0 then begin + if ft_load_glyph(fface,ft_get_char_index(fface,ord(achar)), + ft_load_default) = 0 then begin + int3:= getbuffer(sizeof(glyphinfoty),false); + po1^[int2]:= int3; + ainfo:= pglyphinfoty(pchar(fbuffer)+int3); + with fface^.glyph^ do begin + ainfo^.width:= ftpostopixel(advance.x); + ainfo^.leftbearing:= ftpostopixel(metrics.horibearingx); + ainfo^.rightbearing:= ftpostopixel(metrics.horiadvance-metrics.width); + end; + ainfo^.bitmap:= 0; //not rendered yet + end + else begin + ainfo:= nil; + result:= false; + end; + end + else begin + if forceload then begin + if ft_load_glyph(fface,ft_get_char_index(fface,ord(achar)), + ft_load_default) <> 0 then begin + result:= false; + end; + end; + ainfo:= pglyphinfoty(pchar(fbuffer)+int3); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/graphics/mseftglyphs.pas b/mseide-msegui/lib/common/graphics/mseftglyphs.pas new file mode 100644 index 0000000..3587d41 --- /dev/null +++ b/mseide-msegui/lib/common/graphics/mseftglyphs.pas @@ -0,0 +1,287 @@ +{ MSEgui Copyright (c) 2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseftglyphs; +{$ifdef FPC}{$mode objfpc}{$h+}{$goto on}{$endif} +interface +uses + msefreetype,msestrings,msebitmap,msetypes,msegraphutils; + +type + tftglyphs = class + private + fftface: pft_face; + procedure setheight(const avalue: int32); + protected + fheight: int32; + fascent: int32; + fascent64: int32; + fdescent: int32; + fglyphheight: int32; + flinespacing: int32; + function internalgetglyph(const abitmap: tmaskedbitmap; + const achar: card32; const arot: real; + const aframe: framety; const acolor: colorty; + const acell: boolean): boolean; + public + constructor create(const afontfile: filenamety; const afontindex: int32; + const aheight: int32); //pixels + destructor destroy(); override; + + function getglyph(const abitmap: tmaskedbitmap; const achar: card32; + const acolor: colorty = cl_text): boolean; + //empty bitmap in case of error, retruns true if ok + function getglyph(const abitmap: tmaskedbitmap; const achar: card32; + const aframe: framety; //padding + const acolor: colorty = cl_text): boolean; + //empty bitmap in case of error, retruns true if ok + function getglyph(const abitmap: tmaskedbitmap; const achar: card32; + const arotation: real; //0.0..1.0 -> 0..360deg CCW + const aframe: framety; //padding + const acolor: colorty = cl_text): boolean; + //empty bitmap in case of error, retruns true if ok + function getcell(const abitmap: tmaskedbitmap; const achar: card32; + const acolor: colorty = cl_text): boolean; + //empty bitmap in case of error, retruns true if ok + function getcell(const abitmap: tmaskedbitmap; const achar: card32; + const aframe: framety; //padding + const acolor: colorty = cl_text): boolean; + //empty bitmap in case of error, retruns true if ok + function getcell(const abitmap: tmaskedbitmap; const achar: card32; + const arotation: real; //0.0..1.0 -> 0..360deg CCW + const aframe: framety; //padding + const acolor: colorty = cl_text): boolean; + //empty bitmap in case of error, retruns true if ok + property height: int32 read fheight write setheight; + property ascent: int32 read fascent; + property descent: int32 read fdescent; + property glyphheight: int32 read fglyphheight; + property linespacing: int32 read flinespacing; + end; + +implementation +uses + msefileutils,sysutils,math; + +{ tftglyphs } + +constructor tftglyphs.create(const afontfile: filenamety; + const afontindex: int32; const aheight: int32); +begin + initializefreetype([]); + if ft_new_face(ftlib,pchar(ansistring(tosysfilepath(afontfile))), + afontindex,fftface) = 0 then begin + fheight:= -1; //force loading of 0 + height:= aheight; + end + else begin + raise exception.create('Can not load font "'+ansistring(afontfile)+'"'); + end; +end; + +procedure tftglyphs.setheight(const avalue: int32); +var + scale: real; +begin + if fheight <> avalue then begin + fheight:= avalue; + if ft_set_pixel_sizes(fftface,0,avalue) <> 0 then begin + raise exception.create('Can not set font height '+inttostr(fheight)); + end; + with fftface^ do begin + scale:= fheight/units_per_em; + fascent64:= round(ascender*scale*64); //for transformation matrix + fascent:= (fascent64 + 32) div 64; //pixels + fdescent:= -round(descender*scale); + fglyphheight:= fascent+fdescent; + flinespacing:= ceil(height*scale); + end; + end; +end; + +destructor tftglyphs.destroy(); +begin + if fftface <> nil then begin + ft_done_face(fftface); + end; + releasefreetype(); +end; + +function tftglyphs.internalgetglyph(const abitmap: tmaskedbitmap; + const achar: card32; const arot: real; const aframe: framety; + const acolor: colorty; const acell: boolean): boolean; +const + numscale = $10000; //for 16.16 ft number +var + so,de: pbyte; + i1,i2,step: int32; + sourcestart: pointty; + sourcesize: sizety; + destsize: sizety; + deststart: pointty; + mat1: ft_matrix; + vec1: ft_vector; + rea1: real; + fcos1,fsin1: real; + cos1,sin1: int32; + charindex1: int32; + centre1: pointty; +label + endlab; +begin + result:= false; + abitmap.beginupdate(); + abitmap.clear(); + charindex1:= ft_get_char_index(fftface,ord(achar)); + if arot <> 0 then begin + rea1:= 2*pi*arot; + fcos1:= cos(rea1); + fsin1:= sin(rea1); + cos1:= round(fcos1*numscale); + sin1:= round(fsin1*numscale); + mat1.xx:= cos1; + mat1.xy:= -sin1; + mat1.yx:= sin1; + mat1.yy:= cos1; + if acell then begin + ft_set_transform(fftface,nil,nil); + if ft_load_glyph(fftface,charindex1,ft_load_default) <> 0 then begin + goto endlab; + end; + with fftface^.glyph^.metrics do begin +// centre1.x:= width div 2 - horibearingx; + centre1.x:= horiadvance div 2; +// centre1.y:= horibearingy - height div 2 ; + centre1.y:= fascent64 - fheight * 32; + vec1.x:= -round(centre1.x*fcos1 - centre1.y*fsin1) + centre1.x; + vec1.y:= -round(centre1.x*fsin1 + centre1.y*fcos1) + centre1.y; + end; + ft_set_transform(fftface,@mat1,@vec1); + end + else begin + ft_set_transform(fftface,@mat1,nil); + end; + end + else begin + ft_set_transform(fftface,nil,nil); + end; + if ft_load_glyph(fftface,charindex1,ft_load_default) = 0 then begin + if ft_render_glyph(fftface^.glyph,ft_render_mode_normal) = 0 then begin + abitmap.options:= abitmap.options + [bmo_masked,bmo_graymask]; + with fftface^.glyph^.bitmap do begin //todo: check bitmap format + if (width > 0) and (rows > 0) then begin + sourcesize.cx:= width; + sourcesize.cy:= rows; + if acell then begin +// destsize.cx:= (fftface^.glyph^.advance.x + 32) div 64; + with fftface^.glyph^.metrics do begin + destsize.cx:= (horiadvance + 32) div 64; + end; + destsize.cy:= fglyphheight; + deststart.x:= aframe.left + fftface^.glyph^.bitmap_left; + deststart.y:= aframe.top + fascent - fftface^.glyph^.bitmap_top; + end + else begin + destsize:= sourcesize; + deststart:= pointty(aframe.topleft); + end; + destsize.cx:= destsize.cx + aframe.left + aframe.right; + destsize.cy:= destsize.cy + aframe.top + aframe.bottom; + if (destsize.cx > 0) and (destsize.cx > 0) and + (deststart.x < destsize.cx) and + (deststart.y < destsize.cy) then begin + abitmap.size:= destsize; + sourcestart.x:= 0; + if deststart.x < 0 then begin + sourcestart.x:= -deststart.x; + sourcesize.cx:= sourcesize.cx + deststart.x; + deststart.x:= 0; + end; + sourcestart.y:= 0; + if deststart.y < 0 then begin + sourcestart.y:= -deststart.y; + sourcesize.cy:= sourcesize.cy + deststart.y; + deststart.y:= 0; + end; + if deststart.x + sourcesize.cx > destsize.cx then begin + sourcesize.cx:= destsize.cx - deststart.x; + end; + if deststart.y + sourcesize.cy > destsize.cy then begin + sourcesize.cy:= destsize.cy - deststart.y; + end; + abitmap.size:= destsize; + abitmap.mask.init(0); + de:= abitmap.mask.scanline[deststart.y] + deststart.x; + abitmap.init(acolor); + if pitch < 0 then begin + so:= buffer+(rows-1-sourcestart.y)*pitch; + end + else begin + so:= buffer+sourcestart.y*pitch; + end; + so:= so + sourcestart.x; + step:= abitmap.mask.scanlinestep; + for i1:= sourcesize.cy - 1 downto 0 do begin + for i2:= sourcesize.cx-1 downto 0 do begin + de[i2]:= so[i2]; + end; + so:= so + pitch; + de:= de + step; + end; + end; + end; + end; + result:= true; + end; + end; +endlab: + abitmap.endupdate(); +end; + +function tftglyphs.getglyph(const abitmap: tmaskedbitmap; const achar: card32; + const acolor: colorty = cl_text): boolean; +begin + result:= internalgetglyph(abitmap,achar,0.0,nullframe,acolor,false); +end; + +function tftglyphs.getglyph(const abitmap: tmaskedbitmap; const achar: card32; + const aframe: framety; + const acolor: colorty = cl_text): boolean; +begin + result:= internalgetglyph(abitmap,achar,0.0,aframe,acolor,false); +end; + +function tftglyphs.getglyph(const abitmap: tmaskedbitmap; const achar: card32; + const arotation: real; const aframe: framety; + const acolor: colorty = cl_text): boolean; +begin + result:= internalgetglyph(abitmap,achar,arotation,aframe,acolor,false); +end; + +function tftglyphs.getcell(const abitmap: tmaskedbitmap; const achar: card32; + const acolor: colorty = cl_text): boolean; +begin + result:= internalgetglyph(abitmap,achar,0.0,nullframe,acolor,true); +end; + +function tftglyphs.getcell(const abitmap: tmaskedbitmap; const achar: card32; + const aframe: framety; + const acolor: colorty = cl_text): boolean; +begin + result:= internalgetglyph(abitmap,achar,0.0,aframe,acolor,true); +end; + +function tftglyphs.getcell(const abitmap: tmaskedbitmap; const achar: card32; + const arotation: real; const aframe: framety; + const acolor: colorty = cl_text): boolean; +begin + result:= internalgetglyph(abitmap,achar,arotation,aframe,acolor,true); +end; + +end. diff --git a/mseide-msegui/lib/common/graphics/msegdi32gdi.pas b/mseide-msegui/lib/common/graphics/msegdi32gdi.pas new file mode 100644 index 0000000..4d6f14e --- /dev/null +++ b/mseide-msegui/lib/common/graphics/msegdi32gdi.pas @@ -0,0 +1,3375 @@ +{ MSEgui Copyright (c) 1999-2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msegdi32gdi; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$goto on} +interface +uses + msegraphics,msetypes,windows,msestrings,mseguiglob; + +procedure init; +procedure deinit; + +function gdi32getgdifuncs: pgdifunctionaty; +//function gdi32getgdinum: integer; +procedure gdi32initdefaultfont; +function gdi32getdefaultfontnames: defaultfontnamesty; +//function gdi32creategc(paintdevice: paintdevicety; const akind: gckindty; +// var gc: gcty; const aprintername: msestring): guierrorty; + +{$ifdef FPC} +function GetNextWindow(hWnd: HWND; uCmd: UINT): HWND; stdcall; + external user32 name 'GetWindow'; +function CreateRectRgnIndirect(const _para1:tRECT):HRGN; stdcall; + external gdi32 name 'CreateRectRgnIndirect'; +function winFillRect(hDC:HDC; const lprc:tRECT; hbr:HBRUSH):longint; stdcall; + external user32 name 'FillRect'; + +type + tTEXTMETRICW = record + tmHeight: Longint; + tmAscent: Longint; + tmDescent: Longint; + tmInternalLeading: Longint; + tmExternalLeading: Longint; + tmAveCharWidth: Longint; + tmMaxCharWidth: Longint; + tmWeight: Longint; + tmOverhang: Longint; + tmDigitizedAspectX: Longint; + tmDigitizedAspectY: Longint; + tmFirstChar: WideChar; + tmLastChar: WideChar; + tmDefaultChar: WideChar; + tmBreakChar: WideChar; + tmItalic: Byte; + tmUnderlined: Byte; + tmStruckOut: Byte; + tmPitchAndFamily: Byte; + tmCharSet: Byte; + end; + tTEXTMETRICA = record + tmHeight: Longint; + tmAscent: Longint; + tmDescent: Longint; + tmInternalLeading: Longint; + tmExternalLeading: Longint; + tmAveCharWidth: Longint; + tmMaxCharWidth: Longint; + tmWeight: Longint; + tmOverhang: Longint; + tmDigitizedAspectX: Longint; + tmDigitizedAspectY: Longint; + tmFirstChar: Char; + tmLastChar: Char; + tmDefaultChar: Char; + tmBreakChar: Char; + tmItalic: Byte; + tmUnderlined: Byte; + tmStruckOut: Byte; + tmPitchAndFamily: Byte; + tmCharSet: Byte; + end; + + tGCPRESULTSW = record + lStructSize : DWORD; + lpOutString : pwidechar; + lpOrder : ^UINT; + lpDx : ^WINT; + lpCaretPos : ^WINT; + lpClass : pwidechar; + lpGlyphs : ^UINT; + nGlyphs : UINT; + nMaxFit : UINT; + end; +{$else} +function GetCharacterPlacementW(DC: HDC; p2: PWideChar; p3, p4: Integer; + var p5: TGCPResultsw; p6: DWORD): DWORD; stdcall; + external gdi32 name 'GetCharacterPlacementW'; +type + WINT = longint; +{$endif} + +const + rasterops2: array[rasteropty] of byte = + ($01,$09,$05,$0d, + $03,$0b,$07,$0f, + $02,$0a,$06,$0e, + $04,$0c,$08,$10); + +{ inverse mono bitmap +source dest + rop2 $01 $02 $03 $04 $05 $06 $07 $08 $09 $0a $0b $0c $0d $0e $0f $10 + 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 + 0 1 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 + 1 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 + 1 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 + rop3 $ff $ee $dd $cc $bb $aa $99 $88 $77 $66 $55 $44 $33 $22 $11 $00 +} + + inverserops2: array[rasteropty] of byte = + //for 1->foreground in monochromebitmaps + //rop_clear,rop_and,rop_andnot,rop_copy, + ($10, $0f, $0e, $0d, + //rop_notand,rop_nop,rop_xor,rop_or, + $0c, $0b, $0a, $09, + //rop_nor,rop_notxor,rop_not,rop_ornot, + $08, $07, $06, $05, + //rop_notcopy,rop_notor,rop_nand,rop_set); + $04, $03, $02, $01); + + firstrasterops2: array[rasteropty] of byte = //backgroudcolor = $ffffff, + ($09,$09,$09,$09, //textcolor = $000000, and + $09,$09,$09,$09, + $09,$09,$09,$09, + $09,$09,$09,$09); + + secondrasterops2: array[rasteropty] of byte = //colorbackground = $000000, + ($0f,$0f,$0f,$0f, //textcolor = $ffffff, or + $0f,$0f,$0f,$0f, + $0f,$0f,$0f,$0f, + $0f,$0f,$0f,$0f); + +type + rop3tabty = array[rasteropty] of longword; + prop3tabty = ^rop3tabty; +const +{ inverse mono bitmap +P S D clear,and,andnot,copy,notand,nop,xor,or, +x 1 1 1 0 1 0 1 0 1 0 +x 1 0 1 1 0 0 1 1 0 0 +x 0 1 1 1 1 1 0 0 0 0 +x 0 0 1 1 1 1 1 1 1 1 + $f $e $d $c $b $a $9 $8 +P S D nor,notxor,not,ornot,notcopy,notor,nand,set +x 1 1 1 0 1 0 1 0 1 0 +x 1 0 1 1 0 0 1 1 0 0 +x 0 1 1 1 1 1 0 0 0 0 +x 0 0 0 0 0 0 0 0 0 0 + $7 $6 $5 $4 $3 $2 $1 $0 +} + inverserops3: rop3tabty = + //for 1->foreground in monochromebitmaps + // $ff $ee $dd $cc + ($ff0062,$ee0086,$dd0228,$cc0020, + // $bb $aa $99 $88 + $bb0226,$aa0029,$990066,$8800c6, + // $77 $66 $55 $44 + $7700e6,$660046,$550009,$440328, + // $33 $22 $11 $00 + $330008,$220326,$1100a6,$000042); + + rasterops3: rop3tabty = + ($000042,$8800c6,$440328,$cc0020, + $220326,$aa0029,$660046,$ee0086, + $1100a6,$990066,$550009,$dd0228, + $330008,$bb0226,$7700e6,$ff0062); + +{ inverse mono bitmap +P S D clear,and,andnot,copy,notand,nop,xor, or, +1 x 1 1 0 1 0 1 0 1 0 +1 x 0 1 1 0 0 1 1 0 0 +1 x 1 1 0 1 0 1 0 1 0 +1 x 0 1 1 0 0 1 1 0 0 +0 x 1 1 1 1 1 0 0 0 0 +0 x 0 1 1 1 1 1 1 1 1 +0 x 1 1 1 1 1 0 0 0 0 +0 x 0 1 1 1 1 1 1 1 1 + $ff $fa $f5 $f0 $af $aa $a5 $a0 +P S D nor,notxor,not,ornot,notcopy,notor,nand,set +1 x 1 1 0 1 0 1 0 1 0 +1 x 0 1 1 0 0 1 1 0 0 +1 x 1 1 0 1 0 1 0 1 0 +1 x 0 1 1 0 0 1 1 0 0 +0 x 1 1 1 1 1 0 0 0 0 +0 x 0 0 0 0 0 0 0 0 0 +0 x 1 1 1 1 1 0 0 0 0 +0 x 0 0 0 0 0 0 0 0 0 + $5f $5a $55 $50 $0f $0a $05 $00 +} + inversepatrops3: rop3tabty = + // $ff $fa $f5 $f0 + ($ff0062,$fa0089,$f50225,$f00021, + // $af $aa $a5 $a0 + $af0229,$aa0029,$a50065,$a000c9, + // $5f $5a $55 $50 + $5f00e9,$5a0049,$550009,$500325, + // $0f $0a $05 $00 + $0f0001,$0a0329,$0500a9,$000042); + + + + patrops3: rop3tabty = + ($000042,$a000c9,$500325,$f00021, + $0a0329,$aa0029,$5a0049,$fa0089, + $0500a9,$a50065,$550009,$f50225, + $0f0001,$af0229,$5f00e2,$ff0062); + +implementation +uses + mseguiintf,msegraphutils,msesysintf1,sysutils,msegdiplus; + +type + shapety = (fs_copyarea,fs_rect,fs_ellipse,fs_arc,fs_polygon); + + gcflagty = (gcf_backgroundbrushvalid, + gcf_colorbrushvalid,gcf_patternbrushvalid, + gcf_rasterop, + gcf_selectforegroundbrush,gcf_selectbackgroundbrush, + gcf_foregroundpenvalid, + gcf_selectforegroundpen,gcf_selectnullpen,gcf_selectnullbrush, + gcf_ispatternpen,gcf_isopaquedashpen,gcf_smooth, + gcf_gpregionvalid, + gcf_gpbrushcolorvalid,gcf_gpbrushoriginvalid, + gcf_gpmonochromebrush, + gcf_gppencolorvalid,gcf_gppenvalid,gcf_gppenmode,gcf_gpshiftpen, + {gcf_gpsolidfillvalid,gcf_gpspenvalid,} + gcf_last = 31); + //-> longword + gcflagsty = set of gcflagty; + pgcflagsty = ^gcflagsty; +type + monopalettety = record + Flags: UINT; + Count: UINT; + val0: ARGB; + val1: ARGB; + end; + + graypalettety = record + Flags: UINT; + Count: UINT; + values: array[byte] of ARGB; + end; + gdigraypalettety = record + palVersion: WORD; + palNumEntries: WORD; + values: array[byte] of PALETTEENTRY; + end; + pgdigraypalettety = ^gdigraypalettety; + + win32gcdty = record + flags: gcflagsty; + gpflags: gcflagsty; + backgroundcol,foregroundcol: longword; + backgroundbrush: hbrush; + colorbrush: hbrush; + patternbrush: hbrush; + foregroundpen: hpen; + kind: gckindty; + bru: pixmapty; + rop: rasteropty; + brushorg: pointty; + peninfo: lineinfoty; + gccliporigin: pointty; + selectedpen: hpen; + selectedbrush: hbrush; + secondpen: hpen; +// graypal: hpalette; + gpgraphic: pgpgraphics; + gpregion: pgpregion; + gpsolidfill: pgpsolidfill; + gptexture: pgptexture; + gppalettedata: monopalettety; + gptextureimage: pgpbitmap; + gpbrush: pgpbrush; + gppen: pgppen; + end; + {$if sizeof(win32gcdty) > sizeof(gcpty)} {$error 'buffer overflow'}{$ifend} + win32gcty = record + case integer of + 0: (d: win32gcdty;); + 1: (_bufferspace: gcpty;); + end; + pwin32gcty = ^win32gcty; + + charwidthsty = array[0..255] of integer; + pcharwidthsty = ^charwidthsty; + win32fontdataty = record + charwidths: pcharwidthsty; + overhang: integer; + xwidth: integer; + local: array[{$ifdef cpu64}2{$else}3{$endif}..15] of pointer; //plattform dependent + end; + +type + tsimplebitmap1 = class(tsimplebitmap); + tcanvas1 = class(tcanvas); + +{ +const + graypalette: graypalettety = ( + flags: 0; + count: 256; + values: ( +$00000000,$00010101,$00020202,$00030303,$00040404,$00050505,$00060606,$00070707, +$00080808,$00090909,$000a0a0a,$000b0b0b,$000c0c0c,$000d0d0d,$000e0e0e,$000f0f0f, +$00101010,$00111111,$00121212,$00131313,$00141414,$00151515,$00161616,$00171717, +$00181818,$00191919,$001a1a1a,$001b1b1b,$001c1c1c,$001d1d1d,$001e1e1e,$001f1f1f, +$00202020,$00212121,$00222222,$00232323,$00242424,$00252525,$00262626,$00272727, +$00282828,$00292929,$002a2a2a,$002b2b2b,$002c2c2c,$002d2d2d,$002e2e2e,$002f2f2f, +$00303030,$00313131,$00323232,$00333333,$00343434,$00353535,$00363636,$00373737, +$00383838,$00393939,$003a3a3a,$003b3b3b,$003c3c3c,$003d3d3d,$003e3e3e,$003f3f3f, +$00404040,$00414141,$00424242,$00434343,$00444444,$00454545,$00464646,$00474747, +$00484848,$00494949,$004a4a4a,$004b4b4b,$004c4c4c,$004d4d4d,$004e4e4e,$004f4f4f, +$00505050,$00515151,$00525252,$00535353,$00545454,$00555555,$00565656,$00575757, +$00585858,$00595959,$005a5a5a,$005b5b5b,$005c5c5c,$005d5d5d,$005e5e5e,$005f5f5f, +$00606060,$00616161,$00626262,$00636363,$00646464,$00656565,$00666666,$00676767, +$00686868,$00696969,$006a6a6a,$006b6b6b,$006c6c6c,$006d6d6d,$006e6e6e,$006f6f6f, +$00707070,$00717171,$00727272,$00737373,$00747474,$00757575,$00767676,$00777777, +$00787878,$00797979,$007a7a7a,$007b7b7b,$007c7c7c,$007d7d7d,$007e7e7e,$007f7f7f, +$00808080,$00818181,$00828282,$00838383,$00848484,$00858585,$00868686,$00878787, +$00888888,$00898989,$008a8a8a,$008b8b8b,$008c8c8c,$008d8d8d,$008e8e8e,$008f8f8f, +$00909090,$00919191,$00929292,$00939393,$00949494,$00959595,$00969696,$00979797, +$00989898,$00999999,$009a9a9a,$009b9b9b,$009c9c9c,$009d9d9d,$009e9e9e,$009f9f9f, +$00a0a0a0,$00a1a1a1,$00a2a2a2,$00a3a3a3,$00a4a4a4,$00a5a5a5,$00a6a6a6,$00a7a7a7, +$00a8a8a8,$00a9a9a9,$00aaaaaa,$00ababab,$00acacac,$00adadad,$00aeaeae,$00afafaf, +$00b0b0b0,$00b1b1b1,$00b2b2b2,$00b3b3b3,$00b4b4b4,$00b5b5b5,$00b6b6b6,$00b7b7b7, +$00b8b8b8,$00b9b9b9,$00bababa,$00bbbbbb,$00bcbcbc,$00bdbdbd,$00bebebe,$00bfbfbf, +$00c0c0c0,$00c1c1c1,$00c2c2c2,$00c3c3c3,$00c4c4c4,$00c5c5c5,$00c6c6c6,$00c7c7c7, +$00c8c8c8,$00c9c9c9,$00cacaca,$00cbcbcb,$00cccccc,$00cdcdcd,$00cecece,$00cfcfcf, +$00d0d0d0,$00d1d1d1,$00d2d2d2,$00d3d3d3,$00d4d4d4,$00d5d5d5,$00d6d6d6,$00d7d7d7, +$00d8d8d8,$00d9d9d9,$00dadada,$00dbdbdb,$00dcdcdc,$00dddddd,$00dedede,$00dfdfdf, +$00e0e0e0,$00e1e1e1,$00e2e2e2,$00e3e3e3,$00e4e4e4,$00e5e5e5,$00e6e6e6,$00e7e7e7, +$00e8e8e8,$00e9e9e9,$00eaeaea,$00ebebeb,$00ececec,$00ededed,$00eeeeee,$00efefef, +$00f0f0f0,$00f1f1f1,$00f2f2f2,$00f3f3f3,$00f4f4f4,$00f5f5f5,$00f6f6f6,$00f7f7f7, +$00f8f8f8,$00f9f9f9,$00fafafa,$00fbfbfb,$00fcfcfc,$00fdfdfd,$00fefefe,$00ffffff + ); + ); +} +var + nullpen: hpen; + nullbrush: hbrush; +// graypalette: hpalette; + + capstyles: array[capstylety] of longword = + (ps_endcap_flat,ps_endcap_round,ps_endcap_square); + joinstyles: array[joinstylety] of longword = + (ps_join_miter,ps_join_round,ps_join_bevel); + +const + highresfontshift = 6; //64 + highresfontfakt = 1 shl highresfontshift; + highresfontmask = highresfontfakt - 1; + CLEARTYPE_QUALITY = ANTIALIASED_QUALITY+1; + + defaultfontname = 'Tahoma'; +// defaultfontname = 'MS Sans Serif'; + defaultfontnames: defaultfontnamesty = + //stf_default stf_empty stf_unicode stf_menu stf_message stf_hint stf_report + (defaultfontname, '', '', '', '', '', 'Arial', + //stf_proportional stf_fixed, + defaultfontname, 'Courier New', + //stf_helvetica stf_roman stf_courier + 'Arial', 'Times New Roman', 'Courier New'); + +function gdi32getdefaultfontnames: defaultfontnamesty; +begin + result:= defaultfontnames; +end; + +procedure gdi_createpixmap(var drawinfo: drawinfoty); //gdifunc +begin + with drawinfo.createpixmap do begin + pixmap:= gui_createpixmap(size,0,kind,copyfrom); + end; +end; + +procedure gdi_pixmaptoimage(var drawinfo: drawinfoty); //gdifunc +begin + with drawinfo.pixmapimage do begin + gui_pixmaptoimage(pixmap,image,drawinfo.gc.handle); + end; +end; + +procedure gdi_imagetopixmap(var drawinfo: drawinfoty); //gdifunc +begin + with drawinfo.pixmapimage do begin + error:= gui_imagetopixmap(image,pixmap,drawinfo.gc.handle); + end; +end; + +//function gdi32creategc(paintdevice: paintdevicety; const akind: gckindty; +// var gc: gcty; const aprintername: msestring): guierrorty; +procedure gdi_creategc(var drawinfo: drawinfoty); +var + wrect1: trect; +// palpo: pgdigraypalettety; +// by1: byte; +begin + with drawinfo,creategc do begin + gcpo^.gdifuncs:= gui_getgdifuncs; + with win32gcty(gcpo^.platformdata) do begin + d.kind:= kind; +// d.graypal:= 0; + end; + case kind of + gck_pixmap: begin + error:= gde_creategc; + gcpo^.handle:= createcompatibledc(0); + if gcpo^.handle <> 0 then begin + deleteobject(selectobject(gcpo^.handle,paintdevice)); + { + if gcpo^.kind = bmk_gray then begin + if graypalette = 0 then begin + palpo:= pointer(gui_allocimagemem((sizeof(gdigraypalettety)+3) div 4)); + with palpo^ do begin + palversion:= $0300; + palnumentries:= length(values); + for by1:= 0 to high(values) do begin + with values[by1] do begin + pered:= by1; + pegreen:= by1; + peblue:= by1; + peflags:= 0; + end; + end; + end; + graypalette:= createpalette(logpalette(pointer(palpo)^)); + gui_freeimagemem(pointer(palpo)); + end; + end; + } + end; + end; + gck_printer: begin + error:= gde_createprintergc; + gcpo^.handle:= createdc('WINSPOOL',pansichar(ansistring(printernamepo^)),nil,nil); + setmapperflags(gcpo^.handle,1); //match font-device aspectratio + end; + gck_metafile: begin + error:= gde_createmetafilegc; + wrect1.left:= 0; + wrect1.top:= 0; + wrect1.right:= round((gcpo^.paintdevicesize.cx*100)/gcpo^.ppmm); + wrect1.bottom:= round((gcpo^.paintdevicesize.cy*100)/gcpo^.ppmm); + if printernamepo^ = '' then begin + gcpo^.handle:= createenhmetafilew(gcpo^.refgc,nil,@wrect1,nil); //memory + end + else begin + gcpo^.handle:= createenhmetafilew(gcpo^.refgc,pmsechar(printernamepo^),@wrect1,nil); + //file + end; + setmapperflags(gcpo^.handle,1); //match font-device aspectratio + end; + else begin + error:= gde_creategc; + gcpo^.handle:= getdc(paintdevice); + end; + end; + if gcpo^.handle <> 0 then begin + {$ifdef mse_debuggdi} + inc(gccount); + {$endif} + settextalign(gcpo^.handle,ta_left or ta_baseline or ta_noupdatecp); + setbkmode(gcpo^.handle,transparent); + setmapmode(gcpo^.handle,mm_text); + error:= gde_ok; + end; + end; +end; + +procedure transformpoints(var drawinfo: drawinfoty; const aclose: boolean); +var + po1: ppointty; + po2: ppointty; + int1: integer; +begin + with drawinfo.points do begin + int1:= count; + if aclose then begin + inc(int1); + end; + allocbuffer(drawinfo.buffer,int1*sizeof(pointty)); + po1:= points; + po2:= drawinfo.buffer.buffer; + int1:= count; + with drawinfo.origin do begin + while int1 > 0 do begin + po2^.x:= po1^.x + x; + po2^.y:= po1^.y + y; + inc(po1); + inc(po2); + dec(int1); + end; + end; + if aclose then begin + move(drawinfo.buffer.buffer^,(pchar(drawinfo.buffer.buffer)+ + count*sizeof(pointty))^,sizeof(pointty)); + end; + end; +end; + +procedure adjustlineend(po: ppointty); //solve lineto lastpixel problem +var + po1: ppoint; + dx,dy,dist: integer; + +begin + po1:= ppoint(pchar(po)-sizeof(pointty)); + dx:= po^.x - po1^.x; + dy:= po^.y - po1^.y; + dist:= (abs(dx) + abs(dy)) div 2; + if dx < 0 then begin + if dx + dist <= 0 then begin + dec(po^.x); + end; + end + else begin + if dx >= dist then begin + inc(po^.x); + end; + end; + if dy < 0 then begin + if dy + dist <= 0 then begin + dec(po^.y); + end; + end + else begin + if dy >= dist then begin + inc(po^.y); + end; + end; +end; + +procedure transformrect(var drawinfo: drawinfoty); +begin + allocbuffer(drawinfo.buffer,sizeof(trect)); + with drawinfo,prect(buffer.buffer)^,rect do begin + Left:= rect^.x + origin.x; + right:= Left + rect^.cx; + top:= rect^.y + origin.y; + bottom:= top + rect^.cy; + end; +end; + +procedure offsetrect(var drawinfo: drawinfoty); +begin + allocbuffer(drawinfo.buffer,sizeof(rectty)); + with drawinfo,prectty(buffer.buffer)^,rect do begin + x:= rect^.x + origin.x; + cx:= rect^.cx; + y:= rect^.y + origin.y; + cy:= rect^.cy; + end; +end; + +procedure transformellipseinfo(var drawinfo: drawinfoty; const fill: boolean); +var + int1: integer; +begin + allocbuffer(drawinfo.buffer,sizeof(trect)); + int1:= 1; + if fill then begin + int1:= 2; + end; + with drawinfo,prect(buffer.buffer)^,rect do begin + Left:= rect^.x + origin.x - drawinfo.rect.rect^.cx div 2; + right:= Left + rect^.cx+int1; + top:= rect^.y + origin.y - drawinfo.rect.rect^.cy div 2; + bottom:= top + rect^.cy+int1; + end; +end; + +procedure updateopaquemode(var gc: gcty); +begin + with gc,win32gcty(platformdata).d do begin + settextcolor(handle,foregroundcol); + if df_opaque in drawingflags then begin + setbkmode(handle,opaque); + setbkcolor(handle,backgroundcol); + end + else begin + setbkmode(handle,transparent); + end; + end; +end; + +procedure checkgc2(var gc: gcty); + //second pass for transparent patternpen +begin + with gc,win32gcty(platformdata).d do begin + if gcf_isopaquedashpen in flags then begin + selectobject(handle,secondpen); + deleteobject(selectedpen); + selectedpen:= secondpen; + foregroundpen:= secondpen; + exclude(flags,gcf_foregroundpenvalid); + end + else begin + setbkcolor(handle,$000000); + settextcolor(handle,foregroundcol); + setrop2(handle,secondrasterops2[rop]); + exclude(flags,gcf_rasterop); + end; + end; +end; + +function checkgc(var gc: gcty; aflags: gcflagsty): boolean; + //true if second drawing needed +var + flags1: gcflagsty; + brushinfo: logbrush; + adashes: array[0..high(dashesstringty)] of longword; + int1: integer; + po1: pointer; + dashlen: integer; + astyle: longword; + awidth: integer; + +begin + result:= false; + with gc,win32gcty(platformdata).d do begin + exclude(flags,gcf_isopaquedashpen); + if (df_brush in drawingflags) xor (gcf_ispatternpen in flags) then begin + exclude(flags,gcf_foregroundpenvalid); + end; + if not (gcf_rasterop in flags) and + ([gcf_selectforegroundbrush,gcf_selectforegroundpen] * aflags <> + [gcf_selectforegroundbrush,gcf_selectforegroundpen]) then begin + exclude(flags,gcf_selectforegroundbrush); //refresh rasterop + exclude(flags,gcf_selectforegroundpen); + if df_canvasismonochrome in drawingflags then begin + setrop2(handle,inverserops2[rop]); + end + else begin + setrop2(handle,rasterops2[rop]); + end; + include(flags,gcf_rasterop); + end; + flags1:= gcflagsty((longword(aflags) xor longword(flags)) and longword(aflags)); + //needed objects + if df_brush in drawingflags then begin + exclude(flags1,gcf_colorbrushvalid); + end + else begin + exclude(flags1,gcf_patternbrushvalid); + end; + if gcf_backgroundbrushvalid in flags1 then begin + if backgroundbrush <> 0 then begin + if backgroundbrush = selectedbrush then begin + selectobject(handle,nullbrush); + end; + deleteobject(backgroundbrush); + end; + backgroundbrush:= createsolidbrush(backgroundcol); + end; + if gcf_colorbrushvalid in flags1 then begin + if colorbrush <> 0 then begin + if colorbrush = selectedbrush then begin + selectobject(handle,nullbrush); + end; + deleteobject(colorbrush); + end; + colorbrush:= createsolidbrush(foregroundcol); + end; + if gcf_patternbrushvalid in flags1 then begin + if patternbrush <> 0 then begin + if patternbrush = selectedbrush then begin + selectobject(handle,nullbrush); + end; + deleteobject(patternbrush); + end; + patternbrush:= createpatternbrush(bru); + end; + if gcf_foregroundpenvalid in flags1 then begin + if foregroundpen <> 0 then begin + if selectedpen = foregroundpen then begin + selectobject(handle,nullpen); + end; + deleteobject(foregroundpen); + end; + //todo: emulations for win95, opaquemode + with peninfo do begin + po1:= nil; + dashlen:= length(dashes); + if dashlen > 0 then begin + if df_opaque in drawingflags then begin + include(flags,gcf_isopaquedashpen); + result:= true; + end; + if iswin95 then begin + astyle:= ps_dot; + end + else begin + if dashes = #1#1 then begin + astyle:= ps_alternate or ps_cosmetic; + dashlen:= 0; + end + else begin + for int1:= 1 to length(dashes) do begin + adashes[int1-1]:= ord(dashes[int1]){ div 3}; + end; + po1:= @adashes; + astyle:= ps_userstyle or ps_geometric; + end; + end; + end + else begin + if (df_brush in drawingflags) or (width > 0) then begin + astyle:= ps_geometric; + end + else begin + astyle:= ps_cosmetic; + end; + end; + if astyle and ps_geometric <> 0 then begin + astyle:= astyle or capstyles[capstyle] or joinstyles[joinstyle]; + end; + with brushinfo do begin + if df_brush in drawingflags then begin + lbStyle:= bs_pattern; + lbhatch:= bru; + include(flags,gcf_ispatternpen); + end + else begin + lbStyle:= bs_solid; + lbColor:= foregroundcol; + exclude(flags,gcf_ispatternpen); + end; + end; + if width = 0 then begin + awidth:= 1 + end + else begin + awidth:= width + end; + foregroundpen:= extcreatepen(astyle,awidth,brushinfo, + dashlen,po1); + if gcf_isopaquedashpen in flags then begin + secondpen:= foregroundpen; + with brushinfo do begin + lbStyle:= bs_solid; + lbColor:= backgroundcol; + end; + foregroundpen:= extcreatepen(astyle and + not(ps_userstyle or ps_dot or ps_alternate),awidth,brushinfo, + 0,nil); + end; + end; + end; + if gcf_selectbackgroundbrush in aflags then begin + selectobject(gc.handle,backgroundbrush); + selectedbrush:= backgroundbrush; + end; + if gcf_selectforegroundbrush in aflags then begin + if df_brush in drawingflags then begin + selectobject(gc.handle,patternbrush); + selectedbrush:= patternbrush; + end + else begin + selectobject(gc.handle,colorbrush); + selectedbrush:= colorbrush; + end; + end; + if gcf_selectforegroundpen in aflags then begin + if (gcf_ispatternpen in flags) and + (drawingflags * [df_monochrome,df_opaque] = [df_monochrome]) then begin + result:= true; + setbkcolor(handle,$ffffff); + settextcolor(handle,$000000); + setrop2(handle,firstrasterops2[rop]); + end + else begin + updateopaquemode(gc); + end; + selectobject(gc.handle,foregroundpen); + selectedpen:= foregroundpen; + end; + if gcf_selectnullpen in aflags then begin + selectobject(gc.handle,nullpen); + selectedpen:= nullpen; + end; + if gcf_selectnullbrush in aflags then begin + selectobject(gc.handle,nullbrush); + selectedbrush:= nullbrush; + end; + flags:= flags + flags1; + end; +end; + +procedure deletepgtexture(var gc: gcty); +begin + with win32gcty(gc.platformdata).d do begin + if gptexture <> nil then begin + gdipdeletebrush(pgpbrush(gptexture)); + gptexture:= nil; + end; + if gptextureimage <> nil then begin + gdipdisposeimage(pgpimage(gptextureimage)); +// gdipfree(gptextureimage); + gptextureimage:= nil; + end; + gpflags:= gpflags - + [gcf_gpmonochromebrush,gcf_patternbrushvalid, + gcf_gpbrushoriginvalid,gcf_gpbrushcolorvalid]; + end; +end; + +const + alphamax = $ff000000; + +function gpcolor(const apixel: pixelty): pixelty; inline; +begin + result:= apixel and $0000ff00 or + (apixel and $00ff0000 shr 16) or + (apixel and $000000ff shl 16) or alphamax; +end; + +//todo: optimize, update invalid values only + +const + gpcaps: array[capstylety] of gplinecap = + (linecapflat,linecapround,linecapsquare); + gpdashcaps: array[capstylety] of gpdashcap = + (dashcapflat,dashcapround,dashcaptriangle); + gpjoins: array[joinstylety] of gplinejoin = + (linejoinmiterclipped,linejoinround,linejoinbevel); +const + gpstartflags = [gcf_patternbrushvalid,gcf_gpbrushoriginvalid,gcf_gpregionvalid, + gcf_gpmonochromebrush, + gcf_gpbrushcolorvalid,gcf_gppencolorvalid,gcf_gppenvalid]; +// gcfgpflags = [gcf_gppenmode]; + gplineflags = [gcf_selectforegroundpen]; + gpfillflags = [gcf_selectforegroundbrush]; + +procedure checkgpgc(var gc: gcty; aflags: gcflagsty); + + function checkbrushorcolor: boolean; //true if changed + procedure updatepalette; + begin + with gc,win32gcty(platformdata).d do begin + if gcf_gpmonochromebrush in gpflags then begin + with gppalettedata do begin + longword(val0):= gpcolor(foregroundcol) or $ff000000; + if df_opaque in drawingflags then begin + longword(val1):= gpcolor(backgroundcol) or $ff000000; + flags:= 0; + end + else begin + longword(val1):= backgroundcol; + flags:= PaletteFlagsHasAlpha; + end; + end; + gdipsetimagepalette(pgpimage(gptextureimage),@gppalettedata); + end; + end; + end; //checkgpgc +var + newtexture: boolean; + begin + result:= false; + with gc,win32gcty(platformdata).d do begin + newtexture:= false; + if df_brush in drawingflags then begin + if not (gcf_patternbrushvalid in gpflags) then begin + if gdipcreatebitmapfromhbitmap(bru,0,@gptextureimage) = ok then begin + if df_monochrome in drawingflags then begin + include(gpflags,gcf_gpmonochromebrush); + end; + updatepalette; + gdipcreatetexture(pgpimage(gptextureimage),wrapmodetile,@gptexture); + end; + include(gpflags,gcf_patternbrushvalid); + newtexture:= true; + result:= true; + end; + if gptexture <> nil then begin + gpbrush:= pgpbrush(gptexture); + if not (gcf_gpbrushoriginvalid in gpflags) then begin + gdipresettexturetransform(gptexture); + gdiptranslatetexturetransform(gptexture,brushorg.x,brushorg.y, + matrixorderprepend); + include(gpflags,gcf_gpbrushoriginvalid); + result:= true; + end; + end + else begin + gpbrush:= pgpbrush(gpsolidfill); //error + end; + end + else begin + gpbrush:= pgpbrush(gpsolidfill); + end; + if not (gcf_gpbrushcolorvalid in gpflags) then begin + result:= true; + gdipsetsolidfillcolor(gpsolidfill,gpcolor(foregroundcol)); + if not newtexture then begin + updatepalette; + if gpbrush = pointer(gptexture) then begin + gdipdeletebrush(gpbrush); + gdipcreatetexture(pgpimage(gptextureimage), + wrapmodetile,@gptexture); + gdiptranslatetexturetransform(gptexture,brushorg.x,brushorg.y, + matrixorderprepend); + gpbrush:= pgpbrush(gptexture); + end; + end; + include(gpflags,gcf_gpbrushcolorvalid); + end; + end; + end; //checkbrushorcolor + +var + cap1: gplinecap; + dash1: array[0..high(dashesstringty)] of gpreal; + int1: integer; + dasca: real; + reg: hrgn; +begin + with gc,win32gcty(platformdata).d do begin + if not (gcf_gpregionvalid in gpflags) then begin + if gpregion <> nil then begin + gdipdeleteregion(gpregion); + end; + reg:= createrectrgn(0,0,0,0); + if getcliprgn(handle,reg) = 0 then begin + gdipresetclip(gpgraphic); + gpregion:= nil; + end + else begin + GdipCreateRegionHrgn(reg,@gpregion); + gdipsetclipregion(gpgraphic,gpregion,combinemodereplace); + end; + include(gpflags,gcf_gpregionvalid); + deleteobject(reg); + end; + if gcf_selectforegroundpen in aflags then begin + if checkbrushorcolor then begin + if df_brush in drawingflags then begin + gdipsetpenbrushfill(gppen,gpbrush); + end + else begin + gdipsetpencolor(gppen,gpcolor(foregroundcol)); + end; + end; + if not (gcf_gppenvalid in gpflags) then begin + exclude(gpflags,gcf_gppenmode); + if df_brush in drawingflags then begin + gdipsetpenbrushfill(gppen,gpbrush); + end + else begin + gdipsetpencolor(gppen,gpcolor(foregroundcol)); + end; + exclude(gpflags,gcf_gpshiftpen); + if peninfo.width = 0 then begin + gdipsetpenwidth(gppen,1); + dasca:= 1; + end + else begin + if not odd(peninfo.width) then begin + include(gpflags,gcf_gpshiftpen); + end; + gdipsetpenwidth(gppen,peninfo.width); + dasca:= 1/peninfo.width; + end; + cap1:= gpcaps[peninfo.capstyle]; + gdipsetpenlinecap197819(gppen,cap1,cap1, + gpdashcaps[peninfo.capstyle]); + gdipsetpenlinejoin(gppen,gpjoins[peninfo.joinstyle]); + if length(peninfo.dashes) > 0 then begin + for int1:= 1 to length(peninfo.dashes) do begin + dash1[int1-1]:= ord(peninfo.dashes[int1])*dasca; + end; + gdipsetpendasharray(gppen,@dash1,length(peninfo.dashes)); + gdipsetpendashoffset(gppen,0.5*dasca); + end + else begin + gdipsetpendashstyle(gppen,dashstylesolid); + end; + include(gpflags,gcf_gppenvalid); + end; + end; + if gcf_selectforegroundbrush in aflags then begin + checkbrushorcolor; + end; + if (gcf_selectforegroundpen in aflags) xor + (gcf_gppenmode in gpflags) then begin + if (gcf_selectforegroundpen in aflags) then begin + if gcf_gpshiftpen in gpflags then begin + gdipsetpixeloffsetmode(gpgraphic,pixeloffsetmodehalf); + end + else begin + gdipsetpixeloffsetmode(gpgraphic,pixeloffsetmodenone); + end; +// gdipsetpixeloffsetmode(gpgraphic,pixeloffsetmodehalf); + include(gpflags,gcf_gppenmode); + end + else begin + gdipsetpixeloffsetmode(gpgraphic,pixeloffsetmodehalf); + exclude(gpflags,gcf_gppenmode); + end; +{ + gdipresetworldtransform(gpgraphic); + if gcf_gppenmode in aflags then begin + gdiptranslateworldtransform(gpgraphic,0.5,0.5,matrixorderprepend); + include(gpflags,gcf_gppenmode); + end + else begin + exclude(gpflags,gcf_gppenmode); + end; +} + end; + end; +end; + +function createregion: regionty; overload; +begin +{$ifdef mse_debuggdi} + inc(regioncount); +{$endif} + result:= createrectrgnindirect(trect(nullrect)); +end; + +function createregion(var rect: rectty; const gc: gcty): regionty; overload; +var + rect1: rectty; +begin +{$ifdef mse_debuggdi} + inc(regioncount); +{$endif} + if win32gcty(gc.platformdata).d.kind = gck_printer then begin + rect1:= rect; + recttowinrect(rect1); + lptodp(gc.handle, + {$ifdef FPC}lppoint(@{$endif}rect1{$ifdef FPC}){$endif},2); + result:= createrectrgnindirect(trect(rect1)); + end + else begin + recttowinrect(rect); + result:= createrectrgnindirect(trect(rect)); + winrecttorect(rect); + end; +end; + +procedure gdi_createemptyregion(var drawinfo: drawinfoty); +begin + with drawinfo.regionoperation do begin + dest:= createregion; + end; +end; + +procedure gdi_setcliporigin(var drawinfo: drawinfoty); +var + reg1: hrgn; + delta: pointty; +begin + with drawinfo.gc,win32gcty(platformdata).d do begin + delta:= subpoint(cliporigin,gccliporigin); + if (delta.x <> 0) or (delta.y <> 0) then begin + reg1:= createregion; + if getcliprgn(handle,reg1) > 0 then begin + offsetrgn(reg1,delta.x,delta.y); + selectcliprgn(handle,reg1); + end; + deleteobject(reg1); +{$ifdef mse_debuggdi} + dec(regioncount); +{$endif} + end; + gccliporigin:= cliporigin; + end; +// gdierror(gde_notimplemented,'setcliporigin'); +end; + +procedure gdi_createrectregion(var drawinfo: drawinfoty); +begin + with drawinfo.regionoperation do begin + dest:= createregion(rect,drawinfo.gc); + end; +end; + +procedure gdi_createrectsregion(var drawinfo: drawinfoty); +var + reg1: hrgn; + int1: integer; + rect1: rectty; +begin + with drawinfo.regionoperation do begin + dest:= createregion; + if rectscount > 0 then begin + if win32gcty(drawinfo.gc.platformdata).d.kind = gck_printer then begin + for int1:= 0 to rectscount - 1 do begin + rect1:= rectspo^[int1]; + recttowinrect(rect1); + lptodp(drawinfo.gc.handle, + {$ifdef FPC}lppoint(@{$endif}rect1{$ifdef FPC}){$endif},2); + reg1:= createrectrgnindirect(trect(rect1)); + combinergn(dest,dest,reg1,rgn_or); + deleteobject(reg1); + end; + end + else begin + recttowinrect(@rectspo^[0],rectscount); + for int1:= 0 to rectscount - 1 do begin + reg1:= createrectrgnindirect(trect(rectspo^[int1])); + combinergn(dest,dest,reg1,rgn_or); + deleteobject(reg1); + end; + winrecttorect(@rectspo^[0],rectscount); + end; + end; + end; +end; + +procedure gdi_destroyregion(var drawinfo: drawinfoty); +begin + with drawinfo.regionoperation do begin + if source <> 0 then begin +{$ifdef mse_debuggdi} + dec(regioncount); +{$endif} + deleteobject(source); + end; + end; +end; + +procedure gdi_regionisempty(var drawinfo: drawinfoty); +var + rect1: trect; +begin + with drawinfo.regionoperation do begin + if getrgnbox(source,rect1) = nullregion then begin + dest:= 1; + end + else begin + dest:= 0; + end; + end; +end; + +procedure gdi_regionclipbox(var drawinfo: drawinfoty); +begin + with drawinfo.regionoperation do begin + getrgnbox(source,trect(rect)); + if win32gcty(drawinfo.gc.platformdata).d.kind = gck_printer then begin + dptolp(drawinfo.gc.handle, + {$ifdef FPC}lppoint(@{$endif}rect{$ifdef FPC}){$endif},2); + end; + winrecttorect(rect); + end; +end; + +procedure gdi_copyregion(var drawinfo: drawinfoty); +begin + with drawinfo.regionoperation do begin + if source = 0 then begin + dest:= 0; + end + else begin + dest:= createregion; + combinergn(dest,source,0,rgn_copy); + end; + end; +end; + +procedure gdi_moveregion(var drawinfo: drawinfoty); +begin + with drawinfo.regionoperation do begin + offsetrgn(source,rect.x,rect.y); + end; +end; + +procedure gdi_regsubrect(var drawinfo: drawinfoty); +var + reg1: hrgn; +begin + with drawinfo.regionoperation do begin + reg1:= createregion(rect,drawinfo.gc); + combinergn(dest,dest,reg1,rgn_diff); + deleteobject(reg1); +{$ifdef mse_debuggdi} + dec(regioncount); +{$endif} + end; +end; + +procedure gdi_regsubregion(var drawinfo: drawinfoty); +begin + with drawinfo.regionoperation do begin + combinergn(dest,dest,source,rgn_diff); + end; +end; + +procedure gdi_regaddrect(var drawinfo: drawinfoty); +var + reg1: hrgn; +begin + with drawinfo.regionoperation do begin + reg1:= createregion(rect,drawinfo.gc); + combinergn(dest,dest,reg1,rgn_or); + deleteobject(reg1); +{$ifdef mse_debuggdi} + dec(regioncount); +{$endif} + end; +end; + +procedure gdi_regaddregion(var drawinfo: drawinfoty); +begin + with drawinfo.regionoperation do begin + combinergn(dest,dest,source,rgn_or); + end; +end; + +procedure gdi_regintersectrect(var drawinfo: drawinfoty); +var + reg1: hrgn; +begin + with drawinfo.regionoperation do begin + reg1:= createregion(rect,drawinfo.gc); + combinergn(dest,dest,reg1,rgn_and); + deleteobject(reg1); +{$ifdef mse_debuggdi} + dec(regioncount); +{$endif} + end; +end; + +procedure gdi_regintersectregion(var drawinfo: drawinfoty); +begin + with drawinfo.regionoperation do begin + combinergn(dest,dest,source,rgn_and); + end; +end; + +var + fgdipluschecked: boolean; + fhasgdiplus: boolean; + +procedure gdi_destroygc(var drawinfo: drawinfoty); +begin + with drawinfo,gc,win32gcty(platformdata).d do begin + selectobject(handle,nullpen); + selectobject(handle,nullbrush); +{$ifdef mse_debuggdi} + dec(gccount); +{$endif} + if handle <> 0 then begin + case kind of + gck_pixmap,gck_printer: begin + // bmp1:= createcompatiblebitmap(handle,0,0); + // bmp2:= selectobject(handle,bmp1); //select actual bitmap out of dc + //really needed? + deletedc(handle); + // deleteobject(bmp1); + end; + gck_metafile: begin + deleteenhmetafile(closeenhmetafile(handle)); + end + else begin + releasedc(paintdevice,handle); + end; + end; + end; + if backgroundbrush <> 0 then begin + deleteobject(backgroundbrush); + backgroundbrush:= 0; + end; + if colorbrush <> 0 then begin + deleteobject(colorbrush); + colorbrush:= 0; + end; + if patternbrush <> 0 then begin + deleteobject(patternbrush); + patternbrush:= 0; + end; + if foregroundpen <> 0 then begin + deleteobject(foregroundpen); + foregroundpen:= 0; + end; + selectedpen:= 0; + selectedbrush:= 0; + if fhasgdiplus then begin + if gpgraphic <> nil then begin + gdipdeletegraphics(gpgraphic); + gpgraphic:= nil; + gdipdeletebrush(pgpbrush(gpsolidfill)); + gdipdeletepen(gppen); + if gpregion <> nil then begin + gdipdeleteregion(gpregion); + gpregion:= nil; + end; + if gptexture <> nil then begin + gdipdeletebrush(pgpbrush(gptexture)); + gptexture:= nil; + end; + deletepgtexture(gc); + end; + end; + end; +end; + +function hasgdiplus: boolean; +begin + if not fhasgdiplus and not fgdipluschecked then begin + fgdipluschecked:= true; + fhasgdiplus:= initializegdiplus([],true); + end; + result:= fhasgdiplus; +end; + +procedure checkgdiplusgraphic(var drawinfo: drawinfoty); +var + reg: hrgn; + int1: int; +begin + with drawinfo.gc,win32gcty(platformdata).d do begin + if gpgraphic = nil then begin + with gppalettedata do begin + flags:= 0; + count:= 2; + val0:= 0; + val1:= $ffffffff; + end; + reg:= createrectrgn(0,0,0,0); + int1:= getcliprgn(handle,reg); + selectcliprgn(handle,0); //use full paintdevice rect + gdipcreatefromhdc(handle,@gpgraphic); + if int1 > 0 then begin + selectcliprgn(handle,reg); + end; + deleteobject(reg); + if gpgraphic <> nil then begin + gdipsetsmoothingmode(gpgraphic,smoothingmodeantialias); + gdipsetpixeloffsetmode(gpgraphic,pixeloffsetmodehalf); +// gdipsetpixeloffsetmode(gpgraphic,pixeloffsetmodenone); + gdipcreatesolidfill(alphamax,@gpsolidfill); + gdipcreatepen1(alphamax,1,unitpixel,@gppen); + gpflags:= []; +// gdipsetpenmode(gppen,penalignmentcenter); + end; + end; + end; +end; + +procedure gdi_changegc(var drawinfo: drawinfoty); +begin + with drawinfo.gcvalues^,drawinfo.gc,win32gcty(platformdata).d do begin + if gvm_colorbackground in mask then begin + exclude(flags,gcf_backgroundbrushvalid); + exclude(gpflags,gcf_gpbrushcolorvalid); + backgroundcol:= colorbackground; + end; + if gvm_colorforeground in mask then begin + flags:= flags - [gcf_colorbrushvalid,gcf_foregroundpenvalid]; + gpflags:= gpflags - [gcf_gpbrushcolorvalid,gcf_gppencolorvalid]; + foregroundcol:= colorforeground; + end; + if mask * [gvm_linewidth,gvm_dashes,gvm_capstyle,gvm_joinstyle] <> [] then begin + exclude(flags,gcf_foregroundpenvalid); + exclude(gpflags,gcf_gppenvalid); + peninfo:= lineinfo; + peninfo.width:= (peninfo.width + linewidthroundvalue) shr linewidthshift; + end; + if gvm_rasterop in mask then begin + exclude(flags,gcf_rasterop); + rop:= rasterop; + end; + if gvm_brush in mask then begin + exclude(flags,gcf_patternbrushvalid); +// exclude(gpflags,gcf_patternbrushvalid); + bru:= tsimplebitmap1(brush).handle; + deletepgtexture(drawinfo.gc); //resets vaildflags + end; + if gvm_brushorigin in mask then begin + exclude(gpflags,gcf_gpbrushoriginvalid); + brushorg:= brushorigin; + setbrushorgex(handle,brushorigin.x,brushorigin.y,nil); + end; + if gvm_clipregion in mask then begin + gccliporigin:= cliporigin; + if ((cliporigin.x <> 0) or (cliporigin.y <> 0)) and (clipregion <> 0) then begin + offsetrgn(clipregion,cliporigin.x,cliporigin.y); + selectcliprgn(handle,clipregion); + offsetrgn(clipregion,-cliporigin.x,-cliporigin.y); + end + else begin + selectcliprgn(handle,clipregion); + end; + exclude(gpflags,gcf_gpregionvalid); + end + else begin +// include(gpflags,gcf_gpregionvalid); //??? + end; + if gvm_font in mask then begin + selectobject(handle,font); + end; + if gvm_options in mask then begin + if cao_smooth in options then begin + if hasgdiplus then begin + checkgdiplusgraphic(drawinfo); + if gpgraphic <> nil then begin + if not (gcf_smooth in flags) then begin + gpflags:= gpflags - gpstartflags; + include(flags,gcf_smooth); + end; + end; + end; + end + else begin + exclude(flags,gcf_smooth); + end; + end; +// gpflags:= gpflags - ((flags >< flagsbefore)*flagsbefore); + //invalidate gdiplus + end; +end; + +procedure gdi_getcanvasclass(var drawinfo: drawinfoty); //gdifunc +begin + //dummy +end; + +procedure gdi_endpaint(var drawinfo: drawinfoty); //gdifunc +begin + //dummy +end; + +procedure gdi_flush(var drawinfo: drawinfoty); //gdifunc +begin + with win32gcty(drawinfo.gc.platformdata).d do begin + if gpgraphic <> nil then begin + gdipflush(gpgraphic,flushintentionsync); + end; + end; +end; + +procedure gdi_movewindowrect(var drawinfo: drawinfoty); //gdifunc +begin + with drawinfo.moverect do begin + gui_movewindowrect(drawinfo.paintdevice,dist^,rect^); + end; +end; + +procedure gdi_drawlines(var drawinfo: drawinfoty); +var + po1: ppointty; + bo1: boolean; +begin + transformpoints(drawinfo,false); + if gcf_smooth in win32gcty(drawinfo.gc.platformdata).d.flags then begin + checkgpgc(drawinfo.gc,gplineflags); + with drawinfo,points,win32gcty(gc.platformdata).d do begin + if closed then begin + gdipdrawpolygoni(gpgraphic,gppen,buffer.buffer,count); + end + else begin + gdipdrawlinesi(gpgraphic,gppen,buffer.buffer,count); + end; + end; + end + else begin + with drawinfo,points do begin + if closed then begin + bo1:= checkgc(gc,[gcf_foregroundpenvalid,gcf_selectforegroundpen, + gcf_selectnullbrush]); + windows.polygon(gc.handle,buffer.buffer^,count); + if bo1 then begin + checkgc2(gc); + windows.polygon(gc.handle,buffer.buffer^,count); + end; + end + else begin + bo1:= checkgc(gc,[gcf_foregroundpenvalid,gcf_selectforegroundpen]); + if ((win32gcty(gc.platformdata).d.peninfo.width <= 1) or + (win32gcty(gc.platformdata).d.peninfo.capstyle = cs_butt)) and + (count > 0) then begin + po1:= @pointarty(buffer.buffer)[count-1]; //endpoint + if (po1^.x <> pointarty(buffer.buffer)[0].x) or + (po1^.y <> pointarty(buffer.buffer)[0].y) then begin + adjustlineend(po1); + end; + end; + windows.polyline(gc.handle,buffer.buffer^,count); + if bo1 then begin + checkgc2(gc); + windows.polyline(gc.handle,buffer.buffer^,count); + end; + end; + end; + end; +end; + +procedure gdi_drawlinesegments(var drawinfo: drawinfoty); +var + int1,int2: integer; + po1,po2: pdword; + po3: ppointty; + bo1: boolean; +begin + with drawinfo,win32gcty(gc.platformdata).d do begin + int1:= points.count div 2; + allocbuffer(buffer,points.count*sizeof(pointty)+int1*sizeof(integer)); + //reserve memory + transformpoints(drawinfo,false); + po3:= buffer.buffer; //segments + int1:= points.count div 2; //segmentcount + if gcf_smooth in flags then begin + checkgpgc(drawinfo.gc,gplineflags); + for int2:= 0 to int1-1 do begin + gdipdrawlinesi(gpgraphic,gppen,pointer(po3),2); + inc(po3,2); + end; + end + else begin + po1:= pointer(pchar(buffer.buffer) + int1*sizeof(segmentty)); + inc(po3); //segmentend + po2:= po1; //counts + bo1:= (win32gcty(gc.platformdata).d.peninfo.width < 1); + for int2:= 0 to int1 - 1 do begin + if bo1 then begin + adjustlineend(po3); + inc(po3,2); + end; + po2^:= 2; + inc(po2); + end; + bo1:= checkgc(gc,[gcf_foregroundpenvalid,gcf_selectforegroundpen]); + windows.polyPolyline(gc.handle,buffer.buffer^,po1^,int1); + if bo1 then begin + checkgc2(gc); + windows.polyPolyline(gc.handle,buffer.buffer^,po1^,int1); + end; + end; + end; +end; + +procedure gdi_drawellipse(var drawinfo: drawinfoty); +var + bo1: boolean; +begin + if gcf_smooth in win32gcty(drawinfo.gc.platformdata).d.flags then begin + checkgpgc(drawinfo.gc,gplineflags); + with drawinfo,rect.rect^,win32gcty(gc.platformdata).d do begin + gdipdrawellipsei(gpgraphic,gppen,origin.x+x-cx div 2, + origin.y+y-cy div 2,cx,cy); + end; + end + else begin + transformellipseinfo(drawinfo,false); + with drawinfo do begin + bo1:= checkgc(gc,[gcf_foregroundpenvalid,gcf_selectforegroundpen, + gcf_selectnullbrush]); + windows.ellipse(gc.handle,trect(buffer.buffer^).Left, + trect(buffer.buffer^).top, + trect(buffer.buffer^).right, + trect(buffer.buffer^).bottom); + if bo1 then begin + checkgc2(gc); + windows.ellipse(gc.handle,trect(buffer.buffer^).Left, + trect(buffer.buffer^).top, + trect(buffer.buffer^).right, + trect(buffer.buffer^).bottom); + end; + end; + end; +end; + +procedure getarcinfo(const info: drawinfoty; + out xstart,ystart,xend,yend: integer); +var + stopang: real; +begin + with info,arc,rect^ do begin + stopang:= (startang+extentang); + xstart:= (round(cos(startang)*cy) div 2) + x + origin.x; + ystart:= (round(-sin(startang)*cy) div 2) + y + origin.y; + xend:= (round(cos(stopang)*cy) div 2) + x + origin.x; + yend:= (round(-sin(stopang)*cy) div 2) + y + origin.y; + end; +end; + +const + radianttograd = -360.0/(2.0*pi); + +type + gparcinfoty = record + rect: rectty; + startang,extentang: real; + end; + +procedure adjustgparc(const drawinfo: drawinfoty; out ainfo: gparcinfoty); +begin + with drawinfo,arc,rect^ do begin + ainfo.rect.x:= x + origin.x - cx div 2; + ainfo.rect.y:= y + origin.y - cy div 2; + ainfo.rect.size:= size; + ainfo.startang:= startang*radianttograd; + ainfo.extentang:= extentang*radianttograd; + { + if extentang < 0 then begin + startang:= startang+extentang; + extentang:= -extentang; + end; + while startang < 0 do begin + startang:= startang + 360; + end; + } + end; +end; + +procedure gdi_drawarc(var drawinfo: drawinfoty); +var //todo: optimize + bo1: boolean; + xstart,ystart,xend,yend: integer; + arcinfo: gparcinfoty; +begin + if gcf_smooth in win32gcty(drawinfo.gc.platformdata).d.flags then begin + checkgpgc(drawinfo.gc,gplineflags); + adjustgparc(drawinfo,arcinfo); + with drawinfo,arcinfo,win32gcty(gc.platformdata).d do begin + gdipdrawarci(gpgraphic,gppen,rect.x,rect.y,rect.cx,rect.cy, + startang,extentang); + end; + end + else begin + getarcinfo(drawinfo,xstart,ystart,xend,yend); + with drawinfo,arc,rect^ do begin + if (xstart = xend) and (ystart = yend) and (abs(extentang) < 1) then begin + checkgc(gc,[gcf_foregroundpenvalid,gcf_selectforegroundpen,gcf_selectnullbrush]); + movetoex(gc.handle,xstart,ystart,nil); + if (win32gcty(gc.platformdata).d.peninfo.width = 0) {and + (win32gcty(gc.platformdata).peninfo.capstyle <> cs_butt)} then begin + inc(xstart); + end; + lineto(gc.handle,xstart,ystart); + exit; + end; + if extentang < 0 then begin + setarcdirection(gc.handle,ad_clockwise); + end + else begin + setarcdirection(gc.handle,ad_counterclockwise); + end; + end; + transformellipseinfo(drawinfo,false); + with drawinfo do begin + bo1:= checkgc(gc,[gcf_foregroundpenvalid,gcf_selectforegroundpen,gcf_selectnullbrush]); + windows.arc(gc.handle,trect(buffer.buffer^).Left, + trect(buffer.buffer^).top, + trect(buffer.buffer^).right, + trect(buffer.buffer^).bottom, + xstart,ystart,xend,yend); + if bo1 then begin + checkgc2(gc); + windows.arc(gc.handle,trect(buffer.buffer^).Left, + trect(buffer.buffer^).top, + trect(buffer.buffer^).right, + trect(buffer.buffer^).bottom, + xstart,ystart,xend,yend); + end; + end; + end; +end; + +procedure gdi_drawstring16(var drawinfo: drawinfoty); +begin + with drawinfo do begin + updateopaquemode(gc); + with gc,drawinfo.text16pos do begin + windows.textoutw(handle,pos^.x + origin.x,pos^.y + origin.y,text,count); + end; + end; +end; + +//todo!!!!!: support all rops on win95, test!!! + +function win95maskblt(DestDC: HDC; XDest, YDest, Width, Height: Integer; SrcDC: HDC; + XScr, YScr: Integer; Mask: HBITMAP; amaskdc: hdc; xMask, yMask: Integer; Rop: rasteropty): boolean; +var + maskdc: hdc; + bmp: hbitmap; + dc: hdc; + textcol,bkcol: longword; + + procedure getcopy(arop: rasteropty); + begin + textcol:= gettextcolor(destdc); + bkcol:= getbkcolor(destdc); + settextcolor(destdc,$ffffff); + setbkcolor(destdc,$000000); + bmp:= createcompatiblebitmap(destdc,width,height); + dc:= createcompatibledc(destdc); + selectobject(dc,bmp); + settextcolor(dc,textcol); + setbkcolor(dc,bkcol); + bitblt(dc,0,0,width,height,srcdc,xscr,yscr,rasterops3[rop_copy]); + settextcolor(dc,$ffffff); + setbkcolor(dc,$000000); + bitblt(dc,0,0,width,height,maskdc,xmask,ymask,rasterops3[arop]); + end; + +begin + result:= true; + bmp:= 0; + if amaskdc = 0 then begin + maskdc:= createcompatibledc(0); + selectobject(maskdc,mask); + end + else begin + maskdc:= amaskdc; + end; + case rop of + rop_copy,rop_xor,rop_or: begin + getcopy(rop_and); + if rop = rop_copy then begin + bitblt(destdc,xdest,ydest,width,height,maskdc,xmask,ymask,rasterops3[rop_notand]); + settextcolor(destdc,textcol); + setbkcolor(destdc,bkcol); + bitblt(destdc,xdest,ydest,width,height,dc,0,0,rasterops3[rop_or]); + end + else begin + settextcolor(destdc,textcol); + setbkcolor(destdc,bkcol); + bitblt(destdc,xdest,ydest,width,height,dc,0,0,rasterops3[rop]); + end; + end; + rop_and: begin + getcopy(rop_notor); + settextcolor(destdc,textcol); + setbkcolor(destdc,bkcol); + bitblt(destdc,xdest,ydest,width,height,dc,0,0,rasterops3[rop]); + end; + end; + if amaskdc = 0 then begin + deletedc(maskdc); + end; + if bmp <> 0 then begin + deletedc(dc); + deleteobject(bmp); + end; +end; + +procedure fill(var drawinfo: drawinfoty; shape: shapety); + +var + xstart,ystart,xend,yend: integer; + rop3tab: prop3tabty; + patrop3tab: prop3tabty; + + procedure fill1( adc: hdc; arop: rasteropty); + begin + with drawinfo do begin + if (shape <> fs_rect) and (shape <> fs_copyarea) then begin + if df_canvasismonochrome in gc.drawingflags then begin + setrop2(adc,inverserops2[arop]); + end + else begin + setrop2(adc,rasterops2[arop]); + end; + end; + if shape <> fs_copyarea then begin + with win32gcty(gc.platformdata).d do begin + if patternbrush <> 0 then begin + selectobject(adc,patternbrush); + if adc = gc.handle then begin + selectedbrush:= patternbrush; + end; + end; + end; + end; + case shape of + fs_copyarea: begin + with copyarea,sourcerect^ do begin + if mask = nil then begin + bitblt(adc,destrect^.x,destrect^.y,cx,cy, + tcanvas1(source).fdrawinfo.gc.handle,x,y,rop3tab^[arop]); + end + else begin + if iswin95 or (win32gcty(gc.platformdata).d.kind = gck_printer) then begin +// win95maskblt(adc,destrect^.x,destrect^.y,cx,cy,source^.gc.handle, +// x,y,mask,maskgchandle,x,y,arop); + tcanvas1(mask.canvas).checkgcstate([cs_gc]); + win95maskblt(adc,destrect^.x,destrect^.y,cx,cy, + tcanvas1(source).fdrawinfo.gc.handle, + x,y,tsimplebitmap1(mask).handle, + tcanvas1(mask.canvas).fdrawinfo.gc.handle,x,y,arop); + end + else begin + maskblt(adc,destrect^.x,destrect^.y,cx,cy, + tcanvas1(source).fdrawinfo.gc.handle, + x,y,tsimplebitmap1(mask).handle,x,y, + makerop4(rop3tab^[rop_nop],rop3tab^[arop])); + end; + end; + end; + end; + fs_rect: begin + with prectty(buffer.buffer)^ do begin + windows.patblt(adc,x,y,cx,cy,patrop3tab^[arop]); + end; + end; + fs_ellipse: begin + with trect(buffer.buffer^) do begin + windows.ellipse(adc,left,top,right,bottom); + end; + end; + fs_arc: begin + with trect(buffer.buffer^) do begin + if arc.pieslice then begin + windows.pie(adc,left,top,right,bottom,xstart,ystart,xend,yend); + end + else begin + windows.chord(adc,left,top,right,bottom,xstart,ystart,xend,yend); + end; + end; + end; + fs_polygon: begin + windows.Polygon(adc,buffer.buffer^,points.count); + end; + end; + end; + end; + +var + rect1,rect2: rectty; + po1: ppointty; + int1: integer; + bmp: hbitmap; + dc1: hdc; + +begin + if shape = fs_arc then begin + getarcinfo(drawinfo,xstart,ystart,xend,yend); + end; + with drawinfo do begin + with gc,win32gcty(platformdata).d do begin + if df_canvasismonochrome in gc.drawingflags then begin + rop3tab:= @inverserops3; + patrop3tab:= @inversepatrops3; + end + else begin + rop3tab:= @rasterops3; + patrop3tab:= @patrops3; + end; + + if (drawingflags * [df_monochrome,df_opaque,df_brush] = + [df_monochrome,df_brush]) then begin + if shape <> fs_rect then begin + if shape <> fs_copyarea then begin + checkgc(gc,[gcf_patternbrushvalid,gcf_selectnullpen]); + exclude(flags,gcf_rasterop); + end; + end + else begin + checkgc(gc,[gcf_patternbrushvalid]); + end; + if rop in [rop_or,rop_xor,rop_and,rop_copy,rop_set,rop_clear] then begin + case rop of + rop_or,rop_xor: begin +// setbkcolor(handle,foregroundcol); + settextcolor(handle,foregroundcol); +// settextcolor(handle,$00000000); + setbkcolor(handle,$00000000); + fill1(handle,rop); + end; + rop_and: begin +// setbkcolor(handle,foregroundcol); + settextcolor(handle,foregroundcol); +// settextcolor(handle,$00ffffff); + setbkcolor(handle,$00ffffff); + fill1(handle,rop_and); + end; + rop_set: begin +// setbkcolor(handle,$00ffffff); + settextcolor(handle,$00ffffff); +// settextcolor(handle,$00000000); + setbkcolor(handle,$00000000); + fill1(handle,rop_or); //set pattern + end + else begin +// setbkcolor(handle,$00000000); + settextcolor(handle,$00000000); +// settextcolor(handle,$00ffffff); + setbkcolor(handle,$00ffffff); + fill1(handle,rop_and); //clear pattern + if rop = rop_copy then begin +// settextcolor(handle,$00000000); + setbkcolor(handle,$00000000); +// setbkcolor(handle,foregroundcol); + settextcolor(handle,foregroundcol); + fill1(handle,rop_or); //fill pattern + end; + end; + end; + end + else begin //buffer needed + getclipbox(handle,trect(rect1)); + winrecttorect(rect1); + if (shape = fs_rect) or (shape = fs_copyarea) then begin + rect2:= prectty(buffer.buffer)^; + end + else begin + rect2.x:= maxint; + rect2.y:= maxint; + rect2.cx:= minint; + rect2.cy:= minint; + case shape of //calculate max. dims + fs_polygon: begin + po1:= buffer.buffer; + for int1:= 0 to points.count - 1 do begin + if po1^.x < rect2.x then begin + rect2.x:= po1^.x; + end; + if po1^.x > rect2.cx then begin + rect2.cx:= po1^.x; + end; + if po1^.y < rect2.y then begin + rect2.y:= po1^.y; + end; + if po1^.y > rect2.cy then begin + rect2.cy:= po1^.y; + end; + inc(po1); + end; + end; + end; + winrecttorect(rect2); + end; + if msegraphutils.intersectrect(rect1,rect2,rect1) then begin +// bmp:= gui_createpixmap(rect1.size,0,df_canvasismonochrome in drawingflags); + bmp:= gui_createpixmap(rect1.size,0,gc.kind); + if bmp <> 0 then begin + dc1:= createcompatibledc(0); + if dc1 <> 0 then begin + selectobject(dc1,bmp); + setwindoworgex(dc1,rect1.x,rect1.y,nil); + bitblt(dc1,rect1.x,rect1.y,rect1.cx,rect1.cy,handle,rect1.x,rect1.y,srccopy); //get copy + setbrushorgex(dc1,brushorg.x-rect1.x,brushorg.y-rect1.y,nil); + settextcolor(dc1,foregroundcol); + setbkcolor(dc1,backgroundcol); + fill1(dc1,rop); //draw pattern + settextcolor(dc1,$00000000); + setbkcolor(dc1,$00ffffff); + fill1(dc1,rop_notand); //erase background + settextcolor(handle,$00000000); + setbkcolor(handle,$00ffffff); + fill1(handle,rop_and); //erase pattern + bitblt(handle,rect1.x,rect1.y,rect1.cx,rect1.cy,dc1,rect1.x,rect1.y, + rop3tab^[rop_or]); //combine + deletedc(dc1); + end; + gui_freepixmap(bmp); + end; + end; + end; + end + else begin + if df_opaque in drawingflags then begin +// settextcolor(handle,backgroundcol); + setbkcolor(handle,backgroundcol); +// setbkcolor(handle,foregroundcol); + settextcolor(handle,foregroundcol); + end; + if shape <> fs_rect then begin + checkgc(gc,[gcf_colorbrushvalid,gcf_patternbrushvalid, + gcf_selectforegroundbrush,gcf_selectnullpen]); + end; + case shape of + fs_rect: begin + with prectty(buffer.buffer)^ do begin + if (df_brush in drawingflags) then begin + checkgc(gc,[gcf_colorbrushvalid,gcf_patternbrushvalid, + gcf_selectforegroundbrush]); + windows.patblt(handle,x,y,cx,cy,patrop3tab^[rop]); + end + else begin + if rop = rop_copy then begin + checkgc(gc,[gcf_colorbrushvalid]); + {$ifdef FPC} + winfillrect(handle,mrect(x,y,x+cx,y+cy),colorbrush); + {$else} + windows.fillrect(handle,mrect(x,y,x+cx,y+cy),colorbrush); + {$endif} + end + else begin + checkgc(gc,[gcf_colorbrushvalid,gcf_selectforegroundbrush]); + windows.patblt(handle,x,y,cx,cy,patrop3tab^[rop]); + end; + end; + end; + end; + fs_ellipse: begin + with trect(buffer.buffer^) do begin + windows.ellipse(gc.handle,left,top,right,bottom); + end; + end; + fs_arc: begin + with trect(buffer.buffer^) do begin + if arc.pieslice then begin + windows.pie(gc.handle,left,top,right,bottom,xstart,ystart,xend,yend); + end + else begin + windows.chord(gc.handle,left,top,right,bottom,xstart,ystart,xend,yend); + end; + end; + end; + fs_polygon: begin + windows.Polygon(gc.handle,buffer.buffer^,points.count); + end; + end; + end; + end; + end; +end; + +procedure gdi_fillrect(var drawinfo: drawinfoty); +begin + offsetrect(drawinfo); + fill(drawinfo,fs_rect); +end; + +procedure gdi_fillellipse(var drawinfo: drawinfoty); +begin + if gcf_smooth in win32gcty(drawinfo.gc.platformdata).d.flags then begin + checkgpgc(drawinfo.gc,gpfillflags); + with drawinfo,rect.rect^,win32gcty(gc.platformdata).d do begin + gdipfillellipsei(gpgraphic,gpbrush,origin.x+x-cx div 2, + origin.y+y-cy div 2,cx,cy); + end; + end + else begin + transformellipseinfo(drawinfo,true); + fill(drawinfo,fs_ellipse); + end; +end; + +procedure gdi_fillarc(var drawinfo: drawinfoty); +var + pa1: pGpPath; + arc1: gparcinfoty; +begin + if gcf_smooth in win32gcty(drawinfo.gc.platformdata).d.flags then begin + checkgpgc(drawinfo.gc,gpfillflags); + adjustgparc(drawinfo,arc1); + with drawinfo,arc1,win32gcty(gc.platformdata).d do begin + if arc.pieslice then begin + gdipfillpiei(gpgraphic,gpbrush, + rect.x,rect.y,rect.cx,rect.cy,startang,extentang); + end + else begin + gdipcreatepath(fillmodealternate,@pa1); + gdipaddpatharc(pa1,rect.x,rect.y,rect.cx,rect.cy,startang,extentang); + gdipfillpath(gpgraphic,gpbrush,pa1); + gdipdeletepath(pa1); + end; + end; + end + else begin + transformellipseinfo(drawinfo,true); + fill(drawinfo,fs_arc); + end; +end; + +procedure gdi_fillpolygon(var drawinfo: drawinfoty); +begin + transformpoints(drawinfo,false); + with win32gcty(drawinfo.gc.platformdata).d do begin + if gcf_smooth in flags then begin + checkgpgc(drawinfo.gc,gpfillflags); + gdipfillpolygon2i(gpgraphic,gpbrush,drawinfo.buffer.buffer, + drawinfo.points.count); + end + else begin + fill(drawinfo,fs_polygon); + end; + end; +end; + +procedure gdi_copyarea(var drawinfo: drawinfoty); + +var + maskbmp,stretchedbmp: pixmapty; + smaskdc,destdc: hdc; + bufferbmp: hbitmap; + rect1: rectty; + nomaskblt: boolean; + maskpos: pointty; + + procedure setintpolmode(const ahandle: hdc); + var + pt1: tpoint; + begin + with drawinfo.copyarea do begin + if (al_intpol in alignment) and not iswin95 then begin + getbrushorgex(ahandle,pt1); + setstretchbltmode(ahandle,halftone); + setbrushorgex(ahandle,pt1.x,pt1.y,nil); + end + else begin + if al_or in alignment then begin + setstretchbltmode(ahandle,blackonwhite); + end + else begin + if al_and in alignment then begin + setstretchbltmode(ahandle,whiteonblack); + end + else begin + setstretchbltmode(ahandle,coloroncolor); + end; + end; + end; + end; + end; + + procedure getstretchedbmps; + var + po1: pointty; + begin + with drawinfo,copyarea,sourcerect^,gc do begin + po1.x:= destrect^.x - rect1.x; + po1.y:= destrect^.y - rect1.y; + if mask <> nil then begin + tcanvas1(mask.canvas).checkgcstate([cs_gc]); + smaskdc:= tcanvas1(mask.canvas).fdrawinfo.gc.handle; + maskbmp:= gui_createpixmap(rect1.size,0,bmk_mono); +// maskbmp:= gui_createpixmap(rect1.size,0,true); + end + else begin + maskbmp:= 0; + end; + stretchedbmp:= createcompatiblebitmap(tcanvas1(source).fdrawinfo.gc.handle, + rect1.cx,rect1.cy); + destdc:= createcompatibledc(0); + setintpolmode(destdc); + if mask <> nil then begin + selectobject(destdc,maskbmp); + if al_nomaskscale in alignment then begin + stretchblt(destdc,po1.x,po1.y,destrect^.cx,destrect^.cy,smaskdc, + maskpos.x,maskpos.y,destrect^.cx,destrect^.cy, + rasterops3[rop_copy]); + end + else begin + stretchblt(destdc,po1.x,po1.y,destrect^.cx,destrect^.cy,smaskdc, + maskpos.x,maskpos.y,cx,cy,rasterops3[rop_copy]); + end; + end; + selectobject(destdc,stretchedbmp); + stretchblt(destdc,po1.x,po1.y,destrect^.cx,destrect^.cy, + tcanvas1(source).fdrawinfo.gc.handle, + x,y,cx,cy,rasterops3[rop_copy]); + end; + end; + + procedure deletestretchedbmps; + begin + if maskbmp <> 0 then begin + if bufferbmp = 0 then begin + gui_freepixmap(maskbmp); +// deleteobject(maskbmp); + end; + end; + deletedc(destdc); + deleteobject(stretchedbmp); + end; + + procedure transfer(double: boolean = false; inverserop: boolean = false); + var + rop3tab: prop3tabty; + begin + if inverserop then begin + rop3tab:= @inverserops3; + end + else begin + rop3tab:= @rasterops3; + end; + with drawinfo,copyarea,sourcerect^,gc,win32gcty(platformdata).d do begin + if alignment * [al_stretchx,al_stretchy] = [] then begin + if mask = nil then begin + bitblt(handle,destrect^.x,destrect^.y,cx,cy, + tcanvas1(source).fdrawinfo.gc.handle, + x,y,rop3tab^[copymode]); + if double then begin + setbkcolor(handle,$000000); + settextcolor(handle,foregroundcol); + bitblt(handle,destrect^.x,destrect^.y,cx,cy, + tcanvas1(source).fdrawinfo.gc.handle, + x,y,rop3tab^[rop_or]); + end; + end + else begin + if nomaskblt then begin + tcanvas1(mask.canvas).checkgcstate([cs_gc]); + win95maskblt(handle,destrect^.x,destrect^.y,cx,cy, + tcanvas1(source).fdrawinfo.gc.handle, + x,y,tsimplebitmap1(mask).fhandle, + tcanvas1(mask.canvas).fdrawinfo.gc.handle, + maskpos.x,maskpos.y,copymode); + end + else begin + maskblt(handle,destrect^.x,destrect^.y,cx,cy, + tcanvas1(source).fdrawinfo.gc.handle, + x,y,tsimplebitmap1(mask).handle, + maskpos.x,maskpos.y, + makerop4(rop3tab^[rop_nop],rop3tab^[copymode])); + end; + if double then begin + setbkcolor(handle,$000000); + settextcolor(handle,foregroundcol); + if nomaskblt then begin + win95maskblt(handle,destrect^.x,destrect^.y,cx,cy, + tcanvas1(source).fdrawinfo.gc.handle, + maskpos.x,maskpos.y,tsimplebitmap1(mask).fhandle, + tcanvas1(mask.canvas).fdrawinfo.gc.handle,x,y,rop_or); + end + else begin + maskblt(handle,destrect^.x,destrect^.y,cx,cy, + tcanvas1(source).fdrawinfo.gc.handle, + maskpos.x,maskpos.y,tsimplebitmap1(mask).fhandle,x,y, + makerop4(rop3tab^[rop_nop],rop3tab^[rop_or])); + end; + end; + end; + end + else begin + if mask = nil then begin + stretchblt(handle,destrect^.x,destrect^.y,destrect^.cx,destrect^.cy, + tcanvas1(source).fdrawinfo.gc.handle, + x,y,cx,cy,rop3tab^[copymode]); + if double then begin + setbkcolor(handle,$000000); + settextcolor(handle,foregroundcol); + stretchblt(handle,destrect^.x,destrect^.y,destrect^.cx,destrect^.cy, + tcanvas1(source).fdrawinfo.gc.handle, + x,y,cx,cy,rop3tab^[rop_or]); + end; + end + else begin + getstretchedbmps; + if nomaskblt then begin + win95maskblt(handle,rect1.x,rect1.y,rect1.cx,rect1.cy,destdc, + 0,0,maskbmp,0,0,0,copymode); + end + else begin + maskblt(handle,rect1.x,rect1.y,rect1.cx,rect1.cy,destdc, + 0,0,maskbmp,0,0,makerop4(rop3tab^[rop_nop], + rop3tab^[copymode])); + end; + if double then begin + setbkcolor(handle,$000000); + settextcolor(handle,foregroundcol); + if nomaskblt then begin + win95maskblt(handle,rect1.x,rect1.y,rect1.cx,rect1.cy,destdc, + 0,0,maskbmp,0,0,0,rop_or); + end + else begin + maskblt(handle,rect1.x,rect1.y,rect1.cx,rect1.cy,destdc, + 0,0,maskbmp,0,0,makerop4(rop3tab^[rop_nop], + rop3tab^[rop_or])); + end; + end; + deletestretchedbmps; + end; + end; + end; + end; //transfer + +var + ropbefore: rasteropty; + destdcbefore: hdc; + destpointbefore: pointty; + rect1posbefore: pointty; + destbmp,colormaskbmp: hbitmap; + destbmpdc,maskdc,colormaskdc: hdc; + destimage,sourceimage,colormaskimage: imagety; + rs,gs,bs,rd,gd,bd: integer; + int1: integer; + colormask: tsimplebitmap1; + bufferbmpback: hbitmap; +// point1: tpoint; + maskbefore: tsimplebitmap; + sbmp,dbmp: hbitmap; + sdc,ddcbefore,ddc: hdc; + sourceposbefore: pointty; + pm,ps,pd,pe,po1: pointer; + scanstep: integer; +// by1,by2: byte; + wo1{,wo2}: word; + ca1,ca2: card32; + lwo1: longword; + pint1: ptrint; +begin + with drawinfo,copyarea,gc,win32gcty(platformdata).d do begin + getclipbox(handle,trect(rect1)); + winrecttorect(rect1); + if not intersectrect(destrect^,rect1,rect1) then begin + exit; + end; + + nomaskblt:= iswin95 or (kind = gck_printer); + setintpolmode(handle); + maskbefore:= mask; + maskpos:= addpoint(sourcerect^.pos,maskshift); + if (mask <> nil) and (mask.kind <> bmk_mono) then begin + colormask:= tsimplebitmap1(mask); + mask:= nil; + end + else begin + colormask:= nil; + end; + if ((longword(opacity) <> maxopacity) or (colormask <> nil)) + and not (df_canvasismonochrome in drawingflags) then begin + maskbmp:= 0; + destdcbefore:= handle; + destpointbefore:= destrect^.pos; + bufferbmp:= createcompatiblebitmap(handle,rect1.cx,rect1.cy); + destrect^.pos:= subpoint(destrect^.pos,rect1.pos); + handle:= createcompatibledc(0); + setintpolmode(handle); + selectobject(handle,bufferbmp); + rect1posbefore:= rect1.pos; + rect1.pos:= nullpoint; + end + else begin + bufferbmp:= 0; + destdcbefore:= 0; //compilerwarning + end; + if df_colorconvert in drawingflags then begin + if df_canvasismonochrome in drawingflags then begin + //convert to monochrome + setbkcolor(tcanvas1(source).fdrawinfo.gc.handle,transparentcolor); +// copymode:= rasteropty(inverserops[copymode]); + transfer; + end + else begin + if df_canvasismonochrome in + tcanvas1(source).fdrawinfo.gc.drawingflags + {source.kind = bmk_mono} then begin + //convert from monochrome + if not (df_opaque in drawingflags) then begin + if copymode = rop_xor then begin + setbkcolor(handle,$000000); + settextcolor(handle,foregroundcol); + transfer; + end + else begin + ropbefore:= copymode; + setbkcolor(handle,$ffffff); + settextcolor(handle,$000000); + copymode:= rop_and; + transfer(true); + copymode:= ropbefore; + end; + end + else begin + setbkcolor(handle,backgroundcol); + settextcolor(handle,foregroundcol); + transfer; + end; + end + else begin + sbmp:= createbitmapdata(sourcerect^.size,source.kind,ps); + sdc:= createcompatibledc(0); + selectobject(sdc,sbmp); + bitblt(sdc,0,0,sourcerect^.cx,sourcerect^.cy,source.gchandle, + sourcerect^.x,sourcerect^.y,srccopy); + dbmp:= createbitmapdata(sourcerect^.size,gc.kind,pd); + ddc:= createcompatibledc(0); + selectobject(ddc,dbmp); + scanstep:= ((sourcerect^.cx+3) div 4) * 4; + if source.kind = bmk_gray then begin + //gray to color + for int1:= 0 to sourcerect^.cy - 1 do begin + po1:= ps; + pe:= po1 + sourcerect^.cx; + repeat + wo1:= pbyte(po1)^; + plongword(pd)^:= wo1 or (wo1 shl 8) or (wo1 shl 16); + inc(po1); + inc(plongword(pd)); + until po1 >= pe; + ps:= ps + scanstep; + end; + end + else begin //color to gray + for int1:= 0 to sourcerect^.cy - 1 do begin + po1:= pd; + pe:= po1 + sourcerect^.cx; + repeat + lwo1:= plongword(ps)^; + pbyte(po1)^:= ((lwo1 and $ff) + ((lwo1 and $ff00) shr 8) + + ((lwo1 and $ff0000) shr 16)) div 3; + inc(po1); + inc(plongword(ps)); + until po1 >= pe; + pd:= pd + scanstep; + end; + end; + ddcbefore:= tcanvas1(source).fdrawinfo.gc.handle; + tcanvas1(source).fdrawinfo.gc.handle:= ddc; + sourceposbefore:= sourcerect^.pos; + sourcerect^.pos:= nullpoint; + + transfer; //gray <-> color + tcanvas1(source).fdrawinfo.gc.handle:= ddcbefore; + sourcerect^.pos:= sourceposbefore; + + deletedc(sdc); + deletedc(ddc); + deleteobject(sbmp); + deleteobject(dbmp); + end; + end; + end + else begin //no colorconvert + if df_canvasismonochrome in drawingflags then begin + setbkcolor(handle,$ffffff); + settextcolor(handle,$000000); + transfer(false,true); + end + else begin + transfer(false,false); + end; + end; + if bufferbmp <> 0 then begin //alpha operation //todo: optimze + rect1.pos:= rect1posbefore; + destbmp:= createcompatiblebitmap(handle,rect1.cx,rect1.cy); + destbmpdc:= createcompatibledc(0); + setintpolmode(destbmpdc); + selectobject(destbmpdc,destbmp); + bitblt(destbmpdc,0,0,rect1.cx,rect1.cy,destdcbefore,rect1.x,rect1.y,srccopy); + gui_pixmaptoimage(destbmp,destimage,destbmpdc); + gui_pixmaptoimage(bufferbmp,sourceimage,handle); + ps:= sourceimage.pixels; + pd:= destimage.pixels; + pint1:= ps-pd; + if colormask = nil then begin + rs:= (opacity.red*256 + 128) div 255; + gs:= (opacity.green*256 + 128) div 255; + bs:= (opacity.blue*256 + 128) div 255; + rd:= 256-rs; + gd:= 256-gs; + bd:= 256-bs; + case destimage.kind of + bmk_gray: begin + gs:= (word(rs)+word(gs)+word(bs)) div 3; + gd:= 256-gs; + for int1:= 0 to destimage.size.cy - 1 do begin + po1:= pd; + ps:= po1+pint1; + pe:= po1 + destimage.size.cx; + repeat + pbyte(po1)^:= (rd*pbyte(po1)^ + rs*pbyte(ps)^) shr 8; + inc(po1); + inc(ps); + until po1 >= pe; + pd:= pd + destimage.linebytes; + end; + end; + else begin + for int1:= 0 to destimage.length - 1 do begin + with rgbtriplety(destimage.pixels^[int1]) do begin + red:= (rd*red + rs*rgbtriplety(sourceimage.pixels^[int1]).red) shr 8; + green:= (gd*green + gs*rgbtriplety(sourceimage.pixels^[int1]).green) shr 8; + blue:= (bd*blue + bs*rgbtriplety(sourceimage.pixels^[int1]).blue) shr 8; + end; + end; + end; + end; + end + else begin + tcanvas1(colormask.canvas).checkgcstate([cs_gc]); + colormaskbmp:= gui_createpixmap(rect1.size,0, + tcanvas1(colormask.canvas).fdrawinfo.gc.kind); + colormaskdc:= createcompatibledc(0); + setintpolmode(colormaskdc); + deleteobject(selectobject(colormaskdc,colormaskbmp)); + if al_nomaskscale in alignment then begin + with destrect^ do begin + stretchblt(colormaskdc,x,y,cx,cy, + tcanvas1(colormask.canvas).fdrawinfo.gc.handle, + maskpos.x,maskpos.y,cx,cy, + rasterops3[rop_copy]); + end; + end + else begin + with sourcerect^ do begin + stretchblt(colormaskdc,destrect^.x,destrect^.y,destrect^.cx,destrect^.cy, + tcanvas1(colormask.canvas).fdrawinfo.gc.handle, + maskpos.x,maskpos.y,cx,cy, + rasterops3[rop_copy]); + end; + end; + gui_pixmaptoimage(colormaskbmp,colormaskimage,colormaskdc); + pm:= colormaskimage.pixels; + case colormaskimage.kind of + bmk_gray: begin + rs:= ((word(opacity.red)+word(opacity.green)+word(opacity.blue))*257) div + (3*255); + //-> 0..256 + case destimage.kind of + bmk_gray: begin + for int1:= 0 to destimage.size.cy - 1 do begin + po1:= pd; + ps:= po1 + pint1; + pe:= po1 + destimage.size.cx; + while po1 < pe do begin + ca1:= pbyte(pm)^*rs; + ca2:= 256*256-ca1; + pbyte(po1)^:= (pbyte(po1)^*ca2 + pbyte(ps)^*ca1) div (256*256); + inc(po1); + inc(ps); + inc(pm); + end; + pd:= pd + destimage.linebytes; + end; + end; + else begin + for int1:= 0 to destimage.size.cy - 1 do begin + po1:= pm; + pe:= po1 + colormaskimage.size.cx; + repeat + ca1:= pbyte(po1)^*rs; + ca2:= 256*256-ca1; + with prgbtriplety(pd)^ do begin + red:= (ca2*red + ca1*prgbtriplety(ps)^.red) div (256*256); + green:= (ca2*green + ca1*prgbtriplety(ps)^.green) div (256*256); + blue:= (ca2*blue + ca1*prgbtriplety(ps)^.blue) div (256*256); + end; + inc(po1); + inc(ps,4); + inc(pd,4); + until po1 >= pe; + pm:= pm + colormaskimage.linebytes; + end; + end; + end; + end; + else begin //bmk_rgb + case destimage.kind of + bmk_gray: begin + rs:= ((word(opacity.red)+word(opacity.green)+ + word(opacity.blue))*257) div (3*255); + //->0..256 + for int1:= 0 to destimage.size.cy - 1 do begin + po1:= pd; + ps:= po1 + pint1; + pe:= po1 + destimage.size.cx; + repeat + with prgbtriplety(pm)^ do begin + ca1:= (rs*(word(red)+word(green)+word(blue))); + end; + ca2:= 3*256*256-ca1; + pbyte(po1)^:= (pbyte(po1)^*ca2 + pbyte(ps)^*ca1) div (3*256*256); + inc(po1); + inc(ps); + inc(pm,4); + until po1 >= pe; + pd:= pd + destimage.linebytes; + end; + end; + else begin //bmk_rgb + rs:= (word(opacity.red)*257) div (255); //->0..256 + gs:= (word(opacity.green)*257) div (255); //->0..256 + bs:= (word(opacity.blue)*257) div (255); //->0..256 + po1:= pd; + ps:= po1+pint1; + pe:= po1+destimage.length*4; + while po1 < pe do begin + with prgbtriplety(po1)^ do begin + ca1:= prgbtriplety(pm)^.red*rs; + red:= (prgbtriplety(po1)^.red*(256*256-ca1)+ + (prgbtriplety(ps)^.red*ca1)) div (256*256); + ca1:= prgbtriplety(pm)^.green*gs; + green:= (prgbtriplety(po1)^.green*(256*256-ca1)+ + (prgbtriplety(ps)^.green*ca1)) div (256*256); + ca1:= prgbtriplety(pm)^.blue*bs; + blue:= (prgbtriplety(po1)^.blue*(256*256-ca1)+ + (prgbtriplety(ps)^.blue*ca1)) div (256*256); + end; + inc(po1,4); + inc(ps,4); + inc(pm,4); + end; + { + for int1:= 0 to destimage.length - 1 do begin + with rgbtriplety(destimage.pixels[int1]) do begin + red:= (byte(256 - + rgbtriplety(colormaskimage.pixels^[int1]).red) * red + + rgbtriplety(colormaskimage.pixels^[int1]).red * + rgbtriplety(sourceimage.pixels^[int1]).red) div 256); + green:= (byte(255 - + rgbtriplety(colormaskimage.pixels^[int1]).green) * green + + rgbtriplety(colormaskimage.pixels^[int1]).green * + rgbtriplety(sourceimage.pixels^[int1]).green) div byte(255); + blue:= (byte(255 - + rgbtriplety(colormaskimage.pixels^[int1]).blue) * blue + + rgbtriplety(colormaskimage.pixels^[int1]).blue * + rgbtriplety(sourceimage.pixels^[int1]).blue) div byte(255); + end; + end; + } + end; + end; + end; + end; + gui_freeimagemem(colormaskimage.pixels); + deletedc(colormaskdc); + deleteobject(colormaskbmp); + end; + bufferbmpback:= bufferbmp; + gui_imagetopixmap(destimage,pixmapty(bufferbmp),handle); +//{$ifdef mse_debuggdi} +// dec(pixmapcount); +//{$endif} + gui_freeimagemem(destimage.pixels); + gui_freeimagemem(sourceimage.pixels); + if mask <> nil then begin + if maskbmp <> 0 then begin + if nomaskblt then begin + maskdc:= createcompatibledc(0); + selectobject(maskdc,maskbmp); + settextcolor(destdcbefore,$000000); + setbkcolor(destdcbefore,$ffffff); + bitblt(destdcbefore,rect1.x,rect1.y,rect1.cx,rect1.cy, + maskdc,0,0,rasterops3[rop_and]); + settextcolor(handle,$ffffff); + setbkcolor(handle,$000000); + bitblt(handle,0,0,rect1.cx,rect1.cy,maskdc,rect1.x,rect1.y,rasterops3[rop_and]); + bitblt(destdcbefore,rect1.x,rect1.y,rect1.cx,rect1.cy, + handle,0,0,rasterops3[rop_or]); + deletedc(maskdc); + end + else begin + maskblt(destdcbefore,rect1.x,rect1.y, + rect1.cx,rect1.cy,handle,0,0,maskbmp,0,0, + makerop4(rasterops3[rop_nop],srccopy)); + end; + deleteobject(maskbmp); + end + else begin + if nomaskblt then begin + tcanvas1(mask.canvas).checkgcstate([cs_gc]); + smaskdc:= tcanvas1(mask.canvas).fdrawinfo.gc.handle; + settextcolor(destdcbefore,$000000); + setbkcolor(destdcbefore,$ffffff); + bitblt(destdcbefore,rect1.x,rect1.y,rect1.cx,rect1.cy, + smaskdc,sourcerect^.x-destrect^.x, + sourcerect^.y-destrect^.y,rasterops3[rop_and]); + settextcolor(handle,$ffffff); + setbkcolor(handle,$000000); + bitblt(handle,0,0,destrect^.cx,destrect^.cy,smaskdc, + sourcerect^.x-destrect^.x,sourcerect^.y-destrect^.y, + rasterops3[rop_and]); + bitblt(destdcbefore,rect1.x,rect1.y,rect1.cx,rect1.cy, + handle,0,0,rasterops3[rop_or]); + end + else begin + maskblt(destdcbefore,rect1.x,rect1.y, + rect1.cx,rect1.cy,handle, + 0,0,tsimplebitmap1(mask).handle, + sourcerect^.x-destrect^.x,sourcerect^.y-destrect^.y, + makerop4(rasterops3[rop_nop],srccopy)); + end; + end; + end + else begin + bitblt(destdcbefore,rect1.x,rect1.y,rect1.cx, + rect1.cy,handle,0,0,srccopy); + end; + deletedc(handle); +// deleteobject(bufferbmp); + gui_freepixmap(bufferbmp); + deleteobject(bufferbmpback); + handle:= destdcbefore; + destrect^.pos:= destpointbefore; + deletedc(destbmpdc); + deleteobject(destbmp); + end; + mask:= maskbefore; + end; +end; + +procedure gdi_getimage(var drawinfo: drawinfoty); //gdifunc +begin + //dummy +end; + +procedure gdi_fonthasglyph(var drawinfo: drawinfoty); +begin + with drawinfo,fonthasglyph do begin + hasglyph:= true; + end; +end; + +var + defaultfontinfo: logfont; +type + charsetinfoty = record + name: string; + code: integer; + end; + charsetinfoaty = array[0..18] of charsetinfoty; + +const + charsets: charsetinfoaty = ( + (name: 'ANSI'; code: 0), + (name: 'DEFAULT'; code: 1), + (name: 'SYMBOL'; code: 2), + (name: 'SHIFTJIS'; code: $80), + (name: 'HANGEUL'; code: 129), + (name: 'GB2312'; code: 134), + (name: 'CHINESEBIG5'; code: 136), + (name: 'OEM'; code: 255), + (name: 'JOHAB'; code: 130), + (name: 'HEBREW'; code: 177), + (name: 'ARABIC'; code: 178), + (name: 'GREEK'; code: 161), + (name: 'TURKISH'; code: 162), + (name: 'VIETNAMESE'; code: 163), + (name: 'THAI'; code: 222), + (name: 'EASTEUROPE'; code: 238), + (name: 'RUSSIAN'; code: 204), + (name: 'MAC'; code: 77), + (name: 'BALTIC'; code: 186)); + +type + pboolean = ^boolean; + +{$ifdef FPC} +function fontenumcallback(var _para1:ENUMLOGFONTEX; + var _para2:NEWTEXTMETRICEX; _para3:longint; _para4:LPARAM):longint; stdcall; +{$else} +function fontenumcallback(var _para1:ENUMLOGFONTEX; + var _para2:TNEWTEXTMETRICEXa; _para3:longint; _para4:LPARAM):longint; stdcall; +{$endif} +begin + pboolean(_para4)^:= true; + result:= 0; +end; + + +procedure gdi32initdefaultfont; +var + dc1: hdc; + bo1: boolean; +begin + fillchar(defaultfontinfo,sizeof(defaultfontinfo),0); + defaultfontinfo.lfHeight:= -11; + bo1:= false; + defaultfontinfo.lfFaceName:= defaultfontname; + dc1:= getdc(0); + {$ifdef FPC} + enumfontfamiliesex(dc1,@defaultfontinfo,@fontenumcallback,ptruint(@bo1),0); + {$else} + enumfontfamiliesex(dc1,defaultfontinfo,@fontenumcallback,ptruint(@bo1),0); + {$endif} + if not bo1 then begin + defaultfontinfo.lfFaceName:= 'MS Sans Serif'; + end; + releasedc(0,dc1); +end; + +function dogetfont(var drawinfo: drawinfoty; const ahighres: boolean): boolean; + +var + dc1: hdc; //printer gc is invalid -> create temporary gc + fontbefore: hfont; + font1: hfont; + + procedure closedc; + begin + selectobject(dc1,fontbefore); + releasedc(0,dc1); + with drawinfo.getfont.fontdata^ do begin + if (font1 <> font) and (font1 <> fonthighres) then begin + deleteobject(font1); + end; + end; + end; + +var + fontinfo1: logfont; +// textmetricsw: ttextmetricw; + textmetricsa: ttextmetrica; + str1: string; + int1: integer; +// ar1: array[0..255] of abc; + height1,width1: integer; + rea1: real; + +label + endlab; + +begin + result:= false; + with drawinfo.getfont.fontdata^ do begin + height1:= (h.d.height + fontsizeroundvalue) shr fontsizeshift; + width1:= (h.d.width + fontsizeroundvalue) shr fontsizeshift; + fontinfo1:= defaultfontinfo; + with fontinfo1 do begin + if height1 <> 0 then begin + lfheight:= -height1; //use character height + end; + if h.d.xscale = 1 then begin + if width1 <> 0 then begin + lfwidth:= (width1 + 5) div 10; + if lfwidth = 0 then begin + lfwidth:= 1; + end; + lfoutprecision:= out_tt_only_precis; + end; + end; + if fs_bold in h.d.style then begin + lfweight:= fw_bold; + end; + if fs_italic in h.d.style then begin + lfitalic:= 1; + end; + if (h.d.pitchoptions <> []) or (h.d.familyoptions <> []) then begin + lffacename[0]:= #0; + end + else begin + if (h.name <> '') then begin + strlcopy(@lffacename,pchar(h.name),sizeof(lffacename)-1); + end; + end; + if h.charset <> '' then begin + str1:= uppercase(h.charset); + for int1:= 0 to high(charsets) do begin + if charsets[int1].name = str1 then begin + lfcharset:= charsets[int1].code; + break; + end; + end; + end; + if foo_fixed in h.d.pitchoptions then begin + lfpitchandfamily:= lfpitchandfamily or fixed_pitch; + end + else begin + if foo_proportional in h.d.pitchoptions then begin + lfpitchandfamily:= lfpitchandfamily or variable_pitch; + end + end; + if foo_helvetica in h.d.familyoptions then begin + lfpitchandfamily:= lfpitchandfamily or ff_swiss; + end + else begin + if foo_roman in h.d.familyoptions then begin + lfpitchandfamily:= lfpitchandfamily or ff_roman; + end + else begin + if foo_script in h.d.familyoptions then begin + lfpitchandfamily:= lfpitchandfamily or ff_script; + end + else begin + if foo_decorative in h.d.familyoptions then begin + lfpitchandfamily:= lfpitchandfamily or ff_decorative; + end + end; + end; + end; + if (foo_antialiased2 in h.d.antialiasedoptions) then begin + if cancleartype then begin + lfquality:= cleartype_quality; + end + else begin + lfquality:= antialiased_quality; + end; + end + else begin + if foo_antialiased in h.d.antialiasedoptions then begin + lfquality:= antialiased_quality; + end + else begin + if foo_nonantialiased in h.d.antialiasedoptions then begin + lfquality:= nonantialiased_quality; + end; + end; + end; + if h.d.rotation <> 0 then begin + int1:= round(h.d.rotation*((10*360)/(2*pi))); + lfescapement:= int1; + lforientation:= int1; + lfoutprecision:= out_tt_only_precis; + end; + if ahighres then begin + lfheight:= lfheight * highresfontfakt; + lfwidth:= lfwidth * highresfontfakt; + end; + + font1:= createfontindirect({$ifdef FPC}@{$endif}fontinfo1); + end; + if font1 = 0 then begin + fontinfo1.lfFaceName:= defaultfontinfo.lfFaceName; + font1:= createfontindirect({$ifdef FPC}@{$endif}fontinfo1); + if font1 = 0 then begin + if ahighres then begin + exit; //no highres font available + end; + font1:= createfontindirect({$ifdef FPC}@{$endif}defaultfontinfo); + end; + end; + if font1 <> 0 then begin + dc1:= getdc(0); + fontbefore:= selectobject(dc1,font1); + if not gettextmetricsa(dc1,{$ifdef FPC}@{$endif}textmetricsa) then begin + goto endlab; + end; + if h.d.xscale <> 1 then begin + closedc; + int1:= h.d.width; + rea1:= h.d.xscale; + with win32fontdataty(platformdata) do begin + if ahighres then begin + fontinfo1.lfwidth:= ((xwidth+5) div 10) shl highresfontshift; + //round up + fonthighres:= createfontindirect({$ifdef FPC}@{$endif}fontinfo1); + result:= fonthighres <> 0; + end + else begin + xwidth:= round(h.d.xscale * textmetricsa.tmavecharwidth*10); + h.d.width:= xwidth shl fontsizeshift; + h.d.xscale:= 1.0; + result:= dogetfont(drawinfo,false); + end; + end; + h.d.width:= int1; //restore + h.d.xscale:= rea1; + exit; + end; + with win32fontdataty(platformdata) do begin + if ahighres then begin + fonthighres:= font1; + goto endlab; + end; + font:= font1; + ascent:= textmetricsa.tmAscent; + descent:= textmetricsa.tmDescent; + linespacing:= textmetricsa.tmheight + textmetricsa.tmexternalleading; + realheight:= textmetricsa.tmheight; + overhang:= textmetricsa.tmOverhang; + if textmetricsa.tmpitchandfamily and tmpf_truetype <> 0 then begin + caretshift:= 0; + end + else begin + caretshift:= 1; + end; + if iswin95 then begin + new(charwidths); + (* + if false {getcharabcwidths(dc1,0,255,ar1)} then begin + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + charwidths^[int1]:= abca + integer(abcb) + abcc; + end; + end; + end + else begin //no truetype font + *) + if not getcharwidthw(dc1,0,255,charwidths^) then begin + dispose(charwidths); + goto endlab; + end; + if Overhang <> 0 then begin + for int1:= 0 to high(charwidths^) do begin + dec(charwidths^[int1],Overhang); + end; + end; +// end; + end + else begin + { + new(charwidths); + if not getcharwidth32w(dc1,0,255,charwidths^) then begin + dispose(charwidths); + closedc; + exit; + end; + } + end; + end; + result:= true; + end; + end; +endlab: +{$ifdef mse_debuggdi} + if result then begin + inc(fontcount); + end; +{$endif} + closedc; +end; + +procedure gdi_getfonthighres(var drawinfo: drawinfoty); +begin + dogetfont(drawinfo,true); +end; + +procedure gdi_getfont(var drawinfo: drawinfoty); +begin + drawinfo.getfont.ok:= dogetfont(drawinfo,false); +end; + +procedure gdi_freefontdata(var drawinfo: drawinfoty); +begin + with drawinfo.getfont.fontdata^,win32fontdataty(platformdata) do begin + if charwidths <> nil then begin + dispose(charwidths); + end; + if font <> 0 then begin +{$ifdef mse_debuggdi} + dec(fontcount); +{$endif} + deleteobject(font); + end; + if fonthighres <> 0 then begin +{$ifdef mse_debuggdi} + dec(fontcount); +{$endif} + deleteobject(fonthighres); + end; + end; +end; + +procedure gdi_gettext16width(var drawinfo: drawinfoty); +label //todo: kerning? + endlab; +var + int1,int2: integer; + po1: pmsechar; + wo1: word; + widths: pcharwidthsty; + overha: integer; + fh1: hfont; + gc1: hdc; + gcpresults: tgcpresultsw; +begin + with drawinfo.gettext16width do begin + if drawinfo.gc.handle = invalidgchandle then begin + gc1:= getdc(0); //use default dc + end + else begin + gc1:= drawinfo.gc.handle; + end; + fh1:= selectobject(gc1,fontdata^.font); + if fh1 <> 0 then begin + if not iswin95 then begin + fillchar(gcpresults,sizeof(gcpresults),0); + gcpresults.lstructsize:= sizeof(gcpresults); + gcpresults.nglyphs:= count; + {$ifdef FPC} + result:= getcharacterplacementw(gc1,text,count,0,@gcpresults,0) and $ffff; + {$else} + result:= getcharacterplacementw(gc1,text,count,0,gcpresults,0) and $ffff; + {$endif} + end + else begin + result:= 0; + int1:= count; + po1:= text; + with win32fontdataty(fontdata^.platformdata) do begin + widths:= charwidths; + overha:= overhang; + end; + while int1 > 0 do begin + wo1:= word(po1^); + if wo1 < 256 then begin + inc(result,widths^[wo1]); + end + else begin + int2:= 0; + if iswin95 then begin + if not getcharwidthw(gc1,wo1,wo1,int2) then begin + result:= -1; + goto endlab; + end; + dec(int2,overha); + end + else begin + if not getcharwidth32w(gc1,wo1,wo1,int2) then begin + result:= -1; + goto endlab; + end; + end; + inc(result,int2); + end; + dec(int1); + inc(po1); + end; + end; + end + else begin + result:= -1; + end; +endlab: + if fh1 <> 0 then begin + selectobject(gc1,fh1); + end; + if drawinfo.gc.handle = invalidgchandle then begin + releasedc(0,gc1); + end; + end; +end; + +procedure gdi_getchar16widths(var drawinfo: drawinfoty); +label //todo: kerning? + endlab; +var + int1,int2: integer; + po1,pe: pmsechar; + po2,pde: {$ifdef FPC}objpas.{$endif}pinteger; + wo1: word; + widths: pcharwidthsty; + overha: integer; + ahandle: thandle; + gc1: hdc; + gcpresults: tgcpresultsw; +// fo1: hfont; + hires: boolean; +begin +// result:= gde_fontmetrics; + with drawinfo.getchar16widths do begin + hires:= (df_highresfont in drawinfo.gc.drawingflags) and + (fontdata^.fonthighres <> 0); + if (drawinfo.gc.handle = invalidgchandle) or hires then begin + gc1:= getdc(0); //use default dc + end + else begin + gc1:= drawinfo.gc.handle; + end; + if hires then begin + ahandle:= selectobject(gc1,fontdata^.fonthighres); + end + else begin + ahandle:= selectobject(gc1,fontdata^.font); + end; + if ahandle <> 0 then begin + if not iswin95 then begin + fillchar(gcpresults,sizeof(gcpresults),0); + gcpresults.lstructsize:= sizeof(gcpresults); + gcpresults.lpdx:= pointer(resultpo); + gcpresults.nglyphs:= count; + {$ifdef FPC} + getcharacterplacementw(gc1,text,count,0,@gcpresults,0); + {$else} + getcharacterplacementw(gc1,text,count,0,gcpresults,0); + {$endif} + if hires then begin + po2:= resultpo; + int2:= highresfontfakt div 2; //round up + for int1:= 0 to count - 1 do begin + int2:= int2 + po2^; + po2^:= int2 shr highresfontshift; + int2:= int2 and highresfontmask; + inc(po2); + end; + end; + int1:= count - gcpresults.nglyphs; + if int1 > 0 then begin //has surrogate pairs, + //insert dummy 0's for low pair part + //not tested! + po1:= text; + pe:= text + count; + po2:= resultpo; + pde:= po2 + count; + while (po1 < pe) and (int1 > 0) do begin + if card16(po1^) and $fc00 = $d800 then begin + inc(po1); + if card16(po1^) and $fc00 = $dc00 then begin + inc(po2); + move(po2^,(po2+1)^,((pde-po2)-int1)*sizeof(po2^)); + po2^:= 0; + dec(int1); + end; + end; + inc(po1); + inc(po2); + end; + end; + end + else begin + po1:= text; + po2:= resultpo; + with win32fontdataty(fontdata^.platformdata) do begin + widths:= charwidths; + overha:= overhang; + end; + int1:= count; + while int1 > 0 do begin + wo1:= word(po1^); + if wo1 < 256 then begin + po2^:= widths^[wo1]; + end + else begin + if iswin95 then begin + if not getcharwidthw(gc1,wo1,wo1,po2^) then begin + goto endlab; + end; + dec(po2^,overha); + end + else begin + if not getcharwidth32w(gc1,wo1,wo1,po2^) then begin + goto endlab; + end; + end; + end; + inc(po1); + inc(po2); + dec(int1); + end; + end; +// selectobject(gc1,ahandle); +// result:= gde_ok; + end; + end; + +endlab: + if ahandle <> 0 then begin + selectobject(gc1,ahandle); + end; + if (drawinfo.gc.handle = invalidgchandle) or hires then begin + releasedc(0,gc1); + end; +end; + +procedure gdi_getfontmetrics(var drawinfo: drawinfoty); +var + data: abc; + bo1: boolean; + ahandle: thandle; + +begin +// result:= gde_fontmetrics; + with drawinfo,drawinfo.getfontmetrics do begin + ahandle:= selectobject(gc.handle,fontdata^.font); + if ahandle <> 0 then begin + fillchar(data,sizeof(data),0); + if iswin95 then begin + bo1:= getcharabcwidthsw(gc.handle,longword(char),longword(char),data); + { + if ord(char) < 256 then begin + bo1:= getcharabcwidthsa(gc.handle,longword(char),longword(char),data); + end + else begin + bo1:= false; + end; + } + end + else begin + bo1:= getcharabcwidthsw(gc.handle,longword(char),longword(char),data); + end; + if not bo1 then begin + if iswin95 then begin + bo1:= getcharwidthw(drawinfo.gc.handle,longword(char),longword(char),data.abcb); + dec(data.abcB,win32fontdataty(fontdata^.platformdata).overhang); + end + else begin + bo1:= getcharwidth32w(drawinfo.gc.handle,longword(char),longword(char),data.abcb); + end; + data.abca:= 0; + data.abcC:= 0; + end; + if bo1 then begin + with resultpo^ do begin + leftbearing:= data.abca; + width:= data.abca + integer(data.abcb) + data.abcc; + rightbearing:= data.abcc; + end; + selectobject(gc.handle,ahandle); +// result:= gde_ok; + end; + end; + end; +end; + +procedure init; +var + brushinfo: tlogbrush; +begin + nullpen:= createpen(ps_null,0,0); + fillchar(brushinfo,sizeof(brushinfo),0); + brushinfo.lbStyle:= bs_null; + nullbrush:= createbrushindirect(brushinfo); +end; + +procedure deinit; +begin + deleteobject(nullpen); + nullpen:= 0; + deleteobject(nullbrush); + nullbrush:= 0; +{ + if graypalette <> 0 then begin + deleteobject(graypalette); + graypalette:= 0; + end; +} + if fhasgdiplus then begin + releasegdiplus; + end; +end; + +const + gdifunctions: gdifunctionaty = ( + {$ifdef FPC}@{$endif}gdi_creategc, + {$ifdef FPC}@{$endif}gdi_destroygc, + {$ifdef FPC}@{$endif}gdi_changegc, + {$ifdef FPC}@{$endif}gdi_createpixmap, + {$ifdef FPC}@{$endif}gdi_pixmaptoimage, + {$ifdef FPC}@{$endif}gdi_imagetopixmap, + {$ifdef FPC}@{$endif}gdi_getcanvasclass, + {$ifdef FPC}@{$endif}gdi_endpaint, + {$ifdef FPC}@{$endif}gdi_flush, + {$ifdef FPC}@{$endif}gdi_movewindowrect, + {$ifdef FPC}@{$endif}gdi_drawlines, + {$ifdef FPC}@{$endif}gdi_drawlinesegments, + {$ifdef FPC}@{$endif}gdi_drawellipse, + {$ifdef FPC}@{$endif}gdi_drawarc, + {$ifdef FPC}@{$endif}gdi_fillrect, + {$ifdef FPC}@{$endif}gdi_fillellipse, + {$ifdef FPC}@{$endif}gdi_fillarc, + {$ifdef FPC}@{$endif}gdi_fillpolygon, +// {$ifdef FPC}@{$endif}gdi_drawstring, + {$ifdef FPC}@{$endif}gdi_drawstring16, + {$ifdef FPC}@{$endif}gdi_setcliporigin, + {$ifdef FPC}@{$endif}gdi_createemptyregion, + {$ifdef FPC}@{$endif}gdi_createrectregion, + {$ifdef FPC}@{$endif}gdi_createrectsregion, + {$ifdef FPC}@{$endif}gdi_destroyregion, + {$ifdef FPC}@{$endif}gdi_copyregion, + {$ifdef FPC}@{$endif}gdi_moveregion, + {$ifdef FPC}@{$endif}gdi_regionisempty, + {$ifdef FPC}@{$endif}gdi_regionclipbox, + {$ifdef FPC}@{$endif}gdi_regsubrect, + {$ifdef FPC}@{$endif}gdi_regsubregion, + {$ifdef FPC}@{$endif}gdi_regaddrect, + {$ifdef FPC}@{$endif}gdi_regaddregion, + {$ifdef FPC}@{$endif}gdi_regintersectrect, + {$ifdef FPC}@{$endif}gdi_regintersectregion, + {$ifdef FPC}@{$endif}gdi_copyarea, + {$ifdef FPC}@{$endif}gdi_getimage, + {$ifdef FPC}@{$endif}gdi_fonthasglyph, + {$ifdef FPC}@{$endif}gdi_getfont, + {$ifdef FPC}@{$endif}gdi_getfonthighres, + {$ifdef FPC}@{$endif}gdi_freefontdata, + {$ifdef FPC}@{$endif}gdi_gettext16width, + {$ifdef FPC}@{$endif}gdi_getchar16widths, + {$ifdef FPC}@{$endif}gdi_getfontmetrics +); + +//var +// gdinumber: integer; + +function gdi32getgdifuncs: pgdifunctionaty; +begin + result:= @gdifunctions; +end; +{ +function gdi32getgdinum: integer; +begin + result:= gdinumber; +end; + +initialization + gdinumber:= registergdi(gdi32getgdifuncs); +} +end. diff --git a/mseide-msegui/lib/common/graphics/msegdiplus.pas b/mseide-msegui/lib/common/graphics/msegdiplus.pas new file mode 100644 index 0000000..71a294e --- /dev/null +++ b/mseide-msegui/lib/common/graphics/msegdiplus.pas @@ -0,0 +1,495 @@ +{ MSEgui Copyright (c) 2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msegdiplus; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + windows,msestrings,msectypes,sysutils,msetypes; + +const + gdipluslib: array[0..0] of filenamety = ('gdiplus.dll'); + +type +{$packrecords c}{$packenum 4} + + GpStatus = ( + Ok = 0, + GenericError = 1, + InvalidParameter = 2, + OutOfMemory = 3, + ObjectBusy = 4, + InsufficientBuffer = 5, + NotImplemented = 6, + Win32Error = 7, + WrongState = 8, + Aborted = 9, + FileNotFound = 10, + ValueOverflow = 11, + AccessDenied = 12, + UnknownImageFormat = 13, + FontFamilyNotFound = 14, + FontStyleNotFound = 15, + NotTrueTypeFont = 16, + UnsupportedGdiplusVersion = 17, + GdiplusNotInitialized = 18, + PropertyNotFound = 19, + PropertyNotSupported = 20 + ); + +const + gdipluserrormessages: array[GpStatus] of string = ( + 'Ok', + 'GenericError', + 'InvalidParameter', + 'OutOfMemory', + 'ObjectBusy', + 'InsufficientBuffer', + 'NotImplemented', + 'Win32Error', + 'WrongState', + 'Aborted', + 'FileNotFound', + 'ValueOverflow', + 'AccessDenied', + 'UnknownImageFormat', + 'FontFamilyNotFound', + 'FontStyleNotFound', + 'NotTrueTypeFont', + 'UnsupportedGdiplusVersion', + 'GdiplusNotInitialized', + 'PropertyNotFound', + 'PropertyNotSupported' + ); +type + egdiplus = class(exception) + public + constructor create(const aerror: GpStatus); + end; + + DebugEventLevel = ( + DebugEventLevelFatal, + DebugEventLevelWarning + ); + + DebugEventProc = procedure(level: DebugEventLevel; + message: pchar); stdcall; + GdiplusStartupInput = record + GdiplusVersion: cUINT32; + DebugEventCallback: DebugEventProc; + SuppressBackgroundThread: BOOL; + SuppressExternalCodecs: BOOL; + end; + pGdiplusStartupinput = ^GdiplusStartupinput; + + NotificationHookProc = function(token: ppointer): GpStatus; stdcall; + NotificationUnhookProc = procedure(token: pointer); stdcall; + + GdiplusStartupOutput = record + NotificationHook: NotificationHookProc; + NotificationUnhook: NotificationUnhookProc; + end; + pGdiplusStartupoutput = ^GdiplusStartupoutput; + + GpGraphics = record end;//opaque + PGpGraphics = ^GpGraphics; + PPGpGraphics = ^PGpGraphics; + + INT = cint; + REAL = single; + GpREAL = REAL; + pReal = ^REAL; + ARGB = uint32; + pARGB = ^ARGB; + GpPoint = record + X: INT; + Y: INT; + end; + pGpPoint = ^GpPoint; + +const + PaletteFlagsHasAlpha = $0001; + PaletteFlagsGrayScale = $0002; + PaletteFlagsHalftone = $0004; + +type + ColorPalette = record + Flags: UINT; // Palette flags + Count: UINT; // Number of color entries + Entries: array[0..0] of ARGB; // Palette color entries + end; + pColorPalette = ^ColorPalette; + + GpImage = record end; + pGpImage = ^GpImage; + GpBitmap = record end; + pGpBitmap = ^GpBitmap; + ppGpBitmap = ^pGpBitmap; + GpTexture = record end; + pGpTexture = ^GpTexture; + ppGpTexture = ^pGpTexture; + GpBrush = record end; + pGpBrush = ^GpBrush; + GpSolidFill = record end; + pGpSolidFill = ^GpSolidFill; + ppGpSolidFill = ^pGpSolidFill; + GpPen = record end; + pGpPen = ^GpPen; + ppGpPen = ^pGpPen; + GpPath = record end; + pGpPath = ^GpPath; + ppGpPath = ^pGpPath; + GpRegion = record end; + pGpRegion = ^GpRegion; + ppGpRegion = ^pGpRegion; + + QualityMode = ( + QualityModeInvalid = -1, + QualityModeDefault = 0, + QualityModeLow = 1, // Best performance + QualityModeHigh = 2 // Best rendering quality + ); + pQualityMode = ^QualityMode; + + SmoothingMode = ( + SmoothingModeInvalid = ord(QualityModeInvalid), + SmoothingModeDefault = ord(QualityModeDefault), + SmoothingModeHighSpeed = ord(QualityModeLow), + SmoothingModeHighQuality = ord(QualityModeHigh), + SmoothingModeNone, + SmoothingModeAntiAlias + ); + pSmoothingMode = ^SmoothingMode; + + WrapMode = ( + WrapModeTile, // 0 + WrapModeTileFlipX, // 1 + WrapModeTileFlipY, // 2 + WrapModeTileFlipXY, // 3 + WrapModeClamp // 4 + ); + + GpUnit = ( + UnitWorld, // 0 -- World coordinate (non-physical unit) + UnitDisplay, // 1 -- Variable -- for PageTransform only + UnitPixel, // 2 -- Each unit is one device pixel. + UnitPoint, // 3 -- Each unit is a printer's point, or 1/72 inch. + UnitInch, // 4 -- Each unit is 1 inch. + UnitDocument, // 5 -- Each unit is 1/300 inch. + UnitMillimeter // 6 -- Each unit is 1 millimeter. + ); + GpMatrixOrder = ( + MatrixOrderPrepend = 0, + MatrixOrderAppend = 1 +); + + GpFillMode = ( + FillModeAlternate, // 0 + FillModeWinding // 1 + ); + + GpPenAlignment = ( + PenAlignmentCenter = 0, + PenAlignmentInset = 1 +); + GpLineCap = ( + LineCapFlat = 0, + LineCapSquare = 1, + LineCapRound = 2, + LineCapTriangle = 3, + + LineCapNoAnchor = $10, // corresponds to flat cap + LineCapSquareAnchor = $11, // corresponds to square cap + LineCapRoundAnchor = $12, // corresponds to round cap + LineCapDiamondAnchor = $13, // corresponds to triangle cap + LineCapArrowAnchor = $14, // no correspondence + + LineCapCustom = $ff // custom cap + +// LineCapAnchorMask = 0xf0 // mask to check for anchor or not. + ); + + GpDashCap = ( + DashCapFlat = 0, + DashCapRound = 2, + DashCapTriangle = 3 + ); + + GpDashStyle = ( + DashStyleSolid, // 0 + DashStyleDash, // 1 + DashStyleDot, // 2 + DashStyleDashDot, // 3 + DashStyleDashDotDot, // 4 + DashStyleCustom // 5 +); + + GpLineJoin = ( + LineJoinMiter = 0, + LineJoinBevel = 1, + LineJoinRound = 2, + LineJoinMiterClipped = 3 + ); + + GpCombineMode = ( + CombineModeReplace, // 0 + CombineModeIntersect, // 1 + CombineModeUnion, // 2 + CombineModeXor, // 3 + CombineModeExclude, // 4 + CombineModeComplement // 5 (Exclude From) + ); + + GpFlushIntention = ( + FlushIntentionFlush = 0, // Flush all batched rendering operations + FlushIntentionSync = 1 // Flush all batched rendering operations + // and wait for them to complete + ); + + GpPixelOffsetMode = ( + PixelOffsetModeInvalid = ord(QualityModeInvalid), + PixelOffsetModeDefault = ord(QualityModeDefault), + PixelOffsetModeHighSpeed = ord(QualityModeLow), + PixelOffsetModeHighQuality = ord(QualityModeHigh), + PixelOffsetModeNone, // No pixel offset + PixelOffsetModeHalf // Offset by -0.5, -0.5 for fast anti-alias perf +); +var + GdiplusStartup: function(token: ppointer; input: pGdiplusStartupInput; + output: pGdiplusStartupOutput): GpStatus; stdcall; + GdiplusShutdown: function(token: pointer): GpStatus; stdcall; + + GdipFree: function(ptr: pointer): GpStatus; stdcall; + GdipCreateFromHDC: function(hdc_: HDC; + graphics: PPGpGraphics): GpStatus; stdcall; + GdipCreateFromHDC2: function(hdc_: HDC; hDevice: HANDLE; + graphics: ppGpGraphics): GpStatus; stdcall; + GdipCreateFromHWND: function(hwnd_: HWND; + graphics: ppGpGraphics): GpStatus; stdcall; + GdipDeleteGraphics: function(graphics: PGpGraphics): GpStatus; stdcall; + GdipFlush: function(graphics: pGpGraphics; + intention: GpFlushIntention): Gpstatus; stdcall; + GdipTranslateWorldTransform: function(graphics: pGpGraphics; + dx: REAL; dy: REAL; order: GpMatrixOrder): GpStatus; stdcall; + + GdipSetSmoothingMode: function(graphics: pGpGraphics; + smoothingMode_: SmoothingMode): GpStatus; stdcall; + GdipGetSmoothingMode: function(graphics: pGpGraphics; + smoothingMode: pSmoothingMode): GpStatus; stdcall; + GdipSetPixelOffsetMode: function(graphics: pGpGraphics; + pixelOffsetMode: GpPixelOffsetMode): GpStatus; stdcall; + GdipSetClipRegion: function(graphics: pGpGraphics; region: pGpRegion; + combineMode_: GpCombineMode): GpStatus; stdcall; + GdipResetClip: function(graphics: pGpGraphics): GpStatus; stdcall; + + GdipDeleteBrush: function(brush: pGpBrush): GpStatus; stdcall; + GdipCreateSolidFill: function(color: ARGB; + brush: ppGpSolidFill): GpStatus; stdcall; + GdipSetSolidFillColor: function(brush: pGpSolidFill; + color: ARGB): GpStatus; stdcall; + GdipGetSolidFillColor: function(brush: pGpSolidFill; + color: pARGB): GpStatus; stdcall; + + GdipFillRectangleI: function(graphics: pGpGraphics; brush: pGpBrush; + x: INT; y: INT; width: INT; height: INT): GpStatus; stdcall; + GdipFillPolygon2I: function(graphics: pGpGraphics; brush: pGpBrush; + points: pGpPoint; count: INT): GpStatus; stdcall; + + GdipCreatePen1: function(color: ARGB; width: REAL; unit_: GpUnit; + pen: ppGpPen): GpStatus; stdcall; + GdipDeletePen: function(pen: pGpPen): GpStatus; stdcall; + GdipSetPenMode: function(pen: pGpPen; + penMode: GpPenAlignment): GpStatus; stdcall; + GdipSetPenWidth: function(pen: pGpPen; width: REAL): GpStatus; stdcall; + GdipGetPenWidth: function(pen: pGpPen; width: pREAL): GpStatus; stdcall; + GdipSetPenColor: function(pen: pGpPen; argb_: ARGB): GpStatus; stdcall; + GdipGetPenColor: function(pen: pGpPen; argb_: pARGB): GpStatus; stdcall; + GdipSetPenBrushFill: function(pen: pGpPen; brush: pGpBrush): GpStatus; stdcall; + GdipSetPenLineCap197819: function(pen: pGpPen; startCap: GpLineCap; + endCap: GpLineCap; dashCap: GpDashCap): GpStatus; stdcall; + GdipSetPenLineJoin: function(pen: pGpPen; + lineJoin: GpLineJoin): GpStatus; stdcall; + GdipSetPenDashArray: function(pen: pGpPen; dash: pREAL; + count: INT): GpStatus; stdcall; + GdipSetPenDashOffset: function(pen: pGpPen; offset: REAL): GpStatus; stdcall; + GdipSetPenDashStyle: function(pen: pGpPen; + dashstyle: GpDashStyle): GpStatus; stdcall; + + GdipDrawLinesI: function(graphics: pGpGraphics; pen: pGpPen; + points: pGpPoint; count: INT): GpStatus; stdcall; + GdipDrawPolygonI: function(graphics: pGpGraphics; pen: pGpPen; + points: pGpPoint; count: INT): GpStatus; stdcall; + GdipDrawEllipseI: function(graphics: pGpGraphics; pen: pGpPen; x: INT; y: INT; + width: INT; height: INT): GpStatus; stdcall; + GdipFillEllipseI: function(graphics: pGpGraphics; brush: pGpBrush; + x: INT; y: INT; width: INT; height: INT): GpStatus; stdcall; + GdipDrawArcI: function(graphics: pGpGraphics; pen: pGpPen; x: INT; y: INT; + width: INT; heigh: INT; + startAngle: REAL; sweepAngle: REAL): GpStatus; stdcall; + GdipFillPieI: function(graphics: pGpGraphics; brush: pGpBrush; x: INT; y: INT; + width: INT; height: INT; startAngle: REAL; + sweepAngle: REAL): GpStatus; stdcall; + GdipCreatePath: function(brushMode: GpFillMode; + path: ppGpPath): GpStatus; stdcall; + GdipDeletePath: function(path: pGpPath): GpStatus; stdcall; + GdipStartPathFigure: function(path: pGpPath): GpStatus; stdcall; + GdipClosePathFigure: function(path: pGpPath): GpStatus; stdcall; + GdipAddPathArc: function(path: pGpPath; x: REAL; y: REAL; + width: REAL; height: REAL; + startangle: REAL; sweepangle: REAL): GpStatus; stdcall; + GdipFillPath: function(graphics: pGpGraphics; brush: pGpBrush; + path: pGpPath): GpStatus; stdcall; + GdipCreateRegionHrgn: function(hRgn_: HRGN; + region: ppGpRegion): GpStatus; stdcall; + GdipDeleteRegion: function(region: pGpRegion): GpStatus; stdcall; + GdipResetWorldTransform: function(graphics: pGpGraphics): GpStatus; stdcall; + + GdipDisposeImage: function(image: pGpImage): GpStatus; stdcall; + GdipCreateBitmapFromHBITMAP: function(hbm: HBITMAP; hpal: HPALETTE; + bitmap: ppGpBitmap): GpStatus; stdcall; + GdipSetImagePalette: function(image: pGpImage; + palette: pColorPalette): GpStatus; stdcall; + + GdipCreateTexture: function(image: pGpImage; wrapmode: WrapMode; + texture: ppGpTexture): GpStatus; stdcall; + GdipResetTextureTransform: function (brush: pGpTexture): GpStatus; stdcall; + GdipTranslateTextureTransform: function(brush: pGpTexture; dx: REAL; + dy: REAL; order: GpMatrixOrder): GpStatus; stdcall; + +function initializegdiplus(const sonames: array of filenamety; + const noexception: boolean = false): boolean; + //false if not available +procedure releasegdiplus; +function gdipcheckerror(const aerror: gpstatus): boolean; //true if ok + +implementation +uses + msesys,msedynload; +var + libinfo: dynlibinfoty; + instance: pointer; + +function gdipcheckerror(const aerror: gpstatus): boolean; //true if ok +begin + result:= aerror = ok; + if not result then begin + raise egdiplus.create(aerror); + end; +end; + +procedure initgdiplus(const data: pointer); +var + startupin: gdiplusstartupinput; +// startupout: gdiplusstartupoutput; +begin + fillchar(startupin,sizeof(startupin),0); + startupin.gdiplusversion:= 1; + instance:= nil; + gdipcheckerror(gdiplusstartup(@instance,@startupin,nil{@startupout})); +end; + +procedure deinitgdiplus(const data: pointer); +begin + if instance <> nil then begin + gdiplusshutdown(instance); + instance:= nil; + end; +end; + +function initializegdiplus(const sonames: array of filenamety; + const noexception: boolean = false): boolean; +const + funcs: array[0..54] of funcinfoty = ( + (n: 'GdiplusStartup'; d: @GdiplusStartup), //0 + (n: 'GdiplusShutdown'; d: @GdiplusShutdown), //1 + (n: 'GdipCreateFromHDC'; d: @GdipCreateFromHDC), //2 + (n: 'GdipDeleteGraphics'; d: @GdipDeleteGraphics), //3 + (n: 'GdipDeleteBrush'; d: @GdipDeleteBrush), //4 + (n: 'GdipCreateSolidFill'; d: @GdipCreateSolidFill), //5 + (n: 'GdipSetSolidFillColor'; d: @GdipSetSolidFillColor),//6 + (n: 'GdipGetSolidFillColor'; d: @GdipGetSolidFillColor),//7 + (n: 'GdipFillRectangleI'; d: @GdipFillRectangleI), //8 + (n: 'GdipFillPolygon2I'; d: @GdipFillPolygon2I), //9 + (n: 'GdipSetSmoothingMode'; d: @GdipSetSmoothingMode), //10 + (n: 'GdipGetSmoothingMode'; d: @GdipGetSmoothingMode), //11 + (n: 'GdipDrawLinesI'; d: @GdipDrawLinesI), //12 + (n: 'GdipDrawPolygonI'; d: @GdipDrawPolygonI), //13 + (n: 'GdipCreatePen1'; d: @GdipCreatePen1), //14 + (n: 'GdipDeletePen'; d: @GdipDeletePen), //15 + (n: 'GdipSetPenWidth'; d: @GdipSetPenWidth), //16 + (n: 'GdipGetPenWidth'; d: @GdipGetPenWidth), //17 + (n: 'GdipSetPenColor'; d: @GdipSetPenColor), //18 + (n: 'GdipGetPenColor'; d: @GdipGetPenColor), //19 + (n: 'GdipDrawEllipseI'; d: @GdipDrawEllipseI), //20 + (n: 'GdipFillEllipseI'; d: @GdipFillEllipseI), //21 + (n: 'GdipDrawArcI'; d: @GdipDrawArcI), //22 + (n: 'GdipFillPieI'; d: @GdipFillPieI), //23 + (n: 'GdipCreatePath'; d: @GdipCreatePath), //24 + (n: 'GdipDeletePath'; d: @GdipDeletePath), //25 + (n: 'GdipAddPathArc'; d: @GdipAddPathArc), //26 + (n: 'GdipStartPathFigure'; d: @GdipStartPathFigure), //27 + (n: 'GdipClosePathFigure'; d: @GdipClosePathFigure), //28 + (n: 'GdipAddPathArc'; d: @GdipAddPathArc), //29 + (n: 'GdipFillPath'; d: @GdipFillPath), //30 + (n: 'GdipSetPenLineCap197819'; d: @GdipSetPenLineCap197819), //31 + (n: 'GdipSetPenLineJoin'; d: @GdipSetPenLineJoin), //32 + (n: 'GdipSetPenDashArray'; d: @GdipSetPenDashArray), //33 + (n: 'GdipSetPenDashOffset'; d: @GdipSetPenDashOffset), //34 + (n: 'GdipSetPenDashStyle'; d: @GdipSetPenDashStyle), //35 + (n: 'GdipCreateRegionHrgn'; d: @GdipCreateRegionHrgn), //36 + (n: 'GdipSetClipRegion'; d: @GdipSetClipRegion), //37 + (n: 'GdipDeleteRegion'; d: @GdipDeleteRegion), //38 + (n: 'GdipFlush'; d: @GdipFlush), //39 + (n: 'GdipResetClip'; d: @GdipResetClip), //40 + (n: 'GdipCreateFromHDC2'; d: @GdipCreateFromHDC2), //41 + (n: 'GdipCreateFromHWND'; d: @GdipCreateFromHWND), //42 + (n: 'GdipSetPixelOffsetMode'; d: @GdipSetPixelOffsetMode),//43 + (n: 'GdipSetPenMode'; d: @GdipSetPenMode), //44 + (n: 'GdipTranslateWorldTransform'; d: @GdipTranslateWorldTransform),//45 + (n: 'GdipResetWorldTransform'; d: @GdipResetWorldTransform),//46 + (n: 'GdipDisposeImage'; d: @GdipDisposeImage), //47 + (n: 'GdipCreateBitmapFromHBITMAP'; d: @GdipCreateBitmapFromHBITMAP),//48 + (n: 'GdipCreateTexture'; d: @GdipCreateTexture),//49 + (n: 'GdipResetTextureTransform'; d: @GdipResetTextureTransform),//50 + (n: 'GdipTranslateTextureTransform'; d: @GdipTranslateTextureTransform),//51 + (n: 'GdipSetPenBrushFill'; d: @GdipSetPenBrushFill),//52 + (n: 'GdipFree'; d: @GdipFree),//53 + (n: 'GdipSetImagePalette'; d: @GdipSetImagePalette)//54 + ); +// (n: ''; d: @),// +const + errormessage = 'Can not load gdi+ library. '; +begin + result:= initializedynlib(libinfo,sonames,gdipluslib,funcs,[],errormessage, + @initgdiplus,noexception); +end; + +procedure releasegdiplus; +begin + releasedynlib(libinfo,@deinitgdiplus); +end; + +{ egdiplus } + +constructor egdiplus.create(const aerror: GpStatus); +var + str1: string; +begin + str1:= 'gdi+ error '+inttostr(ord(aerror)); + if aerror <= high(gdipluserrormessages) then begin + str1:= str1+': '+gdipluserrormessages[aerror]; + end; + inherited create(str1); +end; + +initialization + initializelibinfo(libinfo); +finalization + finalizelibinfo(libinfo); +end. diff --git a/mseide-msegui/lib/common/graphics/msegenericgdi.pas b/mseide-msegui/lib/common/graphics/msegenericgdi.pas new file mode 100644 index 0000000..362f8bc --- /dev/null +++ b/mseide-msegui/lib/common/graphics/msegenericgdi.pas @@ -0,0 +1,1285 @@ +{ MSEgui Copyright (c) 2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msegenericgdi; +// +// under construction +// +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +//{$checkpointer on} +uses + mseguiglob,msegraphics,msetypes,msegraphutils; +type + rectextentty = integer; + prectextentty = ^rectextentty; + rectextentaty = array[0..0] of rectextentty; + prectextentaty = ^rectextentaty; + + rectdataty = record + gap: rectextentty; + width: rectextentty; + end; + prectdataty = ^rectdataty; + rectdataaty = array[0..0] of rectdataty; + prectdataaty = ^rectdataaty; + + stripedataty = record //aray[n] of rectdataty + end; + + stripeheaderty = record + height: rectextentty; + rectcount: rectextentty; + end; + + stripety = record + header: stripeheaderty; + data: stripedataty; + end; + pstripety = ^stripety; + + regiondataty = record + end; + + regioninfoty = record + buffersize: ptruint; + datasize: ptruint; + rectcount: integer; + stripecount: integer; + stripestart: rectextentty; + stripeend: rectextentty; + rectstart: rectextentty; //minint = invalid + rectend: rectextentty; //maxint = invalid + datapo: pstripety; + end; + pregioninfoty = ^regioninfoty; + + pointsfprocty = procedure(const gc: gcty; const points: pfpointty; + const count: integer; const close: boolean); + +procedure gdinotimplemented; +function gdi_regiontorects(const aregion: regionty): rectarty; + +procedure gdi_createemptyregion(var drawinfo: drawinfoty); +procedure gdi_createrectregion(var drawinfo: drawinfoty); +procedure gdi_createrectsregion(var drawinfo: drawinfoty); +procedure gdi_destroyregion(var drawinfo: drawinfoty); +procedure gdi_copyregion(var drawinfo: drawinfoty); +procedure gdi_moveregion(var drawinfo: drawinfoty); +procedure gdi_regionisempty(var drawinfo: drawinfoty); +procedure gdi_regionclipbox(var drawinfo: drawinfoty); +procedure gdi_regsubrect(var drawinfo: drawinfoty); +procedure gdi_regsubregion(var drawinfo: drawinfoty); +procedure gdi_regaddrect(var drawinfo: drawinfoty); +procedure gdi_regaddregion(var drawinfo: drawinfoty); +procedure gdi_regintersectrect(var drawinfo: drawinfoty); +procedure gdi_regintersectregion(var drawinfo: drawinfoty); + +procedure segmentellipsef(var drawinfo: drawinfoty; + const segmentsproc: pointsfprocty); + +{$ifdef mse_debugregion} +procedure dumpregion(const atext: string; const aregion: regionty; + const nocheck: boolean = false); +{$endif} + +implementation +//todo: optimize, especially memory handling, use changebuffer +uses + msesysutils,sysutils,math{$ifdef mse_debugregion},typinfo,mseformatstr{$endif} +; + +type + regopty = (reop_add,reop_sub,reop_intersect); + + regionrectstripety = record + header: stripeheaderty; + data: rectdataty; + end; + regionemptystripety = record + header: stripeheaderty; + end; + +const + rowheadersize = 2*sizeof(rectextentty); //height, colstart + celldatasize = 2*sizeof(rectextentty); //width, gap or 0 + +{$ifdef mse_debugregion} + +procedure dodumpstripes(po1: pstripety; const stripecount: rectextentty; + s1: rectextentty; out stripeheight: integer); +var + int1,int2,int3: integer; + c1: rectextentty; +begin + stripeheight:= s1; + for int1:= 0 to stripecount - 1 do begin + with po1^.header do begin + debugwriteln(' stripe'+inttostr(int1)+' $'+hextostr(po1)+ + ' start: '+inttostr(s1)+ + ' height: '+inttostr(height)+ + ' end: ' + inttostr(s1+height)+ + ' rectcount: '+ inttostr(rectcount) + ); + int2:= rectcount; + s1:= s1 + height; + end; + inc(po1); + c1:= 0; + for int3:= 0 to int2-1 do begin + c1:= c1+prectextentty(po1)^; + inc(prectextentty(po1)); + debugwriteln(' '+inttostr(int3)+' start: '+inttostr(c1)+' width: '+ + inttostr(prectextentty(po1)^)); + c1:= c1+prectextentty(po1)^; + inc(prectextentty(po1)); + end; + end; + stripeheight:= s1-stripeheight; +end; + +procedure dumpstripes(const atext: string; const astripe: pstripety; + const stripecount: rectextentty; + const stripestart: rectextentty); +var + int1: integer; +begin + if astripe = nil then begin + debugwriteln('****'+atext+' NIL'); + end + else begin + debugwriteln('****'+atext+' '+ + 'stripecount: '+inttostr(stripecount)+ + ' stripestart: '+inttostr(stripestart)); + dodumpstripes(astripe,stripecount,stripestart,int1); + end; +end; + +procedure dumpregion(const atext: string; const aregion: regionty; + const nocheck: boolean = false); +var + stripeheight: integer; +begin + if aregion = 0 then begin + debugwriteln('*****'+atext+' NIL'); + end + else begin + with pregioninfoty(aregion)^ do begin + debugwriteln('*****'+atext+' '+ + 'stripecount: '+inttostr(stripecount)+ + ' stripestart: '+inttostr(stripestart)+ + ' stripeend: '+inttostr(stripeend)+ + ' rectstart: '+inttostr(rectstart)+ + ' rectend: '+inttostr(rectend)+ + ' rectcount: '+ inttostr(rectcount)+ + ' datasize: '+inttostr(datasize)+ + ' buffersize: '+inttostr(buffersize) + ); + dodumpstripes(datapo,stripecount,stripestart,stripeheight); + if not nocheck and (stripeheight <> stripeend-stripestart) then begin + debugwriteln(' *** ERROR *** stripeheight expected '+ + inttostr(stripeheight)+' stripeend '+inttostr(stripeheight+stripestart)); + end; + end; + end; +end; + +procedure dumpstripe(const atext: string; const astripe: pstripety); +var + int1: integer; + c1: rectextentty; + po1: prectextentty; +begin + with astripe^.header do begin + debugwriteln('***'+atext+' height: '+inttostr(height)+ + ' rectcount: '+inttostr(rectcount)); + po1:= @astripe^.data; + c1:= 0; + for int1:= 0 to rectcount - 1 do begin + c1:= c1+po1^; + inc(po1); + debugwriteln(' '+inttostr(int1)+' start: '+inttostr(c1)+' width: '+ + inttostr(po1^)); + inc(po1); + end; + end; +end; + +{$endif} + +procedure gdinotimplemented; +begin + guierror(gue_notimplemented); +end; + +function calcdatasize(const rowcount,rectcount: integer): ptruint; + {$ifdef FPC} inline;{$endif} +begin + result:= rowcount*rowheadersize + rectcount*celldatasize; +end; + +function stripesize(const astripe: pstripety): integer; +begin + result:= sizeof(stripeheaderty)+ + astripe^.header.rectcount*sizeof(rectdataty) +end; + +procedure incstripe(var astripe: pstripety); {$ifdef FPC} inline;{$endif} +begin + astripe:= pstripety(pchar(astripe)+sizeof(stripeheaderty)+ + astripe^.header.rectcount*sizeof(rectdataty)); +end; + +function nextstripe(const astripe: pstripety):pstripety; + {$ifdef FPC} inline;{$endif} +begin + result:= pstripety(pchar(astripe)+sizeof(stripeheaderty)+ + astripe^.header.rectcount*sizeof(rectdataty)); +end; + +function getregmem(const astripecount,arectcount: integer): pregioninfoty; +begin + getmem(result,sizeof(regioninfoty)); + with result^ do begin + stripecount:= astripecount; + rectcount:= arectcount; + buffersize:= calcdatasize(stripecount,rectcount); + datasize:= buffersize; + rectstart:= maxint; + rectend:= minint; + if buffersize > 0 then begin + getmem(datapo,buffersize); + end + else begin + datapo:= nil; + end; + end; +end; + +procedure checkbuffersize(var reg: regioninfoty; const sizedelta: ptruint; + var refpointer: pointer); +var + po1: pointer; +begin + with reg do begin + datasize:= datasize + sizedelta; + if datasize > buffersize then begin + buffersize:= 2*buffersize + sizedelta; + po1:= datapo; + reallocmem(datapo,buffersize); + refpointer:= refpointer + (pchar(datapo) - pchar(po1)); + end; + end; +end; + +procedure checkbuffersize(var reg: regioninfoty; + const stripechange,rectchange: integer; var refpointer: pointer); +begin + with reg do begin + checkbuffersize(reg,calcdatasize(stripechange,rectchange),refpointer); + stripecount:= stripecount + stripechange; + rectcount:= rectcount + rectchange; + end; +end; + +procedure insertmem(var reg: regioninfoty; const size: ptruint; + var refpointer: pointer); +begin + checkbuffersize(reg,size,refpointer); + move(refpointer^,(pchar(refpointer)+size)^, + reg.datasize-size-(pchar(refpointer)-pchar(reg.datapo))); +end; + +procedure insertemptystripe(var reg: regioninfoty; + const stripe: pstripety; const astart,aheight: rectextentty; + out start: pstripety); +var +// po1: pointer; + ext1: rectextentty; +begin + with reg do begin +// po1:= datapo; + start:= stripe; + insertmem(reg,sizeof(regionemptystripety),start); + start^.header.height:= aheight; + start^.header.rectcount:= 0; + if (stripecount = 0) or (astart < stripestart) then begin + stripestart:= astart; + if stripecount = 0 then begin + stripeend:= astart+aheight; + end; + end; + inc(stripecount); + ext1:= astart + aheight; + if ext1 > stripeend then begin + stripeend:= ext1; + end; + end; +end; + +procedure copystripe(var reg: regioninfoty; + const stripe: pstripety; out start,stop: pstripety); +var +// po1: pointer; + pui1: ptruint; + int1: integer; +begin + with reg do begin +// po1:= datapo; + start:= stripe; + int1:= stripe^.header.rectcount; + pui1:= sizeof(stripeheaderty) + sizeof(rectdataty)*int1; + insertmem(reg,pui1,start); + stop:= pstripety(pchar(start) + pui1); + move(stop^,start^,pui1); + inc(stripecount); + rectcount:= rectcount + int1; + end; +end; + +function findstripe(const reg: regioninfoty; const start: rectextentty; + out astripestart: rectextentty; + out below: pstripety): pstripety; +var + ext1: rectextentty; + po1: pstripety; +begin + result:= nil; + below:= nil; + astripestart:= 0; + with reg do begin + if stripecount > 0 then begin + ext1:= stripestart; + if (ext1 <= start) and (start < stripeend) then begin + po1:= datapo; + while true do begin + ext1:= ext1 + po1^.header.height; + if ext1 > start then begin + ext1:= ext1-po1^.header.height; + break; + end; + below:= po1; + inc(pchar(po1),sizeof(stripeheaderty)+ + po1^.header.rectcount*sizeof(rectdataty)); + end; + astripestart:= ext1; + result:= po1; + end; + end; + end; +end; + +procedure splitstripes(var reg: regioninfoty; + const astripestart: rectextentty; const astripe: pstripety; + out start: pstripety; out belowref: ptrint; + out splitstripecount,splitrectcount: integer); + //start = first deststripe from astripe + //belowref = distance datapo to above last deststripe from astripe +var + po1,po2,po3: pstripety; + ext1,ext2,ext3: rectextentty; + stripeend1: rectextentty; + pui1: ptruint; + bo1: boolean; + int1: integer; +begin + with reg do begin + belowref:= -1; + splitstripecount:= 1; + stripeend1:= astripestart+astripe^.header.height; + if (stripecount = 0) or (astripestart <= stripestart) then begin + ext1:= stripestart; + bo1:= (stripecount = 0) or (stripeend1 < ext1); + if bo1 then begin + ext2:= astripe^.header.height; + end + else begin + ext2:= stripestart-astripestart; + end; + if (astripestart = stripestart) and (stripecount > 0) then begin + start:= datapo; + end + else begin + insertemptystripe(reg,datapo,astripestart,ext2,start); + end; + if bo1 and (stripecount > 1) then begin + po1:= datapo; + ext2:= astripestart+astripe^.header.height; + insertemptystripe(reg, + pstripety(pchar(start)+sizeof(regionemptystripety)), + ext2,ext1-ext2,po2); + pui1:= pchar(datapo)-pchar(po1); //follow reallocmem + start:= pstripety(pchar(start)+pui1); + end; + end + else begin + if astripestart >= stripeend then begin + if astripestart = stripeend then begin + po1:= datapo; + for int1:= stripecount-2 downto 0 do begin + incstripe(po1); + end; //current last + belowref:= pchar(po1)-pchar(datapo); + insertemptystripe(reg, + pstripety(pchar(datapo)+calcdatasize(stripecount,rectcount)), + astripestart,astripe^.header.height,start); + end + else begin + insertemptystripe(reg, + pstripety(pchar(datapo)+calcdatasize(stripecount,rectcount)), + stripeend,astripestart-stripeend,po1); + insertemptystripe(reg, + pstripety(pchar(datapo)+calcdatasize(stripecount,rectcount)), + astripestart,astripe^.header.height,start); + end; + end + else begin + start:= findstripe(reg,astripestart,ext1,po1); + if ext1 <> astripestart then begin + belowref:= pchar(start)-pchar(datapo); + ext2:= astripestart-ext1; + ext3:= start^.header.height-ext2; + start^.header.height:= ext2; + copystripe(reg,start,po1,start); + start^.header.height:= ext3; + end + else begin + if po1 <> nil then begin + belowref:= pchar(po1)-pchar(datapo); + end; + end; + end; + end; + po1:= start; + ext1:= astripestart; + splitrectcount:= 0; + while true do begin //find end of range + splitrectcount:= splitrectcount + po1^.header.rectcount; + ext1:= ext1 + po1^.header.height; + if (ext1 >= stripeend1) or (ext1 >= stripeend) then begin + break; + end; + inc(splitstripecount); + po1:= pstripety(pchar(po1)+sizeof(stripeheaderty)+ + po1^.header.rectcount*sizeof(rectdataty)); + end; + if ext1 < stripeend1 then begin + po1:= datapo; + insertemptystripe(reg, + pstripety(pchar(datapo)+calcdatasize(stripecount,rectcount)), + stripeend,stripeend1-ext1,po2); + start:= pstripety(pchar(start)+(pchar(datapo)-pchar(po1))); + inc(splitstripecount); + end + else begin + if ext1 <> stripeend1 then begin + ext2:= ext1-stripeend1; + ext3:= po1^.header.height-ext2; + po1^.header.height:= ext3; + po2:= datapo; + copystripe(reg,po1,po3,po3); + start:= pstripety(pchar(start)+(pchar(datapo)-pchar(po2))); + po3^.header.height:= ext2; + end; + end; + end; +end; + +function getbuffer(var reg: regioninfoty; + const stripecount,rectcount: integer; + const additionalbuffer: integer): pstripety; +var + pui1,pui2: ptruint; +begin + pui1:= calcdatasize(stripecount,rectcount); + with reg do begin + pui2:= datasize + pui1 + additionalbuffer; + if buffersize < pui2 then begin + reallocmem(datapo,pui2); + buffersize:= pui2; + end; + result:= pstripety(pchar(datapo)+buffersize-pui1); + end; +end; + +type + regopdataty = record + counta: rectextentty; //new + countb: rectextentty; //existing + end; + +function addop(var data: regopdataty): boolean; +begin + with data do begin + result:= odd(counta) or odd(countb); + end; +end; + +function subop(var data: regopdataty): boolean; +begin + with data do begin + result:= not odd(counta) and odd(countb); + end; +end; + +function intersectop(var data: regopdataty): boolean; +begin + with data do begin + result:= odd(counta) and odd(countb); + end; +end; + +type + regopprocty = function (var data: regopdataty): boolean; + +const + regops: array[regopty] of regopprocty = (@addop,@subop,@intersectop); + +procedure stripeop(var reg: regioninfoty; + const astripestart: rectextentty; + const stripe: pstripety; const op: regopty); +var + d: regopdataty; + po1,po6,psa1,psb,psb1,psbb1,pd,pd1,pd2: pstripety; + lastdeststripe: pstripety; + psbbelowref: ptrint; + po2,po3: prectextentaty; +// po4: pointer; +// po5: ppointer; + stripeco,rectco: integer; + posa,posb,startb,startd,endb: rectextentty; + ext1,ext2,ext3: rectextentty; + int1,{int2,}int3: integer; + bo1: boolean; + pui1,pui2: ptruint; + opproc: regopprocty; + don: boolean; + dpos: rectextentty; + dstripeco,drectco: rectextentty; + pendingmovecount: integer; + moves,moved: pointer; +const + endmark = maxint-1; +begin +{$ifdef mse_debugregion} + debugwriteln(''); + debugwriteln('********* stripeop '+getenumname(typeinfo(regopty),ord(op))); + dumpstripes('sourcestripe',stripe,1,astripestart); + dumpregion('region before split ',ptruint(@reg)); +{$endif} + splitstripes(reg,astripestart,stripe,psb,psbbelowref,stripeco,rectco); + with reg do begin + po1:= reg.datapo; + pd:= getbuffer(reg,stripeco,stripeco*(rectco+stripe^.header.rectcount), + stripeco*stripe^.header.rectcount*sizeof(rectdataty)); + //max + {$ifdef mse_debugregion} + dumpregion('region after split ',ptruint(@reg)); + debugwriteln('* stripeco: '+inttostr(stripeco)+' rectco: '+inttostr(rectco)); + {$endif} + pd1:= pd; + psb:= pstripety(pchar(psb)+(pchar(datapo)-(pchar(po1))));//follow reallocmem + psb1:= psb; //first touched + opproc:= regops[op]; + drectco:= 0; + for int1:= stripeco-1 downto 0 do begin + psa1:= stripe; //new + pd1^.header.height:= psb1^.header.height; + pd2:= pd1; //header backup + pd1:= @pd1^.data; + posa:= endmark; + posb:= endmark; + dpos:= 0; + don:= false; + d.counta:= psa1^.header.rectcount * 2; + psa1:= @psa1^.data; + if d.counta > 0 then begin + posa:= prectextentty(psa1)^; + end; + d.countb:= psb1^.header.rectcount * 2; + psb1:= @psb1^.data; + if d.countb > 0 then begin + posb:= prectextentty(psb1)^; + end; + startb:= posb; + startd:= endmark; + while (d.counta > 0) or (d.countb > 0) do begin + while posb < posa do begin //existing + dec(d.countb); + if opproc(d) <> don then begin + don:= not don; + prectextentty(pd1)^:= posb-dpos; + dpos:= posb; + if startd = endmark then begin + startd:= posb; + end; + inc(prectextentty(pd1)); + end; + inc(prectextentty(psb1)); + if (d.countb = 0) then begin + endb:= posb; + posb:= endmark; + break; + end; + posb:= posb + prectextentty(psb1)^; + end; + while posa <= posb do begin //new + if posb = posa then begin + if posa = endmark then begin + break; + end; + dec(d.countb); + inc(prectextentty(psb1)); + if d.countb = 0 then begin + endb:= posb; + posb:= endmark; + end + else begin + posb:= posb + prectextentty(psb1)^; + end; + end; + dec(d.counta); + if opproc(d) <> don then begin + don:= not don; + prectextentty(pd1)^:= posa-dpos; + dpos:= posa; + if startd = endmark then begin + startd:= posa; + end; + inc(prectextentty(pd1)); + end; + inc(prectextentty(psa1)); + if (d.counta = 0) then begin + posa:= endmark; + break; + end; + posa:= posa + prectextentty(psa1)^; + end; + end; + pd2^.header.rectcount:= ((pchar(pd1)-pchar(pd2))-sizeof(stripeheaderty)) + div sizeof(rectdataty); + drectco:= drectco + pd2^.header.rectcount; + if startd <> endmark then begin //has result rects + if startd <= rectstart then begin + rectstart:= startd; + end + else begin + if startb = rectstart then begin //higher + rectstart:= minint; //invalid + end; + end; + if dpos >= rectend then begin + rectend:= dpos; + end + else begin + if endb = rectend then begin //lower + rectend:= maxint; //invalid + end; + end; + end + else begin //no result rects + if startb = rectstart then begin + rectstart:= minint; //invalid + end; + if endb = rectend then begin + rectend:= maxint; + end; + end; + end; + {$ifdef mse_debugregion} + dumpstripes('dest after operation ',pd,stripeco,astripestart); +// dumpregion('region after operation ',ptruint(@reg)); + {$endif} + + //merge stripes in block + + psb1:= pd; //dest + psbb1:= pd; //dest buffer + psa1:= pd; //init last stripe + po1:= nextstripe(pd);//source + int1:= stripeco; + dstripeco:= int1; + dec(int1); + pendingmovecount:= 0; + moves:= nil; //compiler warning + moved:= nil; //compiler warning + while int1 <> 0 do begin //pack similar stripes +// psa1:= po1; //backup last stripe + psa1:= psb1; //backup last stripe + while (int1 <> 0) and + (po1^.header.rectcount = psbb1^.header.rectcount) do begin + po2:= @po1^.data; + po3:= @psbb1^.data; + bo1:= false; + for int3:= psbb1^.header.rectcount*2-1 downto 0 do begin + if po2^[int3] <> po3^[int3] then begin + bo1:= true; //different + break; + end; + end; + if bo1 then begin + break; + end; + dec(dstripeco); + drectco:= drectco - psbb1^.header.rectcount; //merge stripe + psbb1^.header.height:= psbb1^.header.height + po1^.header.height; + incstripe(po1); + dec(int1); + end; + if int1 <> 0 then begin + if pendingmovecount <> 0 then begin + move(moves^,moved^,pendingmovecount); + end; + incstripe(psb1); + if psb1 <> po1 then begin + pendingmovecount:= stripesize(po1); + psbb1:= po1; + moves:= po1; + moved:= psb1; +// move(po1^,psb1^,stripesize(po1)); //first of next group + end + else begin + pendingmovecount:= 0; + psbb1:= psb1; + end; + incstripe(po1); + dec(int1); + end + else begin + if pendingmovecount <> 0 then begin + move(moves^,moved^,pendingmovecount); + end; + end; + end; + lastdeststripe:= psb1; + {$ifdef mse_debugregion} + dumpstripes('dest after pack ',pd,dstripeco,astripestart); +// dumpregion('region after pack',ptruint(@reg)); + {$endif} + + if op <> reop_intersect then begin + //merge stripe above + + pui1:= calcdatasize(stripeco,rectco); //old size + po1:= pstripety(pchar(psb) + pui1); //first stripe after touched block + if (pchar(po1) < (pchar(datapo) + datasize)) and + (po1^.header.rectcount = psa1^.header.rectcount) then begin + po3:= @psa1^.data; //last stripe in new block + po2:= @po1^.data; + bo1:= false; + for int1:= 0 to psa1^.header.rectcount*2-1 do begin + if po2^[int1] <> po3^[int1] then begin + bo1:= true; + break; + end; + end; + if not bo1 then begin + psa1^.header.height:= psa1^.header.height + po1^.header.height; +// po1^.header.height:= psa1^.header.height + po1^.header.height; + //merge to existing + dec(stripecount); + rectcount:= rectcount-psa1^.header.rectcount; + {$ifdef mse_debugregion} + dumpstripes('dest after merge above ',pd,dstripeco,astripestart); + debugwriteln('* stripecoount: '+ + inttostr(stripecount)+' rectcount: '+inttostr(rectcount)); + {$endif} + incstripe(po1); + end; + end; + + //merge stripe below + + if (psbbelowref >= 0) then begin + po6:= pstripety(pchar(datapo)+psbbelowref); //stripe below touched block + if po6^.header.rectcount = pd^.header.rectcount then begin + bo1:= false; + po3:= @pd^.data; //first stripe in new block + po2:= @po6^.data; + for int1:= 0 to pd^.header.rectcount*2-1 do begin + if po2^[int1] <> po3^[int1] then begin + bo1:= true; + break; + end; + end; + if not bo1 then begin + pd^.header.height:= pd^.header.height + po6^.header.height; + dec(stripecount); + rectcount:= rectcount-pd^.header.rectcount; + psb:= po6; + end; + end; + end; + {$ifdef mse_debugregion} + dumpstripes('dest after merge below ',pd,dstripeco,0); + debugwriteln('* stripecoount: '+ + inttostr(stripecount)+' rectcount: '+inttostr(rectcount)); + {$endif} + end + else begin + psb:= datapo; //intersect + stripestart:= astripestart; + stripeend:= stripestart + stripe^.header.height; + end; + if psb = datapo then begin //first stripe + int1:= 0; + po6:= pd; + while (po6^.header.rectcount = 0) and (int1 < dstripeco) do begin + stripestart:= stripestart + po6^.header.height; + inc(int1); + inc(po6); + end; + inc(pd,int1); //remove leading empty stripes + dstripeco:= dstripeco-int1; + end; + pui2:= calcdatasize(dstripeco,drectco); //new size + if op = reop_intersect then begin + datasize:= pui2; + stripecount:= dstripeco; + rectcount:= drectco; + move(pd^,psb^,pui2); //new data + end + else begin + psb1:= pstripety(pchar(psb)+ pui2); //new block end + move(po1^,psb1^,datasize-(pchar(po1)-pchar(datapo))); + //existing data + move(pd^,psb^,pui2); //new data + rectcount:= rectcount - rectco + drectco; + stripecount:= stripecount - stripeco + dstripeco; + datasize:= calcdatasize(stripecount,rectcount); + + {$ifdef mse_debugregion} + dumpregion('region after move',ptruint(@reg)); + {$endif} + + end; + if (lastdeststripe^.header.rectcount = 0) and + ((pchar(psb)-pchar(datapo))+pui2 = datasize) then begin + //changed last stripe + po1:= pd; + ext1:= 0; + ext2:= 0; + ext3:= 0; + for int1:= dstripeco-1 downto 0 do begin + ext1:= ext1+po1^.header.height; + inc(ext3); //empty stripes + if po1^.header.rectcount > 0 then begin + ext3:= 0; + ext2:= ext1; + end; + incstripe(po1); + end; + stripeend:= stripeend-ext1+ext2; //remove trailing empty stripes + stripecount:= stripecount-ext3; + datasize:= datasize-ext3*sizeof(stripeheaderty); + end; + end; +{$ifdef mse_debugregion} + dumpregion('afterstripeop ',ptruint(@reg)); +{$endif} +end; + +procedure regionop(const source: regioninfoty; var dest: regioninfoty; + const op: regopty); +var + int1: integer; + ext1: rectextentty; + po1: pstripety; +begin + with source do begin + po1:= datapo; + ext1:= stripestart; + for int1:= stripecount - 1 downto 0 do begin + stripeop(dest,ext1,po1,op); + ext1:= ext1 + po1^.header.height; + incstripe(po1); + end; + end; +end; + +function recttostripe(const rect: rectty; out stripestart: rectextentty; + out stripe: regionrectstripety): boolean; +begin + result:= (rect.cx > 0) and (rect.cy > 0); + if result then begin + stripestart:= rect.y; + with stripe do begin + header.height:= rect.cy; + header.rectcount:= 1; + data.gap:= rect.x; + data.width:= rect.cx; + end; + end; +end; + +function regextents(var reg: regioninfoty): rectty; +var + mi,ma: rectextentty; + po1,po2: pstripety; + int1: rectextentty; + ext1: rectextentty; +begin + with reg do begin + if rectcount = 0 then begin + result:= nullrect; + end + else begin + if rectend = maxint then begin //invalid + mi:= maxint; + ma:= minint; + po1:= datapo; + po2:= pstripety(pchar(po1)+datasize); + repeat + int1:= po1^.header.rectcount; + po1:= @po1^.data; + if int1 > 0 then begin + ext1:= prectextentty(po1)^; + if ext1 < mi then begin + mi:= ext1 + end; + for int1:= int1*2-2 downto 0 do begin + inc(prectextentty(po1)); + ext1:= ext1 + prectextentty(po1)^; + end; + inc(prectextentty(po1)); + if ext1 > ma then begin + ma:= ext1; + end; + end; + until po1 >= po2; + rectstart:= mi; + rectend:= ma; + end + else begin + if rectstart = minint then begin //invalid + mi:= maxint; + po1:= datapo; + po2:= pstripety(pchar(po1)+datasize); + repeat + int1:= po1^.header.rectcount; + if int1 > 0 then begin + ext1:= prectdataty(@po1^.data)^.gap; + if ext1 < mi then begin + mi:= ext1; + end; + end; + po1:= pstripety(pchar(po1) + sizeof(stripeheaderty) + + sizeof(rectdataty)*int1); + until po1 >= po2; + rectstart:= mi; + end; + end; + result.x:= rectstart; + result.y:= stripestart; + result.cx:= rectend-rectstart; + result.cy:= stripeend-stripestart; + end; + end; +end; + +function gdi_regiontorects(const aregion: regionty): rectarty; +var + po1: prectextentty; + po2: prectty; + int1,int2: integer; + c1,s1,h1: rectextentty; +begin + if aregion = 0 then begin + result:= nil; + exit; + end; + with pregioninfoty(aregion)^ do begin + setlength(result,rectcount); + po1:= pointer(datapo); + po2:= pointer(result); + s1:= stripestart; + for int1:= stripecount-1 downto 0 do begin + h1:= po1^; //rowheight + inc(po1); + c1:= 0; + for int2:= po1^-1 downto 0 do begin + inc(po1); //gap + c1:= c1+po1^; + po2^.x:= c1; + inc(po1); //width + c1:= c1+po1^; + po2^.cx:= po1^; + po2^.y:= s1; + po2^.cy:= h1; + inc(po2); + end; + s1:= s1 + h1; //next row + inc(po1); + end; + end; +end; + +procedure gdi_createemptyregion(var drawinfo: drawinfoty); //gdifunc +begin + with drawinfo.regionoperation do begin + pointer(dest):= getregmem(0,0); + end; +end; + +procedure gdi_createrectsregion(var drawinfo: drawinfoty); //gdifunc +var + stri1: regionrectstripety; + int1: integer; +begin + gdi_createemptyregion(drawinfo); + with drawinfo.regionoperation do begin + stri1.header.rectcount:= 1; + for int1:= rectscount - 1 downto 0 do begin + with rectspo^[int1] do begin + stri1.header.height:= cy; + stri1.data.gap:= x; + stri1.data.width:= cx; + stripeop(pregioninfoty(dest)^,y,@stri1,reop_add); + end; + end; + end; +end; + +procedure gdi_createrectregion(var drawinfo: drawinfoty); //gdifunc +//var +// int1: ptruint; +begin + with drawinfo.regionoperation do begin + if (rect.cx = 0) or (rect.cy = 0) then begin + gdi_createemptyregion(drawinfo); + end + else begin + pointer(dest):= getregmem(1,1); + with pregioninfoty(dest)^ do begin + stripestart:= rect.y; + stripeend:= rect.y + rect.cy; + stripecount:= 1; + rectcount:= 1; + rectstart:= rect.x; + rectend:= rect.x + rect.cx; + with datapo^ do begin + header.height:= rect.cy; + header.rectcount:= 1; + with prectdataty(@data)^ do begin + gap:= rect.x; + width:= rect.cx; + end; + end; + end; + end; + end; +end; + +procedure gdi_destroyregion(var drawinfo: drawinfoty); //gdifunc +begin + with drawinfo.regionoperation do begin + if source <> 0 then begin + with pregioninfoty(source)^ do begin + if buffersize > 0 then begin + freemem(datapo); + end; + end; + freemem(pointer(source)); + end; + end; +end; + +procedure gdi_copyregion(var drawinfo: drawinfoty); //gdifunc +//var +// int1: integer; +begin + with drawinfo.regionoperation do begin + getmem(pointer(dest),sizeof(regioninfoty)); + move(pointer(source)^,pointer(dest)^,sizeof(regioninfoty)); + with pregioninfoty(dest)^ do begin + if datasize > 0 then begin + getmem(datapo,datasize); + move(pregioninfoty(source)^.datapo^,datapo^,datasize); + end + else begin + datapo:= nil; + end; + buffersize:= datasize; + end; + end; +end; + +procedure gdi_moveregion(var drawinfo: drawinfoty); //gdifunc +var + int1,int2: integer; + po1: pstripety; +begin + with drawinfo.regionoperation do begin + with pregioninfoty(dest)^ do begin + stripestart:= stripestart + rect.y; + stripeend:= stripeend + rect.y; + if rect.x <> 0 then begin + if rectstart <> minint then begin + rectstart:= rectstart + rect.x; + end; + if rectend <> maxint then begin + rectend:= rectend + rect.x; + end; + po1:= datapo; + for int1:= stripecount - 1 downto 0 do begin + int2:= po1^.header.rectcount; + inc(po1); + if int2 <> 0 then begin + prectextentty(po1)^:= prectextentty(po1)^+rect.x; + inc(prectdataty(po1),int2); + end; + end; + end; + end; + end; +end; + +procedure gdi_regionisempty(var drawinfo: drawinfoty); //gdifunc +begin + with pregioninfoty(drawinfo.regionoperation.source)^ do begin + drawinfo.regionoperation.dest:= 0; + if rectcount = 0 then begin + drawinfo.regionoperation.dest:= 1; + end; + end; +end; + +procedure gdi_regionclipbox(var drawinfo: drawinfoty); //gdifunc +begin + with drawinfo.regionoperation do begin + rect:= regextents(pregioninfoty(source)^); + end; +end; + +procedure gdi_regsubrect(var drawinfo: drawinfoty); //gdifunc +var + stri1: regionrectstripety; + ext1: rectextentty; +begin + with drawinfo.regionoperation do begin + if recttostripe(rect,ext1,stri1) then begin + stripeop(pregioninfoty(dest)^,ext1,@stri1,reop_sub); + end; + end; +end; + +procedure gdi_regsubregion(var drawinfo: drawinfoty); //gdifunc +begin + with drawinfo.regionoperation do begin + regionop(pregioninfoty(source)^,pregioninfoty(dest)^,reop_sub); + end; +end; + +procedure gdi_regaddrect(var drawinfo: drawinfoty); //gdifunc +var + stri1: regionrectstripety; + ext1: rectextentty; +begin + with drawinfo.regionoperation do begin + if recttostripe(rect,ext1,stri1) then begin + stripeop(pregioninfoty(dest)^,ext1,@stri1,reop_add); + end; + end; +end; + +procedure gdi_regaddregion(var drawinfo: drawinfoty); //gdifunc +begin + with drawinfo.regionoperation do begin + regionop(pregioninfoty(source)^,pregioninfoty(dest)^,reop_add); + end; +end; + +procedure gdi_regintersectrect(var drawinfo: drawinfoty); //gdifunc +var + stri1: regionrectstripety; + ext1: rectextentty; +begin + with drawinfo.regionoperation do begin + if recttostripe(rect,ext1,stri1) then begin + stripeop(pregioninfoty(dest)^,ext1,@stri1,reop_intersect); + end; + end; +end; + +procedure gdi_regintersectregion(var drawinfo: drawinfoty); //gdifunc +begin + with drawinfo.regionoperation do begin + regionop(pregioninfoty(source)^,pregioninfoty(dest)^,reop_intersect); + end; +end; + +procedure segmentellipsef(var drawinfo: drawinfoty; + const segmentsproc: pointsfprocty); +//todo: optimize +var + count: integer; + po1: pfpointty; + ox,oy,x1,y1,si,co,a: double; + do1: double; + int1: integer; +begin + po1:= nil; //compilerwarning + with drawinfo,drawinfo.rect.rect^ do begin + count:= 2; + if cx = 0 then begin + allocbuffer(buffer,2*sizeof(po1^)); + po1:= buffer.buffer; + po1^.x:= x; + po1^.y:= y; + inc(po1); + po1^.x:= x; + po1^.y:= y+cy; + end + else begin + if cy = 0 then begin + allocbuffer(buffer,2*sizeof(po1^)); + po1:= buffer.buffer; + po1^.x:= x; + po1^.y:= y; + inc(po1); + po1^.x:= x+cx; + po1^.y:= y; + end + else begin + int1:= abs(cx); + if abs(cy) > int1 then begin + int1:= abs(cy); + end; + count:= ceil((0.5*pi)/arccos((int1-1)/int1))*4; //one pixel resolution + if count = 0 then begin + count:= 4; + end; + allocbuffer(buffer,count*sizeof(po1^)); + a:= cy/cx; + oy:= y+cy/2; + do1:= cx/2; + x1:= do1; + y1:= 0; + ox:= x+do1; + do1:= 2*pi/count; + si:= sin(do1); + co:= cos(do1); + po1:= buffer.buffer; + po1^.x:= x1+ox; + po1^.y:= oy; + for int1:= count-2 downto 0 do begin + do1:= x1*co - y1*si; + y1:= y1*co + x1*si; + x1:= do1; + inc(po1); + po1^.x:= x1+ox; + po1^.y:= y1*a+oy; + end; + end; + end; + segmentsproc(gc,buffer.buffer,count,true); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/graphics/msegraphics.pas b/mseide-msegui/lib/common/graphics/msegraphics.pas new file mode 100644 index 0000000..d286313 --- /dev/null +++ b/mseide-msegui/lib/common/graphics/msegraphics.pas @@ -0,0 +1,7255 @@ +{ MSEgui Copyright (c) 1999-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msegraphics; +{$ifdef FPC}{$mode objfpc}{$h+}{$GOTO ON}{$interfaces corba}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,msetypes,msestrings,mseerr, + msegraphutils,mseguiglob,mseclasses,mseglob,msesys; + +const + + linewidthshift = 16; + linewidthroundvalue = $8000; + fontsizeshift = 16; + fontsizeroundvalue = $8000; + defaultfontalias = 'stf_default'; + + invalidgchandle = ptruint(-1); + +type + gckindty = (gck_screen,gck_pixmap,gck_printer,gck_metafile); + + drawingflagty = (df_canvasispixmap,df_canvasismonochrome,df_highresfont, + df_doublebuffer,df_smooth, + df_colorconvert, + df_opaque,df_monochrome,df_brush,df_dashed,df_last = 31); + drawingflagsty = set of drawingflagty; + + capstylety = (cs_butt,cs_round,cs_projecting); + joinstylety = (js_miter,js_round,js_bevel); + + dashesstringty = string[8]; + +const + fillmodeinfoflags = [df_opaque,df_monochrome,df_brush]; + da_dot = dashesstringty(#1#1); + da_dash = dashesstringty(#3#3); + da_dashdot = dashesstringty(#3#1#1#1); + +type + //fontalias option char: + fontoptionty = (foo_fixed, // 'p' + foo_proportional, // 'P' + foo_helvetica, // 'H' + foo_roman, // 'R' + foo_script, // 'S' + foo_decorative, // 'D' + foo_antialiased, // 'A' + foo_antialiased2, // 'B' cleartype on windows + foo_nonantialiased // 'a' +// foo_xcore, // 'C' //seems not to work with xft2 +// foo_noxcore // 'c' + ); + fontoptionsty = set of fontoptionty; + +const + fontpitchmask = [foo_fixed,foo_proportional]; + fontfamilymask = [foo_helvetica,foo_roman,foo_script,foo_decorative]; + fontantialiasedmask = [foo_antialiased,foo_antialiased2,foo_nonantialiased]; +// fontxcoremask = [foo_xcore,foo_noxcore]; + fontaliasoptionchars : array[fontoptionty] of char = + ('p','P','H','R','S','D','A','B','a'{,'C','c'}); +type + canvasstatety = + (cs_regioncopy,cs_clipregion,cs_origin,cs_gc, + cs_acolorbackground,cs_acolorforeground,cs_color,cs_colorbackground, + cs_dashes,cs_linewidth,cs_capstyle,cs_joinstyle,cs_options, + cs_fonthandle,cs_font,cs_fontcolor,cs_fontcolorbackground,cs_fonteffect, + cs_rasterop,cs_brush,cs_brushorigin, + cs_painted,cs_internaldrawtext,cs_highresdevice, + cs_inactive,cs_pagestarted,cs_metafile{,cs_monochrome}); + canvasstatesty = set of canvasstatety; +const + linecanvasstates = [cs_dashes,cs_linewidth,cs_capstyle,cs_joinstyle]; + +const + fontstylehandlemask = 3; //[fs_bold,fs_italic] + fontstylesmamask: fontstylesty = + [fs_bold,fs_italic,fs_underline,fs_strikeout,fs_selected]; + +type + pgdifunctionaty = ^gdifunctionaty; + + fontdatapty = array[0..15] of pointer; + + fonthashdty = record //hashed by byteshash + glyph: unicharty; + gdifuncs: pgdifunctionaty; //gdi framework + height: integer; + width: integer; + style: fontstylesty; //fs_bold,fs_italic + pitchoptions,familyoptions,antialiasedoptions: fontoptionsty; + rotation: real; //0..1 -> 0deg..360deg CCW + xscale: real; //default 1.0 + end; + + fonthashdataty = record + d: fonthashdty; + name: string; + charset: string; + end; + + fontdataty = record + h: fonthashdataty; + realfont: fonthashdataty; + + font: fontty; + fonthighres: fontty; + basefont: fontty; + ascent,descent,linespacing,caretshift,linewidth,realheight: integer; + platformdata: fontdatapty; //platform dependent + end; + pfontdataty = ^fontdataty; + + fontmetricsty = record + leftbearing: integer; //left undersize, origin of left edge + width: integer; //character advance + rightbearing: integer;//right undersize + sum: integer; //with - leftbearing - rightbearing, glyph width + end; + pfontmetricsty = ^fontmetricsty; + + + + rasteropty = (rop_clear,rop_and,rop_andnot,rop_copy, + rop_notand,rop_nop,rop_xor,rop_or, + rop_nor,rop_notxor,rop_not,rop_ornot, + rop_notcopy,rop_notor,rop_nand,rop_set); + + tfont = class; + tsimplebitmap = class; + fontchangedeventty = procedure(sender: tfont; changed: canvasstatesty) of object; + + fontstatety = (fsta_infovalid,fsta_none); + fontstatesty = set of fontstatety; + + fontnumty = longword; + + tcanvas = class; + + fontaliasmodety = ( + fam_nooverwrite, //do not change if allready registered + fam_overwrite, //do change if allready registered not fam_fix + fam_fix, //will never be changed + fam_fixnooverwrite //do not change if allready registered, + ); //fix existing + + basefontinfoty = record + color: colorty; + colorbackground: colorty; + colorselect: colorty; + colorselectbackground: colorty; + shadow_color: colorty; + shadow_shiftx: integer; + shadow_shifty: integer; + gloss_color: colorty; + gloss_shiftx: integer; + gloss_shifty: integer; + grayed_color: colorty; + grayed_colorshadow: colorty; + grayed_shiftx: integer; + grayed_shifty: integer; + style: fontstylesty; + xscale: real; //default 1.0 + + height: integer; + width: integer; + extraspace: integer; + name: string; + charset: string; + options: fontoptionsty; + end; + + fontlocalpropty = ( + flp_color,flp_colorbackground,flp_colorselect,flp_colorselectbackground, + flp_shadow_color,flp_shadow_shiftx,flp_shadow_shifty, + flp_gloss_color,flp_gloss_shiftx,flp_gloss_shifty, + flp_grayed_color,flp_grayed_colorshadow,flp_grayed_shiftx,flp_grayed_shifty, + flp_style,flp_xscale,flp_height,flp_width,flp_extraspace,flp_name,flp_charset, + flp_options + ); + fontlocalpropsty = set of fontlocalpropty; + + fontinfoty = record + handles: array[0..fontstylehandlemask] of fontnumty; + baseinfo: basefontinfoty; + glyph: unicharty; + gdifuncs: pgdifunctionaty; + rotation: real; //0..2*pi -> 0deg..360deg CCW + end; + pfontinfoty = ^fontinfoty; + + bitmapkindty = (bmk_mono,bmk_gray,bmk_rgb); + + imagety = record + kind: bitmapkindty; + bgr: boolean; + size: sizety; + length: integer; //number of longword + linelength: integer; //number of longword in row + linebytes: integer; //number of bytes in row + pixels: plongwordaty; + end; + pimagety = ^imagety; + + maskedimagety = record + image: imagety; + mask: imagety; + end; + + icanvas = interface(inullinterface) + procedure gcneeded(const sender: tcanvas); + function getkind: bitmapkindty; + function getsize: sizety; + procedure getcanvasimage(const bgr: boolean; var aimage: maskedimagety); + end; + + canvasclassty = class of tcanvas; + + gcpty = array[0..63] of pointer; + gcty = record + handle: ptruint;//cardinal; + refgc: ptruint;//cardinal; //for windowsmetafile + gdifuncs: pgdifunctionaty; + fontgdifuncs: pgdifunctionaty; + drawingflags: drawingflagsty; + kind: bitmapkindty; + cliporigin: pointty; + paintdevicesize: sizety; + ppmm: real; + platformdata: gcpty; //platform dependent + end; + pgcty = ^gcty; + + bufferty = record + size: integer; //memory size + buffer: pointer; + cursize: integer; //used size + end; + + pdrawinfoty = ^drawinfoty; + rectinfoty = record /// + rect: prectty; // + end; // same layout! + arcinfoty = record // + rect: prectty; /// //rect^.pos = center of ellipse + //rect^.size = dimensions of ellipse + startang: real; //in radiant CCW, 0 = horizontal to the right, + //2*pi = full circle + extentang: real; //in radiant CCW, 2*pi = full circle + pieslice: boolean; + end; + posinfoty = record /// + pos: ppointty; // + end; // same layout! + textposinfoty = record // + pos: ppointty; /// + text: pchar; + count: integer; + end; + text16posinfoty = record + pos: ppointty; + text: pmsechar; + count: integer; + end; + pointsinfoty = record + points: ppointty; + count: integer; + closed: boolean; + end; + colorinfoty = record + color: colorty; + end; + getfontinfoty = record + fontdata: pfontdataty; + basefont: fontty; + ok: boolean; + end; + gettext16widthinfoty = record + text: pmsechar; + count: integer; + fontdata: pfontdataty; + result: integer; + end; + getchar16widthsinfoty = record + text: pmsechar; + count: integer; + fontdata: pfontdataty; + resultpo: pinteger; + end; + getfontmetricsinfoty = record + char: ucs4char; + fontdata: pfontdataty; + resultpo: pfontmetricsty; + end; + copyareainfoty = record + source: tcanvas{pdrawinfoty}; //can be equal to self + sourcerect: prectty; + destrect: prectty; + tileorigin: ppointty; + alignment: alignmentsty; + copymode: rasteropty; + transparentcolor: pixelty; + mask: tsimplebitmap; + maskshiftscaled,maskshift: pointty; + opacity: rgbtriplety; + end; + fonthasglyphinfoty = record + font: fontty; + unichar: unicharty; + hasglyph: boolean; + end; + + rectsty = array[0..bigint div sizeof(rectty)] of rectty; + prectsty = ^rectsty; + regionoperationinfoty = record + source,dest: regionty; + rect: rectty; + rectspo: prectsty; + rectscount: integer; + end; + + createpixmapinfoty = record + size: sizety; + kind: bitmapkindty; + copyfrom: pixmapty; + pixmap: pixmapty; + end; + + pixmapimageinfoty = record + pixmap: pixmapty; + image: imagety; + error: gdierrorty; + end; + + creategcinfoty = record + paintdevice: paintdevicety; + kind: gckindty; + printernamepo: pmsestring; + contextinfopo: pointer; + gcpo: pgcty; + windowrect: prectty; + parent: winidty; + createpaintdevice: boolean; + error: gdierrorty; + end; + + getimageinfoty = record + error: gdierrorty; + image: maskedimagety; + end; + + getcanvasclassinfoty = record + canvasclass: canvasclassty; + kind: bitmapkindty;//monochrome: boolean; + end; + + moverectinfoty = record + dist: ppointty; + rect: prectty; + end; + + gcvaluemaskty = (gvm_clipregion,gvm_colorbackground,gvm_colorforeground, + gvm_dashes,gvm_linewidth,gvm_capstyle,gvm_joinstyle, + gvm_options, + gvm_font,gvm_brush,gvm_brushorigin,gvm_rasterop, + gvm_brushflag); + gcvaluemasksty = set of gcvaluemaskty; + + lineinfoty = record + width: integer; //pixel shl linewidthshift + dashes: dashesstringty; + capstyle: capstylety; + joinstyle: joinstylety; +// options: lineoptionsty; + end; + + canvasoptionty = (cao_smooth); + canvasoptionsty = set of canvasoptionty; + + gcvaluesty = record + mask: gcvaluemasksty; + clipregion: regionty; + colorbackground: pixelty; + colorforeground: pixelty; + font: fontty; + fontnum: fontnumty; + fontdata: pfontdataty; + brush: tsimplebitmap; + brushorigin: pointty; + rasterop: rasteropty; + lineinfo: lineinfoty; + options: canvasoptionsty; + end; + pgcvaluesty = ^gcvaluesty; + + drawinfoty = record + buffer: bufferty; + gc: gcty; + statestamp: longword; +// gcident: longword; + paintdevice: paintdevicety; + origin: pointty; + acolorbackground,acolorforeground: colorty; + gcvalues: pgcvaluesty; //valid in gui_changegc + case integer of + 0: (rect: rectinfoty); + 1: (arc: arcinfoty); + 2: (pos: posinfoty); + 3: (textpos: textposinfoty); + 4: (text16pos: text16posinfoty); + 5: (points: pointsinfoty); + 6: (color: colorinfoty); + 7: (getfont: getfontinfoty); +// 8: (gettextwidth: gettextwidthinfoty); + 9: (gettext16width: gettext16widthinfoty); +// 10: (getcharwidths: getcharwidthsinfoty); + 11: (getchar16widths: getchar16widthsinfoty); + 12: (getfontmetrics: getfontmetricsinfoty); + 13: (copyarea: copyareainfoty); + 14: (regionoperation: regionoperationinfoty); + 15: (fonthasglyph: fonthasglyphinfoty); + 16: (creategc: creategcinfoty); + 17: (getimage: getimageinfoty); + 18: (getcanvasclass: getcanvasclassinfoty); + 19: (createpixmap: createpixmapinfoty); + 20: (pixmapimage: pixmapimageinfoty); + 21: (moverect: moverectinfoty) + end; + + tfonttemplate = class(tpersistenttemplate) + private + procedure setcolor(const avalue: colorty); + procedure setcolorbackground(const avalue: colorty); + procedure setcolorselect(const avalue: colorty); + procedure setcolorselectbackground(const avalue: colorty); + procedure setshadow_color(const avalue: colorty); + procedure setshadow_shiftx(const avalue: integer); + procedure setshadow_shifty(const avalue: integer); + procedure setgloss_color(const avalue: colorty); + procedure setgloss_shiftx(const avalue: integer); + procedure setgloss_shifty(const avalue: integer); + procedure setgrayed_color(const avalue: colorty); + procedure setgrayed_colorshadow(const avalue: colorty); + procedure setgrayed_shiftx(const avalue: integer); + procedure setgrayed_shifty(const avalue: integer); + procedure setstyle(const avalue: fontstylesty); + procedure setxscale(const avalue: real); + procedure setheight(const avalue: integer); + procedure setwidth(const avalue: integer); + procedure setextraspace(const avalue: integer); + procedure setname(const avalue: string); + procedure setcharset(const avalue: string); + procedure setoptions(const avalue: fontoptionsty); + protected + fi: basefontinfoty; + procedure doassignto(dest: tpersistent); override; + function getinfosize: integer; override; + function getinfoad: pointer; override; + public + constructor create(const owner: tmsecomponent; + const onchange: notifyeventty); override; + published + property color: colorty read fi.color write setcolor default cl_default; + //cl_text + property colorbackground: colorty read fi.colorbackground + write setcolorbackground default cl_default; //cl_transparent + property colorselect: colorty read fi.colorselect + write setcolorselect default cl_default; //cl_selectedtext + property colorselectbackground: colorty read fi.colorselectbackground + write setcolorselectbackground default cl_default; + //cl_selectedtextbackground + + property shadow_color: colorty read fi.shadow_color + write setshadow_color default cl_none; + property shadow_shiftx: integer read fi.shadow_shiftx write + setshadow_shiftx default 1; + property shadow_shifty: integer read fi.shadow_shifty write + setshadow_shifty default 1; + + property gloss_color: colorty read fi.gloss_color + write setgloss_color default cl_none; + property gloss_shiftx: integer read fi.gloss_shiftx write + setgloss_shiftx default -1; + property gloss_shifty: integer read fi.gloss_shifty write + setgloss_shifty default -1; + + property grayed_color: colorty read fi.grayed_color + write setgrayed_color default cl_default; //cl_grayed + property grayed_colorshadow: colorty read fi.grayed_colorshadow + write setgrayed_colorshadow default cl_default; + //cl_grayedshadow; + property grayed_shiftx: integer read fi.grayed_shiftx write + setgrayed_shiftx default 1; + property grayed_shifty: integer read fi.grayed_shifty write + setgrayed_shifty default 1; + + property height: integer read fi.height write setheight default 0; + //pixel + property width: integer read fi.width write setwidth default 0; + //avg. character width in 1/10 pixel, 0 = default + property extraspace: integer read fi.extraspace write setextraspace + default 0; + property style: fontstylesty read fi.style write setstyle default []; + property name: string read fi.name write setname; + property charset: string read fi.charset write setcharset; + property options: fontoptionsty read fi.options write setoptions default []; + property xscale: real read fi.xscale write setxscale; + //default 1.0 + + end; + + tfontcomp = class(ttemplatecontainer) + private + function gettemplate: tfonttemplate; + procedure settemplate(const avalue: tfonttemplate); + protected + function gettemplateclass: templateclassty; override; + public + published + property template: tfonttemplate read gettemplate write settemplate; + end; + + getfontfuncty = function (var drawinfo: drawinfoty): boolean of object; + + tfont = class(tlinkedoptionalpersistent,icanvas) + private + finfopo: pfontinfoty; + fonchange: notifyeventty; + flocalprops: fontlocalpropsty; + ftemplate: tfontcomp; + function getextraspace: integer; + procedure setextraspace(const avalue: integer); + procedure setcolorbackground(const Value: colorty); + function getcolorbackground: colorty; + procedure setcolorselectbackground(const Value: colorty); + function getcolorselectbackground: colorty; + + procedure setshadow_color(avalue: colorty); + function getshadow_color: colorty; + procedure setshadow_shiftx(const avalue: integer); + function getshadow_shiftx: integer; + procedure setshadow_shifty(const avalue: integer); + function getshadow_shifty: integer; + + procedure setgloss_color(avalue: colorty); + function getgloss_color: colorty; + procedure setgloss_shiftx(const avalue: integer); + function getgloss_shiftx: integer; + procedure setgloss_shifty(const avalue: integer); + function getgloss_shifty: integer; + + procedure setcolor(const Value: colorty); + function getcolor: colorty; + procedure setcolorselect(const Value: colorty); + function getcolorselect: colorty; + procedure setheight(avalue: integer); + procedure setheightflo(avalue: flo64); + function getheight: integer; + function getheightflo: flo64; + function getwidth: integer; + procedure setwidth(avalue: integer); + procedure setstyle(const Value: fontstylesty); + function getstyle: fontstylesty; + function getascent: integer; + function getdescent: integer; + function getglyphheight: integer; + function getlineheight: integer; + function getcaretshift: integer; + procedure updatehandlepo; + procedure releasehandles(const nochanged: boolean = false); + function getcharset: string; + function getname: string; + procedure setcharset(const Value: string); + function getoptions: fontoptionsty; + procedure setoptions(const avalue: fontoptionsty); + function getbold: boolean; + procedure setbold(const avalue: boolean); + function getitalic: boolean; + procedure setitalic(const avalue: boolean); + function getunderline: boolean; + procedure setunderline(const avalue: boolean); + function getstrikeout: boolean; + procedure setstrikeout(const avalue: boolean); + procedure createhandle(const canvas: tcanvas); + function getrotation: real; + procedure setrotation(const avalue: real); + function getxscale: real; + procedure setxscale(const avalue: real); + + procedure readcolorshadow(reader: treader); + function getlinewidth: integer; + + //icanvas + procedure gcneeded(const sender: tcanvas); +// function getmonochrome: boolean; + function getkind: bitmapkindty; + function getsize: sizety; + procedure getcanvasimage(const bgr: boolean; var aimage: maskedimagety); + function getgrayed_color: colorty; + procedure setgrayed_color(const avalue: colorty); + function getgrayed_colorshadow: colorty; + procedure setgrayed_colorshadow(const avalue: colorty); + function getgrayed_shiftx: integer; + procedure setgrayed_shiftx(const avalue: integer); + function getgrayed_shifty: integer; + procedure setgrayed_shifty(const avalue: integer); + procedure settemplate(const avalue: tfontcomp); + function iscolorstored(): boolean; + function iscolorbackgroundstored(): boolean; + function iscolorselectstored(): boolean; + function iscolorselectbackgroundstored(): boolean; + function isshadow_colorstored(): boolean; + function isshadow_shiftxstored(): boolean; + function isshadow_shiftystored(): boolean; + function isgloss_colorstored(): boolean; + function isgloss_shiftxstored(): boolean; + function isgloss_shiftystored(): boolean; + function isgrayed_colorstored(): boolean; + function isgrayed_colorshadowstored(): boolean; + function isgrayed_shiftxstored(): boolean; + function isgrayed_shiftystored(): boolean; + function isxscalestored(): boolean; + function isstylestored(): boolean; + procedure readdummy(reader: treader); + procedure setlocalprops(const avalue: fontlocalpropsty); + protected + finfo: fontinfoty; + fhandlepo: ^fontnumty; + procedure dochanged(const changed: canvasstatesty; + const nochange: boolean); virtual; + function getfont(var drawinfo: drawinfoty): boolean; virtual; + procedure setname(const Value: string); virtual; + function gethandle: fontnumty; virtual; + function getdatapo: pfontdataty; + procedure assignproperties(const source: tfont; + const ahandles: boolean); virtual; + property rotation: real read getrotation write setrotation; + //0..2*pi-> 0degree..360degree CCW + procedure defineproperties(filer: tfiler); override; + procedure settemplateinfo(const ainfo: basefontinfoty); + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + function isheightstored(): boolean; + function iswidthstored(): boolean; + function isextraspacestored(): boolean; + function isnamestored(): boolean; + function ischarsetstored(): boolean; + function isoptionsstored(): boolean; + public + constructor create; override; + destructor destroy; override; + procedure assign(source: tpersistent); override; + procedure scale(const ascale: real); virtual; + + function gethandleforcanvas(const canvas: tcanvas): fontnumty; + property handle: fontnumty read gethandle; + property ascent: integer read getascent; + property descent: integer read getdescent; + property glyphheight: integer read getglyphheight; //ascent + descent + property lineheight: integer read getlineheight; + property linewidth: integer read getlinewidth; + property caretshift: integer read getcaretshift; + property onchange: notifyeventty read fonchange write fonchange; + + property bold: boolean read getbold write setbold; + property italic: boolean read getitalic write setitalic; + property underline: boolean read getunderline write setunderline; + property strikeout: boolean read getstrikeout write setstrikeout; + property heightflo: flo64 read getheightflo write setheightflo; + //pixel, 0 = default + + published + property color: colorty read getcolor write setcolor + stored iscolorstored default cl_default; //cl_text + property colorbackground: colorty read getcolorbackground + write setcolorbackground stored iscolorbackgroundstored + default cl_default; //cl_transparent + property colorselect: colorty read getcolorselect write setcolorselect + stored iscolorselectstored default cl_default; //cl_selectedtext + property colorselectbackground: colorty read getcolorselectbackground + write setcolorselectbackground stored iscolorselectbackgroundstored + default cl_default; //cl_selectedtextbackground + property shadow_color: colorty read getshadow_color write setshadow_color + stored isshadow_colorstored default cl_none; + property shadow_shiftx: integer read getshadow_shiftx write setshadow_shiftx + stored isshadow_shiftxstored default 1; + property shadow_shifty: integer read getshadow_shifty write setshadow_shifty + stored isshadow_shiftystored default 1; + + property gloss_color: colorty read getgloss_color + write setgloss_color + stored isgloss_colorstored default cl_none; + property gloss_shiftx: integer read getgloss_shiftx write setgloss_shiftx + stored isgloss_shiftxstored default -1; + property gloss_shifty: integer read getgloss_shifty write setgloss_shifty + stored isgloss_shiftystored default -1; + + property grayed_color: colorty read getgrayed_color + write setgrayed_color + stored isgrayed_colorstored default cl_default;//cl_grayed + property grayed_colorshadow: colorty read getgrayed_colorshadow + write setgrayed_colorshadow + stored isgrayed_colorshadowstored default cl_default; + //cl_grayedshadow + property grayed_shiftx: integer read getgrayed_shiftx write + setgrayed_shiftx + stored isgrayed_shiftxstored default 1; + property grayed_shifty: integer read getgrayed_shifty write + setgrayed_shifty + stored isgrayed_shiftystored default 1; + + property height: integer read getheight write setheight + stored isheightstored default 0; + //pixel, 0 = default + property width: integer read getwidth write setwidth + stored iswidthstored default 0; + //avg. character width in 1/10 pixel, 0 = default + property extraspace: integer read getextraspace write setextraspace + stored isextraspacestored default 0; + property style: fontstylesty read getstyle write setstyle + stored isstylestored default []; + property name: string read getname write setname stored isnamestored; + property charset: string read getcharset write setcharset + stored ischarsetstored; + property options: fontoptionsty read getoptions write setoptions + stored isoptionsstored default []; + property xscale: real read getxscale write setxscale stored isxscalestored; + //default 1.0 + + property localprops: fontlocalpropsty read flocalprops write setlocalprops; + //before template! + //No default, is optional object streaming placeholder + property template: tfontcomp read ftemplate write settemplate; + end; + pfont = ^tfont; + fontarty = array of tfont; + + toptionalfont = class(tfont) + end; + + tparentfont = class(tfont) + public + class function getinstancepo(owner: tobject): pfont; virtual; abstract; + end; + parentfontclassty = class of tparentfont; + + tcanvasfont = class(tfont) + private + protected + fcanvas: tcanvas; + fgdifuncs: pgdifunctionaty; + procedure dochanged(const changed: canvasstatesty; + const nochange: boolean); override; + function gethandle: fontnumty; override; + procedure assignproperties(const source: tfont; + const ahandles: boolean); override; + public + constructor create(const acanvas: tcanvas); reintroduce; + end; + + gdifunctionty = procedure(var drawinfo: drawinfoty); + + gdifuncty = (gdf_creategc,gdf_destroygc,gdf_changegc,gdf_createpixmap, + gdf_pixmaptoimage,gdf_imagetopixmap, + gdf_getcanvasclass,gdf_endpaint,gdf_flush,gdf_movewindowrect, + gdf_drawlines,gdf_drawlinesegments,gdf_drawellipse,gdf_drawarc, + gdf_fillrect, + gdf_fillellipse,gdf_fillarc,gdf_fillpolygon,{gdf_drawstring,} + gdf_drawstring16, + gdf_setcliporigin, + gdf_createemptyregion,gdf_createrectregion,gdf_createrectsregion, + gdf_destroyregion,gdf_copyregion,gdf_moveregion, + gdf_regionisempty,gdf_regionclipbox, + gdf_regsubrect,gdf_regsubregion, + gdf_regaddrect,gdf_regaddregion,gdf_regintersectrect, + gdf_regintersectregion, + gdf_copyarea,gdf_getimage, + gdf_fonthasglyph, + gdf_getfont,gdf_getfonthighres,gdf_freefontdata, + gdf_gettext16width,gdf_getchar16widths,gdf_getfontmetrics + ); + + gdifunctionaty = array[gdifuncty] of gdifunctionty; +// pgdifunctionaty = ^gdifunctionaty; + + canvasvaluesty = record + changed: canvasstatesty; + origin: pointty; + brushorigin: pointty; + clipregion: regionty; + color: colorty; + rasterop: rasteropty; + colorbackground: colorty; + font: fontinfoty; + brush: tsimplebitmap; + lineinfo: lineinfoty; + options: canvasoptionsty; + end; + + canvasvaluespoty = ^canvasvaluesty; + canvasvaluesarty = array of canvasvaluesty; + + canvasvaluestackty = record + count: integer; + stack: canvasvaluesarty; + end; + + edgecolorinfoty = record + color,effectcolor: colorty; + effectwidth: integer; + end; + edgecolorpairinfoty = record + light,shadow: edgecolorinfoty; + end; + framecolorinfoty = record + edges: edgecolorpairinfoty; + frame: colorty; + hiddenedges: edgesty; + end; + + edgeinfoty = (kin_dark,kin_reverseend,kin_reversestart); + edgeinfosty = set of edgeinfoty; + + gdiintffuncty = procedure (func: gdifuncty; var drawinfo: drawinfoty); + canvasarty = array of tcanvas; + + tcanvas = class(tpersistent) + private + fvaluestack: canvasvaluestackty; + gccolorbackground,gccolorforeground: colorty; + gcoptions: canvasoptionsty; + fdefaultfont: fontnumty; + fcliporigin: pointty; + fgclinksto: canvasarty; + fgclinksfrom: canvasarty; + procedure adjustrectar(po: prectty; count: integer); + procedure readjustrectar(po: prectty; count: integer); + procedure error(nr: gdierrorty; const text: msestring); + procedure intparametererror(value: integer; const text: msestring); + procedure freevalues(var values: canvasvaluesty); + + function getcolor: colorty; + procedure setcolor(const value: colorty); + procedure setclipregion(const Value: regionty); + function getorigin: pointty; + procedure setorigin(const Value: pointty); + + + function checkforeground(acolor: colorty; lineinfo: boolean): boolean; + procedure checkcolors; + procedure setfont(const Value: tfont); + procedure updatefontinfo; + function getbrush: tsimplebitmap; + procedure setbrush(const Value: tsimplebitmap); + function getbrushorigin: pointty; + procedure setbrushorigin(const Value: pointty); + function getrootbrushorigin: pointty; + procedure setrootbrushorigin(const Value: pointty); + function getcolorbackground: colorty; + procedure setcolorbackground(const Value: colorty); + function getrasterop: rasteropty; + procedure setrasterop(const Value: rasteropty); + function getdashes: dashesstringty; + procedure setdashes(const Value: dashesstringty); + function getlinewidth: integer; + procedure setlinewidth(Value: integer); + function getcapstyle: capstylety; + function getjoinstyle: joinstylety; + function getoptions: canvasoptionsty; inline; + procedure setcapstyle(const Value: capstylety); + procedure setjoinstyle(const Value: joinstylety); + procedure setoptions(const avalue: canvasoptionsty); + procedure initregrect(const adest: regionty; const arect: rectty); + procedure initregreg(const adest: regionty; const asource: regionty); + procedure updatecliporigin(const Value: pointty); + function getlinewidthmm: real; + procedure setlinewidthmm(const avalue: real); + function getkind: bitmapkindty; +// function getmonochrome: boolean; + procedure readlineoptions(reader: treader); + function getsmooth: boolean; + procedure setsmooth(const avalue: boolean); + protected + fuser: tobject; + fintf: pointer; //icanvas; + fstate: canvasstatesty; + fvaluepo: canvasvaluespoty; + fdrawinfo: drawinfoty; + gcfonthandle1: fontnumty; + afonthandle1: fontnumty; + ffont: tfont; + + function getgdifuncs: pgdifunctionaty; virtual; + procedure registergclink(const dest: tcanvas); + procedure unregistergclink(const dest: tcanvas); + procedure gcdestroyed(const sender: tcanvas); virtual; + + procedure setppmm(avalue: real); virtual; + function getfitrect: rectty; virtual; + procedure valuechanged(value: canvasstatety); inline; + procedure valueschanged(values: canvasstatesty); inline; + procedure initgcvalues; virtual; + procedure initgcstate; virtual; + procedure finalizegcstate; virtual; + procedure checkrect(const rect: rectty); + procedure checkgcstate(state: canvasstatesty); virtual; + procedure checkregionstate; //copies region if necessary + function defaultcliprect: rectty; virtual; + function lock: boolean; virtual; + procedure unlock; virtual; + procedure doflush; + procedure gdi(const func: gdifuncty); virtual; + procedure init; + procedure beforeread; + procedure afterread; + procedure internalcopyarea(asource: tcanvas; const asourcerect: rectty; + const adestrect: rectty; acopymode: rasteropty; + atransparentcolor: colorty; + amask: tsimplebitmap; const amaskpos: pointty; + aalignment: alignmentsty; + //only al_stretchx, al_stretchy and al_tiled used + const atileorigin: pointty; + const aopacity: colorty); //cl_none -> opaque); + + procedure setcliporigin(const Value: pointty); + //value not saved! + function getgchandle: ptruint; + function getcanvasimage(const abgr: boolean = false): imagety; + function getimage(const bgr: boolean): maskedimagety; + + procedure fillarc(const def: rectty; const startang,extentang: real; + const acolor: colorty; const pieslice: boolean); + procedure getarcinfo(out startpo,endpo: pointty); + procedure internaldrawtext(var info); virtual; + //info = drawtextinfoty + function createfont: tcanvasfont; virtual; + procedure drawfontline(const startpoint,endpoint: pointty); + //draws line with font color + procedure nextpage; virtual; //used by tcustomprintercanvas + function getcontextinfopo: pointer; virtual; + procedure updatesize(const asize: sizety); virtual; + procedure movewindowrect(const adist: pointty; const arect: rectty); + procedure defineproperties(filer: tfiler); override; + public + target: tobject; //currently assigned widget in twidget.paint() + drawinfopo: pointer; //used to transport additional drawing information + constructor create(const user: tobject; const intf: icanvas); virtual; + destructor destroy; override; + class function getclassgdifuncs: pgdifunctionaty; virtual; + + procedure updatewindowoptions(var aoptions: internalwindowoptionsty); virtual; + function creategc(const apaintdevice: paintdevicety; const akind: gckindty; + var gc: gcty; const aprintername: msestring = ''): gdierrorty; + procedure linktopaintdevice(apaintdevice: paintdevicety; const gc: gcty; + const cliporigin: pointty); virtual; + //calls reset, resets cliporigin, canvas owns the gc! + procedure fitppmm(const asize: sizety); + //for printercanvas + function size: sizety; + + function highresdevice: boolean; + procedure initflags(const dest: tcanvas); virtual; + procedure unlink; //frees gc + procedure initdrawinfo(var adrawinfo: drawinfoty); + function active: boolean; + + procedure reset; virtual;//clears savestack, origin and clipregion + function save: integer; //returns current saveindex + function restore(index: integer = -1): integer; //-1 -> pop from stack + //returns current saveindex + procedure resetpaintedflag; + procedure endpaint; //opengl swap buffer + + procedure move(const dist: pointty); //add dist to origin + procedure remove(const dist: pointty); //sub dist from origin + + procedure copyarea(const asource: tcanvas; const asourcerect: rectty; + const adestpoint: pointty; const acopymode: rasteropty = rop_copy; + const atransparentcolor: colorty = cl_default; + //atransparentcolor used for convert color to monochrome + //cl_default -> colorbackground + const aopacity: colorty = cl_none); overload; + procedure copyarea(const asource: tcanvas; const asourcerect: rectty; + const adestrect: rectty; const alignment: alignmentsty = []; + const acopymode: rasteropty = rop_copy; + const atransparentcolor: colorty = cl_default; + //atransparentcolor used for convert color to monochrome + //cl_default -> colorbackground + const aopacity: colorty = cl_none); overload; + + procedure drawpoint(const point: pointty; const acolor: colorty = cl_default); + procedure drawpoints(const apoints: array of pointty; + const acolor: colorty = cl_default; + first: integer = 0; acount: integer = -1); //-1 -> all + + procedure drawline(const startpoint,endpoint: pointty; + const acolor: colorty = cl_default); + procedure drawline(const startpoint: pointty; const length: sizety; + const acolor: colorty = cl_default); + procedure drawlinesegments(const apoints: array of segmentty; + const acolor: colorty = cl_default); + + procedure drawlines(const apoints: array of pointty; + const aclosed: boolean = false; + const acolor: colorty = cl_default; + const first: integer = 0; const acount: integer = -1); overload; + //-1 = all + procedure drawlines(const apoints: array of pointty; + const abreaks: array of integer; //ascending order + const aclosed: boolean = false; + const acolor: colorty = cl_default; + const first: integer = 0; const acount: integer = -1); overload; + + procedure drawvect(const startpoint: pointty; + const direction: graphicdirectionty; + const length: integer; const acolor: colorty = cl_default); + overload; + procedure drawvect(const startpoint: pointty; + const direction: graphicdirectionty; + const length: integer; out endpoint: pointty; + const acolor: colorty = cl_default); overload; + + procedure drawrect(const arect: rectty; const acolor: colorty = cl_default); + procedure drawcross(const arect: rectty; const acolor: colorty = cl_default; + const alignment: alignmentsty = [al_xcentered,al_ycentered]); + + procedure drawellipse(const def: rectty; const acolor: colorty = cl_default); + //def.pos = center, def.cx = width, def.cy = height + procedure drawellipse1(const def: rectty; const acolor: colorty = cl_default); + //def.pos = topleft + procedure drawcircle(const center: pointty; const radius: integer; + const acolor: colorty = cl_default); + procedure drawarc(const def: rectty; const startang,extentang: real; + const acolor: colorty = cl_default); overload; + //def.pos = center, def.cx = width, def.cy = height + //startang,extentang in radiant (2*pi = 360deg CCW) + procedure drawarc1(const def: rectty; const startang,extentang: real; + const acolor: colorty = cl_default); + //def.pos = topleft + procedure drawarc(const center: pointty; const radius: integer; + const startang,extentang: real; + const acolor: colorty = cl_default); overload; + + procedure fillrect(const arect: rectty; const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); + procedure fillellipse(const def: rectty; const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); + //def.pos = center, def.cx = width, def.cy = height + procedure fillellipse1(const def: rectty; const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); + //def.pos = topleft + procedure fillcircle(const center: pointty; const radius: integer; + const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); + procedure fillarcchord(const def: rectty; const startang,extentang: real; + const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); overload; + //def.pos = center, def.cx = width, def.cy = height + //startang,extentang in radiant (2*pi = 360deg CCW) + procedure fillarcchord1(const def: rectty; const startang,extentang: real; + const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); + //def.pos = topleft + procedure fillarcchord(const center: pointty; const radius: integer; + const startang,extentang: real; + const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); overload; + procedure fillarcpieslice(const def: rectty; const startang,extentang: real; + const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); overload; + //def.pos = center, def.cx = width, def.cy = height + //startang,extentang in radiant (2*pi = 360deg CCW) + procedure fillarcpieslice1(const def: rectty; const startang,extentang: real; + const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); overload; + //def.pos = topleft + procedure fillarcpieslice(const center: pointty; const radius: integer; + const startang,extentang: real; + const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); overload; + procedure fillpolygon(const apoints: array of pointty; + const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); + + procedure drawframe(const arect: rectty; awidth: integer = -1; + const acolor: colorty = cl_default; + const hiddenedges: edgesty = []); overload; + //no dashes, awidth < 0 -> inside frame,! + procedure drawframe(const arect: rectty; awidth: framety; + const acolor: colorty = cl_default; + const hiddenedges: edgesty = []); overload; + procedure drawxorframe(const arect: rectty; const awidth: integer = -1; + const abrush: tsimplebitmap = nil); overload; + procedure drawxorframe(const po1: pointty; const po2: pointty; + const awidth: integer = -1; + const abrush: tsimplebitmap = nil); overload; + procedure fillxorrect(const arect: rectty; + const abrush: tsimplebitmap = nil); overload; + procedure fillxorrect(const start: pointty; const length: integer; + const direction: graphicdirectionty; + const awidth: integer = 0; + const abrush: tsimplebitmap = nil); overload; + procedure drawstring(const atext: msestring; const apos: pointty; + const afont: tfont = nil; const grayed: boolean = false; + const arotation: real = 0); overload; + //0..2*pi-> 0degree..360degree CCW + procedure drawstring(const atext: pmsechar; const acount: integer; const apos: pointty; + const afont: tfont = nil; const grayed: boolean = false; + const arotation: real = 0); overload; + function getstringwidth(const atext: msestring; + const afont: tfont = nil): integer; overload; + function getstringwidth(const atext: pmsechar; const acount: integer; + const afont: tfont = nil): integer; overload; + //sum of cellwidths + function getfontmetrics(const achar: ucs4char; + const afont: tfont = nil): fontmetricsty; + function getfontmetrics(const achar: msechar; + const afont: tfont = nil): fontmetricsty; + + //all boundaries of regionrects are clipped to + // -$8000..$7fff in device space + procedure resetclipregion; + procedure setcliprect(const rect: rectty); + procedure addcliprect(const rect: rectty); + procedure addclipframe(const frame: rectty; inflate: integer); + procedure subcliprect(const rect: rectty); + procedure subclipframe(const frame: rectty; inflate: integer); + procedure intersectcliprect(const rect: rectty); + procedure intersectclipframe(const frame: rectty; inflate: integer); + + procedure addclipregion(const region: regionty); + procedure subclipregion(const region: regionty); + procedure intersectclipregion(const region: regionty); + + function copyclipregion: regionty; + //returns a copy of the current clipregion + + function clipregionisempty: boolean; //true if no drawing possible + function clipbox: rectty; //smallest possible rect around clipregion + + function createregion: regionty; overload; + function createregion(const asource: regionty): regionty; overload; + function createregion(const arect: rectty): regionty; overload; + function createregion(const rects: array of rectty): regionty; overload; + function createregion(frame: rectty; const inflate: integer): regionty; overload; + procedure destroyregion(region: regionty); + + procedure regmove(const adest: regionty; const dist: pointty); + procedure regremove(const adest: regionty; const dist: pointty); + procedure regaddrect(const dest: regionty; const rect: rectty); + procedure regsubrect(const dest: regionty; const rect: rectty); + procedure regintersectrect(const dest: regionty; const rect: rectty); + procedure regaddregion(const dest: regionty; const region: regionty); + procedure regsubregion(const dest: regionty; const region: regionty); + procedure regintersectregion(const dest: regionty; const region: regionty); + + function regionisempty(const region: regionty): boolean; + function regionclipbox(const region: regionty): rectty; + //returns nullrect if region = 0 + + property origin: pointty read getorigin write setorigin; + property clipregion: regionty {read getclipregion} write setclipregion; + //canvas owns the region! + +// property monochrome: boolean read getmonochrome; + property kind: bitmapkindty read getkind; + property color: colorty read getcolor write setcolor default cl_black; + property colorbackground: colorty read getcolorbackground + write setcolorbackground default cl_transparent; + property rasterop: rasteropty read getrasterop write setrasterop default rop_copy; + property font: tfont read ffont write setfont; + property brush: tsimplebitmap read getbrush write setbrush; + property brushorigin: pointty read getbrushorigin write setbrushorigin; + property rootbrushorigin: pointty read getrootbrushorigin write setrootbrushorigin; + //origin = paintdevice top left + procedure adjustbrushorigin(const arect: rectty; + const alignment: alignmentsty); + + property linewidth: integer read getlinewidth write setlinewidth default 0; + property linewidthmm: real read getlinewidthmm write setlinewidthmm; + + property dashes: dashesstringty read getdashes write setdashes; + //todo: dashoffset + property capstyle: capstylety read getcapstyle write setcapstyle + default cs_butt; + property joinstyle: joinstylety read getjoinstyle write setjoinstyle + default js_miter; + property smooth: boolean read getsmooth write setsmooth; + property options: canvasoptionsty read getoptions write setoptions + default []; + + property paintdevice: paintdevicety read fdrawinfo.paintdevice; + property gchandle: ptruint read getgchandle; + property ppmm: real read fdrawinfo.gc.ppmm write setppmm; + //used for linewidth mm, value not saved/restored + property statestamp: longword read fdrawinfo.statestamp; + //incremented by drawing operations + end; + + pixmapstatety = ({pms_monochrome,}pms_ownshandle,pms_maskvalid,pms_nosave, + pms_staticcanvas); + pixmapstatesty = set of pixmapstatety; + + pixmapinfoty = record + handle: pixmapty; + size: sizety; + depth: integer; + end; + + tsimplebitmap = class(tnullinterfacedpersistent,icanvas) + private + function gethandle: pixmapty; + procedure sethandle(const Value: pixmapty); + function getcanvas: tcanvas; + procedure switchtomonochrome; + procedure setwidth(const avalue: integer); + procedure setheight(const avalue: integer); + { + function getgrayscale: boolean; + procedure setgrayscale(const avalue: boolean); + function getmonochrome: boolean; + procedure setmonochrome(const avalue: boolean); + } + protected + fgdifuncs: pgdifunctionaty; + fcanvasclass: canvasclassty; + fcanvas: tcanvas; + fhandle: pixmapty; + fsize: sizety; + fscanlinestep: integer; //bytes + fscanlinewords: integer; + fscanhigh: integer; + fkind: bitmapkindty; + fstate: pixmapstatesty; + fcolorbackground: colorty; + fcolorforeground: colorty; + fdefaultcliporigin: pointty; + procedure updatescanline(); + function createcanvas: tcanvas; virtual; + procedure creategc; + procedure internaldestroyhandle; + procedure destroyhandle; virtual; + procedure createhandle(acopyfrom: pixmapty); virtual; + procedure setkind(const avalue: bitmapkindty); virtual; + function getconverttomonochromecolorbackground: colorty; virtual; + function getmask(out apos: pointty): tsimplebitmap; virtual; + procedure setsize(const avalue: sizety); virtual; + function normalizeinitcolor(const acolor: colorty): colorty; + procedure assign1(const source: tsimplebitmap; const docopy: boolean); virtual; + function getgdiintf: pgdifunctionaty; + //icanvas + procedure gcneeded(const sender: tcanvas); + function getsize: sizety; + function getkind: bitmapkindty; + procedure getcanvasimage(const bgr: boolean; + var aimage: maskedimagety); virtual; + public + constructor create(const akind: bitmapkindty; + const agdifuncs: pgdifunctionaty = nil); reintroduce; + //nil -> default + destructor destroy; override; + + procedure copyhandle; + procedure releasehandle; virtual; + procedure acquirehandle; virtual; + property handle: pixmapty read gethandle write sethandle; + + procedure assign(source: tpersistent); override; + procedure assignnegative(source: tsimplebitmap); + //gets negative copy + procedure clear; virtual;//sets with and height to 0 + procedure init(const acolor: colorty); virtual; + procedure freecanvas; + function canvasallocated: boolean; + procedure copyarea(const asource: tsimplebitmap; const asourcerect: rectty; + const adestpoint: pointty; const acopymode: rasteropty = rop_copy; + const masked: boolean = true; + const acolorforeground: colorty = cl_default; + //cl_default -> asource.colorforeground + //used for monochrome -> color conversion + const acolorbackground: colorty = cl_default; + //cl_default -> asource.colorbackground + //used for monochrome -> color conversion or + //colorbackground for color -> monochrome conversion + const aopacity: colorty = cl_none); overload; + procedure copyarea(const asource: tsimplebitmap; const asourcerect: rectty; + const adestrect: rectty; const aalignment: alignmentsty = []; + const acopymode: rasteropty = rop_copy; + const masked: boolean = true; + const acolorforeground: colorty = cl_default; + //cl_default -> asource.colorforeground + //used for monochrome -> color conversion + const acolorbackground: colorty = cl_default; + //cl_default -> asource.colorbackground + //used for monochrome -> color conversion or + //colorbackground for color -> monochrome conversion + const aopacity: colorty = cl_none); overload; + + property kind: bitmapkindty read fkind write setkind; + { + property monochrome: boolean read getmonochrome write setmonochrome; + property grayscale: boolean read getgrayscale write setgrayscale; + } + property canvas: tcanvas read getcanvas; + property size: sizety read fsize write setsize; + //pixels are not initialized + property width: integer read fsize.cx write setwidth; + property height: integer read fsize.cy write setheight; + function isempty: boolean; + end; + +const + {$ifdef FPC} + {$warnings off} + {$endif} + nullgc: gcty = (handle: 0); + {$ifdef FPC} + {$warnings on} + {$endif} + changedmask = [cs_clipregion,cs_origin,cs_rasterop,cs_options, + cs_acolorbackground,cs_acolorforeground, + cs_color,cs_colorbackground, + cs_fonthandle,cs_font,cs_fontcolor,cs_fontcolorbackground, + cs_fonteffect, + cs_brush,cs_brushorigin] + linecanvasstates; + +type + editfontcolorinfoty = record + text: colorty; + textbackground: colorty; + selectedtext: colorty; + selectedtextbackground: colorty; + end; + +var + defaultframecolors: framecolorinfoty = + (edges:(light: (color: cl_light; effectcolor: cl_highlight; effectwidth: 1); + shadow: (color: cl_shadow; effectcolor: cl_dkshadow; effectwidth: 1); + ); + frame: cl_black; + hiddenedges: [] + ); + + defaulteditfontcolors: editfontcolorinfoty = ( + text: cl_text; + textbackground: cl_transparent; + selectedtext: cl_selectedtext; + selectedtextbackground: cl_selectedtextbackground; + ); + +procedure init; +procedure deinit; + +procedure initdefaultvalues(var avalue: edgecolorinfoty); +procedure initdefaultvalues(var avalue: edgecolorpairinfoty); +procedure drawinfoinit(var info: drawinfoty); + +procedure gdi_lock(); +procedure gdi_unlock(); +function gdi_locked(): boolean; +function gdi_unlockall(): int32; +procedure gdi_relockall(const acount: int32); + +procedure gdi_call(const func: gdifuncty; var drawinfo: drawinfoty; + gdi: pgdifunctionaty = nil); +function getdefaultgdifuncs: pgdifunctionaty;{$ifdef FPC}inline;{$endif} +function registergdi(const agdifuncs: pgdifunctionaty): integer; + //returns unique number +function getgdicanvasclass(const agdi: pgdifunctionaty; + const akind: bitmapkindty): canvasclassty; +function creategdicanvas(const agdi: pgdifunctionaty; + const akind: bitmapkindty; + const user: tobject; const intf: icanvas): tcanvas; + +procedure freefontdata(var drawinfo: drawinfoty); + +procedure allocbuffer(var buffer: bufferty; size: integer); +procedure extendbuffer(var buffer: bufferty; const extension: integer; + var reference: pointer); +function replacebuffer(var buffer: bufferty; size: integer): pointer; +procedure freebuffer(var buffer: bufferty); + +procedure gdierrorlocked(error: gdierrorty; const text: msestring = ''); overload; +procedure gdierrorlocked(error: gdierrorty; sender: tobject; + text: msestring = ''); overload; + +function colortorgb(color: colorty): rgbtriplety; +function colortopixel(color: colorty): pixelty; +function graytopixel(color: colorty): pixelty; +function rgbtocolor(const red,green,blue: integer): colorty; +function blendcolor(const weight: real; const a,b: colorty): colorty; + //0..1 +function opacitycolor(const opacity: real): colorty; +function invertcolor(const color: colorty): colorty; + +procedure setcolormapvalue(index: colorty; const red,green,blue: integer); overload; + //RGB values 0..255 +procedure setcolormapvalue(const index: colorty; const acolor: colorty); overload; +function isvalidmapcolor(index: colorty): boolean; +function transparencytoopacity(const trans: colorty): colorty; + +procedure drawdottedlinesegments(const acanvas: tcanvas; const lines: segmentarty; + const colorline: colorty); + +procedure allocimage(out image: imagety; const asize: sizety; + const akind: bitmapkindty); +procedure freeimage(var image: imagety); +procedure freeimage(var image: maskedimagety); +procedure zeropad(var image: imagety); +procedure checkimagebgr(var aimage: imagety; const bgr: boolean); +procedure movealignment(const source: alignmentsty; var dest: alignmentsty); + +var + flushgdi: boolean; +{$ifdef mse_debuggdisync} +procedure checkgdilock; +procedure checkgdiunlocked; +{$endif} + +implementation +uses + SysUtils,msegui,mseguiintf,msestreaming,mseformatstr,msestockobjects, + msearrayutils,mselist,msebits,msewidgets,msesystypes, + msesysintf1,msesysintf,msesysutils,msefont; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + lineoptionty = (lio_antialias); + lineoptionsty = set of lineoptionty; + +var + gdilockcount: integer; + gdilockthread: threadty; + +procedure initdefaultvalues(var avalue: edgecolorinfoty); +begin + avalue.color:= cl_default; + avalue.effectcolor:= cl_default; + avalue.effectwidth:= -1; +end; + +procedure initdefaultvalues(var avalue: edgecolorpairinfoty); +begin + initdefaultvalues(avalue.shadow); + initdefaultvalues(avalue.light); +end; + +procedure drawinfoinit(var info: drawinfoty); +begin + if flushgdi then begin + fillchar(info.gc.platformdata,sizeof(info.gc.platformdata),0); + end; +end; + +{$ifdef mse_debuggdisync} +procedure gdilockerror(const text: msestring); +var + str1: string; +begin + str1:= text+lineend+ + 'currentth:'+inttostr(sys_getcurrentthread)+ + ' mainth:'+inttostr(application.mainthread)+ + ' applockth:'+inttostr(application.lockthread)+ + ' applockc:'+inttostr(application.lockcount)+lineend+ + ' gdilockc:'+inttostr(gdilockcount)+lineend+ + 'appmutexlockth:'+inttostr(appmutexlockth)+ + ' appmutexunlockth:'+inttostr(appmutexunlockth)+ + ' appmutexlockc:'+inttostr(appmutexlockc)+ + ' appmutexunlockc:'+inttostr(appmutexunlockc)+ + ' appmutexlocks:'+inttostr(appmutexlocks)+ + ' appmutexunlocks:'+inttostr(appmutexunlocks); + debugwriteln(str1); + debugwritestack; +end; + +procedure checkgdilock; +begin + if not application.islockedthread then begin + gdilockerror('GDI lock error.'); + end; +end; + +procedure checkgdiunlocked; +begin + if gdilockcount <> 0 then begin + gdilockerror('GDI unlock error.'); + end; +end; +{$endif} + +function transparencytoopacity(const trans: colorty): colorty; +begin + result:= trans; + if trans <= $00ffffff then begin + result:= result xor $00ffffff; + end; +end; + +procedure movealignment(const source: alignmentsty; var dest: alignmentsty); +begin + dest:= alignmentsty(setsinglebit( + longword(source),longword(dest), + [longword([al_intpol,al_or,al_and]), + longword([al_left,al_xcentered,al_right]), + longword([al_top,al_ycentered,al_bottom]), + longword([al_fit,al_thumbnail,al_tiled])])); +end; + +procedure allocimage(out image: imagety; const asize: sizety; + const akind: bitmapkindty); +begin + with image do begin +// monochrome:= amonochrome; + kind:= akind; + bgr:= false; + pixels:= nil; + size:= asize; + length:= 0; + linelength:= 0; + linebytes:= 0; + if (size.cx <> 0) and (size.cy <> 0) then begin + case kind of + bmk_mono: begin + linelength:= (size.cx+31) div 32; + end; + bmk_gray: begin + linelength:= (size.cx+3) div 4; + end; + else begin + linelength:= size.cx; + length:= size.cy * size.cx; + end; + end; + length:= size.cy * linelength; + linebytes:= linelength * 4; + pixels:= gui_allocimagemem(length); + end; + end; +end; + +procedure freeimage(var image: imagety); +begin + if image.pixels <> nil then begin + gui_freeimagemem(image.pixels); + fillchar(image,sizeof(image),0); + end; +end; + +procedure freeimage(var image: maskedimagety); +begin + freeimage(image.image); + freeimage(image.mask); +end; + +procedure zeropad(var image: imagety); +var + mask: longword; + step: integer; + po1: plongword; + int1: integer; +begin + with image do begin //todo: little/big endian + case kind of + bmk_mono: begin + mask:= bitmask[size.cx and $1f]; + end; + bmk_gray: begin + case size.cx and $3 of + 0: begin + mask:= 0; + end; + 1: begin + mask:= $000000ff; + end; + 2: begin + mask:= $0000ffff; + end; + 3: begin + mask:= $00ffffff; + end; + end; + end + else begin + mask:= 0; + end; + if mask <> 0 then begin + step:= linelength; + po1:= @pixels[step-1]; + for int1:= size.cy - 1 downto 0 do begin + po1^:= po1^ and mask; //mask padding + inc(po1,step); + end; + end; + end; + end; +end; + +procedure checkimagebgr(var aimage: imagety; const bgr: boolean); +var + by1: byte; + int1: integer; + po1: prgbtriplety; +begin + if (aimage.kind = bmk_rgb) and (aimage.bgr xor bgr) then begin + po1:= prgbtriplety(aimage.pixels); + for int1:= aimage.length-1 downto 0 do begin + by1:= po1^.red; + po1^.red:= po1^.blue; + po1^.blue:= by1; + inc(po1); + end; + aimage.bgr:= bgr; + end; +end; + +var + gdinum: integer; + gdifuncs: array of pgdifunctionaty; + +function getdefaultgdifuncs: pgdifunctionaty; {$ifdef FPC}inline;{$endif} +begin + if gdifuncs = nil then begin + gui_registergdi; + end; + result:= gdifuncs[0]; +end; + +function registergdi(const agdifuncs: pgdifunctionaty): integer; + //returns unique number +var + int1: integer; +begin + for int1:= 0 to high(gdifuncs) do begin + if gdifuncs[int1] = agdifuncs then begin + result:= int1; + exit; + end; + end; + setlength(gdifuncs,gdinum+1); //item 0 = system default + gdifuncs[gdinum]:= agdifuncs; + result:= gdinum; + inc(gdinum); +end; + +procedure gdi_lock(); +begin + application.lock(); + gdilockthread:= sys_getcurrentthread(); + if (gdilockcount = 0) and not application.ismainthread then begin + gui_disconnectmaineventqueue(); + end; + inc(gdilockcount); +end; + +procedure gdi_unlock(); +begin + dec(gdilockcount); + if gdilockcount = 0 then begin + gdilockthread:= 0; + if not application.ismainthread then begin + gui_connectmaineventqueue(); + end; + end; + application.unlock(); +end; + +function gdi_locked(): boolean; +begin + result:= (gdilockcount > 0) or application.islockedmainthread(); +end; + +function gdi_unlockall(): int32; +begin + if gdilockthread = sys_getcurrentthread() then begin + result:= gdilockcount; + if result > 1 then begin + gdilockcount:= 1; + end; + if result > 0 then begin + gdi_unlock(); + end; + end + else begin + result:= 0; + end; +end; + +procedure gdi_relockall(const acount: int32); +begin + if acount > 0 then begin + gdi_lock(); + gdilockcount:= gdilockcount + acount - 1; + end; +end; + +procedure gdi_call(const func: gdifuncty; var drawinfo: drawinfoty; + gdi: pgdifunctionaty = nil); + + procedure doflush(); + begin + gdi^[gdf_flush](drawinfo); + gui_flushgdi(); + end; //doflush + +begin + if gdi = nil then begin + gdi:= gdifuncs[0];//gui_getgdifuncs; + end; + if not gdi_locked() then begin + gdi_lock(); + try + gdi^[func](drawinfo); + if flushgdi then begin + doflush() + end; + finally + gdi_unlock(); + end; + end + else begin + gdi^[func](drawinfo); + if flushgdi then begin + doflush(); + end; + end; +end; + +procedure drawdottedlinesegments(const acanvas: tcanvas; const lines: segmentarty; + const colorline: colorty); + {$ifdef mswindows} +var + int1: integer; +// int2: integer; + {$endif} +begin + acanvas.save; + acanvas.color:= colorline; + acanvas.brush:= stockobjects.bitmaps[stb_dens50]; +{$ifdef mswindows} + {workaround: colors are wrong by negativ x on win2000! bug?} + { + int2:= levelshift; + acanvas.remove(makepoint(int2,0)); + for int1:= 0 to high(lines) do begin + inc(lines[int1].a.x,int2); + inc(lines[int1].b.x,int2); + end; + } + if iswin95 then begin //win95 can not draw brushed lines + for int1:= 0 to high(lines) do begin + with lines[int1] do begin + if a.x <> b.x then begin + acanvas.fillrect(makerect(a.x,a.y,b.x-a.x+1,1),cl_brushcanvas); + end + else begin + acanvas.fillrect(makerect(a.x,a.y,1,b.y-a.y+1),cl_brushcanvas); + end; + end; + end; + end + else begin +{$endif} + acanvas.drawlinesegments(lines,cl_brushcanvas); +{$ifdef mswindows} + end; +{$endif} + acanvas.restore; +end; + +var + colormaps: array[colormapsty] of array of pixelty; + inited: boolean; + +function checkfontoptions(const new,old: fontoptionsty): fontoptionsty; +const + mask1: fontoptionsty = fontpitchmask; + mask2: fontoptionsty = fontfamilymask; + mask3: fontoptionsty = fontantialiasedmask; +// mask4: fontoptionsty = fontxcoremask; +var + value1: fontoptionsty; + value2: fontoptionsty; + value3: fontoptionsty; +// value4: fontoptionsty; +begin + value1:= fontoptionsty( + setsinglebit({$ifdef FPC}longword{$else}word{$endif}(new), + {$ifdef FPC}longword{$else}word{$endif}(old), + {$ifdef FPC}longword{$else}word{$endif}(mask1))); + value2:= fontoptionsty( + setsinglebit({$ifdef FPC}longword{$else}word{$endif}(new), + {$ifdef FPC}longword{$else}word{$endif}(old), + {$ifdef FPC}longword{$else}word{$endif}(mask2))); + value3:= fontoptionsty( + setsinglebit({$ifdef FPC}longword{$else}word{$endif}(new), + {$ifdef FPC}longword{$else}word{$endif}(old), + {$ifdef FPC}longword{$else}word{$endif}(mask3))); +(* + value4:= fontoptionsty( + setsinglebit({$ifdef FPC}longword{$else}byte{$endif}(new), + {$ifdef FPC}longword{$else}byte{$endif}(old), + {$ifdef FPC}longword{$else}byte{$endif}(mask4))); +*) + result:= value1 * mask1 + value2 * mask2 + value3 * mask3 {+ value4 * mask4}; +end; + +procedure freebuffer(var buffer: bufferty); +begin + if buffer.buffer <> nil then begin +// freemem(buffer.buffer,buffer.size); + freemem(buffer.buffer); + buffer.size:= 0; + buffer.buffer:= nil; + end; +end; + +procedure allocbuffer(var buffer: bufferty; size: integer); +begin + if size > buffer.size then begin + freebuffer(buffer); + getmem(buffer.buffer,size); + buffer.size:= size; + end; +end; + +procedure extendbuffer(var buffer: bufferty; const extension: integer; + var reference: pointer); +var + po1: pointer; +begin + with buffer do begin + cursize:= cursize + extension; + if cursize > size then begin + size:= cursize*2+1024; + po1:= buffer; + reallocmem(buffer,size); + reference:= reference + (buffer-po1); + end; + end; +end; + +function replacebuffer(var buffer: bufferty; size: integer): pointer; +begin + result:= buffer.buffer; + getmem(buffer.buffer,size); + buffer.size:= size; +end; + +procedure gdierrorlocked(error: gdierrorty; const text: msestring = ''); overload; +begin + gdi_unlock; + gdierror(error,text); +end; + +procedure gdierrorlocked(error: gdierrorty; sender: tobject; + text: msestring = ''); overload; +begin + gdi_unlock; + gdierror(error,sender,text); +end; + +function getdefaultcolorinfo(map: colormapsty; index: integer): pcolorinfoty; +begin + case map of + cm_functional: begin + result:= @defaultfunctional[index]; + end; + cm_mapped: begin + result:= @defaultmapped[index]; + end; + cm_namedrgb: begin + result:= @defaultnamedrgb[index]; + end; + cm_user: begin + result:= @defaultuser[index]; + end; + else begin + result:= nil; + end; + end; +end; + +function colortorgb(color: colorty): rgbtriplety; +var + map: colormapsty; +begin + map:= colormapsty((longword(color) shr speccolorshift)); + color:= colorty(longword(color) and not speccolormask); + if map = cm_rgb then begin + result:= rgbtriplety(color); + end + else begin + dec(map,7); + if (map < cm_rgb) or (map > high(map)) or + (longword(color) >= longword(mapcolorcounts[map])) then begin + result:= colortorgb(cl_invalid); +{ + gdierror(gde_invalidcolor, + hextostrmse(longword(color)+longword(map) shl speccolorshift,8)); +} + end + else begin + result:= rgbtriplety(gui_pixeltorgb(colormaps[map][longword(color)])); + end; + end; +end; + +function colortopixel(color: colorty): pixelty; +var + map: colormapsty; +begin + map:= colormapsty((longword(color) shr speccolorshift)); + color:= colorty(longword(color) and not speccolormask); + if map = cm_rgb then begin + result:= gui_rgbtopixel(color); + end + else begin + dec(map,7); + if (map < cm_rgb) or (map > high(map)) or + (longword(color) >= longword(mapcolorcounts[map])) then begin + result:= colortopixel(cl_invalid); +{ + gdierror(gde_invalidcolor, + hextostrmse(longword(color)+longword(map) shl speccolorshift,8)); +} + end + else begin + result:= colormaps[map][longword(color)]; + end; + end; +end; + +function graytopixel(color: colorty): pixelty; +var + co1: rgbtriplety; + by1: byte; +begin + pixelty(co1):= colortopixel(color); + by1:= (integer(co1.red)+integer(co1.green)+integer(co1.blue)) div 3; + result:= by1 or (by1 shl 8) or (by1 shl 16); +end; + +function rgbtocolor(const red,green,blue: integer): colorty; +begin + result:= (blue and $ff) or ((green and $ff) shl 8) or ((red and $ff) shl 16); +end; + +function blendcolor(const weight: real; const a,b: colorty): colorty; +var +// by1: byte; + ca,cb: rgbtriplety; +begin + ca:= colortorgb(a); + cb:= colortorgb(b); + rgbtriplety(result).red:= ca.red + round((cb.red - ca.red)*weight); + rgbtriplety(result).green:= ca.green + round((cb.green - ca.green)*weight); + rgbtriplety(result).blue:= ca.blue + round((cb.blue - ca.blue)*weight); + rgbtriplety(result).res:= 0; +end; + +function opacitycolor(const opacity: real): colorty; +begin + with rgbtriplety(result) do begin + red:= round(255 * opacity); + green:= red; + blue:= red; + res:= 0; + end; +end; + +function invertcolor(const color: colorty): colorty; +begin + rgbtriplety(result):= colortorgb(color); + with rgbtriplety(result) do begin + red:= 255-red; + green:= 255-green; + blue:= 255-blue; + end; +end; + +function initcolormap: boolean; +var + colormap: colormapsty; + int1: integer; +begin + result:= true; + for colormap:= low(colormapsty) to high(colormapsty) do begin + setlength(colormaps[colormap],mapcolorcounts[colormap]); + {$ifdef FPC} {$checkpointer off} {$endif} + for int1:= 0 to mapcolorcounts[colormap] - 1 do begin + colormaps[colormap][int1]:= gui_rgbtopixel( + longword(getdefaultcolorinfo(colormap,int1)^.rgb)); + end; + {$ifdef FPC} {$checkpointer default} {$endif} + end; + colormaps[cm_namedrgb,integer(longword(cl_0)-longword(cl_namedrgb))]:= + mseguiintf.pixel0; + colormaps[cm_namedrgb,integer(longword(cl_1)-longword(cl_namedrgb))]:= + mseguiintf.pixel1; + gui_initcolormap; +end; + +function isvalidmapcolor(index: colorty): boolean; +var + map: colormapsty; +begin + result:= true; + application.initialize; //colormap must be valid + map:= colormapsty((longword(index) shr speccolorshift)); + index:= colorty(longword(index) and not speccolormask); + dec(map,7); + if (map <= cm_rgb) or (map > high(map)) or + (longword(index) >= longword(mapcolorcounts[map])) then begin + result:= false; + end; +end; + +procedure setcolormapvalue(index: colorty; const red,green,blue: integer); +var + map: colormapsty; +begin + application.initialize; //colormap must be valid + map:= colormapsty((longword(index) shr speccolorshift)); + index:= colorty(longword(index) and not speccolormask); + dec(map,7); + if (map <= cm_rgb) or (map > high(map)) or + (longword(index) >= longword(mapcolorcounts[map])) then begin + gdierror(gde_invalidcolor, + hextostrmse(longword(index)+longword(map) shl speccolorshift,8)); + end; + colormaps[map][longword(index)]:= gui_rgbtopixel(rgbtocolor(red,green,blue)); +end; + +procedure setcolormapvalue(const index: colorty; const acolor: colorty); +var + rgb1: rgbtriplety; +begin + rgb1:= colortorgb(acolor); + setcolormapvalue(index,rgb1.red,rgb1.green,rgb1.blue); +end; + +function getgdicanvasclass(const agdi: pgdifunctionaty; + const akind: bitmapkindty): canvasclassty; +var + info1: drawinfoty; +begin +{$warnings off} + with info1.getcanvasclass do begin + kind:= akind; + canvasclass:= tcanvas; //default + agdi^[gdf_getcanvasclass](info1); + result:= canvasclass; + end; +end; +{$warnings on} + +function creategdicanvas(const agdi: pgdifunctionaty; + const akind: bitmapkindty; const user: tobject; + const intf: icanvas): tcanvas; +begin + result:= getgdicanvasclass(agdi,akind).create(user,intf); +end; + +procedure freefontdata(var drawinfo: drawinfoty); +begin + drawinfo.getfont.fontdata^.h.d.gdifuncs^[gdf_freefontdata](drawinfo); +end; + +procedure init; +var + icon,mask: pixmapty; +begin + gdi_lock; + try + initcolormap; + msefont.init; + msestockobjects.init; + inited:= true; + getwindowicon(nil,icon,mask); + gui_setapplicationicon(icon,mask); + finally + gdi_unlock; + end; +end; + +procedure deinit; +begin + if inited then begin + msestockobjects.deinit; + msefont.deinit; + end; + inited:= false; +end; + + + { tsimplebitmap } + +constructor tsimplebitmap.create(const akind: bitmapkindty; + const agdifuncs: pgdifunctionaty = nil); +begin + fgdifuncs:= agdifuncs; + if fgdifuncs = nil then begin + fgdifuncs:= getdefaultgdifuncs; + end; + fcanvasclass:= getgdicanvasclass(fgdifuncs,kind); + fkind:= akind; +// if monochrome then begin +// include(fstate,pms_monochrome); +// end; + fcolorbackground:= cl_white; + fcolorforeground:= cl_black; +end; + +destructor tsimplebitmap.destroy; +begin + inherited; + destroyhandle; + freeandnil(fcanvas); +end; + +procedure tsimplebitmap.freecanvas; +begin + if pms_staticcanvas in fstate then begin + if fcanvas <> nil then begin + fcanvas.reset; + end; + end + else begin + freeandnil(fcanvas); + end; +end; + +function tsimplebitmap.canvasallocated: boolean; +begin + result:= fcanvas <> nil; +end; + +procedure tsimplebitmap.clear; +begin + size:= nullsize; +end; +{ +function tsimplebitmap.getmonochrome: boolean; +begin + result:= fkind = bmk_mono; +// result:= pms_monochrome in fstate; +end; + +procedure tsimplebitmap.setmonochrome(const avalue: boolean); +begin + kind:= bmk_mono; +end; + +function tsimplebitmap.getgrayscale: boolean; +begin + result:= fkind = bmk_gray; +end; + +procedure tsimplebitmap.setgrayscale(const avalue: boolean); +begin + kind:= bmk_gray; +end; +} +function tsimplebitmap.getconverttomonochromecolorbackground: colorty; +begin + result:= fcolorbackground; +end; +(* +procedure tsimplebitmap.setmonochrome(const avalue: boolean); +var + bmp: tsimplebitmap; + ahandle: pixmapty; +begin + if avalue <> getmonochrome then begin + if isempty then begin + if avalue then begin + fkind:= bmk_mono; + end + else begin + fkind:= bmk_rgb; + end; + { + if avalue then begin + include(fstate,pms_monochrome); + end + else begin + exclude(fstate,pms_monochrome); + end + } + end + else begin + if avalue then begin + bmp:= tsimplebitmap.create(bmk_mono,fgdifuncs); + bmp.size:= fsize; + bmp.canvas.copyarea(canvas,makerect(nullpoint,fsize),nullpoint,rop_copy, + getconverttomonochromecolorbackground); + end + else begin + bmp:= tsimplebitmap.create(bmk_rgb,fgdifuncs); + bmp.size:= fsize; + bmp.canvas.colorbackground:= fcolorbackground; + bmp.canvas.color:= fcolorforeground; + bmp.canvas.copyarea(canvas,makerect(nullpoint,fsize),nullpoint); + end; + ahandle:= bmp.fhandle; + bmp.releasehandle; + bmp.Free; + handle:= ahandle; + acquirehandle; + end; + end; +end; +*) +procedure tsimplebitmap.setkind(const avalue: bitmapkindty); +var + bmp: tsimplebitmap; + ahandle: pixmapty; +begin + if fkind <> avalue then begin + if isempty then begin + destroyhandle(); + fkind:= avalue; + end + else begin + bmp:= tsimplebitmap.create(avalue,fgdifuncs); + bmp.size:= fsize; + case avalue of + bmk_mono: begin + bmp.canvas.copyarea(canvas,makerect(nullpoint,fsize),nullpoint,rop_copy, + getconverttomonochromecolorbackground); + end; + else begin + bmp.canvas.colorbackground:= fcolorbackground; + bmp.canvas.color:= fcolorforeground; + bmp.canvas.copyarea(canvas,makerect(nullpoint,fsize),nullpoint); + end; + end; + ahandle:= bmp.fhandle; + bmp.releasehandle; + bmp.Free; + fkind:= avalue; + handle:= ahandle; + acquirehandle; + end; + end; +end; + + +procedure tsimplebitmap.switchtomonochrome; +begin +// include(fstate,pms_monochrome); + fkind:= bmk_mono; + if fcanvas <> nil then begin + fcanvas.init; + end; +end; + +procedure tsimplebitmap.creategc; +var + gc: gcty; + err: gdierrorty; +begin + if fcanvas <> nil then begin + fillchar(gc,sizeof(gcty),0); + gc.drawingflags:= [df_canvasispixmap]; + gc.paintdevicesize:= fsize; +// if pms_monochrome in fstate then begin + if fkind = bmk_mono then begin + include(gc.drawingflags,df_canvasismonochrome); + end; + gc.kind:= fkind; + gdi_lock; + err:= fcanvas.creategc(fhandle,gck_pixmap,gc); + gdi_unlock; + gdierror(err,self); + fcanvas.linktopaintdevice(fhandle,gc,fdefaultcliporigin); + end; +end; + +function tsimplebitmap.createcanvas: tcanvas; +begin + result:= fcanvasclass.create(self,icanvas(self)); +end; + +function tsimplebitmap.getcanvas: tcanvas; +begin + if fcanvas = nil then begin + fcanvas:= createcanvas; + end; + result:= fcanvas; +end; + +procedure tsimplebitmap.createhandle(acopyfrom: pixmapty); + //copyfrom does not work on windows with in dc selected bmp! +var + info: drawinfoty; +begin + if (fsize.cx > 0) and (fsize.cy > 0) then begin + if fhandle = 0 then begin +{$warnings off} + drawinfoinit(info); + with info.createpixmap do begin + size:= fsize; +// monochrome:= (pms_monochrome in fstate); + kind:= fkind; + copyfrom:= acopyfrom; + handle:= 0; + gdi_call(gdf_createpixmap,info,getgdiintf); + fhandle:= pixmap; + end; +// gdi_lock; +// fhandle:= gui_createpixmap(fsize,0,(pms_monochrome in fstate) and +// (fcanvasclass = nil,copyfrom); +// gdi_unlock; + if fhandle = 0 then begin + gdierror(gde_pixmap); + end; + include(fstate,pms_ownshandle); + end; + end; +end; +{$warnings on} + +procedure tsimplebitmap.releasehandle; +begin + if fhandle <> 0 then begin + if fcanvas <> nil then begin + fcanvas.unlink; + end; +// fhandle:= 0; + exclude(fstate,pms_ownshandle); + end; +end; + +procedure tsimplebitmap.acquirehandle; +begin + if fhandle <> 0 then begin + include(fstate,pms_ownshandle); + end; +end; + +procedure tsimplebitmap.copyhandle; +var + ahandle: pixmapty; +begin + releasehandle; + ahandle:= fhandle; + fhandle:= 0; + createhandle(ahandle); +end; + +procedure tsimplebitmap.internaldestroyhandle; +var + bo1: boolean; +begin + if fhandle <> 0 then begin + bo1:= pms_ownshandle in fstate; + releasehandle; + if bo1 then begin + gdi_lock; + gui_freepixmap(fhandle); + gdi_unlock; + end; + fhandle:= 0; + end; +end; + +procedure tsimplebitmap.destroyhandle; +begin + internaldestroyhandle; +end; + +function tsimplebitmap.getsize: sizety; +begin + result:= fsize; +end; + +procedure tsimplebitmap.setsize(const avalue: sizety); +begin + destroyhandle; + fsize:= avalue; + updatescanline(); +end; + +function tsimplebitmap.getkind(): bitmapkindty; +begin + result:= fkind; +end; + +function tsimplebitmap.isempty(): boolean; +begin + result:= (fsize.cx = 0) or (fsize.cy = 0); +end; + +function tsimplebitmap.gethandle(): pixmapty; +begin + if fhandle = 0 then begin + createhandle(0); + end; + result:= fhandle; +end; + +procedure tsimplebitmap.sethandle(const Value: pixmapty); +var + info: pixmapinfoty; +begin + if fhandle <> value then begin + internaldestroyhandle; + end; + if value <> 0 then begin + info.handle:= value; +// gdi_lock; +// try + gdierror(gui_getpixmapinfo(info)); +// finally +// gdi_unlock; +// end; + fhandle:= value; + with info do begin + fsize:= size; + case depth of + 1: begin + fkind:= bmk_mono; + end; + 8: begin + fkind:= bmk_gray; + end; + else begin + fkind:= bmk_rgb; + end; + end; + { + if depth = 1 then begin + include(fstate,pms_monochrome); + end + else begin + exclude(fstate,pms_monochrome); + end; + } + updatescanline(); + end; + end; +end; + +procedure tsimplebitmap.gcneeded(const sender: tcanvas); +begin + if isempty then begin + gdierror(gde_pixmap); + end + else begin + if not (pms_ownshandle in fstate) and (fhandle <> 0) then begin + copyhandle; + end + else begin + createhandle(0); + end; + creategc; + end; +end; + +function tsimplebitmap.normalizeinitcolor(const acolor: colorty): colorty; +begin + if acolor = cl_transparent then begin + if kind = bmk_mono then begin + result:= cl_0; + end + else begin + result:= cl_white; + end; + end + else begin + result:= acolor; + end; +end; + +procedure tsimplebitmap.init(const acolor: colorty); +begin + with canvas.fvaluepo^.origin do begin + canvas.fillrect(makerect(-x,-y,fsize.cx,fsize.cy),normalizeinitcolor(acolor)); + end; +end; + +procedure tsimplebitmap.assign1(const source: tsimplebitmap; const docopy: boolean); +begin + clear; + with tsimplebitmap(source) do begin + if not isempty then begin + if docopy then begin + // self.handle:= handle; //windows problem: copy handle does not work with bmp selected in dc + // self.copyhandle; + self.clear; + self.kind:= kind; + self.size:= size; + self.copyarea(source,makerect(nullpoint,fsize),nullpoint,rop_copy,false); + end + else begin + self.handle:= handle; + releasehandle; + self.acquirehandle; + end; + end; + end; +end; + +procedure tsimplebitmap.assign(source: tpersistent); +begin + if source is tsimplebitmap then begin + assign1(tsimplebitmap(source),true); + end + else begin + inherited; + end; +end; + +procedure tsimplebitmap.assignnegative(source: tsimplebitmap); + //gets negative copy +begin + clear; + kind:= source.kind; + if not source.isempty then begin + size:= source.size; + copyarea(source,makerect(nullpoint,fsize),nullpoint,rop_notcopy); + end; +end; + +procedure tsimplebitmap.copyarea(const asource: tsimplebitmap; + const asourcerect: rectty; + const adestrect: rectty; const aalignment: alignmentsty = []; + const acopymode: rasteropty = rop_copy; + const masked: boolean = true; + const acolorforeground: colorty = cl_default; + //cl_default -> asource.colorforeground + //used for monochrome -> color conversion + const acolorbackground: colorty = cl_default; + //cl_default -> asource.colorbackground + //used for monochrome -> color conversion or + //colorbackground for color -> monochrome conversion + const aopacity: colorty = cl_none); +var + bo1,bo2: boolean; + amask: tsimplebitmap; + maskpos1: pointty; +begin + bo1:= canvasallocated; + bo2:= asource.canvasallocated; + if bo1 then begin + canvas.save; + canvas.clipregion:= 0; + canvas.origin:= nullpoint; + end; + if bo2 then begin + asource.canvas.save; + asource.canvas.origin:= nullpoint; + end; + if acolorforeground = cl_default then begin + canvas.color:= asource.fcolorforeground; + end + else begin + canvas.color:= acolorforeground; + end; + if acolorbackground = cl_default then begin + canvas.colorbackground:= asource.fcolorbackground; + end + else begin + canvas.colorbackground:= acolorbackground; + end; + if masked then begin + amask:= asource.getmask(maskpos1); + end + else begin + amask:= nil; + maskpos1:= nullpoint; + end; + canvas.internalcopyarea(asource.canvas,asourcerect, + calcrectalignment(adestrect,asourcerect,aalignment),acopymode, + cl_default,amask,maskpos1,aalignment,nullpoint,aopacity); + if bo1 then begin + canvas.restore; + end + else begin + freecanvas; + end; + if bo2 then begin + asource.canvas.restore; + end + else begin + asource.freecanvas; + end; +end; + +procedure tsimplebitmap.copyarea(const asource: tsimplebitmap; const asourcerect: rectty; + const adestpoint: pointty; const acopymode: rasteropty = rop_copy; + const masked: boolean = true; + const acolorforeground: colorty = cl_default; //cl_default -> asource.colorforeground + //used if asource is monchrome + const acolorbackground: colorty = cl_default;//cl_default -> asource.colorbackground + //used if asource is monchrome or + //colorbackground for color -> monochrome conversion + const aopacity: colorty = cl_none); +begin + copyarea(asource,asourcerect,makerect(adestpoint,asourcerect.size),[],acopymode, + masked,acolorforeground,acolorbackground,aopacity); +end; + +{ +procedure tsimplebitmap.stretch(const source: tsimplebitmap; const asize: sizety); +type + cardarty = array[0..0] of longword; +var + sim: pimagety; + simage,dimage: imagety; + po1: ^cardarty; + po2: plongword; + ca1,ca2: longword; + stepx: longword; + int1: integer; +begin + if source.isempty then begin + gdierror(gde_pixmap,self,'stretch'); + end; + if source <> self then begin + clear; + if source.monochrome <> monochrome then begin + gdierror(gde_unmatchedmonochrome,self,'stretch'); + end; + if monochrome then begin + include(fstate,pms_monochrome); + end + else begin + exclude(fstate,pms_monochrome); + end; + end; + sim:= source.getimagepo; + if sim = nil then begin + source.initimage(false,simage); + end + else begin + simage:= sim^; + end; + if simage.pixels = nil then begin + if source.fcanvas <> nil then begin + gdierror(gui_pixmaptoimage(source.handle,simage,source.fcanvas.fdrawinfo.gc.handle)) + end + else begin + gdierror(gui_pixmaptoimage(source.handle,simage,0)) + end; + end; + size:= asize; + initimage(true,dimage); + if monochrome then begin + end + else begin + po1:= pointer(simage.pixels); + po2:= pointer(dimage.pixels); + stepx:= ((($10000*simage.size.cx) + $8000) div dimage.size.cx) shl 15; + ca2:= 0; + for int1:= 0 to asize.cx - 1 do begin + ca1:= po1^[int1]; + repeat + po2^:= ca1; + inc(po2); + inc(ca2,stepx); + until integer(ca2) < 0; + dec(ca2,$80000000); + end; + end; +end; +} +{ +function tsimplebitmap.getmaskhandle(var gchandle: ptruint): pixmapty; +begin + result:= 0; //dummy +end; +} + +function tsimplebitmap.getmask(out apos: pointty): tsimplebitmap; +begin + result:= nil; //dummy +end; +{ +function tsimplebitmap.getimagepo: pimagety; +begin + result:= nil; //dummy +end; +} +{ +procedure tsimplebitmap.initimage(alloc: boolean; out aimage: imagety); + //allocates memory, no clear +var + int1: integer; +begin + with aimage do begin + monochrome:= pms_monochrome in fstate; + pixels:= nil; + size:= fsize; + if alloc and (size.cx <> 0) and (size.cy <> 0) then begin + if monochrome then begin + int1:= fsize.cy * ((fsize.cx+31) div 32); + end + else begin + int1:= fsize.cy * fsize.cx; + end; + allocuninitedarray(int1,sizeof(longword),pixels); + end; + end; +end; +} +procedure tsimplebitmap.getcanvasimage(const bgr: boolean; + var aimage: maskedimagety); +begin + //dummy +end; + +function tsimplebitmap.getgdiintf: pgdifunctionaty; +begin + result:= nil; + if fcanvas <> nil then begin + result:= fcanvas.fdrawinfo.gc.gdifuncs; + end; + if result = nil then begin + result:= fcanvasclass.getclassgdifuncs; + end; +end; + +procedure tsimplebitmap.setwidth(const avalue: integer); +begin + size:= ms(avalue,height); +end; + +procedure tsimplebitmap.setheight(const avalue: integer); +begin + size:= ms(width,avalue); +end; + +procedure tsimplebitmap.updatescanline(); +begin + case fkind of + bmk_mono: begin + fscanlinewords:= ((fsize.cx + 31) div 32); + end; + bmk_gray: begin + fscanlinewords:= ((fsize.cx + 3) div 4); + end; + else begin + fscanlinewords:= fsize.cx; + end; + end; + fscanlinestep:= fscanlinewords * 4; + fscanhigh:= fsize.cx * fsize.cy - 1; +end; + + +procedure initfontinfo(var ainfo: basefontinfoty); +begin + with ainfo do begin + color:= cl_default; //cl_text + colorbackground:= cl_default; //cl_transparent + colorselect:= cl_default; //cl_selectedtext + colorselectbackground:= cl_default; //cl_selectedtxtbackground + shadow_color:= cl_none; + shadow_shiftx:= 1; + shadow_shifty:= 1; + + gloss_color:= cl_none; + gloss_shiftx:= -1; + gloss_shifty:= -1; + + grayed_color:= cl_default; //cl_grayed; + grayed_colorshadow:= cl_default; //cl_grayedshadow; + grayed_shiftx:= 1; + grayed_shifty:= 1; + + xscale:= 1.0; + end; +end; + +{ tfont } + +constructor tfont.create; +begin + if finfopo = nil then begin + finfopo:= @finfo; + end; + initfontinfo(finfopo^.baseinfo); + updatehandlepo; + dochanged([cs_fontcolor,cs_fontcolorbackground,cs_fonteffect],true); +end; + +destructor tfont.destroy; +begin + //handle:= 0; + releasehandles(true); + inherited; +end; + +function tfont.getfont(var drawinfo: drawinfoty): boolean; +begin + gdi_lock; +// gdi_getfont(drawinfo); + drawinfo.gc.gdifuncs^[gdf_getfont](drawinfo); + result:= drawinfo.getfont.ok; + if result then begin + with drawinfo.getfont.fontdata^ do begin + linewidth:= height div (9 * (1 shl fontsizeshift)); + end; + end; + gdi_unlock; +end; + +procedure tfont.createhandle(const canvas: tcanvas); +var + int1: integer; + templ1: tfontcomp; + po1: pfontdataty; + info1: fontinfoty; + opt1: fontoptionsty; +begin + if (canvas <> nil) then begin + canvas.checkgcstate([cs_gc]); //windows needs gc + if finfopo^.gdifuncs <> nil then begin + if finfopo^.gdifuncs <> canvas.fdrawinfo.gc.fontgdifuncs then begin + for int1:= 0 to high(finfopo^.handles) do begin + releasefont(finfopo^.handles[int1]); + finfopo^.handles[int1]:= 0; + end; + end + else begin + releasefont(fhandlepo^); + end; + end; + finfopo^.gdifuncs:= canvas.fdrawinfo.gc.fontgdifuncs; +// finfopo^.gdifuncs:= gdifuncs[canvas.fgdinum]; + templ1:= nil; + fhandlepo^:= getfontnum(finfopo^,canvas.fdrawinfo, + {$ifdef FPC}@{$endif}getfont,templ1); + if fhandlepo^ = 0 then begin + canvas.error(gde_font,msestring(finfopo^.baseinfo.name)); + end; + if (templ1 <> nil) and (ftemplate = nil) then begin + po1:= getfontdata(fhandlepo^); + settemplateinfo(templ1.template.fi); + if fhandlepo^ = 0 then begin + info1:= finfopo^; + with po1^.realfont do begin + if (info1.baseinfo.name = '') and (name <> '') then begin + info1.baseinfo.name:= name; + end; + if (info1.baseinfo.height = 0) and (d.height <> 0) then begin + info1.baseinfo.height:= d.height; + end; + if info1.baseinfo.options = [] then begin + opt1:= d.familyoptions + d.pitchoptions + d.antialiasedoptions; + if opt1 <> [] then begin + info1.baseinfo.options:= opt1; + end; + end; + if (info1.baseinfo.width = 0) and (d.width <> 0) then begin + info1.baseinfo.width:= d.width; + end; + if (info1.baseinfo.xscale = 1) and (d.xscale <> 1) then begin + info1.baseinfo.xscale:= d.xscale; + end; + end; + fhandlepo^:= getfontnum(info1,canvas.fdrawinfo,@getfont,templ1); + end; + end; + end + else begin + fhandlepo^:= 0; + finfopo^.gdifuncs:= nil; + end; +end; + +function tfont.gethandleforcanvas(const canvas: tcanvas): fontnumty; +begin + if (fhandlepo^ <> 0) and + (finfopo^.gdifuncs <> canvas.fdrawinfo.gc.gdifuncs) then begin + releasehandles(true); + end; + if fhandlepo^ = 0 then begin + createhandle(canvas); + end; + result:= fhandlepo^; +end; + +function tfont.gethandle: fontnumty; +var + canvas: tcanvas; +begin + if fhandlepo^ = 0 then begin + canvas:= creategdicanvas(getdefaultgdifuncs,bmk_rgb,self,icanvas(self)); +// canvas:= tcanvas.create(self,icanvas(self)); + try + createhandle(canvas); + finally + canvas.Free; + end; + end; + result:= fhandlepo^; +end; + +function tfont.getdatapo: pfontdataty; +begin + result:= getfontdata(gethandle); +end; +{ +procedure tfont.sethandle(const Value: fontty); +begin + if fhandlepo^ <> value then begin + releasefont(fhandlepo^); + fhandlepo^ := Value; + dochanged([cs_font]); + end; +end; +} +procedure tfont.dochanged(const changed: canvasstatesty; + const nochange: boolean); +begin + if assigned(fonchange) and not nochange then begin + fonchange(self); + end; +end; + +function tfont.getascent: integer; +begin + result:= getdatapo^.ascent {+ finfopo^.extraspace}; +end; + +function tfont.getdescent: integer; +begin + result:= getdatapo^.descent; +end; + +function tfont.getglyphheight: integer; +begin + with getdatapo^ do begin + result:= ascent+descent; + end; +end; + +function tfont.getlineheight: integer; +begin + with getdatapo^ do begin + result:= ascent + descent; + if linespacing > result then begin + result:= linespacing; + end; + end; + result:= result + finfopo^.baseinfo.extraspace; +end; + +function tfont.getlinewidth: integer; +begin + result:= getdatapo^.linewidth; +end; + +function tfont.getcaretshift: integer; +begin + result:= getdatapo^.caretshift; +end; + +function tfont.getextraspace: integer; +begin + result:= finfopo^.baseinfo.extraspace; +end; + +procedure tfont.setextraspace(const avalue: integer); +begin + include(flocalprops,flp_extraspace); + if finfopo^.baseinfo.extraspace <> avalue then begin + finfopo^.baseinfo.extraspace := avalue; + dochanged([cs_font],false); + end; +end; + +procedure tfont.setcolorbackground(const Value: colorty); +begin + include(flocalprops,flp_colorbackground); + with finfopo^.baseinfo do begin + if colorbackground <> value then begin + colorbackground:= Value; + dochanged([cs_fontcolorbackground],false); + end; + end; +end; + +procedure tfont.setcolorselectbackground(const Value: colorty); +begin + include(flocalprops,flp_colorselectbackground); + with finfopo^.baseinfo do begin + if colorselectbackground <> value then begin + colorselectbackground:= Value; + dochanged([cs_fonteffect],false); + end; + end; +end; + +function tfont.getcolorbackground: colorty; +begin + result:= finfopo^.baseinfo.colorbackground; +end; + +function tfont.getcolorselectbackground: colorty; +begin + result:= finfopo^.baseinfo.colorselectbackground; +end; + +procedure tfont.setshadow_color(avalue: colorty); +begin + include(flocalprops,flp_shadow_color); + if avalue = cl_invalid then begin + avalue:= cl_none; + end; + with finfopo^.baseinfo do begin + if shadow_color <> avalue then begin + shadow_color:= avalue; + dochanged([cs_fonteffect],false); + end; + end; +end; + +function tfont.getshadow_color: colorty; +begin + result:= finfopo^.baseinfo.shadow_color; +end; + +procedure tfont.setshadow_shiftx(const avalue: integer); +begin + include(flocalprops,flp_shadow_shiftx); + with finfopo^.baseinfo do begin + if shadow_shiftx <> avalue then begin + shadow_shiftx:= avalue; + dochanged([cs_fonteffect],false); + end; + end; +end; + +function tfont.getshadow_shiftx: integer; +begin + result:= finfopo^.baseinfo.shadow_shiftx; +end; + +procedure tfont.setshadow_shifty(const avalue: integer); +begin + include(flocalprops,flp_shadow_shifty); + with finfopo^.baseinfo do begin + if shadow_shifty <> avalue then begin + shadow_shifty:= avalue; + dochanged([cs_fonteffect],false); + end; + end; +end; + +function tfont.getshadow_shifty: integer; +begin + result:= finfopo^.baseinfo.shadow_shifty; +end; + +procedure tfont.setgloss_color(avalue: colorty); +begin + include(flocalprops,flp_gloss_color); + if avalue = cl_invalid then begin + avalue:= cl_none; + end; + with finfopo^.baseinfo do begin + if gloss_color <> avalue then begin + gloss_color:= avalue; + dochanged([cs_fonteffect],false); + end; + end; +end; + +function tfont.getgloss_color: colorty; +begin + result:= finfopo^.baseinfo.gloss_color; +end; + +procedure tfont.setgloss_shiftx(const avalue: integer); +begin + include(flocalprops,flp_gloss_shiftx); + with finfopo^.baseinfo do begin + if gloss_shiftx <> avalue then begin + gloss_shiftx:= avalue; + dochanged([cs_fonteffect],false); + end; + end; +end; + +function tfont.getgloss_shiftx: integer; +begin + result:= finfopo^.baseinfo.gloss_shiftx; +end; + +procedure tfont.setgloss_shifty(const avalue: integer); +begin + include(flocalprops,flp_gloss_shifty); + with finfopo^.baseinfo do begin + if gloss_shifty <> avalue then begin + gloss_shifty:= avalue; + dochanged([cs_fonteffect],false); + end; + end; +end; + +function tfont.getgloss_shifty: integer; +begin + result:= finfopo^.baseinfo.gloss_shifty; +end; + +function tfont.getgrayed_color: colorty; +begin + result:= finfopo^.baseinfo.grayed_color; +end; + +procedure tfont.setgrayed_color(const avalue: colorty); +begin + include(flocalprops,flp_grayed_color); + with finfopo^.baseinfo do begin + if grayed_color <> avalue then begin + grayed_color:= avalue; + dochanged([cs_fonteffect],false); + end; + end; +end; + +function tfont.getgrayed_colorshadow: colorty; +begin + result:= finfopo^.baseinfo.grayed_colorshadow; +end; + +procedure tfont.setgrayed_colorshadow(const avalue: colorty); +begin + include(flocalprops,flp_grayed_colorshadow); + with finfopo^.baseinfo do begin + if grayed_colorshadow <> avalue then begin + grayed_colorshadow:= avalue; + dochanged([cs_fonteffect],false); + end; + end; +end; + +function tfont.getgrayed_shiftx: integer; +begin + result:= finfopo^.baseinfo.grayed_shiftx; +end; + +procedure tfont.setgrayed_shiftx(const avalue: integer); +begin + include(flocalprops,flp_grayed_shiftx); + with finfopo^.baseinfo do begin + if grayed_shiftx <> avalue then begin + grayed_shiftx:= avalue; + dochanged([cs_fonteffect],false); + end; + end; +end; + +function tfont.getgrayed_shifty: integer; +begin + result:= finfopo^.baseinfo.grayed_shifty; +end; + +procedure tfont.setgrayed_shifty(const avalue: integer); +begin + include(flocalprops,flp_grayed_shifty); + with finfopo^.baseinfo do begin + if grayed_shifty <> avalue then begin + grayed_shifty:= avalue; + dochanged([cs_fonteffect],false); + end; + end; +end; + +procedure tfont.setcolor(const Value: colorty); +begin + include(flocalprops,flp_color); + with finfopo^.baseinfo do begin + if color <> value then begin + color := Value; + dochanged([cs_fontcolor],false); + end; + end; +end; + +procedure tfont.setcolorselect(const Value: colorty); +begin + include(flocalprops,flp_colorselect); + with finfopo^.baseinfo do begin + if colorselect <> value then begin + colorselect := Value; + dochanged([cs_fonteffect],false); + end; + end; +end; + +procedure tfont.assignproperties(const source: tfont; const ahandles: boolean); +var + int1: integer; + bo1: boolean; + changed: canvasstatesty; +begin + changed:= []; + with source,self.finfopo^ do begin + if baseinfo.colorbackground <> finfopo^.baseinfo.colorbackground then begin + baseinfo.colorbackground:= finfopo^.baseinfo.colorbackground; + include(changed,cs_fontcolorbackground); + end; + if baseinfo.colorselectbackground <> + finfopo^.baseinfo.colorselectbackground then begin + baseinfo.colorselectbackground:= finfopo^.baseinfo.colorselectbackground; + include(changed,cs_fonteffect); + end; + + if baseinfo.shadow_color <> finfopo^.baseinfo.shadow_color then begin + baseinfo.shadow_color:= finfopo^.baseinfo.shadow_color; + include(changed,cs_fonteffect); + end; + if baseinfo.shadow_shiftx <> finfopo^.baseinfo.shadow_shiftx then begin + baseinfo.shadow_shiftx:= finfopo^.baseinfo.shadow_shiftx; + include(changed,cs_fonteffect); + end; + if baseinfo.shadow_shifty <> finfopo^.baseinfo.shadow_shifty then begin + baseinfo.shadow_shifty:= finfopo^.baseinfo.shadow_shifty; + include(changed,cs_fonteffect); + end; + + if baseinfo.gloss_color <> finfopo^.baseinfo.gloss_color then begin + baseinfo.gloss_color:= finfopo^.baseinfo.gloss_color; + include(changed,cs_fonteffect); + end; + if baseinfo.gloss_shiftx <> finfopo^.baseinfo.gloss_shiftx then begin + baseinfo.gloss_shiftx:= finfopo^.baseinfo.gloss_shiftx; + include(changed,cs_fonteffect); + end; + if baseinfo.gloss_shifty <> finfopo^.baseinfo.gloss_shifty then begin + baseinfo.gloss_shifty:= finfopo^.baseinfo.gloss_shifty; + include(changed,cs_fonteffect); + end; + + if baseinfo.grayed_color <> finfopo^.baseinfo.grayed_color then begin + baseinfo.grayed_color:= finfopo^.baseinfo.grayed_color; + include(changed,cs_fonteffect); + end; + if baseinfo.grayed_colorshadow <> finfopo^.baseinfo.grayed_colorshadow then begin + baseinfo.grayed_colorshadow:= finfopo^.baseinfo.grayed_colorshadow; + include(changed,cs_fonteffect); + end; + if baseinfo.grayed_shiftx <> finfopo^.baseinfo.grayed_shiftx then begin + baseinfo.grayed_shiftx:= finfopo^.baseinfo.grayed_shiftx; + include(changed,cs_fonteffect); + end; + if baseinfo.grayed_shifty <> finfopo^.baseinfo.grayed_shifty then begin + baseinfo.grayed_shifty:= finfopo^.baseinfo.grayed_shifty; + include(changed,cs_fonteffect); + end; + + if baseinfo.color <> finfopo^.baseinfo.color then begin + baseinfo.color:= finfopo^.baseinfo.color; + include(changed,cs_fontcolor); + end; + if baseinfo.colorselect <> finfopo^.baseinfo.colorselect then begin + baseinfo.colorselect:= finfopo^.baseinfo.colorselect; + include(changed,cs_fonteffect); + end; + if baseinfo.style <> finfopo^.baseinfo.style then begin + baseinfo.style:= finfopo^.baseinfo.style; + self.updatehandlepo; + include(changed,cs_font); + end; + if baseinfo.extraspace <> finfopo^.baseinfo.extraspace then begin + baseinfo.extraspace:= finfopo^.baseinfo.extraspace; + include(changed,cs_font); + end; + if baseinfo.height <> finfopo^.baseinfo.height then begin + baseinfo.height:= finfopo^.baseinfo.height; + include(changed,cs_font); + end; + if baseinfo.width <> finfopo^.baseinfo.width then begin + baseinfo.width:= finfopo^.baseinfo.width; + include(changed,cs_font); + end; + if baseinfo.name <> finfopo^.baseinfo.name then begin + baseinfo.name:= finfopo^.baseinfo.name; + include(changed,cs_font); + end; + if baseinfo.charset <> finfopo^.baseinfo.charset then begin + baseinfo.charset:= finfopo^.baseinfo.charset; + include(changed,cs_font); + end; + if baseinfo.options <> finfopo^.baseinfo.options then begin + baseinfo.options:= finfopo^.baseinfo.options; + include(changed,cs_font); + end; + if baseinfo.xscale <> finfopo^.baseinfo.xscale then begin + baseinfo.xscale:= finfopo^.baseinfo.xscale; + include(changed,cs_font); + end; + bo1:= false; + if ahandles then begin + for int1:= 0 to high(handles) do begin + if handles[int1] <> finfopo^.handles[int1] then begin + bo1:= true; + releasefont(handles[int1]); + handles[int1]:= finfopo^.handles[int1]; + addreffont(handles[int1]); + end; + end; + gdifuncs:= finfopo^.gdifuncs; + end + else begin + for int1:= 0 to high(handles) do begin + if handles[int1] <> 0 then begin + bo1:= true; + releasefont(handles[int1]); + handles[int1]:= 0; + end; + end; + end; + if bo1 then begin + include(changed,cs_fonthandle); + end; + end; + if changed <> [] then begin + dochanged(changed,false); + end; +end; + +procedure tfont.readcolorshadow(reader: treader); +begin + shadow_color:= reader.readinteger; +end; + +procedure tfont.readdummy(reader: treader); +begin + reader.readinteger(); +end; + +procedure tfont.setlocalprops(const avalue: fontlocalpropsty); +begin + if flocalprops <> avalue then begin + flocalprops:= avalue; + if ftemplate <> nil then begin + settemplateinfo(ftemplate.template.fi); + end; + end; +end; + +procedure tfont.defineproperties(filer: tfiler); +begin +// inherited; //no dummy necessary because of localprops + filer.defineproperty('dummy',@readdummy,nil,false); + filer.defineproperty('colorshadow',{$ifdef FPC}@{$endif}readcolorshadow, + nil,false); +end; + +procedure tfont.assign(source: tpersistent); +begin + if source <> self then begin + if source is tfont then begin + assignproperties(tfont(source),true); + end + else begin + inherited; + end; + end; +end; + +procedure tfont.updatehandlepo; +begin + fhandlepo:= @finfopo^.handles[ + {$ifdef FPC}longword{$else}byte{$endif}(finfopo^.baseinfo.style) and + fontstylehandlemask]; +end; + +procedure tfont.setstyle(const Value: fontstylesty); +begin + include(flocalprops,flp_style); + if finfopo^.baseinfo.style <> value then begin + finfopo^.baseinfo.style := Value; + updatehandlepo; + dochanged([cs_font],false); + end; +end; + +procedure tfont.releasehandles(const nochanged: boolean = false); +var + int1: integer; + bo1: boolean; + fo1: fontnumty; +begin + bo1:= false; + for int1:= 0 to high(finfopo^.handles) do begin + fo1:= finfopo^.handles[int1]; + if fo1 <> 0 then begin + bo1:= true; + releasefont(fo1); + end; + end; + if bo1 then begin + fillchar(finfopo^.handles,sizeof(finfopo^.handles),0); + dochanged([cs_font,cs_fonthandle],nochanged); + end + else begin + dochanged([cs_font],nochanged); + end; +end; + +function tfont.getcolor: colorty; +begin + result:= finfopo^.baseinfo.color; +end; + +function tfont.getcolorselect: colorty; +begin + result:= finfopo^.baseinfo.colorselect; +end; + +function tfont.getheight: integer; +begin + result:= (finfopo^.baseinfo.height + fontsizeroundvalue) shr fontsizeshift; +end; + +function tfont.getheightflo: flo64; +begin + result:= finfopo^.baseinfo.height / (1 shl fontsizeshift); +end; + +procedure tfont.setheight(avalue: integer); +begin + include(flocalprops,flp_height); + if avalue < 0 then begin + avalue:= 0; + end; + if finfopo^.baseinfo.height <> avalue then begin + finfopo^.baseinfo.height:= avalue shl fontsizeshift; + releasehandles; + end; +end; + +procedure tfont.setheightflo(avalue: flo64); +begin + include(flocalprops,flp_height); + if avalue < 0 then begin + avalue:= 0; + end; +// if finfopo^.baseinfo.height <> avalue then begin + finfopo^.baseinfo.height:= round(avalue * (1 shl fontsizeshift)); + releasehandles; +// end; +end; + +function tfont.getwidth: integer; +begin + result:= (finfopo^.baseinfo.width + fontsizeroundvalue) shr fontsizeshift; +end; + +procedure tfont.setwidth(avalue: integer); +begin + include(flocalprops,flp_width); + if avalue < 0 then begin + avalue:= 0; + end; + if finfopo^.baseinfo.width <> avalue then begin + finfopo^.baseinfo.width:= avalue shl fontsizeshift; + releasehandles; + end; +end; + +function tfont.getstyle: fontstylesty; +begin + result:= finfopo^.baseinfo.style; +end; + +function tfont.getname: string; +begin + result:= finfopo^.baseinfo.name; +end; + +procedure tfont.setname(const Value: string); +begin + if finfopo^.baseinfo.name <> value then begin + finfopo^.baseinfo.name := trim(Value); + releasehandles; + end; +end; + +function tfont.getoptions: fontoptionsty; +begin + result:= finfopo^.baseinfo.options; +end; + +procedure tfont.setoptions(const avalue: fontoptionsty); +begin + include(flocalprops,flp_options); + if finfopo^.baseinfo.options <> avalue then begin + finfopo^.baseinfo.options:= + checkfontoptions(avalue,finfopo^.baseinfo.options); + releasehandles; + end; +end; + +function tfont.getrotation: real; +begin + result:= finfopo^.rotation; +end; + +procedure tfont.setrotation(const avalue: real); +begin + if finfopo^.rotation <> avalue then begin + finfopo^.rotation:= avalue; + releasehandles(true); + end; +end; + +function tfont.getxscale: real; +begin + result:= finfopo^.baseinfo.xscale; +end; + +procedure tfont.setxscale(const avalue: real); +begin + include(flocalprops,flp_xscale); + if finfopo^.baseinfo.xscale <> avalue then begin + finfopo^.baseinfo.xscale:= avalue; + releasehandles; + end; +end; + +function tfont.getcharset: string; +begin + result:= finfopo^.baseinfo.charset; +end; + +procedure tfont.setcharset(const Value: string); +begin + if finfopo^.baseinfo.charset <> value then begin + finfopo^.baseinfo.charset:= trim(Value); + releasehandles; + end; +end; + + //icanvas +procedure tfont.gcneeded(const sender: tcanvas); +var + gc: gcty; + err: gdierrorty; +begin + fillchar(gc,sizeof(gcty),0); + gc.kind:= bmk_rgb; //default +// gdi_lock; + err:= sender.creategc(0,gck_screen,gc); +// gdi_unlock; + gdierror(err,self); + sender.linktopaintdevice(0,gc,{nullsize,}nullpoint); +end; +{ +function tfont.getmonochrome: boolean; +begin + result:= false; +end; +} +function tfont.getkind: bitmapkindty; +begin + result:= bmk_rgb; +end; + +function tfont.getsize: sizety; +begin + result:= nullsize; +end; + +function tfont.getbold: boolean; +begin + result:= fs_bold in style; +end; + +procedure tfont.setbold(const avalue: boolean); +begin + if avalue then begin + style:= style + [fs_bold]; + end + else begin + style:= style - [fs_bold]; + end; +end; + +function tfont.getitalic: boolean; +begin + result:= fs_italic in style; +end; + +procedure tfont.setitalic(const avalue: boolean); +begin + if avalue then begin + style:= style + [fs_italic]; + end + else begin + style:= style - [fs_italic]; + end; +end; + +function tfont.getunderline: boolean; +begin + result:= fs_underline in style; +end; + +procedure tfont.setunderline(const avalue: boolean); +begin + if avalue then begin + style:= style + [fs_underline]; + end + else begin + style:= style - [fs_underline]; + end; +end; + +function tfont.getstrikeout: boolean; +begin + result:= fs_strikeout in style; +end; + +procedure tfont.setstrikeout(const avalue: boolean); +begin + if avalue then begin + style:= style + [fs_strikeout]; + end + else begin + style:= style - [fs_strikeout]; + end; +end; + +procedure tfont.scale(const ascale: real); +begin + height:= round(height * ascale); + width:= round(width * ascale); +end; + +procedure tfont.getcanvasimage(const bgr: boolean; var aimage: maskedimagety); +begin + //dummy +end; + +procedure tfont.settemplate(const avalue: tfontcomp); +begin + setlinkedvar(avalue,tmsecomponent(ftemplate)); + if (avalue <> nil) and not (csreading in avalue.componentstate) then begin + assign(avalue); + dochanged([],false); + end; +end; + +procedure tfont.settemplateinfo(const ainfo: basefontinfoty); +var + changed1: canvasstatesty = []; +begin + with finfopo^.baseinfo do begin + if not (flp_color in flocalprops) then begin + if color <> ainfo.color then begin + color:= ainfo.color; + include(changed1,cs_fontcolor); + end; + end; + if not (flp_colorbackground in flocalprops) then begin + if colorbackground <> ainfo.colorbackground then begin + colorbackground:= ainfo.colorbackground; + include(changed1,cs_fonteffect); + end; + end; + if not (flp_colorselect in flocalprops) then begin + if colorselect <> ainfo.colorselect then begin + colorselect:= ainfo.colorselect; + include(changed1,cs_fonteffect); + end; + end; + if not (flp_colorselectbackground in flocalprops) then begin + if colorselectbackground <> ainfo.colorselectbackground then begin + colorselectbackground:= ainfo.colorselectbackground; + include(changed1,cs_fontcolorbackground); + end; + end; + if not (flp_shadow_color in flocalprops) then begin + if shadow_color <> ainfo.shadow_color then begin + shadow_color:= ainfo.shadow_color; + include(changed1,cs_fonteffect); + end; + end; + if not (flp_shadow_shiftx in flocalprops) then begin + if shadow_shiftx <> ainfo.shadow_shiftx then begin + shadow_shiftx:= ainfo.shadow_shiftx; + include(changed1,cs_fonteffect); + end; + end; + if not (flp_shadow_shifty in flocalprops) then begin + if shadow_shifty <> ainfo.shadow_shifty then begin + shadow_shifty:= ainfo.shadow_shifty; + include(changed1,cs_fonteffect); + end; + end; + if not (flp_gloss_color in flocalprops) then begin + if gloss_color <> ainfo.gloss_color then begin + gloss_color:= ainfo.gloss_color; + include(changed1,cs_fonteffect); + end; + end; + if not (flp_gloss_shiftx in flocalprops) then begin + if gloss_shiftx <> ainfo.gloss_shiftx then begin + gloss_shiftx:= ainfo.gloss_shiftx; + include(changed1,cs_fonteffect); + end; + end; + if not (flp_gloss_shifty in flocalprops) then begin + if gloss_shifty <> ainfo.gloss_shifty then begin + gloss_shifty:= ainfo.gloss_shifty; + include(changed1,cs_fonteffect); + end; + end; + + if not (flp_grayed_color in flocalprops) then begin + if grayed_color <> ainfo.grayed_color then begin + grayed_color:= ainfo.grayed_color; + include(changed1,cs_fonteffect); + end; + end; + if not (flp_grayed_colorshadow in flocalprops) then begin + if grayed_colorshadow <> ainfo.grayed_colorshadow then begin + grayed_colorshadow:= ainfo.grayed_colorshadow; + include(changed1,cs_fonteffect); + end; + end; + if not (flp_grayed_shifty in flocalprops) then begin + if grayed_shiftx <> ainfo.grayed_shiftx then begin + grayed_shiftx:= ainfo.grayed_shiftx; + include(changed1,cs_fonteffect); + end; + end; + if not (flp_grayed_shifty in flocalprops) then begin + if grayed_shifty <> ainfo.grayed_shifty then begin + grayed_shifty:= ainfo.grayed_shifty; + include(changed1,cs_fonteffect); + end; + end; + if not (flp_xscale in flocalprops) then begin + if (xscale <> 1) and (xscale <> ainfo.xscale) then begin + xscale:= ainfo.xscale; + include(changed1,cs_fonthandle); + end; + end; + if not (flp_style in flocalprops) then begin + if style <> ainfo.style then begin + style:= ainfo.style; + updatehandlepo(); + include(changed1,cs_font); + end; + end; + + if not (flp_height in flocalprops) then begin + if (ainfo.height <> 0) and (height <> + (ainfo.height shl fontsizeshift)) then begin + height:= ainfo.height shl fontsizeshift; + include(changed1,cs_fonthandle); + end; + end; + + if not (flp_width in flocalprops) then begin + if (ainfo.width <> 0) and (width <> + (ainfo.width shl fontsizeshift)) then begin + width:= ainfo.width shl fontsizeshift; + include(changed1,cs_fonthandle); + end; + end; + if not (flp_extraspace in flocalprops) then begin + if extraspace <> ainfo.extraspace then begin + extraspace:= ainfo.extraspace; + include(changed1,cs_font); + end; + end; + if not (flp_name in flocalprops) then begin + if (ainfo.name <> '') and (name <> ainfo.name) then begin + name:= ainfo.name; + include(changed1,cs_fonthandle); + end; + end; + if not (flp_charset in flocalprops) then begin + if charset <> ainfo.charset then begin + charset:= ainfo.charset; + include(changed1,cs_fonthandle); + end; + end; + if not (flp_options in flocalprops) then begin + if (ainfo.options <> []) and (options <> ainfo.options) then begin + options:= ainfo.options; + include(changed1,cs_fonthandle); + end; + end; + + if changed1 <> [] then begin + if cs_fonthandle in changed1 then begin + releasehandles(true); + include(changed1,cs_font); + end; + dochanged(changed1,true); + end; + end; +end; + +function tfont.iscolorstored: boolean; +begin + result:= (ftemplate = nil) and (finfopo^.baseinfo.color <> cl_default) or + (flp_color in flocalprops); +end; + +function tfont.iscolorbackgroundstored: boolean; +begin + result:= (ftemplate = nil) and + (finfopo^.baseinfo.colorbackground <> cl_default) or + (flp_colorbackground in flocalprops); +end; + +function tfont.iscolorselectstored: boolean; +begin + result:= (ftemplate = nil) and (finfopo^.baseinfo.colorselect <> cl_default) or + (flp_colorselect in flocalprops); +end; + +function tfont.iscolorselectbackgroundstored: boolean; +begin + result:= (ftemplate = nil) and + (finfopo^.baseinfo.colorselectbackground <> cl_default) or + (flp_colorselectbackground in flocalprops); +end; + +function tfont.isshadow_colorstored: boolean; +begin + result:= (ftemplate = nil) and + (finfopo^.baseinfo.shadow_color <> cl_none) or + (flp_shadow_color in flocalprops); +end; + +function tfont.isshadow_shiftxstored: boolean; +begin + result:= (ftemplate = nil) and + (finfopo^.baseinfo.shadow_shiftx <> 1) or + (flp_shadow_shiftx in flocalprops); +end; + +function tfont.isshadow_shiftystored: boolean; +begin + result:= (ftemplate = nil) and + (finfopo^.baseinfo.shadow_shifty <> 1) or + (flp_shadow_shifty in flocalprops); +end; + +function tfont.isgloss_colorstored: boolean; +begin + result:= (ftemplate = nil) and + (finfopo^.baseinfo.gloss_color <> cl_none) or + (flp_gloss_color in flocalprops); +end; + +function tfont.isgloss_shiftxstored: boolean; +begin + result:= (ftemplate = nil) and + (finfopo^.baseinfo.gloss_shiftx <> -1) or + (flp_gloss_shiftx in flocalprops); +end; + +function tfont.isgloss_shiftystored: boolean; +begin + result:= (ftemplate = nil) and + (finfopo^.baseinfo.gloss_shifty <> -1) or + (flp_gloss_shifty in flocalprops); +end; + +function tfont.isgrayed_colorstored: boolean; +begin + result:= (ftemplate = nil) and + (finfopo^.baseinfo.grayed_color <> cl_grayed) or + (flp_grayed_color in flocalprops); +end; + +function tfont.isgrayed_colorshadowstored: boolean; +begin + result:= (ftemplate = nil) and + (finfopo^.baseinfo.grayed_colorshadow <> cl_grayedshadow) or + (flp_grayed_colorshadow in flocalprops); +end; + +function tfont.isgrayed_shiftxstored: boolean; +begin + result:= (ftemplate = nil) and + (finfopo^.baseinfo.grayed_shifty <> 1) or + (flp_grayed_shifty in flocalprops); +end; + +function tfont.isgrayed_shiftystored: boolean; +begin + result:= (ftemplate = nil) and + (finfopo^.baseinfo.grayed_shifty <> 1) or + (flp_grayed_shifty in flocalprops); +end; + +function tfont.isxscalestored: boolean; +begin + result:= (ftemplate = nil) and + (finfopo^.baseinfo.xscale <> 1) or (flp_xscale in flocalprops); +end; + +function tfont.isstylestored: boolean; +begin + result:= (ftemplate = nil) and + (finfopo^.baseinfo.style <> []) or (flp_style in flocalprops); +end; + +function tfont.isheightstored: boolean; +begin + result:= (ftemplate = nil) and + (finfopo^.baseinfo.height <> 0) or (flp_height in flocalprops); +end; + +function tfont.iswidthstored: boolean; +begin + result:= (ftemplate = nil) and + (finfopo^.baseinfo.width <> 0) or (flp_width in flocalprops); +end; + +function tfont.isextraspacestored: boolean; +begin + result:= (ftemplate = nil) and + (finfopo^.baseinfo.extraspace <> 0) or + (flp_extraspace in flocalprops); +end; + +function tfont.isnamestored: boolean; +begin + result:= (ftemplate = nil) and + (finfopo^.baseinfo.name <> '') or (flp_name in flocalprops); +end; + +function tfont.ischarsetstored: boolean; +begin + result:= (ftemplate = nil) and + (finfopo^.baseinfo.charset <> '') or (flp_charset in flocalprops); +end; + +function tfont.isoptionsstored: boolean; +begin + result:= (ftemplate = nil) and + (finfopo^.baseinfo.options <> []) or (flp_options in flocalprops); +end; + +procedure tfont.objectevent(const sender: tobject; const event: objecteventty); +begin + inherited; + if (event = oe_changed) and (ftemplate <> nil) and + (ftemplate = sender) then begin + settemplateinfo(tfontcomp(sender).template.fi); + dochanged([],false); + end; +end; + +{ tcanvasfont } + +constructor tcanvasfont.create(const acanvas: tcanvas); +begin + fcanvas:= acanvas; + fgdifuncs:= fcanvas.getgdifuncs; + finfopo:= @fcanvas.fvaluepo^.font; + inherited create; +end; + +procedure tcanvasfont.dochanged(const changed: canvasstatesty; + const nochange: boolean); +begin +// inherited; + fcanvas.valueschanged(changed); +end; + +function tcanvasfont.gethandle: fontnumty; +begin + if fhandlepo^ = 0 then begin + createhandle(fcanvas); + end; + result:= fhandlepo^; +// result:= gethandleforcanvas(fcanvas); +end; + +procedure tcanvasfont.assignproperties(const source: tfont; + const ahandles: boolean); +begin + inherited assignproperties(source,ahandles and + (source.finfopo^.gdifuncs = fgdifuncs)); +end; + +{ tcanvas } + +constructor tcanvas.create(const user: tobject; const intf: icanvas); +begin + fdrawinfo.gc.gdifuncs:= getgdifuncs; //default + fdrawinfo.gc.fontgdifuncs:= fdrawinfo.gc.gdifuncs; + fuser:= user; + fintf:= pointer(intf); + with fvaluestack do begin + setlength(stack,1); + count:= 1; + fvaluepo:= @stack[0]; + end; + ffont:= createfont; + initflags(self); + init; +end; + +destructor tcanvas.destroy; +var + int1: integer; +begin + inherited; + unlink; //deinit, unregister defaultfont + ffont.free; + freebuffer(fdrawinfo.buffer); + for int1:= 0 to high(fgclinksto) do begin + removeitem(pointerarty(tcanvas(fgclinksto[int1]).fgclinksfrom),self); + end; + for int1:= 0 to high(fgclinksfrom) do begin + removeitem(pointerarty(tcanvas(fgclinksfrom[int1]).fgclinksto),self); + end; +end; + +function tcanvas.creategc(const apaintdevice: paintdevicety; + const akind: gckindty; + var gc: gcty; const aprintername: msestring = ''): gdierrorty; +begin + with fdrawinfo.creategc do begin + paintdevice:= apaintdevice; + kind:= akind; + printernamepo:= @aprintername; + contextinfopo:= getcontextinfopo; + gcpo:= @gc; + getgdifuncs^[gdf_creategc](fdrawinfo); + if gc.fontgdifuncs = nil then begin + gc.fontgdifuncs:= gc.gdifuncs; + end; + result:= error; + end; +end; + +procedure tcanvas.registergclink(const dest: tcanvas); +begin + adduniqueitem(pointerarty(dest.fgclinksto),self); + adduniqueitem(pointerarty(fgclinksfrom),dest); +end; + +procedure tcanvas.unregistergclink(const dest: tcanvas); +begin + removeitem(pointerarty(dest.fgclinksto),self); + removeitem(pointerarty(fgclinksfrom),dest); +end; + +procedure tcanvas.gcdestroyed(const sender: tcanvas); +begin + //dummy +end; + +function tcanvas.createfont: tcanvasfont; +begin + result:= tcanvasfont.create(self); +end; + +class function tcanvas.getclassgdifuncs: pgdifunctionaty; +begin + result:= getdefaultgdifuncs; +end; + +function tcanvas.getgdifuncs: pgdifunctionaty; +begin + result:= getclassgdifuncs; +// result:= gui_getgdifuncs; +end; + +procedure tcanvas.error(nr: gdierrorty; const text: msestring); +begin + gdierror(nr,fuser,text); +end; + +function tcanvas.lock: boolean; +begin + result:= not gdi_locked(); + if result then begin + gdi_lock(); + end; +{ + with application do begin + result:= not gdilocked(); + if result then begin + lockgdi(); + end; + end; +} +end; + +procedure tcanvas.unlock; +begin + gdi_unlock(); +// application.unlockgdi(); +end; + +procedure tcanvas.doflush; +begin + fdrawinfo.gc.gdifuncs^[gdf_flush](fdrawinfo); + gui_flushgdi; +end; + +procedure tcanvas.gdi(const func: gdifuncty); +begin + if lock then begin + try + fdrawinfo.gc.gdifuncs^[func](fdrawinfo); + if flushgdi then begin + doflush(); + end; + finally + unlock; + end; + end + else begin + fdrawinfo.gc.gdifuncs^[func](fdrawinfo); + if flushgdi then begin + doflush(); + end; + end; +end; + +procedure tcanvas.checkrect(const rect: rectty); +begin + if (rect.cx < 0) or (rect.cy < 0) then begin + error(gde_invalidrect,''); + end; +end; + + +procedure tcanvas.intparametererror(value: integer; const text: msestring); +begin + error(gde_parameter,text + ' ' + inttostrmse(value)); +end; + +procedure tcanvas.initgcvalues; +begin + gccolorbackground:= cl_none; + gccolorforeground:= cl_none; + gcoptions:= []; + gcfonthandle1:= 0; + fstate:= fstate - changedmask; +end; + +procedure tcanvas.initgcstate; +begin + initgcvalues; +end; + +procedure tcanvas.finalizegcstate; +begin + //dummy +end; + +//var +// gcident: longword; + +procedure tcanvas.linktopaintdevice(apaintdevice: paintdevicety; + const gc: gcty; const cliporigin: pointty); +var + rea1: real; + int1: integer; + func1: pgdifunctionaty; + func2: pgdifunctionaty; +begin + resetpaintedflag; + if (fdrawinfo.gc.handle <> 0) then begin + for int1:= 0 to high(fgclinksto) do begin + fgclinksto[int1].gcdestroyed(self); + end; + gdi(gdf_destroygc); + end; + fdrawinfo.paintdevice:= apaintdevice; + rea1:= fdrawinfo.gc.ppmm; + func1:= fdrawinfo.gc.gdifuncs; + func2:= fdrawinfo.gc.fontgdifuncs; + fdrawinfo.gc:= gc; + if fdrawinfo.gc.fontgdifuncs = nil then begin + fdrawinfo.gc.fontgdifuncs:= fdrawinfo.gc.gdifuncs; + end; + fdrawinfo.gc.ppmm:= rea1; //restore + if fdrawinfo.gc.gdifuncs = nil then begin + fdrawinfo.gc.gdifuncs:= func1; //restore in case of unlink + fdrawinfo.gc.fontgdifuncs:= func2; //restore in case of unlink + end; + updatecliporigin(cliporigin); + if gc.handle <> 0 then begin + gdi(gdf_setcliporigin); + end; + if fdefaultfont <> 0 then begin + releasefont(fdefaultfont); + fdefaultfont:= 0; + end; + if gc.handle <> 0 then begin + initgcstate; + end + else begin + finalizegcstate; + end; +end; + +procedure tcanvas.unlink; +begin + reset; + gdi_lock; + try + linktopaintdevice(0,nullgc,{nullsize,}nullpoint); + finally + gdi_unlock; + end; +end; + +procedure tcanvas.initdrawinfo(var adrawinfo: drawinfoty); +begin + with fdrawinfo do begin + adrawinfo.paintdevice:= paintdevice; + adrawinfo.gc:= gc; + end; +end; + +// +// save stack, properties +// + +procedure tcanvas.init; + + procedure initvalues(var values: canvasvaluesty); + begin + with values do begin + if icanvas(fintf).getkind = bmk_mono then begin + color:= cl_1; + colorbackground:= cl_0; + font.baseinfo.color:= cl_1; + font.baseinfo.colorbackground:= cl_transparent; + end + else begin + color:= cl_black; + colorbackground:= cl_transparent; + font.baseinfo.color:= cl_default; + font.baseinfo.colorbackground:= cl_default; + end; + rasterop:= rop_copy; + end; + end; + +begin + fdrawinfo.gc.ppmm:= defaultppmm; + restore(0); +// reset; + initvalues(fvaluestack.stack[0]); + initvalues(fvaluestack.stack[1]); +end; + +procedure tcanvas.reset; +begin + restore(0); + fstate:= fstate - changedmask; +// clipregion:= 0; +// origin:= nullpoint; +end; + +function tcanvas.save: integer; +var + int1,int2: integer; + +begin +// if fdrawinfo.gc.handle <> 0 then begin +// checkgcstate([]); //update pending changes +// end; + with fvaluestack do begin + result:= count-1; + if count >= length(stack) then begin + setlength(stack,count+1); + end; + if count > 0 then begin + system.move(stack[count-1],stack[count],sizeof(canvasvaluesty)); + end + else begin + error(gde_invalidsaveindex,'save 0'); + end; + fvaluepo:= @stack[count]; + for int1:= 0 to high(fvaluepo^.font.handles) do begin + int2:= fvaluepo^.font.handles[int1]; + if int2 <> 0 then begin + addreffont(int2); + end; + end; + stringaddref(fvaluepo^.font.baseinfo.name); + stringaddref(fvaluepo^.font.baseinfo.charset); + updatefontinfo; + fvaluepo^.changed:= []; //reset changes + inc(count); + end; +end; + +procedure tcanvas.freevalues(var values: canvasvaluesty); +var + int1,int2: integer; +begin + with values do begin + if cs_regioncopy in changed then begin + destroyregion(clipregion); + end; + for int1:= 0 to high(values.font.handles) do begin + int2:= values.font.handles[int1]; + if int2 <> 0 then begin + releasefont(int2); + values.font.handles[int1]:= 0; + end; + end; +// stringrelease({fvaluepo^.}font.name); +// stringrelease({fvaluepo^.}font.charset); + end; + finalize(values); +end; + +function tcanvas.restore(index: integer = -1): integer; +var + int1: integer; + achanged: canvasstatesty; +begin + with fvaluestack do begin + if index >= count then begin + error(gde_invalidsaveindex,inttostrmse(index)); +//index:= count-1; + end; + if index < 0 then begin + if count < 2 then begin + error(gde_invalidsaveindex,inttostrmse(index)); + end; + index:= count - 2; + end; + achanged:= []; + for int1:= count-1 downto index + 1 do begin + achanged:= achanged + stack[int1].changed; + freevalues(stack[int1]); + end; + fstate:= fstate - achanged * changedmask; + fvaluepo:= @stack[index]; + updatefontinfo; + count:= index + 1; + if index = 0 then begin + result:= save; + end + else begin + result:= index; + end; + end; +end; + +procedure tcanvas.valuechanged(value: canvasstatety); +begin + include(fvaluepo^.changed,value); + exclude(fstate,value); +end; + +procedure tcanvas.valueschanged(values: canvasstatesty); +begin + fvaluepo^.changed:= fvaluepo^.changed + values; + fstate:= fstate - values; +end; + +procedure tcanvas.setfont(const Value: tfont); +begin + if ffont <> nil then begin +// if value.fhandlepo^ = 0 then begin +// value.createhandle(self); +// end; + ffont.assignproperties(value,true); +// ffont.assign(Value); + end; +end; + +procedure tcanvas.updatefontinfo; +begin + ffont.finfopo:= @fvaluepo^.font; + ffont.updatehandlepo; +end; + +// +// painting +// + +function ispaintcolor(acolor: colorty): boolean; {$ifdef FPC}inline;{$endif} +begin + result:= (acolor <> cl_transparent) and (acolor <> cl_none); +end; + +procedure tcanvas.checkgcstate(state: canvasstatesty); +var + values: gcvaluesty; + bo1,bo2: boolean; + po1: pfontdataty; +begin + if fdrawinfo.gc.handle = 0 then begin + gdi_lock; + try + icanvas(fintf).gcneeded(self); + finally + gdi_unlock; + end; + if fdrawinfo.gc.handle = 0 then begin + gdierror(gde_invalidgc,fuser); + end; + end; + if state = [cs_gc] then begin + exit; + end; + include(fstate,cs_painted); + inc(fdrawinfo.statestamp); + values.mask:= []; + + if not (cs_clipregion in fstate) then begin + values.clipregion:= fvaluepo^.clipregion; + include(values.mask,gvm_clipregion); + include(fstate,cs_clipregion); + end; + if not (cs_origin in fstate) then begin + fdrawinfo.origin:= fvaluepo^.origin; + include(fstate,cs_origin); + exclude(fstate,cs_brushorigin); + end; + if not (cs_rasterop in fstate) then begin + values.rasterop:= fvaluepo^.rasterop; + include(values.mask,gvm_rasterop); + include(fstate,cs_rasterop); + end; + with fdrawinfo,gc do begin + if not (cs_options in fstate) and (cs_options in state) then begin + values.options:= fvaluepo^.options; + if cao_smooth in values.options then begin + include(drawingflags,df_smooth); + end + else begin + exclude(drawingflags,df_smooth); + end; + include(values.mask,gvm_options); + include(fstate,cs_options); + end; + bo2:= df_brush in drawingflags; + drawingflags:= drawingflags - fillmodeinfoflags; + + if (cs_acolorforeground in state) then begin + bo1:= (acolorforeground = cl_brushcanvas); + if ((acolorforeground = cl_brush) or bo1) and (fvaluepo^.brush <> nil) then begin + include(drawingflags,df_brush); + end; + if (df_brush in drawingflags) xor bo2 then begin + include(values.mask,gvm_brushflag); + end; + if (df_brush in drawingflags) and not (cs_brushorigin in fstate) then begin + include(fstate,cs_brushorigin); + include(values.mask,gvm_brushorigin); + values.brushorigin:= fvaluepo^.brushorigin; + end; + if acolorforeground <> gccolorforeground then begin + if df_brush in drawingflags then begin + with fvaluepo^.brush do begin + if not (cs_brush in self.fstate) then begin + include(values.mask,gvm_brush); + values.brush:= fvaluepo^.brush; + end; + if getkind = bmk_mono then begin + include(drawingflags,df_monochrome); + include(state,cs_acolorbackground); + if bo1 then begin //use canvas colors + acolorforeground:= fvaluepo^.color; + acolorbackground:= fvaluepo^.colorbackground; + end + else begin //use brush colors + acolorforeground:= fcolorforeground; + acolorbackground:= fcolorbackground; + end; + end + else begin + exclude(drawingflags,df_monochrome); + end; + end; + include(fstate,cs_brush); + end; + end; + if acolorforeground <> gccolorforeground then begin + if drawingflags * [df_brush,df_monochrome] <> [df_brush] then begin + include(values.mask,gvm_colorforeground); + if kind = bmk_gray then begin + values.colorforeground:= graytopixel(acolorforeground); + end + else begin + values.colorforeground:= colortopixel(acolorforeground); + end; + end; + gccolorforeground:= acolorforeground; + include(fstate,cs_acolorforeground); + end; + end; + if (cs_acolorbackground in state) and (acolorbackground <> gccolorbackground) then begin + include(values.mask,gvm_colorbackground); + if kind = bmk_gray then begin + values.colorbackground:= graytopixel(acolorbackground); + end + else begin + values.colorbackground:= colortopixel(acolorbackground); + end; + gccolorbackground:= acolorbackground; + end; + if ispaintcolor(gccolorbackground) then begin + include(drawingflags,df_opaque); + end + else begin + exclude(drawingflags,df_opaque); + end; + if cs_font in state then begin + if (afonthandle1 <> gcfonthandle1) then begin + include(values.mask,gvm_font); + values.fontnum:= afonthandle1; + po1:= getfontdata(afonthandle1); + values.fontdata:= po1; + with po1^ do begin + values.font:= font; + if (df_highresfont in fdrawinfo.gc.drawingflags) then begin + checkhighresfont(po1,fdrawinfo); + end; + end; + gcfonthandle1:= afonthandle1; + end; + include(drawingflags,df_monochrome); + end; + + state:= (state - fstate) * linecanvasstates; //update lineinfos + if state <> [] then begin + values.lineinfo:= fvaluepo^.lineinfo; + if length(dashes) > 0 then begin + include(fdrawinfo.gc.drawingflags,df_dashed); + end + else begin + exclude(fdrawinfo.gc.drawingflags,df_dashed); + end; + fstate:= fstate + state; + if cs_linewidth in state then include(values.mask,gvm_linewidth); + if cs_dashes in state then include(values.mask,gvm_dashes); + if cs_capstyle in state then include(values.mask,gvm_capstyle); + if cs_joinstyle in state then include(values.mask,gvm_joinstyle); + fstate:= fstate + state; + end; + if values.mask <> [] then begin + fdrawinfo.gcvalues:= @values; + gdi(gdf_changegc); + end; + end; +end; + +function tcanvas.getgchandle: ptruint; +begin + checkgcstate([cs_gc]); + result:= fdrawinfo.gc.handle; +end; + +function tcanvas.getimage(const bgr: boolean): maskedimagety; +begin + fillchar(result,sizeof(result),0); + icanvas(fintf).getcanvasimage(bgr,result); +end; + +function tcanvas.checkforeground(acolor: colorty; lineinfo: boolean): boolean; +begin + with fdrawinfo do begin + if (acolor = cl_default) or (acolor = cl_parent) then begin + acolorforeground:= fvaluepo^.color; + end + else begin + acolorforeground:= acolor; + end; + if ispaintcolor(acolorforeground) then begin + if lineinfo then begin + if length(dashes) > 0 then begin + acolorbackground:= fvaluepo^.colorbackground; + checkgcstate([cs_options,cs_acolorforeground,cs_acolorbackground]+ + linecanvasstates); + end + else begin + checkgcstate([cs_options,cs_acolorforeground]+linecanvasstates); + end; + end + else begin + checkgcstate([cs_options,cs_acolorforeground]); + end; + result:= true; + end + else begin + result:= false; + end; + end; +end; + +procedure tcanvas.checkcolors; +begin + with fdrawinfo do begin + acolorforeground:= fvaluepo^.color; + acolorbackground:= fvaluepo^.colorbackground; + checkgcstate([cs_acolorforeground,cs_acolorbackground]); + end; +end; + +procedure tcanvas.internalcopyarea(asource: tcanvas; const asourcerect: rectty; + const adestrect: rectty; acopymode: rasteropty; + atransparentcolor: colorty; + amask: tsimplebitmap; + const amaskpos: pointty; + aalignment: alignmentsty; + const atileorigin: pointty; + const aopacity: colorty); //cl_none -> opaque + + //todo: use serverside tiling + // limit stretched rendering to cliprects +var + srect,drect,rect1: rectty; + spoint,dpoint,tileorig: pointty; + startx: integer; + endx,endy: integer; +// endcx,endcy: integer; + stepx,stepy: integer; + sourcex,sourcey: integer; + int1{,int2}: integer; +// bo1,bo2: boolean; + + function checkmaskrect(var arect,brect: rectty): boolean; + var + rect2: rectty; + begin + rect2:= intersectrect(arect,mr(amaskpos,amask.size)); + if (rect2.cx < arect.cx) or (rect2.cy < arect.cy) then begin + //mask not big enough + if (rect2.cx <= 0) or (rect2.cy <= 0) then begin + result:= true; + exit; + end; + brect.x:= brect.x + (rect2.x - arect.x) * brect.cx div arect.cx; + brect.y:= brect.y + (rect2.y - arect.y) * brect.cy div arect.cy; + brect.cx:= (brect.cx * rect2.cx) div arect.cx; + brect.cy:= (brect.cy * rect2.cy) div arect.cy; + arect:= rect2; + end; + result:= false; + end; + +var + al1: alignmentsty; +begin + if (asourcerect.cx <= 0) or (asourcerect.cy <= 0) or + (adestrect.cx <= 0) or (adestrect.cy <= 0) then begin //no div 0 + exit; + end; + if (al_thumbnail in aalignment) and ((asourcerect.cx > adestrect.cx) or + (asourcerect.cy > adestrect.cy)) then begin + include(aalignment,al_fit); + end; + checkgcstate([]); //gc must be valid + if asource <> self then begin + asource.checkgcstate([cs_gc]); //gc must be valid + end; + dpoint:= adestrect.pos; + if aalignment * [al_fit{,al_tiled}] = [] then begin + if not (al_stretchx in aalignment) then begin + int1:= adestrect.cx - asourcerect.cx; + if al_right in aalignment then begin + dpoint.x:= dpoint.x + int1; + end + else begin + if al_xcentered in aalignment then begin + if int1 < 0 then begin + dec(int1); + end; + dpoint.x:= dpoint.x + int1 div 2; + end; + end; + end; + if not (al_stretchy in aalignment) then begin + int1:= adestrect.cy - asourcerect.cy; + if al_bottom in aalignment then begin + dpoint.y:= dpoint.y + int1; + end + else begin + if al_ycentered in aalignment then begin + if int1 < 0 then begin + dec(int1); + end; + dpoint.y:= dpoint.y + int1 div 2; + end; + end; + end; + end; + tileorig:= atileorigin; + if al_tiled in aalignment then begin + if aalignment * [al_xcentered,al_right] <> [] then begin + tileorig.x:= dpoint.x; + end; + if aalignment * [al_ycentered,al_bottom] <> [] then begin + tileorig.y:= dpoint.y; + end; + dpoint:= adestrect.pos; + end; + dpoint.x:= dpoint.x + fdrawinfo.origin.x; + dpoint.y:= dpoint.y + fdrawinfo.origin.y; + tileorig.x:= tileorig.x + fdrawinfo.origin.x; + tileorig.y:= tileorig.y + fdrawinfo.origin.y; + with asourcerect,asource.fvaluepo^ do begin + spoint.x:= x + origin.x; + spoint.y:= y + origin.y; + end; + rect1:= moverect(clipbox,fvaluepo^.origin); + drect.size:= adestrect.size; + if not msegraphutils.intersectrect(makerect(spoint,asourcerect.size), + makerect(makepoint(0,0),icanvas(asource.fintf).getsize),srect) then begin + exit; + end; + al1:= aalignment * [al_stretchx,al_stretchy,al_fit,al_tiled]; + if al1 = [] then begin //clip areas to paintdevice rect + dpoint.x:= dpoint.x + srect.x - spoint.x; + dpoint.y:= dpoint.y + srect.y - spoint.y; + if not msegraphutils.intersectrect(makerect(dpoint,srect.size), + rect1,drect) then begin + exit; + end; + srect.x:= srect.x + drect.x - dpoint.x; + srect.cx:= drect.cx; + srect.y:= srect.y + drect.y - dpoint.y; + srect.cy:= drect.cy; + end + else begin + srect.pos:= spoint; + srect.size:= asourcerect.size; + drect.pos:= dpoint; + if al1 = [al_stretchx] then begin + drect.cy:= srect.cy; + end; + if al1 = [al_stretchy] then begin + drect.cx:= srect.cx; + end; + end; + if amask <> nil then begin + if al_nomaskscale in aalignment then begin + if checkmaskrect(drect,srect) then begin + exit; + end; + end + else begin + if checkmaskrect(srect,drect) then begin + exit; + end; + end; + end; + with fdrawinfo,copyarea do begin + source:= asource; + sourcerect:= @srect; + destrect:= @drect; + alignment:= aalignment; + copymode:= acopymode; + mask:= amask; + if (srect.cx = 0) or (srect.cy = 0) then begin + exit; + end; + if al_fit in aalignment then begin + alignment:= alignment + [al_stretchx,al_stretchy]; + if srect.cy * drect.cx > srect.cx * drect.cy then begin //fit vert + drect.cx:= (srect.cx * drect.cy) div srect.cy; + int1:= adestrect.cx - drect.cx; + if al_right in aalignment then begin + drect.x:= drect.x + int1; + end + else begin + if al_xcentered in aalignment then begin + if int1 < 0 then begin + dec(int1); + end; + drect.x:= drect.x + int1 div 2; + end; + end; + end + else begin + drect.cy:= (srect.cy * drect.cx) div srect.cx; + int1:= adestrect.cy - drect.cy; + if al_bottom in aalignment then begin + drect.y:= drect.y + int1; + end + else begin + if al_ycentered in aalignment then begin + if int1 < 0 then begin + dec(int1); + end; + drect.y:= drect.y + int1 div 2; + end; + end; + end; + end; + maskshift.x:= -amaskpos.x; + maskshift.y:= -amaskpos.y; + maskshiftscaled.x:= (maskshift.x*drect.cx) div srect.cx; + maskshiftscaled.y:= (maskshift.y*drect.cy) div srect.cy; + if aopacity = cl_none then begin + longword(opacity):= maxopacity; + end + else begin + opacity:= colortorgb(aopacity); + end; + + if gc.kind <> source.fdrawinfo.gc.kind then begin //different colorformat + include(gc.drawingflags,df_colorconvert); + with fdrawinfo,gc do begin + acolorforeground:= fvaluepo^.color; + if source.fdrawinfo.gc.kind = bmk_mono then begin //monochrome to color or gray + acolorbackground:= fvaluepo^.colorbackground; + checkgcstate([cs_acolorforeground,cs_acolorbackground]); + end + else begin + if gc.kind = bmk_mono then begin //color or gray to monochrome + if atransparentcolor = cl_default then begin + atransparentcolor:= fvaluepo^.colorbackground; + end; + if source.fdrawinfo.gc.kind = bmk_gray then begin + transparentcolor:= graytopixel(atransparentcolor); + end + else begin + transparentcolor:= colortopixel(atransparentcolor); + end; + end; + end; + end; + end + else begin + exclude(gc.drawingflags,df_colorconvert); + end; + end; + if al_tiled in aalignment then begin + if msegraphutils.intersectrect(drect,rect1,rect1) then begin + if not (al_stretchy in aalignment) then begin + drect.cy:= srect.cy; + if drect.y >= tileorig.y then begin + drect.y:= tileorig.y + ((rect1.y - tileorig.y) div srect.cy) * srect.cy; + end + else begin + drect.y:= tileorig.y - ((tileorig.y - rect1.y + srect.cy) div srect.cy) * srect.cy; + end; + end; + if not (al_stretchx in aalignment) then begin + drect.cx:= srect.cx; + if drect.x >= tileorig.x then begin + startx:= tileorig.x + ((rect1.x - tileorig.x) div srect.cx) * srect.cx; + end + else begin + startx:= tileorig.x - ((tileorig.x - rect1.x + srect.cx) div srect.cx) * srect.cx; + end; + end + else begin + startx:= drect.x; + end; + stepx:= srect.cx; + stepy:= srect.cy; + endx:= rect1.x + rect1.cx; + endy:= rect1.y + rect1.cy; + sourcex:= srect.x; + sourcey:= srect.y; + if not (al_stretchy in aalignment) then begin + int1:= drect.y - rect1.y; + if int1 < 0 then begin + dec(srect.y,int1); + dec(drect.y,int1); + inc(srect.cy,int1); + drect.cy:= srect.cy; + end; + end; + if al_stretchx in aalignment then begin + int1:= 0; + end + else begin + int1:= startx - rect1.x; + if int1 > 0 then begin + int1:= 0; + end; + end; + repeat + if not (al_stretchy in aalignment) then begin + if drect.y + srect.cy > endy then begin + srect.cy:= endy - drect.y; + end; + drect.cy:= srect.cy; + end; + drect.x:= startx; + dec(srect.x,int1); + dec(drect.x,int1); + inc(srect.cx,int1); + repeat + if not (al_stretchx in aalignment) then begin + if drect.x + srect.cx > endx then begin + srect.cx:= endx - drect.x; + end; + drect.cx:= srect.cx; + end; + if (srect.cx > 0) and (srect.cy > 0) then begin + gdi(gdf_copyarea); + end; + inc(drect.x,srect.cx); + srect.cx:= stepx; + srect.x:= sourcex; + until (al_stretchx in aalignment) or (drect.x >= endx); + inc(drect.y,srect.cy); + srect.y:= sourcey; + srect.cy:= stepy; + drect.cy:= stepy; + until (al_stretchy in aalignment) or (drect.y >= endy); + end; + end + else begin + gdi(gdf_copyarea); + end; + if amask <> nil then begin + exclude(fstate,cs_clipregion); + end; +end; + +procedure tcanvas.copyarea(const asource: tcanvas; const asourcerect: rectty; + const adestpoint: pointty; + const acopymode: rasteropty = rop_copy; + const atransparentcolor: colorty = cl_default; + const aopacity: colorty = cl_none); +begin + if cs_inactive in fstate then exit; + internalcopyarea(asource,asourcerect,makerect(adestpoint,asourcerect.size), + acopymode,atransparentcolor,nil,nullpoint,[],nullpoint,aopacity); +end; + +procedure tcanvas.copyarea(const asource: tcanvas; const asourcerect: rectty; + const adestrect: rectty; const alignment: alignmentsty = []; + const acopymode: rasteropty = rop_copy; + const atransparentcolor: colorty = cl_default; + //atransparentcolor used for convert color to monochrome + //cl_default -> colorbackground + const aopacity: colorty = cl_none); +begin + if cs_inactive in fstate then exit; + internalcopyarea(asource,asourcerect,adestrect, + acopymode,atransparentcolor,nil,nullpoint,alignment, + nullpoint,aopacity); +end; + +procedure tcanvas.drawpoints(const apoints: array of pointty; const acolor: colorty; + first, acount: integer); +var + int1,int2: integer; + pointar: pointarty; +begin + if cs_inactive in fstate then exit; + if length(apoints) > 0 then begin + if checkforeground(acolor,true) then begin + with fdrawinfo.points do begin + int1:= length(apoints) - first; + if int1 < 0 then begin + intparametererror(first,'drawpoints first'); + end; + if acount < 0 then begin + acount:= int1; + end + else begin + if acount > int1 then begin + intparametererror(acount,'drawponts acount'); + end; + end; + count:= 2*acount; + setlength(pointar,count); + int2:= 0; + for int1:= first to first + acount - 1 do begin + pointar[int2]:= apoints[int1]; + pointar[int2+1]:= apoints[int1]; + inc(int2,2); + end; + points:= @pointar[0]; + end; + gdi(gdf_drawlinesegments); + end; + end; +end; + +procedure tcanvas.drawpoint(const point: pointty; + const acolor: colorty = cl_default); +begin + if cs_inactive in fstate then exit; + drawpoints(point,acolor,0,1); +end; + +procedure tcanvas.drawlines(const apoints: array of pointty; + const aclosed: boolean = false; + const acolor: colorty = cl_default; + const first: integer = 0; const acount: integer = -1); + //-1 -> all +var + int1: integer; +begin + if cs_inactive in fstate then exit; + if length(apoints) > 0 then begin + if checkforeground(acolor,true) then begin + with fdrawinfo.points do begin + int1:= length(apoints) - first; + if int1 < 0 then begin + intparametererror(first,'drawlines first'); + end; + if acount < 0 then begin + count:= int1; + end + else begin + if acount > int1 then begin + intparametererror(acount,'drawlines acount'); + end; + count:= acount; + end; + int1:= count - 2; + if (int1 > 0) and (apoints[int1].x = apoints[int1+1].x) and + (apoints[int1].y = apoints[int1+1].y) then begin + //coincident endpoints are not drawn on x11 + dec(count); + end; + closed:= aclosed; + points:= @apoints[first]; + end; + gdi(gdf_drawlines); + end; + end; +end; + +procedure tcanvas.drawlines(const apoints: array of pointty; + const abreaks: array of integer; //ascending order + const aclosed: boolean = false; + const acolor: colorty = cl_default; + const first: integer = 0; const acount: integer = -1); +var + int1: integer; + s,e: integer; + e1: integer; +begin + if cs_inactive in fstate then exit; + if length(apoints) > 0 then begin + if checkforeground(acolor,true) then begin + int1:= length(apoints) - first; + if int1 < 0 then begin + intparametererror(first,'drawlines first'); + end; + if acount < 0 then begin + e1:= int1; + end + else begin + if acount > int1 then begin + intparametererror(acount,'drawlines acount'); + end; + e1:= acount; + end; + + s:= first; + e1:= s + e1; + int1:= 0; + while int1 <= high(abreaks) do begin + if abreaks[int1] > s then begin + break; + end; + inc(int1); + end; + with fdrawinfo.points do begin + closed:= false; + repeat + e:= e1; + if (int1 <= high(abreaks)) and (abreaks[int1] < e) then begin + e:= abreaks[int1]; + inc(int1); + end; + points:= @apoints[s]; + count:= e-s; + if (first = 0) and (e = length(apoints)) then begin + closed:= aclosed; + end; + gdi(gdf_drawlines); + s:= e; + until e = e1; + end; + end; + end; +end; + +procedure tcanvas.drawrect(const arect: rectty; const acolor: colorty = cl_default); +begin + if cs_inactive in fstate then exit; + with arect do begin + drawlines([pos,makepoint(x+cx,y),makepoint(x+cx,y+cy),makepoint(x,y+cy)], + true,acolor); + end; +end; + +procedure tcanvas.drawcross(const arect: rectty; const acolor: colorty = cl_default; + const alignment: alignmentsty = [al_xcentered,al_ycentered]); +var + ar1: segmentarty; +begin + if cs_inactive in fstate then exit; + if (arect.cx > 0) and (arect.cy > 0) then begin + setlength(ar1,2); + with arect do begin + with ar1[0] do begin + a:= pos; + b.x:= x + cx - 1; + b.y:= y + cy - 1; + end; + with ar1[1] do begin + a.x:= x; + a.y:= ar1[0].b.y; + b.x:= ar1[0].b.x; + b.y:= y; + end; + drawlinesegments(ar1,acolor); + end; + end; +end; + +procedure tcanvas.drawlinesegments(const apoints: array of segmentty; + const acolor: colorty = cl_default); +begin + if cs_inactive in fstate then exit; + if length(apoints) > 0 then begin + if (high(apoints) >= 0) and checkforeground(acolor,true) then begin + with fdrawinfo.points do begin + points:= @apoints[0]; + count:= length(apoints) * 2; + end; + gdi(gdf_drawlinesegments); + end; + end; +end; + +procedure tcanvas.drawline(const startpoint,endpoint: pointty; + const acolor: colorty = cl_default); +begin + if cs_inactive in fstate then exit; + drawlinesegments([segment(startpoint,endpoint)],acolor); +end; + +procedure tcanvas.drawline(const startpoint: pointty; const length: sizety; + const acolor: colorty = cl_default); +var + seg1: segmentty; +begin + if cs_inactive in fstate then exit; + seg1.a:= startpoint; + seg1.b.x:= seg1.a.x + length.cx; + seg1.b.y:= seg1.a.y + length.cy; + drawlinesegments([seg1],acolor); +end; + +procedure tcanvas.drawvect(const startpoint: pointty; + const direction: graphicdirectionty; + const length: integer; out endpoint: pointty; + const acolor: colorty = cl_default); +var + endpoint1: pointty; +begin + if cs_inactive in fstate then exit; + endpoint1:= startpoint; + case direction of + gd_right: inc(endpoint1.x,length); + gd_up: dec(endpoint1.y,length); + gd_left: dec(endpoint1.x,length); + gd_down: inc(endpoint1.y,length); + else begin + endpoint:= endpoint1; + exit; + end; + end; + drawlinesegments([segment(startpoint,endpoint1)],acolor); + endpoint:= endpoint1; +end; + +procedure tcanvas.drawvect(const startpoint: pointty; + const direction: graphicdirectionty; + const length: integer; const acolor: colorty = cl_default); +var + po1: pointty; +begin + if cs_inactive in fstate then exit; + drawvect(startpoint,direction,length,po1,acolor); +end; + +procedure tcanvas.drawellipse(const def: rectty; + const acolor: colorty = cl_default); + //def.pos = center, def.cx = width, def.cy = height +begin + if cs_inactive in fstate then exit; + if checkforeground(acolor,true) then begin + fdrawinfo.rect.rect:= @def; + gdi(gdf_drawellipse); + end; +end; + +procedure tcanvas.drawcircle(const center: pointty; const radius: integer; + const acolor: colorty = cl_default); +var + rect1: rectty; +begin + rect1.pos:= center; + rect1.cx:= 2*radius; + rect1.cy:= rect1.cx; + drawellipse(rect1,acolor); +end; + +procedure tcanvas.drawellipse1(const def: rectty; + const acolor: colorty = cl_default); + //def.pos = topleft, def.cx = width, def.cy = height +begin + drawellipse(recenterrect(def),acolor); +end; + +procedure tcanvas.drawarc(const def: rectty; const startang,extentang: real; + const acolor: colorty = cl_default); +begin + if cs_inactive in fstate then exit; + if checkforeground(acolor,true) then begin + fdrawinfo.arc.rect:= @def; + fdrawinfo.arc.startang:= startang; + fdrawinfo.arc.extentang:= extentang; + gdi(gdf_drawarc); + end; +end; + +procedure tcanvas.drawarc(const center: pointty; const radius: integer; + const startang,extentang: real; + const acolor: colorty = cl_default); +var + rect1: rectty; +begin + rect1.pos:= center; + rect1.cx:= 2*radius; + rect1.cy:= rect1.cx; + drawarc(rect1,startang,extentang,acolor); +end; + +procedure tcanvas.drawarc1(const def: rectty; const startang,extentang: real; + const acolor: colorty = cl_default); +begin + drawarc(recenterrect(def),startang,extentang,acolor); +end; + +procedure tcanvas.fillrect(const arect: rectty; + const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); +var + rect1: rectty; +begin + if cs_inactive in fstate then exit; + if checkforeground(acolor,false) then begin + with fdrawinfo.rect do begin + rect:= @arect; + if (arect.cx < 0) then begin + rect:= @rect1; + rect1.x:= arect.x + arect.cx + 1; + rect1.cx:= -arect.cx; + if arect.cy < 0 then begin + rect1.y:= arect.y + arect.cy + 1; + rect1.cy:= -arect.cy; + end + else begin + rect1.y:= arect.y; + rect1.cy:= arect.cy; + end; + end + else begin + if arect.cy < 0 then begin + rect:= @rect1; + rect1.y:= arect.y + arect.cy + 1; + rect1.cy:= -arect.cy; + rect1.x:= arect.x; + rect1.cx:= arect.cx; + end; + end; + end; + gdi(gdf_fillrect); + end; + if (linecolor <> cl_none) then begin + drawrect(arect,linecolor); + end; +end; + +procedure tcanvas.fillellipse(const def: rectty; + const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); +begin + if (cs_inactive in fstate) or (def.cx = 0) or (def.cy = 0) then exit; + if checkforeground(acolor,false) then begin + with fdrawinfo.rect do begin + rect:= @def; + end; + gdi(gdf_fillellipse); + end; + if (linecolor <> cl_none) then begin + drawellipse(def,linecolor); + end; +end; + +procedure tcanvas.fillcircle(const center: pointty; const radius: integer; + const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); +var + rect1: rectty; +begin + rect1.pos:= center; + rect1.cx:= 2*radius; + rect1.cy:= rect1.cx; + fillellipse(rect1,acolor,linecolor); +end; + +procedure tcanvas.fillellipse1(const def: rectty; + const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); +begin + fillellipse(recenterrect(def),acolor,linecolor); +end; + +procedure tcanvas.fillarc(const def: rectty; const startang: real; + const extentang: real; const acolor: colorty; + const pieslice: boolean); +begin + if cs_inactive in fstate then exit; + if checkforeground(acolor,false) then begin + fdrawinfo.arc.rect:= @def; + fdrawinfo.arc.startang:= startang; + fdrawinfo.arc.extentang:= extentang; + fdrawinfo.arc.pieslice:= pieslice; + gdi(gdf_fillarc); + end; +end; + +procedure tcanvas.getarcinfo(out startpo,endpo: pointty); +var + stopang: real; +begin + with fdrawinfo,arc,rect^ do begin + stopang:= (startang+extentang); + startpo.x:= (round(cos(startang)*cx) div 2) + x; + startpo.y:= (round(-sin(startang)*cy) div 2) + y; + endpo.x:= (round(cos(stopang)*cx) div 2) + x; + endpo.y:= (round(-sin(stopang)*cy) div 2) + y; + end; +end; + +procedure tcanvas.fillarcchord(const def: rectty; const startang: real; + const extentang: real; const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); +var + startpo,endpo: pointty; +begin + if cs_inactive in fstate then exit; + fillarc(def,startang,extentang,acolor,false); + if (linecolor <> cl_none) then begin + fdrawinfo.arc.rect:= @def; //necessary for 64 bit + getarcinfo(startpo,endpo); + drawline(startpo,endpo,linecolor); + drawarc(def,startang,extentang,linecolor); + end; +end; + +procedure tcanvas.fillarcchord(const center: pointty; const radius: integer; + const startang,extentang: real; + const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); +var + rect1: rectty; +begin + rect1.pos:= center; + rect1.cx:= 2*radius; + rect1.cy:= rect1.cx; + fillarcchord(rect1,startang,extentang,acolor,linecolor); +end; + +procedure tcanvas.fillarcchord1(const def: rectty; const startang: real; + const extentang: real; const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); +begin + fillarcchord(recenterrect(def),startang,extentang,acolor,linecolor); +end; + +procedure tcanvas.fillarcpieslice(const def: rectty; const startang: real; + const extentang: real; const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); +var + startpo,endpo: pointty; +begin + if cs_inactive in fstate then exit; + fillarc(def,startang,extentang,acolor,true); + if (linecolor <> cl_none) then begin + fdrawinfo.arc.rect:= @def; //necessary for 64 bit + getarcinfo(startpo,endpo); + drawlines([startpo,def.pos,endpo],false,linecolor); + drawarc(def,startang,extentang,linecolor); + end; +end; + +procedure tcanvas.fillarcpieslice(const center: pointty; const radius: integer; + const startang,extentang: real; + const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); +var + rect1: rectty; +begin + rect1.pos:= center; + rect1.cx:= 2*radius; + rect1.cy:= rect1.cx; + fillarcpieslice(rect1,startang,extentang,acolor,linecolor); +end; + +procedure tcanvas.fillarcpieslice1(const def: rectty; const startang: real; + const extentang: real; const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); +begin + fillarcpieslice(recenterrect(def),startang,extentang,acolor,linecolor); +end; + +procedure tcanvas.fillpolygon(const apoints: array of pointty; + const acolor: colorty = cl_default; + const linecolor: colorty = cl_none); +begin + if cs_inactive in fstate then exit; + if checkforeground(acolor,false) then begin + with fdrawinfo.points do begin + points:= @apoints; + count:= length(apoints); + end; + gdi(gdf_fillpolygon); + end; + if (linecolor <> cl_none) then begin + drawlines(apoints,true,linecolor); + end; +end; + +procedure tcanvas.drawstring(const atext: pmsechar; const acount: integer; + const apos: pointty; + const afont: tfont = nil; const grayed: boolean = false; + const arotation: real = 0); +var + afontnum: integer; + po1: pfontinfoty; + font1: tfont; +// int1: integer; +begin + if cs_inactive in fstate then exit; + with fdrawinfo do begin + if afont <> nil then begin //foreign font + if fs_blank in afont.style then begin + exit; + end; + font1:= afont; + with afont do begin + po1:= finfopo; + rotation:= arotation; + afontnum:= gethandleforcanvas(self); + afonthandle1:= afontnum; + acolorbackground:= colorbackground; + end; + end + else begin + if fs_blank in ffont.style then begin + exit; + end; + font1:= ffont; + ffont.rotation:= arotation; + afonthandle1:= ffont.gethandle; + po1:= @fvaluepo^.font; + with fvaluepo^.font do begin + acolorbackground:= baseinfo.colorbackground; + end; + end; + with fdrawinfo.text16pos do begin + pos:= @apos; + text:= pointer(atext); + count:= acount; + if grayed and (po1^.baseinfo.grayed_colorshadow <> cl_none) or + (po1^.baseinfo.shadow_color <> cl_none) or + (po1^.baseinfo.gloss_color <> cl_none) then begin + if grayed then begin + acolorforeground:= po1^.baseinfo.grayed_colorshadow;//cl_white; + if acolorforeground = cl_default then begin + acolorforeground:= cl_grayedshadow; + end; + inc(pos^.x,po1^.baseinfo.grayed_shiftx); + inc(pos^.y,po1^.baseinfo.grayed_shifty); +// inc(pos^.x,po1^.shadow_shiftx); +// inc(pos^.y,po1^.shadow_shifty); + end + else begin + if po1^.baseinfo.shadow_color <> cl_none then begin + acolorforeground:= po1^.baseinfo.shadow_color; + inc(pos^.x,po1^.baseinfo.shadow_shiftx); + inc(pos^.y,po1^.baseinfo.shadow_shifty); + end + else begin + acolorforeground:= po1^.baseinfo.gloss_color; + inc(pos^.x,po1^.baseinfo.gloss_shiftx); + inc(pos^.y,po1^.baseinfo.gloss_shifty); + end; + end; + acolorbackground:= cl_transparent; + if acolorforeground = cl_default then begin + acolorforeground:= cl_text; + end; + checkgcstate([cs_font,cs_acolorforeground,cs_acolorbackground]); + gdi(gdf_drawstring16); + if grayed then begin + dec(pos^.x,po1^.baseinfo.grayed_shiftx); + dec(pos^.y,po1^.baseinfo.grayed_shifty); + acolorforeground:= po1^.baseinfo.grayed_color;//cl_dkgray; + if acolorforeground = cl_default then begin + acolorforeground:= cl_grayed; + end; + end + else begin + if po1^.baseinfo.shadow_color <> cl_none then begin + dec(pos^.x,po1^.baseinfo.shadow_shiftx); + dec(pos^.y,po1^.baseinfo.shadow_shifty); + if po1^.baseinfo.gloss_color <> cl_none then begin + acolorforeground:= po1^.baseinfo.gloss_color; + inc(pos^.x,po1^.baseinfo.gloss_shiftx); + inc(pos^.y,po1^.baseinfo.gloss_shifty); + checkgcstate([cs_font,cs_acolorforeground,cs_acolorbackground]); + gdi(gdf_drawstring16); + dec(pos^.x,po1^.baseinfo.gloss_shiftx); + dec(pos^.y,po1^.baseinfo.gloss_shifty); + end; + end + else begin + dec(pos^.x,po1^.baseinfo.gloss_shiftx); + dec(pos^.y,po1^.baseinfo.gloss_shifty); + end; + acolorforeground:= po1^.baseinfo.color; + end; + if acolorforeground = cl_default then begin + acolorforeground:= cl_text; + end; + checkgcstate([cs_acolorforeground]); + gdi(gdf_drawstring16); + end + else begin + if grayed then begin + acolorforeground:= po1^.baseinfo.grayed_color; + end + else begin + acolorforeground:= po1^.baseinfo.color; + end; + if acolorforeground = cl_default then begin + acolorforeground:= cl_text; + end; + if acolorbackground = cl_default then begin + acolorbackground:= cl_transparent; + end; + checkgcstate([cs_font,cs_acolorforeground,cs_acolorbackground]); + gdi(gdf_drawstring16); + end; + end; + font1.rotation:= 0; + end; +end; + +procedure tcanvas.drawfontline(const startpoint,endpoint: pointty); + //draws line with font color +var + linewidthbefore: integer; + capstylebefore: capstylety; + pt1,pt2: pointty; + co1: colorty; +begin + linewidthbefore:= linewidth; + capstylebefore:= capstyle; + linewidth:= font.linewidth; + capstyle:= cs_butt; + + with fvaluepo^.font do begin + if (baseinfo.shadow_color <> cl_none) then begin + pt1.x:= startpoint.x + baseinfo.shadow_shiftx; + pt1.y:= startpoint.y + baseinfo.shadow_shifty; + pt2.x:= endpoint.x + baseinfo.shadow_shiftx; + pt2.y:= endpoint.y + baseinfo.shadow_shifty; + drawline(pt1,pt2,baseinfo.shadow_color); + end; + if (baseinfo.gloss_color <> cl_none) then begin + pt1.x:= startpoint.x + baseinfo.gloss_shiftx; + pt1.y:= startpoint.y + baseinfo.gloss_shifty; + pt2.x:= endpoint.x + baseinfo.gloss_shiftx; + pt2.y:= endpoint.y + baseinfo.gloss_shifty; + drawline(pt1,pt2,baseinfo.gloss_color); + end; + end; + co1:= font.color; + if co1 = cl_default then begin + co1:= cl_text; + end; + drawline(startpoint,endpoint,co1); + linewidth:= linewidthbefore; + capstyle:= capstylebefore; +end; + +procedure tcanvas.nextpage; //used by tcustomprintercanvas +begin + //dummy +end; + +procedure tcanvas.drawstring(const atext: msestring; const apos: pointty; + const afont: tfont = nil; const grayed: boolean = false; + const arotation: real = 0); +begin + if cs_inactive in fstate then exit; + drawstring(pointer(atext),length(atext),apos,afont,grayed,arotation); +end; + +function tcanvas.getstringwidth(const atext: pmsechar; const acount: integer; + const afont: tfont = nil): integer; +var + afontnum: integer; +begin + result:= 0; + if atext <> '' then begin + checkgcstate([cs_gc]); + if afont <> nil then begin //foreign font + if fs_blank in afont.style then begin + exit; + end; + afontnum:= afont.gethandleforcanvas(self); + end + else begin + if fs_blank in ffont.style then begin + exit; + end; + afontnum:= ffont.handle; + end; + with fdrawinfo.gettext16width do begin + fontdata:= getfontdata(afontnum); + text:= atext; + count:= acount; + end; + gdi(gdf_gettext16width); + result:= fdrawinfo.gettext16width.result; + end; +end; + +function tcanvas.getstringwidth(const atext: msestring; const afont: tfont = nil): integer; +begin + result:= getstringwidth(pmsechar(atext),length(atext),afont); +end; + +function tcanvas.getfontmetrics(const achar: ucs4char; + const afont: tfont = nil): fontmetricsty; +var + afontnum: integer; +begin + if afont <> nil then begin //foreign font + afontnum:= afont.gethandleforcanvas(self); + end + else begin + afontnum:= ffont.handle; + end; + with fdrawinfo.getfontmetrics do begin + fontdata:= getfontdata(afontnum); + char:= achar; + resultpo:= @result; + end; + checkgcstate([cs_gc]); + gdi(gdf_getfontmetrics); +// gdi_lock; +// gdierrorlocked(gui_getfontmetrics(fdrawinfo),self); + with result do begin + sum:= width - leftbearing - rightbearing; + end; +end; + +function tcanvas.getfontmetrics(const achar: msechar; + const afont: tfont = nil): fontmetricsty; +begin + result:= getfontmetrics(ucs4char(card16(achar)),afont); +end; + +procedure tcanvas.drawframe(const arect: rectty; awidth: integer; + const acolor: colorty; const hiddenedges: edgesty); +var + rect1,rect2: rectty; +begin + if cs_inactive in fstate then exit; + + if ispaintcolor(acolor) then begin + if awidth <> 0 then begin + if awidth < 0 then begin + rect2:= arect; + awidth:= - awidth; + end + else begin + rect2.x:= arect.x - awidth; + rect2.y:= arect.y - awidth; + rect2.cx:= arect.cx + awidth + awidth; + rect2.cy:= arect.cy + awidth + awidth; + end; + if checkforeground(acolor,false) then begin + with fdrawinfo.rect do begin + rect:= @rect1; + with rect2 do begin + rect1.pos:= pos; + rect1.cx:= cx; + rect1.cy:= awidth; + if not (edg_top in hiddenedges) then begin + gdi(gdf_fillrect); //top + end; + rect1.pos.y:= y + cy - awidth; + if not (edg_bottom in hiddenedges) then begin + gdi(gdf_fillrect); //bottom + end; + rect1.pos.y:= y; + rect1.cy:= cy; + if not (edg_top in hiddenedges) then begin + inc(rect1.pos.y,awidth); + dec(rect1.cy,awidth); + end; + if not (edg_bottom in hiddenedges) then begin + dec(rect1.cy,awidth); + end; + rect1.cx:= awidth; + if not (edg_left in hiddenedges) then begin + gdi(gdf_fillrect); //left + end; + rect1.pos.x:= x + cx - awidth; + if not (edg_right in hiddenedges) then begin + gdi(gdf_fillrect); //right + end; + end; + end; + end; + end; + end; +end; + +procedure tcanvas.drawframe(const arect: rectty; awidth: framety; + const acolor: colorty = cl_default; + const hiddenedges: edgesty = []); +var + rect1,rect2: rectty; +begin + if cs_inactive in fstate then exit; + if ispaintcolor(acolor) then begin + rect2:= arect; + if checkforeground(acolor,false) then begin + with fdrawinfo.rect do begin + rect:= @rect1; + with rect2 do begin + rect1.pos:= pos; + rect1.cx:= cx; + rect1.cy:= awidth.top; + if (rect1.cx > 0) and (rect1.cy > 0) then begin + gdi(gdf_fillrect); //top + end; + rect1.pos.y:= y + cy - awidth.bottom; + rect1.cy:= awidth.bottom; + if (rect1.cx > 0) and (rect1.cy > 0) then begin + gdi(gdf_fillrect); //bottom + end; + rect1.pos.y:= y; + rect1.cy:= cy; + inc(rect1.pos.y,awidth.top); + dec(rect1.cy,awidth.top); + dec(rect1.cy,awidth.bottom); + rect1.cx:= awidth.left; + if (rect1.cx > 0) and (rect1.cy > 0) then begin + gdi(gdf_fillrect); //left + end; + rect1.pos.x:= x + cx - awidth.right; + rect1.cx:= awidth.right; + if (rect1.cx > 0) and (rect1.cy > 0) then begin + gdi(gdf_fillrect); //right + end; + end; + end; + end; + end; +end; + +procedure tcanvas.drawxorframe(const arect: rectty; const awidth: integer = -1; + const abrush: tsimplebitmap = nil); +var + rasteropbefore: rasteropty; + brushbefore: tsimplebitmap; + brushoriginbefore: pointty; + int1: integer; +begin + if cs_inactive in fstate then exit; + int1:= -awidth*2; + if (abs(arect.cx) < int1) or (abs(arect.cy) < int1) then begin + fillxorrect(arect,abrush); //avoid xor overlap + end + else begin + rasteropbefore:= rasterop; + rasterop:= rop_xor; + if abrush = nil then begin + drawframe(arect,awidth,cl_white); + end + else begin + brushbefore:= brush; + brushoriginbefore:= brushorigin; + brushorigin:= nullpoint; + brush:= abrush; + drawframe(arect,awidth,cl_brush); + brush:= brushbefore; + brushorigin:= brushoriginbefore; + end; + rasterop:= rasteropbefore; + end; +end; + +procedure tcanvas.drawxorframe(const po1, po2: pointty; const awidth: integer = -1; + const abrush: tsimplebitmap = nil); +begin + if cs_inactive in fstate then exit; + drawxorframe(makerect(po1,makesize(po2.x-po1.x,po2.y-po1.y)),awidth,abrush); +end; + +procedure tcanvas.fillxorrect(const arect: rectty; + const abrush: tsimplebitmap = nil); +var + rasteropbefore: rasteropty; + brushbefore: tsimplebitmap; + brushoriginbefore: pointty; +begin + if cs_inactive in fstate then exit; + rasteropbefore:= rasterop; + rasterop:= rop_xor; + if abrush = nil then begin + fillrect(arect,cl_white); + end + else begin + brushbefore:= brush; + brushoriginbefore:= brushorigin; + brushorigin:= nullpoint; + brush:= abrush; + fillrect(arect,cl_brush); + brush:= brushbefore; + brushorigin:= brushoriginbefore; + end; + rasterop:= rasteropbefore; +end; + +procedure tcanvas.fillxorrect(const start: pointty; const length: integer; + const direction: graphicdirectionty; + const awidth: integer = 0; + const abrush: tsimplebitmap = nil); +var + rect1: rectty; +begin + case direction of + gd_left: begin + rect1.x:= start.x - length; + rect1.y:= start.y - awidth div 2; + rect1.cx:= length; + rect1.cy:= awidth; + end; + gd_down: begin + rect1.y:= start.y; + rect1.x:= start.x - awidth div 2; + rect1.cy:= length; + rect1.cx:= awidth; + end; + gd_up: begin + rect1.y:= start.y - length; + rect1.x:= start.x - awidth div 2; + rect1.cy:= length; + rect1.cx:= awidth; + end; + else begin //gd_right + rect1.x:= start.x; + rect1.y:= start.y - awidth div 2; + rect1.cx:= length; + rect1.cy:= awidth; + end; + end; + fillxorrect(rect1,abrush); +end; + + +// +// region helpers +// + +function tcanvas.createregion: regionty; +begin + fdrawinfo.gc.gdifuncs^[gdf_createemptyregion](fdrawinfo); + result:= fdrawinfo.regionoperation.dest; +end; + +function tcanvas.createregion(const asource: regionty): regionty; +begin + with fdrawinfo.regionoperation do begin + source:= asource; + fdrawinfo.gc.gdifuncs^[gdf_copyregion](fdrawinfo); + result:= dest; + end; +end; + +function tcanvas.createregion(const arect: rectty): regionty; +begin + with fvaluepo^,fdrawinfo.regionoperation do begin + rect:= arect; + inc(rect.x,origin.x); + inc(rect.y,origin.y); + fdrawinfo.gc.gdifuncs^[gdf_createrectregion](fdrawinfo); + result:= dest; + end; +end; + +function tcanvas.createregion(const rects: array of rectty): regionty; +begin + result:= 0; + with fdrawinfo.regionoperation do begin + rectscount:= high(rects) + 1; + if rectscount > 0 then begin + rectspo:= @rects[0]; + adjustrectar(@rects[0],rectscount); + fdrawinfo.gc.gdifuncs^[gdf_createrectsregion](fdrawinfo); + result:= dest; + readjustrectar(@rects[0],rectscount); + end + else begin + result:= createregion; + end; + end; +end; + +function tcanvas.createregion(frame: rectty; const inflate: integer): regionty; + //frame +var + reg1: regionty; +begin + with fvaluepo^ do begin + inc(frame.x,origin.x); + inc(frame.y,origin.y); + end; + if inflate > 0 then begin + result:= createregion(inflaterect(frame,inflate)); + reg1:= createregion(frame); + end + else begin + result:= createregion(frame); + reg1:= createregion(inflaterect(frame,inflate)); + end; + regsubregion(result,reg1); + destroyregion(reg1); +end; + +procedure tcanvas.destroyregion(region: regionty); +begin + with fdrawinfo.regionoperation do begin + source:= region; + fdrawinfo.gc.gdifuncs^[gdf_destroyregion](fdrawinfo); + end; +end; + +procedure tcanvas.regmove(const adest: regionty; const dist: pointty); +begin + with fdrawinfo.regionoperation do begin + dest:= adest; + rect.pos:= dist; + end; + fdrawinfo.gc.gdifuncs^[gdf_moveregion](fdrawinfo); +end; + +procedure tcanvas.regremove(const adest: regionty; const dist: pointty); +begin + regmove(adest,makepoint(-dist.x,-dist.y)); +end; + +procedure tcanvas.initregrect(const adest: regionty; const arect: rectty); +begin + with fdrawinfo,regionoperation do begin + dest:= adest; + rect:= arect; + inc(rect.x,fvaluepo^.origin.x); + dec(rect.x,gc.cliporigin.x); + inc(rect.y,fvaluepo^.origin.y); + dec(rect.y,gc.cliporigin.y); + if rect.x < -$8000 then begin + rect.x:= -$8000; + end; + if rect.x > $7fff then begin + rect.x:= $7fff; + end; + if rect.cx < 0 then begin + rect.cx:= 0; + end; + if rect.cx + rect.x > $7fff then begin + rect.cx:= $7fff - rect.x + end; + if rect.y < -$8000 then begin + rect.y:= -$8000; + end; + if rect.y > $7fff then begin + rect.y:= $7fff; + end; + if rect.cy < 0 then begin + rect.cy:= 0; + end; + if rect.cy + rect.y > $7fff then begin + rect.cy:= $7fff - rect.y; + end; + end; +end; + +procedure tcanvas.initregreg(const adest: regionty; const asource: regionty); +begin + with fdrawinfo,regionoperation do begin + dest:= adest; + source:= asource; + end; +end; + +procedure tcanvas.regsubrect(const dest: regionty; const rect: rectty); +begin + initregrect(dest,rect); + fdrawinfo.gc.gdifuncs^[gdf_regsubrect](fdrawinfo); +end; + +procedure tcanvas.regaddrect(const dest: regionty; const rect: rectty); +begin + initregrect(dest,rect); + fdrawinfo.gc.gdifuncs^[gdf_regaddrect](fdrawinfo); +end; + +procedure tcanvas.regintersectrect(const dest: regionty; const rect: rectty); +begin + initregrect(dest,rect); + fdrawinfo.gc.gdifuncs^[gdf_regintersectrect](fdrawinfo); +end; + +procedure tcanvas.regaddregion(const dest: regionty; const region: regionty); +begin + initregreg(dest,region); + fdrawinfo.gc.gdifuncs^[gdf_regaddregion](fdrawinfo); +end; + +procedure tcanvas.regsubregion(const dest: regionty; const region: regionty); +begin + initregreg(dest,region); + fdrawinfo.gc.gdifuncs^[gdf_regsubregion](fdrawinfo); +end; + +procedure tcanvas.regintersectregion(const dest: regionty; const region: regionty); +begin + initregreg(dest,region); + fdrawinfo.gc.gdifuncs^[gdf_regintersectregion](fdrawinfo); +end; + +function tcanvas.regionisempty(const region: regionty): boolean; +begin + with fdrawinfo.regionoperation do begin + source:= region; + fdrawinfo.gc.gdifuncs^[gdf_regionisempty](fdrawinfo); + result:= dest <> 0; + end; +end; + +function tcanvas.regionclipbox(const region: regionty): rectty; +begin + if region <> 0 then begin + with fdrawinfo.regionoperation do begin + source:= region; + fdrawinfo.gc.gdifuncs^[gdf_regionclipbox](fdrawinfo); + result:= rect; + end; + end + else begin + result:= nullrect; + end; +end; + +// +// clip region functions +// + +procedure tcanvas.setclipregion(const Value: regionty); +begin + with fvaluepo^ do begin + if cs_regioncopy in changed then begin + destroyregion(clipregion); + end; + include(changed,cs_regioncopy); + clipregion := Value; + valuechanged(cs_clipregion); + end; +end; + +procedure tcanvas.subcliprect(const rect: rectty); +begin + checkregionstate; + regsubrect(fvaluepo^.clipregion,rect); +end; + +procedure tcanvas.subclipframe(const frame: rectty; inflate: integer); +var + reg1: regionty; +begin + checkregionstate; + reg1:= createregion(frame,inflate); + regsubregion(fvaluepo^.clipregion,reg1); + destroyregion(reg1); +end; + +procedure tcanvas.subclipregion(const region: regionty); +begin + checkregionstate; + regsubregion(fvaluepo^.clipregion,region); +end; + +procedure tcanvas.addcliprect(const rect: rectty); +begin + checkregionstate; + regaddrect(fvaluepo^.clipregion,rect); +end; + +procedure tcanvas.setcliprect(const rect: rectty); +begin + clipregion:= createregion(removerect(rect,fcliporigin)); +end; + +procedure tcanvas.addclipframe(const frame: rectty; inflate: integer); +var + reg1: regionty; +begin + checkregionstate; + reg1:= createregion(frame,inflate); + regaddregion(fvaluepo^.clipregion,reg1); + destroyregion(reg1); +end; + +procedure tcanvas.addclipregion(const region: regionty); +begin + checkregionstate; + regaddregion(fvaluepo^.clipregion,region); +end; + +procedure tcanvas.intersectcliprect(const rect: rectty); +begin + checkregionstate; + regintersectrect(fvaluepo^.clipregion,rect); +end; + +procedure tcanvas.intersectclipframe(const frame: rectty; inflate: integer); +var + reg1: regionty; +begin + checkregionstate; + reg1:= createregion(frame,inflate); + regintersectregion(fvaluepo^.clipregion,reg1); + destroyregion(reg1); +end; + +procedure tcanvas.intersectclipregion(const region: regionty); +begin + checkregionstate; + regintersectregion(fvaluepo^.clipregion,region); +end; + +procedure tcanvas.resetclipregion; +begin + clipregion:= 0; +end; + +function tcanvas.copyclipregion: regionty; +begin + with fdrawinfo.regionoperation do begin + source:= fvaluepo^.clipregion; + fdrawinfo.gc.gdifuncs^[gdf_copyregion](fdrawinfo); + result:= dest; + end; +end; + +// +// +// + +procedure tcanvas.adjustrectar(po: prectty; count: integer); +var + dx,dy: integer; +begin + dx:= fvaluepo^.origin.x; + dy:= fvaluepo^.origin.y; + if (dx <> 0) or (dy <> 0 ) then begin + while count > 0 do begin + inc(po^.x,dx); + inc(po^.y,dy); + inc(po); + dec(count); + end; + end; +end; + +procedure tcanvas.readjustrectar(po: prectty; count: integer); +var + dx,dy: integer; +begin + dx:= fvaluepo^.origin.x; + dy:= fvaluepo^.origin.y; + if (dx <> 0) or (dy <> 0 ) then begin + while count > 0 do begin + dec(po^.x,dx); + dec(po^.y,dy); + inc(po); + dec(count); + end; + end; +end; + +function tcanvas.getcolor: colorty; +begin + result:= fvaluepo^.color; +end; + +procedure tcanvas.setcolor(const value: colorty); +begin + if fvaluepo^.color <> value then begin + fvaluepo^.color:= value; + valuechanged(cs_color); + end; +end; + +function tcanvas.getcolorbackground: colorty; +begin + result:= fvaluepo^.colorbackground; +end; + +procedure tcanvas.setcolorbackground(const Value: colorty); +begin + if fvaluepo^.colorbackground <> value then begin + fvaluepo^.colorbackground:= value; + valuechanged(cs_colorbackground); + end; +end; + +function tcanvas.getrasterop: rasteropty; +begin + result:= fvaluepo^.rasterop; +end; + +procedure tcanvas.setrasterop(const Value: rasteropty); +begin + if fvaluepo^.rasterop <> value then begin + fvaluepo^.rasterop:= value; + valuechanged(cs_rasterop); + end; +end; + +function tcanvas.getlinewidth: integer; +begin + result:= (fvaluepo^.lineinfo.width + linewidthroundvalue) shr linewidthshift; +end; + +procedure tcanvas.setlinewidth(Value: integer); +begin + value:= value shl linewidthshift; + if fvaluepo^.lineinfo.width <> value then begin + fvaluepo^.lineinfo.width:= value; + valuechanged(cs_linewidth); + end; +end; + +function tcanvas.getlinewidthmm: real; +begin + result:= fvaluepo^.lineinfo.width / + (fdrawinfo.gc.ppmm * (1 shl linewidthshift)); +end; + +procedure tcanvas.setlinewidthmm(const avalue: real); +var + int1: integer; +begin + int1:= round(avalue * (1 shl linewidthshift) * fdrawinfo.gc.ppmm); + if fvaluepo^.lineinfo.width <> int1 then begin + fvaluepo^.lineinfo.width:= int1; + valuechanged(cs_linewidth); + end; +end; + +function tcanvas.getdashes: dashesstringty; +begin + result:= fvaluepo^.lineinfo.dashes; +end; + +procedure tcanvas.setdashes(const Value: dashesstringty); +var + int1: integer; +begin + with fvaluepo^.lineinfo do begin + dashes:= value; + for int1:= 1 to length(dashes) do begin + if dashes[int1] = #0 then begin + setlength(dashes,int1-1); + break; + end; + end; + if odd(length(dashes)) then begin + setlength(dashes,length(dashes)-1); + end; + end; + valuechanged(cs_dashes); +end; + +function tcanvas.getcapstyle: capstylety; +begin + result:= fvaluepo^.lineinfo.capstyle; +end; + +procedure tcanvas.setcapstyle(const Value: capstylety); +begin + fvaluepo^.lineinfo.capstyle:= value; + valuechanged(cs_capstyle); +end; + +function tcanvas.getjoinstyle: joinstylety; +begin + result:= fvaluepo^.lineinfo.joinstyle; +end; + +function tcanvas.getoptions: canvasoptionsty; +begin + result:= fvaluepo^.options; +end; + +procedure tcanvas.setjoinstyle(const Value: joinstylety); +begin + fvaluepo^.lineinfo.joinstyle:= value; + valuechanged(cs_joinstyle); +end; + +procedure tcanvas.setoptions(const avalue: canvasoptionsty); +begin + fvaluepo^.options:= avalue; + valuechanged(cs_options); +end; + +function tcanvas.defaultcliprect: rectty; +begin + result:= makerect(nullpoint,fdrawinfo.gc.paintdevicesize); +end; + +procedure tcanvas.checkregionstate; +begin + with fvaluepo^ do begin + if clipregion = 0 then begin + checkgcstate([cs_gc]); //fsize must be valid + clipregion:= createregion(defaultcliprect); + end + else begin + if not (cs_regioncopy in changed) then begin + clipregion:= createregion(clipregion); + end; + end; + include(changed,cs_regioncopy); + include(changed,cs_clipregion); + end; + exclude(fstate,cs_clipregion); +end; + +procedure tcanvas.move(const dist: pointty); +begin + if (dist.x <> 0) or (dist.y <> 0) then begin + with fvaluepo^ do begin + inc(origin.x,dist.x); + inc(origin.y,dist.y); + end; + valuechanged(cs_origin); + end; +end; + +procedure tcanvas.remove(const dist: pointty); +begin + with fvaluepo^ do begin + dec(origin.x,dist.x); + dec(origin.y,dist.y); + end; + valuechanged(cs_origin); +end; + +function tcanvas.getorigin: pointty; +begin + result:= subpoint(fvaluepo^.origin,fdrawinfo.gc.cliporigin); +end; + +procedure tcanvas.setorigin(const Value: pointty); +var + po1: pointty; +begin + po1:= addpoint(value,fdrawinfo.gc.cliporigin); + if not pointisequal(fvaluepo^.origin,po1) then begin + fvaluepo^.origin:= po1; + valuechanged(cs_origin); + end; +end; + +function tcanvas.clipregionisempty: boolean; +begin + with fvaluepo^ do begin + if clipregion = 0 then begin + result:= false; + end + else begin + result:= regionisempty(clipregion); + end; + end; +end; + +function tcanvas.clipbox: rectty; +begin + with fvaluepo^ do begin + if clipregion = 0 then begin + result:= makerect(makepoint(-origin.x,-origin.y),icanvas(fintf).getsize); + end + else begin + result:= regionclipbox(clipregion); + dec(result.x,origin.x); + inc(result.x,fdrawinfo.gc.cliporigin.x); + dec(result.y,origin.y); + inc(result.y,fdrawinfo.gc.cliporigin.y); + end; + end; +end; + +{ +procedure tcanvas.drawedge(const vector: graphicvectorty; level: integer; + const colorinfo: framecolorinfoty); +//procedure paintkante2(painter: qpainterh; const startpoint: tpoint; +// length: integer; direction: tgraphicdirection; +// width: integer; const color: qcolorh; +// glanz: integer = 0; const colorglanz: qcolorh = nil; +// infos: kanteninfosty = []); + //glanz < 0 -> am schluss bei dark +var + points: tpointarray; + breite1,breite2: integer; + step1a,step2a,step3a: integer; + step1b,step2b,step3b: integer; + reverseoffset: integer; + +begin + if length <= 0 then begin + exit; + end; + if not (kin_dark in infos) then begin + glanz:= -glanz; + end; + setlength(points,8); + points[0]:= startpoint; + if glanz <= 0 then begin //glanz am schluss + breite1:= width+glanz; + qpainter_setpen(painter,color); + qpainter_setbrush(painter,color); + end + else begin //glanz zu beginn + breite1:= glanz; + qpainter_setpen(painter,colorglanz); + qpainter_setbrush(painter,colorglanz); + end; + if breite1 > width then begin + breite1:= width; + end; + if breite1 < 0 then begin + breite1:= 0; + end; + reverseoffset:= 2*width; + dec(length); + dec(width); + dec(breite1); + breite2:= width-breite1-1; + if kin_reverseend in infos then begin + step1a:= -breite1; + step2a:= -1; + step3a:= -width; + length:= length-reverseoffset; + end + else begin + step1a:= breite1; + step2a:= 1; + step3a:= width; + end; + if kin_reversestart in infos then begin + step1b:= -breite1+reverseoffset; + step2b:= -1; + step3b:= -width+reverseoffset; + end + else begin + reverseoffset:= 0; + step1b:= breite1; + step2b:= 1; + step3b:= width; + end; + case direction of + gd_right: begin + points[0].X:= startpoint.X + reverseoffset; + points[1].x:= startpoint.X + length; + points[1].Y:= startpoint.Y; + points[2].X:= points[1].X - step1a; + points[2].Y:= startpoint.Y + breite1; + points[3].x:= startpoint.x + step1b; + points[3].Y:= points[2].Y; + if breite2 >= 0 then begin + points[4].X:= points[3].X + step2b; + points[4].Y:= points[3].Y + 1; + points[5].X:= points[2].X - step2a; + points[5].y:= points[2].y + 1; + points[6].X:= points[1].X - step3a; + points[6].Y:= startpoint.Y + width; + points[7].x:= startpoint.x + step3b; + points[7].Y:= points[6].Y; + end; + end; + gd_up: begin + points[0].y:= startpoint.y - reverseoffset; + points[1].x:= startpoint.X; + points[1].Y:= startpoint.Y-length; + points[2].X:= startpoint.X + breite1; + points[2].Y:= points[1].Y + step1a; + points[3].x:= points[2].x; + points[3].Y:= startpoint.Y - step1b; + if breite2 >= 0 then begin + points[4].X:= points[3].X + 1; + points[4].Y:= points[3].Y - step2b; + points[5].X:= points[2].X + 1; + points[5].y:= points[2].y + step2a; + points[6].X:= startpoint.x + width; + points[6].Y:= points[1].Y + step3a; + points[7].x:= points[6].x; + points[7].Y:= startpoint.y - step3b; + end; + end; + gd_left: begin + points[0].X:= startpoint.X - reverseoffset; + points[1].x:= startpoint.X - length; + points[1].Y:= startpoint.Y; + points[2].X:= points[1].X + step1a; + points[2].Y:= startpoint.Y - breite1; + points[3].x:= startpoint.x - step1b; + points[3].Y:= points[2].Y; + if breite2 >= 0 then begin + points[4].X:= points[3].X - step2b; + points[4].Y:= points[3].Y - 1; + points[5].X:= points[2].X + step2a; + points[5].y:= points[2].y - 1; + points[6].X:= points[1].X + step3a; + points[6].Y:= startpoint.Y - width; + points[7].x:= startpoint.x - step3b; + points[7].Y:= points[6].Y; + end; + end; + gd_down: begin + points[0].y:= startpoint.y + reverseoffset; + points[1].x:= startpoint.X; + points[1].Y:= startpoint.Y+length; + points[2].X:= startpoint.X - breite1; + points[2].Y:= points[1].Y - step1a; + points[3].x:= points[2].x; + points[3].Y:= startpoint.Y + step1b; + if breite2 >= 0 then begin + points[4].X:= points[3].X - 1; + points[4].Y:= points[3].Y + step2b; + points[5].X:= points[2].X - 1; + points[5].y:= points[2].y - step2a; + points[6].X:= startpoint.x - width; + points[6].Y:= points[1].Y - step3a; + points[7].x:= points[6].x; + points[7].Y:= startpoint.y + step3b; + end; + end; + end; + if breite1 >= 0 then begin + if breite1 > 1 then begin + qpainter_drawpolygon(painter,@points[0],false,0,4); + end + else begin + qpainter_moveto(painter,@points[0]); + qpainter_lineto(painter,@points[1]); + if breite1 = 1 then begin + qpainter_moveto(painter,@points[2]); + qpainter_lineto(painter,@points[3]); + end; + end; + end; + if breite2 >= 0 then begin + if glanz < 0 then begin + qpainter_setpen(painter,colorglanz); + qpainter_setbrush(painter,colorglanz); + end + else begin + qpainter_setpen(painter,color); + qpainter_setbrush(painter,color); + end; + if breite2 > 1 then begin + qpainter_drawpolygon(painter,@points[0],false,4,4); + end + else begin + qpainter_moveto(painter,@points[4]); + qpainter_lineto(painter,@points[5]); + if breite2 = 1 then begin + qpainter_moveto(painter,@points[6]); + qpainter_lineto(painter,@points[7]); + end; + end; + end; +end; +} +{ +procedure tcanvas.drawedge(const vector: graphicvectorty; level: integer; + const colorinfo: framecolorinfoty); +var + poly: pointarty; + + procedure shrink(value: integer); + begin + case vector.direction of + gd_right: begin + poly[2].x:= poly[1].x - value; + poly[2].y:= poly[1].y - value; + poly[3].x:= poly[0].x + value; + poly[3].y:= poly[0].y - value; + end; + gd_up: begin + poly[2].x:= poly[1].x - value; + poly[2].y:= poly[1].y + value; + poly[3].x:= poly[0].x - value; + poly[3].y:= poly[0].y - value; + end; + gd_left: begin + poly[2].x:= poly[1].x - value; + poly[2].y:= poly[1].y + value; + poly[3].x:= poly[0].x + value; + poly[3].y:= poly[0].y + value; + end; + gd_down: begin + poly[2].x:= poly[1].x + value; + poly[2].y:= poly[1].y + value; + poly[3].x:= poly[0].x + value; + poly[3].y:= poly[0].y - value; + end; + end; + end; + + procedure offset; + begin + case vector.direction of + gd_right: begin + inc(poly[0].x); + dec(poly[0].y); + dec(poly[1].x); + dec(poly[1].y); + end; + gd_up: begin + dec(poly[0].x); + dec(poly[0].y); + dec(poly[1].x); + inc(poly[1].y); + end; + gd_left: begin + inc(poly[0].x); + inc(poly[0].y); + dec(poly[1].x); + inc(poly[1].y); + end; + gd_down: begin + inc(poly[0].x); + dec(poly[0].y); + inc(poly[1].x); + inc(poly[1].y); + end; + end; + end; + + procedure draw(with1,with2: integer; col1,col2: colorty); + begin + if with1 > 0 then begin + if with1 = 1 then begin + drawlines(poly,col1,2); + end + else begin + shrink(with1); + fillpolygon(poly,col1); + poly[0]:= poly[3]; + poly[1]:= poly[2]; + end; + end; + if with2 > 0 then begin + offset; + if with2 = 1 then begin + drawlines(poly,col2,2); + end + else begin + shrink(with2); + fillpolygon(poly,col2); + end; + end; + end; + +var + topleft,inlight,effectfirst: boolean; + effcol,normcol: colorty; + effwidth: integer; + +begin + if level = 0 then begin + exit; + end; + with colorinfo do begin + topleft:= vector.direction in [gd_left,gd_down]; + inlight:= topleft; + if level < 0 then begin + level:= -level; + inlight:= not inlight; + end; + if inlight then begin + normcol:= collight; + effcol:= colhighlight; + effwidth:= highlight; + end + else begin + normcol:= colshadow; + effcol:= coldkshadow; + effwidth:= dkshadow; + end; + if effwidth < 0 then begin + effwidth:= -effwidth; + effectfirst:= topleft; + end + else begin + effectfirst:= false; + end; + if effwidth > level then begin + effwidth:= level; + level:= 0; + end + else begin + level:= level - effwidth; + end; + if not inlight then begin + if (level = 0) then begin + level:= effwidth; + effwidth:= 0; + end; + end; + end; + setlength(poly,4); + vectortoline(vector,poly[0],poly[1]); + poly[0]:= vector.start; + if effectfirst then begin + draw(effwidth,level,effcol,normcol); + end + else begin + draw(level,effwidth,normcol,effcol); + end; +end; +} +function tcanvas.getbrush: tsimplebitmap; +begin + result:= fvaluepo^.brush; +end; + +procedure tcanvas.setbrush(const Value: tsimplebitmap); +begin + if fvaluepo^.brush <> value then begin + fvaluepo^.brush:= value; + valuechanged(cs_brush); + gccolorforeground:= cl_none; //force reload + end; +end; + +procedure tcanvas.resetpaintedflag; +begin + exclude(fstate,cs_painted); +end; + +function tcanvas.getbrushorigin: pointty; +begin + result.x:= fvaluepo^.brushorigin.x-fvaluepo^.origin.x; + result.y:= fvaluepo^.brushorigin.y-fvaluepo^.origin.y; +end; + +procedure tcanvas.setbrushorigin(const Value: pointty); +begin + fvaluepo^.brushorigin.x:= value.x+fvaluepo^.origin.x; + fvaluepo^.brushorigin.y:= value.y+fvaluepo^.origin.y; + valuechanged(cs_brushorigin); +end; + +function tcanvas.getrootbrushorigin: pointty; +begin + result.x:= fvaluepo^.brushorigin.x-fcliporigin.x; + result.y:= fvaluepo^.brushorigin.y-fcliporigin.y; +end; + +procedure tcanvas.setrootbrushorigin(const Value: pointty); +begin + fvaluepo^.brushorigin.x:= value.x+fcliporigin.x; + fvaluepo^.brushorigin.y:= value.y+fcliporigin.y; + valuechanged(cs_brushorigin); +end; + +procedure tcanvas.adjustbrushorigin(const arect: rectty; + const alignment: alignmentsty); +var + siz1: sizety; + pt1: pointty; +begin + if fvaluepo^.brush <> nil then begin + siz1:= fvaluepo^.brush.size; + end + else begin + siz1:= nullsize; + end; + pt1.x:= -fvaluepo^.origin.x; + pt1.y:= -fvaluepo^.origin.y; + if al_left in alignment then begin + pt1.x:= arect.x; + end + else begin + if al_xcentered in alignment then begin + pt1.x:= arect.x + (arect.cx - siz1.cx) div 2; + end + else begin + if al_right in alignment then begin + pt1.x:= arect.x + arect.cx - siz1.cx; + end; + end; + end; + if al_top in alignment then begin + pt1.y:= arect.y; + end + else begin + if al_ycentered in alignment then begin + pt1.y:= arect.y + (arect.cy - siz1.cy) div 2; + end + else begin + if al_bottom in alignment then begin + pt1.y:= arect.y + arect.cy - siz1.cy; + end; + end; + end; + brushorigin:= pt1; +end; + +function tcanvas.active: boolean; +begin + result:= fdrawinfo.gc.handle <> 0; +end; + +procedure tcanvas.updatecliporigin(const Value: pointty); +var + delta: pointty; + int1: integer; +begin + delta:= subpoint(value,fcliporigin); + fcliporigin:= value; + fdrawinfo.gc.cliporigin:= value; + with fvaluestack do begin + for int1:= 0 to count-1 do begin + addpoint1(stack[int1].origin,delta); + end; + end; + addpoint1(fdrawinfo.origin,delta); +end; + +procedure tcanvas.setcliporigin(const Value: pointty); +begin + checkgcstate([cs_gc]); + updatecliporigin(value); + gdi(gdf_setcliporigin); +end; + +procedure tcanvas.setppmm(avalue: real); +begin + if avalue < 0.1 then begin + avalue:= 0.1; + end; + fdrawinfo.gc.ppmm:= avalue; +end; + +procedure tcanvas.internaldrawtext(var info); +begin + gdierror(gde_notimplemented); +end; + +procedure tcanvas.initflags(const dest: tcanvas); +begin + with dest do begin + exclude(fdrawinfo.gc.drawingflags,df_highresfont); + ffont.releasehandles; + gcfonthandle1:= 0; //invalid + end; +end; + +function tcanvas.highresdevice: boolean; +begin + result:= cs_highresdevice in fstate; +end; + +function tcanvas.getkind: bitmapkindty; +begin + result:= icanvas(fintf).getkind; +end; + +function tcanvas.getcontextinfopo: pointer; +begin + result:= nil; //dummy +end; + +function tcanvas.getcanvasimage(const abgr: boolean = false): imagety; + //todo: handle monochrome and mask +var + int1: integer; +begin + fillchar(fdrawinfo.getimage,sizeof(fdrawinfo.getimage),0); + with fdrawinfo,getimage do begin + if gc.handle <> 0 then begin + image.image.bgr:= abgr; + int1:= gc.paintdevicesize.cx * gc.paintdevicesize.cy; + if int1 > 0 then begin + allocimage(image.image,gc.paintdevicesize,bmk_rgb); + with image.image do begin +// pixels:= gui_allocimagemem(int1); + if pixels <> nil then begin +// size:= gc.paintdevicesize; +// length:= int1; + error:= gde_notimplemented; + gdi(gdf_getimage); + end; + end; + end; + end; + checkimagebgr(image.image,abgr); + result:= image.image; + end; +end; + +procedure tcanvas.endpaint; +begin + if fdrawinfo.gc.handle <> 0 then begin + gdi(gdf_endpaint); + end; +end; + +procedure tcanvas.updatewindowoptions(var aoptions: internalwindowoptionsty); +begin + //dummy +end; + +procedure tcanvas.updatesize(const asize: sizety); +begin + fdrawinfo.gc.paintdevicesize:= asize; +end; + +procedure tcanvas.movewindowrect(const adist: pointty; const arect: rectty); +begin + checkgcstate([cs_gc]); + with fdrawinfo.moverect do begin + dist:= @adist; + rect:= @arect; + gdi(gdf_movewindowrect); + end; +end; + +procedure tcanvas.fitppmm(const asize: sizety); +begin + with getfitrect do begin + if (asize.cx <> 0) and (asize.cy <> 0) and + (size.cx <> 0) and (size.cy <> 0) then begin + if asize.cx/asize.cy > size.cx/size.cy then begin + self.ppmm:= ppmm * asize.cx/size.cx; + end + else begin + self.ppmm:= ppmm * asize.cy/size.cy; + end; + end; + end; +end; + +function tcanvas.getfitrect: rectty; +begin + result.pos:= nullpoint; + checkgcstate([cs_gc]); + result.size:= fdrawinfo.gc.paintdevicesize; +end; + +procedure tcanvas.beforeread; +begin + reset; +end; + +procedure tcanvas.afterread; +begin + fvaluestack.stack[0]:= fvaluestack.stack[1]; //streamed values are default + fstate:= fstate - changedmask; +end; + +procedure tcanvas.readlineoptions(reader: treader); +var + liopt1: lineoptionsty; +begin + liopt1:= lineoptionsty(reader.readset(typeinfo(lineoptionsty))); + if lio_antialias in liopt1 then begin + options:= options + [cao_smooth]; + end; +end; + +procedure tcanvas.defineproperties(filer: tfiler); +begin + filer.defineproperty('lineoptions',@readlineoptions,nil,false); +end; + +function tcanvas.getsmooth: boolean; +begin + result:= cao_smooth in fvaluepo^.options; +end; + +procedure tcanvas.setsmooth(const avalue: boolean); +begin + if avalue <> (cao_smooth in fvaluepo^.options) then begin + if avalue then begin + options:= fvaluepo^.options + [cao_smooth]; + end + else begin + options:= fvaluepo^.options - [cao_smooth]; + end; + end; +end; + +function tcanvas.size: sizety; +begin + result:= getfitrect().size; +end; + +{ tfontcomp } + +function tfontcomp.gettemplate: tfonttemplate; +begin + result:= tfonttemplate(ftemplate); +end; + +procedure tfontcomp.settemplate(const avalue: tfonttemplate); +begin + ftemplate.assign(avalue); +end; + +function tfontcomp.gettemplateclass: templateclassty; +begin + result:= tfonttemplate; +end; + +{ tfonttemplate } + +constructor tfonttemplate.create(const owner: tmsecomponent; + const onchange: notifyeventty); +begin + initfontinfo(fi); + inherited; +end; + +procedure tfonttemplate.setcolor(const avalue: colorty); +begin + fi.color:= avalue; + changed(); +end; + +procedure tfonttemplate.setcolorbackground(const avalue: colorty); +begin + fi.colorbackground:= avalue; + changed(); +end; + +procedure tfonttemplate.setcolorselect(const avalue: colorty); +begin + fi.colorselect:= avalue; + changed(); +end; + +procedure tfonttemplate.setcolorselectbackground(const avalue: colorty); +begin + fi.colorselectbackground:= avalue; + changed(); +end; + +procedure tfonttemplate.setshadow_color(const avalue: colorty); +begin + fi.shadow_color:= avalue; + changed(); +end; + +procedure tfonttemplate.setshadow_shiftx(const avalue: integer); +begin + fi.shadow_shiftx:= avalue; + changed(); +end; + +procedure tfonttemplate.setshadow_shifty(const avalue: integer); +begin + fi.shadow_shifty:= avalue; + changed(); +end; + +procedure tfonttemplate.setgloss_color(const avalue: colorty); +begin + fi.gloss_color:= avalue; + changed(); +end; + +procedure tfonttemplate.setgloss_shiftx(const avalue: integer); +begin + fi.gloss_shiftx:= avalue; + changed(); +end; + +procedure tfonttemplate.setgloss_shifty(const avalue: integer); +begin + fi.gloss_shifty:= avalue; + changed(); +end; + +procedure tfonttemplate.setgrayed_color(const avalue: colorty); +begin + fi.grayed_color:= avalue; + changed(); +end; + +procedure tfonttemplate.setgrayed_colorshadow(const avalue: colorty); +begin + fi.grayed_colorshadow:= avalue; + changed(); +end; + +procedure tfonttemplate.setgrayed_shiftx(const avalue: integer); +begin + fi.grayed_shiftx:= avalue; + changed(); +end; + +procedure tfonttemplate.setgrayed_shifty(const avalue: integer); +begin + fi.grayed_shifty:= avalue; + changed(); +end; + +procedure tfonttemplate.setstyle(const avalue: fontstylesty); +begin + fi.style:= avalue; + changed(); +end; + +procedure tfonttemplate.setxscale(const avalue: real); +begin + fi.xscale:= avalue; + changed(); +end; + +procedure tfonttemplate.doassignto(dest: tpersistent); +begin + if dest is tfont then begin + with tfont(dest) do begin + settemplateinfo(self.fi); + end; + end; +end; + +function tfonttemplate.getinfosize: integer; +begin + result:= sizeof(fi); +end; + +function tfonttemplate.getinfoad: pointer; +begin + result:= @fi; +end; + +procedure tfonttemplate.setheight(const avalue: integer); +begin + fi.height:= avalue; + changed(); +end; + +procedure tfonttemplate.setwidth(const avalue: integer); +begin + fi.width:= avalue; + changed(); +end; + +procedure tfonttemplate.setextraspace(const avalue: integer); +begin + fi.extraspace:= avalue; + changed(); +end; + +procedure tfonttemplate.setname(const avalue: string); +begin + fi.name:= avalue; + changed(); +end; + +procedure tfonttemplate.setcharset(const avalue: string); +begin + fi.charset:= avalue; + changed(); +end; + +procedure tfonttemplate.setoptions(const avalue: fontoptionsty); +begin + fi.options:= avalue; + changed(); +end; + +initialization +{$ifdef mse_flushgdi} + flushgdi:= true; +{$endif} +// setlength(gdifuncs,1); //item 0 = system default +// gdifuncs[0]:= gui_getgdifuncs; +finalization + deinit; +end. diff --git a/mseide-msegui/lib/common/graphics/msegraphutils.pas b/mseide-msegui/lib/common/graphics/msegraphutils.pas new file mode 100644 index 0000000..70f32f9 --- /dev/null +++ b/mseide-msegui/lib/common/graphics/msegraphutils.pas @@ -0,0 +1,2113 @@ +{ MSEgui Copyright (c) 1999-2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msegraphutils; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + msetypes,msestrings,mseerr; + +const + redmask = $ff0000; + redshift = 16; + greenmask = $00ff00; + greenshift = 8; + bluemask = $0000ff; + blueshift = 0; + +type + imagenrty = type integer; //for timagelist + facenrty = type integer; //for tfacelist + pixelty = longword; + pixelaty = array[0..0] of pixelty; + ppixelaty = ^pixelaty; + + colorty = type longword; + pcolorty = ^colorty; + colorarty = array of colorty; + + rgbtriplety = packed record + blue: byte; + green: byte; + red: byte; + res: byte; + end; + prgbtriplety = ^rgbtriplety; + rgbtriplearty = array of rgbtriplety; + rgbtripleaty = array[0..0] of rgbtriplety; + prgbtripleaty = ^rgbtripleaty; + + colormapsty = (cm_rgb,cm_functional,cm_mapped,cm_namedrgb,cm_user); + colormapty = array[colormapsty] of longwordarty; + + colorinfoty = record + name: string; + rgb: rgbtriplety; + end; + pcolorinfoty = ^colorinfoty; + colorinfoarty = array of colorinfoty; + +const + maxopacity = $00ffffff; + speccolormask = $f0000000; + speccolorshift = 28; + cl_functional = colorty($80000000); + cl_mapped = colorty($90000000); + cl_namedrgb = colorty($a0000000); + cl_user = colorty($b0000000); + + cl_invalid = cl_functional + 0; + //can not be used as default value + cl_default = cl_functional + 1; + cl_parent = cl_functional + 2; + cl_transparent = cl_functional + 3; + cl_brush = cl_functional + 4; + cl_brushcanvas = cl_functional + 5; + cl_none = cl_functional + 6; cl_nonenum = 6; + cl_font = cl_functional + 7; //use color of current font + cl_normal = cl_functional + 8; //used in tmenitem.coloractive + cl_lastfunctional = cl_functional + 9; + + cl_dkshadow = cl_mapped + 0; + cl_shadow = cl_mapped + 1; + cl_mid = cl_mapped + 2; + cl_light = cl_mapped + 3; + cl_highlight = cl_mapped + 4; + cl_background = cl_mapped + 5; + cl_foreground = cl_mapped + 6; + cl_active = cl_mapped + 7; + cl_noedit = cl_mapped + 8; + cl_text = cl_mapped + 9; + cl_selectedtext = cl_mapped + 10; + cl_selectedtextbackground = cl_mapped + 11; + cl_infobackground = cl_mapped + 12; + cl_glyph = cl_mapped + 13; + cl_activegrip = cl_mapped + 14; + cl_empty = cl_mapped + 15; + cl_emptytext = cl_mapped + 16; + cl_emptytextbackground = cl_mapped + 17; + cl_zebra = cl_mapped + 18; + cl_grayed = cl_mapped + 19; + cl_grayedshadow = cl_mapped + 20; + + cl_gridactive = cl_mapped + 21; + cl_gridfocus = cl_mapped + 22; + cl_gridselect = cl_mapped + 23; + cl_gridline = cl_mapped + 24; + cl_gridlinefix = cl_mapped + 25; + cl_gridframe = cl_mapped + 26; + cl_scrollbarpattern = cl_mapped + 27; + cl_scrollbarpatternclicked = cl_mapped + 28; + cl_buttondefaultrect = cl_mapped + 29; + cl_glyphactive = cl_mapped + 30; + cl_treeline = cl_mapped + 31; + cl_treelineactive = cl_mapped + 32; + cl_lastmapped = cl_mapped + 33; + + cl_0 = cl_namedrgb + 0; //select colorbackground for monochrome bitmaps + cl_1 = cl_namedrgb + 1; //select colorforeground + cl_black = cl_namedrgb + 2; + cl_dkgray = cl_namedrgb + 3; + cl_gray = cl_namedrgb + 4; + cl_ltgray = cl_namedrgb + 5; + cl_white = cl_namedrgb + 6; + + cl_red = cl_namedrgb + 7; + cl_green = cl_namedrgb + 8; + cl_blue = cl_namedrgb + 9; + cl_cyan = cl_namedrgb + 10; + cl_magenta = cl_namedrgb + 11; + cl_yellow = cl_namedrgb + 12; + + cl_dkred = cl_namedrgb + 13; + cl_dkgreen = cl_namedrgb + 14; + cl_dkblue = cl_namedrgb + 15; + cl_dkcyan = cl_namedrgb + 16; + cl_dkmagenta = cl_namedrgb + 17; + cl_dkyellow = cl_namedrgb + 18; + + cl_ltred = cl_namedrgb + 19; + cl_ltgreen = cl_namedrgb + 20; + cl_ltblue = cl_namedrgb + 21; + cl_ltcyan = cl_namedrgb + 22; + cl_ltmagenta = cl_namedrgb + 23; + cl_ltyellow = cl_namedrgb + 24; + + cl_lastnamedrgb = cl_namedrgb + 25; + + cl_user0 = cl_user + 0; + cl_user1 = cl_user + 1; + cl_user2 = cl_user + 2; + cl_user3 = cl_user + 3; + cl_user4 = cl_user + 4; + cl_user5 = cl_user + 5; + cl_user6 = cl_user + 6; + cl_user7 = cl_user + 7; + cl_user8 = cl_user + 8; + cl_user9 = cl_user + 9; + cl_user10 = cl_user + 10; + cl_user11 = cl_user + 11; + cl_user12 = cl_user + 12; + cl_user13 = cl_user + 13; + cl_user14 = cl_user + 14; + cl_user15 = cl_user + 15; + cl_user16 = cl_user + 16; + cl_user17 = cl_user + 17; + cl_user18 = cl_user + 18; + cl_user19 = cl_user + 19; + cl_fade0 = cl_user + 20; + cl_fade1 = cl_user + 21; + cl_fade2 = cl_user + 22; + cl_fade3 = cl_user + 23; + cl_fade4 = cl_user + 24; + cl_fade5 = cl_user + 25; + cl_fade6 = cl_user + 26; + cl_fade7 = cl_user + 27; + cl_fade8 = cl_user + 28; + cl_fade9 = cl_user + 29; + + cl_lastuser = cl_user + 30; + + functionalcolorcount = integer(cl_lastfunctional)-integer(cl_functional); + mappedcolorcount = integer(cl_lastmapped)-integer(cl_mapped); + namedrgbcolorcount = integer(cl_lastnamedrgb)-integer(cl_namedrgb); + usercolorcount = integer(cl_lastuser)-integer(cl_user); + mapcolorcounts: array[colormapsty] of integer = ( + 0, + functionalcolorcount, + mappedcolorcount, + namedrgbcolorcount, + usercolorcount + ); + + defaultfunctional: array[0..functionalcolorcount-1] + of colorinfoty = + ( + (name: 'cl_invalid'; rgb: (blue: $ff; green: $ff; red: $ff; res: $00)), //0 + (name: 'cl_default'; rgb: (blue: $ff; green: $ff; red: $ff; res: $00)), //1 + (name: 'cl_parent'; rgb: (blue: $ff; green: $ff; red: $ff; res: $00)), //2 + (name: 'cl_transparent'; rgb: (blue: $ff; green: $ff; red: $ff; res: $00)), //3 + (name: 'cl_brush'; rgb: (blue: $ff; green: $ff; red: $ff; res: $00)), //4 + (name: 'cl_brushcanvas'; rgb: (blue: $ff; green: $ff; red: $ff; res: $00)), //5 + (name: 'cl_none'; rgb: (blue: $ff; green: $ff; red: $ff; res: $00)), //6 + (name: 'cl_font'; rgb: (blue: $ff; green: $ff; red: $ff; res: $00)), //7 + (name: 'cl_normal'; rgb: (blue: $ff; green: $ff; red: $ff; res: $00)) //8 +// (name: 'cl_mask'; rgb: (blue: $00; green: $00; red: $00; res: $00)) +// (name: 'cl_grayed'; rgb: (blue: $80; green: $80; red: $80; res: $00)) + ); + + defaultmapped: array[0..mappedcolorcount-1] + of colorinfoty = + ( + (name: 'cl_dkshadow'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //0 + (name: 'cl_shadow'; rgb: (blue: $80; green: $80; red: $80; res: $00)), //1 + (name: 'cl_mid'; rgb: (blue: $c0; green: $c0; red: $c0; res: $00)), //2 + (name: 'cl_light'; rgb: (blue: $e0; green: $e0; red: $e0; res: $00)), //3 + (name: 'cl_highlight'; rgb: (blue: $ff; green: $ff; red: $ff; res: $00)), //4 + (name: 'cl_background'; rgb: (blue: $d0; green: $d0; red: $d0; res: $00)), //5 + (name: 'cl_foreground'; rgb: (blue: $ff; green: $ff; red: $ff; res: $00)), //6 + (name: 'cl_active'; rgb: (blue: $e0; green: $e0; red: $e0; res: $00)), //7 + (name: 'cl_noedit'; rgb: (blue: $e0; green: $e0; red: $e0; res: $00)), //8 + //canvas defaultcolors + (name: 'cl_text'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //9 + (name: 'cl_selectedtext'; rgb: (blue: $ff; green: $ff; red: $ff; res: $00)), //10 + (name: 'cl_selectedtextbackground'; rgb: (blue: $c0; green: $00; red: $00; res: $00)), //11 + (name: 'cl_infobackground'; rgb: (blue: $e0; green: $ff; red: $ff; res: $00)), //12 + (name: 'cl_glyph'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //13 + (name: 'cl_activegrip'; rgb: (blue: $90; green: $20; red: $20; res: $00)), //14 + (name: 'cl_empty'; rgb: (blue: $a0; green: $a0; red: $ff; res: $00)), //15 + (name: 'cl_emptytext'; rgb: (blue: $ff; green: $ff; red: $ff; res: $00)), //16 + (name: 'cl_emptytextbackground'; rgb: (blue: $00; green: $00; red: $ff; res: $00)), //17 + (name: 'cl_zebra'; rgb: (blue: $ff; green: $ff; red: $e0; res: $00)), //18 + (name: 'cl_grayed'; rgb: (blue: $80; green: $80; red: $80; res: $00)), //19 + (name: 'cl_grayedshadow'; rgb: (blue: $ff; green: $ff; red: $ff; res: $00)), //20 + + (name: 'cl_gridactive'; rgb: (blue: $e0; green: $e0; red: $e0; res: $00)), //21 + (name: 'cl_gridfocus'; rgb: (blue: $e0; green: $e0; red: $e0; res: $00)), //22 + (name: 'cl_gridselect'; rgb: (blue: $e0; green: $e0; red: $e0; res: $00)), //23 + (name: 'cl_gridline'; rgb: (blue: $80; green: $80; red: $80; res: $00)), //24 + (name: 'cl_gridlinefix'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //25 + (name: 'cl_gridframe'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //26 + (name: 'cl_scrollbarpattern'; rgb: (blue: $ff; green: $ff; red: $ff; res: $00)), //27 + (name: 'cl_scrollbarpatternclicked'; rgb:(blue: $00; green: $00; red: $00; res: $00)), //28 + (name: 'cl_buttondefaultrect'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //29 + (name: 'cl_glyphactive'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //30 + (name: 'cl_treeline'; rgb: (blue: $80; green: $80; red: $80; res: $00)), //31 + (name: 'cl_treelineactive'; rgb: (blue: $80; green: $80; red: $80; res: $00)) //32 + ); + + defaultnamedrgb: array[0..namedrgbcolorcount-1] + of colorinfoty = + ( + (name: 'cl_0'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //0 + (name: 'cl_1'; rgb: (blue: $ff; green: $ff; red: $ff; res: $00)), //1 + + (name: 'cl_black'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //2 + (name: 'cl_dkgray'; rgb: (blue: $80; green: $80; red: $80; res: $00)), //3 + (name: 'cl_gray'; rgb: (blue: $c0; green: $c0; red: $c0; res: $00)), //4 + (name: 'cl_ltgray'; rgb: (blue: $e0; green: $e0; red: $e0; res: $00)), //5 + (name: 'cl_white'; rgb: (blue: $ff; green: $ff; red: $ff; res: $00)), //6 + + (name: 'cl_red'; rgb: (blue: $00; green: $00; red: $ff; res: $00)), //7 + (name: 'cl_green'; rgb: (blue: $00; green: $ff; red: $00; res: $00)), //8 + (name: 'cl_blue'; rgb: (blue: $ff; green: $00; red: $00; res: $00)), //9 + (name: 'cl_cyan'; rgb: (blue: $ff; green: $ff; red: $00; res: $00)), //10 + (name: 'cl_magenta'; rgb: (blue: $ff; green: $00; red: $ff; res: $00)), //11 + (name: 'cl_yellow'; rgb: (blue: $00; green: $ff; red: $ff; res: $00)), //12 + + (name: 'cl_dkred'; rgb: (blue: $00; green: $00; red: $c0; res: $00)), //13 + (name: 'cl_dkgreen'; rgb: (blue: $00; green: $c0; red: $00; res: $00)), //14 + (name: 'cl_dkblue'; rgb: (blue: $c0; green: $00; red: $00; res: $00)), //15 + (name: 'cl_dkcyan'; rgb: (blue: $80; green: $80; red: $00; res: $00)), //16 + (name: 'cl_dkmagenta'; rgb: (blue: $80; green: $00; red: $80; res: $00)), //17 + (name: 'cl_dkyellow'; rgb: (blue: $00; green: $80; red: $80; res: $00)), //18 + + (name: 'cl_ltred'; rgb: (blue: $a0; green: $a0; red: $ff; res: $00)), //19 + (name: 'cl_ltgreen'; rgb: (blue: $a0; green: $ff; red: $a0; res: $00)), //20 + (name: 'cl_ltblue'; rgb: (blue: $ff; green: $a0; red: $a0; res: $00)), //21 + (name: 'cl_ltcyan'; rgb: (blue: $ff; green: $ff; red: $a0; res: $00)), //22 + (name: 'cl_ltmagenta'; rgb: (blue: $ff; green: $a0; red: $ff; res: $00)), //23 + (name: 'cl_ltyellow'; rgb: (blue: $a0; green: $ff; red: $ff; res: $00)) //24 + ); + + defaultuser: array[0..usercolorcount-1] + of colorinfoty = + ( + (name: 'cl_user0'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //0 + (name: 'cl_user1'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //1 + (name: 'cl_user2'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //2 + (name: 'cl_user3'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //3 + (name: 'cl_user4'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //4 + (name: 'cl_user5'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //5 + (name: 'cl_user6'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //6 + (name: 'cl_user7'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //7 + (name: 'cl_user8'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //8 + (name: 'cl_user9'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //9 + (name: 'cl_user10'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //10 + (name: 'cl_user11'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //11 + (name: 'cl_user12'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //12 + (name: 'cl_user13'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //13 + (name: 'cl_user14'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //14 + (name: 'cl_user15'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //15 + (name: 'cl_user16'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //16 + (name: 'cl_user17'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //17 + (name: 'cl_user18'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //18 + (name: 'cl_user19'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //19 + (name: 'cl_fade0'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //20 + (name: 'cl_fade1'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //21 + (name: 'cl_fade2'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //22 + (name: 'cl_fade3'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //23 + (name: 'cl_fade4'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //24 + (name: 'cl_fade5'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //25 + (name: 'cl_fade6'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //26 + (name: 'cl_fade7'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //27 + (name: 'cl_fade8'; rgb: (blue: $00; green: $00; red: $00; res: $00)), //28 + (name: 'cl_fade9'; rgb: (blue: $00; green: $00; red: $00; res: $00)) //29 + ); + +type + graphicdirectionty = (gd_right,gd_up,gd_left,gd_down,gd_none); + pgraphicdirectionty = ^graphicdirectionty; + graphicdirectionsty = set of graphicdirectionty; + pgraphicdirectionsty = ^graphicdirectionsty; + //0 1 2 3 4 5 + alignmentty = (al_left,al_xcentered,al_right,al_top,al_ycentered,al_bottom, + //6 + al_grayed, + //7 8 9 10 11 + al_stretchx,al_stretchy,al_fit,al_thumbnail,al_tiled, + //12 + al_nomaskscale, + //13 14 15 + al_intpol,al_or,al_and); + alignmentsty = set of alignmentty; + + edgety = (edg_right,edg_top,edg_left,edg_bottom); + edgesty = set of edgety; + + fontstylety = (fs_bold,fs_italic, + fs_underline,fs_strikeout,fs_selected,fs_blank, + fs_force); + //order fix + fontstylesty = set of fontstylety; + + pointty = record + x,y: integer; + end; + ppointty = ^pointty; + pointarty = array of pointty; + ppointarty = ^pointarty; + pointararty = array of pointarty; + pointaty = array[0..0] of pointty; + ppointaty = ^pointaty; + pointpoarty = array of ppointty; + pppointty = ^ppointty; + + fpointty = record + x,y: single; + end; + pfpointty = ^fpointty; + fpointarty = array of fpointty; + pfpointarty = ^fpointarty; + fpointaty = array[0..0] of fpointty; + pfpointaty = ^fpointaty; + + dpointty = record + x,y: double; + end; + pdpointty = ^dpointty; + dpointarty = array of dpointty; + pdpointarty = ^dpointarty; + dpointaty = array[0..0] of dpointty; + pdpointaty = ^dpointaty; + + segmentty = record a,b: pointty end; + psegmentty = ^segmentty; + segmentarty = array of segmentty; + + graphicvectorty = record + start: pointty; + direction: graphicdirectionty; + length: integer; + end; + + sizety = record + cx,cy: integer; + end; + + rectty = record + case integer of + 0: (x,y,cx,cy: integer); + 1: (pos: pointty; size: sizety); + end; + framety = record + case integer of + 0: (left,top,right,bottom: integer); + 1: (topleft,bottomright: sizety); + end; + pframety = ^framety; + prectty = ^rectty; + rectarty = array of rectty; + prectarty = ^rectarty; + rectextty = record + case integer of + 0: (left,top,right,bottom: integer); + 1: (topleft,bottomright: pointty); + end; + prectextty = ^rectextty; + +const + nullpoint: pointty = (x: 0; y: 0); + nullsize: sizety = (cx: 0; cy: 0); + nullrect: rectty = (x: 0; y: 0; cx: 0; cy: 0); + nullframe: framety = (left: 0; top: 0; right: 0; bottom: 0); + emptyrectext: rectextty = (left: maxint; top: maxint; right: minint; + bottom: minint); + + minimalframe: framety = (left: 1; top: 1; right: 1; bottom: 1); + minimaltextframe: framety = (left: 1; top: 0; right: 1; bottom: 0); + +type + gdierrorty = (gde_ok, + gde_creategc,gde_createprintergc,gde_createmetafilegc, + gde_invalidgc, + gde_notruecolor, + gde_invalidcolor, + gde_invalidsaveindex, + gde_parameter, + gde_font, + gde_pixmap,gde_freepixmap, + gde_invalidcopymode,gde_mustbebitmap, + gde_notmonochrome,gde_unmatchedmonochrome, + gde_fontmetrics,gde_image,gde_invalidrect,gde_invalidfileformat, + gde_invalidindex, + gde_notimplemented, + gde_noglx,gde_novisual,gde_rendercontext,gde_glxpixmap, + gde_createwindow + ); + + egdi = class(eerror) + private + ferror1: gdierrorty; + public + constructor create(aerror: gdierrorty; atext: string); + property error: gdierrorty read ferror1; + end; + +type + getrectintegerty = function(const arect: rectty): integer; + setrectintegerty = procedure(var arect: rectty; const avalue: integer); + getintpointty = function(const value,ovalue: integer): pointty; + getintsizety = function(const value,ovalue: integer): sizety; + getpointintty = function(const apoint: pointty): integer; + getsizeintty = function(const asize: sizety): integer; + setpointintty = procedure(var apoint: pointty; const avalue: integer); + setsizeintty = procedure(var asize: sizety; const avalue: integer); + + rectaccessty = record + pos,size,stop,opos,osize,ostop: getrectintegerty; + setpos,setsize,setstop,setopos,setosize,setostop: setrectintegerty; + makepos,makeopos: getintpointty; + makesize,makeosize: getintsizety; + pt,opt: getpointintty; + si,osi: getsizeintty; + setpt,setopt: setpointintty; + setsi,setosi: setsizeintty; + end; + prectaccessty = ^rectaccessty; + +function rx(const arect: rectty): integer; +function ry(const arect: rectty): integer; +function rcx(const arect: rectty): integer; +function rcy(const arect: rectty): integer; +function rstopx(const arect: rectty): integer; +function rstopy(const arect: rectty): integer; +procedure rsetx(var arect: rectty; const avalue: integer); +procedure rsety(var arect: rectty; const avalue: integer); +procedure rsetcx(var arect: rectty; const avalue: integer); +procedure rsetcy(var arect: rectty; const avalue: integer); +procedure rsetstopx(var arect: rectty; const avalue: integer); +procedure rsetstopy(var arect: rectty; const avalue: integer); +function makesizex(const value,ovalue: integer): sizety; +function makesizey(const value,ovalue: integer): sizety; +function makeposx(const value,ovalue: integer): pointty; +function makeposy(const value,ovalue: integer): pointty; +function px(const apoint: pointty): integer; +function py(const apoint: pointty): integer; +function sx(const asize: sizety): integer; +function sy(const asize: sizety): integer; +procedure psetx(var apoint: pointty; const avalue: integer); +procedure psety(var apoint: pointty; const avalue: integer); +procedure ssetx(var asize: sizety; const avalue: integer); +procedure ssety(var asize: sizety; const avalue: integer); + +const + rectaccessx: rectaccessty = ( + pos: {$ifdef FPC}@{$endif}rx; + size: {$ifdef FPC}@{$endif}rcx; + stop: {$ifdef FPC}@{$endif}rstopx; + opos: {$ifdef FPC}@{$endif}ry; + osize: {$ifdef FPC}@{$endif}rcy; + ostop: {$ifdef FPC}@{$endif}rstopy; + setpos: {$ifdef FPC}@{$endif}rsetx; + setsize: {$ifdef FPC}@{$endif}rsetcx; + setstop: {$ifdef FPC}@{$endif}rsetstopx; + setopos: {$ifdef FPC}@{$endif}rsety; + setosize: {$ifdef FPC}@{$endif}rsetcy; + setostop: {$ifdef FPC}@{$endif}rsetstopy; + makepos: {$ifdef FPC}@{$endif}makeposx; + makeopos: {$ifdef FPC}@{$endif}makeposy; + makesize: {$ifdef FPC}@{$endif}makesizex; + makeosize: {$ifdef FPC}@{$endif}makesizey; + pt: {$ifdef FPC}@{$endif}px; + opt: {$ifdef FPC}@{$endif}py; + si: {$ifdef FPC}@{$endif}sx; + osi: {$ifdef FPC}@{$endif}sy; + setpt: {$ifdef FPC}@{$endif}psetx; + setopt: {$ifdef FPC}@{$endif}psety; + setsi: {$ifdef FPC}@{$endif}ssetx; + setosi: {$ifdef FPC}@{$endif}ssety; + ); + rectaccessy: rectaccessty = ( + pos: {$ifdef FPC}@{$endif}ry; + size: {$ifdef FPC}@{$endif}rcy; + stop: {$ifdef FPC}@{$endif}rstopy; + opos: {$ifdef FPC}@{$endif}rx; + osize: {$ifdef FPC}@{$endif}rcx; + ostop: {$ifdef FPC}@{$endif}rstopy; + setpos: {$ifdef FPC}@{$endif}rsety; + setsize: {$ifdef FPC}@{$endif}rsetcy; + setstop: {$ifdef FPC}@{$endif}rsetstopy; + setopos: {$ifdef FPC}@{$endif}rsetx; + setosize: {$ifdef FPC}@{$endif}rsetcx; + setostop: {$ifdef FPC}@{$endif}rsetstopx; + makepos: {$ifdef FPC}@{$endif}makeposy; + makeopos: {$ifdef FPC}@{$endif}makeposx; + makesize: {$ifdef FPC}@{$endif}makesizey; + makeosize: {$ifdef FPC}@{$endif}makesizex; + pt: {$ifdef FPC}@{$endif}py; + opt: {$ifdef FPC}@{$endif}px; + si: {$ifdef FPC}@{$endif}sy; + osi: {$ifdef FPC}@{$endif}sx; + setpt: {$ifdef FPC}@{$endif}psety; + setopt: {$ifdef FPC}@{$endif}psetx; + setsi: {$ifdef FPC}@{$endif}ssety; + setosi: {$ifdef FPC}@{$endif}ssetx; + ); + +procedure gdierror(error: gdierrorty; const text: msestring = ''); overload; +procedure gdierror(error: gdierrorty; sender: tobject; + text: msestring = ''); overload; + +function stringtocolor(const text: string): colorty; +function trystringtocolor(text: string; out value: colorty): boolean; +function colortostring(value: colorty): string; +function getcolornames: msestringarty; +function getcolorvalues: colorarty; + +function makepoint(const x,y: integer): pointty; {$ifdef FPC}inline;{$endif} +function makesize(const cx,cy: integer): sizety; {$ifdef FPC}inline;{$endif} +function makerect(const x,y,cx,cy: integer): rectty; overload; + {$ifdef FPC}inline;{$endif} +function makerect(const pos: pointty; const size: sizety): rectty; overload; + {$ifdef FPC}inline;{$endif} +function makesegment(const a,b: pointty): segmentty; + {$ifdef FPC}inline;{$endif} +function makeframe(const left,top,right,bottom: integer): framety; + {$ifdef FPC}inline;{$endif} + +function mp(const x,y: integer): pointty; {$ifdef FPC}inline;{$endif} +function ms(const cx,cy: integer): sizety; {$ifdef FPC}inline;{$endif} +function mr(const x,y,cx,cy: integer): rectty; overload; + {$ifdef FPC}inline;{$endif} +function mr(const pos: pointty; const size: sizety): rectty; overload; + {$ifdef FPC}inline;{$endif} +function mg(const a,b: pointty): segmentty; + {$ifdef FPC}inline;{$endif} +function mf(const left,top,right,bottom: integer): framety; + {$ifdef FPC}inline;{$endif} + +function bottomright(const rect: rectty): pointty; {$ifdef FPC}inline;{$endif} +function isnullpoint(const point: pointty): boolean; {$ifdef FPC}inline;{$endif} +function isnullsize(const size: sizety): boolean; {$ifdef FPC}inline;{$endif} +function isnullrect(const rect: rectty): boolean; {$ifdef FPC}inline;{$endif} +function isnullframe(const frame: framety): boolean; {$ifdef FPC}inline;{$endif} +function pointisequal(const a,b: pointty): boolean; {$ifdef FPC}inline;{$endif} +function sizeisequal(const a,b: sizety): boolean; {$ifdef FPC}inline;{$endif} +function rectisequal(const a,b: rectty): boolean; {$ifdef FPC}inline;{$endif} +function frameisequal(const a,b: framety): boolean; {$ifdef FPC}inline;{$endif} + +function addpoint(const a,b: pointty): pointty;{$ifdef FPC}inline;{$endif} + //result:= a+b +procedure addpoint1(var dest: pointty; const point: pointty);{$ifdef FPC}inline;{$endif} +function subpoint(const a,b: pointty): pointty; {$ifdef FPC}inline;{$endif} + //result:= a-b +procedure subpoint1(var dest: pointty; const point: pointty); + {$ifdef FPC}inline;{$endif} +function distance(const a,b: pointty): integer;{$ifdef FPC}inline;{$endif} + +function addsize(const a,b: sizety): sizety;{$ifdef FPC}inline;{$endif} + //result:= a+b +procedure addsize1(var dest: sizety; const size: sizety); + {$ifdef FPC}inline;{$endif} +function subsize(const a,b: sizety): sizety; {$ifdef FPC}inline;{$endif} + //result:= a-b +procedure subsize1(var dest: sizety; const size: sizety); + {$ifdef FPC}inline;{$endif} + +function fitsize(const asize: sizety; const maxsize: sizety): sizety; + +function rectcenter(const arect: rectty): pointty; +procedure centerrect(apos: pointty; asize: integer; out rect: rectty); +function excenterrect(const arect: rectty): rectty; +function recenterrect(const arect: rectty): rectty; + +function inflaterect(const rect: rectty; value: integer): rectty; +function inflaterect(const rect: rectty; const value: int32; + const disablededges: edgesty): rectty; +function inflaterect(const rect: rectty; const frame: framety): rectty; +procedure inflaterect1(var rect: rectty; value: integer); +procedure inflaterect1(var rect: rectty; const value: int32; + const disablededges: edgesty); +procedure inflaterect1(var rect: rectty; const frame: framety); +function deflaterect(const rect: rectty; const frame: framety): rectty; +procedure deflaterect1(var rect: rectty; const frame: framety); +procedure normalizerect1(var arect: rectty); +function normalizerect(const arect: rectty): rectty; +procedure swapxy1(var arect: rectty); + +function addframe(const a,b: framety): framety; +procedure addframe1(var dest: framety; const frame: framety); +function subframe(const a,b: framety): framety; +procedure subframe1(var dest: framety; const frame: framety); +function expandrectext(const a,b: rectextty): rectextty; +procedure expandrectext1(var dest: rectextty; const frame: rectextty); + +procedure inflaterectext1(var ext: rectextty; const frame: framety); +function inflaterectext(const ext: rectextty; const frame: framety): rectextty; +procedure deflaterectext1(var ext: rectextty; const frame: framety); +function deflaterectext(const ext: rectextty; const frame: framety): rectextty; + +procedure inflateframe1(var frame: framety; value: integer); +function inflateframe(const frame: framety; value: integer): framety; + +function moverect(const rect: rectty; const dist: pointty): rectty; +procedure moverect1(var rect: rectty; const dist: pointty); +function removerect(const rect: rectty; const dist: pointty): rectty; +procedure removerect1(var rect: rectty; const dist: pointty); +procedure shiftinrect(var rect: rectty; const outerrect: rectty); +procedure centerinrect(var rect: rectty; const outerrect: rectty); +function changerectdirection(const arect: rectty; + const olddirction,newdirection: graphicdirectionty): rectty; +function rotateframe(const aframe: framety; const olddirection, + newdirection: graphicdirectionty): framety; +procedure rotateframe1(var aframe: framety; const olddirection, + newdirection: graphicdirectionty); + +function intersectrect(const a,b: rectty; out dest: rectty): boolean; overload; +function intersectrect(const a,b: rectty): rectty; overload; +procedure intersectrect1(var dest: rectty; const source: rectty); +function testintersectrect(const a,b: rectty): boolean; + //true on intersection +function combinerect(const a,b: rectty): rectty; +procedure combinerect1(var a: rectty; const b: rectty); +function clipinrect(const point: pointty; + const boundsrect: rectty): pointty; overload; +function clipinrect(const rect: rectty; + const boundsrect: rectty): rectty; overload; +function clipinrect1(var point: pointty; + const boundsrect: rectty): boolean; overload; +function clipinrect1(var rect: rectty; + const boundsrect: rectty): boolean; overload; + //true if changed +function calcrectalignment(const dest: rectty; source: rectty; + const alignment: alignmentsty): rectty; + +function pointinrect(const point: pointty; const rect: rectty): boolean; + //true if point is in rect +function pointinellipse(const point: pointty; const rect: rectty): boolean; + //true if point is in ellipse circumscribed by rect +function rectinrect(const inner,outer: rectty): boolean; + //true if inner in outer + +function segment(const a,b: pointty): segmentty; {$ifdef FPC}inline;{$endif} + +procedure vectortoline(const vector: graphicvectorty; out a,b: pointty); + +function rotatedirection(const olddest,newvalue, + oldvalue: graphicdirectionty): graphicdirectionty; + +procedure removeduplicatedpoints(var vect: pointarty); + +function hsbtorgb(hue,sat,bri: word): colorty; + +implementation +uses + mseglob,SysUtils,mseformatstr,classes,mclasses; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + errortexts: array[gdierrorty] of string = ( + '', + 'Invalid GC', + 'Can not create gc', + 'Can not create printer gc', + 'Can not create metafile gc', + 'Color mode must be truecolor', + 'Invalid color', + 'Invalid saveindex', + 'Invalid parameter', + 'Invalid font', + 'Invalid pixmap', + 'Can not free pixmap', + 'Invalid copymode', + 'Must be bitmap', + 'Must be monochrome', + 'Unmatched monochrome', + 'Invalid fontmetrics', + 'Can not create image', + 'Invalid rect', + 'Invalid file format', + 'Invalid index', + 'Not implemented', + 'GLX extension not supported.', + 'Could not find visual.', + 'Could not create a rendering context.', + 'Could not create a GLXPixmap.', + 'Could not create canvas window.' + ); + +function hsbtorgb(hue,sat,bri: word): colorty; +var + r,g,b: real; + int1: integer; + rea1,rea2: real; +begin + if hue > 360 then begin + hue:= 360; + end; + if sat > 100 then begin + sat:= 100; + end; + if bri > 100 then begin + bri:= 100; + end; + int1:= hue; + r:= 0; + g:= 0; + b:= 0; + if int1 < 60 then begin + r:= 60; + g:= int1; + end + else begin + if int1 < 120 then begin + r:= 120 - int1; + g:= 60; + end + else begin + if int1 < 180 then begin + g:= 60; + b:= int1 - 120; + end + else begin + if int1 < 240 then begin + g:= 240 - int1; + b:= 60 + end + else begin + if int1 < 300 then begin + b:= 60; + r:= int1 - 240; + end + else begin + b:= 360 - int1; + r:= 60; + end; + end; + end; + end; + end; + rea1:= sat / 100; + rea2:= 1-rea1; + rea1:= rea1 / 60; + r:= r * rea1 + rea2; + g:= g * rea1 + rea2; + b:= b * rea1 + rea2; + rea1:= bri / 100; + r:= r*rea1; + g:= g*rea1; + b:= b*rea1; + with rgbtriplety(result) do begin + res:= 0; + red:= round(r*255); + green:= round(g*255); + blue:= round(b*255); + end; +end; + +function calcrectalignment(const dest: rectty; source: rectty; + const alignment: alignmentsty): rectty; +begin + result:= dest; + if (al_tiled in alignment) or + (al_thumbnail in alignment) and + ((dest.cx < source.cx) or (dest.cy < source.cy)) then begin + exit; + end; + if al_fit in alignment then begin + if source.cy * dest.cx > source.cx * dest.cy then begin //fit vert + if source.cy <> 0 then begin + source.cx:= (source.cx * dest.cy) div source.cy; + source.cy:= (source.cy * dest.cy) div source.cy; + end; + end + else begin + if source.cx <> 0 then begin + source.cy:= (source.cy * dest.cx) div source.cx; + source.cx:= (source.cx * dest.cx) div source.cx; //fit horz + end; + end; + end; + if al_stretchx in alignment then begin + source.cx:= dest.cx; + end; + if al_stretchy in alignment then begin + source.cy:= dest.cy; + end; + result.size:= source.size; + if al_xcentered in alignment then begin + result.x:= dest.x + (dest.cx - source.cx) div 2 + end + else begin + if al_right in alignment then begin + result.x:= dest.x + dest.cx - source.cx; + end; + end; + if al_ycentered in alignment then begin + result.y:= dest.y + (dest.cy - source.cy) div 2 + end + else begin + if al_bottom in alignment then begin + result.y:= dest.y + dest.cy - source.cy; + end; + end; + intersectrect1(result,dest); +end; + +procedure removeduplicatedpoints(var vect: pointarty); +var + ar1: pointarty; + int1,int2: integer; +begin + if vect <> nil then begin + setlength(ar1,length(vect)); + int2:= 0; + ar1[0]:= vect[0]; + for int1:= 1 to high(vect) do begin + if (ar1[int2].x <> vect[int1].x) or (ar1[int2].y <> vect[int1].y) then begin + inc(int2); + ar1[int2]:= vect[int1]; + end; + end; + setlength(ar1,int2+1); + vect:= ar1; + end; +end; + +function trystringtocolor(text: string; out value: colorty): boolean; +var + ca1: longword; +begin + value:= cl_none; + result:= true; + text:= trim(text); + if trystrtohex(text,longword(value)) then begin + if longword(result) > $00ffffff then begin + result:= false; + exit; + end; + end + else begin + text:= lowercase(text); + for ca1:= 0 to mapcolorcounts[cm_namedrgb] - 1 do begin + if defaultnamedrgb[ca1].name = text then begin + value:= colorty(ca1 + longword(cl_namedrgb)); + exit; + end; + end; + for ca1:= 0 to mapcolorcounts[cm_mapped] - 1 do begin + if defaultmapped[ca1].name = text then begin + value:= colorty(ca1 + longword(cl_mapped)); + exit; + end; + end; + for ca1:= 0 to mapcolorcounts[cm_functional] - 1 do begin + if defaultfunctional[ca1].name = text then begin + value:= colorty(ca1 + longword(cl_functional)); + exit; + end; + end; + for ca1:= 0 to mapcolorcounts[cm_user] - 1 do begin + if defaultuser[ca1].name = text then begin + value:= colorty(ca1 + longword(cl_user)); + exit; + end; + end; + result:= false; + end; +end; + +function stringtocolor(const text: string): colorty; +begin + if not trystringtocolor(text,result) then begin + gdierror(gde_invalidcolor); + end; +end; + +function colortostring(value: colorty): string; +begin + if longword(value) <= $00ffffff then begin + result:= '$'+hextostr(longword(value),6); + end + else begin + if (longword(value) >= longword(cl_namedrgb)) and + (longword(value) < longword(cl_lastnamedrgb)) then begin + result:= defaultnamedrgb[longword(value) - longword(cl_namedrgb)].name; + end + else begin + if (longword(value) >= longword(cl_mapped)) and + (longword(value) < longword(cl_lastmapped)) then begin + result:= defaultmapped[longword(value) - longword(cl_mapped)].name; + end + else begin + if (longword(value) >= longword(cl_functional)) and + (longword(value) < longword(cl_lastfunctional)) then begin + result:= defaultfunctional[longword(value) - longword(cl_functional)].name; + end + else begin + if (longword(value) >= longword(cl_user)) and + (longword(value) < longword(cl_lastuser)) then begin + result:= defaultuser[longword(value) - longword(cl_user)].name; + end + else begin + result:= 'Invalid ($'+hextostr(longword(value),8)+')'; + end; + end; + end; + end; + end; +end; + +var + mappedcolorlookup: array[0..mappedcolorcount-1] of int32 = ( + 0, //cl_dkshadow = cl_mapped + 0; + 1, //cl_shadow = cl_mapped + 1; + 2, //cl_mid = cl_mapped + 2; + 3, //cl_light = cl_mapped + 3; + 4, //cl_highlight = cl_mapped + 4; + 5, //cl_background = cl_mapped + 5; + 6, //cl_foreground = cl_mapped + 6; + 7, //cl_active = cl_mapped + 7; + 8, //cl_noedit = cl_mapped + 8; + 9, //cl_text = cl_mapped + 9; + 10,//cl_selectedtext = cl_mapped + 10; + 11,//cl_selectedtextbackground = cl_mapped + 11; + 12,//cl_infobackground = cl_mapped + 12; + 13,//cl_glyph = cl_mapped + 13; + 30,//cl_glyphactive = cl_mapped + 30; + 14,//cl_activegrip = cl_mapped + 14; + 15,//cl_empty = cl_mapped + 15; + 16,//cl_emptytext = cl_mapped + 16; + 17,//cl_emptytextbackground = cl_mapped + 17; + 18,//cl_zebra = cl_mapped + 18; + 19,//cl_grayed = cl_mapped + 19; + 20,//cl_grayedshadow = cl_mapped + 20; + + 21,//cl_gridactive = cl_mapped + 21; + 22,//cl_gridfocus = cl_mapped + 22; + 23,//cl_gridselect = cl_mapped + 23; + 24,//cl_gridline = cl_mapped + 24; + 25,//cl_gridlinefix = cl_mapped + 25; + 26,//cl_gridframe = cl_mapped + 26; + 27,//cl_scrollbarpattern = cl_mapped + 27; + 28,//cl_scrollbarpatternclicked = cl_mapped + 28; + 29,//cl_buttondefaultrect = cl_mapped + 29; + 31,//cl_treeline = cl_mapped + 31; + 32 //cl_treelineactive = cl_mapped + 32; + ); + +function getcolornames: msestringarty; +var + int1,int2: integer; +begin + setlength(result,namedrgbcolorcount+mappedcolorcount+ + functionalcolorcount+usercolorcount-1); //cl_invalid skipped + for int1:= 0 to high(defaultnamedrgb) do begin + result[int1]:= msestring(defaultnamedrgb[int1].name); + end; + int2:= namedrgbcolorcount; + for int1:= 0 to high(defaultmapped) do begin + result[int1+int2]:= msestring(defaultmapped[mappedcolorlookup[int1]].name); + end; + inc(int2,mappedcolorcount); + result[int2]:= msestring(defaultfunctional[cl_nonenum].name); + //cl_invalid skipped + for int1:= 1 to cl_nonenum-1 do begin + result[int1+int2]:= msestring(defaultfunctional[int1].name); + end; + for int1:= cl_nonenum + 1 to functionalcolorcount-1 do begin + result[int1-1+int2]:= msestring(defaultfunctional[int1].name); + end; + { + for int1:= cl_nonenum+1 to high(defaultfunctional) do begin + result[int1+int2-1]:= defaultfunctional[int1].name; + end; + } + inc(int2,functionalcolorcount-1); + for int1:= 0 to high(defaultuser) do begin + result[int1+int2]:= msestring(defaultuser[int1].name); + end; +end; + +function getcolorvalues: colorarty; +var + int1,int2: integer; +begin + setlength(result,namedrgbcolorcount+mappedcolorcount+ + functionalcolorcount+usercolorcount-1);//cl_invalid skipped + for int1:= 0 to high(defaultnamedrgb) do begin + result[int1]:= cl_namedrgb + longword(int1); + end; + int2:= namedrgbcolorcount; + for int1:= 0 to high(defaultmapped) do begin + result[int1+int2]:= cl_mapped + longword(mappedcolorlookup[int1]); + end; + inc(int2,mappedcolorcount); + result[int2]:= cl_functional+cl_nonenum; //cl_invalid skipped + for int1:= 1 to cl_nonenum-1 do begin + result[int1+int2]:= cl_functional + longword(int1); + end; + for int1:= cl_nonenum+1 to functionalcolorcount-1 do begin + result[int1-1+int2]:= cl_functional + longword(int1); + end; + inc(int2,functionalcolorcount-1); + for int1:= 0 to high(defaultuser) do begin + result[int1+int2]:= cl_user + longword(int1); + end; +end; + +function rotateframe(const aframe: framety; const olddirection, + newdirection: graphicdirectionty): framety; +begin + result:= aframe; + rotateframe1(result,olddirection,newdirection); +end; + +procedure rotateframe1(var aframe: framety; const olddirection, + newdirection: graphicdirectionty); +var + int1: integer; + frame1: framety; +begin + if olddirection <> newdirection then begin + frame1:= aframe; + int1:= (ord(newdirection) - ord(olddirection)) and $3; + case int1 of + 1: begin + aframe.top:= frame1.right; + aframe.left:= frame1.top; + aframe.bottom:= frame1.left; + aframe.right:= frame1.bottom; + end; + 2: begin + aframe.left:= frame1.right; + aframe.bottom:= frame1.top; + aframe.right:= frame1.left; + aframe.top:= frame1.bottom; + end; + 3: begin + aframe.bottom:= frame1.right; + aframe.right:= frame1.top; + aframe.top:= frame1.left; + aframe.left:= frame1.bottom; + end; + end; + end; +end; + +function rotatedirection(const olddest,newvalue, + oldvalue: graphicdirectionty): graphicdirectionty; +begin + result:= graphicdirectionty(((ord(olddest)+ord(newvalue)-ord(oldvalue)) and $3)); +end; + +procedure shiftinrect(var rect: rectty; const outerrect: rectty); +var + int1: integer; +begin + with rect do begin + int1:= outerrect.x + outerrect.cx - (x + cx); + if int1 < 0 then begin + inc(x,int1); + end; + int1:= outerrect.y + outerrect.cy - (y + cy); + if int1 < 0 then begin + inc(y,int1); + end; + if x < outerrect.x then begin + x:= outerrect.x; + end; + if y < outerrect.y then begin + y:= outerrect.y; + end; + end; +end; + +procedure centerinrect(var rect: rectty; const outerrect: rectty); +begin + with outerrect do begin + rect.x:= x + (cx - rect.cx) div 2; + rect.y:= y + (cy - rect.cy) div 2; + end; +end; + +function changerectdirection(const arect: rectty; + const olddirction,newdirection: graphicdirectionty): rectty; +begin + result.pos:= arect.pos; + if (olddirction in [gd_left,gd_right]) xor + (newdirection in [gd_left,gd_right]) then begin + result.cx:= arect.cy; + result.cy:= arect.cx; + end + else begin + result.size:= arect.size; + end; +end; + +function makepoint(const x,y: integer): pointty; {$ifdef FPC}inline;{$endif} +begin + result.x:= x; + result.y:= y; +end; + +function makesize(const cx,cy: integer): sizety; {$ifdef FPC}inline;{$endif} +begin + result.cx:= cx; + result.cy:= cy; +end; + +function makerect(const x,y,cx,cy: integer): rectty; {$ifdef FPC}inline;{$endif} +begin + result.x:= x; + result.y:= y; + result.cx:= cx; + result.cy:= cy; +end; + +function makerect(const pos: pointty; const size: sizety): rectty; overload; + {$ifdef FPC}inline;{$endif} +begin + result.pos:= pos; + result.size:= size; +end; + +function makeframe(const left,top,right,bottom: integer): framety; + {$ifdef FPC}inline;{$endif} +begin + result.left:= left; + result.top:= top; + result.right:= right; + result.bottom:= bottom; +end; + +function mf(const left,top,right,bottom: integer): framety; + {$ifdef FPC}inline;{$endif} +begin + result.left:= left; + result.top:= top; + result.right:= right; + result.bottom:= bottom; +end; + +function makesegment(const a,b: pointty): segmentty; + {$ifdef FPC}inline;{$endif} +begin + result.a:= a; + result.b:= b; +end; + +function mp(const x,y: integer): pointty;{$ifdef FPC}inline;{$endif} +begin + result.x:= x; + result.y:= y; +end; + +function ms(const cx,cy: integer): sizety; {$ifdef FPC}inline;{$endif} +begin + result.cx:= cx; + result.cy:= cy; +end; + +function mr(const x,y,cx,cy: integer): rectty; {$ifdef FPC}inline;{$endif} +begin + result.x:= x; + result.y:= y; + result.cx:= cx; + result.cy:= cy; +end; + +function mr(const pos: pointty; const size: sizety): rectty; overload; + {$ifdef FPC}inline;{$endif} +begin + result.pos:= pos; + result.size:= size; +end; + +function mg(const a,b: pointty): segmentty; + {$ifdef FPC}inline;{$endif} +begin + result.a:= a; + result.b:= b; +end; + +function bottomright(const rect: rectty): pointty; {$ifdef FPC}inline;{$endif} +begin + result.x:= rect.x + rect.cx; + result.y:= rect.y + rect.cy; +end; + +function isnullpoint(const point: pointty): boolean;{$ifdef FPC}inline;{$endif} +begin + with point do begin + result:= (x = 0) and (y = 0); + end; +end; + +function isnullsize(const size: sizety): boolean;{$ifdef FPC}inline;{$endif} +begin + with size do begin + result:= (cx = 0) and (cy = 0); + end; +end; + +function isnullrect(const rect: rectty): boolean;{$ifdef FPC}inline;{$endif} +begin + with rect do begin + result:= (x = 0) and (y = 0) and (cx = 0) and (cy = 0); + end; +end; + +function isnullframe(const frame: framety): boolean;{$ifdef FPC}inline;{$endif} +begin + with frame do begin + result:= (left = 0) and (top = 0) and (right = 0) and (bottom = 0); + end; +end; + +function pointisequal(const a,b: pointty): boolean;{$ifdef FPC}inline;{$endif} +begin + result:= (a.x = b.x) and (a.y = b.y); +end; + +function sizeisequal(const a,b: sizety): boolean; {$ifdef FPC}inline;{$endif} +begin + result:= (a.cx = b.cx) and (a.cy = b.cy); +end; + +function rectisequal(const a,b: rectty): boolean; {$ifdef FPC}inline;{$endif} +begin + result:= (a.x = b.x) and (a.y = b.y) and + (a.cx = b.cx) and (a.cy = b.cy); +end; + +function frameisequal(const a,b: framety): boolean;{$ifdef FPC}inline;{$endif} +begin + result:= (a.left = b.left) and (a.top = b.top) and + (a.right = b.right) and (a.bottom = b.bottom); +end; + +function addpoint(const a,b: pointty): pointty;{$ifdef FPC}inline;{$endif} + //result:= a-b +begin + result.x:= a.x+b.x; + result.y:= a.y+b.y; +end; + +procedure addpoint1(var dest: pointty; const point: pointty); + {$ifdef FPC}inline;{$endif} +begin + inc(dest.x,point.x); + inc(dest.y,point.y); +end; + +function subpoint(const a,b: pointty): pointty;{$ifdef FPC}inline;{$endif} + //result:= a-b +begin + result.x:= a.x-b.x; + result.y:= a.y-b.y; +end; + +procedure subpoint1(var dest: pointty; const point: pointty); + {$ifdef FPC}inline;{$endif} +begin + dec(dest.x,point.x); + dec(dest.y,point.y); +end; + +function distance(const a,b: pointty): integer;{$ifdef FPC}inline;{$endif} +begin + result:= abs(a.x-b.x) + abs(a.y-b.y); +end; + +function addsize(const a,b: sizety): sizety;{$ifdef FPC}inline;{$endif} + //result:= a+b +begin + result.cx:= a.cx+b.cx; + result.cy:= a.cy+b.cy; +end; + +procedure addsize1(var dest: sizety; const size: sizety); + {$ifdef FPC}inline;{$endif} +begin + inc(dest.cx,size.cx); + inc(dest.cy,size.cy); +end; + +function subsize(const a,b: sizety): sizety;{$ifdef FPC}inline;{$endif} + //result:= a-b +begin + result.cx:= a.cx-b.cx; + result.cy:= a.cy-b.cy; +end; + +procedure subsize1(var dest: sizety; const size: sizety); + {$ifdef FPC}inline;{$endif} +begin + dec(dest.cx,size.cx); + dec(dest.cy,size.cy); +end; + +function segment(const a,b: pointty): segmentty; {$ifdef FPC}inline;{$endif} +begin + result.a:= a; + result.b:= b; +end; + +procedure vectortoline(const vector: graphicvectorty; out a,b: pointty); +begin + with vector do begin + a:= start; + case direction of + gd_right: begin + b.x:= start.x+length; + b.y:= start.y; + end; + gd_up: begin + b.x:= start.x; + b.y:= start.y - length; + end; + gd_left: begin + b.x:= start.x - length; + b.y:= start.y; + end; + gd_down: begin + b.x:= start.x; + b.y:= start.y + length; + end; + end; + end; +end; + +function deflaterect(const rect: rectty; const frame: framety): rectty; +begin + result.x:= rect.x + frame.left; + result.cx:= rect.cx - frame.left - frame.right; + result.y:= rect.y + frame.top; + result.cy:= rect.cy - frame.top - frame.bottom; +end; + +procedure deflaterect1(var rect: rectty; const frame: framety); +begin + inc(rect.x,frame.left); + dec(rect.cx,frame.left); + inc(rect.y,frame.top); + dec(rect.cy,frame.top); + dec(rect.cx,frame.right); + dec(rect.cy,frame.bottom); +end; + +procedure normalizerect1(var arect: rectty); +begin + if arect.cx < 0 then begin + arect.x:= arect.x + arect.cx + 1; + arect.cx:= -arect.cx; + end; + if arect.cy < 0 then begin + arect.y:= arect.y + arect.cy + 1; + arect.cy:= -arect.cy; + end; +end; + +function normalizerect(const arect: rectty): rectty; +begin + result:= arect; + normalizerect1(result); +end; + +procedure swapxy1(var arect: rectty); +var + int1: integer; +begin + with arect do begin + int1:= x; + x:= y; + y:= int1; + int1:= cx; + cx:= cy; + cy:= int1; + end; +end; + +function addframe(const a,b: framety): framety; +begin + with result do begin + left:= a.left + b.left; + top:= a.top + b.top; + right:= a.right + b.right; + bottom:= a.bottom + b.bottom; + end; +end; + +procedure addframe1(var dest: framety; const frame: framety); +begin + with dest do begin + left:= left + frame.left; + top:= top + frame.top; + right:= right + frame.right; + bottom:= bottom + frame.bottom; + end; +end; + +function subframe(const a,b: framety): framety; +begin + with result do begin + left:= a.left - b.left; + top:= a.top - b.top; + right:= a.right - b.right; + bottom:= a.bottom - b.bottom; + end; +end; + +procedure subframe1(var dest: framety; const frame: framety); +begin + with dest do begin + left:= left - frame.left; + top:= top - frame.top; + right:= right - frame.right; + bottom:= bottom - frame.bottom; + end; +end; + +function expandrectext(const a,b: rectextty): rectextty; +begin + result:= a; + with result do begin + if b.left < left then begin + left:= b.left; + end; + if b.right > right then begin + right:= b.right; + end; + if b.top < top then begin + top:= b.top; + end; + if b.bottom < bottom then begin + bottom:= b.bottom; + end; + end; +end; + +procedure expandrectext1(var dest: rectextty; const frame: rectextty); +begin + with dest do begin + if frame.left < left then begin + left:= frame.left; + end; + if frame.right > right then begin + right:= frame.right; + end; + if frame.top < top then begin + top:= frame.top; + end; + if frame.bottom > bottom then begin + bottom:= frame.bottom; + end; + end; +end; + +procedure inflaterectext1(var ext: rectextty; const frame: framety); +begin + with ext do begin + left:= left - frame.left; + top:= top - frame.top; + right:= right + frame.right; + bottom:= bottom + frame.bottom; + end; +end; + +function inflaterectext(const ext: rectextty; const frame: framety): rectextty; +begin + with result do begin + left:= ext.left - frame.left; + top:= ext.top - frame.top; + right:= ext.right + frame.right; + bottom:= ext.bottom + frame.bottom; + end; +end; + +procedure deflaterectext1(var ext: rectextty; const frame: framety); +begin + with ext do begin + left:= left + frame.left; + top:= top + frame.top; + right:= right - frame.right; + bottom:= bottom - frame.bottom; + end; +end; + +function deflaterectext(const ext: rectextty; const frame: framety): rectextty; +begin + with result do begin + left:= ext.left + frame.left; + top:= ext.top + frame.top; + right:= ext.right - frame.right; + bottom:= ext.bottom - frame.bottom; + end; +end; + +function pointinrect(const point: pointty; const rect: rectty): boolean; + //true if point is in rect +begin + result:= (point.x >= rect.x) and (point.x < rect.x + rect.cx) and + (point.y >= rect.y) and (point.y < rect.y + rect.cy); +end; + +function pointinellipse(const point: pointty; const rect: rectty): boolean; + //true if point is in ellipse circumscribed by rect +var + x1,y1: real; + x0q,y0q: real; +begin + x1:= point.x - rect.x - rect.cx div 2; + y1:= point.y - rect.y - rect.cy div 2; + x0q:= rect.cx*rect.cx; + y0q:= rect.cy*rect.cy; + result:= (x1*x1*y0q+y1*y1*x0q)*4 <= x0q*y0q; +end; + +function fitsize(const asize: sizety; const maxsize: sizety): sizety; +begin + result:= nullsize; + if asize.cx*maxsize.cy > maxsize.cx*asize.cy then begin //fit horz + result.cx:= maxsize.cx; + if asize.cx <> 0 then begin + result.cy:= (asize.cy*maxsize.cx) div asize.cx; + end; + end + else begin //fit vert + result.cy:= maxsize.cy; + if asize.cy <> 0 then begin + result.cx:= (asize.cx*maxsize.cy) div asize.cy; + end; + end; +end; + +function rectcenter(const arect: rectty): pointty; +begin + with arect do begin + result.x:= x + cx div 2; + result.y:= y + cy div 2; + end; +end; + +procedure centerrect(apos: pointty; asize: integer; out rect: rectty); +var + int1: integer; +begin + int1:= asize div 2; + with rect do begin + x:= apos.x - int1; + y:= apos.y - int1; + cx:= asize; + cy:= asize; + end; +end; + +function excenterrect(const arect: rectty): rectty; +begin + with result do begin + x:= arect.x - arect.cx div 2; + y:= arect.y - arect.cy div 2; + cx:= arect.cx; + cy:= arect.cy; + end; +end; + +function recenterrect(const arect: rectty): rectty; +begin + with result do begin + x:= arect.x + arect.cx div 2; + y:= arect.y + arect.cy div 2; + cx:= arect.cx; + cy:= arect.cy; + end; +end; + +function inflaterect(const rect: rectty; value: integer): rectty; +begin + with rect do begin + result.x:= x - value; + result.y:= y - value; + result.cx:= cx + value + value; + result.cy:= cy + value + value; + end; +end; + +function inflaterect(const rect: rectty; const value: int32; + const disablededges: edgesty): rectty; +begin + result:= rect; + with result do begin + if not (edg_left in disablededges) then begin + dec(x,value); + inc(cx,value); + end; + if not (edg_top in disablededges) then begin + dec(y,value); inc(cy,value); + end; + if not (edg_right in disablededges) then begin + inc(cx,value); + end; + if not (edg_bottom in disablededges) then begin + inc(cy,value); + end; + end; +end; + +function inflaterect(const rect: rectty; const frame: framety): rectty; +begin + result.x:= rect.x - frame.left; + result.cx:= rect.cx + frame.left + frame.right; + result.y:= rect.y - frame.top; + result.cy:= rect.cy + frame.top + frame.bottom; +end; + +procedure inflaterect1(var rect: rectty; value: integer); +begin + with rect do begin + dec(x,value); + dec(y,value); + inc(cx,value); + inc(cx,value); + inc(cy,value); + inc(cy,value); + end; +end; + +procedure inflaterect1(var rect: rectty; const value: int32; + const disablededges: edgesty); +begin + with rect do begin + if not (edg_left in disablededges) then begin + dec(x,value); + inc(cx,value); + end; + if not (edg_top in disablededges) then begin + dec(y,value); + inc(cy,value); + end; + if not (edg_right in disablededges) then begin + inc(cx,value); + end; + if not (edg_bottom in disablededges) then begin + inc(cy,value); + end; + end; +end; + +procedure inflaterect1(var rect: rectty; const frame: framety); +begin + dec(rect.x,frame.left); + inc(rect.cx,frame.left); + dec(rect.y,frame.top); + inc(rect.cy,frame.top); + inc(rect.cx,frame.right); + inc(rect.cy,frame.bottom); +end; + + +procedure inflateframe1(var frame: framety; value: integer); +begin + inc(frame.left,value); + inc(frame.top,value); + inc(frame.right,value); + inc(frame.bottom,value); +end; + +function inflateframe(const frame: framety; value: integer): framety; +begin + result.left:= frame.left + value; + result.top:= frame.top + value; + result.right:= frame.right + value; + result.bottom:= frame.bottom + value; +end; + + +function moverect(const rect: rectty; const dist: pointty): rectty; +begin + result.x:= rect.x + dist.x; + result.y:= rect.y + dist.y; + result.size:= rect.size; +end; + +procedure moverect1(var rect: rectty; const dist: pointty); +begin + inc(rect.x,dist.x); + inc(rect.y,dist.y); +end; + +function removerect(const rect: rectty; const dist: pointty): rectty; +begin + result.x:= rect.x - dist.x; + result.y:= rect.y - dist.y; + result.size:= rect.size; +end; + +procedure removerect1(var rect: rectty; const dist: pointty); +begin + dec(rect.x,dist.x); + dec(rect.y,dist.y); +end; + +function intersectrect(const a,b: rectty; out dest: rectty): boolean; +var + rect1: rectty; +begin + with rect1 do begin + if a.x > b.x then begin + x:= a.x; + if a.x + a.cx > b.x + b.cx then begin + cx:= b.x + b.cx - a.x; + end + else begin + cx:= a.cx; + end; + end + else begin + x:= b.x; + if b.x + b.cx > a.x + a.cx then begin + cx:= a.x + a.cx - b.x; + end + else begin + cx:= b.cx; + end; + end; + if a.y > b.y then begin + y:= a.y; + if a.y + a.cy > b.y + b.cy then begin + cy:= b.y + b.cy - a.y; + end + else begin + cy:= a.cy; + end; + end + else begin + y:= b.y; + if b.y + b.cy > a.y + a.cy then begin + cy:= a.y + a.cy - b.y; + end + else begin + cy:= b.cy; + end; + end; + if (cx <= 0) or (cy <= 0) then begin + result:= false; + dest:= nullrect; + end + else begin + result:= true; + dest:= rect1; + end; + end; +end; + +function intersectrect(const a,b: rectty): rectty; +begin + intersectrect(a,b,result); +end; + +procedure intersectrect1(var dest: rectty; const source: rectty); +begin + intersectrect(source,dest,dest); +end; + +function testintersectrect(const a,b: rectty): boolean; + //true on intersection +var + rect1: rectty; +begin + result:= intersectrect(a,b,rect1); +end; + +function combinerect(const a,b: rectty): rectty; +var + i1: int32; + ps,pe: pointty; +begin + ps:= a.pos; + if a.x > b.x then begin + ps.x:= b.x; + end; + if a.y > b.y then begin + ps.y:= b.y; + end; + pe.x:= a.x + a.cx; + i1:= b.x + b.cx; + if i1 > pe.x then begin + pe.x:= i1; + end; + pe.y:= a.y + a.cy; + i1:= b.y + b.cy; + if i1 > pe.y then begin + pe.y:= i1; + end; + result.pos:= ps; + result.cx:= pe.x-ps.x; + result.cy:= pe.y-ps.y; +end; + +procedure combinerect1(var a: rectty; const b: rectty); +begin + a:= combinerect(a,b); +end; + +function rectinrect(const inner,outer: rectty): boolean; + + procedure normalize(const rect: rectty; out topleft,bottomright: pointty); + begin + with rect do begin + if cx < 0 then begin + topleft.x:= x + cx; + bottomright.x:= x; + end + else begin + topleft.x:= x; + bottomright.x:= x + cx; + end; + if cy < 0 then begin + topleft.y:= y + cy; + bottomright.y:= y; + end + else begin + topleft.y:= y; + bottomright.y:= y + cy; + end; + end; + end; + +var + itopleft,ibottomright: pointty; + otopleft,obottomright: pointty; +begin + normalize(inner,itopleft,ibottomright); + normalize(outer,otopleft,obottomright); + result:= (itopleft.x >= otopleft.x) and (ibottomright.x <= obottomright.x) and + (itopleft.y >= otopleft.y) and (ibottomright.y <= obottomright.y); +end; + +function clipinrect1(var point: pointty; const boundsrect: rectty): boolean; +begin + result:= false; + with boundsrect do begin + if point.x < x then begin + result:= true; + point.x:= x; + end; + if point.x >= x + cx then begin + result:= true; + point.x:= x + cx - 1; + end; + if point.y < y then begin + result:= true; + point.y:= y; + end; + if point.y >= y + cy then begin + result:= true; + point.y:= y + cy - 1; + end; + end; +end; + +function clipinrect(const point: pointty; const boundsrect: rectty): pointty; +begin + result:= point; + clipinrect1(result,boundsrect); +end; + +function clipinrect1(var rect: rectty; const boundsrect: rectty): boolean; +begin + result:= false; + with boundsrect do begin + if rect.x < x then begin + result:= true; + rect.x:= x; + end; + if rect.x + rect.cx > x + cx then begin + rect.x:= x + cx - rect.cx; + if rect.x < x then begin + result:= true; + rect.x:= x; + rect.cx:= cx; + end; + end; + if rect.y < y then begin + result:= true; + rect.y:= y; + end; + if rect.y + rect.cy > y + cy then begin + result:= true; + rect.y:= y + cy - rect.cy; + if rect.y < y then begin + rect.y:= y; + rect.cy:= cy; + end; + end; + end; +end; + +function clipinrect(const rect: rectty; const boundsrect: rectty): rectty; +begin + result:= rect; + clipinrect1(result,boundsrect); +end; + +function rx(const arect: rectty): integer; +begin + result:= arect.x; +end; + +function ry(const arect: rectty): integer; +begin + result:= arect.y; +end; + +function rcx(const arect: rectty): integer; +begin + result:= arect.cx; +end; + +function rcy(const arect: rectty): integer; +begin + result:= arect.cy; +end; + +function rstopx(const arect: rectty): integer; +begin + result:= arect.x + arect.cx; +end; + +function rstopy(const arect: rectty): integer; +begin + result:= arect.y + arect.cy; +end; + +procedure rsetx(var arect: rectty; const avalue: integer); +begin + arect.x:= avalue; +end; + +procedure rsety(var arect: rectty; const avalue: integer); +begin + arect.y:= avalue; +end; + +procedure rsetcx(var arect: rectty; const avalue: integer); +begin + arect.cx:= avalue; +end; + +procedure rsetcy(var arect: rectty; const avalue: integer); +begin + arect.cy:= avalue; +end; + +procedure rsetstopx(var arect: rectty; const avalue: integer); +begin + arect.cx:= avalue - arect.x; +end; + +procedure rsetstopy(var arect: rectty; const avalue: integer); +begin + arect.cy:= avalue - arect.y; +end; + +function makesizex(const value,ovalue: integer): sizety; +begin + result.cx:= value; + result.cy:= ovalue; +end; + +function makesizey(const value,ovalue: integer): sizety; +begin + result.cy:= value; + result.cx:= ovalue; +end; + +function makeposx(const value,ovalue: integer): pointty; +begin + result.x:= value; + result.y:= ovalue; +end; + +function makeposy(const value,ovalue: integer): pointty; +begin + result.y:= value; + result.x:= ovalue; +end; + +function px(const apoint: pointty): integer; +begin + result:= apoint.x; +end; + +function py(const apoint: pointty): integer; +begin + result:= apoint.y; +end; + +function sx(const asize: sizety): integer; +begin + result:= asize.cx; +end; + +function sy(const asize: sizety): integer; +begin + result:= asize.cy; +end; + +procedure psetx(var apoint: pointty; const avalue: integer); +begin + apoint.x:= avalue; +end; + +procedure psety(var apoint: pointty; const avalue: integer); +begin + apoint.y:= avalue; +end; + +procedure ssetx(var asize: sizety; const avalue: integer); +begin + asize.cx:= avalue; +end; + +procedure ssety(var asize: sizety; const avalue: integer); +begin + asize.cy:= avalue; +end; + +procedure gdierror(error: gdierrorty; const text: msestring = ''); overload; +begin + if error = gde_ok then begin + exit; + end; + raise egdi.create(error,ansistring(text)); +end; + +procedure gdierror(error: gdierrorty; sender: tobject; + text: msestring = ''); overload; +begin + if error = gde_ok then begin + exit; + end; + if sender <> nil then begin + text:= msestring(sender.classname) + ' ' + text; + if sender is tcomponent then begin + text:= text + ' ' + msestring(fullcomponentname(tcomponent(sender))); + end; + end; + gdierror(error,text); +end; + +{ egdi } + +constructor egdi.create(aerror: gdierrorty; atext: string); +begin + inherited create(integer(aerror),atext,errortexts); +end; + +end. + diff --git a/mseide-msegui/lib/common/graphics/mselinetria.pas b/mseide-msegui/lib/common/graphics/mselinetria.pas new file mode 100644 index 0000000..8ebf75c --- /dev/null +++ b/mseide-msegui/lib/common/graphics/mselinetria.pas @@ -0,0 +1,943 @@ +{ MSEgui Copyright (c) 2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mselinetria; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msegraphics,msegraphutils,msetriaglob; +type + lineshiftvectorty = record + shift: pointty; + d: pointty; //delta + c: integer; //length + end; + lineshiftinfoty = record + dist: integer; + offsx,offsy: integer; + pointa: ppointty; + pointb: ppointty; + linestart: ppointty; + v: lineshiftvectorty; + offs: pointty; + dest: ppointty; + dashlen: integer; + dashind: integer; + dashpos: integer; + dashref: integer; + reverse: boolean; + end; + plineshiftinfoty = ^lineshiftinfoty; + +function linestria(var drawinfo: drawinfoty; out apoints: ppointty; + out apointcount: integer): boolean; + //true if triangles, tristrip otherwise +procedure linesegmentstria(var drawinfo: drawinfoty; + out atriangles: ptrianglety; out atrianglecount: integer); + +procedure updatestarttria(var drawinfo: drawinfoty; var li: lineshiftinfoty); +procedure updatestartstrip(var drawinfo: drawinfoty; var li: lineshiftinfoty); +procedure updateendtria(var drawinfo: drawinfoty; var li: lineshiftinfoty); +procedure updateendstrip(var drawinfo: drawinfoty; var li: lineshiftinfoty); + +implementation +const + arctablesize = 20; // max diameter + arcrowsize = arctablesize div 2 - 2; + arcscalefact = 256; //value scaling = 128 + bevelangsin = sin(2*pi*11.0/360.0); +type + arctablety = array[0..arctablesize,0..arcrowsize] of byte; +const + arctable: arctablety = ( + (0,0,0,0,0,0,0,0,0), //0 + (0,0,0,0,0,0,0,0,0), //1 + (0,0,0,0,0,0,0,0,0), //2 + (33,0,0,0,0,0,0,0,0), //3 + (17,0,0,0,0,0,0,0,0), //4 + (11,51,0,0,0,0,0,0,0), //5 + (7,33,0,0,0,0,0,0,0), //6 + (5,23,62,0,0,0,0,0,0), //7 + (4,17,43,0,0,0,0,0,0), //8 + (3,13,33,69,0,0,0,0,0), //9 + (3,11,26,51,0,0,0,0,0), //10 + (2,9,21,40,75,0,0,0,0), //11 + (2,7,17,33,57,0,0,0,0), //12 + (2,6,14,27,46,79,0,0,0), //13 + (1,5,12,23,38,62,0,0,0), //14 + (1,5,11,20,33,51,82,0,0), //15 + (1,4,9,17,28,43,66,0,0), //16 + (1,4,8,15,24,37,55,85,0), //17 + (1,3,7,13,22,33,48,69,0), //18 + (1,3,7,12,19,29,41,59,87), //19 + (1,3,6,11,17,26,37,51,72) //20 +); +// +//todo: optimize smooth line generation +// +function calclineshift(const drawinfo: drawinfoty; var info: lineshiftinfoty; + const skipzerolength: boolean): boolean; + //true if valid +var + dx1,dy1: integer; +begin + result:= true; + with info do begin + dx1:= pointb^.x - pointa^.x; + dy1:= pointb^.y - pointa^.y; + if skipzerolength and (dx1 = 0) and (dy1 = 0) then begin + result:= false; + exit; + end; + v.c:= round(sqrt(dx1*dx1 + dy1*dy1)); //todo: optimize + offsx:= 0; + offsy:= 0; + if v.c = 0 then begin + v.shift.x:= 0; //default direction + v.shift.y:= dist; + end + else begin + v.shift.x:= (dy1*dist) div v.c; + v.shift.y:= (dx1*dist) div v.c; + if dist and $10000 <> 0 then begin //odd, shift 0.5 pixel + offsx:= abs(dy1 shl 15) div v.c; + offsy:= abs(dx1 shl 15) div v.c; + end; + end; + offs.x:= (drawinfo.origin.x shl 16) + v.shift.x div 2 + offsx; + offs.y:= (drawinfo.origin.y shl 16) - v.shift.y div 2 + offsy; + linestart:= pointa; + v.d.x:= dx1; + v.d.y:= dy1; + end; +end; + +function isbevelang(const li: lineshiftinfoty; const da: pointty): boolean; +const + bevelangmax = round(bevelangsin*256); +var + int1,int2: integer; + dax,day,dbx,dby: integer; +begin + result:= false; + with li do begin + dax:= da.y div 256; //with is orthogonal to vector, negative + day:= da.x div 256; + dbx:= li.v.shift.y div 256; + dby:= li.v.shift.x div 256; + if dax*dbx + day*dby < 0 then begin + int1:= dbx*day - dax*dby; + int2:= dist div (16*256); + result:= abs(int1 div (int2 * int2)) < bevelangmax; + end; + end; +end; + +procedure shiftpoint(var info: lineshiftinfoty); +var + x1,y1: integer; +begin + with info do begin + x1:= (pointa^.x shl 16) + offs.x; + y1:= (pointa^.y shl 16) + offs.y; + dest^.x:= x1; + dest^.y:= y1; + inc(dest); + dest^.x:= x1 - v.shift.x; + dest^.y:= y1 + v.shift.y; + inc(dest); + pointa:= pointb; + inc(pointb); + end; +end; + +procedure shiftpointa(var info: lineshiftinfoty); + //no source increment +var + x1,y1: integer; +begin + with info do begin + x1:= (pointa^.x shl 16) + offs.x; + y1:= (pointa^.y shl 16) + offs.y; + dest^.x:= x1; + dest^.y:= y1; + inc(dest); + dest^.x:= x1 - v.shift.x; + dest^.y:= y1 + v.shift.y; + inc(dest); + end; +end; + +procedure shiftpointb(var info: lineshiftinfoty); + //no source increment +var + x1,y1: integer; +begin + with info do begin + x1:= (pointb^.x shl 16) + offs.x; + y1:= (pointb^.y shl 16) + offs.y; + dest^.x:= x1; + dest^.y:= y1; + inc(dest); + dest^.x:= x1 - v.shift.x; + dest^.y:= y1 + v.shift.y; + inc(dest); + end; +end; + +type + intersectinfoty = record + da,db: pointty; + p0,p1: ppointty; + isect: pointty; + axbx,axby,aybx,ayby: int64; + q: integer; + end; + +procedure intersect2(var info: intersectinfoty); + //todo: limit overflow +begin + with info do begin +//xa == (dxa*dxb*y0 - dxa*dxb*y1 + dxa*dyb*x1 - dxb*dya*x0)/(dxa*dyb - dxb*dya) + isect.x:= (axbx*p0^.y - axbx*p1^.y + axby*p1^.x - aybx*p0^.x) div q; +//ya == (dxa*dyb*y0 - dxb*dya*y1 - dya*dyb*x0 + dya*dyb*x1)/(dxa*dyb - dxb*dya) + isect.y:= (axby*p0^.y - aybx*p1^.y - ayby*p0^.x + ayby*p1^.x) div q; + end; +end; + +function intersect(var info: intersectinfoty): boolean; + //todo: limit overflow +begin + result:= false; + with info do begin + axby:= da.x*db.y; + aybx:= da.y*db.x; + q:= axby - aybx; + if q <> 0 then begin + result:= true; + axbx:= da.x*db.x; + ayby:= da.y*db.y; + intersect2(info); + end; + end; +end; + +procedure roundcapstarttria(var drawinfo: drawinfoty; var li: lineshiftinfoty); +var + sx1,sy1,sx2,sy2: integer; + int1: integer; + po1: ppointty; + po2: pbyte; + pt1,pt2: pointty; + first: boolean; +begin + with triagcty(drawinfo.gc.platformdata).d do begin + po1:= li.dest; + dec(po1); + pt2:= (po1)^; + dec(po1); + pt1:= (po1)^; + if linewidth <= arctablesize then begin + sx1:= (li.v.shift.y) div 2; //axial + sy1:= (li.v.shift.x) div 2; + po1^.x:= (pt1.x + pt2.x) div 2 - sx1; + po1^.y:= (pt1.y + pt2.y) div 2 - sy1; + inc(po1); + po2:= @arctable[linewidth]; + inc(po2,linewidth1 div 2 - 2); + first:= true; + for int1:= linewidth div 2 - 1 downto 1 do begin + if not first then begin + po1^:= (po1-2)^; //0 + inc(po1); + po1^:= (po1-2)^; //1 + inc(po1); + end; + sx1:= (li.v.shift.y*int1) div linewidth1; //axial + sy1:= (li.v.shift.x*int1) div linewidth1; + sx2:= (li.v.shift.x*po2^) div arcscalefact; //orthogonal + sy2:= (li.v.shift.y*po2^) div arcscalefact; + if li.reverse then begin + sx2:= -sx2; + sy2:= -sy2; + end; + po1^.x:= pt1.x - sx1 - sx2; //2 + po1^.y:= pt1.y - sy1 + sy2; + inc(po1); + if not first then begin + po1^:= (po1-2)^; //3 + inc(po1); + po1^:= (po1-2)^; //4 + inc(po1); + end; + po1^.x:= pt2.x - sx1 + sx2; //5 + po1^.y:= pt2.y - sy1 - sy2; + inc(po1); + dec(po2); + first:= false; + end; + if not first then begin + po1^:= (po1-2)^; //0 + inc(po1); + po1^:= (po1-2)^; //1 + inc(po1); + po1^:= pt1; //2 + inc(po1); + po1^:= (po1-2)^; //3 + inc(po1); + end; + po1^:= pt1; //4 + inc(po1); + po1^:= pt2; //5 + inc(po1); + po1^:= pt1; //0 + inc(po1); + po1^:= pt2; //1 + inc(po1); + li.dest:= po1; + end; + end; +end; + +procedure updatestarttria(var drawinfo: drawinfoty; var li: lineshiftinfoty); +var + sx1,sy1: integer; +begin + with triagcty(drawinfo.gc.platformdata).d do begin + if (linewidth = 0) or (trf_capprojecting in triaflags) then begin + sx1:= li.v.shift.y div 2 - li.offsy; + sy1:= li.v.shift.x div 2 - li.offsx; + with (li.dest-2)^ do begin + x:= x - sx1; + y:= y - sy1; + end; + with (li.dest-1)^ do begin + x:= x - sx1; + y:= y - sy1; + end; + end + else begin + if trf_capround in triaflags then begin + roundcapstarttria(drawinfo,li); + end; + end; + end; +end; + +procedure roundcapstartstrip(var drawinfo: drawinfoty; var li: lineshiftinfoty); +var + sx1,sy1,sx2,sy2: integer; + int1: integer; + po1: ppointty; + po2: pbyte; + pt1,pt2: pointty; +begin + with triagcty(drawinfo.gc.platformdata).d do begin + po1:= li.dest; + dec(po1); + pt2:= (po1)^; + dec(po1); + pt1:= (po1)^; + if linewidth <= arctablesize then begin + sx1:= (li.v.shift.y) div 2; //axial + sy1:= (li.v.shift.x) div 2; + po1^.x:= (pt1.x + pt2.x) div 2 - sx1; + po1^.y:= (pt1.y + pt2.y) div 2 - sy1; + inc(po1); + po2:= @arctable[linewidth]; + inc(po2,linewidth1 div 2 - 2); + for int1:= linewidth div 2 - 1 downto 1 do begin + sx1:= (li.v.shift.y*int1) div linewidth1; //axial + sy1:= (li.v.shift.x*int1) div linewidth1; + sx2:= (li.v.shift.x*po2^) div arcscalefact; //orthogonal + sy2:= (li.v.shift.y*po2^) div arcscalefact; + if li.reverse then begin + sx2:= -sx2; + sy2:= -sy2; + end; + po1^.x:= pt1.x - sx1 - sx2; + po1^.y:= pt1.y - sy1 + sy2; + inc(po1); + po1^.x:= pt2.x - sx1 + sx2; + po1^.y:= pt2.y - sy1 - sy2; + inc(po1); + dec(po2); + end; + po1^:= pt1; + inc(po1); + po1^:= pt2; + inc(po1); + li.dest:= po1; + end; + end; +end; + +procedure updatestartstrip(var drawinfo: drawinfoty; var li: lineshiftinfoty); +var + sx1,sy1: integer; +begin + with triagcty(drawinfo.gc.platformdata).d do begin + if (linewidth = 0) or (trf_capprojecting in triaflags) then begin + sx1:= li.v.shift.y div 2 - li.offsy; + sy1:= li.v.shift.x div 2 - li.offsx; + with (li.dest-2)^ do begin + x:= x - sx1; + y:= y - sy1; + end; + with (li.dest-1)^ do begin + x:= x - sx1; + y:= y - sy1; + end; + end + else begin + if trf_capround in triaflags then begin + roundcapstartstrip(drawinfo,li); + end; + end; + end; +end; + +procedure updateendtria(var drawinfo: drawinfoty; var li: lineshiftinfoty); +var + sx1,sy1,sx2,sy2: integer; + int1: integer; + po1: ppointty; + po2: pbyte; + pt1,pt2: pointty; +begin + with triagcty(drawinfo.gc.platformdata).d do begin + if (linewidth = 0) or (trf_capprojecting in triaflags) then begin + sx1:= li.v.shift.y div 2 + li.offsy; + sy1:= li.v.shift.x div 2 + li.offsx; + with (li.dest-2)^ do begin + x:= x + sx1; + y:= y + sy1; + end; + with (li.dest-1)^ do begin + x:= x + sx1; + y:= y + sy1; + end; + end + else begin + if trf_capround in triaflags then begin + if linewidth <= arctablesize then begin + po1:= li.dest; + (po1-4)^:= (po1-2)^; + pt1:= (po1-2)^; + pt2:= (po1-1)^; + po1^:= pt1; + inc(po1); + po1^:= pt2; + inc(po1); + po2:= @arctable[linewidth]; + for int1:= 1 to linewidth div 2 - 1 do begin + sx1:= (li.v.shift.y*int1) div linewidth1; //axial + sy1:= (li.v.shift.x*int1) div linewidth1; + sx2:= (li.v.shift.x*po2^) div arcscalefact; //orthogonal + sy2:= (li.v.shift.y*po2^) div arcscalefact; + if li.reverse then begin + sx2:= -sx2; + sy2:= -sy2; + end; + po1^.x:= pt1.x + sx1 - sx2; //0 + po1^.y:= pt1.y + sy1 + sy2; + inc(po1); + po1^:= (po1-2)^; //1 + inc(po1); + po1^:= (po1-2)^; //2 + inc(po1); + po1^.x:= pt2.x + sx1 + sx2; //3 + po1^.y:= pt2.y + sy1 - sy2; + inc(po1); + po1^:= (po1-2)^; //4 + inc(po1); + po1^:= (po1-2)^; //5 + inc(po1); + inc(po2); + end; + sx1:= (li.v.shift.y) div 2; //axial + sy1:= (li.v.shift.x) div 2; + po1^.x:= (pt1.x + pt2.x) div 2 + sx1; + po1^.y:= (pt1.y + pt2.y) div 2 + sy1; + inc(po1); + li.dest:= po1; + exit; + end; + end; + end; + end; + (li.dest-4)^:= (li.dest-2)^; +end; + +procedure updateendstrip(var drawinfo: drawinfoty; var li: lineshiftinfoty); +var + sx1,sy1,sx2,sy2: integer; + int1: integer; + po1: ppointty; + po2: pbyte; + pt1,pt2: pointty; +begin + with triagcty(drawinfo.gc.platformdata).d do begin + if (linewidth = 0) or (trf_capprojecting in triaflags) then begin + sx1:= li.v.shift.y div 2 + li.offsy; + sy1:= li.v.shift.x div 2 + li.offsx; + with (li.dest-2)^ do begin + x:= x + sx1; + y:= y + sy1; + end; + with (li.dest-1)^ do begin + x:= x + sx1; + y:= y + sy1; + end; + end + else begin + if trf_capround in triaflags then begin + if linewidth <= arctablesize then begin + po1:= li.dest; + pt1:= (po1-2)^; + pt2:= (po1-1)^; + po2:= @arctable[linewidth]; + for int1:= 1 to linewidth div 2 - 1 do begin + sx1:= (li.v.shift.y*int1) div linewidth1; //axial + sy1:= (li.v.shift.x*int1) div linewidth1; + sx2:= (li.v.shift.x*po2^) div arcscalefact; //orthogonal + sy2:= (li.v.shift.y*po2^) div arcscalefact; + if li.reverse then begin + sx2:= -sx2; + sy2:= -sy2; + end; + po1^.x:= pt1.x + sx1 - sx2; + po1^.y:= pt1.y + sy1 + sy2; + inc(po1); + po1^.x:= pt2.x + sx1 + sx2; + po1^.y:= pt2.y + sy1 - sy2; + inc(po1); + inc(po2); + end; + sx1:= (li.v.shift.y) div 2; //axial + sy1:= (li.v.shift.x) div 2; + po1^.x:= (pt1.x + pt2.x) div 2 + sx1; + po1^.y:= (pt1.y + pt2.y) div 2 + sy1; + inc(po1); + li.dest:= po1; + end; + end; + end; + end; +end; + +procedure dashinit(var drawinfo: drawinfoty; var li: lineshiftinfoty); +var + int1: integer; +begin + with drawinfo,triagcty(gc.platformdata).d do begin +// allocbuffer(buffer,3*sizeof(pointty)); //possible first triangle + buffer.cursize:= 0; + li.dest:= buffer.buffer; + li.dashlen:= 0; + for int1:= 1 to length(xftdashes) do begin + li.dashlen:= li.dashlen + ord(xftdashes[int1]); + end; + end; +end; + +procedure dash(var drawinfo: drawinfoty; var li: lineshiftinfoty; + const start: boolean; const endpoint: boolean); +var + po3: ppointty; + pt0: pointty; + dx,dy: integer; + dashstop,dashpos,dashind: integer; + x1,y1: integer; + int1: integer; +begin + with drawinfo,triagcty(gc.platformdata).d do begin + if start then begin + dashpos:= ord(xftdashes[1]); + dashind:= 1; + li.dashref:= 0; + end + else begin + dashpos:= li.dashpos-li.dashref; + dashind:= li.dashind; + end; + dashstop:= li.v.c; + int1:= ((dashstop-dashpos) div li.dashlen + 1)*length(xftdashes) + 3*2; + //+3*2 -> additional memory for ends and vertex + if trf_capround in triaflags then begin + int1:= int1*linewidth1; + end; + int1:= int1 * 6*sizeof(pointty); //2 triangles per segment + extendbuffer(buffer,int1,li.dest); + po3:= li.dest; + pt0.x:= (li.linestart^.x shl 16) + li.offs.x; + pt0.y:= (li.linestart^.y shl 16) + li.offs.y; + dx:= (li.v.d.x shl 16) div li.v.c; + dy:= (li.v.d.y shl 16) div li.v.c; + while dashpos < dashstop do begin + if odd(dashind) then begin //end dash + x1:= pt0.x + dashpos*dx; + y1:= pt0.y + dashpos*dy; + po3^.x:= x1; + po3^.y:= y1; + inc(po3); + po3^:= (po3-2)^; + inc(po3); + po3^.x:= x1; + po3^.y:= y1; + inc(po3); + po3^.x:= x1 - li.v.shift.x; + po3^.y:= y1 + li.v.shift.y; + inc(po3); + li.dest:= po3; + if linewidth <> 0 then begin + updateendtria(drawinfo,li); + po3:= li.dest; + end; + end + else begin //start dash + x1:= pt0.x + dashpos*dx; + y1:= pt0.y + dashpos*dy; + po3^.x:= x1; + po3^.y:= y1; + inc(po3); + po3^.x:= x1 - li.v.shift.x; + po3^.y:= y1 + li.v.shift.y; + inc(po3); + li.dest:= po3; + if linewidth <> 0 then begin + updatestarttria(drawinfo,li); + po3:= li.dest; + end; + end; + inc(dashind); + if dashind > length(xftdashes) then begin + dashind:= 1; + end; + dashpos:= dashpos + ord(xftdashes[dashind]); + end; + if odd(dashind) and endpoint then begin //end dash + x1:= pt0.x + (li.v.d.x shl 16); + y1:= pt0.y + (li.v.d.y shl 16); + po3^.x:= x1; + po3^.y:= y1; + inc(po3); + po3^:= (po3-2)^; + inc(po3); + po3^.x:= x1; + po3^.y:= y1; + inc(po3); + po3^.x:= x1 - li.v.shift.x; + po3^.y:= y1 + li.v.shift.y; + inc(po3); + li.dest:= po3; + if linewidth <> 0 then begin + updateendtria(drawinfo,li); + po3:= li.dest; + end; + end; + li.dest:= po3; + li.dashind:= dashind; + li.dashpos:= dashpos+li.dashref; + li.dashref:= li.dashref+li.v.c; + end; +end; + +function linestria(var drawinfo: drawinfoty; out apoints: ppointty; + out apointcount: integer): boolean; +var + li: lineshiftinfoty; + pt0,pt1,pt3: pointty; + int1,int2: integer; + pointcount: integer; + ints: intersectinfoty; + pend: ppointty; + firstdash,bo1,bo2: boolean; + singlepoint: array[0..1] of pointty; + pointsbefore: ppointty; + pt2: pointty; + po0: ppointty; + +begin + //todo: remove overlapping regions + result:= false; + with drawinfo,points,triagcty(gc.platformdata).d do begin + pointsbefore:= points; + pointcount:= count; + if count = 1 then begin + singlepoint[0]:= points^; + singlepoint[1]:= points^; //dummy segment + points:= @singlepoint[0]; + inc(pointcount); + end; + if closed then begin + inc(pointcount); + end; + pointcount:= pointcount*2; + li.pointa:= points; + pend:= points+count; + li.pointb:= li.pointa+1; + li.dist:= linewidth16; + li.reverse:= false; + if closed then begin + int2:= count-1; + end + else begin + int2:= count-3; + end; + if df_dashed in gc.drawingflags then begin + result:= true; + int1:= (pointcount+linewidth1); //for round caps + if trf_joinround in triaflags then begin + int1:= int1 + linewidth div 2; //round corners + end; + allocbuffer(buffer,int1*2*6*sizeof(pointty)); + dashinit(drawinfo,li); + calclineshift(drawinfo,li,false); + shiftpoint(li); + if (linewidth <> 0) and not closed then begin + updatestarttria(drawinfo,li); + end; + firstdash:= true; //start dash + for int1:= 0 to int2 do begin + if li.pointb = pend then begin + li.pointb:= points; + end; + dash(drawinfo,li,firstdash,false); + firstdash:= false; + if odd(li.dashind) then begin //dash end + inc(li.dest); + li.dest^:= (li.dest-2)^; + inc(li.dest); + shiftpointa(li); + (li.dest-4)^:= (li.dest-2)^; + end; + + ints.da:= li.v.d; + pt2:= li.v.shift; + calclineshift(drawinfo,li,false); + shiftpoint(li); + po0:= li.dest; + ints.db:= li.v.d; + ints.p0:= po0-4; + ints.p1:= po0-2; + pt0:= (li.dest-2)^; + pt1:= (li.dest-1)^; + if trf_joinround in triaflags then begin + if odd(li.dashind) then begin + roundcapstarttria(drawinfo,li); + end; + end + else begin + if intersect(ints) then begin + pt3:= subpoint(ints.isect,ints.p1^); //intersection - bstart + bo1:= ((pt3.x > 0) xor (li.v.d.x > 0)) or ((pt3.y > 0) xor (li.v.d.y > 0)); + //outer, cw + bo2:= (trf_joinbevel in triaflags) or + (trf_joinmiter in triaflags) and isbevelang(li,pt2); + ///bevel + if not bo1 then begin + inc(ints.p0); + inc(ints.p1); + intersect2(ints); + if not bo2 then begin + pt1:= ints.isect; + end; + end + else begin + if not bo2 then begin + pt0:= ints.isect; + end; + end; + if odd(li.dashind) then begin + if bo1 then begin //cw + if bo2 then begin //bevel + po0^:= (po0-4)^; + inc(po0); + po0^:= (po0-3)^; //start next + inc(po0); + po0^:= (po0-3)^; + inc(po0); + end + else begin //mieter + pt0:= ints.isect; + po0^:= pt0; //8 + inc(po0); + po0^:= pt0; //9 + inc(po0); + po0^:= (po0-6)^; //10 + inc(po0); + po0^:= (po0-4)^; //11 + inc(po0); + po0^:= (po0-6)^; //12 + inc(po0); + po0^:= (po0-6)^; //13 + inc(po0); + end; + end + else begin //ccw + if bo2 then begin //bevel + po0^:= (po0-3)^; + inc(po0); + po0^:= (po0-3)^; //start next + inc(po0); + po0^:= (po0-3)^; + inc(po0); + end + else begin //miter + pt1:= ints.isect; + po0^:= pt1; //8 + inc(po0); + po0^:= pt1; //9 + inc(po0); + po0^:= (po0-5)^; //10 + inc(po0); + po0^:= (po0-5)^; //11 + inc(po0); + po0^:= (po0-6)^; //12 + inc(po0); + po0^:= (po0-6)^; //13 + inc(po0); + end; + end; + end; + end; + li.dest:= po0; + end; + if not odd(li.dashind) then begin //no dash + dec(li.dest,2); //remove start + end; + end; + if closed then begin +{$warnings off} + (ppointty(buffer.buffer))^:= pt0; + (ppointty(buffer.buffer)+1)^:= pt1; + (ppointty(buffer.buffer)+3)^:= pt1; + end + else begin + dash(drawinfo,li,firstdash,true); + end; + end + else begin + int1:= 2; //for bevel + if trf_joinround in triaflags then begin + int1:= int1 + (linewidth1+1) div 2; //round corners + end; + int1:= int1*pointcount+linewidth; //for round caps + allocbuffer(buffer,int1*(2*sizeof(pointty))); + li.dest:= buffer.buffer; + calclineshift(drawinfo,li,false); + shiftpoint(li); + if not closed then begin + updatestartstrip(drawinfo,li); + end; + for int1:= 0 to int2 do begin + if li.pointb = pend then begin + li.pointb:= points; + end; + shiftpointa(li); //no source increment + ints.da:= li.v.d; + pt2:= li.v.shift; + if calclineshift(drawinfo,li,true) then begin + shiftpoint(li); + ints.db:= li.v.d; + ints.p0:= li.dest-4; + ints.p1:= li.dest-2; + if intersect(ints) then begin + if trf_joinround in triaflags then begin + roundcapstartstrip(drawinfo,li); + ints.p1:= li.dest-1; + end + else begin + pt1:= subpoint(ints.isect,ints.p1^); //intersection - bstart + bo1:= ((pt1.x > 0) xor (li.v.d.x > 0)) or + ((pt1.y > 0) xor (li.v.d.y > 0)); //outer + bo2:= (trf_joinbevel in triaflags) or + (trf_joinmiter in triaflags) and isbevelang(li,pt2); + if bo1 and not bo2 then begin //move to intersection + ints.p1^:= ints.isect; + (ints.p1-2)^:= ints.isect; + end; + inc(ints.p0); + inc(ints.p1); + intersect2(ints); + if not bo1 and not bo2 then begin //move to intersection + ints.p1^:= ints.isect; + (ints.p1-2)^:= ints.isect; + end; + end; + end; + end + else begin //zero length line + dec(li.dest,2); + li.pointa:= li.pointb; + inc(li.pointb); + end; + end; + if closed then begin + (ppointty(buffer.buffer))^:= (ints.p1-1)^; + (ppointty(buffer.buffer)+1)^:= ints.p1^; + end + else begin + shiftpoint(li); + updateendstrip(drawinfo,li); + end; + end; + points:= pointsbefore; + apoints:= buffer.buffer; + apointcount:= li.dest-ppointty(buffer.buffer); + end; +end; +{$warnings on} +procedure linesegmentstria(var drawinfo: drawinfoty; + out atriangles: ptrianglety; out atrianglecount: integer); +var + int1: integer; + li: lineshiftinfoty; +begin + with drawinfo,drawinfo.points,triagcty(gc.platformdata).d do begin + li.pointa:= points; + li.pointb:= li.pointa+1; + li.dist:= linewidth16; + li.reverse:= false; + allocbuffer(buffer,count*(6+6*linewidth1)*sizeof(pointty)); + //for round caps + if df_dashed in gc.drawingflags then begin + dashinit(drawinfo,li); + for int1:= 0 to (count div 2)-1 do begin + calclineshift(drawinfo,li,false); + shiftpoint(li); + if linewidth <> 0 then begin + updatestarttria(drawinfo,li); + end; + dash(drawinfo,li,true,true); + li.pointa:= li.pointb; + inc(li.pointb); + end; + end + else begin + li.dest:= buffer.buffer; + for int1:= 0 to (count div 2)-1 do begin + calclineshift(drawinfo,li,false); + shiftpoint(li); + updatestarttria(drawinfo,li); + inc(li.dest); + li.dest^:= (li.dest-2)^; + inc(li.dest); + shiftpoint(li); + updateendtria(drawinfo,li); +// (li.dest-4)^:= (li.dest-2)^; + end; + end; + atriangles:= buffer.buffer; + atrianglecount:= (li.dest-ppointty(buffer.buffer)) div 3; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/graphics/msepolytria.pas b/mseide-msegui/lib/common/graphics/msepolytria.pas new file mode 100644 index 0000000..98abf49 --- /dev/null +++ b/mseide-msegui/lib/common/graphics/msepolytria.pas @@ -0,0 +1,1793 @@ +{ MSEgui Copyright (c) 2013-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msepolytria; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msegraphics,msegraphutils,msetriaglob; + +procedure polytria(var drawinfo: drawinfoty; out atriangles: ptrianglety; + out trianglecount: integer); + +{$ifdef mse_debugpolytria1} +type + trapdispinfoty = array[0..3] of pointty; + trity = record + p: array[0..2] of pointty; + end; + triarty = array of trity; + mountaininfoty = record + chain: pointarty; + end; + mountaininfoarty = array of mountaininfoty; +var + debugtraps: array of trapdispinfoty; + debugtriangles: triarty; + debugmountains: mountaininfoarty; + debugdiags: segmentarty; +{$endif} + +{$ifdef mse_debugpolytria} +var + debugstop: integer = -1; //stop at segment n + debugnoa: boolean; //do not handle point a of segment + debugnob: boolean; //do not handle point b of segment + debugnoseg: boolean; //do not handle segment + debugnosegsplit: boolean; //not handle segsplit + debugdumperror: boolean; + +{$endif} + +implementation +uses + msetypes,msenoise + {$ifdef mse_debugpolytria} + ,mseformatstr,sysutils,msearrayutils,msesysutils + {$endif}; + +type + trapnodekindty = (tnk_y,tnk_x,tnk_trap); + segdirty = (sd_none,sd_same,sd_up,sd_down,sd_left,sd_right); + xposty = (xp_left,xp_center,xp_right); + + + ptrapinfoty = ^trapinfoty; + pseginfoty = ^seginfoty; + ptrapnodeinfoty = ^trapnodeinfoty; + + trapinfoty = record + top,bottom: ppointty; + left,right: pseginfoty; + node: ptrapnodeinfoty; + above,abover,below,belowr: ptrapinfoty; //above,below = single or left + end; + + segflagty = (sf_pointhandled,sf_reverse); //sf_reverse -> b below a + segflagsty = set of segflagty; + ppseginfoty = ^pseginfoty; + segheaderty = record + previous: pseginfoty; + next: pseginfoty; + b: ppointty; //a is in previous segment + end; + seginfoty = record + h: segheaderty; + flags: segflagsty; + dx,dy: integer; //a-b + trap: ptrapinfoty; //inserted trap for b + splitseg: pseginfoty; //segment for horizontal split at b + diags: array[0..2] of pseginfoty; + end; + + trapnodeinfoty = record + p,l,r: ptrapnodeinfoty; //parent,left,right + case kind: trapnodekindty of + tnk_y: (y: ppointty); + tnk_x: (seg: pseginfoty); + tnk_trap: (trap: ptrapinfoty); + end; + + pmountainpointty = ^mountainpointty; + mountainpointty = record + p: ppointty; + prev: pmountainpointty; + next: pmountainpointty; + end; +const + trapcountfact = 4; //todo: check maximal buffer size + nodecountfact = 8; + mountaincountfact = 1; + trianglecountfact = 1; + trapsize = sizeof(trapinfoty)*trapcountfact; + trapnodesize = sizeof(trapnodeinfoty)*nodecountfact; + mountainsize = (3 * sizeof(mountainpointty)) * mountaincountfact; + //worst case + trianglesize = sizeof(trianglety) * trianglecountfact; + firstsize = trapsize+trapnodesize; + secondsize = mountainsize+trianglesize; +{$if secondsize > firstsize} + {$error 'mountain-triangles memory overflow'} +{$endif} + +{$ifdef mse_debugpolytria1} +function calcx(const y: integer; const seg: seginfoty): integer; +var + int1: integer; +begin + with seg do begin + if dy = 0 then begin + int1:= y - h.b^.y; + if int1 > 0 then begin + result:= bigint; + end + else begin + if int1 = 0 then begin + result:= h.b^.x; + exit; + end + else begin + result:= -bigint; + end; + end; + result:= result * dx; + end + else begin + result:= h.b^.x + (y - h.b^.y) * dx div dy; + end; + end; +end; +{$endif} + +{$ifdef mse_debugpolytria} +type + trapdumpinfoty = record + t: ptrapinfoty; + index: integer; + end; + +function calcx(const seg: pseginfoty; const y: integer): integer; +begin + with seg^ do begin + if dy = 0 then begin + result:= bigint; + if y < seg^.h.b^.y then begin + result:= -bigint; + end; + result:= result*dx; + end + else begin + result:= h.b^.x + ((y - h.b^.y)*dx) div dy; + end; + end; +end; + +function cmptrap(const l,r): integer; +var + y: integer; +begin + result:= 0; + y:= 0; + if trapdumpinfoty(l).t^.top = nil then begin + if trapdumpinfoty(r).t^.top <> nil then begin + result:= -1; + end; + end + else begin + if trapdumpinfoty(r).t^.top = nil then begin + result:= 1; + end + else begin + y:= trapdumpinfoty(r).t^.top^.y; + result:= trapdumpinfoty(l).t^.top^.y - y; + if result = 0 then begin + result:= trapdumpinfoty(l).t^.top-trapdumpinfoty(r).t^.top; + end; + end; + end; + if result = 0 then begin + if trapdumpinfoty(l).t^.left = nil then begin + if trapdumpinfoty(r).t^.left <> nil then begin + result:= -1; + end; + end + else begin + if trapdumpinfoty(r).t^.left = nil then begin + result:= 1; + end + else begin + result:= calcx(trapdumpinfoty(l).t^.left,y) - + calcx(trapdumpinfoty(r).t^.left,y); + if result = 0 then begin + if trapdumpinfoty(r).t^.right = nil then begin + result:= -1; + end; + if trapdumpinfoty(l).t^.right = nil then begin + inc(result); + end; + end; + end; + end; + end; +end; + +function intvalx(const value: integer): string; +begin + if value <= -10000 then begin + result:= ' <'; + end + else begin + if value >= 10000 then begin + result:= ' >'; + end + else begin + result:= rstring(inttostr(value),5); + end; + end; +end; + +function intvaly(const value: integer): string; +begin + if value <= -10000 then begin + result:= ' ^'; + end + else begin + if value >= 10000 then begin + result:= ' v'; + end + else begin + result:= rstring(inttostr(value),5); + end; + end; +end; + +function pointval(const x,y: integer): string; +begin + result:= intvalx(x)+':'+intvaly(y)+' '; +end; //pointval + +function pointval(const apoint: ppointty): string; +begin + result:= intvalx(apoint^.x)+':'+intvaly(apoint^.y)+' '; +end; //pointval + + +procedure dumpnodes(const anodes: ptrapnodeinfoty; + const atraps: ptrapinfoty; const asegments: pseginfoty); +type + levelsty = array[0..255] of boolean; +var + level: integer; + levels: levelsty; + + procedure dump(const n: ptrapnodeinfoty; const lline,rline: boolean); + var + int1: integer; + begin + if n <> nil then begin + inc(level); + if n^.kind <> tnk_trap then begin + levels[level-1]:= lline; + dump(n^.l,false,true); + end; + for int1:= 0 to level-2 do begin + if levels[int1] then begin + debugwrite('|'); + end + else begin + debugwrite(' '); + end; + end; + debugwrite('+'); + case n^.kind of + tnk_trap: begin + debugwriteln('('+inttostr(n^.trap-atraps)+')$'+hextostr(ptruint(n))); + end; + tnk_x: begin + debugwriteln('X='+inttostr(n^.seg-asegments)); + end; + tnk_y: begin + debugwriteln('Y='+inttostr(n^.y^.y)); + end; + end; + if n^.kind <> tnk_trap then begin + levels[level-1]:= rline; + dump(n^.r,true,false); + end; + dec(level); + levels[level]:= false; + end; + end; +begin + level:= 0; + dump(anodes,false,false); +end; + +function trapval(const atrap: ptrapinfoty; const atraps: ptrapinfoty): string; +begin + if atrap = nil then begin + result:= 'NIL'; + end + else begin + result:= rstring(inttostr(atrap-atraps),3); + end; +end; //trapval + +procedure dumpseg(const seg: pseginfoty; const asegments: pseginfoty; + const anpoints: integer; + const atraps: ptrapinfoty); +var + seg1: pseginfoty; +begin +// debugwriteln('********************************'); + debugwriteln(' S A B Atr Asp Brt Bsp'); + seg1:= seg-1; + if seg1 < asegments then begin + inc(seg1,anpoints); + end; + debugwriteln(rstring(inttostr(seg-asegments),3)+ + pointval(seg1^.h.b)+' '+pointval(seg^.h.b)+' '+ + trapval(seg1^.trap,atraps)+' '+trapval(nil,atraps)+' '+ + trapval(seg^.trap,atraps)+' '+trapval(nil,atraps)+' '); +end; + +procedure dumptraps(const atraps: ptrapinfoty; const acount: integer; + const asegments: pseginfoty; const anpoints: integer; + const caption: string; const noerr: boolean); +var + ar1: array of trapdumpinfoty; + ar2: integerarty; + + function trapval(const atrap: ptrapinfoty): string; + begin + if atrap = nil then begin + result:= 'NIL'; + end + else begin + result:= rstring(inttostr(atrap-atraps),3); + end; + end; //trapval + + procedure getpoints(const seg: pseginfoty; out top,bottom: ppointty); + var + seg1: pseginfoty; + begin + top:= nil; + bottom:= nil; + if seg <> nil then begin + seg1:= seg-1; + if seg1 < asegments then begin + inc(seg1,anpoints); + end; + if sf_reverse in seg^.flags then begin + top:= seg^.h.b; + bottom:= seg1^.h.b; + end + else begin + top:= seg1^.h.b; + bottom:= seg^.h.b; + end; + end; + end; //getpoints + +type + pointposty = (pp_none,pp_left,pp_right,pp_both); + + function pointpos(const p: ppointty; + const left,right: ppointty): pointposty; + begin + result:= pp_none; + if p = left then begin + result:= pp_left; + if p = right then begin + result:= pp_both; + end; + end + else begin + if p = right then begin + result:= pp_right; + end; + end; + end; //pointpos + + function pointpostop(const trap: ptrapinfoty): pointposty; + var + lefttop,leftbottom,righttop,rightbottom: ppointty; + begin + with trap^ do begin + getpoints(left,lefttop,leftbottom); + getpoints(right,righttop,rightbottom); + result:= pointpos(top,lefttop,righttop); + end; + end; + + function pointposbottom(const trap: ptrapinfoty): pointposty; + var + lefttop,leftbottom,righttop,rightbottom: ppointty; + begin + with trap^ do begin + getpoints(left,lefttop,leftbottom); + getpoints(right,righttop,rightbottom); + result:= pointpos(bottom,leftbottom,rightbottom); + end; + end; + +var + error: boolean; + + procedure seterror; + begin + if not noerr then begin + error:= true; + end; + end; + +var + int1: integer; + lt,lb,rt,rb,t,b: integer; + toterror: boolean; + trap1: ptrapinfoty; + +begin + setlength(ar1,acount); + for int1:= 0 to high(ar1) do begin + ar1[int1].t:= atraps+int1; + ar1[int1].index:= int1; + end; + sortarray(ar1,sizeof(trapdumpinfoty),@cmptrap,ar2); + debugwriteln('------------------------------------------------------- '+caption); + debugwriteln(' T t b tl tr bl br A AR B BR'); + toterror:= false; + for int1:= 0 to high(ar1) do begin + trap1:= ar1[int1].t; + with trap1^ do begin + lt:= -10000; + lb:= -10000; + t:= -10000; + rt:= 10000; + rb:= 10000; + b:= 10000; + if top <> nil then begin + t:= top^.y; + end; + if bottom <> nil then begin + b:= bottom^.y; + end; + if left <> nil then begin + lt:= calcx(left,t); + lb:= calcx(left,b); + end; + if right <> nil then begin + rt:= calcx(right,t); + rb:= calcx(right,b); + end; + debugwrite(rstring(inttostr(ar1[int1].index),3)+' '+ + intvaly(t)+' '+intvaly(b)+' '+ + intvalx(lt)+' '+intvalx(rt)+' '+intvalx(lb)+' '+intvalx(rb)+' '+ + trapval(above)+' '+trapval(abover)+' '+ + trapval(below)+' '+trapval(belowr)); + error:= false; + + if above <> nil then begin + case pointpostop(trap1) of + pp_left: begin + case pointposbottom(above) of + pp_left: begin + if (above^.below <> trap1) or (above^.belowr <> nil) then begin + seterror; + end; + end; + pp_none: begin + if (above^.belowr <> trap1) or (above^.below = trap1) then begin + seterror; + end; + end; + else begin + seterror; + end; + end; + end; + pp_right: begin + case pointposbottom(above) of + pp_right: begin + if (above^.below <> trap1) or (above^.belowr <> nil) then begin + seterror; + end; + end; + pp_none: begin + if (above^.below <> trap1) or (above^.belowr = trap1) then begin + seterror; + end; + end; + else begin + seterror; + end; + end; + end; + pp_none: begin + case pointposbottom(above) of + pp_right: begin + if (abover = nil) or (abover^.below <> trap1) then begin + seterror; + end; + end; + pp_none: begin + if (above^.below <> trap1) or (above^.belowr <> nil) then begin + seterror; + end; + end; + end; + end; + end; + if abover <> nil then begin + case pointpostop(trap1) of + pp_none: begin + if (abover^.below <> trap1) or (abover^.belowr <> nil) then begin + seterror; + end; + end; + else begin + seterror; + end; + end; + end; + end + else begin + if abover <> nil then begin + seterror; + end; + end; + + if below <> nil then begin + case pointposbottom(trap1) of + pp_left: begin + case pointpostop(below) of + pp_left: begin + if (below^.above <> trap1) or (below^.abover <> nil) then begin + seterror; + end; + end; + pp_none: begin + if (below^.abover <> trap1) or (below^.above = nil) then begin + seterror; + end; + end; + else begin + seterror; + end; + end; + end; + pp_right: begin + case pointpostop(below) of + pp_right: begin + if (below^.above <> trap1) or (below^.abover <> nil) then begin + seterror; + end; + end; + pp_none: begin + if (below^.above <> trap1) or (below^.abover = nil) then begin + seterror; + end; + end; + else begin + seterror; + end; + end; + end; + pp_none: begin + case pointpostop(below) of + pp_right,pp_none: begin + if (below^.above <> trap1) or (below^.abover <> nil) then begin + seterror; + end; + end; + else begin + seterror; + end; + end; + end; + end; + if belowr <> nil then begin + case pointposbottom(trap1) of + pp_none: begin + case pointpostop(belowr) of + pp_left: begin + if (belowr^.above <> trap1) or (belowr^.abover <> nil) then begin + seterror; + end; + end; + else begin + seterror; + end; + end; + end; + else begin + seterror; + end; + end; + end; + end + else begin + if belowr <> nil then begin + seterror; + end; + end; + if error then begin + debugwriteln(' *'); + toterror:= true; + end + else begin + debugwriteln(''); + end; + end; + end; + if toterror then begin + debugwriteln(' ***error***'); + debugdumperror:= true; + end; +end; + +procedure dump(const atraps: ptrapinfoty; const ntraps: integer; + const asegments: pseginfoty; const anpoints: integer; + const anodes: ptrapnodeinfoty; const caption: string; + const noerr: boolean); +begin + debugdumperror:= false; + dumptraps(atraps,ntraps,asegments,anpoints,caption,noerr); + debugwriteln(''); + dumpnodes(anodes,atraps,asegments); +end; +{$endif mse_debugpolytria} + +procedure polytria(var drawinfo: drawinfoty; out atriangles: ptrianglety; + out trianglecount: integer); + +// x,y range = $7fff..-$8000 (16 bit X11 space) +var + points: ppointty; + npoints: integer; + traps: ptrapinfoty; + nodes: ptrapnodeinfoty; + segments: pseginfoty; + shuffle: ppseginfoty; + newtraps: ptrapinfoty; + newnodes: ptrapnodeinfoty; + + function newtrap: ptrapinfoty; + begin + result:= newtraps; + inc(newtraps); + result^.above:= nil; + result^.abover:= nil; + result^.below:= nil; + result^.belowr:= nil; + result^.node:= nil; + end; + + function newnode: ptrapnodeinfoty; + begin + result:= newnodes; + inc(newnodes); + end; + + function isbelow(const l,r: ppointty): boolean; //true if l beow r + var + int1: integer; + begin + int1:= l^.y - r^.y; + if int1 = 0 then begin + result:= l - r >= 0; + end + else begin + result:= int1 >= 0; + end; + end; //isbelow + + function xdist(const point: ppointty; ref: pseginfoty): integer; + var + int1: integer; + begin + if ref^.dy = 0 then begin + result:= point^.y - ref^.h.b^.y; + if result = 0 then begin + if ref = segments then begin + int1:= npoints-1; + end + else begin + int1:= 1; + end; + if not (sf_reverse in ref^.flags) then begin + int1:= -int1; + end; + result:= int1*(point^.x - ref^.h.b^.x) - (point-ref^.h.b)*ref^.dx; + if not (sf_reverse in ref^.flags) then begin + result:= -result; + end; + end + else begin + if not (sf_reverse in ref^.flags) then begin //?????? + result:= -result; + end; + end; + end + else begin + // result:= point^.x -(ref^.h.b^.x + (point^.y-ref^.h.b^.y)*ref^.dx div ref^.dy); + result:= ref^.dy*(point^.x - ref^.h.b^.x) - (point^.y-ref^.h.b^.y)*ref^.dx; + if ref^.dy < 0 then begin + result:= -result; + end; + end; + end; + + function isright(const point: ppointty; ref: pseginfoty): boolean; + //true if point right of segment + begin + // result:= xpos(point,ref) = xp_right; + result:= xdist(point,ref) >= 0; + end; + + function segdirdown(const seg,ref: pseginfoty): segdirty; + var + segcommon: pseginfoty; + ptseg,ptref: ppointty; + begin + if seg = ref then begin + result:= sd_same; + end + else begin + segcommon:= seg^.h.previous; + if segcommon = ref then begin + ptseg:= seg^.h.b; + ptref:= ref^.h.previous^.h.b; + end + else begin + segcommon:= ref^.h.previous; + if segcommon = seg then begin + ptseg:= seg^.h.previous^.h.b; + ptref:= ref^.h.b; + end + else begin + result:= sd_none; + exit; + end; + end; + if isbelow(segcommon^.h.b,ptseg) then begin + result:= sd_up; + end + else begin + result:= sd_left; + if ptseg^.x = ptref^.x then begin + if isbelow(ptseg,ptref) then begin + result:= sd_right; + end; + end + else begin + if seg^.dy = 0 then begin + if ref^.dy = 0 then begin + if ptref^.x-segcommon^.h.b^.x < 0 then begin + if ptseg^.x-segcommon^.h.b^.x > 0 then begin + result:= sd_right; + end + else begin + if isbelow(ptseg,ptref) then begin + result:= sd_right; + end; + end; + end + else begin + if ptseg^.x-segcommon^.h.b^.x > 0 then begin + if isbelow(ptref,ptseg) then begin + result:= sd_right; + end; + end; + end; + end + else begin + if ptseg^.x-segcommon^.h.b^.x >= 0 then begin + result:= sd_right; + end; + end; + end + else begin + if ref^.dy = 0 then begin + if ptref^.x-segcommon^.h.b^.x < 0 then begin + result:= sd_right; + end; + end + else begin + if (seg^.dx*ref^.dy < ref^.dx*seg^.dy) xor + not((sf_reverse in ref^.flags) xor (sf_reverse in seg^.flags)) then begin + // not((ref^.dy < 0) xor (seg^.dy < 0)) then begin + //direction of one segment reversed + result:= sd_right; + end; + end; + end; + end; + end; + end; + end; + + function angdelta(const a,b,c: pointty): integer; + //>0 -> ccw, a.y <= b.y <= c.y + var + dx1,dy1,dx2,dy2: integer; + + procedure calctandiff; + begin + dy1:= b.y - a.y; + dy2:= c.y - b.y; + result:= dx2*dy1 - dx1*dy2; //y is top-down + end; //calctandiff + + begin + result:= 0; + dx1:= b.x - a.x; + dx2:= c.x - b.x; + if dx1 >= 0 then begin + if dx2 < 0 then begin + if c.y-a.y < 0 then begin + result:= 1; + end + else begin + result:= -1; + end; + end + else begin + calctandiff; + end; + end + else begin + if dx2 > 0 then begin + if c.y-a.y < 0 then begin + result:= -1; + end + else begin + result:= 1; + end; + end + else begin + calctandiff; + end; + end; + end; //angdelta + +var + toptrap: ptrapinfoty = nil; + + procedure finddiags; + + function checkdiag(const atrap: ptrapinfoty; const up: boolean): boolean; + //false if error or triangle + var + topseg,bottomseg,lefta,righta: pseginfoty; + begin + result:= true; + with atrap^ do begin + if (atrap = nil) or (left = nil) or (right = nil) or + (top = nil) or (bottom = nil) then begin //segment crossing + result:= false; + exit; + end; + lefta:= left^.h.previous; + righta:= right^.h.previous; + if (left = righta) and (up xor (left^.h.b = bottom)) or + (right = lefta) and (up xor (right^.h.b = bottom)) then begin //triangle + result:= false; + end; + if not((top = left^.h.b) and (bottom = lefta^.h.b) or + (bottom = left^.h.b) and (top = lefta^.h.b) or + (top = right^.h.b) and (bottom = righta^.h.b) or + (bottom = right^.h.b) and (top = righta^.h.b)) then begin + topseg:= segments+(top-points); + bottomseg:= segments+(bottom-points); + with topseg^ do begin + if diags[0] <> nil then begin + if diags[1] <> nil then begin + diags[2]:= bottomseg; + end + else begin + diags[1]:= bottomseg; + end; + end + else begin + diags[0]:= bottomseg; + end; + end; + with bottomseg^ do begin + if diags[0] <> nil then begin + if diags[1] <> nil then begin + diags[2]:= topseg; + end + else begin + diags[1]:= topseg; + end; + end + else begin + diags[0]:= topseg; + end; + end; + end; + end; + end; //checkdiag + + procedure findup(const atrap: ptrapinfoty); forward; + + procedure finddown(const atrap: ptrapinfoty); + var + tr1: ptrapinfoty; + begin + tr1:= atrap; + while checkdiag(tr1,false) do begin + with tr1^ do begin + if belowr <> nil then begin + finddown(belowr); + end; + if below^.above = tr1 then begin + if below^.abover <> nil then begin + findup(below^.abover); + end; + end + else begin + findup(below^.above); + end; + tr1:= below; + end; + end; + end; //finddown + + procedure findup(const atrap: ptrapinfoty); + var + tr1: ptrapinfoty; + begin + tr1:= atrap; + while checkdiag(tr1,true) do begin + with tr1^ do begin + if abover <> nil then begin + findup(abover); + end; + if above^.below = tr1 then begin + if above^.belowr <> nil then begin + finddown(above^.belowr); + end; + end + else begin + finddown(above^.below); + end; + tr1:= above; + end; + end; + end; //findup + + begin + finddown(toptrap); + end; //finddiags + + function newnode(const atrap: ptrapinfoty; + const aparent: ptrapnodeinfoty): ptrapnodeinfoty; + begin + result:= newnodes; + inc(newnodes); + result^.kind:= tnk_trap; + result^.trap:= atrap; + result^.p:= aparent; + atrap^.node:= result; + end; //newnode + + function findtrap(const apoint,second: ppointty): ptrapinfoty; + //second used if apoint is on edge + var + no1,no2: ptrapnodeinfoty; + int1: integer; + begin + {$ifdef mse_debugpolytria} + debugwrite('Search '+inttostr(apoint^.x)+':'+inttostr(apoint^.y)); + {$endif} + no1:= nodes; + while true do begin + no2:= no1^.l; + case no1^.kind of + tnk_trap: begin + result:= no1^.trap; + break; + end; + tnk_y: begin + if isbelow(apoint,no1^.y) then begin + no2:= no1^.r; + end; + end; + tnk_x: begin + int1:= xdist(apoint,no1^.seg); + if int1 = 0 then begin + int1:= xdist(second,no1^.seg); + end; + if int1 > 0 then begin + no2:= no1^.r; + end; + end; + end; + no1:= no2; + end; +{$ifdef mse_debugpolytria} + debugwriteln(' found trap '+inttostr(result-traps)); +{$endif} + end; //findtrap + + procedure handlepoint(const seg: pseginfoty); + var + tplower,tpupper,tpbelow,tpbelowr: ptrapinfoty; + no1,nol,nor: ptrapnodeinfoty; + ppt1: ppointty; + begin + ppt1:= seg^.h.b; + tpupper:= findtrap(ppt1,ppt1); + tplower:= newtrap; //split trap, lower + tplower^.top:= ppt1; + tplower^.bottom:= tpupper^.bottom; + tpupper^.bottom:= ppt1; //upper + tplower^.left:= tpupper^.left; //same segment + tplower^.right:= tpupper^.right; //same segment + tplower^.below:= tpupper^.below; //same below + tplower^.belowr:= tpupper^.belowr;//same belowr + tplower^.above:= tpupper; //abover = nil + tpbelow:= tpupper^.below; + tpbelowr:= tpupper^.belowr; + if tpbelow <> nil then begin + if tpbelow^.above = tpupper then begin + tpbelow^.above:= tplower; + end; + if tpbelow^.abover = tpupper then begin + tpbelow^.abover:= tplower; + end; + if tpbelowr <> nil then begin + if tpbelowr^.above = tpupper then begin + tpbelowr^.above:= tplower; + end; + if tpbelowr^.abover = tpupper then begin + tpbelowr^.abover:= tplower; + end; + end; + end; + tpupper^.below:= tplower; + tpupper^.belowr:= nil; //no split segment + seg^.trap:= tplower; + + no1:= tpupper^.node; //old leaf + nol:= newnode(tpupper,no1); //new leaf + nor:= newnode(tplower,no1); //new leaf + no1^.l:= nol; + no1^.r:= nor; + no1^.kind:= tnk_y; + no1^.y:= ppt1; + + include(seg^.flags,sf_pointhandled); + end; //handlepoint + +var + segcounter: integer; + + procedure handlesegment(const aseg: pseginfoty); + + procedure splitnode(const newright: boolean; const ltrap,rtrap: ptrapinfoty); + var + noabove,noleft,noright: ptrapnodeinfoty; + begin + if newright then begin + noabove:= ltrap^.node; + noleft:= newnode(ltrap,noabove); + noright:= rtrap^.node; + if noright = nil then begin //new trap + noright:= newnode(rtrap,noabove); + end; + end + else begin + noabove:= rtrap^.node; + noright:= newnode(rtrap,noabove); + noleft:= ltrap^.node; + if noleft = nil then begin //new trap + noleft:= newnode(ltrap,noabove); + end; + end; + with noabove^ do begin + l:= noleft; // (Tb) -> (s) + r:= noright; // (Tl) (Tr) + kind:= tnk_x; + seg:= aseg; + end; + end; //splitnode horz + + var + bottompoint: ppointty; + + procedure updatebelow(const newright: boolean; const trold,trnew: ptrapinfoty); + var + aisright: boolean; + seg1: pseginfoty; + begin + if trold^.below = nil then begin + exit; //crossing + end; + + if newright then begin + seg1:= trold^.right; + end + else begin + seg1:= trold^.left; + end; + if trold^.below^.top = bottompoint then begin //last + if trold^.belowr <> nil then begin //existing segment below + if newright then begin + trnew^.below:= trold^.belowr; + trnew^.below^.above:= trnew; + end + else begin + trnew^.below:= trold^.below; + trold^.below^.above:= trnew; + trold^.below:= trold^.belowr; + end; + trold^.belowr:= nil; + trnew^.belowr:= nil; + end + else begin + if trold^.below^.abover <> nil then begin //existing segment above + trnew^.below:= trold^.below; + if (trold^.below^.above = trold) xor newright then begin + //existing trap is not on new side + if newright then begin + trold^.below^.abover:= trnew; + end + else begin + trold^.below^.above:= trnew; + end; + end; + end + else begin //no existing segment + trnew^.below:= trold^.below; + with trold^.below^ do begin + if newright then begin + abover:= trnew; + end + else begin + above:= trnew; + abover:= trold; + end; + end; + end; + end; + end + else begin //not last + aisright:= isright(trold^.below^.top,seg1); + if trold^.belowr = nil then begin //no existing segment below + trnew^.below:= trold^.below; + with trold^.below^ do begin + if abover = nil then begin //single trap above + if newright then begin + abover:= trnew; + end + else begin + abover:= trold; + above:= trnew; + end; + end + else begin + if aisright then begin + if newright then begin + above:= trnew; + end; + end + else begin + if not newright then begin + abover:= trnew; + end; + end; + end; + end; + end + else begin //existing segment below + if aisright then begin + trnew^.below:= trold^.below; + if newright then begin + trnew^.belowr:= trold^.belowr; + trnew^.below^.above:= trnew; + trold^.belowr^.above:= trnew; + trold^.belowr:= nil; + end; + end + else begin + if newright then begin + trnew^.below:= trold^.belowr; + end + else begin + trnew^.below:= trold^.below; + trnew^.below^.above:= trnew; + trnew^.belowr:= trold^.belowr; + trnew^.belowr^.above:= trnew; + trold^.below:= trold^.belowr; + trold^.belowr:= nil; + end; + end; + end; + end; + end; //updatebelow + + procedure splittrap(const newright: boolean; const old: ptrapinfoty; + var left,right,trnew: ptrapinfoty); + var + trabove: ptrapinfoty; + trabover: ptrapinfoty; + begin + trnew:= newtrap; + trabove:= old^.above; + trabover:= old^.abover; + trnew^.top:= old^.top; + trnew^.bottom:= old^.bottom; + trnew^.left:= old^.left; + trnew^.right:= old^.right; + trnew^.above:= trabove; + if newright then begin + old^.right:= aseg; + trnew^.left:= aseg; + right:= trnew; + left:= old; + old^.abover:= nil; + end + else begin + old^.left:= aseg; + trnew^.right:= aseg; + right:= old; + left:= trnew; + if old^.abover <> nil then begin + old^.above:= old^.abover; + old^.abover:= nil; + end; + end; + updatebelow(newright,old,trnew); + left^.above:= trabove; + if trabover = nil then begin //no existing segment above + right^.above:= trabove; + if newright or (trabove^.belowr = nil) then begin //first segment + trabove^.belowr:= right; + end + else begin + if not newright then begin + trabove^.below:= left; + end; + end; + end + else begin + trabove^.below:= left; + right^.above:= trabover; + trabover^.below:= right; + end; + splitnode(newright,left,right); + end; //splittrap + + var + sd1: segdirty; + sega,segb: pseginfoty; + trap1,trap2,trap1l,trap1r,trbelow,trbelowr,exttrap: ptrapinfoty; + isright1{,bo2}: boolean; + + begin + if sf_reverse in aseg^.flags then begin + sega:= aseg; + segb:= aseg^.h.previous; + end + else begin + segb:= aseg; + sega:= aseg^.h.previous; + end; + bottompoint:= segb^.trap^.top; + if sega^.splitseg = nil then begin //no existing edge + isright1:= false; + splittrap(true,sega^.trap,trap1l,trap1r,trap1); + sega^.splitseg:= aseg; + end + else begin + trap1:= sega^.trap; + sd1:= segdirdown(sega^.splitseg,aseg); + case sd1 of + sd_up: begin //existing edge above + if trap1^.below = nil then begin + exit; //error + end; + isright1:= isright(trap1^.below^.top,aseg); + end; + sd_right: begin + if trap1^.above = nil then begin + exit; //error + end; + trap1:= trap1^.above^.below; + isright1:= true; + if (trap1^.above = traps) then begin + toptrap:= trap1; + end; + end; + else begin + if trap1^.above = nil then begin + exit; //error + end; + trap1:= trap1^.above^.belowr; + isright1:= false; + if (trap1^.above = traps) then begin + toptrap:= trap1; + end; + end; + end; + splittrap(not isright1,trap1,trap1l,trap1r,trap1); + end; + {$ifdef mse_debugpolytria} + dump(traps,newtraps-traps,segments,npoints,nodes,'segment0',true); + if not ((segcounter = debugstop) and debugnosegsplit) then begin + {$endif} + + while trap1^.below <> nil do begin + trap2:= trap1^.below; + if trap2^.top = bottompoint then begin + break; + end; + + isright1:= isright(trap2^.top,aseg); //point right of segment + if (trap1^.belowr <> nil) and not isright1 then begin + trap2:= trap1^.belowr; + end; + trbelow:= trap2^.below; + trbelowr:= trap2^.belowr; + + //split crossed lines by segment + if isright1 then begin + exttrap:= trap1l; + trap2^.left:= aseg; //move edge to right + if trap2^.above = exttrap then begin + trap2^.above:= trap2^.abover; + trap2^.abover:= nil; + end; + trap1l^.bottom:= trap2^.bottom; + trap1r:= trap2; + trap1l^.below:= trbelow; + trap1l^.belowr:= trbelowr; + end + else begin + exttrap:= trap1r; + trap2^.right:= aseg; //move edge to left + if trap2^.abover = exttrap then begin + trap2^.abover:= nil; + end; + trap1l:= trap2; + if trbelowr <> nil then begin + trap1r^.below:= trbelowr; + end + else begin + trap1r^.below:= trbelow; + end; + trap1r^.belowr:= nil; + end; + exttrap^.bottom:= trap2^.bottom; + updatebelow(not isright1,trap2,exttrap); + splitnode(not isright1,trap1l,trap1r); + trap1:= trap2; + end; +{$ifdef mse_debugpolytria} + end; +{$endif} + segb^.splitseg:= aseg; + {$ifdef mse_debugpolytria} + dump(traps,newtraps-traps,segments,npoints,nodes,'segment1',false); + {$endif} + end; + +var + int1,int2: integer; + seg1,seg2: pseginfoty; + sizetraps,sizenodes: integer; + ppt1,ppt2: ppointty; + bo1: boolean; + newmountain: pmountainpointty; + triangles,newtriangle: ptrianglety; + + procedure findmountains(const aseg: pseginfoty; const first: boolean); + var + seg1,seg2: pseginfoty; + int1: integer; + start: pmountainpointty; + rightside,bottomup: boolean; + pttop,ptbottom,pt1,pt2: pmountainpointty; + dy,dx: integer; + searchcount: integer; + begin + start:= newmountain; + seg1:= aseg; + repeat + with seg1^ do begin + newmountain^.prev:= newmountain-1; + newmountain^.next:= newmountain+1; + newmountain^.p:= h.b; + inc(newmountain); + seg2:= nil; + int1:= 0; + if diags[0] <> nil then begin + seg2:= diags[0]; + end; + if (seg2 <> aseg) and ((diags[1] > seg2) or (diags[1] = aseg)) then begin + seg2:= diags[1]; + int1:= 1; + end; + if (seg2 <> aseg) and ((diags[2] > seg2) or (diags[2] = aseg)) then begin + seg2:= diags[2]; + int1:= 2; + end; + if seg2 <> nil then begin + diags[int1]:= nil; //eat + if seg2 <> aseg then begin //new mountain + {$ifdef mse_debugpolytria1} + setlength(debugdiags,high(debugdiags)+2); + with debugdiags[high(debugdiags)] do begin + a:= seg1^.h.b^;; + b:= seg2^.h.b^; + end; + {$endif} + findmountains(seg1,false); + end; + seg1:= seg2; + end + else begin + seg1:= seg1^.h.next; + end; + end; + until seg1 = aseg; + + {$ifdef mse_debugpolytria1} + setlength(debugmountains,high(debugmountains)+2); + with debugmountains[high(debugmountains)] do begin + setlength(chain,newmountain-start); + for int1:= 0 to high(chain) do begin + chain[int1]:= start[int1].p^; + end; + end; + {$endif} + + dec(newmountain); //last + start^.prev:= nil; + newmountain^.next:= nil; + ptbottom:= start; + pttop:= start; + pt1:= start; + repeat + if isbelow(pt1^.p,ptbottom^.p) then begin + ptbottom:= pt1; + end; + if isbelow(pttop^.p,pt1^.p) then begin + pttop:= pt1; + end; + pt1:= pt1^.next; + until pt1 = nil; + start^.prev:= newmountain; + newmountain^.next:= start; + if ptbottom^.next = pttop then begin + ptbottom^.next:= nil; + pttop^.prev:= nil; + end + else begin + pttop^.next:= nil; + ptbottom^.prev:= nil; + end; + if pttop^.p^.y <> ptbottom^.p^.y then begin //not empty + bottomup:= ptbottom^.prev = nil; + if bottomup then begin + pt1:= ptbottom^.next; + end + else begin + pt1:= pttop^.next; + end; + pt2:= pt1; + int1:= 0; + dx:= pttop^.p^.x - ptbottom^.p^.x; + dy:= pttop^.p^.y - ptbottom^.p^.y; //always negative + repeat + int1:= dy*(pt1^.p^.x - pttop^.p^.x) - (pt1^.p^.y-pttop^.p^.y)*dx; + pt1:= pt1^.next; + until (int1 <> 0) or (pt1 = nil); + if int1 <> 0 then begin //not empty + rightside:= int1 < 0; + pt1:= pt2; + bo1:= false; + searchcount:= 0; + while searchcount < 4 do begin //else error + int1:= angdelta(pt1^.prev^.p^,pt1^.p^,pt1^.next^.p^); + if int1 <> 0 then begin //not empty + if (int1 > 0) xor rightside xor bottomup then begin //cut ear + searchcount:= 0; + newtriangle^[0]:= pt1^.prev^.p^; + newtriangle^[1]:= pt1^.p^; + newtriangle^[2]:= pt1^.next^.p^; + inc(newtriangle); + end + else begin //no ear, try next + if bo1 then begin + pt1:= pt1^.prev; + if pt1^.prev = nil then begin + inc(searchcount); + pt1:= pt1^.next; + bo1:= false; + end; + end + else begin + pt1:= pt1^.next; + if pt1^.next = nil then begin + inc(searchcount); + pt1:= pt1^.prev; + bo1:= true; + end; + end; + continue; + end; + end; + pt1^.prev^.next:= pt1^.next; + pt1^.next^.prev:= pt1^.prev; + pt1:= pt1^.prev; + if pt1^.prev = nil then begin + pt1:= pt1^.next; + if pt1^.next = nil then begin + break; + end; + end; + end; + end; + end; + newmountain:= start; //restore + end; //findmountains + +var + noisestate: mwcinfoty; + pt1,pt2: ppointty; +begin + noisestate.fw:= defaultmwcseedw; //"random" seed + noisestate.fz:= defaultmwcseedz; //"random" seed + npoints:= drawinfo.points.count; + if npoints < 3 then begin + atriangles:= nil; + trianglecount:= 0; + exit; + end; + + points:= drawinfo.points.points; + + sizetraps:= npoints*trapsize; + sizenodes:= npoints*trapnodesize; + allocbuffer(drawinfo.buffer,npoints*(sizeof(pointty)+sizeof(seginfoty)+ + sizeof(pseginfoty)) + sizetraps + sizenodes); + with drawinfo,drawinfo.points do begin + int1:= count; + pt1:= points; + pt2:= buffer.buffer; + with origin do begin + repeat + pt2^.x:= pt1^.x + x; + pt2^.y:= pt1^.y + y; + inc(pt1); + inc(pt2); + dec(int1); + until int1 = 0; + end; + end; + points:= drawinfo.buffer.buffer; + segments:= pointer(points+npoints); + shuffle:= pointer(segments+npoints); + traps:= pointer(shuffle+npoints); + nodes:= pointer(traps)+sizetraps; + ppt1:= points; //b + ppt2:= points+npoints-1; //a + seg1:= segments; + for int1:= npoints-1 downto 0 do begin //init segments + shuffle[int1]:= seg1; + with seg1^ do begin + h.previous:= seg1-1; + h.next:= seg1+1; + splitseg:= nil; + trap:= nil; + flags:= []; + diags[0]:= nil; + diags[1]:= nil; + diags[2]:= nil; + + h.b:= ppt1; + dx:= ppt2^.x-ppt1^.x; //b->a slope + dy:= ppt2^.y-ppt1^.y; //b->a slope + if dy = 0 then begin + if ppt2 > ppt1 then begin + include(flags,sf_reverse); + end; + end + else begin + if dy > 0 then begin + include(flags,sf_reverse); + end; + end; + ppt2:= ppt1; + inc(ppt1); + end; + inc(seg1); + end; + segments^.h.previous:= segments + npoints - 1; + (segments+npoints-1)^.h.next:= segments; + for int1:= npoints-1 downto 0 do begin //shuffle segments + int2:= mwcnoise(noisestate) mod npoints; + seg1:= shuffle[int2]; + shuffle[int2]:= shuffle[int1]; + shuffle[int1]:= seg1; + end; + + newtraps:= traps; //init memory sources + newnodes:= nodes; + + with newnode^ do begin //init root node + kind:= tnk_trap; + trap:= traps; + end; + + with newtrap^ do begin //init trap plane + node:= nodes; + left:= nil; + right:= nil; + top:= nil; + bottom:= nil; + end; + + for segcounter:= npoints-1 downto 0 do begin + seg1:= shuffle[segcounter]; + seg2:= seg1^.h.previous; + {$ifdef mse_debugpolytria} + debugwriteln('************************************** ('+ + inttostr(segcounter)+')'); + dumpseg(seg1,segments,npoints,traps); + {$endif} + + {$ifdef mse_debugpolytria} + if not((segcounter = debugstop) and debugnoa) then begin + {$endif} + + if not (sf_pointhandled in seg2^.flags) then begin + handlepoint(seg2); + {$ifdef mse_debugpolytria} + dump(traps,newtraps-traps,segments,npoints,nodes,'point A',false); + {$endif} + end; + + {$ifdef mse_debugpolytria} + end; + {$endif} + + {$ifdef mse_debugpolytria} + if not((segcounter = debugstop) and debugnoa) then begin + {$endif} + + if not (sf_pointhandled in seg1^.flags) then begin + handlepoint(seg1); + {$ifdef mse_debugpolytria} + dump(traps,newtraps-traps,segments,npoints,nodes,'point B',false); + {$endif} + end; + + {$ifdef mse_debugpolytria} + end; + debugwriteln('----------------'); + dumpseg(seg1,segments,npoints,traps); + if (segcounter = debugstop) and + (debugnoseg or debugnoa or debugnob) then begin + break; + end; + {$endif} + + handlesegment(seg1); + {$ifdef mse_debugpolytria} + debugwriteln('----------------'); + dumpseg(seg1,segments,npoints,traps); + {$endif} + end; +{$ifdef mse_debugpolytria} + debugwriteln('toptrap: '+trapval(toptrap,traps)+' points: '+inttostr(npoints)+ + ' traps: '+inttostr(newtraps-traps)+' nodes: '+inttostr(newnodes-nodes)+ + ' '+formatfloatmse((newnodes-nodes)/npoints,'0.00')); + if debugdumperror then begin + debugwriteln('****error**** '+ + '****error****'); + end + else begin + debugwriteln('OK '+ + ' OK'); + end; +{$endif} +{$ifdef mse_debugpolytria1} + setlength(debugtraps,newtraps-traps); + int2:= 0; + for int1:= 0 to high(debugtraps) do begin + with traps[int1] do begin + if top = nil then begin + debugtraps[int1][0].y:= 0; + debugtraps[int1][1].y:= 0; + end + else begin + debugtraps[int1][0].y:= top^.y; + debugtraps[int1][1].y:= top^.y; + end; + if bottom = nil then begin + debugtraps[int1][2].y:= maxint; + debugtraps[int1][3].y:= maxint; + end + else begin + debugtraps[int1][2].y:= bottom^.y; + debugtraps[int1][3].y:= bottom^.y; + end; + if left = nil then begin + debugtraps[int1][0].x:= 0; + debugtraps[int1][3].x:= 0; + end + else begin + if top = nil then begin + debugtraps[int1][0].x:= 0; + end + else begin + debugtraps[int1][0].x:= calcx(top^.y,left^); + end; + if bottom = nil then begin + debugtraps[int1][3].x:= maxint; + end + else begin + debugtraps[int1][3].x:= calcx(bottom^.y,left^); + end; + end; + if right = nil then begin + debugtraps[int1][1].x:= maxint; + debugtraps[int1][2].x:= maxint; + end + else begin + if top = nil then begin + debugtraps[int1][1].x:= maxint; + end + else begin + debugtraps[int1][1].x:= calcx(top^.y,right^); + end; + if bottom = nil then begin + debugtraps[int1][2].x:= 0; + end + else begin + debugtraps[int1][2].x:= calcx(bottom^.y,right^); + end; + end; + end; + end; +{$endif} + + finddiags; + newmountain:= pointer(traps); //traps not used anymore + triangles:= pointer(newmountain)+npoints*mountainsize; + newtriangle:= triangles; +{$ifdef mse_debugpolytria1} + debugmountains:= nil; + debugdiags:= nil; +{$endif} + findmountains(segments,true); +{$ifdef mse_debugpolytria1} + setlength(debugtriangles,newtriangle-triangles); + for int1:= 0 to high(debugtriangles) do begin + with debugtriangles[int1] do begin + p[0].x:= triangles[int1][0].x; + p[0].y:= triangles[int1][0].y; + p[1].x:= triangles[int1][1].x; + p[1].y:= triangles[int1][1].y; + p[2].x:= triangles[int1][2].x; + p[2].y:= triangles[int1][2].y; + end; + end; +{$endif} + atriangles:= triangles; + trianglecount:= (newtriangle-triangles); +end; + +end. diff --git a/mseide-msegui/lib/common/graphics/msetriaglob.pas b/mseide-msegui/lib/common/graphics/msetriaglob.pas new file mode 100644 index 0000000..4ec9e4c --- /dev/null +++ b/mseide-msegui/lib/common/graphics/msetriaglob.pas @@ -0,0 +1,51 @@ +{ MSEgui Copyright (c) 2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msetriaglob; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msegraphutils,msegraphics; +type + trianglety = array[0..2] of pointty; + ptrianglety = ^trianglety; + + triaflagty = (trf_capbutt,trf_capround,trf_capprojecting, + trf_joinmiter,trf_joinround,trf_joinbevel); + triaflagsty = set of triaflagty; + +const + triacapflags: array[capstylety] of triaflagsty = ( + [trf_capbutt],[trf_capround],[trf_capprojecting]); + triajoinflags: array[joinstylety] of triaflagsty = ( + [trf_joinmiter],[trf_joinround],[trf_joinbevel]); + triacapmask = [trf_capbutt,trf_capround,trf_capprojecting]; + triajoinmask = [trf_joinmiter,trf_joinround,trf_joinbevel]; + +type + triainfoty = record + linewidth: integer; + linewidth1: integer; + linewidth16: integer; +// xftlinewidthsquare: integer; + xftdashes: dashesstringty; + triaflags: triaflagsty; +// capstyle: capstylety; +// joinstyle: joinstylety; +// zerowidth: boolean; + end; + + triagcty = record + case integer of + 0: (d: triainfoty;); + 1: (_bufferspace: gcpty;); + end; + +implementation +end. diff --git a/mseide-msegui/lib/common/graphics/msex11gdi.pas b/mseide-msegui/lib/common/graphics/msex11gdi.pas new file mode 100644 index 0000000..b32f9f0 --- /dev/null +++ b/mseide-msegui/lib/common/graphics/msex11gdi.pas @@ -0,0 +1,3335 @@ +{ MSEgui Copyright (c) 1999-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msex11gdi; +{$ifdef FPC}{$mode objfpc}{$h+}{$goto on}{$endif} +interface +uses + {$ifdef FPC}xlib{$else}Xlib{$endif},mxft, + {$ifdef FPC}x,xutil,dynlibs,{$endif} + msegraphics,mseguiglob,msestrings,msegraphutils,mseguiintf,msetypes, + msectypes,mxrender,msefontconfig,msetriaglob; + +procedure init(const adisp: pdisplay; const avisual: msepvisual; + const adepth: integer); +function hasxft: boolean; +function fontdatatoxftpat(const fontdata: fontdataty; + const highres: boolean): pfcpattern; +procedure getxftfontdata(po: pxftfont; var drawinfo: drawinfoty); + +function x11getgdifuncs: pgdifunctionaty; +//function x11getgdinum: integer; + +//function x11creategc(paintdevice: paintdevicety; const akind: gckindty; +// var gc: gcty; const aprintername: msestring): guierrorty; +function x11regiontorects(const aregion: regionty): rectarty; +function x11getdefaultfontnames: defaultfontnamesty; + +type + createcolorpicfuncty = function(const acolor: txrendercolor): tpicture; +var + createcolorpic: createcolorpicfuncty; +// pictformats: array[bitmapkindty] of pxrenderpictformat; + screenrenderpictformat,bitmaprenderpictformat, + alpharenderpictformat, + rgbrenderpictformat,argbrenderpictformat: pxrenderpictformat; + +function createalphapicture(const size: sizety; + const arepeat: boolean = false): tpicture; +function creatergbpicture(const size: sizety; + const arepeat: boolean = false; + const alphamap: tpicture = 0): tpicture; +function createargbpicture(const size: sizety; + const arepeat: boolean = false): tpicture; + +{$ifdef FPC} + {$macro on} + {$define xchar2b:=txchar2b} + {$define xcharstruct:=txcharstruct} + {$define xfontstruct:=txfontstruct} + {$define xfontprop:=txfontprop} + {$define xpoint:=txpoint} + {$define xgcvalues:=txgcvalues} + {$define region:=tregion} + {$define ximage:=tximage} + {$define xwindowattributes:=txwindowattributes} + {$define xclientmessageevent:=txclientmessageevent} + {$define xtype:=_type} + {$define xrectangle:=txrectangle} + {$define keysym:=tkeysym} + {$define xsetwindowattributes:=txsetwindowattributes} + {$define xwindowchanges:=txwindowchanges} + {$define xevent:=txevent} + {$define xfunction:=_function} + {$define xwindow:=window} + {$define xlookupkeysym_:=xlookupkeysymval} + {$define c_class:= _class} + {$define xtextproperty:= txtextproperty} +{$endif} +type + + //from region.h + box = record + x1,x2,y1,y2: smallint + end; + pbox = ^box; + XRegion = record + size: clong; + numRects: clong; + rects: pbox; + extents: box; + end; + pxregion = ^xregion; + + fontmatrixmodety = (fmm_fix,fmm_linear,fmm_matrix); + x11fontdatadty = record + infopo: pxfontstruct; + matrixmode: fontmatrixmodety; + defaultwidth: integer; + xftascent,xftdescent: integer; + rowlength: word; + xftdirection: graphicdirectionty; + end; + px11fontdatadty = ^x11fontdatadty; + x11fontdataty = record + case integer of + 0: (d: x11fontdatadty;); + 1: (_bufferspace: fontdatapty;); + end; + + +{$ifndef staticxft} +var //xft functions + XftDrawDestroy: procedure(draw:PXftDraw); cdecl; + XftDrawSetClipRectangles: function (draw:PXftDraw; xOrigin:longint; + yOrigin:longint; rects:PXRectangle; n:longint):TFcBool; cdecl; + XftDrawCreate: function(dpy:PDisplay; drawable:TDrawable; visual:PVisual; + colormap:TColormap): PXftDraw; cdecl; + XftDrawSetClip: function(draw:PXftDraw; r:TRegion):TFcBool; cdecl; + XftTextExtents16: procedure(dpy:PDisplay; pub:PXftFont; + _string: pwidechar{PFcChar16}; len:longint; extents:PXGlyphInfo); cdecl; + XftTextExtentsUtf16: procedure (dpy: pDisplay; pub: pXftFont; + _string: pFcChar8; endian: tFcEndian; + len: cint; extents: pXGlyphInfo); cdecl; + XftTextExtents32: procedure(dpy: pDisplay; pub: pXftFont; _string: pFcChar32; + len: cint; extents: pXGlyphInfo); cdecl; + XftFontOpenName: function(dpy:PDisplay; screen:longint;name:Pchar):PXftFont; + cdecl; + XftFontClose: procedure(dpy:PDisplay; pub:PXftFont); cdecl; + XftDrawString16: procedure(draw:PXftDraw; color:PXftColor; pub:PXftFont; + x:longint; y:longint; _string:pwidechar; len:longint); cdecl; + XftDrawStringUtf16: procedure(draw: pXftDraw; color: pXftColor; pub: pXftFont; + x: cint; y: cint; _string: pFcChar8; endian: tFcEndian; len: cint); + cdecl; + XftDefaultHasRender: function(dpy:PDisplay):TFcBool; cdecl; + XftGetVersion: function():longint; cdecl; + XftInit: function(config:Pchar):TFcBool; cdecl; + XftInitFtLibrary: function ():TFcBool; cdecl; + + XftCharExists: function(dpy:PDisplay; pub:PXftFont; ucs4:TFcChar32):TFcBool; + cdecl; + XftNameParse: function(name:Pchar): PFcPattern;cdecl; + XftFontMatch: function(dpy:PDisplay; screen:longint; pattern:PFcPattern; + result:PFcResult): PFcPattern;cdecl; + XftFontOpenPattern: function(dpy:PDisplay; pattern:PFcPattern):PXftFont;cdecl; + XftDefaultSubstitute: procedure(dpy:PDisplay; screen:longint; + pattern:PFcPattern);cdecl; + XftDrawPicture: function(draw: PXftDraw): tpicture; cdecl; + XftDrawSrcPicture: function(draw: pXftDraw; color: pXftColor): tpicture; cdecl; +{$endif} + +var + XRenderSetPictureClipRectangles: procedure(dpy:PDisplay; picture:TPicture; + xOrigin:longint; yOrigin:longint; rects:PXRectangle; n:longint); + cdecl; + XRenderSetPictureClipRegion: procedure(dpy: pDisplay; picture: TPicture; + r: regionty); cdecl; + XRenderCreatePicture: function(dpy:PDisplay; drawable:TDrawable; + format: PXRenderPictFormat; valuemask: culong; + attributes: PXRenderPictureAttributes): TPicture; cdecl; + XRenderFillRectangle: procedure(dpy: PDisplay; op: longint; dst: TPicture; + color: PXRenderColor; x: longint; + y: longint; width: dword; height: dword);cdecl; + XRenderSetPictureTransform: procedure(dpy:PDisplay; picture:TPicture; + transform:PXTransform); + cdecl; + XRenderSetPictureFilter: procedure(dpy:PDisplay; picture:TPicture; + filter: pchar; params: pinteger; nparams: integer); + cdecl; + XRenderCreateSolidFill: function(dpy: pDisplay; + color: pXRenderColor): TPicture; cdecl; + + XRenderFreePicture: procedure(dpy:PDisplay; picture:TPicture); + cdecl; + XRenderComposite: procedure(dpy:PDisplay; op:longint; src:TPicture; + mask:TPicture; dst:TPicture; + src_x:longint; src_y:longint; mask_x:longint; mask_y:longint; + dst_x:longint; + dst_y:longint; width:dword; height:dword);cdecl; + XRenderQueryExtension: function(dpy: PDisplay; event_basep: Pinteger; + error_basep: Pinteger): TBool;cdecl; + XRenderFindVisualFormat: function(dpy: PDisplay; + visual: PVisual): PXRenderPictFormat;cdecl; + XRenderFindStandardFormat: function(dpy: PDisplay; + format: longint): PXRenderPictFormat; cdecl; + XRenderFindFormat: function(dpy: PDisplay; mask: culong; + templ: PXRenderPictFormat; count: longint): PXRenderPictFormat; cdecl; + + XRenderCompositeTriangles: procedure(dpy: pDisplay; op: cint; src: tPicture; + dst: tPicture; maskFormat: pXRenderPictFormat; + xSrc: cint; ySrc: cint; triangles: pXTriangle; + ntriangle: cint); cdecl; + XRenderCompositeTriStrip: procedure(dpy: pdisplay; op: cint; src: tpicture; + dst: tpicture; maskFormat: PXRenderPictFormat; + xSrc: cint; ySrc: cint; points: PXPointFixed; + npoint: cint); cdecl; + XRenderCompositeTriFan: procedure(dpy: pdisplay; op: cint; src: tpicture; + dst: tpicture; maskFormat: PXRenderPictFormat; + xSrc: cint; ySrc: cint; points: PXPointFixed; + npoint: cint); cdecl; + XRenderChangePicture: procedure(dpy: pdisplay; picture: tpicture; + valuemask: culong; attributes: PXRenderPictureAttributes); cdecl; + +implementation +uses + msesys,msesonames,sysutils,msefcfontselect,msedynload, + msepolytria,mselinetria,mseellipsetria; + +// +//todo: optimise tesselation +// + +(* +//function fontdatatoxftname(const fontdata: fontdataty): string; +*) +type + tsimplebitmap1 = class(tsimplebitmap); + tcanvas1 = class(tcanvas); + +const +// xrenderlineshiftx = 65536 div 2; +// xrenderlineshifty = 65536 div 2; +// xrenderfillshiftx = 0; +// xrenderfillshifty = 0; + xrenderop = pictopover; + xrendercolorsourcesize = 1; + xrendernullcolor: txrendercolor = (red: 0; green: 0; blue: 0; alpha: 0); + + capstyles: array[capstylety] of integer = (capbutt,capround,capprojecting); + joinstyles: array[joinstylety] of integer = (joinmiter,joinround,joinbevel); + defaultfontnames: defaultfontnamesty = + //stf_default stf_empty stf_unicode stf_menu stf_message stf_hint stf_report + ('Helvetica', '', '', '', '', '', 'Arial', + //stf_proportional stf_fixed, + 'Helvetica', 'Courier', + //stf_helvetica stf_roman stf_courier + 'Arial', 'Times New Roman', 'Courier New'); + + xftdefaultfontnames: defaultfontnamesty = + //stf_default stf_empty stf_unicode stf_menu stf_message stf_hint stf_report + ('sans', '', '', '', '', '', 'Arial', + //stf_proportional stf_fixed, + 'sans', 'monospace', + //stf_helvetica stf_roman stf_courier + 'Arial', 'serif', 'Courier New'); +const + wholecircle = 360*64; + +type + fontpropertiesty = ( + FOUNDRY,FAMILY_NAME,WEIGHT_NAME,SLANT,SETWIDTH_NAME,ADD_STYLE_NAME, + PIXEL_SIZE,POINT_SIZE,RESOLUTION_X,RESOLUTION_Y,SPACING,AVERAGE_WIDTH, + CHARSET_REGISTRY,CHARSET_ENCODING,{QUAD_WIDTH,RESOLUTION,}MIN_SPACE, + NORM_SPACE,MAX_SPACE,END_SPACE,SUPERSCRIPT_X,SUPERSCRIPT_Y,SUBSCRIPT_X, + SUBSCRIPT_Y,UNDERLINE_POSITION,UNDERLINE_THICKNESS,STRIKEOUT_ASCENT, + STRIKEOUT_DESCENT,ITALIC_ANGLE,X_HEIGHT,WEIGHT,FACE_NAME,{FULL_NAME,} + FONT,COPYRIGHT,AVG_CAPITAL_WIDTH,AVG_LOWERCASE_WIDTH,RELATIVE_SETWIDTH, + RELATIVE_WEIGHT,CAP_HEIGHT,SUPERSCRIPT_SIZE,FIGURE_WIDTH,SUBSCRIPT_SIZE, + SMALL_CAP_SIZE,NOTICE,DESTINATION,FONT_TYPE,FONT_VERSION,RASTERIZER_NAME, + RASTERIZER_VERSION,RAW_ASCENT,RAW_DESCENT,AXIS_NAMES,AXIS_LIMITS, + AXIS_TYPES,fpnone); + + fontpropty = record + name: string; isstring: boolean; + end; + + intfontproparty = array[fontpropertiesty] of ptrint; + strfontproparty = array[fontpropertiesty] of string; + + const + fontpropertynames: array[fontpropertiesty] of fontpropty = ( + (name: 'FOUNDRY'; isstring: true), + (name: 'FAMILY_NAME'; isstring: true), + (name: 'WEIGHT_NAME'; isstring: true), + (name: 'SLANT'; isstring: true), + (name: 'SETWIDTH_NAME'; isstring: true), + (name: 'ADD_STYLE_NAME'; isstring: true), + (name: 'PIXEL_SIZE'; isstring: false), + (name: 'POINT_SIZE'; isstring: false), + (name: 'RESOLUTION_X'; isstring: false), + (name: 'RESOLUTION_Y'; isstring: false), + (name: 'SPACING'; isstring: true), + (name: 'AVERAGE_WIDTH'; isstring: false), + (name: 'CHARSET_REGISTRY'; isstring: true), + (name: 'CHARSET_ENCODING'; isstring: true), + {'QUAD_WIDTH','RESOLUTION',} + (name: 'MIN_SPACE'; isstring: false), + (name: 'NORM_SPACE'; isstring: false), + (name: 'MAX_SPACE'; isstring: false), + (name: 'END_SPACE'; isstring: false), + (name: 'SUPERSCRIPT_X'; isstring: false), + (name: 'SUPERSCRIPT_Y'; isstring: false), + (name: 'SUBSCRIPT_X'; isstring: false), + (name: 'SUBSCRIPT_Y'; isstring: false), + (name: 'UNDERLINE_POSITION'; isstring: false), + (name: 'UNDERLINE_THICKNESS'; isstring: false), + (name: 'STRIKEOUT_ASCENT'; isstring: false), + (name: 'STRIKEOUT_DESCENT'; isstring: false), + (name: 'ITALIC_ANGLE'; isstring: false), + (name: 'X_HEIGHT'; isstring: false), + (name: 'WEIGHT'; isstring: false), + (name: 'FACE_NAME'; isstring: true), + {'FULL_NAME',} + (name: 'FONT'; isstring: true), + (name: 'COPYRIGHT'; isstring: true), + (name: 'AVG_CAPITAL_WIDTH'; isstring: false), + (name: 'AVG_LOWERCASE_WIDTH'; isstring: false), + (name: 'RELATIVE_SETWIDTH'; isstring: false), + (name: 'RELATIVE_WEIGHT'; isstring: false), + (name: 'CAP_HEIGHT'; isstring: false), + (name: 'SUPERSCRIPT_SIZE'; isstring: false), + (name: 'FIGURE_WIDTH'; isstring: false), + (name: 'SUBSCRIPT_SIZE'; isstring: false), + (name: 'SMALL_CAP_SIZE'; isstring: false), + (name: 'NOTICE'; isstring: true), + (name: 'DESTINATION'; isstring: false), + (name: 'FONT_TYPE'; isstring: true), + (name: 'FONT_VERSION'; isstring: true), + (name: 'RASTERIZER_NAME'; isstring: true), + (name: 'RASTERIZER_VERSION'; isstring: true), + (name: 'RAW_ASCENT'; isstring: false), + (name: 'RAW_DESCENT'; isstring: false), + (name: 'AXIS_NAMES'; isstring: true), + (name: 'AXIS_LIMITS'; isstring: true), + (name: 'AXIS_TYPES'; isstring: true), + (name: ''; isstring: false) + ); + +var + appdisp: pdisplay; + defvisual: msepvisual; + defdepth: integer; + hasxrender: boolean; + fhasxft: boolean; +type + xftcolorcacheinfoty = record + picture: tpicture; + pixel: pixelty; + end; + +const + xftcolorcachemask = $1f; +type + xftstatety = (xfts_clipregionvalid,xfts_smooth,xfts_foregroundvalid, + xfts_monobrush,xfts_hasdashes); + xftstatesty = set of xftstatety; + x11gcdty = record + triainfo: triainfoty; //first! + gcdrawingflags: drawingflagsty; + gcrasterop: rasteropty; + gcclipregion: regionty; + gclinewidth_: int32; + gccapstyle_: int32; +// gchasdashes: boolean; + xftdraw: pxftdraw; + xftdrawpic: tpicture; + xftcolor: txftcolor; + xftcolorbackground: txftcolor; + xftfont: pxftfont; + xftfontdata: px11fontdatadty; + xftstate: xftstatesty; + xftforegroundpic: tpicture; +// xftcolorforegroundpicx: xftcolorcacheinfoty; +// xftcolorbackgroundpicx: xftcolorcacheinfoty; + xftbrush: pixmapty; + xftbrushorigin: pointty; + xftbrushsize: sizety; + xftbrushpic: tpicture; + xftbrushalphapic: tpicture; + end; + {$if sizeof(x11gcdty) > sizeof(gcpty)} {$error 'buffer overflow'}{$ifend} + x11gcty = record + case integer of + 0: (d: x11gcdty;); + 1: (_bufferspace: gcpty;); + end; + +var +// xftcolorcache: array[0..xftcolorcachemask] of xftcolorcacheinfoty; + fontpropertyatoms: array[fontpropertiesty] of atom; + +procedure init(const adisp: pdisplay; const avisual: msepvisual; + const adepth: integer); +var + int1,int2: integer; + fontpropnames: strfontproparty; + propnum: fontpropertiesty; +begin + appdisp:= adisp; + defvisual:= avisual; + defdepth:= adepth; + + hasxrender:= hasxrender and + (xrenderqueryextension(appdisp,@int1,@int2) <> 0); + if hasxrender then begin +// pictformats[bmk_mono]:= xrenderfindstandardformat(appdisp,pictstandarda1); +// pictformats[bmk_gray]:= xrenderfindstandardformat(appdisp,pictstandarda8); +// pictformats[bmk_rgb]:= xrenderfindvisualformat(appdisp,pvisual(defvisual)); + screenrenderpictformat:= xrenderfindvisualformat(appdisp,pvisual(defvisual)); + bitmaprenderpictformat:= xrenderfindstandardformat(appdisp,pictstandarda1); + alpharenderpictformat:= xrenderfindstandardformat(appdisp,pictstandarda8); + rgbrenderpictformat:= xrenderfindstandardformat(appdisp,pictstandardrgb24); + argbrenderpictformat:= xrenderfindstandardformat(appdisp,pictstandardargb32); + end; + if not noxft then begin + fhasxft:= fhasxft and xftdefaulthasrender(appdisp) and (xftgetversion() >= 20000); + if fhasxft then begin + fhasxft:= xftinit(nil); + if fhasxft then begin + fhasxft:= xftinitftlibrary(); + if fhasxft and not hasdefaultfontarg then begin + defaultfontinfo[fn_family_name]:= 'sans'; + end; + end; + end; + end + else begin + fhasxft:= false; + end; + for propnum:= low(fontpropertiesty) to high(fontpropertiesty) do begin + fontpropnames[propnum]:= fontpropertynames[propnum].name; + end; + + xinternatoms(appdisp,@fontpropnames[low(fontpropertiesty)], + integer(high(fontpropertiesty)),{$ifdef xboolean}true{$else}1{$endif}, + @fontpropertyatoms[low(fontpropertiesty)]); + +end; + +function fontinfotoxlfdname(const info: fontinfoty): string; +var + en1: fontnamety; +begin + result:= ''; + for en1:= low(fontnamety) to high(fontnamety) do begin + result:= result + '-' + info[en1]; + end; +end; + +procedure getxftfontdata(po: pxftfont; var drawinfo: drawinfoty); +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + if po <> nil then begin + {$ifdef FPC} {$checkpointer off} {$endif} + with drawinfo.getfont.fontdata^,x11fontdataty(platformdata) do begin + font:= ptruint(po); + ascent:= po^.ascent; + descent:= po^.descent; + // linespacing:= ascent + descent; + linespacing:= po^.height; +// realheight:= po^.height; + caretshift:= 0; + d.infopo:= nil; + d.xftascent:= po^.ascent; + d.xftdescent:= po^.descent; + d.xftdirection:= gd_right; + end; + {$ifdef FPC} {$checkpointer default} {$endif} + end; +end; + +(* +function buildxftname(const fontdata: fontdataty; + const fontinfo: fontinfoty): ansistring; +var + str1: ansistring; + int1: integer; +begin + with fontdata do begin + str1:= ''; + if fontinfo[fn_foundry] <> '*' then begin + str1:= str1+':foundry='+fontinfo[fn_foundry]; + end; + if (familyoptions = []) then begin + if (pitchoptions = []) and (fontinfo[fn_family_name] <> '*') then begin + str1:= str1 + ':family=' + fontinfo[fn_family_name]; + end; + end + else begin + if foo_helvetica in familyoptions then begin + str1:= str1 + ':family=sans'; + end + else begin + if foo_roman in familyoptions then begin + str1:= str1 + ':family=serif'; + end + else begin + if foo_decorative in familyoptions then begin + end + else begin + if foo_script in familyoptions then begin + end; + end; + end; + end; + end; + if fs_bold in style then begin + str1:= str1 + ':bold'; + end; + if fs_italic in style then begin + str1:= str1 + ':italic'; + end; + if fontinfo[fn_pixel_size] <> '*' then begin + str1:= str1 + ':pixelsize=' + fontinfo[fn_pixel_size]; + end; + if fontinfo[fn_average_width] <> '*' then begin + try + int1:= (strtoint(fontinfo[fn_average_width]) + 5) div 10; + str1:= str1 + ':charwidth='+inttostr(int1); + except + end; + end; + if foo_fixed in pitchoptions then begin + str1:= str1 + ':mono'; + end; + if foo_proportional in pitchoptions then begin + str1:= str1 + ':proportional'; + end; + if foo_antialiased in antialiasedoptions then begin + str1:= str1 + ':antialias=1'; + end; + if foo_nonantialiased in antialiasedoptions then begin + str1:= str1 + ':antialias=0'; + end; + { + if foo_xcore in xcoreoptions then begin + str1:= str1 + ':core=1'; + end; + if foo_noxcore in xcoreoptions then begin + str1:= str1 + ':core=0'; + end; + } + if fontinfo[fn_charset_registry] <> '*' then begin + str1:= str1 + ':encoding=' + fontinfo[fn_charset_registry]; + if fontinfo[fn_encoding] <> '*' then begin + str1:= str1 +'-'+fontinfo[fn_encoding]; + end; + end; + end; + result:= str1; +end; +*) + +{ +function fontdatatoxftname(const fontdata: fontdataty): ansistring; +var + fontinfo: fontinfoty; +begin + setupfontinfo(fontdata,fontinfo); + result:= buildxftname(fontdata,fontinfo); +end; +} +function fontdatatoxftpat(const fontdata: fontdataty; const highres: boolean): pfcpattern; +var + fontinfo: fontinfoty; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + setupfontinfo(fontdata,fontinfo); + result:= buildxftpat(fontdata,fontinfo,highres); +end; + +procedure gdi_createpixmap(var drawinfo: drawinfoty); //gdifunc +begin + with drawinfo.createpixmap do begin + pixmap:= gui_createpixmap(size,0,kind,copyfrom); + end; +end; + +procedure gdi_pixmaptoimage(var drawinfo: drawinfoty); //gdifunc +begin + with drawinfo.pixmapimage do begin + gui_pixmaptoimage(pixmap,image,drawinfo.gc.handle); + end; +end; + +procedure gdi_imagetopixmap(var drawinfo: drawinfoty); //gdifunc +begin + with drawinfo.pixmapimage do begin + error:= gui_imagetopixmap(image,pixmap,drawinfo.gc.handle); + end; +end; + +function creategc(const device: paintdevicety): tgc; +var + xvalues: xgcvalues; +begin + xvalues.graphics_exposures:= 0; + result:= xcreategc(appdisp,device,gcgraphicsexposures,@xvalues); +end; + +//function x11creategc(paintdevice: paintdevicety; const akind: gckindty; +// var gc: gcty; const aprintername: msestring): guierrorty; +procedure gdi_creategc(var drawinfo: drawinfoty); //gdifunc +begin +// gdi_lock; + with drawinfo.creategc do begin +// gcpo^.gdifuncs:= getdefaultgdifuncs; + gcpo^.gdifuncs:= x11getgdifuncs; + if paintdevice = 0 then begin + paintdevice:= gui_getrootwindow(); + end; + gcpo^.handle:= ptruint(creategc(paintdevice) + {xcreategc(appdisp,paintdevice,0,nil)}); + if gcpo^.handle = 0 then begin + error:= gde_creategc; + end + else begin +// xsetgraphicsexposures(appdisp,tgc(gcpo^.handle), +// {$ifdef xboolean}false{$else}0{$endif}); + with x11gcty(gcpo^.platformdata) do begin + //nothing to do, gc is nulled + end; + error:= gde_ok; + end; + end; +// gdi_unlock; +end; + +procedure transformpoints(var drawinfo: drawinfoty; const aclose: boolean); +var + po1: ppointty; + po2: pxpoint; + int1: integer; +begin + with drawinfo,drawinfo.points do begin + int1:= count; + if aclose then begin + inc(int1); + end; + allocbuffer(buffer,int1*sizeof(xpoint)); + int1:= count; + po1:= points; + po2:= buffer.buffer; + with origin do begin + while int1 > 0 do begin + po2^.x:= po1^.x + x; + po2^.y:= po1^.y + y; + inc(po1); + inc(po2); + dec(int1); + end; + end; + if aclose then begin + move(buffer.buffer^,(pchar(buffer.buffer)+count*sizeof(xpoint))^,sizeof(xpoint)); + end; + end; +end; + +procedure transformpos(var drawinfo: drawinfoty); +begin + with drawinfo,drawinfo.pos do begin + allocbuffer(buffer,sizeof(xpoint)); + with pxpoint(buffer.buffer)^ do begin + x:= pos^.x + origin.x; + y:= pos^.y + origin.y; + end; + end; +end; + +function transformtext16pos(var drawinfo: drawinfoty): pxchar2b; +var + po1: pword; + po2: pword; + int1: integer; +begin + with drawinfo,drawinfo.text16pos do begin + allocbuffer(buffer,sizeof(xpoint)+count*2); + with pxpoint(buffer.buffer)^ do begin + x:= pos^.x + origin.x; + y:= pos^.y + origin.y; + end; + po1:= pword(text); + result:= pxchar2b(pchar(buffer.buffer) + sizeof(xpoint)); + po2:= pword(result); + for int1:= count-1 downto 0 do begin + po2^:= (po1^ shl 8) or (po1^ shr 8); //simply swap bytes + inc(po1); + inc(po2); + end; + end; +end; + +function x11regiontorects(const aregion: regionty): rectarty; +var + int1: integer; + boxpo: pbox; +begin + gdi_lock; + if aregion = 0 then begin + result:= nil; + end + else begin + with pxregion(aregion)^ do begin + setlength(result,numrects); + boxpo:= rects; + for int1:= 0 to numrects-1 do begin + with boxpo^,result[int1] do begin + x:= x1; + y:= y1; + cx:= x2 - x1; + cy:= y2 - y1; + end; + inc(boxpo); + end; + end; + end; + gdi_unlock; +end; + +function x11getdefaultfontnames: defaultfontnamesty; +begin + if fhasxft then begin + result:= xftdefaultfontnames; + end + else begin + result:= defaultfontnames; + end; +end; + +procedure freexftbrush(var drawinfo: drawinfoty); +begin + with x11gcty(drawinfo.gc.platformdata).d do begin + if xftbrushpic <> 0 then begin + xrenderfreepicture(appdisp,xftbrushpic); + xftbrushpic:= 0; + end; + if xftbrushalphapic <> 0 then begin + xrenderfreepicture(appdisp,xftbrushalphapic); + xftbrushalphapic:= 0; + end; + end; +end; + +procedure gdi_destroygc(var drawinfo: drawinfoty); //gdifunc +begin + gdi_lock; + with drawinfo do begin + with x11gcty(gc.platformdata).d do begin + if xftdraw <> nil then begin + freexftbrush(drawinfo); + xftdrawdestroy(xftdraw); + end; + end; + xfreegc(appdisp,tgc(gc.handle)); + end; + gdi_unlock; +end; + +function colortorendercolor(const avalue: rgbtriplety): txrendercolor; overload; +begin + with result do begin + red:= (avalue.red shl 8) or avalue.red; + green:= (avalue.green shl 8) or avalue.green; + blue:= (avalue.blue shl 8) or avalue.blue; + alpha:= $ffff; + end; +end; + +function colortorendercolor(const avalue: colorty): txrendercolor; overload; +begin + result:= colortorendercolor(colortorgb(avalue)); +end; + +function alphatorendercolor(const avalue: rgbtriplety): txrendercolor; overload; +var + wo1: word; +begin + with result do begin + wo1:= (integer(avalue.red)+integer(avalue.green)+integer(avalue.blue)) div 3; + wo1:= wo1 or (wo1 shl 8); + red:= 0; + green:= 0; + blue:= 0; + alpha:= wo1; + end; +end; + +function alphatorendercolor(const avalue: colorty): txrendercolor; overload; +begin + result:= alphatorendercolor(colortorgb(avalue)); +end; + +function graytorendercolor(const avalue: rgbtriplety): txrendercolor; overload; +var + wo1: word; +begin + with result do begin + wo1:= (integer(avalue.red)+integer(avalue.green)+integer(avalue.blue)) div 3; + wo1:= wo1 or (wo1 shl 8); + red:= wo1; + green:= wo1; + blue:= wo1; + alpha:= $ffff; + end; +end; + +function graytorendercolor(const avalue: colorty): txrendercolor; overload; +begin + result:= graytorendercolor(colortorgb(avalue)); +end; + +procedure setregion(var gc: gcty; const aregion: region; + const pic: tpicture = 0; const draw: pxftdraw = nil); +var + po1,rectspo: pxrectangle; + boxpo: pbox; + int1: integer; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + {$ifdef FPC} {$checkpointer off} {$endif} + with pxregion(aregion)^ do begin + if numrects > 0 then begin + boxpo:= rects; + getmem(rectspo,numrects*sizeof(xrectangle)); + po1:= rectspo; + for int1:= numrects - 1 downto 0 do begin + rectspo^.x:= boxpo^.x1; + rectspo^.y:= boxpo^.y1; + rectspo^.width:= boxpo^.x2-boxpo^.x1; + rectspo^.height:= boxpo^.y2-boxpo^.y1; + inc(boxpo); + inc(rectspo); + end; + if pic <> 0 then begin + xrendersetpicturecliprectangles(appdisp,pic,gc.cliporigin.x, + gc.cliporigin.y,po1,numrects); + end + else begin + if draw <> nil then begin + xftdrawsetcliprectangles(draw,gc.cliporigin.x,gc.cliporigin.y,po1,numrects); + end + else begin + xsetcliprectangles(appdisp,tgc(gc.handle),gc.cliporigin.x,gc.cliporigin.y,po1,numrects,yxbanded); + end; + end; + freemem(po1); + end + else begin + if pic <> 0 then begin + xrendersetpicturecliprectangles(appdisp,pic,gc.cliporigin.x,gc.cliporigin.y,nil,0); + end + else begin + if draw <> nil then begin + xftdrawsetcliprectangles(draw,gc.cliporigin.x,gc.cliporigin.y,nil,0); + end + else begin + xsetcliprectangles(appdisp,tgc(gc.handle),gc.cliporigin.x,gc.cliporigin.y,nil,0,yxbanded); + end; + end; + end; + end; + {$ifdef FPC} {$checkpointer default} {$endif} +end; + +const + unitytransform: txtransform = ((65536,0,0), + (0,65536,0), + (0,0,65536)); + +function creatergbpicture(const size: sizety; + const arepeat: boolean = false; + const alphamap: tpicture = 0): tpicture; +var + attributes: txrenderpictureattributes; + pixmap: pixmapty; + int1: integer; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + pixmap:= xcreatepixmap(appdisp,gui_getrootwindow(),size.cx,size.cy,24); + attributes._repeat:= repeatnormal; + attributes.alpha_map:= alphamap; + int1:= 0; + if arepeat then begin + int1:= cprepeat; + end; + if alphamap <> 0 then begin + int1:= int1 or cpalphamap; + end; + result:= xrendercreatepicture(appdisp,pixmap, + rgbrenderpictformat,int1,@attributes); + xfreepixmap(appdisp,pixmap); +end; + +function createalphapicture(const size: sizety; + const arepeat: boolean = false): tpicture; +var + attributes: txrenderpictureattributes; + pixmap: pixmapty; + int1: integer; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + pixmap:= xcreatepixmap(appdisp,gui_getrootwindow(),size.cx,size.cy,8); + attributes._repeat:= repeatnormal; + int1:= cpcomponentalpha; + if arepeat then begin + int1:= cprepeat; + end; + result:= xrendercreatepicture(appdisp,pixmap, + alpharenderpictformat,int1,@attributes); + xfreepixmap(appdisp,pixmap); +end; + +function createargbpicture(const size: sizety; + const arepeat: boolean = false): tpicture; +var + attributes: txrenderpictureattributes; + pixmap: pixmapty; + int1: integer; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + pixmap:= xcreatepixmap(appdisp,gui_getrootwindow(),size.cx,size.cy,32); + attributes._repeat:= repeatnormal; + int1:= 0; + if arepeat then begin + int1:= cprepeat; + end; + result:= xrendercreatepicture(appdisp,pixmap, + argbrenderpictformat,int1,@attributes); + xfreepixmap(appdisp,pixmap); +end; + +function createcolorpi(const acolor: txrendercolor; + const aformat: pxrenderpictformat): tpicture; +var + attributes: txrenderpictureattributes; +// col: txrendercolor; + pixmap: pixmapty; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + pixmap:= gui_createpixmap( + makesize(xrendercolorsourcesize,xrendercolorsourcesize)); + attributes._repeat:= repeatnormal; + result:= xrendercreatepicture(appdisp,pixmap, + screenrenderpictformat,cprepeat,@attributes); +// col:= colortorendercolor(acolor); + xrenderfillrectangle(appdisp,pictopsrc,result,@acolor,0,0, + xrendercolorsourcesize,xrendercolorsourcesize); + xfreepixmap(appdisp,pixmap); +end; + +function createcolorpic1(const acolor: txrendercolor): tpicture; +begin + result:= createcolorpi(acolor,screenrenderpictformat); +end; + +function createcolorpic2(const acolor: txrendercolor): tpicture; +//var +// col: txrendercolor; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} +// col:= colortorendercolor(acolor); + result:= xrendercreatesolidfill(appdisp,@acolor); +end; + +function createcolorpicture(const acolor: colorty): tpicture; +begin + result:= createcolorpic(colortorendercolor(acolor)); +end; + +function creategraycolorpicture(const acolor: colorty): tpicture; +begin + result:= createcolorpic(graytorendercolor(acolor)); +end; + +function createalphacolorpicture(const acolor: colorty): tpicture; +begin + result:= createcolorpic(alphatorendercolor(acolor)); +end; +{ +function creategraypicture(const acolor: colorty): tpicture; +begin + result:= createcolorpi(alphatorendercolor(acolor),alpharenderpictformat); +end; +} +type + ppxrenderpictformat = ^pxrenderpictformat; + +const + renderformats: array[bitmapkindty] of ppxrenderpictformat = +// bmk_mono, bmk_gray, bmk_rgb + (@bitmaprenderpictformat,@alpharenderpictformat,@screenrenderpictformat); + +function createmaskpicture(const acolor: rgbtriplety; + const akind: bitmapkindty): tpicture; +var + attributes: txrenderpictureattributes; + col: txrendercolor; + pixmap: pixmapty; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + pixmap:= gui_createpixmap(makesize(1,1),0,akind); + attributes._repeat:= repeatnormal; + col:= colortorendercolor(acolor); + attributes.component_alpha:= 1; + if akind = bmk_gray then begin + col.alpha:= (col.red + col.green + col.blue) div 3; + end; + result:= xrendercreatepicture(appdisp,pixmap,renderformats[akind]^, + cprepeat or cpcomponentalpha,@attributes); + xrenderfillrectangle(appdisp,pictopsrc,result,@col,0,0,1,1); + gui_freepixmap(pixmap); +end; + +function createmaskpicture(const ahandle: pixmapty; + const akind: bitmapkindty): tpicture; +var + attributes: txrenderpictureattributes; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= 0; + if ahandle <> 0 then begin + attributes.component_alpha:= 0; + if akind = bmk_rgb then begin + attributes.component_alpha:= 1; + end; + result:= xrendercreatepicture(appdisp,ahandle, + renderformats[akind]^,cpcomponentalpha,@attributes); + end; +end; + +function createmaskpicture(const amask: tsimplebitmap): tpicture; overload; +begin + if amask <> nil then begin + result:= createmaskpicture(tsimplebitmap1(amask).handle,amask.kind); + end; +end; + +procedure checkxftdraw(var drawinfo: drawinfoty); +var + attr: txrenderpictureattributes; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with x11gcty(drawinfo.gc.platformdata).d do begin + if xftdraw = nil then begin + xftdraw:= xftdrawcreate(appdisp,drawinfo.paintdevice, + xlib.pvisual(defvisual),0); + xftdrawpic:= xftdrawpicture(xftdraw); + attr.poly_edge:= polyedgesmooth; + attr.poly_mode:= polymodeprecise; +// attr.poly_mode:= polymodeimprecise; + xrenderchangepicture(appdisp,xftdrawpic,cppolyedge or cppolymode,@attr); +// xftcolorforegroundpic:= createcolorpicture(cl_black); + end; + if not (xfts_clipregionvalid in xftstate) then begin + if gcclipregion = 0 then begin + xftdrawsetclip(xftdraw,nil); + end + else begin + setregion(drawinfo.gc,region(gcclipregion),0,xftdraw); + end; + include(xftstate,xfts_clipregionvalid); + end; + end; +end; + +procedure checkxftstate(var drawinfo: drawinfoty; const aflags: xftstatesty); + procedure updatemonocolor; + var + co1: txrendercolor; + begin + with drawinfo.gc,x11gcty(platformdata).d do begin + if df_opaque in drawingflags then begin + co1:= xftcolorbackground.color; + end + else begin + co1:= xrendernullcolor; + end; + xrenderfillrectangle(appdisp,pictopsrc,xftbrushpic, + @co1,0,0,xftbrushsize.cx,xftbrushsize.cy); + xrendercomposite(appdisp,pictopover,xftdrawsrcpicture(xftdraw,@xftcolor), + xftbrushalphapic,xftbrushpic,0,0,0,0, + 0,0,xftbrushsize.cx,xftbrushsize.cy); + end; + end; //updatemonocolor + +var + flags1: xftstatesty; + attributes: txrenderpictureattributes; +//todo: fix xftbrushorigin, seems to be unreliable +begin + with drawinfo.gc,x11gcty(platformdata).d do begin + if not (xfts_clipregionvalid in xftstate) then begin + if gcclipregion = 0 then begin + xftdrawsetclip(xftdraw,nil); + end + else begin + setregion(drawinfo.gc,region(gcclipregion),0,xftdraw); + end; + include(xftstate,xfts_clipregionvalid); + end; + flags1:= (xftstate >< aflags) * aflags; + if xfts_foregroundvalid in flags1 then begin + if df_brush in drawinfo.gc.drawingflags then begin + if (xftbrush <> 0) then begin + if (xftbrushpic = 0) then begin + attributes._repeat:= repeatnormal; + if xfts_monobrush in xftstate then begin + xftbrushalphapic:= xrendercreatepicture(appdisp,xftbrush, + bitmaprenderpictformat,cprepeat,@attributes); + xftbrushpic:= createargbpicture(xftbrushsize,true); + updatemonocolor; + end + else begin + xftbrushpic:= xrendercreatepicture(appdisp,xftbrush, + screenrenderpictformat,cprepeat,@attributes); + end; + end + else begin + if xfts_monobrush in xftstate then begin + updatemonocolor; + end; + end; + end; + xftforegroundpic:= xftbrushpic; + end + else begin + xftforegroundpic:= xftdrawsrcpicture(xftdraw,@xftcolor); + end; + include(xftstate,xfts_foregroundvalid); + end; + end; +end; +const + posroundval = $0;//7fff; + +procedure compositetriangles(var drawinfo: drawinfoty; + const triangles: ptrianglety; const trianglecount: integer); +begin + checkxftstate(drawinfo,[xfts_foregroundvalid]); + with x11gcty(drawinfo.gc.platformdata).d do begin + xrendercompositetriangles(appdisp,xrenderop,xftforegroundpic, + xftdrawpic,alpharenderpictformat, + xftbrushorigin.x+(ppointty(triangles)^.x+posroundval) div 65536, + xftbrushorigin.y+(ppointty(triangles)^.y+posroundval) div 65536, + pxtriangle(triangles),trianglecount); + end; +end; + +procedure compositetristrip(var drawinfo: drawinfoty; + const points: ppointty; const pointcount: integer); +begin + checkxftstate(drawinfo,[xfts_foregroundvalid]); + with x11gcty(drawinfo.gc.platformdata).d do begin + xrendercompositetristrip(appdisp,xrenderop,xftforegroundpic, + xftdrawpic,alpharenderpictformat, + xftbrushorigin.x+(points^.x+posroundval) div 65536, + xftbrushorigin.y+(points^.y+posroundval) div 65536, + pxpointfixed(points),pointcount); + end; +end; + +procedure compositetrifan(var drawinfo: drawinfoty; + const points: ppointty; const pointcount: integer); +begin + checkxftstate(drawinfo,[xfts_foregroundvalid]); + with x11gcty(drawinfo.gc.platformdata).d do begin + xrendercompositetrifan(appdisp,xrenderop,xftforegroundpic, + xftdrawpic,alpharenderpictformat, + xftbrushorigin.x+(points^.x+posroundval) div 65536, + xftbrushorigin.y+(points^.y+posroundval) div 65536, + pxpointfixed(points),pointcount); + end; +end; + +procedure gdi_changegc(var drawinfo: drawinfoty); //gdifunc +var + xmask: longword; + xvalues: xgcvalues; + agc: tgc; + int1: integer; + needslinecheck: boolean; + +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + xmask:= 0; + with drawinfo.gcvalues^,drawinfo.gc,x11gcty(platformdata).d do begin + agc:= tgc(handle); + needslinecheck:= false; + if gvm_colorforeground in mask then begin + xmask:= xmask or gcforeground; + xvalues.foreground:= colorforeground; + xvalues.fill_style:= fillsolid; + if fhasxft then begin + xftcolor.pixel:= colorforeground; + xftcolor.color:= colortorendercolor(drawinfo.acolorforeground); + exclude(xftstate,xfts_foregroundvalid); + end; + end; + if (drawingflags >< gcdrawingflags) + * (fillmodeinfoflags+[df_smooth]) <> [] then begin + xmask:= xmask or gcfillstyle; + if df_brush in drawingflags then begin + if df_monochrome in drawingflags then begin + include(xftstate,xfts_monobrush); + if df_opaque in drawingflags then begin + xvalues.fill_style:= fillopaquestippled; + end + else begin + xvalues.fill_style:= fillstippled; + end; + end + else begin + xvalues.fill_style:= filltiled; + end; + end + else begin + exclude(xftstate,xfts_monobrush); + xvalues.fill_style:= fillsolid; + end; + if (df_smooth in drawingflags) and fhasxft then begin + checkxftdraw(drawinfo); + if not (xfts_smooth in xftstate) then begin + include(xftstate,xfts_smooth); + needslinecheck:= true; + end; + end + else begin + if xfts_smooth in xftstate then begin + exclude(xftstate,xfts_smooth); + needslinecheck:= true; + end; + end; + end; + gcdrawingflags:= drawingflags; + + if gvm_rasterop in mask then begin + xmask:= xmask or gcfunction; + xvalues.xfunction:= integer(rasterop); + gcrasterop:= rasterop; + end; + if gvm_linewidth in mask then begin + needslinecheck:= true; + xmask:= xmask or gclinewidth; + xvalues.line_width:= + (lineinfo.width + linewidthroundvalue) shr linewidthshift; + triainfo.linewidth:= xvalues.line_width; + if triainfo.linewidth = 0 then begin + triainfo.linewidth1:= 1; + end + else begin + triainfo.linewidth1:= triainfo.linewidth; + end; + triainfo.linewidth16:= triainfo.linewidth1 shl 16; + gclinewidth_:= xvalues.line_width; + end; + if gvm_dashes in mask then begin + with lineinfo do begin + needslinecheck:= true; + if dashes = '' then begin + exclude(xftstate,xfts_hasdashes); + end + else begin + include(xftstate,xfts_hasdashes); + end; + triainfo.xftdashes:= dashes; + int1:= length(dashes); + if int1 <> 0 then begin + if df_opaque in drawingflags then begin + xvalues.line_style:= linedoubledash; + end + else begin + xvalues.line_style:= lineonoffdash; + end; + xsetdashes(appdisp,agc,0,@lineinfo.dashes[1],int1); + end + else begin + xvalues.line_style:= linesolid; + end; + end; + xmask:= xmask or gclinestyle; + end; + if gvm_capstyle in mask then begin + needslinecheck:= true; +// triainfo.capstyle:= lineinfo.capstyle; + triainfo.triaflags:= triainfo.triaflags - triacapmask + + triacapflags[lineinfo.capstyle]; + xvalues.cap_style:= capstyles[lineinfo.capstyle]; + gccapstyle_:= xvalues.cap_style; + xmask:= xmask or gccapstyle; + end; + if gvm_joinstyle in mask then begin +// triainfo.joinstyle:= lineinfo.joinstyle; + triainfo.triaflags:= triainfo.triaflags - triajoinmask + + triajoinflags[lineinfo.joinstyle]; + xvalues.join_style:= joinstyles[lineinfo.joinstyle]; + xmask:= xmask or gcjoinstyle; + end; + if gvm_font in mask then begin +// fontdirection:= x11fontdataty(fontdata^.platformdata).d.direction; + if fhasxft then begin + xftfont:= pxftfont(font); + xftfontdata:= @x11fontdataty(fontdata^.platformdata).d; + end + else begin + xmask:= xmask or gcfont; + xvalues.font:= font; + end; + end; + if gvm_colorbackground in mask then begin + xmask:= xmask or gcbackground; + xvalues.background:= colorbackground; + if df_dashed in drawingflags then begin + if df_opaque in drawingflags then begin + xvalues.line_style:= linedoubledash; + end + else begin + xvalues.line_style:= lineonoffdash; + end; + xmask:= xmask or gclinestyle; + end; + if fhasxft then begin + xftcolorbackground.pixel:= colorbackground; + xftcolorbackground.color:= colortorendercolor(drawinfo.acolorbackground); + if xfts_monobrush in xftstate then begin + exclude(xftstate,xfts_foregroundvalid); + end; + end; + end; + if gvm_brushorigin in mask then begin + xmask:= xmask or gctilestipxorigin or gctilestipyorigin; + xvalues.ts_x_origin:= brushorigin.x; + xvalues.ts_y_origin:= brushorigin.y; + xftbrushorigin.x:= -brushorigin.x;//-drawinfo.origin.x; + xftbrushorigin.y:= -brushorigin.y;//-drawinfo.origin.y; + end; + + if gvm_brush in mask then begin + exclude(xftstate,xfts_foregroundvalid); + with tsimplebitmap1(brush) do begin + xftbrush:= handle; + xftbrushsize:= size; + end; + freexftbrush(drawinfo); + if df_monochrome in drawingflags then begin + xvalues.stipple:= xftbrush; + xmask:= xmask or gcstipple; + end + else begin + xvalues.tile:= xftbrush; + xmask:= xmask or gctile; + end; + end; + + if needslinecheck and zerolineworkaround then begin + if (gclinewidth_ = 0) and not (xfts_smooth in xftstate) then begin + xvalues.line_width:= 1; + if xfts_hasdashes in xftstate then begin + xvalues.cap_style:= capbutt; + end + else begin + xvalues.cap_style:= capprojecting; + end; + end + else begin + xvalues.line_width:= gclinewidth_; + xvalues.cap_style:= gccapstyle_; + end; + xmask:= xmask or (gclinewidth or gccapstyle); + end; + + if xmask <> 0 then begin + xchangegc(appdisp,agc,xmask,@xvalues); + end; + if gvm_clipregion in mask then begin + exclude(xftstate,xfts_clipregionvalid); + gcclipregion:= clipregion; + if clipregion = 0 then begin + xsetclipmask(appdisp,agc,none); + end + else begin + setregion(drawinfo.gc,region(clipregion)); +// xsetregion(appdisp,agc,region(clipregion)); + end; + end; + end; +end; + +procedure gdi_getcanvasclass(var drawinfo: drawinfoty); //gdifunc +begin + //dummy +end; + +procedure gdi_endpaint(var drawinfo: drawinfoty); //gdifunc +begin + //dummy +end; + +procedure gdi_flush(var drawinfo: drawinfoty); //gdifunc +begin + //dummy +end; + +procedure gdi_movewindowrect(var drawinfo: drawinfoty); //gdifunc +begin + with drawinfo.moverect do begin + gui_movewindowrect(drawinfo.paintdevice,dist^,rect^); + end; +end; + +function getmatrixcharstruct(char: msechar; const fontdata: x11fontdataty): pxcharstruct; +type + xchar2b = record + byte2: byte; //lsb + byte1: byte; //msb + end; + +begin +{$ifdef FPC} {$checkpointer off} {$endif} + with fontdata,d.infopo^ do begin + if (xchar2b(char).byte1 >= min_byte1) and (xchar2b(char).byte1 <= max_byte1) and + (xchar2b(char).byte2 >= min_char_or_byte2) and + (xchar2b(char).byte2 <= max_char_or_byte2) then begin + result:= pxcharstruct(pchar(per_char) + + ((xchar2b(char).byte1 - min_byte1) * d.rowlength + + (xchar2b(char).byte2 - min_char_or_byte2) + ) * sizeof(xcharstruct)); + end + else begin + result:= nil; + end; + end; +{$ifdef FPC} {$checkpointer default} {$endif} +end; + +procedure gdi_getchar16widths(var drawinfo: drawinfoty); +var + int1,int2: integer; + char: word; + po1,pe: pmsechar; + po2: pinteger; + charstructpo: pxcharstruct; + glyphinfo: txglyphinfo; + bo1: boolean; + po3: pxftfont; + ca1: card32; + +begin + gdi_lock; + with drawinfo.getchar16widths do begin + po1:= text; + po2:= resultpo; +{$ifdef FPC} {$checkpointer off} {$endif} + with fontdata^,x11fontdataty(platformdata),d.infopo^ do begin + if fhasxft then begin + bo1:= (df_highresfont in drawinfo.gc.drawingflags) and + (fonthighres <> 0); + if bo1 then begin + po3:= pxftfont(fonthighres); + end + else begin + po3:= pxftfont(font); + end; + pe:= po1 + count; + while po1 < pe do begin + ca1:= card16(po1^); + if (ca1 and $fc00 = $d800) then begin //surrogate pair + inc(po1); + if (card16(po1^) and $fc00 = $dc00) then begin + ca1:= ((ca1 + ($0040-$d800)) shl 10) + card16(po1^) - $dc00; + xfttextextents32(appdisp,po3,@ca1,1,@glyphinfo); + po2^:= glyphinfo.xoff; + inc(po2); + po2^:= 0; + end + else begin + dec(po1); //invalid low part + xfttextextents32(appdisp,po3,@ca1,1,@glyphinfo); + po2^:= glyphinfo.xoff; + end; + end + else begin + xfttextextents32(appdisp,po3,@ca1,1,@glyphinfo); + po2^:= glyphinfo.xoff; + end; + inc(po1); + inc(po2); + end; + + if bo1 then begin + po2:= resultpo; + int2:= highresfontfakt div 2; //round up + for int1:= 0 to count - 1 do begin + int2:= int2 + po2^; + po2^:= int2 shr highresfontshift; + int2:= int2 and highresfontmask; + inc(po2); + end; + end; + end + else begin + case d.matrixmode of + fmm_linear: begin + for int1:= 0 to count - 1 do begin + char:= word(po1^); + if (char >= min_char_or_byte2) and (char <= max_char_or_byte2) then begin + po2^:= pxcharstruct(pchar(per_char) + + (char - min_char_or_byte2)*sizeof(xcharstruct))^.width; + end + else begin + po2^:= d.defaultwidth; + end; + inc(po1); + inc(po2); + end; + end; + fmm_matrix: begin + for int1:= 0 to count -1 do begin + charstructpo:= getmatrixcharstruct(po1^, + x11fontdataty(fontdata^.platformdata)); + if charstructpo <> nil then begin + po2^:= charstructpo^.width; + if po2^ = 0 then begin + po2^:= d.defaultwidth; + end; + end + else begin + po2^:= d.defaultwidth; + end; + inc(po1); + inc(po2); + end; + end; + else begin //fm_fix + int2:= max_bounds.width; + for int1:= 0 to count - 1 do begin + po2^:= int2; + inc(po2); + end; + end; + end; + end; + end; +{$ifdef FPC} {$checkpointer default} {$endif} + end; +// result:= gde_ok; + gdi_unlock; +end; + +procedure gdi_getfontmetrics(var drawinfo: drawinfoty); +var + po1: pxcharstruct; + glyphinfo: txglyphinfo; +begin + gdi_lock; + with drawinfo.getfontmetrics do begin +{$ifdef FPC} {$checkpointer off} {$endif} + with fontdata^,x11fontdataty(platformdata),d.infopo^ do begin + if fhasxft then begin + xfttextextents32(appdisp,pxftfont(font),@char,1,@glyphinfo); + with resultpo^ do begin + width:= glyphinfo.xoff; + leftbearing:= -glyphinfo.x; + rightbearing:= glyphinfo.xoff-glyphinfo.width+glyphinfo.x; + end; + end + else begin + case d.matrixmode of + fmm_linear: begin + if (word(char) >= min_char_or_byte2) and (word(char) <= max_char_or_byte2) then begin + po1:= pxcharstruct(pchar(per_char) + + (word(char) - min_char_or_byte2)*sizeof(xcharstruct)); + end + else begin + po1:= pxcharstruct(pchar(per_char) + + (default_char - min_char_or_byte2)*sizeof(xcharstruct)); + end; + end; + fmm_matrix: begin + po1:= getmatrixcharstruct(msechar(card16(char)), + x11fontdataty(fontdata^.platformdata)); + if po1 = nil then begin + po1:= getmatrixcharstruct(msechar(default_char), + x11fontdataty(fontdata^.platformdata)); + if po1 = nil then begin + with resultpo^ do begin + width:= 0; + leftbearing:= 0; + rightbearing:= 0; + end; + end; + end; + end; + else begin //fm_fix + po1:= @max_bounds; + end; + end; + with resultpo^ do begin + width:= po1^.width; + leftbearing:= po1^.lbearing; + rightbearing:= width - po1^.rbearing; + end; + end; + end; + end; +{$ifdef FPC} {$checkpointer default} {$endif} +// result:= gde_ok; + gdi_unlock; +end; + +procedure gdi_gettext16width(var drawinfo: drawinfoty); +var + int1: integer; + char: word; + charstructpo: pxcharstruct; + glyphinfo: txglyphinfo; +begin + gdi_lock; +{$ifdef FPC} {$checkpointer off} {$endif} + with drawinfo.gettext16width do begin + result:= 0; + with fontdata^,x11fontdataty(platformdata),d.infopo^ do begin + if fhasxft then begin + xfttextextentsutf16(appdisp,pxftfont(font),pointer(text),fcendianlittle, + count*2,@glyphinfo); + result:= glyphinfo.xoff; + end + else begin + case d.matrixmode of + fmm_linear: begin + for int1:= 0 to count - 1 do begin + char:= word(text[int1]); + if (char >= min_char_or_byte2) and (char <= max_char_or_byte2) then begin + inc(result,pxcharstruct(pchar(per_char) + + (char - min_char_or_byte2)*sizeof(xcharstruct))^.width); + end + else begin + inc(result,d.defaultwidth); + end; + end; + end; + fmm_matrix: begin + for int1:= 0 to count - 1 do begin + charstructpo:= getmatrixcharstruct(text[int1], + x11fontdataty(fontdata^.platformdata)); + if charstructpo <> nil then begin + inc(result,charstructpo^.width); + end + else begin + inc(result,d.defaultwidth); + end; + end; + end; + else begin //fm_fix + result:= max_bounds.width * count; + end; + end; + end; + end; + end; +{$ifdef FPC} {$checkpointer default} {$endif} + gdi_unlock; +end; + +function getcharstruct(const fontdata: fontdataty; char: msechar): pxcharstruct; +begin +{$ifdef FPC} {$checkpointer off} {$endif} + result:= nil; + with fontdata,x11fontdataty(platformdata),d.infopo^ do begin + case d.matrixmode of + fmm_linear: begin + if (word(char) >= min_char_or_byte2) and + (word(char) <= max_char_or_byte2) then begin + result:= pxcharstruct(pchar(per_char) + + (word(char) - min_char_or_byte2)*sizeof(xcharstruct)); + end; + end; + fmm_matrix: begin + result:= getmatrixcharstruct(char,x11fontdataty(fontdata.platformdata)); + end; + else begin //fmm_fix + result:= @d.infopo^.max_bounds; + end; + end; + end; +{$ifdef FPC} {$checkpointer default} {$endif} +end; + + +type + fontpropinfoty = record + foundry: string; + family_name: string; + weight_name: string; + slant: string; + setwidth_name: string; + add_style_name: string; + pixel_size: ptrint; + point_size: ptrint; + resolution_x: ptrint; + resolution_y: ptrint; + spacing: string; + average_width: ptrint; + charset_registry: string; + charset_encodeing: string; + min_space: ptrint; + norm_space: ptrint; + max_space: ptrint; + end_space: ptrint; + superscript_x: ptrint; + superscript_y: ptrint; + subscript_x: ptrint; + subscript_y: ptrint; + underline_position: ptrint; + underline_thickness: ptrint; + strikeout_ascent: ptrint; + strikeout_descent: ptrint; + italic_angle: ptrint; + x_height: ptrint; + weight: ptrint; + face_name: string; + font: string; + copyright: string; + avg_capital_width: ptrint; + avg_lowercase_width: ptrint; + relative_setwidth: ptrint; + relative_weight: ptrint; + cap_height: ptrint; + superscript_size: ptrint; + figure_width: ptrint; + subscript_size: ptrint; + small_cap_size: ptrint; + notice: string; + destination: ptrint; + font_type: string; + font_version: string; + rasterizer_name: string; + rasterizer_version: string; + raw_ascent: ptrint; + raw_descent: ptrint; + axis_names: string; + axis_limits: string; + axis_types: string; + dummy: ptrint; + end; + +procedure getfontproperties(var fontstruct: xfontstruct; var propinfo: fontpropinfoty); + + procedure setproperty(const prop: xfontprop); + + var + propnum: fontpropertiesty; + po: pchar; + + begin //setproperty + with prop do begin + for propnum:= low(fontpropertiesty) to high(fontpropertiesty) do begin + if name = fontpropertyatoms[propnum] then begin + break; + end; + end; + if propnum < fpnone then begin + if fontpropertynames[propnum].isstring then begin + if prop.card32 = 0 then begin + strfontproparty(propinfo)[propnum]:= ''; + end + else begin + po:= xgetatomname(appdisp,prop.card32); + strfontproparty(propinfo)[propnum]:= po; + xfree(po); + end; + end + else begin + intfontproparty(propinfo)[propnum]:= prop.card32; + end; + end; + end; + end; +var + int1: integer; + po: pxfontprop; + +begin //getfontproperties +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with fontstruct do begin + po:= properties; + for int1:= 0 to n_properties - 1 do begin + setproperty(po^); + inc(po); + end; + end; +end; + + +procedure gdi_getfonthighres(var drawinfo: drawinfoty); +var + pat1,pat2: pfcpattern; + res1: tfcresult; +// po1: pxftfont; +begin + gdi_lock; + if fhasxft then begin + with drawinfo.getfont do begin + pat1:= fontdatatoxftpat(fontdata^,true); + pat2:= xftfontmatch(appdisp,xdefaultscreen(appdisp),pat1,@res1); + if pat2 <> nil then begin + fontdata^.fonthighres:= ptruint(xftfontopenpattern(appdisp,pat2)); + end; + fcpatterndestroy(pat1); + end; + end; + gdi_unlock; +end; + +procedure gdi_getfont(var drawinfo: drawinfoty); + + procedure getfontdata(po: pxfontstruct); + var + charstructpo: pxcharstruct; + begin +{$ifdef FPC} {$checkpointer off} {$endif} + with drawinfo.getfont,fontdata^,x11fontdataty(platformdata) do begin + font:= po^.fid; + ascent:= po^.ascent; + descent:= po^.descent; + linespacing:= ascent + descent; + realheight:= linespacing; + caretshift:= 0; + d.infopo:= po; + with po^ do begin + if per_char = nil then begin + d.matrixmode:= fmm_fix; + end + else begin + if (min_byte1 = 0) and (max_byte1 = 0) then begin + d.matrixmode:= fmm_linear; + end + else begin + d.matrixmode:= fmm_matrix; + d.rowlength:= max_char_or_byte2 - min_char_or_byte2 + 1; + end; + end; + charstructpo:= getcharstruct(fontdata^,msechar(default_char)); + if charstructpo <> nil then begin + d.defaultwidth:= charstructpo^.width; + end; //0 otherwise + end; +{$ifdef FPC} {$checkpointer default} {$endif} + end; + end; + +var + po1: pxfontstruct; + po2: pxftfont; + fontinfo: fontinfoty; + int1: integer; + po3,po4: pfcpattern; + res1: tfcresult; + rea1: real; + {$ifdef mse_debugxft} + po5: pchar; + {$endif} +begin + gdi_lock; + setupfontinfo(drawinfo.getfont.fontdata^,fontinfo); +{$ifdef FPC} {$checkpointer off} {$endif} + with drawinfo.getfont.fontdata^ do begin + if fhasxft then begin + drawinfo.getfont.ok:= false; + po3:= buildxftpat(drawinfo.getfont.fontdata^,fontinfo,false); + po4:= xftfontmatch(appdisp,xdefaultscreen(appdisp),po3,@res1); + if po4 <> nil then begin + if fcpatterngetinteger(po4,fc_pixel_size,0,@int1) = fcresultmatch then begin + realheight:= int1; + end; + {$ifdef mse_debugxft} + if fcpatterngetstring(po4,fc_file,0,@po5) = fcresultmatch then begin + writeln('Font found. Name: "'+h.name+'" Height: '+ + inttostr(h.d.height)+' Realheight: '+inttostr(int1)+' File:'); + writeln('"'+string(po5)+'"'); + end; + {$endif} + po2:= xftfontopenpattern(appdisp,po4); //font owns the pattern + if po2 <> nil then begin + drawinfo.getfont.ok:= true; + getxftfontdata(po2,drawinfo); + if h.d.rotation <> 0 then begin //ascent and descent are 0 for rotated fonts + fcpatterndestroy(po3); + rea1:= h.d.rotation; + if rea1 <> 0 then begin + int1:= round(rea1/(pi/2)) mod 4; + if int1 < 0 then begin + int1:= int1 + 4; + end; + x11fontdataty(platformdata).d.xftdirection:= graphicdirectionty(int1); + //for xft colorbackground + end; + h.d.rotation:= 0; + po3:= buildxftpat(drawinfo.getfont.fontdata^,fontinfo,false); + po4:= xftfontmatch(appdisp,xdefaultscreen(appdisp),po3,@res1); + if po4 <> nil then begin + po2:= xftfontopenpattern(appdisp,po4); + if po2 <> nil then begin + ascent:= po2^.ascent; + descent:= po2^.descent; + x11fontdataty(platformdata).d.xftascent:= po2^.ascent; + x11fontdataty(platformdata).d.xftdescent:= po2^.descent; + xftfontclose(appdisp,po2); + end; + end; + h.d.rotation:= rea1; + end; + end; + end; + fcpatterndestroy(po3); + end + else begin + po1:= xloadqueryfont(appdisp,pchar(fontinfotoxlfdname(fontinfo))); + if po1 = nil then begin + if fs_italic in h.d.style then begin + fontinfo[fn_slant]:= 'o'; + po1:= xloadqueryfont(appdisp,pchar(fontinfotoxlfdname(fontinfo))); + fontinfo[fn_slant]:= 'i'; + end; + if po1 = nil then begin + if (h.name <> '') and (h.d.style * [fs_italic,fs_bold] = []) and + (h.charset <> '') and (h.d.height = 0) then begin + po1:= xloadqueryfont(appdisp,pchar(h.name)); + end; + if po1 = nil then begin + if simpledefaultfont then begin + po1:= xloadqueryfont(appdisp,pchar(fontinfo[fn_family_name])); + end; + if po1 = nil then begin + fontinfo[fn_family_name]:= 'fixed'; + po1:= xloadqueryfont(appdisp,pchar(fontinfotoxlfdname(fontinfo))); + if po1 = nil then begin + po1:= xloadqueryfont(appdisp,'fixed'); + end; + end; + end; + end; + end; + if po1 <> nil then begin + getfontdata(po1); + drawinfo.getfont.ok:= true; + end + else begin + drawinfo.getfont.ok:= false; + end; + end; + end; + {$ifdef FPC} {$checkpointer default} {$endif} + gdi_unlock; +end; + +procedure gdi_freefontdata(var drawinfo: drawinfoty); +begin + gdi_lock; + with drawinfo.getfont.fontdata^ do begin + if fhasxft then begin + xftfontclose(appdisp,pxftfont(font)); + if fonthighres <> 0 then begin + xftfontclose(appdisp,pxftfont(fonthighres)); + end; + end + else begin + with x11fontdataty(platformdata) do begin + xfreefontinfo(nil,d.infopo,1); + xunloadfont(appdisp,font); + end; + end; + end; + gdi_unlock; +end; + +{ +const + rgbwhite: rgbtriplety = (blue: $ff; green: $ff; red: $ff; res: $00); +} +procedure graytorgb(const sdev: paintdevicety; const srect: rectty; + const ddev: paintdevicety; const dpos: pointty; const gc: pgcty); +var + putpixelfunc: function (para1:PXImage; para2:cint; + para3:cint; para4:culong):cint; cdecl; + dimage,simage: pximage; + ps,ps1,pse,pd,pd1,pde: pointer; + int1,int2: integer; + gc1: tgc; +begin + with srect do begin + simage:= xgetimage(appdisp,sdev,x,y,cx,cy,$ff,zpixmap); + if simage <> nil then begin + dimage:= xcreateimage(appdisp,defvisual,defdepth,zpixmap,0,nil, + cx,cy,32,0); + if dimage <> nil then begin + try + int1:= cy*dimage^.bytes_per_line; + getmem(dimage^.data,int1); + ps:= simage^.data; + pd:= dimage^.data; + pde:= pd+int1; + if dimage^.bits_per_pixel = 32 then begin + repeat + ps1:= ps; + pse:= ps+cx; + pd1:= pd; + repeat + pbyte(pd1)^:= pbyte(ps1)^; + inc(pd1); + pbyte(pd1)^:= pbyte(ps1)^; + inc(pd1); + pbyte(pd1)^:= pbyte(ps1)^; + inc(pd1,2); + inc(ps1); + until ps1 = pse; + ps:= ps+simage^.bytes_per_line; + pd:= pd+dimage^.bytes_per_line; + until pd = pde; + end + else begin + putpixelfunc:= dimage^.f.put_pixel; + for int1:= 0 to cy - 1 do begin + ps1:= ps; + for int2:= 0 to cx - 1 do begin + putpixelfunc(dimage,int2,int1,gui_graytopixel(pbyte(ps1)[int2])); + end; + ps:= ps+simage^.bytes_per_line; + end; + end; + except + end; + if gc <> nil then begin + gc1:= tgc(gc^.handle); + end + else begin + gc1:= creategc(ddev); + end; + xputimage(appdisp,ddev,gc1,dimage,0,0,dpos.x,dpos.y,cx,cy); + if gc = nil then begin + xfreegc(appdisp,gc1); + end; + if dimage^.data <> nil then begin + freemem(dimage^.data); + dimage^.data:= nil; + end; + xdestroyimage(dimage); + end; + xdestroyimage(simage); + end; + end; +end; + +procedure rgbtogray(const sdev: paintdevicety; const srect: rectty; + const ddev: paintdevicety; const dpos: pointty; const gc: pgcty); +var + getpixelfunc: function (para1:PXImage; para2:cint; para3:cint):culong; cdecl; + dimage,simage: pximage; + ps,ps1,pse,pd,pd1,pde: pointer; + int1,int2: integer; + wo1: word; + lwo1: word; + gc1: tgc; +begin + with srect do begin + simage:= xgetimage(appdisp,sdev,x,y,cx,cy,$ffffff,zpixmap); + if simage <> nil then begin + dimage:= xcreateimage(appdisp,defvisual,8,zpixmap,0,nil,cx,cy,32,0); + if dimage <> nil then begin + try + int1:= cy*dimage^.bytes_per_line; + getmem(dimage^.data,int1); + ps:= simage^.data; + pd:= dimage^.data; + pde:= pd+int1; + if simage^.bits_per_pixel = 32 then begin + repeat + ps1:= ps; + pse:= ps+cx*4; + pd1:= pd; + repeat + wo1:= pbyte(ps1)^; + inc(ps1); + wo1:= wo1 + pbyte(ps1)^; + inc(ps1); + pbyte(pd1)^:= (wo1 + pbyte(ps1)^) div 3; + inc(ps1,2); + inc(pd1); + until ps1 = pse; + ps:= ps+simage^.bytes_per_line; + pd:= pd+dimage^.bytes_per_line; + until pd = pde; + end + else begin + getpixelfunc:= simage^.f.get_pixel; + for int1:= 0 to cy - 1 do begin + pd1:= pd; + for int2:= 0 to cx - 1 do begin + lwo1:= getpixelfunc(simage,int2,int1); + pbyte(pd1)[int2]:= (lwo1 and $ff + ((lwo1 and $ff00) shr 8) + + ((lwo1 and $ff0000) shr 16)) div 3; + + end; + pd:= pd+dimage^.bytes_per_line; + end; + end; + except + end; + if gc <> nil then begin + gc1:= tgc(gc^.handle); + end + else begin + gc1:= creategc(ddev); + end; + xputimage(appdisp,ddev,gc1,dimage,0,0,dpos.x,dpos.y,cx,cy); + if gc = nil then begin + xfreegc(appdisp,gc1); + end; + if dimage^.data <> nil then begin + freemem(dimage^.data); + dimage^.data:= nil; + end; + xdestroyimage(dimage); + end; + xdestroyimage(simage); + end; + end; +end; + +procedure gdi_copyarea(var drawinfo: drawinfoty); //gdifunc +var + needstransform: boolean; + transform: txtransform; + + procedure updatetransform(const apic: tpicture); + begin + if needstransform then begin + xrendersetpicturetransform(appdisp,apic,@transform); + if al_intpol in drawinfo.copyarea.alignment then begin + xrendersetpicturefilter(appdisp,apic,'good',nil,0); + end; + end + end; + + function getscale(const sourcesize,destsize,sourcepos: integer; + out destpos: integer): txfixed; +// var +// int1: integer; + begin + if (sourcesize > 0) and (sourcesize <> destsize) then begin + result:= (sourcesize * $10000) div destsize; + //pixel end to pixel end + if result > 0 then begin + if sourcesize * $10000 div result < destsize then begin + dec(result); + end; + destpos:= (sourcepos * $10000 + result div 2) div result; + end + else begin + destpos:= sourcepos * $10000; //very big + end; + end + else begin + result:= $10000; + destpos:= sourcepos; + end; + end; + +var + amask: pixmapty; + xvalues: xgcvalues; + pixmap: pixmapty; + pixmapgc: tgc; + maskgc: gcty; + bitmap: pixmapty; + bitmapgc,bitmapgc2: tgc; + int1: integer; + spic,dpic,cpic,maskpic: tpicture; + sattributes: txrenderpictureattributes; + dattributes: txrenderpictureattributes; + pixmap2: pixmapty; + pictop: integer; + sourceformats: culong = cpclipmask or cpclipxorigin or cpclipyorigin; + destformats: culong = cpgraphicsexposure; + monomask: boolean; +// stipplemask: boolean; + spd: paintdevicety; + skind,dkind: bitmapkindty; + x1,y1: integer; + int2: integer; + format1: pxrenderpictformat; + ax,ay,sx,sy,dx,dy: integer; + sdev: paintdevicety; + ddev: paintdevicety; + + procedure checkddevcopy(); + begin + with drawinfo,copyarea do begin + if ddev <> paintdevice then begin + sdev:= gui_createpixmap(destrect^.size,0,bmk_gray); + rgbtogray(ddev,mr(nullpoint,destrect^.size),sdev,nullpoint,nil); + with destrect^ do begin + xcopyarea(appdisp,sdev,paintdevice,tgc(gc.handle),0,0,cx,cy,x,y); + end; + xfreepixmap(appdisp,sdev); + xfreepixmap(appdisp,ddev); + end; + end; + end; + +var + opapic,masksourcepic: tpicture; + destcopygc: tgc; + dpic2: tpicture; + ddev2: paintdevicety; +label + endlab,endlab2; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + xvalues.graphics_exposures:= {$ifdef xboolean}false{$else}0{$endif}; + with drawinfo,copyarea,sourcerect^,gc,x11gcty(platformdata).d do begin + dkind:= kind; + skind:= tcanvas1(source).fdrawinfo.gc.kind; + needstransform:= (alignment * [al_stretchx,al_stretchy] <> []) and + ((destrect^.cx <> sourcerect^.cx) or + (destrect^.cy <> sourcerect^.cy)) and + (destrect^.cx > 0) and (destrect^.cy > 0); + monomask:= (mask = nil) or (mask.kind = bmk_mono); +// stipplemask:= false; + if hasxrender and (needstransform or (longword(opacity) <> maxopacity) or + not monomask) then begin + if needstransform then begin + if mask <> nil then begin + monomask:= false; //xrender ignores clip_mask for transformations + end; + transform:= unitytransform; + transform[0,0]:= getscale(cx,destrect^.cx,x,ax); + transform[1,1]:= getscale(cy,destrect^.cy,y,ay); + end + else begin + ax:= x; + ay:= y; + end; + sx:= ax; + sy:= ay; + pictop:= pictopsrc; + maskpic:= 0; + if (longword(opacity) <> maxopacity) and (mask = nil){monomask} then begin + maskpic:= createmaskpicture(opacity,bmk_rgb); + //clip_mask ignored by xrender + pictop:= pictopover; + end + else begin + if not monomask then begin + if (longword(opacity) <> maxopacity) then begin + ax:= 0; + ay:= 0; + bitmap:= gui_createpixmap(size,0,mask.kind); + if bitmap <> 0 then begin + xvalues.foreground:= 0; + bitmapgc2:= xcreategc(appdisp,bitmap, + gcforeground or gcgraphicsexposures,@xvalues); + if bitmapgc2 <> nil then begin + xfillrectangle(appdisp,bitmap,bitmapgc2,0,0,cx,cy); + xfreegc(appdisp,bitmapgc2); + opapic:= createmaskpicture(opacity,mask.kind); + masksourcepic:= createmaskpicture(mask); + maskpic:= createmaskpicture(bitmap,mask.kind); + xrendercomposite(appdisp,pictopover,masksourcepic,opapic,maskpic, + x,y,0,0,0,0,cx,cy); + xrenderfreepicture(appdisp,opapic); + xrenderfreepicture(appdisp,masksourcepic); + end; + gui_freepixmap(bitmap); + end; + end + else begin + maskpic:= createmaskpicture(mask); + end; + if not(al_nomaskscale in alignment) then begin + updatetransform(maskpic); + end; + pictop:= pictopover; + end; + end; + with sattributes do begin + clip_x_origin:= 0; + clip_y_origin:= 0; + if (mask <> nil) and monomask then begin + clip_mask:= tsimplebitmap1(mask).handle; + end + else begin + clip_mask:= 0; + end; + end; + with dattributes do begin + graphics_exposures:= 0; +// clip_mask:= sattributes.clip_mask; + end; + if (dkind <> skind) and ((dkind = bmk_mono) or (skind = bmk_mono)) then begin + if dkind = bmk_mono then begin //color to mono + if maskpic <> 0 then begin + xrenderfreepicture(appdisp,maskpic); + end; + exit; //not supported; //todo !!! + end + else begin //monochrome -> color + bitmapgc2:= nil; + bitmap:= 0; + if (mask <> nil) and (mask.kind = bmk_mono) then begin + bitmap:= gui_createpixmap(size,0,bmk_mono); + if bitmap <> 0 then begin + bitmapgc2:= xcreategc(appdisp,bitmap,gcgraphicsexposures,@xvalues); + if bitmapgc2 <> nil then begin + xcopyarea(appdisp,tcanvas1(source).fdrawinfo.paintdevice, + bitmap,bitmapgc2,x,y,cx,cy,0,0); + xvalues.xfunction:= gxand; + xchangegc(appdisp,bitmapgc2,gcfunction,@xvalues); + xcopyarea(appdisp,mask.handle,bitmap,bitmapgc2,x,y,cx,cy,0,0); + //new source = source and mask + ax:= 0; + ay:= 0; + x1:= 0; + y1:= 0; + with sattributes do begin + clip_x_origin:= 0; + clip_y_origin:= 0; + end; + end + else begin + goto endlab2; + end; + end + else begin + goto endlab2; + end; + spd:= bitmap; + end + else begin + spd:= tcanvas1(source).fdrawinfo.paintdevice; + x1:= x; + y1:= y; + end; + spic:= xrendercreatepicture(appdisp,spd,bitmaprenderpictformat, + sourceformats,@sattributes); + format1:= screenrenderpictformat; + dx:= destrect^.x; + dy:= destrect^.y; + ddev:= paintdevice; + if (maskpic <> 0) or (dkind = bmk_gray) then begin + //bmk_gray is alpha only -> needs rgb copy + dx:= 0; + dy:= 0; + ddev:= gui_createpixmap(destrect^.size,0,bmk_rgb); + if dkind = bmk_gray then begin + graytorgb(paintdevice,destrect^,ddev,nullpoint,nil); + if maskpic <> 0 then begin //get original copy + ddev2:= gui_createpixmap(destrect^.size,0,bmk_rgb); + destcopygc:= xcreategc(appdisp,ddev,gcgraphicsexposures, + @xvalues); + with destrect^ do begin + xcopyarea(appdisp,ddev,ddev2,destcopygc,0,0,cx,cy,0,0); + end; + xfreegc(appdisp,destcopygc); + end; + end + else begin + destcopygc:= xcreategc(appdisp,ddev,gcgraphicsexposures, + @xvalues); + with destrect^ do begin + xcopyarea(appdisp,paintdevice,ddev,destcopygc,x,y,cx,cy,0,0); + end; + xfreegc(appdisp,destcopygc); + ddev2:= paintdevice; //use original destination + end; + end; + dpic:= xrendercreatepicture(appdisp,ddev,format1, + destformats,@dattributes); + pictop:= pictopover; + if dkind = bmk_gray then begin + cpic:= creategraycolorpicture(acolorforeground); + end + else begin + cpic:= createcolorpicture(acolorforeground); + end; + if (gcclipregion <> 0) and (ddev = paintdevice) then begin + setregion(gc,region(gcclipregion),dpic); + end; + updatetransform(spic); + if acolorforeground <> cl_transparent then begin + xrendercomposite(appdisp,pictop,cpic,spic,dpic,0,0,ax,ay, + dx,dy,destrect^.cx,destrect^.cy); + end; + xrenderfreepicture(appdisp,cpic); + if df_opaque in gc.drawingflags then begin + if bitmap <> 0 then begin + xvalues.xfunction:= gxorinverted; + xchangegc(appdisp,bitmapgc2,gcfunction,@xvalues); + xcopyarea(appdisp,mask.handle,bitmap,bitmapgc2,x,y,cx,cy,0,0); + end; + xvalues.xfunction:= gxxor; + xvalues.foreground:= $ffffffff; + bitmapgc:= xcreategc(appdisp,spd, + gcforeground or gcfunction or gcgraphicsexposures,@xvalues); + xfillrectangle(appdisp,spd,bitmapgc,x1,y1,cx,cy); + if dkind = bmk_gray then begin + cpic:= creategraycolorpicture(acolorbackground); + end + else begin + cpic:= createcolorpicture(acolorbackground); + end; + xrendercomposite(appdisp,pictop,cpic,spic,dpic,0,0,ax,ay, + dx,dy,destrect^.cx,destrect^.cy); + xrenderfreepicture(appdisp,cpic); + xfillrectangle(appdisp,spd,bitmapgc,x1,y1,cx,cy); + xfreegc(appdisp,bitmapgc); + end; + xrenderfreepicture(appdisp,spic); + if maskpic <> 0 then begin + dpic2:= xrendercreatepicture(appdisp,ddev2,format1, + destformats,@dattributes); + with destrect^ do begin + xrendercomposite(appdisp,pictop,dpic,maskpic,dpic2,0,0,ax,ay,x,y,cx,cy); + end; + xrenderfreepicture(appdisp,dpic2); + xfreepixmap(appdisp,ddev); + if dkind = bmk_gray then begin + ddev:= ddev2; + end + else begin + ddev:= paintdevice; //no checkddevcopy() + end; + end; + xrenderfreepicture(appdisp,dpic); + checkddevcopy(); //possibly rgb -> gray conversion +endlab2: + if maskpic <> 0 then begin + xrenderfreepicture(appdisp,maskpic); + end; + if bitmapgc2 <> nil then begin + xfreegc(appdisp,bitmapgc2); + end; + if bitmap <> 0 then begin + xfreepixmap(appdisp,bitmap); + end; + end; + end + else begin //no colorconvert + if al_nomaskscale in alignment then begin + ax:= ax + maskshift.x; + ay:= ay + maskshift.y; + end + else begin + ax:= ax + maskshiftscaled.x; + ay:= ay + maskshiftscaled.y; + end; + dx:= destrect^.x; + dy:= destrect^.y; + format1:= screenrenderpictformat; + sdev:= tcanvas1(source).paintdevice; + ddev:= paintdevice; + if skind = bmk_gray then begin + sx:= 0; + sy:= 0; + sdev:= gui_createpixmap(sourcerect^.size,0,bmk_rgb); + graytorgb(tcanvas1(source).paintdevice,sourcerect^,sdev,nullpoint,nil); + end; + if dkind = bmk_gray then begin + dx:= 0; + dy:= 0; + ddev:= gui_createpixmap(destrect^.size,0,bmk_rgb); + graytorgb(paintdevice,destrect^,ddev,nullpoint,nil); + end; + spic:= xrendercreatepicture(appdisp,sdev,format1, + sourceformats,@sattributes); + dpic:= xrendercreatepicture(appdisp,ddev,format1, + destformats,@dattributes); + if (gcclipregion <> 0) and (ddev = paintdevice) then begin + setregion(gc,region(gcclipregion),dpic); + end; + updatetransform(spic); + xrendercomposite(appdisp,pictop,spic,maskpic,dpic,sx,sy,ax,ay, + dx,dy,destrect^.cx,destrect^.cy); + xrenderfreepicture(appdisp,spic); + xrenderfreepicture(appdisp,dpic); + if sdev <> tcanvas1(source).paintdevice then begin + xfreepixmap(appdisp,sdev); + end; + checkddevcopy(); + if maskpic <> 0 then begin + xrenderfreepicture(appdisp,maskpic); + end; + end; + end + else begin //direct x11 + pixmap2:= 0; + if copymode <> gcrasterop then begin + xsetfunction(appdisp,tgc(gc.handle),integer(copymode)); + end; + if mask <> nil then begin + amask:= tsimplebitmap1(mask).handle; + if gcclipregion <> 0 then begin + pixmap2:= gui_createpixmap(size,0,bmk_mono); + maskgc.handle:= ptruint(xcreategc(appdisp,pixmap2,gcgraphicsexposures, + @xvalues)); + xfillrectangle(appdisp,pixmap2,tgc(maskgc.handle),0,0,cx,cy); + maskgc.cliporigin:= subpoint(cliporigin,destrect^.pos); + setregion(maskgc,region(gcclipregion)); + xcopyarea(appdisp,amask,pixmap2,tgc(maskgc.handle), + x+maskshiftscaled.x,y+maskshiftscaled.y,cx,cy,0,0); + xvalues.clip_x_origin:= destrect^.x; + xvalues.clip_y_origin:= destrect^.y; + xvalues.clip_mask:= pixmap2; + xchangegc(appdisp,tgc(gc.handle),gcclipxorigin or gcclipyorigin or + gcclipmask,@xvalues); + xfreegc(appdisp,tgc(maskgc.handle)); + end + else begin + xvalues.clip_mask:= amask; + xvalues.clip_x_origin:= destrect^.x - x - maskshiftscaled.x; + xvalues.clip_y_origin:= destrect^.y - y - maskshiftscaled.y; + xchangegc(appdisp,tgc(gc.handle),gcclipxorigin or gcclipyorigin or + gcclipmask,@xvalues); + end; + end; + if skind = dkind then begin + xcopyarea(appdisp,tcanvas1(source).fdrawinfo.paintdevice,paintdevice, + tgc(gc.handle),x,y,cx,cy,destrect^.x,destrect^.y); + end + else begin + if (skind = bmk_gray) and (dkind = bmk_rgb) then begin + graytorgb(tcanvas1(source).fdrawinfo.paintdevice,sourcerect^, + paintdevice,destrect^.pos,@gc); + end + else begin + if (skind = bmk_rgb) and (dkind = bmk_gray) then begin + rgbtogray(tcanvas1(source).fdrawinfo.paintdevice,sourcerect^, + paintdevice,destrect^.pos,@gc); + end + else begin + if dkind = bmk_mono then begin //convert to monochrome + pixmap:= gui_createpixmap(size,0,skind); + if pixmap = 0 then begin + goto endlab; + end; + pixmapgc:= xcreategc(appdisp,pixmap,gcgraphicsexposures,@xvalues); + if pixmapgc <> nil then begin + xcopyarea(appdisp,tcanvas1(source).fdrawinfo.paintdevice,pixmap, + pixmapgc,x,y,cx,cy,0,0); + xvalues.foreground:= transparentcolor; + xvalues.xfunction:= integer(rop_xor); + xchangegc(appdisp,pixmapgc,gcforeground or gcfunction,@xvalues); + xfillrectangle(appdisp,pixmap,pixmapgc,0,0,cx,cy); + bitmap:= gui_createpixmap(size,0,bmk_mono); + if bitmap <> 0 then begin + xvalues.foreground:= pixel0; + bitmapgc:= xcreategc(appdisp,bitmap, + gcforeground or gcgraphicsexposures,@xvalues); + if bitmapgc <> nil then begin + xfillrectangle(appdisp,bitmap,bitmapgc,0,0,cx,cy); + xvalues.xfunction:= integer(rop_or); + xvalues.background:= pixel0; + xvalues.foreground:= pixel1; + xchangegc(appdisp,bitmapgc,gcfunction or gcforeground or + gcbackground,@xvalues); + if skind = bmk_gray then begin + int2:= 8; + end + else begin + int2:= defdepth; + end; + for int1:= 0 to int2-1 do begin + xcopyplane(appdisp,pixmap,bitmap,bitmapgc,0,0,cx,cy, + 0,0,1 shl int1); + end; + xcopyarea(appdisp,bitmap,paintdevice,tgc(gc.handle),0,0,cx,cy, + destrect^.x,destrect^.y); + xfreegc(appdisp,bitmapgc); + end; + xfreepixmap(appdisp,bitmap) + end; + xfreegc(appdisp,pixmapgc); + end; + xfreepixmap(appdisp,pixmap); + end + else begin + //convert from monochrome +// stipplemask:= true; + pixmapgc:= xcreategc(appdisp,paintdevice,gcgraphicsexposures,@xvalues); + if pixmapgc <> nil then begin + xcopygc(appdisp,tgc(gc.handle),gcfunction or gcplanemask or + gcsubwindowmode or gcgraphicsexposures or gcclipxorigin or + gcclipyorigin or gcclipmask or gcforeground or gcbackground,pixmapgc); + with xvalues do begin + stipple:= tcanvas1(source).fdrawinfo.paintdevice; + ts_x_origin:= destrect^.x-x; + ts_y_origin:= destrect^.y-y; + if df_opaque in gc.drawingflags then begin + fill_style:= fillopaquestippled; + end + else begin + fill_style:= fillstippled; + end; + end; + xchangegc(appdisp,pixmapgc,gcfillstyle or gcstipple or + gctilestipxorigin or gctilestipyorigin,@xvalues); + xfillrectangle(appdisp,paintdevice,pixmapgc,destrect^.x,destrect^.y,cx,cy); + xfreegc(appdisp,pixmapgc); + end; + end; + end; + end; + end; + if mask <> nil then begin + xvalues.clip_x_origin:= 0; + xvalues.clip_y_origin:= 0; + xchangegc(appdisp,tgc(gc.handle),gcclipxorigin or gcclipyorigin,@xvalues); + end; + if copymode <> gcrasterop then begin + xsetfunction(appdisp,tgc(gc.handle),integer(gcrasterop)); + end; +endlab: + if pixmap2 <> 0 then begin + xfreepixmap(appdisp,pixmap2); + end; + end; + end; +end; + +procedure gdi_getimage(var drawinfo: drawinfoty); //gdifunc +begin + //dummy +end; + +procedure gdi_fonthasglyph(var drawinfo: drawinfoty); //gdifunc +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo,fonthasglyph do begin + if fhasxft then begin + hasglyph:= xftcharexists(appdisp,pxftfont(font),unichar); + end + else begin + hasglyph:= true; + end; + end; +end; + +procedure gdi_drawlines(var drawinfo: drawinfoty); //gdifunc +var + po1: ppointty; + pointcount: integer; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo,points,x11gcty(gc.platformdata).d do begin + if xfts_smooth in xftstate then begin + if linestria(drawinfo,po1,pointcount) then begin + compositetriangles(drawinfo,ptrianglety(po1),pointcount div 3); + end + else begin + compositetristrip(drawinfo,po1,pointcount); + end; + end + else begin + transformpoints(drawinfo,closed); + pointcount:= count; + if closed then begin + inc(pointcount); + end; + xdrawlines(appdisp,paintdevice,tgc(gc.handle),buffer.buffer,pointcount, + coordmodeorigin); + end; + end; +end; + +procedure gdi_drawlinesegments(var drawinfo: drawinfoty); //gdifunc +var + triacount: integer; + po1: ptrianglety; + +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo,drawinfo.points,x11gcty(gc.platformdata).d do begin + if xfts_smooth in xftstate then begin + linesegmentstria(drawinfo,po1,triacount); + compositetriangles(drawinfo,po1,triacount); + end + else begin + transformpoints(drawinfo,false); + xdrawsegments(appdisp,paintdevice,tgc(gc.handle),buffer.buffer,count div 2); + end; + end; +end; + +procedure gdi_fillellipse(var drawinfo: drawinfoty); //gdifunc +var + po1: ppointty; + pointcount: integer; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo,drawinfo.rect.rect^ do begin + if xfts_smooth in x11gcty(gc.platformdata).d.xftstate then begin + fillellipsetria(drawinfo,po1,pointcount); + with x11gcty(gc.platformdata).d do begin + compositetrifan(drawinfo,po1,pointcount); + end; + end + else begin + xfillarc(appdisp,paintdevice,tgc(gc.handle), + x+origin.x-cx div 2,y+origin.y - cy div 2,cx,cy,0,wholecircle); + end; + end; +end; + +const + angscale = 64*360/(2*pi); + +procedure gdi_fillarc(var drawinfo: drawinfoty); //gdifunc +var + xvalues: xgcvalues; + po1: ppointty; + pointcount: integer; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo,x11gcty(gc.platformdata).d,drawinfo.arc,rect^ do begin + if xfts_smooth in xftstate then begin + fillarctria(drawinfo,po1,pointcount); + compositetrifan(drawinfo,po1,pointcount); + end + else begin + if pieslice then begin + xvalues.arc_mode:= arcpieslice; + end + else begin + xvalues.arc_mode:= arcchord; + end; + xchangegc(appdisp,tgc(gc.handle),gcarcmode,@xvalues); + xfillarc(appdisp,paintdevice,tgc(gc.handle), + x+origin.x-cx div 2,y+origin.y - cy div 2,cx,cy, + round(startang*angscale),round(extentang*angscale)); + end; + end; +end; + +procedure gdi_drawarc(var drawinfo: drawinfoty); //gdifunc +var + po1: ppointty; + pointcount: integer; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo,x11gcty(gc.platformdata).d,drawinfo.arc,rect^, + triagcty(gc.platformdata).d do begin + if xfts_smooth in xftstate then begin + if arctria(drawinfo,po1,pointcount) then begin + compositetriangles(drawinfo,ptrianglety(po1),pointcount div 3); + end + else begin + compositetristrip(drawinfo,po1,pointcount); + end; + end + else begin + xdrawarc(appdisp,paintdevice,tgc(gc.handle), + x+origin.x-cx div 2,y+origin.y - cy div 2,cx,cy, + round(startang*angscale),round(extentang*angscale)); + end; + end; +end; + +procedure gdi_drawellipse(var drawinfo: drawinfoty); //gdifunc +var + po1: ppointty; + pointcount: integer; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo,x11gcty(gc.platformdata).d,rect.rect^ do begin + if xfts_smooth in xftstate then begin + with x11gcty(gc.platformdata).d do begin + if ellipsetria(drawinfo,po1,pointcount) then begin + compositetriangles(drawinfo,ptrianglety(po1),pointcount div 3); + end + else begin + compositetristrip(drawinfo,po1,pointcount); + end; + end; + end + else begin + xdrawarc(appdisp,paintdevice,tgc(gc.handle), + x+origin.x-cx div 2,y+origin.y - cy div 2,cx,cy,0,wholecircle); + end; + end; +end; + +procedure gdi_drawstring16(var drawinfo: drawinfoty); //gdifunc +var + po1: pxchar2b; + xvalues: xgcvalues; + glyphinfo: txglyphinfo; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo,drawinfo.text16pos do begin + if fhasxft then begin + {$ifdef FPC}{$checkpointer off}{$endif} + checkxftdraw(drawinfo); + checkxftstate(drawinfo,[]); + transformpos(drawinfo); + with pxpoint(buffer.buffer)^ do begin + with x11gcty(gc.platformdata).d do begin + if df_opaque in gc.drawingflags then begin + xfttextextentsutf16(appdisp,xftfont,pointer(text),fcendianlittle, + count*2,@glyphinfo); + xvalues.foreground:= xftcolorbackground.pixel; + xchangegc(appdisp,tgc(gc.handle),gcforeground,@xvalues); + with x11gcty(gc.platformdata).d.xftfontdata^ do begin + case xftdirection of + gd_right: begin + xfillrectangle(appdisp,paintdevice,tgc(gc.handle), + x{-glyphinfo.x},y-xftascent, + glyphinfo.xoff,xftascent+xftdescent); + end; + gd_up: begin + xfillrectangle(appdisp,paintdevice,tgc(gc.handle), + x-xftascent,y+glyphinfo.yoff, + xftascent+xftdescent,-glyphinfo.yoff); + end; + gd_left: begin + xfillrectangle(appdisp,paintdevice,tgc(gc.handle), + x+glyphinfo.xoff{-glyphinfo.x},y-xftdescent, + -glyphinfo.xoff,xftascent+xftdescent); + end; + gd_down: begin + xfillrectangle(appdisp,paintdevice,tgc(gc.handle), + x-xftdescent,y, + xftascent+xftdescent,glyphinfo.yoff); + end; + end; + end; + xvalues.foreground:= xftcolor.pixel; + xchangegc(appdisp,tgc(gc.handle),gcforeground,@xvalues); + end; + xftdrawstringutf16(xftdraw,@xftcolor,xftfont,x,y,pointer(text), + fcendianlittle,count*2); + end; + end +{$ifdef FPC}{$checkpointer default}{$endif} + end + else begin + po1:= transformtext16pos(drawinfo); //swap bytes + with pxpoint(buffer.buffer)^ do begin + if df_opaque in gc.drawingflags then begin + xdrawimagestring16(appdisp,paintdevice,tgc(gc.handle),x,y,po1,count); + end + else begin + xdrawstring16(appdisp,paintdevice,tgc(gc.handle),x,y,po1,count); + end; + end; + end; + end; +end; + +procedure gdi_setcliporigin(var drawinfo: drawinfoty); //gdifunc +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo,gc do begin + xsetcliporigin(appdisp,tgc(handle),cliporigin.x,cliporigin.y); + end; +end; + +procedure gdi_fillrect(var drawinfo: drawinfoty); //gdifunc +var + points1: array[0..3] of xpoint; + x1,y1: smallint; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo,drawinfo.rect.rect^ do begin + x1:= x+origin.x; + y1:= y+origin.y; + points1[0].x:= x1; + points1[0].y:= y1; + points1[1].y:= y1; + points1[3].x:= x1; + inc(x1,cx); + inc(y1,cy); + points1[1].x:= x1; + points1[2].x:= x1; + points1[2].y:= y1; + points1[3].y:= y1; + + xfillpolygon(appdisp,paintdevice,tgc(gc.handle),@points1[0],4, + complex,coordmodeorigin); + end; +end; + +procedure gdi_fillpolygon(var drawinfo: drawinfoty); //gdifunc +var + int1: integer; + po1,po2: pxpointfixed; + po3: ppointty; +// offsx,offsy: integer; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo do begin + if xfts_smooth in x11gcty(gc.platformdata).d.xftstate then begin + if points.count > 2 then begin + polytria(drawinfo,ptrianglety(po3),int1); + if int1 > 0 then begin + po1:= pointer(po3); + po2:= pointer(ptrianglety(po3)+int1); + repeat + po1^.x:= po1^.x << 16; + po1^.y:= po1^.y << 16; + inc(po1); + until po1 = po2; + compositetriangles(drawinfo,ptrianglety(po3),int1); + end; + end; + end + else begin + transformpoints(drawinfo,false); + with points do begin + xfillpolygon(appdisp,paintdevice,tgc(gc.handle),buffer.buffer, + count,complex,coordmodeorigin); + end; + end; + end; +end; + + +function createregion: regionty; overload; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= regionty(xcreateregion()); +end; + +function recttoxrect(const rect: rectty): xrectangle; +begin + with rect do begin + result.x:= x; + result.y:= y; + result.width:= cx; + result.height:= cy; + end; +end; + +function createregion(const rect: rectty): regionty; overload; +var + rect1: xrectangle; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= regionty(xcreateregion); + rect1:= recttoxrect(rect); + xunionrectwithregion(@rect1,region(result),region(result)); +end; + +procedure gdi_createemptyregion(var drawinfo: drawinfoty); //gdifunc +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo.regionoperation do begin + dest:= createregion; + end; +end; + +procedure gdi_createrectregion(var drawinfo: drawinfoty); //gdifunc +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo.regionoperation do begin + dest:= createregion(rect); + end; +end; + +procedure gdi_createrectsregion(var drawinfo: drawinfoty); //gdifunc +var + int1: integer; + rect1: xrectangle; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo.regionoperation do begin + dest:= createregion; + for int1:= 0 to rectscount - 1 do begin + rect1:= recttoxrect(rectspo^[int1]); + xunionrectwithregion(@rect1,region(dest),region(dest)); + end; + end; +end; + +procedure gdi_destroyregion(var drawinfo: drawinfoty); //gdifunc +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo.regionoperation do begin + if source <> 0 then begin + xdestroyregion(region(source)); + end; + end; +end; + +procedure gdi_regionisempty(var drawinfo: drawinfoty); //gdifunc +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo.regionoperation do begin + dest:= xemptyregion(region(source)); + if dest <> 0 then begin + dest:= 1; + end; + end; +end; + +procedure gdi_regionclipbox(var drawinfo: drawinfoty); //gdifunc +var + rect1: xrectangle; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo.regionoperation do begin + xclipbox(region(source),@rect1); + rect.x:= rect1.x; + rect.y:= rect1.y; + rect.cx:= rect1.width; + rect.cy:= rect1.height; + end; +end; + +procedure gdi_copyregion(var drawinfo: drawinfoty); //gdifunc +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo.regionoperation do begin + if source = 0 then begin + dest:= 0; + end + else begin + dest:= ptruint(xcreateregion); + xunionregion(region(dest),region(source),region(dest)); + end; + end; +end; + +procedure gdi_moveregion(var drawinfo: drawinfoty); //gdifunc +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo.regionoperation do begin + xoffsetregion(region(source),rect.x,rect.y); + end; +end; + +procedure gdi_regsubrect(var drawinfo: drawinfoty); //gdifunc +var + reg1: region; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo.regionoperation do begin + reg1:= region(createregion(rect)); + xsubtractregion(region(dest),reg1,region(dest)); + xdestroyregion(reg1); + end; +end; + +procedure gdi_regintersectrect(var drawinfo: drawinfoty); //gdifunc +var + reg1: region; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo.regionoperation do begin + reg1:= region(createregion(rect)); + xintersectregion(region(dest),reg1,region(dest)); + xdestroyregion(reg1); + end; +end; + +procedure gdi_regintersectregion(var drawinfo: drawinfoty); //gdifunc +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo.regionoperation do begin + xintersectregion(region(dest),region(source),region(dest)); + end; +end; + +procedure gdi_regaddrect(var drawinfo: drawinfoty); //gdifunc +var + rect1: xrectangle; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo.regionoperation do begin + rect1:= recttoxrect(rect); + xunionrectwithregion(@rect1,region(dest),region(dest)); + end; +end; + +procedure gdi_regaddregion(var drawinfo: drawinfoty); //gdifunc +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo.regionoperation do begin + xunionregion(region(dest),region(source),region(dest)); + end; +end; + +procedure gdi_regsubregion(var drawinfo: drawinfoty); //gdifunc +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + with drawinfo.regionoperation do begin + xsubtractregion(region(dest),region(source),region(dest)); + end; +end; + +function hasxft: boolean; +begin + result:= fhasxft; +end; + +var + fhasfontconfig: boolean; + +function getxftlib: boolean; +const + funcs: array[0..21] of funcinfoty = ( + (n: 'XftDrawDestroy'; d: @XftDrawDestroy), + (n: 'XftDrawSetClipRectangles'; d: @XftDrawSetClipRectangles), + (n: 'XftDrawCreate'; d: @XftDrawCreate), + (n: 'XftDrawSetClip'; d: @XftDrawSetClip), + (n: 'XftTextExtents16'; d: @XftTextExtents16), + (n: 'XftTextExtentsUtf16'; d: @XftTextExtentsUtf16), + (n: 'XftTextExtents32'; d: @XftTextExtents32), + (n: 'XftFontOpenName'; d: @XftFontOpenName), + (n: 'XftFontClose'; d: @XftFontClose), + (n: 'XftDrawString16'; d: @XftDrawString16), + (n: 'XftDrawStringUtf16'; d: @XftDrawStringUtf16), + (n: 'XftDefaultHasRender'; d: @XftDefaultHasRender), + (n: 'XftGetVersion'; d: @XftGetVersion), + (n: 'XftInit'; d: @XftInit), + (n: 'XftInitFtLibrary'; d: @XftInitFtLibrary), + (n: 'XftCharExists'; d: @XftCharExists), + (n: 'XftNameParse'; d: @XftNameParse), + (n: 'XftFontMatch'; d: @XftFontMatch), + (n: 'XftFontOpenPattern'; d: @XftFontOpenPattern), + (n: 'XftDefaultSubstitute'; d: @XftDefaultSubstitute), + (n: 'XftDrawPicture'; d: @XftDrawPicture), + (n: 'XftDrawSrcPicture'; d: @XftDrawSrcPicture) + ); +begin +{$ifndef staticxft} + result:= false; + initializefontconfig([]); + fhasfontconfig:= true; + if getprocaddresses(xftnames,funcs,true) = 0 then begin + exit; + end; +{$endif} //not staticxft + result:= true; +end; + +function getxrenderlib: boolean; +const + funcs: array[0..14] of funcinfoty = ( + (n: 'XRenderSetPictureClipRectangles'; + d: {$ifndef FPC}@{$endif}@XRenderSetPictureClipRectangles), + (n: 'XRenderCreatePicture'; d: {$ifndef FPC}@{$endif}@XRenderCreatePicture), + (n: 'XRenderFillRectangle'; d: {$ifndef FPC}@{$endif}@XRenderFillRectangle), + (n: 'XRenderSetPictureTransform'; + d: {$ifndef FPC}@{$endif}@XRenderSetPictureTransform), + (n: 'XRenderSetPictureFilter'; + d: {$ifndef FPC}@{$endif}@XRenderSetPictureFilter), + (n: 'XRenderFreePicture'; d: {$ifndef FPC}@{$endif}@XRenderFreePicture), + (n: 'XRenderComposite'; d: {$ifndef FPC}@{$endif}@XRenderComposite), + (n: 'XRenderQueryExtension'; + d: {$ifndef FPC}@{$endif}@XRenderQueryExtension), + (n: 'XRenderFindVisualFormat'; + d: {$ifndef FPC}@{$endif}@XRenderFindVisualFormat), + (n: 'XRenderFindStandardFormat'; + d: {$ifndef FPC}@{$endif}@XRenderFindStandardFormat), + (n: 'XRenderCompositeTriStrip'; + d: {$ifndef FPC}@{$endif}@XRenderCompositeTriStrip), + (n: 'XRenderCompositeTriFan'; + d: {$ifndef FPC}@{$endif}@XRenderCompositeTriFan), + (n: 'XRenderCompositeTriangles'; + d: {$ifndef FPC}@{$endif}@XRenderCompositeTriangles), + (n: 'XRenderChangePicture'; + d: {$ifndef FPC}@{$endif}@XRenderChangePicture), + (n: 'XRenderFindFormat'; + d: {$ifndef FPC}@{$endif}@XRenderFindFormat) + ); + + funcsopt: array[0..1] of funcinfoty = ( + (n: 'XRenderCreateSolidFill'; + d: {$ifndef FPC}@{$endif}@XRenderCreateSolidFill), + (n: 'XRenderSetPictureClipRegion'; + d: {$ifndef FPC}@{$endif}@XRenderSetPictureClipRegion) + ); + +var + handle: tlibhandle; +begin + handle:= getprocaddresses(xrendernames,funcs,true); + result:= handle <> 0; + if result then begin + getprocaddresses(handle,funcsopt,true); + if xrendercreatesolidfill <> nil then begin + createcolorpic:= @createcolorpic2; + end + else begin + createcolorpic:= @createcolorpic1; + end; + end; +end; + +const + gdifunctions: gdifunctionaty = ( + {$ifdef FPC}@{$endif}gdi_creategc, + {$ifdef FPC}@{$endif}gdi_destroygc, + {$ifdef FPC}@{$endif}gdi_changegc, + {$ifdef FPC}@{$endif}gdi_createpixmap, + {$ifdef FPC}@{$endif}gdi_pixmaptoimage, + {$ifdef FPC}@{$endif}gdi_imagetopixmap, + {$ifdef FPC}@{$endif}gdi_getcanvasclass, + {$ifdef FPC}@{$endif}gdi_endpaint, + {$ifdef FPC}@{$endif}gdi_flush, + {$ifdef FPC}@{$endif}gdi_movewindowrect, + {$ifdef FPC}@{$endif}gdi_drawlines, + {$ifdef FPC}@{$endif}gdi_drawlinesegments, + {$ifdef FPC}@{$endif}gdi_drawellipse, + {$ifdef FPC}@{$endif}gdi_drawarc, + {$ifdef FPC}@{$endif}gdi_fillrect, + {$ifdef FPC}@{$endif}gdi_fillellipse, + {$ifdef FPC}@{$endif}gdi_fillarc, + {$ifdef FPC}@{$endif}gdi_fillpolygon, + {$ifdef FPC}@{$endif}gdi_drawstring16, + {$ifdef FPC}@{$endif}gdi_setcliporigin, + {$ifdef FPC}@{$endif}gdi_createemptyregion, + {$ifdef FPC}@{$endif}gdi_createrectregion, + {$ifdef FPC}@{$endif}gdi_createrectsregion, + {$ifdef FPC}@{$endif}gdi_destroyregion, + {$ifdef FPC}@{$endif}gdi_copyregion, + {$ifdef FPC}@{$endif}gdi_moveregion, + {$ifdef FPC}@{$endif}gdi_regionisempty, + {$ifdef FPC}@{$endif}gdi_regionclipbox, + {$ifdef FPC}@{$endif}gdi_regsubrect, + {$ifdef FPC}@{$endif}gdi_regsubregion, + {$ifdef FPC}@{$endif}gdi_regaddrect, + {$ifdef FPC}@{$endif}gdi_regaddregion, + {$ifdef FPC}@{$endif}gdi_regintersectrect, + {$ifdef FPC}@{$endif}gdi_regintersectregion, + {$ifdef FPC}@{$endif}gdi_copyarea, + {$ifdef FPC}@{$endif}gdi_getimage, + {$ifdef FPC}@{$endif}gdi_fonthasglyph, + {$ifdef FPC}@{$endif}gdi_getfont, + {$ifdef FPC}@{$endif}gdi_getfonthighres, + {$ifdef FPC}@{$endif}gdi_freefontdata, + {$ifdef FPC}@{$endif}gdi_gettext16width, + {$ifdef FPC}@{$endif}gdi_getchar16widths, + {$ifdef FPC}@{$endif}gdi_getfontmetrics +); + +//var +// gdinumber: integer; + +function x11getgdifuncs: pgdifunctionaty; +begin + result:= @gdifunctions; +end; +{ +function x11getgdinum: integer; +begin + result:= gdinumber; +end; +} +initialization +// zerolineworkaround:= true; + fhasxft:= getxftlib; + hasxrender:= getxrenderlib; +// gdinumber:= registergdi(x11getgdifuncs); +finalization + if fhasfontconfig then begin + releasefontconfig; + end; +end. diff --git a/mseide-msegui/lib/common/i18n/msei18nglob.pas b/mseide-msegui/lib/common/i18n/msei18nglob.pas new file mode 100644 index 0000000..0e43fde --- /dev/null +++ b/mseide-msegui/lib/common/i18n/msei18nglob.pas @@ -0,0 +1,26 @@ +{ MSEgui Copyright (c) 2005-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msei18nglob; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +const + registerlangname = 'registerlang'; + unregisterlangname = 'unregisterlang'; +type + registermodulety = procedure(datapo: pointer; //pobjectdataty + const objectclassname: shortstring; + const name: shortstring); cdecl; + registerresourcety = procedure(datapo: pointer); cdecl; + //pobjectdataty + +// procedure registerlang(const registerlangmoduleproc: registerlangmodulety); + +implementation +end. diff --git a/mseide-msegui/lib/common/i18n/msei18nutils.pas b/mseide-msegui/lib/common/i18n/msei18nutils.pas new file mode 100644 index 0000000..e953e5e --- /dev/null +++ b/mseide-msegui/lib/common/i18n/msei18nutils.pas @@ -0,0 +1,359 @@ +{ MSEgui Copyright (c) 2005-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msei18nutils; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifndef FPC}{$ifdef linux} {$define UNIX} {$endif}{$endif} + +{$undef internalresstrhandling} +{$ifndef FPC} + {$define internalresstrhandling} +{$endif} + +{$if fpc_fullversion >= 30000} + {$define mse_fpc_3} +{$endif} + +(* +{$ifdef FPC} + {$if fpc_fullversion < 20301} + {$ifndef VER2_2}{$define internalresstrhandling}{$endif} + {$endif} +{$endif} +*) + +interface +uses + msetypes,msei18nglob,msefileutils; +//todo: optimize resourcestring loading +// wide resourcestrings + +function loadlangunit(aname: string; + const quiet: boolean = false): boolean; + //'' -> reset to builtin + //true if ok +procedure registermodule(datapo: pointer; //pobjectdataty + const objectclassname: shortstring; + const name: shortstring); cdecl; +procedure unregistermodule(datapo: pointer; //pobjectdataty + const objectclassname: shortstring; + const name: shortstring); cdecl; +procedure registerresourcestrings(datapo: pointer); cdecl; +{$ifdef internalresstrhandling} +procedure unregisterresourcestrings(datapo: pointer); cdecl; +{$endif} + +implementation +uses + {$ifdef FPC}dynlibs,{$ifdef UNIX}dl,{$endif}{$endif}sysutils,mseclasses, + mselist,msearrayutils,msestrings,mseapplication,msesysintf; + +type + resourcestringinfoty = record + name: string; + value: msestring; + end; + presourcestringinfoty = ^resourcestringinfoty; + + tresourcestringlist = class(torderedrecordlist) + protected + function getcomparefunc: sortcomparemethodty; override; + procedure finalizerecord(var item); override; + procedure copyrecord(var item); override; + function compare(const l,r): integer; + public + constructor create; + procedure readvalues(data: pobjectdataty); + function find(const aname: string; out po: presourcestringinfoty): boolean; + end; + +{$ifdef internalresstrhandling} +Type //copied from objpas.pp + + PResourceStringRecord = ^TResourceStringRecord; + TResourceStringRecord = Packed Record + DefaultValue, + CurrentValue : AnsiString; + HashValue : longint; + Name : AnsiString; + end; + + TResourceStringTable = Packed Record + Count : longint; + Resrec : Array[Word] of TResourceStringRecord; + end; + PResourceStringTable = ^TResourceStringTable; + + TResourceTableList = Packed Record + Count : longint; + Tables : Array[Word] of PResourceStringTable; + end; + + +Var + ResourceStringTable : TResourceTablelist; + {$ifdef FPC} External Name 'FPC_RESOURCESTRINGTABLES';{$endif} + //todo: fix for delphi +{$endif} + +var + langlibhandle: {$ifdef FPC}tlibhandle{$else}hmodule{$endif}; +type + registerlangty = procedure(const registermoduleproc: registermodulety; + const registerresourceproc: registerresourcety); + +procedure registermodule(datapo: pointer; const objectclassname: shortstring; + const name: shortstring); cdecl; +begin + registerobjectdata(pobjectdataty(datapo),objectclassname,name); +end; + +procedure unregistermodule(datapo: pointer; const objectclassname: shortstring; + const name: shortstring); cdecl; +begin + unregisterobjectdata(objectclassname,name); +end; + +{$ifndef internalresstrhandling} +Function setresstr(Name,Value: AnsiString; Hash: Longint; + arg: pointer) : AnsiString; +var + po1: presourcestringinfoty; +begin + if tresourcestringlist(arg).find(name,po1) then begin + {$ifdef mse_fpc_3} + result:= ''; + utf8string(pointer(result)):= stringtoutf8(po1^.value); + {$else} + result:= po1^.value; + {$endif} + end + else begin + result:= ''; + end; +end; + +Function unsetresstr(Name,Value: AnsiString; Hash: Longint; + arg: pointer) : AnsiString; +var + po1: presourcestringinfoty; +begin + if tresourcestringlist(arg).find(name,po1) then begin + result:= value; + end + else begin + result:= ''; + end; +end; +{$endif} + +procedure registerresourcestrings(datapo: pointer); cdecl; +{$ifdef FPC} +var + list1: tresourcestringlist; +{$ifdef internalresstrhandling} + int1,int2: integer; + po1: presourcestringinfoty; +{$endif} +{$endif} +begin +{$ifdef FPC} + list1:= tresourcestringlist.create; + try + list1.readvalues(pobjectdataty(datapo)); +{$ifndef internalresstrhandling} + setresourcestrings(@setresstr,list1); +{$else} + for int1:= 0 to resourcestringtable.count - 1 do begin + with resourcestringtable.tables[int1]^ do begin + for int2:= 0 to count - 1 do begin + with resrec[int2] do begin + if list1.find(name,po1) then begin + currentvalue:= po1^.value; + end; + end; + end; + end; + end; +{$endif} + finally + list1.free; + end; +{$endif} +end; + +procedure unregisterresourcestrings(datapo: pointer); cdecl; +var + list1: tresourcestringlist; +{$ifdef internalresstrhandling} + int1,int2: integer; + po1: presourcestringinfoty; +{$endif} +begin + list1:= tresourcestringlist.create; + try + list1.readvalues(pobjectdataty(datapo)); +{$ifndef internalresstrhandling} + setresourcestrings(@unsetresstr,list1); +{$else} + for int1:= 0 to resourcestringtable.count - 1 do begin + with resourcestringtable.tables[int1]^ do begin + for int2:= 0 to count - 1 do begin + with resrec[int2] do begin + if list1.find(name,po1) then begin + currentvalue:= defaultvalue; + end; + end; + end; + end; + end; +{$endif} + finally + list1.free; + end; +end; + +function loadlangunit(aname: string; const quiet: boolean = false): boolean; + //true if ok +var + reglang: registerlangty; +{$ifndef windows} + fdir,fname: filenamety; +{$endif} +begin + result:= false; + try + resetchangedmodules; + if langlibhandle <> 0 then begin + {$ifdef FPC}pointer({$endif}reglang{$ifdef FPC}){$endif}:= + getprocaddress(langlibhandle,unregisterlangname); + if {$ifndef FPC}@{$endif}reglang <> nil then begin + reglang(@unregistermodule,@unregisterresourcestrings); + end; + {$ifdef FPC}unloadlibrary{$else}freelibrary{$endif}(langlibhandle); + langlibhandle:= 0; + end; + if aname <> '' then begin + {$ifdef mswindows} + aname:= aname+'.dll'; + {$else} + splitfilepath(aname,fdir,fname); +// aname:= 'lib'+aname+'.so'; + aname:= fdir+'lib'+fname+'.so'; + {$endif} + langlibhandle:= loadlibrary( + {$ifndef FPC}pchar({$endif}aname{$ifndef FPC}){$endif}); + {$ifdef UNIX} + if (langlibhandle = 0) and (fdir = '') then begin + //try in application dir + langlibhandle:= loadlibrary({$ifndef FPC}pchar({$endif} + filedir(sys_getapplicationpath)+aname{$ifndef FPC}){$endif}); + end; + {$endif} + if langlibhandle <> 0 then begin + {$ifdef FPC}pointer({$endif}reglang{$ifdef FPC}){$endif}:= + getprocaddress(langlibhandle,registerlangname); + if {$ifndef FPC}@{$endif}reglang <> nil then begin + reglang(@registermodule,@registerresourcestrings); + end; + result:= true; + end + else begin + if not quiet then begin + {$ifdef FPC} + {$ifdef UNIX} + raise exception.create(dlerror); + {$else} + raise exception.create('Library not found.'); + {$endif} + {$else} + raise exception.create('Library not found.'); + {$endif} + end + else begin + exit; + end; + end; + end; + reloadchangedmodules; + except + on e: exception do begin + e.message:= 'Can not load langunit "'+aname+'":'+lineend+e.message; + application.handleexception(nil); + end; + end; +end; + +{ tresourcestringlist } + +constructor tresourcestringlist.create; +begin + inherited create(sizeof(resourcestringinfoty),[rels_needsfinalize,rels_needscopy]); +end; + +procedure tresourcestringlist.finalizerecord(var item); +begin + finalize(resourcestringinfoty(item)); +end; + +procedure tresourcestringlist.copyrecord(var item); +begin + with resourcestringinfoty(item) do begin + stringaddref(name); + stringaddref(value); + end; +end; + +function tresourcestringlist.getcomparefunc: sortcomparemethodty; +begin + result:= {$ifdef FPC}@{$endif}compare; +end; + +function tresourcestringlist.compare(const l,r): integer; +begin + result:= stringcomp(resourcestringinfoty(l).name,resourcestringinfoty(r).name); +end; + +procedure tresourcestringlist.readvalues(data: pobjectdataty); +var + po1: pchar; + info: resourcestringinfoty; + str1: string; +begin + clear; + if data^.size > 0 then begin + po1:= @data^.data; + repeat + info.name:= po1; + inc(po1,length(info.name)+1); + str1:= po1; + inc(po1,length(str1)+1); + info.value:= utf8tostringansi(str1); + add(info); + until po1 - pchar(@data^.data) >= data^.size; + end; +end; + +function tresourcestringlist.find(const aname: string; + out po: presourcestringinfoty): boolean; +var + info: resourcestringinfoty; + int1: integer; +begin + info.name:= aname; + result:= internalfind(info,int1); + if result then begin + po:= presourcestringinfoty(pchar(datapo) + int1 * sizeof(resourcestringinfoty)); + end + else begin + po:= nil; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/i18n/mselanglink.pas b/mseide-msegui/lib/common/i18n/mselanglink.pas new file mode 100644 index 0000000..114274e --- /dev/null +++ b/mseide-msegui/lib/common/i18n/mselanglink.pas @@ -0,0 +1,59 @@ +unit mselanglink; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msei18nglob; + +type + registermodulehookty = procedure( + const registermoduleproc: registermodulety); + registerresourcehookty = procedure( + const registerresourceproc: registerresourcety); +var + registermodulehook: registermodulehookty; + registerresourcehook: registerresourcehookty; + +procedure registerlang(const registermoduleproc: registermodulety; + const registerresourceproc: registerresourcety); +procedure unregisterlang(const unregistermoduleproc: registermodulety; + const unregisterresourceproc: registerresourcety); + +implementation + +var + lastmodulehook: registermodulehookty; + lastresourcehook: registerresourcehookty; + +procedure registerlang(const registermoduleproc: registermodulety; + const registerresourceproc: registerresourcety); +begin + if registermodulehook = nil then begin + registermodulehook:= lastmodulehook; + end; + lastmodulehook:= registermodulehook; + while registermodulehook <> nil do begin + registermodulehook(registermoduleproc); + end; + if registerresourcehook = nil then begin + registerresourcehook:= lastresourcehook; + end; + lastresourcehook:= registerresourcehook; + while registerresourcehook <> nil do begin + registerresourcehook(registerresourceproc); + end; +end; + +procedure unregisterlang(const unregistermoduleproc: registermodulety; + const unregisterresourceproc: registerresourcety); +begin + registermodulehook:= lastmodulehook; + while registermodulehook <> nil do begin + registermodulehook(unregistermoduleproc); + end; + registerresourcehook:= lastresourcehook; + while registerresourcehook <> nil do begin + registerresourcehook(unregisterresourceproc); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/i18n/msestringcontainer.pas b/mseide-msegui/lib/common/i18n/msestringcontainer.pas new file mode 100644 index 0000000..f2dfc15 --- /dev/null +++ b/mseide-msegui/lib/common/i18n/msestringcontainer.pas @@ -0,0 +1,184 @@ +{ MSEgui Copyright (c) 2012-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msestringcontainer; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,mseclasses,msedatalist,classes,mclasses,msehash,msestrings; + +type + tstringcontainer = class; + + getstringeventty = procedure(const sender: tobject; + const aindex: integer; var avalue: msestring) of object; + + tcustomstringcontainer = class(tmsecomponent) + private + fonreadstate: notifyeventty; + foneventloopstart: notifyeventty; + protected + procedure readstate(reader: treader); override; + procedure doasyncevent(var atag: integer); override; + published + property onreadstate: notifyeventty read fonreadstate write fonreadstate; + property oneventloopstart: notifyeventty read foneventloopstart + write foneventloopstart; + end; + + tstringcontainer = class(tcustomstringcontainer) + private + fstrings: tmsestringdatalist; + fongetstring: getstringeventty; + procedure setstrings(const avalue: tmsestringdatalist); + protected + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function i(const aindex: integer): msestring; //by index + property byindex[const aindex: integer]: msestring read i; default; + published + property strings: tmsestringdatalist read fstrings write setstrings; + property ongetstring: getstringeventty read fongetstring write fongetstring; + end; + + tkeystringdatalist = class(tdoublemsestringdatalist) + end; + + tkeystringcontainer = class(tcustomstringcontainer) + private + fstrings: tkeystringdatalist; + fhash: tintegermsestringhashdatalist; + fongetstring: getstringeventty; + procedure setstrings(const avalue: tkeystringdatalist); + protected + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function k(const akey: msestring): msestring; //by key + function i(const aindex: integer): msestring; //by index + property byindex[const aindex: integer]: msestring read i; default; + published + property strings: tkeystringdatalist read fstrings write setstrings; + //a = strings, b = keys + property ongetstring: getstringeventty read fongetstring write fongetstring; + end; + +implementation + +{ tcustomstringcontainer } + +procedure tcustomstringcontainer.readstate(reader: treader); +begin + inherited; + if assigned(fonreadstate) then begin + fonreadstate(self); + end; + if assigned(foneventloopstart) then begin + asyncevent; + end; +end; + +procedure tcustomstringcontainer.doasyncevent(var atag: integer); +begin + inherited; + if canevent(tmethod(foneventloopstart)) then begin + foneventloopstart(self); + end; +end; + +{ tstringcontainer } + +constructor tstringcontainer.create(aowner: tcomponent); +begin + fstrings:= tmsestringdatalist.create; + inherited; +end; + +destructor tstringcontainer.destroy; +begin + inherited; + fstrings.free; +end; + +function tstringcontainer.i(const aindex: integer): msestring; +begin + if (aindex < 0) or (aindex >= fstrings.count) then begin + result:= ''; + end + else begin + result:= pmsestringaty(fstrings.datapo)^[aindex]; + if assigned(fongetstring) then begin + fongetstring(self,aindex,result); + end; + end; +end; + +procedure tstringcontainer.setstrings(const avalue: tmsestringdatalist); +begin + fstrings.assign(avalue); +end; + +{ tkeystringcontainer } + +constructor tkeystringcontainer.create(aowner: tcomponent); +begin + fstrings:= tkeystringdatalist.create; + fhash:= tintegermsestringhashdatalist.create; + inherited; +end; + +destructor tkeystringcontainer.destroy; +begin + inherited; + fstrings.free; + fhash.free; +end; + +function tkeystringcontainer.k(const akey: msestring): msestring; +var + po1: pdoublemsestringaty; + int1: integer; +begin + with fstrings do begin + if not (dls_sortio in fstate) then begin + include(fstate,dls_sortio); + fhash.clear; + fhash.capacity:= count; + po1:= datapo; + for int1:= 0 to count-1 do begin + fhash.add(po1^[int1].b,int1); + end; + end; + end; + result:= i(fhash.find(akey)); + if result = '' then begin + result:= akey; + end; +end; + +function tkeystringcontainer.i(const aindex: integer): msestring; +begin + if (aindex < 0) or (aindex >= fstrings.count) then begin + result:= ''; + end + else begin + result:= pdoublemsestringaty(fstrings.datapo)^[aindex].a; + if assigned(fongetstring) then begin + fongetstring(self,aindex,result); + end; + end; +end; + +procedure tkeystringcontainer.setstrings(const avalue: tkeystringdatalist); +begin + fstrings.assign(avalue); +end; + +end. diff --git a/mseide-msegui/lib/common/i18n/mseucs2toru.pas b/mseide-msegui/lib/common/i18n/mseucs2toru.pas new file mode 100644 index 0000000..083d8d0 --- /dev/null +++ b/mseide-msegui/lib/common/i18n/mseucs2toru.pas @@ -0,0 +1,168 @@ +{ MSEgui Copyright (c) 2007 by IvankoB + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseucs2toru; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msestrings; + +function ucs2to866(const avalue: msechar): char; +function ucs2to866(const avalue: msestring): ansistring; + +function cp866toUCS2(const avalue: char): msechar; +function cp866toUCS2(const avalue: ansistring): msestring; + +implementation + +const + + cp866_2: array[$2550..$256C] of byte = ( + $cd,$ba,$d5,$d6,$c9,$b8,$b7,$bb,$d4,$d3,$c8,$be,$bd,$bc,$c6, + $c7,$cc,$b5,$b6,$b9,$d1,$d2,$cb,$cf,$d0,$ca,$d8,$d7,$ce + ); + + cpUCS2_1: array[$b5..$be] of longword = ( + $2561,$2562,$2556,$2555,$2563,$2551,$2557,$255D,$255C,$255B + ); + + cpUCS2_2: array[$c6..$d8] of longword = ( + $255E,$255F,$255A,$2554,$2569,$2566,$2560,$2550,$256C,$2567, + $2568,$2564,$2565,$2559,$2558,$2552,$2553,$256B,$256A + ); + + + +function ucs2to866(const avalue: msechar): char; +var + i: longword; +begin +i:= longword(avalue); +case i of + $0..$7f: result:= char(avalue); + $A0: result:= char($ff); + $A4: result:= char($fd); + $B0,$BA: result:= char($f8); + $B7: result:= char($fa); + $401: result:= char($f0); + $404: result:= char($f2); + $407: result:= char($f4); + $40E: result:= char($f6); + $410..$43f: result:= char(i-$390); + $440..$44f: result:= char(i-$360); + $451: result:= char($f1); + $454: result:= char($f3); + $457: result:= char($f5); + $45E: result:= char($f7); + $2116: result:= char($fc); + $2219: result:= char($f9); + $221A: result:= char($fb); + $2500: result:= char($c4); + $2502: result:= char($b3); + $250C: result:= char($da); + $2510: result:= char($bf); + $2514: result:= char($c0); + $2518: result:= char($d9); + $251C: result:= char($c3); + $2524: result:= char($b4); + $252C: result:= char($c2); + $2534: result:= char($c1); + $253C: result:= char($c5); + $2550..$256C: result:= char(cp866_2[i]); + $2580: result:= char($df); + $2584: result:= char($dc); + $2588: result:= char($db); + $258C: result:= char($dd); + $2590: result:= char($de); + $2591: result:= char($b0); + $2592: result:= char($b1); + $2593: result:= char($b2); + $25A0: result:= char($fe); +else + result:= char($20); +end; +end; + + +function ucs2to866(const avalue: msestring): ansistring; +var + i,i1: integer; +begin +i1:= length(avalue); +setlength(result,i1); +for i:= 1 to i1 do begin + result[i]:= ucs2to866(avalue[i]); +end; +end; + + +function cp866toUCS2(const avalue: char): msechar; +var + i: byte; +begin +i:= byte(avalue); +case i of + $0..$7f: result:= widechar(avalue); + $80..$af: result:= widechar(i + $390); + $b0: result:= widechar($2591); + $b1: result:= widechar($2592); + $b2: result:= widechar($2593); + $b3: result:= widechar($2502); + $b4: result:= widechar($2524); + $b5..$be: result:= widechar(cpUCS2_1[i]); + $bf: result:= widechar($2510); + $c0: result:= widechar($2514); + $c1: result:= widechar($2534); + $c2: result:= widechar($252C); + $c3: result:= widechar($251C); + $c4: result:= widechar($2500); + $c5: result:= widechar($253C); + $c6..$d8: result:= widechar(cpUCS2_2[i]); + $d9: result:= widechar($2518); + $da: result:= widechar($250C); + $db: result:= widechar($2588); + $dc: result:= widechar($2584); + $dd: result:= widechar($258C); + $de: result:= widechar($2590); + $df: result:= widechar($2580); + $e0..$ef: result:= widechar(i + $360); + $f0: result:= widechar($401); + $f1: result:= widechar($451); + $f2: result:= widechar($404); + $f3: result:= widechar($454); + $f4: result:= widechar($407); + $f5: result:= widechar($457); + $f6: result:= widechar($40E); + $f7: result:= widechar($45E); + $f8: result:= widechar($B0); + $f9: result:= widechar($2219); + $fa: result:= widechar($b7); + $fb: result:= widechar($221A); + $fc: result:= widechar($2116); + $fd: result:= widechar($a4); + $fe: result:= widechar($25A0); + $ff: result:= widechar($a0); + else + result:= widechar($20); +end; +end; + +function cp866toUCS2(const avalue: ansistring): msestring; +var + i,i1: integer; +begin +i1:= length(avalue); +setlength(result,i1); +for i:= 1 to i1 do begin + result[i]:= cp866toUCS2(avalue[i]); +end; +end; + +end. diff --git a/mseide-msegui/lib/common/ifi/mseifi.pas b/mseide-msegui/lib/common/ifi/mseifi.pas new file mode 100644 index 0000000..0b51c40 --- /dev/null +++ b/mseide-msegui/lib/common/ifi/mseifi.pas @@ -0,0 +1,2089 @@ +{ MSEgui Copyright (c) 2007-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseifi; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses,mseapplication,mseclasses,msearrayprops,mseact,msestrings, + msetypes,mseevent, + mseglob,msestream,msepipestream,{msegui,}mseifiglob,typinfo,msebintree, + msesystypes,msesockets,msecryptio,msethread,msedatalist,msesercomm; + +//todo: use icommclient instead of oninputavailable + +type + + sequencety = longword; + + ifireckindty = (ik_none,ik_data,ik_itemheader,ik_actionfired,ik_propertychanged, + ik_widgetcommand,ik_widgetproperties,ik_requestmodule, + ik_moduledata, + ik_requestfielddefs,ik_fielddefsdata,ik_fieldrec, + ik_griddata,ik_gridcommand,ik_coldatachange,ik_rowstatechange, + ik_selection, + ik_requestopen,ik_dsdata,ik_postresult,ik_modulecommand); + ifireckindsty = set of ifireckindty; +const + ifiitemkinds = [ik_actionfired,ik_propertychanged,ik_widgetcommand, + ik_widgetproperties,ik_requestmodule,ik_moduledata, + ik_modulecommand]; + ifiasynckinds = [ik_moduledata]; +// mainloopifikinds = [ik_moduledata]; + +type + ifinamety = array[0..0] of char; //null terminated + pifinamety = ^ifinamety; + + ifidatakindty = (idk_none,idk_null,idk_integer,idk_int64,idk_currency, + idk_real,idk_realint, + idk_msestring,idk_msestringint, + idk_bytes, + idk_rowstate,idk_rowstatecolmerge, + idk_rowstaterowheight, + idk_selection); + pifidatakindty = ^ifidatakindty; + + datarecty = record //dummy + end; + + ifirealintty = record + rea: double; + int: integer; + end; + pifirealintty = ^ifirealintty; + + ifimsestringintty = record + int: integer; + mstr: ifinamety; + end; + pifimsestringintty = ^ifimsestringintty; + + selectdataty = record + col: integer; + row: integer; + select: boolean; + end; + pselectdataty = ^selectdataty; + + ifibytesty = record + length: integer; + data: datarecty; + end; + pifibytesty = ^ifibytesty; + + ifidataheaderty = record + kind: ifidatakindty; + end; + ifidataty = record + header: ifidataheaderty; + data: datarecty; //variable length + end; + pifidataty = ^ifidataty; + + itemheaderty = record + tag: integer; + name: ifinamety; + end; + pitemheaderty = ^itemheaderty; + + modulecommanddataty = record + command: ificommandcodety; + end; + pmodulecommanddataty = ^modulecommanddataty; + modulecommandty = record + header: itemheaderty; + data: modulecommanddataty; + end; + pmodulecommandty = ^modulecommandty; + + actionfiredty = record + header: itemheaderty; + end; + + propertychangedty = record + header: itemheaderty; + propertyname: ifinamety; + data: ifidataty; + end; + ppropertychangedty = ^propertychangedty; + + ifiwidgetcommandty = (iwc_enable,iwc_disable,iwc_show,iwc_hide); + pifiwidgetcommandty = ^ifiwidgetcommandty; + widgetcommandty = record + header: itemheaderty; + command: ifiwidgetcommandty; + end; + + widgetpropertiesty = record + header: itemheaderty; + streamdata: ifibytesty; + end; + pwidgetpropertiesty = ^widgetpropertiesty; + + requestmodulety = record + header: itemheaderty; + moduleclassname: ifinamety; + end; + + moduledatadataty = record +// sequence: sequencety; + parentclass: ifinamety; + data: ifibytesty; + end; + pmoduledatadataty = ^moduledatadataty; + + moduledataty = record + header: itemheaderty; + data: moduledatadataty; + end; + + requestfielddefsty = record + header: itemheaderty; + end; + fielddefsdatadataty = record + data: datarecty; //dummy + end; + pfielddefsdatadataty = ^fielddefsdatadataty; + + fielddefsdataty = record + header: itemheaderty; + data: fielddefsdatadataty; + end; + + postresultcodety = (pc_none,pc_ok,pc_error); + + postresultdataty = record + code: postresultcodety; + message: ifinamety; + end; + ppostresultdataty = ^postresultdataty; + + postresultty = record + header: itemheaderty; + data: postresultdataty; + end; + + fielddataheaderty = record + index: integer; + end; + fielddataty = record + header: fielddataheaderty; + data: ifidataty; + end; + pfielddataty = ^fielddataty; + + requestopenty = record + header: itemheaderty; + end; + fieldreckindty = (frk_edit,frk_insert,frk_delete); + fieldrecheaderty = record + kind: fieldreckindty; + rowindex: integer; //null based + count: integer; + end; + fieldrecdataty = record + header: fieldrecheaderty; + data: datarecty; //dummy, array[count] of fielddataty + end; + pfieldrecdataty = ^fieldrecdataty; + + fieldrecty = record + header: itemheaderty; + data: fieldrecdataty; + end; + + rowstateheaderty = record + row: integer; + end; + prowstateheaderty = ^rowstateheaderty; + rowstatedataty = record + header: rowstateheaderty; + data: ifidataty; //idk_rowstate, idk_rowstatecolmerge, idk_rowstaterowheight + end; + prowstatedataty = ^rowstatedataty; + + selectiondataty = record + data: ifidataty; //idk_selection + end; + + colitemheaderty = record + row: integer; + name: ifinamety; + end; + colitemdataty = record + header: colitemheaderty; + data: ifidataty; + end; + pcolitemdataty = ^colitemdataty; + + coldataty = record + kind: listdatatypety; + name: ifinamety; + data: datarecty; //array[0..rows-1] of datatype + end; + pcoldataty = ^coldataty; + griddatadataty = record + cols: integer; + rows: integer; + data: datarecty; //array[0..cols-1] of coldataty + rowinfo: ifibytesty; //if folded + end; + pgriddatadataty = ^griddatadataty; + griddataty = record + header: itemheaderty; + data: griddatadataty; + end; + + gridcommandkindty = (gck_insertrow,gck_deleterow,gck_moverow,gck_rowenter); + gridcommanddatadataty = record + kind: gridcommandkindty; + dest: integer; + source: integer; + count: integer; + end; + pgridcommanddatadataty = ^gridcommanddatadataty; + gridcommanddataty = record + header: itemheaderty; + data: gridcommanddatadataty; + end; + + recdataheaderty = record + count: integer; //recordcount + end; + recdataty = record + header: recdataheaderty; + data: datarecty; //dummy, array[count] of + //array[fielddef count] of ifidataty + end; + precdataty = ^recdataty; + + dsdataty = record + header: itemheaderty; + fileddefs: fielddefsdatadataty; + recdata: recdataty; + end; + +type + ifirecstatety = (irs_async); + ifirecstatesty = set of ifirecstatety; + ifiheaderty = record + size: integer; //overall size + sequence: sequencety; + answersequence: sequencety; + kind: ifireckindty; + state: ifirecstatesty; + end; + pifiheaderty = ^ifiheaderty; + + ifirecty = record + header: ifiheaderty; + case ifireckindty of + ik_data:( + data: ifidataty; + ); + ik_itemheader:( + itemheader: itemheaderty; + ); + ik_actionfired:( + actionfired: actionfiredty; + ); + ik_propertychanged:( + propertychanged: propertychangedty; + ); + ik_widgetcommand: ( + widgetcommand: widgetcommandty; + ); + ik_requestmodule: ( + requestmodule: requestmodulety; + ); + ik_moduledata: ( + moduledata: moduledataty; + ); + ik_requestfielddefs: ( + requestfielddefs: requestfielddefsty; + ); + ik_fielddefsdata: ( + fielddefsdata: fielddefsdataty; + ); + ik_fieldrec: ( + fieldrec: fieldrecty; + ); + ik_griddata: ( + griddata: griddataty; + ); + ik_requestopen: ( + requestopends: requestopenty; + ); + ik_postresult: ( + postresult: postresultty; + ); + ik_modulecommand: ( + modulecommand: modulecommandty; + ); + end; + pifirecty = ^ifirecty; + + twaitingclient = class(tintegeravlnode) + private + fsem: semty; + public + constructor create(const asequence: sequencety); + destructor destroy; override; + procedure answered; + function wait(const awaitus: integer): boolean; + end; + + tiosynchronizer = class; + stringdataprocty = procedure(var adata: string) of object; + + tiosynchronizer = class(teventthread) + private + fwaitingclients: tintegeravltree; //todo: use hashlist + fondatareceived: stringdataprocty; + protected + procedure datareceived(const adata: string); + procedure eventloop; + function execute(thread: tmsethread): integer; override; + public + constructor create(const aondatareceived: stringdataprocty); + destructor destroy; override; + procedure answerreceived(const asequence: sequencety); + function preparewait(const asequence: sequencety): twaitingclient; + function waitforanswer(const aclient: twaitingclient; + const waitus: integer): boolean; //false on timeout + end; + + tcustomiochannel = class; + iochanneleventty = procedure(const sender: tcustomiochannel) of object; + optioniochty = (oic_releaseondisconnect); + optionsiochty = set of optioniochty; + iochannelstatety = (iocs_connecting,iocs_disconnecting, + iocs_localsetting); + iochannelstatesty = set of iochannelstatety; + + tcustomiochannel = class(tactcomponent) + private + frxdata: string; + factive: boolean; + fsequence: sequencety; + fonbeforeconnect: iochanneleventty; + fonafterconnect: iochanneleventty; + fonbeforedisconnect: iochanneleventty; + fonafterdisconnect: iochanneleventty; + foptionsio: optionsiochty; + flocalconn: tcustomiochannel; + procedure setlocalconn(const avalue: tcustomiochannel); + protected + fsynchronizer: tiosynchronizer; + fstate: iochannelstatesty; + procedure setactive(const avalue: boolean); override; + procedure checkinactive; + function canconnect: boolean; virtual; + procedure datareceived(var adata: ansistring); + procedure internalconnect; virtual; abstract; + procedure internaldisconnect; virtual; abstract; + function commio: boolean; virtual; + procedure localsenddata(const adata: ansistring); virtual; + procedure internalsenddata(const adata: ansistring); virtual; abstract; + procedure loaded; override; + procedure dobeforeconnect; + procedure doafterconnect; virtual; + procedure connect; + procedure disconnect; + procedure disconnected; + procedure doactivated; override; + procedure dodeactivated; override; + procedure receiveevent(const event: tobjectevent); override; + procedure receivelocaldata(const adata: string); virtual; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function checkconnection: boolean; + procedure senddata(const adata: ansistring); + function sequence: sequencety; + procedure asyncrx; //posts current rxdata to application queue + property synchronizer: tiosynchronizer read fsynchronizer; + property active: boolean read factive write setactive default false; + property rxdata: string read frxdata write frxdata; + property localconn: tcustomiochannel read flocalconn write setlocalconn; + published + property optionsio: optionsiochty read foptionsio write foptionsio default []; + property onbeforeconnect: iochanneleventty read fonbeforeconnect + write fonbeforeconnect; + property onafterconnect: iochanneleventty read fonafterconnect + write fonafterconnect; + property onbeforedisconnect: iochanneleventty read fonbeforedisconnect + write fonbeforedisconnect; + property onafterdisconnect: iochanneleventty read fonafterdisconnect + write fonafterdisconnect; + end; + + pipeiostatety = (pis_rxstarted); + pipeiostatesty = set of pipeiostatety; + + tstuffediochannel = class(tcustomiochannel) + private + fbuffer: string; + fpipestate: pipeiostatesty; + frxcheckedindex: integer; + protected + function stuff(const adata: string): string; + function unstuff(const adata: string): string; + procedure resetrxbuffer; + procedure addata(const adata: string); + procedure receivelocaldata(const adata: string); override; + end; + + tcustompipeiochannel = class(tstuffediochannel) + private + frx: tpipereader; + ftx: tpipewriter; + fserverapp: msestring; + fprochandle: integer; + protected + procedure internalconnect; override; + procedure internaldisconnect; override; + function commio: boolean; override; + procedure localsenddata(const adata: ansistring); override; + procedure internalsenddata(const adata: ansistring); override; + procedure doinputavailable(const sender: tpipereader); + procedure dopipebroken(const sender: tpipereader); + procedure doasyncevent(var atag: integer); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property active; + end; + + tpipeiochannel = class(tcustompipeiochannel) + published + property active; + property activator; + property serverapp: msestring read fserverapp write fserverapp; + //stdin, stdout if '' + property localconn; + end; + + tsocketstdiochannel = class(tcustompipeiochannel) + private + fcryptoio: tcryptoio; + fcryptoioinfo: cryptoioinfoty; + procedure setcryptoio(const avalue: tcryptoio); + protected + procedure internalconnect; override; + procedure internaldisconnect; override; + public + constructor create(aowner: tcomponent); override; + published + property active; + property activator; + property cryptoio: tcryptoio read fcryptoio write setcryptoio; + property cryptoiokindt: cryptoiokindty read fcryptoioinfo.kind + write fcryptoioinfo.kind; + end; + + tifisocketclient = class(tcustomsocketclient) + published + property pipes; + property cryptoio; + + property kind; + property url; + property port; + end; + + tsocketclientiochannel = class(tstuffediochannel) + private + fsocket: tifisocketclient; + procedure setsocket(const avalue: tifisocketclient); + protected + procedure internalconnect; override; + procedure internaldisconnect; override; + function commio: boolean; override; + procedure localsenddata(const adata: ansistring); override; + procedure internalsenddata(const adata: ansistring); override; + procedure doinputavailable(const sender: tpipereader); + procedure dobeforedisconnect(const sender: tcustomcommpipes); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property active; + property activator; + property socket: tifisocketclient read fsocket write setsocket; + property localconn; + end; + + tcustomsocketserveriochannel = class(tstuffediochannel) + private + fpipes: tcustomsocketpipes; + funlinking: integer; + protected + procedure internalconnect; override; + procedure internaldisconnect; override; + function commio: boolean; override; + procedure localsenddata(const adata: ansistring); override; + procedure internalsenddata(const adata: ansistring); override; + procedure doinputavailable(const sender: tpipereader); + procedure dobeforedisconnect(const sender: tcustomcommpipes); + procedure unlink; reintroduce; + function canconnect: boolean; override; + public + destructor destroy; override; + procedure link(const apipes: tcustomcommpipes); + end; + + tsocketserveriochannel = class(tcustomsocketserveriochannel) + public + published + property localconn; + end; + + tifiiolinkcomponent = class(tmsecomponent) + private + procedure setchannel(const avalue: tcustomiochannel); + protected + fchannel: tcustomiochannel; + published + property channel: tcustomiochannel read fchannel write setchannel; + end; + +procedure initifirec(out arec: string; const akind: ifireckindty; + const asequence: sequencety; const datalength: integer; out datapo: pchar); +procedure inititemheader(const atag: integer; const aname: string; + out arec: string; const akind: ifireckindty; + const asequence: sequencety; const datasize: integer; out datapo: pchar); +function ifinametostring(const source: pifinamety; out dest: string): integer; +function stringtoifiname(const source: string; const dest: pifinamety): integer; + +function encodeifinull(const headersize: integer = 0): string; +function encodeifidata(const avalue: boolean; + const headersize: integer = 0): string; overload; +function encodeifidata(const avalue: integer; + const headersize: integer = 0): string; overload; +function encodeifidata(const avalue: int64; + const headersize: integer = 0): string; overload; +function encodeifidata(const avalue: currency; + const headersize: integer = 0): string; overload; +function encodeifidata(const avalue: real; + const headersize: integer = 0): string; overload; +{$ifndef FPC} +function encodeifidatareal(const avalue: real; + const headersize: integer = 0): string; overload; +{$endif} +function encodeifidata(const avalue: realintty; + const headersize: integer = 0): string; overload; +function encodeifidata(const avalue: msestring; + const headersize: integer = 0): string; overload; +function encodeifidata(const avalue: msestringintty; + const headersize: integer = 0): string; overload; +function encodeifidata(const avalue: ansistring; + const headersize: integer = 0): string; overload; +function encodeifidata(const alist: tdatalist; const aindex: integer; + const headersize: integer = 0): string; overload; +function encodeifidata(const avalue: rowstatety; + const headersize: integer = 0): string; overload; +function encodeifidata(const avalue: rowstatecolmergety; + const headersize: integer = 0): string; overload; +function encodeifidata(const avalue: rowstaterowheightty; + const headersize: integer = 0): string; overload; +function encodeifidata(const avalue: selectdataty; + const headersize: integer = 0): string; overload; + +function skipifidata(const source: pifidataty): integer; +function decodeifidata(const source: pifidataty; out dest: msestring): integer; + overload; +function decodeifidata(const source: pifidataty; out dest: string): integer; + overload; +function decodeifidata(const source: pifidataty; out dest: integer): integer; + overload; +function decodeifidata(const source: pifidataty; out dest: int64): integer; + overload; +function decodeifidata(const source: pifidataty; out dest: real): integer; + overload; +{$ifndef FPC} +function decodeifidatareal(const source: pifidataty; out dest: double): integer; + overload; +{$endif} +function decodeifidata(const source: pifidataty; out dest: realintty): integer; + overload; +function decodeifidata(const source: pifidataty; out dest: currency): integer; + overload; +function decodeifidata(const source: pifidataty; + out dest: msestringintty): integer; overload; +function decodeifidata(const source: pifidataty; out dest: variant): integer; + overload; +function decodeifidata(const source: pifidataty; const aindex: integer; + const alist: tdatalist): integer; overload; + //alist can be nil +function decodeifidata(const source: pifidataty; const aindex: integer; + const alist: subdatainfoty): integer; overload; +function decodeifidata(const source: pifidataty; out dest: rowstatety): integer; + overload; +function decodeifidata(const source: pifidataty; out dest: rowstatecolmergety): integer; + overload; +function decodeifidata(const source: pifidataty; out dest: rowstaterowheightty): integer; + overload; +function decodeifidata(const source: pifidataty; out dest: selectdataty): integer; + overload; + +procedure addifiintegervalue(var adata: ansistring; var adatapo: pchar; + const avalue: integer); +function readifivariant(const adata: pifirecty; var adatapo: pchar): variant; +function setifibytes(const source: pointer; const size: integer; + const dest: pifibytesty): integer; overload; + +const + datarecsizes: array[ifidatakindty] of integer = ( + sizeof(ifidataty), //idk_none + sizeof(ifidataty), //idk_null + sizeof(ifidataty)+sizeof(integer), //idk_integer + sizeof(ifidataty)+sizeof(int64), //idk_int64 + sizeof(ifidataty)+sizeof(currency), //idk_currency + sizeof(ifidataty)+sizeof(double), //idk_real + sizeof(ifidataty)+sizeof(ifirealintty), //idk_realint + sizeof(ifidataty)+sizeof(ifinamety), //idk_msestring + sizeof(ifidataty)+sizeof(ifimsestringintty), //idk_msestringint + sizeof(ifidataty)+sizeof(ifibytesty), //idk_bytes + sizeof(ifidataty)+sizeof(rowstatety), //idk_rowstate + sizeof(ifidataty)+sizeof(rowstatecolmergety), //idk_rowstatecolmerge + sizeof(ifidataty)+sizeof(rowstaterowheightty), //idk_rowstaterowheight + sizeof(ifidataty)+sizeof(selectdataty) //idk_selection + ); +implementation +uses + sysutils,mseprocutils,msesysintf1,msesysintf,{mseforms,}msetmpmodules, + msesysutils,variants,msesumlist {$ifndef FPC},classes_del{$endif}; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tsocketreader1 = class(tsocketreader); + tsocketwriter1 = class(tsocketwriter); + +const + headersizes: array[ifireckindty] of integer = ( + sizeof(ifiheaderty), //ik_none + sizeof(ifiheaderty), //ik_data + sizeof(ifiheaderty)+sizeof(itemheaderty), //ik_itemheader + sizeof(ifiheaderty)+sizeof(actionfiredty), //ik_actionfired + sizeof(ifiheaderty)+sizeof(propertychangedty), //ik_propertychanged + sizeof(ifiheaderty)+sizeof(widgetcommandty), //ik_widgetcommand + sizeof(ifiheaderty)+sizeof(widgetpropertiesty), //ik_widgetproperties + sizeof(ifiheaderty)+sizeof(requestmodulety), //ik_requestmodule + sizeof(ifiheaderty)+sizeof(moduledataty), //ik_moduledata + sizeof(ifiheaderty)+sizeof(requestfielddefsty), //ik_requestfielddefs + sizeof(ifiheaderty)+sizeof(fielddefsdataty), //ik_fielddefsdata + sizeof(ifiheaderty)+sizeof(fieldrecty), //ik_fieldrec + sizeof(ifiheaderty)+sizeof(griddataty), //ik_griddata + sizeof(ifiheaderty)+sizeof(gridcommanddataty), //ik_gridcommand + sizeof(ifiheaderty)+sizeof(colitemdataty), //ik_coldatachange + sizeof(ifiheaderty)+sizeof(rowstatedataty), //ik_rowstatechange + sizeof(ifiheaderty)+sizeof(selectiondataty), //ik_selection + sizeof(ifiheaderty)+sizeof(requestopenty), //ik_requestopen + sizeof(ifiheaderty)+sizeof(dsdataty), //ik_dsdata + sizeof(ifiheaderty)+sizeof(postresultty), //ik_postresult + sizeof(ifiheaderty)+sizeof(modulecommandty) //ik_modulecommand + ); + + stuffchar = c_dle; + stx = c_dle + c_stx; + etx = c_dle + c_etx; + +function setifibytes(const source: pointer; const size: integer; + const dest: pifibytesty): integer; overload; +begin + result:= sizeof(ifibytesty) + size; + dest^.length:= size; + move(source^,dest^.data,size); +end; + +function setifibytes(const source: string; + const dest: pifibytesty): integer; overload; +var + int1: integer; +begin + int1:= length(source); + result:= sizeof(ifibytesty) + int1; + dest^.length:= int1; + move(pointer(source)^,dest^.data,int1); +end; + +function initdataheader(const headersize: integer; const kind: ifidatakindty; + const datasize: integer; out data: string): pchar; +begin + setlength(data,headersize+datarecsizes[kind]+datasize); + result:= pointer(data); + fillchar(result^,headersize,0); + inc(result,headersize); + pifidataty(result)^.header.kind:= kind; + inc(result,sizeof(ifidataheaderty)); +end; + +function encodeifinull(const headersize: integer = 0): string; +begin + initdataheader(headersize,idk_null,0,result) +end; + +function encodeifidata(const avalue: boolean; + const headersize: integer = 0): string; overload; +var + int1: integer; +begin + int1:= 0; + if avalue then begin + int1:= integer(longbool(true)); + end; + pinteger(initdataheader(headersize,idk_integer,0,result))^:= int1; +end; + +function encodeifidata(const avalue: integer; + const headersize: integer = 0): string; overload; +begin + pinteger(initdataheader(headersize,idk_integer,0,result))^:= avalue; +// result:= encodeifidata(int64(avalue),headersize); +end; + +function encodeifidata(const avalue: int64; + const headersize: integer = 0): string; overload; +begin + pint64(initdataheader(headersize,idk_int64,0,result))^:= avalue; +end; + +function encodeifidata(const avalue: currency; + const headersize: integer = 0): string; overload; +begin + pcurrency(initdataheader(headersize,idk_currency,0,result))^:= avalue; +end; + +function encodeifidata(const avalue: real; + const headersize: integer = 0): string; overload; +begin + preal(initdataheader(headersize,idk_real,0,result))^:= avalue; +end; + +{$ifndef FPC} +function encodeifidatareal(const avalue: real; + const headersize: integer = 0): string; overload; +begin + preal(initdataheader(headersize,idk_real,0,result))^:= avalue; +end; +{$endif} + +function encodeifidata(const avalue: realintty; + const headersize: integer = 0): string; overload; +begin + with pifirealintty(initdataheader(headersize,idk_realint,0,result))^ do begin + rea:= avalue.rea; + int:= avalue.int; + end; +end; + +function encodeifidata(const avalue: msestring; + const headersize: integer = 0): string; overload; +var + str1: string; +begin + str1:= stringtoutf8ansi(avalue); + stringtoifiname(str1,pifinamety( + initdataheader(headersize,idk_msestring,length(str1),result))); +end; + +function encodeifidata(const avalue: msestringintty; + const headersize: integer = 0): string; overload; +var + str1: string; + po1: pifimsestringintty; +begin + str1:= stringtoutf8ansi(avalue.mstr); + po1:= pifimsestringintty(initdataheader( + headersize,idk_msestringint,length(str1),result)); + po1^.int:= avalue.int; + stringtoifiname(str1,@po1^.mstr); +end; + +function encodeifidata(const avalue: ansistring; + const headersize: integer = 0): string; overload; +begin + setifibytes(avalue,pifibytesty( + initdataheader(headersize,idk_bytes,length(avalue),result))); +end; + +function encodeifidata(const alist: tdatalist; const aindex: integer; + const headersize: integer = 0): string; +begin + case alist.datatype of + dl_integer: begin + result:= encodeifidata(tintegerdatalist(alist).items[aindex],headersize); + end; + dl_msestring: begin + result:= encodeifidata(tmsestringdatalist(alist).items[aindex],headersize); + end; + dl_real: begin + {$ifdef FPC} + result:= encodeifidata(trealdatalist(alist).items[aindex],headersize); + {$else} + result:= encodeifidatareal(trealdatalist(alist).items[aindex],headersize); + {$endif} + end; + dl_msestringint: begin + result:= encodeifidata(tmsestringintdatalist(alist).doubleitems[aindex],headersize); + end; + dl_realint,dl_realsum: begin + result:= encodeifidata(trealintdatalist(alist).doubleitems[aindex],headersize); + end; + else begin + raise exception.create('Wrong datakind.'); + //result:= ''; + end; + end; +end; + +function encodeifidata(const avalue: rowstatety; + const headersize: integer = 0): string; overload; +begin + prowstatety(initdataheader(headersize, + idk_rowstate,0,result))^:= avalue; +end; + +function encodeifidata(const avalue: rowstatecolmergety; + const headersize: integer = 0): string; overload; +begin + prowstatecolmergety(initdataheader(headersize, + idk_rowstatecolmerge,0,result))^:= avalue; +end; + +function encodeifidata(const avalue: rowstaterowheightty; + const headersize: integer = 0): string; overload; +begin + prowstaterowheightty(initdataheader(headersize, + idk_rowstatecolmerge,0,result))^:= avalue; +end; + +function encodeifidata(const avalue: selectdataty; + const headersize: integer = 0): string; overload; +begin + pselectdataty(initdataheader(headersize,idk_selection,0,result))^:= avalue; +end; + +procedure addifiintegervalue(var adata: ansistring; var adatapo: pchar; + const avalue: integer); +begin + setlength(adata,adatapo-pointer(adata)); + adata:= adata + encodeifidata(avalue); + pifirecty(adata)^.header.size:= length(adata); + adatapo:= pchar(pointer(adata)) + length(adata); +end; + +function readifivariant(const adata: pifirecty; var adatapo: pchar): variant; +type + variantarty = array of variant; +var + ar1: variantarty; + po1: pchar; +// int1: integer; +begin + ar1:= nil; //compiler warning + po1:= pchar(adata)+adata^.header.size; + while adatapo < po1 do begin + setlength(ar1,high(ar1)+2); + inc(adatapo,decodeifidata(pifidataty(adatapo),ar1[high(ar1)])); + end; + case high(ar1) of + -1: begin + result:= null; + end; + 0: begin + result:= ar1[0]; + end; + else begin + dynarraytovariant(result,pointer(ar1),typeinfo(variantarty)); + end; + end; +end; + +procedure datakinderror; +begin + raise exception.create('Wrong datakind.'); +end; + +function skipifidata(const source: pifidataty): integer; +var + str1: string; +begin + case source^.header.kind of + idk_msestring: begin + ifinametostring(pifinamety(@source^.data),str1); + result:= length(str1); + end; + idk_bytes: begin + result:= pifibytesty(@source^.data)^.length; + end; + else begin + result:= 0; + end; + end; + result:= result + datarecsizes[source^.header.kind]; +end; + +function decodeifidata(const source: pifidataty; out dest: msestring): integer; +var + str1: string; +begin + if source^.header.kind <> idk_msestring then begin + datakinderror; + end; + ifinametostring(pifinamety(@source^.data),str1); + dest:= utf8tostringansi(str1); + result:= datarecsizes[idk_msestring] + length(str1); +end; + +function decodeifidata(const source: pifidataty; out dest: string): integer; +begin + if source^.header.kind <> idk_bytes then begin + datakinderror; + end; + with pifibytesty(@source^.data)^ do begin + setlength(dest,length); + if length > 0 then begin + move(data,pointer(dest)^,length); + end; + result:= datarecsizes[idk_bytes] + length; + end; +end; + +function decodeifidata(const source: pifidataty; out dest: integer): integer; +begin + if source^.header.kind <> idk_integer then begin + datakinderror; + end; + dest:= pinteger(@source^.data)^; + result:= datarecsizes[idk_integer]; +end; + +function decodeifidata(const source: pifidataty; out dest: int64): integer; +begin + if source^.header.kind <> idk_int64 then begin + datakinderror; + end; + dest:= pint64(@source^.data)^; + result:= datarecsizes[idk_int64]; +end; + +function decodeifidata(const source: pifidataty; out dest: real): integer; +begin + if source^.header.kind <> idk_real then begin + datakinderror; + end; + dest:= preal(@source^.data)^; + result:= datarecsizes[idk_real]; +end; + +{$ifndef FPC} +function decodeifidatareal(const source: pifidataty; out dest: double): integer; +begin + if source^.header.kind <> idk_real then begin + datakinderror; + end; + dest:= preal(@source^.data)^; + result:= datarecsizes[idk_real]; +end; +{$endif} + +function decodeifidata(const source: pifidataty; out dest: realintty): integer; +begin + if source^.header.kind <> idk_realint then begin + datakinderror; + end; + with pifirealintty(@source^.data)^ do begin + dest.rea:= rea; + dest.int:= int; + end; + result:= datarecsizes[idk_realint]; +end; + +function decodeifidata(const source: pifidataty; out dest: currency): integer; +begin + if source^.header.kind <> idk_currency then begin + datakinderror; + end; + dest:= pcurrency(@source^.data)^; + result:= datarecsizes[idk_currency]; +end; + +function decodeifidata(const source: pifidataty; + out dest: msestringintty): integer; overload; +var + str1: string; + po1: pifimsestringintty; +begin + if source^.header.kind <> idk_msestringint then begin + datakinderror; + end; + po1:= @source^.data; + dest.int:= po1^.int; + ifinametostring(pifinamety(@po1^.mstr),str1); + dest.mstr:= utf8tostringansi(str1); + result:= datarecsizes[idk_msestringint] + length(str1); +end; + +function decodeifidata(const source: pifidataty; out dest: variant): integer; +var + integer1: integer; + int641: int64; + currency1: currency; + real1: real; + msestring1: msestring; + ansistring1: ansistring; +begin + case source^.header.kind of + idk_null: begin + dest:= null; + result:= sizeof(ifidataty); + end; + idk_integer: begin + result:= decodeifidata(source,integer1); + dest:= integer1; + end; + idk_int64: begin + result:= decodeifidata(source,int641); + dest:= int641; + end; + idk_currency: begin + result:= decodeifidata(source,currency1); + dest:= currency1; + end; + idk_real: begin + result:= decodeifidata(source,real1); + dest:= real1; + end; + idk_msestring: begin + result:= decodeifidata(source,msestring1); + dest:= msestring1; + end; + idk_bytes: begin + result:= decodeifidata(source,ansistring1); + dest:= ansistring1; + end; + else begin + raise exception.create('Invalid IfI data'); + end; + end; +end; + +function decodeifidata(const source: pifidataty; const aindex: integer; + const alist: tdatalist): integer; overload; + //alist can be nil +var + ainfo: subdatainfoty; +begin + ainfo.list:= alist; + ainfo.subindex:= 0; + result:= decodeifidata(source,aindex,ainfo); +end; + +function decodeifidata(const source: pifidataty; const aindex: integer; + const alist: subdatainfoty): integer; overload; + //alist can be nil +var + int1: integer; + lint1: int64; + rea1: real; + mstr1: msestring; + strint1: msestringintty; + realint1: realintty; +begin + with alist do begin + result:= 0; + if (list <> nil) and (aindex < list.count) then begin + if alist.subindex = 0 then begin + case source^.header.kind of + idk_null: begin + list.cleardata(aindex); + end; + idk_integer: begin + if list.datatype = dl_integer then begin + result:= decodeifidata(source,int1); + tintegerdatalist(list)[aindex]:= int1; + end; + end; + idk_int64: begin + if list.datatype = dl_int64 then begin + result:= decodeifidata(source,lint1); + tint64datalist(list)[aindex]:= lint1; + end; + end; + idk_msestring: begin + if list.datatype = dl_msestring then begin + result:= decodeifidata(source,mstr1); + tmsestringdatalist(list)[aindex]:= mstr1; + end; + end; + idk_real: begin + if list.datatype in [dl_real,dl_realsum] then begin + result:= decodeifidata(source,rea1); + trealdatalist(list)[aindex]:= rea1; + end; + end; + idk_msestringint: begin + if list.datatype = dl_msestringint then begin + result:= decodeifidata(source,strint1); + tmsestringintdatalist(list)[aindex]:= strint1; + end; + end; + idk_realint: begin + if list is trealintdatalist then begin + result:= decodeifidata(source,realint1); + trealintdatalist(list).doubleitems[aindex]:= realint1; + end; + end; + end; + end + else begin + case source^.header.kind of + idk_null: begin + list.clearmemberitem(subindex,aindex); + end; + idk_integer: begin + result:= decodeifidata(source,int1); + list.setmemberitem(subindex,aindex,int1); + end; + end; + end; + end; + if result = 0 then begin + result:= skipifidata(source); + end; + end; +end; + +function decodeifidata(const source: pifidataty; out dest: rowstatety): integer; +begin + if not (source^.header.kind in + [idk_rowstate,idk_rowstatecolmerge,idk_rowstaterowheight]) then begin + datakinderror; + end; + dest:= prowstatety(@source^.data)^; + result:= datarecsizes[source^.header.kind]; +end; + +function decodeifidata(const source: pifidataty; + out dest: rowstatecolmergety): integer; +begin + case source^.header.kind of + idk_rowstate: begin + fillchar(dest.colmerge,sizeof(dest.colmerge),0); + prowstatety(@dest)^:= prowstatety(@source^.data)^; + end; + idk_rowstatecolmerge,idk_rowstaterowheight: begin + dest:= prowstatecolmergety(@source^.data)^; + end; + else begin + datakinderror; + end; + end; + result:= datarecsizes[source^.header.kind]; +end; + +function decodeifidata(const source: pifidataty; + out dest: rowstaterowheightty): integer; +begin + case source^.header.kind of + idk_rowstate: begin + fillchar(dest.colmerge,sizeof(dest.colmerge)+sizeof(dest.rowheight),0); + prowstatety(@dest)^:= prowstatety(@source^.data)^; + end; + idk_rowstatecolmerge: begin + fillchar(dest.rowheight,sizeof(dest.rowheight),0); + prowstatecolmergety(@dest)^:= prowstatecolmergety(@source^.data)^; + end; + idk_rowstaterowheight: begin + dest:= prowstaterowheightty(@source^.data)^; + end; + else begin + datakinderror; + end; + end; + result:= datarecsizes[source^.header.kind]; +end; + +function decodeifidata(const source: pifidataty; out dest: selectdataty): integer; +begin + if source^.header.kind <> idk_selection then begin + datakinderror; + end; + dest:= pselectdataty(@source^.data)^; + result:= datarecsizes[idk_selection]; +end; + +{ +function decodecolitemdata(const source: pcolitemdataty; + const alist: tdatalist): integer; +begin + result:= sizeof(colitemheaderty) + + decodeifidata(@source^.data,alist,source^.header.row); +end; +} +procedure initifirec(out arec: string; const akind: ifireckindty; + const asequence: sequencety; const datalength: integer; + out datapo: pchar); +var + int1: integer; +begin + int1:= headersizes[akind] + datalength; + arec:= nullstring(int1); +// setlength(arec,int1); +// fillchar(arec[1],int1,0); + with pifiheaderty(arec)^ do begin + size:= int1; + answersequence:= asequence; +// sequence:= fsequence; + kind:= akind; + end; + datapo:= pchar(pointer(arec)) + sizeof(ifiheaderty); +end; + +function stringtoifiname(const source: string; const dest: pifinamety): integer; +var + int1: integer; +begin + int1:= length(source); + if int1 > 0 then begin + move(source[1],dest^,int1); + end; + pchar(dest)[int1]:= #0; + result:= int1 + 1; +end; + +function ifinametostring(const source: pifinamety; + out dest: string): integer; +begin + dest:= pchar(source); + result:= length(dest) + 1; +end; +{ +procedure ifidatasynchronize(const sender: tiosynchronizer; var adata: string); +begin + if length(adata) >= sizeof(ifiheaderty) then begin + with pifiheaderty(adata)^ do begin + if answersequence <> 0 then begin + sender.answerreceived(answersequence); + end; + end; + end; +end; +} +procedure inititemheader(const atag: integer; const aname: string; + out arec: string; const akind: ifireckindty; const asequence: sequencety; + const datasize: integer; out datapo: pchar); +var + po1: pchar; +begin + initifirec(arec,akind,asequence,datasize+length(aname),po1); + with pitemheaderty(po1)^ do begin + tag:= atag; + po1:= @name; + end; + inc(po1,stringtoifiname(aname,pifinamety(po1))); + datapo:= po1; +end; + +{ tcustomiochannel } + +constructor tcustomiochannel.create(aowner: tcomponent); +begin + fsynchronizer:= tiosynchronizer.create({$ifdef FPC}@{$endif}datareceived); + inherited; +end; + +destructor tcustomiochannel.destroy; +begin + fsynchronizer.free; + active:= false; + localconn:= nil; + inherited; +end; + +function tcustomiochannel.checkconnection: boolean; +begin + result:= commio; + if not result and not (csloading in componentstate) then begin + internaldisconnect(); + factive:= false; + if canconnect then begin + connect; + result:= commio; + end; + end; +end; + +function tcustomiochannel.sequence: sequencety; +begin + inc(fsequence); + if fsequence = 0 then begin + inc(fsequence); + end; + result:= fsequence; +end; + +procedure tcustomiochannel.localsenddata(const adata: ansistring); +begin + flocalconn.receivelocaldata(adata); +end; + +procedure tcustomiochannel.senddata(const adata: ansistring); +begin + if checkconnection then begin + if flocalconn <> nil then begin + localsenddata(adata); + end + else begin + internalsenddata(adata); + end; + end; +end; + +procedure tcustomiochannel.datareceived(var adata: ansistring); +var + str1: string; +begin + str1:= frxdata; + frxdata:= adata; + try + sendchangeevent(oe_dataready); //todo: don't broadcast, use hashed list + finally + frxdata:= str1; + end; +end; + +procedure tcustomiochannel.receiveevent(const event: tobjectevent); +begin + if (event.kind = ek_objectdata) and (event is tstringobjectevent) then begin + datareceived(tstringobjectevent(event).data); + end + else begin + inherited; + end; +end; + +procedure tcustomiochannel.receivelocaldata(const adata: string); +begin + //dummy +end; + +procedure tcustomiochannel.asyncrx; //posts current rxdata to application queue +var + str1: ansistring; +begin + str1:= frxdata; + frxdata:= ''; + application.postevent(tstringobjectevent.create(str1,ievent(self))); +end; + +procedure tcustomiochannel.setactive(const avalue: boolean); +begin + if factive <> avalue then begin + if componentstate * [csloading,csdesigning] = [] then begin + if avalue then begin + connect; + end + else begin + disconnect; + end; + end; + factive:= avalue; + end; +end; + +procedure tcustomiochannel.loaded; +begin + inherited; + if factive and not (csdesigning in componentstate) then begin + connect; + end; +end; + +procedure tcustomiochannel.dobeforeconnect; +begin + if canevent(tmethod(fonbeforeconnect)) then begin + fonbeforeconnect(self); + end; +end; + +procedure tcustomiochannel.doafterconnect; +begin + if canevent(tmethod(fonafterconnect)) then begin + fonafterconnect(self); + end; +end; + +procedure tcustomiochannel.connect; +begin + if not (iocs_connecting in fstate) then begin +{$ifdef mse_debugsockets} + debugout(self,'connect'); +{$endif} + include(fstate,iocs_connecting); + try + dobeforeconnect; + if flocalconn <> nil then begin + flocalconn.connect; + doactivated; + end + else begin + internalconnect; + end; + doafterconnect; + {$ifdef mse_debugsockets} + debugout(self,'connected'); + {$endif} + finally + exclude(fstate,iocs_connecting); + end; + end; +end; + +procedure tcustomiochannel.disconnected; +begin +{$ifdef mse_debugsockets} + debugout(self,'disconnected'); +{$endif} + if canevent(tmethod(fonafterdisconnect)) then begin + fonafterdisconnect(self); + end; + if (oic_releaseondisconnect in foptionsio) and + not (csdesigning in componentstate) and (owner is tactcomponent) then begin + tactcomponent(owner).release; + end; +end; + +procedure tcustomiochannel.disconnect; +begin + if not(iocs_disconnecting in fstate) then begin + include(fstate,iocs_disconnecting); + {$ifdef mse_debugsockets} + debugout(self,'disconnect'); + {$endif} + try + if canevent(tmethod(fonbeforedisconnect)) then begin + fonbeforedisconnect(self); + end; + if flocalconn <> nil then begin + flocalconn.disconnect; + end + else begin + internaldisconnect; + end; + factive:= false; + disconnected; + finally + exclude(fstate,iocs_disconnecting); + end; + end; +end; + +procedure tcustomiochannel.checkinactive; +begin + if active and not(csloading in componentstate) then begin + exception.create(name+': Must be inactive.'); + end; +end; + +function tcustomiochannel.canconnect: boolean; +begin + result:= true; +end; + +function tcustomiochannel.commio: boolean; +begin + result:= (flocalconn <> nil) and flocalconn.active; +end; + +procedure tcustomiochannel.doactivated; +begin + active:= true; +// if factive then begin +// connect; +// end; +end; + +procedure tcustomiochannel.dodeactivated; +begin + active:= false; +end; + +procedure tcustomiochannel.setlocalconn(const avalue: tcustomiochannel); +begin + if (avalue <> flocalconn) and not (iocs_localsetting in fstate) then begin + include(fstate,iocs_localsetting); + try + if avalue <> nil then begin + checkinactive; + avalue.checkinactive; + end + else begin + active:= false; + end; + if flocalconn <> nil then begin + flocalconn.localconn:= nil; + end; + flocalconn:= avalue; + if avalue <> nil then begin + avalue.localconn:= self; + end; + finally + exclude(fstate,iocs_localsetting); + end; + end; +end; + +{ tstuffediochannel } + +procedure tstuffediochannel.resetrxbuffer; +begin + fbuffer:= ''; + exclude(fpipestate,pis_rxstarted); + frxcheckedindex:= 0; +end; + +procedure tstuffediochannel.addata(const adata: string); +var + int1,int2: integer; + po1: pchar; + str1: string; +begin + fbuffer:= fbuffer + adata; + int1:= length(fbuffer); + if (int1 >= 2) then begin + po1:= pointer(fbuffer); + if (pis_rxstarted in fpipestate) then begin + for int2:= frxcheckedindex to int1-2 do begin + if (po1[int2] = c_dle) and (po1[int2+1] = c_etx) and + ((int2 = 0) or (po1[int2-1] <> c_dle)) then begin + str1:= copy(fbuffer,int2+3,int1); //next frame + setlength(fbuffer,int2); + try + fsynchronizer.datareceived(unstuff(fbuffer)); + except + application.handleexception(self); + end; + resetrxbuffer; + if str1 <> '' then begin + addata(str1); + end; + exit; + end; + end; + end + else begin + for int2:= 0 to int1-2 do begin + if (po1[int2] = c_dle) and (po1[int2+1] = c_stx) and + ((int2 = 0) or (po1[int2-1] <> c_dle)) then begin + fbuffer:= copy(fbuffer,int2+3,int1); + include(fpipestate,pis_rxstarted); + addata(''); + exit; + end; + end; + end; + repeat + dec(int1); + until (int1 = 0) or (po1[int1] <> c_dle); + frxcheckedindex:= int1; + end; +end; + +procedure tstuffediochannel.receivelocaldata(const adata: string); +begin + addata(adata); +end; + +function tstuffediochannel.stuff(const adata: string): string; +var + int1: integer; + po1,po2: pchar; +begin + setlength(result,2*length(adata)); //max + po1:= pointer(adata); + po2:= pointer(result); + for int1:= 0 to length(adata) - 1 do begin + po2^:= po1[int1]; + if po2^ = stuffchar then begin + inc(po2); + po2^:= stuffchar; + end; + inc(po2); + end; + setlength(result,po2-pointer(result)); +end; + +function tstuffediochannel.unstuff(const adata: string): string; +var +// int1: integer; + po1,po2,po3: pchar; +begin + setlength(result,length(adata)); //max + po1:= pointer(adata); + po3:= po1 + length(adata); + po2:= pointer(result); + while po1 < po3 do begin + po2^:= po1^; + if (po1^ = stuffchar) and (po1[1] = stuffchar) then begin + inc(po1); + end; + inc(po1); + inc(po2); + end; + setlength(result,po2-pointer(result)); +end; + +{ tcustompipeiochannel } + +constructor tcustompipeiochannel.create(aowner: tcomponent); +begin + if frx = nil then begin + frx:= tpipereader.create; + end; + if ftx = nil then begin + ftx:= tpipewriter.create; + end; + fprochandle:= invalidprochandle; + frx.oninputavailable:= {$ifdef FPC}@{$endif}doinputavailable; + frx.onpipebroken:= {$ifdef FPC}@{$endif}dopipebroken; + inherited; +end; + +destructor tcustompipeiochannel.destroy; +begin + inherited; + ftx.free; + frx.free; +end; + +procedure tcustompipeiochannel.internalconnect; +begin + resetrxbuffer; + if fserverapp <> '' then begin + fprochandle:= execmse2(fserverapp,ftx,frx,nil,{false,}-1,[exo_inactive] + {true,false}); + end + else begin + ftx.connect(sys_stdout); + frx.connect(sys_stdin); + end; +end; + +procedure tcustompipeiochannel.internaldisconnect; +var + int1: integer; +begin + ftx.close; + frx.close; + fbuffer:= ''; + if fprochandle <> invalidprochandle then begin + int1:= fprochandle; + fprochandle:= invalidprochandle; + killprocess(int1); + end; +end; + +function tcustompipeiochannel.commio: boolean; +begin + result:= inherited commio or + ((fserverapp = '') or (fprochandle <> invalidprochandle)) + and frx.active; +end; + +procedure tcustompipeiochannel.localsenddata(const adata: ansistring); +begin + flocalconn.receivelocaldata(stx+stuff(adata)+etx); +end; + +procedure tcustompipeiochannel.internalsenddata(const adata: ansistring); +begin + ftx.writestr(stx+stuff(adata)+etx); +end; + +procedure tcustompipeiochannel.doinputavailable(const sender: tpipereader); +begin + addata(sender.readdatastring); +end; + +procedure tcustompipeiochannel.dopipebroken(const sender: tpipereader); +begin + asyncevent(closepipestag); +end; + +procedure tcustompipeiochannel.doasyncevent(var atag: integer); +begin + if atag = closepipestag then begin + disconnect; + end + else begin + inherited; + end; +end; + +{ tpipeifichannel } +{ +constructor tpipeifichannel.create(aowner: tcomponent); +begin + fsynchronizer:= tifisynchronizer.create; + inherited; +end; +} +{ tsocketpipeiochannel } +{ +constructor tsocketpipeiochannel.create(aowner: tcomponent); +begin + if freader = nil then begin + freader:= tsocketreader.create; + end; + if fwriter = nil then begin + fwriter:= tsocketwriter.create; + end; + inherited; +end; +} +{ tiosynchronizer } + +constructor tiosynchronizer.create(const aondatareceived: stringdataprocty); +begin + fondatareceived:= aondatareceived; + fwaitingclients:= tintegeravltree.create; + inherited create; +end; + +destructor tiosynchronizer.destroy; +begin + fwaitingclients.free; + inherited; +end; + +procedure tiosynchronizer.answerreceived(const asequence: sequencety); +var + client1: twaitingclient; +begin + if fwaitingclients.find(integer(asequence),tintegeravlnode(client1)) then begin + client1.answered; + end; +end; + +function tiosynchronizer.preparewait(const asequence: sequencety): twaitingclient; +begin + if threadty(getcurrentthreadid) = id then begin + raise exception.create('Deadlock in tiosynchrionizer.waitforanswer.'); + end; + result:= twaitingclient.create(asequence); + fwaitingclients.addnode(result); +end; + +function tiosynchronizer.waitforanswer(const aclient: twaitingclient; + const waitus: integer): boolean; +var + int1: integer; +begin + int1:= application.unlockall; + try + result:= aclient.wait(waitus); + finally + application.relockall(int1); + end; + fwaitingclients.removenode(aclient); + aclient.free; +end; + +procedure tiosynchronizer.datareceived(const adata: string); +begin + postevent(tstringevent.create(adata)); +end; + +procedure tiosynchronizer.eventloop; +var + str1: string; + event: tstringevent; +begin + while not terminated do begin + event:= tstringevent(waitevent); + if event <> nil then begin + str1:= event.data; + event.free1; + application.lock; + try + fondatareceived(str1); + except + application.handleexception(self); + end; + application.unlock; + end; + end; +end; + +function tiosynchronizer.execute(thread: tmsethread): integer; +begin + eventloop; + result:= 0; +end; + +{ twaitingclient } + +constructor twaitingclient.create(const asequence: sequencety); +begin + sys_semcreate(fsem,0); + inherited create(integer(asequence)); +end; + +destructor twaitingclient.destroy; +begin + sys_semdestroy(fsem); +end; + +procedure twaitingclient.answered; +begin + sys_sempost(fsem); +end; + +function twaitingclient.wait(const awaitus: integer): boolean; +begin + result:= sys_semwait(fsem,awaitus) = sye_ok; +// application.processmessages; +end; + +{ tifisocketclient } +{ +constructor tifisocketclient.create(aowner: tcomponent); +begin + fpipes:= tifisocketclientpipes.create(self); + inherited; +end; +} +{ tsocketclientiochannel } + +constructor tsocketclientiochannel.create(aowner: tcomponent); +begin + fsocket:= tifisocketclient.create(self{nil}); + fsocket.setsubcomponent(true); + fsocket.pipes.rx.oninputavailable:= {$ifdef FPC}@{$endif}doinputavailable; + fsocket.pipes.onbeforedisconnect:= {$ifdef FPC}@{$endif}dobeforedisconnect; + inherited; +end; + +destructor tsocketclientiochannel.destroy; +begin + freeandnil(fsocket);; + inherited; +end; + +procedure tsocketclientiochannel.internalconnect; +begin + fsocket.active:= true; +end; + +procedure tsocketclientiochannel.internaldisconnect; +begin + if fsocket <> nil then begin + fsocket.active:= false; + end; +end; + +function tsocketclientiochannel.commio: boolean; +begin + result:= inherited commio or (fsocket.active and fsocket.pipes.rx.active); +end; + +procedure tsocketclientiochannel.internalsenddata(const adata: ansistring); +begin + fsocket.pipes.tx.writestr(stx+stuff(adata)+etx); +end; + +procedure tsocketclientiochannel.localsenddata(const adata: ansistring); +begin + flocalconn.receivelocaldata(stx+stuff(adata)+etx); +end; + +procedure tsocketclientiochannel.doinputavailable(const sender: tpipereader); +begin + addata(sender.readdatastring); +end; + +procedure tsocketclientiochannel.setsocket(const avalue: tifisocketclient); +begin + fsocket.assign(avalue); +end; + +procedure tsocketclientiochannel.dobeforedisconnect( + const sender: tcustomcommpipes); +begin + disconnect; +end; + +{ tsocketclientifichannel } +{ +constructor tsocketclientifichannel.create(aowner: tcomponent); +begin + fsynchronizer:= tifisynchronizer.create; + inherited; +end; +} +{ tcustomsocketserveriochannel } + +destructor tcustomsocketserveriochannel.destroy; +begin + unlink; + inherited; +end; + +procedure tcustomsocketserveriochannel.link(const apipes: tcustomcommpipes); +begin + unlink; + dobeforeconnect; + setlinkedvar(apipes,tlinkedpersistent(fpipes)); + fpipes.onbeforedisconnect:= {$ifdef FPC}@{$endif}dobeforedisconnect; + fpipes.rx.oninputavailable:= {$ifdef FPC}@{$endif}doinputavailable; + doafterconnect; +end; + +procedure tcustomsocketserveriochannel.unlink; +begin + if funlinking = 0 then begin + inc(funlinking); + try + if fpipes <> nil then begin + fpipes.rx.oninputavailable:= nil; + fpipes.close; + end; + finally + setlinkedvar(nil,tlinkedpersistent(fpipes)); +// fpipes:= nil; + dec(funlinking); + end; + end; +end; + +procedure tcustomsocketserveriochannel.internalconnect; +begin + raise exception.create('Not implemented.'); +end; + +procedure tcustomsocketserveriochannel.internaldisconnect; +begin + if fpipes <> nil then begin + fpipes.close; + end; +end; + +function tcustomsocketserveriochannel.commio: boolean; +begin + result:= inherited commio or (fpipes <> nil) and fpipes.rx.active; +end; + +procedure tcustomsocketserveriochannel.internalsenddata(const adata: ansistring); +begin + fpipes.tx.writestr(stx+stuff(adata)+etx); +end; + +procedure tcustomsocketserveriochannel.localsenddata(const adata: ansistring); +begin + flocalconn.receivelocaldata(stx+stuff(adata)+etx); +end; + +procedure tcustomsocketserveriochannel.doinputavailable(const sender: tpipereader); +begin + addata(sender.readdatastring); +end; + +procedure tcustomsocketserveriochannel.dobeforedisconnect( + const sender: tcustomcommpipes); +begin + disconnect; + unlink; +end; + +function tcustomsocketserveriochannel.canconnect: boolean; +begin + result:= false; +end; + +{ tsocketserveriochannel } + +{ tifiiolinkcomponent } + +procedure tifiiolinkcomponent.setchannel(const avalue: tcustomiochannel); +begin + setlinkedvar(avalue,tmsecomponent(fchannel)); +// avalue.fsynchronizer.onsynchronize:= @ifidatasynchronize; +end; + +{ tsocketserverifichannel } +{ +constructor tsocketserverifichannel.create(aowner: tcomponent); +begin + fsynchronizer:= tifisynchronizer.create; + inherited; +end; +} +{ tsocketserverstdifichannel } +{ +constructor tsocketserverstdifichannel.create(aowner: tcomponent); +begin + fsynchronizer:= tifisynchronizer.create; + inherited; +end; +} +{ tsocketstdiochannel } + +constructor tsocketstdiochannel.create(aowner: tcomponent); +begin + frx:= tsocketreader.create(nil); //todo: test!!!!!! + tsocketreader1(frx).fonafterconnect:= {$ifdef FPC}@{$endif}doafterconnect; + ftx:= tsocketwriter.create(nil); + inherited; +end; + +procedure tsocketstdiochannel.setcryptoio(const avalue: tcryptoio); +begin + setlinkedvar(avalue,tmsecomponent(fcryptoio)); +end; +{ +procedure tsocketstdiochannel.doafterconnect; +begin + fcryptioinfo.handler:= fcryptio; + connectcryptio(tsocketwriter(ftx),tsocketreader(frx),fcryptioinfo); +end; +} +procedure tsocketstdiochannel.internalconnect; +begin +// fcryptioinfo.handler:= fcryptio; + connectcryptoio(fcryptoio,tsocketwriter(ftx),tsocketreader(frx),fcryptoioinfo, + sys_stdout,sys_stdin); + inherited; +end; + +procedure tsocketstdiochannel.internaldisconnect; +begin + inherited; + cryptounlink(fcryptoioinfo); +end; + +end. diff --git a/mseide-msegui/lib/common/ifi/mseificomp.pas b/mseide-msegui/lib/common/ifi/mseificomp.pas new file mode 100644 index 0000000..ed0fd36 --- /dev/null +++ b/mseide-msegui/lib/common/ifi/mseificomp.pas @@ -0,0 +1,5392 @@ +{ MSEgui Copyright (c) 2009-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + experimental user <-> business logic connection components. + Warning: works with RTTI and is therefore slow. +} +{$ifdef FPC} + {$if defined(FPC) and (fpc_fullversion >= 020501)} + {$define mse_fpc_2_6} + {$ifend} + {$if defined(FPC) and (fpc_fullversion >= 030000)} + {$define mse_fpc_3_0} + {$ifend} + {$ifdef mse_fpc_2_6} + {$define mse_hasvtunicodestring} + {$endif} + {$ifdef mse_fpc_3_0} + {$define mse_hastkpointer} + {$endif} +{$endif} +unit mseificomp; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,mseclasses,{msegui,}mseifiglob,mseglob,typinfo,msestrings, + msetypes,mseinterfaces,msetimer, + mseificompglob,msearrayprops,msedatalist,msestat,msestatfile,mseapplication, + mseeditglob; + +type + tifilinkcomp = class; + tifivaluelinkcomp = class; + tcustomificlientcontroller = class; + tstringclientcontroller = class; + tintegerclientcontroller = class; + tint64clientcontroller = class; + tpointerclientcontroller = class; + tbooleanclientcontroller = class; + trealclientcontroller = class; + tdatetimeclientcontroller = class; + + ifieventty = procedure(const sender: tcustomificlientcontroller) of object; + ificlienteventty = procedure(const sender: tcustomificlientcontroller; + const aclient: iificlient) of object; + ifistringclienteventty = procedure(const sender: tstringclientcontroller; + const aclient: iifidatalink) of object; + ifiintegerclienteventty = procedure(const sender: tintegerclientcontroller; + const aclient: iifidatalink) of object; + ifiint64clienteventty = procedure(const sender: tint64clientcontroller; + const aclient: iifidatalink) of object; + ifipointerclienteventty = procedure(const sender: tpointerclientcontroller; + const aclient: iifidatalink) of object; + ifibooleanclienteventty = procedure(const sender: tbooleanclientcontroller; + const aclient: iifidatalink) of object; + ifirealclienteventty = procedure(const sender: trealclientcontroller; + const aclient: iifidatalink) of object; + ifidatetimeclienteventty = procedure(const sender: tdatetimeclientcontroller; + const aclient: iifidatalink) of object; + + ificlientstateeventty = procedure(const sender: tcustomificlientcontroller; + const aclient: iificlient; + const astate: ifiwidgetstatesty; + const achangedstate: ifiwidgetstatesty) of object; + ificlientmodalresulteventty = + procedure(const sender: tcustomificlientcontroller; + const aclient: iificlient; + const amodalresult: modalresultty) of object; + ificlientclosequeryeventty = + procedure(const sender: tcustomificlientcontroller; + const aclient: iificlient; + var amodalresult: modalresultty) of object; + + ifivaluelinkstatety = (ivs_linking,ivs_valuesetting,ivs_loadedproc); + ifivaluelinkstatesty = set of ifivaluelinkstatety; + valueclientoptionty = (vco_datalist,vco_nosync,vco_novaluetoclient, + vco_readonly,vco_notnull); + valueclientoptionsty = set of valueclientoptionty; + + tcustomificlientcontroller = class(tlinkedpersistent,iifidataserver,istatfile) + private + fonclientvaluechanged: ificlienteventty; + fonclientexecute: ificlienteventty; + fonclientstatechanged: ificlientstateeventty; + fonclientmodalresult: ificlientmodalresulteventty; + fstatfile: tstatfile; + fstatvarname: msestring; + fstatpriority: integer; + fonchangebefore: ifieventty; + fonchangeafter: ifieventty; + fonclientclosequery: ificlientclosequeryeventty; + function getintegerpro(const aname: string): integer; + procedure setintegerpro(const aname: string; const avalue: integer); + function getmsestringpro(const aname: string): msestring; + procedure setmsestringpro(const aname: string; const avalue: msestring); + function getbooleanpro(const aname: string): boolean; + procedure setbooleanpro(const aname: string; const avalue: boolean); + function getrealtypro(const aname: string): realty; + procedure setrealtypro(const aname: string; const avalue: realty); + function getdatetimepro(const aname: string): tdatetime; + procedure setdatetimepro(const aname: string; const avalue: tdatetime); + procedure setstatfile(const avalue: tstatfile); + protected + fowner: tmsecomponent; + fkind: ttypekind; + fstate: ifivaluelinkstatesty; + foptionsvalue: valueclientoptionsty; + fwidgetstate: ifiwidgetstatesty; + fwidgetstatebefore: ifiwidgetstatesty; + fchangedclient: pointer; + + fapropname: string; + fapropkind: ttypekind; + fapropvalue: pointer; + + procedure dogetprop(const alink: pointer); + procedure getprop(const aname: string; const akind: ttypekind; + const avaluepo: pointer); + procedure dosetprop(const alink: pointer); + procedure setprop(const aname: string; const akind: ttypekind; + const avaluepo: pointer); + procedure finalizelink(const alink: pointer); + procedure finalizelinks; + procedure loaded; virtual; + function errorname(const ainstance: tobject): string; + procedure interfaceerror; + function getifilinkkind: ptypeinfo; virtual; + function checkcomponent(const aintf: iifilink): pointer; virtual; + //returns interface info, exception if link invalid + procedure valuestootherclient(const alink: pointer); + procedure valuestoclient(const alink: pointer); virtual; + procedure clienttovalues(const alink: pointer); virtual; + procedure change(const alink: iificlient = nil); +// procedure change(); + procedure linkset(const alink: iificlient); virtual; + + function setmsestringval(const alink: iificlient; const aname: string; + const avalue: msestring): boolean; + //true if found + function getmsestringval(const alink: iificlient; const aname: string; + var avalue: msestring): boolean; + //true if found + function setintegerval(const alink: iificlient; const aname: string; + const avalue: integer): boolean; + //true if found + function getintegerval(const alink: iificlient; const aname: string; + var avalue: integer): boolean; + //true if found + function setint64val(const alink: iificlient; const aname: string; + const avalue: int64): boolean; + //true if found + function getint64val(const alink: iificlient; const aname: string; + var avalue: int64): boolean; + //true if found + function setpointerval(const alink: iifidatalink; const aname: string; + const avalue: pointer): boolean; + //true if found + function getpointerval(const alink: iifidatalink; const aname: string; + var avalue: pointer): boolean; + //true if found + function setbooleanval(const alink: iificlient; const aname: string; + const avalue: boolean): boolean; + //true if found + function getbooleanval(const alink: iificlient; const aname: string; + var avalue: boolean): boolean; + //true if found + function setrealtyval(const alink: iificlient; const aname: string; + const avalue: realty): boolean; + //true if found + function getrealtyval(const alink: iificlient; const aname: string; + var avalue: realty): boolean; + //true if found + function setdatetimeval(const alink: iificlient; const aname: string; + const avalue: tdatetime): boolean; + //true if found + function getdatetimeval(const alink: iificlient; const aname: string; + var avalue: tdatetime): boolean; + //true if found + procedure distribute(const sender: iificlient; + const local: boolean; const exec: boolean); virtual; + //iifiserver + procedure execute(const sender: iificlient); virtual; + procedure valuechanged(const sender: iifidatalink); + procedure statechanged(const sender: iificlient; + const astate: ifiwidgetstatesty); virtual; + procedure setvalue(const sender: iificlient; var avalue; + var accept: boolean; const arow: integer); virtual; + procedure dataentered(const sender: iificlient; const arow: integer); virtual; + procedure closequery(const sender: iificlient; + var amodalresult: modalresultty); virtual; + procedure sendmodalresult(const sender: iificlient; + const amodalresult: modalresultty); virtual; + procedure updateoptionsedit(var avalue: optionseditty); virtual; + //istatfile + procedure dostatread(const reader: tstatreader); virtual; + procedure dostatwrite(const writer: tstatwriter); virtual; + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + public + constructor create(const aowner: tmsecomponent; const akind: ttypekind); + reintroduce; overload; + constructor create(const aowner: tmsecomponent); overload; virtual; + function canconnect(const acomponent: tcomponent): boolean; virtual; + + property msestringprop[const aname: string]: msestring read getmsestringpro + write setmsestringpro; + property integerprop[const aname: string]: integer read getintegerpro + write setintegerpro; + property booleanprop[const aname: string]: boolean read getbooleanpro + write setbooleanpro; + property realtyprop[const aname: string]: realty read getrealtypro + write setrealtypro; + property datetimeprop[const aname: string]: tdatetime read getdatetimepro + write setdatetimepro; + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read fstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + property onchangebefore: ifieventty read fonchangebefore + write fonchangebefore; + //for data change and execute + property onchangeafter: ifieventty read fonchangeafter write fonchangeafter; + //for data change and execute + property onclientvaluechanged: ificlienteventty read fonclientvaluechanged + write fonclientvaluechanged; + property onclientstatechanged: ificlientstateeventty + read fonclientstatechanged write fonclientstatechanged; + property onclientclosequery: ificlientclosequeryeventty + read fonclientclosequery write fonclientclosequery; + property onclientmodalresult: ificlientmodalresulteventty + read fonclientmodalresult write fonclientmodalresult; + property onclientexecute: ificlienteventty read fonclientexecute + write fonclientexecute; + end; + + customificlientcontrollerclassty = class of tcustomificlientcontroller; + + tificlientcontroller = class(tcustomificlientcontroller) + published + property statfile; + property statvarname; + property statpriority; + property onchangebefore; + property onchangeafter; + { + property onclientvaluechanged; + } + property onclientstatechanged; + property onclientclosequery; + property onclientmodalresult; + property onclientexecute; + end; + + texecclientcontroller = class(tificlientcontroller) + private + fenabled: boolean; + procedure setenabled(const avalue: boolean); + protected + function getifilinkkind: ptypeinfo; override; + procedure setclientenabled(const alink: pointer); + procedure valuestoclient(const alink: pointer); override; + procedure execute(const sender: iificlient) override; + procedure linkset(const alink: iificlient); override; + procedure dostatread(const reader: tstatreader) override; + procedure dostatwrite(const writer: tstatwriter) override; + public + constructor create(const aowner: tmsecomponent); override; + function canconnect(const acomponent: tcomponent): boolean; override; + procedure execute; reintroduce; + published + property optionsvalue: valueclientoptionsty read foptionsvalue + write foptionsvalue default []; + property enabled: boolean read fenabled write setenabled default true; + property onclientvaluechanged; + end; + + tformclientcontroller = class(tificlientcontroller) + private + procedure setmodalresult(const avalue: modalresultty); + protected + fmodalresult: modalresultty; + function getifilinkkind: ptypeinfo; override; +// procedure execute(const sender: iificlient); overload; override; + procedure linkset(const alink: iificlient) override; + procedure valuestoclient(const alink: pointer) override; + procedure sendmodalresult(const sender: iificlient; + const amodalresult: modalresultty) override; + public + property modalresult: modalresultty read fmodalresult write setmodalresult; + property onclientvaluechanged; + end; + + valarsetterty = procedure(const alink: pointer; var handled: boolean) of object; + valargetterty = procedure(const alink: pointer; var handled: boolean) of object; + + itemsetterty = procedure(const alink: pointer; var handled: boolean) of object; + itemgetterty = procedure(const alink: pointer; var handled: boolean) of object; + + tifidatasource = class; + ififieldnamety = type ansistring; //type for property editor + ifisourcefieldnamety = type ansistring; //type for property editor + + iififieldinfo = interface(inullinterface)[miid_iififieldinfo] + procedure getfieldinfo(const apropname: ififieldnamety; + var adatasource: tifidatasource; + var atypes: listdatatypesty); + end; + + iifidatasourceclient = interface(iobjectlink) + function getobjectlinker: tobjectlinker; + procedure bindingchanged; + function ifigriddata: tdatalist; + function ififieldname: string; + end; + + indexeventty = procedure(const sender: tcustomificlientcontroller; + const aclient: iificlient; const aindex: integer) of object; + + setbooleanclienteventty = + procedure(const sender: tcustomificlientcontroller; + const aclient: iificlient; var avalue: boolean; + var accept: boolean; const aindex: integer) of object; + setstringclienteventty = + procedure(const sender: tcustomificlientcontroller; + const aclient: iificlient; var avalue: msestring; + var accept: boolean; const aindex: integer) of object; + setansistringclienteventty = procedure( + const sender: tcustomificlientcontroller; + var avalue: ansistring; + var accept: boolean; const aindex: integer) of object; + setintegerclienteventty = + procedure(const sender: tobject; const aclient: iificlient; + var avalue: integer; + var accept: boolean; const aindex: integer) of object; + //equal parameters as setcoloreventty for tcoloredit! + setint64clienteventty = + procedure(const sender: tcustomificlientcontroller; + const aclient: iificlient; var avalue: int64; + var accept: boolean; const aindex: integer) of object; + setpointerclienteventty = + procedure(const sender: tcustomificlientcontroller; + const aclient: iificlient; var avalue: pointer; + var accept: boolean; const aindex: integer) of object; + setrealclienteventty = + procedure(const sender: tcustomificlientcontroller; + const aclient: iificlient; var avalue: realty; + var accept: boolean; const aindex: integer) of object; + setdatetimeclienteventty = + procedure(const sender: tcustomificlientcontroller; + const aclient: iificlient; var avalue: tdatetime; + var accept: boolean; const aindex: integer) of object; + + tvalueclientcontroller = class(tificlientcontroller, + iififieldinfo,iifidatasourceclient) + private +// fvalarpo: pointer; + fitempo: pointer; +// fitemindex: integer; + fonclientdataentered: indexeventty; + fdatasource: tifidatasource; + ffieldname: ififieldnamety; + procedure setoptionsvalue(const avalue: valueclientoptionsty); + procedure setdatasource(const avalue: tifidatasource); + procedure setfieldname(const avalue: ififieldnamety); + procedure linkdatalist1(const alink: pointer); + procedure updatereadonlystate1(const alink: pointer); + protected + fdatalist: tdatalist; + procedure updateoptionsedit(var avalue: optionseditty); override; + procedure linkset(const alink: iificlient); override; + + function getifilinkkind: ptypeinfo; override; + procedure setvalue(const sender: iificlient; var avalue; + var accept: boolean; const arow: integer); override; + procedure dataentered(const sender: iificlient; + const arow: integer); override; + procedure loaded; override; + procedure statreadvalue(const reader: tstatreader); virtual; + procedure statwritevalue(const reader: tstatwriter); virtual; + procedure dostatread(const reader: tstatreader); override; + procedure dostatwrite(const writer: tstatwriter); override; + + procedure linkdatalist; + procedure updatereadonlystate; + procedure optionsvaluechanged; virtual; + function createdatalist: tdatalist; virtual; abstract; + function getlistdatatypes: listdatatypesty; virtual; abstract; + procedure statreadlist(const alink: pointer); + procedure statwritelist(const alink: pointer; var handled: boolean); + //iifidatasourceclient + procedure bindingchanged; + function ifigriddata: tdatalist; + function ififieldname: string; + //iififieldinfo + procedure getfieldinfo(const apropname: ififieldnamety; + var adatasource: tifidatasource; + var atypes: listdatatypesty); + public + destructor destroy; override; + function canconnect(const acomponent: tcomponent): boolean; override; + property datalist: tdatalist read fdatalist; + published + property onclientdataentered: indexeventty read fonclientdataentered + write fonclientdataentered; + property optionsvalue: valueclientoptionsty read foptionsvalue + write setoptionsvalue default []; + property datasource: tifidatasource read fdatasource write setdatasource; + property fieldname: ififieldnamety read ffieldname write setfieldname; + end; + + tifimsestringdatalist = class; + + tstringclientcontroller = class(tvalueclientcontroller) + private + fvalue: msestring; + fvaluedefault: msestring; + fonclientsetvalue: setstringclienteventty; + procedure setvalue1(const avalue: msestring); + function getgriddata: tifimsestringdatalist; + function getonclientvaluechanged: ifistringclienteventty; + procedure setonclientvaluechanged(const avalue: ifistringclienteventty); + protected + procedure valuestoclient(const alink: pointer); override; + procedure clienttovalues(const alink: pointer); override; + procedure setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); override; + function createdatalist: tdatalist; override; + function getlistdatatypes: listdatatypesty; override; + //istatfile + procedure statreadvalue(const reader: tstatreader); override; + procedure statwritevalue(const writer: tstatwriter); override; + public + constructor create(const aowner: tmsecomponent); override; + property griddata: tifimsestringdatalist read getgriddata; +// property gridvalues: msestringarty read getgridvalues write setgridvalues; +// property gridvalue[const index: integer]: msestring read getgridvalue +// write setgridvalue; + published + property value: msestring read fvalue write setvalue1; + property valuedefault: msestring read fvaluedefault write fvaluedefault; + property onclientsetvalue: setstringclienteventty + read fonclientsetvalue write fonclientsetvalue; + property onclientvaluechanged: ifistringclienteventty + read getonclientvaluechanged write setonclientvaluechanged; + end; + + tifidropdowncol = class(tmsestringdatalist,iififieldinfo,iifidatasourceclient) + private + fdatasource: tifidatasource; + fdatafield: ififieldnamety; + procedure setdatasource(const avalue: tifidatasource); + procedure setdatafield(const avalue: ififieldnamety); + protected + //iifidatasourceclient + procedure bindingchanged; + function ifigriddata: tdatalist; + function ififieldname: string; + //iififieldinfo + procedure getfieldinfo(const apropname: ififieldnamety; + var adatasource: tifidatasource; + var atypes: listdatatypesty); + published + property datasource: tifidatasource read fdatasource write setdatasource; + property datafield: ififieldnamety read fdatafield write setdatafield; + end; + + tifidropdownlistcontroller = class; + + tifidropdowncols = class(townedpersistentarrayprop) + private + function getitems(const index: integer): tifidropdowncol; + protected + procedure createitem(const index: integer; var item: tpersistent); override; + procedure colchanged(const sender: tobject); + procedure dochange(const index: integer); override; + public + class function getitemclasstype: persistentclassty; override; + constructor create(const aowner: tifidropdownlistcontroller); reintroduce; + property items[const index: integer]: tifidropdowncol read getitems; default; + end; + + iifidropdownlistdatalink = interface(iifidatalink) + procedure ifidropdownlistchanged(const acols: tifidropdowncols); + end; + + tifidropdownlistcontroller = class(teventpersistent) + private + fcols: tifidropdowncols; + fowner: tvalueclientcontroller; + procedure setcols(const avalue: tifidropdowncols); + procedure valuestoclient(const alink: pointer); + public + constructor create(const aowner: tvalueclientcontroller); reintroduce; + destructor destroy; override; + published + property cols: tifidropdowncols read fcols write setcols; + end; + + tdropdownlistclientcontroller = class(tstringclientcontroller) + private + fdropdown: tifidropdownlistcontroller; + procedure setdropdown(const avalue: tifidropdownlistcontroller); + protected + function getifilinkkind: ptypeinfo; override; + procedure valuestoclient(const alink: pointer); override; + public + constructor create(const aowner: tmsecomponent); override; + destructor destroy; override; + published + property dropdown: tifidropdownlistcontroller read fdropdown write setdropdown; + end; + + tifiintegerdatalist = class; + + tintegerclientcontroller = class(tvalueclientcontroller) + private + fvalue: integer; + fvaluedefault: integer; + fvaluemin: integer; + fvaluemax: integer; + fonclientsetvalue: setintegerclienteventty; + procedure setvalue1(const avalue: integer); + procedure setvaluemin(const avalue: integer); + procedure setvaluemax(const avalue: integer); + function getgriddata: tifiintegerdatalist; + procedure readmin(reader: treader); + procedure readmax(reader: treader); + function getonclientvaluechanged: ifiintegerclienteventty; + procedure setonclientvaluechanged(const avalue: ifiintegerclienteventty); + protected + procedure defineproperties(filer: tfiler) override; + procedure valuestoclient(const alink: pointer); override; + procedure clienttovalues(const alink: pointer); override; + procedure setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); override; + function createdatalist: tdatalist; override; + function getlistdatatypes: listdatatypesty; override; + //istatfile + procedure statreadvalue(const reader: tstatreader); override; + procedure statwritevalue(const writer: tstatwriter); override; + public + constructor create(const aowner: tmsecomponent); override; + property griddata: tifiintegerdatalist read getgriddata; + published + property value: integer read fvalue write setvalue1 default 0; + property valuedefault: integer read fvaluedefault + write fvaluedefault default 0; + property valuemin: integer read fvaluemin write setvaluemin default 0; + property valuemax: integer read fvaluemax write setvaluemax default maxint; + property onclientsetvalue: setintegerclienteventty + read fonclientsetvalue write fonclientsetvalue; + property onclientvaluechanged: ifiintegerclienteventty + read getonclientvaluechanged write setonclientvaluechanged; + end; + + tifiint64datalist = class; + + tint64clientcontroller = class(tvalueclientcontroller) + private + fvalue: int64; + fvaluedefault: int64; + fvaluemin: int64; + fvaluemax: int64; + fonclientsetvalue: setint64clienteventty; + procedure setvalue1(const avalue: int64); + procedure setvaluemin(const avalue: int64); + procedure setvaluemax(const avalue: int64); + function getgriddata: tifiint64datalist; + procedure readmin(reader: treader); + procedure readmax(reader: treader); + function getonclientvaluechanged: ifiint64clienteventty; + procedure setonclientvaluechanged(const avalue: ifiint64clienteventty); + protected + procedure defineproperties(filer: tfiler) override; + procedure valuestoclient(const alink: pointer); override; + procedure clienttovalues(const alink: pointer); override; + procedure setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); override; + function createdatalist: tdatalist; override; + function getlistdatatypes: listdatatypesty; override; + //istatfile + procedure statreadvalue(const reader: tstatreader); override; + procedure statwritevalue(const writer: tstatwriter); override; + public + constructor create(const aowner: tmsecomponent); override; + property griddata: tifiint64datalist read getgriddata; + published + property value: int64 read fvalue write setvalue1 default 0; + property valuedefault: int64 read fvaluedefault + write fvaluedefault default 0; + property valuemin: int64 read fvaluemin write setvaluemin default 0; + property valuemax: int64 read fvaluemax write setvaluemax default maxint; + property onclientsetvalue: setint64clienteventty + read fonclientsetvalue write fonclientsetvalue; + property onclientvaluechanged: ifiint64clienteventty + read getonclientvaluechanged write setonclientvaluechanged; + end; + + tifipointerdatalist = class; + + tpointerclientcontroller = class(tvalueclientcontroller) + private + fvalue: pointer; + fonclientsetvalue: setpointerclienteventty; + procedure setvalue1(const avalue: pointer); + function getgriddata: tifipointerdatalist; + function getonclientvaluechanged: ifipointerclienteventty; + procedure setonclientvaluechanged(const avalue: ifipointerclienteventty); + protected + procedure valuestoclient(const alink: pointer); override; + procedure clienttovalues(const alink: pointer); override; + procedure setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); override; + function createdatalist: tdatalist; override; + function getlistdatatypes: listdatatypesty; override; + public + constructor create(const aowner: tmsecomponent); override; + property griddata: tifipointerdatalist read getgriddata; + property value: pointer read fvalue write setvalue1 default nil; + published + property onclientsetvalue: setpointerclienteventty + read fonclientsetvalue write fonclientsetvalue; + property onclientvaluechanged: ifipointerclienteventty + read getonclientvaluechanged write setonclientvaluechanged; + end; + + tenumclientcontroller = class(tintegerclientcontroller) + private + fdropdown: tifidropdownlistcontroller; + procedure setdropdown(const avalue: tifidropdownlistcontroller); + protected + function getifilinkkind: ptypeinfo; override; + procedure valuestoclient(const alink: pointer); override; + public + constructor create(const aowner: tmsecomponent); override; + destructor destroy; override; + published + property dropdown: tifidropdownlistcontroller read fdropdown write setdropdown; + property value default -1; + property valuedefault default -1; + property valuemin default -1; + end; + + tifibooleandatalist = class; + + tbooleanclientcontroller = class(tvalueclientcontroller) + private + fvalue: longbool; + fvaluedefault: longbool; + fonclientsetvalue: setbooleanclienteventty; + function getvalue: boolean; + procedure setvalue1(const avalue: boolean); + function getvaluedefault: boolean; + procedure setvaluedefault(const avalue: boolean); +// function getgridvalues: longboolarty; +// procedure setgridvalues(const avalue: longboolarty); +// function getgridvalue(const index: integer): boolean; +// procedure setgridvalue(const index: integer; const avalue: boolean); + function getgriddata: tifibooleandatalist; + function getonclientvaluechanged: ifibooleanclienteventty; + procedure setonclientvaluechanged(const avalue: ifibooleanclienteventty); + protected + procedure valuestoclient(const alink: pointer); override; + procedure clienttovalues(const alink: pointer); override; + procedure setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); override; + function createdatalist: tdatalist; override; + function getlistdatatypes: listdatatypesty; override; + //istatfile + procedure statreadvalue(const reader: tstatreader); override; + procedure statwritevalue(const writer: tstatwriter); override; + public + constructor create(const aowner: tmsecomponent); override; + property griddata: tifibooleandatalist read getgriddata; +// property gridvalues: longboolarty read getgridvalues write setgridvalues; +// property gridvalue[const index: integer]: boolean read getgridvalue +// write setgridvalue; + published + property value: boolean read getvalue write setvalue1 default false; + property valuedefault: boolean read getvaluedefault write setvaluedefault + default false; + property onclientsetvalue: setbooleanclienteventty + read fonclientsetvalue write fonclientsetvalue; + property onclientvaluechanged: ifibooleanclienteventty + read getonclientvaluechanged write setonclientvaluechanged; + end; + + tifirealdatalist = class; + + trealclientcontroller = class(tvalueclientcontroller) + private + fvalue: realty; + fvaluedefault: realty; + fvaluemin: realty; + fvaluemax: realty; + fonclientsetvalue: setrealclienteventty; + procedure setvalue1(const avalue: realty); + procedure setvaluemin(const avalue: realty); + procedure setvaluemax(const avalue: realty); + procedure readvalue(reader: treader); + procedure readmin1(reader: treader); + procedure readmax1(reader: treader); + procedure readvaluedefault(reader: treader); + function getgriddata: tifirealdatalist; + procedure readmin(reader: treader); + procedure readmax(reader: treader); + function getonclientvaluechanged: ifirealclienteventty; + procedure setonclientvaluechanged(const avalue: ifirealclienteventty); + protected + procedure valuestoclient(const alink: pointer); override; + procedure clienttovalues(const alink: pointer); override; + procedure setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); override; + function createdatalist: tdatalist; override; + procedure defineproperties(filer: tfiler); override; + function getlistdatatypes: listdatatypesty; override; + //istatfile + procedure statreadvalue(const reader: tstatreader); override; + procedure statwritevalue(const writer: tstatwriter); override; + public + constructor create(const aowner: tmsecomponent); override; + property griddata: tifirealdatalist read getgriddata; +// property gridvalues: realarty read getgridvalues write setgridvalues; +// property gridvalue[const index: integer]: real read getgridvalue +// write setgridvalue; + published + property value: realty read fvalue write setvalue1 {stored false}; + property valuedefault: realty read fvaluedefault + write fvaluedefault {stored false}; + property valuemin: realty read fvaluemin write setvaluemin {stored false}; + property valuemax: realty read fvaluemax write setvaluemax {stored false}; + property onclientsetvalue: setrealclienteventty + read fonclientsetvalue write fonclientsetvalue; + property onclientvaluechanged: ifirealclienteventty + read getonclientvaluechanged write setonclientvaluechanged; + end; + + tifidatetimedatalist = class; + + tdatetimeclientcontroller = class(tvalueclientcontroller) + private + fvalue: tdatetime; + fvaluedefault: tdatetime; + fvaluemin: tdatetime; + fvaluemax: tdatetime; + fonclientsetvalue: setdatetimeclienteventty; + procedure setvalue1(const avalue: tdatetime); + procedure setvaluemin(const avalue: tdatetime); + procedure setvaluemax(const avalue: tdatetime); + procedure readvalue(reader: treader); + procedure readmin1(reader: treader); + procedure readmax1(reader: treader); + procedure readvaluedefault(reader: treader); + function getgriddata: tifidatetimedatalist; + procedure readmin(reader: treader); + procedure readmax(reader: treader); + function getonclientvaluechanged: ifidatetimeclienteventty; + procedure setonclientvaluechanged(const avalue: ifidatetimeclienteventty); + protected + procedure valuestoclient(const alink: pointer); override; + procedure clienttovalues(const alink: pointer); override; + procedure setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); override; + function createdatalist: tdatalist; override; + procedure defineproperties(filer: tfiler); override; + function getlistdatatypes: listdatatypesty; override; + //istatfile + procedure statreadvalue(const reader: tstatreader); override; + procedure statwritevalue(const writer: tstatwriter); override; + public + constructor create(const aowner: tmsecomponent); override; + property griddata: tifidatetimedatalist read getgriddata; + published + property value: tdatetime read fvalue write setvalue1 {stored false}; + property valuedefault: tdatetime read fvaluedefault + write fvaluedefault {stored false}; + property valuemin: tdatetime read fvaluemin write setvaluemin {stored false}; + property valuemax: tdatetime read fvaluemax write setvaluemax {stored false}; + property onclientsetvalue: setdatetimeclienteventty + read fonclientsetvalue write fonclientsetvalue; + property onclientvaluechanged: ifidatetimeclienteventty + read getonclientvaluechanged write setonclientvaluechanged; + end; + + ificelleventty = procedure(const sender: tobject; + var info: ificelleventinfoty) of object; + ifibeforeblockeventty = procedure(const sender: tobject; + var aindex,acount: integer; const userinput: boolean) of object; + ifiafterblockeventty = procedure(const sender: tobject; + const aindex,acount: integer; const userinput: boolean) of object; + + tificolitem = class(tmsecomponentlinkitem) + private + function getlink: tifivaluelinkcomp; + procedure setlink(const avalue: tifivaluelinkcomp); + published + property link: tifivaluelinkcomp read getlink write setlink; + end; + + tifilinkcomparrayprop = class(tmsecomponentlinkarrayprop) + private + function getitems(const index: integer): tificolitem; + public + constructor create; + class function getitemclasstype: persistentclassty; override; + property items[const index: integer]: tificolitem read getitems; default; + end; + + tgridclientcontroller = class; + + trowstatehandler = class(tdatalist,iifidatalink) + private + fifilink: tifivaluelinkcomp; + flistlink: listlinkinfoty; + findexpar: integer; + procedure setifilink(const avalue: tifivaluelinkcomp); + protected + fowner: tgridclientcontroller; + procedure updateclient(const alink: pointer); virtual; abstract; + procedure updateremote(const sender: tcustomrowstatelist; + const aindex: integer); virtual; abstract; + procedure itemchanged(const sender: tcustomrowstatelist; + const aindex: integer); + //iifidatalink + procedure setifiserverintf(const aintf: iifiserver); + function getdefaultifilink: iificlient; virtual; + procedure ifisetvalue(var avalue; var accept: boolean); + procedure getifivalue(var avalue); + procedure setifivalue(const avalue); + function getifilinkkind: ptypeinfo; + procedure setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); + procedure updateifigriddata(const sender: tobject; const alist: tdatalist); + function getgriddata: tdatalist; reintroduce; overload; + function getvalueprop: ppropinfo; + procedure updatereadonlystate; + property ifilink: tifivaluelinkcomp read fifilink write setifilink; + public + constructor create(const aowner: tgridclientcontroller); reintroduce; + destructor destroy; override; + procedure listdestroyed(const sender: tdatalist); override; + procedure sourcechange(const sender: tdatalist; + const aindex: integer); override; + function canlink(const asource: tdatalist; + const atag: integer): boolean; override; + end; + + tifiintegerlinkcomp = class; + + trowstateintegerhandler = class(trowstatehandler) + private + function getifilink: tifiintegerlinkcomp; + procedure setifilink(const avalue: tifiintegerlinkcomp); + public + property ifilink: tifiintegerlinkcomp read getifilink write setifilink; + end; + + tifibooleanlinkcomp = class; + + trowstatebooleanhandler = class(trowstatehandler) + private + function getifilink: tifibooleanlinkcomp; + procedure setifilink(const avalue: tifibooleanlinkcomp); + public + property ifilink: tifibooleanlinkcomp read getifilink write setifilink; + end; + + trowstatecolorhandler = class(trowstateintegerhandler) + protected + procedure updateclient(const alink: pointer); override; + procedure updateremote(const sender: tcustomrowstatelist; + const aindex: integer); override; + end; + + trowstatefonthandler = class(trowstateintegerhandler) + protected + procedure updateclient(const alink: pointer); override; + procedure updateremote(const sender: tcustomrowstatelist; + const aindex: integer); override; + end; + + trowstatefoldlevelhandler = class(trowstateintegerhandler) + protected + procedure updateclient(const alink: pointer); override; + procedure updateremote(const sender: tcustomrowstatelist; + const aindex: integer); override; + end; + + trowstatehiddenhandler = class(trowstatebooleanhandler) + protected + procedure updateclient(const alink: pointer); override; + procedure updateremote(const sender: tcustomrowstatelist; + const aindex: integer); override; + end; + + trowstatefoldissumhandler = class(trowstatebooleanhandler) + protected + procedure updateclient(const alink: pointer); override; + procedure updateremote(const sender: tcustomrowstatelist; + const aindex: integer); override; + end; + + gridclientstatety = (gcs_itemchangelock); + gridclientstatesty = set of gridclientstatety; + + tgridclientcontroller = class(tificlientcontroller,idatalistclient) + private + frowcount: integer; + foncellevent: ificelleventty; + fdatacols: tifilinkcomparrayprop; + fcheckautoappend: boolean; + fitempo: pointer; + frowstatecolor: trowstatecolorhandler; + frowstatefont: trowstatefonthandler; + frowstatefoldlevel: trowstatefoldlevelhandler; + frowstatehidden: trowstatehiddenhandler; + frowstatefoldissum: trowstatefoldissumhandler; + fonrowsinserting: ifibeforeblockeventty; + fonrowsinserted: ifiafterblockeventty; + fonrowsdeleting: ifibeforeblockeventty; + fonrowsdeleted: ifiafterblockeventty; + procedure setrowcount(const avalue: integer); + procedure setdatacols(const avalue: tifilinkcomparrayprop); + function getrowstate: tcustomrowstatelist; + procedure statreadrowstate(const alink: pointer); + procedure statwriterowstate(const alink: pointer; var handled: boolean); + function getrowstate_color: tifiintegerlinkcomp; + procedure setrowstate_color(const avalue: tifiintegerlinkcomp); + function getrowstate_font: tifiintegerlinkcomp; + procedure setrowstate_font(const avalue: tifiintegerlinkcomp); + function getrowstate_foldlevel: tifiintegerlinkcomp; + procedure setrowstate_foldlevel(const avalue: tifiintegerlinkcomp); + function getrowstate_hidden: tifibooleanlinkcomp; + procedure setrowstate_hidden(const avalue: tifibooleanlinkcomp); + function getrowstate_foldissum: tifibooleanlinkcomp; + procedure setrowstate_foldissum(const avalue: tifibooleanlinkcomp); + protected + fgridstate: gridclientstatesty; + procedure itemchanged(const sender: tdatalist; const aindex: integer); + function getifilinkkind: ptypeinfo; override; + procedure valuestoclient(const alink: pointer); override; + procedure clienttovalues(const alink: pointer); override; + procedure itemappendrow(const alink: pointer); + procedure getrowstate1(const alink: pointer; var handled: boolean); + procedure canclose1(const alink: pointer; var handled: boolean); + + procedure dostatread(const reader: tstatreader); override; + procedure dostatwrite(const writer: tstatwriter); override; + function checkcomponent(const aintf: iifilink): pointer; override; + public + constructor create(const aowner: tmsecomponent); override; + destructor destroy; override; + procedure docellevent(var info: ificelleventinfoty); + procedure dorowsinserting(var index,count: integer; + const userinput: boolean); + procedure dorowsinserted(const index,count: integer; + const userinput: boolean); + procedure dorowsdeleting(var index,count: integer; + const userinput: boolean); + procedure dorowsdeleted(const index,count: integer; + const userinput: boolean); + procedure appendrow(const avalues: array of const; + const checkautoappend: boolean = false); + function canclose: boolean; + function rowempty(const arow: integer): boolean; + property rowstate: tcustomrowstatelist read getrowstate; + published + property rowcount: integer read frowcount write setrowcount default 0; + property oncellevent: ificelleventty read foncellevent write foncellevent; + property onrowsinserting: ifibeforeblockeventty read fonrowsinserting + write fonrowsinserting; + property onrowsinserted: ifiafterblockeventty read fonrowsinserted + write fonrowsinserted; + property onrowsdeleting: ifibeforeblockeventty read fonrowsdeleting + write fonrowsdeleting; + property onrowsdeleted: ifiafterblockeventty read fonrowsdeleted + write fonrowsdeleted; +// property onclientcellevent: celleventty read fclientcellevent +// write fclientcellevent; + property datacols: tifilinkcomparrayprop read fdatacols write setdatacols; +// property rowstate_font: tintegerlinkcomp read frowstate_font +// write setrowstate_font; + property rowstate_color: tifiintegerlinkcomp read getrowstate_color + write setrowstate_color; + property rowstate_font: tifiintegerlinkcomp read getrowstate_font + write setrowstate_font; + property rowstate_foldlevel: tifiintegerlinkcomp read getrowstate_foldlevel + write setrowstate_foldlevel; + property rowstate_hidden: tifibooleanlinkcomp read getrowstate_hidden + write setrowstate_hidden; + property rowstate_foldissum: tifibooleanlinkcomp read getrowstate_foldissum + write setrowstate_foldissum; + end; + + tifilinkcomp = class(tmsecomponent) + private + fcontroller: tcustomificlientcontroller; + protected + procedure setcontroller(const avalue: tcustomificlientcontroller); + function getcontrollerclass: customificlientcontrollerclassty; virtual; + procedure loaded; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property c: tcustomificlientcontroller read fcontroller + write setcontroller; + property controller: tcustomificlientcontroller read fcontroller + write setcontroller; + published + end; + + tifivaluelinkcomp = class(tifilinkcomp) + private + function getcontroller: tvalueclientcontroller; + public + property c: tvalueclientcontroller read getcontroller; + property controller: tvalueclientcontroller read getcontroller; + end; + + tifistringlinkcomp = class(tifivaluelinkcomp) + private + function getcontroller: tstringclientcontroller; + procedure setcontroller(const avalue: tstringclientcontroller); + protected + function getcontrollerclass: customificlientcontrollerclassty; override; + public + property c: tstringclientcontroller read getcontroller + write setcontroller; + published + property controller: tstringclientcontroller read getcontroller + write setcontroller; + end; + + tifidropdownlistlinkcomp = class(tifistringlinkcomp) + private + function getcontroller: tdropdownlistclientcontroller; + procedure setcontroller(const avalue: tdropdownlistclientcontroller); + protected + function getcontrollerclass: customificlientcontrollerclassty; override; + public + property c: tdropdownlistclientcontroller read getcontroller + write setcontroller; + published + property controller: tdropdownlistclientcontroller read getcontroller + write setcontroller; + end; + + tifiintegerlinkcomp = class(tifivaluelinkcomp) + private + function getcontroller: tintegerclientcontroller; + procedure setcontroller(const avalue: tintegerclientcontroller); + protected + function getcontrollerclass: customificlientcontrollerclassty; override; + public + property c: tintegerclientcontroller read getcontroller + write setcontroller; + published + property controller: tintegerclientcontroller read getcontroller + write setcontroller; + end; + + tifiint64linkcomp = class(tifivaluelinkcomp) + private + function getcontroller: tint64clientcontroller; + procedure setcontroller(const avalue: tint64clientcontroller); + protected + function getcontrollerclass: customificlientcontrollerclassty; override; + public + property c: tint64clientcontroller read getcontroller + write setcontroller; + published + property controller: tint64clientcontroller read getcontroller + write setcontroller; + end; + + tifipointerlinkcomp = class(tifivaluelinkcomp) + private + function getcontroller: tpointerclientcontroller; + procedure setcontroller(const avalue: tpointerclientcontroller); + protected + function getcontrollerclass: customificlientcontrollerclassty; override; + public + property c: tpointerclientcontroller read getcontroller + write setcontroller; + published + property controller: tpointerclientcontroller read getcontroller + write setcontroller; + end; + + tifienumlinkcomp = class(tifiintegerlinkcomp) + private + function getcontroller: tenumclientcontroller; + procedure setcontroller(const avalue: tenumclientcontroller); + protected + function getcontrollerclass: customificlientcontrollerclassty; override; + public + property c: tenumclientcontroller read getcontroller + write setcontroller; + published + property controller: tenumclientcontroller read getcontroller + write setcontroller; + end; + + tifibooleanlinkcomp = class(tifivaluelinkcomp) + private + function getcontroller: tbooleanclientcontroller; + procedure setcontroller(const avalue: tbooleanclientcontroller); + protected + function getcontrollerclass: customificlientcontrollerclassty; override; + public + property c: tbooleanclientcontroller read getcontroller + write setcontroller; + published + property controller: tbooleanclientcontroller read getcontroller + write setcontroller; + end; + + tifireallinkcomp = class(tifivaluelinkcomp) + private + function getcontroller: trealclientcontroller; + procedure setcontroller(const avalue: trealclientcontroller); + protected + function getcontrollerclass: customificlientcontrollerclassty; override; + public + property c: trealclientcontroller read getcontroller + write setcontroller; + published + property controller: trealclientcontroller read getcontroller + write setcontroller; + end; + + tifidatetimelinkcomp = class(tifivaluelinkcomp) + private + function getcontroller: tdatetimeclientcontroller; + procedure setcontroller(const avalue: tdatetimeclientcontroller); + protected + function getcontrollerclass: customificlientcontrollerclassty; override; + public + property c: tdatetimeclientcontroller read getcontroller + write setcontroller; + published + property controller: tdatetimeclientcontroller read getcontroller + write setcontroller; + end; + + tifiactionlinkcomp = class(tifilinkcomp) + private + function getcontroller: texecclientcontroller; + procedure setcontroller(const avalue: texecclientcontroller); + protected + function getcontrollerclass: customificlientcontrollerclassty; override; + public + property c: texecclientcontroller read getcontroller + write setcontroller; + published + property controller: texecclientcontroller read getcontroller + write setcontroller; + end; + + tififormlinkcomp = class(tifilinkcomp) + private + function getcontroller: tformclientcontroller; + procedure setcontroller(const avalue: tformclientcontroller); + protected + function getcontrollerclass: customificlientcontrollerclassty; override; + public + property c: tformclientcontroller read getcontroller + write setcontroller; + published + property controller: tformclientcontroller read getcontroller + write setcontroller; + end; + + tifigridlinkcomp = class(tifilinkcomp) + private + function getcontroller: tgridclientcontroller; + procedure setcontroller(const avalue: tgridclientcontroller); + protected + function getcontrollerclass: customificlientcontrollerclassty; override; + public + property c: tgridclientcontroller read getcontroller + write setcontroller; + published + property controller: tgridclientcontroller read getcontroller + write setcontroller; + end; + + iififieldsource = interface(inullinterface)[miid_iififieldsource] + function getfieldnames(const atypes: listdatatypesty): msestringarty; + end; + + iififieldlinksource = interface(inullinterface)[miid_iififieldlinksource] + function getfieldnames(const apropname: ifisourcefieldnamety): msestringarty; + procedure setdesignsourcefieldname(const aname: ifisourcefieldnamety); + end; + + tififield = class(tvirtualpersistent) + private + ffieldname: ansistring; + fdatatype: listdatatypety; + public + published + property fieldname: ansistring read ffieldname write ffieldname; + property datatype: listdatatypety read fdatatype write fdatatype; + end; + ififieldclassty = class of tififield; + + tififields = class(tpersistentarrayprop,iififieldsource) + protected + function getififieldclass: ififieldclassty; virtual; + public + constructor create; +// function destdatalists: datalistarty; + //iififieldsource + class function getitemclasstype: persistentclassty; override; + function getfieldnames(const atypes: listdatatypesty): msestringarty; + end; + + tififieldlinks = class; + + tififieldlink = class(tififield,iififieldlinksource) + private + fsourcefieldname: ifisourcefieldnamety; + protected + fowner: tififieldlinks; + //iififieldlinksource + function getfieldnames( + const appropname: ifisourcefieldnamety): msestringarty; + procedure setdesignsourcefieldname(const aname: ifisourcefieldnamety); + {$ifndef FPC} + function _addref: integer; stdcall; + function _release: integer; stdcall; + function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall; + {$endif} + public + published + property sourcefieldname: ifisourcefieldnamety read fsourcefieldname + write fsourcefieldname; + end; + ififieldlinkclassty = class of tififieldlink; + + tififieldlinks = class(tififields) + protected + function getififieldclass: ififieldlinkclassty; reintroduce; virtual; + procedure createitem(const index: integer; var item: tpersistent); override; + function getfieldnames( + const adatatype: listdatatypety): msestringarty; virtual; + public + function sourcefieldnames: stringarty; + function sourcefieldtype(const afieldname: string): listdatatypety virtual; +end; + + iifidataconnection = interface(inullinterface)[miid_iifidataconnection] + procedure fetchdata(const acolnames: array of string; + acols: array of tdatalist); + function getfieldnames(const adatatype: listdatatypety): msestringarty; + function getdatatype(const aname: ansistring): listdatatypety; + //dl_none if not found + end; + +//{$define usedelegation} not working in FPC 2.4 + tifidatasource = class(tactcomponent,iififieldsource) + private + {$ifdef usedelegation} + ffieldsourceintf: iififieldsource; + {$endif} + fopenafterread: boolean; + + fonbeforeopen: notifyeventty; + fonafteropen: notifyeventty; + findex: integer; + fnamear: stringarty; + flistar: datalistarty; + ftimer: tsimpletimer; + procedure setfields(const avalue: tififields); + {$ifdef usedelegation} + property fieldsurceintf: iififieldsource read ffieldsourceintf + implements iififieldsource; + //not working in FPC 2.4 + {$endif} + procedure getbindinginfo(const alink: pointer); + protected + factive: boolean; + frefreshing: boolean; + ffields: tififields; + procedure setactive(const avalue: boolean); override; + procedure open; virtual; + procedure afteropen; + procedure dorefresh(const sender: tobject); + procedure close; virtual; + procedure loaded; override; + procedure doactivated; override; + procedure dodeactivated; override; + procedure destdatalists(out names: stringarty; out lists: datalistarty); +{$ifndef usedelegation} + //iififieldsource + function getfieldnames(const atypes: listdatatypesty): msestringarty; +{$endif} + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure refresh(const delayus: integer = -1); + //-1 -> no delay, 0 -> in onidle + procedure checkrefresh(); //makes pending delayed refresh + property refreshing: boolean read frefreshing; + published + property fields: tififields read ffields write setfields; + property active: boolean read factive write setactive default false; + property activator; + property onbeforeopen: notifyeventty read fonbeforeopen write fonbeforeopen; + property onafteropen: notifyeventty read fonafteropen write fonafteropen; + end; + + tconnectedifidatasource = class; + tificonnectedfields = class(tififieldlinks) + protected + fowner: tconnectedifidatasource; + function getfieldnames( + const adatatype: listdatatypety): msestringarty; override; + public + constructor create(const aowner: tconnectedifidatasource); + function sourcefieldtype(const afieldname: string): listdatatypety override; + end; + + tconnectedifidatasource = class(tifidatasource) + private + fconnection: tmsecomponent; + procedure setconnection(const avalue: tmsecomponent); + function getfields: tificonnectedfields; + procedure setfields(const avalue: tificonnectedfields); + protected + fconnectionintf: iifidataconnection; + function getfieldnames(const adatatype: listdatatypety): msestringarty; + procedure open; override; + procedure close; override; + procedure checkconnection; + public + constructor create(aowner: tcomponent); override; + published + property connection: tmsecomponent read fconnection write setconnection; + property fields: tificonnectedfields read getfields write setfields; + end; + + tifiintegerdatalist = class(tintegerdatalist) + protected + fowner: tintegerclientcontroller; + function getdefault: pointer; override; + public + constructor create(const aowner: tintegerclientcontroller); reintroduce; + end; + + tifiint64datalist = class(tint64datalist) + protected + fowner: tint64clientcontroller; + function getdefault: pointer; override; + public + constructor create(const aowner: tint64clientcontroller); reintroduce; + end; + + tifipointerdatalist = class(tpointerdatalist) + protected + fowner: tpointerclientcontroller; + public + constructor create(const aowner: tpointerclientcontroller); reintroduce; + end; + + tifibooleandatalist = class(tbooleandatalist) + private + protected + fowner: tbooleanclientcontroller; + function getdefault: pointer; override; + public + constructor create(const aowner: tbooleanclientcontroller); reintroduce; + end; + + tifirealdatalist = class(trealdatalist) + protected + fowner: trealclientcontroller; + function getdefault: pointer; override; + public + constructor create(const aowner: trealclientcontroller); reintroduce; + end; + + tifidatetimedatalist = class(tdatetimedatalist) + protected + fowner: tdatetimeclientcontroller; + function getdefault: pointer; override; + public + constructor create(const aowner: tdatetimeclientcontroller); reintroduce; + end; + + tifimsestringdatalist = class(tmsestringdatalist) + protected + fowner: tstringclientcontroller; + function getdefault: pointer; override; + public + constructor create(const aowner: tstringclientcontroller); reintroduce; + end; + +procedure setifilinkcomp(const alink: iifilink; + const alinkcomp: tifilinkcomp; var dest: tifilinkcomp); +procedure setifidatasource(const aintf: iifidatasourceclient; + const source: tifidatasource; var dest: tifidatasource); + +implementation +uses + sysutils,msereal,msestreaming; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + valuevarname = '_value'; + listvarname = '_list'; +// arvaluevarname = 'arvalue'; + rowstatevarname = '_rowstate'; + +type + tmsecomponent1 = class(tmsecomponent); + tdatalist1 = class(tdatalist); + +procedure setifilinkcomp(const alink: iifilink; + const alinkcomp: tifilinkcomp; var dest: tifilinkcomp); +var + po1: pointer; +begin + alink.setifiserverintf(nil); + po1:= nil; + if alinkcomp <> nil then begin + po1:= alinkcomp.fcontroller.checkcomponent(alink); + end; + alink.getobjectlinker.setlinkedvar(alink,alinkcomp,tmsecomponent(dest),po1); + if dest <> nil then begin + alink.setifiserverintf(iifidataserver(dest.fcontroller)); + if (alinkcomp is tifivaluelinkcomp) and + not (csloading in alinkcomp.componentstate) and + (vco_datalist in + tifivaluelinkcomp(alinkcomp).controller.optionsvalue) then begin + iifidatalink(alink).updateifigriddata(alinkcomp, + tifivaluelinkcomp(alinkcomp).controller.fdatalist); + end; + dest.fcontroller.linkset(alink); +// dest.fcontroller.change(alink); + end; +end; + +procedure setifidatasource(const aintf: iifidatasourceclient; + const source: tifidatasource; var dest: tifidatasource); +begin + aintf.getobjectlinker.setlinkedvar(aintf,source,tmsecomponent(dest), + typeinfo(iifidatasourceclient)); + aintf.bindingchanged; +end; + +{ tcustomificlientcontroller} + +constructor tcustomificlientcontroller.create(const aowner: tmsecomponent; + const akind: ttypekind); +begin + fowner:= aowner; + fkind:= akind; + inherited create; +end; + +constructor tcustomificlientcontroller.create(const aowner: tmsecomponent); +begin + create(aowner,tkunknown); +end; + +procedure tcustomificlientcontroller.interfaceerror; +begin + raise exception.create(fowner.name+' wrong iificlient interface.'); + //todo: better error message +end; + +function tcustomificlientcontroller.checkcomponent( + const aintf: iifilink): pointer; +begin + if not isinterface(aintf.getifilinkkind,getifilinkkind) then begin + interfaceerror; + end; + result:= self; +end; + +{ +procedure tcustomifivaluewidgetcontroller.setcomponent(const aintf: iificlient); +var + kind1: ttypekind; + prop1: ppropinfo; + inst1: tobject; +begin + if not (ivs_linking in fstate) then begin + include(fstate,ivs_linking); + try + prop1:= nil; + kind1:= tkunknown; + if aintf <> nil then begin + inst1:= aintf.getinstance; + prop1:= getpropinfo(inst1,'value'); + if prop1 = nil then begin + raise exception.create(errorname(inst1)+' has no value property.'); + end + else begin + kind1:= prop1^.proptype^.kind; + if kind1 <> fkind then begin + raise exception.create(errorname(inst1)+' wrong value data kind.'); + end; + end; + end; + if fintf <> nil then begin + fintf.setifiserverintf(nil); + end; + setlinkedvar(aintf,iobjectlink(fintf)); + fintf:= aintf; + fvalueproperty:= prop1; + if fintf <> nil then begin + fintf.setifiserverintf(iifiserver(self)); + valuetowidget; +// if not (csloading in fowner.componentstate) then begin +// updatestate; +// end; + end; + finally + exclude(fstate,ivs_linking); + end; + end; +end; +} +procedure tcustomificlientcontroller.distribute(const sender: iificlient; + const local: boolean; const exec: boolean); +begin + if not (ivs_valuesetting in fstate) and + not(csloading in fowner.componentstate) then begin + include(fstate,ivs_valuesetting); + try + if assigned(fonchangebefore) then begin + fonchangebefore(self); + end; + if local then begin + if not (vco_novaluetoclient in foptionsvalue) then begin + if sender <> nil then begin + valuestoclient(pointer(sender)); + end + else begin + tmsecomponent1(fowner).getobjectlinker.forall( + {$ifdef FPC}@{$endif}valuestoclient,self); + end; + end; + end + else begin + clienttovalues(pointer(sender)); + if foptionsvalue*[vco_nosync,vco_datalist] = [] then begin + fchangedclient:= pointer(sender); + tmsecomponent1(fowner).getobjectlinker.forall( + {$ifdef FPC}@{$endif}valuestootherclient,self); + end; + end; + if assigned(fonchangeafter) then begin + fonchangeafter(self); + end; + if not local then begin + if exec then begin + if assigned(fonclientexecute) then begin + fonclientexecute(self,sender); + end; + end + else begin + if assigned(fonclientvaluechanged) then begin + fonclientvaluechanged(self,sender); + end; + end; + end; + finally + exclude(fstate,ivs_valuesetting); + end; + end; +end; + +procedure tcustomificlientcontroller.change(const alink: iificlient); +begin + distribute(alink,true,false); +end; +(* +procedure tcustomificlientcontroller.change(const alink: iificlient); +begin + if {(fvalueproperty <> nil) and} not (ivs_valuesetting in fstate) and + not (csloading in fowner.componentstate) then begin + include(fstate,ivs_valuesetting); + try + if assigned(fonchangebefore) then begin + fonchangebefore(self); + end; + if not (vco_novaluetoclient in foptionsvalue) then begin + if alink <> nil then begin + valuestoclient(pointer(alink)); + end + else begin + tmsecomponent1(fowner).getobjectlinker.forall( + {$ifdef FPC}@{$endif}valuestoclient,self); + end; + end; + if assigned(fonchangeafter) then begin + fonchangeafter(self); + end; + finally + exclude(fstate,ivs_valuesetting); + end; + end; +end; +*) +procedure tcustomificlientcontroller.valuechanged(const sender: iifidatalink); +begin + distribute(sender,false,false); +// dovaluechanged(sender,false); +end; + +procedure tcustomificlientcontroller.execute(const sender: iificlient); +begin + distribute(sender,false,true); +{ + if fowner.canevent(tmethod(fonclientexecute)) then begin + fonclientexecute(self,sender); + end; +} +end; + + +procedure tcustomificlientcontroller.statechanged(const sender: iificlient; + const astate: ifiwidgetstatesty); +begin + fwidgetstate:= astate; + if fowner.canevent(tmethod(fonclientstatechanged)) then begin + fonclientstatechanged(self,sender,astate, + ifiwidgetstatesty({$ifdef FPC}longword{$else}byte{$endif}(astate) xor + {$ifdef FPC}longword{$else}byte{$endif}(fwidgetstatebefore))); + fwidgetstatebefore:= astate; + end; +end; + +procedure tcustomificlientcontroller.closequery(const sender: iificlient; + var amodalresult: modalresultty); +begin + if fowner.canevent(tmethod(fonclientclosequery)) then begin + fonclientclosequery(self,sender,amodalresult); + end; +end; + + +procedure tcustomificlientcontroller.sendmodalresult(const sender: iificlient; + const amodalresult: modalresultty); +begin + if fowner.canevent(tmethod(fonclientmodalresult)) then begin + fonclientmodalresult(self,sender,amodalresult); + end; +end; +{ +procedure tcustomifivaluewidgetcontroller.widgettovalue; +begin + //dummy +end; +} + +procedure tcustomificlientcontroller.valuestoclient(const alink: pointer); +var + obj: tobject; +begin + if not (ivs_loadedproc in fstate) and + (fowner.componentstate * [csdesigning,csloading,csdestroying] = + [csdesigning]) then begin + obj:= iobjectlink(alink).getinstance; + if (obj is tcomponent) and (tcomponent(obj).owner <> fowner.owner) then begin + designchanged(tcomponent(obj)); + end; + end; +end; + +procedure tcustomificlientcontroller.valuestootherclient(const alink: pointer); +begin + if alink <> fchangedclient then begin + valuestoclient(alink); + end; +end; + +procedure tcustomificlientcontroller.clienttovalues(const alink: pointer); +begin + //dummy +end; + +{ +function tcustomifivaluewidgetcontroller.getclientinstance: tobject; +begin + result:= nil; + if fintf <> nil then begin + result:= fintf.getinstance; + end; +end; +} +{ +function tcustomifivaluewidgetcontroller.getwidget: twidget; +begin + result:= twidget(fcomponent); +end; + +procedure tcustomifivaluewidgetcontroller.setwidget(const avalue: twidget); +var + intf1: iifilink; +begin + intf1:= nil; + if (avalue <> nil) and + not getcorbainterface(avalue,typeinfo(iifilink),intf1) then begin + raise exception.create(avalue.name + ' is no IfI data widget.'); + end; + setcomponent(avalue,intf1); +end; +} +procedure tcustomificlientcontroller.linkset(const alink: iificlient); +begin + fwidgetstatebefore:= []; + change(alink); +end; + +procedure tcustomificlientcontroller.finalizelink(const alink: pointer); +begin + iificlient(alink).setifiserverintf(nil); +end; + +procedure tcustomificlientcontroller.finalizelinks; +begin + if tmsecomponent1(fowner).fobjectlinker <> nil then begin + tmsecomponent1(fowner).fobjectlinker.forall({$ifdef FPC}@{$endif}finalizelink,self); + end; +end; + +procedure tcustomificlientcontroller.setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); +begin + //dummy +end; + +procedure tcustomificlientcontroller.dataentered(const sender: iificlient; + const arow: integer); +begin + //dummy +end; + +function tcustomificlientcontroller.canconnect( + const acomponent: tcomponent): boolean; +var + po1: pointer; +begin +// result:= getcorbainterface(acomponent,typeinfo(iifilink),po1); + result:= getcorbainterface(acomponent,getifilinkkind(),po1); +end; + +function tcustomificlientcontroller.errorname(const ainstance: tobject): string; +begin + if ainstance = nil then begin + result:= 'NIL'; + end + else begin + if ainstance is tcomponent then begin + result:= tcomponent(ainstance).name; + end + else begin + result:= ainstance.classname; + end; + end; +end; + +function tcustomificlientcontroller.setmsestringval(const alink: iificlient; + const aname: string; const avalue: msestring): boolean; +var + inst: tobject; + prop: ppropinfo; + +begin + inst:= alink.getinstance; + prop:= getpropinfo(inst,aname); + result:= (prop <> nil) and (prop^.proptype^.kind = msestringtypekind); + if result then begin + setmsestringprop(inst,prop,avalue); + end; +end; + +function tcustomificlientcontroller.getmsestringval( + const alink: iificlient; const aname: string; + var avalue: msestring): boolean; + //true if found +var + inst: tobject; + prop: ppropinfo; + +begin + inst:= alink.getinstance; + prop:= getpropinfo(inst,aname); + result:= (prop <> nil) and (prop^.proptype^.kind = msestringtypekind); + if result then begin + avalue:= getmsestringprop(inst,prop); + end; +end; + +function tcustomificlientcontroller.setintegerval(const alink: iificlient; + const aname: string; const avalue: integer): boolean; +var + inst: tobject; + prop: ppropinfo; + +begin + inst:= alink.getinstance; + prop:= getpropinfo(inst,aname); + result:= (prop <> nil) and (prop^.proptype^.kind = tkinteger); + if result then begin + setordprop(inst,prop,avalue); + end; +end; + +function tcustomificlientcontroller.getintegerval( + const alink: iificlient; const aname: string; + var avalue: integer): boolean; + //true if found +var + inst: tobject; + prop: ppropinfo; + +begin + inst:= alink.getinstance; + prop:= getpropinfo(inst,aname); + result:= (prop <> nil) and (prop^.proptype^.kind = tkinteger); + if result then begin + avalue:= getordprop(inst,prop); + end; +end; + +function tcustomificlientcontroller.setint64val(const alink: iificlient; + const aname: string; const avalue: int64): boolean; +var + inst: tobject; + prop: ppropinfo; + +begin + inst:= alink.getinstance; + prop:= getpropinfo(inst,aname); + result:= (prop <> nil) and (prop^.proptype^.kind = tkint64); + if result then begin + setordprop(inst,prop,avalue); + end; +end; + +function tcustomificlientcontroller.getint64val( + const alink: iificlient; const aname: string; + var avalue: int64): boolean; + //true if found +var + inst: tobject; + prop: ppropinfo; + +begin + inst:= alink.getinstance; + prop:= getpropinfo(inst,aname); + result:= (prop <> nil) and (prop^.proptype^.kind = tkint64); + if result then begin + avalue:= getordprop(inst,prop); + end; +end; + +function tcustomificlientcontroller.setpointerval(const alink: iifidatalink; + const aname: string; const avalue: pointer): boolean; +var + inst: tobject; + prop: ppropinfo; +begin + inst:= alink.getinstance; + prop:= getpropinfo(inst,aname); + result:= (prop <> nil) and (prop^.proptype^.kind = tkint64); + if result then begin + setordprop(inst,prop,ptrint(avalue)); + end + else begin + alink.setifivalue(avalue); + end; +end; + +function tcustomificlientcontroller.getpointerval(const alink: iifidatalink; + const aname: string; var avalue: pointer): boolean; +var + inst: tobject; + prop: ppropinfo; + +begin + inst:= alink.getinstance; + prop:= getpropinfo(inst,aname); + result:= (prop <> nil) and + {$ifdef mse_hastkpointer} + (prop^.proptype^.kind = tkpointer) + {$else} + (prop^.proptype^.kind = + {$ifdef cpu64}tkint64{$else}tkinteger{$endif}) + {$endif} + ; + if result then begin + avalue:= pointer(ptrint(getordprop(inst,prop))); + end + else begin + alink.getifivalue(avalue); + end; +end; + +function tcustomificlientcontroller.setbooleanval(const alink: iificlient; + const aname: string; const avalue: boolean): boolean; +var + inst: tobject; + prop: ppropinfo; + +begin + inst:= alink.getinstance; + prop:= getpropinfo(inst,aname); + result:= (prop <> nil) and (prop^.proptype^.kind in boolprops); + if result then begin + setordprop(inst,prop,ord(avalue)); + end; +end; + +function tcustomificlientcontroller.getbooleanval( + const alink: iificlient; const aname: string; + var avalue: boolean): boolean; + //true if found +var + inst: tobject; + prop: ppropinfo; + +begin + inst:= alink.getinstance; + prop:= getpropinfo(inst,aname); + result:= (prop <> nil) and (prop^.proptype^.kind in boolprops); + if result then begin + avalue:= getordprop(inst,prop) <> 0; + end; +end; + +function tcustomificlientcontroller.setrealtyval(const alink: iificlient; + const aname: string; const avalue: realty): boolean; +var + inst: tobject; + prop: ppropinfo; + +begin + inst:= alink.getinstance; + prop:= getpropinfo(inst,aname); + result:= (prop <> nil) and (prop^.proptype^.kind = tkfloat); + if result then begin + setfloatprop(inst,prop,avalue); + end; +end; + +function tcustomificlientcontroller.getrealtyval( + const alink: iificlient; const aname: string; + var avalue: realty): boolean; + //true if found +var + inst: tobject; + prop: ppropinfo; + +begin + inst:= alink.getinstance; + prop:= getpropinfo(inst,aname); + result:= (prop <> nil) and (prop^.proptype^.kind = tkfloat); + if result then begin + avalue:= getfloatprop(inst,prop); + end; +end; + +function tcustomificlientcontroller.setdatetimeval(const alink: iificlient; + const aname: string; const avalue: tdatetime): boolean; +var + inst: tobject; + prop: ppropinfo; + +begin + inst:= alink.getinstance; + prop:= getpropinfo(inst,aname); + result:= (prop <> nil) and (prop^.proptype^.kind = tkfloat); + if result then begin + setfloatprop(inst,prop,avalue); + end; +end; + +function tcustomificlientcontroller.getdatetimeval( + const alink: iificlient; const aname: string; + var avalue: tdatetime): boolean; + //true if found +var + inst: tobject; + prop: ppropinfo; + +begin + inst:= alink.getinstance; + prop:= getpropinfo(inst,aname); + result:= (prop <> nil) and (prop^.proptype^.kind = tkfloat); + if result then begin + avalue:= getfloatprop(inst,prop); + end; +end; + +procedure tcustomificlientcontroller.loaded; +begin + include(fstate,ivs_loadedproc); + try + change; + finally + exclude(fstate,ivs_loadedproc); + end; +end; + +procedure tcustomificlientcontroller.dogetprop(const alink: pointer); +begin + case fapropkind of + tkinteger: begin + getintegerval(iificlient(alink),fapropname,pinteger(fapropvalue)^); + end; + tkint64: begin + getint64val(iificlient(alink),fapropname,pint64(fapropvalue)^); + end; + {$ifdef FPC}tkbool{$else}tkenumeration{$endif}: begin + getbooleanval(iificlient(alink),fapropname,pboolean(fapropvalue)^); + end; + tkfloat: begin + getrealtyval(iificlient(alink),fapropname,prealty(fapropvalue)^); + end; + msestringtypekind: begin + getmsestringval(iificlient(alink),fapropname,pmsestring(fapropvalue)^); + end; + end; +end; + +procedure tcustomificlientcontroller.getprop(const aname: string; + const akind: ttypekind; const avaluepo: pointer); +begin + fapropname:= aname; + fapropkind:= akind; + fapropvalue:= avaluepo; + tmsecomponent1(fowner).getobjectlinker.forall({$ifdef FPC}@{$endif}dogetprop,self); +end; + +procedure tcustomificlientcontroller.dosetprop(const alink: pointer); +begin + case fapropkind of + tkinteger: begin + setintegerval(iificlient(alink),fapropname,pinteger(fapropvalue)^); + end; + tkint64: begin + setint64val(iificlient(alink),fapropname,pint64(fapropvalue)^); + end; + {$ifdef FPC}tkbool{$else}tkenumeration{$endif}: begin + setbooleanval(iificlient(alink),fapropname,pboolean(fapropvalue)^); + end; + tkfloat: begin + setrealtyval(iificlient(alink),fapropname,prealty(fapropvalue)^); + end; + msestringtypekind: begin + setmsestringval(iificlient(alink),fapropname,pmsestring(fapropvalue)^); + end; + end; +end; + +procedure tcustomificlientcontroller.setprop(const aname: string; + const akind: ttypekind; const avaluepo: pointer); +begin + fapropname:= aname; + fapropkind:= akind; + fapropvalue:= avaluepo; + tmsecomponent1(fowner).getobjectlinker.forall({$ifdef FPC}@{$endif}dosetprop,self); +end; + +function tcustomificlientcontroller.getintegerpro(const aname: string): integer; +begin + result:= 0; + getprop(aname,tkinteger,@result); +end; + +procedure tcustomificlientcontroller.setintegerpro(const aname: string; + const avalue: integer); +begin + setprop(aname,tkinteger,@avalue); +end; + +function tcustomificlientcontroller.getmsestringpro(const aname: string): msestring; +begin + result:= ''; + getprop(aname,msestringtypekind,@result); +end; + +procedure tcustomificlientcontroller.setmsestringpro(const aname: string; + const avalue: msestring); +begin + setprop(aname,msestringtypekind,@avalue); +end; + +function tcustomificlientcontroller.getbooleanpro(const aname: string): boolean; +begin + result:= false; + getprop(aname,{$ifdef FPC}tkbool{$else}tkenumeration{$endif},@result); +end; + +procedure tcustomificlientcontroller.setbooleanpro(const aname: string; + const avalue: boolean); +begin + setprop(aname,{$ifdef FPC}tkbool{$else}tkenumeration{$endif},@avalue); +end; + +function tcustomificlientcontroller.getrealtypro(const aname: string): realty; +begin + result:= emptyreal; + getprop(aname,tkfloat,@result); +end; + +procedure tcustomificlientcontroller.setrealtypro(const aname: string; + const avalue: realty); +begin + setprop(aname,tkfloat,@avalue); +end; + +function tcustomificlientcontroller.getdatetimepro(const aname: string): tdatetime; +begin + result:= emptydatetime; + getprop(aname,tkfloat,@result); +end; + +procedure tcustomificlientcontroller.setdatetimepro(const aname: string; + const avalue: tdatetime); +begin + setprop(aname,tkfloat,@avalue); +end; + +function tcustomificlientcontroller.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iifilink); +end; + +procedure tcustomificlientcontroller.setstatfile(const avalue: tstatfile); +begin + setstatfilevar(istatfile(self),avalue,fstatfile); +end; + +procedure tcustomificlientcontroller.dostatread(const reader: tstatreader); +begin + //dummy +end; + +procedure tcustomificlientcontroller.dostatwrite(const writer: tstatwriter); +begin + //dummy +end; + +procedure tcustomificlientcontroller.statreading; +begin + //dummy +end; + +procedure tcustomificlientcontroller.statread; +begin + //dummy +end; + +function tcustomificlientcontroller.getstatvarname: msestring; +begin + if fstatvarname = '' then begin + result:= msestring(ownernamepath(fowner)); + if result = '' then begin + result:= '.'; //dummy, statfiler can not get componentname because + //self is no tcomponent + end; + end + else begin + result:= fstatvarname; + end; +end; + +procedure tcustomificlientcontroller.updateoptionsedit(var avalue: optionseditty); +begin + //dummy +end; + +function tcustomificlientcontroller.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +{ tifilinkcomp } + +constructor tifilinkcomp.create(aowner: tcomponent); +begin + fcontroller:= getcontrollerclass.create(self); + inherited; +end; + +destructor tifilinkcomp.destroy; +begin + fcontroller.finalizelinks; + inherited; + fcontroller.free; +end; + +procedure tifilinkcomp.setcontroller(const avalue: tcustomificlientcontroller); +begin + fcontroller.assign(avalue); +end; + +function tifilinkcomp.getcontrollerclass: customificlientcontrollerclassty; +begin + result:= tificlientcontroller; +end; + +procedure tifilinkcomp.loaded; +begin + inherited; + fcontroller.loaded; +end; + +{ tvalueclientcontroller } + +destructor tvalueclientcontroller.destroy; +begin + freeandnil(fdatalist); + inherited; +end; + +function tvalueclientcontroller.canconnect(const acomponent: tcomponent): boolean; +var + prop1: ppropinfo; +begin + result:= inherited canconnect(acomponent); + if result then begin + prop1:= getpropinfo(acomponent,'value'); + result:= (prop1 <> nil) and (prop1^.proptype^.kind = fkind); + end; +end; + +function tvalueclientcontroller.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iifidatalink); +end; +{ +procedure tvalueclientcontroller.getdatalist1(const alink: pointer; + var handled: boolean); +var + datalist1: tdatalist; +begin + datalist1:= iifidatalink(alink).ifigriddata; + if datalist1 <> nil then begin + pdatalist(fitempo)^:= datalist1; + handled:= true; + end; +end; + +function tvalueclientcontroller.getfirstdatalist1: tdatalist; +begin + result:= fdatalist; + if result = nil then begin + fitempo:= @result; + tmsecomponent1(fowner).getobjectlinker.forfirst(@getdatalist1, + self); + if result = nil then begin + raise exception.create('No datalist.'); + end; + end; +end; + +function tvalueclientcontroller.getfirstdatalist: tdatalist; +begin + result:= getfirstdatalist1; + if result = nil then begin + raise exception.create('No datalist.'); + end; +end; +} +{ +procedure tvalueclientcontroller.setmsestringvalar(const alink: pointer; + var handled: boolean); +//var +// datalist: tdatalist; +begin +// datalist:= iifidatalink(alink).ifigriddata; + if datalist is tmsestringdatalist then begin + tmsestringdatalist(datalist).asarray:= pmsestringarty(fvalarpo)^; + handled:= true; + end; +end; + +procedure tvalueclientcontroller.getmsestringvalar(const alink: pointer; + var handled: boolean); +var + datalist: tdatalist; +begin + datalist:= iifidatalink(alink).ifigriddata; + if datalist is tmsestringdatalist then begin + pmsestringarty(fvalarpo)^:= tmsestringdatalist(datalist).asarray; + handled:= true; + end; +end; + +procedure tvalueclientcontroller.setintegervalar(const alink: pointer; + var handled: boolean); +var + datalist: tdatalist; +begin + datalist:= iifidatalink(alink).ifigriddata; + if datalist is tintegerdatalist then begin + tintegerdatalist(datalist).asarray:= pintegerarty(fvalarpo)^; + handled:= true; + end; +end; + +procedure tvalueclientcontroller.getintegervalar(const alink: pointer; + var handled: boolean); +var + datalist: tdatalist; +begin + datalist:= iifidatalink(alink).ifigriddata; + if datalist is tintegerdatalist then begin + pintegerarty(fvalarpo)^:= tintegerdatalist(datalist).asarray; + handled:= true; + end; +end; + +procedure tvalueclientcontroller.setrealtyvalar(const alink: pointer; + var handled: boolean); +var + datalist: tdatalist; +begin + datalist:= iifidatalink(alink).ifigriddata; + if datalist is trealdatalist then begin + trealdatalist(datalist).asarray:= prealarty(fvalarpo)^; + handled:= true; + end; +end; + +procedure tvalueclientcontroller.getrealtyvalar(const alink: pointer; + var handled: boolean); +var + datalist: tdatalist; +begin + datalist:= iifidatalink(alink).ifigriddata; + if datalist is trealdatalist then begin + prealarty(fvalarpo)^:= trealdatalist(datalist).asarray; + handled:= true; + end; +end; + +procedure tvalueclientcontroller.setdatetimevalar(const alink: pointer; + var handled: boolean); +var + datalist: tdatalist; +begin + datalist:= iifidatalink(alink).ifigriddata; + if datalist is trealdatalist then begin + trealdatalist(datalist).asarray:= pdatetimearty(fvalarpo)^; + handled:= true; + end; +end; + +procedure tvalueclientcontroller.getdatetimevalar(const alink: pointer; + var handled: boolean); +var + datalist: tdatalist; +begin + datalist:= iifidatalink(alink).ifigriddata; + if datalist is trealdatalist then begin + prealarty(fvalarpo)^:= trealdatalist(datalist).asarray; + handled:= true; + end; +end; + +procedure tvalueclientcontroller.setbooleanvalar(const alink: pointer; + var handled: boolean); +var + datalist: tdatalist; +begin + datalist:= iifidatalink(alink).ifigriddata; + if datalist is tintegerdatalist then begin + tintegerdatalist(datalist).asarray:= pintegerarty(fvalarpo)^; + handled:= true; + end; +end; + +procedure tvalueclientcontroller.getbooleanvalar(const alink: pointer; + var handled: boolean); +var + datalist: tdatalist; +begin + datalist:= iifidatalink(alink).ifigriddata; + if datalist is tintegerdatalist then begin + pintegerarty(fvalarpo)^:= tintegerdatalist(datalist).asarray; + handled:= true; + end; +end; + +procedure tvalueclientcontroller.getvalar(const agetter: valargetterty; + var avalue); +begin + fvalarpo:= @avalue; + tmsecomponent1(fowner).getobjectlinker.forfirst(agetter,self); +end; + +procedure tvalueclientcontroller.setvalar(const asetter: valarsetterty; + const avalue); +begin + fvalarpo:= @avalue; + tmsecomponent1(fowner).getobjectlinker.forfirst(asetter,self); +end; + +procedure tvalueclientcontroller.setmsestringitem(const alink: pointer; + var handled: boolean); +var + datalist: tdatalist; + int1: integer; +begin + datalist:= iifidatalink(alink).ifigriddata; + if datalist is tmsestringdatalist then begin + int1:= fitemindex; + if int1 = maxint then begin + int1:= datalist.count - 1; + end; + tmsestringdatalist(datalist)[int1]:= pmsestring(fitempo)^; + handled:= true; + end; +end; + +procedure tvalueclientcontroller.getmsestringitem(const alink: pointer; + var handled: boolean); +var + datalist: tdatalist; +begin + datalist:= iifidatalink(alink).ifigriddata; + if datalist is tmsestringdatalist then begin + pmsestring(fitempo)^:= tmsestringdatalist(datalist)[fitemindex]; + handled:= true; + end; +end; + +procedure tvalueclientcontroller.setintegeritem(const alink: pointer; + var handled: boolean); +var + datalist: tdatalist; + int1: integer; +begin + datalist:= iifidatalink(alink).ifigriddata; + if datalist is tintegerdatalist then begin + int1:= fitemindex; + if int1 = maxint then begin + int1:= datalist.count - 1; + end; + tintegerdatalist(datalist)[int1]:= pinteger(fitempo)^; + handled:= true; + end; +end; + +procedure tvalueclientcontroller.getintegeritem(const alink: pointer; + var handled: boolean); +var + datalist: tdatalist; +begin + datalist:= iifidatalink(alink).ifigriddata; + if datalist is tintegerdatalist then begin + pinteger(fitempo)^:= tintegerdatalist(datalist)[fitemindex]; + handled:= true; + end; +end; + +procedure tvalueclientcontroller.setrealtyitem(const alink: pointer; + var handled: boolean); +var + datalist: tdatalist; + int1: integer; +begin + datalist:= iifidatalink(alink).ifigriddata; + if datalist is trealdatalist then begin + int1:= fitemindex; + if int1 = maxint then begin + int1:= datalist.count - 1; + end; + trealdatalist(datalist)[int1]:= prealty(fitempo)^; + handled:= true; + end; +end; + +procedure tvalueclientcontroller.getrealtyitem(const alink: pointer; + var handled: boolean); +var + datalist: tdatalist; +begin + datalist:= iifidatalink(alink).ifigriddata; + if datalist is trealdatalist then begin + prealty(fitempo)^:= trealdatalist(datalist)[fitemindex]; + handled:= true; + end; +end; + +procedure tvalueclientcontroller.setdatetimeitem(const alink: pointer; + var handled: boolean); +var + datalist: tdatalist; + int1: integer; +begin + datalist:= iifidatalink(alink).ifigriddata; + if datalist is trealdatalist then begin + int1:= fitemindex; + if int1 = maxint then begin + int1:= datalist.count - 1; + end; + trealdatalist(datalist)[int1]:= pdatetime(fitempo)^; + handled:= true; + end; +end; + +procedure tvalueclientcontroller.getdatetimeitem(const alink: pointer; + var handled: boolean); +var + datalist: tdatalist; +begin + datalist:= iifidatalink(alink).ifigriddata; + if datalist is trealdatalist then begin + pdatetime(fitempo)^:= trealdatalist(datalist)[fitemindex]; + handled:= true; + end; +end; + +procedure tvalueclientcontroller.setbooleanitem(const alink: pointer; + var handled: boolean); +var + datalist: tdatalist; + int1: integer; +begin + datalist:= iifidatalink(alink).ifigriddata; + if datalist is tintegerdatalist then begin + int1:= fitemindex; + if int1 = maxint then begin + int1:= datalist.count - 1; + end; + if pinteger(fitempo)^ = 0 then begin + tintegerdatalist(datalist)[int1]:= longint(longbool(false)); + end + else begin + tintegerdatalist(datalist)[int1]:= longint(longbool(true)); + end; + handled:= true; + end; +end; + +procedure tvalueclientcontroller.getbooleanitem(const alink: pointer; + var handled: boolean); +var + datalist: tdatalist; +begin + datalist:= iifidatalink(alink).ifigriddata; + if datalist is tintegerdatalist then begin + pintegerarty(fitempo)^:= tintegerdatalist(datalist).asarray; + handled:= true + end; +end; + +procedure tvalueclientcontroller.getitem(const index: integer; + const agetter: itemgetterty; var avalue); +begin + fitempo:= @avalue; + fitemindex:= index; + tmsecomponent1(fowner).getobjectlinker.forfirst(agetter,self); +end; + +procedure tvalueclientcontroller.setitem(const index: integer; + const asetter: itemsetterty; const avalue); +begin + fitempo:= @avalue; + fitemindex:= index; + tmsecomponent1(fowner).getobjectlinker.forfirst(asetter,self); +end; +} +procedure tvalueclientcontroller.statreadlist(const alink: pointer); +//var +// datalist: tdatalist; +begin +// datalist:= iifidatalink(alink).ifigriddata; + if datalist <> nil then begin + tstatreader(fitempo).readdatalist(getstatvarname,datalist); + end; +end; + +procedure tvalueclientcontroller.statwritelist(const alink: pointer; + var handled: boolean); +//var +// datalist: tdatalist; +begin +// datalist:= iifidatalink(alink).ifigriddata; + if datalist <> nil then begin + tstatwriter(fitempo).writedatalist(getstatvarname,datalist); + handled:= true; + end; +end; + +procedure tvalueclientcontroller.setvalue(const sender: iificlient; var avalue; + var accept: boolean; const arow: integer); +begin + inherited; +// if accept and fowner.canevent(tmethod(fonclientdataentered)) then begin +// fonclientdataentered(fowner,arow); +// end; +end; + +procedure tvalueclientcontroller.dataentered(const sender: iificlient; + const arow: integer); +begin + inherited; + if fowner.canevent(tmethod(fonclientdataentered)) then begin + fonclientdataentered(self,sender,arow); + end; +end; + +procedure tvalueclientcontroller.setoptionsvalue( + const avalue: valueclientoptionsty); +begin + if foptionsvalue <> avalue then begin + foptionsvalue:= avalue; + optionsvaluechanged; + end; +end; + +procedure tvalueclientcontroller.linkdatalist1(const alink: pointer); +begin + iifidatalink(alink).updateifigriddata(fowner,fdatalist); +end; + +procedure tvalueclientcontroller.linkdatalist; +begin + with tmsecomponent1(fowner) do begin + if fobjectlinker <> nil then begin + fobjectlinker.forall({$ifdef FPC}@{$endif}self.linkdatalist1,self); + end; + end; +end; + +procedure tvalueclientcontroller.updatereadonlystate1(const alink: pointer); +begin + iifidatalink(alink).updatereadonlystate; +end; + +procedure tvalueclientcontroller.updatereadonlystate; +begin + with tmsecomponent1(fowner) do begin + if fobjectlinker <> nil then begin + fobjectlinker.forall({$ifdef FPC}@{$endif}self.updatereadonlystate1,self); + end; + end; +end; + +procedure tvalueclientcontroller.optionsvaluechanged; +begin + if (vco_datalist in foptionsvalue) xor (fdatalist <> nil) then begin + if vco_datalist in foptionsvalue then begin + fdatalist:= createdatalist; + if fdatalist <> nil then begin + include(tdatalist1(fdatalist).fstate,dls_remote); + if not (csloading in fowner.componentstate) then begin + linkdatalist; + end; + end; + end + else begin + freeandnil(fdatalist); + end; + end; + if not (csloading in fowner.componentstate) then begin + updatereadonlystate; + end; +end; + +procedure tvalueclientcontroller.loaded; +begin + if fdatalist <> nil then begin + linkdatalist; + end; + updatereadonlystate; + inherited; +end; + +procedure tvalueclientcontroller.setdatasource(const avalue: tifidatasource); +begin + if avalue <> fdatasource then begin + setifidatasource(iifidatasourceclient(self),avalue,fdatasource); + end; +end; + +procedure tvalueclientcontroller.setfieldname(const avalue: ififieldnamety); +begin + if avalue <> ffieldname then begin + ffieldname:= avalue; + bindingchanged; + end; +end; + +procedure tvalueclientcontroller.bindingchanged; +begin +end; + +function tvalueclientcontroller.ifigriddata: tdatalist; +begin + result:= fdatalist; + if result = nil then begin + componentexception(fowner,'No datalist, activate optionsvalue vco_datalist.'); + end; +end; + +function tvalueclientcontroller.ififieldname: string; +begin + result:= ffieldname; +end; + +procedure tvalueclientcontroller.getfieldinfo(const apropname: ififieldnamety; + var adatasource: tifidatasource; var atypes: listdatatypesty); +begin + adatasource:= fdatasource; + atypes:= getlistdatatypes; +end; + +procedure tvalueclientcontroller.dostatread(const reader: tstatreader); +begin + inherited; + if reader.candata then begin + if fdatalist = nil then begin + statreadvalue(reader); + end + else begin + reader.readdatalist(listvarname,fdatalist); + end; + end; +end; + +procedure tvalueclientcontroller.dostatwrite(const writer: tstatwriter); +begin + inherited; + if writer.candata then begin + if fdatalist = nil then begin + statwritevalue(writer); + end + else begin + writer.writedatalist(listvarname,fdatalist); + end; + end; +end; + +procedure tvalueclientcontroller.statreadvalue(const reader: tstatreader); +begin + //dummy +end; + +procedure tvalueclientcontroller.statwritevalue(const reader: tstatwriter); +begin + //dummy +end; + +procedure tvalueclientcontroller.updateoptionsedit(var avalue: optionseditty); +begin + if not (csdesigning in fowner.componentstate) then begin + if vco_readonly in foptionsvalue then begin + include(avalue,oe_readonly); + end; + if vco_notnull in foptionsvalue then begin + include(avalue,oe_notnull); + end; + end; +end; + +procedure tvalueclientcontroller.linkset(const alink: iificlient); +begin + if not (vco_nosync in foptionsvalue) then begin + inherited; + end; +end; + +{ tstringclientcontroller } + +constructor tstringclientcontroller.create(const aowner: tmsecomponent); +begin + inherited create(aowner,msestringtypekind); +end; + +procedure tstringclientcontroller.setvalue1(const avalue: msestring); +begin + fvalue:= avalue; + change; +end; + +procedure tstringclientcontroller.valuestoclient(const alink: pointer); +begin + setmsestringval(iificlient(alink),'value',fvalue); + inherited; +end; + +procedure tstringclientcontroller.clienttovalues(const alink: pointer); +begin + inherited; + getmsestringval(iificlient(alink),'value',fvalue); +end; + +{ +procedure tstringwidgetcontroller.widgettovalue; +begin + value:= getmsestringprop(clientinstance,fvalueproperty); +end; +} +procedure tstringclientcontroller.setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); +begin + if fowner.canevent(tmethod(fonclientsetvalue)) then begin + fonclientsetvalue(self,sender,msestring(avalue),accept,arow); + end; + inherited; +end; +{ +function tstringclientcontroller.getgridvalues: msestringarty; +begin + result:= nil; + getvalar(@getmsestringvalar,result); +end; + +procedure tstringclientcontroller.setgridvalues(const avalue: msestringarty); +begin + setvalar(@setmsestringvalar,avalue); +end; + +function tstringclientcontroller.getgridvalue(const index: integer): msestring; +begin + result:= ''; + getitem(index,@getmsestringitem,result); +end; + +procedure tstringclientcontroller.setgridvalue(const index: integer; + const avalue: msestring); +begin + setitem(index,@setmsestringitem,avalue); +end; +} +function tstringclientcontroller.getgriddata: tifimsestringdatalist; +begin + result:= tifimsestringdatalist(ifigriddata); +end; + +function tstringclientcontroller.getonclientvaluechanged: + ifistringclienteventty; +begin + result:= ifistringclienteventty(fonclientvaluechanged); +end; + +procedure tstringclientcontroller.setonclientvaluechanged( + const avalue: ifistringclienteventty); +begin + fonclientvaluechanged:= ificlienteventty(avalue); +end; + +procedure tstringclientcontroller.statreadvalue(const reader: tstatreader); +begin + inherited; + value:= reader.readmsestring(valuevarname,value); +end; + +procedure tstringclientcontroller.statwritevalue(const writer: tstatwriter); +begin + inherited; + writer.writemsestring(valuevarname,value); +end; + +function tstringclientcontroller.createdatalist: tdatalist; +begin + result:= tifimsestringdatalist.create(self); +end; + +function tstringclientcontroller.getlistdatatypes: listdatatypesty; +begin + result:= [dl_msestring]; +end; + +{ tintegerclientcontroller } + +constructor tintegerclientcontroller.create(const aowner: tmsecomponent); +begin + fvaluemax:= maxint; + inherited create(aowner,tkinteger); +end; + +procedure tintegerclientcontroller.setvalue1(const avalue: integer); +begin + fvalue:= avalue; + change; +end; + +procedure tintegerclientcontroller.valuestoclient(const alink: pointer); +begin + setintegerval(iificlient(alink),'value',fvalue); + setintegerval(iificlient(alink),'valuemin',fvaluemin); + setintegerval(iificlient(alink),'valuemax',fvaluemax); + inherited; +end; + +procedure tintegerclientcontroller.clienttovalues(const alink: pointer); +begin + inherited; + getintegerval(iificlient(alink),'value',fvalue); +end; + +procedure tintegerclientcontroller.setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); +begin + if fowner.canevent(tmethod(fonclientsetvalue)) then begin + fonclientsetvalue(fowner,sender,integer(avalue),accept,arow); + end; + inherited; +end; + +procedure tintegerclientcontroller.setvaluemin(const avalue: integer); +begin + fvaluemin:= avalue; + change; +end; + +procedure tintegerclientcontroller.setvaluemax(const avalue: integer); +begin + fvaluemax:= avalue; + change; +end; +{ +function tintegerclientcontroller.getgridvalues: integerarty; +begin + result:= nil; + getvalar(@getintegervalar,result); +end; + +procedure tintegerclientcontroller.setgridvalues(const avalue: integerarty); +begin + setvalar(@setintegervalar,avalue); +end; + +function tintegerclientcontroller.getgridvalue(const index: integer): integer; +begin + result:= 0; + getitem(index,@getintegeritem,result); +end; + +procedure tintegerclientcontroller.setgridvalue(const index: integer; + const avalue: integer); +begin + setitem(index,@setintegeritem,avalue); +end; +} +function tintegerclientcontroller.getgriddata: tifiintegerdatalist; +begin + result:= tifiintegerdatalist(ifigriddata); +end; + +procedure tintegerclientcontroller.readmin(reader: treader); +begin + valuemin:= reader.readinteger; +end; + +procedure tintegerclientcontroller.readmax(reader: treader); +begin + valuemax:= reader.readinteger; +end; + +function tintegerclientcontroller.getonclientvaluechanged: ifiintegerclienteventty; +begin + result:= ifiintegerclienteventty(fonclientvaluechanged); +end; + +procedure tintegerclientcontroller.setonclientvaluechanged( + const avalue: ifiintegerclienteventty); +begin + fonclientvaluechanged:= ificlienteventty(avalue); +end; + +procedure tintegerclientcontroller.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('min',@readmin,nil,false); + filer.defineproperty('max',@readmax,nil,false); +end; + +procedure tintegerclientcontroller.statreadvalue(const reader: tstatreader); +begin + inherited; + value:= reader.readinteger(valuevarname,value,valuemin,valuemax); +end; + +procedure tintegerclientcontroller.statwritevalue(const writer: tstatwriter); +begin + inherited; + writer.writeinteger(valuevarname,value); +end; + +function tintegerclientcontroller.createdatalist: tdatalist; +begin + result:= tifiintegerdatalist.create(self); +end; + +function tintegerclientcontroller.getlistdatatypes: listdatatypesty; +begin + result:= [dl_integer]; +end; + +{ tint64clientcontroller } + +constructor tint64clientcontroller.create(const aowner: tmsecomponent); +begin + fvaluemax:= maxint; + inherited create(aowner,tkint64); +end; + +procedure tint64clientcontroller.setvalue1(const avalue: int64); +begin + fvalue:= avalue; + change; +end; + +procedure tint64clientcontroller.valuestoclient(const alink: pointer); +begin + setint64val(iificlient(alink),'value',fvalue); + setint64val(iificlient(alink),'valuemin',fvaluemin); + setint64val(iificlient(alink),'valuemax',fvaluemax); + inherited; +end; + +procedure tint64clientcontroller.clienttovalues(const alink: pointer); +begin + inherited; + getint64val(iificlient(alink),'value',fvalue); +end; + +procedure tint64clientcontroller.setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); +begin + if fowner.canevent(tmethod(fonclientsetvalue)) then begin + fonclientsetvalue(self,sender,int64(avalue),accept,arow); + end; + inherited; +end; + +procedure tint64clientcontroller.setvaluemin(const avalue: int64); +begin + fvaluemin:= avalue; + change; +end; + +procedure tint64clientcontroller.setvaluemax(const avalue: int64); +begin + fvaluemax:= avalue; + change; +end; +{ +function tint64clientcontroller.getgridvalues: int64arty; +begin + result:= nil; + getvalar(@getint64valar,result); +end; + +procedure tint64clientcontroller.setgridvalues(const avalue: int64arty); +begin + setvalar(@setint64valar,avalue); +end; + +function tint64clientcontroller.getgridvalue(const index: int64): int64; +begin + result:= 0; + getitem(index,@getint64item,result); +end; + +procedure tint64clientcontroller.setgridvalue(const index: int64; + const avalue: int64); +begin + setitem(index,@setint64item,avalue); +end; +} +function tint64clientcontroller.getgriddata: tifiint64datalist; +begin + result:= tifiint64datalist(ifigriddata); +end; + +procedure tint64clientcontroller.readmin(reader: treader); +begin + valuemin:= reader.readint64(); +end; + +procedure tint64clientcontroller.readmax(reader: treader); +begin + valuemax:= reader.readint64() +end; + +function tint64clientcontroller.getonclientvaluechanged: ifiint64clienteventty; +begin + result:= ifiint64clienteventty(fonclientvaluechanged); +end; + +procedure tint64clientcontroller.setonclientvaluechanged( + const avalue: ifiint64clienteventty); +begin + fonclientvaluechanged:= ificlienteventty(avalue); +end; + +procedure tint64clientcontroller.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('min',@readmin,nil,false); + filer.defineproperty('max',@readmax,nil,false); +end; + +procedure tint64clientcontroller.statreadvalue(const reader: tstatreader); +begin + inherited; + value:= reader.readint64(valuevarname,value,valuemin,valuemax); +end; + +procedure tint64clientcontroller.statwritevalue(const writer: tstatwriter); +begin + inherited; + writer.writeint64(valuevarname,value); +end; + +function tint64clientcontroller.createdatalist: tdatalist; +begin + result:= tifiint64datalist.create(self); +end; + +function tint64clientcontroller.getlistdatatypes: listdatatypesty; +begin + result:= [dl_int64]; +end; + +{ tpointerclientcontroller } + + +constructor tpointerclientcontroller.create(const aowner: tmsecomponent); +begin +{$ifdef mse_hastkpointer} + inherited create(aowner,tkpointer); +{$else} + inherited create(aowner,{$ifdef cpu64}tkint64{$else}tkinteger{$endif}); +{$endif} +end; + +procedure tpointerclientcontroller.setvalue1(const avalue: pointer); +begin + fvalue:= avalue; + change; +end; + +function tpointerclientcontroller.getgriddata: tifipointerdatalist; +begin + result:= tifipointerdatalist(ifigriddata); +end; + +function tpointerclientcontroller.getonclientvaluechanged(): + ifipointerclienteventty; +begin + result:= ifipointerclienteventty(fonclientvaluechanged); +end; + +procedure tpointerclientcontroller.setonclientvaluechanged( + const avalue: ifipointerclienteventty); +begin + fonclientvaluechanged:= ificlienteventty(avalue); +end; + +procedure tpointerclientcontroller.valuestoclient(const alink: pointer); +begin + setpointerval(iifidatalink(alink),'value',fvalue); + inherited; +end; + +procedure tpointerclientcontroller.clienttovalues(const alink: pointer); +begin + inherited; + getpointerval(iifidatalink(alink),'value',fvalue); +end; + +procedure tpointerclientcontroller.setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); +begin + if fowner.canevent(tmethod(fonclientsetvalue)) then begin + fonclientsetvalue(self,sender,pointer(avalue),accept,arow); + end; + inherited; +end; + +function tpointerclientcontroller.createdatalist: tdatalist; +begin + result:= tifipointerdatalist.create(self); +end; + +function tpointerclientcontroller.getlistdatatypes: listdatatypesty; +begin + result:= [dl_pointer]; +end; + +{ tbooleanclientcontroller } + +constructor tbooleanclientcontroller.create(const aowner: tmsecomponent); +begin + inherited create(aowner,{$ifdef FPC}tkbool{$else}tkenumeration{$endif}); +end; + +procedure tbooleanclientcontroller.setvalue1(const avalue: boolean); +begin + fvalue:= avalue; + change; +end; + +procedure tbooleanclientcontroller.valuestoclient(const alink: pointer); +begin + setbooleanval(iificlient(alink),'value',fvalue); + inherited; +end; + +procedure tbooleanclientcontroller.clienttovalues(const alink: pointer); +var + bo1: boolean; +begin + inherited; + bo1:= fvalue; + getbooleanval(iificlient(alink),'value',bo1); + fvalue:= bo1; +end; + +procedure tbooleanclientcontroller.setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); +begin + if fowner.canevent(tmethod(fonclientsetvalue)) then begin + fonclientsetvalue(self,sender,boolean(avalue),accept,arow); + end; + inherited; +end; + +function tbooleanclientcontroller.createdatalist: tdatalist; +begin + result:= tifibooleandatalist.create(self); +end; + +{ +function tbooleanclientcontroller.getgridvalues: longboolarty; +begin + result:= nil; + getvalar(@getbooleanvalar,result); +end; + +procedure tbooleanclientcontroller.setgridvalues(const avalue: longboolarty); +begin + setvalar(@setbooleanvalar,avalue); +end; + +function tbooleanclientcontroller.getgridvalue(const index: integer): boolean; +begin + result:= false; + getitem(index,@getbooleanitem,result); +end; + +procedure tbooleanclientcontroller.setgridvalue(const index: integer; + const avalue: boolean); +begin + setitem(index,@setbooleanitem,avalue); +end; +} +function tbooleanclientcontroller.getgriddata: tifibooleandatalist; +begin + result:= tifibooleandatalist(ifigriddata); +end; + +function tbooleanclientcontroller.getonclientvaluechanged: + ifibooleanclienteventty; +begin + result:= ifibooleanclienteventty(fonclientvaluechanged); +end; + +procedure tbooleanclientcontroller.setonclientvaluechanged( + const avalue: ifibooleanclienteventty); +begin + fonclientvaluechanged:= ificlienteventty(avalue); +end; + +procedure tbooleanclientcontroller.statreadvalue(const reader: tstatreader); +begin + inherited; + value:= reader.readboolean(valuevarname,value); +end; + +procedure tbooleanclientcontroller.statwritevalue(const writer: tstatwriter); +begin + inherited; + writer.writeboolean(valuevarname,value); +end; + +function tbooleanclientcontroller.getvalue: boolean; +begin + result:= fvalue; +end; + +function tbooleanclientcontroller.getvaluedefault: boolean; +begin + result:= fvaluedefault; +end; + +procedure tbooleanclientcontroller.setvaluedefault(const avalue: boolean); +begin + fvaluedefault:= avalue; +end; + +function tbooleanclientcontroller.getlistdatatypes: listdatatypesty; +begin + result:= [dl_integer]; +end; + +{ trealclientcontroller } + +constructor trealclientcontroller.create(const aowner: tmsecomponent); +begin + fvalue:= emptyreal; + fvaluedefault:= emptyreal; + fvaluemin:= emptyreal; + fvaluemax:= bigreal; + inherited create(aowner,tkfloat); +end; + +procedure trealclientcontroller.setvalue1(const avalue: realty); +begin + fvalue:= avalue; + change; +end; + +procedure trealclientcontroller.valuestoclient(const alink: pointer); +begin + setrealtyval(iificlient(alink),'value',fvalue); + setrealtyval(iificlient(alink),'valuemin',fvaluemin); + setrealtyval(iificlient(alink),'valuemax',fvaluemax); + inherited; +end; + +procedure trealclientcontroller.clienttovalues(const alink: pointer); +begin + inherited; + getrealtyval(iificlient(alink),'value',fvalue); +end; + +procedure trealclientcontroller.setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); +begin + if fowner.canevent(tmethod(fonclientsetvalue)) then begin + fonclientsetvalue(self,sender,realty(avalue),accept,arow); + end; + inherited; +end; + +function trealclientcontroller.createdatalist: tdatalist; +begin + result:= tifirealdatalist.create(self); +end; + +procedure trealclientcontroller.setvaluemin(const avalue: realty); +begin + fvaluemin:= avalue; + change; +end; + +procedure trealclientcontroller.setvaluemax(const avalue: realty); +begin + fvaluemax:= avalue; + change; +end; + +procedure trealclientcontroller.readvalue(reader: treader); +begin + value:= readrealty(reader); +end; + +procedure trealclientcontroller.readmin1(reader: treader); +begin + fvaluemin:= readrealty(reader); +end; + +procedure trealclientcontroller.readmax1(reader: treader); +begin + fvaluemax:= readrealty(reader); +end; + +procedure trealclientcontroller.readvaluedefault(reader: treader); +begin + valuedefault:= readrealty(reader); +end; + +procedure trealclientcontroller.readmin(reader: treader); +begin + valuemin:= reader.readfloat; +end; + +procedure trealclientcontroller.readmax(reader: treader); +begin + valuemax:= reader.readfloat; +end; + +function trealclientcontroller.getonclientvaluechanged: ifirealclienteventty; +begin + result:= ifirealclienteventty(fonclientvaluechanged); +end; + +procedure trealclientcontroller.setonclientvaluechanged( + const avalue: ifirealclienteventty); +begin + fonclientvaluechanged:= ificlienteventty(avalue); +end; + +procedure trealclientcontroller.defineproperties(filer: tfiler); +begin + inherited; + + filer.DefineProperty('val', + {$ifdef FPC}@{$endif}readvalue,nil,false); + filer.DefineProperty('mi',{$ifdef FPC}@{$endif}readmin1,nil,false); + filer.DefineProperty('ma',{$ifdef FPC}@{$endif}readmax1,nil,false); + filer.DefineProperty('def',{$ifdef FPC}@{$endif}readvaluedefault,nil,false); + filer.defineproperty('min',@readmin,nil,false); + filer.defineproperty('max',@readmax,nil,false); +end; + +function trealclientcontroller.getgriddata: tifirealdatalist; +begin + result:= tifirealdatalist(ifigriddata); +end; + +procedure trealclientcontroller.statreadvalue(const reader: tstatreader); +begin + inherited; + value:= reader.readreal(valuevarname,value,valuemin,valuemax); +end; + +procedure trealclientcontroller.statwritevalue(const writer: tstatwriter); +begin + inherited; + writer.writereal(valuevarname,value); +end; + +function trealclientcontroller.getlistdatatypes: listdatatypesty; +begin + result:= [dl_real]; +end; + +{ tdatetimeclientcontroller } + +constructor tdatetimeclientcontroller.create(const aowner: tmsecomponent); +begin + fvalue:= emptydatetime; + fvaluedefault:= emptydatetime; + fvaluemin:= emptydatetime; + fvaluemax:= bigdatetime; + inherited create(aowner,tkfloat); +end; + +procedure tdatetimeclientcontroller.setvalue1(const avalue: tdatetime); +begin + fvalue:= avalue; + change; +end; + +procedure tdatetimeclientcontroller.valuestoclient(const alink: pointer); +begin + setdatetimeval(iificlient(alink),'value',fvalue); + setdatetimeval(iificlient(alink),'valuemin',fvaluemin); + setdatetimeval(iificlient(alink),'valuemax',fvaluemax); + inherited; +end; + +procedure tdatetimeclientcontroller.clienttovalues(const alink: pointer); +begin + inherited; + getdatetimeval(iificlient(alink),'value',fvalue); +end; + +procedure tdatetimeclientcontroller.setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); +begin + if fowner.canevent(tmethod(fonclientsetvalue)) then begin + fonclientsetvalue(self,sender,tdatetime(avalue),accept,arow); + end; + inherited; +end; + +function tdatetimeclientcontroller.createdatalist: tdatalist; +begin + result:= tifidatetimedatalist.create(self); +end; + +procedure tdatetimeclientcontroller.setvaluemin(const avalue: tdatetime); +begin + fvaluemin:= avalue; + change; +end; + +procedure tdatetimeclientcontroller.setvaluemax(const avalue: tdatetime); +begin + fvaluemax:= avalue; + change; +end; + +procedure tdatetimeclientcontroller.readvalue(reader: treader); +begin + value:= readrealty(reader); +end; +{ +procedure tdatetimeclientcontroller.writevalue(writer: twriter); +begin + writerealty(writer,fvalue); +end; +} +procedure tdatetimeclientcontroller.readmin1(reader: treader); +begin + fvaluemin:= readrealty(reader); +end; +{ +procedure tdatetimeclientcontroller.writemin(writer: twriter); +begin + writerealty(writer,fmin); +end; +} +procedure tdatetimeclientcontroller.readmax1(reader: treader); +begin + fvaluemax:= readrealty(reader); +end; +{ +procedure tdatetimeclientcontroller.writemax(writer: twriter); +begin + writerealty(writer,fmax); +end; +} +procedure tdatetimeclientcontroller.readvaluedefault(reader: treader); +begin + valuedefault:= readrealty(reader); +end; +{ +procedure tdatetimeclientcontroller.writevaluedefault(writer: twriter); +begin + writerealty(writer,fvaluedefault); +end; +} +procedure tdatetimeclientcontroller.readmin(reader: treader); +begin + valuemin:= reader.readfloat(); +end; + +procedure tdatetimeclientcontroller.readmax(reader: treader); +begin + valuemax:= reader.readfloat(); +end; + +function tdatetimeclientcontroller.getonclientvaluechanged: + ifidatetimeclienteventty; +begin + result:= ifidatetimeclienteventty(fonclientvaluechanged); +end; + +procedure tdatetimeclientcontroller.setonclientvaluechanged( + const avalue: ifidatetimeclienteventty); +begin + fonclientvaluechanged:= ificlienteventty(avalue); +end; + +procedure tdatetimeclientcontroller.defineproperties(filer: tfiler); +begin + inherited; + + filer.DefineProperty('val', + {$ifdef FPC}@{$endif}readvalue,nil,false); + filer.DefineProperty('mi',{$ifdef FPC}@{$endif}readmin1,nil,false); + filer.DefineProperty('ma',{$ifdef FPC}@{$endif}readmax1,nil,false); + filer.DefineProperty('def',{$ifdef FPC}@{$endif}readvaluedefault,nil,false); + filer.defineproperty('min',@readmin,nil,false); + filer.defineproperty('max',@readmax,nil,false); +end; +{ +function tdatetimeclientcontroller.getgridvalues: datetimearty; +begin + result:= nil; + getvalar(@getdatetimevalar,result); +end; + +procedure tdatetimeclientcontroller.setgridvalues(const avalue: datetimearty); +begin + setvalar(@setdatetimevalar,avalue); +end; + +function tdatetimeclientcontroller.getgridvalue(const index: integer): tdatetime; +begin + result:= emptydatetime; + getitem(index,@getdatetimeitem,result); +end; + +procedure tdatetimeclientcontroller.setgridvalue(const index: integer; + const avalue: tdatetime); +begin + setitem(index,@setdatetimeitem,avalue); +end; +} +function tdatetimeclientcontroller.getgriddata: tifidatetimedatalist; +begin + result:= tifidatetimedatalist(ifigriddata); +end; + +procedure tdatetimeclientcontroller.statreadvalue(const reader: tstatreader); +begin + inherited; + value:= reader.readreal(valuevarname,value,valuemin,valuemax); +end; + +procedure tdatetimeclientcontroller.statwritevalue(const writer: tstatwriter); +begin + inherited; + writer.writereal(valuevarname,value); +end; + +function tdatetimeclientcontroller.getlistdatatypes: listdatatypesty; +begin + result:= [dl_real]; +end; + +{ tifistringlinkcomp } + +function tifistringlinkcomp.getcontrollerclass: + customificlientcontrollerclassty; +begin + result:= tstringclientcontroller; +end; + +function tifistringlinkcomp.getcontroller: tstringclientcontroller; +begin + result:= tstringclientcontroller(inherited controller); +end; + +procedure tifistringlinkcomp.setcontroller(const avalue: tstringclientcontroller); +begin + inherited setcontroller(avalue); +end; + +{ tifidropdownlistlinkcomp } + +function tifidropdownlistlinkcomp.getcontroller: tdropdownlistclientcontroller; +begin + result:= tdropdownlistclientcontroller(inherited controller); +end; + +procedure tifidropdownlistlinkcomp.setcontroller( + const avalue: tdropdownlistclientcontroller); +begin + inherited setcontroller(avalue); +end; + +function tifidropdownlistlinkcomp.getcontrollerclass: + customificlientcontrollerclassty; +begin + result:= tdropdownlistclientcontroller; +end; + +{ tifiintegerlinkcomp } + +function tifiintegerlinkcomp.getcontrollerclass: + customificlientcontrollerclassty; +begin + result:= tintegerclientcontroller; +end; + +function tifiintegerlinkcomp.getcontroller: tintegerclientcontroller; +begin + result:= tintegerclientcontroller(inherited controller); +end; + +procedure tifiintegerlinkcomp.setcontroller(const avalue: tintegerclientcontroller); +begin + inherited setcontroller(avalue); +end; + +{ tifiint64linkcomp } + +function tifiint64linkcomp.getcontrollerclass: + customificlientcontrollerclassty; +begin + result:= tint64clientcontroller; +end; + +function tifiint64linkcomp.getcontroller: tint64clientcontroller; +begin + result:= tint64clientcontroller(inherited controller); +end; + +procedure tifiint64linkcomp.setcontroller(const avalue: tint64clientcontroller); +begin + inherited setcontroller(avalue); +end; + +{ tifipointerlinkcomp } + +function tifipointerlinkcomp.getcontroller: tpointerclientcontroller; +begin + result:= tpointerclientcontroller(inherited controller); +end; + +procedure tifipointerlinkcomp.setcontroller( + const avalue: tpointerclientcontroller); +begin + inherited setcontroller(avalue); +end; + +function tifipointerlinkcomp.getcontrollerclass: customificlientcontrollerclassty; +begin + result:= tpointerclientcontroller; +end; + +{ tifibooleanlinkcomp } + +function tifibooleanlinkcomp.getcontrollerclass: + customificlientcontrollerclassty; +begin + result:= tbooleanclientcontroller; +end; + +function tifibooleanlinkcomp.getcontroller: tbooleanclientcontroller; +begin + result:= tbooleanclientcontroller(inherited controller); +end; + +procedure tifibooleanlinkcomp.setcontroller(const avalue: tbooleanclientcontroller); +begin + inherited setcontroller(avalue); +end; + +{ tifireallinkcomp } + +function tifireallinkcomp.getcontrollerclass: + customificlientcontrollerclassty; +begin + result:= trealclientcontroller; +end; + +function tifireallinkcomp.getcontroller: trealclientcontroller; +begin + result:= trealclientcontroller(inherited controller); +end; + +procedure tifireallinkcomp.setcontroller(const avalue: trealclientcontroller); +begin + inherited setcontroller(avalue); +end; + +{ tifidatetimelinkcomp } + +function tifidatetimelinkcomp.getcontrollerclass: + customificlientcontrollerclassty; +begin + result:= tdatetimeclientcontroller; +end; + +function tifidatetimelinkcomp.getcontroller: tdatetimeclientcontroller; +begin + result:= tdatetimeclientcontroller(inherited controller); +end; + +procedure tifidatetimelinkcomp.setcontroller(const avalue: tdatetimeclientcontroller); +begin + inherited setcontroller(avalue); +end; + +{ tificlientcontroller } + +{ tifiactionlinkcomp } + +function tifiactionlinkcomp.getcontrollerclass: + customificlientcontrollerclassty; +begin + result:= texecclientcontroller; +end; + +function tifiactionlinkcomp.getcontroller: texecclientcontroller; +begin + result:= texecclientcontroller(inherited controller); +end; + +procedure tifiactionlinkcomp.setcontroller(const avalue: texecclientcontroller); +begin + inherited setcontroller(avalue); +end; + +{ tififormlinkcomp } + +function tififormlinkcomp.getcontrollerclass: + customificlientcontrollerclassty; +begin + result:= tformclientcontroller; +end; + +function tififormlinkcomp.getcontroller: tformclientcontroller; +begin + result:= tformclientcontroller(inherited controller); +end; + +procedure tififormlinkcomp.setcontroller(const avalue: tformclientcontroller); +begin + inherited setcontroller(avalue); +end; + +{ texecclientcontroller } + +constructor texecclientcontroller.create(const aowner: tmsecomponent); +begin + fenabled:= true; + inherited; +end; + +procedure texecclientcontroller.setclientenabled(const alink: pointer); +begin + iifiexeclink(alink).ifisetenabled(fenabled); +end; + +procedure texecclientcontroller.setenabled(const avalue: boolean); +begin + if fenabled <> avalue then begin + fenabled:= avalue; + if not (csloading in fowner.componentstate) then begin + tmsecomponent1(fowner).getobjectlinker.forall(@setclientenabled,self); + end; + end; +end; + +function texecclientcontroller.canconnect(const acomponent: tcomponent): boolean; +var + po1: pointer; +// prop1: ppropinfo; +begin +// result:= inherited canconnect(acomponent); + result:= getcorbainterface(acomponent,typeinfo(iifiexeclink),po1); + { + if result then begin + prop1:= getpropinfo(acomponent,'onexecute'); + result:= (prop1 <> nil) and (prop1^.proptype^.kind = tkmethod); + end; + } +end; + +procedure texecclientcontroller.valuestoclient(const alink: pointer); +begin + if not (ivs_loadedproc in fstate) then begin + iifiexeclink(alink).execute; + end; +end; + +procedure texecclientcontroller.execute(const sender: iificlient); +begin + if fenabled then begin + inherited; + end; +end; + +{ +procedure texecclientcontroller.execute(const sender: iificlient); +begin + dovaluechanged(sender,true); //distribute event + inherited; +end; +} +procedure texecclientcontroller.execute; +begin + if enabled then begin + distribute(nil,true,true); + end; +// dovaluechanged(nil,true); //distribute event +end; + +procedure texecclientcontroller.linkset(const alink: iificlient); +begin + //do nothing +end; + +procedure texecclientcontroller.dostatread(const reader: tstatreader); +begin + inherited; + if reader.canstate then begin + enabled:= reader.readboolean('_enabled',fenabled); + end; +end; + +procedure texecclientcontroller.dostatwrite(const writer: tstatwriter); +begin + inherited; + if writer.canstate then begin + writer.writeboolean('_enabled',fenabled); + end; +end; + +function texecclientcontroller.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iifiexeclink); +end; + +{ tifigridlinkcomp } + +function tifigridlinkcomp.getcontrollerclass: + customificlientcontrollerclassty; +begin + result:= tgridclientcontroller; +end; + +function tifigridlinkcomp.getcontroller: tgridclientcontroller; +begin + result:= tgridclientcontroller(inherited controller); +end; + +procedure tifigridlinkcomp.setcontroller(const avalue: tgridclientcontroller); +begin + inherited setcontroller(avalue); +end; + +{ tifilinkcomparrayprop } + +constructor tifilinkcomparrayprop.create; +begin + inherited create(tificolitem); +end; + +class function tifilinkcomparrayprop.getitemclasstype: persistentclassty; +begin + result:= tificolitem; +end; + +function tifilinkcomparrayprop.getitems(const index: integer): tificolitem; +begin + result:= tificolitem(inherited getitems(index)); +end; + +{ tifivaluelinkcomp } + +function tifivaluelinkcomp.getcontroller: tvalueclientcontroller; +begin + result:= tvalueclientcontroller(fcontroller); +end; + +{ tificolitem } + +function tificolitem.getlink: tifivaluelinkcomp; +begin + result:= tifivaluelinkcomp(item); +end; + +procedure tificolitem.setlink(const avalue: tifivaluelinkcomp); +begin + item:= avalue; +end; + +{ tifidropdowncols } + +constructor tifidropdowncols.create(const aowner: tifidropdownlistcontroller); +begin + inherited create(aowner,nil); +end; + +class function tifidropdowncols.getitemclasstype: persistentclassty; +begin + result:= tifidropdowncol; +end; + +procedure tifidropdowncols.createitem(const index: integer; + var item: tpersistent); +begin + item:= tifidropdowncol.create; + tifidropdowncol(item).onchange:= {$ifdef FPC}@{$endif}colchanged; +end; + +function tifidropdowncols.getitems(const index: integer): tifidropdowncol; +begin + result:= tifidropdowncol(inherited getitems(index)); +end; + +procedure tifidropdowncols.colchanged(const sender: tobject); +begin + change(-1); +end; + +procedure tifidropdowncols.dochange(const index: integer); +begin + tifidropdownlistcontroller(fowner).fowner.change(nil); +end; + +{ tifidropdownlistcontroller } + +constructor tifidropdownlistcontroller.create( + const aowner: tvalueclientcontroller); +begin + fowner:= aowner; + fcols:= tifidropdowncols.create(self); + inherited create; +end; + +destructor tifidropdownlistcontroller.destroy; +begin + inherited; + fcols.free; +end; + +procedure tifidropdownlistcontroller.setcols(const avalue: tifidropdowncols); +begin + fcols.assign(avalue); +end; + +procedure tifidropdownlistcontroller.valuestoclient(const alink: pointer); +begin + iifidropdownlistdatalink(alink).ifidropdownlistchanged(fcols); +end; + +{ tdropdownlistclientcontroller } + +constructor tdropdownlistclientcontroller.create(const aowner: tmsecomponent); +begin + fdropdown:= tifidropdownlistcontroller.create(self); + inherited; +end; + +destructor tdropdownlistclientcontroller.destroy; +begin + inherited; + fdropdown.free; +end; + +procedure tdropdownlistclientcontroller.setdropdown( + const avalue: tifidropdownlistcontroller); +begin + fdropdown.assign(avalue); +end; + +function tdropdownlistclientcontroller.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iifidropdownlistdatalink); +end; + +procedure tdropdownlistclientcontroller.valuestoclient(const alink: pointer); +begin + fdropdown.valuestoclient(alink); + inherited; +end; + +{ tenumclientcontroller } + +constructor tenumclientcontroller.create(const aowner: tmsecomponent); +begin + fdropdown:= tifidropdownlistcontroller.create(self); + inherited; + fvaluemin:= -1; + fvalue:= -1; + fvaluedefault:= -1; +end; + +destructor tenumclientcontroller.destroy; +begin + inherited; + fdropdown.free; +end; + +procedure tenumclientcontroller.setdropdown( + const avalue: tifidropdownlistcontroller); +begin + fdropdown.assign(avalue); +end; + +function tenumclientcontroller.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iifidropdownlistdatalink); +end; + +procedure tenumclientcontroller.valuestoclient(const alink: pointer); +begin + fdropdown.valuestoclient(alink); + inherited; +end; + +{ tifienumlinkcomp } + +function tifienumlinkcomp.getcontroller: tenumclientcontroller; +begin + result:= tenumclientcontroller(inherited controller); +end; + +procedure tifienumlinkcomp.setcontroller( + const avalue: tenumclientcontroller); +begin + inherited setcontroller(avalue); +end; + +function tifienumlinkcomp.getcontrollerclass: customificlientcontrollerclassty; +begin + result:= tenumclientcontroller; +end; + +{ tifidropdowncol } + +procedure tifidropdowncol.setdatasource(const avalue: tifidatasource); +begin + if avalue <> fdatasource then begin + setifidatasource(iifidatasourceclient(self),avalue,fdatasource); + end; +end; + +procedure tifidropdowncol.setdatafield(const avalue: ififieldnamety); +begin + if avalue <> fdatafield then begin + fdatafield:= avalue; + bindingchanged; + end; +end; + +procedure tifidropdowncol.bindingchanged; +begin +end; + +procedure tifidropdowncol.getfieldinfo(const apropname: ififieldnamety; + var adatasource: tifidatasource; var atypes: listdatatypesty); +begin + adatasource:= fdatasource; + atypes:= [dl_msestring,dl_ansistring]; +end; + +function tifidropdowncol.ifigriddata: tdatalist; +begin + result:= self; +end; + +function tifidropdowncol.ififieldname: string; +begin + result:= fdatafield; +end; + +{ tifidatasource } + +constructor tifidatasource.create(aowner: tcomponent); +begin + if ffields = nil then begin + ffields:= tififields.create; + end; +{$ifdef usedelegation} + ffieldsourceintf:= iififieldsource(ffields); +{$endif} + inherited; +end; + +destructor tifidatasource.destroy; +begin + freeandnil(ftimer); + inherited; + ffields.free; +end; + +procedure tifidatasource.setfields(const avalue: tififields); +begin + ffields.assign(avalue); +end; +{$ifndef usedelegation} +function tifidatasource.getfieldnames(const atypes: listdatatypesty): msestringarty; +begin + result:= ffields.getfieldnames(atypes); +end; +{$endif} + +procedure tifidatasource.open; +begin + if canevent(tmethod(fonbeforeopen)) then begin + fonbeforeopen(self); + end; +end; + +procedure tifidatasource.afteropen; +begin + factive:= true; + if canevent(tmethod(fonafteropen)) then begin + fonafteropen(self); + end; +end; + +procedure tifidatasource.close; +begin + factive:= false; +end; + +procedure tifidatasource.setactive(const avalue: boolean); +begin + if csreading in componentstate then begin + fopenafterread:= avalue; + end + else begin + if factive <> avalue then begin + if avalue then begin + open; + end + else begin + fopenafterread:= false; + close; + end; + end; + end; +end; + +procedure tifidatasource.dorefresh(const sender: tobject); +var + b1: boolean; + ar1: datalistarty; + ar2: stringarty; + int1: integer; +begin + destdatalists(ar2,ar1); + b1:= frefreshing; + frefreshing:= true; + for int1:= 0 to high(ar1) do begin + ar1[int1].beginupdate(); + end; + try + active:= false; + active:= true; + finally + for int1:= 0 to high(ar1) do begin + ar1[int1].endupdate(); + end; + frefreshing:= b1; + end; +end; + +procedure tifidatasource.refresh(const delayus: integer = -1); +begin + if delayus < 0 then begin + freeandnil(ftimer); + dorefresh(nil); + end + else begin + if ftimer = nil then begin + ftimer:= tsimpletimer.create(delayus,@dorefresh,true,[to_single]); + end + else begin + ftimer.interval:= delayus; //single shot + ftimer.enabled:= true; + end; + end; +end; + +procedure tifidatasource.checkrefresh(); +begin + if ftimer <> nil then begin + ftimer.firependingandstop; //cancel wait + end; +end; + +procedure tifidatasource.loaded; +begin + inherited; + if fopenafterread then begin + try + active:= true; + except + if csdesigning in componentstate then begin + application.handleexception; + end + else begin + raise; + end; + end; + end; +end; + +procedure tifidatasource.doactivated; +begin + active:= true; +end; + +procedure tifidatasource.dodeactivated; +begin + active:= false; +end; + +procedure tifidatasource.getbindinginfo(const alink: pointer); +begin + with iifidatasourceclient(alink) do begin + fnamear[findex]:= ififieldname; + flistar[findex]:= ifigriddata; + end; + inc(findex); +end; + +procedure tifidatasource.destdatalists(out names: stringarty; + out lists: datalistarty); +var + int1,int2,int3: integer; +begin + with getobjectlinker do begin + setlength(fnamear,count); + setlength(flistar,count); + setlength(names,count); + setlength(lists,count); + findex:= 0; + forall({$ifdef FPC}@{$endif}getbindinginfo,typeinfo(iifidatasourceclient)); + end; + int3:= 0; + with ffields do begin +// result:= nil; +// setlength(result,count); + for int1:= 0 to high(fnamear) do begin + if fnamear[int1] <> '' then begin + for int2:= 0 to high(fitems) do begin + if (fnamear[int1] = tififield(fitems[int2]).ffieldname) then begin + names[int3]:= fnamear[int1]; + lists[int3]:= flistar[int1]; + inc(int3); + break; + end; + end; + end; + end; + end; + setlength(lists,int3); + setlength(names,int3); + fnamear:= nil; + flistar:= nil; +// for int1:= 0 to high(result) do begin +// end; +end; + +{ tififield } + +{ tififields } + +constructor tififields.create; +begin + inherited create(getififieldclass); +end; + +function tififields.getififieldclass: ififieldclassty; +begin + result:= tififield; +end; + +function tififields.getfieldnames(const atypes: listdatatypesty): msestringarty; +var + int1,int2: integer; +begin + setlength(result,count); + int2:= 0; + for int1:= 0 to count - 1 do begin + with tififield(fitems[int1]) do begin + if (atypes = []) or (datatype in atypes) then begin + result[int2]:= msestring(fieldname); + inc(int2); + end; + end; + end; + setlength(result,int2); +end; + +class function tififields.getitemclasstype: persistentclassty; +begin + result:= tififield; +end; + +{ tififieldlink } + +function tififieldlink.getfieldnames( + const appropname: ifisourcefieldnamety): msestringarty; +begin + result:= fowner.getfieldnames(datatype); +end; + +procedure tififieldlink.setdesignsourcefieldname( + const aname: ifisourcefieldnamety); +begin + if ffieldname = '' then begin + ffieldname:= aname; + end; + if fdatatype = dl_none then begin + datatype:= fowner.sourcefieldtype(aname); + end; +end; + +{$ifndef FPC} +function tififieldlink._addref: integer; +begin + result:= -1; +end; + +function tififieldlink._release: integer; +begin + result:= -1; +end; + +function tififieldlink.QueryInterface(const IID: TGUID; out Obj): HResult; +begin + if GetInterface(IID, Obj) then begin + Result:=0 + end + else begin + result:= integer(e_nointerface); + end; +end; +{$endif} +{ tififieldlinks } + +function tififieldlinks.getififieldclass: ififieldlinkclassty; +begin + result:= tififieldlink; +end; + +procedure tififieldlinks.createitem(const index: integer; var item: tpersistent); +begin + item:= getififieldclass.create; + tififieldlink(item).fowner:= self; +end; + +function tififieldlinks.getfieldnames( + const adatatype: listdatatypety): msestringarty; +begin + result:= nil; +end; + +function tififieldlinks.sourcefieldnames: stringarty; +var + int1: integer; +begin + setlength(result,count); + for int1:= 0 to high(result) do begin + result[int1]:= tififieldlink(fitems[int1]).sourcefieldname; + end; +end; + +function tififieldlinks.sourcefieldtype( + const afieldname: string): listdatatypety; +begin + result:= dl_none; //dummy +end; + +{ tificonnectedfields } + +constructor tificonnectedfields.create(const aowner: tconnectedifidatasource); +begin + inherited create; + fowner:= aowner; +end; + +function tificonnectedfields.sourcefieldtype( + const afieldname: string): listdatatypety; +begin + result:= dl_none; + if fowner.fconnectionintf <> nil then begin + result:= fowner.fconnectionintf.getdatatype(afieldname); + end; +end; + +function tificonnectedfields.getfieldnames( + const adatatype: listdatatypety): msestringarty; +begin + result:= fowner.getfieldnames(adatatype); +end; + +{ tconnectedifidatasource } + +constructor tconnectedifidatasource.create(aowner: tcomponent); +begin + if ffields = nil then begin + ffields:= tificonnectedfields.create(self); + end; + inherited; +end; + +procedure tconnectedifidatasource.setconnection(const avalue: tmsecomponent); +begin + if avalue <> nil then begin + checkcorbainterface(self,avalue,typeinfo(iifidataconnection),fconnectionintf); + end; + setlinkedvar(avalue,fconnection); +end; + +function tconnectedifidatasource.getfields: tificonnectedfields; +begin + result:= tificonnectedfields(inherited fields); +end; + +procedure tconnectedifidatasource.setfields(const avalue: tificonnectedfields); +begin + inherited setfields(avalue); +end; + +function tconnectedifidatasource.getfieldnames( + const adatatype: listdatatypety): msestringarty; +begin + result:= nil; + if fconnectionintf <> nil then begin + result:= fconnectionintf.getfieldnames(adatatype); + end; +end; + +procedure tconnectedifidatasource.open; +var + ar1: stringarty; + ar2: datalistarty; +begin + inherited; + checkconnection; + destdatalists(ar1,ar2); + fconnectionintf.fetchdata(ar1,ar2); + afteropen; +end; + +procedure tconnectedifidatasource.close; +var + ar1: datalistarty; + ar2: stringarty; + int1: integer; +begin + destdatalists(ar2,ar1); + for int1:= 0 to high(ar1) do begin + ar1[int1].clear; + end; + inherited; +end; + +procedure tconnectedifidatasource.checkconnection; +begin + if fconnectionintf = nil then begin + raise exception.create(name+': No connection.'); + end; +end; + +{ tifiintegerdatalist } + +constructor tifiintegerdatalist.create(const aowner: tintegerclientcontroller); +begin + fowner:= aowner; + inherited create; +end; + +function tifiintegerdatalist.getdefault: pointer; +begin + result:= @fowner.valuedefault; +end; + +{ tifiint64datalist } + +constructor tifiint64datalist.create(const aowner: tint64clientcontroller); +begin + fowner:= aowner; + inherited create; +end; + +function tifiint64datalist.getdefault: pointer; +begin + result:= @fowner.valuedefault; +end; + +{ tifipointerdatalist } + +constructor tifipointerdatalist.create(const aowner: tpointerclientcontroller); +begin + fowner:= aowner; + inherited create; +end; + +{ tifibooleandatalist } + +constructor tifibooleandatalist.create(const aowner: tbooleanclientcontroller); +begin + fowner:= aowner; + inherited create; +end; + +function tifibooleandatalist.getdefault: pointer; +begin + result:= @fowner.fvaluedefault; +end; + +{ tifirealdatalist } + +constructor tifirealdatalist.create(const aowner: trealclientcontroller); +begin + fowner:= aowner; + inherited create; +end; + +function tifirealdatalist.getdefault: pointer; +begin + result:= @fowner.fvaluedefault; +end; + +{ tifidatetimedatalist } + +constructor tifidatetimedatalist.create(const aowner: tdatetimeclientcontroller); +begin + fowner:= aowner; + inherited create; +end; + +function tifidatetimedatalist.getdefault: pointer; +begin + result:= @fowner.fvaluedefault; +end; + +{ tifimsestringdatalist } + +constructor tifimsestringdatalist.create(const aowner: tstringclientcontroller); +begin + fowner:= aowner; + inherited create; +end; + +function tifimsestringdatalist.getdefault: pointer; +begin + result:= @fowner.fvaluedefault; +end; + +{ trowstatehandler } + +constructor trowstatehandler.create(const aowner: tgridclientcontroller); +begin + fowner:= aowner; + initsource(flistlink); + inherited create; +end; + +destructor trowstatehandler.destroy; +begin + removesource(flistlink); + inherited; +end; + +procedure trowstatehandler.setifilink(const avalue: tifivaluelinkcomp); +begin + setifilinkcomp(iifidatalink(self),avalue,tifilinkcomp(fifilink)); +end; + +procedure trowstatehandler.setifiserverintf(const aintf: iifiserver); +begin + //dummy +end; + +procedure trowstatehandler.ifisetvalue(var avalue; var accept: boolean); +begin + //dummy +end; + +procedure trowstatehandler.getifivalue(var avalue); +begin + //dummy +end; + +procedure trowstatehandler.setifivalue(const avalue); +begin + //dummy +end; + +function trowstatehandler.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iifidatalink); +end; + +procedure trowstatehandler.setvalue(const sender: iificlient; var avalue; + var accept: boolean; const arow: integer); +begin + //dummy +end; + +procedure trowstatehandler.updateifigriddata(const sender: tobject; + const alist: tdatalist); +begin + internallinksource(alist,0,flistlink.source); +end; + +function trowstatehandler.getgriddata: tdatalist; +begin + result:= nil; +end; + +function trowstatehandler.getvalueprop: ppropinfo; +begin + result:= nil; +end; + +procedure trowstatehandler.sourcechange(const sender: tdatalist; + const aindex: integer); +begin //todo: optimize + if checksourcechange(flistlink,sender,aindex) then begin + if not (dls_remotelock in fstate) then begin + include(fstate,dls_remotelock); + try + if aindex < 0 then begin + fowner.rowcount:= sender.count; + end; + findexpar:= aindex; + tmsecomponent1(fowner.fowner).getobjectlinker.forall( + {$ifdef FPC}@{$endif}updateclient,fowner); + //... + finally + exclude(fstate,dls_remotelock); + end; + end; + end; +end; + +function trowstatehandler.canlink(const asource: tdatalist; + const atag: integer): boolean; +begin + result:= true; //datalist type defined by ifidatalink kind +end; + +procedure trowstatehandler.listdestroyed(const sender: tdatalist); +begin + if sender = flistlink.source then begin + flistlink.source:= nil; + end; + inherited; +end; + +procedure trowstatehandler.itemchanged(const sender: tcustomrowstatelist; + const aindex: integer); +begin //todo: optimize + if (flistlink.source <> nil) and not (dls_remotelock in fstate) then begin + include(fstate,dls_remotelock); + try + if aindex < 0 then begin + flistlink.source.count:= sender.count; + end; + updateremote(sender,aindex); + finally + exclude(fstate,dls_remotelock); + end; + end; +end; + +procedure trowstatehandler.updatereadonlystate; +begin + //dummy +end; + +function trowstatehandler.getdefaultifilink: iificlient; +begin + result:= iifidatalink(self); +end; + +{ trowstateintegerhandler } + +function trowstateintegerhandler.getifilink: tifiintegerlinkcomp; +begin + result:= tifiintegerlinkcomp(fifilink); +end; + +procedure trowstateintegerhandler.setifilink(const avalue: tifiintegerlinkcomp); +begin + inherited setifilink(avalue); +end; + +{ trowstatebooleanhandler } + +function trowstatebooleanhandler.getifilink: tifibooleanlinkcomp; +begin + result:= tifibooleanlinkcomp(fifilink); +end; + +procedure trowstatebooleanhandler.setifilink(const avalue: tifibooleanlinkcomp); +begin + inherited setifilink(avalue); +end; + +{ trowstatecolorhandler } + +procedure trowstatecolorhandler.updateclient(const alink: pointer); +begin + with iifigridlink(alink) do begin + with getrowstate do begin + if findexpar < 0 then begin + colorar:= tintegerdatalist(flistlink.source).asarray; + end + else begin + color[findexpar]:= tintegerdatalist(flistlink.source)[findexpar]; + end; + rowchanged(findexpar); + end; + end; +end; + +procedure trowstatecolorhandler.updateremote(const sender: tcustomrowstatelist; + const aindex: integer); +begin + if aindex < 0 then begin + tintegerdatalist(flistlink.source).asarray:= sender.colorar; + end + else begin + tintegerdatalist(flistlink.source)[aindex]:= sender.color[aindex]; + end; +end; + +{ trowstatefonthandler } + +procedure trowstatefonthandler.updateclient(const alink: pointer); +begin + with iifigridlink(alink) do begin + with getrowstate do begin + if findexpar < 0 then begin + fontar:= tintegerdatalist(flistlink.source).asarray; + end + else begin + font[findexpar]:= tintegerdatalist(flistlink.source)[findexpar]; + end; + rowchanged(findexpar); + end; + end; +end; + +procedure trowstatefonthandler.updateremote(const sender: tcustomrowstatelist; + const aindex: integer); +begin + if aindex < 0 then begin + tintegerdatalist(flistlink.source).asarray:= sender.fontar; + end + else begin + tintegerdatalist(flistlink.source)[aindex]:= sender.font[aindex]; + end; +end; + +{ trowstatefoldlevelhandler } + +procedure trowstatefoldlevelhandler.updateclient(const alink: pointer); +begin + with iifigridlink(alink) do begin + with getrowstate do begin + if findexpar < 0 then begin + foldlevelar:= tintegerdatalist(flistlink.source).asarray; + end + else begin + foldlevel[findexpar]:= tintegerdatalist(flistlink.source)[findexpar]; + end; + rowchanged(findexpar); + rowstatechanged(findexpar); + end; + end; +end; + +procedure trowstatefoldlevelhandler.updateremote(const sender: tcustomrowstatelist; + const aindex: integer); +begin + if aindex < 0 then begin + tintegerdatalist(flistlink.source).asarray:= sender.foldlevelar; + end + else begin + tintegerdatalist(flistlink.source)[aindex]:= sender.foldlevel[aindex]; + end; +end; + +{ trowstatehiddenhandler } + +procedure trowstatehiddenhandler.updateclient(const alink: pointer); +begin + with iifigridlink(alink) do begin + with getrowstate do begin + if findexpar < 0 then begin + hiddenar:= tbooleandatalist(flistlink.source).asarray; + end + else begin + hidden[findexpar]:= tbooleandatalist(flistlink.source)[findexpar]; + end; +// rowchanged(findexpar); +// rowstatechanged(findexpar); +// layoutchanged; + end; + end; +end; + +procedure trowstatehiddenhandler.updateremote(const sender: tcustomrowstatelist; + const aindex: integer); +begin + if aindex < 0 then begin + tbooleandatalist(flistlink.source).asarray:= sender.hiddenar; + end + else begin + tbooleandatalist(flistlink.source)[aindex]:= sender.hidden[aindex]; + end; +end; + +{ trowstatehiddenhandler } + +procedure trowstatefoldissumhandler.updateclient(const alink: pointer); +begin + with iifigridlink(alink) do begin + with getrowstate do begin + if findexpar < 0 then begin + foldissumar:= tbooleandatalist(flistlink.source).asarray; + end + else begin + foldissum[findexpar]:= tbooleandatalist(flistlink.source)[findexpar]; + end; +// rowchanged(findexpar); +// rowstatechanged(findexpar); +// layoutchanged; + end; + end; +end; + +procedure trowstatefoldissumhandler.updateremote(const sender: tcustomrowstatelist; + const aindex: integer); +begin + if aindex < 0 then begin + tbooleandatalist(flistlink.source).asarray:= sender.foldissumar; + end + else begin + tbooleandatalist(flistlink.source)[aindex]:= sender.foldissum[aindex]; + end; +end; + +{ tgridclientcontroller } + +constructor tgridclientcontroller.create(const aowner: tmsecomponent); +begin + fdatacols:= tifilinkcomparrayprop.create; + frowstatecolor:= trowstatecolorhandler.create(self); + frowstatefont:= trowstatefonthandler.create(self); + frowstatefoldlevel:= trowstatefoldlevelhandler.create(self); + frowstatehidden:= trowstatehiddenhandler.create(self); + frowstatefoldissum:= trowstatefoldissumhandler.create(self); + inherited; +end; + +destructor tgridclientcontroller.destroy; +begin + fdatacols.free; + frowstatecolor.free; + frowstatefont.free; + frowstatefoldlevel.free; + frowstatehidden.free; + frowstatefoldissum.free; + inherited; +end; + +procedure tgridclientcontroller.statreadrowstate(const alink: pointer); +var + list1: tcustomrowstatelist; +begin + list1:= iifigridlink(alink).getrowstate; + if list1 <> nil then begin + tstatreader(fitempo).readdatalist(rowstatevarname,list1); + end; +end; + +procedure tgridclientcontroller.dostatread(const reader: tstatreader); +var + int1: integer; + lico: tifivaluelinkcomp; +begin + inherited; + fitempo:= reader; + tmsecomponent1(fowner).getobjectlinker.forall({$ifdef FPC}@{$endif}statreadrowstate,self); + for int1:= 0 to datacols.count - 1 do begin + lico:= datacols[int1].link; + if lico <> nil then begin + with lico.controller do begin + if fstatfile = nil then begin + dostatread(reader); + end; + end; + end; + end; +end; + +procedure tgridclientcontroller.statwriterowstate(const alink: pointer; + var handled: boolean); +var + list1: tcustomrowstatelist; +begin + list1:= iifigridlink(alink).getrowstate; + if list1 <> nil then begin + tstatwriter(fitempo).writedatalist(rowstatevarname,list1); + handled:= true; + end; +end; + +procedure tgridclientcontroller.dostatwrite(const writer: tstatwriter); +var + int1: integer; + lico: tifivaluelinkcomp; +begin + inherited; + fitempo:= writer; + tmsecomponent1(fowner).getobjectlinker.forfirst({$ifdef FPC}@{$endif}statwriterowstate,self); + for int1:= 0 to datacols.count - 1 do begin + lico:= datacols[int1].link; + if lico <> nil then begin + with lico.controller do begin + if fstatfile = nil then begin + dostatwrite(writer); +// fitempo:= writer; +// tmsecomponent1(fowner).getobjectlinker.forfirst( +// @statwritelist,lico.controller); + end; + end; + end; + end; +end; + +procedure tgridclientcontroller.setrowcount(const avalue: integer); +begin + frowcount:= avalue; + change; +end; + +procedure tgridclientcontroller.valuestoclient(const alink: pointer); +begin + setintegerval(iifigridlink(alink),'rowcount',frowcount); + inherited; +end; + +procedure tgridclientcontroller.clienttovalues(const alink: pointer); +begin + inherited; + getintegerval(iifigridlink(alink),'rowcount',frowcount); +end; + +procedure tgridclientcontroller.docellevent(var info: ificelleventinfoty); +begin + if fowner.canevent(tmethod(foncellevent)) then begin + foncellevent(self,info); + end; +end; + +procedure tgridclientcontroller.dorowsinserting(var index: integer; + var count: integer; const userinput: boolean); +begin + if fowner.canevent(tmethod(fonrowsinserting)) then begin + fonrowsinserting(self,index,count,userinput); + end; +end; + +procedure tgridclientcontroller.dorowsinserted(const index: integer; + const count: integer; const userinput: boolean); +begin + if fowner.canevent(tmethod(fonrowsinserted)) then begin + fonrowsinserted(self,index,count,userinput); + end; +end; + +procedure tgridclientcontroller.dorowsdeleting(var index: integer; + var count: integer; const userinput: boolean); +begin + if fowner.canevent(tmethod(fonrowsdeleting)) then begin + fonrowsdeleting(self,index,count,userinput); + end; +end; + +procedure tgridclientcontroller.dorowsdeleted(const index: integer; + const count: integer; const userinput: boolean); +begin + if fowner.canevent(tmethod(fonrowsdeleted)) then begin + fonrowsdeleted(self,index,count,userinput); + end; +end; + +function tgridclientcontroller.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iifigridlink); +end; + +procedure tgridclientcontroller.setdatacols(const avalue: tifilinkcomparrayprop); +begin + fdatacols.assign(avalue); +end; + +procedure tgridclientcontroller.itemappendrow(const alink: pointer); +begin + iifigridlink(alink).appendrow(fcheckautoappend); +end; + +procedure tgridclientcontroller.getrowstate1(const alink: pointer; + var handled: boolean); +var + list1: tcustomrowstatelist; +begin + list1:= iifigridlink(alink).getrowstate; + if list1 <> nil then begin + handled:= true; + pdatalist(fitempo)^:= list1; + end; +end; + +function tgridclientcontroller.getrowstate: tcustomrowstatelist; +begin + result:= nil; + fitempo:= @result; + tmsecomponent1(fowner).getobjectlinker.forfirst({$ifdef FPC}@{$endif}getrowstate1,self); +end; + +procedure tgridclientcontroller.appendrow(const avalues: array of const; + const checkautoappend: boolean = false); +var + int1,int2: integer; + comp1: tifilinkcomp; +begin + fcheckautoappend:= checkautoappend; + tmsecomponent1(fowner).getobjectlinker.forall({$ifdef FPC}@{$endif}itemappendrow,self); + int2:= high(avalues); + if int2 >= datacols.count then begin + int2:= datacols.count; + end; + for int1:= 0 to int2 do begin + comp1:= tificolitem(fdatacols.fitems[int1]).link; + if comp1 <> nil then begin + with avalues[int1] do begin + case vtype of + vtstring: begin + if comp1 is tifistringlinkcomp then begin + with tifistringlinkcomp(comp1).controller do begin + if fdatalist <> nil then begin + griddata[fdatalist.count-1]:= msestring(vstring^); + end; + end; + end; + end; + vtansistring: begin + if comp1 is tifistringlinkcomp then begin + with tifistringlinkcomp(comp1).controller do begin + if fdatalist <> nil then begin + griddata[fdatalist.count-1]:= msestring(ansistring(vansistring)); + end; + end; + end; + end; + {$ifdef mse_hasvtunicodestring} + vtunicodestring: begin + if comp1 is tifistringlinkcomp then begin + with tifistringlinkcomp(comp1).controller do begin + if fdatalist <> nil then begin + griddata[fdatalist.count-1]:= unicodestring(vunicodestring); + end; + end; + end; + end; + {$endif} + vtwidestring: begin + if comp1 is tifistringlinkcomp then begin + with tifistringlinkcomp(comp1).controller do begin + if fdatalist <> nil then begin + griddata[fdatalist.count-1]:= widestring(vwidestring); + end; + end; + end; + end; + vtpchar: begin + if comp1 is tifistringlinkcomp then begin + with tifistringlinkcomp(comp1).controller do begin + if fdatalist <> nil then begin + griddata[fdatalist.count-1]:= msestring(ansistring(vpchar)); + end; + end; + end; + end; + vtpwidechar: begin + if comp1 is tifistringlinkcomp then begin + with tifistringlinkcomp(comp1).controller do begin + if fdatalist <> nil then begin + griddata[fdatalist.count-1]:= msestring(vpwidechar); + end; + end; + end; + end; + vtchar: begin + if comp1 is tifistringlinkcomp then begin + with tifistringlinkcomp(comp1).controller do begin + if fdatalist <> nil then begin + griddata[fdatalist.count-1]:= msestring(vchar); + end; + end; + end; + end; + vtwidechar: begin + if comp1 is tifistringlinkcomp then begin + with tifistringlinkcomp(comp1).controller do begin + if fdatalist <> nil then begin + griddata[fdatalist.count-1]:= vwidechar; + end; + end; + end; + end; + vtboolean: begin + if comp1 is tifibooleanlinkcomp then begin + with tifibooleanlinkcomp(comp1).controller do begin + if fdatalist <> nil then begin + griddata[fdatalist.count-1]:= longbool(vboolean); + end; + end; + end; + end; + vtinteger: begin + if comp1 is tifiintegerlinkcomp then begin + with tifiintegerlinkcomp(comp1).controller do begin + if fdatalist <> nil then begin + griddata[fdatalist.count-1]:= vinteger; + end; + end; + end; + end; + vtextended: begin + if comp1 is tifireallinkcomp then begin + with tifireallinkcomp(comp1).controller do begin + if fdatalist <> nil then begin + griddata[fdatalist.count-1]:= vextended^; + end; + end; + end + else begin + if comp1 is tifidatetimelinkcomp then begin + with tifidatetimelinkcomp(comp1).controller do begin + if fdatalist <> nil then begin + griddata[fdatalist.count-1]:= vextended^; + end; + end; + end; + end; + end; + end; + end; + end; + end; +end; + +function tgridclientcontroller.rowempty(const arow: integer): boolean; +var + int1: integer; + link1: tifivaluelinkcomp; +begin + result:= true; + if arow >= 0 then begin + for int1:= 0 to high(datacols.fitems) do begin + link1:= tificolitem(datacols.fitems[int1]).link; + if link1 <> nil then begin + with link1.controller.datalist do begin + if (arow < count) and not empty(arow) then begin + result:= false; + break; + end; + end; + end; + end; + end; +end; + +function tgridclientcontroller.getrowstate_color: tifiintegerlinkcomp; +begin + result:= frowstatecolor.ifilink; +end; + +procedure tgridclientcontroller.setrowstate_color(const avalue: tifiintegerlinkcomp); +begin + frowstatecolor.ifilink:= avalue; +end; + +function tgridclientcontroller.getrowstate_font: tifiintegerlinkcomp; +begin + result:= frowstatefont.ifilink; +end; + +procedure tgridclientcontroller.setrowstate_font( + const avalue: tifiintegerlinkcomp); +begin + frowstatefont.ifilink:= avalue; +end; + +function tgridclientcontroller.getrowstate_foldlevel: tifiintegerlinkcomp; +begin + result:= frowstatefoldlevel.ifilink; +end; + +procedure tgridclientcontroller.setrowstate_foldlevel( + const avalue: tifiintegerlinkcomp); +begin + frowstatefoldlevel.ifilink:= avalue; +end; + +function tgridclientcontroller.getrowstate_hidden: tifibooleanlinkcomp; +begin + result:= frowstatehidden.ifilink; +end; + +procedure tgridclientcontroller.setrowstate_hidden( + const avalue: tifibooleanlinkcomp); +begin + frowstatehidden.ifilink:= avalue; +end; + +function tgridclientcontroller.getrowstate_foldissum: tifibooleanlinkcomp; +begin + result:= frowstatefoldissum.ifilink; +end; + +procedure tgridclientcontroller.setrowstate_foldissum( + const avalue: tifibooleanlinkcomp); +begin + frowstatefoldissum.ifilink:= avalue; +end; + +function tgridclientcontroller.checkcomponent(const aintf: iifilink): pointer; +begin + result:= inherited checkcomponent(aintf); + iifigridlink(aintf).getrowstate.linkclient(idatalistclient(self)); +end; + +procedure tgridclientcontroller.itemchanged(const sender: tdatalist; + const aindex: integer); +begin + if not (gcs_itemchangelock in fgridstate) then begin + include(fgridstate,gcs_itemchangelock); + try + frowstatecolor.itemchanged(tcustomrowstatelist(sender),aindex); + frowstatefont.itemchanged(tcustomrowstatelist(sender),aindex); + frowstatefoldlevel.itemchanged(tcustomrowstatelist(sender),aindex); + frowstatehidden.itemchanged(tcustomrowstatelist(sender),aindex); + frowstatefoldissum.itemchanged(tcustomrowstatelist(sender),aindex); + finally + exclude(fgridstate,gcs_itemchangelock); + end; + end; +end; + +procedure tgridclientcontroller.canclose1(const alink: pointer; + var handled: boolean); +begin + pboolean(fitempo)^:= iifigridlink(alink).canclose1; + handled:= not pboolean(fitempo)^; +end; + +function tgridclientcontroller.canclose: boolean; +begin + result:= true; + fitempo:= @result; + tmsecomponent1(fowner).getobjectlinker.forfirst( + {$ifdef FPC}@{$endif}canclose1,self); +end; + +{ tformclientcontroller } + +procedure tformclientcontroller.setmodalresult(const avalue: modalresultty); +begin + fmodalresult:= avalue; + change(nil); +end; + +function tformclientcontroller.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iififormlink); +end; + +procedure tformclientcontroller.linkset(const alink: iificlient); +begin + //do nothing +end; + +procedure tformclientcontroller.valuestoclient(const alink: pointer); +begin + iififormlink(alink).setmodalresult(fmodalresult); +end; + +procedure tformclientcontroller.sendmodalresult(const sender: iificlient; + const amodalresult: modalresultty); +begin + fmodalresult:= amodalresult; + inherited; +end; + +end. diff --git a/mseide-msegui/lib/common/ifi/mseificompglob.pas b/mseide-msegui/lib/common/ifi/mseificompglob.pas new file mode 100644 index 0000000..a8fa562 --- /dev/null +++ b/mseide-msegui/lib/common/ifi/mseificompglob.pas @@ -0,0 +1,81 @@ +{ MSEgui Copyright (c) 2010-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseificompglob; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +interface +uses + mseglob,mseifiglob,mseclasses,msetypes,msegridsglob,mseguiglob,msegraphutils, + typinfo,msedatalist,mseapplication,mseinterfaces; + +type + ificelleventinfoty = record //same layout as celleventinfoty + cell: gridcoordty; + grid: tobject; + case eventkind: celleventkindty of + cek_exit,cek_enter,cek_focusedcellchanged: + (cellbefore,newcell: gridcoordty; selectaction: focuscellactionty); + cek_select: + (selected: boolean; accept: boolean); + cek_mousemove,cek_mousepark,cek_firstmousepark, + cek_buttonpress,cek_buttonrelease: + (zone: cellzonety; mouseeventinfopo: pmouseeventinfoty; + gridmousepos: pointty); + cek_keydown,cek_keyup: + (keyeventinfopo: pkeyeventinfoty); + end; + + iifilink = interface(iificlient)[miid_iifilink] + function getifilinkkind: ptypeinfo; + function getobjectlinker: tobjectlinker; + end; + + iifiexeclink = interface(iifilink)[miid_iifiexeclink] + procedure execute(const force: boolean = false); + procedure ifisetenabled(const avalue: boolean); + end; + + iififormlink = interface(iifilink)[miid_iififormlink] + procedure setmodalresult(const avalue: modalresultty); + end; + + iifidialoglink = interface(iifilink)[miid_iifidialoglink] + function showdialog(out adialog: tactcomponent): modalresultty; + end; + + iifidatalink = interface(iifilink)[miid_iifidatalink] + procedure updateifigriddata(const sender: tobject; const alist: tdatalist); + function getgriddata: tdatalist; + function getvalueprop: ppropinfo; + procedure getifivalue(var avalue); //for pointer property without RTTI + procedure setifivalue(const avalue); //for pointer property without RTTI + procedure updatereadonlystate; + end; + + iifigridlink = interface(iifidatalink)[miid_iifigridlink] + function appendrow(const checkautoappend: boolean = false): integer; + function getrowstate: tcustomrowstatelist; + procedure rowchanged(const arow: integer); + procedure rowstatechanged(const arow: integer); + procedure layoutchanged; + function canclose1: boolean; + end; + + iifidataserver = interface(iifiserver) + procedure valuechanged(const sender: iifidatalink); + procedure setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); + end; + + iifigridserver = interface(iifiserver) + + end; + +implementation +end. diff --git a/mseide-msegui/lib/common/ifi/mseifidbcomp.pas b/mseide-msegui/lib/common/ifi/mseifidbcomp.pas new file mode 100644 index 0000000..a4020dc --- /dev/null +++ b/mseide-msegui/lib/common/ifi/mseifidbcomp.pas @@ -0,0 +1,265 @@ +{ MSEgui Copyright (c) 2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + experimental user <-> business logic connection components. + Warning: works with RTTI and is therefore slow. +} +unit mseifidbcomp; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +interface +uses + mseglob,mseificomp,msesqlresult,msqldb,mseclasses,classes,msedatalist,msestrings,mdb, + msedb,msetypes,mseinterfaces; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +type +{ + tifisqldatasource = class; + tifisqlfieldlinks = class(tififieldlinks) + protected + fowner: tifisqldatasource; + function getfieldnames( + const adatatype: listdatatypety): msestringarty; override; + end; + + tifisqldatasource = class(tifidatasource) + private + fsource: tsqlresult; + procedure setsource(const avalue: tsqlresult); + protected + procedure open; override; + procedure close; override; + public + constructor create(aowner: tcomponent); override; + procedure refresh; + published + property source: tsqlresult read fsource write setsource; + end; +} + dbfieldinfoty = record + name: msestring; + datatype: tfieldtype; + end; + dbfieldinfoarty = array of dbfieldinfoty; + + iifidbdataconnection = interface(iifidataconnection)[miid_iifidbdataconnection] + function getfieldinfos: dbfieldinfoarty; + end; + + tifisqlresult = class(tsqlresult,iifidataconnection,iifidbdataconnection) + protected + //iifidataconnection + procedure fetchdata(const acolnames: array of string; + acols: array of tdatalist); + function getfieldnames(const adatatype: listdatatypety): msestringarty; + function getdatatype(const aname: ansistring): listdatatypety; + //dl_none if not found + //iifidbdataconnection + function getfieldinfos: dbfieldinfoarty; + public + end; + +const + listtypecompatibledbtypes: array[listdatatypety] of fieldtypesty = + ( +//dl_none,dl_integer, dl_int64, dl_currency, + [], longintfcomp,largeintfcomp+[ftlargeint],realfcomp, +//dl_real, dl_realint,dl_realsum, + realfcomp,realfcomp, realfcomp, +//dl_datetime, + datetimefcomp, +//dl_pointer + [], +//dl_ansistring,dl_msestring,dl_doublemsestring,dl_msestringint, + stringfcomp, stringfcomp, stringfcomp, stringfcomp, +//dl_complex,dl_rowstate,dl_custom + [], [], []); + + compatiblelisttypes: array[tfieldtype] of listdatatypety = ( + //ftUnknown,ftString, ftSmallint,ftInteger, ftWord, + dl_none, dl_msestring,dl_integer,dl_integer,dl_integer, + // ftBoolean,ftFloat,ftCurrency,ftBCD, + dl_integer, dl_real,dl_real, dl_currency, + //ftDate, ftTime, ftDateTime, + dl_datetime,dl_datetime,dl_datetime, + //ftBytes, ftVarBytes, ftAutoInc, ftBlob, ftMemo, + dl_ansistring,dl_ansistring,dl_integer,dl_ansistring,dl_msestring, + //ftGraphic, ftFmtMemo, + dl_ansistring,dl_msestring, + //ftParadoxOle,ftDBaseOle,ftTypedBinary,ftCursor,ftFixedChar, + dl_none, dl_none, dl_none, dl_none, dl_msestring, + //ftWideString,ftLargeint,ftADT, ftArray,ftReference, + dl_msestring,dl_int64, dl_none,dl_none,dl_none, + //ftDataSet,ftOraBlob,ftOraClob,ftVariant,ftInterface, + dl_none, dl_none, dl_none, dl_none, dl_none, + //ftIDispatch,ftGuid, ftTimeStamp,ftFMTBcd,ftFixedWideChar,ftWideMemo); + dl_none, dl_none,dl_datetime,dl_real, dl_msestring, dl_msestring + ); + +implementation +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +function matchfielddatatypes(const afielddefs: tfielddefs; + const atype: listdatatypety): msestringarty; +var + int1,int2: integer; +begin + result:= nil; + if afielddefs <> nil then begin + int2:= 0; + setlength(result,afielddefs.count); + for int1:= 0 to afielddefs.count-1 do begin + with afielddefs[int1] do begin + if (atype = dl_none) or + (datatype in listtypecompatibledbtypes[atype]) then begin + result[int2]:= msestring(name); + inc(int2); + end; + end; + end; + setlength(result,int2); + end; +end; + +function fielddefstodatatype(const afielddefs: tfielddefs; + const aname: ansistring): listdatatypety; +var + int1: integer; +begin + result:= dl_none; + for int1:= 0 to afielddefs.count - 1 do begin + with afielddefs[int1] do begin + if name = aname then begin + result:= compatiblelisttypes[datatype]; + break; + end; + end; + end; +end; + +(* +{ tifisqlfieldlinks } + +function tifisqlfieldlinks.getfieldnames( + const adatatype: listdatatypety): msestringarty; +begin + result:= matchfielddatatypes(fowner.fsource.fielddefs,adatatype); +end; + +{ tifisqldatasource } + +constructor tifisqldatasource.create(aowner: tcomponent); +begin + if ffields = nil then begin + ffields:= tifisqlfieldlinks.create; + tifisqlfieldlinks(ffields).fowner:= self; + end; + inherited; +end; + +procedure tifisqldatasource.setsource(const avalue: tsqlresult); +begin + setlinkedvar(avalue,tmsecomponent(fsource)); +end; + +procedure tifisqldatasource.open; +begin + inherited; + if fsource <> nil then begin + fsource.refresh; + end; + afteropen; +end; + +procedure tifisqldatasource.close; +begin + if fsource <> nil then begin + fsource.active:= false; + end; + inherited; +end; + +procedure tifisqldatasource.refresh; +begin + inherited close; + open; +end; +*) +{ tifisqlresult } + +function tifisqlresult.getfieldnames( + const adatatype: listdatatypety): msestringarty; +begin + result:= matchfielddatatypes(fielddefs,adatatype); +end; + +function tifisqlresult.getdatatype(const aname: ansistring): listdatatypety; + //dl_none if not found +begin + result:= fielddefstodatatype(fielddefs,aname); +end; + +procedure tifisqlresult.fetchdata(const acolnames: array of string; + acols: array of tdatalist); +//var +// ar1: datalistarty; +// ar2: integerarty; +// int1: integer; +begin + refresh; + if high(acols) <> high(acolnames) then begin + componentexception(self,'fetchdata() item count mismatch.'); + end; + internalloaddatalists(datacols.colsindexbyname(acolnames),acols); +{ + ar2:= cols.colsindexbyname(acolnames); + if high(ar2) > high(acols) then begin + setlength(ar2,length(acols)); + end; +} + { + setlength(ar1,cols.count); + for int1:= 0 to high(ar2) do begin + ar1[ar2[int1]]:= acols[int1]; + end; +// internalloaddatalists(acols); + } +// internalloaddatalists(ar1,ar2); + active:= false; +end; + +function tifisqlresult.getfieldinfos: dbfieldinfoarty; +var + int1: integer; + def1: tfielddef; +begin + setlength(result,fielddefs.count); + for int1:= 0 to high(result) do begin + def1:= fielddefs[int1]; + with result[int1] do begin + name:= msestring(def1.name); + datatype:= def1.datatype; + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/ifi/mseifidbgui.pas b/mseide-msegui/lib/common/ifi/mseifidbgui.pas new file mode 100644 index 0000000..7f149cd --- /dev/null +++ b/mseide-msegui/lib/common/ifi/mseifidbgui.pas @@ -0,0 +1,228 @@ +{ MSEgui Copyright (c) 2010-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseifidbgui; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,mdb,mseifigui,mseifids,mseifi,msedatalist,msegui,msemenus, + msegrids,mseguiglob,msetypes,mseapplication,msegraphics; +type + tdbrxwidgetgrid = class; + + bindnamesty = array[rowstatememberty] of string; +// rowstatebindingty = array[rowstatememberty] of integer; + + tifidbwidgetgridcontroller = class(tifiwidgetgridcontroller) + private +// frowstatebinding: rowstatebindingty; + fcolbinding: subdatainfoarty; + fnames: bindnamesty; + protected + procedure decoderecord(const aindex: integer; var adatapo: pifidataty); + procedure processdata(const adata: pifirecty; var adatapo: pchar); override; + function getifireckinds: ifireckindsty; override; + function bindnames(const aname: string; var ainfo: subdatainfoty): boolean; + public + constructor create(const aowner: tdbrxwidgetgrid; + const aintf: iactivatorclient); + published + property name_select: string read fnames[rsm_select] write fnames[rsm_select]; + property name_color: string read fnames[rsm_color] write fnames[rsm_color]; + property name_font: string read fnames[rsm_font] write fnames[rsm_font]; + property name_readonly: string read fnames[rsm_readonly] + write fnames[rsm_readonly]; + property name_foldlevel: string read fnames[rsm_foldlevel] + write fnames[rsm_foldlevel]; + property name_foldissum: string read fnames[rsm_foldissum] + write fnames[rsm_foldissum]; + property name_hidden: string read fnames[rsm_hidden] + write fnames[rsm_hidden]; + property name_merged: string read fnames[rsm_merged] + write fnames[rsm_merged]; + property name_height: string read fnames[rsm_height] write fnames[rsm_height]; + end; + + tdbrxwidgetgrid = class(trxwidgetgrid) + private + function getifi1: tifidbwidgetgridcontroller; + procedure setifi1(const avalue: tifidbwidgetgridcontroller); + protected + procedure rowstatechanged(const arow: integer); override; + public + constructor create(aowner: tcomponent); override; + published + property ifi: tifidbwidgetgridcontroller read getifi1 write setifi1; + end; + +implementation +uses + mseifilink; + +{ tifidbwidgetgridcontroller } + +constructor tifidbwidgetgridcontroller.create(const aowner: tdbrxwidgetgrid; + const aintf: iactivatorclient); +begin + inherited create(aowner,aintf); +end; + +function tifidbwidgetgridcontroller.getifireckinds: ifireckindsty; +begin + result:= inherited getifireckinds + [ik_dsdata,ik_fieldrec]; +end; + +procedure tifidbwidgetgridcontroller.decoderecord(const aindex: integer; + var adatapo: pifidataty); +var + int1: integer; +begin + for int1:= 0 to high(fcolbinding) do begin + inc(pchar(adatapo),decodeifidata(adatapo,aindex,fcolbinding[int1])); + end; +end; + +procedure tifidbwidgetgridcontroller.processdata(const adata: pifirecty; + var adatapo: pchar); +var + fielddefs1: tfielddefs; + int1,int2: integer; + index1: integer; +begin + with adata^.header do begin + case kind of + ik_dsdata: begin + fielddefs1:= tfielddefs.create(nil); + try + if decodefielddefs(pfdefdataty(adatapo),fielddefs1,int1) then begin + inc(adatapo,int1); + with tdbrxwidgetgrid(fowner) do begin +// fillchar(frowstatebinding,sizeof(frowstatebinding),0); + fcolbinding:= nil; + setlength(fcolbinding,fielddefs1.count); + for int1:= 0 to high(fcolbinding) do begin + if not bindnames(fielddefs1[int1].name,fcolbinding[int1]) then begin + fcolbinding[int1]:= datacols.colsubdatainfo(fielddefs1[int1].name); + end; + end; + if (igo_state in foptionsrx) or + (answersequence <> 0) and (answersequence = fdatasequence) then begin + beginupdate; + inc(fcommandlock); + try + rowcount:= precdataty(adatapo)^.header.count; + inc(adatapo,sizeof(recdataheaderty)); + for int1:= 0 to rowcount - 1 do begin + decoderecord(int1,pifidataty(adatapo)); + end; + include(fistate,rws_datareceived); + finally + dec(fcommandlock); + endupdate; + end; + end; + end; + end; + finally + fielddefs1.free; + end; + end; + ik_fieldrec: begin + with pfieldrecdataty(adatapo)^.header do begin + index1:= rowindex; + int2:= count; + with tdbrxwidgetgrid(fowner) do begin + case kind of + frk_insert: begin + insertrow(index1); + end; + frk_delete: begin + deleterow(index1); + exit; + end; + end; + end; + end; + adatapo:= @pfieldrecdataty(adatapo)^.data; + inc(fcommandlock); + try + for int1:= 0 to int2 - 1 do begin + with pfielddataty(adatapo)^ do begin + inc(adatapo,decodeifidata(@data,index1,fcolbinding[header.index]) + + sizeof(fielddataheaderty)); + end; + end; + finally + dec(fcommandlock); + end; + end; + else begin + inherited; + end; + end; + end; +end; + +function tifidbwidgetgridcontroller.bindnames(const aname: string; + var ainfo: subdatainfoty): boolean; +var + na1: rowstatememberty; +begin + result:= false; + for na1:= low(rowstatememberty) to high(rowstatememberty) do begin + if fnames[na1] = aname then begin + ainfo.list:= tdbrxwidgetgrid(fowner).datacols.rowstate; + ainfo.subindex:= ord(na1) + 1; + result:= true; + break; + end; + end; +end; + +{ tdbrxwidgetgrid } + +constructor tdbrxwidgetgrid.create(aowner: tcomponent); +begin + fifi:= tifidbwidgetgridcontroller.create(self,iactivatorclient(self)); + inherited; +end; + +function tdbrxwidgetgrid.getifi1: tifidbwidgetgridcontroller; +begin + result:= tifidbwidgetgridcontroller(fifi); +end; + +procedure tdbrxwidgetgrid.setifi1(const avalue: tifidbwidgetgridcontroller); +begin + setifi(avalue); +end; + +procedure tdbrxwidgetgrid.rowstatechanged(const arow: integer); +var + rsm1: rowstatememberty; +begin + with tifidbwidgetgridcontroller(fifi) do begin + if cancommandsend(igo_coldata) then begin + if arow < 0 then begin + //todo + end + else begin + for rsm1:= low(rowstatememberty) to high(rowstatememberty) do begin + if fnames[rsm1] <> '' then begin + senditem(ik_coldatachange,[encodecolchangedata(fnames[rsm1],arow, + fdatacols.rowstate,rsm1)]); + end; + end; + end; + end; + end; + inherited; +end; + +end. diff --git a/mseide-msegui/lib/common/ifi/mseifidialogcomp.pas b/mseide-msegui/lib/common/ifi/mseifidialogcomp.pas new file mode 100644 index 0000000..e13f6ea --- /dev/null +++ b/mseide-msegui/lib/common/ifi/mseifidialogcomp.pas @@ -0,0 +1,153 @@ +{ MSEgui Copyright (c) 2009-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseifidialogcomp; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseificompglob,mseificomp,mseapplication,mseclasses,mseglob,mseact,mserttistat; + +type + + beforedialogeventty = procedure(const sender: tobject; + const adialog: tactcomponent) of object; + afterdialogeventty = procedure(const sender: tobject; + const adialog: tactcomponent; + const amodalresult: modalresultty) of object; + + ifidialoginfoty = record + modalresult: modalresultty; + dialog: tactcomponent; + end; + pifidialoginfoty = ^ifidialoginfoty; + + tdialogclientcontroller = class(tcustomificlientcontroller) + private + fonbeforedialog: beforedialogeventty; + fonafterdialog: afterdialogeventty; + finfopo: pifidialoginfoty; + faction: tcustomaction; + frttistat: tcustomrttistat; + procedure execdialog(const alink: pointer; var handled: boolean); + procedure setaction(const avalue: tcustomaction); + procedure setrttistat(const avalue: tcustomrttistat); + protected + procedure beforedialog(const adialog: tactcomponent); + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + public + function execute: modalresultty; reintroduce; + published + property onbeforedialog: beforedialogeventty read fonbeforedialog + write fonbeforedialog; + property onafterdialog: afterdialogeventty read fonafterdialog + write fonafterdialog; + property action: tcustomaction read faction write setaction; + property rttistat: tcustomrttistat read frttistat write setrttistat; + end; + + tifidialoglinkcomp = class(tifilinkcomp) + private + function getcontroller: tdialogclientcontroller; + procedure setcontroller(const avalue: tdialogclientcontroller); + protected + function getcontrollerclass: customificlientcontrollerclassty; override; + published + property controller: tdialogclientcontroller read getcontroller + write setcontroller; + end; + +implementation +type + tmsecomponent1 = class(tmsecomponent); + +{ tdialogclientcontroller } + +procedure tdialogclientcontroller.beforedialog(const adialog: tactcomponent); +begin + if frttistat <> nil then begin + frttistat.objtovalues(adialog); + end; + if fowner.canevent(tmethod(fonbeforedialog)) then begin + fonbeforedialog(self,adialog); + end; +end; + +procedure tdialogclientcontroller.execdialog(const alink: pointer; + var handled: boolean); +begin + handled:= true; + with finfopo^ do begin + modalresult:= iifidialoglink(alink).showdialog(dialog); + if (modalresult = mr_ok) and (frttistat <> nil) then begin + frttistat.valuestoobj(dialog); + end; + if fowner.canevent(tmethod(fonafterdialog)) then begin + fonafterdialog(self,dialog,modalresult); + end; + end; +end; + +function tdialogclientcontroller.execute: modalresultty; +var + info1: ifidialoginfoty; + po1: pifidialoginfoty; +begin + po1:= finfopo; + fillchar(info1,sizeof(info1),0); + finfopo:= @info1; + try + tmsecomponent1(fowner).getobjectlinker.forfirst( + {$ifdef FPC}@{$endif}execdialog,self); + result:= info1.modalresult; + finally + info1.dialog.release; + finfopo:= po1; + end; +end; + +procedure tdialogclientcontroller.setaction(const avalue: tcustomaction); +begin + setlinkedvar(avalue,tmsecomponent(faction)); +end; + +procedure tdialogclientcontroller.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (event = oe_fired) and (sender = faction) then begin + execute; + end; +end; + +procedure tdialogclientcontroller.setrttistat(const avalue: tcustomrttistat); +begin + setlinkedvar(avalue,tmsecomponent(frttistat)); +end; + +{ tifidialoglinkcomp } + +function tifidialoglinkcomp.getcontrollerclass: + customificlientcontrollerclassty; +begin + result:= tdialogclientcontroller; +end; + +function tifidialoglinkcomp.getcontroller: tdialogclientcontroller; +begin + result:= tdialogclientcontroller(inherited controller); +end; + +procedure tifidialoglinkcomp.setcontroller( + const avalue: tdialogclientcontroller); +begin + inherited setcontroller(avalue); +end; + +end. diff --git a/mseide-msegui/lib/common/ifi/mseifids.pas b/mseide-msegui/lib/common/ifi/mseifids.pas new file mode 100644 index 0000000..2d7a2c4 --- /dev/null +++ b/mseide-msegui/lib/common/ifi/mseifids.pas @@ -0,0 +1,3100 @@ +{ MSEgui Copyright (c) 2007-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseifids; +{$if defined(FPC) and (fpc_fullversion >= 020200)} + {$define mse_FPC_2_2} +{$ifend} +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses,mdb,mseifi,mseclasses,mseglob,mseevent,msedb,msetypes, + msebufdataset,msehash, + msestrings,mseifilink,msesqldb,msearrayprops,mseapplication; + + +type + ififieldoptionty = (ifo_local); + ififieldoptionsty = set of ififieldoptionty; +(* + recheaderty = record + blobinfo: pointer; //dummy + fielddata: fielddataty; + end; + precheaderty = ^recheaderty; + + intheaderty = record + end; + + intrecordty = record + intheader: intheaderty; + header: recheaderty; + end; + pintrecordty = ^intrecordty; + + bookmarkdataty = record + recno: integer; + recordpo: pintrecordty; + end; + pbookmarkdataty = ^bookmarkdataty; + + bufbookmarkty = record + data: bookmarkdataty; + flag : tbookmarkflag; + end; + pbufbookmarkty = ^bufbookmarkty; + + dsheaderty = record + bookmark: bufbookmarkty; + end; + dsrecordty = record + dsheader: dsheaderty; + header: recheaderty; + end; + pdsrecordty = ^dsrecordty; +*) +const +{$ifdef FPC} + intheadersize = sizeof(intrecordty.intheader); + dsheadersize = sizeof(dsrecordty.dsheader); +{$else} + intheadersize = sizeof(intheaderty); + dsheadersize = sizeof(dsheaderty); +{$endif} +type + +// structure of internal recordbuffer: +// +------------------+ +// intrecheaderty, |recheaderty,fielddata | +// |moved to tdataset buffer header| +// |fieldoffsets are in ffieldinfos[].offset +// | | +// structure of dataset recordbuffer: +// +--------------------------------+ +// +------------------+ | +// dsrecheaderty, |recheaderty,fielddata |calcfields | +// |moved to internal buffer header| | +// |<-field offsets are in ffieldinfos[].offset | +// |<-calcfield offsets are in fcalcfieldbufpositions| + + ifidsstatety = (ids_openpending,ids_fielddefsreceived,ids_remotedata, + ids_updating,ids_append,ids_sendpostresult,ids_postpending); + ifidsstatesty = set of ifidsstatety; +type + iifidscontroller = interface(iactivatorclient) + function getfielddefs: tfielddefs; + function getfieldinfos: fieldinfoarty; + procedure requestopendsreceived(const asequence: sequencety); + procedure fielddefsdatareceived( const asequence: sequencety; + const adata: pfielddefsdatadataty); + procedure dsdatareceived( const asequence: sequencety; + const adata: pfielddefsdatadataty); + procedure cancelconnection; + function getmodifiedfields: string; + procedure initmodifiedfields; + function setcurrentbuf(const abuf: pintrecordty): pintrecordty; + end; + + tififieldoptions = class(tsetarrayprop) + end; + + tpostechoevent = class(tobjectevent) + private + fmodifiedfields: string; + fbookmark: string; + public + constructor create(const amodifiedfields: string; const abookmark:string; + const dest: ievent); + end; + + changedataty = record + header: ptruintdataty; + data: record end; //array of byte for change flags + end; + changehashdataty = record + header: hashheaderty; + data: changedataty; + end; + pchangehashdataty = ^changehashdataty; + + tcurrentchangedlist = class(tptruinthashdatalist) + private + fnullmasksize: int32; + protected + function getrecordsize(): int32 override; + public + constructor create(const anullmasksize: integer); + procedure fieldchanged(const afield: tfield; const aindex: integer); + end; + + ifioptiondbty = (iod_autopost); + ifioptionsdbty = set of ifioptiondbty; + + tifidscontroller = class(tificontroller,ievent) + private +// fintf: iifidscontroller; + fremotedatachange: notifyeventty; + fpostsequence: sequencety; + fpostcode: postresultcodety; + fpostmessage: msestring; + frxbindings: integerarty; + ftxbindings: integerarty; + foptionsdb: ifioptionsdbty; + protected + fistate: ifidsstatesty; + fdscontroller: tdscontroller; + procedure requestfielddefsreceived(const asequence: sequencety); + procedure processfieldrecdata(const asequence: sequencety; + const adata: pfieldrecdataty); + procedure processdata(const adata: pifirecty; var adatapo: pchar); + override; + function getifireckinds: ifireckindsty; override; + procedure doremotedatachange; + function encodefielddefs: string; + procedure postrecord1(const akind: fieldreckindty; + const amodifiedfields: pbyte); + procedure receiveevent(const event: tobjectevent); + procedure sendchangedrecord(const aitem: pchangehashdataty); + procedure setowneractive(const avalue: boolean); override; + public + constructor create(const aowner: tdataset; const aintf: iifidscontroller); + destructor destroy; override; + function getfield(const aindex: integer): tfield; + function encoderecord(const aindex: integer; + const recpo: pintrecordty): string; + function encoderecords(const arecordcount: integer; + const abufs: pointerarty): string; + procedure sendpostresult(const asequence: sequencety; + const acode: postresultcodety; const amessage: msestring); + procedure sendchangedrecords(const alist: tcurrentchangedlist); + procedure post; + procedure delete; + procedure opened; + procedure closed; + procedure updaterxbindings; + published + property remotedatachange: notifyeventty read fremotedatachange + write fremotedatachange; + property optionsdb: ifioptionsdbty read foptionsdb write foptionsdb + default []; + end; + + tifidataset = class(tdataset,idscontroller,igetdscontroller,imselocate, + iifidscontroller,iifimodulelink,iactivatorclient) + private +// fifimodulelink: iifimodulelink; +// property ifimodulelink: iifimodulelink read fifimodulelink +// implements iifimodulelink; + //compiler crash +// fstrings: integerarty; +// fmsestrings: integerarty; + fcontroller: tdscontroller; + fificontroller: tifidscontroller; + fmsestringpositions: integerarty; + fansistringpositions: integerarty; + Ffieldinfos: fieldinfoarty; + frecordsize: integer; + fcalcrecordsize: integer; + fnullmasksize: integer; + fmodifiedfields: string; //same layout as nullmask + + frecno: integer; + fbrecordcount: integer; //always 1 if open + fcurrentbuf: pintrecordty; + fbufs: pointerarty; + fopen: boolean; + +// fremotedatachange: notifyeventty; +// foptions: ifirxoptionsty; + fupdating: integer; + procedure initmodifiedfields; + procedure setcontroller(const avalue: tdscontroller); + function getcontroller: tdscontroller; + //idscontroller + procedure inheritedresync(const mode: tresyncmode); + procedure inheriteddataevent(const event: tdataevent; const info: ptrint); + procedure inheritedcancel; + procedure inheritedpost; + procedure inheriteddelete(); + procedure inheritedinsert(); + function inheritedmoveby(const distance: integer): integer; + procedure inheritedinternalinsert; + procedure inheritedinternaldelete; + procedure inheritedinternalopen; virtual; + procedure inheritedinternalclose; + function getblobdatasize: integer; + function getnumboolean: boolean; + function getfloatdate: boolean; + function getint64currency: boolean; + function getsavepointoptions(): savepointoptionsty; + + function intallocrecord: pintrecordty; + procedure finalizestrings(var header: recheaderty); + procedure finalizecalcstrings(var header: recheaderty); + procedure finalizechangedstrings(const tocompare: recheaderty; + var tofinalize: recheaderty); + procedure addrefstrings(var header: recheaderty); + procedure intfinalizerecord(const buffer: pintrecordty); + procedure intfreerecord(var buffer: pintrecordty); + procedure internalsetrecno(const avalue: integer); + function findrecord(arecordpo: pintrecordty): integer; reintroduce; + //returns index, -1 if not found + function getfiltereditkind: filtereditkindty; + procedure beginfilteredit(const akind: filtereditkindty); + procedure endfilteredit; + procedure clearfilter; +// procedure doidleapplyupdates; + + procedure setificountroller(const avalue: tifidscontroller); + function getifistate: ifidsstatesty; + function getrestorerecno: boolean; + procedure setrestorerecno(const avalue: boolean); + protected + ffielddefsequence: sequencety; + procedure checkrecno(const avalue: integer); +// procedure dscontrolleroptionschanged(const aoptions: datasetoptionsty); + + //iifidscontroller + function updatesortfield(const afield: tfield; + const adescend: boolean): boolean; + function getfielddefs: tfielddefs; + function getfieldinfos: fieldinfoarty; + procedure requestfielddefsreceived(const asequence: sequencety); virtual; + procedure requestopendsreceived(const asequence: sequencety); virtual; + procedure fielddefsdatareceived( const asequence: sequencety; + const adata: pfielddefsdatadataty); virtual; + procedure dsdatareceived( const asequence: sequencety; + const adata: pfielddefsdatadataty); virtual; + function getmodifiedfields: string; + function setcurrentbuf(const abuf: pintrecordty): pintrecordty; + + procedure decoderecord(var adata: pointer; const dest: pintrecordty); + function decoderecords(const adata: precdataty; out asize: integer): boolean; + + procedure notimplemented(const atext: string); + + procedure bindfields(const bind: boolean); + function AllocRecordBuffer: PChar; override; + procedure FreeRecordBuffer(var Buffer: PChar); override; + procedure GetBookmarkData(Buffer: PChar; Data: Pointer); override; + function GetBookmarkFlag(Buffer: PChar): TBookmarkFlag; override; + function GetRecord(Buffer: PChar; GetMode: TGetMode; + DoCheck: Boolean): TGetResult; override; + function GetRecordSize: Word; override; + function getrecno: integer; override; + procedure setrecno(value: longint); override; + function GetRecordCount: Longint; override; + + function getfieldbuffer(const afield: tfield; + out buffer: pointer; out datasize: integer): boolean; overload; + //read, true if not null + function getfieldbuffer(const afield: tfield; + const isnull: boolean; out datasize: integer): pointer; overload; + //write + function getmsestringdata(const sender: tmsestringfield; + out avalue: msestring): boolean; + procedure setmsestringdata(const sender: tmsestringfield; avalue: msestring); + + procedure dataevent(event: tdataevent; info: ptrint); override; + + procedure InternalCancel; override; + procedure internaledit; override; + procedure InternalRefresh; override; + + procedure InternalAddRecord(Buffer: Pointer; AAppend: Boolean); override; + procedure InternalClose; override; + procedure InternalDelete; override; + procedure InternalFirst; override; + procedure InternalGotoBookmark(ABookmark: Pointer); override; +// procedure InternalHandleException; override; + procedure InternalInitFieldDefs; override; + procedure InternalInitRecord(Buffer: PChar); override; + procedure InternalLast; override; + procedure InternalOpen; override; + procedure InternalPost; override; + procedure InternalSetToRecord(Buffer: PChar); override; + function IsCursorOpen: Boolean; override; + procedure SetBookmarkFlag(Buffer: PChar; Value: TBookmarkFlag); override; + procedure SetBookmarkData(Buffer: PChar; Data: Pointer); override; + function getcanmodify: boolean; override; + + procedure cancelconnection; + procedure calcrecordsize; + + procedure setactive (const value : boolean);{ override;} reintroduce; + function getactive: boolean; + procedure loaded; override; + function getfieldclass(fieldtype: tfieldtype): tfieldclass; override; + procedure openlocal; + procedure internalinsert; override; + procedure begindisplaydata; + procedure enddisplaydata; + //iifimodulelink + procedure connectmodule(const sender: tcustommodulelink); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure beginupdate; + procedure endupdate; + + procedure Append; + function locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; + reintroduce; +{ + function locate(const key: integer; const field: tfield; + const options: locateoptionsty = []): locateresultty; + function locate(const key: string; const field: tfield; + const options: locateoptionsty = []): locateresultty; +} + function getfielddata(field: tfield; buffer: pointer; + nativeformat: boolean): boolean; override; + function getfielddata(field: tfield; buffer: pointer): boolean; override; + procedure setfielddata(field: tfield; buffer: pointer); override; + procedure setfielddata(field: tfield; buffer: pointer; + nativeformat: boolean); override; + procedure AppendRecord(const Values: array of const); + procedure cancel; override; + procedure post; override; + function moveby(const distance: integer): integer; + function islastrecord: boolean; + property ifistate: ifidsstatesty read getifistate; + published + property controller: tdscontroller read fcontroller write setcontroller; + property Active: boolean read getactive write setactive default false; + property ifi: tifidscontroller read fificontroller write setificountroller; + + property BeforeOpen; + property AfterOpen; + property BeforeClose; + property AfterClose; + property BeforeInsert; + property AfterInsert; + property BeforeEdit; + property AfterEdit; + property BeforePost; + property AfterPost; + property BeforeCancel; + property AfterCancel; + property BeforeDelete; + property AfterDelete; + property BeforeScroll; + property AfterScroll; + property OnCalcFields; + property OnDeleteError; + property OnEditError; + property OnFilterRecord; + property OnNewRecord; + property OnPostError; + property onmodified; + property AutoCalcFields default false; + end; + + trxdataset = class(tifidataset,iifitxaction) + private + procedure inheritedinternalopen; override; + protected + procedure txactionfired(var adata: ansistring; var adatapo: pchar); + procedure fielddefsdatareceived(const asequence: sequencety; + const adata: pfielddefsdatadataty); override; + procedure dsdatareceived(const asequence: sequencety; + const adata: pfielddefsdatadataty); override; + published + property fielddefs; + end; + + ttxdataset = class(tifidataset) + private + protected + procedure requestopendsreceived(const asequence: sequencety); override; +// procedure inheritedinternalopen; override; + public + constructor create(aowner: tcomponent); override; + published + property fielddefs; + end; + + ttxsqlquery = class(tmsesqlquery,iifidscontroller,iactivatorclient) + private + fificontroller: tifidscontroller; + fmodifiedfields: string; //same layout as nullmask + fclientbefporeopen: tdatasetnotifyevent; + fclientbeforeopen: tdatasetnotifyevent; + fclientafteropen: tdatasetnotifyevent; + fcurrentchanged: tcurrentchangedlist; + procedure setificontroller(const avalue: tifidscontroller); + procedure initmodifiedfields; + protected + + procedure currentrecordupdated(const aindex: integer); + + procedure internalopen; override; + procedure internalclose; override; + procedure InternalPost; override; + function getfieldbuffer(const afield: tfield; + const aisnull: boolean; out datasize: integer): pointer; override; + procedure iactivatorclient.setactive = setcontrolleractive; + procedure iifidscontroller.setactive = setcontrolleractive; + //iifids + function getfielddefs: tfielddefs; + function getfieldinfos: fieldinfoarty; + procedure requestopendsreceived(const asequence: sequencety); + procedure fielddefsdatareceived( const asequence: sequencety; + const adata: pfielddefsdatadataty); + procedure dsdatareceived( const asequence: sequencety; + const adata: pfielddefsdatadataty); + function getmodifiedfields: string; + function setcurrentbuf(const abuf: pintrecordty): pintrecordty; + procedure aftercurrentset(const afield: tfield); override; + + procedure cancelconnection; + procedure internaledit; override; + procedure inheritedinternalinsert; override; + procedure inheritedinternaldelete; override; + procedure fixupcurrentset; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure currentbeginupdate; override; + procedure currentendupdate; override; +// procedure deccurrentupdate; override; + published + property ifi: tifidscontroller read fificontroller write setificontroller; + property clientbeforeopen: tdatasetnotifyevent read fclientbefporeopen + write fclientbeforeopen; + property clientafteropen: tdatasetnotifyevent read fclientafteropen + write fclientafteropen; + end; + + fdefitemty = record + datatype: tfieldtype; + size: integer; + name: ifinamety; + end; + pfdefitemty = ^fdefitemty; + fdefdataty = record + count: integer; + items: datarecty; //dummy + end; + pfdefdataty = ^fdefdataty; + +procedure loadtxdatagridfromdataset(const agrid: ttxdatagrid; + const asource: tdataset); +function decodefielddefs(const adata: pfdefdataty; + const fielddefs: tfielddefs; out asize: integer): boolean; + +implementation +uses + sysutils,msearrayutils,msedatalist, + {$ifdef FPC}dbconst{$else}dbconst_del{$endif},msereal; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +type + tmsestringfield1 = class(tmsestringfield); + tdataset1 = class(tdataset); + +const + ifidskinds = [ik_requestfielddefs,ik_requestopen,ik_fielddefsdata, + ik_fieldrec,ik_dsdata,ik_postresult,ik_coldatachange, + ik_gridcommand]; + openflags = [ids_openpending,ids_fielddefsreceived,ids_append]; + +type + ttxdatagrid1 = class(ttxdatagrid); + +fieldtoificolprocty = procedure(const acol: tifidatacol; const aindex: integer; + const afield: tfield); +fieldtoificolprocarty = array of fieldtoificolprocty; + +procedure storemsestringfield(const acol: tifidatacol; const aindex: integer; + const afield: tfield); +begin + acol.asmsestring[aindex]:= tmsestringfield(afield).asmsestring; +end; + +procedure storestringfield(const acol: tifidatacol; const aindex: integer; + const afield: tfield); +begin + acol.asmsestring[aindex]:= msestring(afield.asstring); +end; + +procedure storelongintfield(const acol: tifidatacol; const aindex: integer; + const afield: tfield); +begin + acol.asinteger[aindex]:= afield.aslongint; +end; + +procedure storelargintfield(const acol: tifidatacol; const aindex: integer; + const afield: tfield); +begin + acol.asint64[aindex]:= afield.aslargeint; +end; + +procedure storefloatfield(const acol: tifidatacol; const aindex: integer; + const afield: tfield); +begin + if afield.isnull then begin + acol.asreal[aindex]:= emptyreal; + end + else begin + acol.asreal[aindex]:= afield.asfloat; + end; +end; + +procedure storebcdfield(const acol: tifidatacol; const aindex: integer; + const afield: tfield); +begin + acol.ascurrency[aindex]:= afield.ascurrency; +end; + +procedure loadtxdatagridfromdataset(const agrid: ttxdatagrid; + const asource: tdataset); +type + fieldlinkinfoty = record + col: tifidatacol; + field: tfield; + proc: fieldtoificolprocty; + end; + fieldlinkinfoarty = array of fieldlinkinfoty; + +var + bm: string; + ar1: fieldlinkinfoarty; + int1,int2: integer; + str1: string; + bo1: boolean; +begin + setlength(ar1,agrid.datacols.count); //max + int2:= 0; + for int1:= 0 to high(ar1) do begin + bo1:= false; + with ar1[int2] do begin + col:= agrid.datacols[int1]; + str1:= col.name; + if str1 <> '' then begin + field:= asource.findfield(str1); + if field <> nil then begin + bo1:= true; + if field is tmsestringfield then begin + proc:= @storemsestringfield; + end + else begin + case field.datatype of + ftboolean,ftsmallint,ftinteger,ftword: begin + proc:= @storelongintfield; + end; + ftstring: begin + proc:= @storestringfield; + end; + ftbcd: begin + proc:= @storebcdfield; + end; + ftfloat,fttime,ftdate,ftdatetime: begin + proc:= @storefloatfield; + end; + else begin + bo1:= false; + end; + end; + end; + end; + end; + if bo1 then begin + inc(int2); + end; + end; + end; + setlength(ar1,int2); + + with ttxdatagrid1(agrid) do begin + asource.disablecontrols; + bm:= asource.bookmark; + try + beginupdate; + try + clear; + asource.first; + int2:= 0; + while not asource.eof do begin + agrid.rowcount:= int2+1; + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + proc(col,int2,field); + end; + end; + asource.next; + inc(int2); + end; + finally + endupdate; + end; + finally + asource.bookmark:= bm; + asource.enablecontrols; + end; + end; +end; + +function decodefielddefs(const adata: pfdefdataty; + const fielddefs: tfielddefs; out asize: integer): boolean; +var + po1: pchar; + int1: integer; + str1: string; + datatype1: tfieldtype; + size1: integer; +begin + fielddefs.clear; + po1:= @adata^.items; + for int1:= 0 to adata^.count - 1 do begin + datatype1:= pfdefitemty(po1)^.datatype; + size1:= pfdefitemty(po1)^.size; + po1:= @pfdefitemty(po1)^.name; + inc(po1,ifinametostring(pifinamety(po1),str1)); + tfielddef.create(fielddefs,str1,datatype1,size1,false,int1+1); + end; + asize:= pchar(pointer(po1)) - pchar(pointer(adata)); + result:= true; +end; + +function decodepostresult(const adata: ppostresultdataty; + out acode: postresultcodety; + out amessage: msestring): boolean; +var + str1: string; +begin + result:= true; + with adata^ do begin + acode:= code; + ifinametostring(@message,str1); + amessage:= utf8tostringansi(str1); + end; +end; + +function encodefielddata(const ainfo: fieldinfoty; const headersize: integer): string; +begin + with ainfo,base,ext do begin + if field.isnull then begin + result:= encodeifinull(headersize); + end + else begin + case fieldtype of + ftinteger: begin + result:= encodeifidata(field.asinteger,headersize); + end; + ftlargeint: begin + result:= encodeifidata(field.aslargeint,headersize); + end; + ftfloat,ftcurrency: begin + {$ifdef FPC} + result:= encodeifidata(field.asfloat,headersize); + {$else} + result:= encodeifidatareal(field.asfloat,headersize); + {$endif} + end; + ftbcd: begin + {$ifdef FPC} + result:= encodeifidata(field.ascurrency,headersize); + {$else} + result:= encodeifidatareal(field.ascurrency,headersize); + {$endif} + end; + ftblob,ftgraphic,ftmemo: begin + result:= encodeifidata(field.asstring,headersize); + end; + ftstring: begin + if field is tmsestringfield then begin + result:= encodeifidata(tmsestringfield(field).asmsestring,headersize); + end + else begin + result:= encodeifidata(msestring(field.asstring),headersize); + end; + end; + else begin + result:=''; + exit; + end; + end; + end; + end; +end; + +{ tpostechoevent } + +constructor tpostechoevent.create(const amodifiedfields: string; + const abookmark: string; const dest: ievent); +begin + fmodifiedfields:= amodifiedfields; + setlength(fmodifiedfields,length(fmodifiedfields)); //unique + fbookmark:= abookmark; + inherited create(ek_mse,dest); +end; + +{ tifidscontroller } + +constructor tifidscontroller.create(const aowner: tdataset; + const aintf: iifidscontroller); +var + intf1: igetdscontroller; +begin +// fintf:= aintf; + if getcorbainterface(aowner,typeinfo(igetdscontroller),intf1) then begin + fdscontroller:= intf1.getcontroller; + end; +// ffieldoptions:= tififieldoptions.create(typeinfo(ififieldoptionsty)); + inherited create(aowner,aintf); +end; + +destructor tifidscontroller.destroy; +begin + inherited; +// ffieldoptions.free; +end; + +function tifidscontroller.encodefielddefs: string; +var + int1,int2: integer; + po1: pchar; + infos: fieldinfoarty; +begin + int2:= 0; + infos:= iifidscontroller(fintf).getfieldinfos; + for int1:= 0 to high(ftxbindings) do begin + int2:= int2 + length(infos[ftxbindings[int1]].ext.field.fieldname); + end; + setlength(result,sizeof(fdefdataty)+length(ftxbindings)*sizeof(fdefitemty)+ + int2*6); //max + with pfdefdataty(result)^ do begin + count:= length(ftxbindings); + po1:= @items; + end; + for int1:= 0 to high(ftxbindings) do begin + with infos[ftxbindings[int1]],base,ext do begin + pfdefitemty(po1)^.datatype:= fieldtype; + pfdefitemty(po1)^.size:= dbfieldsize; + po1:= @pfdefitemty(po1)^.name; + inc(po1,stringtoifiname(field.fieldname,pifinamety(po1))); + end; + end; + setlength(result,pchar(pointer(po1))-pchar(pointer(result))); +end; + +procedure tifidscontroller.postrecord1(const akind: fieldreckindty; + const amodifiedfields: pbyte); + function encodefdat(const ainfo: fieldinfoty; const aindex: integer): string; + begin + result:= encodefielddata(ainfo,sizeof(fielddataheaderty)); + if result <> '' then begin + with pfielddataty(result)^ do begin + header.index:= aindex; + end; + end; + end; + +var + int1,int2,int3: integer; + str1: string; + ar1: stringarty; + po1: pfieldrecdataty; + po2: pchar; +// modifiedfields: pbyte; + fieldinfos1: fieldinfoarty; + index1: integer; + +begin //postrecord + fieldinfos1:= iifidscontroller(fintf).getfieldinfos; + setlength(ar1,length(fieldinfos1)); //max + int2:= 0; + int3:= 0; + if akind <> frk_delete then begin +// modifiedfields:= pbyte(amodifiedfields); + for int1:= 0 to high(ftxbindings) do begin + index1:= ftxbindings[int1]; + if getfieldflag(amodifiedfields,index1) then begin + ar1[int2]:= encodefdat(fieldinfos1[index1],int1); + if ar1[int2] <> '' then begin + inc(int2); + end; + end; + end; + for int1:= 0 to int2 - 1 do begin + int3:= int3 + length(ar1[int1]); + end; + end; + inititemheader(str1,ik_fieldrec,0,int3+sizeof(fieldrecdataty), + pchar(po1)); + po1^.header.kind:= akind; + po1^.header.rowindex:= fdscontroller.recnozerobased; + po1^.header.count:= int2; + po2:= @po1^.data; + for int1:= 0 to int2 - 1 do begin + int3:= length(ar1[int1]); + move(ar1[int1][1],po2^,int3); + inc(po2,int3); + end; + if not (ids_sendpostresult in fistate) then begin + include(fistate,ids_postpending); + fpostsequence:= 0; + fpostcode:= pc_none; + if not senddataandwait(str1,fpostsequence) then begin + exclude(fistate,ids_postpending); + application.errormessage('Timeout.'); + iifidscontroller(fintf).cancelconnection; + end + else begin + if (fpostcode <> pc_ok) then begin + exclude(fistate,ids_postpending); + application.errormessage(fpostmessage); + tdataset(fowner).refresh; //todo: optimize + end; + end; + exclude(fistate,ids_postpending); + end + else begin + senddata(str1); + end; +end; + +procedure tifidscontroller.post; +begin + if fistate * [ids_remotedata,ids_updating] = [] then begin + if tdataset(fowner).state = dsinsert then begin + postrecord1(frk_insert,pbyte(iifidscontroller(fintf).getmodifiedfields)); + end + else begin + postrecord1(frk_edit,pbyte(iifidscontroller(fintf).getmodifiedfields)); + end; + exclude(fistate,ids_append); + iifidscontroller(fintf).initmodifiedfields; + end; +end; + +procedure tifidscontroller.sendchangedrecord(const aitem: pchangehashdataty); +begin + fdscontroller.recnozerobased:= aitem^.data.header.key; + postrecord1(frk_edit,@(aitem^.data.data)); +// postrecord1(frk_edit,pbyte(@aitem.data)); +end; + +procedure tifidscontroller.sendchangedrecords(const alist: tcurrentchangedlist); +//var +// int1: integer; +begin + if alist.count > 0 then begin + fdscontroller.beginupdate; + try + alist.iterate(hashiteratorprocty(@sendchangedrecord)); + finally + fdscontroller.endupdate; + end; + end; +end; + +procedure tifidscontroller.delete; +begin + if fistate * [ids_remotedata,ids_updating] = [] then begin + postrecord1(frk_delete,nil); + iifidscontroller(fintf).initmodifiedfields; + end; +end; + +procedure tifidscontroller.doremotedatachange; +begin + if checkcanevent(fowner,tmethod(fremotedatachange)) then begin + fremotedatachange(fowner); + end; +end; + +procedure tifidscontroller.requestfielddefsreceived(const asequence: sequencety); +var + str1,str2: ansistring; + po1: pchar; +begin + str2:= encodefielddefs; + inititemheader(str1,ik_fielddefsdata,asequence,length(str2),po1); + with pfielddefsdatadataty(po1)^ do begin + move(str2[1],data,length(str2)); + end; + senddata(str1); +end; + +procedure tifidscontroller.receiveevent(const event: tobjectevent); +var + bm1: ansistring; +begin + if (event.kind = ek_mse) and (event is tpostechoevent) then begin + with tdataset(fowner),tpostechoevent(event) do begin + bm1:= bookmark; + try + bookmark:= fbookmark; + postrecord1(frk_edit,pbyte(fmodifiedfields)); + except + end; + bookmark:= bm1; + end; + end; +end; + +function ifidatatofield(const datapo: pifidataty; const afield: tfield): integer; +var + str1: string; + mstr1: msestring; + integer1: integer; + int641: int64; + rea1: real; + cu1: currency; + realint1: realintty; +begin + result:= 0; + case datapo^.header.kind of + idk_null: begin + afield.clear; + result:= sizeof(ifidataty); + end; + idk_integer: begin + result:= decodeifidata(datapo,integer1); + afield.asinteger:= integer1; + end; + idk_int64: begin + result:= decodeifidata(datapo,int641); + afield.aslargeint:= int641; + end; + idk_real: begin + result:= decodeifidata(datapo,rea1); + afield.asfloat:= rea1; + end; + idk_realint: begin + result:= decodeifidata(datapo,realint1); + afield.asfloat:= realint1.rea; + end; + idk_currency: begin + result:= decodeifidata(datapo,cu1); + afield.ascurrency:= cu1; + end; + idk_bytes: begin + result:= decodeifidata(datapo,str1); + afield.asstring:= str1; + end; + idk_msestring: begin + result:= decodeifidata(datapo,mstr1); + afield.aswidestring:= mstr1; + { + if afield is tmsestringfield then begin + tmsestringfield(afield).asmsestring:= mstr1; + end + else begin + afield.asstring:= mstr1; + end; + } + end; + end; +end; + +procedure tifidscontroller.processfieldrecdata(const asequence: sequencety; + const adata: pfieldrecdataty); +var + int1: integer; + index1: integer; + po1: pchar; + str1: string; +// field1: tfield; + bo1: boolean; + bm: ansistring; + ar1: fieldinfoarty; +begin + with tdataset(fowner) do begin + if active then begin + try + checkbrowsemode; +// disablecontrols; + ar1:= iifidscontroller(fintf).getfieldinfos; + bm:= bookmark; + include(fistate,ids_remotedata); + try + if adata^.header.kind = frk_delete then begin + fdscontroller.recnozerobased:= adata^.header.rowindex; + delete; + end + else begin + bo1:= adata^.header.kind = frk_insert; + if bo1 then begin + if adata^.header.rowindex >= recordcount-1 then begin + append; + end + else begin + fdscontroller.recnozerobased:= adata^.header.rowindex; + insert; + end; + end + else begin + fdscontroller.recnozerobased:= adata^.header.rowindex; + edit; + end; + po1:= @adata^.data; + for int1:= 0 to adata^.header.count - 1 do begin + index1:= pfielddataty(po1)^.header.index; + if (index1 >= 0) and (index1 <= high(frxbindings)) then begin + with ar1[frxbindings[index1]],base,ext do begin + {$ifdef FPC} + inc(po1,sizeof(mseifi.fielddataty.header)); + {$else} + inc(po1,sizeof(mseifi.fielddataheaderty)); + {$endif} + inc(po1,ifidatatofield(pifidataty(po1),field)); + clearfieldflag(pbyte(iifidscontroller(fintf).getmodifiedfields),index1); + //reset changeflag + end; + end; + end; + iifidscontroller(fintf).initmodifiedfields; //init for postecho + post; + end; + if (irxo_postecho in foptions) and + (adata^.header.kind in [frk_insert,frk_edit]) then begin + str1:= iifidscontroller(fintf).getmodifiedfields; + if not isnullstring(str1) then begin + application.postevent(tpostechoevent.create(str1,bookmark, + ievent(self))); + end; + end; + doremotedatachange; + finally + try + bookmark:= bm; + except + end; + exclude(fistate,ids_remotedata); +// enablecontrols; + end; + if ids_sendpostresult in fistate then begin + sendpostresult(asequence,pc_ok,''); + end; + except + on e: exception do begin + if ids_sendpostresult in fistate then begin + sendpostresult(asequence,pc_error,msestring(e.message)); + end; + end; + end; + end + else begin + if ids_sendpostresult in fistate then begin + sendpostresult(asequence,pc_error,'Dataset inactive.'); + end; + end; + end; +end; + +procedure tifidscontroller.processdata(const adata: pifirecty; var adatapo: pchar); +var + int1: integer; + str1: string; + field1: tfield; + ckind1: gridcommandkindty; + source1,dest1,count1: integer; +begin + with adata^ do begin + case header.kind of + ik_requestfielddefs: begin + requestfielddefsreceived(header.sequence); + end; + ik_requestopen: begin + iifidscontroller(fintf).requestopendsreceived(header.sequence); + end; + ik_fielddefsdata: begin + iifidscontroller(fintf).fielddefsdatareceived(header.answersequence, + pfielddefsdatadataty(adatapo)); + end; + ik_dsdata: begin + iifidscontroller(fintf).dsdatareceived(header.answersequence,pfielddefsdatadataty(adatapo)); + end; + ik_postresult: begin + if (ids_postpending in fistate) and + (header.answersequence = fpostsequence) then begin + decodepostresult(ppostresultdataty(adatapo),fpostcode,fpostmessage); + end; + end; + ik_fieldrec: begin + processfieldrecdata(header.sequence,pfieldrecdataty(adatapo)); + end; + ik_coldatachange: begin + int1:= pcolitemdataty(adatapo)^.header.row; + ifinametostring(@pcolitemdataty(adatapo)^.header.name,str1); + adatapo:= pchar(@pcolitemdataty(adatapo)^.data)+length(str1); + with tdataset(fowner) do begin + field1:= findfield(str1); + if field1 <> nil then begin + include(fistate,ids_remotedata); + fdscontroller.recnozerobased:= int1; + try + if not (state in [dsedit,dsinsert]) then begin + edit; + end; + inc(adatapo,ifidatatofield(pifidataty(adatapo),field1)); + if iod_autopost in foptionsdb then begin + post; + end; + finally + exclude(fistate,ids_remotedata); + end; + end; + end; + end; + ik_gridcommand: begin + inc(adatapo,decodegridcommanddata(adatapo,ckind1,source1,dest1,count1)); + include(fistate,ids_remotedata); + try + with tdataset(fowner) do begin + case ckind1 of + gck_insertrow: begin + if dest1 >= recordcount then begin + append; + end + else begin + fdscontroller.recnozerobased:= dest1; + insert; + end; +// post; + end; + gck_deleterow: begin + fdscontroller.recnozerobased:= dest1; + delete; + end; + end; + end; + finally + exclude(fistate,ids_remotedata); + end; + end; + end; + end; +end; + +function tifidscontroller.encoderecord(const aindex: integer; + const recpo: pintrecordty): string; +var + str1: string; + mstr1: msestring; + +begin + if not getfieldflag(pbyte(@recpo^.header.fielddata.nullmask),aindex) then begin + result:= encodeifinull; + end + else begin + with iifidscontroller(fintf).getfieldinfos[aindex],base,ext do begin + case fieldtype of + ftinteger: begin + result:= encodeifidata(pinteger(pchar(pointer(recpo))+offset)^); + end; + ftlargeint: begin + result:= encodeifidata(plargeint(pchar(pointer(recpo))+offset)^); + end; + ftsmallint: begin + result:= encodeifidata(integer(psmallint(pchar(pointer(recpo))+offset)^)); + end; + ftword: begin + result:= encodeifidata(integer(pword(pchar(pointer(recpo))+offset)^)); + end; + ftboolean: begin + result:= encodeifidata(integer(pwordbool(pchar(pointer(recpo))+offset)^)); + end; + ftfloat,ftcurrency: begin + {$ifdef FPC} + result:= encodeifidata(pdouble(pchar(pointer(recpo))+offset)^); + {$else} + result:= encodeifidatareal(pdouble(pchar(pointer(recpo))+offset)^); + {$endif} + end; + ftbcd: begin + {$ifdef FPC} + result:= encodeifidata(pcurrency(pchar(pointer(recpo))+offset)^); + {$else} + result:= encodeifidatareal(pcurrency(pchar(pointer(recpo))+offset)^); + {$endif} + end; + ftmemo: begin + mstr1:= field.aswidestring; + result:= encodeifidata(mstr1); + end; + ftblob,ftgraphic: begin + str1:= field.asstring; + result:= encodeifidata(str1); + end; + ftstring: begin + result:= encodeifidata(pmsestring(pchar(pointer(recpo))+offset)^); + end; + else begin + result:= encodeifinull; +// result:=''; + exit; + end; + end; + end; + end; +end; + +function tifidscontroller.encoderecords(const arecordcount: integer; + const abufs: pointerarty): string; + //todo: optimize +var + ind1: integer; + + procedure put(const avalue: string; const alength: integer); + begin + if ind1 + alength > length(result) then begin + setlength(result,length(result)*2); + end; + move(avalue,result[ind1],alength); + inc(ind1,alength); + end; + +var + int1,int2: integer; + str1: string; + bufbefore: pintrecordty; + statebefore: tdatasetstate; + +begin + setlength(result,16); + ind1:= 1; + move(arecordcount,result[1],sizeof(arecordcount)); + inc(ind1,sizeof(arecordcount)); + bufbefore:= iifidscontroller(fintf).setcurrentbuf(nil); + statebefore:= tdataset1(fowner).settempstate(dscurvalue); + for int1:= 0 to arecordcount - 1 do begin + iifidscontroller(fintf).setcurrentbuf(abufs[int1]); + for int2:= 0 to high(ftxbindings) do begin + str1:= encoderecord(ftxbindings[int2],abufs[int1]); + if ind1 + length(str1) > length(result) then begin + setlength(result,length(result)*2+length(str1)); + end; + move(str1[1],result[ind1],length(str1)); + inc(ind1,length(str1)); + end; + end; + iifidscontroller(fintf).setcurrentbuf(bufbefore); + tdataset1(fowner).restorestate(statebefore); + setlength(result,ind1 - 1); +end; + +procedure tifidscontroller.sendpostresult(const asequence: sequencety; + const acode: postresultcodety; const amessage: msestring); +var + str1,str2: string; + po1: pointer; +begin + str2:= stringtoutf8ansi(amessage); + inititemheader(str1,ik_postresult,asequence, + length(str2),pchar(po1)); + with ppostresultdataty(po1)^ do begin + code:= acode; + stringtoifiname(str2,@message); + end; + senddata(str1); +end; +{ +procedure tifidscontroller.setfieldoptions(const avalue: tififieldoptions); +begin + ffieldoptions.assign(avalue); +end; +} +function tifidscontroller.getfield(const aindex: integer): tfield; +var + ar1: fieldinfoarty; +begin + result:= nil; + ar1:= iifidscontroller(fintf).getfieldinfos; + if aindex <= high(ar1) then begin + result:= ar1[aindex].ext.field; + end; +end; + +procedure tifidscontroller.opened; +var + int1,int2: integer; + ar1: fieldinfoarty; +begin + ar1:= iifidscontroller(fintf).getfieldinfos; + setlength(ftxbindings,length(ar1)); + int2:= 0; + for int1:= 0 to high(ftxbindings) do begin + with ar1[int1].ext do begin + if field <> nil then begin + with field do begin + if not (of_hidden in optionsfield) {and (recno >= 0)} then begin + ftxbindings[int2]:= int1; + inc(int2); + end; + end; + end; + end; + end; + setlength(ftxbindings,int2); + frxbindings:= ftxbindings; + { + with tdataset(fowner) do begin + setlength(fbindings,fields.count); + setlength(ffielddefindex,fields.count); + int2:= 0; + for int1:= 0 to high(fbindings) do begin + with fields[int1] do begin + if not (pfhidden in providerflags) and (index >= 0) then begin + fbindings[int2]:= field1.index; + ffielddefindex[int2]:= int1; + inc(int2); + end; + end; + setlength(fbindings,int2); + setlength(ffielddefindex,int2); + end; + } +end; + +function tifidscontroller.getifireckinds: ifireckindsty; +begin + result:= ifidskinds; +end; + +procedure tifidscontroller.updaterxbindings; +var + int1,int2: integer; + field1: tfield; +begin + with tdataset(fowner) do begin + setlength(frxbindings,fielddefs.count); + int2:= 0; + for int1:= 0 to high(frxbindings) do begin + field1:= findfield(fielddefs[int1].name); + if (field1 <> nil) and (field1.index >= 0) then begin + frxbindings[int2]:= field1.index; + inc(int2); + end; + end; + setlength(frxbindings,int2); + ftxbindings:= frxbindings; + end; +end; + +procedure tifidscontroller.closed; +begin + frxbindings:= nil; + ftxbindings:= nil; +end; + +procedure tifidscontroller.setowneractive(const avalue: boolean); +begin + tdataset(fowner).active:= avalue; +end; + +{ tifidataset } + +constructor tifidataset.create(aowner: tcomponent); +begin +// foptions:= defaultifidsoptions; + frecno:= -1; +// fdefaulttimeout:= defaultifidstimeout; +// fobjectlinker:= tobjectlinker.create(ievent(self), +// {$ifdef FPC}@{$endif}objectevent); +// setunidirectional(true); + inherited; + bookmarksize := sizeof(bufbookmarkty); + fcontroller:= tdscontroller.create(self,idscontroller(self),-1,false); + fificontroller:= tifidscontroller.create(self,iifidscontroller(self)); +// fifimoduleink:= iifimodulelink(fificontroller); +end; + +destructor tifidataset.destroy; +begin + fcontroller.free; + inherited; + fificontroller.free; +// fobjectlinker.free; +end; + +procedure tifidataset.connectmodule(const sender: tcustommodulelink); +begin + fificontroller.connectmodule(sender); +end; + +function tifidataset.intallocrecord: pintrecordty; +begin + result:= allocmem(frecordsize+intheadersize); + fillchar(result^,frecordsize+intheadersize,0); +end; + +procedure tifidataset.finalizestrings(var header: recheaderty); +var + int1: integer; +begin + for int1:= high(fmsestringpositions) downto 0 do begin + pmsestring(pointer(pchar(@header)+fmsestringpositions[int1]))^:= ''; + end; + for int1:= high(fansistringpositions) downto 0 do begin + pansistring(pointer(pchar(@header)+fansistringpositions[int1]))^:= ''; + end; +end; + +procedure tifidataset.finalizecalcstrings(var header: recheaderty); +begin +end; + +procedure tifidataset.finalizechangedstrings(const tocompare: recheaderty; + var tofinalize: recheaderty); +var + int1: integer; +begin + for int1:= high(fmsestringpositions) downto 0 do begin + if ppointer(pointer(pchar(@tocompare)+fmsestringpositions[int1]))^ <> + ppointer(pointer(pchar(@tofinalize)+fmsestringpositions[int1]))^ then begin + pmsestring(pointer(pchar(@tofinalize)+fmsestringpositions[int1]))^:= ''; + end; + end; + for int1:= high(fansistringpositions) downto 0 do begin + if ppointer(pointer(pchar(@tocompare)+fansistringpositions[int1]))^ <> + ppointer(pointer(pchar(@tofinalize)+fansistringpositions[int1]))^ then begin + pansistring(pointer(pchar(@tofinalize)+fansistringpositions[int1]))^:= ''; + end; + end; +end; + +procedure tifidataset.addrefstrings(var header: recheaderty); +var + int1: integer; +begin + for int1:= high(fmsestringpositions) downto 0 do begin + stringaddref(pmsestring(pointer(pchar(@header)+fmsestringpositions[int1]))^); + end; + for int1:= high(fansistringpositions) downto 0 do begin + stringaddref(pansistring(pointer(pchar(@header)+fansistringpositions[int1]))^); + end; +end; + +procedure tifidataset.intfinalizerecord(const buffer: pintrecordty); +begin +// freeblobs(buffer^.header.blobinfo); + finalizestrings(buffer^.header); +end; + +procedure tifidataset.intfreerecord(var buffer: pintrecordty); +begin + if buffer <> nil then begin + intfinalizerecord(buffer); + freemem(buffer); + buffer:= nil; + end; +end; + +function tifidataset.AllocRecordBuffer: PChar; +begin + result := allocmem(dsheadersize+fcalcrecordsize); + initrecord(result); +end; + +procedure tifidataset.FreeRecordBuffer(var Buffer: PChar); +begin + if buffer <> nil then begin + reallocmem(buffer,0); + end; +end; + +procedure tifidataset.GetBookmarkData(Buffer: PChar; Data: Pointer); +begin + move(pdsrecordty(buffer)^.dsheader.bookmark,data^,sizeof(bookmarkdataty)); +end; + +function tifidataset.GetBookmarkFlag(Buffer: PChar): TBookmarkFlag; +begin + result:= pdsrecordty(buffer)^.dsheader.bookmark.flag; +end; +{ +function tifidataset.GetDataSource: TDataSource; +begin +end; +} +procedure tifidataset.internalsetrecno(const avalue: integer); +begin + frecno:= avalue; + if (avalue < 0) or (avalue >= fbrecordcount) then begin + fcurrentbuf:= nil; + end + else begin + fcurrentbuf:= fbufs[avalue]; + end; +end; + +function tifidataset.GetRecord(Buffer: PChar; GetMode: TGetMode; + DoCheck: Boolean): TGetResult; +begin + result:= grok; + case getmode of + gmprior: begin + if frecno <= 0 then begin + result := grbof; + end + else begin + internalsetrecno(frecno-1); + end; + end; + gmcurrent: begin + if (frecno < 0) or (frecno >= fbrecordcount) or (fcurrentbuf = nil) then begin + result := grerror; + end; + end; + gmnext: begin + if frecno >= fbrecordcount - 1 then begin + result:= greof; + end + else begin + internalsetrecno(frecno+1); + end; + end; + end; + if result = grok then begin + with pdsrecordty(buffer)^ do begin + with dsheader.bookmark do begin + data.recno:= frecno; + data.recordpo:= fcurrentbuf; + flag:= bfcurrent; + end; + move(fcurrentbuf^.header,header,frecordsize); + { + getcalcfields(buffer); + if filtered then begin + state1:= settempstate(tdatasetstate(dscheckfilter)); + try + dofilterrecord(acceptable); + finally + restorestate(state1); + end; + end; + if (getmode = gmcurrent) and not acceptable then begin + result:= grerror; + end; + } + end; + end; +end; + +function tifidataset.GetRecordSize: Word; +begin + result:= frecordsize; +end; + +procedure tifidataset.bindfields(const bind: boolean); +var + int1: integer; + field1: tfield; + int2: integer; + fielddef1: tfielddef; +begin + fielddef1:= nil; + for int1:= fields.count - 1 downto 0 do begin + field1:= fields[int1]; + if bind then begin + if field1.fieldkind = fkdata then begin + fielddef1:= tfielddef(fielddefs.find(field1.fieldname)); + //needed for FPC 2_2 + if fielddef1 <> nil then begin + field1.fieldname:= fielddef1.name; + //get exact name for quoting in update statements + end; + end + else begin + fielddef1:= nil; + end; + end; + if field1 is tmsestringfield then begin + int2:= 0; + if bind then begin + int2:= field1.size; + if fielddef1 <> nil then begin + int2:= fielddef1.size; + end; + tmsestringfield1(field1).setismsestring({$ifdef FPC}@{$endif}getmsestringdata, + {$ifdef FPC}@{$endif}setmsestringdata,int2,false); + end + else begin + tmsestringfield1(field1).setismsestring(nil,nil,int2,false); + end; + end + else begin + if field1 is tmseblobfield then begin + { + if bind then begin + tmseblobfield1(field1).fgetblobid:= @getfieldblobid; + end + else begin + tmseblobfield1(field1).fgetblobid:= nil; + end; + } + end; + end; + end; + inherited bindfields(bind); +end; + +function tifidataset.getfieldbuffer(const afield: tfield; out buffer: pointer; + out datasize: integer): boolean; + //read, true if not null +var + int1: integer; +begin + result:= false; + buffer:= nil; + if not active then begin + exit; + end; + int1:= afield.fieldno - 1; + case ord(state) of + ord(dscalcfields): begin +// buffer:= @pdsrecordty(calcbuffer)^.header; + end; + dscheckfilter: begin +// buffer:= @fcheckfilterbuffer^.header; + end; + ord(dsfilter): begin +// buffer:= @ffilterbuffer^.header; + end; + ord(dscurvalue): begin +// buffer:= @fcurrentbuf^.header; + end; + else begin + buffer:= @pdsrecordty(activebuffer)^.header; + { + if bs_internalcalc in fbstate then begin + if int1 < 0 then begin//calc field + buffer:= @pdsrecordty(activebuffer)^.header; + //values invalid! + end + else begin + buffer:= @fcurrentbuf^.header; + end; + end + else begin + if bs_recapplying in fbstate then begin + buffer:= @fnewvaluebuffer^.header; + end + else begin + buffer:= @pdsrecordty(activebuffer)^.header; + end; + end; + } + end; + end; + if int1 >= 0 then begin // data field + result:= false; + { + if state = dsoldvalue then begin + if getrecordupdatebuffer then begin + buffer:= fupdatebuffer[fcurrentupdatebuffer].oldvalues; + if buffer <> nil then begin + buffer:= @pintrecordty(buffer)^.header; + end; + end + else begin + buffer:= @fcurrentbuf^.header //there is no old value available + end; + end; + } + if buffer <> nil then begin + result:= getfieldflag(@precheaderty(buffer)^.fielddata.nullmask,int1); + inc(pchar(buffer),ffieldinfos[int1].base.offset{ffieldbufpositions[int1]}); + datasize:= ffieldinfos[int1].base.size{ffieldsizes[int1]}; + end + else begin + datasize:= 0; + end; + end + else begin + int1:= -2 - int1; + if int1 >= 0 then begin //calc field + { + result:= not getfieldisnull(pbyte(buffer+frecordsize),int1); + inc(buffer,fcalcfieldbufpositions[int1]); + datasize:= fcalcfieldsizes[int1]; + } + end + else begin + buffer:= nil; + datasize:= 0; + end; + end; +end; + +function tifidataset.getfieldbuffer(const afield: tfield; const isnull: boolean; + out datasize: integer): pointer; + //write +var + int1: integer; +begin + result:= nil; + if not ((state in dswritemodes - [dsinternalcalc,dscalcfields]) or + (afield.fieldkind = fkinternalcalc) and + (state = dsinternalcalc) or + (afield.fieldkind = fkcalculated) and + (state = dscalcfields)) then begin + databaseerrorfmt(snotediting,[name],self); + end; + int1:= afield.fieldno-1; + case state of + dscalcfields: begin +// result:= @pdsrecordty(calcbuffer)^.header; + end; + dsfilter: begin +// result:= @ffilterbuffer^.header; + end; + else begin + result:= @pdsrecordty(activebuffer)^.header; + { + if bs_internalcalc in fbstate then begin + if int1 < 0 then begin//calc field + result:= @pdsrecordty(activebuffer)^.header; + //values invalid! + end + else begin + result:= @fcurrentbuf^.header; + end; + end + else begin + if bs_recapplying in fbstate then begin + result:= @fnewvaluebuffer^.header; + end + else begin + result:= @pdsrecordty(activebuffer)^.header; + end; + end; + } + end; + end; + if int1 >= 0 then begin // data field + setfieldflag(pointer(fmodifiedfields),int1); //modified + if isnull then begin + clearfieldflag(@precheaderty(result)^.fielddata.nullmask,int1); + end + else begin + setfieldflag(@precheaderty(result)^.fielddata.nullmask,int1); + end; + inc(pchar(result),ffieldinfos[int1].base.offset{ffieldbufpositions[int1]}); + datasize:= ffieldinfos[int1].base.size{ffieldsizes[int1]}; + end + else begin + int1:= -2 - int1; + result:= nil; + datasize:= 0; + { + if int1 >= 0 then begin //calc field + if isnull then begin + setfieldisnull(pbyte(result+frecordsize),int1); + end + else begin + unsetfieldisnull(pbyte(result+frecordsize),int1); + end; + inc(result,fcalcfieldbufpositions[int1]); + datasize:= fcalcfieldsizes[int1]; + end + else begin + result:= nil; + datasize:= 0; + end; + } + end; +end; + +function tifidataset.getmsestringdata(const sender: tmsestringfield; + out avalue: msestring): boolean; +var + po1: pointer; + int1: integer; +begin + result:= getfieldbuffer(sender,po1,int1); + if result then begin + avalue:= msestring(po1^); + end + else begin + avalue:= ''; + end; +end; + +procedure tifidataset.setmsestringdata(const sender: tmsestringfield; + avalue: msestring); +var + po1: pointer; + int1: integer; +begin + po1:= getfieldbuffer(sender,false,int1); + msestring(po1^):= avalue; + if (sender.characterlength > 0) and + (length(avalue) > sender.characterlength) then begin + setlength(msestring(po1^),sender.characterlength); + end; + if (sender.fieldno > 0) and not + (state in [dscalcfields,dsinternalcalc,{dsfilter,}dsnewvalue]) then begin + dataevent(defieldchange,ptrint(sender)); + end; +end; + +function tifidataset.getfielddata(field: tfield; buffer: pointer; + nativeformat: boolean): boolean; +begin + result:= getfielddata(field,buffer); +end; + +function tifidataset.getfielddata(field: tfield; buffer: pointer): boolean; +var + po1: pointer; + datasize: integer; +begin + result:= getfieldbuffer(field,po1,datasize); + if (buffer <> nil) and result then begin + move(po1^,buffer^,datasize); + end; +end; + +procedure tifidataset.setfielddata(field: tfield; buffer: pointer; + nativeformat: boolean); +begin + setfielddata(field,buffer); +end; + +procedure tifidataset.setfielddata(field: tfield; buffer: pointer); +var + po1: pointer; + datasize: integer; +begin + po1:= getfieldbuffer(field,buffer = nil,datasize); + if buffer <> nil then begin + move(buffer^,po1^,datasize); + end; + if (field.fieldno > 0) and not + (state in [dscalcfields,dsinternalcalc,{dsfilter,}dsnewvalue]) then begin + dataevent(defieldchange, ptrint(field)); + end; +end; + +procedure tifidataset.initmodifiedfields; +begin + setlength(fmodifiedfields,fnullmasksize); + fillchar(pointer(fmodifiedfields)^,fnullmasksize,#0); +end; + +procedure tifidataset.InternalCancel; +begin + with pdsrecordty(activebuffer)^,header do begin + finalizestrings(header); + end; + exclude(fificontroller.fistate,ids_append); +end; + +procedure tifidataset.internaledit; +begin + initmodifiedfields; + addrefstrings(pdsrecordty(activebuffer)^.header); + inherited; +end; + +procedure tifidataset.InternalPost; +begin + with pdsrecordty(activebuffer)^ do begin + if state = dsinsert then begin + fcurrentbuf:= intallocrecord; + dsheader.bookmark.data.recordpo:= fcurrentbuf; + dsheader.bookmark.data.recno:= frecno; + if fbrecordcount >= high(fbufs) then begin + setlength(fbufs,(high(fbufs)+7)*2); + end; + move(fbufs[frecno],fbufs[frecno+1],(fbrecordcount-frecno)*sizeof(pointer)); + fbufs[frecno]:= fcurrentbuf; + inc(fbrecordcount); + end + else begin + finalizestrings(fcurrentbuf^.header); + end; + + move(header,fcurrentbuf^.header,frecordsize); //get new field values +// fillchar(pointer(fmodifiedfields)^,fnullmasksize,0); + end; + fificontroller.post; +end; + +procedure tifidataset.InternalAddRecord(Buffer: Pointer; AAppend: Boolean); +begin + notimplemented('Add record'); +end; + +procedure tifidataset.InternalFirst; +begin + internalsetrecno(-1); +end; + +function tifidataset.findrecord(arecordpo: pintrecordty): integer; +var + int1: integer; +begin + if arecordpo = fcurrentbuf then begin + result:= frecno; + end + else begin + for int1:= frecno to fbrecordcount - 1 do begin + if fbufs[int1] = arecordpo then begin + result:= int1; + exit; + end; + end; + for int1:= frecno downto 0 do begin + if fbufs[int1] = arecordpo then begin + result:= int1; + exit; + end; + end; + result:= -1; + end; +end; + +procedure tifidataset.InternalGotoBookmark(ABookmark: Pointer); +var + int1: integer; + int2: integer; +begin + if abookmark <> nil then begin + with pbufbookmarkty(abookmark)^.data do begin + if (recno >= fbrecordcount) or (recno < 0) then begin + databaseerror('Invalid bookmark recno: '+inttostr(recno)+'.'); + end; + int1:= recno; + if recordpo <> nil then begin + int2:= -1; + for int1:= frecno to high(fbufs) do begin + if fbufs[int1] = recordpo then begin + int2:= int1; + break; + end; + end; + for int1:= frecno downto 0 do begin + if fbufs[int1] = recordpo then begin + int2:= int1; + break; + end; + end; + if int2 < 0 then begin + databaseerror('Invalid bookmarkdata.'); + end; + end + else begin + int2:= recno; + end; + internalsetrecno(int2); + end; + end; +end; +{ +procedure tifidataset.InternalHandleException; +begin +end; +} +procedure tifidataset.InternalInitFieldDefs; +begin + //dummy +end; + +procedure tifidataset.InternalInitRecord(Buffer: PChar); +begin + with pdsrecordty(buffer)^ do begin + fillchar(header,fcalcrecordsize, #0); + end; +end; + +procedure tifidataset.InternalLast; +begin + internalsetrecno(fbrecordcount) +end; + +procedure tifidataset.InternalSetToRecord(Buffer: PChar); +begin + internalsetrecno(pdsrecordty(buffer)^.dsheader.bookmark.data.recno); +end; + +function tifidataset.IsCursorOpen: Boolean; +begin + result:= fopen; +end; + +procedure tifidataset.SetBookmarkFlag(Buffer: PChar; Value: TBookmarkFlag); +begin + pdsrecordty(buffer)^.dsheader.bookmark.flag:= value; +end; + +procedure tifidataset.SetBookmarkData(Buffer: PChar; Data: Pointer); +begin + move(data^,pdsrecordty(buffer)^.dsheader.bookmark,sizeof(bookmarkdataty)); +end; + +procedure tifidataset.notimplemented(const atext: string); +begin + raise exception.create(name+': '+atext+' not implemented.'); +end; + +procedure tifidataset.calcrecordsize; +var + int1,int2,int3: integer; + field1: tfield; +begin + int3:= 0; + fmsestringpositions:= nil; + fansistringpositions:= nil; + int1:= fielddefs.count; +// frecordsize:= 0; + frecordsize:= sizeof(blobinfoarty); + fnullmasksize:= (int1+7) div 8; + inc(frecordsize,fnullmasksize); + alignfieldpos(frecordsize); + setlength(ffieldinfos,int1); + for int2:= 0 to int1 - 1 do begin + with fielddefs[int2] do begin + field1:= fields.findfield(name); + if (field1 <> nil) and (field1.fieldkind = fkdata) then begin + case datatype of + ftstring,ftfixedchar: begin + additem(fmsestringpositions,frecordsize); + int3:= sizeof(msestring); + end; + ftsmallint,ftinteger,ftword: begin + int3:= sizeof(longint); + end; + ftboolean: begin + int3:= sizeof(wordbool); + end; + ftbcd: begin + int3:= sizeof(currency); + end; + ftfloat,ftcurrency: begin + int3:= sizeof(double); + end; + ftlargeint: begin + int3:= sizeof(largeint); + end; + fttime,ftdate,ftdatetime: begin + int3:= sizeof(tdatetime); + end; + ftblob,ftmemo: begin + additem(fansistringpositions,frecordsize); + int3:= sizeof(string); + end; + else begin + int3:= 0; + end; + end; + end; + with ffieldinfos[int2],base,ext do begin + offset:= frecordsize; + inc(frecordsize,int3); + alignfieldpos(frecordsize); + size:= int3; + fieldtype:= datatype; + field:= field1; + end; + end; + end; + fcalcrecordsize:= frecordsize; //no calcfields +end; + +function tifidataset.locate(const afields: array of tfield; + const akeys: array of const; const aisnull: array of boolean; + const akeyoptions: array of locatekeyoptionsty; + const aoptions: locaterecordoptionsty = []): locateresultty; +begin + result:= locaterecord(self,afields,akeys,aisnull,akeyoptions,aoptions); +end; +{ +function tifidataset.locate(const key: integer; const field: tfield; + const options: locateoptionsty = []): locateresultty; +begin + result:= fcontroller.locate(key,field,options); +end; + +function tifidataset.locate(const key: string; + const field: tfield; const options: locateoptionsty = []): locateresultty; +begin + result:= fcontroller.locate(key,field,options); +end; +} +procedure tifidataset.AppendRecord(const Values: array of const); +begin + fcontroller.appendrecord(values); +end; + +procedure tifidataset.setcontroller(const avalue: tdscontroller); +begin + fcontroller.assign(avalue); +end; + +function tifidataset.getactive: boolean; +begin + result:= inherited active; +end; + +procedure tifidataset.cancelconnection; +begin + fificontroller.fistate:= fificontroller.fistate - openflags; +end; + +procedure tifidataset.setactive(const value: boolean); +begin + if not value then begin + cancelconnection; + end; + if fcontroller.setactive(value) then begin + inherited setactive(value); + end; +end; + +procedure tifidataset.loaded; +begin + inherited; + fcontroller.loaded; +end; + +function tifidataset.getfieldclass(fieldtype: tfieldtype): tfieldclass; +begin + fcontroller.getfieldclass(fieldtype,result); +end; + +function tifidataset.getcontroller: tdscontroller; +begin + result:= fcontroller; +end; + +procedure tifidataset.inheritedresync(const mode: tresyncmode); +begin + inherited resync(mode); +end; + +procedure tifidataset.inheritedcancel; +begin + inherited cancel; +end; + +procedure tifidataset.cancel; +begin + fcontroller.cancel; +end; + +function tifidataset.inheritedmoveby(const distance: integer): integer; +begin + result:= inherited moveby(distance); +end; + +procedure tifidataset.inheritedinternalinsert; +begin + initmodifiedfields; + with pdsrecordty(activebuffer)^.dsheader.bookmark.data do begin + recordpo:= nil; + recno:= frecno; + end; + inherited internalinsert; +end; + +procedure tifidataset.internalinsert; +begin + fcontroller.internalinsert; +end; + +function tifidataset.moveby(const distance: integer): integer; +begin + result:= fcontroller.moveby(distance); +end; + +procedure tifidataset.inheritedinternalopen; +begin + if defaultfields then begin + createfields; + end; + bindfields(true); + calcrecordsize; + fopen:= true; + fificontroller.opened; +end; + +procedure tifidataset.internalopen; +begin + fcontroller.internalopen; +end; + +procedure tifidataset.inheritedpost; +begin + inherited post; +end; + +procedure tifidataset.post; +begin + fcontroller.post; +end; + +procedure tifidataset.inheritedinternaldelete; +begin + if state = dsedit then begin + internalcancel; + end; + intfreerecord(fcurrentbuf); + dec(fbrecordcount); + move(fbufs[frecno+1],fbufs[frecno],(fbrecordcount-frecno)*sizeof(pointer)); + fificontroller.delete; +end; + +procedure tifidataset.internaldelete; +begin + fcontroller.internaldelete; +end; + +procedure tifidataset.openlocal; +begin + inheritedinternalopen; +end; + +procedure tifidataset.inheritedinternalclose; +var + int1: integer; +begin + cancelconnection; + fopen:= false; + bindfields(false); + if defaultfields then begin + destroyfields; + end; + for int1:= 0 to fbrecordcount - 1 do begin + intfreerecord(pintrecordty(fbufs[int1])); + end; + frecno:= -1; + fcurrentbuf:= nil; + fbrecordcount:= 0; +// inherited internalclose; +end; + +procedure tifidataset.internalclose; +begin + fificontroller.closed; + fcontroller.internalclose; +end; + +function tifidataset.getblobdatasize: integer; +begin + result:= 0; //no blobs +end; + +function tifidataset.getnumboolean: boolean; +begin + result:= true; +end; + +function tifidataset.getfloatdate: boolean; +begin + result:= false; +end; + +function tifidataset.getint64currency: boolean; +begin + result:= false; +end; + +function tifidataset.getsavepointoptions(): savepointoptionsty; +begin + result:= []; +end; +{ +procedure tifidataset.setchannel(const avalue: tcustomiochannel); +begin + fobjectlinker.setlinkedvar(ievent(self),avalue,fchannel); +end; + +procedure tifidataset.link(const source: iobjectlink; const dest: iobjectlink; + valuepo: pointer = nil; ainterfacetype: pointer = nil; + once: boolean = false); +begin + fobjectlinker.link(source,dest,valuepo,ainterfacetype,once); +end; + +procedure tifidataset.unlink(const source: iobjectlink; const dest: iobjectlink; + valuepo: pointer = nil); +begin + fobjectlinker.unlink(source,dest,valuepo); +end; + +procedure tifidataset.objevent(const sender: iobjectlink; + const event: objecteventty); +begin + fobjectlinker.objevent(sender,event); +end; + +function tifidataset.getinstance: tobject; +begin + result:= self; +end; + +procedure tifidataset.objectevent(const sender: tobject; + const event: objecteventty); +var + po1: pifirecty; +begin + if (event = oe_dataready) and (sender = fchannel) then begin + if (length(fchannel.rxdata) >= sizeof(ifiheaderty)) then begin + with fchannel do begin + po1:= pifirecty(rxdata); + with po1^.header do begin + if size = length(rxdata) then begin + processdata(po1); + end; + end; + end; + end; + end; +end; + +procedure tifidataset.receiveevent(const event: tobjectevent); +begin + //dummy +end; +} +procedure tifidataset.requestfielddefsreceived(const asequence: sequencety); +begin + //dummy +end; + +procedure tifidataset.requestopendsreceived(const asequence: sequencety); +begin + //dummy +end; + +procedure tifidataset.fielddefsdatareceived(const asequence: sequencety; + const adata: pfielddefsdatadataty); +begin + //dummy +end; + +procedure tifidataset.dsdatareceived(const asequence: sequencety; + const adata: pfielddefsdatadataty); +begin + //dummy +end; + +{ +procedure tifidataset.waitforanswer(const asequence: sequencety; + waitus: integer = 0); +begin + if waitus = 0 then begin + waitus:= fdefaulttimeout; + end; + fchannel.waitforanswer(asequence,fdefaulttimeout); +end; +} +{ +procedure tifidataset.fieldrecdatareceived(const adata: pfieldrecdataty); +var + int1: integer; + index1: integer; + po1: pchar; + mstr1: msestring; + int641: int64; + rea1: real; + cu1: currency; + str1: string; + field1: tfield; + bo1: boolean; + bm: string; + +begin + if active then begin + checkbrowsemode; + disablecontrols; + include(fificontroller.fistate,ids_remotedata); + bm:= bookmark; + try + if adata^.kind = frk_delete then begin + recno:= adata^.recno; + delete; + end + else begin + bo1:= adata^.kind = frk_insert; + if bo1 then begin + if adata^.recno >= recordcount then begin + append; + end + else begin + recno:= adata^.recno; + insert; + end; + end + else begin + recno:= adata^.recno; + edit; + end; + po1:= @adata^.data; + for int1:= 0 to adata^.count - 1 do begin + index1:= pfielddataty(po1)^.header.index; + if (index1 >= 0) and (index1 <= high(fbindings)) and + (fbindings[index1] >= 0) then begin + field1:= fields[fbindings[index1]]; + inc(po1,sizeof(mseifi.fielddataty.header)); + case pifidataty(po1)^.header.kind of + idk_null: begin + field1.clear; + inc(po1,sizeof(ifidataty)); + end; + idk_int64: begin + inc(po1,decodeifidata(pifidataty(po1),int641)); + field1.aslargeint:= int641; + end; + idk_real: begin + inc(po1,decodeifidata(pifidataty(po1),rea1)); + field1.asfloat:= rea1; + end; + idk_currency: begin + inc(po1,decodeifidata(pifidataty(po1),cu1)); + field1.ascurrency:= cu1; + end; + idk_bytes: begin + inc(po1,decodeifidata(pifidataty(po1),str1)); + field1.asstring:= str1; + end; + idk_msestring: begin + inc(po1,decodeifidata(pifidataty(po1),mstr1)); + if field1 is tmsestringfield then begin + tmsestringfield(field1).asmsestring:= mstr1; + end + else begin + field1.asstring:= mstr1; + end; + end; + end; + end; + setfieldisnull(pointer(fmodifiedfields),index1); //reset changeflag + end; + post; + end; + fificontroller.doremotedatachange; + try + bookmark:= bm; + except + end; + finally + exclude(fificontroller.fistate,ids_remotedata); + enablecontrols; + end; + end; +end; +} +procedure tifidataset.inheriteddataevent(const event: tdataevent; + const info: ptrint); +begin + if (event = defieldchange) and + (fificontroller.fistate * [ids_remotedata,ids_updating] = []) then begin + if TField(Info).FieldKind in [fkData,fkInternalCalc] then begin + SetModified(True); + end; + exit; + end; + inherited dataevent(event,info); +end; + +procedure tifidataset.dataevent(event: tdataevent; info: ptrint); +begin + fcontroller.dataevent(event,info); +end; + +procedure tifidataset.Append; +begin + include(fificontroller.fistate,ids_append); + inherited; +end; + +procedure tifidataset.checkrecno(const avalue: integer); +begin + if (avalue > recordcount) or (avalue < 1) then begin + databaseerror(snosuchrecord,self); + end; +end; + +function tifidataset.getrecno: integer; +begin + result:= 0; + if activebuffer <> nil then begin + with pdsrecordty(activebuffer)^.dsheader.bookmark do begin + if state = dsinsert then begin + if (ids_append in fificontroller.fistate) or (fbrecordcount = 0) then begin + result:= fbrecordcount + 1; + end + else begin + result:= data.recno + 1; + end; + end + else begin + if fbrecordcount > 0 then begin + result:= data.recno + 1; + end; + end; + end; + end; +end; + +procedure tifidataset.setrecno(value: longint); +var + bm: bufbookmarkty; +begin + checkbrowsemode; + checkrecno(value); + bm.data.recordpo:= nil; + bm.data.recno:= value-1; + gotobookmark(@bm); +end; + +function tifidataset.GetRecordCount: Longint; +begin + result:= fbrecordcount; +end; + +procedure tifidataset.decoderecord(var adata: pointer; const dest: pintrecordty); +var + integer1: integer; + int641: int64; + double1: double; + cur1: currency; + mstr1: msestring; + str1: string; + int1: integer; +begin + for int1:= 0 to high(fificontroller.frxbindings) do begin +// if fificontroller.fbindings[int1] >= 0 then begin + if pifidataty(adata)^.header.kind <> idk_null then begin + setfieldflag(pbyte(@dest^.header.fielddata.nullmask), + fificontroller.frxbindings[int1]); + with ffieldinfos[fificontroller.frxbindings[int1]].base do begin + case fieldtype of + ftinteger: begin + inc(pchar(adata),decodeifidata(pifidataty(adata),integer1)); + pinteger(pchar(pointer(dest))+offset)^:= integer1; + end; + ftlargeint: begin + inc(pchar(adata),decodeifidata(pifidataty(adata),int641)); + plargeint(pchar(pointer(dest))+offset)^:= int641; + end; + ftfloat,ftcurrency: begin + {$ifdef FPC} + inc(pchar(adata),decodeifidata(pifidataty(adata),double1)); + {$else} + inc(pchar(adata),decodeifidatareal(pifidataty(adata),double1)); + {$endif} + pdouble(pchar(pointer(dest))+offset)^:= double1; + end; + ftbcd: begin + inc(pchar(adata),decodeifidata(pifidataty(adata),cur1)); + pcurrency(pchar(pointer(dest))+offset)^:= cur1; + end; + ftblob,ftgraphic,ftmemo: begin + inc(pchar(adata),decodeifidata(pifidataty(adata),str1)); + pstring(pchar(pointer(dest))+offset)^:= str1; + end; + ftstring: begin + inc(pchar(adata),decodeifidata(pifidataty(adata),mstr1)); + pmsestring(pchar(pointer(dest))+offset)^:= mstr1; + end; + end; + end; + end + else begin + inc(pchar(adata),skipifidata(pifidataty(adata))); + end; + end; +end; + +function tifidataset.decoderecords(const adata: precdataty; + out asize: integer): boolean; +var + int1: integer; + po1: pointer; +begin + result:= true; + fbrecordcount:= adata^.header.count; + setlength(fbufs,fbrecordcount); + po1:= @adata^.data; + for int1:= 0 to high(fbufs) do begin + fbufs[int1]:= intallocrecord; + decoderecord(po1,fbufs[int1]); + end; + asize:= pchar(po1) - pchar(pointer(adata)); +end; + +function tifidataset.getfiltereditkind: filtereditkindty; +begin + result:= fek_filter; +end; + +procedure tifidataset.beginfilteredit(const akind: filtereditkindty); +begin + //dummy +end; + +procedure tifidataset.endfilteredit; +begin + //dummy +end; + +procedure tifidataset.clearfilter; +begin + //dumm +end; + +procedure tifidataset.beginupdate; +begin + inc(fupdating); + include(fificontroller.fistate,ids_updating); +end; + +procedure tifidataset.endupdate; +begin + dec(fupdating); + if fupdating = 0 then begin + exclude(fificontroller.fistate,ids_updating); + end; +end; + +procedure tifidataset.setificountroller(const avalue: tifidscontroller); +begin + fificontroller.assign(avalue); +end; + +function tifidataset.getfielddefs: tfielddefs; +begin + result:= fielddefs; +end; +{ +procedure tifidataset.doidleapplyupdates; +begin + //dummy +end; +} +{ +function tifidataset.getbindings: integerarty; +begin + result:= fbindings; +end; +} +function tifidataset.getmodifiedfields: string; +begin + result:= fmodifiedfields; +end; + +function tifidataset.setcurrentbuf(const abuf: pintrecordty): pintrecordty; +begin + result:= fcurrentbuf; + fcurrentbuf:= abuf; +end; + +function tifidataset.getifistate: ifidsstatesty; +begin + result:= fificontroller.fistate; +end; + +function tifidataset.getfieldinfos: fieldinfoarty; +begin + result:= ffieldinfos; +end; + +procedure tifidataset.InternalRefresh; +begin + active:= false; + active:= true; +end; + +function tifidataset.getcanmodify: boolean; +begin + result:= fcontroller.getcanmodify and inherited getcanmodify; +end; +{ +procedure tifidataset.dscontrolleroptionschanged(const aoptions: datasetoptionsty); +begin + //dummy +end; +} +function tifidataset.getrestorerecno: boolean; +begin + result:= false; +end; + +procedure tifidataset.setrestorerecno(const avalue: boolean); +begin + //dummy +end; + +function tifidataset.islastrecord: boolean; +begin + result:= eof or (recno = recordcount); +end; + +function tifidataset.updatesortfield(const afield: tfield; + const adescend: boolean): boolean; +begin + result:= false; +end; + +procedure tifidataset.begindisplaydata; +begin + //dummy +end; + +procedure tifidataset.enddisplaydata; +begin + //dummy +end; + +procedure tifidataset.inheriteddelete; +begin + inherited delete(); +end; + +procedure tifidataset.inheritedinsert; +begin + inherited insert(); +end; + +{ trxdataset } + +procedure trxdataset.fielddefsdatareceived(const asequence: sequencety; + const adata: pfielddefsdatadataty); +var + int1: integer; +begin + if (ids_openpending in fificontroller.fistate) and + (asequence = ffielddefsequence) then begin + if decodefielddefs(@adata^.data,fielddefs,int1) then begin + exclude(fificontroller.fistate,ids_openpending); + include(fificontroller.fistate,ids_fielddefsreceived); +// active:= true; + end + else begin + cancelconnection; + end; + end; +end; + +procedure trxdataset.dsdatareceived(const asequence: sequencety; + const adata: pfielddefsdatadataty); +var + int1,int2: integer; +begin + if (ids_openpending in fificontroller.fistate) and + (asequence = ffielddefsequence) then begin + if decodefielddefs(@adata^.data,fielddefs,int1) then begin + inherited inheritedinternalopen; + fificontroller.updaterxbindings; + if decoderecords(pointer(pchar(@adata^.data)+int1),int2) then begin + exclude(fificontroller.fistate,ids_openpending); + include(fificontroller.fistate,ids_fielddefsreceived); + end; + end + else begin + cancelconnection; + end; + end; +end; + +procedure trxdataset.inheritedinternalopen; +var + str1: ansistring; + po1: pointer; +begin + with fificontroller do begin + if (channel <> nil) or + not ((csdesigning in componentstate) and + (irxo_useclientchannel in foptions)) then begin + inititemheader(str1,ik_requestopen,0,0,pchar(po1)); + include(fistate,ids_openpending); + if senddataandwait(str1,ffielddefsequence) and + (ids_fielddefsreceived in fistate) then begin + // inherited; + end + else begin + sysutils.abort; + //error + end; + end + else begin + inherited; + end; + end; +end; + +procedure trxdataset.txactionfired(var adata: ansistring; var adatapo: pchar); +begin + if active then begin + checkbrowsemode; + end; + addifiintegervalue(adata,adatapo,recno); +end; + +{ ttxdataset } + +constructor ttxdataset.create(aowner: tcomponent); +begin + inherited; + include(fificontroller.fistate,ids_sendpostresult); +end; + +{ +procedure ttxdataset.inheritedinternalopen; +begin + inherited; +end; +} +procedure ttxdataset.requestopendsreceived(const asequence: sequencety); +var + str1,str2,str3: ansistring; + po1: pchar; +begin + str2:= fificontroller.encodefielddefs; + str3:= fificontroller.encoderecords(fbrecordcount,fbufs); + fificontroller.inititemheader(str1,ik_dsdata,asequence, + length(str2)+length(str3),po1); + with pfielddefsdatadataty(po1)^ do begin +// sequence:= asequence; + move(str2[1],data,length(str2)); + move(str3[1],(pointer(pchar(@data)+length(str2)))^,length(str3)); + end; + fificontroller.senddata(str1); +end; + +{ ttxsqlquery } + +constructor ttxsqlquery.create(aowner: tcomponent); +begin + inherited; + fificontroller:= tifidscontroller.create(self,iifidscontroller(self)); + include(fificontroller.fistate,ids_sendpostresult); +end; + +destructor ttxsqlquery.destroy; +begin + inherited; + fificontroller.free; + fcurrentchanged.free +end; + +procedure ttxsqlquery.setificontroller(const avalue: tifidscontroller); +begin + fificontroller.assign(avalue); +end; + +procedure ttxsqlquery.requestopendsreceived(const asequence: sequencety); +var + str1,str2,str3: ansistring; + po1: pchar; +begin + if checkcanevent(self,tmethod(fclientbeforeopen)) then begin + fclientbeforeopen(self); + end; + str2:= fificontroller.encodefielddefs; + if factindexpo = nil then begin + str3:= fificontroller.encoderecords(fbrecordcount,nil); + end + else begin + str3:= fificontroller.encoderecords(fbrecordcount,factindexpo^.ind); + end; + fificontroller.inititemheader(str1,ik_dsdata,asequence, + length(str2)+length(str3),po1); + with pfielddefsdatadataty(po1)^ do begin +// sequence:= asequence; + move(str2[1],data,length(str2)); + move(str3[1],(pointer(pchar(@data)+length(str2)))^,length(str3)); + end; + fificontroller.senddata(str1); + if checkcanevent(self,tmethod(fclientafteropen)) then begin + fclientafteropen(self); + end; +end; + +procedure ttxsqlquery.fielddefsdatareceived(const asequence: sequencety; + const adata: pfielddefsdatadataty); +begin +end; + +procedure ttxsqlquery.dsdatareceived(const asequence: sequencety; + const adata: pfielddefsdatadataty); +begin +end; +{ +procedure ttxsqlquery.fieldrecdatareceived(const adata: pfieldrecdataty); +begin +end; +} +function ttxsqlquery.getfielddefs: tfielddefs; +begin + result:= fielddefs; +end; + +procedure ttxsqlquery.internalopen; +begin + inherited; + fcurrentchanged.free; + fcurrentchanged:= tcurrentchangedlist.create(nullmasksize); + fificontroller.opened; +end; + +procedure ttxsqlquery.internalclose; +begin + fificontroller.closed; + inherited; +end; + +function ttxsqlquery.getmodifiedfields: string; +begin + result:= fmodifiedfields; +end; + +function ttxsqlquery.setcurrentbuf(const abuf: pintrecordty): pintrecordty; +begin + result:= fcurrentbuf; + fcurrentbuf:= abuf; +end; + +procedure ttxsqlquery.initmodifiedfields; +begin + setlength(fmodifiedfields,nullmasksize); + fillchar(pointer(fmodifiedfields)^,nullmasksize,#0); +end; + +procedure ttxsqlquery.internaledit; +begin + initmodifiedfields; + inherited; +end; + +procedure ttxsqlquery.inheritedinternalinsert; +begin + initmodifiedfields; + inherited; +end; + +procedure ttxsqlquery.InternalPost; +begin + fificontroller.post; + inherited; +end; + +function ttxsqlquery.getfieldinfos: fieldinfoarty; +begin + result:= ffieldinfos; +end; + +procedure ttxsqlquery.inheritedinternaldelete; +begin + fificontroller.delete; + inherited; +end; + +function ttxsqlquery.getfieldbuffer(const afield: tfield; const aisnull: boolean; + out datasize: integer): pointer; +var + int1: integer; +begin + result:= inherited getfieldbuffer(afield,aisnull,datasize); + int1:= afield.fieldno-1; + if (int1 >= 0) and (state <> dscurvalue) and + not (bs_fetching in fbstate) then begin //datafield + setfieldflag(pointer(fmodifiedfields),int1); //modified + end; +end; + +procedure ttxsqlquery.cancelconnection; +begin + //dummy +end; + +procedure ttxsqlquery.fixupcurrentset; +begin + inherited; +end; +{ +procedure ttxsqlquery.deccurrentupdate; +begin + if fcurrentupdating = 0 then begin + fupdatedcurrentrecords:= nil; + fupdatedcurrentrecordcount:= 0; + end; + inherited; +end; +} +procedure ttxsqlquery.aftercurrentset(const afield: tfield); +begin + inherited; + if flastcurrentindex >= 0 then begin + if fcurrentupdating = 0 then begin + currentrecordupdated(flastcurrentindex); + end + else begin + fcurrentchanged.fieldchanged(afield,flastcurrentindex); + end; + end; +end; + +procedure ttxsqlquery.currentrecordupdated(const aindex: integer); +begin +end; + +procedure ttxsqlquery.currentbeginupdate; +begin + if fcurrentupdating = 0 then begin + fcurrentchanged.clear; + end; + inherited; +end; + +procedure ttxsqlquery.currentendupdate; +begin + inherited; + if fcurrentupdating = 0 then begin + fificontroller.sendchangedrecords(fcurrentchanged); + fcurrentchanged.clear; + end; +end; + +{ tcurrentchangedlist } + +constructor tcurrentchangedlist.create(const anullmasksize: integer); +begin + fnullmasksize:= anullmasksize; + inherited create(); + include(fstate,hls_needsnull); +end; + +function tcurrentchangedlist.getrecordsize(): int32; +begin + result:= sizeof(ptruinthashdataty)+fnullmasksize; +end; + +procedure tcurrentchangedlist.fieldchanged(const afield: tfield; + const aindex: integer); +begin + setfieldflag(@pchangehashdataty(addunique(ptruint(aindex)))^.data.data, + afield.fieldno-1); +end; + +end. diff --git a/mseide-msegui/lib/common/ifi/mseifiendpoint.pas b/mseide-msegui/lib/common/ifi/mseifiendpoint.pas new file mode 100644 index 0000000..bef20ce --- /dev/null +++ b/mseide-msegui/lib/common/ifi/mseifiendpoint.pas @@ -0,0 +1,418 @@ +{ MSEgui Copyright (c) 2013-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseifiendpoint; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msestrings,mclasses,mseclasses,mseificompglob,mseificomp,typinfo,msedatalist, + msetypes; + +type + tifidataendpoint = class(tmsecomponent,iifidatalink) + private + fonchange: notifyeventty; + protected + fifilink: tifilinkcomp; + procedure change; + //iifidatalink + function getifilinkkind: ptypeinfo; + procedure setifilink(const avalue: tifilinkcomp); + function ifigriddata: tdatalist; + procedure updateifigriddata(const sender: tobject; const alist: tdatalist); + function getgriddata: tdatalist; + function getvalueprop: ppropinfo; + procedure getifivalue(var avalue) virtual; + procedure setifivalue(const avalue) virtual; + procedure updatereadonlystate; + published + property onchange: notifyeventty read fonchange write fonchange; + end; + + tifiintegerendpoint = class(tifidataendpoint) + private + fvalue: integer; + fondatachange: updateintegereventty; + function getifilink: tifiintegerlinkcomp; + procedure setifilink(const avalue: tifiintegerlinkcomp); + procedure setvalue(const avalue: integer); + published + property ifilink: tifiintegerlinkcomp read getifilink write setifilink; + property value: integer read fvalue write setvalue default 0; + property ondatachange: updateintegereventty read fondatachange + write fondatachange; + end; + + tifiint64endpoint = class(tifidataendpoint) + private + fvalue: int64; + fondatachange: updateint64eventty; + function getifilink: tifiint64linkcomp; + procedure setifilink(const avalue: tifiint64linkcomp); + procedure setvalue(const avalue: int64); + published + property ifilink: tifiint64linkcomp read getifilink write setifilink; + property value: int64 read fvalue write setvalue default 0; + property ondatachange: updateint64eventty read fondatachange + write fondatachange; + end; + + tifipointerendpoint = class(tifidataendpoint) + private + fvalue: pointer; + fondatachange: updatepointereventty; + function getifilink: tifipointerlinkcomp; + procedure setifilink(const avalue: tifipointerlinkcomp); + procedure setvalue(const avalue: pointer); + protected + procedure getifivalue(var avalue) override; + procedure setifivalue(const avalue) override; + public + property value: pointer read fvalue write setvalue default nil; + published + property ifilink: tifipointerlinkcomp read getifilink write setifilink; + property ondatachange: updatepointereventty read fondatachange + write fondatachange; + end; + + tifibooleanendpoint = class(tifidataendpoint) + private + fvalue: boolean; + fondatachange: updatebooleaneventty; + function getifilink: tifibooleanlinkcomp; + procedure setifilink(const avalue: tifibooleanlinkcomp); + procedure setvalue(const avalue: boolean); + published + property ifilink: tifibooleanlinkcomp read getifilink write setifilink; + property value: boolean read fvalue write setvalue default false; + property ondatachange: updatebooleaneventty read fondatachange + write fondatachange; + end; + + tifirealendpoint = class(tifidataendpoint) + private + fvalue: real; + fondatachange: updaterealeventty; + function getifilink: tifireallinkcomp; + procedure setifilink(const avalue: tifireallinkcomp); + procedure setvalue(const avalue: real); + public + constructor create(aowner: tcomponent); override; + published + property ifilink: tifireallinkcomp read getifilink write setifilink; + property value: real read fvalue write setvalue; + property ondatachange: updaterealeventty read fondatachange + write fondatachange; + end; + + tifidatetimeendpoint = class(tifidataendpoint) + private + fvalue: tdatetime; + fondatachange: updatedatetimeeventty; + function getifilink: tifidatetimelinkcomp; + procedure setifilink(const avalue: tifidatetimelinkcomp); + procedure setvalue(const avalue: tdatetime); + public + constructor create(aowner: tcomponent); override; + published + property ifilink: tifidatetimelinkcomp read getifilink write setifilink; + property value: tdatetime read fvalue write setvalue; + property ondatachange: updatedatetimeeventty read fondatachange + write fondatachange; + end; + + tifistringendpoint = class(tifidataendpoint) + private + fvalue: msestring; + fondatachange: updatestringeventty; + function getifilink: tifistringlinkcomp; + procedure setifilink(const avalue: tifistringlinkcomp); + procedure setvalue(const avalue: msestring); + public + published + property ifilink: tifistringlinkcomp read getifilink write setifilink; + property value: msestring read fvalue write setvalue; + property ondatachange: updatestringeventty read fondatachange + write fondatachange; + end; + + tifiactionendpoint = class(tmsecomponent,iifiexeclink) + private + fonexecute: notifyeventty; + procedure setifilink(const avalue: tifiactionlinkcomp); + //iifilink + function getifilinkkind: ptypeinfo; + protected + fifilink: tifiactionlinkcomp; + public + //iifiexeclink + procedure execute(const force: boolean = false); + procedure ifisetenabled(const avalue: boolean); + published + property ifilink: tifiactionlinkcomp read fifilink write setifilink; + property onexecute: notifyeventty read fonexecute write fonexecute; + end; + +implementation + +{ tifidataendpoint } + +function tifidataendpoint.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iifidatalink); +end; + +procedure tifidataendpoint.setifilink(const avalue: tifilinkcomp); +begin + mseificomp.setifilinkcomp(iifidatalink(self),avalue,fifilink); +end; + +function tifidataendpoint.ifigriddata: tdatalist; +begin + result:= nil; +end; + +procedure tifidataendpoint.updateifigriddata(const sender: tobject; + const alist: tdatalist); +begin + //dummy +end; + +function tifidataendpoint.getgriddata: tdatalist; +begin + result:= nil; +end; + +function tifidataendpoint.getvalueprop: ppropinfo; +begin + result:= nil; +end; + +procedure tifidataendpoint.getifivalue(var avalue); +begin + //dummy +end; + +procedure tifidataendpoint.setifivalue(const avalue); +begin + //dummy +end; + +procedure tifidataendpoint.updatereadonlystate; +begin + //dummy +end; + +procedure tifidataendpoint.change; +begin + if canevent(tmethod(fonchange)) then begin + fonchange(self); + end; + if fifiserverintf <> nil then begin + iifidataserver(fifiserverintf).valuechanged(iifidatalink(self)); + end; +end; + +{ tifiintegerendpoint } + +function tifiintegerendpoint.getifilink: tifiintegerlinkcomp; +begin + result:= tifiintegerlinkcomp(fifilink); +end; + +procedure tifiintegerendpoint.setifilink(const avalue: tifiintegerlinkcomp); +begin + inherited setifilink(avalue); +end; + +procedure tifiintegerendpoint.setvalue(const avalue: integer); +begin + fvalue:= avalue; + if canevent(tmethod(fondatachange)) then begin + fondatachange(self,fvalue); + end; + change; +end; + +{ tifiint64endpoint } + +function tifiint64endpoint.getifilink: tifiint64linkcomp; +begin + result:= tifiint64linkcomp(fifilink); +end; + +procedure tifiint64endpoint.setifilink(const avalue: tifiint64linkcomp); +begin + inherited setifilink(avalue); +end; + +procedure tifiint64endpoint.setvalue(const avalue: int64); +begin + fvalue:= avalue; + if canevent(tmethod(fondatachange)) then begin + fondatachange(self,fvalue); + end; + change; +end; + +{ tifipointerendpoint } + +function tifipointerendpoint.getifilink: tifipointerlinkcomp; +begin + result:= tifipointerlinkcomp(fifilink); +end; + +procedure tifipointerendpoint.setifilink(const avalue: tifipointerlinkcomp); +begin + inherited setifilink(avalue); +end; + +procedure tifipointerendpoint.setvalue(const avalue: pointer); +begin + fvalue:= avalue; + if canevent(tmethod(fondatachange)) then begin + fondatachange(self,fvalue); + end; + change; +end; + +procedure tifipointerendpoint.getifivalue(var avalue); +begin + pointer(avalue):= fvalue; +end; + +procedure tifipointerendpoint.setifivalue(const avalue); +begin + fvalue:= pointer(avalue); +end; + +{ tifibooleanendpoint } + +function tifibooleanendpoint.getifilink: tifibooleanlinkcomp; +begin + result:= tifibooleanlinkcomp(fifilink); +end; + +procedure tifibooleanendpoint.setifilink(const avalue: tifibooleanlinkcomp); +begin + inherited setifilink(avalue); +end; + +procedure tifibooleanendpoint.setvalue(const avalue: boolean); +begin + fvalue:= avalue; + if canevent(tmethod(fondatachange)) then begin + fondatachange(self,fvalue); + end; + change; +end; + +{ tifirealendpoint } + +constructor tifirealendpoint.create(aowner: tcomponent); +begin + fvalue:= emptyreal; + inherited; +end; + +function tifirealendpoint.getifilink: tifireallinkcomp; +begin + result:= tifireallinkcomp(fifilink); +end; + +procedure tifirealendpoint.setifilink(const avalue: tifireallinkcomp); +begin + inherited setifilink(avalue); +end; + +procedure tifirealendpoint.setvalue(const avalue: real); +begin + fvalue:= avalue; + if canevent(tmethod(fondatachange)) then begin + fondatachange(self,fvalue); + end; + change; +end; + +{ tifidatetimeendpoint } + +constructor tifidatetimeendpoint.create(aowner: tcomponent); +begin + fvalue:= emptydatetime; + inherited; +end; + +function tifidatetimeendpoint.getifilink: tifidatetimelinkcomp; +begin + result:= tifidatetimelinkcomp(fifilink); +end; + +procedure tifidatetimeendpoint.setifilink(const avalue: tifidatetimelinkcomp); +begin + inherited setifilink(avalue); +end; + +procedure tifidatetimeendpoint.setvalue(const avalue: tdatetime); +begin + fvalue:= avalue; + if canevent(tmethod(fondatachange)) then begin + fondatachange(self,fvalue); + end; + change; +end; + +{ tifistringendpoint } + +function tifistringendpoint.getifilink: tifistringlinkcomp; +begin + result:= tifistringlinkcomp(fifilink); +end; + +procedure tifistringendpoint.setifilink(const avalue: tifistringlinkcomp); +begin + inherited setifilink(avalue); +end; + +procedure tifistringendpoint.setvalue(const avalue: msestring); +begin + fvalue:= avalue; + if canevent(tmethod(fondatachange)) then begin + fondatachange(self,fvalue); + end; + change; +end; + +{ tifiactionendpoint } + +procedure tifiactionendpoint.setifilink(const avalue: tifiactionlinkcomp); +begin + mseificomp.setifilinkcomp(iifiexeclink(self),avalue,tifilinkcomp(fifilink)); +end; + +procedure tifiactionendpoint.execute(const force: boolean = false); +begin + if canevent(tmethod(fonexecute)) then begin + fonexecute(self); + end; + if fifiserverintf <> nil then begin + fifiserverintf.execute(iifiexeclink(self)); + end; +end; + +procedure tifiactionendpoint.ifisetenabled(const avalue: boolean); +begin + //dummy +end; + +function tifiactionendpoint.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iifiexeclink); +end; + +end. diff --git a/mseide-msegui/lib/common/ifi/mseifiglob.pas b/mseide-msegui/lib/common/ifi/mseifiglob.pas new file mode 100644 index 0000000..6f02fdc --- /dev/null +++ b/mseide-msegui/lib/common/ifi/mseifiglob.pas @@ -0,0 +1,62 @@ +{ MSEgui Copyright (c) 2007-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseifiglob; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +interface +uses + mseglob,mseeditglob,typinfo,mseinterfaces; +{$ifdef mse_no_ifi} + {$error 'MSEifi support required, please do not compile with "-dmse_no_ifi"'} +{$endif} +const + ifiwidgetstatename = '#widgetstate#'; + ifiwidgetmodalresultname = '#modalres#'; +{$ifdef FPC} + boolprops = [tkbool,tkinteger,tkenumeration]; +{$else} + boolprops = [tkinteger,tkenumeration]; +{$endif} + +type + ifiwidgetstatety = ({iws_closed,}iws_loaded,iws_releasing,iws_destroying, + iws_visible,iws_enabled,iws_entered,iws_focused,iws_active); + ifiwidgetstatesty = set of ifiwidgetstatety; +const + ifidatatypes = [dl_integer,dl_int64,dl_currency,dl_real, + dl_msestring,dl_ansistring,dl_msestringint, + dl_realint,dl_realsum]; + +type + iificlient = interface; + + iifiserver = interface(inullinterface) + procedure execute(const sender: iificlient); +// procedure valuechanged(const sender: iificlient); + procedure statechanged(const sender: iificlient; + const astate: ifiwidgetstatesty); + procedure dataentered(const sender: iificlient; const arow: integer); + procedure closequery(const sender: iificlient; + var amodalresult: modalresultty); + procedure sendmodalresult(const sender: iificlient; + const amodalresult: modalresultty); + procedure updateoptionsedit(var avalue: optionseditty); + end; + + iificlient = interface(iobjectlink)[miid_iificlient] + procedure setifiserverintf(const aintf: iifiserver); + function getdefaultifilink: iificlient; + function getifidatatype: listdatatypety; + end; + ificommandcodety = (icc_none,icc_close,icc_release); + iificommand = interface(inullinterface)[miid_iificommand] + procedure executeificommand(var acommand: ificommandcodety); + end; +implementation +end. diff --git a/mseide-msegui/lib/common/ifi/mseifigui.pas b/mseide-msegui/lib/common/ifi/mseifigui.pas new file mode 100644 index 0000000..ac6014b --- /dev/null +++ b/mseide-msegui/lib/common/ifi/mseifigui.pas @@ -0,0 +1,856 @@ +{ MSEgui Copyright (c) 2007-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseifigui; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses,mseclasses,mseguiglob,mseifiglob,mseifi,mseact,msegui,typinfo, + msestrings,mseapplication,mseforms,msedatanodes,msedataedits, + msearrayprops,mseglob,msetypes,mseifilink,msewidgetgrid,msemenus, + mseevent,msegrids,msegraphutils,msedatalist,mseificomp,mseificompglob, + mseifidialogcomp,msegraphics; + +type + + ifiwidgetlinkoptionty = (iwlo_sendvalue,iwlo_sendmodalresult, + iwlo_sendhide,iwlo_sendshow, + iwlo_sendfocus,iwlo_senddefocus,iwlo_sendactivate,iwlo_senddeactivate); + ifiwidgetlinkoptionsty = set of ifiwidgetlinkoptionty; +const + widgetstateoptionsty = [iwlo_sendhide,iwlo_sendshow,iwlo_sendfocus, + iwlo_senddefocus,iwlo_sendactivate,iwlo_senddeactivate]; +type + + tvaluewidgetlink = class(tcustomvaluecomponentlink) + private + foptions: ifiwidgetlinkoptionsty; + fwidgetstatebefore: ifiwidgetstatesty; + function getwidget: twidget; + procedure setwidget(const avalue: twidget); + published + property widget: twidget read getwidget write setwidget; + property options: ifiwidgetlinkoptionsty read foptions + write foptions default []; + end; + + tvaluewidgetlinks = class(tvaluelinks) + private + function getitems(const index: integer): tvaluewidgetlink; + protected + function getitemclass: modulelinkpropclassty; override; + public + class function getitemclasstype: persistentclassty; override; + function byname(const aname: string): tvaluewidgetlink; + property items[const index: integer]: tvaluewidgetlink read getitems; default; + end; + + tformlink = class(tcustommodulelink) + private + function getvaluewidgets: tvaluewidgetlinks; + procedure setvaluewidgets(const avalue: tvaluewidgetlinks); + protected + function widgetcommandreceived(const atag: integer; const aname: string; + const acommand: ifiwidgetcommandty): boolean; + function widgetpropertiesreceived(const atag: integer; const aname: string; + const adata: pifibytesty): boolean; + function processdataitem(const adata: pifirecty; var adatapo: pchar; + const atag: integer; const aname: string): boolean; override; + procedure valuechanged(const sender: iificlient); override; + procedure statechanged(const sender: iificlient; + const astate: ifiwidgetstatesty); override; + procedure sendmodalresult(const sender: iificlient; + const amodalresult: modalresultty); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property valuewidgets: tvaluewidgetlinks read getvaluewidgets + write setvaluewidgets; + property valuecomponents; + property linkname; + property actionsrx; + property actionstx; + property modulesrx; + property modulestx; + property channel; + property options; + end; + + trxwidgetgrid = class; + + tifiwidgetgridcontroller = class(tifigridcontroller) + protected + procedure processdata(const adata: pifirecty; var adatapo: pchar); override; + procedure setowneractive(const avalue: boolean); override; + function encodegriddata(const asequence: sequencety): ansistring; override; + public + constructor create(const aowner: trxwidgetgrid; + const aintf: iactivatorclient); + end; + + tifiwidgetcol = class(twidgetcol) + protected + procedure datachange(const arow: integer); override; + end; + ifiwidgetcolarty = array of tifiwidgetcol; + + rxwidgetstatety = ({rws_openpending,}rws_datareceived,rws_commandsending); + rxwidgetstatesty = set of rxwidgetstatety; + + trxwidgetgrid = class(twidgetgrid,iifimodulelink) + private + factive: boolean; + procedure setactive1(const avalue: boolean); + protected + fistate: rxwidgetstatesty; + fifi: tifiwidgetgridcontroller; + procedure setactive(const avalue: boolean); override; + procedure setifi(const avalue: tifiwidgetgridcontroller); + procedure loaded; override; + procedure internalopen; + procedure internalclose; + procedure docolmoved(const fromindex,toindex: integer); override; + procedure dorowsmoved(const fromindex,toindex,count: integer); override; + procedure dorowsinserted(const index,count: integer); override; + procedure dorowsdeleted(index,count: integer); override; + procedure rowstatechanged(const arow: integer); override; + procedure docellevent(var info: celleventinfoty); override; + procedure createdatacol(const index: integer; out item: tdatacol); override; + procedure setselected(const cell: gridcoordty; + const avalue: boolean); override; + //iifimodulelink + procedure connectmodule(const sender: tcustommodulelink); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property ifi: tifiwidgetgridcontroller read fifi write setifi; + property active: boolean read factive write setactive1 default false; + end; + + getdialogclasseventty = procedure(const sender: tobject; + var adialogclass: custommseformclassty) of object; + + tifidialog = class(tmsecomponent,iifidialoglink) + private + fifilink: tifidialoglinkcomp; + fongetdialogclass: getdialogclasseventty; + function getifilinkkind: ptypeinfo; + procedure setifilink(const avalue: tifidialoglinkcomp); + protected + function showdialog(out adialog: tactcomponent): modalresultty; virtual; + published + property ifilink: tifidialoglinkcomp read fifilink write setifilink; + property ongetdialogclass: getdialogclasseventty + read fongetdialogclass write fongetdialogclass; + end; + +implementation +uses + sysutils,msestream,msesysutils,msetmpmodules,mseeditglob,mselistbrowser; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tcustommodulelink1 = class(tcustommodulelink); + tdatacols1 = class(tdatacols); + tdialogclientcontroller1 = class(tdialogclientcontroller); + +// tlinkdata1 = class(tlinkdata); + +{ tvaluewidgetlink } + +function tvaluewidgetlink.getwidget: twidget; +begin + result:= twidget(fcomponent); +end; + +procedure tvaluewidgetlink.setwidget(const avalue: twidget); +var + intf1: iificlient; +begin + intf1:= nil; + fwidgetstatebefore:= []; + fvalueproperty:= nil; + if (avalue <> nil) and + not getcorbainterface(avalue,typeinfo(iificlient),intf1) then begin + raise exception.create(avalue.name+': No ifiwidget.'); + end; + if fintf <> nil then begin + fintf.setifiserverintf(nil); + end; + fintf:= intf1; + if fintf <> nil then begin + fintf:= fintf.getdefaultifilink(); + fintf.setifiserverintf(iifiserver(tcustommodulelink(fowner))); + end; + inherited component:= avalue; +end; + +{ tvaluewidgetlinks } + +class function tvaluewidgetlinks.getitemclasstype: persistentclassty; +begin + result:= tvaluewidgetlink; +end; + +function tvaluewidgetlinks.getitems(const index: integer): tvaluewidgetlink; +begin + result:= tvaluewidgetlink(inherited getitems(index)); +end; + +function tvaluewidgetlinks.byname(const aname: string): tvaluewidgetlink; +begin + result:= tvaluewidgetlink(inherited byname(aname)); +end; + +function tvaluewidgetlinks.getitemclass: modulelinkpropclassty; +begin + result:= tvaluewidgetlink; +end; + +{ tformlink } + +constructor tformlink.create(aowner: tcomponent); +begin + if fvalues = nil then begin + fvalues:= tvaluewidgetlinks.create(self); + end; + inherited; +end; + +destructor tformlink.destroy; +begin + inherited; +end; + +function tformlink.getvaluewidgets: tvaluewidgetlinks; +begin + result:= tvaluewidgetlinks(fvalues); +end; + +procedure tformlink.setvaluewidgets(const avalue: tvaluewidgetlinks); +begin + fvalues.assign(avalue); +end; + +function tformlink.processdataitem(const adata: pifirecty; + var adatapo: pchar; const atag: integer; const aname: string): boolean; +var + command1: ifiwidgetcommandty; +begin + with adata^ do begin + case header.kind of + ik_widgetcommand: begin + command1:= pifiwidgetcommandty(adatapo)^; + result:= widgetcommandreceived(atag,aname,command1); + end; + ik_widgetproperties: begin + result:= widgetpropertiesreceived(atag,aname,pifibytesty(adatapo)); + end; + else begin + result:= inherited processdataitem(adata,adatapo,atag,aname); + end; + end; + end; +end; + +function tformlink.widgetcommandreceived(const atag: integer; + const aname: string; const acommand: ifiwidgetcommandty): boolean; +var + wi1: tvaluewidgetlink; +begin + wi1:= tvaluewidgetlink(fvalues.finditem(aname)); + result:= wi1 <> nil; + if result and (wi1.fcomponent <> nil) then begin + with wi1.widget do begin + case acommand of + iwc_enable: begin + enabled:= true; + end; + iwc_disable: begin + enabled:= false; + end; + iwc_show: begin + visible:= true; + end; + iwc_hide: begin + visible:= false; + end; + end; + end; + end; +end; + +function tformlink.widgetpropertiesreceived(const atag: integer; + const aname: string; const adata: pifibytesty): boolean; +var + wi1: tvaluewidgetlink; + stream1: tmemorystream; +begin + wi1:= tvaluewidgetlink(fvalues.finditem(aname)); + result:= wi1 <> nil; + if result and (wi1.fcomponent <> nil) then begin + stream1:= tmemorycopystream.create(@adata^.data,adata^.length); + try + stream1.readcomponent(wi1.fcomponent); + finally + stream1.free; + end; + end; +end; + +procedure tformlink.valuechanged(const sender: iificlient); +var + int1: integer; +begin + if hasconnection then begin + with tvaluewidgetlinks(fvalues ) do begin + for int1:= 0 to high(fitems) do begin + with tvaluewidgetlink(fitems[int1]) do begin + if fupdatelock = 0 then begin + if (fintf = sender) then begin + if iwlo_sendvalue in options then begin + sendvalue(fvalueproperty); + end; + break; + end; + end; + end; + end; + end; + end; +end; + +procedure tformlink.sendmodalresult(const sender: iificlient; + const amodalresult: modalresultty); +var + int1: integer; +begin + if hasconnection then begin + with tvaluewidgetlinks(fvalues ) do begin + for int1:= 0 to high(fitems) do begin + with tvaluewidgetlink(fitems[int1]) do begin + if fupdatelock = 0 then begin + if (fintf = sender) then begin + if iwlo_sendmodalresult in options then begin + sendmodalresult(amodalresult); + end; + break; + end; + end; + end; + end; + end; + end; +end; + +procedure tformlink.statechanged(const sender: iificlient; + const astate: ifiwidgetstatesty); +var + int1: integer; + states1: ifiwidgetstatesty; +begin + if hasconnection then begin + with tvaluewidgetlinks(fvalues ) do begin + for int1:= 0 to high(fitems) do begin + with tvaluewidgetlink(fitems[int1]) do begin + if (fintf = sender) then begin + if options * widgetstateoptionsty <> [] then begin + states1:= ifiwidgetstatesty( + {$ifdef FPC}longword{$else}byte{$endif}(fwidgetstatebefore) xor + {$ifdef FPC}longword{$else}byte{$endif}(astate)); + if (iws_visible in states1) and + ((iwlo_sendshow in options) and (iws_visible in astate) or + (iwlo_sendhide in options) and not (iws_visible in astate)) or + (iws_focused in states1) and + ((iwlo_sendfocus in options) and (iws_focused in astate) or + (iwlo_senddefocus in options) and not(iws_focused in astate)) or + (iws_active in states1) and + ((iwlo_sendactivate in options) and (iws_active in astate) or + (iwlo_senddeactivate in options) and not(iws_active in astate)) + then begin + sendstate(astate); + end; + end; + fwidgetstatebefore:= astate; + break; + end; + end; + end; + end; + end; +end; + +{ tifiwidgetgridcontroller } + +constructor tifiwidgetgridcontroller.create(const aowner: trxwidgetgrid; + const aintf: iactivatorclient); +begin + inherited create(aowner,aintf); +end; + +procedure tifiwidgetgridcontroller.setowneractive(const avalue: boolean); +begin + trxwidgetgrid(fowner).active:= avalue; +end; + +function tifiwidgetgridcontroller.encodegriddata( + const asequence: sequencety): ansistring; +var + po1: pchar; + int1,int2,int3: integer; + ar1: booleanarty; +begin + with trxwidgetgrid(fowner) do begin + setlength(ar1,datacols.count); + int2:= 0; + int3:= 0; + for int1:= 0 to datacols.count - 1 do begin + with datacols[int1] do begin + ar1[int1]:= (name <> '') and (datalist <> nil) and + (datalist.datatype in ifidatatypes); + if ar1[int1] then begin + inc(int3); + int2:= int2 + (sizeof(listdatatypety)+1) + length(name) + + datalisttoifidata(datalist); + end; + end; + end; +{$warnings off} + int2:= int2 + datalisttoifidata(tdatacols1(datacols).frowstate); +{$warnings on} + inititemheader(result,ik_griddata,asequence,int2,po1); + with pgriddatadataty(po1)^ do begin + rows:= rowcount; + cols:= int3; + po1:= @data; + for int1:= 0 to high(ar1) do begin + if ar1[int1] then begin + with datacols[int1] do begin + with pcoldataty(po1)^ do begin + kind:= datalist.datatype; + po1:= @name; + end; + inc(po1,stringtoifiname(name,pifinamety(po1))); + datalisttoifidata(datalist,po1); + end; + end; + end; +{$warnings off} + datalisttoifidata(tdatacols1(datacols).frowstate,po1); +{$warnings on} + end; + end; +end; + +procedure tifiwidgetgridcontroller.processdata(const adata: pifirecty; + var adatapo: pchar); +var + int1,int2: integer; + rows1,cols1: integer; + kind1: listdatatypety; + po1: pchar; + str1: ansistring; + ckind1: gridcommandkindty; + source1,dest1,count1: integer; + rowstate1: rowstaterowheightty; + select1: selectdataty; + datalist1: subdatainfoty; + po3: prowstaterowheightty; + ifikind1: ifidatakindty; +begin + with adata^.header do begin + case kind of + ik_requestopen: begin + senddata(encodegriddata(sequence)); + end; + ik_griddata: begin + if (igo_state in foptionsrx) or + (answersequence <> 0) and (answersequence = fdatasequence) then begin + with trxwidgetgrid(fowner) do begin + beginupdate; + try + with pgriddatadataty(adatapo)^ do begin + rows1:= rows; + rowcount:= rows1; + cols1:= cols; + po1:= @data; + end; + for int1:= 0 to cols1 - 1 do begin + with pcoldataty(po1)^ do begin + kind1:= kind; + po1:= @name; + inc(po1,ifinametostring(pifinamety(po1),str1)); + inc(po1,ifidatatodatalist(kind1,rows1,po1, + datacols.colsubdatainfo(str1))); + end; + end; +{$warnings off} + inc(po1,ifidatatodatalist(dl_rowstate,rows1,po1, + tdatacols1(datacols).frowstate)); +{$warnings on} + include(fistate,rws_datareceived); + finally + endupdate; + end; + end; + end; + end; + ik_gridcommand: begin + inc(adatapo,decodegridcommanddata(adatapo,ckind1,source1,dest1,count1)); + with trxwidgetgrid(fowner) do begin + inc(fcommandlock); + try + case ckind1 of + gck_insertrow: begin + if igo_rowinsert in foptionsrx then begin + insertrow(dest1,count1); + end; + end; + gck_deleterow: begin + if igo_rowdelete in foptionsrx then begin + deleterow(dest1,count1); + end; + end; + gck_moverow: begin + if igo_rowmove in foptionsrx then begin + moverow(source1,dest1,count1); + end; + end; + gck_rowenter: begin + if igo_rowenter in foptionsrx then begin + row:= dest1; + end; + end; + end; + finally + dec(fcommandlock); + end; + end; + end; + ik_coldatachange: begin + if igo_coldata in foptionsrx then begin + inc(fcommandlock); + try + int1:= pcolitemdataty(adatapo)^.header.row; + ifinametostring(@pcolitemdataty(adatapo)^.header.name,str1); + inc(adatapo,sizeof(colitemheaderty)+length(str1)); + datalist1.list:= nil; + if igo_coldata in foptionsrx then begin + datalist1:= trxwidgetgrid(fowner).fdatacols.colsubdatainfo(str1); + end; //skip data otherwise + inc(adatapo,decodeifidata(pifidataty(adatapo),int1,datalist1)); + finally + dec(fcommandlock); + end; + end; + end; + ik_rowstatechange: begin + if igo_rowstate in foptionsrx then begin + inc(fcommandlock); + try + int1:= prowstatedataty(adatapo)^.header.row; + inc(adatapo,sizeof(rowstateheaderty)); + ifikind1:= pifidataty(adatapo)^.header.kind; + case ifikind1 of + idk_rowstatecolmerge: begin + inc(adatapo,decodeifidata(pifidataty(adatapo), + prowstatecolmergety(@rowstate1)^)); + end; + idk_rowstaterowheight: begin + inc(adatapo,decodeifidata(pifidataty(adatapo), + prowstaterowheightty(@rowstate1)^)); + + end; + else begin + inc(adatapo,decodeifidata(pifidataty(adatapo), + prowstatety(@rowstate1)^)); + end; + end; + with trxwidgetgrid(fowner) do begin + int2:= ord(datacols.rowstate.infolevel) - ord(ril_normal); + if ord(ifikind1)-ord(idk_rowstate) < int2 then begin + ifikind1:= ifidatakindty(ord(idk_rowstate)+int2); + end; + rowcolorstate[int1]:= rowstate1.normal.color; + rowfontstate[int1]:= rowstate1.normal.font; + rowhidden[int1]:= rowstate1.normal.fold and foldhiddenmask <> 0; + rowfoldlevel[int1]:= rowstate1.normal.fold and foldlevelmask; + if ifikind1 >= idk_rowstatecolmerge then begin + po3:= prowstaterowheightty(fdatacols.rowstate.getitempo(int1)); + if po3^.colmerge.merged <> rowstate1.colmerge.merged then begin + po3^.colmerge.merged:= rowstate1.colmerge.merged; + tdatacols1(fdatacols).mergechanged(int1); + end; + if ifikind1 >= idk_rowstaterowheight then begin + rowheight[int1]:= rowstate1.rowheight.height; + end; + end; + end; + finally + dec(fcommandlock); + end; + end; + end; + ik_selection: begin + if igo_selection in foptionsrx then begin + inc(fcommandlock); + try + inc(adatapo,decodeifidata(pifidataty(adatapo),select1)); + with select1 do begin + trxwidgetgrid(fowner).fdatacols.selected[makegridcoord(col,row)]:= select; + end; + finally + dec(fcommandlock); + end; + end; + end; + end; + end; +end; + +{ tifiwidgetcol } + +procedure tifiwidgetcol.datachange(const arow: integer); +begin + with trxwidgetgrid(fcellinfo.grid).fifi do begin + if (self.name <> '') and (arow >= 0) and cancommandsend(igo_coldata) and + (fdata <> nil) then begin + senditem(ik_coldatachange,[encodecolchangedata(self.name,arow,fdata)]); + end; + end; +end; + +{ trxwidgetgrid } + +constructor trxwidgetgrid.create(aowner: tcomponent); +begin + if fifi = nil then begin + fifi:= tifiwidgetgridcontroller.create(self,iactivatorclient(self)); + end; + inherited; +end; + +destructor trxwidgetgrid.destroy; +begin + inherited; + fifi.free; +end; + +procedure trxwidgetgrid.setifi(const avalue: tifiwidgetgridcontroller); +begin + fifi.assign(avalue); +end; + +procedure trxwidgetgrid.setactive(const avalue: boolean); +begin + if avalue <> factive then begin + if avalue then begin + try + internalopen; + except + active:= false; + raise; + end; + factive:= true; + end + else begin + internalclose; + factive:= false; + end; + end; +end; + +procedure trxwidgetgrid.loaded; +begin + inherited; + fifi.loaded; +end; + +procedure trxwidgetgrid.internalopen; +var + str1: string; + po1: pchar; +begin + with fifi do begin + if cansend then begin + inititemheader(str1,ik_requestopen,0,0,po1); + if senddataandwait(str1,fdatasequence) and + (rws_datareceived in fistate) then begin + end + else begin + raise exception.create('Can not open '+name+'.'); //sysutils.abort; + end; + end; + end; +end; + +procedure trxwidgetgrid.internalclose; +begin + rowcount:= 0; +end; + +procedure trxwidgetgrid.docolmoved(const fromindex: integer; + const toindex: integer); +begin + inherited; +end; + +procedure trxwidgetgrid.dorowsmoved(const fromindex: integer; + const toindex: integer; const count: integer); +begin + inherited; + with fifi do begin + if cancommandsend(igo_rowmove) then begin + senditem(ik_gridcommand,[ + encodegridcommanddata(gck_moverow,fromindex,toindex,count)]); + end; + end; +end; + +procedure trxwidgetgrid.dorowsinserted(const index: integer; + const count: integer); +begin + inherited; + with fifi do begin + if cancommandsend(igo_rowinsert) then begin + senditem(ik_gridcommand,[ + encodegridcommanddata(gck_insertrow,index,index,count)]); + end; + end; +end; + +procedure trxwidgetgrid.dorowsdeleted(index: integer; count: integer); +begin + inherited; + with fifi do begin + if cancommandsend(igo_rowdelete) then begin + senditem(ik_gridcommand,[ + encodegridcommanddata(gck_deleterow,index,index,count)]); + end; + end; +end; + +procedure trxwidgetgrid.rowstatechanged(const arow: integer); +begin + inherited; + with fifi do begin + if cancommandsend(igo_rowstate) then begin + case fdatacols.rowstate.infolevel of + ril_normal: begin + senditem(ik_rowstatechange, + [encoderowstatedata(arow,fdatacols.rowstate.items[arow])]); + end; + ril_colmerge: begin + senditem(ik_rowstatechange, + [encoderowstatedata(arow,fdatacols.rowstate.itemscolmerge[arow])]); + end; + ril_rowheight: begin + senditem(ik_rowstatechange, + [encoderowstatedata(arow,fdatacols.rowstate.itemsrowheight[arow])]); + end; + end; + end; + end; +end; + +procedure trxwidgetgrid.setselected(const cell: gridcoordty; + const avalue: boolean); +begin + inherited; + with fifi do begin + if cancommandsend(igo_selection) then begin + senditem(ik_selection,[encodeselectiondata(cell,avalue)]); + end; + end; +end; + +procedure trxwidgetgrid.docellevent(var info: celleventinfoty); +begin + inherited; + if isrowenter(info) and fifi.cancommandsend(igo_rowenter) then begin + fifi.senditem(ik_gridcommand,[ + encodegridcommanddata(gck_rowenter,info.cell.row,info.cell.row,0)]); + end; +end; + +procedure trxwidgetgrid.createdatacol(const index: integer; out item: tdatacol); +begin + item:= tifiwidgetcol.create(self,fdatacols); +end; + +procedure trxwidgetgrid.connectmodule(const sender: tcustommodulelink); +begin + fifi.connectmodule(sender); +end; + +procedure trxwidgetgrid.setactive1(const avalue: boolean); +begin + if fifi.setactive(avalue) then begin + setactive(avalue); + end; +end; + +{ tifidialog } + +function tifidialog.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iifidialoglink); +end; + +procedure tifidialog.setifilink(const avalue: tifidialoglinkcomp); +begin + mseificomp.setifilinkcomp(iifidialoglink(self),avalue,tifilinkcomp(fifilink)); +end; + +function tifidialog.showdialog(out adialog: tactcomponent): modalresultty; +var + dia1: custommseformclassty; +begin + dia1:= nil; + adialog:= nil; + result:= mr_none; + dia1:= nil; + if owner is tcustommseform then begin + dia1:= custommseformclassty(owner.classtype); + end; + if canevent(tmethod(fongetdialogclass)) then begin + fongetdialogclass(self,dia1); + end; + if dia1 <> nil then begin + adialog:= dia1.create(nil); + if fifilink <> nil then begin + tdialogclientcontroller1(fifilink.controller).beforedialog(adialog); + end; + try + result:= twidget(adialog).show(ml_application); + except + result:= mr_exception; + application.handleexception; + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/ifi/mseifilink.pas b/mseide-msegui/lib/common/ifi/mseifilink.pas new file mode 100644 index 0000000..f582f0d --- /dev/null +++ b/mseide-msegui/lib/common/ifi/mseifilink.pas @@ -0,0 +1,3936 @@ +{ MSEgui Copyright (c) 2007-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseifilink; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses,mseclasses,mseifiglob,mseifi,msearrayprops,mseapplication, + mseact,mseinterfaces, + mseevent,mseglob,msestrings,msetypes,msedatalist,msegraphutils,typinfo, + mseeditglob; + +type + formlinkoptionty = (flo_useclientchannel); + formlinkoptionsty = set of formlinkoptionty; +const + defaultformlinkoptions = [flo_useclientchannel]; +type + tmodulelinkarrayprop = class; + + tmodulelinkprop = class(townedeventpersistent) + private + fprop: tmodulelinkarrayprop; + fname: ansistring; + ftag: integer; + protected + procedure inititemheader(out arec: string; + const akind: ifireckindty; const asequence: sequencety; + const datasize: integer; + out datapo: pchar); virtual; + public + property prop: tmodulelinkarrayprop read fprop; + published + property name: ansistring read fname write fname; + property tag: integer read ftag write ftag default 0; + end; + modulelinkpropclassty = class of tmodulelinkprop; + + tcustommodulelink = class; + + tmodulelinkarrayprop = class(tpersistentarrayprop) + private + fowner: tcustommodulelink; + protected + procedure createitem(const index: integer; var item: tpersistent); override; + function getitemclass: modulelinkpropclassty; virtual; abstract; + public + constructor create(const aowner: tcustommodulelink); + function finditem(const aname: string): tmodulelinkprop; + function byname(const aname: string): tmodulelinkprop; + property owner: tcustommodulelink read fowner; + end; + + tlinkaction = class(tmodulelinkprop) + private + faction: tcustomaction; + procedure setaction(const avalue: tcustomaction); + protected + public + destructor destroy; override; + published + property action: tcustomaction read faction write setaction; + end; + + trxlinkaction = class; + + ifiexecuteeventty = procedure(const sender: trxlinkaction; const atag: integer; + const aparams: variant) of object; + + trxlinkaction = class(tlinkaction) + private + fonexecute: ifiexecuteeventty; + published + property onexecute: ifiexecuteeventty read fonexecute write fonexecute; + //sender = item, avalue = tx tag + end; + + iifitxaction = interface(inullinterface)[miid_iifitxaction] + procedure txactionfired(var adata: ansistring; var adatapo: pchar); + end; + + ttxlinkaction = class(tlinkaction) + private + fificomp: tcomponent; + fificompintf: iifitxaction; + procedure setificomp(const avalue: tcomponent); + protected + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + public + procedure execute; + published + property ificomp: tcomponent read fificomp write setificomp; + end; + + tlinkactions = class(tmodulelinkarrayprop) + private + protected + public + end; + + trxlinkactions = class(tlinkactions) + private + fonexecute: ifiexecuteeventty; + function getitems(const index: integer): trxlinkaction; + protected + function getitemclass: modulelinkpropclassty; override; + public + constructor create(const aowner: tcustommodulelink); + class function getitemclasstype: persistentclassty; override; + function byname(const aname: string): trxlinkaction; + property items[const index: integer]: trxlinkaction read getitems; default; + published + property onexecute: ifiexecuteeventty read fonexecute write fonexecute; + //sender = item, avalue = tx tag + end; + + ttxlinkactions = class; + + ttxactiondestroyhandler = class(tcomponent) + private + fowneractions: ttxlinkactions; + protected + procedure notification(acomponent: tcomponent; + operation: toperation); override; + public + constructor create(aowner: ttxlinkactions); reintroduce; + end; + + ttxlinkactions = class(tlinkactions) + private + fdestroyhandler: ttxactiondestroyhandler; + function getitems(const index: integer): ttxlinkaction; + protected + function getitemclass: modulelinkpropclassty; override; + public + constructor create(const aowner: tcustommodulelink); + destructor destroy; override; + class function getitemclasstype: persistentclassty; override; + function byname(const aname: string): ttxlinkaction; + property items[const index: integer]: ttxlinkaction read getitems; default; + end; + + tlinkmodule = class(tmodulelinkprop) + end; + + ttxlinkmodule = class(tlinkmodule) + private + fmoduleclassname: string; + fmoduleparentclassname: string; + public + procedure sendmodule; + procedure close; + published + property moduleclassname: string read fmoduleclassname write fmoduleclassname; + property moduleparentclassname: string read fmoduleparentclassname + write fmoduleparentclassname; + end; + + ttxlinkmodules = class(tmodulelinkarrayprop) + private + function getitems(const index: integer): ttxlinkmodule; + protected + function getitemclass: modulelinkpropclassty; override; + public + constructor create(const aowner: tcustommodulelink); + class function getitemclasstype: persistentclassty; override; + function byname(const aname: string): ttxlinkmodule; + property items[const index: integer]: ttxlinkmodule read getitems; default; + end; + + trxlinkmodule = class; + rxlinkmoduleeventty = procedure(sender: trxlinkmodule) of object; + + rxlinkoptionty = (rlo_closeconnonfree); + rxlinkoptionsty = set of rxlinkoptionty; + + trxlinkmodule = class(tlinkaction) + private + fmodule: tmsecomponent; + fcommandintf: iificommand; + fonmodulereceived: rxlinkmoduleeventty; + fsequence: sequencety; + foptions: rxlinkoptionsty; + protected + procedure objevent(const sender: iobjectlink; + const event: objecteventty); override; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + procedure domodulereceived; + public + procedure requestmodule; + property module: tmsecomponent read fmodule; + published + property onmodulereceived: rxlinkmoduleeventty read fonmodulereceived + write fonmodulereceived; + property options: rxlinkoptionsty read foptions write foptions default []; + end; + + trxlinkmodules = class(tmodulelinkarrayprop) + private + function getitems(const index: integer): trxlinkmodule; + protected + function finditem(const asequence: sequencety): trxlinkmodule; overload; + function getitemclass: modulelinkpropclassty; override; + public + constructor create(const aowner: tcustommodulelink); + class function getitemclasstype: persistentclassty; override; + function byname(const aname: string): trxlinkmodule; + property items[const index: integer]: trxlinkmodule read getitems; default; + end; + + tvaluelink = class; + + propertychangedeventty = procedure(const sender: tvaluelink; + const atag: integer; const apropertyname: string) of object; + widgetstatechangedeventty = procedure(const sender: tvaluelink; + const atag: integer; const astate: ifiwidgetstatesty) of object; + modalresulteventty = procedure(const sender: tvaluelink; + const atag: integer; const amodalresult: modalresultty) of object; + +//todo: beginupdate/endupdate, use tifivaluelinkcontroller + + tvaluelink = class(tmodulelinkprop) + private + fint64value: int64; + fdoublevalue: double; + fmsestringvalue: msestring; +// fansistringvalue: ansistring; + fdatakind: ifidatakindty; + fonpropertychanged: propertychangedeventty; + fonwidgetstatechanged: widgetstatechangedeventty; + fonmodalresult: modalresulteventty; + procedure checkdatakind(const akind: ifidatakindty); + function getasinteger: integer; + procedure setasinteger(const avalue: integer); + function getaslargeint: int64; + procedure setaslargeint(const avalue: int64); + function getasfloat: double; + procedure setasfloat(const avalue: double); + function getasmsestring: msestring; + procedure setasmsestring(const avalue: msestring); + function getasansistring: ansistring; + procedure setasansistring(const avalue: ansistring); + procedure setenabled(const avalue: boolean); + procedure setvisible(const avalue: boolean); + protected + procedure setdata(const adata: pifidataty; const aname: ansistring); virtual; + procedure initpropertyrecord(out arec: string; const apropertyname: string; + const akind: ifidatakindty; const datasize: integer; out datapo: pchar); + procedure sendvalue(const aname: string; const avalue: int64); overload; + procedure sendvalue(const aname: string; const avalue: double); overload; + procedure sendvalue(const aname: string; const avalue: msestring); overload; + procedure sendvalue(const aname: string; const avalue: ansistring); overload; + procedure sendcommand(const acommand: ifiwidgetcommandty); + public + procedure sendproperty(const aname: string; const avalue: boolean); overload; + procedure sendproperty(const aname: string; const avalue: integer); overload; + procedure sendproperty(const aname: string; const avalue: colorty); overload; + procedure sendproperty(const aname: string; const avalue: int64); overload; + procedure sendproperty(const aname: string; const avalue: string); overload; + procedure sendproperty(const aname: string; const avalue: msestring); overload; + procedure sendproperty(const aname: string; const avalue: realty); overload; + procedure sendproperty(const aname: string; const avalue: currency); overload; + + property asinteger: integer read getasinteger write setasinteger; + property aslargeint: int64 read getaslargeint write setaslargeint; + property asfloat: double read getasfloat write setasfloat; + property asmsestring: msestring read getasmsestring write setasmsestring; + property asstring: string read getasansistring write setasansistring; + property enabled: boolean write setenabled; + property visible: boolean write setvisible; + published + property onpropertychanged: propertychangedeventty read fonpropertychanged + write fonpropertychanged; + property onwidgetstatechanged: widgetstatechangedeventty + read fonwidgetstatechanged write fonwidgetstatechanged; + property onmodalresult: modalresulteventty read fonmodalresult + write fonmodalresult; + end; + + tvaluelinks = class(tmodulelinkarrayprop) + private + function getitems(const index: integer): tvaluelink; + protected + function getitemclass: modulelinkpropclassty; override; + public + class function getitemclasstype: persistentclassty; override; + function byname(const aname: string): tvaluelink; + property items[const index: integer]: tvaluelink read getitems; default; + end; + + tcustomvaluecomponentlink = class(tvaluelink) + private + procedure setcomponent(const avalue: tmsecomponent); + procedure checkcomponent; + protected + fcomponent: tmsecomponent; + fintf: iificlient; + fvalueproperty: ppropinfo; + fupdatelock: integer; + procedure setdata(const adata: pifidataty; const aname: ansistring); override; + procedure sendvalue(const aproperty: ppropinfo); overload; + procedure sendstate(const astate: ifiwidgetstatesty); + procedure sendmodalresult(const amodalresult: modalresultty); + public + procedure sendvalue(const aname: string; const avalue: colorty); overload; + procedure sendproperties; + property component: tmsecomponent read fcomponent write setcomponent; + end; + + tvaluecomponentlink = class(tcustomvaluecomponentlink) + published + property component; + end; + + tvaluecomponentlinks = class(tvaluelinks) + private + function getitems(const index: integer): tvaluecomponentlink; + protected + function getitemclass: modulelinkpropclassty; override; + public + class function getitemclasstype: persistentclassty; override; + function byname(const aname: string): tvaluecomponentlink; + property items[const index: integer]: tvaluecomponentlink read getitems; default; + end; + + iifimodulelink = interface(inullinterface)[miid_iifimodulelink] + procedure connectmodule(const sender: tcustommodulelink); + end; + + tcustommodulelink = class(tifiiolinkcomponent,iifiserver,iifimodulelink) + private + factionsrx: trxlinkactions; + factionstx: ttxlinkactions; + fmodulestx: ttxlinkmodules; + fmodulesrx: trxlinkmodules; + foptions: formlinkoptionsty; + flinkname: string; + procedure setactionsrx(const avalue: trxlinkactions); + procedure setactionstx(const avalue: ttxlinkactions); + procedure setmodulestx(const avalue: ttxlinkmodules); + procedure setmodulesrx(const avalue: trxlinkmodules); + procedure setvalues(const avalue: tvaluelinks); + procedure setvaluecomponents(const avalue: tvaluecomponentlinks); + protected + fvalues: tvaluelinks; + fvaluecomponents: tvaluecomponentlinks; + function hasconnection: boolean; + function encodemodulecommand(const acommand: ificommandcodety; + const atag: integer; const aname: string): string; + procedure closemodule(const atag: integer; const aname: string); + function encodeactionfired(const atag: integer; const aname: string; + out adatapo: pchar): string; + procedure actionfired(const sender: tlinkaction; + const acompintf: iifitxaction); virtual; + function actionreceived(const adata: pifirecty; var adatapo: pchar; + const atag: integer; const aname: string):boolean; + function requestmodulereceived(const atag: integer; const aname: string; + const asequence: sequencety): boolean; + function modulecommandreceived(const atag: integer; const aname: string; + const adata: pmodulecommanddataty): boolean; + function moduledatareceived(const atag: integer; const aname: string; + const asequence: sequencety; + const adata: pmoduledatadataty): boolean; + procedure moduleloaded(const sender: tmsecomponent); + function propertychangereceived(const atag: integer; const aname: string; + const apropertyname: string; const adata: pifidataty): boolean; + + procedure objectevent(const sender: tobject; const event: objecteventty); override; + function processdataitem(const adata: pifirecty; var adatapo: pchar; + const atag: integer; const aname: string): boolean; virtual; + //true if handled + function processdata(const adata: pifirecty): boolean; + //true if handled + function senddata(const adata: ansistring): sequencety; + //returns sequence number + procedure receiveevent(const event: tobjectevent); override; + //iifiserver + procedure execute(const sender: iificlient); virtual; + procedure valuechanged(const sender: iificlient); virtual; + procedure statechanged(const sender: iificlient; + const astate: ifiwidgetstatesty); virtual; + procedure setvalue(const sender: iificlient; + var avalue; var accept: boolean; const arow: integer); + procedure dataentered(const sender: iificlient; const arow: integer); + procedure updateoptionsedit(var avalue: optionseditty); + procedure closequery(const sender: iificlient; + var amodalresult: modalresultty); + procedure sendmodalresult(const sender: iificlient; + const amodalresult: modalresultty); virtual; + //imodulelink + procedure connectmodule(const sender: tcustommodulelink); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure updatecomponent(const anamepath: ansistring; + const aobjecttext: ansistring); + property linkname: string read flinkname write flinkname; + property actionsrx: trxlinkactions read factionsrx write setactionsrx; + property actionstx: ttxlinkactions read factionstx write setactionstx; + property modulesrx: trxlinkmodules read fmodulesrx write setmodulesrx; + property modulestx: ttxlinkmodules read fmodulestx write setmodulestx; + property valuecomponents: tvaluecomponentlinks read fvaluecomponents + write setvaluecomponents; + property values: tvaluelinks read fvalues write setvalues; + property options: formlinkoptionsty read foptions write foptions + default defaultformlinkoptions; + end; + + tmodulelink = class(tcustommodulelink) + published + property linkname; + property actionsrx; + property actionstx; + property modulesrx; + property modulestx; + property values; + property valuecomponents; + property channel; + property options; + end; + + ifirxoptionty = (irxo_useclientchannel,irxo_postecho); + ifirxoptionsty = set of ifirxoptionty; + +const + defaultifirxoptions = [irxo_useclientchannel]; + defaultifirxtimeout = 10000000; //10 second + +type + tificontroller = class(tactivatorcontroller,iifimodulelink) + private + fchannel: tcustomiochannel; + flinkname: string; + ftag: integer; + fdefaulttimeout: integer; + procedure setchannel(const avalue: tcustomiochannel); + protected + foptions: ifirxoptionsty; + procedure objectevent(const sender: tobject; const event: objecteventty); + override; + function senddata(const adata: ansistring; + const asequence: sequencety = 0): sequencety; + function senddataandwait(const adata: ansistring; + out asequence: sequencety; atimeoutus: integer = 0): boolean; + function senditem(const kind: ifireckindty; + const data: array of ansistring): sequencety; + //returns sequence number + procedure inititemheader(out arec: string; + const akind: ifireckindty; const asequence: sequencety; + const datasize: integer; out datapo: pchar); + procedure processdata(const adata: pifirecty; var adatapo: pchar); + virtual; abstract; + function getifireckinds: ifireckindsty; virtual; + //iifimodulelink + procedure connectmodule(const sender: tcustommodulelink); + public + constructor create(const aowner: tcomponent; const aintf: iactivatorclient); + function cansend: boolean; + published + property channel: tcustomiochannel read fchannel write setchannel; + property linkname: string read flinkname write flinkname; + property tag: integer read ftag write ftag default 0; + property options: ifirxoptionsty read foptions write foptions + default defaultifirxoptions; + property timeoutus: integer read fdefaulttimeout write fdefaulttimeout + default defaultifirxtimeout; + end; +{ + tifirxcontroller = class(tificontroller) + end; + tifitxcontroller = class(tificontroller) + end; +} + tifidatacol = class; + + ifidatacolchangeeventty = procedure(const sender: tifidatacol; + const aindex: integer) of object; + + ifidatacolstatety = (icos_selected); + ifidatacolstatesty = set of ifidatacolstatety; + + tifidatacol = class(tindexpersistent) + private + fdata: tdatalist; + fdatakind: ifidatakindty; + fname: ansistring; + fonchange: ifidatacolchangeeventty; + fstate: ifidatacolstatesty; + fselectedrow: integer; + fselectlock: integer; + procedure setdatakind(const avalue: ifidatakindty); + function getdatalist: tdatalist; + function getasinteger(const aindex: integer): integer; + procedure setasinteger(const aindex: integer; const avalue: integer); + function getasint64(const aindex: integer): int64; + procedure setasint64(const aindex: integer; const avalue: int64); + function getascurrency(const aindex: integer): currency; + procedure setascurrency(const aindex: integer; const avalue: currency); + function getasreal(const aindex: integer): real; + procedure setasreal(const aindex: integer; const avalue: real); + function getasmsestring(const aindex: integer): msestring; + procedure setasmsestring(const aindex: integer; const avalue: msestring); + function getasbytes(const aindex: integer): ansistring; + procedure setasbytes(const aindex: integer; const avalue: ansistring); + function getasmsestringint(const aindex: integer): msestringintty; + procedure setasmsestringint(const aindex: integer; const avalue: msestringintty); + function getasmsestringinti(const aindex: integer): integer; + procedure setasmsestringinti(const aindex: integer; const avalue: integer); + function getasmsestringints(const aindex: integer): msestring; + procedure setasmsestringints(const aindex: integer; const avalue: msestring); + function getselected(row: integer): boolean; + procedure setselected(row: integer; const avalue: boolean); + function getmerged(const row: integer): boolean; virtual; + procedure setmerged(const row: integer; const avalue: boolean); virtual; + function getasrealint(const aindex: integer): realintty; + procedure setasrealint(const aindex: integer; const avalue: realintty); + function getasrealintr(const aindex: integer): realty; + procedure setasrealintr(const aindex: integer; const avalue: realty); + function getasrealinti(const aindex: integer): integer; + procedure setasrealinti(const aindex: integer; const avalue: integer); + protected + procedure freedatalist; + procedure checkdatalist; overload; + procedure checkdatalist(const akind: ifidatakindty); overload; + procedure dochange(const sender: tdatalist; const aindex: integer); + procedure doselectionchanged; + procedure beginselect; + procedure endselect; + procedure datachange(const aindex: integer); + public + constructor create(const aowner: tobject; + const aprop: tindexpersistentarrayprop); override; + destructor destroy; override; + property datalist: tdatalist read getdatalist; + + property asinteger[const aindex: integer]: integer read getasinteger + write setasinteger; + property asint64[const aindex: integer]: int64 read getasint64 + write setasint64; + property ascurrency[const aindex: integer]: currency read getascurrency + write setascurrency; + property asreal[const aindex: integer]: real read getasreal + write setasreal; + property asmsestring[const aindex: integer]: msestring read getasmsestring + write setasmsestring; + property asmsestringint[const aindex: integer]: msestringintty + read getasmsestringint write setasmsestringint; + property asmsestringinti[const aindex: integer]: integer + read getasmsestringinti write setasmsestringinti; + property asmsestringints[const aindex: integer]: msestring + read getasmsestringints write setasmsestringints; + property asrealint[const aindex: integer]: realintty read getasrealint write + setasrealint; + property asrealintr[const aindex: integer]: realty read getasrealintr write + setasrealintr; + property asrealinti[const aindex: integer]: integer read getasrealinti write + setasrealinti; + property asbytes[const aindex: integer]: ansistring read getasbytes + write setasbytes; + property merged[const row: integer]: boolean read getmerged write setmerged; + property selected[row: integer]: boolean read getselected write setselected; + published + property datakind: ifidatakindty read fdatakind write setdatakind + default idk_none; + property name: ansistring read fname write fname; + property onchange: ifidatacolchangeeventty read fonchange write fonchange; + end; + + ttxdatagrid = class; + tifirowstatelist = class(tcustomrowstatelist) + protected + procedure sethidden(const index: integer; const avalue: boolean); override; + procedure setfoldlevel(const index: integer; const avalue: byte); + procedure setfoldissum(const index: integer; const avalue: boolean); override; + public + property hidden[const index: integer]: boolean read gethidden write sethidden; + property foldlevel[const index: integer]: byte read getfoldlevel + write setfoldlevel; //0..63 + property foldissum[const index: integer]: boolean read getfoldissum + write setfoldissum; + end; + + tifidatacols = class(tindexpersistentarrayprop) + private + frowstate: tifirowstatelist; + fselectedrow: integer; //-1 none, -2 more than one + function getcols(const index: integer): tifidatacol; + procedure setcols(const index: integer; const avalue: tifidatacol); + function getselectedcells: gridcoordarty; + procedure setselectedcells(const avalue: gridcoordarty); + function Getselected(const cell: gridcoordty): boolean; + procedure Setselected(const cell: gridcoordty; const avalue: boolean); + procedure beginselect; + procedure endselect; + public + constructor create(const aowner: ttxdatagrid); reintroduce; + destructor destroy; override; + class function getitemclasstype: persistentclassty; override; + function colbyname(const aname: ansistring): tifidatacol; + function datalistbyname(const aname: ansistring): tdatalist; + + procedure clearselection; + function hasselection: boolean; + function selectedcellcount: integer; + function hascolselection: boolean; + property selectedcells: gridcoordarty read getselectedcells write setselectedcells; + property selected[const cell: gridcoordty]: boolean read Getselected write Setselected; + //col < 0 and row < 0 -> whole grid, col < 0 -> whole col, + //row = < 0 -> whole row + procedure setselectedrange(const rect: gridrectty; const value: boolean); overload; + procedure setselectedrange(const start,stop: gridcoordty; + const value: boolean); overload; + + procedure mergecols(const arow: integer; const astart: longword = 0; + const acount: longword = bigint); + procedure unmergecols(const arow: integer = invalidaxis); + //invalidaxis = all + + property rowstate: tifirowstatelist read frowstate; + property cols[const index: integer]: tifidatacol read getcols write setcols; + default; + end; + + ifigridoptionty = ( + igo_state, //send the whole gridstate after endupdate + igo_rowenter,igo_rowmove,igo_rowdelete, + igo_rowinsert,igo_rowstate,igo_selection,igo_coldata); + ifigridoptionsty = set of ifigridoptionty; + + tifigridcontroller = class(tificontroller) + private + fupdating: integer; + protected + foptionstx: ifigridoptionsty; + foptionsrx: ifigridoptionsty; + fdatasequence: sequencety; + fcommandlock: integer; + function encodegriddata(const asequence: sequencety): ansistring; + virtual; abstract; + function getifireckinds: ifireckindsty; override; + public + function cancommandsend(const akind: ifigridoptionty): boolean; + procedure beginupdate; + procedure endupdate; + procedure sendstate; + published + property optionstx: ifigridoptionsty read foptionstx + write foptionstx default[]; + property optionsrx: ifigridoptionsty read foptionsrx + write foptionsrx default[]; + + end; + + ttxdatagridcontroller = class(tifigridcontroller) + private + protected +// function getifireckinds: ifireckindsty; override; + procedure setowneractive(const avalue: boolean); override; + procedure processdata(const adata: pifirecty; var adatapo: pchar); + override; + function encodegriddata(const asequence: sequencety): ansistring; override; + public + constructor create(const aowner: ttxdatagrid; const aintf: iactivatorclient); + end; + + ifigriditemeventty = procedure(const sender: ttxdatagrid; + const aindex: integer) of object; + ifigridblockeventty = procedure(const sender: ttxdatagrid; + const aindex: integer; const acount: integer) of object; + ifigridblockmovedeventty = procedure(const sender: ttxdatagrid; + const fromindex,toindex,acount: integer) of object; + ifigrideventty = procedure(const sender: ttxdatagrid) of object; + + ttxdatagrid = class(tactcomponent) + private + fifi: ttxdatagridcontroller; + fdatacols: tifidatacols; + frowcount: integer; + frow: integer; + fonrowsdeleted: ifigridblockeventty; + fonrowsinserted: ifigridblockeventty; + fonrowsmoved: ifigridblockmovedeventty; + fonrowindexchanged: ifigrideventty; + fonrowstatechanged: ifigriditemeventty; + fonbeforeopen: ifigrideventty; + procedure rowstatechanged(const aindex: integer); + procedure setifi(const avalue: ttxdatagridcontroller); + procedure setdatacols(const avalue: tifidatacols); + procedure setrowcount(const avalue: integer); + function getrowhigh: integer; + procedure setrow(const avalue: integer); + function getrowcolorstate(index: integer): rowstatenumty; + procedure setrowcolorstate(index: integer; const avalue: rowstatenumty); + function getrowfontstate(index: integer): rowstatenumty; + procedure setrowfontstate(index: integer; const avalue: rowstatenumty); + function getrowreadonlystate(const index: integer): boolean; + procedure setrowreadonlystate(const index: integer; const avalue: boolean); + function getrowhidden(const index: integer): boolean; + procedure setrowhidden(const index: integer; const avalue: boolean); + function getrowfoldlevel(const index: integer): byte; + procedure setrowfoldlevel(const index: integer; const avalue: byte); + function getrowfoldissum(const index: integer): boolean; + procedure setrowfoldissum(const index: integer; const avalue: boolean); + protected + procedure setselected(const cell: gridcoordty; const avalue: boolean); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + + procedure beginupdate; + procedure endupdate; + procedure clear; + procedure moverow(const curindex,newindex: integer; const count: integer = 1); + procedure insertrow(index: integer; count: integer = 1); + procedure deleterow(index: integer; count: integer = 1); + property rowhigh: integer read getrowhigh; + property row: integer read frow write setrow; + property rowcolorstate[index: integer]: rowstatenumty read getrowcolorstate + write setrowcolorstate; //default = -1 + property rowfontstate[index: integer]: rowstatenumty read getrowfontstate + write setrowfontstate; //default = -1 + property rowreadonlystate[const index: integer]: boolean read getrowreadonlystate + write setrowreadonlystate; + property rowhidden[const index: integer]: boolean read getrowhidden + write setrowhidden; + property rowfoldlevel[const index: integer]: byte read getrowfoldlevel + write setrowfoldlevel; + property rowfoldissum[const index: integer]: boolean read getrowfoldissum + write setrowfoldissum; + published + property ifi: ttxdatagridcontroller read fifi write setifi; + property datacols: tifidatacols read fdatacols write setdatacols; + property rowcount: integer read frowcount write setrowcount default 0; + property onrowsdeleted: ifigridblockeventty read fonrowsdeleted + write fonrowsdeleted; + property onrowsinserted: ifigridblockeventty read fonrowsinserted + write fonrowsinserted; + property onrowsmoved: ifigridblockmovedeventty read fonrowsmoved + write fonrowsmoved; + property onrowindexchanged: ifigrideventty read fonrowindexchanged + write fonrowindexchanged; + property onrowstatechanged: ifigriditemeventty read fonrowstatechanged + write fonrowstatechanged; + property onbeforeopen: ifigrideventty read fonbeforeopen write fonbeforeopen; + end; + +function ifidatatodatalist(const akind: listdatatypety; const arowcount: integer; + const adata: pchar; const adatalist: tdatalist): integer; overload; + //returns datasize +function ifidatatodatalist(const akind: listdatatypety; const arowcount: integer; + const adata: pchar; const adatalist: subdatainfoty): integer; overload; + //returns datasize +function datalisttoifidata(const adatalist: tdatalist): integer; overload; +procedure datalisttoifidata(const adatalist: tdatalist; + var dest: pchar); overload; + +function encodegridcommanddata(const akind: gridcommandkindty; + const asource,adest,acount: integer): string; +function decodegridcommanddata(const adata: pchar; out akind: gridcommandkindty; + out asource,adest,acount: integer): integer; +function encodecolchangedata(const acolname: string; const arow: integer; + const alist: tdatalist): string; overload; +function encodecolchangedata(const acolname: string; const arow: integer; + const alist: tcustomrowstatelist; + const subindex: rowstatememberty): string; overload; +function encoderowstatedata(const arow: integer; + const astate: rowstatety): string; overload; +function encoderowstatedata(const arow: integer; + const astate: rowstatecolmergety): string; overload; +function encoderowstatedata(const arow: integer; + const astate: rowstaterowheightty): string; overload; +function encodeselectiondata(const acell: gridcoordty; + const avalue: boolean): string; + +implementation +uses + sysutils,msestream,msesysutils,msetmpmodules,msebits,mseobjecttext, + msestreaming{$ifndef FPC},classes_del{$endif}; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tcustomrowstatelist1 = class(tcustomrowstatelist); + + tmoduledataevent = class(tstringobjectevent) + protected + fmodulelink: trxlinkmodule; + fmoduledata: pmoduledatadataty; + public + constructor create(const adata: ansistring; const dest: ievent; + const amodulelink: trxlinkmodule; const amoduledata: pmoduledatadataty); + end; + +function encodegridcommanddata(const akind: gridcommandkindty; + const asource,adest,acount: integer): string; +begin + result:= nullstring(sizeof(gridcommanddatadataty)); + with pgridcommanddatadataty(result)^ do begin + kind:= akind; + dest:= adest; + source:= asource; + count:= acount; + end; +end; + +function decodegridcommanddata(const adata: pchar; out akind: gridcommandkindty; + out asource,adest,acount: integer): integer; +begin + result:= sizeof(gridcommanddatadataty); + with pgridcommanddatadataty(adata)^ do begin + akind:= kind; + adest:= dest; + asource:= source; + acount:= count; + end; +end; + +function encodecolchangedata(const acolname: string; const arow: integer; + const alist: tdatalist): string; +begin + result:= encodeifidata(alist,arow,sizeof(colitemheaderty)+length(acolname)); + if result <> '' then begin + with pcolitemdataty(result)^.header do begin + row:= arow; + stringtoifiname(acolname,@name); + end; + end; +end; + +function encodecolchangedata(const acolname: string; const arow: integer; + const alist: tcustomrowstatelist; + const subindex: rowstatememberty): string; +var + int1: integer; +begin + result:= ''; + int1:= sizeof(colitemheaderty)+length(acolname); + case subindex of + rsm_select: begin + result:= encodeifidata(alist.selected[arow],int1); + end; + rsm_color: begin + result:= encodeifidata(alist.color[arow],int1); + end; + rsm_font: begin + result:= encodeifidata(alist.font[arow],int1); + end; + rsm_readonly: begin + result:= encodeifidata(alist.readonly[arow],int1); + end; + rsm_foldlevel: begin + result:= encodeifidata(alist.foldlevel[arow],int1); + end; + rsm_foldissum: begin + result:= encodeifidata(alist.foldissum[arow],int1); + end; + rsm_hidden: begin + result:= encodeifidata(alist.foldissum[arow],int1); + end; + rsm_merged: begin + if alist.infolevel >= ril_colmerge then begin + result:= encodeifidata(alist.merged[arow],int1); + end; + end; + rsm_height: begin + if alist.infolevel >= ril_rowheight then begin + result:= encodeifidata(alist.height[arow],int1); + end; + end; + end; + if result <> '' then begin + with pcolitemdataty(result)^.header do begin + row:= arow; + stringtoifiname(acolname,@name); + end; + end; +end; + +function encoderowstatedata(const arow: integer; + const astate: rowstatety): string; +begin + result:= encodeifidata(astate,sizeof(rowstateheaderty)); + with prowstatedataty(result)^.header do begin + row:= arow; + end; +end; + +function encoderowstatedata(const arow: integer; + const astate: rowstatecolmergety): string; +begin + result:= encodeifidata(astate,sizeof(rowstateheaderty)); + with prowstatedataty(result)^.header do begin + row:= arow; + end; +end; + +function encoderowstatedata(const arow: integer; + const astate: rowstaterowheightty): string; +begin + result:= encodeifidata(astate,sizeof(rowstateheaderty)); + with prowstatedataty(result)^.header do begin + row:= arow; + end; +end; + +function encodeselectiondata(const acell: gridcoordty; + const avalue: boolean): string; +var + sel1: selectdataty; +begin + fillchar(sel1,sizeof(sel1),0); + sel1.col:= acell.col; + sel1.row:= acell.row; + sel1.select:= avalue; + result:= encodeifidata(sel1); +end; + +{ tmodulelinkprop } + +procedure tmodulelinkprop.inititemheader(out arec: string; + const akind: ifireckindty; const asequence: sequencety; + const datasize: integer; out datapo: pchar); +begin + mseifi.inititemheader(ftag,fname,arec,akind,asequence,datasize,datapo); +end; + +{ tlinkaction } + +destructor tlinkaction.destroy; +begin + action:= nil; + inherited; +end; + +procedure tlinkaction.setaction(const avalue: tcustomaction); +begin + setlinkedvar(avalue,tmsecomponent(faction)); +end; + +{ trxlinkaction } + +{ ttxlinkaction } + +procedure ttxlinkaction.execute; +begin + tcustommodulelink(fowner).actionfired(self,fificompintf); +end; + +procedure ttxlinkaction.objectevent(const sender: tobject; + const event: objecteventty); +begin + if (event = oe_fired) and (sender = faction) then begin + execute; + end; +end; + +procedure ttxlinkaction.setificomp(const avalue: tcomponent); +begin + if fificomp <> nil then begin + ttxlinkactions(prop).fdestroyhandler.removefreenotification(fificomp); + end; + fificomp:= avalue; + if fificomp <> nil then begin + ttxlinkactions(prop).fdestroyhandler.freenotification(fificomp); + mseclasses.getcorbainterface(fificomp,typeinfo(iifitxaction),fificompintf); + end + else begin + fificompintf:= nil; + end; +end; + +{ tmodulelinkarrayprop } + +constructor tmodulelinkarrayprop.create(const aowner: tcustommodulelink); +begin + fowner:= aowner; + inherited create(getitemclass); +end; + +procedure tmodulelinkarrayprop.createitem(const index: integer; var item: tpersistent); +begin + item:= modulelinkpropclassty(fitemclasstype).create(fowner); + tmodulelinkprop(item).fprop:= self; +end; + +function tmodulelinkarrayprop.finditem(const aname: string): tmodulelinkprop; +var + int1: integer; +begin + result:= nil; + for int1:= 0 to high(fitems) do begin + if tmodulelinkprop(fitems[int1]).fname = aname then begin + result:= tmodulelinkprop(fitems[int1]); + exit; + end; + end; +end; + +function tmodulelinkarrayprop.byname(const aname: string): tmodulelinkprop; +begin + result:= finditem(aname); + if result = nil then begin + raise exception.create(fowner.name+': array property "'+aname+'" not found.'); + end; +end; + +{ trxlinkactions } + +constructor trxlinkactions.create(const aowner: tcustommodulelink); +begin + inherited create(aowner); +end; + +class function trxlinkactions.getitemclasstype: persistentclassty; +begin + result:= trxlinkaction; +end; + +function trxlinkactions.getitems(const index: integer): trxlinkaction; +begin + result:= trxlinkaction(inherited getitems(index)); +end; + +function trxlinkactions.byname(const aname: string): trxlinkaction; +begin + result:= trxlinkaction(inherited byname(aname)); +end; + +function trxlinkactions.getitemclass: modulelinkpropclassty; +begin + result:= trxlinkaction; +end; + +{ ttxactiondestroyhandler } + +constructor ttxactiondestroyhandler.create(aowner: ttxlinkactions); +begin + fowneractions:= aowner; + inherited create(nil); +end; + +procedure ttxactiondestroyhandler.notification(acomponent: tcomponent; + operation: toperation); +var + int1: integer; +begin + inherited; + if operation = opremove then begin + with fowneractions do begin + for int1:= 0 to high(fitems) do begin + with ttxlinkaction(fitems[int1]) do begin + if acomponent = fificomp then begin + fificomp:= nil; + fificompintf:= nil; + end; + end; + end; + end; + end; +end; + +{ ttxlinkactions } + +constructor ttxlinkactions.create(const aowner: tcustommodulelink); +begin + fdestroyhandler:= ttxactiondestroyhandler.create(self); + inherited create(aowner); +end; + +destructor ttxlinkactions.destroy; +begin + inherited; + fdestroyhandler.destroy; +end; + +class function ttxlinkactions.getitemclasstype: persistentclassty; +begin + result:= ttxlinkaction; +end; + +function ttxlinkactions.getitems(const index: integer): ttxlinkaction; +begin + result:= ttxlinkaction(inherited getitems(index)); +end; + +function ttxlinkactions.byname(const aname: string): ttxlinkaction; +begin + result:= ttxlinkaction(inherited byname(aname)); +end; + +function ttxlinkactions.getitemclass: modulelinkpropclassty; +begin + result:= ttxlinkaction; +end; + +{ ttxlinkmodules } + +constructor ttxlinkmodules.create(const aowner: tcustommodulelink); +begin + inherited create(aowner); +end; + +class function ttxlinkmodules.getitemclasstype: persistentclassty; +begin + result:= ttxlinkmodule; +end; + +function ttxlinkmodules.getitems(const index: integer): ttxlinkmodule; +begin + result:= ttxlinkmodule(inherited getitems(index)); +end; + +function ttxlinkmodules.byname(const aname: string): ttxlinkmodule; +begin + result:= ttxlinkmodule(inherited byname(aname)); +end; + +function ttxlinkmodules.getitemclass: modulelinkpropclassty; +begin + result:= ttxlinkmodule; +end; + +{ trxlinkmodule } + +procedure trxlinkmodule.requestmodule; +var + str1: string; + po1: pchar; +begin + inititemheader(str1,ik_requestmodule,0,0,po1); + fsequence:= tcustommodulelink(fowner).senddata(str1); +end; + +procedure trxlinkmodule.objevent(const sender: iobjectlink; + const event: objecteventty); +var + conn1: tcustomiochannel; +begin + if (event = oe_destroyed) and (rlo_closeconnonfree in foptions) and + (sender.getinstance = fmodule) then begin + conn1:= tcustommodulelink(fowner).channel; + if conn1 <> nil then begin + conn1.active:= false; + end; + end; + inherited; +end; + +procedure trxlinkmodule.objectevent(const sender: tobject; + const event: objecteventty); +begin + if (event = oe_fired) and (sender = faction) then begin + requestmodule; + end; +end; + +procedure trxlinkmodule.domodulereceived; +begin + if tcustommodulelink(fowner).canevent(tmethod(fonmodulereceived)) then begin + fonmodulereceived(self); + end; +end; + +{ trxlinkmodules } + +constructor trxlinkmodules.create(const aowner: tcustommodulelink); +begin + inherited create(aowner); +end; + +class function trxlinkmodules.getitemclasstype: persistentclassty; +begin + result:= trxlinkmodule; +end; + +function trxlinkmodules.getitems(const index: integer): trxlinkmodule; +begin + result:= trxlinkmodule(inherited getitems(index)); +end; + +function trxlinkmodules.byname(const aname: string): trxlinkmodule; +begin + result:= trxlinkmodule(inherited byname(aname)); +end; + +function trxlinkmodules.finditem(const asequence: sequencety): trxlinkmodule; +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + if trxlinkmodule(fitems[int1]).fsequence = asequence then begin + result:= trxlinkmodule(fitems[int1]); + exit; + end; + end; + result:= nil; +end; + +function trxlinkmodules.getitemclass: modulelinkpropclassty; +begin + result:= trxlinkmodule; +end; + +{ tvaluelink } + +procedure tvaluelink.sendvalue(const aname: string; const avalue: int64); +var + str1: string; + po1: pchar; +begin + initpropertyrecord(str1,aname,idk_int64,0,po1); + pint64(po1)^:= avalue; + tcustommodulelink(fowner).senddata(str1); +end; + +procedure tvaluelink.sendvalue(const aname: string; const avalue: double); +var + str1: string; + po1: pchar; +begin + initpropertyrecord(str1,aname,idk_real,0,po1); + pdouble(po1)^:= avalue; + tcustommodulelink(fowner).senddata(str1); +end; + +procedure tvaluelink.sendvalue(const aname: string; const avalue: msestring); +var + str1,str2: string; + po1: pchar; +begin + str2:= stringtoutf8ansi(avalue); + initpropertyrecord(str1,aname,idk_msestring,length(str2),po1); + stringtoifiname(str2,pifinamety(po1)); + tcustommodulelink(fowner).senddata(str1); +end; + +procedure tvaluelink.sendvalue(const aname: string; const avalue: ansistring); +begin + sendvalue(aname,msestring(avalue)); +end; +{ +procedure tvaluelink.sendvalue(const aname: string; const avalue: ansistring); +var + str1: string; + po1: pchar; +begin + initpropertyrecord(str1,aname,idk_ansistring,length(avalue),po1); + stringtoifiname(avalue,pifinamety(po1)); + tcustommodulelink(fowner).senddata(str1); +end; +} +procedure tvaluelink.initpropertyrecord(out arec: string; + const apropertyname: string; const akind: ifidatakindty; + const datasize: integer; out datapo: pchar); +var + po1: pchar; +begin + inititemheader(arec,ik_propertychanged,0,datarecsizes[akind]+ + length(apropertyname)+datasize,po1); + + inc(po1,stringtoifiname(apropertyname,pifinamety(po1))); + pifidataty(po1)^.header.kind:= akind; + datapo:= po1 + sizeof(ifidataheaderty); +end; + +procedure tvaluelink.sendcommand(const acommand: ifiwidgetcommandty); +var + str1: string; + po1: pchar; +begin + inititemheader(str1,ik_widgetcommand,0,0,po1); + pifiwidgetcommandty(po1)^:= acommand; + tcustommodulelink(fowner).senddata(str1); +end; + +procedure tvaluelink.setdata(const adata: pifidataty; const aname: ansistring); +var + str1: string; +begin + with adata^ do begin + fdatakind:= header.kind; + case fdatakind of + idk_int64: begin + fint64value:= pint64(@data)^; + end; + idk_real: begin + fdoublevalue:= pdouble(@data)^; + end; + idk_msestring: begin + ifinametostring(pifinamety(@data),str1); + fmsestringvalue:= utf8tostringansi(str1); + end; + end; + end; +end; + +procedure tvaluelink.checkdatakind(const akind: ifidatakindty); +begin + if fdatakind <> akind then begin + raise exception.create('Invalid datakind'); + end; +end; + +function tvaluelink.getasinteger: integer; +begin + checkdatakind(idk_int64); + result:= fint64value; +end; + +procedure tvaluelink.setasinteger(const avalue: integer); +begin + setaslargeint(avalue); +end; + +function tvaluelink.getaslargeint: int64; +begin + checkdatakind(idk_int64); + result:= fint64value; +end; + +procedure tvaluelink.setaslargeint(const avalue: int64); +begin + fdatakind:= idk_int64; + fint64value:= avalue; + sendvalue('value',fint64value); +end; + +function tvaluelink.getasfloat: double; +begin + checkdatakind(idk_real); + result:= fdoublevalue; +end; + +procedure tvaluelink.setasfloat(const avalue: double); +begin + fdatakind:= idk_real; + fdoublevalue:= avalue; + sendvalue('value',fdoublevalue); +end; + +function tvaluelink.getasmsestring: msestring; +begin + checkdatakind(idk_msestring); + result:= fmsestringvalue; +{ + if fdatakind = idk_ansistring then begin + result:= fansistringvalue; + end + else begin + checkdatakind(idk_msestring); + result:= fmsestringvalue; + end; + } +end; + +procedure tvaluelink.setasmsestring(const avalue: msestring); +begin + fdatakind:= idk_msestring; + fmsestringvalue:= avalue; + sendvalue('value',fmsestringvalue); +end; + +function tvaluelink.getasansistring: ansistring; +begin + result:= ansistring(getasmsestring); +end; + +procedure tvaluelink.setasansistring(const avalue: ansistring); +begin + setasmsestring(msestring(avalue)); +end; + +procedure tvaluelink.setenabled(const avalue: boolean); +begin + if avalue then begin + sendcommand(iwc_enable); + end + else begin + sendcommand(iwc_disable); + end; +end; + +procedure tvaluelink.setvisible(const avalue: boolean); +begin + if avalue then begin + sendcommand(iwc_show); + end + else begin + sendcommand(iwc_hide); + end; +end; + +procedure tvaluelink.sendproperty(const aname: string; const avalue: boolean); +var + int1: integer; +begin + int1:= 0; + if avalue then begin + int1:= -1; + end; + sendvalue(aname,int1); +end; + +procedure tvaluelink.sendproperty(const aname: string; const avalue: integer); +begin + sendvalue(aname,avalue); +end; + +procedure tvaluelink.sendproperty(const aname: string; const avalue: colorty); +begin + sendvalue(aname,avalue); +end; + +procedure tvaluelink.sendproperty(const aname: string; const avalue: int64); +begin + sendvalue(aname,avalue); +end; + +procedure tvaluelink.sendproperty(const aname: string; const avalue: string); +begin + sendvalue(aname,avalue); +end; + +procedure tvaluelink.sendproperty(const aname: string; const avalue: msestring); +begin + sendvalue(aname,avalue); +end; + +procedure tvaluelink.sendproperty(const aname: string; const avalue: realty); +begin + sendvalue(aname,avalue); +end; + +procedure tvaluelink.sendproperty(const aname: string; const avalue: currency); +begin + sendvalue(aname,avalue); +end; + +{ tvaluelinks } + +class function tvaluelinks.getitemclasstype: persistentclassty; +begin + result:= tvaluelink; +end; + +function tvaluelinks.getitems(const index: integer): tvaluelink; +begin + result:= tvaluelink(inherited getitems(index)); +end; + +function tvaluelinks.byname(const aname: string): tvaluelink; +begin + result:= tvaluelink(inherited byname(aname)); +end; + +function tvaluelinks.getitemclass: modulelinkpropclassty; +begin + result:= tvaluelink; +end; + +{ tcustomvaluecomponentlink } + +procedure tcustomvaluecomponentlink.setcomponent(const avalue: tmsecomponent); +begin + setlinkedvar(avalue,fcomponent); + if avalue <> nil then begin + fvalueproperty:= getpropinfo(avalue,'value'); + end; +end; + +procedure tcustomvaluecomponentlink.checkcomponent; +begin + if fcomponent = nil then begin + exception.create(tcustommodulelink(fowner).name+': No component.'); + end; +end; + +function getnestedpropinfo(var ainstance: tobject; + apropname: pchar; out aindex: integer; + out arraypropkind: arraypropkindty): ppropinfo; +var + po1,po2: pchar; + prop1: ppropinfo; + index1: integer; +begin + result:= nil; + po2:= nil; + po1:= apropname; + index1:= -1; + arraypropkind:= apk_none; + while po1^ <> #0 do begin + if po1^ = '.' then begin + break; + end; + if po1^ = '[' then begin + po2:= po1+1; + while (po2^ <> ']') and (po2^ <> #0) do begin + inc(po2); + end; + if po2^ <> #0 then begin + if not trystrtoint(psubstr(po1+1,po2),index1) then begin + index1:= -1; + end; + inc(po2); + end; + break; + end; + inc(po1); + end; + if po1 <> apropname then begin + result:= getpropinfo(ainstance,psubstr(apropname,po1)); + if result <> nil then begin + if result^.proptype^.kind = tkclass then begin + ptruint(ainstance):= ptruint(getordprop(ainstance,result)); + prop1:= result; + result:= nil; + if ainstance <> nil then begin + if index1 >= 0 then begin + if ainstance is tarrayprop then begin + with tarrayprop(ainstance) do begin + if index1 < count then begin + arraypropkind:= propkind; + if arraypropkind = apk_tpersistent then begin + ainstance:= tpersistentarrayprop(ainstance)[index1]; + if po2^ = '.' then begin + result:= getnestedpropinfo(ainstance,po2+1,index1,arraypropkind); + end; + end + else begin + result:= prop1; + end; + end; + end; + end + end + else begin + if (po1^ = '.') then begin + result:= getnestedpropinfo(ainstance,po1+1,index1,arraypropkind); + end + else begin + result:= nil; + end; + end; + end; + end; + end; + end; + aindex:= index1; +end; + +procedure tcustomvaluecomponentlink.setdata(const adata: pifidataty; + const aname: ansistring); +var + aproperty: ppropinfo; + instance: tobject; + index1: integer; + arraypropkind: arraypropkindty; +begin + inherited; + aproperty:= nil; + instance:= fcomponent; + with adata^ do begin + if aname = 'value' then begin + aproperty:= fvalueproperty; + index1:= -1; + end + else begin + if fcomponent <> nil then begin + aproperty:= getnestedpropinfo(instance,pchar(aname),index1,arraypropkind); + end; + end; + if (aproperty <> nil) and (instance <> nil) then begin + inc(fupdatelock); + try + if index1 >= 0 then begin + case arraypropkind of + apk_integer,apk_colorty: begin + tintegerarrayprop(instance)[index1]:= asinteger; + end; + apk_real: begin + trealarrayprop(instance)[index1]:= asfloat; + end; + apk_string: begin + tstringarrayprop(instance)[index1]:= asstring; + end; + apk_msestring: begin + tmsestringarrayprop(instance)[index1]:= asmsestring; + end; + apk_boolean: begin + tbooleanarrayprop(instance)[index1]:= asinteger <> 0;; + end; + end; + end + else begin + case aproperty^.proptype^.kind of + tkInteger,{$ifdef FPC}tkBool,{$endif}tkInt64,tkset: begin + setordprop(instance,aproperty,aslargeint); + end; + tkFloat: begin + setfloatprop(instance,aproperty,asfloat); + end; + tkWString: begin + setwidestrprop(instance,aproperty,asmsestring); + end; + {$if defined(FPC) and (FPC_FULLVERSION >= 20300)} +// {$ifdef mse_unicodestring} + tkUString: begin + setunicodestrprop(instance,aproperty,asmsestring); + end; + {$ifend} + {$ifdef FPC} + tkSString,tkLString,tkAString: begin + {$else} + tkString,tkLString: begin + {$endif} + setstrprop(instance,aproperty,asstring); + end; + end; + end; + finally + dec(fupdatelock); + end; + end; + end; +end; + +procedure tcustomvaluecomponentlink.sendvalue(const aproperty: ppropinfo); +begin + if aproperty <> nil then begin + case aproperty^.proptype^.kind of + tkInteger,{$ifdef FPC}tkBool,{$endif}tkInt64: begin + sendvalue(aproperty^.name,getordprop(fcomponent,aproperty)); + end; + tkFloat: begin + {$ifdef FPC} + sendvalue(aproperty^.name,double(getfloatprop(fcomponent,aproperty))); + {$else} + sendvalue(aproperty^.name,getfloatprop(fcomponent,aproperty)); + {$endif} + end; + {$if defined(FPC) and (FPC_FULLVERSION >= 20300)} +// {$ifdef mse_unicodestring} + tkUString: begin + sendvalue(aproperty^.name,getunicodestrprop(fcomponent,aproperty)); + end; + {$ifend} + tkWString: begin + sendvalue(aproperty^.name,getwidestrprop(fcomponent,aproperty)); + end; + {$ifdef FPC} + tkSString,tkLString,tkAString: begin + {$else} + tkString,tkLString: begin + {$endif} + sendvalue(aproperty^.name,getstrprop(fcomponent,aproperty)); + end; + end; + end; +end; + +procedure tcustomvaluecomponentlink.sendstate(const astate: ifiwidgetstatesty); +begin + sendvalue(ifiwidgetstatename,{$ifdef FPC}integer{$else}byte{$endif}(astate)); +end; + +procedure tcustomvaluecomponentlink.sendmodalresult(const amodalresult: modalresultty); +begin + sendvalue(ifiwidgetmodalresultname,integer(amodalresult)); +end; + +procedure tcustomvaluecomponentlink.sendproperties; +var + stream1: tmemorystream; + str1: string; + po1: pchar; +begin + checkcomponent; + stream1:= tmemorystream.create; + try + writecomponentmse(stream1,fcomponent); + inititemheader(str1,ik_widgetproperties,0,stream1.size,po1); + setifibytes(stream1.memory,stream1.size,pifibytesty(po1)); + finally + stream1.free; + end; + tcustommodulelink(fowner).senddata(str1); +end; + +procedure tcustomvaluecomponentlink.sendvalue(const aname: string; + const avalue: colorty); +begin + sendvalue(aname,int64(avalue)); +end; + +{ tvaluecomponentlinks } + +class function tvaluecomponentlinks.getitemclasstype: persistentclassty; +begin + result:= tvaluecomponentlink; +end; + +function tvaluecomponentlinks.getitems(const index: integer): tvaluecomponentlink; +begin + result:= tvaluecomponentlink(inherited getitems(index)); +end; + +function tvaluecomponentlinks.byname(const aname: string): tvaluecomponentlink; +begin + result:= tvaluecomponentlink(inherited byname(aname)); +end; + +function tvaluecomponentlinks.getitemclass: modulelinkpropclassty; +begin + result:= tvaluecomponentlink; +end; + +{ tcustommodulelink } + +constructor tcustommodulelink.create(aowner: tcomponent); +begin + foptions:= defaultformlinkoptions; + factionsrx:= trxlinkactions.create(self); + factionstx:= ttxlinkactions.create(self); + fmodulestx:= ttxlinkmodules.create(self); + fmodulesrx:= trxlinkmodules.create(self); + fvaluecomponents:= tvaluecomponentlinks.create(self); + if fvalues = nil then begin + fvalues:= tvaluelinks.create(self); + end; + inherited; +end; + +destructor tcustommodulelink.destroy; +begin + factionsrx.free; + factionstx.free; + fmodulesrx.free; + fmodulestx.free; + fvaluecomponents.free; + fvalues.free; + inherited; +end; + +procedure tcustommodulelink.setactionsrx(const avalue: trxlinkactions); +begin + factionsrx.assign(avalue); +end; + +procedure tcustommodulelink.setactionstx(const avalue: ttxlinkactions); +begin + factionstx.assign(avalue); +end; + +procedure tcustommodulelink.updatecomponent(const anamepath: ansistring; + const aobjecttext: ansistring); +var + comp1: tcomponent; + stream1: tstringcopystream; + stream2: tmemorystream; +begin + comp1:= findcomponentbynamepath(anamepath); + if comp1 = nil then begin + raise exception.create('Component "'+anamepath+'" not found.'); + end; + stream1:= tstringcopystream.create(aobjecttext); + stream2:= tmemorystream.create; + try + objecttexttobinarymse(stream1,stream2); + stream2.position:= 0; + stream2.readcomponent(comp1); + finally + stream1.free; + stream2.free; + end; +end; + +function tcustommodulelink.encodemodulecommand(const acommand: ificommandcodety; + const atag: integer; const aname: string): string; +var + po1: pchar; +begin + initifirec(result,ik_modulecommand,0,length(aname),po1); + with pmodulecommandty(po1)^ do begin + with header do begin + tag:= atag; + po1:= @name; + inc(po1,stringtoifiname(aname,@name)); + end; + end; + with pmodulecommanddataty(po1)^ do begin + command:= acommand; + end; +end; + +procedure tcustommodulelink.closemodule(const atag: integer; const aname: string); +begin + if fchannel <> nil then begin + fchannel.senddata(encodemodulecommand(icc_close,atag,aname)); + end; +end; + +procedure tcustommodulelink.actionfired(const sender: tlinkaction; + const acompintf: iifitxaction); +var + str1: string; + po1: pchar; +begin + if fchannel <> nil then begin + str1:= encodeactionfired(sender.tag,sender.name,po1); + if acompintf <> nil then begin + acompintf.txactionfired(str1,po1); + end; + fchannel.senddata(str1); + end; +end; + +function tcustommodulelink.encodeactionfired(const atag: integer; + const aname: string; out adatapo: pchar): string; +var + po1: pchar; +begin + initifirec(result,ik_actionfired,0,length(aname),po1); + with pifirecty(result)^.actionfired.header do begin + tag:= atag; + adatapo:= @name; + inc(adatapo,stringtoifiname(aname,pifinamety(adatapo))); + end; +end; + +procedure tcustommodulelink.objectevent(const sender: tobject; + const event: objecteventty); +var + po1: pifirecty; +// str1: string; +begin + if (event = oe_dataready) and (sender = fchannel) then begin + if (length(fchannel.rxdata) >= sizeof(ifiheaderty)) then begin + with fchannel do begin + po1:= pifirecty(rxdata); + with po1^.header do begin + if size = length(rxdata) then begin + if (kind in ifiasynckinds) and not (irs_async in state) then begin + include(state,irs_async); + asyncrx; + end + else begin + if processdata(po1) then begin + rxdata:= ''; + end; + end; + end; + end; + end; + end; + end; +end; + +function tcustommodulelink.processdataitem(const adata: pifirecty; + var adatapo: pchar; const atag: integer; const aname: string): boolean; +var + str2: string; +begin + result:= false; + with adata^ do begin + case header.kind of + ik_actionfired: begin + result:= actionreceived(adata,adatapo,atag,aname); + end; + ik_propertychanged: begin + with propertychanged.header do begin + inc(adatapo,ifinametostring(pifinamety(adatapo),str2)); + result:= propertychangereceived(atag,aname,str2,pifidataty(adatapo)); + end; + end; + ik_requestmodule: begin + result:= requestmodulereceived(atag,aname,adata^.header.sequence); + end; + ik_moduledata: begin + result:= moduledatareceived(atag,aname,header.answersequence, + pmoduledatadataty(adatapo)); + end; + ik_modulecommand: begin + result:= modulecommandreceived(atag,aname,pmodulecommanddataty(adatapo)); + end; + end; + end; +end; + +function tcustommodulelink.processdata(const adata: pifirecty): boolean; + //todo: optimize link name check +var + tag1: integer; + str1: string; + po1: pchar; + ar1: stringarty; +begin + result:= false; + with adata^ do begin + if header.kind in ifiitemkinds then begin + with itemheader do begin + tag1:= tag; + po1:= @name; + end; + inc(po1,ifinametostring(pifinamety(po1),str1)); + ar1:= splitstring(str1,'.'); + if high(ar1) = 1 then begin + if ar1[0] <> flinkname then begin + exit; + end; + str1:= ar1[1]; + end; + result:= processdataitem(adata,po1,tag1,str1); + if result and (header.answersequence <> 0) then begin + channel.synchronizer.answerreceived(header.answersequence); + end; + end; + end; +end; + +procedure tcustommodulelink.receiveevent(const event: tobjectevent); +var +// comp1: tmsecomponent; + stream1: tmemorycopystream; + po1: pchar; + str1: string; +begin + if event.kind = ek_objectdata then begin + if event is tmoduledataevent then begin + with tmoduledataevent(event) do begin + po1:= @fmoduledata^.parentclass; + inc(po1,ifinametostring(pifinamety(po1),str1)); + with fmodulelink do begin + freeandnil(fmodule); + with pifibytesty(po1)^ do begin + stream1:= tmemorycopystream.create(@data,length); + try + fmodule:= createtmpmodule(str1,stream1,{$ifdef FPC}@{$endif}moduleloaded); + fmodule.getcorbainterface(typeinfo(iificommand),fcommandintf); + finally + stream1.free; + end; + end; + setlinkedvar(fmodule,fmodule); + domodulereceived; + end; + end; + end; + end + else begin + inherited; + end; +end; + +function tcustommodulelink.actionreceived(const adata: pifirecty; + var adatapo: pchar; const atag: integer; const aname: string): boolean; +var + act1: trxlinkaction; +// int1: integer; + var1: variant; +begin + result:= false; + with factionsrx do begin + act1:= trxlinkaction(finditem(aname)); + if act1 <> nil then begin + result:= true; + if adatapo^ <> #0 then begin + var1:= readifivariant(adata,adatapo); + end + else begin //end of string + var1:= null; + end; + if assigned(act1.fonexecute) then begin + act1.fonexecute(act1,atag,var1); + end; + if assigned(fonexecute) then begin + fonexecute(act1,atag,var1); + end; + with act1 do begin + if (faction <> nil) and faction.enabled then begin + faction.execute; + end; + end; + end; + end; +end; + +function tcustommodulelink.requestmodulereceived(const atag: integer; + const aname: string; const asequence: sequencety): boolean; +var + mo1: ttxlinkmodule; + po1: pobjectdataty; + str1,str2: string; + po2,po3: pchar; +begin + {$ifdef mse_debugifi} + debugout(self,'requestmodule '+aname); + {$endif} + mo1:= ttxlinkmodule(fmodulestx.finditem(aname)); + result:= mo1 <> nil; + if result and (mo1.fmoduleclassname <> '') then begin + po1:= findmoduledata(mo1.fmoduleclassname,str2); + if mo1.moduleparentclassname <> '' then begin + str2:= mo1.moduleparentclassname; + end; + if po1 <> nil then begin + mo1.inititemheader(str1,ik_moduledata,asequence,length(str2)+po1^.size,po2); + with pmoduledatadataty(po2)^ do begin + po3:= @parentclass; + inc(po3,stringtoifiname(str2,pifinamety(po3))); + setifibytes(@po1^.data,po1^.size,pifibytesty(po3)); + end; + senddata(str1); + end + else begin + raise exception.create('Module resouces for "'+aname+'" class "'+ + mo1.fmoduleclassname+'" not found.'); + end; + end; +end; + +procedure tcustommodulelink.connectmodule(const sender: tcustommodulelink); +begin + if flo_useclientchannel in options then begin + channel:= sender.channel; + end; +end; + +procedure tcustommodulelink.moduleloaded(const sender: tmsecomponent); +var + int1: integer; + intf1: iifimodulelink; +begin + with sender do begin + for int1:= 0 to componentcount - 1 do begin + if mseclasses.getcorbainterface(components[int1],typeinfo(iifimodulelink), + intf1) then begin + intf1.connectmodule(self); + end; + end; + end; +end; + +function tcustommodulelink.modulecommandreceived(const atag: integer; + const aname: string; const adata: pmodulecommanddataty): boolean; +var + mo1: trxlinkmodule; +begin + mo1:= trxlinkmodule(fmodulesrx.finditem(aname)); + result:= mo1 <> nil; + if result then begin + with mo1 do begin + if fmodule <> nil then begin + if fcommandintf <> nil then begin + fcommandintf.executeificommand(adata^.command); + end; + end; + end; + end; +end; + +function tcustommodulelink.moduledatareceived(const atag: integer; + const aname: string; const asequence: sequencety; + const adata: pmoduledatadataty): boolean; +var + mo1: trxlinkmodule; + comp1: tmsecomponent; + stream1: tmemorycopystream; + po1: pchar; + str1: string; +begin + if csdesigning in componentstate then begin + result:= false; + exit; + end; + if asequence <> 0 then begin + mo1:= fmodulesrx.finditem(asequence); + end + else begin + mo1:= trxlinkmodule(fmodulesrx.finditem(aname)); + end; + result:= mo1 <> nil; + if result then begin + with mo1 do begin + po1:= adata^.parentclass; + inc(po1,ifinametostring(pifinamety(po1),str1)); + freeandnil(fmodule); + with pifibytesty(po1)^ do begin + stream1:= tmemorycopystream.create(@data,length); + try + comp1:= createtmpmodule(str1,stream1,{$ifdef FPC}@{$endif}moduleloaded); + comp1.getcorbainterface(typeinfo(iificommand),fcommandintf); + finally + stream1.free; + end; + end; + setlinkedvar(comp1,fmodule); + end; + end; +end; + +function tcustommodulelink.propertychangereceived(const atag: integer; + const aname: string; const apropertyname: string; + const adata: pifidataty): boolean; + + procedure check(const alinks: tvaluelinks); + var + wi1: tvaluelink; + begin + wi1:= tvaluelink(alinks.finditem(aname)); + result:= wi1 <> nil; + if result then begin + with wi1 do begin + setdata(adata,apropertyname); + if apropertyname = ifiwidgetstatename then begin + if assigned(fonwidgetstatechanged) then begin + fonwidgetstatechanged(wi1,atag,ifiwidgetstatesty( + {$ifndef FPC}byte({$endif}asinteger{$ifndef FPC}){$endif})); + end; + end + else begin + if apropertyname = ifiwidgetmodalresultname then begin + if assigned(fonmodalresult) then begin + fonmodalresult(wi1,atag,modalresultty(asinteger)); + end; + end + else begin + if assigned(fonpropertychanged) then begin + fonpropertychanged(wi1,atag,apropertyname); + end; + end; + end; + end; + end; + end; //check + +begin + result:= false; + check(fvalues); + if not result then begin + check(fvaluecomponents); + end; +end; + +procedure tcustommodulelink.execute(const sender: iificlient); +begin + //dummy +end; + +procedure tcustommodulelink.valuechanged(const sender: iificlient); +begin + //dummy +end; + +procedure tcustommodulelink.dataentered(const sender: iificlient; + const arow: integer); +begin + //dummy +end; + +procedure tcustommodulelink.updateoptionsedit(var avalue: optionseditty); +begin + //dummy +end; + +procedure tcustommodulelink.closequery(const sender: iificlient; + var amodalresult: modalresultty); +begin + //dummy +end; + +procedure tcustommodulelink.statechanged(const sender: iificlient; + const astate: ifiwidgetstatesty); +begin + //dummy +end; + +procedure tcustommodulelink.setvalue(const sender: iificlient; var avalue; + var accept: boolean; const arow: integer); +begin + //dummy +end; + +procedure tcustommodulelink.sendmodalresult(const sender: iificlient; + const amodalresult: modalresultty); +begin + //dummy +end; + +function tcustommodulelink.hasconnection: boolean; +begin + result:= (fchannel <> nil) and fchannel.checkconnection; +end; + +function tcustommodulelink.senddata(const adata: ansistring): sequencety; +begin + if fchannel = nil then begin + raise exception.create(name+': No IO channel assigned.'); + end; + result:= fchannel.sequence; + with pifirecty(adata)^.header do begin + sequence:= result; + end; + fchannel.senddata(adata); +end; + +procedure tcustommodulelink.setmodulestx(const avalue: ttxlinkmodules); +begin + fmodulestx.assign(avalue); +end; + +procedure tcustommodulelink.setmodulesrx(const avalue: trxlinkmodules); +begin + fmodulesrx.assign(avalue); +end; + +procedure tcustommodulelink.setvalues(const avalue: tvaluelinks); +begin + fvalues.assign(avalue); +end; + +procedure tcustommodulelink.setvaluecomponents(const avalue: tvaluecomponentlinks); +begin + fvaluecomponents.assign(avalue); +end; + +{ ttxlinkmodule } + +procedure ttxlinkmodule.sendmodule; +begin + tcustommodulelink(fowner).requestmodulereceived(tag,name,0); +end; + +procedure ttxlinkmodule.close; +begin + tcustommodulelink(fowner).closemodule(tag,name); +end; + +{ tmoduledataevent } + +constructor tmoduledataevent.create(const adata: ansistring; const dest: ievent; + const amodulelink: trxlinkmodule; + const amoduledata: pmoduledatadataty); +begin + fmodulelink:= amodulelink; + fmoduledata:= amoduledata; + inherited create(adata,dest); +end; + +{ tificontroller } + +constructor tificontroller.create(const aowner: tcomponent; + const aintf: iactivatorclient); +begin + foptions:= defaultifirxoptions; + fdefaulttimeout:= defaultifirxtimeout; + inherited create(aowner,aintf); +end; + +procedure tificontroller.connectmodule(const sender: tcustommodulelink); +begin + if irxo_useclientchannel in options then begin + channel:= sender.channel; + end; +end; + +procedure tificontroller.inititemheader(out arec: string; + const akind: ifireckindty; const asequence: sequencety; + const datasize: integer; out datapo: pchar); +begin + mseifi.inititemheader(tag,flinkname,arec,akind,asequence,datasize,datapo); +end; + +procedure tificontroller.setchannel(const avalue: tcustomiochannel); +begin + setlinkedvar(avalue,tmsecomponent(fchannel)); +end; + +function tificontroller.senddata(const adata: ansistring; + const asequence: sequencety = 0): sequencety; +begin + if fchannel = nil then begin + raise exception.create(fowner.name+': No IO channel assigned.'); + end; + result:= asequence; + if result = 0 then begin + result:= fchannel.sequence; + end; + with pifirecty(adata)^.header do begin + sequence:= result; + end; + fchannel.senddata(adata); +end; + +function tificontroller.senddataandwait(const adata: ansistring; + out asequence: sequencety; atimeoutus: integer = 0): boolean; +var + client1: twaitingclient; +begin + if fchannel = nil then begin + raise exception.create(fowner.name+': No IO channel assigned.'); + end; + asequence:= fchannel.sequence; + client1:= fchannel.synchronizer.preparewait(asequence); + senddata(adata,asequence); + if atimeoutus = 0 then begin + atimeoutus:= timeoutus; + end; + result:= fchannel.synchronizer.waitforanswer(client1,atimeoutus); + if not result then begin + asequence:= 0; //!!! race condition? + end; +end; + +function tificontroller.senditem(const kind: ifireckindty; + const data: array of ansistring): sequencety; + //returns sequence number +var + str1: ansistring; + po1: pchar; + int1,int2: integer; +begin + int2:= 0; + for int1:= 0 to high(data) do begin + inc(int2,length(data[int1])); + end; + inititemheader(str1,ik_itemheader,0,int2,po1); + pifirecty(str1)^.header.kind:= kind; + for int1:= 0 to high(data) do begin + int2:= length(data[int1]); + move(pointer(data[int1])^,po1^,int2); + inc(po1,int2); + end; + result:= senddata(str1); +end; + +procedure tificontroller.objectevent(const sender: tobject; + const event: objecteventty); +var + po1: pifirecty; +// tag1: integer; + str1: string; + po2: pchar; +// int1: integer; +// mstr1: msestring; +begin + if (event = oe_dataready) and (sender = fchannel) then begin + if (length(fchannel.rxdata) >= sizeof(ifiheaderty)) then begin + with fchannel do begin + po1:= pifirecty(rxdata); + with po1^,header do begin + if (size = length(rxdata)) and (kind in getifireckinds) then begin + with itemheader do begin +// tag1:= tag; + po2:= @name; + end; + inc(po2,ifinametostring(pifinamety(po2),str1)); + if str1 = flinkname then begin + processdata(po1,po2); + if answersequence <> 0 then begin + channel.synchronizer.answerreceived(answersequence); + end; +// rxdata:= ''; + end; + end; + end; + end; + end; + end + else begin + inherited; + end; +end; + +function tificontroller.getifireckinds: ifireckindsty; +begin + result:= []; +end; + +function tificontroller.cansend: boolean; +begin + result:= (channel <> nil) or + not ((csdesigning in fowner.componentstate) and + (irxo_useclientchannel in foptions)); +end; + +{ tifidatacol } + +constructor tifidatacol.create(const aowner: tobject; + const aprop: tindexpersistentarrayprop); +begin + fselectedrow:= -1; + inherited; +end; + +destructor tifidatacol.destroy; +begin + freedatalist; + inherited; +end; + +procedure tifidatacol.freedatalist; +begin + fdata.free; +end; + +procedure tifidatacol.setdatakind(const avalue: ifidatakindty); +begin + if fdatakind <> avalue then begin + freedatalist; + fdatakind:= avalue; + end; +end; + +procedure tifidatacol.checkdatalist; +begin + if fdata = nil then begin + case datakind of + idk_integer: begin + fdata:= tintegerdatalist.create; + end; + { + idk_int64: begin + fdatalist:= tint64datalist.create; + end; + idk_currency: begin + fdatalist:= tcurrencydatalist.create; + end; + } + idk_real: begin + fdata:= trealdatalist.create; + end; + idk_msestring: begin + fdata:= tmsestringdatalist.create; + end; + idk_msestringint: begin + fdata:= tmsestringintdatalist.create; + end; + idk_bytes: begin + fdata:= tansistringdatalist.create; + end; + idk_realint: begin + fdata:= trealintdatalist.create; + end; + else begin + raise exception.create('Invalid ifidatakind.'); + end; + end; + end; + fdata.count:= ttxdatagrid(fowner).rowcount; + fdata.onitemchange:= {$ifdef FPC}@{$endif}dochange; +end; + +procedure tifidatacol.checkdatalist(const akind: ifidatakindty); +begin + if akind <> datakind then begin + raise exception.create('Wrong datakind.'); + end; + if fdata = nil then begin + checkdatalist; + end; +end; + +procedure tifidatacol.dochange(const sender: tdatalist; const aindex: integer); +begin + if ttxdatagrid(fowner).canevent(tmethod(fonchange)) then begin + fonchange(self,aindex); + end; +end; + +function tifidatacol.getdatalist: tdatalist; +begin + checkdatalist; + result:= fdata; +end; + +procedure tifidatacol.datachange(const aindex: integer); +begin + with ttxdatagrid(fowner).fifi do begin + if (self.name <> '') and cancommandsend(igo_coldata) and + (fdata <> nil) then begin + senditem(ik_coldatachange,[encodecolchangedata(self.name,aindex,fdata)]); + end; + end; +end; + +function tifidatacol.getasinteger(const aindex: integer): integer; +begin + checkdatalist(idk_integer); + result:= tintegerdatalist(fdata).items[aindex]; +end; + +procedure tifidatacol.setasinteger(const aindex: integer; const avalue: integer); +begin + checkdatalist(idk_integer); + tintegerdatalist(fdata).items[aindex]:= avalue; + datachange(aindex); +end; + +function tifidatacol.getasint64(const aindex: integer): int64; +begin + checkdatalist(idk_int64); + result:= tint64datalist(fdata).items[aindex]; +end; + +procedure tifidatacol.setasint64(const aindex: integer; const avalue: int64); +begin + checkdatalist(idk_int64); + tint64datalist(fdata).items[aindex]:= avalue; + datachange(aindex); +end; + +function tifidatacol.getascurrency(const aindex: integer): currency; +begin + checkdatalist(idk_currency); + result:= tcurrencydatalist(fdata).items[aindex]; +end; + +procedure tifidatacol.setascurrency(const aindex: integer; + const avalue: currency); +begin + checkdatalist(idk_currency); + tcurrencydatalist(fdata).items[aindex]:= avalue; + datachange(aindex); +end; + +function tifidatacol.getasreal(const aindex: integer): real; +begin + checkdatalist(idk_real); + result:= trealdatalist(fdata).items[aindex]; +end; + +procedure tifidatacol.setasreal(const aindex: integer; const avalue: real); +begin + checkdatalist(idk_real); + trealdatalist(fdata).items[aindex]:= avalue; + datachange(aindex); +end; + +function tifidatacol.getasmsestring(const aindex: integer): msestring; +begin + checkdatalist(idk_msestring); + result:= tmsestringdatalist(fdata).items[aindex]; +end; + +procedure tifidatacol.setasmsestring(const aindex: integer; + const avalue: msestring); +begin + checkdatalist(idk_msestring); + tmsestringdatalist(fdata).items[aindex]:= avalue; + datachange(aindex); +end; + +function tifidatacol.getasbytes(const aindex: integer): ansistring; +begin + checkdatalist(idk_bytes); + result:= tansistringdatalist(fdata).items[aindex]; +end; + +procedure tifidatacol.setasbytes(const aindex: integer; + const avalue: ansistring); +begin + checkdatalist(idk_bytes); + tansistringdatalist(fdata).items[aindex]:= avalue; + datachange(aindex); +end; + +function tifidatacol.getasmsestringint(const aindex: integer): msestringintty; +begin + checkdatalist(idk_msestringint); + result:= tmsestringintdatalist(fdata).doubleitems[aindex]; +end; + +procedure tifidatacol.setasmsestringint(const aindex: integer; + const avalue: msestringintty); +begin + checkdatalist(idk_msestringint); + tmsestringintdatalist(fdata).doubleitems[aindex]:= avalue; + datachange(aindex); +end; + +function tifidatacol.getasmsestringinti(const aindex: integer): integer; +begin + checkdatalist(idk_msestringint); + result:= tmsestringintdatalist(fdata).itemsb[aindex]; +end; + +procedure tifidatacol.setasmsestringinti(const aindex: integer; + const avalue: integer); +begin + checkdatalist(idk_msestringint); + tmsestringintdatalist(fdata).itemsb[aindex]:= avalue; + datachange(aindex); +end; + +function tifidatacol.getasmsestringints(const aindex: integer): msestring; +begin + checkdatalist(idk_msestringint); + result:= tmsestringintdatalist(fdata).items[aindex]; +end; + +procedure tifidatacol.setasmsestringints(const aindex: integer; + const avalue: msestring); +begin + checkdatalist(idk_msestringint); + tmsestringintdatalist(fdata).items[aindex]:= avalue; + datachange(aindex); +end; + +function tifidatacol.getasrealint(const aindex: integer): realintty; +begin + checkdatalist(idk_realint); + result:= trealintdatalist(fdata).doubleitems[aindex]; +end; + +procedure tifidatacol.setasrealint(const aindex: integer; + const avalue: realintty); +begin + checkdatalist(idk_realint); + trealintdatalist(fdata).doubleitems[aindex]:= avalue; + datachange(aindex); +end; + +function tifidatacol.getasrealintr(const aindex: integer): realty; +begin + checkdatalist(idk_realint); + result:= trealintdatalist(fdata).items[aindex]; +end; + +procedure tifidatacol.setasrealintr(const aindex: integer; + const avalue: realty); +begin + checkdatalist(idk_realint); + trealintdatalist(fdata).items[aindex]:= avalue; + datachange(aindex); +end; + +function tifidatacol.getasrealinti(const aindex: integer): integer; +begin + checkdatalist(idk_realint); + result:= trealintdatalist(fdata).itemsb[aindex]; +end; + +procedure tifidatacol.setasrealinti(const aindex: integer; + const avalue: integer); +begin + checkdatalist(idk_realint); + trealintdatalist(fdata).itemsb[aindex]:= avalue; + datachange(aindex); +end; + +function tifidatacol.getmerged(const row: integer): boolean; +begin + if index = 0 then begin + result:= false; + end + else begin + if index > mergedcolmax then begin + result:= tifidatacols(prop).frowstate.getitempocolmerge(row)^.colmerge.merged = mergedcolall; + end + else begin + result:= tifidatacols(prop).frowstate.getitempocolmerge(row)^.colmerge.merged and + bits[index-1] <> 0; + end; + end; +end; + +procedure tifidatacol.setmerged(const row: integer; const avalue: boolean); +begin + if (index > 0) and (index <= mergedcolmax) then begin + if updatebit(tifidatacols(prop).frowstate.getitempocolmerge(row)^.colmerge.merged,index-1, + avalue) then begin + ttxdatagrid(fowner).rowstatechanged(row); + end; + end; +end; + +function tifidatacol.getselected(row: integer): boolean; +begin + if ident <= selectedcolmax then begin + if row >= 0 then begin + result:= (icos_selected in fstate) or + (tifidatacols(prop).frowstate.getitempo(row)^.selected and + (bits[ident] or wholerowselectedmask) <> 0); + end + else begin + result:= icos_selected in fstate; + end; + end + else begin + result:= false; + end; +end; + +procedure tifidatacol.setselected(row: integer; const avalue: boolean); +var + po1: prowstatety; + ca1: longword; + int1: integer; +begin + if ident <= selectedcolmax then begin + if row >= 0 then begin + with tifidatacols(prop).frowstate.getitempo(row)^ do begin + ca1:= selected; + if avalue then begin + ca1:= selected or bits[ident]; + end + else begin + ca1:= selected and not (bits[ident] {or wholerowselectedmask}); + end; + if ca1 <> selected then begin + if avalue then begin + if fselectedrow = -1 then begin + fselectedrow:= row; + end + else begin + fselectedrow:= -2; + end; + end + else begin + if fselectedrow = row then begin + fselectedrow:= -1; + end; + end; +// invalidatecell(row); + doselectionchanged; + end; + end; + end + else begin //row < 0 + if avalue then begin + if not (icos_selected in fstate) then begin + include(fstate,icos_selected); + fselectedrow:= -2; +// changed; + doselectionchanged; + end; + end + else begin + exclude(fstate,icos_selected); + if fselectedrow <> -1 then begin + po1:= tifidatacols(prop).frowstate.datapo; + ca1:= not (bits[ident] {or wholerowselectedmask}); + if fselectedrow >= 0 then begin + prowstateaty(po1)^[fselectedrow].selected:= + prowstateaty(po1)^[fselectedrow].selected and ca1; +// invalidatecell(fselectedrow); +// cellchanged(fselectedrow); + end + else begin + for int1:= 0 to ttxdatagrid(fowner).frowcount - 1 do begin + po1^.selected:= po1^.selected and ca1; + inc(po1); + end; +// changed; + end; + fselectedrow:= -1; + doselectionchanged; + end; + end; + end; + end; +end; + +procedure tifidatacol.doselectionchanged; +begin + //dummy +end; + +procedure tifidatacol.beginselect; +begin +end; + +procedure tifidatacol.endselect; +begin +end; + +{ tifidatacols } + +constructor tifidatacols.create(const aowner: ttxdatagrid); +begin + fselectedrow:= -1; + frowstate:= tifirowstatelist.create(ril_colmerge); + inherited create(aowner,tifidatacol); +end; + +destructor tifidatacols.destroy; +begin + inherited; + frowstate.free; +end; + +class function tifidatacols.getitemclasstype: persistentclassty; +begin + result:= tifidatacol; +end; + +function tifidatacols.getcols(const index: integer): tifidatacol; +begin + result:= tifidatacol(inherited getitems(index)); +end; + +procedure tifidatacols.setcols(const index: integer; const avalue: tifidatacol); +begin + tifidatacol(inherited getitems(index)).assign(avalue); +end; + +function tifidatacols.colbyname(const aname: ansistring): tifidatacol; +var + int1: integer; +begin + result:= nil; + for int1:= 0 to count - 1 do begin + if tifidatacol(fitems[int1]).fname = aname then begin + result:= tifidatacol(fitems[int1]); + break; + end; + end; +end; + +function tifidatacols.datalistbyname(const aname: ansistring): tdatalist; +var + col1: tifidatacol; +begin + result:= nil; + col1:= colbyname(aname); + if col1 <> nil then begin + result:= col1.datalist; + end; +end; + +function tifidatacols.getselectedcells: gridcoordarty; +const + capacitystep = 64; +var + int1,int2,int3: integer; + cell: gridcoordty; + bo1: boolean; +begin + result:= nil; + if hasselection then begin //todo: optimize + int3:= 0; + bo1:= hascolselection; + for int1:= 0 to frowstate.count - 1 do begin + if bo1 or (frowstate.getitempo(int1)^.selected <> 0) then begin + cell.row:= int1; + for int2:= 0 to count - 1 do begin + if tifidatacol(fitems[int2]).selected[int1] then begin + if int3 >= length(result) then begin + setlength(result,length(result)*2 + capacitystep); + end; + cell.col:= int2; + result[int3]:= cell; + inc(int3); + end; + end; + end; + end; + setlength(result,int3); + end; +end; + +procedure tifidatacols.setselectedcells(const avalue: gridcoordarty); +var + int1: integer; +begin + ttxdatagrid(fowner).beginupdate; + beginselect; + clearselection; + for int1:= 0 to high(avalue) do begin + setselected(avalue[int1],true); + end; + endselect; + ttxdatagrid(fowner).endupdate; +end; + +function tifidatacols.Getselected(const cell: gridcoordty): boolean; +var + int1: integer; +begin + if cell.col >= 0 then begin + result:= cols[cell.col].getselected(cell.row); + end + else begin + if cell.row >= 0 then begin + result:= (frowstate.getitempo(cell.row)^.selected and wholerowselectedmask <> 0); + end + else begin + result:= true; + for int1:= 0 to count - 1 do begin + if not (icos_selected in cols[int1].fstate) then begin + result:= false; + break; + end; + end; + end; + end; +end; + +procedure tifidatacols.Setselected(const cell: gridcoordty; + const avalue: boolean); +var + lwo1: longword; +// bo1: boolean; + po1: prowstatety; + int1: integer; +begin + ttxdatagrid(fowner).setselected(cell,avalue); + if cell.col >= 0 then begin + cols[cell.col].setselected(cell.row,avalue); + end + else begin //select-deselect whole row +// fgrid.beginupdate; +// try + for int1:= 0 to count - 1 do begin + cols[int1].setselected(cell.row,avalue); + end; + if avalue then begin + lwo1:= $ffffffff; + end + else begin + lwo1:= 0; + end; +// bo1:= false; + if cell.row >= 0 then begin + po1:= frowstate.getitempo(cell.row); + if lwo1 <> po1^.selected then begin + if avalue then begin + if fselectedrow = -1 then begin + fselectedrow:= cell.row; + end + else begin + fselectedrow:= -2; + end; + end + else begin + if fselectedrow = cell.row then begin + fselectedrow:= -1; + end; + end; + po1^.selected:= lwo1; +// fgrid.invalidaterow(cell.row); //for fixcols +// bo1:= true; + end; + end + else begin + po1:= frowstate.datapo; + if avalue then begin + for int1:= 0 to frowstate.count - 1 do begin +// if ca1 <> po1^.selected then begin + po1^.selected:= lwo1; +// fgrid.invalidaterow(int1); //for fixcols +// end; + inc(po1); + end; + fselectedrow:= -2; + end + else begin + if fselectedrow <> -1 then begin + if fselectedrow >= 0 then begin + prowstateaty(po1)^[fselectedrow].selected:= lwo1; +// fgrid.invalidaterow(fselectedrow); //for fixcols +// bo1:= true; + end + else begin + for int1:= 0 to frowstate.count - 1 do begin + if lwo1 <> po1^.selected then begin + po1^.selected:= lwo1; +// fgrid.invalidaterow(int1); //for fixcols +// bo1:= true; + end; + inc(po1); + end; + end; + fselectedrow:= -1; + end; + end; + end; + end; +// if bo1 then begin +// fgrid.internalselectionchanged; +// end; + +end; + +function tifidatacols.selectedcellcount: integer; +var + int1,int2: integer; + bo1: boolean; +begin + result:= 0; + if hasselection then begin + bo1:= hascolselection; + for int1:= 0 to frowstate.count - 1 do begin + if bo1 or (frowstate.getitempo(int1)^.selected <> 0) then begin + for int2:= 0 to count - 1 do begin + if tifidatacol(fitems[int2]).selected[int1] then begin + inc(result); + end; + end; + end; + end; + end; +end; + +function tifidatacols.hascolselection: boolean; +var + int1: integer; +begin + result:= false; + for int1:= 0 to count - 1 do begin + if icos_selected in tifidatacol(fitems[int1]).fstate then begin + result:= true; + exit; + end; + end; +end; + +procedure tifidatacols.setselectedrange(const rect: gridrectty; + const value: boolean); +begin + setselectedrange(rect.pos, + makegridcoord(rect.col+rect.colcount,rect.row+rect.rowcount), + value); +end; + +procedure tifidatacols.setselectedrange(const start: gridcoordty; + const stop: gridcoordty; const value: boolean); +var + int1,int2: integer; +// mo1: cellselectmodety; + rect: gridrectty; +begin + rect.pos:= start; + rect.colcount:= stop.col - start.col; + rect.rowcount:= stop.row - start.row; + normalizerect1(rectty(rect)); + for int1:= rect.col to rect.col + rect.colcount - 1 do begin + cols[int1].beginselect; + for int2:= rect.row to rect.row + rect.rowcount - 1 do begin + selected[makegridcoord(int1,int2)]:= value; + end; + end; + for int1:= rect.col to rect.col + rect.colcount - 1 do begin + dec(cols[int1].fselectlock); + end; +end; + +procedure tifidatacols.mergecols(const arow: integer; + const astart: longword = 0; const acount: longword = bigint); +begin + if frowstate.mergecols(arow,astart,acount) then begin + ttxdatagrid(fowner).rowstatechanged(arow); + end; +end; + +procedure tifidatacols.unmergecols(const arow: integer = invalidaxis); +begin + if frowstate.unmergecols(arow) then begin + ttxdatagrid(fowner).rowstatechanged(arow); + end; +end; + +function tifidatacols.hasselection: boolean; +var + int1: integer; +begin + result:= fselectedrow <> -1; + if not result then begin + for int1:= 0 to count - 1 do begin + if cols[int1].fselectedrow <> -1 then begin + result:= true; + break; + end; + end; + end; +end; + +procedure tifidatacols.beginselect; +begin +end; + +procedure tifidatacols.endselect; +begin +end; + +procedure tifidatacols.clearselection; +begin + setselected(invalidcell,false); +end; + +{ ttxdatagrid } + +constructor ttxdatagrid.create(aowner: tcomponent); +begin + fifi:= ttxdatagridcontroller.create(self,iactivatorclient(self)); + inherited; + fdatacols:= tifidatacols.create(self); +end; + +destructor ttxdatagrid.destroy; +begin + fdatacols.free; + inherited; + fifi.free; +end; + +procedure ttxdatagrid.setifi(const avalue: ttxdatagridcontroller); +begin + fifi.assign(avalue); +end; + +procedure ttxdatagrid.setdatacols(const avalue: tifidatacols); +begin + fdatacols.assign(avalue); +end; + +procedure ttxdatagrid.setrowcount(const avalue: integer); +var + int1: integer; +begin + if frowcount <> avalue then begin + frowcount:= avalue; + with fdatacols do begin + for int1:= 0 to high(fitems) do begin + with tifidatacol(fitems[int1]) do begin + if fdata <> nil then begin + fdata.count:= avalue; + end; + end; + end; + frowstate.count:= avalue; + end; + end; +end; + +function ttxdatagrid.getrowcolorstate(index: integer): rowstatenumty; +begin + result:= fdatacols.frowstate.color[index]; +end; + +procedure ttxdatagrid.setrowcolorstate(index: integer; + const avalue: rowstatenumty); +begin + fdatacols.frowstate.color[index]:= avalue; + rowstatechanged(index); +end; + +function ttxdatagrid.getrowfontstate(index: integer): rowstatenumty; +begin + result:= fdatacols.frowstate.font[index]; +end; + +procedure ttxdatagrid.setrowfontstate(index: integer; + const avalue: rowstatenumty); +begin + fdatacols.frowstate.font[index]:= avalue; + rowstatechanged(index); +end; + +function ttxdatagrid.getrowreadonlystate(const index: integer): boolean; +begin + result:= fdatacols.frowstate.readonly[index]; +end; + +procedure ttxdatagrid.setrowreadonlystate(const index: integer; + const avalue: boolean); +begin + fdatacols.frowstate.readonly[index]:= avalue; + rowstatechanged(index); +end; + +function ttxdatagrid.getrowhidden(const index: integer): boolean; +begin + result:= fdatacols.frowstate.hidden[index]; +end; + +procedure ttxdatagrid.setrowhidden(const index: integer; + const avalue: boolean); +begin + fdatacols.frowstate.hidden[index]:= avalue; +end; + +function ttxdatagrid.getrowfoldlevel(const index: integer): byte; +begin + result:= fdatacols.frowstate.foldlevel[index]; +end; + +procedure ttxdatagrid.setrowfoldlevel(const index: integer; + const avalue: byte); +begin + fdatacols.frowstate.foldlevel[index]:= avalue; +end; + +function ttxdatagrid.getrowfoldissum(const index: integer): boolean; +begin + result:= fdatacols.frowstate.foldissum[index]; +end; + +procedure ttxdatagrid.setrowfoldissum(const index: integer; + const avalue: boolean); +begin + fdatacols.frowstate.foldissum[index]:= avalue; +end; + +function ttxdatagrid.getrowhigh: integer; +begin + result:= frowcount - 1; +end; + +procedure ttxdatagrid.moverow(const curindex: integer; const newindex: integer; + const count: integer = 1); +var + int1: integer; +begin + with fdatacols do begin + for int1:= 0 to high(fitems) do begin + with tifidatacol(fitems[int1]) do begin + if fdata <> nil then begin + fdata.blockmovedata(curindex,newindex,count); + end; + end; + end; + frowstate.blockmovedata(curindex,newindex,count); + end; + if canevent(tmethod(fonrowsmoved)) then begin + fonrowsmoved(self,curindex,newindex,count); + end; + with fifi do begin + if cancommandsend(igo_rowmove) then begin + senditem(ik_gridcommand,[ + encodegridcommanddata(gck_moverow,curindex,newindex,count)]); + end; + end; +end; + +procedure ttxdatagrid.insertrow(index: integer; count: integer = 1); +var + int1: integer; +begin + with fdatacols do begin + for int1:= 0 to high(fitems) do begin + with tifidatacol(fitems[int1]) do begin + if fdata <> nil then begin + fdata.insertitems(index,count); + end; + end; + end; + frowstate.insertitems(index,count); + end; + if canevent(tmethod(fonrowsinserted)) then begin + fonrowsinserted(self,index,count); + end; + with fifi do begin + if cancommandsend(igo_rowinsert) then begin + senditem(ik_gridcommand,[ + encodegridcommanddata(gck_insertrow,index,index,count)]); + end; + end; +end; + +procedure ttxdatagrid.deleterow(index: integer; count: integer = 1); +var + int1: integer; +begin + with fdatacols do begin + for int1:= 0 to high(fitems) do begin + with tifidatacol(fitems[int1]) do begin + if fdata <> nil then begin + fdata.deleteitems(index,count); + end; + end; + end; + frowstate.deleteitems(index,count); + end; + if canevent(tmethod(fonrowsdeleted)) then begin + fonrowsdeleted(self,index,count); + end; + with fifi do begin + if cancommandsend(igo_rowdelete) then begin + senditem(ik_gridcommand,[ + encodegridcommanddata(gck_deleterow,index,index,count)]); + end; + end; +end; + +procedure ttxdatagrid.setrow(const avalue: integer); +begin + frow:= avalue; + if canevent(tmethod(fonrowindexchanged)) then begin + fonrowindexchanged(self); + end; + with fifi do begin + if cancommandsend(igo_rowenter) then begin + senditem(ik_gridcommand, + [encodegridcommanddata(gck_rowenter,avalue,avalue,0)]); + end; + end; +end; + +procedure ttxdatagrid.rowstatechanged(const aindex: integer); +begin + if canevent(tmethod(fonrowstatechanged)) then begin + fonrowstatechanged(self,aindex); + end; + with fifi do begin + if cancommandsend(igo_rowstate) then begin + senditem(ik_rowstatechange, + [encoderowstatedata(aindex,fdatacols.rowstate.itemscolmerge[aindex])]); + end; + end; +end; + +procedure ttxdatagrid.beginupdate; +begin + fifi.beginupdate; +end; + +procedure ttxdatagrid.endupdate; +begin + fifi.endupdate; +end; + +procedure ttxdatagrid.clear; +begin + rowcount:= 0; +end; + +procedure ttxdatagrid.setselected(const cell: gridcoordty; + const avalue: boolean); +begin + with fifi do begin + if cancommandsend(igo_selection) then begin + senditem(ik_selection,[encodeselectiondata(cell,avalue)]); + end; + end; +end; + +{ tifigridcontroller } + +function tifigridcontroller.getifireckinds: ifireckindsty; +begin + result:= [ik_griddata,ik_requestopen,ik_gridcommand, + ik_coldatachange,ik_rowstatechange,ik_selection]; +end; + +function tifigridcontroller.cancommandsend( + const akind: ifigridoptionty): boolean; +begin + result:= (akind in foptionstx) and (fcommandlock = 0) and + (fupdating = 0) and cansend; +end; + +procedure tifigridcontroller.sendstate; +begin + if cansend then begin + senddata(encodegriddata(0)); + end; +end; + +procedure tifigridcontroller.beginupdate; +begin + inc(fupdating); +end; + +procedure tifigridcontroller.endupdate; +begin + dec(fupdating); + if (fupdating = 0) and cancommandsend(igo_state) then begin + sendstate; + end; +end; + +{ ttxdatagridcontroller } + +constructor ttxdatagridcontroller.create(const aowner: ttxdatagrid; + const aintf: iactivatorclient); +begin + inherited create(aowner,aintf); +end; + +procedure ttxdatagridcontroller.processdata(const adata: pifirecty; + var adatapo: pchar); +var + int1: integer; + rows1,cols1: integer; + kind1: listdatatypety; + po1: pchar; + str1: ansistring; + datalist1: tdatalist; + ckind1: gridcommandkindty; + source1,dest1,count1: integer; + rowstate1: rowstatecolmergety; + lwo1: longword; + select1: selectdataty; + +begin + with adata^.header do begin + case kind of + ik_requestopen: begin + with ttxdatagrid(fowner) do begin + if canevent(tmethod(fonbeforeopen)) then begin + inc(fcommandlock); + inc(fupdating); + try + fonbeforeopen(ttxdatagrid(fowner)); + finally + dec(fcommandlock); + dec(fupdating); + end; + end; + end; + senddata(encodegriddata(sequence)); + end; + ik_griddata: begin + if (igo_state in foptionsrx) then begin + with ttxdatagrid(fowner) do begin + with pgriddatadataty(adatapo)^ do begin + rows1:= rows; + rowcount:= rows1; + cols1:= cols; + po1:= @data; + end; + for int1:= 0 to cols1 - 1 do begin + with pcoldataty(po1)^ do begin + kind1:= kind; + po1:= @name; + inc(po1,ifinametostring(pifinamety(po1),str1)); + inc(po1,ifidatatodatalist(kind1,rows1,po1, + datacols.datalistbyname(str1))); + end; + end; + end; + end; + end; + ik_gridcommand: begin + inc(adatapo,decodegridcommanddata(adatapo,ckind1,source1,dest1,count1)); + with ttxdatagrid(fowner) do begin + inc(fcommandlock); + try + case ckind1 of + gck_insertrow: begin + if igo_rowinsert in foptionsrx then begin + insertrow(dest1,count1); + end; + end; + gck_deleterow: begin + if igo_rowdelete in foptionsrx then begin + deleterow(dest1,count1); + end; + end; + gck_moverow: begin + if igo_rowmove in foptionsrx then begin + moverow(source1,dest1,count1); + end; + end; + gck_rowenter: begin + if igo_rowenter in foptionsrx then begin + row:= dest1; + end; + end; + end; + finally + dec(fcommandlock); + end; + end; + end; + ik_coldatachange: begin + if igo_coldata in foptionsrx then begin + inc(fcommandlock); + try + int1:= pcolitemdataty(adatapo)^.header.row; + ifinametostring(@pcolitemdataty(adatapo)^.header.name,str1); + inc(adatapo,sizeof(colitemheaderty)+length(str1)); + datalist1:= nil; + if igo_coldata in foptionsrx then begin + datalist1:= ttxdatagrid(fowner).fdatacols.datalistbyname(str1); + end; //skip data otherwise + inc(adatapo,decodeifidata(pifidataty(adatapo),int1,datalist1)); + finally + dec(fcommandlock); + end; + end; + end; + ik_rowstatechange: begin + if igo_rowstate in foptionsrx then begin + inc(fcommandlock); + try + int1:= prowstatedataty(adatapo)^.header.row; + inc(adatapo,sizeof(rowstateheaderty)); + inc(adatapo,decodeifidata(pifidataty(adatapo),rowstate1)); + with ttxdatagrid(fowner),rowstate1 do begin + rowcolorstate[int1]:= normal.color; + rowfontstate[int1]:= normal.font; + lwo1:= fdatacols.rowstate[int1].selected; + if lwo1 <> normal.selected then begin + fdatacols.rowstate.getitempo(int1)^.selected:= lwo1; + end; + rowhidden[int1]:= normal.fold and foldhiddenmask <> 0; + rowfoldlevel[int1]:= normal.fold and foldlevelmask; + end; + finally + dec(fcommandlock); + end; + end; + end; + ik_selection: begin + if igo_selection in foptionsrx then begin + inc(fcommandlock); + try + inc(adatapo,decodeifidata(pifidataty(adatapo),select1)); + with ttxdatagrid(fowner),select1 do begin + fdatacols.selected[makegridcoord(col,row)]:= select; + end; + finally + dec(fcommandlock); + end; + end; + end; + end; + end; +end; + +procedure ttxdatagridcontroller.setowneractive(const avalue: boolean); +begin + //dummy +end; +{ +function ttxdatagridcontroller.getifireckinds: ifireckindsty; +begin + result:= [ik_requestopen,ik_griddata,ik_gridcommand,ik_coldatachange, + ik_rowstatechange]; +end; +} +function ifidatatodatalist(const akind: listdatatypety; const arowcount: integer; + const adata: pchar; const adatalist: tdatalist): integer; + //returns datasize +var + info1: subdatainfoty; +begin + info1.subindex:= 0; + info1.list:= adatalist; + result:= ifidatatodatalist(akind,arowcount,adata,info1); +end; + +function ifidatatodatalist(const akind: listdatatypety; const arowcount: integer; + const adata: pchar; const adatalist: subdatainfoty): integer; +var + int1,int2: integer; + posource,podest: pchar; + movesize,sourcestep,deststep: integer; + po1: pmsestring; + po2: pinteger; + po3: pansistring; + po4: pmsestringintty; +begin + with adatalist do begin + if (list <> nil) and (list.datatype <> akind) and + not((akind = dl_realint) and (list.datatype = dl_realsum)) then begin + raise exception.create('Datakinds do not match.'); + end; + case akind of + dl_integer: begin + result:= arowcount * sizeof(integer); + if list <> nil then begin + move(adata^,list.datapo^,result); + end; + end; + dl_int64: begin + result:= arowcount * sizeof(int64); + if list <> nil then begin + move(adata^,list.datapo^,result); + end; + end; + dl_currency: begin + result:= arowcount * sizeof(currency); + if list <> nil then begin + move(adata^,list.datapo^,result); + end; + end; + dl_real: begin + result:= arowcount * sizeof(real); + if list <> nil then begin + move(adata^,list.datapo^,result); + end; + end; + dl_msestring: begin + po2:= pinteger(adata); + result:= arowcount * sizeof(integer); + if list <> nil then begin + deststep:= list.size; + po1:= list.datapo; + for int1:= 0 to arowcount - 1 do begin + move(po2^,int2,sizeof(integer)); + setlength(po1^,int2); + int2:= int2 * sizeof(msechar); + result:= result + int2; + inc(po2); + move(po2^,pointer(po1^)^,int2); + inc(pchar(pointer(po2)),int2); + inc(pchar(po1),deststep); + end; + end + else begin + for int1:= 0 to arowcount - 1 do begin + int2:= po2^*sizeof(msechar); + result:= result + int2; + inc(po2); + inc(pchar(pointer(po2)),int2); + end; + end; + end; + dl_msestringint: begin + po2:= pinteger(adata); + result:= arowcount * (sizeof(integer)+sizeof(integer)); + if list <> nil then begin + po4:= list.datapo; + deststep:= list.size; + for int1:= 0 to arowcount - 1 do begin + move(po2^,po4^.int,sizeof(integer)); + inc(po2); + move(po2^,int2,sizeof(integer)); + setlength(po4^.mstr,int2); + int2:= int2 * sizeof(msechar); + result:= result + int2; + inc(po2); + move(po2^,po4^.mstr[1],int2); + inc(pchar(pointer(po2)),int2); + inc(pchar(po4),deststep); + end; + end + else begin + for int1:= 0 to arowcount - 1 do begin + inc(po2); + int2:= po2^*sizeof(msechar); + result:= result + int2; + inc(po2); + inc(pchar(pointer(po2)),int2); + end; + end; + end; + dl_realint,dl_realsum: begin + result:= list.setdatablock(adata,sizeof(ifirealintty),arowcount); + exit; + end; + dl_rowstate: begin + move(adata^,int1,sizeof(int1)); + posource:= adata; + inc(posource,sizeof(int1)); + sourcestep:= rowinfosizes[rowinfolevelty(int1)]; + result:= arowcount * sourcestep; + if list <> nil then begin + // tcustomrowstatelist1(adatalist).initdirty; + if tcustomrowstatelist(list).infolevel = + rowinfolevelty(int1) then begin + move(posource^,list.datapo^,result); + end + else begin + podest:= list.datapo; + deststep:= list.size; + movesize:= deststep; + if movesize > sourcestep then begin + movesize:= sourcestep; + end; + for int2:= 0 to arowcount - 1 do begin + move(posource^,podest^,movesize); + inc(posource,sourcestep); + inc(podest,deststep); + end; + end; + tcustomrowstatelist1(list).recalchidden; + end; + result:= result + sizeof(int1); + end; + dl_ansistring: begin + po2:= pinteger(adata); + result:= arowcount * sizeof(integer); + if list <> nil then begin + deststep:= list.size; + po3:= list.datapo; + for int1:= 0 to arowcount - 1 do begin + move(po2^,int2,sizeof(integer)); + setlength(po3^,int2); + result:= result + int2; + inc(po2); + move(po2^,pansistringaty(po3)^[int1][1],int2); + inc(pchar(pointer(po2)),int2); + inc(pchar(po3),deststep); + end; + end + else begin + for int1:= 0 to arowcount - 1 do begin + int2:= po2^; + result:= result + int2; + inc(po2); + inc(pchar(pointer(po2)),int2); + end; + end; + end; + else begin + raise exception.create('Invalid datakind.'); + end; + end; + if list <> nil then begin + list.change(-1); + end; + end; +end; + +procedure datalisttoifidata(const adatalist: tdatalist; + var dest: pchar); overload; +var + int1,int2: integer; + po4: pchar; +begin + with adatalist do begin + po4:= datapo; + case datatype of + dl_integer: begin + int2:= count * sizeof(integer); + move(po4^,dest^,int2); + inc(dest,int2); + end; + dl_int64: begin + int2:= count * sizeof(int64); + move(po4^,dest^,int2); + inc(dest,int2); + end; + dl_currency: begin + int2:= count * sizeof(currency); + move(po4^,dest^,int2); + inc(dest,int2); + end; + dl_real: begin + int2:= count * sizeof(real); + move(po4^,dest^,int2); + inc(dest,int2); + end; + dl_realint,dl_realsum: begin + inc(dest,getdatablock(dest,sizeof(ifirealintty))); + end; + dl_msestring: begin + for int1:= 0 to count - 1 do begin + int2:= length(pmsestringaty(po4)^[int1]); + move(int2,dest^,sizeof(integer)); + int2:= int2 * sizeof(msechar); + inc(dest,sizeof(integer)); + move(pointer(pmsestringaty(po4)^[int1])^,dest^,int2); + inc(dest,int2); + end; + end; + dl_msestringint: begin + for int1:= 0 to count - 1 do begin + move(pmsestringintaty(po4)^[int1].int,dest^,sizeof(integer)); + inc(dest,sizeof(integer)); + int2:= length(pmsestringintaty(po4)^[int1].mstr); + move(int2,dest^,sizeof(integer)); + int2:= int2 * sizeof(msechar); + inc(dest,sizeof(integer)); + move(pmsestringintaty(po4)^[int1].mstr[1],dest^,int2); + inc(dest,int2); + end; + end; + dl_rowstate: begin + int1:= integer(tcustomrowstatelist(adatalist).infolevel); + move(int1,dest^,sizeof(integer)); + inc(dest,sizeof(integer)); + int2:= count * size; + move(po4^,dest^,int2); + inc(dest,int2); + end; + dl_ansistring: begin + for int1:= 0 to count - 1 do begin + int2:= length(pansistringaty(po4)^[int1]); + move(int2,dest^,sizeof(integer)); + inc(dest,sizeof(integer)); + move(pointer(pansistringaty(po4)^[int1])^,dest^,int2); + inc(dest,int2); + end; + end; + else begin + raise exception.create('No ifi datalist'); + end; + end; + end; +end; + +function datalisttoifidata(const adatalist: tdatalist): integer; overload; +// returns size +var + int1: integer; + po1: pmsestring; + po2: pansistring; + po3: pmsestringintty; + s1: integer; +begin + with adatalist do begin + s1:= size; + case adatalist.datatype of + dl_integer: begin + result:= count * sizeof(integer); + end; + dl_int64: begin + result:= count * sizeof(int64); + end; + dl_currency: begin + result:= count * sizeof(currency); + end; + dl_real: begin + result:= count * sizeof(real); + end; + dl_msestring: begin + po1:= datapo; + result:= count * sizeof(integer); + for int1:= 0 to count - 1 do begin + result:= result + length(po1^) * sizeof(msechar); + inc(pchar(po1),s1); + end; + end; + dl_msestringint: begin + po3:= datapo; + result:= count * (sizeof(integer)+sizeof(integer)); + for int1:= 0 to count - 1 do begin + result:= result + length(po3^.mstr) * sizeof(msechar); + inc(pchar(po3),s1); + end; + end; + dl_realint,dl_realsum: begin + result:= count * sizeof(ifirealintty); + end; + dl_rowstate: begin + result:= count * size + sizeof(integer); + end; + dl_ansistring: begin + po2:= datapo; + result:= count * sizeof(integer); + for int1:= 0 to count - 1 do begin + result:= result + length(po2^); + inc(pchar(po2),s1); + end; + end; + else begin + raise exception.create('No ifi datalist.'); + end; + end; + end; +end; + +function ttxdatagridcontroller.encodegriddata( + const asequence: sequencety): ansistring; +var + po1{,po4}: pchar; + int1,int2{,int3,int4}: integer; +// po2: pmsestring; +// po3: pansistring; + ar1: booleanarty; +begin + with ttxdatagrid(fowner) do begin + setlength(ar1,datacols.count); + int2:= 0; + for int1:= 0 to datacols.count - 1 do begin + with datacols[int1] do begin + checkdatalist; + ar1[int1]:= (name <> '') and (datalist.datatype in ifidatatypes); + if ar1[int1] then begin + int2:= int2 + (sizeof(listdatatypety)+1) + length(name) + + datalisttoifidata(datalist); + end; + end; + end; + int2:= int2 + datalisttoifidata(datacols.frowstate); + inititemheader(result,ik_griddata,asequence,int2,po1); + with pgriddatadataty(po1)^ do begin + rows:= rowcount; + cols:= datacols.count; + po1:= @data; + for int1:= 0 to high(ar1) do begin + if ar1[int1] then begin + with datacols[int1] do begin + with pcoldataty(po1)^ do begin + kind:= datalist.datatype; + po1:= @name; + end; + inc(po1,stringtoifiname(name,pifinamety(po1))); + datalisttoifidata(datalist,po1); + end; + end; + end; + datalisttoifidata(datacols.frowstate,po1); + end; + end; +end; + +{ tifirowstatelist } + +procedure tifirowstatelist.sethidden(const index: integer; + const avalue: boolean); +begin + updatebit(getitempo(index)^.fold,foldhiddenbit,avalue); +end; + +procedure tifirowstatelist.setfoldlevel(const index: integer; + const avalue: byte); +begin + replacebits1(byte(getitempo(index)^.fold),byte(avalue),byte(foldlevelmask)); +end; + +procedure tifirowstatelist.setfoldissum(const index: integer; + const avalue: boolean); +begin + updatebit(getitempo(index)^.flags,foldissumbit,avalue); +end; + +end. + diff --git a/mseide-msegui/lib/common/ifi/msejson.pas b/mseide-msegui/lib/common/ifi/msejson.pas new file mode 100644 index 0000000..e5b6ff5 --- /dev/null +++ b/mseide-msegui/lib/common/ifi/msejson.pas @@ -0,0 +1,1177 @@ +{ MSEgui Copyright (c) 2015-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} + +unit msejson; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,msestrings,msesystypes,msetypes,sysutils,mseformatstr; + +type + ejsonerror = class(exception); + + jsonencodeoptionty = (jseo_tabindent); + jsonencodeoptionsty = set of jsonencodeoptionty; + + jsondatatypty = (jot_null,jot_string,jot_boolean,jot_int32,jot_int64, + jot_flo64); //zero init -> null + jsondataty = record + case typ: jsondatatypty of + jot_null: (vnull: record end); + jot_string: (vstring: pointer); //msestring + jot_boolean: (vboolean: boolean); + jot_int32: (vint32: int32); + jot_int64: (vint64: int64); + jot_flo64: (vflo64: double); + end; + + jsonkindty = (jok_empty,jok_error,jok_value,jok_object,jok_array); + //zero init -> empty + jsonvaluety = record + case kind: jsonkindty of + jok_empty,jok_error: (err: record end); + jok_object:(obj: pointer); //jsonitemarty + jok_array: (ar: pointer); //jsonvaluearty + jok_value: (val: jsondataty); + end; + pjsonvaluety = ^jsonvaluety; + jsonvaluearty = array of jsonvaluety; + + jsonitemty = record + name: msestring; + value: jsonvaluety; + end; + pjsonitemty = ^jsonitemty; + jsonitemarty = array of jsonitemty; + + arraystartmethodty = procedure(var adata; + const acount: int32) of object; + arrayitemmethodty = procedure(var adata; + const aindex: int32; const aitem: jsonvaluety) of object; + + arraystartprocty = procedure(var adata; + const acount: int32); + arrayitemprocty = procedure(var adata; + const aindex: int32; const aitem: jsonvaluety); + + tjsoncontainer = class + private + protected + fvalue: jsonvaluety; + function findvaluevalue(const names: array of msestring): pjsonvaluety; + public + constructor create(const avalue: jsonvaluety); //owns the value + constructor create(const adata: string); + class function trycreate(out ainstance: tjsoncontainer; + const adata: string): boolean; + destructor destroy(); override; + property value: jsonvaluety read fvalue; + function findvalue(const names: array of msestring; + const raiseexception: boolean = false): pjsonvaluety; + //nil if not found + function asstring(const names: array of msestring): msestring; + function asboolean(const names: array of msestring): boolean; + function asint32(const names: array of msestring): int32; + function asint64(const names: array of msestring): int64; + function asflo64(const names: array of msestring): flo64; + procedure iteratearray(const names: array of msestring; var adata; + const startproc: arraystartmethodty; + const itemproc: arrayitemmethodty); + procedure iteratearray(const names: array of msestring; var adata; + const startproc: arraystartprocty; + const itemproc: arrayitemprocty); + end; + +procedure jsonvalueinit(var avalue: jsonvaluety); //inits to null value +procedure jsonvaluefree(var avalue: jsonvaluety); + +function jsonfindvalue(const avalue: jsonvaluety; + const names: array of msestring; + const raiseexception: boolean = false): pjsonvaluety; +function jsonasstring(const avalue: jsonvaluety; + const names: array of msestring): msestring; +function jsonasint32(const avalue: jsonvaluety; + const names: array of msestring): int32; +function jsonasint64(const avalue: jsonvaluety; + const names: array of msestring): int64; +function jsonasflo64(const avalue: jsonvaluety; + const names: array of msestring): flo64; +function jsonasboolean(const avalue: jsonvaluety; + const names: array of msestring): boolean; +procedure jsoniteratearray(const avalue: jsonvaluety; + const names: array of msestring; + var adata; const startproc: arraystartprocty; + const itemproc: arrayitemprocty); +procedure jsoniteratearray(const avalue: jsonvaluety; + const names: array of msestring; + var adata; const startproc: arraystartmethodty; + const itemproc: arrayitemmethodty); +function jsonadditems(var jvalue: jsonvaluety; const anames: array of msestring; + const avalues: array of const): pjsonvaluety; + //if jvalue is a null value it will be converted to object + //[nil] -> null, returns the last added item or @jvalue +function jsonaddvalues(var jvalue: jsonvaluety; + const avalues: array of const): pjsonvaluety; + //if jvalue is a null value it will be converted to array + //[nil] -> null, returns the last added item or @jvalue + +function jsondecode(const adata: string; out avalue:jsonvaluety): boolean; +function jsonencode(const avalue: jsonvaluety; const adest: tstream; + const aoptions: jsonencodeoptionsty = []): syserrorty; + +implementation +uses + msearrayutils,msefloattostr; + +procedure error(const atext: msestring); +begin + raise ejsonerror.create('json error: '+ansistring(atext)); +end; + +procedure nameserror(const names: array of msestring); +begin + error('"'+concatstrings(opentodynarraym(names),'.')+'" not found'); +end; + +procedure conversionerror(const names: array of msestring); +begin + error('"'+concatstrings(opentodynarraym(names),'.')+'" conversion error'); +end; + +{$implicitexceptions off} + +procedure jsonvalueinit(var avalue: jsonvaluety); +begin + avalue.kind:= jok_value; + avalue.val.typ:= jot_null; +end; + +procedure jsonitemfree(var aitem: jsonitemty); forward; + +procedure jsonvaluefree(var avalue: jsonvaluety); +var + po1: pjsonitemty; + po2: pjsonvaluety; + pe: pointer; +begin + case avalue.kind of + jok_value: begin + if avalue.val.typ = jot_string then begin + msestring(avalue.val.vstring):= ''; + end; + end; + jok_array: begin + po2:= avalue.ar; + if po2 <> nil then begin + pe:= po2 + high(jsonvaluearty(po2)); + while po2 <= pe do begin + jsonvaluefree(po2^); + inc(po2); + end; + freeuninitedarray(avalue.ar); + end; + end; + jok_object: begin + po1:= avalue.obj; + if po1 <> nil then begin + pe:= po1 + high(jsonitemarty(po1)); + while po1 <= pe do begin + jsonitemfree(po1^); + inc(po1); + end; + freeuninitedarray(avalue.obj); + end; + end; + end; + avalue.kind:= jok_value; + avalue.val.typ:= jot_null; +end; + +procedure jsonitemfree(var aitem: jsonitemty); +begin + aitem.name:= ''; + jsonvaluefree(aitem.value); +end; + +function stringtojsonstringascii(const avalue: msestring): ansistring; +var + ps,pe: pmsechar; + pd: pchar; + ch1: char; + mch1: msechar; +begin + setlength(result,length(avalue)*6+2); //max; + ps:= pointer(avalue); + pe:= ps + length(avalue); + pd:= pointer(result); + pd^:= '"'; + inc(pd); + while ps < pe do begin + ch1:= char(byte(ps^)); + pd^:= '\'; + case ps^ of + '"','\','/': begin + inc(pd); + end; + c_backspace: begin + inc(pd); + ch1:= 'b'; + end; + c_formfeed: begin + inc(pd); + ch1:= 'f'; + end; + c_linefeed: begin + inc(pd); + ch1:= 'r'; + end; + c_return: begin + inc(pd); + ch1:= 'r'; + end; + c_tab: begin + inc(pd); + ch1:= 't'; + end; + else begin + mch1:= ps^; + if (mch1 < #$20) or (mch1 > #$7f) then begin + inc(pd); + pd^:= 'u'; + inc(pd); + pd^:= charhex[(card16(mch1) and $f000) shr 12]; + inc(pd); + pd^:= charhex[(card16(mch1) and $0f00) shr 8]; + inc(pd); + pd^:= charhex[(card16(mch1) and $00f0) shr 4]; + inc(pd); + ch1:= charhex[(card16(mch1) and $000f)]; + end; + end; + end; + pd^:= ch1; + inc(pd); + inc(ps); + end; + pd^:= '"'; + inc(pd); + setlength(result,pd-pchar(pointer(result))); +end; + +const + maxindent = 32; + indents: array[0..maxindent] of char8 = ( + c_tab,c_tab,c_tab,c_tab,c_tab,c_tab,c_tab,c_tab, //8 + c_tab,c_tab,c_tab,c_tab,c_tab,c_tab,c_tab,c_tab, //16 + c_tab,c_tab,c_tab,c_tab,c_tab,c_tab,c_tab,c_tab, //24 + c_tab,c_tab,c_tab,c_tab,c_tab,c_tab,c_tab,c_tab, //32 + c_tab); + +function jsonencode(const avalue: jsonvaluety; const adest: tstream; + const aoptions: jsonencodeoptionsty = []): syserrorty; +var + error: syserrorty; + indentlevel,indentcount: int32; + hasindent: boolean; + + procedure incindent(); + begin + if hasindent then begin + inc(indentlevel); + if indentlevel <= maxindent then begin + indentcount:= indentlevel; + end; + end; + end; + + procedure decindent(); + begin + if hasindent then begin + dec(indentlevel); + if indentlevel <= maxindent then begin + indentcount:= indentlevel; + end; + end; + end; + + procedure putindent(); + begin + if (indentcount > 0) and (error = sye_ok) then begin + error:= adest.trywritebuffer(indents,indentcount); + end; + end;//putindent + + procedure put(const atext: string); + begin + if error = sye_ok then begin + error:= adest.trywritebuffer(pointer(atext)^,length(atext)); + end; + end;//put + + procedure putvalue(const avalue: jsonvaluety); + var + pi: pjsonitemty; + pv: pjsonvaluety; + pe: pointer; + begin + case avalue.kind of + jok_object: begin + put('{'+c_linefeed); + incindent(); + pi:= avalue.obj; + pe:= pi + dynarraylength(avalue.obj); + if pe > pi then begin + while error = sye_ok do begin + putindent(); + put(stringtojsonstringascii(pi^.name)+':'); + putvalue(pi^.value); + inc(pi); + if pi >= pe then begin + break; + end; + put(','+c_linefeed); + end; + end + else begin +// decindent(); //same indent as '{' + putindent(); +// incindent() + end; + put('}'); + decindent(); + end; + jok_array: begin + put('['+c_linefeed); + incindent(); + pv:= avalue.ar; + pe:= pv + dynarraylength(avalue.ar); + if pe > pv then begin + while error = sye_ok do begin + putindent(); + putvalue(pv^); + inc(pv); + if pv >= pe then begin + break; + end; + put(','+c_linefeed); + end; + end + else begin + putindent(); + end; + put(']'); + decindent(); + end; + jok_value: begin + case avalue.val.typ of + jot_null: begin + put('null'); + end; + jot_string: begin + put(stringtojsonstringascii(msestring(avalue.val.vstring))); + end; + jot_boolean: begin + if avalue.val.vboolean then begin + put('true'); + end + else begin + put('false'); + end; + end; + jot_int32: begin + put(inttostr(avalue.val.vint32)); + end; + jot_int64: begin + put(inttostr(avalue.val.vint64)); + end; + jot_flo64: begin + put(ansistring(doubletostring(avalue.val.vflo64,0,fsm_default,'.'))); + end; + end; + end; + end; + end;//putvalue + +begin + error:= sye_ok; + indentlevel:= 0; + indentcount:= 0; + hasindent:= jseo_tabindent in aoptions; + putvalue(avalue); + result:= error; +end; + +function jsondecode(const adata: string; out avalue: jsonvaluety): boolean; +const + whitechars = [' ',c_tab,c_linefeed,c_return]; +var + pc,pe: pchar; + error: boolean; + + procedure skipwhitespace(); inline; + begin + if pc < pe then begin + inc(pc); + while (pc^ in whitechars) and (pc < pe) do begin + inc(pc); + end; + end; + end;//skipwhitespace + + function getstring: msestring; + var + po1,po2,pe1: pchar; + len,capacity: int32; + i1: int32; + mstr1: msestring; + mch1: msechar; + ca1: card32; + + procedure put(); inline; + begin + if po1 <> po2 then begin + mstr1:= utf8tostring(po2,po1-po2); + i1:= len; + len:= len + length(mstr1); + if len >= capacity then begin //at least one character reserve + capacity:= 2*len+32; + setlength(result,capacity); + end; + move(pointer(mstr1)^,(pmsechar(pointer(result))+i1)^, + length(mstr1)*sizeof(msechar)); + end + else begin + if len >= capacity then begin //at least one character reserve + capacity:= 2*len+32; + setlength(result,capacity); + end; + end; + end;//put + + begin//getstring + po1:= pc; + pe1:= pe; + result:= ''; + len:= 0; + capacity:= 0; + inc(po1); //leading " + po2:= po1; + while (po1^ <> '"') and (po1 < pe1) do begin + if po1^ = '\' then begin + put(); + inc(po1); // '\' + case po1^ of + '"': mch1:= '"'; + '\': mch1:= '\'; + '/': mch1:= '/'; + 'b': mch1:= c_backspace; + 'f': mch1:= c_formfeed; + 'n': mch1:= c_linefeed; + 'r': mch1:= c_return; + 't': mch1:= c_tab; + 'u': begin + inc(po1); + if pe1-po1 > 4 then begin + if not trystrtohex(po1,4,ca1) then begin + error:= true; + break; + end; + inc(po1,3); + mch1:= msechar(card16(ca1)); + end; + end; + end; + pmsechar(pointer(result))[len]:= mch1; + inc(len); + po2:= po1 + 1; //new start + end; + inc(po1); + end; + put(); + pc:= po1; + if po1^ <> '"' then begin + error:= true; + end; + setlength(result,len); + end;//getstring + + procedure getobj(var avalue: jsonvaluety); forward; + procedure getarray(var avalue: jsonvaluety); forward; + + procedure getvalue(var avalue: jsonvaluety); + var + mstr1: msestring; + po1,po2,po3: pchar; + i1: int32; + lstr1: lstringty; + begin + skipwhitespace(); + if pc < pe then begin + avalue.kind:= jok_value; //default + case pc^ of + '{': begin + getobj(avalue); + end; + '[': begin + getarray(avalue); + end; + '"': begin + avalue.val.typ:= jot_string; + mstr1:= getstring; + stringaddref(mstr1); + avalue.val.vstring:= pointer(mstr1); + end; + else begin + po1:= pc; + po2:= po1; + while not (po2^ in whitechars+[',',']','}']) and (po2 < pe) do begin + inc(po2); + end; + pc:= po2-1; + i1:= po2-po1; + if i1 = 4 then begin + if (po1^ = 't') and ((po1+1)^ = 'r') and ((po1+2)^ = 'u') and + ((po1+3)^ = 'e') then begin + avalue.val.typ:= jot_boolean; + avalue.val.vboolean:= true; + exit; + end; + if (po1^ = 'n') and ((po1+1)^ = 'u') and ((po1+2)^ = 'l') and + ((po1+3)^ = 'l') then begin + avalue.val.typ:= jot_null; + exit; + end; + end + else begin + if (i1 = 5) and (po1^ = 'f') and ((po1+1)^ = 'a') and ((po1+2)^ = 'l') and + ((po1+3)^ = 's') and ((po1+4)^ = 'e') then begin + avalue.val.typ:= jot_boolean; + avalue.val.vboolean:= true; + exit; + end + else begin + po3:= po1; + lstr1.po:= po1; + lstr1.len:= i1; + while po3 < po2 do begin + if po3^ in ['.','e','E'] then begin + if trystrtodouble(lstr1,avalue.val.vflo64,'.') then begin + avalue.val.typ:= jot_flo64; + end + else begin + error:= true; + end; + exit; + end; + inc(po3); + end; + if trystrtoint(lstr1,avalue.val.vint32) then begin + avalue.val.typ:= jot_int32; + end + else begin + if trystrtoint64(lstr1,avalue.val.vint64) then begin + avalue.val.typ:= jot_int64; + end + else begin + error:= true; + end; + end; + end; + end; + end; + end; + end; + end;//getvalue + + procedure getarray(var avalue: jsonvaluety); + var + ar1: jsonvaluearty; + count: int32; + value: pjsonvaluety; + begin + ar1:= nil; + avalue.kind:= jok_array; + count:= 0; + skipwhitespace(); + if pc^ <> ']' then begin //else empty + dec(pc); //restore leading char + repeat + additem(ar1,typeinfo(ar1),count); + value:= @ar1[count-1]; + getvalue(value^); //calls skipwhitespace() + skipwhitespace(); + if pc^ <> ',' then begin + if pc^ <> ']' then begin + error:= true; + end; + break; + end; + until error; + end; + setlength(ar1,count); + arrayaddref(ar1); + avalue.ar:= pointer(ar1); + end;//getarray + + procedure getobj(var avalue: jsonvaluety); + var + ar1: jsonitemarty; + count: int32; + item: pjsonitemty; + begin + ar1:= nil; + avalue.kind:= jok_object; + count:= 0; + repeat + additem(ar1,typeinfo(ar1),count); + item:= @ar1[count-1]; + skipwhitespace(); //leading '{' or ',' + if pc^ <> '"' then begin + error:= true; + break; + end; + item^.name:= getstring(); + skipwhitespace(); + if pc^ = ':' then begin + getvalue(item^.value); //calls skipwhitespace() + end + else begin + error:= true; + end; + skipwhitespace(); + if pc^ <> ',' then begin + if pc^ <> '}' then begin + error:= true; + end; + break; + end; + until error; + setlength(ar1,count); + arrayaddref(ar1); + avalue.obj:= pointer(ar1); + end;//getobj + +begin + error:= false; + if adata <> '' then begin + pc:= pointer(adata); + pe:= pc+length(adata); + dec(pc); + getvalue(avalue); + if error then begin + jsonvaluefree(avalue); + avalue.kind:= jok_error; + end; + end + else begin + avalue.kind:= jok_value; + avalue.val.typ:= jot_null; + end; + result:= not error; +end; + +function jsonfindvalue(const avalue: jsonvaluety; + const names: array of msestring; + const raiseexception: boolean = false): pjsonvaluety; + //todo: use hash cache +var + pv: pjsonvaluety; + pi: pjsonitemty; + pe: pointer; + i1: int32; + mstr1: msestring; + + procedure nameerror(); + begin + pv:= nil; + if raiseexception then begin + nameserror(copy(opentodynarraym(names),0,i1+1)); + end; + end;//nameerror + +begin + pv:= @avalue; + if high(names) >= 0 then begin + for i1:= 0 to high(names) do begin + if pv^.kind <> jok_object then begin + nameerror(); + break; + end; + mstr1:= names[i1]; + pi:= pv^.obj; + pe:= pi + dynarraylength(pi); + while (pi < pe) and (pi^.name <> mstr1) do begin + inc(pi); + end; + if pi < pe then begin + pv:= @pi^.value; + end + else begin + nameerror(); + break; + end; + end; + end; + result:= pv; +end; + +function jsonfindvaluevalue(const avalue: jsonvaluety; + const names: array of msestring): pjsonvaluety; +begin + result:= jsonfindvalue(avalue,names,true); + if result^.kind <> jok_value then begin + error('No value'); + end; +end; + +function jsonasstring(const avalue: jsonvaluety; + const names: array of msestring): msestring; +var + po1: pjsonvaluety; +begin + po1:= jsonfindvaluevalue(avalue,names); + case po1^.val.typ of + jot_null: begin + result:= ''; + end; + jot_string: begin + result:= msestring(po1^.val.vstring); + end; + jot_boolean: begin + if po1^.val.vboolean then begin + result:= 'true'; + end + else begin + result:= 'false'; + end; + end; + jot_int32: begin + result:= inttostrmse(po1^.val.vint32); + end; + jot_int64: begin + result:= inttostrmse(po1^.val.vint64); + end; + jot_flo64: begin + result:= realtostrmse(po1^.val.vflo64); + end; + end; +end; + +function jsonasint32(const avalue: jsonvaluety; + const names: array of msestring): int32; +var + po1: pjsonvaluety; +begin + po1:= jsonfindvaluevalue(avalue,names); + case po1^.val.typ of + jot_int32: begin + result:= po1^.val.vint32; + end; + jot_int64: begin + result:= po1^.val.vint64; + end; + jot_flo64: begin + result:= round(po1^.val.vflo64); + end; + jot_boolean: begin + if po1^.val.vboolean then begin + result:= 1; + end + else begin + result:= 0; + end; + end; + jot_null: begin + result:= 0; + end; + jot_string: begin + if not trystrtoint(msestring(po1^.val.vstring),result) then begin + conversionerror(names); + end; + end; + end; +end; + +function jsonasint64(const avalue: jsonvaluety; + const names: array of msestring): int64; +var + po1: pjsonvaluety; +begin + po1:= jsonfindvaluevalue(avalue,names); + case po1^.val.typ of + jot_int64: begin + result:= po1^.val.vint64; + end; + jot_int32: begin + result:= po1^.val.vint32; + end; + jot_flo64: begin + result:= round(po1^.val.vflo64); + end; + jot_boolean: begin + if po1^.val.vboolean then begin + result:= 1; + end + else begin + result:= 0; + end; + end; + jot_null: begin + result:= 0; + end; + jot_string: begin + if not trystrtoint64(msestring(po1^.val.vstring),result) then begin + conversionerror(names); + end; + end; + end; +end; + +function jsonasflo64(const avalue: jsonvaluety; + const names: array of msestring): flo64; +var + po1: pjsonvaluety; +begin + po1:= jsonfindvaluevalue(avalue,names); + case po1^.val.typ of + jot_flo64: begin + result:= po1^.val.vflo64; + end; + jot_int32: begin + result:= po1^.val.vint32; + end; + jot_int64: begin + result:= po1^.val.vint64; + end; + jot_boolean: begin + if po1^.val.vboolean then begin + result:= 1; + end + else begin + result:= 0; + end; + end; + jot_null: begin + result:= 0; + end; + jot_string: begin + if not trystrtodouble(msestring(po1^.val.vstring),result,'.') then begin + conversionerror(names); + end; + end; + end; +end; + +function jsonasboolean(const avalue: jsonvaluety; + const names: array of msestring): boolean; +var + po1: pjsonvaluety; +begin + po1:= jsonfindvaluevalue(avalue,names); + case po1^.val.typ of + jot_boolean: begin + result:= po1^.val.vboolean; + end; + jot_int32: begin + result:= po1^.val.vint32 <> 0; + end; + jot_int64: begin + result:= po1^.val.vint64 <> 0; + end; + jot_flo64: begin + result:= round(po1^.val.vflo64) <> 0; + end; + jot_null: begin + result:= false; + end; + jot_string: begin + result:= msestring(po1^.val.vstring) = 'true'; + if not result and (msestring(po1^.val.vstring) <> 'false') then begin + conversionerror(names); + end; + end; + end; +end; + +procedure jsoniteratearray(const avalue: jsonvaluety; + const names: array of msestring; + var adata; const startproc: arraystartprocty; + const itemproc: arrayitemprocty); +var + po1: pjsonvaluety; + i1: int32; + pv,pe: pjsonvaluety; +begin + po1:= jsonfindvalue(avalue,names,true); + if po1^.kind <> jok_array then begin + error('No array'); + end; + pv:= po1^.ar; + i1:= dynarraylength(pv); + if startproc <> nil then begin + startproc(adata,i1); + end; + if itemproc <> nil then begin + pe:= pv + i1; + i1:= 0; + while pv < pe do begin + itemproc(adata,i1,pv^); + inc(pv); + inc(i1); + end; + end; +end; + +procedure jsoniteratearray(const avalue: jsonvaluety; + const names: array of msestring; + var adata; const startproc: arraystartmethodty; + const itemproc: arrayitemmethodty); +var + po1: pjsonvaluety; + i1: int32; + pv,pe: pjsonvaluety; +begin + po1:= jsonfindvalue(avalue,names,true); + if po1^.kind <> jok_array then begin + error('No array'); + end; + pv:= po1^.ar; + i1:= dynarraylength(pv); + if startproc <> nil then begin + startproc(adata,i1); + end; + if itemproc <> nil then begin + pe:= pv + i1; + i1:= 0; + while pv < pe do begin + itemproc(adata,i1,pv^); + inc(pv); + inc(i1); + end; + end; +end; + +procedure setvalue(var jvalue: jsonvaluety; const avalue: tvarrec); +begin + with jvalue,avalue do begin //todo: vtvariant + kind:= jok_value; + case avalue.vtype of + vtinteger: begin + val.typ:= jot_int32; + val.vint32:= vinteger; + end; + vtunicodestring: begin + val.typ:= jot_string; + msestring(val.vstring):= unicodestring(vunicodestring); + end; + vtwidestring: begin + val.typ:= jot_string; + msestring(val.vstring):= widestring(vunicodestring); + end; + vtansistring: begin + val.typ:= jot_string; + msestring(val.vstring):= widestring(vansistring); + end; + vtchar: begin + val.typ:= jot_string; + msestring(val.vstring):= msestring(vchar); + end; + vtwidechar: begin + val.typ:= jot_string; + msestring(val.vstring):= vwidechar; + end; + vtstring: begin + val.typ:= jot_string; + msestring(val.vstring):= msestring(vstring^); + end; + vtpchar: begin + val.typ:= jot_string; + msestring(val.vstring):= msestring(string(vpchar)); + end; + vtpwidechar: begin + val.typ:= jot_string; + msestring(val.vstring):= msestring(vpwidechar); + end; + vtextended: begin + val.typ:= jot_flo64; + val.vflo64:= vextended^; + end; + vtcurrency: begin + val.typ:= jot_flo64; + val.vflo64:= vcurrency^; + end; + vtboolean: begin + val.typ:= jot_boolean; + val.vboolean:= vboolean; + end; + vtint64: begin + val.typ:= jot_int64; + val.vint64:= vint64^; + end; + else begin + val.typ:= jot_null; + end; + end; + end; +end; + +function jsonadditems(var jvalue: jsonvaluety; const anames: array of msestring; + const avalues: array of const): pjsonvaluety; + //if jvalue is a null value it will be converted to object + //[nil] -> null, returns the last added item or @jvalue +var + i1,i2: int32; + pi: pjsonitemty; +begin + if high(anames) <> high(avalues) then begin + error('jsonadditems(): Name count <> value count'); + end; + if (jvalue.kind = jok_value) and (jvalue.val.typ = jot_null) then begin + jvalue.kind:= jok_object; + jvalue.obj:= nil; + end; + if jvalue.kind <> jok_object then begin + error('jsonadditems(): jvalue must be jok_object or null value'); + end; + i2:= high(avalues); + if i2 >= 0 then begin + i1:= high(jsonitemarty(jvalue.ar)); + setlength(jsonitemarty(jvalue.ar),i1+i2+2); + pi:= @jsonitemarty(jvalue.ar)[i1+1]; + for i1:= 0 to i2 do begin + pi^.name:= anames[i1]; + setvalue(pi^.value,avalues[i1]); + inc(pi); + end; + result:= @((pi-1)^.value); + end + else begin + result:= @jvalue; + end; +end; + +function jsonaddvalues(var jvalue: jsonvaluety; + const avalues: array of const): pjsonvaluety; + //if jvalue is a null value it will be converted to array + //[nil] -> null, returns the last added item or @jvalue +var + i1,i2: int32; + pv: pjsonvaluety; +begin + if (jvalue.kind = jok_value) and (jvalue.val.typ = jot_null) then begin + jvalue.kind:= jok_array; + jvalue.ar:= nil; + end; + if jvalue.kind <> jok_array then begin + error('jsonaddvalues(): jvalue must be jok_object or null value'); + end; + i2:= high(avalues); + if i2 >= 0 then begin + i1:= high(jsonvaluearty(jvalue.ar)); + setlength(jsonvaluearty(jvalue.ar),i1+i2+2); + pv:= @jsonvaluearty(jvalue.ar)[i1+1]; + for i1:= 0 to i2 do begin + setvalue(pv^,avalues[i1]); + inc(pv); + end; + result:= pv-1; + end + else begin + result:= @jvalue; + end; +end; + +{$implicitexceptions on} + +{ tjsoncontainer } + +constructor tjsoncontainer.create(const avalue: jsonvaluety); +begin + fvalue:= avalue; +end; + +class function tjsoncontainer.trycreate(out ainstance: tjsoncontainer; + const adata: string): boolean; +var + val1: jsonvaluety; +begin + result:= jsondecode(adata,val1); + if result then begin + ainstance:= tjsoncontainer.create(val1); + ainstance.fvalue:= val1; + end; +end; + +constructor tjsoncontainer.create(const adata: string); +begin + if not jsondecode(adata,fvalue) then begin + error('Invalid json data'); + end; +end; + +destructor tjsoncontainer.destroy; +begin + jsonvaluefree(fvalue); +end; + +function tjsoncontainer.findvalue(const names: array of msestring; + const raiseexception: boolean = false): pjsonvaluety; + //todo: use hash cache +begin + result:= jsonfindvalue(fvalue,names,raiseexception); +end; + +function tjsoncontainer.findvaluevalue( + const names: array of msestring): pjsonvaluety; +begin + result:= jsonfindvaluevalue(fvalue,names); +end; + +function tjsoncontainer.asstring(const names: array of msestring): msestring; +begin + result:= jsonasstring(fvalue,names); +end; + +function tjsoncontainer.asint32(const names: array of msestring): int32; +begin + result:= jsonasint32(fvalue,names); +end; + +function tjsoncontainer.asint64(const names: array of msestring): int64; +begin + result:= jsonasint64(fvalue,names); +end; + +function tjsoncontainer.asflo64(const names: array of msestring): flo64; +begin + result:= jsonasflo64(fvalue,names); +end; + +function tjsoncontainer.asboolean(const names: array of msestring): boolean; +begin + result:= jsonasboolean(fvalue,names); +end; + +procedure tjsoncontainer.iteratearray(const names: array of msestring; + var adata; const startproc: arraystartprocty; + const itemproc: arrayitemprocty); +begin + jsoniteratearray(fvalue,names,adata,startproc,itemproc); +end; + +procedure tjsoncontainer.iteratearray(const names: array of msestring; + var adata; const startproc: arraystartmethodty; + const itemproc: arrayitemmethodty); +begin + jsoniteratearray(fvalue,names,adata,startproc,itemproc); +end; + +end. + diff --git a/mseide-msegui/lib/common/ifi/msesockets.pas b/mseide-msegui/lib/common/ifi/msesockets.pas new file mode 100644 index 0000000..3779352 --- /dev/null +++ b/mseide-msegui/lib/common/ifi/msesockets.pas @@ -0,0 +1,815 @@ +{ MSEgui Copyright (c) 2007-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msesockets; +//todo: separate comm base code and sockets + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +interface +uses + classes,mclasses,mseglob,mseclasses,msesystypes,msesys,msestrings,msepipestream, + mseapplication,msethread,mseevent,msecryptio,msetypes,msesercomm; + +const + defaultmaxconnections = 16; + +type + + tsocketreader = class(tcommreader) + protected + procedure settimeoutms(const avalue: integer); override; + procedure sethandle(value: integer); override; + function internalread(var buf; const acount: integer; out readcount: integer; + const nonblocked: boolean = false): boolean; override; + procedure closehandle(const ahandle: integer); override; + public + constructor create(const aowner: tcustomcommpipes); + end; + + tsocketwriter = class(tcommwriter) + protected + procedure settimeoutms(const avalue: integer); override; + procedure closehandle(const ahandle: integer); override; + function internalwrite(const buffer; count: longint): longint; override; + end; + + tcustomsocketclient = class; + + tcustomsocketpipes = class(tcustomcommpipes) + protected + procedure createpipes; override; + end; + + tsocketpipes = class(tcustomsocketpipes) + published + property optionsreader; + property overloadsleepus; + property oninputavailable; + property oncommbroken; + end; +{ + tclientsocketpipes = class(tsocketpipes) + protected + procedure doafterconnect; override; + end; + + + tserversocketpipes = class(tcustomsocketpipes) + protected + procedure doafterconnect; override; + end; +} + + socketpipesarty = array of tsocketpipes; + tcustomsocketserver = class; + + tcustomsocketcomp = class(tcustomcommcomp) + end; + + tsocketcomp = class(tcustomsocketcomp) + published + property active; + property activator; + property cryptoio; + property onbeforeconnect; + property onafterconnect; + property onbeforedisconnect; + property onafterdisconnect; + end; + + tcustomurlsocketcomp = class(tcustomsocketcomp) + private + fkind: socketkindty; + furl: msestring; + fport: word; + procedure seturl(const avalue: filenamety); + protected + function getsockaddr: socketaddrty; + property kind: socketkindty read fkind write fkind default sok_local; + property url: filenamety read furl write seturl; + property port: word read fport write fport default 0; + end; + + turlsocketcomp = class(tcustomurlsocketcomp) + published + property active; + property activator; + property cryptoio; + property onbeforeconnect; + property onafterconnect; + property onbeforedisconnect; + property onafterdisconnect; + + property kind; + property url; + property port; + end; + + tcustomsocketclient = class(tcustomurlsocketcomp) + private + procedure setpipes(const avalue: tsocketpipes); + protected + fpipes: tsocketpipes; + procedure internalconnect; override; + procedure internaldisconnect; override; + procedure closepipes(const sender: tcustomcommpipes); override; + procedure doasyncevent(var atag: integer); override; + function trywritedata(const adata: string): syserrorty; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property pipes: tsocketpipes read fpipes write setpipes; + end; + + tsocketclient = class(tcustomsocketclient) + published + property pipes; + property active; + property activator; + property cryptoio; + property onbeforeconnect; + property onafterconnect; + property onbeforedisconnect; + property onafterdisconnect; + + property kind; + property url; + property port; + end; + + tsocketstdio = class(tsocketcomp) + private + procedure setpipes(const avalue: tsocketpipes); + function getcryptoiokind: cryptoiokindty; + procedure setcryptoiokind(const avalue: cryptoiokindty); + protected + fpipes: tsocketpipes; + procedure internalconnect; override; + procedure internaldisconnect; override; + procedure closepipes(const sender: tcustomcommpipes); override; + procedure doasyncevent(var atag: integer); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property pipes: tsocketpipes read fpipes write setpipes; + property cryptiokind: cryptoiokindty read getcryptoiokind + write setcryptoiokind default cyk_none; + end; + + + socketaccepteventty = procedure(const sender: tcustomsocketserver; + const asocket: integer; + const addr: socketaddrty; var accept: boolean) of object; + socketserverconnecteventty = procedure(const sender: tcustomsocketserver; + const apipes: tcustomcommpipes) of object; + + socketserverstatety = (sss_closepipespending); + socketserverstatesty = set of socketserverstatety; + + tcustomsocketserver = class(tcustomurlsocketcomp) + private + fstate: socketserverstatesty; + fthread: tmsethread; + fmaxconnections: integer; + faccepttimeoutms: integer; + fonaccept: socketaccepteventty; + fonbeforechconnect: socketserverconnecteventty; + fonafterchconnect: socketserverconnecteventty; + fonbeforechdisconnect: socketserverconnecteventty; + fonafterchdisconnect: socketserverconnecteventty; + fpipes: socketpipesarty; + foverloadsleepus: integer; + foninputavailable: commpipeseventty; + fonsocketbroken: commpipeseventty; + fconnectioncount: integer; + foptionsreader: pipereaderoptionsty; + frxtimeoutms: integer; + ftxtimeoutms: integer; + function execthread(thread: tmsethread): integer; + protected + procedure internaldisconnect; override; + procedure doclosepipes; + procedure closepipes(const sender: tcustomcommpipes); override; + procedure doasyncevent(var atag: integer); override; + procedure doafterchconnect(const sender: tcustomcommpipes); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure runhandlerapp(const asocket: integer; const acommandline: filenamety); + property connectioncount: integer read fconnectioncount; + published + property maxconnections: integer read fmaxconnections write fmaxconnections + default defaultmaxconnections; + property accepttimeoutms: integer read faccepttimeoutms + write faccepttimeoutms default 0; + property rxtimeoutms: integer read frxtimeoutms write frxtimeoutms default 0; + property txtimeoutms: integer read ftxtimeoutms write ftxtimeoutms default 0; + + property onaccept: socketaccepteventty read fonaccept write fonaccept; + property onbeforechconnect: socketserverconnecteventty read fonbeforechconnect + write fonbeforechconnect; + property onafterchconnect: socketserverconnecteventty read fonafterchconnect + write fonafterchconnect; + property onbeforechdisconnect: socketserverconnecteventty read fonbeforechdisconnect + write fonbeforechdisconnect; + property onafterchdisconnect: socketserverconnecteventty read fonafterchdisconnect + write fonafterchdisconnect; + property overloadsleepus: integer read foverloadsleepus + write foverloadsleepus default -1; + //checks application.checkoverload before calling oninputavaliable + //if >= 0 + property optionsreader: pipereaderoptionsty read foptionsreader + write foptionsreader default []; + property oninputavailable: commpipeseventty read foninputavailable + write foninputavailable; + property onsocketbroken: commpipeseventty read fonsocketbroken + write fonsocketbroken; + end; + + tsocketserver = class(tcustomsocketserver) + protected + procedure internalconnect; override; + published + property active; + property activator; + property cryptoio; + property onbeforeconnect; + property onafterconnect; + property onbeforedisconnect; + property onafterdisconnect; + + property kind; + property url; + property port; + end; + + tsocketserverstdio = class(tcustomsocketserver) + protected + procedure internalconnect; override; + public + constructor create(aowner: tcomponent); override; + published + property active; + end; + +procedure checksyserror(const aresult: integer); + +procedure socketerror(const error: syserrorty; const text: string = ''); + +implementation +uses + msefileutils,msesysintf,sysutils,msestream,mseprocutils,msesysutils, + msesocketintf,msearrayutils; + +type + tcustompipes1 = class(tcustomcommpipes); + +procedure socketerror(const error: syserrorty; const text: string = ''); +begin + case error of + sye_ok: begin + end; + sye_sockaddr: begin + raise esys.create(error,text+soc_getaddrerrortext(mselasterror)); + end; + sye_socket: begin + raise esys.create(error,text+soc_geterrortext(mselasterror)); + end; + else begin + syserror(error,msestring(text)); + end; + end; +end; + +procedure checksyserror(const aresult: integer); +begin + if aresult <> 0 then begin + syserror(syelasterror); + end; +end; + +{ tcustomurlsocketcomp} + +procedure tcustomurlsocketcomp.seturl(const avalue: filenamety); +begin + checkinactive; + furl:= avalue; +end; + +function tcustomurlsocketcomp.getsockaddr: socketaddrty; +begin + with result do begin + kind:= fkind; + port:= fport; + fillchar(platformdata,sizeof(platformdata),0); + size:= 0; + url:= furl; + case fkind of + sok_local: begin + end; + sok_inet,sok_inet6: begin + socketerror(soc_urltoaddr(result)); + end; + end; + end; +end; + +{ tsocketstdio } + +constructor tsocketstdio.create(aowner: tcomponent); +begin + if fpipes = nil then begin + fpipes:= tsocketpipes.create(self,cyk_none); + end; + inherited; +end; + +destructor tsocketstdio.destroy; +begin + fpipes.free; + inherited; +end; + +procedure tsocketstdio.setpipes(const avalue: tsocketpipes); +begin + fpipes.assign(avalue); +end; + +procedure tsocketstdio.internalconnect; +begin + fpipes.tx.handle:= sys_stdout; + fpipes.rx.handle:= sys_stdin; + factive:= true; +end; + +procedure tsocketstdio.internaldisconnect; +begin + fpipes.handle:= invalidfilehandle; + inherited +end; + +procedure tsocketstdio.closepipes(const sender: tcustomcommpipes); +begin + asyncevent(closepipestag); +end; + +procedure tsocketstdio.doasyncevent(var atag: integer); +begin + if atag = closepipestag then begin + disconnect; + end; +end; + +function tsocketstdio.getcryptoiokind: cryptoiokindty; +begin + result:= fpipes.fcryptoioinfo.kind; +end; + +procedure tsocketstdio.setcryptoiokind(const avalue: cryptoiokindty); +begin + fpipes.fcryptoioinfo.kind:= avalue; +end; + +{ tclientsocketpipes } +{ +procedure tclientsocketpipes.doafterconnect; +begin + if fcryptioinfo.handler <> nil then begin + ftx.fcrypt:= @fcryptioinfo; + frx.fcrypt:= @fcryptioinfo; + fcryptioinfo.handler.link(ftx.handle,frx.handle,fcryptioinfo); + cryptconnect(fcryptioinfo,frx.timeoutms); + end; + inherited; +end; +} +{ tcustomsocketclient } + +constructor tcustomsocketclient.create(aowner: tcomponent); +begin + if fpipes = nil then begin + fpipes:= tsocketpipes.create(self,cyk_client); + end; + inherited; +end; + +destructor tcustomsocketclient.destroy; +begin + fpipes.free; + inherited; +end; + +procedure tcustomsocketclient.setpipes(const avalue: tsocketpipes); +begin + fpipes.assign(avalue); +end; + +procedure tcustomsocketclient.internalconnect; +begin + socketerror(soc_open(fkind,true,fhandle)); + try + socketerror(soc_connect(fhandle,getsockaddr,fpipes.tx.timeoutms)); + except + sys_closefile(fhandle); + fhandle:= invalidfilehandle; + raise; + end; + try + fpipes.onafterconnect:= {$ifdef FPC}@{$endif}doafterconnect; + fpipes.setcryptoio(fcryptoio); + fpipes.handle:= fhandle; + except + internaldisconnect; + raise; + end; + factive:= true; +end; + +procedure tcustomsocketclient.internaldisconnect; +begin + fpipes.handle:= invalidfilehandle; + inherited +end; + +procedure tcustomsocketclient.closepipes(const sender: tcustomcommpipes); +begin + if (csdestroying in componentstate) and application.ismainthread then begin + disconnect; + end + else begin + asyncevent(closepipestag); + end; +end; + +procedure tcustomsocketclient.doasyncevent(var atag: integer); +begin + if atag = closepipestag then begin + disconnect; + end; +end; + +function tcustomsocketclient.trywritedata(const adata: string): syserrorty; +begin + result:= fpipes.tx.trywritebuffer(pointer(adata)^,length(adata)); +end; + +{ tserversocketpipes } +{ +procedure tserversocketpipes.doafterconnect; +begin + if fcryptioinfo.handler <> nil then begin + ftx.fcrypt:= @fcryptioinfo; + frx.fcrypt:= @fcryptioinfo; + fcryptioinfo.handler.link(ftx.handle,frx.handle,fcryptioinfo); + cryptaccept(fcryptioinfo,frx.timeoutms); + end; + inherited; +end; +} +{ tcustomsocketserver } + +constructor tcustomsocketserver.create(aowner: tcomponent); +begin + fmaxconnections:= defaultmaxconnections; + foverloadsleepus:= -1; + inherited; +end; + +destructor tcustomsocketserver.destroy; +var + int1: integer; +begin + disconnect; + inherited; + freeandnil(fthread); + for int1:= 0 to high(fpipes) do begin + fpipes[int1].free; + end; +end; + +procedure tcustomsocketserver.doafterchconnect(const sender: tcustomcommpipes); +begin + if canevent(tmethod(fonafterchconnect)) then begin + application.lock; + try + fonafterchconnect(self,sender); + finally + application.unlock; + end; + end; +end; + +function tcustomsocketserver.execthread(thread: tmsethread): integer; +var + addr: socketaddrty; + conn: integer; + bo1: boolean; + int1,int2: integer; + err: syserrorty; +// cryptioinfo: cryptioinfoty; +begin +{$ifdef mse_debugsockets} + debugout(self,'server execthread'); +{$endif} + result:= 0; + addr.kind:= fkind; + addr.size:= sizeof(addr.platformdata); + while not thread.terminated do begin + err:= soc_accept(fhandle,true,conn,addr,0); +{$ifdef mse_debugsockets} + debugout(self,'accept error:' + inttostr(ord(err))); +{$endif} + if not thread.terminated then begin + if err = sye_ok then begin + try + application.lock; + try + if canevent(tmethod(fonaccept)) then begin + bo1:= false; + fonaccept(self,conn,addr,bo1); + end + else begin + bo1:= true; + end; + if bo1 then begin + int2:= -1; + for int1:= 0 to high(fpipes) do begin + if fpipes[int1] = nil then begin + int2:= int1; + break; + end; + end; + if int2 < 0 then begin + setlength(fpipes,high(fpipes)+2); + int2:= high(fpipes); + end; + fpipes[int2]:= tsocketpipes.create(self,cyk_server); + inc(fconnectioncount); + with fpipes[int2] do begin + rx.timeoutms:= frxtimeoutms; + tx.timeoutms:= ftxtimeoutms; + optionsreader:= self.foptionsreader; + overloadsleepus:= self.foverloadsleepus; + oninputavailable:= self.foninputavailable; + onsocketbroken:= self.fonsocketbroken; + onafterconnect:= {$ifdef FPC}@{$endif}self.doafterchconnect; + if canevent(tmethod(fonbeforechconnect)) then begin + fonbeforechconnect(self,fpipes[int2]); + end; + setcryptoio(fcryptoio); + handle:= conn; + end; + end + else begin + // sys_shutdownsocket(conn,ssk_both); + soc_close(conn); + end; + finally + application.unlock; + end; + except + application.handleexception(self); + end; + end + else begin + if (err <> sye_timeout) or (fconnectioncount = 0) then begin + asyncevent(closeconnectiontag); + break; + end; + end; + end; + {$ifdef mse_debugsockets} + debugout(self,'server exitthread'); + {$endif} + end; +end; + +procedure tcustomsocketserver.internaldisconnect; +var + int1: integer; +begin +{$ifdef mse_debugsockets} + debugout(self,'internaldisconnect'); +{$endif} + if fthread <> nil then begin + fthread.terminate; + end; + for int1:= 0 to high(fpipes) do begin + if fpipes[int1] <> nil then begin + try + closepipes(fpipes[int1]); + except + end; + end; + end; + if fhandle <> invalidfilehandle then begin + soc_shutdown(fhandle,ssk_rx); + soc_close(fhandle); + end; + if fthread <> nil then begin + application.waitforthread(fthread); + end; + freeandnil(fthread); +// soc_close(fhandle); + inherited; +end; + +procedure tcustomsocketserver.doclosepipes; +var + int1: integer; +begin + for int1:= 0 to high(fpipes) do begin + if (fpipes[int1] <> nil) and + (fpipes[int1].tx.handle = invalidfilehandle) then begin + fpipes[int1].release; + if not (csdestroying in application.componentstate) and + not application.terminated then begin + fpipes[int1]:= nil; //destroying can be delayed + end; + end; + end; +end; + +procedure tcustomsocketserver.closepipes(const sender: tcustomcommpipes); +begin + if (sender.rx.handle <> invalidfilehandle) or + (cps_detached in tcustompipes1(sender).fstate) then begin + exclude(tcustompipes1(sender).fstate,cps_detached); + if canevent(tmethod(fonbeforechdisconnect)) then begin + try + fonbeforechdisconnect(self,sender); + except + application.handleexception(self); + end; + end; + sender.tx.handle:= invalidfilehandle; + dec(fconnectioncount); + if (csdestroying in componentstate) and application.ismainthread then begin + doclosepipes; + end + else begin + if not (sss_closepipespending in fstate) then begin + include(fstate,sss_closepipespending); + asyncevent(closepipestag); + end; + end; + if canevent(tmethod(fonafterchdisconnect)) then begin + fonafterchdisconnect(self,sender); + end; + end; +end; + +procedure tcustomsocketserver.doasyncevent(var atag: integer); +begin + case atag of + closepipestag: begin + exclude(fstate,sss_closepipespending); + doclosepipes; + end; + closeconnectiontag: begin + active:= false; + end; + end; +end; + +procedure tcustomsocketserver.runhandlerapp(const asocket: integer; + const acommandline: filenamety); +var + int1,int2: integer; +begin + syserror(sys_dup(asocket,int1)); + syserror(sys_dup(asocket,int2)); + execmse3(acommandline,@int1,@int2); +end; + +{ tsocketserver } + +procedure tsocketserver.internalconnect; +begin + if not (csdesigning in componentstate) then begin + syserror(soc_open(fkind,true,fhandle)); + try + syserror(soc_bind(fhandle,getsockaddr)); + except + sys_closefile(fhandle); + fhandle:= invalidfilehandle; + raise; + end; + try + syserror(soc_listen(fhandle,fmaxconnections)); + except + internaldisconnect; + raise; + end; + factive:= true; + fthread:= tmsethread.create({$ifdef FPC}@{$endif}execthread); + end; + factive:= true; +end; + +{ tsocketserverstdio } + +constructor tsocketserverstdio.create(aowner: tcomponent); +begin + inherited; + fkind:= sok_inet; +end; + +procedure tsocketserverstdio.internalconnect; +begin + if not (csdesigning in componentstate) then begin + syserror(sys_dup(sys_stdin,fhandle)); + factive:= true; + fthread:= tmsethread.create({$ifdef FPC}@{$endif}execthread); + end + else begin + factive:= true; + end; +end; + +{ tsocketreader } + +constructor tsocketreader.create(const aowner: tcustomcommpipes); +begin + inherited; + fstate:= fstate + [tss_nosigio,tss_unblocked]; +end; + +procedure tsocketreader.sethandle(value: integer); +begin + if value <> invalidfilehandle then begin + soc_setnonblock(value,true); + end; + inherited; +end; + +function tsocketreader.internalread(var buf; const acount: integer; + out readcount: integer; + const nonblocked: boolean = false): boolean; +var + int1: integer; +begin + if nonblocked then begin + int1:= -1; + end + else begin + int1:= 0; + end; + soc_read(handle,@buf,acount,readcount,int1); + result:= readcount >= 0; + if not result then begin + readcount:= 0; + end; +end; + +procedure tsocketreader.closehandle(const ahandle: integer); +begin + soc_shutdown(ahandle,ssk_rx); + inherited; +end; + +procedure tsocketreader.settimeoutms(const avalue: integer); +begin + inherited; + if handle <> invalidfilehandle then begin + soc_setrxtimeout(handle,avalue); + end; +end; + +{ tsocketwriter } + +procedure tsocketwriter.closehandle(const ahandle: integer); +begin +// sys_shutdownsocket(ahandle,ssk_tx); + inherited; +end; + +procedure tsocketwriter.settimeoutms(const avalue: integer); +begin + inherited; + if handle <> invalidfilehandle then begin + soc_settxtimeout(handle,avalue); + end; +end; + +function tsocketwriter.internalwrite(const buffer; count: longint): longint; +begin + soc_write(handle,@buffer,count,result,0); +end; + +{ tcustomsocketpipes } + +procedure tcustomsocketpipes.createpipes; +begin + frx:= tsocketreader.create(self); + ftx:= tsocketwriter.create(self); +end; + +end. diff --git a/mseide-msegui/lib/common/image/mseformatbmpicoread.pas b/mseide-msegui/lib/common/image/mseformatbmpicoread.pas new file mode 100644 index 0000000..0ca8be0 --- /dev/null +++ b/mseide-msegui/lib/common/image/mseformatbmpicoread.pas @@ -0,0 +1,505 @@ +{ MSEgui Copyright (c) 2006-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseformatbmpicoread; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + bmplabel = 'bmp'; + icolabel = 'ico'; +procedure registerformat; + +//param for ico: [index: integer] + +implementation +uses + classes,mclasses,msebitmap,msebits,msegraphutils,mseguiintf,msegraphicstream, + msestockobjects,msegraphics; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tbitmap1 = class(tbitmap); + +const + RT_BITMAP = PChar(2); + +type + DWORD = longword; + BITMAPFILEHEADERty = packed record + bfType: Word; + bfSize: DWORD; + bfReserved1: Word; + bfReserved2: Word; + bfOffBits: DWORD; + end; + BITMAPINFOHEADERty = packed record + biSize: DWORD; + biWidth: Longint; + biHeight: Longint; + biPlanes: Word; + biBitCount: Word; + biCompression: DWORD; + biSizeImage: DWORD; + biXPelsPerMeter: Longint; + biYPelsPerMeter: Longint; + biClrUsed: DWORD; + biClrImportant: DWORD; + end; + RGBQUADty = packed record + rgbBlue: Byte; + rgbGreen: Byte; + rgbRed: Byte; + rgbReserved: Byte; + end; + ICONHEADERty = packed record + idReserved: WORD; // Reserved (must be 0) + idType: WORD; // Resource Type (1 for icons) + idCount: WORD; // How many images? + //ICONDIRENTRY idEntries[1]; // An entry for each image (idCount of 'em) + end; + ICONDIRENTRYty = packed record + bWidth: BYTE; // Width, in pixels, of the image + bHeight: BYTE; // Height, in pixels, of the image + bColorCount: BYTE; // Number of colors in image (0 if >=8bpp) + bReserved: BYTE; // Reserved ( must be 0) + wPlanes: WORD; // Color Planes + wBitCount: WORD; // Bits per pixel + dwBytesInRes: DWORD; // How many bytes in this resource? + dwImageOffset: DWORD; // Where in the file is this image? + end; + ICONIMAGEty = packed record + icHeader: BITMAPINFOHEADERty; // DIB header +// RGBQUAD icColors[1]; // Color table +// BYTE icXOR[1]; // DIB bits for XOR mask +// BYTE icAND[1]; // DIB bits for AND mask + end; + + +const + BM = $4d42; + BI_RGB = 0; + BI_RLE8 = 1; + BI_RLE4 = 2; + BI_BITFIELDS = 3; + +function readbmp(stream: tformatstream; bfoffbits: integer; dest: tbitmap; + icomode: boolean = false): boolean; + //bfoffbits <= 0 -> image at colormapend - bfoffbits + //true if biheight < 0 +var + infoheader: bitmapinfoheaderty; + palette: array of longword; + pixdata: array of byte; + rowbytelength,paddingcount: integer; + int1,int2: integer; + start,stop,step: integer; + po1: pbyte; + po2: plongword; + wo1: word; + +begin + stream.read(infoheader,sizeof(infoheader)); + with infoheader do begin + if icomode then begin + biheight:= biheight div 2; + end; + result:= biheight < 0; + if result then begin + biheight:= -biheight; + start:= 0; + stop:= biheight; + step:= 1; + end + else begin + start:= biheight-1; + stop:= -1; + step:= -1; + end; + if bicompression <> bi_rgb then begin + stream.formaterror; + end; + if bisize > sizeof(infoheader) then begin + stream.seek(infoheader.bisize-sizeof(infoheader)); + end; + if (bibitcount > 32) or (biclrused > bits[bibitcount]) then begin + stream.formaterror; + end; + if (biclrused = 0) and (bibitcount <= 8) then begin + biclrused:= bits[bibitcount]; + end; + if bfoffbits <= 0 then begin + bfoffbits:= stream.pos + integer(biclrused) * sizeof(longword) - bfoffbits; + end; + paddingcount:= ((biwidth * bibitcount+7) div 8); //bytecount + rowbytelength:= ((paddingcount+3) div 4) * 4; //4 byte boundaries + paddingcount:= rowbytelength - paddingcount; + setlength(pixdata,rowbytelength*biheight); + dest.clear; + if bibitcount = 1 then begin + dest.kind:= bmk_mono; + end + else begin + dest.kind:= bmk_rgb; + end; + dest.size:= makesize(biwidth,biheight); + int1:= start; + po1:= @pixdata[0]; + case bibitcount of + 16: begin + stream.pos:= bfoffbits; + stream.read(pixdata[0],length(pixdata)); + while int1 <> stop do begin + po2:= dest.scanline[int1]; + for int2:= 0 to biwidth - 1 do begin + wo1:= pword(po1)^; + pbyte(po2)^:= (wo1 and $7c00) shr 7; //red + inc(pbyte(po2)); + pbyte(po2)^:= (wo1 and $3e0) shr 2; //green + inc(pbyte(po2)); + pbyte(po2)^:= (wo1 and $1f) shl 3; //blue + inc(pbyte(po2)); + pbyte(po2)^:= 0; + inc(po1,2); + end; + inc(po1,paddingcount); + inc(int1,step); + end; + end; + 32: begin + stream.Pos:= bfoffbits; + while int1 <> stop do begin + stream.read(dest.scanline[int1]^,biwidth*4); + inc(int1,step); + end; + end; + 24: begin + stream.pos:= bfoffbits; + stream.read(pixdata[0],length(pixdata)); + while int1 <> stop do begin + po2:= dest.scanline[int1]; + for int2:= 0 to biwidth - 1 do begin + po2^:= plongword(po1)^ and $ffffff; + inc(po1,3); + inc(po2) + end; + inc(po1,paddingcount); + inc(int1,step); + end; + end; + 1: begin + stream.pos:= bfoffbits; + stream.read(pixdata[0],length(pixdata)); + while int1 <> stop do begin + po2:= dest.scanline[int1]; + for int2:= 0 to rowbytelength - 1 do begin + pbyte(po2)^:= not bitreverse[po1^]; + inc(pbyte(po2)); + inc(po1); + end; + inc(int1,step); + end; + end; + 4,8: begin + setlength(palette,bits[bibitcount]); + stream.read(palette[0],biclrused*sizeof(longword)); +// for int2:= 0 to biclrused - 1 do begin +// swaprgb1(palette[int2]); +// end; + stream.pos:= bfoffbits; + stream.read(pixdata[0],length(pixdata)); + if bibitcount = 4 then begin + if odd(biwidth) then begin + inc(paddingcount); + end; + while int1 <> stop do begin + po2:= dest.scanline[int1]; + for int2:= 0 to biwidth - 1 do begin + if not odd(int2) then begin + po2^:= palette[po1^ shr 4]; + end + else begin + po2^:= palette[po1^ and $0f]; + inc(po1); + end; + inc(po2); + end; + inc(po1,paddingcount); + inc(int1,step); + end; + end + else begin + while int1 <> stop do begin + po2:= dest.scanline[int1]; + for int2:= 0 to biwidth - 1 do begin + po2^:= palette[po1^]; + inc(po2); + inc(po1); + end; + inc(po1,paddingcount); + inc(int1,step); + end; + end; + end; + else begin + stream.formaterror; + end; + end; + end; +end; + +function readimagebmp(source: tstream; dest: tbitmap): boolean; +var + stream: tformatstream; + fileheader: bitmapfileheaderty; + +begin + result:= false; + stream:= tformatstream.create(source,'bmp'); + try + stream.read(fileheader,sizeof(fileheader)); + if (fileheader.bftype <> BM) then begin + exit; +// stream.formaterror; + end; + dest.clear; + if dest is tmaskedbitmap then begin + tmaskedbitmap(dest).masked:= false; + end; + dest.kind:= bmk_rgb; +// dest.monochrome:= false; + readbmp(stream,fileheader.bfoffbits,dest); + finally + stream.free; + end; + result:= true; +end; + +function readimageico1(source: tstream; dest1: tmaskedbitmap; + dest2: timagelist; index: integer): boolean; +var + stream: tformatstream; + iconheader: iconheaderty; + icondir: array of icondirentryty; + + procedure readicobmp(index: integer; dest: tmaskedbitmap); + var + bo1: boolean; + po1: pbyte; + po2: plongword; + int1,int3,int4: integer; + begin + dest.clear; +// dest.monochrome:= false; + dest.kind:= bmk_rgb; + with icondir[index] do begin + stream.Pos:= dwimageoffset; + bo1:= readbmp(stream,0,dest,true); + int3:= ((bwidth+31) div 32)*4; + int4:=int3*bheight; + getmem(po1,int4); + stream.read(po1^,int4); + po2:= pointer(po1); + for int1:= 0 to int4 div 4 - 1 do begin + po2^:= not po2^; + inc(po2); + end; + tbitmap1(dest.mask).handle:= gui_createbitmapfromdata(makesize(bwidth,bheight), + po1,true,true,not bo1); + freemem(po1); + end; + end; + +var + size1: sizety; + mono: boolean; + int1: integer; + buffer: tmaskedbitmap; + +begin + result:= false; + stream:= tformatstream.create(source,'ico'); + try + stream.Read(iconheader,sizeof(iconheader)); + with iconheader do begin + if (idtype <> 1) or (idcount <= index) then begin + exit; +// stream.formaterror; + end; + setlength(icondir,idcount); + stream.Read(icondir[0],length(icondir)*sizeof(icondirentryty)); + if dest1 <> nil then begin + readicobmp(index,dest1); + end + else begin + if dest2 <> nil then begin + size1:= nullsize; + mono:= true; + for int1:= 0 to idcount - 1 do begin + with icondir[int1] do begin + if bwidth > size1.cx then begin + size1.cx:= bwidth; + end; + if bheight > size1.cy then begin + size1.cy:= bheight; + end; + if bcolorcount <> 1 then begin + mono:= false; + end; + end; + end; + with dest2 do begin + size:= size1; + if mono then begin + kind:= bmk_mono; + end + else begin + kind:= bmk_rgb; + end; +// monochrome:= mono; + masked:= true; + count:= idcount; + end; + if mono then begin + buffer:= tmaskedbitmap.create(bmk_mono); + end + else begin + buffer:= tmaskedbitmap.create(bmk_rgb); + end; + try + for int1:= 0 to idcount - 1 do begin + readicobmp(int1,buffer); + dest2.setimage(int1,buffer); + end; + finally + buffer.free; + end; + end; + end; + end; + finally + stream.free; + end; + result:= true; +end; + +procedure readimageico(source: tstream; dest: tmaskedbitmap; index: integer = 0); + overload; +begin + readimageico1(source,dest,nil,index); +end; + +procedure readimageico(source: tstream; dest: timagelist); overload; +begin + readimageico1(source,nil,dest,0); +end; + +procedure readimage(source: tstream; dest: tmaskedbitmap); +var + posbefore: integer; +begin + posbefore:= source.Position; + try + readimagebmp(source,dest); + dest.masked:= false; + except + on egraphicformat do begin + source.Position:= posbefore; + readimageico(source,dest); + end; + else raise; + end; +end; + +function readgraphicbmp(const asource: tstream; + const dest: tobject; var format: string; + const params: array of const): boolean; +begin + result:= false; + if dest is tbitmap then begin + result:= readimagebmp(asource,tbitmap(dest)); + if result then begin + tbitmap(dest).change; + end; + end + else begin + if dest is timagelist then begin + result:= readimagebmp(asource,timagelist(dest).bitmap); + if result then begin + timagelist(dest).bitmap.change; + end; + end + else begin + result:= false; + end; + end; +end; + +function readgraphicico(const asource: tstream; + const dest: tobject; var format: string; + const params: array of const): boolean; +var + int1: integer; +begin + result:= false; + if dest is tmaskedbitmap then begin + with tmaskedbitmap(dest) do begin + int1:= -1; + if (high(params) >= 0) then begin + with tvarrec(params[0]) do begin + if vtype = vtinteger then begin + int1:= vinteger; + end; + end; + end; + if int1 < 0 then begin + int1:= 0; + end; + result:= readimageico1(asource,tmaskedbitmap(dest),nil,int1); + if result then begin + change; + end; + end; + end + else begin + if dest is timagelist then begin + result:= readimageico1(asource,nil,timagelist(dest),0); + end + else begin + result:= false; + end; + end; +end; + +procedure registerformat; +begin + registergraphicformat(bmplabel,{$ifdef FPC}@{$endif}readgraphicbmp,nil, + stockobjects.captions[sc_MS_Bitmap],['*.bmp']); + registergraphicformat(icolabel,{$ifdef FPC}@{$endif}readgraphicico,nil, + stockobjects.captions[sc_MS_Icon],['*.ico']); +end; + +initialization + registerformat(); +end. diff --git a/mseide-msegui/lib/common/image/mseformatjpgread.pas b/mseide-msegui/lib/common/image/mseformatjpgread.pas new file mode 100644 index 0000000..b0fef34 --- /dev/null +++ b/mseide-msegui/lib/common/image/mseformatjpgread.pas @@ -0,0 +1,70 @@ +{ MSEgui Copyright (c) 2006-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseformatjpgread; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +const + jpglabel = 'jpeg'; +procedure registerformat; + +implementation +uses + classes,mclasses,msegraphics,msebitmap,fpreadjpeg,msegraphicstream, + msestockobjects,msestream; + +type + tmsefpreaderjpeg = class(tfpreaderjpeg) + protected + function InternalCheck(Str: TStream): boolean; override; + end; + +function readgraphic(const source: tstream; + const dest: tobject; var format: string; + const params: array of const): boolean; +begin + if dest is tbitmap then begin + result:= readfpgraphic(source,tmsefpreaderjpeg,tbitmap(dest)); + if result then begin + tbitmap(dest).change; + end; + end + else begin + result:= false; + end; +end; + +{ tmsefpreaderjpeg } + +function tmsefpreaderjpeg.InternalCheck(Str: TStream): boolean; +var + int1: integer; + ar1: array[0..1] of byte; +begin + result:= false; + int1:= str.position; + try + str.readbuffer(ar1,sizeof(ar1)); + if (ar1[0] = $ff) and (ar1[1] = $d8) then begin + result:= true; + end; + finally + str.position:= int1; + end; +end; + +procedure registerformat; +begin + registergraphicformat(jpglabel,{$ifdef FPC}@{$endif}readgraphic,nil, + stockobjects.captions[sc_JPEG_Image],['*.jpg','*.jpeg']); +end; + +initialization + registerformat(); +end. diff --git a/mseide-msegui/lib/common/image/mseformatjpgwrite.pas b/mseide-msegui/lib/common/image/mseformatjpgwrite.pas new file mode 100644 index 0000000..8d3b574 --- /dev/null +++ b/mseide-msegui/lib/common/image/mseformatjpgwrite.pas @@ -0,0 +1,51 @@ +{ MSEgui Copyright (c) 2006-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseformatjpgwrite; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +const + jpglabel = 'jpeg'; +procedure registerformat; + +implementation +uses + classes,mclasses,msegraphics,msebitmap,fpreadjpeg,msegraphicstream, + msestockobjects,msestream,fpwritejpeg,sysutils,typinfo; + +procedure writegraphic(const dest: tstream; + const source: tobject; const format: string; + const params: array of const); + //[compressionquality: integer] 0..100, default 75 +var + ima: tmsefpmemoryimage; + writer: tfpwriterjpeg; +begin + try + ima:= tmsefpmemoryimage.create(0,0); + ima.assign(tpersistent(source)); + writer:= tfpwriterjpeg.create; + if (length(params) > 0) and (tvarrec(params[0]).vtype = vtinteger) then begin + writer.compressionquality:= tvarrec(params[0]).vinteger; + end; + ima.writetostream(dest,writer); + finally + ima.free; + end; +end; + +procedure registerformat; +begin + registergraphicformat(jpglabel,nil,{$ifdef FPC}@{$endif}writegraphic, + stockobjects.captions[sc_JPEG_Image],['*.jpg','*.jpeg']); +end; + +initialization + registerformat(); +end. diff --git a/mseide-msegui/lib/common/image/mseformatpngread.pas b/mseide-msegui/lib/common/image/mseformatpngread.pas new file mode 100644 index 0000000..71760c5 --- /dev/null +++ b/mseide-msegui/lib/common/image/mseformatpngread.pas @@ -0,0 +1,70 @@ +{ MSEgui Copyright (c) 2006-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseformatpngread; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +const + pnglabel = 'png'; +procedure registerformat; + +implementation +uses + classes,mclasses,msegraphics,msebitmap,fpreadpng,msegraphicstream, + msestockobjects; + +type + tmsefpreaderpng = class(tfpreaderpng) + protected +// function InternalCheck(Str: TStream): boolean; override; + end; + +function readgraphic(const source: tstream; + const dest: tobject; var format: string; + const params: array of const): boolean; +begin + if dest is tbitmap then begin + result:= readfpgraphic(source,tmsefpreaderpng,tbitmap(dest)); + if result then begin + tbitmap(dest).change; + end; + end + else begin + result:= false; + end; +end; + +{ tmsefpreaderpng } +{ +function tmsefpreaderpng.InternalCheck(Str: TStream): boolean; +var + int1: integer; + ar1: array[0..7] of char; +begin + result:= false; + int1:= str.position; + try + str.readbuffer(ar1,sizeof(ar1)); + if ar1 = #137#80#78#71#13#10#26#10 then begin + result:= true; + end; + finally + str.position:= int1; + end; +end; +} +procedure registerformat; +begin + registergraphicformat(pnglabel,{$ifdef FPC}@{$endif}readgraphic,nil, + stockobjects.captions[sc_PNG_Image],['*.png']); +end; + +initialization + registerformat(); +end. diff --git a/mseide-msegui/lib/common/image/mseformatpngwrite.pas b/mseide-msegui/lib/common/image/mseformatpngwrite.pas new file mode 100644 index 0000000..597631a --- /dev/null +++ b/mseide-msegui/lib/common/image/mseformatpngwrite.pas @@ -0,0 +1,87 @@ +{ MSEgui Copyright (c) 2006-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseformatpngwrite; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +const + pnglabel = 'png'; +procedure registerformat; + +implementation +uses + classes,mclasses,msegraphics,msebitmap,fpwritepng,msegraphicstream,msestockobjects, + fpimage; + +procedure writegraphic(const dest: tstream; + const source: tobject; const format: string; + const params: array of const); + //[grayscale (default false), + // indexed (default false), + // compressedtext (default true), + // wordsized (default false), + // usealpha (default source): boolean] +var + ima: tmsefpmemoryimage; + writer: tfpwriterpng; + col1: tfpcolor; +begin + try + ima:= tmsefpmemoryimage.create(0,0); + ima.assign(tpersistent(source)); + writer:= tfpwriterpng.create; + writer.grayscale:= false; + writer.indexed:= false; + writer.compressedtext:= true; + writer.wordsized:= false; + writer.usealpha:= ima.hasalpha; + if (length(params) > 0) and (tvarrec(params[0]).vtype = vtboolean) then begin + writer.grayscale:= tvarrec(params[0]).vboolean; + if (length(params) > 1) and (tvarrec(params[1]).vtype = vtboolean) then begin + writer.indexed:= tvarrec(params[1]).vboolean; + if (length(params) > 2) and (tvarrec(params[2]).vtype = vtboolean) then begin + writer.compressedtext:= tvarrec(params[2]).vboolean; + if (length(params) > 3) and (tvarrec(params[3]).vtype = vtboolean) then begin + writer.wordsized:= tvarrec(params[3]).vboolean; + if (length(params) > 4) and (tvarrec(params[4]).vtype = vtboolean) then begin + writer.usealpha:= tvarrec(params[4]).vboolean; + end; + end; + end; + end; + end; + with ima do begin + if hasalpha and monoalpha then begin + if (height <> 0) and (width <> 0) then begin + col1:= colors[0,0]; //force mode 4 + if col1.alpha = 0 then begin + col1.alpha:= 1; + end + else begin + col1.alpha:= $fffe; + end; + colors[0,0]:= col1; + end; + end; + end; + ima.writetostream(dest,writer); + finally + ima.free; + end; +end; + +procedure registerformat; +begin + registergraphicformat(pnglabel,nil,{$ifdef FPC}@{$endif}writegraphic, + stockobjects.captions[sc_PNG_Image],['*.png']); +end; + +initialization + registerformat(); +end. diff --git a/mseide-msegui/lib/common/image/mseformatpnmread.pas b/mseide-msegui/lib/common/image/mseformatpnmread.pas new file mode 100644 index 0000000..25c9ef1 --- /dev/null +++ b/mseide-msegui/lib/common/image/mseformatpnmread.pas @@ -0,0 +1,70 @@ +{ MSEgui Copyright (c) 2006-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseformatpnmread; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +const + pnmlabel = 'pnm'; +procedure registerformat; + +implementation +uses + classes,mclasses,msegraphics,msebitmap,fpreadpnm,msegraphicstream, + msestockobjects; + +type + tmsefpreaderpnm = class(tfpreaderpnm) + protected + function InternalCheck(Str: TStream): boolean; override; + end; + +{ tmsefpreaderpnm } + +function tmsefpreaderpnm.InternalCheck(Str: TStream): boolean; +var + int1: integer; + ar1: array[0..1] of char; +begin + result:= false; + int1:= str.position; + try + str.readbuffer(ar1,sizeof(ar1)); + if (ar1[0] = 'P') and (ar1[1] >= '1') and (ar1[1] <= '6') then begin + result:= true; + end; + finally + str.position:= int1; + end; +end; + +function readgraphic(const source: tstream; + const dest: tobject; var format: string; + const params: array of const): boolean; +begin + if dest is tbitmap then begin + result:= readfpgraphic(source,tmsefpreaderpnm,tbitmap(dest)); + if result then begin + tbitmap(dest).change; + end; + end + else begin + result:= false; + end; +end; + +procedure registerformat; +begin + registergraphicformat(pnmlabel,{$ifdef FPC}@{$endif}readgraphic,nil, + stockobjects.captions[sc_PNM_Image],['*.pnm','*.pgm','*.pbm']); +end; + +initialization + registerformat(); +end. diff --git a/mseide-msegui/lib/common/image/mseformattgaread.pas b/mseide-msegui/lib/common/image/mseformattgaread.pas new file mode 100644 index 0000000..d093481 --- /dev/null +++ b/mseide-msegui/lib/common/image/mseformattgaread.pas @@ -0,0 +1,71 @@ +{ MSEgui Copyright (c) 2006-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseformattgaread; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +const + tgalabel = 'tga'; +procedure registerformat; + +implementation +uses + classes,mclasses,msegraphics,msebitmap,fpreadtga,msegraphicstream, + msestockobjects; + +type + tmsefpreadertarga = class(tfpreadertarga) + protected + function InternalCheck(Str: TStream): boolean; override; + end; + +function readgraphic(const source: tstream; + const dest: tobject; var format: string; + const params: array of const): boolean; +begin + if dest is tbitmap then begin + result:= readfpgraphic(source,tmsefpreadertarga,tbitmap(dest)); + if result then begin + tbitmap(dest).change; + end; + end + else begin + result:= false; + end; +end; + +{ tmsefpreadertarga } + +function tmsefpreadertarga.InternalCheck(Str: TStream): boolean; +var + int1: integer; + ar1: array[0..2] of byte; +begin + result:= false; + int1:= str.position; + try + str.readbuffer(ar1,sizeof(ar1)); + if ((ar1[1] = $00) or (ar1[1] = $01)) and + (ar1[2] > 0) and (ar1[2] <= 11) then begin + result:= true; + end; + finally + str.position:= int1; + end; +end; + +procedure registerformat; +begin + registergraphicformat(tgalabel,{$ifdef FPC}@{$endif}readgraphic,nil, + stockobjects.captions[sc_TARGA_Image],['*.tga']); +end; + +initialization + registerformat(); +end. diff --git a/mseide-msegui/lib/common/image/mseformattiffread.pas b/mseide-msegui/lib/common/image/mseformattiffread.pas new file mode 100644 index 0000000..9a3a61b --- /dev/null +++ b/mseide-msegui/lib/common/image/mseformattiffread.pas @@ -0,0 +1,70 @@ +{ MSEgui Copyright (c) 2006-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseformattiffread; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +const + tifflabel = 'tif'; +procedure registerformat; + +implementation +uses + classes,mclasses,msegraphics,msebitmap,fpreadtiff,msegraphicstream, + msestockobjects; + +type + tmsefpreadertiff = class(tfpreadertiff) + protected +// function InternalCheck(Str: TStream): boolean; override; + end; + +function readgraphic(const source: tstream; + const dest: tobject; var format: string; + const params: array of const): boolean; +begin + if dest is tbitmap then begin + result:= readfpgraphic(source,tmsefpreadertiff,tbitmap(dest)); + if result then begin + tbitmap(dest).change; + end; + end + else begin + result:= false; + end; +end; + +{ tmsefpreadertiff } +{ +function tmsefpreadertiff.InternalCheck(Str: TStream): boolean; +var + int1: integer; + ar1: array[0..7] of char; +begin + result:= false; + int1:= str.position; + try + str.readbuffer(ar1,sizeof(ar1)); + if ar1 = #137#80#78#71#13#10#26#10 then begin + result:= true; + end; + finally + str.position:= int1; + end; +end; +} +procedure registerformat; +begin + registergraphicformat(tifflabel,{$ifdef FPC}@{$endif}readgraphic,nil, + stockobjects.captions[sc_TIFF_Image],['*.tif','*.tiff']); +end; + +initialization + registerformat(); +end. diff --git a/mseide-msegui/lib/common/image/mseformattiffwrite.pas b/mseide-msegui/lib/common/image/mseformattiffwrite.pas new file mode 100644 index 0000000..77fcccf --- /dev/null +++ b/mseide-msegui/lib/common/image/mseformattiffwrite.pas @@ -0,0 +1,52 @@ +{ MSEgui Copyright (c) 2012-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseformattiffwrite; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +const + tifflabel = 'tif'; +procedure registerformat; + +implementation +uses + classes,mclasses,msegraphics,msebitmap,fpwritetiff,msegraphicstream,msestockobjects, + fpimage; + +// +// todo: -TFPWriterTiff writes a black image, maybe it needs initialization +// -add parameter +// +procedure writegraphic(const dest: tstream; + const source: tobject; const format: string; + const params: array of const); + //no params up to now +var + ima: tmsefpmemoryimage; + writer: tfpwritertiff; +begin + try + ima:= tmsefpmemoryimage.create(0,0); + ima.assign(tpersistent(source)); + writer:= tfpwritertiff.create; + ima.writetostream(dest,writer); + finally + ima.free; + end; +end; + +procedure registerformat; +begin + registergraphicformat(tifflabel,nil,{$ifdef FPC}@{$endif}writegraphic, + stockobjects.captions[sc_TIFF_Image],['*.tif','*.tiff']); +end; + +initialization + registerformat(); +end. diff --git a/mseide-msegui/lib/common/image/mseformatxpmread.pas b/mseide-msegui/lib/common/image/mseformatxpmread.pas new file mode 100644 index 0000000..a761505 --- /dev/null +++ b/mseide-msegui/lib/common/image/mseformatxpmread.pas @@ -0,0 +1,59 @@ +{ MSEgui Copyright (c) 2006-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseformatxpmread; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +const + xpmlabel = 'xpm'; +procedure registerformat; + +implementation +uses + classes,mclasses,msegraphics,msebitmap,fpreadxpm,msegraphicstream, + msestockobjects,fpimage; + +type + tmsefpreaderxpm = class(tfpreaderxpm) + protected + procedure InternalRead (Str:TStream; Img:TFPCustomImage); override; + end; + +function readgraphic(const source: tstream; + const dest: tobject; var format: string; + const params: array of const): boolean; +begin + if dest is tbitmap then begin + result:= readfpgraphic(source,tmsefpreaderxpm,tbitmap(dest)); + if result then begin + tbitmap(dest).change; + end; + end + else begin + result:= false; + end; +end; + +{ tmsefpreadertaxpm } + +procedure tmsefpreaderxpm.InternalRead(Str: TStream; Img: TFPCustomImage); +begin + img.usepalette:= true; + inherited; +end; + +procedure registerformat; +begin + registergraphicformat(xpmlabel,{$ifdef FPC}@{$endif}readgraphic,nil, + stockobjects.captions[sc_XPM_Image],['*.xpm']); +end; + +initialization + registerformat(); +end. diff --git a/mseide-msegui/lib/common/image/msegraphicsmagick.pas b/mseide-msegui/lib/common/image/msegraphicsmagick.pas new file mode 100644 index 0000000..2788d74 --- /dev/null +++ b/mseide-msegui/lib/common/image/msegraphicsmagick.pas @@ -0,0 +1,1124 @@ +{ MSEgui Copyright (c) 2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msegraphicsmagick; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes{msestrings},msectypes,msedynload; + +const +{$ifdef mswindows} + graphicsmagiclib: array[0..0] of filenamety = ('CORE_RL_magick_.dll'); + graphicsmagicwandlib: array[0..0] of filenamety = ('CORE_RL_wand_.dll'); +{$else} + graphicsmagicwandlib: array[0..1] of filenamety = + ('libGraphicsMagickWand.so.2','libGraphicsMagickWand.so'); + graphicsmagiclib: array[0..1] of filenamety = + ('libGraphicsMagick.so.3','libGraphicsMagick.so'); +{$endif} + +{$packrecords c} + +type + quantumdepthty = (qd_8,qd_16,qd_32); + + MagickBool = cuint; +const + MagickTrue = 1; + MagickFalse = 0; +type + MagickPassFail = cuint; +const + MagickPass = 1; + MagickFail = 0; + +type + EndianType = ( + UndefinedEndian, + LSBEndian, //* "little" endian */ + MSBEndian, //* "big" endian */ + NativeEndian //* native endian */ + ); + StorageType = ( + CharPixel, //* Unsigned 8 bit 'unsigned char' */ + ShortPixel, //* Unsigned 16 bit 'unsigned short int' */ + IntegerPixel, //* Unsigned 32 bit 'unsigned int' */ + LongPixel, //* Unsigned 32 or 64 bit (CPU dependent) 'unsigned long' */ + FloatPixel, //* Floating point 32-bit 'float' */ + DoublePixel //* Floating point 64-bit 'double' */ + ); + + QuantumType = ( + UndefinedQuantum, //* Not specified */ + IndexQuantum, //* Colormap indexes */ + GrayQuantum, //* Grayscale values (minimum value is black) */ + IndexAlphaQuantum, //* Colormap indexes with transparency */ + GrayAlphaQuantum, //* Grayscale values with transparency */ + RedQuantum, //* Red values only (RGBA) */ + CyanQuantum, //* Cyan values only (CMYKA) */ + GreenQuantum, //* Green values only (RGBA) */ + YellowQuantum, //* Yellow values only (CMYKA) */ + BlueQuantum, //* Blue values only (RGBA) */ + MagentaQuantum, //* Magenta values only (CMYKA) */ + AlphaQuantum, //* Transparency values (RGBA or CMYKA) */ + BlackQuantum, //* Black values only (CMYKA) */ + RGBQuantum, //* Red, green, and blue values */ + RGBAQuantum, //* Red, green, blue, and transparency values */ + CMYKQuantum, //* Cyan, magenta, yellow, and black values */ + CMYKAQuantum, //* Cyan, magenta, yellow, black, and transparency values */ + CIEYQuantum, //* CIE Y values, based on CCIR-709 primaries */ + CIEXYZQuantum //* CIE XYZ values, based on CCIR-709 primaries */ + ); + + QuantumSampleType = ( + UndefinedQuantumSampleType, //* Not specified */ + UnsignedQuantumSampleType, //* Unsigned integral type (1-32 or 64 bits) */ + FloatQuantumSampleType //* Floating point type (16, 24, 32, or 64 bit) */ + ); + + CompressionType = ( + UndefinedCompression, + NoCompression, + BZipCompression, + FaxCompression, +// Group3Compression = FaxCompression, + Group4Compression, + JPEGCompression, + LosslessJPEGCompression, + LZWCompression, + RLECompression, + ZipCompression, + LZMACompression, //* Lempel-Ziv-Markov chain algorithm */ + JPEG2000Compression, //* ISO/IEC std 15444-1 */ + JBIG1Compression, //* ISO/IEC std 11544 / ITU-T rec T.82 */ + JBIG2Compression //* ISO/IEC std 14492 / ITU-T rec T.88 */ + ); + + InterlaceType = ( + UndefinedInterlace, + NoInterlace, + LineInterlace, + PlaneInterlace, + PartitionInterlace + ); + + ResolutionType = ( + UndefinedResolution, + PixelsPerInchResolution, + PixelsPerCentimeterResolution + ); + + ColorspaceType = ( + UndefinedColorspace, + RGBColorspace, //* Plain old RGB colorspace */ + GRAYColorspace, //* Plain old full-range grayscale */ + TransparentColorspace, //* RGB but preserve matte channel during quantize */ + OHTAColorspace, + XYZColorspace, //* CIE XYZ */ + YCCColorspace, //* Kodak PhotoCD PhotoYCC */ + YIQColorspace, + YPbPrColorspace, + YUVColorspace, + CMYKColorspace, //* Cyan, magenta, yellow, black, alpha */ + sRGBColorspace, //* Kodak PhotoCD sRGB */ + HSLColorspace, //* Hue, saturation, luminosity */ + HWBColorspace, //* Hue, whiteness, blackness */ + LABColorspace, //* LAB colorspace not supported yet other than via lcms */ + CineonLogRGBColorspace,//* RGB data with Cineon Log scaling, 2.048 density range */ + Rec601LumaColorspace, //* Luma (Y) according to ITU-R 601 */ + Rec601YCbCrColorspace, //* YCbCr according to ITU-R 601 */ + Rec709LumaColorspace, //* Luma (Y) according to ITU-R 709 */ + Rec709YCbCrColorspace //* YCbCr according to ITU-R 709 */ + ); + + ImageType = ( + UndefinedType, + BilevelType, + GrayscaleType, + GrayscaleMatteType, + PaletteType, + PaletteMatteType, + TrueColorType, + TrueColorMatteType, + ColorSeparationType, + ColorSeparationMatteType, + OptimizeType + ); + + PreviewType = ( + UndefinedPreview = 0, + RotatePreview, + ShearPreview, + RollPreview, + HuePreview, + SaturationPreview, + BrightnessPreview, + GammaPreview, + SpiffPreview, + DullPreview, + GrayscalePreview, + QuantizePreview, + DespecklePreview, + ReduceNoisePreview, + AddNoisePreview, + SharpenPreview, + BlurPreview, + ThresholdPreview, + EdgeDetectPreview, + SpreadPreview, + SolarizePreview, + ShadePreview, + RaisePreview, + SegmentPreview, + SwirlPreview, + ImplodePreview, + WavePreview, + OilPaintPreview, + CharcoalDrawingPreview, + JPEGPreview + ); + + ClassType = ( + UndefinedClass, + DirectClass, + PseudoClass + ); + + OrientationType = ( //* Line direction / Frame Direction */ + //* -------------- / --------------- */ + UndefinedOrientation, //* Unknown / Unknown */ + TopLeftOrientation, //* Left to right / Top to bottom */ + TopRightOrientation, //* Right to left / Top to bottom */ + BottomRightOrientation, //* Right to left / Bottom to top */ + BottomLeftOrientation, //* Left to right / Bottom to top */ + LeftTopOrientation, //* Top to bottom / Left to right */ + RightTopOrientation, //* Top to bottom / Right to left */ + RightBottomOrientation, //* Bottom to top / Right to left */ + LeftBottomOrientation //* Bottom to top / Left to right */ + ); + + RenderingIntent = ( + UndefinedIntent, + SaturationIntent, + PerceptualIntent, + AbsoluteIntent, + RelativeIntent + ); + + FilterTypes = ( + UndefinedFilter, + PointFilter, + BoxFilter, + TriangleFilter, + HermiteFilter, + HanningFilter, + HammingFilter, + BlackmanFilter, + GaussianFilter, + QuadraticFilter, + CubicFilter, + CatromFilter, + MitchellFilter, + LanczosFilter, + BesselFilter, + SincFilter + ); + + GravityType = ( + ForgetGravity, + NorthWestGravity, + NorthGravity, + NorthEastGravity, + WestGravity, + CenterGravity, + EastGravity, + SouthWestGravity, + SouthGravity, + SouthEastGravity, + StaticGravity + ); + + CompositeOperator = ( + UndefinedCompositeOp = 0, + OverCompositeOp, + InCompositeOp, + OutCompositeOp, + AtopCompositeOp, + XorCompositeOp, + PlusCompositeOp, + MinusCompositeOp, + AddCompositeOp, + SubtractCompositeOp, + DifferenceCompositeOp, + MultiplyCompositeOp, + BumpmapCompositeOp, + CopyCompositeOp, + CopyRedCompositeOp, + CopyGreenCompositeOp, + CopyBlueCompositeOp, + CopyOpacityCompositeOp, + ClearCompositeOp, + DissolveCompositeOp, + DisplaceCompositeOp, + ModulateCompositeOp, + ThresholdCompositeOp, + NoCompositeOp, + DarkenCompositeOp, + LightenCompositeOp, + HueCompositeOp, + SaturateCompositeOp, + ColorizeCompositeOp, + LuminizeCompositeOp, + ScreenCompositeOp, //* Not yet implemented */ + OverlayCompositeOp, //* Not yet implemented */ + CopyCyanCompositeOp, + CopyMagentaCompositeOp, + CopyYellowCompositeOp, + CopyBlackCompositeOp, + DivideCompositeOp + ); + + DisposeType = ( + UndefinedDispose, + NoneDispose, + BackgroundDispose, + PreviousDispose + ); + + TimerState = ( + UndefinedTimerState, + StoppedTimerState, + RunningTimerState + ); + + Quantum8 = cuchar; + Quantum16 = cushort; + Quantum32 = cuint; + + PixelPacket8 = record + {$ifdef WORDS_BIGENDIAN} + //* RGBA */ + {$define MAGICK_PIXELS_RGBA} + red: Quantum8; + green: Quantum8; + blue: Quantum8; + opacity: Quantum8; + {$else} + //* BGRA (as used by Microsoft Windows DIB) */ + {$define MAGICK_PIXELS_BGRA} + blue: Quantum8; + green: Quantum8; + red: Quantum8; + opacity: Quantum8; + {$endif} + end; + pPixelPacket8 = ^PixelPacket8; + + PixelPacket16 = record + {$ifdef WORDS_BIGENDIAN} + //* RGBA */ + {$define MAGICK_PIXELS_RGBA} + red: Quantum16; + green: Quantum16; + blue: Quantum16; + opacity: Quantum16; + {$else} + //* BGRA (as used by Microsoft Windows DIB) */ + {$define MAGICK_PIXELS_BGRA} + blue: Quantum16; + green: Quantum16; + red: Quantum16; + opacity: Quantum16; + {$endif} + end; + pPixelPacket16 = ^PixelPacket16; + + PixelPacket32 = record + {$ifdef WORDS_BIGENDIAN} + //* RGBA */ + {$define MAGICK_PIXELS_RGBA} + red: Quantum32; + green: Quantum32; + blue: Quantum32; + opacity: Quantum32; + {$else} + //* BGRA (as used by Microsoft Windows DIB) */ + {$define MAGICK_PIXELS_BGRA} + blue: Quantum32; + green: Quantum32; + red: Quantum32; + opacity: Quantum32; + {$endif} + end; + pPixelPacket32 = ^PixelPacket32; + + _FILE = record + end; //todo: link tstream and C-stream + pFILE = ^_FILE; + _CacheInfoPtr_ = pointer; + _BlobInfoPtr_ = pointer; + + MaxTextExtent = 0..2052; //??? + + const //ExceptionBaseType + UndefinedExceptionBase = 0; + ExceptionBase = 1; + ResourceBase = 2; + ResourceLimitBase = 2; + TypeBase = 5; + AnnotateBase = 5; + OptionBase = 10; + DelegateBase = 15; + MissingDelegateBase = 20; + CorruptImageBase = 25; + FileOpenBase = 30; + BlobBase = 35; + StreamBase = 40; + CacheBase = 45; + CoderBase = 50; + ModuleBase = 55; + DrawBase = 60; + RenderBase = 60; + ImageBase = 65; + WandBase = 67; + TemporaryFileBase = 70; + TransformBase = 75; + XServerBase = 80; + X11Base = 81; + UserBase = 82; + MonitorBase = 85; + LocaleBase = 86; + DeprecateBase = 87; + RegistryBase = 90; + ConfigureBase = 95; + //ExceptionType + UndefinedException = 0; + EventException = 100; + ExceptionEvent = EventException + ExceptionBase; + ResourceEvent = EventException + ResourceBase; + ResourceLimitEvent = EventException + ResourceLimitBase; + TypeEvent = EventException + TypeBase; + AnnotateEvent = EventException + AnnotateBase; + OptionEvent = EventException + OptionBase; + DelegateEvent = EventException + DelegateBase; + MissingDelegateEvent = EventException + MissingDelegateBase; + CorruptImageEvent = EventException + CorruptImageBase; + FileOpenEvent = EventException + FileOpenBase; + BlobEvent = EventException + BlobBase; + StreamEvent = EventException + StreamBase; + CacheEvent = EventException + CacheBase; + CoderEvent = EventException + CoderBase; + ModuleEvent = EventException + ModuleBase; + DrawEvent = EventException + DrawBase; + RenderEvent = EventException + RenderBase; + ImageEvent = EventException + ImageBase; + WandEvent = EventException + WandBase; + TemporaryFileEvent = EventException + TemporaryFileBase; + TransformEvent = EventException + TransformBase; + XServerEvent = EventException + XServerBase; + X11Event = EventException + X11Base; + UserEvent = EventException + UserBase; + MonitorEvent = EventException + MonitorBase; + LocaleEvent = EventException + LocaleBase; + DeprecateEvent = EventException + DeprecateBase; + RegistryEvent = EventException + RegistryBase; + ConfigureEvent = EventException + ConfigureBase; + + WarningException = 300; + ExceptionWarning = WarningException + ExceptionBase; + ResourceWarning = WarningException + ResourceBase; + ResourceLimitWarning = WarningException + ResourceLimitBase; + TypeWarning = WarningException + TypeBase; + AnnotateWarning = WarningException + AnnotateBase; + OptionWarning = WarningException + OptionBase; + DelegateWarning = WarningException + DelegateBase; + MissingDelegateWarning = WarningException + MissingDelegateBase; + CorruptImageWarning = WarningException + CorruptImageBase; + FileOpenWarning = WarningException + FileOpenBase; + BlobWarning = WarningException + BlobBase; + StreamWarning = WarningException + StreamBase; + CacheWarning = WarningException + CacheBase; + CoderWarning = WarningException + CoderBase; + ModuleWarning = WarningException + ModuleBase; + DrawWarning = WarningException + DrawBase; + RenderWarning = WarningException + RenderBase; + ImageWarning = WarningException + ImageBase; + WandWarning = WarningException + WandBase; + TemporaryFileWarning = WarningException + TemporaryFileBase; + TransformWarning = WarningException + TransformBase; + XServerWarning = WarningException + XServerBase; + X11Warning = WarningException + X11Base; + UserWarning = WarningException + UserBase; + MonitorWarning = WarningException + MonitorBase; + LocaleWarning = WarningException + LocaleBase; + DeprecateWarning = WarningException + DeprecateBase; + RegistryWarning = WarningException + RegistryBase; + ConfigureWarning = WarningException + ConfigureBase; + + ErrorException = 400; + ExceptionError = ErrorException + ExceptionBase; + ResourceError = ErrorException + ResourceBase; + ResourceLimitError = ErrorException + ResourceLimitBase; + TypeError = ErrorException + TypeBase; + AnnotateError = ErrorException + AnnotateBase; + OptionError = ErrorException + OptionBase; + DelegateError = ErrorException + DelegateBase; + MissingDelegateError = ErrorException + MissingDelegateBase; + CorruptImageError = ErrorException + CorruptImageBase; + FileOpenError = ErrorException + FileOpenBase; + BlobError = ErrorException + BlobBase; + StreamError = ErrorException + StreamBase; + CacheError = ErrorException + CacheBase; + CoderError = ErrorException + CoderBase; + ModuleError = ErrorException + ModuleBase; + DrawError = ErrorException + DrawBase; + RenderError = ErrorException + RenderBase; + ImageError = ErrorException + ImageBase; + WandError = ErrorException + WandBase; + TemporaryFileError = ErrorException + TemporaryFileBase; + TransformError = ErrorException + TransformBase; + XServerError = ErrorException + XServerBase; + X11Error = ErrorException + X11Base; + UserError = ErrorException + UserBase; + MonitorError = ErrorException + MonitorBase; + LocaleError = ErrorException + LocaleBase; + DeprecateError = ErrorException + DeprecateBase; + RegistryError = ErrorException + RegistryBase; + ConfigureError = ErrorException + ConfigureBase; + + FatalErrorException = 700; + ExceptionFatalError = FatalErrorException + ExceptionBase; + ResourceFatalError = FatalErrorException + ResourceBase; + ResourceLimitFatalError = FatalErrorException + ResourceLimitBase; + TypeFatalError = FatalErrorException + TypeBase; + AnnotateFatalError = FatalErrorException + AnnotateBase; + OptionFatalError = FatalErrorException + OptionBase; + DelegateFatalError = FatalErrorException + DelegateBase; + MissingDelegateFatalError = FatalErrorException + MissingDelegateBase; + CorruptImageFatalError = FatalErrorException + CorruptImageBase; + FileOpenFatalError = FatalErrorException + FileOpenBase; + BlobFatalError = FatalErrorException + BlobBase; + StreamFatalError = FatalErrorException + StreamBase; + CacheFatalError = FatalErrorException + CacheBase; + CoderFatalError = FatalErrorException + CoderBase; + ModuleFatalError = FatalErrorException + ModuleBase; + DrawFatalError = FatalErrorException + DrawBase; + RenderFatalError = FatalErrorException + RenderBase; + ImageFatalError = FatalErrorException + ImageBase; + WandFatalError = FatalErrorException + WandBase; + TemporaryFileFatalError = FatalErrorException + TemporaryFileBase; + TransformFatalError = FatalErrorException + TransformBase; + XServerFatalError = FatalErrorException + XServerBase; + X11FatalError = FatalErrorException + X11Base; + UserFatalError = FatalErrorException + UserBase; + MonitorFatalError = FatalErrorException + MonitorBase; + LocaleFatalError = FatalErrorException + LocaleBase; + DeprecateFatalError = FatalErrorException + DeprecateBase; + RegistryFatalError = FatalErrorException + RegistryBase; + ConfigureFatalError = FatalErrorException + ConfigureBase; +type + ExceptionInfo = record + severity: cint; //* Exception severity, reason, and description */ + reason: pcchar; + description: pcchar; + error_number: cint; //* Value of errno (or equivalent) when exception was thrown. */ + module: pcchar; //*Reporting source module, function (if available), and source + // module line. */ + _function: pchar; + line: culong; + signature: culong; //* Structure sanity check + end; + pExceptionInfo = ^ExceptionInfo; + + PrimaryInfo = record + x: cdouble; + y: cdouble; + z: cdouble; + end; + + ChromaticityInfo = record + red_primary: PrimaryInfo; + green_primary: PrimaryInfo; + blue_primary: PrimaryInfo; + white_point: PrimaryInfo; + end; + + RectangleInfo = record + width: culong; + height: culong; + x: clong; + y: clong; + end; + + ErrorInfo = record + mean_error_per_pixel: cdouble; //* Average error per pixel (absolute range) */ + normalized_mean_error: cdouble; //* Average error per pixel (normalized to 1.0) */ + normalized_maximum_error: cdouble; //* Maximum error encountered (normalized to 1.0) */ + end; + + Timer = record + start: cdouble; + stop: cdouble; + total: cdouble; + end; + + TimerInfo = record + user: Timer; + elapsed: Timer; + state: TimerState; + signature: culong; + end; + + _ThreadViewSetPtr_ = pointer; + _ImageAttributePtr_ = pointer; + _Ascii85InfoPtr_ = pointer; + _SemaphoreInfoPtr_ = pointer; + + Imagea = record + storage_class: ClassType; //* DirectClass (TrueColor) or PseudoClass (colormapped) */ + colorspace: ColorspaceType; //* Current image colorspace/model */ + compression: CompressionType; //* Compression algorithm to use when encoding image */ + dither: MagickBool; //* True if image is to be dithered */ + matte: MagickBool; //* True if image has an opacity (alpha) channel */ + columns: culong; //* Number of image columns */ + rows: culong; //* Number of image rows */ + colors: cuint; //* Current number of colors in PseudoClass colormap */ + depth: cuint; //* Bits of precision to preserve in color quantum */ + end; + Imageb8 = record + colormap: pPixelPacket8; //* Pseudoclass colormap array */ + background_color: PixelPacket8; //* Background color */ + border_color: PixelPacket8; //* Border color */ + matte_color: PixelPacket8; //* Matte (transparent) color */ + end; + Imageb16 = record + colormap: pPixelPacket16; //* Pseudoclass colormap array */ + background_color: PixelPacket16; //* Background color */ + border_color: PixelPacket16; //* Border color */ + matte_color: PixelPacket16; //* Matte (transparent) color */ + end; + Imageb32 = record + colormap: pPixelPacket32; //* Pseudoclass colormap array */ + background_color: PixelPacket32; //* Background color */ + border_color: PixelPacket32; //* Border color */ + matte_color: PixelPacket32; //* Matte (transparent) color */ + end; + Imagec = record + gamma: cdouble; //* Image gamma (e.g. 0.45) */ + chromaticity: ChromaticityInfo; //* Red, green, blue, and white chromaticity values */ + orientation: OrientationType; //* Image orientation */ + rendering_intent: RenderingIntent; //* Rendering intent */ + units: ResolutionType; //* Units of image resolution (density) */ + montage: pcchar; //* Tile size and offset within an image montage */ + directory: pcchar; //* Tile names from within an image montage */ + geometry: pcchar; //* Composite/Crop options */ + offset: clong; //* Offset to start of image data */ + x_resolution: cdouble; //* Horizontal resolution (also see units) */ + y_resolution: cdouble; //* Vertical resolution (also see units) */ + page: RectangleInfo; //* Offset to apply when placing image */ + tile_info: RectangleInfo; //* Subregion tile dimensions and offset */ + blur: cdouble; //* Amount of blur to apply when zooming image */ + fuzz: cdouble; //* Colors within this distance match target color */ + filter: FilterTypes; //* Filter to use when zooming image */ + interlace: InterlaceType; //* Interlace pattern to use when writing image */ + endian: EndianType; //* Byte order to use when writing image */ + gravity: GravityType; //* Image placement gravity */ + compose: CompositeOperator; //* Image placement composition (default OverCompositeOp) */ + _dispose: DisposeType; //* GIF disposal option */ + scene: culong; //* Animation frame scene number */ + delay: culong; //* Animation frame scene delay */ + iterations: culong; //* Animation iterations */ + total_colors: culong; //* Number of unique colors. See GetNumberColors() */ + start_loop: clong; //* Animation frame number to start looping at */ + error: ErrorInfo; //* Computed image comparison or quantization error */ + timer: TimerInfo; //* Operation micro-timer */ + client_data: pointer; //* User specified opaque data pointer */ +//* +// Output file name. +// A colon delimited format identifier may be prepended to the file +// name in order to force a particular output format. Otherwise the +// file extension is used. If no format prefix or file extension is +// present, then the output format is determined by the 'magick' +// field. */ + filename: array[MaxTextExtent] of char; +//* Original file name (name of input image file) */ + magick_filename: array[MaxTextExtent] of cchar; +//* +// File format of the input file, and the default output format. +// The precedence when selecting the output format is: +// 1) magick prefix to file name (e.g. "jpeg:foo). +// 2) file name extension. (e.g. "foo.jpg") +// 3) content of this magick field. */ + magick: array[MaxTextExtent] of cchar; +//* Original image width (before transformations) */ + magick_columns: culong; +//* Original image height (before transformations) */ + magick_rows: culong; + exception: ExceptionInfo; //* Any error associated with this image frame */ + previous: pointer{pImage}; //* Pointer to previous frame */ + next: pointer{pImage}; //* Pointer to next frame */ +//* To be added here for a later release: +// quality? +// subsampling +// video black/white setup levels (ReferenceBlack/ReferenceWhite) +// sample format (integer/float) */ + +//* Only private members appear past this point */ + profiles: pointer; //* Private, Embedded profiles */ + is_monochrome: cuint; //* Private, True if image is known to be monochrome */ + is_grayscale: cuint; //* Private, True if image is known to be grayscale */ + taint: cuint; //* Private, True if image has not been modifed */ + clip_mask: pointer{pImage}; //* Private, Clipping mask to apply when updating pixels */ + ping: MagickBool; //* Private, if true, pixels are undefined */ + cache: _CacheInfoPtr_; //* Private, image pixel cache */ + default_views: _ThreadViewSetPtr_; //* Private, default cache views */ + attributes: _ImageAttributePtr_; //* Private, Image attribute list */ + ascii85: _Ascii85InfoPtr_; //* Private, supports huffman encoding */ + blob: _BlobInfoPtr_; //* Private, file I/O object */ + reference_count: clong; //* Private, Image reference count */ + semaphore: _SemaphoreInfoPtr_; //* Private, Per image lock (for reference count) */ + logging: cuint; //* Private, True if logging is enabled */ + list: pointer{pImage}; //* Private, used only by display */ + signature: culong; //* Private, Unique code to validate structure */ + end; + + Image8 = record + a: Imagea; + b: Imageb8; + c: Imagec; + end; + pImage8 = ^Image8; + Image16 = record + a: Imagea; + b: Imageb16; + c: Imagec; + end; + pImage16 = ^Image16; + Image32 = record + a: Imagea; + b: Imageb32; + c: Imagec; + end; + pImage32 = ^Image32; + + + ImageInfoa = record + compression: CompressionType; //* Image compression to use while decoding */ + temporary: MagickBool; //* Remove file "filename" once it has been read. */ + adjoin: MagickBool; //* If True, join multiple frames into one file */ + antialias: MagickBool; //* If True, antialias while rendering */ + subimage: culong; //* Starting image scene ID to select */ + subrange: culong; //* Span of image scene IDs (from starting scene) to select */ + depth: culong; //* Number of quantum bits to preserve while encoding */ + size: pchar; //* Desired/known dimensions to use when decoding image */ + tile: pchar; //* Deprecated, name of image to tile on background */ + page: pchar; //* Output page size & offset */ + interlace: InterlaceType; //* Interlace scheme to use when decoding image */ + endian: EndianType; //* Select MSB/LSB endian output for TIFF format */ + units: ResolutionType; //* Units to apply when evaluating the density option */ + quality: culong; //* Compression quality factor (format specific) */ + sampling_factor: pchar; //* JPEG, MPEG, and YUV chroma downsample factor */ + server_name: pchar; //* X11 server display specification */ + font: pchar; //* Font name to use for text annotations */ + texture: pchar; //* Name of texture image to use for background fills */ + density: pchar; //* Image resolution (also see units) */ + pointsize: cdouble; //* Font pointsize */ + fuzz: cdouble; //* Colors within this distance are a match */ + end; + ImageInfob8 = record + pen: PixelPacket8; //* Stroke or fill color while drawing */ + background_color: PixelPacket8; //* Background color */ + border_color: PixelPacket8; //* Border color (color surrounding frame) */ + matte_color: PixelPacket8; //* Matte color (frame color) */ + end; + ImageInfob16 = record + pen: PixelPacket16; //* Stroke or fill color while drawing */ + background_color: PixelPacket16; //* Background color */ + border_color: PixelPacket16; //* Border color (color surrounding frame) */ + matte_color: PixelPacket16; //* Matte color (frame color) */ + end; + ImageInfob32 = record + pen: PixelPacket8; //* Stroke or fill color while drawing */ + background_color: PixelPacket8; //* Background color */ + border_color: PixelPacket8; //* Border color (color surrounding frame) */ + matte_color: PixelPacket8; //* Matte color (frame color) */ + end; + ImageInfoc = record + dither: MagickBool; //* If true, dither image while writing */ + monochrome: MagickBool; //* If true, use monochrome format */ + progress: MagickBool; //* If true, show progress indication */ + colorspace: ColorspaceType; //* Colorspace representations of image pixels */ + _type: ImageType; //* Desired image type (used while reading or writing) */ + group: clong; //* X11 window group ID */ + verbose: cuint; //* If non-zero, display high-level processing */ + view: pchar; //* FlashPIX view specification */ + authenticate: pchar; //* Password used to decrypt file */ + client_data: pointer; //* User-specified data to pass to coder */ + _file: pFILE; //* If not null, stdio FILE * to read image from + // (fopen mode "rb") or write image to (fopen + // mode "rb+"). */ + magick: array[MaxTextExtent] of cchar; //* File format to read. Overrides file extension */ + filename: array[MaxTextExtent] of cchar; //* File name to read */ + + // Only private members appear past this point + + cache: _CacheInfoPtr_;//* Private. Used to pass image via open cache */ + definitions: pointer; //* Private. Map of coder specific options passed by user. + //Use AddDefinitions, RemoveDefinitions, & AccessDefinition + //to access and manipulate this data. */ + attributes: pointer{pImage}; //* Private. Image attribute list */ + ping: MagickBool; //* Private, if true, read file header only */ + preview_type: PreviewType; //* Private, used by PreviewImage */ + affirm: MagickBool; //* Private, when true do not intuit image format */ + blob: _BlobInfoPtr_; //* Private, used to pass in open blob */ + length: size_t; //* Private, used to pass in open blob length */ + unique: array[MaxTextExtent] of cchar; //* Private, passes temporary filename to TranslateText */ + zero: array[MaxTextExtent] of cchar; //* Private, passes temporary filename to TranslateText */ + signature: culong; //* Private, used to validate structure */ + end; + ImageInfo8 = record + a: ImageInfoa; + b: ImageInfob8; + c:ImageInfoc + end; + pImageInfo8 = ^ImageInfo8; + + ImageInfo16 = record + a: ImageInfoa; + b: ImageInfob16; + c:ImageInfoc + end; + pImageInfo16 = ^ImageInfo16; + + ImageInfo32 = record + a: ImageInfoa; + b: ImageInfob32; + c:ImageInfoc + end; + pImageInfo32 = ^ImageInfo32; + +// pExportPixelAreaOptions = ^ExportPixelAreaOptions; + + ExportPixelAreaOptions = record + sample_type: QuantumSampleType; //* Quantum sample type */ + double_minvalue: cdouble; + //* Minimum value (default 0.0) for linear floating point samples */ + double_maxvalue: cdouble; + //* Maximum value (default 1.0) for linear floating point samples */ + grayscale_miniswhite: MagickBool; + //* Grayscale minimum value is white rather than black */ + pad_bytes: culong; + //* Number of pad bytes to output after pixel data */ + pad_value: cuchar; + //* Value to use when padding end of pixel data */ + endian: EndianType; + //* Endian orientation for 16/32/64 bit types (default MSBEndian) */ + signature: culong; + end; + pExportPixelAreaOptions = ^ExportPixelAreaOptions; + + ImportPixelAreaOptions = record + sample_type: QuantumSampleType; //* Quantum sample type */ + double_minvalue: cdouble; + //* Minimum value (default 0.0) for linear floating point samples */ + double_maxvalue: cdouble; + //* Maximum value (default 1.0) for linear floating point samples */ + grayscale_miniswhite: MagickBool; + //* Grayscale minimum value is white rather than black */ + endian: EndianType; //* Endian orientation for 16/32/64 bit types + //(default MSBEndian) */ + signature: culong; + end; + pImportPixelAreaOptions = ^ImportPixelAreaOptions; + + ExportPixelAreaInfo = record + bytes_exported: size_t; //* Number of bytes which were exported */ + end; + pExportPixelAreaInfo = ^ExportPixelAreaInfo; + + ImportPixelAreaInfo = record + bytes_imported: size_t; //* Number of bytes which were imported */ + end; + pImportPixelAreaInfo = ^ImportPixelAreaInfo; + + MagickWand = record + end; + pMagickWand = ^MagickWand; + +var + InitializeMagick: procedure(path: pcchar); + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + DestroyMagick: procedure(); + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + MagickMalloc: function(size: size_t): pointer; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + MagickFree: procedure(memory: pointer); + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + MagickGetVersion: function(version: pculong): pcchar; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + MagickGetQuantumDepth: function(depth: pculong): pchar; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + MagickQueryFormats: function(pattern: pcchar; + number_formats: pculong): ppcchar; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + GetExceptionInfo: procedure(exception: pExceptionInfo); + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + DestroyExceptionInfo: procedure(exception: pExceptionInfo); + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + CloneImageInfo: function(image_info: pointer{pImageInfo}): pointer{pImageInfo}; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + DestroyImageInfo: procedure(image_info: pointer{pImageInfo}); + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + AllocateImage: function(image_info: pointer{pImageInfo}): pointer{pImage}; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + PingImage: function(image_info: pointer{pImageInfo}; + exception: pExceptionInfo):pointer{pImage}; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + ReadImage: function(image_info: pointer{pImageInfo}; + exception: pExceptionInfo): pointer{pImage}; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + PingBlob: function(imageinfo: pointer{pImageInfo}; blob: pointer; + length: size_t; exception: pExceptionInfo): pointer{pImage}; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + BlobToImage: function(image_info: pointer{pImageInfo}; blob: pointer; + length: size_t; exception: pExceptionInfo): pointer{pImage}; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + WriteImage: function(image_info: pointer{pImageInfo}; + image: pointer{pImage}): cuint; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + ImageToBlob: function(image_info: pointer{pImageInfo}; + image: pointer{pImage}; length: psize_t; + exception: pExceptionInfo): pointer; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + DestroyImage: procedure(image: pointer{pImage}); + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + DispatchImage: function(image: pointer{pImage8}; + x_offset: clong; y_offset: clong; + columns: culong; rows: culong; map: pcchar; _type: StorageType; + pixels: pointer; exception: pExceptionInfo): MagickPassFail; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + ConstituteImage: function(width: cuint; height: cuint; + map: pcchar; _type: StorageType; pixels: pointer; + exception: pExceptionInfo): pointer{pImage}; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + ExportImagePixelArea: function(image: pointer{pImage}; + quantum_type: QuantumType; + quantum_size: cuint; destination: pcuchar; + options: pExportPixelAreaOptions; + export_info: pExportPixelAreaInfo): MagickPassFail; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + ImportImagePixelArea: function(image: pointer{pImage}; + quantum_type: QuantumType; + quantum_size: cuint; source: pcuchar; + options: pImportPixelAreaOptions; + import_info: pImportPixelAreaInfo): MagickPassFail; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + ImportPixelAreaOptionsInit: procedure(options: pImportPixelAreaOptions); + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + ExportPixelAreaOptionsInit: procedure(options: pExportPixelAreaOptions); + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + GetImagePixels: function(image: pointer{pImage}; x: clong; y: clong; + columns: culong; rows: culong): pointer{pPixelPacket}; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + SetImagePixels: function(image: pointer{pImage}; x: clong; const y: clong; + columns: culong; rows: culong): pointer{pPixelPacket}; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + SyncImagePixels: function(image: pointer{pImage}): MagickPassFail; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + AllocateImageColormap: function(image: pointer{pImage}; colors: culong): cuint; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + SampleImage: function(image: pointer{pImage}; columns: culong; + rows: culong; exception: pExceptionInfo): pointer{pImage}; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + ScaleImage: function(image: pointer{pImage}; columns: culong; + rows: culong; exception: pExceptionInfo): pointer{pImage}; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + ResizeImage: function(image: pointer{pImage}; columns: culong; rows: culong; + filter: FilterTypes; blur: cdouble; + exception: pExceptionInfo): pointer{pImage}; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + RotateImage: function(image: pointer{pImage}; degrees: cdouble; + exception: pExceptionInfo): pointer{pImage}; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + NewMagickWand: function(): pMagickWand; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + DestroyMagickWand: procedure(wand: pMagickWand); + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + MagickReadImage: function(wand: pMagickWand; filename: pcchar): cuint; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + MagickReadImageBlob: function(wand: pMagickWand; blob: pcuchar; + length: size_t): cuint; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + MagickReadImageFile: function(wand: pMagickWand; _file: pFILE): cuint; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + MagickWriteImage: function(wand: pMagickWand; filename: pcchar): cuint; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + MagickWriteImageFile: function(wand: pMagickWand; _file: pFILE): cuint; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + MagickWriteImageBlob: function(wand: pMagickWand; length: psize_t): cuchar; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + MagickSetFormat: function(wand: pMagickWand; format: pcchar): cuint; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +procedure initializegraphicsmagick(const sonames, + sonameswand: array of filenamety); + //[] = default +procedure releasegraphicsmagick; +function quantumdepth: quantumdepthty; + +procedure reggminit(const initproc: dynlibprocty); +procedure reggmdeinit(const deinitproc: dynlibprocty); +procedure reggmwandinit(const initproc: dynlibprocty); +procedure reggmwanddeinit(const deinitproc: dynlibprocty); + +implementation +uses + mseapplication; + +var + libinfo: dynlibinfoty; + libinfowand: dynlibinfoty; + qdepth: quantumdepthty; + +procedure reggminit(const initproc: dynlibprocty); +begin + regdynlibinit(libinfo,initproc); +end; + +procedure reggmdeinit(const deinitproc: dynlibprocty); +begin + regdynlibdeinit(libinfo,deinitproc); +end; + +procedure reggmwandinit(const initproc: dynlibprocty); +begin + regdynlibinit(libinfowand,initproc); +end; + +procedure reggmwanddeinit(const deinitproc: dynlibprocty); +begin + regdynlibdeinit(libinfowand,deinitproc); +end; + +function quantumdepth: quantumdepthty; +begin + result:= qdepth; +end; + +procedure init(const data: pointer); +var + l1: culong; +begin + initializemagick(pcchar(application.applicationname)); + magickgetquantumdepth(@l1); + case l1 of + 8: begin + qdepth:= qd_8; + end; + 16: begin + qdepth:= qd_16; + end + else begin + qdepth:= qd_32; + end; + end; +end; + +procedure deinit(const data: pointer); +begin + destroymagick(); +end; + +procedure initializegraphicsmagick(const sonames, + sonameswand: array of filenamety); + //[] = default +const + funcs: array[0..29] of funcinfoty = ( +// (n: ''; d: {$ifndef FPC}@{$endif}@), + (n: 'InitializeMagick'; d: {$ifndef FPC}@{$endif}@InitializeMagick), + (n: 'DestroyMagick'; d: {$ifndef FPC}@{$endif}@DestroyMagick), + (n: 'MagickMalloc'; d: {$ifndef FPC}@{$endif}@MagickMalloc), + (n: 'MagickFree'; d: {$ifndef FPC}@{$endif}@MagickFree), + (n: 'ExportImagePixelArea'; d: {$ifndef FPC}@{$endif}@ExportImagePixelArea), + (n: 'PingImage'; d: {$ifndef FPC}@{$endif}@PingImage), + (n: 'ReadImage'; d: {$ifndef FPC}@{$endif}@ReadImage), + (n: 'CloneImageInfo'; d: {$ifndef FPC}@{$endif}@CloneImageInfo), + (n: 'GetExceptionInfo'; d: {$ifndef FPC}@{$endif}@GetExceptionInfo), + (n: 'DestroyExceptionInfo'; d: {$ifndef FPC}@{$endif}@DestroyExceptionInfo), + (n: 'DestroyImage'; d: {$ifndef FPC}@{$endif}@DestroyImage), + (n: 'DispatchImage'; d: {$ifndef FPC}@{$endif}@DispatchImage), + (n: 'PingBlob'; d: {$ifndef FPC}@{$endif}@PingBlob), + (n: 'BlobToImage'; d: {$ifndef FPC}@{$endif}@BlobToImage), + (n: 'ConstituteImage'; d: {$ifndef FPC}@{$endif}@ConstituteImage), + (n: 'ImportImagePixelArea'; d: {$ifndef FPC}@{$endif}@ImportImagePixelArea), + (n: 'ImportPixelAreaOptionsInit'; + d: {$ifndef FPC}@{$endif}@ImportPixelAreaOptionsInit), + (n: 'ExportPixelAreaOptionsInit'; + d: {$ifndef FPC}@{$endif}@ExportPixelAreaOptionsInit), + (n: 'AllocateImage'; d: {$ifndef FPC}@{$endif}@AllocateImage), + (n: 'GetImagePixels'; d: {$ifndef FPC}@{$endif}@GetImagePixels), + (n: 'SetImagePixels'; d: {$ifndef FPC}@{$endif}@SetImagePixels), + (n: 'DestroyImageInfo'; d: {$ifndef FPC}@{$endif}@DestroyImageInfo), + (n: 'WriteImage'; d: {$ifndef FPC}@{$endif}@WriteImage), + (n: 'ImageToBlob'; d: {$ifndef FPC}@{$endif}@ImageToBlob), + (n: 'SyncImagePixels'; d: {$ifndef FPC}@{$endif}@SyncImagePixels), + (n: 'AllocateImageColormap'; + d: {$ifndef FPC}@{$endif}@AllocateImageColormap), + (n: 'ResizeImage'; d: {$ifndef FPC}@{$endif}@ResizeImage), + (n: 'SampleImage'; d: {$ifndef FPC}@{$endif}@SampleImage), + (n: 'ScaleImage'; d: {$ifndef FPC}@{$endif}@ScaleImage), + (n: 'RotateImage'; d: {$ifndef FPC}@{$endif}@RotateImage) + ); + errormessage = 'Can not load GraphicsMagick library. '; + + funcswand: array[0..11] of funcinfoty = ( + (n: 'NewMagickWand'; d: {$ifndef FPC}@{$endif}@NewMagickWand), + (n: 'DestroyMagickWand'; d: {$ifndef FPC}@{$endif}@DestroyMagickWand), + (n: 'MagickGetVersion'; d: {$ifndef FPC}@{$endif}@MagickGetVersion), + (n: 'MagickGetQuantumDepth'; + d: {$ifndef FPC}@{$endif}@MagickGetQuantumDepth), + (n: 'MagickQueryFormats'; d: {$ifndef FPC}@{$endif}@MagickQueryFormats), + (n: 'MagickReadImage'; d: {$ifndef FPC}@{$endif}@MagickReadImage), + (n: 'MagickReadImageBlob'; d: {$ifndef FPC}@{$endif}@MagickReadImageBlob), + (n: 'MagickReadImageFile'; d: {$ifndef FPC}@{$endif}@MagickReadImageFile), + (n: 'MagickWriteImage'; d: {$ifndef FPC}@{$endif}@MagickWriteImage), + (n: 'MagickWriteImageFile'; d: {$ifndef FPC}@{$endif}@MagickWriteImageFile), + (n: 'MagickWriteImageBlob'; d: {$ifndef FPC}@{$endif}@MagickWriteImageBlob), + (n: 'MagickSetFormat'; d: {$ifndef FPC}@{$endif}@MagickSetFormat) + ); + errormessagewand = 'Can not load GraphicsMagickWand library. '; + +begin + initializedynlib(libinfo,sonames,graphicsmagiclib,funcs,[],errormessage,nil); + initializedynlib(libinfowand,sonameswand,graphicsmagicwandlib,funcswand, + [],errormessagewand,@init); +end; + +procedure releasegraphicsmagick; +begin + releasedynlib(libinfowand,@deinit); + releasedynlib(libinfo,@deinit); +end; + +initialization + initializelibinfo(libinfo); + initializelibinfo(libinfowand); +finalization + finalizelibinfo(libinfo); + finalizelibinfo(libinfowand); +end. diff --git a/mseide-msegui/lib/common/image/msegraphicstream.pas b/mseide-msegui/lib/common/image/msegraphicstream.pas new file mode 100644 index 0000000..85b883a --- /dev/null +++ b/mseide-msegui/lib/common/image/msegraphicstream.pas @@ -0,0 +1,933 @@ +{ MSEgui Copyright (c) 2006-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msegraphicstream; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + sysutils,classes,mclasses,msebitmap,msegraphics,fpimage, + msestrings,msetypes; + +const + graphicformatdelimiter = ';'; +type + egraphicformat = class(exception); + + fpreaderclassty = class of tfpcustomimagereader; + + tmsefpmemoryimage = class(tfpmemoryimage) + private + fhasalpha: boolean; + fmonoalpha: boolean; + public + procedure assign(source: tpersistent); override; + procedure assignto(dest: tpersistent); override; + procedure writetostream(const dest: tstream; + const awriter: tfpcustomimagewriter); + //owns the writer + property hasalpha: boolean read fhasalpha; + property monoalpha: boolean read fmonoalpha; + end; + + readgraphicprocty = function(const source: tstream; + const dest: tobject; var format: string; + const params: array of const): boolean; + writegraphicprocty = procedure(const dest: tstream; + const source: tobject; const format: string; + const params: array of const); + +function readgraphic(const source: tstream; const dest: tbitmap; + const aformatname: string = ''; + const params: array of const): string; overload; + //returns formatname +function readgraphic(const source: tstream; const dest: tmaskedbitmap; + const aformatname: string = ''; + const params: array of const): string; overload; + //returns formatname +function readgraphic(const source: tstream; + const dest: timagelist): string; overload; + //returns formatname +function tryreadgraphic(const source: tstream; const dest: tbitmap; + const aformatname: string = ''; + const params: array of const): string; overload; + //returns format name, '' = unknown/not supported + //exception in case of read error +function tryreadgraphic(const source: tstream; const dest: tmaskedbitmap; + const aformatname: string = ''; + const params: array of const): string; overload; + //returns format name, '' = unknown/not supported + //exception in case of read error +function tryreadgraphic(const source: tstream; + const dest: timagelist): string; overload; + //returns format name, '' = unknown/not supported + //exception in case of read error + +procedure writegraphic(const dest: tstream; const source: tbitmap; + const aformatname: string; + const params: array of const); overload; +procedure writegraphic(const dest: tstream; const source: tmaskedbitmap; + const aformatname: string; + const params: array of const); overload; +procedure writegraphic(const dest: tstream; const source: timagelist); overload; + //for ico + +procedure registergraphicformat(const aformatlabel: string; + const areadproc: readgraphicprocty; + const awriteproc: writegraphicprocty; + const afiltername: msestring; + const afilemask: array of msestring); +function graphicformatlabels: stringarty; +function graphicfilemasks: filenamearty; +function graphicfilefilternames: msestringarty; +function graphicfilefiltermasks: msestringarty; +function graphicfilefilterlabel(const index: integer): string; + +function readfpgraphic(const source: tstream; const readerclass: fpreaderclassty; + const dest: tpersistent): boolean; + +implementation +uses + msestockobjects,msegraphutils,msearrayutils; + +type + tmaskedbitmap1 = class(tmaskedbitmap); + + graphicformatinfoty = record + formatlabel: string; + readproc: readgraphicprocty; + writeproc: writegraphicprocty; + filtername: msestring; + filemask: msestringarty; + end; + graphicformatinfoarty = array of graphicformatinfoty; + +var + formats: graphicformatinfoarty; + +function order: integerarty; +var + ar1: msestringarty; + int1: integer; +begin + setlength(ar1,length(formats)); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= formats[int1].filtername; + end; + sortarray(ar1,sms_upi,result); +end; + +function graphicformatlabels: stringarty; +var + ar1: stringarty; + int1: integer; +begin + setlength(ar1,length(formats)); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= formats[int1].formatlabel; + end; + orderarray(order,ar1); + setlength(result,1); + result[0]:= ''; + stackarray(ar1,result); +end; + +function graphicfilefilterlabel(const index: integer): string; +var + ar1: stringarty; +begin + ar1:= graphicformatlabels; + if (index < 0) or (index > high(ar1)) then begin + result:= ''; + end + else begin + result:= ar1[index]; + end; +end; + +function graphicfilefilternames: msestringarty; +var + ar1: msestringarty; + int1: integer; +begin + setlength(ar1,length(formats)); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= formats[int1].filtername; + end; + orderarray(order,ar1); + setlength(result,1); + result[0]:= stockobjects.captions[sc_All]; + stackarray(ar1,result); +end; + +function graphicfilefiltermasks: msestringarty; +var + ar1: msestringararty; + int1,int2: integer; + ar2: msestringarty; +begin + setlength(ar1,length(formats)); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= formats[int1].filemask; + end; + orderarray(order,ar1,sizeof(ar1[0])); + setlength(result,1); + for int1:= 0 to high(ar1) do begin + for int2:= 0 to high(ar1[int1]) do begin + result[0]:= result[0]+'"'+ar1[int1][int2]+'" '; + end; + end; + if result[0] <> '' then begin + setlength(result[0],length(result[0])-1); + end; + setlength(ar2,length(ar1)); + for int1:= 0 to high(ar2) do begin + if high(ar1[int1]) > 0 then begin + for int2:= 0 to high(ar1[int1]) do begin + ar2[int1]:= ar2[int1] + '"' + ar1[int1][int2] + '" '; + end; + setlength(ar2[int1],length(ar2[int1])-1); + end + else begin + if ar1[int1] <> nil then begin + ar2[int1]:= ar1[int1][0]; + end; + end; + end; + setlength(result,1+length(ar2)); + for int1:= 0 to high(ar2) do begin + result[int1+1]:= ar2[int1]; + end; +end; + +function graphicfilemasks: filenamearty; +var + co: integer; + int1,int2: integer; +begin + co:= 0; + for int1:= 0 to high(formats) do begin + for int2:= 0 to high(formats[int1].filemask) do begin + additem(result,formats[int1].filemask[int2],co); + end; + end; + setlength(result,co); +end; + +procedure formaterror(const text,format: string); +var + str1: string; +begin + str1:= text; + if format <> '' then begin + str1:= str1 + ': '+format; + end; + str1:= str1 + '.'; + raise egraphicformat.create(str1); +end; + +procedure registergraphicformat(const aformatlabel: string; + const areadproc: readgraphicprocty; + const awriteproc: writegraphicprocty; + const afiltername: msestring; + const afilemask: array of msestring); +var + int1,int2: integer; +begin + int2:= -1; + for int1:= 0 to high(formats) do begin + if formats[int1].formatlabel = aformatlabel then begin + int2:= int1; + break; + end; + end; + if int2 < 0 then begin + setlength(formats,high(formats) + 2); + int2:= high(formats); + end; + with formats[int2] do begin + formatlabel:= aformatlabel; + if {$ifndef FPC}@{$endif}areadproc <> nil then begin + readproc:= areadproc; + end; + if {$ifndef FPC}@{$endif}awriteproc <> nil then begin + writeproc:= awriteproc; + end; + filtername:= afiltername; + setlength(filemask,length(afilemask)); + for int1:= 0 to high(filemask) do begin + filemask[int1]:= afilemask[int1]; + end; + end; +end; + +function readgraphic1(const atry: boolean; const source: tstream; + const adest: tobject; const aformatlabel: string; + const params: array of const): string; + //index = select image in ico format +var + int1,int3: integer; + ar1: stringarty; + found: boolean; + str1: string; +begin + result:= ''; + ar1:= nil; //compiler warning + if aformatlabel = '' then begin + found:= high(formats) >= 0; + for int1:= 0 to high(formats) do begin + with formats[int1] do begin + if assigned(readproc) then begin + str1:= formats[int1].formatlabel; + if readproc(source,adest,str1,params) then begin + result:= str1; + exit; + end; + source.position:= 0; + end; + end; + end; + end + else begin + found:= false; + ar1:= splitstring(aformatlabel,graphicformatdelimiter); + for int3:= 0 to high(ar1) do begin + for int1:= 0 to high(formats) do begin + with formats[int1] do begin + if (formatlabel = ar1[int3]) then begin + found:= true; + if assigned(readproc) then begin + str1:= formats[int1].formatlabel; + if readproc(source,adest,str1,params) then begin + result:= str1; + exit; + end; + end; + break; + end; + end; + end; + end; + end; + if not atry then begin + if not found then begin + formaterror( + ansistring(stockobjects.captions[sc_graphic_format_not_supported]), + aformatlabel); + end + else begin + formaterror(ansistring(stockobjects.captions[sc_graphic_format_error]), + aformatlabel); + end; + end; +end; + +procedure writegraphic1(const dest: tstream; const asource: tobject; + const aformatlabel: string; const params: array of const); +var + int1,int2: integer; +begin + int2:= -1; + for int1:= 0 to high(formats) do begin + with formats[int1] do begin + if (formatlabel = aformatlabel) then begin + if assigned(writeproc) then begin + int2:= int1; + end; + break; + end; + end; + end; + if int2 < 0 then begin + formaterror( + ansistring(stockobjects.captions[sc_graphic_format_not_supported]), + aformatlabel); + end; + with formats[int2] do begin + writeproc(dest,asource,aformatlabel,params); + end; +end; + +function readgraphic(const source: tstream; const dest: tbitmap; + const aformatname: string = ''; + const params: array of const): string; overload; +begin + result:= readgraphic1(false,source,dest,aformatname,params); +end; + +function readgraphic(const source: tstream; const dest: tmaskedbitmap; + const aformatname: string = ''; + const params: array of const): string; overload; + //index = select image in ico format +begin + result:= readgraphic1(false,source,dest,aformatname,params); +end; + +function readgraphic(const source: tstream; + const dest: timagelist): string; overload; +begin + result:= readgraphic1(false,source,dest,'ico',[-1]); +end; + +function tryreadgraphic(const source: tstream; const dest: tbitmap; + const aformatname: string = ''; + const params: array of const): string; overload; +begin + result:= readgraphic1(true,source,dest,aformatname,params); +end; + +function tryreadgraphic(const source: tstream; const dest: tmaskedbitmap; + const aformatname: string = ''; + const params: array of const): string; overload; + //index = select image in ico format +begin + result:= readgraphic1(true,source,dest,aformatname,params); +end; + +function tryreadgraphic(const source: tstream; + const dest: timagelist): string; overload; +begin + result:= readgraphic1(true,source,dest,'ico',[-1]); +end; + +procedure writegraphic(const dest: tstream; const source: tbitmap; + const aformatname: string; + const params: array of const); overload; +begin + writegraphic1(dest,source,aformatname,params); +end; + +procedure writegraphic(const dest: tstream; const source: tmaskedbitmap; + const aformatname: string; + const params: array of const); overload; + +begin + writegraphic1(dest,source,aformatname,params); +end; + +procedure writegraphic(const dest: tstream; const source: timagelist); overload; + //index = select image in ico format +begin + writegraphic1(dest,source,'ico',[]); +end; + +function readfpgraphic(const source: tstream; const readerclass: fpreaderclassty; + const dest: tpersistent): boolean; +var + reader: tfpcustomimagereader; + img: tmsefpmemoryimage; + int1: integer; +begin + result:= false; + reader:= readerclass.create; + try + int1:= source.position; + if reader.checkcontents(source) then begin + img:= tmsefpmemoryimage.create(0,0); + img.usepalette:= false; + try + source.position:= int1; + reader.imageread(source,img); + dest.assign(img); + result:= true; + finally + img.free; + end; + end + else begin + source.position:= int1; + end; + finally + reader.free; + end; +end; + +{ tmsefpmemoryimage } + +procedure tmsefpmemoryimage.writetostream(const dest: tstream; + const awriter: tfpcustomimagewriter); + //owns the writer +begin + try + savetostream(dest,awriter); + finally + awriter.free; + end; +end; + +procedure tmsefpmemoryimage.assign(source: tpersistent); + function to16(const acolor: colorty): tfpcolor; + var + rgb1: rgbtriplety; + begin + rgb1:= colortorgb(acolor); + result.red:= rgb1.red + (rgb1.red shl 8); + result.green:= rgb1.green + (rgb1.green shl 8); + result.blue:= rgb1.blue + (rgb1.blue shl 8); + result.alpha:= 0; + end; +var + col1,col0,col3: tfpcolor; + int1,int2: integer; + wo1: word; + lwo1: longword; + masked1: boolean; + maskkind1: bitmapkindty; + pimageline,pmaskline: pointer; + pi,pm: pointer; + imagestep,maskstep: integer; +begin + if source is tbitmap then begin + setsize(0,0); //clear + masked1:= source is tmaskedbitmap; + if masked1 then begin + with tmaskedbitmap(source) do begin + masked1:= masked; + if masked1 then begin + with mask do begin + maskkind1:= mask.kind; + fmonoalpha:= maskkind1 = bmk_mono; + pmaskline:= scanline[0]; + maskstep:= scanlinestep; + end; + end; + end; + end; + fhasalpha:= masked1; + with tbitmap(source) do begin + pimageline:= scanline[0]; + imagestep:= scanlinestep; + self.setsize(width,height); + usepalette:= false; + col3.alpha:= 0; + case kind of + bmk_mono: begin //mono + col0:= to16(colorbackground); + col1:= to16(colorforeground); + usepalette:= true; + if masked1 then begin + case maskkind1 of + bmk_mono: begin //mono monmask + for int1:= 0 to height - 1 do begin + pi:= pimageline; + pm:= pmaskline; + lwo1:= $00000001; + for int2:= 0 to width-1 do begin + if plongword(pi)^ and lwo1 <> 0 then begin + if plongword(pm)^ and lwo1 <> 0 then begin + col1.alpha:= $ffff; + end + else begin + col1.alpha:= $0000; + end; + colors[int2,int1]:= col1; + end + else begin + if plongword(pm)^ and lwo1 <> 0 then begin + col0.alpha:= $ffff; + end + else begin + col0.alpha:= $0000; + end; + colors[int2,int1]:= col0; + end; + lwo1:= lwo1 shl 1; + if lwo1 = 0 then begin + inc(plongword(pi)); + inc(plongword(pm)); + lwo1:= $00000001; + end; + end; + inc(pimageline,imagestep); + inc(pmaskline,maskstep); + end; + end; + bmk_gray: begin //mono graymask + for int1:= 0 to height - 1 do begin + pi:= pimageline; + pm:= pmaskline; + lwo1:= $00000001; + for int2:= 0 to width-1 do begin + if plongword(pi)^ and lwo1 <> 0 then begin + wo1:= pbyte(pm)^; + col1.alpha:= wo1 or (wo1 shl 8); + colors[int2,int1]:= col1; + end + else begin + wo1:= pbyte(pm)^; + col1.alpha:= wo1 or (wo1 shl 8); + colors[int2,int1]:= col0; + end; + lwo1:= lwo1 shl 1; + inc(pbyte(pm)); + if lwo1 = 0 then begin + inc(plongword(pi)); + lwo1:= $00000001; + end; + end; + inc(pimageline,imagestep); + inc(pmaskline,maskstep); + end; + end; + else begin //mono rgbmask + for int1:= 0 to height - 1 do begin + pi:= pimageline; + pm:= pmaskline; + lwo1:= $00000001; + for int2:= 0 to width-1 do begin + if plongword(pi)^ and lwo1 <> 0 then begin + wo1:= (word(prgbtriplety(pm)^.red)+ + word(prgbtriplety(pm)^.green)+ + word(prgbtriplety(pm)^.blue)) div 3; + col1.alpha:= wo1 or (wo1 shl 8); + colors[int1,int2]:= col1; + end + else begin + wo1:= (word(prgbtriplety(pm)^.red)+ + word(prgbtriplety(pm)^.green)+ + word(prgbtriplety(pm)^.blue)) div 3; + col0.alpha:= wo1 or (wo1 shl 8); + colors[int2,int1]:= col0; + end; + lwo1:= lwo1 shl 1; + if lwo1 = 0 then begin + inc(plongword(pi)); + lwo1:= $00000001; + end; + inc(plongword(pm)); + end; + inc(pimageline,imagestep); + inc(pmaskline,maskstep); + end; + end; + end; + end + else begin //mono unmasked + for int1:= 0 to height - 1 do begin + pi:= pimageline; + lwo1:= $00000001; + for int2:= 0 to width-1 do begin + if plongword(pi)^ and lwo1 <> 0 then begin + colors[int2,int1]:= col1; + end + else begin + colors[int2,int1]:= col0; + end; + lwo1:= lwo1 shl 1; + if lwo1 = 0 then begin + inc(plongword(pm)); + lwo1:= $00000001; + end; + end; + inc(pimageline,imagestep); + end; + end; + end; + bmk_gray: begin + if masked1 then begin + case maskkind1 of + bmk_mono: begin //gray monomask + for int1:= 0 to height - 1 do begin + pi:= pimageline; + pm:= pmaskline; + lwo1:= $00000001; + for int2:= 0 to width - 1 do begin + wo1:= pbyte(pi)^; + wo1:= wo1 shl 8; + col3.red:= wo1; + col3.green:= wo1; + col3.blue:= wo1; + if plongword(pm)^ and lwo1 <> 0 then begin + col3.alpha:= $ffff; + end + else begin + col3.alpha:= $0000; + end; + colors[int2,int1]:= col3; + inc(pbyte(pi)); + lwo1:= lwo1 shl 1; + if lwo1 = 0 then begin + inc(plongword(pm)); + lwo1:= $00000001; + end; + end; + inc(pimageline,imagestep); + inc(pmaskline,maskstep); + end; + end; + bmk_gray: begin //gray graymask + for int1:= 0 to height - 1 do begin + pi:= pimageline; + pm:= pmaskline; + for int2:= 0 to width - 1 do begin + wo1:= pbyte(pi)^; + wo1:= wo1 shl 8; + col3.red:= wo1; + col3.green:= wo1; + col3.blue:= wo1; + wo1:= pbyte(pm)^; + col3.alpha:= wo1 or (wo1 shl 8); + colors[int2,int1]:= col3; + inc(pbyte(pi)); + inc(pbyte(pm)); + end; + inc(pimageline,imagestep); + inc(pmaskline,maskstep); + end; + end; + else begin //gray colormask + for int1:= 0 to height - 1 do begin + pi:= pimageline; + pm:= pmaskline; + for int2:= 0 to width - 1 do begin + wo1:= pbyte(pi)^; + wo1:= wo1 shl 8; + col3.red:= wo1; + col3.green:= wo1; + col3.blue:= wo1; + wo1:= (prgbtriplety(pm)^.red + prgbtriplety(pm)^.green + + prgbtriplety(pm)^.blue) div 3; + col3.alpha:= wo1 or (wo1 shl 8); + colors[int2,int1]:= col3; + inc(pbyte(pi)); + inc(prgbtriplety(pm)); + end; + inc(pimageline,imagestep); + inc(pmaskline,maskstep); + end; + end; + end; + end + else begin //gray unmasked + for int1:= 0 to height - 1 do begin + pi:= pimageline; + for int2:= 0 to width - 1 do begin + wo1:= pbyte(pi)^; + wo1:= wo1 shl 8; + col3.red:= wo1; + col3.green:= wo1; + col3.blue:= wo1; + colors[int2,int1]:= col3; + inc(pbyte(pi)); + end; + inc(pimageline,imagestep); + end; + end; + end; + else begin //bmk_rgb + if masked1 then begin + case maskkind1 of + bmk_mono: begin //color monomask + for int1:= 0 to height - 1 do begin + pi:= pimageline; + pm:= pmaskline; + lwo1:= $00000001; + for int2:= 0 to width - 1 do begin + wo1:= prgbtriplety(pi)^.red; + col3.red:= wo1 or wo1 shl 8; + wo1:= prgbtriplety(pi)^.green; + col3.green:= wo1 or wo1 shl 8; + wo1:= prgbtriplety(pi)^.blue; + col3.blue:= wo1 or wo1 shl 8; + if plongword(pm)^ and lwo1 <> 0 then begin + col3.alpha:= $ffff; + end + else begin + col3.alpha:= $0000; + end; + colors[int2,int1]:= col3; + inc(plongword(pi)); + lwo1:= lwo1 shl 1; + if lwo1 = 0 then begin + inc(plongword(pm)); + lwo1:= $00000001; + end; + end; + inc(pimageline,imagestep); + inc(pmaskline,maskstep); + end; + end; + bmk_gray: begin //color graymask + for int1:= 0 to height - 1 do begin + pi:= pimageline; + pm:= pmaskline; + for int2:= 0 to width - 1 do begin + wo1:= (prgbtriplety(pi)^.red); + col3.red:= wo1 or (wo1 shl 8); + wo1:= (prgbtriplety(pi)^.green); + col3.green:= wo1 or (wo1 shl 8); + wo1:= (prgbtriplety(pi)^.blue); + col3.blue:= wo1 or (wo1 shl 8); + wo1:= pbyte(pm)^; + col3.alpha:= wo1 or (wo1 shl 8); + colors[int2,int1]:= col3; + inc(prgbtriplety(pi)); + inc(pbyte(pm)); + end; + inc(pimageline,imagestep); + inc(pmaskline,maskstep); + end; + end; + else begin //color colormask + for int1:= 0 to height - 1 do begin + pi:= pimageline; + pm:= pmaskline; + for int2:= 0 to width - 1 do begin + wo1:= (prgbtriplety(pi)^.red); + col3.red:= wo1 or (wo1 shl 8); + wo1:= (prgbtriplety(pi)^.green); + col3.green:= wo1 or (wo1 shl 8); + wo1:= (prgbtriplety(pi)^.blue); + col3.blue:= wo1 or (wo1 shl 8); + wo1:= (prgbtriplety(pm)^.red + prgbtriplety(pm)^.green + + prgbtriplety(pm)^.blue) div 3; + col3.alpha:= wo1 or (wo1 shl 8); + colors[int2,int1]:= col3; + inc(prgbtriplety(pi)); + inc(prgbtriplety(pm)); + end; + inc(pimageline,imagestep); + inc(pmaskline,maskstep); + end; + end; + end; + end + else begin //color unmasked + for int1:= 0 to height - 1 do begin + pi:= pimageline; + for int2:= 0 to width - 1 do begin + wo1:= (prgbtriplety(pi)^.red); + col3.red:= wo1 or (wo1 shl 8); + wo1:= (prgbtriplety(pi)^.green); + col3.green:= wo1 or (wo1 shl 8); + wo1:= (prgbtriplety(pi)^.blue); + col3.blue:= wo1 or (wo1 shl 8); + colors[int2,int1]:= col3; + inc(prgbtriplety(pi)); + end; + inc(pimageline,imagestep); + end; + end; + end; + end; + end; + end + else begin + inherited; + end; +end; + +procedure tmsefpmemoryimage.assignto(dest: tpersistent); + +var + grayalpha1: boolean; + + function getmaskdata(ashift: word): boolean; + var + int1,int2,int3: integer; + bo1,bo2: boolean; +// po1: prgbtripleaty; + po1: pbyte; + by1: byte; + begin + bo1:= false; + bo2:= false; + with tmaskedbitmap1(dest) do begin + with fmask do begin + po1:= scanline[0]; + int3:= scanlinestep; + end; + for int1:= 0 to height - 1 do begin + for int2:= 0 to width - 1 do begin + by1:= colors[int2,int1].alpha shr ashift; + bo1:= bo1 or ((by1 < 255) and (by1 > 0)); + bo2:= bo2 and (by1 <> 0); + po1[int2]:= by1; + { + with po1^[int2] do begin + red:= by1; + green:= by1; + blue:= by1; + res:= 0; + end; + } + end; + inc(po1,int3); + end; + end; + grayalpha1:= bo1; + result:= bo2; + end; + +var + int1,int2,int3: integer; + po1: prgbtripleaty; + col1: tfpcolor; + col2: colorty; + bo1: boolean; + ismaskedbitmap: boolean; +begin + if dest is tbitmap then begin + ismaskedbitmap:= dest is tmaskedbitmap; + try + with tbitmap(dest) do begin + beginupdate(); + if ismaskedbitmap then begin + tmaskedbitmap(dest).masked:= false; + end; + clear(); + kind:= bmk_rgb; + size:= makesize(self.width,self.height); + bo1:= false; + po1:= scanline[0]; + int3:= scanlinestep; + for int1:= 0 to height - 1 do begin + for int2:= 0 to width - 1 do begin + col1:= colors[int2,int1]; + with po1^[int2] do begin + red:= col1.red shr 8; + green:= col1.green shr 8; + blue:= col1.blue shr 8; + res:= 0; + bo1:= bo1 or (col1.alpha < $ff00); + end; + end; + inc(pointer(po1),int3); + end; + fhasalpha:= bo1; + fmonoalpha:= false; + if ismaskedbitmap then begin + with tmaskedbitmap1(dest) do begin + if self.hasalpha then begin + graymask:= true; + include(foptions,bmo_masked); + createmask(bmk_gray); + fmask.size:= size; + include(fstate,pms_maskvalid); + if not getmaskdata(8) then begin + getmaskdata(0); //try 8 bit + end; + col2:= maskcolorbackground; + maskcolorbackground:= 0; + graymask:= grayalpha1; + fmonoalpha:= not grayalpha1; + maskcolorbackground:= col2; + include(foptions,bmo_masked); + end; + end; + end; + change; + end; + finally + tmaskedbitmap(dest).endupdate(); + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/image/msemagickstream.pas b/mseide-msegui/lib/common/image/msemagickstream.pas new file mode 100644 index 0000000..cfb9f52 --- /dev/null +++ b/mseide-msegui/lib/common/image/msemagickstream.pas @@ -0,0 +1,1148 @@ +{ MSEgui Copyright (c) 2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msemagickstream; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes{msestrings},msegraphicsmagick,sysutils,mclasses,msebitmap,msegraphutils; +const + defaultblur = 1.0; +type + tmagickexception = class(exception) + public + constructor create(const ainfo: exceptioninfo); + end; + gminfoty = record + formatlabel: string; + size: sizety; + depth: integer; + end; + gmoptionty = ( + rgmo_rotmonomask, + rgmo_rotbeforescale, //rotate before scaling + rgmo_rotafterscale, //rotate after scaling + rgmo_sample, //use SampleImage() instead of ScaleImage() + rgmo_resize //use ResizeImage() with filtertype instead of ScaleImage() + ); + gmoptionsty = set of gmoptionty; + +procedure registerformats(const labels: array of string; + const filternames: array of msestring; + const filemasks: array of msestringarty); +//readgraphic parameters: + //[index: integer, width: integer, height: integer, rotation: real, + //sequence nr 0 = default 0 = default 0..2pi CCW + // -1 = default + // backgroundcolor: colorty, pixelpermm: real, options: gmoptionsty, + // default = cl_transparent 0 = default default = [] + // filter: filtertypes, blur: real] + // default = UndefinedFilter default = 1 + +//writegraphic parameters: + //[compressionquality: integer, width: integer, height: integer, + // 0..100, -1 = default 0 = default 0 = default + // rotation: real, backgroundcolor: colorty, pixelpermm: real, + // 0..2pi CCW default 0 default = cl_transparent 0 = default + // options: gmoptionsty filter: filtertypes, blur: real] + // default = [] default = UndefinedFilter default = 1 + +function readgmgraphic(const source: tstream; const dest: tbitmap; + const aindex: integer = -1; const awidth: integer = 0; + const aheight: integer = 0; const arotation: real = 0; + const abackgroundcolor: colorty = cl_transparent; + const apixelpermm: real = 0; + const aoptions: gmoptionsty = []; + const afilter: filtertypes = undefinedfilter; + const ablur: real = defaultblur): string; + //returns label +procedure writegmgraphic(const dest: tstream; const source: tbitmap; + const format: string; const aquality: integer = -1; + const awidth: integer = 0; const aheight: integer = 0; + const arotation: real = 0; + const abackgroundcolor: colorty = cl_transparent; + const apixelpermm: real = 0; + const aoptions: gmoptionsty = []; + const afilter: filtertypes = undefinedfilter; + const ablur: real = defaultblur); +function pinggmgraphic(const source: tstream; + out ainfo: gminfoty): boolean; + +implementation +uses + msegraphics,msegraphicstream,msestream,msestockobjects, + msectypes,msebits,mseclasses,mseformatstr,math; + +type + tbitmap1 = class(tbitmap); +const + ppmmtoppi = 25.4; +var + inited: boolean; + qdepth: quantumdepthty; + +procedure checkinit; +begin + if not inited then begin + initializegraphicsmagick([],[]); + qdepth:= quantumdepth(); + inited:= true; + end; +end; + +function checksnap90(const arotation: double): boolean; +begin + result:= (abs(frac(arotation / (pi/2.0))) < 0.0000001); +end; + +function snap90(const arotation: double): double; +begin + result:= arotation*(-180/pi); + if checksnap90(arotation) then begin + result:= round(result); + end; +end; + +procedure setcolor(const acolor: colorty; const dest: pointer; + const index: integer = 0); +var + rgb: rgbtriplety; + opac: card32; +begin + if acolor = cl_transparent then begin + opac:= $ffffffff; + end + else begin + opac:= 0; + end; + rgb:= colortorgb(acolor); + case qdepth of + qd_8: begin + with ppixelpacket8(dest)[index] do begin + red:= rgb.red; + green:= rgb.green; + blue:= rgb.blue; + opacity:= opac; + end; + end; + qd_16: begin + with ppixelpacket16(dest)[index] do begin + red:= rgb.red + (rgb.red shl 8); + green:= rgb.green + (rgb.green shl 8); + blue:= rgb.blue + (rgb.blue shl 8); + opacity:= opac; + end; + end; + qd_32: begin + with ppixelpacket32(dest)[index] do begin + red:= rgb.red + (rgb.red shl 8)+ (rgb.red shl 16)+ (rgb.red shl 24); + green:= rgb.green + (rgb.green shl 8) + (rgb.green shl 16) + + (rgb.green shl 24); + blue:= rgb.blue + (rgb.blue shl 8) + (rgb.blue shl 16) + (rgb.blue shl 24); + opacity:= opac; + end; + end; + end; +end; + +procedure setimagebackgroundcolor(const image: pointer; color: colorty); +begin + case qdepth of + qd_8: begin + with pimage8(image)^ do begin + setcolor(color,@b.background_color); + end; + end; + qd_16: begin + with pimage16(image)^ do begin + setcolor(color,@b.background_color); + end; + end; + else begin + with pimage32(image)^ do begin + setcolor(color,@b.background_color); + end; + end; + end; +end; + +procedure swapbits(var aimage: imagety); +var + po1,e: pbyte; +begin + with aimage do begin + po1:= pointer(pixels); + e:= po1 + length*4-1; + repeat + po1^:= bitreverse[po1^]; + inc(po1); + until po1 = e; + end; +end; + +function gmstring(const avalue: string): pcchar; +begin + result:= magickmalloc(length(avalue)+1); + move(pchar(avalue)^,result^,length(avalue)+1); +end; + +function rotrect(const avalue: sizety; const rotation: real): dpointty; + //calculate rotated dimensions + //todo: simplify +var + si1,co1: double; + minx: double = 0; + maxx: double = 0; + miny: double = 0; + maxy: double = 0; + + procedure rot(var p: dpointty); + var + x,y: double; + begin + x:= p.x * co1 + p.y * si1; + y:= -p.x * si1 + p.y * co1; + p.x:= x; + p.y:= y; + end; //rot + + procedure checkmax(var p: dpointty); + begin + if p.x < minx then begin + minx:= p.x; + end; + if p.y < miny then begin + miny:= p.y; + end; + if p.x > maxx then begin + maxx:= p.x; + end; + if p.y > maxy then begin + maxy:= p.y; + end; + end; //checkmax + +var + points: array[0..2] of dpointty; + int1: integer; + +begin + if rotation <> 0.0 then begin + si1:= sin(rotation); //todo: simplify + co1:= cos(rotation); + fillchar(points,sizeof(points),0); + points[0].x:= avalue.cx; + points[1].y:= avalue.cy; + points[2].x:= avalue.cx; + points[2].y:= avalue.cy; + for int1:= 0 to high(points) do begin + rot(points[int1]); + end; + for int1:= 0 to high(points) do begin + checkmax(points[int1]); + end; + result.x:= maxx-minx; + result.y:= maxy-miny; + end + else begin + result.x:= avalue.cx; + result.y:= avalue.cy; + end; +end; + +function fitscale(const width: integer; const height: integer; + const current: sizety; out dest: sizety; + const rotation: real; const rotafter: boolean; + const rotcurrent: dpointty): boolean; + //true if scaling necessary +var + {rotcurrent,}rotdest: dpointty; + sca1: double; +begin + dest:= current; + result:= (current.cx > 0) and (current.cy > 0); + if result then begin + if rotafter and (rotation <> 0) then begin + { + si1:= sin(rotation); //todo: simplify + co1:= cos(rotation); + fillchar(points,sizeof(points),0); + points[0].x:= current.cx; + points[1].y:= current.cy; + points[2].x:= current.cx; + points[2].y:= current.cy; + for int1:= 0 to high(points) do begin + rot(points[int1]); + end; + for int1:= 0 to high(points) do begin + checkmax(points[int1]); + end; + rotcurrent.x:= maxx-minx; + rotcurrent.y:= maxy-miny; + } + rotdest:= rotcurrent; + if width <> 0 then begin + rotdest.x:= width; + end; + if height <> 0 then begin + rotdest.y:= height; + end; + if rotdest.x*rotcurrent.y > rotdest.y*rotcurrent.x then begin + rotdest.x:= (rotcurrent.x*rotdest.y) / rotcurrent.y; + sca1:= rotdest.x/rotcurrent.x; + end + else begin + rotdest.y:= (rotcurrent.y*rotdest.x) / rotcurrent.x; + sca1:= rotdest.y/rotcurrent.y; + end; + dest.cx:= round(current.cx*sca1); + dest.cy:= round(current.cy*sca1); + end + else begin //scale to fit in destrect + if width <> 0 then begin + dest.cx:= width; + end; + if height <> 0 then begin + dest.cy:= height; + end; + if dest.cx*current.cy > dest.cy*current.cx then begin + dest.cx:= (current.cx*dest.cy) div current.cy; + end + else begin + dest.cy:= (current.cy*dest.cx) div current.cx; + end; + end; + result:= (current.cx <> dest.cx) or (current.cy <> dest.cy); + end; +end; + +function checkrotafter(const asize: sizety; const awidth: integer; + const aheight: integer; const aoptions: gmoptionsty; + const rotation: real; out rotcurrent: dpointty): boolean; +var + si1: sizety; +begin + rotcurrent:= rotrect(asize,rotation); + if rgmo_rotbeforescale in aoptions then begin + result:= false; + end + else begin + if rgmo_rotafterscale in aoptions then begin + result:= true; + end + else begin + si1:= asize; + if awidth <> 0 then begin + si1.cx:= awidth; + end; + if aheight <> 0 then begin + si1.cy:= aheight; + end; + result:= (si1.cx < rotcurrent.x) or (si1.cy < rotcurrent.y); + end; + end; +end; + +procedure writegmgraphic(const dest: tstream; const source: tbitmap; + const format: string; const aquality: integer = -1; + const awidth: integer = 0; const aheight: integer = 0; + const arotation: real = 0; + const abackgroundcolor: colorty = cl_transparent; + const apixelpermm: real = 0; + const aoptions: gmoptionsty = []; + const afilter: filtertypes = undefinedfilter; + const ablur: real = defaultblur); +var + exceptinf: exceptioninfo; + image,image2: pointer; + hasmask,monomask,rotmask: boolean; + si1,si2: sizety; + imagebuffer: maskedimagety; + buf: pointer; + maskscanstep: integer; + maskscanpo: pointer; + rotcurrent: dpointty; + + procedure error; + begin + raise tmagickexception.create(exceptinf); + end; + + procedure dorotate(); + begin + if arotation <> 0 then begin + image2:= rotateimage(image,snap90(arotation),@exceptinf); + if image2 = nil then begin + exit; + end; + destroyimage(image); + image:= image2; + if rotmask then begin + pimage8(image)^.a.matte:= magicktrue; + end; + si1:= ms(pimage8(image)^.a.columns,pimage8(image)^.a.rows); + end; + end; //dorotate + + procedure doscale(const rotafter: boolean); + begin + if fitscale(awidth,aheight,si1,si2,arotation,rotafter,rotcurrent) then begin + if rgmo_sample in aoptions then begin + image2:= sampleimage(image,si2.cx,si2.cy,@exceptinf); + end + else begin + if rgmo_resize in aoptions then begin + image2:= resizeimage(image,si2.cx,si2.cy,afilter,ablur,@exceptinf); + end + else begin + image2:= scaleimage(image,si2.cx,si2.cy,@exceptinf); + end; + end; + if image2 = nil then begin + exit; + end; + destroyimage(image); + image:= image2; + si1:= ms(pimage8(image)^.a.columns,pimage8(image)^.a.rows); + end; + end; //doscale + + procedure checkcolormask(); + var + d,e: pbyte; + s: prgbtriplety; + begin + with imagebuffer.mask do begin + if kind = bmk_rgb then begin + getmem(buf,length); + d:= buf; + e:= buf + length; + s:= pointer(imagebuffer.mask.pixels); + maskscanpo:= buf; + maskscanstep:= imagebuffer.mask.size.cx; + repeat + d^:= (word(s^.red) + word(s^.green) + word(s^.blue)) div 3; + inc(s); + inc(d); + until d = e; + end + else begin + maskscanpo:= imagebuffer.mask.pixels; + maskscanstep:= imagebuffer.mask.linebytes; + end; + end; + if monomask then begin + swapbits(imagebuffer.mask); + end; + end; + +var + bo1,bo2: boolean; + imageinfo: pointer; + si: size_t; + blob: pointer; + int1: integer; + po1,po2: pointer; + s,d,e,e1: prgbtriplety; + sw1,sw2: plongword; + sb1: pbyte; + lwo1: longword; + +begin + if source is tbitmap then begin + with tbitmap1(source) do begin + if hasimage then begin + checkinit; + getexceptioninfo(@exceptinf); + imageinfo:= nil; + image:= nil; + blob:= nil; + buf:= nil; + try + rotmask:= (abackgroundcolor = cl_transparent) and + not checksnap90(arotation); + monomask:= false; + hasmask:= (source is tmaskedbitmap) and (tmaskedbitmap(source).masked); + bo1:= getimageref(imagebuffer.image); + bo2:= false; + if hasmask then begin + bo2:= tbitmap1(tmaskedbitmap(source).mask).getimageref(imagebuffer.mask); + monomask:= imagebuffer.mask.kind = bmk_mono; + end; + case imagebuffer.image.kind of + bmk_mono: begin //mono + imageinfo:= cloneimageinfo(nil); + image:= allocateimage(imageinfo); + allocateimagecolormap(image,2); + with pimage8(image)^ do begin + a.storage_class:= pseudoclass; + a.columns:= imagebuffer.image.size.cx; + a.rows:= imagebuffer.image.size.cy; + a.depth:= 1; + if hasmask then begin + a.matte:= magicktrue; + checkcolormask(); + end; + end; + case qdepth of + qd_8: begin + with pimage8(image)^ do begin + setcolor(colorbackground,b.colormap,0); + setcolor(colorforeground,b.colormap,1); + end; + end; + qd_16: begin + with pimage16(image)^ do begin + setcolor(colorbackground,b.colormap,0); + setcolor(colorforeground,b.colormap,1); + end; + end; + else begin + with pimage32(image)^ do begin + setcolor(colorbackground,b.colormap,0); + setcolor(colorforeground,b.colormap,1); + end; + end; + end; + with imagebuffer.image do begin + swapbits(imagebuffer.image); + po1:= pixels; + po2:= maskscanpo; + for int1:= 0 to imagebuffer.image.size.cy-1 do begin + if (setimagepixels(image,0,int1, + imagebuffer.image.size.cx,1) = nil) or + (importimagepixelarea(image,indexquantum,1,po1, + nil,nil) = magickfail) then begin + error(); + end; + if hasmask then begin + if monomask then begin + if importimagepixelarea(image,alphaquantum,1,po2, + nil,nil) = magickfail then begin + error(); + end; + end + else begin + if importimagepixelarea(image,alphaquantum,8,po2, + nil,nil) = magickfail then begin + error(); + end; + end; + inc(po2,maskscanstep); + end; + if SyncImagePixels(image) = 0 then begin + error(); + end; + inc(po1,scanlinestep); + end; + if not bo1 then begin //restore bit order + swapbits(imagebuffer.image); + end; + if hasmask then begin + if monomask and not bo2 then begin + swapbits(imagebuffer.mask); //restore bit order + end; + with pimage8(image)^ do begin + a.colors:= 0; + a.storage_class:= directclass; + end; + case qdepth of //GraphicMagick removes + qd_8: begin //alpha channel for palette images + with pimage8(image)^ do begin + magickfree(b.colormap); + b.colormap:= nil; + end; + end; + qd_16: begin + with pimage16(image)^ do begin + magickfree(b.colormap); + b.colormap:= nil; + end; + end; + qd_32: begin + with pimage32(image)^ do begin + magickfree(b.colormap); + b.colormap:= nil; + end; + end; + end; + end; + end; + end; + bmk_gray: begin //gray + imageinfo:= cloneimageinfo(nil); + image:= allocateimage(imageinfo); + with pimage8(image)^ do begin + a.storage_class:= directclass; + a.columns:= imagebuffer.image.size.cx; + a.rows:= imagebuffer.image.size.cy; + a.depth:= 8; + if hasmask then begin + a.matte:= magicktrue; + checkcolormask(); + end; + end; + with imagebuffer.image do begin + po1:= pixels; + po2:= maskscanpo; + for int1:= 0 to imagebuffer.image.size.cy-1 do begin + if (setimagepixels(image,0,int1, + imagebuffer.image.size.cx,1) = nil) or + (importimagepixelarea(image,redquantum,8,po1, + nil,nil) = magickfail) or + (importimagepixelarea(image,greenquantum,8,po1, + nil,nil) = magickfail) or + (importimagepixelarea(image,bluequantum,8,po1, + nil,nil) = magickfail) + then begin + error(); + end; + if hasmask then begin + if monomask then begin + if importimagepixelarea(image,alphaquantum,1,po2, + nil,nil) = magickfail then begin + error(); + end; + end + else begin + if importimagepixelarea(image,alphaquantum,8,po2, + nil,nil) = magickfail then begin + error(); + end; + end; + inc(po2,maskscanstep); + end; + if SyncImagePixels(image) = 0 then begin + error(); + end; + inc(po1,scanlinestep); + end; + end; + if monomask and not bo2 then begin + swapbits(imagebuffer.mask); //restore bit order + end; + end; + bmk_rgb: begin //color + if hasmask then begin + d:= pointer(imagebuffer.image.pixels); + e:= d + imagebuffer.image.length; + case imagebuffer.mask.kind of + bmk_mono: begin + sw1:= pointer(imagebuffer.mask.pixels); + repeat + lwo1:= $00000001; + sw2:= sw1; + e1:= d + width; + repeat + if sw2^ and lwo1 <> 0 then begin + d^.res:= $ff; + end + else begin + d^.res:= 0; + end; + lwo1:= lwo1 shl 1; + if lwo1 = 0 then begin + inc(sw2); + lwo1:= $00000001; + end; + inc(d); + until d = e1; + sw1:= pointer(sw1) + imagebuffer.mask.linebytes; + until d = e; + end; + bmk_gray: begin + sb1:= pointer(imagebuffer.mask.pixels); + repeat + d^.res:= sb1^; + inc(sb1); + inc(d); + until d = e; + end; + else begin + s:= pointer(imagebuffer.mask.pixels); + repeat + d^.res:= (word(s^.red) + word(s^.green) + word(s^.blue)) div 3; + inc(s); + inc(d); + until d = e; + end; + end; + image:= constituteimage(imagebuffer.image.size.cx, + imagebuffer.image.size.cy,'BGRA',charpixel, + imagebuffer.image.pixels,@exceptinf); + if not bo1 then begin //restore res byte + s:= pointer(imagebuffer.mask.pixels); + d:= pointer(imagebuffer.image.pixels); + repeat + d^.res:= 0; + inc(d); + until d = e; + end; + end + else begin + image:= constituteimage(imagebuffer.image.size.cx, + imagebuffer.image.size.cy,'BGRP',charpixel, + imagebuffer.image.pixels,@exceptinf); + end; + end; + end; + if image = nil then begin + raise tmagickexception.create(exceptinf); + end; + imageinfo:= cloneimageinfo(nil); + with pimageinfo8(imageinfo)^ do begin + if aquality >= 0 then begin + a.quality:= aquality; + end; + end; + case qdepth of + qd_8: begin + with pimage8(image)^ do begin + c.magick:= uppercase(format); + end; + end; + qd_16: begin + with pimage16(image)^ do begin + c.magick:= uppercase(format); + end; + end; + else begin + with pimage32(image)^ do begin + c.magick:= uppercase(format); + end; + end; + end; + setimagebackgroundcolor(image,abackgroundcolor); + si1:= imagebuffer.image.size; + if checkrotafter(si1,awidth,aheight,aoptions,arotation,rotcurrent) then begin + doscale(true); + dorotate(); + end + else begin + dorotate(); + doscale(false); + end; + if apixelpermm > 0 then begin + with pimageinfo8(imageinfo)^ do begin + a.units:= pixelsperinchresolution; + a.density:= gmstring(ansistring(formatfloatmse(apixelpermm*ppmmtoppi, + '',true))); + end; + end; + + blob:= imagetoblob(imageinfo,image,@si,@exceptinf); + if blob = nil then begin + error(); + end; + dest.writebuffer(blob^,si); + finally + if buf <> nil then begin + freemem(buf); + end; + if blob <> nil then begin + magickfree(blob); + end; + if imageinfo <> nil then begin + destroyimageinfo(imageinfo); + end; + if image <> nil then begin + destroyimage(image); + end; + destroyexceptioninfo(@exceptinf); + if bo1 then begin + freeimage(imagebuffer.image); + end; + if bo2 then begin + freeimage(imagebuffer.mask); + end; + end; + end; + end; + end; +end; + +function pinggmgraphic(const source: tstream; + out ainfo: gminfoty): boolean; +var + imageinfo: pointer; + exceptinf: exceptioninfo; + image: pointer; + str1: string; + datapo: pointer; + datalen: card32; +begin + result:= false; + checkinit; + datapo:= source.memory; + datalen:= source.size; + if datapo = nil then begin + str1:= source.readdatastring; + datapo:= pointer(str1); + datalen:= length(str1); + end; + getexceptioninfo(@exceptinf); + imageinfo:= cloneimageinfo(nil); + image:= pingblob(imageinfo,datapo,datalen,@exceptinf); + if image <> nil then begin + with pimage8(image)^ do begin + ainfo.size.cx:= a.columns; + ainfo.size.cy:= a.rows; + ainfo.depth:= a.depth; + end; + case qdepth of + qd_8: begin + with pimage8(image)^ do begin + ainfo.formatlabel:= lowercase(c.magick); + end; + end; + qd_16: begin + with pimage16(image)^ do begin + ainfo.formatlabel:= lowercase(c.magick); + end; + end; + else begin + with pimage32(image)^ do begin + ainfo.formatlabel:= lowercase(c.magick); + end; + end; + end; + result:= true; + destroyimage(image); + end; + destroyimageinfo(imageinfo); + destroyexceptioninfo(@exceptinf); +end; + +function readgmgraphic(const source: tstream; const dest: tbitmap; + const aindex: integer = -1; + const awidth: integer = 0; const aheight: integer = 0; + const arotation: real = 0; + const abackgroundcolor: colorty = cl_transparent; + const apixelpermm: real = 0; + const aoptions: gmoptionsty = []; + const afilter: filtertypes = undefinedfilter; + const ablur: real = defaultblur): string; + //returns label +var + exceptinf: exceptioninfo; + image,image2: pointer; + hasmask,monomask,rotmask: boolean; + si1,si2: sizety; + rotcurrent: dpointty; + + procedure dorotate(); + begin + if arotation <> 0 then begin + setimagebackgroundcolor(image,abackgroundcolor); + image2:= rotateimage(image,snap90(arotation),@exceptinf); + if image2 = nil then begin + exit; + end; + destroyimage(image); + image:= image2; + if rotmask then begin + pimage8(image)^.a.matte:= magicktrue; + monomask:= not hasmask and (rgmo_rotmonomask in aoptions); + hasmask:= true; + end; + si1:= ms(pimage8(image)^.a.columns,pimage8(image)^.a.rows); + end; + end; //dorotate + + procedure doscale(const rotafter: boolean); + begin + if fitscale(awidth,aheight,si1,si2,arotation,rotafter,rotcurrent) then begin + if rgmo_sample in aoptions then begin + image2:= sampleimage(image,si2.cx,si2.cy,@exceptinf); + end + else begin + if rgmo_resize in aoptions then begin + image2:= resizeimage(image,si2.cx,si2.cy,afilter,ablur,@exceptinf); + end + else begin + image2:= scaleimage(image,si2.cx,si2.cy,@exceptinf); + end; + end; +// image2:= scaleimage(image,si2.cx,si2.cy,@exceptinf); + if image2 = nil then begin + exit; + end; + destroyimage(image); + image:= image2; + si1:= ms(pimage8(image)^.a.columns,pimage8(image)^.a.rows); + end; + end; //doscale + +var + imageinfo: pointer; + imagebuffer: maskedimagety; + str1: string; //todo: use tstream -> c-stream adaptor + bo2: boolean; + datapo: pointer; + datalen: card32; + po1: pointer; + int1: integer; + cx1,cy1: integer; + +begin + result:= ''; + monomask:= false; + bo2:= dest is tmaskedbitmap; + rotmask:= bo2 and (abackgroundcolor = cl_transparent) and + (abs(frac(arotation / (pi/2.0))) > 0.0000001); + imagebuffer.image.pixels:= nil; + imagebuffer.mask.pixels:= nil; + checkinit; + datapo:= source.memory; + datalen:= source.size; + if datapo = nil then begin + str1:= source.readdatastring; + datapo:= pointer(str1); + datalen:= length(str1); + end; + getexceptioninfo(@exceptinf); + image:= nil; + imageinfo:= cloneimageinfo(nil); + try + with pimageinfo8(imageinfo)^ do begin //a identical for all dephts + if apixelpermm > 0 then begin + a.units:= pixelsperinchresolution; + a.density:= gmstring(ansistring(formatfloatmse(apixelpermm*ppmmtoppi, + '',true))); + end; + if aindex >= 0 then begin + a.subimage:= aindex; + end; + image:= pingblob(imageinfo,datapo,datalen,@exceptinf); + if image = nil then begin + exit; + end; + if (pimage8(image)^.a.columns > 0) and (pimage8(image)^.a.rows > 0) then begin + //limit to necessary size + if (awidth <> 0) and (pimage8(image)^.a.columns > awidth) or + (aheight <> 0) and (pimage8(image)^.a.rows > aheight) then begin + cx1:= awidth; + if cx1 = 0 then begin + cx1:= (pimage8(image)^.a.columns * aheight) div pimage8(image)^.a.rows; + end; + cy1:= aheight; + if cy1 = 0 then begin + cy1:= (pimage8(image)^.a.rows * awidth) div pimage8(image)^.a.columns; + end; + a.size:= gmstring(inttostr(cx1)+'x'+inttostr(cy1)); + end; + end; + destroyimage(image); + image:= nil; + end; + case qdepth of + qd_8: begin + with pimageinfo8(imageinfo)^ do begin + end; + end; + qd_16: begin + with pimageinfo16(imageinfo)^ do begin + end; + end; + else begin + with pimageinfo32(imageinfo)^ do begin + end; + end; + end; + + image:= blobtoimage(imageinfo,datapo,datalen,@exceptinf); + if image <> nil then begin + with pimage8(image)^ do begin //a is identical for all depths + hasmask:= a.matte = magicktrue; + si1:= ms(a.columns,a.rows); + end; + if checkrotafter(si1,awidth,aheight,aoptions,arotation,rotcurrent) then begin + doscale(true); + dorotate(); + end + else begin + dorotate(); + doscale(false); + end; + case qdepth of + qd_8: begin + with pimage8(image)^ do begin + result:= lowercase(c.magick); + if result = '' then begin + result:= lowercase(c.magick_filename); + end; + end; + end; + qd_16: begin + with pimage16(image)^ do begin + result:= lowercase(c.magick); + if result = '' then begin + result:= lowercase(c.magick_filename); + end; + end; + end; + else begin + with pimage32(image)^ do begin + result:= lowercase(c.magick); + if result = '' then begin + result:= lowercase(c.magick_filename); + end; + end; + end; + end; + allocimage(imagebuffer.image,si1,bmk_rgb); + if dispatchimage(image,0,0,si1.cx,si1.cy,'BGRP',charpixel, + imagebuffer.image.pixels,@exceptinf) = magickpass then begin + if hasmask and bo2 then begin + if monomask then begin + allocimage(imagebuffer.mask,si1,bmk_mono); + po1:= imagebuffer.mask.pixels; + for int1:= 0 to si1.cy-1 do begin + if getimagepixels(image,0,int1,si1.cx,1) = nil then begin + result:= ''; + break; + end; + if exportimagepixelarea(image,alphaquantum,1,po1, + nil,nil) = magickfail then begin + result:= ''; + break; + end; + inc(po1,imagebuffer.mask.linebytes); + end; + swapbits(imagebuffer.mask); + end + else begin + allocimage(imagebuffer.mask,si1,bmk_gray); + po1:= imagebuffer.mask.pixels; + for int1:= 0 to si1.cy-1 do begin + if getimagepixels(image,0,int1,si1.cx,1) = nil then begin + result:= ''; + break; + end; + if exportimagepixelarea(image,alphaquantum,8,po1, + nil,nil) = magickfail then begin + result:= ''; + break; + end; + inc(po1,imagebuffer.mask.linebytes); + end; + end; + end; + end + else begin + result:= ''; + end; + end; + if result <> '' then begin + if bo2 then begin + tmaskedbitmap(dest).loadfrommaskedimage(imagebuffer); + end + else begin + tbitmap(dest).loadfromimage(imagebuffer.image); + end; + tbitmap(dest).change; + end; + finally + freeimage(imagebuffer.image); + freeimage(imagebuffer.mask); + destroyimageinfo(imageinfo); + destroyexceptioninfo(@exceptinf); + if image <> nil then begin + destroyimage(image); + end; + end; +end; + +function readgraphic(const source: tstream; + const dest: tobject; var format: string; + const params: array of const): boolean; +var + index: integer = -1; + width: integer = 0; + height: integer = 0; + rotation: extended = 0; + backgroundcolor: colorty = cl_transparent; + density: extended = 0; + options: gmoptionsty = []; + filter: filtertypes = undefinedfilter; + blur: extended = defaultblur; +begin + result:= false; + if dest is tbitmap then begin + matchparams(params, + [index,width,height,rotation,backgroundcolor,density,longword(options), + filter,blur], + [@index,@width,@height,@rotation,@backgroundcolor,@density,@options, + @filter,@blur]); + format:= readgmgraphic(source,tbitmap(dest),index,width,height,rotation, + backgroundcolor,density,options,filter,blur); + result:= format <> ''; + end; +end; + +procedure writegraphic(const dest: tstream; const source: tobject; + const format: string; const params: array of const); +var + quality: integer = -1; + width: integer = 0; + height: integer = 0; + rotation: extended = 0; + backgroundcolor: colorty = cl_transparent; + density: extended = 0; + options: gmoptionsty = []; + filter: filtertypes = undefinedfilter; + blur: extended = defaultblur; +begin + if source is tbitmap then begin + matchparams(params, + [quality,width,height,rotation,backgroundcolor,density, + longword(options),filter,blur], + [@quality,@width,@height,@rotation,@backgroundcolor,@density,@filter,@blur]); + writegmgraphic(dest,tbitmap(source),format,quality,width,height, + rotation,backgroundcolor,density,options,filter,blur); + end; +end; + +procedure registerformats(const labels: array of string; + const filternames: array of msestring; + const filemasks: array of msestringarty); +var + int1: integer; + fname: msestring; + fmask: msestringarty; +begin + checkinit(); + for int1:= 0 to high(labels) do begin + fname:= ''; + fmask:= nil; + if int1 <= high(filternames) then begin + fname:= filternames[int1]; + end; + if int1 <= high(filemasks) then begin + fmask:= filemasks[int1]; + end; + registergraphicformat(labels[int1],@readgraphic,@writegraphic,fname,fmask); + end; +end; + +{ tmagickexception } + +constructor tmagickexception.create(const ainfo: exceptioninfo); +begin + inherited create('GraphicsMagick exception'+lineend+ainfo.reason+lineend+ + ainfo.description); +end; + +initialization +finalization + if inited then begin + releasegraphicsmagick(); + inited:= false; + end; +end. diff --git a/mseide-msegui/lib/common/kernel/kernel_bmp.pas b/mseide-msegui/lib/common/kernel/kernel_bmp.pas new file mode 100644 index 0000000..6af88a7 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/kernel_bmp.pas @@ -0,0 +1,33 @@ +unit kernel_bmp; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msebitmap; + +const + objdata_taction: record size: integer; data: array[0..293] of byte end = + (size: 294; data: ( + 84,80,70,48,16,116,98,105,116,109,97,112,99,111,110,116,97,105,110,101, + 114,7,116,97,99,116,105,111,110,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,0,0,0,128,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,216,0,0,0,0,0,0,0, + 0,0,0,0,24,0,0,0,24,0,0,0,164,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,255,0,255,87,0,0,255,2,255,0,255,20, + 0,0,255,2,255,0,255,19,0,0,255,3,255,0,255,19,0,0,255,2, + 255,0,255,20,0,0,255,2,255,0,255,23,0,0,255,2,255,0,255,24, + 0,0,255,2,255,0,255,24,0,0,255,2,255,0,255,24,0,0,255,2, + 255,0,255,21,0,0,255,2,255,0,255,21,0,0,255,1,255,0,255,17, + 0,0,255,1,255,0,255,3,0,0,255,2,255,0,255,18,0,0,255,1, + 255,0,255,2,0,0,255,1,255,0,255,19,0,0,255,1,255,0,255,1, + 0,0,255,2,255,0,255,20,0,0,255,2,255,0,255,1,0,0,255,3, + 255,0,255,18,0,0,255,3,255,0,255,137,0,0) + ); + +initialization + registerobjectdata(@objdata_taction,tbitmapcontainer,'taction'); +end. diff --git a/mseide-msegui/lib/common/kernel/linux/cwstring.pas b/mseide-msegui/lib/common/kernel/linux/cwstring.pas new file mode 100644 index 0000000..b6a2c2a --- /dev/null +++ b/mseide-msegui/lib/common/kernel/linux/cwstring.pas @@ -0,0 +1,641 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 2005 by Florian Klaempfl, + member of the Free Pascal development team. + + libc based wide string support + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + **********************************************************************} +{$ifdef FPC}{$mode objfpc}{$endif} + +{$define unicodeversion} +{$if fpc_fullversion >= 30000} + {$define mse_fpc_3} +{$endif} +{$if fpc_fullversion >= 30001} + {$define hascompareoptions} +{$endif} +unit cwstring; +{$ifndef FPC} +interface //dummy +implementation + +{$else} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + msetypes,sysutils,msesetlocale,mselibc{$ifdef mse_fpc_3},unixcp{$endif}; +type + eiconv = class(econverterror) + end; + +procedure SetCWidestringManager(); + +implementation +{$ifdef FPC}{$linklib c}{$endif} + +{$ifndef linux} // Linux (and maybe glibc platforms in general), have iconv in glibc. + {$ifndef FreeBSD5} + {$linklib iconv} + {$define useiconv} + {$endif} +{$endif linux} +Uses +// BaseUnix, + msectypes,{$ifndef FPC}msetypes,{$endif} +// unix, +// unixtype, +// sysutils, +// initc, + {msedatalist,}msesysintf1,msesysintf,msestrings; + +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +Const +{$ifdef useiconv} + libiconvname='iconv'; +{$else} + libiconvname='c'; // is in libc under Linux. +{$endif} + +{$if defined(darwin) or defined(freebsd) and not defined(freebsd5)} + prefix = 'lib'; +{$else} + prefix = ''; +{$endif} + +{ Case-mapping "arrays" } +//var +// AnsiUpperChars: AnsiString; // 1..255 +// AnsiLowerChars: AnsiString; // 1..255 +// WideUpperChars: WideString; // 1..65535 +// WideLowerChars: WideString; // 1..65535 + +{ the following declarations are from the libc unit for linux so they + might be very linux centric + maybe this needs to be splitted in an os depend way later } +function towlower(__wc:wint_t):wint_t;cdecl;external libiconvname name 'towlower'; +function towupper(__wc:wint_t):wint_t;cdecl;external libiconvname name 'towupper'; +function wcscoll (__s1:pwchar_t; __s2:pwchar_t):cint;cdecl;external libiconvname name 'wcscoll'; +function strcoll (__s1:pchar; __s2:pchar):cint;cdecl;external libiconvname name 'strcoll'; + +const +//{$ifdef linux} +// __LC_CTYPE = 0; +// _NL_CTYPE_CLASS = (__LC_CTYPE shl 16); +// _NL_CTYPE_CODESET_NAME = (_NL_CTYPE_CLASS)+14; +// CODESET = _NL_CTYPE_CODESET_NAME; +//{$else linux} +//{$ifdef darwin} +// CODESET = 0; +//{$else darwin} +//{$ifdef FreeBSD} // actually FreeBSD5. internationalisation is afaik not default on 4. +// CODESET = 0; +//{$else freebsd} +//{$ifdef solaris} +// CODESET=49; +//{$else} +//{$error lookup the value of CODESET in /usr/include/langinfo.h for your OS } +// and while doing it, check if iconv is in libc, and if the symbols are prefixed with iconv_ or libiconv_ +//{$endif solaris} +//{$endif FreeBSD} +//{$endif darwin} +//{$endif linux} + +{ unicode encoding name } +{$ifdef FPC_LITTLE_ENDIAN} + unicode_encoding = 'UNICODELITTLE'; +{$else FPC_LITTLE_ENDIAN} + unicode_encoding = 'UNICODEBIG'; +{$endif FPC_LITTLE_ENDIAN} + +type + + piconv_t = ^iconv_t; + iconv_t = pointer; + nl_item = cint; + +function nl_langinfo(__item:nl_item):pchar cdecl + external libiconvname name 'nl_langinfo'; +function iconv_open(__tocode: pchar; __fromcode: pchar): iconv_t cdecl + external libiconvname name prefix+'iconv_open'; +function iconv(__cd: iconv_t; __inbuf: ppchar; __inbytesleft: psize_t; + __outbuf: ppchar; __outbytesleft: psize_t): size_t cdecl + external libiconvname name prefix+'iconv'; +function iconv_close(__cd: iconv_t): cint cdecl + external libiconvname name prefix+'iconv_close'; + +var +// iconv_ansi2ucs4, +// iconv_ucs42ansi, + iconv_ansi2wide, + iconv_wide2ansi : iconv_t; + +// lock_ansi2ucs4 : integer = -1; +// lock_ucs42ansi : integer = -1; + lock_ansi2wide : integer = -1; + lock_wide2ansi : integer = -1; + +procedure lockiconv(var lockcount: integer); +begin + while interlockedincrement(lockcount) <> 0 do begin + interlockeddecrement(lockcount); + sys_threadschedyield; + end; +end; + +procedure unlockiconv(var lockcount: integer); +begin + interlockeddecrement(lockcount); +end; + +{$ifdef mse_fpc_3} +Type + PAnsiRec = ^TAnsiRec; + TAnsiRec = Record + CodePage : TSystemCodePage; + ElementSize : Word; +{$ifdef CPU64} + { align fields } + Dummy : DWord; +{$endif CPU64} + Ref : SizeInt; + Len : SizeInt; + end; + +procedure Wide2AnsiMove(source:pwidechar;var dest:RawByteString; + cp : TSystemCodePage; len:SizeInt); + //todo: convert codepages +{$else} +procedure Wide2AnsiMove(source:pwidechar; var dest:ansistring; len:SizeInt); +{$endif} + var + outlength, + outoffset, + srclen, + outleft : size_t; + srcpos : pwidechar; + destpos: pchar; + mynil : pchar; + my0 : size_t; + begin +{$ifdef mse_fpc_3} + if (cp = cp_utf8) or (cp = cp_acp) and + (DefaultSystemCodePage = cp_utf8) then begin + dest:= stringtoutf8(source,len); + end + else begin +{$endif} + mynil:=nil; + my0:=0; + { rought estimation } + setlength(dest,len*3); + outlength:=len*3; + srclen:=len*2; + srcpos:=source; + destpos:=pchar(dest); + outleft:=outlength; + lockiconv(lock_wide2ansi); + while iconv(iconv_wide2ansi,@srcpos,@srclen,@destpos,@outleft)=size_t(-1) do + begin + case __errno_location()^ of +// case fpgetCerrno of + EILSEQ: + begin + { skip and set to '?' } + inc(srcpos); + dec(srclen,2); + destpos^:='?'; + inc(destpos); + dec(outleft); + { reset } + iconv(iconv_wide2ansi,@mynil,@my0,@mynil,@my0); + end; + E2BIG: + begin + outoffset:=destpos-pchar(dest); + { extend } + setlength(dest,outlength+len*3); + inc(outleft,len*3); + inc(outlength,len*3); + { string could have been moved } + destpos:=pchar(dest)+outoffset; + end; + else + begin + unlockiconv(lock_wide2ansi); + raise eiconv.Create('iconv error '+ + IntToStr(sys_getlasterror{fpgetCerrno})); + end; + end; + end; + unlockiconv(lock_wide2ansi); + // truncate string + setlength(dest,length(dest)-outleft); + {$ifdef mse_fpc_3} + pansirec(pointer(dest)-sizeof(tansirec))^.codepage:= cp; + {$endif} +{$ifdef mse_fpc_3} + end; +{$endif} +end; + +{$ifdef mse_fpc_3} +procedure Ansi2WideMove(source:pchar;cp : TSystemCodePage; + var dest:widestring;len:SizeInt); + //todo: codepages +{$else} +procedure Ansi2WideMove(source:pchar;var dest:widestring;len:SizeInt); +{$endif} + var + outlength, + outoffset, + outleft : size_t; + srcpos, + destpos: pchar; + mynil : pchar; + my0 : size_t; + begin +{$ifdef mse_fpc_3} + if (cp = cp_utf8) or (cp = cp_acp) and + (DefaultSystemCodePage = cp_utf8) then begin + dest:= utf8tostring(source,len); + end + else begin +{$endif} + mynil:=nil; + my0:=0; + // extra space + outlength:=len+1; + setlength(dest,outlength); + outlength:=len+1; + srcpos:=source; + destpos:=pchar(dest); + outleft:=outlength*2; + lockiconv(lock_ansi2wide); + while iconv(iconv_ansi2wide,@srcpos,@len,@destpos,@outleft)=size_t(-1) do + begin +// case fpgetCerrno of + case __errno_location()^ of + EILSEQ: + begin + { skip and set to '?' } + inc(srcpos); + dec(len); + pwidechar(destpos)^:='?'; + inc(destpos,2); + dec(outleft,2); + { reset } + iconv(iconv_ansi2wide,@mynil,@my0,@mynil,@my0); + end; + E2BIG: + begin + outoffset:=destpos-pchar(dest); + { extend } + setlength(dest,outlength+len); + inc(outleft,len*2); + inc(outlength,len); + { string could have been moved } + destpos:=pchar(dest)+outoffset; + end; + else + begin + unlockiconv(lock_ansi2wide); + raise eiconv.Create('iconv error '+ + IntToStr(sys_getlasterror{fpgetCerrno})); + end; + end; + end; + unlockiconv(lock_ansi2wide); + // truncate string + setlength(dest,length(dest)-outleft div 2); +{$ifdef mse_fpc_3} + end; +{$endif} +end; + + +function lowerwidestring(const s : widestring) : widestring; +var + i1: int32; + ps,pd,pe: pmsechar; +begin + i1:= length(s); + setlength(result,i1); + ps:= pointer(s); + pd:= pointer(result); + pe:= pd + i1; + while pd < pe do begin + pd^:= widechar(towlower(wint_t(ps^))); + inc(ps); + inc(pd); + end; +end; + +function upperwidestring(const s : widestring) : widestring; +var + i1: int32; + ps,pd,pe: pmsechar; +begin + i1:= length(s); + setlength(result,i1); + ps:= pointer(s); + pd:= pointer(result); + pe:= pd + i1; + while pd < pe do begin + pd^:= widechar(towupper(wint_t(ps^))); + inc(ps); + inc(pd); + end; +end; + +function CompareTextWideString(const s1, s2 : WideString): PtrInt; +var //no surrogate pair handling, no decomposition handling + w1,w2: array[0..1] of ucs4char; + int1: integer; + max: integer; + pa,pb,pe: pmsechar; +begin + result:= 0; + if pointer(s1) <> pointer(s2) then begin + if s1 = '' then begin + result:= -1; + end + else begin + if s2 = '' then begin + result:= 1; + end + else begin + pa:= pointer(s1); + pb:= pointer(s2); + max:= length(s1); + int1:= length(s2); + if max > int1 then begin + max:= int1; + end; + pe:= pa + max; + while pa <= pe do begin //including terminating #0 + if pa^ <> pb^ then begin + w1[0]:= towupper(wint_t(word(pa^))); + w2[0]:= towupper(wint_t(word(pb^))); + if w1[0] <> w2[0] then begin + w1[1]:= 0; + w2[1]:= 0; + result:= wcscoll(pwchar_t(@w1),pwchar_t(@w2)); + break; + end; + end; + inc(pa); + inc(pb); + end; + end; + end; + end; +end; + +function CompareWideString(const s1, s2 : WideString + {$ifdef hascompareoptions};Options : TCompareOptions{$endif}): PtrInt; +var //no surrogate pair handling, no decomposition handling + w1,w2: array[0..1] of ucs4char; + int1: integer; + max: integer; + pa,pb,pe: pmsechar; +begin +{$ifdef hascompareoptions} + if (coignorecase in options) then begin + result:= comparetextwidestring(s1,s2); + exit; + end; +{$endif} + result:= 0; + if pointer(s1) <> pointer(s2) then begin + if s1 = '' then begin + result:= -1; + end + else begin + if s2 = '' then begin + result:= 1; + end + else begin + pa:= pointer(s1); + pb:= pointer(s2); + max:= length(s1); + int1:= length(s2); + if max > int1 then begin + max:= int1; + end; + pe:= pa + max; + while pa <= pe do begin //including terminating #0 + if pa^ <> pb^ then begin + w1[0]:= ord(pa^); + w1[1]:= 0; + w2[0]:= ord(pb^); + w2[1]:= 0; + result:= wcscoll(pwchar_t(@w1),pwchar_t(@w2)); + break; + end; + inc(pa); + inc(pb); + end; + end; + end; + end; +end; + +function StrCompAnsi(s1,s2 : PChar): PtrInt; + begin + result:=strcoll(s1,s2); + end; + +{$ifdef mse_fpc_3} +//copied from fpc rtl +{$ifdef FPC_HAS_CPSTRING} + +function envvarset(const varname: pchar): boolean; +var + varval: pchar; +begin + varval:= getenv(varname); + result:= + assigned(varval) and + (varval[0]<>#0); +end; + +function GetStandardCodePage( + const stdcp: TStandardCodePageEnum): TSystemCodePage; +var + langinfo: pchar; +begin +{$ifdef FPCRTL_FILESYSTEM_UTF8} + if stdcp=scpFileSystemSingleByte then + begin + result:=CP_UTF8; + exit; + end; +{$endif} + { if none of the relevant LC_* environment variables are set, fall back to + UTF-8 (this happens under some versions of OS X for GUI applications, which + otherwise get CP_ASCII) } + if envvarset('LC_ALL') or + envvarset('LC_CTYPE') or + envvarset('LANG') then + begin + langinfo:=nl_langinfo(CODESET); + { there's a bug in the Mac OS X 10.5 libc (based on FreeBSD's) + that causes it to return an empty string of UTF-8 locales + -> patch up (and in general, UTF-8 is a good default on + Unix platforms) } + if not assigned(langinfo) or + (langinfo^=#0) then + langinfo:='UTF-8'; + Result:= GetCodepageByName(ansistring(langinfo)); + end + else + Result:=unixcp.GetSystemCodepage; +end; + +procedure SetStdIOCodePage(var T: Text); inline; +begin + case TextRec(T).Mode of + fmInput:TextRec(T).CodePage:=GetStandardCodePage(scpConsoleInput); + fmOutput:TextRec(T).CodePage:=GetStandardCodePage(scpConsoleOutput); + end; +end; + +procedure SetStdIOCodePages; inline; +begin + SetStdIOCodePage(system.Input); + SetStdIOCodePage(system.Output); + SetStdIOCodePage(system.ErrOutput); + SetStdIOCodePage(system.StdOut); + SetStdIOCodePage(system.StdErr); +end; +{$endif FPC_HAS_CPSTRING} + +{$endif} + +var +{$ifdef unicodeversion} + widestringmanagerbefore : TUnicodeStringManager; +{$else} + widestringmanagerbefore : TWideStringManager; +{$endif} + +Procedure SetCWideStringManager; +Var +{$ifdef unicodeversion} + CWideStringManager : TUnicodeStringManager; +{$else} + CWideStringManager : TWideStringManager; +{$endif} +begin + widestringmanagerbefore:= widestringmanager; + CWideStringManager:= widestringmanager; + With CWideStringManager do begin + Wide2AnsiMoveProc:= @Wide2AnsiMove; + Ansi2WideMoveProc:= @Ansi2WideMove; + + UpperWideStringProc:= @UpperWideString; + LowerWideStringProc:= @LowerWideString; + + CompareWideStringProc:= @CompareWideString; + {$ifndef hascompareoptions} + CompareTextWideStringProc:= @CompareTextWideString; + {$endif} +{$ifdef unicodeversion} + Unicode2AnsiMoveProc:= @Wide2AnsiMove; + Ansi2UnicodeMoveProc:= @Ansi2WideMove; + + UpperUnicodeStringProc:= @UpperWideString; + LowerUnicodeStringProc:= @LowerWideString; + + CompareUnicodeStringProc:= @CompareWideString; + {$ifndef hascompareoptions} + CompareTextUnicodeStringProc:= @CompareTextWideString; + {$endif} +{$endif} + { + CharLengthPCharProc + + UpperAnsiStringProc + LowerAnsiStringProc + CompareStrAnsiStringProc + CompareTextAnsiStringProc + } + StrCompAnsiStringProc:=@StrCompAnsi; + { + StrICompAnsiStringProc + StrLCompAnsiStringProc + StrLICompAnsiStringProc + StrLowerAnsiStringProc + StrUpperAnsiStringProc + } + {$ifdef mse_fpc_3} + GetStandardCodePageProc:=@GetStandardCodePage; + {$endif} + end; + SetWideStringManager(CWideStringManager); +end; + +procedure unSetCWidestringManager(); +begin + widestringmanager:= widestringmanagerbefore; +end; + +initialization + setlocale(LC_ALL,''); + { init conversion tables } + +{$ifdef mse_fpc_3} + { set the DefaultSystemCodePage } + DefaultSystemCodePage:=GetStandardCodePage(scpAnsi); + DefaultFileSystemCodePage:=GetStandardCodePage(scpFileSystemSingleByte); + DefaultRTLFileSystemCodePage:=DefaultFileSystemCodePage; + + {$ifdef FPC_HAS_CPSTRING} + SetStdIOCodePages; + {$endif FPC_HAS_CPSTRING} +{$endif} + + iconv_wide2ansi:=iconv_open(nl_langinfo(CODESET),unicode_encoding); + iconv_ansi2wide:=iconv_open(unicode_encoding,nl_langinfo(CODESET)); +// iconv_ucs42ansi:=iconv_open(nl_langinfo(CODESET),'UCS4'); +// iconv_ansi2ucs4:=iconv_open('UCS4',nl_langinfo(CODESET)); + SetCWideStringManager(); + +finalization + unSetCWideStringManager(); + if iconv_wide2ansi <> nil then begin + iconv_close(iconv_wide2ansi); + end; + if iconv_ansi2wide <> nil then begin + iconv_close(iconv_ansi2wide); + end; +// iconv_close(iconv_ucs42ansi); +// if iconv_ansi2ucs4 <> nil then begin +// iconv_close(iconv_ansi2ucs4); +// end; +{$endif} +end. diff --git a/mseide-msegui/lib/common/kernel/linux/ice.pas b/mseide-msegui/lib/common/kernel/linux/ice.pas new file mode 100644 index 0000000..545f4e5 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/linux/ice.pas @@ -0,0 +1,148 @@ + +unit ice; +interface +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +{$IFDEF FPC} + {$PACKRECORDS C} +{$else} + {$ALIGN 4} + {$MINENUMSIZE 4} +{$ENDIF} + + + { $Xorg: ICE.h,v 1.4 2001/02/09 02:03:26 xorgcvs Exp $ } + {***************************************************************************** + + + Copyright 1993, 1998 The Open Group + + Permission to use, copy, modify, distribute, and sell this software and its + documentation for any purpose is hereby granted without fee, provided that + the above copyright notice appear in all copies and that both that + copyright notice and this permission notice appear in supporting + documentation. + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the name of The Open Group shall not be + used in advertising or otherwise to promote the sale, use or other dealings + in this Software without prior written authorization from The Open Group. + + Author: Ralph Mor, X Consortium + + ***************************************************************************** } + { + * Protocol Version + } + + const + IceProtoMajor = 1; + IceProtoMinor = 0; + { + * Byte Order + } + IceLSBfirst = 0; + IceMSBfirst = 1; + { + * ICE minor opcodes + } + ICE_Error = 0; + ICE_ByteOrder = 1; + ICE_ConnectionSetup = 2; + ICE_AuthRequired = 3; + ICE_AuthReply = 4; + ICE_AuthNextPhase = 5; + ICE_ConnectionReply = 6; + ICE_ProtocolSetup = 7; + ICE_ProtocolReply = 8; + ICE_Ping = 9; + ICE_PingReply = 10; + ICE_WantToClose = 11; + ICE_NoClose = 12; + { + * Error severity + } + IceCanContinue = 0; + IceFatalToProtocol = 1; + IceFatalToConnection = 2; + { + * ICE error classes that are common to all protocols + } + IceBadMinor = $8000; + IceBadState = $8001; + IceBadLength = $8002; + IceBadValue = $8003; + { + * ICE error classes that are specific to the ICE protocol + } + IceBadMajor = 0; + IceNoAuth = 1; + IceNoVersion = 2; + IceSetupFailed = 3; + IceAuthRejected = 4; + IceAuthFailed = 5; + IceProtocolDuplicate = 6; + IceMajorOpcodeDuplicate = 7; + IceUnknownProtocol = 8; + { _ICE_H_ } + +type + Bool = integer;{longbool}//protocoll does not accept -1 for true + IcePointer = pointer; + IceConn = pointer; + Status = integer; + IceProcessMessagesStatus = (IceProcessMessagesSuccess,IceProcessMessagesIOError, + IceProcessMessagesConnectionClosed); + + IceReplyWaitInfo = record + sequence_of_request: longword; + major_opcode_of_request: integer; + minor_opcode_of_request: integer; + reply: IcePointer; + end; + pIceReplyWaitInfo = ^IceReplyWaitInfo; + + IceWatchProc = procedure(_iceConn: IceConn; clientData: IcePointer; + opening: Bool; var watchData: IcePointer); cdecl; + +var + IceConnectionNumber: function (_iceConn: IceConn): integer; cdecl; + IceAddConnectionWatch: function(watchProc: IceWatchProc; + clientData: IcePointer): Status; cdecl; + IceRemoveConnectionWatch: procedure(watchProc: IceWatchProc; + clientData: IcePointer); cdecl; + IceProcessMessages: function(_iceConn: IceConn; replyWait: pIceReplyWaitInfo; + var replyReadyRet: bool): IceProcessMessagesStatus; cdecl; +function geticelib: boolean; + +implementation +uses + msesys,msesonames,msedynload; + +function geticelib: boolean; +begin + result:= checkprocaddresses(icenames, + [ + 'IceConnectionNumber', //0 + 'IceAddConnectionWatch', //1 + 'IceRemoveConnectionWatch', //2 + 'IceProcessMessages' //3 + ], + [ + {$ifndef FPC}@{$endif}@IceConnectionNumber, //0 + {$ifndef FPC}@{$endif}@IceAddConnectionWatch, //1 + {$ifndef FPC}@{$endif}@IceRemoveConnectionWatch,//2 + {$ifndef FPC}@{$endif}@IceProcessMessages //3 + ]); +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/linux/mseguiintf.pas b/mseide-msegui/lib/common/kernel/linux/mseguiintf.pas new file mode 100644 index 0000000..52fb1ed --- /dev/null +++ b/mseide-msegui/lib/common/kernel/linux/mseguiintf.pas @@ -0,0 +1,7148 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseguiintf; //X11 + +{$ifdef FPC}{$mode objfpc}{$h+}{$GOTO ON}{$endif} +{$ifndef FPC}{$ifdef linux} {$define UNIX} {$endif}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{$ifdef mse_debugwindowfocus} + {$define mse_debug} +{$endif} +{$ifdef mse_debugconfigure} + {$define mse_debug} +{$endif} +{$ifdef mse_debugshow} + {$define mse_debug} +{$endif} +uses + {$ifdef FPC}xlib{$else}Xlib{$endif},msetypes,mseapplication,msesys, + msegraphutils,mseevent,msepointer,mseguiglob,msesystypes,{msestockobjects,} + msethread{$ifdef FPC},x,xutil,dynlibs{$endif}, + mselibc,msectypes,msesysintf,msegraphics, + msestrings,mxft,mxrender,mxrandr; + +{$ifdef FPC} + {$define xbooleanresult} + {$if defined(FPC) and (fpc_fullversion < 020300)} + {$define xboolean} + {$ifend} + {$ifdef UNIX} + {$ifdef msedebug} +var + _IO_stdin: P_IO_FILE; cvar; + //avoid link errors if rtl is compiled with stabs info + _IO_stdout: P_IO_FILE; cvar; + _IO_stderr: P_IO_FILE; cvar; + __malloc_initialized : longint;cvar; + h_errno : longint;cvar; + {$endif} + {$endif} +{$endif} + +{ $define smdebug} + +{$include ../mseguiintf.inc} + +{$define with_sm} + +{$ifndef with_sm} + { $define with_saveyourself} +{$endif} +type +{$ifndef FPC} + txevent = xevent; +{$endif} + + x11internalwindowoptionsdty = record + depth: cint; + visual: pvisual; + colormap: tcolormap; + end; + {$if sizeof(x11internalwindowoptionsdty) > sizeof(internalwindowoptionspty)} + {$error 'buffer overflow'} + {$ifend} + x11internalwindowoptionsty = record + case integer of + 0: (d: x11internalwindowoptionsdty;); + 1: (_bufferspace: internalwindowoptionspty;); + end; + + {$if sizeof(x11internalwindowoptionsdty) > sizeof(internalwindowoptionspty)} + {$error 'buffer overflow'} + {$ifend} + + syseventty = type txevent; +const + //from keysymdef.h + XK_BackSpace = $FF08; //* back space, back char */ + XK_Tab = $FF09; + XK_Linefeed = $FF0A; //* Linefeed, LF */ + XK_Clear = $FF0B; + XK_Return = $FF0D; //* Return, enter */ + XK_Pause = $FF13; //* Pause, hold */ + XK_Scroll_Lock = $FF14; + XK_Sys_Req = $FF15; + XK_Escape = $FF1B; + XK_Delete = $FFFF; //* Delete, rubout */ + +//* Cursor control & motion */ + XK_Home = $FF50; + XK_Left = $FF51; //* Move left, left arrow */ + XK_Up = $FF52; //* Move up, up arrow */ + XK_Right = $FF53; //* Move right, right arrow */ + XK_Down = $FF54; //* Move down, down arrow */ + XK_Prior = $FF55; //* Prior, previous */ + XK_Page_Up = $FF55; + XK_Next = $FF56; //* Next */ + XK_Page_Down = $FF56; + XK_End = $FF57; //* EOL */ + XK_Begin = $FF58; //* BOL */ + +//* Misc Functions */ + XK_Select = $FF60; //* Select, mark */ + XK_Print = $FF61; + XK_Execute = $FF62; //* Execute, run, do */ + XK_Insert = $FF63; //* Insert, insert here */ + XK_Undo = $FF65; //* Undo, oops */ + XK_Redo = $FF66; //* redo, again */ + XK_Menu = $FF67; + XK_Find = $FF68; //* Find, search */ + XK_Cancel = $FF69; //* Cancel, stop, abort, exit */ + XK_Help = $FF6A; //* Help */ + XK_Break = $FF6B; + XK_Mode_switch = $FF7E; //* Character set switch */ + XK_script_switch = $FF7E; //* Alias for mode_switch */ + XK_Num_Lock = $FF7F; + +//* Keypad Functions, keypad numbers cleverly chosen to map to ascii */ + XK_KP_Space = $FF80; //* space */ + XK_KP_Tab = $FF89; + XK_KP_Enter = $FF8D; //* enter */ + XK_KP_F1 = $FF91; //* PF1, KP_A, ... */ + XK_KP_F2 = $FF92; + XK_KP_F3 = $FF93; + XK_KP_F4 = $FF94; + XK_KP_Home = $FF95; + XK_KP_Left = $FF96; + XK_KP_Up = $FF97; + XK_KP_Right = $FF98; + XK_KP_Down = $FF99; + XK_KP_Prior = $FF9A; + XK_KP_Page_Up = $FF9A; + XK_KP_Next = $FF9B; + XK_KP_Page_Down = $FF9B; + XK_KP_End = $FF9C; + XK_KP_Begin = $FF9D; + XK_KP_Insert = $FF9E; + XK_KP_Delete = $FF9F; + XK_KP_Equal = $FFBD; //* equals */ + XK_KP_Multiply = $FFAA; + XK_KP_Add = $FFAB; + XK_KP_Separator = $FFAC; //* separator, often comma */ + XK_KP_Subtract = $FFAD; + XK_KP_Decimal = $FFAE; + XK_KP_Divide = $FFAF; + + XK_KP_0 = $FFB0; + XK_KP_1 = $FFB1; + XK_KP_2 = $FFB2; + XK_KP_3 = $FFB3; + XK_KP_4 = $FFB4; + XK_KP_5 = $FFB5; + XK_KP_6 = $FFB6; + XK_KP_7 = $FFB7; + XK_KP_8 = $FFB8; + XK_KP_9 = $FFB9; + + XK_F1 = $FFBE; + XK_F35 = $FFE0; + +//* Modifiers */ + XK_Shift_L = $FFE1; //* Left shift */ + XK_Shift_R = $FFE2; //* Right shift */ + XK_Control_L = $FFE3; //* Left control */ + XK_Control_R = $FFE4; //* Right control */ + XK_Caps_Lock = $FFE5; //* Caps lock */ + XK_Shift_Lock = $FFE6; //* Shift lock */ + + XK_Meta_L = $FFE7; //* Left meta */ + XK_Meta_R = $FFE8; //* Right meta */ + XK_Alt_L = $FFE9; //* Left alt */ + XK_Alt_R = $FFEA; //* Right alt */ + XK_Super_L = $FFEB; //* Left super */ + XK_Super_R = $FFEC; //* Right super */ + XK_Hyper_L = $FFED; //* Left hyper */ + XK_Hyper_R = $FFEE; //* Right hyper */ + + //ISO 9995 Function and Modifier Keys + //Byte 3 = 0xFE + + XK_ISO_Lock = $FE01; + XK_ISO_Level2_Latch = $FE02; + XK_ISO_Level3_Shift = $FE03; + XK_ISO_Level3_Latch = $FE04; + XK_ISO_Level3_Lock = $FE05; + XK_ISO_Level5_Shift = $FE11; + XK_ISO_Level5_Latch = $FE12; + XK_ISO_Level5_Lock = $FE13; + XK_ISO_Group_Shift = $FF7E; + XK_ISO_Group_Latch = $FE06; + XK_ISO_Group_Lock = $FE07; + XK_ISO_Next_Group = $FE08; + XK_ISO_Next_Group_Lock = $FE09; + XK_ISO_Prev_Group = $FE0A; + XK_ISO_Prev_Group_Lock = $FE0B; + XK_ISO_First_Group = $FE0C; + XK_ISO_First_Group_Lock = $FE0D; + XK_ISO_Last_Group = $FE0E; + XK_ISO_Last_Group_Lock = $FE0F; + + XK_ISO_Left_Tab = $FE20; + XK_ISO_Move_Line_Up = $FE21; + XK_ISO_Move_Line_Down = $FE22; + XK_ISO_Partial_Line_Up = $FE23; + XK_ISO_Partial_Line_Down = $FE24; + XK_ISO_Partial_Space_Left = $FE25; + XK_ISO_Partial_Space_Right = $FE26; + XK_ISO_Set_Margin_Left = $FE27; + XK_ISO_Set_Margin_Right = $FE28; + XK_ISO_Release_Margin_Left = $FE29; + XK_ISO_Release_Margin_Right = $FE2A; + XK_ISO_Release_Both_Margins = $FE2B; + XK_ISO_Fast_Cursor_Left = $FE2C; + XK_ISO_Fast_Cursor_Right = $FE2D; + XK_ISO_Fast_Cursor_Up = $FE2E; + XK_ISO_Fast_Cursor_Down = $FE2F; + XK_ISO_Continuous_Underline = $FE30; + XK_ISO_Discontinuous_Underline = $FE31; + XK_ISO_Emphasize = $FE32; + XK_ISO_Center_Object = $FE33; + XK_ISO_Enter = $FE34; + + //from cursorfont.h + XC_num_glyphs = 154; + XC_X_cursor = 0; + XC_arrow = 2; + XC_based_arrow_down = 4; + XC_based_arrow_up = 6; + XC_boat = 8; + XC_bogosity = 10; + XC_bottom_left_corner = 12; + XC_bottom_right_corner = 14; + XC_bottom_side = 16; + XC_bottom_tee = 18; + XC_box_spiral = 20; + XC_center_ptr = 22; + XC_circle = 24; + XC_clock = 26; + XC_coffee_mug = 28; + XC_cross = 30; + XC_cross_reverse = 32; + XC_crosshair = 34; + XC_diamond_cross = 36; + XC_dot = 38; + XC_dotbox = 40; + XC_double_arrow = 42; + XC_draft_large = 44; + XC_draft_small = 46; + XC_draped_box = 48; + XC_exchange = 50; + XC_fleur = 52; + XC_gobbler = 54; + XC_gumby = 56; + XC_hand1 = 58; + XC_hand2 = 60; + XC_heart = 62; + XC_icon = 64; + XC_iron_cross = 66; + XC_left_ptr = 68; + XC_left_side = 70; + XC_left_tee = 72; + XC_leftbutton = 74; + XC_ll_angle = 76; + XC_lr_angle = 78; + XC_man = 80; + XC_middlebutton = 82; + XC_mouse = 84; + XC_pencil = 86; + XC_pirate = 88; + XC_plus = 90; + XC_question_arrow = 92; + XC_right_ptr = 94; + XC_right_side = 96; + XC_right_tee = 98; + XC_rightbutton = 100; + XC_rtl_logo = 102; + XC_sailboat = 104; + XC_sb_down_arrow = 106; + XC_sb_h_double_arrow = 108; + XC_sb_left_arrow = 110; + XC_sb_right_arrow = 112; + XC_sb_up_arrow = 114; + XC_sb_v_double_arrow = 116; + XC_shuttle = 118; + XC_sizing = 120; + XC_spider = 122; + XC_spraycan = 124; + XC_star = 126; + XC_target = 128; + XC_tcross = 130; + XC_top_left_arrow = 132; + XC_top_left_corner = 134; + XC_top_right_corner = 136; + XC_top_side = 138; + XC_top_tee = 140; + XC_trek = 142; + XC_ul_angle = 144; + XC_umbrella = 146; + XC_ur_angle = 148; + XC_watch = 150; + XC_xterm = 152; + + {$ifdef FPC} +// threadslib = 'pthread'; + Xlibmodulename = 'X11'; + {$endif} + sXlib = Xlibmodulename; + pixel0 = $000000; + pixel1 = $ffffff; +type + Bool = cint; + XID = type culong; +// TXICCEncodingStyle = (XStringStyle,XCompoundTextStyle,XTextStyle, +// XStdICCTextStyle,XUTF8StringStyle); +{$ifdef FPC} + Colormap = TXID; + Atom = type culong; +// Atom = type longword; + Cursor = TXID; + ppwchar_t = ^pwchar_t; +{$endif} + wchar_t = longword; + pwchar_t = ^wchar_t; + patom = ^atom; + atomarty = array of atom; + atomaty = array[0..0] of atom; + patomaty = ^atomaty; + ulongarty = array of culong; + +function msedisplay: pdisplay; +function msevisual: pvisual; +//function mserootwindow(id: winidty = 0): winidty; +function msedefaultscreen: pscreen; +function msedefaultscreenno: integer; + +{$ifdef FPC} + {$PACKRECORDS C} +{$else} + {$ALIGN 4} + {$MINENUMSIZE 4} +{$endif} + +type + _XIM = record end; + XIM = ^_XIM; + _XIC = record end; + XIC = ^_XIC; + ppucs4char = ^pucs4char; + dword = longword; + + VisualID = culong; + Visual = record + ext_data: PXExtData; { hook for extension to hang data } + visualid: VisualID; { visual id of this visual } + _class: cint; + red_mask: culong; + green_mask: culong; + blue_mask: culong; + bits_per_rgb: cint; + map_entries: cint; + end; + msepvisual = ^visual; + +(* + VisualID = dword; + Visual = record + ext_data: PXExtData; { hook for extension to hang data } + visualid: VisualID; { visual id of this visual } + _class: Longint; + red_mask: longword; + green_mask: longword; + blue_mask: longword; + bits_per_rgb: Longint; + map_entries: Longint; + end; + msepvisual = ^visual; +*) + PXWMHints = ^XWMHints; + XWMHints = record + flags: clong; { marks which fields in this structure are defined } + input: Bool; { does this application rely on the window manager to get keyboard input? } + initial_state: Longint; { see below } + icon_pixmap: xid; { pixmap to be used as icon } + icon_window: xid; { window to be used as icon } + icon_x: cint; { initial position of icon } + icon_y: cint; + icon_mask: xid; { icon mask bitmap } + window_group: XID; { id of related window group } + { this structure may be extended in the future } + end; + +{ definition for flags of XWMHints } +const + InputHint = 1 shl 0; + StateHint = 1 shl 1; + IconPixmapHint = 1 shl 2; + IconWindowHint = 1 shl 3; + IconPositionHint = 1 shl 4; + IconMaskHint = 1 shl 5; + WindowGroupHint = 1 shl 6; + AllHints = (((((InputHint or StateHint) or IconPixmapHint) or IconWindowHint) + or IconPositionHint) or IconMaskHint) or WindowGroupHint; + XUrgencyHint = 1 shl 8; + +type + MwmHints = record + flags: culong; + functions: culong; + decorations: culong; + input_mode: clong; + status: culong + end; + +const + MWM_HINTS_FUNCTIONS = 1 shl 0; + MWM_HINTS_DECORATIONS = 1 shl 1; + + MWM_FUNC_ALL = 1 shl 0; + MWM_FUNC_RESIZE = 1 shl 1; + MWM_FUNC_MOVE = 1 shl 2; + MWM_FUNC_MINIMIZE = 1 shl 3; + MWM_FUNC_MAXIMIZE = 1 shl 4; + MWM_FUNC_CLOSE = 1 shl 5; +{ +type + TXICCEncodingStyle = (XStringStyle,XCompoundTextStyle,XTextStyle, + XStdICCTextStyle,XUTF8StringStyle); + } +function XSetWMHints(Display: PDisplay; W: xid; WMHints: PXWMHints): cint; cdecl; + external sXLib name 'XSetWMHints'; +function XSetForeground(Display: PDisplay; GC: TGC; + Foreground: culong): cint; cdecl; external sXLib name 'XSetForeground'; + //bug in borland Xlib.pas +procedure XDrawImageString(Display: PDisplay; D: TDrawable; GC: TGC; + X, Y: Integer; S: PChar; Len: Integer); cdecl; + external sXLib name 'XDrawImageString'; +procedure XDrawImageString16(Display: PDisplay; D: TDrawable; GC: TGC; + X, Y: Integer; S: Pxchar2b; Len: Integer); cdecl; + external sXLib name 'XDrawImageString16'; +procedure XDrawString16(Display: PDisplay; D: TDrawable; GC: TGC; + X, Y: Integer; S: Pxchar2b; Len: Integer); cdecl; + external sXLib name 'XDrawString16'; +function XOpenIM(Display: PDisplay; rdb: PXrmHashBucketRec; + res_name: pchar; res_class: pchar): XIM; cdecl; + external sXLib name 'XOpenIM'; +function XCloseIM(IM: XIM): TStatus; cdecl; + external sXLib name 'XCloseIM'; +function XCreateIC(IM: XIM): XIC; cdecl; varargs; + external sXLib name 'XCreateIC'; +procedure XDestroyIC(IC: XIC); cdecl; + external sXLib name 'XDestroyIC'; +function XSetLocaleModifiers(modifier_list: pchar): pchar; cdecl; + external sXLib name 'XSetLocaleModifiers'; +function XSetICValues(IC: XIC): PChar; cdecl; varargs; + external sXLib name 'XSetICValues'; +function XSetIMValues(IC: XIM): PChar; cdecl; varargs; + external sXLib name 'XSetIMValues'; +//function XSetICValues(para1:XIC; dotdotdot:array of const):Pchar;cdecl; +// external sXLib name 'XSetICValues'; +function XGetICValues(IC: XIC): PChar; cdecl; varargs; + external sXLib name 'XGetICValues'; +procedure XSetICFocus(IC: XIC); cdecl; + external sXLib name 'XSetICFocus'; +procedure XUnsetICFocus(IC: XIC); cdecl; + external sXLib name 'XUnsetICFocus'; +{ +function XwcLookupString(IC: XIC; Event: PXKeyPressedEvent; + BufferReturn: Pucs4char; WCharsBuffer: Longint; KeySymReturn: PKeySym; + StatusReturn: PStatus): Longint; cdecl; + external sXLib name 'XwcLookupString'; +} +function Xutf8LookupString(IC: XIC; Event: PXKeyPressedEvent; + BufferReturn: Pchar; CharsBuffer: Longint; KeySymReturn: PKeySym; + StatusReturn: PStatus): Longint; cdecl; + external sXLib name 'Xutf8LookupString'; +(* +function XwcTextListToTextProperty(para1:PDisplay; para2:PPucs4Char; + para3: integer; para4: integer{TXICCEncodingStyle}; + para5:PXTextProperty): integer;cdecl; + external sXLib name 'XwcTextListToTextProperty'; +*) +function XCreateImage(Display: PDisplay; Visual: msePVisual; Depth: longword; + Format: Longint; Offset: Longint; Data: PChar; Width, Height: longword; + BitmapPad: Longint; BytesPerLine: Longint): PXImage; cdecl; + external sXLib name 'XCreateImage'; +function Xutf8TextListToTextProperty(para1:PDisplay; para2:PPchar; + para3: integer; para4: integer{TXICCEncodingStyle}; + para5: PXTextProperty): integer; cdecl; + external sXLib name 'Xutf8TextListToTextProperty'; + +function Xutf8TextPropertyToTextList(para1:PDisplay; para2:PXTextProperty; + para3:PPPchar; para4: pinteger): integer; cdecl; + external sXlib name 'Xutf8TextPropertyToTextList'; + +implementation +uses + msebits,msekeyboard,sysutils,msesysutils,msefileutils,msedatalist,msedragglob + {$ifdef with_sm},sm,ice{$endif},msesonames,msegui,mseactions,msex11gdi, + msearrayutils,msesysintf1,msesysdnd,classes,rtlconsts,mseclasses, + mseglob,msetimer,mseprocess,mseprocmonitor,typinfo + {$ifdef mse_debug},mseformatstr{$endif}; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + xdndprotocolversion = 4; +var + pixmapcount: integer; + +type + pwinid = ^TXID; + + twindow1 = class(msegui.twindow); + tguiapplication1 = class(tguiapplication); + tcanvas1 = class(tcanvas); + +{$ifdef FPC} + {$macro on} + {$define xchar2b:=txchar2b} + {$define xcharstruct:=txcharstruct} + {$define xfontstruct:=txfontstruct} + {$define xfontprop:=txfontprop} + {$define xpoint:=txpoint} + {$define xgcvalues:=txgcvalues} + {$define region:=tregion} + {$define ximage:=tximage} + {$define xwindowattributes:=txwindowattributes} + {$define xclientmessageevent:=txclientmessageevent} + {$define xselectionevent:= txselectionevent} + {$define xselectionclearevent:=txselectionclearevent} + {$define xselectionrequestevent:=txselectionrequestevent} + {$define xtype:=_type} + {$define xrectangle:=txrectangle} + {$define keysym:=tkeysym} + {$define xsetwindowattributes:=txsetwindowattributes} + {$define xwindowchanges:=txwindowchanges} + {$define xevent:=txevent} + {$define xfunction:=_function} + {$define xwindow:=window} + {$define xlookupkeysym_:=xlookupkeysymval} + {$define c_class:= _class} + {$define xtextproperty:= txtextproperty} + {$define xcolor:= txcolor} + {$define xpointer:= txpointer} + TXIMProc = procedure (para1:PXIM; para2:XPointer; para3:XPointer);cdecl; + + TXICProc = function (para1:PXIC; para2:XPointer; para3:XPointer):TBool;cdecl; + PXIMCallback = ^TXIMCallback; + TXIMCallback = record + client_data : TXPointer; + callback : TXIMProc; + end; + + PXICCallback = ^TXICCallback; + TXICCallback = record + client_data : TXPointer; + callback : TXICProc; + end; +{$else} + tboolresult = longbool; + PXIM = ^TXIM; + TXIM = record + end; + + PXIC = ^TXIC; + TXIC = record + end; + TXIMProc = procedure (para1:TXIM; para2:XPointer; para3:XPointer);cdecl; + + TXICProc = function (para1:TXIC; para2:XPointer; para3:XPointer):TBool;cdecl; + PXIMCallback = ^TXIMCallback; + TXIMCallback = record + client_data : XPointer; + callback : TXIMProc; + end; + + PXICCallback = ^TXICCallback; + TXICCallback = record + client_data : XPointer; + callback : TXICProc; + end; +{$endif} + +const + x_copyarea = 62; + IsUnmapped = 0; + IsUnviewable = 1; + IsViewable = 2; + +{ definitions for initial window state } +{ for windows that are not mapped } + WithdrawnState = 0; + {$EXTERNALSYM WithdrawnState} +{ most applications want to start this way } + NormalState = 1; + {$EXTERNALSYM NormalState} +{ application wants to start as an icon } + IconicState = 3; + {$EXTERNALSYM IconicState} +{ Obsolete states no longer defined by ICCCM } +{ don't know or care } + DontCareState = 0; + {$EXTERNALSYM DontCareState} +{ application wants to start zoomed } + ZoomState = 2; + {$EXTERNALSYM ZoomState} +{ application believes it is seldom used; } + InactiveState = 4; + {$EXTERNALSYM InactiveState} + +type + + x11windowdty = record + ic: xic; + end; + x11windowty = record + case integer of + 0: (d: x11windowdty;); + 1: (_bufferspace: windowpty;); + end; + +const + atombits = sizeof(atom)*8; + mouseeventmask = buttonpressmask or buttonreleasemask or pointermotionmask; + + + { + cursorshapety = (cr_default, + cr_none,cr_arrow,cr_cross,cr_wait,cr_ibeam, + cr_sizever,cr_sizehor,cr_sizebdiag,cr_sizefdiag,cr_sizeall, + cr_splitv,cr_splith,cr_pointinghand,cr_forbidden,cr_drag, + cr_topleftcorner,cr_bottomleftcorner, + cr_bottomrightcorner,cr_toprightcorner, + cr_res0,cr_res1,cr_res2,cr_res3,cr_res4,cr_res5,cr_res6,cr_res7, + cr_user); + } + defaultshape = xc_left_ptr; + standardcursors: array[cursorshapety] of longword = ( + defaultshape,defaultshape,defaultshape, + xc_left_ptr,{xc_tcross}xc_crosshair,xc_watch,xc_xterm, + xc_sb_v_double_arrow,xc_sb_h_double_arrow,xc_top_right_corner, + xc_bottom_right_corner,xc_fleur, + xc_sb_v_double_arrow,xc_sb_h_double_arrow,xc_hand2,xc_circle,xc_sailboat, + xc_top_left_corner,xc_bottom_left_corner, + xc_bottom_right_corner,xc_top_right_corner, + defaultshape,defaultshape,defaultshape,defaultshape, + defaultshape,defaultshape,defaultshape,defaultshape, + defaultshape); +type + wmprotocolty = (wm_delete_window + {$ifdef with_saveyourself},wm_save_yourself{$endif}); + XErrorHandler = function (Display: PDisplay; ErrorEvent: PXErrorEvent): + Longint; cdecl; + wmstatety = (wms_none,wms_withdrawn,wms_normal,wms_invalid,wms_iconic); + +var + xlockerror: integer = 0; + appdisp: pdisplay; + appid: winidty; +// defscreenid: cint; + defscreen: pscreen; + defvisual: msepvisual; + defdepth: integer; + msecolormap: colormap; + istruecolor: boolean; + is8bitcolor: boolean; + xredmask,xgreenmask,xbluemask: longword; + xredshift,xgreenshift,xblueshift: integer; + xredshiftbase,xgreenshiftbase,xblueshiftbase: integer; + xredshiftleft,xgreenshiftleft,xblueshiftleft: boolean; + defcolormap: colormap; + hassm: boolean; + hasxrandrlib: boolean; + hasxrandr: boolean; + xrandreventbase: cint; + xrandrerrorbase: cint; + + numlockstate: cuint; + rootid: winidty; + lastfocuswindow: winidty; + atomatom: atom; + mseclientmessageatom,{timeratom,wakeupatom,} + wmprotocolsatom,wmstateatom,wmnameatom,wmclassatom: atom; + wmtransientforatom,wmclientleaderatom: atom; + wmprotocols: array[wmprotocolty] of atom; +// clipboardatom: atom; + cardinalatom,windowatom,stringatom,utf8_stringatom,compound_textatom, + textatom,textplainatom: atom; + timestampatom: atom; + multipleatom: atom; + targetsatom: atom; + convertselectionpropertyatom: atom; + + {$ifdef with_sm} +type + sminfoty = record + iceconnection: iceconn; + smconnection: smcconn; + fd: integer; + shutdown: boolean; + shutdownpending: boolean; + interactstyle: integer; + interactwaiting,interactgranted: boolean; + end; + psminfoty = ^sminfoty; +var + sminfo: sminfoty; + {$endif} + + {$ifdef with_saveyourself} + wmcommandatom: atom; + saveyourselfwindow: integer; + {$endif} + +type + netatomty = + (net_supported, + //suports checked below + net_workarea, + net_wm_state, + net_wm_state_maximized_vert,net_wm_state_maximized_horz, + //not needed below + net_wm_window_type, + net_wm_state_fullscreen, + net_wm_state_skip_taskbar,net_wm_state_demands_attention, + net_restack_window,net_close_window,net_active_window, + //not supports checked below + net_wm_pid,net_wm_desktop, + + net_wm_window_type_desktop, + net_wm_window_type_dock, + net_wm_window_type_toolbar, + net_wm_window_type_menu, + net_wm_window_type_utility, + net_wm_window_type_splash, + net_wm_window_type_dialog, + net_wm_window_type_dropdown_menu, + net_wm_window_type_popup_menu, + net_wm_window_type_tooltip, + net_wm_window_type_notification, + net_wm_window_type_combo, + net_wm_window_type_dnd, + net_wm_window_type_normal, + net_wm_icon, + net_wm_name, + + net_frame_extents, + net_request_frame_extents, + net_system_tray_s0,net_system_tray_opcode,net_system_tray_message_data, + xembed,xembed_info,motif_wm_hints,wm_normal_hints, + //onlyifexist below + net_wm_window_opacity, + + net_none //dummy +); + netwmstateoperationty = (nso_remove,nso_add,nso_toggle); +const + needednetatom = net_wm_state_maximized_horz; + firstcheckedatom = net_workarea; + lastcheckedatom = net_active_window; + firstonlyifexistatom = net_wm_window_opacity; + netatomnames: array[netatomty] of string = + ('_NET_SUPPORTED','_NET_WORKAREA', + '_NET_WM_STATE', + '_NET_WM_STATE_MAXIMIZED_VERT','_NET_WM_STATE_MAXIMIZED_HORZ', + //not needed below + '_NET_WM_WINDOW_TYPE', + '_NET_WM_STATE_FULLSCREEN', + '_NET_WM_STATE_SKIP_TASKBAR','_NET_WM_STATE_DEMANDS_ATTENTION', + '_NET_RESTACK_WINDOW','_NET_CLOSE_WINDOW','_NET_ACTIVE_WINDOW', + '_NET_WM_PID','_NET_WM_DESKTOP', + + '_NET_WM_WINDOW_TYPE_DESKTOP', + '_NET_WM_WINDOW_TYPE_DOCK', + '_NET_WM_WINDOW_TYPE_TOOLBAR', + '_NET_WM_WINDOW_TYPE_MENU', + '_NET_WM_WINDOW_TYPE_UTILITY', + '_NET_WM_WINDOW_TYPE_SPLASH', + '_NET_WM_WINDOW_TYPE_DIALOG', + '_NET_WM_WINDOW_TYPE_DROPDOWN_MENU', + '_NET_WM_WINDOW_TYPE_POPUP_MENU', + '_NET_WM_WINDOW_TYPE_TOOLTIP', + '_NET_WM_WINDOW_TYPE_NOTIFICATION', + '_NET_WM_WINDOW_TYPE_COMBO', + '_NET_WM_WINDOW_TYPE_DND', + '_NET_WM_WINDOW_TYPE_NORMAL', + '_NET_WM_ICON', + '_NET_WM_NAME', + + '_NET_FRAME_EXTENTS', + '_NET_REQUEST_FRAME_EXTENTS', + '_NET_SYSTEM_TRAY_S0','_NET_SYSTEM_TRAY_OPCODE', + '_NET_SYSTEM_TRAY_MESSAGE_DATA', + '_XEMBED','_XEMBED_INFO', + '_MOTIF_WM_HINTS','WM_NORMAL_HINTS', + '_NET_WM_WINDOW_OPACITY', + ''); +// needednetatom = netatomty(ord(high(netatomty))-4); +type + xdndatomty = (xdnd_aware,xdnd_selection,xdnd_typelist, + xdnd_actionlist,xdnd_actiondescription,xdnd_proxy, + xdnd_enter,xdnd_position,xdnd_status,xdnd_leave,xdnd_drop,xdnd_finished + ); +const + xdndatomnames: array[xdndatomty] of string = ( + 'XdndAware','XdndSelection','XdndTypeList', + 'XdndActionList','XdndActionDescription','XdndProxy', + 'XdndEnter','XdndPosition','XdndStatus','XdndLeave','XdndDrop','XdndFinished' + ); + xdndactionatomnames: array[dndactionty] of string = ( + 'XdndActionCopy','XdndActionMove','XdndActionLink','XdndActionAsk', + 'XdndActionPrivate' + ); + +type + clipboardinfoty = record + name: atom; + buffer: msestring; + timestamp: ttime; + end; +const + clipboardnames: array[clipboardbufferty] of string = ('CLIPBOARD','PRIMARY'); + +var + netatoms: array[netatomty] of atom; + xdndatoms: array[xdndatomty] of atom; + xdndactionatoms: array[dndactionty] of atom; + + netsupported: boolean; + canfullscreen: boolean; + canframeextents: boolean; + netsupportedatom: atom; + + sigtimerbefore: sighandler_t; + sigtermbefore: sighandler_t; + sigchldbefore: sighandler_t; + + timerevent: boolean; + terminated: boolean; + childevent: boolean; +// cursorshape: cursorshapety; +// screencursor: cursor; + im: xim; + appic: xic; + appicmask: longword; +// icwindow: windowty; + imewinid: winidty; + errorhandlerbefore: xerrorhandler; + lasteventtime: ttime; +// lastshiftstate: shiftstatesty; + clipboardbuffers: array[clipboardbufferty] of clipboardinfoty; + fidnum: integer; + +procedure deleteitemat(var dest: atomarty; index: integer); overload; +begin + if (index < 0) or (index > high(dest)) then begin + tlist.Error(SListIndexError, Index); + end; + move(dest[index+1],dest[index],sizeof(dest[0])*(high(dest)-index)); + setlength(dest,high(dest)); +end; + +procedure deleteitemwi(var dest: winidarty; index: integer); overload; +begin + if (index < 0) or (index > high(dest)) then begin + tlist.Error(SListIndexError, Index); + end; + move(dest[index+1],dest[index],sizeof(dest[0])*(high(dest)-index)); + setlength(dest,high(dest)); +end; + +procedure usevariables; +begin + if (multipleatom = 0) and (wmnameatom = 0) and (defcolormap = 0) then begin + end; +end; + +function getidnum: longword; +begin + result:= interlockedincrement(fidnum); + if result = 0 then begin + result:= interlockedincrement(fidnum); + end; +end; + +type + ucs4string = array of wchar_t; + +function msestringtoucs4string(const value: msestring): ucs4string; +var + po1: pmsechar; + po2: pwchar_t; + ca1: ucs4char; +begin + setlength(result,length(value)+1); //max + po1:= pmsechar(value); + po2:= pwchar_t(result); + while true do begin + ca1:= card16(po1^); + if ca1 and $fc00 = $d800 then begin + inc(po1); + if (card16(po1^) and $fc00 = $dc00) then begin + ca1:= ((ca1 + ($0040-$d800)) shl 10) + card16(po1^) - $dc00; + end; + end; + po2^:= ca1; + inc(po1); + inc(po2); + if ca1 = 0 then begin + break; + end; + end; + setlength(result,po2-pwchar_t(pointer(result))); +end; + +procedure setstringproperty(id: winidty; prop: atom; value: string); +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + xchangeproperty(appdisp,id,prop,stringatom,8,propmodereplace, + pbyte(pchar(value)),length(value)+1); +end; + +procedure setmsestringproperty(id: winidty; prop: atom; const value: msestring); +var + str1: string; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + str1:= stringtoutf8(value); + xchangeproperty(appdisp,id,prop,utf8_stringatom,8,propmodereplace, + pbyte(pchar(str1)),length(str1)+1); +end; + +procedure setwinidproperty(id: winidty; prop: atom; value: winidty); +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + xchangeproperty(appdisp,id,prop,windowatom,32,propmodereplace,@value,1); +end; + +procedure setlongproperty(id: winidty; prop: atom; value: culong); overload; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + xchangeproperty(appdisp,id,prop,cardinalatom,32,propmodereplace,@value,1); +end; + +procedure setlongproperty(const id: winidty; const prop: atom; + const value: array of culong; + const datatype: atom); overload; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + if (prop <> 0) and (datatype <> 0) then begin + xchangeproperty(appdisp,id,prop,datatype,32,propmodereplace,@value, + length(value)); + end; +end; + +function readatomproperty(id: winidty; name: atom; var value: atomarty): boolean; +var + actualtype: atom; + actualformat: cint; + nitems: clong; + bytesafter: culong; + prop: pchar; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= false; + if xgetwindowproperty(appdisp,id,name,0,10000,{$ifdef xboolean}false{$else}0{$endif}, + atomatom,@actualtype,@actualformat,@nitems,@bytesafter,@prop) = success then begin + if (actualtype = atomatom) and (actualformat = 32) then begin + setlength(value,nitems); + if nitems > 0 then begin + {$ifdef FPC} {$checkpointer off} {$endif} + move(prop^,value[0],nitems*sizeof(value[0])); + {$ifdef FPC} {$checkpointer default} {$endif} + end; + result:= true; + end; + xfree(prop); + end; +end; + +procedure setatomproperty(id: winidty; prop: atom; value: atom); +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + xchangeproperty(appdisp,id,prop,atomatom,32,propmodereplace,@value,1); +end; + +procedure setatomarrayitemproperty(id: winidty; prop: atom; value: atom); +var + ar1: atomarty; + int1: integer; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + readatomproperty(id,prop,ar1); + for int1:= 0 to high(ar1) do begin + if ar1[int1] = value then begin + exit; //already set + end; + end; + setlength(ar1,high(ar1)+2); + ar1[high(ar1)]:= value; + xchangeproperty(appdisp,id,prop,atomatom,32,propmodereplace, + pointer(ar1),length(ar1)); +end; + +procedure resetatomarrayitemproperty(id: winidty; prop: atom; value: atom); +var + ar1: atomarty; + int1: integer; + bo1: boolean; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + readatomproperty(id,prop,ar1); + bo1:= false; + for int1:= high(ar1) downto 0 do begin + if ar1[int1] = value then begin + deleteitemat(ar1,int1); + bo1:= true; + end; + end; + if bo1 then begin + xchangeproperty(appdisp,id,prop,atomatom,32,propmodereplace,pointer(ar1), + length(ar1)); + end; +end; + +function readcardinalproperty(id: winidty; name: atom; count: longword; + var value): boolean; +var + actualtype: atom; + actualformat: cint; + nitems: clong; + bytesafter: culong; + prop: pchar; + {$ifdef CPU64} + int1: integer; + po1: pculong; + po2: plongword; + {$endif} +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= false; + if xgetwindowproperty(appdisp,id,name,0,count,{$ifdef xboolean}false{$else}0{$endif}, + anypropertytype,@actualtype,@actualformat,@nitems,@bytesafter,@prop) = success then begin + if (nitems = count) and (actualformat = 32) then begin +{$ifdef CPU64} + po1:= pointer(prop); + po2:= @value; + for int1:= count-1 downto 0 do begin + po2^:= po1^; + inc(po1); + inc(po2); + end; +{$else} + {$ifdef FPC} {$checkpointer off} {$endif} + move(prop^,value,nitems*sizeof(longword)); + {$ifdef FPC} {$checkpointer default} {$endif} +{$endif} + result:= true; + end; + xfree(prop); + end; +end; + +function readcardinallistproperty(const id: winidty; const name: atom; + out value: longwordarty): boolean; +var + actualtype: atom; + actualformat: cint; + nitems: clong; + bytesafter: culong; + prop: pchar; + {$ifdef CPU64} + int1: integer; + po1: pculong; + po2: plongword; + {$endif} +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= false; + if xgetwindowproperty(appdisp,id,name,0,bigint,{$ifdef xboolean}false{$else}0{$endif}, + anypropertytype,@actualtype,@actualformat, + @nitems,@bytesafter,@prop) = success then begin + if actualformat = 32 then begin + setlength(value,nitems); +{$ifdef CPU64} + po1:= pointer(prop); + po2:= pointer(value); + for int1:= nitems-1 downto 0 do begin + po2^:= po1^; + inc(po1); + inc(po2); + end; +{$else} + {$ifdef FPC} {$checkpointer off} {$endif} + move(prop^,value,nitems*sizeof(value[0])); + {$ifdef FPC} {$checkpointer default} {$endif} + result:= true; +{$endif} + end; + xfree(prop); + end; +end; + +function stringtotextproperty(const value: msestring; + const style: txiccencodingstyle; + out textproperty: xtextproperty): boolean; +var + listxwctext: array[0..0] of ucs4string; + listutf8: array[0..0] of pchar; + str1: string; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + if style = xstdicctextstyle then begin + listxwctext[0]:= msestringtoucs4string(value); + result:= xwctextlisttotextproperty(appdisp,@listxwctext,1,style, + @textproperty) >= 0; + end + else begin + str1:= stringtoutf8ansi(value); + listutf8[0]:= pchar(str1); + result:= xutf8textlisttotextproperty( + appdisp,@listutf8,1,ord(style),@textproperty) >= 0; + end; + if not result then begin + fillchar(textproperty,0,sizeof(textproperty)); + end; +end; + + +function setnetstring(const id: winidty; const aproperty: netatomty; + const avalue: msestring): boolean; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= false; + if netatoms[aproperty] <> 0 then begin + setmsestringproperty(id,netatoms[aproperty],avalue); + result:= true; + end; +end; + +function setnetcardinal(const id: winidty; const aproperty: netatomty; + const avalue: longword): boolean; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= false; + if netatoms[aproperty] <> 0 then begin + setlongproperty(id,netatoms[aproperty],avalue); + result:= true; + end; +end; + +function getnetcardinal(const id: winidty; const aproperty: netatomty; + out avalue: longword): boolean; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= false; + if netatoms[aproperty] <> 0 then begin + result:= readcardinalproperty(id,netatoms[aproperty],1,avalue); + end; +end; + +function setnetatom(const id: winidty; const aproperty: netatomty; + const avalue: netatomty): boolean; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= false; + if (netatoms[aproperty] <> 0) and (netatoms[avalue] <> 0) then begin + setatomproperty(id,netatoms[aproperty],netatoms[avalue]); + result:= true; + end; +end; + +function setnetatomarrayitem(const id: winidty; const aproperty: netatomty; + const avalue: netatomty): boolean; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= false; + if (netatoms[aproperty] <> 0) and (netatoms[avalue] <> 0) then begin + setatomarrayitemproperty(id,netatoms[aproperty],netatoms[avalue]); + result:= true; + end; +end; + +function resetnetatomarrayitem(const id: winidty; const aproperty: netatomty; + const avalue: netatomty): boolean; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= false; + if (netatoms[aproperty] <> 0) and (netatoms[avalue] <> 0) then begin + resetatomarrayitemproperty(id,netatoms[aproperty],netatoms[avalue]); + result:= true; + end; +end; + +function gui_sethighrestimer(const avalue: boolean): guierrorty; +begin + result:= gue_ok; //dummy +end; + +function gui_grouphideminimizedwindows: boolean; +begin + result:= false; +end; +{ +function hasxft: boolean; +begin + result:= fhasxft; +end; +} +function gui_getdefaultfontnames: defaultfontnamesty; +begin + result:= x11getdefaultfontnames; +end; + +function gui_canstackunder: boolean; +begin + result:= not norestackwindow or not noreconfigurewmwindow; +end; + +function gui_copytoclipboard(const value: msestring; + const buffer: clipboardbufferty): guierrorty; +begin + gdi_lock; + with clipboardbuffers[buffer] do begin + buffer:= value; + timestamp:= lasteventtime; + // clipboardtimestamp:= clipboardtimestamp; //no "not used" compiler message + xsetselectionowner(appdisp,name,appid,lasteventtime); + result:= gue_ok; + end; + gdi_unlock; +end; + +function eventlater(const atime: ttime): boolean; +begin + result:= (atime = currenttime) or (lasteventtime = currenttime) or + laterorsame(lasteventtime,atime); +end; + +function pastefromclipboard(out value: string; const selection: atom; + const timestamp: longword; + const datatypes: array of atom; + out acttype: atom; out actformat: cint; + out nitems1: integer): guierrorty; +const + transferbuffersize = 1024 div 4; //1kb +var + clipboardowner: longword; + value1: string; +// nitems1: integer; +// acttype: atom; +// actformat: cint; + + function getdata(const target: atom; const resulttarget: atom): guierrorty; + var + event: xevent; + po1: pchar; + nitems: culong; + bytesafter: culong; + charoffset: integer; + longoffset: clong; + time1: longword; + int1: integer; + bo1{,bo2}: boolean; + begin + result:= gue_clipboard; + charoffset:= 1; + longoffset:= 0; + xdeleteproperty(appdisp,appid,convertselectionpropertyatom); + repeat //remove pending notifications +// until not (xcheckwindowevent(appdisp,appid, +// propertychangemask,@event) +// {$ifndef xbooleanresult} <> 0{$endif}); + until not (xchecktypedevent(appdisp,selectionnotify,@event) + {$ifndef xbooleanresult} <> 0{$endif}); + + xconvertselection(appdisp,selection,target,convertselectionpropertyatom, + appid,timestamp); + time1:= timestep(2000000); //2 sec + bo1:= true; + repeat +// bo1:= {not} (xcheckwindowevent(appdisp,appid, +// propertychangemask or selectionnotifymask,@event) +// {$ifndef xbooleanresult} <> 0 {$endif}); + bo1:= (xchecktypedevent(appdisp,selectionnotify,@event) + {$ifndef xbooleanresult} <> 0{$endif}); + + if bo1 then begin + case event.xany.xtype of + selectionnotify: begin + with event.xselection do begin + {$ifdef FPC} + if _property <> convertselectionpropertyatom then begin + {$else} + if xproperty <> convertselectionpropertyatom then begin + {$endif} + exit; + end; + end; + end; + else begin + exit; //error + end; + end; + end; +// if xcheckwindowevent(appdisp,appid,propertychangemask,@event) +// {$ifndef FPC} = 0 {$endif} then begin + if not bo1 then begin + if timeout(time1) then begin + exit; + end; + if bo1 then begin + bo1:= false; +// sys_threadschedyield; + sys_schedyield; + end + else begin + sleep(20); + end; + end + else begin +// with event.xproperty do begin + nitems1:= 0; + bytesafter:= 0; + value1:= ''; + repeat + if xgetwindowproperty(appdisp,appid,convertselectionpropertyatom, + longoffset,transferbuffersize,{$ifdef xboolean} true{$else}1{$endif}, + anypropertytype,@acttype,@actformat,@nitems,@bytesafter,@po1) = success then begin + if (resulttarget = 0) or (acttype = resulttarget) then begin + if actformat = 32 then begin + actformat:= atombits; + end; + int1:= (actformat div 8) * nitems; //bytecount + if nitems > 0 then begin + inc(nitems1,nitems); + setlength(value1,length(value1) + int1 ); + move(po1^,value1[charoffset],int1); + inc(charoffset,int1); + inc(longoffset,int1 div sizeof(dword)); +// inc(longoffset,int1 div sizeof(atom)); //32/64 bit + result:= gue_ok; + end; + end + else begin + bytesafter:= 0; + result:= gue_clipboard; + end; + xfree(po1); + end + else begin + if timeout(time1) then begin + exit; + end; + end; + until bytesafter = 0; + break; + end; +// end; + until false; + end; //getdata + +var + int1,int2: integer; + po1: patomaty; +// atoms1: array[0..4] of atom; + atom1: atom; + +begin + value1:= ''; + gdi_lock; + acttype:= 0; + actformat:= 0; + nitems1:= 0; + clipboardowner:= xgetselectionowner(appdisp,selection); + if clipboardowner = appid then begin +// value:= clipboard; + result:= gue_ok; + end + else begin + result:= gue_clipboard; + value:= ''; + if clipboardowner <> none then begin + atom1:= 0; + if high(datatypes) > 0 then begin + result:= getdata(targetsatom,atomatom); + if result = gue_ok then begin + po1:= pointer(value1); + for int2:= low(datatypes) to high(datatypes) do begin + for int1:= 0 to (length(value1) div sizeof(atom)) - 1 do begin + if po1^[int1] = datatypes[int2] then begin + atom1:= datatypes[int2]; + break; + end; + end; + if atom1 <> 0 then begin + break; + end; + end; + end; + end + else begin + if high(datatypes) = 0 then begin + atom1:= datatypes[0]; + end; + end; + if atom1 <> 0 then begin + result:= getdata(atom1,0); + if result = gue_ok then begin + value:= value1; + end; + end; + end; + end; + gdi_unlock; +end; + +function gui_pastefromclipboard(out value: msestring; + const buffer: clipboardbufferty): guierrorty; +var + value1: string; + acttype: atom; + actformat: cint; + nitems1: integer; + po2: ppchar; + prop1: xtextproperty; + int1: integer; +begin + gdi_lock(); + with clipboardbuffers[buffer] do begin + result:= pastefromclipboard(value1,name,lasteventtime, + [utf8_stringatom,compound_textatom,textatom,textplainatom,stringatom], + acttype,actformat,nitems1); + if result = gue_ok then begin + if acttype = 0 then begin + value:= buffer; + end + else begin + if acttype = utf8_stringatom then begin + value:= utf8tostringansi(value1); + end + else begin + if (acttype = textatom) or (acttype = textplainatom) then begin + value:= msestring(value1); //current locale + end + else begin + if acttype = compound_textatom then begin + with prop1 do begin + value:= pointer(value1); + encoding:= acttype; + format:= actformat; + nitems:= nitems1; + end; + xutf8textpropertytotextlist(appdisp,@prop1,@po2,@int1); + if int1 >= 1 then begin + value:= utf8tostringansi(string(po2^)); + end; + xfreestringlist(po2); + end + else begin + value:= latin1tostring(value1); + end; + end; + end; + end; + end; + end; + gdi_unlock(); +end; + +function gui_canpastefromclipboard(const buffer: clipboardbufferty): boolean; +begin + gdi_lock; + with clipboardbuffers[buffer] do begin + result:= xgetselectionowner(appdisp,name) <> none; + end; + gdi_unlock; +end; + +function windowmapped(const id: winidty): boolean; +var + attributes: xwindowattributes; +begin + xgetwindowattributes(appdisp,id,@attributes); + result:= attributes.map_state = isviewable; +end; + +function getwmstate(id: winidty): wmstatety; +type + wmstatety = record + state: longword; + icon: winidty; + end; + pwmstatety = ^wmstatety; + +var + typeatom: atom; + format: cint; + itemcount: culong; + po1: pwmstatety; + bytesafterreturn: culong; + +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= wms_none; + if xgetwindowproperty(appdisp,id,wmstateatom,0,2, + {$ifdef xboolean}false{$else}0{$endif},wmstateatom,@typeatom,@format, + @itemcount,@bytesafterreturn,@po1) = success then begin +{$ifdef FPC} {$checkpointer off} {$endif} + if (format = 32) and (itemcount = 2) then begin + longword(result):= po1^.state + longword(wms_withdrawn); + end; +{$ifdef FPC} {$checkpointer default} {$endif} + xfree(po1); + end; +end; + +function gui_getrootwindow(id: winidty = 0): winidty; +var + x,y: cint; + width,height,border,depth: cuint; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + if id <> 0 then begin + if xgetgeometry(appdisp,id,@result,@x,@y, + @width,@height,@border,@depth) <> 0 then begin + exit; + end; + end; + result:= rootid; +end; + +function gui_getwindowsize(id: winidty): windowsizety; +var + state: wmstatety; + atomar: atomarty; + int1: integer; + maxh,maxv: boolean; +begin + gdi_lock; + state:= getwmstate(id); + case state of + wms_iconic: begin + result:= wsi_minimized; + end; + else begin + result:= wsi_normal; + if netsupported and readatomproperty(id,netatoms[net_wm_state],atomar) then begin + maxh:= false; + maxv:= false; + for int1:= 0 to high(atomar) do begin + if atomar[int1] = netatoms[net_wm_state_fullscreen] then begin + result:= wsi_fullscreen; + break; + end; + if (atomar[int1] = netatoms[net_wm_state_maximized_vert]) then begin + maxv:= true; + end + else begin + if (atomar[int1] = netatoms[net_wm_state_maximized_horz]) then begin + maxh:= true; + end; + end; + end; + if (result = wsi_normal) and maxh and maxv then begin + result:= wsi_maximized; + end; + end; + end; + end; + gdi_unlock; +end; + +function gui_getwindowdesktop(const id: winidty): integer; +var + lwo1: longword; +begin + result:= 0; + if getnetcardinal(id,net_wm_desktop,lwo1) then begin + result:= lwo1; + end; +end; + +function changenetwmstate(id: winidty; const operation: netwmstateoperationty; + const value1: netatomty; const value2: netatomty = net_none): boolean; +var + xevent: xclientmessageevent; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= false; + if netsupported then begin + fillchar(xevent,sizeof(xevent),0); + with xevent do begin + xtype:= clientmessage; + display:= appdisp; + xwindow:= id; + format:= 32; + message_type:= netatoms[net_wm_state]; + data.l[0]:= ord(operation); + data.l[1]:= netatoms[value1]; + data.l[2]:= netatoms[value2]; + if xsendevent(appdisp,gui_getrootwindow(id), + {$ifdef xboolean}false{$else}0{$endif}, + substructurenotifymask or + substructureredirectmask,@xevent) <> 0 then begin + result:= true; + end; + end; + end; +end; + +function sendnetcardinalmessage(const adest: winidty; const messagetype: atom; + const aid: winidty; const adata: array of longword; + const amask: longword = noeventmask): boolean; + //true if ok +var + xevent: xclientmessageevent; + int1: integer; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= netsupported and (messagetype <> 0) and (high(adata) <= 4); + if result then begin + fillchar(xevent,sizeof(xevent),0); + with xevent do begin + xtype:= clientmessage; + display:= appdisp; + xwindow:= aid; + format:= 32; + message_type:= messagetype; + for int1:= 0 to high(adata) do begin + data.l[int1]:= adata[int1]; + end; + result:= xsendevent(appdisp,adest, + {$ifdef xboolean}false{$else}0{$endif},amask,@xevent) <> 0; + end; + end; +end; + +function sendnetrootcardinalmessage(const messagetype: atom; + const aid: winidty; const adata: array of longword): boolean; + //true if ok +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= sendnetcardinalmessage(rootid,messagetype,aid,adata, + substructurenotifymask or substructureredirectmask); +end; + +function waitfordecoration(id: winidty; raiseexception: boolean = true): boolean; +var + int1: integer; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + int1:= 0; + result:= false; + repeat + xsync(appdisp,0); //windowmanager has to work +// xflush(appdisp); //windowmanager has to work + sys_schedyield; + if gui_windowvisible(id) then begin + result:= true; + break; + end; +// xflush(appdisp); //windowmanager has to work + sleep(5*int1); + inc(int1); + until (int1 > 45); + if raiseexception and not result then begin + raise exception.Create('not decorated'); + end; +end; + +function gui_setwindowstate(id: winidty; size: windowsizety; + visible: boolean): guierrorty; + procedure fullscreen; + begin + if size = wsi_fullscreenvirt then begin + gui_reposwindow(id,gui_getscreenrect(0)); + end + else begin + gui_reposwindow(id,gui_getscreenrect(id)); + end + end; + +begin + gdi_lock; + result:= gue_ok; + if visible then begin +{$ifdef mse_debugshow} + debugwindow('*gui_setwindowstate xmapwindow ',id); +{$endif} + if (getwmstate(id) = wms_iconic) and windowmapped(id) and + (netatoms[net_active_window] <> 0)then begin + //probably gnome mutter + sendnetrootcardinalmessage(netatoms[net_active_window],id, + [1,lasteventtime,lastfocuswindow]); + end + else begin + xmapwindow(appdisp,id); + end; + end; + if size in [wsi_fullscreen,wsi_fullscreenvirt] then begin + if not canfullscreen or + not changenetwmstate(id,nso_add,net_wm_state_fullscreen) then begin + fullscreen; //no windowmanager + end; + end + else begin + changenetwmstate(id,nso_remove,net_wm_state_fullscreen); + case size of + wsi_minimized: begin + if xiconifywindow(appdisp,id,0) = 0 then begin + result:= gue_show; + end; + gdi_unlock; + exit; + end; + wsi_maximized: begin + if not changenetwmstate(id,nso_add, + net_wm_state_maximized_horz,net_wm_state_maximized_vert) then begin + fullscreen; + end; + end + else begin + changenetwmstate(id,nso_remove, + net_wm_state_maximized_horz,net_wm_state_maximized_vert); + end; + end; + end; + gdi_unlock; +end; + +procedure freetextproperty(const value: xtextproperty); +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + xfree(value.value); +end; + +function gui_setwindowcaption(id: winidty; + const caption: msestring): guierrorty; +var + textprop: xtextproperty; +begin + gdi_lock; + if stringtotextproperty(caption, + xstdicctextstyle{xutf8stringstyle},textprop) then begin + //jwm can not handle xutf8stringstyle + xsetwmname(appdisp,id,@textprop); + freetextproperty(textprop); + result:= gue_ok; + end + else begin + result:= gue_characterencoding; + end; + setnetstring(id,net_wm_name,caption); + gdi_unlock; +end; + +function gui_setwindowicon(id: winidty; const icon,mask: pixmapty): guierrorty; +var + hints: pxwmhints; + ima,maskima: imagety; + ps,pe,ps1: pbyte; + pd,pde: prgbtriplety; + ar1: longwordarty; + {$ifdef cpu64} +// ar2: qwordarty; + ar2: array of culong; + {$endif} + int1: integer; + bmask,lwo1: longword; + rgb1: rgbtriplety; + npixels: integer; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + hints:= pxwmhints(xgetwmhints(appdisp,id)); + if hints = nil then begin + hints:= pxwmhints(xallocwmhints); + end; + with hints^ do begin + icon_pixmap:= icon; + icon_mask:= mask; + if icon <> 0 then begin + flags:= flags or (1 shl 2); //iconpixmaphint + end + else begin + flags:= flags and not(1 shl 2); + end; + if mask <> 0 then begin + flags:= flags or (1 shl 5); //iconmaskhint + end + else begin + flags:= flags and not(1 shl 5); + end; + end; + xsetwmhints(appdisp,id,hints); + xfree(hints); + if netatoms[net_wm_icon] <> 0 then begin + ima.pixels:= nil; + maskima.pixels:= nil; + if icon <> 0 then begin + if gui_pixmaptoimage(icon,ima,0) <> gde_ok then begin + ima.pixels:= nil; + end; + end; + if mask <> 0 then begin + if gui_pixmaptoimage(mask,maskima,0) <> gde_ok then begin + maskima.pixels:= nil; + end; + end; + if ima.pixels <> nil then begin + npixels:= ima.size.cx*ima.size.cy; + int1:= 2 + npixels; + setlength(ar1,int1); + ar1[0]:= ima.size.cx; + ar1[1]:= ima.size.cy; + pd:= @ar1[2]; + ps:= pointer(ima.pixels); + case ima.kind of + bmk_rgb: begin + move(ps^,pd^,npixels*sizeof(longword)); + end; + bmk_gray: begin + for int1:= 0 to ima.size.cy-1 do begin + ps1:= ps; + pe:= ps+ima.size.cx; + repeat + pd^.red:= ps1^; + pd^.green:= ps1^; + pd^.blue:= ps1^; + inc(ps1); + inc(pd); + until ps1 >= pe; + ps:= ps+ima.linebytes; + end; + end; + bmk_mono: begin + for int1:= 0 to ima.size.cy-1 do begin + pde:= pd+ima.size.cx; + ps1:= ps; + bmask:= 1; + lwo1:= plongword(ps1)^; + repeat + if lwo1 and bmask = 0 then begin + longword(pd^):= $ffffffff; //ar1 is nulled + end; + bmask:= bmask shl 1; + if bmask = 0 then begin + bmask:= 1; + inc(plongword(ps1)); + lwo1:= plongword(ps1)^; + end; + inc(pd); + until pd >= pde; + pd:= pde; + ps:= ps+ima.linebytes; + end; + end; + else begin + ar1:= nil; //not supported + end; + end; + if maskima.pixels <> nil then begin + pd:= @ar1[2]; + ps:= pointer(maskima.pixels); + case maskima.kind of + bmk_rgb: begin + pde:= pd+npixels; + repeat + rgb1:= prgbtriplety(ps)^; + pd^.res:= (word(rgb1.red)+word(rgb1.green)+word(rgb1.blue)) div 3; + inc(pd); + inc(prgbtriplety(ps)); + until pd >= pde; + end; + bmk_gray: begin + for int1:= 0 to ima.size.cx-1 do begin + ps1:= ps; + pe:= ps+ima.size.cx; + repeat + pd^.res:= ps1^; + inc(pd); + inc(ps1); + until ps1 >= pe; + ps:= ps+maskima.linebytes; + end; + end; + bmk_mono: begin + for int1:= 0 to ima.size.cy-1 do begin + pde:= pd+ima.size.cx; + ps1:= ps; + bmask:= 1; + lwo1:= plongword(ps1)^; + repeat + if lwo1 and bmask <> 0 then begin + pd^.res:= $ff; + end + else begin + pd^.res:= $00; + end; + bmask:= bmask shl 1; + if bmask = 0 then begin + bmask:= 1; + inc(plongword(ps1)); + lwo1:= plongword(ps1)^; + end; + inc(pd); + until pd >= pde; + pd:= pde; + ps:= ps+maskima.linebytes; + end; + end; + else begin + ar1:= nil; //not supported + end; + end; + end + else begin + pd:= @ar1[2]; + pde:= pd+npixels; + repeat + pd^.res:= $ff; + inc(pd); + until pd >= pde; + end; + gui_freeimagemem(ima.pixels); + if ar1 <> nil then begin + {$ifdef cpu64} + setlength(ar2,length(ar1)); + for int1:= 0 to high(ar2) do begin + ar2[int1]:= ar1[int1]; + end; + setlongproperty(id,netatoms[net_wm_icon],ar2,cardinalatom); + {$else} + setlongproperty(id,netatoms[net_wm_icon],ar1,cardinalatom); + {$endif} + end; + end; + if maskima.pixels <> nil then begin + gui_freeimagemem(maskima.pixels); + end; + end; + result:= gue_ok; +end; + +function gui_setwindowopacity(id: winidty; const opacity: real): guierrorty; +var + f1: flo64; + at1: atom; +begin + result:= gue_notsupported; + at1:= netatoms[net_wm_window_opacity]; + if at1 <> 0 then begin + if opacity = emptyreal then begin + xdeleteproperty(appdisp,id,at1); + end + else begin + f1:= opacity; + if (f1 < 0) then begin + f1:= 0; + end + else begin + if (f1 > 1) then begin + f1:= 1; + end; + end; + setlongproperty(id,at1,round($ffffffff*f1)); + end; + result:= gue_ok; + end; +end; + +function gui_setapplicationicon(const icon,mask: pixmapty): guierrorty; +begin + result:= gue_ok; +end; + +function gui_pidtowinid(const pids: procidarty): winidty; + +var + level: integer; + + function scanchildren(const aparent: winidty): boolean; + + function checkpid(const apid: integer): boolean; + var + int1: integer; + begin + result:= false; + for int1:= 0 to high(pids) do begin + if pids[int1] = apid then begin + result:= true; + break; + end; + end; + end; + + var + parent,root: winidty; + ca1: longword; + children: pwinid; + int1: integer; +// id1: winidty; + ar1: atomarty; + begin + children:= nil; + result:= false; + if (gui_windowvisible(aparent) or (getwmstate(aparent) = wms_iconic)) and + readcardinalproperty(aparent,netatoms[net_wm_pid],1,int1) and checkpid(int1) then begin + result:= true; + gui_pidtowinid:= aparent; + end + else begin + if not netsupported or + not readatomproperty(aparent,netatoms[net_wm_state],ar1) then begin + //no wm toplevel window + if (xquerytree(appdisp,aparent,@root,@parent,@children,@ca1) <> 0) and + (children <> nil) then begin + inc(level); + for int1:= integer(ca1)-1 downto 0 do begin + if scanchildren(pwinidaty(children)^[int1]) then begin + result:= true; + break; + end; + end; + dec(level); + xfree(children); + end; + end; + end; + end; + +begin + gdi_lock; + result:= 0; + level:= 0; + if (netatoms[net_wm_pid] <> 0) then begin + scanchildren(rootid); + end; + gdi_unlock; +end; + +function XDestroyImage(Image: PXImage): Longint; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} +{$ifdef FPC} {$checkpointer off} {$endif} + Result := Image^.f.destroy_image(Image); +{$ifdef FPC} {$checkpointer default} {$endif} +end; + +function getwindowstack(const id: winidty): winidarty; +var + parent,root: winidty; + ca1: longword; + children: pwinid; + count: integer; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= nil; + count:= 0; + additem(result,id,count); + parent:= id; + repeat + if (xquerytree(appdisp,parent,@root,@parent,@children,@ca1) <> 0) then begin + if children <> nil then begin + xfree(children); + end; + end + else begin + break; + end; + additem(result,parent,count); + until (parent = root); + setlength(result,count); +end; + +function toplevelwindow(const id: winidty): winidty; +var + ar1: winidarty; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + if id = rootid then begin + result:= rootid; + end + else begin + ar1:= getwindowstack(id); + if high(ar1) > 0 then begin + result:= ar1[high(ar1)-1]; + end + else begin + result:= 0; + end; + end; +end; + +function gui_getzorder(const ids: winidarty; out zorders: integerarty): guierrorty; +var + ar1: winidararty; + int1,int2,int3: integer; + bo1: boolean; + parent,root: winidty; + ca1: longword; + children: pwinid; + +begin + gdi_lock; +{$ifdef FPC} {$checkpointer off} {$endif} + setlength(zorders,length(ids)); + if high(ids) > 0 then begin + setlength(ar1,length(ids)); + for int1:= 0 to high(ids) do begin + ar1[int1]:= getwindowstack(ids[int1]); + end; + if high(ar1[0]) > 0 then begin + int2:= 0; + bo1:= false; + repeat //find common ancestor + inc(int2); + int3:= ar1[0][high(ar1[0])-int2]; + for int1:= 1 to high(ar1) do begin + if (int2 > high(ar1[int1])) or (integer(ar1[int1][high(ar1[int1])-int2]) <> int3) then begin + bo1:= true; + break; + end; + end; + until bo1; + if (xquerytree(appdisp,ar1[0][high(ar1[0])-(int2-1)],@root,@parent,@children,@ca1) <> 0) then begin + for int1:= 0 to ca1 - 1 do begin + for int3:= 0 to high(ids) do begin + if integer(ar1[int3][high(ar1[int3])-int2]) = pwinidaty(children)^[int1] then begin + zorders[int3]:= int1; + break; + end; + end; + end; + if children <> nil then begin + xfree(children); + end; + end; + end; + end; +{$ifdef FPC} {$checkpointer default} {$endif} + result:= gue_ok; + gdi_unlock; +end; + +function gui_raisewindow(id: winidty; + const topmost: boolean = false): guierrorty; +begin + gdi_lock; +{$ifdef mse_debugzorder} + debugwindow('* gui_raisewindow ',id); +{$endif} + if toplevelraise then begin +// waitfordecoration(id); + xraisewindow(appdisp,toplevelwindow(id)); + end + else begin + xraisewindow(appdisp,id); + end; + result:= gue_ok; + gdi_unlock; +end; + +function gui_lowerwindow(id: winidty; + const topmost: boolean = false): guierrorty; +begin + gdi_lock; +{$ifdef mse_debugzorder} + debugwindow('* gui_lowerwindow ',id); +{$endif} + xlowerwindow(appdisp,id); + result:= gue_ok; + gdi_unlock; +end; + +function stackwindow(id: winidty; predecessor: winidty; + stackmode: integer): guierrorty; +var + bo1: boolean; +// id1: winidty; + changes: xwindowchanges; + ar1: winidarty; + int1: integer; + idindex,pindex: integer; +// topid,toppred: winidty; +// winar1: array[0..1] of winidty; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} +{$ifdef mse_debugzorder} + if stackmode = above then begin + debugwindow('*stackwindow above'+' ',id); + end + else begin + if stackmode = below then begin + debugwindow('*stackwindow below'+' ',id); + end + else begin + debugwindow('*stackwindow '+inttostr(stackmode)+' ',id); + end; + end; + debugwindow(' predecessor ',predecessor); +{$endif} + if predecessor = 0 then begin + result:= gui_raisewindow(id); + end + else begin + if id <> predecessor then begin + if gui_canstackunder then begin + bo1:= not norestackwindow and (netatoms[net_restack_window] <> 0); + if {not bo1 and} (stackmode = below) and stackmodebelowworkaround then begin + // xflush(appdisp); + // xsync(appdisp,false); + //many WM place stack_mode below windows + //below all other windows so we need this ugly workaround + //??? OK ??? + application.sortzorder; + ar1:= application.winidar; + pindex:= -1; + for int1:= high(ar1) downto 0 do begin + if ar1[int1] = predecessor then begin + pindex:= int1; + break; + end; + end; + if bo1 then begin + sendnetrootcardinalmessage(netatoms[net_restack_window],predecessor, + [2,id,above]); + {$ifdef mse_debugzorder} + debugwriteln(' net_restack_window workaround'); + {$endif} + end + else begin + {$ifdef mse_debugzorder} + debugwriteln(' reconfigurewmwindow workaround'); + {$endif} + changes.stack_mode:= above; + changes.sibling:= id; + xreconfigurewmwindow(appdisp,predecessor,msedefaultscreenno, + cwsibling or cwstackmode,@changes); + end; + if pindex > 0 then begin + for int1:= pindex+1 to high(ar1) do begin + if (ar1[int1] <> id) and (ar1[int1-1] <> id) then begin + if bo1 then begin + sendnetrootcardinalmessage(netatoms[net_restack_window],ar1[int1], + [2,ar1[int1-1],above]); + end + else begin + changes.sibling:= ar1[int1-1]; + xreconfigurewmwindow(appdisp,ar1[int1],msedefaultscreenno, + cwsibling or cwstackmode,@changes); + end; + end; + end; + end; + // xflush(appdisp); + end + else begin + if bo1 then begin + {$ifdef mse_debugzorder} + debugwriteln(' net_restack_window'); + {$endif} + sendnetrootcardinalmessage(netatoms[net_restack_window],id, + [2,predecessor,stackmode]); + end + else begin + changes.sibling:= predecessor; + changes.stack_mode:= stackmode; + {$ifdef mse_debugzorder} + debugwriteln(' reconfigurewmwindow'); + debugwindow( ' window: ',id); + debugwindow( ' sibling:',changes.sibling); + debugwriteln(' mode: '+inttostr(changes.stack_mode)); + {$endif} + xreconfigurewmwindow(appdisp,id,msedefaultscreenno, + cwsibling or cwstackmode,@changes); + end; + end; + { + changes.sibling:= predecessor; + changes.stack_mode:= stackmode; + xreconfigurewmwindow(appdisp,id,msedefaultscreenno, + cwsibling or cwstackmode,@changes); + } + { + topid:= toplevelwindow(id); + toppred:= toplevelwindow(predecessor); + if stackmode = above then begin + winar1[0]:= topid; + winar1[1]:= toppred; + end + else begin + winar1[0]:= toppred; + winar1[1]:= topid; + end; + xrestackwindows(appdisp,@winar1,2); + } + { + changes.sibling:= toplevelwindow(predecessor); + changes.stack_mode:= stackmode; + xconfigurewindow(appdisp,toplevelwindow(id),cwsibling or cwstackmode,@changes); + } + end + else begin + application.sortzorder; + ar1:= application.winidar; + idindex:= -1; + pindex:= -1; + for int1:= high(ar1) downto 0 do begin + if ar1[int1] = id then begin + idindex:= int1; + break; + end; + end; + for int1:= high(ar1) downto 0 do begin + if ar1[int1] = predecessor then begin + pindex:= int1; + break; + end; + end; + if (idindex >= 0) and (pindex >= 0) then begin + if not ( + (stackmode = above) and (pindex < high(ar1)) and (ar1[pindex+1] = id) or + (stackmode <> above) and (pindex > 0) and (ar1[pindex-1] = id) + ) then begin + deleteitem(ar1,idindex); + if idindex < pindex then begin + dec(pindex); + end; + if stackmode = above then begin + insertitem(ar1,pindex+1,id); + end + else begin + insertitem(ar1,pindex,id); + dec(pindex); + end; + if pindex < 0 then begin + pindex:= 0; + end; + for int1:= pindex to high(ar1) do begin + gui_raisewindow(ar1[int1]); + end; + end; + end; + { //code below does not work because wm takes no notice about the new stacking order + if xgetwindowattributes(appdisp,changes.sibling,@attributes1) <> 0 then begin + changes.sibling:= toplevelwindow(predecessor); + changes.stack_mode:= stackmode; + id1:= toplevelwindow(id); + if xgetwindowattributes(appdisp,id1,@attributes2) <> 0 then begin + attributes3.override_redirect:= 1; + if attributes1.override_redirect = 0 then begin + xchangewindowattributes(appdisp,changes.sibling,cwoverrideredirect,@attributes3); + end; + if attributes2.override_redirect = 0 then begin + xchangewindowattributes(appdisp,id1,cwoverrideredirect,@attributes3); + end; + xconfigurewindow(appdisp,id1,cwsibling or cwstackmode,@changes); + attributes3.override_redirect:= 0; + if attributes1.override_redirect = 0 then begin + xchangewindowattributes(appdisp,changes.sibling,cwoverrideredirect,@attributes3); + end; + if attributes2.override_redirect = 0 then begin + xchangewindowattributes(appdisp,id1,cwoverrideredirect,@attributes3); + end; + end; + application.sortzorder; + ar1:= application.winidar; + for int1:= 0 to high(ar1) do begin + if (ar1[int1] = id) or (ar1[int1] = predecessor) then begin + for int2:= int1 to high(ar1) do begin + xraisewindow(appdisp,ar1[int1]); + end; + break; + end; + end; + end; + } + end; + end; + result:= gue_ok; + end; +end; + +function gui_stackunderwindow(id: winidty; predecessor: winidty): guierrorty; +begin + gdi_lock; + result:= stackwindow(id,predecessor,below); + gdi_unlock; +end; + +function gui_stackoverwindow(id: winidty; predecessor: winidty): guierrorty; +begin + gdi_lock; + result:= stackwindow(id,predecessor,above); + gdi_unlock; +end; + +type + screeninfoty = record + rect: rectty; + ppmmwidth,ppmmheight: flo64; + end; + screeninfoarty = array of screeninfoty; + +var + screenrects: screeninfoarty; + screenrectsvalid: boolean; + +procedure updatescreenrects(); +var + info: pxrrscreenresources; + int1,int2: integer; + rectnum: integer; + po1: prroutput; + po2: pxrroutputinfo; + po3: pxrrcrtcinfo; + crtcs: array of pxrrcrtcinfo; +begin + if hasxrandr then begin + info:= xrrgetscreenresources(appdisp,rootid); + setlength(crtcs,info^.ncrtc); + for int1:= 0 to high(crtcs) do begin + crtcs[int1]:= xrrgetcrtcinfo(appdisp,info,info^.crtcs[int1]); + end; + setlength(screenrects,info^.noutput); + po1:= info^.outputs; + rectnum:= 0; + for int1:= 0 to high(screenrects) do begin + po2:= xrrgetoutputinfo(appdisp,info,po1^); + if (po2 <> nil) and (po2^.crtc <> 0) then begin + for int2:= 0 to high(crtcs) do begin + if po2^.crtc = info^.crtcs[int2] then begin + po3:= crtcs[int2]; + if po3 <> nil then begin + with screenrects[rectnum] do begin + with rect do begin + x:= po3^.x; + y:= po3^.y; + cx:= po3^.width; + cy:= po3^.height; + inc(rectnum); + end; + if po2^.mm_width > 0 then begin + ppmmwidth:= po3^.width / po2^.mm_width; + end + else begin + ppmmwidth:= 0; + end; + if po2^.mm_height > 0 then begin + ppmmheight:= po3^.height / po2^.mm_height; + end + else begin + ppmmheight:= 0; + end; + end; + end; + end; + end; + xrrfreeoutputinfo(po2); + end; + inc(po1); + end; + xrrfreescreenresources(info); + setlength(screenrects,rectnum); + for int1:= 0 to high(crtcs) do begin + if crtcs[int1] <> nil then begin + xrrfreecrtcinfo(crtcs[int1]); + end; + end; + end + else begin + screenrects:= nil; + end; + screenrectsvalid:= true; +end; + +procedure checkscreenrects(); +begin + if not screenrectsvalid then begin + updatescreenrects(); + end; +end; + +function getscreenrectindex(id: winidty): int32; +var + i1: int32; + rect1: rectty; + pt1: pointty; +label + endlab; +begin + result:= -1; + checkscreenrects(); + if screenrects <> nil then begin + if id = 0 then begin + id:= rootid; + end; + if gui_getdecoratedwindowrect(id,rect1) = gue_ok then begin + for i1:= 0 to high(screenrects) do begin + if rectinrect(rect1,screenrects[i1].rect) then begin + result:= i1; + goto endlab; + end; + end; + pt1.x:= rect1.x + rect1.cx div 2; + pt1.y:= rect1.y + rect1.cy div 2; + for i1:= 0 to high(screenrects) do begin + if pointinrect(pt1,screenrects[i1].rect) then begin + result:= i1; + goto endlab; + end; + end; + end; + for i1:= 0 to high(screenrects) do begin + if testintersectrect(rect1,screenrects[i1].rect) then begin + result:= i1; + goto endlab; + end; + end; + end; +endlab: +end; + +function gui_getscreenrect(const id: winidty): rectty; //0 -> virtual screen +var + i1: int32; +label + endlab; +begin + gdi_lock(); + if id <> 0 then begin + i1:= getscreenrectindex(id); + if i1 >= 0 then begin + result:= screenrects[i1].rect; + goto endlab; + end; + end; + result.pos:= nullpoint; +{$ifdef FPC} {$checkpointer off} {$endif} + result.cx:= defscreen^.width; + result.cy:= defscreen^ .height; +{$ifdef FPC} {$checkpointer default} {$endif} +endlab: + gdi_unlock(); +end; + + +function gui_getworkarea(id: winidty): rectty; +var + i1: int32; + bo1: boolean; +begin + gdi_lock; + bo1:= false; + if netsupported then begin + bo1:= readcardinalproperty(gui_getrootwindow(id), + netatoms[net_workarea],4,result); + end; + if not bo1 then begin + result:= gui_getscreenrect(id); + end; + i1:= getscreenrectindex(id); + if i1 >= 0 then begin + result:= intersectrect(result,screenrects[i1].rect); + end; + gdi_unlock; +end; + +procedure gui_getppmm(id: winidty; out appmmwidth,appmmheight: flo64); + //0.0 if not supported +var + i1: int32; +begin + gdi_lock(); + i1:= getscreenrectindex(id); + appmmwidth:= 0; + appmmheight:= 0; + if i1 >= 0 then begin + with screenrects[i1] do begin + appmmwidth:= ppmmwidth; + appmmheight:= ppmmheight; + end; + end; + if appmmwidth = 0 then begin + with defscreen^ do begin + if mwidth > 0 then begin + appmmwidth:= width / mwidth; + end; + end; + end; + if appmmheight = 0 then begin + with defscreen^ do begin + if mheight > 0 then begin + appmmheight:= height / mheight; + end; + end; + end; + gdi_unlock(); +end; + +function getwindowframe(id: winidty): framety; +var + bo1: boolean; + ar1: array[0..3] of integer; +// win1: winidty; +// root: winidty; + rect1,rect2: rectty; +// int1: integer; +// pt1: pointty; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + bo1:= false; + if canframeextents then begin + bo1:= readcardinalproperty(id,netatoms[net_frame_extents],4,ar1); + end; + if bo1 then begin + with result do begin + left:= ar1[0]; + top:= ar1[2]; + right:= ar1[1]; + bottom:= ar1[3]; + end; + end + else begin + result:= nullframe; + if (gui_getwindowrect(id,rect1) = gue_ok) and + (gui_getwindowrect(toplevelwindow(id),rect2) = gue_ok) then begin + result.left:= rect1.x - rect2.x; + result.top:= rect1.y - rect2.y; + result.right:= rect2.x + rect2.cx - rect1.x - rect1.cx; + result.bottom:= rect2.y + rect2.cy - rect1.y - rect1.cy; + end; + end; +end; + +function gui_setmainthread: guierrorty; //set mainthread to currentthread +begin + //not used in linux-x11 + result:= gue_ok; +end; + +function gui_getpointerpos: pointty; +var + ca1: longword; +begin + gdi_lock; + xquerypointer(appdisp,rootid,@ca1,@ca1,@result.x,@result.y,@ca1,@ca1,@ca1); + gdi_unlock; +end; + +function gui_setpointerpos(const pos: pointty): guierrorty; +begin + gdi_lock; + xwarppointer(appdisp,none,rootid,0,0,0,0,pos.x,pos.y); + result:= gue_ok; + gdi_unlock; +end; + +function gui_movepointer(const dist: pointty): guierrorty; +begin + gdi_lock; + xwarppointer(appdisp,rootid,none,0,0,0,0,dist.x,dist.y); + result:= gue_ok; + gdi_unlock; +end; + +var + pointergrabbed: boolean; + grabwinid: winidty; + +function gui_grabpointer(id: winidty): guierrorty; +begin + gdi_lock; + xflush(appdisp); //possibly show window + if xgrabpointer(appdisp,id,{$ifdef xboolean}false{$else}0{$endif}, + mouseeventmask,grabmodeasync,grabmodeasync, + none,none,currenttime) = grabsuccess then begin + result:= gue_ok; + pointergrabbed:= true; + grabwinid:= id; + xflush(appdisp); + end + else begin + result:= gue_capturemouse; + end; + gdi_unlock; +end; + +function gui_ungrabpointer: guierrorty; +begin + gdi_lock; + xungrabpointer(appdisp,currenttime); + result:= gue_ok; + pointergrabbed:= false; + xflush(appdisp); + gdi_unlock; +end; + +function gui_allocimagemem(length: integer): plongwordaty; +begin + if length = 0 then begin + result:= nil; + end + else begin + getmem(result,length * sizeof(longword)); + end; +end; + +procedure gui_freeimagemem(data: plongwordaty); +begin + freemem(data); +end; + +function gui_pixmaptoimage(pixmap: pixmapty; out image: imagety; + gchandle: longword): gdierrorty; +var + info: pixmapinfoty; + ximage1: pximage; + po1: plongword; + po2: pbyte; + int1,int2: integer; + wordmax: integer; +begin + gdi_lock; + info.handle:= pixmap; + result:= gui_getpixmapinfo(info); + if result = gde_ok then begin + image.size:= info.size; + image.pixels:= nil; + case info.depth of + 1: begin //monochrome + // image.kind:= bmk_mono; + ximage1:= xgetimage(appdisp,pixmap,0,0,info.size.cx,info.size.cy,1,xypixmap); + if ximage1 = nil then begin + result:= gde_image; + gdi_unlock; + exit; + end; + {$ifdef FPC} {$checkpointer off} {$endif} + with ximage1^ do begin + // wordmax:= (image.size.cx + 31) div 32; + // image.length:= wordmax * image.size.cy; + // image.pixels:= gui_allocimagemem(image.length); + allocimage(image,info.size,bmk_mono); + wordmax:= image.linelength; + po1:= @image.pixels^[0]; + po2:= pbyte(data); + if bitmap_pad = 32 then begin + move(po2^,po1^,image.size.cy * bytes_per_line); + end + else begin + for int1:= 0 to image.size.cy - 1 do begin + move(po2^,po1^,bytes_per_line); + inc(po2,bytes_per_line); + inc(po1,wordmax); + end; + end; + if byte_order <> lsbfirst then begin + case bitmap_unit of + 32: begin + for int1:= 0 to image.length - 1 do begin + swapbytes1(image.pixels^[int1]); + end; + end; + 16: begin + for int1:= 0 to image.length*2-1 do begin + swapbytes1(pwordaty(image.pixels)^[int1]); + end; + end; + end; + end; + if bitmap_bit_order <> lsbfirst then begin + po2:= @image.pixels^[0]; + for int1:= 0 to image.length*4-1 do begin + po2^:= bitreverse[po2^]; + inc(po2); + end; + end; + end; + {$ifdef FPC} {$checkpointer default} {$endif} + end; + 8: begin //gray //what about indexed pixmap???? + ximage1:= xgetimage(appdisp,pixmap,0,0,info.size.cx,info.size.cy,$ff,zpixmap); + if ximage1 = nil then begin + result:= gde_image; + gdi_unlock; + exit; + end; + allocimage(image,info.size,bmk_gray); + with ximage1^ do begin + po1:= @image.pixels^[0]; + po2:= pbyte(data); + if bitmap_pad = 32 then begin + move(po2^,po1^,image.size.cy * bytes_per_line); + end + else begin + wordmax:= image.linelength; + for int1:= 0 to image.size.cy - 1 do begin + move(po2^,po1^,bytes_per_line); + inc(po2,bytes_per_line); + inc(po1,wordmax); + end; + end; + end; + end; + else begin + // image.monochrome:= false; + // image.length:= image.size.cx * image.size.cy; + ximage1:= xgetimage(appdisp,pixmap,0,0,info.size.cx,info.size.cy, + $ffffffff,zpixmap); + if ximage1 = nil then begin + result:= gde_image; + gdi_unlock; + exit; + end; + allocimage(image,info.size,bmk_rgb); + // image.pixels:= gui_allocimagemem(image.length); + + //todo: optimize + + po1:= @image.pixels[0]; + for int1:= 0 to info.size.cy - 1 do begin + for int2:= 0 to info.size.cx - 1 do begin + po1^:= gui_pixeltorgb(ximage1^.f.get_pixel(ximage1,int2,int1)); + inc(po1); + end; + end; + end; + end; + xdestroyimage(ximage1); + end; + gdi_unlock; +end; + +function gui_getpixel(const id: winidty; const pos: pointty; + out pixel: pixelty): guierrorty; +var + ximage1: pximage; +begin + gdi_lock(); + result:= gue_error; + ximage1:= xgetimage(appdisp,id,pos.x,pos.y,1,1,$ffffffff,zpixmap); + if ximage1 <> nil then begin + pixel:= ximage1^.f.get_pixel(ximage1,0,0); + xdestroyimage(ximage1); + result:= gue_ok; + end; + gdi_unlock(); +end; + +function gui_imagetopixmap(const image: imagety; out pixmap: pixmapty; + gchandle: longword): gdierrorty; +var + ximage: pximage; + po1: prgbtriplety; + po2: pchar; + gc: tgc; + int1,int2: integer; +begin + gdi_lock; + result:= gde_ok; + po2:= nil; + case image.kind of + bmk_mono: begin + ximage:= XCreateImage(appdisp,nil,1,xypixmap,0,nil, + image.size.cx,image.size.cy,32,0); + if ximage = nil then begin + result:= gde_image; + gdi_unlock; + exit; + end; + with ximage^ do begin + bitmap_bit_order:= LSBFirst; + byte_order:= lsbfirst; + bitmap_unit:= 32; + data:= @image.pixels[0]; + end; + end; + bmk_gray: begin + ximage:= XCreateImage(appdisp,nil,8,zpixmap,0,nil, + image.size.cx,image.size.cy,32,0); + if ximage = nil then begin + result:= gde_image; + gdi_unlock; + exit; + end; + with ximage^ do begin + bitmap_bit_order:= LSBFirst; + byte_order:= lsbfirst; + bitmap_unit:= 32; + data:= @image.pixels[0]; + end; + end; + else begin + ximage:= XCreateImage(appdisp,defvisual,defdepth,zpixmap,0,nil, + image.size.cx,image.size.cy,32,0); + if ximage = nil then begin + result:= gde_image; + gdi_unlock; + exit; + end; + with ximage^ do begin + { + bitmap_bit_order:= LSBFirst; + byte_order:= lsbfirst; + bitmap_unit:= 32; + red_mask:= redmask; + green_mask:= greenmask; + blue_mask:= bluemask; + data:= @image.pixels[0]; + } + getmem(po2,image.size.cy * bytes_per_line); + data:= po2; + po1:= @image.pixels^[0]; + for int1:= 0 to image.size.cy - 1 do begin + for int2:= 0 to image.size.cx - 1 do begin + f.put_pixel(ximage,int2,int1,gui_rgbtopixel(longword(po1^))); + inc(po1); + end; + end; + end; + end; + end; + pixmap:= gui_createpixmap(image.size,0,image.kind); + gc:= xcreategc(appdisp,pixmap,0,nil); + xsetgraphicsexposures(appdisp,gc,{$ifdef xboolean}false{$else}0{$endif}); + xputimage(appdisp,pixmap,gc,ximage,0,0,0,0,image.size.cx,image.size.cy); + xfreegc(appdisp,gc); + ximage^.data:= nil; + xdestroyimage(ximage); + if po2 <> nil then begin + freemem(po2); + end; + gdi_unlock; +end; + +function gui_createpixmap(const size: sizety; winid: winidty = 0; + kind: bitmapkindty = bmk_rgb; copyfrom: pixmapty = 0): pixmapty; +var + gc: tgc; +begin + gdi_lock; + inc(pixmapcount); + if winid = 0 then begin + winid:= rootid; + end; + case kind of + bmk_mono: begin + result:= xcreatepixmap(appdisp,winid,size.cx,size.cy,1); + end; + bmk_gray: begin + result:= xcreatepixmap(appdisp,winid,size.cx,size.cy,8); + end; + else begin + result:= xcreatepixmap(appdisp,winid,size.cx,size.cy,defdepth); + end; + end; + if copyfrom <> 0 then begin + gc:= xcreategc(appdisp,result,0,nil); + xcopyarea(appdisp,copyfrom,result,gc,0,0,size.cx,size.cy,0,0); + xfreegc(appdisp,gc); + end; + gdi_unlock; +end; + +function gui_freepixmap(pixmap: pixmapty): gdierrorty; +begin + gdi_lock; + dec(pixmapcount); + if xfreepixmap(appdisp,pixmap) <> success then begin + result:= gde_pixmap; + end + else begin + result:= gde_ok; + end; + gdi_unlock; +end; + +function gui_createbitmapfromdata(const size: sizety; datapo: pbyte; + msbitfirst: boolean = false; dwordaligned: boolean = false; + bottomup: boolean = false): pixmapty; +var + image: ximage; + gc: tgc; + po1,po2: pbyte; + int1: integer; + +begin + gdi_lock; +// result:= xcreatebitmapfromdata(appdisp,rootid,datapo,size.cx,size.cy); + inc(pixmapcount); + result:= XCreatePixmap(appdisp,rootid,size.cx,size.cy,1); + if result <> 0 then begin + gc:= XCreateGC(appdisp,result,0,nil); + if gc = nil then begin + xfreepixmap(appdisp,result); + result:= 0; + end + else begin + with image do begin + width:= size.cx; + height:= size.cy; + depth:= 1; + bits_per_pixel:= 1; + xoffset:= 0; + format:= XYPixmap; + byte_order:= LSBFirst; + bitmap_unit:= 8; + if msbitfirst then begin + bitmap_bit_order:= mSBFirst; + end + else begin + bitmap_bit_order:= lSBFirst; + end; + if dwordaligned then begin + bitmap_pad:= 32; + bytes_per_line:= ((size.cx+31) div 32)*4; + end + else begin + bitmap_pad:= 8; + bytes_per_line:= (size.cx+7) div 8; + end; + if bottomup then begin + getmem(po1,bytes_per_line*size.cy); + data:= pchar(po1); + po2:= pbyte(pchar(datapo)+bytes_per_line*(size.cy-1)); + for int1:= 0 to size.cy - 1 do begin + move(po2^,po1^,bytes_per_line); + inc(po1,bytes_per_line); + dec(po2,bytes_per_line); + end; + XPutImage(appdisp,result,gc,@image,0,0,0,0,size.cx,size.cy); + freemem(data); + end + else begin + data:= pchar(datapo); + XPutImage(appdisp,result,gc,@image,0,0,0,0,size.cx,size.cy); + end; + end; + XFreeGC(appdisp, gc); + end; + end; + gdi_unlock; +end; + +function gui_getpixmapinfo(var info: pixmapinfoty): gdierrorty; +var + ca1: longword; +begin + gdi_lock; + with info do begin + if xgetgeometry(appdisp,handle,@ca1,@ca1,@ca1,@size.cx,@size.cy,@ca1, + @depth) = 0 then begin + result:= gde_pixmap; + end + else begin + result:= gde_ok; + end; + end; + gdi_unlock; +end; + +function gui_windowvisible(id: winidty): boolean; +var + attributes: xwindowattributes; +begin + gdi_lock; + xgetwindowattributes(appdisp,id,@attributes); + result:= (attributes.map_state = isviewable) and + (getwmstate(id) = wms_normal); + //gnome does not unmap iconic windows + gdi_unlock; +end; + +function hasoverrideredirect(const id: winidty): boolean; +var + attributes: xwindowattributes; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + xgetwindowattributes(appdisp,id,@attributes); + result:= (attributes.override_redirect {$ifndef xboolean}<> 0{$endif}); +end; + +function gui_showwindow(id: winidty): guierrorty; +var + min,max: sizety; + rect1: rectty; + transientfor: winidty; + bo1: boolean; +begin + gdi_lock; + xmapwindow(appdisp,id); +{$ifdef mse_debugshow} + debugwindow('*gui_showwindow ',id); +{$endif} + result:= gue_ok; + rect1:= nullrect; + application.checkwindowrect(id,rect1); + min:= rect1.size; + rect1.cx:= bigint; + rect1.cy:= bigint; + application.checkwindowrect(id,rect1); + max:= rect1.size; + if max.cx = bigint then begin + max.cx:= 0; + end; + if max.cy = bigint then begin + max.cy:= 0; + end; + if (max.cx <> 0) or (max.cy <> 0) or (min.cx <> 0) or (min.cy <> 0) then begin + waitfordecoration(id); + gui_setsizeconstraints(id,min,max); + end; + transientfor:= 0; + bo1:= xgettransientforhint(appdisp,id,@transientfor) <> 0; + if hasoverrideredirect(id) or bo1 then begin + waitfordecoration(id); + if (transientfor = 0) or (transientfor = rootid) then begin + gui_raisewindow(id); + end + else begin + waitfordecoration(transientfor); + gui_raisewindow(transientfor); + gui_raisewindow(id); +// gui_stackunderwindow(transientfor,id); + end; + end; + gdi_unlock; +end; +{ +procedure printwindowname(aid: winidty; const atext: string); +var + window1: twindow1; +begin + if application.findwindow(aid,window1) then begin + writeln(window1.fowner.name,' ',atext); + end; +end; +} +function getic(const awindow: winidty): xic; +var + window1: twindow1; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= appic; + {$ifdef FPC} + if application.findwindow(awindow,twindow(window1)) then begin + {$else} + if application.findwindow(awindow,twindow(window1)) then begin + {$endif} + with x11windowty(window1.fwindow.platformdata).d do begin + if ic <> nil then begin + result:= ic; + end; + end; + end; +end; + +function gui_setwindowfocus(id: winidty): guierrorty; +begin + gdi_lock; +{$ifdef mse_debugwindowfocus} + debugwindow('*gui_setwindowfocus ',id); +{$endif} + +// xseticfocus(getic(id)); + waitfordecoration(id); + if netatoms[net_active_window] <> 0 then begin + sendnetrootcardinalmessage(netatoms[net_active_window],id, + [1,lasteventtime,lastfocuswindow]); + end; +// setnetatomarrayitem(id,net_wm_state,net_wm_state_demands_attention); + xsetinputfocus(appdisp,id,reverttoparent,currenttime); + xsync(appdisp,0); +// xflush(appdisp); + result:= gue_ok; + gdi_unlock; +end; + +function gui_setimefocus(var awindow: windowty): guierrorty; +begin + gdi_lock; + result:= gue_ok; + with awindow,x11windowty(platformdata).d do begin + if ic <> nil then begin + xseticvalues(ic,pchar(xnfocuswindow),id,nil); + xseticfocus(ic); + end + else begin + xseticvalues(appic,pchar(xnfocuswindow),id,nil); + imewinid:= id; + xseticfocus(appic); + end; + end; + gdi_unlock; +end; + +procedure unsetime(const awindow: winidty); +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + if awindow = imewinid then begin + xunseticfocus(appic); + xseticvalues(appic,pchar(xnfocuswindow),appid,nil); + imewinid:= 0; + end; +end; + +function gui_unsetimefocus(var awindow: windowty): guierrorty; +begin + gdi_lock; + result:= gue_ok; + with x11windowty(awindow.platformdata).d do begin + if ic <> nil then begin + xunseticfocus(ic); + end + else begin + unsetime(awindow.id); + end; + end; + gdi_unlock; +end; + +function gui_setappfocus(id: winidty): guierrorty; +begin + result:= gui_setwindowfocus(id); +end; + +function gui_minimizeapplication: guierrorty; +begin + result:= gue_ok; //dummy +end; + +function gui_setcursorshape(winid: winidty; shape: cursorshapety): guierrorty; +var + cursor1: cursor; + bmp: pixmapty; + color: xcolor; +begin + result:= gue_ok; + if winid = 0 then begin + exit; //do not modify root window cursor + end; + gdi_lock; + if shape = cr_none then begin + fillchar(color,sizeof(color),0); + bmp:= xcreatebitmapfromdata(appdisp,winid,@color,1,1); //dummy data + cursor1:= xcreatepixmapcursor(appdisp,bmp,bmp,@color,@color,0,0); + xfreepixmap(appdisp,bmp); + end + else begin + cursor1:= xcreatefontcursor(appdisp,standardcursors[shape]); + end; + if cursor1 <> 0 then begin + xdefinecursor(appdisp,winid,cursor1); + xflush(appdisp); + xfreecursor(appdisp,cursor1); + end + else begin + result:= gue_cursor; + end; + gdi_unlock; +end; + +var + mainthreadid: threadty; + connectpipe: tpipedescriptors; + dummybyte: byte; + +procedure sigtimer(SigNum: Integer); cdecl; +begin + timerevent:= true; + if sys_getcurrentthread() <> mainthreadid then begin + //FreeBSD needs this + sys_write(connectpipe.writedes,@dummybyte,1); + end; +end; + +procedure sigterminate(SigNum: Integer); cdecl; +begin + terminated:= true; +end; + +procedure sigchild(SigNum: Integer); cdecl; +begin + childevent:= true; + mseprocmonitor.sigchildcallback(); +end; + +function getclientpointer(const event: xclientmessageevent): pointer; +begin + with event do begin + {$ifdef CPU64} + result:= pointer((data.l[0] and $ffffffff) + ((data.l[1] and $ffffffff) shl 32)); + {$else} + result:= pointer(data.l[0]); + {$endif} + end; +end; + +procedure setclientpointer(const ptr: pointer; out event: xclientmessageevent); +begin + fillchar(event,sizeof(event),0); + with event do begin + xtype:= clientmessage; + format:= 32; + message_type:= mseclientmessageatom; + {$ifdef CPU64} + data.l[0]:= ptruint(ptr) and $ffffffff; + data.l[1]:= (ptruint(ptr) shr 32) and $ffffffff; + {$else} + data.l[0]:= ptruint(ptr); + {$endif} + end; +end; + +function gui_postevent(event: tmseevent): guierrorty; +var + xevent1: xclientmessageevent; +begin + gdi_lock; + setclientpointer(event,xevent1); + if xsendevent(appdisp,appid,{$ifdef xboolean}false{$else}0{$endif},0, + @xevent1) = 0 then begin + result:= gue_postevent; + end + else begin + xflush(appdisp); + result:= gue_ok; + end; + gdi_unlock; +end; + +function settimer1(us: longword): guierrorty; + //send et_timer event after delay of us (micro seconds) +var + timerval: itimerval; +begin + fillchar(timerval,sizeof(timerval),0); + timerval.it_value.tv_sec:= us div 1000000; + timerval.it_value.tv_usec:= us mod 1000000; + if mselibc.setitimer(itimer_real,@timerval,nil) = 0 then begin + result:= gue_ok; + end + else begin + result:= gue_timer; + end; +end; + +function gui_settimer(us: longword): guierrorty; +begin + if us = 0 then begin + us:= 1; + end; + result:= settimer1(us); +end; + +function gui_rgbtopixel(rgb: longword): pixelty; +var + lwo1: longword; +begin //todo: speedup + if xredshiftleft then begin + lwo1:= ((rgb and redmask) shl xredshift) and xredmask; + end + else begin + lwo1:= ((rgb and redmask) shr xredshift) and xredmask; + end; + if xgreenshiftleft then begin + lwo1:= lwo1 or (((rgb and greenmask) shl xgreenshift) and xgreenmask); + end + else begin + lwo1:= lwo1 or (((rgb and greenmask) shr xgreenshift) and xgreenmask); + end; + if xblueshiftleft then begin + result:= lwo1 or (((rgb and bluemask) shl xblueshift) and xbluemask); + end + else begin + result:= lwo1 or (((rgb and bluemask) shr xblueshift) and xbluemask); + end; +end; + +function gui_graytopixel(gray: byte): pixelty; +var + lwo1: longword; +begin + lwo1:= gray; //todo: speedup + result:= (lwo1 shl xredshiftbase) and xredmask or + (lwo1 shl xgreenshiftbase) and xgreenmask or + (lwo1 shl xblueshiftbase) and xbluemask; +end; + +{ +function gui_rgbtocolormappixel(rgb: longword): pixelty; +begin + with rgbtriplety(rgb) do begin + if is8bitcolor and (red = green) and (red = blue) and (red <> 255) then begin + red:= red and xbluemask; + green:= green and xbluemask; //more neutral gray + end; + end; + result:= gui_rgbtopixel(rgb); +end; +} +function gui_pixeltorgb(pixel: longword): longword; +begin +// if istruecolor then begin + if xredshiftleft then begin + result:= (pixel and xredmask) shr xredshift; + end + else begin + result:= (pixel and xredmask) shl xredshift; + end; + if xgreenshiftleft then begin + result:= result or ((pixel and xgreenmask) shr xgreenshift); + end + else begin + result:= result or ((pixel and xgreenmask) shl xgreenshift); + end; + if xblueshiftleft then begin + result:= result or ((pixel and xbluemask) shr xblueshift); + end + else begin + result:= result or ((pixel and xbluemask) shl xblueshift); + end; +// end; +end; + +function gui_pixeltogray(pixel: pixelty): byte; +var + int1: integer; +begin + int1:= (pixel and xredmask) shr xredshiftbase; + int1:= int1 + ((pixel and xgreenmask) shr xgreenshiftbase); + int1:= int1 + ((pixel and xbluemask) shr xblueshiftbase); + result:= int1 div 3; +end; + + +function xtomousebutton(button: longword): mousebuttonty; +begin + case button of + button1: result:= mb_left; + button2: result:= mb_middle; + button3: result:= mb_right; + else result:= mb_none; + end; +end; + +function xtoshiftstate(const shiftstate: longword; + const key: keyty; const button: mousebuttonty; + const up: boolean): shiftstatesty; +begin + result:= []; + if shiftstate and button1mask <> 0 then include(result,ss_left); + if shiftstate and button2mask <> 0 then include(result,ss_middle); + if shiftstate and button3mask <> 0 then include(result,ss_right); + if shiftstate and shiftmask <> 0 then include(result,ss_shift); + if shiftstate and controlmask <> 0 then include(result,ss_ctrl); + if shiftstate and mod1mask <> 0 then include(result,ss_alt); + case key of + key_shift: if up then exclude(result,ss_shift) else include(result,ss_shift); + key_control: if up then exclude(result,ss_ctrl) else include(result,ss_ctrl); + key_alt: if up then exclude(result,ss_alt) else include(result,ss_alt); + end; + case button of + mb_left: if up then exclude(result,ss_left) else include(result,ss_left); + mb_middle: if up then exclude(result,ss_middle) else include(result,ss_middle); + mb_right: if up then exclude(result,ss_right) else include(result,ss_right); + end; +end; + +//var +// messcount: integer; + +procedure freeclientevents; +var + xev: xevent; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + while xpending(appdisp) > 0 do begin + xnextevent(appdisp,@xev); + with xev.xclient do begin + if (xtype = clientmessage) and (display = appdisp) and + (message_type = mseclientmessageatom) then begin + tmseevent(getclientpointer(xev.xclient)).free1; + end; + end; + end; +end; + +function gui_hasevent: boolean; +begin + gdi_lock; + result:= ((xpending(appdisp) > 0) or timerevent) and not terminated; + gdi_unlock; +end; + +function xkeytokey(key: keysym; var shiftstate: shiftstatesty): keyty; +begin + if (key >= $61) and (key <= $7a) then begin //a..z + result:= keyty(key - $20); //A..Z + end + else begin + case key of + xk_backspace: result:= key_backspace; + xk_tab: result:= key_tab; + xk_iso_left_tab: result:= key_backtab; +// xk_linefeed: result:= key_linefeed; +// xk_clear: result:= key_clear; + xk_return: result:= key_return; + xk_pause: result:= key_pause; + xk_scroll_lock: result:= key_scrolllock; + xk_sys_req: result:= key_sysreq; + xk_escape: result:= key_escape; + xk_delete: result:= key_delete; + xk_home: result:= key_home; + xk_left: result:= key_left; + xk_up: result:= key_up; + xk_right: result:= key_right; + xk_down: result:= key_down; +// xk_prior: result:= key_prior; + xk_page_up: result:= key_pageup; +// xk_next: result:= key_next; + xk_page_down: result:= key_pagedown; + xk_end: result:= key_end; +// xk_begin: result:= key_begin; + +// xk_select: result:= key_select; + xk_print: result:= key_print; +// xk_execute: result:= key_execute; + xk_insert: result:= key_insert; +// xk_undo: result:= key_undo; +// xk_redo: result:= key_redo; + xk_menu: result:= key_menu; +// xk_find: result:= key_find; +// xk_cancel: result:= key_cancel; + xk_help: result:= key_help; + xk_break: result:= key_pause; //key_break; +// xk_mode_switch: result:= key_modeswitch; +// xk_script_switch: result:= key_scriptswitch; + xk_num_lock: result:= key_numlock; + + xk_kp_space: begin + result:= key_space; + include(shiftstate,ss_second); + end; + xk_kp_tab: begin + result:= key_tab; + include(shiftstate,ss_second); + end; + xk_kp_enter: begin + result:= key_return; + include(shiftstate,ss_second); + end; + xk_kp_f1: begin + result:= key_f1; + include(shiftstate,ss_second); + end; + xk_kp_f2: begin + result:= key_f2; + include(shiftstate,ss_second); + end; + xk_kp_f3: begin + result:= key_f3; + include(shiftstate,ss_second); + end; + xk_kp_f4: begin + result:= key_f4; + include(shiftstate,ss_second); + end; + xk_kp_home: begin + result:= key_home; + include(shiftstate,ss_second); + end; + xk_kp_left: begin + result:= key_left; + include(shiftstate,ss_second); + end; + xk_kp_up: begin + result:= key_up; + include(shiftstate,ss_second); + end; + xk_kp_right: begin + result:= key_right; + include(shiftstate,ss_second); + end; + xk_kp_down: begin + result:= key_down; + include(shiftstate,ss_second); + end; +// xk_kp_prior: result:= key_prior; + xk_kp_page_up: begin + result:= key_pageup; + include(shiftstate,ss_second); + end; +// xk_kp_next: result:= key_next; + xk_kp_page_down: begin + result:= key_pagedown; + include(shiftstate,ss_second); + end; + xk_kp_end: begin + result:= key_end; + include(shiftstate,ss_second); + end; +// xk_kp_begin: result:= key_begin; + xk_kp_insert: begin + result:= key_insert; + include(shiftstate,ss_second); + end; + xk_kp_delete: begin + result:= key_delete; + include(shiftstate,ss_second); + end; + xk_kp_equal: begin + result:= key_equal; + include(shiftstate,ss_second); + end; + xk_kp_multiply: begin + result:= key_asterisk; + include(shiftstate,ss_second); + end; + xk_kp_add: begin + result:= key_plus; + include(shiftstate,ss_second); + end; + xk_kp_separator: begin + result:= key_comma; + include(shiftstate,ss_second); + end; + xk_kp_subtract: begin + result:= key_minus; + include(shiftstate,ss_second); + end; + xk_kp_decimal: begin + result:= key_decimal; + include(shiftstate,ss_second); + end; + xk_kp_divide: begin + result:= key_slash; + include(shiftstate,ss_second); + end; + xk_kp_0..xk_kp_9: begin + result:= keyty(longword(key_0) + key - xk_kp_0); + include(shiftstate,ss_second); + end; + + xk_f1..xk_f35: result:= keyty(longword(key_f1) + key - xk_f1); + + xk_shift_l: result:= key_shift; + xk_shift_r: begin + result:= key_shift; + include(shiftstate,ss_second); + end; + xk_control_l: result:= key_control; + xk_control_r: begin + result:= key_control; + include(shiftstate,ss_second); + end; + xk_caps_lock: result:= key_capslock; +// xk_shift_lock: result:= key_shift_lock; + + xk_meta_l: result:= key_meta; + xk_meta_r: begin + result:= key_meta; + include(shiftstate,ss_second); + end; + xk_alt_l: result:= key_alt; + xk_alt_r: begin + result:= key_alt; + include(shiftstate,ss_second); + end; + xk_super_l: result:= key_super; + xk_super_r: begin + result:= key_super; + include(shiftstate,ss_second); + end; + xk_hyper_l: result:= key_hyper; + xk_hyper_r: begin + result:= key_hyper; + include(shiftstate,ss_second); + end; + + xk_iso_level3_shift: begin + result:= key_altgr; + end; + + else result:= keyty(key and not modmask); + end; + end; +end; + +function pchartomsestring(value: pchar; len: integer): msestring; +var + int1: integer; + buffer: longwordarty; +begin + setlength(buffer,len); + int1:= mbsnrtowcs(pointer(buffer),@value,len,len,nil); + if int1 > 0 then begin + setlength(result,int1); + for int1:= 0 to int1-1 do begin + result[int1+1]:= msechar(buffer[int1]); + end; + end + else begin + setlength(result,0); + end; +end; + +function ucs4stringtomsestring(const source: longwordarty): msestring; +var + int1: integer; +begin + setlength(result,length(source)); + for int1:= 0 to length(source)-1 do begin + result[int1+1]:= msechar(source[int1]); + end; +end; + +var + getrootpathlevel: integer; + +function getrootpath(const id: winidty; out rootpath: longwordarty): boolean; +var + root,parent: winidty;//{$ifdef FPC}dword{$else}xlib.twindow{$endif}; + children: pwinid; + count: integer; + ca1: longword; + id1: winidty; + +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= false; + id1:= id; + setlength(rootpath,5); + rootpath[0]:= id; + count:= 1; //reserve for root + inc(xlockerror); //parent window possibly destroyed by WM + repeat + if xquerytree(appdisp,id1,@root,@parent,@children,@ca1) = 0 then begin + dec(xlockerror); + if (count > 1) and (getrootpathlevel < 4) then begin + {$ifdef mse_debugrootpath} + debugwindow('*** rootpatherror ',id); + {$endif} + inc(getrootpathlevel); + result:= getrootpath(id,rootpath); + dec(getrootpathlevel); + end; + exit; + end; + if children <> nil then begin + xfree(children); + end; + if count >= length(rootpath) then begin + setlength(rootpath,count+5); + end; + rootpath[count]:= parent; + id1:= parent; + inc(count); + until parent = root; + dec(xlockerror); + setlength(rootpath,count); + result:= true; +end; + +function gui_getchildren(const id: winidty; out children: winidarty): guierrorty; +var + root,parent: winidty;//{$ifdef FPC}dword{$else}xlib.twindow{$endif}; + chi: pwinid; +// count: integer; + ca1: longword; + int1: integer; +begin + gdi_lock; + result:= gue_getchildren; + children:= nil; + if xquerytree(appdisp,id,@root,@parent,@chi,@ca1) = 0 then begin + gdi_unlock; + exit; + end; + if chi <> nil then begin + setlength(children,ca1); + for int1:= 0 to high(children) do begin + children[int1]:= pwinidaty(chi)^[int1]; + end; + xfree(chi); + end; + result:= gue_ok; + gdi_unlock; +end; + +function getrootoffset(const id: winidty; var aoffset: pointty): boolean; +var + int1: integer; + rootpath: longwordarty; + ax,ay: integer; + width,height,border: longword; + ca1: longword; + offset: pointty; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= getrootpath(id,rootpath); + if result then begin + result:= false; + offset:= nullpoint; + for int1:= 1 to high(rootpath) - 1 do begin + if xgetgeometry(appdisp,rootpath[int1],@ca1,@ax,@ay,@width, + @height,@border,@ca1) = 0 then begin + exit; + end; + with offset do begin + inc(x,ax); + inc(y,ay); + end; + end; + end; +{$warnings off} + aoffset:= offset; + result:= true; +end; +{$warnings on} +function settransientforhint(id,transientfor: winidty): guierrorty; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + if transientfor = 0 then begin + if wmtransientforatom <> 0 then begin + xdeleteproperty(appdisp,id,wmtransientforatom); + end + else begin + xsettransientforhint(appdisp,id,rootid); + end; + end + else begin + xsettransientforhint(appdisp,id,transientfor); + end; + result:= gue_ok; +end; + +function gui_settransientfor(var awindow: windowty; + const transientfor: winidty): guierrorty; +//var +// attributes: xwindowattributes; +begin + gdi_lock; + result:= settransientforhint(awindow.id,transientfor); +(* + if result = gue_ok then begin + if xgetwindowattributes(appdisp,awindow.id,@attributes) <> 0 then begin + if attributes.override_redirect{$ifndef xboolean} <> 0 {$endif}then begin + gui_stackunderwindow(transientfor,awindow.id); + end; + end; + end; +*) + gdi_unlock; +end; + +function gui_windowatpos(const pos: pointty): winidty; +var + int1: integer; + id: winidty; +begin + gdi_lock; + id:= rootid; + repeat + result:= id; + if longint(xtranslatecoordinates(appdisp,rootid,result, + pos.x,pos.y,@int1,@int1,@id)) = 0 then begin + result:= 0; + gdi_unlock; + exit; + end; + until id = none; + gdi_unlock; +end; + +function windowsatpos(const pos: pointty): winidarty; + //top down without root +var + int1: integer; + id,id1: winidty; + int2: integer; +begin + id:= rootid; + int2:= 0; + while true do begin + id1:= id; + if (longint(xtranslatecoordinates(appdisp,rootid,id1, + pos.x,pos.y,@int1,@int1,@id)) = 0) or (id = 0) then begin + break; + end; + additem(integerarty(result),id,int2); + end; + setlength(result,int2); +end; + +function gui_setwindowgroup(id,group: winidty): guierrorty; +var + wmhints: pxwmhints; +begin + gdi_lock; +{$ifdef FPC}{$checkpointer off}{$endif} + wmhints:= pxwmhints(xgetwmhints(appdisp,id)); + if wmhints = nil then begin + wmhints:= pxwmhints(xallocwmhints); + end; + with wmhints^ do begin + window_group:= group; + flags:= flags or windowgrouphint; + xsetwmhints(appdisp,id,wmhints); + end; + xfree(wmhints); +{$ifdef FPC}{$checkpointer default}{$endif} + setwinidproperty(id,wmclientleaderatom,group); + result:= gue_ok; + gdi_unlock; +end; + +const + windowtypes: array[windowtypeoptionty] of netatomty = + ( +// wo_popup, wo_message, +net_wm_window_type_dropdown_menu,net_wm_window_type_dialog, +//wo_desktop, wo_dock, wo_toolbar, +net_wm_window_type_desktop,net_wm_window_type_dock,net_wm_window_type_toolbar, +//wo_menu, wo_utility, wo_splash, +net_wm_window_type_menu,net_wm_window_type_utility,net_wm_window_type_splash, +//wo_dialog, wo_dropdownmenu, +net_wm_window_type_dialog,net_wm_window_type_dropdown_menu, +//wo_popupmenu, wo_tooltip, +net_wm_window_type_popup_menu,net_wm_window_type_tooltip, +//wo_notification, wo_combo, wo_dnd +net_wm_window_type_notification,net_wm_window_type_combo,net_wm_window_type_dnd + ); + +function gui_createwindow(const rect: rectty; + var options: internalwindowoptionsty; var awindow: windowty): guierrorty; +var + attributes: xsetwindowattributes; + valuemask: longword; + width,height: integer; + id1: winidty; + icmask: longword; + colormap1: tcolormap; + opt1: windowtypeoptionty; +begin + gdi_lock; + with awindow,x11windowty(platformdata).d do begin + valuemask:= 0; + if options.options * [wo_popup,wo_overrideredirect] <> [] then begin + attributes.override_redirect:= {$ifdef xboolean}true{$else}1{$endif}; + valuemask:= valuemask or cwoverrideredirect; + end; + if rect.cx <= 0 then begin + width:= 1; + end + else begin + width:= rect.cx; + end; + if rect.cy <= 0 then begin + height:= 1; + end + else begin + height:= rect.cy; + end; + if options.parent <> 0 then begin + id1:= options.parent; + end + else begin + id1:= rootid; + end; + with x11internalwindowoptionsty(options.platformdata).d do begin + if colormap <> 0 then begin + colormap1:= colormap; + end + else begin + colormap1:= msecolormap; + end; + if colormap1 <> 0 then begin + attributes.colormap:= colormap1; + valuemask:= valuemask or cwcolormap; + end; + if depth = 0 then begin + depth:= copyfromparent; + end; + if visual = nil then begin + visual:= pvisual(copyfromparent); + end; +// if nocreatestaticgravity then begin + attributes.win_gravity:= northwestgravity; +// end +// else begin +// attributes.win_gravity:= staticgravity; +// end; + attributes.bit_gravity:= northwestgravity; + valuemask:= valuemask or cwwingravity or cwbitgravity; + + id:= xcreatewindow(appdisp,id1,rect.x,rect.y,width,height,0, + depth,copyfromparent,visual, + valuemask,@attributes); + if colormap <> 0 then begin + xfreecolormap(appdisp,colormap); + colormap:= 0; + end; + end; + if id = 0 then begin + result:= gue_createwindow; + gdi_unlock; + exit; + end; + result:= gue_ok; + if options.parent <> 0 then begin //embedded window + xselectinput(appdisp,id,exposuremask); //will be mapped to parent + gdi_unlock; + exit; + end; + if (options.transientfor <> 0) or + (options.options * [wo_popup,wo_message] <> []) then begin + settransientforhint(id,options.transientfor); + end; + with options do begin + if icon <> 0 then begin + gui_setwindowicon(id,icon,iconmask); + end; + end; + if options.setgroup then begin + if options.groupleader = 0 then begin + gui_setwindowgroup(id,id); + end + else begin + gui_setwindowgroup(id,options.groupleader); + end; + end; + if options.pos <> wp_default then begin + gui_reposwindow(id,rect); + end; +{ //single ic for whole application + ic:= xcreateic(im,pchar(xninputstyle), + ximstatusnothing or ximpreeditnothing, + pchar(xnclientwindow),id,nil); +} + icmask:= appicmask; + if ic <> nil then begin + xgeticvalues(ic,pchar(xnfilterevents),@icmask,nil); + xseticvalues(ic,pchar(xnresetstate),pchar(ximpreservestate),nil); + end; + xselectinput(appdisp,id,icmask or + KeymapStateMask or + KeyPressMask or KeyReleaseMask or + buttonpressmask or buttonreleasemask or + pointermotionmask or + EnterWindowMask or LeaveWindowMask or + FocusChangeMask or PropertyChangeMask or + exposuremask or structurenotifymask + ); + xsetwmprotocols(appdisp,id,@wmprotocols[low(wmprotocolty)], + integer(high(wmprotocolty))+1); + setstringproperty(id,wmclassatom,ansistring( + filename(sys_getapplicationpath)+#0+application.applicationname)); + setnetcardinal(id,net_wm_pid,getpid); + if (wo_popup in options.options) and (options.transientfor <> 0) then begin + gui_raisewindow(options.transientfor); + //transientforhint not used by overrideredirect + end; + if options.options * windowtypeoptions <> [] then begin + for opt1:= low(windowtypeoptionty) to high(windowtypeoptionty) do begin + if opt1 in options.options then begin + setnetatomarrayitem(id,net_wm_window_type,windowtypes[opt1]); +// break; + end; + end; + end + else begin + setnetatomarrayitem(id,net_wm_window_type,net_wm_window_type_normal); + end; + if (options.options * noframewindowtypes <> []) and + (netatoms[motif_wm_hints] <> 0) then begin + setlongproperty(id,netatoms[motif_wm_hints],[mwm_hints_decorations,0,0,0,0], + netatoms[motif_wm_hints]); + end; + if (wo_popup in options.options) then begin + gui_raisewindow(id); + end + else begin + if wo_notaskbar in options.options then begin +// changenetwmstate(id,nso_add,net_wm_state_skip_taskbar,net_none); + setnetatomarrayitem(id,net_wm_state,net_wm_state_skip_taskbar); + end; + end; + if wo_sysdnd in options.options then begin + setatomproperty(id,xdndatoms[xdnd_aware],xdndprotocolversion); + end + else begin + xdeleteproperty(appdisp,id,xdndatoms[xdnd_aware]); + end; + end; + gdi_unlock; +end; + +function gui_destroywindow(var awindow: windowty): guierrorty; +begin + gdi_lock; + with awindow,x11windowty(platformdata).d do begin + if ic <> nil then begin + xdestroyic(ic); + ic:= nil; + end; + if id <> 0 then begin + {$ifdef with_saveyourself} + if id <> saveyourselfwindow then begin + {$endif} + unsetime(id); + xdestroywindow(appdisp,id); + {$ifdef with_saveyourself} + end; + {$endif} + end; + end; + result:= gue_ok; + gdi_unlock; +end; + +function getwindowrect(id: winidty; out rect: rectty; out origin: pointty): guierrorty; +var + int1: integer; +begin + result:= gue_error; + with rect do begin + if getrootoffset(id,origin) and + (xgetgeometry(appdisp,id,@int1,@x,@y,@cx,@cy,@int1,@int1) <> 0) then begin + result:= gue_ok; + end; + end; +end; + +function gui_getwindowrect(id: winidty; out rect: rectty): guierrorty; +var +// int1: integer; + po1: pointty; +begin + gdi_lock; + result:= getwindowrect(id,rect,po1); + if result = gue_ok then begin + addpoint1(rect.pos,po1); + end; + gdi_unlock; +end; + +function gui_getwindowpos(id: winidty; out pos: pointty): guierrorty; +var + int1: integer; +// po1: pointty; +begin + gdi_lock; + result:= gue_error; + with pos do begin + if xgetgeometry(appdisp,id,@int1,@x,@y,@int1,@int1,@int1,@int1) <> 0 then begin + result:= gue_ok; + end; + end; + gdi_unlock; +end; + +procedure wmwait; +begin + xsync(appdisp,false); + sys_schedyield; + xsync(appdisp,false); +end; + +function gui_reposwindow(id: winidty; const rect: rectty): guierrorty; +var + changes: xwindowchanges; + sizehints: pxsizehints; + int1: clong; +// rect1: rectty; + frame1: framety; + bo1: boolean; +begin + gdi_lock; + fillchar(changes,sizeof(changes),0); + bo1:= hasoverrideredirect(id); + with changes do begin + if not bo1 and nostaticgravity then begin + wmwait(); + frame1:= getwindowframe(id); + {$ifdef mse_debugconfigure} + debugwindow('*reposw.framekorr'+' '+inttostr(frame1.left)+' '+ + inttostr(frame1.top)+' ',id); + {$endif} + x:= rect.x-frame1.left; + y:= rect.y-frame1.top; + end + else begin + x:= rect.x; + y:= rect.y; + end; + width:= rect.cx; + height:= rect.cy; + if width <= 0 then begin + width:= 1; + end; + if height <= 0 then begin + height:= 1; + end; + end; + if not bo1 then begin + {$ifdef FPC} {$checkpointer off} {$endif} + sizehints:= xallocsizehints; + xgetwmnormalhints(appdisp,id,sizehints,@int1); + with sizehints^ do begin + flags:= flags or pposition or psize or usposition or ussize + {or pbasesize} or pwingravity; + x:= changes.x; + y:= changes.y; + width:= changes.width; + height:= changes.height; +// base_width:= width; //openbox does not allow size smaller than this? +// base_height:= height; + if nostaticgravity then begin + win_gravity:= northwestgravity; + end + else begin + win_gravity:= staticgravity; + end; + end; + xsetwmnormalhints(appdisp,id,sizehints); + xfree(sizehints); + end; + {$ifdef mse_debugconfigure} + with changes do begin + debugwindow('*reposwindow '+' '+inttostr(x)+' '+inttostr(y)+ + ' '+inttostr(width)+' '+inttostr(height)+' ',id); + end; + {$endif} + xconfigurewindow(appdisp,id,cwx or cwy or cwwidth or cwheight,@changes); +(* + if nostaticgravity and gui_windowvisible(id) then begin + wmwait; + if (gui_getwindowrect(id,rect1) = gue_ok) and + not rectisequal(rect1,rect) then begin + //simulate staticgravity + with changes do begin + x:= x + rect.x-rect1.x; + y:= y + rect.y-rect1.y; + width:= width + rect.cx-rect1.cx; + height:= height + rect.cy-rect1.cy; + end; + {$ifdef mse_debugconfigure} + with changes do begin + debugwindow('*reposwindow2 '+' '+inttostr(x)+' '+inttostr(y)+ + ' '+inttostr(width)+' '+inttostr(height)+' ',id); + end; + {$endif} + xconfigurewindow(appdisp,id,cwx or cwy or cwwidth or cwheight,@changes); + end; + end; +*) + {$ifdef FPC} {$checkpointer default} {$endif} + result:= gue_ok; +// xflush(appdisp); + gdi_unlock; +end; + +function gui_getdecoratedwindowrect(id: winidty; out arect: rectty): guierrorty; +//var +// frame1: framety; +begin + gdi_lock; + result:= gui_getwindowrect(id,arect); + if result = gue_ok then begin + inflaterect1(arect,getwindowframe(id)) + end; + gdi_unlock; +end; + +function gui_setdecoratedwindowrect(id: winidty; const rect: rectty; + out clientrect: rectty): guierrorty; +var + frame1: framety; +begin + gdi_lock; + frame1:= getwindowframe(id); + with clientrect,frame1 do begin + x:= rect.x + left; + cx:= rect.cx - left - right; + y:= rect.y + top; + cy:= rect.cy - top - bottom; + end; + result:= gui_reposwindow(id,clientrect); + gdi_unlock; +end; + +function gui_setembeddedwindowrect(id: winidty; const rect: rectty): guierrorty; +var + changes: xwindowchanges; +begin + gdi_lock; + fillchar(changes,sizeof(changes),0); + with changes do begin + x:= rect.x; + y:= rect.y; + width:= rect.cx; + height:= rect.cy; + if width <= 0 then begin + width:= 1; + end; + if height <= 0 then begin + height:= 1; + end; + end; + xconfigurewindow(appdisp,id,cwx or cwy or cwwidth or cwheight,@changes); + gdi_unlock(); + result:= gue_ok; +end; + +function gui_setsizeconstraints(id: winidty; const min,max: sizety): guierrorty; +var + sizehints: pxsizehints; + int1: clong; +begin + gdi_lock; + sizehints:= xallocsizehints; + {$ifdef FPC} {$checkpointer off} {$endif} + xgetwmnormalhints(appdisp,id,sizehints,@int1); + with sizehints^ do begin +// flags:= flags or pminsize or pmaxsize; + if (min.cx <> 0) or (min.cy <> 0) then begin + flags:= flags or pminsize; + end + else begin + flags:= flags and not pminsize; + end; + if (max.cx <> 0) or (max.cy <> 0) then begin + flags:= flags or pmaxsize; + end + else begin + flags:= flags and not pmaxsize; + end; + min_width:= min.cx; + min_height:= min.cy; + if max.cx = 0 then begin + max_width:= 30000; + end + else begin + max_width:= max.cx; + end; + if max.cy = 0 then begin + max_height:= 30000; + end + else begin + max_height:= max.cy; + end; + end; + {$ifdef FPC} {$checkpointer default} {$endif} + xsetwmnormalhints(appdisp,id,sizehints); + xfree(sizehints); + result:= gue_ok; + gdi_unlock; +end; + +procedure unmapwindow(id: winidty); +var + ev1: txunmapevent; + root1: winidty; +begin + root1:= gui_getrootwindow(id); + xunmapwindow(appdisp,id); + ev1._type:= unmapnotify; + ev1.event:= root1; + ev1.window:= id; + ev1.from_configure:= 0; + xsendevent(appdisp,root1,{$ifdef xboolean}false{$else}0{$endif}, + substructurenotifymask or substructureredirectmask,@ev1); + //synthetic +end; + +function gui_hidewindow(id: winidty): guierrorty; +begin + gdi_lock; + unsetime(id); + unmapwindow(id); + result:= gue_ok; + gdi_unlock; +end; + +function gui_getparentwindow(const awindow: winidty): winidty; +var + root,parent: winidty;//{$ifdef FPC}dword{$else}xlib.twindow{$endif}; + children: pwinid; +// count: integer; + ca1: longword; +begin + gdi_lock; + result:= 0; + if xquerytree(appdisp,awindow,@root,@parent,@children,@ca1) = 0 then begin + gdi_unlock; + exit; + end; + if children <> nil then begin + xfree(children); + end; + result:= parent; + gdi_unlock; +end; + +function gui_reparentwindow(const child: winidty; const parent: winidty; + const pos: pointty): guierrorty; +var + wi1: winidty; +begin + gdi_lock; + result:= gue_ok; + wi1:= parent; + if wi1 = 0 then begin + wi1:= rootid; + end; + xsync(appdisp,0); + xreparentwindow(appdisp,child,wi1,pos.x,pos.y); + xsync(appdisp,0); + gdi_unlock; +end; + + +function getsyswin(const akind: syswindowty): winidty; +var + at1: atom; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= 0; + case akind of + sywi_tray: begin + at1:= netatoms[net_system_tray_s0]; + if at1 <> 0 then begin + result:= xgetselectionowner(appdisp,at1); + end; + end; + end; +end; + +const + xembedversion = 0; + xembedflagsunmapped = 0; + xembedflagsmapped = 1; + +procedure initxembed(const id: winidty; const flags: int32); +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + setlongproperty(id,netatoms[xembed_info],[xembedversion,flags], + netatoms[xembed_info]{cardinalatom}); +end; + +procedure finalizexembed(const id: winidty); +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + xdeleteproperty(appdisp,id,netatoms[xembed_info]); +end; + +function gui_showsysdock(var awindow: windowty): guierrorty; +begin + gdi_lock; + initxembed(awindow.id,xembedflagsmapped); + result:= gui_showwindow(awindow.id); //xembedflagsmapped + //does not work for some WM's + result:= gue_ok; + gdi_unlock; +end; + +function gui_hidesysdock(var awindow: windowty): guierrorty; +begin + gdi_lock; + initxembed(awindow.id,xembedflagsunmapped); + result:= gui_hidewindow(awindow.id); //xembedflagsunmapped + //does not work for some WM's + result:= gue_ok; + gdi_unlock; +end; + + +const + system_tray_request_dock = 0; + system_tray_begin_message = 1; + system_tray_cancel_message = 2; + +function sendtraymessage(const dest: winidty; const awindow: winidty; + const opcode: integer; + const data1: longword = 0; const data2: longword = 0; + const data3: longword = 0): guierrorty; +var + at1: atom; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= gue_notraywindow; + if dest <> 0 then begin + at1:= netatoms[net_system_tray_opcode]; + if (at1 <> 0) and sendnetcardinalmessage(dest,at1,awindow, + [{currenttime}lasteventtime,opcode,data1,data2,data3]) then begin + result:= gue_ok; + end; + end; +end; + +function removesizehints(id: winidty): guierrorty; +var + sizehints: pxsizehints; +begin + sizehints:= xallocsizehints; + with sizehints^ do begin + flags:= 0; + end; + xsetwmnormalhints(appdisp,id,sizehints); + xfree(sizehints); + result:= gue_ok; +end; + +function gui_docktosyswindow(var child: windowty; + const akind: syswindowty): guierrorty; +var + syswin: winidty; + parentbefore,id1: winidty; + i1: integer; + pt1: pointty; + rect1: rectty; +const + maxwait = 200; //1s +begin + gdi_lock; + gui_hidewindow(child.id); //window must be unmapped for some WM's + xsync(appdisp,0); + if akind = sywi_none then begin + //does not work with newer WM's, + //window must be destroyed + result:= getwindowrect(child.id,rect1,pt1); + if result = gue_ok then begin + result:= gui_reparentwindow(child.id,0,rect1.pos); + end; + finalizexembed(child.id); + end + else begin + result:= gue_windownotfound; + syswin:= getsyswin(akind); + if syswin <> 0 then begin + removesizehints(child.id); + initxembed(child.id,xembedflagsunmapped); +// xdeleteproperty(appdisp,child.id,netatoms[wm_normal_hints]); +// xdeleteproperty(appdisp,child.id,wmclassatom); + parentbefore:= gui_getparentwindow(child.id); + result:= gue_ok; + i1:= 0; + case akind of + sywi_tray: begin + result:= sendtraymessage(syswin,syswin, + system_tray_request_dock,child.id); + end; + end; + repeat + { + case akind of + sywi_tray: begin + result:= sendtraymessage(syswin,syswin, + system_tray_request_dock,child.id); + //does not always work the first time... + end; + end; + } + xsync(appdisp,0); + sys_schedyield; + id1:= gui_getparentwindow(child.id); + if (id1 <> parentbefore) and (id1 <> rootid) then begin + break; + end; + sleep(5); + inc(i1); + until i1 = maxwait; + if i1 >= maxwait then begin + {$ifdef mse_debugxembed} + debugwindow('***error docktosyswindow child ',child.id); + debugwindow(' syswin ',syswin); + {$endif} + result:= gue_docktosyswindow; + end + else begin + {$ifdef mse_debugxembed} + debugwindow('* docktosyswindow attempt:'+inttostr(i1)+' child',child.id); + debugwindow(' syswin ',syswin); + {$endif} + end; + end + else begin + {$ifdef mse_debugxembed} + debugwindow('***error docktosyswindow child:',child.id); + debugwindow(' syswin:',syswin); + {$endif} + end; + end; + gdi_unlock; +end; + +function gui_traymessage(var awindow: windowty; const message: msestring; + out messageid: longword; + const timeoutms: longword = 0): guierrorty; +var + str1: ansistring; + int1: integer; + event1: xclientmessageevent; + po1: pchar; + win1: winidty; + at1: atom; +label + errorlab; +begin + gdi_lock; + result:= gue_notraywindow; + win1:= getsyswin(sywi_tray); + at1:= netatoms[net_system_tray_message_data]; + if (win1 <> 0) and (at1 <> 0) then begin + messageid:= getidnum; + str1:= stringtoutf8ansi(message); + int1:= length(str1); + str1:= str1 + #0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0; + result:= sendtraymessage(win1,awindow.id,system_tray_begin_message,timeoutms, + int1,messageid); + if result = gue_ok then begin + fillchar(event1,sizeof(event1),0); + with event1 do begin + xtype:= clientmessage; + display:= appdisp; + xwindow:= awindow.id; + format:= 8; + message_type:= at1; + po1:= pchar(str1); + while (result = gue_ok) and (int1 > 0) do begin + move(po1^,data.b[0],20); + inc(po1,20); + int1:= int1 - 20; + if xsendevent(appdisp,win1,false,0 + {structurenotifymask or substructurenotifymask},@event1) = 0 then begin + result:= gue_sendevent; + end; + end; + end; + xsync(appdisp,0); + end; + end; +errorlab: + gdi_unlock; +end; + +function gui_canceltraymessage(var awindow: windowty; + const messageid: longword): guierrorty; +begin + gdi_lock; + result:= sendtraymessage(getsyswin(sywi_tray),awindow.id, + system_tray_cancel_message,messageid,0,0); + gdi_unlock; +end; + +function gui_settrayicon(var awindow: windowty; + const icon,mask: pixmapty): guierrorty; +begin + result:= gui_setwindowicon(awindow.id,icon,mask); +end; + +function gui_settrayhint(var awindow: windowty; + const hint: msestring): guierrorty; +begin + result:= gue_ok; //dummy +end; + +{$ifndef FPC} +type + tlibhandle = longword; +{$endif} + + +function gui_regiontorects(const aregion: regionty): rectarty; +begin + result:= x11regiontorects(aregion); +end; + +function gui_movewindowrect(id: winidty; const dist: pointty; + const rect: rectty): guierrorty; +var + gc: tgc; +begin + gdi_lock; + gc:= xcreategc(appdisp,id,0,nil); + if gc <> nil then begin + xcopyarea(appdisp,id,id,gc,rect.x,rect.y,rect.cx,rect.cy,rect.x+dist.x, + rect.y+dist.y); + xfreegc(appdisp,gc); + result:= gue_ok; + end + else begin + result:= gue_scroll; + end; + gdi_unlock; +end; + +procedure gui_beep; +begin + gdi_lock; + xbell(appdisp,0); + xflush(appdisp); + gdi_unlock; +end; + +function gui_flushgdi(const synchronize: boolean = false): guierrorty; +begin + gdi_lock; + if synchronize then begin + xsync(appdisp,0); + end + else begin + xflush(appdisp); + end; + result:= gue_ok; + gdi_unlock; +end; + +function msedisplay: pdisplay; +begin + result:= appdisp; +end; + +function msevisual: pvisual; +begin + result:= pvisual(defvisual); +end; + +function msedefaultscreen: pscreen; +begin + result:= defscreen; +end; + +function msedefaultscreenno: integer; +begin + result:= xscreennumberofscreen(defscreen); +end; + +{$ifdef with_sm} +//callbacks +procedure icewatch(_iceConn: IceConn; clientData: IcePointer; + opening: Bool; var watchData: IcePointer); cdecl; +begin + with psminfoty(clientdata)^ do begin + if iceconnection = nil then begin + iceconnection:= _iceconn; + end; + if _iceconn = iceconnection then begin + if (opening <> 0) then begin + fd:= iceconnectionnumber(_iceconn); + end + else begin + fd:= -1; + end; + end; + end; +end; + +procedure SmcSaveYourself(_smcConn: SmcConn; clientData: pointer; + saveType: integer; ashutdown: bool; + ainteractStyle: integer; fast: bool); cdecl; +begin + with psminfoty(clientdata)^ do begin + if (ashutdown <> 0) then begin + shutdown:= true; + interactstyle:= ainteractstyle; + end + else begin + smcsaveyourselfdone(_smcconn,1); + end; + end; +end; + +procedure SmcDie(_smcConn: SmcConn; clientData: pointer); cdecl; +begin +end; + +procedure SmcSaveComplete(_smcConn: SmcConn; clientData: pointer); cdecl; +begin +end; + +procedure SmcShutdownCancelled(_smcConn: SmcConn; + clientData: pointer); cdecl; +begin + with psminfoty(clientdata)^ do begin + shutdown:= false; + shutdownpending:= false; + end; +end; + +procedure interact(_smcConn: SmcConn; clientData: SmPointer); cdecl; +begin + with psminfoty(clientdata)^ do begin + interactgranted:= true; + end; +end; + +{$endif} + +procedure gui_cancelshutdown; +begin +{$ifdef with_sm} + gdi_lock; + if hassm then begin + with sminfo do begin + {$ifdef smdebug} + writeln('gui_cancelshutdown ',shutdown,shutdownpending, + interactwaiting,interactgranted); + {$endif} + if shutdown and shutdownpending and interactgranted then begin + smcinteractdone(smconnection,1); + {$ifdef smdebug} + writeln('gui_cancelshutdown smcinteractdone'); + {$endif} + smcsaveyourselfdone(smconnection,1); + {$ifdef smdebug} + writeln('gui_cancelshutdown smcsaveyourselfdone'); + {$endif} + interactwaiting:= false; + interactgranted:= false; + end; + end; + end; + gdi_unlock; +{$endif} +end; + +var + escapepressed: boolean; + +function gui_escapepressed: boolean; +begin + result:= escapepressed; +end; + +procedure gui_resetescapepressed; +begin + escapepressed:= false; +end; + +function getkeynomod(var xev: {$ifdef FPC}txkeyevent{$else} + xkeyevent{$endif}): keyty; +const + modimask = not (shiftmask or lockmask or controlmask or + mod1mask or mod2mask or mod3mask or + mod4mask or mod5mask); +var +// keysym1: pkeysym; +// int1{,int2}: integer; + ss1: shiftstatesty; +// po1: pcuint; + statebefore: cuint; + keysym1: keysym; +begin +{$ifdef mse_debuggdisync} + checkgdilock; +{$endif} + result:= key_none; + statebefore:= xev.state; + xev.state:= xev.state and modimask or numlockstate; + xlookupstring(@xev,nil,0,@keysym1,nil); + xev.state:= statebefore; + ss1:= []; + result:= xkeytokey(keysym1,ss1); + + (* + {$ifdef fpc} {$checkpointer off} {$endif} + inc(xlockerror); + ss1:= []; + keysym1:= xgetkeyboardmapping(appdisp,xev.keycode,1,@int1); + if keysym1 <> nil then begin + result:= xkeytokey(keysym1^,ss1); + xfree(keysym1); + end; + dec(xlockerror); + {$ifdef fpc} {$checkpointer default} {$endif} +*) +end; + +var + timeoutcount: integer; //for safety timertick + repeatkey: integer; + repeatkeytime: ttime; + +procedure resetrepeatkey(); +begin +{$ifdef mse_debugkey} + debugwriteln('resetrepeatkey key:'+inttostr(repeatkey)+ + ' time:'+inttostr(repeatkeytime)); +{$endif} + repeatkey:= 0; + repeatkeytime:= 0; +end; + +type + tsysdndreader = class //todo: scrolling + private + fwinid: winidty; + fsource: winidty; + fprotocolversion: byte; + faction: atom; + fdataformats: msestringarty; + fformatistext: booleanarty; + fdatatypeatoms: atomarty; + fdata: stringarty; + ftext: msestringarty; + fpos: pointty; + fshiftstate: shiftstatesty; + fscroll: boolean; + fdroptimestamp: longword; + protected + function handleevent(var aevent: xclientmessageevent): tmseevent; + public + constructor create(const aevent: xclientmessageevent); + property winid: winidty read fwinid; + function readdata(var adata: string; + const typeindex: integer): guierrorty; + function readtext(var atext: msestring; + const typeindex: integer): guierrorty; + end; + + sysdndwriterstatety = (sdws_destroying); + sysdndwriterstatesty = set of sysdndwriterstatety; + + tsysdndwriter = class(tlinkedobject) + private + frepeater: tsimpletimer; + fstate: sysdndwriterstatesty; + fintf: isysdnd; + ftimestamp: longword; + fformats: atomarty; + fsource: winidty; + fdest: winidty; + fdestaccepts: boolean; + fpos: pointty; + fentervalues: array[0..4] of longword; + fpositionvalues: array[0..4] of longword; + protected + procedure startcheckrepeater; + procedure docheckrepeat(const sender: tobject); + procedure resetdest; + procedure selectioncleared(var aevent: xselectionclearevent); + function check(const apos: pointty): boolean; + function handleevent(var aevent: xclientmessageevent): tmseevent; + function drop: boolean; + function getdata(var aevent: xselectionrequestevent; + var adata: string; var aproperty: atom): boolean; + //false if no data + procedure objevent(const sender: iobjectlink; + const event: objecteventty); override; + public + constructor create(const aintf: isysdnd; const asource: winidty); + destructor destroy; override; + end; + +var + sysdndreader: tsysdndreader; + sysdndwriter: tsysdndwriter; + +{ tsysdndreader } + +constructor tsysdndreader.create(const aevent: xclientmessageevent); +var + lwo1: longword; + int1,int2: integer; + ar1: atomarty; +begin + freeandnil(sysdndwriter); + with aevent do begin + fwinid:= xwindow; + fsource:= data.l[0]; + lwo1:= data.l[1]; + fprotocolversion:= lwo1 shr 24; + faction:= data.l[4]; + if lwo1 and 1 <> 0 then begin //more than 3 types + //todo: suport for inc protocol + readatomproperty(fsource,xdndatoms[xdnd_typelist],ar1); + end + else begin + setlength(ar1,3); + move(data.l[2],ar1[0],3*sizeof(ar1[0])); + end; + setlength(fdataformats,length(ar1)); + setlength(fdatatypeatoms,length(ar1)); + int2:= 0; + for int1:= 0 to high(ar1) do begin + if ar1[int1] <> 0 then begin + fdatatypeatoms[int2]:= ar1[int1]; + fdataformats[int2]:= msestring(xgetatomname(appdisp,ar1[int1])); + inc(int2); + end; + end; + setlength(fdataformats,int2); + setlength(fdata,int2); + setlength(ftext,int2); + fformatistext:= nil; + setlength(fformatistext,int2); + end; +end; + +function tsysdndreader.readdata(var adata: string; + const typeindex: integer): guierrorty; +var + acttype: atom; + actformat: cint; + nitems: integer; +begin + if (typeindex < 0) or (typeindex > high(fdatatypeatoms)) then begin + result:= gue_index; + end + else begin + result:= gue_ok; + if fdata[typeindex] = '' then begin + result:= pastefromclipboard(fdata[typeindex],xdndatoms[xdnd_selection], + fdroptimestamp,[fdatatypeatoms[typeindex]],acttype,actformat,nitems); + end; + if result = gue_ok then begin + adata:= fdata[typeindex]; + end; + end; +end; + +function tsysdndreader.readtext(var atext: msestring; + const typeindex: integer): guierrorty; +var + acttype: atom; + actformat: cint; + nitems: integer; +begin + if (typeindex < 0) or (typeindex > high(fdatatypeatoms)) then begin + result:= gue_index; + end + else begin + result:= gue_ok; + if ftext[typeindex] = '' then begin + result:= pastefromclipboard(fdata[typeindex],xdndatoms[xdnd_selection], + fdroptimestamp,[fdatatypeatoms[typeindex]],acttype,actformat,nitems); + if result = gue_ok then begin + ftext[typeindex]:= msestring(fdata[typeindex]); + end; + end; + if result = gue_ok then begin + atext:= ftext[typeindex]; + end; + end; +end; + +function tsysdndreader.handleevent(var aevent: xclientmessageevent): tmseevent; + + function checkhandler(const updateposition: boolean): boolean; + begin + result:= false; + if sysdndreader <> nil then begin + if (sysdndreader.winid <> aevent.xwindow) or + (aevent.data.l[0] <> sysdndreader.fsource) then begin + freeandnil(sysdndreader); //there is something wrong + end + else begin + result:= true; + if updateposition then begin + with aevent,sysdndreader do begin + fpos:= mp(longword(data.l[2]) shr 16,data.l[2] and $ffff); + fshiftstate:= xtoshiftstate(data.l[1] and $ff,key_none,mb_none,false); + fscroll:= data.l[1] and (1 shl 10) <> 0; + faction:= data.l[4]; + end; + end; + end; + end; + end; //checkhandler + + function createevent(const akind: drageventkindty): tsysdndevent; + var + act1: dndactionty; + act2: dndactionsty; + begin + with sysdndreader do begin + act2:= []; + for act1:= low(dndactionty) to high(dndactionty) do begin + if xdndactionatoms[act1] = faction then begin + include(act2,act1); + break; + end; + end; + result:= tsysdndevent.create(akind,fwinid,fpos,fshiftstate, + fscroll,fdataformats,fformatistext,act2); + end; + end; //createevent + +begin + result:= nil; + with aevent do begin + if message_type = xdndatoms[xdnd_position] then begin + if checkhandler(true) then begin + result:= createevent(dek_check); + end; + end + else begin + if message_type = xdndatoms[xdnd_drop] then begin + if checkhandler(false) then begin + result:= createevent(dek_drop); + sysdndreader.fdroptimestamp:= data.l[2]; + end; + end + else begin + if message_type = xdndatoms[xdnd_leave] then begin + result:= createevent(dek_leavesysdnd); + freeandnil(sysdndreader); + end; + end; + end; + end; +end; + +function getactionatom(const aactions: dndactionsty): atom; +var + act1: dndactionty; +begin + result:= 0; + for act1:= low(dndactionty) to high(dndactionty) do begin + if act1 in aactions then begin + result:= xdndactionatoms[act1]; + break; + end; + end; +end; + +{ tsysdndwriter } + +constructor tsysdndwriter.create(const aintf: isysdnd; const asource: winidty); +var + ar1: msestringarty; + int1: integer; +// act1: dndactionty; +// act2: dndactionsty; +begin + fintf:= aintf; + getobjectlinker.link(iobjectlink(self),aintf); + fsource:= asource; + ftimestamp:= lasteventtime; + freeandnil(sysdndreader); + fentervalues[0]:= fsource; + fpositionvalues[0]:= fsource; + fpositionvalues[3]:= ftimestamp; + fpositionvalues[4]:= getactionatom(aintf.getactions); + ar1:= aintf.getformats; + setlength(fformats,length(ar1)); //todo: what about empty types? + for int1:= 0 to high(ar1) do begin + fformats[int1]:= xinternatom(appdisp,pchar(string(ar1[int1])), + {$ifdef xboolean}false{$else}0{$endif}); + if int1 <= high(fentervalues)-2 then begin + fentervalues[int1+2]:= fformats[int1]; + end; + end; + if high(fformats) > 2 then begin + setlongproperty(fsource,xdndatoms[xdnd_typelist],ulongarty(fformats),atomatom); + end; + gdi_lock; + xsetselectionowner(appdisp,xdndatoms[xdnd_selection],fsource,ftimestamp); + gdi_unlock; +end; + +destructor tsysdndwriter.destroy; +begin + include(fstate,sdws_destroying); + gdi_lock; + resetdest; + xsetselectionowner(appdisp,xdndatoms[xdnd_selection],0,ftimestamp); + //release selection + xdeleteproperty(appdisp,appid,xdndatoms[xdnd_typelist]); + gdi_unlock; + if fintf <> nil then begin + fintf.cancelsysdnd; + end; + inherited; +end; + +procedure tsysdndwriter.objevent(const sender: iobjectlink; + const event: objecteventty); +begin + inherited; + if (sender = fintf) and (event = oe_destroyed) then begin + fintf:= nil; + if not (sdws_destroying in fstate) then begin + freeandnil(sysdndwriter); + end; + end; +end; + +procedure tsysdndwriter.selectioncleared(var aevent: xselectionclearevent); +begin + if laterorsame(ftimestamp,aevent.time) then begin + if fintf <> nil then begin + fintf.cancelsysdnd; + end; + if sysdndwriter <> nil then begin //??? + sysdndwriter:= nil; + inherited destroy; + end; + end; +end; + +procedure tsysdndwriter.resetdest; +begin + if fdest <> 0 then begin + freeandnil(frepeater); + fdestaccepts:= false; + sendnetcardinalmessage(fdest,xdndatoms[xdnd_leave],fdest,[fsource]); + fdest:= 0; + freeandnil(frepeater); + end; +end; + +function tsysdndwriter.check(const apos: pointty): boolean; +var + ar1: atomarty; + ar2: winidarty; + int1: integer; +begin + result:= false; + ar2:= windowsatpos(apos); + for int1:= high(ar2) downto 0 do begin + if readatomproperty(ar2[int1],xdndatoms[xdnd_aware],ar1) and + (high(ar1) = 0) then begin + if ar2[int1] <> fdest then begin + if fdest <> 0 then begin + fdestaccepts:= false; + sendnetcardinalmessage(fdest,xdndatoms[xdnd_leave],fdest,[fsource]); + end; + fdest:= ar2[int1]; + if ar1[0] < 3 then begin + ar1[0]:= 3; + end + else begin + if ar1[0] > 4 then begin + ar1[0]:= 4; + end; + end; + ar1[0]:= ar1[0] shr 24; + if high(fformats) > 2 then begin + ar1[0]:= ar1[0] or 1; + end; + fentervalues[1]:= ar1[0]; + sendnetcardinalmessage(fdest,xdndatoms[xdnd_enter],fdest,fentervalues); + end; + fpos:= apos; + fpositionvalues[2]:= (fpos.x shl 16) or (fpos.y and $ffff); + fpositionvalues[4]:= getactionatom(fintf.getactions); + sendnetcardinalmessage(fdest,xdndatoms[xdnd_position],fdest,fpositionvalues); + result:= true; + startcheckrepeater; + exit; + end; + end; + if fdest <> 0 then begin + application.postevent(tsysdndstatusevent.create(fintf.geteventintf,false)); + end; + resetdest; +end; + +procedure tsysdndwriter.docheckrepeat(const sender: tobject); +begin + sendnetcardinalmessage(fdest,xdndatoms[xdnd_position],fdest,fpositionvalues); +end; + +const + checkrepeatinterval = 200000; + +procedure tsysdndwriter.startcheckrepeater; +begin + if frepeater = nil then begin + frepeater:= tsimpletimer.create(checkrepeatinterval, + {$ifdef FPC}@{$endif}docheckrepeat,true,[]); + end + else begin + frepeater.interval:= checkrepeatinterval; + end; +end; + +function tsysdndwriter.handleevent(var aevent: xclientmessageevent): tmseevent; +begin + result:= nil; + with aevent do begin + if (message_type = xdndatoms[xdnd_status]) then begin + if (fdest <> 0) and (data.l[0] = fdest) then begin + fdestaccepts:= data.l[1] and 1 <> 0; + result:= tsysdndstatusevent.create(fintf.geteventintf,fdestaccepts); + end; + end + else begin + if (message_type = xdndatoms[xdnd_finished]) then begin + freeandnil(sysdndwriter); + end; + end; + end; +end; + +function tsysdndwriter.drop: boolean; +begin + result:= true; + sendnetcardinalmessage(fdest,xdndatoms[xdnd_drop],fdest, + [fsource,0,ftimestamp]); +end; + +function tsysdndwriter.getdata(var aevent: xselectionrequestevent; + var adata: string; var aproperty: atom): boolean; +var + int1: integer; +begin + result:= false; + with aevent do begin + for int1:= 0 to high(fformats) do begin + if fformats[int1] = target then begin + adata:= fintf.convertmimedata(int1); + result:= true; + break; + end; + end; + end; + if not result then begin + aproperty:= none; + end; +end; + +function gui_sysdnd(const action: sysdndactionty; + const aintf: isysdnd; const arect: rectty; + out aresult: boolean): guierrorty; +var + act1: atom; +begin + aresult:= false; + result:= gue_nodragpending; + if sysdndwriter <> nil then begin + result:= gue_ok; + case action of + sdnda_begin: begin + freeandnil(sysdndwriter); + sysdndwriter:= tsysdndwriter.create(aintf,appid); + end; + sdnda_finished: begin + if sysdndwriter <> nil then begin + if not sysdndwriter.fdestaccepts then begin //todo: timeout + freeandnil(sysdndwriter); + end; + end; + end; + sdnda_destroyed: begin + freeandnil(sysdndwriter); + end; + sdnda_check: begin + aresult:= sysdndwriter.check(arect.pos); + end; + sdnda_drop: begin + aresult:= sysdndwriter.drop; + end; + else begin + result:= gue_error; + end; + end; + end + else begin + if sysdndreader <> nil then begin + //todo: use limit rectangle + result:= gue_ok; + with sysdndreader do begin + if aintf <> nil then begin + act1:= getactionatom(aintf.getactions); + end + else begin + act1:= faction; + end; + case action of + sdnda_reject: begin + sendnetcardinalmessage(fsource,xdndatoms[xdnd_status],fsource, + [fwinid,2,0,0,act1]); //always get position messages + end; + sdnda_accept: begin + sendnetcardinalmessage(fsource,xdndatoms[xdnd_status],fsource, + [fwinid,3,0,0,act1]); //always get position messages + end; + sdnda_finished: begin + sendnetcardinalmessage(fsource,xdndatoms[xdnd_finished],fsource, + [fwinid,1,act1]); //always accepted + freeandnil(sysdndreader); + end; + else begin + result:= gue_error; + end; + end; + end; + end + else begin //writer = nil + result:= gue_ok; + case action of + sdnda_begin: begin + sysdndwriter:= tsysdndwriter.create(aintf,appid); + end; + else begin + result:= gue_nodragpending; + end; + end; + end; + end; +end; + +function gui_sysdndreaddata(var adata: string; + const typeindex: integer): guierrorty; +begin + result:= gue_nodragpending; + if sysdndreader <> nil then begin + result:= sysdndreader.readdata(adata,typeindex); + end; +end; + +function gui_sysdndreadtext(var atext: msestring; + const typeindex: integer): guierrorty; +begin + result:= gue_nodragpending; + if sysdndreader <> nil then begin + result:= sysdndreader.readtext(atext,typeindex); + end; +end; + +function handlexdnd(var aevent: xclientmessageevent): tmseevent; + +begin + result:= nil; + with aevent do begin + if sysdndwriter <> nil then begin + result:= sysdndwriter.handleevent(aevent); + end + else begin + if message_type = xdndatoms[xdnd_enter] then begin + freeandnil(sysdndreader); + sysdndreader:= tsysdndreader.create(aevent); + end + else begin + if sysdndreader <> nil then begin + result:= sysdndreader.handleevent(aevent); + end; + end; + end; + end; +end; + +function getclipboarddata(var aevent: xselectionrequestevent; + const buffer: clipboardbufferty; + var adata: string; var aproperty: atom): boolean; + //false if no data +var + atomar: array[0..7] of atom; + textprop: xtextproperty; +begin + with aevent,clipboardbuffers[buffer] do begin + result:= false; + if target = targetsatom then begin + atomar[0]:= textplainatom; + atomar[1]:= utf8_stringatom; + atomar[2]:= compound_textatom; + atomar[3]:= stringatom; + atomar[4]:= textatom; + atomar[5]:= targetsatom; + atomar[6]:= timestampatom; +// atomar[7]:= multipleatom; //not implemented + xchangeproperty(appdisp,requestor,aproperty,atomatom,32, + propmodereplace,@atomar[0],7); + end + else begin + if target = timestampatom then begin + atomar[0]:= timestamp; + xchangeproperty(appdisp,requestor,aproperty,target,32, + propmodereplace,@atomar[0],1); + end + else begin + result:= true; + if target = utf8_stringatom then begin + adata:= stringtoutf8ansi(buffer); + end + else begin + if target = stringatom then begin + adata:= stringtolatin1(buffer); + end + else begin + if (target = textatom) or (target = textplainatom) then begin + adata:= ansistring(buffer); //current locale + end + else begin + result:= false; + if target = compound_textatom then begin + if stringtotextproperty(buffer,xcompoundtextstyle, + textprop) then begin + with textprop do begin + xchangeproperty(appdisp,requestor, + {$ifdef FPC}_property{$else}xproperty{$endif},encoding, + format,propmodereplace,value,nitems); + xfree(value); + end; + end + else begin + aproperty:= none; + end; + end + else begin + aproperty:= none; + end; + end; + end; + end; + end; + end; + end; +end; + +function isclipboard(const aselection: atom; + out buffer: clipboardbufferty): boolean; +var + buf1: clipboardbufferty; +begin + result:= false; + for buf1:= low(clipboardbufferty) to high(clipboardbufferty) do begin + if clipboardbuffers[buf1].name = aselection then begin + buffer:= buf1; + result:= true; + break; + end; + end; +end;//isclipboard + +procedure handleselectionrequest(var aevent: xselectionrequestevent); +var + event1: xselectionevent; + str1: string; + bo1: boolean; + buffer: clipboardbufferty; + +begin + with aevent do begin + event1.xtype:= selectionnotify; + event1.requestor:= requestor; + event1.selection:= selection; + if {$ifdef FPC}_property{$else}xproperty{$endif} = none then begin + {$ifdef FPC}_property{$else}xproperty{$endif}:= target; + end; + event1.target:= target; + event1.{$ifdef FPC}_property{$else}xproperty{$endif}:= + {$ifdef FPC}_property{$else}xproperty{$endif}; + event1.time:= time; + bo1:= false; + if isclipboard(selection,buffer) then begin + bo1:= getclipboarddata(aevent,buffer,str1, + event1.{$ifdef FPC}_property{$else}xproperty{$endif}); + end + else begin + if (selection = xdndatoms[xdnd_selection]) and + (sysdndwriter <> nil) then begin + bo1:= sysdndwriter.getdata(aevent,str1, + {$ifdef FPC}_property{$else}xproperty{$endif}); + end + else begin + {$ifdef FPC}_property{$else}xproperty{$endif}:= none; + end; + end; + if bo1 then begin + xchangeproperty(appdisp,requestor, + {$ifdef FPC}_property{$else}xproperty{$endif},target,8, + propmodereplace,pbyte(pchar(str1)),length(str1)); + end; + xsendevent(appdisp,requestor,{$ifdef xboolean}false{$else}0{$endif},0, + @event1); + end; +end; + +var + connectmutex1: mutexty; + connectmutex2: mutexty; + +procedure gui_disconnectmaineventqueue(); //called by gdi_lock() +begin + sys_mutexlock(connectmutex2); + if sys_mutextrylock(connectmutex1) <> sye_ok then begin + sys_write(connectpipe.writedes,@dummybyte,1); + sys_mutexlock(connectmutex1); + end; +end; + +procedure gui_connectmaineventqueue(); //called by gdi_unlock() +begin + sys_mutexunlock(connectmutex1); + sys_mutexunlock(connectmutex2); +end; + +type + pollinfoarty = array of pollfd; + pollinfoty = record + callback: pollcallbackty; + data: pointer; + end; + pollinfodestarty = array of pollinfoty; + pollinfty = record + pollinfo: pollinfoarty; + pollinfodest: pollinfodestarty; + end; + ppollinfty = ^pollinfty; + +var +// pollinfo: array[0..2] of pollfd; + //0 connection, 1 sessionmanagement + pollinf: ppollinfty; + +function gui_addpollfd(var id: int32; const afd: int32; + const aflags: pollflagsty; + const acallback: pollcallbackty = nil; + const adata: pointer = nil): guierrorty; +begin + result:= gue_ok; + with pollinf^ do begin + setlength(pollinfo,high(pollinfo)+2); + setlength(pollinfodest,length(pollinfo)); + id:= high(pollinfo); + with pollinfo[id] do begin + fd:= afd; + events:= int32(aflags * [pf_in,pf_pri,pf_out]); + with pollinfodest[id] do begin + callback:= acallback; + data:= adata; + end; + end; + end; +end; + +function gui_removepollfd(const id: int32): guierrorty; +begin + with pollinf^ do begin + if (id < 0) or (id > high(pollinfo)) then begin + result:= gue_index; + end + else begin + deleteitem(pollinfo,typeinfo(pollinfo),id); + deleteitem(pollinfodest,typeinfo(pollinfodest),id); + result:= gue_ok; + end; + end; +end; + +function gui_setpollfdactive(const id: int32; + const aactive: boolean): guierrorty; +begin + with pollinf^ do begin + if (id < 0) or (id > high(pollinfo)) then begin + result:= gue_index; + end + else begin + with pollinfo[id] do begin + if (fd >= 0) xor aactive then begin + if fd = 0 then begin + fd:= minint; + end + else begin + if fd = minint then begin + fd:= 0; + end + else begin + fd:= -fd; + end; + end; + end; + end; + result:= gue_ok; + end; + end; +end; + +{$ifdef mse_debugsysevent} + +function eventname(const event: int32): string; +begin + case event of + 2: result:= 'KeyPress'; + 3: result:= 'KeyRelease'; + 4: result:= 'ButtonPress'; + 5: result:= 'ButtonRelease'; + 6: result:= 'MotionNotify'; + 7: result:= 'EnterNotify'; + 8: result:= 'LeaveNotify'; + 9: result:= 'FocusIn'; + 10: result:= 'FocusOut'; + 11: result:= 'KeymapNotify'; + 12: result:= 'Expose'; + 13: result:= 'GraphicsExpose'; + 14: result:= 'NoExpose'; + 15: result:= 'VisibilityNotify'; + 16: result:= 'CreateNotify'; + 17: result:= 'DestroyNotify'; + 18: result:= 'UnmapNotify'; + 19: result:= 'MapNotify'; + 20: result:= 'MapRequest'; + 21: result:= 'ReparentNotify'; + 22: result:= 'ConfigureNotify'; + 23: result:= 'ConfigureRequest'; + 24: result:= 'GravityNotify'; + 25: result:= 'ResizeRequest'; + 26: result:= 'CirculateNotify'; + 27: result:= 'CirculateRequest'; + 28: result:= 'PropertyNotify'; + 29: result:= 'SelectionClear'; + 30: result:= 'SelectionRequest'; + 31: result:= 'SelectionNotify'; + 32: result:= 'ColormapNotify'; + 33: result:= 'ClientMessage'; + 34: result:= 'MappingNotify'; + 35: result:= 'GenericEvent'; + else result:= ''; + end; +end; + +procedure debugevent(const aevent: xevent); +var + atomar: atomarty; + i1: int32; +begin + debugwrite(debugwindow1('sysevent ',aevent.xany.xwindow)+' '+ + inttostr(aevent.xany.xtype)+' '+eventname(aevent.xany.xtype)); + case aevent.xany.xtype of + propertynotify: begin + debugwrite(' '+xgetatomname(appdisp,aevent.xproperty.atom)); + if aevent.xproperty.atom = wmstateatom then begin + debugwrite(' '+getenumname(typeinfo(wmstatety), + ord(getwmstate(aevent.xproperty.xwindow)))); + end + else begin + if aevent.xproperty.atom = netatoms[net_wm_state] then begin + readatomproperty(aevent.xproperty.xwindow,netatoms[net_wm_state],atomar); + debugwrite(':'); + for i1:= 0 to high(atomar) do begin + debugwrite(' '+xgetatomname(appdisp,atomar[i1])); + end; + end; + end; + end; + end; + debugwriteln(''); +end; +{$endif} + +var + hasminimizeunmapworkaround: boolean; //for gnome + lastmapwindow: xid; + +function windowdestroyed(const w: winidty): boolean; +var + xev2: txevent; +begin + xsync(appdisp,0); + result:= xchecktypedwindowevent(appdisp,w,destroynotify,@xev2); +end; + +function gui_getevent: tmseevent; + + function checkrepeatkey(const aevent: xevent): boolean; + begin + if (repeatkey = aevent.xkey.keycode) and + (repeatkeytime = aevent.xkey.time) then begin + {$ifdef mse_debugkey} + debugwriteln('is repeatkey key:'+inttostr(repeatkey)+ + ' time:'+inttostr(repeatkeytime)); + {$endif} + result:= true; + end + else begin + resetrepeatkey(); + result:= false; + end; + end;//checkrepeatkey + +var + xev,xev2: xevent; +// w: winidty; + eventkind: eventkindty; + akey: keysym; + buffer: string; + icstatus: tstatus; + chars: msestring; + i1,i2: integer; +// event: xevent; +// str1: string; +{$ifdef with_sm} + int2: integer; +{$endif} + shiftstate1: shiftstatesty; + key1,key2: keyty; + button1: mousebuttonty; + bo1: boolean; + rect1: rectty; + pt1: pointty; + aic: xic; + window1: twindow; + buf1: clipboardbufferty; + fdwakeup: boolean; + allsig,sig1: sigset_t; + timeout1: timespec; + b1: boolean; + win1: twindow; + +type + char_0_19 = array[0..19] of char; + +label + eventrestart; +begin + result:= nil; + sigfillset(allsig); + timeout1.tv_sec:= 10; + timeout1.tv_nsec:= 0; + fdwakeup:= false; + while not fdwakeup do begin + if timerevent then begin + application.postevent(tmseevent.create(ek_timer)); + timerevent:= false; + end; + if terminated then begin + application.postevent(tmseevent.create(ek_terminate)); + terminated:= false; + end; + if childevent then begin + childevent:= false; + handlesigchld; + end; + if gui_hasevent then begin + break; + end; + + pthread_sigmask(sig_block,@allsig,@sig1); //block signals + if not timerevent and not terminated and not childevent then begin + repeat + if not application.unlock() then begin + guierror(gue_notlocked); + end; + + sys_mutexlock(connectmutex1); +// int1:= poll(@pollinfo[0],length(pollinfo),1000); +// //todo: use ppoll? no timeout? + with pollinf^ do begin + i1:= ppoll(@pollinfo[0],length(pollinfo),@timeout1,@sig1); + if pollinfo[1].revents <> 0 then begin + repeat //empty pipe + until (__read(connectpipe.readdes,dummybyte,1) < 0) and + (sys_getlasterror() = ewouldblock); + end; + sys_mutexunlock(connectmutex1); + sys_mutexlock(connectmutex2); + sys_mutexunlock(connectmutex2); + + if i1 > 0 then begin + for i2:= 0 to high(pollinfo) do begin + with pollinfo[i2] do begin + if (fd >= 0) then begin + with pollinfodest[i2] do begin + if (callback <> nil) and (revents <> 0) then begin + callback(pollflagsty(card32(card16(revents))),data); + fdwakeup:= true; + end; + end; + end; + end; + end; + end; + end; + //wakeup clientmessages are sometimes missed with xcb ??? + if i1 = 0 then begin //timeout + inc(timeoutcount); + if timeoutcount mod 1 = 0 then begin + timerevent:= true; //every 10 seconds without messages + //in case of lost timer alarm + end; + end; + application.lock; + until (i1 <> -1) or timerevent or terminated or childevent or fdwakeup; + pthread_sigmask(sig_setmask,@sig1,nil); //enable signals + {$ifdef with_sm} + if hassm then begin + if (i1 > 0) and (pollinf^.pollinfo[2].revents <> 0) then begin + iceprocessmessages(sminfo.iceconnection,nil,int2); + with sminfo do begin + if shutdown then begin + if not shutdownpending then begin + interactgranted:= false; + shutdownpending:= true; + if (interactstyle = sminteractstyleerrors) or + (interactstyle = sminteractstyleany) then begin + if SmcInteractRequest(smconnection,smdialognormal, + {$ifdef FPC}@{$endif}interact,@sminfo) = 0 then begin + {$ifdef smdebug} + writeln('gui_getevent SmcInteractRequest'); + {$endif} + terminated:= true; + end + else begin + interactwaiting:= true; + end; + end + else begin + interactwaiting:= false; + terminated:= true; + end; + end + else begin + if interactwaiting and interactgranted then begin + terminated:= true; + interactwaiting:= false; + end; + end; + end; + end; + end; + end; +{$endif} + end + else begin + pthread_sigmask(sig_setmask,@sig1,nil); //enable signals + end; + end; + +eventrestart: + b1:= false; + while true do begin + i1:= xpending(appdisp); + if i1 > 0 then begin + xnextevent(appdisp,@xev); + if (xev.xtype = keyrelease) then begin + {$ifdef mse_debugkey} + debugwriteln('repeatkey start pending:'+inttostr(i1)); + {$endif} + if i1 < 2 then begin + xsync(appdisp,0); + i1:= xpending(appdisp) + 1; + {$ifdef mse_debugkey} + debugwriteln('repeatkey second pending:'+inttostr(i1)); + {$endif} + end; + if i1 > 1 then begin + xpeekevent(appdisp,@xev2); + if (xev2.xtype = keypress) and + (xev.xkey.keycode = xev2.xkey.keycode) and + (xev.xkey.time = xev2.xkey.time) then begin + repeatkey:= xev.xkey.keycode; + repeatkeytime:= xev.xkey.time; + {$ifdef mse_debugkey} + debugwriteln('repeatkey key:'+inttostr(repeatkey)+ + ' time:'+inttostr(repeatkeytime)); + {$endif} + end; + end; + end; + {$ifdef mse_debugsysevent} + debugevent(xev); + {$endif} + if longint(xfilterevent(@xev,none)) = 0 then begin + b1:= true; + break; + end + else begin + {$ifdef mse_debugsysevent} + debugwriteln('sysevent filtered'); + {$endif} + end; + end + else begin + break; + end; + end; + if not b1 then begin + {$ifdef mse_debugsysevent} + debugwriteln('sysevent exit'); + {$endif} + exit; + end; + + bo1:= false; + tguiapplication1(application).sysevent(xev.xany.xwindow,syseventty(xev),bo1); + if bo1 then begin + exit; + end; + if xev.xany.xwindow = appid then begin + if (xev.xtype = selectionclear) then begin + if isclipboard(xev.xselectionclear.selection,buf1) then begin + clipboardbuffers[buf1].buffer:= ''; + exit; + end; + if (xev.xselectionclear.selection = xdndatoms[xdnd_selection]) and + (sysdndwriter <> nil) then begin + sysdndwriter.selectioncleared(xev.xselectionclear); + end; + end + else begin + if xev.xtype = selectionrequest then begin + handleselectionrequest(xev.xselectionrequest); + exit; + end; + end; + end; + case xev.xtype of + clientmessage: begin + with xev.xclient do begin + if display = appdisp then begin + if message_type = mseclientmessageatom then begin + result:= tmseevent(getclientpointer(xev.xclient)); + end + else begin + if message_type = wmprotocolsatom then begin + if longword(data.l[0]) = wmprotocols[wm_delete_window] then begin + result:= twindowevent.create(ek_close,xwindow); +{$ifdef with_saveyourself} + end + else begin + if longword(data.l[0]) = wmprotocols[wm_save_yourself] then begin + result:= tevent.create(ek_terminate); + saveyourselfwindow:= window; + end; + end; +{$else} + end; +{$endif} + end + else begin + {$ifdef mse_debugxembed} + if (netatoms[xembed] <> 0) and + (message_type = netatoms[xembed]) then begin + debugwindow('*xembed ',window); + writeln(' ',inttohex(data.l[0],8),' ', + inttohex(data.l[1],8),' ', + inttohex(data.l[2],8),' ', + inttohex(data.l[3],8),' ', + inttohex(data.l[4],8)); + end; + if (netatoms[net_system_tray_message_data] <> 0) and + (message_type = netatoms[net_system_tray_message_data]) then begin + debugwindow( + '*net_system_tray_message_data format:'+inttostr(format)+' ',window); + writeln(' ',char_0_19(data.b)); + end; + if (netatoms[net_system_tray_opcode] <> 0) and + (message_type = netatoms[net_system_tray_opcode]) then begin + debugwindow( + '*net_system_tray_opcode format:'+inttostr(format)+' ',window); + writeln(' ',inttohex(data.l[0],8),' ', + inttohex(data.l[1],8),' ', + inttohex(data.l[2],8),' ', + inttohex(data.l[3],8),' ', + inttohex(data.l[4],8)); + end; + {$endif} + result:= handlexdnd(xev.xclient); + end; + end; + end; + end; + end; + propertynotify: begin + with xev.xproperty do begin + if atom = wmstateatom then begin //gnome workaround, missing unmap/map + if application.findwindow(xwindow,win1) then begin + if windowdestroyed(xwindow) then begin + result:= twindowevent.create(ek_destroy,xwindow); + end + else begin + case getwmstate(xwindow) of + wms_iconic: begin + if windowmapped(xwindow) then begin + result:= twindowevent.create(ek_hide,xwindow); + hasminimizeunmapworkaround:= true; + lastmapwindow:= 0; + {$ifdef mse_debugsysevent} + debugwriteln(' synthetic ek_hide'); + {$endif} + end; + end; + wms_normal: begin + if hasminimizeunmapworkaround and + (lastmapwindow <> xwindow) then begin + lastmapwindow:= 0; + result:= twindowevent.create(ek_show,xwindow); + {$ifdef mse_debugsysevent} + debugwriteln(' synthetic ek_show'); + {$endif} + end; + end; + end; + end; + end; + end; + end; + end; + enternotify: begin + with xev.xcrossing do begin + result:= tmouseenterevent.create(xwindow, + makepoint(x,y),xtoshiftstate(state,key_none,mb_none,false), + time*1000); + end; + end; + leavenotify: begin + with xev.xcrossing do begin + if mode = notifynormal then begin //?? + result:= twindowevent.create(ek_leavewindow,xwindow); + end; + end; + end; + motionnotify: begin + with xev.xmotion do begin + lasteventtime:= time; + result:= tmouseevent.create(xwindow,false,mb_none,mw_none, + makepoint(x,y),xtoshiftstate(state,key_none,mb_none,false),time*1000); + end; + end; + keypress: begin + with xev.xkey do begin + b1:= false; + {$ifdef FPC} + aic:= getic(window); + {$else} + aic:= getic(xwindow); + {$endif} + lasteventtime:= time; + setlength(buffer,20); + i1:= xutf8lookupstring(aic,@xev.xkey,@buffer[1],length(buffer), + @akey,@icstatus); + setlength(buffer,i1); + if icstatus = xbufferoverflow then begin + xutf8lookupstring(aic,@xev.xkey,@buffer[1],length(buffer),@akey,@icstatus); + end; + chars:= utf8tostringansi(buffer); + {$ifdef mse_debugkey} + debugwriteln('*X11keypress window '+hextostr(window,8)+'"'+buffer+'" key:'+ + inttostr(akey)+' time:'+inttostr(time)); + {$endif} + case icstatus of + xlookupnone: exit; + xlookupchars: akey:= 0; + xlookupkeysym_: chars:= ''; + end; + {$ifdef mse_debugkey} + debugwriteln('after icstatuscheck'); + {$endif} + shiftstate1:= []; + key1:= xkeytokey(akey,shiftstate1); + if key1 = key_escape then begin + escapepressed:= true; + end; + shiftstate1:= shiftstate1 + xtoshiftstate(state,key1,mb_none,false); + if checkrepeatkey(xev) then begin + include(shiftstate1,ss_repeat); + end; + if (keycode = repeatkey) and (time = repeatkeytime) then begin + include(shiftstate1,ss_repeat); + resetrepeatkey; + end; + key2:= getkeynomod(xev.xkey); + result:= tkeyevent.create(xwindow,false,key1,key2, + shiftstate1,chars,time*1000); + end; + end; + keyrelease: begin + with xev.xkey do begin + lasteventtime:= time; + if checkrepeatkey(xev) then begin + {$ifdef mse_debugkey} + debugwriteln('keyrelease dropped, eventrestart'); + {$endif} + goto eventrestart; + end; + i1:= keycode; + xlookupstring(@xev.xkey,nil,0,@akey,nil); + {$ifdef mse_debugkey} + debugwriteln('*X11keyrelease window '+hextostr(window,8)+ + ' key:'+inttostr(akey)+' time:'+inttostr(time)); + {$endif} + shiftstate1:= []; + key1:= xkeytokey(akey,shiftstate1); + key2:= getkeynomod(xev.xkey); + shiftstate1:= shiftstate1 + xtoshiftstate(state,key1,mb_none,true); + (* does not work anymore because of intermediate messages by IM + if xpending(appdisp) > 0 then begin + xpeekevent(appdisp,@xev); + if (xev.xtype = keypress) and (time - lasteventtime < 10) and + (keycode = int1) then begin + repeatkey:= int1; + repeatkeytime:= time; + {$ifdef mse_debugkey} + debugwriteln('eventrestart'); + {$endif} + goto eventrestart; //auto repeat key, don't send + end; + end; + *) + result:= tkeyevent.create(xwindow,true,key1,key2,shiftstate1,'',time*1000); + end; + end; + buttonpress,buttonrelease: begin + with xev.xbutton do begin + {$ifdef mse_debugmouse} + if xtype = buttonpress then begin + debugwrite('*X11buttonpress'); + end + else begin + debugwrite('*X11buttonrelease'); + end; + debugwriteln(' window '+hextostr(window,8)+ + ' button:'+inttostr(button)+' x:'+inttostr(x)+' y:'+inttostr(y)+ + ' time:'+inttostr(time)); + {$endif} + lasteventtime:= time; + button1:= xtomousebutton(button); + shiftstate1:= xtoshiftstate(state,key_none,button1,xev.xtype=buttonrelease); + if button = 4 then begin + if xev.xtype = buttonpress then begin + result:= tmouseevent.create(xwindow,false,mb_none,mw_up, + makepoint(x,y),shiftstate1,time*1000); + end; + end + else begin + if button = 5 then begin + if xev.xtype = buttonpress then begin + result:= tmouseevent.create(xwindow,false,mb_none,mw_down, + makepoint(x,y),shiftstate1,time*1000); + end; + end + else begin + result:= tmouseevent.create(xwindow,xtype = buttonrelease,button1,mw_none, + makepoint(x,y),shiftstate1,time*1000); + end; + end; + end; + end; + mappingnotify: begin + xrefreshkeyboardmapping(@xev.xkeymap); + end; + mapnotify: begin + with xev.xmap do begin + lastmapwindow:= xwindow; + result:= twindowevent.create(ek_show,xwindow); + if application.findwindow(xwindow,window1) and + (wo_notaskbar in window1.options) then begin + setnetatomarrayitem(xwindow,net_wm_state,net_wm_state_skip_taskbar); + end; + end; + end; + unmapnotify: begin + with xev.xunmap do begin + result:= twindowevent.create(ek_hide,xwindow); + end; + end; + reparentnotify: begin + with xev.xreparent do begin + result:= treparentevent.create(ek_reparent,xwindow,parent); + end; + end; + focusin,focusout: begin + with xev.xfocus do begin + if xtype = focusin then begin + eventkind:= ek_focusin; + lastfocuswindow:= window; + end + else begin + eventkind:= ek_focusout; + lastfocuswindow:= 0; + end; + if mode <> notifypointer then begin + result:= twindowevent.create(eventkind,window); + end; + end; + end; + expose: begin + with xev.xexpose do begin + result:= twindowrectevent.create(ek_expose,xwindow, + makerect(x,y,width,height),nullpoint); + end; + end; + graphicsexpose: begin + with xev.xgraphicsexpose do begin + result:= twindowrectevent.create(ek_expose,drawable, + makerect(x,y,width,height),nullpoint); + end; + end; + configurenotify: begin + with xev.xconfigure do begin + if windowdestroyed(xwindow) then begin + result:= twindowevent.create(ek_destroy,xwindow); + end + else begin + if not application.deinitializing then begin + rect1.x:= x; + rect1.y:= y; + pt1:= nullpoint; + if send_event = 0 then begin //from window manager? + getrootoffset(xwindow,pt1); //no, map to screen origin + end; + rect1.cx:= width; + rect1.cy:= height; + {$ifdef mse_debugconfigure} + debugwindow('*conf winrect:'+ + inttostr(pt1.x)+' '+inttostr(pt1.y)+'|'+ + inttostr(rect1.x)+' '+inttostr(rect1.y)+ + ' '+inttostr(rect1.cx)+' '+inttostr(rect1.cy)+ + ' above:',above,xwindow); + {$endif} + result:= twindowrectevent.create(ek_configure,xwindow,rect1,pt1); + end; + +(* gnome bug workaround + if not application.deinitializing and + (getwindowrect(w,rect1,pt1) = gue_ok) then begin + //there can be an Xerror? + //gnome returns a different pos on window resizing than on window moving! + {$ifdef mse_debugconfigure} + debugwindow('*conf winrect '+ + inttostr(pt1.x)+' '+inttostr(pt1.y)+'|'+ + inttostr(rect1.x)+' '+inttostr(rect1.y)+ + ' '+inttostr(rect1.cx)+' '+inttostr(rect1.cy)+' ',w); + {$endif} + result:= twindowrectevent.create(ek_configure,w,rect1,pt1); + end; + {$ifdef mse_debugconfigure} + debugwriteln(' '+inttostr(x)+' '+inttostr(y)+ + ' '+inttostr(width)+' '+inttostr(height)); + {$endif} + while tboolresult(xchecktypedwindowevent( + appdisp,w,configurenotify,@xev)) do begin + {$ifdef mse_debugconfigure} + debugwriteln(' '+inttostr(x)+' '+inttostr(y)+ + ' '+inttostr(width)+' '+inttostr(height)); + {$endif} + end; +*) + end; + end; + end; + destroynotify: begin + with xev.xdestroywindow do begin + if xwindow = lastmapwindow then begin + lastmapwindow:= 0; + end; + if (sysdndreader <> nil) and + (sysdndreader.winid = xwindow) then begin + freeandnil(sysdndreader); + end; + if (sysdndwriter <> nil) then begin + with sysdndwriter do begin + if fdest = xwindow then begin + fdest:= 0; + end; + if fsource = xwindow then begin + freeandnil(sysdndwriter); + end; + end; + end; + result:= twindowevent.create(ek_destroy,xwindow); + end; + end; + else begin + if hasxrandr and (xev.xtype >= xrandreventbase) and + (xev.xtype <= xrandreventbase+rrlastnotify) then begin + screenrectsvalid:= false; + xrrupdateconfiguration(@xev); + end; + end; + end; +end; + +function errorhandler(Display: PDisplay; ErrorEvent: PXErrorEvent): + Longint; cdecl; +const + buflen = 256; +var + buffer: array[0..buflen] of char; +begin + if xlockerror = 0 then begin + xgeterrortext(display,errorevent^.error_code,@buffer,buflen); + sys_errorout('X Error: '+ pchar(@buffer) + ' '+inttostr(errorevent^.error_code)+ + lineend +' Major opcode: '+inttostr(errorevent^.request_code)+lineend); + end; + result:= 0; +end; + +function gui_initcolormap: guierrorty; +begin + gdi_lock; + if is8bitcolor and istruecolor then begin + setcolormapvalue(cl_background,$d0,$e0,$d0); + //green instead of blue tint + end; + result:= gue_ok; + gdi_unlock; +end; + +procedure initcolormap; +const + redm = $07; + reds = 5; + greenm = $38; + greens = 2; + bluem = $c0; + blues = 0; +{ + redm = $e0; + reds = 0; + greenm = $1c; + greens = 3; + bluem = $03; + blues = 6; +} +var + map1: array[0..255] of xcolor; + int1: integer; +begin + msecolormap:= xcreatecolormap(appdisp,rootid,pointer(defvisual),allocall); + if msecolormap <> 0 then begin + xredshiftbase:= reds; + xgreenshiftbase:= greens; + xblueshiftbase:= blues; + xredshiftleft:= false; + xredshift:= 16 + reds; + xredmask:= redm; + xgreenshiftleft:= false; + xgreenshift:= 8 + greens; + xgreenmask:= greenm; + xblueshiftleft:= false; + xblueshift:= 0 + blues; + xbluemask:= bluem; + for int1:= 0 to 255 do begin +{$warnings off} + with map1[int1] do begin + pixel:= int1; + red:= ($ffff*(int1 and redm)) div redm ; + green:= ($ffff*(int1 and greenm)) div greenm ; + blue:= ($ffff*(int1 and bluem)) div bluem ; + {$ifdef FPC} + flags:= dored or dogreen or doblue; + pad:= 0; + {$else} + flags:= char(dored or dogreen or doblue); + pad:= #0; + {$endif} + end; + end; + with map1[$f6] do begin //value for cl_background + red:= $d000; + green:= $d000; + blue:= $d000; + end; + xstorecolors(appdisp,msecolormap,@map1,256); + end; +end; +{$warnings on} +{ +function createappic: boolean; forward; +function icdestroyed(ic: txic; client_data: txpointer; + call_data: txpointer): longbool; cdecl; +begin + result:= false; + appic:= nil; + if not terminated then begin + if not createappic then begin + debugwriteln('Input context lost.'); + halt(1); + end; + end; +end; +} +function createappic: boolean; +//var +// xiccallback: txiccallback; +begin + appic:= xcreateic(im,pchar(xninputstyle),ximstatusnothing or ximpreeditnothing,nil); + result:= appic <> nil; + if result then begin + { + xiccallback.client_data:= nil; + xiccallback.callback:= @icdestroyed; + } + xseticvalues(appic,pchar(xnclientwindow),appid, + {pchar(xndestroycallback)@,xiccallback,}nil); + xgeticvalues(appic,pchar(xnfilterevents),@appicmask,nil); + end; +end; + +function createim: boolean; forward; + +function checklocale: pchar; +begin + result:= setlocale(lc_all,''); + if xsupportslocale() = 0 then begin + setlocale(lc_all,'en_US.UTF-8'); + if xsupportslocale() = 0 then begin + setlocale(lc_all,'en_US.utf8'); + if xsupportslocale() = 0 then begin + setlocale(lc_all,'POSIX'); + if xsupportslocale() = 0 then begin + setlocale(lc_all,'C'); + xsupportslocale(); + end; + end; + end; + end; +end; + +procedure imdestroyed(ic: pxim; client_data: xpointer; + call_data: xpointer); cdecl; +var + po1: pchar; +begin + im:= nil; + appic:= nil; + if not terminated then begin + po1:= checklocale; + if not createim or not createappic then begin + debugwriteln('Input method lost.'); + halt(1); + end; + setlocale(lc_all,po1); //restore original + end; +end; + +function createim: boolean; +var + ximcallback: tximcallback; +begin + xsetlocalemodifiers(''); + im:= xopenim(appdisp,nil,nil,nil); + if im = nil then begin + xsetlocalemodifiers('@im=none'); + im:= xopenim(appdisp,nil,nil,nil); + { + xsetlocalemodifiers('@im=local'); + im:= xopenim(appdisp,nil,nil,nil); + if im = nil then begin + xsetlocalemodifiers('@im='); + im:= xopenim(appdisp,nil,nil,nil); + end; + } + end; + result:= im <> nil; + if result then begin + ximcallback.client_data:= nil; + ximcallback.callback:= @imdestroyed; + xsetimvalues(im,pchar(xndestroycallback),@ximcallback,nil); + end; +end; + +function gui_init: guierrorty; +label + error; +var +// fontpropnames: strfontproparty; +// propnum: fontpropertiesty; + attrib: xsetwindowattributes; + netnum: netatomty; + int1,int2: integer; + po1: pchar; + atom1: atom; + atomar: atomarty; + rect1: rectty; + sigset1,sigset2: sigset_t; +{$ifdef with_sm} + smcb: smccallbacks; + clientid: pchar; + smerror: array[0..255] of char; +{$endif} + po2: pkeycode; + modmap: pxmodifierkeymap; + numlockcode: cuint; + buf1: clipboardbufferty; + +begin + gdi_lock; + try + getmem(pollinf,sizeof(pollinfty)); + fillchar(pollinf^,sizeof(pollinfty),0); + sys_mutexcreate(connectmutex1); + sys_mutexcreate(connectmutex2); + pipe2(connectpipe,o_cloexec or o_nonblock); + resetrepeatkey; + {$ifdef mse_flushgdi} + xinitthreads; + {$endif} + {$ifdef with_sm} + if hassm then begin + if sminfo.smconnection = nil then begin + if iceaddconnectionwatch(@icewatch,@sminfo) <> 0 then begin + with smcb do begin + save_yourself.callback:= @SmcSaveYourself; + save_yourself.client_data:= @sminfo; + die.callback:= @SmcDie; + die.client_data:= @sminfo; + save_complete.callback:= @SmcSaveComplete; + save_complete.client_data:= @sminfo; + shutdown_cancelled.callback:= @SmcShutdownCancelled; + shutdown_cancelled.client_data:= @sminfo; + end; + + sminfo.smconnection:= smcopenconnection(nil,nil,SmProtoMajor,SmProtoMinor, + SmcSaveYourselfProcMask or SmcDieProcMask or SmcSaveCompleteProcMask or + SmcShutdownCancelledProcMask,smcb,nil,clientid,sizeof(smerror),@smerror); + if clientid <> nil then begin + xfree(clientid); + end; + if sminfo.smconnection = nil then begin + hassm:= false; + sys_errorout('Sessionmanager Error: '+ smerror+lineend); + end; + end; + end; + end; + {$endif} + {$ifdef with_saveyourself} + saveyourselfwindow:= 0; + {$endif} + lasteventtime:= currenttime; + + po1:= checklocale; + terminated:= false; + result:= gue_nodisplay; + timerevent:= false; + sigtimerbefore:= signal(sigalrm,{$ifdef FPC}@{$endif}sigtimer); + sigtermbefore:= signal(sigterm,{$ifdef FPC}@{$endif}sigterminate); + sigchldbefore:= signal(sigchld,{$ifdef FPC}@{$endif}sigchild); + sigemptyset(sigset1); + sigaddset(sigset1,sigchld); + pthread_sigmask(sig_unblock,@sigset1,@sigset2); + + appdisp:= xopendisplay(nil); + if appdisp = nil then begin + goto error; + end; + + if not createim then begin + result:= gue_inputmanager; + goto error; + end; + setlocale(lc_all,po1); //restore original + +// defscreenid:= xdefaultscreen(appdisp); + defscreen:= xdefaultscreenofdisplay(appdisp); + rootid:= xrootwindowofscreen(defscreen); + defvisual:= msepvisual(xdefaultvisualofscreen(defscreen)); + defdepth:= xdefaultdepthofscreen(defscreen); + msex11gdi.init(appdisp,defvisual,defdepth); + attrib.event_mask:= propertychangemask; + appid:= xcreatewindow(appdisp,rootid,0,0,200,200,0, + 0,inputonly,xlib.pvisual(copyfromparent),cweventmask,@attrib); + if appid = 0 then begin + result:= gue_createwindow; + goto error; + end; + + if hasxrandrlib then begin + hasxrandr:= xrrqueryextension( + appdisp,@xrandreventbase,@xrandrerrorbase) <> 0; + if hasxrandr then begin + xrrselectinput(appdisp,rootid, RRScreenChangeNotifyMask or + RRCrtcChangeNotifyMask or RROutputChangeNotifyMask); + end; + end + else begin + hasxrandr:= false; + end; + + if not createappic then begin + result:= gue_inputcontext; + goto error; + end; + {$ifdef FPC} + is8bitcolor:= defaultdepthofscreen(defscreen) = 8; + {$else} + is8bitcolor:= defscreen^.root_depth = 8; + {$endif} + if (defvisual^._class = pseudocolor) and is8bitcolor then begin + istruecolor:= false; + initcolormap; + if msecolormap = 0 then begin + result:= gue_nocolormap; + goto error; + end; + end + else begin + istruecolor:= (defvisual^._class = truecolor) or + (defvisual^._class = directcolor); + if istruecolor then begin + xredmask:= defvisual^.red_mask; + xgreenmask:= defvisual^.green_mask; + xbluemask:= defvisual^.blue_mask; + xredshiftbase:= highestbit(xredmask)-7; + xgreenshiftbase:= highestbit(xgreenmask)-7; + xblueshiftbase:= highestbit(xbluemask)-7; + xredshift:= xredshiftbase - redshift; + if xredshift < 0 then begin + xredshiftleft:= false; + xredshift:= -xredshift; + end + else begin + xredshiftleft:= true; + end; + xgreenshift:= xgreenshiftbase - greenshift; + if xgreenshift < 0 then begin + xgreenshiftleft:= false; + xgreenshift:= -xgreenshift; + end + else begin + xgreenshiftleft:= true; + end; + xblueshift:= xblueshiftbase - blueshift; + if xblueshift < 0 then begin + xblueshiftleft:= false; + xblueshift:= -xblueshift; + end + else begin + xblueshiftleft:= true; + end; + end + else begin + result:= gue_notruecolor; + goto error; + end; + end; + + defcolormap:= xdefaultcolormapofscreen(defscreen); + + atomatom:= xinternatom(appdisp,'ATOM', + {$ifdef xboolean}true{$else}1{$endif}); + mseclientmessageatom:= xinternatom(appdisp,'mseclientmessage', + {$ifdef xboolean}false{$else}0{$endif}); + wmprotocolsatom:= xinternatom(appdisp,'WM_PROTOCOLS', + {$ifdef xboolean}false{$else}0{$endif}); + wmnameatom:= xinternatom(appdisp,'WM_NAME', + {$ifdef xboolean}false{$else}0{$endif}); + wmclassatom:= xinternatom(appdisp,'WM_CLASS', + {$ifdef xboolean}false{$else}0{$endif}); + wmprotocols[wm_delete_window]:= xinternatom(appdisp,'WM_DELETE_WINDOW', + {$ifdef xboolean}false{$else}0{$endif}); + {$ifdef with_saveyourself} + wmprotocols[wm_save_yourself]:= xinternatom(appdisp,'WM_SAVE_YOURSELF', + {$ifdef FPC}false{$else}0{$endif}); + wmcommandatom:= xinternatom(appdisp,'WM_COMMAND', + {$ifdef FPC}false{$else}0{$endif}); + {$endif} + wmstateatom:= xinternatom(appdisp,'WM_STATE', + {$ifdef xboolean}false{$else}0{$endif}); + wmtransientforatom:= xinternatom(appdisp,'WM_TRANSIENT_FOR', + {$ifdef xboolean}false{$else}0{$endif}); + wmclientleaderatom:= xinternatom(appdisp,'WM_CLIENT_LEADER', + {$ifdef xboolean}false{$else}0{$endif}); + for buf1:= low(clipboardbuffers) to high(clipboardbuffers) do begin + clipboardbuffers[buf1].name:= xinternatom(appdisp, + pchar(clipboardnames[buf1]),{$ifdef xboolean}false{$else}0{$endif}); + end; + cardinalatom:= xinternatom(appdisp,'CARDINAL', + {$ifdef xboolean}false{$else}0{$endif}); + windowatom:= xinternatom(appdisp,'WINDOW', + {$ifdef xboolean}false{$else}0{$endif}); + stringatom:= xinternatom(appdisp,'STRING', + {$ifdef xboolean}false{$else}0{$endif}); + textatom:= xinternatom(appdisp,'TEXT', + {$ifdef xboolean}false{$else}0{$endif}); + textplainatom:= xinternatom(appdisp,'text/plain', + {$ifdef xboolean}false{$else}0{$endif}); + compound_textatom:= xinternatom(appdisp,'COMPOUND_TEXT', + {$ifdef xboolean}false{$else}0{$endif}); + utf8_stringatom:= xinternatom(appdisp,'UTF8_STRING', + {$ifdef xboolean}false{$else}0{$endif}); + timestampatom:= xinternatom(appdisp,'TIMESTAMP', + {$ifdef xboolean}false{$else}0{$endif}); + multipleatom:= xinternatom(appdisp,'MULTIPLE', + {$ifdef xboolean}false{$else}0{$endif}); + targetsatom:= xinternatom(appdisp,'TARGETS', + {$ifdef xboolean}false{$else}0{$endif}); + convertselectionpropertyatom:= xinternatom(appdisp,'mseconvselprop', + {$ifdef xboolean}false{$else}0{$endif}); + + netsupportedatom:= xinternatom(appdisp,'_NET_SUPPORTED', + {$ifdef xboolean}false{$else}0{$endif}); + + fillchar(xdndatoms,sizeof(xdndatoms),0); //get or create xdnd atoms + xinternatoms(appdisp,@xdndatomnames[low(xdndatomty)], + integer(high(xdndatomty))+1,{$ifdef xboolean}false{$else}0{$endif}, + @xdndatoms[low(xdndatomty)]); + fillchar(xdndactionatoms,sizeof(xdndactionatoms),0); //get or create xdnd atoms + xinternatoms(appdisp,@xdndactionatomnames[firstdndaction], + integer(high(dndactionty)),{$ifdef xboolean}false{$else}0{$endif}, + @xdndactionatoms[firstdndaction]); //first = 0 + + fillchar(netatoms,sizeof(netatoms),0); //check _net_ + xinternatoms(appdisp,@netatomnames[low(netatomty)], + integer(firstonlyifexistatom),false,@netatoms[low(netatomty)]); + xinternatoms(appdisp,@netatomnames[firstonlyifexistatom], + integer(high(netatomty))-integer(firstonlyifexistatom), + true,@netatoms[firstonlyifexistatom]); + + netsupported:= netsupportedatom <> 0; + if netsupported then begin + netsupported:= readatomproperty(rootid,netsupportedatom,atomar); + for netnum:= firstcheckedatom to lastcheckedatom do begin + atom1:= netatoms[netnum]; + netatoms[netnum]:= 0; + for int1:= 0 to high(atomar) do begin + if atomar[int1] = atom1 then begin + netatoms[netnum]:= atom1; + break; + end; + end; + end; + end; + for netnum:= low(netatomty) to needednetatom do begin + if netatoms[netnum] = 0 then begin + netsupported:= false; + break; + end; + end; + + netsupported:= netsupported and + readcardinalproperty(rootid,netatoms[net_workarea],4,rect1); + canframeextents:= netatoms[net_frame_extents] <> 0; + canfullscreen:= netatoms[net_wm_state_fullscreen] <> 0; + if netsupported and not canfullscreen then begin + netatoms[net_wm_state_fullscreen]:= xinternatom(appdisp, + @netatomnames[net_wm_state_fullscreen], + {$ifdef xboolean}false{$else}0{$endif}); //fake + end; + + numlockstate:= 0; + numlockcode:= xkeysymtokeycode(appdisp,xk_num_lock); + if numlockcode <> nosymbol then begin //return numlock state + modmap:= xgetmodifiermapping(appdisp); + {$ifdef FPC} {$checkpointer off} {$endif} + po2:= modmap^.modifiermap; + for int1:= 0 to 7 do begin + for int2:= 0 to modmap^.max_keypermod - 1 do begin + if po2^ = numlockcode then begin + numlockstate:= 1 shl int1; + break; + end; + inc(po2); + end; + if numlockstate <> 0 then begin + break; + end; + end; + xfreemodifiermap(modmap); + {$ifdef FPC} {$checkpointer default} {$endif} + end; + +// fillchar(pollinfo,sizeof(pollinfo),0); +// pollcount:= 2; + pollinf^.pollinfo:= nil; + gui_addpollfd(int1,xconnectionnumber(appdisp),[pf_in,pf_pri]); //0 + gui_addpollfd(int1,connectpipe.readdes,[pf_in,pf_pri]); //1 + {$ifdef with_sm} + if hassm and (sminfo.fd > 0) then begin + gui_addpollfd(int1,sminfo.fd,[pf_in,pf_pri]); //2 + end; + {$endif} +(* + with pollinfo[0] do begin + fd:= xconnectionnumber(appdisp); + events:= pollin or pollpri; + end; + with pollinfo[1] do begin + fd:= connectpipe.readdes; + events:= pollin or pollpri; + end; +{$ifdef with_sm} + if hassm then begin + if sminfo.fd > 0 then begin + with pollinfo[2] do begin + fd:= sminfo.fd; + events:= pollin or pollpri; + end; + inc(pollcount); + end; + end; +{$endif} +*) + result:= gue_ok; + {$ifdef mse_flushgdi} + xsynchronize(appdisp,1); + {$endif} + errorhandlerbefore:= xseterrorhandler({$ifdef FPC}@{$endif}errorhandler); + exit; + error: + deinit; + finally + gdi_unlock; + end; +end; + +function gui_deinit: guierrorty; +var + buf1: clipboardbufferty; +begin + gdi_lock; + try + freeandnil(sysdndreader); + freeandnil(sysdndwriter); + for buf1:= low(clipboardbuffers) to high(clipboardbuffers) do begin + clipboardbuffers[buf1].buffer:= ''; + end; + result:= gue_ok; + settimer1(0); //kill timer + terminated:= true; + freeclientevents; + {$ifdef with_sm} + if hassm then begin + with sminfo do begin + if smconnection <> nil then begin + if shutdown and shutdownpending then begin + if interactwaiting and interactgranted then begin + smcinteractdone(smconnection,0); + {$ifdef smdebug} + writeln('gui_deinit smcinteractdone'); + {$endif} + end; + smcsaveyourselfdone(smconnection,1); + {$ifdef smdebug} + writeln('gui_deinit saveyourselfdone'); + {$endif} + end; + iceremoveconnectionwatch({$ifdef FPC}@{$endif}icewatch,@sminfo); + {$ifdef smdebug} + writeln('gui_deinit iceremoveconnectionwatch'); + {$endif} + smccloseconnection(sminfo.smconnection,0,nil); + {$ifdef smdebug} + writeln('gui_deinit smccloseconnection'); + {$endif} + fillchar(sminfo,sizeof(sminfo),0); + end; + end; + end; + {$endif} + {$ifdef with_saveyourself} + if saveyourselfwindow <> 0 then begin + setstringproperty(saveyourselfwindow,wmcommandatom,''); + end; + {$endif} + if appic <> nil then begin + xdestroyic(appic); + appic:= nil; + end; + if im <> nil then begin + xcloseim(im); + im:= nil; + end; + if appid <> 0 then begin + xdestroywindow(appdisp,appid); + appid:= 0; + end; + // if screencursor <> 0 then begin + // xfreecursor(appdisp,screencursor); + // screencursor:= 0; + // end; + if appdisp <> nil then begin + if msecolormap <> 0 then begin + xfreecolormap(appdisp,msecolormap); + msecolormap:= 0; + end; + xclosedisplay(appdisp); + appdisp:= nil; + end; + sys_closefile(connectpipe.writedes); + sys_closefile(connectpipe.readdes); + sys_mutexdestroy(connectmutex1); + sys_mutexdestroy(connectmutex2); + signal(sigalrm,sigtimerbefore); + signal(sigterm,sigtermbefore); + signal(sigchld,sigchldbefore); + xseterrorhandler(errorhandlerbefore); + screenrects:= nil; + screenrectsvalid:= false; + finalize(pollinf^); + freemem(pollinf); + finally + gdi_unlock; + end; +end; + +{ +procedure gui_gdifunc(const func: gdifuncty; var drawinfo: drawinfoty); +begin + gdifunctions[func](drawinfo); +end; +} + +function gui_getgdifuncs: pgdifunctionaty; +begin + result:= x11getgdifuncs; +end; + +var + debugungrabbed: boolean; + +procedure GUI_DEBUGBEGIN; +var + int1: integer; +begin + int1:= sys_getlasterror; + if pointergrabbed then begin + debugungrabbed:= true; + gui_ungrabpointer; + end; + if appdisp <> nil then begin + xflush(appdisp); + end; + sys_setlasterror(int1); +end; + +procedure GUI_DEBUGEND; +var + int1: integer; +begin + if debugungrabbed then begin + int1:= sys_getlasterror; + gui_grabpointer(grabwinid); + sys_setlasterror(int1); + debugungrabbed:= false; + end; +end; + +function gui_registergdi: guierrorty; +begin + registergdi(x11getgdifuncs); + result:= gue_ok; +end; + +initialization + mainthreadid:= sys_getcurrentthread(); + norestackwindow:= true; + noreconfigurewmwindow:= true; + stackmodebelowworkaround:= false; +// nocreatestaticgravity:= true; + hassm:= geticelib and getsmlib; + hasxrandrlib:= getxrandrlib; +end. \ No newline at end of file diff --git a/mseide-msegui/lib/common/kernel/linux/msenoguiintf.pas b/mseide-msegui/lib/common/kernel/linux/msenoguiintf.pas new file mode 100644 index 0000000..4297578 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/linux/msenoguiintf.pas @@ -0,0 +1,126 @@ +{ MSEgui Copyright (c) 1999-2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msenoguiintf; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msesystypes; + +{$include ../msenoguiintf.inc} + +implementation +uses + mselibc,mseevent,msesysintf1,mseapplication,msenogui,mseprocmonitor; +type + tapplication1 = class(tnoguiapplication); +var + sigtimerbefore: sighandler_t; + sigtermbefore: sighandler_t; + sigchldbefore: sighandler_t; + timerevent: boolean; + terminated: boolean; + childevent: boolean; + sempo: psemty; + +procedure settimer1(us: longword); + //send et_timer event after delay of us (micro seconds) +var + timerval: itimerval; +begin + fillchar(timerval,sizeof(timerval),0); + timerval.it_value.tv_sec:= us div 1000000; + timerval.it_value.tv_usec:= us mod 1000000; + mselibc.setitimer(itimer_real,{$ifdef FPC}@{$endif}timerval,nil); +end; + +procedure nogui_waitevent; + procedure checkevents; + begin + if timerevent then begin + timerevent:= false; + application.postevent(tmseevent.create(ek_timer)); + end; + if terminated then begin + timerevent:= false; + application.postevent(tmseevent.create(ek_terminate)); + end; + if childevent then begin + childevent:= false; + handlesigchld; + end; + end; + +begin + with tapplication1(application) do begin + include(fstate,aps_waiting); + checkevents; + while eventlist.count = 0 do begin + with linuxsemty(sempo^) do begin + unlock; + sem_wait(d.sema); + lock; + checkevents; + end; + end; + fstate:= fstate -[aps_waiting,aps_woken]; + end; +end; + +procedure nogui_settimer(us: longword); +begin + if us = 0 then begin + us:= 1; + end; + settimer1(us); +end; + +procedure sigtimer(SigNum: Integer); cdecl; +begin + timerevent:= true; + sem_post(linuxsemty(sempo^).d.sema); +end; + +procedure sigterminate(SigNum: Integer); cdecl; +begin + terminated:= true; + sem_post(linuxsemty(sempo^).d.sema); +end; + +procedure sigchild(SigNum: Integer); cdecl; +begin + childevent:= true; + mseprocmonitor.sigchildcallback(); + sem_post(linuxsemty(sempo^).d.sema); +end; + +procedure nogui_init(const asempo: psemty); +var + sigset1,sigset2: sigset_t; +begin + sempo:= asempo; + sigtimerbefore:= signal(sigalrm,{$ifdef FPC}@{$endif}sigtimer); + sigtermbefore:= signal(sigterm,{$ifdef FPC}@{$endif}sigterminate); + sigchldbefore:= signal(sigchld,{$ifdef FPC}@{$endif}sigchild); + sigemptyset(sigset1); + sigaddset(sigset1,sigchld); + sigprocmask(sig_unblock,@sigset1,@sigset2); +end; + +procedure nogui_deinit; +begin + terminated:= true; + settimer1(0); + signal(sigalrm,sigtimerbefore); + signal(sigterm,sigtermbefore); + signal(sigchld,sigchldbefore); +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/linux/mseprocmonitor.pas b/mseide-msegui/lib/common/kernel/linux/mseprocmonitor.pas new file mode 100644 index 0000000..4b9ecec --- /dev/null +++ b/mseide-msegui/lib/common/kernel/linux/mseprocmonitor.pas @@ -0,0 +1,239 @@ +{ MSEgui Copyright (c) 2008-2009 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseprocmonitor; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +interface +uses + msesystypes,mseglob,msetypes,mselibc; + + {$include ../mseprocmonitor.inc} + +procedure sigchildcallback; +function timedwaitpid(__pid: __pid_t; __stat_loc: plongint; + const waitus: integer): __pid_t; + //waitus must be > 0 + //result -1 -> error, -2 -> timeout + +implementation +uses + mseapplication,msedatalist,msearrayutils,msesysintf1,msesysutils,sysutils; + +type + procinfoty = record + prochandle: prochandlety; + dest: iprocmonitor; + data: pointer; + end; + procinfoarty = array of procinfoty; +var + infos: procinfoarty; + +function pro_listentoprocess(const aprochandle: prochandlety; + const adest: iprocmonitor; const adata: pointer): boolean; +begin + application.lock; + setlength(infos,high(infos)+2); + with infos[high(infos)] do begin + prochandle:= aprochandle; + dest:= adest; + data:= adata; + end; + application.unlock; + result:= true; +end; + +procedure pro_unlistentoprocess(const aprochandle: prochandlety; + const adest: iprocmonitor); +var + int1: integer; +begin + application.lock; + for int1:= high(infos) downto 0 do begin + with infos[int1] do begin + if (prochandle = aprochandle) and (dest = adest) then begin + deleteitem(infos,typeinfo(procinfoarty),int1); + end; + end; + end; + application.unlock; +end; + +procedure checkchildproc(); +var + int1,int2,int3: integer; + dwo1: dword; + execresult: integer; +begin + application.lock; + int1:= high(infos); + while int1 >= 0 do begin + int3:= waitpid(infos[int1].prochandle,@dwo1,wnohang); + if (int3 > 0) and (wifexited(dwo1) or wifsignaled(dwo1)) then begin + execresult:= wexitstatus(dwo1); + end + else begin + execresult:= -2; //still running for int3 = 0 + if (int3 < 0) and (sys_getlasterror() = ECHILD) then begin + execresult:= -1; + end; + end; + if execresult >= -1 then begin + for int2:= int1 downto 0 do begin + with infos[int2] do begin + if prochandle = infos[int1].prochandle then begin + if dest <> nil then begin + dest.processdied(prochandle,execresult,data); + end; + deleteitem(infos,typeinfo(procinfoarty),int2); + if int2 <> int1 then begin + dec(int1); + end; + end; + end; + end; + end; + dec(int1); + end; + application.unlock; +end; + +procedure pro_killzombie(const aprochandle: prochandlety); +begin + pro_listentoprocess(aprochandle,nil,nil); +end; + +type + psemelety = ^semelety; + semelety = record + prev: psemelety; + next: psemelety; + sem: semty; + end; + +var + semaphorelock: mutexty; + semaphores: psemelety; +{$ifdef mse_debugprocmonitor} +var + semcount: int32; + +procedure checksemaphores(); +var + i1: int32; + po1: psemelety; +begin + i1:= 0; + po1:= semaphores; + while po1 <> nil do begin + inc(i1); + po1:= po1^.next; + end; + if i1 <> semcount then begin + raise exception.create('Invalid procmonitor semaphores'); + end; +end; + +{$endif} + +procedure sigchildcallback(); +var + po1: psemelety; +begin +{$ifdef mse_debugprocmonitor} + checksemaphores(); +{$endif} + po1:= semaphores; + while po1 <> nil do begin + sys_sempost(po1^.sem); + po1:= po1^.next; + end; +end; + +function timedwaitpid(__pid: __pid_t; __stat_loc: plongint; + const waitus: integer): __pid_t; + //waitus must be > 0 + //result -1 -> error, -2 -> timeout +var + semele: semelety; + lwo1: longword; + int1: integer; +begin + result:= -1; + if waitus > 0 then begin + lwo1:= timestep(waitus); + sys_semcreate(semele.sem,0); + + sys_mutexlock(semaphorelock); +{$ifdef mse_debugprocmonitor} + checksemaphores(); +{$endif} + semele.prev:= semaphores; + semele.next:= nil; + if semaphores = nil then begin + interlockedexchange(semaphores,@semele); + end + else begin + interlockedexchange(semaphores^.next,@semele); + end; +{$ifdef mse_debugprocmonitor} + inc(semcount); + checksemaphores(); +{$endif} + sys_mutexunlock(semaphorelock); + + while true do begin + repeat + result:= waitpid(__pid,__stat_loc,wnohang); + until (result >= 0) or (sys_getlasterror <> eintr); + if (result = __pid) or (result < 0) then begin + break; + end; + int1:= lwo1-timestamp; + if int1 > 0 then begin + sys_semwait(semele.sem,int1); + end + else begin + result:= waitpid(__pid,__stat_loc,wnohang); + if result < 0 then begin + result:= -2; + end; + break; + end; + end; + + sys_mutexlock(semaphorelock); +{$ifdef mse_debugprocmonitor} + checksemaphores(); +{$endif} +// if semele.prev = nil then begin + if semaphores = @semele then begin + interlockedexchange(semaphores,semele.next); + end + else begin + interlockedexchange(semele.prev^.next,semele.next); + end; +{$ifdef mse_debugprocmonitor} + dec(semcount); + checksemaphores(); +{$endif} + sys_mutexunlock(semaphorelock); + + sys_semdestroy(semele.sem); + end; +end; + +initialization + onhandlesigchld:= @checkchildproc; + sys_mutexcreate(semaphorelock); + +finalization + onhandlesigchld:= nil; + sys_mutexdestroy(semaphorelock); +end. diff --git a/mseide-msegui/lib/common/kernel/linux/msesetlocale.pas b/mseide-msegui/lib/common/kernel/linux/msesetlocale.pas new file mode 100644 index 0000000..45f89d5 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/linux/msesetlocale.pas @@ -0,0 +1,258 @@ +{ MSEgui Copyright (c) 1999-2008 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msesetlocale; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mselibc,msesys; + +function getcodeset(): string; + +implementation +uses + cwstring,sysutils,msestrings,mseformatstr,msetypes,msesysintf; + +function getlocstr(const id: integer; const defaultvalue: string): string; +var + po1: pchar; +begin + po1:= nl_langinfo(id); + if po1 = nil then begin + result:= defaultvalue; + end + else begin + result:= po1; + end; +end; + +function getcodeset(): string; +begin + result:= getlocstr(codeset,''); +end; + +function convertcformatstring(const source,defaultvalue: string): string; +var + po1: pchar; +begin + result:= ''; + po1:= pchar(source); + while po1^ <> #0 do begin + if po1^ = '%' then begin + inc(po1); + case po1^ of + '%': result:= result + '%'; + 'a': result:= result + 'ddd'; + 'A': result:= result + 'dddd'; + 'b': result:= result + 'mmm'; + 'B': result:= result + 'mmmm'; + 'c': result:= result + 'c'; +// 'C': + 'd': result:= result + 'dd'; + 'D': result:= result + 'mm/dd/yy'; + 'e': result:= result + 'd'; +// 'E': + 'g': result:= result + 'yy'; + 'G': result:= result + 'yyyy'; + 'h': result:= result + 'mmm'; + 'H': result:= result + 'HH'; + 'I': result:= result + 'hh'; +// 'j': + 'k': result:= result + 'H'; + 'l': result:= result + 'h'; + 'm': result:= result + 'mm'; + 'M': result:= result + 'nn'; + 'n': result:= result + lineend; +// 'O': + 'P','p': result:= result + 'ampm'; + 'r': result:= result + convertcformatstring(nl_langinfo(t_fmt_ampm),''); + 'R': result:= result + 'hh:nn'; +// 's': + 'S': result:= result + 'ss'; + 't': result:= result + c_tab; + 'T': result:= result + 'hh:nn:ss'; +// 'u': +// 'U': +// 'V': +// 'w': +// 'W': + 'x': result:= result + convertcformatstring(nl_langinfo(d_fmt),''); + 'X': result:= result + convertcformatstring(nl_langinfo(t_fmt),''); + 'y': result:= result + 'yy'; + 'Y': result:= result + 'yyyy'; +// 'z': + end; + end + else begin + result:= result + po1^; + end; + inc(po1); + end; + result:= trimright(result); + if result = '' then begin + result:= defaultvalue; + end; +end; + +procedure findfirstchar(const value,chars: msestring; var result: msechar); +var + int1: integer; + po1: pmsechar; +begin + po1:= pmsechar(value); + while po1^ <> #0 do begin + for int1:= 1 to length(chars) do begin + if po1^ = chars[int1] then begin + result:= po1^; + break; + end; + end; + inc(po1); + end; +end; + +procedure initformatsettings; +{$ifdef FPC} +var + int1: integer; + ch1,ch2{$ifdef linux},ch3{$endif}: char; + str1,str2: string; + mstr1: msestring; +{$ifndef linux} + bo1: boolean; +{$endif} + + currfo: array[0..1,0..1] of byte = ((1,3),(0,2)); + //[p_cs_precedes,p_sep_by_space] +{$ifdef linux} + negcurrfo: array[0..1,0..1,0..4] of byte = + (((4,5,7,6,7),(15,8,10,13,10)),((0,1,3,1,2),(14,9,11,9,12))); + //[n_cs_precedes,n_sep_by_space,n_sign_posn] +{$endif} +{$endif} +begin + initdefaultformatsettings; + //msesys initialization will be called after msesetlocale initialization. + //FPC bug? + + with defaultformatsettingsmse do begin + {$ifdef FPC} + mstr1:= msestring(getlocstr(decimal_point,ansistring(decimalseparator))); + if mstr1 <> '' then begin + decimalseparator:= mstr1[1]; + end; + mstr1:= msestring(getlocstr(thousands_sep,ansistring(thousandseparator))); + if mstr1 <> '' then begin + thousandseparator:= mstr1[1]; + end + else begin + mstr1:= msestring(getlocstr(mon_decimal_point,ansistring(decimalseparator))); + if mstr1 <> '' then begin + decimalseparator:= mstr1[1]; + mstr1:= msestring(getlocstr(mon_thousands_sep, + ansistring(thousandseparator))); + if mstr1 <> '' then begin + thousandseparator:= mstr1[1]; + end + else begin + thousandseparator:= ' '; + end; + end + else begin + thousandseparator:= ' '; + end; + end; + + for int1:= 1 to 12 do begin + shortmonthnames[int1]:= msestring(getlocstr(abmon_1 + int1 - 1, + ansistring(shortmonthnames[int1]))); + longmonthnames[int1]:= msestring(getlocstr(mon_1 + int1 - 1, + ansistring(longmonthnames[int1]))); + end; + for int1:= 1 to 7 do begin + shortdaynames[int1]:= msestring(getlocstr(abday_1 + int1 - 1, + ansistring(shortdaynames[int1]))); + longdaynames[int1]:= msestring(getlocstr(day_1 + int1 - 1, + ansistring(longdaynames[int1]))); + end; + shortdateformat:= msestring(convertcformatstring(getlocstr(d_fmt,''), + ansistring(shortdateformat))); + str1:= getlocstr(d_t_fmt,''); + str2:= getlocstr(t_fmt,''); + int1:= pos(str2,str1); + if int1 > 0 then begin + str1:= trimright(copy(str1,1,int1-1)); + end; + longdateformat:= msestring(convertcformatstring(str1, + ansistring(longdateformat))); + // longdateformat:= convertcformatstring(getlocstr(d_t_fmt,''),longdateformat); + shorttimeformat:= msestring(convertcformatstring(getlocstr(t_fmt,''), + ansistring(shorttimeformat))); + longtimeformat:= msestring(convertcformatstring(getlocstr(t_fmt_ampm,''), + ansistring(longtimeformat))); + findfirstchar(shortdateformat,'./-',dateseparator); + findfirstchar(shorttimeformat,':.',timeseparator); + + timeamstring:= msestring(getlocstr(am_str,ansistring(timeamstring))); + if timeamstring = '' then begin + timeamstring:= 'am'; + end; + timepmstring:= msestring(getlocstr(pm_str,ansistring(timepmstring))); + if timepmstring = '' then begin + timepmstring:= 'pm'; + end; + currencystring:= msestring(getlocstr(currency_symbol, + ansistring(currencystring))); +{$ifdef linux} + {$ifdef FPC}{$checkpointer off}{$endif} + ch1:= nl_langinfo(p_cs_precedes)^; + ch2:= nl_langinfo(p_sep_by_space)^; + if (ch1 in [#0,#1]) and (ch2 in [#0,#1]) then begin + currencyformat:= currfo[ord(ch1),ord(ch2)]; + ch3:= nl_langinfo(p_sign_posn)^; + if ord(ch3) in [0..4] then begin + negcurrformat:= negcurrfo[ord(ch1),ord(ch2),ord(ch3)]; + end; + end; + ch1:= nl_langinfo(frac_digits)^; + if byte(ch1) < 127 then begin + currencydecimals:= ord(ch1); + end; +{$else} //bsd + if currencystring <> '' then begin + ch1:= #0; + ch2:= #0; + bo1:= true; + case currencystring[1] of + '-': ch1:= #1; + '+': ch1:= #0; + '.': ch1:= #0; //not suported + else bo1:= false; + end; + if bo1 then begin + currencystring:= copy(currencystring,2,bigint); + currencyformat:= currfo[ord(ch1),ord(ch2)]; + end; + end; +{$endif} + saveformatsettings; + {$ifdef FPC}{$checkpointer default}{$endif} + {$endif} + end; + + str1:= strlowercase(getcodeset()); + if (str1 = 'utf8') or (str1 = 'utf-8') then begin + filenameutfoptions:= [uto_storeinvalid]; + end; +end; + +initialization + setlocale(LC_ALL,''); + initformatsettings; +end. diff --git a/mseide-msegui/lib/common/kernel/linux/msesocketintf.pas b/mseide-msegui/lib/common/kernel/linux/msesocketintf.pas new file mode 100644 index 0000000..8c49e30 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/linux/msesocketintf.pas @@ -0,0 +1,501 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msesocketintf; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + msesystypes,msesys; +{$ifdef FPC} + {$include ../msesocketintf.inc} +{$else} + {$include msesocketintf.inc} +{$endif} + +implementation +uses + mselibc,msefileutils,msesysintf1,msesysintf,msesysutils,sysutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + datarecty = record + //dummy + end; + + locsockaddrty = record + sa_family: sa_family_t; + sa_data: datarecty; + end; + plocsockaddrty = ^locsockaddrty; + + linuxsockadty = record + case integer of + 0: (addr: sockaddr_in); + 1: (addr6: sockaddr_in6); + end; + + linuxsockaddrty = record + ad: linuxsockadty; + platformdata: array[7..32] of longword; + end; + +function soc_getaddrerrortext(aerror: integer): string; +begin + result:= strpas(gai_strerror(aerror)); +end; + +function soc_geterrortext(aerror: integer): string; +begin + result:= inttostr(aerror); +end; + +function soc_setnonblock(const handle: integer; const nonblock: boolean): syserrorty; +var + int1: integer; +begin + result:= sye_ok; + int1:= fcntl(handle,f_getfl,[0]); + if int1 = -1 then begin + result:= syelasterror + end + else begin + if nonblock then begin + int1:= int1 or o_nonblock; + end + else begin + int1:= int1 and not o_nonblock; + end; + if fcntl(handle,f_setfl,[int1]) = -1 then begin + result:= sye_lasterror; + end; + end; +end; + +function soc_open(const kind: socketkindty; const nonblock: boolean; + out handle: integer): syserrorty; +var + int1: integer; +begin + case kind of + sok_inet: int1:= pf_inet; + sok_inet6: int1:= pf_inet6; + else int1:= pf_local; //sok_local + end; + handle:= socket(int1,sock_stream,0); + if handle = -1 then begin + result:= syelasterror; + end + else begin + result:= soc_setnonblock(handle,nonblock); + end; +end; + +function soc_shutdown(const handle: integer; + const kind: socketshutdownkindty): syserrorty; +begin + if mselibc.shutdown(handle,ord(kind)) <> 0 then begin + result:= syelasterror; + end + else begin + result:= sye_ok; + end; +end; + +function soc_close(const handle: integer): syserrorty; +begin + if mselibc.__close(handle) = 0 then begin + result:= sye_ok; + end + else begin + result:= syelasterror; + end; +end; + +function soc_connect(const handle: integer; const addr: socketaddrty; + const timeoutms: integer): syserrorty; +var + str1: string; + po1: plocsockaddrty; + int1{,int2}: integer; + pollres: pollkindsty; +begin + result:= sye_ok; + with addr do begin + if kind = sok_local then begin + str1:= ansistring(tosysfilepath(url)); + int1:= sizeof(locsockaddrty)+length(str1)+1; + getmem(po1,int1); + po1^.sa_family:= af_local; + move(str1[1],po1^.sa_data,length(str1)); + pchar(@po1^.sa_data)[length(str1)]:= #0; + {$ifdef FPC} + if connect(handle,pointer(po1),int1) <> 0 then begin + {$else} + if connect(handle,psockaddr(po1)^,int1) <> 0 then begin + {$endif} + result:= soc_poll(handle,[poka_write],timeoutms,pollres); + if result = sye_ok then begin + {$ifdef FPC} + if connect(handle,pointer(po1),int1) <> 0 then begin + {$else} + if connect(handle,psockaddr(po1)^,int1) <> 0 then begin + {$endif} + result:= syelasterror; + end; + end; + end; + freemem(po1); + end + else begin + with linuxsockaddrty(platformdata) do begin + {$ifdef linux} + int1:= __libc_sa_len(ad.addr.sa_family); + {$else} + int1:= ad.addr.sa_len; + {$endif} + po1:= @ad.addr; + {$ifdef FPC} + if connect(handle,pointer(po1),int1) <> 0 then begin + {$else} + if connect(handle,psockaddr(po1)^,int1) <> 0 then begin + {$endif}; + result:= soc_poll(handle,[poka_write],timeoutms,pollres); + if result = sye_ok then begin + {$ifdef FPC} + if connect(handle,pointer(po1),int1) <> 0 then begin + {$else} + if connect(handle,psockaddr(po1)^,int1) <> 0 then begin + {$endif} + result:= syelasterror; + end; + end; + end; + end; + end; + end; +end; + +function soc_read(const fd: longint; const buf: pointer; + const nbytes: longword; out readbytes: integer; + const timeoutms: integer): syserrorty; + //atimeoutms < 0 -> nonblocked +var + pollres: pollkindsty; +begin + result:= sye_ok; + if timeoutms >= 0 then begin + result:= soc_poll(fd,[poka_read],timeoutms,pollres); + end; + if result = sye_ok then begin + readbytes:= __read(fd,buf^,nbytes); + if readbytes <= 0 then begin + if (timeoutms < 0) then begin + if not ((sys_getlasterror = ewouldblock) or + (sys_getlasterror = eagain)) then begin + result:= syelasterror; + end + else begin + readbytes:= 0; + end; + end + else begin + result:= syelasterror; + end; + end; + end + else begin + readbytes:= -1; + end; +end; + +function soc_write(const fd: longint; buf: pointer; + nbytes: longword; out writebytes: integer; + const timeoutms: integer): syserrorty; +begin + writebytes:= sys_write(fd,buf,nbytes); + if writebytes > 0 then begin + result:= sye_ok; + end + else begin + result:= syelasterror; + end; +end; + +function soc_bind(const handle: integer; + const addr: socketaddrty): syserrorty; +var + str1: string; + po1: plocsockaddrty; + int1,int2: integer; +begin + result:= sye_ok; + with addr do begin + if kind = sok_local then begin + str1:= ansistring(tosysfilepath(url)); + int1:= sizeof(locsockaddrty)+length(str1)+1; + getmem(po1,int1); + po1^.sa_family:= af_local; + move(str1[1],po1^.sa_data,length(str1)); + pchar(@po1^.sa_data)[length(str1)]:= #0; + int2:= bind(handle,pointer(po1),int1); + if (int2 <> 0) and (sys_getlasterror = EADDRINUSE) then begin + mselibc.unlink(pchar(str1)); + int2:= bind(handle,pointer(po1),int1); + end; + if int2 <> 0 then begin + result:= syelasterror; + end; + freemem(po1); + end + else begin + with linuxsockaddrty(platformdata) do begin + {$ifdef linux} + if bind(handle,@ad,__libc_sa_len(ad.addr.sa_family)) <> 0 then begin + {$else} + if bind(handle,@ad,ad.addr.sa_len) <> 0 then begin + {$endif} + result:= syelasterror; + end; + end; + end; + end; +end; + +function soc_listen(const handle: integer; const maxconnections: integer): syserrorty; +begin + if listen(handle,maxconnections) <> 0 then begin + result:= syelasterror; + end + else begin + result:= sye_ok; + end; +end; + +function soc_accept(const handle: integer; const nonblock: boolean; out conn: integer; + out addr: socketaddrty; const timeoutms: integer): syserrorty; +var + pollres: pollkindsty; +begin + result:= soc_poll(handle,[poka_read],timeoutms,pollres); + if result = sye_ok then begin + addr.size:= sizeof(linuxsockadty); + conn:= accept(handle,@addr.platformdata,@addr.size); + if conn = -1 then begin + result:= syelasterror; + end + else begin + result:= soc_setnonblock(conn,nonblock); + end; + end; +end; + +function setsocktimeout(const handle: integer; const ms: integer; + const optname: integer): syserrorty; +var + ti: ttimeval; +begin + ti.tv_sec:= ms div 1000; + ti.tv_usec:= (ms mod 1000) * 1000; + if setsockopt(handle,sol_socket,optname,@ti,sizeof(ti)) <> 0 then begin + result:= syelasterror; + end + else begin + result:= sye_ok; + end; +end; + +function soc_setrxtimeout(const handle: integer; const ms: integer): syserrorty; +begin + result:= setsocktimeout(handle,ms,so_rcvtimeo); +end; + +function soc_settxtimeout(const handle: integer; const ms: integer): syserrorty; +begin + result:= setsocktimeout(handle,ms,so_sndtimeo); +end; + +function soc_urltoaddr(var addr: socketaddrty): syserrorty; +var + str1: string; + int1: integer; +// str2: string; +// err: integer; + info1: addrinfo; + po1: paddrinfo; +begin + result:= sye_ok; + with addr,linuxsockaddrty(platformdata) do begin + if kind = sok_local then begin + str1:= ansistring(tosysfilepath(url)); + end + else begin + str1:= ansistring(url); + end; + fillchar(info1,sizeof(addrinfo),0); + with info1 do begin + ai_socktype:= ord(sock_stream); + case kind of + sok_local: begin + ai_family:= af_local; + end; + sok_inet: begin + ai_family:= af_inet; + end; + sok_inet6: begin + ai_family:= af_inet6; + end; + end; + end; + int1:= getaddrinfo(pchar(str1),nil,@info1,@po1); + if int1 <> 0 then begin + mselasterror:= int1; + result:= sye_sockaddr; + end + else begin + with po1^ do begin + move(ai_addr^,ad,ai_addrlen); + if port <> 0 then begin + case ai_family of + af_inet: begin + ad.addr.sin_port:= htons(port); + end; + af_inet6: begin + ad.addr6.sin6_port:= htons(port); + end; + end; + end; + end; + freeaddrinfo(po1); + end; + end; +end; + +function soc_getaddr(const addr: socketaddrty): string; +begin + with linuxsockaddrty(addr.platformdata).ad do begin + case addr.sa_family of + af_inet: begin + setlength(result,sizeof(addr.sin_addr)); + move(addr.sin_addr,result[1],length(result)); + end; + af_inet6: begin + setlength(result,sizeof(addr6.sin6_addr)); + move(addr6.sin6_addr,result[1],length(result)); + end; + else begin + result:= ''; + end; + end; + end; +end; + +function soc_poll(const handle: integer; const kind: pollkindsty; + const timeoutms: longword; + out pollres: pollkindsty): syserrorty; + //0 -> no timeout + //for blocking mode +var + int1,int2: integer; + lwo1,lwo2: longword; + info: pollfd; +begin + lwo1:= 0; + pollres:= []; + fillchar(info,sizeof(info),0); + with info do begin + fd:= handle; + if poka_read in kind then begin + events:= events or pollin; + end; + if poka_write in kind then begin + events:= events or pollout; + end; + if poka_except in kind then begin + events:= events or pollpri; + end; + end; + if timeoutms > 0 then begin + lwo1:= timestampms + timeoutms; + int2:= timeoutms; + end + else begin + int2:= -1; + end; + while true do begin + int1:= poll(@info,1,int2); + if (int1 >= 0) or (sys_getlasterror <> eintr) then begin + break; + end; + if timeoutms > 0 then begin + lwo2:= lwo1 - timestampms; + if integer(lwo2) <= 0 then begin + int1:= 0; + break; + end; + int2:= lwo2; + end; + end; + if int1 < 0 then begin + result:= syelasterror; + end + else begin + if int1 = 0 then begin + result:= sye_timeout; + end + else begin + with info do begin + if revents and not pollin <> 0 then begin + include(pollres,poka_read); + end; + if revents and not pollout <> 0 then begin + include(pollres,poka_write); + end; + if revents and not pollpri <> 0 then begin + include(pollres,poka_except); + end; + end; + result:= sye_ok; + end; + end; +end; + +function soc_getport(const addr: socketaddrty): integer; +begin + with linuxsockaddrty(addr.platformdata).ad do begin + case addr.sa_family of + af_inet: begin + result:= ntohs(addr.sin_port); + end; + af_inet6: begin + result:= ntohs(addr6.sin6_port); + end; + else begin + result:= 0; + end; + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/linux/msesysintf.pas b/mseide-msegui/lib/common/kernel/linux/msesysintf.pas new file mode 100644 index 0000000..4b34a21 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/linux/msesysintf.pas @@ -0,0 +1,1450 @@ +{ MSEgui Copyright (c) 1999-2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msesysintf; //linux, freebsd +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +{$ifdef mse_debuglock} + {$define mse_debugmutex} +{$endif} +{$ifdef mse_debuggdisync} + {$define mse_debugmutex} +{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion > 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + msesys,msesystypes,msesetlocale,{$ifdef FPC}cthreads,cwstring,{$endif}msetypes, + mselibc,msectypes, + msestrings,msestream; + +var + thread1: threadty; + filenameutfoptions: utfoptionsty; + +{$ifdef msedebug} +var //!!!!todo: link with correct location + _IO_stdin: P_IO_FILE; cvar; + _IO_stdout: P_IO_FILE; cvar; + _IO_stderr: P_IO_FILE; cvar; + __malloc_initialized : longint;cvar; + h_errno : longint;cvar; +{$endif} + +{$include ../msesysintf.inc} + +function timestampms: longword; +function blocksignal(const signum: integer): boolean; + //true if blocked before +function unblocksignal(const signum: integer): boolean; + //true if blocked before + +function sigactionex(SigNum: Integer; var Action: TSigActionex; OldAction: PSigAction): Integer; + +procedure setcloexec(const fd: integer); + +implementation +uses + msesysintf1,sysutils,msesysutils,msefileutils,msearrayutils + {$ifdef FPC},dateutils{$else},DateUtils,classes_del{$endif},msedate + {$ifdef mse_debugmutex},mseapplication{$endif} + {$ifdef freebsd},msedynload{$endif}; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +function sigactionex(SigNum: Integer; var Action: TSigActionex; + OldAction: PSigAction): Integer; +begin + action.sa_flags:= action.sa_flags or SA_SIGINFO; + result:= sigaction(signum,@action,oldaction); +end; + + +(* + tstatbuf64 = packed record // Renamed due to conflict with stat64 function + st_dev: __dev_t; { Device. } + __pad1: Word; + __st_ino: __ino_t; { 32bit file serial number. } + st_mode: __mode_t; { File mode. } + st_nlink: __nlink_t; { Link count. } + st_uid: __uid_t; { User ID of the file's owner. } + st_gid: __gid_t; { Group ID of the file's group. } + st_rdev: __dev_t; { Device number, if device. } + __pad2: Word; + st_size: __off64_t; { Size of file, in bytes. } + st_blksize: __blksize_t; { Optimal block size for I/O. } + st_blocks: __blkcnt64_t; { Number 512-byte blocks allocated. } + st_atime: __time_t; { Time of last access. } + st_atime_usec: LongWord; + st_mtime: __time_t; { Time of last modification. } + st_mtime_usec: LongWord; + st_ctime: __time_t; { Time of last status change. } + st_ctime_usec: LongWord; + st_ino: __ino64_t; { File serial number. } + end; +*) + +const +// stat_ver_mse = 3; + + path_max = 1024; + filetypes: array[filetypety] of longword = (0,s_ifdir,s_ifblk, + s_ifchr,s_ifreg,s_iflnk,s_ifsock,s_ififo); +// timeoffset = 0.0; +// o_cloexec = $080000; + +type + dirstreamlinuxdty = record + dir: pdirectorystream; + dirpath: pointer; + needsstat: boolean; + needstype: boolean; + end; + {$if sizeof(dirstreamlinuxdty) > sizeof(dirstreampty)} + {$error 'buffer overflow'} + {$ifend} + dirstreamlinuxty = record + case integer of + 0: (d: dirstreamlinuxdty;); + 1: (_bufferspace: dirstreampty;); + end; + +function unblocksignal(const signum: integer): boolean; + //true if blocked before +var + set1,set2: tsigset; +begin + sigemptyset(set1); + sigaddset(set1,signum); + pthread_sigmask(sig_unblock,@set1,@set2); + result:= sigismember(set2,signum) <> 0; +end; + +function blocksignal(const signum: integer): boolean; + //true if blocked before +var + set1,set2: tsigset; +begin + sigemptyset(set1); + sigaddset(set1,signum); + pthread_sigmask(sig_block,@set1,@set2); + result:= sigismember(set2,signum) <> 0; +end; + +function sys_getpid: procidty; +begin + result:= mselibc.getpid; +end; + +function sys_terminateprocess(const proc: prochandlety): syserrorty; +begin + if (kill(proc,sigterm) = 0) or (sys_getlasterror = esrch) then begin + result:= sye_ok; + end + else begin + result:= syelasterror; + end; +end; + +function sys_killprocess(const proc: prochandlety): syserrorty; +begin + if (kill(proc,sigkill) = 0) or (sys_getlasterror = esrch) then begin + result:= sye_ok; + end + else begin + result:= syelasterror; + end; +end; + +function sys_stdin: integer; +begin + result:= stdin; +end; + +function sys_stdout: integer; +begin + result:= stdout; +end; + +function sys_stderr: integer; +begin + result:= stderr; +end; + +function sys_getprintcommand: msestring; +begin + result:= defaultprintcommand; + if result = '' then begin + result:= 'lp -'; + end; +end; + +{$ifdef freebsd} +{$packrecords c} +type + procstat = record + end; + pprocstat = ^procstat; + + pargs = record //from user.h + end; + ppargs = ^pargs; + proc = record + end; + pproc = ^proc; + user = record + end; + puser = ^user; + vnode = record + end; + pvnode = ^vnode; + filedesc = record + end; + pfiledesc = ^filedesc; + vmspace = record + end; + pvmspace = ^vmspace; + + kinfo_proc = record + ki_structsize: cint; //* size of this structure */ + ki_layout: cint; //* reserved: layout identifier */ + ki_args: ppargs; //* address of command arguments */ + ki_paddr: pproc; //* address of proc */ + ki_addr: puser; //* kernel virtual addr of u-area */ + ki_tracep: pvnode; //* pointer to trace file */ + ki_textvp: pvnode; //* pointer to executable file */ + ki_fd: pfiledesc; //* pointer to open file info */ + ki_vmspace: pvmspace; //* pointer to kernel vmspace struct */ + ki_wchan: pointer; //* sleep address */ + ki_pid: pid_t; //* Process identifier */ + ki_ppid: pid_t; //* parent process id */ + ki_pgid: pid_t; //* process group id */ + ki_tpgid: pid_t; //* tty process group id */ + ki_sid: pid_t; //* Process session ID */ + ki_tsid: pid_t; //* Terminal session ID */ + ki_jobc: cshort; //* job control counter */ + //... see below + end; + pkinfo_proc = ^kinfo_proc; +{ + short ki_spare_short1; /* unused (just here for alignment) */ + dev_t ki_tdev; /* controlling tty dev */ + sigset_t ki_siglist; /* Signals arrived but not delivered */ + sigset_t ki_sigmask; /* Current signal mask */ + sigset_t ki_sigignore; /* Signals being ignored */ + sigset_t ki_sigcatch; /* Signals being caught by user */ + uid_t ki_uid; /* effective user id */ + uid_t ki_ruid; /* Real user id */ + uid_t ki_svuid; /* Saved effective user id */ + gid_t ki_rgid; /* Real group id */ + gid_t ki_svgid; /* Saved effective group id */ + short ki_ngroups; /* number of groups */ + short ki_spare_short2; /* unused (just here for alignment) */ + gid_t ki_groups[KI_NGROUPS]; /* groups */ + vm_size_t ki_size; /* virtual size */ + segsz_t ki_rssize; /* current resident set size in pages */ + segsz_t ki_swrss; /* resident set size before last swap */ + segsz_t ki_tsize; /* text size (pages) XXX */ + segsz_t ki_dsize; /* data size (pages) XXX */ + segsz_t ki_ssize; /* stack size (pages) */ + u_short ki_xstat; /* Exit status for wait & stop signal */ + u_short ki_acflag; /* Accounting flags */ + fixpt_t ki_pctcpu; /* %cpu for process during ki_swtime */ + u_int ki_estcpu; /* Time averaged value of ki_cpticks */ + u_int ki_slptime; /* Time since last blocked */ + u_int ki_swtime; /* Time swapped in or out */ + u_int ki_cow; /* number of copy-on-write faults */ + u_int64_t ki_runtime; /* Real time in microsec */ + struct timeval ki_start; /* starting time */ + struct timeval ki_childtime; /* time used by process children */ + long ki_flag; /* P_* flags */ + long ki_kiflag; /* KI_* flags (below) */ + int ki_traceflag; /* Kernel trace points */ + char ki_stat; /* S* process status */ + signed char ki_nice; /* Process "nice" value */ + char ki_lock; /* Process lock (prevent swap) count */ + char ki_rqindex; /* Run queue index */ + u_char ki_oncpu; /* Which cpu we are on */ + u_char ki_lastcpu; /* Last cpu we were on */ + char ki_tdname[TDNAMLEN+1]; /* thread name */ + char ki_wmesg[WMESGLEN+1]; /* wchan message */ + char ki_login[LOGNAMELEN+1]; /* setlogin name */ + char ki_lockname[LOCKNAMELEN+1]; /* lock name */ + char ki_comm[COMMLEN+1]; /* command name */ + char ki_emul[KI_EMULNAMELEN+1]; /* emulation name */ + char ki_loginclass[LOGINCLASSLEN+1]; /* login class */ + /* + * When adding new variables, take space for char-strings from the + * front of ki_sparestrings, and ints from the end of ki_spareints. + * That way the spare room from both arrays will remain contiguous. + */ + char ki_sparestrings[50]; /* spare string space */ + int ki_spareints[KI_NSPARE_INT]; /* spare room for growth */ + int ki_flag2; /* P2_* flags */ + int ki_fibnum; /* Default FIB number */ + u_int ki_cr_flags; /* Credential flags */ + int ki_jid; /* Process jail ID */ + int ki_numthreads; /* XXXKSE number of threads in total */ + lwpid_t ki_tid; /* XXXKSE thread id */ + struct priority ki_pri; /* process priority */ + struct rusage ki_rusage; /* process rusage statistics */ + /* XXX - most fields in ki_rusage_ch are not (yet) filled in */ + struct rusage ki_rusage_ch; /* rusage of children processes */ + struct pcb *ki_pcb; /* kernel virtual addr of pcb */ + void *ki_kstack; /* kernel virtual addr of stack */ + void *ki_udata; /* User convenience pointer */ + struct thread *ki_tdaddr; /* address of thread */ + /* + * When adding new variables, take space for pointers from the + * front of ki_spareptrs, and longs from the end of ki_sparelongs. + * That way the spare room from both arrays will remain contiguous. + */ + void *ki_spareptrs[KI_NSPARE_PTR]; /* spare room for growth */ + long ki_sparelongs[KI_NSPARE_LONG]; /* spare room for growth */ + long ki_sflag; /* PS_* flags */ + long ki_tdflags; /* XXXKSE kthread flag */ +} +const +///* +// * KERN_PROC subtypes +// */ + KERN_PROC_ALL = 0; //* everything */ + KERN_PROC_PID = 1; //* by process id */ + KERN_PROC_PGRP = 2; //* by process group id */ + KERN_PROC_SESSION = 3; //* by session of pid */ + KERN_PROC_TTY = 4; //* by controlling tty */ + KERN_PROC_UID = 5; //* by effective uid */ + KERN_PROC_RUID = 6; //* by real uid */ + KERN_PROC_ARGS = 7; //* get/set arguments/proctitle */ + KERN_PROC_PROC = 8; //* only return procs */ + KERN_PROC_SV_NAME = 9; //* get syscall vector name */ + KERN_PROC_RGID = 10; //* by real group id */ + KERN_PROC_GID = 11; //* by effective group id */ + KERN_PROC_PATHNAME = 12; //* path to executable */ + KERN_PROC_OVMMAP = 13; //* Old VM map entries for process */ + KERN_PROC_OFILEDESC = 14; //* Old file descriptors for process */ + KERN_PROC_KSTACK = 15; //* Kernel stacks for process */ + KERN_PROC_INC_THREAD = $10; //* +// * modifier for pid, pgrp, tty, +// * uid, ruid, gid, rgid and proc +// * This effectively uses 16-31 +// */ + KERN_PROC_VMMAP = 32; //* VM map entries for process */ + KERN_PROC_FILEDESC = 33; //* File descriptors for process */ + KERN_PROC_GROUPS = 34; //* process groups */ + KERN_PROC_ENV = 35; //* get environment */ + KERN_PROC_AUXV = 36; //* get ELF auxiliary vector */ + KERN_PROC_RLIMIT = 37; //* process resource limits */ + KERN_PROC_PS_STRINGS = 38; //* get ps_strings location */ + KERN_PROC_UMASK = 39; //* process umask */ + KERN_PROC_OSREL = 40; //* osreldate for process binary */ + KERN_PROC_SIGTRAMP = 41; //* signal trampoline location */ + +var + haslibprocstat: boolean; + procstat_open_sysctl: function(): pprocstat; cdecl; + procstat_close: procedure(procstat: pprocstat); cdecl; + procstat_getprocs: function(procstat: pprocstat; what: cint; arg: cint; + count: pcuint): pkinfo_proc; cdecl; + procstat_freeprocs: procedure(procstat: pprocstat; p: pkinfo_proc); cdecl; + +function sys_getprocesses: procitemarty; +var + stat: pprocstat; + proc,po1: pkinfo_proc; + ca1: cuint; +begin + result:= nil; + if haslibprocstat then begin + stat:= procstat_open_sysctl(); + if stat <> nil then begin + proc:= procstat_getprocs(stat,KERN_PROC_PROC,0,@ca1); + if proc <> nil then begin + setlength(result,ca1); + po1:= proc; + for ca1:= 0 to high(result) do begin + result[ca1].pid:= po1^.ki_pid; + result[ca1].ppid:= po1^.ki_ppid; + inc(pointer(po1),po1^.ki_structsize); + end; + procstat_freeprocs(stat,proc); + end; + procstat_close(stat); + end; + end; +end; + +{$else} +function sys_getprocesses: procitemarty; +var + filelist: tfiledatalist; + int1,int2: integer; + stream: ttextstream; + str1: string; +begin + filelist:= tfiledatalist.create(); + filelist.adddirectory('/proc',fil_name,nil,[fa_dir]); + setlength(result,filelist.count); + int2:= 0; + for int1:= 0 to filelist.count - 1 do begin + with filelist[int1] do begin + if (name[1] >= '0') and (name[1] <= '9') then begin + if ttextstream.trycreate(stream,'/proc/'+name+'/stat',fm_read) = + sye_ok then begin + stream.readln(str1); + with result[int2] do begin + if mselibc.sscanf(pchar(str1),'%d (%*a[^)]) %*c %d', +// {$ifdef FPC}[{$endif}@pid,@ppid{$ifdef FPC}]{$endif}) = 2 then begin + [@pid,@ppid]) = 2 then begin + inc(int2); + end; + end; + stream.free; + end; + end; + end; + end; + filelist.free; + setlength(result,int2); +end; +{$endif} + +procedure sys_schedyield; +begin + sched_yield; +end; + +procedure sys_usleep(const us: longword); +begin + if us = 0 then begin + sched_yield; + end + else begin + mselibc.usleep(us); + end; +end; + +function sys_filesystemiscaseinsensitive: boolean; +begin + result:= false; +end; + +function sys_getapplicationpath: filenamety; +begin + result:= filenamety(paramstr(0)); +end; + +function sys_getcommandlinearguments: msestringarty; +var + av: pcharpoaty; + ac: pinteger; + int1: integer; +begin + ac:= {$ifdef FPC}@argc{$else}@argcount{$endif}; + av:= pcharpoaty({$ifdef FPC}argv{$else}argvalues{$endif}); + setlength(result,ac^); + for int1:= 0 to ac^-1 do begin + result[int1]:= av^[int1]; + end; +end; + +procedure sys_getenvvars(out names: msestringarty; out values: msestringarty); +var + str1: string; + po1: ppchar; + po2,po3,po4: pchar; +begin + po1:= environ; + if po1 <> nil then begin + while true do begin + po2:= po1^; + if po2 = nil then begin + break; + end; + po3:= po2; + while po3^ <> #0 do begin + inc(po3); + end; + po4:= po2; + while (po4^ <> '=') and (po4 < po3) do begin + inc(po4); + end; + str1:= psubstr(po2,po4); + additem(names,msestring(str1)); + str1:= psubstr(po4+1,po3); + additem(values,msestring(str1)); + inc(po1); + end; + end; +end; + +function sys_getenv(const aname: msestring; out avalue: msestring): boolean; + //true if found +var + po1: pchar; + str1: ansistring; +begin + avalue:= ''; + po1:= getenv(pchar(ansistring(aname))); + result:= po1 <> nil; + if result then begin + str1:= po1; + avalue:= msestring(str1); + end; +end; + +function sys_setenv(const aname: msestring; const avalue: msestring): syserrorty; +begin + result:= sye_ok; + if setenv(pchar(ansistring(aname)),pchar(ansistring(avalue)),1) <> 0 then begin + result:= syelasterror; + end; +end; + +function sys_unsetenv(const aname: msestring): syserrorty; +begin + result:= sye_ok; + if unsetenv(pchar(ansistring(aname))) <> 0 then begin + result:= syelasterror; + end; +end; + +function timestampms: longword; +var + t1: timeval; +begin + gettimeofday(@t1,ptimezone(nil)); + result:= t1.tv_sec * 1000 + t1.tv_usec div 1000; +end; + +var + lastlocaltime: integer; + gmtoff: real; + +function sys_localtimeoffset: tdatetime; +var + tm: tunixtime; + int1: integer; +begin + int1:= __time(nil); + if int1 <> lastlocaltime then begin + lastlocaltime:= int1; + localtime_r(@int1,@tm); + gmtoff:= tm.__tm_gmtoff / (24.0*60.0*60.0); + end; + result:= gmtoff; +end; + +function sys_getutctime: tdatetime; +var + ti: timeval; +begin + gettimeofday(@ti,nil); +{$ifdef FPC} + result:= ti.tv_sec / (double(24.0)*60.0*60.0) + + ti.tv_usec / (double(24.0)*60.0*60.0*1e6) - unidatetimeoffset; +{$else} + result:= ti.tv_sec / (24.0*60.0*60.0) + + ti.tv_usec / (24.0*60.0*60.0*1e6) - unidatetimeoffset; +{$endif} +end; + +function sys_getlocaltime: tdatetime; +var + ti: timeval; +begin + gettimeofday(@ti,nil); +{$ifdef FPC} + result:= ti.tv_sec / (double(24.0)*60.0*60.0) + + ti.tv_usec / (double(24.0)*60.0*60.0*1e6) - unidatetimeoffset; +{$else} + result:= ti.tv_sec / (24.0*60.0*60.0) + + ti.tv_usec / (24.0*60.0*60.0*1e6) - unidatetimeoffset; +{$endif} + if ti.tv_sec = lastlocaltime then begin + result:= result + gmtoff; + end + else begin + result:= result + sys_localtimeoffset; + end; +end; + +function sys_tosysfilepath(var path: msestring): syserrorty; +begin + result:= sye_ok; +end; + +const + openmodes: array[fileopenmodety] of longword = +// fm_none,fm_read, fm_write,fm_readwrite,fm_create, + (0, o_rdonly,o_wronly,o_rdwr, o_rdwr or o_creat or o_trunc, +// fm_append + o_rdwr or o_creat {or o_trunc}); + +function getfilerights(const rights: filerightsty): longword; +const + filerights: array[filerightty] of longword = + (mselibc.s_irusr,mselibc.s_iwusr,mselibc.s_ixusr, + mselibc.s_irgrp,mselibc.s_iwgrp,mselibc.s_ixgrp, + mselibc.s_iroth,mselibc.s_iwoth,mselibc.s_ixoth, + mselibc.s_isuid,mselibc.s_isgid,mselibc.s_isvtx); +var + fr: filerightty; +begin + result:= 0; + for fr:= low(filerightty) to high(filerightty) do begin + if fr in rights then begin + result:= result or filerights[fr]; + end; + end; +end; + +function tosys(const avalue: filenamety): string; +begin + if filenameutfoptions <> [] then begin + result:= stringtoutf8(avalue,filenameutfoptions); + end + else begin + result:= ansistring(avalue); + end; +end; + +function fromsys(const avalue: string): filenamety; +begin + if filenameutfoptions <> [] then begin + result:= utf8tostringansi(avalue,filenameutfoptions); + end + else begin + result:= filenamety(avalue); + end; +end; + +function sys_createdir(const path: msestring; const rights: filerightsty): syserrorty; +var + str1: string; +begin + str1:= tosys(path); + if mselibc.__mkdir(pchar(str1), + getfilerights(rights)) <> 0 then begin +// result:= sye_createdir; + result:= syelasterror; + end + else begin + result:= sye_ok; + end; +end; + +procedure setcloexec(const fd: integer); +var + flags: integer; +begin + flags:= fcntl(fd,f_getfd); + if flags <> -1 then begin + flags:= flags or fd_cloexec; + fcntl(fd,f_setfd,[flags]) + end; +end; + +function sys_openfile(const path: filenamety; const openmode: fileopenmodety; + const accessmode: fileaccessmodesty; + const rights: filerightsty; out handle: integer): syserrorty; +var + str1: string; + str2: msestring; + stat1: _stat; +const + defaultopenflags = o_cloexec; +begin + str2:= path; + sys_tosysfilepath(str2); + str1:= tosys(str2); + handle:= Integer(mselibc.open(PChar(str1), openmodes[openmode] or + defaultopenflags,[getfilerights(rights)])); + if handle >= 0 then begin + if fstat(handle,@stat1) = 0 then begin + if s_isdir(stat1.st_mode) then begin + mselibc.__close(handle); + handle:= -1; + result:= sye_isdir; + end + else begin + setcloexec(handle); + result:= sye_ok; + end; + end + else begin + mselibc.__close(handle); + handle:= -1; + result:= syelasterror; + end; + end + else begin + result:= syelasterror; + end; +end; + +function sys_closefile(const handle: integer): syserrorty; +var + int1: cint; +begin + result:= sye_ok; + if (handle <> invalidfilehandle) then begin + repeat + int1:= mselibc.__close(handle); + until (int1 = 0) or (sys_getlasterror <> EINTR); + if int1 <> 0 then begin + result:= syelasterror; + end; + end; +end; + +function sys_flushfile(const handle: integer): syserrorty; +begin + result:= sye_ok; + while mselibc.fsync(handle) <> 0 do begin + if sys_getlasterror <> eintr then begin + result:= syelasterror; + break; + end; + end; +end; + +function sys_dup(const source: integer; out dest: integer): syserrorty; +begin + dest:= dup(source); + if dest = -1 then begin + result:= syelasterror; + end + else begin + result:= sye_ok; + end; +end; + +function sys_truncatefile(const handle: integer; const size: int64): syserrorty; +begin + result:= sye_ok; + while mselibc.ftruncate64(handle,size) <> 0 do begin + if sys_getlasterror <> eintr then begin + result:= syelasterror; + break; + end; + end; +end; + +function sys_read(fd: longint; buf: pointer; nbytes: dword): integer; +begin + repeat + result:= mselibc.__read(fd,buf^,nbytes); + until (result >= 0) or (sys_getlasterror <> eintr); + if (result < 0) and (sys_getlasterror = EAGAIN) then begin + result:= 0; //nonblock + end; +end; + +function sys_write(fd:longint; buf: pointer; nbytes: longword): integer; +var + int1: integer; +begin + result:= nbytes; + repeat + int1:= mselibc.__write(fd,buf^,nbytes); + if int1 = -1 then begin + if sys_getlasterror <> eintr then begin + result:= int1; + break; + end; + continue; + end; + inc(pchar(buf),int1); + dec(nbytes,int1); + until integer(nbytes) <= 0; +end; + +function sys_errorout(const atext: string): syserrorty; +begin + if (length(atext) = 0) or + (mselibc.__write(2, + pchar(atext)^,length(atext)) = length(atext)) then begin + result:= sye_ok; + end + else begin + result:= syelasterror; + end; +end; + +{$R-} +function sys_gettimeus: longword; +var + time1: timeval; + time2: timespec; +begin + if ({$ifndef FPC}@{$endif}clock_gettime = nil) or + (clock_gettime(clock_monotonic,@time2) <> 0) then begin + gettimeofday(@time1,ptimezone(nil)); + result:= time1.tv_sec * 1000000 + time1.tv_usec; + end + else begin + result:= time2.tv_sec * 1000000 + time2.tv_nsec div 1000; + end; +end; + +{$ifdef FPC} + +function threadexec(infopo : pointer) : ptrint{longint}; +begin + threadinfoty(infopo^).id:= threadty(getcurrentthreadid); + pthread_setcanceltype(pthread_cancel_asynchronous,nil); + pthread_setcancelstate(pthread_cancel_enable,nil); + unblocksignal(sigio); + result:= threadinfoty(infopo^).threadproc(); +end; + +{$else} + +function threadexec(infopo: pointer): integer; cdecl; +begin + threadinfoty(infopo^).id:= threadty(getcurrentthreadid); + pthread_setcanceltype(pthread_cancel_asynchronous,nil); + pthread_setcancelstate(pthread_cancel_enable,nil); + result:= threadinfoty(infopo^).threadproc(); +end; + +{$endif} + +function sys_issamethread(const a,b: threadty): boolean; +begin + result:= pthread_equal(a,b) <> 0; +end; + +function sys_threadcreate(var info: threadinfoty): syserrorty; +var +{$ifndef FPC} + attr: pthread_attr_t; +{$else} + id1: threadty; +{$endif} + sigs1,sigs2: __sigset_t; +begin + {$ifdef FPC} + with info do begin + sigfillset(sigs1); //block all + pthread_sigmask(sig_block,@sigs1,@sigs2); + id:= 0; + id:= threadty(beginthread(@threadexec,@info,tthreadid(id1),info.stacksize)); + pthread_sigmask(sig_setmask,@sigs2,nil); //restore + if id = 0 then begin + result:= sye_thread; + end + else begin + result:= sye_ok; + end; + end; + {$else} + with info do begin + ismultithread:= true; + pthread_attr_init(attr); + if pthread_create(ppthread_t(@id), + @attr,{$ifdef FPC}@{$endif}threadexec,@info) <> 0 then begin + result:= sye_thread; + end + else begin + result:= sye_ok; + end; + end; + {$endif} +end; + +function sys_threadwaitfor(var info: threadinfoty): syserrorty; +begin +{$ifdef FPC} + waitforthreadterminate(tthreadid(info.id),0); + result:= sye_ok; +{$else} + result:= syeseterror(pthread_join(info.id,nil)); +{$endif} +end; + +function sys_threaddestroy(var info: threadinfoty): syserrorty; +begin + result:= sye_ok; +{$ifdef FPC} + killthread(tthreadid(info.id)); +{$else} + pthread_detach(info.id); + pthread_cancel(info.id); +{$endif} +end; + +function sys_threadschedyield: syserrorty; +begin + result:= sye_ok; + sched_yield; +end; + +function sys_getcurrentthread: threadty; +begin + result:= pthread_self; +end; + +function sys_copyfile(const oldfile,newfile: msestring): syserrorty; +const + bufsize = $2000; //8k +var + str1,str2: string; + source,dest: integer; + stat: _stat64; + lwo1: longword; + po1: pointer; +begin + str1:= tosys(oldfile); + str2:= tosys(newfile); + result:= sye_copyfile; + source:= mselibc.open(pchar(str1),o_rdonly); + if source <> -1 then begin + if fstat64(source,@stat) = 0 then begin + dest:= mselibc.open(pchar(str2),o_rdwr or o_creat or o_trunc, + [s_irusr or s_iwusr]); + if dest <> -1 then begin + getmem(po1,bufsize); + lwo1:= 0; //compiler warning + while true do begin + lwo1:= mselibc.__read(source,po1^,bufsize); + if (lwo1 = 0) or (lwo1 = longword(-1)) then begin + break; + end; + if mselibc.__write(dest,po1^,lwo1) <> integer(lwo1) then begin + break; + end; + end; + freemem(po1); + if lwo1 = 0 then begin + if mselibc.fchmod(dest,stat.st_mode) = 0 then begin + result:= sye_ok; + end + else begin + result:= syelasterror; + end; + end + else begin + result:= syelasterror; + end; + mselibc.__close(dest); + end + else begin + result:= syelasterror; + end; + end + else begin + result:= syelasterror; + end; + mselibc.__close(source); + end + else begin + result:= syelasterror; + end; +end; + +function sys_renamefile(const oldname,newname: filenamety): syserrorty; +var + str1,str2: string; +begin + str1:= tosys(oldname); + str2:= tosys(newname); + if mselibc.__rename(pchar(str1),pchar(str2)) = -1 then begin + result:= syelasterror; + end + else begin + result:= sye_ok; + end; +end; + +function sys_deletefile(const filename: filenamety): syserrorty; +var + str1: string; +begin + str1:= tosys(filename); + if mselibc.unlink(pchar(str1)) = -1 then begin + result:= syelasterror; + end + else begin + result:= sye_ok; + end; +end; + +function sys_deletedir(const filename: filenamety): syserrorty; +var + str1: string; +begin + str1:= tosys(filename); + if mselibc.rmdir(pchar(str1)) = -1 then begin + result:= syelasterror; + end + else begin + result:= sye_ok; + end; +end; + +function getfiletype(value: longword): filetypety; +var + count: filetypety; +begin + result:= ft_unknown; + value:= value and s_ifmt; + for count:= low(filetypety) to high(filetypety) do begin + if value = filetypes[count] then begin + result:= count; + break; + end; + end; +end; + +function getfileattributes(value: __mode_t): fileattributesty; +begin + result:= []; + + if value and s_irusr <> 0 then include(result,fa_rusr); + if value and s_iwusr <> 0 then include(result,fa_wusr); + if value and s_ixusr <> 0 then include(result,fa_xusr); + + if value and s_irgrp <> 0 then include(result,fa_rgrp); + if value and s_iwgrp <> 0 then include(result,fa_wgrp); + if value and s_ixgrp <> 0 then include(result,fa_xgrp); + + if value and s_iroth <> 0 then include(result,fa_roth); + if value and s_iwoth <> 0 then include(result,fa_woth); + if value and s_ixoth <> 0 then include(result,fa_xoth); + + if value and s_isuid <> 0 then include(result,fa_suid); + if value and s_isgid <> 0 then include(result,fa_sgid); + if value and s_isvtx <> 0 then include(result,fa_svtx); + +end; + +function getmodebits(const value: fileattributesty): __mode_t; +begin + result:= 0; + + if fa_rusr in value then result:= result or s_irusr; + if fa_wusr in value then result:= result or s_iwusr; + if fa_xusr in value then result:= result or s_ixusr; + + if fa_rgrp in value then result:= result or s_irgrp; + if fa_wgrp in value then result:= result or s_iwgrp; + if fa_xgrp in value then result:= result or s_ixgrp; + + if fa_roth in value then result:= result or s_iroth; + if fa_woth in value then result:= result or s_iwoth; + if fa_xoth in value then result:= result or s_ixoth; + + if fa_suid in value then result:= result or s_isuid; + if fa_sgid in value then result:= result or s_isgid; + if fa_svtx in value then result:= result or s_isvtx; + +end; + +function getaccessbits(const value: accessmodesty): cint; +begin + result:= 0; + if am_read in value then result:= result or r_ok; + if am_write in value then result:= result or w_ok; + if am_execute in value then result:= result or x_ok; + if am_exist in value then result:= result or f_ok; +end; + +function filetimetodatetime(const value: timespec): tdatetime; +begin + result:= value.tv_sec / (double(24.0)*60.0*60.0) + + value.tv_nsec / (double(24.0)*60.0*60.0*1e9) - unidatetimeoffset; +end; + +function filetimetodatetime(const sec,nsec: culong): tdatetime; +begin + result:= sec / (double(24.0)*60.0*60.0) + + nsec / (double(24.0)*60.0*60.0*1e9) - unidatetimeoffset; +end; + +function sys_getcurrentdir: msestring; +var + str1: string; + po1: pchar; +begin + str1:= ''; + repeat + setlength(str1,length(str1) + path_max); + po1:= getcwd(@str1[1],length(str1)); + until (po1 <> nil) or (sys_getlasterror() <> erange); + setlength(str1,strlen(po1)); + result:= msestring(str1); +end; + +function sys_getuserhomedir: filenamety; +var + po1: pchar; +begin + po1:= getenv('HOME'); + if po1 <> nil then begin + result:= filenamety(string(po1)); + end + else begin + result:= ''; + end; +end; + +function sys_getusername: msestring; +var + po1: pchar; + s1: string; + pwd: passwd; + res: ppasswd; + i1: cint; +begin + result:= ''; + if getpwuid_r <> nil then begin + setlength(s1,10000); + while true do begin + i1:= getpwuid_r(getuid(),@pwd,pointer(s1),length(s1),@res); + case i1 of + 0: begin + if res <> nil then begin + result:= msestring(ansistring(pwd.pw_name)); + end; + break; + end; + eintr: begin + //try again + end; + erange: begin + setlength(s1,length(s1)*2); + end; + else begin + break; //error + end; + end; + end; + end + else begin + if cuserid <> nil then begin + po1:= cuserid(nil); + result:= msestring(ansistring(po1)); + end; + end; +end; + +function sys_getapphomedir: filenamety; +begin + result:= sys_getuserhomedir; +end; + +function sys_gettempdir: filenamety; +var + str1: string; +begin + str1:= getenvironmentvariable('temp'); + if str1 = '' then begin + str1:= getenvironmentvariable('tmp'); + end; + if str1 = '' then begin + str1:= '/tmp/' + end; + str1:= includetrailingpathdelimiter(str1); + result:= tomsefilepath(filenamety(str1)); +end; + +function sys_setcurrentdir(const dirname: filenamety): syserrorty; +var + str1: string; +begin + str1:= tosys(dirname); + if mselibc.__chdir(pchar(str1)) = 0 then begin + result:= sye_ok; + end + else begin + result:= syelasterror; + end; +end; + +const + nameattributes = [fa_hidden]; + typeattributes = nameattributes + [fa_dir]; + +function sys_opendirstream(var stream: dirstreamty): syserrorty; +var + str1: string; +begin + checkdirstreamdata(stream); + str1:= tosys(stream.dirinfo.dirname); + with stream,dirinfo,dirstreamlinuxty(platformdata) do begin +{$ifdef FPC} + d.dir:= pdir(opendir(pchar(str1))); +{$else} + pointer(d.dir):= pdir(opendir(pchar(str1))); +{$endif} + if d.dir = nil then begin + result:= syelasterror; + end + else begin + if (str1 <> '') and (str1[length(str1)] <> '/') then begin + str1:= str1 + '/'; + end; + string(d.dirpath):= str1; //for stat + d.needsstat:= (infolevel >= fil_ext1) or + not (fa_all in include) and (include-typeattributes <> []) or + (exclude-typeattributes <> []); + d.needstype:= not d.needsstat and + ((infolevel >= fil_type) or + not (fa_all in include) and (include-nameattributes <> []) or + (exclude-nameattributes <> [])); + result:= sye_ok; + end; + end; +end; + +function sys_closedirstream(var stream: dirstreamty): syserrorty; +begin + with dirstreamlinuxty(stream.platformdata) do begin + string(d.dirpath):= ''; + if closedir(pointer(d.dir)) = 0 then begin + result:= sye_ok; + end + else begin + result:= sye_dirstream; + end; + end; +end; + +function sys_readdirstream(var stream: dirstreamty; var info: fileinfoty): boolean; + //true if valid +var + dirent: dirent64; + po1: pdirent64; + statbuffer: _stat64; + //stat1: tstatbuf; + str1: string; + error: boolean; +begin + result:= false; + po1:= nil; + with stream,dirinfo,dirstreamlinuxty(platformdata) do begin + if not ((include <> []) and (fa_all in exclude)) then begin + while true do begin + if (readdir64_r(pdir(d.dir),@dirent,@po1) = 0) and + (po1 <> nil) then begin + with info do begin + str1:= dirent.d_name; + name:= fromsys(str1); + if checkfilename(info.name,stream) then begin + if d.needsstat or d.needstype and + ((dirent.d_type = dt_unknown) or (dirent.d_type = dt_lnk)) then begin + error:= stat64(pchar(string(d.dirpath)+str1),@statbuffer) <> 0; + end + else begin + error:= false; + statbuffer.st_mode:= dirent.d_type shl 12; + end; + with extinfo1,extinfo2,statbuffer do begin + if not error then begin + filetype:= getfiletype(st_mode); + attributes:= getfileattributes(st_mode); + if (length(name) > 0) and (info.name[1] = '.') then begin + system.include(attributes,fa_hidden); + end; + if filetype = ft_dir then begin + system.include(attributes,fa_dir); + end; + if ((fa_all in include) or (attributes * include <> [])) and + ((attributes * exclude) = []) then begin + if d.needstype then begin + system.include(state,fis_typevalid); + end; + if d.needsstat then begin + state:= state + [fis_typevalid,fis_extinfo1valid,fis_extinfo2valid]; + size:= st_size; + modtime:= filetimetodatetime(st_mtime,st_mtime_nsec); + accesstime:= filetimetodatetime(st_atime,st_atime_nsec); + ctime:= filetimetodatetime(st_ctime,st_ctime_nsec); + id:= st_ino; + owner:= st_uid; + group:= st_gid; + end; + result:= true; + break; + end; + end; + end; + end; + end; + end + else begin + break; + end; + end; + end; + end; +end; + +procedure stattofileinfo(const statbuffer: _stat64; var info: fileinfoty); +begin + with info,extinfo1,extinfo2,statbuffer do begin + filetype:= getfiletype(st_mode); + attributes:= getfileattributes(st_mode); + if (length(name) > 0) and (info.name[1] = '.') then begin + system.include(attributes,fa_hidden); + end; + if filetype = ft_dir then begin + system.include(attributes,fa_dir); + end; + state:= state + [fis_typevalid,fis_extinfo1valid,fis_extinfo2valid]; + size:= st_size; + modtime:= filetimetodatetime(st_mtime,st_mtime_nsec); + accesstime:= filetimetodatetime(st_atime,st_atime_nsec); + ctime:= filetimetodatetime(st_ctime,st_ctime_nsec); + id:= st_ino; + owner:= st_uid; + group:= st_gid; + end; +end; + +function sys_getfileinfo(const path: filenamety; var info: fileinfoty): boolean; +var + str1: filenamety; + statbuffer: _stat64; +begin + clearfileinfo(info); + str1:= tosysfilepath(path); + fillchar(statbuffer,sizeof(statbuffer),0); + result:= stat64(pchar(tosys(str1)),@statbuffer) = 0; + if result then begin + stattofileinfo(statbuffer,info); + splitfilepath(filepath(path),str1,info.name); + end; +end; + +function sys_getfdinfo(const fd: longint; var info: fileinfoty): boolean; +var + statbuffer: _stat64; +begin + clearfileinfo(info); + fillchar(statbuffer,sizeof(statbuffer),0); + result:= fstat64(fd,@statbuffer) = 0; + if result then begin + stattofileinfo(statbuffer,info); + end; +end; + +function sys_access(const path: filenamety; + const accessmodes: accessmodesty): syserrorty; +var + str1: filenamety; +begin + str1:= tosysfilepath(path); + if mselibc.access(pchar(string(str1)), + getaccessbits(accessmodes)) = 0 then begin + result:= sye_ok; + end + else begin + result:= syelasterror(); + end; +end; + +function sys_setfilerights(const path: filenamety; + const rights: filerightsty): syserrorty; +var + str1: filenamety; +begin + str1:= tosysfilepath(path); + if chmod(pchar(tosys(str1)), + getmodebits(fileattributesty(rights))) = 0 then begin + result:= sye_ok; + end + else begin + result:= syelasterror(); + end; +end; + +function sys_setfdrights(const fd: longint; + const rights: filerightsty; + const filename: filenamety = ''): syserrorty; +begin + if fchmod(fd,getmodebits(fileattributesty(rights))) = 0 then begin + result:= sye_ok; + end + else begin + result:= syelasterror(); + end; +end; + +function sys_getlangname: string; +var + po1: pchar; + ar1: stringarty; +begin + po1:= setlocale(lc_messages,nil); + ar1:= splitstring(string(po1),'_'); + if high(ar1) >= 0 then begin + result:= ar1[0]; + end + else begin + result:= string(po1); + end; +end; + +procedure sigtest(SigNum: Integer); cdecl; +begin +end; + +procedure sigdummy(SigNum: Integer); cdecl; +begin +end; + +procedure setsighandlers; +var + info: tsigaction; +begin + fillchar(info,sizeof(info),0); + with info do begin + {$ifdef FPC} + sa_handler:= @sigdummy; + {$else} + __sigaction_handler:= @sigdummy; + {$endif} + sa_flags:= sa_restart; + end; + sigaction(sigio,@info,nil); +end; + +{$ifdef freebsd} +procedure initfreebsd(); +begin + haslibprocstat:= checkprocaddresses(['libprocstat.so.1','libprocstat.so'], + ['procstat_open_sysctl','procstat_close','procstat_getprocs', + 'procstat_freeprocs'], + [@procstat_open_sysctl,@procstat_close,@procstat_getprocs, + @procstat_freeprocs]); +end; +{$endif} + +initialization + setsighandlers; +{$ifdef freebsd} + initfreebsd(); +{$endif} +end. diff --git a/mseide-msegui/lib/common/kernel/linux/msesysintf1.pas b/mseide-msegui/lib/common/kernel/linux/msesysintf1.pas new file mode 100644 index 0000000..55469e2 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/linux/msesysintf1.pas @@ -0,0 +1,432 @@ +{ MSEgui Copyright (c) 1999-2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msesysintf1; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msesystypes,mselibc,sysutils; +type + linuxmutexty = record + case integer of + 0: (mutex: pthread_mutex_t;); + 1: (_bufferspace: mutexty;); + end; + linuxconddty = record + cond: tcondvar; + mutex: pthread_mutex_t; + end; + linuxcondty = record + case integer of + 0: (d: linuxconddty;); + 1: (_bufferspace: condty;); + end; + + linuxsemdty = record + destroyed: integer; + sema: tsemaphore; + end; + linuxsemty = record + case integer of + 0: (d: linuxsemdty;); + 1: (_bufferspace: semty;); + end; + +{$ifdef FPC} + {$include ../msesysintf1.inc} +{$else} + {$include msesysintf1.inc} +{$endif} + +function unigettimestamp(timeoutusec: integer): timespec; +procedure initmutex(out mutex: pthread_mutex_t); + +{$ifdef mse_debuggdisync} + {$define mse_debugmutex} +{$endif} +{$ifdef mse_debugmutex} +var + mutexsequ: integer; + mutexcount: integer; + appmutexcount: integer; + appmutexlockth: threadty; + appmutexlockc: integer; + appmutexlocks: integer; + appmutexunlockth: threadty; + appmutexunlockc: integer; + appmutexunlocks: integer; +{$endif} + +implementation + +uses + dateutils {$ifdef mse_debugmutex},mseapplication,msesysintf{$endif} + (*,msedate *); + +const + unidatetimeoffset = -25569; + +function unigettimestamp(timeoutusec: integer): timespec; +var + ti: timeval; +begin + gettimeofday(@ti,nil); + ti.tv_usec:= ti.tv_usec + timeoutusec; + result.tv_sec:= ti.tv_sec + integer(longword(ti.tv_usec) div 1000000); + result.tv_nsec:= (longword(ti.tv_usec) mod 1000000) * 1000; +end; + +function sys_getlasterror: Integer; +begin + {$ifdef FPC}{$checkpointer off}{$endif} + Result := __errno_location()^; + {$ifdef FPC}{$checkpointer default}{$endif} +end; + +procedure sys_setlasterror(const avalue: integer); +begin + {$ifdef FPC}{$checkpointer off}{$endif} + __errno_location()^:= avalue; + {$ifdef FPC}{$checkpointer default}{$endif} +end; + +function sys_geterrortext(aerror: integer): string; +const + buflen = 1024; +var + buffer: array[0..buflen] of char; + po1: pchar; +begin + result:= ''; //compilerwarning + po1:= strerror_r(aerror,pchar(@buffer),buflen); + setstring(result,po1,strlen(po1)); +end; + +procedure initmutex(out mutex: pthread_mutex_t); +var + attr: tmutexattribute; +begin + pthread_mutexattr_init(attr); + pthread_mutexattr_settype(attr,recursive); +// attr.__mutexkind:= recursive; + pthread_mutex_init(@mutex,@attr); + pthread_mutexattr_destroy(attr); +end; + +procedure destroymutex(var mutex: pthread_mutex_t); +begin + while pthread_mutex_destroy(mutex) = ebusy do begin + pthread_mutex_unlock(mutex); + {$ifdef mse_debugmutex} + interlockeddecrement(mutexcount); + if application.getmutexaddr = @mutex then begin + interlockeddecrement(appmutexcount); + end; + {$endif} + end; +end; + +function sys_mutexcreate(out mutex: mutexty): syserrorty; +begin + initmutex(linuxmutexty(mutex).mutex); + result:= sye_ok; +end; + +function sys_mutexdestroy(var mutex: mutexty): syserrorty; +begin + destroymutex(linuxmutexty(mutex).mutex); + result:= sye_ok; +end; + +function sys_mutexlock(var mutex: mutexty): syserrorty; +begin + if pthread_mutex_lock(linuxmutexty(mutex).mutex) = 0 then begin + result:= sye_ok; + {$ifdef mse_debugmutex} + interlockedincrement(mutexsequ); + interlockedincrement(mutexcount); + if applicationallocated and (application.getmutexaddr = @mutex) then begin + interlockedincrement(appmutexcount); + appmutexlockth:= sys_getcurrentthread; + appmutexlockc:= appmutexcount; + appmutexlocks:= mutexsequ; + end; + {$endif} + end + else begin + result:= sye_mutex; + end; +end; + +function sys_mutextrylock(var mutex: mutexty): syserrorty; +var + int1: integer; +begin + int1:= pthread_mutex_trylock(linuxmutexty(mutex).mutex); + {$ifdef mse_debugmutex} + if int1 = 0 then begin + interlockedincrement(mutexsequ); + interlockedincrement(mutexcount); + if application.getmutexaddr = @mutex then begin + interlockedincrement(appmutexcount); + appmutexlockth:= sys_getcurrentthread; + appmutexlockc:= appmutexcount; + appmutexlocks:= mutexsequ; + end; + end; + {$endif} + case int1 of + 0: result:= sye_ok; + ebusy: result:= sye_busy; + else result:= sye_mutex; + end; +end; + +function sys_mutexunlock(var mutex: mutexty): syserrorty; +begin + {$ifdef mse_debugmutex} + interlockedincrement(mutexsequ); + interlockeddecrement(mutexcount); + if applicationallocated and (application.getmutexaddr = @mutex) then begin + interlockeddecrement(appmutexcount); + appmutexunlockth:= sys_getcurrentthread; + appmutexunlockc:= appmutexcount; + appmutexunlocks:= mutexsequ; + end; + {$endif} + if pthread_mutex_unlock(linuxmutexty(mutex).mutex) = 0 then begin + result:= sye_ok; + end + else begin + result:= sye_mutex; + end; +end; + +function sys_semcreate(out sem: semty; count: integer): syserrorty; +begin + fillchar(sem,sizeof(sem),0); + with linuxsemty(sem) do begin + if sem_init(d.sema,0,count) = 0 then begin + result:= sye_ok; + end + else begin + result:= sye_semaphore; + end; + end; +end; + +function sempost1(var sem: semty): syserrorty; +begin + with linuxsemty(sem) do begin + if sem_post(d.sema) = 0 then begin + result:= sye_ok; + end + else begin + result:= sye_semaphore; + end; + end; +end; + +function sys_sempost(var sem: semty): syserrorty; +begin + with linuxsemty(sem) do begin + if d.destroyed <> 0 then begin + result:= sye_semaphore; + exit; + end; + end; + result:= sempost1(sem); +end; + +function sys_semdestroy(var sem: semty): syserrorty; +var + int1: integer; +begin + result:= sye_ok; + with linuxsemty(sem) do begin + int1:= interlockedincrement(d.destroyed); + if int1 = 1 then begin + while sys_semcount(sem) = 0 do begin + if sem_post(d.sema) <> 0 then begin + break; + end; + end; + sem_destroy(d.sema); + end; + end; +end; + +function sys_semwait(var sem: semty; timeoutusec: integer): syserrorty; + //timeoutus = 0 -> no timeout; +var + time1: ttimespec; +// err: integer; +begin + result:= sye_semaphore; + with linuxsemty(sem) do begin + if d.destroyed <> 0 then begin + exit; + end; + if timeoutusec <= 0 then begin + while sem_wait(d.sema) <> 0 do begin + if sys_getlasterror <> eintr then begin + exit; + end; + end; + end + else begin + time1:= unigettimestamp(timeoutusec); + while sem_timedwait(d.sema,@time1) <> 0 do begin + case sys_getlasterror of + eintr: begin + end; + etimedout: begin + result:= sye_timeout; + exit; + end + else begin + exit; + end; + end; + end; + end; + end; + result:= sye_ok; +end; + +function sys_semtrywait(var sem: semty): boolean; +begin + with linuxsemty(sem) do begin + if d.destroyed <> 0 then begin + result:= false; + exit; + end; + repeat + result:= sem_trywait(d.sema) = 0; + until result or (sys_getlasterror <> eintr); + end; +end; + +function sys_semcount(var sem: semty): integer; +begin + with linuxsemty(sem) do begin + sem_getvalue(d.sema,@result); + end; +end; + +function sys_condcreate(out cond: condty): syserrorty; +begin + pthread_cond_init(linuxcondty(cond).d.cond,nil); + initmutex(linuxcondty(cond).d.mutex); + result:= sye_ok; +end; + +function sys_conddestroy(var cond: condty): syserrorty; +begin + while true do begin + pthread_mutex_lock(linuxcondty(cond).d.mutex); + if pthread_cond_destroy(linuxcondty(cond).d.cond) = 0 then begin + pthread_mutex_unlock(linuxcondty(cond).d.mutex); + destroymutex(linuxcondty(cond).d.mutex); + break; + end; + pthread_cond_broadcast(linuxcondty(cond).d.cond); + pthread_mutex_unlock(linuxcondty(cond).d.mutex); + end; + result:= sye_ok; +end; + +function sys_condlock(var cond: condty): syserrorty; +begin + pthread_mutex_lock(linuxcondty(cond).d.mutex); + result:= sye_ok; +end; + +function sys_condunlock(var cond: condty): syserrorty; +begin + pthread_mutex_unlock(linuxcondty(cond).d.mutex); + result:= sye_ok; +end; + +function sys_condsignal(var cond: condty): syserrorty; +begin + pthread_cond_signal(linuxcondty(cond).d.cond); + result:= sye_ok; +end; + +function sys_condbroadcast(var cond: condty): syserrorty; +begin + pthread_cond_broadcast(linuxcondty(cond).d.cond); + result:= sye_ok; +end; + +function sys_condwait(var cond: condty; timeoutusec: integer): syserrorty; + //timeoutus = 0 -> no timeout; + //gue_ok -> condition signaled + //gue_timeout -> timeout + //gue_cond -> error +var + time1: ttimespec; +begin + result:= sye_ok; + if timeoutusec = 0 then begin + pthread_cond_wait(linuxcondty(cond).d.cond,linuxcondty(cond).d.mutex); + end + else begin + time1:= unigettimestamp(timeoutusec); + if pthread_cond_timedwait(linuxcondty(cond).d.cond,linuxcondty(cond).d.mutex, + @time1) <> 0 then begin + result:= sye_timeout; + end; + end; +end; + +function sys_utctolocaltime(const value: tdatetime): tdatetime; +var + ti1: integer; + rea1: real; + tm: tunixtime; +begin + rea1:= value + unidatetimeoffset; + if rea1 < 0 then begin + ti1:= 0; + end + else begin + ti1:= round(rea1) * 24*60*60; //seconds + end; + localtime_r(@ti1,@tm); + result:= incsecond(value,tm.__tm_gmtoff); +// result:= value + sys_localtimeoffset; +end; + +function sys_localtimetoutc(const value: tdatetime): tdatetime; +var + year,month,day,hour,minute,second,millisecond: word; + tm: tunixtime; +begin + if value < -unidatetimeoffset then begin + decodedatetime(-unidatetimeoffset,year,month,day,hour,minute,second,millisecond); + end + else begin + decodedatetime(value,year,month,day,hour,minute,second,millisecond); + end; + with tm do begin + tm_sec:= second; + tm_min:= minute; + tm_hour:= hour; + tm_mday:= day; + tm_mon:= month; + tm_year:= year-1900; + end; + timelocal(tm); + result:= incsecond(value,-tm.__tm_gmtoff); +// result:= value - sys_localtimeoffset; +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/linux/mseuniintf.pas b/mseide-msegui/lib/common/kernel/linux/mseuniintf.pas new file mode 100644 index 0000000..ef55ea9 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/linux/mseuniintf.pas @@ -0,0 +1,131 @@ +{ MSEgui Copyright (c) 1999-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseuniintf; //X11 + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msegraphics,msetypes{msestrings}; + +{$include ../mseuniintf.inc} + +function uni_listfontswithglyph(achar: msechar): msestringarty; + +implementation +uses + mseguiintf,msex11gdi,mxft,xlib,msefontconfig; + +function uni_getfontwithglyph(var drawinfo: drawinfoty): boolean; +var + pat1: pfcpattern; + charset1,charset2: pfccharset; + res1: tfcresult; + fontset1: pfcfontset; + po1: ppfcpattern; + int1: integer; + font1: pxftfont; +begin + result:= false; + if hasxft then begin +{$ifdef FPC} {$checkpointer off} {$endif} + pat1:= fontdatatoxftpat(drawinfo.getfont.fontdata^,false); + if pat1 <> nil then begin + with drawinfo.getfont.fontdata^ do begin + charset1:= fccharsetcreate(); + fccharsetaddchar(charset1,h.d.glyph); + fcpatternaddcharset(pat1,fc_charset,charset1); + fccharsetdestroy(charset1); + fcconfigsubstitute(nil,pat1,fcmatchpattern); + fcconfigsubstitute(nil,pat1,fcmatchfont); + xftdefaultsubstitute(msedisplay,xdefaultscreen(msedisplay),pat1); + fontset1:= fcfontsort(nil,pat1,true,@charset1,@res1); + if fccharsethaschar(charset1,h.d.glyph) then begin + with fontset1^ do begin + po1:= fonts; + for int1:= 0 to nfont - 1 do begin + if fcpatterngetcharset(po1^,fc_charset,0,@charset2) = fcresultmatch then begin + if fccharsethaschar(charset2,h.d.glyph) then begin + font1:= xftfontopenpattern(msedisplay, + fcfontrenderprepare(nil,pat1,po1^)); + if font1 <> nil then begin + if xftcharexists(msedisplay,font1,h.d.glyph) then begin + getxftfontdata(font1,drawinfo); + result:= true; + end + else begin + xftfontclose(msedisplay,font1); + end; + end; + break; + end; + end; + inc(po1); + end; + end; + end; + fccharsetdestroy(charset1); + fcpatterndestroy(pat1); + fcfontsetdestroy(fontset1); + end; + end; +{$ifdef FPC} {$checkpointer default} {$endif} + end; +end; + +function uni_listfontswithglyph(achar: msechar): msestringarty; +var + pat1: pfcpattern; + charset1,charset2: pfccharset; + res1: tfcresult; + fontset1: pfcfontset; + po1: ppfcpattern; + int1,int2: integer; +// font1: pxftfont; + po2: pchar; +begin + result:= nil; + if hasxft then begin +{$ifdef FPC} {$checkpointer off} {$endif} + pat1:= fcpatterncreate(); + charset1:= fccharsetcreate(); + fccharsetaddchar(charset1,longword(achar)); + fcpatternaddcharset(pat1,fc_charset,charset1); + fccharsetdestroy(charset1); + fcconfigsubstitute(nil,pat1,fcmatchpattern); + fcconfigsubstitute(nil,pat1,fcmatchfont); + xftdefaultsubstitute(msedisplay,xdefaultscreen(msedisplay),pat1); + fontset1:= fcfontsort(nil,pat1,true,@charset1,@res1); + if fccharsethaschar(charset1,longword(achar)) then begin + with fontset1^ do begin + po1:= fonts; + setlength(result,nfont); + int2:= 0; + for int1:= 0 to nfont - 1 do begin + if fcpatterngetcharset(po1^,fc_charset,0,@charset2) = fcresultmatch then begin + if fccharsethaschar(charset2,longword(achar)) then begin + if fcpatterngetstring(po1^,fc_family,0,@po2) = fcresultmatch then begin + result[int2]:= po2; + end; + inc(int2); + end; + end; + inc(po1); + end; + setlength(result,int2); + end; + end; + fccharsetdestroy(charset1); + fcpatterndestroy(pat1); + fcfontsetdestroy(fontset1); + end; +{$ifdef FPC} {$checkpointer default} {$endif} +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/linux/mxft.pas b/mseide-msegui/lib/common/kernel/linux/mxft.pas new file mode 100644 index 0000000..4f48f73 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/linux/mxft.pas @@ -0,0 +1,454 @@ +unit mxft; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + {$ifdef FPC}x,{$endif}Xlib,mxrender,mselibc,msectypes,msefontconfig; + +{ + Automatically converted by H2Pas 0.99.16 from Xft.h + The following command line parameters were used: + -D + -l + xft + -o + xft.pas + -T + -u + xft + Xft.h +} + +{$IFDEF FPC} + {$PACKRECORDS C} +{$ELSE} + {$ALIGN 4} + {$MINENUMSIZE 4} +{$ENDIF} + +type //from fontconfig.h, XftCompat.h + XftType = ( + XftTypeVoid, + XftTypeInteger, + XftTypeDouble, + XftTypeString, + XftTypeBool, + XftTypeMatrix, + XftTypeCharSet, + XftTypeFTFace, + XftTypeLangSet + ); + const + External_library='libXft.so'; +// fclib = 'libfontconfig.so'; + Type + + TFT_FaceRec = record //from freetype.h + //dummy + end; + TFT_Face = ^TFT_FaceRec; + + TFT_UInt = longword; //from fttypes.h + + +// PDisplay = ^Display; + PFT_UInt = ^TFT_UInt; + Plongint = ^longint; +// PVisual = ^Visual; + + { + * $XFree86: xc/lib/Xft/Xft.h,v 1.32 2003/02/25 21:57:53 dawes Exp $ + * + * Copyright ? 2000 Keith Packard, member of The XFree86 Project, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + } + const + XFT_MAJOR = 2; + XFT_MINOR = 1; + XFT_REVISION = 0; + XftVersion = ((XFT_MAJOR * 10000) + (XFT_MINOR * 100) + (XFT_REVISION)); + + const + XFT_CORE = 'core'; + XFT_RENDER = 'render'; + XFT_XLFD = 'xlfd'; + XFT_MAX_GLYPH_MEMORY = 'maxglyphmemory'; + XFT_MAX_UNREF_FONTS = 'maxunreffonts'; +{ + var + _XftFTlibrary : TFT_Library;cvar;external; +} + type + + TXftDraw = record + //dummy + end; + PXftDraw = ^TXftDraw; + + TXftFont = record + ascent : longint; + descent : longint; + height : longint; + max_advance_width : longint; + charset : ^TFcCharSet; + pattern : ^TFcPattern; + end; + PXftFont = ^TXftFont; + + TXftFontinfo = record + //dummy + end; + PXftFontInfo = ^TXftFontInfo; + + TXftColor = record + pixel : culong; + color : TXRenderColor; + end; + PXftColor = ^TXftColor; + + TXftCharSpec = record + ucs4 : TFcChar32; + x : smallint; + y : smallint; + end; + PXftCharSpec = ^TXftCharSpec; + + TXftCharFontSpec = record + font : ^TXftFont; + ucs4 : TFcChar32; + x : smallint; + y : smallint; + end; + PXftCharFontSpec = ^TXftCharFontSpec; + + TXftGlyphSpec = record + glyph : TFT_UInt; + x : smallint; + y : smallint; + end; + PXftGlyphSpec = ^TXftGlyphSpec; + + TXftGlyphFontSpec = record + font : ^TXftFont; + glyph : TFT_UInt; + x : smallint; + y : smallint; + end; + PXftGlyphFontSpec = ^TXftGlyphFontSpec; + + +{$ifdef staticxft} + { fccharset.c } + function FcCharSetCreate: PFcCharSet;cdecl; + external fclib name 'FcCharSetCreate'; + procedure FcCharSetDestroy(fcs:PFcCharSet);cdecl; + external fclib name 'FcCharSetDestroy'; + function FcCharSetAddChar(fcs:PFcCharSet; ucs4:TFcChar32):TFcBool;cdecl; + external fclib name 'FcCharSetAddChar'; + function FcCharSetHasChar(fcs:PFcCharSet; ucs4:TFcChar32):TFcBool;cdecl; + external External_library name 'FcCharSetHasChar'; + { fcpat.c } + function FcPatternCreate: PFcPattern;cdecl; + external fclib name 'FcPatternCreate'; + function FcPatternDuplicate(p:PFcPattern): PFcPattern;cdecl; + external fclib name 'FcPatternDuplicate'; + function FcPatternAdd(p:PFcPattern; aobject:Pchar; value:TFcValue; + append:TFcBool):TFcBool;cdecl; + external fclib name 'FcPatternAdd'; + procedure FcPatternDestroy(p: PFcPattern);cdecl; + external fclib name 'FcPatternDestroy'; + function FcPatternGetCharSet(p:PFcPattern; aobject:Pchar; n:longint; + c:PPFcCharSet):TFcResult;cdecl; + external fclib name 'FcPatternGetCharSet'; + function FcPatternAddInteger(p:PFcPattern; aobject:Pchar; i:longint):TFcBool; + cdecl;external fclib name 'FcPatternAddInteger'; + function FcPatternAddDouble(p:PFcPattern; aobject:Pchar; d:Tdouble):TFcBool; + cdecl;external fclib name 'FcPatternAddDouble'; + function FcPatternAddString(p:PFcPattern; aobject:Pchar; s: pansichar):TFcBool; + cdecl;external fclib name 'FcPatternAddString'; + function FcPatternAddMatrix(p:PFcPattern; aobject:Pchar; s:PFcMatrix):TFcBool; + cdecl;external fclib name 'FcPatternAddMatrix'; + function FcPatternAddCharSet(p:PFcPattern; + aobject:Pchar; c:PFcCharSet):TFcBool;cdecl; + external fclib name 'FcPatternAddCharSet'; + function FcPatternAddBool(p:PFcPattern; aobject:Pchar; b:TFcBool):TFcBool; + cdecl;external fclib name 'FcPatternAddBool'; + function FcPatternAddLangSet(p:PFcPattern; aobject:Pchar; + ls:PFcLangSet):TFcBool;cdecl; + external fclib name 'FcPatternAddLangSet'; + { fclist.c } + function FcObjectSetCreate: PFcObjectSet;cdecl; + external fclib name 'FcObjectSetCreate'; + function FcObjectSetAdd(os: PFcObjectSet; aobject:Pchar):TFcBool;cdecl; + external fclib name 'FcObjectSetAdd'; + procedure FcObjectSetDestroy(os: PFcObjectSet);cdecl; + external fclib name 'FcObjectSetDestroy'; + function FcFontList(config: PFcConfig; p:PFcPattern; + os:PFcObjectSet): PFcFontSet;cdecl; + external fclib name 'FcFontList'; + { fcmatch.c } + function FcFontSort(config:PFcConfig; p:PFcPattern; trim:TFcBool; + csp:PPFcCharSet; result:PFcResult): PFcFontSet;cdecl; + external fclib name 'FcFontSort'; + function FcFontRenderPrepare(config:PFcConfig; pat:PFcPattern; + font:PFcPattern): PFcPattern;cdecl; + external fclib name 'FcFontRenderPrepare'; + { fcfs.c } + procedure FcFontSetDestroy(s:PFcFontSet);cdecl; + external fclib name 'FcFontSetDestroy'; + + { fccfg.c } + function FcConfigSubstitute(config:PFcConfig; p:PFcPattern; + kind:TFcMatchKind):TFcBool;cdecl; + external fclib name 'FcConfigSubstitute'; + { fcdefault.c } + procedure FcDefaultSubstitute(pattern:PFcPattern);cdecl; + external fclib name 'FcDefaultSubstitute'; + { fcmatrix-c } + procedure FcMatrixRotate(m:PFcMatrix; c:Tdouble; s:Tdouble);cdecl; + external fclib name 'FcMatrixRotate'; + + procedure FcMatrixScale(m:PFcMatrix; sx:Tdouble; sy:Tdouble);cdecl; + external fclib name 'FcMatrixScale'; + { xftcolor.c } + + function XftColorAllocName (dpy: PDisplay; visual: PVisual; cmap: TColormap; + name: PChar; result: PXftColor): TFcBool; + cdecl;external External_library name 'XftColorAllocName'; + + function XftColorAllocValue(dpy:PDisplay; visual:PVisual; cmap:TColormap; + color:PXRenderColor; result:PXftColor):TFcBool; + cdecl;external External_library name 'XftColorAllocValue'; + + procedure XftColorFree(dpy:PDisplay; visual:PVisual; cmap:TColormap; color:PXftColor);cdecl;external External_library name 'XftColorFree'; + + { xftcore.c } + { xftdir.c } + function XftDirScan(aset:PFcFontSet; dir:Pchar; force:TFcBool):TFcBool;cdecl;external External_library name 'XftDirScan'; + + function XftDirSave(aset:PFcFontSet; dir:Pchar):TFcBool;cdecl;external External_library name 'XftDirSave'; + + { xftdpy.c } + function XftDefaultHasRender(dpy:PDisplay):TFcBool;cdecl;external External_library name 'XftDefaultHasRender'; + + function XftDefaultSet(dpy:PDisplay; defaults:PFcPattern):TFcBool;cdecl;external External_library name 'XftDefaultSet'; + + procedure XftDefaultSubstitute(dpy:PDisplay; screen:longint; pattern:PFcPattern);cdecl;external External_library name 'XftDefaultSubstitute'; + + { xftdraw.c } + function XftDrawCreate(dpy:PDisplay; drawable:TDrawable; visual:PVisual; colormap:TColormap): PXftDraw;cdecl;external External_library name 'XftDrawCreate'; + + function XftDrawCreateBitmap(dpy:PDisplay; bitmap:TPixmap): PXftDraw;cdecl;external External_library name 'XftDrawCreateBitmap'; + + function XftDrawCreateAlpha(dpy:PDisplay; pixmap:TPixmap; depth:longint): PXftDraw;cdecl;external External_library name 'XftDrawCreateAlpha'; + + procedure XftDrawChange(draw:PXftDraw; drawable:TDrawable);cdecl;external External_library name 'XftDrawChange'; + + function XftDrawDisplay(draw:PXftDraw): PDisplay;cdecl;external External_library name 'XftDrawDisplay'; + + function XftDrawDrawable(draw:PXftDraw):TDrawable;cdecl;external External_library name 'XftDrawDrawable'; + + function XftDrawColormap(draw:PXftDraw):TColormap;cdecl;external External_library name 'XftDrawColormap'; + + function XftDrawVisual(draw:PXftDraw): PVisual;cdecl;external External_library name 'XftDrawVisual'; + + procedure XftDrawDestroy(draw:PXftDraw);cdecl;external External_library name 'XftDrawDestroy'; + + function XftDrawPicture(draw:PXftDraw):TPicture;cdecl;external External_library name 'XftDrawPicture'; + + function XftDrawSrcPicture(draw:PXftDraw; color:PXftColor):TPicture;cdecl;external External_library name 'XftDrawSrcPicture'; + + procedure XftDrawGlyphs(draw:PXftDraw; color:PXftColor; pub:PXftFont; x:longint; y:longint; + glyphs:PFT_UInt; nglyphs:longint);cdecl;external External_library name 'XftDrawGlyphs'; + + procedure XftDrawString8(draw:PXftDraw; color:PXftColor; pub:PXftFont; x:longint; y:longint; + _string:PFcChar8; len:longint);cdecl;external External_library name 'XftDrawString8'; + + procedure XftDrawString16(draw:PXftDraw; color:PXftColor; pub:PXftFont; x:longint; y:longint; + _string:pwidechar; len:longint);cdecl;external External_library name 'XftDrawString16'; + + procedure XftDrawString32(draw:PXftDraw; color:PXftColor; pub:PXftFont; x:longint; y:longint; + _string:PFcChar32; len:longint);cdecl;external External_library name 'XftDrawString32'; + + procedure XftDrawStringUtf8(draw:PXftDraw; color:PXftColor; pub:PXftFont; x:longint; y:longint; + _string:PFcChar8; len:longint);cdecl;external External_library name 'XftDrawStringUtf8'; + + procedure XftDrawStringUtf16(draw:PXftDraw; color:PXftColor; pub:PXftFont; x:longint; y:longint; + _string:PFcChar8; endian:TFcEndian; len:longint);cdecl;external External_library name 'XftDrawStringUtf16'; + + procedure XftDrawCharSpec(draw:PXftDraw; color:PXftColor; pub:PXftFont; chars:PXftCharSpec; len:longint);cdecl;external External_library name 'XftDrawCharSpec'; + + procedure XftDrawCharFontSpec(draw:PXftDraw; color:PXftColor; chars:PXftCharFontSpec; len:longint);cdecl;external External_library name 'XftDrawCharFontSpec'; + + procedure XftDrawGlyphSpec(draw:PXftDraw; color:PXftColor; pub:PXftFont; glyphs:PXftGlyphSpec; len:longint);cdecl;external External_library name 'XftDrawGlyphSpec'; + + procedure XftDrawGlyphFontSpec(draw:PXftDraw; color:PXftColor; glyphs:PXftGlyphFontSpec; len:longint);cdecl;external External_library name 'XftDrawGlyphFontSpec'; + + procedure XftDrawRect(draw:PXftDraw; color:PXftColor; x:longint; y:longint; width:dword; + height:dword);cdecl;external External_library name 'XftDrawRect'; + + function XftDrawSetClip(draw:PXftDraw; r:TRegion):TFcBool;cdecl;external External_library name 'XftDrawSetClip'; + + function XftDrawSetClipRectangles(draw:PXftDraw; xOrigin:longint; yOrigin:longint; rects:PXRectangle; n:longint):TFcBool;cdecl;external External_library name 'XftDrawSetClipRectangles'; + + procedure XftDrawSetSubwindowMode(draw:PXftDraw; mode:longint);cdecl;external External_library name 'XftDrawSetSubwindowMode'; + + { xftextent.c } + procedure XftGlyphExtents(dpy:PDisplay; pub:PXftFont; glyphs:PFT_UInt; nglyphs:longint; extents:PXGlyphInfo);cdecl;external External_library name 'XftGlyphExtents'; + + procedure XftTextExtents8(dpy:PDisplay; pub:PXftFont; _string:PFcChar8; len:longint; extents:PXGlyphInfo);cdecl;external External_library name 'XftTextExtents8'; + + procedure XftTextExtents16(dpy:PDisplay; pub:PXftFont; _string: pwidechar{PFcChar16}; len:longint; extents:PXGlyphInfo);cdecl;external External_library name 'XftTextExtents16'; + + procedure XftTextExtents32(dpy:PDisplay; pub:PXftFont; _string:PFcChar32; len:longint; extents:PXGlyphInfo);cdecl;external External_library name 'XftTextExtents32'; + + procedure XftTextExtentsUtf8(dpy:PDisplay; pub:PXftFont; _string:PFcChar8; len:longint; extents:PXGlyphInfo);cdecl;external External_library name 'XftTextExtentsUtf8'; + + procedure XftTextExtentsUtf16(dpy:PDisplay; pub:PXftFont; _string:PFcChar8; endian:TFcEndian; len:longint; + extents:PXGlyphInfo);cdecl;external External_library name 'XftTextExtentsUtf16'; + + { xftfont.c } + function XftFontMatch(dpy:PDisplay; screen:longint; pattern:PFcPattern; result:PFcResult): PFcPattern;cdecl;external External_library name 'XftFontMatch'; + + function XftFontOpen(dpy:PDisplay; screen:longint; args: array of const):PXftFont;cdecl;external External_library name 'XftFontOpen'; + + function XftFontOpenName(dpy:PDisplay; screen:longint; name:Pchar):PXftFont;cdecl;external External_library name 'XftFontOpenName'; + + function XftFontOpenXlfd(dpy:PDisplay; screen:longint; xlfd:Pchar):PXftFont;cdecl;external External_library name 'XftFontOpenXlfd'; + + function XftLockFace(pub:PXftFont):TFT_Face;cdecl;external External_library name 'XftLockFace'; + + procedure XftUnlockFace(pub:PXftFont);cdecl;external External_library name 'XftUnlockFace'; + + function XftFontInfoCreate(dpy:PDisplay; pattern:PFcPattern):PXftFontInfo;cdecl;external External_library name 'XftFontInfoCreate'; + + procedure XftFontInfoDestroy(dpy:PDisplay; fi:PXftFontInfo);cdecl;external External_library name 'XftFontInfoDestroy'; + + function XftFontInfoHash(fi:PXftFontInfo):TFcChar32;cdecl;external External_library name 'XftFontInfoHash'; + + function XftFontInfoEqual(a:PXftFontInfo; b:PXftFontInfo):TFcBool;cdecl;external External_library name 'XftFontInfoEqual'; + + function XftFontOpenInfo(dpy:PDisplay; pattern:PFcPattern; fi:PXftFontInfo): PXftFont;cdecl;external External_library name 'XftFontOpenInfo'; + + function XftFontOpenPattern(dpy:PDisplay; pattern:PFcPattern):PXftFont;cdecl;external External_library name 'XftFontOpenPattern'; + + function XftFontCopy(dpy:PDisplay; pub:PXftFont):PXftFont;cdecl;external External_library name 'XftFontCopy'; + + procedure XftFontClose(dpy:PDisplay; pub:PXftFont);cdecl;external External_library name 'XftFontClose'; + + function XftInitFtLibrary:TFcBool;cdecl;external External_library name 'XftInitFtLibrary'; + + { xftglyphs.c } + procedure XftFontLoadGlyphs(dpy:PDisplay; pub:PXftFont; need_bitmaps:TFcBool; glyphs:PFT_UInt; nglyph:longint);cdecl;external External_library name 'XftFontLoadGlyphs'; + + procedure XftFontUnloadGlyphs(dpy:PDisplay; pub:PXftFont; glyphs:PFT_UInt; nglyph:longint);cdecl;external External_library name 'XftFontUnloadGlyphs'; + + + const + XFT_NMISSING = 256; + + function XftFontCheckGlyph(dpy:PDisplay; pub:PXftFont; need_bitmaps:TFcBool; glyph:TFT_UInt; missing:PFT_UInt; + nmissing:Plongint):TFcBool;cdecl;external External_library name 'XftFontCheckGlyph'; + + function XftCharExists(dpy:PDisplay; pub:PXftFont; ucs4:TFcChar32):TFcBool;cdecl;external External_library name 'XftCharExists'; + + function XftCharIndex(dpy:PDisplay; pub:PXftFont; ucs4:TFcChar32):TFT_UInt;cdecl;external External_library name 'XftCharIndex'; + + { xftgram.y } + { xftinit.c } + function XftInit(config:Pchar):TFcBool;cdecl;external External_library name 'XftInit'; + + function XftGetVersion:longint;cdecl;external External_library name 'XftGetVersion'; + + { xftlex.l } + { xftlist.c } + + function XftListFonts(dpy:PDisplay; screen:longint; + args:array of const):PFcFontSet;cdecl;external External_library name 'XftListFonts'; + + { xftmatch.c } + { xftmatrix.c } + { xftname.c } + function XftNameParse(name:Pchar): PFcPattern;cdecl;external External_library name 'XftNameParse'; + + { xftpat.c } + + { xftrender.c } + procedure XftGlyphRender(dpy:PDisplay; op:longint; src:TPicture; pub:PXftFont; dst:TPicture; + srcx:longint; srcy:longint; x:longint; y:longint; glyphs:PFT_UInt; + nglyphs:longint);cdecl;external External_library name 'XftGlyphRender'; + + procedure XftGlyphSpecRender(dpy:PDisplay; op:longint; src:TPicture; pub:PXftFont; dst:TPicture; + srcx:longint; srcy:longint; glyphs:PXftGlyphSpec; nglyphs:longint);cdecl;external External_library name 'XftGlyphSpecRender'; + + procedure XftCharSpecRender(dpy:PDisplay; op:longint; src:TPicture; pub:PXftFont; dst:TPicture; + srcx:longint; srcy:longint; chars:PXftCharSpec; len:longint);cdecl;external External_library name 'XftCharSpecRender'; + + procedure XftGlyphFontSpecRender(dpy:PDisplay; op:longint; src:TPicture; dst:TPicture; srcx:longint; + srcy:longint; glyphs:PXftGlyphFontSpec; nglyphs:longint);cdecl;external External_library name 'XftGlyphFontSpecRender'; + + procedure XftCharFontSpecRender(dpy:PDisplay; op:longint; src:TPicture; dst:TPicture; srcx:longint; + srcy:longint; chars:PXftCharFontSpec; len:longint);cdecl;external External_library name 'XftCharFontSpecRender'; + + procedure XftTextRender8(dpy:PDisplay; op:longint; src:TPicture; pub:PXftFont; dst:TPicture; + srcx:longint; srcy:longint; x:longint; y:longint; _string:PFcChar8; + len:longint);cdecl;external External_library name 'XftTextRender8'; + + procedure XftTextRender16(dpy:PDisplay; op:longint; src:TPicture; pub:PXftFont; dst:TPicture; + srcx:longint; srcy:longint; x:longint; y:longint; _string:PFcChar16; + len:longint);cdecl;external External_library name 'XftTextRender16'; + + procedure XftTextRender16BE(dpy:PDisplay; op:longint; src:TPicture; pub:PXftFont; dst:TPicture; + srcx:longint; srcy:longint; x:longint; y:longint; _string:PFcChar8; + len:longint);cdecl;external External_library name 'XftTextRender16BE'; + + procedure XftTextRender16LE(dpy:PDisplay; op:longint; src:TPicture; pub:PXftFont; dst:TPicture; + srcx:longint; srcy:longint; x:longint; y:longint; _string:PFcChar8; + len:longint);cdecl;external External_library name 'XftTextRender16LE'; + + procedure XftTextRender32(dpy:PDisplay; op:longint; src:TPicture; pub:PXftFont; dst:TPicture; + srcx:longint; srcy:longint; x:longint; y:longint; _string:PFcChar32; + len:longint);cdecl;external External_library name 'XftTextRender32'; + + procedure XftTextRender32BE(dpy:PDisplay; op:longint; src:TPicture; pub:PXftFont; dst:TPicture; + srcx:longint; srcy:longint; x:longint; y:longint; _string:PFcChar8; + len:longint);cdecl;external External_library name 'XftTextRender32BE'; + + procedure XftTextRender32LE(dpy:PDisplay; op:longint; src:TPicture; pub:PXftFont; dst:TPicture; + srcx:longint; srcy:longint; x:longint; y:longint; _string:PFcChar8; + len:longint);cdecl;external External_library name 'XftTextRender32LE'; + + procedure XftTextRenderUtf8(dpy:PDisplay; op:longint; src:TPicture; pub:PXftFont; dst:TPicture; + srcx:longint; srcy:longint; x:longint; y:longint; _string:PFcChar8; + len:longint);cdecl;external External_library name 'XftTextRenderUtf8'; + + procedure XftTextRenderUtf16(dpy:PDisplay; op:longint; src:TPicture; pub:PXftFont; dst:TPicture; + srcx:longint; srcy:longint; x:longint; y:longint; _string:PFcChar8; + endian:TFcEndian; len:longint);cdecl;external External_library name 'XftTextRenderUtf16'; + + { xftstr.c } + { xftxlfd.c } + function XftXlfdParse(xlfd_orig:Pchar; ignore_scalable:TFcBool; complete:TFcBool):PFcPattern;cdecl;external External_library name 'XftXlfdParse'; + +{$endif staticxft} + +implementation + + +end. diff --git a/mseide-msegui/lib/common/kernel/linux/mxrandr.pas b/mseide-msegui/lib/common/kernel/linux/mxrandr.pas new file mode 100644 index 0000000..3d178df --- /dev/null +++ b/mseide-msegui/lib/common/kernel/linux/mxrandr.pas @@ -0,0 +1,216 @@ +unit mxrandr; +{/* + * Copyright © 2000 Compaq Computer Corporation, Inc. + * Copyright © 2002 Hewlett-Packard Company, Inc. + * Copyright © 2006 Intel Corporation + * Copyright © 2008 Red Hat, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + * + * Author: Jim Gettys, HP Labs, Hewlett-Packard, Inc. + * Keith Packard, Intel Corporation + */} +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msectypes,x,xlib; + +{$packrecords c} + +const +//* Event selection bits */ + RRScreenChangeNotifyMask = 1 shl 0; +///* V1.2 additions */ + RRCrtcChangeNotifyMask = 1 shl 1; + RROutputChangeNotifyMask = 1 shl 2; + RROutputPropertyNotifyMask = 1 shl 3; +//* V1.4 additions */ + RRProviderChangeNotifyMask = 1 shl 4; + RRProviderPropertyNotifyMask = 1 shl 5; + RRResourceChangeNotifyMask = 1 shl 6; + +//* Event codes */ + RRScreenChangeNotify = 0; +//* V1.2 additions */ + RRNotify = 1; +//* RRNotify Subcodes */ + RRNotify_CrtcChange = 0; + RRNotify_OutputChange = 0; + RRNotify_OutputProperty = 2; + RRNotify_ProviderChange = 3; + RRNotify_ProviderProperty = 4; + RRNotify_ResourceChange = 5; + rrlastnotify = RRNotify + 5; + +//* used in the rotation field; rotation and reflection in 0.1 proto. */ + RR_Rotate_0 = 1; + RR_Rotate_90 = 2; + RR_Rotate_180 = 4; + RR_Rotate_270 = 8; + +//* new in 1.0 protocol, to allow reflection of screen */ + + RR_Reflect_X = 16; + RR_Reflect_Y = 32; + +type + Window = txid; + Rotation = cushort; + Connection = cushort; + SubpixelOrder = cushort; + SizeID = cushort; + + RROutput = txid; + pRROutput = ^RROutput; + RRCrtc = txid; + pRRCrtc = ^RRCrtc; + RRMode = txid; + pRRMode = ^RRMode; + RRProvider = txid; + pRRProvider = ^RRProvider; + + Time = culong; + pTime = pculong; + + XRRModeFlags = culong; + + XRRModeInfo = record + id: RRMode; + width: cuint; + height: cuint; + dotClock: culong; + hSyncStart: cuint; + hSyncEnd: cuint; + hTotal: cuint; + hSkew: cuint; + vSyncStart: cuint; + vSyncEnd: cuint; + vTotal: cuint; + name: pchar; + nameLength: cuint; + modeFlags: XRRModeFlags; + end; + pXRRModeInfo = ^XRRModeInfo; + + XRRScreenResources = record + timestamp: Time; + configTimestamp:Time; + ncrtc: cint; + crtcs: pRRCrtc; + noutput: cint; + outputs: pRROutput; + nmode: cint; + modes: pXRRModeInfo; + end; + pXRRScreenResources = ^XRRScreenResources; + + XRROutputInfo = record + timestamp: Time; + crtc: RRCrtc; + name: pcchar; + nameLen: cint; + mm_width: culong; + mm_height: culong; + connection: Connection; + subpixel_order: SubpixelOrder; + ncrtc: cint ; + crtcs: pRRCrtc; + nclone: cint; + clones: pRROutput; + nmode: cint; + npreferred: cint; + modes: pRRMode; + end; + pXRROutputInfo = ^XRROutputInfo; + + XRRCrtcInfo = record + timestamp: Time; + x,y: cint; + width,height: cuint; + mode: RRMode; + rotation: Rotation; + noutput: cint; + outputs: pRROutput; + rotations: Rotation; + npossible: cint; + possible: pRROutput; + end; + pXRRCrtcInfo = ^XRRCrtcInfo; + + XRRScreenChangeNotifyEvent = record + _type: cint ; //* event base */ + serial: culong; //* # of last request processed by server */ + send_event: cBool; //* true if this came from a SendEvent request */ + display: pDisplay; //* Display the event was read from */ + window: Window; //* window which selected for this event */ + root: Window; //* Root window for changed screen */ + timestamp: Time ; //* when the screen change occurred */ + config_timestamp: Time; //* when the last configuration change */ + size_index: SizeID; + subpixel_order: SubpixelOrder; + rotation: Rotation; + width: cint; + height: cint; + mwidth: cint; + mheight: cint; + end; + +var + XRRQueryExtension: function (dpy: pDisplay; event_base_return: pcint; + error_base_return: pcint): cBool cdecl; + XRRGetScreenResources: function(dpy: pDisplay; + window: Window): pXRRScreenResources cdecl; + XRRFreeScreenResources: procedure(resources: pXRRScreenResources) cdecl; + XRRGetCrtcInfo: function(dpy: pDisplay; resources: pXRRScreenResources; + crtc: RRCrtc): pXRRCrtcInfo cdecl; + XRRFreeCrtcInfo: procedure(crtcInfo: pXRRCrtcInfo) cdecl; + XRRGetOutputInfo: function(dpy: pDisplay; resources: pXRRScreenResources; + output: RROutput): pXRROutputInfo cdecl; + XRRFreeOutputInfo: procedure(outputInfo: pXRROutputInfo) cdecl; + + XRRSelectInput: procedure(dpy: pDisplay; window: Window; mask: cint) cdecl; + XRRUpdateConfiguration: function(event: pXEvent): cint cdecl; + +function getxrandrlib: boolean; + +implementation +uses + msesys,msesonames,msedynload; + +function getxrandrlib: boolean; +const +// (n: ''; d: @) + funcs: array[0..8] of funcinfoty = ( + (n: 'XRRQueryExtension'; d: @XRRQueryExtension), + (n: 'XRRGetScreenResources'; d: @XRRGetScreenResources), + (n: 'XRRFreeScreenResources'; d: @XRRFreeScreenResources), + (n: 'XRRGetCrtcInfo'; d: @XRRGetCrtcInfo), + (n: 'XRRFreeCrtcInfo'; d: @XRRFreeCrtcInfo), + (n: 'XRRGetOutputInfo'; d: @XRRGetOutputInfo), + (n: 'XRRFreeOutputInfo'; d: @XRRFreeOutputInfo), + (n: 'XRRSelectInput'; d: @XRRSelectInput), + (n: 'XRRUpdateConfiguration'; d: @XRRUpdateConfiguration) + ); + +begin + result:= checkprocaddresses(xrandrnames,funcs); +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/linux/mxrender.pas b/mseide-msegui/lib/common/kernel/linux/mxrender.pas new file mode 100644 index 0000000..aff50e9 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/linux/mxrender.pas @@ -0,0 +1,490 @@ +unit mxrender; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + {$ifdef FPC} x,{$endif}Xlib,mselibc,msectypes; + + const + External_library='libXrender.so'; + +{$IFDEF FPC} + {$PACKRECORDS C} +{$ELSE} + {$ALIGN 4} + {$MINENUMSIZE 4} +{$ENDIF} + + + { + * $XFree86: xc/lib/Xrender/Xrender.h,v 1.18 2002/11/23 02:34:45 keithp Exp $ + * + * Copyright ? 2000 SuSE, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of SuSE not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. SuSE makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Keith Packard, SuSE, Inc. + } + + type + +{$ifndef FPC} + txid = xid; +{$endif} + TBool = integer; + dword = longword; + Pdword = ^dword; + Tdouble = double; + TXFixed = integer; + PXFixed = ^TXFixed; + TGlyph = txid; + PGlyph = ^TGlyph; + TGlyphSet = txid; + PGlyphSet = ^TGlyphSet; + TPicture = txid; + PPicture = ^TPicture; + TPictFormat = txid; + PPictFormat = ^TPictFormat; + {$ifdef FPC} + TRegion = pointer; + {$else} + TRegion = Region; + {$endif} + PRegion = ^TRegion; + + const //from render.h + BadPictFormat = 0; + BadPicture = 1; + BadPictOp = 2; + BadGlyphSet = 3; + BadGlyph = 4; + RenderNumberErrors = BadGlyph + 1; + PictTypeIndexed = 0; + PictTypeDirect = 1; + PictOpMinimum = 0; + PictOpClear = 0; + PictOpSrc = 1; + PictOpDst = 2; + PictOpOver = 3; + PictOpOverReverse = 4; + PictOpIn = 5; + PictOpInReverse = 6; + PictOpOut = 7; + PictOpOutReverse = 8; + PictOpAtop = 9; + PictOpAtopReverse = 10; + PictOpXor = 11; + PictOpAdd = 12; + PictOpSaturate = 13; + PictOpMaximum = 13; + { + * Operators only available in version 0.2 + } + PictOpDisjointMinimum = $10; + PictOpDisjointClear = $10; + PictOpDisjointSrc = $11; + PictOpDisjointDst = $12; + PictOpDisjointOver = $13; + PictOpDisjointOverReverse = $14; + PictOpDisjointIn = $15; + PictOpDisjointInReverse = $16; + PictOpDisjointOut = $17; + PictOpDisjointOutReverse = $18; + PictOpDisjointAtop = $19; + PictOpDisjointAtopReverse = $1a; + PictOpDisjointXor = $1b; + PictOpDisjointMaximum = $1b; + PictOpConjointMinimum = $20; + PictOpConjointClear = $20; + PictOpConjointSrc = $21; + PictOpConjointDst = $22; + PictOpConjointOver = $23; + PictOpConjointOverReverse = $24; + PictOpConjointIn = $25; + PictOpConjointInReverse = $26; + PictOpConjointOut = $27; + PictOpConjointOutReverse = $28; + PictOpConjointAtop = $29; + PictOpConjointAtopReverse = $2a; + PictOpConjointXor = $2b; + PictOpConjointMaximum = $2b; + PolyEdgeSharp = 0; + PolyEdgeSmooth = 1; + PolyModePrecise = 0; + PolyModeImprecise = 1; + CPRepeat = 1 shl 0; + CPAlphaMap = 1 shl 1; + CPAlphaXOrigin = 1 shl 2; + CPAlphaYOrigin = 1 shl 3; + CPClipXOrigin = 1 shl 4; + CPClipYOrigin = 1 shl 5; + CPClipMask = 1 shl 6; + CPGraphicsExposure = 1 shl 7; + CPSubwindowMode = 1 shl 8; + CPPolyEdge = 1 shl 9; + CPPolyMode = 1 shl 10; + CPDither = 1 shl 11; + CPComponentAlpha = 1 shl 12; + CPLastBit = 11; + { Filters included in 0.6 } + FilterNearest = 'nearest'; + FilterBilinear = 'bilinear'; + FilterFast = 'fast'; + FilterGood = 'good'; + FilterBest = 'best'; + FilterAliasNone = -(1); + { Subpixel orders included in 0.6 } + SubPixelUnknown = 0; + SubPixelHorizontalRGB = 1; + SubPixelHorizontalBGR = 2; + SubPixelVerticalRGB = 3; + SubPixelVerticalBGR = 4; + SubPixelNone = 5; + +type + TXRenderDirectFormat = record + red : smallint; + redMask : smallint; + green : smallint; + greenMask : smallint; + blue : smallint; + blueMask : smallint; + alpha : smallint; + alphaMask : smallint; + end; + PXRenderDirectFormat = ^TXRenderDirectFormat; + + TXRenderPictFormat = record + id : TPictFormat; + _type : longint; + depth : longint; + direct : TXRenderDirectFormat; + colormap : TColormap; + end; + PXRenderPictFormat = ^TXRenderPictFormat; + + const + PictFormatID = 1 shl 0; + PictFormatType = 1 shl 1; + PictFormatDepth = 1 shl 2; + PictFormatRed = 1 shl 3; + PictFormatRedMask = 1 shl 4; + PictFormatGreen = 1 shl 5; + PictFormatGreenMask = 1 shl 6; + PictFormatBlue = 1 shl 7; + PictFormatBlueMask = 1 shl 8; + PictFormatAlpha = 1 shl 9; + PictFormatAlphaMask = 1 shl 10; + PictFormatColormap = 1 shl 11; + RepeatNone = 0; + RepeatNormal = 1; + RepeatPad = 2; + RepeatReflect = 2; + + type + + TXRenderPictureAttributes = record + _repeat : TBool; + alpha_map : TPicture; + alpha_x_origin : longint; + alpha_y_origin : longint; + clip_x_origin : longint; + clip_y_origin : longint; + clip_mask : TPixmap; + graphics_exposures : TBool; + subwindow_mode : longint; + poly_edge : longint; + poly_mode : longint; + dither : TAtom; + component_alpha : TBool; + end; + PXRenderPictureAttributes = ^TXRenderPictureAttributes; + + TXRenderColor = record + red : word; + green : word; + blue : word; + alpha : word; + end; + PXRenderColor = ^TXRenderColor; + + TXGlyphInfo = record + width : word; + height : word; + x : smallint; + y : smallint; + xOff : smallint; + yOff : smallint; + end; + PXGlyphInfo = ^TXGlyphInfo; + + TXGlyphElt8 = record + glyphset : TGlyphSet; + chars : ^char; + nchars : longint; + xOff : longint; + yOff : longint; + end; + PXGlyphElt8 = ^TXGlyphElt8; + + TXGlyphElt16 = record + glyphset : TGlyphSet; + chars : ^word; + nchars : longint; + xOff : longint; + yOff : longint; + end; + PXGlyphElt16 = TXGlyphElt16; + + TXGlyphElt32 = record + glyphset : TGlyphSet; + chars : ^dword; + nchars : longint; + xOff : longint; + yOff : longint; + end; + PXGlyphElt32 = ^TXGlyphElt32; + + TXDouble = Tdouble; + + TXPointDouble = record + x : TXDouble; + y : TXDouble; + end; + PXPointDouble = ^TXPointDouble; + + TXPointFixed = record + x : TXFixed; + y : TXFixed; + end; + PXPointFixed = ^TXPointFixed; + + TXLineFixed = record + p1 : TXPointFixed; + p2 : TXPointFixed; + end; + PXLineFixed = ^TXLineFixed; + + TXTriangle = record + p1 : TXPointFixed; + p2 : TXPointFixed; + p3 : TXPointFixed; + end; + PXTriangle = ^TXTriangle; + + TXTrapezoid = record + top : TXFixed; + bottom : TXFixed; + left : TXLineFixed; + right : TXLineFixed; + end; + PXTrapezoid = ^TXTrapezoid; + + TXTransform = array[0..2] //row + of array[0..2] of TXFixed; //col + //m00,m01,0 + //m10,m11,0 x' = m00 * x + m01 * y + dx + //dx, dy, 1 y' = m11 * y + m10 * x + dy + + PXTransform = ^TXTransform; + + TXFilters = record + nfilter : longint; + filter : PPchar; + nalias : longint; + alias : ^smallint; + end; + PXFilters = ^TXFilters; + + TXIndexValue = record + pixel : culong; + red : word; + green : word; + blue : word; + alpha : word; + end; + PXIndexValue = ^TXIndexValue; + + TXAnimCursor = record + cursor : TCursor; + delay : culong; + end; + PXAnimCursor = ^TXAnimCursor; + + const + PictStandardARGB32 = 0; + PictStandardRGB24 = 1; + PictStandardA8 = 2; + PictStandardA4 = 3; + PictStandardA1 = 4; + PictStandardNUM = 5; + +{$ifdef staticxrender} + + function XRenderQueryExtension(dpy: PDisplay; event_basep: Pinteger; + error_basep: Pinteger): TBool; + cdecl;external External_library name 'XRenderQueryExtension'; + + function XRenderQueryVersion(dpy:PDisplay; major_versionp:Plongint; + minor_versionp:Plongint):TStatus; + cdecl;external External_library name 'XRenderQueryVersion'; + + function XRenderQueryFormats(dpy:PDisplay):TStatus; + cdecl;external External_library name 'XRenderQueryFormats'; + + function XRenderQuerySubpixelOrder(dpy:PDisplay; screen:longint):longint; + cdecl;external External_library name 'XRenderQuerySubpixelOrder'; + + function XRenderSetSubpixelOrder(dpy: PDisplay; screen: longint; + subpixel: longint): TBool; cdecl; + external External_library name 'XRenderSetSubpixelOrder'; + + function XRenderFindVisualFormat(dpy: PDisplay; + visual: PVisual): PXRenderPictFormat; cdecl; + external External_library name 'XRenderFindVisualFormat'; + + function XRenderFindFormat(dpy: PDisplay; mask: culong; + templ: PXRenderPictFormat; count: longint): PXRenderPictFormat; cdecl; + external External_library name 'XRenderFindFormat'; + + + function XRenderFindStandardFormat(dpy:PDisplay; + format:longint):PXRenderPictFormat; + cdecl;external External_library name 'XRenderFindStandardFormat'; + +function XRenderQueryPictIndexValues(dpy:PDisplay; format:PXRenderPictFormat; + num:Plongint):PXIndexValue; + cdecl;external External_library name 'XRenderQueryPictIndexValues'; + +function XRenderCreatePicture(dpy:PDisplay; drawable:TDrawable; + format:PXRenderPictFormat; valuemask:culong; + attributes:PXRenderPictureAttributes):TPicture; + cdecl;external External_library name 'XRenderCreatePicture'; + +procedure XRenderFreePicture(dpy:PDisplay; picture:TPicture); + cdecl;external External_library name 'XRenderFreePicture'; + +procedure XRenderChangePicture(dpy:PDisplay; picture:TPicture; + valuemask:culong; attributes:PXRenderPictureAttributes); + cdecl;external External_library name 'XRenderChangePicture'; + +procedure XRenderSetPictureClipRectangles(dpy:PDisplay; picture:TPicture; + xOrigin:longint; yOrigin:longint; rects:PXRectangle; n:longint); + cdecl;external External_library name 'XRenderSetPictureClipRectangles'; + +procedure XRenderSetPictureClipRegion(dpy:PDisplay; picture:TPicture; r:TRegion); + cdecl;external External_library name 'XRenderSetPictureClipRegion'; + +procedure XRenderSetPictureTransform(dpy:PDisplay; picture:TPicture; transform:PXTransform); + cdecl;external External_library name 'XRenderSetPictureTransform'; + + +procedure XRenderComposite(dpy:PDisplay; op:longint; src:TPicture; mask:TPicture; dst:TPicture; + src_x:longint; src_y:longint; mask_x:longint; mask_y:longint; dst_x:longint; + dst_y:longint; width:dword; height:dword);cdecl;external External_library name 'XRenderComposite'; + + function XRenderCreateGlyphSet(dpy:PDisplay; format:PXRenderPictFormat):TGlyphSet;cdecl;external External_library name 'XRenderCreateGlyphSet'; + + function XRenderReferenceGlyphSet(dpy:PDisplay; existing:TGlyphSet):TGlyphSet;cdecl;external External_library name 'XRenderReferenceGlyphSet'; + + procedure XRenderFreeGlyphSet(dpy:PDisplay; glyphset:TGlyphSet);cdecl;external External_library name 'XRenderFreeGlyphSet'; + + procedure XRenderAddGlyphs(dpy:PDisplay; glyphset:TGlyphSet; gids:PGlyph; glyphs:PXGlyphInfo; nglyphs:longint; + images:Pchar; nbyte_images:longint);cdecl;external External_library name 'XRenderAddGlyphs'; + + procedure XRenderFreeGlyphs(dpy:PDisplay; glyphset:TGlyphSet; gids:PGlyph; nglyphs:longint);cdecl;external External_library name 'XRenderFreeGlyphs'; + + procedure XRenderCompositeString8(dpy:PDisplay; op:longint; src:TPicture; dst:TPicture; maskFormat:PXRenderPictFormat; + glyphset:TGlyphSet; xSrc:longint; ySrc:longint; xDst:longint; yDst:longint; + _string:Pchar; nchar:longint);cdecl;external External_library name 'XRenderCompositeString8'; + + procedure XRenderCompositeString16(dpy:PDisplay; op:longint; src:TPicture; dst:TPicture; maskFormat:PXRenderPictFormat; + glyphset:TGlyphSet; xSrc:longint; ySrc:longint; xDst:longint; yDst:longint; + _string:Pword; nchar:longint);cdecl;external External_library name 'XRenderCompositeString16'; + + procedure XRenderCompositeString32(dpy:PDisplay; op:longint; src:TPicture; dst:TPicture; maskFormat:PXRenderPictFormat; + glyphset:TGlyphSet; xSrc:longint; ySrc:longint; xDst:longint; yDst:longint; + _string:Pdword; nchar:longint);cdecl;external External_library name 'XRenderCompositeString32'; + + procedure XRenderCompositeText8(dpy:PDisplay; op:longint; src:TPicture; dst:TPicture; maskFormat:PXRenderPictFormat; + xSrc:longint; ySrc:longint; xDst:longint; yDst:longint; elts:PXGlyphElt8; + nelt:longint);cdecl;external External_library name 'XRenderCompositeText8'; + + procedure XRenderCompositeText16(dpy:PDisplay; op:longint; src:TPicture; dst:TPicture; maskFormat:PXRenderPictFormat; + xSrc:longint; ySrc:longint; xDst:longint; yDst:longint; elts:PXGlyphElt16; + nelt:longint);cdecl;external External_library name 'XRenderCompositeText16'; + + procedure XRenderCompositeText32(dpy:PDisplay; op:longint; src:TPicture; dst:TPicture; maskFormat:PXRenderPictFormat; + xSrc:longint; ySrc:longint; xDst:longint; yDst:longint; elts:PXGlyphElt32; + nelt:longint);cdecl;external External_library name 'XRenderCompositeText32'; + + procedure XRenderFillRectangle(dpy:PDisplay; op:longint; dst:TPicture; color:PXRenderColor; x:longint; + y:longint; width:dword; height:dword);cdecl;external External_library name 'XRenderFillRectangle'; + + procedure XRenderFillRectangles(dpy:PDisplay; op:longint; dst:TPicture; color:PXRenderColor; rectangles:PXRectangle; + n_rects:longint);cdecl;external External_library name 'XRenderFillRectangles'; + + procedure XRenderCompositeTrapezoids(dpy:PDisplay; op:longint; src:TPicture; dst:TPicture; maskFormat:PXRenderPictFormat; + xSrc:longint; ySrc:longint; traps:PXTrapezoid; ntrap:longint);cdecl;external External_library name 'XRenderCompositeTrapezoids'; + + procedure XRenderCompositeTriangles(dpy:PDisplay; op:longint; src:TPicture; dst:TPicture; maskFormat:PXRenderPictFormat; + xSrc:longint; ySrc:longint; triangles:PXTriangle; ntriangle:longint);cdecl;external External_library name 'XRenderCompositeTriangles'; + + procedure XRenderCompositeTriStrip(dpy:PDisplay; op:longint; src:TPicture; dst:TPicture; maskFormat:PXRenderPictFormat; + xSrc:longint; ySrc:longint; points:PXPointFixed; npoint:longint);cdecl;external External_library name 'XRenderCompositeTriStrip'; + + procedure XRenderCompositeTriFan(dpy:PDisplay; op:longint; src:TPicture; dst:TPicture; maskFormat:PXRenderPictFormat; + xSrc:longint; ySrc:longint; points:PXPointFixed; npoint:longint);cdecl;external External_library name 'XRenderCompositeTriFan'; + +// procedure XRenderCompositeDoublePoly(dpy:PDisplay; op:longint; src:TPicture; dst:TPicture; maskFormat:PXRenderPictFormat; +// xSrc:longint; ySrc:longint; xDst:longint; yDst:longint; fpoints:PXPointDouble; +// npoints:longint; winding:longint);cdecl;external External_library name 'XRenderCompositeDoublePoly'; + + function XRenderParseColor(dpy:PDisplay; spec:Pchar; def:PXRenderColor):TStatus;cdecl;external External_library name 'XRenderParseColor'; + + function XRenderCreateCursor(dpy:PDisplay; source:TPicture; x:dword; y:dword):TCursor;cdecl;external External_library name 'XRenderCreateCursor'; + + function XRenderQueryFilters(dpy:PDisplay; drawable:TDrawable):PXFilters;cdecl;external External_library name 'XRenderQueryFilters'; + + procedure XRenderSetPictureFilter(dpy:PDisplay; picture:TPicture; filter:Pchar; params:PXFixed; nparams:longint);cdecl;external External_library name 'XRenderSetPictureFilter'; + + function XRenderCreateAnimCursor(dpy:PDisplay; ncursor:longint; cursors:PXAnimCursor):TCursor;cdecl;external External_library name 'XRenderCreateAnimCursor'; + +{$endif staticxrender} + + //macros + + function XDoubleToFixed(f : TXDouble) : TXFixed; +//#define XDoubleToFixed(f) ((XFixed) ((f) * 65536)) + + function XFixedToDouble(f : TXFixed) : TXDouble; +//#define XFixedToDouble(f) (((XDouble) (f)) / 65536) + +implementation + + function XDoubleToFixed(f : TXDouble) : TXFixed; + begin + XDoubleToFixed:= round(f * 65536); + end; + + function XFixedToDouble(f : TXFixed) : TXDouble; + begin + XFixedToDouble:= f / 65536; + end; + + +end. diff --git a/mseide-msegui/lib/common/kernel/linux/sm.pas b/mseide-msegui/lib/common/kernel/linux/sm.pas new file mode 100644 index 0000000..92504e6 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/linux/sm.pas @@ -0,0 +1,197 @@ + +unit sm; +interface +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +{$IFDEF FPC} + {$PACKRECORDS C} +{$else} + {$ALIGN 4} + {$MINENUMSIZE 4} +{$ENDIF} + + + { $Xorg: SM.h,v 1.4 2001/02/09 02:03:30 xorgcvs Exp $ } + { + + Copyright 1993, 1998 The Open Group + + Permission to use, copy, modify, distribute, and sell this software and its + documentation for any purpose is hereby granted without fee, provided that + the above copyright notice appear in all copies and that both that + copyright notice and this permission notice appear in supporting + documentation. + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the name of The Open Group shall not be + used in advertising or otherwise to promote the sale, use or other dealings + in this Software without prior written authorization from The Open Group. + + } + { + * Author: Ralph Mor, X Consortium + } + { + * Protocol Version + } + + const + SmProtoMajor = 1; + SmProtoMinor = 0; + { + * Interact Style + } + SmInteractStyleNone = 0; + SmInteractStyleErrors = 1; + SmInteractStyleAny = 2; + { + * Dialog Type + } + SmDialogError = 0; + SmDialogNormal = 1; + { + * Save Type + } + SmSaveGlobal = 0; + SmSaveLocal = 1; + SmSaveBoth = 2; + { + * Restart Style Hints + } + SmRestartIfRunning = 0; + SmRestartAnyway = 1; + SmRestartImmediately = 2; + SmRestartNever = 3; + { + * Property names + } + SmCloneCommand = 'CloneCommand'; + SmCurrentDirectory = 'CurrentDirectory'; + SmDiscardCommand = 'DiscardCommand'; + SmEnvironment = 'Environment'; + SmProcessID = 'ProcessID'; + SmProgram = 'Program'; + SmRestartCommand = 'RestartCommand'; + SmResignCommand = 'ResignCommand'; + SmRestartStyleHint = 'RestartStyleHint'; + SmShutdownCommand = 'ShutdownCommand'; + SmUserID = 'UserID'; + { + * Property types + } + SmCARD8 = 'CARD8'; + SmARRAY8 = 'ARRAY8'; + SmLISTofARRAY8 = 'LISTofARRAY8'; + { + * SM minor opcodes + } + SM_Error = 0; + SM_RegisterClient = 1; + SM_RegisterClientReply = 2; + SM_SaveYourself = 3; + SM_SaveYourselfRequest = 4; + SM_InteractRequest = 5; + SM_Interact = 6; + SM_InteractDone = 7; + SM_SaveYourselfDone = 8; + SM_Die = 9; + SM_ShutdownCancelled = 10; + SM_CloseConnection = 11; + SM_SetProperties = 12; + SM_DeleteProperties = 13; + SM_GetProperties = 14; + SM_PropertiesReply = 15; + SM_SaveYourselfPhase2Request = 16; + SM_SaveYourselfPhase2 = 17; + SM_SaveComplete = 18; + { _SM_H_ } + SmcSaveYourselfProcMask = 1 shl 0; + SmcDieProcMask = 1 shl 1; + SmcSaveCompleteProcMask = 1 shl 2; + SmcShutdownCancelledProcMask = 1 shl 3; + +type + bool = integer;{longbool} //protocoll does not accept -1 for true + Status = integer; + SmPointer = pointer; + SmcConn = pointer; + SmcCloseStatus = (SmcClosedNow,SmcClosedASAP,SmcConnectionInUse); + + SmcSaveYourselfProc = procedure(_smcConn: SmcConn; clientData: pointer; + saveType: integer; shutdown: bool; + interactStyle: integer; fast: bool); cdecl; + SmcDieProc = procedure(_smcConn: SmcConn; clientData: pointer); cdecl; + SmcSaveCompleteProc = procedure(_smcConn: SmcConn; clientData: pointer); cdecl; + SmcShutdownCancelledProc = procedure(_smcConn: SmcConn; + clientData: pointer); cdecl; + + SmcCallbacks = record + save_yourself: record + callback: SmcSaveYourselfProc; + client_data: pointer; + end; + die: record + callback: SmcDieProc; + client_data: pointer; + end; + save_complete: record + callback: SmcSaveCompleteProc; + client_data: pointer; + end; + shutdown_cancelled: record + callback: SmcShutdownCancelledProc; + client_data: pointer; + end; + end; + + SmcInteractProc = procedure(_smcConn: SmcConn; clientData: SmPointer); cdecl; + +var + SmcOpenConnection: function(networkIdsList: pchar; context: Pointer; + xsmpMajorRev: integer; xsmpMinorRev: integer; + mask: longword; var callbacks: SmcCallbacks; + previousId: pchar; var clientIdRet: pchar; + errorLength: integer; errorStringRet: pchar): SmcConn; cdecl; + SmcCloseConnection: function(_smcConn: SmcConn; + count: integer; reasonMsgs: ppchar): SmcCloseStatus; cdecl; + SmcSaveYourselfDone: procedure(_smcConn: SmcConn; success: Bool); cdecl; + SmcInteractRequest: function(_smcConn: SmcConn; dialogType: integer; + interactProc: SmcInteractProc; clientData: SmPointer): Status; + cdecl; + SmcInteractDone: procedure(_smcConn: SmcConn; cancelShutdown: Bool); cdecl; + +function getsmlib: boolean; + +implementation +uses + msesys,msesonames,msedynload; + +function getsmlib: boolean; +begin + result:= checkprocaddresses(smnames, + [ + 'SmcOpenConnection', //0 + 'SmcCloseConnection', //1 + 'SmcSaveYourselfDone', //2 + 'SmcInteractRequest', //3 + 'SmcInteractDone' //4 + ], + [ + {$ifndef FPC}@{$endif}@SmcOpenConnection, //0 + {$ifndef FPC}@{$endif}@SmcCloseConnection, //1 + {$ifndef FPC}@{$endif}@SmcSaveYourselfDone, //2 + {$ifndef FPC}@{$endif}@SmcInteractRequest, //3 + {$ifndef FPC}@{$endif}@SmcInteractDone //4 + ]); +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/mseact.pas b/mseide-msegui/lib/common/kernel/mseact.pas new file mode 100644 index 0000000..408acf3 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseact.pas @@ -0,0 +1,1472 @@ +{ MSEgui Copyright (c) 1999-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseact; +{$ifdef FPC} + {$mode objfpc}{$h+}{$interfaces corba} +{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,mseclasses,mserichstring, + msetypes,mseglob,mseapplication, mseevent,msestat,msestatfile,msestrings, + typinfo,msegraphutils,mseinterfaces + {$ifdef mse_with_ifi},mseifiglob,mseificomp,mseificompglob{$endif}; + +const + defaultactionstates = []; +type + shapestatety = (shs_disabled,shs_invisible,shs_checked,shs_default, + //actionstatesty + + shs_separator,shs_optional, //for menu separators + shs_checkbox,shs_radiobutton, + //menuactionoptionty + + shs_clicked,shs_mouse,shs_moveclick,shs_focused,shs_active, + shs_suppressed, + shs_horz,shs_vert,shs_opposite,shs_ellipsemouse, + shs_widgetorg,shs_showfocusrect,shs_showdefaultrect, + shs_flat,shs_noanimation,shs_nomouseanimation, + shs_noclickanimation,shs_nofocusanimation,shs_focusanimation, + shs_focuscolor, + //use cl_selectedtext and cl_selecetetextbackground + //if focused + shs_checkbutton,shs_menuarrow,shs_noinnerrect); + shapestatesty = set of shapestatety; + + actionstatety = (as_disabled = ord(shs_disabled),as_invisible=ord(shs_invisible), + as_checked=ord(shs_checked),as_default=ord(shs_default), + as_repeatshortcut, + as_localdisabled,as_localinvisible,as_localchecked,as_localdefault, + as_localrepeatshortcut, + as_localcaption, + as_localimagelist,as_localimagenr,as_localimagenrdisabled, + as_localimagecheckedoffset, + as_localcolorglyph,as_localcolor, + as_localhint,as_localshortcut,as_localshortcut1,as_localtag, + as_localgroup,as_localonbeforeexecute,as_localonexecute, + as_localonafterexecute,as_syncdisabledlocked); + actionstatesty = set of actionstatety; + actionstatesarty = array of actionstatesty; + + menuactionoptionty = (mao_separator, + mao_optional, //suppress separators without adjacent + //visible normal items + mao_checkbox,mao_radiobutton, + + mao_shortcutcaption, + mao_asyncexecute,mao_singleregion, + mao_showhint,mao_noshowhint, + mao_nocandefocus); + menuactionoptionsty = set of menuactionoptionty; + +const + invisibleactionstates = [ord(as_syncdisabledlocked)]; + actionstatesmask: actionstatesty = + [as_disabled,as_checked,as_invisible,as_default, + as_repeatshortcut]; + actionshapestatesconst = [as_disabled,as_invisible,as_checked,as_default]; + actionshapestates: actionstatesty = actionshapestatesconst; + actionoptionshapestates: menuactionoptionsty = + [mao_separator,mao_optional,mao_checkbox,mao_radiobutton]; + actionoptionshapelshift = ord(shs_separator); + + localactionstates: actionstatesty = + [as_localdisabled,as_localinvisible,as_localchecked,as_localdefault, + as_localrepeatshortcut, + as_localcaption, + as_localimagelist,as_localimagenr,as_localimagenrdisabled, + as_localimagecheckedoffset, + as_localcolorglyph,as_localcolor, + as_localhint,as_localshortcut,as_localshortcut1,as_localtag, + as_localgroup,as_localonbeforeexecute,as_localonexecute, + as_localonafterexecute]; + localactionlshift = ord(as_localdisabled); + localactionstatestates: actionstatesty = + [as_localdisabled,as_localinvisible,as_localchecked,as_localdefault, + as_localrepeatshortcut]; +type + actionoptionty = (ao_updateonidle,ao_localshortcut,ao_globalshortcut, + ao_nocandefocus); +const + defaultactionoptions = []; + +type + tcustomaction = class; + actioneventty = procedure(const sender: tcustomaction) of object; + + actioninfoty = record + action: tcustomaction; + captiontext: msestring; + caption1: richstringty; + state: actionstatesty; + options: menuactionoptionsty; + shortcut: shortcutarty; + shortcut1: shortcutarty; + group: integer; + imagenr: imagenrty; //imagenrty; + imagenrdisabled: imagenrty; //-2 -> grayed + colorglyph: colorty; + color: colorty; + imagecheckedoffset: integer; + imagelist: tobject; //timagelist + hint: msestring; + tag: integer; + tagpo: pointer; + onexecute: notifyeventty; + onbeforeexecute: accepteventty; + onafterexecute: notifyeventty; + end; + pactioninfoty = ^actioninfoty; + + iactionlink = interface(iobjectlink)[miid_iactionlink] + function getactioninfopo: pactioninfoty; + procedure actionchanged; + function loading: boolean; + function shortcutseparator: msechar; + procedure calccaptiontext(var ainfo: actioninfoty); + procedure setshortcuts(const avalue: shortcutarty); + procedure setshortcuts1(const avalue: shortcutarty); + end; + + asynceventty = procedure(const sender: tobject; var atag: integer) of object; + + actionoptionsty = set of actionoptionty; + + tcustomaction = class(tactcomponent,istatfile{,iimagelistinfo} + {$ifdef mse_with_ifi},iifiexeclink{$endif}) + private + fonupdate: actioneventty; + fstatvarname: msestring; + fstatfile: tstatfile; + fonchange: notifyeventty; + fonasyncevent: asynceventty; + fonexecuteaction: actioneventty; + fstatpriority: integer; +{$ifdef mse_with_ifi} + fifilink: tifiactionlinkcomp; + function getifilinkkind: ptypeinfo; + procedure setifilink(const avalue: tifiactionlinkcomp); overload; +{$endif} + function getcaption: captionty; + procedure setcaption(const Value: captionty); + procedure setonexecute(const avalue: notifyeventty); + procedure setonbeforeexecute(const avalue: accepteventty); + procedure setonafterexecute(const avalue: notifyeventty); + procedure setimagenr(const Value: imagenrty); + procedure setimagenrdisabled(const avalue: imagenrty); + procedure setcolorglyph(const avalue: colorty); + procedure setcolor(const avalue: colorty); + procedure setimagecheckedoffset(const Value: integer); + function getstate: actionstatesty; + procedure setstate(const Value: actionstatesty); + function getgroup: integer; + procedure setgroup(const Value: integer); + procedure sethint(const Value: msestring); + procedure settag(const Value: integer); + function getenabled: boolean; + procedure setenabled(const avalue: boolean); + procedure ifisetenabled(const avalue: boolean); + procedure doupdateinfo(const info: linkinfoty); + procedure dounlinkaction(const info: linkinfoty); + function getchecked: boolean; + procedure setchecked(const Value: boolean); + procedure setoptions(const Value: actionoptionsty); + procedure setstatfile(const Value: tstatfile); + function getvisible: boolean; + procedure setvisible(const avalue: boolean); + protected + finfo: actioninfoty; + foptions: actionoptionsty; + procedure registeronshortcut(const avalue: boolean); virtual; + procedure loaded; override; + procedure changed; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + procedure receiveevent(const event: tobjectevent) override; + procedure doidle(var again: boolean); + procedure doasyncevent(var atag: integer); override; + procedure eventfired(const sender: tobject; const ainfo: actioninfoty); + procedure doafterunlink; virtual; + + //istatfile, saves state of as_checked + procedure dostatread(const reader: tstatreader); + procedure dostatwrite(const writer: tstatwriter); + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + + //iimagelistinfo +// function getimagelist: timagelist; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure doupdate; + procedure execute(const force: boolean = false); + procedure asyncexecute(); + procedure updateinfo(const sender: iactionlink); + property caption: captionty read getcaption write setcaption; + property state: actionstatesty read getstate write setstate default []; + property visible: boolean read getvisible write setvisible; + property enabled: boolean read getenabled write setenabled; + property checked: boolean read getchecked write setchecked; + property group: integer read getgroup write setgroup default 0; + property imagenr: imagenrty read finfo.imagenr write setimagenr default -1; + property imagenrdisabled: imagenrty read finfo.imagenrdisabled + write setimagenrdisabled default -2; + property colorglyph: colorty read finfo.colorglyph + write setcolorglyph default cl_default; + property color: colorty read finfo.color write setcolor default cl_default; + property imagecheckedoffset: integer read finfo.imagecheckedoffset + write setimagecheckedoffset default 0; + property hint: msestring read finfo.hint write sethint; + property tagaction: integer read finfo.tag write settag default 0; + property options: actionoptionsty read foptions write setoptions + default defaultactionoptions; + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read getstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; +{$ifdef mse_with_ifi} + property ifilink: tifiactionlinkcomp read fifilink write setifilink; +{$endif} + + property onexecute: notifyeventty read finfo.onexecute write setonexecute; + property onbeforeexecute: accepteventty read finfo.onbeforeexecute + write setonbeforeexecute; + property onafterexecute: notifyeventty read finfo.onafterexecute + write setonafterexecute; + property onexecuteaction: actioneventty read fonexecuteaction write fonexecuteaction; + property onupdate: actioneventty read fonupdate write fonupdate; + property onchange: notifyeventty read fonchange write fonchange; + property onasyncevent: asynceventty read fonasyncevent write fonasyncevent; + end; + + tnoguiaction = class(tcustomaction) + protected + published + property caption; + property state; + property group; + property tagaction; +// property imagelist; + property imagenr; + property imagenrdisabled; + property colorglyph; + property color; + property imagecheckedoffset; + property hint; +// property shortcut; + property statfile; + property statvarname; + property statpriority; + property options; + property onexecute; + property onbeforeexecute; + property onafterexecute; + property onupdate; + property onchange; + property onasyncevent; +{$ifdef mse_with_ifi} + property ifilink; +{$endif} + end; + +procedure linktoaction(const sender: iactionlink; const aaction: tcustomaction; + var info: actioninfoty); + //remove existing link, copy action to instance +procedure setactionchecked(const sender: iactionlink; const value: boolean); +procedure setactioncaption(const sender: iactionlink; const value: msestring); +function isactioncaptionstored(const info: actioninfoty): boolean; + +procedure setactionimagenr(const sender: iactionlink; const value: integer); +function isactionimagenrstored(const info: actioninfoty): boolean; +procedure setactionimagenrdisabled(const sender: iactionlink; + const value: integer); +function isactionimagenrdisabledstored(const info: actioninfoty): boolean; +procedure setactioncolorglyph(const sender: iactionlink; const value: colorty); +function isactioncolorglyphstored(const info: actioninfoty): boolean; +procedure setactioncolor(const sender: iactionlink; const value: colorty); +function isactioncolorstored(const info: actioninfoty): boolean; +procedure setactionimagecheckedoffset(const sender: iactionlink; + const value: integer); +function isactionimagecheckedoffsetstored(const info: actioninfoty): boolean; +procedure setactionhint(const sender: iactionlink; const value: msestring); +function isactionhintstored(const info: actioninfoty): boolean; +procedure setactiontag(const sender: iactionlink; const value: integer); +function isactiontagstored(const info: actioninfoty): boolean; + +procedure setactionstate(const sender: iactionlink; + const value: actionstatesty); +function isactionstatestored(const info: actioninfoty): boolean; + +procedure setactionoptions(const sender: iactionlink; + const value: menuactionoptionsty); + +procedure setactiongroup(const sender: iactionlink; const value: integer); +function isactiongroupstored(const info: actioninfoty): boolean; +procedure setactiononexecute(const sender: iactionlink; + const value: notifyeventty; const aloading: boolean); +function isactiononexecutestored(const info: actioninfoty): boolean; +procedure setactiononbeforeexecute(const sender: iactionlink; + const value: accepteventty; const aloading: boolean); +function isactiononbeforeexecutestored(const info: actioninfoty): boolean; +procedure setactiononafterexecute(const sender: iactionlink; + const value: notifyeventty; const aloading: boolean); +function isactiononafterexecutestored(const info: actioninfoty): boolean; + +procedure actionbeginload(const sender: iactionlink); +procedure actionendload(const sender: iactionlink); + +function doactionexecute(const sender: tobject; var info: actioninfoty; + const nocheckbox: boolean = false; + const nocandefocus: boolean = false; + const beforeexecute: proceventty = nil; + const force: boolean = false): boolean; + //true if local checked changed +function doactionexecute1(const sender: tobject; var info: actioninfoty; + out changed: boolean; + const nocheckbox: boolean = false; + const nocandefocus: boolean = false; + const beforeexecute: proceventty = nil; + const force: boolean = false): boolean; + //true if not canceled + +procedure initactioninfo(var info: actioninfoty; + aoptions: menuactionoptionsty = []); +procedure actionstatestoshapestates(const source: actioninfoty; + var dest: shapestatesty); +procedure shapestatestoactionstates(source: shapestatesty; + var dest: actionstatesty; + const mask: actionstatesty = actionshapestatesconst); +function translateshortcut(const akey: shortcutty): shortcutty; +procedure translateshortcut1(var akey: shortcutty); + //update for new modifier layout + +var + assistiveexechandler: procedure(const sender: tobject; + const info: actioninfoty); +implementation +uses + msebits,sysutils,msekeyboard; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +procedure translateshortcut1(var akey: shortcutty); +begin + if akey and $1000 <> 0 then begin //update for new modifier layout + akey:= akey and not $1000 or $0100; + end; +end; + +function translateshortcut(const akey: shortcutty): shortcutty; +begin + result:= akey; + translateshortcut1(result); +end; + +function doactionexecute1(const sender: tobject; var info: actioninfoty; + out changed: boolean; + const nocheckbox: boolean = false; + const nocandefocus: boolean = false; + const beforeexecute: proceventty = nil; + const force: boolean = false): boolean; + //true if not canceled +var + bo1: boolean; +begin + result:= false; + changed:= false; + with info do begin + if not (as_disabled in state) or force then begin + if not nocandefocus and + ((action = nil) or not(ao_nocandefocus in action.options)) then begin + if not application.candefocus then begin + exit; + end; + end; + if checkcanevent(tmethod(info.onbeforeexecute)) then begin + bo1:= true; + info.onbeforeexecute(sender,bo1); + if not bo1 then begin + exit; + end; + end; + if not nocheckbox then begin + if (mao_checkbox in info.options) then begin + if action <> nil then begin + action.checked:= not action.checked; + end + else begin + togglebit1(longword(info.state),ord(as_checked)); + changed:= true; + end; + end + else begin + if mao_radiobutton in info.options then begin + if action <> nil then begin + action.checked:= true; + end + else begin + if not checkbit(longword(info.state),ord(as_checked)) then begin + setbit1(longword(info.state),ord(as_checked)); + changed:= true; + end; + end; + end; + end; + end; + if assigned(assistiveexechandler) then begin + assistiveexechandler(sender,info); + end; + if assigned(beforeexecute) then begin + beforeexecute; + end; + if checkcanevent(tmethod(info.onexecute)) then begin + info.onexecute(sender); + end; + if info.action <> nil then begin + info.action.eventfired(sender,info); + end; + if checkcanevent(tmethod(info.onafterexecute)) then begin + info.onafterexecute(sender); + end; + result:= true; + end; + end; +end; + +function doactionexecute(const sender: tobject; var info: actioninfoty; + const nocheckbox: boolean = false; + const nocandefocus: boolean = false; + const beforeexecute: proceventty = nil; + const force: boolean = false): boolean; + //true if local checked changed +begin + doactionexecute1(sender,info,result,nocheckbox,nocandefocus,beforeexecute, + force); +end; + +procedure actionstatestoshapestates(const source: actioninfoty; var dest: shapestatesty); +begin + dest:= shapestatesty(replacebits({$ifdef FPC}longword{$else}longword{$endif}(source.state), + {$ifdef FPC}longword{$else}longword{$endif}(dest), + {$ifdef FPC}longword{$else}longword{$endif}(actionshapestates))); + dest:= shapestatesty(replacebits( + {$ifdef FPC}longword{$else}word{$endif}( + {$ifdef FPC}longword{$else}word{$endif}(source.options) + shl {$ifdef FPC}longword{$else}word{$endif}(actionoptionshapelshift) + ), + {$ifdef FPC}longword{$else}longword{$endif}(dest), + {$ifdef FPC}longword{$else}word{$endif}( + {$ifdef FPC}longword{$else}word{$endif}(actionoptionshapestates) + shl {$ifdef FPC}longword{$else}longword{$endif}(actionoptionshapelshift)) + ) + ); +end; + +procedure shapestatestoactionstates(source: shapestatesty; var dest: actionstatesty; + const mask: actionstatesty = actionshapestatesconst); +begin + dest:= actionstatesty(replacebits({$ifdef FPC}longword{$else}longword{$endif}(source), + {$ifdef FPC}longword{$else}longword{$endif}(dest), + {$ifdef FPC}longword{$else}longword{$endif}(actionshapestates*mask))); +end; + +procedure resetlocalstates(var states: actionstatesty); +begin + states:= states - localactionstates; +end; + +procedure setlocalstates(var states: actionstatesty); +begin + states:= states + localactionstates; +end; + +procedure initactioninfo(var info: actioninfoty; + aoptions: menuactionoptionsty = []); +begin + with info do begin + imagenr:= -1; + imagenrdisabled:= -2; + options:= aoptions; + colorglyph:= cl_default; + color:= cl_default; + end; +end; + +procedure actionbeginload(const sender: iactionlink); +begin +// include(sender.getactioninfopo^.options,mao_loading); +end; + +procedure actionendload(const sender: iactionlink); +var + p1: pactioninfoty; + b1: boolean; +begin + p1:= sender.getactioninfopo(); + b1:= as_syncdisabledlocked in p1^.state; + include(p1^.state,as_syncdisabledlocked); + try +// exclude(sender.getactioninfopo^.options,mao_loading); + sender.actionchanged; + finally + if not b1 then begin + exclude(p1^ .state,as_syncdisabledlocked); + end; + end; +end; + +procedure linktoaction(const sender: iactionlink; const aaction: tcustomaction; + var info: actioninfoty); +//var +// sepchar: msechar; +begin + with info do begin + if aaction <> action then begin + setlinkedcomponent(sender,aaction,tmsecomponent(action),typeinfo(iactionlink)); + if action <> nil then begin + action.updateinfo(sender); + end + else begin + if state * localactionstates <> localactionstates then begin + // sepchar:= sender.shortcutseparator; + if not (as_localcaption in state) then begin + captiontext:= ''; + sender.calccaptiontext(info); + end; + if not (as_localshortcut in state) then begin + shortcut:= nil; + sender.calccaptiontext(info); + end; + if not (as_localshortcut1 in state) then begin + shortcut1:= nil; + end; + if not (as_localimagelist in state) then begin + imagelist:= nil; //do not unink,imagelist is owned by action + end; + if not (as_localimagenr in state) then begin + imagenr:= -1; + end; + if not (as_localimagenrdisabled in state) then begin + imagenrdisabled:= -2; + end; + if not (as_localcolorglyph in state) then begin + colorglyph:= cl_default; + end; + if not (as_localcolor in state) then begin + color:= cl_default; + end; + if not (as_localimagecheckedoffset in state) then begin + imagecheckedoffset:= 0; + end; + if not (as_localtag in state) then begin + tag:= 0; + end; + if not (as_localgroup in state) then begin + group:= 0; + end; + if not (as_localhint in state) then begin + hint:= ''; + end; + if not (as_localonexecute in state) then begin + onexecute:= nil; + end; + if not (as_localonbeforeexecute in state) then begin + onbeforeexecute:= nil; + end; + if not (as_localonafterexecute in state) then begin + onafterexecute:= nil; + end; + state:= state - actionstatesty( + longword(localactionstatestates) shr localactionlshift); + sender.actionchanged; + end; + end; + end; + end; +end; +{ +procedure actiondoidle(const info: actioninfoty); +begin + if info.action <> nil then begin + info.action.doupdate; + end; +end; +} +{ +function isactionvisiblestored(const info: actioninfoty): boolean; +begin + with info do begin + result:= (ss_localinvisible in state) and + not ((action = nil) and not(ss_invisible in state)); + end; +end; + +function isactioncheckedstored(const info: actioninfoty): boolean; +begin + with info do begin + result:= (ss_localchecked in state) and + not ((action = nil) and not (ss_checked in state)); + end; +end; +} + +procedure setactionchecked(const sender: iactionlink; const value: boolean); +var + po1: pactioninfoty; + bo1: boolean; +begin + po1:= sender.getactioninfopo; + with po1^ do begin + bo1:= as_checked in state; + if bo1 <> value then begin + if not (as_localchecked in state) and (action <> nil) then begin + action.checked:= value; + end + else begin + updatebit(longword(state),ord(as_checked),value); + sender.actionchanged; + end; + end; + end; +end; + +procedure setactioncaption(const sender: iactionlink; const value: msestring); +var + po1: pactioninfoty; +begin + po1:= sender.getactioninfopo; + with po1^ do begin + captiontext:= value; + include(state,as_localcaption); + end; + sender.calccaptiontext(po1^); + sender.actionchanged; +end; + +function isactioncaptionstored(const info: actioninfoty): boolean; +begin + with info do begin + result:= (as_localcaption in state) and + not ((action = nil) and (captiontext = '')); + end; +end; + +procedure setactiontag(const sender: iactionlink; const value: integer); +var + po1: pactioninfoty; +begin + po1:= sender.getactioninfopo; + with po1^ do begin + tag:= value; + include(state,as_localtag); + end; + sender.actionchanged; +end; + +function isactiontagstored(const info: actioninfoty): boolean; +begin + with info do begin + result:= (as_localtag in state) and + not ((action = nil) and (tag = 0)); + end; +end; + +procedure setactionimagenr(const sender: iactionlink; const value: integer); +begin + with sender.getactioninfopo^ do begin + imagenr:= value; + include(state,as_localimagenr); + end; + sender.actionchanged; +end; + +function isactionimagenrstored(const info: actioninfoty): boolean; +begin + with info do begin + result:= (as_localimagenr in state) and + not ((action = nil) and (imagenr = -1)); + end; +end; + +procedure setactionimagenrdisabled(const sender: iactionlink; const value: integer); +begin + with sender.getactioninfopo^ do begin + imagenrdisabled:= value; + include(state,as_localimagenrdisabled); + end; + sender.actionchanged; +end; + +function isactionimagenrdisabledstored(const info: actioninfoty): boolean; +begin + with info do begin + result:= (as_localimagenrdisabled in state) and + not ((action = nil) and (imagenrdisabled = -2)); + end; +end; + +procedure setactioncolorglyph(const sender: iactionlink; const value: colorty); +begin + with sender.getactioninfopo^ do begin + colorglyph:= value; + include(state,as_localcolorglyph); + end; + sender.actionchanged; +end; + +procedure setactioncolor(const sender: iactionlink; const value: colorty); +begin + with sender.getactioninfopo^ do begin + color:= value; + include(state,as_localcolor); + end; + sender.actionchanged; +end; + +function isactioncolorglyphstored(const info: actioninfoty): boolean; +begin + with info do begin + result:= (as_localcolorglyph in state) and + not ((action = nil) and (colorglyph = cl_default)); + end; +end; + +function isactioncolorstored(const info: actioninfoty): boolean; +begin + with info do begin + result:= (as_localcolor in state) and + not ((action = nil) and (color = cl_default)); + end; +end; + +procedure setactionimagecheckedoffset(const sender: iactionlink; const value: integer); +begin + with sender.getactioninfopo^ do begin + imagecheckedoffset:= value; + include(state,as_localimagecheckedoffset); + end; + sender.actionchanged; +end; + +function isactionimagecheckedoffsetstored(const info: actioninfoty): boolean; +begin + with info do begin + result:= (as_localimagecheckedoffset in state) and + not ((action = nil) and (imagecheckedoffset = 0)); + end; +end; + +procedure setactionhint(const sender: iactionlink; const value: msestring); +begin + with sender.getactioninfopo^ do begin + hint:= value; + include(state,as_localhint); + end; + sender.actionchanged; +end; + +function isactionhintstored(const info: actioninfoty): boolean; +begin + with info do begin + result:= (as_localhint in state) and + not ((action = nil) and (hint = '')); + end; +end; + +procedure setactionstate(const sender: iactionlink; const value: actionstatesty); +var + startstate,statebefore: actionstatesty; + bo1: boolean; + po1: pactioninfoty; +begin + po1:= sender.getactioninfopo; + with po1^ do begin + startstate:= state; + statebefore:= state; + state:= actionstatesty(replacebits( + {$ifdef FPC}longword{$else}longword{$endif}(value), + {$ifdef FPC}longword{$else}longword{$endif}(state), + {$ifdef FPC}longword{$else}longword{$endif}(localactionstates))); + bo1:= state <> statebefore; + statebefore:= state; + state:= actionstatesty(replacebits( + {$ifdef FPC}longword{$else}longword{$endif}(value), + {$ifdef FPC}longword{$else}longword{$endif}(state), + {$ifdef FPC}longword{$else}longword{$endif}(actionstatesmask))); + if statebefore <> state then begin + if (mao_shortcutcaption in options) and + (statebefore * [as_disabled] <> state * [as_disabled]) then begin + sender.calccaptiontext(po1^); + end; + end; + if not sender.loading then begin +{$ifdef FPC}longword{$else}longword{$endif}(state):= + {$ifdef FPC}longword{$else}longword{$endif}(state) or + ( + ( + ( + {$ifdef FPC}longword{$else}longword{$endif}(state) xor + {$ifdef FPC}longword{$else}longword{$endif}(statebefore) + ) and + {$ifdef FPC}longword{$else}longword{$endif}(actionstatesmask) + ) + shl localactionlshift + ); + end; + if bo1 and (action <> nil) then begin + action.updateinfo(sender); + end; + if state <> startstate then begin + sender.actionchanged; + end; + end; +end; + +procedure setactionoptions(const sender: iactionlink; + const value: menuactionoptionsty); +const + mask1: menuactionoptionsty = [mao_showhint,mao_noshowhint]; + mask2: menuactionoptionsty = [mao_checkbox,mao_radiobutton]; +var + optionsbefore: menuactionoptionsty; + po1: pactioninfoty; +begin + po1:= sender.getactioninfopo; + with po1^ do begin + optionsbefore:= options; + options:= menuactionoptionsty(setsinglebit( + {$ifdef FPC}longword{$else}word{$endif}(value), + {$ifdef FPC}longword{$else}word{$endif}(options), + {$ifdef FPC}longword{$else}word{$endif}(mask1))); + options:= menuactionoptionsty(setsinglebit( + {$ifdef FPC}longword{$else}word{$endif}(options), + {$ifdef FPC}longword{$else}word{$endif}(optionsbefore), + {$ifdef FPC}longword{$else}word{$endif}(mask2))); + if optionsbefore * [mao_shortcutcaption] <> options * + [mao_shortcutcaption] then begin + sender.calccaptiontext(po1^); + end; + end; + sender.actionchanged; +end; + +function isactionstatestored(const info: actioninfoty): boolean; +begin + result:= true; + { + with info do begin + result:= (state * localactionstatestates <> []) and + not ((action = nil) and (state * actionstatesmask = [])); + end; + } +end; + +procedure setactiongroup(const sender: iactionlink; const value: integer); +begin + with sender.getactioninfopo^ do begin + group:= value; + include(state,as_localgroup); + end; + sender.actionchanged; +end; + +function isactiongroupstored(const info: actioninfoty): boolean; +begin + with info do begin + result:= (as_localgroup in state) and + not ((action = nil) and (group = 0)); + end; +end; + +procedure setactiononexecute(const sender: iactionlink; + const value: notifyeventty; const aloading: boolean); +begin + with sender.getactioninfopo^ do begin + onexecute:= value; + if not aloading then begin //IDE sets csloading while method pointer swapping + include(state,as_localonexecute); + end; + end; + sender.actionchanged; +end; + +function isactiononexecutestored(const info: actioninfoty): boolean; +begin + with info do begin + result:= (as_localonexecute in state) and + not ((action = nil) and + (tmethod(info.onexecute).code = nil) and + (tmethod(info.onexecute).data = nil)); + end; +end; + +procedure setactiononbeforeexecute(const sender: iactionlink; + const value: accepteventty; const aloading: boolean); +begin + with sender.getactioninfopo^ do begin + onbeforeexecute:= value; + if not aloading then begin //IDE sets csloading while method pointer swapping + include(state,as_localonbeforeexecute); + end; + end; + sender.actionchanged; +end; + +function isactiononbeforeexecutestored(const info: actioninfoty): boolean; +begin + with info do begin + result:= (as_localonbeforeexecute in state) and + not ((action = nil) and (tmethod(info.onexecute).code = nil) and + (tmethod(info.onexecute).data = nil)); + //assigned does not work + end; +end; + +procedure setactiononafterexecute(const sender: iactionlink; + const value: notifyeventty; const aloading: boolean); +begin + with sender.getactioninfopo^ do begin + onafterexecute:= value; + if not aloading then begin //IDE sets csloading while method pointer swapping + include(state,as_localonafterexecute); + end; + end; + sender.actionchanged; +end; + +function isactiononafterexecutestored(const info: actioninfoty): boolean; +begin + with info do begin + result:= (as_localonafterexecute in state) and + not ((action = nil) and + (tmethod(info.onafterexecute).code = nil) and + (tmethod(info.onafterexecute).data = nil)); + end; +end; + + {tcustomaction} + +constructor tcustomaction.create(aowner: tcomponent); +begin + initactioninfo(finfo); + finfo.action:= self; + foptions:= defaultactionoptions; + inherited; +end; + +procedure tcustomaction.dounlinkaction(const info: linkinfoty); +begin + linktoaction(iactionlink(info.dest),nil, + iactionlink(info.dest).getactioninfopo^); +end; + +destructor tcustomaction.destroy; +begin + if fobjectlinker <> nil then begin + fobjectlinker.forall({$ifdef FPC}@{$endif}dounlinkaction,typeinfo(iactionlink)); + end; + doafterunlink; + options:= []; + inherited; +end; + +procedure tcustomaction.setstatfile(const Value: tstatfile); +begin + setstatfilevar(istatfile(self),value,fstatfile); +end; + +function tcustomaction.getcaption: captionty; +begin + result:= finfo.captiontext; +end; + +procedure tcustomaction.setcaption(const Value: captionty); +begin + finfo.captiontext:= value; + changed; +end; +{ +function tcustomaction.getimagelist: timagelist; +begin + result:= finfo.imagelist; +end; +} +{ +function tcustomaction.getimagenr: integer; +begin + result:= finfo.imagenr; +end; +} +procedure tcustomaction.setimagenr(const Value: imagenrty); +begin + finfo.imagenr:= value; + changed; +end; + +procedure tcustomaction.setimagenrdisabled(const avalue: imagenrty); +begin + finfo.imagenrdisabled:= avalue; + changed; +end; + +procedure tcustomaction.setcolorglyph(const avalue: colorty); +begin + finfo.colorglyph:= avalue; + changed; +end; + +procedure tcustomaction.setcolor(const avalue: colorty); +begin + finfo.color:= avalue; + changed; +end; + +procedure tcustomaction.setimagecheckedoffset(const Value: integer); +begin + finfo.imagecheckedoffset:= value; + changed; +end; + +{ +function tcustomaction.gethint: msestring; +begin + result:= finfo.hint; +end; +} +procedure tcustomaction.sethint(const Value: msestring); +begin + finfo.hint:= value; + changed; +end; + +function tcustomaction.getstate: actionstatesty; +begin + result:= finfo.state; +end; + +procedure tcustomaction.setstate(const Value: actionstatesty); +begin + if value * actionstatesmask <> finfo.state * actionstatesmask then begin + finfo.state:= actionstatesty(replacebits( + {$ifdef FPC}longword{$else}longword{$endif}(value), + {$ifdef FPC}longword{$else}longword{$endif}(finfo.state), + {$ifdef FPC}longword{$else}longword{$endif}(actionstatesmask))); + changed; + end; +end; + +function tcustomaction.getgroup: integer; +begin + result:= finfo.group; +end; + +procedure tcustomaction.setgroup(const Value: integer); +begin + finfo.group:= value; + changed; +end; + +procedure tcustomaction.settag(const Value: integer); +begin + finfo.tag := Value; + changed; +end; + +procedure tcustomaction.setonexecute(const avalue: notifyeventty); +begin + if not issamemethod(tmethod(avalue),tmethod(finfo.onexecute)) then begin + finfo.onexecute := avalue; + changed; + end; +end; + +procedure tcustomaction.setonbeforeexecute(const avalue: accepteventty); +begin + if not issamemethod(tmethod(avalue),tmethod(finfo.onbeforeexecute)) then begin + finfo.onbeforeexecute:= avalue; + changed; + end; +end; + +procedure tcustomaction.setonafterexecute(const avalue: notifyeventty); +begin + if not issamemethod(tmethod(avalue),tmethod(finfo.onafterexecute)) then begin + finfo.onafterexecute:= avalue; + changed; + end; +end; + +procedure tcustomaction.loaded; +begin + inherited; + changed; +end; + +procedure tcustomaction.updateinfo(const sender: iactionlink); +var + bo1: boolean; + mask: actionstatesty; + po1: pactioninfoty; +// sepchar: msechar; +begin + bo1:= false; + po1:= sender.getactioninfopo; + with po1^ do begin +// sepchar:= sender.shortcutseparator; + if not (as_localcaption in state) and + (captiontext <> finfo.captiontext) then begin + captiontext:= finfo.captiontext; + sender.calccaptiontext(po1^); + bo1:= true; + end; + if not (as_localshortcut in state) and + (shortcut <> finfo.shortcut) then begin + shortcut:= finfo.shortcut; + sender.calccaptiontext(po1^); + bo1:= true; + end; + if not (as_localshortcut1 in state) and + (shortcut1 <> finfo.shortcut1) then begin + shortcut1:= finfo.shortcut1; + bo1:= true; + end; + if not (as_localimagelist in state) and + (imagelist <> finfo.imagelist) then begin + imagelist:= finfo.imagelist; + bo1:= true; + end; + if not (as_localimagenr in state) and + (imagenr <> finfo.imagenr) then begin + imagenr:= finfo.imagenr; + bo1:= true; + end; + if not (as_localimagenrdisabled in state) and + (imagenrdisabled <> finfo.imagenrdisabled) then begin + imagenrdisabled:= finfo.imagenrdisabled; + bo1:= true; + end; + if not (as_localcolorglyph in state) and + (colorglyph <> finfo.colorglyph) then begin + colorglyph:= finfo.colorglyph; + bo1:= true; + end; + if not (as_localcolor in state) and + (color <> finfo.color) then begin + color:= finfo.color; + bo1:= true; + end; + if not (as_localimagecheckedoffset in state) and + (imagecheckedoffset <> finfo.imagecheckedoffset) then begin + imagecheckedoffset:= finfo.imagecheckedoffset; + bo1:= true; + end; + if not (as_localtag in state) and + (tag <> finfo.tag) then begin + tag:= finfo.tag; + bo1:= true; + end; + if not (as_localgroup in state) and + (group <> finfo.group) then begin + group:= finfo.group; + bo1:= true; + end; + if not (as_localhint in state) and + (hint <> finfo.hint) then begin + hint:= finfo.hint; + bo1:= true; + end; + if not (as_localonexecute in state) and + not issamemethod(tmethod(onexecute),tmethod(finfo.onexecute)) then begin + onexecute:= finfo.onexecute; + bo1:= true; + end; + if not (as_localonbeforeexecute in state) and + not issamemethod(tmethod(onbeforeexecute), + tmethod(finfo.onbeforeexecute)) then begin + onbeforeexecute:= finfo.onbeforeexecute; + bo1:= true; + end; + if not (as_localonafterexecute in state) and + not issamemethod(tmethod(onafterexecute), + tmethod(finfo.onafterexecute)) then begin + onafterexecute:= finfo.onafterexecute; + bo1:= true; + end; + mask:= actionstatesmask - + actionstatesty( + {$ifdef FPC}longword{$else}longword{$endif}( + {$ifdef FPC}longword{$else}longword{$endif}(state * localactionstatestates) shr + localactionlshift) + ); +// if as_localstate in state then begin +// mask:= mask - actionstatesmask; +// end; + { + if ss_localchecked in state then begin + exclude(mask,ss_checked); + end; + } + if state * mask <> finfo.state * mask then begin + bo1:= true; + state:= actionstatesty( + replacebits({$ifdef FPC}longword{$else}longword{$endif}(finfo.state), + {$ifdef FPC}longword{$else}longword{$endif}(state), + {$ifdef FPC}longword{$else}longword{$endif}(mask))); + end; + end; + if bo1 then begin + sender.actionchanged; + end; +end; + +procedure tcustomaction.doupdateinfo(const info: linkinfoty); +begin + updateinfo(iactionlink(info.dest)); +end; + +procedure tcustomaction.changed; +begin + if not (csloading in componentstate) then begin + if fobjectlinker <> nil then begin + fobjectlinker.forall({$ifdef FPC}@{$endif}doupdateinfo, + typeinfo(iactionlink)); + end; + if canevent(tmethod(fonchange)) then begin + fonchange(self); + end; + end; +end; + +procedure tcustomaction.doupdate; +begin + if assigned(fonupdate) and not (csdesigning in componentstate) then begin + fonupdate(self); + end; +end; + +procedure tcustomaction.doidle(var again: boolean); +begin + doupdate; +end; + +procedure tcustomaction.execute(const force: boolean = false); +begin + if (componentstate*[csloading,csdesigning,csdestroying] = []) and + doactionexecute(self,finfo,false,false,nil,force) then begin + changed; + end; +end; + +procedure tcustomaction.asyncexecute(); +begin + application.postevent(tobjectevent.create(ek_execute,self)); +end; + +procedure tcustomaction.receiveevent(const event: tobjectevent); +begin + inherited; + case event.kind of + ek_execute: begin + execute(); + end; + end; +end; + +procedure tcustomaction.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (event = oe_destroyed) and (sender = finfo.imagelist) then begin + finfo.imagelist:= nil; + changed; + end; +end; + +function tcustomaction.getenabled: boolean; +begin + result:= not (as_disabled in finfo.state); +end; + +procedure tcustomaction.setenabled(const avalue: boolean); +begin + if avalue then begin + state:= finfo.state - [as_disabled]; + end + else begin + state:= finfo.state + [as_disabled]; + end; +end; + +procedure tcustomaction.ifisetenabled(const avalue: boolean); +begin + if not (as_localdisabled in finfo.state) then begin + setenabled(avalue); + end; +end; + +function tcustomaction.getchecked: boolean; +begin + result:= as_checked in finfo.state; +end; + +procedure tcustomaction.setchecked(const Value: boolean); +begin + if value then begin + state:= state + [as_checked]; + end + else begin + state:= state - [as_checked]; + end; +end; + +procedure tcustomaction.setoptions(const Value: actionoptionsty); +var + delta: actionoptionsty; +begin + delta:= actionoptionsty({$ifdef FPC}longword{$else}byte{$endif}(foptions) xor + {$ifdef FPC}longword{$else}byte{$endif}(value)); + if delta <> [] then begin + foptions := Value; + if not (csdesigning in componentstate) then begin + if ao_updateonidle in delta then begin + if (ao_updateonidle in value) and + not (csdesigning in componentstate) then begin + application.registeronidle({$ifdef FPC}@{$endif}doidle); + end + else begin + application.unregisteronidle({$ifdef FPC}@{$endif}doidle); + end; + end; + if [ao_globalshortcut,ao_localshortcut] * delta <> [] then begin + registeronshortcut([ao_globalshortcut,ao_localshortcut] * value <> []); + end; + end; + end; +end; + +procedure tcustomaction.dostatread(const reader: tstatreader); +begin + if reader.candata then begin + checked:= reader.readboolean('checked',checked); + end; +end; + +procedure tcustomaction.dostatwrite(const writer: tstatwriter); +begin + if writer.candata then begin + writer.writeboolean('checked',checked); + end; +end; + +procedure tcustomaction.statreading; +begin + //dummy +end; + +procedure tcustomaction.statread; +begin + //dummy +end; + +function tcustomaction.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +procedure tcustomaction.doasyncevent(var atag: integer); +begin + if canevent(tmethod(fonasyncevent)) then begin + fonasyncevent(self,atag); + end; +end; + +procedure tcustomaction.eventfired(const sender: tobject; + const ainfo: actioninfoty); +begin + if canevent(tmethod(fonexecuteaction)) then begin + fonexecuteaction(self); + end; + sendchangeevent(oe_fired); +{$ifdef mse_with_ifi} + if fifiserverintf <> nil then begin + fifiserverintf.execute(iifiexeclink(self)); + end; +{$endif} +end; + +procedure tcustomaction.registeronshortcut(const avalue: boolean); +begin + //dummy +end; + +procedure tcustomaction.doafterunlink; +begin + //dummy +end; + +{$ifdef mse_with_ifi} +function tcustomaction.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iifiexeclink); +end; + +procedure tcustomaction.setifilink(const avalue: tifiactionlinkcomp); +begin + mseificomp.setifilinkcomp(iifiexeclink(self),avalue,tifilinkcomp(fifilink)); + if (fifilink <> nil) then begin + ifisetenabled(fifilink.c.enabled); + end; +end; +{$endif} + +function tcustomaction.getvisible: boolean; +begin + result:= not(as_invisible in finfo.state); +end; + +procedure tcustomaction.setvisible(const avalue: boolean); +begin + if avalue then begin + state:= state - [as_invisible]; + end + else begin + state:= state + [as_invisible]; + end; +end; + +function tcustomaction.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +end. + diff --git a/mseide-msegui/lib/common/kernel/mseactions.pas b/mseide-msegui/lib/common/kernel/mseactions.pas new file mode 100644 index 0000000..b74ffd8 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseactions.pas @@ -0,0 +1,2250 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseactions; +{$ifdef FPC} + {$mode objfpc}{$h+} +{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses,mseact,mseglob,mseguiglob,msegui,mseevent,mseclasses,msebitmap, + msekeyboard,msetypes,msestrings,msearrayprops,msestatfile,msestat, + mseinterfaces; + +type + + sysshortcutty = (sho_copy,sho_paste,sho_cut,sho_selectall, + sho_rowinsert,sho_rowappend,sho_rowdelete, + sho_copycells,sho_pastecells,sho_groupundo,sho_groupredo); + sysshortcutaty = array[sysshortcutty] of shortcutty; + psysshortcutaty = ^sysshortcutaty; + + shortcutconstty = array[0..2] of shortcutty; + assistiveshortcutty = (shoa_speakagain,shoa_speakpath, + shoa_firstelement,shoa_lastelement, + shoa_cancelspeech, + shoa_slower,shoa_faster,shoa_volumedown,shoa_volumeup); + assistiveshortcutconstty = array[assistiveshortcutty] of shortcutconstty; + assistiveshortcutaty = array[assistiveshortcutty] of shortcutarty; + passistiveshortcutaty = ^assistiveshortcutaty; + + taction = class(tcustomaction,iimagelistinfo,iactionlink) + private +// fmultishortcut: integer; //0 = none, 1 = shortcut, 2 = shortcut1 +// fmultiindex: integer; //index of current checked char + procedure setimagelist(const Value: timagelist); + function getshortcut: shortcutty; + procedure setshortcut(const avalue: shortcutty); + function getshortcut1: shortcutty; + procedure setshortcut1(const avalue: shortcutty); + procedure setshortcuts(const avalue: shortcutarty); + procedure setshortcuts1(const avalue: shortcutarty); + procedure readshortcut(reader: treader); + procedure readshortcut1(reader: treader); + procedure readsc(reader: treader); + procedure writesc(writer: twriter); + procedure readsc1(reader: treader); + procedure writesc1(writer: twriter); + //iimagelistinfo + function getimagelist: timagelist; + //iactionlink + function getactioninfopo: pactioninfoty; + procedure actionchanged; + function shortcutseparator: msechar; + procedure calccaptiontext(var ainfo: actioninfoty); + protected + procedure registeronshortcut(const avalue: boolean); override; + procedure doshortcut(const sender: twidget; var keyinfo: keyeventinfoty); + procedure doafterunlink; override; + procedure defineproperties(filer: tfiler); override; + public +// destructor destroy; override; + property shortcuts: shortcutarty read finfo.shortcut write setshortcuts; + property shortcuts1: shortcutarty read finfo.shortcut1 write setshortcuts1; + published + property imagelist: timagelist read getimagelist write setimagelist; + property shortcut: shortcutty read getshortcut write setshortcut + stored false default ord(key_none) ; + property shortcut1: shortcutty read getshortcut1 write setshortcut1 + stored false default ord(key_none); + property caption; + property state; + property group; + property tagaction; + property imagenr; + property imagenrdisabled; + property colorglyph; + property color; + property imagecheckedoffset; + property hint; + property statfile; + property statvarname; + property statpriority; + property options; + property onexecute; + property onbeforeexecute; + property onafterexecute; + property onexecuteaction; + property onupdate; + property onchange; + property onasyncevent; +{$ifdef mse_with_ifi} + property ifilink; +{$endif} + end; + + tshortcutaction = class(townedeventpersistent,iactionlink) + private + finfo: actioninfoty; //as interface to shortcut propertyeditor + faction: taction; +// fshortcutsdefault: shortcutarty; +// fshortcuts1default: shortcutarty; + fdispname: msestring; +// fhint: msestring; + procedure setaction(const avalue: taction); + procedure readsc(reader: treader); + procedure writesc(writer: twriter); + procedure readsc1(reader: treader); + procedure writesc1(writer: twriter); + procedure readshortcut(reader: treader); + procedure readshortcut1(reader: treader); + procedure setshortcuts(const avalue: shortcutarty); + procedure setshortcuts1(const avalue: shortcutarty); + //iactionlink + function getactioninfopo: pactioninfoty; + procedure actionchanged; + function loading: boolean; + function shortcutseparator: msechar; + procedure calccaptiontext(var ainfo: actioninfoty); + + protected + function getshortcutdefault: shortcutty; + procedure setshortcutdefault(const avalue: shortcutty); + function getshortcut1default: shortcutty; + procedure setshortcut1default(const avalue: shortcutty); + procedure defineproperties(filer: tfiler); override; + public + property shortcutsdefault: shortcutarty read finfo.shortcut + write setshortcuts; + property shortcuts1default: shortcutarty read finfo.shortcut1 + write setshortcuts1; + published + property action: taction read faction write setaction; + property shortcutdefault: shortcutty read getshortcutdefault + write setshortcutdefault + stored false default 0; + property shortcut1default: shortcutty read getshortcut1default + write setshortcut1default + stored false default 0; + property dispname: msestring read fdispname write fdispname; + property hint: msestring read finfo.hint write finfo.hint; + end; + +type + shortcutrecarty = array of + record + name: string; + value: int32; + end; + + tshortcutcontroller = class; + tshortcutactions = class(townedeventpersistentarrayprop) + private + protected + function getitems(const index: integer): tshortcutaction; + public + constructor create(const aowner: tshortcutcontroller); reintroduce; + class function getitemclasstype: persistentclassty; override; + public + property items[const index: integer]: tshortcutaction read getitems; + default; + end; + + tsysshortcuts = class(tintegerarrayprop) + private + fowner: tcomponent; + fdatapo: psysshortcutaty; + fshortcuts: shortcutrecarty; + function getitems(const index: sysshortcutty): shortcutty; + procedure setitems(const index: sysshortcutty; const avalue: shortcutty); + function getshortcutrecord(const index: integer): msestring; + procedure setshortcutcount(const acount: integer); + procedure setshortcutrecord(const index: integer; const avalue: msestring); + protected + procedure setfixcount(const avalue: integer); override; + procedure dochange(const aindex: integer); override; + procedure dostatread(const varname: msestring; const reader: tstatreader); + procedure dostatwrite(const varname: msestring; const writer: tstatwriter); + procedure readitem(const index: integer; reader: treader); override; + public + constructor create(const aowner: tcomponent; const adatapo: psysshortcutaty); + property items[const index: sysshortcutty]: shortcutty read getitems + write setitems; default; + end; + + assistiveshortcutrecarty = array of + record + name: string; + value: shortcutarty; + end; + + tassistiveshortcuts = class(tdynarrayarrayprop) + private + fowner: tcomponent; + fdatapo: passistiveshortcutaty; + fshortcuts: assistiveshortcutrecarty; + function getitems(const index: assistiveshortcutty): shortcutarty; + procedure setitems(const index: assistiveshortcutty; const avalue: shortcutarty); + function getshortcutrecord(const index: integer): msestring; + procedure setshortcutcount(const acount: integer); + procedure setshortcutrecord(const index: integer; const avalue: msestring); + protected + procedure internalsetcount(const acount: int32) override; + procedure setfixcount(const avalue: integer); override; + procedure dochange(const aindex: integer); override; + procedure dostatread(const varname: msestring; const reader: tstatreader); + procedure dostatwrite(const varname: msestring; const writer: tstatwriter); + procedure writeitem(const index: integer; writer: twriter); override; + procedure readitem(const index: integer; reader: treader); override; + public + constructor create(const aowner: tcomponent; const adatapo: passistiveshortcutaty); + property items[const index: assistiveshortcutty]: shortcutarty read getitems + write setitems; default; + end; + + shortcutstatinfoty = record + name: ansistring; + shortcut: shortcutarty; + shortcut1: shortcutarty; + end; + shortcutstatinfoarty = array of shortcutstatinfoty; + shortcutcontrollereventty = procedure( + const sender: tshortcutcontroller) of object; + tshortcutcontroller = class(tmsecomponent,istatfile) + private + factions: tshortcutactions; + fstatfile: tstatfile; + fstatvarname: msestring; + fstatinfos: shortcutstatinfoarty; + fsysshortcuts: tsysshortcuts; + fsysshortcuts1: tsysshortcuts; + fonafterupdate: shortcutcontrollereventty; + fstatpriority: integer; + fassistiveshortcuts: tassistiveshortcuts; + fassistiveshortcuts1: tassistiveshortcuts; + procedure setactions(const avalue: tshortcutactions); + procedure setstatfile(const avalue: tstatfile); + function getactionrecord(const index: integer): msestring; + procedure setactionreccount(const acount: integer); + procedure setactionrecord(const index: integer; const avalue: msestring); + procedure setsysshortcuts(const avalue: tsysshortcuts); + procedure setsysshortcuts1(const avalue: tsysshortcuts); + procedure setassistiveshortcuts(const avalue: tassistiveshortcuts); + procedure setassistiveshortcuts1(const avalue: tassistiveshortcuts); + protected + procedure updateaction(const aaction: taction); reintroduce; + //istatfile + procedure dostatread(const reader: tstatreader); virtual; + procedure dostatwrite(const writer: tstatwriter); virtual; + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure doafterupdate; + published + property actions: tshortcutactions read factions write setactions; + property sysshortcuts: tsysshortcuts read fsysshortcuts + write setsysshortcuts; + property sysshortcuts1: tsysshortcuts read fsysshortcuts1 + write setsysshortcuts1; + property assistiveshortcuts: tassistiveshortcuts read fassistiveshortcuts + write setassistiveshortcuts; + property assistiveshortcuts1: tassistiveshortcuts read fassistiveshortcuts1 + write setassistiveshortcuts1; + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read getstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + property onafterupdate: shortcutcontrollereventty read fonafterupdate + write fonafterupdate; + end; + + tcustomhelpcontroller = class; + helpcontrollereventty = procedure(const sender: tcustomhelpcontroller; + const helpsender: tmsecomponent; var handled: boolean) of object; + helpcontrollerprocty = procedure(const sender: tcustomhelpcontroller; + const helpsender: tmsecomponent; var handled: boolean); + + tcustomhelpcontroller = class(tmsecomponent) + private + fonhelp: helpcontrollereventty; + fonhelp1: helpcontrollerprocty; + fshortcut: shortcutty; + fshortcut1: shortcutty; + fshortcutregistered: boolean; + procedure setshortcut(const avalue: shortcutty); + procedure setshortcut1(const avalue: shortcutty); + procedure checkshortcuts(); + protected + procedure dohelp(const sender: tmsecomponent; var handled: boolean); virtual; + procedure doshortcut(const sender: twidget; var keyinfo: keyeventinfoty); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property onhelp: helpcontrollereventty read fonhelp write fonhelp; + property onhelp1: helpcontrollerprocty read fonhelp1 write fonhelp1; + property shortcut: shortcutty read fshortcut write setshortcut + default ord(key_none) ; + property shortcut1: shortcutty read fshortcut1 write setshortcut1 + default ord(key_none); + end; + + thelpcontroller = class(tcustomhelpcontroller) + published + property onhelp; + property shortcut; + property shortcut1; + end; + +function issameshortcut(const a,b: shortcutarty): boolean; +function getsimpleshortcut(const asource: shortcutarty): shortcutty; overload; +function getsimpleshortcut(const asource: actioninfoty): shortcutty; overload; +function getsimpleshortcut1(const asource: actioninfoty): shortcutty; +function setsimpleshortcut(const avalue: shortcutty): shortcutarty; overload; +procedure setsimpleshortcut(const avalue: shortcutty; + var adest: shortcutarty); overload; +procedure setsimpleshortcut(const avalue: shortcutty; + var adest: actioninfoty); overload; +procedure setsimpleshortcut1(const avalue: shortcutty; var adest: actioninfoty); +function checkshortcutconflict(const a,b: shortcutarty): boolean; + +procedure setactionshortcuts(const sender: iactionlink; + const value: shortcutarty); +procedure setactionshortcuts1(const sender: iactionlink; + const value: shortcutarty); +procedure setactionshortcut(const sender: iactionlink; const value: shortcutty); +procedure setactionshortcut1(const sender: iactionlink; + const value: shortcutty); +function isactionshortcutstored(const info: actioninfoty): boolean; +function isactionshortcut1stored(const info: actioninfoty): boolean; +procedure setactionimagelist(const sender: iactionlink; + const value: timagelist); +function isactionimageliststored(const info: actioninfoty): boolean; + +procedure getshortcutlist(out keys: integerarty; out names: msestringarty); +function getshortcutname(const shortcut: shortcutty): msestring; +function getshortcutname(const key: keyty; + const shiftstate: shiftstatesty): msestring; +//function getshortcutname(key: shortcutarty): msestring; +function getsysshortcutdispname(const aitem: sysshortcutty): msestring; +function getassistiveshortcutdispname( + const aitem: assistiveshortcutty): msestring; + +function isvalidshortcut(const ashortcut: shortcutty): boolean; +function encodeshortcut(const akey: keyty; + const ashiftstate: shiftstatesty): shortcutty; +function encodeshortcutname(const key: shortcutarty): msestring; overload; +function encodeshortcutname(const key: shortcutty): msestring; overload; +function checkshortcutcode(const shortcut: shortcutty; + const info: keyeventinfoty; + const apreview: boolean = false): boolean; overload; +function checkshortcutcode(const shortcut: shortcutty; + const info: keyinfoty): boolean; overload; +function checkactionshortcut(const ashortcut: shortcutarty; + var keyinfo: keyeventinfoty): boolean; //true if done +function checkactionshortcut(var info: actioninfoty; + var keyinfo: keyeventinfoty): boolean; //true if done +function doactionshortcut(const sender: tobject; var info: actioninfoty; + var keyinfo: keyeventinfoty; + const beforeexecute: proceventty = nil): boolean; + //true if executed +procedure calccaptiontext(var info: actioninfoty; const aseparator: msechar); +function issysshortcut(const ashortcut: sysshortcutty; + const ainfo: keyeventinfoty): boolean; + +const + shift = ord(key_modshift); + ctrl = ord(key_modctrl); + alt = ord(key_modalt); + pad = ord(key_modpad); + + modmask = shift or ctrl or alt or $1000 or pad; // $1000 -> old format + + defaultsysshortcuts: sysshortcutaty = +//sho_copy, sho_paste, sho_cut, + (ctrl+ord(key_c), ctrl+ord(key_v), ctrl+ord(key_x), +//sho_selectall + ctrl+ord(key_a), +//sho_rowinsert, sho_rowappend, sho_rowdelete + ctrl+ord(key_insert),shift+ctrl+ord(key_insert),ctrl+ord(key_delete), +//sho_copycells sho_pastecells + (ctrl+shift+ord(key_c)),(ctrl+shift+ord(key_v)), +//sho_groupundo, sho_groupredo + ctrl+ord(key_z), shift+ctrl+ord(key_z) + ); + + defaultsysshortcuts1: sysshortcutaty = +//sho_copy, sho_paste, sho_cut, + (ord(key_none), shift+ord(key_insert), shift+ord(key_delete), +//sho_selectall + ord(key_none), +//sho_rowinsert, sho_rowappend, sho_rowdelete + ord(key_none), ord(key_none), ord(key_none), +//sho_copycells sho_pastecells + ord(key_none), ord(key_none), +//sho_groupundo, sho_groupredo + ord(key_none), ord(key_none) + ); + + defaultassistiveshortcuts: assistiveshortcutconstty = + //shoa_speakagain, shoa_speakpath + ((ctrl+ord(key_space),0,0),(ctrl+shift+ord(key_space),0,0), + //shoa_firstelement, shoa_lastelement + (ctrl+ord(key_y),ord(key_f),0),(ctrl+ord(key_y),ord(key_l),0), + //shoa_cancelspeech + (ctrl+ord(key_y),ord(key_c),0), + //shoa_slower, shoa_faster + (pad+ctrl+ord(key_minus),0,0),(pad+ctrl+ord(key_plus),0,0), + //shoa_volumedown, shoa_volumeup + (pad+shift+ctrl+ord(key_minus),0,0),(pad+shift+ctrl+ord(key_plus),0,0) + ); + defaultassistiveshortcuts1: assistiveshortcutconstty = + //shoa_speakagain, shoa_speakpath + ((pad+ctrl+ord(key_return),0,0),(pad+ctrl+shift+ord(key_return),0,0), + //shoa_firstelement, shoa_lastelement + (ord(key_none),0,0),(ord(key_none),0,0), + //shoa_cancelspeech + (ord(key_none),0,0), + //shoa_slower, shoa_faster + (ord(key_none),0,0),(ord(key_none),0,0), + //shoa_volumedown, shoa_volumeup + (ord(key_none),0,0),(ord(key_none),0,0) + ); +var + sysshortcuts: sysshortcutaty; + sysshortcuts1: sysshortcutaty; + assistiveshortcuts: assistiveshortcutaty; + assistiveshortcuts1: assistiveshortcutaty; + +implementation +uses + sysutils,mserichstring,msestream,typinfo,mseformatstr,msestreaming, + msestockobjects,mseassistiveserver,msearrayutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + twidget1 = class(twidget); + +const + letterkeycount = ord('z') - ord('a') + 1; + cipherkeycount = ord('9') - ord('0') + 1; + functionkeycount = 12; + misckeycount = ord(key_sysreq) - ord(key_escape) + 1; + cursorkeycount = ord(key_pagedown) - ord(key_home) + 1; + specialshortcutcount = ord(high(specialshortcutty))+1; + specialkeycount = misckeycount + specialshortcutcount + cursorkeycount; + padcharkeycount = ord(key_slash)-ord(key_asterisk) + 1; + padspecialkeycount = ord(key_decimal)-ord(key_decimal) + 1; +{ + shortcutcount = (letterkeycount + cipherkeycount) * 2 + //ctrl,shiftctrl + 3 + //space + functionkeycount * 4 + //none,shift,ctrl,shiftctrl + specialkeycount * 4; //none,shift,ctrl,shiftctrl +} + baseshortcutcount = letterkeycount + cipherkeycount + 1 + //Space + functionkeycount + specialkeycount; + shortcutcount = 4 * (baseshortcutcount + padcharkeycount + padspecialkeycount + + cipherkeycount); + //none,shift,ctrl,shift+ctrl + +var + shortcutkeys: integerarty; + shortcutnames: msestringarty; + baseshortcutkeys: integerarty; + baseshortcutnames: msestringarty; + padcharshortcutkeys: integerarty; + padcharshortcutnames: msestringarty; + padspecialshortcutkeys: integerarty; + padspecialshortcutnames: msestringarty; + +procedure handleassistiveexec(const sender: tobject; const info: actioninfoty); +begin + if assistiveserver <> nil then begin + if sender is twidget then begin + assistiveserver.doactionexecute(twidget1(sender).getiassistiveclient(), + sender,info); + end + else begin + assistiveserver.doactionexecute(nil,sender,info); + end; + end; +end; + +function issysshortcut(const ashortcut: sysshortcutty; + const ainfo: keyeventinfoty): boolean; +begin + result:= checkshortcutcode(sysshortcuts[ashortcut],ainfo) or + checkshortcutcode(sysshortcuts1[ashortcut],ainfo); +end; + +procedure getvalues(var bottom: integer; prefix: msestring; + const modvalue: integer; var keys: integerarty; + var names: msestringarty); +var + int1: integer; + akey: keyty; +begin + keys[bottom]:= ord(key_space) + modvalue; + names[bottom]:= prefix+spacekeyname; + inc(bottom); + for int1:= bottom to bottom+cipherkeycount-1 do begin + keys[int1]:= ord(key_0) + int1-bottom + modvalue; + names[int1]:= prefix+msestring(msechar(int1-bottom+ord('0'))); + end; + bottom:= bottom + cipherkeycount; + for int1:= bottom to bottom+letterkeycount-1 do begin + keys[int1]:= ord(key_a) + int1-bottom + modvalue; + names[int1]:= prefix+msestring(msechar(int1-bottom+ord('A'))); + end; + bottom:= bottom + letterkeycount; + for int1:= bottom to bottom + functionkeycount - 1 do begin + keys[int1]:= (ord(key_f1) + int1-bottom) or modvalue; + names[int1]:= prefix+'F'+inttostrmse(int1-bottom+1); + end; + bottom:= bottom+functionkeycount; + for int1:= bottom to bottom+misckeycount-1 do begin + akey:= keyty(ord(key_escape) + int1-bottom); + keys[int1]:= ord(akey)or modvalue; + names[int1]:= prefix+shortmisckeynames[akey]; + end; + bottom:= bottom+misckeycount; + for int1:= bottom to bottom+specialshortcutcount-1 do begin + keys[int1]:= ord(specialkeys[specialshortcutty(int1-bottom)]) or modvalue; + names[int1]:= prefix+specialkeynames[specialshortcutty(int1-bottom)]; + end; + bottom:= bottom+specialshortcutcount; + for int1:= bottom to bottom+cursorkeycount-1 do begin + akey:= keyty(ord(key_home) + int1-bottom); + keys[int1]:= ord(akey)or modvalue; + names[int1]:= prefix+shortcursorkeynames[akey]; + end; + bottom:= bottom+cursorkeycount; +end; + +procedure getpadcharvalues(var bottom: integer; prefix: msestring; + const modvalue: integer; var keys: integerarty; + var names: msestringarty); +var + int1: integer; + akey: keyty; +begin + for int1:= bottom to bottom + padcharkeycount - 1 do begin + akey:= keyty(ord(key_asterisk) + int1-bottom); + keys[int1]:= ord(akey) or modvalue; + names[int1]:= prefix+padcharkeynames[akey]; + end; + bottom:= bottom+padcharkeycount; +end; + +procedure getpadspecialvalues(var bottom: integer; prefix: msestring; + const modvalue: integer; var keys: integerarty; + var names: msestringarty); +var + int1: integer; + akey: keyty; +begin + for int1:= bottom to bottom + padspecialkeycount - 1 do begin + akey:= keyty(ord(key_decimal) + int1-bottom); + keys[int1]:= ord(akey) or modvalue; + names[int1]:= prefix+padspecialkeynames[akey]; + end; + bottom:= bottom+padspecialkeycount; +end; + +procedure getpadvalues(var bottom: integer; prefix: msestring; + const modvalue: integer; var keys: integerarty; + var names: msestringarty); +var + int1: integer; + akey: keyty; +begin + for int1:= bottom to bottom+cipherkeycount-1 do begin + keys[int1]:= ord(key_0) + int1-bottom + modvalue; + names[int1]:= prefix+msestring(msechar(int1-bottom+ord('0'))); + end; + bottom:= bottom + cipherkeycount; + for int1:= bottom to bottom + padcharkeycount - 1 do begin + akey:= keyty(ord(key_asterisk) + int1-bottom); + keys[int1]:= ord(akey) or modvalue; + names[int1]:= prefix+padcharkeynames[akey]; + end; + bottom:= bottom+padcharkeycount; + for int1:= bottom to bottom + padspecialkeycount - 1 do begin + akey:= keyty(ord(key_decimal) + int1-bottom); + keys[int1]:= ord(akey) or modvalue; + names[int1]:= prefix+padspecialkeynames[akey]; + end; + bottom:= bottom+padspecialkeycount; +end; + +procedure getshortcutlist(out keys: integerarty; out names: msestringarty); +var +// int1: integer; + bo1: boolean; + bottom: integer; +// akey: keyty; +begin + bo1:= false; + if shortcutkeys = nil then begin + setlength(shortcutkeys,shortcutcount); + bo1:= true; + end; + if shortcutnames = nil then begin + setlength(shortcutnames,shortcutcount); + bo1:= true; + end; + keys:= shortcutkeys; + names:= shortcutnames; + if bo1 then begin + bottom:= 0; + getvalues(bottom,'',0,keys,names); + getvalues(bottom,'Shift+',key_modshift,keys,names); + getvalues(bottom,'Ctrl+',key_modctrl,keys,names); + getvalues(bottom,'Shift+Ctrl+',key_modshiftctrl,keys,names); + getpadvalues(bottom,'Pad+',key_modpad,keys,names); + getpadvalues(bottom,'Shift+Pad+',key_modpadshift,keys,names); + getpadvalues(bottom,'Ctrl+Pad+',key_modpadctrl,keys,names); + getpadvalues(bottom,'Shift+Ctrl+Pad+',key_modpadshiftctrl,keys,names); + end; +end; + +function getshortcutname(const shortcut: shortcutty): msestring; +var + int1{,int2}: integer; + keys: integerarty; + names: msestringarty; +begin + result:= ''; + if shortcut <> 0 then begin + getshortcutlist(keys,names); + for int1:= 0 to high(keys) do begin + if shortcut = keys[int1] then begin + result:= names[int1]; + exit; + end; + end; + result:= '$'+msestring(intvaluetostr(shortcut,nb_hex,16)); + end; +end; + +function getshortcutname(const key: keyty; + const shiftstate: shiftstatesty): msestring; +var + shortcut: shortcutty; +begin + shortcut:= ord(key); + if ss_shift in shiftstate then begin + shortcut:= shortcut or shift; + end; + if ss_ctrl in shiftstate then begin + shortcut:= shortcut or ctrl; + end; + if ss_alt in shiftstate then begin + shortcut:= shortcut or alt; + end; + if ss_second in shiftstate then begin + shortcut:= shortcut or pad; + end; + result:= getshortcutname(shortcut); +end; +{ +function getshortcutname(key: shortcutarty): msestring; +var + keys: integerarty; + names: msestringarty; + int1,int2,int3: integer; +begin + result:= ''; + if high(key) >= 0 then begin + getshortcutlist(keys,names); + for int3:= 0 to high(key) do begin + int2:= key[int3]; + for int1:= 0 to high(keys) do begin + if keys[int1] = int2 then begin + result:= result + names[int1] + ' '; + break; + end; + end; + end; + if result <> '' then begin + setlength(result,length(result)-1); + end; + end; +end; +} +//todo: internationalize +function getsysshortcutdispname(const aitem: sysshortcutty): msestring; +const + list: array[sysshortcutty] of stockcaptionty = ( + sc_Copy,sc_Paste,sc_cut,sc_select_all, + sc_row_insert,sc_row_append,sc_row_delete, + sc_copy_cells,sc_paste_cells,sc_undo,sc_redo); +begin + result:= stockobjects.captions[list[aitem]]; +end; + +function getassistiveshortcutdispname( + const aitem: assistiveshortcutty): msestring; +const + list: array[assistiveshortcutty] of stockcaptionty = ( + sc_speakagain,sc_speakpath,sc_firstelement,sc_lastelement, + sc_cancelspeech, + sc_slower,sc_faster,sc_volumedown,sc_volumeup); +begin + result:= stockobjects.captions[list[aitem]]; +end; + +function isnormalkey(const akey: shortcutty): boolean; +begin + result:= (akey >= ord(key_0)) and (akey <= ord(key_9)) or + (akey >= ord(key_a)) and (akey <= ord(key_z)) or + (akey >= ord(key_asterisk)) and (akey <= ord(key_slash)) or + (akey = ord(key_left)) or + (akey = ord(key_right)) or + (akey = ord(key_up)) or + (akey = ord(key_down)) or + (akey = ord(key_tab)) or + (akey = ord(key_space)) or + (akey = ord(key_return)){ or + (akey = ord(key_enter))}; +end; + +function isnormalshiftkey(const akey: shortcutty): boolean; +begin + result:= (akey >= ord(key_0)) and (akey <= ord(key_9)) or + (akey >= ord(key_a)) and (akey <= ord(key_z)) or + (akey = ord(key_tab)); +end; + +function isvalidshortcut(const ashortcut: shortcutty): boolean; +var + key: word; +begin + key:= ashortcut and not modmask; + result:= (key <> 0) and (key <> word(not modmask)); + if result then begin + if ashortcut and (modmask and not pad) = 0 then begin + result:= not isnormalkey(key); + end + else begin + if ashortcut and modmask = shift then begin + result:= not isnormalshiftkey(key); + end; + end; + end; +end; + +function encodeshortcut(const akey: keyty; + const ashiftstate: shiftstatesty): shortcutty; +begin + result:= ord(akey) and not modmask; + if ss_shift in ashiftstate then begin + result:= result or shift; + end; + if ss_ctrl in ashiftstate then begin + result:= result or ctrl; + end; + if ss_alt in ashiftstate then begin + result:= result or alt; + end; + if ss_second in ashiftstate then begin + result:= result or pad; + end; +end; + +function encodeshortcutname(const key: shortcutty): msestring; +var + bo1: boolean; + int1: integer; + k1: shortcutty; + mstr1: msestring; +begin + bo1:= false; + if baseshortcutkeys = nil then begin + setlength(baseshortcutkeys,baseshortcutcount); + bo1:= true; + end; + if baseshortcutnames = nil then begin + setlength(baseshortcutnames,baseshortcutcount); + bo1:= true; + end; + if padcharshortcutkeys = nil then begin + setlength(padcharshortcutkeys,padcharkeycount); + bo1:= true; + end; + if padcharshortcutnames = nil then begin + setlength(padcharshortcutnames,padcharkeycount); + bo1:= true; + end; + if padspecialshortcutkeys = nil then begin + setlength(padspecialshortcutkeys,padspecialkeycount); + bo1:= true; + end; + if padspecialshortcutnames = nil then begin + setlength(padspecialshortcutnames,padspecialkeycount); + bo1:= true; + end; + if bo1 then begin + int1:= 0; + getvalues(int1,'',0,baseshortcutkeys,baseshortcutnames); + int1:= 0; + getpadcharvalues(int1,'',0,padcharshortcutkeys,padcharshortcutnames); + int1:= 0; + getpadspecialvalues(int1,'',0,padspecialshortcutkeys,padspecialshortcutnames); + end; + mstr1:= ''; + k1:= key and not modmask; + for int1:= 0 to high(baseshortcutkeys) do begin + if baseshortcutkeys[int1] = k1 then begin + mstr1:= baseshortcutnames[int1]; + break; + end; + end; + if mstr1 = '' then begin + for int1:= 0 to high(padcharshortcutkeys) do begin + if padcharshortcutkeys[int1] = k1 then begin + mstr1:= padcharshortcutnames[int1]; + break; + end; + end; + end; + if mstr1 = '' then begin + for int1:= 0 to high(padspecialshortcutkeys) do begin + if padspecialshortcutkeys[int1] = k1 then begin + mstr1:= padspecialshortcutnames[int1]; + break; + end; + end; + end; + if mstr1 = '' then begin + if key = 0 then begin + result:= ''; + end + else begin + result:= '$'+hextostrmse(key,4); + end; + end + else begin + result:= ''; + if (key and shift) <> 0 then begin + result:= result + 'Shift+'; + end; + if (key and alt) <> 0 then begin + result:= result + 'Alt+'; + end; + if (key and ctrl) <> 0 then begin + result:= result + 'Ctrl+'; + end; + if (key and pad) <> 0 then begin + result:= result + 'Pad+'; + end; + result:= result + mstr1; + end; +end; + +function encodeshortcutname(const key: shortcutarty): msestring; +var + int1: integer; +begin + result:= ''; + if high(key) >= 0 then begin + for int1:= 0 to high(key) do begin + result:= result + encodeshortcutname(key[int1]) + ' '; + end; + setlength(result,length(result)-1); + end; +end; + +procedure calccaptiontext(var info: actioninfoty; const aseparator: msechar); +var + str1: msestring; +begin + str1:= info.captiontext; + if (info.shortcut <> nil) and (mao_shortcutcaption in info.options) then begin + str1:= str1 + aseparator + '('+encodeshortcutname(info.shortcut)+')'; + end; + captiontorichstring(str1,info.caption1); +end; + +function issameshortcut(const a,b: shortcutarty): boolean; +var + int1: integer; +begin + result:= (a = b); + if not result then begin + result:= high(a) = high(b); + if result then begin + for int1:= 0 to high(a) do begin + if a[int1] <> b[int1] then begin + result:= false; + break; + end; + end; + end; + end; +end; + +function getsimpleshortcut(const asource: shortcutarty): shortcutty; +begin + result:= 0; + if asource <> nil then begin + result:= asource[0]; + end; +end; + +function getsimpleshortcut(const asource: actioninfoty): shortcutty; +begin + result:= 0; + if asource.shortcut <> nil then begin + result:= asource.shortcut[0]; + end; +end; + +function getsimpleshortcut1(const asource: actioninfoty): shortcutty; +begin + result:= 0; + if asource.shortcut1 <> nil then begin + result:= asource.shortcut1[0]; + end; +end; + +procedure setsimpleshortcut(const avalue: shortcutty; var adest: shortcutarty); +begin + if avalue = 0 then begin + adest:= nil; + end + else begin + setlength(adest,1); + adest[0]:= avalue; + end; +end; + +function setsimpleshortcut(const avalue: shortcutty): shortcutarty; +begin + setsimpleshortcut(avalue,result); +end; + +procedure setsimpleshortcut(const avalue: shortcutty; var adest: actioninfoty); +begin + if avalue = 0 then begin + adest.shortcut:= nil; + end + else begin + setlength(adest.shortcut,1); + adest.shortcut[0]:= avalue; + end; +end; + +procedure setsimpleshortcut1(const avalue: shortcutty; var adest: actioninfoty); +begin + if avalue = 0 then begin + adest.shortcut1:= nil; + end + else begin + setlength(adest.shortcut1,1); + adest.shortcut1[0]:= avalue; + end; +end; + +function checkshortcutconflict(const a,b: shortcutarty): boolean; + function pos1(const sub,checked:shortcutarty): boolean; + var + int1,int2: integer; + begin + result:= sub <> nil; + if result then begin + result:= sub = checked; + if not result and (high(checked) >= high(sub)) then begin + for int1:= 0 to high(checked) - high(sub) do begin + if checked[int1] = sub[0] then begin + result:= true; + for int2:= 1 to high(sub) do begin + if checked[int1+int2] <> sub[int2] then begin + result:= false; + break; + end; + end; + if result then begin + break; + end; + end; + end; + end; + end; + end; //pos1 +begin + result:= pos1(a,b) or pos1(b,a); +end; + +procedure setactionshortcut(const sender: iactionlink; const value: shortcutty); +var + po1: pactioninfoty; +begin + po1:= sender.getactioninfopo; + setsimpleshortcut(value,po1^); + include(po1^.state,as_localshortcut); + sender.calccaptiontext(po1^{,sender.shortcutseparator}); + sender.actionchanged; +end; + +procedure setactionshortcut1(const sender: iactionlink; const value: shortcutty); +var + po1: pactioninfoty; +begin + po1:= sender.getactioninfopo; + setsimpleshortcut1(value,po1^); + include(po1^.state,as_localshortcut1); + sender.actionchanged; +end; + +procedure setactionshortcuts(const sender: iactionlink; + const value: shortcutarty); +var + po1: pactioninfoty; +begin + po1:= sender.getactioninfopo; + po1^.shortcut:= value; + include(po1^.state,as_localshortcut); + sender.calccaptiontext(po1^{,sender.shortcutseparator}); + sender.actionchanged; +end; + +procedure setactionshortcuts1(const sender: iactionlink; + const value: shortcutarty); +var + po1: pactioninfoty; +begin + po1:= sender.getactioninfopo; + po1^.shortcut1:= value; + include(po1^.state,as_localshortcut1); + sender.actionchanged; +end; + +function isactionshortcutstored(const info: actioninfoty): boolean; +begin + with info do begin + result:= (as_localshortcut in state) and + not ((action = nil) and (shortcut = nil)); + end; +end; + +function isactionshortcut1stored(const info: actioninfoty): boolean; +begin + with info do begin + result:= (as_localshortcut1 in state) and + not ((action = nil) and (shortcut1 = nil)); + end; +end; + +procedure setactionimagelist(const sender: iactionlink; const value: timagelist); +begin + with sender.getactioninfopo^ do begin + if not (as_localimagelist in state) then begin + imagelist:= nil; //do not unink,imagelist is owned by action + end; + setlinkedcomponent(sender,value,tmsecomponent(imagelist)); + include(state,as_localimagelist); + end; + sender.actionchanged; +end; + +function isactionimageliststored(const info: actioninfoty): boolean; +begin + with info do begin + result:= (as_localimagelist in state) and + not ((action = nil) and (imagelist = nil)); + end; +end; + +function checkshortcutcode(const shortcut: shortcutty; + const info: keyeventinfoty; const apreview: boolean = false): boolean; +var + acode: shortcutty; +begin + result:= false; + if (shortcut <> 0) and + ((es_preview in info.eventstate) xor not apreview) then begin + with info do begin + acode:= 0; + if ss_shift in shiftstate then begin + acode:= acode or key_modshift; + end; + if ss_ctrl in shiftstate then begin + acode:= acode or key_modctrl; + end; + if ss_alt in shiftstate then begin + acode:= acode or key_modalt; + end; + if ss_second in shiftstate then begin + acode:= acode or key_modpad; + end; + result:= (acode or ord(key) = shortcut) or + (acode or ord(keynomod) = shortcut); + end; + end; +end; + +function checkshortcutcode(const shortcut: shortcutty; + const info: keyinfoty): boolean; +var + acode: shortcutty; +begin + result:= false; + if (shortcut <> 0) then begin + with info do begin + acode:= 0; + if ss_shift in shiftstate then begin + acode:= acode or key_modshift; + end; + if ss_ctrl in shiftstate then begin + acode:= acode or key_modctrl; + end; + if ss_alt in shiftstate then begin + acode:= acode or key_modalt; + end; + if ss_second in shiftstate then begin + acode:= acode or key_modpad; + end; + result:= (acode or ord(key) = shortcut) or + (acode or ord(keynomod) = shortcut); + end; + end; +end; + +function getshortcutcodenomod(const info: keyeventinfoty): shortcutty; +begin + with info do begin + result:= ord(info.keynomod); + if ss_shift in info.shiftstate then begin + result:= result or key_modshift; + end; + if ss_ctrl in info.shiftstate then begin + result:= result or key_modctrl; + end; + if ss_alt in info.shiftstate then begin + result:= result or key_modalt; + end; + end; +end; + +{ +function doactionshortcut(const sender: tobject; var info: actioninfoty; + var keyinfo: keyeventinfoty): boolean; + //true if done +var + key: word; +begin + result:= false; + with info do begin + if not (as_disabled in state) and not (es_processed in keyinfo.eventstate) and + (not (ss_repeat in keyinfo.shiftstate) or + (as_repeatshortcut in info.state)) then begin + if high(shortcut) = 0 then begin + if checkshortcutcode(shortcut[0],keyinfo) then begin + doactionexecute(sender,info,false,false); + result:= true; + end; + end; + if not result then begin + if high(shortcut1) = 0 then begin + if checkshortcutcode(shortcut1[0],keyinfo) then begin + doactionexecute(sender,info); + result:= true; + end; + end; + end; + if result then begin + include(keyinfo.eventstate,es_processed); + end; + end; + end; +end; +} + +function check(const ar1: shortcutarty; out exec: boolean; + var keyinfo: keyeventinfoty): boolean; +var + int1,int2,int3: integer; +begin +{ + if anum = 2 then begin + ar1:= info.shortcut1; + end + else begin + ar1:= info.shortcut; + end; +} + result:= false; + exec:= false; + if (high(ar1) > 0) and (es_preview in keyinfo.eventstate) then begin + exec:= true; + for int1:= high(ar1) downto 0 do begin + if checkshortcutcode(ar1[int1],keyinfo,true) then begin + result:= true; + with application do begin + if high(keyhistory) >= int1-1 then begin + int3:= 0; + if int1 > 0 then begin + for int2:= int1 - 1 downto 0 do begin + if not checkshortcutcode(ar1[int2],keyhistory[int3]) then begin + result:= false; + exec:= false; + break; + end; + inc(int3); + end; + end + else begin + exec:= false; + end; + end + else begin + exec:= false; + result:= false; + end; + end; + if exec then begin + break; + end; + end + else begin + exec:= false + end; + end; + if exec then begin + application.clearkeyhistory; + end; + end + else begin + if high(ar1) >= 0 then begin + if checkshortcutcode(ar1[0],keyinfo,false) then begin + result:= true; + if high(ar1) = 0 then begin + exec:= true; + end; + end; + end; + end; +end; //check + +function checkactionshortcut(var info: actioninfoty; + var keyinfo: keyeventinfoty): boolean; //true if done +var + bo1: boolean; +begin + bo1:= check(info.shortcut,result,keyinfo); + if not bo1 then begin + bo1:= check(info.shortcut1,result,keyinfo); + end; + if bo1 then begin + include(keyinfo.eventstate,es_processed); + end; +end; + +function checkactionshortcut(const ashortcut: shortcutarty; + var keyinfo: keyeventinfoty): boolean; //true if done +begin + if check(ashortcut,result,keyinfo) then begin + include(keyinfo.eventstate,es_processed); + end; +end; + + +function doactionshortcut(const sender: tobject; var info: actioninfoty; + var keyinfo: keyeventinfoty; + const beforeexecute: proceventty = nil): boolean; //true if done +var + bo1: boolean; +begin + result:= checkactionshortcut(info,keyinfo); + if result then begin + result:= doactionexecute1(sender,info,bo1,false,false,beforeexecute); + end; +end; + +{ taction } + +function taction.getimagelist: timagelist; +begin + result:= timagelist(finfo.imagelist); +end; + +procedure taction.setimagelist(const Value: timagelist); +begin + if value <> finfo.imagelist then begin + setlinkedvar(value,tmsecomponent(finfo.imagelist)); + changed; + end; +end; +{ +function taction.getshortcut: shortcutty; +begin + result:= shortcutty(finfo.shortcut); +end; +} +function taction.getshortcut: shortcutty; +begin + result:= getsimpleshortcut(finfo); +end; + +procedure taction.setshortcut(const avalue: shortcutty); +begin + setsimpleshortcut(avalue,finfo); + changed; +end; + +function taction.getshortcut1: shortcutty; +begin + result:= getsimpleshortcut1(finfo); +end; + +procedure taction.setshortcut1(const avalue: shortcutty); +begin + setsimpleshortcut1(avalue,finfo); + changed; +end; + +procedure taction.setshortcuts(const avalue: shortcutarty); +begin + finfo.shortcut:= avalue; + changed; +end; + +procedure taction.setshortcuts1(const avalue: shortcutarty); +begin + finfo.shortcut1:= avalue; + changed; +end; + +procedure taction.registeronshortcut(const avalue: boolean); +begin + if avalue then begin + application.registeronshortcut({$ifdef FPC}@{$endif}doshortcut); + end + else begin + application.unregisteronshortcut({$ifdef FPC}@{$endif}doshortcut); + end; +end; + +procedure taction.doshortcut(const sender: twidget; var keyinfo: keyeventinfoty); +begin + if not (es_local in keyinfo.eventstate) and (ao_globalshortcut in foptions) or + (es_local in keyinfo.eventstate) and (ao_localshortcut in foptions) and + (owner <> nil) and issubcomponent(owner,sender) then begin + doupdate; + with finfo do begin + if not (as_disabled in state) and + not (es_processed in keyinfo.eventstate) and + (not (ss_repeat in keyinfo.shiftstate) or + (as_repeatshortcut in finfo.state)) then begin + if doactionshortcut(sender,finfo,keyinfo) then begin + changed; + end; + end; + end; + end; +end; + +(* +procedure taction.doshortcut(const sender: twidget; var keyinfo: keyeventinfoty); + + function check(const anum: integer; out exec: boolean): boolean; + var + ar1: shortcutarty; + int1,int2,int3: integer; + begin + if anum = 2 then begin + ar1:= finfo.shortcut1; + end + else begin + ar1:= finfo.shortcut; + end; + result:= false; + exec:= false; + if (high(ar1) > 0) and (es_preview in keyinfo.eventstate) then begin + exec:= true; + for int1:= high(ar1) downto 0 do begin + if checkshortcutcode(ar1[int1],keyinfo,true) then begin + result:= true; + with application do begin + if high(keyhistory) >= int1-1 then begin + int3:= 0; + if int1 > 0 then begin + for int2:= int1 - 1 downto 0 do begin + if not checkshortcutcode(ar1[int2],keyhistory[int3]) then begin + result:= false; + exec:= false; + break; + end; + inc(int3); + end; + end + else begin + exec:= false; + end; + end + else begin + exec:= false; + result:= false; + end; + end; + if exec then begin + break; + end; + end + else begin + exec:= false + end; + end; + if exec then begin + application.clearkeyhistory; + end; + end + else begin + if high(ar1) >= 0 then begin + if checkshortcutcode(ar1[0],keyinfo,false) then begin + result:= true; + if high(ar1) = 0 then begin + exec:= true; + end; + end; + end; + end; + end; //check + +var + bo1,bo2: boolean; +begin + bo1:= false; + if not (es_local in keyinfo.eventstate) and (ao_globalshortcut in foptions) or + (es_local in keyinfo.eventstate) and (ao_localshortcut in foptions) and + (owner <> nil) and issubcomponent(owner,sender) then begin + doupdate; + with finfo do begin + if not (as_disabled in state) and + not (es_processed in keyinfo.eventstate) and + (not (ss_repeat in keyinfo.shiftstate) or + (as_repeatshortcut in finfo.state)) then begin + bo1:= check(1,bo2); + if not bo1 then begin + bo1:= check(2,bo2); + end; + end; + end; + end; + if bo1 then begin + include(keyinfo.eventstate,es_processed); + if bo2 then begin + doactionexecute(sender,finfo,false,false); + changed; + end; + end; +end; +*) +procedure taction.doafterunlink; +begin + imagelist:= nil; +end; + +procedure taction.readshortcut(reader: treader); +begin + shortcut:= translateshortcut(reader.readinteger); +end; + +procedure taction.readshortcut1(reader: treader); +begin + shortcut1:= translateshortcut(reader.readinteger); +end; + +procedure taction.readsc(reader: treader); +begin + shortcuts:= readshortcutarty(reader); +end; + +procedure taction.writesc(writer: twriter); +begin + writeshortcutarty(writer,finfo.shortcut); +end; + +procedure taction.readsc1(reader: treader); +begin + shortcuts1:= readshortcutarty(reader); +end; + +procedure taction.writesc1(writer: twriter); +begin + writeshortcutarty(writer,finfo.shortcut1); +end; + +procedure taction.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('shortcut',{$ifdef FPC}@{$endif}readshortcut,nil,false); + filer.defineproperty('shortcut1',{$ifdef FPC}@{$endif}readshortcut1,nil,false); + filer.defineproperty('sc',{$ifdef FPC}@{$endif}readsc, + {$ifdef FPC}@{$endif}writesc, + (filer.ancestor = nil) and (shortcuts <> nil) or + ((filer.ancestor <> nil) and + not issameshortcut(shortcuts,taction(filer.ancestor).shortcuts))); + filer.defineproperty('sc1',{$ifdef FPC}@{$endif}readsc1, + {$ifdef FPC}@{$endif}writesc1, + (filer.ancestor = nil) and (shortcuts1 <> nil) or + ((filer.ancestor <> nil) and + not issameshortcut(shortcuts1,taction(filer.ancestor).shortcuts1))); +end; + +function taction.getactioninfopo: pactioninfoty; +begin + result:= @finfo; +end; + +procedure taction.actionchanged; +begin + changed; +end; + +function taction.shortcutseparator: msechar; +begin + result:= ' '; +end; + +procedure taction.calccaptiontext(var ainfo: actioninfoty); +begin + //dummy +end; + +{ tshortcutactions } + +constructor tshortcutactions.create(const aowner: tshortcutcontroller); +begin + inherited create(aowner,tshortcutaction); +end; + +class function tshortcutactions.getitemclasstype: persistentclassty; +begin + result:= tshortcutaction; +end; + +function tshortcutactions.getitems(const index: integer): tshortcutaction; +begin + result:= tshortcutaction(inherited getitems(index)); +end; + +{ tshortcutcontroller } + +constructor tshortcutcontroller.create(aowner: tcomponent); +begin + factions:= tshortcutactions.create(self); + fsysshortcuts:= tsysshortcuts.create(self,@mseactions.sysshortcuts); + fsysshortcuts1:= tsysshortcuts.create(self,@mseactions.sysshortcuts1); + fassistiveshortcuts:= tassistiveshortcuts.create(self, + @mseactions.assistiveshortcuts); + fassistiveshortcuts1:= tassistiveshortcuts.create(self, + @mseactions.assistiveshortcuts1); + inherited; +end; + +destructor tshortcutcontroller.destroy; +begin + inherited; + factions.free; + fsysshortcuts.free; + fsysshortcuts1.free; + fassistiveshortcuts.free; + fassistiveshortcuts1.free; +end; + +procedure tshortcutcontroller.setactions(const avalue: tshortcutactions); +begin + factions.assign(avalue); +end; + +procedure tshortcutcontroller.setstatfile(const avalue: tstatfile); +begin + setstatfilevar(istatfile(self),avalue,fstatfile); +end; + +procedure tshortcutcontroller.setactionreccount(const acount: integer); +begin + fstatinfos:= nil; + setlength(fstatinfos,acount); +end; + +procedure tshortcutcontroller.setactionrecord(const index: integer; + const avalue: msestring); +var + ar1: msestringarty; + int1,int2: integer; +begin + ar1:= splitstring(avalue, msechar(' ')); + with fstatinfos[index] do begin + if high(ar1) >= 0 then begin + name:= ansistring(ar1[0]); + setlength(shortcut,high(ar1) div 2); + setlength(shortcut1,length(shortcut)); + //backward compatibilty with single shortcut + int2:= 1; + for int1:= 0 to high(shortcut) do begin + shortcut[int1]:= translateshortcut(strtoint(ar1[int2])); + inc(int2); + shortcut1[int1]:= translateshortcut(strtoint(ar1[int2])); + inc(int2); + end; + for int1:= 0 to high(shortcut) do begin + if shortcut[int1] = 0 then begin + setlength(shortcut,int1); + break; + end; + end; + for int1:= 0 to high(shortcut1) do begin + if shortcut1[int1] = 0 then begin + setlength(shortcut1,int1); + break; + end; + end; + end; + end; +end; + +procedure tshortcutcontroller.dostatread(const reader: tstatreader); +begin + if reader.candata then begin + fsysshortcuts.dostatread('sysshortcuts',reader); + fsysshortcuts1.dostatread('sysshortcuts1',reader); + fassistiveshortcuts.dostatread('assistiveshortcuts',reader); + fassistiveshortcuts1.dostatread('assistiveshortcuts1',reader); + reader.readrecordarray('shortcuts',{$ifdef FPC}@{$endif}setactionreccount, + {$ifdef FPC}@{$endif}setactionrecord); + end; +end; + +function tshortcutcontroller.getactionrecord(const index: integer): msestring; +var + int1,int2: integer; +begin + with tshortcutaction(factions[index]) do begin + if action <> nil then begin + result:= msestring(ownernamepath(action)); + with action do begin + int2:= high(shortcuts); + if high(shortcuts1) > int2 then begin + int2:= high(shortcuts1) + end; + for int1:= 0 to int2 do begin + if int1 <= high(shortcuts) then begin + result:= result + ' '+inttostrmse(shortcuts[int1]); + end + else begin + result:= result + ' 0'; + end; + if int1 <= high(shortcuts1) then begin + result:= result + ' '+inttostrmse(shortcuts1[int1]); + end + else begin + result:= result + ' 0'; + end; + end; + end; +// result:= encoderecord([ownernamepath(action),integer(action.shortcut), +// integer(action.shortcut1)]); + end + else begin + result:= ''; + end; + end; +end; + +procedure tshortcutcontroller.dostatwrite(const writer: tstatwriter); +begin + if writer.candata then begin + fsysshortcuts.dostatwrite('sysshortcuts',writer); + fsysshortcuts1.dostatwrite('sysshortcuts1',writer); + fassistiveshortcuts.dostatwrite('assistiveshortcuts',writer); + fassistiveshortcuts1.dostatwrite('assistiveshortcuts1',writer); + writer.writerecordarray('shortcuts',factions.count, + {$ifdef FPC}@{$endif}getactionrecord); + end; +end; + +procedure tshortcutcontroller.statreading; +begin + //dummy +end; + +procedure tshortcutcontroller.doafterupdate; +begin + if canevent(tmethod(fonafterupdate)) then begin + fonafterupdate(self); + end; +end; + +procedure tshortcutcontroller.statread; +var + int1: integer; +begin + for int1:= 0 to factions.count - 1 do begin + with factions[int1] do begin + if action <> nil then begin + updateaction(action); + end; + end; + end; + doafterupdate; +end; + +function tshortcutcontroller.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +procedure tshortcutcontroller.updateaction(const aaction: taction); +var + int1: integer; + str1: ansistring; +begin + str1:= ownernamepath(aaction); + for int1:= 0 to high(fstatinfos) do begin + with fstatinfos[int1] do begin + if str1 = name then begin + aaction.shortcuts:= shortcut; + aaction.shortcuts1:= shortcut1; + end; + end; + end; +end; + +procedure tshortcutcontroller.setsysshortcuts(const avalue: tsysshortcuts); +begin + fsysshortcuts.assign(avalue); +end; + +procedure tshortcutcontroller.setsysshortcuts1(const avalue: tsysshortcuts); +begin + fsysshortcuts1.assign(avalue); +end; + +procedure tshortcutcontroller.setassistiveshortcuts( + const avalue: tassistiveshortcuts); +begin + fassistiveshortcuts.assign(avalue); +end; + +procedure tshortcutcontroller.setassistiveshortcuts1( + const avalue: tassistiveshortcuts); +begin + fassistiveshortcuts1.assign(avalue); +end; + +function tshortcutcontroller.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +{ tshortcutaction } + +procedure tshortcutaction.setaction(const avalue: taction); +begin + with tshortcutcontroller(fowner) do begin + setlinkedvar(avalue,tmsecomponent(faction)); + if (avalue <> nil) then begin + if csdesigning in componentstate then begin + shortcutsdefault:= avalue.shortcuts; + shortcuts1default:= avalue.shortcuts1; + end + else begin + updateaction(avalue); + end; + end; + end; +end; + +function tshortcutaction.getshortcutdefault: shortcutty; +begin + result:= getsimpleshortcut(finfo.shortcut); +end; + +procedure tshortcutaction.setshortcutdefault(const avalue: shortcutty); +begin + setsimpleshortcut(avalue,finfo.shortcut); +end; + +function tshortcutaction.getshortcut1default: shortcutty; +begin + result:= getsimpleshortcut(finfo.shortcut1); +end; + +procedure tshortcutaction.setshortcut1default(const avalue: shortcutty); +begin + setsimpleshortcut(avalue,finfo.shortcut1); +end; + +procedure tshortcutaction.readsc(reader: treader); +begin + finfo.shortcut:= readshortcutarty(reader); +end; + +procedure tshortcutaction.writesc(writer: twriter); +begin + writeshortcutarty(writer,finfo.shortcut); +end; + +procedure tshortcutaction.readsc1(reader: treader); +begin + finfo.shortcut:= readshortcutarty(reader); +end; + +procedure tshortcutaction.writesc1(writer: twriter); +begin + writeshortcutarty(writer,finfo.shortcut); +end; + +procedure tshortcutaction.readshortcut(reader: treader); +begin + shortcutdefault:= translateshortcut(reader.readinteger); +end; + +procedure tshortcutaction.readshortcut1(reader: treader); +begin + shortcut1default:= translateshortcut(reader.readinteger); +end; + +procedure tshortcutaction.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('shortcut',{$ifdef FPC}@{$endif}readshortcut,nil,false); + filer.defineproperty('shortcut1',{$ifdef FPC}@{$endif}readshortcut1,nil,false); + filer.defineproperty('sc',{$ifdef FPC}@{$endif}readsc, + {$ifdef FPC}@{$endif}writesc, + (filer.ancestor = nil) and (finfo.shortcut <> nil) or + ((filer.ancestor <> nil) and + not issameshortcut(finfo.shortcut, + tshortcutaction(filer.ancestor).shortcutsdefault))); + filer.defineproperty('sc1',{$ifdef FPC}@{$endif}readsc1, + {$ifdef FPC}@{$endif}writesc1, + (filer.ancestor = nil) and (finfo.shortcut1 <> nil) or + ((filer.ancestor <> nil) and + not issameshortcut(finfo.shortcut1, + tshortcutaction(filer.ancestor).shortcuts1default))); +end; + +procedure tshortcutaction.setshortcuts(const avalue: shortcutarty); +begin + finfo.shortcut:= avalue; +end; + +procedure tshortcutaction.setshortcuts1(const avalue: shortcutarty); +begin + finfo.shortcut1:= avalue; +end; + +function tshortcutaction.getactioninfopo: pactioninfoty; +begin + result:= @finfo; +end; + +procedure tshortcutaction.actionchanged; +begin + //dummy +end; + +function tshortcutaction.loading: boolean; +begin + result:= csloading in tcomponent(fowner).componentstate; +end; + +function tshortcutaction.shortcutseparator: msechar; +begin + result:= ' '; //not used +end; + +procedure tshortcutaction.calccaptiontext(var ainfo: actioninfoty); +begin + mseactions.calccaptiontext(ainfo,shortcutseparator); +end; + +{ tsysshortcuts } + +constructor tsysshortcuts.create(const aowner: tcomponent; + const adatapo: psysshortcutaty); +var + sc1: sysshortcutty; +begin + inherited create; + inherited setfixcount(ord(high(sysshortcutty))+1); + fowner:= aowner; + fdatapo:= adatapo; + for sc1:= low(sc1) to high(sc1) do begin + fitems[ord(sc1)]:= ord(fdatapo^[sc1]); //init with current values + end; +end; + +function tsysshortcuts.getitems(const index: sysshortcutty): shortcutty; +begin + result:= inherited getitems(ord(index)); +end; + +procedure tsysshortcuts.setitems(const index: sysshortcutty; + const avalue: shortcutty); +begin + inherited setitems(ord(index),ord(avalue)); +end; + +procedure tsysshortcuts.setfixcount(const avalue: integer); +begin + //dummy +end; + +procedure tsysshortcuts.dochange(const aindex: integer); +var + sc1: sysshortcutty; +begin + inherited; + if (fowner <> nil) and not (csdesigning in fowner.componentstate) then begin + if aindex < 0 then begin + for sc1:= low(sc1) to high(sc1) do begin + fdatapo^[sc1]:= fitems[ord(sc1)]; + end; + end + else begin + fdatapo^[sysshortcutty(aindex)]:= fitems[aindex]; + end; + end; +end; + +procedure tsysshortcuts.setshortcutcount(const acount: integer); +begin + setlength(fshortcuts,acount); +end; + +procedure tsysshortcuts.setshortcutrecord(const index: integer; + const avalue: msestring); +begin + with fshortcuts[index] do begin + decoderecord(avalue,[@name,@value],'si'); + end; +end; + +procedure tsysshortcuts.dostatread(const varname: msestring; + const reader: tstatreader); +var + int1,int2: integer; +begin + fshortcuts:= nil; + reader.readrecordarray(varname,{$ifdef FPC}@{$endif}setshortcutcount, + {$ifdef FPC}@{$endif}setshortcutrecord); + for int1:= 0 to high(fshortcuts) do begin + with fshortcuts[int1] do begin + value:= translateshortcut(value); + int2:= getenumvalue(typeinfo(sysshortcutty),name); + if int2 >= 0 then begin + items[sysshortcutty(int2)]:= value; + end; + end; + end; + fshortcuts:= nil; +end; + +function tsysshortcuts.getshortcutrecord(const index: integer): msestring; +begin + result:= encoderecord([getenumname(typeinfo(sysshortcutty),index),fitems[index]]); +end; + +procedure tsysshortcuts.dostatwrite(const varname: msestring; + const writer: tstatwriter); +begin + writer.writerecordarray(varname,count, + {$ifdef FPC}@{$endif}getshortcutrecord); +end; + +procedure tsysshortcuts.readitem(const index: integer; reader: treader); +begin + inherited; + fitems[index]:= translateshortcut(fitems[index]); +end; + +{ tassistiveshortcuts } + +constructor tassistiveshortcuts.create(const aowner: tcomponent; + const adatapo: passistiveshortcutaty); +var + sc1: assistiveshortcutty; +begin + inherited create; + inherited setfixcount(ord(high(assistiveshortcutty))+1); + fowner:= aowner; + fdatapo:= adatapo; + for sc1:= low(sc1) to high(sc1) do begin + shortcutarty(fitems[ord(sc1)]):= fdatapo^[sc1]; //init with current values + end; +end; + +function tassistiveshortcuts.getitems( + const index: assistiveshortcutty): shortcutarty; +begin + result:= shortcutarty(inherited getitems(ord(index))); +end; + +procedure tassistiveshortcuts.setitems(const index: assistiveshortcutty; + const avalue: shortcutarty); +begin + checkindex(ord(index)); + shortcutarty(fitems[ord(index)]):= avalue; + change(ord(index)); +end; + +procedure tassistiveshortcuts.setfixcount(const avalue: integer); +begin + //dummy +end; + +procedure tassistiveshortcuts.dochange(const aindex: integer); +var + sc1: assistiveshortcutty; +begin + inherited; + if (fowner <> nil) and not (csdesigning in fowner.componentstate) then begin + if aindex < 0 then begin + for sc1:= low(sc1) to high(sc1) do begin + fdatapo^[sc1]:= shortcutarty(fitems[ord(sc1)]); + end; + end + else begin + fdatapo^[assistiveshortcutty(aindex)]:= shortcutarty(fitems[aindex]); + end; + end; +end; + +procedure tassistiveshortcuts.setshortcutcount(const acount: integer); +begin + setlength(fshortcuts,acount); +end; + +procedure tassistiveshortcuts.setshortcutrecord(const index: integer; + const avalue: msestring); +var + s1: string; + ar1: stringarty; + ar2: shortcutarty; + c1: card32; + i1: int32; +begin + with fshortcuts[index] do begin + decoderecord(avalue,[@name,@s1],'ss'); + value:= nil; + ar1:= splitstring(s1,' '); + setlength(ar2,length(ar1)); + for i1:= 0 to high(ar1) do begin + if not trystrtohex(ar1[i1],c1) then begin + exit; + end; + ar2[i1]:= c1; + end; + value:= ar2; + end; +end; + +procedure tassistiveshortcuts.internalsetcount(const acount: int32); +begin + setlength(int16ararty(fitems),acount); +end; + +procedure tassistiveshortcuts.dostatread(const varname: msestring; + const reader: tstatreader); +var + int1,int2: integer; +begin + fshortcuts:= nil; + reader.readrecordarray(varname,@setshortcutcount,@setshortcutrecord); + for int1:= 0 to high(fshortcuts) do begin + with fshortcuts[int1] do begin +// value:= translateshortcut(value); + int2:= getenumvalue(typeinfo(assistiveshortcutty),name); + if int2 >= 0 then begin + items[assistiveshortcutty(int2)]:= value; + end; + end; + end; + fshortcuts:= nil; +end; + +function tassistiveshortcuts.getshortcutrecord(const index: integer): msestring; +var + s1: string; + i1: int32; + ar1: shortcutarty; +begin + ar1:= shortcutarty(fitems[index]); + s1:= ''; + for i1:= 0 to high(ar1) do begin + s1:= s1+hextostr(ar1[i1],4); + if i1 <> high(ar1) then begin + s1:= s1+' '; + end; + end; + result:= encoderecord([getenumname(typeinfo(assistiveshortcutty),index),s1]); +end; + +procedure tassistiveshortcuts.dostatwrite(const varname: msestring; + const writer: tstatwriter); +begin + writer.writerecordarray(varname,count,@getshortcutrecord); +end; + +procedure tassistiveshortcuts.writeitem(const index: integer; writer: twriter); +begin + writeintar(writer,int16arty(fitems[index])); +end; + +procedure tassistiveshortcuts.readitem(const index: integer; reader: treader); +var + ar1: int16arty; +begin + readintar(reader,ar1); + int16arty(fitems[index]):= ar1; +// inherited; +// fitems[index]:= translateshortcut(fitems[index]); +end; + +{ tcustomhelpcontroller } + +constructor tcustomhelpcontroller.create(aowner: tcomponent); +begin + inherited; + if not (csdesigning in componentstate) then begin + application.registerhelphandler({$ifdef FPC}@{$endif}dohelp); + end; +end; + +destructor tcustomhelpcontroller.destroy; +begin + if not (csdesigning in componentstate) then begin + application.unregisterhelphandler({$ifdef FPC}@{$endif}dohelp); + fshortcut:= 0; + fshortcut1:= 0; + checkshortcuts(); //unregister + end; + inherited; +end; + +procedure tcustomhelpcontroller.setshortcut(const avalue: shortcutty); +begin + if avalue <> fshortcut then begin + fshortcut:= avalue; + checkshortcuts(); + end; +end; + +procedure tcustomhelpcontroller.setshortcut1(const avalue: shortcutty); +begin + if avalue <> fshortcut1 then begin + fshortcut1:= avalue; + checkshortcuts(); + end; +end; + +procedure tcustomhelpcontroller.checkshortcuts(); +begin + if not (csdesigning in componentstate) and + (fshortcutregistered xor + ((fshortcut <> 0) or (fshortcut1 <> 0))) then begin + if fshortcutregistered then begin + application.unregisteronshortcut(@doshortcut); + fshortcutregistered:= false; + end + else begin + application.registeronshortcut(@doshortcut); + fshortcutregistered:= true; + end; + end; +end; + +procedure tcustomhelpcontroller.dohelp(const sender: tmsecomponent; + var handled: boolean); +begin + if not handled and canevent(tmethod(fonhelp)) then begin + fonhelp(self,sender,handled); + end; + if not handled and assigned(fonhelp1) then begin + fonhelp1(self,sender,handled); + end; +end; + +procedure tcustomhelpcontroller.doshortcut(const sender: twidget; + var keyinfo: keyeventinfoty); +begin + if not (es_processed in keyinfo.eventstate) and + not (ss_repeat in keyinfo.shiftstate) and + (checkshortcutcode(fshortcut,keyinfo) or + checkshortcutcode(fshortcut1,keyinfo)) then begin + include(keyinfo.eventstate,es_processed); + application.help(sender); + end; +end; + +procedure doinit(); + + procedure setdefault(const source: assistiveshortcutconstty; + out dest: assistiveshortcutaty); + var + i1: int32; + sh1: assistiveshortcutty; + begin + for sh1:= low(sh1) to high(sh1) do begin + dest[sh1]:= nil; + for i1:= 0 to high(source[low(sh1)]) do begin + if source[sh1][i1] = 0 then begin + break; + end; + additem(int16arty(dest[sh1]),int16(source[sh1][i1])); + end; + end; + end; //setdefault + +begin + sysshortcuts:= defaultsysshortcuts; + sysshortcuts1:= defaultsysshortcuts1; + setdefault(defaultassistiveshortcuts,assistiveshortcuts); + setdefault(defaultassistiveshortcuts1,assistiveshortcuts1); + assistiveexechandler:= @handleassistiveexec; +end; + +initialization + doinit(); +end. diff --git a/mseide-msegui/lib/common/kernel/mseapplication.pas b/mseide-msegui/lib/common/kernel/mseapplication.pas new file mode 100644 index 0000000..d2a931d --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseapplication.pas @@ -0,0 +1,2147 @@ +{ MSEgui Copyright (c) 1999-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseapplication; +{$ifdef FPC} + {$mode objfpc}{$h+}{$interfaces corba} +{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} + +{$ifdef mse_debuglock} + {$define mse_debugmutex} +{$endif} +{$ifdef mse_debuggdisync} + {$define mse_debugmutex} +{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,mseclasses,mseevent,mseglob,sysutils,msetypes,mselist, + msethread,msesystypes,msesys,{msethreadcomp,}msestrings,mseinterfaces + {$ifdef mse_with_ifi},mseifiglob{$endif}; + +type + activatoroptionty = (avo_activateonloaded,avo_activatedelayed, + avo_deactivateonterminated,avo_deactivatebottomup, + avo_handleexceptions,avo_quietexceptions, + avo_abortonexception,avo_waitcursor); + activatoroptionsty = set of activatoroptionty; + activatorabortactionty = (aaa_abortexception,aaa_abort,aaa_deactivate, + aaa_retry); + +const + defaultactivatoroptions = [avo_handleexceptions,avo_quietexceptions]; + +type + iactivator = interface(inullinterface) + end; + iactivatorclient = interface(inullinterface)[miid_iactivatorclient] + procedure setactive(const avalue: boolean); + end; + + tactivator = class; + + activateerroreventty = procedure(const sender: tactivator; + const aclient: tobject; const aexception: exception; + var handled: boolean) of object; + + actcomponentstatety = (acs_releasing,acs_dooncreatecalled); + actcomponentstatesty = set of actcomponentstatety; + + tactcomponent = class(tmsecomponent,iactivatorclient) + private + factivator: tactivator; + procedure setactivator(const avalue: tactivator); + protected + factstate: actcomponentstatesty; + fdesignchangedlock: integer; + procedure designchanged(const apropname: string = ''; + const apropindex: int32 = -1); //for designer notify + procedure loaded; override; + procedure doactivated; virtual; + procedure dodeactivated; virtual; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + procedure receiveevent(const event: tobjectevent); override; + {$ifdef mse_with_ifi} + procedure executeificommand(var acommand: ificommandcodety); override; + {$endif} + //iactivatorclient + procedure setactive(const avalue: boolean); virtual; + public + procedure release(const nomodaldefer: boolean=false); virtual; + function releasing: boolean; + procedure deactivate(const achildren: boolean = true); virtual; + property activator: tactivator read factivator write setactivator; + end; + pactcomponent = ^tactcomponent; + + applicationeventeventty = procedure(const sender: tactcomponent; + var aevent: tmseevent; var handled: boolean) of object; + + activatoraborteventty = procedure(const sender: tactivator; + var aaction: activatorabortactionty) of object; + tactivator = class(tactcomponent) + private + foptions: activatoroptionsty; + fonbeforeactivate: notifyeventty; + fonafteractivate: notifyeventty; + fonbeforedeactivate: notifyeventty; + fonafterdeactivate: notifyeventty; + factive: boolean; + factivated: boolean; + factivecount: integer; + fonactivateerror: activateerroreventty; + fonabort: activatoraborteventty; + fabortaction: activatorabortactionty; + procedure readclientnames(reader: treader); + procedure writeclientnames(writer: twriter); + function getclients: integer; + procedure setclients(const avalue: integer); + procedure setoptions(const avalue: activatoroptionsty); + function getclientinstances(const index: integer): tobject; + function getclientinterfaces(const index: integer): iobjectlink; + protected + fclientnames: stringarty; + fclients: pointerarty; + procedure setactive(const avalue: boolean); override; + procedure registerclient(const aclient: iobjectlink); + procedure unregisterclient(const aclient: iobjectlink); + procedure updateorder; + function getclientnames: stringarty; + procedure defineproperties(filer: tfiler); override; + procedure doasyncevent(var atag: integer); override; + procedure loaded; override; + procedure unlink(const source,dest: iobjectlink; + valuepo: pointer = nil); override; + procedure objevent(const sender: iobjectlink; + const event: objecteventty); override; + procedure doterminated(const sender: tobject); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + class procedure addclient(const aactivator: tactivator; + const aclient: iobjectlink; var dest: tactivator); + procedure activaterecursive; //increments activecount + procedure deactivaterecursive; //decrements activecount + procedure activateclients; + procedure deactivateclients; + property activated: boolean read factivated; + property activecount: integer read factivecount; + property clientinstances[const index: integer]: tobject + read getclientinstances; + property clientinterfaces[const index: integer]: iobjectlink + read getclientinterfaces; + property clientcount: integer read getclients; + published + property clients: integer read getclients write setclients; + //hook for object inspector + property options: activatoroptionsty read foptions write setoptions + default defaultactivatoroptions; + property active: boolean read factive write setactive default false; + property abortaction: activatorabortactionty read fabortaction + write fabortaction default aaa_abortexception; + property onbeforeactivate: notifyeventty read fonbeforeactivate + write fonbeforeactivate; + property onactivateerror: activateerroreventty read fonactivateerror + write fonactivateerror; + property onabort: activatoraborteventty read fonabort write fonabort; + property onafteractivate: notifyeventty read fonafteractivate + write fonafteractivate; + property onbeforedeactivate: notifyeventty read fonbeforedeactivate + write fonbeforedeactivate; + property onafterdeactivate: notifyeventty read fonafterdeactivate + write fonafterdeactivate; + property activator; + end; + + tactivatorcontroller = class(tlinkedpersistent) + private + factive: boolean; + floaded: boolean; + factivator: tactivator; + procedure setactivator(const avalue: tactivator); + protected + fowner: tcomponent; + fintf: iactivatorclient; + function getinstance: tobject; override; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + procedure setowneractive(const avalue: boolean); virtual; abstract; + public + constructor create(const aowner: tcomponent; const aintf: iactivatorclient); reintroduce; + function setactive (const value : boolean): boolean; + procedure loaded; + published + property activator: tactivator read factivator write setactivator; + end; + + exceptioneventty = procedure (const sender: tobject; const e: exception; + const leadingtext: msestring; var handled: boolean) of object; + + terminatequeryeventty = procedure (var terminate: boolean) of object; + idleeventty = procedure (var again: boolean) of object; + + tonterminatequerylist = class(tmethodlist) + protected + public + function doterminatequery: boolean; + //true if accepted + end; + + tonidlelist = class(tmethodlist) + protected + public + function doidle: boolean; //true if again requested + public + end; + + applicationstatety = + (aps_inited,aps_running,aps_terminated,aps_mousecaptured, + aps_invalidated,aps_zordervalid,aps_needsupdatewindowstack, + aps_focused,aps_activewindowchecked,aps_restorelocktransientfor, + aps_exitloop,aps_cancelloop,aps_looplocked, + aps_active,aps_waiting,aps_woken, + aps_terminating,aps_deinitializing, + aps_shortcutting,aps_clearkeyhistory, + aps_waitstarted,aps_waitcanceled,aps_waitterminated,aps_waitok, + aps_waitidlelock,aps_eventflushing,aps_processmessages); + applicationstatesty = set of applicationstatety; + + synchronizeprocty = procedure(const adata: pointer); + synchronizeeventty = procedure(const adata: pointer) of object; + + teventlist = class(tobjectqueue) + protected + procedure finalizeitem(var item: pointer); override; + end; + + applicationeventhandlereventty = procedure(var aevent: tmseevent; + var handled: boolean) of object; + + tonapplicationeventlist = class(tmethodlist) + public + procedure doevent(var aevent: tmseevent; var handled: boolean); + end; + + applicationoptionty = (apo_terminateonexception,apo_noautodestroymodules); + applicationoptionsty = set of applicationoptionty; + + tcustomapplication = class(tmsecomponent) + private + fapplicationname: filenamety; + flockthread: threadty; + fmutex: mutexty; + feventlist: teventlist; + feventlock: mutexty; + fpostedevents: eventarty; + fpostedeventslocal: eventarty; + fidlecount: integer; + fcheckoverloadlock: integer; + fexceptioncount: integer; + fonexception: exceptioneventty; + finiting: integer; + fhighrestimercount: integer; + function dolock: boolean; + function internalunlock(count: integer): boolean; + function getterminated: boolean; + procedure setterminated(const Value: boolean); + function gethighrestimer: boolean; + protected + flockcount: integer; + foptions: applicationoptionsty; + fthread: threadty; + fstate: applicationstatesty; + fwaitcount: integer; + fserial: card32; + fnoignorewaitevents: integer; + fonterminatedlist: tnotifylist; + fonterminatequerylist: tonterminatequerylist; + fonidlelist: tonidlelist; + fonapplicationeventlist: tonapplicationeventlist; + ftimertriggercount: integer; + procedure receiveevent(const event: tobjectevent); override; + procedure flusheventbuffer; + procedure doidle; + procedure sethighrestimer(const avalue: boolean); virtual; abstract; + procedure dopostevent(const aevent: tmseevent); virtual; abstract; + function getevents: integer; virtual; abstract; + //application must be locked + //returns count of queued events + procedure doeventloop(const once: boolean); virtual; abstract; + procedure incidlecount; + procedure dobeforerun; virtual; + procedure doafterrun; virtual; + procedure dowakeup(sender: tobject); + property eventlist: teventlist read feventlist; + procedure internalinitialize; virtual; + procedure internaldeinitialize; virtual; + procedure objecteventdestroyed(const sender: tobjectevent); virtual; + procedure resettimertrigger; + public + {$ifdef mse_debugmutex} + function getmutexaddr: pointer; + function getmutexcount: integer; + procedure checklockcount; + {$endif} + constructor create(aowner: tcomponent); override; + destructor destroy; override; + + procedure beforedestruction() override; + procedure initialize; + procedure deinitialize; + procedure beginhighrestimer; + procedure endhighrestimer; + property highrestimer: boolean read gethighrestimer; + + function procid: procidty; + function getserial(): card32; + function createdatamodule(instanceclass: msecomponentclassty; + var reference): tmsecomponent; + procedure run; + function running: boolean; //true if eventloop entered + procedure processmessages; virtual; //handle with care! + function idle: boolean; virtual; + function modallevel: integer; virtual; abstract; //-1 invalid, + //0 single loop stack + property applicationname: msestring read fapplicationname + write fapplicationname; + + procedure postevent(event: tmseevent; + const aoptions: posteventoptionsty = []); + //peo_local -> direcly to the internal queue + //peo_first implies peo_local + //peo_modaldefer -> deliver in current modallevel + function checkoverload(const asleepus: integer = 100000): boolean; + //true if never idle since last call, + // unlocks application and calls sleep if not mainthread and asleepus >= 0 + procedure handleexception(sender: tobject = nil; + const leadingtext: msestring = ''); + procedure showexception(e: exception; const leadingtext: msestring = ''); + virtual; abstract; + procedure errormessage(const amessage: msestring); virtual; abstract; + procedure registeronterminated(const method: notifyeventty); + procedure unregisteronterminated(const method: notifyeventty); + procedure registeronterminate(const method: terminatequeryeventty); + procedure unregisteronterminate(const method: terminatequeryeventty); + procedure registeronidle(const method: idleeventty); + procedure unregisteronidle(const method: idleeventty); + procedure registerapplicationeventhandler( + const method: applicationeventhandlereventty); + procedure unregisterapplicationeventhandler( + const method: applicationeventhandlereventty); + + procedure settimer(const us: integer); virtual; + + function islockedthread: boolean; //true if calling thread holds the lock + function islockedmainthread: boolean; + //true if calling thread holds the lock and is mainthread + function trylock: boolean; + function lock: boolean; + //synchronizes calling thread with main event loop (mutex), + //false if calling thread allready holds the mutex + //mutex is recursive + function unlock: boolean; + //release mutex if calling thread holds the mutex, + //false if no unlock done + function unlockall: integer virtual; + //release mutex recursive if calling thread holds the mutex, + //returns count for relockall + procedure relockall(count: integer) virtual; + procedure lockifnotmainthread; + procedure unlockifnotmainthread; + + function synchronize(const proc: proceventty; const quiet: boolean = false; + const aoptions: posteventoptionsty = []): boolean; + function synchronize(const proc: synchronizeeventty; const data: pointer; + const quiet: boolean = false; + const aoptions: posteventoptionsty = []): boolean; + function synchronize(const proc: synchronizeprocty; const data: pointer; + const quiet: boolean = false; + const aoptions: posteventoptionsty = []): boolean; + //true if not aborted, quiet -> show no exceptions + + procedure queueasynccall(const proc: proceventty; + const aoptions: posteventoptionsty = []); + procedure queueasynccall(const proc: synchronizeeventty; const data: pointer; + const aoptions: posteventoptionsty = []); + procedure queueasynccall(const proc: synchronizeprocty; const data: pointer; + const aoptions: posteventoptionsty = []); + + procedure releaseobject(const aobject: tobject); + function ismainthread: boolean; + function islockthread: boolean; + procedure waitforthread(athread: tmsethread); + //does unlock-relock for waiting + function semwait(var sem: semty; timeoutusec: integer): syserrorty; + //does unlock-relock for waiting + //timeoutusec <= 0 -> no timeout + //sye_ok -> semaphore signaled + //sye_timeout -> timeout + //sye_semaphore -> error + procedure wakeupmainthread; + procedure langchanged; virtual; + procedure beginwait(const aprocessmessages: boolean = false); virtual; + procedure endwait; virtual; + function waitescaped: boolean; virtual; + procedure idlesleep(const asleepus: integer); + //calls unlockall-relockall + function candefocus(const caller: tobject=nil): boolean; virtual; + property terminated: boolean read getterminated write setterminated; + //thread safe + property mainthread: threadty read fthread; + property lockthread: threadty read flockthread; + property lockcount: integer read flockcount; + property exceptioncount: integer read fexceptioncount; + property options: applicationoptionsty read foptions write foptions; + property onexception: exceptioneventty read fonexception write fonexception; + end; + applicationclassty = class of tcustomapplication; + +function application: tcustomapplication; +function applicationallocated: boolean; +function applicationdestroyed: boolean; + +procedure registerapplicationclass(const aclass: applicationclassty); + +procedure freedesigncomponent(const acomponent: tcomponent); +procedure designvalidaterename(const acomponent: tcomponent; + const curname, newname: string); +procedure handlesigchld; + + //helper functions for component extenders +procedure updateclientorder(var fclientnames: stringarty; + var fclients: pointerarty; + const getclientnames: getstringareventty); +function getclientname(const avalue: tobject; + const aindex: integer): string; +procedure designchanged(const acomponent: tcomponent); //for designer notify + +type + validaterenameeventty = procedure(const acomponent: tcomponent; + const curname, newname: string) of object; + propertynotifyeventty = procedure(const sender: tobject; + const propname: string; const itemindex: int32) of object; +var + onhandlesigchld: procedure; + //designer hooks + ondesignchanged: propertynotifyeventty; + onfreedesigncomponent: componenteventty; + ondesignvalidaterename: validaterenameeventty; + ondesignexception: notifyeventty; + +procedure releaseandnil(var acomponent: tactcomponent); + +implementation +uses + msebits,msesysintf1,msesysintf,msesysutils,msefileutils,msedatalist, + msearrayutils{$ifndef FPC},classes_del{$endif} + {$ifdef mse_debuggdisync},msegraphics{$endif}; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tobjectevent1 = class(tobjectevent); + + tasyncqueueevent = class(texecuteevent) + end; + + tappasyncevent = class(tasyncqueueevent) + private + fproc: proceventty; + protected + procedure execute(); override; + public + constructor create(const aproc: proceventty); + end; + + tappasyncdataevent = class(tasyncqueueevent) + private + fproc: synchronizeeventty; + fdata: pointer; + protected + procedure execute(); override; + public + constructor create(const aproc: synchronizeeventty; const adata: pointer); + end; + + tappasyncprocevent = class(tasyncqueueevent) + private + fproc: synchronizeprocty; + fdata: pointer; + protected + procedure execute(); override; + public + constructor create(const aproc: synchronizeprocty; const adata: pointer); + end; + + tappsynchronizeevent = class(tsynchronizeevent) + private + fproc: proceventty; + protected + procedure execute; override; + public + constructor create(const aproc: proceventty; const aquiet: boolean); + end; + + tappsynchronizedataevent = class(tsynchronizeevent) + private + fproc: synchronizeeventty; + fdata: pointer; + protected + procedure execute; override; + public + constructor create(const aproc: synchronizeeventty; const adata: pointer; + const aquiet: boolean); + end; + + tappsynchronizeprocevent = class(tsynchronizeevent) + private + fproc: synchronizeprocty; + fdata: pointer; + protected + procedure execute; override; + public + constructor create(const aproc: synchronizeprocty; const adata: pointer; + const aquiet: boolean); + end; + + treleaseevent = class(tobjectevent) + private + fobject: tobject; + public + constructor create(const dest: ievent; const aobject: tobject); + end; + +var + appinst: tcustomapplication; + appclass: applicationclassty; + fapplicationdestroyed: boolean; + +threadvar + exceptionactive: integer; + +procedure releaseandnil(var acomponent: tactcomponent); +begin + if acomponent <> nil then begin + acomponent.release; + acomponent:= nil; + end; +end; + + +procedure designchanged(const acomponent: tcomponent); //for designer notify +begin + if assigned(ondesignchanged) and + (acomponent.componentstate*[csdesigning,csloading,csdestroying] = + [csdesigning]) then begin + ondesignchanged(acomponent,'',-1); + end; +end; + +function getclientname(const avalue: tobject; + const aindex: integer): string; +begin + if avalue is tcomponent then begin + result:= ownernamepath(tcomponent(avalue)); + { + with tcomponent(avalue) do begin + if owner <> nil then begin + if not (csdesigning in componentstate) or + ((owner.owner <> nil) and (owner.owner.owner = nil)) then begin + result:= owner.name+'.'+name; + end + else begin + result:= name; + end; + end + else begin + result:= ''; + end; + end; + } + end + else begin + result:= inttostr(aindex)+'<'+avalue.classname+'>'; + end; +end; + +procedure updateclientorder(var fclientnames: stringarty; + var fclients: pointerarty; + const getclientnames: getstringareventty); +var + int1,int2: integer; + ar1: stringarty; + ar2,ar3: integerarty; +begin + ar1:= nil; //compilerwarning + if fclientnames <> nil then begin + ar1:= getclientnames(); + setlength(ar2,length(ar1)); + for int1:= 0 to high(fclientnames) do begin + for int2:= 0 to high(ar1) do begin + if ar1[int2] = fclientnames[int1] then begin + ar2[int2]:= int1-bigint; //not found items last + ar1[int2]:= ''; + end; + end; + end; + sortarray(ar2,ar3); + orderarray(ar3,fclients); + end; +end; + +procedure handlesigchld; +begin + if assigned(onhandlesigchld) then begin + onhandlesigchld; + end; +end; + +procedure freedesigncomponent(const acomponent: tcomponent); +begin + if assigned(onfreedesigncomponent) then begin + onfreedesigncomponent(acomponent); + end + else begin + acomponent.free; + end; +end; + +procedure designvalidaterename(const acomponent: tcomponent; + const curname, newname: string); +begin + if assigned(ondesignvalidaterename) then begin + ondesignvalidaterename(acomponent,curname,newname); + end; +end; + +function application: tcustomapplication; +begin + if appinst = nil then begin + if appclass = nil then begin + raise exception.create('No application class registered.'); + end; + appclass.create(nil); + end; + result:= appinst; +end; + +function applicationallocated: boolean; +begin + result:= appinst <> nil; +end; + +function applicationdestroyed: boolean; +begin + result:= fapplicationdestroyed; +end; + +procedure registerapplicationclass(const aclass: applicationclassty); +begin + if appclass <> nil then begin + raise exception.create('Application class already registered.'); + end; + appclass:= aclass; +end; + +{ tactcomponent } + +procedure tactcomponent.designchanged(const apropname: string = ''; + const apropindex: int32 = -1); //for designer notify +begin + if assigned(ondesignchanged) and (fdesignchangedlock = 0) and + (componentstate*[csdesigning,csloading] = [csdesigning]) then begin + ondesignchanged(self,apropname,apropindex); + end; +end; + +procedure tactcomponent.setactivator(const avalue: tactivator); +begin + tactivator.addclient(avalue,ievent(self),factivator); +end; + +procedure tactcomponent.loaded; +begin + inherited; + if (factivator <> nil) and factivator.activated then begin + doactivated; + end; +end; + +procedure tactcomponent.doactivated; +begin + //dummy; +end; + +procedure tactcomponent.dodeactivated; +begin + //dummy; +end; + +procedure tactcomponent.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (sender = factivator) then begin + case event of + oe_activate: begin + doactivated; + end; + oe_deactivate: begin + dodeactivated; + end; + end; + end; +end; + +procedure tactcomponent.release(const nomodaldefer: boolean = false); +begin + if not (acs_releasing in factstate) and + not (csdestroying in componentstate) then begin + appinst.postevent(tobjectevent.create(ek_release,ievent(self), + not nomodaldefer)); + { + if nomodaldefer then begin + appinst.postevent(tobjectevent.create(ek_release,ievent(self))); + end + else begin + appinst.postevent(tobjectevent.create(ek_releasedefer,ievent(self))); + end; + } + include(factstate,acs_releasing); + end; +end; + +function tactcomponent.releasing: boolean; +begin + result:= acs_releasing in factstate; +end; + +procedure tactcomponent.receiveevent(const event: tobjectevent); +begin + inherited; + case event.kind of + ek_release: begin + free; + end; + end; +end; + +procedure tactcomponent.setactive(const avalue: boolean); +begin + //dummy +end; + +procedure tactcomponent.deactivate(const achildren: boolean = true); + procedure deactivateall(const acomp: tcomponent); + var + intf1: iactivatorclient; + int1: integer; + begin + if mseclasses.getcorbainterface(acomp, + typeinfo(iactivatorclient),intf1) then begin + intf1.setactive(false); + end; + with acomp do begin + int1:= componentcount - 1; + while int1 >= 0 do begin + if int1 >= componentcount then begin + int1:= componentcount - 1; + end; + deactivateall(components[int1]); + dec(int1); + end; + end; + end; +begin + if achildren then begin + deactivateall(self); + end; + setactive(false); +end; + +{$ifdef mse_with_ifi} +procedure tactcomponent.executeificommand(var acommand: ificommandcodety); +begin + inherited; + case acommand of + icc_release: begin + release; + end; + end; +end; + +{$endif} + +{ tactivator } + +constructor tactivator.create(aowner: tcomponent); +begin + foptions:= defaultactivatoroptions; + inherited; + application.registeronterminated({$ifdef FPC}@{$endif}doterminated); +end; + +destructor tactivator.destroy; +begin + application.unregisteronterminated({$ifdef FPC}@{$endif}doterminated); + inherited; +end; + +class procedure tactivator.addclient(const aactivator: tactivator; + const aclient: iobjectlink; var dest: tactivator); +var + act1: tactivator; +begin + if dest <> nil then begin + dest.unregisterclient(aclient); + end; + if aactivator <> nil then begin + act1:= tactivator(aclient.getinstance); + if act1 is tactivator then begin + repeat + if act1 = aactivator then begin + raise exception.create('Circular reference.'); + end; + act1:= act1.activator; + until act1 = nil; + end; + aclient.link(aclient,ievent(aactivator),@dest); + aactivator.registerclient(aclient); + end; + dest:= aactivator; +end; + +procedure tactivator.registerclient(const aclient: iobjectlink); +begin + additem(fclients,pointer(aclient)); +end; + +procedure tactivator.unregisterclient(const aclient: iobjectlink); +begin + removeitem(fclients,pointer(aclient)); +end; + +procedure tactivator.updateorder; +begin + updateclientorder(fclientnames,fclients,{$ifdef FPC}@{$endif}getclientnames); +end; +{ +procedure tactivator.updateorder; +var + int1,int2: integer; + ar1: stringarty; + ar2,ar3: integerarty; +begin + ar1:= nil; //compilerwarning + if fclientnames <> nil then begin + ar1:= getclientnames; + setlength(ar2,length(ar1)); + for int1:= 0 to high(fclientnames) do begin + for int2:= 0 to high(ar1) do begin + if ar1[int2] = fclientnames[int1] then begin + ar2[int2]:= int1-bigint; //not found items last + ar1[int2]:= ''; + end; + end; + end; + sortarray(ar2,ar3); + orderarray(ar3,fclients); + end; +end; +} +procedure tactivator.doasyncevent(var atag: integer); +begin + activateclients; +end; + +procedure tactivator.loaded; +begin + inherited; + if not (csdesigning in componentstate) or factive then begin + if avo_activateonloaded in foptions then begin + if csdesigning in componentstate then begin + try + activateclients; + except + application.handleexception(self); + factivated:= false; //do not activate in clients.loaded + end; + end + else begin + activateclients; + end; + end; + if avo_activatedelayed in foptions then begin + asyncevent; + end; + end; +end; + +procedure tactivator.doterminated(const sender: tobject); +begin + if avo_deactivateonterminated in foptions then begin + deactivateclients; + end; +end; + +{ +function tactivator.getclientname(const avalue: tobject; + const aindex: integer): string; +begin + if avalue is tcomponent then begin + with tcomponent(avalue) do begin + if owner <> nil then begin + if not (csdesigning in componentstate) or + ((owner.owner <> nil) and (owner.owner.owner = nil)) then begin + result:= owner.name+'.'+name; + end + else begin + result:= name; + end; + end + else begin + result:= ''; + end; + end; + end + else begin + result:= inttostr(aindex)+'<'+avalue.classname+'>'; + end; +end; +} +function tactivator.getclientnames: stringarty; +var + int1: integer; +begin + setlength(result,length(fclients)); + for int1:= 0 to high(result) do begin + result[int1]:= getclientname(iobjectlink(fclients[int1]).getinstance,int1); + end; +end; + +procedure tactivator.readclientnames(reader: treader); +begin + readstringar(reader,fclientnames); +end; + +procedure tactivator.writeclientnames(writer: twriter); +begin + writestringar(writer,getclientnames); +end; + +procedure tactivator.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('clientnames',{$ifdef FPC}@{$endif}readclientnames, + {$ifdef FPC}@{$endif}writeclientnames,high(fclients) >= 0); +end; + +procedure tactivator.objevent(const sender: iobjectlink; + const event: objecteventty); +begin + inherited; + if (event = oe_activate) and (sender.getinstance = activator) then begin + activateclients; + end; +end; + +procedure tactivator.unlink(const source,dest: iobjectlink; + valuepo: pointer = nil); +begin + removeitem(fclients,pointer(dest)); + inherited; +end; + +function tactivator.getclients: integer; +begin + result:= length(fclients); +end; + +procedure tactivator.setclients(const avalue: integer); +begin + // dummy; +end; + +procedure tactivator.activateclients; +var + int1: integer; + bo1,bo2: boolean; + act1: activatorabortactionty; +begin + try + if avo_waitcursor in foptions then begin + application.beginwait; + end; + factive:= true; + factivated:= true; + if canevent(tmethod(fonbeforeactivate)) then begin + fonbeforeactivate(self); + end; + if factive then begin + updateorder; + bo2:= canevent(tmethod(fonactivateerror)); + for int1:= 0 to high(fclients) do begin + try + iobjectlink(fclients[int1]).objevent(ievent(self),oe_activate); + except + on e: exception do begin + bo1:= false; + if bo2 then begin + fonactivateerror(self,iobjectlink(fclients[int1]).getinstance,e,bo1); + end; + if not bo1 then begin + if (avo_handleexceptions in foptions) and + not (csdesigning in componentstate) then begin + if not (avo_quietexceptions in foptions) then begin + application.showexception(e); + end; + end + else begin + // factive:= false; + raise; + end; + end; + if avo_abortonexception in foptions then begin + act1:= fabortaction; + if canevent(tmethod(fonabort)) then begin + fonabort(self,act1); + end; + factivated:= false; //no activation in clients.loaded + case act1 of + aaa_retry,aaa_deactivate: begin + deactivateclients; + if act1 = aaa_retry then begin + activateclients; + end; + exit; + end; + aaa_abortexception: begin + abort; + end; + end; + break; + end; + end; + end; + end; + if canevent(tmethod(fonafteractivate)) then begin + fonafteractivate(self); + end; + end; + finally + if avo_waitcursor in foptions then begin + application.endwait; + end; + end; +end; + +procedure tactivator.deactivateclients; +var + int1: integer; +begin + factive:= false; + factivecount:= 0; + if canevent(tmethod(fonbeforedeactivate)) then begin + fonbeforedeactivate(self); + end; + if not active then begin + updateorder; + if avo_deactivatebottomup in foptions then begin + for int1:= 0 to high(fclients) do begin + iobjectlink(fclients[int1]).objevent(ievent(self),oe_deactivate); + end; + end + else begin + for int1:= high(fclients) downto 0 do begin + iobjectlink(fclients[int1]).objevent(ievent(self),oe_deactivate); + end; + end; + if canevent(tmethod(fonafterdeactivate)) then begin + fonafterdeactivate(self); + end; + end; +end; + +procedure tactivator.setactive(const avalue: boolean); +begin + if avalue <> factive then begin + if componentstate * [csloading,csdesigning] = [csloading,csdesigning] then begin + factive:= avalue; + end + else begin + if not (csloading in componentstate) then begin + if avalue then begin + activateclients; + end + else begin + deactivateclients; + end; + end; + end; + end; +end; + +procedure tactivator.setoptions(const avalue: activatoroptionsty); +const + mask: activatoroptionsty = [avo_activateonloaded,avo_activatedelayed]; +begin + foptions:= activatoroptionsty(setsinglebit( + {$ifdef FPC}longword{$else}byte{$endif}(avalue), + {$ifdef FPC}longword{$else}byte{$endif}(foptions), + {$ifdef FPC}longword{$else}byte{$endif}(mask))); +end; + +procedure tactivator.activaterecursive; +begin + inc(factivecount); + active:= true; +end; + +procedure tactivator.deactivaterecursive; +begin + dec(factivecount); + if factivecount < 0 then begin + factivecount:= 0; + end; + if factivecount = 0 then begin + active:= false; + end; +end; + +function tactivator.getclientinstances(const index: integer): tobject; +var + intf1: iobjectlink; +begin + intf1:= getclientinterfaces(index); + result:= nil; + if intf1 <> nil then begin + result:= intf1.getinstance; + end; +end; + +function tactivator.getclientinterfaces(const index: integer): iobjectlink; +begin + checkarrayindex(fclients,index); + result:= iobjectlink(fclients[index]); +end; + +{ tonterminatequerylist } + +function tonterminatequerylist.doterminatequery: boolean; +begin + factitem:= 0; + result:= true; + while (factitem < fcount) and result do begin + terminatequeryeventty(getitempo(factitem)^)(result); + inc(factitem); + end; +end; + +{ tonidlelist} + +function tonidlelist.doidle: boolean; +var + bo1: boolean; +begin + result:= false; + factitem:= 0; + while factitem < fcount do begin + bo1:= false; + idleeventty(getitempo(factitem)^)(bo1); + result:= result or bo1; + inc(factitem); + end; +end; + +{ teventlist } + +procedure teventlist.finalizeitem(var item: pointer); +begin + if ownsobjects then begin + tmseevent(item).Free1; + item:= nil; + end; +end; + +{ tonapplicationeventlist } + +procedure tonapplicationeventlist.doevent(var aevent: tmseevent; + var handled: boolean); +begin + factitem:= 0; + while (factitem < fcount) and not handled do begin + applicationeventhandlereventty(getitempo(factitem)^)(aevent,handled); + inc(factitem); + end; +end; + +{ tcustomapplication } + +{$ifdef mse_debugmutex} +function tcustomapplication.getmutexaddr: pointer; +begin + result:= @fmutex; +end; +function tcustomapplication.getmutexcount: integer; +begin + result:= flockcount; +end; +procedure tcustomapplication.checklockcount; +var + str1: string; +begin + if appmutexcount <> flockcount then begin + str1:= 'appmutexerror, lockcount: '+inttostr(flockcount)+ + ' mutexcount: '+inttostr(appmutexcount); + debugwriteln(str1); + debugwritestack; + raise exception.create(str1); + end; +end; +{$endif} + +constructor tcustomapplication.create(aowner: tcomponent); +begin + if appinst <> nil then begin + raise exception.create('Application already created.'); + end; + appinst:= self; + fapplicationname:= filename(sys_getapplicationpath); + fthread:= sys_getcurrentthread; + feventlist:= teventlist.create(true); + fonterminatedlist:= tnotifylist.create; + fonterminatequerylist:= tonterminatequerylist.create; + fonidlelist:= tonidlelist.create; + sys_mutexcreate(fmutex); + sys_mutexcreate(feventlock); + classes.wakemainthread:= {$ifdef FPC}@{$endif}dowakeup; + fonapplicationeventlist:= tonapplicationeventlist.create; + lock; + initialize; +end; + +destructor tcustomapplication.destroy; +begin + inherited; + deinitialize; + fonidlelist.free; + fonterminatedlist.free; + fonterminatequerylist.free; + feventlist.free; + sys_mutexdestroy(fmutex); + sys_mutexdestroy(feventlock); + fonapplicationeventlist.free; +end; + +procedure tcustomapplication.registeronterminated(const method: notifyeventty); +begin + fonterminatedlist.add(tmethod(method)); +end; + +procedure tcustomapplication.unregisteronterminated(const method: notifyeventty); +begin + fonterminatedlist.remove(tmethod(method)); +end; + +procedure tcustomapplication.registeronterminate(const method: terminatequeryeventty); +begin + fonterminatequerylist.add(tmethod(method)); +end; + +procedure tcustomapplication.unregisteronterminate(const method: terminatequeryeventty); +begin + fonterminatequerylist.remove(tmethod(method)); +end; + +procedure tcustomapplication.registeronidle(const method: idleeventty); +begin + fonidlelist.add(tmethod(method)); +end; + +procedure tcustomapplication.unregisteronidle(const method: idleeventty); +begin + fonidlelist.remove(tmethod(method)); +end; + +procedure tcustomapplication.registerapplicationeventhandler( + const method: applicationeventhandlereventty); +begin + fonapplicationeventlist.add(tmethod(method)); +end; + +procedure tcustomapplication.unregisterapplicationeventhandler( + const method: applicationeventhandlereventty); +begin + fonapplicationeventlist.remove(tmethod(method)); +end; + +function tcustomapplication.dolock: boolean; +var + athread: threadty; +begin + inc(flockcount); + athread:= sys_getcurrentthread; + if not sys_issamethread(flockthread,athread) then begin + result:= true; + flockthread:= athread; + end + else begin + result:= false; + end; + {$ifdef mse_debuglock} + debugout(self,'lock, count: '+inttostr(flockcount) + ' thread: '+ + inttostr(flockthread)); + {$endif} + {$ifdef mse_debugmutex} + checklockcount; + {$endif} +end; + +function tcustomapplication.lock: boolean; +begin + syserror(sys_mutexlock(fmutex)); + result:= dolock; +end; + +function tcustomapplication.islockedthread: boolean; + //true if calling thread holds the lock +begin + result:= (flockcount > 0) and (flockthread = sys_getcurrentthread()); +end; + +function tcustomapplication.islockedmainthread: boolean; +var + id: threadty; +begin + id:= sys_getcurrentthread(); + result:= (flockcount > 0) and (id = flockthread) and (id = fthread); +end; + +function tcustomapplication.trylock: boolean; +begin + result:= sys_mutextrylock(fmutex) = sye_ok; + {$ifdef mse_debuglock} + debugout(self,'trylock, result: '+booltostr(result)+' count: '+ + inttostr(flockcount) + ' thread: '+ + inttostr(flockthread)); + {$endif} + if result then begin + dolock; + end; +end; + +function tcustomapplication.internalunlock(count: integer): boolean; +begin + result:= sys_issamethread(flockthread,sys_getcurrentthread); + if result then begin + if count > flockcount then begin + raise exception.create('tcustomapplication.internalunlock lock count error.'); + end; + flusheventbuffer; + while count > 0 do begin + {$ifdef mse_debugmutex} + checklockcount; + {$endif} + dec(count); + dec(flockcount); + if flockcount = 0 then begin + flockthread:= 0; + end; + sys_mutexunlock(fmutex); + end; + {$ifdef mse_debuglock} + debugout(self,'unlock, result: '+booltostr(result)+ + ' count: '+inttostr(flockcount) + ' thread: '+ + inttostr(flockthread)); + {$endif} + end; +end; + +function tcustomapplication.unlock: boolean; +begin + result:= internalunlock(1); +end; + +function tcustomapplication.unlockall: integer; +begin + if ismainthread then begin + inc(fcheckoverloadlock); + end; + result:= flockcount; + if not internalunlock(flockcount) then begin + result:= 0; + end; +end; + +procedure tcustomapplication.relockall(count: integer); +begin + if count > 0 then begin + lock; + dec(count); + inc(flockcount,count); + while count > 0 do begin + sys_mutexlock(fmutex); + dec(count); + end; + if ismainthread then begin + dec(fcheckoverloadlock); + end; + end; +end; + +procedure tcustomapplication.lockifnotmainthread; +begin + if not ismainthread then begin + lock; + end; +end; + +procedure tcustomapplication.unlockifnotmainthread; +begin + if not ismainthread then begin + unlock; + end; +end; + +function tcustomapplication.synchronize(const proc: proceventty; + const quiet: boolean = false; + const aoptions: posteventoptionsty = []): boolean; +var + event: tappsynchronizeevent; +begin + event:= tappsynchronizeevent.create(proc,quiet); + try + result:= synchronizeevent(event,aoptions); + finally + event.free; + end; +end; + +function tcustomapplication.synchronize(const proc: synchronizeeventty; + const data: pointer; const quiet: boolean = false; + const aoptions: posteventoptionsty = []): boolean; +var + event: tappsynchronizedataevent; +begin + event:= tappsynchronizedataevent.create(proc,data,quiet); + try + result:= synchronizeevent(event,aoptions); + finally + event.free; + end; +end; + +function tcustomapplication.synchronize(const proc: synchronizeprocty; + const data: pointer; const quiet: boolean = false; + const aoptions: posteventoptionsty = []): boolean; +var + event: tappsynchronizeprocevent; +begin + event:= tappsynchronizeprocevent.create(proc,data,quiet); + try + result:= synchronizeevent(event,aoptions); + finally + event.free; + end; +end; + +procedure tcustomapplication.queueasynccall(const proc: proceventty; + const aoptions: posteventoptionsty = []); +begin + postevent(tappasyncevent.create(proc),aoptions) +end; + +procedure tcustomapplication.queueasynccall(const proc: synchronizeeventty; + const data: pointer; const aoptions: posteventoptionsty = []); +begin + postevent(tappasyncdataevent.create(proc,data),aoptions); +end; + +procedure tcustomapplication.queueasynccall(const proc: synchronizeprocty; + const data: pointer; const aoptions: posteventoptionsty = []); +begin + postevent(tappasyncprocevent.create(proc,data),aoptions); +end; + +function tcustomapplication.ismainthread: boolean; +begin + result:= sys_getcurrentthread = fthread; +end; + +function tcustomapplication.islockthread: boolean; +begin + result:= sys_getcurrentthread = flockthread; +end; + +procedure tcustomapplication.waitforthread(athread: tmsethread); + //does unlock-relock before waiting +var + int1: integer; +begin + int1:= unlockall; + try + athread.waitfor; + finally + relockall(int1); + end; +end; + +function tcustomapplication.semwait(var sem: semty; + timeoutusec: integer): syserrorty; + //does unlock-relock before waiting +var + int1: integer; +begin + int1:= unlockall; + try + result:= sys_semwait(sem,timeoutusec); + finally + relockall(int1); + end; +end; + +procedure tcustomapplication.incidlecount; +begin + inc(fidlecount); +end; + +procedure tcustomapplication.flusheventbuffer; +var + int1: integer; + event1: tmseevent; +begin + sys_mutexlock(feventlock); + if not (aps_eventflushing in fstate) then begin + include(fstate,aps_eventflushing); + for int1:= 0 to high(fpostedeventslocal) do begin + event1:= fpostedeventslocal[int1]; + if (event1 is tobjectevent) {and ismainthread} then begin + with tobjectevent1(event1) do begin + if oes_modaldeferred in fstate then begin + fmodallevel:= self.modallevel; + end; + end; + end; + feventlist.add(event1); + end; + fpostedeventslocal:= nil; + for int1:= 0 to high(fpostedevents) do begin + event1:= fpostedevents[int1]; + if (event1 is tobjectevent) {and ismainthread} then begin + with tobjectevent1(event1) do begin + if oes_modaldeferred in fstate then begin + fmodallevel:= self.modallevel; + end; + end; + end; + dopostevent(event1); + end; + fpostedevents:= nil; + exclude(fstate,aps_eventflushing); + end; + sys_mutexunlock(feventlock); +end; + +procedure tcustomapplication.postevent(event: tmseevent; + const aoptions: posteventoptionsty); +var + bo1: boolean; +begin + if csdestroying in componentstate then begin + event.free1; + end + else begin + bo1:= event is tobjectevent; + if (peo_modaldefer in aoptions) and bo1 then begin + include(tobjectevent1(event).fstate,oes_modaldeferred); + end; + if trylock then begin + try + if bo1 then begin + with tobjectevent1(event) do begin + if (oes_modaldeferred in fstate) then begin + fmodallevel:= self.modallevel; + end; + end; + end; + flusheventbuffer; + if aoptions * [peo_local,peo_first] <> [] then begin + if peo_first in aoptions then begin + eventlist.insert(0,event); + end + else begin + eventlist.add(event); + end; + wakeupmainthread; + end + else begin + dopostevent(event); + end; + except + event.free1; + unlock; + raise; + end; + unlock; + end + else begin + sys_mutexlock(feventlock); + if (peo_local in aoptions) then begin + setlength(fpostedeventslocal,high(fpostedeventslocal) + 2); + fpostedeventslocal[high(fpostedeventslocal)]:= event; + end + else begin + setlength(fpostedevents,high(fpostedevents) + 2); + fpostedevents[high(fpostedevents)]:= event; + end; + sys_mutexunlock(feventlock); + end; + end; +end; + +function tcustomapplication.checkoverload(const asleepus: integer = 100000): boolean; + //true if never idle since last call, + // unlocks application and calls sleep if not mainthread and asleepus >= 0 +//todo: fix for concurent calls, use wait queue instead of sleep +var + int1: integer; +begin + result:= (fidlecount = 0) and not (aps_waiting in fstate) and + (fcheckoverloadlock = 0); + fidlecount:= 0; + if result and (asleepus >= 0) and not ismainthread then begin + int1:= unlockall; + repeat + sleepus(asleepus); + until (fidlecount > 0) or (aps_waiting in fstate) or (fcheckoverloadlock <> 0); + relockall(int1); + end; +end; + +function tcustomapplication.getterminated: boolean; +begin + result:= aps_terminated in fstate; +end; + +procedure tcustomapplication.setterminated(const Value: boolean); +begin + if value then begin + lock; + include(fstate,aps_terminated); + if not ismainthread then begin + wakeupmainthread; + end; + unlock; + end + else begin + exclude(fstate,aps_terminated); + end; +end; + +procedure tcustomapplication.wakeupmainthread; +begin + if fstate * [aps_running,aps_waiting,aps_woken] = + [aps_running,aps_waiting] then begin + include(fstate,aps_woken); + postevent(tmseevent.create(ek_wakeup)); + end; +end; + +procedure tcustomapplication.langchanged; +begin + //dummy +end; + +procedure tcustomapplication.beginwait(const aprocessmessages: boolean = false); +begin + if aprocessmessages then begin + processmessages; + end; +end; + +procedure tcustomapplication.endwait; +begin + //dummy +end; + +procedure tcustomapplication.idlesleep(const asleepus: integer); +var + int1: integer; +begin + int1:= unlockall; + sleepus(asleepus); + relockall(int1); +end; + +{ +function tcustomapplication.waitdialog(const athread: tthreadcomp = nil; + const atext: msestring = ''; const caption: msestring = ''; + const acancelaction: notifyeventty = nil; + const aexecuteaction: notifyeventty = nil; + const aidleaction: waitidleeventty = nil): boolean; +begin + result:= false; //dummy +end; +} +procedure tcustomapplication.handleexception(sender: tobject = nil; + const leadingtext: msestring = ''); +var + handled: boolean; + exceptobj: tobject; +begin + exceptobj:= exceptobject; + if exceptobj is exception then begin + if not (exceptobj is eabort) then begin + if exceptionactive = 0 then begin + //do not handle subsequent exceptions + inc(exceptionactive); + try + interlockedincrement(fexceptioncount); + handled:= false; + if assigned(fonexception) then begin + fonexception(sender,exception(exceptobj),leadingtext,handled); + end; + if not handled then begin + showexception(exception(exceptobj),leadingtext); + end; + finally + dec(exceptionactive); + if apo_terminateonexception in foptions then begin + terminated:= true; + end; + end; + end + else begin + interlockedincrement(fexceptioncount); +// sysutils.showexception(exceptobject, exceptaddr); + end; + end; + end; +end; + +procedure tcustomapplication.run; +var + threadbefore: threadty; +begin + dobeforerun; + threadbefore:= fthread; + fthread:= sys_getcurrentthread; + include(fstate,aps_running); + try + doeventloop(false); + fonterminatedlist.notify(application); + finally + fthread:= threadbefore; + exclude(fstate,aps_running); + end; + doafterrun; +end; + +function tcustomapplication.running: boolean; +begin + result:= aps_running in fstate; +end; + +procedure tcustomapplication.processmessages; +var + bo1: boolean; +begin + if not ismainthread then begin + raise exception.create('processmessages must be called from main thread.'); + end; + bo1:= aps_processmessages in fstate; + include(fstate,aps_processmessages); +// int1:= unlockall; + lock(); + try + doeventloop(true); + finally +// relockall(int1); + if not bo1 then begin + exclude(fstate,aps_processmessages); + end; + unlock(); + end; +end; + +procedure tcustomapplication.dobeforerun; +begin + //dummy +end; + +procedure tcustomapplication.doafterrun; +begin + //dummy +end; + +procedure tcustomapplication.doidle; +var + int1: integer; +begin + while true do begin + if not fonidlelist.doidle then begin + break; + end; + int1:= getevents; + if int1 <> 0 then begin + break; + end; + end; + if ismainthread then begin + checksynchronize; + end; +end; + +function tcustomapplication.createdatamodule(instanceclass: msecomponentclassty; + var reference): tmsecomponent; +begin + result:= mseclasses.createmodule(self,instanceclass,reference); +end; +{ +procedure tcustomapplication.setlinkedvar(const source: tmsecomponent; + var dest: tmsecomponent; const linkintf: iobjectlink = nil); +begin + inherited; +end; + +procedure tcustomapplication.setlinkedvar(const source: tlinkedobject; + var dest: tlinkedobject; const linkintf: iobjectlink = nil); +begin + inherited; +end; + +procedure tcustomapplication.setlinkedvar(const source: tlinkedpersistent; + var dest: tlinkedpersistent; const linkintf: iobjectlink = nil); +begin + inherited; +end; +} +procedure tcustomapplication.dowakeup(sender: tobject); +begin + wakeupmainthread; +end; + +function tcustomapplication.idle: boolean; +begin + result:= (high(fpostedevents) < 0) and (high(fpostedeventslocal) < 0) and + (feventlist.count = 0); +end; + +function tcustomapplication.candefocus(const caller: tobject = nil): boolean; +begin + result:= true; //dummy +end; + +function tcustomapplication.procid: procidty; +begin + result:= sys_getpid; +end; + +function tcustomapplication.getserial(): card32; +begin + repeat + result:= interlockedincrement(fserial); + until result <> 0; +end; + +procedure tcustomapplication.internalinitialize; +begin + //dummy +end; + +procedure tcustomapplication.internaldeinitialize; +begin + //dummy +end; + +procedure tcustomapplication.initialize; +begin + if not (aps_inited in fstate) and (finiting = 0) then begin + inc(finiting); + fstate:= []; + try + internalinitialize; + finally + dec(finiting); + end; + include(fstate,aps_inited); + end; +end; + +procedure tcustomapplication.deinitialize; +begin + if aps_inited in fstate then begin + include(fstate,aps_deinitializing); + try + internaldeinitialize; + finally + exclude(fstate,aps_deinitializing); + end; + exclude(fstate,aps_inited); + end; +end; + +procedure tcustomapplication.objecteventdestroyed(const sender: tobjectevent); +begin + //dummy +end; + +procedure tcustomapplication.beginhighrestimer; +begin + if fhighrestimercount = 0 then begin + sethighrestimer(true); + end; + inc(fhighrestimercount); +end; + +procedure tcustomapplication.endhighrestimer; +begin + dec(fhighrestimercount); + if fhighrestimercount = 0 then begin + sethighrestimer(false); + end; +end; + +function tcustomapplication.gethighrestimer: boolean; +begin + result:= fhighrestimercount > 0; +end; + +function tcustomapplication.waitescaped: boolean; +begin + result:= false; +end; + +procedure tcustomapplication.settimer(const us: integer); +begin + if interlockedincrement(ftimertriggercount) = 1 then begin + postevent(tmseevent.create(ek_timer)); + end; +end; + +procedure tcustomapplication.resettimertrigger; +begin + interlockedexchange(ftimertriggercount,0); +end; + +procedure tcustomapplication.beforedestruction(); +begin + fapplicationdestroyed:= true; + inherited; +end; + +procedure tcustomapplication.releaseobject(const aobject: tobject); +begin + postevent(treleaseevent.create(ievent(self),aobject)); +end; + +procedure tcustomapplication.receiveevent(const event: tobjectevent); +begin + inherited; + if (event.kind = ek_releaseobject) and + (event is treleaseevent) then begin + treleaseevent(event).fobject.free; + end; +end; + +{ tactivatorcontroller } + +constructor tactivatorcontroller.create(const aowner: tcomponent; + const aintf: iactivatorclient); +begin + fintf:= aintf; + fowner:= aowner; + inherited create; +end; + +function tactivatorcontroller.setactive(const value: boolean): boolean; +begin + factive:= value; + result:= floaded or not (csloading in fowner.componentstate); +end; + +procedure tactivatorcontroller.loaded; +begin + floaded:= true; + try + if (factivator = nil) or factivator.activated then begin + if factivator <> nil then begin + factive:= true; //activated + end; + if csdesigning in fowner.componentstate then begin + try + setowneractive(factive); + except + if assigned(ondesignexception) then begin + ondesignexception(fowner); + end + else begin + application.handleexception(fowner); + end; + end; + end + else begin + setowneractive(factive); + end; + end; + finally + floaded:= false; + end; +end; + +procedure tactivatorcontroller.setactivator(const avalue: tactivator); +begin + tactivator.addclient(avalue,iobjectlink(self),factivator); +end; + +procedure tactivatorcontroller.objectevent(const sender: tobject; + const event: objecteventty); +begin + if (sender = factivator) then begin + case event of + oe_activate: begin + floaded:= true; + factive:= true; + try + setowneractive(factive); + finally + floaded:= false; + end; + end; + oe_deactivate: begin + factive:= false; + setowneractive(factive); + end; + end; + end; +end; + +function tactivatorcontroller.getinstance: tobject; +begin + result:= fowner; +end; + +{ tappasyncevent } + +constructor tappasyncevent.create(const aproc: proceventty); +begin + fproc:= aproc; + inherited create(); +end; + +procedure tappasyncevent.execute(); +begin + fproc(); +end; + +{ tappasyncdataevent } + +constructor tappasyncdataevent.create(const aproc: synchronizeeventty; + const adata: pointer); +begin + fproc:= aproc; + fdata:= adata; + inherited create(); +end; + +procedure tappasyncdataevent.execute(); +begin + fproc(fdata); +end; + +{ tappasyncprocevent } + +constructor tappasyncprocevent.create(const aproc: synchronizeprocty; + const adata: pointer); +begin + fproc:= aproc; + fdata:= adata; + inherited create(); +end; + +procedure tappasyncprocevent.execute(); +begin + fproc(fdata); +end; + +{ tappsynchronizeevent } + +constructor tappsynchronizeevent.create(const aproc: proceventty; + const aquiet: boolean); +begin + fproc:= aproc; + inherited create(aquiet); +end; + +procedure tappsynchronizeevent.execute; +begin + fproc; +end; + +{ tappsynchronizedataeevent } + +constructor tappsynchronizedataevent.create(const aproc: synchronizeeventty; + const adata: pointer; const aquiet: boolean); +begin + fproc:= aproc; + fdata:= adata; + inherited create(aquiet); +end; + +procedure tappsynchronizedataevent.execute; +begin + fproc(fdata); +end; + +{ tappsynchronizeprocevent } + +constructor tappsynchronizeprocevent.create(const aproc: synchronizeprocty; + const adata: pointer; const aquiet: boolean); +begin + fproc:= aproc; + fdata:= adata; + inherited create(aquiet); +end; + +procedure tappsynchronizeprocevent.execute; +begin + fproc(fdata); +end; + +{ treleaseevent } + +constructor treleaseevent.create(const dest: ievent; const aobject: tobject); +begin + fobject:= aobject; + inherited create(ek_releaseobject,dest); +end; + +initialization +finalization + appinst.Free; + appinst:= nil; +end. diff --git a/mseide-msegui/lib/common/kernel/msearrayprops.pas b/mseide-msegui/lib/common/kernel/msearrayprops.pas new file mode 100644 index 0000000..8cfc06a --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msearrayprops.pas @@ -0,0 +1,2266 @@ +{ MSEgui Copyright (c) 1999-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msearrayprops; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + sysutils,classes,mclasses,typinfo,mselist, + msegraphutils,msetypes,msestrings,mseclasses,mseglob,msestat; + +type + earraystreamerror = class(estreamerror); + earrayproperror = class(exception); + + tarrayprop = class; + arrayproparrayty = array of tarrayprop; + + arraychangeeventty = procedure(const sender: tarrayprop; + const index: integer) of object; + arraysizechangeeventty = procedure(sender: tarrayprop) of object; + + arraypropstatety = (aps_linking,aps_destroying,aps_needsindexing,aps_moved); + arraypropsstatesty = set of arraypropstatety; + + arraypropkindty = (apk_none,apk_tpersistent,apk_integer,apk_colorty,apk_real, + apk_string,apk_msestring,apk_boolean,apk_pointer,apk_int64); + + tarrayprop = class(tpersistent) + private + itemsread: boolean; + linkedarrays: arrayproparrayty; + fonchange: arraychangeeventty; + ffixcount: integer; + procedure internalinsert(const index: integer; const init: boolean); + protected + fstate: arraypropsstatesty; + fupdating: integer; + fcountbefore: integer; + procedure setfixcount(const avalue: integer); virtual; + procedure change(const index: integer); virtual; + function getcount: integer; virtual; abstract; + function getdatapo: pointer; virtual; abstract; + procedure checkcount(var acount: integer); virtual; + procedure setcount1(acount: integer; doinit: boolean); virtual; + procedure setcount(const acount: integer); + procedure dosizechanged; virtual; + function getsize: integer; virtual; abstract; + function getitemspo(const index: integer): pointer; virtual; abstract; + procedure writeitem(const index: integer; writer: twriter); virtual; abstract; + procedure readitem(const index: integer; reader: treader); virtual; abstract; + procedure defineproperties(filer: tfiler); override; + procedure readcount(reader: treader); + procedure writecount(writer: twriter); + procedure readitems(reader: treader); + procedure writeitems(writer: twriter); + procedure init(startindex,endindex: integer); virtual; + procedure dochange(const aindex: integer); virtual; + procedure checkindex(const index: integer); + function checkstored(ancestor: tpersistent): boolean; virtual; + public + function propkind: arraypropkindty; virtual; + procedure beginupdate; + procedure endupdate(nochange: boolean = false); + procedure clear; + procedure insertempty(const index: integer); + procedure insertdefault(const index: integer); + procedure delete(const index: integer); + procedure move(const curindex,newindex: integer); virtual; + procedure order(const sourceorder: integerarty); //sourceorder can be nil + procedure reorder(const destorder: integerarty); //destorder can be nil + procedure link(alinkedarrays: array of tarrayprop{; + onsizechanged: arraysizechangeeventty = nil}); + property fixcount: integer read ffixcount write setfixcount default 0; + property onchange: arraychangeeventty read fonchange write fonchange; + published + property count: integer read getcount write setcount default 0; + end; + + tintegerarrayprop = class(tarrayprop) + private + protected + fitems: integerarty; + function getitems(const index: integer): integer; + procedure setitems(const index: integer; const Value: integer); + function getcount: integer; override; + procedure setcount1(acount: integer; doinit: boolean); override; + procedure writeitem(const index: integer; writer: twriter); override; + procedure readitem(const index: integer; reader: treader); override; + function getsize: integer; override; + function getdatapo: pointer; override; + function getitemspo(const index: integer): pointer; override; + function checkstored(ancestor: tpersistent): boolean; override; + public + function propkind: arraypropkindty; override; + procedure assign(source: tpersistent); override; + property items[const index: integer]: integer read getitems write setitems; default; + end; + + tcolorarrayprop = class(tintegerarrayprop) + private + function getitems(const index: integer): colorty; + procedure setitems(const index: integer; const Value: colorty); + protected + fvaluedefault: colorty; + procedure init(startindex,endindex: integer); override; + public + constructor create; + function propkind: arraypropkindty; override; + property items[const index: integer]: colorty read getitems + write setitems; default; + end; + + tint64arrayprop = class(tarrayprop) + private + protected + fitems: int64arty; + function getitems(const index: integer): int64; + procedure setitems(const index: integer; const Value: int64); + function getcount: integer; override; + procedure setcount1(acount: integer; doinit: boolean); override; + procedure writeitem(const index: integer; writer: twriter); override; + procedure readitem(const index: integer; reader: treader); override; + function getsize: integer; override; + function getdatapo: pointer; override; + function getitemspo(const index: integer): pointer; override; + function checkstored(ancestor: tpersistent): boolean; override; + public + function propkind: arraypropkindty; override; + procedure assign(source: tpersistent); override; + property items[const index: integer]: int64 read getitems write setitems; default; + end; + + trealarrayprop = class(tarrayprop) + private + function getitems(const index: integer): real; + procedure setitems(const index: integer; const Value: real); + protected + fitems: realarty; + function getcount: integer; override; + procedure setcount1(acount: integer; doinit: boolean); override; + procedure writeitem(const index: integer; writer: twriter); override; + procedure readitem(const index: integer; reader: treader); override; + function getsize: integer; override; + function getdatapo: pointer; override; + function getitemspo(const index: integer): pointer; override; + function checkstored(ancestor: tpersistent): boolean; override; + public + function propkind: arraypropkindty; override; + procedure assign(source: tpersistent); override; + property items[const index: integer]: real read getitems write setitems; default; + end; + + tstringarrayprop = class(tarrayprop) + private + function getitems(const index: integer): string; + procedure setitems(const index: integer; const Value: string); + protected + fitems: stringarty; + function getcount: integer; override; + procedure setcount1(acount: integer; doinit: boolean); override; + procedure writeitem(const index: integer; writer: twriter); override; + procedure readitem(const index: integer; reader: treader); override; + function getsize: integer; override; + function getdatapo: pointer; override; + function getitemspo(const index: integer): pointer; override; + function checkstored(ancestor: tpersistent): boolean; override; + public + function propkind: arraypropkindty; override; + procedure assign(source: tpersistent); override; + function itemar: stringarty; + property items[const index: integer]: string read getitems write setitems; default; + end; + + tmsestringarrayprop = class(tarrayprop) + private + function getitems(const index: integer): msestring; + procedure setitems(const index: integer; const Value: msestring); + protected + fitems: msestringarty; + function getcount: integer; override; + procedure setcount1(acount: integer; doinit: boolean); override; + procedure writeitem(const index: integer; writer: twriter); override; + procedure readitem(const index: integer; reader: treader); override; + function getsize: integer; override; + function getdatapo: pointer; override; + function getitemspo(const index: integer): pointer; override; + function checkstored(ancestor: tpersistent): boolean; override; + public + function propkind: arraypropkindty; override; + procedure assign(source: tpersistent); override; + property items[const index: integer]: msestring read getitems write setitems; default; + end; + + tbooleanarrayprop = class(tintegerarrayprop) + private + function getitems(const index: integer): boolean; + procedure setitems(const index: integer; const Value: boolean); + public + function propkind: arraypropkindty; override; + property items[const index: integer]: boolean read getitems write setitems; default; + end; + + tenumarrayprop = class(tintegerarrayprop) + protected + ftypeinfo: ptypeinfo; + public + constructor create(typeinfo: ptypeinfo); reintroduce; + end; + + tsetarrayprop = class(tintegerarrayprop) + private + function getitems(const index: integer): tintegerset; + protected + ftypeinfo: ptypeinfo; + procedure setitems(const index: integer; const Value: tintegerset); virtual; + procedure writeitem(const index: integer; writer: twriter); override; + procedure readitem(const index: integer; reader: treader); override; + public + constructor create(typeinfo: ptypeinfo); reintroduce; + property typeinfo: ptypeinfo read ftypeinfo; + property items[const index: integer]: tintegerset read getitems write setitems; default; + end; + + tpointerarrayprop = class(tarrayprop) + private + protected + fitems: pointerarty; + function getitems(const index: integer): pointer; + procedure setitems(const index: integer; const Value: pointer); + function getcount: integer; override; + procedure setcount1(acount: integer; doinit: boolean); override; + procedure writeitem(const index: integer; writer: twriter); override; + procedure readitem(const index: integer; reader: treader); override; + function getsize: integer; override; + function getdatapo: pointer; override; + function getitemspo(const index: integer): pointer; override; + function checkstored(ancestor: tpersistent): boolean; override; + public + function propkind: arraypropkindty; override; + procedure assign(source: tpersistent); override; + property items[const index: integer]: pointer read getitems write setitems; default; + end; + + tdynarrayarrayprop = class(tpointerarrayprop) + protected + procedure internalsetcount(const acount: int32) virtual abstract; + procedure setcount1(acount: integer; doinit: boolean); override; + public + destructor destroy(); override; + end; + + tpersistentarrayprop = class(tarrayprop,iobjectlink) + private //same layout as tpointerarrayprop! + protected + fitems: persistentarty; //same layout as tintegerarrayprop! + fdestroyingitem: tpersistent; + fitemclasstype: virtualpersistentclassty; + fobjectlinker: tobjectlinker; + function _addref: integer; stdcall; + function _release: integer; stdcall; + function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall; + + //iobjectlink + procedure link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); + procedure unlink(const source,dest: iobjectlink; valuepo: pointer = nil); + procedure objevent(const sender: iobjectlink; const event: objecteventty); + function getinstance: tobject; + + function getobjectlinker: tobjectlinker; + procedure objectevent(const sender: tobject; const event: objecteventty); virtual; + function getitems(const index: integer): tpersistent;{ virtual;} + procedure init(startindex,endindex: integer); override; + function getcount: integer; override; + procedure setcount1(acount: integer; doinit: boolean); override; + procedure writeitem(const index: integer; writer: twriter); override; + procedure readitem(const index: integer; reader: treader); override; + function getsize: integer; override; + function getdatapo: pointer; override; + function getitemspo(const index: integer): pointer; override; + procedure createitem(const index: integer; var item: tpersistent); virtual; + procedure defineproperties(filer: tfiler); override; + procedure readcollection(reader: treader); + procedure writecollection(writer: twriter); + function getcollectionname(const index: integer): string; virtual; + function ispropertystored(index: integer): boolean; virtual; + procedure setlinkedvar(const source: tmsecomponent; var dest: tmsecomponent; + const linkintf: iobjectlink = nil); overload; + procedure setlinkedvar(const source: tlinkedobject; var dest: tlinkedobject; + const linkintf: iobjectlink = nil); overload; + public + constructor create(aitemclasstype: virtualpersistentclassty); reintroduce; + destructor destroy; override; + procedure itemdestroyed(const aitem: tpersistent); + procedure assign(source: tpersistent); override; + function propkind: arraypropkindty; override; + function displayname(const index: integer): msestring; virtual; + procedure add(const item: tpersistent); + function add(): tpersistent; //returns added element + function indexof(const aitem: tpersistent): integer; //-1 if not found + class function getitemclasstype: persistentclassty; virtual; + //used in dumpunitgroups + property itemclasstype: virtualpersistentclassty read fitemclasstype; + property items[const index: integer]: tpersistent read getitems; default; + end; + persistentarraypropclassty = class of tpersistentarrayprop; + + tmsecomponentlinkarrayprop = class; + + tmsecomponentlinkitem = class(tvirtualpersistent) + private + fitem: tmsecomponent; + procedure setitem(const avalue: tmsecomponent); + protected + fprop: tmsecomponentlinkarrayprop; + property item: tmsecomponent read fitem write setitem; + public + destructor destroy; override; + published + end; + + msecomponentlinkitemclassty = class of tmsecomponentlinkitem; + + tmsecomponentlinkarrayprop = class(tpersistentarrayprop) + private +// function getitems(const index: integer): tmsecomponent; +// procedure setitems(const index: integer; const avalue: tmsecomponent); + protected + procedure createitem(const index: integer; var item: tpersistent); override; + public + constructor create(const aitemclasstype: msecomponentlinkitemclassty); + class function getitemclasstype: persistentclassty; override; +// property items[const index: integer]: tmsecomponent read getitems +// write setitems; default; + end; + + ownedpersistentclassty = class of townedpersistent; + + townedpersistentarrayprop = class(tpersistentarrayprop) + private + protected + fowner: tobject; + procedure createitem(const index: integer; var item: tpersistent); override; + procedure internalcreate(const aowner: tobject; + aclasstype: virtualpersistentclassty); + public + constructor create(const aowner: tobject; + aclasstype: ownedpersistentclassty); virtual; + end; + + tindexpersistentarrayprop = class; + + ownedeventpersistentclassty = class of townedeventpersistent; + + townedeventpersistentarrayprop = class(tpersistentarrayprop) + private + protected + fowner: tobject; + procedure createitem(const index: integer; var item: tpersistent); override; + public + constructor create(const aowner: tobject; + aclasstype: ownedeventpersistentclassty); + end; + + tpersistonchangearrayprop = class(tpersistentarrayprop) + protected + onchange1: notifyeventty; + public + constructor create(aclasstype: virtualpersistentclassty; aonchange: notifyeventty); + end; + + tstringlistarrayprop = class(tpersistentarrayprop) + private + function getitems(index: integer): tstringlist; reintroduce; + procedure setitems(index: integer; const Value: tstringlist); reintroduce; + protected + procedure createitem(const index: integer; var item: tpersistent); override; + public + property items[index: integer]: tstringlist read getitems write setitems; + end; + + tindexpersistent = class(townedeventpersistent) + private + fident: integer; + fprop: tindexpersistentarrayprop; + protected + findex: integer; + procedure dostatwrite(const writer: tstatwriter); virtual; + procedure dostatread(const reader: tstatreader); virtual; + public + constructor create(const aowner: tobject; + const aprop: tindexpersistentarrayprop); reintroduce; virtual; + property index: integer read findex; + property ident: integer read fident; + property prop: tindexpersistentarrayprop read fprop; + end; + + indexpersistentclassty = class of tindexpersistent; + + tindexpersistentarrayprop = class(townedpersistentarrayprop) + private + fident: integer; + function getidents: integerarty; + function getidentmap: integerarty; + protected + procedure createitem(const index: integer; var item: tpersistent); override; + procedure change(const index: integer); override; + function getidentnum(const index: integer): integer; + procedure dosizechanged; override; + function originalorder: integerarty; //restores original order, returns sort vector + public + constructor create(const aowner: tobject; aclasstype: indexpersistentclassty); + reintroduce; virtual; + procedure add(const item: tindexpersistent); + procedure dostatwrite(const writer: tstatwriter; const aorder: boolean); + procedure writeorder(const writer: tstatwriter); + function readorder(const reader: tstatreader): integerarty; + procedure dostatread(const reader: tstatreader; const aorder: boolean); + procedure clearorder; //ident order = index order + function newident: integer; + property idents: integerarty read getidents; + property identmap: integerarty read getidentmap; + end; +{ + tsubcomponentitem = class(tindexpersistent) + protected + fitem: tcomponent; + function createitem: tcomponent; virtual; abstract; + function getnamebase: string; virtual; + public + constructor create(const aowner: tobject; + const aprop: tindexpersistentarrayprop); override; + destructor destroy; override; + end; + subcomponentitemclassty = class of tsubcomponentitem; + + tsubcomponentarrayprop = class(tindexpersistentarrayprop) + protected +// procedure createitem(const index: integer; var item: tpersistent); override; + public + constructor create(const aowner: tcomponent; + const aitemclasstype: subcomponentitemclassty); reintroduce; + end; +} +implementation +uses + rtlconsts,msedatalist,msearrayutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tbinaryobjectreader1 = class(tbinaryobjectreader); + twriter1 = class(twriter); + treader1 = class(treader); + +{ tarrayprop } + +procedure tarrayprop.checkindex(const index: integer); +begin + if (index < 0) or (index >= count) then begin + tlist.Error({$ifndef FPC}@{$endif}SListIndexError, Index); + end; +end; + +function tarrayprop.checkstored(ancestor: tpersistent): boolean; +begin + if ancestor is tarrayprop then begin + with tarrayprop(ancestor) do begin + result:= (self.count <> 0) or (count <> 0); + end; + end + else begin + result:= false; + end; +end; + +procedure tarrayprop.change(const index: integer); +begin + if (fupdating = 0) and not (aps_destroying in fstate) then begin + dochange(index); + end; +end; + +procedure tarrayprop.beginupdate; +begin + inc(fupdating); +end; + +procedure tarrayprop.endupdate(nochange: boolean = false); +begin + dec(fupdating); + if not nochange then begin + change(-1); + end; +end; + +procedure tarrayprop.clear; +begin + count:= 0; +end; + +procedure tarrayprop.dosizechanged; +begin + //dummy +{ + if assigned(fonsizechanged) then begin + fonsizechanged(self); + end; + } +end; + +procedure tarrayprop.checkcount(var acount: integer); +begin + if ffixcount <> 0 then begin + acount:= ffixcount; + end; +end; + +procedure tarrayprop.setcount1(acount: integer; doinit: boolean); +var + int1: integer; + obj: tarrayprop; + count2: integer; + +begin + if acount <> fcountbefore then begin + if acount = 0 then begin + fstate:= fstate - [aps_needsindexing,aps_moved]; + end; + count2:= fcountbefore; + if acount > fcountbefore then begin +// fillchar(getitemspo(fcountbefore)^,(acount-fcountbefore)*getsize,#0); + if doinit then begin + init(fcountbefore,acount-1); + end; + end + else begin + if aps_moved in fstate then begin + include(fstate,aps_needsindexing); + end; + end; + fcountbefore:= acount; + if not (aps_linking in fstate) then begin + for int1:= 0 to length(linkedarrays) - 1 do begin + obj:= linkedarrays[int1]; + if obj <> self then begin + include(obj.fstate,aps_linking); + try + obj.count:= acount; + finally + exclude(obj.fstate,aps_linking); + end; + end; + end; + end; + change(-1); + if (count2 <> acount) and not (aps_destroying in fstate) then begin + dosizechanged; + end; + end; +end; + +procedure tarrayprop.setcount(const acount: integer); +begin + setcount1(acount,true); +end; + +procedure tarrayprop.setfixcount(const avalue: integer); +begin + if ffixcount <> avalue then begin + ffixcount:= avalue; + setcount(avalue); + end; +end; + +procedure tarrayprop.readcount(reader: treader); +begin + beginupdate; + try + count:= reader.ReadInteger; + finally + endupdate; + end; +end; + +procedure tarrayprop.writecount(writer: twriter); +begin + writer.writeinteger(count); +end; + +procedure tarrayprop.readitems(reader: treader); +var + int1: integer; +begin + int1:= 0; + reader.ReadListBegin; + while not reader.EndOfList do begin + if int1 >= count then begin + raise earraystreamerror.create('Arrayproperty length mismatch: '+ + inttostr(count) + '.'); + end; + readitem(int1,reader); + inc(int1); + end; + reader.readlistend; + itemsread:= true; +end; + +procedure tarrayprop.writeitems(writer: twriter); +var + int1: integer; +begin + writer.writeListBegin; + for int1:= 0 to count-1 do begin + writeitem(int1,writer); + end; + writer.writelistend; +end; + +procedure tarrayprop.defineproperties(filer: tfiler); + + function DoWrite: Boolean; + begin + if Filer.Ancestor <> nil then begin + Result := checkstored(filer.Ancestor); + end + else begin + Result := Count > 0; + end; + end; + +begin +// filer.DefineProperty('count',readcount,writecount,true); + filer.DefineProperty('items',{$ifdef FPC}@{$endif}readitems, + {$ifdef FPC}@{$endif}writeitems,dowrite); + if itemsread then begin + itemsread:= false; + change(-1); + end; +end; + +procedure tarrayprop.link(alinkedarrays: array of tarrayprop{; + onsizechanged: arraysizechangeeventty = nil}); +var + int1: integer; +begin +// fonsizechanged:= onsizechanged; + setlength(linkedarrays,high(alinkedarrays)+1); + for int1:= 0 to high(alinkedarrays) do begin + linkedarrays[int1]:= alinkedarrays[int1]; + end; + for int1:= 0 to length(linkedarrays)-1 do begin + if linkedarrays[int1] <> self then begin + linkedarrays[int1].linkedarrays:= linkedarrays; + end; + end; + setcount(count); +end; + +procedure tarrayprop.init(startindex, endindex: integer); +begin + //dummy +end; + +procedure tarrayprop.dochange(const aindex: integer); +begin + if assigned(fonchange) then begin + fonchange(self,aindex); + end; +end; + +procedure tarrayprop.move(const curindex, newindex: integer); +var + postart,pocur,ponew,poend,backup: pchar; + size,count1: integer; +begin + if curindex <> newindex then begin + checkindex(curindex); + checkindex(newindex); + include(fstate,aps_moved); + size:= getsize; + count1:= getcount; + postart:= getitemspo(0); + pocur:= postart + curindex*size; + ponew:= postart + newindex*size; + poend:= postart + count1*size; + getmem(backup,size); + try + system.move(pocur^,backup^,size); + system.move((pocur+size)^,pocur^,poend-pocur-size); + system.move(ponew^,(ponew+size)^,poend-ponew-size); + system.move(backup^,ponew^,size); + finally + freemem(backup); + end; + change(-1); +// change(curindex); +// change(newindex); + end; +end; + +procedure tarrayprop.order(const sourceorder: integerarty); +var + int1: integer; +begin + if sourceorder <> nil then begin + int1:= getcount; + if int1 <> length(sourceorder) then begin + raise exception.create('tarrayprop: Wrong length of neworder'); + end; + if int1 > 0 then begin + include(fstate,aps_moved); + orderarray(sourceorder,getdatapo^,getsize); + end; + change(-1); + end; +end; + +procedure tarrayprop.reorder(const destorder: integerarty); +var + int1: integer; +begin + int1:= getcount; + if int1 <> length(destorder) then begin + raise exception.create('tarrayprop: Wrong length of neworder'); + end; + if int1 > 0 then begin + include(fstate,aps_moved); + reorderarray(destorder,getdatapo^,getsize); + end; + change(-1); +end; + +procedure tarrayprop.delete(const index: integer); +begin + beginupdate; + try + move(index,count - 1); + count:= count - 1; + finally + endupdate; + end; +end; + +procedure tarrayprop.internalinsert(const index: integer; const init: boolean); +begin + include(fstate,aps_moved); + beginupdate; + try + setcount1(count + 1,init); + move(count-1,index); + finally + endupdate; + end; +end; + +procedure tarrayprop.insertempty(const index: integer); +begin + internalinsert(index,false); +end; + +procedure tarrayprop.insertdefault(const index: integer); +begin + internalinsert(index,true); +end; + +function tarrayprop.propkind: arraypropkindty; +begin + result:= apk_none; +end; + +{ tintegerarrayprop } + +function tintegerarrayprop.checkstored(ancestor: tpersistent): boolean; +begin + result:= not (ancestor is tintegerarrayprop); + if not result then begin + with tintegerarrayprop(ancestor) do begin + result:= self.count <> count; + if not result then begin + result:= not comparemem(@self.fitems[0],@fitems[0], + length(fitems)*sizeof(integer)); + end; + end; + end; +end; + +function tintegerarrayprop.getcount: integer; +begin + result:= length(fitems); +end; + +procedure tintegerarrayprop.readitem(const index: integer; reader: treader); +begin + fitems[index]:= reader.ReadInteger; +end; + +procedure tintegerarrayprop.writeitem(const index: integer; writer: twriter); +begin + writer.writeinteger(fitems[index]); +end; + +procedure tintegerarrayprop.setcount1(acount: integer; doinit: boolean); +begin + checkcount(acount); + setlength(fitems,acount); //immer zuerst! + inherited; +end; + +function tintegerarrayprop.getitemspo(const index: integer): pointer; +begin + result:= @fitems[index]; +end; + +function tintegerarrayprop.getsize: integer; +begin + result:= sizeof(integer); +end; + +function tintegerarrayprop.getdatapo: pointer; +begin + result:= @fitems; +end; + +function tintegerarrayprop.getitems(const index: integer): integer; +begin + checkindex(index); + result:= fitems[index]; +end; + +procedure tintegerarrayprop.setitems(const index: integer; const Value: integer); +begin + checkindex(index); + fitems[index]:= value; + change(index); +end; + +procedure tintegerarrayprop.assign(source: tpersistent); +begin + if source is tintegerarrayprop then begin + fitems:= copy(tintegerarrayprop(source).fitems); + beginupdate; + setcount1(length(fitems),false); + endupdate; + end + else begin + inherited; + end; +end; + +function tintegerarrayprop.propkind: arraypropkindty; +begin + result:= apk_integer; +end; + +{ tcolorarrayprop } + +constructor tcolorarrayprop.create; +begin + fvaluedefault:= cl_none; + inherited; +end; + +function tcolorarrayprop.getitems(const index: integer): colorty; +begin + checkindex(index); + result:= fitems[index]; +end; + +procedure tcolorarrayprop.setitems(const index: integer; const Value: colorty); +begin + inherited setitems(index,value); +end; + +procedure tcolorarrayprop.init(startindex, endindex: integer); +var + int1: integer; +begin + for int1:= startindex to endindex do begin + items[int1]:= fvaluedefault; + end; +end; + +function tcolorarrayprop.propkind: arraypropkindty; +begin + result:= apk_colorty; +end; + +{ tint64arrayprop } + +function tint64arrayprop.checkstored(ancestor: tpersistent): boolean; +begin + result:= not (ancestor is tint64arrayprop); + if not result then begin + with tint64arrayprop(ancestor) do begin + result:= self.count <> count; + if not result then begin + result:= not comparemem(@self.fitems[0],@fitems[0], + length(fitems)*sizeof(int64)); + end; + end; + end; +end; + +function tint64arrayprop.getcount: integer; +begin + result:= length(fitems); +end; + +procedure tint64arrayprop.readitem(const index: integer; reader: treader); +begin + fitems[index]:= reader.ReadInt64; +end; + +procedure tint64arrayprop.writeitem(const index: integer; writer: twriter); +begin + writer.writeinteger(fitems[index]); +end; + +procedure tint64arrayprop.setcount1(acount: integer; doinit: boolean); +begin + checkcount(acount); + setlength(fitems,acount); //immer zuerst! + inherited; +end; + +function tint64arrayprop.getitemspo(const index: integer): pointer; +begin + result:= @fitems[index]; +end; + +function tint64arrayprop.getsize: integer; +begin + result:= sizeof(int64); +end; + +function tint64arrayprop.getdatapo: pointer; +begin + result:= @fitems; +end; + +function tint64arrayprop.getitems(const index: integer): int64; +begin + checkindex(index); + result:= fitems[index]; +end; + +procedure tint64arrayprop.setitems(const index: integer; const Value: int64); +begin + checkindex(index); + fitems[index]:= value; + change(index); +end; + +procedure tint64arrayprop.assign(source: tpersistent); +begin + if source is tint64arrayprop then begin + fitems:= copy(tint64arrayprop(source).fitems); + beginupdate; + setcount1(length(fitems),false); + endupdate; + end + else begin + inherited; + end; +end; + +function tint64arrayprop.propkind: arraypropkindty; +begin + result:= apk_int64; +end; + +{ trealarrayprop } + +function trealarrayprop.getcount: integer; +begin + result:= length(fitems); +end; + +function trealarrayprop.getitemspo(const index: integer): pointer; +begin + result:= @fitems[index]; +end; + +function trealarrayprop.getsize: integer; +begin + result:= sizeof(real); +end; + +function trealarrayprop.getdatapo: pointer; +begin + result:= @fitems; +end; + +procedure trealarrayprop.setcount1(acount: integer; doinit: boolean); +begin + checkcount(acount); + setlength(fitems,acount); //immer zuerst! + inherited; +end; + +procedure trealarrayprop.readitem(const index: integer; reader: treader); +begin + fitems[index]:= reader.ReadFloat; +end; + +procedure trealarrayprop.writeitem(const index: integer; writer: twriter); +begin + writer.writefloat(fitems[index]); +end; + +function trealarrayprop.getitems(const index: integer): real; +begin + checkindex(index); + result:= fitems[index]; +end; + +procedure trealarrayprop.setitems(const index: integer; const Value: real); +begin + checkindex(index); + fitems[index]:= value; + change(index); +end; + +function trealarrayprop.checkstored(ancestor: tpersistent): boolean; +begin + result:= not (ancestor is trealarrayprop); + if not result then begin + with trealarrayprop(ancestor) do begin + result:= self.count <> count; + if not result then begin + result:= not comparemem(@self.fitems[0],@fitems[0], + length(fitems)*sizeof(real)); + end; + end; + end; +end; + +procedure trealarrayprop.assign(source: tpersistent); +begin + if source is trealarrayprop then begin + fitems:= copy(trealarrayprop(source).fitems); + beginupdate; + setcount1(length(fitems),false); + endupdate; + end + else begin + inherited; + end; +end; + +function trealarrayprop.propkind: arraypropkindty; +begin + result:= apk_real; +end; + +{ tstringarrayprop } + +function tstringarrayprop.checkstored(ancestor: tpersistent): boolean; +var + int1: integer; +begin + result:= not (ancestor is tstringarrayprop); + if not result then begin + with tstringarrayprop(ancestor) do begin + result:= self.count <> count; + if not result then begin + for int1:= 0 to count - 1 do begin + if self.fitems[int1] <> fitems[int1] then begin + result:= true; + break; + end; + end; + end; + end; + end; +end; + +function tstringarrayprop.getcount: integer; +begin + result:= length(fitems); +end; + +function tstringarrayprop.getitems(const index: integer): string; +begin + checkindex(index); + result:= fitems[index]; +end; + +function tstringarrayprop.getitemspo(const index: integer): pointer; +begin + result:= @fitems[index]; +end; + +function tstringarrayprop.getsize: integer; +begin + result:= sizeof(string); +end; + +function tstringarrayprop.getdatapo: pointer; +begin + result:= @fitems; +end; + +procedure tstringarrayprop.readitem(const index: integer; reader: treader); +begin + fitems[index]:= reader.Readstring; +end; + +procedure tstringarrayprop.setcount1(acount: integer; doinit: boolean); +begin + checkcount(acount); + setlength(fitems,acount); //immer zuerst! + inherited; +end; + +procedure tstringarrayprop.setitems(const index: integer; const Value: string); +begin + checkindex(index); + fitems[index]:= value; + change(index); +end; + +procedure tstringarrayprop.writeitem(const index: integer; writer: twriter); +begin + writer.writestring(fitems[index]); +end; + +procedure tstringarrayprop.assign(source: tpersistent); +begin + if source is tstringarrayprop then begin + fitems:= copy(tstringarrayprop(source).fitems); + beginupdate; + setcount1(length(fitems),false); + endupdate; + end + else begin + inherited; + end; +end; + +function tstringarrayprop.propkind: arraypropkindty; +begin + result:= apk_string; +end; + +function tstringarrayprop.itemar: stringarty; +begin + result:= copy(fitems); +end; + +{ tmsestringarrayprop } + +function tmsestringarrayprop.checkstored(ancestor: tpersistent): boolean; +var + int1: integer; +begin + result:= not (ancestor is tmsestringarrayprop); + if not result then begin + with tmsestringarrayprop(ancestor) do begin + result:= self.count <> count; + if not result then begin + for int1:= 0 to count - 1 do begin + if self.fitems[int1] <> fitems[int1] then begin + result:= true; + break; + end; + end; + end; + end; + end; +end; + +function tmsestringarrayprop.getcount: integer; +begin + result:= length(fitems); +end; + +function tmsestringarrayprop.getitems(const index: integer): msestring; +begin + checkindex(index); + result:= fitems[index]; +end; + +function tmsestringarrayprop.getitemspo(const index: integer): pointer; +begin + result:= @fitems[index]; +end; + +function tmsestringarrayprop.getsize: integer; +begin + result:= sizeof(msestring); +end; + +function tmsestringarrayprop.getdatapo: pointer; +begin + result:= @fitems; +end; + +procedure tmsestringarrayprop.readitem(const index: integer; reader: treader); +begin + fitems[index]:= treader_readmsestring(reader); //msestringimplementation +// {$ifdef mse_unicodestring} +// fitems[index]:= reader.Readunicodestring; //msestringimplementation +// {$else} +// fitems[index]:= reader.Readwidestring; //msestringimplementation +// {$endif} +end; + +procedure tmsestringarrayprop.setcount1(acount: integer; doinit: boolean); +begin + checkcount(acount); + setlength(fitems,acount); //immer zuerst! + inherited; +end; + +procedure tmsestringarrayprop.setitems(const index: integer; const Value: msestring); +begin + checkindex(index); + fitems[index]:= value; + change(index); +end; + +procedure tmsestringarrayprop.writeitem(const index: integer; writer: twriter); +begin + twriter_writemsestring(writer,fitems[index]); +// {$ifdef mse_unicodestring} +// writer.writeunicodestring(fitems[index]); +// {$else} +// writer.writewidestring(fitems[index]); //msestringimplementation +// {$endif} +end; + +procedure tmsestringarrayprop.assign(source: tpersistent); +begin + if source is tmsestringarrayprop then begin + fitems:= copy(tmsestringarrayprop(source).fitems); + beginupdate; + setcount1(length(fitems),false); + endupdate; + end + else begin + inherited; + end; +end; + +function tmsestringarrayprop.propkind: arraypropkindty; +begin + result:= apk_msestring; +end; + +{ tbooleanarrayprop } + +function tbooleanarrayprop.getitems(const index: integer): boolean; +begin + checkindex(index); + result:= boolean(fitems[index]); +end; + +procedure tbooleanarrayprop.setitems(const index: integer; + const Value: boolean); +begin + inherited setitems(index,integer(value)); +end; + +function tbooleanarrayprop.propkind: arraypropkindty; +begin + result:= apk_boolean; +end; + +{ tenumarrayprop } + +constructor tenumarrayprop.create(typeinfo: ptypeinfo); +begin + if typeinfo^.Kind <> tkenumeration then begin + raise earrayproperror.Create('typ muss enum sein!'); + end; + ftypeinfo:= typeinfo; + inherited create; +end; + +{ tsetarraypropmse } + +constructor tsetarrayprop.create(typeinfo: ptypeinfo); +var + typedatapo: ptypedata; + +begin + if typeinfo^.Kind <> tkset then begin + raise earrayproperror.Create('typ muss set sein!'); + end; + ftypeinfo:= typeinfo; + typedatapo:= gettypedata(ftypeinfo); + typedatapo:= gettypedata(typedatapo^.comptype{$ifndef FPC}^{$endif}); +// fsize:= (typedatapo^.maxvalue - typedatapo^.minvalue) div 8 + 1; + if (typedatapo^.maxvalue - typedatapo^.minvalue) div 8 + 1 > + sizeof(tintegerset) then begin + raise earrayproperror.Create('set muss <= 32 sein!'); + end; +// {$ifdef FPC} +// fsize:= sizeof(longword); +// {$endif} + inherited create; +end; +{ +function tsetarrayprop.getcount: integer; +begin + result:= length(fitems); +end; +} +function tsetarrayprop.getitems(const index: integer): tintegerset; +begin + checkindex(index); + result:= tintegerset(fitems[index]); +end; +{ +function tsetarrayprop.getitemspo(const index: integer): pointer; +begin + result:= @fitems[index]; +end; + +function tsetarrayprop.getsize: integer; +begin + result:= sizeof(tintegerset); +end; + +function tsetarrayprop.getdatapo: pointer; +begin + result:= @fitems; +end; + +procedure tsetarrayprop.setcount1(acount: integer; doinit: boolean); +begin + checkcount(acount); + setlength(fitems,acount); //immer zuerst! + inherited; +end; +} +procedure tsetarrayprop.setitems(const index: integer; const Value: tintegerset); +begin + checkindex(index); + fitems[index]:= integer(value); + change(index); +end; + +procedure tsetarrayprop.writeitem(const index: integer; writer: twriter); +begin + writeset(writer,tintegerset(fitems[index]),ftypeinfo); +end; + +procedure tsetarrayprop.readitem(const index: integer; reader: treader); +begin + fitems[index]:= integer(readset(reader,ftypeinfo)); +end; +{ +procedure tsetarrayprop.getset(const index: integer; out value); +begin + checkindex(index); + system.move(fitems[index],value,fsize); +end; + +procedure tsetarrayprop.setset(const index: integer; const value); +begin + checkindex(index); + fillchar(fitems[index],sizeof(tintegerset),0); + system.move(value,fitems[index],fsize); +end; +} + +{ tpointerarrayprop } + +function tpointerarrayprop.checkstored(ancestor: tpersistent): boolean; +begin + result:= not (ancestor is tpointerarrayprop); + if not result then begin + with tpointerarrayprop(ancestor) do begin + result:= self.count <> count; + if not result then begin + result:= not comparemem(@self.fitems[0],@fitems[0], + length(fitems)*sizeof(pointer)); + end; + end; + end; +end; + +function tpointerarrayprop.getcount: integer; +begin + result:= length(fitems); +end; + +procedure tpointerarrayprop.readitem(const index: integer; reader: treader); +begin +{$ifdef CPU64} + fitems[index]:= pointer(reader.ReadInt64); +{$else} + fitems[index]:= pointer(reader.ReadInteger); +{$endif} +end; + +procedure tpointerarrayprop.writeitem(const index: integer; writer: twriter); +begin +{$ifdef CPU64} + writer.writeinteger(int64(fitems[index])); +{$else} + writer.writeinteger(integer(fitems[index])); +{$endif} +end; + +procedure tpointerarrayprop.setcount1(acount: integer; doinit: boolean); +begin + checkcount(acount); + setlength(fitems,acount); //immer zuerst! + inherited; +end; + +function tpointerarrayprop.getitemspo(const index: integer): pointer; +begin + result:= @fitems[index]; +end; + +function tpointerarrayprop.getsize: integer; +begin + result:= sizeof(pointer); +end; + +function tpointerarrayprop.getdatapo: pointer; +begin + result:= @fitems; +end; + +function tpointerarrayprop.getitems(const index: integer): pointer; +begin + checkindex(index); + result:= fitems[index]; +end; + +procedure tpointerarrayprop.setitems(const index: integer; const Value: pointer); +begin + checkindex(index); + fitems[index]:= value; + change(index); +end; + +procedure tpointerarrayprop.assign(source: tpersistent); +begin + if source is tpointerarrayprop then begin + fitems:= copy(tpointerarrayprop(source).fitems); + beginupdate; + setcount1(length(fitems),false); + endupdate; + end + else begin + inherited; + end; +end; + +function tpointerarrayprop.propkind: arraypropkindty; +begin + result:= apk_pointer; +end; + +{ tdynarrayarrayprop } + +destructor tdynarrayarrayprop.destroy(); +begin + inherited; + internalsetcount(0); +end; + +procedure tdynarrayarrayprop.setcount1(acount: integer; doinit: boolean); +begin + checkcount(acount); + internalsetcount(acount); + inherited; +end; + +{ tpersistentarrayprop } + +constructor tpersistentarrayprop.create(aitemclasstype: virtualpersistentclassty); +begin + fitemclasstype:= aitemclasstype; + inherited create; +end; + +destructor tpersistentarrayprop.destroy; +begin + include(fstate,aps_destroying); + setlength(linkedarrays,0); + clear; + inherited; + fobjectlinker.free; +end; + +function tpersistentarrayprop.getcount: integer; +begin + result:= length(fitems); +end; + +procedure tpersistentarrayprop.init(startindex, endindex: integer); +var + int1: integer; +begin + inherited; + for int1:= startindex to endindex do begin + createitem(int1,fitems[int1]); + end; +end; + +procedure tpersistentarrayprop.setcount1(acount: integer; doinit: boolean); +var + {lengthvorher,}int1: integer; + ar1: persistentarty; + pers1: tpersistent; +begin + if not (aps_destroying in fstate) then begin + checkcount(acount); + end; + int1:= length(fitems) - acount; + if int1 > 0 then begin + pers1:= fdestroyingitem; + ar1:= copy(fitems,acount,int1); + setlength(fitems,acount); //return new count + for int1:= high(ar1) downto 0 do begin + fdestroyingitem:= ar1[int1]; + ar1[int1].free; + end; + fdestroyingitem:= pers1; + end + else begin + setlength(fitems,acount); + end; + inherited; +end; + +procedure tpersistentarrayprop.readitem(const index: integer; reader: treader); +begin + //dummy +end; + +procedure tpersistentarrayprop.writeitem(const index: integer; writer: twriter); +begin + //dummy +end; + +function tpersistentarrayprop.getitemspo(const index: integer): pointer; +begin + result:= @fitems[index]; +end; + +function tpersistentarrayprop.getsize: integer; +begin + result:= sizeof(tpersistent); +end; + +function tpersistentarrayprop.getdatapo: pointer; +begin + result:= @fitems; +end; + +procedure tpersistentarrayprop.createitem(const index: integer; + var item: tpersistent); +begin + if fitemclasstype <> nil then begin + item:= fitemclasstype.create; + end + else begin + item:= nil; + end; +end; + +function tpersistentarrayprop.ispropertystored(index: integer): boolean; +begin + result:= fitems[index] <> nil; +end; + +procedure tpersistentarrayprop.readcollection(reader: treader); +var + int1,int2,int3: integer; + str1: string; +begin + with treader1(reader) do begin + readvalue; + int1:= 0; + while not EndOfList do begin + if NextValue in [vaInt8, vaInt16, vaInt32] then ReadInteger; + int2:= int1; + if nextvalue = vaident then begin + str1:= readident; + if str1 <> '' then begin + for int3:= 0 to count-1 do begin + if getcollectionname(int3) = str1 then begin + int2:= int3; + break; + end; + end; + end; + end; + ReadListBegin; + while not EndOfList do begin + if int2 <= high(fitems) then begin + treader1(reader).ReadProperty(getitems(int2)); + end + else begin + tbinaryobjectreader1(reader.driver).skipproperty; + end; + end; + ReadListEnd; + inc(int1); + end; + readlistend; + end; + itemsread:= true; +end; + +procedure tpersistentarrayprop.writecollection(writer: twriter); +var + int1,int2,int3: integer; + proppathvorher: string; + ancestorbefore: tpersistentarrayprop; + str1: string; + +begin + proppathvorher:= getfproppath(writer); + setfproppath(writer,''); + ancestorbefore:= tpersistentarrayprop(writer.ancestor); + try + with twriter1(writer) do begin + driver.begincollection; + for int1 := 0 to Count - 1 do begin + str1:= getcollectionname(int1); + if str1 <> '' then begin + writeident(str1); + end; + WriteListBegin; + ancestor:= nil; + if ancestorbefore <> nil then begin + int2:= int1; + if (str1 <> '') then begin + int2:= bigint; //needs ancestor name + for int3:= 0 to ancestorbefore.count-1 do begin + if ancestorbefore.getcollectionname(int3) = str1 then begin + int2:= int3; + break; + end; + end; + end; + if (int2 < ancestorbefore.count) then begin + ancestor:= ancestorbefore.fitems[int2]; + end; + end; + if ispropertystored(int1) then begin + twriter1(writer).WriteProperties(getitems(int1)); + end; + WriteListEnd; + end; + WriteListEnd; + end; + finally + setfproppath(writer,proppathvorher); + writer.Ancestor:= ancestorbefore; + end; +end; + +procedure tpersistentarrayprop.defineproperties(filer: tfiler); +begin + filer.DefineProperty('items',{$ifdef FPC}@{$endif}readcollection, + {$ifdef FPC}@{$endif}writecollection,count>0); +// inherited; + if itemsread and (filer is treader) then begin + itemsread:= false; + change(-1); + end; +end; + +procedure tpersistentarrayprop.link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); +begin + getobjectlinker.link(source,dest,valuepo,ainterfacetype,once); +end; + +procedure tpersistentarrayprop.unlink(const source,dest: iobjectlink; valuepo: pointer = nil); +begin + getobjectlinker.unlink(source,dest,valuepo); +end; + +procedure tpersistentarrayprop.objevent(const sender: iobjectlink; const event: objecteventty); +begin + getobjectlinker.objevent(sender,event); +end; + +function tpersistentarrayprop.getinstance: tobject; +begin + result:= self; +end; + +function tpersistentarrayprop._addref: integer; stdcall; +begin + result:= -1; +end; + +function tpersistentarrayprop._release: integer; stdcall; +begin + result:= -1; +end; + +function tpersistentarrayprop.QueryInterface(const IID: TGUID; out Obj): HResult; stdcall; +begin + if GetInterface(IID, Obj) then begin + Result:=0 + end + else begin + result:= integer(e_nointerface); + end; +end; + +function tpersistentarrayprop.getobjectlinker: tobjectlinker; +begin + if fobjectlinker = nil then begin + createobjectlinker(iobjectlink(self),{$ifdef FPC}@{$endif}objectevent,fobjectlinker); + end; + result:= fobjectlinker; +end; + +procedure tpersistentarrayprop.objectevent(const sender: tobject; + const event: objecteventty); +begin + //dummy +end; + +procedure tpersistentarrayprop.setlinkedvar(const source: tmsecomponent; + var dest: tmsecomponent; const linkintf: iobjectlink = nil); +begin + if linkintf = nil then begin + getobjectlinker.setlinkedvar(iobjectlink(self),source,dest); + end + else begin + getobjectlinker.setlinkedvar(linkintf,source,dest); + end; +end; + +procedure tpersistentarrayprop.setlinkedvar(const source: tlinkedobject; + var dest: tlinkedobject; const linkintf: iobjectlink = nil); +begin + if linkintf = nil then begin + getobjectlinker.setlinkedvar(iobjectlink(self),source,dest); + end + else begin + getobjectlinker.setlinkedvar(linkintf,source,dest); + end; +end; + +function tpersistentarrayprop.getitems(const index: integer): tpersistent; +begin + checkindex(index); + result:= fitems[index]; +end; + +function tpersistentarrayprop.displayname(const index: integer): msestring; +begin + if fitemclasstype <> nil then begin + result:= msestring(PTypeInfo(fitemclasstype.ClassInfo)^.name); + end + else begin + result:= ''; + end; +end; + +procedure tpersistentarrayprop.add(const item: tpersistent); +begin + beginupdate; + setlength(fitems,high(fitems)+2); +// insertempty(length(fitems)); + fitems[high(fitems)]:= item; + setcount1(length(fitems),false); + endupdate; +end; + +function tpersistentarrayprop.add(): tpersistent; //returns added element +begin + count:= count+1; + result:= fitems[high(fitems)]; +end; + +function tpersistentarrayprop.indexof(const aitem: tpersistent): integer; //-1 if not found +var + int1: integer; +begin + result:= -1; + for int1:= 0 to high(fitems) do begin + if fitems[int1] = aitem then begin + result:= int1; + end; + end; +end; + +function tpersistentarrayprop.propkind: arraypropkindty; +begin + result:= apk_tpersistent; +end; + +procedure tpersistentarrayprop.assign(source: tpersistent); +var + int1: integer; +begin + if source is tpersistentarrayprop then begin + clear; + with tpersistentarrayprop(source) do begin + self.count:= count; + for int1:= 0 to count - 1 do begin + self.fitems[int1].assign(fitems[int1]); + end; + end; + end + else begin + inherited; + end; +end; + +class function tpersistentarrayprop.getitemclasstype: persistentclassty; +begin + result:= nil; //dummy +end; + +function tpersistentarrayprop.getcollectionname(const index: integer): string; +begin + result:= ''; +end; + +procedure tpersistentarrayprop.itemdestroyed(const aitem: tpersistent); +begin + if not (aps_destroying in fstate) and (aitem <> fdestroyingitem) then begin + if removeitem(pointerarty(fitems),aitem) >= 0 then begin + change(-1); + dosizechanged; + end; + end; +end; + +{ townedpersistentarrayprop } + +constructor townedpersistentarrayprop.create(const aowner: tobject; + aclasstype: ownedpersistentclassty); +begin + internalcreate(aowner,aclasstype); +end; + +procedure townedpersistentarrayprop.internalcreate(const aowner: tobject; + aclasstype: virtualpersistentclassty); +begin + fowner:= aowner; + inherited create(aclasstype); +end; + +procedure townedpersistentarrayprop.createitem(const index: integer; + var item: tpersistent); +begin + if fitemclasstype <> nil then begin + item:= tpersistent(fitemclasstype.newinstance); + townedpersistent(item).create(fowner); + end + else begin + item:= nil; + end; +end; + +{ townedeventpersistentarrayprop } + +constructor townedeventpersistentarrayprop.create(const aowner: tobject; + aclasstype: ownedeventpersistentclassty); +begin + fowner:= aowner; + inherited create(aclasstype); +end; + +procedure townedeventpersistentarrayprop.createitem(const index: integer; + var item: tpersistent); +begin + if fitemclasstype <> nil then begin + item:= ownedeventpersistentclassty(fitemclasstype).create(fowner); + end + else begin + item:= nil; + end; +end; + +{ tpersistonchangearrayprop } + +constructor tpersistonchangearrayprop.create(aclasstype: virtualpersistentclassty; + aonchange: notifyeventty); +begin + onchange1:= aonchange; + inherited create(aclasstype); +end; + +{ tstringlistarrayprop } + +procedure tstringlistarrayprop.createitem(const index: integer; + var item: tpersistent); +begin + item:= tstringlist.create; +end; + +function tstringlistarrayprop.getitems(index: integer): tstringlist; +begin + checkindex(index); + result:= tstringlist(fitems[index]); +end; + +procedure tstringlistarrayprop.setitems(index: integer; + const Value: tstringlist); +begin + checkindex(index); + tstringlist(fitems[index]).assign(value); +end; + +{ tindexpersistentarrayprop } + +constructor tindexpersistentarrayprop.create(const aowner: tobject; + aclasstype: indexpersistentclassty); +begin + internalcreate(aowner,aclasstype); +end; + +procedure tindexpersistentarrayprop.createitem(const index: integer; + var item: tpersistent); +begin + if fitemclasstype <> nil then begin + item:= indexpersistentclassty(fitemclasstype).create(fowner,self); + tindexpersistent(item).findex:= index; + end + else begin + item:= nil; + end; +end; + +procedure tindexpersistentarrayprop.change(const index: integer); +var + int1: integer; + item1: tindexpersistent; +begin + if (index < 0) and (fupdating = 0) then begin + for int1:= 0 to high(fitems) do begin + item1:= tindexpersistent(fitems[int1]); + if item1 <> nil then begin + item1.findex:= int1; + end; + end; + end; + inherited; +end; + +function tindexpersistentarrayprop.getidentnum(const index: integer): integer; +var + item1: tindexpersistent; +begin + item1:= tindexpersistent(fitems[index]); + if item1 <> nil then begin + result:= item1.fident; + end + else begin + result:= bigint; + end; +end; + +function tindexpersistentarrayprop.newident: integer; +begin + if aps_needsindexing in fstate then begin + result:= newidentnum(count,{$ifdef FPC}@{$endif}getidentnum); + end + else begin + result:= fident; + inc(fident); + end; +end; + +procedure tindexpersistentarrayprop.dosizechanged; +begin + if count = 0 then begin + exclude(fstate,aps_needsindexing); + fident:= 0; + end + else begin + if not (aps_needsindexing in fstate) then begin + fident:= count; + end; + end; + inherited; +end; + +procedure tindexpersistentarrayprop.writeorder(const writer: tstatwriter); +var + int1,int2,int3: integer; + ar1: integerarty; + bo1: boolean; +begin + if count > 0 then begin + setlength(ar1,count); + int2:= tindexpersistent(fitems[0]).fident; + bo1:= false; + for int1:= 0 to count -1 do begin + int3:= tindexpersistent(fitems[int1]).fident; + if int3 < int2 then begin + bo1:= true; + end; + ar1[int1]:= int3; + int2:= int3; + end; + if bo1 then begin + writer.writearray('order',ar1); + end; + end; +end; + +function tindexpersistentarrayprop.readorder( + const reader: tstatreader): integerarty; +var + ar1,ar2: integerarty; + int1: integer; +begin + result:= nil; + beginupdate; + try + ar1:= nil; + ar1:= reader.readarray('order',ar1); + if (ar1 <> nil) and (high(ar1) = high(fitems)) then begin + sortarray(ar1,ar2); + for int1:= 0 to high(ar1) do begin + if ar1[int1] <> int1 then begin + exit; //invalid + end; + end; + reorderarray(ar2,pointerarty(fitems)); + for int1:= 0 to count -1 do begin + tindexpersistent(fitems[int1]).findex:= int1; + end; + result:= ar2; + end; + finally + endupdate; + end; +end; + +procedure tindexpersistentarrayprop.dostatread(const reader: tstatreader; + const aorder: boolean); +var + int1: integer; +begin + if reader.canstate then begin + beginupdate; + try + if aorder then begin + readorder(reader); + end; + for int1:= 0 to count -1 do begin + tindexpersistent(fitems[int1]).dostatread(reader); + end; + finally + endupdate; + end; + end; +end; + +procedure tindexpersistentarrayprop.dostatwrite(const writer: tstatwriter; + const aorder: boolean); +var + int1: integer; +begin + if writer.canstate then begin + for int1:= 0 to count -1 do begin + tindexpersistent(fitems[int1]).dostatwrite(writer); + end; + if aorder then begin + writeorder(writer); + end; + end; +end; + +procedure tindexpersistentarrayprop.add(const item: tindexpersistent); +begin + item.findex:= count; + inherited add(item); +end; + +function tindexpersistentarrayprop.getidents: integerarty; +var + int1: integer; +begin + setlength(result,count); + for int1:= 0 to high(fitems) do begin + result[int1]:= tindexpersistent(fitems[int1]).fident; + end; +end; + +function tindexpersistentarrayprop.originalorder: integerarty; +var + int1: integer; + ar1: integerarty; +begin + ar1:= getidents; + sortarray(ar1,result); + orderarray(result,pointerarty(fitems)); + for int1:= 0 to count -1 do begin + tindexpersistent(fitems[int1]).findex:= int1; + end; +end; + +function tindexpersistentarrayprop.getidentmap: integerarty; + var + int1,int2: integer; +begin + int2:= -1; + for int1:= 0 to high(fitems) do begin + with tindexpersistent(fitems[int1]) do begin + if fident > int2 then begin + int2:= fident; + end; + end; + end; + setlength(result,int2+1); + for int2:= 0 to high(result) do begin + result[int2]:= -1; + for int1:= 0 to high(fitems) do begin + with tindexpersistent(fitems[int1]) do begin + if fident = int2 then begin + result[int2]:= int1; + break; + end; + end; + end; + end; +end; + +procedure tindexpersistentarrayprop.clearorder; +var + int1: integer; +begin + fident:= count; + exclude(fstate,aps_needsindexing); + for int1:= 0 to fident - 1 do begin + with tindexpersistent(fitems[int1]) do begin + fident:= int1; + end; + end; +end; + +{ tindexpersistent } + +constructor tindexpersistent.create(const aowner: tobject; + const aprop: tindexpersistentarrayprop); +begin + findex:= -1; + fprop:= aprop; + inherited create(aowner); + fident:= fprop.newident; +end; + +procedure tindexpersistent.dostatread(const reader: tstatreader); +begin + //dummy +end; + +procedure tindexpersistent.dostatwrite(const writer: tstatwriter); +begin + //dummy +end; + +{ tmsecomponenlinktitem } + +destructor tmsecomponentlinkitem.destroy; +begin + item:= nil; + inherited; +end; + +procedure tmsecomponentlinkitem.setitem(const avalue: tmsecomponent); +begin + fprop.setlinkedvar(avalue,fitem); +end; + +{ tmsecomponentlinkarrayprop } + +constructor tmsecomponentlinkarrayprop.create( + const aitemclasstype: msecomponentlinkitemclassty); +begin + inherited create(aitemclasstype); +end; +{ +function tmsecomponentarrayprop.getitems(const index: integer): tmsecomponent; +begin + result:= tmsecomponent(inherited getitems(index)); +end; + +procedure tmsecomponentarrayprop.setitems(const index: integer; + const avalue: tmsecomponent); +begin + inherited; +end; +} +procedure tmsecomponentlinkarrayprop.createitem(const index: integer; + var item: tpersistent); +begin + inherited; + tmsecomponentlinkitem(item).fprop:= self; +end; + +class function tmsecomponentlinkarrayprop.getitemclasstype: persistentclassty; +begin + result:= tmsecomponentlinkitem; +// result:= tmsecomponent; +end; +(* +{ tsubcomponentarrayprop } + +constructor tsubcomponentarrayprop.create(const aowner: tcomponent; + const aitemclasstype: subcomponentitemclassty); +begin + inherited create(aowner,aitemclasstype); +end; + +{ tsubcomponentitem } + +constructor tsubcomponentitem.create(const aowner: tobject; + const aprop: tindexpersistentarrayprop); +begin + inherited; + fitem:= createitem; + if not (csloading in tcomponent(aowner).componentstate) then begin + fitem.name:= getnumberedname(tcomponent(aowner),getnamebase); + end; +end; + +destructor tsubcomponentitem.destroy; +begin + inherited; + fitem.free; +end; + +function tsubcomponentitem.getnamebase: string; +begin + result:= 'item'; +end; +*) + +end. diff --git a/mseide-msegui/lib/common/kernel/msearrayutils.pas b/mseide-msegui/lib/common/kernel/msearrayutils.pas new file mode 100644 index 0000000..d9d855f --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msearrayutils.pas @@ -0,0 +1,3426 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msearrayutils; +{$ifdef FPC}{$mode objfpc}{$h+}{$goto on}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + msetypes,msestrings; +const + arrayminlenghtstep = 32; + +type + stringsortmodety = (sms_none,sms_upascii,sms_upiascii,sms_up,sms_upi); + pointercomparemethodty = function(l,r:pointer): integer of object; + pointercomparefuncty = function(l,r:pointer): integer; + + arraysortcomparety = function (const l,r): integer; + sortcomparemethodty = function (const l,r): integer of object; + sortcomparemethodarty = array of sortcomparemethodty; + indexsortcomparemethodty = function (const l,r: integer): integer of object; + + tvarrecarty = array of tvarrec; + +procedure deleteitem(var value; const typeinfo: pdynarraytypeinfo; + const aindex: integer); overload; + //value = array of type which needs no finalize +procedure arrayaddref(var dynamicarray); +procedure arraydecref(var dynamicarray); + //no finalize and freemem if refcount = 0 +procedure allocuninitedarray(count,itemsize: integer; out dynamicarray); + //does not init memory, dynamicarray must be nil! +procedure reallocuninitedarray(count,itemsize: integer; var dynamicarray); + //does not init memory, dynamicarray must be unique! +procedure freeuninitedarray(var dynamicarray); + //does not finalize items, dynamicarray must be unique! +function arrayrefcount(var dynamicarray): sizeint; +function arrayminhigh(arrays: array of pointer): integer; + //array of dynamicarray +function dynarrayelesize(const typinfo: pdynarraytypeinfo): sizeint; inline; +function dynarrayhigh(const value: pointer): sizeint; inline; +function dynarraylength(const value: pointer): sizeint; inline; +function incrementarraylength(var value: pointer; typeinfo: pdynarraytypeinfo; + increment: integer = 1): sizeint; overload; + //returns new length + +function additem(var value; const typeinfo: pdynarraytypeinfo; + //typeinfo of dynarray + var count: integer): boolean; overload; + //value = array of type, returns true if extended +function additemindex(var value; const typeinfo: pdynarraytypeinfo; + //typeinfo of dynarray + var count: integer): integer; overload; + //value = array of type, returns true if extended +function additempo(var value; const typeinfo: pdynarraytypeinfo; + //typeinfo of dynarray + var count: integer): pointer; overload; + //returns adress of new item + +function firstitem(const source: stringarty): string; overload; +function firstitem(const source: msestringarty): msestring; overload; + + //return true if extended +function additem(var dest: stringarty; const value: string; + var count: integer): boolean; overload; +function additem(var dest: stringararty; const value: stringarty; + var count: integer): boolean; overload; +function additem(var dest: msestringarty; const value: msestring; + var count: integer): boolean; overload; +function additem(var dest: msestringararty; const value: msestringarty; + var count: integer): boolean; overload; +function additem(var dest: lstringarty; const value: lstringty; + var count: integer): boolean; overload; +function additem(var dest: lmsestringarty; const value: lmsestringty; + var count: integer): boolean; overload; +function additem(var dest: int16arty; const value: int16; + var count: integer): boolean; overload; +function additem(var dest: integerarty; const value: integer; + var count: integer): boolean; overload; +function additem(var dest: longwordarty; const value: longword; + var count: integer): boolean; overload; +function additem(var dest: realarty; const value: real; + var count: integer): boolean; overload; +function additem(var dest: pointerarty; const value: pointer; + var count: integer): boolean; overload; +{$ifndef FPC} +function addpointeritem(var dest: pointerarty; const value: pointer; + var count: integer): boolean; +{$endif} +function additem(var dest: winidarty; const value: winidty; + var count: integer): boolean; overload; + +procedure additem(var dest: stringarty; const value: string); overload; +procedure additem(var dest: msestringarty; const value: msestring); overload; +procedure additem(var dest: doublemsestringarty; + const valuea,valueb: msestring); overload; +procedure additem(var dest: msestringararty; + const value: msestringarty); overload; +procedure additem(var dest: int16arty; const value: int16); overload; +procedure additem(var dest: integerarty; const value: integer); overload; +procedure additem(var dest: int64arty; const value: int64); overload; +procedure additem(var dest: card64arty; const value: card64); overload; +procedure additem(var dest: longwordarty; const value: longword); overload; +procedure additem(var dest: longboolarty; const value: longbool); overload; +procedure additem(var dest: booleanarty; const value: boolean); overload; +procedure additem(var dest: realarty; const value: real); overload; +procedure additem(var dest: pointerarty; const value: pointer); overload; +procedure additem(var dest: winidarty; const value: winidty); overload; +procedure deleteitem(var dest: stringarty; index: integer); overload; +procedure deleteitem(var dest: msestringarty; index: integer); overload; +procedure deleteitem(var dest: integerarty; index: integer); overload; +procedure deleteitem(var dest: int64arty; index: integer); overload; +procedure deleteitem(var dest: card64arty; index: integer); overload; +procedure deleteitem(var dest: booleanarty; index: integer); overload; +procedure deleteitem(var dest: realarty; index: integer); overload; +procedure deleteitem(var dest: complexarty; index: integer); overload; +procedure deleteitem(var dest: pointerarty; index: integer); overload; +procedure deleteitem(var dest: winidarty; index: integer); overload; +procedure insertitem(var dest: integerarty; index: integer; + value: integer); overload; +procedure insertitem(var dest: int64arty; index: integer; + value: int64); overload; +procedure insertitem(var dest: booleanarty; index: integer; + value: boolean); overload; +procedure insertitem(var dest: longwordarty; index: integer; + value: longword); overload; +procedure insertitem(var dest: realarty; index: integer; + value: realty); overload; +procedure insertitem(var dest: complexarty; index: integer; + value: complexty); overload; +procedure insertitem(var dest: pointerarty; index: integer; + value: pointer); overload; +procedure insertitem(var dest: winidarty; index: integer; value: winidty); overload; +procedure insertitem(var dest: stringarty; index: integer; value: string); overload; +procedure insertitem(var dest: msestringarty; index: integer; value: msestring); overload; + +procedure removeitems(var dest: pointerarty; const aitem: pointer); + //removes all matching items +function removeitem(var dest: pointerarty; const aitem: pointer): integer; + overload; + //returns removed index, -1 if none + +function finditem(const ar: pointerarty; const aitem: pointer): integer; + overload; + //-1 if none + +procedure moveitem(var dest; const sourceindex: integer; + destindex: integer; const itemsize: integer); overload; +procedure moveitem(var dest: pointerarty; const sourceindex: integer; + destindex: integer); overload; + +function removeitem(var dest: stringarty; const aitem: string): integer; + overload; + //returns removed index, -1 if none +function finditem(const ar: stringarty; const aitem: string): integer; + overload; + //-1 if none +procedure moveitem(var dest: stringarty; const sourceindex: integer; + destindex: integer); overload; + +function removeitem(var dest: msestringarty; const aitem: msestring): integer; + overload; + //returns removed index, -1 if none +function finditem(const ar: msestringarty; const aitem: msestring): integer; + overload; + //-1 if none +procedure moveitem(var dest: msestringarty; const sourceindex: integer; + destindex: integer); overload; + + +function removeitem(var dest: integerarty; const aitem: integer): integer; + overload; + //returns removed index, -1 if none +function finditem(const ar: integerarty; const aitem: integer): integer; + overload; //-1 if none +procedure moveitem(var dest: integerarty; const sourceindex: integer; + destindex: integer); overload; + +function adduniqueitem(var dest: pointerarty; const value: pointer): integer; + //returns index +function addnewitem(var dest: pointerarty; const value: pointer): integer; + //returns index, -1 if already existing + +function isequalarray(const a: integerarty; const b: integerarty): boolean; + +procedure minmax(const ar: realarty; out minval,maxval: realty); + +function stackarfunc(const ar1,ar2: integerarty): integerarty; +procedure stackarray(const source: stringarty; var dest: stringarty); overload; +procedure stackarray(const source: msestringarty; var dest: msestringarty); overload; +procedure stackarray(const source: integerarty; var dest: integerarty); overload; +procedure stackarray(const source: longwordarty; var dest: longwordarty); overload; +procedure stackarray(const source: pointerarty; var dest: pointerarty); overload; +procedure stackarray(const source: winidarty; var dest: winidarty); overload; +procedure stackarray(const source: realarty; var dest: realarty); overload; +procedure insertarray(const source: integerarty; var dest: integerarty); overload; +procedure insertarray(const source: realarty; var dest: realarty); overload; +function reversearray(const source: msestringarty): msestringarty; overload; +function reversearray(const source: integerarty): integerarty; overload; +function reversearray(const source: pointerarty): pointerarty; overload; +procedure removearrayduplicates(var value: pointerarty); +function packarray(source: pointerarty): pointerarty; overload; + //remove nil items +function packarray(source: msestringarty): msestringarty; overload; + //remove '' items + +procedure checkarrayindex(const value; const index: integer); + //value = dynamic array, exception bei ungueltigem index +procedure checkarrayindexcount(const count: int32; const index: int32); + +procedure splitcomplexar(const acomplex: complexarty; out re,im: realarty); + +function comparepointer(const l,r): integer; +function compareinteger(const l,r): integer; +function compareint64(const l,r): integer; +function comparecard64(const l,r): integer; +function comparerealty(const l,r): integer; +function compareasciistring(const l,r): integer; +function compareiasciistring(const l,r): integer; +function compareansistring(const l,r): integer; +function compareiansistring(const l,r): integer; +function comparemsestring(const l,r): integer; +function compareimsestring(const l,r): integer; + +function findarrayvalue(const item; const items; const itemsize: integer; + const count: integer; const compare: arraysortcomparety; + out foundindex: integer): boolean; overload; +function findarrayvalue(const item; const items; const itemsize: integer; + const index: integerarty; const compare: arraysortcomparety; + out foundindex: integer): boolean; overload; + //true if exact else next bigger + //for compare: l is item, r are tablevalues + //array must be sorted + +procedure quicksortpointer(const adata: ppointer; //-> array of pointer + const alength: int32; const acompare: pointercomparefuncty); + //position stable + +procedure mergesortarray(var asortlist; const aitemsize,alength: integer; + const acompare: arraysortcomparety; + out aindexlist: integerarty; const order: boolean); + //asortlist = array of type +procedure mergesort(var adata: pointerarty; const acount: integer; + const compare: pointercomparemethodty); overload; + +procedure mergesort(var adata: pointer; const aitemsize,acount: integer; + const acompare: sortcomparemethodty); overload; + //reallocates adata memory +procedure mergesort(const adata: pointer; const aitemsize,acount: integer; + const acompare: sortcomparemethodty; + out aindexlist: integerarty); overload; +procedure mergesort(const adata: pointer; const asize,acount: integer; + const acompare: sortcomparemethodty; + out aindexlist: integerarty; + var refindex: integer; out moved: boolean); overload; +procedure mergesort(const acount: integer; + const acompare: indexsortcomparemethodty; + out aindexlist: integerarty); overload; +procedure mergesort(const acount: integer; + const acompare: indexsortcomparemethodty; out aindexlist: integerarty; + var refindex: integer; out moved: boolean); overload; +procedure mergesortoffset(const adata: pointer; const asize,acount: integer; + const acompare: sortcomparemethodty; + out aoffsetlist: integerarty); overload; +procedure mergesortpointer(const adata: pointer; const asize,acount: integer; + const acompare: sortcomparemethodty; + out apointerlist: pointerarty); overload; + +function findarrayitem(const item; const ar; const itemsize: integer; + const compare: arraysortcomparety; + out foundindex: integer): boolean; overload; + //ar = sorted array of type + //true if exact else next bigger + //for compare: l is item, r are tablevalues +function findarrayitem(const item; const ar: pointerarty; + const compare: sortcomparemethodty; + out foundindex: integer): boolean; overload; + //ar = sorted array of type + //true if exact else next bigger + //for compare: l is item, r are tablevalues + +procedure sortarray(var sortlist; const itemsize: integer; + const compare: arraysortcomparety); overload; + //sortlist = array of type +procedure sortarray(var sortlist; const itemsize: integer; + const compare: arraysortcomparety; + out indexlist: integerarty); overload; + //sortlist = array of type +procedure sortarray(var dest: pointerarty; const compare: arraysortcomparety); overload; +procedure sortarray(var dest: pointerarty; const compare: arraysortcomparety; + out indexlist: integerarty); overload; +procedure sortarray(var dest: pointerarty); overload; //compares adresses +procedure sortarray(var dest: integerarty); overload; +procedure sortarray(var dest: integerarty; out indexlist: integerarty); overload; +procedure sortarray(var dest: longwordarty); overload; +procedure sortarray(var dest: longwordarty; out indexlist: integerarty); overload; +procedure sortarray(var dest: realarty); overload; +procedure sortarray(var dest: realarty; out indexlist: integerarty); overload; + +procedure sortarray(var dest: msestringarty; const compare: arraysortcomparety); overload; +procedure sortarray(var dest: msestringarty; const compare: arraysortcomparety; + out indexlist: integerarty); overload; +procedure sortarray(var dest: stringarty; const compare: arraysortcomparety); overload; +procedure sortarray(var dest: stringarty; const compare: arraysortcomparety; + out indexlist: integerarty); overload; + +procedure sortarray(var dest: msestringarty; + const sortmode: stringsortmodety = sms_up); overload; +procedure sortarray(var dest: msestringarty; const sortmode: stringsortmodety; + out indexlist: integerarty); overload; +procedure sortarray(var dest: stringarty; + const sortmode: stringsortmodety = sms_upascii); overload; +procedure sortarray(var dest: stringarty; + const sortmode: stringsortmodety; out indexlist: integerarty); overload; + +procedure orderarray(const sourceorderlist: integerarty; var sortlist; size: integer); overload; + //sortlist = array of type +procedure orderarray(const sourceorderlist: integerarty; + var sortlist: pointerarty); overload; +procedure orderarray(const sourceorderlist: integerarty; + var sortlist: integerarty); overload; +procedure orderarray(const sourceorderlist: integerarty; + var sortlist: msestringarty); overload; +procedure orderarray(const sourceorderlist: integerarty; + var sortlist: msestringararty); overload; +procedure orderarray(const sourceorderlist: integerarty; + var sortlist: stringarty); overload; + +procedure reorderarray(const destorderlist: integerarty; + var sortlist; size: integer); overload; + //sortlist = array of type +procedure reorderarray(const destorderlist: integerarty; + var sortlist: pointerarty); overload; +procedure reorderarray(const destorderlist: integerarty; + var sortlist: integerarty); overload; +procedure reorderarray(const destorderlist: integerarty; + var sortlist: msestringarty); overload; +procedure reorderarray(const destorderlist: integerarty; + var sortlist: stringarty); overload; + +function cmparray(const a,b: msestringarty): boolean; + //true if equal + +function opentodynarraym(const items: array of msestring): msestringarty; +function opentodynarrays(const items: array of string): stringarty; +function opentodynarrayi(const items: array of integer): integerarty; +function opentodynarrayr(const items: array of realty): realarty; +function opentodynarraybo(const items: array of boolean): booleanarty; +function opentodynarrayby(const items: array of byte): bytearty; + +function dynarraytovararray(const avalue: int64arty): tvarrecarty; + +procedure copytore(const source: realarty; var dest: complexarty); +procedure copytoim(const source: realarty; var dest: complexarty); + +implementation +uses + rtlconsts,classes,sysutils,msereal,msesys{$ifndef FPC},classes_del{$endif}; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +procedure splitcomplexar(const acomplex: complexarty; out re,im: realarty); +var + int1: integer; +begin + re:= nil; //compiler warning + im:= nil; //compiler warning + int1:= length(acomplex); + if int1 > 0 then begin + allocuninitedarray(int1,sizeof(re[0]),re); + allocuninitedarray(int1,sizeof(im[0]),im); + for int1:= int1-1 downto 0 do begin + re[int1]:= acomplex[int1].re; + im[int1]:= acomplex[int1].im; + end; + end; +end; + +function aligntoptr(p: pointer): pointer; inline; +begin +{$ifdef FPC_REQUIRES_PROPER_ALIGNMENT} + result:= align(p,sizeof(p)); +{$else FPC_REQUIRES_PROPER_ALIGNMENT} + result:=p; +{$endif FPC_REQUIRES_PROPER_ALIGNMENT} +end; + +function DynArraySize(a: Pointer): sizeint; +{$ifdef FPC} +begin + result:= length(bytearty(a)); +end; +{$else} +asm + TEST EAX, EAX + JZ @@exit + MOV EAX, [EAX-4] +@@exit: +end; +{$endif} + +function incrementarraylength(var value: pointer; typeinfo: pdynarraytypeinfo; + increment: integer = 1): sizeint; + //returns new length +begin + result:= dynarraysize(value) + increment; + dynarraysetlength(value,typeinfo,1,@result); +end; + +function dynarrayelesize(const typinfo: pdynarraytypeinfo): sizeint; inline; +var + ti: pdynarraytypeinfo; +begin + ti:= typinfo; +{$ifdef FPC} + inc(pointer(ti),ord(pdynarraytypeinfo(ti)^.namelen)+2); + ti:= aligntoptr(ti); + result:= psizeint(ti)^; +// inc(pchar(ti),ord(ti^.namelen)); +// result:= ti^.elesize; +{$else} + inc(pchar(ti),length(ti^.name)); + result:= ti^.elsize; +{$endif} +end; + +function dynarrayhigh(const value: pointer): sizeint; inline; +begin + if value = nil then begin + result:= -1; + end + else begin + result:= (psizeint(value)-1)^; + end; +end; + +function dynarraylength(const value: pointer): sizeint; inline; +begin + if value = nil then begin + result:= 0; + end + else begin + result:= (psizeint(value)-1)^+1; + end; +end; + +function decrementarraylength(var value: pointer; const typeinfo: pdynarraytypeinfo; + decrement: integer = 1): sizeint; + //returns new length +begin + result:= dynarraysize(value) - decrement; + dynarraysetlength(value,typeinfo,1,@result); +end; + +function additem(var value; const typeinfo: pdynarraytypeinfo; + var count: integer): boolean; +var + int1: integer; +begin + result:= false; + int1:= high(pointerarty(value)) + 1; + if int1 <= count then begin + incrementarraylength(pointer(value),typeinfo,2*count+arrayminlenghtstep); +// incrementarraylength(pointer(value),typeinfo,count-int1+step); + result:= true; + end; + inc(count); +end; + +function additemindex(var value; const typeinfo: pdynarraytypeinfo; + var count: integer): integer; +var + int1: integer; +begin + int1:= high(pointerarty(value)) + 1; + if int1 <= count then begin + incrementarraylength(pointer(value),typeinfo,2*count+arrayminlenghtstep); +// incrementarraylength(pointer(value),typeinfo,count-int1+step); + end; + result:= count; + inc(count); +end; + +function additempo(var value; const typeinfo: pdynarraytypeinfo; + //typeinfo of dynarray + var count: integer): pointer; overload; + //returns adress of new item +var + int1: integer; +begin + int1:= high(pointerarty(value)) + 1; + if int1 <= count then begin + incrementarraylength(pointer(value),typeinfo,2*count+arrayminlenghtstep); + end; + result:= pointer(value) + count*dynarrayelesize(typeinfo); + inc(count); +end; + +procedure deleteitem(var value; const typeinfo: pdynarraytypeinfo; + const aindex: integer); + //value = array of type which needs no finalize +var + int1: integer; +begin + int1:= dynarrayelesize(pdynarraytypeinfo(typeinfo)); + move((pchar(value)+int1*(aindex+1))^,(pchar(value)+int1*aindex)^, + int1*(high(bytearty(value))-aindex)); + decrementarraylength(pointer(value),typeinfo); +end; + +procedure arrayaddref(var dynamicarray); +var + refpo: psizeint; +begin + if pointer(dynamicarray) <> nil then begin + refpo:= psizeint(pchar(dynamicarray)-2*sizeof(sizeint)); + if refpo^ >= 0 then begin + {$ifdef CPU64} + interlockedincrement64(refpo^); + {$else} + interlockedincrement(refpo^); + {$endif} + end; + end; +end; + +function arrayrefcount(var dynamicarray): sizeint; +begin + result:= 0; + if pointer(dynamicarray) <> nil then begin + result:= psizeint(pchar(dynamicarray)-2*sizeof(sizeint))^; + end; +end; + +function arrayminhigh(arrays: array of pointer): integer; + //array of dynamicarray +var + int1,int2: integer; +begin + result:= bigint; + for int1:= 0 to high(arrays) do begin + int2:= high(pointerarty(arrays[int1])); + if int1 < result then begin + result:= int2; + end; + end; + if result = bigint then begin + result:= -1; + end; +end; + +procedure arraydecref(var dynamicarray); +var + refpo: psizeint; +begin + if pointer(dynamicarray) <> nil then begin + refpo:= psizeint(pchar(dynamicarray)-2*sizeof(sizeint)); + if refpo^ > 0 then begin + {$ifdef CPU64} + interlockeddecrement64(refpo^); + {$else} + interlockeddecrement(refpo^); + {$endif} + end; + end; +end; + +procedure allocuninitedarray(count,itemsize: integer; out dynamicarray); + //does not init memory, dynamicarray must be nil! +var + po1: psizeint; +begin +{$warnings off} + if pointer(dynamicarray) <> nil then begin + raise exception.Create('allocunitedarray: dynamicarray not nil'); + end; + if count > 0 then begin + getmem(po1,count * itemsize + 2 * sizeof(sizeint)); + po1^:= 1; //refcount + {$ifdef FPC} + psizeint(pchar(po1)+sizeof(sizeint))^:= count - 1; //high + {$else} + psizeint(pchar(po1)+sizeof(sizeint))^:= count; //count + {$endif} + pointer(dynamicarray):= pointer(pchar(po1) + 2 * sizeof(sizeint)); + end; +end; +{$warnings on} + +procedure reallocuninitedarray(count,itemsize: integer; var dynamicarray); + //does not init memory, dynamicarray must be unique +var + po1: psizeint; +begin + po1:= pointer(dynamicarray); + if po1 <> nil then begin + po1:= pointer(pchar(po1) - 2 * sizeof(sizeint)); + if po1^ <> 1 then begin + raise exception.Create('reallocunitedarray: dynamicarray not unique'); + end; + end + else begin + allocuninitedarray(count,itemsize,dynamicarray); + exit; + end; + if count = 0 then begin + freemem(po1); + pointer(dynamicarray):= nil; + end + else begin + reallocmem(po1,count * itemsize + 2 * sizeof(sizeint)); + {$ifdef FPC} + psizeint(pchar(po1)+sizeof(sizeint))^:= count - 1; //high + {$else} + psizeint(pchar(po1)+sizeof(sizeint))^:= count; //count + {$endif} + pointer(dynamicarray):= pointer(pchar(po1) + 2 * sizeof(sizeint)); + end; +end; + +procedure freeuninitedarray(var dynamicarray); + //does not finalize items, dynamicarray must be unique! +var + po1: psizeint; +begin + po1:= pointer(dynamicarray); + if po1 <> nil then begin + po1:= pointer(pchar(po1) - 2 * sizeof(sizeint)); + if po1^ <> 1 then begin + raise exception.Create('reallocunitedarray: dynamicarray not unique'); + end; + freemem(po1); + pointer(dynamicarray):= nil; + end; +end; + +function firstitem(const source: stringarty): string; overload; +begin + if length(source) > 0 then begin + result:= source[0]; + end + else begin + result:= ''; + end; +end; + +function firstitem(const source: msestringarty): msestring; overload; +begin + if length(source) > 0 then begin + result:= source[0]; + end + else begin + result:= ''; + end; +end; + +function additem(var dest: stringarty; const value: string; + var count: integer): boolean; +begin + result:= false; + if length(dest) <= count then begin + setlength(dest,count+arrayminlenghtstep+2*length(dest)); + result:= true; + end; + dest[count]:= value; + inc(count); +end; + +function additem(var dest: stringararty; const value: stringarty; + var count: integer): boolean; overload; +begin + result:= false; + if length(dest) <= count then begin + setlength(dest,count+arrayminlenghtstep+2*length(dest)); + result:= true; + end; + dest[count]:= value; + inc(count); +end; + +function additem(var dest: msestringarty; const value: msestring; + var count: integer): boolean; +begin + result:= false; + if length(dest) <= count then begin + setlength(dest,count+arrayminlenghtstep+2*length(dest)); + result:= true; + end; + dest[count]:= value; + inc(count); +end; + +function additem(var dest: msestringararty; const value: msestringarty; + var count: integer): boolean; +begin + result:= false; + if length(dest) <= count then begin + setlength(dest,count+arrayminlenghtstep+2*length(dest)); + result:= true; + end; + dest[count]:= value; + inc(count); +end; + +function additem(var dest: lstringarty; const value: lstringty; + var count: integer): boolean; +begin + result:= false; + if length(dest) <= count then begin + setlength(dest,count+arrayminlenghtstep+2*length(dest)); + result:= true; + end; + dest[count]:= value; + inc(count); +end; + +function additem(var dest: lmsestringarty; const value: lmsestringty; + var count: integer): boolean; +begin + result:= false; + if length(dest) <= count then begin + setlength(dest,count+arrayminlenghtstep+2*length(dest)); + result:= true; + end; + dest[count]:= value; + inc(count); +end; +function additem(var dest: int16arty; const value: int16; + var count: integer): boolean; overload; +begin + result:= false; + if length(dest) <= count then begin + setlength(dest,count+arrayminlenghtstep+2*length(dest)); + result:= true; + end; + dest[count]:= value; + inc(count); +end; + +function additem(var dest: integerarty; const value: integer; + var count: integer): boolean; +begin + result:= false; + if length(dest) <= count then begin + setlength(dest,count+arrayminlenghtstep+2*length(dest)); + result:= true; + end; + dest[count]:= value; + inc(count); +end; + +function additem(var dest: longwordarty; const value: longword; + var count: integer): boolean; +begin + result:= false; + if length(dest) <= count then begin + setlength(dest,count+arrayminlenghtstep+2*length(dest)); + result:= true; + end; + dest[count]:= value; + inc(count); +end; + +function additem(var dest: realarty; const value: real; + var count: integer): boolean; +begin + result:= false; + if length(dest) <= count then begin + setlength(dest,count+arrayminlenghtstep+2*length(dest)); + result:= true; + end; + dest[count]:= value; + inc(count); +end; + +function additem(var dest: pointerarty; const value: pointer; + var count: integer): boolean; +begin + result:= false; + if length(dest) <= count then begin + setlength(dest,count+arrayminlenghtstep+2*length(dest)); + result:= true; + end; + dest[count]:= value; + inc(count); +end; + +{$ifndef FPC} +function addpointeritem(var dest: pointerarty; const value: pointer; + var count: integer): boolean; +begin + result:= false; + if length(dest) <= count then begin + setlength(dest,count+step+2*length(dest)); + result:= true; + end; + dest[count]:= value; + inc(count); +end; +{$endif} + +function additem(var dest: winidarty; const value: winidty; + var count: integer): boolean; +begin + result:= false; + if length(dest) <= count then begin + setlength(dest,count+arrayminlenghtstep+2*length(dest)); + result:= true; + end; + dest[count]:= value; + inc(count); +end; + +procedure additem(var dest: stringarty; const value: string); +begin + setlength(dest,high(dest)+2); + dest[high(dest)]:= value; +end; + +procedure additem(var dest: msestringarty; const value: msestring); +begin + setlength(dest,high(dest)+2); + dest[high(dest)]:= value; +end; + +procedure additem(var dest: doublemsestringarty; + const valuea,valueb: msestring); +begin + setlength(dest,high(dest)+2); + with dest[high(dest)] do begin + a:= valuea; + b:= valueb; + end; +end; + +procedure additem(var dest: msestringararty; + const value: msestringarty); overload; +begin + setlength(dest,high(dest)+2); + dest[high(dest)]:= value; +end; + +procedure additem(var dest: int16arty; const value: int16); +begin + setlength(dest,high(dest)+2); + dest[high(dest)]:= value; +end; + +procedure additem(var dest: integerarty; const value: integer); +begin + setlength(dest,high(dest)+2); + dest[high(dest)]:= value; +end; + +procedure additem(var dest: int64arty; const value: int64); +begin + setlength(dest,high(dest)+2); + dest[high(dest)]:= value; +end; + +procedure additem(var dest: card64arty; const value: card64); +begin + setlength(dest,high(dest)+2); + dest[high(dest)]:= value; +end; + +procedure additem(var dest: longwordarty; const value: longword); +begin + setlength(dest,high(dest)+2); + dest[high(dest)]:= value; +end; + +procedure additem(var dest: longboolarty; const value: longbool); +begin + setlength(dest,high(dest)+2); + dest[high(dest)]:= value; +end; + +procedure additem(var dest: booleanarty; const value: boolean); +begin + setlength(dest,high(dest)+2); + dest[high(dest)]:= value; +end; + +procedure additem(var dest: realarty; const value: real); +begin + setlength(dest,high(dest)+2); + dest[high(dest)]:= value; +end; + +procedure additem(var dest: pointerarty; const value: pointer); +begin + setlength(dest,high(dest)+2); + dest[high(dest)]:= value; +end; + +procedure additem(var dest: winidarty; const value: winidty); +begin + setlength(dest,high(dest)+2); + dest[high(dest)]:= value; +end; + +procedure deleteitem(var dest: stringarty; index: integer); +begin + if (index < 0) or (index > high(dest)) then begin + tlist.Error(SListIndexError, Index); + end; + dest[index]:= ''; + move(dest[index+1],dest[index],sizeof(dest[0])*(high(dest)-index)); + pointer(dest[high(dest)]):= nil; + setlength(dest,high(dest)); +end; + +procedure deleteitem(var dest: msestringarty; index: integer); +begin + if (index < 0) or (index > high(dest)) then begin + tlist.Error(SListIndexError, Index); + end; + dest[index]:= ''; + move(dest[index+1],dest[index],sizeof(dest[0])*(high(dest)-index)); + pointer(dest[high(dest)]):= nil; + setlength(dest,high(dest)); +end; + +procedure deleteitem(var dest: integerarty; index: integer); +begin + if (index < 0) or (index > high(dest)) then begin + tlist.Error(SListIndexError, Index); + end; + move(dest[index+1],dest[index],sizeof(dest[0])*(high(dest)-index)); + setlength(dest,high(dest)); +end; + +procedure deleteitem(var dest: int64arty; index: integer); +begin + if (index < 0) or (index > high(dest)) then begin + tlist.Error(SListIndexError, Index); + end; + move(dest[index+1],dest[index],sizeof(dest[0])*(high(dest)-index)); + setlength(dest,high(dest)); +end; + +procedure deleteitem(var dest: card64arty; index: integer); +begin + if (index < 0) or (index > high(dest)) then begin + tlist.Error(SListIndexError, Index); + end; + move(dest[index+1],dest[index],sizeof(dest[0])*(high(dest)-index)); + setlength(dest,high(dest)); +end; + +procedure deleteitem(var dest: booleanarty; index: integer); +begin + if (index < 0) or (index > high(dest)) then begin + tlist.Error(SListIndexError, Index); + end; + move(dest[index+1],dest[index],sizeof(dest[0])*(high(dest)-index)); + setlength(dest,high(dest)); +end; + +procedure deleteitem(var dest: realarty; index: integer); +begin + if (index < 0) or (index > high(dest)) then begin + tlist.Error(SListIndexError, Index); + end; + move(dest[index+1],dest[index],sizeof(dest[0])*(high(dest)-index)); + setlength(dest,high(dest)); +end; + +procedure deleteitem(var dest: complexarty; index: integer); +begin + if (index < 0) or (index > high(dest)) then begin + tlist.Error(SListIndexError, Index); + end; + move(dest[index+1],dest[index],sizeof(dest[0])*(high(dest)-index)); + setlength(dest,high(dest)); +end; + +procedure deleteitem(var dest: pointerarty; index: integer); +begin + if (index < 0) or (index > high(dest)) then begin + tlist.Error(SListIndexError, Index); + end; + move(dest[index+1],dest[index],sizeof(dest[0])*(high(dest)-index)); + setlength(dest,high(dest)); +end; + +procedure deleteitem(var dest: winidarty; index: integer); +begin + if (index < 0) or (index > high(dest)) then begin + tlist.Error(SListIndexError, Index); + end; + move(dest[index+1],dest[index],sizeof(dest[0])*(high(dest)-index)); + setlength(dest,high(dest)); +end; + +procedure insertitem(var dest: integerarty; index: integer; value: integer); +begin + setlength(dest,high(dest) + 2); + move(dest[index],dest[index+1],(high(dest)-index) * sizeof(dest[0])); + dest[index]:= value; +end; + +procedure insertitem(var dest: int64arty; index: integer; value: int64); +begin + setlength(dest,high(dest) + 2); + move(dest[index],dest[index+1],(high(dest)-index) * sizeof(dest[0])); + dest[index]:= value; +end; + +procedure insertitem(var dest: booleanarty; index: integer; + value: boolean); +begin + setlength(dest,high(dest) + 2); + move(dest[index],dest[index+1],(high(dest)-index) * sizeof(dest[0])); + dest[index]:= value; +end; + +procedure insertitem(var dest: longwordarty; index: integer; value: longword); +begin + setlength(dest,high(dest) + 2); + move(dest[index],dest[index+1],(high(dest)-index) * sizeof(dest[0])); + dest[index]:= value; +end; + +procedure insertitem(var dest: realarty; index: integer; value: realty); +begin + setlength(dest,high(dest) + 2); + move(dest[index],dest[index+1],(high(dest)-index) * sizeof(dest[0])); + dest[index]:= value; +end; + +procedure insertitem(var dest: complexarty; index: integer; value: complexty); +begin + setlength(dest,high(dest) + 2); + move(dest[index],dest[index+1],(high(dest)-index) * sizeof(dest[0])); + dest[index]:= value; +end; + +procedure insertitem(var dest: pointerarty; index: integer; value: pointer); +begin + setlength(dest,high(dest) + 2); + move(dest[index],dest[index+1],(high(dest)-index) * sizeof(dest[0])); + dest[index]:= value; +end; + +procedure insertitem(var dest: winidarty; index: integer; value: winidty); +begin + setlength(dest,high(dest) + 2); + move(dest[index],dest[index+1],(high(dest)-index) * sizeof(dest[0])); + dest[index]:= value; +end; + +procedure insertitem(var dest: stringarty; index: integer; value: string); +begin + setlength(dest,high(dest) + 2); + move(dest[index],dest[index+1],(high(dest)-index) * sizeof(dest[0])); + pointer(dest[index]):= nil; + dest[index]:= value; +end; + +procedure insertitem(var dest: msestringarty; index: integer; value: msestring); +begin + setlength(dest,high(dest) + 2); + move(dest[index],dest[index+1],(high(dest)-index) * sizeof(dest[0])); + pointer(dest[index]):= nil; + dest[index]:= value; +end; + +procedure removeitems(var dest: pointerarty; const aitem: pointer); + //removes all matching items +var + int1,int2: integer; + ar1: pointerarty; +begin + setlength(ar1,length(dest)); + int2:= 0; + for int1:= 0 to high(dest) do begin + if dest[int1] <> aitem then begin + ar1[int2]:= dest[int1]; + inc(int2); + end; + end; + setlength(ar1,int2); + dest:= ar1; +end; + +function removeitem(var dest: pointerarty; const aitem: pointer): integer; +var + int1: integer; +begin + result:= -1; + for int1:= 0 to high(dest) do begin + if dest[int1] = aitem then begin + result:= int1; + deleteitem(dest,int1); + break; + end; + end; +end; + +function isequalarray(const a: integerarty; const b: integerarty): boolean; +var + int1: integer; + po1,po2: pintegeraty; +begin + result:= pointer(a) = pointer(b); + if not result and (high(a) = high(b)) then begin + po1:= pointer(a); + po2:= pointer(b); + for int1:= high(a) downto 0 do begin + if po1^[int1] <> po2^[int1] then begin + exit; + end; + end; + result:= true; + end; +end; + +function finditem(const ar: pointerarty; const aitem: pointer): integer; + //-1 if none +var + int1: integer; +begin + result:= -1; + for int1:= 0 to high(ar) do begin + if ar[int1] = aitem then begin + result:= int1; + break; + end; + end; +end; + +procedure moveitem(var dest; const sourceindex: integer; + destindex: integer; const itemsize: integer); overload; +var + po1: pchar; +begin + if (pointer(dest) <> nil) and (destindex <> sourceindex) then begin + getmem(po1,itemsize); + move((pchar(dest)+sourceindex*itemsize)^,po1^,itemsize); + if destindex < sourceindex then begin + move((pchar(dest)+destindex*itemsize)^, + (pchar(dest)+(destindex+1)*itemsize)^, + (sourceindex-destindex)*itemsize); + end + else begin + move((pchar(dest)+(sourceindex+1)*itemsize)^, + (pchar(dest)+sourceindex*itemsize)^, + (destindex-sourceindex)*itemsize); + end; + move(po1^,(pchar(dest)+destindex*itemsize)^,itemsize); + freemem(po1); + end; +end; + +procedure moveitem(var dest: pointerarty; const sourceindex: integer; + destindex: integer); +var + po1: pointer; +begin + po1:= dest[sourceindex]; + deleteitem(dest,sourceindex); + insertitem(dest,destindex,po1); +end; + + +function removeitem(var dest: stringarty; const aitem: string): integer; +var + int1: integer; +begin + result:= -1; + for int1:= 0 to high(dest) do begin + if dest[int1] = aitem then begin + result:= int1; + deleteitem(dest,int1); + break; + end; + end; +end; + +function finditem(const ar: stringarty; const aitem: string): integer; + //-1 if none +var + int1: integer; +begin + result:= -1; + for int1:= 0 to high(ar) do begin + if ar[int1] = aitem then begin + result:= int1; + break; + end; + end; +end; + +procedure moveitem(var dest: stringarty; const sourceindex: integer; + destindex: integer); +var + po1: string; +begin + po1:= dest[sourceindex]; + deleteitem(dest,sourceindex); + insertitem(dest,destindex,po1); +end; + +function removeitem(var dest: msestringarty; const aitem: msestring): integer; +var + int1: integer; +begin + result:= -1; + for int1:= 0 to high(dest) do begin + if dest[int1] = aitem then begin + result:= int1; + deleteitem(dest,int1); + break; + end; + end; +end; + +function finditem(const ar: msestringarty; const aitem: msestring): integer; + //-1 if none +var + int1: integer; +begin + result:= -1; + for int1:= 0 to high(ar) do begin + if ar[int1] = aitem then begin + result:= int1; + break; + end; + end; +end; + +procedure moveitem(var dest: msestringarty; const sourceindex: integer; + destindex: integer); +var + po1: msestring; +begin + po1:= dest[sourceindex]; + deleteitem(dest,sourceindex); + insertitem(dest,destindex,po1); +end; + +function removeitem(var dest: integerarty; const aitem: integer): integer; +var + int1: integer; +begin + result:= -1; + for int1:= 0 to high(dest) do begin + if dest[int1] = aitem then begin + result:= int1; + deleteitem(dest,int1); + break; + end; + end; +end; + +function finditem(const ar: integerarty; const aitem: integer): integer; + //-1 if none +var + int1: integer; +begin + result:= -1; + for int1:= 0 to high(ar) do begin + if ar[int1] = aitem then begin + result:= int1; + break; + end; + end; +end; + +procedure moveitem(var dest: integerarty; const sourceindex: integer; + destindex: integer); +var + int1: integer; +begin + int1:= dest[sourceindex]; + deleteitem(dest,sourceindex); + insertitem(dest,destindex,int1); +end; + +function adduniqueitem(var dest: pointerarty; const value: pointer): integer; + //returns index +var + int1: integer; +begin + for int1:= 0 to high(dest) do begin + if dest[int1] = value then begin + result:= int1; + exit; + end; + end; + result:= high(dest) + 1; + setlength(dest,result+1); + dest[result]:= value; +end; + +function addnewitem(var dest: pointerarty; const value: pointer): integer; + //returns index +var + int1: integer; +begin + for int1:= 0 to high(dest) do begin + if dest[int1] = value then begin + result:= -1; + exit; + end; + end; + result:= high(dest) + 1; + setlength(dest,result+1); + dest[result]:= value; +end; + +procedure minmax(const ar: realarty; out minval,maxval: realty); +var + int1: integer; + min1,max1: realty; +begin + min1:= bigreal; + max1:= emptyreal; + for int1:= high(ar) downto 0 do begin + if ar[int1] = emptyreal then begin + min1:= ar[int1]; + end + else begin + if (max1 = emptyreal) or (ar[int1] > max1) then begin + max1:= ar[int1]; + end; + if not (min1 = emptyreal) and (min1 > ar[int1]) then begin + min1:= ar[int1]; + end; + end; + end; + minval:= min1; + maxval:= max1; +end; + +function stackarfunc(const ar1,ar2: integerarty): integerarty; +begin + setlength(result,length(ar1) + length(ar2)); + move(ar1[0],result[0],length(ar1)*sizeof(ar1[0])); + move(ar2[0],result[length(ar1)],length(ar2)*sizeof(ar2[0])); +end; + +procedure stackarray(const source: stringarty; var dest: stringarty); +var + laengevorher: integer; + int1: integer; +begin + laengevorher:= length(dest); + setlength(dest,laengevorher+length(source)); + for int1:= 0 to high(source) do begin + dest[laengevorher]:= source[int1]; + inc(laengevorher); + end; +end; + +procedure stackarray(const source: msestringarty; var dest: msestringarty); +var + laengevorher: integer; + int1: integer; +begin + laengevorher:= length(dest); + setlength(dest,laengevorher+length(source)); + for int1:= 0 to high(source) do begin + dest[laengevorher]:= source[int1]; + inc(laengevorher); + end; +end; + +procedure stackarray(const source: integerarty; var dest: integerarty); +var + laengevorher: integer; +begin + laengevorher:= length(dest); + setlength(dest,laengevorher+length(source)); + move(source[0],dest[laengevorher],length(source)*sizeof(source[0])); +end; + +procedure stackarray(const source: longwordarty; var dest: longwordarty); +var + laengevorher: integer; +begin + laengevorher:= length(dest); + setlength(dest,laengevorher+length(source)); + move(source[0],dest[laengevorher],length(source)*sizeof(source[0])); +end; + +procedure stackarray(const source: pointerarty; var dest: pointerarty); +var + laengevorher: integer; +begin + laengevorher:= length(dest); + setlength(dest,laengevorher+length(source)); + move(source[0],dest[laengevorher],length(source)*sizeof(source[0])); +end; + +procedure stackarray(const source: winidarty; var dest: winidarty); +var + laengevorher: integer; +begin + laengevorher:= length(dest); + setlength(dest,laengevorher+length(source)); + move(source[0],dest[laengevorher],length(source)*sizeof(source[0])); +end; + +procedure insertarray(const source: integerarty; var dest: integerarty); +var + laengevorher: integer; +begin + laengevorher:= length(dest); + setlength(dest,laengevorher+length(source)); + move(dest[0],dest[length(source)],laengevorher*sizeof(dest[0])); + move(source[0],dest[0],length(source)*sizeof(source[0])); +end; + +procedure stackarray(const source: realarty; var dest: realarty); +var + laengevorher: integer; +begin + laengevorher:= length(dest); + setlength(dest,laengevorher+length(source)); + move(source[0],dest[laengevorher],length(source)*sizeof(source[0])); +end; + +procedure insertarray(const source: realarty; var dest: realarty); +var + laengevorher: integer; +begin + laengevorher:= length(dest); + setlength(dest,laengevorher+length(source)); + move(dest[0],dest[length(source)],laengevorher*sizeof(dest[0])); + move(source[0],dest[0],length(source)*sizeof(source[0])); +end; + +function reversearray(const source: msestringarty): msestringarty; +var + ar1: msestringarty; + int1,int2: integer; +begin +{$warnings off} + if pointer(source) = pointer(result) then begin + ar1:= copy(source); + end + else begin + ar1:= source; + end; + int2:= high(ar1); + setlength(result,int2+1); + for int1:= 0 to int2 do begin + result[int1]:= ar1[int2]; + dec(int2); + end; +end; +{$warnings on} + +function reversearray(const source: integerarty): integerarty; overload; +var + ar1: integerarty; + int1,int2: integer; +begin +{$warnings off} + if pointer(source) = pointer(result) then begin + ar1:= copy(source); + end + else begin + ar1:= source; + end; + int2:= high(ar1); + setlength(result,int2+1); + for int1:= 0 to int2 do begin + result[int1]:= ar1[int2]; + dec(int2); + end; +end; +{$warnings on} + +function reversearray(const source: pointerarty): pointerarty; overload; +var + ar1: pointerarty; + int1,int2: integer; +begin +{$warnings off} + if pointer(source) = pointer(result) then begin + ar1:= copy(source); + end + else begin + ar1:= source; + end; + int2:= high(ar1); + setlength(result,int2+1); + for int1:= 0 to int2 do begin + result[int1]:= ar1[int2]; + dec(int2); + end; +end; +{$warnings on} + +procedure removearrayduplicates(var value: pointerarty); +var + int1,int2: integer; +begin + for int1:= 0 to high(value) do begin //remove duplicates + if value[int1] <> nil then begin + for int2:= int1 + 1 to high(value) do begin + if value[int2] = value[int1] then begin + value[int2]:= nil + end; + end; + end; + end; + int2:= 0; + for int1:= 0 to high(value) do begin + if value[int1] <> nil then begin + value[int2]:= value[int1]; + inc(int2); + end; + end; + setlength(value,int2); +end; + +function packarray(source: pointerarty): pointerarty; //removes nil items +var + int1,int2: integer; +begin + setlength(result,length(source)); + int2:= 0; + for int1:= 0 to high(source) do begin + result[int2]:= source[int1]; + if source[int1] <> nil then begin + inc(int2); + end; + end; + setlength(result,int2); +end; + +function packarray(source: msestringarty): msestringarty; +var + int1,int2: integer; +begin + setlength(result,length(source)); + int2:= 0; + for int1:= 0 to high(source) do begin + result[int2]:= source[int1]; + if source[int1] <> '' then begin + inc(int2); + end; + end; + setlength(result,int2); +end; + +procedure checkarrayindex(const value; const index: integer); + //value = dynamic array, exception bei ungueltigem index +begin + if (index < 0) or (index > high(bytearty(value))) then begin + raise exception.Create('Invalid arrayindex: '+inttostr(index)+ ' max: ' + + inttostr(high(bytearty(value)))+'.'); + end; +end; + +procedure checkarrayindexcount(const count: int32; const index: int32); +begin + if (index < 0) or (index >= count) then begin + raise exception.Create('Invalid arrayindex: '+inttostr(index)+ ' max: ' + + inttostr(count-1)+'.'); + end; +end; + +type + sortinfoty = record + indexlist: integerarty; + sortlist: pchar; + compare: arraysortcomparety; + size: integer; + end; + +function findarrayvalue(const item; const items; + const itemsize: integer; const count: integer; + const compare: arraysortcomparety; + out foundindex: integer): boolean; + //true if exact else next bigger + //for compare: l is item, r are tablevalues +var + ilo,ihi:integer; + int1,int2: integer; +// bo1: boolean; +begin + foundindex:= count; + result:= false; + if foundindex > 0 then begin + ilo:= 0; + ihi:= foundindex - 1; +// bo1:= false; + while true do begin + int1:= (ilo + ihi) div 2; + int2:= compare(item,(pchar(items)+int1*itemsize)^); + if int2 >= 0 then begin //item <= pivot + if int2 = 0 then begin + result:= true; //found + end; + if ihi = ilo then begin + foundindex:= ihi + 1; + break; + end; + if ilo = int1 then begin + inc(ilo); + end + else begin + ilo:= int1; + end; + end + else begin //item > pivot + if ihi = ilo then begin + foundindex:= ihi; + break; + end; + ihi:= int1; + end; + end; + if result then begin + dec(foundindex); + end; + end; +end; + +function findarrayitem(const item; const ar; const itemsize: integer; + const compare: arraysortcomparety; + out foundindex: integer): boolean; + //ar = array of type + //true if exact else next bigger + //for compare: l is item, r are tablevalues +begin + result:= findarrayvalue(item,ar,itemsize,length(pointerarty(ar)), + compare,foundindex); +end; + +function findarrayvalue(const item; const items; const itemsize: integer; + const index: integerarty; + const compare: arraysortcomparety; + out foundindex: integer): boolean; + //true if exact else next bigger + //for compare: l is item, r are tablevalues +var + ilo,ihi:integer; + int1,int2: integer; +// bo1: boolean; +begin + foundindex:= length(index); + result:= false; + if foundindex > 0 then begin + ilo:= 0; + ihi:= foundindex - 1; +// bo1:= false; + while true do begin + int1:= (ilo + ihi) div 2; + int2:= compare(item,(pchar(items)+index[int1]*itemsize)^); + if int2 >= 0 then begin //item <= pivot + if int2 = 0 then begin + result:= true; //found + end; + if ihi = ilo then begin + foundindex:= ihi + 1; + break; + end; + if ilo = int1 then begin + inc(ilo); + end + else begin + ilo:= int1; + end; + end + else begin //item > pivot + if ihi = ilo then begin + foundindex:= ihi; + break; + end; + ihi:= int1; + end; + end; + if result then begin + dec(foundindex); + end; + end; +end; + +function findarrayitem(const item; const ar: pointerarty; + const compare: sortcomparemethodty; + out foundindex: integer): boolean; overload; + //ar = sorted array of type + //true if exact else next bigger + //for compare: l is item, r are tablevalues +var + ilo,ihi:integer; + int1,int2: integer; +// bo1: boolean; +begin + foundindex:= length(ar); + result:= false; + if foundindex > 0 then begin + ilo:= 0; + ihi:= foundindex - 1; +// bo1:= false; + while true do begin + int1:= (ilo + ihi) div 2; + int2:= compare(item,ar[int1]^); + if int2 >= 0 then begin //item <= pivot + if int2 = 0 then begin + result:= true; //found + end; + if ihi = ilo then begin + foundindex:= ihi + 1; + break; + end; + if ilo = int1 then begin + inc(ilo); + end + else begin + ilo:= int1; + end; + end + else begin //item > pivot + if ihi = ilo then begin + foundindex:= ihi; + break; + end; + ihi:= int1; + end; + end; + if result then begin + dec(foundindex); + end; + end; +end; + +function comparepointer(const l,r): integer; +var + pint1: ptrint; +begin + result:= 1; + pint1:= ptrint(l) - ptrint(r); + if pint1 < 0 then begin + result:= -1 + end + else begin + if pint1 = 0 then begin + result:= 0; + end; + end; +end; + +function compareinteger(const l,r): integer; +begin + result:= integer(l) - integer(r); +end; + +function compareint64(const l,r): integer; +begin + result:= int64(l) - int64(r); +end; + +function comparecard64(const l,r): integer; +begin + result:= card64(l) - card64(r); +end; + +procedure doquicksortpointer(const compare: pointercomparefuncty; + l, r: ppointer); +var + poi, poj: ppointer; + pop: ppointer; + po1: ppointer; + int1: integer; +begin + repeat + poi := l; + poj := r; + pop := pointer((ptruint(l) div 2 + ptruint(r) div 2) and pointeralignmask); + //pivot element + repeat + while true do begin + int1:= compare(poi^,pop^); + if int1 = 0 then begin + int1:= poi-pop; + end; + if int1 >= 0 then break; + inc(poi); + end; + while true do begin + int1:= compare(poj^,pop^); + if int1 = 0 then begin + int1:= poj-pop; + end; + if int1 <= 0 then break; + dec(poj); + end; + if poi <= poj then begin + po1:= poi^; //swap elementm + poi^:= poj^; + poj^:= po1; + if pop = poi then begin + pop:= poj + end + else begin + if pop = poj then begin + pop:= poi; + end; + end; + inc(poi); + dec(poj); + end; + until poi > poj; + if l < poj then begin + doquicksortpointer(compare,l, poj); + end; + l:= poi; + until poi >= r; +end; + +procedure quicksortpointer(const adata: ppointer; const alength: int32; + const acompare: pointercomparefuncty); +begin + if alength > 1 then begin + doquicksortpointer(acompare,adata,adata+alength-1); + end; +end; + +procedure mergesortarray(var asortlist; const aitemsize,alength: integer; + const acompare: arraysortcomparety; + out aindexlist: integerarty; const order: boolean); + //asortlist = array of type + //todo: optimize +var + ar1: integerarty; + step: integer; + l,r,d: pinteger; + stopl,stopr,stops: pinteger; + source,dest: pinteger; + int1: integer; + po1: pchar; +label + endstep; +begin + aindexlist:= nil; + if alength = 0 then begin + exit; + end; + po1:= pointer(asortlist); + allocuninitedarray(alength,sizeof(integer),ar1); + allocuninitedarray(alength,sizeof(integer),aindexlist); + for int1:= alength-1 downto 0 do begin + aindexlist[int1]:= int1; + end; + source:= pointer(aindexlist); + dest:= pointer(ar1); + step:= 1; + while step < alength do begin + d:= dest; + l:= source; + {$ifdef FPC} + r:= source+step; + {$else} + r:= pointer(pchar(source)+step*sizeof(source^)); + {$endif} + stopl:= r; + {$ifdef FPC} + stopr:= r+step; + {$else} + stopr:= pointer(pchar(r)+step*sizeof(r^)); + {$endif} + {$ifdef FPC} + stops:= source + alength; + {$else} + stops:= pointer(pchar(source) + alength*sizeof(source^)); + {$endif} + if pchar(stopr) > pchar(stops) then begin + stopr:= stops; + end; + while true do begin //runs + while true do begin //steps + while acompare((po1+l^*aitemsize)^,(po1+r^*aitemsize)^) <= 0 do begin + //merge from left + d^:= l^; + inc(l); + inc(d); + if l = stopl then begin + while r <> stopr do begin + d^:= r^; //copy rest + inc(d); + inc(r); + end; + goto endstep; + end; + end; + while acompare((po1+l^*aitemsize)^,(po1+r^*aitemsize)^) > 0 do begin + //merge from right; + d^:= r^; + inc(r); + inc(d); + if r = stopr then begin + while l <> stopl do begin + d^:= l^; //copy rest + inc(d); + inc(l); + end; + goto endstep; + end; + end; + end; +endstep: + if stopr = stops then begin + break; //run finished + end; + l:= stopr; //next step + {$ifdef FPC} + r:= l + step; + {$else} + r:= pointer(pchar(l) + step*sizeof(l^)); + {$endif} + if pchar(r) >= pchar(stops) then begin + {$ifdef FPC} + r:= stops-1; + {$else} + r:= pointer(pchar(stops)-1*sizeof(stops^)); + {$endif} + end; + if r = l then begin + d^:= l^; + break; + end; + stopl:= r; + {$ifdef FPC} + stopr:= r + step; + {$else} + stopr:= pointer(pchar(r) + step*sizeof(r^)); + {$endif} + if pchar(stopr) > pchar(stops) then begin + stopr:= stops; + end; + end; + d:= source; //swap buffer + source:= dest; + dest:= d; + step:= step*2; + end; + + if source <> pointer(aindexlist) then begin + aindexlist:= ar1; + end; + if order then begin + orderarray(aindexlist,asortlist,aitemsize); + end; +end; + + +(* +procedure mergesort(var adata: pointerarty; const acount: integer; + const compare: pointercomparemethodty); + //todo: optimize +var + ar1: pointerarty; + step: integer; + l,r,d: ppointer; + stopl,stopr,stops: ppointer; + source,dest: ppointer; +label + endstep; +begin + allocuninitedarray(length(adata),sizeof(pointer),ar1); + source:= pointer(adata); + dest:= pointer(ar1); + step:= 1; + while step < acount do begin + d:= dest; + l:= source; + r:= source + step; + stopl:= r; + stopr:= r+step; + stops:= source + acount; + if stopr > stops then begin + stopr:= stops; + end; + while true do begin //runs + while true do begin //steps + while compare(l^,r^) <= 0 do begin //merge from left + d^:= l^; + inc(l); + inc(d); + if l = stopl then begin + while r <> stopr do begin + d^:= r^; //copy rest + inc(d); + inc(r); + end; + goto endstep; + end; + end; + while compare(l^,r^) > 0 do begin //merge from right; + d^:= r^; + inc(r); + inc(d); + if r = stopr then begin + while l <> stopl do begin + d^:= l^; //copy rest + inc(d); + inc(l); + end; + goto endstep; + end; + end; + end; +endstep: + if stopr = stops then begin + break; //run finished + end; + l:= stopr; //next step + r:= l + step; + if r >= stops then begin + r:= stops-1; + end; + if r = l then begin + d^:= l^; + break; + end; + stopl:= r; + stopr:= r + step; + if stopr > stops then begin + stopr:= stops; + end; + end; + d:= source; //swap buffer + source:= dest; + dest:= d; + step:= step*2; + end; + + if source <> pointer(adata) then begin + adata:= ar1; + end; +end; +*) + +procedure mergesort(const adata: pointer; const aitemsize,acount: integer; + const acompare: sortcomparemethodty; + out aindexlist: integerarty); + //todo: optimize +var + ar1: integerarty; + step: integer; + l,r,d: pinteger; + stopl,stopr,stops: pinteger; + source,dest: pinteger; + int1: integer; + po1: pchar; +label + endstep; +begin + aindexlist:= nil; + if acount = 0 then begin + exit; + end; + po1:= pointer(adata); + allocuninitedarray(acount,sizeof(integer),ar1); + allocuninitedarray(acount,sizeof(integer),aindexlist); + for int1:= acount-1 downto 0 do begin + aindexlist[int1]:= int1; + end; + source:= pointer(aindexlist); + dest:= pointer(ar1); + step:= 1; + while step < acount do begin + d:= dest; + l:= source; + {$ifdef FPC} + r:= source+step; + {$else} + r:= pointer(pchar(source)+step*sizeof(source^)); + {$endif} + stopl:= r; + {$ifdef FPC} + stopr:= r+step; + {$else} + stopr:= pointer(pchar(r)+step*sizeof(r^)); + {$endif} + {$ifdef FPC} + stops:= source + acount; + {$else} + stops:= pointer(pchar(source) + acount*sizeof(source^)); + {$endif} + if pchar(stopr) > pchar(stops) then begin + stopr:= stops; + end; + while true do begin //runs + while true do begin //steps + while acompare((po1+l^*aitemsize)^,(po1+r^*aitemsize)^) <= 0 do begin + //merge from left + d^:= l^; + inc(l); + inc(d); + if l = stopl then begin + while r <> stopr do begin + d^:= r^; //copy rest + inc(d); + inc(r); + end; + goto endstep; + end; + end; + while acompare((po1+l^*aitemsize)^,(po1+r^*aitemsize)^) > 0 do begin + //merge from right; + d^:= r^; + inc(r); + inc(d); + if r = stopr then begin + while l <> stopl do begin + d^:= l^; //copy rest + inc(d); + inc(l); + end; + goto endstep; + end; + end; + end; +endstep: + if stopr = stops then begin + break; //run finished + end; + l:= stopr; //next step + {$ifdef FPC} + r:= l + step; + {$else} + r:= pointer(pchar(l) + step*sizeof(l^)); + {$endif} + if pchar(r) >= pchar(stops) then begin + {$ifdef FPC} + r:= stops-1; + {$else} + r:= pointer(pchar(stops)-1*sizeof(stops^)); + {$endif} + end; + if r = l then begin + d^:= l^; + break; + end; + stopl:= r; + {$ifdef FPC} + stopr:= r + step; + {$else} + stopr:= pointer(pchar(r) + step*sizeof(r^)); + {$endif} + if pchar(stopr) > pchar(stops) then begin + stopr:= stops; + end; + end; + d:= source; //swap buffer + source:= dest; + dest:= d; + step:= step*2; + end; + + if source <> pointer(aindexlist) then begin + aindexlist:= ar1; + end; +end; + +procedure mergesortoffset(const adata: pointer; const asize,acount: integer; + const acompare: sortcomparemethodty; + out aoffsetlist: integerarty); + //todo: optimize +var + ar1: integerarty; + step: integer; + l,r,d: pinteger; + stopl,stopr,stops: pinteger; + source,dest: pinteger; + int1: integer; + po1: pchar; +label + endstep; +begin + aoffsetlist:= nil; + if acount = 0 then begin + exit; + end; + po1:= pointer(adata); + allocuninitedarray(acount,sizeof(integer),ar1); + allocuninitedarray(acount,sizeof(integer),aoffsetlist); + for int1:= acount-1 downto 0 do begin + aoffsetlist[int1]:= int1*asize; + end; + source:= pointer(aoffsetlist); + dest:= pointer(ar1); + step:= 1; + while step < acount do begin + d:= dest; + l:= source; + {$ifdef FPC} + r:= source+step; + {$else} + r:= pointer(pchar(source)+step*sizeof(source^)); + {$endif} + stopl:= r; + {$ifdef FPC} + stopr:= r+step; + {$else} + stopr:= pointer(pchar(r)+step*sizeof(r^)); + {$endif} + {$ifdef FPC} + stops:= source + acount; + {$else} + stops:= pointer(pchar(source) + acount*sizeof(source^)); + {$endif} + if pchar(stopr) > pchar(stops) then begin + stopr:= stops; + end; + while true do begin //runs + while true do begin //steps + while acompare((po1+l^{*asize})^,(po1+r^{*asize})^) <= 0 do begin + //merge from left + d^:= l^; + inc(l); + inc(d); + if l = stopl then begin + while r <> stopr do begin + d^:= r^; //copy rest + inc(d); + inc(r); + end; + goto endstep; + end; + end; + while acompare((po1+l^{*asize})^,(po1+r^{*asize})^) > 0 do begin + //merge from right; + d^:= r^; + inc(r); + inc(d); + if r = stopr then begin + while l <> stopl do begin + d^:= l^; //copy rest + inc(d); + inc(l); + end; + goto endstep; + end; + end; + end; +endstep: + if stopr = stops then begin + break; //run finished + end; + l:= stopr; //next step + {$ifdef FPC} + r:= l + step; + {$else} + r:= pointer(pchar(l) + step*sizeof(l^)); + {$endif} + if pchar(r) >= pchar(stops) then begin + {$ifdef FPC} + r:= stops-1; + {$else} + r:= pointer(pchar(stops)-1*sizeof(stops^)); + {$endif} + end; + if r = l then begin + d^:= l^; + break; + end; + stopl:= r; + {$ifdef FPC} + stopr:= r + step; + {$else} + stopr:= pointer(pchar(r) + step*sizeof(r^)); + {$endif} + if pchar(stopr) > pchar(stops) then begin + stopr:= stops; + end; + end; + d:= source; //swap buffer + source:= dest; + dest:= d; + step:= step*2; + end; + + if source <> pointer(aoffsetlist) then begin + aoffsetlist:= ar1; + end; +end; + +procedure mergesortpointer(const adata: pointer; const asize,acount: integer; + const acompare: sortcomparemethodty; + out apointerlist: pointerarty); + //todo: optimize +var + ar1: pointerarty; + step: integer; + l,r,d: ppointer; + stopl,stopr,stops: ppointer; + source,dest: ppointer; + int1: integer; +// po1: pchar; +label + endstep; +begin + apointerlist:= nil; + if acount = 0 then begin + exit; + end; +// po1:= pointer(adata); + allocuninitedarray(acount,sizeof(pointer),ar1); + allocuninitedarray(acount,sizeof(pointer),apointerlist); + for int1:= acount-1 downto 0 do begin + apointerlist[int1]:= pchar(adata)+int1*asize; + end; + source:= pointer(apointerlist); + dest:= pointer(ar1); + step:= 1; + while step < acount do begin + d:= dest; + l:= source; + {$ifdef FPC} + r:= source+step; + {$else} + r:= pointer(pchar(source)+step*sizeof(source^)); + {$endif} + stopl:= r; + {$ifdef FPC} + stopr:= r+step; + {$else} + stopr:= pointer(pchar(r)+step*sizeof(r^)); + {$endif} + {$ifdef FPC} + stops:= source + acount; + {$else} + stops:= pointer(pchar(source) + acount*sizeof(source^)); + {$endif} + if pchar(stopr) > pchar(stops) then begin + stopr:= stops; + end; + while true do begin //runs + while true do begin //steps + while acompare(({po1+}l^{*asize})^,({po1+}r^{*asize})^) <= 0 do begin + //merge from left + d^:= l^; + inc(l); + inc(d); + if l = stopl then begin + while r <> stopr do begin + d^:= r^; //copy rest + inc(d); + inc(r); + end; + goto endstep; + end; + end; + while acompare(({po1+}l^{*asize})^,({po1+}r^{*asize})^) > 0 do begin + //merge from right; + d^:= r^; + inc(r); + inc(d); + if r = stopr then begin + while l <> stopl do begin + d^:= l^; //copy rest + inc(d); + inc(l); + end; + goto endstep; + end; + end; + end; +endstep: + if stopr = stops then begin + break; //run finished + end; + l:= stopr; //next step + {$ifdef FPC} + r:= l + step; + {$else} + r:= pointer(pchar(l) + step*sizeof(l^)); + {$endif} + if pchar(r) >= pchar(stops) then begin + {$ifdef FPC} + r:= stops-1; + {$else} + r:= pointer(pchar(stops)-1*sizeof(stops^)); + {$endif} + end; + if r = l then begin + d^:= l^; + break; + end; + stopl:= r; + {$ifdef FPC} + stopr:= r + step; + {$else} + stopr:= pointer(pchar(r) + step*sizeof(r^)); + {$endif} + if pchar(stopr) > pchar(stops) then begin + stopr:= stops; + end; + end; + d:= source; //swap buffer + source:= dest; + dest:= d; + step:= step*2; + end; + + if source <> pointer(apointerlist) then begin + apointerlist:= ar1; + end; +end; + +procedure checkrefmoved(const aindexlist: integerarty; var refindex: integer; + out moved: boolean); +var + int1,int2,int3: integer; + bo1: boolean; +begin + int2:= refindex; + bo1:= false; + for int1:= high(aindexlist) downto 0 do begin + int3:= aindexlist[int1]; + if not bo1 then begin + bo1:= int3 <> int1; + end; + if int3 = int2 then begin + refindex:= int1; + if bo1 then begin + break; + end; + end; + end; + moved:= bo1; +end; + +procedure mergesort(var adata: pointer; const aitemsize,acount: integer; + const acompare: sortcomparemethodty); +var + ar1: integerarty; + ps,pd,po1: pointer; + int1: integer; +begin + mergesort(adata,aitemsize,acount,acompare,ar1); + pd:= getmem(aitemsize*acount); + po1:= pd; + ps:= adata; + for int1:= 0 to high(ar1) do begin + move((ps+ar1[int1])^,po1^,aitemsize); + inc(po1,aitemsize); + end; + freemem(ps); + adata:= pd; +end; + +procedure mergesort(const adata: pointer; const asize,acount: integer; + const acompare: sortcomparemethodty; + out aindexlist: integerarty; + var refindex: integer; out moved: boolean); +begin + mergesort(adata,asize,acount,acompare,aindexlist); + checkrefmoved(aindexlist,refindex,moved); +end; + +procedure mergesort(const acount: integer; + const acompare: indexsortcomparemethodty; out aindexlist: integerarty); + //todo: optimize +var + ar1: integerarty; + step: integer; + l,r,d: pinteger; + stopl,stopr,stops: pinteger; + source,dest: pinteger; + int1: integer; +label + endstep; +begin + aindexlist:= nil; + if acount = 0 then begin + exit; + end; + allocuninitedarray(acount,sizeof(integer),ar1); + allocuninitedarray(acount,sizeof(integer),aindexlist); + for int1:= acount-1 downto 0 do begin + aindexlist[int1]:= int1; + end; + source:= pointer(aindexlist); + dest:= pointer(ar1); + step:= 1; + while step < acount do begin + d:= dest; + l:= source; + {$ifdef FPC} + r:= source+step; + {$else} + r:= pointer(pchar(source)+step*sizeof(source^)); + {$endif} + stopl:= r; + {$ifdef FPC} + stopr:= r+step; + {$else} + stopr:= pointer(pchar(r)+step*sizeof(r^)); + {$endif} + {$ifdef FPC} + stops:= source + acount; + {$else} + stops:= pointer(pchar(source) + acount*sizeof(source^)); + {$endif} + if pchar(stopr) > pchar(stops) then begin + stopr:= stops; + end; + while true do begin //runs + while true do begin //steps + while acompare(l^,r^) <= 0 do begin + //merge from left + d^:= l^; + inc(l); + inc(d); + if l = stopl then begin + while r <> stopr do begin + d^:= r^; //copy rest + inc(d); + inc(r); + end; + goto endstep; + end; + end; + while acompare(l^,r^) > 0 do begin + //merge from right; + d^:= r^; + inc(r); + inc(d); + if r = stopr then begin + while l <> stopl do begin + d^:= l^; //copy rest + inc(d); + inc(l); + end; + goto endstep; + end; + end; + end; +endstep: + if stopr = stops then begin + break; //run finished + end; + l:= stopr; //next step + {$ifdef FPC} + r:= l + step; + {$else} + r:= pointer(pchar(l) + step*sizeof(l^)); + {$endif} + if pchar(r) >= pchar(stops) then begin + {$ifdef FPC} + r:= stops-1; + {$else} + r:= pointer(pchar(stops)-1*sizeof(stops^)); + {$endif} + end; + if r = l then begin + d^:= l^; + break; + end; + stopl:= r; + {$ifdef FPC} + stopr:= r + step; + {$else} + stopr:= pointer(pchar(r) + step*sizeof(r^)); + {$endif} + if pchar(stopr) > pchar(stops) then begin + stopr:= stops; + end; + end; + d:= source; //swap buffer + source:= dest; + dest:= d; + step:= step*2; + end; + + if source <> pointer(aindexlist) then begin + aindexlist:= ar1; + end; +end; + +procedure mergesort(const acount: integer; + const acompare: indexsortcomparemethodty; out aindexlist: integerarty; + var refindex: integer; out moved: boolean); overload; +begin + mergesort(acount,acompare,aindexlist); + checkrefmoved(aindexlist,refindex,moved); +end; + +procedure mergesort(var adata: pointerarty; const acount: integer; + const compare: pointercomparemethodty); +var + ar1: pointerarty; + step: integer; + l,r,d: ppointer; + stopl,stopr,stops: ppointer; + source,dest: ppointer; +label + endstep; +begin + allocuninitedarray(length(adata),sizeof(pointer),ar1); + source:= pointer(adata); + dest:= pointer(ar1); + step:= 1; + while step < acount do begin + d:= dest; + l:= source; + {$ifdef FPC} + r:= source + step; + {$else} + r:= pointer(pchar(source) + step*sizeof(source^)); + {$endif} + stopl:= r; + {$ifdef FPC} + stopr:= r+step; + {$else} + stopr:= pointer(pchar(r)+step*sizeof(r^)); + {$endif} + {$ifdef FPC} + stops:= source + acount; + {$else} + stops:= pointer(pchar(source) + acount*sizeof(source^)); + {$endif} + if pchar(stopr) > pchar(stops) then begin + stopr:= stops; + end; + while true do begin //runs + while true do begin //steps + while compare(l^,r^) <= 0 do begin //merge from left + d^:= l^; + inc(l); + inc(d); + if l = stopl then begin + while r <> stopr do begin + d^:= r^; //copy rest + inc(d); + inc(r); + end; + goto endstep; + end; + end; + while compare(l^,r^) > 0 do begin //merge from right; + d^:= r^; + inc(r); + inc(d); + if r = stopr then begin + while l <> stopl do begin + d^:= l^; //copy rest + inc(d); + inc(l); + end; + goto endstep; + end; + end; + end; +endstep: + if stopr = stops then begin + break; //run finished + end; + l:= stopr; //next step + {$ifdef FPC} + r:= l + step; + {$else} + r:= pointer(pchar(l) + step*sizeof(l^)); + {$endif} + if pchar(r) >= pchar(stops) then begin + {$ifdef FPC} + r:= stops-1; + {$else} + r:= pointer(pchar(stops)-1*sizeof(stops^)); + {$endif} + end; + if r = l then begin + d^:= l^; + break; + end; + stopl:= r; + {$ifdef FPC} + stopr:= r + step; + {$else} + stopr:= pointer(pchar(r) + step*sizeof(r^)); + {$endif} + if pchar(stopr) > pchar(stops) then begin + stopr:= stops; + end; + end; + d:= source; //swap buffer + source:= dest; + dest:= d; + step:= step*2; + end; + if source <> pointer(adata) then begin + adata:= ar1; + end; +end; + +const + adsize = 2*sizeof(sizeint); + +function initorderbuffer(var sortlist; const size: integer; clear: boolean; + out destpo: pchar): boolean; +begin + if pointer(sortlist) = nil then begin + result:= false; + end + else begin + getmem(destpo,size*length(bytearty(sortlist))+adsize); + psizeint(destpo)^:= 1; //refcount + inc(destpo,sizeof(sizeint)); + psizeint(destpo)^:= pinteger(pchar(sortlist)-sizeof(sizeint))^; //length or high + inc(destpo,sizeof(sizeint)); + result:= true; + if clear then begin + fillchar(destpo^,size*length(bytearty(sortlist)),0); + end; + end; +end; + +procedure storebuffer(const asource: pchar; var sortlist); +var + po1: psizeint; +begin + po1:= psizeint(pchar(sortlist) - 2*sizeof(sizeint)); + dec(po1^); + if po1^ >= 0 then begin + if po1^ = 0 then begin + freemem(po1); + end + end + else begin + inc(po1^) //constant + end; + pointer(sortlist):= asource; +end; + +procedure orderarray(const sourceorderlist: integerarty; var sortlist; size: integer); + //sortlist = array of type +var + po2: pchar; + po3: pchar; + int1: integer; +begin + if initorderbuffer(sortlist,size,false,po2) then begin + po3:= po2; + for int1:= 0 to high(sourceorderlist) do begin + move((pchar(sortlist)+sourceorderlist[int1] * size)^,po3^,size); + inc(po3,size); + end; + storebuffer(po2,sortlist); + end; +end; + +procedure reorderarray(const destorderlist: integerarty; var sortlist; size: integer); + //sortlist = array of type +var + po2: pchar; + po3: pchar; + int1: integer; +begin + if initorderbuffer(sortlist,size,false,po2) then begin + po3:= pchar(sortlist); + for int1:= 0 to high(destorderlist) do begin + move(po3^,(po2+destorderlist[int1] * size)^,size); + inc(po3,size); + end; + storebuffer(po2,sortlist); + end; +end; + +procedure orderarray(const sourceorderlist: integerarty; var sortlist: pointerarty); +var + po2: pchar; + int1: integer; +begin + if initorderbuffer(sortlist,sizeof(pointer),false,po2) then begin + for int1:= 0 to high(sourceorderlist) do begin + pointerarty(pointer(po2))[int1]:= sortlist[sourceorderlist[int1]]; + end; + storebuffer(po2,sortlist); + end; +end; + +procedure orderarray(const sourceorderlist: integerarty; + var sortlist: integerarty); +var + po2: pchar; + int1: integer; +begin + if initorderbuffer(sortlist,sizeof(integer),false,po2) then begin + for int1:= 0 to high(sourceorderlist) do begin + integerarty(pointer(po2))[int1]:= sortlist[sourceorderlist[int1]]; + end; + storebuffer(po2,sortlist); + end; +end; + +procedure reorderarray(const destorderlist: integerarty; var sortlist: pointerarty); +var + po2: pchar; + int1: integer; +begin + if initorderbuffer(sortlist,sizeof(pointer),false,po2) then begin + for int1:= 0 to high(destorderlist) do begin + pointerarty(pointer(po2))[destorderlist[int1]]:= sortlist[int1]; + end; + storebuffer(po2,sortlist); + end; +end; + +procedure reorderarray(const destorderlist: integerarty; + var sortlist: integerarty); +var + po2: pchar; + int1: integer; +begin + if initorderbuffer(sortlist,sizeof(integer),false,po2) then begin + for int1:= 0 to high(destorderlist) do begin + integerarty(pointer(po2))[destorderlist[int1]]:= sortlist[int1]; + end; + storebuffer(po2,sortlist); + end; +end; + +procedure orderarray(const sourceorderlist: integerarty; var sortlist: stringarty); +var + ar1: stringarty; + int1: integer; +begin + setlength(ar1,length(sourceorderlist)); + for int1:= 0 to high(sourceorderlist) do begin + ar1[int1]:= sortlist[sourceorderlist[int1]]; + end; + sortlist:= ar1; +end; + +procedure reorderarray(const destorderlist: integerarty; var sortlist: stringarty); +var + ar1: stringarty; + int1: integer; +begin + setlength(ar1,length(destorderlist)); + for int1:= 0 to high(destorderlist) do begin + ar1[destorderlist[int1]]:= sortlist[int1]; + end; + sortlist:= ar1; +end; + +procedure orderarray(const sourceorderlist: integerarty; var sortlist: msestringarty); +var + ar1: msestringarty; + int1: integer; +begin + setlength(ar1,length(sourceorderlist)); + for int1:= 0 to high(sourceorderlist) do begin + ar1[int1]:= sortlist[sourceorderlist[int1]]; + end; + sortlist:= ar1; +end; + +procedure orderarray(const sourceorderlist: integerarty; + var sortlist: msestringararty); overload; +var + ar1: msestringararty; + int1: integer; +begin + setlength(ar1,length(sourceorderlist)); + for int1:= 0 to high(sourceorderlist) do begin + ar1[int1]:= sortlist[sourceorderlist[int1]]; + end; + sortlist:= ar1; +end; + +procedure reorderarray(const destorderlist: integerarty; var sortlist: msestringarty); +var + ar1: msestringarty; + int1: integer; +begin + setlength(ar1,length(destorderlist)); + for int1:= 0 to high(destorderlist) do begin + ar1[destorderlist[int1]]:= sortlist[int1]; + end; + sortlist:= ar1; +end; + +procedure sortarray(var sortlist; const itemsize: integer; + const compare: arraysortcomparety; + out indexlist: integerarty); +begin + mergesortarray(sortlist,itemsize,length(bytearty(sortlist)), + compare,indexlist,true); +end; + +procedure sortarray(var sortlist; const itemsize: integer; + const compare: arraysortcomparety); +var + indexlist: integerarty; +begin + sortarray(sortlist,itemsize,compare,indexlist); +end; + +procedure sortarray(var dest: pointerarty; const compare: arraysortcomparety; + out indexlist: integerarty); +begin + mergesortarray(dest,sizeof(pointer),length(dest),compare,indexlist,false); + orderarray(indexlist,dest); +end; + +procedure sortarray(var dest: pointerarty; const compare: arraysortcomparety); +var + ar1: pointerarty; + step: integer; + l,r,d: ppointer; + stopl,stopr,stops: ppointer; + sourcepo,destpo: ppointer; + acount: integer; +label + endstep; +begin + allocuninitedarray(length(dest),sizeof(pointer),ar1); + sourcepo:= pointer(dest); + destpo:= pointer(ar1); + step:= 1; + acount:= length(dest); + while step < acount do begin + d:= destpo; + l:= sourcepo; + {$ifdef FPC} + r:= sourcepo + step; + {$else} + r:= pointer(pchar(sourcepo) + step*sizeof(sourcepo^)); + {$endif} + stopl:= r; + {$ifdef FPC} + stopr:= r+step; + {$else} + stopr:= pointer(pchar(r)+step*sizeof(r^)); + {$endif} + {$ifdef FPC} + stops:= sourcepo + acount; + {$else} + stops:= pointer(pchar(sourcepo) + acount*sizeof(sourcepo^)); + {$endif} + if pchar(stopr) > pchar(stops) then begin + stopr:= stops; + end; + while true do begin //runs + while true do begin //steps + while compare(l^,r^) <= 0 do begin //merge from left + d^:= l^; + inc(l); + inc(d); + if l = stopl then begin + while r <> stopr do begin + d^:= r^; //copy rest + inc(d); + inc(r); + end; + goto endstep; + end; + end; + while compare(l^,r^) > 0 do begin //merge from right; + d^:= r^; + inc(r); + inc(d); + if r = stopr then begin + while l <> stopl do begin + d^:= l^; //copy rest + inc(d); + inc(l); + end; + goto endstep; + end; + end; + end; +endstep: + if stopr = stops then begin + break; //run finished + end; + l:= stopr; //next step + {$ifdef FPC} + r:= l + step; + {$else} + r:= pointer(pchar(l) + step*sizeof(l^)); + {$endif} + if pchar(r) >= pchar(stops) then begin + {$ifdef FPC} + r:= stops-1; + {$else} + r:= pointer(pchar(stops)-1*sizeof(stops^)); + {$endif} + end; + if r = l then begin + d^:= l^; + break; + end; + stopl:= r; + {$ifdef FPC} + stopr:= r + step; + {$else} + stopr:= pointer(pchar(r) + step*sizeof(r^)); + {$endif} + if pchar(stopr) > pchar(stops) then begin + stopr:= stops; + end; + end; + d:= sourcepo; //swap buffer + sourcepo:= destpo; + destpo:= d; + step:= step*2; + end; + if sourcepo <> pointer(dest) then begin + dest:= ar1; + end; +end; + +{ +procedure sortarray(var dest: pointerarty; const compare: arraysortcomparety); +var + indexlist: integerarty; +begin + sortarray(dest,compare,indexlist); +end; +} +procedure sortarray(var dest: msestringarty; const compare: arraysortcomparety; + out indexlist: integerarty); +begin + mergesortarray(dest,sizeof(pointer),length(dest),compare,indexlist,false); + orderarray(indexlist,dest); +end; + +procedure sortarray(var dest: msestringarty; const compare: arraysortcomparety); +var + indexlist: integerarty; +begin + sortarray(dest,compare,indexlist); +end; + +procedure sortarray(var dest: stringarty; const compare: arraysortcomparety; + out indexlist: integerarty); +begin + mergesortarray(dest,sizeof(pointer),length(dest),compare,indexlist,false); + orderarray(indexlist,dest); +end; + +procedure sortarray(var dest: stringarty; const compare: arraysortcomparety); +var + indexlist: integerarty; +begin + sortarray(dest,compare,indexlist); +end; + +procedure sortarray(var dest: pointerarty); +begin + sortarray(dest,sizeof(pointer),{$ifdef FPC}@{$endif}comparepointer); +end; + +procedure sortarray(var dest: integerarty); +begin + sortarray(dest,sizeof(integer),{$ifdef FPC}@{$endif}compareinteger); +end; + +procedure sortarray(var dest: integerarty; out indexlist: integerarty); +begin + sortarray(dest,sizeof(integer),{$ifdef FPC}@{$endif}compareinteger,indexlist); +end; + +function comparelongword(const l,r): integer; +begin + if longword(l) > longword(r) then begin + result:= 1; + end + else begin + if longword(l) < longword(r) then begin + result:= -1; + end + else begin + result:= 0; + end; + end; +end; + +procedure sortarray(var dest: longwordarty); +begin + sortarray(dest,sizeof(longword),{$ifdef FPC}@{$endif}comparelongword); +end; + +procedure sortarray(var dest: longwordarty; out indexlist: integerarty); +begin + sortarray(dest,sizeof(longword),{$ifdef FPC}@{$endif}comparelongword,indexlist); +end; + +function comparereal(const l,r): integer; +var + rea1: real; +begin + rea1:= real(l) - real(r); + if rea1 < 0 then begin + result:= -1; + end + else begin + if rea1 > 0 then begin + result:= 1; + end + else begin + result:= 0; + end; + end; +end; + +function comparerealty(const l,r): integer; +begin + result:= cmprealty(realty(l),realty(r)); +end; + +procedure sortarray(var dest: realarty); overload; +begin + sortarray(dest,sizeof(realty),{$ifdef FPC}@{$endif}comparerealty); +end; + +procedure sortarray(var dest: realarty; out indexlist: integerarty); overload; +begin + sortarray(dest,sizeof(realty),{$ifdef FPC}@{$endif}comparerealty,indexlist); +end; + +function comparemsestring(const l,r): integer; +begin +// {$ifdef FPC} +// result:= comparestr(msestring(l),msestring(r)); //!!!todo optimize +// {$else} + result:= msecomparestr(msestring(l),msestring(r)); +// {$endif} +end; + +function compareimsestring(const l,r): integer; +begin +// {$ifdef FPC} +// result:= comparetext(msestring(l),msestring(r)); +// {$else} + result:= msecomparetext(msestring(l),msestring(r)); +// {$endif} +end; +{ +function compareasciistring(const l,r): integer; +begin + result:= stringcomp(string(l),string(r)); +// result:= comparestr(ansistring(l),ansistring(r)); +end; + +function compareiasciistring(const l,r): integer; +begin + result:= stringicomp(string(l),string(r)); +// result:= comparetext(ansistring(l),ansistring(r)); +end; +} + +function compareasciistring(const l,r): integer; +var + by1: byte; + po1,po2: pchar; +begin + po1:= pointer(string(l)); + po2:= pointer(string(r)); + if po1 = nil then begin + if po2 = nil then begin + result:= 0; + exit; + end; + result:= -1; + exit; + end; + if po2 = nil then begin + result:= 1; + exit; + end; + while true do begin + by1:= byte(po1^)-byte(po2^); + if (by1 <> 0) or (po1^ = #0) or (po2^=#0) then begin + break; + end; + inc(po1); + inc(po2); + end; + result:= shortint(by1); +end; + +function compareiasciistring(const l,r): integer; +var + by1: byte; + po1,po2: pchar; +begin + po1:= pointer(string(l)); + po2:= pointer(string(r)); + if po1 = nil then begin + if po2 = nil then begin + result:= 0; + exit; + end; + result:= -1; + exit; + end; + if po2 = nil then begin + result:= 1; + exit; + end; + while true do begin + by1:= byte(upperchars[po1^])-byte(upperchars[po2^]); + if (by1 <> 0) or (po1^ = #0) or (po2^=#0) then begin + break; + end; + inc(po1); + inc(po2); + end; + result:= shortint(by1); +end; + +function compareansistring(const l,r): integer; +begin + result:= ansicomparestr(ansistring(l),ansistring(r)); +end; + +function compareiansistring(const l,r): integer; +begin + result:= ansicomparetext(ansistring(l),ansistring(r)); +end; + +procedure sortarray(var dest: msestringarty; + const sortmode: stringsortmodety = sms_up); +begin + setlength(dest,length(dest)); //refcount1 + case sortmode of + sms_up: sortarray(pointerarty(dest), + {$ifdef FPC}@{$endif}comparemsestring); + sms_upi: sortarray(pointerarty(dest), + {$ifdef FPC}@{$endif}compareimsestring); + end; +end; + +procedure sortarray(var dest: msestringarty; const sortmode: stringsortmodety; + out indexlist: integerarty); +begin + setlength(dest,length(dest)); //refcount1 + case sortmode of + sms_up: sortarray(pointerarty(dest), + {$ifdef FPC}@{$endif}comparemsestring,indexlist); + sms_upi: sortarray(pointerarty(dest), + {$ifdef FPC}@{$endif}compareimsestring,indexlist); + end; +end; + +procedure sortarray(var dest: stringarty; + const sortmode: stringsortmodety = sms_upascii); +begin + setlength(dest,length(dest)); //refcount1 + case sortmode of + sms_up: sortarray(pointerarty(dest),{$ifdef FPC}@{$endif}compareansistring); + sms_upi: sortarray(pointerarty(dest),{$ifdef FPC}@{$endif}compareiansistring); + sms_upascii: sortarray(pointerarty(dest), + {$ifdef FPC}@{$endif}compareasciistring); + sms_upiascii: sortarray(pointerarty(dest), + {$ifdef FPC}@{$endif}compareiasciistring); + end; +end; + +procedure sortarray(var dest: stringarty; const sortmode: stringsortmodety; + out indexlist: integerarty); +begin + setlength(dest,length(dest)); //refcount1 + case sortmode of + sms_up: sortarray(pointerarty(dest), + {$ifdef FPC}@{$endif}compareansistring,indexlist); + sms_upi: sortarray(pointerarty(dest), + {$ifdef FPC}@{$endif}compareiansistring,indexlist); + sms_upascii: sortarray(pointerarty(dest), + {$ifdef FPC}@{$endif}compareasciistring,indexlist); + sms_upiascii: sortarray(pointerarty(dest), + {$ifdef FPC}@{$endif}compareiasciistring,indexlist); + end; +end; + +function cmparray(const a,b: msestringarty): boolean; + //true if equal +var + int1: integer; +begin + result:= a = b; + if not result and (high(a) = high(b)) then begin + for int1:= 0 to high(a) do begin + if a[int1] <> b[int1] then begin + exit; + end; + end; + result:= true; + end; +end; + +function opentodynarraym(const items: array of msestring): msestringarty; +var + int1: integer; +begin + setlength(result,length(items)); + for int1:= 0 to high(items) do begin + result[int1]:= items[int1]; + end; +end; + +function opentodynarrays(const items: array of string): stringarty; +var + int1: integer; +begin + setlength(result,length(items)); + for int1:= 0 to high(items) do begin + result[int1]:= items[int1]; + end; +end; + +function opentodynarrayi(const items: array of integer): integerarty; +var + int1: integer; +begin + setlength(result,length(items)); + for int1:= 0 to high(items) do begin + result[int1]:= items[int1]; + end; +end; + +function opentodynarrayr(const items: array of realty): realarty; +var + int1: integer; +begin + setlength(result,length(items)); + for int1:= 0 to high(items) do begin + result[int1]:= items[int1]; + end; +end; + +function opentodynarraybo(const items: array of boolean): booleanarty; +var + int1: integer; +begin + setlength(result,length(items)); + for int1:= 0 to high(items) do begin + result[int1]:= items[int1]; + end; +end; + +function opentodynarrayby(const items: array of byte): bytearty; +var + int1: integer; +begin + setlength(result,length(items)); + for int1:= 0 to high(items) do begin + result[int1]:= items[int1]; + end; +end; + +function dynarraytovararray(const avalue: int64arty): tvarrecarty; +var + i1: integer; +begin + result:= nil; //compiler warning + allocuninitedarray(length(avalue),sizeof(result[0]),result); + for i1:= 0 to high(avalue) do begin + with result[i1] do begin + vtype:= vtint64; + vint64:= @avalue[i1]; + end; + end; +end; + +procedure copytore(const source: realarty; var dest: complexarty); +var + ps,pe: preal; + pd: pcomplexty; +begin + setlength(dest,length(source)); + if source <> nil then begin + ps:= pointer(source); + pe:= ps+length(dest); + pd:= pointer(dest); + repeat + pd^.re:= ps^; + inc(pd); + inc(ps); + until ps = pe; + end; +end; + +procedure copytoim(const source: realarty; var dest: complexarty); +var + ps,pe: preal; + pd: pcomplexty; +begin + setlength(dest,length(source)); + if source <> nil then begin + ps:= pointer(source); + pe:= ps+length(source); + pd:= pointer(preal(pointer(dest))+1); + repeat + pd^.re:= ps^; + inc(pd); + inc(ps); + until ps = pe; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/mseassistiveclient.pas b/mseide-msegui/lib/common/kernel/mseassistiveclient.pas new file mode 100644 index 0000000..0f99ebb --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseassistiveclient.pas @@ -0,0 +1,80 @@ +{ MSEgui Copyright (c) 2015-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseassistiveclient; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} +interface +uses + msestrings,mseglob,mseinterfaces,msetypes,mseificompglob; +type + assistiveflagty = (asf_embedded,asf_container,asf_toplevel,asf_mainwindow, + asf_dummy, + asf_grid,asf_widgetgrid, + asf_gridcell, + asf_widgetcell, + asf_gridwidget, //implies iassistiveclientgridwidget + asf_datetime,asf_menu,asf_message,asf_popup, + asf_textedit,asf_graphicedit,asf_readonly, + asf_inplaceedit,asf_button,asf_dispwidget,asf_db, + asf_scrolllimit, + asf_focused,asf_disabled,asf_hasdropdown,asf_async); + assistiveflagsty = set of assistiveflagty; + + iassistiveclient = interface(inullinterface)[miid_iassistiveclient] + function getassistiveparent(): iassistiveclient; + function getinstance: tobject; + function getassistivewidget: tobject; //twidget, can be nil + function getassistivename(): msestring; + function getassistivecaption(): msestring; + function getassistivetext(): msestring; + function getassistivecaretindex(): int32; //-1 -> none + function getassistivehint(): msestring; + function getassistiveflags(): assistiveflagsty; + {$ifdef mse_with_ifi} + function getifidatalinkintf(): iifidatalink; //can be nil + {$endif} + end; + + assistivegridinfoty = record + colmin: int32; + colmax: int32; + rowmin: int32; + rowmax: int32; + end; + + iassistiveclientgrid = interface(iassistiveclient)[miid_iassistiveclientgrid] + function getassistivecellcaption(const acell: gridcoordty): msestring; + function getassistivecelltext(const acell: gridcoordty; + out aflags: assistiveflagsty): msestring; + function getassistivefocusedcell(): gridcoordty; + function getassistivegridinfo(): assistivegridinfoty; + end; + + iassistiveclientedit = interface(iassistiveclient)[miid_iassistiveclientedit] + end; + + iassistiveclientdata = interface(iassistiveclient)[miid_iassistiveclientdata] + end; + + iassistiveclientgridwidget = interface(iassistiveclientdata) + [miid_iassistiveclientgridwidget] + function getassistivecolumncaption(): msestring; + end; + + iassistiveclientmenu = interface(iassistiveclient)[miid_iassistiveclientmenu] + function getassistiveselfcaption(): msestring; + function getassistiveselfname(): msestring; + function getassistiveselfhint(): msestring; + end; + +implementation +end. diff --git a/mseide-msegui/lib/common/kernel/mseassistiveserver.pas b/mseide-msegui/lib/common/kernel/mseassistiveserver.pas new file mode 100644 index 0000000..798217d --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseassistiveserver.pas @@ -0,0 +1,104 @@ +{ MSEgui Copyright (c) 2015-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseassistiveserver; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseguiglob,mseglob,msestrings,mseinterfaces,mseact,mseshapes, + mseassistiveclient,msemenuwidgets,msegrids,msetypes,msegraphutils; + +type + + editinputmodety = (eim_insert,eim_overwrite); + edittextblockmodety = (etbm_delete,etbm_cut,etbm_copy,etbm_insert,etbm_paste); + assistiveoptionty = ( + aso_textfirst, + aso_nodefaultbutton, + aso_noreturnbutton, //do not execute button by return key + aso_returntogglevalue, //ttogglegtraphdataedit togglevalue by return key + aso_tabnavig,aso_widgetnavig,aso_nearestortho, + aso_menunavig,aso_gridnavig, + aso_noreturnkeymenuexecute, + aso_nomenumousemove, + aso_nogridmousemove, + aso_saverate,aso_savevolume, + aso_savelanguage,aso_savegender,aso_saveage, + aso_savepitch,aso_saverange, + aso_savecapitals,aso_savewordgap + ); + + assistiveoptionsty = set of assistiveoptionty; + assistivedbeventkindty = (adek_none,adek_bof,adek_eof); +const + defaultassistiveoptions = [aso_textfirst,aso_nodefaultbutton, + aso_returntogglevalue, + aso_tabnavig,aso_widgetnavig, + aso_menunavig,aso_gridnavig, + aso_noreturnkeymenuexecute, + aso_nomenumousemove,aso_nogridmousemove]; + +type + iassistiveserver = interface(inullinterface)[miid_iassistiveserver] + procedure doapplicationactivated(); + procedure doapplicationdeactivated(); + procedure dowindowactivated(const sender: iassistiveclient); + procedure dowindowdeactivated(const sender: iassistiveclient); + procedure dowindowclosed(const sender: iassistiveclient); + procedure doenter(const sender: iassistiveclient); + procedure doactivate(const sender: iassistiveclient); + procedure dodeactivate(const sender: iassistiveclient); + procedure doclientmouseevent(const sender: iassistiveclient; + const info: mouseeventinfoty); + procedure dofocuschanged(const sender: iassistiveclient; + const oldwidget,newwidget: iassistiveclient); + procedure dokeydown(const sender: iassistiveclient; + const info: keyeventinfoty); + procedure dochange(const sender: iassistiveclient); + procedure dodbvaluechanged(const sender: iassistiveclientdata); + procedure dodataentered(const sender: iassistiveclientdata); + procedure docellevent(const sender: iassistiveclientgrid; + const info: celleventinfoty); + procedure dogridbordertouched(const sender: iassistiveclientgrid; + const adirection: graphicdirectionty); + + procedure doeditcharenter(const sender: iassistiveclientedit; + const achar: msestring); + procedure doeditchardelete(const sender: iassistiveclientedit; + const achar: msestring); + procedure doeditwithdrawn(const sender: iassistiveclientedit); + procedure doeditindexmoved(const sender: iassistiveclientedit; + const aindex: int32); + procedure doeditinputmodeset(const sender: iassistiveclientedit; + const amode: editinputmodety); + procedure doedittextblock(const sender: iassistiveclientedit; + const amode: edittextblockmodety; const atext: msestring); + procedure donavigbordertouched(const sender: iassistiveclient; + const adirection: graphicdirectionty); + procedure dotabordertouched(const sender: iassistiveclient; + const adown: boolean); + + procedure doactionexecute(const sender: iassistiveclient;//sender can be nil + const senderobj: tobject; const info: actioninfoty); + procedure doitementer(const sender: iassistiveclient; //sender can be nil + const items: shapeinfoarty; const aindex: integer); + procedure domenuactivated(const sender: iassistiveclientmenu); + procedure doitementer(const sender: iassistiveclientmenu;//sender can be nil + const items: menucellinfoarty; const aindex: integer); + procedure dodatasetevent(const sender: iassistiveclient; + const akind: assistivedbeventkindty; + const adataset: pointer); //tdataset +end; + +var + assistiveserver: iassistiveserver; + assistiveoptions: assistiveoptionsty; + +implementation +end. diff --git a/mseide-msegui/lib/common/kernel/msebintree.pas b/mseide-msegui/lib/common/kernel/msebintree.pas new file mode 100644 index 0000000..ce03128 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msebintree.pas @@ -0,0 +1,870 @@ +{ MSEgui Copyright (c) 2007 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msebintree; +{$ifdef FPC}{$mode objfpc}{$h+}{$GOTO ON}{$endif} +interface +type + tavlnode = class + private + fup: tavlnode; + fleft: tavlnode; + fright: tavlnode; + fbalance: integer; + public + destructor destroy; override; + property balance: integer read fbalance; + property up: tavlnode read fup; + property left: tavlnode read fleft; + property right: tavlnode read fright; + end; + + tintegeravlnode = class(tavlnode) + private + fkey: integer; + public + constructor create(const akey: integer); + property key: integer read fkey; + end; + + tint64avlnode = class(tavlnode) + protected + fkey: int64; + public + constructor create(const akey: int64); overload; + property key: int64 read fkey; + end; + + avlnodeclassty = class of tavlnode; + pavlnode = ^tavlnode; + + nodecomparefuncty = function(const left,right: tavlnode): integer; + nodeprocty = procedure(const anode: tavlnode) of object; + + tavltree = class + private + froot: tavlnode; + fcount: integer; +// fnodeclass: avlnodeclassty; +// procedure freenode(const anode: tavlnode); + protected + fcompare: nodecomparefuncty; + function parentpo(const anode: tavlnode): pavlnode; + procedure dobalance(const anode: tavlnode; const deleted: boolean); + procedure addnode(const anode: tavlnode); + function find(const aleft: tavlnode; out anode: tavlnode): boolean; + //true if exact + public + destructor destroy; override; + procedure clear; virtual;//frees the nodes + procedure removenode(const anode: tavlnode); //does not free node + procedure traverse(const aproc: nodeprocty); + property count: integer read fcount; + property root: tavlnode read froot; + end; + + integernodeprocty = procedure(const anode: tintegeravlnode) of object; + + tintegeravltree = class(tavltree) + public + constructor create; + function addnode(const akey: integer): tintegeravlnode; overload; + procedure addnode(const anode: tintegeravlnode); overload; + function find(const akey: integer; out anode: tintegeravlnode): boolean; overload; + procedure traverse(const aproc: integernodeprocty); + end; + + int64nodeprocty = procedure(const anode: tint64avlnode) of object; + + tint64avltree = class(tavltree) + public + constructor create; + function addnode(const akey: int64): tint64avlnode; overload; + function find(const akey: int64; out anode: tint64avlnode): boolean; overload; + procedure traverse(const aproc: int64nodeprocty); + end; + + tcachenode = class(tint64avlnode) + private + fprev: tcachenode; + fnext: tcachenode; + protected + fsize: integer; + end; + + tdatacachenode = class(tcachenode) + private + fdata: pointer; + public + constructor create(const akey: int64; const adata: pointer; const asize: integer); + destructor destroy; override; + property data: pointer read fdata; + property size: integer read fsize; + end; + + tcacheavltree = class(tint64avltree) + private + fsize: integer; + ffirst: tcachenode; + flast: tcachenode; + fmaxsize: integer; + procedure setmaxsize(const avalue: integer); + procedure checkbuffersize; + protected + procedure addnode(const anode: tcachenode); + function find(const akey: tcachenode; out anode: tcachenode): boolean; overload; + public + procedure clear; overload; override; + procedure removenode(const anode: tcachenode); //does not free node + property maxsize: integer read fmaxsize write setmaxsize; //0 -> no limit + property size: integer read fsize; + end; + + tdatacacheavltree = class(tcacheavltree) + public + function addnode(const akey: int64; const adata: pointer; + const asize: integer): tdatacachenode; + end; + + tstringcachenode = class(tcachenode) + private + fdata: string; + public + constructor create(const akey: int64; const adata: string); overload; + property data: string read fdata; + end; + + tstringcacheavltree = class(tcacheavltree) + public + function addnode(const akey: int64; + const adata: string): tstringcachenode; overload; + end; + +implementation +uses + sysutils; + +{ tavlnode } + +destructor tavlnode.destroy; +begin + fleft.free; + fright.free; +end; + +{ tavltree } + +destructor tavltree.destroy; +begin + clear; + inherited; +end; + +procedure tavltree.clear; +begin + fcount:= 0; + freeandnil(froot); +end; +{ +procedure tavltree.freenode(const anode: tavlnode); +begin + if anode <> nil then begin + freenode(anode.fleft); + freenode(anode.fright); + anode.free; + end; +end; +} +function tavltree.find(const aleft: tavlnode; out anode: tavlnode): boolean; +var + n1: tavlnode; + int1: integer; +begin + anode:= nil; + result:= false; + if froot <> nil then begin + n1:= froot; + while true do begin + int1:= fcompare(n1,aleft); + if int1 = 0 then begin //exact + anode:= n1; + result:= true; + break; + end; + if int1 > 0 then begin //too big + if n1.fleft = nil then begin + anode:= n1; + break; + end; + n1:= n1.fleft; + end + else begin //too small + if n1.fright = nil then begin + anode:= n1.fup; + if (anode <> nil) and (anode.fleft <> n1) then begin + anode:= nil; + end; + break; + end; + n1:= n1.fright; + end; + end; + end; +end; + +function tavltree.parentpo(const anode: tavlnode): pavlnode; +var + n1: tavlnode; +begin + n1:= anode.fup; + if n1 = nil then begin + result:= @froot; + end + else begin + if anode = n1.fleft then begin + result:= @n1.fleft; + end + else begin + result:= @n1.fright; + end; + end; +end; + +procedure tavltree.dobalance(const anode: tavlnode; const deleted: boolean); +var + n3,n4,n5: tavlnode; + po1: pavlnode; + + procedure initpointer; + begin + n5:= n4.fup; + po1:= parentpo(n4); + end; + +begin //balance + n3:= anode; + n5:= nil; //compiler warning + po1:= nil; + while true do begin + n4:= n3.fup; + if n4 = nil then begin + break; //root reached + end; + if (n4.fleft = n3) xor deleted then begin + if (n4.fbalance < 0) then begin //left heavy + initpointer; + if n4.fleft.fbalance > 0 then begin + //rotate left right + // A=n4 B + // / \ / \ + // C a C A=n4 + // / \ / \ / \ + // c B c b2 b1 a + // / \ + // b2 b1 + po1^:= n4.fleft.fright; //B -> top + po1^.fup:= n4.fup; //A.up -> B.up + n4.fleft.fright:= po1^.fleft; //b2 -> C.right + if n4.fleft.fright <> nil then begin + n4.fleft.fright.fup:= n4.fleft; //C -> b2.up + end; + po1^.fleft:= n4.fleft; //C -> B.left + n4.fleft.fup:= po1^; //B -> C.up + n4.fleft:= po1^.fright; //b1 -> A.left + if n4.fleft <> nil then begin + n4.fleft.fup:= n4; + end; + po1^.fright:= n4; //A -> B.right + n4.fup:= po1^; //B -> A.up + + //before A B C after A B C + // -2 +1 +1 0 0 -1 + // -2 0 +1 0 0 0 + // -2 -1 +1 +1 0 0 + if po1^.fbalance = 0 then begin //B + n4.fbalance:= 0; //A + po1^.fleft.fbalance:= 0; //C + end + else begin + if po1^.fbalance < 0 then begin //B + n4.fbalance:= 1; //A + po1^.fleft.fbalance:= 0; //C + end + else begin + n4.fbalance:= 0; //A + po1^.fleft.fbalance:= -1; //C + end; + end; + po1^.fbalance:= 0; + if not deleted then begin + exit; //new height compensated + end; + end + else begin + //rotate right A=n4 B + // / \ / \ + // B a c A=n4 + // / \ / \ + // c b b a + po1^:= n4.fleft; //B -> top + po1^.fup:= n4.fup; //A.up -> B.up + n4.fleft:= po1^.fright; //b -> A.left + po1^.fright:= n4; //A -> B.right + + //before A B after A B + // -2 -1 0 0 + // -2 0 -1 +1 + if po1^.fbalance = 0 then begin + n4.fbalance:= -1; + po1^.fbalance:= 1; + end + else begin + n4.fbalance:= 0; + po1^.fbalance:= 0; + end; + end; + po1^.fup:= n5; //up -> B.up + n4.fup:= po1^; //B -> A.up + if n4.fleft <> nil then begin + n4.fleft.fup:= n4; //A -> b1.up ¦ A -> b.up + end; + if (po1^.fbalance = 0) xor deleted then begin + exit; //B was unbalanced; + end; + n4:= po1^; + end + else begin + dec(n4.fbalance); + if (n4.fbalance = 0) xor deleted then begin + exit; + end; + end; + end + else begin + if (n4.fbalance > 0) then begin //right heavy + initpointer; + if n4.fright.fbalance < 0 then begin + //rotate right left + // A=n4 B + // / \ / \ + // a C A=n4 C + // / \ / \ / \ + // B c a b1 b2 c + // / \ + // b1 b2 + po1^:= n4.fright.fleft; //B -> top + po1^.fup:= n4.fup; //A.up -> B.up + n4.fright.fleft:= po1^.fright; //b2 -> C.left + if n4.fright.fleft <> nil then begin + n4.fright.fleft.fup:= n4.fright; //C -> b2.up + end; + po1^.fright:= n4.fright; //C -> B.right + n4.fright.fup:= po1^; //B -> C.up + n4.fright:= po1^.fleft; //b1 -> A.right + if n4.fright <> nil then begin + n4.fright.fup:= n4; + end; + po1^.fleft:= n4; //A -> B.left + n4.fup:= po1^; //B -> A.up + + //before A B C after A B C + // +2 +1 -1 -1 0 0 + // +2 0 -1 0 0 0 + // +2 -1 -1 0 0 1 + if po1^.fbalance = 0 then begin //B + n4.fbalance:= 0; //A + po1^.fright.fbalance:= 0; //C + end + else begin + if po1^.fbalance < 0 then begin //B + n4.fbalance:= 0; //A + po1^.fright.fbalance:= 1; //C + end + else begin + n4.fbalance:= -1; //A + po1^.fright.fbalance:= 0; //C + end; + end; + po1^.fbalance:= 0; + if not deleted then begin + exit; //new height compensated + end; + end + else begin + //rotate left A=n4 B + // / \ / \ + // a B A=n4 c + // / \ / \ + // b c a b + po1^:= n4.fright; //B -> top + po1^.fup:= n4.fup; //A.up -> B.up + n4.fright:= po1^.fleft; //b -> A.right + po1^.fleft:= n4; //A -> B.left + + //before A B after A B + // +2 +1 0 0 + // +2 0 +1 -1 + if po1^.fbalance = 0 then begin + n4.fbalance:= 1; + po1^.fbalance:= -1; + end + else begin + n4.fbalance:= 0; + po1^.fbalance:= 0; + end; + end; + po1^.fup:= n5; + n4.fup:= po1^; + if n4.fright <> nil then begin + n4.fright.fup:= n4; //A -> b1.up ¦ A -> b.up + end; + if (po1^.fbalance = 0) xor deleted then begin + exit; //B was unbalanced; + end; + n4:= po1^; + end + else begin + inc(n4.fbalance); + if (n4.fbalance = 0) xor deleted then begin + exit; + end; + end; + end; + { + if (n4.fbalance = 0) and (anode <> n3) then begin + exit; + end; + } + n3:= n4; + end; +end; + +procedure tavltree.addnode(const anode: tavlnode); +var + n1{,n2}: tavlnode; + +begin + inc(fcount); + if froot = nil then begin + froot:= anode; + end + else begin + n1:= froot; + while true do begin + if fcompare(anode,n1) >= 0 then begin + if n1.fright = nil then begin + n1.fright:= anode; + anode.fup:= n1; + if n1.fleft = nil then begin + dobalance(anode,false); + end + else begin + n1.fbalance:= 0; + end; + break; + end + else begin + n1:= n1.fright; + end; + end + else begin + if n1.fleft = nil then begin + n1.fleft:= anode; + anode.fup:= n1; + if n1.fright = nil then begin + dobalance(anode,false); + end + else begin + n1.fbalance:= 0; + end; + break; + end + else begin + n1:= n1.fleft; + end; + end; + end; + end; +end; + +procedure tavltree.removenode(const anode: tavlnode); + + procedure checkbalance; + begin + if anode.fup <> nil then begin + with anode.fup do begin + if anode = fright then begin + if (fleft.fleft = nil) and (fleft.fright = nil) or (fbalance < 0) then begin + dobalance(anode,true); + end + else begin + fbalance:= -1; + end; + end + else begin + if (fright.fleft = nil) and (fright.fright = nil) or (fbalance > 0) then begin + dobalance(anode,true); + end + else begin + fbalance:= 1; + end; + end; + end; + end; + end; + +var + n1,n2: tavlnode; + int1: integer; +begin + dec(fcount); + n1:= anode; + if (n1.fleft <> nil) and (n1.fright <> nil) then begin + n1:= n1.fright; + while n1.fleft <> nil do begin + n1:= n1.fleft; //find smallest in right branch + end; + int1:= anode.fbalance; //swap values + anode.fbalance:= n1.fbalance; + n1.fbalance:= int1; + parentpo(anode)^:= n1; + n2:= anode.fleft; + anode.fleft:= n1.fleft; + n1.fleft:= n2; + if n2 <> nil then begin + n2.fup:= n1; + end; + if n1.fup = anode then begin + anode.fright:= n1.fright; + n1.fright:= anode; + n1.fup:= anode.fup; + anode.fup:= n1; + end + else begin + parentpo(n1)^:= anode; + n2:= anode.fup; + anode.fup:= n1.fup; + n1.fup:= n2; + n2:= anode.fright; + anode.fright:= n1.fright; + n1.fright:= n2; + n2.fup:= n1; + end; + end; + if anode.fleft = nil then begin + if anode.fright <> nil then begin + checkbalance; + anode.fright.fup:= anode.fup; + end + else begin + if (anode.fup <> nil) then begin //leaf + with anode.fup do begin + if fleft = anode then begin + if (fright = nil) or (fright.fright <> nil) or (fright.fleft <> nil) or + (fbalance > 0) then begin + dobalance(anode,true); + end + else begin + fbalance:= 1; + end; + end + else begin + if (fleft = nil) or (fleft.fright <> nil) or (fleft.fleft <> nil) or + (fbalance < 0) then begin + dobalance(anode,true); + end + else begin + fbalance:= -1; + end; + end; + end; + end; + end; + parentpo(anode)^:= anode.fright; + end + else begin + checkbalance; + anode.fleft.fup:= anode.fup; + parentpo(anode)^:= anode.fleft; + end; + anode.fleft:= nil; + anode.fright:= nil; +end; + +procedure tavltree.traverse(const aproc: nodeprocty); +label + down; +var + n1: tavlnode; +begin + if froot <> nil then begin + n1:= froot; +down: + while n1.fleft <> nil do begin + n1:= n1.fleft; //find smallest leaf + end; + aproc(n1); + if (n1.fleft = nil) and (n1.fright <> nil) then begin + n1:= n1.fright; + goto down; + end; + while n1.fup <> nil do begin + if n1 = n1.fup.fleft then begin + n1:= n1.fup; + aproc(n1); + if n1.fright <> nil then begin + n1:= n1.fright; + goto down; + end; + end + else begin + n1:= n1.fup; + end; + end; + end; +end; + +{ tintegeravlnode } + +constructor tintegeravlnode.create(const akey: integer); +begin + fkey:= akey; + inherited create; +end; + +{ tintegeravltree } + +function compareintegeravl(const left,right: tavlnode): integer; +begin + result:= tintegeravlnode(left).fkey - tintegeravlnode(right).fkey; +end; + +constructor tintegeravltree.create; +begin +// fnodeclass:= tintegeravlnode; + fcompare:= {$ifdef FPC}@{$endif}compareintegeravl; + inherited; +end; + +function tintegeravltree.addnode(const akey: integer): tintegeravlnode; +begin + result:= tintegeravlnode.create(akey); + inherited addnode(result); +end; + +function tintegeravltree.find(const akey: integer; + out anode: tintegeravlnode): boolean; +var + n1: tintegeravlnode; +begin + n1:= tintegeravlnode.create(akey); + result:= find(n1,tavlnode(anode)); + n1.free; +end; + +procedure tintegeravltree.traverse(const aproc: integernodeprocty); +begin + inherited traverse(nodeprocty(aproc)); +end; + +procedure tintegeravltree.addnode(const anode: tintegeravlnode); +begin + inherited addnode(anode); +end; + +{ tint64avlnode } + +constructor tint64avlnode.create(const akey: int64); +begin + fkey:= akey; + inherited create; +end; + +{ tint64avltree } + +function compareint64avl(const left,right: tavlnode): integer; +var + lint1: int64; +begin + result:= 0; + lint1:= tint64avlnode(left).fkey - tint64avlnode(right).fkey; + if lint1 > 0 then begin + result:= 1; + end + else begin + if lint1 < 0 then begin + result:= -1; + end; + end; +end; + +constructor tint64avltree.create; +begin + fcompare:= {$ifdef FPC}@{$endif}compareint64avl; + inherited; +end; + +function tint64avltree.addnode(const akey: int64): tint64avlnode; +begin + result:= tint64avlnode.create(akey); + inherited addnode(result); +end; + +function tint64avltree.find(const akey: int64; + out anode: tint64avlnode): boolean; +var + n1: tint64avlnode; +begin + n1:= tint64avlnode.create(akey); + result:= find(n1,tavlnode(anode)); + n1.free; +end; + +procedure tint64avltree.traverse(const aproc: int64nodeprocty); +begin + inherited traverse(nodeprocty(aproc)); +end; + +{ tdatacachenode } + +constructor tdatacachenode.create(const akey: int64; const adata: pointer; + const asize: integer); +begin + fdata:= adata; + fsize:= asize; + inherited create(akey); +end; + +destructor tdatacachenode.destroy; +begin + if fsize > 0 then begin + freemem(fdata); + end; + inherited; +end; + +{ tcacheavltree } + +procedure tcacheavltree.checkbuffersize; +var + n1: tcachenode; +begin + if fmaxsize > 0 then begin + while (fsize > fmaxsize) and (fcount > 1) do begin + n1:= ffirst; + removenode(n1); + n1.free; + end; + end; +end; + +procedure tcacheavltree.addnode(const anode: tcachenode); +begin + fsize:= fsize + anode.fsize; + if ffirst = nil then begin + ffirst:= anode; + flast:= anode; + end + else begin + anode.fprev:= flast; + flast.fnext:= anode; + flast:= anode; + end; + inherited addnode(anode); + checkbuffersize; +end; + +function tcacheavltree.find(const akey: tcachenode; out anode: tcachenode): boolean; +begin + result:= inherited find(akey,tavlnode(anode)); + if result and (anode <> flast) then begin + if anode.fprev <> nil then begin + anode.fprev.fnext:= anode.fnext; + end + else begin + ffirst:= anode.fnext; + end; + if anode.fnext <> nil then begin + anode.fnext.fprev:= anode.fprev; + end; + flast.fnext:= anode; + anode.fprev:= flast; + anode.fnext:= nil; + flast:= anode; + end; +end; + +procedure tcacheavltree.clear; +begin + fsize:= 0; + ffirst:= nil; + flast:= nil; + inherited; +end; + +procedure tcacheavltree.removenode(const anode: tcachenode); +begin + fsize:= fsize - anode.fsize; + if fcount > 1 then begin + if anode = ffirst then begin + ffirst:= anode.fnext; + ffirst.fprev:= nil; + end + else begin + if anode = flast then begin + flast:= anode.fprev; + flast.fnext:= nil; + end; + end; + end + else begin + ffirst:= nil; + flast:= nil; + end; + anode.fprev:= nil; + anode.fnext:= nil; + inherited removenode(anode); +end; + +procedure tcacheavltree.setmaxsize(const avalue: integer); +begin + if fmaxsize <> avalue then begin + fmaxsize:= avalue; + checkbuffersize; + end; +end; + +{ tdatacacheavltree } + +function tdatacacheavltree.addnode(const akey: int64; const adata: pointer; + const asize: integer): tdatacachenode; +begin + result:= tdatacachenode.create(akey,adata,asize); + inherited addnode(result); +end; + +{ tstringcachenode } + +constructor tstringcachenode.create(const akey: int64; const adata: string); +begin + fdata:= adata; + fsize:= length(adata); + inherited create(akey); +end; + +{ tstringcacheavltree } + +function tstringcacheavltree.addnode(const akey: int64; + const adata: string): tstringcachenode; +begin + result:= tstringcachenode.create(akey,adata); + inherited addnode(result); +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/msebits.pas b/mseide-msegui/lib/common/kernel/msebits.pas new file mode 100644 index 0000000..e0ffedf --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msebits.pas @@ -0,0 +1,815 @@ +{ MSEgui Copyright (c) 1999-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msebits; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +//bitmanipulationhelpers +interface +uses + msetypes; + +type + bitnumty = 0..32; +const + twoexp32 = flo64(4294967296.0); + bytebits: array[0..8] of byte = ($01,$02,$04,$08,$10,$20,$40,$80,$00); + bytemask: array[0..8] of byte = ($00,$01,$03,$07,$0f,$1f,$3f,$7f,$ff); + bytebitsreverse: array[0..8] of byte = ($80,$40,$20,$10,$08,$04,$02,$01,$00); + + bits: array[bitnumty] of longword = ( + $00000001,$00000002,$00000004,$00000008, + $00000010,$00000020,$00000040,$00000080, + $00000100,$00000200,$00000400,$00000800, + $00001000,$00002000,$00004000,$00008000, + $00010000,$00020000,$00040000,$00080000, + $00100000,$00200000,$00400000,$00800000, + $01000000,$02000000,$04000000,$08000000, + $10000000,$20000000,$40000000,$80000000, + $00000000); + bitmask: array[bitnumty] of longword = ( + $00000000,$00000001,$00000003,$00000007, + $0000000f,$0000001f,$0000003f,$0000007f, + $000000ff,$000001ff,$000003ff,$000007ff, + $00000fff,$00001fff,$00003fff,$00007fff, + $0000ffff,$0001ffff,$0003ffff,$0007ffff, + $000fffff,$001fffff,$003fffff,$007fffff, + $00ffffff,$01ffffff,$03ffffff,$07ffffff, + $0fffffff,$1fffffff,$3fffffff,$7fffffff, + $ffffffff); + bitreverse: array[byte] of byte = ( + $00,$80,$40,$c0,$20,$a0,$60,$e0,$10,$90,$50,$d0,$30,$b0,$70,$f0, + $08,$88,$48,$c8,$28,$a8,$68,$e8,$18,$98,$58,$d8,$38,$b8,$78,$f8, + $04,$84,$44,$c4,$24,$a4,$64,$e4,$14,$94,$54,$d4,$34,$b4,$74,$f4, + $0c,$8c,$4c,$cc,$2c,$ac,$6c,$ec,$1c,$9c,$5c,$dc,$3c,$bc,$7c,$fc, + $02,$82,$42,$c2,$22,$a2,$62,$e2,$12,$92,$52,$d2,$32,$b2,$72,$f2, + $0a,$8a,$4a,$ca,$2a,$aa,$6a,$ea,$1a,$9a,$5a,$da,$3a,$ba,$7a,$fa, + $06,$86,$46,$c6,$26,$a6,$66,$e6,$16,$96,$56,$d6,$36,$b6,$76,$f6, + $0e,$8e,$4e,$ce,$2e,$ae,$6e,$ee,$1e,$9e,$5e,$de,$3e,$be,$7e,$fe, + $01,$81,$41,$c1,$21,$a1,$61,$e1,$11,$91,$51,$d1,$31,$b1,$71,$f1, + $09,$89,$49,$c9,$29,$a9,$69,$e9,$19,$99,$59,$d9,$39,$b9,$79,$f9, + $05,$85,$45,$c5,$25,$a5,$65,$e5,$15,$95,$55,$d5,$35,$b5,$75,$f5, + $0d,$8d,$4d,$cd,$2d,$ad,$6d,$ed,$1d,$9d,$5d,$dd,$3d,$bd,$7d,$fd, + $03,$83,$43,$c3,$23,$a3,$63,$e3,$13,$93,$53,$d3,$33,$b3,$73,$f3, + $0b,$8b,$4b,$cb,$2b,$ab,$6b,$eb,$1b,$9b,$5b,$db,$3b,$bb,$7b,$fb, + $07,$87,$47,$c7,$27,$a7,$67,$e7,$17,$97,$57,$d7,$37,$b7,$77,$f7, + $0f,$8f,$4f,$cf,$2f,$af,$6f,$ef,$1f,$9f,$5f,$df,$3f,$bf,$7f,$ff); + + intexp10ar: array[0..9] of integer = + (1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000); + int64exp10ar: array[0..19] of int64 = + (1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000, + 1000000000,10000000000,100000000000,1000000000000,10000000000000, + 100000000000000,1000000000000000,10000000000000000, + 100000000000000000,1000000000000000000); +type + int64recty = record + lsw: longword; + msw: longword; + end; + +function highestbit(value: longword): integer; +//0-> first, 31-> last($80000000), -1-> none ($00000000) +function lowestbit(value: longword): integer; +//0-> first, 31-> last($80000000), -1-> none ($00000000) +function nextpowerof2(const avalue: longword): longword; + +function highestbit64(value: qword): integer; +//0-> first, 63-> last($8000000000000000), -1-> none ($0000000000000000) +function lowestbit64(value: qword): integer; +//0-> first, 63-> last($8000000000000000), -1-> none ($0000000000000000) + +function replacebits(const new,old,mask: byte): byte; overload; +function replacebits(const new,old,mask: word): word; overload; +function replacebits(const new,old,mask: longword): longword; overload; +function replacebits1(var dest: byte; const value,mask: byte): boolean; overload; +function replacebits1(var dest: word; const value,mask: word): boolean; overload; +function replacebits1(var dest: longword; + const value,mask: longword): boolean; overload; + //true if modified +function bitschanged(const a,b,mask: byte): boolean; overload; +function bitschanged(const a,b,mask: word): boolean; overload; +function bitschanged(const a,b,mask: longword): boolean; overload; + +function setsinglebit(const new,old,mask: byte): byte; overload; +function setsinglebit(const new,old,mask: word): word; overload; +function setsinglebit(const new,old,mask: longword): longword; overload; +function setsinglebit(const new,old: byte; + const mask: array of byte): byte; overload; +function setsinglebit(const new,old: word; + const mask: array of word): word; overload; +function setsinglebit(const new,old: longword; + const mask: array of longword): longword; overload; +{$ifndef FPC} +function setsinglebitar8(const new,old: byte; + const mask: array of byte): byte; +function setsinglebitar16(const new,old: word; + const mask: array of word): word; +function setsinglebitar32(const new,old: longword; + const mask: array of longword): longword; +{$endif} + +function checkbit(const value: byte; const bitnum: integer): boolean; overload; +function checkbit(const value: word; const bitnum: integer): boolean; overload; +function checkbit(const value: longword; const bitnum: integer): boolean; overload; + +function updatebit(var dest: byte; bitnum: integer; value: boolean): boolean; overload; + //true if changed +function updatebit(var dest: word; bitnum: integer; value: boolean): boolean; overload; + //true if changed +function updatebit(var dest: longword; bitnum: integer; value: boolean):boolean; overload; + //true if changed +procedure updatebit1(var dest: byte; bitnum: integer; value: boolean); overload; +procedure updatebit1(var dest: word; bitnum: integer; value: boolean); overload; +procedure updatebit1(var dest: longword; bitnum: integer; value: boolean); overload; + +procedure setbit1(var dest: byte; bitnum: integer); overload; +procedure setbit1(var dest: word; bitnum: integer); overload; +procedure setbit1(var dest: longword; bitnum: integer); overload; +function setbit(const source: byte; bitnum: integer): byte; overload; +function setbit(const source: word; bitnum: integer): word; overload; +function setbit(const source: longword; bitnum: integer): longword; overload; + +procedure clearbit1(var dest: byte; bitnum: integer); overload; +procedure clearbit1(var dest: word; bitnum: integer); overload; +procedure clearbit1(var dest: longword; bitnum: integer); overload; +function clearbit(const source: byte; bitnum: integer): byte; overload; +function clearbit(const source: word; bitnum: integer): word; overload; +function clearbit(const source: longword; bitnum: integer): longword; overload; + +procedure togglebit1(var dest: byte; bitnum: integer); overload; +procedure togglebit1(var dest: word; bitnum: integer); overload; +procedure togglebit1(var dest: longword; bitnum: integer); overload; +function togglebit(const source: byte; bitnum: integer): byte; overload; +function togglebit(const source: word; bitnum: integer): word; overload; +function togglebit(const source: longword; bitnum: integer): longword; overload; + +function iszero(address: pointer; count: integer): boolean; + +function swapbytes(const value: word): word; overload; + //value and result at different adresses! +function swapbytes(const value: longword): longword; overload; + //value and result at different adresses! +procedure swapbytes1(var value: word); overload; +procedure swapbytes1(var value: longword); overload; + +function swapbits(const value: word): word; overload; + //value and result at different adresses! +function swapbits(const value: longword): longword; overload; + //value and result at different adresses! +procedure swapbits1(var value: word); overload; +procedure swapbits1(var value: longword); overload; + +procedure swaprgb1(var value: longword); +function swaprgb(const value: longword): longword; + +function roundint(const value: integer; const step: integer): integer; +procedure scaleexp101(var value: int64; const exp: integer); overload; +procedure scaleexp101(var value: integer; const exp: integer); overload; +procedure scaleexp101(var value: currency; const exp: integer); overload; +function scaleexp10(const value: int64; const exp: integer): int64; overload; +function scaleexp10(const value: integer; const exp: integer): integer; overload; +function scaleexp10(const value: currency; const exp: integer): currency; overload; + +implementation + +function updatebit(var dest: byte; bitnum: integer; value: boolean): boolean; +var + by1: byte; +begin + by1:= dest; + if value then begin + dest:= dest or bits[bitnum]; + end + else begin + dest:= dest and not bits[bitnum]; + end; + result:= dest <> by1; +end; + +function updatebit(var dest: word; bitnum: integer; value: boolean): boolean; +var + wo1: word; +begin + wo1:= dest; + if value then begin + dest:= dest or bits[bitnum]; + end + else begin + dest:= dest and not bits[bitnum]; + end; + result:= dest <> wo1; +end; + +function updatebit(var dest: longword; bitnum: integer; value: boolean): boolean; +var + wo1: longword; +begin + wo1:= dest; + if value then begin + dest:= dest or bits[bitnum]; + end + else begin + dest:= dest and not bits[bitnum]; + end; + result:= dest <> wo1; +end; + +procedure updatebit1(var dest: byte; bitnum: integer; value: boolean); +//var +// by1: byte; +begin +// by1:= dest; + if value then begin + dest:= dest or bits[bitnum]; + end + else begin + dest:= dest and not bits[bitnum]; + end; +end; + +procedure updatebit1(var dest: word; bitnum: integer; value: boolean); +//var +// wo1: word; +begin +// wo1:= dest; + if value then begin + dest:= dest or bits[bitnum]; + end + else begin + dest:= dest and not bits[bitnum]; + end; +end; + +procedure updatebit1(var dest: longword; bitnum: integer; value: boolean); +//var +// wo1: longword; +begin +// wo1:= dest; + if value then begin + dest:= dest or bits[bitnum]; + end + else begin + dest:= dest and not bits[bitnum]; + end; +end; + +procedure setbit1(var dest: byte; bitnum: integer); +begin + dest:= dest or bits[bitnum]; +end; + +procedure setbit1(var dest: word; bitnum: integer); +begin + dest:= dest or bits[bitnum]; +end; + +procedure setbit1(var dest: longword; bitnum: integer); +begin + dest:= dest or bits[bitnum]; +end; + +procedure clearbit1(var dest: byte; bitnum: integer); +begin + dest:= dest and not bits[bitnum]; +end; + +procedure clearbit1(var dest: word; bitnum: integer); +begin + dest:= dest and not bits[bitnum]; +end; + +procedure clearbit1(var dest: longword; bitnum: integer); +begin + dest:= dest and not bits[bitnum]; +end; + +procedure togglebit1(var dest: byte; bitnum: integer); +begin + dest:= dest xor byte(bits[bitnum]); +end; + +procedure togglebit1(var dest: word; bitnum: integer); +begin + dest:= dest xor word(bits[bitnum]); +end; + +procedure togglebit1(var dest: longword; bitnum: integer); +begin + dest:= dest xor bits[bitnum]; +end; + +function setbit(const source: byte; bitnum: integer): byte; +begin + result:= source or bits[bitnum]; +end; + +function setbit(const source: word; bitnum: integer): word; +begin + result:= source or bits[bitnum]; +end; + +function setbit(const source: longword; bitnum: integer): longword; +begin + result:= source or bits[bitnum]; +end; + +function clearbit(const source: byte; bitnum: integer): byte; +begin + result:= source and not bits[bitnum]; +end; + +function clearbit(const source: word; bitnum: integer): word; +begin + result:= source and not bits[bitnum]; +end; + +function clearbit(const source: longword; bitnum: integer): longword; +begin + result:= source and not bits[bitnum]; +end; + +function togglebit(const source: byte; bitnum: integer): byte; +begin + result:= source xor byte(bits[bitnum]); +end; + +function togglebit(const source: word; bitnum: integer): word; +begin + result:= source xor word(bits[bitnum]); +end; + +function togglebit(const source: longword; bitnum: integer): longword; +begin + result:= source xor bits[bitnum]; +end; + +function replacebits(const new,old,mask: byte): byte; +begin + result:= old and not mask or new and mask; +end; + +function replacebits(const new,old,mask: word): word; +begin + result:= old and not mask or new and mask; +end; + +function replacebits(const new,old,mask: longword): longword; +begin + result:= old and not mask or new and mask; +end; + +function replacebits1(var dest: byte; const value,mask: byte): boolean; +begin + result:= (dest xor value) and mask <> 0; + if result then begin + dest:= dest and not mask or value and mask + end; +end; + +function replacebits1(var dest: word; + const value,mask: word): boolean; overload; +begin + result:= (dest xor value) and mask <> 0; + if result then begin + dest:= dest and not mask or value and mask + end; +end; + +function replacebits1(var dest: longword; + const value,mask: longword): boolean; overload; +begin + result:= (dest xor value) and mask <> 0; + if result then begin + dest:= dest and not mask or value and mask + end; +end; + +function bitschanged(const a,b,mask: byte): boolean; overload; +begin + result:= (a xor b) and mask <> 0; +end; + +function bitschanged(const a,b,mask: word): boolean; overload; +begin + result:= (a xor b) and mask <> 0; +end; + +function bitschanged(const a,b,mask: longword): boolean; overload; +begin + result:= (a xor b) and mask <> 0; +end; + +function setsinglebit(const new,old,mask: byte): byte; overload; +var + v1: byte; +begin + if new and mask = 0 then begin + result:= new and not mask; + end + else begin + v1:= (old xor new) and mask; + if v1 = 0 then begin + result:= new; //no change + end + else begin + result:= (new and not mask) or + bits[lowestbit(v1 and new)]; + end; + end; +end; + +function setsinglebit(const new,old,mask: word): word; overload; +var + v1: word; +begin + if new and mask = 0 then begin + result:= new and not mask; + end + else begin + v1:= (old xor new) and mask; + if v1 = 0 then begin + result:= new; //no change + end + else begin + result:= (new and not mask) or + bits[lowestbit(v1 and new)]; + end; + end; +end; + +function setsinglebit(const new,old,mask: longword): longword; overload; +var + v1: longword; +begin + if new and mask = 0 then begin + result:= new and not mask; + end + else begin + v1:= (old xor new) and mask; + if v1 = 0 then begin + result:= new; //no change + end + else begin + result:= (new and not mask) or + bits[lowestbit(v1 and new)]; + end; + end; +end; + +function setsinglebit(const new,old: byte; + const mask: array of byte): byte; +var + int1: integer; +begin + result:= new; + for int1:= 0 to high(mask) do begin + result:= setsinglebit(result,old,mask[int1]); + end; +end; + +function setsinglebit(const new,old: word; + const mask: array of word): word; +var + int1: integer; +begin + result:= new; + for int1:= 0 to high(mask) do begin + result:= setsinglebit(result,old,mask[int1]); + end; +end; +{$ifndef FPC} +function setsinglebitar8(const new,old: byte; + const mask: array of byte): byte; +var + int1: integer; +begin + result:= new; + for int1:= 0 to high(mask) do begin + result:= setsinglebit(result,old,mask[int1]); + end; +end; +function setsinglebitar16(const new,old: word; + const mask: array of word): word; +var + int1: integer; +begin + result:= new; + for int1:= 0 to high(mask) do begin + result:= setsinglebit(result,old,mask[int1]); + end; +end; + +function setsinglebitar32(const new,old: longword; + const mask: array of longword): longword; +var + int1: integer; +begin + result:= new; + for int1:= 0 to high(mask) do begin + result:= setsinglebit(result,old,mask[int1]); + end; +end; +{$endif} +function setsinglebit(const new,old: longword; + const mask: array of longword): longword; +var + int1: integer; +begin + result:= new; + for int1:= 0 to high(mask) do begin + result:= setsinglebit(result,old,mask[int1]); + end; +end; + +function checkbit(const value: byte; const bitnum: integer): boolean; overload; +begin + result:= value and bits[bitnum] <> 0; +end; + +function checkbit(const value: word; const bitnum: integer): boolean; overload; +begin + result:= value and bits[bitnum] <> 0; +end; + +function checkbit(const value: longword; const bitnum: integer): boolean; overload; +begin + result:= value and bits[bitnum] <> 0; +end; + + + +function roundint(const value: integer; const step: integer): integer; +var + int1: integer; +begin + int1:= step div 2; + if value < 0 then begin + int1:= -int1; + end; + result:= ((value + int1) div step) * step; +end; + +function scaleexp10(const value: int64; const exp: integer): int64; +begin + if exp < 0 then begin + result:= value div int64exp10ar[-exp]; + end + else begin + result:= value * int64exp10ar[exp]; + end; +end; + +function scaleexp10(const value: integer; const exp: integer): integer; +begin + if exp < 0 then begin + result:= value div intexp10ar[-exp]; + end + else begin + result:= value * intexp10ar[exp]; + end; +end; + +function scaleexp10(const value: currency; const exp: integer): currency; +begin +//{$ifdef FPC} +// if exp < 0 then begin +// int64(result):= int64(value) div int64exp10ar[-exp]; +// end +// else begin +// int64(result):= int64(value) * int64exp10ar[exp]; +// end; +//{$else} + if exp < 0 then begin + pint64(@result)^:= pint64(@value)^ div int64exp10ar[-exp]; + end + else begin + pint64(@result)^:= pint64(@value)^ * int64exp10ar[exp]; + end; +//{$endif} +end; + +procedure scaleexp101(var value: int64; const exp: integer); +begin + if exp < 0 then begin + value:= value div int64exp10ar[-exp]; + end + else begin + value:= value * int64exp10ar[exp]; + end; +end; + +procedure scaleexp101(var value: integer; const exp: integer); +begin + if exp < 0 then begin + value:= value div intexp10ar[-exp]; + end + else begin + value:= value * intexp10ar[exp]; + end; +end; + +procedure scaleexp101(var value: currency; const exp: integer); +begin +//{$ifdef FPC} +// if exp < 0 then begin +// int64(value):= int64(value) div int64exp10ar[-exp]; +// end +// else begin +// int64(value):= int64(value) * int64exp10ar[exp]; +// end; +//{$else} + if exp < 0 then begin + pint64(@value)^:= pint64(@value)^ div int64exp10ar[-exp]; + end + else begin + pint64(@value)^:= pint64(@value)^ * int64exp10ar[exp]; + end; +//{$endif} +end; + +procedure swaprgb1(var value: longword); +var + by1: byte; +begin + by1:= byte(value); + pchar(@value)^:= (pchar(@value)+2)^; + byte((pchar(@value)+2)^):= by1; +end; + +function swaprgb(const value: longword): longword; +begin + result:= value; + pchar(@result)^:= (pchar(@value)+2)^; + byte((pchar(@result)+2)^):= byte(value); +end; + +//todo: optimize + +procedure swapbytes1(var value: word); overload; +var + wo1: word; +begin + wo1:= value; + (pchar(@value))^:= (pchar(@wo1)+1)^; + (pchar(@value)+1)^:= (pchar(@wo1))^; +end; + +procedure swapbytes1(var value: longword); overload; +var + ca1: longword; + po1,po2: pchar; +begin + ca1:= value; + po1:= @value; + po2:= pchar(@ca1)+3; + po1^:= po2^; inc(po1); dec(po2); + po1^:= po2^; inc(po1); dec(po2); + po1^:= po2^; inc(po1); dec(po2); + po1^:= po2^; +end; + +function swapbytes(const value: word): word; overload; +begin + (pchar(@result))^:= (pchar(@value)+1)^; + (pchar(@result)+1)^:= (pchar(@value))^; +end; + +function swapbytes(const value: longword): longword; overload; +var + po1,po2: pchar; +begin + po1:= @result; + po2:= pchar(@value)+3; + po1^:= po2^; inc(po1); dec(po2); + po1^:= po2^; inc(po1); dec(po2); + po1^:= po2^; inc(po1); dec(po2); + po1^:= po2^; +end; + +function swapbits(const value: word): word; overload; + //value and result at different adresses! +begin + pbyte(pchar(@result))^:= bitreverse[pbyte(pchar(@value)+1)^]; + pbyte(pchar(@result)+1)^:= bitreverse[pbyte(pchar(@value))^]; +end; + +function swapbits(const value: longword): longword; overload; + //value and result at different adresses! +var + po1,po2: pbyte; +begin + po1:= @result; + po2:= pbyte(pchar(@value)+3); + po1^:= bitreverse[po2^]; inc(po1); dec(po2); + po1^:= bitreverse[po2^]; inc(po1); dec(po2); + po1^:= bitreverse[po2^]; inc(po1); dec(po2); + po1^:= bitreverse[po2^]; +end; + +procedure swapbits1(var value: word); overload; +var + wo1: word; +begin + wo1:= value; + value:= swapbits(wo1); +end; + +procedure swapbits1(var value: longword); overload; +var + lwo1: longword; +begin + lwo1:= value; + value:= swapbits(lwo1); +end; + +function iszero(address: pointer; count: integer): boolean; +var + int1: integer; +begin + result:= false; + for int1:= 0 to count - 1 do begin + if pbyte(address)^ <> 0 then begin + exit; + end; + inc(pbyte(address)); + end; + result:= true; +end; + +function highestbit(value: longword): integer; +//0-> first, 31-> last($80000000), -1-> none ($00000000) +begin + result:= -1; + while value <> 0 do begin + inc(result); + value:= value shr 1; + end; +end; + +function lowestbit(value: longword): integer; +//0-> first, 31-> last($80000000), -1-> none ($00000000) +begin + result:= -1; + if value <> 0 then begin + result:= 32; + while value <> 0 do begin + dec(result); + value:= value shl 1; + end; + end; +end; + +function nextpowerof2(const avalue: longword): longword; +var + int1: integer; +begin + int1:= highestbit(avalue); + if avalue - bits[int1] <> 0 then begin + result:= bits[int1+1]; + end + else begin + result:= avalue; + end; +end; + +function highestbit64(value: qword): integer; +//0-> first, 63-> last($8000000000000000), -1-> none ($0000000000000000) +begin + result:= -1; + while value <> 0 do begin + inc(result); + value:= value shr 1; + end; +end; + +function lowestbit64(value: qword): integer; +//0-> first, 63-> last($8000000000000000), -1-> none ($0000000000000000) +begin + result:= -1; + if value <> 0 then begin + result:= 64; + while value <> 0 do begin + dec(result); + value:= value shl 1; + end; + end; +end; + +function getmask(const mask: array of bitnumty): longword; +var + int1: integer; +begin + result:= 0; + for int1:= 0 to high(mask) do begin + result:= result or bits[mask[int1]]; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/msebucketlist.pas b/mseide-msegui/lib/common/kernel/msebucketlist.pas new file mode 100644 index 0000000..b179c35 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msebucketlist.pas @@ -0,0 +1,884 @@ +{ MSEgui Copyright (c) 1999-2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msebucketlist; +// +// deprecated, use t*hashdatalist in msehash.pas instead +// +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msestrings; + +const + defaultbucketcount = $20; + defaultgrowstep = 8; + +type + datastatety = (ds_empty,ds_data); + bucketty = record + count: integer; + keys: array of ptruint; //0-> free + datapo: pointer; + end; + pbucketty = ^bucketty; + bucketarty = array of bucketty; + + tbucketlist = class + private + fbuckets: bucketarty; + fsize: integer; + fmask1: longword; + fcapacitystep: integer; + fstepbucket,fstepindex: integer; + procedure invalidkey; + function bucketindex(const key: ptruint): integer; + protected + fcount: integer; + procedure freedata(var data); virtual; + procedure initdata(var data); virtual; + function add(const key: ptruint; const data): pointer; //key <> 0 + //returns pointer to new data, @data can be nil -> data inited with 0 + function internalfind(const key: ptruint; var bucket,index: integer): boolean; + function find(const key: ptruint): pointer; + function next: pointer; + public + constructor create(recordsize: integer; abucketcount: integer = defaultbucketcount); + destructor destroy; override; + procedure clear; + function count: integer; + function delete(const key: ptruint): boolean; //true if found + end; + + datastringty = record + key: string; + data: pointer; + end; + pdatastringty = ^datastringty; + + stringbucketty = array of datastringty; + stringbucketpoty = ^stringbucketty; + stringbucketarty = array of stringbucketty; + + thashedstrings = class + private + fbuckets: stringbucketarty; + fmask: longword; + fcapacitystep: integer; + fcount: integer; + fstepbucket,fstepindex: integer; + function getbucketcount: integer; + procedure setbucketcount(const Value: integer); + function internalfind(const key: string): pdatastringty; overload; + function internalfind(const key: lstringty): pdatastringty; overload; + public + constructor create; + procedure clear; virtual; + procedure add(const key: string; data: pointer = pointer($ffffffff)); overload; + //nil nicht erlaubt + procedure add(const keys: array of string; + startindex: pointer = pointer($00000001)); overload; + //data = arrayindex + startindex + procedure delete(const key: lstringty); overload; virtual; + procedure delete(const key: string); overload; + function find(const key: string): pointer; overload; //casesensitive + function find(const key: lstringty): pointer; overload; //casesensitive + function findi(const key: string): pointer; overload; //caseinsensitive + function findi(const key: lstringty): pointer; overload; //caseinsensitive + property bucketcount: integer read getbucketcount write setbucketcount default defaultbucketcount; + property count: integer read fcount; + function next: pdatastringty; + end; + + msedatastringty = record + key: msestring; + data: pointer; + end; + pmsedatastringty = ^msedatastringty; + + msestringbucketty = array of msedatastringty; + pmsestringbucketty = ^msestringbucketty; + msestringbucketarty = array of msestringbucketty; + + thashedmsestrings = class + private + fcount: integer; + fbuckets: msestringbucketarty; + fmask: longword; + fcapacitystep: integer; + fstepbucket,fstepindex: integer; + function getbucketcount: integer; + procedure setbucketcount(const Value: integer); + function internalfind(const key: msestring): pmsedatastringty; + public + constructor create; + procedure clear; virtual; + procedure add(const key: msestring; data: pointer = pointer($ffffffff)); overload; + procedure add(const keys: array of msestring; + startindex: pointer = pointer($00000001)); + overload; //data = arrayindex + startindex + procedure delete(const key: msestring); virtual; + function find(const key: msestring): pointer; overload; + function find(const key: lmsestringty): pointer; overload; + function findi(const key: msestring): pointer; overload; + function findi(const key: lmsestringty): pointer; overload; + property bucketcount: integer read getbucketcount write setbucketcount default defaultbucketcount; + property count: integer read fcount; + function next: pmsedatastringty; + end; + + thashedmsestringobjects = class(thashedmsestrings) + public + destructor destroy; override; + procedure clear; override; + procedure add(const key: msestring; aobject: tobject); + procedure delete(const key: msestring); override; + function find(const key: msestring): tobject; overload; + function find(const key: lmsestringty): tobject; overload; + function findi(const key: msestring): tobject; overload; + function findi(const key: lmsestringty): tobject; overload; + end; + + thashedstringobjects = class(thashedstrings) + public + destructor destroy; override; + procedure clear; override; + procedure add(const key: string; aobject: tobject); + procedure delete(const key: lstringty); override; + function find(const key: string): tobject; overload; + function find(const key: lstringty): tobject; overload; + function findi(const key: string): tobject; overload; + function findi(const key: lstringty): tobject; overload; + end; + +implementation +uses + sysutils,msehash; + +function maxbitmask(value: longword): longword; +begin + if value = 0 then begin + result:= 0; + end + else begin + result:= $ffffffff; + while value and $80000000 = 0 do begin + result:= result shr 1; + value:= value shl 1; + end; + end; +end; + +{ tbucketlist } + +constructor tbucketlist.create(recordsize: integer; + abucketcount: integer = defaultbucketcount); +begin + fcapacitystep:= defaultgrowstep; + fsize:= recordsize; + fmask1:= maxbitmask(abucketcount-1); + setlength(fbuckets,fmask1+1); +end; + +destructor tbucketlist.destroy; +begin + clear; + inherited; +end; + +function tbucketlist.bucketindex(const key: ptruint): integer; +begin + if key = 0 then begin + invalidkey; + end; + result:= (key xor (key shr 4)) and fmask1; +end; + +procedure tbucketlist.clear; +var + int1,int2: integer; + po1: pchar; +begin + for int1:= 0 to high(fbuckets) do begin + with fbuckets[int1] do begin + po1:= datapo; + if po1 <> nil then begin + for int2:= 0 to high(keys) do begin + if keys[int2] <> 0 then begin + freedata(po1^); + end; + inc(po1,fsize); + end; + freemem(datapo); + datapo:= nil; + setlength(keys,0); + count:= 0; + end; + end; + end; + fcount:= 0; +end; + +procedure tbucketlist.freedata(var data); +begin + //dummy +end; + +function tbucketlist.count: integer; +begin + result:= fcount; +end; + +procedure tbucketlist.initdata(var data); +begin + //dummy +end; + +function tbucketlist.add(const key: ptruint; const data): pointer; +var + int1: integer; +begin + with fbuckets[bucketindex(key)] do begin + if count >= length(keys) then begin + int1:= length(keys); + setlength(keys,length(keys)+fcapacitystep); + reallocmem(datapo,length(keys)*fsize); + end + else begin + int1:= high(keys); + while keys[int1] <> 0 do begin + dec(int1); + end; + end; + keys[int1]:= key; + result:= pchar(datapo) + int1*fsize; + if @data = nil then begin + fillchar(result^,fsize,0); + end + else begin + move(data,result^,fsize); + end; + inc(count); + inc(fcount); + initdata(result^); + end; +end; + +function tbucketlist.internalfind(const key: ptruint; var bucket,index: integer): boolean; +var + int1: integer; +begin + result:= false; + bucket:= bucketindex(key); + with fbuckets[bucket] do begin + for int1:= 0 to high(keys) do begin + if keys[int1] = key then begin + index:= int1; + result:= true; + break; + end; + end; + end; +end; + +function tbucketlist.delete(const key: ptruint): boolean; + //true if found +var + bucket,index: integer; +begin + result:= internalfind(key,bucket,index); + if result then begin + with fbuckets[bucket] do begin + freedata((pchar(datapo) + index*fsize)^); + dec(count); + keys[index]:= 0; + dec(fcount); + end; + end; +end; + +procedure tbucketlist.invalidkey; +begin + raise exception.Create('Invalid keyvalue.'); +end; + +function tbucketlist.find(const key: ptruint): pointer; +var + bucket,index: integer; +begin + if internalfind(key,bucket,index) then begin + result:= pchar(fbuckets[bucket].datapo) + index*fsize; + end + else begin + result:= nil; + end; +end; + +function tbucketlist.next: pointer; +begin + result:= nil; + if fcount > 0 then begin + inc(fstepindex); + repeat + if fstepbucket >= length(fbuckets) then begin + fstepbucket:= 0; + fstepindex:= 0; + end; + with fbuckets[fstepbucket] do begin + if fstepindex >= length(keys) then begin + inc(fstepbucket); + fstepindex:= 0; + end + else begin + if keys[fstepindex] <> 0 then begin + result:= pchar(datapo) + fstepindex*fsize; + end + else begin + inc(fstepindex); + end; + end; + end; + until result <> nil; + end; +end; + +{ thashedstrings } + +constructor thashedstrings.create; +begin + fcapacitystep:= defaultgrowstep; + setbucketcount(defaultbucketcount); +end; + +procedure thashedstrings.add(const key: string; data: pointer = pointer($ffffffff)); +var + po: stringbucketpoty; + po1: pdatastringty; + int1: integer; + freefound: boolean; +begin + if data = nil then begin + raise exception.create('nil not allowed.'); + end; + inc(fcount); + po:= @fbuckets[stringhash(key) and fmask]; + po1:= @po^[0]; + freefound:= false; + for int1:= 0 to high(po^) do begin + if po1^.data = nil then begin + freefound:= true; + break; + end; + inc(po1) + end; + if not freefound then begin + int1:= length(po^); + setlength(po^,int1+fcapacitystep); + po1:= @po^[int1]; + end; + po1^.key:= key; + po1^.data:= data; +end; + +procedure thashedstrings.add(const keys: array of string; + startindex: pointer = pointer($00000001)); +var + ca1: longword; +begin + if ptruint(length(keys)) + ptruint(startindex) <= ptruint(length(keys)) then begin + raise exception.create('nil not allowed.'); + end; + for ca1:= 0 to high(keys) do begin + add(keys[ca1],pointer(ca1+ptruint(startindex))); + end; +end; + +procedure thashedstrings.clear; +var + int1: integer; +begin + for int1:= 0 to high(fbuckets) do begin + fbuckets[int1]:= nil; + end; + fcount:= 0; +end; + +function thashedstrings.internalfind(const key: string): pdatastringty; +var + po: stringbucketpoty; + po1: pdatastringty; + int1: integer; +begin + result:= nil; + if fcount > 0 then begin + po:= @fbuckets[stringhash(key) and fmask]; + po1:= @po^[0]; + for int1:= 0 to high(po^) do begin + if (po1^.data <> nil) and (po1^.key = key) then begin + result:= po1; + break; + end; + inc(po1) + end; + end; +end; + +function thashedstrings.internalfind(const key: lstringty): pdatastringty; +var + po: stringbucketpoty; + po1: pdatastringty; + int1,int2: integer; +begin + result:= nil; + if fcount > 0 then begin + po:= @fbuckets[stringhash(key) and fmask]; + po1:= @po^[0]; + for int1:= 0 to high(po^) do begin + if po1^.data <> nil then begin + int2:= length(po1^.key); + if int2 > 0 then begin + if int2 < key.len then begin + int2:= key.len; + end; + if strlcomp(key.po,pointer(po1^.key),int2) = 0 then begin + result:= po1; + break; + end; + end; + end; + inc(po1) + end; + end; +end; + +function thashedstrings.find(const key: lstringty): pointer; +var + po1: pdatastringty; +begin + po1:= internalfind(key); + if po1 <> nil then begin + result:= po1^.data; + end + else begin + result:= nil; + end; +end; + +function thashedstrings.find(const key: string): pointer; +var + po1: pdatastringty; +begin + po1:= internalfind(key); + if po1 <> nil then begin + result:= po1^.data; + end + else begin + result:= nil; + end; +end; + + +function thashedstrings.findi(const key: string): pointer; +begin + if fcount > 0 then begin + result:= find(struppercase(key)); + end + else begin + result:= nil; + end; +end; + +function thashedstrings.findi(const key: lstringty): pointer; +begin + if fcount > 0 then begin + result:= find(struppercase(key)); + end + else begin + result:= nil; + end; +end; + +procedure thashedstrings.delete(const key: lstringty); +var + po1: pdatastringty; +begin + while true do begin + po1:= internalfind(key); + if po1 = nil then begin + break; + end; + po1^.data:= nil; + dec(fcount); + end; +end; + +procedure thashedstrings.delete(const key: string); +var + lstr1: lstringty; +begin + lstr1.len:= length(key); + lstr1.po:= pointer(key); + delete(lstr1); +end; + +function thashedstrings.getbucketcount: integer; +begin + result:= length(fbuckets); +end; + +procedure thashedstrings.setbucketcount(const Value: integer); +begin + fmask:= maxbitmask(value-1); + setlength(fbuckets,fmask+1); +end; + +function thashedstrings.next: pdatastringty; +begin + result:= nil; + if fcount > 0 then begin + inc(fstepindex); + repeat + if fstepbucket > high(fbuckets) then begin + fstepbucket:= 0; + fstepindex:= 0; + end; + if fstepindex > high(fbuckets[fstepbucket]) then begin + inc(fstepbucket); + fstepindex:= 0; + end + else begin + if fbuckets[fstepbucket][fstepindex].data <> nil then begin + result:= @fbuckets[fstepbucket][fstepindex]; + end + else begin + inc(fstepindex); + end; + end; + until result <> nil; + end; +end; + +{ thashedmsestrings } + +constructor thashedmsestrings.create; +begin + fcapacitystep:= defaultgrowstep; + setbucketcount(defaultbucketcount); +end; + +procedure thashedmsestrings.add(const key: msestring; + data: pointer = pointer($ffffffff)); +var + po: pmsestringbucketty; + po1: pmsedatastringty; + int1: integer; + freefound: boolean; +begin + if data = nil then begin + raise exception.create('nil not allowed.'); + end; + inc(fcount); + po:= @fbuckets[stringhash(key) and fmask]; + po1:= @po^[0]; + freefound:= false; + for int1:= 0 to high(po^) do begin + if po1^.data = nil then begin + freefound:= true; + break; + end; + inc(po1) + end; + if not freefound then begin + int1:= length(po^); + setlength(po^,int1+fcapacitystep); + po1:= @po^[int1]; + end; + po1^.key:= key; + po1^.data:= data; +end; + +procedure thashedmsestrings.add(const keys: array of msestring; + startindex: pointer = pointer($00000001)); +var + ca1: longword; +begin + if longword(length(keys)) + ptruint(startindex) <= longword(length(keys)) then begin + raise exception.create('nil not alowed.'); + end; + for ca1:= 0 to high(keys) do begin + add(keys[ca1],pointer(ca1+ptruint(startindex))); + end; +end; + +procedure thashedmsestrings.clear; +var + int1: integer; +begin + for int1:= 0 to high(fbuckets) do begin + fbuckets[int1]:= nil; + end; + fcount:= 0; +end; + +function thashedmsestrings.internalfind(const key: msestring): pmsedatastringty; +var + po: pmsestringbucketty; + po1: pmsedatastringty; + int1: integer; +begin + result:= nil; + if fcount > 0 then begin + po:= @fbuckets[stringhash(key) and fmask]; + po1:= @po^[0]; + for int1:= 0 to high(po^) do begin + if (po1^.data <> nil) and (po1^.key = key) then begin + result:= po1; + break; + end; + inc(po1) + end; + end; +end; + +function thashedmsestrings.find(const key: lmsestringty): pointer; +var + po: pmsestringbucketty; + po1: pmsedatastringty; + int1,int2: integer; +begin + result:= nil; + if fcount > 0 then begin + po:= @fbuckets[stringhash(key) and fmask]; + po1:= @po^[0]; + for int1:= 0 to high(po^) do begin + if po1^.data <> nil then begin + int2:= length(po1^.key); + if int2 > 0 then begin + if int2 < key.len then begin + int2:= key.len; + end; + if msestrlcomp(key.po,pointer(po1^.key),int2) = 0 then begin + result:= po1^.data; + break; + end; + end; + end; + inc(po1) + end; + end; +end; + +function thashedmsestrings.find(const key: msestring): pointer; +var + po1: pmsedatastringty; +begin + po1:= internalfind(key); + if po1 <> nil then begin + result:= po1^.data; + end + else begin + result:= nil; + end; +end; + +function thashedmsestrings.findi(const key: lmsestringty): pointer; +begin + result:= find(struppercase(key)); +end; + +function thashedmsestrings.findi(const key: msestring): pointer; +begin + if fcount > 0 then begin + result:= find(struppercase(key)); + end + else begin + result:= nil; + end; +end; + +procedure thashedmsestrings.delete(const key: msestring); +var + po1: pmsedatastringty; +begin + repeat + po1:= internalfind(key); + if po1 <> nil then begin + dec(fcount); + po1^.data:= nil; + end; + until po1 = nil; +end; + +function thashedmsestrings.getbucketcount: integer; +begin + result:= length(fbuckets); +end; + +procedure thashedmsestrings.setbucketcount(const Value: integer); +begin + fmask:= maxbitmask(value-1); + setlength(fbuckets,fmask+1); +end; + +function thashedmsestrings.next: pmsedatastringty; +begin + result:= nil; + if fcount > 0 then begin + inc(fstepindex); + repeat + if fstepbucket > high(fbuckets) then begin + fstepbucket:= 0; + fstepindex:= 0; + end; + if fstepindex > high(fbuckets[fstepbucket]) then begin + inc(fstepbucket); + fstepindex:= 0; + end + else begin + if fbuckets[fstepbucket][fstepindex].data <> nil then begin + result:= @fbuckets[fstepbucket][fstepindex]; + end + else begin + inc(fstepindex); + end; + end; + until result <> nil; + end; +end; + +{ thashedstringobjects } + +destructor thashedstringobjects.destroy; +begin + clear; + inherited; +end; + +procedure thashedstringobjects.clear; +var + int1,int2: integer; +begin + for int1:= 0 to high(fbuckets) do begin + if fbuckets[int1] <> nil then begin + for int2:= 0 to high(fbuckets[int1]) do begin + if fbuckets[int1][int2].data <> nil then begin + tobject(fbuckets[int1][int2].data).free; + end; + end; + end; + fbuckets[int1]:= nil; + end; + fcount:= 0; +end; + +procedure thashedstringobjects.add(const key: string; aobject: tobject); +begin + inherited add(key,aobject); +end; + +procedure thashedstringobjects.delete(const key: lstringty); +var + po1: pdatastringty; +begin + repeat + po1:= internalfind(key); + if po1 <> nil then begin + tobject(po1^.data).Free; + po1^.data:= nil; + dec(fcount); + end; + until po1 = nil; +end; + +function thashedstringobjects.find(const key: string): tobject; +begin + result:= tobject(inherited find(key)); +end; + +function thashedstringobjects.find(const key: lstringty): tobject; +begin + result:= tobject(inherited find(key)); +end; + +function thashedstringobjects.findi(const key: string): tobject; +begin + result:= tobject(inherited findi(key)); +end; + +function thashedstringobjects.findi(const key: lstringty): tobject; +begin + result:= tobject(inherited findi(key)); +end; + +{ thashedmsestringobjects } + +destructor thashedmsestringobjects.destroy; +begin + clear; + inherited; +end; + +procedure thashedmsestringobjects.clear; +var + int1,int2: integer; +begin + for int1:= 0 to high(fbuckets) do begin + if fbuckets[int1] <> nil then begin + for int2:= 0 to high(fbuckets[int1]) do begin + if fbuckets[int1][int2].data <> nil then begin + tobject(fbuckets[int1][int2].data).free; + end; + end; + end; + fbuckets[int1]:= nil; + end; + fcount:= 0; +end; + +procedure thashedmsestringobjects.add(const key: msestring; aobject: tobject); +begin + inherited add(key,aobject); +end; + +procedure thashedmsestringobjects.delete(const key: msestring); +var + po1: pmsedatastringty; +begin + repeat + po1:= internalfind(key); + if po1 <> nil then begin + tobject(po1^.data).Free; + po1^.data:= nil; + dec(fcount); + end; + until po1 = nil; +end; + +function thashedmsestringobjects.find(const key: msestring): tobject; +begin + result:= tobject(inherited find(key)); +end; + +function thashedmsestringobjects.find(const key: lmsestringty): tobject; +begin + result:= tobject(inherited find(key)); +end; + +function thashedmsestringobjects.findi(const key: msestring): tobject; +begin + result:= tobject(inherited findi(key)); +end; + +function thashedmsestringobjects.findi(const key: lmsestringty): tobject; +begin + result:= tobject(inherited findi(key)); +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/mseclasses.pas b/mseide-msegui/lib/common/kernel/mseclasses.pas new file mode 100644 index 0000000..774fdf3 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseclasses.pas @@ -0,0 +1,6100 @@ +{ MSEgui Copyright (c) 1999-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseclasses; +{$ifdef FPC} + {$mode objfpc}{$h+}{$interfaces corba} +{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} +{$ifndef mse_methodswap} + {$define mse_nomethodswap} +{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,mseglob,mseevent,msetypes,msestrings,sysutils,typinfo,mselist, + msegraphutils{$ifdef mse_with_ifi},mseifiglob{$endif} + {$ifndef FPC},classes_del{$endif}; + +{$if defined(FPC) and (fpc_fullversion >= 020403)} + {$define mse_fpc_2_4_3} +{$ifend} +{$if defined(FPC) and (fpc_fullversion >= 020400)} + {$define mse_fpc_2_4} +{$ifend} + +{$ifdef FPC} + {$ifdef mse_FPC_2_4} + {$define hascorbagetinterface} + {$endif} +const + s_ok = 0; +{$endif} + +const +{$ifdef linux} + {$ifdef CPU64} + platformtext = 'x86_64-linux'; + {$else} + {$ifdef CPUARM} + platformtext = 'arm-linux'; + {$else} + platformtext = 'i386-linux'; + {$endif} + {$endif} +{$else} + {$ifdef openbsd} + {$ifdef CPU64} + platformtext = 'x86_64-openbsd'; + {$else} + platformtext = 'i386-openbsd'; + {$endif} + {$else} + {$ifdef bsd} + {$ifdef CPU64} + platformtext = 'x86_64-bsd'; + {$else} + platformtext = 'i386-bsd'; + {$endif} + {$else} + {$ifdef cpu64} + platformtext = 'x86_64-win64'; + {$else} + platformtext = 'i386-win32'; + {$endif} + {$endif} + {$endif} +{$endif} + + moduleclassnamename = 'moduleclassname'; +// inheritedmoduleclassnamename = 'inheritedmoduleclassname'; + compilerdefaults = + '{$ifdef FPC}{$mode objfpc}{$h+}{$endif}'; + +type + tcomponentevent = class; + posteventoptionty = (peo_local,peo_first,peo_modaldefer); + posteventoptionsty = set of posteventoptionty; + + notifyeventty = procedure (const sender: tobject) of object; + componenteventty = procedure (const acomponent: tcomponent) of object; + checkeventty = function (const sender: tobject): boolean of object; + accepteventty = procedure (const sender: tobject; + var accept: boolean) of object; + eventeventty = procedure (const sender: tobject; + const aevent: tobjectevent) of object; + componenteventeventty = procedure (const sender: tobject; + const aevent: tcomponentevent) of object; + asynceventeventty = procedure (const sender: tobject; + var atag: integer) of object; + + booleanchangedeventty = procedure (const sender: tobject; + const avalue: boolean) of object; + stringchangedeventty = procedure (const sender: tobject; + const avalue: msestring) of object; + integerchangedeventty = procedure (const sender: tobject; + const avalue: integer) of object; + realchangedeventty = procedure (const sender: tobject; + const avalue: realty) of object; + + getintegereventty = function: integer of object; + getint64eventty = function: int64 of object; + getmsestringeventty = function: msestring of object; + getstringareventty = function: stringarty of object; + + updatestringeventty = procedure(const sender: tobject; + var avalue: msestring) of object; + updateansistringeventty = procedure(const sender: tobject; + var avalue: ansistring) of object; + updateintegereventty = procedure(const sender: tobject; + var avalue: integer) of object; + updateint64eventty = procedure(const sender: tobject; + var avalue: int64) of object; + updatepointereventty = procedure(const sender: tobject; + var avalue: pointer) of object; + updatebooleaneventty = procedure(const sender: tobject; + var avalue: boolean) of object; + updaterealeventty = procedure(const sender: tobject; + var avalue: real) of object; + updatedatetimeeventty = procedure(const sender: tobject; + var avalue: tdatetime) of object; + + setbooleaneventty = procedure(const sender: tobject; var avalue: boolean; + var accept: boolean) of object; + setstringeventty = procedure(const sender: tobject; var avalue: msestring; + var accept: boolean) of object; + setansistringeventty = procedure(const sender: tobject; var avalue: ansistring; + var accept: boolean) of object; + setintegereventty = procedure(const sender: tobject; var avalue: integer; + var accept: boolean) of object; + //equal parameters as setcoloreventty for tcoloredit! + setint64eventty = procedure(const sender: tobject; var avalue: int64; + var accept: boolean) of object; + setrealeventty = procedure(const sender: tobject; var avalue: realty; + var accept: boolean) of object; + setdatetimeeventty = procedure(const sender: tobject; var avalue: tdatetime; + var accept: boolean) of object; + + setbooleanindexeventty = procedure(const sender: tobject; var avalue: boolean; + var accept: boolean; const aindex: integer) of object; + setstringindexeventty = procedure(const sender: tobject; var avalue: msestring; + var accept: boolean; const aindex: integer) of object; + setansistringindexeventty = procedure(const sender: tobject; var avalue: ansistring; + var accept: boolean; const aindex: integer) of object; + setintegerindexeventty = procedure(const sender: tobject; var avalue: integer; + var accept: boolean; const aindex: integer) of object; + //equal parameters as setcoloreventty for tcoloredit! + setint64indexeventty = procedure(const sender: tobject; var avalue: int64; + var accept: boolean; const aindex: integer) of object; + setrealindexeventty = procedure(const sender: tobject; var avalue: realty; + var accept: boolean; const aindex: integer) of object; + setdatetimeindexeventty = procedure(const sender: tobject; var avalue: tdatetime; + var accept: boolean; const aindex: integer) of object; + + progresseventty = procedure(const sender: tobject; const avalue: real; + var acancel: boolean) of object; + + persistentarty = array of tpersistent; + persistentclassty = class of tpersistent; + + componentarty = array of tcomponent; + componentaty = array[0..0] of tcomponent; + pcomponentaty = ^componentaty; + + componentclassty = class of tcomponent; + + propinfopoarty = array of ppropinfo; + + tvirtualpersistent = class(tpersistent) + protected + procedure internalcreate; virtual; + public + constructor create; virtual; + end; + virtualpersistentclassty = class of tvirtualpersistent; + + townedpersistent = class(tvirtualpersistent) + protected + fowner: tobject; + public + constructor create(aowner: tobject); reintroduce; virtual; + property owner: tobject read fowner; + end; + + tlinkedobject = class; + + linkinfoty = record + source: pointer; //iobjectlink + dest: pointer; //iobjectlink + refcount: integer; + valuepo: pointer; + interfacetype: pointer; + end; + plinkinfoty = ^linkinfoty; + + linkinfoaty = array[0..0] of linkinfoty; + plinkinfoaty = ^linkinfoaty; + + plinkedobject = ^tlinkedobject; + tmsecomponent = class; + pmsecomponent = ^tmsecomponent; + pobjectlinker = ^tobjectlinker; + tlinkedpersistent = class; + plinkedpersistent = ^tlinkedpersistent; + + objectlinkprocty = procedure(const info: linkinfoty) of object; + objectlinkintfprocty = procedure(const alink: pointer) of object; + objectlinkfirstprocty = procedure(const info: linkinfoty; + var handled: boolean) of object; + objectlinkintffirstprocty = procedure(const alink: pointer; + var handled: boolean) of object; + + tobjectlinker = class(trecordlist) + private + fonevent: objectlinkeventty; + fownerintf: pointer; //iobjectlink; + finstancepo: pobjectlinker; + fnopack: integer; + procedure dopack; + procedure removelink(var item: linkinfoty; destroyed: boolean); + protected + function isempty(var item): boolean; override; +// function findsource(const item: linkinfoty): integer; + public + {$ifdef debugobjectlink} + debugon: boolean; + {$endif} + constructor create(const owner: iobjectlink; onevent: objectlinkeventty); + destructor destroy; override; + procedure link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); overload; + procedure link(const dest: tmsecomponent; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); overload; + procedure unlink(const source,dest: iobjectlink; valuepo: pointer = nil); overload; + //source = 1 -> dest destroyed + procedure unlink(const dest: tmsecomponent; valuepo: pointer = nil); overload; + function linkedobjects: objectarty; overload; + function linkedobjects(const ainterfacetype: pointer): objectarty; overload; + + procedure setlinkedvar(const linkintf: iobjectlink; + const source: iobjectlink; var dest: iobjectlink; + const ainterfacetype: pointer = nil); overload; + procedure setlinkedvar(const linkintf: iobjectlink; + const source: tlinkedobject; var dest: tlinkedobject; + const ainterfacetype: pointer = nil); overload; + procedure setlinkedvar(const linkintf: iobjectlink; + const source: tlinkedpersistent; + var dest: tlinkedpersistent; + const ainterfacetype: pointer = nil); overload; + procedure setlinkedvar(const linkintf: iobjectlink; + const source: tmsecomponent; var dest: tmsecomponent; + const ainterfacetype: pointer = nil); overload; + + procedure setlink(const linkintf: iobjectlink; + const source: tmsecomponent; var dest: tmsecomponent; + const ainterfacetype: pointer = nil); overload; + //no automatic nil setting + procedure sendevent(event: objecteventty); + procedure objevent(const sender: iobjectlink; const event: objecteventty); + procedure forall(const proc: objectlinkprocty; + const ainterfacetype: pointer); overload; + procedure forall(const proc: objectlinkintfprocty; + const ainterfacetype: pointer); overload; + procedure forfirst(const proc: objectlinkfirstprocty; + const ainterfacetype: pointer); overload; + procedure forfirst(const proc: objectlinkintffirstprocty; + const ainterfacetype: pointer); overload; + end; + + tlinkedobject = class(tnullinterfacedobject,iobjectlink) + private + protected + fobjectlinker: tobjectlinker; + function getobjectlinker: tobjectlinker; + procedure objectevent(const sender: tobject; + const event: objecteventty); virtual; + procedure setlinkedvar(const source: tmsecomponent; var dest: tmsecomponent; + const linkintf: iobjectlink = nil); overload; + procedure setlinkedvar(const source: tlinkedobject; var dest: tlinkedobject; + const linkintf: iobjectlink = nil); overload; + //iobjectlink + procedure link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); + procedure unlink(const source,dest: iobjectlink; valuepo: pointer = nil); + procedure objevent(const sender: iobjectlink; + const event: objecteventty); virtual; + function getinstance: tobject; + public + destructor destroy; override; +// property objectlinker: tobjectlinker read getobjectlinker; + end; + + tlinkedrecordlist = class(trecordlist,iobjectlink) + protected + fobjectlinker: tobjectlinker; + function getobjectlinker: tobjectlinker; + procedure objectevent(const sender: tobject; + const event: objecteventty); virtual; + procedure setlinkedvar(const source: tmsecomponent; var dest: tmsecomponent; + const linkintf: iobjectlink = nil); overload; + procedure setlinkedvar(const source: tlinkedobject; var dest: tlinkedobject; + const linkintf: iobjectlink = nil); overload; + //iobjectlink + procedure link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); + procedure unlink(const source,dest: iobjectlink; valuepo: pointer = nil); + procedure objevent(const sender: iobjectlink; + const event: objecteventty); virtual; + function getinstance: tobject; + public + destructor destroy; override; + end; + +(* + tnullinterfacedobject = class(tobject,iunknown) + protected + function _addref: integer; + {$ifdef mswindows}stdcall{$else} cdecl{$endif}; + function _release: integer; + {$ifdef mswindows}stdcall{$else} cdecl{$endif}; + function queryinterface({$ifdef fpc_has_constref}constref{$else}const{$endif} + iid: tguid; out obj): hresult; + {$ifdef mswindows}stdcall{$else} cdecl{$endif}; + end; +*) + tnullinterfacedpersistent = class(tvirtualpersistent,iunknown) + protected + {$ifdef FPC} + function _addref: integer; + {$ifdef mswindows}stdcall{$else} cdecl{$endif}; + function _release: integer; + {$ifdef mswindows}stdcall{$else} cdecl{$endif}; + function QueryInterface({$ifdef fpc_has_constref}constref{$else}const{$endif} + IID: TGUID; out Obj): HResult; + {$ifdef mswindows}stdcall{$else} cdecl{$endif}; + {$endif} + end; + + toptionalpersistent = class(tnullinterfacedpersistent) + private + procedure writedummy(writer: twriter); + protected + procedure readdummy(reader: treader); + procedure defineproperties(filer : tfiler); override; + function isoptional: boolean; virtual; + end; + + tlinkedpersistent = class(tnullinterfacedpersistent,iobjectlink) + private + protected + fobjectlinker: tobjectlinker; + function getobjectlinker: tobjectlinker; + procedure objectevent(const sender: tobject; + const event: objecteventty); virtual; + //iobjectlink + procedure link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); + procedure unlink(const source,dest: iobjectlink; valuepo: pointer = nil); + procedure objevent(const sender: iobjectlink; + const event: objecteventty); virtual; + function getinstance: tobject; virtual; + + public + destructor destroy; override; + procedure setlinkedvar(const source: iobjectlink; var dest: iobjectlink; + const linkintf: iobjectlink = nil); overload; + procedure setlinkedvar(const source: tmsecomponent; var dest: tmsecomponent; + const linkintf: iobjectlink = nil); overload; + procedure setlinkedvar(const source: tlinkedobject; var dest: tlinkedobject; + const linkintf: iobjectlink = nil); overload; + procedure setlinkedvar(const source: tlinkedpersistent; + var dest: tlinkedpersistent; + const linkintf: iobjectlink = nil); overload; + end; + + tlinkedoptionalpersistent = class(tlinkedpersistent) + private + procedure readdummy(reader: treader); + procedure writedummy(writer: twriter); + protected + procedure defineproperties(filer : tfiler); override; + function isoptional: boolean; virtual; + end; + + teventpersistent = class(tlinkedpersistent,ievent) + protected + procedure receiveevent(const event: tobjectevent); virtual; + public + end; + + townedeventpersistent = class(tlinkedpersistent) + protected + fowner: tobject; + public + constructor create(aowner: tobject); reintroduce; virtual; + property owner: tobject read fowner; + end; + + teventobject = class(tlinkedobject,ievent) + protected + procedure receiveevent(const event: tobjectevent); virtual; + public + end; + + componenteventstatety = (ces_processed,ces_callchildren); + componenteventstatesty = set of componenteventstatety; + + tcomponentevent = class(tobjectevent) + private + fsender: tobject; + public + state: componenteventstatesty; + tag: integer; + constructor create(const asender: tobject; const atag: integer = 0; + const callchildren: boolean = true); + overload; + property sender: tobject read fsender; + end; + + msecomponentstatety = (cs_ismodule,cs_beginreadproc,cs_endreadproc, + cs_loadedproc, + cs_inheritedloading,cs_noload,cs_tmpmodule, + cs_subcompref, //subcomponent can be referenced + //by component properties + cs_parentwidgetrect //info for designer, example ttabpage +// cs_skinloaded + {cs_hasskin,cs_noskin}{,cs_updateskinproc}); + msecomponentstatesty = set of msecomponentstatety; + + createprocty = procedure of object; + + skinoptionty = (sko_container); + skinoptionsty = set of skinoptionty; + + skinobjectkindty = (sok_component,sok_widget,sok_groupbox, + sok_simplebutton,sok_databutton,sok_slider, + sok_tabbar,sok_tabpage,sok_toolbar, + sok_splitter,sok_dispwidget, + sok_edit,sok_dataedit,sok_booleanedit, + sok_grid, + sok_mainmenu,sok_popupmenu,sok_mainmenuwidget, + sok_user); + + skininfoty = record + instance: tobject; + userkind: integer; + group: integer; + objectkind: skinobjectkindty; + options: skinoptionsty; + end; + + tmsecomponent = class(tcomponent,ievent + {$ifdef mse_with_ifi},iificommand,iificlient{$endif}) + private + fonbeforeupdateskin: notifyeventty; + fonafterupdateskin: notifyeventty; + procedure readmoduleclassname(reader: treader); + procedure writemoduleclassname(writer: twriter); + procedure beginread;// virtual; + procedure endread; + protected + fmsecomponentstate: msecomponentstatesty; + fobjectlinker: tobjectlinker; + factualclassname: pshortstring; + fancestorclassname: string; + fhelpcontext: msestring; + +{$ifdef mse_with_ifi} + fifiserverintf: iifiserver; + //iificlient + procedure setifiserverintf(const aintf: iifiserver); + function getdefaultifilink: iificlient; virtual; + function getifidatatype: listdatatypety virtual; + //iificommand + procedure executeificommand(var acommand: ificommandcodety); virtual; +{$endif} + + function getancestorclassname: string; + function getmsecomponentstate: msecomponentstatesty; + function getobjectlinker: tobjectlinker; + procedure objectevent(const sender: tobject; + const event: objecteventty); virtual; + procedure dobeginread; virtual; + procedure doendread; virtual; + procedure readstate(reader: treader); override; + procedure loaded; override; + procedure validaterename(acomponent: tcomponent; + const curname, newname: string); override; + procedure setchildorder(child: tcomponent; order: integer); override; + procedure sendchangeevent(const aevent: objecteventty = oe_changed); + function linkcount: integer; + function candestroyevent(const event: tmethod): boolean; + function gethelpcontext: msestring; virtual; + + class function classskininfo: skininfoty; virtual; + function skininfo: skininfoty; virtual; + function hasskin: boolean; virtual; + function getcomponentinstance: tcomponent; + procedure getcompchildren(const proc: tgetchildproc; + const root: tcomponent); + + //iobjectlink + procedure link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); + procedure unlink(const source,dest: iobjectlink; valuepo: pointer = nil); virtual; + procedure objevent(const sender: iobjectlink; + const event: objecteventty); virtual; + function getinstance: tobject; + function getcomponent: tcomponent; + //ievent + procedure receiveevent(const event: tobjectevent); virtual; + + procedure designselected(const selected: boolean); virtual; + procedure setlinkedvar(const source: iobjectlink; var dest: iobjectlink; + const linkintf: iobjectlink = nil); overload; + procedure setlinkedvar(const source: tmsecomponent; var dest: tmsecomponent; + const linkintf: iobjectlink = nil); overload; + procedure setlinkedvar(const source: tlinkedobject; var dest: tlinkedobject; + const linkintf: iobjectlink = nil); overload; + procedure setlinkedvar(const source: tlinkedpersistent; + var dest: tlinkedpersistent; + const linkintf: iobjectlink = nil); overload; + function getactualclassname: string; + class function getmoduleclassname: string; virtual; + class function hasresource: boolean; virtual; + procedure defineproperties(filer: tfiler); override; + procedure componentevent(const event: tcomponentevent); virtual; + procedure doasyncevent(var atag: integer); virtual; + procedure doafterload; virtual; + public + destructor destroy; override; + procedure writestate(writer: twriter); override; + procedure updateskin(const recursive: boolean = false); virtual; +// procedure removeskin(const recursive: boolean = false); virtual; + function loading: boolean; reintroduce; + //this hides FPC tcomponent.loading which is not Delphi compatible + {$ifdef FPC} + procedure setinline(value: boolean); + procedure setancestor(value: boolean); + {$endif} + procedure setsubcompref; + function canevent(const event: tmethod): boolean; + procedure setoptionalobject(const value: tpersistent; var instance; + createproc: createprocty); + procedure getoptionalobject(const instance: tobject; createproc: createprocty); + function getcorbainterface(const aintf: ptypeinfo; out obj) : boolean; +// function getcorbainterface(const aintf: tguid; out obj) : boolean; + procedure initnewcomponent(const ascale: real); virtual; + function checkowned(component: tcomponent): boolean; + //true if component is owned or self + function checkowner(component: tcomponent): boolean; + //true if component is owner or self + function rootowner: tcomponent; +// function rootcomponent: tcomponent; //rootowner or self + function getrootcomponentpath: componentarty; + function linkedobjects: objectarty; + //returns items of objeclinker and free notify list + + procedure sendcomponentevent(const event: tcomponentevent; + const destroyevent: boolean = true); + //event will be destroyed if not async + procedure sendrootcomponentevent(const event: tcomponentevent; + const destroyevent: boolean = true); + //event will be destroyed if not async + procedure asyncevent(atag: integer = 0; + const aoptions: posteventoptionsty = []); + //posts event for doasyncevent to self + procedure postcomponentevent(const event: tcomponentevent; + const aoptions: posteventoptionsty = []); + + property moduleclassname: string read getmoduleclassname; + property actualclassname: string read getactualclassname; + property msecomponentstate: msecomponentstatesty read fmsecomponentstate; + property onbeforeupdateskin: notifyeventty read fonbeforeupdateskin + write fonbeforeupdateskin; + property onafterupdateskin: notifyeventty read fonafterupdateskin + write fonafterupdateskin; + published + property helpcontext: msestring read gethelpcontext write fhelpcontext; + end; + + msecomponenteventty = procedure(const sender: tmsecomponent) of object; + msecomponentclassty = class of tmsecomponent; + msecomponentarty = array of tmsecomponent; + + tlinkedqueue = class(tpointerqueue,iobjectlink) + private + fobjectlinker: tobjectlinker; + fainstance: tobject; + fownsobjects: boolean; + function getitems(const index: integer): iobjectlink; + procedure setitems(const index: integer; const Value: iobjectlink); + procedure objectevent(const sender: tobject; const event: objecteventty); + //iobjectlink + procedure link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); + procedure unlink(const source,dest: iobjectlink; valuepo: pointer = nil); + procedure objevent(const sender: iobjectlink; const event: objecteventty); + function getinstance: tobject; + protected + procedure finalizeitem(var item: pointer); override; + procedure linkdestroyed(const alink: iobjectlink); virtual; + public + constructor create(aownsobjects: boolean); + destructor destroy; override; + function destroying: boolean; + function add(const value: iobjectlink): integer; + procedure insert(const index: integer; const value: iobjectlink); reintroduce; + function getfirst: iobjectlink; + function getlast: iobjectlink; + procedure sendchangenotification(sender: tobject); + property items[const index: integer]: iobjectlink read getitems write setitems; default; + property ownsobjects: boolean read fownsobjects write fownsobjects; + end; + + tlinkedobjectqueue = class(tlinkedqueue,iobjectlink) + private + protected + function getitems(const index: integer): tlinkedobject; + procedure setitems(const index: integer; const Value: tlinkedobject); + public + function findobject(const aobject: tlinkedobject): integer; + //-1 if not found + function add(const value: tlinkedobject): integer; + procedure insert(const index: integer; const value: tlinkedobject); reintroduce; + function getfirst: tlinkedobject; + function getlast: tlinkedobject; + property items[const index: integer]: tlinkedobject read getitems write setitems; default; + end; + + tpersistentqueue = class(tlinkedqueue,iobjectlink) + private + function getitems(const index: integer): tlinkedpersistent; + procedure setitems(const index: integer; const Value: tlinkedpersistent); + protected + public + function findobject(const aobject: tlinkedpersistent): integer; + //-1 if not found + procedure add(const value: tlinkedpersistent); + procedure insert(const index: integer; const value: tlinkedpersistent); reintroduce; + function getfirst: tlinkedpersistent; + function getlast: tlinkedpersistent; + property items[const index: integer]: tlinkedpersistent read getitems write setitems; default; + end; + + tcomponentqueue = class(tlinkedqueue,iobjectlink) + private + function getitems(const index: integer): tmsecomponent; + procedure setitems(const index: integer; const Value: tmsecomponent); + protected + public + function findobject(const aobject: tmsecomponent): integer; + //-1 if not found + function add(const value: tmsecomponent): integer; + procedure insert(const index: integer; const value: tmsecomponent); reintroduce; + function getfirst: tmsecomponent; + function getlast: tmsecomponent; + property items[const index: integer]: tmsecomponent read getitems write setitems; default; + end; + + tobjectlinkrecordlist = class(trecordlist,iobjectlink) + private + protected + fobjectlinker: tobjectlinker; + procedure finalizerecord(var item); override; + procedure dounlink(var item); virtual; abstract; + procedure itemdestroyed(const sender: iobjectlink); virtual; abstract; + //iobjectlink + procedure link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); + procedure unlink(const source,dest: iobjectlink; valuepo: pointer = nil); + procedure objevent(const sender: iobjectlink; const event: objecteventty); + function getinstance: tobject; + public + constructor create(arecordsize: integer; aoptions: recordliststatesty = []); + destructor destroy; override; + end; + + objectdataty = record + size: integer; + data: array[0..0] of byte; + end; + pobjectdataty = ^objectdataty; + + tpersistenttemplate = class(tlinkedpersistent) + private + fonchange: notifyeventty; + protected + fowner: tmsecomponent; + procedure changed; + function getinfosize: integer; virtual; abstract; + function getinfoad: pointer; virtual; abstract; + procedure copyinfo(const source: tpersistenttemplate); virtual; + procedure assignto(dest: tpersistent); override; + procedure doassignto(dest: tpersistent); virtual; abstract; + public + constructor create(const owner: tmsecomponent; const onchange: notifyeventty); + reintroduce; virtual; + procedure assign(source: tpersistent); override; + end; + + templateclassty = class of tpersistenttemplate; + + ttemplatecontainer = class(tmsecomponent) + protected + ftemplate: tpersistent; + procedure assignto(dest: tpersistent); override; + function gettemplateclass: templateclassty; virtual; abstract; + procedure templatechanged(const sender: tobject); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + end; + + tnotifylist = class(tmethodlist) + public + procedure notify(const sender: tobject); + end; + + tmodulelist = class(tcomponentqueue) + protected + flocked: integer; + procedure ancestornotfound(Reader: TReader; const ComponentName: string; + ComponentClass: TPersistentClass; var Component: TComponent); + public + function findmodulebyname(const name: string): tcomponent; + procedure lock; + procedure unlock; + end; + + getchildreneventty = procedure (const sender: tmsecomponent; + const proc: tgetchildproc; const root: tcomponent) of object; + + twritermse = class(twriter) + private +// fgetchildrenbefore: getchildreneventty; + fancestorlookuplevel: integer; + fchildlevel: integer; + fnoancestor: boolean; //used for copy paste of inherited components + fmasterancestor: boolean; //used to restore field class in tpersistentfields + {$ifndef FPC} + FAncestors: TStringList; + fcurrentpos: integer; + fancestorpos: integer; + fsignaturewritten: boolean; + {$endif} + procedure DetermineAncestor(Component : TComponent); + procedure AddToAncestorList(Component: TComponent); + procedure DoFindAncestor(Component : TComponent); + protected + frootrootancestor: tcomponent; + frootroot: tcomponent; + function rootcompname(const acomp: tcomponent; + const aroot: tcomponent): string; overload; + function rootcompname(const acomp: tcomponent; + arootlevel: integer): string; overload; + procedure getchildren1(const acomp: tcomponent; + const proc: tgetchildproc; const aroot: tcomponent); + procedure WriteChildren(Component : TComponent); + procedure WriteComponentData(Instance: TComponent); + function getclassname(const aobj: tobject): shortstring; override; + public + constructor create(const stream: tstream; const bufsize: integer; + const anoancestor: boolean = false; + const amasterancestor: boolean = false); + destructor destroy; override; + procedure WriteComponent(Component: TComponent); + procedure writedescendent(const aroot: tcomponent; + const aancestor: tcomponent); + procedure writerootcomponent(aroot: tcomponent); + property masterancestor: boolean read fmasterancestor; + end; + + tobjectdatastream = class(tcustommemorystream) + public + constructor create(data: pobjectdataty); + function Write(const Buffer; Count: Longint): Longint; override; + end; + + setsplitpairty = record + oldenum,newenum: string + end; + setsplitinfoty = record + maintype: ptypeinfo; + splittype: ptypeinfo; + enums: array of setsplitpairty; + end; + + writerecordprocty = procedure(const writer: twriter; const data); + readrecordprocty = procedure(const reader: treader; var data); + +function ownscomponent(const owner: tcomponent; const child: tcomponent): boolean; +function ownernamepath(const acomponent: tcomponent): string; + //namepath from root to acomponent separated by '.' +function ownernamepath(const aroot: tcomponent; + const acomponent: tcomponent): string; + //namepath from aroot to acomponent separated by '.' + //excluding aroot +function namepathowner(const acomponent: tcomponent): string; + //namepath from acomponent to root separated by '.' +function getnumberedname(const acomp: tcomponent; + const namebase: string): string; +function ownercomponentpath(const acomponent: tcomponent): componentarty; + //componentpath from root to acomponent +function componentpathowner(const acomponent: tcomponent): componentarty; + //componentpath from acomponent to root +function rootcomponent(const acomponent: tcomponent): tcomponent; +procedure setcomponentorder(const owner: tcomponent; const anames: msestringarty); +function getcomponentchildren(const acomp: tcomponent; + const aroot: tcomponent; + const nestedowners: boolean = false; + const nestedparents: boolean = false): componentarty; +function getpropinfoar(const obj: tobject): propinfopoarty; overload; +function getpropinfoar(const atypeinfo: ptypeinfo): propinfopoarty; overload; + +procedure createobjectlinker(const owner: iobjectlink; onevent: objectlinkeventty; + var instance: tobjectlinker); + //sets finstancepo +procedure getoptionalobject(const componentstate: tcomponentstate; + const instance: tobject; createproc: createprocty); overload; +procedure getoptionalobject(const aowner: tcomponent; //can be nil + const instance: tobject; createproc: createprocty); overload; +procedure getoptionalobject(const componentstate: tcomponentstate; + var instance: tvirtualpersistent; + const aclass: virtualpersistentclassty); overload; +procedure setoptionalobject(const componentstate: tcomponentstate; + const value: tpersistent; var instance; + createproc: createprocty); overload; +procedure setoptionalobject(const aowner: tcomponent; //can be nil + const value: tpersistent; var instance; + createproc: createprocty); overload; +procedure setoptionalobject(const componentstate: tcomponentstate; + const value: tvirtualpersistent; var instance; + const aclass: virtualpersistentclassty); overload; +procedure setlinkedcomponent(const sender: iobjectlink; const source: tmsecomponent; + var instance: tmsecomponent; ainterfacetype: pointer = nil); + +function createmodule(aowner: tcomponent; instanceclass: msecomponentclassty; + var reference): tmsecomponent; +procedure registerobjectdata(datapo: pobjectdataty; + objectclass: tpersistentclass; name: string = ''); overload; +procedure registerobjectdata(datapo: pobjectdataty; + const objectclassname: string; const name: string = ''); overload; + //language overrides +procedure unregisterobjectdata(const objectclassname: string; const name: string = ''); + //language overrides +procedure resetchangedmodules; +procedure reloadchangedmodules; +procedure reloadmodules; + +procedure msebegingloballoading; //recursive +procedure mseendgloballoading; //calls notifygloballoading in level 0 + +procedure reloadmsecomponent(Instance: tmsecomponent); +function initmsecomponent(instance: tmsecomponent; rootancestor: tclass; + out needsloading: boolean): boolean; + //true if root and all inherited classes loaded +function initmsecomponent1(instance: tcomponent; rootancestor: tclass): boolean; + //true if root and all inherited classes loaded +function findancestorcomponent(const areader: treader; + const componentname: string): tcomponent; +procedure loadmsemodule(const instance: tmsecomponent; const rootancestor: tclass); +function findmoduledata(const aclassname: string; + out aparentclassname: string): pobjectdataty; + +function getfproppath(const writer:twriter): string; +procedure setfproppath(const writer:twriter; const value: string); + +procedure freecomponents(const acomponents: componentarty); + //uses freenotification +function copycomponent(const source: tcomponent; const aowner: tcomponent = nil; + const onfindancestor: tfindancestorevent = nil; + const onfindcomponentclass: tfindcomponentclassevent = nil; + const oncreatecomponent: tcreatecomponentevent = nil; + const onancestornotfound: tancestornotfoundevent = nil): tcomponent; + //copy by stream.writecomponent, readcomponent +procedure refreshancestor(var deletedcomps: componentarty; + const descendent,newancestor,oldancestor: tcomponent; + const revert: boolean; + const onfindancestor: tfindancestorevent = nil; + const onfindcomponentclass: tfindcomponentclassevent = nil; + const oncreatecomponent: tcreatecomponentevent = nil; + {$ifdef mse_nomethodswap} + const onsetmethodproperty: tsetmethodpropertyevent = nil; + const onwritemethodproperty: twritemethodpropertyevent = nil; + const newcomponent: pboolean = nil + {$else} + const onfindmethod: tfindmethodevent = nil; + const sourcemethodtab: pointer = nil; + const destmethodtab: pointer = nil + {$endif}); + +procedure initinline(const acomponent: tcomponent); + //sets inline, resets ancestor, sets ancestor of children +procedure checkinline(const acomponent: tcomponent); + //resets csancestor of csinline components +procedure initrootdescendent(const acomponent: tcomponent); + //clears csinline flags of acomoponent and children, + // sets csancestor +function issubcomponent(const root,child: tcomponent): boolean; +function fixupsetchildorder(const sender: tcomponent; + const child: tcomponent; const order: integer): boolean; + //true if handled +function findcomponentbynamepath(const namepath: string): tcomponent; +function findcomponentbynamepath(const namepath: string; + const root: tcomponent): tcomponent; +function findsubcomponentbynamepath(const namepath: string; + const root: tcomponent): tcomponent; + //name path does not contain root +function getlinkedcomponents(const acomponent: tcomponent): componentarty; + //returns items of free notify list + + +procedure lockfindglobalcomponent; //switch of findglobalcomponent +procedure unlockfindglobalcomponent; //switch on findglobalcomponent +function findglobalcomponentlocked: boolean; + +function getenumnames(const atypeinfo: ptypeinfo): msestringarty; +function getclasspropvalue(const instance: tobject; const apropname: string; + const aclass: tclass): tobject; +function getclasspropvalue(const instance: tobject; const apropname: string; + const aclass: tclass; out avalue: tobject): boolean; + + +procedure nosupportfor(const sender: tcomponent; const avalue: tcomponent; + const ainterface: ptypeinfo); +function getcorbainterface(const aobject: tobject; const aintf: ptypeinfo; + out obj) : boolean; +procedure checkcorbainterface(const sender: tcomponent; + const avalue: tcomponent; + const ainterface: ptypeinfo; out obj); +function isinterface(const actual: ptypeinfo; const wanted: ptypeinfo): boolean; +function isinterfaceornil(const actual: ptypeinfo; const wanted: ptypeinfo): boolean; + +function checkcanevent(const acomponent: tcomponent; + const event: tmethod): boolean; overload; +function checkcanevent(const event: tmethod): boolean; + {$ifdef FPC}inline;{$endif} overload; + +procedure readstringar(const reader: treader; out ar: stringarty); overload; +procedure readstringar(const reader: treader; out ar: msestringarty); overload; +procedure writestringar(const writer: twriter; const ar: stringarty); overload; +procedure writestringar(const writer: twriter; const ar: msestringarty); overload; +procedure readintar(const reader: treader; out ar: int32arty); +procedure readintar(const reader: treader; out ar: int16arty); +procedure writeintar(const writer: twriter; const ar: int32arty); +procedure writeintar(const writer: twriter; const ar: int16arty); +procedure readrecordar(const reader: treader; out ar; //array of type + const typeinfo: pdynarraytypeinfo; const readproc: readrecordprocty); +procedure writerecordar(const writer: twriter; const ar; //array of type + const typeinfo: pdynarraytypeinfo; const writeproc: writerecordprocty); + +function valuescaletorange(const reader: treader): real; + +function swapmethodtable(const instance: tobject; const newtable: pointer): pointer; + +function checkenumvalue(typeinfo : ptypeinfo;const name : string) : integer; + //exception on error +function readenum(const reader: treader; const atypeinfo: ptypeinfo): integer; +procedure writeenum(const writer: twriter; const value: integer; + const atypeinfo: ptypeinfo); +function readset(const reader: treader; const atypeinfo: ptypeinfo): tintegerset; +procedure writeset(const writer: twriter; const value: tintegerset; + const atypeinfo: ptypeinfo); +function readsplitset(const reader: treader; const info: setsplitinfoty; + out set1,set2: tintegerset): boolean; + //true if splitted +function setloading(const acomponent: tcomponent; const avalue: boolean): boolean; + //returns old value + +function alive(const acomponent: tcomponent): boolean; + +procedure componentexception(const acomponent: tcomponent; + const atext: msestring); +type + skineventty = procedure(const ainfo: skininfoty) of object; +var + oninitskinobject: skineventty; +//threadvar +// onstreaminggetchildren: getchildreneventty; + +function getcomponentlist(const acomponent: tcomponent): tfplist; +procedure clearcomponentlist(const acomponent: tcomponent); +procedure clearpastedcomponents; +procedure addpastedcomponentname(const acomp: tcomponent); +function findpastedcomponent(const origname: string): tcomponent; +function findpastedcomponentname(const comp: tcomponent): string; + +procedure copyvarrec(const source: tvarrec; const dest: pointer); +procedure matchparams(const aparam: array of const; + const defaults: array of const; const dest: array of pointer); + + +{$ifdef mse_debug} +procedure dumptextstream(const stream: tstream; const atext: string); +procedure dumpcomponent(const acomp: tcomponent; const atext: string = ''); +procedure dumpstreamcomponent(const acomp: tcomponent; const atext: string = ''); +procedure debugstreamout(const stream: tstream; const atext: string); +procedure debugbinstreamout(const acomp,aancestor: tcomponent; + const aonfindancestor: tfindancestorevent; const atext: string); +function debugstringarty(const astringar: stringarty): string; +function debugcompname(const acomponent: tcomponent): string; +function debugcompnames(const acomponents: componentarty): string; +function debugcomprootname(const acomponent: tcomponent): string; +function debugcomprootnames(const acomponents: componentarty): string; +{$endif} + +implementation +uses +{$ifdef debugobjectlink} + msegui,mseformatstr, +{$endif} + mseapplication, +{$ifdef mse_debug} + mseobjecttext, +{$endif} + msestream,msesys,msedatalist,msedatamodules,rtlconsts,msesysutils, + msearrayutils,msestreaming + {$ifdef mswindows} + ,windows +{$endif} +; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tpersistent1 = class(tpersistent); + tcomponent1 = class(tcomponent); + twriter1 = class(twriter); + treader1 = class(treader); +{$ifndef FPC} +const + filersignature : array[1..4] of char = 'TPF0'; +type +{$endif} +{ + tobjectdatastream = class(tcustommemorystream) + public + constructor create(data: pobjectdataty); + function Write(const Buffer; Count: Longint): Longint; override; + end; +} + objectdatainfoty = record + objectclass: tclass; + objectdata: pobjectdataty; + langobjectdata: pobjectdataty; + name: string; + changed: boolean; + end; + + pobjectdatainfoty = ^objectdatainfoty; + + tobjectdatainfolist = class(trecordlist) //todo: hashed or ordered list for speedup + protected + procedure finalizerecord(var item); override; + procedure copyrecord(var item); override; + procedure reload(const all: boolean); + public + constructor create; + function itempo(const index: integer): pobjectdatainfoty; + procedure add(const value: objectdatainfoty); + function find(aclass: tclass; aname: string): pobjectdatainfoty; overload; + function find(aclassname: string; aname: string): pobjectdatainfoty; overload; + procedure resetchanged; + procedure reloadchanged; + procedure reloadall; + end; + + tloadedlist = class(tcomponent) + protected + procedure notification(acomponent: tcomponent; operation: toperation); override; + end; + + trefreshwriter = class(twritermse) + protected + end; + +var + objectdatalist: tobjectdatainfolist; + fmodules: tmodulelist; + floadedlist: tloadedlist; + fmodulestoregister: msecomponentarty; + +{$ifdef mse_debug} +function debugstringarty(const astringar: stringarty): string; +begin + if astringar = nil then begin + result:= 'NIL'; + end + else begin + result:= concatstrings(astringar,','); + end; +end; + +function debugcompname(const acomponent: tcomponent): string; +begin + if acomponent = nil then begin + result:= 'NIL'; + end + else begin + result:= acomponent.name+'<'+acomponent.classname+'>'; + end; +end; + +function debugcompnames(const acomponents: componentarty): string; +var + int1: integer; +begin + if acomponents = nil then begin + result:= 'NIL'; + end + else begin + for int1:= 0 to high(acomponents) do begin + result:= result + debugcompname(acomponents[int1]) + ','; + end; + if result <> '' then begin + setlength(result,length(result)-1); + end; + end; +end; + +function debugcomprootname(const acomponent: tcomponent): string; +var + comp1: tcomponent; +begin + if acomponent = nil then begin + result:= 'NIL'; + end + else begin + comp1:= acomponent; + repeat + result:= comp1.name+'<'+comp1.classname+'>'+'.'+result; + comp1:= comp1.owner; + until comp1 = nil; + setlength(result,length(result)-1); + end; +end; + +function debugcomprootnames(const acomponents: componentarty): string; +var + int1: integer; +begin + if acomponents = nil then begin + result:= 'NIL'; + end + else begin + result:= ''; + for int1:= 0 to high(acomponents) do begin + result:= result + debugcomprootname(acomponents[int1]) + ','; + end; + if result <> '' then begin + setlength(result,length(result)-1); + end; + end; +end; + +procedure dumpcomponent(const acomp: tcomponent; const atext: string = ''); +var + indent: string; + + procedure dodump(const acomp: tcomponent); + var + int1: integer; + str1: string; + begin + str1:= settostring(ptypeinfo(typeinfo(tcomponentstate)), + integer(tintegerset(acomp.componentstate)),true); + debugwriteln(indent+acomp.name+' '+str1); + indent:= indent+' '; + for int1:= 0 to acomp.componentcount-1 do begin + dodump(acomp.components[int1]); + end; + setlength(indent,length(indent)-1); + end; + +begin + if atext = '' then begin + debugwriteln('*dumpcomp') + end + else begin + debugwriteln(atext); + end; + dodump(acomp); +end; + +procedure debugstreamout(const stream: tstream; const atext: string); +var + teststream: ttextstream; +begin + debugwriteln(atext); + teststream:= ttextstream.create; + stream.position:= 0; + teststream.size:= 0; + objectbinarytotextmse(stream,teststream); + teststream.position:= 0; + teststream.writetotext(output); + teststream.free; + flush(output); +end; + +procedure dumptextstream(const stream: tstream; const atext: string); +var + int1: integer; + str1: string; +begin + debugwriteln(atext); + int1:= stream.position; + stream.position:= 0; + setlength(str1,stream.size); + stream.readbuffer(pointer(str1)^,length(str1)); + debugwriteln(str1); + stream.position:= int1; +end; + +procedure debugbinstreamout(const acomp,aancestor: tcomponent; + const aonfindancestor: tfindancestorevent; const atext: string); +var + stream1: tmemorystream; + writer1: twritermse; +begin + stream1:= tmemorystream.create; + writer1:= twritermse.create(stream1,1024,false); + writer1.onfindancestor:= aonfindancestor; +// writer1.onfindancestor:= {$ifdef FPC}@{$endif}fdesigner.findancestor; + writer1.writedescendent(acomp,aancestor); + writer1.free; + debugstreamout(stream1,atext); + stream1.free; +end; + +procedure dumpstreamcomponent(const acomp: tcomponent; const atext: string = ''); +begin + debugbinstreamout(acomp,nil,nil,atext); +end; + +{$endif} + +function aligntoptr(p: pointer): pointer; inline; +begin +{$ifdef FPC_REQUIRES_PROPER_ALIGNMENT} + result:= align(p,sizeof(p)); +{$else FPC_REQUIRES_PROPER_ALIGNMENT} + result:=p; +{$endif FPC_REQUIRES_PROPER_ALIGNMENT} +end; + +procedure copyvarrec(const source: tvarrec; const dest: pointer); +begin + with source do begin + case vtype of + vtInteger: begin + pinteger(dest)^:= vinteger; + end; + vtBoolean: begin + system.pboolean(dest)^:= vboolean; + end; + vtChar: begin + pchar(dest)^:= vchar; + end; + vtExtended: begin + pextended(dest)^:= vextended^; + end; + vtString: begin + pshortstring(dest)^:= vstring^; + end; + vtPointer: begin + ppointer(dest)^:= vpointer; + end; + vtPChar: begin + ppchar(dest)^:= vpchar; + end; + vtObject: begin + pobject(dest)^:= vobject; + end; + vtClass: begin + pclass(dest)^:= vclass; + end; + vtWideChar: begin + pwidechar(dest)^:= vwidechar; + end; + vtPWideChar: begin + ppwidechar(dest)^:= vpwidechar; + end; + vtAnsiString: begin + pansistring(dest)^:= ansistring(vansistring); + end; + vtCurrency: begin + pcurrency(dest)^:= vcurrency^; + end; + vtVariant: begin + pvariant(dest)^:= vvariant^; + end; + vtInterface: begin + ppointer(dest)^:= vinterface; //reference counting? + end; + vtWideString: begin + pwidestring(dest)^:= widestring(vwidestring); + end; + vtInt64: begin + pint64(dest)^:= vint64^; + end; + vtQWord: begin + pqword(dest)^:= vqword^; + end; + vtUnicodeString: begin + punicodestring(dest)^:= unicodestring(vunicodestring); + end; + end; + end; +end; + +procedure matchparams(const aparam: array of const; + const defaults: array of const; const dest: array of pointer); +var + int1: integer; +begin + int1:= high(aparam); + if int1 > high(defaults) then begin + int1:= high(defaults); + end; + if int1 > high(dest) then begin + int1:= high(dest); + end; + for int1:= 0 to int1 do begin + if tvarrec(aparam[int1]).vtype = tvarrec(defaults[int1]).vtype then begin + copyvarrec(aparam[int1],dest[int1]); + end + else begin + copyvarrec(defaults[int1],dest[int1]); + end; + end; +end; + +function alive(const acomponent: tcomponent): boolean; + {$ifdef FPC}inline;{$endif} +begin + result:= (acomponent <> nil) and + not (csdestroying in acomponent.componentstate); +end; + +procedure componentexception(const acomponent: tcomponent; + const atext: msestring); +begin + raise exception.create(ansistring( + msestring(acomponent.name+':'+acomponent.classname+':'+ lineend) + + atext)); +end; + +function getfproppath(const writer:twriter): string; +begin +{$warnings off} + result:= twriter1(writer).fproppath; +{$warnings on} +end; + +procedure setfproppath(const writer:twriter; const value: string); +begin +{$warnings off} + twriter1(writer).fproppath:= value; +{$warnings on} +end; + +function modules: tmodulelist; +begin + if fmodules = nil then begin + fmodules:= tmodulelist.create(false); + end; + result:= fmodules; +end; + +function getcomponentlist(const acomponent: tcomponent): tfplist; +begin +{$warnings off} + with tcomponent1(acomponent) do begin +{$warnings on} + if fcomponents = nil then begin + fcomponents:= tfplist.create; + end; + result:= fcomponents; + end; +end; + +procedure clearcomponentlist(const acomponent: tcomponent); +begin +{$warnings off} + freeandnil(tcomponent1(acomponent).fcomponents); +{$warnings on} +end; + +type + pastedcompinfoty = record + comp: tcomponent; + origname: string; + end; +var + pastedcomps: array of pastedcompinfoty; + +procedure clearpastedcomponents; +begin + pastedcomps:= nil; +end; + +procedure addpastedcomponentname(const acomp: tcomponent); +begin + setlength(pastedcomps,high(pastedcomps)+2); + with pastedcomps[high(pastedcomps)] do begin + comp:= acomp; + origname:= comp.name; + end; +end; + +function findpastedcomponent(const origname: string): tcomponent; +var + int1: integer; +begin + result:= nil; + for int1:= 0 to high(pastedcomps) do begin + if pastedcomps[int1].origname = origname then begin + result:= pastedcomps[int1].comp; + break; + end; + end; +end; + +function findpastedcomponentname(const comp: tcomponent): string; +var + int1: integer; +begin + result:= ''; + for int1:= 0 to high(pastedcomps) do begin + if pastedcomps[int1].comp = comp then begin + result:= pastedcomps[int1].origname; + break; + end; + end; +end; + +function setloading(const acomponent: tcomponent; const avalue: boolean): boolean; +begin + result:= csdesigning in acomponent.componentstate; +{$warnings off} + with tcomponent1(acomponent) do begin +{$warnings on} + if avalue then begin + include(fcomponentstate,csloading); + end + else begin + exclude(fcomponentstate,csloading); + end; + end; +end; + +procedure clearinline(const acomponent: tcomponent); +var + int1: integer; +begin + tmsecomponent(acomponent).setinline(false); + for int1:= 0 to acomponent.componentcount - 1 do begin + clearinline(acomponent.components[int1]); + end; +end; + +procedure initinline(const acomponent: tcomponent); + //sets inline, resets ancestor, sets ancestor of children + //clears inline of children +var + int1: integer; + comp1: tcomponent; +begin +{$warnings off} + with tcomponent1(acomponent) do begin +{$warnings on} + exclude(fcomponentstate,csancestor); + include(fcomponentstate,csinline); + end; + for int1:= 0 to acomponent.componentcount - 1 do begin + comp1:= acomponent.components[int1]; + tcomponent1(comp1).setancestor(true); +// clearinline(comp1); + end; +end; + +procedure checkinline(const acomponent: tcomponent); +var + int1: integer; + comp1: tcomponent1; +begin + if csinline in acomponent.componentstate then begin +{$warnings off} + with tcomponent1(acomponent) do begin +{$warnings on} + exclude(fcomponentstate,csancestor); + end; + for int1:= 0 to acomponent.componentcount - 1 do begin + comp1:= tcomponent1(acomponent.components[int1]); + comp1.setancestor(true); + clearinline(comp1); + end; + end + else begin + for int1:= 0 to acomponent.componentcount - 1 do begin + checkinline(acomponent.components[int1]); + end; + end; +end; + +procedure initrootdescendent(const acomponent: tcomponent); +begin + clearinline(acomponent); + tcomponent1(acomponent).setancestor(true); +end; + +function swapmethodtable(const instance: tobject; const newtable: pointer): pointer; +var + {$ifdef mswindows} + ca1: longword; + {$endif} + methodtabpo: ppointer; +begin + methodtabpo:= ppointer(pchar(instance.classtype)+vmtmethodtable); + {$ifdef mswindows} + virtualprotect(methodtabpo,sizeof(pointer),page_readwrite,{$ifdef FPC}@{$endif}ca1); + {$endif} + result:= methodtabpo^; + methodtabpo^:= newtable; + {$ifdef mswindows} + virtualprotect(methodtabpo,sizeof(pointer),ca1,nil); + {$endif} +end; + +procedure writeset(const writer: twriter; const value: tintegerset; + const atypeinfo: ptypeinfo); +var +{$ifndef FPC} + i: integer; +{$endif} + basetype: ptypeinfo; +begin + basetype:= gettypedata(atypeinfo)^.comptype{$ifndef FPC}^{$endif}; + with twriter1(writer) do begin + driver.writeset(longint(value),basetype); + end; +end; + +function checkenumvalue(typeinfo : ptypeinfo;const name : string) : integer; +begin + result:= getenumvalue(typeinfo,name); + if result < 0 then begin + raise exception.create('In valid enum name for '+typeinfo^.name+ + ': "'+name+'".'); + end; +end; + +function readenum(const reader: treader; const atypeinfo: ptypeinfo): integer; +begin + result:= getenumvalue(atypeinfo,reader.readident); + if result < 0 then begin + raise ereaderror.create(sinvalidpropertyvalue); + end; +end; + +procedure writeenum(const writer: twriter; const value: integer; + const atypeinfo: ptypeinfo); +begin + writer.writeident(getenumname(atypeinfo,value)); +end; + +function readset(const reader: treader; const atypeinfo: ptypeinfo): tintegerset; +begin + {$ifdef FPC} + reader.checkvalue(vaset); + result:= tintegerset(treader1(reader).driver.readset( + gettypedata(atypeinfo)^.comptype{$ifndef fpc}^{$endif})); + {$else} + result:= tintegerset(treader1(reader).readset(atypeinfo)); + {$endif} +end; + +function readsplitset(const reader: treader; const info: setsplitinfoty; + out set1,set2: tintegerset): boolean; + //true if splitted +var + int1,int2: integer; + str1: string; + po1,po2: ptypeinfo; +begin + reader.checkvalue(vaset); + set1:= []; + set2:= []; + result:= false; + with info do begin + while true do begin + po1:= gettypedata(maintype)^.comptype{$ifndef FPC}^{$endif}; + po2:= gettypedata(splittype)^.comptype{$ifndef FPC}^{$endif}; + str1:= reader.driver.readstr; + if str1 = '' then begin + break; + end; + int1:= getenumvalue(po1,str1); + if int1 >= 0 then begin + include(set1,int1); + end + else begin + for int2:= 0 to high(enums) do begin + if enums[int1].oldenum = str1 then begin + int1:= getenumvalue(po2,enums[int1].newenum); + if int1 >= 0 then begin + include(set2,int1); + end; + result:= true; + break; + end; + end; + end; + if int1 < 0 then begin + repeat + until reader.driver.readstr = ''; + raise ereaderror.create(sinvalidpropertyvalue); + end; + end; + end; +end; + +function checkcanevent(const acomponent: tcomponent; const event: tmethod): boolean; +begin + result:= (event.code <> nil) and (acomponent <> nil) and (event.data <> nil) and + (acomponent.componentstate * [csloading,csdesigning,csdestroying] = []); +end; + +function checkcanevent(const event: tmethod): boolean; +begin + result:= (event.code <> nil) and (event.data <> nil); +end; + +procedure writestringar(const writer: twriter; const ar: stringarty); +var + int1: integer; +begin + writer.writelistbegin; + for int1:= 0 to high(ar) do begin + writer.writestring(ar[int1]); + end; + writer.writelistend; +end; + +procedure writestringar(const writer: twriter; const ar: msestringarty); +var + int1: integer; +begin + writer.writelistbegin; + for int1:= 0 to high(ar) do begin + writer.writeunicodestring(ar[int1]); + end; + writer.writelistend; +end; + +procedure readstringar(const reader: treader; out ar: stringarty); +var + int1: integer; +begin + int1:= 0; + ar:= nil; + reader.readlistbegin; + while not reader.endoflist do begin + additem(ar,reader.readstring,int1); + end; + reader.readlistend; + setlength(ar,int1); +end; + +procedure readstringar(const reader: treader; out ar: msestringarty); +var + int1: integer; +begin + int1:= 0; + ar:= nil; + reader.readlistbegin; + while not reader.endoflist do begin + additem(ar,reader.readunicodestring,int1); + end; + reader.readlistend; + setlength(ar,int1); +end; + +procedure readintar(const reader: treader; out ar: int32arty); +var + i1: int32; +begin + i1:= 0; + ar:= nil; + reader.readlistbegin; + while not reader.endoflist do begin + additem(ar,reader.readinteger,i1); + end; + reader.readlistend; + setlength(ar,i1); +end; + +procedure readintar(const reader: treader; out ar: int16arty); +var + i1: int32; +begin + i1:= 0; + ar:= nil; + reader.readlistbegin; + while not reader.endoflist do begin + additem(ar,int16(reader.readinteger),i1); + end; + reader.readlistend; + setlength(ar,i1); +end; + +procedure writeintar(const writer: twriter; const ar: int32arty); +var + i1: int32; +begin + writer.writelistbegin; + for i1:= 0 to high(ar) do begin + writer.writeinteger(ar[i1]); + end; + writer.writelistend; +end; + +procedure writeintar(const writer: twriter; const ar: int16arty); +var + i1: int32; +begin + writer.writelistbegin; + for i1:= 0 to high(ar) do begin + writer.writeinteger(ar[i1]); + end; + writer.writelistend; +end; + +procedure readrecordar(const reader: treader; out ar; + const typeinfo: pdynarraytypeinfo; const readproc: readrecordprocty); +var + int1: integer; + lint1: sizeint; +begin + int1:= 0; + reader.readlistbegin; + while not reader.endoflist do begin + reader.readlistbegin; + readproc(reader,additempo(ar,typeinfo,int1)^); + reader.readlistend; + end; + reader.readlistend; + lint1:= int1; + dynarraysetlength(pointer(ar),typeinfo,1,@lint1); +end; + +procedure writerecordar(const writer: twriter; const ar; + const typeinfo: pdynarraytypeinfo; const writeproc: writerecordprocty); +var + int1,int2: integer; +begin + writer.writelistbegin; + int2:= dynarrayelesize(typeinfo); + for int1:= 0 to high(pointerarty(ar)) do begin + writer.writelistbegin; + writeproc(writer,(pointer(ar)+int2*int1)^); + writer.writelistend; + end; + writer.writelistend; +end; + +function valuescaletorange(const reader: treader): real; +begin + result:= reader.readfloat; + if result <> 0 then begin + result:= 1/result; + end; +end; + +procedure lockfindglobalcomponent; //switch of findglobalcomponent +begin + modules.lock; +end; + +procedure unlockfindglobalcomponent; //switch on findglobalcomponent +begin + modules.unlock; +end; + +function findglobalcomponentlocked: boolean; +begin + result:= modules.flocked <> 0; +end; + +function ownscomponent(const owner: tcomponent; const child: tcomponent): boolean; +var + comp1: tcomponent; +begin + result:= false; + comp1:= child; + while comp1 <> nil do begin + if comp1 = owner then begin + result:= true; + break; + end; + comp1:= comp1.owner; + end; +end; + +function ownernamepath(const acomponent: tcomponent): string; +var + comp: tcomponent; +begin + if acomponent = nil then begin + result:= '' + end + else begin + with acomponent do begin + result:= name; + comp:= owner; + while comp <> nil do begin + if comp.Name <> '' then begin + result:= comp.Name + '.' + result; + end; + comp:= comp.Owner; + end; + end; + end; +end; + +function ownernamepath(const aroot: tcomponent; + const acomponent: tcomponent): string; + //namepath from aroot to acomponent separated by '.' + //excluding aroot +var + comp: tcomponent; +begin + if acomponent = nil then begin + result:= '' + end + else begin + with acomponent do begin + result:= name; + comp:= owner; + while (comp <> nil) and (comp <> aroot) do begin + if comp.Name <> '' then begin + result:= comp.Name + '.' + result; + end; + comp:= comp.Owner; + end; + end; + end; +end; + +function namepathowner(const acomponent: tcomponent): string; + //namepath from acomponent to root separated by '.' +var + comp: tcomponent; +begin + if acomponent = nil then begin + result:= '' + end + else begin + with acomponent do begin + result:= name; + comp:= owner; + while comp <> nil do begin + if comp.Name <> '' then begin + result:= result + '.' + comp.Name; + end; + comp:= comp.Owner; + end; + end; + end; +end; + +function componentpathowner(const acomponent: tcomponent): componentarty; + //componentpath from acomponent to root +var + count: integer; + comp1: tcomponent; +begin + count:= 0; + if acomponent <> nil then begin + comp1:= acomponent; + repeat + {$ifndef FPC} + addpointeritem(pointerarty(result),pointer(comp1),count); + {$else} + additem(pointerarty(result),pointer(comp1),count); + {$endif} + comp1:= comp1.owner; + until comp1 = nil; + end; + setlength(result,count); +end; + +function ownercomponentpath(const acomponent: tcomponent): componentarty; + //componentpath from root to acomponent +begin + result:= componentarty(reversearray(pointerarty( + componentpathowner(acomponent)))); +end; + +function getnumberedname(const acomp: tcomponent; + const namebase: string): string; +var + int1: integer; +begin + int1:= 0; + repeat + result:= namebase+inttostr(int1); + until acomp.findcomponent(result) = nil; +end; + +function rootcomponent(const acomponent: tcomponent): tcomponent; +begin + result:= acomponent; + if result <> nil then begin + while result.owner <> nil do begin + result:= result.owner; + end; + end; +end; + +procedure setcomponentorder(const owner: tcomponent; const anames: msestringarty); +var + comp1: tcomponent; + int1: integer; +begin + for int1:= 0 to high(anames) do begin + comp1:= owner.findcomponent(ansistring(anames[int1])); +{$warnings off} + with tcomponent1(owner).fcomponents do begin +{$warnings on} + remove(comp1); + add(comp1); + end; + end; +end; + +{ trefreshwriter } + +type + tgetcomponentchildren = class + private + fcomp: tcomponent; + froot: tcomponent; + fnestedowners: boolean; + fnestedparents: boolean; + fchildren: componentarty; + fcount: integer; + fcurrroot: tcomponent; + function getchildrenar: componentarty; + protected + procedure childproc(child: tcomponent); + public + constructor create(const acomp: tcomponent; const aroot: tcomponent; + const nestedowners: boolean = false; + const nestedparents: boolean = false); + property children: componentarty read getchildrenar; + end; + +{ tgetcomponentchildren } + +constructor tgetcomponentchildren.create(const acomp: tcomponent; + const aroot: tcomponent; const nestedowners: boolean = false; + const nestedparents: boolean = false); +begin + fcomp:= acomp; + froot:= aroot; + fnestedowners:= nestedowners; + fnestedparents:= nestedparents; +end; + +procedure tgetcomponentchildren.childproc(child: tcomponent); +begin + additem(pointerarty(fchildren),child,fcount); + if fnestedparents then begin + tcomponent1(child).getchildren({$ifdef FPC}@{$endif}childproc,fcurrroot); + end; +end; + +function tgetcomponentchildren.getchildrenar: componentarty; +var + comp1: tcomponent; +begin + fchildren:= nil; + fcount:= 0; + if fnestedowners then begin + comp1:= fcomp; + while (comp1 <> froot) and (comp1 <> nil) do begin + fcurrroot:= comp1; + tcomponent1(fcomp).getchildren({$ifdef FPC}@{$endif}childproc,comp1); + comp1:= comp1.owner; + end; + end; + if froot <> nil then begin + fcurrroot:= froot; + tcomponent1(fcomp).getchildren({$ifdef FPC}@{$endif}childproc,froot); + end; + setlength(fchildren,fcount); + result:= fchildren; +end; + +function getcomponentchildren(const acomp: tcomponent; + const aroot: tcomponent; + const nestedowners: boolean = false; + const nestedparents: boolean = false): componentarty; +var + obj: tgetcomponentchildren; +// ev1: getchildreneventty; +begin +// ev1:= onstreaminggetchildren; +// try +// onstreaminggetchildren:= nil; + obj:= tgetcomponentchildren.create(acomp,aroot,nestedowners,nestedparents); + result:= obj.children; + obj.free; +// finally +// onstreaminggetchildren:= ev1; +// end; +end; + +function getlinkedcomponents(const acomponent: tcomponent): componentarty; +var + int1: integer; +begin + result:= nil; +{$warnings off} + with tcomponent1(acomponent) do begin +{$warnings on} + if ffreenotifies <> nil then begin + for int1:= 0 to ffreenotifies.count - 1 do begin + additem(pointerarty(result),ffreenotifies[int1]); + end; + end; + end; +end; + +function getpropinfoar(const atypeinfo: ptypeinfo): propinfopoarty; +var + po1: ptypedata; +begin + po1:= gettypedata(atypeinfo); + setlength(result,po1^.PropCount); + getpropinfos(atypeinfo,pointer(result)); +end; + +function getpropinfoar(const obj: tobject): propinfopoarty; +begin + if (obj <> nil) and (obj.classinfo <> nil) then begin + result:= getpropinfoar(obj.classinfo); + end + else begin + result:= nil; + end; +end; + +function getenumnames(const atypeinfo: ptypeinfo): msestringarty; +var + typedata1: ptypedata; + int1{,int2}: integer; +begin + typedata1:= gettypedata(atypeinfo); + with typedata1^ do begin + setlength(result,maxvalue-minvalue+1); + for int1:= 0 to high(result) do begin + result[int1]:= msestring(getenumname(atypeinfo,int1)); + end; + { + int2:= 0; + for int1:= MinValue to MaxValue do begin + result[int2]:= getenumname(atypeinfo,int1); + inc(int2); + end; + } + end; +end; + +function getclasspropvalue(const instance: tobject; const apropname: string; + const aclass: tclass): tobject; +var + po1: ppropinfo; + po2: ptypeinfo; +begin + result:= nil; + if instance <> nil then begin + po1:= getpropinfo(instance,apropname); + if (po1 <> nil) then begin + po2:= po1^.proptype; + if (po2^.kind = tkclass) and + (gettypedata(po2)^.classtype.inheritsfrom(aclass)) then begin + {$ifdef cpu64} + result:= tobject(ptruint(getint64prop(instance,po1))); + {$else} + result:= tobject(ptruint(getordprop(instance,po1))); + {$endif} + end; + end; + end; +end; + +function getclasspropvalue(const instance: tobject; const apropname: string; + const aclass: tclass; out avalue: tobject): boolean; +begin + avalue:= getclasspropvalue(instance,apropname,aclass); + result:= avalue <> nil; +end; + +type + tcomponentdestroyer = class(tcomponent) + private + fcomps: componentarty; + fcurrentcomponent: tcomponent; + protected + procedure notification(acomponent: tcomponent; + operation: toperation); override; + public + constructor create(const acomps: componentarty); reintroduce; + end; + +{ tcomponentdestroyer } + +constructor tcomponentdestroyer.create(const acomps: componentarty); +var + int1: integer; +begin + inherited create(nil); + fcomps:= copy(acomps); + for int1:= 0 to high(fcomps) do begin + fcomps[int1].freenotification(self); + end; + for int1:= 0 to high(fcomps) do begin + fcurrentcomponent:= fcomps[int1]; + fcurrentcomponent.free; + end; +end; + +procedure tcomponentdestroyer.notification(acomponent: tcomponent; + operation: toperation); +var + int1: integer; +begin + if (operation = opremove) and (acomponent <> fcurrentcomponent) then begin + for int1:= high(fcomps) downto 0 do begin + if fcomps[int1] = acomponent then begin + fcomps[int1]:= nil; + break; + end; + end; + end; + inherited; +end; + +procedure freecomponents(const acomponents: componentarty); + //uses freenotification +begin + tcomponentdestroyer.create(acomponents).free; +end; + +function copycomponent(const source: tcomponent; const aowner: tcomponent = nil; + const onfindancestor: tfindancestorevent = nil; + const onfindcomponentclass: tfindcomponentclassevent = nil; + const oncreatecomponent: tcreatecomponentevent = nil; + const onancestornotfound: tancestornotfoundevent = nil): tcomponent; + //copy by stream.writecomponent, readcomponent + + procedure copyflags(const source: tcomponent; const dest: tcomponent); + var + int1: integer; + comp1,comp2: tcomponent; + begin + for int1:= 0 to source.componentcount - 1 do begin + comp1:= source.components[int1]; + comp2:= dest.findcomponent(comp1.name); + if comp2 <> nil then begin + if csancestor in comp1.componentstate then begin + tcomponent1(comp2).setancestor(true); + end + else begin + copyflags(comp1,comp2); + end; + end; + end; + end; //copyflags + +var + stream: tmemorystream; + writer: twritermse; + reader: treader; + {$ifdef mse_debugcopycomponent} + debugstream: ttextstream; + {$endif} +begin + result:= tcomponent(source.NewInstance); + try + if csdesigning in source.componentstate then begin + tcomponent1(result).setdesigning(true); +// result.name:= source.name; + end; + result.Create(aowner); + stream:= tmemorystream.Create; + try + writer:= twritermse.Create(stream,4096,false); + try + writer.OnFindAncestor:= onfindancestor; + writer.Writerootcomponent(source); + finally + writer.Free; + end; + {$ifdef mse_debugcopycomponent} + debugstream:= ttextstream.create; + stream.position:= 0; + objectbinarytotextmse(stream,debugstream); + debugstream.position:= 0; + writeln(output,'***copycomponent source'); + dumpcomponent(source); + debugstream.writetotext(output); + flush(output); + {$endif} + stream.Position:= 0; + reader:= treader.Create(stream,4096); + try + reader.OnFindComponentClass:= onfindcomponentclass; + reader.OnCreateComponent:= oncreatecomponent; + reader.onancestornotfound:= onancestornotfound; +// reader.ancestor:= aancestor; + reader.ReadrootComponent(result); + if (source.owner = nil) and (csancestor in source.componentstate) then begin + tcomponent1(source).setancestor(true); + end + else begin + copyflags(source,result); + end; + finally + reader.free; + end; + {$ifdef mse_debugcopycomponent} + stream.clear; + writer:= twritermse.Create(stream,4096); + writer.Writerootcomponent(result); + writer.Free; + stream.position:= 0; + debugstream.clear; + objectbinarytotextmse(stream,debugstream); + debugstream.position:= 0; + writeln(output,'***copycomponent dest'); + dumpcomponent(result); + debugstream.writetotext(output); + flush(output); + debugstream.free; + {$endif} + finally + stream.Free; + end; + except + result.free; + raise; + end; + if source is tmsecomponent then begin + tmsecomponent(result).factualclassname:= tmsecomponent(source).factualclassname; + end; +end; + + +function issubcomponent(const root,child: tcomponent): boolean; +var + comp: tcomponent; +begin + result:= false; + comp:= child.Owner; + while comp <> nil do begin + if comp = root then begin + result:= true; + break; + end; + comp:= comp.Owner; + end; +end; + +function fixupsetchildorder(const sender: tcomponent; + const child: tcomponent; const order: integer): boolean; + //true if handled +begin + result:= false; + if (csloading in child.componentstate) and + (child.getparentcomponent = nil) and ownscomponent(sender,child) and + (child.owner.componentstate*[csreading,csinline] = [csreading,csinline]) and + (child.owner <> sender) then begin + //treader set root as parent istead of lookuproot. + tcomponent1(child.owner).setchildorder(child,order); + result:= true; + end; +end; + +function createmodule(aowner: tcomponent; instanceclass: msecomponentclassty; + var reference): tmsecomponent; +var + instance: tmsecomponent; +begin + instance := tmsecomponent(instanceclass.newinstance); + additem(pointerarty(fmodulestoregister),instance); +// fmodules.add(instance); //not before completely loaded, + //submodules call globalfixupreferences + if @reference <> nil then begin + tmsecomponent(reference):= instance; + end; + try + instance.create(aowner); + except + if @reference <> nil then begin + tcomponent(reference) := nil; + end; + raise; + end; + result:= instance; +end; + + +function findmoduledata(const aclassname: string; + out aparentclassname: string): pobjectdataty; +var + po1: pobjectdatainfoty; +begin + result:= nil; + aparentclassname:= ''; + po1:= objectdatalist.find(aclassname,''); + if po1 <> nil then begin + aparentclassname:= po1^.objectclass.classparent.classname; + result:= po1^.objectdata; + end; +end; + +procedure loadmodule(const instance: tcomponent; + const po1: pobjectdatainfoty; asinherited: boolean); +var + stream: tobjectdatastream; + reader: treader; + po2: pobjectdataty; +// intf: iobjectlink; +begin + po2:= po1^.langobjectdata; + if po2 = nil then begin + po2:= po1^.objectdata; + end; + stream:= tobjectdatastream.create(po2); + try + globalnamespace.beginwrite; + if asinherited then begin + reader := tasinheritedreader.create(stream, 4096,true); + end + else begin + reader := treader.create(stream, 4096); + end; + try + reader.onancestornotfound:= {$ifdef FPC}@{$endif}modules.ancestornotfound; + reader.readrootcomponent(instance); + finally + reader.free; + end; + finally + globalnamespace.endwrite; + stream.free; + end; + if floadedlist = nil then begin + floadedlist:= tloadedlist.create(nil); + end; + instance.freenotification(floadedlist); +end; + +const + skipmark = 'h71%z/ur'; + +type + trefresheventhandler = class(tcomponent) + private + fcomponentar: componentarty; + procedure onsetname(reader: treader; component: tcomponent; var aname: string); + procedure onerror(reader: treader; const message: string; var handled: boolean); + procedure doancestornotfound(reader: treader; const componentname: string; + componentclass: tpersistentclass; var component: tcomponent); + protected + procedure notification(acomponent: tcomponent; operation: toperation); + override; + public + destructor destroy; override; + end; + + trefreshexception = class(exception) + end; + +destructor trefresheventhandler.destroy; +var + int1: integer; +begin + for int1:= 0 to high(fcomponentar) do begin + fcomponentar[int1].free; //FPC does not free the component + end; + inherited; +end; + +procedure trefresheventhandler.notification(acomponent: tcomponent; operation: toperation); +begin + if (operation = opremove) then begin + removeitem(pointerarty(fcomponentar),acomponent); + end; + inherited; +end; + +procedure trefresheventhandler.onerror(reader: treader; const message: string; + var handled: boolean); +begin + if message = skipmark then begin + handled:= true; + end; +end; + +procedure trefresheventhandler.onsetname(reader: treader; + component: tcomponent; var aname: string); +begin +exit; + if (component.owner <> nil) and ((csinline in component.owner.componentstate) and + not(csancestor in component.componentstate) or + (component.owner.findcomponent(aname) <> nil)) then begin + additem(pointerarty(fcomponentar),component); + component.freenotification(self); + raise trefreshexception.create(skipmark); //skip the component + end; +end; + +procedure trefresheventhandler.doancestornotfound(reader: treader; + const componentname: string; componentclass: tpersistentclass; + var component: tcomponent); +begin + if component = nil then begin + component:= tasinheritedreader(reader).existingcomp; + if (component = nil) then begin + if assigned(reader.oncreatecomponent) then begin + reader.oncreatecomponent(reader,tcomponentclass(componentclass),component); + end; + if component = nil then begin + component:= tcomponent(componentclass.newinstance); + {$warnings off} + with tcomponent1(component) do begin + {$warnings on} + fcomponentstate:= componentstate + [csloading,csancestor]; + end; + try + component.create(reader.owner); + except + component.free; + raise; + end; + end; + end; + end; +end; + + +type + tcomponentdeleter = class(tcomponent) + private + fdelcomponents: componentarty; + protected + procedure notification(acomponent: tcomponent; operation: toperation); override; + public + constructor create(const acomponents: componentarty); reintroduce; + end; + +{ tcomponentdeleter } + +constructor tcomponentdeleter.create(const acomponents: componentarty); +var + int1: integer; +begin + inherited create(nil); + fdelcomponents:= acomponents; + for int1:= 0 to high(fdelcomponents) do begin + if fdelcomponents[int1] <> nil then begin + fdelcomponents[int1].freenotification(self); + end; + end; +end; + +procedure tcomponentdeleter.notification(acomponent: tcomponent; + operation: toperation); +var + int1: integer; +begin + inherited; + if operation = opremove then begin + for int1:= 0 to high(fdelcomponents) do begin + if fdelcomponents[int1] = acomponent then begin + fdelcomponents[int1]:= nil; + end; + end; + end; +end; + +type + trefreshancestoreventhandler = class(trefresheventhandler) + private + fnonancestors: componentarty; + fsetancestorroot: tcomponent; + protected + procedure setchildancestor(child: tcomponent); + procedure setancestors(const acomponent: tcomponent); + procedure notification(acomponent: tcomponent; operation: toperation); + override; + end; + +procedure trefreshancestoreventhandler.notification(acomponent: tcomponent; + operation: toperation); +begin + if operation = opremove then begin + removeitem(pointerarty(fnonancestors),pointer(acomponent)); + end; + inherited; +end; + +procedure trefreshancestoreventhandler.setchildancestor(child: tcomponent); +begin + with tcomponent1(child) do begin + setancestor(true); + getchildren({$ifdef FPC}@{$endif}setchildancestor,fsetancestorroot); + end; +end; + +procedure trefreshancestoreventhandler.setancestors(const acomponent: tcomponent); +begin + fsetancestorroot:= acomponent.owner; + setchildancestor(acomponent); +end; + +procedure refreshancestor(var deletedcomps: componentarty; + const descendent,newancestor,oldancestor: tcomponent; + const revert: boolean; + const onfindancestor: tfindancestorevent = nil; + const onfindcomponentclass: tfindcomponentclassevent = nil; + const oncreatecomponent: tcreatecomponentevent = nil; + {$ifdef mse_nomethodswap} + const onsetmethodproperty: tsetmethodpropertyevent = nil; + const onwritemethodproperty: twritemethodpropertyevent = nil; + const newcomponent: system.pboolean = nil + {$else} + const onfindmethod: tfindmethodevent = nil; + const sourcemethodtab: pointer = nil; + const destmethodtab: pointer = nil + {$endif}); + +var + descendentroot: tcomponent; + newancestorroot: tcomponent; + oldancestorroot: tcomponent; + eventhandler: trefreshancestoreventhandler; + + procedure deletecomps(const adescendent,anewancestor,aoldancestor: tcomponent); + var + deleter: tcomponentdeleter; + descendentar,newancestorar,oldancestorar: componentarty; + int1,int2: integer; + comp1,comp2: tcomponent; + str1: string; + begin + descendentar:= getcomponentchildren(adescendent,descendentroot,true); + //nested components + deleter:= tcomponentdeleter.create(descendentar); + try + newancestorar:= getcomponentchildren(anewancestor,newancestorroot,true); + if not revert then begin + oldancestorar:= getcomponentchildren(aoldancestor,oldancestorroot,true); + end; + for int1:= 0 to high(descendentar) do begin + if descendentar[int1] <> nil then begin + str1:= descendentar[int1].name; + comp1:= nil; + for int2:= 0 to high(newancestorar) do begin + if newancestorar[int2].name = str1 then begin + comp1:= newancestorar[int2]; + break; + end; + end; + comp2:= nil; + if not revert then begin + for int2:= 0 to high(oldancestorar) do begin + if oldancestorar[int2].name = str1 then begin + comp2:= oldancestorar[int2]; + break; + end; + end; + end; + if ((comp1 = nil) or (finditem(pointerarty(deletedcomps),comp1) >= 0)) and + (revert or (comp2 <> nil)) then begin + additem(pointerarty(deletedcomps),pointer(descendentar[int1])); +// freedesigncomponent(descendentar[int1]); +// descendentar[int1].free; + end + else begin + if revert or (comp2 <> nil) then begin + deletecomps(descendentar[int1],comp1,comp2); + end + else begin + with tcomponent1(descendentar[int1]) do begin + if owner.componentstate * [csinline,csancestor] <> [] then begin + eventhandler.setancestors(descendentar[int1]); + end; + end; + end; + end; + end; + end; + if not revert then begin + with eventhandler do begin + for int1:= 0 to high(fnonancestors) do begin + tcomponent1(fnonancestors[int1]).setancestor(false); + end; + end; + end; + finally + deleter.free; + end; + end; + +var + nonancestors: componentarty; + stream1,stream2,stream4: tmemorystream; + writer: twritermse; + reader: tasinheritedreader; + inl: boolean; + int1,int2: integer; + intf1: iactivatorclient; +{$ifndef mse_nomethodswap} + tabbefore: pointer; +{$endif} + {$ifdef mse_debugrefresh} + comp1: tcomponent; + stream3: ttextstream; + {$endif} + +begin + descendentroot:= rootcomponent(descendent); + newancestorroot:= rootcomponent(newancestor); + oldancestorroot:= rootcomponent(oldancestor); + if not revert then begin + nonancestors:= getcomponentchildren(descendent,descendentroot,false,true); + //nested components + int2:= 0; + for int1:= 0 to high(nonancestors) do begin + if not (csancestor in nonancestors[int1].componentstate) then begin + nonancestors[int2]:= nonancestors[int1]; + inc(int2); + end; + end; + setlength(nonancestors,int2); + end; + +{$ifdef mse_debugrefresh} + if revert then begin + write('****revert '); + end + else begin + write('****refresh '); + end; + comp1:= descendentroot; + writeln('root: '+comp1.name+' descendent: '+ descendent.name + ' newancestor: '+ + newancestor.name + ' oldancestor: '+oldancestor.name); + dumpcomponent(descendent,'*descendent'); + dumpcomponent(newancestor,'*newancestor'); + dumpcomponent(oldancestor,'*oldancestor'); + stream3:= ttextstream.create; +{$endif} + + eventhandler:= trefreshancestoreventhandler.create(nil); + for int1:= 0 to high(nonancestors) do begin + nonancestors[int1].freenotification(eventhandler); + end; + eventhandler.fnonancestors:= nonancestors; + nonancestors:= nil; + stream1:= tmemorystream.Create; + stream2:= tmemorystream.Create; + stream4:= tmemorystream.Create; + + try + writer:= trefreshwriter.Create(stream1,4096,false); +{$ifdef mse_nomethodswap} + writer.onwritemethodproperty:= onwritemethodproperty; +{$else} + tabbefore:= nil; //compiler warning + if destmethodtab <> nil then begin + tabbefore:= swapmethodtable(descendent,destmethodtab); + end; +{$endif} + try + writer.OnFindAncestor:= onfindancestor; + writer.WriteDescendent(descendent,oldancestor); //changes from oldancestor + finally +{$ifndef mse_nomethodswap} + if destmethodtab <> nil then begin + swapmethodtable(descendent,tabbefore); + end; +{$endif} + writer.Free; + end; + +{$ifdef mse_debugrefresh} + stream1.position:= 0; + objectbinarytotextmse(stream1,stream3); + stream3.position:= 0; + writeln('**changes descendent->oldancestor'); + stream3.writetotext(output); +{$endif} + + writer:= twritermse.Create(stream2,4096,false,true); + inl:= csinline in newancestor.componentstate; + if csinline in descendent.componentstate then begin + tmsecomponent(newancestor).SetInline(true); + end; + +{$ifdef mse_nomethodswap} + writer.onwritemethodproperty:= onwritemethodproperty; +{$else} + if sourcemethodtab <> nil then begin + tabbefore:= swapmethodtable(newancestor,sourcemethodtab); + end; +{$endif} + + try + writer.OnFindAncestor:= onfindancestor; + writer.WriteDescendent(newancestor,descendent); + //new state before deactivate + writer.free; + {$ifdef mse_debugrefresh} + stream2.position:= 0; + stream3.setsize(0); + objectbinarytotextmse(stream2,stream3); + stream3.position:= 0; + writeln('**changes newancestor->descendent before deactivate'); + stream3.writetotext(output); + {$endif} + + if descendent is tactcomponent then begin + tactcomponent(descendent).deactivate(true); + end + else begin + if getcorbainterface(descendent,typeinfo(iactivatorclient),intf1) then begin + intf1.setactive(false); + end; + end; + + writer:= twritermse.Create(stream4,4096,false,true); + {$ifdef mse_nomethodswap} + writer.onwritemethodproperty:= onwritemethodproperty; + {$endif} + writer.WriteDescendent(newancestor,descendent); //new state after deactivate + finally + writer.free; + tmsecomponent(newancestor).SetInline(inl); +{$ifndef mse_nomethodswap} + if sourcemethodtab <> nil then begin + swapmethodtable(newancestor,tabbefore); + end; +{$endif} + end; + + {$ifdef mse_debugrefresh} + stream4.position:= 0; + stream3.setsize(0); + objectbinarytotextmse(stream4,stream3); + stream3.position:= 0; + writeln('**changes newancestor->descendent after deactivate'); + stream3.writetotext(output); + {$endif} + + stream1.Position:= 0; + stream2.Position:= 0; + stream4.Position:= 0; + + {$ifndef mse_nomethodswap} + if destmethodtab <> nil then begin + tabbefore:= swapmethodtable(descendent,destmethodtab); + end; + {$endif} + try + reader:= tasinheritedreader.create(stream2,4096,inl{false}); + //new state before deactivate + reader.OnFindComponentClass:= onfindcomponentclass; + reader.OnCreateComponent:= oncreatecomponent; + {$ifdef mse_nomethodswap} + reader.onsetmethodproperty:= onsetmethodproperty; + {$else} + reader.onfindmethod:= onfindmethod; + {$endif} + reader.onancestornotfound:= + {$ifdef FPC}@{$endif}eventhandler.doancestornotfound; + {$ifdef mse_debugrefresh} + writeln('**reading changes newancestor->descendent before deactivate'); + {$endif} + reader.ReadRootComponent(descendent); //changes + if newcomponent <> nil then begin + newcomponent^:= reader.newcomp; + end; + reader.free; + + reader:= tasinheritedreader.create(stream4,4096,inl{false}); + //new state after deactivate + reader.OnFindComponentClass:= onfindcomponentclass; + reader.OnCreateComponent:= oncreatecomponent; + {$ifdef mse_nomethodswap} + reader.onsetmethodproperty:= onsetmethodproperty; + {$else} + reader.onfindmethod:= onfindmethod; + {$endif} + reader.onancestornotfound:= + {$ifdef FPC}@{$endif}eventhandler.doancestornotfound; + {$ifdef mse_debugrefresh} + writeln('**reading changes newancestor->descendent after deactivate'); + {$endif} + reader.ReadRootComponent(descendent); //changes + + if not revert then begin + reader.free; + reader:= tasinheritedreader.create(stream1,4096,false); //restore old changes + reader.OnFindComponentClass:= onfindcomponentclass; + reader.OnCreateComponent:= oncreatecomponent; + {$ifdef mse_nomethodswap} + reader.onsetmethodproperty:= onsetmethodproperty; + {$else} + reader.onfindmethod:= onfindmethod; + {$endif} + reader.onsetname:= {$ifdef FPC}@{$endif}eventhandler.onsetname; + reader.onerror:= {$ifdef FPC}@{$endif}eventhandler.onerror; + reader.onancestornotfound:= + {$ifdef FPC}@{$endif}eventhandler.doancestornotfound; + {$ifdef mse_debugrefresh} + writeln('**reading changes descendent->oldancestor'); + {$endif} + reader.ReadRootComponent(descendent); //changes descendent->oldancestor + end; + + {$ifdef mse_debugrefresh} + debugwriteln('**deleteldcomps before delete '+ + debugcomprootnames(deletedcomps)); + {$endif} + + finally + {$ifndef mse_nomethodswap} + if destmethodtab <> nil then begin + swapmethodtable(descendent,tabbefore); + end; + {$endif} + reader.free; + removefixupreferences(descendent,''); + end; + + finally + try + nonancestors:= eventhandler.fnonancestors; + deletecomps(descendent,newancestor,oldancestor); + {$ifdef mse_debugrefresh} + debugwriteln('**deleteldcomps after delete '+ + debugcomprootnames(deletedcomps)); + dumpcomponent(descendent,'**descendent'); + {$endif} + finally + stream1.Free; + stream2.Free; + stream4.Free; + + {$ifdef mse_debugrefresh} + stream3.free; + {$endif} + + eventhandler.free; + end; + end; + +end; + +type + globalloadinfoty = record + modules: msecomponentarty; + modulecount: integer; + end; + globalloadinfoarty = array of globalloadinfoty; + + tloadmoduletracker = class(tlinkedobject) + private + fgloballoadings: globalloadinfoarty; + fgloballevel: integer; + protected + procedure unlink(var ainfo: globalloadinfoty); + procedure objectevent(const sender: tobject; const event: objecteventty); + override; + public + constructor create; + procedure moduleloaded(const amodule: tmsecomponent); + procedure beginglobal; + procedure endglobal; + procedure notifyloading; + end; + +{ tloadmoduletracker } + +constructor tloadmoduletracker.create; +begin + setlength(fgloballoadings,16); +end; + +procedure tloadmoduletracker.moduleloaded(const amodule: tmsecomponent); +begin + with fgloballoadings[fgloballevel] do begin + if length(modules) <= modulecount then begin + setlength(modules,modulecount*2+16); + end; + modules[modulecount]:= amodule; + getobjectlinker.link(amodule); + inc(modulecount); + end; +end; + +procedure tloadmoduletracker.beginglobal; +begin + if length(fgloballoadings) >= fgloballevel then begin + setlength(fgloballoadings,fgloballevel*2+16); + end; + inc(fgloballevel); +end; + +procedure tloadmoduletracker.endglobal; +begin + unlink(fgloballoadings[fgloballevel]); + dec(fgloballevel); +end; + +procedure tloadmoduletracker.unlink(var ainfo: globalloadinfoty); +var + comp1: tmsecomponent; + int1: integer; +begin + with ainfo do begin + for int1:= 0 to modulecount-1 do begin + comp1:= modules[int1]; + if comp1 <> nil then begin + modules[int1]:= nil; + fobjectlinker.unlink(comp1); + end; + end; + modulecount:= 0; + end; +end; + +procedure tloadmoduletracker.objectevent(const sender: tobject; + const event: objecteventty); +var + int1,int2: integer; +begin + inherited; + if event = oe_destroyed then begin + for int1:= 0 to fgloballevel do begin + with fgloballoadings[int1] do begin + for int2:= 0 to modulecount-1 do begin + if modules[int2] = sender then begin + modules[int2]:= nil; + end; + end; + end; + end; + end; +end; + +procedure tloadmoduletracker.notifyloading; +var + comp1: tmsecomponent; + int1: integer; +begin + with fgloballoadings[fgloballevel] do begin + try + for int1:= modulecount - 1 downto 0 do begin + comp1:= modules[int1]; + if comp1 <> nil then begin + modules[int1]:= nil; + fobjectlinker.unlink(comp1); + comp1.doafterload; + end; + end; + finally + unlink(fgloballoadings[fgloballevel]); + end; + end; +end; + +var + moduleloadlevel: integer; + globalloadlevel: integer; + loadmoduletracker: tloadmoduletracker; + +procedure msebegingloballoading; +begin + inc(globalloadlevel); + if globalloadlevel = 1 then begin + begingloballoading; + end; +end; + +procedure mseendgloballoading; +begin + dec(globalloadlevel); + if globalloadlevel = 0 then begin + notifygloballoading; + endgloballoading; + loadmoduletracker.notifyloading; + end; +end; + +function initmsecomponent(instance: tmsecomponent; rootancestor: tclass; + out needsloading: boolean): boolean; +var + allloaded: boolean; + ancestorloaded: boolean; + loadlevel: integer; + + rootancestor1: tclass; + + procedure doload(const aclass: msecomponentclassty); + var + po1: pobjectdatainfoty; + begin + if (aclass <> rootancestor1) and (aclass <> tmsecomponent) then begin + if loadlevel > 0 then begin + include(instance.fmsecomponentstate,cs_inheritedloading); + end; + inc(loadlevel); + try + doload(msecomponentclassty(aclass.classparent)); + finally + dec(loadlevel); + if loadlevel = 0 then begin + exclude(instance.fmsecomponentstate,cs_inheritedloading); + end; + end; + po1:= nil; + if objectdatalist <> nil then begin + po1:= objectdatalist.find(aclass,instance.name); + if (po1 = nil) and (rootancestor <> nil) then begin + po1:= objectdatalist.find(aclass,''); + end; + end; + if (po1 <> nil) then begin + if not ancestorloaded then begin + ancestorloaded:= true; + inc(moduleloadlevel); + if (moduleloadlevel = 1) and (globalloadlevel = 0) then begin + begingloballoading; + end; + end; + loadmodule(instance,po1,false); + end + else begin + if aclass.hasresource then begin + allloaded:= false; + needsloading:= true; + end; + end; + end; + end; + +begin + loadlevel:= 0; + if (rootancestor = nil) then begin + rootancestor1:= instance.classtype.classparent; + end + else begin + rootancestor1:= rootancestor; + end; + ancestorloaded:= false; + needsloading:= false; + allloaded:= true; + try + loadmoduletracker.moduleloaded(instance); + doload(msecomponentclassty(instance.classtype)); + if finditem(pointerarty(fmodulestoregister),instance) >= 0 then begin + modules.add(tmsecomponent(instance)); + globalfixupreferences; + end; + if ancestorloaded and (moduleloadlevel = 1) and (globalloadlevel = 0) then begin + moduleloadlevel:= 0; //allow loading of forms in loaded procedure + notifygloballoading; + end; + finally + if ancestorloaded then begin + if moduleloadlevel > 0 then begin + dec(moduleloadlevel); + end; + if (moduleloadlevel = 0) and (globalloadlevel = 0) then begin + endgloballoading; + end; + end; + removeitem(pointerarty(fmodulestoregister),instance); + end; + if (moduleloadlevel = 0) and (globalloadlevel = 0) then begin + loadmoduletracker.notifyloading; + end; + result:= allloaded and ancestorloaded; +end; + +function initmsecomponent1(instance: tcomponent; rootancestor: tclass): boolean; + //true if root loaded +var + bo1: boolean; +begin + if instance is tmsecomponent then begin + result:= initmsecomponent(tmsecomponent(instance),rootancestor,bo1); + end + else begin + result:= false; + end; +end; + +procedure reloadmsecomponent(Instance: tmsecomponent); +var + po1: pobjectdatainfoty; + +begin + po1:= objectdatalist.find(instance.classtype,instance.name); + if po1 = nil then begin + po1:= objectdatalist.find(instance.classtype,''); + end; + loadmodule(instance,po1,true); +end; +(* +procedure registerclassproperties(aclass: tclass); +type + PFieldClassTable = ^TFieldClassTable; + TFieldClassTable = packed record + Count: Smallint; + {$ifdef FPC} + fClasses: array[0..8191] of TPersistentClass; + {$else} + fClasses: array[0..8191] of ^TPersistentClass; + {$endif} + end; + +{$ifdef FPC} + pfieldtable = ^tfieldtable; + TFieldTable = packed record + FieldCount: Word; + ClassTable: Pointer; + { Fields: array[Word] of TFieldInfo; Elements have variant size! } + end; + +function getfieldclasstable(aclass: tclass): pfieldclasstable; +begin + {$ifdef FPC} {$checkpointer off} {$endif} + result:= pfieldclasstable(PFieldTable((Pointer(aclass) + vmtFieldTable)^)^.classtable); + {$ifdef FPC} {$checkpointer default} {$endif} +end; +{$else} +function GetFieldClassTable(AClass: TClass): PFieldClassTable; assembler; +asm + MOV EAX,[EAX].vmtFieldTable + OR EAX,EAX + JE @@1 + MOV EAX,[EAX+2].Integer +@@1: +end; +{$endif} + +var + int1: integer; + fieldclasstab: pfieldclasstable; + +begin + {$ifdef FPC} {$checkpointer off} {$endif} + fieldclasstab:= getfieldclasstable(aclass); + if fieldclasstab <> nil then begin + with fieldclasstab^ do begin + for int1:= 0 to count - 1 do begin + {$ifdef FPC} + classes.registerclass(fclasses[int1]); + registerclassproperties(fclasses[int1]); + {$else} + classes.registerclass(fclasses[int1]^); + registerclassproperties(fclasses[int1]^); + {$endif} + //register classes of subproperties + end; + end; + end; +end; +*) +procedure loadmsemodule(const instance: tmsecomponent; + const rootancestor: tclass); +var + needsloading: boolean; + +begin + //try mse moduleloading + if not initmsecomponent(instance,rootancestor,needsloading) then begin + if needsloading {or not + initinheritedcomponent(instance,needsloading)} then begin + //try FPC module loading + mseerror(mse_resnotfound,instance); + end; + end; + {$ifdef FPC} {$checkpointer default} {$endif} +end; + +function findancestorcomponent(const areader: treader; + const componentname: string): tcomponent; +var + comp1: tcomponent; +begin + result:= nil; + if csinline in areader.lookuproot.componentstate then begin + comp1:= areader.lookuproot; //check added component + while comp1 <> nil do begin + result:= comp1.findcomponent(componentname); + if result <> nil then begin + break; + end; + comp1:= comp1.owner; + end; + end; +end; + +{ tnotifylist } + +procedure tnotifylist.notify(const sender: tobject); +begin + factitem:= 0; + while (factitem < fcount) do begin + notifyeventty(getitempo(factitem)^)(sender); + inc(factitem); + end; +end; + + { tmodulelist} +{ +procedure tmodulelist.findmethod(Reader: TReader; const MethodName: string; + var Address: Pointer; var Error: Boolean); +var //does not work because method.data is not writable + comp1: tcomponent; + str1: string; + po1,po2: pchar; +begin + if error and (methodname <> '') then begin + po1:= pchar(pointer(methodname)); + po2:= strscan(po1,'.'); + if po2 <> nil then begin + setstring(str1,po1,po2-po1); + comp1:= findmodulebyname(str1); + if comp1 <> nil then begin + address:= comp1.MethodAddress(copy(methodname,po2-po1+2,bigint)) + end; + error:= address = nil; + end; + end; +end; +} +function tmodulelist.findmodulebyname(const name: string): tcomponent; +var + int1: integer; + comp1: tcomponent; +begin + result:= nil; + if (self <> nil) and (flocked = 0) then begin + for int1:= 0 to count - 1 do begin + comp1:= items[int1]; + if stricomp(pchar(comp1.name),pchar(name)) = 0 then begin + result:= comp1; + break; + end; + end; + end; +end; + +procedure tmodulelist.ancestornotfound(Reader: TReader; + const ComponentName: string; ComponentClass: TPersistentClass; + var Component: TComponent); +begin + component:= findancestorcomponent(reader,componentname); +end; + +procedure tmodulelist.lock; +begin + inc(flocked); +end; + +procedure tmodulelist.unlock; +begin + dec(flocked); +end; + +{ tloadedlist } + +procedure tloadedlist.notification(acomponent: tcomponent; + operation: toperation); +begin + inherited; + if operation = opremove then begin + removefixupreferences(acomponent,''); + end; +end; + +{ tobjectdatastream} + +constructor tobjectdatastream.create(data: pobjectdataty); +begin + inherited create; + {$ifdef FPC} {$checkpointer off} {$endif} + setpointer(@data^.data,data^.size); + {$ifdef FPC} {$checkpointer default} {$endif} +end; + +function tobjectdatastream.Write(const Buffer; Count: Integer): Longint; +begin + result:= 0; + raise exception.Create('readonly.'); +end; + +{ tobjectdatainfolist} + +constructor tobjectdatainfolist.create; +begin + inherited create(sizeof(objectdatainfoty),[rels_needsfinalize,rels_needscopy]); +end; + +function tobjectdatainfolist.find(aclass: tclass; aname: string): pobjectdatainfoty; +var + int1: integer; +begin + aname:= uppercase(aname); + result:= pobjectdatainfoty(fdata); + for int1:= 0 to fcount -1 do begin + if (result^.objectclass = aclass) and ((aname = '') or (result^.name = aname)) then begin + exit; + end; + inc(result); + end; + result:= nil; +end; + +function tobjectdatainfolist.find(aclassname: string; aname: string): pobjectdatainfoty; +var + int1: integer; +begin + aname:= uppercase(aname); + aclassname:= uppercase(aclassname); + result:= pobjectdatainfoty(fdata); + for int1:= 0 to fcount -1 do begin + if (stringicompupper(result^.objectclass.classname,aclassname) = 0) and + ((aname = '') or (result^.name = aname)) then begin + exit; + end; + inc(result); + end; + result:= nil; +end; + +function tobjectdatainfolist.itempo(const index: integer): pobjectdatainfoty; +begin + result:= pobjectdatainfoty(getitempo(index)); +end; + +procedure tobjectdatainfolist.add(const value: objectdatainfoty); +begin + inherited add(value); +end; + +procedure tobjectdatainfolist.copyrecord(var item); +begin + with objectdatainfoty(item) do begin + reallocstring(name); + end; +end; + +procedure tobjectdatainfolist.finalizerecord(var item); +begin + finalize(objectdatainfoty(item)); +end; + +procedure tobjectdatainfolist.resetchanged; +var + int1: integer; + po1: pobjectdatainfoty; +begin + po1:= pobjectdatainfoty(fdata); + for int1:= 0 to count - 1 do begin + po1^.changed:= false; + inc(po1); + end; +end; + +procedure tobjectdatainfolist.reload(const all: boolean); +var + int1: integer; + int2: integer; + po1: pobjectdatainfoty; + comp1: tmsecomponent; +begin + if fmodules <> nil then begin + po1:= pobjectdatainfoty(fdata); + for int1:= 0 to count - 1 do begin + if all or po1^.changed then begin + for int2:= 0 to fmodules.count - 1 do begin + comp1:= fmodules[int2]; + with comp1 do begin + if (classtype = po1^.objectclass) and (po1^.name = '') or + (stringicompupper(name,po1^.name) = 0) then begin + comp1.name:= ''; + loadmodule(comp1,po1,true); + end; + end; + end; + po1^.changed:= false; + end; + inc(po1); + end; + end; +end; + +procedure tobjectdatainfolist.reloadchanged; +begin + reload(false); +end; + +procedure tobjectdatainfolist.reloadall; +begin + reload(true); +end; + +procedure registerobjectdata(datapo: pobjectdataty; + objectclass: tpersistentclass; name: string = ''); +var + info: objectdatainfoty; +begin + if objectdatalist = nil then begin + objectdatalist:= tobjectdatainfolist.create; + end; + fillchar(info,sizeof(info),0); + info.objectclass:= objectclass; + info.objectdata:= datapo; + info.name:= uppercase(name); + objectdatalist.add(info); + mclasses.registerclass(objectclass); +end; + +procedure registerobjectdata(datapo: pobjectdataty; + const objectclassname: string; const name: string = ''); +var + po1: pobjectdatainfoty; +begin + if objectdatalist <> nil then begin + po1:= objectdatalist.find(objectclassname,name); + if po1 <> nil then begin + po1^.langobjectdata:= datapo; + po1^.changed:= true; + end; + end; +end; + +procedure unregisterobjectdata(const objectclassname: string; const name: string = ''); +var + po1: pobjectdatainfoty; +begin + if objectdatalist <> nil then begin + po1:= objectdatalist.find(objectclassname,name); + if po1 <> nil then begin + po1^.langobjectdata:= nil; + po1^.changed:= true; + end; + end; +end; + +procedure resetchangedmodules; +begin + if objectdatalist <> nil then begin + objectdatalist.resetchanged; + end; +end; + +procedure reloadchangedmodules; +begin + if objectdatalist <> nil then begin + objectdatalist.reloadchanged; + end; +end; + +procedure reloadmodules; +begin + if objectdatalist <> nil then begin + objectdatalist.reloadall; + end; +end; + +procedure getoptionalobject(const componentstate: tcomponentstate; + const instance: tobject; createproc: createprocty); +begin + if (instance = nil) and (csreading in componentstate) then begin + createproc; + end; +end; + +procedure getoptionalobject(const aowner: tcomponent; + const instance: tobject; createproc: createprocty); +var + sta1: tcomponentstate; +begin + sta1:= []; + if aowner <> nil then begin + sta1:= aowner.componentstate; + end; + getoptionalobject(sta1,instance,createproc); +end; + +procedure getoptionalobject(const componentstate: tcomponentstate; + var instance: tvirtualpersistent; const aclass: virtualpersistentclassty); +begin + if (instance = nil) and (csreading{csloading} in componentstate) then begin + instance:= aclass.create; + end; +end; + +procedure setoptionalobject(const componentstate: tcomponentstate; + const value: tpersistent; var instance; createproc: createprocty); +begin + if value <> nil then begin + if tpersistent(instance) = nil then begin + createproc; + end; + if pointer(value) <> pointer(1) then begin + tpersistent(instance).assign(value); + end; + end + else begin + freeandnil(tpersistent(instance)); + end; +end; + +procedure setoptionalobject(const aowner: tcomponent; //can be nil + const value: tpersistent; var instance; + createproc: createprocty); overload; +var + sta1: tcomponentstate; +begin + sta1:= []; + if aowner <> nil then begin + sta1:= aowner.componentstate; + end; + setoptionalobject(sta1,value,instance,createproc); +end; + +procedure setoptionalobject(const componentstate: tcomponentstate; + const value: tvirtualpersistent; var instance; + const aclass: virtualpersistentclassty); +begin + if value <> nil then begin + if tpersistent(instance) = nil then begin + tvirtualpersistent(instance):= aclass.create; + end; + if pointer(value) <> pointer(1) then begin + tpersistent(instance).assign(value); + end; + end + else begin + freeandnil(tpersistent(instance)); + end; +end; + +procedure setlinkedcomponent(const sender: iobjectlink; + const source: tmsecomponent; + var instance: tmsecomponent; ainterfacetype: pointer = nil); +begin + if source <> nil then begin + sender.link(sender,ievent(source),@instance,ainterfacetype); + end; + if instance <> nil then begin + sender.unlink(sender,ievent(instance),@instance); + end; + instance:= source; +end; + +procedure createobjectlinker(const owner: iobjectlink; + onevent: objectlinkeventty; var instance: tobjectlinker); + //sets finstancepo +begin + if instance = nil then begin + instance:= tobjectlinker.create(owner,onevent); + instance.finstancepo:= @instance; + end; +end; + +{ townedpersistent } + +constructor townedpersistent.create(aowner: tobject); +begin + fowner:= aowner; + inherited create; +end; + +{ tobjectlinker } + +{$ifdef debugobjectlink} + + function intftext(aintf: iobjectlink): string; + var + obj1: tobject; + begin + result:= ''; + if odd(ptruint(aintf)) then begin + dec(pointer(aintf)); + end; + if aintf = nil then begin + result:= result+''; + end + else begin + if ptrint(aintf) = 1 then begin + result:= result + '<-1->'; + end + else begin + result:= result + hextostr(longword(aintf),8) + ' '; + obj1:= iobjectlink(aintf).getinstance; + result:= result + hextostr(longword(obj1),8); + if obj1 <> nil then begin + result:= result + ' '+obj1.classname; + end; + if obj1 is tcomponent then begin + result:= result+' '+tcomponent(obj1).Name; + end + else begin + if obj1 is twindow then begin + result:= result+' '+twindow(obj1).owner.Name; + end; + end + end; + end; + end; + +procedure getdebugtext(owner: tobjectlinker; const source,dest:iobjectlink; + valuepo: pointer); +begin + if rels_destroying in owner.fstate then begin + write('*'); + end + else begin + write(' '); + end; + write('v:'+ hextostr(longword(valuepo),8)); + write(' o:'+intftext(iobjectlink(owner.fownerintf))); + write(' s:'+intftext(source)); + write(' d:'+intftext(dest)); + writeln; +end; + +{$endif} + +constructor tobjectlinker.create(const owner: iobjectlink; + onevent: objectlinkeventty); +begin +{$ifdef debugobjectlink} + writeln('create o: ' + intftext(owner)); +{$endif} + pointer(fownerintf):= pointer(owner); + fonevent:= onevent; + inherited create(sizeof(linkinfoty)); +end; + +destructor tobjectlinker.destroy; +var + po1: pointer; + po2: plinkinfoty; + int1: integer; + {$ifndef FPC} + po3: pointer; + {$endif} +begin +{$ifdef debugobjectlink} + writeln('destroy o: ' + intftext(iobjectlink(fownerintf))); +{$endif} + include(fstate,rels_destroying); + po2:= datapo; + for int1:= 0 to count - 1 do begin + with po2^ do begin + po1:= dest; + if po1 <> nil then begin +{$ifdef debugobjectlink} + write('destrev');getdebugtext(self,iobjectlink(source), + iobjectlink(dest),valuepo); +{$endif} + dest:= nil; + if odd(ptruint(source)) then begin + iobjectlink(po1).objevent(iobjectlink(pchar(source)-1),oe_destroyed); + if valuepo <> nil then begin + pobject(valuepo)^:= nil; + end; + end + else begin + {$ifdef FPC} + iobjectlink(po1).unlink(iobjectlink(pointer(1)), + iobjectlink(source),valuepo); + {$else} + po3:= pointer(1); + iobjectlink(po1).unlink(iobjectlink(po3),iobjectlink(source),valuepo); + {$endif} + end; + end; + end; + inc(po2); + end; + pointer(fownerintf):= nil; + inherited; +end; + +procedure tobjectlinker.sendevent(event: objecteventty); +var + int1: integer; +begin + if event <> oe_destroyed then begin + inc(fnopack); + try + int1:= 0; + while int1 < count do begin + with plinkinfoaty(fdata)^[int1] do begin + if dest <> nil then begin + iobjectlink(dest).objevent(iobjectlink(fownerintf),event); + end; + end; + inc(int1); + end; + finally + dec(fnopack); + end; + end; +end; + +procedure tobjectlinker.dopack; +begin + if (fnopack = 0) and not (rels_destroying in fstate) then begin + pack; + if (count = 0) and (finstancepo <> nil) {$ifdef debugobjectlink} + and not debugon {$endif} then begin + freeandnil(finstancepo^); + end; + end; +end; + +procedure tobjectlinker.removelink(var item: linkinfoty; destroyed: boolean); +var + int1: integer; + po1: plinkinfoty; +begin + po1:= plinkinfoty(fdata); + for int1:= 0 to count - 1 do begin + with po1^ do begin + if (dest <> nil) and (dest = item.dest) and + (destroyed or + (valuepo = item.valuepo) and (source = item.source)) then begin + if (refcount = 0) or destroyed then begin + dest:= nil; + end + else begin + dec(refcount); + end; + end; + end; + inc(po1); + end; +end; + +procedure tobjectlinker.link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); +var + info: linkinfoty; + int1: integer; + po1: plinkinfoty; + bo1: boolean; +begin + if not (rels_destroying in fstate) then begin +{$ifdef debugobjectlink} + write('link ');getdebugtext(self,source,dest,valuepo); +{$endif} + fillchar(info,sizeof(info),0); + info.source:= pointer(source); + info.dest:= pointer(dest); + info.valuepo:= valuepo; + info.interfacetype:= ainterfacetype; + if not (once {and (findsource(info) >= 0)}) then begin + bo1:= false; + po1:= datapo; + for int1:= 0 to count - 1 do begin + with po1^ do begin + if (dest = info.dest) and (source = info.source) and + (valuepo = info.valuepo) and (interfacetype = info.interfacetype) then begin + inc(refcount); + bo1:= true; + break; + end + end; + inc(po1); + end; + if not bo1 then begin + add(info); + end; + if not odd(ptruint(source)) then begin //full link + dest.link(iobjectlink(pchar(dest)+1),source,valuepo,ainterfacetype); + //create backlink + source.objevent(dest,oe_connect); + end; + end; + end; +end; + +procedure tobjectlinker.link(const dest: tmsecomponent; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); +begin + if dest <> nil then begin + link(iobjectlink(fownerintf),ievent(dest),valuepo,ainterfacetype,once); + end; +end; + +procedure tobjectlinker.unlink(const source,dest: iobjectlink; valuepo: pointer = nil); +var + info: linkinfoty; +begin +{$ifdef debugobjectlink} + write('unlink');getdebugtext(self,source,dest,valuepo); +{$endif} + info.source:= pointer(source); + info.dest:= pointer(dest); + info.valuepo:= valuepo; + removelink(info,ptrint(source) = 1); + if not odd(ptruint(source)) then begin //full link + inc(fnopack); + dest.unlink(iobjectlink(pchar(dest)+1),source,valuepo); + //remove backlink + dec(fnopack); + end; + dopack; +end; + +procedure tobjectlinker.unlink(const dest: tmsecomponent; valuepo: pointer = nil); +begin + if dest <> nil then begin + unlink(iobjectlink(fownerintf),ievent(dest),valuepo); + end; +end; + +procedure tobjectlinker.setlinkedvar(const linkintf: iobjectlink; + const source: iobjectlink; + var dest: iobjectlink; + const ainterfacetype: pointer = nil); +var + ba: pointer; +begin + if source <> dest then begin + ba:= pointer(dest); + pointer(dest):= pointer(source); + if source <> nil then begin + link(linkintf,source,@dest,ainterfacetype); + end; + if ba <> nil then begin + unlink(linkintf,iobjectlink(ba),@dest); + end; + end; +end; + +procedure tobjectlinker.setlinkedvar(const linkintf: iobjectlink; + const source: tlinkedobject; var dest: tlinkedobject; + const ainterfacetype: pointer = nil); +var + ba: tlinkedobject; +begin + if source <> dest then begin + ba:= dest; + dest:= source; + if source <> nil then begin + link(linkintf,iobjectlink(source),@dest,ainterfacetype); + end; + if ba <> nil then begin + unlink(linkintf,iobjectlink(ba),@dest); + end; + end; +end; + +procedure tobjectlinker.setlinkedvar(const linkintf: iobjectlink; + const source: tlinkedpersistent; var dest: tlinkedpersistent; + const ainterfacetype: pointer = nil); +var + ba: tlinkedpersistent; +begin + if source <> dest then begin + ba:= dest; + dest:= source; + if source <> nil then begin + link(linkintf,iobjectlink(source),@dest,ainterfacetype); + end; + if ba <> nil then begin + unlink(linkintf,iobjectlink(ba),@dest); + end; + end; +end; + +procedure tobjectlinker.setlinkedvar(const linkintf: iobjectlink; + const source: tmsecomponent; var dest: tmsecomponent; + const ainterfacetype: pointer = nil); +var + ba: tmsecomponent; +begin + if source <> dest then begin + ba:= dest; + dest:= source; + if source <> nil then begin + link(linkintf,ievent(source),@dest,ainterfacetype); + end; + if ba <> nil then begin + unlink(linkintf,ievent(ba),@dest); + end; + end; +end; + +procedure tobjectlinker.setlink(const linkintf: iobjectlink; + const source: tmsecomponent; var dest: tmsecomponent; + const ainterfacetype: pointer = nil); overload; + //no automatic nil setting +var + ba: tmsecomponent; +begin + if source <> dest then begin + ba:= dest; + dest:= source; + if source <> nil then begin + link(linkintf,ievent(source),nil,ainterfacetype); + end; + if ba <> nil then begin + unlink(linkintf,ievent(ba),nil); + end; + end; +end; + +function tobjectlinker.isempty(var item): boolean; +begin + with linkinfoty(item) do begin + result:= dest = nil; + end; +end; + +procedure tobjectlinker.objevent(const sender: iobjectlink; + const event: objecteventty); +var + info: linkinfoty; +begin + if event = oe_destroyed then begin + inc(fnopack); + info.dest:= pointer(sender); + info.valuepo:= nil; + removelink(info,true); + end; + if assigned(fonevent) and not (rels_destroying in fstate) then begin + fonevent(sender.getinstance,event); + end; + if event = oe_destroyed then begin + dec(fnopack); + dopack; + end; +end; + +procedure tobjectlinker.forall(const proc: objectlinkprocty; + const ainterfacetype: pointer); +var + po1: plinkinfoty; + int1: integer; +begin + inc(fnopack); + try + for int1:= 0 to fcount - 1 do begin + po1:= @plinkinfoaty(fdata)^[int1]; + if (po1^.dest <> nil) and odd(ptruint(po1^.source)) and + (ainterfacetype = po1^.interfacetype) then begin + proc(po1^); + end; + end; + finally + dec(fnopack); + end; +end; + +procedure tobjectlinker.forall(const proc: objectlinkintfprocty; + const ainterfacetype: pointer); +var + po1: plinkinfoty; + int1: integer; +begin + inc(fnopack); + try + for int1:= 0 to fcount - 1 do begin + po1:= @plinkinfoaty(fdata)^[int1]; + if (po1^.dest <> nil) and odd(ptruint(po1^.source)) and + (ainterfacetype = po1^.interfacetype) then begin + proc(po1^.dest); + end; + end; + finally + dec(fnopack); + end; +end; + +procedure tobjectlinker.forfirst(const proc: objectlinkfirstprocty; + const ainterfacetype: pointer); +var + po1: plinkinfoty; + int1: integer; + bo1: boolean; +begin + inc(fnopack); + try + bo1:= false; + for int1:= 0 to fcount - 1 do begin + po1:= @plinkinfoaty(fdata)^[int1]; + if (po1^.dest <> nil) and odd(ptruint(po1^.source)) and + (ainterfacetype = po1^.interfacetype) then begin + proc(po1^,bo1); + if bo1 then begin + break; + end; + end; + end; + finally + dec(fnopack); + end; +end; + +procedure tobjectlinker.forfirst(const proc: objectlinkintffirstprocty; + const ainterfacetype: pointer); +var + po1: plinkinfoty; + int1: integer; + bo1: boolean; +begin + inc(fnopack); + try + bo1:= false; + for int1:= 0 to fcount - 1 do begin + po1:= @plinkinfoaty(fdata)^[int1]; + if (po1^.dest <> nil) and odd(ptruint(po1^.source)) and + (ainterfacetype = po1^.interfacetype) then begin + proc(po1^.dest,bo1); + if bo1 then begin + break; + end; + end; + end; + finally + dec(fnopack); + end; +end; + +function tobjectlinker.linkedobjects: objectarty; +var + po1: plinkinfoty; + int1: integer; +begin + result:= nil; + po1:= plinkinfoty(fdata); + for int1:= 0 to fcount - 1 do begin + if (po1^.dest <> nil) and odd(ptruint(po1^.source)) then begin + additem(pointerarty(result),iobjectlink(po1^.dest).getinstance); + end; + inc(po1); + end; + removearrayduplicates(pointerarty(result)); +end; + +function tobjectlinker.linkedobjects( + const ainterfacetype: pointer): objectarty; +var + po1: plinkinfoty; + int1: integer; +begin + result:= nil; + po1:= plinkinfoty(fdata); + for int1:= 0 to fcount - 1 do begin + if (po1^.dest <> nil) and odd(ptruint(po1^.source)) and + (po1^.interfacetype = ainterfacetype) then begin + additem(pointerarty(result),iobjectlink(po1^.dest).getinstance); + end; + inc(po1); + end; + removearrayduplicates(pointerarty(result)); +end; + +{ tlinkedobject } + +destructor tlinkedobject.destroy; +begin + inherited; + freeandnil(fobjectlinker); +end; + +function tlinkedobject.getobjectlinker: tobjectlinker; +begin + createobjectlinker(self,{$ifdef FPC}@{$endif}objectevent,fobjectlinker); + result:= fobjectlinker; +end; + +procedure tlinkedobject.objectevent(const sender: tobject; + const event: objecteventty); +begin + //dummy +end; + +procedure tlinkedobject.setlinkedvar(const source: tmsecomponent; + var dest: tmsecomponent; + const linkintf: iobjectlink = nil); +begin + if linkintf = nil then begin + getobjectlinker.setlinkedvar(iobjectlink(self),source,dest); + end + else begin + getobjectlinker.setlinkedvar(linkintf,source,dest); + end; +end; + +procedure tlinkedobject.setlinkedvar(const source: tlinkedobject; + var dest: tlinkedobject; + const linkintf: iobjectlink = nil); +begin + if linkintf = nil then begin + getobjectlinker.setlinkedvar(iobjectlink(self),source,dest); + end + else begin + getobjectlinker.setlinkedvar(linkintf,source,dest); + end; +end; + +procedure tlinkedobject.link(const source,dest: iobjectlink; + valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); +begin + getobjectlinker.link(source,dest,valuepo,ainterfacetype,once); +end; + +procedure tlinkedobject.unlink(const source,dest: iobjectlink; + valuepo: pointer = nil); +begin + getobjectlinker.unlink(source,dest,valuepo); +end; + +procedure tlinkedobject.objevent(const sender: iobjectlink; + const event: objecteventty); +begin + getobjectlinker.objevent(sender,event); +end; + +function tlinkedobject.getinstance: tobject; +begin + result:= self; +end; + +{ tlinkedrecordlist } + +destructor tlinkedrecordlist.destroy; +begin + inherited; + freeandnil(fobjectlinker); +end; + +function tlinkedrecordlist.getobjectlinker: tobjectlinker; +begin + createobjectlinker(self,{$ifdef FPC}@{$endif}objectevent,fobjectlinker); + result:= fobjectlinker; +end; + +procedure tlinkedrecordlist.objectevent(const sender: tobject; + const event: objecteventty); +begin + //dummy +end; + +procedure tlinkedrecordlist.setlinkedvar(const source: tmsecomponent; + var dest: tmsecomponent; const linkintf: iobjectlink = nil); +begin + if linkintf = nil then begin + getobjectlinker.setlinkedvar(iobjectlink(self),source,dest); + end + else begin + getobjectlinker.setlinkedvar(linkintf,source,dest); + end; +end; + +procedure tlinkedrecordlist.setlinkedvar(const source: tlinkedobject; + var dest: tlinkedobject; + const linkintf: iobjectlink = nil); +begin + if linkintf = nil then begin + getobjectlinker.setlinkedvar(iobjectlink(self),source,dest); + end + else begin + getobjectlinker.setlinkedvar(linkintf,source,dest); + end; +end; + +procedure tlinkedrecordlist.link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); +begin + getobjectlinker.link(source,dest,valuepo,ainterfacetype,once); +end; + +procedure tlinkedrecordlist.unlink(const source,dest: iobjectlink; valuepo: pointer = nil); +begin + getobjectlinker.unlink(source,dest,valuepo); +end; + +procedure tlinkedrecordlist.objevent(const sender: iobjectlink; const event: objecteventty); +begin + getobjectlinker.objevent(sender,event); +end; + +function tlinkedrecordlist.getinstance: tobject; +begin + result:= self; +end; + +(* +{ tnullinterfacedobject } + +function tnullinterfacedobject._addref: integer; stdcall; +begin + result:= -1; +end; + +function tnullinterfacedobject._release: integer; stdcall; +begin + result:= -1; +end; + +function tnullinterfacedobject.queryinterface( + {$ifdef fpc_has_constref}constref{$else}const{$endif}iid: tguid; + out obj): hresult; stdcall; +begin + if getinterface(iid, obj) then begin + result:=0 + end + else begin + result:= integer(e_nointerface); + end; +end; +*) +{ tnullinterfacedpersistent } +{$ifdef FPC} +function tnullinterfacedpersistent._addref: integer; + {$ifdef mswindows}stdcall{$else} cdecl{$endif}; +begin + result:= -1; +end; + +function tnullinterfacedpersistent._release: integer; + {$ifdef mswindows}stdcall{$else} cdecl{$endif}; +begin + result:= -1; +end; + +function tnullinterfacedpersistent.QueryInterface( + {$ifdef fpc_has_constref}constref{$else}const{$endif} IID: TGUID; + out Obj): HResult; + {$ifdef mswindows}stdcall{$else} cdecl{$endif}; +begin + if GetInterface(IID, Obj) then begin + Result:=0 + end + else begin + result:= integer(e_nointerface); + end; +end; +{$endif} + +{ toptionalpersistent } + +procedure toptionalpersistent.readdummy(reader: treader); +begin + reader.readinteger; +end; + +procedure toptionalpersistent.writedummy(writer: twriter); +begin + writer.writeinteger(0); +end; + +procedure toptionalpersistent.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('dummy',{$ifdef FPC}@{$endif}readdummy, + {$ifdef FPC}@{$endif}writedummy,(filer.ancestor = nil) and isoptional); + //in order to create optional instance +end; + +function toptionalpersistent.isoptional: boolean; +begin + result:= true; +end; + +{ tlinkedoptionalpersistent } + +procedure tlinkedoptionalpersistent.readdummy(reader: treader); +begin + reader.readinteger; +end; + +procedure tlinkedoptionalpersistent.writedummy(writer: twriter); +begin + writer.writeinteger(0); +end; + +procedure tlinkedoptionalpersistent.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('dummy',{$ifdef FPC}@{$endif}readdummy, + {$ifdef FPC}@{$endif}writedummy,(filer.ancestor = nil) and isoptional); + //in order to create optional instance +end; + +function tlinkedoptionalpersistent.isoptional: boolean; +begin + result:= true; +end; + +{ tlinkedpersistent } + +destructor tlinkedpersistent.destroy; +begin + inherited; + freeandnil(fobjectlinker); +end; + +function tlinkedpersistent.getobjectlinker: tobjectlinker; +begin + if fobjectlinker = nil then begin + createobjectlinker(iobjectlink(self),{$ifdef FPC}@{$endif}objectevent,fobjectlinker); + end; + result:= fobjectlinker; +end; + +procedure tlinkedpersistent.objectevent(const sender: tobject; + const event: objecteventty); +begin + //dummy +end; + +procedure tlinkedpersistent.setlinkedvar(const source: tmsecomponent; var dest: tmsecomponent; + const linkintf: iobjectlink = nil); +begin + if linkintf = nil then begin + getobjectlinker.setlinkedvar(iobjectlink(self),source,dest); + end + else begin + getobjectlinker.setlinkedvar(linkintf,source,dest); + end; +end; + +procedure tlinkedpersistent.setlinkedvar(const source: iobjectlink; var dest: iobjectlink; + const linkintf: iobjectlink = nil); +begin + if linkintf = nil then begin + getobjectlinker.setlinkedvar(iobjectlink(self),source,dest); + end + else begin + getobjectlinker.setlinkedvar(linkintf,source,dest); + end; +end; + +procedure tlinkedpersistent.setlinkedvar(const source: tlinkedobject; var dest: tlinkedobject; + const linkintf: iobjectlink = nil); +begin + if linkintf = nil then begin + getobjectlinker.setlinkedvar(iobjectlink(self),source,dest); + end + else begin + getobjectlinker.setlinkedvar(linkintf,source,dest); + end; +end; + +procedure tlinkedpersistent.setlinkedvar(const source: tlinkedpersistent; + var dest: tlinkedpersistent; const linkintf: iobjectlink = nil); +begin + if linkintf = nil then begin + getobjectlinker.setlinkedvar(iobjectlink(self),source,dest); + end + else begin + getobjectlinker.setlinkedvar(linkintf,source,dest); + end; +end; + +procedure tlinkedpersistent.link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); +begin + getobjectlinker.link(source,dest,valuepo,ainterfacetype,once); +end; + +procedure tlinkedpersistent.unlink(const source,dest: iobjectlink; valuepo: pointer = nil); +begin + getobjectlinker.unlink(source,dest,valuepo); +end; + +procedure tlinkedpersistent.objevent(const sender: iobjectlink; + const event: objecteventty); +begin + getobjectlinker.objevent(sender,event); +end; + +function tlinkedpersistent.getinstance: tobject; +begin + result:= self; +end; + +{ teventobject } + +procedure teventobject.receiveevent(const event: tobjectevent); +begin + //dummy +end; + +{ tcomponentevent } + +constructor tcomponentevent.create(const asender: tobject; const atag: integer = 0; + const callchildren: boolean = true); +begin + inherited create(ek_component,nil); + fsender:= asender; + tag:= atag; + if callchildren then begin + state:= [ces_callchildren]; + end; +end; + + { tmsecomponent } + +destructor tmsecomponent.destroy; +begin + inherited; + freeandnil(fobjectlinker); +end; + +function tmsecomponent.getobjectlinker: tobjectlinker; +begin + if fobjectlinker = nil then begin + createobjectlinker(ievent(self),{$ifdef FPC}@{$endif}objectevent,fobjectlinker); + end; + result:= fobjectlinker; +end; + +procedure tmsecomponent.initnewcomponent(const ascale: real); +begin + //dummy +end; + +function tmsecomponent.checkowned(component: tcomponent): boolean; +begin + result:= false; + while component <> nil do begin + if component = self then begin + result:= true; + break; + end; + component:= component.Owner; + end; +end; + +function tmsecomponent.checkowner(component: tcomponent): boolean; +var + comp1: tcomponent; +begin + result:= false; + comp1:= self; + while comp1 <> nil do begin + if comp1 = component then begin + result:= true; + break; + end; + comp1:= comp1.Owner; + end; +end; + +function tmsecomponent.rootowner: tcomponent; +begin + result:= owner; + if result <> nil then begin + while result.owner <> nil do begin + result:= result.Owner; + end; + end; +end; +{ +function tmsecomponent.rootcomponent: tcomponent; +begin + result:= rootowner; + if result = nil then begin + result:= self; + end; +end; +} +function tmsecomponent.getrootcomponentpath: componentarty; +var + count: integer; + comp: tcomponent; +begin + result:= nil; + count:= 0; + comp:= self; + while comp <> nil do begin + if length(result) <= count then begin + setlength(result,length(result)+32); + end; + result[count]:= comp; + inc(count); + comp:= comp.owner; + end; + setlength(result,count); +end; + +procedure tmsecomponent.setlinkedvar(const source: iobjectlink; + var dest: iobjectlink; const linkintf: iobjectlink = nil); +begin + if (fobjectlinker = nil) and (csdestroying in componentstate) then begin + dest:= source; + end + else begin + if linkintf = nil then begin + getobjectlinker.setlinkedvar(ievent(self),source,dest); + end + else begin + getobjectlinker.setlinkedvar(linkintf,source,dest); + end; + end; +end; + +procedure tmsecomponent.setlinkedvar(const source: tmsecomponent; + var dest: tmsecomponent; const linkintf: iobjectlink = nil); +begin + if (fobjectlinker = nil) and (csdestroying in componentstate) then begin + dest:= source; + end + else begin + if linkintf = nil then begin + getobjectlinker.setlinkedvar(ievent(self),source,dest); + end + else begin + getobjectlinker.setlinkedvar(linkintf,source,dest); + end; + end; +end; + +procedure tmsecomponent.setlinkedvar(const source: tlinkedobject; + var dest: tlinkedobject; const linkintf: iobjectlink = nil); +begin + if (fobjectlinker = nil) and (csdestroying in componentstate) then begin + dest:= source; + end + else begin + if linkintf = nil then begin + getobjectlinker.setlinkedvar(ievent(self),source,dest); + end + else begin + getobjectlinker.setlinkedvar(linkintf,source,dest); + end; + end; +end; + +procedure tmsecomponent.setlinkedvar(const source: tlinkedpersistent; + var dest: tlinkedpersistent; const linkintf: iobjectlink = nil); +begin + if (fobjectlinker = nil) and (csdestroying in componentstate) then begin + dest:= source; + end + else begin + if linkintf = nil then begin + getobjectlinker.setlinkedvar(ievent(self),source,dest); + end + else begin + getobjectlinker.setlinkedvar(linkintf,source,dest); + end; + end; +end; + +function tmsecomponent.linkcount: integer; +begin + if fobjectlinker = nil then begin + result:= 0; + end + else begin + result:= fobjectlinker.count; + end; +end; + +function tmsecomponent.canevent(const event: tmethod): boolean; +begin + result:= (event.code <> nil) and (event.data <> nil) and + (componentstate * [csloading,csdesigning,csdestroying] = []); +end; + +function tmsecomponent.candestroyevent(const event: tmethod): boolean; +begin + result:= (event.code <> nil) and (event.data <> nil) and + (componentstate * [csloading,csdesigning] = []); +end; + +procedure tmsecomponent.receiveevent(const event: tobjectevent); +var + int1: integer; +begin + case event.kind of + ek_async: begin + int1:= tasyncevent(event).tag; + doasyncevent(int1); + end; + ek_component: begin + sendcomponentevent(event as tcomponentevent,false); + end; + end; +end; + +procedure tmsecomponent.asyncevent(atag: integer = 0; + const aoptions: posteventoptionsty = []); +begin + application.postevent(tasyncevent.create(ievent(self),atag),aoptions); +end; + +procedure tmsecomponent.doasyncevent(var atag: integer); +begin + //dummy +end; + +procedure tmsecomponent.postcomponentevent(const event: tcomponentevent; + const aoptions: posteventoptionsty = []); +begin + event.create(event.kind,ievent(self)); + application.postevent(event,aoptions); +end; + +{$ifdef FPC} + +procedure tmsecomponent.setinline(value: boolean); +begin + if value then begin + include(fcomponentstate,csinline); + end + else begin + exclude(fcomponentstate,csinline); + end; +end; + +procedure tmsecomponent.setancestor(value: boolean); +begin + if value then begin + include(fcomponentstate,csancestor); + end + else begin + exclude(fcomponentstate,csancestor); + end; +end; + +{$endif FPC} + +{$ifdef hascorbagetinterface} +function getcorbainterface(const aobject: tobject; const aintf: ptypeinfo; + out obj) : boolean; +var + typedata1: ptypedata; + po1: pshortstring; +begin + pointer(obj):= nil; + result:= false; + if aobject <> nil then begin + typedata1:= gettypedata(aintf); + po1:= pshortstring( + ptruint(@typedata1^.rawintfunit)+length(typedata1^.rawintfunit)+1); + po1:= aligntoptr(pointer(po1)); + if po1^[0] <> #0 then begin + result:= aobject.getinterfacebystr(po1^,obj); //works in FPC 2.4+ + end + end; +end; + +{$else} + +function getcorbainterface(const aobject: tobject; const aintf: ptypeinfo; + out obj) : boolean; +var + intf1: pinterfaceentry; + typedata1: ptypedata; + po1: pshortstring; +begin +// result:= getinterface(aintf,obj); + typedata1:= gettypedata(aintf); + {$ifdef FPC} + po1:= pshortstring( + ptruint(@typedata1^.rawintfunit)+length(typedata1^.rawintfunit)+1); + if po1^[0] <> #0 then begin + intf1:= aobject.getinterfaceentrybystr(po1^); + end + else begin + intf1:= nil; + end; + {$else} + intf1:= aobject.getinterfaceentry(typedata1^.guid); + {$endif} + if intf1 <> nil then begin + {$ifdef FPC} + pointer(obj):= pointer(aobject) + intf1^.ioffset; + {$else} + pointer(obj):= pointer(integer(aobject) + intf1^.ioffset); + {$endif} + result:= true; + end + else begin + pointer(obj):= nil; + result:= false; + end; +end; +{$endif} //hascorbagetinterface + +procedure nosupportfor(const sender: tcomponent; const avalue: tcomponent; + const ainterface: ptypeinfo); +begin + raise exception.create(sender.name+': '+avalue.name+' does not provide '+ + ainterface^.name+'.'); +end; + +procedure checkcorbainterface(const sender: tcomponent; + const avalue: tcomponent; + const ainterface: ptypeinfo; out obj); +begin + if not getcorbainterface(avalue,ainterface,obj) then begin + nosupportfor(sender,avalue,ainterface); + end; +end; + +//function tmsecomponent.getcorbainterface(const aintf: tguid; out obj) : boolean; +function tmsecomponent.getcorbainterface(const aintf: ptypeinfo; + out obj) : boolean; +begin + result:= mseclasses.getcorbainterface(self,aintf,obj); +end; + +function isinterface(const actual: ptypeinfo; const wanted: ptypeinfo): boolean; +var + po1: ptypeinfo; +begin +{$ifdef FPC} + result:= (actual^.kind = tkinterfaceraw) and (wanted^.kind = tkinterfaceraw); + if result then begin + po1:= actual; + while po1 <> nil do begin + if po1 = wanted then begin + exit; + end; + po1:= gettypedata(po1)^.rawintfparent; + end; + result:= false; + end + else begin +{$endif} + result:= (actual^.kind = tkinterface) and (wanted^.kind = tkinterface); + if result then begin + po1:= actual; + while po1 <> nil do begin + if po1 = wanted then begin + exit; + end; + po1:= gettypedata(po1)^.intfparent{$ifndef FPC}^{$endif}; + end; + result:= false; + end; +{$ifdef FPC} + end; +{$endif} +end; + +function isinterfaceornil(const actual: ptypeinfo; const wanted: ptypeinfo): boolean; +begin + result:= (actual = nil) or isinterface(actual,wanted); +end; + +procedure tmsecomponent.link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); +begin + getobjectlinker.link(source,dest,valuepo,ainterfacetype,once); +end; + +procedure tmsecomponent.unlink(const source,dest: iobjectlink; valuepo: pointer = nil); +begin + getobjectlinker.unlink(source,dest,valuepo); +end; + +procedure tmsecomponent.objevent(const sender: iobjectlink; + const event: objecteventty); +begin + getobjectlinker.objevent(sender,event); +end; + +function tmsecomponent.getinstance: tobject; +begin + result:= self; +end; + +function tmsecomponent.getcomponent: tcomponent; +begin + result:= self; +end; + +function tmsecomponent.getcomponentinstance: tcomponent; +begin + result:= self; +end; + +procedure tmsecomponent.getcompchildren(const proc: tgetchildproc; + const root: tcomponent); +var + int1: integer; + comp1: tcomponent; +begin + if root = self then begin + for int1:= 0 to componentcount - 1 do begin + comp1:= components[int1]; + if not (cssubcomponent in comp1.componentstyle) and + not comp1.hasparent or (comp1 is tmsedatamodule) then begin + proc(comp1); + end; + end; + end; +end; + +procedure tmsecomponent.componentevent(const event: tcomponentevent); +var + int1: integer; + comp1: tcomponent; +begin + with event do begin + if ces_callchildren in state then begin + for int1:= 0 to componentcount - 1 do begin + if ces_processed in state then begin + break; + end; + comp1:= components[int1]; + if comp1 is tmsecomponent then begin + tmsecomponent(comp1).componentevent(event); + end; + end; + end; + end; +end; + +procedure tmsecomponent.sendcomponentevent(const event: tcomponentevent; + const destroyevent: boolean); +begin + try + componentevent(event); + finally + if destroyevent then begin + event.Free1; + end; + end; +end; + +procedure tmsecomponent.sendrootcomponentevent(const event: tcomponentevent; + const destroyevent: boolean); +var + int1: integer; + ar1: componentarty; +begin + try + ar1:= getrootcomponentpath; + for int1:= high(ar1) downto 0 do begin + if ar1[int1] is tmsecomponent then begin + tmsecomponent(ar1[int1]).sendcomponentevent(event,false); + break; + end; + end; + finally + if destroyevent then begin + event.Free1; + end; + end; +end; + +procedure tmsecomponent.getoptionalobject(const instance: tobject; + createproc: createprocty); +begin + if not (cs_endreadproc in fmsecomponentstate) then begin + mseclasses.getoptionalobject(componentstate,instance,createproc); + end; +end; + +procedure tmsecomponent.setoptionalobject(const value: tpersistent; + var instance; createproc: createprocty); +begin + mseclasses.setoptionalobject(componentstate,value,instance,createproc); +end; + +procedure tmsecomponent.loaded; +begin + inherited; + include(fmsecomponentstate,cs_loadedproc); + try + sendchangeevent; + finally + exclude(fmsecomponentstate,cs_loadedproc); + end; +end; + +procedure tmsecomponent.beginread; +var + int1: integer; + comp1: tcomponent; +begin + include(fmsecomponentstate,cs_beginreadproc); + try + dobeginread; + for int1:= 0 to componentcount - 1 do begin + comp1:= components[int1]; + if (cssubcomponent in comp1.componentstyle) and + (comp1 is tmsecomponent) then begin + tmsecomponent(comp1).beginread; + end; + end; + finally + exclude(fmsecomponentstate,cs_beginreadproc); + end; +end; + +procedure tmsecomponent.endread; +var + int1: integer; + comp1: tcomponent; +begin + include(fmsecomponentstate,cs_endreadproc); + try + doendread; + for int1:= 0 to componentcount - 1 do begin + comp1:= components[int1]; + if (cssubcomponent in comp1.componentstyle) and + (comp1 is tmsecomponent) then begin + tmsecomponent(comp1).endread; + end; + end; + finally + exclude(fmsecomponentstate,cs_endreadproc); + end; +end; + +procedure tmsecomponent.readstate(reader: treader); +begin + beginread; + inherited; + endread; +end; + +procedure tmsecomponent.objectevent(const sender: tobject; + const event: objecteventty); +begin + //dummy +end; + +procedure tmsecomponent.sendchangeevent(const aevent: objecteventty = oe_changed); +begin + if (fobjectlinker <> nil) and not (csloading in componentstate) then begin + fobjectlinker.sendevent(aevent); + end; +end; + +procedure tmsecomponent.designselected(const selected: boolean); +begin + //dummy +end; + +function tmsecomponent.getancestorclassname: string; +begin + if fancestorclassname <> '' then begin + result:= fancestorclassname; + end + else begin + result:= getmoduleclassname; + end; +end; + +procedure tmsecomponent.readmoduleclassname(reader: treader); +begin + reader.ReadString; //dummy +end; + +procedure tmsecomponent.writemoduleclassname(writer: twriter); +begin + writer.writestring(getancestorclassname); +end; + +procedure tmsecomponent.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty(moduleclassnamename, + {$ifdef FPC}@{$endif}readmoduleclassname, + {$ifdef FPC}@{$endif}writemoduleclassname, + (cs_ismodule in fmsecomponentstate) and (filer.Root = self) and + ((filer.ancestor = nil) or + (tmsecomponent(filer.ancestor).getancestorclassname <> + getancestorclassname))); +end; + +function tmsecomponent.getactualclassname: string; +begin + if factualclassname <> nil then begin + result:= factualclassname^; + end + else begin + result:= classname; + end; +end; + +class function tmsecomponent.getmoduleclassname: string; +begin + result:= tmsecomponent.classname; +end; + +class function tmsecomponent.hasresource: boolean; +begin + result:= false; +end; + +(* +function setclassname(const instance: tobject; + const aclassname: pshortstring): pshortstring; +var + classnamepo: ppointer; + {$ifdef mswindows} + ca1: longword; + {$endif} +begin + if aclassname = nil then begin + result:= nil; + end + else begin + classnamepo:= ppointer(pchar(instance.classtype)+vmtclassname); + {$ifdef mswindows} + virtualprotect(classnamepo,sizeof(pointer),page_readwrite,{$ifdef FPC}@{$endif}ca1); + {$endif} + result:= classnamepo^; + classnamepo^:= aclassname; + {$ifdef mswindows} + virtualprotect(classnamepo,sizeof(pointer),ca1,nil); + {$endif} + end; +end; +*) + +procedure tmsecomponent.writestate(writer: twriter); +//var +// classnamebefore: pshortstring; +begin +// classnamebefore:= setclassname(self,factualclassname); +// try + if writer is twritermse then begin + twritermse(writer).writecomponentdata(self); + end + else begin + inherited; + end; +// finally +// setclassname(self,classnamebefore); +// end; +end; + +function tmsecomponent.gethelpcontext: msestring; +begin + result:= fhelpcontext; +end; + +class function tmsecomponent.classskininfo: skininfoty; +begin + fillchar(result,sizeof(result),0); + result.objectkind:= sok_component; +end; + +function tmsecomponent.skininfo: skininfoty; +begin + result:= classskininfo; + result.instance:= self; +end; + +function tmsecomponent.linkedobjects: objectarty; +begin + result:= objectarty(getlinkedcomponents(self)); + if fobjectlinker <> nil then begin + stackarray(pointerarty(fobjectlinker.linkedobjects),pointerarty(result)); + end; + removearrayduplicates(pointerarty(result)); +end; + +function tmsecomponent.loading: boolean; +begin + result:= csloading in componentstate; +end; + +procedure tmsecomponent.dobeginread; +begin + //dummy +end; + +procedure tmsecomponent.doendread; +begin + //dummy +end; + +procedure tmsecomponent.doafterload; +begin + //dummy +end; +{ +procedure tmsecomponent.getchildren1(const proc: tgetchildproc; + const root: tcomponent); +begin + //dummy +end; + +procedure tmsecomponent.getchildren(proc: tgetchildproc; root: tcomponent); +var + ev1: getchildreneventty; +begin + ev1:= onstreaminggetchildren; + if assigned(ev1) then begin + ev1(self,proc,root); + end + else begin + getchildren1(proc,root); + end; +end; +} +procedure tmsecomponent.updateskin(const recursive: boolean = false); +var + int1: integer; + comp1: tcomponent; + methodpo: ^skineventty; +begin + if componentstate*[csdesigning] = [] then begin + methodpo:= {$ifndef FPC}@{$endif}@oninitskinobject; + end + else begin +// methodpo:= {$ifndef FPC}@{$endif}@oninitskinobjectdesign; + exit; //do nothing + end; + if assigned(methodpo^) then begin + if recursive then begin + for int1:= 0 to componentcount - 1 do begin + comp1:= components[int1]; + if comp1 is tmsecomponent then begin + tmsecomponent(comp1).updateskin(true); + end; + end; + end; + if hasskin then begin +// if cs_skinloaded in fmsecomponentstate then begin +// removeskin; +// end; + if assigned(fonbeforeupdateskin) then begin + fonbeforeupdateskin(tobject(tmethod(methodpo^).data)); + end; + methodpo^(skininfo); +// include(fmsecomponentstate,cs_skinloaded); + if assigned(fonbeforeupdateskin) then begin + fonafterupdateskin(tobject(tmethod(methodpo^).data)); + end; + end; + end; +end; +(* +procedure tmsecomponent.removeskin(const recursive: boolean = false); +var + int1: integer; + comp1: tcomponent; + methodpo: ^skineventty; +begin + if componentstate*[csdesigning] = [] then begin + methodpo:= {$ifndef FPC}@{$endif}@onremoveskinobject; + end + else begin + methodpo:= {$ifndef FPC}@{$endif}@onremoveskinobjectdesign; + end; + if assigned(methodpo^) then begin + if recursive then begin + for int1:= 0 to componentcount - 1 do begin + comp1:= components[int1]; + if comp1 is tmsecomponent then begin + tmsecomponent(comp1).removeskin(true); + end; + end; + end; + if hasskin and (cs_skinloaded in fmsecomponentstate) then begin + methodpo^(skininfo); + exclude(fmsecomponentstate,cs_skinloaded); + end; + end; +end; +*) +function tmsecomponent.getmsecomponentstate: msecomponentstatesty; +begin + result:= fmsecomponentstate; +end; + +function tmsecomponent.hasskin: boolean; +begin + result:= true; +end; + +procedure tmsecomponent.validaterename(acomponent: tcomponent; + const curname: string; const newname: string); +begin + inherited; + if componentstate * [csdesigning,csreading,csloading,csdestroying] = + [csdesigning] then begin + if acomponent = nil then begin + acomponent:= self; + end; + designvalidaterename(acomponent,curname,newname); + end; +end; + +procedure tmsecomponent.setsubcompref; +begin + setsubcomponent(true); + include (fmsecomponentstate,cs_subcompref); +end; + +procedure tmsecomponent.setchildorder(child: tcomponent; order: integer); +var + int1,int2: integer; +begin + int2:= -1; + for int1:= 0 to componentcount-1 do begin + if not components[int1].hasparent then begin //number simple owned only + inc(int2); + if int2 = order then begin + child.componentindex:= int1; + break; + end; + end; + end; +end; + +{$ifdef mse_with_ifi} +procedure tmsecomponent.setifiserverintf(const aintf: iifiserver); +begin + fifiserverintf:= aintf; +end; +{ +function tmsecomponent.getifiserverintf: iifiserver; +begin + result:= fifiserverintf; +end; +} +procedure tmsecomponent.executeificommand(var acommand: ificommandcodety); +begin + //dummy +end; + +function tmsecomponent.getdefaultifilink: iificlient; +begin + result:= iificlient(self); +end; + +function tmsecomponent.getifidatatype: listdatatypety; +begin + result:= dl_none; +end; + +{$endif} + +{ tlinkedqueue } + +constructor tlinkedqueue.create(aownsobjects: boolean); +begin + fownsobjects:= aownsobjects; + fobjectlinker:= tobjectlinker.create(iobjectlink(self),{$ifdef FPC}@{$endif}objectevent); + inherited create; +end; + +destructor tlinkedqueue.destroy; +begin + include(fobjectlinker.fstate,rels_destroying); + inherited; + freeandnil(fobjectlinker); +end; + +function tlinkedqueue.destroying: boolean; +begin + result:= (fobjectlinker = nil) or (rels_destroying in fobjectlinker.fstate); +end; + +function tlinkedqueue.add(const value: iobjectlink): integer; +begin + result:= inherited add(pointer(value)); + fobjectlinker.link(iobjectlink(self),value); +end; + +function tlinkedqueue.getfirst: iobjectlink; +begin + result:= iobjectlink(inherited getfirst); + fobjectlinker.unlink(iobjectlink(self),result); +end; + +function tlinkedqueue.getlast: iobjectlink; +begin + result:= iobjectlink(inherited getlast); + fobjectlinker.unlink(iobjectlink(self),result); +end; + +function tlinkedqueue.getitems(const index: integer): iobjectlink; +begin + result:= iobjectlink(inherited getitems(index)); +end; + +procedure tlinkedqueue.insert(const index: integer; + const value: iobjectlink); +begin + inherited insert(index,pointer(value)); + fobjectlinker.link(iobjectlink(self),value); +end; + +procedure tlinkedqueue.setitems(const index: integer; + const Value: iobjectlink); +begin + fobjectlinker.unlink(iobjectlink(self),getitems(index)); + inherited setitems(index,pointer(value)); + fobjectlinker.link(iobjectlink(self),value); +end; + +procedure tlinkedqueue.objectevent(const sender: tobject; + const event: objecteventty); +begin + //dummy +end; + +procedure tlinkedqueue.link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); +begin + fobjectlinker.link(source,dest,valuepo,ainterfacetype,once); +end; + +procedure tlinkedqueue.unlink(const source,dest: iobjectlink; valuepo: pointer = nil); +begin + fobjectlinker.unlink(source,dest,valuepo); +end; + +procedure tlinkedqueue.objevent(const sender: iobjectlink; const event: objecteventty); +begin + fobjectlinker.objevent(sender,event); + if event = oe_destroyed then begin + linkdestroyed(sender); + inc(fnofinalize); + try + remove(pointer(sender)); + finally + dec(fnofinalize); + end; + end; +end; + +function tlinkedqueue.getinstance: tobject; +begin + result:= fainstance; +end; + +procedure tlinkedqueue.finalizeitem(var item: pointer); +begin + fobjectlinker.unlink(iobjectlink(self),iobjectlink(item)); + if fownsobjects then begin + iobjectlink(item).getinstance.Free; + end; + inherited; +end; + +procedure tlinkedqueue.sendchangenotification(sender: tobject); +begin + fainstance:= sender; + fobjectlinker.sendevent(oe_changed); + fainstance:= nil; +end; + +procedure tlinkedqueue.linkdestroyed(const alink: iobjectlink); +begin + //dummy +end; + +{ tlinkedobjectqueue } + +function tlinkedobjectqueue.add(const value: tlinkedobject): integer; +begin + result:= inherited add(iobjectlink(value)); +end; + +function tlinkedobjectqueue.getfirst: tlinkedobject; +begin + result:= tlinkedobject(inherited getfirst.getinstance); +end; + +function tlinkedobjectqueue.getlast: tlinkedobject; +begin + result:= tlinkedobject(inherited getlast.getinstance); +end; + +function tlinkedobjectqueue.getitems(const index: integer): tlinkedobject; +begin + result:= tlinkedobject(inherited getitems(index).getinstance); +end; + +procedure tlinkedobjectqueue.insert(const index: integer; + const value: tlinkedobject); +begin + inherited insert(index,iobjectlink(value)); +end; + +procedure tlinkedobjectqueue.setitems(const index: integer; + const Value: tlinkedobject); +begin + inherited setitems(index,iobjectlink(value)); +end; + +function tlinkedobjectqueue.findobject(const aobject: tlinkedobject): integer; +begin + result:= indexof(pointer(iobjectlink(aobject))); +end; + +{ tpersistentqueue } + +procedure tpersistentqueue.add(const value: tlinkedpersistent); +begin + inherited add(iobjectlink(value)); +end; + +function tpersistentqueue.getfirst: tlinkedpersistent; +begin + result:= tlinkedpersistent(inherited getfirst.getinstance); +end; + +function tpersistentqueue.getlast: tlinkedpersistent; +begin + result:= tlinkedpersistent(inherited getlast.getinstance); +end; + +function tpersistentqueue.getitems(const index: integer): tlinkedpersistent; +begin + result:= tlinkedpersistent(inherited getitems(index).getinstance); +end; + +procedure tpersistentqueue.insert(const index: integer; + const value: tlinkedpersistent); +begin + inherited insert(index,iobjectlink(value)); +end; + +procedure tpersistentqueue.setitems(const index: integer; + const Value: tlinkedpersistent); +begin + inherited setitems(index,iobjectlink(value)); +end; + +function tpersistentqueue.findobject(const aobject: tlinkedpersistent): integer; +begin + result:= indexof(pointer(iobjectlink(aobject))); +end; + +{ tcomponentqueue } + +function tcomponentqueue.add(const value: tmsecomponent): integer; +begin + result:= inherited add(ievent(value)); +end; + +function tcomponentqueue.getfirst: tmsecomponent; +begin + result:= tmsecomponent(inherited getfirst.getinstance); +end; + +function tcomponentqueue.getlast: tmsecomponent; +begin + result:= tmsecomponent(inherited getlast.getinstance); +end; + +function tcomponentqueue.getitems(const index: integer): tmsecomponent; +begin + result:= tmsecomponent(inherited getitems(index).getinstance); +end; + +procedure tcomponentqueue.insert(const index: integer; + const value: tmsecomponent); +begin + inherited insert(index,ievent(value)); +end; + +procedure tcomponentqueue.setitems(const index: integer; + const Value: tmsecomponent); +begin + inherited setitems(index,ievent(value)); +end; + +function tcomponentqueue.findobject(const aobject: tmsecomponent): integer; +begin + result:= indexof(pointer(ievent(aobject))); +end; + +{ tobjectlinkrecordlist } + +constructor tobjectlinkrecordlist.create(arecordsize: integer; aoptions: recordliststatesty = []); +begin + inherited create(arecordsize,aoptions+[rels_needsfinalize]); + fobjectlinker:= tobjectlinker.create(iobjectlink(self),nil); +end; + +destructor tobjectlinkrecordlist.destroy; +begin + inherited; + fobjectlinker.free; +end; + +procedure tobjectlinkrecordlist.finalizerecord(var item); +begin + dounlink(item) +end; + +function tobjectlinkrecordlist.getinstance: tobject; +begin + result:= self; +end; + +procedure tobjectlinkrecordlist.link(const source, dest: iobjectlink; valuepo, + ainterfacetype: pointer; once: boolean); +begin + fobjectlinker.link(source,dest,valuepo,ainterfacetype,once); +end; + +procedure tobjectlinkrecordlist.objevent(const sender: iobjectlink; + const event: objecteventty); +begin + fobjectlinker.objevent(sender,event); + if event = oe_destroyed then begin + itemdestroyed(sender); + end; +end; + +procedure tobjectlinkrecordlist.unlink(const source, dest: iobjectlink; + valuepo: pointer); +begin + fobjectlinker.unlink(source,dest,valuepo); +end; + +{ tvirtualpersistent } + +constructor tvirtualpersistent.create; +begin + inherited; + internalcreate; +end; + +procedure tvirtualpersistent.internalcreate; +begin + //dummy +end; + +{ townedeventpersistent } + +constructor townedeventpersistent.create(aowner: tobject); +begin + fowner:= aowner; + inherited create; +end; + +{ teventpersistent } + +procedure teventpersistent.receiveevent(const event: tobjectevent); +begin + //dummy +end; + +{ tpersistenttemplate } + +constructor tpersistenttemplate.create(const owner: tmsecomponent; + const onchange: notifyeventty); +begin + fowner:= owner; + fonchange:= onchange; +end; + +procedure tpersistenttemplate.changed; +begin + if assigned(fonchange) and not (csloading in fowner.componentstate) then begin + fonchange(self); + end; +end; + +procedure tpersistenttemplate.copyinfo(const source: tpersistenttemplate); +begin + //dummy +end; + +procedure tpersistenttemplate.assignto(dest: tpersistent); +begin + doassignto(dest); +end; + +procedure tpersistenttemplate.assign(source: tpersistent); +begin + if source is classtype then begin + move(tpersistenttemplate(source).getinfoad^,getinfoad^,getinfosize); + copyinfo(tpersistenttemplate(source)); + changed; + end + else begin + inherited; + end; +end; + +{ ttemplatecontainer } + +constructor ttemplatecontainer.create(aowner: tcomponent); +begin + ftemplate:= gettemplateclass.create(self,{$ifdef FPC}@{$endif}templatechanged); + inherited; +end; + +destructor ttemplatecontainer.destroy; +begin + inherited; + ftemplate.free; +end; + +procedure ttemplatecontainer.assignto(dest: tpersistent); +begin + tpersistent1(ftemplate).assignto(dest); +end; + +procedure ttemplatecontainer.templatechanged(const sender: tobject); +begin + sendchangeevent; +end; + +function findmodulebyname(const name: string): tcomponent; +begin + result:= modules.findmodulebyname(name); +end; + +function findcomponentbynamepath(const namepath: string): tcomponent; +var + ar1: stringarty; + int1: integer; +begin + result:= nil; + ar1:= splitstring(namepath,'.'); + if high(ar1) >= 0 then begin + result:= modules.findmodulebyname(ar1[0]); + for int1:= 1 to high(ar1) do begin + if result = nil then begin + break; + end; + result:= result.FindComponent(ar1[int1]); + end; + end; +end; + +function findcomponentbynamepath(const namepath: string; + const root: tcomponent): tcomponent; + //name path does not contain root +var + po1,po2: pchar; +// comp1: tcomponent; +begin + result:= nil; + if (root <> nil) and (namepath <> '') then begin + po1:= pchar(namepath); + po2:= po1; + while (po2^ <> '.') and (po2^ <> #0) do begin + inc(po2); + end; + if stringicomp(root.name,psubstr(po1,po2)) = 0 then begin + result:= root; + while po2^ <> #0 do begin + inc(po2); + po1:= po2; + while (po2^ <> '.') and (po2^ <> #0) do begin + inc(po2); + end; + result:= result.findcomponent(psubstr(po1,po2)); + if result = nil then begin + break; + end; + end; + end; + end; +end; + +function findsubcomponentbynamepath(const namepath: string; + const root: tcomponent): tcomponent; +var + po1,po2: pchar; + comp1: tcomponent; +begin + result:= nil; + if (root <> nil) and (namepath <> '') then begin + comp1:= root; + po1:= pchar(namepath); + po2:= po1; + while true do begin + po1:= po2; + while (po2^ <> '.') and (po2^ <> #0) do begin + inc(po2); + end; + result:= comp1.findcomponent(psubstr(po1,po2)); + if result = nil then begin + break; + end; + if po2^ = #0 then begin + break; + end; + inc(po2); + comp1:= result; + end; + end; +end; + +Type + TPosComponent = Class(TObject) + FPos : Integer; + FComponent : TComponent; + Constructor Create(APos : Integer; AComponent : TComponent); + end; + +Constructor TPosComponent.Create(APos : Integer; AComponent : TComponent); + +begin + FPos:=APos; + FComponent:=AComponent; +end; + +{ twritermse } + +constructor twritermse.create(const stream: tstream; const bufsize: integer; + const anoancestor: boolean = false; + const amasterancestor: boolean = false); +begin +// fgetchildrenbefore:= onstreaminggetchildren; +// onstreaminggetchildren:= @dogetchildren; + fnoancestor:= anoancestor; + fmasterancestor:= amasterancestor; + inherited create(stream,bufsize); +end; + +destructor twritermse.destroy; +begin + inherited; +// onstreaminggetchildren:= fgetchildrenbefore; +end; + +function twritermse.rootcompname(const acomp: tcomponent; + const aroot: tcomponent): string; +var + comp1: tcomponent; +begin + result:= acomp.name; + comp1:= acomp.owner; + while (comp1 <> aroot) and (comp1 <> nil) do begin + result:= comp1.name+'.'+result; + comp1:= comp1.owner; + end; +end; + +function twritermse.rootcompname(const acomp: tcomponent; + arootlevel: integer): string; +var + comp1: tcomponent; +begin + result:= acomp.name; + comp1:= acomp.owner; + while (arootlevel > 0) and (comp1 <> nil) do begin + result:= comp1.name+'.'+result; + comp1:= comp1.owner; + dec(arootlevel); + end; +end; + +// Used as argument for calls to TComponent.GetChildren: +procedure TWritermse.AddToAncestorList(Component: TComponent); +begin + FAncestors.AddObject(rootcompname(Component,fancestorlookuplevel), + TPosComponent.Create(FAncestors.Count,Component)); +end; + + +procedure TWritermse.DetermineAncestor(Component : TComponent); + +Var + I : Integer; + comp1: tcomponent; + int1: integer; +begin + // Should be set only when we write an inherited with children. + if Not Assigned(FAncestors) then begin + exit; + end; + comp1:= froot; + for int1:= fancestorlookuplevel-1 downto 0 do begin + comp1:= comp1.owner; + end; + if comp1 = nil then begin + comp1:= flookuproot; //should not happen + end; + I:=FAncestors.IndexOf(rootcompname(Component,comp1)); + If (I=-1) then + begin + FAncestor:=Nil; + FAncestorPos:=-1; + end + else begin + With TPosComponent(FAncestors.Objects[i]) do begin + FAncestor:=FComponent; + FAncestorPos:=FPos; + end; + end; +end; + +procedure TWritermse.DoFindAncestor(Component : TComponent); + +Var + C : TComponent; + +begin + if Assigned(FOnFindAncestor) then + if (Ancestor=Nil) or (Ancestor is TComponent) then + begin + C:=TComponent(Ancestor); + FOnFindAncestor(Self,Component,Component.Name,C,FRootAncestor); + Ancestor:=C; + end; + if frootrootancestor = nil then begin + frootrootancestor:= tcomponent(fancestor); + end; +end; + +procedure TWritermse.WriteComponent(Component: TComponent); + +var + SA : TPersistent; + SR, SRA : TComponent; +begin + SR:=FRoot; + SA:=FAncestor; + SRA:=FRootAncestor; + inc(fchildlevel); + Try +{$warnings off} + tcomponent1(Component).FComponentState:= + tcomponent1(Component).FComponentState+[csWriting]; +{$warnings on} + Try + if not fnoancestor or (csinline in component.componentstate) or + (fchildlevel > 1) then begin + // Possibly set ancestor. + DetermineAncestor(Component); + DoFindAncestor(Component); + // Mainly for IDE when a parent form had an ancestor renamed... + end; + tcomponent1(Component).WriteState(Self); + // Will call WriteComponentData. + {$ifdef FPC} + FDriver.EndList; + {$else} + writelistend; + {$endif} + Finally +{$warnings off} + tcomponent1(Component).FComponentState:= + tcomponent1(Component).FComponentState-[csWriting]; +{$warnings on} + end; + Finally + dec(fchildlevel); + FAncestor:=SA; + FRoot:=SR; + FRootAncestor:=SRA; + end; +end; + +procedure TWritermse.WriteChildren(Component : TComponent); + +Var + SRoot, SRootA : TComponent; + SList : TStringList; + SPos : Integer; + I : Integer; + ancestorlookuplevelbefore: integer; + rootrootancestorbefore: tcomponent; + +begin + // Write children list. + // While writing children, the ancestor environment must be saved + // This is recursive... + SRoot:=FRoot; + SRootA:=FRootAncestor; + SList:=FAncestors; + SPos:=FCurrentPos; + ancestorlookuplevelbefore:= fancestorlookuplevel; + rootrootancestorbefore:= frootrootancestor; + try + FAncestors:=Nil; + FCurrentPos:=0; + FAncestorPos:=-1; + if csInline in Component.ComponentState then + FRoot:=Component; + if (FAncestor is TComponent) then + begin + FAncestors:=TStringList.Create; + if csInline in TComponent(FAncestor).ComponentState then begin + FRootAncestor := TComponent(FAncestor); + if frootrootancestor <> frootancestor then begin + inc(fancestorlookuplevel); + end; + end; +// TComponent1(FAncestor).GetChildren(@AddToAncestorList,frootancestor); + GetChildren1(tcomponent(FAncestor),{$ifdef FPC}@{$endif}AddToAncestorList,frootancestor); + FAncestors.Sorted:=True; + end; + try +// tcomponent1(Component).GetChildren(@WriteComponent, FRoot); + GetChildren1(component,{$ifdef FPC}@{$endif}WriteComponent, FRoot); + Finally + If Assigned(Fancestors) then + For I:=0 to FAncestors.Count-1 do + FAncestors.Objects[i].Free; + FreeAndNil(FAncestors); + end; + finally + FAncestors:=Slist; + FRoot:=SRoot; + FRootAncestor:=SRootA; + FCurrentPos:=SPos; + FAncestorPos:=Spos; + fancestorlookuplevel:= ancestorlookuplevelbefore; + frootrootancestor:= rootrootancestorbefore; + end; +end; + +procedure TWritermse.WriteComponentData(Instance: TComponent); +var + Flags: TFilerFlags; +begin + Flags := []; + If (Assigned(FAncestor)) and //has ancestor + (not (csInline in Instance.ComponentState) or // no inline component + // .. or the inline component is inherited + (csAncestor in Instance.Componentstate) and (FAncestors <> nil)) then + Flags:=[ffInherited] + else If csInline in Instance.ComponentState then + Flags:=[ffInline]; + If (FAncestors<>Nil) and ((FCurrentPos<>FAncestorPos) or (FAncestor=Nil)) then + Include(Flags,ffChildPos); + FDriver.BeginComponent(Instance,Flags,FCurrentPos); + If (FAncestors<>Nil) then + Inc(FCurrentPos); + WriteProperties(Instance); + WriteListEnd; + // Needs special handling of ancestor. + If not IgnoreChildren then begin + WriteChildren(Instance); + end; +end; +{ +procedure twritermse.dogetchildren(const sender: tmsecomponent; + const proc: tgetchildproc; const aroot: tcomponent); +var + root1: tcomponent; + comp1,comp2: tcomponent; + int1: integer; +begin + comp1:= aroot; + if aroot = rootancestor then begin + comp2:= frootrootancestor; + int1:= fancestorlookuplevel; + try + while (comp1 <> nil) and (fancestorlookuplevel >= 0) do begin + tmsecomponent(sender).getchildren1(proc,comp1); + comp1:= comp1.owner; + dec(fancestorlookuplevel); + end; + finally + fancestorlookuplevel:= int1; + end; + end + else begin + comp2:= frootroot; + while comp1 <> nil do begin + tmsecomponent(sender).getchildren1(proc,comp1); + if comp1 = comp2 then begin + break; + end; + comp1:= comp1.owner; + end; + end; +end; +} +procedure twritermse.getchildren1(const acomp: tcomponent; + const proc: tgetchildproc; const aroot: tcomponent); + //support for added components to submodules +var +// root1: tcomponent; + comp1,comp2: tcomponent; + int1: integer; +begin + comp1:= aroot; + if aroot = rootancestor then begin + comp2:= frootrootancestor; + int1:= fancestorlookuplevel; + try + while (comp1 <> nil) and (fancestorlookuplevel >= 0) do begin + tcomponent1(acomp).getchildren(proc,comp1); + comp1:= comp1.owner; + dec(fancestorlookuplevel); + end; + finally + fancestorlookuplevel:= int1; + end; + end + else begin + comp2:= frootroot; + while comp1 <> nil do begin + tcomponent1(acomp).getchildren(proc,comp1); + if comp1 = comp2 then begin + break; + end; + comp1:= comp1.owner; + end; + end; +end; + +procedure twritermse.writedescendent(const aroot: tcomponent; + const aancestor: tcomponent); +begin + frootrootancestor:= aancestor; + frootroot:= aroot; + FRoot := ARoot; + FAncestor := AAncestor; + FRootAncestor := AAncestor; + FLookupRoot := ARoot; + + WriteComponent(ARoot); +// inherited writedescendent(aroot,aancestor); +end; + +procedure twritermse.writerootcomponent(aroot: tcomponent); +begin + writedescendent(aroot,nil); +end; + +function twritermse.getclassname(const aobj: tobject): shortstring; +begin + if aobj is tmsecomponent then begin + result:= tmsecomponent(aobj).actualclassname; + end + else begin + result:= inherited getclassname(aobj); + end; +end; + +initialization + loadmoduletracker:= tloadmoduletracker.create; +{$ifdef FPC} + registerinitcomponenthandler(tmsecomponent,@initmsecomponent1); +{$endif} + registerfindglobalcomponentproc({$ifdef FPC}@{$endif}findmodulebyname); +finalization + freeandnil(fmodules); + freeandnil(floadedlist); +{$ifdef FPC} +// unregisterinitcomponenthandler(tcomponent,@initmsecomponent); +{$endif} + unregisterfindglobalcomponentproc({$ifdef FPC}@{$endif}findmodulebyname); + loadmoduletracker.free; + freeandnil(objectdatalist); +end. diff --git a/mseide-msegui/lib/common/kernel/mseconsts.pas b/mseide-msegui/lib/common/kernel/mseconsts.pas new file mode 100644 index 0000000..3a0e104 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseconsts.pas @@ -0,0 +1,492 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseconsts; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface + +uses + msestockobjects,mseglob,msestrings,mseapplication,msetypes; + +type + stockcaptionaty = array[stockcaptionty] of msestring; + pstockcaptionaty = ^stockcaptionaty; + defaultmodalresulttextty = array[modalresultty] of msestring; + pdefaultmodalresulttextty = ^defaultmodalresulttextty; + defaultgeneratortextty = array[textgeneratorty] of textgeneratorfuncty; + pdefaultgeneratortextty = ^defaultgeneratortextty; + + langty = (la_none,la_en,la_de,la_ru,la_es,la_uzcyr,la_id,la_zh, + la_fr); + +const + langnames: array[langty] of string = ( + '','en','de','ru','es','uz_cyr','id','zh', + 'fr'); + + function modalresulttext(const index: modalresultty): msestring; + function modalresulttextnoshortcut(const index: modalresultty): msestring; + function stockcaptions(const index: stockcaptionty): msestring; + function stocktextgenerators(const index: textgeneratorty): textgeneratorfuncty; + function uc(const index: integer): msestring; //get user caption + + procedure registeruserlangconsts(name: string; + const caption: array of msestring); + procedure registerlangconsts(const name: string; + const stockcaptionpo: pstockcaptionaty; + const modalresulttextpo: pdefaultmodalresulttextty; + const modalresulttextnoshortcutpo: pdefaultmodalresulttextty; + const textgeneratorpo: pdefaultgeneratortextty); + function setlangconsts(const name: string): boolean; + //true if ok, no change otherwise + function getcurrentlangconstsname: string; + procedure setuserlangconsts(const name: string); + //called by setlangconsts automatically +type + langchangeprocty = procedure(const langname: ansistring); + + procedure registerlangchangeproc(const aproc: langchangeprocty); + procedure unregisterlangchangeproc(const aproc: langchangeprocty); + +implementation +uses + sysutils,msesysintf,msearrayutils,mseformatstr; + +type + langinfoty = record + name: string; + stockcaption: pstockcaptionaty; + modalresulttext: pdefaultmodalresulttextty; + modalresulttextnoshortcut: pdefaultmodalresulttextty; + textgenerator: pdefaultgeneratortextty; + end; + userlanginfoty = record + name: string; + caption: msestringarty; + end; + +var + langs: array of langinfoty; + lang: langinfoty; + langbefore: ansistring; + userlangs: array of userlanginfoty; + userlang: userlanginfoty; + langchangeprocs: array of langchangeprocty; + +const + en_modalresulttext: defaultmodalresulttextty = + ('', //mr_none + '', //mr_canclose + '', //mr_windowclosed + '', //mr_windowdestroyed + '', //mr_escape + '', //mr_f10 + '', //mr_exception + '&Cancel', //mr_cancel + '&Abort', //mr_abort + '&OK', //mr_ok + '&Yes', //mr_yes + '&No', //mr_no + '&All', //mr_all + 'Yes &all', //mr_yesall + 'N&o all', //mr_noall + '&Ignore', //mr_ignore + '&Skip', //mr_skip + 'Skip a&ll', //mr_skipall + 'Co&ntinue' //mr_continue + ); + + en_modalresulttextnoshortcut: defaultmodalresulttextty = + ('', //mr_none + '', //mr_canclose + '', //mr_windowclosed + '', //mr_windowdestroyed + '', //mr_esc + '', //mr_f10 + '', //mr_exception + 'Cancel', //mr_cancel + 'Abort', //mr_abort + 'OK', //mr_ok + 'Yes', //mr_yes + 'No', //mr_no + 'All', //mr_all + 'Yes all', //mr_yesall + 'No all', //mr_noall + 'Ignore', //mr_ignore + 'Skip', //mr_skip + 'Skip all', //mr_skipall + 'Continue' //mr_continue + ); + + en_stockcaption: stockcaptionaty = ( + '', //sc_none + 'is invalid', //sc_is_invalid + 'Format error', //sc_Format_error + 'Value is required', //sc_Value_is_required + 'Error', //sc_Error + 'Min', //sc_Min + 'Max', //sc_Max + 'Range error', //sc_Range_error + + '&Undo', //sc_Undohk /// /// + '&Redo', //sc_Redohk // // + '&Copy', //sc_Copyhk // hotkeys // + 'Cu&t', //sc_Cuthk // // + '&Paste', //sc_Pastehk // // hotkeys + 'Select &all', //sc_Select_allhk /// // + '&Insert Row', //sc_insert_rowhk /// // + '&Append Row', //sc_append_rowhk // hotkeys // + '&Delete Row', //sc_delete_rowhk /// /// + + '&Dir', //sc_Dirhk /// + '&Home', //sc_homehk // + '&Up', //sc_Uphk // + '&New dir', //sc_New_dirhk // hotkeys + '&Name', //sc_Namehk // + '&Show hidden files', //sc_Show_hidden_fileshk // + '&Filter', //sc_Filterhk /// + 'Save', //sc_save + 'Open', //sc_open + 'Name', //sc_name + 'Create new directory',//sc_create_new_directory + 'Back', //sc_back + 'Forward', //sc_forward + 'Up', //sc_up + 'File', //sc_file + 'exists, do you want to overwrite?', //sc_exists_overwrite + 'is modified. Save?', //sc_is_modified_save + 'WARNING', //sc_warningupper + 'ERROR', //sc_errorupper + 'Exception', //sc_exception + 'System', //sc_system + 'does not exist', //sc_does_not_exist + 'PASSWORD', //sc_passwordupper + 'Enter password', //sc_enterpassword + 'Invalid password!', //sc_invalidpassword + 'Can not read directory', //sc_can_not_read_directory + 'Graphic format not supported', //sc_graphic_not_supported + 'Graphic format error', //sc_graphic_format_error + 'MS Bitmap', //sc_MS_Bitmap + 'MS Icon', //sc_MS_Icon + 'JPEG Image', //sc_JPEG_Image + 'PNG Image', //sc_PNG_Image + 'XPM Image', //sc_XPM_Image + 'PNM Image', //sc_PNM_Image + 'TARGA Image', //sc_TARGA_image + 'TIFF Image', //sc_TIFF_image + 'All', //sc_All + 'Confirmation', //sc_Confirmation + 'Delete record?', //sc_Delete_record_question + 'Copy record?', //sc_Copy_record_question + 'Close page', //sc_close_page + 'First', //sc_first + 'Prior', //sc_prior + 'Next', //sc_next + 'Last', //sc_last + 'Append', //sc_append + 'Delete', //sc_delete + 'Edit', //sc_edit + 'Post', //sc_post + 'Cancel', //sc_cancel + 'Refresh', //sc_refresh + 'Edit filter', //sc_filter_filter + 'Edit filter minimum',//sc_edit_filter_min + 'Edit filter maximum',//sc_filter_edit_max + 'Reset filter', //sc_reset_filter + 'Filter on', //sc_filter_on + 'Search', //sc_search + 'Auto edit', //sc_auto_edit + 'Copy record', //sc_copy_record + 'Dialog', //sc_dialog + 'Insert', //sc_insert + 'Copy', //sc_copy + 'Paste', //sc_paste + 'Row insert', //sc_row_insert + 'Row append', //sc_row_append + 'Row delete', //sc_row_delete + 'Undo', //sc_undo + 'Redo', //sc_redo + 'Cut', //sc_cut + 'Select all', //sc_select_all + + 'Filter off', //sc_filter_off + 'Portrait', //sc_portrait print orientation + 'Landscape', //sc_landscape print orientation + 'Delete row?', //sc_Delete_row_question + 'selected rows?', //sc_selected_rows + 'Single item only', //sc_Single_item_only + 'Copy Cells', //sc_Copy_Cells + 'Paste Cells', //sc_Paste_Cells + 'Close', //sc_close + 'Maximize', //sc_maximize + 'Normalize', //sc_normalize + 'Minimize', //sc_minimize + 'Fix size', //sc_fix_size + 'Float', //sc_float + 'Stay on top', //sc_stay_on_top + 'Stay in background', //sc_stay_in_background + 'Lock children', //sc_lock_children + 'No lock', //sc_no_lock + 'Input', //sc_input + 'Button', //sc_button + 'On', //sc_on + 'Off', //sc_off + 'Left border', //sc_leftborder + 'Top border', //sc_topborder + 'Right border', //sc_rightborder + 'Bottom border', //sc_bottomborder + 'Begin of text', //sc_beginoftext + 'End of text', //sc_endoftext + 'Inputmode', //sc_inputmode + 'Overwrite', //sc_overwrite + 'Deleted', //sc_deleted + 'Copied', //sc_copied + 'Inserted', //sc_inserted + 'Pasted', //sc_pasted + 'Withdrawn', //sc_withdrawn + 'Window activated', //sc_windowactivated + 'Menu', //sc_menu + 'Beginning of file', //sc_bof + 'End of file', //sc_eof + 'Voice output', //sc_voiceoutput + 'Speak again', //sc_speakagain + 'First column', //sc_firstcol + 'First row', //sc_firstrow + 'Last column', //sc_lastcol + 'Last row', //sc_lastrow + 'Selection', //sc_selection + 'Speak path', //sc_speakpath + 'Disabled button', //sc_disabledbutton + 'First field', //sc_firstfield + 'Last field', //sc_lastfield + 'First element', //sc_firstelement + 'Last element', //sc_lastelement + 'Slower', //sc_slower + 'Faster', //sc_faster + 'Window', //sc_window + 'Area', //sc_area + 'Area activated', //sc_areaactivated + 'Volume down', //sc_volumedown + 'Volume up', //sc_volumeup + 'Cancel speech' //sc_cancelspeech +); + +function delete_n_selected_rows(const params: array of const): msestring; +begin + with params[0] do begin + if vinteger = 1 then begin + result:= 'Delete selected row?' + end + else begin + result:= 'Delete '+inttostrmse(vinteger)+' selected rows?'; + end; + end; +end; + +const + en_textgenerator: defaultgeneratortextty = ( + {$ifdef FPC}@{$endif}delete_n_selected_rows //tg_delete_n_selected_rows + ); + +procedure setitem(var item: langinfoty; + const name: string; + const stockcaptionpo: pstockcaptionaty; + const modalresulttextpo: pdefaultmodalresulttextty; + const modalresulttextnoshortcutpo: pdefaultmodalresulttextty; + const textgeneratorpo: pdefaultgeneratortextty); +begin + item.name:= name; + item.stockcaption:= stockcaptionpo; + item.modalresulttext:= modalresulttextpo; + item.modalresulttextnoshortcut:= modalresulttextnoshortcutpo; + item.textgenerator:= textgeneratorpo; +end; + +procedure registerlangconsts(const name: string; + const stockcaptionpo: pstockcaptionaty; + const modalresulttextpo: pdefaultmodalresulttextty; + const modalresulttextnoshortcutpo: pdefaultmodalresulttextty; + const textgeneratorpo: pdefaultgeneratortextty); + + +var + int1: integer; +begin + for int1:= 0 to high(langs) do begin + if langs[int1].name = name then begin + setitem(langs[int1],name,stockcaptionpo,modalresulttextpo, + modalresulttextnoshortcutpo,textgeneratorpo); + exit; + end; + end; + setlength(langs,high(langs)+2); + setitem(langs[high(langs)],name,stockcaptionpo,modalresulttextpo, + modalresulttextnoshortcutpo,textgeneratorpo); +end; + +procedure registeruserlangconsts(name: string; + const caption: array of msestring); + procedure setitem(var item: userlanginfoty); + var + int1: integer; + begin + item.name:= name; + setlength(item.caption,length(caption)); + for int1:= 0 to high(caption) do begin + item.caption[int1]:= caption[int1]; + end; + end; + +var + int1: integer; +begin + name:= lowercase(name); + for int1:= 0 to high(userlangs) do begin + if userlangs[int1].name = name then begin + setitem(userlangs[int1]); + exit; + end; + end; + setlength(userlangs,high(userlangs)+2); + setitem(userlangs[high(userlangs)]); +end; + +procedure setuserlangconsts(const name: string); +var + int1: integer; +begin + if name = '' then begin + if high(userlangs) >= 0 then begin + userlang:= userlangs[0]; + end; + end + else begin + if name <> userlang.name then begin + for int1:= 0 to high(userlangs) do begin + if userlangs[int1].name = name then begin + userlang:= userlangs[int1]; + break; + end; + end; + end; + end; +end; + +function getcurrentlangconstsname: string; +begin + result:= lang.name; +end; + +function setlangconsts(const name: string): boolean; +var + int1: integer; + bo1: boolean; + str1: string; +begin + if name = '' then begin + str1:= lowercase(sys_getlangname); + if str1 = '' then begin + str1:= langnames[la_en]; + end; + end + else begin + str1:= lowercase(name); + end; + setuserlangconsts(str1); + result:= false; + bo1:= lang.name = ''; + if lang.name <> str1 then begin + for int1:= 0 to high(langs) do begin + if langs[int1].name = str1 then begin + lang:= langs[int1]; + result:= true; + break; + end; + end; + if bo1 then begin + if lang.name = '' then begin + setitem(lang,langnames[la_en],@en_stockcaption,@en_modalresulttext, + @en_modalresulttextnoshortcut,@en_textgenerator); +{ + with lang do begin + name:= langnames[la_en]; + stockcaption:= @en_stockcaption; + modalresulttext:= @en_modalresulttext; + modalresulttextnoshortcut:= @en_modalresulttextnoshortcut; + textgenerator:= @en_textgenerator; + end; +} + end; + end; + end; + if lowercase(str1) <> langbefore then begin + for int1:= 0 to high(langchangeprocs) do begin + langchangeprocs[int1](str1); + end; + application.langchanged; + end; +end; + +procedure checklang; +begin + if lang.name = '' then begin + setlangconsts(''); + end; +end; + +function uc(const index: integer): msestring; +begin + if userlang.name = '' then begin + setuserlangconsts(''); + end; + if (index < 0) or (index > high(userlang.caption)) then begin + raise exception.create('Invalid user caption index: '+inttostr(index)+'.'); + end; + result:= userlang.caption[index]; +end; + +function modalresulttext(const index: modalresultty): msestring; +begin + checklang; + result:= lang.modalresulttext^[index]; +end; + +function modalresulttextnoshortcut(const index: modalresultty): msestring; +begin + checklang; + result:= lang.modalresulttextnoshortcut^[index]; +end; + +function stocktextgenerators(const index: textgeneratorty): textgeneratorfuncty; +begin + checklang; + result:= lang.textgenerator^[index]; +end; + +function stockcaptions(const index: stockcaptionty): msestring; +begin + checklang; + result:= lang.stockcaption^[index]; +end; + +procedure registerlangchangeproc(const aproc: langchangeprocty); +begin + additem(pointerarty(langchangeprocs),{$ifndef FPC}@{$endif}aproc); +end; + +procedure unregisterlangchangeproc(const aproc: langchangeprocty); +begin + removeitem(pointerarty(langchangeprocs),{$ifndef FPC}@{$endif}aproc); +end; + +initialization + registerlangconsts(langnames[la_en],@en_stockcaption,@en_modalresulttext, + @en_modalresulttextnoshortcut,@en_textgenerator); + langbefore:= langnames[la_en]; +end. diff --git a/mseide-msegui/lib/common/kernel/mseconsts_de.pas b/mseide-msegui/lib/common/kernel/mseconsts_de.pas new file mode 100644 index 0000000..ac2243b --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseconsts_de.pas @@ -0,0 +1,236 @@ +{ MSEgui Copyright (c) 1999-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseconsts_de; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseconsts; + +implementation +uses + msetypes{msestrings},sysutils,mseformatstr; +const + de_modalresulttext: defaultmodalresulttextty = + ('', //mr_none + '', //mr_canclose + '', //mr_windowclosed + '', //mr_windowdestroyed + '', //mr_escape + '', //mr_f10 + '', //mr_exception + '&Abbrechen', //mr_cancel + '&Abbrechen', //mr_abort + '&OK', //mr_ok + '&Ja', //mr_yes + '&Nein', //mr_no + 'A&lle', //mr_all + 'Ja a&lle', //mr_yesall + 'N&ein alle', //mr_noall + '&Ignorieren', //mr_ignore + #0220'bers&pringen', //mr_skip + 'Alles '#0252'&berspringen', //mr_skipall + '&Fortfahren' //mr_continue + ); + + de_modalresulttextnoshortcut: defaultmodalresulttextty = + ('', //mr_none + '', //mr_canclose + '', //mr_windowclosed + '', //mr_windowdestroyed + '', //mr_escape + '', //mr_f10 + '', //mr_exception + 'Abbrechen', //mr_cancel + 'Abbrechen', //mr_abort + 'OK', //mr_ok + 'Ja', //mr_yes + 'Nein', //mr_no + 'Alle', //mr_all + 'Ja alle', //mr_yesall + 'Nein alle', //mr_noall + 'Ignorieren', //mr_ignore + #0220'berspringen', //mr_skip + 'Alles '#0252'berspringen', //mr_skipall + 'Fortfahren' //mr_continue + ); + + de_stockcaption: stockcaptionaty = ( + '', //sc_none + 'ist ung'#0252'ltig', //sc_is_invalid + 'Format Fehler', //sc_Format_error + 'Wert wird ben'#0246'tigt', //sc_Value_is_required + 'Fehler', //sc_Error + 'Min', //sc_Min + 'Max', //sc_Max + 'Bereichs Fehler', //sc_Range_error + + '&R'#0252'ckg'#0228'ngig', //sc_Undohk /// /// + '&Redo', //sc_Redohk // // + '&Kopieren', //sc_Copyhk // hotkeys // + '&Ausschneiden', //sc_Cuthk // // + '&Einf'#0252'gen', //sc_Pastehk // // hotkeys + 'Alles &markieren', //sc_Select_allhk /// // + 'Zeile e&inf'#0252'gen', //sc_insert_rowhk /// // + 'Zeile a&nf'#0252'gen', //sc_append_rowhk // hotkeys // + 'Zeile &l'#0246'schen', //sc_delete_rowhk /// /// + + '&Dir', //sc_Dirhk /// + '&Home', //sc_homehk // + '&Auf', //sc_Uphk // + 'Dir &neu', //sc_New_dirhk // hotkeys + 'N&ame', //sc_Namehk // + '&Verst.Dat.anzeigen', //sc_Show_hidden_fileshk // + '&Filter', //sc_Filterhk /// + 'Speichern', //sc_save + #0214'ffnen', //sc_open + 'Name', //sc_name + 'Verzeichnis erstellen',//sc_create_new_directory + 'Zurück', //sc_back + 'Forw'#0228'rts', //sc_forward + 'Aufw'#0228'rts', //sc_up + 'Datei', //sc_file + 'existiert, wollen Sie '#0252'berschreiben?', //sc_exists_overwrite + 'wurde geändert, wollen Sie speichern?', //sc_is_modified_save + 'WARNUNG', //sc_warningupper + 'FEHLER', //sc_errorupper + 'Exception', //sc_exception + 'System', //sc_system + 'existiert nicht', //sc_does_not_exist + 'PASSWORT', //sc_passwordupper + 'Ppassworteingabe', //sc_enterpassword + 'Ung'#0252'ltiges Passwort!',//sc_invalidpassword + 'Verzeichnis kann nicht gelesen werden', //sc_can_not_read_directory + 'Grafik Format nicht unterst'#0252'tzt', //sc_graphic_not_supported + 'Grafik Format Fehler', //sc_graphic_format_error + 'MS Bitmap', //sc_MS_Icon + 'MS Icon', //sc_MS_Icon + 'JPEG Bild', //sc_JPEG_Image + 'PNG Bild', //sc_PNG_Image + 'XPM Bild', //sc_XPM_Image + 'PNM Bild', //sc_PNM_Image + 'TARGA Bild', //sc_TARGA_image + 'TIFF Bild', //sc_TIFF_image + 'Alle', //sc_All + 'Best'#0228'tigung', //sc_Confirmation + 'Datensatz l'#0246'schen?', //sc_Delete_record_question + 'Datensatz kopieren?', //sc_Copy_record_question + 'Seite schliessen', //sc_close_page + 'Erster', //sc_first + 'Vorheriger', //sc_prior + 'N'#0228'chster', //sc_next + 'Letzter', //sc_last + 'Anf'#0252'gen', //sc_append + 'L'#0246'schen', //sc_delete + 'Bearbeiten', //sc_edit + 'Eintragen', //sc_post + 'Verwerfen', //sc_cancel + 'Auffrischen', //sc_refresh + 'Filter bearbeiten', //sc_filter_filter + 'Filter Minimum bearbeiten',//sc_edit_filter_min + 'Filter Maximum bearbeiten',//sc_filter_edit_max + 'Filter r'#0252'ckstellen', //sc_reset_filter + 'Filter ein', //sc_filter_on + 'Suchen', //sc_search + 'Automatisch bearbeiten', //sc_auto_edit + 'Datensatz kopieren', //sc_copy_record + 'Dialog', //sc_dialog + 'Einf'#0252'gen', //sc_insert + 'Kopieren', //sc_copy + 'Einf'#0252'gen', //sc_paste + 'Zeile einf'#0252'gen', //sc_row_insert + 'Zeile anf'#0252'gen', //sc_row_append + 'Zeile l'#0246'schen', //sc_row_delete + 'R'#0252'ckg'#0228'ngig', //sc_undo + 'Wiederherstellen', //sc_redo + 'Ausschneiden', //sc_cut + 'Alles markieren', //sc_select_all + 'Filter aus', //sc_filter_off + 'Hochformat', //sc_portrait print orientation + 'Querformat', //sc_landscape print orientation + 'Zeile l'#0246'schen?', //sc_Delete_row_question + 'gew'#0228'hlte Zeilen', //sc_selected_rows + 'Nur Einzeleintrag erlaubt', //sc_Single_item_only + 'Zellen kopieren', //sc_Copy_Cells + 'Zellen einf'#0252'gen', //sc_Paste_Cells + 'Schliessen', //sc_close + 'Maximieren', //sc_maximize + 'Normalisieren', //sc_normalize + 'Minimieren', //sc_minimize + 'Feste Gr'#0246'sse', //sc_fix_size + 'Lösen', //sc_float + 'Im Fordergrund', //sc_stay_on_top + 'Im Hintergrund', //sc_stay_in_background + 'Blockiere Unterfenster', //sc_lock_children + 'Kein Blockieren', //sc_no_lock + 'Eingabe', //sc_input + 'Schaltfeld', //sc_button + 'Ein', //sc_on + 'Aus', //sc_off + 'Linker Rand', //sc_leftborder + 'Oberer Rand', //sc_topborder + 'Rechter Rand', //sc_rightborder + 'Unterer Rand', //sc_bottomborder + 'Text start', //sc_beginoftext + 'Text ende', //sc_endoftext + 'Eingabe Modus', //sc_inputmode + #$00DC'berschreiben', //sc_overwrite + 'Gel'#$00F6'scht', //sc_deleted + 'Kopiert', //sc_copied + 'Eingef'#$00FC'gt', //sc_inserted + 'Eingef'#$00FC'gt', //sc_pasted + 'R'#$00FC'ckg'#$00E4'ngig', //sc_withdrawn + 'Fenster aktiviert', //sc_windowactivated + 'Men'#$00FC, //sc_menu + 'Datei Beginn', //sc_bof + 'Datei Ende', //sc_eof + 'Sprachausgabe', //sc_voiceoutput + 'Wiederhole Sprachausgabe', //sc_speakagain + 'Erste Spalte', //sc_firstcol + 'Erste Zeile', //sc_firstrow + 'Letzte Spalte', //sc_lastcol + 'Letzte Zeile', //sc_lastrow + 'Auswahl', //sc_selection + 'Spreche Pfad', //sc_speakpath + 'Deaktiviertes Schaltfeld', //sc_disabledbutton + 'Erstes Feld', //sc_firstfield + 'Letztes Feld', //sc_lastfield + 'Erstes Element', //sc_firstelement + 'Letztes Element', //sc_lastelement + 'Langsamer', //sc_slower + 'Schneller', //sc_faster + 'Fenster', //sc_window + 'Bereich', //sc_area + 'Bereich aktiviert', //sc_areaactivated + 'Leiser', //sc_volumedown + 'Lauter', //sc_volumeup + 'Ansage abbrechen' //sc_cancelspeech +); + +function delete_n_selected_rows(const params: array of const): msestring; +begin + with params[0] do begin + if vinteger = 1 then begin + result:= 'Gew'#0228'hlte Zeile l'#0246'schen?'; + end + else begin + result:= inttostrmse(vinteger)+ + widestring(' gew'#0228'hlte Zeilen l'#0246'schen?'); + end; + end; +end; + +const + de_textgenerator: defaultgeneratortextty = ( + {$ifdef FPC}@{$endif}delete_n_selected_rows //tg_delete_n_selected_rows + ); +initialization + registerlangconsts(langnames[la_de],@de_stockcaption,@de_modalresulttext, + @de_modalresulttextnoshortcut,@de_textgenerator); +end. diff --git a/mseide-msegui/lib/common/kernel/mseconsts_es.pas b/mseide-msegui/lib/common/kernel/mseconsts_es.pas new file mode 100644 index 0000000..7165ea1 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseconsts_es.pas @@ -0,0 +1,238 @@ +{ MSEgui Copyright (c) 1999-2006 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Spanish translation by Julio Jimenez Borreguero. + +} +unit mseconsts_es; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseconsts; + +implementation +uses + msetypes{msestrings},sysutils,mseformatstr; +const + es_modalresulttext: defaultmodalresulttextty = + ('', //mr_none + '', //mr_canclose + '', //mr_windowclosed + '', //mr_windowdestroyed + '', //mr_escape + '', //mr_f10 + '', //mr_exception + '&Cancelar', //mr_cancel + '&Abortar', //mr_abort + '&OK', //mr_ok + '&S'#0237, //mr_yes + '&No', //mr_no + '&Todo', //mr_all + '&S'#0237' &todo', //mr_yesall + 'N&o todo', //mr_noall + '&Ignorar', //mr_ignore + 'O&mitir', //mr_skip + 'Omitir &todo', //mr_skipall + 'Co&ntinuar' //mr_continue + ); + + es_modalresulttextnoshortcut: defaultmodalresulttextty = + ('', //mr_none + '', //mr_canclose + '', //mr_windowclosed + '', //mr_windowdestroyed + '', //mr_escape + '', //mr_f10 + '', //mr_exception + 'Cancelar', //mr_cancel + 'Abortar', //mr_abort + 'OK', //mr_ok + 'S'#0237, //mr_yes + 'No', //mr_no + 'Todo', //mr_all + 'S'#$00ED' todo', //mr_yesall + 'No todo', //mr_noall + 'Ignorar', //mr_ignore + 'Omitir', //mr_skip + 'Omitir todo', //mr_skipall + 'Continuar' //mr_continue + ); + + es_stockcaption: stockcaptionaty = ( + '', //sc_none + 'es inv'#0225'lido', //sc_is_invalid + 'Error de formato', //sc_Format_error + 'Debe introducir un valor', //sc_Value_is_required + 'Error', //sc_Error + 'M'#0237'n.', //sc_Min + 'M'#0225'x.', //sc_Max + 'Error de rango', //sc_Range_error + + '&Deshacer', //sc_Undohk /// /// + '&Rehacer', //sc_Redohk // // + '&Copiar', //sc_Copyhk // hotkeys // + 'C&ortar', //sc_Cuthk // // + '&Pegar', //sc_Pastehk // // hotkeys + '&Select all', //sc_Select_allhk /// // + '&Insertar fila', //sc_insert_rowhk /// // + '&A'#0241'adir fila', //sc_append_rowhk // hotkeys // + '&Borrar fila', //sc_delete_rowhk /// /// + + '&Carpetas', //sc_Dir /// + '&Principal', //sc_home // + '&Subir un nivel', //sc_Up // + 'Crear carpeta', //sc_New_dir // hotkeys + 'N&ombre', //sc_Name // + '&Mostrar archivos ocultos', //sc_Show_hidden_files // + '&Filtro', //sc_Filter /// + 'Guardar', //sc_save + 'Abrir', //sc_open + 'Nombre', //sc_name1 + 'Crear una carpeta nueva', //sc_create_new_directory + 'Atr'#0225's', //sc_back + 'Adelante', //sc_forward + 'Arriba', //sc_up + 'Archivo', //sc_file + 'existe, '#0191'quiere sobreescribirlo?', //sc_exists_overwrite + 'ha sido modificado. '#0191'Guardar?', //sc_is_modified_save + 'ADVERTENCIA', //sc_warningupper + 'ERROR', //sc_errorupper + 'Excepci'#0243'n', //sc_exception + 'Sistema', //sc_system + 'no existe', //sc_does_not_exist + 'CONTRASE'#0209'A', //sc_passwordupper + 'Introduzca contrase'#0241'a', //sc_enterpassword + #0161'contrase'#0241'a incorrecta!', //sc_invalidpassword + 'No puedo leer la carpeta', //sc_can_not_read_directory + 'Formato gr'#0225'fico no soportado', //sc_graphic_not_supported + 'Error de formato gr'#0225'fico', //sc_graphic_format_error + 'Bitmap MS', //sc_MS_Icon + 'Icono MS', //sc_MS_Icon + 'Imagen JPEG', //sc_JPEG_Image + 'Imagen PNG', //sc_PNG_Image + 'Imagen XPM', //sc_XPM_Image + 'Imagen PNM', //sc_PNM_Image + 'Imagen TARGA', //sc_TARGA_image + 'Imagen TIFF', //sc_TIFF_image + 'Todo', //sc_All + 'Confirme', //sc_Confirmation + #0191'Borrar el registro?', //sc_Delete_record_question + #0191'Copiar el registro?', //sc_Copy_record_question + 'Cerrar p'#0225'gina', //sc_close_page + 'Primero', //sc_first + 'Anterior', //sc_prior + 'Siguiente', //sc_next + #0218'ltimo', //sc_last + 'A'#0241'adir', //sc_append + 'Borrar', //sc_delete + 'Editar', //sc_edit + 'Guardar', //sc_post + 'Cancelar', //sc_cancel + 'Refrescar', //sc_refresh + 'Filtro edici'#0243'n', //sc_filter_filter + 'Filtro edici'#0243'n m'#0237'nimo', //sc_edit_filter_min + 'Filtro edici'#0243'n m'#0225'ximo', //sc_filter_edit_max + 'Reiniciar filtro', //sc_reset_filter + 'Filtro activo', //sc_filter_on + 'Buscar', //sc_search + 'Edici'#0243'n autom'#0225'tica', //sc_autoedit + 'Copiar registro', //sc_copy_record + 'Di'#0225'logo', //sc_dialog + 'Insertar', //sc_insert + 'Copiar', //sc_copy + 'Pegar', //sc_paste + 'Insertar fila', //sc_row_insert + 'A'#0241'adir fila', //sc_row_append + 'Borrar fila', //sc_row_delete + 'Deshacer', //sc_undo + 'Rehacer', //sc_redo + 'Cortar', //sc_cut + 'Seleccionar todo', //sc_select_all + 'Filtro apagado', //sc_filter_off + 'Vertical', //sc_portrait print orientation + 'Apaisado', //sc_landscape print orientation + #0191'Borrar fila?', //sc_Delete_row_question + 'filas seleccionadas?', //sc_selected_rows + 'un elemento solamente', //sc_Single_item_only + 'Copiar Celdas', //sc_Copy_Cells + 'Pegar Celdas', //sc_Paste_Cells + 'Cerrar', //sc_close + 'Maximizar', //sc_maximize + 'Restaurar', //sc_normalize + 'Minimizar', //sc_minimize + 'Ajustar tama'#0241'o', //sc_fix_size + 'Flotar', //sc_float + 'Permanecer en el primer plano', //sc_stay_on_top + 'Permanecer en el fondo', //sc_stay_in_background + 'Bloquear hijas', //sc_lock_children + 'Sin bloquear', //sc_no_lock + 'Entrada', //sc_input + 'Bot'#0243'n', //sc_button + 'Encendido', //sc_on + 'Apagado', //sc_off + 'Borde izquierdo', //sc_leftborder + 'Borde superior', //sc_topborder + 'Borde derecho', //sc_rightborder + 'Borde inferior', //sc_bottomborder + 'Principio del texto', //sc_beginoftext + 'Fin del texto', //sc_endoftext + 'Modo entrada', //sc_inputmode + 'Sobrescribir', //sc_overwrite + 'Borrado', //sc_deleted + 'Copiado', //sc_copied + 'Insertado', //sc_inserted + 'Pegado', //sc_pasted + 'Retirado', //sc_withdrawn + 'Ventana activada', //sc_windowactivated + 'Men'#0250, //sc_menu + 'Principio del archivo', //sc_bof + 'Fin del archivo', //sc_eof + 'Salida de voz', //sc_voiceoutput + 'Hablar de nuevo', //sc_speakagain + 'Primera columna', //sc_firstcol + 'Primera fila', //sc_firstrow + #0218'ltima columna', //sc_lastcol + #0218'ltima fila', //sc_lastrow + 'Selecci'#0243'n', //sc_selection + 'Ruta de hablar', //sc_speakpath + 'Deshabilitar bot'#0243'n', //sc_disabledbutton + 'Primer campo', //sc_firstfield + #$00DA'ltimo campo', //sc_lastfield + 'Primer elemento', //sc_firstelement + #$00DA'ltimo elemento', //sc_lastelement + 'M'#$00E1's lento', //sc_slower + 'M'#$00E1's r'#$00E1'pido', //sc_faster + 'Ventana', //sc_window + #$00C1'rea', //sc_area + #$00C1'rea activada', //sc_areaactivated + 'Bajar volumen', //sc_volumedown + 'Subir volumen', //sc_volumeup + 'Cancelar habla' //sc_cancelspeech +); + +function delete_n_selected_rows(const params: array of const): msestring; +begin + with params[0] do begin + if vinteger = 1 then begin + result:= #0191'Borrar la fila seleccionada?' + end + else begin + result:= #0191'Borrar '+inttostrmse(vinteger)+' filas seleccionadas?'; + end; + end; +end; + +const + es_textgenerator: defaultgeneratortextty = ( + {$ifdef FPC}@{$endif}delete_n_selected_rows //tg_delete_n_selected_rows + ); +initialization + registerlangconsts(langnames[la_es],@es_stockcaption,@es_modalresulttext, + @es_modalresulttextnoshortcut,@es_textgenerator); +end. diff --git a/mseide-msegui/lib/common/kernel/mseconsts_fr.pas b/mseide-msegui/lib/common/kernel/mseconsts_fr.pas new file mode 100644 index 0000000..169a67c --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseconsts_fr.pas @@ -0,0 +1,277 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + French translation by Fabrice Michel Bouillerot. + UTF-8 Accented french characters + + À A grave +  A circumflex + Ä A diaresis + Æ AE Aesh Ash + È E grave + Ë E diaresis + É E acute + Ê E circumflex + Ë E diaresis + Î I circumflex + Ï I diaresis + Ô O circumflex + Ö O diaresis + Ù U grave + Û U circumflex + Ü U diaresis + à a grave + â a circumflex + ä a diaresis + æ aesc ash + è e grave + é e acute + ê e circumflex + ë e diaresis + î i circumflex + ï i diaresis + ô o circumflex + ö o diaresis + ù u grave + û u circumflex + ü u diaresis + ÿ y diaresis + Œ OE ethel + œ oe ethel + Ÿ Y diaresis + + ’ apostrophe +} +unit mseconsts_fr; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseconsts; + +implementation +uses + msetypes{msestrings},sysutils,mseformatstr; +const + fr_modalresulttext: defaultmodalresulttextty = + ('', //mr_none + '', //mr_canclose + '', //mr_windowclosed + '', //mr_windowdestroyed + '', //mr_escape + '', //mr_f10 + '', //mr_exception + '&Effacer', //mr_cancel + '&Arr'#0234'ter',//mr_abort + '&Valider', //mr_ok + '&Oui', //mr_yes + '&Non', //mr_no + '&Tout', //mr_all + 'Oui &tout', //mr_yesall + 'A&ucun', //mr_noall + '&Ignorer', //mr_ignore + '&Passer', //mr_skip + 'Passer &tout', //mr_skipall + 'Co&ntinuer' //mr_continue + ); + + fr_modalresulttextnoshortcut: defaultmodalresulttextty = + ('', //mr_none + '', //mr_canclose + '', //mr_windowclosed + '', //mr_windowdestroyed + '', //mr_escape + '', //mr_f10 + '', //mr_exception + 'Effacer', //mr_cancel + 'Arr'#0234'ter',//mr_abort + 'Valider', //mr_ok + 'Oui', //mr_yes + 'Non', //mr_no + 'Tout', //mr_all + 'Oui tout', //mr_yesall + 'Aucun', //mr_noall + 'Ignorer', //mr_ignore + 'Passer', //mr_skip + 'Passer tout', //mr_skipall + 'Continuer' //mr_continue + ); + + fr_stockcaption: stockcaptionaty = ( + '', //sc_none + 'est invalide', //sc_is_invalid + 'Erreur de format', //sc_Format_error + 'Valeur requise', //sc_Value_is_required + 'Erreur', //sc_Error + 'Min.', //sc_Min + 'Max.', //sc_Max + 'Erreur de rang', //sc_Range_error + + '&D'#0233'faire', //sc_Undo /// /// + '&Refaire', //sc_Redo // // + '&Copier', //sc_Copy // hotkeys // + 'C&ouper', //sc_Cut // // + 'Co&ller', //sc_Paste // // hotkeys + '&S'#0233'lectionner tout', //sc_Select_allhk /// // + '&Ins'#0233'rer ligne', //sc_insert_row /// // + '&Ajouter ligne', //sc_append_row // hotkeys // + '&Supprimer ligne', //sc_delete_row /// /// + + 'R'#0233'&pertoire', //sc_Dir /// + '&Racine', //sc_home // + '&Remonter', //sc_Up // + '&Nouveau r'#0233'pertoire', //sc_New_dir // hotkeys + 'N&om', //sc_Name // + '&Afficher fichiers cach'#0233's', //sc_Show_hidden_files // + '&Filtre', //sc_Filter /// + 'Sauver', //sc_save + 'Ouvrir', //sc_open + 'Nom', //sc_name1 + 'Cr'#0233'er un nouveau r'#0233'pertoire',//sc_create_new_directory + 'Arri'#0232're', //sc_back + 'Avant', //sc_forward + 'Dessus', //sc_up + 'Fichier', //sc_file + 'existe, Remplacer ?', //sc_exists_overwrite + 'modifi'#0233'. Enregistrer ?', //sc_is_modified_save + 'AVERTISSEMENT', //sc_warningupper + 'ERREUR', //sc_errorupper + 'Exception', //sc_exception + 'Syst'#0232'me', //sc_system + 'n'#8217'existe pas', //sc_does_not_exist + 'MOT DE PASSE', //sc_passwordupper + 'Entrer le mot de passe', //sc_enterpassword + 'Mot de passe invalide!', //sc_invalidpassword + 'Impossible de lire le r'#0233'pertoire', //sc_can_not_read_directory + 'Format graphique non support'#0233'', //sc_graphic_not_supported + 'Erreur de format graphique', //sc_graphic_format_error + 'Bitmap MS', //sc_MS_Icon + 'Icone MS', //sc_MS_Icon + 'Image JPEG', //sc_JPEG_Image + 'Image PNG', //sc_PNG_Image + 'Image XPM', //sc_XPM_Image + 'Image PNM', //sc_PNM_Image + 'Image TARGA', //sc_TARGA_image + 'Image TIFF', //sc_TIFF_image + 'Tous', //sc_All + 'Confirmer', //sc_Confirmation + 'Effacer l'#8217'enregistrement ?', //sc_Delete_record_question + 'Copier l'#8217'enregistrement ?', //sc_Copy_record_question + 'Fermer page', //sc_close_page + 'Premier', //sc_first + 'Pr'#0233'c'#0233'dent', //sc_prior + 'Suivant', //sc_next + 'Dernier', //sc_last + 'Ajouter', //sc_append + 'Supprimer', //sc_delete + #0201'diter', //sc_edit + 'Poster', //sc_post + 'Effacer', //sc_cancel + 'Rafra'#0238'chir', //sc_refresh + #0201'dition Filtre', //sc_filter_filter + #0201'dition Filtre Minimum', //sc_edit_filter_min + #0201'dition Filtre Maximum', //sc_filter_edit_max + 'R'#0233'initialiser le filtre', //sc_reset_filter + 'Filtre actif', //sc_filter_on + 'Rechercher', //sc_search + #0201'dition automatique', //sc_autoedit + 'Copier l'#08217'enregistrement', //sc_copy_record + 'Dialogue', //sc_dialog + 'Ins'#0233'rer', //sc_insert + 'Copier', //sc_copy + 'Coller', //sc_paste + 'Ins'#0233'rer ligne', //sc_row_insert + 'Ajouter ligne', //sc_row_append + 'Supprimer ligne', //sc_row_delete + 'D'#0233'faire', //sc_undo + 'Refaire', //sc_redo + 'Couper', //sc_cut + 'S'#0233'lectionner tout', //sc_select_all + 'Filtre inactif', //sc_filter_off + 'Portrait', //sc_portrait print orientation + 'Paysage', //sc_landscape print orientation + 'Supprimer ligne ?', //sc_Delete_row_question + 'Lignes s'#0233'lectionn'#0233'es', //sc_selected_rows + 'seulement un '#0233'l'#0233'ment', //sc_Single_item_only + 'Copier cellules', //sc_Copy_Cells + 'Coller cellules', //sc_Paste_Cells + 'Fermer', //sc_close + 'Maximiser', //sc_maximize + 'Normaliser', //sc_normalize + 'Minimiser', //sc_minimize + 'Taille fixe', //sc_fix_size + 'Flottant', //sc_float + 'Rester en avant', //sc_stay_on_top + 'Rester en arri'#0232're', //sc_stay_in_background + 'Bloquer les descendants', //sc_lock_children + 'Ne pas bloquer', //sc_no_lock + 'Entr'#0233'e', //sc_input + 'Boutton', //sc_button + 'Allum'#0233'', //sc_on + #0201'teint', //sc_off + 'Bord gauche', //sc_leftborder + 'Bord haut', //sc_topborder + 'Bord droit', //sc_rightborder + 'Bord bas', //sc_bottomborder + 'D'#0233'but du texte', //sc_beginoftext + 'Fin du texte', //sc_endoftext + 'Mode entr'#0233'e', //sc_inputmode + #0201'craser', //sc_overwrite + 'D'#0233'truit', //sc_deleted + 'Copie'#0233, //sc_copied + 'Inser'#0233, //sc_inserted + 'Coll'#0233, //sc_pasted + 'Retir'#0233, //sc_withdrawn + 'Fen'#0232'tre activ'#0233'e', //sc_windowactivated + 'Menu', //sc_menu + 'D'#0233'but du fichier', //sc_bof + 'Fin du fichier', //sc_eof + 'Sortie voix', //sc_voiceoutput + 'R'#0233'p'#0233'ter', //sc_speakagain + 'Premi'#0232're colonne', //sc_firstcol + 'Premi'#0232're ligne', //sc_firstrow + 'D'#0232'rni'#0232're colonne', //sc_lastcol + 'D'#0232'rni'#0232're ligne', //sc_lastrow + 'S'#0233'lection', //sc_selection + 'Chemin de speak', //sc_speakpath + 'D'#0233'sactiver le boutton', //sc_disabledbutton + 'Premier champ', //sc_firstfield + 'D'#0232'rnier champ', //sc_lastfield + 'Premier '#0233'lement', //sc_firstelement + 'D'#0232'rnier '#0233'lement', //sc_lastelement + 'Plus lent', //sc_slower + 'Plus rapide', //sc_faster + 'Fen'#0232'tre', //sc_window + 'Aire', //sc_area + 'Aire activ'#0233'e', //sc_areaactivated + 'Volume moins', //sc_volumedown + 'Volume plus', //sc_volumeup + 'Annuler speech' //sc_cancelspeech +); + +function delete_n_selected_rows(const params: array of const): msestring; +begin + with params[0] do begin + if vinteger = 1 then begin + result:= 'Effacer le fichier s'#0233'lectionn'#0233' ?' + end + else begin + result:= 'Effacer les '+inttostrmse(vinteger)+ + ' fichiers s'#0233'lectionn'#0233's ?'; + end; + end; +end; + +const + fr_textgenerator: defaultgeneratortextty = ( + {$ifdef FPC}@{$endif}delete_n_selected_rows //tg_delete_n_selected_rows + ); +initialization + registerlangconsts(langnames[la_fr],@fr_stockcaption,@fr_modalresulttext, + @fr_modalresulttextnoshortcut,@fr_textgenerator); +end. diff --git a/mseide-msegui/lib/common/kernel/mseconsts_id.pas b/mseide-msegui/lib/common/kernel/mseconsts_id.pas new file mode 100644 index 0000000..0c433ec --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseconsts_id.pas @@ -0,0 +1,235 @@ +{ MSEgui Copyright (c) 1999-2010 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Indonesia translation by Wahono. + +} +unit mseconsts_id; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface + +implementation +uses + mseconsts,msetypes{msestrings},sysutils,mseformatstr; + +const + id_modalresulttext: defaultmodalresulttextty = + ('', //mr_none + '', //mr_canclose + '', //mr_windowclosed + '', //mr_windowdestroyed + '', //mr_escape + '', //mr_f10 + '', //mr_exception + '&Batal', //mr_cancel + '&Gagalkan', //mr_abort + '&OK', //mr_ok + '&Ya', //mr_yes + '&Tidak', //mr_no + '&Semua', //mr_all + 'Yes &all', //mr_yesall + 'Tid&ak Semua', //mr_noall + '&Abaikan', //mr_ignore + '&Skip', //mr_skip + 'Skip &all', //mr_skipall + 'Co&ntinue' //mr_continue + ); + + id_modalresulttextnoshortcut: defaultmodalresulttextty = + ('', //mr_none + '', //mr_canclose + '', //mr_windowclosed + '', //mr_windowdestroyed + '', //mr_escape + '', //mr_f10 + '', //mr_exception + 'Gagal', //mr_cancel + 'Batal', //mr_abort + 'OK', //mr_ok + 'Ya', //mr_yes + 'Tidak', //mr_no + 'Semua', //mr_all + 'Yes all', //mr_yesall + 'Tidak Semua', //mr_noall + 'Abaikan', //mr_ignore + 'Skip', //mr_skip + 'Skip all', //mr_skipall + 'Continue' //mr_continue + ); + + id_stockcaption: stockcaptionaty = ( + '', //sc_none + 'adalah salah', //sc_is_invalid + 'Format salah', //sc_Format_error + 'Nilai dibutuhkan', //sc_Value_is_required + 'Salah', //sc_Error + 'Min', //sc_Min + 'Max', //sc_Max + 'Range salah', //sc_Range_error + '&Batal', //sc_Undohk /// + '&Redo', //sc_Redohk // // + '&Salin', //sc_Copyhk // hotkeys + 'Po&tong', //sc_Cuthk // + '&Tempel', //sc_Pastehk // + '&Select all', //sc_Select_allhk /// // + '&Sisipkan Baris', //sc_insert_rowhk + '&Tambah Baris', //sc_append_rowhk + '&Hapus Baris', //sc_delete_rowhk + '&Direktori', //sc_Dirhk /// + '&Home', //sc_homehk // + '&Naik', //sc_Uphk // + 'Dir &Baru', //sc_New_dirhk // hotkeys + '&Nama File', //sc_Namehk // + '&File tersembunyi', //sc_Show_hidden_fileshk // + '&Filter', //sc_Filterhk /// + 'Simpan', //sc_save + 'Buka', //sc_open + 'Nama', //sc_name + 'Buat Direktori Baru', //sc_create_new_directory + 'Back', //sc_back + 'Forward', //sc_forward + 'Up', //sc_up + 'File', //sc_file + 'sudah ada, akan ditimpa?', //sc_exists_overwrite + 'is modified. Save?', //sc_is_modified_save + 'PERINGATAN', //sc_warningupper + 'SALAH', //sc_errorupper + 'Exception', //sc_exception + 'System', //sc_system + 'tidak ada', //sc_does_not_exist + 'PASSWORD', //sc_passwordupper + 'Enter password', //sc_enterpassword + 'Invalid password!', //sc_invalidpassword + 'tidak dapat membaca direktori', //sc_can_not_read_directory + 'Format grafik tidak didukung', //sc_graphic_not_supported + 'Format grafik salah', //sc_graphic_format_error + 'MS Bitmap', //sc_MS_Bitmap + 'MS Icon', //sc_MS_Icon + 'JPEG Image', //sc_JPEG_Image + 'PNG Image', //sc_PNG_Image + 'XPM Image', //sc_XPM_Image + 'PNM Image', //sc_PNM_Image + 'TARGA Image', //sc_TARGA_image + 'TIFF Image', //sc_TIFF_image + 'Semua', //sc_All + 'Konfirmasi', //sc_Confirmation + 'Hapus Rekaman?', //sc_Delete_record_question + 'Salin record?', //sc_Copy_record_question + 'Tutup', //sc_close_page + 'Awal', //sc_first + 'Sebelum', //sc_prior + 'Sesudah', //sc_next + 'Akhir', //sc_last + 'Tambah', //sc_append + 'Hapus', //sc_delete + 'Rubah', //sc_edit + 'Simpan', //sc_post + 'Batal', //sc_cancel + 'Refresh', //sc_refresh + 'Rubah filter', //sc_filter_filter + 'Rubah filter minimum', //sc_edit_filter_min + 'Rubah filter maximum', //sc_filter_edit_max + 'Reset filter', //sc_reset_filter + 'Filter hidup', //sc_filter_on + 'Cari', //sc_search + 'Rubah Otomatis', //sc_autoedit + 'Salin record', //sc_copy_record + 'Dialog', //sc_dialog + 'Sisipkan', //sc_insert + 'Salin', //sc_copy + 'Paste', //sc_paste + 'Row insert', //sc_row_insert + 'Row append', //sc_row_append + 'Row delete', //sc_row_delete + 'Undo', //sc_undo + 'Redo', //sc_redo + 'Cut', //sc_cut + 'Select all', //sc_select_all + 'Filter mati', //sc_filter_off + 'Berdiri', //sc_portrait print orientation + 'Rebah', //sc_landscape print orientation + 'Hapus baris?', //sc_Delete_row_question + 'baris yang terpilih?', //sc_selected_rows + 'Hanya satu item', //sc_Single_item_only, + 'Salin Cell', //sc_Copy_Cells + 'Tempel Cell', //sc_Paste_Cells + 'Close', //sc_close + 'Maximize', //sc_maximize + 'Normalize', //sc_normalize + 'Minimize', //sc_minimize + 'Fix size', //sc_fix_size + 'Float', //sc_float + 'Stay on top', //sc_stay_on_top + 'Stay in background', //sc_stay_in_background + 'Lock children', //sc_lock_children + 'No lock', //sc_no_lock + 'Input', //sc_input + 'Button', //sc_button + 'On', //sc_on + 'Off', //sc_off + 'Left border', //sc_leftborder + 'Top border', //sc_topborder + 'Right border', //sc_rightborder + 'Bottom border', //sc_bottomborder + 'Begin of text', //sc_beginoftext + 'End of text', //sc_endoftext + 'Inputmode', //sc_inputmode + 'Overwrite', //sc_overwrite + 'Deleted', //sc_deleted + 'Copied', //sc_copied + 'Inserted', //sc_inserted + 'Pasted', //sc_pasted + 'Withdrawn', //sc_withdrawn + 'Window activated', //sc_windowactivated + 'Menu', //sc_menu + 'Beginning of file', //sc_bof + 'End of file', //sc_eof + 'Voice output', //sc_voiceoutput + 'Speak again', //sc_speakagain + 'First column', //sc_firstcol + 'First row', //sc_firstrow + 'Last column', //sc_lastcol + 'Last row', //sc_lastrow + 'Selection', //sc_selection + 'Speak path', //sc_speakpath + 'Disabled button', //sc_disabledbutton + 'First field', //sc_firstfield + 'Last field', //sc_lastfield + 'First element', //sc_firstelement + 'Last element', //sc_lastelement + 'Slower', //sc_slower + 'Faster', //sc_faster + 'Window', //sc_window + 'Area', //sc_area + 'Area activated', //sc_areaactivated + 'Volume down', //sc_volumedown + 'Volume up', //sc_volumeup + 'Cancel speech' //sc_cancelspeech +); + +function delete_n_selected_rows(const params: array of const): msestring; +begin + with params[0] do begin + if vinteger = 1 then begin + result:= 'Delete selected row?' + end + else begin + result:= 'Delete '+inttostrmse(vinteger)+' selected rows?'; + end; + end; +end; + +const + id_textgenerator: defaultgeneratortextty = ( + {$ifdef FPC}@{$endif}delete_n_selected_rows //tg_delete_n_selected_rows + ); +initialization + registerlangconsts(langnames[la_id],@id_stockcaption,@id_modalresulttext, + @id_modalresulttextnoshortcut,@id_textgenerator); +end. diff --git a/mseide-msegui/lib/common/kernel/mseconsts_ru.pas b/mseide-msegui/lib/common/kernel/mseconsts_ru.pas new file mode 100644 index 0000000..d3be879 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseconsts_ru.pas @@ -0,0 +1,280 @@ +{ MSEgui Copyright (c) 1999-2006 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Russian translation by IvankoB and AlexL. + +} + +unit mseconsts_ru; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +implementation +uses + mseconsts,msetypes{msestrings},sysutils,mseformatstr; + +const + ru_modalresulttext: defaultmodalresulttextty = ( + '', //mr_none => Nichego + '', //mr_canclose => + //Mozhno zakryt` + '', //mr_windowclosed => + //Okno zakryto + '', //mr_windowdestroyed => + //Okno udaleno + '', //mr_escape + '', //mr_f10 + '', //mr_exception => + //Neozhidannaya situatsiya + '&'#1054#1090#1084#1077#1085#1080#1090#1100 , //mr_cancel => &Otmenit` + '&'#1055#1088#1077#1088#1074#1072#1090#1100 , //mr_abort => &Prervat` + '&'#1043#1086#1090#1086#1074#1086 , //mr_ok => &Gotovo + '&'#1044#1072 , //mr_yes => &Da + '&'#1053#1077#1090 , //mr_no => &Net + '&'#1042#1089#1077 , //mr_all => &Vse + 'Yes &all', //mr_yesall + #1053'&'#1080#1082#1072#1082#1080#1077 , //mr_noall => N&ikakie + #1053#1077#1074#1072'&'#1078#1085#1086, //mr_ignore => Neva&zhno + '&Skip', //mr_skip + 'Skip &all', //mr_skipall + 'Co&ntinue' //mr_continue +); + + ru_modalresulttextnoshortcut: defaultmodalresulttextty = + ('', //mr_none + '', //mr_canclose + '', //mr_windowclosed + '', //mr_windowdestroyed + '', //mr_escape + '', //mr_f10 + #1053#1077#1086#1078#1080#1076#1072#1085#1085#1072#1103' ' + + #1089#1080#1090#1091#1072#1094#1080#1103 , //mr_exception + #1054#1090#1084#1077#1085#1080#1090#1100 , //mr_cancel => Otmenit` + #1055#1088#1077#1088#1074#1072#1090#1100 , //mr_abort => Prervat` + #1043#1086#1090#1086#1074#1086 , //mr_ok => Gotovo + #1044#1072 , //mr_yes => Da + #1053#1077#1090 , //mr_no => Net + #1042#1089#1077 , //mr_all => Vse + 'Yes all', //mr_yesall + #1053#1080#1082#1072#1082#1080#1077 , //mr_noall => Nikakie + #1053#1077#1074#1072#1078#1085#1086, //mr_ignore => Nevazhno + 'Skip', //mr_skip + 'Skip all', //mr_skipall + 'Continue' //mr_continue + ); + + ru_stockcaption: stockcaptionaty = ( + '', //sc_none + '- '#1085#1077#1074#1077#1088#1085#1086 , //sc_is_invalid => - neverno + #1053#1077#1089#1086#1086#1090#1074#1077#1090#1089#1090#1074#1080#1077' '+ + #1092#1086#1088#1084#1072#1090#1091 , //sc_Format_error => + //Nesootvetstvie formatu + #1058#1088#1077#1073#1091#1077#1090#1089#1103' '+ + #1079#1085#1072#1095#1077#1085#1080#1077 , //sc_Value_is_required => + //Trebuetsya znachenie + #1054#1096#1080#1073#1082#1072 , //sc_Error => Oshibka + #1052#1080#1085'.' , //sc_Min => Min. + #1052#1072#1082#1089'.' , //sc_Max => Maks. + #1053#1077#1089#1086#1086#1090#1074#1077#1090#1089#1090#1074#1080#1077' '+ + #1076#1080#1072#1087#1072#1079#1086#1085#1091 , + //sc_Range_error => + //Nesootvetstvie diapazonu + + // hotkeys/// + #1042#1077#1088#1085#1091#1090#1100 , //sc_Undohk => Vernut` + 'П#1086#1074#1090#1086#1088', //sc_Redohk => Povtor// // + #1057#1082#1086#1087#1080#1088#1086#1074#1072#1090#1100 , + //sc_Copyhk => Skopirovat` + #1042#1099#1088#1077#1079#1072#1090#1100 , //sc_Cuthk => Vyrezat` + #1042#1089#1090#1072#1074#1080#1090#1100 , ///sc_Pastehk => Vstavit` + '&Select all', //sc_Select_allhk /// // + '&'#1042#1089#1090#1072#1074#1080#1090#1100' '#1089#1090#1088#1086#1082#1091, //sc_insert_rowhk => Vstavit' stroku /// // + '&'#1044#1086#1073#1072#1074#1080#1090#1100' '#1089#1090#1088#1086#1082#1091, //sc_append_rowhk => Dobavit' stroku // hotkeys // + '&'#1059#1076#1072#1083#1080#1090#1100' '#1089#1090#1088#1086#1082#1091, //sc_delete_rowhk => Udalit' stroku/// /// + + // hotkeys/// + '&'#1050#1072#1090#1072#1083#1086#1075 , //sc_Dirhk => Katalog + '&'#1044#1086#1084'.', //sc_homehk => Dom. // + '&'#1042#1074#1077#1088#1093 , //sc_Uphk => Vverh + '&'#1053#1086#1074'. '#1082#1072#1090'-'#1075 , //sc_New_dirhk => Nov. kat-g + #1053#1072'&'#1079#1074#1072#1085#1080#1077 , //sc_Namehk => Nazvanie + + #1055#1086#1082#1072#1079'. &'#1089#1082#1088#1099#1090'. '+ + #1092#1072#1081#1083#1099 , //sc_Show_hidden_fileshk => + //Pokaz. skryt. faily + '&'#1060#1080#1083#1100#1090#1088 , ///sc_Filterhk => Fil`tr + + #1057#1086#1093#1088#1072#1085#1080#1090#1100 , //sc_save => Sohranit` + #1054#1090#1082#1088#1099#1090#1100 , //sc_open => Otkryt` + #1048#1084#1103, //sc_name + #1057#1086#1079#1076#1072#1090#1100' '#1085#1086#1074#1099#1081' '+ + #1082#1072#1090#1072#1083#1086#1075 , //sc_create_new_directory + 'Back', //sc_back + 'Forward', //sc_forward + 'Up', //sc_up + #1060#1072#1081#1083 , //sc_file + #1091#1078#1077' '#1077#1089#1090#1100', '+ + #1087#1077#1088#1077#1079#1072#1087#1080#1089#1072#1090#1100'?' , + //sc_exists_overwrite + #1073#1099#1083' '#1080#1079#1084#1077#1085#1105#1085'. '#1057#1086#1093#1088#1072#1085#1080#1090#1100'?', //sc_is_modified_save + #1055#1056#1045#1044#1059#1055#1056#1045#1046#1044#1045#1053#1048#1045 , + //sc_warningupper + #1054#1064#1048#1041#1050#1040 , //sc_errorupper + #1048#1089#1082#1083#1102#1095#1077#1085#1080#1077, //sc_exception + #1057#1080#1089#1090#1077#1084#1072, //sc_system + #1085#1077' '#1089#1091#1097#1077#1089#1090#1074#1091#1077#1090 , + //sc_does_not_exist + #1055#1072#1088#1086#1083#1100, //sc_passwordupper + #1042#1074#1077#1076#1080#1090#1077' '#1087#1072#1088#1086#1083#1100, //sc_enterpassword + #1053#1077#1074#1077#1088#1085#1099#1081' '#1087#1072#1088#1086#1083#1100'!', //sc_invalidpassword + #1053#1077' '#1091#1076#1072#1077#1090#1089#1103' '+ + #1087#1088#1086#1095#1077#1089#1090#1100' '+ + #1089#1086#1076#1077#1088#1078#1080#1084#1086#1077+ + ' '#1082#1072#1090#1072#1083#1086#1075#1072 , //sc_can_not_read_directory + #1043#1088#1072#1092#1080#1095#1077#1089#1082#1080#1081' '+ + #1092#1086#1088#1084#1072#1090' '#1085#1077' '+ + #1087#1086#1076#1076#1077#1088#1078#1080#1074#1072#1077#1090#1089#1103 , + //sc_graphic_not_supported + #1043#1088#1072#1092#1080#1095#1077#1089#1082#1080#1077' '+ + #1076#1072#1085#1085#1099#1077' '#1085#1077' '+ + #1089#1086#1086#1090#1074#1077#1090#1089#1090#1074#1091#1102#1090' '+ + #1092#1086#1088#1084#1072#1090#1091 , //sc_graphic_format_error + 'BMP-'#1080#1079#1086#1073#1088#1072#1078#1077#1085#1080#1077 , + //sc_MS_Bitmap + 'ICO-'#1080#1079#1086#1073#1088#1072#1078#1077#1085#1080#1077 , + //sc_MS_Icon + 'JPEG-'#1080#1079#1086#1073#1088#1072#1078#1077#1085#1080#1077 , + //sc_JPEG_Image + 'PNG-'#1080#1079#1086#1073#1088#1072#1078#1077#1085#1080#1077 , + //sc_PNG_Image + 'XPM-'#1080#1079#1086#1073#1088#1072#1078#1077#1085#1080#1077 , + //sc_XPM_Image + 'PNM-'#1080#1079#1086#1073#1088#1072#1078#1077#1085#1080#1077 , + //sc_PNM_Image + 'TARGA-'#1080#1079#1086#1073#1088#1072#1078#1077#1085#1080#1077 , + //sc_TARGA_image + 'TIFF-'#1080#1079#1086#1073#1088#1072#1078#1077#1085#1080#1077 , + //sc_TIFF_image + #1042#1089#1077 , //sc_All + #1055#1086#1076#1090#1074#1077#1088#1078#1076#1077#1085#1080#1077 , + //sc_Confirmation + #1059#1076#1072#1083#1080#1090#1100' '#1079#1072#1087#1080#1089#1100'?', + //sc_Delete_record_question + #1047#1072#1082#1088#1099#1090#1100#32#1089#1090#1088#1072#1085#1080#1094#1091, //sc_close_page + #1057#1085#1072#1095#1072#1083#1072, //sc_first + #1055#1088#1080#1086#1088, //sc_prior + #1044#1072#1083#1077#1077, //sc_next + #1053#1072#1079#1072#1076, //sc_last + #1044#1086#1073#1072#1074#1080#1090#1100, //sc_append + #1059#1076#1072#1083#1080#1090#1100, //sc_delete + #1055#1088#1072#1074#1080#1090#1100, //sc_edit + #1055#1086#1089#1083#1077, //sc_post + #1054#1090#1084#1077#1085#1072, //sc_cancel + #1054#1073#1085#1086#1074#1080#1090#1100, //sc_refresh + #1048#1079#1084#1077#1085#1080#1090#1100' '#1092#1080#1083#1100#1090#1088, //sc_filter_filter + #1048#1079#1084#1077#1085#1080#1090#1100' '#1084#1080#1085'. '#1092#1080#1083#1100#1090#1088 ,//sc_edit_filter_min + #1048#1079#1084#1077#1085#1080#1090#1100' '#1084#1072#1082#1089'. '#1092#1080#1083#1100#1090#1088, //sc_filter_edit_max + 'Reset filter', //sc_reset_filter + #1042#1082#1083'. '#1092#1080#1083#1100#1090#1088, //sc_filter_on + #1055#1086#1080#1089#1082, //sc_search + #1040#1074#1090#1086#1084#1072#1090'. '#1087#1088#1072#1074#1082#1072, //sc_autoedit + #1050#1086#1087#1080#1088#1086#1074#1072#1090#1100' '#1079#1072#1087#1080#1089#1100, //sc_copy_record + #1050#1086#1087#1080#1088#1086#1074#1072#1090#1100' '#1079#1072#1087#1080#1089#1100'?', //sc_Copy_record_question + #1044#1080#1072#1083#1086#1075, //sc_dialog + #1042#1089#1090#1072#1074#1080#1090#1100, //sc_insert + #1050#1086#1087#1080#1088#1086#1074#1072#1090#1100, //sc_copy + #1042#1089#1090#1072#1074#1080#1090#1100, //sc_paste + #1042#1089#1090#1072#1074#1080#1090#1100' '#1089#1090#1088#1086#1082#1091, //sc_row_insert + #1044#1086#1073#1072#1074#1080#1090#1100' '#1089#1090#1088#1086#1082#1091, //sc_row_append + #1059#1076#1072#1083#1080#1090#1100' '#1089#1090#1088#1086#1082#1091, //sc_row_delete + #1054#1090#1084#1077#1085#1080#1090#1100, //sc_undo + #1055#1086#1074#1090#1086#1088#1080#1090#1100, //sc_redo + #1042#1099#1088#1077#1079#1072#1090#1100, //sc_cut + #1042#1099#1076#1077#1083#1080#1090#1100' '#1074#1089#1105, //sc_select_all + #1054#1090#1082#1083'. '#1092#1080#1083#1100#1090#1088, //sc_filter_off + #1040#1083#1100#1073#1086#1084#1085#1072#1103, //sc_portrait print orientation + #1050#1085#1080#1078#1085#1072#1103, //sc_landscape print orientation + #1059#1076#1072#1083#1080#1090#1100' '#1089#1090#1088#1086#1082#1091'?', //sc_Delete_row_question + #1074#1099#1073#1088#1072#1085#1085#1099#1077' '#1089#1090#1088#1086#1082#1080'?', //sc_selected_rows + #1058#1086#1083#1100#1082#1086' '#1087#1088#1086#1089#1090#1086#1081' '#1087#1091#1085#1082#1090, //sc_Single_item_only + #1050#1086#1087#1080#1088#1086#1074#1072#1090#1100' '#1103#1095#1077#1081#1082#1080, //sc_Copy_Cells + #1042#1089#1090#1072#1074#1080#1090#1100' '#1103#1095#1077#1081#1082#1080, //sc_Paste_Cells + 'Close', //sc_close + 'Maximize', //sc_maximize + 'Normalize', //sc_normalize + 'Minimize', //sc_minimize + 'Fix size', //sc_fix_size + 'Float', //sc_float + 'Stay on top', //sc_stay_on_top + 'Stay in background', //sc_stay_in_background + 'Lock children', //sc_lock_children + 'No lock', //sc_no_lock + 'Input', //sc_input + 'Button', //sc_button + 'On', //sc_on + 'Off', //sc_off + 'Left border', //sc_leftborder + 'Top border', //sc_topborder + 'Right border', //sc_rightborder + 'Bottom border', //sc_bottomborder + 'Begin of text', //sc_beginoftext + 'End of text', //sc_endoftext + 'Inputmode', //sc_inputmode + 'Overwrite', //sc_overwrite + 'Deleted', //sc_deleted + 'Copied', //sc_copied + 'Inserted', //sc_inserted + 'Pasted', //sc_pasted + 'Withdrawn', //sc_withdrawn + 'Window activated', //sc_windowactivated + 'Menu', //sc_menu + 'Beginning of file', //sc_bof + 'End of file', //sc_eof + 'Voice output', //sc_voiceoutput + 'Speak again', //sc_speakagain + 'First column', //sc_firstcol + 'First row', //sc_firstrow + 'Last column', //sc_lastcol + 'Last row', //sc_lastrow + 'Selection', //sc_selection + 'Speak path', //sc_speakpath + 'Disabled button', //sc_disabledbutton + 'First field', //sc_firstfield + 'Last field', //sc_lastfield + 'First element', //sc_firstelement + 'Last element', //sc_lastelement + 'Slower', //sc_slower + 'Faster', //sc_faster + 'Window', //sc_window + 'Area', //sc_area + 'Area activated', //sc_areaactivated + 'Volume down', //sc_volumedown + 'Volume up', //sc_volumeup + 'Cancel speech' //sc_cancelspeech +); + +function delete_n_selected_rows(const params: array of const): msestring; +begin + with params[0] do begin + if vinteger = 1 then begin + result:= #1059#1076#1072#1083#1080#1090#1100' '#1074#1099#1073#1088#1072#1085#1085#1091#1102' '#1089#1090#1088#1086#1082#1091'?' + end + else begin + result:= #1059#1076#1072#1083#1080#1090#1100' '+inttostrmse(vinteger)+' '#1074#1099#1073#1088#1072#1085#1085#1091#1102' '#1089#1090#1088#1086#1082#1091'?'; + end; + end; +end; + +const + ru_textgenerator: defaultgeneratortextty = ( + {$ifdef FPC}@{$endif}delete_n_selected_rows //tg_delete_n_selected_rows + ); +initialization + registerlangconsts(langnames[la_ru],@ru_stockcaption,@ru_modalresulttext, + @ru_modalresulttextnoshortcut,@ru_textgenerator); +end. diff --git a/mseide-msegui/lib/common/kernel/mseconsts_uzcyr.pas b/mseide-msegui/lib/common/kernel/mseconsts_uzcyr.pas new file mode 100644 index 0000000..ec3841c --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseconsts_uzcyr.pas @@ -0,0 +1,243 @@ +{ MSEgui Copyright (c) 1999-2006 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Uzbek-Cyrillic translation by IvankoB. + +} + + +unit mseconsts_uzcyr; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseconsts; + +implementation +uses + msetypes{msestrings},sysutils,mseformatstr; +const + uzcyr_modalresulttext: defaultmodalresulttextty = ( + '', //mr_none => Nichego + '', //mr_canclose => Mozhno zakryt` + '', //mr_windowclosed => Okno zakryto + '', //mr_windowdestroyed => Okno udaleno + '', //mr_escape + '', //mr_f10 + #1061#1072#1090#1086 , //mr_exception => Neozhidannaya situatsiya + '&'#1041#1077#1082#1086#1088' '#1179#1080#1083#1080#1096 , //mr_cancel => &Otmenit` + '&'#1059#1079#1080#1073' '#1179#1118#1081#1080#1096 , //mr_abort => &Prervat` + '&'#1058#1072#1081#1105#1088 , //mr_ok => &Gotovo + '&'#1202#1072 , //mr_yes => &Da + '&'#1049#1118#1082 , //mr_no => &Net + #1041#1072'&'#1088#1095#1072 , //mr_all => &Vse + 'Yes &all', //mr_yesall + #1202#1077'&'#1095' '#1073#1080#1088#1080 , //mr_noall => N&ikakie + '&'#1052#1072#1085' '#1101#1090#1080#1096, //mr_ignore => Neva&zhno + '&Skip', //mr_skip + 'Skip &all', //mr_skipall + 'Co&ntinue' //mr_continue + ); + + uzcyr_modalresulttextnoshortcut: defaultmodalresulttextty = + ('', //mr_none + '', //mr_canclose + '', //mr_windowclosed + '', //mr_windowdestroyed + '', //mr_escape + '', //mr_f10 + #1061#1072#1090#1086 , //mr_exception + #1041#1077#1082#1086#1088' '#1179#1080#1083#1080#1096 , //mr_cancel => Otmenit` + #1059#1079#1080#1073' '#1179#1118#1081#1080#1096 , //mr_abort => Prervat` + #1058#1072#1081#1105#1088 , //mr_ok => Gotovo + #1202#1072 , //mr_yes => Da + #1049#1118#1082 , //mr_no => Net + #1041#1072#1088#1095#1072 , //mr_all => Vse + 'Yes all', //mr_yesall + #1202#1077#1095' '#1073#1080#1088#1080 , //mr_noall => Nikakie + #1052#1072#1085' '#1101#1090#1080#1096, //mr_ignore => Nevazhno + 'Skip', //mr_skip + 'Skip all', //mr_skipall + 'Continue' //mr_continue + ); + + uzcyr_stockcaption: stockcaptionaty = ( + '', //sc_none + '- '#1085#1086#1072#1085#1080#1179 , //sc_is_invalid => - neverno + #1060#1086#1088#1084#1072#1090' '#1085#1086#1090#1118#1171#1088#1080 , + //sc_Format_error => Nesootvetstvie formatu + #1202#1077#1095' '#1085#1072#1088#1089#1072' '#1082#1077#1088#1072#1082' '#1101#1084#1072#1089 , + //sc_Value_is_required => Trebuetsya znachenie + #1053#1086#1090#1118#1171#1088#1080 , //sc_Error => Oshibka + #1052#1080#1085'.' , //sc_Min => Min. + #1052#1072#1082#1089'.' , //sc_Max => Maks. + #1053#1086#1090#1118#1171#1088#1080' '#1076#1080#1072#1087#1072#1079#1086#1085 , + //sc_Range_error => Nesootvetstvie diapazonu + + #1054#1083#1076#1080#1085#1075#1080 , //sc_Undohk => Vernut` + '&Redo', //sc_Redohk // // + #1050#1118#1095#1080#1088#1080#1096 , //sc_Copyhk // hotkeys=> Skopirovat` + #1054#1083#1080#1073' '#1090#1072#1096#1083#1072#1096 , //sc_Cuthk => Vyrezat` + #1025#1079#1080#1073' '#1179#1118#1081#1080#1096 , //sc_Pastehk => Vstavit` + '&Select all', //sc_Select_allhk /// // + '&Insert Row', //sc_insert_rowhk /// // + '&Append Row', //sc_append_rowhk // hotkeys // + '&Delete Row', //sc_delete_rowhk /// /// + + #1050#1072#1090#1072#1083#1086#1075 , //sc_Dirhk => Katalog + '&Home', //sc_homehk // + #1058#1077#1087#1087#1072#1075#1072 , //sc_Up => Vverh + #1071#1085#1075#1080' '#1082#1072#1090'.' , //sc_New_dir => Nov. kat-g + #1053#1086#1084#1080 , ///sc_Name => Nazvanie + #1041#1077#1088#1080#1090#1080#1083#1075#1072#1085' '#1092#1072#1081#1083#1072#1088#1085#1080' '#1179#1091#1088#1089#1072#1090#1080#1096 , //sc_Show_hidden_files => Pokaz. skryt. faily + #1060#1080#1083#1100#1090#1088 , //sc_Filter => Fil`tr + #1057#1072#1082#1083#1072#1096 , //sc_save => Sohranit` + #1054#1095#1080#1096 , //sc_open => Otkryt` + 'Name', //sc_name + 'Create new directory',//sc_create_new_directory + 'Back', //sc_back + 'Forward', //sc_forward + 'Up', //sc_up + 'File', //sc_file + 'exists, do you want to overwrite?', //sc_exists_overwrite + 'is modified. Save?', //sc_is_modified_save + 'WARNING', //sc_warningupper + 'ERROR', //sc_errorupper + 'Exception', //sc_exception + 'System', //sc_system + 'does not exist', //sc_does_not_exist + 'PASSWORD', //sc_passwordupper + 'Enter password', //sc_enterpassword + 'Invalid password!', //sc_invalidpassword + 'Can not read directory', //sc_can_not_read_directory + #1043#1088#1072#1092#1080#1082' '#1092#1086#1088#1084#1072#1090' '#1090#1072#1098#1084#1080#1085#1083#1072#1085#1084#1072#1075#1072#1085 , //sc_graphic_not_supported + #1053#1086#1090#1118#1171#1088#1080' '#1075#1088#1072#1092#1080#1082' '#1092#1086#1088#1084#1072#1090#1080 , //sc_graphic_format_error + 'BMP-'#1088#1072#1089#1084#1080 , //sc_MS_Bitmap + 'ICO-'#1088#1072#1089#1084#1080 , //sc_MS_Icon + 'JPEG-'#1088#1072#1089#1084#1080 , //sc_JPEG_Image + 'PNG-'#1088#1072#1089#1084#1080 , //sc_PNG_Image + 'XPM-'#1088#1072#1089#1084#1080 , //sc_XPM_Image + 'PNM-'#1088#1072#1089#1084#1080 , //sc_PNM_Image + 'TARGA-'#1088#1072#1089#1084#1080 , //sc_TARGA_image + 'TIFF-'#1088#1072#1089#1084#1080 , //sc_TIFF_image + #1041#1072#1088#1095#1072 , //sc_All + #1058#1072#1089#1076#1080#1179#1083#1072#1096 , //sc_Confirmation + #1025#1079#1091#1074#1085#1080' '#1118#1095#1080#1088#1080#1096, //sc_Delete_record_question + 'Copy record?', //sc_Copy_record_question + 'Close page', //sc_close_page + 'First', //sc_first + 'Prior', //sc_prior + 'Next', //sc_next + 'Last', //sc_last + 'Append', //sc_append + 'Delete', //sc_delete + 'Edit', //sc_edit + 'Post', //sc_post + 'Cancel', //sc_cancel + 'Refresh', //sc_refresh + 'Edit filter', //sc_filter_filter + 'Edit filter minimum',//sc_edit_filter_min + 'Edit filter maximum',//sc_filter_edit_max + 'Reset filter', //sc_reset_filter + 'Filter on', //sc_filter_on + 'Search', //sc_search + 'Auto edit', //sc_autoedit + 'Copy record', //sc_copy_record + 'Dialog', //sc_dialog + 'Insert', //sc_insert + 'Copy', //sc_copy + 'Paste', //sc_paste + 'Row insert', //sc_row_insert + 'Row append', //sc_row_append + 'Row delete', //sc_row_delete + 'Undo', //sc_undo + 'Redo', //sc_redo + 'Cut', //sc_cut + 'Select all', //sc_select_all + 'Filter off', //sc_filter_off + 'Portrait', //sc_portrait print orientation + 'Landscape', //sc_landscape print orientation + 'Delete row?', //sc_Delete_row_question + 'selected rows?', //sc_selected_rows + 'Single item only', //sc_Single_item_only + 'Copy Cells', //sc_Copy_Cells + 'Paste Cells', //sc_Paste_Cells + 'Close', //sc_close + 'Maximize', //sc_maximize + 'Normalize', //sc_normalize + 'Minimize', //sc_minimize + 'Fix size', //sc_fix_size + 'Float', //sc_float + 'Stay on top', //sc_stay_on_top + 'Stay in background', //sc_stay_in_background + 'Lock children', //sc_lock_children + 'No lock', //sc_no_lock + 'Input', //sc_input + 'Button', //sc_button + 'On', //sc_on + 'Off', //sc_off + 'Left border', //sc_leftborder + 'Top border', //sc_topborder + 'Right border', //sc_rightborder + 'Bottom border', //sc_bottomborder + 'Begin of text', //sc_beginoftext + 'End of text', //sc_endoftext + 'Inputmode', //sc_inputmode + 'Overwrite', //sc_overwrite + 'Deleted', //sc_deleted + 'Copied', //sc_copied + 'Inserted', //sc_inserted + 'Pasted', //sc_pasted + 'Withdrawn', //sc_withdrawn + 'Window activated', //sc_windowactivated + 'Menu', //sc_menu + 'Beginning of file', //sc_bof + 'End of file', //sc_eof + 'Voice output', //sc_voiceoutput + 'Speak again', //sc_speakagain + 'First column', //sc_firstcol + 'First row', //sc_firstrow + 'Last column', //sc_lastcol + 'Last row', //sc_lastrow + 'Selection', //sc_selection + 'Speak path', //sc_speakpath + 'Disabled button', //sc_disabledbutton + 'First field', //sc_firstfield + 'Last field', //sc_lastfield + 'First element', //sc_firstelement + 'Last element', //sc_lastelement + 'Slower', //sc_slower + 'Faster', //sc_faster + 'Window', //sc_window + 'Area', //sc_area + 'Area activated', //sc_areaactivated + 'Volume down', //sc_volumedown + 'Volume up', //sc_volumeup + 'Cancel speech' //sc_cancelspeech +); + +function delete_n_selected_rows(const params: array of const): msestring; +begin + with params[0] do begin + if vinteger = 1 then begin + result:= 'Delete selected row?' + end + else begin + result:= 'Delete '+inttostrmse(vinteger)+' selected rows?'; + end; + end; +end; + +const + uzcyr_textgenerator: defaultgeneratortextty = ( + {$ifdef FPC}@{$endif}delete_n_selected_rows //tg_delete_n_selected_rows + ); +initialization + registerlangconsts(langnames[la_uzcyr],@uzcyr_stockcaption,@uzcyr_modalresulttext, + @uzcyr_modalresulttextnoshortcut,@uzcyr_textgenerator); +end. diff --git a/mseide-msegui/lib/common/kernel/mseconsts_zh.pas b/mseide-msegui/lib/common/kernel/mseconsts_zh.pas new file mode 100644 index 0000000..1be2d21 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseconsts_zh.pas @@ -0,0 +1,242 @@ +{ MSEgui Copyright (c) 1999-2009 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Chinese translation by liuzg2. + +} +unit mseconsts_zh; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseconsts; + +implementation +uses + msetypes{msestrings},sysutils,mseformatstr; +const + zh_modalresulttext: defaultmodalresulttextty = + ('', //mr_none + '', //mr_canclose + '', //mr_windowclosed + '', //mr_windowdestroyed + '', //mr_escape + '', //mr_f10 + '', //mr_exception + '&C'#31163#24320, //mr_cancel + '&A'#21462#28040, //mr_abort + '&O'#30830#23450, //mr_ok + '&Y'#26159, //mr_yes + '&N'#21542, //mr_no + '&l'#25152#26377, //mr_all + 'Yes &all', //mr_yesall + #21462#28040#25152#26377, //mr_noall + '&g'#24573#30053, //mr_ignore + '&Skip', //mr_skip + 'Skip &all', //mr_skipall + 'Co&ntinue' //mr_continue + ); + + zh_modalresulttextnoshortcut: defaultmodalresulttextty = + ('', //mr_none + '', //mr_canclose + '', //mr_windowclosed + '', //mr_windowdestroyed + '', //mr_esc + '', //mr_f10 + '', //mr_exception + #31163#24320, //mr_cancel + #21462#28040, //mr_abort + #30830#23450, //mr_ok + #26159, //mr_yes + #21542, //mr_no + #25152#26377, //mr_all + 'Yes all', //mr_yesall + #21462#28040#25152#26377, //mr_noall + #24573#30053, //mr_ignore + 'Skip', //mr_skip + 'Skip all', //mr_skipall + 'Continue' //mr_continue + ); + + zh_stockcaption: stockcaptionaty = ( + '', //sc_none + #26080#25928, //sc_is_invalid + #26684#24335#38169#35823, //sc_Format_error + #20540#19981#33021#20026#31354, //sc_Value_is_required + #38169#35823, //sc_Error + #26368#23567, //sc_Min + #26368#22823, //sc_Max + #28322#20986#38169#35823, //sc_Range_error + + '&u'#21462#28040, //sc_Undohk /// /// + '&Redo', //sc_Redohk // // + '&c'#22797#21046, //sc_Copyhk // hotkeys // + '&t'#21098#20999, //sc_Cuthk // // + '&p'#31896#36148, //sc_Pastehk // // hotkeys + '&Select all', //sc_Select_allhk /// // + '&I'#25554#20837#19968#34892, //sc_insert_rowhk /// // + '&A'#22686#21152#19968#34892, //sc_append_rowhk // hotkeys // + '&D'#21024#38500#25152#36873#34892, //sc_delete_rowhk /// /// + + '&D'#25991#20214#22841, //sc_Dirhk /// + '&Home', //sc_homehk // + '&U'#21521#19978, //sc_Uphk // + '&N'#26032#25991#20214#22841, //sc_New_dirhk // hotkeys + '&N'#25991#20214#21517, //sc_Namehk // + '&S'#26174#31034#38544#34255#25991#20214, //sc_Show_hidden_fileshk // + '&F'#20445#23384#31867#22411, //sc_Filterhk /// + #20445#23384, //sc_save + 'O'#25171#24320, //sc_open + #21517#31216, //sc_name + #26032#24314#25991#20214#22841, //sc_create_new_directory + 'Back', //sc_back + 'Forward', //sc_forward + 'Up', //sc_up + #25991#20214, //sc_file + #25991#20214#24050#32463#23384#22312#65292#26159#21542#35206#30422#65311, //sc_exists_overwrite + 'is modified. Save?', //sc_is_modified_save + + #35686#21578, //sc_warningupper + #38169#35823, //sc_errorupper + 'Exception', //sc_exception + 'System', //sc_system + #19981#23384#22312, //sc_does_not_exist + 'PASSWORD', //sc_passwordupper + 'Enter password', //sc_enterpassword + 'Invalid password!', //sc_invalidpassword + #25214#19981#21040#25991#20214#22841, //sc_can_not_read_directory + #22270#24418#26684#24335#19981#25903#25345,//sc_graphic_not_supported + #22270#24418#26684#24335#38169#35823, //sc_graphic_format_error + 'MS Bitmap', //sc_MS_Bitmap + 'MS Icon', //sc_MS_Icon + 'JPEG Image', //sc_JPEG_Image + 'PNG Image', //sc_PNG_Image + 'XPM Image', //sc_XPM_Image + 'PNM Image', //sc_PNM_Image + 'TARGA Image', //sc_TARGA_image + 'TIFF Image', //sc_TIFF_image + #25152#26377, //sc_All + #35777#26126, //sc_Confirmation + #21024#38500#35760#24405#65311, //sc_Delete_record_question + 'Copy record?', //sc_Copy_record_question + #20851#38381#39029, //sc_close_page + #31532#19968#26465, //sc_first + #21069#19968#26465, //sc_prior + #19979#19968#26465, //sc_next + #26368#21518, //sc_last + #22686#21152, //sc_append + #21024#38500, //sc_delete + #20462#25913, //sc_edit + #20445#23384, //sc_post + #31163#24320, //sc_cancel + #21047#26032, //sc_refresh + #32534#36753#22120#36807#28388, //sc_filter_filter + 'Edit filter minimum', //sc_edit_filter_min + 'Edit filter maximum', //sc_filter_edit_max + 'Reset filter', //sc_reset_filter + #36807#28388#24320#21551, //sc_filter_on + #26597#25214, //sc_search + 'Auto edit', //sc_autoedit + 'Copy record', //sc_copy_record + 'Dialog', //sc_dialog + #25554#20837, //sc_insert + 'Copy', //sc_copy + 'Paste', //sc_paste + 'Row insert', //sc_row_insert + 'Row append', //sc_row_append + 'Row delete', //sc_row_delete + 'Undo', //sc_undo + 'Redo', //sc_redo + 'Cut', //sc_cut + 'Select all', //sc_select_all + #36807#28388#20851#38381, //sc_filter_off + 'Portrait', //sc_portrait print orientation + 'Landscape', //sc_landscape print orientation + #30830#23450#21024#38500#27492#26465#35760#24405#21527#65311, + //sc_Delete_row_question + #30830#23450#21024#38500#25152#36873#35760#24405#21527#65311, + //sc_selected_rows + 'Single item only', //sc_Single_item_only + 'Copy Cells', //sc_Copy_Cells + 'Paste Cells', //sc_Paste_Cells + 'Close', //sc_close + 'Maximize', //sc_maximize + 'Normalize', //sc_normalize + 'Minimize', //sc_minimize + 'Fix size', //sc_fix_size + 'Float', //sc_float + 'Stay on top', //sc_stay_on_top + 'Stay in background', //sc_stay_in_background + 'Lock children', //sc_lock_children + 'No lock', //sc_no_lock + 'Input', //sc_input + 'Button', //sc_button + 'On', //sc_on + 'Off', //sc_off + 'Left border', //sc_leftborder + 'Top border', //sc_topborder + 'Right border', //sc_rightborder + 'Bottom border', //sc_bottomborder + 'Begin of text', //sc_beginoftext + 'End of text', //sc_endoftext + 'Inputmode', //sc_inputmode + 'Overwrite', //sc_overwrite + 'Deleted', //sc_deleted + 'Copied', //sc_copied + 'Inserted', //sc_inserted + 'Pasted', //sc_pasted + 'Withdrawn', //sc_withdrawn + 'Window activated', //sc_windowactivated + 'Menu', //sc_menu + 'Beginning of file', //sc_bof + 'End of file', //sc_eof + 'Voice output', //sc_voiceoutput + 'Speak again', //sc_speakagain + 'First column', //sc_firstcol + 'First row', //sc_firstrow + 'Last column', //sc_lastcol + 'Last row', //sc_lastrow + 'Selection', //sc_selection + 'Speak path', //sc_speakpath + 'Disabled button', //sc_disabledbutton + 'First field', //sc_firstfield + 'Last field', //sc_lastfield + 'First element', //sc_firstelement + 'Last element', //sc_lastelement + 'Slower', //sc_slower + 'Faster', //sc_faster + 'Window', //sc_window + 'Area', //sc_area + 'Area activated', //sc_areaactivated + 'Volume down', //sc_volumedown + 'Volume up', //sc_volumeup + 'Cancel speech' //sc_cancelspeech +); + +function delete_n_selected_rows(const params: array of const): msestring; +begin + with params[0] do begin + if vinteger = 1 then begin + result:= #30830#23450#21024#38500#27492#26465#35760#24405#21527#65311 + end + else begin + result:= #30830#23450#21024#38500#25152#36873#25321#30340' '+ + inttostrmse(vinteger)+' '#34892#35760#24405#21527#65311; + end; + end; +end; + +const + zh_textgenerator: defaultgeneratortextty = ( + {$ifdef FPC}@{$endif}delete_n_selected_rows //tg_delete_n_selected_rows + ); +initialization + registerlangconsts(langnames[la_zh],@zh_stockcaption,@zh_modalresulttext, + @zh_modalresulttextnoshortcut,@zh_textgenerator); +end. diff --git a/mseide-msegui/lib/common/kernel/msectypes.pas b/mseide-msegui/lib/common/kernel/msectypes.pas new file mode 100644 index 0000000..0f89825 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msectypes.pas @@ -0,0 +1,117 @@ +unit msectypes; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef FPC} + {$ifndef mswindows} +uses + msetypes; //for uint64 in kylix + {$endif} +{$endif} +//todo: win64 +type +// from bits/types.h + __S8_TYPE = shortint; + __U8_TYPE = byte; + __S16_TYPE = smallint; + __U16_TYPE = word; + __S32_TYPE = longint; + __U32_TYPE = longword; + __S64_TYPE = int64; + __U64_TYPE = uint64; + +{$ifndef CPU64} + __ULONGLONGWORD_TYPE = uint64; + __SLONGLONGWORD_TYPE = int64; + __SLONGWORD_TYPE = longint; + __ULONGWORD_TYPE = longword; + __SQUAD_TYPE = int64; + __UQUAD_TYPE = uint64; + __SWORD_TYPE = integer; + __UWORD_TYPE = longword; + __SLONG32_TYPE = integer; + __ULONG32_TYPE = longword; +{$else} + __ULONGLONGWORD_TYPE = uint64; + __SLONGLONGWORD_TYPE = int64; + __SLONGWORD_TYPE = int64; + __ULONGWORD_TYPE = uint64; + __SQUAD_TYPE = int64; + __UQUAD_TYPE = uint64; + __SWORD_TYPE = int64; + __UWORD_TYPE = uint64; + __SLONG32_TYPE = integer; + __ULONG32_TYPE = longword; +{$endif} + + cchar = char; + pcchar = ^cchar; + ppcchar = ^pcchar; + cuchar = byte; + pcuchar = ^cuchar; + ppcuchar = ^pcuchar; + culonglong = __ULONGLONGWORD_TYPE; + clonglong = __SLONGLONGWORD_TYPE; + culong = __ULONGWORD_TYPE; + pculong = ^culong; + clong = __SLONGWORD_TYPE; + pclong = ^clong; + cint = __S32_TYPE; + pcint = ^cint; + cuint = __U32_TYPE; + pcuint = ^cuint; + cshort = __S16_TYPE; + csshort = __S16_TYPE; + pcshort = ^cshort; + cushort = __U16_TYPE; + pcushort = ^cushort; + cint8 = __S8_TYPE; + pcint8 = ^cint8; + cuint8 = __U8_TYPE; + pcuint8 = ^cuint8; + cint16 = __S16_TYPE; + pcint16 = ^cint16; + cuint16 = __U16_TYPE; + pcuint16 = ^cuint16; + cint32 = __S32_TYPE; + pcint32 = ^cint32; + cuint32 = __U32_TYPE; + pcuint32 = ^cuint32; + cint64 = __SQUAD_TYPE; + pcint64 = ^cint64; + cuint64 = __UQUAD_TYPE; + pucint64 = ^cuint64; + + cbool = cint; + pcbool = pcint; + + cfloat = single; + pcfloat = ^cfloat; + cdouble = double; + pcdouble = ^cdouble; + + cenum = cint; + + wchar_t = cint32; + pwchar_t = ^wchar_t; + +{$ifdef cpu64} + size_t = cuint64; + off_t = cuint64; + ssize_t = cint64; + clock_t = cuint64; + time_t = cint64; +{$else} + size_t = cuint32; + off_t = cuint32; + ssize_t = cint32; + clock_t = culong; + time_t = clong; +{$endif} + psize_t = ^size_t; + poff_t = ^off_t; + pssize_t = ^ssize_t; + pclock_t = ^clock_t; + ptime_t = ^time_t; + +implementation +end. diff --git a/mseide-msegui/lib/common/kernel/msedatamodules.pas b/mseide-msegui/lib/common/kernel/msedatamodules.pas new file mode 100644 index 0000000..1dbecf7 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msedatamodules.pas @@ -0,0 +1,511 @@ +{ MSEgui Copyright (c) 1999-2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msedatamodules; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + classes,mclasses,mseclasses,msetypes,msegraphutils,msestatfile,mseevent,mseapplication; + +type + datamoduleoptionty = (dmo_autoreadstat,dmo_delayedreadstat, + dmo_autowritestat,dmo_iconic); + datamoduleoptionsty = set of datamoduleoptionty; +const + defaultdatamoduleoptions = [dmo_autoreadstat,dmo_autowritestat]; + +type + tmsedatamodule = class(tactcomponent) + private + fsize: sizety; + foncreate: notifyeventty; + foncreated: notifyeventty; + fondestroy: notifyeventty; + fondestroyed: notifyeventty; + foptions: datamoduleoptionsty; + fstatfile: tstatfile; + fonloaded: notifyeventty; + fonasyncevent: asynceventeventty; + foneventloopstart: notifyeventty; + fonevent: eventeventty; + fonterminatequery: terminatequeryeventty; + fonterminated: notifyeventty; +// procedure writesize(writer: twriter); + fonidle: idleeventty; + factivatortarget: tactivator; + fonapplicationevent: applicationeventeventty; + procedure readsize(reader: treader); + { + procedure readsize_x(reader: treader); + procedure writesize_x(writer: twriter); + procedure readsize_y(reader: treader); + procedure writesize_y(writer: twriter); + } + procedure setstatfile(const avalue: tstatfile); + function getbounds_x: integer; + procedure setbounds_x(const avalue: integer); + function getbounds_y: integer; + procedure setbounds_y(const avalue: integer); + procedure setbounds_cx(const avalue: integer); + procedure setbounds_cy(const avalue: integer); + procedure setsize(const avalue: sizety); + procedure setoptions(const avalue: datamoduleoptionsty); + procedure setactivatortarget(const avalue: tactivator); + procedure setonapplicationeventty(const avalue: applicationeventeventty); + protected + procedure boundschanged; + procedure doterminated(const sender: tobject); + procedure doterminatequery(var terminate: boolean); + procedure getchildren(proc: tgetchildproc; + root: tcomponent); override; + class function getmoduleclassname: string; override; + class function hasresource: boolean; override; + procedure defineproperties(filer: tfiler); override; + procedure dooncreate; virtual; + procedure readstate(reader: treader); override; + procedure doafterload; override; + procedure autoreadstat; + procedure loaded; override; + procedure doasyncevent(var atag: integer); override; + procedure doeventloopstart; virtual; + procedure doidle(var again: boolean); virtual; + procedure receiveevent(const event: tobjectevent); override; + procedure doapplicationevent(var aevent: tmseevent; + var handled: boolean) virtual; + public + constructor create(aowner: tcomponent); overload; override; + constructor create(aowner: tcomponent; load: boolean); reintroduce; overload; + destructor destroy; override; + procedure afterconstruction; override; + procedure reload; + function hasparent: boolean; override; + function getparentcomponent: tcomponent; override; + procedure beforedestruction; override; + procedure freeinstance override; + property size: sizety read fsize write setsize; + published + property activatortarget: tactivator read factivatortarget + write setactivatortarget; + property options: datamoduleoptionsty read foptions write setoptions + default defaultdatamoduleoptions; + property bounds_x: integer read getbounds_x write setbounds_x stored false; + property bounds_y: integer read getbounds_y write setbounds_y stored false; + property bounds_cx: integer read fsize.cx write setbounds_cx; + property bounds_cy: integer read fsize.cy write setbounds_cy; + + property statfile: tstatfile read fstatfile write setstatfile; + property oncreate: notifyeventty read foncreate write foncreate; + property oncreated: notifyeventty read foncreated write foncreated; + property onloaded: notifyeventty read fonloaded write fonloaded; + property oneventloopstart: notifyeventty read foneventloopstart + write foneventloopstart; + property ondestroy: notifyeventty read fondestroy write fondestroy; + property ondestroyed: notifyeventty read fondestroyed write fondestroyed; + property onevent: eventeventty read fonevent write fonevent; + property onasyncevent: asynceventeventty read fonasyncevent write fonasyncevent; + property onterminatequery: terminatequeryeventty read fonterminatequery + write fonterminatequery; + property onterminated: notifyeventty read fonterminated + write fonterminated; + property onidle: idleeventty read fonidle write fonidle; + property onapplicationevent: applicationeventeventty + read fonapplicationevent write setonapplicationeventty; + end; + datamoduleclassty = class of tmsedatamodule; + msedatamodulearty = array of tmsedatamodule; + +function createmsedatamodule(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; +implementation +uses + sysutils; + +type + tmsecomponent1 = class(tmsecomponent); + +function createmsedatamodule(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; +begin + result:= datamoduleclassty(aclass).create(nil,false); + tmsecomponent1(result).factualclassname:= aclassname; +end; + +{ tmsedatamodule } + +constructor tmsedatamodule.create(aowner: tcomponent); +begin + create(aowner,not (cs_noload in fmsecomponentstate)); +end; + +constructor tmsedatamodule.create(aowner: tcomponent; load: boolean); +begin + foptions:= defaultdatamoduleoptions; + include(fmsecomponentstate,cs_ismodule); + designinfo:= 100+(100 shl 16); + inherited create(aowner); + application.registeronterminated({$ifdef FPC}@{$endif}doterminated); + application.registeronterminate({$ifdef FPC}@{$endif}doterminatequery); + application.registeronidle({$ifdef FPC}@{$endif}doidle); + if load and not (csdesigning in componentstate) then begin + loadmsemodule(self,tmsedatamodule); + end; + if not (acs_dooncreatecalled in factstate) then begin + dooncreate; + end; +// autoreadstat; + if not load then begin + doafterload; + end; +end; + +destructor tmsedatamodule.destroy; +var + bo1: boolean; +begin + application.unregisteronterminated({$ifdef FPC}@{$endif}doterminated); + application.unregisteronterminate({$ifdef FPC}@{$endif}doterminatequery); + application.unregisteronidle({$ifdef FPC}@{$endif}doidle); + if not (csdesigning in componentstate) and + assigned(fonapplicationevent) then begin + application.unregisterapplicationeventhandler(@doapplicationevent); + end; + bo1:= csdesigning in componentstate; + inherited; //csdesigningflag is removed + if not bo1 and candestroyevent(tmethod(fondestroyed)) then begin + fondestroyed(self); + end; +end; + +procedure tmsedatamodule.afterconstruction; +begin + inherited; + if assigned(foncreated) then begin + foncreated(self); + end; +end; + +procedure tmsedatamodule.beforedestruction; +begin + if (fstatfile <> nil) and (dmo_autowritestat in foptions) and + not (csdesigning in componentstate) then begin + fstatfile.writestat; + end; + inherited; + if candestroyevent(tmethod(fondestroy)) then begin + fondestroy(self); + end; +end; + +procedure tmsedatamodule.reload; +begin + name:= ''; + reloadmsecomponent(self); +// doafterload; +end; + +procedure tmsedatamodule.dooncreate; +begin + if not (cs_inheritedloading in msecomponentstate) then begin + include(factstate,acs_dooncreatecalled); + if assigned(foncreate) then begin //csloading possibly set + foncreate(self); + end; + end; +end; + +procedure tmsedatamodule.doafterload; +begin + inherited; +// if (fstatfile <> nil) and +// (foptions*[dmo_autoreadstat,dmo_delayedreadstat] = +// [dmo_autoreadstat]) then begin +// fstatfile.readstat; +// end; + autoreadstat; + if canevent(tmethod(fonloaded)) then begin + fonloaded(self); + end; +end; + +procedure tmsedatamodule.loaded; +begin + if (factivatortarget <> nil) and not (csdesigning in componentstate) then begin + factivatortarget.activaterecursive; + end; + inherited; + application.postevent(tobjectevent.create(ek_loaded,ievent(self))); +end; + +procedure tmsedatamodule.freeinstance; +begin + if (factivatortarget <> nil) and not (csdesigning in componentstate) then begin + try + factivatortarget.deactivaterecursive; + finally + inherited; + end; + end + else begin + inherited; + end; +end; + +procedure tmsedatamodule.readstate(reader: treader); +begin + inherited; + if not (acs_dooncreatecalled in factstate) then begin + dooncreate; + end; +end; + +function tmsedatamodule.getparentcomponent: tcomponent; +begin + result:= owner; +end; + +function tmsedatamodule.hasparent: boolean; +begin + result:= getparentcomponent <> nil; +end; + +procedure tmsedatamodule.getchildren(proc: tgetchildproc; root: tcomponent); +var + int1: integer; + comp1: tcomponent; +begin + if root = self then begin + for int1:= 0 to componentcount - 1 do begin + comp1:= components[int1]; + if not (cssubcomponent in comp1.componentstyle) and + (comp1.getparentcomponent = self) then begin + proc(comp1); + end; + end; + for int1:= 0 to componentcount - 1 do begin + comp1:= components[int1]; + if not (cssubcomponent in comp1.componentstyle) and + not comp1.hasparent then begin + proc(comp1); + end; + end; + end; +end; + +class function tmsedatamodule.getmoduleclassname: string; +begin +// result:= tmsedatamodule.ClassName; + //bug in dcc32: tmsedatamodule is replaced by self + result:= 'tmsedatamodule'; +end; + +class function tmsedatamodule.hasresource: boolean; +begin + result:= self <> tmsedatamodule; +end; +{ +procedure tmsedatamodule.writesize(writer: twriter); +begin + with writer do begin + writelistbegin; + writeinteger(fsize.cx); + writeinteger(fsize.cy); + writelistend; + end; +end; +} +procedure tmsedatamodule.readsize(reader: treader); +begin + with reader do begin + readlistbegin; + fsize.cx:= readinteger; + fsize.cy:= readinteger; + readlistend; + end; +end; + +procedure tmsedatamodule.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('size',{$ifdef FPC}@{$endif}readsize,nil,false); +end; + +procedure tmsedatamodule.setstatfile(const avalue: tstatfile); +begin + setlinkedvar(avalue,tmsecomponent(fstatfile)); +end; + +procedure tmsedatamodule.doasyncevent(var atag: integer); +begin + if canevent(tmethod(fonasyncevent)) then begin + fonasyncevent(self,atag); + end; + inherited; +end; + +procedure tmsedatamodule.doeventloopstart; +begin + if (fstatfile <> nil) and not (csdesigning in componentstate) and + (foptions*[dmo_autoreadstat,dmo_delayedreadstat] = + [dmo_autoreadstat,dmo_delayedreadstat]) then begin + fstatfile.readstat; + end; + if canevent(tmethod(foneventloopstart)) then begin + foneventloopstart(self); + end; +end; + +procedure tmsedatamodule.doidle(var again: boolean); +begin + if canevent(tmethod(fonidle)) then begin + fonidle(again); + end; +end; + +procedure tmsedatamodule.receiveevent(const event: tobjectevent); +begin + if canevent(tmethod(fonevent)) then begin + fonevent(self,event); + end; + inherited; + if event.kind = ek_loaded then begin + doeventloopstart; + end; +end; + +procedure tmsedatamodule.doapplicationevent(var aevent: tmseevent; + var handled: boolean); +begin + if assigned(fonapplicationevent) then begin + fonapplicationevent(self,aevent,handled); + end; +end; + +procedure tmsedatamodule.doterminated(const sender: tobject); +begin + if canevent(tmethod(fonterminated)) then begin + fonterminated(sender); + end; +end; + +procedure tmsedatamodule.doterminatequery(var terminate: boolean); +begin + if canevent(tmethod(fonterminatequery)) then begin + fonterminatequery(terminate); + end; +end; + +procedure tmsedatamodule.boundschanged; +begin + designchanged; +end; + +function tmsedatamodule.getbounds_x: integer; +begin + result:= longrec(designinfo).lo; +end; + +procedure tmsedatamodule.setbounds_x(const avalue: integer); +var + rec: longrec; +begin + rec:= longrec(designinfo); + if rec.lo <> avalue then begin + rec.lo:= avalue; + designinfo:= longint(rec); + boundschanged; + end; +end; + +function tmsedatamodule.getbounds_y: integer; +begin + result:= longrec(designinfo).hi; +end; + +procedure tmsedatamodule.setbounds_y(const avalue: integer); +var + rec: longrec; +begin + rec:= longrec(designinfo); + if rec.hi <> avalue then begin + rec.hi:= avalue; + designinfo:= longint(rec); + boundschanged; + end; +end; + +procedure tmsedatamodule.setbounds_cx(const avalue: integer); +begin + if fsize.cx <> avalue then begin + fsize.cx:= avalue; + boundschanged; + end; +end; + +procedure tmsedatamodule.setbounds_cy(const avalue: integer); +begin + if fsize.cy <> avalue then begin + fsize.cy:= avalue; + boundschanged; + end; +end; + +procedure tmsedatamodule.setsize(const avalue: sizety); +begin + if (fsize.cx <> avalue.cx) or (fsize.cy <> avalue.cy) then begin + fsize:= avalue; + boundschanged; + end; +end; + +procedure tmsedatamodule.setoptions(const avalue: datamoduleoptionsty); +var + optionsbefore: datamoduleoptionsty; +begin + optionsbefore:= foptions; + foptions:= avalue; + if (dmo_iconic in avalue) xor (dmo_iconic in optionsbefore) then begin + boundschanged; + end; +end; + +procedure tmsedatamodule.autoreadstat; +begin + if (fstatfile <> nil) and not (csdesigning in componentstate) and + (foptions*[dmo_autoreadstat,dmo_delayedreadstat] = + [dmo_autoreadstat]) then begin + fstatfile.readstat; + end; +end; + +procedure tmsedatamodule.setactivatortarget(const avalue: tactivator); +begin + setlinkedvar(avalue,tmsecomponent(factivatortarget)); +end; + +procedure tmsedatamodule.setonapplicationeventty( + const avalue: applicationeventeventty); +begin + if not (csdesigning in componentstate) then begin + if assigned(avalue) then begin + if not assigned(fonapplicationevent) then begin + application.registerapplicationeventhandler(@doapplicationevent); + end; + end + else begin + if assigned(fonapplicationevent) then begin + application.unregisterapplicationeventhandler(@doapplicationevent); + end; + end; + end; + fonapplicationevent:= avalue; +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/msedate.pas b/mseide-msegui/lib/common/kernel/msedate.pas new file mode 100644 index 0000000..efc64b2 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msedate.pas @@ -0,0 +1,84 @@ +{ MSEgui Copyright (c) 1999-2006 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msedate; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +const + unidatetimeoffset = -25569; + +function nowutc: tdatetime; +function nowlocal: tdatetime; +function maxdays(year: word; month: word): word; +function utctolocaltime(const value: tdatetime): tdatetime; +function localtimetoutc(const value: tdatetime): tdatetime; +function unixtodatetime(const value: longword): tdatetime; + +implementation +uses + msesysintf1,msesysintf; + +function nowutc: tdatetime; +begin + result:= sys_getutctime; +end; + +function nowlocal: tdatetime; +begin + result:= sys_getlocaltime; +end; + +function utctolocaltime(const value: tdatetime): tdatetime; +begin + result:= sys_utctolocaltime(value); +// result:= value + sys_localtimeoffset; +end; + +function localtimetoutc(const value: tdatetime): tdatetime; +begin + result:= sys_localtimetoutc(value); +// result:= value - sys_localtimeoffset; +end; + +function unixtodatetime(const value: longword): tdatetime; +begin + result:= value/(24.0*60*60) - unidatetimeoffset; +end; + +function maxdays(year: word; month: word): word; +begin + if month = 0 then begin + year:= year - 1; + month:= 12; + end; + if month = 14 then begin + year:= year + 1; + month:= 1; + end; + if month = 13 then begin + month:= 12; + end; + case month of + 1,3,5,7,8,10,12: + result:= 31; + 2: begin + if (year mod 4 = 0) and (not (year mod 100 = 0) or (year mod 400 = 0)) then + result:= 29 + else + result:= 28; + end; + else + result:= 30; + end; +end; + + +end. diff --git a/mseide-msegui/lib/common/kernel/msedrag.pas b/mseide-msegui/lib/common/kernel/msedrag.pas new file mode 100644 index 0000000..eb04868 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msedrag.pas @@ -0,0 +1,578 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msedrag; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface +uses + msegraphutils,mseevent,classes,mseclasses,mseglob,mseguiglob,msedragglob, + msegui,msetimer; +type + idragcontroller = interface(inullinterface) + function getwidget: twidget; + function getdragrect(const apos: pointty): rectty; + end; + +type + drageventty = procedure(const asender: tobject; const apos: pointty; + var adragobject: tdragobject; var processed: boolean) of object; + dragovereventty = procedure(const asender: tobject; const apos: pointty; + var adragobject: tdragobject; var accept: boolean; + var processed: boolean) of object; + dragendeventty = procedure(const asender: tobject; const apos: pointty; + var adragobject: tdragobject; const accepted: boolean; + var processed: boolean) of object; + + ttagdragobject = class(tdragobject) + private + protected + ftag: integer; + public + constructor create(const asender: tobject; var instance: tdragobject; + const apickpos: pointty; const tag: integer); + function tag: integer; + end; + + tobjectdragobject = class(tdragobject) + private + protected + fdata: tobject; + public + constructor create(const asender: tobject; var instance: tdragobject; + const apickpos: pointty; const dataobject: tobject); + property data: tobject read fdata; + end; + + tstringdragobject = class(tdragobject) + public + data: string; + end; + + dragstatety = (ds_clicked,ds_beginchecked,ds_cursorshapechanged, + ds_haddragobject); + dragstatesty = set of dragstatety; + +const + dragstates = [ds_clicked,ds_beginchecked,ds_haddragobject]; + sdndexpiretime = 5000000; //5s + dragmindist = 4; + +type + drageventsty = record + dragbegin: drageventty; + dragover: dragovereventty; + dragdrop: drageventty; + dragend: dragendeventty; + end; + + sysdndinfoty = record + dragobj: tdragobject; +// expiretime: longword; + end; + + dragoptionty = (do_child,do_nocursorshape,do_nearstart,do_mousewidget); + dragoptionsty = set of dragoptionty; + + tcustomdragcontroller = class(tlinkedpersistent,ievent) + private + ftimer: tsimpletimer; + foptions: dragoptionsty; + procedure initdraginfo(var info: draginfoty; + const eventkind: drageventkindty; const pos: pointty); + function checkcandragdrop(const pos: pointty; + out sysdndpending: boolean): twidget; + protected + fpickpos: pointty; + fpickrect: rectty; + fdragobject: tdragobject; + fstate: dragstatesty; + fintf: idragcontroller; + fsysdndobjects: array[0..3] of sysdndinfoty; + flastwidget: twidget; + procedure dokeypress(const sender: twidget; var info: keyeventinfoty) + virtual; + procedure doexpiresdnd(const sender: tobject); + function checkclickstate(const info: mouseeventinfoty): boolean; virtual; + function checksysdnd(const aaction: sysdndactionty; + const arect: rectty): boolean; virtual; + function canbegindrag: boolean; virtual; + //ievent + procedure receiveevent(const aevent: tobjectevent); virtual; + public + constructor create(const aintf: idragcontroller); reintroduce; + destructor destroy; override; + function active: boolean; + procedure enddrag; virtual; + procedure mouseevent(var info: mouseeventinfoty); virtual; + procedure clientmouseevent(var info: mouseeventinfoty); virtual; + procedure childormouseevent(const sender: twidget; + var info: mouseeventinfoty); virtual; + function beforedragevent(var info: draginfoty): boolean; virtual; abstract; + //true if processed + function afterdragevent(var info: draginfoty): boolean; virtual; abstract; + //true if processed + property pickpos: pointty read fpickpos; //clientorigin + property options: dragoptionsty read foptions + write foptions default []; + end; + + tdragcontroller = class(tcustomdragcontroller) + private + fonbefore,fonafter: drageventsty; + function dodragevent(const events: drageventsty; + var info: draginfoty): boolean; + public + function beforedragevent(var info: draginfoty): boolean; override; + //true if processed + function afterdragevent(var info: draginfoty): boolean; override; + //true if processed + published + property onbeforedragbegin: drageventty read fonbefore.dragbegin + write fonbefore.dragbegin; + property onbeforedragover: dragovereventty read fonbefore.dragover + write fonbefore.dragover; + property onbeforedragdrop: drageventty read fonbefore.dragdrop + write fonbefore.dragdrop; + property onbeforedragend: dragendeventty read fonbefore.dragend + write fonbefore.dragend; + property onafterdragbegin: drageventty read fonafter.dragbegin + write fonafter.dragbegin; + property onafterdragover: dragovereventty read fonafter.dragover + write fonafter.dragover; + property onafterdragdrop: drageventty read fonafter.dragdrop + write fonafter.dragdrop; + property onafterdragend: dragendeventty read fonafter.dragend + write fonafter.dragend; + property options; + end; + +function isobjectdrag(const dragobject: tdragobject; + objectclass: tclass): boolean; + +implementation +uses + msebits,msepointer,msekeyboard,msesysdnd,sysutils,msesysutils, + mseguiintf; +type +// tguiapplication1 = class(tguiapplication); + tdragobject1 = class(tdragobject); + +function isobjectdrag(const dragobject: tdragobject; + objectclass: tclass): boolean; +begin + result:= (dragobject is tobjectdragobject) and + (tobjectdragobject(dragobject).fdata is objectclass); +end; + +{ tcustomdragcontroller } + +constructor tcustomdragcontroller.create(const aintf: idragcontroller); +begin + fintf:= aintf; +end; + +destructor tcustomdragcontroller.destroy; +var + int1: integer; +begin + enddrag; + ftimer.free; + for int1:= 0 to high(fsysdndobjects) do begin + freeandnil(fsysdndobjects[int1]); + end; + inherited; +end; + +function tcustomdragcontroller.active: boolean; +begin + result:= ds_clicked in fstate; +end; + +procedure tcustomdragcontroller.doexpiresdnd(const sender: tobject); +var + int1: integer; +begin + for int1:= low(fsysdndobjects) to high(fsysdndobjects) do begin + freeandnil(fsysdndobjects[int1].dragobj); + end; + freeandnil(ftimer); +end; + +procedure tcustomdragcontroller.enddrag; +var + int1,int2: integer; + draginfo: draginfoty; + owner: twidget; + po1: pointty; +begin +// checksysdnd(sdnda_finished,nullrect); + if fdragobject <> nil then begin + owner:= fintf.getwidget(); + if dos_dropped in fdragobject.state then begin + po1:= translateclientpoint(fdragobject.droppos,nil,owner); + end + else begin + po1:= fdragobject.pickpos; + end; + initdraginfo(draginfo,dek_end,po1); + owner.dragevent(draginfo); + if dos_sysdroppending in tdragobject1(fdragobject).fstate then begin + int2:= 0; + for int1:= 0 to high(fsysdndobjects) do begin + if fsysdndobjects[int1].dragobj = nil then begin + int2:= int1; + break; + end; + end; + with fsysdndobjects[int2] do begin + if dragobj <> nil then begin + dragobj.destroy; + end; + tdragobject1(fdragobject).finstancepo:= @dragobj; + dragobj:= fdragobject; + if ftimer = nil then begin + ftimer:= tsimpletimer.create(sdndexpiretime,{$ifdef FPC}@{$endif}doexpiresdnd, + true,[to_single]); + end + else begin + ftimer.interval:= sdndexpiretime; + end; + end; + fdragobject:= nil; + end + else begin + fdragobject.free; + end; + end; + if ds_haddragobject in fstate then begin + if not (do_nocursorshape in foptions) then begin + application.cursorshape:= cr_default; + end; + end; + application.unregisteronkeypress(@dokeypress); + fstate:= fstate - dragstates; +end; + +procedure tcustomdragcontroller.dokeypress(const sender: twidget; + var info: keyeventinfoty); +begin + if active and (info.key = key_escape) then begin + enddrag; + include(info.eventstate,es_processed); + end; +end; + +function tcustomdragcontroller.checkcandragdrop(const pos: pointty; + out sysdndpending: boolean): twidget; +var + window: twindow; + pt1: pointty; + info: draginfoty; +begin + result:= nil; + window:= nil; + pt1:= translateclientpoint(pos,fintf.getwidget,nil); + if do_mousewidget in foptions then begin + result:= application.mousewidget; + if result <> nil then begin + window:= result.window; + end; + end + else begin + window:= application.windowatpos(pt1); + if window <> nil then begin + result:= window.owner.widgetatpos(translatewidgetpoint(pt1,nil,window.owner), + [ws_visible,ws_enabled]); + end; + end; + if window <> nil then begin + sysdndpending:= false; + if (flastwidget <> result) then begin + if (flastwidget <> nil) then begin + initdraginfo(info,dek_leavewidget, + translateclientpoint(pt1,nil,flastwidget)); + flastwidget.dragevent(info); + end; + setlinkedvar(result,tmsecomponent(flastwidget)); + end; + if result <> nil then begin + initdraginfo(info,dek_check,translateclientpoint(pt1,nil,result)); + result.dragevent(info); + if not info.accept then begin + result:= nil; + end; + end + end + else begin + sysdndpending:= checksysdnd(sdnda_check,mr(pt1,nullsize)); + end; +end; + +procedure tcustomdragcontroller.initdraginfo(var info: draginfoty; + const eventkind: drageventkindty; const pos: pointty); +begin + fillchar(info,sizeof(info),0); + info.eventkind:= eventkind; + info.pos:= pos; + info.clientpickpos:= fpickpos; + info.pickpos:= translateclientpoint(fpickpos,fintf.getwidget,nil); + info.dragobjectpo:= @fdragobject; + if (eventkind = dek_drop) and (fdragobject <> nil) then begin + include(tdragobject1(fdragobject).fstate,dos_dropped); + end; +end; + +function tcustomdragcontroller.checkclickstate( + const info: mouseeventinfoty): boolean; +begin + result:= info.shiftstate - [ss_left] = []; +end; + +procedure tcustomdragcontroller.clientmouseevent(var info: mouseeventinfoty); +var + owner: twidget; + widget1: twidget; + draginfo: draginfoty; + bo1: boolean; +begin + owner:= fintf.getwidget; + case info.eventkind of + {ek_clientmouseleave,ek_mouseleave}ek_mousecaptureend: begin + enddrag; + end; + ek_buttonpress: begin + if checkclickstate(info) then begin + fpickpos:= info.pos; + if do_nearstart in foptions then begin + fpickrect.x:= info.pos.x - dragmindist; + fpickrect.y:= info.pos.y - dragmindist; + fpickrect.cx:= 2 * dragmindist; + fpickrect.cy:= 2 * dragmindist; + end + else begin + fpickrect:= fintf.getdragrect(fpickpos); + end; + include(fstate,ds_clicked); + end; + end; + ek_buttonrelease: begin + try + if fdragobject <> nil then begin + fdragobject.droppos:= translateclientpoint(info.pos,owner,nil); + include(info.eventstate,es_processed); + widget1:= checkcandragdrop(info.pos,bo1); + if widget1 <> nil then begin + initdraginfo(draginfo,dek_drop, + translateclientpoint(info.pos,owner,widget1)); + widget1.dragevent(draginfo); + end + else begin + if bo1 then begin + include(tdragobject1(fdragobject).fstate,dos_sysdroppending); + end; + checksysdnd(sdnda_drop,nullrect); + end; + if flastwidget <> nil then begin + initdraginfo(draginfo,dek_leavewidget, + translateclientpoint(info.pos,owner,flastwidget)); + flastwidget.dragevent(draginfo); + setlinkedvar(nil,tmsecomponent(flastwidget)); + end; + end; + finally + enddrag; + end; + end; + ek_mousemove,ek_mousepark: begin + if checkclickstate(info) then begin + if (fstate * [ds_clicked,ds_beginchecked] = [ds_clicked]) and + (fdragobject = nil) and not pointinrect(info.pos,fpickrect) + {(distance(info.pos,fpickpos) > mindragdist)} then begin + include(fstate,ds_beginchecked); + if canbegindrag then begin + application.registeronkeypress({$ifdef FPC}@{$endif}dokeypress); + initdraginfo(draginfo,dek_begin,fpickpos); + owner.dragevent(draginfo); + checksysdnd(sdnda_begin,nullrect); + end; + end; + if (fdragobject <> nil) then begin + include(fstate,ds_haddragobject); + tdragobject1(fdragobject).feventintf:= ievent(self); + include(info.eventstate,es_processed); + if checkcandragdrop(info.pos,bo1) <> nil then begin + if not (do_nocursorshape in foptions) then begin + application.cursorshape:= cr_drag; + end; + fdragobject.acepted(translateclientpoint(info.pos,owner,nil)); + end + else begin + if not bo1 then begin + if not (do_nocursorshape in foptions) then begin + application.cursorshape:= cr_forbidden; + end; + fdragobject.refused(translateclientpoint(info.pos,owner,nil)); + end; + end; + end; + end + else begin + enddrag; + end; + end; + end; + if fdragobject = nil then begin + exclude(info.eventstate,es_drag); + end + else begin + include(info.eventstate,es_drag); + end; +end; + +procedure tcustomdragcontroller.mouseevent(var info: mouseeventinfoty); +var + po1: pointty; +begin + po1:= fintf.getwidget.clientwidgetpos; + subpoint1(info.pos,po1); + clientmouseevent(info); + addpoint1(info.pos,po1); +end; + +function tcustomdragcontroller.checksysdnd(const aaction: sysdndactionty; + const arect: rectty): boolean; +begin + result:= false; + if fdragobject <> nil then begin + result:= tdragobject1(fdragobject).checksysdnd(aaction,arect); + end; +end; + +procedure tcustomdragcontroller.receiveevent(const aevent: tobjectevent); +begin + if (fdragobject <> nil) and (aevent is tsysdndstatusevent) then begin + with tsysdndstatusevent(aevent) do begin + if ds_beginchecked in fstate then begin + if not (do_nocursorshape in foptions) then begin + if accept then begin + application.cursorshape:= cr_drag; + end + else begin + application.cursorshape:= cr_forbidden; + end; + end; + end; + end; + end; +end; + +procedure tcustomdragcontroller.childormouseevent(const sender: twidget; + var info: mouseeventinfoty); +var + widget1: twidget; + pt1: pointty; +begin + if es_child in info.eventstate then begin + widget1:= fintf.getwidget; + if sender <> widget1 then begin + if (do_child in foptions) and + (info.eventkind in [ek_buttonpress,ek_buttonrelease,ek_mousewheel, + ek_mousemove,ek_mousepark]) then begin + pt1:= info.pos; + translatewidgetpoint1(info.pos,sender,widget1); + try + mouseevent(info); + finally + info.pos:= pt1; + end; + end; + end + else begin + mouseevent(info); + end; + end + else begin + mouseevent(info); + end; +end; + +function tcustomdragcontroller.canbegindrag: boolean; +begin + result:= true; +end; + +{ tdragcontroller } + +function tdragcontroller.dodragevent(const events: drageventsty; + var info: draginfoty): boolean; +begin + with events,info do begin + result:= false; + case eventkind of + dek_begin: begin + if assigned(dragbegin) then begin + dragbegin(fintf.getwidget,pos,dragobjectpo^,result); + end; + end; + dek_check: begin + if assigned(dragover) then begin + dragover(fintf.getwidget,pos,dragobjectpo^,accept,result); + end; + end; + dek_drop: begin + if assigned(dragdrop) then begin + dragdrop(fintf.getwidget,pos,dragobjectpo^,result); + end; + end; + dek_end: begin + if assigned(dragend) then begin + dragend(fintf.getwidget,pos,dragobjectpo^,(dragobjectpo^ <> nil) and + (dos_dropped in dragobjectpo^.state),result); + end; + end; + end; + end; +end; + +function tdragcontroller.beforedragevent(var info: draginfoty): boolean; +begin + result:= dodragevent(fonbefore,info); +end; + +function tdragcontroller.afterdragevent(var info: draginfoty): boolean; +begin + result:= dodragevent(fonafter,info); +end; + +{ tobjectdragobject } + +constructor tobjectdragobject.create(const asender: tobject; + var instance: tdragobject; const apickpos: pointty; const dataobject: tobject); +begin + fdata:= dataobject; + inherited create(asender,instance,apickpos); +end; + +{ ttagdragobject } + +constructor ttagdragobject.create(const asender: tobject; + var instance: tdragobject; const apickpos: pointty; const tag: integer); +begin + ftag:= tag; + inherited create(asender,instance,apickpos); +end; + +function ttagdragobject.tag: integer; +begin + result:= ftag; +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/msedynload.pas b/mseide-msegui/lib/common/kernel/msedynload.pas new file mode 100644 index 0000000..e4ec1d8 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msedynload.pas @@ -0,0 +1,492 @@ +unit msedynload; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msesystypes,{$ifdef FPC}dynlibs,{$endif}{msestrings,}sysutils,msetypes{,msesys}; + +{$ifndef cpuarm}{$define set8087cw}{$endif} + +type + funcinfoty = record + n: string; //name + d: ppointer; //destination + end; + dynlibinfoty = record + libhandle: tlibhandle; + libname: filenamety; + refcount: integer; + inithooks: pointerarty; //array of dynlibprocty + deinithooks: pointerarty; //array of dynlibprocty + cw8087: word; //fpu control word after lib load + end; + dynlibprocty = procedure(const dynlib: dynlibinfoty); + dynloadcallbackty = procedure(const data: pointer); + + edynload = class(ecrashstatfile) + end; + +procedure initializelibinfo(var info: dynlibinfoty); +procedure finalizelibinfo(var info: dynlibinfoty); + +function initializedynlib(var info: dynlibinfoty; + const libnames: array of filenamety; + const libnamesdefault: array of filenamety; + const funcs: array of funcinfoty; + const funcsopt: array of funcinfoty; + const errormessage: msestring = ''; + const callback: dynloadcallbackty = nil; + const noexception: boolean = false; + const callbackdata: pointer = nil): boolean; + //called after lib load + //returns true if all funcsopt found +procedure releasedynlib(var info: dynlibinfoty; + const callback: dynloadcallbackty = nil; + const nodlunload: boolean = false; + const callbackdata: pointer = nil); + //called before lib unload +procedure regdynlibinit(var info: dynlibinfoty; const initproc: dynlibprocty); +procedure regdynlibdeinit(var info: dynlibinfoty; const initproc: dynlibprocty); + +procedure dynloadlock; +procedure dynloadunlock; + +function loadlib(const libnames: array of filenamety; out libname: filenamety; + const errormessage: msestring = ''; + const noexception: boolean = false): tlibhandle; + +function getprocaddresses(const lib: tlibhandle; + const procedures: array of funcinfoty; + const noexception: boolean = false; + const libname: msestring = ''): boolean; overload; +function getprocaddresses(const lib: tlibhandle; const anames: array of string; + const adest: array of ppointer; + const noexception: boolean = false; + const libname: msestring = ''): boolean; overload; +function getprocaddresses(const libinfo: dynlibinfoty; + const procedures: array of funcinfoty; + const noexception: boolean = false): boolean; overload; +function getprocaddresses(const libnames: array of msestring; + const procedures: array of funcinfoty; + const noexception: boolean = false): tlibhandle; overload; +function getprocaddresses(const libinfo: dynlibinfoty; + const anames: array of string; + const adest: array of ppointer; + const noexception: boolean = false): boolean; overload; +function getprocaddresses(const libnames: array of filenamety; + const anames: array of string; + const adest: array of ppointer; + const noexception: boolean = false): tlibhandle; overload; +function checkprocaddresses(const libnames: array of filenamety; + const anames: array of string; + const adest: array of ppointer): boolean; +function checkprocaddresses(const libnames: array of filenamety; + const procedures: array of funcinfoty): boolean; +function quotelibnames(const libnames: array of filenamety): msestring; + +implementation + +uses + msesysintf1{$ifdef linux},dl{$endif},msearrayutils,msestrings; + +function getprocaddresses(const lib: tlibhandle; + const procedures: array of funcinfoty; + const noexception: boolean = false; + const libname: msestring = ''): boolean; overload; +var + int1: integer; + mstr1: msestring; +begin + result:= true; + mstr1:= ''; + for int1:= 0 to high(procedures) do begin + with procedures[int1] do begin + {$ifdef FPC} + d^:= getprocedureaddress(lib,n); + {$else} + d^:= getprocaddress(lib,pansichar(n)); + {$endif} + if (d^ = nil) then begin + result:= false; + if not noexception then begin + if libname <> '' then begin + mstr1:= libname + lineend; + end; + mstr1:= mstr1 + 'Function "'+msestring(n)+'" not found.'; + raise edynload.create(ansistring(mstr1)); + end; + end; + end; + end; +end; + +function getprocaddresses(const lib: tlibhandle; const anames: array of string; + const adest: array of ppointer; + const noexception: boolean = false; + const libname: msestring = ''): boolean; +var + int1: integer; + mstr1: msestring; +begin + if high(anames) <> high(adest) then begin + raise exception.create('Invalid parameter.'); + end; + mstr1:= ''; + result:= true; + for int1:= 0 to high(anames) do begin + adest[int1]^:= getprocaddress(lib,pansichar(anames[int1])); + if (adest[int1]^ = nil) then begin + result:= false; + if not noexception then begin + if libname <> '' then begin + mstr1:= libname + lineend; + end; + mstr1:= mstr1 + 'Function "'+msestring(anames[int1])+'" not found.'; + raise exception.create(ansistring(mstr1)); + end; + end; + end; +end; + +function getprocaddresses(const libinfo: dynlibinfoty; + const procedures: array of funcinfoty; + const noexception: boolean = false): boolean; +begin + with libinfo do begin + result:= getprocaddresses(libhandle,procedures,noexception,libname); + end; +end; + +function getprocaddresses(const libnames: array of msestring; + const procedures: array of funcinfoty; + const noexception: boolean = false): tlibhandle; +var + str1: msestring; +begin + result:= loadlib(libnames,str1,'',noexception); + if result <> 0 then begin + if not getprocaddresses(result,procedures,noexception,str1) then begin + unloadlibrary(result); + result:= 0; + end; + end; +end; + +function getprocaddresses(const libinfo: dynlibinfoty; + const anames: array of string; + const adest: array of ppointer; + const noexception: boolean = false): boolean; overload; +begin + with libinfo do begin + result:= getprocaddresses(libhandle,anames,adest,noexception,libname); + end; +end; + +function loadlib(const libnames: array of filenamety; out libname: filenamety; + const errormessage: msestring = ''; + const noexception: boolean = false): tlibhandle; +var + int1: integer; + s1: string; +{$ifdef linux} + p1: pchar; + ar1: stringarty; +{$endif} +begin + result:= 0; + libname:= ''; +{$ifdef linux} + p1:= nil; +{$endif} + for int1:= 0 to high(libnames) do begin + {$ifdef FPC} + result:= loadlibrary(libnames[int1]); + {$else} + result:= loadlibrary(pansichar(string(libnames[int1]))); + {$endif} + if result <> 0 then begin + libname:= libnames[int1]; + break; + end; + {$ifdef linux} + p1:= dlerror(); + additem(ar1,string(p1)); + {$endif} + end; + if (result = 0) and not noexception then begin + s1:= ansistring(errormessage+ + 'Library '+quotelibnames(libnames)+' not found.'); + {$ifdef linux} + if ar1 <> nil then begin + s1:= s1+lineend+concatstrings(ar1,lineend); + end; + {$endif} + raise exception.create(s1); + end; +end; + +function getprocaddresses(const libnames: array of filenamety; + const anames: array of string; const adest: array of ppointer; + const noexception: boolean = false): tlibhandle; overload; +var + mstr1: filenamety; +begin + result:= loadlib(libnames,mstr1); + getprocaddresses(result,anames,adest,noexception); +end; + +function checkprocaddresses(const libnames: array of filenamety; + const anames: array of string; + const adest: array of ppointer): boolean; +var + int1: integer; +begin + for int1:= 0 to high(adest) do begin + adest[int1]^:= nil; + end; + result:= true; + try + getprocaddresses(libnames,anames,adest,true); + except + result:= false; + exit; + end; + for int1:= 0 to high(adest) do begin + if adest[int1]^ = nil then begin + result:= false; + break; + end; + end; +end; + +function checkprocaddresses(const libnames: array of filenamety; + const procedures: array of funcinfoty): boolean; +var + int1: integer; +begin + for int1:= 0 to high(procedures) do begin + procedures[int1].d^:= nil; + end; + result:= true; + try + getprocaddresses(libnames,procedures,true); + except + result:= false; + exit; + end; + for int1:= 0 to high(procedures) do begin + if procedures[int1].d^ = nil then begin + result:= false; + break; + end; + end; +end; + +function quotelibnames(const libnames: array of filenamety): msestring; +var + int1: integer; +begin + result:= ''; + for int1:= 0 to high(libnames) do begin + result:= result+'"'+libnames[int1]+'",'; + end; + if length(result) > 0 then begin + setlength(result,length(result)-1); + end; +end; + +{$ifndef FPC} +const + nilhandle = 0; + +Function UnloadLibrary(Lib : TLibHandle) : Boolean; +begin + result:= freelibrary(lib); +end; +{$endif} + +var + lock: mutexty; + +function adduniqueitem(var dest: pointerarty; const value: pointer): integer; + //returns index +var + int1: integer; +begin + for int1:= 0 to high(dest) do begin + if dest[int1] = value then begin + result:= int1; + exit; + end; + end; + result:= high(dest) + 1; + setlength(dest,result+1); + dest[result]:= value; +end; + +procedure regdynlibinit(var info: dynlibinfoty; const initproc: dynlibprocty); +begin + sys_mutexlock(lock); + adduniqueitem(info.inithooks,pointer({$ifndef FPC}@{$endif}initproc)); + sys_mutexunlock(lock); +end; + +procedure regdynlibdeinit(var info: dynlibinfoty; const initproc: dynlibprocty); +begin + sys_mutexlock(lock); + adduniqueitem(info.deinithooks,pointer({$ifndef FPC}@{$endif}initproc)); + sys_mutexunlock(lock); +end; + +function initializedynlib(var info: dynlibinfoty; + const libnames: array of filenamety; + const libnamesdefault: array of filenamety; + const funcs: array of funcinfoty; + const funcsopt: array of funcinfoty; + const errormessage: msestring = ''; + const callback: dynloadcallbackty = nil; + const noexception: boolean = false; + const callbackdata: pointer = nil): boolean; + //true if all funcsopt found +var + int1: integer; + {$ifdef set8087cw} + wo1: word; + {$endif} +begin + with info do begin + sys_mutexlock(lock); + try + result:= false; + if refcount = 0 then begin + if (high(libnames) >= 0) or (high(libnamesdefault) >= 0) then begin + {$ifdef set8087cw} + wo1:= get8087cw; + {$endif} + if (high(libnames) >= 0) then begin + libhandle:= loadlib(libnames,libname,errormessage,noexception); + end + else begin + libhandle:= loadlib(libnamesdefault,libname,errormessage,noexception); + end; + if libhandle <> nilhandle then begin + {$ifdef set8087cw} + cw8087:= get8087cw; + set8087cw(wo1); + {$endif} + try + result:= getprocaddresses(libhandle,funcs,noexception); + if not result then begin + if unloadlibrary(libhandle) then begin + libhandle:= nilhandle; + end; + exit; + end; + except + on e: exception do begin + e.message:= ansistring( + errormessage+'Library "'+libname+'": '+msestring(e.message)); + if unloadlibrary(libhandle) then begin + libhandle:= nilhandle; + end; + raise; + end; + end; + result:= getprocaddresses(libhandle,funcsopt,true); + end; + end + else begin + {$ifdef set8087cw} + cw8087:= get8087cw; //refresh + {$endif} + end; + if libhandle <> nilhandle then begin + inc(refcount); + for int1:= 0 to high(inithooks) do begin + dynlibprocty(inithooks[int1])(info); + end; + if ({$ifndef FPC}@{$endif}callback <> nil) then begin + callback(callbackdata); + end; + end; + end + else begin + inc(refcount); + end; + finally + sys_mutexunlock(lock); + end; + end; +end; + +procedure releasedynlib(var info: dynlibinfoty; + const callback: dynloadcallbackty = nil; + const nodlunload: boolean = false; + const callbackdata: pointer = nil); +var + int1: integer; +begin + with info do begin + sys_mutexlock(lock); + try + if refcount > 1 then begin + dec(refcount); + end + else begin + if refcount = 1 then begin //not initialized otherwise + try + if {$ifndef FPC}@{$endif}callback <> nil then begin + callback(callbackdata); + end; + for int1:= 0 to high(deinithooks) do begin + dynlibprocty(deinithooks[int1])(info); + end; + finally + if nodlunload then begin + dec(refcount); + end + else begin + if (libhandle = nilhandle) or unloadlibrary(libhandle) then begin + dec(refcount); + libhandle:= nilhandle; + end; + end; + end; + end; + end; + finally + sys_mutexunlock(lock); + end; + end; +end; + +procedure initializelibinfo(var info: dynlibinfoty); +begin + sys_mutexcreate(lock); + with info do begin + libname:= ''; + refcount:= 0; + libhandle:= 0; + end; +end; + +procedure finalizelibinfo(var info: dynlibinfoty); +begin + with info do begin + end; +end; + +procedure dynloadlock; +begin + sys_mutexlock(lock); +end; + +procedure dynloadunlock; +begin + sys_mutexunlock(lock); +end; + +initialization + sys_mutexcreate(lock); +finalization + sys_mutexdestroy(lock); +end. \ No newline at end of file diff --git a/mseide-msegui/lib/common/kernel/mseerr.pas b/mseide-msegui/lib/common/kernel/mseerr.pas new file mode 100644 index 0000000..13a5f33 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseerr.pas @@ -0,0 +1,61 @@ +{ MSEgui Copyright (c) 1999-2006 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseerr; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +//helpers for errormessages +interface + +uses + SysUtils; + +type + eerror = class(exception) + protected + ferror: integer; + public + text: string; + constructor create(error: integer; atext: string; + const errortexts: array of string); + property error: integer read ferror; + end; + +implementation +uses + msetypes{msestrings}; + +{ eerror } + +constructor eerror.create(error: integer; atext: string; + const errortexts: array of string); +var + ch1: char; +begin + ferror:= error; + text:= atext; + if text = '' then begin + inherited create(errortexts[error]+'.'); + end + else begin + text:= errortexts[error]+ ' ' + text; + ch1:= text[length(text)]; + if (ch1 <> '.') and (ch1 <> c_return) and (ch1 <> c_linefeed) then begin + text:= text + '.'; + end; + inherited create(text); + end; +end; + +end. + + + + + diff --git a/mseide-msegui/lib/common/kernel/mseevent.pas b/mseide-msegui/lib/common/kernel/mseevent.pas new file mode 100644 index 0000000..4fb8cc2 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseevent.pas @@ -0,0 +1,440 @@ +{ MSEgui Copyright (c) 1999-2010 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseevent; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface +uses + mselist,mseglob,msegraphutils,msekeyboard,msetypes,msestrings,msesystypes; + +const +// eta_timer = 1; //tags for userevents + eta_release = 2; + +type + eventkindty = (ek_none,ek_focusin,ek_focusout,ek_checkapplicationactive, + ek_enterwindow,ek_leavewindow, + ek_buttonpress,ek_buttonrelease,ek_mousewheel, + ek_mousemove,ek_mousepark, + ek_mouseenter,ek_mouseleave,ek_mousecaptureend, + ek_clientmouseenter,ek_clientmouseleave, + ek_expose,ek_configure,ek_reparent, + ek_terminate,ek_abort,ek_destroy,ek_show,ek_hide,ek_close, + ek_activate,ek_loaded, + ek_keypress,ek_keyrelease,ek_timer,ek_wakeup, + ek_release,{ek_releasedefer,}ek_closeform,ek_checkscreenrange, + ek_childscaled,ek_resize, + ek_dropdown,ek_async,ek_execute,ek_object,ek_component, + ek_asyncexec,ek_releaseobject, + ek_connect, + ek_dbedit,ek_dbupdaterowdata,ek_data,ek_objectdata,ek_childproc, + ek_dbinsert, //for tdscontroller + ek_sysdnd,ek_sysdndstatus, + ek_mse, + ek_user); +const + mouseregionevents = [ek_mousepark,ek_mouseenter,ek_mouseleave, + ek_mousecaptureend, + ek_clientmouseenter,ek_clientmouseleave]; + mouseposevents = [ek_buttonpress,ek_buttonrelease,ek_mousemove,ek_mousepark]; + waitignoreevents = [ek_keypress,ek_buttonpress,ek_mousewheel]; + +type + eventstatety = (es_processed,es_child,es_parent,es_preview,es_client, + es_transientfor, //mousewheel from upper modal window + es_local,es_broadcast,es_modal,es_drag,es_objectpicking, + es_reflected,es_nofocus,es_designcall); + eventstatesty = set of eventstatety; + + tmseevent = class(tnullinterfacedobject) + private + protected + fkind: eventkindty; + procedure internalfree1; virtual; + public + constructor create(const akind: eventkindty); + property kind: eventkindty read fkind; + procedure free1; //do nothing for ownedevents + end; + + eventarty = array of tmseevent; + eventaty = array[0..0] of tmseevent; + peventaty = ^eventaty; + + tstringevent = class(tmseevent) + private + fdata: ansistring; + public + constructor create(const adata: string); + property data: ansistring read fdata write fdata; + end; + + tobjectevent = class; + + ievent = interface(iobjectlink) + procedure receiveevent(const event: tobjectevent); + end; + + objeventstatety = (oes_islinked,oes_modaldeferred); + objeventstatesty = set of objeventstatety; + + tobjectevent = class(tmseevent,iobjectlink) + private + finterface: pointer; //ievent; + procedure link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); + procedure unlink(const source,dest: iobjectlink; valuepo: pointer = nil); + procedure objevent(const sender: iobjectlink; const event: objecteventty); + function getinstance: tobject; + protected + fstate: objeventstatesty; + fmodallevel: integer; + public + constructor create(akind: eventkindty; const dest: ievent; + const modaldefer: boolean = false); + destructor destroy; override; + procedure deliver; + property modallevel: integer read fmodallevel; + end; + + tchildprocevent = class(tobjectevent) + public + prochandle: prochandlety; + execresult: integer; + data: pointer; + constructor create(const dest: ievent; const aprochandle: prochandlety; + const aexecresult: integer; const adata: pointer); + end; + + tstringobjectevent = class(tobjectevent) + private + public + data: ansistring; + constructor create(const adata: ansistring; const dest: ievent); +// property data: ansistring read fdata write fdata; + end; + + tpointobjectevent = class(tobjectevent) + private + public + data: pointty; + constructor create(const adata: pointty; const dest: ievent); + // property data: pointty read fdata write fdata; + end; + + tuserevent = class(tobjectevent) + ftag: integer; + public + constructor create(const dest: ievent; tag: integer; + const amodaldefer: boolean = false); + property tag: integer read ftag; + end; + + tasyncevent = class(tuserevent) + constructor create(const dest: ievent; atag: integer; + const amodaldefer: boolean = false); + end; + + texecuteevent = class(tmseevent) + protected + procedure execute(); virtual; abstract; + public + constructor create(); + procedure deliver(); virtual; + end; + + tcustomeventqueue = class(tobjectqueue) + end; + + teventqueue = class(tcustomeventqueue) + private + fsem: semty; + fmutex: mutexty; + fdestroying: boolean; + public + constructor create(aownsobjects: boolean); + destructor destroy; override; + procedure lock(); + procedure unlock(); + procedure clear; override; + procedure post(event: tmseevent); + procedure post(const events: tcustomeventqueue); //transfer items + function wait(const timeoutus: integer = 0): tmseevent; + // -1 infinite, 0 no block, can return nil + end; + +implementation +uses + msesysintf1,mseapplication; +type + tapplication1 = class(tcustomapplication); + +{ tmseevent } + +constructor tmseevent.create(const akind: eventkindty); +begin + fkind:= akind; +end; + +procedure tmseevent.free1; +begin + if (self <> nil) then begin + internalfree1; + end; +end; + +procedure tmseevent.internalfree1; +begin + self.destroy; +end; + +{ tstringevent } + +constructor tstringevent.create(const adata: string); +begin + fdata:= adata; + inherited create(ek_data); +end; + +{ tobjectevent } + +constructor tobjectevent.create(akind: eventkindty; const dest: ievent; + const modaldefer: boolean = false); +{$ifndef FPC} +var + po1: pointer; +{$endif} +begin + finterface:= pointer(dest); + fmodallevel:= -1; +// if akind = ek_releasedefer then begin + if modaldefer then begin + include(fstate,oes_modaldeferred); + end; + if (finterface <> nil) then begin + if application.islockedthread() then begin + include(fstate,oes_islinked); + {$ifndef FPC} + po1:= pointer(1); + ievent(finterface).link(iobjectlink(po1),iobjectlink(self)); + {$else} + ievent(finterface).link(iobjectlink(pointer(1)),iobjectlink(self)); + {$endif} + end; + end; + inherited create(akind); +end; + +destructor tobjectevent.destroy; +{$ifndef FPC} +var + po1: pointer; +{$endif} +begin + if (fmodallevel >= 0) then begin + tapplication1(application).objecteventdestroyed(self); + end; + if (oes_islinked in fstate) and (finterface <> nil) then begin +{$ifndef FPC} + po1:= pointer(1); + ievent(finterface).unlink(iobjectlink(po1),iobjectlink(self)); +{$else} + ievent(finterface).unlink(iobjectlink(pointer(1)),iobjectlink(self)); +{$endif} + end; + inherited; +end; + +procedure tobjectevent.deliver; +begin + if finterface <> nil then begin + ievent(finterface).receiveevent(self); + end; +end; + +procedure tobjectevent.objevent(const sender: iobjectlink; + const event: objecteventty); +begin + if event = oe_destroyed then begin + finterface:= nil; + end; +end; + +function tobjectevent.getinstance: tobject; +begin + result:= self; +end; + +procedure tobjectevent.link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); +begin + //dummy +end; + +procedure tobjectevent.unlink(const source,dest: iobjectlink; + valuepo: pointer = nil); +begin + //dummy +end; + +{ tstringobjectevent } + +constructor tstringobjectevent.create(const adata: ansistring; const dest: ievent); +begin + data:= adata; + inherited create(ek_objectdata,dest); +end; + +{ tpointobjectevent } + +constructor tpointobjectevent.create(const adata: pointty; const dest: ievent); +begin + data:= adata; + inherited create(ek_objectdata,dest); +end; + +{ tuserevent } + +constructor tuserevent.create(const dest: ievent; tag: integer; + const amodaldefer: boolean = false); +begin + ftag:= tag; + inherited create(ek_user,dest,amodaldefer); +end; + +{ tasyncevent } + +constructor tasyncevent.create(const dest: ievent; atag: integer; + const amodaldefer: boolean = false); +begin + inherited; + fkind:= ek_async; +end; + +{ texecuteevent } + +constructor texecuteevent.create; +begin + inherited create(ek_asyncexec); +end; + +procedure texecuteevent.deliver; +begin + execute(); +end; + +{ teventqueue } + +constructor teventqueue.create(aownsobjects: boolean); +begin + sys_semcreate(fsem,0); + sys_mutexcreate(fmutex); + inherited; +end; + +destructor teventqueue.destroy; +begin + fdestroying:= true; + while sys_semcount(fsem) < 0 do begin + sys_sempost(fsem); + end; + sys_semdestroy(fsem); + sys_mutexdestroy(fmutex); + inherited; +end; + +procedure teventqueue.lock(); +begin + sys_mutexlock(fmutex); +end; + +procedure teventqueue.unlock(); +begin + sys_mutexunlock(fmutex); +end; + +procedure teventqueue.post(event: tmseevent); +begin + sys_mutexlock(fmutex); + if not fdestroying then begin + add(event); + end; + sys_mutexunlock(fmutex); + sys_sempost(fsem); +end; + +procedure teventqueue.post(const events: tcustomeventqueue); +begin + events.normalizering(); + sys_mutexlock(fmutex); + if not fdestroying then begin + tpointerlist(self).add(ppointer(pointer(events.fitems)),events.fcount); + end; + events.fcount:= 0; + sys_mutexunlock(fmutex); + sys_sempost(fsem); +end; + +function teventqueue.wait(const timeoutus: integer = 0): tmseevent; + + function get(out item: tmseevent): boolean; + begin + sys_mutexlock(fmutex); + item:= nil; + result:= not fdestroying; + if result then begin + if fcount > 0 then begin + item:= tmseevent(getfirst); + end; + end; + sys_mutexunlock(fmutex); + end; + +begin + if get(result) and (result = nil) then begin + if timeoutus = 0 then begin + if sys_semtrywait(fsem) then begin + get(result); + end; + end + else begin + if sys_semwait(fsem,0) = sye_ok then begin + get(result); + end; + end; + end; +end; + +procedure teventqueue.clear; +begin + if not fdestroying then begin + sys_mutexlock(fmutex); + inherited; + sys_mutexunlock(fmutex); + end + else begin + inherited; + end; +end; + +{ tchildprocevent } + +constructor tchildprocevent.create(const dest: ievent; + const aprochandle: prochandlety; const aexecresult: integer; + const adata: pointer); +begin + prochandle:= aprochandle; + execresult:= aexecresult; + data:= adata; + inherited create(ek_childproc,dest); +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/msefileutils.pas b/mseide-msegui/lib/common/kernel/msefileutils.pas new file mode 100644 index 0000000..e664998 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msefileutils.pas @@ -0,0 +1,2254 @@ +{ MSEgui Copyright (c) 1999-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msefileutils; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + msesysintf,msearrayutils,msedatalist,msesystypes,msesys,msebits,msetypes, + msestream,msestrings; + +type + filelistoptionty = (flo_sortname,flo_sorttime,flo_sortsize, + flo_sorttype,flo_casesensitive,flo_downsort); + filelistoptionsty = set of filelistoptionty; + filekindty = (fk_default,fk_file,fk_dir); + + filechangety = (fc_name,fc_attributes,fc_modtime,fc_accesstime,fc_ctime, + fc_size,fc_removed,fc_direntries,fc_force); + filechangesty = set of filechangety; + checkfileeventty = procedure (const sender: tobject; + const streaminfo: dirstreaminfoty; + const fileinfo: fileinfoty; + var accept: boolean) of object; + //default true + pathrelocateoptionty = (pro_preferenew,pro_onlynew,pro_rootpath); + pathrelocateoptionsty = set of pathrelocateoptionty; + +const + sortflags: filelistoptionsty = [flo_sortname,flo_sorttime,flo_sortsize]; + intermediatefileextension = '.tmp'; +type + filesortfuncty = function(const l,r: fileinfoty): integer of object; + + tcustomfiledatalist = class(tdynamicdatalist) + private + foptions: filelistoptionsty; + fsortfunc: filesortfuncty; + function getitems(index: integer): fileinfoty; + procedure setoptions(const Value: filelistoptionsty); + function sortname(const l,r: fileinfoty): integer; + function sorttime(const l,r: fileinfoty): integer; + function sortsize(const l,r: fileinfoty): integer; + protected + procedure freedata(var data); override; + procedure beforecopy(var data); override; + function compare(const l,r): integer; override; + public + constructor create; override; + function add(const value: fileinfoty): integer; + function adddirectory(const directoryname: filenamety; + ainfolevel: fileinfolevelty = fil_name; const amask: filenamearty = nil; + const aincludeattrib: fileattributesty = [fa_all]; + const aexcludeattrib: fileattributesty = []; + const aoptions: dirstreamoptionsty = []; + const acheckproc: checkfileeventty = nil; + const noexception: boolean = false): boolean; overload; + //amask = nil -> all, true if ok + function adddirectory(const directoryname: filenamety; + ainfolevel: fileinfolevelty; const amask: filenamety; + const aincludeattrib: fileattributesty = [fa_all]; + const aexcludeattrib: fileattributesty = []; + const aoptions: dirstreamoptionsty = []; + const acheckproc: checkfileeventty = nil; + const noexception: boolean = false): boolean; overload; + //amask = '' -> all, true if ok + {$ifndef FPC} + function adddirectory1(const directoryname: filenamety; + ainfolevel: fileinfolevelty = fil_name; const amask: filenamearty = nil; + const aincludeattrib: fileattributesty = [fa_all]; + const aexcludeattrib: fileattributesty = []; + const aoptions: dirstreamoptionsty = []; + const acheckproc: checkfileeventty = nil; + const noexception: boolean = false): boolean; + //amask = nil -> all, true if ok + function adddirectory2(const directoryname: filenamety; + ainfolevel: fileinfolevelty; const amask: filenamety; + const aincludeattrib: fileattributesty = [fa_all]; + const aexcludeattrib: fileattributesty = []; + const aoptions: dirstreamoptionsty = []; + const acheckproc: checkfileeventty = nil; + const noexception: boolean = false): boolean; + //amask = '' -> all, true if ok + {$endif} + function itempo(const index: integer): pfileinfoty; + //invalid after capacity change! + function indexof(const filename: filenamety): integer; + //case sensitive + function isdir(index: integer): boolean; + property items[index: integer]: fileinfoty read getitems; default; + property options: filelistoptionsty read foptions write setoptions default []; + end; + + tfiledatalist = class(tcustomfiledatalist) + published + property options; + end; + +function quotefilename(const name: filenamety): filenamety; overload; +function quotefilename(const directory,name: filenamety): filenamety; overload; +function quotefilename(const names: filenamearty): filenamety; overload; +function quotefilename(const names: array of filenamety): filenamety; overload; +procedure unquotefilename(const names: filenamety; + var result: filenamearty); overload; +function unquotefilename(const name: filenamety): filenamety; overload; +function extractrootpath(var names: filenamearty): filenamety; +function combinerootpath(const rootpath: filenamety; + const names: filenamearty): filenamearty; overload; +function combinerootpath(const rootpaths: filenamearty; + const name: filenamety): filenamearty; overload; + +function syscommandline(const acommandline: filenamety): filenamety; + //converts exec path to sys format +function filepath({const} directory: filenamety; {const} filename: filenamety; + kind: filekindty = fk_default; + relative: boolean = false): filenamety; overload; + //directory ignored if filename starts with root + //"~/....." expands to sys_getuserhomedir()/..... + //"^/....." expands to sys_getapphomedir()/..... + +function filepath({const} path: filenamety; + kind: filekindty = fk_default; + relative: boolean = false): filenamety; overload; +function relativepath(const path: filenamety; const root: filenamety = ''; + const kind: filekindty = fk_default): filenamety; + //root = '' -> currentdir +function relocatepath(const olddir,newdir: filenamety; + var apath: filenamety; + const options: pathrelocateoptionsty = []): boolean; +//searches file in newdir relative to olddir or in original position, +//updates apath, returns true if found +function isrelativepath(const path: filenamety): boolean; +function isrootdir(const path: filenamety): boolean; +function removelastpathsection(path: filenamety): filenamety; +function getlastpathsection(const path: filenamety): filenamety; +function removelastdir(path: filenamety; var newpath: filenamety): filenamety; +procedure splitfilepath(const path: filenamety; + out directory,filename: filenamety); overload; +procedure splitfilepath(const path: filenamety; + out directory,filename,fileext: filenamety); overload; +function splitfilepath(const path: filenamety): filenamearty; +function splitrootpath(const path: filenamety): filenamearty; +function mergerootpath(const segments: filenamearty): filenamety; + +function checkfilename(const filename,mask: filenamety; + casesensitive: boolean = false): boolean; overload; + //true if filename fits mask, maskchars: '*','?' +function checkfilename(const filename: filenamety; const mask: filenamearty; + casesensitive: boolean = false): boolean; overload; +function checkfilename(const filename: filenamety; + const dirstream: dirstreamty): boolean; overload; +function hasmaskchars(const filename: filenamety): boolean; +function issamefilename(const a,b: filenamety): boolean; +function issamefilepath(const a,b: filenamety): boolean; + +function filename(const path: filenamety): filenamety; +function filedir(const path: filenamety): filenamety; +function filenamebase(const path: filenamety): filenamety; //without ext +function fileext(const path: filenamety): filenamety; +function removefileext(const path: filenamety): filenamety; +function hasfileext(const path: filenamety): boolean; +function checkfileext(const path: filenamety; const extensions: array of filenamety): boolean; +function replacefileext(const path,newext: filenamety): filenamety; + +function tomsefilepath(const path: filenamety; + const quoted: boolean = false): filenamety; +procedure tomsefilepath1(var path: filenamety; const quoted: boolean = false); +function tosysfilepath(const path: filenamety; + const quoted: boolean = false): filenamety; +function tosysfilepath(const path: filenamearty; + const quoted: boolean = false): filenamearty; +procedure tosysfilepath1(var path: filenamety; const quoted: boolean = false); + +function searchfile(const filename: filenamety; dir: boolean = false; + const aoptions: dirstreamoptionsty = []): filenamety; overload; + //returns rootpath if file exists, '' otherwise +function searchfile(const afilename: filenamety; + const adirnames: array of filenamety; + const ainclude: fileattributesty = [fa_all]; + const aexclude: fileattributesty = []; + const aoptions: dirstreamoptionsty = []): filenamety; overload; + //returns directory of last occurence in dirs, '' if none + //afilename can be path and can have wildchars ('?','*'), + //adirnames can have wildchars ('?','*','**','***') + //'?' -> any char + //'*' -> any chars + //'**' -> 1..x directory levels + //'***' -> 0..x directory levels +function searchfile(const afilename: filenamety; const adirname: filenamety; + const ainclude: fileattributesty = [fa_all]; + const aexclude: fileattributesty = []; + const aoptions: dirstreamoptionsty = []): filenamety; overload; + //returns directory, '' if none + //afilename must be simple filename and can have wildchars ('?','*'), + //adirname can have wildchars ('?','*','**','***') + +function searchfiles(const afilename: filenamety; + const adirnames: array of filenamety; + const ainclude: fileattributesty = [fa_all]; + const aexclude: fileattributesty = []; + const aoptions: dirstreamoptionsty = []): filenamearty; overload; + //returns filepaths + //afilename can be path or quoted list of paths + //and can have wildchars ('?','*') example: '"a/*.pas" "b/*.pp"', + //adirnames can have wildchars ('?','*','**','***') +function searchfiles(const afilename: filenamety; + const adirname: filenamety; + const ainclude: fileattributesty = [fa_all]; + const aexclude: fileattributesty = []; + const aoptions: dirstreamoptionsty = []): filenamearty; overload; + //returns filepaths + //afilename must be simple filename or quoted list of simple filenames + //and can have wildchars ('?','*') example: '"*.pp" "*.pas"', + //adirname can have wildchars ('?','*','**','***') + +function searchfilenames(const afilename: filenamety; const adirname: filenamety; + const ainclude: fileattributesty = [fa_all]; + const aexclude: fileattributesty = []; + const aoptions: dirstreamoptionsty = []): filenamearty; + //returns filenames + //afilename must be simple filename or quoted list of simple filenames + //and can have wildchars ('?','*') example: '"*.pp" "*.pas"', + //empty -> all + +function dirhasentries(const adirname: filenamety; + const ainclude: fileattributesty = [fa_all]; + const aexclude: fileattributesty = []): boolean; + +function findfile(filename: filenamety; //no const bcause of var path param + const dirnames: array of filenamety; + var path: filenamety): boolean; overload; + //no out because of caller side finalization + //true if found, path not touched if not found +function findfile(filename: filenamety; //no const bcause of var path param + var path: filenamety): boolean; overload; + //no out because of caller side finalization + //true if found, path not touched if not found +function findfile(const filename: filenamety; const dirnames: + array of filenamety): boolean; overload; +function findfile(const filename: filenamety): boolean; overload; +function finddir(const filename: filenamety): boolean; +function findfileordir(const filename: filenamety): boolean; +function uniquefilename(const path: filenamety): filenamety; + //adds numbers if necessary + +function isrootpath(const path: filenamety): boolean; +function copyfile(const oldfile,newfile: filenamety; + const canoverwrite: boolean = true): boolean; + //false if newfile exists and not canoverwrite +function trycopyfile(const oldfile,newfile: filenamety; + const canoverwrite: boolean = true): boolean; + //false on error or newfile exists and not canoverwrite +function renamefile(const oldname,newname: filenamety; + const canoverwrite: boolean = true): boolean; + //false if newname exists and not canoverwrite +function deletefile(const filename: filenamety): boolean; + //false if not existing +function trydeletefile(const filename: filenamety): boolean; + //false if not existing or not deleted +procedure createdir(const path: filenamety; + const rights: filerightsty = defaultdirrights); +procedure createdirpath(const path: filenamety; + const rights: filerightsty = defaultdirrights); +function deletedir(const path: filenamety): boolean; + //deletes files and directories recursively, false if not existing +function trydeletedir(const path: filenamety): boolean; + //deletes files and directories recursively, + // false if not existing or not deleted +function getcurrentdir: filenamety; deprecated; +function getcurrentdirmse: filenamety; +function setcurrentdir(const path: filenamety): filenamety; deprecated; +function setcurrentdirmse(const path: filenamety): filenamety; +function trysetcurrentdirmse(const path: filenamety): boolean; overload; +function trysetcurrentdirmse(const path: filenamety; + out pathbefore: msestring): boolean; overload; + +procedure clearfileinfo(var info: fileinfoty); +procedure initdirfileinfo(var info: fileinfoty; const aname: filenamety; + open: boolean = false); +function getfileinfo(const path: filenamety; var info: fileinfoty): boolean; + //false if not found +function getfilemodtime(const path: filenamety): tdatetime; + //empty date if not found + +function filesystemiscaseinsensitive: boolean; + +function compfileinfos(const info1,info2: fileinfoty): filechangesty; +function compfiletime(const a,b: tdatetime): integer; + //-1 if a < b, 0 if a = b, 1 if a > b + +function intermediatefilename(const aname: filenamety): filenamety; +function msegettempdir: filenamety; +function msegettempfilename(const aname: filenamety): filenamety; + +implementation +uses + sysutils,msedate,mseprocutils,mseformatstr; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + quotechar = msechar('"'); + slashchar = msechar('/'); + dotchar = msechar('.'); + +type + checkmaskresultty = (cmr_correct,cmr_wrong,cmr_wrongfinished,cmr_correctfinished); +const + checkmaskfinished = cmr_wrongfinished; + +function msegettempdir: filenamety; +begin + result:= sys_gettempdir; +end; + +function msegettempfilename(const aname: filenamety): filenamety; +begin + result:= intermediatefilename(filepath(msegettempdir,aname,fk_file)); +end; + +function intermediatefilename(const aname: filenamety): filenamety; +var + fname1,fname2: filenamety; + int1: integer; +begin + fname1:= aname + intermediatefileextension + inttostrmse(getpid); + fname2:= fname1; + int1:= 0; + while findfile(fname2) do begin + inc(int1); + fname2:= fname1 + '_'+inttostrmse(int1); + end; + result:= fname2; +end; + +procedure commitstreamtransaction(const astream: tmsefilestream; + const aname: filenamety); +var + fname1: filenamety; +begin + astream.flush; + fname1:= astream.filename; + astream.close; + msefileutils.renamefile(fname1,aname); +end; + +function compfiletime(const a,b: tdatetime): integer; + //-1 if a < b, 0 if a = b, 1 if a > b +const + deltamin = 1/(24*60*60*1000); //1 ms + +var + rea1: real; +begin + result:= 0; + rea1:= a - b; + if rea1 < -deltamin then begin + result:= -1; + end + else begin + if rea1 > deltamin then begin + result:= 1; + end; + end; +end; + +function compfileinfos(const info1,info2: fileinfoty): filechangesty; +begin + result:= []; + if info1.name <> info2.name then include(result,fc_name); + if info1.extinfo1.attributes <> info2.extinfo1.attributes then include(result,fc_attributes); + if compfiletime(info1.extinfo1.modtime,info2.extinfo1.modtime) <> 0 then include(result,fc_modtime); + if compfiletime(info1.extinfo1.accesstime,info2.extinfo1.accesstime) <> 0 then include(result,fc_accesstime); + if compfiletime(info1.extinfo1.ctime,info2.extinfo1.ctime) <> 0 then include(result,fc_ctime); + if info1.extinfo1.size <> info2.extinfo1.size then include(result,fc_size); +end; + +procedure clearfileinfo(var info: fileinfoty); +begin + finalize(info); + fillchar(info,sizeof(info),0); +end; + +procedure initdirfileinfo(var info: fileinfoty; const aname: filenamety; open: boolean = false); +begin + clearfileinfo(info); + with info do begin + name:= aname; + if open then begin + state:= [fis_typevalid,fis_diropen]; + end + else begin + state:= [fis_typevalid]; + end; + extinfo1.filetype:= ft_dir; + end; +end; + +function getfileinfo(const path: filenamety; var info: fileinfoty): boolean; + //false if not found +begin + result:= sys_getfileinfo(path,info); +end; + +function getfilemodtime(const path: filenamety): tdatetime; + //empty date if not found +var + info1: fileinfoty; +begin + if getfileinfo(path,info1) then begin + result:= info1.extinfo1.modtime; + end + else begin + result:= emptydatetime; + end; +end; + +function copyfile(const oldfile,newfile: filenamety; + const canoverwrite: boolean = true): boolean; + //false if dest exists and not canoverwrite + //todo: remove race condition +begin + if not canoverwrite and findfile(newfile) then begin + result:= false; + end + else begin + result:= true; + syserror(sys_copyfile(oldfile,newfile), + 'Can not copy File "'+oldfile+'" to "'+newfile+'": '); + end; +end; + +function trycopyfile(const oldfile,newfile: filenamety; + const canoverwrite: boolean = true): boolean; + //false if dest exists and not canoverwrite +begin + //todo: remove race condition + if not canoverwrite and findfile(newfile) then begin + result:= false; + end + else begin + result:= sys_copyfile(oldfile,newfile) = sye_ok; + end; +end; + +function renamefile(const oldname,newname: filenamety; + const canoverwrite: boolean = true): boolean; + //false if newname exists and not canoverwrite +begin + if not canoverwrite and findfile(newname) then begin + result:= false; + end + else begin + result:= true; + syserror(sys_renamefile(oldname,newname), + 'Can not rename File "'+oldname+'" to "'+newname+'": '); + end; +end; + +function deletefile(const filename: filenamety): boolean; + //false if not existing +var + err: syserrorty; +begin + err:= sys_deletefile(filename); + result:= err = sye_ok; + if not result and findfile(filename) then begin + syserror(err,'Can not delete file "'+filename+'".'); + end; +end; + +function trydeletefile(const filename: filenamety): boolean; + //false if not existing or not deleted +begin + result:= sys_deletefile(filename) = sye_ok; +end; + +function deletefilesanddir(const path: filenamety): syserrorty; +var + ar1: filenamearty; + i1: int32; +begin + ar1:= searchfilenames('',path,[fa_all],[fa_dir]); + for i1:= 0 to high(ar1) do begin + result:= sys_deletefile(path+'/'+ar1[i1]); + if result <> sye_ok then begin + exit; + end; + end; + ar1:= searchfilenames('',path,[fa_dir]); + for i1:= 0 to high(ar1) do begin + result:= deletefilesanddir(path+'/'+ar1[i1]); + if result <> sye_ok then begin + exit; + end; + end; + result:= sys_deletedir(path); +end; + +function deletedir(const path: filenamety): boolean; + //deletes files and directories recursively, false if not existing +var + err: syserrorty; +begin + err:= deletefilesanddir(path); + result:= err = sye_ok; + if not result and finddir(path) then begin + syserror(err,'Can not delete dir "'+path+'". '); + end; +end; + +function trydeletedir(const path: filenamety): boolean; + //deletes files and directories recursively, + // false if not existing or not deleted +begin + result:= deletefilesanddir(path) = sye_ok; +end; + +procedure createdir(const path: filenamety; + const rights: filerightsty = defaultdirrights); +begin +// syserror(sys_createdir(tosysfilepath(path))); + syserror(sys_createdir(path,rights)); +end; + +procedure createdirpath(const path: filenamety; + const rights: filerightsty = defaultdirrights); +var + ar1: filenamearty; + mstr1: filenamety; + int1: integer; +begin + ar1:= splitrootpath(path); + mstr1:= ''; + for int1:= 0 to high(ar1) do begin + mstr1:= mstr1+slashchar+ar1[int1]; + if not finddir(mstr1) then begin + createdir(mstr1,rights); + end; + end; +end; + +function getcurrentdirmse: filenamety; +begin + result:= sys_getcurrentdir; +end; + +function getcurrentdir: filenamety; +begin + result:= getcurrentdirmse; +end; + +function setcurrentdirmse(const path: filenamety): filenamety; +var + error: syserrorty; +begin + result:= sys_getcurrentdir; + error:= sys_setcurrentdir(path); + if error <> sye_ok then begin + syserror(error,'Setcurrentdir "'+ path + quotechar+':'+lineend); + end; +end; + +function trysetcurrentdirmse(const path: filenamety; + out pathbefore: filenamety): boolean; +begin + pathbefore:= sys_getcurrentdir; + result:= sys_setcurrentdir(path) = sye_ok; +end; + +function trysetcurrentdirmse(const path: filenamety): boolean; +begin + result:= sys_setcurrentdir(path) = sye_ok; +end; + +function setcurrentdir(const path: filenamety): filenamety; +begin + result:= setcurrentdirmse(path); +end; + +function remquote(const path: filenamety): filenamety; +begin + if pmsechar(path)^ = quotechar then begin + result:= copy(path,2,bigint); + end + else begin + result:= path; + end; +end; + +procedure requote(var path: filenamety; const newvalue: filenamety); +begin + if pmsechar(path)^ = quotechar then begin + path:= quotechar + newvalue; + end + else begin + path:= newvalue; + end; +end; + +function isrootpath(const path: filenamety): boolean; +var + str1: filenamety; +begin + str1:= remquote(path); + tomsefilepath1(str1); + result:= (length(str1) > 0) and (str1[1] = slashchar); +end; + +procedure checkmask(s: pmsechar; mask: pmsechar; var result: checkmaskresultty); +var + po1: pmsechar; +begin + while true do begin + if s^ = #0 then begin + if mask^ = #0 then begin + result:= cmr_correctfinished; + break; + end; + end; + case mask^ of + '*': begin + po1:= mask + 1; + if po1^ = #0 then begin + result:= cmr_correctfinished; + break; + end; + while true do begin + checkmask(s,po1,result); + if (result = cmr_correctfinished) or (s^ = #0) then begin + break; + end; + inc(s); + result:= cmr_correct; + end; + break; + end; + '?': begin + if s^ = #0 then begin + result:= cmr_wrongfinished; + break; + end; + inc(s); + inc(mask); + end; + #0: begin + result:= cmr_wrongfinished; + break; + end; + else begin + if s^ = mask^ then begin + inc(s); + inc(mask); + continue; + end + else begin + result:= cmr_wrong; + break; + end; + end; + end; + end; +end; + +function internalcheckfilename(const filename,mask: filenamety): boolean; +var + checkresult: checkmaskresultty; +begin + checkresult:= cmr_correct; + checkmask(pmsechar(filename),pmsechar(mask),checkresult); + result:= checkresult = cmr_correctfinished; +end; + +function checkfilename(const filename,mask: filenamety; + casesensitive: boolean = false): boolean; + //'*' and '?' are possible maskchars +var + str1,str2: msestring; +begin + if casesensitive then begin + result:= internalcheckfilename(filename,mask); + end + else begin + str1:= mseuppercase(filename); + str2:= mseuppercase(mask); + result:= internalcheckfilename(str1,str2); + end; +end; + +function checkfilename(const filename: filenamety; const mask: filenamearty; + casesensitive: boolean = false): boolean; +var + str1,str2: msestring; + int1: integer; +begin + if mask = nil then begin + result:= true; + end + else begin + result:= false; + if casesensitive then begin + for int1:= 0 to high(mask) do begin + if internalcheckfilename(filename,mask[int1]) then begin + result:= true; + break; + end; + end; + end + else begin + str1:= mseuppercase(filename); + for int1:= 0 to high(mask) do begin + str2:= mseuppercase(mask[int1]); + if internalcheckfilename(str1,str2) then begin + result:= true; + break; + end; + end; + end; + end; +end; + +function checkfilename(const filename: filenamety; + const dirstream: dirstreamty): boolean; + //mask must be uppercase if case sensitive +var + str1{,str2}: msestring; + int1: integer; +begin + with dirstream,dirinfo do begin + if mask = nil then begin + result:= true; + end + else begin + result:= false; + if caseinsensitive then begin + str1:= mseuppercase(filename); + for int1:= 0 to high(mask) do begin + if internalcheckfilename(str1,mask[int1]) then begin + result:= true; + break; + end; + end; + end + else begin + for int1:= 0 to high(mask) do begin + if internalcheckfilename(filename,mask[int1]) then begin + result:= true; + break; + end; + end; + end; + end; + end; +end; + +function hasmaskchars(const filename: filenamety): boolean; +begin + if msestrscan(pmsechar(filename),msechar('*')) = nil then begin + result:= msestrscan(pmsechar(filename),msechar('?')) <> nil; + end + else begin + result:= true; + end; +end; + +function filesystemiscaseinsensitive: boolean; +begin + result:= sys_filesystemiscaseinsensitive; +end; + +function issamefilename(const a,b: filenamety): boolean; +begin + if filesystemiscaseinsensitive then begin + result:= msecomparetext(filepath(a),filepath(b)) = 0; + end + else begin + result:= filepath(a) = filepath(b); + end; +end; + +function issamefilepath(const a,b: filenamety): boolean; +begin + result:= issamefilename(filepath(a),filepath(b)); +end; + +function searchfile(const filename: filenamety;dir: boolean = false; + const aoptions: dirstreamoptionsty = []): filenamety; overload; + //returns rootpath if file exists, '' otherwise +begin + result:= filepath(filename); + if not (dir and finddir(result) or + not dir and findfile(result)) then begin + result:= ''; + end; +end; + +function searchfile(const afilename: filenamety; const adirname: filenamety; + const ainclude: fileattributesty = [fa_all]; + const aexclude: fileattributesty = []; + const aoptions: dirstreamoptionsty = []): filenamety; +var + ar1{,ar2}: filenamearty; + int1: integer; + dirstream: dirstreamty; + fileinfo: fileinfoty; + recursive: boolean; + fna1: filenamety; +begin + result:= ''; + ar1:= nil; //compiler warning + fillchar(dirstream,sizeof(dirstream),0); + if hasmaskchars(adirname) then begin + recursive:= false; + ar1:= splitrootpath(adirname); + for int1:= 0 to high(ar1) do begin + if hasmaskchars(ar1[int1]) then begin + with dirstream,dirinfo do begin + if int1 > 0 then begin + dirname:= mergerootpath(copy(ar1,0,int1)); + end + else begin + dirname:= slashchar; + end; + if ar1[int1] = '***' then begin + deleteitem(ar1,int1); + result:= searchfile(afilename,mergerootpath(ar1), + ainclude,aexclude,aoptions); + if result <> '' then begin + break; + end; + insertitem(ar1,int1,'**'); + end; + mask:= copy(ar1,int1,1); + if mask[0] = '**' then begin + recursive:= true; + mask[0]:= '*'; + end; + include:= [fa_dir]; + if sys_opendirstream(dirstream) <> sye_ok then begin + exit; + end; + fna1:= ar1[int1]; + while sys_readdirstream(dirstream,fileinfo) do begin + if (fileinfo.name <> dotchar) and (fileinfo.name <> '..') then begin + ar1[int1]:= fileinfo.name; + result:= searchfile(afilename,mergerootpath(ar1),ainclude, + aexclude,aoptions); + if result <> '' then begin + break; + end; + if recursive then begin + insertitem(ar1,int1+1,'**'); + result:= searchfile(afilename,mergerootpath(ar1)); + if result <> '' then begin + break; + end; + deleteitem(ar1,int1+1); + end; + end; + end; + ar1[int1]:= fna1; + end; + sys_closedirstream(dirstream); + exit; + end; + end; + end + else begin + with dirstream,dirinfo do begin + dirname:= filepath(adirname,fk_file); + if afilename <> '' then begin + setlength(mask,1); + mask[0]:= afilename; + end; + include:= ainclude; + exclude:= aexclude; + if sys_opendirstream(dirstream) <> sye_ok then begin + exit; + end; + if sys_readdirstream(dirstream,fileinfo) then begin + result:= filepath(adirname,fk_dir); + end; + sys_closedirstream(dirstream); + end; + end; +end; + +function searchfile(const afilename: filenamety; + const adirnames: array of filenamety; + const ainclude: fileattributesty = [fa_all]; + const aexclude: fileattributesty = []; + const aoptions: dirstreamoptionsty = []): filenamety; + //returns directory of last occurence in adirnames, '' if none +var + int1: integer; + dir1,file1: filenamety; +begin + result:= ''; + file1:= trim(afilename); + if (file1 <> '') and (high(adirnames) < 0) then begin + splitfilepath(afilename,dir1,file1); + result:= searchfile(file1,dir1,ainclude,aexclude,aoptions); + end + else begin + for int1:= high(adirnames) downto 0 do begin + if afilename = '' then begin + dir1:= adirnames[int1]; + end + else begin + splitfilepath(filepath(adirnames[int1],afilename,fk_file,true),dir1,file1); + end; + result:= searchfile(file1,dir1,ainclude,aexclude,aoptions); + if result <> '' then begin + break; + end; + end; + end; +end; + +function searchfiles(const afilename: filenamety; const adirname: filenamety; + const ainclude: fileattributesty = [fa_all]; + const aexclude: fileattributesty = []; + const aoptions: dirstreamoptionsty = []): filenamearty; +var + ar1{,ar2}: filenamearty; + int1,int2: integer; + dirstream: dirstreamty; + fileinfo: fileinfoty; + recursive: boolean; + fna1: filenamety; +begin +// result:= ''; + result:= nil; + ar1:= nil; //compiler warning + fillchar(dirstream,sizeof(dirstream),0); + if hasmaskchars(adirname) then begin + recursive:= false; + ar1:= splitrootpath(adirname); + for int1:= 0 to high(ar1) do begin + if hasmaskchars(ar1[int1]) then begin + with dirstream,dirinfo do begin + if int1 > 0 then begin + dirname:= mergerootpath(copy(ar1,0,int1)); + end + else begin + dirname:= slashchar; + end; + if ar1[int1] = '***' then begin + deleteitem(ar1,int1); + stackarray(searchfiles(afilename,mergerootpath(ar1), + ainclude,aexclude,aoptions),result); + insertitem(ar1,int1,'**'); + end; + mask:= copy(ar1,int1,1); + if mask[0] = '**' then begin + recursive:= true; + mask[0]:= '*'; + end; + include:= [fa_dir]; + if sys_opendirstream(dirstream) <> sye_ok then begin + exit; + end; + fna1:= ar1[int1]; + while sys_readdirstream(dirstream,fileinfo) do begin + if (fileinfo.name <> dotchar) and (fileinfo.name <> '..') then begin + ar1[int1]:= fileinfo.name; + stackarray(searchfiles(afilename, + mergerootpath(ar1),ainclude,aexclude,aoptions),result); + if recursive then begin + insertitem(ar1,int1+1,'**'); + stackarray(searchfiles(afilename, + mergerootpath(ar1),ainclude,aexclude,aoptions),result); + deleteitem(ar1,int1+1); + end; + end; + end; + ar1[int1]:= fna1; + end; + sys_closedirstream(dirstream); + exit; + end; + end; + end + else begin + with dirstream,dirinfo do begin + dirname:= filepath(adirname,fk_file); + options:= aoptions; + if afilename <> '' then begin + unquotefilename(afilename,mask); +// setlength(mask,1); +// mask[0]:= afilename; + end; + include:= ainclude; + exclude:= aexclude; + infolevel:= fil_type; + if sys_opendirstream(dirstream) <> sye_ok then begin + exit; + end; + int2:= 0; + while sys_readdirstream(dirstream,fileinfo) do begin + if (fileinfo.extinfo1.filetype <> ft_dir) or + (fileinfo.name <> dotchar) and (fileinfo.name <> '..') then begin + if high(result) < int2 then begin + setlength(result,int2*2+16); + end; + result[int2]:= filepath(dirname,fileinfo.name); + inc(int2); + end; + end; + setlength(result,int2); + sys_closedirstream(dirstream); + end; + end; +end; + +function searchfilenames(const afilename: filenamety; const adirname: filenamety; + const ainclude: fileattributesty = [fa_all]; + const aexclude: fileattributesty = []; + const aoptions: dirstreamoptionsty = []): filenamearty; +var + int2: integer; + dirstream: dirstreamty; + fileinfo: fileinfoty; +begin + result:= nil; + fillchar(dirstream,sizeof(dirstream),0); + with dirstream,dirinfo do begin + dirname:= filepath(adirname,fk_file); + options:= aoptions; + if afilename <> '' then begin + unquotefilename(afilename,mask); +// setlength(mask,1); +// mask[0]:= afilename; + end; + include:= ainclude; + exclude:= aexclude; + infolevel:= fil_type; + if sys_opendirstream(dirstream) <> sye_ok then begin + exit; + end; + int2:= 0; + while sys_readdirstream(dirstream,fileinfo) do begin + if (fileinfo.extinfo1.filetype <> ft_dir) or + (fileinfo.name <> dotchar) and (fileinfo.name <> '..') then begin + if high(result) < int2 then begin + setlength(result,int2*2+16); + end; + result[int2]:= fileinfo.name; + inc(int2); + end; + end; + setlength(result,int2); + sys_closedirstream(dirstream); + end; +end; + +function searchfiles(const afilename: filenamety; + const adirnames: array of filenamety; + const ainclude: fileattributesty = [fa_all]; + const aexclude: fileattributesty = []; + const aoptions: dirstreamoptionsty = []): filenamearty; +var + int1,i2: integer; + dir1,file1: filenamety; + ar1: filenamearty; +begin + result:= nil; + file1:= trim(afilename); + unquotefilename(file1,ar1); + if (file1 <> '') and (high(adirnames) < 0) then begin + for int1:= 0 to high(ar1) do begin + splitfilepath(ar1[int1],dir1,file1); + stackarray(searchfiles(file1,dir1,ainclude,aexclude,aoptions),result); + end; + end + else begin + for int1:= 0 to high(adirnames) do begin + if afilename = '' then begin + dir1:= adirnames[int1]; + stackarray(searchfiles(file1,dir1,ainclude,aexclude,aoptions),result); + end + else begin + for i2:= 0 to high(ar1) do begin + splitfilepath(filepath(adirnames[int1],ar1[int1],fk_file,true),dir1,file1); + stackarray(searchfiles(file1,dir1,ainclude,aexclude,aoptions),result); + end; + end; + end; + end; +end; + +function dirhasentries(const adirname: filenamety; + const ainclude: fileattributesty = [fa_all]; + const aexclude: fileattributesty = []): boolean; +var + dirstream: dirstreamty; + fileinfo: fileinfoty; +begin + result:= false; + fillchar(dirstream,sizeof(dirstream),0); + with dirstream,dirinfo do begin + dirname:= filepath(adirname,fk_file); + include:= ainclude; + exclude:= aexclude; + if sys_opendirstream(dirstream) <> sye_ok then begin + exit; + end; + while sys_readdirstream(dirstream,fileinfo) do begin + if (fileinfo.name <> dotchar) and (fileinfo.name <> '..') then begin + result:= true; + break; + end; + end; + sys_closedirstream(dirstream); + end; +end; + +function findfile(filename: filenamety; + const dirnames: array of filenamety; var path: filenamety): boolean; + //true if found, path not touched if not found +var + fna1: filenamety; +begin + fna1:= searchfile(filename,dirnames); + if fna1 <> '' then begin + path:= fna1 + msefileutils.filename(filename); + result:= true; + end + else begin + result:= false; + end; +end; + +function findfile(filename: filenamety; //no const bcause of var path param + var path: filenamety): boolean; + //no out because of caller side finalization + //true if found, path not touched if not found +var + fna1: filenamety; +begin + fna1:= searchfile(filename); + if fna1 <> '' then begin + path:= fna1 + msefileutils.filename(filename); + result:= true; + end + else begin + result:= false; + end; +end; + +function findfile(const filename: filenamety; + const dirnames: array of filenamety): boolean; + //true if found +var + fna1: filenamety; +begin + result:= findfile(filename,dirnames,fna1); +end; + +function findfileordir(const filename: filenamety): boolean; +var + info: fileinfoty; +begin + result:= sys_getfileinfo(filename,info); +end; + +function findfile(const filename: filenamety): boolean; overload; +var + info: fileinfoty; +begin + result:= sys_getfileinfo(filename,info) and (info.extinfo1.filetype <> ft_dir); +end; + +function finddir(const filename: filenamety): boolean; +var + info: fileinfoty; +begin + result:= sys_getfileinfo(filename,info) and (info.extinfo1.filetype = ft_dir); +end; + +function quotefilename(const name: filenamety): filenamety; overload; +begin + if (findchar(name,msechar(' ')) = 0) or (name[1] = quotechar) then begin + result:= name; + end + else begin + result:= quotestring(name,quotechar); + end; +end; + +function quotefilename(const names: filenamearty): filenamety; overload; +var + int1: integer; +begin + result:= ''; + if length(names) = 1 then begin + result:= quotefilename(names[0]); + end + else begin + for int1:= 0 to high(names) do begin + if pointer(names[int1]) <> nil then begin + result:= result + quotestring(names[int1],quotechar) + ' '; + end; + end; + if length(result) > 0 then begin + setlength(result,length(result)-1); + end; + end; +end; + +function quotefilename(const names: array of filenamety): filenamety; overload; +begin + result:= quotefilename(opentodynarraym(names)); +end; + +function quotefilename(const directory,name: filenamety): filenamety; +var + ar1: filenamearty; + str1: filenamety; + int1: integer; +begin + unquotefilename(name,ar1); + str1:= unquotefilename(trim(directory)); + if str1 <> '' then begin + str1:= filepath(str1,fk_dir,true); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= filepath(str1+ar1[int1],fk_file,true); + end + end + else begin + for int1:= 0 to high(ar1) do begin + ar1[int1]:= filepath(ar1[int1],fk_file,true); + end; + end; + result:= quotefilename(ar1); +end; + +procedure unquotefilename(const names: filenamety; var result: filenamearty); +begin + if findchar(names,quotechar) <> 0 then begin + splitstringquoted(trim(names),result,quotechar); + end + else begin + setlength(result,1); + result[0]:= trim(names); + if result[0] = '' then begin + result:= nil; + end; + end; +end; + +function unquotefilename(const name: filenamety): filenamety; overload; +begin + result:= trim(name); + if (length(result) > 1) and + (result[1] = quotechar) and (result[length(result)] = quotechar) then begin + result:= copy(result,2,length(result)-2); + end; +end; + +function extractrootpath(var names: filenamearty): filenamety; +var + ch1: msechar; + int1,int2,int3: integer; + bo1: boolean; +begin + result:= ''; + if names <> nil then begin + int3:= 0; + bo1:= false; + for int2:= 1 to length(names[0]) do begin + ch1:= names[0][int2]; + for int1:= 1 to high(names) do begin + if names[int1][int2] <> ch1 then begin + bo1:= true; + break; + end; + end; + if bo1 then begin + break; + end; + if ch1 = slashchar then begin + int3:= int2; + end; + end; + result:= copy(names[0],1,int3); + names:= copy(names); + for int1:= 0 to high(names) do begin + names[int1]:= copy(names[int1],int3+1,bigint); + end; + end; +end; + +function combinerootpath(const rootpath: filenamety; const names: filenamearty): filenamearty; +var + int1: integer; + str1,str2: filenamety; +begin + str1:= filepath(rootpath,fk_dir,true); + setlength(result,length(names)); + for int1:= 0 to high(names) do begin + str2:= filepath(names[int1],fk_default,true); + if (length(str2) > 0) and (str2[1] = slashchar) then begin + result[int1]:= str2; + end + else begin + result[int1]:= str1 + str2 {$ifndef FPC}+''{$endif}; //delphi bug + end; + end; +end; + +function combinerootpath(const rootpaths: filenamearty; const name: filenamety): filenamearty; +var + int1: integer; +begin + setlength(result,length(rootpaths)); + for int1:= 0 to high(rootpaths) do begin + result[int1]:= filepath(rootpaths[int1],name,fk_default,true); + end; +end; + +function isrelativepath(const path: filenamety): boolean; +var + str1: filenamety; +begin + str1:= remquote(path); + result:= not ( + (length(str1) > 0) and ((str1[1] = '\') or (str1[1] = slashchar)) or + (length(str1) >= 1) and (str1[2] = ':') + ); +end; + +function isrootdir(const path: filenamety): boolean; +begin + result:= (path = slashchar) or (path = '\') or (path = '"/"') or (path = '"\"'); +end; + +procedure tomsefilepath1(var path: filenamety; const quoted: boolean = false); + + procedure doname(var path: filenamety); + var + str1: filenamety; + begin + str1:= remquote(path); + replacechar1(str1,msechar('\'),msechar(slashchar)); //calls uniquestring + if (length(str1) >= 2) and (str1[2] = ':'){ and (str1[3] = slashchar)} then begin + setlength(str1,length(str1)+1); + move(str1[1],str1[2],(length(str1)-1)*sizeof(msechar)); // 'c:x' -> 'cc:x' + pmsecharaty(str1)^[0]:= slashchar; // /c: + pmsecharaty(str1)^[1]:= str1[2];//charuppercase(str1[2]); + end; + requote(path,str1); + end; + +var + ar1: filenamearty; + int1: integer; + +begin //tomsefilepath1 + path:= trim(path); + if findchar(path,quotechar) <> 0 then begin + unquotefilename(path,ar1); + for int1:= 0 to high(ar1) do begin + doname(ar1[int1]); + end; + path:= quotefilename(ar1); + end + else begin + doname(path); + if quoted then begin + path:= quotefilename(path); + end; + end; +end; + +procedure tosysfilepath1(var path: filenamety; const quoted: boolean = false); +var + ar1: filenamearty; + int1: integer; +begin + path:= trim(path); + if findchar(path,quotechar) <> 0 then begin + unquotefilename(path,ar1); + for int1:= 0 to high(ar1) do begin + syserror(sys_tosysfilepath(ar1[int1])); + end; + path:= quotefilename(ar1); + end + else begin + if quoted then begin + path:= quotefilename(path); + end; + syserror(sys_tosysfilepath(path)); + end; +end; + +function tomsefilepath(const path: filenamety; + const quoted: boolean = false): filenamety; +begin + result:= path; + tomsefilepath1(result,quoted); +end; + +function tosysfilepath(const path: filenamety; + const quoted: boolean = false): filenamety; +begin + result:= path; + tosysfilepath1(result,quoted); +end; + +function tosysfilepath(const path: filenamearty; + const quoted: boolean = false): filenamearty; +var + i1: int32; +begin + setlength(result,length(path)); + for i1:= 0 to high(path) do begin + result[i1]:= tosysfilepath(path[i1],quoted); + end; +end; + +procedure syncpathdelim(const source: filenamety; var dest: filenamety; + kind: filekindty); +begin + if length(dest) > 0 then begin + if (length(dest) >= 3) and (length(dest) <= 4) and + (dest[1] = slashchar) and (dest[3] = ':') then begin + kind:= fk_dir; // /a: -> /a:/ + // /a:/ -> /a:/ + end; + if kind = fk_default then begin + if (length(source) > 0) and (source[length(source)] = slashchar) then begin + kind:= fk_dir; + end + else begin + kind:= fk_file; + end; + end; + case kind of + fk_dir: begin + if dest[length(dest)] <> slashchar then begin + dest:= dest + slashchar; + end; + end; + fk_file: begin + if (length(dest) > 1) and (dest[length(dest)] = slashchar) then begin + setlength(dest,length(dest) - 1); + end; + end; + end; + end; +end; + +function filepath({const} path: filenamety; + kind: filekindty = fk_default; relative: boolean = false): filenamety; overload; +var + ar1,ar2: filenamearty; + int1,int2: integer; + mstr1: filenamety; + bo1: boolean; +begin + mstr1:= unquotefilename(tomsefilepath(path)); + if (length(mstr1) > 1) and (mstr1[2] = slashchar) then begin + if mstr1[1] = '~' then begin + mstr1:= sys_getuserhomedir + copy(mstr1,2,bigint); + end + else begin + if mstr1[1] = '^' then begin + mstr1:= sys_getapphomedir + copy(mstr1,2,bigint); + end + end; + end; + if not relative and not isrootpath(mstr1) then begin + if mstr1 <> '' then begin + mstr1:= sys_getcurrentdir + slashchar + mstr1; + end + else begin + mstr1:= sys_getcurrentdir; + end; + end; + ar1:= nil; + splitstring(msestring(mstr1),msestringarty(ar1),msechar(slashchar)); + setlength(ar2,length(ar1)); + int2:= 0; + for int1:= 0 to high(ar1) do begin + if ar1[int1] = '..' then begin + if (int2 > 1) or + (int2 = 1) and not ((length(ar2[0]) = 2) and (ar2[0][2] = ':')) then begin + dec(int2); + if ar2[int2] = '..' then begin //for relative path + inc(int2); + ar2[int2]:= ar1[int1]; + inc(int2); + end; + end + else begin + if relative then begin //if not relative ignore '..' if rootdir + ar2[int2]:= ar1[int1]; + inc(int2); + end; + end; + end + else begin + if (ar1[int1] <> dotchar) and (ar1[int1] <> '') then begin + ar2[int2]:= ar1[int1]; + inc(int2); + end; + end; + end; + result:= ''; + bo1:= (length(mstr1) > 0) and (mstr1[1] = slashchar); //rootpath + if bo1 and (int2 = 0) then begin + result:= slashchar; +// inc(int2); + end; + bo1:= not relative or bo1; + for int1:= 0 to int2 - 1 do begin + if bo1 then begin + result:= result + slashchar + ar2[int1]; + end + else begin + result:= result + ar2[int1]; //relative start + bo1:= true; + end; + end; + if relative and ((mstr1 = dotchar) or msestartsstr('./',mstr1)) and + not msestartsstr('../',result) then begin + result:= './' + result; + end; + syncpathdelim(mstr1,result,kind); + if msestartsstr('//',mstr1) then begin + result:= slashchar+result; //restore uncfilename + end; +end; + +function filepath({const} directory,filename: filenamety; kind: filekindty = fk_default; + relative: boolean = false): filenamety; overload; +begin + if not isrelativepath(filename) then begin + result:= filepath(filename,kind,relative); + end + else begin + result:= filepath(directory,fk_dir,relative); + result:= filepath(result + unquotefilename(filename),kind,relative); + tomsefilepath1(result); //really needed? + end; +end; + +function syscommandline(const acommandline: filenamety): filenamety; + //converts exec path to sys format +var + int1,int2,int3: integer; +begin + result:= ''; + int1:= 0; + int2:= 0; + int3:= 0; + if length(acommandline) > 0 then begin + int1:= 1; //start exe + if acommandline[1] = quotechar then begin + int1:= 2; + int2:= findchar(pmsechar(@acommandline[2]),quotechar);//end of exe + if int2 = 0 then begin + int2:= length(acommandline); + end + else begin + inc(int2); + end; + int3:= int2+1; //start of params + end + else begin + int2:= findchar(acommandline,' ');//end of exe + if int2 <= 0 then begin + int2:= length(acommandline); + end; + int3:= int2; + end; + end; + if int1 > 1 then begin //quoted + result:= quotechar+tosysfilepath(copy(acommandline,int1,int2-int1)) + + quotechar+ copy(acommandline,int3,bigint); + end + else begin + result:= tosysfilepath(copy(acommandline,int1,int2-int1)) + + copy(acommandline,int3,bigint); + end; +end; + +function relativepath(const path: filenamety; const root: filenamety = ''; + const kind: filekindty = fk_default): filenamety; + //root = '' -> currentdir +var + root1: filenamety; + str1,str2,str3: filenamety; + ar1,ar2,ar3:filenamearty; + int1,int2,int3: integer; +begin + if root = '' then begin + root1:= sys_getcurrentdir; + end + else begin + root1:= filepath(root,fk_dir); + end; + str1:= filepath(path); + ar3:= splitrootpath(str1); + if filesystemiscaseinsensitive then begin + str2:= mseuppercase(root1); + str3:= mseuppercase(str1); + ar2:= splitrootpath(str3); + end + else begin + str2:= root1; + str3:= str1; + ar2:= ar3; + end; + ar1:= splitrootpath(str2); + int2:= high(ar2); + if int2 > high(ar1) then begin + int2:= high(ar1); + end; + int3:= int2 + 1; + for int1:= 0 to int2 do begin + if ar1[int1] <> ar2[int1] then begin + int3:= int1; + break; + end; + end; + result:= ''; + for int1:= int3 to high(ar1) do begin + result:= result + '../'; + end; + for int1:= int3 to high(ar3) do begin + result:= result + ar3[int1] + slashchar; + end; + if int3 <= high(ar3) then begin + setlength(result,length(result)-1); //remove last slashchar + end; + if result = '' then begin + result:= dotchar; + end; + syncpathdelim(str1,result,kind); +end; + +function relocatepath(const olddir,newdir: filenamety; + var apath: filenamety; + const options: pathrelocateoptionsty = []): boolean; +//searches file in newdir relative to olddir if apath not found, updates +//apath to the new location if found +var + mstr1: filenamety; +begin + result:= true; + if options * [pro_preferenew,pro_onlynew] <> [] then begin + mstr1:= filepath(newdir,relativepath(apath,olddir)); + result:= findfile(mstr1); + if result then begin + apath:= mstr1; + end + else begin + if not (pro_onlynew in options) then begin + result:= findfile(apath); + end; + end; + end + else begin + if not findfile(apath) then begin + mstr1:= filepath(newdir,relativepath(apath,olddir)); + result:= findfile(mstr1); + if result then begin + apath:= mstr1; + end; + end; + end; + if pro_rootpath in options then begin + apath:= filepath(apath); + end; +end; + +procedure splitfilepath(const path: filenamety; + out directory,filename: filenamety); +var + str1: filenamety; +begin +// str1:= unquotefilename(filepath(path,fk_default,true)); + str1:= filepath(path,fk_default,true); + if (str1 = '') or (str1[length(str1)] = slashchar) then begin + directory:= str1; + filename:= ''; + end + else begin + directory:= removelastpathsection(str1); + if directory <> '' then begin + if directory = slashchar then begin //root + filename:= copy(str1,2,bigint); + end + else begin + if directory = '//' then begin //unc root + filename:= copy(str1,3,bigint); + end + else begin + directory:= directory + slashchar; + filename:= copy(str1,length(directory)+1,bigint); + end; + end; + end + else begin + filename:= str1; + end; + end; +end; + +procedure splitfilepath(const path: filenamety; + out directory,filename,fileext: filenamety); +var + fstr1: filenamety; + int1: integer; +begin + splitfilepath(path,directory,fstr1); + int1:= findlastchar(fstr1,dotchar); + if int1 > 1 then begin + filename:= copy(fstr1,1,int1-1); + fileext:= copy(fstr1,int1,bigint); + end + else begin + filename:= fstr1; + fileext:= ''; + end; +end; + +function splitfilepath(const path: filenamety): filenamearty; +var + str1: filenamety; +begin + str1:= unquotefilename(filepath(path,fk_file,true)); + result:= nil; + if str1 <> '' then begin + splitstring(str1,result,msechar(slashchar)); + if result[0] = '' then begin //root + result:= copy(result,1,bigint); + end; + end; +end; + +function splitrootpath(const path: filenamety): filenamearty; +var + str1: filenamety; +begin + str1:= unquotefilename(filepath(path,fk_file)); + result:= nil; + splitstring(str1,result,msechar(slashchar)); + result:= copy(result,1,bigint); +end; + +function mergerootpath(const segments: filenamearty): filenamety; +var + int1: integer; +begin + if segments = nil then begin + result:= slashchar; + end + else begin + result:= ''; + for int1:= 0 to high(segments) do begin + result:= result + slashchar + segments[int1]; + end; + end; +end; + +function filename(const path: filenamety): filenamety; +var + str1: filenamety; +begin + splitfilepath(path,str1,result); +end; + +function filedir(const path: filenamety): filenamety; +var + str1: filenamety; +begin + splitfilepath(path,result,str1); +end; + +function filenamebase(const path: filenamety): filenamety; //without ext +var + mstr1,mstr2: filenamety; +begin + splitfilepath(path,mstr1,result,mstr2); +end; + +function removefileext(const path: filenamety): filenamety; +var + str1: filenamety; + int1: integer; +begin + str1:= tomsefilepath(path); + int1:= findlastchar(str1,dotchar); + if (int1 > 1) and (findlastchar(str1,slashchar) < int1) then begin + result:= copy(str1,1,int1-1); + end + else begin + result:= str1; + end; +end; + +function hasfileext(const path: filenamety): boolean; +var + int1: integer; +begin + int1:= findlastchar(path,dotchar); + result:= (int1 > 1) and (findlastchar(path,slashchar) < int1); +end; + +function fileext(const path: filenamety): filenamety; +var + str1: filenamety; + int1: integer; +begin + str1:= filename(path); + int1:= findlastchar(str1,dotchar); + if int1 > 1 then begin + result:= copy(str1,int1+1,bigint); + end + else begin + result:= ''; + end; +end; + +function checkfileext(const path: filenamety; const extensions: array of filenamety): boolean; +var + int1: integer; + ext: filenamety; +begin + result:= false; + ext:= fileext(path); + if filesystemiscaseinsensitive then begin + ext:= mseuppercase(ext); + end; + for int1:= 0 to high(extensions) do begin + if filesystemiscaseinsensitive then begin + result:= ext = mseuppercase(extensions[int1]); + end + else begin + result:= ext = extensions[int1]; + end; + if result then begin + break; + end; + end; +end; + +function replacefileext(const path,newext: filenamety): filenamety; +begin + result:= removefileext(path); + if newext <> '' then begin + result:= result + dotchar + newext; + end; +end; + +function uniquefilename(const path: filenamety): filenamety; + //adds numbers if necessary +var + int1: integer; + dir,name,ext: filenamety; +begin + result:= path; + if findfileordir(path) then begin + int1:= 1; + splitfilepath(path,dir,name,ext); + repeat + result:= dir+name+inttostrmse(int1)+ext; + inc(int1); + until not findfileordir(result); + end; +end; + +function removelastpathsection(path: filenamety): filenamety; +var + int1: integer; +begin + int1:= findlastchar(path,msechar(slashchar)); + if (int1 > 1) then begin + result:= copy(path,1,int1-1); + if (int1 = 2) and (path[1] = slashchar) then begin + result:= slashchar + result; //UNC + end; + end + else begin + if int1 = 1 then begin + result:= slashchar; //root + end + else begin + result:= ''; + end; + end; +end; + +function getlastpathsection(const path: filenamety): filenamety; +var + fna1: filenamety; + int1,int2: integer; +// po1: pmsechar; +begin + result:= ''; + fna1:= filepath(path); + if fna1 <> '' then begin + int1:= length(fna1); + if fna1[int1] = slashchar then begin + dec(int1); //skip trailing slash + end; + int2:= int1; + while int2 > 0 do begin + if fna1[int2] = slashchar then begin + break; + end; + dec(int2); + end; + if (int2 <= 1) or (int2 = 2) and (fna1[1] = slashchar) then begin //UNC + result:= copy(fna1,1,int1); //all without trailing slash + exit; + end; + result:= copy(fna1,int2+1,int1-int2); + end; +end; + +function removelastdir(path: filenamety; var newpath: filenamety): filenamety; +begin + if (path = '') or isrootdir(path) then begin + newpath:= path; + result:= ''; + end + else begin + if path[length(path)] = slashchar then begin + newpath:= removelastpathsection(copy(path,1,length(path)-1)); + if newpath = slashchar then begin + result:= copy(path,length(newpath)+1,length(path)-length(newpath)-1); + end + else begin + result:= copy(path,length(newpath)+2,length(path)-length(newpath)-2); + end; + end + else begin + newpath:= removelastpathsection(path); + result:= copy(path,length(newpath)+2,length(path)-length(newpath)-1); + end; + if (newpath <> slashchar) and (newpath <> '//') then begin + newpath:= newpath + slashchar; + end; + end; +end; + +{ tcustomfiledatalist } + +constructor tcustomfiledatalist.create; +begin + inherited; + fsize:= sizeof(fileinfoty) +end; + +procedure tcustomfiledatalist.beforecopy(var data); +begin + stringaddref(fileinfoty(data).name); +end; + +procedure tcustomfiledatalist.freedata(var data); +begin + fileinfoty(data).name:= ''; +end; + +function tcustomfiledatalist.adddirectory(const directoryname: filenamety; + ainfolevel: fileinfolevelty = fil_name; const amask: filenamearty = nil; + const aincludeattrib: fileattributesty = [fa_all]; + const aexcludeattrib: fileattributesty = []; + const aoptions: dirstreamoptionsty = []; + const acheckproc: checkfileeventty = nil; + const noexception: boolean = false + ): boolean; + //amask = '' -> all, +var + dirstream: dirstreamty; + info: fileinfoty; + bo1,bo2: boolean; + err1: syserrorty; + ar1: filenamearty; + i1: int32; +begin + unquotefilename(directoryname,ar1); + fillchar(dirstream,sizeof(dirstream),0); + beginupdate(); + try + for i1:= 0 to high(ar1) do begin + with dirstream,dirinfo do begin + options:= aoptions; + dirname:= filepath(ar1[i1],fk_file); + mask:= amask; + include:= aincludeattrib; + exclude:= aexcludeattrib; + infolevel:= ainfolevel; + end; + err1:= sys_opendirstream(dirstream); + result:= err1 = sye_ok; + if not result then begin + if not noexception then begin + syserror(err1,quotechar+dirstream.dirinfo.dirname + '" '); + end + else begin + exit; + end; + end; + try + finalize(info); + fillchar(info,sizeof(info),0); + repeat + bo1:= sys_readdirstream(dirstream,info); + if bo1 then begin + if not ((info.extinfo1.filetype = ft_dir) and ((info.name = dotchar) or + (info.name = '..'))) then begin + bo2:= true; + if assigned(acheckproc) then begin + acheckproc(self,dirstream.dirinfo,info,bo2); + end; + if bo2 then begin + add(info); + end; + end; + end; + until not bo1; + finally + sys_closedirstream(dirstream); + end; + end; + finally + endupdate(); + end; +end; + +function tcustomfiledatalist.adddirectory(const directoryname: filenamety; + ainfolevel: fileinfolevelty; const amask: filenamety; + const aincludeattrib: fileattributesty = [fa_all]; + const aexcludeattrib: fileattributesty = []; + const aoptions: dirstreamoptionsty = []; + const acheckproc: checkfileeventty = nil; + const noexception: boolean = false): boolean; + //amask = '' -> all +var + ar1: filenamearty; +begin + unquotefilename(amask,ar1); + result:= adddirectory(directoryname,ainfolevel,ar1, + aincludeattrib,aexcludeattrib,aoptions,acheckproc,noexception); +end; + +{$ifndef FPC} +function tcustomfiledatalist.adddirectory1(const directoryname: filenamety; + ainfolevel: fileinfolevelty = fil_name; const amask: filenamearty = nil; + const aincludeattrib: fileattributesty = [fa_all]; + const aexcludeattrib: fileattributesty = []; + const aoptions: dirstreamoptionsty = []; + const acheckproc: checkfileeventty = nil; + const noexception: boolean = false): boolean; + //amask = nil -> all, true if ok +begin + result:= adddirectory(directoryname,ainfolevel,amask,aincludeattrib, + aexcludeattrib,aoptions,acheckproc,noexception); +end; + +function tcustomfiledatalist.adddirectory2(const directoryname: filenamety; + ainfolevel: fileinfolevelty; const amask: filenamety; + const aincludeattrib: fileattributesty = [fa_all]; + const aexcludeattrib: fileattributesty = []; + const aoptions: dirstreamoptionsty = []; + const acheckproc: checkfileeventty = nil; + const noexception: boolean = false): boolean; + //amask = '' -> all, true if ok +begin + result:= adddirectory(directoryname,ainfolevel,amask,aincludeattrib, + aexcludeattrib,aoptions,acheckproc,noexception); +end; +{$endif} + +function tcustomfiledatalist.itempo(const index: integer): pfileinfoty; +begin + result:= pfileinfoty(getitempo(index)); +end; + +function tcustomfiledatalist.indexof(const filename: filenamety): integer; + //case sensitive +var + po1: pfileinfoty; + int1: integer; +begin + normalizering; + result:= -1; + po1:= pfileinfoty(fdatapo); + for int1:= 0 to count - 1 do begin + if po1^.name = filename then begin + result:= int1; + break; + end; + inc(po1); + end; +end; + +function tcustomfiledatalist.getitems(index: integer): fileinfoty; +begin + result:= itempo(index)^; +end; + +function tcustomfiledatalist.add(const value: fileinfoty): integer; +begin + result:= adddata(value); +end; + +procedure tcustomfiledatalist.setoptions(const Value: filelistoptionsty); +begin + if foptions <> value then begin + foptions:= filelistoptionsty( + {$ifdef FPC} + setsinglebit(longword(value),longword(foptions),longword(sortflags))); + {$else} + setsinglebit(byte(value),byte(foptions),byte(sortflags))); + {$endif} + + {$ifdef FPC} + case longword(foptions*sortflags) of + {$else} + case byte(foptions*sortflags) of + {$endif} + 1 shl byte(flo_sortname): begin + fsortfunc:= {$ifdef FPC}@{$endif}sortname; + end; + 1 shl byte(flo_sorttime): begin + fsortfunc:= {$ifdef FPC}@{$endif}sorttime; + end; + 1 shl byte(flo_sortsize): begin + fsortfunc:= {$ifdef FPC}@{$endif}sortsize; + end; + else begin + fsortfunc:= nil; + end; + end; + if assigned(fsortfunc) or (flo_sorttype in foptions) then begin + if sorted then begin + sort; + end + else begin + sorted:= true; + end + end + else begin + sorted:= false; + end; + end; +end; + +function tcustomfiledatalist.compare(const l,r): integer; +begin + if flo_sorttype in foptions then begin + result:= integer(fileinfoty(l).extinfo1.filetype) - + integer(fileinfoty(r).extinfo1.filetype); + end + else begin + result:= 0; + end; + if (result = 0) and assigned(fsortfunc) then begin + result:= fsortfunc(fileinfoty(l),fileinfoty(r)); + if result = 0 then begin + if flo_sortname in foptions then begin + result:= sorttime(fileinfoty(l),fileinfoty(r)); + end + else begin + result:= sortname(fileinfoty(l),fileinfoty(r)); + end; + end; + if flo_downsort in foptions then begin + result:= - result; + end; + end; +end; + +function tcustomfiledatalist.sortname(const l, r: fileinfoty): integer; +begin + if flo_casesensitive in foptions then begin +// {$ifdef FPC} +// result:= comparestr(l.name,r.name); //!!!!todo +// {$else} + result:= msecomparestr(l.name,r.name); +// {$endif} + end + else begin +// {$ifdef FPC} +// result:= comparetext(l.name,r.name); //!!!!todo +// {$else} + result:= msecomparetext(l.name,r.name); +// {$endif} + end; +end; + +function tcustomfiledatalist.sortsize(const l, r: fileinfoty): integer; +begin + if l.extinfo1.size > r.extinfo1.size then begin + result:= 1 + end + else begin + if l.extinfo1.size = r.extinfo1.size then begin + result:= 0; + end + else begin + result:= -1; + end; + end; +end; + +function tcustomfiledatalist.sorttime(const l, r: fileinfoty): integer; +begin + if l.extinfo1.modtime > r.extinfo1.modtime then begin + result:= 1 + end + else begin + if l.extinfo1.modtime = r.extinfo1.modtime then begin + result:= 0; + end + else begin + result:= -1; + end; + end; +end; + +function tcustomfiledatalist.isdir(index: integer): boolean; +begin + result:= fa_dir in itempo(index)^.extinfo1.attributes; +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/msefloattostr.pas b/mseide-msegui/lib/common/kernel/msefloattostr.pas new file mode 100644 index 0000000..072d23b --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msefloattostr.pas @@ -0,0 +1,621 @@ +{ MSEgui Copyright (c) 1999-2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msefloattostr; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msestrings,msetypes; + +const + expochar = msechar('E'); + +type + floatstringmodety = (fsm_default,fsm_fix,fsm_sci,fsm_engfix,fsm_engflo, + fsm_engsymfix,fsm_engsymflo); +// {$ifndef FPC} +// qword = int64; +// {$endif} + doublerecty = packed record //little endian + case integer of + 0: (by0,by1,by2,by3,by4,by5,by6,by7: byte); + 1: (wo0,wo1,wo2,wo3: word); + 2: (lwo0,lwo1: longword); + 3: (qwo0: qword); + end; + +function doubletostring(const value: double; const precision: integer = 0; + const mode: floatstringmodety = fsm_default; + const decimalsep: msechar = '.'; + const thousandsep: msechar = #0): msestring; + //precision <= 0 -> remove trailing 0 + //precision = 0 in fsm_default mode = maximal precision + +function tryintexp10(aexp: integer; out value: double): boolean; +function intexp10(aexp: integer): double; + +implementation +uses + sysutils; + +const + binexps: array[0..8] of double = (1e1,1e2,1e4,1e8,1e16,1e32,1e64,1e128,1e256); + binnegexps: array[0..8] of double = + (1e-1,1e-2,1e-4,1e-8,1e-16,1e-32,1e-64,1e-128,1e-256); + +type + expsymty = + // -8 -7 -6 -5 -4 -3 -2 -1 0 + (exs_yocto=-8,exs_zepto,exs_atto,exs_femto,exs_pico,exs_nano,exs_micro,exs_milli, +// 0 + exs_none, +// 1 2 3 4 5 6 7 8 + exs_kilo,exs_mega,exs_giga,exs_tera,exs_peta,exs_exa,exs_zetta,exs_yotta); + +const + expsyms: array[expsymty] of msechar = + ('y','z','a','f','p','n','u','m', + ' ', + 'k','M','G','T','P','E','Z','Y'); + +function tryintexp10(aexp: integer; out value: double): boolean; +var + do1: double; + int1,int2,int3: integer; +begin + result:= true; + if aexp = 0 then begin + value:= 1; + exit; + end; + do1:= 1; + int3:= 1; + int2:= abs(aexp); + if int2 <= $1ff then begin + if aexp < 0 then begin + for int1:= 0 to 8 do begin + if int2 and int3 <> 0 then begin + do1:= do1 * binnegexps[int1]; + end; + int3:= int3 shl 1; + end; + end + else begin + for int1:= 0 to 8 do begin + if int2 and int3 <> 0 then begin + do1:= do1 * binexps[int1]; + end; + int3:= int3 shl 1; + end; + end; + value:= do1; + end + else begin + result:= false; + end; +end; + +function intexp10(aexp: integer): double; +begin + if not tryintexp10(aexp,result) then begin + raise exception.create('Exponent overflow'); + end; +end; + +function doubletostring1(value: double; out msbcarry: boolean; + precision: integer; mode: floatstringmodety = fsm_default; + decimalsep: msechar = '.'; thousandsep: msechar = #0): msestring; + //format double: + // 1 11 52 + //|s| e | f | + +const + maxdigits = 17; + defaultprecision = maxdigits-2; + +type + bufferty = array[0..30] of msechar; + + function getfixoverflowvalue: msestring; + var + int1: integer; + begin +// if precision = 0 then begin + int1:= defaultprecision-1; + if precision < 0 then begin + int1:= -int1; + end; +// end +// else begin +// int1:= precision; +// end; + result:= doubletostring(value,int1,fsm_sci,decimalsep,thousandsep); + end; + + procedure checkcarry(start: byte; var dest: bufferty); + var + int1: integer; + begin + for int1:= start downto 1 do begin + if dest[int1] <= '9' then begin + break; + end; + dec(dest[int1],10); + inc(dest[int1-1]); //carry + end; + end; + +const +{$ifndef FPC} + lsbrounding = 2.2517998136852482e015; +{$else} +// lsbrounding = exp(51*ln(2)); + lsbrounding = flo64($0008000000000000); //2^51 +{$endif} + expo0max = 1-1/lsbrounding; + expo1max = 10-10/lsbrounding; + expo3max = 1000-1000/lsbrounding; + expmask = $7ff0; //for wo3 + halfexp = (1023-1) shl 4; //value >= 0.5 for wo3 +{$ifndef FPC} + exp2to10 = 0.30102999566398121; +{$else} + exp2to10 = ln(2)/ln(10); +{$endif} + exps: array[0..maxdigits] of double = + (1e0,1e1,1e2,1e3,1e4,1e5,1e6,1e7,1e8,1e9,1e10, + 1e11,1e12,1e13,1e14,1e15,1e16,1e17 + ); + lsbroundings: array[0..maxdigits] of double = + (1e0/lsbrounding,1e1/lsbrounding,1e2/lsbrounding,1e3/lsbrounding, + 1e4/lsbrounding,1e5/lsbrounding,1e6/lsbrounding,1e7/lsbrounding, + 1e8/lsbrounding,1e9/lsbrounding,1e10/lsbrounding,1e11/lsbrounding, + 1e12/lsbrounding,1e13/lsbrounding,1e14/lsbrounding,1e15/lsbrounding, + 1e16/lsbrounding,1e17/lsbrounding + ); + +var + buffer: bufferty; + neg: boolean; + nan: boolean; + inf: boolean; + defaultmode: boolean; + exp: smallint; + do1: double; + int1,int2,int3,int4: integer; + lastindex,intdigits,leadingzeros,space,thousandsepcount: integer; + po1: pmsechar; + mode1: floatstringmodety; + preci: integer; + +begin + msbcarry:= false; + preci:= abs(precision); + with doublerecty(value) do begin + neg:= by7 and $80 <> 0; + by7:= by7 and $7f; //remove sign + {$ifndef FPC} + exp:= (wo3 and $7ff0) shr 4; + {$else} + exp:= (wo3 and %0111111111110000) shr 4; + {$endif} + nan:= false; + inf:= false; + if exp = 2047 then begin + if (lwo0 <> 0) or (lwo1 and $000fffff <> 0) then begin + nan:= true; + end + else begin + inf:= true; + end; + end; + end; + defaultmode:= mode = fsm_default; + if nan then begin + result:= 'Nan'; + end + else begin + if inf then begin + if neg then begin + result:= '-Inf'; + end + else begin + result:= '+Inf'; + end; + end + else begin + if exp = 0 then begin // value = 0 + if preci >= maxdigits then begin + preci:= maxdigits; + end; + case mode of + fsm_sci,fsm_engfix,fsm_engflo,fsm_engsymfix,fsm_engsymflo: begin + if preci = 0 then begin + if mode in [fsm_engsymfix,fsm_engsymflo] then begin + result:= '0 '; + end + else begin + result:= '0E+000'; + end; + exit; + end; + if mode in [fsm_engsymfix,fsm_engsymflo] then begin + int2:= preci+2; + end + else begin + int2:= preci+6; + end; + setlength(result,int2+1); + for int1:= 0 to int2 do begin + pmsecharaty(result)^[int1]:= '0'; + end; + if mode in [fsm_engsymfix,fsm_engsymflo] then begin + pmsecharaty(result)^[int2]:= ' '; + end + else begin + pmsecharaty(result)^[int2-4]:= expochar; + pmsecharaty(result)^[int2-3]:= '+'; + end; + end; + else begin //fix format + if (preci = 0) or defaultmode then begin + result:= '0'; + exit; + end + else begin + int2:= preci+1; + setlength(result,int2+1); + for int1:= 0 to int2 do begin + pmsecharaty(result)^[int1]:= '0'; + end; + end; + end; + end; + pmsecharaty(result)^[1]:= decimalsep; + exit; + end; + + exp:= exp - 1023; //value <> 0 + do1:= exp*exp2to10; + intdigits:= trunc(do1); + if defaultmode then begin + if preci = 0 then begin + preci:= maxdigits; + end; + if (value < 1e-6) or (value >= 1e15) then begin + mode:= fsm_sci; + end; + end; + + if mode >= fsm_sci then begin //exp format + if intdigits < 0 then begin + dec(intdigits); //trunk -> floor + end; + int3:= intdigits; + if mode in [fsm_engflo,fsm_engsymflo] then begin + do1:= value / intexp10(intdigits); + if do1 >= expo1max then begin + inc(intdigits); //correct overflow for precision correction + end; + end; + + if mode >= fsm_engfix then begin + if int3 < 0 then begin + int3:= int3 + ((-int3) mod 3) - 3; + end + else begin + int3:= int3 - (int3 mod 3); + end; + end; + if int3 < 0 then begin + do1:= intexp10(-int3); + do1:= value*do1; + end + else begin + do1:= intexp10(int3); + do1:= value/do1; + end; + if (mode < fsm_engfix) then begin //fsm_sci + if (do1 >= expo1max) then begin + do1:= do1 / exps[1]; + inc(int3); + end + else begin + if (do1 < exps[0]) then begin + do1:= do1 * exps[1]; + dec(int3); + end + end; + end + else begin //fsm_engfix,fsm_engflo,fsm_engsyfix,fsm_engsyflo + if (do1 >= expo3max) then begin + do1:= do1 / exps[3]; + inc(int3,3); + end + else begin + if (do1 < exps[0]) then begin + do1:= do1 * exps[3]; + dec(int3,3); + end + end; + end; +// if neg then begin +// do1:= -do1; +// end; + if mode in [fsm_engflo,fsm_engsymflo] then begin + if (intdigits = 0) and (int3 < 0)then begin + dec(intdigits); //trunc -> floor + end; + preci:= preci - intdigits + int3; + if preci < 0 then begin + preci:= 0; + end; + end; + if defaultmode and (precision = 0) then begin + mode1:= fsm_default; + end + else begin + mode1:= fsm_fix; + end; + int1:= preci; + if (precision < 0) or defaultmode and (precision = 0) then begin + int1:= -int1; + end; + result:= doubletostring1(do1,msbcarry,int1,mode1,decimalsep); //get mantissa digits + if msbcarry then begin + if mode1 = fsm_fix then begin + if (int1 <= 0) then begin //999.99-> 1000.00 -> 1000 (trimmed trailing 0) + if (mode >= fsm_engfix) then begin +// int4:= 3; +// if result[1] = '-' then begin +// inc(int4); +// end; + if length(result) > 3{int4} then begin + if precision > 0 then begin + setlength(result,length(result)-3+precision+1); + result[length(result)-precision]:= decimalsep; + end + else begin + setlength(result,length(result)-3); + end; + int3:= int3 + 3; //correct carry, 999.99-> 1000 -> 1 + end; + end + else begin + setlength(result,length(result)-1); + inc(int3); //correct carry, 9.9999-> 10 -> 1 + end; + end + else begin + if mode >= fsm_engfix then begin + if (length(result) >= 5) and (result[5] = decimalsep) then begin + pmsecharaty(result)^[4]:= result[4]; + pmsecharaty(result)^[3]:= result[3]; + pmsecharaty(result)^[2]:= result[2]; + pmsecharaty(result)^[1]:= decimalsep; + if (mode = fsm_engfix) or (mode = fsm_engsymfix) then begin + setlength(result,length(result)-3); //correct carry, 999.999-> 1000.000 -> 1.000 + end + else begin + setlength(result,length(result)-1); //correct carry, 999.999-> 1000.000 -> 1.00000 + end; + int3:= int3+3; + end + else begin + if (mode = fsm_engflo) or (mode = fsm_engsymflo) then begin + if length(result) > precision + 2 then begin + setlength(result,length(result)-1); //correct carry, 99.999-> 100.000 -> 100.00 + end; + end + end; + end + else begin + if length(result) > precision + 2 then begin + pmsecharaty(result)^[2]:= result[2]; + pmsecharaty(result)^[1]:= decimalsep; + setlength(result,length(result)-1); //correct carry, 9.999 ->10.000 -> 1.000 + inc(int3); + end; + end; + end; + end; + end; + if neg then begin + result:= '-'+result; + end; + int1:= int3 div 3; + if (mode >= fsm_engsymfix) and (int1 >= ord(low(expsymty))) and + (int1 <= ord(high(expsymty))) then begin + int2:= length(result)+1; + setlength(result,int2); + (pmsechar(pointer(result))+int2-1)^:= expsyms[expsymty(int1)]; + //exponent symbol + end + else begin + int2:= length(result)+5; + setlength(result,int2); + po1:= pmsechar(pointer(result))+int2; + if int3 < 0 then begin + (po1-4)^:= '-'; + end + else begin + (po1-4)^:= '+'; + end; + int3:= abs(int3); + for int1:= 0 to 2 do begin + dec(po1); + po1^:= msechar(ord('0')+(int3 mod 10)); + int3:= int3 div 10; + end; + (po1-2)^:= expochar; + end; + exit; + end; //exp format ^^^ + + if value > 999999999999999 then begin + result:= getfixoverflowvalue; + exit; + end; + lastindex:= intdigits + preci; //fix format + int1:= maxdigits - 1; + if defaultmode then begin + int1:= defaultprecision - 1; + end; + if lastindex > int1 then begin + preci:= preci - lastindex + int1; + if (preci < 0) then begin + result:= getfixoverflowvalue; + exit; + end; + lastindex:= int1; + end; + inc(lastindex); + buffer[0]:= '0'; //for carry + if intdigits < 0 then begin + do1:= value*exps[-intdigits]; + end + else begin + do1:= value/exps[intdigits]; //value 0.1..10 + end; + + if (exp = -1) and (do1 >= expo0max) then begin + exp:= 0; //fix for no int test + end; + + if lastindex >= 1 then begin //calculate numbers + for int1:= 1 to lastindex do begin + int2:= trunc(do1); + buffer[int1]:= msechar(int2+ord('0')); + checkcarry(int1,buffer); + do1:= frac(do1)*10; + end; + msbcarry:= buffer[0] = '0'; + if do1 > 0 then begin + do1:= do1 - 5 + lsbroundings[lastindex]; //round up lsb + if (do1 > 0) then begin + inc(buffer[lastindex]); + checkcarry(lastindex,buffer); + end; + end; + msbcarry:= msbcarry and (buffer[0] <> '0'); + if (precision < 0) or (defaultmode and (precision = 0)) then begin + int2:= lastindex - preci + 1; //remove trayling zeros + for int1:= lastindex downto int2 do begin + if (buffer[int1] <> '0') then begin + preci:= preci - lastindex + int1; + lastindex:= int1; + break; + end; + if int1 = int2 then begin + preci:= 0; + lastindex:= int1-1; + end; + end; + end; + end + else begin + lastindex:= 0; //single '0' + end; + + space:= 0; //update string + if neg then begin + inc(space); //add space for sign + end; + if preci > 0 then begin + inc(space); //add space for decimal separator + end; + + if exp < 0 then begin //<1, no int + space:= space + preci; + setlength(result,space+1); //add space for leading zero + po1:= pmsechar(pointer(result))+space; + if lastindex > space then begin + lastindex:= space; + end; + for int1:= lastindex downto 0 do begin + po1^:= buffer[int1]; + dec(po1); + end; + for int1:= space - lastindex - 1 downto 0 do begin + po1^:= '0'; //fill rest with '0' + dec(po1); + end; + if preci > 0 then begin + inc(po1,space - preci + 1); //decimal separator + (po1-1)^:= po1^; //move possible carry + po1^:= decimalsep; + end; + end + else begin //>1 with int + leadingzeros:= 0; + while buffer[leadingzeros] = '0' do begin + inc(leadingzeros); //remove leading '0' + end; + thousandsepcount:= 0; + if thousandsep <> #0 then begin + thousandsepcount:= (lastindex-leadingzeros-preci) div 3; + space:= space + thousandsepcount; + end; + space:= space + lastindex - leadingzeros; + setlength(result,space+1); + po1:= pmsechar(pointer(result)) + space; + if preci > 0 then begin + for int3:= lastindex downto lastindex - preci + 1 do begin + po1^:= buffer[int3]; //fract + dec(po1); + end; + po1^:= decimalsep; + dec(po1); + for int3:= lastindex - preci downto leadingzeros do begin + po1^:= buffer[int3]; //int + dec(po1); + end; + end + else begin + for int3:= lastindex downto leadingzeros do begin + po1^:= buffer[int3]; //int + dec(po1); + end; + end; + if thousandsepcount > 0 then begin + int3:= space-lastindex+leadingzeros; //first int char + int4:= space - preci; //last int char + if preci > 0 then begin + dec(int3); //thousand separator + dec(int4); + end; + po1:= pmsechar(pointer(result)) + int3 - thousandsepcount; + for int3:= int3 to space - preci - 3 do begin + po1^:= pmsecharaty(result)^[int3]; + inc(po1); + if (int3 - int4) mod 3 = 0 then begin + po1^:= thousandsep; + inc(po1); + end; + end; + end; + end; + if neg then begin + pmsechar(pointer(result))^:= '-'; + end; + end; + end; +end; + +function doubletostring(const value: double; const precision: integer = 0; + const mode: floatstringmodety = fsm_default; + const decimalsep: msechar = '.'; + const thousandsep: msechar = #0): msestring; +var + bo1: boolean; +begin + result:= doubletostring1(value,bo1,precision,mode,decimalsep,thousandsep); +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/mseformatstr.pas b/mseide-msegui/lib/common/kernel/mseformatstr.pas new file mode 100644 index 0000000..be1bc67 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseformatstr.pas @@ -0,0 +1,5891 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseformatstr; //stringwandelroutinen 31.5.99 mse + +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$goto on}{$endif} + +interface +uses + classes,mclasses,msetypes,msestrings,SysUtils,msemacros,mseglob + {$ifndef FPC},classes_del{$endif}; +{$ifdef FPC}{$define hasqword}{$endif} +{$ifdef mswindows}{$define hasqword}{$endif} +type + dateconvertty = (dc_none,dc_tolocal,dc_toutc); + + TMonthNameArraymse = array[1..12] of msestring; + TWeekNameArraymse = array[1..7] of msestring; + + TFormatSettingsmse = record + CurrencyFormat: Byte; + NegCurrFormat: Byte; + ThousandSeparator: mseChar; + DecimalSeparator: mseChar; + CurrencyDecimals: Byte; + DateSeparator: mseChar; + TimeSeparator: mseChar; + ListSeparator: mseChar; + CurrencyString: msestring; + ShortDateFormat: msestring; + LongDateFormat: msestring; + TimeAMString: msestring; + TimePMString: msestring; + ShortTimeFormat: msestring; + LongTimeFormat: msestring; + ShortMonthNames: TMonthNameArraymse; + LongMonthNames: TMonthNameArraymse; + ShortDayNames: TWeekNameArraymse; + LongDayNames: TWeekNameArraymse; + TwoDigitYearCenturyWindow: Word; + end; + + tformatmacrolist = class(tmacrolist) + public + procedure addmac(const aname: msestring; const avalue: msestring; + const ahandler: macrohandlerty = nil); + end; + +var + DefaultFormatSettingsmse : TFormatSettingsmse = ( + CurrencyFormat: 1; + NegCurrFormat: 5; + ThousandSeparator: ','; + DecimalSeparator: '.'; + CurrencyDecimals: 2; + DateSeparator: '-'; + TimeSeparator: ':'; + ListSeparator: ','; + CurrencyString: '$'; + ShortDateFormat: 'd/m/y'; + LongDateFormat: 'dd" "mmmm" "yyyy'; + TimeAMString: 'AM'; + TimePMString: 'PM'; + ShortTimeFormat: 'hh:nn'; + LongTimeFormat: 'hh:nn:ss'; + ShortMonthNames: ('Jan','Feb','Mar','Apr','May','Jun', + 'Jul','Aug','Sep','Oct','Nov','Dec'); + LongMonthNames: ('January','February','March','April','May','June', + 'July','August','September','October','November', + 'December'); + ShortDayNames: ('Sun','Mon','Tue','Wed','Thu','Fri','Sat'); + LongDayNames: ('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday', + 'Saturday'); + TwoDigitYearCenturyWindow: 50; + ); + +const +// noformatsettings = 14.5; //rtlversion + noformatsettings = 15; //rtlversion + fc_keinplatzchar = '*'; + nullen = '000000000000000000000000000000'; + msenullen = msestring('000000000000000000000000000000'); + msespace = msestring(' '); + +type + numbasety = (nb_bin,nb_oct,nb_dec,nb_hex); + +function lstring(const s: string; const minwidth: integer): string; +function rstring(const s: string; const minwidth: integer): string; + +{$warnings off} + // ${THEMACRO} checks formatmacros, macro name case sensitive +{$warnings on} + +function formatdatetimemse(const formatstr: msestring; const datetime: tdatetime; + const formatsettings: tformatsettingsmse): msestring; +// 'I' = ISO date, 'II' ISO datetime, 'III' ISO datetime + ms +function formatdatetimemse(const formatstr: msestring; + const datetime: tdatetime): msestring; +function formatdatetimemse(const datetime: tdatetime; formatstr: msestring; + const formatsettings: tformatsettingsmse): msestring; +// 'I' = ISO date, 'II' ISO datetime, 'III' ISO datetime + ms +function formatdatetimemse(const datetime: tdatetime; + const formatstr: msestring): msestring; + +function formatfloatmse(value: double; format: msestring; + const formatsettings: tformatsettingsmse; + const dot: boolean = false): msestring; overload; + //dot = true -> always '.' as decimal separator + //formatstring: + // formats for positive, negative and zero value can be separated by ; + // ' and " qoted text as is + // c -> currencyformat + // C -> currencyformat without currencyname + // + // + 0 or number digit + // |+ show defaultformatsettingsmse.thousandseparator + // ||+ defaultformatsettingsmse.decimalseparator or '.' if dot = true + // ||| removed if there are no fract digits + // |||+ 0 or number digit + // 0,.0 + // + // + space or number digit + // | + removed or number digit + // #.# + // + // + scientific notation with 'e' + // |+ remove '+' from positive exponent + // ||+++ 0 or exponent digit + // 0.0e-000 + // + // + show '+' of positive exponent + // 0.0e+ + // + // + scientific notation with 'E' + // 0.0E + // + // + engeneering notation with 'e', exponent = n*3 + // | + // 0.0f + // + // ++++++ mantissa - 1 digits max + // 0..000###f + // +++ mantissa - 1 digits min + // + // + engeneering notation with 'E', exponent = n*3 + // 0.0F + // + // + engeneering notation with metric system prefixes, exponent = n*3 + // | no space for 10^0 + // 0.0g + // + // + engeneering notation with metric system prefixes, exponent = n*3 + // | space for 10^0 + // 0.0G + // + // examples for value = 12345.678 + // '0.0' -> '12345.7' + // '0.000e -> '1.235e4' + // '0.000f -> '12.346e3' + // '0.000g -> '12.346k' + // '0.###f -> '12.35e3' + +function formatfloatmse(const value: double; const format: msestring; + const dot: boolean = false): msestring; overload; +function realtostrmse(const value: double; + const dot: boolean = false): msestring; +function realtytostrmse(const value: double; + const dot: boolean = false): msestring; + +function inttostr(const value: integer): string; +function inttostr(const value: longword): string; +function inttostr(const value: int64): string; +function inttostr(const value: qword): string; + +function inttostrmse(const value: integer): msestring; overload; +function inttostrmse(const value: longword): msestring; overload; +function inttostrmse(const value: int64): msestring; overload; +function inttostrmse(const value: qword): msestring; overload; + +function trystrtodouble(const s: lstringty; out value: double; + const decimalseparator: char): boolean; overload; +function trystrtodouble(const s: lmsestringty; out value: double; + const decimalseparator: msechar): boolean; overload; +function trystrtodouble(const s: string; out value: double; + const decimalseparator: char): boolean; overload; +function trystrtodouble(const s: msestring; out value: double; + const decimalseparator: msechar): boolean; overload; +function strtodouble(const s: string; + const decimalseparator: char): double; +function strtodouble(const s: msestring; + const decimalseparator: msechar): double; +function trystrtodouble(const s: string; out value: double): boolean; overload; +function trystrtodouble(const s: msestring; out value: double): boolean; overload; +function strtodouble(const s: string): double; +function strtodouble(const s: msestring): double; + +function realtostr(const value: double): string; //immer'.' als separator +function strtoreal(const s: string): double; //immer'.' als separator +function trystrtoreal(const s: string; out value: real): boolean; + //immer'.' als separator +function strtoreal(const s: msestring): double; //immer'.' als separator +function trystrtoreal(const s: msestring; out value: real): boolean; + //immer'.' als separator +function currencytostr(const avalue: currency): string; + //always '.' as as decimal separator +function currencytostrmse(const avalue: currency): msestring; + //always '.' as as decimal separator + +function trystrtorealty(const ein: msestring; out value: realty; + forcevalue: boolean = false): boolean; +function strtorealty(const ein: string; forcevalue: boolean = false): realty; +function strtorealty(const ein: msestring; forcevalue: boolean = false): realty; +function strtorealtydot(const ein: string): realty; +function strtorealtydot(const ein: msestring): realty; +function trystrtorealtydot(const ein: string; out value: realty): boolean; +function trystrtorealtydot(const ein: msestring; out value: realty): boolean; +//function realtytostr(const val: realty; const format: msestring = ''): msestring; +function realtytostr(const val: realty; const format: msestring = ''; + const scale: real = 1): msestring; + deprecated 'use realtytostring() instead'; + //use realtytostring() instead +function realtytostring(const val: realty; const format: msestring = ''; + const scale: real = 1): msestring; +function realtytostrrange(const val: realty; const format: msestring = ''; + const range: real = 1; + const offset: real = 0): msestring; +function realtytostrdot(const val: realty): string; +function realtytostrdotmse(const val: realty): msestring; + +function wordtostr(const avalue: longword): string; + +function bytetohex(const inp: byte): string; + //wandelt byte in zwei ascii hexzeichen +function wordtohex(const inp: word; lsbfirst: boolean = false): string; + //wandelt word in vier ascii hexzeichen + +function valtohex(const avalue: byte): string; overload; +function valtohex(const avalue: word): string; overload; +function valtohex(const avalue: longword): string; overload; +function valtohex(const avalue: qword): string; overload; + +function dectostr(const inp: integer; digits: integer): string; overload; + //leading zeroes if digits < 0 +function dectostr(const inp: int64; digits: integer): string; overload; + //leading zeroes if digits < 0 +function bintostr(inp: longword; digits: integer): string; overload; + //convert longword to binstring, digits = bit count +function bintostr(inp: qword; digits: integer): string; overload; + //convert longword to binstring, digits = bit count +function octtostr(inp: longword; digits: integer): string; overload; + //convert longword to octaltring, digits = octet count +function octtostr(inp: qword; digits: integer): string; overload; + //convert longword to octaltring, digits = octet count +function hextostr(inp: longword; + digits: integer = 2*sizeof(longword)): string; overload; + //convert longword to hexstring, digits = nibble count, 0 -> variable +function hextostr(inp: qword; + digits: integer = 2*sizeof(qword)): string; overload; + //convert qword to hexstring, digits = nibble count, 0 -> variable +function hextostr(const inp: pointer; + digits: integer = 2*sizeof(pointer)): string; overload; + //convert pointer to hexstring, digits = nibble count, 0 -> variable +function hextostrmse(inp: longword; + digits: integer = 2*sizeof(longword)): msestring; overload; + //convert longword to hexstring, digits = nibble count, 0 -> variable +function hextostrmse(inp: qword; + digits: integer = 2*sizeof(qword)): msestring; overload; + //convert qword to hexstring, digits = nibble count, 0 -> variable +function hextostrmse(const inp: pointer; + digits: integer = 2*sizeof(pointer)): msestring; overload; + //convert pointer to hexstring, digits = nibble count, 0 -> variable +function hextocstr(const inp: longword; stellen: integer): string; overload; + //convert longword to 0x..., digits = nibble count, 0 -> variable +function hextocstr(const inp: qword; stellen: integer): string; overload; + //convert longword to 0x..., digits = nibble count, 0 -> variable +function ptruinttocstr(inp: ptruint): string; overload; + //convert ptruint to 0x... +function qwordtocstr(inp: qword): string; overload; + //convert ptruint to 0x... +function intvaluetostr(const value: integer; const base: numbasety = nb_dec; + const bitcount: integer = 32): string; overload; +function intvaluetostr(const value: int64; const base: numbasety = nb_dec; + const bitcount: integer = 64): string; overload; + +function trystrtoptruint(const inp: string; out value: ptruint): boolean; +function strtoptruint(const inp: string): ptruint; + +function trystrtobin(const inp: string; out value: longword): boolean; +function strtobin(const inp: string): longword; +function trystrtooct(const inp: string; out value: longword): boolean; +function strtooct(const inp: string): longword; +function trystrtodec(const inp: string; out value: longword): boolean; +function strtodec(const inp: string): longword; +function trystrtohex(const inp: pchar; const len: int32; + out value: longword): boolean; +function trystrtohex(const inp: lstringty; out value: longword): boolean; +function trystrtohex(const inp: string; out value: longword): boolean; +function trystrtohex(const inp: msestring; out value: longword): boolean; +function strtohex(const inp: string): longword; +function strtohex(const inp: msestring): longword; + +function trystrtobin64(const inp: string; out value: qword): boolean; +function strtobin64(const inp: string): qword; +function trystrtooct64(const inp: string; out value: qword): boolean; +function strtooct64(const inp: string): qword; +function trystrtodec64(const inp: string; out value: qword): boolean; +function strtodec64(const inp: string): qword; +function trystrtohex64(const inp: string; out value: qword): boolean; +function strtohex64(const inp: string): qword; + + +function trystrtoint(const text: pchar; const len: int32; + out value: integer): boolean; +function trystrtoint(const text: lstringty; out value: integer): boolean; +function trystrtoint(const text: string; out value: integer): boolean; +function trystrtoint(const text: msestring; out value: integer): boolean; +function strtoint(const text: string): integer; +function strtoint(const text: msestring): integer; +function trystrtoint(const text: string; out value: longword): boolean; +function trystrtoint(const text: msestring; out value: longword): boolean; +function strtoint64(const text: string): int64; +function strtoint64(const text: msestring): int64; +function trystrtoint64(const text: lstringty; out value: int64): boolean; +function trystrtoint64(const text: string; out value: int64): boolean; +function trystrtoint64(const text: msestring; out value: int64): boolean; +function trystrtoqword(const text: string; out value: qword): boolean; +function trystrtoqword(const text: msestring; out value: qword): boolean; + +function trystrtointvalue(const inp: string; + out value: longword): boolean; overload; + //% prefix -> bin, & -> oct, # -> dez, $ -> hex 0x -> hex +function strtointvalue(const inp: string): longword; overload; +function trystrtointvalue(const text: msestring; base: numbasety; + out value: longword): boolean; overload; +function strtointvalue(const text: msestring; base: numbasety): longword; overload; + +function trystrtointvalue64(const inp: string; + out value: qword): boolean; overload; + //% prefix -> bin, & -> oct, # -> dez, $ -> hex 0x -> hex +function strtointvalue64(const inp: string): qword; overload; +function trystrtointvalue64(const text: msestring; base: numbasety; + out value: qword): boolean; overload; +function strtointvalue64(const text: msestring; base: numbasety): qword; overload; + + +function bytestrtostr(const inp: ansistring; base: numbasety = nb_hex; + spacechar: char = #0): string; + //wandelt bytefolge in ascii hexstring, spacechar #0 -> none +function bytestrtobin(const inp: ansistring; abstand: boolean): string; + //wandelt bytefolge in ascii binstring, + // letztes zeichen = anzahl gueltige bits in letztem byte +function bitmaske(const data: ansistring): integer; //anzahl gueltige bits in vorletztem byte +function bitcount(const data: ansistring): integer; //anzahl gueltige bits + +function bcdtostr(inp: byte): string; + //wandelt bcdwert in zwei ascii zeichen +function bytetobcd(inp: byte): word; + //wandelt byte in bcdwert +function bcdtobyte(inp: byte): byte; + //wandelt bcdbyte in byte +function strtobytestr(inp: string): ansistring; + //wandelt hex asciistring in bytefolge +function strtobinstr(inp: string): ansistring; + //wandelt bin asciistring in bytefolge +function strtobytes(const inp: string; out dest: bytearty): boolean; +//msb first, true if ok + +function inttostrlen(inp: integer; len: integer; + rechtsbuendig: boolean = true; fillchar: char = ' '): ansistring; + //wandelt integer in string fester laenge +function inttostrlenmse(inp: integer; len: integer; + rechtsbuendig: boolean = true; fillchar: msechar = ' '): msestring; +{ +function filename(inp: string): string; +//bringt filenamen ohne pfad und extension +function replaceext(inp,ext: string): string; +//ersetzt fileextension +} +function bcdtoint(inp: byte): integer; +function inttobcd(inp: integer): byte; + +function stringtotime(const avalue: msestring; + const convert: dateconvertty = dc_none): tdatetime; overload; +function stringtotime(const avalue: msestring; + const aformat: msestring; + const convert: dateconvertty = dc_none): tdatetime; overload; +function trystringtotime(const text: msestring; + out value: tdatetime; + const convert: dateconvertty = dc_none): boolean; overload; +function trystringtotime(const text: msestring; + const aformat: msestring; out value: tdatetime; + const convert: dateconvertty = dc_none): boolean; overload; + +function timetostring(const avalue: tdatetime; + const format: msestring = 't'): msestring; +function datetostring(const avalue: tdatetime; + const format: msestring = 'c'): msestring; +function stringtodate(const avalue: msestring; + const convert: dateconvertty = dc_none): tdatetime; overload; +function stringtodate(const avalue: msestring; + const aformat: msestring; + const convert: dateconvertty = dc_none): tdatetime; overload; +function trystringtodate(const text: msestring; out value: tdatetime; + const convert: dateconvertty = dc_none): boolean; overload; +function trystringtodate(const text: msestring; + const aformat: msestring; + out value: tdatetime; + const convert: dateconvertty = dc_none): boolean; overload; +function datetimetostring(const avalue: tdatetime; + const format: msestring = 'c'): msestring; +function stringtodatetime(const avalue: msestring; + const convert: dateconvertty = dc_none): tdatetime; overload; +function stringtodatetime(const avalue: msestring; + const aformat: msestring; + const convert: dateconvertty = dc_none): tdatetime; overload; +function trystringtodatetime(const text: msestring; + out value: tdatetime; + const convert: dateconvertty = dc_none): boolean; overload; +function trystringtodatetime(const text: msestring; + aformat: msestring; + out value: tdatetime; + const convert: dateconvertty = dc_none): boolean; overload; +procedure checkdateconvert(const convert: dateconvertty; var value: tdatetime); +procedure checkdatereconvert(const convert: dateconvertty; var value: tdatetime); + +function timemse(const value: tdatetime): tdatetime; + //bringt timeanteil im mseformat + +function cstringtostring(inp: pchar): string; overload; +function cstringtostring(const inp: string): string; overload; +function cstringtostringvar(var inp: pchar): string; +function stringtocstring(const inp: msestring): string; overload; +function stringtocstring(const inp: pmsechar; + const count: integer): string; overload; +function stringtopascalstring(const value: msestring; + const maxlinelength: int32 = 0): string; + //0 -> no limit +function pascalstringtostring(const value: string): msestring; +function trypascalstringtostring(const value: string; + out res: msestring ): boolean; +function getpascalstring(var value: pchar): msestring; + +function encodebase64(const abinary: string; + const maxlinelength: integer = defaultbase64linelength): string; overload; +function encodebase64(const abinary: pbyte; acount: integer; + const maxlinelength: integer = defaultbase64linelength): string; overload; +function decodebase64(const atext: string): string; +function encodexmlstring(const value: msestring): msestring; + +{$ifndef FPC} +function TryStrToQWord(const S: string; out Value: QWord): Boolean; +{$endif} + +procedure msestrtotvarrec(const value: ansistring; out varrec: tvarrec); +procedure msestrtotvarrec(const value: msestring; out varrec: tvarrec); + +function tvarrectoansistring(const value: tvarrec): ansistring; +function tvarrectomsestring(const value: tvarrec): msestring; + +function formatmse(const fmt: msestring; const args: array of const): msestring; +function formatmse(const fmt: msestring; const args: array of const; + const formatsettings: tformatsettingsmse): msestring; + +function formatmacros: tformatmacrolist; +procedure clearformatmacros; + +{$ifdef FPC} + {$define withformatsettings} +{$endif} +{$ifdef mswindows} + {$define withformatsettings} +{$endif} + +var + defaultformatsettingsdot: tformatsettings; //mit '.' als dezitrenner + +const + charhex: array[0..15] of char = + ('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'); + charhexlower: array[0..15] of char = + ('0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'); + hexchars: array[char] of byte = ( + $80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80, //0 + $80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80, //1 + $80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80, //2 + $00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$80,$80,$80,$80,$80,$80, //3 + $80,$0A,$0B,$0C,$0D,$0E,$0F,$80,$80,$80,$80,$80,$80,$80,$80,$80, //4 + $80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80, //5 + $80,$0a,$0b,$0c,$0d,$0e,$0f,$80,$80,$80,$80,$80,$80,$80,$80,$80, //6 + $80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80, //7 + $80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80, //8 + $80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80, //9 + $80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80, //a + $80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80, //b + $80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80, //c + $80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80, //d + $80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80, //e + $80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80);//f + + base64mask = $3f; + base64encoding: array[0..63] of char = ( +//0 1 2 3 4 5 6 7 8 9 a b c d e f + 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P', //00 + 'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f', //10 + 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v', //20 + 'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/');//30 + + base64decoding: array[0..255] of byte = ( +//0 1 2 3 4 5 6 7 8 9 a b c d e f + $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff, //00 + $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff, //10 +// '+' '/' + $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$3e,$ff,$ff,$ff,$3f, //20 +//'0','1','2','3','4','5','6','7','8','9', + $34,$35,$36,$37,$38,$39,$3a,$3b,$3c,$3d,$ff,$ff,$ff,$ff,$ff,$ff, //30 +// 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O', + $ff,$00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$0a,$0b,$0c,$0d,$0e, //40 +//'P','Q','R','S','T','U','V','W','X','Y','Z', + $0f,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$ff,$ff,$ff,$ff,$ff, //50 +// 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o', + $ff,$1a,$1b,$1c,$1d,$1e,$1f,$20,$21,$22,$23,$24,$25,$26,$27,$28, //60 +//'p','q','r','s','t','u','v','w','x','y','z', + $29,$2a,$2b,$2c,$2d,$2e,$2f,$30,$31,$32,$33,$ff,$ff,$ff,$ff,$ff, //70 + $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff, //80 + $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff, //90 + $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff, //a0 + $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff, //b0 + $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff, //c0 + $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff, //d0 + $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff, //e0 + $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff);//f0 + +implementation +uses + sysconst,msedate,msereal,Math,msefloattostr,msearrayutils,msesys,msebits, + formatfunc; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +function lstring(const s: string; const minwidth: integer): string; +var + int1: integer; +begin + int1:= length(s); + if int1 < minwidth then begin + result:= s + charstring(' ',minwidth-int1); + end + else begin + result:= s; + end; +end; + +function rstring(const s: string; const minwidth: integer): string; +var + int1: integer; +begin + int1:= length(s); + if int1 < minwidth then begin + result:= charstring(' ',minwidth-int1) + s; + end + else begin + result:= s; + end; +end; + +function encodexmlstring(const value: msestring): msestring; +var + i1: int32; + ps,pe,pd,pde: pmsechar; + + procedure checkgrow(); + var + i1: ptrint; + p1: pmsechar; + begin + if pde - pd <= 5 then begin + p1:= pointer(result); + setlength(result,length(result) * 2); + i1:= pmsechar(pointer(result)) - p1; + pd:= pd+i1; + pde:= pde+i1; + end; + end; //checkgrow + +type + char4ty = array[0..3] of msechar; + pchar4ty = ^char4ty; + char5ty = array[0..4] of msechar; + pchar5ty = ^char5ty; + char6ty = array[0..5] of msechar; + pchar6ty = ^char6ty; + +begin + result:= ''; + if value <> '' then begin + ps:= pointer(value); + i1:= length(value); + pe:= ps + i1; + setlength(result,i1); + pd:= pointer(result); + pde:= pd+i1; + while ps < pe do begin + case ps^ of + '"': begin + checkgrow(); + pchar6ty(pd)^:= '"'; + inc(pd,5); + end; + '''': begin + checkgrow(); + pchar6ty(pd)^:= '''; + inc(pd,5); + end; + '<': begin + checkgrow(); + pchar4ty(pd)^:= '<'; + inc(pd,3); + end; + '>': begin + checkgrow(); + pchar4ty(pd)^:= '>'; + inc(pd,3); + end; + '&': begin + checkgrow(); + pchar5ty(pd)^:= '&'; + inc(pd,4); + end; + else begin + pd^:= ps^; + end; + end; + inc(ps); + inc(pd); + end; + setlength(result,pd-pmsechar(pointer(result))); + end; +end; + +var + fformatmacros: tformatmacrolist; + +function formatmse(const fmt: msestring; const args: array of const; + const formatsettings: tformatsettingsmse): msestring; +begin + result:= formatfunc.unicodeformat(fmt,args,formatsettings); +end; + +function formatmse(const fmt: msestring; const args: array of const): msestring; +begin + result:= formatmse(fmt,args,defaultformatsettingsmse); +end; + +function formatmacros: tformatmacrolist; +begin + if fformatmacros = nil then begin + fformatmacros:= tformatmacrolist.create( + [mao_curlybraceonly,mao_removeunknown]); + end; + result:= fformatmacros; +end; + +procedure checkformatmacros(var format: msestring); +begin + if (fformatmacros <> nil) and (findchar(format,'{') > 0) then begin + fformatmacros.expandmacros1(format); + end; +end; + +{$ifndef FPC} +function trystrtoqword(const s: string; out value: qword): boolean; +begin + result:= trystrtoint64(s,int64(value)); +end; + +function composedatetime(const adate: tdatetime; const atime: tdatetime): tdatetime; +begin + if date < 0 then begin + result := trunc(date) - abs(frac(time)); + end + else begin + result := trunc(date) + abs(frac(time)); + end; +end; +{$endif} + +//copied from FPC dati.inc + +function formatdatetimemse(const datetime: tdatetime; formatstr: msestring; + const formatsettings: tformatsettingsmse): msestring; +var + ResultLen: integer; + ResultBuffer: array[0..255] of msechar; + ResultCurrent: pmsechar; + + procedure StoreStr(Str: pmsechar; Len: integer); + begin + if ResultLen + Len < SizeOf(ResultBuffer) div 2 then begin + Move(Str^, ResultCurrent^, Len*sizeof(msechar)); + ResultCurrent := ResultCurrent + Len; + ResultLen := ResultLen + Len; + end ; + end ; + + procedure StoreString(const Str: msestring); + var Len: integer; + begin + Len := Length(Str); + if ResultLen + Len < SizeOf(ResultBuffer) div 2 then begin // strmove not safe + Move( pointer(Str)^,ResultCurrent^,Len*sizeof(msechar)); + ResultCurrent := ResultCurrent + Len; + ResultLen := ResultLen + Len; + end; + end; + + procedure StoreInt(Value, Digits: integer); + var S: msestring; Len: integer; + begin + S := IntToStrmse(Value); + Len := Length(S); + if Len < Digits then begin + S := copy(msestring('0000'), 1, Digits - Len) + S; + Len := Digits; + end ; + StoreStr(pmsechar(pointer(S)), Len); + end ; + +var + Year, Month, Day, DayOfWeek, Hour, Minute, Second, MilliSecond: word; + + procedure StoreFormat(const FormatStr: msestring); + var + Token,lastformattoken: msechar; + FormatCurrent: pmsechar; + FormatEnd: pmsechar; + Count: integer; + Clock12: boolean; + P: pmsechar; + tmp:integer; + + begin + with formatsettings do begin + FormatCurrent := Pmsechar(pointer(FormatStr)); + FormatEnd := FormatCurrent + Length(FormatStr); + Clock12 := false; + P := FormatCurrent; + while P < FormatEnd do begin + Token := charUpperCase(P^); + if (Token = '"') or (token = '''') then begin + P := P + 1; + while (P < FormatEnd) and (P^ <> Token) do + P := P + 1; + end + else if Token = 'A' then begin + if (mseStrLIComp(P, 'A/P', 3) = 0) or + (mseStrLIComp(P, 'AMPM', 4) = 0) or + (mseStrLIComp(P, 'AM/PM', 5) = 0) then begin + Clock12 := true; + break; + end ; + end ; + P := P + 1; + end ; + token:=#255; + lastformattoken:=' '; + while FormatCurrent < FormatEnd do + begin + Token := charUpperCase(FormatCurrent^); + Count := 1; + P := FormatCurrent + 1; + case Token of + '''', '"': begin + while (P < FormatEnd) and (p^ <> Token) do + P := P + 1; + P := P + 1; + Count := P - FormatCurrent; + StoreStr(FormatCurrent + 1, Count - 2); + end ; + 'A': begin + if mseStrLIComp(FormatCurrent, pmsechar(msestring('AMPM')), 4) = 0 then begin + Count := 4; + if Hour < 12 then StoreString(TimeAMString) + else StoreString(TimePMString); + end + else if mseStrLIComp(FormatCurrent, 'AM/PM', 5) = 0 then begin + Count := 5; + if Hour < 12 then StoreStr('am', 2) + else StoreStr('pm', 2); + end + else if mseStrLIComp(FormatCurrent, 'A/P', 3) = 0 then begin + Count := 3; + if Hour < 12 then StoreStr('a', 1) + else StoreStr('p', 1); + end + else +// Raise EConvertError.Create('Illegal character in format string'); + end ; + '/': StoreStr(@DateSeparator, 1); + ':': StoreStr(@TimeSeparator, 1); + ' ', 'C', 'D', 'H', 'I', 'M', 'N', 'S', 'T', 'Y','Z' : + begin + while (P < FormatEnd) and (charUpperCase(P^) = Token) do + P := P + 1; + Count := P - FormatCurrent; + case Token of + ' ': StoreStr(FormatCurrent, Count); + 'Y': begin + if Count>2 then + StoreInt(Year, 4) + else + StoreInt(Year mod 100, 2); + end; + 'M': begin + if lastformattoken='H' then + begin + if Count = 1 then + StoreInt(Minute, 0) + else + StoreInt(Minute, 2); + + end + else + begin + case Count of + 1: StoreInt(Month, 0); + 2: StoreInt(Month, 2); + 3: StoreString(ShortMonthNames[Month]); + 4: StoreString(LongMonthNames[Month]); + end; + end; + end; + 'D': begin + case Count of + 1: StoreInt(Day, 0); + 2: StoreInt(Day, 2); + 3: StoreString(ShortDayNames[DayOfWeek]); + 4: StoreString(LongDayNames[DayOfWeek]); + 5: StoreFormat(ShortDateFormat); + 6: StoreFormat(LongDateFormat); + end ; + end ; + 'H': begin + if Clock12 then begin + tmp:=hour mod 12; + if tmp=0 then tmp:=12; + if Count = 1 then StoreInt(tmp, 0) + else StoreInt(tmp, 2); + end + else begin + if Count = 1 then StoreInt(Hour, 0) + else StoreInt(Hour, 2); + end ; + end ; + 'N': begin + if Count = 1 then StoreInt(Minute, 0) + else StoreInt(Minute, 2); + end ; + 'S': begin + if Count = 1 then StoreInt(Second, 0) + else StoreInt(Second, 2); + end ; + 'Z': begin + if Count = 1 then StoreInt(MilliSecond, 0) + else StoreInt(MilliSecond, 3); + end ; + 'T': begin + if Count = 1 then StoreFormat(ShortTimeFormat) + else StoreFormat(LongTimeFormat); + end ; + 'C': begin + StoreFormat(ShortDateFormat); + if (Hour<>0) or (Minute<>0) or (Second<>0) then + begin + StoreString(' '); + StoreFormat(LongTimeFormat); + end; + end; + 'I': begin + case count of + 1: begin + StoreFormat('YYYY-MM-DD'); + end; + 2: begin + StoreFormat('YYYY-MM-DD"T"HH:MM:SS'); + end; + else begin + StoreFormat('YYYY-MM-DD"T"HH:MM:SS:ZZZ'); + end; + end; + end; + end; + lastformattoken:=token; + end; + else + StoreStr(@Token, 1); + end ; + FormatCurrent := FormatCurrent + Count; + end ; + end; + end ; + +begin + result:= ''; + if datetime = emptydatetime then begin + exit; + end; + + checkformatmacros(formatstr); + DecodeDateFully(DateTime, Year, Month, Day, DayOfWeek); + DecodeTime(DateTime, Hour, Minute, Second, MilliSecond); + ResultLen := 0; + ResultCurrent := @ResultBuffer[0]; + StoreFormat(FormatStr); +// ResultBuffer[ResultLen] := #0; +// result := StrPas(@ResultBuffer[0]); + setlength(result,resultlen); + move(resultbuffer,pointer(result)^,resultlen*sizeof(msechar)); + +end ; + +function formatdatetimemse(const datetime: tdatetime; + const formatstr: msestring): msestring; +begin + result:= formatdatetimemse(datetime,formatstr,defaultformatsettingsmse); +end; + +function formatdatetimemse(const formatstr: msestring; const datetime: tdatetime; + const formatsettings: tformatsettingsmse): msestring; +begin + result:= formatdatetimemse(datetime,formatstr,formatsettings); +end; + +function formatdatetimemse(const formatstr: msestring; + const datetime: tdatetime): msestring; +begin + result:= formatdatetimemse(datetime,formatstr,defaultformatsettingsmse); +end; + +(* +//copied from FPC sysstr.inc +//todo: optimize, use threadsave formatsettings + +Function FloatToTextFmt(Buffer: PmseChar; Value: Extended; format: PmseChar; + const formatsettings: tformatsettingsmse): Integer; + +Var + Digits: String[40]; { String Of Digits } + Exponent: String[8]; { Exponent strin } + FmtStart, FmtStop: PmseChar; { Start And End Of relevant part } + { Of format String } + ExpFmt, ExpSize: Integer; { Type And Length Of } + { exponential format chosen } + Placehold: Array[1..4] Of Integer; { Number Of placeholders In All } + { four Sections } + thousand: Boolean; { thousand separators? } + UnexpectedDigits: Integer; { Number Of unexpected Digits that } + { have To be inserted before the } + { First placeholder. } + DigitExponent: Integer; { Exponent Of First digit In } + { Digits Array. } + + { Find end of format section starting at P. False, if empty } + + Function GetSectionEnd(Var P: PmseChar): Boolean; + Var + C: mseChar; + SQ, DQ: Boolean; + Begin + Result := False; + SQ := False; + DQ := False; + C := P[0]; + While (C<>#0) And ((C<>';') Or SQ Or DQ) Do + Begin + Result := True; + Case C Of + #34: If Not SQ Then DQ := Not DQ; + #39: If Not DQ Then SQ := Not SQ; + End; + Inc(P); + C := P[0]; + End; + End; + + { Find start and end of format section to apply. If section doesn't exist, + use section 1. If section 2 is used, the sign of value is ignored. } + + Procedure GetSectionRange(section: Integer); + Var + Sec: Array[1..3] Of PmseChar; + SecOk: Array[1..3] Of Boolean; + Begin + Sec[1] := format; + SecOk[1] := GetSectionEnd(Sec[1]); + If section > 1 Then + Begin + Sec[2] := Sec[1]; + If Sec[2][0] <> #0 Then + Inc(Sec[2]); + SecOk[2] := GetSectionEnd(Sec[2]); + If section > 2 Then + Begin + Sec[3] := Sec[2]; + If Sec[3][0] <> #0 Then + Inc(Sec[3]); + SecOk[3] := GetSectionEnd(Sec[3]); + End; + End; + If Not SecOk[1] Then + FmtStart := Nil + Else + Begin + If Not SecOk[section] Then + section := 1 + Else If section = 2 Then + Value := -Value; { Remove sign } + If section = 1 Then FmtStart := format Else + Begin + FmtStart := Sec[section - 1]; + Inc(FmtStart); + End; + FmtStop := Sec[section]; + End; + End; + + { Find format section ranging from FmtStart to FmtStop. } + + Procedure GetFormatOptions; + Var + Fmt: PmseChar; + SQ, DQ: Boolean; + area: Integer; + Begin + SQ := False; + DQ := False; + Fmt := FmtStart; + ExpFmt := 0; + area := 1; + thousand := False; + Placehold[1] := 0; + Placehold[2] := 0; + Placehold[3] := 0; + Placehold[4] := 0; + While Fmt < FmtStop Do + Begin + Case Fmt[0] Of + #34: + Begin + If Not SQ Then + DQ := Not DQ; + Inc(Fmt); + End; + #39: + Begin + If Not DQ Then + SQ := Not SQ; + Inc(Fmt); + End; + Else + { This was 'if not SQ or DQ'. Looked wrong... } + If Not (SQ Or DQ) Then + Begin + Case Fmt[0] Of + '0': + Begin + Case area Of + 1: + area := 2; + 4: + Begin + area := 3; + Inc(Placehold[3], Placehold[4]); + Placehold[4] := 0; + End; + End; + Inc(Placehold[area]); + Inc(Fmt); + End; + + '#': + Begin + If area=3 Then + area:=4; + Inc(Placehold[area]); + Inc(Fmt); + End; + '.': + Begin + If area<3 Then + area:=3; + Inc(Fmt); + End; + ',': + Begin + thousand := True; + Inc(Fmt); + End; + 'e', 'E': + If ExpFmt = 0 Then + Begin + If (Fmt[0]='E') Then + ExpFmt:=1 + Else + ExpFmt := 3; + Inc(Fmt); + If (Fmt 0 Then + Begin + Inc(Fmt); + ExpSize := 0; + While (Fmt= '0') and (fmt^ <= '9') do +// (Fmt[0] In ['0'..'9']) Do + Begin + Inc(ExpSize); + Inc(Fmt); + End; + End; + End; + End + Else + Inc(Fmt); + Else { Case } + Inc(Fmt); + End; { Case } + End { Begin } + Else + Begin + Inc(Fmt) + End; + End; { Case } + End; { While .. Begin } + End; + + Procedure FloatToStr; + + Var + I, J, Exp, Width, Decimals, DecimalPoint, len: Integer; + + Begin + If ExpFmt = 0 Then + Begin + { Fixpoint } + Decimals:=Placehold[3]+Placehold[4]; + Width:=Placehold[1]+Placehold[2]+Decimals; + If (Decimals=0) Then + Str(Value:Width:0,Digits) + Else + Str(Value:Width+1:Decimals,Digits); + len:=Length(Digits); + { Find the decimal point } + If (Decimals=0) Then + DecimalPoint:=len+1 + Else + DecimalPoint:=len-Decimals; + { If value is very small, and no decimal places + are desired, remove the leading 0. } + If (Abs(Value) < 1) And (Placehold[2] = 0) Then + Begin + If (Placehold[1]=0) Then + Delete(Digits,DecimalPoint-1,1) + Else + Digits[DecimalPoint-1]:=' '; + End; + + { Convert optional zeroes to spaces. } + I:=len; + J:=DecimalPoint+Placehold[3]; + While (I>J) And (Digits[I]='0') Do + Begin + Digits[I] := ' '; + Dec(I); + End; + { If integer value and no obligatory decimal + places, remove decimal point. } + If (DecimalPoint < len) And (Digits[DecimalPoint + 1] = ' ') Then + Digits[DecimalPoint] := ' '; + { Convert spaces left from obligatory decimal point to zeroes. } + I:=DecimalPoint-Placehold[2]; + While (I Digits With Decimals + And adjusted Exponent. } + If Placehold[1]+Placehold[2]=0 Then + Placehold[1]:=1; + Decimals := Placehold[3] + Placehold[4]; + Width:=Placehold[1]+Placehold[2]+Decimals; + Str(Value:Width+8,Digits); + { Find and cut out exponent. Always the + last 6 characters in the string. + -> 0000E+0000 } + I:=Length(Digits)-5; + Val(Copy(Digits,I+1,5),Exp,J); + Exp:=Exp+1-(Placehold[1]+Placehold[2]); + Delete(Digits, I, 6); + { Str() always returns at least one digit after the decimal point. + If we don't want it, we have to remove it. } + If (Decimals=0) And (Placehold[1]+Placehold[2]<= 1) Then + Begin + If (Digits[4]>='5') Then + Begin + Inc(Digits[2]); + If (Digits[2]>'9') Then + Begin + Digits[2] := '1'; + Inc(Exp); + End; + End; + Delete(Digits, 3, 2); + DecimalPoint := Length(Digits) + 1; + End + Else + Begin + { Move decimal point at the desired position } + Delete(Digits, 3, 1); + DecimalPoint:=2+Placehold[1]+Placehold[2]; + If (Decimals<>0) Then + Insert('.',Digits,DecimalPoint); + End; + + { Convert optional zeroes to spaces. } + I := Length(Digits); + J := DecimalPoint + Placehold[3]; + While (I > J) And (Digits[I] = '0') Do + Begin + Digits[I] := ' '; + Dec(I); + End; + + { If integer number and no obligatory decimal paces, remove decimal point } + + If (DecimalPoint= 0 Then + Begin + If (ExpFmt In [1,3]) Then + Insert('+', Exponent, 1); + End + Else + Insert('-',Exponent,1); + If (ExpFmt<3) Then + Insert('E',Exponent,1) + Else + Insert('e',Exponent,1); + End; + DigitExponent:=DecimalPoint-2; + If (Digits[1]='-') Then + Dec(DigitExponent); + UnexpectedDigits:=DecimalPoint-1-(Placehold[1]+Placehold[2]); + End; + + Function PutResult: LongInt; + + Var + SQ, DQ: Boolean; + Fmt, Buf: PmseChar; + Dig, N: Integer; + + Begin + with formatsettings do begin + SQ := False; + DQ := False; + Fmt := FmtStart; + Buf := Buffer; + Dig := 1; + While (Fmt0) Then + Begin + { Everything unexpected is written before the first digit } + For N := 1 To UnexpectedDigits Do + Begin + Buf[0] := widechar(Digits[N]); + Inc(Buf); + If thousand And (Digits[N]<>'-') Then + Begin + If (DigitExponent Mod 3 = 0) And (DigitExponent>0) Then + Begin +// Buf[0] := widechar(ThousandSeparator); + Buf[0] := ThousandSeparator; + Inc(Buf); + End; + Dec(DigitExponent); + End; + End; + Inc(Dig, UnexpectedDigits); + End; + If (Digits[Dig]<>' ') Then + Begin + If (Digits[Dig]='.') Then + Buf[0] := DecimalSeparator +// Buf[0] := widechar(DecimalSeparator) + Else + Buf[0] := widechar(Digits[Dig]); + Inc(Buf); + If thousand And (DigitExponent Mod 3 = 0) And (DigitExponent > 0) Then + Begin +// Buf[0] := widechar(ThousandSeparator); + Buf[0] := ThousandSeparator; + Inc(Buf); + End; + End; + Inc(Dig); + Dec(DigitExponent); + Inc(Fmt); + End; + 'e', 'E': + Begin + If ExpFmt <> 0 Then + Begin + Inc(Fmt); + If Fmt < FmtStop Then + Begin +// If Fmt[0] In ['+', '-'] Then + If (Fmt[0] = '+') or (fmt[0] = '-') Then + Begin + Inc(Fmt, ExpSize); + For N:=1 To Length(Exponent) Do + Buf[N-1] := widechar(Exponent[N]); + Inc(Buf,Length(Exponent)); + ExpFmt:=0; + End; + Inc(Fmt); + End; + End + Else + Begin + { No legal exponential format. + Simply write the 'E' to the result. } + Buf[0] := Fmt[0]; + Inc(Buf); + Inc(Fmt); + End; + End; + Else { Case } + { Usual character } + If (Fmt[0]<>',') Then + Begin + Buf[0] := Fmt[0]; + Inc(Buf); + End; + Inc(Fmt); + End; { Case } + End + Else { IF } + Begin + { Character inside single or double quotes } + Buf[0] := Fmt[0]; + Inc(Buf); + Inc(Fmt); + End; + End; { Case } + End; { While .. Begin } +// Result:=PtrInt(Buf)-PtrInt(Buffer); + result:= buf - buffer; + end; + End; + +var + int1: integer; +begin + if value > 0 then begin + getsectionrange(1); + end + else begin + if (value < 0) then begin + getsectionrange(2) + end + else begin + getsectionrange(3); + end; + end; + if fmtstart = nil then begin + {$ifdef FPC} + result:= floattotext(pchar(buffer),value,ffgeneral,15,4); + {$else} + result:= floattotext(pchar(buffer),value,fvextended,ffgeneral,15,4); + {$endif} + end + else begin + getformatoptions; + if (expfmt = 0) and (abs(value) >= 1e18) then begin + {$ifdef FPC} + result:= floattotext(pchar(buffer),value,ffgeneral,15,4); + {$else} + result:= floattotext(pchar(buffer),value,fvextended,ffgeneral,15,4); + {$endif} + end + else begin + floattostr; + result:= putresult; + exit; + end; + end; + for int1:= result - 1 downto 0 do begin + pmsecharaty(buffer)^[int1]:= widechar(pcharaty(buffer)^[int1]); + //convert to msestring + end; +end; +*) + +function cstringtostringvar(var inp: pchar): string; + +const + quotechar = '"'; + escapechar = '\'; + +var + po1,po2: pchar; + int1,int2: integer; + ch1: char; + +begin + result:= ''; + if inp <> nil then begin + po1:= inp; + while true do begin + while (po1^ = ' ') do begin //first quote + inc(po1); + end; + if (po1^ <> quotechar) then begin + break; //end or no start quote + end; + inc(po1); + po2:= po1; //text + while true do begin + while (po1^ <> quotechar) and (po1^ <> escapechar) do begin + if (po1^ = #0) then begin + result:= ''; + inp:= nil; + exit; //error: no end quote + end; + inc(po1); + end; + int1:= po1-po2; //text length + int2:= length(result)+1; + setlength(result,length(result) + int1); + move(po2^,result[int2],int1); //add text + if po1^ = escapechar then begin + inc(po1); + case po1^ of + 'a': ch1:= #$07; + 'b': ch1:= #$08; + 'f': ch1:= #$0c; + 'n': ch1:= #$0a; + 'r': ch1:= #$0d; + 't': ch1:= #$09; + 'v': ch1:= #$0b; + '\': ch1:= '\'; + '''': ch1:= ''''; + '"': ch1:= '"'; + '?': ch1:= '?'; + '0'..'7': begin + po2:= po1; + for int1:= 0 to 2 do begin + if (po1^ < '0') or (po1^ > '7') then begin + break; + end; + inc(po1); + end; + ch1:= char(strtooct(psubstr(po2,po1))); + dec(po1); + end; + 'x','X': begin + inc(po1); + po2:= po1; + while (po1^ >= '0') and (po1^ <= '9') or + (po1^ >= 'a') and (po1^ <= 'f') or + (po1^ >= 'A') and (po1^ <= 'F') do begin + inc(po1); + end; + ch1:= char(strtohex(psubstr(po2,po1))); + dec(po1); + end; + else begin + ch1:= ' '; + end; + end; + result:= result + ch1; + inc(po1); + end + else begin + inc(po1); + break; + end; + po2:= po1; //past quote + end; + end; + inp:= po1; + end; +end; + +function cstringtostring(inp: pchar): string; +begin + result:= cstringtostringvar(inp); +end; + +function cstringtostring(const inp: string): string; +var + po1: pchar; +begin + po1:= pchar(inp); + result:= cstringtostringvar(po1); +end; + +function stringtocstring(const inp: pmsechar; + const count: integer): string; overload; +var + po1: pmsechar; + innum: boolean; + int1: integer; +begin + result:= '"'; + po1:= inp; + innum:= false; + for int1:= count - 1 downto 0 do begin +// if (po1^ < #$20) or (po1^ > #$ff) or (po1^ = #$7f) then begin + if (po1^ < #$20) or (po1^ >= #$7f) then begin + innum:= true; + if po1^ < #$100 then begin + result:= result + '\x'+hextostr(ord(po1^),2); + end + else begin + result:= result + '\x'+hextostr(ord(po1^),4); + end; + end + else begin + if po1^ = '"' then begin + result:= result + '\"'; + innum:= false; + end + else begin + if innum then begin + result:= result + '" "'+char(po1^); + innum:= false; + end + else begin + result:= result + char(po1^); + end; + end; + end; + inc(po1); + end; + result:= result + '"'; +end; + +function stringtocstring(const inp: msestring): string; +begin + result:= stringtocstring(pmsechar(pointer(inp)),length(inp)); +end; + +function stringtopascalstring(const value: msestring; + const maxlinelength: int32 = 0): string; +const + reserve = 32; +var + int1,int2,mle: integer; + i1: ptrint; + po1,ps,pse,pe: pchar; + p0: pointer; + ln,str1: string; + asciimode: boolean; +begin + if length(value) = 0 then begin + result:= ''''''; + end + else begin + ln:= lineend; + asciimode:= false; +// setlength(result,2+6*length(value)); +// // maxlength for single char: '#65535' = 2 + 6 + setlength(result,length(value)+reserve); + pe:= pointer(result)+length(result)-reserve; + po1:= pchar(pointer(result)); + ps:= po1; + mle:= maxlinelength-2; + if mle < 20 then begin + mle:= 20; + end; + pse:= ps+mle; +// int2:= 1; + for int1:= 1 to length(value) do begin + if maxlinelength > 0 then begin + if po1 >= pse then begin + if asciimode then begin + po1^:= ''''; + end + else begin + po1^:= ' '; + end; + inc(po1); + po1^:= '+'; + inc(po1); + move(pointer(ln)^,po1^,length(ln)); + inc(po1,length(ln)); + if asciimode then begin + po1^:= ''''; + inc(po1); + end; + ps:= po1; + pse:= ps+mle; + end; + end; + if po1 >= pe then begin + p0:= pointer(result); + setlength(result,length(result)*2+reserve); + i1:= pointer(result)-p0; + po1:= po1 + i1; + ps:= ps + i1; + pse:= pse + i1; + pe:= pointer(result)+length(result)-reserve; + end; + int2:= ord(value[int1]); + if (int2 >= 32) and (int2 < 127) then begin + if not asciimode then begin + asciimode:= true; + po1^:= ''''; + inc(po1); + end; + if char(int2) = '''' then begin + po1^:= ''''; //double quote + inc(po1); + end; + po1^:= char(int2); + inc(po1); + end + else begin + if asciimode then begin + asciimode:= false; + po1^:= ''''; + inc(po1); + end; + po1^:= '#'; + inc(po1); + str1:= '$'+hextostr(card32(int2),4); + move(pchar(pointer(str1))^,po1^,length(str1)); + inc(po1,length(str1)); + end; + end; + if asciimode then begin + po1^:= ''''; + inc(po1); + end; + setlength(result,po1-pchar(pointer(result))); + end; +end; + +function trypascalstringtostring(const value: string; + out res: msestring ): boolean; + +var + po1: pmsechar; + po2,po3: pmsechar; + int1: integer; + mstr1,source1: msestring; +begin + result:= false; + source1:= msestring(value); //assume locale encoding + setlength(res,length(source1)); //max length + po1:= pmsechar(pointer(res)); + po2:= pmsechar(source1); + while po2^ <> #0 do begin + case po2^ of + '#': begin + inc(po2); + if po2^ = '$' then begin + inc(po2); + po3:= po2; + while po2^ in ['0'..'9','a'..'f','A'..'F'] do begin + inc(po2); + end; + setstring(mstr1,po3,po2-po3); + po1^:= msechar(strtohex(mstr1)); + end + else begin + po3:= po2; + while (po2^ >= '0') and (po2^ <= '9') do begin + inc(po2); + end; + setstring(mstr1,po3,po2-po3); + po1^:= msechar(strtoint(mstr1)); + end; + inc(po1); + end; + '''': begin + inc(po2); //'..... + po3:= po2; + while (po2^ <> '''') and (po2^ <> #0) do begin + inc(po2) + end; + if po2^ <> #0 then begin + for int1:= 0 to po2 - po3 - 1 do begin //'abcd'...... + po1^:= msechar((po3+int1)^); + inc(po1); + end; + inc(po2); + if po2^ = '''' then begin //'abcd'? + po1^:= ''''; //'abcd'' + inc(po1); + end; + end + else begin + res:= ''; + exit; + end; + end; + ' ',c_tab: begin + inc(po2) + end + else begin + res:= ''; + exit; + end; + end; + end; + setlength(res,po1-pmsechar(pointer(res))); + result:= true; +end; + +function pascalstringtostring(const value: string): msestring; +begin + if not trypascalstringtostring(value,result) then begin + raise exception.Create('Invalid pascalstring: "'+value+'".'); + end; +end; + +function getpascalstring(var value: pchar): msestring; + +var + po2,po3: pchar; +// int1: integer; + str1: string; + charcount: integer; + + procedure addstring(const astr: msestring); + var + int1,int2: integer; + begin + int1:= length(astr); + int2:= charcount; + charcount:= charcount+int1; + if length(result) < charcount then begin + setlength(result,2*charcount+32); + end; + move(pointer(astr)^,(pmsechar(pointer(result))+int2)^,int1*sizeof(msechar)); + end; + +begin + result:= ''; + charcount:= 0; + po2:= value; + while po2^ <> #0 do begin + case po2^ of + '#': begin + inc(po2); + if po2^ = '$' then begin + inc(po2); + po3:= po2; + while po2^ in ['0'..'9','a'..'f','A'..'F'] do begin + inc(po2); + end; + setstring(str1,po3,po2-po3); + addstring(msechar(strtohex(str1))); + end + else begin + po3:= po2; + while (po2^ >= '0') and (po2^ <= '9') do begin + inc(po2); + end; + setstring(str1,po3,po2-po3); + addstring(msechar(strtoint(str1))); + end; + end; + '''': begin + inc(po2); //'..... + po3:= po2; + while (po2^ <> '''') and (po2^ <> #0) do begin + inc(po2) + end; + if po2^ <> #0 then begin + setstring(str1,po3,po2-po3); + addstring(msestring(str1)); + inc(po2); + if po2^ = '''' then begin //'abcd'? + addstring(''''); //'abcd'' + end; + end + else begin + result:= ''; + exit; + end; + end; + ' ',c_tab: begin + inc(po2) + end + else begin + break; + end; + end; + end; + setlength(result,charcount); + value:= po2; +end; + + +function encodebase64(const abinary: pbyte; acount: integer; + const maxlinelength: integer = defaultbase64linelength): string; + //todo: optimize +var + int1: integer; + ps,pe: pbyte; + pd,pline: pchar; + tail,linestep: integer; + by1: byte; +begin + result:= ''; + if acount > 0 then begin + int1:= ((acount+2) div 3)*4; + linestep:= maxlinelength and $fffffffc; //do not cut 4 char boundary + if maxlinelength > 0 then begin + if linestep = 0 then begin + linestep:= 4; + end; + int1:= int1 + 2*((int1+linestep-1)div linestep - 1); //return-linefeed + end; + setlength(result,int1); + ps:= abinary; + int1:= acount; + tail:= int1 mod 3; + pchar(pe):= pchar(ps)+int1-tail; + pd:= pointer(result); + if maxlinelength > 0 then begin + pline:= pd + linestep; + end + else begin + pline:= pointer(not ptruint(0)); + end; + while pchar(ps) < pchar(pe) do begin + if pd >= pline then begin + pd^:= c_return; + inc(pd); + pd^:= c_linefeed; + inc(pd); + pline:= pd+linestep; + end; + by1:= ps^; //s0 + pd^:= base64encoding[by1 shr 2]; //d0 + inc(ps); //s1 + inc(pd); //d1 + pd^:= base64encoding[((by1 shl 4) or (ps^ shr 4)) and base64mask]; + by1:= ps^ shl 2; + inc(ps); //s2 + inc(pd); //d2 + pd^:= base64encoding[(by1 or (ps^ shr 6)) and base64mask]; + inc(pd); //d3 + pd^:= base64encoding[ps^ and base64mask]; + inc(ps); + inc(pd); //d0 + end; + if tail > 0 then begin + if pd >= pline then begin + pd^:= c_return; + inc(pd); + pd^:= c_linefeed; + inc(pd); + end; + by1:= ps^; //s0 + pd^:= base64encoding[by1 shr 2]; //d0 + inc(pd); //d1 + pd^:= base64encoding[(by1 shl 4) and base64mask]; + if tail > 1 then begin + inc(ps); //s1 + pd^:= base64encoding[((by1 shl 4) or (ps^ shr 4)) and base64mask]; + inc(pd); //d2 + pd^:= base64encoding[(ps^ shl 2) and base64mask]; + end + else begin + inc(pd); //d2 + pd^:= '='; + end; + inc(pd); //d3 + pd^:= '='; + end; + end; +end; + +function encodebase64(const abinary: string; + const maxlinelength: integer = defaultbase64linelength): string; +begin + result:= encodebase64(pointer(abinary),length(abinary),maxlinelength); +end; + +function decodebase64(const atext: string): string; + //todo: optimize +label + endlab; +var + ps,pend: pchar; + pd: pbyte; + by1: byte; +begin + setlength(result,length(atext)); //>max + if atext <> '' then begin + ps:= pointer(atext); + pd:= pointer(result); + pend:= ps+length(atext); + while ps < pend do begin + by1:= base64decoding[ord(ps^)]; //s0 + while shortint(by1) < 0 do begin + inc(ps); + if (ps >= pend) or (char(by1) = '=') then begin + goto endlab; + end; + by1:= base64decoding[ord(ps^)]; + end; + pd^:= by1 shl 2; //d0 + inc(ps); + by1:= base64decoding[ord(ps^)]; //s1 + while shortint(by1) < 0 do begin + inc(ps); + if (ps >= pend) or (char(by1) = '=') then begin + goto endlab; + end; + by1:= base64decoding[ord(ps^)]; + end; + pd^:= pd^ or (by1 shr 4); + inc(pd); //d1 + pd^:= by1 shl 4; + inc(ps); + by1:= base64decoding[ord(ps^)]; //s2 + while shortint(by1) < 0 do begin + inc(ps); + if (ps >= pend) or (char(by1) = '=') then begin + goto endlab; + end; + by1:= base64decoding[ord(ps^)]; + end; + pd^:= pd^ or by1 shr 2; + inc(pd); //d2 + pd^:= by1 shl 6; + inc(ps); + by1:= base64decoding[ord(ps^)]; //s3 + while shortint(by1) < 0 do begin + inc(ps); + if (ps >= pend) or (char(by1) = '=') then begin + goto endlab; + end; + by1:= base64decoding[ord(ps^)]; + end; + pd^:= pd^ or by1; + inc(pd); + inc(ps); //s0 + end; +endlab: + setlength(result,pchar(pointer(pd))-pchar(pointer(result))); + end; +end; + +procedure checkdateconvert(const convert: dateconvertty; var value: tdatetime); +begin + if value <> emptydatetime then begin + if convert = dc_toutc then begin + value:= localtimetoutc(value); + end + else begin + if convert = dc_tolocal then begin + value:= utctolocaltime(value); + end; + end; + end; +end; + +procedure checkdatereconvert(const convert: dateconvertty; var value: tdatetime); +begin + if value <> emptydatetime then begin + if convert = dc_tolocal then begin + value:= localtimetoutc(value); + end + else begin + if convert = dc_toutc then begin + value:= utctolocaltime(value); + end; + end; + end; +end; +(* +function stringtotime(const text: msestring; out value: tdatetime; + const convert: dateconvertty = dc_none): boolean; +var + mstr1: msestring; + timesep: msechar; +begin + result:= true; + if text = ' ' then begin + if convert = dc_toutc then begin + value:= frac(nowutc); + end + else begin + value:= frac(nowlocal); + end; + end + else begin + if text = '' then begin + value:= emptydatetime; + end + else begin + timesep:= defaultformatsettingsmse.timeseparator; + if (countchars(text,timesep) = 0) and + (countchars(text,defaultformatsettingsmse.timeseparator) = 0) then begin + case length(text) of + 3,4: begin + mstr1:= copy(text,1,2)+timesep+copy(text,3,2); + end; + 5,6: begin + mstr1:= copy(text,1,2)+timesep+copy(text,3,2)+timesep+ + copy(text,5,2); + end; + else begin + mstr1:= text; + end; + end; + result:= sysutils.trystrtotime(mstr1,value); + end + else begin + result:= sysutils.trystrtotime(text,value); + end; + checkdateconvert(convert,value); + end; + end; +end; +*) +function timetostring(const avalue: tdatetime; const format: msestring = 't'): msestring; +begin + if avalue = emptydatetime then begin + result:= ''; + end + else begin + if format = '' then begin + result:= formatdatetimemse('t',avalue,defaultformatsettingsmse); + end + else begin + result:= formatdatetimemse(format,avalue,defaultformatsettingsmse); + end; + end; +end; + +function datetimetostring(const avalue: tdatetime; + const format: msestring = 'c'): msestring; +begin + if avalue = emptydatetime then begin + result:= ''; + end + else begin + if format = '' then begin + result:= formatdatetimemse('c',avalue,defaultformatsettingsmse); + end + else begin + result:= formatdatetimemse(format,avalue,defaultformatsettingsmse); + end; + end; +end; + +function datetostring(const avalue: tdatetime; + const format: msestring = 'c'): msestring; +begin + if avalue = emptydatetime then begin + result:= ''; + end + else begin + result:= datetimetostring(trunc(avalue),format); + end; +end; + +procedure formaterror(const value: string); +begin + raise exception.Create('Invalid value '''+value+'''.'); +end; + +procedure formaterror(const value: msestring); +begin + formaterror(ansistring(value)); +end; + +type + datetimeformattokenty = ( + dtft_default, // c shortdateformat + ' ' + longtimeformat + dtft_day, // d day of month + dtft_dayzero, // dd day of month (leading zero) + dtft_dayabbr, // ddd day of week (abbreviation) + dtft_dayfull, // dddd day of week (full) + dtft_shortdate, // ddddd shortdateformat + dtft_longdate, // dddddd longdateformat + dtft_month, // m month + dtft_monthzero, // mm month (leading zero) + dtft_monthabbr, // mmm month (abbreviation) + dtft_monthfull, // mmmm month (full) + dtft_year, // y year (2 digits) + dtft_yearzero, // yy year (two digits) + dtft_yearcentury, // yyyy year (with century) + dtft_hour, // h hour + dtft_hourzero, // hh hour (leading zero) + dtft_minute, // n minute + dtft_minutezero, // nn minute (leading zero) + dtft_second, // s second + dtft_secondzero, // ss second (leading zero) + dtft_shorttime, // t shorttimeformat + dtft_longtime, // tt longtimeformat + dtft_ampm, // ampm + dtft_amspm, // am/pm use 12 hour clock and + // display am and pm accordingly + dtft_ap, // a/p use 12 hour clock and display + // a and p accordingly + dtft_datesep, // / insert date seperator + dtft_timesep, // : insert time seperator + dtft_millisec // z milliseconds + ); + +dttokengroupty = (dttg_none,dttg_millisec,dttg_sec, + dttg_min,dttg_hour, + dttg_day,dttg_mon,dttg_year); +dttokeninfoty = record + token: datetimeformattokenty; + group: dttokengroupty; + chars: msestring; +end; + +const + tokeninfos: array[0..ord(high(datetimeformattokenty))] of dttokeninfoty = + ( //longest first + (token: dtft_default; group: dttg_none; chars: 'C'), //0 + (token: dtft_longdate; group: dttg_none; chars: 'DDDDDD'), //1 + (token: dtft_shortdate; group: dttg_none; chars: 'DDDDD'), //2 + (token: dtft_longtime; group: dttg_none; chars: 'TT'), //3 + (token: dtft_shorttime; group: dttg_none; chars: 'T'), //4 + (token: dtft_datesep; group: dttg_none; chars: '/'), //5 + (token: dtft_timesep; group: dttg_none; chars: ':'), //6 + + (token: dtft_amspm; group: dttg_none; chars: 'AM/PM'), //7 + (token: dtft_ampm; group: dttg_none; chars: 'AMPM'), + (token: dtft_dayfull; group: dttg_day; chars: 'DDDD'), + (token: dtft_monthfull; group: dttg_mon; chars: 'MMMM'), + (token: dtft_yearcentury; group: dttg_year; chars: 'YYYY'), + (token: dtft_ap; group: dttg_none; chars: 'A/P'), + (token: dtft_dayabbr; group: dttg_day; chars: 'DDD'), + (token: dtft_monthabbr; group: dttg_mon; chars: 'MMM'), + (token: dtft_dayzero; group: dttg_day; chars: 'DD'), + (token: dtft_monthzero; group: dttg_mon; chars: 'MM'), + (token: dtft_yearzero; group: dttg_year; chars: 'YY'), + (token: dtft_hourzero; group: dttg_hour; chars: 'HH'), + (token: dtft_minutezero; group: dttg_min; chars: 'NN'), + (token: dtft_secondzero; group: dttg_sec; chars: 'SS'), + (token: dtft_day; group: dttg_day; chars: 'D'), + (token: dtft_month; group: dttg_mon; chars: 'M'), + (token: dtft_year; group: dttg_year; chars: 'Y'), + (token: dtft_hour; group: dttg_hour; chars: 'H'), + (token: dtft_minute; group: dttg_min; chars: 'N'), + (token: dtft_second; group: dttg_sec; chars: 'S'), + (token: dtft_millisec; group: dttg_millisec; chars: 'Z') + ); + + startscan = 7; + +//todo: use format cache + +type + scaninfoty = record + index: integer; + group: dttokengroupty; + end; + +function comparescan(const l,r): integer; +begin + result:= scaninfoty(l).index - scaninfoty(r).index; +end; + +function trystringtodatetime(const text: msestring; + aformat: msestring; out value: tdatetime; + const convert: dateconvertty = dc_none): boolean; + procedure removequotes(var astring: msestring); + var + po1: pmsechar; + begin + uniquestring(astring); + po1:= pmsechar(astring); + while po1^ <> #0 do begin + case po1^ of + '"': begin + repeat + po1^:= ' '; + inc(po1) + until (po1^ = '"') or (po1^ = #0 ); + if po1^ <> #0 then begin + po1^:= ' '; + end; + end; + end; + case po1^ of + '''': begin + repeat + po1^:= ' '; + inc(po1) + until (po1^ = '''') or (po1^ = #0 ); + if po1^ <> #0 then begin + po1^:= ' '; + end; + end; + else begin + if (po1^ >= 'a') and (po1^ <= 'z') then begin + dec(po1^,ord('a')-ord('A')); + end; + inc(po1); + end; + end; + end; + end; //removequotes + + procedure expand(var astring: msestring; const ainfo: dttokeninfoty; + const substitute: msestring); + var + mstr1,mstr2: msestring; + int1,int2: integer; + begin + mstr1:= astring; + mstr2:= substitute; + removequotes(mstr2); + int2:= length(ainfo.chars); + int1:= 1; + while true do begin + int1:= mseposex(ainfo.chars,mstr1,int1); //no recursion + if int1 = 0 then begin + break; + end; + mstr1:= copy(mstr1,1,int1-1)+mstr2+copy(mstr1,int1+int2,bigint); + int1:= int1 + int2; + end; + astring:= mstr1; + end; //expand + +var + scanar: array of scaninfoty; + scanindex: integer; + + procedure scan(var astring: msestring; const ainfo: dttokeninfoty); + var + po1: pmsecharaty; + int1,int2,int3: integer; + begin + int1:= 1; + while true do begin + int1:= mseposex(ainfo.chars,astring,int1); //no recursion + if int1 = 0 then begin + break; + end; + with scanar[scanindex] do begin + index:= int1; + group:= ainfo.group; + end; + inc(scanindex); + po1:= @astring[int1]; + int3:= length(ainfo.chars); + for int2:= 0 to int3-1 do begin + po1^[int2]:= ' '; + end; + int1:= int1 + int3; + end; + end; //scan + +var + dateorder: array[0..2] of dttokengroupty; + { = (dttg_none,dttg_none,dttg_none); does not work in delphi} + + function finddateorder(const agroup: dttokengroupty): integer; + var + int1: integer; + begin + result:= -1; + for int1:= 0 to high(dateorder) do begin + if agroup = dateorder[int1] then begin + result:= int1; + break; + end; + end; + end; + +var + mstr1: msestring; + int1,int2,int3,int4,int5: integer; + dt1,dt2: tdatetime; + grouporder: array of dttokengroupty; + groupused: array[dttokengroupty] of boolean; + ar1: msestringarty; + datear,timear: integerarty; + po1,po2: pmsechar; + tisep: msechar; + year,month,defmonth,day,hour,minute,second,millisecond: word; + ispm,hasmonthname,hasdateformat,hastimeformat: boolean; + refdate: tdatetime; + defaultdateorder: array[0..2] of dttokengroupty; + { = (dttg_year,dttg_mon,dttg_day);} + +begin + checkformatmacros(aformat); + result:= false; + if text = '' then begin + value:= emptydatetime; + result:= true; + exit; + end + else begin + for int1:= 0 to high(dateorder) do begin + dateorder[int1]:= dttg_none; //delphi compatibility + end; + defaultdateorder[0]:= dttg_year; + defaultdateorder[1]:= dttg_mon; + defaultdateorder[2]:= dttg_day; + + if convert = dc_toutc then begin + refdate:= nowutc; + end + else begin + refdate:= nowlocal; + end; + if aformat = '' then begin + mstr1:= 'c'; + end + else begin + mstr1:= aformat; + end; + removequotes(mstr1); + expand(mstr1,tokeninfos[0],defaultformatsettingsmse.shortdateformat + ' ' + + defaultformatsettingsmse.longtimeformat); //c + expand(mstr1,tokeninfos[1],defaultformatsettingsmse.longdateformat); //dddddd + expand(mstr1,tokeninfos[2],defaultformatsettingsmse.shortdateformat);//ddddd + expand(mstr1,tokeninfos[3],defaultformatsettingsmse.longtimeformat); //tt + expand(mstr1,tokeninfos[4],defaultformatsettingsmse.shorttimeformat);//t + allocuninitedarray(length(mstr1),sizeof(scaninfoty{scanar[0]}),scanar); //max + //fpc 3.0 warning + scanindex:= 0; + for int1:= startscan to high(tokeninfos) do begin + scan(mstr1,tokeninfos[int1]); + end; + setlength(scanar,scanindex); + sortarray(scanar,sizeof(scanar[0]),@comparescan); + fillchar(groupused,sizeof(groupused),0); + allocuninitedarray(length(scanar),sizeof(scanar[0]),grouporder); //max + int2:= 0; + for int1:= 0 to high(scanar) do begin + with scanar[int1] do begin + if not groupused[group] then begin + groupused[group]:= true; + grouporder[int2]:= group; + inc(int2); + end; + end; + end; + setlength(grouporder,int2); + int2:= 0; + hastimeformat:= false; + for int1:= 0 to high(grouporder) do begin + if grouporder[int1] in [dttg_hour,dttg_min,dttg_sec,dttg_millisec] then begin + hastimeformat:= true; + end; + end; + hasdateformat:= false; + for int1:= 0 to high(grouporder) do begin + if grouporder[int1] in [dttg_year,dttg_mon,dttg_day] then begin + hasdateformat:= true; + dateorder[int2]:= grouporder[int1]; + inc(int2); + if int2 > high(dateorder) then begin + break; + end; + end; + end; + for int1:= 0 to high(dateorder)do begin + if dateorder[int1] = dttg_none then begin + break; + end; + for int2:= high(defaultdateorder) downto 0 do begin + if defaultdateorder[int2] = dateorder[int1] then begin + defaultdateorder[int2]:= dttg_none; + break; + end; + end; + end; + for int1:= high(dateorder) downto 0 do begin + if dateorder[int1] <> dttg_none then begin + break; + end; + for int2:= high(defaultdateorder) downto 0 do begin + if defaultdateorder[int2] <> dttg_none then begin + dateorder[int1]:= defaultdateorder[int2]; + defaultdateorder[int2]:= dttg_none; + break; + end; + end; + end; + + int2:= length(text); + if (int2 > 2) and isnumber(text) then begin + mstr1:= ''; + int1:= 1; + while int1 <= int2 do begin + mstr1:= mstr1+copy(text,int1,2)+' '; + int1:= int1 + 2; + end; + end + else begin + mstr1:= struppercase(text); + end; + setlength(ar1,length(mstr1)); //max + int2:= 0; + po1:= pmsechar(mstr1); + tisep:= defaultformatsettingsmse.timeseparator; + while po1^ <> #0 do begin //split numerals + case po1^ of + '0'..'9': begin + po2:= po1; + while (po1^ >= '0') and (po1^ <= '9') do begin + inc(po1); + end; + int3:= po1-po2; + setlength(ar1[int2],int3); + move(po2^,pointer(ar1[int2])^,int3*sizeof(msechar)); + inc(int2); + dec(po1); + end; + 'A','P': begin + setlength(ar1[int2],1); + ar1[int2]:= po1^; + inc(int2); + inc(po1); + if po1^ <> 'M' then begin + dec(po1) + end; + end; + else begin + if po1^ = tisep then begin + setlength(ar1[int2],1); + ar1[int2]:= ':'; + inc(int2); + end; + end; + end; + inc(po1); + end; + setlength(ar1,int2); + + month:= 0; //check month names + hasmonthname:= false; + for int1:= 1 to 12 do begin + if pos(struppercase(defaultformatsettingsmse.longmonthnames[int1]), + mstr1) <> 0 then begin + month:= int1; + hasmonthname:= true; + break; + end; + end; + if month = 0 then begin + for int1:= 1 to 12 do begin + if pos(struppercase(defaultformatsettingsmse.shortmonthnames[int1]), + mstr1) <> 0 then begin + month:= int1; + hasmonthname:= true; + break; + end; + end; + end; + + ispm:= false; //split date/time formats + setlength(datear,length(ar1)); //max + setlength(timear,length(ar1)); //max + int2:= 0; + int3:= 0; + for int1:= 0 to high(ar1) do begin + case ar1[int1][1] of + 'P': begin + ispm:= true; + end; + '0'..'9': begin + if (int1 > 0) and (ar1[int1-1][1] = ':') or + (int1 < high(ar1)) and (ar1[int1+1][1] = ':') then begin + timear[int3]:= int1; + inc(int3); + end + else begin + datear[int2]:= int1; + inc(int2); + end; + end; + end; + end; + + setlength(datear,int2); + setlength(timear,int3); + decodedate(refdate,year,defmonth,day); +// decodetime(refdate,hour,minute,second,millisecond); + if (high(timear) < 0) and not hasdateformat then begin + timear:= datear; //use entries for time + datear:= nil; + end; + case high(datear) of + -1: begin + end; + 0: begin + day:= strtoint(ar1[datear[0]]); + end; + 1: begin + if month = 0 then begin //no month name found + if finddateorder(dttg_mon) > finddateorder(dttg_day) then begin + day:= strtoint(ar1[datear[0]]); + month:= strtoint(ar1[datear[1]]); + end + else begin + day:= strtoint(ar1[datear[1]]); + month:= strtoint(ar1[datear[0]]); + end; + end + else begin + if finddateorder(dttg_year) > finddateorder(dttg_day) then begin + day:= strtoint(ar1[datear[0]]); + year:= strtoint(ar1[datear[1]]); + end + else begin + day:= strtoint(ar1[datear[1]]); + year:= strtoint(ar1[datear[0]]); + end; + end; + end; + else begin //>= 2 + for int1:= 0 to 2 do begin + mstr1:= ar1[datear[int1]]; + int2:= strtoint(mstr1); + case dateorder[int1] of + dttg_year: begin + if length(mstr1) <= 2 then begin + int3:= defaultformatsettingsmse.twodigityearcenturywindow; + int4:= year-int3; //window start + int5:= int4 div 100; //century + if (int3 <> 0) and ((int4 mod 100) > int2) then begin + inc(int5); + end; + int2:= int2 + int5 * 100; + end; + year:= int2; + end; + dttg_mon: begin + month:= int2; + end; + dttg_day: begin + day:= int2; + end; + end; + end; + end; + end; + if month = 0 then begin + month:= defmonth; //use current month + end; + int1:= high(timear); + if int1 >= 0 then begin + if int1 >= 3 then begin + millisecond:= strtoint(ar1[timear[3]]); + end + else begin + millisecond:= 0; + end; + if int1 >= 2 then begin + second:= strtoint(ar1[timear[2]]); + end + else begin + second:= 0; + end; + if int1 >= 1 then begin + minute:= strtoint(ar1[timear[1]]); + end + else begin + minute:= 0; + end; + hour:= strtoint(ar1[timear[0]]); + if ispm and (hour < 12) then begin + hour:= hour + 12; + end; + if high(datear) >= 0 then begin + if not tryencodedate(year,month,day,dt1) then begin + exit; + end; + if not tryencodetime(hour,minute,second,millisecond,dt2) then begin + exit; + end; + value:= composedatetime(dt1,dt2); + result:= true; + end + else begin + if not tryencodetime(hour,minute,second,millisecond,value) then begin + exit; + end; + result:= true; + end; + end + else begin + if (high(datear) >= 0) or hasmonthname then begin + if not tryencodedate(year,month,day,value) then begin + exit; + end; + result:= true; + end + else begin + if text = ' ' then begin + result:= true; + if hasdateformat and hastimeformat or + not(hasdateformat or hastimeformat) then begin + value:= refdate; + end + else begin + if hasdateformat then begin + value:= trunc(refdate); + end + else begin + value:= frac(refdate); + end; + end; + exit; + end; + end; + end; + end; + if result then begin + checkdateconvert(convert,value); + end; +end; + +function stringtodatetime(const avalue: msestring; const aformat: msestring; + const convert: dateconvertty = dc_none): tdatetime; +begin + if not trystringtodatetime(avalue,aformat,result,convert) then begin + formaterror(avalue); + end; +end; + +function trystringtodatetime(const text: msestring; out value: tdatetime; + const convert: dateconvertty = dc_none): boolean; +var + mstr1: msestring; + datsep: msechar; +begin + result:= true; + if text = '' then begin + value:= emptydatetime; + end + else begin + if text = ' ' then begin + if convert = dc_toutc then begin + value:= nowutc; + end + else begin + value:= nowlocal; + end; + end + else begin + datsep:= defaultformatsettingsmse.dateseparator; + if (countchars(text,datsep) = 0) and + (countchars(text,defaultformatsettingsmse.timeseparator) = 0) then begin + case length(text) of + 3,4: begin + mstr1:= copy(text,1,2)+datsep+copy(text,3,2); + end; + 5,6: begin + mstr1:= copy(text,1,2)+datsep+copy(text,3,2)+datsep+ + copy(text,5,2); + end; + else begin + mstr1:= text; + end; + end; + result:= trystrtodatetime(ansistring(mstr1),value); + end + else begin + result:= trystrtodatetime(ansistring(text),value); + end; + if result then begin + checkdateconvert(convert,value); + end; + end; + end; +end; + +function stringtodatetime(const avalue: msestring; + const convert: dateconvertty = dc_none): tdatetime; +begin + if not trystringtodatetime(avalue,result,convert) then begin + formaterror(avalue); + end; +end; + +function trystringtodate(const text: msestring; + const aformat: msestring; out value: tdatetime; + const convert: dateconvertty = dc_none): boolean; +begin + if text = '' then begin + value:= emptydatetime; + result:= true; + end + else begin + result:= trystringtodatetime(text,aformat,value,convert); + if result then begin + value:= trunc(value); + end; + end; +end; + +function stringtodate(const avalue: msestring; + const aformat: msestring; + const convert: dateconvertty = dc_none): tdatetime; +begin + if not trystringtodate(avalue,aformat,result,convert) then begin + formaterror(avalue); + end; +end; + +function trystringtodate(const text: msestring; out value: tdatetime; + const convert: dateconvertty = dc_none): boolean; +begin + if text = '' then begin + value:= emptydatetime; + result:= true; + end + else begin + result:= trystringtodatetime(text,value,convert); + if result then begin + value:= trunc(value); + end; + end; +end; + +function stringtodate(const avalue: msestring; + const convert: dateconvertty = dc_none): tdatetime; +begin + if not trystringtodate(avalue,result,convert) then begin + formaterror(avalue); + end; +end; + +function trystringtotime(const text: msestring; + const aformat: msestring; out value: tdatetime; + const convert: dateconvertty = dc_none): boolean; +var + mstr1: msestring; +begin + if text = '' then begin + value:= emptydatetime; + result:= true; + end + else begin + if aformat = '' then begin + mstr1:= 'tt'; + end + else begin + mstr1:= aformat; + end; + result:= trystringtodatetime(text,mstr1,value,convert); + if result then begin + value:= frac(value); + end; + end; +end; + +function stringtotime(const avalue: msestring; + const aformat: msestring; + const convert: dateconvertty = dc_none): tdatetime; +begin + if not trystringtotime(avalue,aformat,result,convert) then begin + formaterror(avalue); + end; +end; + +function trystringtotime(const text: msestring; out value: tdatetime; + const convert: dateconvertty = dc_none): boolean; +//var +// mstr1: msestring; +begin + if text = '' then begin + value:= emptydatetime; + result:= true; + end + else begin + result:= trystringtodatetime(text,value,convert); + if result then begin + value:= frac(value); + end; + end; +end; + +function stringtotime(const avalue: msestring; + const convert: dateconvertty = dc_none): tdatetime; +begin + if not trystringtotime(avalue,result,convert) then begin + formaterror(avalue); + end; +end; + +function timemse(const value: tdatetime): tdatetime; + //bringt timeanteil im mseformat +begin + result:= frac(value); +// if result = 0 then begin +// result:= nulltime; +// end; +end; + +function bcdtoint(inp: byte): integer; +begin + result:= ((inp and $f0) shr 4) * 10 + (inp and $0f); +end; + +function inttobcd(inp: integer): byte; +begin + result:= byte(((inp div 10) shl 4) + (inp mod 10)) +end; + +function formatfloatmse(value: double; format: msestring; + const formatsettings: tformatsettingsmse; + const dot: boolean = false): msestring; + +var + po1,po2: pmsechar; + expsign{,noexpsign}: boolean; + + procedure quote; + begin + case po2^ of + '''': begin //'quoted string + inc(po2); + while po2^ <> #0 do begin + if po2^ = '''' then begin + inc(po2); + if po2^ <> '''' then begin + break; + end; + end; + po1^:= po2^; + inc(po1); + inc(po2); + end; + end; + '"': begin //"quoted string + inc(po2); + while po2^ <> #0 do begin + if po2^ = '"' then begin + inc(po2); + if po2^ <> '"' then begin + break; + end; + end; + po1^:= po2^; + inc(po1); + inc(po2); + end; + end; + end; + end; + + procedure checkexp; + begin + if (po2+1)^ = '+' then begin + expsign:= true; + inc(po2); + end + else begin + if (po2+1)^ = '-' then begin + inc(po2); + end; + end; + end; + +var + int1,int2,int3: integer; + decimalsep,thousandsep: msechar; + intopt,intmust,fracmust,fracopt,expopt,expmust: integer; + decifound,doubledecifound,thousandfound,numberprinted,expofound, + engfound,engsymfound,engsymnospacefound: boolean; + mstr1: msestring; + format1: msestring; + mantissaend: integer; + ar1: array[0..2] of integer; //indexes positive, negative, zero + expchar: msechar; + bo1: boolean; + po3,po4: pmsechar; + +begin + result:= ''; + if value = emptyreal then begin + exit; + end; + checkformatmacros(format); + ar1[0]:= 0; + with formatsettings do begin + if dot then begin + decimalsep:= '.'; + end + else begin + decimalsep:= decimalseparator; + end; + bo1:= format = 'C'; + if (format = 'c') or bo1 then begin + if bo1 then begin + mstr1:= ''; + end + else begin + mstr1:= currencystring; + end; + if value < 0 then begin + case negcurrformat of + 0: begin + result:= '('+mstr1; + end; + 1: begin + result:= '-'+mstr1; + end; + 2: begin + result:= mstr1+'-'; + end; + 3: begin + result:= mstr1; + end; + 4,15: begin + result:= '('; + end; + 5,8: begin + result:= '-'; + end; + 9: begin + result:= '-'+mstr1+' '; + end; + 11: begin + result:= mstr1+' '; + end; + 12: begin + result:= mstr1+' -'; + end; + 14: begin + result:= '('+mstr1+' '; + end; + end; + end + else begin + case currencyformat of + 0: begin + result:= mstr1; + end; + 2: begin + result:= mstr1 + ' '; + end; + end; + end; + result:= result+doubletostring(abs(value),currencydecimals, + fsm_fix,decimalsep,thousandseparator); + if value < 0 then begin + case negcurrformat of + 0,14: begin + result:= result + ')'; + end; + 3,11: begin + result:= result + '-'; + end; + 4: begin + result:= result + mstr1 + ')'; + end; + 5: begin + result:= result + mstr1; + end; + 6: begin + result:= result + '-' + mstr1; + end; + 7: begin + result:= result + mstr1 + '-'; + end; + 8: begin + result:= result + ' ' + mstr1; + end; + 10: begin + result:= result + ' ' + mstr1 + '-'; + end; + 13: begin + result:= result + '- ' + mstr1; + end; + 15: begin + result:= result + ' ' + mstr1 + ')' + end; + end; + end + else begin + case currencyformat of + 1: begin + result:= result + mstr1; + end; + 3: begin + result:= result + ' ' + mstr1; + end; + end; + end; + exit; + end; + end; + expchar:= 'E'; + setlength(result,length(format)+50); //max + numberprinted:= false; + po1:= pmsechar(result); + po2:= pmsechar(format); + int1:= 0; //arrayindex + while po2^ <> #0 do begin + quote; + if po2^ = ';' then begin + ar1[int1]:= po2 - pmsechar(pointer(format)); + inc(int1); + if int1 = 3 then begin + break; + end; + end; + inc(po2); + end; + if int1 < 3 then begin + ar1[int1]:= length(format); + end; + if (value = 0) and (int1 >= 2) then begin + setlength(format1,ar1[2]-ar1[1]-1); + move((pmsechar(pointer(format))+ar1[1]+1)^,pmsechar(pointer(format1))^, + (ar1[2]-ar1[1]-1)*sizeof(msechar)); + po2:= pmsechar(format1); + end + else begin + if (value < 0) and (int1 >= 1) then begin + setlength(format1,ar1[1]-ar1[0]-1); + move((pmsechar(pointer(format))+ar1[0]+1)^,pmsechar(pointer(format1))^, + (ar1[1]-ar1[0]-1)*sizeof(msechar)); + po2:= pmsechar(format1); + end + else begin + setlength(format1,ar1[0]); + move((pmsechar(pointer(format)))^,pmsechar(pointer(format1))^, + (ar1[0])*sizeof(msechar)); + po2:= pmsechar(format1); + end; + end; + if format1 = '' then begin + result:= doubletostring(value,0,fsm_default,decimalsep); + end + else begin + if int1 > 0 then begin + value:= abs(value); //no sign + end; + po1:= pmsechar(result); + while po2^ <> #0 do begin + quote; + case po2^ of + #0: begin //was terminating quote + end; + ',','.','0','#': begin + intopt:= 0; + intmust:= 0; + fracopt:= 0; + fracmust:= 0; + expopt:= 0; + expmust:= 0; + decifound:= false; + doubledecifound:= false; + thousandfound:= false; + expofound:= false; + engfound:= false; + engsymfound:= false; + engsymnospacefound:= false; + expsign:= false; + while po2^ <> #0 do begin + case po2^ of + '.': begin + decifound:= true; + if (po2+1)^ = '.' then begin + doubledecifound:= true; + end; + end; + ',': begin + thousandfound:= true; + end; + 'e','E': begin + expofound:= true; + expchar:= po2^; + checkexp; + end; + 'f','F': begin + engfound:= true; + expchar:= msechar(ord(po2^)-1); + checkexp; + end; + 'g','G': begin + engsymfound:= true; + engfound:= true; + if po2^ = 'g' then begin + engsymnospacefound:= true; + end; + expchar:= msechar(ord(po2^)-2); + checkexp; + end; + '0': begin + if expofound or engfound then begin + inc(expmust); + end + else begin + if decifound then begin + inc(fracmust); + end + else begin + inc(intmust); + end; + end; + end; + '#': begin + if expofound or engfound then begin + inc(expopt); + end + else begin + if decifound then begin + inc(fracopt); + end + else begin + inc(intopt); + end; + end; + end + else begin + break; + end; + end; + inc(po2); + end; + if not numberprinted then begin + numberprinted:= true; + if thousandfound then begin + thousandsep:= formatsettings.thousandseparator; + end + else begin + thousandsep:= #0; + end; + if expofound then begin + mstr1:= doubletostring(value,fracmust+fracopt,fsm_sci,decimalsep, + thousandsep); + end + else begin + if engfound then begin + if engsymfound then begin + int1:= ord(fsm_engsymfix) - ord(fsm_engfix); + end + else begin + int1:= 0; + end; + if not doubledecifound then begin + mstr1:= doubletostring(value,fracopt+fracmust, + floatstringmodety(ord(fsm_engfix)+int1),decimalsep,thousandsep); + end + else begin + mstr1:= doubletostring(value,fracopt+fracmust, + floatstringmodety(ord(fsm_engflo)+int1),decimalsep,thousandsep); + if mstr1 <> '' then begin + po3:= pointer(mstr1); + if po3^ = '-' then begin + inc(po3); + end; + po4:= po3; + while (po3^ >= '0') and (po3^ <= '9') do begin + //no thousandsep possible + inc(po3); + end; + int1:= po3-po4-1; + fracmust:= fracmust-int1; + if fracmust < 0 then begin + fracopt:= fracopt+fracmust; + fracmust:= 0; + if fracopt < 0 then begin + fracopt:= 0; + end; + end; + end; + end; + end + else begin + if intopt+intmust+fracmust+fracopt = 0 then begin + mstr1:= doubletostring(value,0,fsm_default,decimalsep,thousandsep); + end + else begin + mstr1:= doubletostring(value,fracmust+fracopt,fsm_fix, + decimalsep,thousandsep); + end; + end; + end; + if expofound or engfound then begin //format exponent + if (length(mstr1) > 5) and (mstr1[length(mstr1)-4] = expochar) then begin + if {noexpsign or} not expsign then begin + int1:= length(mstr1)-3; + if mstr1[int1] = '+' then begin + delete(mstr1,int1,1); //remove exp sign + end; + end; + expmust:= expmust+expopt; + if expmust = 0 then begin + expmust:= 1; + end; + int2:= length(mstr1)-expmust+1; //last zero + int3:= length(mstr1)-2; //firstzero + for int1:= int3 to int2 do begin + if mstr1[int1] <> '0' then begin + int2:= int1; + break; + end; + end; + delete(mstr1,int3,int2-int3); //remove leading zeros end; + end; + end; + + int1:= findlastchar(mstr1,decimalsep)-1; //format mantissa + if int1 <= 0 then begin + int1:= length(mstr1); + end; + int2:= 1; + if mstr1[1] = '-' then begin + inc(int2); //firstnumber + end; + if (intmust = 0) and (mstr1[int2] = '0') then begin + delete(mstr1,int2,1); //remove first 0 + dec(int1); + end; + int3:= intmust - int1 + int2 - 1; + if thousandsep <> #0 then begin + int3:= int3 + (int1 + int2 - 1) div 4; + end; + if int3 > 0 then begin + insert(copy(msenullen,1,int3),mstr1,int2); //insert zeros + inc(int1,int3); + end; + int3:= intmust + intopt - int1 + int2 - 1; + if int3 > 0 then begin + insert(copy(msespace,1,int3),mstr1,1); //insert spaces + inc(int1,int3); + end; + int2:= int1 + fracmust+1; + mantissaend:= findchar(mstr1,expochar); //ok for exa + if (mantissaend > 0) and (mantissaend < length(mstr1)) then begin + //not exa + mstr1[mantissaend]:= expchar; + end + else begin + if (mantissaend = 0) and engsymfound then begin + mantissaend:= length(mstr1); + end; + end; + dec(mantissaend); + if mantissaend <= 0 then begin + mantissaend:= length(mstr1); + end; + for int3:= mantissaend downto int2 do begin + if (mstr1[int3] <> '0') then begin //remove traling zeros + int2:= int3; + break; + end; + end; + if engsymnospacefound and (mstr1 <> '') and + (mstr1[length(mstr1)] = ' ') then begin + setlength(mstr1,length(mstr1)-1); + end; + if int2 < length(mstr1) then begin + if mstr1[int2] = decimalsep then begin + dec(int2); + end; + delete(mstr1,int2+1,mantissaend-int2); + end; + move(pointer(mstr1)^,po1^,length(mstr1)*sizeof(msechar)); + inc(po1,length(mstr1)); + end; + end + else begin + po1^:= po2^; + inc(po1); + inc(po2); + end; + end; + end; + setlength(result,po1-pmsechar(result)); + end; +end; + +function formatfloatmse(const value: double; const format: msestring; + const dot: boolean = false): msestring; overload; +begin + result:= formatfloatmse(value,format,defaultformatsettingsmse,dot); +end; + +function realtostrmse(const value: double; + const dot: boolean = false): msestring; +var + sep: msechar; +begin + sep:= '.'; + if not dot then begin + sep:= defaultformatsettingsmse.decimalseparator; + end; + result:= doubletostring(value,0,fsm_default,sep); +end; + +function realtytostrmse(const value: double; + const dot: boolean = false): msestring; +begin + if value = emptyreal then begin + result:= ''; + end + else begin + result:= realtostrmse(value,dot); + end; +end; + +function inttostr(const value: integer): string; +var + buffer: array[0..22] of char; + int1,int2: integer; + lwo1,lwo2: longword; +begin + lwo1:= abs(value); + if lwo1 = 0 then begin + result:= '0'; + exit; + end; + int1:= high(buffer); + while lwo1 > 0 do begin + lwo2:= lwo1 div 10; + buffer[int1]:= char(lwo1 - lwo2 * 10 + ord('0')); + lwo1:= lwo2; + dec(int1); + end; + if value < 0 then begin + buffer[int1]:= char('-'); + dec(int1); + end; + int2:= (high(buffer))-int1; + setlength(result,int2); + move(buffer[int1+1],pointer(result)^,int2*sizeof(char)); +end; + +function inttostrmse(const value: integer): msestring; +var + buffer: array[0..22] of msechar; + int1,int2: integer; + lwo1,lwo2: longword; +begin + lwo1:= abs(value); + if lwo1 = 0 then begin + result:= '0'; + exit; + end; + int1:= high(buffer); + while lwo1 > 0 do begin + lwo2:= lwo1 div 10; + buffer[int1]:= msechar(lwo1 - lwo2 * 10 + ord('0')); + lwo1:= lwo2; + dec(int1); + end; + if value < 0 then begin + buffer[int1]:= msechar('-'); + dec(int1); + end; + int2:= (high(buffer))-int1; + setlength(result,int2); + move(buffer[int1+1],pointer(result)^,int2*sizeof(msechar)); +end; + +function inttostr(const value: longword): string; +var + buffer: array[0..22] of char; + int1,int2: integer; + lwo1,lwo2: longword; +begin + lwo1:= value; + if lwo1 = 0 then begin + result:= '0'; + exit; + end; + int1:= high(buffer); + while lwo1 > 0 do begin + lwo2:= lwo1 div 10; + buffer[int1]:= char(lwo1 - lwo2 * 10 + ord('0')); + lwo1:= lwo2; + dec(int1); + end; + int2:= (high(buffer))-int1; + setlength(result,int2); + move(buffer[int1+1],pointer(result)^,int2*sizeof(char)); +end; + +function inttostrmse(const value: longword): msestring; +var + buffer: array[0..22] of msechar; + int1,int2: integer; + lwo1,lwo2: longword; +begin + lwo1:= value; + if lwo1 = 0 then begin + result:= '0'; + exit; + end; + int1:= high(buffer); + while lwo1 > 0 do begin + lwo2:= lwo1 div 10; + buffer[int1]:= msechar(lwo1 - lwo2 * 10 + ord('0')); + lwo1:= lwo2; + dec(int1); + end; + int2:= (high(buffer))-int1; + setlength(result,int2); + move(buffer[int1+1],pointer(result)^,int2*sizeof(msechar)); +end; + +function inttostr(const value: int64): string; +var + buffer: array[0..22] of char; + int1,int2: integer; + lwo1,lwo2: qword; +begin + lwo1:= abs(value); + if lwo1 = 0 then begin + result:= '0'; + exit; + end; + int1:= high(buffer); + while lwo1 > 0 do begin + lwo2:= lwo1 div 10; + buffer[int1]:= char(lwo1 - lwo2 * 10 + ord('0')); + lwo1:= lwo2; + dec(int1); + end; + if value < 0 then begin + buffer[int1]:= char('-'); + dec(int1); + end; + int2:= (high(buffer))-int1; + setlength(result,int2); + move(buffer[int1+1],pointer(result)^,int2*sizeof(char)); +end; + +function inttostrmse(const value: int64): msestring; +var + buffer: array[0..22] of msechar; + int1,int2: integer; + lwo1,lwo2: qword; +begin + lwo1:= abs(value); + if lwo1 = 0 then begin + result:= '0'; + exit; + end; + int1:= high(buffer); + while lwo1 > 0 do begin + lwo2:= lwo1 div 10; + buffer[int1]:= msechar(lwo1 - lwo2 * 10 + ord('0')); + lwo1:= lwo2; + dec(int1); + end; + if value < 0 then begin + buffer[int1]:= msechar('-'); + dec(int1); + end; + int2:= (high(buffer))-int1; + setlength(result,int2); + move(buffer[int1+1],pointer(result)^,int2*sizeof(msechar)); +end; + +function inttostr(const value: qword): string; +var + buffer: array[0..22] of char; + int1,int2: integer; + lwo1,lwo2: qword; +begin + lwo1:= value; + if lwo1 = 0 then begin + result:= '0'; + exit; + end; + int1:= high(buffer); + while lwo1 > 0 do begin + lwo2:= lwo1 div 10; + buffer[int1]:= char(lwo1 - lwo2 * 10 + ord('0')); + lwo1:= lwo2; + dec(int1); + end; + int2:= (high(buffer))-int1; + setlength(result,int2); + move(buffer[int1+1],pointer(result)^,int2*sizeof(char)); +end; + +function inttostrmse(const value: qword): msestring; +var + buffer: array[0..22] of msechar; + int1,int2: integer; + lwo1,lwo2: qword; +begin + lwo1:= value; + if lwo1 = 0 then begin + result:= '0'; + exit; + end; + int1:= high(buffer); + while lwo1 > 0 do begin + lwo2:= lwo1 div 10; + buffer[int1]:= msechar(lwo1 - lwo2 * 10 + ord('0')); + lwo1:= lwo2; + dec(int1); + end; + int2:= (high(buffer))-int1; + setlength(result,int2); + move(buffer[int1+1],pointer(result)^,int2*sizeof(msechar)); +end; +{ +function formatfloatmse(const value: double; const format: msestring; + const dot: boolean = false): msestring; +var + int1: integer; +begin + setlength(result,length(format)+200); //max + int1:= floattotextfmt(pmsechar(result),value,pmsechar(format), + defaultformatsettingsmse); + setlength(result,int1); + if dot then begin +// replacechar1(result,widechar(decimalseparator),widechar('.')); + replacechar1(result,defaultformatsettingsmse.decimalseparator,widechar('.')); + end; +end; +} +function trystrtodouble(const s: lstringty; out value: double; + const decimalseparator: char): boolean; overload; +var + po1,decisep,mantstart,mantend: pchar; + pend: pchar; + neg,negexp: boolean; + mant,do1: double; + exp: integer; +begin + result:= false; + if s.len = 0 then begin + exit; + end; + pend:= s.po+s.len; + po1:= s.po; + while ((po1^ = ' ') or (po1^ = c_tab)) do begin + inc(po1); + if po1 = pend then begin + exit; + end; + end; + neg:= po1^ = '-'; + if po1^ = '+' then begin + inc(po1); + end; + if neg then begin + inc(po1); + end; + decisep:= nil; + mantstart:= po1; + mant:= 0; + exp:= 0; + while true do begin + case po1^ of + '0'..'9': begin + mant:= mant*10 + (byte(po1^)-byte('0')); + end; + 'e','E': begin + mantend:= po1; + inc(po1); + negexp:= po1^ = '-'; + if po1^ = '+' then begin + inc(po1); + end; + if negexp then begin + inc(po1); + end; + if (po1^ < '0') or (po1^ > '9') then begin + exit; + end; + while true do begin + case po1^ of + '0'..'9': begin + exp:= exp * 10 + (byte(po1^)-byte('0')); + end; + else begin + break; + end; + end; + inc(po1); + if po1 = pend then begin + break; + end; + end; + if negexp then begin + exp:= -exp; + end; + break; + end; + else begin + if po1^ = decimalseparator then begin + if decisep <> nil then begin + exit; + end; + decisep:= po1; + end + else begin + mantend:= po1; + break; + end; + end; + end; + inc(po1); + if po1 = pend then begin + mantend:= po1; + break; + end; + end; + if (mantstart = mantend) or (decisep = mantstart) and + (mantend-mantstart = 1) then begin + exit; //empty + end; + if decisep <> nil then begin + exp:= exp-(mantend-decisep)+1; + end; + while po1 <> pend do begin + if not((po1^ = ' ') or (po1^ = c_tab)) then begin + exit; + end; + inc(po1); + end; + if not tryintexp10(exp,do1) then begin + exit; + end; + do1:= mant * do1; + if neg then begin + do1:= -do1; + end; + value:= do1; + result:= true; +end; + +function trystrtodouble(const s: lmsestringty; out value: double; + const decimalseparator: msechar): boolean; overload; +var + po1,decisep,mantstart,mantend: pmsechar; + pend: pmsechar; + neg,negexp: boolean; + mant,do1: double; + exp: integer; +begin + result:= false; + if s.len = 0 then begin + exit; + end; + pend:= s.po+s.len; + po1:= s.po; + while ((po1^ = ' ') or (po1^ = c_tab)) do begin + inc(po1); + if po1 = pend then begin + exit; + end; + end; + neg:= po1^ = '-'; + if po1^ = '+' then begin + inc(po1); + end; + if neg then begin + inc(po1); + end; + decisep:= nil; + mantstart:= po1; + mant:= 0; + exp:= 0; + while true do begin + case po1^ of + '0'..'9': begin + mant:= mant*10 + (byte(po1^)-byte('0')); + end; + 'e','E': begin + mantend:= po1; + inc(po1); + negexp:= po1^ = '-'; + if po1^ = '+' then begin + inc(po1); + end; + if negexp then begin + inc(po1); + end; + if (po1^ < '0') or (po1^ > '9') then begin + exit; + end; + while true do begin + case po1^ of + '0'..'9': begin + exp:= exp * 10 + (byte(po1^)-byte('0')); + end; + else begin + break; + end; + end; + inc(po1); + if po1 = pend then begin + break; + end; + end; + if negexp then begin + exp:= -exp; + end; + break; + end; + else begin + if po1^ = decimalseparator then begin + if decisep <> nil then begin + exit; + end; + decisep:= po1; + end + else begin + mantend:= po1; + break; + end; + end; + end; + inc(po1); + if po1 = pend then begin + mantend:= po1; + break; + end; + end; + if (mantstart = mantend) or (decisep = mantstart) and + (mantend-mantstart = 1) then begin + exit; //empty + end; + if decisep <> nil then begin + exp:= exp-(mantend-decisep)+1; + end; + while po1 <> pend do begin + if not((po1^ = ' ') or (po1^ = c_tab)) then begin + exit; + end; + inc(po1); + end; + if not tryintexp10(exp,do1) then begin + exit; + end; + do1:= mant * do1; + if neg then begin + do1:= -do1; + end; + value:= do1; + result:= true; +end; + +function trystrtodouble(const s: string; out value: double; + const decimalseparator: char): boolean; overload; +var + lstr1: lstringty; +begin + lstr1.po:= pointer(s); + lstr1.len:= length(s); + result:= trystrtodouble(lstr1,value,decimalseparator); +end; + +function trystrtodouble(const s: msestring; out value: double; + const decimalseparator: msechar): boolean; overload; +var + lstr1: lmsestringty; +begin + lstr1.po:= pointer(s); + lstr1.len:= length(s); + result:= trystrtodouble(lstr1,value,decimalseparator); +end; + +function trystrtodouble(const s: string; out value: double): boolean; +begin + result:= trystrtodouble(s,value,defaultformatsettingsmse.decimalseparator); +end; + +function trystrtodouble(const s: msestring; out value: double): boolean; +begin + result:= trystrtodouble(s,value,defaultformatsettingsmse.decimalseparator); +end; + +function strtodouble(const s: string; + const decimalseparator: char): double; +begin + if not trystrtodouble(s,result,decimalseparator) then begin + raise EConvertError.CreateFmt(SInvalidFloat,[s]); + end; +end; + +function strtodouble(const s: msestring; + const decimalseparator: msechar): double; +begin + if not trystrtodouble(s,result,decimalseparator) then begin + raise EConvertError.CreateFmt(SInvalidFloat,[s]); + end; +end; + +function strtodouble(const s: string): double; +begin + result:= strtodouble(s,defaultformatsettingsmse.decimalseparator); +end; + +function strtodouble(const s: msestring): double; +begin + result:= strtodouble(s,defaultformatsettingsmse.decimalseparator); +end; + +function realToStr(const value: double): string; //immer'.' als separator +begin +{$ifdef withformatsettings} + result:= floattostr(value,defaultformatsettingsdot) +{$else} + result:= replacechar(floattostr(value),decimalseparator,'.'); +{$endif} +end; + +function StrToreal(const S: string): double; //immer'.' als separator +begin + result:= strtodouble(s,'.'); +end; + +function trystrtoreal(const s: string; out value: real): boolean; +begin + result:= trystrtodouble(s,double(value),'.'); +end; + +function StrToreal(const S: msestring): double; //immer'.' als separator +begin + result:= strtodouble(s,'.'); +end; + +function trystrtoreal(const s: msestring; out value: real): boolean; +begin + result:= trystrtodouble(s,double(value),'.'); +end; + +function realtytostring(const val: realty; const format: msestring = ''; + const scale: real = 1): msestring; +var + rea1: real; +begin + if val = emptyreal then begin + result:= emptyrealstring; + end + else begin + if scale <> 0 then begin + rea1:= val/scale; + end + else begin + rea1:= val; + end; + result:= formatfloatmse(rea1,format,defaultformatsettingsmse); + end; +end; + +function realtytostr(const val: realty; const format: msestring = ''; + const scale: real = 1): msestring; +begin + result:= realtytostring(val,format,scale); +end; + +function currencytostr(const avalue: currency): string; + //always '.' as as decimal separator +var + buffer: array[0..23] of char; + int1,int2: integer; + lwo1,lwo2: qword; +const + dotpos = high(buffer)-4; + +begin + lwo1:= abs(int64(avalue)); + if lwo1 = 0 then begin + result:= '0'; + exit; + end; + buffer[dotpos]:= '.'; + int1:= high(buffer); + while (lwo1 > 0) or (int1 >= dotpos-1) do begin + if int1 <> dotpos then begin + lwo2:= lwo1 div 10; + buffer[int1]:= msechar(lwo1 - lwo2 * 10 + ord('0')); + lwo1:= lwo2; + end; + dec(int1); + end; + if int64(avalue) < 0 then begin + buffer[int1]:= msechar('-'); + dec(int1); + end; + int2:= high(buffer); + while buffer[int2] = '0' do begin + dec(int2); + end; + if int2 = dotpos then begin + dec(int2); + end; + int2:= int2-int1; + setlength(result,int2); + move(buffer[int1+1],pointer(result)^,int2*sizeof(char)); +end; + +function currencytostrmse(const avalue: currency): msestring; + //always '.' as as decimal separator +var + buffer: array[0..23] of msechar; + int1,int2: integer; + lwo1,lwo2: qword; +const + dotpos = high(buffer)-4; + +begin + lwo1:= abs(int64(avalue)); + if lwo1 = 0 then begin + result:= '0'; + exit; + end; + buffer[dotpos]:= '.'; + int1:= high(buffer); + while (lwo1 > 0) or (int1 >= dotpos-1) do begin + if int1 <> dotpos then begin + lwo2:= lwo1 div 10; + buffer[int1]:= msechar(lwo1 - lwo2 * 10 + ord('0')); + lwo1:= lwo2; + end; + dec(int1); + end; + if int64(avalue) < 0 then begin + buffer[int1]:= msechar('-'); + dec(int1); + end; + int2:= high(buffer); + while buffer[int2] = '0' do begin + dec(int2); + end; + if int2 = dotpos then begin + dec(int2); + end; + int2:= int2-int1; + setlength(result,int2); + move(buffer[int1+1],pointer(result)^,int2*sizeof(msechar)); +end; + +function realtytostrrange(const val: realty; const format: msestring = ''; + const range: real = 1; const offset: real = 0): msestring; +var + rea1: real; +begin + if val = emptyreal then begin + result:= emptyrealstring; + end + else begin + if range <> 0 then begin + rea1:= val*range+offset; + end + else begin + rea1:= val; + end; + result:= formatfloatmse(rea1,format,defaultformatsettingsmse); + end; +end; + +const + expos: array[ord('A')..ord('z')] of shortint = + // A B C D E F G H I J K L M + ( 0, 0, 0, 0, 6*3, 0, 3*3, 0, 0, 0, 0, 0, 2*3, + // N O P Q R S T U V W X Y Z + 0, 0, 5*3, 0, 0, 0, 4*3, 0, 0, 0, 0, 8*3, 7*3, + //[ \ ] ^ _ ' + 0,0,0,0,0,0, + // a b c d e f g h i j k l m + -6*3, 0, 0, 0, 0,-5*3, 0, 0, 0, 0, 1*3, 0,-1*3, + // n o p q r s t u v w x y z + -3*3, 0,-4*3, 0, 0, 0, 0,-2*3, 0, 0, 0,-8*3,-7*3); + +function trystrtorealty(const ein: string; out value: realty; + forcevalue: boolean = false): boolean; +var + str1: string; + ch1: char; + sint1: shortint; +begin + str1:= trim(ein); + result:= true; + if not forcevalue and (str1 = emptyrealstring) then begin + value:= emptyreal; + end + else begin + removechar(str1,{$ifdef FPC}defaultformatsettingsmse.{$endif}thousandseparator); + if length(str1) > 0 then begin + ch1:= str1[length(str1)]; + if (ch1 >= 'A') and (ch1 <= 'z') then begin + sint1:= expos[ord(ch1)]; + if sint1 <> 0 then begin + setlength(str1,length(str1)-1); + str1:= str1 + 'E'+inttostr(sint1); + end; + end; + end; + result:= trystrtodouble(str1,double(value)); + end; +end; + +function trystrtorealty(const ein: msestring; out value: realty; + forcevalue: boolean = false): boolean; +var + str1: msestring; + ch1: msechar; + sint1: shortint; +begin + str1:= trim(ein); + result:= true; + if not forcevalue and (str1 = emptyrealstring) then begin + value:= emptyreal; + end + else begin + removechar(str1,{$ifdef FPC}defaultformatsettingsmse.{$endif}thousandseparator); + if length(str1) > 0 then begin + ch1:= str1[length(str1)]; + if (ch1 >= 'A') and (ch1 <= 'z') then begin + sint1:= expos[ord(ch1)]; + if sint1 <> 0 then begin + setlength(str1,length(str1)-1); + str1:= str1 + 'E'+inttostrmse(sint1); + end; + end; + end; + result:= trystrtodouble(str1,double(value)); + end; +end; + +function strtorealty(const ein: string; forcevalue: boolean = false): realty; +begin + if not trystrtorealty(ein,result,forcevalue) then begin + raise EConvertError.CreateFmt(SInvalidFloat,[ein]); + end; +end; + +function strtorealty(const ein: msestring; forcevalue: boolean = false): realty; +begin + if not trystrtorealty(ein,result,forcevalue) then begin + raise EConvertError.CreateFmt(SInvalidFloat,[ein]); + end; +end; + +function realtytostrdot(const val: realty): string; +begin + if val = emptyreal then begin + result:= emptyrealstring; + end + else begin + result:= ansistring(doubletostring(val)); +(* + {$ifdef withformatsettings} + result:= floattostr(val,defaultformatsettingsdot); + {$else} + result:= replacechar(floattostr(val),decimalseparator,'.'); + {$endif} + *) + end; +end; + +function realtytostrdotmse(const val: realty): msestring; +begin + if val = emptyreal then begin + result:= emptyrealstring; + end + else begin + result:= doubletostring(val); + end; +end; + +function strtorealtydot(const ein: string): realty; + +begin + if trim(ein) = emptyrealstring then begin + result:= emptyreal; + end + else begin + result:= strtodouble(ein,'.'); + end; +end; + +function strtorealtydot(const ein: msestring): realty; + +begin + if trim(ein) = emptyrealstring then begin + result:= emptyreal; + end + else begin + result:= strtodouble(ein,'.'); + end; +end; + +function trystrtorealtydot(const ein: string; out value: realty): boolean; +begin + result:= true; + if trim(ein) = emptyrealstring then begin + value:= emptyreal; + end + else begin + result:= trystrtodouble(ein,double(value),'.'); + end; +end; + +function trystrtorealtydot(const ein: msestring; out value: realty): boolean; +begin + result:= true; + if trim(ein) = emptyrealstring then begin + value:= emptyreal; + end + else begin + result:= trystrtodouble(ein,double(value),'.'); + end; +end; + +function bcdtostr(inp: byte): string; + //wandelt bcdwert in zwei ascii zeichen +begin + result:= char(byte(inp shr byte(4)) + ord('0'))+ + char(byte(inp and $0f) + ord('0')); +end; + +function bytetobcd(inp: byte): word; + //wandelt byte in bcdwert +begin + result:= (inp div 100 shl 8) or ((inp div 10) mod 10 shl 4) or (inp mod 10) +end; + +function bcdtobyte(inp: byte): byte; + //wandelt bcdbyte in byte +begin + result:= (inp shr 4)*10 + inp and $0f; +end; + +function wordtostr(const avalue: longword): string; +begin + str(avalue,result); +end; + +function bytetohex(const inp: byte): string; + //wandelt byte in zwei ascii hexzeichen +var + ch1,ch2: char; +begin + ch1:= char((inp shr 4) + byte('0')); + if ch1 > '9' then begin + ch1:= char(byte(ch1) + byte('A')-byte('0')-10); + end; + ch2:= char((inp and $0f) + byte('0')); + if ch2 > '9' then begin + ch2:= char(byte(ch2) + byte('A')-byte('0')-10); + end; + result:= ch1 + ch2; +end; + +function wordtohex(const inp: word; lsbfirst: boolean = false): string; + //wandelt word in vier ascii hexzeichen +begin + if lsbfirst then begin + result:= bytetohex(inp) + bytetohex(inp shr 8); + end + else begin + result:= bytetohex(inp shr 8) + bytetohex(inp); + end; +end; + +function valtohex(const avalue: byte): string; +begin + setlength(result,2); + pchar(pointer(result))^:= charhexlower[avalue shr 4]; + pchar(pchar(pointer(result))+1)^:= charhexlower[avalue and $f]; +end; + +function valtohex(const avalue: word): string; +begin + setlength(result,4); + pchar(pointer(result))^:= charhexlower[avalue shr 12]; + pchar(pchar(pointer(result))+1)^:= charhexlower[(avalue shr 8) and $f]; + pchar(pchar(pointer(result))+2)^:= charhexlower[(avalue shr 4) and $f]; + pchar(pchar(pointer(result))+3)^:= charhexlower[avalue and $f]; +end; + +function valtohex(const avalue: longword): string; +begin + setlength(result,8); + pchar(pointer(result))^:= charhexlower[avalue shr 28]; + pchar(pchar(pointer(result))+1)^:= charhexlower[(avalue shr 24) and $f]; + pchar(pchar(pointer(result))+2)^:= charhexlower[(avalue shr 20) and $f]; + pchar(pchar(pointer(result))+3)^:= charhexlower[(avalue shr 16) and $f]; + pchar(pchar(pointer(result))+4)^:= charhexlower[(avalue shr 12) and $f]; + pchar(pchar(pointer(result))+5)^:= charhexlower[(avalue shr 8) and $f]; + pchar(pchar(pointer(result))+6)^:= charhexlower[(avalue shr 4) and $f]; + pchar(pchar(pointer(result))+7)^:= charhexlower[avalue and $f]; +end; + +function valtohex(const avalue: qword): string; +begin + result:= valtohex(avalue shr 32)+valtohex(avalue); +end; + +function bytestrtostr(const inp: ansistring; base: numbasety = nb_hex; + spacechar: char = #0): string; + //wandelt bytefolge in ascii hexstring +var + int1: integer; +begin + result:= ''; + for int1:= 1 to length(inp) do begin + result:= result + intvaluetostr(byte(inp[int1]),base,8); + if (spacechar <> #0) and (int1 <> length(inp)) then begin + result:= result + spacechar; + end; + end; +end; + +function strtobytestr(inp: string): ansistring; + //wandelt hex asciistring in bytefolge +var + int1,int2, int3: integer; + str1: string; +begin + result:= ''; + removechar(inp,' '); + int2:= length(inp); + if int2 > 0 then begin + setlength(result,(int2+1) div 2); + setlength(str1,2); + int1:= 1; + int3:= 1; + while int1 <= int2 do begin + str1[1]:= inp[int1]; + inc(int1); + if int1 > int2 then begin + setlength(str1,1); + end + else begin + str1[2]:= inp[int1]; + end; + result[int3]:= char(strtohex(str1)); + inc(int1); + inc(int3); + end; + end; +end; + +function strtobytes(const inp: string; out dest: bytearty): boolean; +var + po1,po2: pchar; + int1: integer; + by1: shortint; +begin + result:= false; + int1:= length(inp)+1; + setlength(dest,int1 div 2); + po1:= @inp[int1]; + po2:= pchar(inp); + int1:= high(dest); + while po1 > po2 do begin + dec(po1); + by1:= hexchars[po1^]; + if by1 < 0 then begin + exit; + end; + dest[int1]:= by1; + + if po1 = po2 then begin + break; + end; + dec(po1); + by1:= hexchars[po1^]; + if by1 < 0 then begin + exit; + end; + dest[int1]:= dest[int1] or (by1 shl 4); + dec(int1); + end; + result:= true; +end; + +function bytestrtobin(const inp: ansistring; abstand: boolean): string; + //wandelt bytefolge in ascii binstring, + // letztes zeichen = anzahl gueltige bits in letztem byte +var + int1,int2,int3,int4: integer; +// str1: string; + by1,by2: byte; + +begin + result:= ''; + int2:= bitcount(inp)-1; + int3:= 1; + int4:= 0; + while int2 >= 0 do begin + by1:= byte(inp[int3]); + by2:= $01; + for int1:= 0 to 7 do begin + if by1 and by2 <> 0 then begin + result:= result + '1'; + end + else begin + result:= result + '0'; + end; + if int4+int1 >= int2 then begin + break; + end; + by2:= by2 shl 1; + end; + if int4+(int1 and $07) >= int2 then begin + break; + end; + if abstand then begin + result:= result + ' '; + end; + inc(int3); + inc(int4,8); + end; +end; + +function strtobinstr(inp: string): ansistring; + //wandelt bin asciistring in bytefolge, + // letztes byte = anzahl gueltige bits in vorletztem byte +var + int1,int2,int3: integer; + by1,by2: byte; + ch1: char; +begin + result:= ''; + removechar(inp,' '); + int1:= length(inp); + int3:= 1; + int2:= 0; + while int3 <= int1 do begin + by1:= 1; + by2:= 0; + for int2:= 0 to 7 do begin + if int3 + int2 > int1 then begin + break; + end; + ch1:= inp[int3+int2]; + if ch1 = '1' then begin + by2:= by2 or by1; + end + else begin + if ch1 <> '0' then begin + raise EConvertError.CreateFmt(SInvalidInteger,[inp]); + end; + end; + by1:= by1 shl 1; + end; + int3:= int3 + 8; + result:= result + char(by2); + end; + if length(result) > 0 then begin + result:= result + char(int2); + end; +end; + +function bitmaske(const data: ansistring): integer; +begin + if length(data) > 1 then begin + result:= byte(data[length(data)]); + if result > 8 then begin + result:= 8 + end; + end + else begin + result:= 0; + end; +end; + +function bitcount(const data: ansistring): integer; //anzahl gueltige bits +var + int1: integer; +begin + int1:= length(data); + if int1 > 1 then begin + result:= 8*(int1-2) + bitmaske(data); + end + else begin + result:= 0; + end; +end; + +function bintostr(inp: longword; digits: integer): string; + //convert longword to binstring, digits = bit count +var + int1: integer; +begin + setlength(result,digits); + for int1:= digits downto 1 do begin + result[int1]:= char(ord('0') + (inp and $1)); + inp:= inp shr 1; + end; +end; + +function bintostr(inp: qword; digits: integer): string; + //convert longword to binstring, digits = bit count +var + int1: integer; +begin + setlength(result,digits); + for int1:= digits downto 1 do begin + result[int1]:= char(ord('0') + (inp and $1)); + inp:= inp shr 1; + end; +end; + +function octtostr(inp: longword; digits: integer): string; + //convert longword to octaltring, digits = octet count +var + int1: integer; +begin + setlength(result,digits); + for int1:= digits downto 1 do begin + result[int1]:= char(ord('0') + (inp and $7)); + inp:= inp shr 3; + end; +end; + +function octtostr(inp: qword; digits: integer): string; + //convert longword to octaltring, digits = octet count +var + int1: integer; +begin + setlength(result,digits); + for int1:= digits downto 1 do begin + result[int1]:= char(ord('0') + (inp and $7)); + inp:= inp shr 3; + end; +end; + +function dectostr(const inp: integer; digits: integer): string; + //leading zeroes if digits < 0 +begin + result:= inttostr(abs(inp)); + if digits < 0 then begin + digits:= -digits; + if digits > length(nullen) then begin + digits:= length(nullen); + end; + result:= copy(nullen,1,digits-length(result)) + result; + end; + result:= copy(result,length(result)-digits+1,bigint); + if inp < 0 then begin + result:= '-' + result; + end; +end; + +function dectostr(const inp: int64; digits: integer): string; + //leading zeroes if digits < 0 +begin + result:= inttostr(abs(inp)); + if digits < 0 then begin + digits:= -digits; + if digits > length(nullen) then begin + digits:= length(nullen); + end; + result:= copy(nullen,1,digits-length(result)) + result; + end; + result:= copy(result,length(result)-digits+1,bigint); + if (inp < 0) and (result[1] <> '-') then begin + result:= '-' + result; + end; +end; + +function hextostr(inp: longword; digits: integer): string; + //wandelt longword in hexstring, stellen = anzahl nibbles +var + int1: integer; +begin + if digits = 0 then begin + digits:= (highestbit(inp)+4) div 4; + if digits = 0 then begin + digits:= 1; + end; + end; + setlength(result,digits); + for int1:= digits downto 1 do begin + result[int1]:= char(ord('0') + (inp and $f)); + if result[int1] > '9' then begin + inc(result[int1],ord('A')-ord('9')-1); + end; + inp:= inp shr 4; + end; +end; + +function hextostr(inp: qword; digits: integer): string; + //wandelt longword in hexstring, stellen = anzahl nibbles +var + int1: integer; +begin + if digits = 0 then begin + digits:= (highestbit64(inp)+4) div 4; + if digits = 0 then begin + digits:= 1; + end; + end; + setlength(result,digits); + for int1:= digits downto 1 do begin + result[int1]:= char(ord('0') + (inp and $f)); + if result[int1] > '9' then begin + inc(result[int1],ord('A')-ord('9')-1); + end; + inp:= inp shr 4; + end; +end; + +function hextostr(const inp: pointer; + digits: integer = 2*sizeof(pointer)): string; overload; + //convert pointer to hexstring, digits = nibble count +begin + result:= hextostr(ptruint(inp),digits); +end; + +function hextostrmse(inp: longword; digits: integer): msestring; + //wandelt longword in hexstring, stellen = anzahl nibbles +var + int1: integer; +begin + if digits = 0 then begin + digits:= (highestbit(inp)+4) div 4; + if digits = 0 then begin + digits:= 1; + end; + end; + setlength(result,digits); + for int1:= digits downto 1 do begin + result[int1]:= msechar(ord('0') + (inp and $f)); + if result[int1] > '9' then begin + inc(result[int1],ord('A')-ord('9')-1); + end; + inp:= inp shr 4; + end; +end; + +function hextostrmse(inp: qword; digits: integer): msestring; + //wandelt longword in hexstring, stellen = anzahl nibbles +var + int1: integer; +begin + if digits = 0 then begin + digits:= (highestbit64(inp)+4) div 4; + if digits = 0 then begin + digits:= 1; + end; + end; + setlength(result,digits); + for int1:= digits downto 1 do begin + result[int1]:= msechar(ord('0') + (inp and $f)); + if result[int1] > '9' then begin + inc(result[int1],ord('A')-ord('9')-1); + end; + inp:= inp shr 4; + end; +end; + +function hextostrmse(const inp: pointer; + digits: integer = 2*sizeof(pointer)): msestring; overload; + //convert pointer to hexstring, digits = nibble count +begin + result:= hextostrmse(ptruint(inp),digits); +end; + +function hextocstr(const inp: longword; stellen: integer): string; +begin + result:= '0x' + hextostr(inp, stellen); +end; + +function hextocstr(const inp: qword; stellen: integer): string; +begin + result:= '0x' + hextostr(inp, stellen); +end; + +function ptruinttocstr(inp: ptruint): string; + //convert ptrint to 0x... +var + int1: integer; +begin + result:= '0x'; + setlength(result,2+sizeof(ptrint)*2); + for int1:= length(result) downto 3 do begin + result[int1]:= char(ord('0') + (inp and $f)); + if result[int1] > '9' then begin + inc(result[int1],ord('A')-ord('9')-1); + end; + inp:= inp shr 4; + end; +end; + +function qwordtocstr(inp: qword): string; + //convert qword to 0x... +var + int1: integer; +begin + result:= '0x'; + int1:= 8*2; +// if inp <= $ffffffff then begin +// int1:= 4*2; +// end; + setlength(result,2+int1); + for int1:= length(result) downto 3 do begin + result[int1]:= char(ord('0') + (inp and $f)); + if result[int1] > '9' then begin + inc(result[int1],ord('A')-ord('9')-1); + end; + inp:= inp shr 4; + end; +end; + +function trystrtoint(const text: pchar; const len: int32; + out value: integer): boolean; +const + max = maxint div 10; +var + po1,pe: pchar; + neg: boolean; +begin + result:= false; + neg:= false; + value:= 0; + if len > 0 then begin + po1:= text; + pe:= po1 + len; + while ((po1^ = ' ') or (po1^ = c_tab)) and (po1 < pe) do begin + inc(po1); + end; + neg:= po1^ = char('-'); + if not neg then begin + if po1^ = '+' then begin + inc(po1); + end; + end + else begin + inc(po1); + end; + if po1 >= pe then begin + exit; + end; + while po1 < pe do begin + if (po1^ < '0') or (po1^ > '9') then begin + exit; + end; +// if value < 0 then begin +// exit; +// end; + if card32(value) > max then begin + exit; + end; + value:= value * 10 + (byte(po1^) - byte('0')); + inc(po1); + end; + end; + if neg then begin + if (value < 0) and (value <> minint) then begin + exit; + end; + value:= -value; + end + else begin + if value < 0 then begin + exit; + end; + end; + result:= true; +end; + +function trystrtoint(const text: lstringty; out value: integer): boolean; +begin + result:= trystrtoint(text.po,text.len,value); +end; + +function trystrtoint(const text: string; out value: integer): boolean; +begin + result:= trystrtoint(pointer(text),length(text),value); +end; + +function strtoint(const text: string): integer; +begin + if not trystrtoint(pointer(text),length(text),result) then begin + raise EConvertError.CreateFmt(SInvalidInteger,[text]); + end; +end; + +function trystrtoint(const text: msestring; out value: integer): boolean; +const + max = maxint div 10; +var + po1: pmsechar; + neg: boolean; +begin + result:= false; + neg:= false; + value:= 0; + if text <> '' then begin + po1:= pointer(text); + while (po1^ = ' ') or (po1^ = c_tab) do begin + inc(po1); + end; + neg:= po1^ = msechar('-'); + if not neg then begin + if po1^ = '+' then begin + inc(po1); + end; + end + else begin + inc(po1); + end; + if po1^ = #0 then begin + exit; + end; + while po1^ <> #0 do begin + if (po1^ < '0') or (po1^ > '9') then begin + exit; + end; +// if value < 0 then begin +// exit; +// end; + if card32(value) > max then begin + exit; + end; + value:= value * 10 + (word(po1^) - word('0')); + inc(po1); + end; + end; + if neg then begin + if (value < 0) and (value <> minint) then begin + exit; + end; + value:= -value; + end + else begin + if value < 0 then begin + exit; + end; + end; + result:= true; +end; + +function strtoint(const text: msestring): integer; +begin + if not trystrtoint(text,result) then begin + raise EConvertError.CreateFmt(SInvalidInteger,[string(text)]); + end; +end; + +function trystrtoint(const text: string; out value: longword): boolean; +const + max = $ffffffff div 10; +var + po1: pchar; +begin + result:= false; + value:= 0; + if text <> '' then begin + po1:= pointer(text); + while (po1^ = ' ') or (po1^ = c_tab) do begin + inc(po1); + end; + if po1^ = '+' then begin + inc(po1); + end; + if po1^ = #0 then begin + exit; + end; + while po1^ <> #0 do begin + if (po1^ < '0') or (po1^ > '9') then begin + exit; + end; + if value > max then begin + exit; + end; + value:= value * longword(10) + longword(byte(po1^) - byte('0')); + inc(po1); + end; + end; + result:= true; +end; + +function trystrtoint(const text: msestring; out value: longword): boolean; +const + max = $ffffffff div 10; +var + po1: pmsechar; +// neg: boolean; +begin + result:= false; + value:= 0; + if text <> '' then begin + po1:= pointer(text); + while (po1^ = ' ') or (po1^ = c_tab) do begin + inc(po1); + end; +// neg:= po1^ = msechar('-'); +// if not neg then begin + if po1^ = '+' then begin + inc(po1); + end; +// end +// else begin +// inc(po1); +// end; + if po1^ = #0 then begin + exit; + end; + while po1^ <> #0 do begin + if (po1^ < '0') or (po1^ > '9') then begin + exit; + end; +// if value < 0 then begin +// exit; +// end; + if value > max then begin + exit; + end; + value:= value * longword(10) + longword(word(po1^) - word('0')); + inc(po1); + end; + end; +// if neg then begin +// if (value < 0) and (value <> minint) then begin +// exit; +// end; +// value:= -value; +// end +// else begin +// if value < 0 then begin +// exit; +// end; +// end; + result:= true; +end; + +function trystrtoint64(const text: lstringty; out value: int64): boolean; +const + max = maxint64 div 10; +var + po1,pe: pchar; + neg: boolean; +begin + result:= false; + neg:= false; + value:= 0; + if text.len > 0 then begin + po1:= text.po; + pe:= po1 + text.len; + while ((po1^ = ' ') or (po1^ = c_tab)) and (po1 < pe) do begin + inc(po1); + end; + neg:= po1^ = char('-'); + if not neg then begin + if po1^ = '+' then begin + inc(po1); + end; + end + else begin + inc(po1); + end; + if po1 >= pe then begin + exit; + end; + while po1 < pe do begin + if (po1^ < '0') or (po1^ > '9') then begin + exit; + end; +// if value < 0 then begin +// exit; +// end; + if card64(value) > max then begin + exit; + end; + value:= value * 10 + (ord(po1^) - ord('0')); + inc(po1); + end; + end; + if neg then begin + if (value < 0) and (value <> $8000000000000000) then begin + exit; + end; + value:= -value; + end + else begin + if value < 0 then begin + exit; + end; + end; + result:= true; +end; + +function trystrtoint64(const text: string; out value: int64): boolean; +begin + result:= trystrtoint64(stringtolstring(text),value); +end; + +function strtoint64(const text: string): int64; +begin + if not trystrtoint64(text,result) then begin + raise EConvertError.CreateFmt(SInvalidInteger,[text]); + end; +end; + +function strtoint64(const text: msestring): int64; +begin + if not trystrtoint64(text,result) then begin + raise EConvertError.CreateFmt(SInvalidInteger,[string(text)]); + end; +end; + +function trystrtoint64(const text: msestring; out value: int64): boolean; +const + max = maxint64 div 10; +var + po1: pmsechar; + neg: boolean; +begin + result:= false; + neg:= false; + value:= 0; + if text <> '' then begin + po1:= pointer(text); + while (po1^ = ' ') or (po1^ = c_tab) do begin + inc(po1); + end; + neg:= po1^ = msechar('-'); + if not neg then begin + if po1^ = '+' then begin + inc(po1); + end; + end + else begin + inc(po1); + end; + if po1^ = #0 then begin + exit; + end; + while po1^ <> #0 do begin + if (po1^ < '0') or (po1^ > '9') then begin + exit; + end; +// if value < 0 then begin +// exit; +// end; + if card64(value) > max then begin + exit; + end; + value:= value * 10 + (ord(po1^) - ord('0')); + inc(po1); + end; + end; + if neg then begin + if (value < 0) and (value <> $8000000000000000) then begin + exit; + end; + value:= -value; + end + else begin + if value < 0 then begin + exit; + end; + end; + result:= true; +end; + +function trystrtoqword(const text: string; out value: qword): boolean; +const + max = 1844674407370955161; +var + po1: pchar; + bo1: boolean; +begin + result:= false; + value:= 0; + if text <> '' then begin + po1:= pointer(text); + while (po1^ = ' ') or (po1^ = c_tab) do begin + inc(po1); + end; + if po1^ = #0 then begin + exit; + end; + while po1^ <> #0 do begin + if (po1^ < '0') or (po1^ > '9') then begin + exit; + end; + if value > max then begin + exit; + end; + value:= value * 10; + bo1:= int64(value) < 0; + value:= value + (ord(po1^) - ord('0')); + if bo1 and (int64(value) >= 0) then begin + exit; + end; + inc(po1); + end; + end; + result:= true; +end; + +function trystrtoqword(const text: msestring; out value: qword): boolean; +const + max = 1844674407370955161; +var + po1: pmsechar; + bo1: boolean; +begin + result:= false; + value:= 0; + if text <> '' then begin + po1:= pointer(text); + while (po1^ = ' ') or (po1^ = c_tab) do begin + inc(po1); + end; + if po1^ = #0 then begin + exit; + end; + while po1^ <> #0 do begin + if (po1^ < '0') or (po1^ > '9') then begin + exit; + end; + if value > max then begin + exit; + end; + value:= value * 10; + bo1:= int64(value) < 0; + value:= value + (ord(po1^) - ord('0')); + if bo1 and (int64(value) >= 0) then begin + exit; + end; + inc(po1); + end; + end; + result:= true; +end; + +function trystrtointvalue(const text: msestring; base: numbasety; + out value: longword): boolean; +var + str1: string; +begin + str1:= ansistring(trim(text)); + case base of + nb_bin: begin + result:= trystrtobin(str1,value); + end; + nb_oct: begin + result:= trystrtooct(str1,value); + end; + nb_hex: begin + result:= trystrtohex(str1,value); + end + else begin //nb_dec + result:= trystrtodec(str1,value); + end; + end; +end; + +function trystrtointvalue64(const text: msestring; base: numbasety; + out value: qword): boolean; overload; +var + str1: string; +begin + str1:= ansistring(trim(text)); + case base of + nb_bin: begin + result:= trystrtobin64(str1,value); + end; + nb_oct: begin + result:= trystrtooct64(str1,value); + end; + nb_hex: begin + result:= trystrtohex64(str1,value); + end + else begin //nb_dec + result:= trystrtodec64(str1,value); + end; + end; +end; + +function strtointvalue(const text: msestring; base: numbasety): longword; +begin + if not trystrtointvalue(text,base,result) then begin + formaterror(text); + end; +end; + +function strtointvalue64(const text: msestring; base: numbasety): qword; +begin + if not trystrtointvalue64(text,base,result) then begin + formaterror(text); + end; +end; + +function intvaluetostr(const value: integer; const base: numbasety = nb_dec; + const bitcount: integer = 32): string; +begin + case base of + nb_bin: begin + result:= bintostr(longword(value),abs(bitcount)); + end; + nb_oct: begin + result:= octtostr(longword(value),(abs(bitcount)+2) div 3); + end; + nb_hex: begin + result:= hextostr(longword(value),(abs(bitcount)+3) div 4); + end; + else begin //nb_dec + result:= dectostr(value,sign(bitcount)*(abs(bitcount)*100+331) div 332); + end; + end; +end; + +function intvaluetostr(const value: int64; const base: numbasety = nb_dec; + const bitcount: integer = 64): string; +begin + case base of + nb_bin: begin + result:= bintostr(uint64(value),abs(bitcount)); + end; + nb_oct: begin + result:= octtostr(uint64(value),(abs(bitcount)+2) div 3); + end; + nb_hex: begin + result:= hextostr(uint64(value),(abs(bitcount)+3) div 4); + end; + else begin //nb_dec + result:= dectostr(value,sign(bitcount)*(abs(bitcount)*100+331) div 332); + end; + end; +end; + +function strtobin1(const inp: string; out value: longword): boolean; + //wandelt 1..0-string in longword) +var + int1: integer; + lwo1: longword; +begin + result:= false; + if inp <> '' then begin + value:= 0; + lwo1:= 1; + for int1:= length(inp) downto 1 do begin + if inp[int1] = '1' then begin + value:= value + lwo1; + end + else begin + if inp[int1] <> '0' then begin + exit; + end; + end; + lwo1:= lwo1 shl 1; + end; + result:= true; + end; +end; + +function strtobin164(const inp: string; out value: qword): boolean; + //wandelt 1..0-string in longword) +var + int1: integer; + lwo1: qword; +begin + result:= false; + if inp <> '' then begin + value:= 0; + lwo1:= 1; + for int1:= length(inp) downto 1 do begin + if inp[int1] = '1' then begin + value:= value + lwo1; + end + else begin + if inp[int1] <> '0' then begin + exit; + end; + end; + lwo1:= lwo1 shl 1; + end; + result:= true; + end; +end; + +function trystrtobin(const inp: string; out value: longword): boolean; +begin + result:= strtobin1(inp,value); + if not result then begin + result:= trystrtointvalue(inp,value); + end; +end; + +function trystrtobin64(const inp: string; out value: qword): boolean; +begin + result:= strtobin164(inp,value); + if not result then begin + result:= trystrtointvalue64(inp,value); + end; +end; + +function strtobin(const inp: string): longword; + //wandelt 0..1-string in longword) +begin + if not trystrtobin(inp,result) then begin + formaterror(inp); + end; +end; + +function strtobin64(const inp: string): qword; + //wandelt 0..1-string in longword) +begin + if not trystrtobin64(inp,result) then begin + formaterror(inp); + end; +end; + +function strtooct1(const inp: string; out value: longword): boolean; +var + int1: integer; + ca1: longword; + ch1: char; +begin + result:= false; + if inp <> '' then begin + value:= 0; + ca1:= 0; + for int1:= length(inp) downto 1 do begin + ch1:= inp[int1]; + if (ch1 < '0') or (ch1 > '7') then begin + exit; + end; + value:= value + longword(((ord(ch1) - ord('0'))) shl ca1); + inc(ca1,3); + end; + result:= true; + end; +end; + +function strtooct164(const inp: string; out value: qword): boolean; +var + int1: integer; + ca1: longword; + ch1: char; +begin + result:= false; + if inp <> '' then begin + value:= 0; + ca1:= 0; + for int1:= length(inp) downto 1 do begin + ch1:= inp[int1]; + if (ch1 < '0') or (ch1 > '7') then begin + exit; + end; + value:= value + qword(((ord(ch1) - ord('0'))) shl ca1); + inc(ca1,3); + end; + result:= true; + end; +end; + +function trystrtooct(const inp: string; out value: longword): boolean; +begin + result:= strtooct1(inp,value); + if not result then begin + result:= trystrtointvalue(inp,value); + end; +end; + +function trystrtooct64(const inp: string; out value: qword): boolean; +begin + result:= strtooct164(inp,value); + if not result then begin + result:= trystrtointvalue64(inp,value); + end; +end; + +function strtooct(const inp: string): longword; + //wandelt 1..0-string in longword) +begin + if not trystrtooct(inp,result) then begin + formaterror(inp); + end; +end; + +function strtooct64(const inp: string): qword; + //wandelt 1..0-string in longword) +begin + if not trystrtooct64(inp,result) then begin + formaterror(inp); + end; +end; + +function strtodec1(const inp: string; out value: longword): boolean; +begin + result:= trystrtoint(inp,integer(value)); +end; + +function strtodec164(const inp: string; out value: qword): boolean; +begin + result:= trystrtoint64(inp,int64(value)); +end; + +function trystrtodec(const inp: string; out value: longword): boolean; +begin + result:= strtodec1(inp,value); + if not result then begin + result:= trystrtointvalue(inp,value); + end; +end; + +function trystrtodec64(const inp: string; out value: qword): boolean; +begin + result:= strtodec164(inp,value); + if not result then begin + result:= trystrtointvalue64(inp,value); + end; +end; + +function strtodec(const inp: string): longword; + //wandelt 0..9-string in longword) +begin + if not trystrtodec(inp,result) then begin + formaterror(inp); + end; +end; + +function strtodec64(const inp: string): qword; + //wandelt 0..9-string in longword) +begin + if not trystrtodec64(inp,result) then begin + formaterror(inp); + end; +end; + +function trystrtohex(const inp: pchar; const len: int32; + out value: longword): boolean; +var + po1,pe: pchar; + ch1: char; +begin + value:= 0; + result:= (len > 0) and (len <= 8); + if result then begin + po1:= inp; + pe:= po1+len; + while po1 < pe do begin + ch1:= po1^; + value:= value shl 4; + if (ch1 >= '0') and (ch1 <= '9') then begin + value:= value + ord(ch1) - ord('0'); + end + else begin + if (ch1 >= 'a') and (ch1 <= 'f') then begin + value:= value + ord(ch1) - (ord('a')-10); + end + else begin + if (ch1 >= 'A') and (ch1 <= 'F') then begin + value:= value + ord(ch1) - (ord('A')-10); + end + else begin + result:= false; + break; + end; + end; + end; + inc(po1); + end; + end; +// result:= trystrtoint('$'+inp,integer(value)); +end; + +function strtohex1(const inp: msestring; out value: longword): boolean; +var + po1: pmsechar; + ch1: msechar; + int1: integer; +begin + value:= 0; + int1:= length(inp); + result:= (int1 > 0) and (int1 <= 8); + if result then begin + po1:= pointer(inp); + while true do begin + ch1:= po1^; + if ch1 = #0 then begin + break; + end; + value:= value shl 4; + if (ch1 >= '0') and (ch1 <= '9') then begin + value:= value + ord(ch1) - ord('0'); + end + else begin + if (ch1 >= 'a') and (ch1 <= 'f') then begin + value:= value + ord(ch1) - (ord('a')-10); + end + else begin + if (ch1 >= 'A') and (ch1 <= 'F') then begin + value:= value + ord(ch1) - (ord('A')-10); + end + else begin + result:= false; + break; + end; + end; + end; + inc(po1); + end; + end; +end; + +function strtohex164(const inp: string; out value: qword): boolean; +var + po1: pchar; + ch1: char; + int1: integer; +begin + value:= 0; + int1:= length(inp); + result:= (int1 > 0) and (int1 <= 16); + if result then begin + po1:= pointer(inp); + while true do begin + ch1:= po1^; + if ch1 = #0 then begin + break; + end; + value:= value shl 4; + if (ch1 >= '0') and (ch1 <= '9') then begin + value:= value + ord(ch1) - ord('0'); + end + else begin + if (ch1 >= 'a') and (ch1 <= 'f') then begin + value:= value + ord(ch1) - (ord('a')-10); + end + else begin + if (ch1 >= 'A') and (ch1 <= 'F') then begin + value:= value + ord(ch1) - (ord('A')-10); + end + else begin + result:= false; + break; + end; + end; + end; + inc(po1); + end; + end; +// result:= trystrtoint64('$'+inp,int64(value)); +end; + +function trystrtohex(const inp: lstringty; out value: longword): boolean; +begin + result:= trystrtohex(inp.po,inp.len,value); +end; + +function trystrtohex(const inp: string; out value: longword): boolean; +begin + result:= trystrtohex(pointer(inp),length(inp),value); + if not result then begin + result:= trystrtointvalue(inp,value); + end; +end; + +function trystrtohex(const inp: msestring; out value: longword): boolean; +begin + result:= strtohex1(inp,value); + if not result then begin + result:= trystrtointvalue(ansistring(inp),value); + end; +end; + +function trystrtohex64(const inp: string; out value: qword): boolean; +begin + result:= strtohex164(inp,value); + if not result then begin + result:= trystrtointvalue64(inp,value); + end; +end; + +function strtohex(const inp: string): longword; +begin + if not trystrtohex(inp,result) then begin + formaterror(inp); + end; +end; + +function strtohex(const inp: msestring): longword; +begin + if not trystrtohex(inp,result) then begin + formaterror(inp); + end; +end; + +function strtohex64(const inp: string): qword; +begin + if not trystrtohex64(inp,result) then begin + formaterror(inp); + end; +end; + +function trystrtointvalue(const inp: string; out value: longword): boolean; +var + lint1: int64; +begin + result:= false; + if length(inp) > 0 then begin + case inp[1] of + '%': result:= strtobin1(copy(inp,2,length(inp)-1),value); + '&': result:= strtooct1(copy(inp,2,length(inp)-1),value); + '#': result:= strtodec1(copy(inp,2,length(inp)-1),value); + '$': result:= trystrtohex(copy(inp,2,length(inp)-1),value); + else begin + if (length(inp) > 2) and + ((inp[2] = 'x') or (inp[2] = 'X')) and (inp[1] = '0') then begin + result:= trystrtohex(copy(inp,3,length(inp)-2),value); + end + else begin + result:= trystrtoint64(inp,lint1); + if result then begin + value:= lint1; + end; + end; + end; + end; + end; +end; + +function trystrtointvalue64(const inp: string; out value: qword): boolean; +var + lint1: int64; +begin + result:= false; + if length(inp) > 0 then begin + case inp[1] of + '%': result:= strtobin164(copy(inp,2,length(inp)-1),value); + '&': result:= strtooct164(copy(inp,2,length(inp)-1),value); + '#': result:= strtodec164(copy(inp,2,length(inp)-1),value); + '$': result:= strtohex164(copy(inp,2,length(inp)-1),value); + else begin + if (length(inp) > 2) and + ((inp[2] = 'x') or (inp[2] = 'X')) and (inp[1] = '0') then begin + result:= strtohex164(copy(inp,3,length(inp)-2),value); + end + else begin + if (inp <> '') and (inp[1] = '-') then begin + result:= trystrtoint64(inp,lint1); + end + else begin + result:= trystrtoqword(inp,qword(lint1)); + end; + if result then begin + value:= lint1; + end; + end; + end; + end; + end; +end; + +function strtointvalue(const inp: string): longword; +begin + if not trystrtointvalue(inp,result) then begin + formaterror(inp); + end; +end; + +function strtointvalue64(const inp: string): qword; +begin + if not trystrtointvalue64(inp,result) then begin + formaterror(inp); + end; +end; + +//todo: 64bit + +function strtoptruint(const inp: string): ptruint; +begin + result:= strtointvalue(inp); +end; + +function trystrtoptruint(const inp: string; out value: ptruint): boolean; +begin + {$ifdef CPU64} + result:= trystrtointvalue64(inp,qword(value)); + {$else} + result:= trystrtointvalue(inp,longword(value)); + {$endif} +end; + +function inttostrlen(inp: integer; len: integer; + rechtsbuendig: boolean = true; fillchar: char = ' '): ansistring; + //wandelt integer in string fester laenge +var + int1: integer; +begin + result:= inttostr(inp); + int1:= length(result); + setlength(result,len); + if int1 < len then begin + if rechtsbuendig then begin + move(result[1],result[len-int1+1],int1); + system.fillchar(result[1],len-int1,fillchar); + end + else begin + system.fillchar(result[int1+1],len-int1,fillchar); + end; + end + else begin + if int1 > len then begin + system.fillchar(result[1],len,fc_keinplatzchar); + end; + end; +end; + +function inttostrlenmse(inp: integer; len: integer; + rechtsbuendig: boolean = true; fillchar: msechar = ' '): msestring; + //wandelt integer in string fester laenge +var + int1: integer; +begin + result:= inttostrmse(inp); + int1:= length(result); + setlength(result,len); + if int1 < len then begin + if rechtsbuendig then begin + move(result[1],result[len-int1+1],int1*sizeof(msechar)); + system.fillword(result[1],len-int1,card16(fillchar)); + end + else begin + system.fillword(result[int1+1],len-int1,card16(fillchar)); + end; + end + else begin + if int1 > len then begin + system.fillword(result[1],len,card16(msechar(fc_keinplatzchar))); + end; + end; +end; + +procedure msestrtotvarrec(const value: ansistring; out varrec: tvarrec); +begin + varrec.vtype:= vtansistring; + varrec.vansistring:= pointer(value); +end; + +procedure msestrtotvarrec(const value: msestring; out varrec: tvarrec); +begin +{$ifdef mse_hasvtunicodestring} + varrec.vtype:= vtunicodestring; + varrec.vunicodestring:= pointer(value); //msestringimplementation +{$else} + varrec.vtype:= vtwidestring; + varrec.vwidestring:= pointer(value); //msestringimplementation +{$endif} +end; + +function tvarrectoansistring(const value: tvarrec): ansistring; +begin + with value do begin + case vtype of + vtAnsiString: begin + result:= ansistring(VAnsiString); + end; + vtInteger: begin + result:= inttostr(VInteger); + end; + vtBoolean: begin + result:= booltostr(VBoolean); + end; + vtChar: begin + result:= VChar; + end; + vtWideChar: begin + result:= ansistring(VWideChar); + end; + vtExtended: begin + result:= ansistring(doubletostring(VExtended^)); + end; + vtString: begin + result:= VString^; + end; + vtPointer: begin + result:= hextostr(VPointer); + end; + vtPChar: begin + result:= VPChar; + end; + vtObject: begin + result:= hextostr(VObject); + end; + vtClass: begin + result:= hextostr(VClass); + end; + vtPWideChar: begin + result:= ansistring(unicodestring(VPWideChar)); + end; + vtCurrency: begin + result:= currtostr(VCurrency^); + end; + vtVariant: begin + result:= VVariant^; + end; + vtInterface: begin + result:= hextostr(VInterface); + end; + vtWideString: begin + result:= ansistring(widestring(VWideString)); + end; + vtInt64: begin + result:= inttostr(VInt64^); + end; + vtUnicodeString: begin + result:= ansistring(unicodestring(VUnicodeString)); + end; + vtQWord: begin + result:= inttostr(VQWord^); + end + else begin + result:= ''; + end; + end; + end; +end; + +function tvarrectomsestring(const value: tvarrec): msestring; +begin + with value do begin + case vtype of + vtUnicodeString: begin + result:= unicodestring(VUnicodeString); + end; + vtInteger: begin + result:= inttostrmse(VInteger); + end; + vtBoolean: begin + result:= msestring(booltostr(VBoolean)); + end; + vtChar: begin + result:= msestring(VChar); + end; + vtWideChar: begin + result:= VWideChar; + end; + vtExtended: begin + result:= doubletostring(VExtended^); + end; + vtString: begin + result:= msestring(VString^); + end; + vtPointer: begin + result:= msestring(hextostr(VPointer)); + end; + vtPChar: begin + result:= VPChar; + end; + vtObject: begin + result:= msestring(hextostr(VObject)); + end; + vtClass: begin + result:= msestring(hextostr(VClass)); + end; + vtPWideChar: begin + result:= unicodestring(VPWideChar); + end; + vtAnsiString: begin + result:= msestring(ansistring(VAnsiString)); + end; + vtCurrency: begin + result:= msestring(currtostr(VCurrency^)); + end; + vtVariant: begin + result:= VVariant^; + end; + vtInterface: begin + result:= msestring(hextostr(VInterface)); + end; + vtWideString: begin + result:= widestring(VWideString); + end; + vtInt64: begin + result:= inttostrmse(VInt64^); + end; + vtQWord: begin + result:= inttostrmse(VQWord^); + end + else begin + result:= ''; + end; + end; + end; +end; + +{ tformatmacrolist } + +procedure tformatmacrolist.addmac(const aname: msestring; + const avalue: msestring; const ahandler: macrohandlerty = nil); +begin + add([aname],[avalue],[ahandler]); +end; + +procedure clearformatmacros; +begin + freeandnil(fformatmacros); +end; + +initialization +{$ifndef FPC} + {$ifdef mswindows} + getlocaleformatsettings(0,defaultformatsettingsdot); + {$else} + defaultformatsettingsdot:= defaultformatsettings; + {$endif} +{$else} + defaultformatsettingsdot:= sysutils.defaultformatsettings; +{$endif} + defaultformatsettingsdot.DecimalSeparator:= '.'; +finalization + clearformatmacros; +end. diff --git a/mseide-msegui/lib/common/kernel/mseglob.pas b/mseide-msegui/lib/common/kernel/mseglob.pas new file mode 100644 index 0000000..1684665 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseglob.pas @@ -0,0 +1,185 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseglob; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +interface +uses + classes,mclasses,mseerr,msetypes; +const + invalidaxis = -bigint; + defaultbase64linelength = 76; //todo: find better place + +type + listdatatypety = (dl_none,dl_integer,dl_int64,dl_currency, + dl_real,dl_realint,dl_realsum, + dl_datetime, + dl_pointer, + dl_ansistring,dl_msestring,dl_doublemsestring,dl_msestringint, + dl_complex,dl_rowstate,dl_custom); + listdatatypesty = set of listdatatypety; + + shortcutty = type word; + shortcutarty = array of shortcutty; + modalresultty = (mr_none,mr_canclose,mr_windowclosed,mr_windowdestroyed, + mr_escape,mr_f10, + mr_exception, + mr_cancel,mr_abort,mr_ok,mr_yes,mr_no,mr_all, + mr_yesall,mr_noall, + mr_ignore,mr_skip,mr_skipall,mr_continue); + pmodalresultty = ^modalresultty; + modalresultsty = set of modalresultty; + + inullinterface = interface + //no referencecount, only for fpc, not available in delphi + end; + +// {$ifdef FPC} +// tnullinterfacedobject = class(tobject) //not used +// end; +// {$else} + tnullinterfacedobject = class(tobject,iunknown) + protected + function _addref: integer; + {$ifdef FPC} + {$ifdef mswindows}stdcall{$else} cdecl{$endif}; + {$else}stdcall;{$endif} + + function _release: integer; + {$ifdef FPC} + {$ifdef mswindows}stdcall{$else} cdecl{$endif}; + {$else}stdcall;{$endif} + function queryinterface( + {$ifdef fpc_has_constref}constref{$else}const{$endif} + iid: tguid; out obj): hresult; + {$ifdef FPC} + {$ifdef mswindows}stdcall{$else} cdecl{$endif}; + {$else}stdcall;{$endif} + end; +// {$endif} + + objecteventty = (oe_destroyed,oe_connect,oe_disconnect, + oe_changed,oe_designchanged, + oe_activate,oe_deactivate,oe_fired,oe_dataready, + oe_bindfields,oe_releasefields); + objectlinkeventty = procedure(const sender: tobject; + const event: objecteventty) of object; + iobjectlink = interface(inullinterface) + procedure link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); + procedure unlink(const source,dest: iobjectlink; valuepo: pointer = nil); + //source = 1 -> dest destroyed + procedure objevent(const sender: iobjectlink; const event: objecteventty); + function getinstance: tobject; + end; + + mseerrorty = (mse_ok,mse_resnotfound); + emse = class(eerror) + private + function geterror: mseerrorty; + public + constructor create(aerror: mseerrorty; atext: string); + property error: mseerrorty read geterror; + end; + +function fullcomponentname(component: tcomponent): string; + + +procedure mseerror(error: mseerrorty; text: string = ''); overload; +procedure mseerror(error: mseerrorty; sender: tobject; text: string = ''); overload; + +implementation +//uses +// mseclasses; +const + errortexts: array[mseerrorty] of string = + ('', + 'Resource not found' + ); + +function fullcomponentname(component: tcomponent): string; +begin + result:= component.name; + while component.owner <> nil do begin + component:= component.owner; + result:= component.name + '.' + result; + end; +end; + +procedure mseerror(error: mseerrorty; text: string); overload; +begin + if error = mse_ok then begin + exit; + end; + raise emse.create(error,text); +end; + +procedure mseerror(error: mseerrorty; sender: tobject; + text: string = ''); overload; +begin + if error = mse_ok then begin + exit; + end; + if sender <> nil then begin + text:= sender.classname + ' ' + text; + if sender is tcomponent then begin + text:= text + fullcomponentname(tcomponent(sender)); + end; + end; + mseerror(error,text); +end; + +{ tnullinterfacedobject } + +//{$ifndef fpc} +function tnullinterfacedobject._addref: integer; + {$ifdef FPC} + {$ifdef mswindows}stdcall{$else} cdecl{$endif}; + {$else}stdcall;{$endif} +begin + result:= -1; +end; + +function tnullinterfacedobject._release: integer; + {$ifdef FPC} + {$ifdef mswindows}stdcall{$else} cdecl{$endif}; + {$else}stdcall;{$endif} +begin + result:= -1; +end; + +function tnullinterfacedobject.QueryInterface( + {$ifdef fpc_has_constref}constref{$else}const{$endif} + IID: TGUID; out Obj): HResult; + {$ifdef FPC} + {$ifdef mswindows}stdcall{$else} cdecl{$endif}; + {$else}stdcall;{$endif} +begin + if getinterface(iid, obj) then begin + result:=0 + end + else begin + result:= integer(e_nointerface); + end; +end; +//{$endif} + +{ emse } + +constructor emse.create(aerror: mseerrorty; atext: string); +begin + inherited create(integer(aerror),atext,errortexts); +end; + +function emse.geterror: mseerrorty; +begin + result:= mseerrorty(ferror); +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/msegui.pas b/mseide-msegui/lib/common/kernel/msegui.pas new file mode 100644 index 0000000..ded4e48 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msegui.pas @@ -0,0 +1,22378 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msegui; + +{$ifdef FPC} + {$mode objfpc}{$h+}{$GOTO ON}{$interfaces corba} +{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses,sysutils,msegraphics,msetypes,mseact, + msestrings,mseerr,msegraphutils,mseapplication,msedragglob, + msepointer,mseevent,msekeyboard,mseclasses,mseglob,mseguiglob,mselist, + msesystypes,msethread,mseguiintf,{msesysdnd,}mseassistiveclient, + msebitmap,msearrayprops,msethreadcomp,mserichstring,msearrayutils + {$ifdef mse_with_ifi},mseifiglob,mseificompglob{$endif}; + +const + mseguiversiontext = '4.6.3'; + copyrighttext = 'Copyright 1999-2018'; + + defaultwidgetcolor = cl_default; + defaulttoplevelwidgetcolor = cl_background; + defaultfadecolor = cl_ltgray; + defaultfadecolor1 = cl_dkgray; + defaultfadeopacolor = cl_white; + hintdelaytime = 500000; //us + defaulthintshowtime = 3000000; //us + mouseparktime = 500000; //us + defaultdblclicktime = 400000; //us + mindragdist = 4; + + mousebuttons = [ss_left,ss_right,ss_middle]; + + //hintid values, user values > 0 + hintidnone = 0; + //internal ranges + hintidwidget = -1; + hintidframe = -100; + +type + + gdiregionty = record + gdi: pgdifunctionaty; + region: regionty; + end; + + frameskinoptionty = (fso_flat, + fso_noanim,fso_nomouseanim,fso_noclickanim,fso_nofocusanim, + fso_focusrect,fso_nofocusrect,fso_forcefocusrect, + fso_nodefaultrect,fso_noinnerrect, + fso_clientfacerect,fso_faceoverlay); + frameskinoptionsty = set of frameskinoptionty; + + frameskincontrolleroptionty = + (fsco_colorclient, //set colorclient in skincontroller + fsco_frameileftsize,fsco_frameirightsize, + fsco_frameitopsize,fsco_frameibottomsize, + //adjust clientsize in skincontroller by + //framei values + fsco_noclientsize); + //do not restore clientsize after frame size changes + frameskincontrolleroptionsty = set of frameskincontrolleroptionty; + + optionwidgetty = (ow_background,ow_top,ow_ultratop,ow_transientformain, + ow_noautosizing, //don't use, moved to optionswidget1 + ow_mousefocus,ow_tabfocus, + ow_parenttabfocus,ow_arrowfocus, + ow_arrowfocusin,ow_arrowfocusout, + ow_subfocus, //reflects focus to children + ow_focusbackonesc, + ow_keyreturntaborder, + //key_return and key_enter work like key_tab + ow_nosiblingshortcut, //do not react to shortcuts + //from siblings + ow_nochildshortcut, //do not propagate shortcuts to parent + ow_noparentshortcut, //do not react to shortcuts from parent + ow_canclosenil, // don't use, moved to optionswidget1 + ow_mousetransparent,ow_mousewheel, + ow_noscroll,ow_nochildpaintclip,ow_nochildclipsiblings, + ow_destroywidgets,ow_nohidewidgets, + ow_hinton,ow_hintoff,ow_disabledhint,ow_appinactivehint, + ow_multiplehint, + ow_timedhint + ); + optionswidgetty = set of optionwidgetty; + optionwidget1ty = ( + ow1_clientcxmin,ow1_clientcymin, + ow1_clientcxmax,ow1_clientcymax, + ow1_fontglyphheight, + //track font.glyphheight, + //create fonthighdelta and childscaled events + ow1_fontlineheight, + //track font.linespacing, + //create fonthighdelta and childscaled events + ow1_autoscale, //synchronizes bounds_cy or bonds_cx + //with fontheightdelta + ow1_autowidth,ow1_autoheight, + ow1_autosizeanright,ow1_noautosizeanright, + ow1_autosizeanbottom,ow1_noautosizeanbottom, + ow1_noparentwidthextend,ow1_noparentheightextend, + ow1_invisibleparentsizeextend, + ow1_canclosenil, //call canclose(nil) on exit + ow1_nocancloseifhidden, + ow1_modalcallonactivate,ow1_modalcallondeactivate, + //used in tactionwidget + ow1_noautosizing, //used in tdockcontroller + ow1_noclampinview, //used in doactivate() + ow1_noassistive + ); + +const + deprecatedoptionswidget= [ow_noautosizing,ow_canclosenil]; + invisibleoptionswidget = [ord(ow_noautosizing),ord(ow_canclosenil)]; + +type + optionswidget1ty = set of optionwidget1ty; + + optionskinty = (osk_skin,osk_noskin,osk_framebuttononly, + osk_noframe,osk_noface,osk_nooptions, + osk_container,osk_noclientsize, + osk_colorcaptionframe, + //use widget_colorcaptionframe independent of caption + osk_nocolorcaptionframe, + //don't use widget_colorcaptinframe independent of caption + osk_nopropleft,osk_noproptop, //used by tlayouter + osk_nopropwidth,osk_nopropheight, //used by tlayouter + osk_nopropfont, //used by tlayouter + osk_noalignx,osk_noaligny, //used by tlayouter + osk_nopaintref, //used by alignx()/aligny() + osk_nolayoutcx,osk_nolayoutcy //used by syncmaxaoutsize() + ); + optionsskinty = set of optionskinty; + + anchorty = (an_left,an_top,an_right,an_bottom); + anchorsty = set of anchorty; + + widgetstatety = (ws_visible,ws_enabled, + ws_active,ws_entered,ws_entering,ws_exiting,ws_focused, + ws_mouseinclient,ws_wantmousebutton,ws_wantmousemove, + //valid after call of updatemousestate only +// ws_wantmousewheel, + ws_wantmousefocus,ws_iswidget,ws_designing, + ws_opaque,ws_nopaint, + ws_lclicked,ws_mclicked,ws_rclicked, + ws_mousecaptured,ws_clientmousecaptured, + ws_newmousecapture, + ws_loadlock,ws_loadedproc,ws_showproc, + ws_minclientsizevalid, +// ws_showed,ws_hidden, //used in tcustomeventwidget + ws_destroying, + ws_staticframe,ws_staticface, + ws_isvisible + ); + widgetstatesty = set of widgetstatety; + widgetstate1ty = (ws1_childscaled,ws1_childrectchanged, + ws1_widgetrectsetting, + ws1_scaling,ws1_autoscaling,ws1_autosizing, + ws1_painting,ws1_updateopaque, + ws1_widgetregionvalid,ws1_rootvalid, + ws1_anchorsizing,ws1_anchorsetting,ws1_layoutplacing, + ws1_parentclientsizeinited, + ws1_parentupdating, //set while setparentwidget + ws1_isstreamed, //used by ttabwidget + ws1_scaled, //used in tcustomscalingwidget + ws1_forceclose, + ws1_noclipchildren,ws1_tryshrink, + ws1_noframewidgetshift,ws1_framemouse, + ws1_nodesignvisible,ws1_nodesignframe,ws1_nodesignhandles, + ws1_nodesigndelete,ws1_nodesignmove, + ws1_designactive,ws1_nodisabledclick,ws1_designwidget, + ws1_fakevisible,ws1_nominsize, + //used for report size calculations + ws1_onkeydowncalled + ); + widgetstates1ty = set of widgetstate1ty; + + framestatety = (fs_sbhorzon,fs_sbverton,fs_sbhorzfix,fs_sbvertfix, + fs_sbhorztop,fs_sbvertleft, + fs_sbleft,fs_sbtop,fs_sbright,fs_sbbottom, + fs_nowidget,fs_nosetinstance,fs_framemouse, + fs_disabled,fs_creating,fs_stateupdating, + fs_clientrectchanging, + fs_cancaptionsyncx,fs_cancaptionsyncy, + fs_drawfocusrect,fs_paintrectfocus, + fs_captionfocus,fs_captionhint, + fs_rectsvalid,fs_widgetregionchanging, + fs_widgetactive,fs_paintposinited,fs_needsmouseinvalidate, + fs_canclientextendx,fs_canclientextendy); + framestatesty = set of framestatety; + + hintflagty = (hfl_show,hfl_custom,{hfl_left,hfl_top,hfl_right,hfl_bottom,} + hfl_noautohidemove); + hintflagsty = set of hintflagty; + +const + defaultwidgetstates = [ws_visible,ws_enabled,ws_iswidget,ws_isvisible]; + defaultwidgetstatesinvisible = [ws_enabled,ws_iswidget]; + focusstates = [ws_visible,ws_enabled]; + defaultoptionswidget = [ow_mousefocus,ow_tabfocus,ow_arrowfocus,{ow_mousewheel,} + ow_destroywidgets{,ow_autoscale}]; +// defaultoptionswidget1 = [ow1_modalcallondeactivate]; + defaultoptionswidget1 = [ow1_autoscale]; + defaultoptionswidgetmousewheel = defaultoptionswidget + [ow_mousewheel]; + defaultoptionswidgetnofocus = defaultoptionswidget - + [ow_mousefocus,ow_tabfocus,ow_arrowfocus]; + defaultoptionswidgetsubfocus = defaultoptionswidget + [ow_subfocus]; + defaultoptionsskin = []; + defaultcontainerskinoptions = defaultoptionsskin + + [osk_container,osk_noclientsize]; + + defaultwidgetwidth = 50; + defaultwidgetheight = 50; + defaultanchors = [an_left,an_top]; + defaulthintflags = []; + +type + + framelocalpropty = (frl_levelo,frl_leveli,frl_framewidth,{frl_extraspace,} + frl_colorframe,frl_colorframeactive, + frl_colordkshadow,frl_colorshadow, + frl_colorlight,frl_colorhighlight, + frl_colordkwidth,frl_colorhlwidth, + frl_hiddenedges, + frl_fileft,frl_fitop,frl_firight,frl_fibottom, + frl_frameimagelist,frl_frameimageleft,frl_frameimagetop, + frl_frameimageright,frl_frameimagebottom, + frl_frameimageoffset,frl_frameimageoffset1, + frl_frameimageoffsetdisabled,frl_frameimageoffsetmouse, + frl_frameimageoffsetclicked, + frl_frameimageoffsetfocused,frl_frameimageoffsetactive, +{ + frl_frameimageoffsetactivemouse, + frl_frameimageoffsetactiveclicked, +} + frl_optionsskin, + frl_colorclient, + frl_nodisable); + framelocalpropsty = set of framelocalpropty; + + framelocalprop1ty = (frl1_framefacelist, + frl1_framefaceoffset,frl1_framefaceoffset1, + frl1_framefaceoffsetdisabled,frl1_framefaceoffsetmouse, + frl1_framefaceoffsetclicked, + frl1_framefaceoffsetfocused,frl1_framefaceoffsetactive, + { + frl1_framefaceoffsetactivemouse, + frl1_framefaceoffsetactiveclicked, + } + frl1_font,frl1_captiondist,frl1_captionoffset, + frl1_focusrectdist, + frl1_imagedist,frl1_imagedist1,frl1_imagedist2, + frl1_extraspace, + frl1_foleft,frl1_fotop,frl1_foright,frl1_fobottom, + frl1_colorglyph, //for menu template + frl1_colorpattern, + frl1_colorframedisabled,frl1_colorframemouse, + frl1_colorframeclicked,frl1_colorframedefault + ); + framelocalprops1ty = set of framelocalprop1ty; + + framestateflagty = (fsf_offset1,fsf_disabled,fsf_focused,fsf_active, + fsf_mouse,fsf_clicked,fsf_default); + framestateflagsty = set of framestateflagty; + +const + allframelocalprops: framelocalpropsty = + [frl_levelo,frl_leveli,frl_framewidth, + frl_colorframe,frl_colorframeactive, + frl_colordkshadow,frl_colorshadow, + frl_colorlight,frl_colorhighlight, + frl_colordkwidth,frl_colorhlwidth, + frl_hiddenedges, + frl_fileft,frl_fitop,frl_firight,frl_fibottom, + frl_frameimagelist,frl_frameimageleft,frl_frameimagetop, + frl_frameimageright,frl_frameimagebottom, + frl_frameimageoffset,frl_frameimageoffset1, + frl_frameimageoffsetdisabled,frl_frameimageoffsetmouse, + frl_frameimageoffsetclicked, + frl_frameimageoffsetfocused,frl_frameimageoffsetactive, +{ + frl_frameimageoffsetactivemouse, + frl_frameimageoffsetactiveclicked, +} + frl_optionsskin, + frl_colorclient, + frl_nodisable]; + allframelocalprops1: framelocalprops1ty = [ + frl1_framefacelist, + frl1_framefaceoffset,frl1_framefaceoffset1, + frl1_framefaceoffsetdisabled,frl1_framefaceoffsetmouse, + frl1_framefaceoffsetclicked, + frl1_framefaceoffsetfocused,frl1_framefaceoffsetactive, + { + frl1_framefaceoffsetactivemouse, + frl1_framefaceoffsetactiveclicked, + } + frl1_font,frl1_captiondist,frl1_captionoffset, + frl1_focusrectdist, + frl1_extraspace, + frl1_imagedist,frl1_imagedist1,frl1_imagedist2, + frl1_foleft,frl1_fotop,frl1_foright,frl1_fobottom, + frl1_colorglyph,frl1_colorpattern, + frl1_colorframedisabled,frl1_colorframemouse, + frl1_colorframeclicked,frl1_colorframedefault]; +type + facelocalpropty = (fal_options,fal_framei_left,fal_framei_top, + fal_framei_right,fal_framei_bottom, + fal_fadirection,fal_image, + fal_fapos,fal_facolor,fal_faopapos,fal_faopacolor, + fal_fatransparency, + fal_faopacity,fal_frameimagelist,fal_frameimageoffset); + facelocalpropsty = set of facelocalpropty; + +const + allfacelocalprops: facelocalpropsty = + [fal_options,fal_framei_left,fal_framei_top, + fal_framei_right,fal_framei_bottom, + fal_fadirection,fal_image, + fal_fapos,fal_facolor,fal_faopapos,fal_faopacolor, + fal_fatransparency, + fal_faopacity,fal_frameimagelist,fal_frameimageoffset]; +deprecatedfacelocalprops = [fal_fatransparency]; +invisiblefacelocalprops = [ord(fal_fatransparency)]; + +type + twidget = class; + widgetclassty = class of twidget; + tcustomframe = class; + + hintinfoty = record + flags: hintflagsty; + caption: captionty; + posrect: rectty; + placement: captionposty; + showtime: integer; + mouserefpos: pointty; + hintwidgetclass: widgetclassty; +// id: int32; + end; + + showhinteventty = procedure(const sender: tobject; var info: hintinfoty) of object; + + iframe = interface(inullinterface) + procedure setframeinstance(instance: tcustomframe); + procedure setstaticframe(value: boolean); + function getstaticframe: boolean; + procedure scrollwidgets(const dist: pointty); + procedure clientrectchanged; + function getcomponentstate: tcomponentstate; + function getmsecomponentstate: msecomponentstatesty; + procedure invalidate; + procedure invalidatewidget; + procedure invalidaterect(const rect: rectty; + const org: originty = org_client; const noclip: boolean = false); + function getwidget: twidget; + function getwidgetrect: rectty; + function getframestateflags: framestateflagsty; + end; + + icaptionframe = interface(iframe) + function getcanvas(aorigin: originty = org_client): tcanvas; + function getframefont: tfont; + procedure setwidgetrect(const rect: rectty); + end; + + iscrollframe = interface(icaptionframe) + function widgetstate: widgetstatesty; + function getzoomrefframe: framety; + end; + + tfacelist = class; + + frameoffsetsty = record + offset: integer; + offset1: integer; + disabled: integer; + mouse: integer; + clicked: integer; + active: integer; + focused: integer; + { + activemouse: integer; + activeclicked: integer; + } + end; + + frameimageoffsetsty = record + offset: imagenrty; + offset1: imagenrty; + disabled: imagenrty; + mouse: imagenrty; + clicked: imagenrty; + active: imagenrty; + focused: imagenrty; + { + activemouse: imagenrty; + activeclicked: imagenrty; + } + end; + + framefaceoffsetsty = record + offset: facenrty; + offset1: facenrty; + disabled: facenrty; + mouse: facenrty; + clicked: facenrty; + active: facenrty; + focused: facenrty; + // activemouse: facenrty; +// activeclicked: facenrty; + end; + + baseframeinfoty = record + levelo: integer; + leveli: integer; + framewidth: integer; + colorframe: colorty; + colorframeactive: colorty; + colorframedisabled: colorty; + colorframemouse: colorty; + colorframeclicked: colorty; + colorframedefault: colorty; + hiddenedges: edgesty; + framecolors: framecolorinfoty; + colorclient: colorty; + innerframe: framety; + outerframe: framety; + focusrectdist: int32; + extraspace: int32; + imagedist: int32; + imagedist1: int32; + imagedist2: int32; + + colorglyph: colorty; //for menu template and scrollbar + colorpattern: colorty; //for scrollbar + + frameimage_left: integer; + frameimage_top: integer; + frameimage_right: integer; + frameimage_bottom: integer; + frameimage_offsets: frameimageoffsetsty; + + frameface_offsets: framefaceoffsetsty; + optionsskin: frameskinoptionsty; + + frameface_list: tfacelist; //not copied by move + frameimage_list: timagelist; // + end; + + captionframeinfoty = record + captiondist: integer; + captionoffset: integer; + font: toptionalfont; + end; + + frameinfoty = record + ba: baseframeinfoty; + capt: captionframeinfoty + end; + + widgetatposinfoty = record + pos: pointty; + mouseeventinfopo: pmouseeventinfoty; + parentstate,childstate: widgetstatesty + end; + + tframecomp = class; + + tcustomframe = class(toptionalpersistent,iimagelistinfo) + private + procedure setlevelo(const Value: integer); + function islevelostored: boolean; + procedure setleveli(const Value: integer); + function islevelistored: boolean; + procedure setframewidth(const Value: integer); + function isframewidthstored: boolean; + procedure setcolorframe(const Value: colorty); + function iscolorframestored: boolean; + procedure setcolorframeactive(const avalue: colorty); + function iscolorframeactivestored: boolean; + procedure setcolorframedisabled(const avalue: colorty); + function iscolorframedisabledstored: boolean; + procedure setcolorframemouse(const avalue: colorty); + function iscolorframemousestored: boolean; + procedure setcolorframeclicked(const avalue: colorty); + function iscolorframeclickedstored: boolean; + procedure setcolorframedefault(const avalue: colorty); + function iscolorframedefaultstored: boolean; + procedure setcolordkshadow(const avalue: colorty); + function iscolordkshadowstored: boolean; + procedure setcolorshadow(const avalue: colorty); + function iscolorshadowstored: boolean; + procedure setcolorlight(const avalue: colorty); + function iscolorlightstored: boolean; + procedure setcolorhighlight(const avalue: colorty); + function iscolorhighlightstored: boolean; + procedure setcolordkwidth(const avalue: integer); + function iscolordkwidthstored: boolean; + procedure setcolorhlwidth(const avalue: integer); + function iscolorhlwidthstored: boolean; + procedure sethiddenedges(const avalue: edgesty); + function ishiddenedgesstored: boolean; + + procedure setframei(const avalue: framety); + procedure setframei_bottom(const Value: integer); + function isfibottomstored: boolean; + procedure setframei_left(const Value: integer); + function isfileftstored: boolean; + procedure setframei_right(const Value: integer); + function isfirightstored: boolean; + procedure setframei_top(const Value: integer); + function isfitopstored: boolean; + + procedure setframeo(const avalue: framety); + procedure setframeo_bottom(const Value: integer); + function isfobottomstored: boolean; + procedure setframeo_left(const Value: integer); + function isfoleftstored: boolean; + procedure setframeo_right(const Value: integer); + function isforightstored: boolean; + procedure setframeo_top(const Value: integer); + function isfotopstored: boolean; + + procedure setframeimage_list(const avalue: timagelist); + function getimagelist: timagelist; + function isframeimage_liststored: boolean; + procedure setframeimage_left(const avalue: integer); + function isframeimage_leftstored: boolean; + procedure setframeimage_top(const avalue: integer); + function isframeimage_topstored: boolean; + procedure setframeimage_right(const avalue: integer); + function isframeimage_rightstored: boolean; + procedure setframeimage_bottom(const avalue: integer); + function isframeimage_bottomstored: boolean; + + procedure setframeimage_offset(const avalue: imagenrty); + function isframeimage_offsetstored: boolean; + procedure setframeimage_offset1(const avalue: imagenrty); + function isframeimage_offset1stored: boolean; + procedure setframeimage_offsetdisabled(const avalue: imagenrty); + function isframeimage_offsetdisabledstored: boolean; + procedure setframeimage_offsetmouse(const avalue: imagenrty); + function isframeimage_offsetmousestored: boolean; + procedure setframeimage_offsetclicked(const avalue: imagenrty); + function isframeimage_offsetclickedstored: boolean; + procedure setframeimage_offsetactive(const avalue: imagenrty); + function isframeimage_offsetactivestored: boolean; + procedure setframeimage_offsetfocused(const avalue: imagenrty); + function isframeimage_offsetfocusedstored: boolean; + procedure setframeface_list(const avalue: tfacelist); + function isframeface_liststored: boolean; + procedure setframeface_offset(const avalue: facenrty); + function isframeface_offsetstored: boolean; + procedure setframeface_offset1(const avalue: facenrty); + function isframeface_offset1stored: boolean; + procedure setframeface_offsetdisabled(const avalue: facenrty); + function isframeface_offsetdisabledstored: boolean; + procedure setframeface_offsetmouse(const avalue: facenrty); + function isframeface_offsetmousestored: boolean; + procedure setframeface_offsetclicked(const avalue: facenrty); + function isframeface_offsetclickedstored: boolean; + procedure setframeface_offsetactive(const avalue: facenrty); + function isframeface_offsetactivestored: boolean; + procedure setframeface_offsetfocused(const avalue: facenrty); + function isframeface_offsetfocusedstored: boolean; + procedure setoptionsskin(const avalue: frameskinoptionsty); + function isoptionsskinstored: boolean; + + procedure setcolorclient(const Value: colorty); + function iscolorclientstored: boolean; + procedure setfocusrectdist(const avalue: int32); + function isfocusrectdiststored: boolean; + procedure setextraspace(const avalue: int32); + function isextraspacestored: boolean; + procedure setimagedist(const avalue: int32); + function isimagediststored: boolean; + procedure setimagedist1(const avalue: int32); + function isimagedist1stored: boolean; + procedure setimagedist2(const avalue: int32); + function isimagedist2stored: boolean; + procedure settemplate(const avalue: tframecomp); + procedure setlocalprops(const avalue: framelocalpropsty); + procedure setlocalprops1(const avalue: framelocalprops1ty); + protected + ftemplate: tframecomp; + flocalprops: framelocalpropsty; + flocalprops1: framelocalprops1ty; + fintf: iframe; + fstate: framestatesty; + fwidth: framety; + fouterframe: framety; + fpaintframedelta: framety; + fpaintframe: framety; + finnerframe: framety; + fpaintrect: rectty; + fclientrect: rectty; //origin = fpaintrect.pos + finnerclientrect: rectty; //origin = fpaintrect.pos + fpaintposbefore: pointty; + fi: baseframeinfoty; + procedure defineproperties(filer: tfiler); override; + function isoptional: boolean; override; + procedure settemplateinfo(const ainfo: frameinfoty); virtual; + procedure setdisabled(const value: boolean); virtual; + procedure updateclientrect; virtual; + class function calcpaintframe(const afi: baseframeinfoty): framety; + class function calcinnerframe(const afi: baseframeinfoty): framety; + procedure calcrects; + procedure updaterects; virtual; + procedure internalupdatestate(); + procedure updatestate(); virtual; + procedure checkstate; + procedure poschanged; virtual; + procedure fontcanvaschanged; virtual; + procedure visiblechanged; virtual; + procedure getpaintframe(var frame: framety); virtual; + //additional space, (scrollbars,mainmenu...) + procedure dokeydown(var info: keyeventinfoty); virtual; + function checkfocusshortcut(var info: keyeventinfoty): boolean; virtual; + procedure parentfontchanged; virtual; + procedure dopaintfocusrect(const canvas: tcanvas; + const rect: rectty); virtual; + procedure updatewidgetstate; virtual; + procedure updatemousestate(const sender: twidget; + const info: mouseeventinfoty); virtual; + function needsactiveinvalidate: boolean; + function needsenabledinvalidate: boolean; + function needsfocusedinvalidate: boolean; + function needsmouseinvalidate: boolean; + function needsclickinvalidate: boolean; + function needsmouseenterinvalidate: boolean; + procedure activechanged; virtual; + procedure enabledchanged(); virtual; + procedure focusedchanged virtual; + function needsfocuspaint: boolean virtual; + function haspaintrectfocus(): boolean virtual; + function ishintarea(const apos: pointty; var aid: int32): boolean virtual; + procedure checkminscrollsize(var asize: sizety) virtual; + procedure checkminclientsize(var asize: sizety) virtual; + procedure checkminshrinksize(var asize: sizety) virtual; + procedure addscrollbarwidth(var asize: sizety) virtual; + procedure subscrollbarwidth(var asize: sizety) virtual; + procedure paintframeface(const canvas: tcanvas; const arect: rectty); + class procedure drawframe(const canvas: tcanvas; const rect2: rectty; + const afi: baseframeinfoty; const astate: framestateflagsty); + function actualcolorclient(): colorty virtual; + procedure internalpaintbackground(const canvas: tcanvas; + const arect: rectty; const clip: boolean; + const move: boolean) virtual; + procedure internalpaintoverlay(const canvas: tcanvas; + const arect: rectty) virtual; + procedure updatehotkeys() virtual; + //iassistiveclient + function getassistivecaption(): msestring; virtual; + public + constructor create(const intf: iframe); reintroduce; + destructor destroy; override; + procedure checktemplate(const sender: tobject); virtual; + procedure assign(source: tpersistent); override; + procedure scale(const ascale: real); virtual; + procedure checkwidgetsize(var asize: sizety); virtual; + //extends to minimal size + procedure showhint(const aid: int32; var info: hintinfoty); virtual; + + procedure paintbackground(const canvas: tcanvas; + const arect: rectty; const clip: boolean; const move: boolean); + procedure paintoverlay(const canvas: tcanvas; const arect: rectty); + function pointinmask(const pos: pointty; const arect: rectty): boolean; + + function outerframedim: sizety; //widgetsize - framesize + function outerframecx: int32; + function outerframecy: int32; + function frameframedim: sizety; //widgetsize - (paintsize + paintframe) + function frameframecx: int32; + function frameframecy: int32; + function paintframedim: sizety; //widgetsize - paintsize + function paintframecx: int32; + function paintframecy: int32; + function innerframedim: sizety; //widgetsize - innersize + function innerframecx: int32; + function innerframecy: int32; + function outerframe: framety; + function paintframe: framety; + function paintframedelta: framety; //paintframe-outerframe + function innerframe: framety; + function cellframe: framety; //innerframe without paintframedelta + function pointincaption(const point: pointty): boolean; virtual; + //origin = widgetrect + procedure initgridframe; virtual; + procedure changedirection(const oldvalue: graphicdirectionty; + const newvalue: graphicdirectionty); + property intf: iframe read fintf; + property levelo: integer read fi.levelo write setlevelo + stored islevelostored default 0; + property leveli: integer read fi.leveli write setleveli + stored islevelistored default 0; + property framewidth: integer read fi.framewidth write setframewidth + stored isframewidthstored default 0; + property colorframe: colorty read fi.colorframe write setcolorframe + stored iscolorframestored default cl_default; + property colorframeactive: colorty read fi.colorframeactive + write setcolorframeactive + stored iscolorframeactivestored default cl_default; + property colorframedisabled: colorty read fi.colorframedisabled + write setcolorframedisabled + stored iscolorframedisabledstored default cl_default; + property colorframemouse: colorty read fi.colorframemouse + write setcolorframemouse + stored iscolorframemousestored default cl_default; + property colorframeclicked: colorty read fi.colorframeclicked + write setcolorframeclicked + stored iscolorframeclickedstored default cl_default; + property colorframedefault: colorty read fi.colorframedefault + write setcolorframedefault + stored iscolorframedefaultstored default cl_default; + + property colordkshadow: colorty read fi.framecolors.edges.shadow.effectcolor + write setcolordkshadow + stored iscolordkshadowstored default cl_default; + property colorshadow: colorty read fi.framecolors.edges.shadow.color + write setcolorshadow + stored iscolorshadowstored default cl_default; + property colorlight: colorty read fi.framecolors.edges.light.color + write setcolorlight + stored iscolorlightstored default cl_default; + property colorhighlight: colorty read fi.framecolors.edges.light.effectcolor + write setcolorhighlight + stored iscolorhighlightstored default cl_default; + property colordkwidth: integer read fi.framecolors.edges.shadow.effectwidth + write setcolordkwidth + stored iscolordkwidthstored default -1; + property colorhlwidth: integer read fi.framecolors.edges.light.effectwidth + write setcolorhlwidth + stored iscolorhlwidthstored default -1; + property hiddenedges: edgesty read fi.hiddenedges + write sethiddenedges default []; + + property framei: framety read fi.innerframe write setframei; + //does not set localprops + property framei_left: integer read fi.innerframe.left write setframei_left + stored isfileftstored default 0; + property framei_top: integer read fi.innerframe.top write setframei_top + stored isfitopstored default 0; + property framei_right: integer read fi.innerframe.right write setframei_right + stored isfirightstored default 0; + property framei_bottom: integer read fi.innerframe.bottom + write setframei_bottom + stored isfibottomstored default 0; + + property frameo: framety read fi.outerframe write setframeo; + //does not set localprops + property frameo_left: integer read fi.outerframe.left write setframeo_left + stored isfoleftstored default 0; + property frameo_top: integer read fi.outerframe.top write setframeo_top + stored isfotopstored default 0; + property frameo_right: integer read fi.outerframe.right write setframeo_right + stored isforightstored default 0; + property frameo_bottom: integer read fi.outerframe.bottom + write setframeo_bottom + stored isfobottomstored default 0; + + property frameimage_list: timagelist read fi.frameimage_list + write setframeimage_list stored isframeimage_liststored; + //imagenr 0 = topleft, 1 = left, 2 = bottomleft, 3 = bottom, + //4 = bottomright, 5 = right, 6 = topright, 7 = top + property frameimage_left: integer read fi.frameimage_left + write setframeimage_left + stored isframeimage_leftstored default 0; + property frameimage_top: integer read fi.frameimage_top + write setframeimage_top + stored isframeimage_topstored default 0; + property frameimage_right: integer read fi.frameimage_right + write setframeimage_right + stored isframeimage_rightstored default 0; + property frameimage_bottom: integer read fi.frameimage_bottom + write setframeimage_bottom + stored isframeimage_bottomstored default 0; + //added to imagelist size. + property frameimage_offset: imagenrty read fi.frameimage_offsets.offset + write setframeimage_offset + stored isframeimage_offsetstored default 0; + property frameimage_offset1: imagenrty read fi.frameimage_offsets.offset1 + write setframeimage_offset1 + stored isframeimage_offset1stored default 0; + //used for default button + property frameimage_offsetdisabled: imagenrty + read fi.frameimage_offsets.disabled + write setframeimage_offsetdisabled + stored isframeimage_offsetdisabledstored default 0; + property frameimage_offsetmouse: imagenrty + read fi.frameimage_offsets.mouse + write setframeimage_offsetmouse + stored isframeimage_offsetmousestored default 0; + property frameimage_offsetclicked: imagenrty + read fi.frameimage_offsets.clicked + write setframeimage_offsetclicked + stored isframeimage_offsetclickedstored default 0; + property frameimage_offsetactive: imagenrty + read fi.frameimage_offsets.active + write setframeimage_offsetactive + stored isframeimage_offsetactivestored default 0; + property frameimage_offsetfocused: imagenrty + read fi.frameimage_offsets.focused + write setframeimage_offsetfocused + stored isframeimage_offsetfocusedstored default 0; + property frameface_list: tfacelist read fi.frameface_list + write setframeface_list stored isframeface_liststored; + property frameface_offset: facenrty read fi.frameface_offsets.offset + write setframeface_offset + stored isframeface_offsetstored default 0; + property frameface_offset1: facenrty + read fi.frameface_offsets.offset1 + write setframeface_offset1 + stored isframeface_offset1stored default 0; + //used for default button + property frameface_offsetdisabled: facenrty + read fi.frameface_offsets.disabled + write setframeface_offsetdisabled + stored isframeface_offsetdisabledstored default 0; + property frameface_offsetmouse: facenrty + read fi.frameface_offsets.mouse + write setframeface_offsetmouse + stored isframeface_offsetmousestored default 0; + property frameface_offsetclicked: facenrty + read fi.frameface_offsets.clicked + write setframeface_offsetclicked + stored isframeface_offsetclickedstored default 0; + property frameface_offsetactive: facenrty + read fi.frameface_offsets.active + write setframeface_offsetactive + stored isframeface_offsetactivestored default 0; + property frameface_offsetfocused: facenrty + read fi.frameface_offsets.focused + write setframeface_offsetfocused + stored isframeface_offsetfocusedstored default 0; + property optionsskin: frameskinoptionsty read fi.optionsskin + write setoptionsskin stored isoptionsskinstored default []; + property focusrectdist: int32 read fi.focusrectdist + write setfocusrectdist + stored isfocusrectdiststored default 0; + property extraspace: int32 read fi.extraspace + write setextraspace + stored isextraspacestored default 0; + property imagedist: int32 read fi.imagedist + write setimagedist + stored isimagediststored default 0; + property imagedist1: int32 read fi.imagedist1 + write setimagedist1 + stored isimagedist1stored default 0; + property imagedist2: int32 read fi.imagedist2 + write setimagedist2 + stored isimagedist2stored default 0; + property colorclient: colorty read fi.colorclient write setcolorclient + stored iscolorclientstored default cl_default; + property localprops: framelocalpropsty read flocalprops + write setlocalprops {default []}; + property localprops1: framelocalprops1ty read flocalprops1 + write setlocalprops1 {default []}; + property template: tframecomp read ftemplate write settemplate; + end; + + tframe = class(tcustomframe) + published + property levelo; + property leveli; + property framewidth; + property colorframe; + property colorframeactive; + property colorframedisabled; + property colorframemouse; + property colorframeclicked; + property colorframedefault; + property framei_left; + property framei_top; + property framei_right; + property framei_bottom; + property frameo_left; + property frameo_top; + property frameo_right; + property frameo_bottom; + + property frameimage_list; + property frameimage_left; + property frameimage_right; + property frameimage_top; + property frameimage_bottom; + property frameimage_offset; + property frameimage_offset1; + property frameimage_offsetdisabled; + property frameimage_offsetmouse; + property frameimage_offsetclicked; + property frameimage_offsetactive; + property frameimage_offsetfocused; + + property frameface_list; + property frameface_offset; + property frameface_offset1; + property frameface_offsetdisabled; + property frameface_offsetmouse; + property frameface_offsetclicked; + property frameface_offsetactive; + property frameface_offsetfocused; + + property optionsskin; + + property focusrectdist; + property extraspace; + property imagedist; + property imagedist1; + property imagedist2; + + property colorclient; + property colordkshadow; + property colorshadow; + property colorlight; + property colorhighlight; + property colordkwidth; + property colorhlwidth; + property hiddenedges; + property localprops; //before template + property localprops1; //before template + property template; + end; + + tframetemplate = class; + + beforeframepaintbackgroundeventty = procedure (const sender: tcustomframe; + const canvas: tcanvas; const arect: rectty; + const clip: boolean; const move: boolean; + var handled: boolean) of object; + afterframepaintbackgroundeventty = procedure (const sender: tcustomframe; + const canvas: tcanvas; const arect: rectty; + const clip: boolean; const move: boolean) of object; + beforeframepaintoverlayeventty = procedure (const sender: tcustomframe; + const canvas: tcanvas; const arect: rectty; + var handled: boolean) of object; + afterframepaintoverlayeventty = procedure (const sender: tcustomframe; + const canvas: tcanvas; const arect: rectty) of object; + + beforeframetemplatepaintbackgroundeventty = + procedure (const sender: tframetemplate; const canvas: tcanvas; + const arect: rectty; const astate: framestateflagsty; + var handled: boolean) of object; + afterframetemplatepaintbackgroundeventty = + procedure (const sender: tframetemplate; const canvas: tcanvas; + const arect: rectty; const astate: framestateflagsty) of object; + beforeframetemplatepaintoverlayeventty = + procedure (const sender: tframetemplate; const canvas: tcanvas; + const arect: rectty; const astate: framestateflagsty; + var handled: boolean) of object; + afterframetemplatepaintoverlayeventty = + procedure (const sender: tframetemplate; const canvas: tcanvas; + const arect: rectty; const astate: framestateflagsty) of object; + + tframetemplate = class(tpersistenttemplate,iimagelistinfo) + private + foptionsskincontroller: frameskincontrolleroptionsty; + fclientsizeextend: sizety; + fonbeforepaintbackground: beforeframepaintbackgroundeventty; + fonafterpaintbackground: afterframepaintbackgroundeventty; + fonbeforepaintoverlay: beforeframepaintoverlayeventty; + fonafterpaintoverlay: afterframepaintoverlayeventty; + fonbeforetemplatepaintbackground: beforeframetemplatepaintbackgroundeventty; + fonaftertemplatepaintbackground: afterframetemplatepaintbackgroundeventty; + fonbeforetemplatepaintoverlay: beforeframetemplatepaintoverlayeventty; + fonaftertemplatepaintoverlay: afterframetemplatepaintoverlayeventty; + procedure setcolorclient(const Value: colorty); + procedure setcolorframe(const Value: colorty); + procedure setcolorframeactive(const avalue: colorty); + procedure setcolorframedisabled(const avalue: colorty); + procedure setcolorframemouse(const avalue: colorty); + procedure setcolorframeclicked(const avalue: colorty); + procedure setcolorframedefault(const avalue: colorty); + procedure setcolordkshadow(const avalue: colorty); + procedure setcolorshadow(const avalue: colorty); + procedure setcolorlight(const avalue: colorty); + procedure setcolorhighlight(const avalue: colorty); + procedure setcolordkwidth(const avalue: integer); + procedure setcolorhlwidth(const avalue: integer); + procedure setcolorglyph(const avalue: colorty); + procedure setcolorpattern(const avalue: colorty); + + procedure sethiddenedges(const avalue: edgesty); + + procedure setframei_bottom(const Value: integer); + procedure setframei_left(const Value: integer); + procedure setframei_right(const Value: integer); + procedure setframei_top(const Value: integer); + procedure setframeo_bottom(const Value: integer); + procedure setframeo_left(const Value: integer); + procedure setframeo_right(const Value: integer); + procedure setframeo_top(const Value: integer); + procedure setframewidth(const Value: integer); + procedure setextraspace(const avalue: integer); + procedure setimagedist(const avalue: integer); + procedure setimagedist1(const avalue: integer); + procedure setimagedist2(const avalue: integer); + procedure setleveli(const Value: integer); + procedure setlevelo(const Value: integer); + + procedure setframeimage_list(const avalue: timagelist); + function getimagelist: timagelist; + procedure setframeimage_left(const avalue: integer); + procedure setframeimage_top(const avalue: integer); + procedure setframeimage_right(const avalue: integer); + procedure setframeimage_bottom(const avalue: integer); + procedure setframeimage_offset(const avalue: imagenrty); + procedure setframeimage_offset1(const avalue: imagenrty); + procedure setframeimage_offsetdisabled(const avalue: imagenrty); + procedure setframeimage_offsetmouse(const avalue: imagenrty); + procedure setframeimage_offsetclicked(const avalue: imagenrty); + procedure setframeimage_offsetactive(const avalue: imagenrty); + procedure setframeimage_offsetfocused(const avalue: imagenrty); + + procedure setframeface_list(const avalue: tfacelist); + procedure setframeface_offset(const avalue: facenrty); + procedure setframeface_offset1(const avalue: facenrty); + procedure setframeface_offsetdisabled(const avalue: facenrty); + procedure setframeface_offsetmouse(const avalue: facenrty); + procedure setframeface_offsetclicked(const avalue: facenrty); + procedure setframeface_offsetactive(const avalue: facenrty); + procedure setframeface_offsetfocused(const avalue: facenrty); + + procedure setoptionsskin(const avalue: frameskinoptionsty); + function getfont: toptionalfont; + procedure setfont(const avalue: toptionalfont); + function isfontstored: boolean; + procedure setcaptiondist(const avalue: integer); + procedure setcaptionoffset(const avalue: integer); + procedure setfocusrectdist(const avalue: integer); + procedure fontchanged(const sender: tobject); + procedure readdummy(reader: treader); + procedure readimagedisttop(reader: treader); + procedure readimagedistbottom(reader: treader); + protected + fi: frameinfoty; +// fextraspace: integer; +// fimagedist: integer; +// fimagedist1: integer; +// fimagedist2: integer; + procedure doassignto(dest: tpersistent); override; + function getinfosize: integer; override; + function getinfoad: pointer; override; + procedure copyinfo(const source: tpersistenttemplate); override; + procedure defineproperties(filer: tfiler); override; + public + constructor create(const owner: tmsecomponent; + const onchange: notifyeventty); override; + destructor destroy; override; + procedure paintbackground(const acanvas: tcanvas; const arect: rectty; + const astate: framestateflagsty = []); + //arect = paintrect + procedure paintoverlay(const acanvas: tcanvas; const arect: rectty; + const astate: framestateflagsty = []); + //arect = paintrect + procedure paintbackgroundframe(const acanvas: tcanvas; const arect: rectty; + const astate: framestateflagsty = []); + //arect = framerect + procedure paintoverlayframe(const acanvas: tcanvas; const arect: rectty; + const astate: framestateflagsty = []); + //arect = framerect + function paintframe: framety; + function innerframe: framety; + function paintframedim: sizety; + function innerframedim: sizety; + procedure createfont; + property framei: framety read fi.ba.innerframe; + property frameo: framety read fi.ba.outerframe; + property clientsizeextend: sizety read fclientsizeextend + write fclientsizeextend; + published + property levelo: integer read fi.ba.levelo write setlevelo default 0; + property leveli: integer read fi.ba.leveli write setleveli default 0; + property framewidth: integer read fi.ba.framewidth + write setframewidth default 0; + property colorframe: colorty read fi.ba.colorframe + write setcolorframe default cl_default; + property colorframeactive: colorty read fi.ba.colorframeactive + write setcolorframeactive default cl_default; + property colorframedisabled: colorty read fi.ba.colorframedisabled + write setcolorframedisabled default cl_default; + property colorframemouse: colorty read fi.ba.colorframemouse + write setcolorframemouse default cl_default; + property colorframeclicked: colorty read fi.ba.colorframeclicked + write setcolorframeclicked default cl_default; + property colorframedefault: colorty read fi.ba.colorframedefault + write setcolorframedefault default cl_default; + property colorglyph: colorty read fi.ba.colorglyph + write setcolorglyph default cl_default; + property colorpattern: colorty read fi.ba.colorpattern + write setcolorpattern default cl_default; + + property framei_left: integer read fi.ba.innerframe.left + write setframei_left default 0; + property framei_top: integer read fi.ba.innerframe.top + write setframei_top default 0; + property framei_right: integer read fi.ba.innerframe.right + write setframei_right default 0; + property framei_bottom: integer read fi.ba.innerframe.bottom + write setframei_bottom default 0; + + property frameo_left: integer read fi.ba.outerframe.left + write setframeo_left default 0; + property frameo_top: integer read fi.ba.outerframe.top + write setframeo_top default 0; + property frameo_right: integer read fi.ba.outerframe.right + write setframeo_right default 0; + property frameo_bottom: integer read fi.ba.outerframe.bottom + write setframeo_bottom default 0; + + property frameimage_list: timagelist read fi.ba.frameimage_list + write setframeimage_list; + //imagenr 0 = topleft, 1 = left, 2 = bottomleft, 3 = bottom, 4 = bottomright + //5 = right, 6 = topright, 7 = top + property frameimage_left: integer read fi.ba.frameimage_left + write setframeimage_left default 0; + property frameimage_top: integer read fi.ba.frameimage_top + write setframeimage_top default 0; + property frameimage_right: integer read fi.ba.frameimage_right + write setframeimage_right default 0; + property frameimage_bottom: integer read fi.ba.frameimage_bottom + write setframeimage_bottom default 0; + //added to imagelist size. + property frameimage_offset: imagenrty + read fi.ba.frameimage_offsets.offset + write setframeimage_offset default 0; + property frameimage_offset1: imagenrty + read fi.ba.frameimage_offsets.offset1 + write setframeimage_offset1 default 0; + property frameimage_offsetdisabled: imagenrty + read fi.ba.frameimage_offsets.disabled + write setframeimage_offsetdisabled default 0; + property frameimage_offsetmouse: imagenrty + read fi.ba.frameimage_offsets.mouse + write setframeimage_offsetmouse default 0; + property frameimage_offsetclicked: imagenrty + read fi.ba.frameimage_offsets.clicked + write setframeimage_offsetclicked default 0; + property frameimage_offsetactive: imagenrty + read fi.ba.frameimage_offsets.active + write setframeimage_offsetactive default 0; + property frameimage_offsetfocused: imagenrty + read fi.ba.frameimage_offsets.focused + write setframeimage_offsetfocused default 0; + property frameface_list: tfacelist read fi.ba.frameface_list + write setframeface_list; + property frameface_offset: facenrty + read fi.ba.frameface_offsets.offset + write setframeface_offset default 0; + property frameface_offset1: facenrty + read fi.ba.frameface_offsets.offset1 + write setframeface_offset1 default 0; + property frameface_offsetdisabled: facenrty + read fi.ba.frameface_offsets.disabled + write setframeface_offsetdisabled default 0; + property frameface_offsetmouse: facenrty + read fi.ba.frameface_offsets.mouse + write setframeface_offsetmouse default 0; + property frameface_offsetclicked: facenrty + read fi.ba.frameface_offsets.clicked + write setframeface_offsetclicked default 0; + property frameface_offsetactive: facenrty + read fi.ba.frameface_offsets.active + write setframeface_offsetactive default 0; + property frameface_offsetfocused: facenrty + read fi.ba.frameface_offsets.focused + write setframeface_offsetfocused default 0; + + //for tcaptionframe + property font: toptionalfont read getfont write setfont stored isfontstored; + //used in tmenu.itemframetemplate, itemframtemplateactive, + //tmainmenu.popupitemframetemplate, popupitemframetemplate also + property captiondist: integer read fi.capt.captiondist + write setcaptiondist default 0; //not used if font not set + property captionoffset: integer read fi.capt.captionoffset + write setcaptionoffset default 0; //not used if font not set + property fucusrectdist: int32 read fi.ba.focusrectdist + write setfocusrectdist default 0; + property extraspace: integer read fi.ba.extraspace + write setextraspace default 0; + property imagedist: integer read fi.ba.imagedist + write setimagedist default 0; + property imagedist1: integer read fi.ba.imagedist1 + write setimagedist1 default 0; + property imagedist2: integer read fi.ba.imagedist2 + write setimagedist2 default 0; + property colorclient: colorty read fi.ba.colorclient write setcolorclient + default cl_default; + property colordkshadow: colorty + read fi.ba.framecolors.edges.shadow.effectcolor + write setcolordkshadow default cl_default; + property colorshadow: colorty read fi.ba.framecolors.edges.shadow.color + write setcolorshadow default cl_default; + property colorlight: colorty read fi.ba.framecolors.edges.light.color + write setcolorlight default cl_default; + property colorhighlight: colorty + read fi.ba.framecolors.edges.light.effectcolor + write setcolorhighlight default cl_default; + property colordkwidth: integer + read fi.ba.framecolors.edges.shadow.effectwidth + write setcolordkwidth default -1; + property colorhlwidth: integer + read fi.ba.framecolors.edges.light.effectwidth + write setcolorhlwidth default -1; + property hiddenedges: edgesty read fi.ba.hiddenedges write sethiddenedges + default []; + property optionsskin: frameskinoptionsty read fi.ba.optionsskin + write setoptionsskin default []; + property optionsskincontroller: frameskincontrolleroptionsty + read foptionsskincontroller + write foptionsskincontroller default []; + property clientsizeextend_cx: int32 read fclientsizeextend.cx + write fclientsizeextend.cx default 0; + property clientsizeextend_cy: int32 read fclientsizeextend.cy + write fclientsizeextend.cy default 0; + property onbeforepaintbackground: beforeframepaintbackgroundeventty + read fonbeforepaintbackground write fonbeforepaintbackground; + property onafterpaintbackground: afterframepaintbackgroundeventty + read fonafterpaintbackground write fonafterpaintbackground; + property onbeforepaintoverlay: beforeframepaintoverlayeventty + read fonbeforepaintoverlay write fonbeforepaintoverlay; + property onafterpaintoverlay: afterframepaintoverlayeventty + read fonafterpaintoverlay write fonafterpaintoverlay; + + property onbeforetemplatepaintbackground: + beforeframetemplatepaintbackgroundeventty + read fonbeforetemplatepaintbackground + write fonbeforetemplatepaintbackground; + property onaftertemplatepaintbackground: + afterframetemplatepaintbackgroundeventty + read fonaftertemplatepaintbackground + write fonaftertemplatepaintbackground; + property onbeforetemplatepaintoverlay: + beforeframetemplatepaintoverlayeventty + read fonbeforetemplatepaintoverlay + write fonbeforetemplatepaintoverlay; + property onaftertemplatepaintoverlay: afterframetemplatepaintoverlayeventty + read fonaftertemplatepaintoverlay + write fonaftertemplatepaintoverlay; + + end; + + tframecomp = class(ttemplatecontainer) + private + function gettemplate: tframetemplate; + procedure settemplate(const Value: tframetemplate); + protected + function gettemplateclass: templateclassty; override; + public + published + property template: tframetemplate read gettemplate write settemplate; + end; + + tcustomface = class; + iface1 = interface(inullinterface) + function translatecolor(const acolor: colorty): colorty; + end; + iface = interface(iface1) + procedure invalidatewidget; + procedure invalidaterect(const rect: rectty; + const org: originty = org_client; const noclip: boolean = false); + function getclientrect: rectty; + procedure setlinkedvar(const source: tmsecomponent; var dest: tmsecomponent; + const linkintf: iobjectlink = nil); + function getcomponentstate: tcomponentstate; + procedure widgetregioninvalid; + end; + + faceoptionty = (fao_alphafadeimage,fao_alphafadenochildren,fao_alphafadeall, + fao_alphaimage, + fao_fadeoverlay,fao_overlay); + faceoptionsty = set of faceoptionty; + + tfadecolorarrayprop = class(tcolorarrayprop) + public + constructor create; + end; + + tfadeopacolorarrayprop = class(tcolorarrayprop) + public + constructor create; + end; + + tfacebitmap = class(tmaskedbitmap) + private + fowner: tcustomface; + fpos: pointty; + procedure setx(const avalue: int32); + procedure sety(const avalue: int32); + procedure setpos(const avalue: pointty); + procedure setcenter(avalue: pointty); + function getcenter: pointty; + public + constructor create(const aowner: tcustomface); + //nil -> default + property pos: pointty read fpos write setpos; + property center: pointty read getcenter write setcenter; + published + property x: int32 read fpos.x write setx default 0; + property y: int32 read fpos.y write sety default 0; + end; + + faceinfoty = record + frameimage_offset: integer; + options: faceoptionsty; + framei: framety; + + frameimage_list: timagelist; //not copied by move + fade_direction: graphicdirectionty; + image: tfacebitmap; + fade_pos: trealarrayprop; + fade_color: tfadecolorarrayprop; + fade_opacity: colorty; + fade_opapos: trealarrayprop; + fade_opacolor: tfadeopacolorarrayprop; + end; + + + tfacecomp = class; + tcustomface = class(toptionalpersistent) + private + flocalprops: facelocalpropsty; + ftemplate: tfacecomp; + falphabuffer: tmaskedbitmap; + falphabufferdest: pointty; + procedure settemplateinfo(const ainfo: faceinfoty); + procedure setoptions(const avalue: faceoptionsty); + function isoptionsstored: boolean; + procedure setframei_left(const avalue: integer); + function isframei_leftstored(): boolean; + procedure setframei_top(const avalue: integer); + function isframei_topstored(): boolean; + procedure setframei_right(const avalue: integer); + function isframei_rightstored(): boolean; + procedure setframei_bottom(const avalue: integer); + function isframei_bottomstored(): boolean; + + procedure setimage(const value: tfacebitmap); + function isimagestored: boolean; + procedure setfade_color(const Value: tfadecolorarrayprop); + function isfacolorstored: boolean; + procedure setfade_pos(const Value: trealarrayprop); + function isfaposstored: boolean; + procedure setfade_direction(const Value: graphicdirectionty); + function isfadirectionstored: boolean; + procedure setfade_opacity(avalue: colorty); + function isfaopacitystored: boolean; + procedure setfade_opacolor(const Value: tfadeopacolorarrayprop); + function isfaopacolorstored: boolean; + procedure setfade_opapos(const Value: trealarrayprop); + function isfaopaposstored: boolean; + procedure setframeimage_list(const avalue: timagelist); + function isframeimage_liststored: boolean; + procedure setframeimage_offset(const avalue: integer); + function isframeimage_offsetstored: boolean; + procedure settemplate(const avalue: tfacecomp); + procedure setlocalprops(avalue: facelocalpropsty); + procedure readtransparency(reader: treader); + protected + fintf: iface; + fi: faceinfoty; + procedure dochange(const sender: tarrayprop; const index: integer); + procedure change; + procedure imagechanged(const sender: tobject); + procedure internalcreate; override; + procedure doalphablend(const canvas: tcanvas); + procedure defineproperties(filer: tfiler); override; + procedure internalpaint(const canvas: tcanvas; const arect: rectty); virtual; + public + constructor create; overload; override; + constructor create(const owner: twidget); reintroduce; overload; + //sets fowner.fframe + constructor create(const intf: iface); reintroduce; overload; + destructor destroy; override; + procedure checktemplate(const sender: tobject); + procedure assign(source: tpersistent); override; + procedure paint(const canvas: tcanvas; const arect: rectty); + property options: faceoptionsty read fi.options write setoptions + stored isoptionsstored default []; + property framei_left: integer read fi.framei.left write setframei_left + stored isframei_leftstored default 0; + property framei_top: integer read fi.framei.top write setframei_top + stored isframei_topstored default 0; + property framei_right: integer read fi.framei.right write setframei_right + stored isframei_rightstored default 0; + property framei_bottom: integer read fi.framei.bottom write setframei_bottom + stored isframei_bottomstored default 0; + + property image: tfacebitmap read fi.image write setimage + stored isimagestored; + property fade_pos: trealarrayprop read fi.fade_pos write setfade_pos + stored isfaposstored; + property fade_color: tfadecolorarrayprop read fi.fade_color + write setfade_color stored isfacolorstored; + property fade_direction: graphicdirectionty read fi.fade_direction + write setfade_direction + stored isfadirectionstored default gd_right ; + property fade_opacity: colorty read fi.fade_opacity + write setfade_opacity + stored isfaopacitystored default cl_none; + property fade_opapos: trealarrayprop read fi.fade_opapos + write setfade_opapos stored isfaopaposstored; + property fade_opacolor: tfadeopacolorarrayprop read fi.fade_opacolor + write setfade_opacolor stored isfaopacolorstored; + + property frameimage_list: timagelist read fi.frameimage_list + write setframeimage_list stored isframeimage_liststored; + //imagenr 0 = topleft, 1 = left, 2 = bottomleft, 3 = bottom, + // 4 = bottomright 5 = right, 6 = topright, 7 = top + property frameimage_offset: integer read fi.frameimage_offset + write setframeimage_offset + stored isframeimage_offsetstored default 0; + + property localprops: facelocalpropsty read flocalprops + write setlocalprops {default []}; + //before template + property template: tfacecomp read ftemplate write settemplate; + end; + + tface = class(tcustomface) + published + property options; + property image; + property framei_left; + property framei_top; + property framei_right; + property framei_bottom; + property fade_pos; + property fade_color; + property fade_opapos; + property fade_opacolor; + property fade_direction; + property fade_opacity; + property frameimage_list; + property frameimage_offset; + property localprops; //before template + property template; + end; + + tfacearrayprop = class(tpersistentarrayprop) + private + fintf: iface; + function getitems(const index: integer): tface; + protected + procedure createitem(const index: integer; var item: tpersistent); override; + public + constructor create(const aintf: iface); reintroduce; + class function getitemclasstype: persistentclassty; override; + property items[const index: integer]: tface read getitems; default; + end; + + tfacelist = class(tmsecomponent,iface) + private + flist: tfacearrayprop; + findexlookup: msestring; + procedure setlist(const avalue: tfacearrayprop); + //iface + procedure invalidatewidget(); + procedure invalidaterect(const rect: rectty; + const org: originty = org_client; const noclip: boolean = false); + function translatecolor(const acolor: colorty): colorty; + function getclientrect: rectty; + function getcomponentstate: tcomponentstate; + procedure widgetregioninvalid; + procedure setindexlookup(const avalue: msestring); + protected + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure paint(const canvas: tcanvas; const aindex: int32; + const dest: rectty); + function lookup(const aindex: int32): int32; + published + property list: tfacearrayprop read flist write setlist; + property indexlookup: msestring read findexlookup write setindexlookup; + //array of int16 + end; + + beforefacepainteventty = procedure (const sender: tcustomface; + const canvas: tcanvas; const arect: rectty; + var handled: boolean) of object; + afterfacepainteventty = procedure (const sender: tcustomface; + const canvas: tcanvas; const arect: rectty) of object; + + tfacetemplate = class(tpersistenttemplate,iface1) + private + fi: faceinfoty; + fonbeforepaint: beforefacepainteventty; + fonafterpaint: afterfacepainteventty; + procedure setoptions(const avalue: faceoptionsty); + procedure setframei_left(const avalue: integer); + procedure setframei_top(const avalue: integer); + procedure setframei_right(const avalue: integer); + procedure setframei_bottom(const avalue: integer); + + procedure setfade_color(const Value: tfadecolorarrayprop); + procedure setfade_pos(const Value: trealarrayprop); + procedure setfade_opacolor(const Value: tfadeopacolorarrayprop); + procedure setfade_opapos(const Value: trealarrayprop); + procedure setfade_opacity(avalue: colorty); + procedure setfade_direction(const Value: graphicdirectionty); + procedure setimage(const Value: tfacebitmap); + procedure doimagechange(const sender: tobject); + procedure dochange(const sender: tarrayprop; const index: integer); + procedure setframeimage_list(const avalue: timagelist); + procedure setframeimage_offset(const avalue: integer); + procedure readtransparency(reader: treader); + protected + procedure doassignto(dest: tpersistent); override; + function getinfosize: integer; override; + function getinfoad: pointer; override; + procedure copyinfo(const source: tpersistenttemplate); override; + procedure internalcreate; override; + procedure defineproperties(filer: tfiler); override; + //iface1 + function translatecolor(const acolor: colorty): colorty; + public + constructor create(const owner: tmsecomponent; + const onchange: notifyeventty); override; + destructor destroy; override; + procedure paint(const canvas: tcanvas; const arect: rectty); + published + property options: faceoptionsty read fi.options write setoptions default []; + property framei_left: integer read fi.framei.left + write setframei_left default 0; + property framei_top: integer read fi.framei.top + write setframei_top default 0; + property framei_right: integer read fi.framei.right + write setframei_right default 0; + property framei_bottom: integer read fi.framei.bottom + write setframei_bottom default 0; + + property image: tfacebitmap read fi.image write setimage; + property fade_pos: trealarrayprop read fi.fade_pos write setfade_pos; + property fade_color: tfadecolorarrayprop read fi.fade_color + write setfade_color; + property fade_opapos: trealarrayprop read fi.fade_opapos + write setfade_opapos; + property fade_opacolor: tfadeopacolorarrayprop read fi.fade_opacolor + write setfade_opacolor; + property fade_direction: graphicdirectionty read fi.fade_direction + write setfade_direction default gd_right; + property fade_opacity: colorty read fi.fade_opacity + write setfade_opacity default cl_none; + + property frameimage_list: timagelist read fi.frameimage_list + write setframeimage_list; + //imagenr 0 = topleft, 1 = left, 2 = bottomleft, 3 = bottom, 4 = bottomright + //5 = right, 6 = topright, 7 = top + property frameimage_offset: integer read fi.frameimage_offset + write setframeimage_offset default 0; + property onbeforepaint: beforefacepainteventty read fonbeforepaint + write fonbeforepaint; + property onafterpaint: afterfacepainteventty read fonafterpaint + write fonafterpaint; + end; + + tfacecomp = class(ttemplatecontainer) + private + function gettemplate: tfacetemplate; + procedure settemplate(const Value: tfacetemplate); + protected + function gettemplateclass: templateclassty; override; + public + published + property template: tfacetemplate read gettemplate write settemplate; + end; + + mouseeventty = procedure (const sender: twidget; + var ainfo: mouseeventinfoty) of object; + mousewheeleventty = procedure (const sender: twidget; + var ainfo: mousewheeleventinfoty) of object; + keyeventty = procedure (const sender: twidget; + var ainfo: keyeventinfoty) of object; + shortcuteventty = procedure (const sender: twidget; var ainfo: keyeventinfoty; + const origin: twidget) of object; + painteventty = procedure (const sender: twidget; + const acanvas: tcanvas) of object; + pointeventty = procedure(const sender: twidget; + const apoint: pointty) of object; + widgeteventty = procedure(const sender: tobject; + const awidget: twidget) of object; + + widgetarty = array of twidget; + + twindow = class; + pwindow = ^twindow; + + windowinfoty = record + options: windowoptionsty; + initialwindowpos: windowposty; + transientfor: twindow; + groupleader: twindow; + icon,iconmask: pixmapty; + end; + + naviginfoty = record + sender: twidget; + direction: graphicdirectionty; + startingrect: rectty; + wraprect: rectty; + distance: integer; + nearest: twidget; + down: boolean; + hastarget: boolean; + end; + + twidgetfont = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + widgetfontclassty = class of twidgetfont; + + twidgetfontempty = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + widgetfontemptyclassty = class of twidgetfontempty; + + twidgetevent = class(tcomponentevent) + end; + + modallevelty = (ml_none,ml_application, //call eventloop + ml_window); //reflect window focus + + rootchangeflagty = (rcf_widgetregioninvalid,rcf_windowset,rcf_windowremove); + rootchangeflagsty = set of rootchangeflagty; + + widgetalignmodety = (wam_none,wam_start,wam_center,wam_end); + navigrequesteventty = procedure(const sender: twidget; + var ainfo: naviginfoty) of object; + twidget = class(tactcomponent,iscrollframe,iface,iassistiveclient) + private + fwidgetregion: gdiregionty; + frootpos: pointty; //position in rootwindow + fcursor: cursorshapety; + ftaborder: integer; + fminsize,fmaxsize: sizety; + fminclientsize: sizety; + fminscrollsize: sizety; + fminshrinksize: sizety; + ffocusedchild,ffocusedchildbefore: twidget; + ffontheight: integer; + fsetwidgetrectcount: integer; //for recursive setpos + fautosizelevel: byte; + + foptionsskin: optionsskinty; + fskingroup: integer; + fonnavigrequest: navigrequesteventty; + geframewidth: integer; + procedure invalidateparentminclientsize; + function getwidgets(const index: integer): twidget; + function dofindwidget(const awidgets: widgetarty; + aname: ansistring): twidget; + + procedure setpos(const Value: pointty); + procedure setsize(const Value: sizety); + procedure setbounds_x(const Value: integer); + procedure setbounds_y(const Value: integer); + procedure setbounds_cx(const Value: integer); + procedure setbounds_cy(const Value: integer); + procedure updatesizerange(value: integer; var dest: integer); overload; + procedure updatesizerange(const value: sizety; var dest: sizety); overload; + procedure setbounds_cxmax(const Value: integer); + procedure setbounds_cymax(const Value: integer); + procedure setbounds_cxmin(const Value: integer); + procedure setbounds_cymin(const Value: integer); + procedure setminsize(const avalue: sizety); + procedure setmaxsize(const avalue: sizety); + + procedure setcursor(const avalue: cursorshapety); + function getsize: sizety; + + function invalidateneeded: boolean; + procedure addopaquechildren(var region: gdiregionty); + procedure updatewidgetregion; + function isclientmouseevent(var info: mouseeventinfoty): boolean; + procedure internaldofocus; + procedure internaldodefocus; + procedure internaldoenter; + procedure internaldoexit; + procedure internaldoactivate; + procedure internaldodeactivate; + procedure internalkeydown(var info: keyeventinfoty); + + function clipcaret: rectty; //origin = pos + procedure reclipcaret; + procedure updatetaborder(awidget: twidget); + procedure settaborder(const Value: integer); + procedure parentfontchanged; + procedure setanchors(const Value: anchorsty); + + function getzorder: integer; + procedure setzorder(const value: integer); + + function getparentclientpos: pointty; + procedure setparentclientpos(const avalue: pointty); + + function getscreenpos: pointty; + procedure setscreenpos(const avalue: pointty); + + function getclientoffset: pointty; + function calcframewidth(arect: prectty): sizety; + + procedure readfontheight(reader: treader); + procedure writefontheight(writer: twriter); + procedure updatefontheight; + + procedure checkwidgetsize(var size: sizety); + //check size constraints + procedure setoptionsskin(const avalue: optionsskinty); + function getpaintsize: sizety; + procedure setpaintsize(const avalue: sizety); + function getframesize: sizety; + procedure setframesize(const avalue: sizety); + procedure setframewidth(const avalue: integer); + function getframeheight: integer; + procedure setframeheight(const avalue: integer); + function getpaintwidth: integer; + procedure setpaintwidth(const avalue: integer); + function getpaintheight: integer; + procedure setpaintheight(const avalue: integer); + protected + fwidgets: widgetarty; + fnoinvalidate: integer; + fwidgetupdating: integer; + foptionswidget: optionswidgetty; + foptionswidget1: optionswidget1ty; + fparentwidget: twidget; + fanchors: anchorsty; + fwidgetstate: widgetstatesty; + fwidgetstate1: widgetstates1ty; + fcolor: colorty; + fwindow: twindow; + fwidgetrect: rectty; + fparentclientsize: sizety; + fframe: tcustomframe; + fface: tcustomface; + ffont: twidgetfont; + ffontempty: twidgetfontempty; + fhint: msestring; + fdefaultfocuschild: twidget; + + procedure checksizes(); + function widgetminsize1: sizety; + //checks ws1_clientcxmin,ws1_clientcymin + function widgetmaxsize1: sizety; + //checks ws1_clientcxmin,ws1_clientcymin + function minclientsize: sizety; + function isdesignwidget(): boolean; virtual; + procedure setdesignwidget(); + //sets ws1_designwidget and removes ws_iswidget for self and children + procedure designmouseevent(var info: moeventinfoty; + capture: twidget); virtual; + procedure designkeyevent(const eventkind: eventkindty; + var info: keyeventinfoty); virtual; + + procedure defineproperties(filer: tfiler); override; + function gethelpcontext: msestring; override; + class function classskininfo: skininfoty; override; + function skininfo: skininfoty; override; + function hasskin: boolean; override; + + function navigstartrect: rectty; virtual; //origin = pos + function navigrect: rectty; virtual; //origin = pos + procedure navigrequest(var info: naviginfoty; + const nowrap: boolean = false); virtual; + function navigdistance(var info: naviginfoty; + const nowrap: boolean = false): integer; virtual; + + function nexttaborderoverride(const sender: twidget; + const down: boolean = false): twidget virtual; + + function getwidgetrects(const awidgets: array of twidget): rectarty; + procedure setwidgetrects(const awidgets: array of twidget; + const arects: rectarty); + + procedure updateroot; + procedure setcolor(const avalue: colorty); virtual; + function gethint: msestring; virtual; + procedure sethint(const Value: msestring); virtual; + function ishintstored: boolean; virtual; + function getshowhint: boolean; + procedure showhint(const aid: int32; var info: hintinfoty); virtual; + + function isgroupleader: boolean; virtual; + function needsfocuspaint: boolean; virtual; + function needsfocuspaintstate(): boolean; //checks ws_focused, ws_active + function getnoscroll(): boolean; virtual; + function getenabled: boolean; + procedure setenabled(const Value: boolean); virtual; + function getvisible: boolean; + procedure setvisible(const avalue: boolean); virtual; + function isvisible: boolean; //checks designing + function parentisvisible: boolean;//checks isvisible flags of ancestors + function parentvisible: boolean; //checks visible flags of ancestors + function updateopaque(const children: boolean; + const widgetregioncall: boolean): boolean; + //true if widgetregionchanged called + procedure dragstarted; virtual; //called by tapplication.dragstarted + //iscrollframe + function getzoomrefframe: framety; virtual; + //idragcontroller + function getdragrect(const apos: pointty): rectty; virtual; + //iface + procedure widgetregioninvalid; + //iframe + procedure setframeinstance(instance: tcustomframe); virtual; + procedure setstaticframe(value: boolean); + function getstaticframe: boolean; + function getwidgetrect: rectty; + function getcomponentstate: tcomponentstate; + + function getframestateflags: framestateflagsty; virtual; + //igridcomp,itabwidget + function getwidget: twidget; + + function getframe: tcustomframe; + procedure setframe(const avalue: tcustomframe); + function getface: tcustomface; + procedure setface(const avalue: tcustomface); + + function getgdi: pgdifunctionaty; virtual; + procedure createwindow; virtual; + procedure objectchanged(const sender: tobject); virtual; + procedure objectevent(const sender: tobject; const event: objecteventty); override; + procedure receiveevent(const event: tobjectevent); override; + procedure setchildorder(child: tcomponent; order: integer); overload; override; + procedure setparentcomponent(value: tcomponent); override; + function clearparentwidget: twidget; + //returns old parentwidget + procedure setparentwidget(const Value: twidget); virtual; + procedure setlockedparentwidget(const avalue: twidget); + //sets ws_loadlock before setting, restores afterwards + procedure updatewindowinfo(var info: windowinfoty); virtual; + procedure windowcreated; virtual; + procedure setoptionswidget(const avalue: optionswidgetty); virtual; + procedure setoptionswidget1(const avalue: optionswidget1ty); virtual; + procedure getchildren(proc: tgetchildproc; root: tcomponent); override; + + procedure initparentclientsize; + function getcaretcliprect: rectty; virtual; //origin = clientrect.pos + procedure dobeginread; override; + procedure doendread; override; + procedure loaded; override; + procedure setdesigning(value: boolean; + setchildren : boolean = true); override; + + procedure updatemousestate(const info: mouseeventinfoty); virtual; + //updates fstate about mouseposition + procedure setclientclick; //grabs mouse and sets clickflags + procedure releasebuttonpressgrab(); + + procedure registerchildwidget(const child: twidget); virtual; + procedure unregisterchildwidget(const child: twidget); virtual; + function isfontstored: Boolean; + procedure setfont(const avalue: twidgetfont); + function getfont: twidgetfont; + function getfont1: twidgetfont; //no getoptionalobject + function isfontemptystored: Boolean; + procedure setfontempty(const avalue: twidgetfontempty); + function getfontempty: twidgetfontempty; + function getfontempty1: twidgetfontempty; //no getoptionalobject + function getframefont: tfont; + procedure fontchanged; virtual; + procedure fontcanvaschanged; virtual; + procedure updatecursorshape(apos: pointty){(force: boolean = false)}; + + procedure parentclientrectchanged; virtual; + procedure parentwidgetregionchanged(const sender: twidget); virtual; + procedure widgetregionchanged(const sender: twidget); virtual; + procedure scalebasechanged(const sender: twidget); virtual; //used by tlayouter + + {$ifdef mse_with_ifi} + procedure ifiwidgetstatechanged; + function getifiwidgetstate: ifiwidgetstatesty; virtual; + {$endif} + procedure cursorchanged; + procedure statechanged; virtual; //enabled,active,visible + // todo: + //use an universal state*changed() + //with state mask instead + procedure enabledchanged; virtual; + procedure activechanged; virtual; + procedure visiblepropchanged; virtual; + procedure visiblechanged; virtual; + procedure colorchanged; virtual; + procedure sizechanged; virtual; + procedure getautopaintsize(var asize: sizety); virtual; + procedure getautocellsize(const acanvas: tcanvas; + var asize: sizety); virtual; + procedure childclientrectchanged(const sender: twidget); virtual; + procedure childautosizechanged(const sender: twidget); virtual; + procedure poschanged; virtual; + procedure clientrectchanged; virtual; + procedure parentchanged; virtual; + procedure rootchanged(const aflags: rootchangeflagsty); virtual; + function getdefaultfocuschild: twidget; virtual; + //returns first focusable widget + procedure setdefaultfocuschild(const value: twidget); virtual; + function trycancelmodal(const newactive: twindow): boolean; virtual; + //called by twindow.internalactivate, true if accepted + procedure sortzorder; + + function needsdesignframe: boolean; virtual; + function getactface: tcustomface; virtual; + procedure dobeforepaint(const canvas: tcanvas); virtual; + procedure dopaint(const canvas: tcanvas); virtual; + procedure paintbackground(const canvas: tcanvas; + const arect: rectty); virtual; + procedure dopaintbackground(const canvas: tcanvas); virtual; + procedure doonpaintbackground(const canvas: tcanvas); virtual; + procedure dobeforepaintforeground(const canvas: tcanvas); virtual; + procedure dopaintforeground(const canvas: tcanvas); virtual; + procedure doonpaint(const canvas: tcanvas); virtual; + procedure paintoverlay(const canvas: tcanvas; + const arect: rectty); virtual; + procedure dopaintoverlay(const canvas: tcanvas); virtual; + procedure doafterpaint(const canvas: tcanvas); virtual; + + procedure doscroll(const dist: pointty); virtual; + procedure doscrolled(const dist: pointty); virtual; + + procedure doloaded() virtual; + procedure dohide() virtual; + procedure doshow() virtual; + procedure doactivate() virtual; + procedure doafteractivate() virtual; + procedure dodeactivate() virtual; + procedure doenter() virtual; + procedure doexit() virtual; + procedure dofocus() virtual; + procedure dodefocus() virtual; + procedure dochildfocused(const sender: twidget); virtual; + procedure dofocuschanged(const oldwidget,newwidget: twidget); virtual; + procedure domousewheelevent(var info: mousewheeleventinfoty); virtual; + + function wantmousefocus(const info: mouseeventinfoty): boolean; + procedure reflectmouseevent(var info: mouseeventinfoty); + //posts mousevent to window under mouse + procedure mouseevent(var info: mouseeventinfoty); virtual; + procedure mousepreview(const sender: twidget; + var info: mouseeventinfoty); virtual; + procedure childmouseevent(const sender: twidget; + var info: mouseeventinfoty); virtual; + procedure clientmouseevent(var info: mouseeventinfoty); virtual; + procedure mousewheelevent(var info: mousewheeleventinfoty); virtual; + + procedure dokeydown1(var info: keyeventinfoty); + //updates flags, calls dokeydown + procedure dokeydown(var info: keyeventinfoty); virtual; + //do not call dokeydown, call dokeydown1 + procedure doshortcut(var info: keyeventinfoty; const sender: twidget); + virtual; + //called twice, first before dokeydown with es_preview set + function checkfocusshortcut(var info: keyeventinfoty): boolean; virtual; + procedure handlenavigkeys(var info: keyeventinfoty; + const nowrap: boolean = false); virtual; + procedure dokeydownaftershortcut(var info: keyeventinfoty); virtual; + procedure dokeyup(var info: keyeventinfoty); virtual; + + procedure dofontchanged(const sender: tobject); + procedure setfontheight; + procedure postchildscaled; + function verticalfontheightdelta: boolean; virtual; + procedure dofontheightdelta(var delta: integer); virtual; + procedure syncsinglelinefontheight(const lineheight: boolean = false; + const space: integer = 2); + + procedure setwidgetrect(const Value: rectty); + procedure internalsetwidgetrect(Value: rectty; + const windowevent: boolean); virtual; + function getclientpos: pointty; + function getclientsize: sizety; + procedure setclientsize(const asize: sizety); virtual; + //used in tscrollingwidget + function getclientwidth: integer; + procedure setclientwidth(const avalue: integer); + function getclientheight: integer; + procedure setclientheight(const avalue: integer); + function internalshow(const modallevel: modallevelty; + const transientfor: pwindow; //follow linkedvar state + const windowevent,nomodalforreset: boolean): modalresultty; virtual; + procedure internalhide(const windowevent: boolean); + function checksubfocus(const aactivate: boolean): boolean; virtual; + function getnextfocus: twidget; + function cantabfocus: boolean; + function getdisprect: rectty; virtual; + //origin pos, clamped in view by activate + + function getshrinkpriority: integer; virtual; //default 0 + procedure tryshrink(const aclientsize: sizety); virtual; + function calcminscrollsize: sizety; virtual; + function getminshrinkpos: pointty; virtual; + function calcminshrinksize: sizety; virtual; + function getcontainer: twidget; virtual; + function getchildwidgets(const index: integer): twidget; virtual; + + function getright: integer; //if placed in datamodule + procedure setright(const avalue: integer); + function getbottom: integer; + procedure setbottom(const avalue: integer); + function ownswindow1: boolean; //does not check winid + + procedure internalcreateframe; virtual; + procedure internalcreateface; virtual; + function getfontclass: widgetfontclassty; virtual; + function getfontemptyclass: widgetfontemptyclassty; virtual; + procedure internalcreatefont; virtual; + procedure internalcreatefontempty; virtual; + + function getclientrect: rectty; + function windowpo: pwindowty; + function canclose1: boolean; + + function getiassistiveclient(): iassistiveclient virtual; + //iassistiveclient + function getassistiveparent(): iassistiveclient virtual; + function getassistivewidget(): tobject virtual; + function getassistivename(): msestring virtual; + function getassistivecaption(): msestring virtual; + function getassistivetext(): msestring virtual; + function getassistivecaretindex(): int32 virtual; + function getassistivehint(): msestring virtual; + function getassistiveflags(): assistiveflagsty virtual; + {$ifdef mse_with_ifi} + function getifidatalinkintf(): iifidatalink virtual; + {$endif} + public + constructor create(aowner: tcomponent); overload; override; + constructor create(const aowner: tcomponent; + const aparentwidget: twidget); overload; + constructor create(const aowner: tcomponent; + const aparentwidget: twidget; + const aiswidget: boolean{ = true}); overload; + //uses setlockedparentwidget + constructor createandinit(const aowner: tcomponent; + const aparentwidget: twidget; + const aiswidget: boolean); overload; + //uses setlockedparentwidget + destructor destroy; override; + procedure afterconstruction; override; + procedure initnewcomponent(const ascale: real); override; + //called before inserting in parentwidget + procedure initnewwidget(const ascale: real); virtual; + //called after inserting in parentwidget + procedure createframe; + procedure createface; + procedure createfont; + procedure createfontempty; + procedure checkautosize(); + procedure updatehotkeys() virtual; + + function isloading: boolean; //checks ws_loadlock and csdestroing too + procedure beginupdate; //sets ws_loadlock and noinvalidate + procedure endupdate; + function canmouseinteract: boolean; //checks csdesigning and cssubcomponent + function canassistive(): boolean virtual; + function widgetstate: widgetstatesty; //iframe + property widgetstate1: widgetstates1ty read fwidgetstate1; + function hasparent: boolean; override; //tcomponent + function getparentcomponent: tcomponent; override; //tcomponent + function hascaret: boolean; + function canwindow: boolean; + //true if twindow allocated or not rootwidget destroying + function windowallocated: boolean; + //true if winid allocated and not loading and not destroying + function ownswindow: boolean; + //true if valid toplevelwindow with assigned winid + function updaterect: rectty; //invalidated area, origin = clientpos + + procedure beforeclosequery(var amodalresult: modalresultty); virtual; + //called on top level window + function canclose(const newfocus: twidget = nil): boolean; virtual; + function canparentclose(const newfocus: twidget): boolean; overload; + //window.focusedwidget is first checked if it is descendant + function forceclose: boolean; //newfocus=nil, sets ws1_forceclose, true if ok + function canparentclose: boolean; overload; + //newfocus = window.focusedwidget + function canfocus: boolean; virtual; + function setfocus(aactivate: boolean = true): boolean; virtual;//true if ok + procedure parentfocus; //sets focus to self or focusable parent + procedure nextfocus; //sets inputfocus to then next appropriate widget + function findtabfocus(const ataborder: integer): twidget; + //nil if can not focus + function firsttabfocus: twidget; + function lasttabfocus: twidget; + function nexttaborder(const down: boolean = false; + nowrap: boolean = false): twidget; + function focusback(const aactivate: boolean = true): boolean; virtual; + //false if focus not changed + + function parentcolor: colorty; + function actualcolor: colorty; virtual; + function actualopaquecolor: colorty; virtual; + function backgroundcolor: colorty; + function translatecolor(const acolor: colorty): colorty; + + procedure widgetevent(const event: twidgetevent); virtual; + procedure sendwidgetevent(const event: twidgetevent); + //event will be destroyed + + procedure release(const nomodaldefer: boolean=false); override; + function show(const modallevel: modallevelty; + const transientfor: twindow = nil): modalresultty; + overload; virtual; + function show(const modallevel: modallevelty; + const transientfor: twidget): modalresultty; overload; + function show(const modal: boolean = false; + const transientfor: twindow = nil): modalresultty; overload; + procedure endmodal; + procedure hide; + procedure activate(const abringtofront: boolean = true; + const aforce: boolean = false); virtual; + //show and setfocus + procedure bringtofront; + procedure sendtoback; + procedure stackunder(const predecessor: twidget); + procedure setchildorder(const achildren: widgetarty); overload; + //last is top, nil items ignored + + procedure paint(const canvas: tcanvas); virtual; + procedure update; virtual; + procedure scrollwidgets(const dist: pointty); + procedure scrollrect(const dist: pointty; const rect: rectty; + scrollcaret: boolean); //origin = paintrect.pos + procedure scroll(const dist: pointty); + //scrolls paintrect and widgets + procedure clampinview(const arect: rectty; + const bottomright: boolean = false); virtual; + //origin paintpos + + procedure getcaret; + procedure scrollcaret(const dist: pointty); + function mousecaptured: boolean; + function capturemouse(grab: boolean = true): boolean; + //true for new grab + procedure releasemouse(const grab: boolean = false); + function capturekeyboard: boolean; //true for new grab + procedure releasekeyboard; + procedure synctofontheight; virtual; + + procedure dragevent(var info: draginfoty); virtual; + procedure dolayout(const sender: twidget); virtual; + + procedure invalidatewidget; //invalidates whole widget + procedure invalidate; //invalidates clientrect + procedure invalidaterect(const rect: rectty; + const org: originty = org_client; const noclip: boolean = false); + procedure invalidateframestate; + procedure invalidateframestaterect(const rect: rectty; + const aframe: tcustomframe; const org: originty = org_client); + function hasoverlappingsiblings(arect: rectty): boolean; //origin = pos + + function window: twindow; + function rootwidget: twidget; + function parentofcontainer: twidget; + //parentwidget.parentwidget if parentwidget has not ws_iswidget, + //parentwidget otherwise + property parentwidget: twidget read fparentwidget write setparentwidget; + function getrootwidgetpath: widgetarty; //root widget is last + function widgetcount: integer; + function parentwidgetindex: integer; + //index in parentwidget.widgets, -1 if none + function indexofwidget(const awidget: twidget): integer; + function checkdescendent(awidget: twidget): boolean; + //true if widget is descendent or self + function checkancestor(awidget: twidget): boolean; + //true if widget is ancestor or self + function containswidget(awidget: twidget): boolean; + + property widgets[const index: integer]: twidget read getwidgets; + function widgetatpos(var info: widgetatposinfoty): twidget; overload; + function widgetatpos(const pos: pointty): twidget; overload; + function widgetatpos(const pos: pointty; + const state: widgetstatesty): twidget; overload; + + property container: twidget read getcontainer; + function containeroffset: pointty; + function childrencount: integer; virtual; + function visiblechildrencount: integer; + property children[const index: integer]: twidget read getchildwidgets; + default; + //children of container + function findtagchild(const atag: integer; + const aclass: widgetclassty): twidget; + //returns first matching descendent + function findchild(const aname: ansistring): twidget; + //searches in container.widgets, case insensitive + function childatpos(const pos: pointty; + const clientorigin: boolean = true): twidget; virtual; + function gettaborderedwidgets: widgetarty; + function getvisiblewidgets: widgetarty; + function getcornerwidget(const side: graphicdirectionty; + const visibleonly: boolean): twidget; + function getsortxchildren(const banded: boolean = false): widgetarty; + //banded -> row,column order + function getsortychildren(const banded: boolean = false): widgetarty; + //banded -> column,row order + function getlogicalchildren: widgetarty; virtual; //children of container + procedure addlogicalchildren(var achildren: widgetarty); + function findlogicalchild(const aname: ansistring): twidget; + //case insensitive + + property focusedchild: twidget read ffocusedchild; + property focusedchildbefore: twidget read ffocusedchildbefore; + function enteredchild(): twidget; + + function mouseeventwidget(const info: mouseeventinfoty): twidget; + + procedure insertwidget(const awidget: twidget); overload; + procedure insertwidget(const awidget: twidget; + const apos: pointty); overload; virtual; + //widget can be child + + function iswidgetclick(const info: mouseeventinfoty; + const caption: boolean = false): boolean; + //true if eventtype = et_butonrelease, button is mb_left, + // clicked and pos in clientrect or in frame.caption if caption = true, + // origin = pos + function iswidgetdblclick(const info: mouseeventinfoty; + const caption: boolean = false): boolean; + //true if eventtype = et_butonrelease, button is mb_left, + // clicked and pos in clientrect or in frame.caption if caption = true, + // and timedlay to last buttonpress is short + // origin = pos + function iswidgetdblclicked(const info: mouseeventinfoty; + const caption: boolean = false): boolean; + //true if eventkind = ek_buttonrelease, button is mb_left, + // and pos in clientrect or in frame.caption if caption = true + // and timedelay to last buttonrelease is short + // origin = pos + function isclick(const info: mouseeventinfoty): boolean; + //true if eventkind = ek_buttonrelease, button is mb_left, + // clicked and pos in clientrect + function isdblclick(const info: mouseeventinfoty): boolean; + //true if eventtype = ek_buttonpress, button is mb_left, pos in clientrect + // and timedelay to last buttonpress is short + // origin = paintrect.pos + function isdblclicked(const info: mouseeventinfoty): boolean; + //true if eventkind in [ek_buttonpress,ek_buttonrelease], button is mb_left, + // and timedelay to last same buttonevent is short + function isleftbuttondown(const info: mouseeventinfoty): boolean; overload; + //true if eventkind = ek_buttonpress, button is mb_left, pos in clientrect + // origin = paintrect.pos + function isleftbuttondown(const info: mouseeventinfoty; + const akeyshiftstate: shiftstatesty): boolean; overload; + + function widgetmousepos(const ainfo: mouseeventinfoty): pointty; + //translates to widgetpos if necessary + + function rootpos: pointty; + function rootwidgetrect: rectty; + property screenpos: pointty read getscreenpos write setscreenpos; + + function clientpostowidgetpos(const apos: pointty): pointty; + function widgetpostoclientpos(const apos: pointty): pointty; + function widgetpostopaintpos(const apos: pointty): pointty; + function paintpostowidgetpos(const apos: pointty): pointty; + procedure scale(const ascale: real); virtual; + + property widgetrect: rectty read fwidgetrect write setwidgetrect; + function widgetscreenrect: rectty; //screen origin + function widgetclientrect: rectty; //origin = clientrect.pos + + property pos: pointty read fwidgetrect.pos write setpos; + property size: sizety read fwidgetrect.size write setsize; + property minsize: sizety read fminsize write setminsize; + function widgetminsize: sizety; + //calls checkwidgetsize and frame.checkwidgetsize + //checks ws1_clientcxmin,ws1_clientcymin + function widgetmaxsize: sizety; + //calls checkwidgetsize and frame.checkwidgetsize + //checks ws1_clientcxmin,ws1_clientcymin + + property maxsize: sizety read fmaxsize write setmaxsize; + function maxclientsize: sizety; virtual; + function minscrollsize: sizety; //uses cache + function minshrinksize: sizety; //uses cache + property bounds_x: integer read fwidgetrect.x write setbounds_x; + property bounds_y: integer read fwidgetrect.y write setbounds_y; + property bounds_cx: integer read fwidgetrect.cx write setbounds_cx + {default defaultwidgetwidth} stored true; + property bounds_cy: integer read fwidgetrect.cy write setbounds_cy + {default defaultwidgetheight} stored true; + property bounds_cxmin: integer read fminsize.cx + write setbounds_cxmin default 0; + property bounds_cymin: integer read fminsize.cy + write setbounds_cymin default 0; + property bounds_cxmax: integer read fmaxsize.cx + write setbounds_cxmax default 0; + property bounds_cymax: integer read fmaxsize.cy + write setbounds_cymax default 0; + + property left: integer read fwidgetrect.x write setbounds_x; + property right: integer read getright write setright; + //widgetrect.x + widgetrect.cx, sets cx if an_left is set + property top: integer read fwidgetrect.y write setbounds_y; + property bottom: integer read getbottom write setbottom; + //widgetrect.y + widgetrect.cy, sets cy if an_top is set + property width: integer read fwidgetrect.cx write setbounds_cx; + property height: integer read fwidgetrect.cy write setbounds_cy; + + procedure setclippedwidgetrect(arect: rectty); + //clips into parentwidget or workarea if no parentwidget + + property anchors: anchorsty read fanchors write setanchors + default defaultanchors; + property defaultfocuschild: twidget read getdefaultfocuschild + write setdefaultfocuschild; + + function framedim: sizety; //widgetrect.size - paintrect.size + function framedimnoscrollbar: sizety; + function clientframewidth: sizety; //widgetrect.size - clientrect.size + function innerclientframewidth: sizety; + //widgetrect.size - innerclientrect.size + function innerframewidth: sizety; + //clientrect.size - innerclientrect.size + function framerect: rectty; //origin = pos + function framepos: pointty; //origin = pos + property framesize: sizety read getframesize write setframesize; + //widget size - outer frame + property framewidth: integer read geframewidth write setframewidth; + property frameheight: integer read getframeheight write setframeheight; + function frameinnerrect: rectty; //origin = pos + + function paintrect: rectty; //origin = pos + function paintclientrect: rectty; //origin = clientrect + function paintpos: pointty; //origin = pos + property paintsize: sizety read getpaintsize write setpaintsize; + property paintwidth: integer read getpaintwidth write setpaintwidth; + property paintheight: integer read getpaintheight write setpaintheight; + function clippedpaintrect: rectty; //origin = pos, + //clipped by all parentpaintrects + function innerpaintrect: rectty; //origin = pos + + procedure setanchordwidgetsize(const asize: sizety); + //checks bottom-right anchors + function widgetsizerect: rectty; //pos = nullpoint + function paintsizerect: rectty; //pos = nullpoint + function clientsizerect: rectty; //pos = nullpoint + function containerclientsizerect: rectty; //pos = nullpoint + + property clientrect: rectty read getclientrect; //origin = paintrect.pos + procedure changeclientsize(const delta: sizety); //asynchronous + property clientsize: sizety read getclientsize write setclientsize; + property clientwidth: integer read getclientwidth write setclientwidth; + property clientheight: integer read getclientheight write setclientheight; + property clientpos: pointty read getclientpos; //origin = paintrect.pos; + function clientwidgetrect: rectty; //origin = pos + function clientwidgetpos: pointty; //origin = pos + function clientparentpos: pointty; //origin = parentwidget.pos + property parentclientpos: pointty read getparentclientpos + write setparentclientpos; + //origin = parentwidget.clientpos + function paintparentrect: rectty; //origin = parentwidget.pos + function paintparentpos: pointty; //origin = parentwidget.pos + function parentpaintpos: pointty; //origin = parentwidget.paintpos + //nullpoint if parent = nil + function refpos(const aorigin: originty): pointty; + + function paintrectparent: rectty; //origin = paintpos, + //nullrect if parent = nil, + function clientrectparent: rectty; //origin = paintpos, + //nullrect if parent = nil, + function innerparentrect: rectty; //origin = parentwidget.pos + function innerwidgetrect: rectty; //origin = pos + function innerclientrect: rectty; //origin = clientpos + function innerclientsize: sizety; + function innerclientpos: pointty; //origin = clientpos + function innerclientframe: framety; + function innerclientpaintpos: pointty; //origin = paintpos + function innerclientwidgetpos: pointty; //origin = pos + procedure innertopaintsize(var asize: sizety); + procedure outertopaintsize(var asize: sizety); + procedure painttowidgetsize(var asize: sizety); + procedure widgettopaintsize(var asize: sizety); + + property frame: tcustomframe read getframe write setframe; + property face: tcustomface read getface write setface; + + function getcanvas(aorigin: originty = org_client): tcanvas; + function showing: boolean; + //true if self and all ancestors visible and window allocated + function isenabled: boolean; + //true if self and all ancestors enabled + + function active: boolean; + function entered: boolean; + function activeentered: boolean; + //true if entered and window is regularactivewindow or inactivated + function activefocused(): boolean; + function focused: boolean; + function clicked: boolean; + + procedure changedirection(const avalue: graphicdirectionty; + var dest: graphicdirectionty); virtual; + procedure placexorder(const startx: integer; const dist: array of integer; + const awidgets: array of twidget; + const endmargin: integer = minint); + //origin = clientpos, endmargin by size adjust of widgets + //with [an_left,an_right], minint -> no change + procedure placeyorder(const starty: integer; const dist: array of integer; + const awidgets: array of twidget; + const endmargin: integer = minint); + //origin = clientpos, endmargin by size adjust of widgets + //with [an_top,an_bottom], minint -> no change + function alignx(const mode: widgetalignmodety; + const awidgets: array of twidget; + const glue: widgetalignmodety = wam_none; + const margin: integer = 0): integer; + //returns reference point, margin reference = clientrect + function aligny(const mode: widgetalignmodety; + const awidgets: array of twidget; + const glue: widgetalignmodety = wam_none; + const margin: integer = 0): integer; + //returns reference point, margin reference = clientrect + property optionswidget: optionswidgetty read foptionswidget + write setoptionswidget default defaultoptionswidget; + property optionswidget1: optionswidget1ty read foptionswidget1 + write setoptionswidget1 default defaultoptionswidget1; + property optionsskin: optionsskinty read foptionsskin + write setoptionsskin default []; + function actualcursor(const apos: pointty): cursorshapety; virtual; + //origin = pos + property cursor: cursorshapety read fcursor write setcursor + default cr_default; + property color: colorty read fcolor write setcolor + default defaultwidgetcolor; + property visible: boolean read getvisible write setvisible default true; + property enabled: boolean read getenabled write setenabled default true; + property taborder: integer read ftaborder write settaborder default 0; + property hint: msestring read gethint write sethint stored ishintstored; + property zorder: integer read getzorder write setzorder; + published + property onnavigrequest: navigrequesteventty read fonnavigrequest + write fonnavigrequest; + property skingroup: integer read fskingroup write fskingroup default 0; + property onbeforeupdateskin; + property onafterupdateskin; + end; + pwidget = ^twidget; + + windowstatety = (tws_posvalid,tws_sizevalid,tws_windowvisible, + tws_focusoutpending,tws_windowshowpending, + {tws_modal,}tws_modalfor,tws_modalcalling, + tws_needsdefaultpos, + tws_closing,tws_painting,tws_activating, + tws_globalshortcuts,tws_localshortcuts, + tws_buttonendmodal, + tws_grouphidden,tws_groupminimized,tws_groupmaximized, + tws_transientforminimized, + tws_grab,tws_activatelocked, + tws_canvasoverride,tws_destroying,tws_candefocus, + tws_raise,tws_lower); + windowstatesty = set of windowstatety; + + pmodalinfoty = ^modalinfoty; + modalinfoty = record + modalend: boolean; + modalwindowbefore: twindow; + level: integer; + parent: pmodalinfoty; + events: eventarty; //deferred events + end; + showinfoty = record + widget: twidget; + transientfor: twindow; + windowevent,nomodalforreset: boolean + end; + pshowinfoty = ^showinfoty; + + twindowevent = class(tmseevent) + private + public + fwinid: winidty; + constructor create(akind: eventkindty; winid: winidty); + end; + pwindowevent = ^twindowevent; + treparentevent = class(twindowevent) + public + fparent: winidty; + constructor create(akind: eventkindty; winid: winidty; + aparent: winidty); + end; + + twindow = class(teventobject,icanvas) + private + ffocuscount: longword; //for recursive setwidgetfocus + factivecount: longword; //for recursive activate,deactivate + factivating: integer; + ffocusing: integer; + fsizeerrorcount: integer; + fmoving: integer; + ffocusedwidget: twidget; + fenteredwidget: twidget; + fcaller: twidget; //used in twidget.doshortcut + fmodalinfopo: pmodalinfoty; + foptions: windowoptionsty; + ftransientfor: twindow; + ftransientforcount: integer; + fwindowpos: windowposty; + fwindowposbefore: windowposty; + fnormalwindowrect: rectty; + fcaption: msestring; + fscrollnotifylist: tnotifylist; + fsyscontainer: syswindowty; + fmodalwidget: twidget; + fmodallevel: integer; + fsysdragobject: tobject; //tsysmimedragobject; + + fopacity: realty; + procedure setcaption(const avalue: msestring); + procedure widgetdestroyed(widget: twidget); + + procedure showed; + procedure hidden; + procedure activated; + procedure deactivated; + procedure wmconfigured(const arect: rectty; const aorigin: pointty); + procedure windowdestroyed; + + function internalupdate: boolean; + //updates screen representation, false if nothing is painted + procedure deactivate; + function canactivate: boolean; + //icanvas + procedure gcneeded(const sender: tcanvas); +// function getmonochrome: boolean; + function getkind: bitmapkindty; + function getsize: sizety; + procedure getcanvasimage(const bgr: boolean; var aimage: maskedimagety); + + procedure checkrecursivetransientfor(const value: twindow); + procedure settransientfor(const Value: twindow; const windowevent: boolean); + procedure sizeconstraintschanged; + procedure setsizeconstraints(const amin,amax: sizety); + procedure createwindow; + procedure checkwindowid; + procedure checkwindow(windowevent: boolean); + procedure doshortcut(var info: keyeventinfoty; const sender: twidget); virtual; + //nil if from application + procedure show(windowevent: boolean); + procedure hide(windowevent: boolean); + procedure setfocusedwidget(const widget: twidget); + procedure setmodalresult(const Value: modalresultty); + function getglobalshortcuts: boolean; + function getlocalshortcuts: boolean; + procedure setglobalshortcuts(const Value: boolean); + procedure setlocalshortcuts(const Value: boolean); + function getbuttonendmodal: boolean; + procedure setbuttonendmodal(const value: boolean); + + function getdecoratedwidgetrect: rectty; + procedure setdecoratedwidgetrect(const avalue: rectty); + function getdecoratedpos: pointty; + procedure setdecoratedpos(const avalue: pointty); + function getdecoratedsize: sizety; + procedure setdecoratedsize(const avalue: sizety); + function getdecoratedbounds_x: integer; + procedure setdecoratedbounds_x(const avalue: integer); + function getdecoratedbounds_y: integer; + procedure setdecoratedbounds_y(const avalue: integer); + function getdecoratedbounds_cx: integer; + procedure setdecoratedbounds_cx(const avalue: integer); + function getdecoratedbounds_cy: integer; + procedure setdecoratedbounds_cy(const avalue: integer); + procedure setcontainer(const avalue: winidty); + procedure containerwindestroyed(const aid: winidty); + procedure setsyscontainer(const avalue: syswindowty); + function getscreenpos: pointty; + procedure setscreenpos(const avalue: pointty); + function getmodalfor: boolean; + procedure setopacity(const avalue: realty); + protected + fstate: windowstatesty; + fgdi: pgdifunctionaty; + fwindow: windowty; + fcontainer: winidty; + fownerwidget: twidget; + fcanvas: tcanvas; + fasynccanvas: tcanvas; + fmodalresult: modalresultty; + fupdateregion: gdiregionty; + procedure setasynccanvas(const acanvas: tcanvas); + //used from treport + procedure releaseasynccanvas; + procedure processsysdnd(const event: twindowevent); //tsysdndevent + + function getwindowsize: windowsizety; + procedure setwindowsize(const value: windowsizety); + function getwindowpos: windowposty; + procedure setwindowpos(const Value: windowposty); + procedure invalidaterect(const arect: rectty; const sender: twidget = nil); + //clipped by paintrect of sender.parentwidget + procedure mouseparked; + procedure movewindowrect(const dist: pointty; const rect: rectty); virtual; + procedure checkmousewidget(const info: mouseeventinfoty; + var capture: twidget); + procedure dispatchmouseevent(var info: moeventinfoty; + capture: twidget); virtual; + procedure dispatchkeyevent(const eventkind: eventkindty; + var info: keyeventinfoty); virtual; + procedure sizechanged; virtual; + procedure poschanged; virtual; + procedure internalactivate(const windowevent: boolean; + const force: boolean = false); + procedure noactivewidget; + procedure lockactivate; + procedure unlockactivate; + procedure setzorder(const value: integer); + function topmodaltransientfor: twindow; + function beginmodal(const showinfo: pshowinfoty): boolean; overload; + //true if window destroyed + public + constructor create(const aowner: twidget; const agdi: pgdifunctionaty = nil); + //nil = platform default + destructor destroy; override; + procedure destroywindow; + procedure recreatewindow(); + procedure registeronscroll(const method: notifyeventty); + procedure unregisteronscroll(const method: notifyeventty); + + function beginmodal: boolean; overload;//true if window destroyed + procedure endmodal; + function modal: boolean; + function modalwindowbefore: twindow; + function transientforstackactive: boolean; + //true if the window is member of the active transient for stack + procedure activate(const force: boolean = false); + function active: boolean; + function deactivateintermediate: boolean; + //true if ok, sets app.finactivewindow + procedure reactivate(const force: boolean = false); + //clears app.finactivewindow + procedure update; + function candefocus: boolean; + procedure nofocus; + property focuscount: longword read ffocuscount; + function close: boolean; overload; //true if ok + function close(const amodalresult: modalresultty): boolean; + overload;//true if ok + procedure beginmoving; //lock window rect modification + procedure endmoving; + procedure bringtofront; + procedure bringtofrontlocal; + procedure sendtoback; + procedure sendtobacklocal; + procedure stackunder(const predecessor: twindow); + //stacking is performed in mainloop idle, nil means top + procedure stackover(const predecessor: twindow); + //stacking is performed in mainloop idle, nil means bottom + function stackedunder(const avisible: boolean = false): twindow; //nil if top + function stackedover(const avisible: boolean = false): twindow; + //nil if bottom + function hastransientfor: boolean; + function istransientfor(const base: twindow): boolean; + //base can be nil + function defaulttransientfor: twindow; + + function capturemouse: boolean; //true for new grab + procedure releasemouse; + function mousecaptured: boolean; + + procedure postkeyevent(const akey: keyty; + const ashiftstate: shiftstatesty = []; const release: boolean = false; + const achars: msestring = ''); + + function winid: winidty; + function haswinid: boolean; + function state: windowstatesty; + function visible: boolean; + function activating: boolean; //in internalactivate proc + function normalwindowrect: rectty; + property updateregion: regionty read fupdateregion.region; + function updaterect: rectty; + + procedure registermovenotification(sender: iobjectlink); + procedure unregistermovenotification(sender: iobjectlink); + + property options: windowoptionsty read foptions; + function ispopup: boolean; {$ifdef FPC}inline;{$endif} + property owner: twidget read fownerwidget; + property focusedwidget: twidget read ffocusedwidget; + function firstfocuswidget(): twidget; + function lastfocuswidget(): twidget; + property transientfor: twindow read ftransientfor; + property modalfor: boolean read getmodalfor; + property modalresult: modalresultty read fmodalresult write setmodalresult; + property buttonendmodal: boolean read getbuttonendmodal write setbuttonendmodal; + property globalshortcuts: boolean read getglobalshortcuts write setglobalshortcuts; + property localshortcuts: boolean read getlocalshortcuts write setlocalshortcuts; + property windowpos: windowposty read getwindowpos write setwindowpos; + property caption: msestring read fcaption write setcaption; + property container: winidty read fcontainer + write setcontainer default 0; + property syscontainer: syswindowty read fsyscontainer + write setsyscontainer default sywi_none; + + property screenpos: pointty read getscreenpos write setscreenpos; + property decoratedwidgetrect: rectty read getdecoratedwidgetrect + write setdecoratedwidgetrect; + property decoratedpos: pointty read getdecoratedpos + write setdecoratedpos; + property decoratedsize: sizety read getdecoratedsize + write setdecoratedsize; + property decoratedbounds_x: integer read getdecoratedbounds_x + write setdecoratedbounds_x; + property decoratedbounds_y: integer read getdecoratedbounds_y + write setdecoratedbounds_y; + property decoratedbounds_cx: integer read getdecoratedbounds_cx + write setdecoratedbounds_cx; + property decoratedbounds_cy: integer read getdecoratedbounds_cy + write setdecoratedbounds_cy; + property opacity: realty read fopacity write setopacity; + //default emptyreal -> undefined + end; + + windowarty = array of twindow; + pwindowarty = ^windowarty; + windowaty = array[0..0] of twindow; + pwindowaty = ^windowaty; + + windowchangeeventty = procedure(const oldwindow,newwindow: twindow) of object; + widgetchangeeventty = procedure(const oldwidget,newwidget: twidget) of object; + windoweventty = procedure(const awindow: twindow) of object; + winideventty = procedure(const awinid: winidty) of object; + booleaneventty = procedure(const avalue: boolean) of object; + + twindowrectevent = class(twindowevent) + private + public + frect: rectty; + forigin: pointty; + constructor create(akind: eventkindty; winid: winidty; + const rect: rectty; const aorigin: pointty); + end; + + tmouseevent = class(twindowevent) + private + ftimestamp: longword; + public + fpos: pointty; + fbutton: mousebuttonty; + fwheel: mousewheelty; + fshiftstate: shiftstatesty; + freflected: boolean; + property timestamp: longword read ftimestamp; //usec, 0 -> invalid + constructor create(const winid: winidty; const release: boolean; + const button: mousebuttonty; const wheel: mousewheelty; + const pos: pointty; const shiftstate: shiftstatesty; + atimestamp: longword; const reflected: boolean = false); + //button = none for mousemove + end; + + tmouseenterevent = class(tmouseevent) + public + constructor create(const winid: winidty; const pos: pointty; + const shiftstate: shiftstatesty; atimestamp: longword); + end; + + tkeyevent = class(twindowevent) + private + ftimestamp: longword; + public + fkey: keyty; + fkeynomod: keyty; + fchars: msestring; + fbutton: mousebuttonty; + fshiftstate: shiftstatesty; + fposted: boolean; + constructor create(const winid: winidty; const release: boolean; + const key,keynomod: keyty; const shiftstate: shiftstatesty; + const chars: msestring; const atimestamp: longword; + const posted: boolean = false); + //do not dispatch if active window is not winid + property timestamp: longword read ftimestamp; //usec + end; + + tresizeevent = class(tobjectevent) + public + size: sizety; + constructor create(const dest: ievent; const asize: sizety); + end; + + tguiapplication = class; + waitidleeventty = procedure(const sender: tguiapplication; var again: boolean) + of object; + helpeventty = procedure(const sender: tmsecomponent; + var handled: boolean) of object; + + syseventhandlereventty = procedure(const awindow: winidty; + var aevent: syseventty; var handled: boolean) of object; + + keyinfoty = record + key: keyty; + keynomod: keyty; + shiftstate: shiftstatesty; + end; + + guiappoptionty = (gao_forcezorder); + guiappoptionsty = set of guiappoptionty; + + keyinfoarty = array of keyinfoty; + tguiapplication = class(tcustomapplication) + private + fwindows: windowarty; + fwindowupdateindex: integer; + fgroupzorder: windowarty; + factivewindow: twindow; + flastactivewindow: twindow; + fwantedactivewindow: twindow; //set by twindow.activate if modal + finactivewindow: twindow; + ffocuslockwindow: twindow; + ffocuslocktransientfor: twindow; + fmouse: tmouse; + fcaret: tcaret; + fmousecapturewidget: twidget; + fmousewidget: twidget; + fmousewidgetpos: pointty; //last mousepos sent to widget + fmousehintwidget: twidget; + fkeyboardcapturewidget: twidget; + fclientmousewidget: twidget; + fhintedwidget: twidget; + fhintedid: int32; + fhintforwidget: twidget; + fhintinfo: hintinfoty; + fmainwindow: twindow; + fdblclicktime: integer; + fcursorshape: cursorshapety; + fwidgetcursorshape: cursorshapety; + fbuttonpresswidgetbefore: twidget; + fbuttonreleasewidgetbefore: twidget; + factmousewindow: twindow; + fdelayedmouseshift: pointty; + fmodalwindowbeforewaitdialog: twindow; + fonterminatebefore: threadcompeventty; + fexecuteaction: notifyeventty; + fidleaction: waitidleeventty; + feventlooping: integer; + fkeyhistory: keyinfoarty; + flastshiftstate: shiftstatesty; + flastkey: keyty; + flastbutton: mousebuttonty; + fkeyeventinfo: pkeyeventinfoty; + fmouseeventinfo: pmouseeventinfoty; + fmousewheeleventinfo: pmousewheeleventinfoty; + + fmousewheelfrequmin: real; + fmousewheelfrequmax: real; + fmousewheeldeltamin: real; + fmousewheeldeltamax: real; + fmousewheelaccelerationmax: real; + flastinputtimestamp: longword; + flastmousewheeltimestamp: longword; + flastmousewheeltimestampbefore: longword; + + fcurrmodalinfo: pmodalinfoty; + flooplevel: integer; + + fmousewheelsensitivity: real; + fhintwidgetclass: widgetclassty; + procedure invalidated; + function grabpointer(const aid: winidty): boolean; + function ungrabpointer: boolean; + procedure setmousewidget(const widget: twidget); + procedure setclientmousewidget(const widget: twidget; const apos: pointty); + procedure capturemouse(const sender: twidget; const grab: boolean); + //sender = nil for release + procedure activatehint; + procedure deactivatehint; + procedure hinttimer(const sender: tobject); + procedure internalshowhint(const sender: twidget; + const ahintwidget: twidget); + procedure setmainwindow(const Value: twindow); + procedure setcursorshape(const avalue: cursorshapety); + procedure setwidgetcursorshape(const avalue: cursorshapety); + function getwindows(const index: integer): twindow; + procedure dothreadterminated(const sender: tthreadcomp); + procedure dowaitidle(var again: boolean); + procedure dowaitidle1(var again: boolean); + function getforcezorder: boolean; + procedure setforcezorder(const avalue: boolean); + protected + flastshowmenuwidget: twidget; + foptionsgui: guiappoptionsty; + fgdilockcount: int32; + procedure sysevent(const awindow: winidty; var aevent: syseventty; + var handled: boolean); + procedure sethighrestimer(const avalue: boolean); override; + procedure dopostevent(const aevent: tmseevent); override; + procedure eventloop(const once: boolean = false); + //used in win32 wm_queryendsession and wm_entersizemove + procedure exitloop; //used in win32 cancelshutdown + procedure receiveevent(const event: tobjectevent); override; + procedure doafterrun; override; + procedure internalinitialize; override; + procedure internaldeinitialize; override; +// procedure dobeginthreadlock; override; +// procedure doendthreadlock; override; + procedure objecteventdestroyed(const sender: tobjectevent); override; + procedure dragstarted; //calls dragstarted of all known widgets + procedure internalpackwindowzorder(); virtual; + procedure zorderinvalid(); + public + constructor create(aowner: tcomponent); override; + procedure destroyforms; + property optionsgui: guiappoptionsty read foptionsgui + write foptionsgui default []; + property forcezorder: boolean read getforcezorder write setforcezorder; + procedure langchanged; override; + procedure settimer(const us: integer); override; + function findwindow(aid: winidty; out window: twindow): boolean; + procedure checkwindowrect(winid: winidty; var rect: rectty); + //callback from win32 wm_sizing + + function createform(instanceclass: widgetclassty; var reference): twidget; + procedure invalidate; //invalidates all registered forms + procedure processmessages; override; //handle with care! + function idle: boolean; override; + function modallevel: integer; override; + + function unlockall: integer override; + procedure relockall(count: integer) override; + procedure beginnoignorewaitevents; + procedure endnoignorewaitevents; + procedure beginwait(const aprocessmessages: boolean = false); override; + procedure endwait; override; + function waiting: boolean; + function waitescaped: boolean; override; + //true if escape pressed while waiting + + procedure resetwaitdialog; + function waitdialog(const athread: tthreadcomp = nil; const atext: msestring = ''; + const caption: msestring = ''; + const acancelaction: notifyeventty = nil; + const aexecuteaction: notifyeventty = nil; + const aidleaction: waitidleeventty = nil; + const acontinueaction: notifyeventty = nil): boolean; + //true if not canceled + procedure terminatewait; + procedure cancelwait; + function waitstarted: boolean; + function waitcanceled: boolean; + function waitterminated: boolean; + + procedure showexception(e: exception; const leadingtext: msestring = ''); override; + procedure showasyncexception(e: exception; const leadingtext: msestring = ''); + //messege posted in queue + procedure errormessage(const amessage: msestring); override; + + property hintwidgetclass: widgetclassty read fhintwidgetclass + write fhintwidgetclass; + procedure inithintinfo(var info: hintinfoty; const ahintedwidget: twidget); + //hint at mousepos + procedure initwidgethintinfo(var info: hintinfoty; + const ahintedwidget: twidget); + //hint at widgetrect + procedure showhint(const sender: twidget; const hint: msestring; + const aposrect: rectty; const aplacement: captionposty = cp_bottomleft; + const ashowtime: integer = defaulthintshowtime; //0 -> inifinite, + // -1 defaultshowtime if ow_timedhint in sender.optionswidget + const aflags: hintflagsty = defaulthintflags); + procedure showhint(const sender: twidget; const hint: msestring; + const apos: pointty; + const ashowtime: integer = defaulthintshowtime; //0 -> inifinite, + // -1 defaultshowtime if ow_timedhint in sender.optionswidget + const aflags: hintflagsty = defaulthintflags); + procedure showhint(const sender: twidget; const info: hintinfoty); + procedure showhint(const sender: twidget; const hint: msestring); + procedure showhint(const sender: twidget; const hintwidget: twidget; + const ashowtime: integer = defaulthintshowtime; //0 -> inifinite, + // -1 defaultshowtime if ow_timedhint in sender.optionswidget + const aflags: hintflagsty = defaulthintflags); + procedure hidehint; + procedure restarthint(const sender: twidget); + function hintedwidget: twidget; //last hinted widget + function activehintedwidget: twidget; //nil if no hint active + + procedure help(const sender: tmsecomponent); + procedure registerhelphandler(const ahandler: helpeventty); + procedure unregisterhelphandler(const ahandler: helpeventty); + function activehelpcontext: msestring; + //returns helpcontext of active widget, '' if none; + function mousehelpcontext: msestring; + //returns helpcontext of mouse widget, '' if none; + + function active: boolean; + procedure activate(); + function screenrect(const awindow: twindow = nil): rectty; + //nil -> virtualscreeen + function workarea(const awindow: twindow = nil): rectty; + //nil -> current active window + function ppmm(const awindow: twindow = nil): complexty; + //nil -> current active window, pixel per mm, + //result.re -> horizontal + //result.im -> vertical + property activewindow: twindow read factivewindow; + property lastactivewindow: twindow read flastactivewindow; + property inactivewindow: twindow read finactivewindow; + function normalactivewindow: twindow; + //active window or active window after closing modal stack if defined + function regularactivewindow: twindow; //first no transientfor window + function unreleasedactivewindow: twindow; + function activewidget: twidget; + function activerootwidget: twidget; + property lastshowmenuwidget: twidget read flastshowmenuwidget; + + function windowatpos(const pos: pointty): twindow; + function findwidget(const namepath: string; out awidget: twidget): boolean; + //false if invalid namepath, '' -> nil and true + procedure sortzorder(); + //window list is ordered by z, bottom first, top last, + //invisibles first + procedure packwindowzorder(); + + function windowar: windowarty; + function winidar: winidarty; + function windowcount: integer; + property windows[const index: integer]: twindow read getwindows; + function bottomwindow: twindow; + //lowest visible window in stackorder, calls sortzorder + function topwindow: twindow; + //highest visible window in stackorder, calls sortzorder + function candefocus(const caller: tobject = nil): boolean; override; + //checks candefocus of all windows expect caller + + procedure registeronkeypress(const method: keyeventty); + procedure unregisteronkeypress(const method: keyeventty); + procedure registeronshortcut(const method: keyeventty); + procedure unregisteronshortcut(const method: keyeventty); + procedure registeronwidgetactivechanged(const method: widgetchangeeventty); + procedure unregisteronwidgetactivechanged(const method: widgetchangeeventty); + procedure registeronwindowactivechanged(const method: windowchangeeventty); + procedure unregisteronwindowactivechanged(const method: windowchangeeventty); + procedure registeronwindowdestroyed(const method: windoweventty); + procedure unregisteronwindowdestroyed(const method: windoweventty); + procedure registeronwiniddestroyed(const method: winideventty); + procedure unregisteronwiniddestroyed(const method: winideventty); + procedure registeronapplicationactivechanged(const method: booleaneventty); + procedure unregisteronapplicationactivechanged(const method: booleaneventty); + procedure registersyseventhandler(const method: syseventhandlereventty); + procedure unregistersyseventhandler(const method: syseventhandlereventty); + + function terminate(const sender: twindow = nil): boolean; + //calls canclose of all windows except sender and terminatequery + //true if terminated + function terminating: boolean; + function deinitializing: boolean; + function shortcutting: boolean; //widget is in doshortcut procedure + property caret: tcaret read fcaret; + property mouse: tmouse read fmouse; + procedure mouseparkevent; //simulates mouseparkevent + procedure delayedmouseshift(const ashift: pointty); + procedure calcmousewheeldelta(var info: mousewheeleventinfoty; + const fmin,fmax,deltamin,deltamax: real); + function mousewheelacceleration(const avalue: real): real; overload; + function mousewheelacceleration(const avalue: integer): integer; overload; + procedure clearkeyhistory; //called by matching shortcut sequence + property keyhistory: keyinfoarty read fkeyhistory; + //does not contain modifier keys + property lastinputtimestamp: longword read flastinputtimestamp; + //microseconds + property lastshiftstate: shiftstatesty read flastshiftstate; + property lastkey: keyty read flastkey; + property lastbutton: mousebuttonty read flastbutton; + property mouseeventinfo: pmouseeventinfoty read fmouseeventinfo; + //nil if no mouse event processing + property mousewheeleventinfo: pmousewheeleventinfoty + read fmousewheeleventinfo; + //nil if no mousewheel event processing + property keyeventinfo: pkeyeventinfoty read fkeyeventinfo; + //nil if no key event processing + + property cursorshape: cursorshapety read fcursorshape write setcursorshape; + //persistent + property widgetcursorshape: cursorshapety read fwidgetcursorshape write + setwidgetcursorshape; + //removed by mouse widget change + procedure updatecursorshape; //restores cursorshape of mousewidget + property mousewidget: twidget read fmousewidget; + property clientmousewidget: twidget read fclientmousewidget; + property mousecapturewidget: twidget read fmousecapturewidget; + property keyboardcapturewidget: twidget read fkeyboardcapturewidget; + property mainwindow: twindow read fmainwindow write setmainwindow; + property thread: threadty read fthread; + + property buttonpresswidgetbefore: twidget read fbuttonpresswidgetbefore; + property buttonreleasewidgetbefore: twidget read fbuttonreleasewidgetbefore; + property dblclicktime: integer read fdblclicktime write fdblclicktime default + defaultdblclicktime; //us + property mousewheelsensitivity: real read fmousewheelsensitivity + write fmousewheelsensitivity; + property mousewheelfrequmin: real read fmousewheelfrequmin + write fmousewheelfrequmin; + property mousewheelfrequmax: real read fmousewheelfrequmax + write fmousewheelfrequmax; + property mousewheeldeltamin: real read fmousewheeldeltamin + write fmousewheeldeltamin; + property mousewheeldeltamax: real read fmousewheeldeltamax + write fmousewheeldeltamax; + property mousewheelaccelerationmax: real read fmousewheelaccelerationmax + write fmousewheelaccelerationmax; + end; + +function translatewidgetpoint(const point: pointty; + const source,dest: twidget): pointty; +procedure translatewidgetpoint1(var point: pointty; + const source,dest: twidget); +function translatewidgetrect(const rect: rectty; + const source,dest: twidget): rectty; + //translates from source widget to dest widget, to screen if dest = nil + //source = nil -> screen +function translatepaintpoint(const point: pointty; + const source,dest: twidget): pointty; +procedure translatepaintpoint1(var point: pointty; + const source,dest: twidget); +function translatepaintrect(const rect: rectty; + const source,dest: twidget): rectty; + //translates from source widget to dest widget, to screen if dest = nil + //source = nil -> screen +function translatewidgettopaintpoint(const point: pointty; + const source,dest: twidget): pointty; +procedure translatewidgettopaintpoint1(var point: pointty; + const source,dest: twidget); +function translatewidgettopaintrect(const rect: rectty; + const source,dest: twidget): rectty; + //translates from source widget to dest widget, to screen if dest = nil + //source = nil -> screen +function translateclientpoint(const point: pointty; + const source,dest: twidget): pointty; +procedure translateclientpoint1(var point: pointty; + const source,dest: twidget); +function translateclientrect(const rect: rectty; + const source,dest: twidget): rectty; + //translates from source client to dest client, to screen if dest = nil + //source = nil -> screen + +procedure sortwidgetsxorder(var awidgets: widgetarty; const parent: twidget = nil); +procedure sortwidgetsyorder(var awidgets: widgetarty; const parent: twidget = nil); + +procedure syncmaxautosize(const widgets: array of twidget); + //checks osk_nolayoutcx, osk_nolayoutcy +procedure syncpaintwidth(const awidgets: array of twidget; + const awidgetwidth: integer = -1); + //biggest if < 0 + //synchronizes paintwidth with paintwidth of largest outer framewidth + //(ex. largest caption) +procedure syncpaintheight(const awidgets: array of twidget; + const awidgetheight: integer = -1); + //biggest if < 0 + //synchronizes paintheight with paintheight of largest outer framewidth + //(ex. largest caption) + +function checkshortcut(var info: keyeventinfoty; + const caption: msestring; const checkalt: boolean): boolean; overload; +function checkshortcut(var info: keyeventinfoty; + const key: keyty; const shiftstate: shiftstatesty): boolean; overload; + +type + getwidgetintegerty = function(const awidget: twidget): integer; + getwidgetbooleanty = function(const awidget: twidget): boolean; + setwidgetintegerty = procedure(const awidget: twidget; const avalue: integer); + widgetaccessty = record + pos,size,stop,min,max,opos,osize,ostop,omin,omax: getwidgetintegerty; + setpos,setsize,setanchordsize,setstop,setmin,setmax, + setopos,setosize,setostop,setomin,setomax: setwidgetintegerty; + anchstop,oanchstop,anchboth,oanchboth: getwidgetbooleanty; + end; + pwidgetaccessty = ^widgetaccessty; + +function wbounds_x(const awidget: twidget): integer; +procedure wsetbounds_x(const awidget: twidget; const avalue: integer); +function wbounds_y(const awidget: twidget): integer; +procedure wsetbounds_y(const awidget: twidget; const avalue: integer); +function wbounds_cx(const awidget: twidget): integer; +procedure wsetbounds_cx(const awidget: twidget; const avalue: integer); +procedure wsetanchord_cx(const awidget: twidget; const avalue: integer); +function wbounds_cy(const awidget: twidget): integer; +procedure wsetbounds_cy(const awidget: twidget; const avalue: integer); +procedure wsetanchord_cy(const awidget: twidget; const avalue: integer); +function wstopx(const awidget: twidget): integer; +procedure wsetstopx(const awidget: twidget; const avalue: integer); +function wstopy(const awidget: twidget): integer; +procedure wsetstopy(const awidget: twidget; const avalue: integer); +function wanchstopx(const awidget: twidget): boolean; +function wanchstopy(const awidget: twidget): boolean; +function wanchbothx(const awidget: twidget): boolean; +function wanchbothy(const awidget: twidget): boolean; + +function wbounds_cxmin(const awidget: twidget): integer; +procedure wsetbounds_cxmin(const awidget: twidget; const avalue: integer); +function wbounds_cymin(const awidget: twidget): integer; +procedure wsetbounds_cymin(const awidget: twidget; const avalue: integer); +function wbounds_cxmax(const awidget: twidget): integer; +procedure wsetbounds_cxmax(const awidget: twidget; const avalue: integer); +function wbounds_cymax(const awidget: twidget): integer; +procedure wsetbounds_cymax(const awidget: twidget; const avalue: integer); + +const + widgetaccessx: widgetaccessty = ( + pos: {$ifdef FPC}@{$endif}wbounds_x; + size: {$ifdef FPC}@{$endif}wbounds_cx; + stop: {$ifdef FPC}@{$endif}wstopx; + min: {$ifdef FPC}@{$endif}wbounds_cxmin; + max: {$ifdef FPC}@{$endif}wbounds_cxmax; + opos: {$ifdef FPC}@{$endif}wbounds_y; + osize: {$ifdef FPC}@{$endif}wbounds_cy; + ostop: {$ifdef FPC}@{$endif}wstopy; + omin: {$ifdef FPC}@{$endif}wbounds_cymin; + omax: {$ifdef FPC}@{$endif}wbounds_cymax; + setpos: {$ifdef FPC}@{$endif}wsetbounds_x; + setsize: {$ifdef FPC}@{$endif}wsetbounds_cx; + setanchordsize: {$ifdef FPC}@{$endif}wsetanchord_cx; + setstop: {$ifdef FPC}@{$endif}wsetstopx; + setmin: {$ifdef FPC}@{$endif}wsetbounds_cxmin; + setmax: {$ifdef FPC}@{$endif}wsetbounds_cxmax; + setopos: {$ifdef FPC}@{$endif}wsetbounds_y; + setosize: {$ifdef FPC}@{$endif}wsetbounds_cy; + setostop: {$ifdef FPC}@{$endif}wsetstopy; + setomin: {$ifdef FPC}@{$endif}wsetbounds_cymin; + setomax: {$ifdef FPC}@{$endif}wsetbounds_cymax; + anchstop: {$ifdef FPC}@{$endif}wanchstopx; + oanchstop: {$ifdef FPC}@{$endif}wanchstopy; + anchboth: {$ifdef FPC}@{$endif}wanchbothx; + oanchboth: {$ifdef FPC}@{$endif}wanchbothy; + ); + widgetaccessy: widgetaccessty = ( + pos: {$ifdef FPC}@{$endif}wbounds_y; + size: {$ifdef FPC}@{$endif}wbounds_cy; + stop: {$ifdef FPC}@{$endif}wstopy; + min: {$ifdef FPC}@{$endif}wbounds_cymin; + max: {$ifdef FPC}@{$endif}wbounds_cymax; + opos: {$ifdef FPC}@{$endif}wbounds_x; + osize: {$ifdef FPC}@{$endif}wbounds_cx; + ostop: {$ifdef FPC}@{$endif}wstopx; + omin: {$ifdef FPC}@{$endif}wbounds_cxmin; + omax: {$ifdef FPC}@{$endif}wbounds_cxmax; + setpos: {$ifdef FPC}@{$endif}wsetbounds_y; + setsize: {$ifdef FPC}@{$endif}wsetbounds_cy; + setanchordsize: {$ifdef FPC}@{$endif}wsetanchord_cy; + setstop: {$ifdef FPC}@{$endif}wsetstopy; + setmin: {$ifdef FPC}@{$endif}wsetbounds_cymin; + setmax: {$ifdef FPC}@{$endif}wsetbounds_cymax; + setopos: {$ifdef FPC}@{$endif}wsetbounds_x; + setosize: {$ifdef FPC}@{$endif}wsetbounds_cx; + setostop: {$ifdef FPC}@{$endif}wsetstopx; + setomin: {$ifdef FPC}@{$endif}wsetbounds_cxmin; + setomax: {$ifdef FPC}@{$endif}wsetbounds_cxmax; + anchstop: {$ifdef FPC}@{$endif}wanchstopy; + oanchstop: {$ifdef FPC}@{$endif}wanchstopx; + anchboth: {$ifdef FPC}@{$endif}wanchbothy; + oanchboth: {$ifdef FPC}@{$endif}wanchbothx; + ); + +function application: tguiapplication; +function mousebuttontoshiftstate(button: mousebuttonty): shiftstatesty; +function isenterkey(const awidget: twidget; const key: keyty): boolean; +function isdblclick(const ainfo: mouseeventinfoty; + const abutton: mousebuttonty = mb_left): boolean; +function eatdblclick(var ainfo: mouseeventinfoty; + const abutton: mousebuttonty = mb_left): boolean; +function simulatemodalresult(const awidget: twidget; + const amodres: modalresultty): boolean; + +procedure beep; +procedure guibeep; +procedure enablewidgets(awidgets: array of twidget); +procedure disablewidgets(awidgets: array of twidget); +procedure showwidgets(awidgets: array of twidget); +procedure hidewidgets(awidgets: array of twidget); +function showmodalwidget(const aclass: widgetclassty): modalresultty; + +function getiassistiveclient(const awidget: twidget): iassistiveclient; + +procedure writewidgetnames(const writer: twriter; const ar: widgetarty); +function needswidgetnamewriting(const ar: widgetarty): boolean; overload; +function needswidgetnamewriting(const ar1,ar2: widgetarty): boolean; overload; + +procedure designeventloop; + +function getprocesswindow(const procid: integer): winidty; +function activateprocesswindow(const procid: integer; + const araise: boolean = true): boolean; + //true if ok +function combineframestateflags(const disabled,focused,active, + mouse,clicked: boolean): framestateflagsty; +function combineframestateflags( + const astate: shapestatesty): framestateflagsty; + +{$ifdef mse_debug} +procedure debugwindow(const atext: string; const awindow: twindow); +procedure debugwindow(const atext: string; const aid: winidty); +function debugwindow1(const atext: string; const aid: winidty): string; +procedure debugwindow(const atext: string; const aid1,aid2: winidty); +function checkwindowname(const aid: winidty; const aname: string): boolean; +function debugwidgetname(const awidget: twidget; const atext: string): string; +{$endif} + +implementation +uses + msesysintf,typinfo,msestreaming,msetimer,msebits,msewidgets, + mseshapes,msestockobjects,msefileutils,msedatalist,Math,msesysutils, + rtlconsts,{$ifndef FPC}classes_del,{$endif}mseformatstr, + mseprocutils,msesys,msesysdnd,mseassistiveserver; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + faceoptionsmask1: faceoptionsty = [fao_alphafadeimage,fao_alphafadenochildren, + fao_alphafadeall]; + faceoptionsmask2: faceoptionsty = [fao_alphaimage,fao_alphafadeimage]; +type + tcanvas1 = class(tcanvas); + tfadecolorarrayprop1 = class(tfadecolorarrayprop); + trealarrayprop1 = class(trealarrayprop); + tcaret1 = class(tcaret); + tobjectevent1 = class(tobjectevent); + tsysmimedragobject1 = class(tsysmimedragobject); + timagelist1 = class(timagelist); + +const + cancelwaittag = 823757; +type + tasyncmessageevent = class(tuserevent) + private + fmessage: msestring; + fcaption: msestring; + public + constructor create(const amessage: msestring; const acaption: msestring); + end; + + twidgetshowevent = class(tsynchronizeevent) + private + fwidget: twidget; + fmodalresult: modalresultty; + fmodallevel: modallevelty; + ftransientfor: twindow; + protected + procedure execute; override; + end; + + tcreatewindowevent = class(tsynchronizeevent) + private + fsender: twindow; + frect: rectty; + foptionspo: pinternalwindowoptionsty; + fwindowpo: pwindowty; + protected + procedure execute; override; + end; + + tdestroywindowevent = class(tsynchronizeevent) + private + fwindowpo: pwindowty; + protected + procedure execute; override; + end; + + tonkeyeventlist = class(tmethodlist) + protected + procedure dokeyevent(const sender: twidget; var info: keyeventinfoty); + end; + + tonwidgetchangelist = class(tmethodlist) + protected + procedure dowidgetchange(const oldwidget,newwidget: twidget); + end; + + tonwindowchangelist = class(tmethodlist) + protected + procedure dowindowchange(const oldwindow,newwindow: twindow); + end; + + tonwindoweventlist = class(tmethodlist) + protected + procedure doevent(const awindow: twindow); + end; + + tonwinideventlist = class(tmethodlist) + protected + procedure doevent(const awinid: winidty); + end; + + tonapplicationactivechangedlist = class(tmethodlist) + protected + procedure doevent(const activated: boolean); + end; + + tonhelpeventlist = class(tmethodlist) + protected + procedure doevent(const sender: tmsecomponent); + end; + + tonsyseventlist = class(tmethodlist) + protected + procedure doevent(const awindow: winidty; var aevent: syseventty; + var handled: boolean); + end; + + windowstackinfoty = record + lower,upper: twindow; + level: integer; + recursion: boolean; + end; + windowstackinfoarty = array of windowstackinfoty; + +const + keyhistorylen = 10; + +type + tinternalapplication = class(tguiapplication,imouse) + //avoid circular interface references + private + fonkeypresslist: tonkeyeventlist; + fonshortcutlist: tonkeyeventlist; + fonwidgetactivechangelist: tonwidgetchangelist; + fonwindowactivechangelist: tonwindowchangelist; + fonwindowdestroyedlist: tonwindoweventlist; + fonwiniddestroyedlist: tonwinideventlist; + fonapplicationactivechangedlist: tonapplicationactivechangedlist; + fonhelp: tonhelpeventlist; + fonsyseventlist: tonsyseventlist; + + fcaretwidget: twidget; + fmousewinid: winidty; + fdesigning: boolean; + fmodalwindow: twindow; + flockupdatewindowstack: twindow; + fhintwidget: twidget;//thintwidget; + fhinttimer: tsimpletimer; + fmouseparktimer: tsimpletimer; + fmouseparkeventinfo: mouseeventinfoty; + ftimestampbefore: longword; + flastbuttonpress: mousebuttonty; + flastbuttonpresstimestamp: longword; + flastbuttonrelease: mousebuttonty; + flastbuttonreleasetimestamp: longword; + fdoublemousepress,fdoublemouserelease: boolean; + fwindowstack: windowstackinfoarty; + ftimertick: boolean; + + procedure twindowdestroyed(const sender: twindow); + procedure windowdestroyed(aid: winidty); + procedure setwindowfocus(winid: winidty); + procedure unsetwindowfocus(winid: winidty); + procedure registerwindow(awindow: twindow); + procedure unregisterwindow(awindow: twindow); + procedure widgetdestroyed(const widget: twidget); + + procedure processexposeevent(event: twindowrectevent); + procedure processconfigureevent(event: twindowrectevent); + procedure processshowingevent(event: twindowevent); + procedure processmouseevent(event: tmouseevent); + procedure processkeyevent(event: tkeyevent); + procedure processleavewindow; + procedure processwindowcrossingevent(event: twindowevent); + + function getmousewinid: winidty; //for tmouse.setshape + procedure waitevent; + //application must be locked + procedure checkactivewindow; + function focusinpending: boolean; + procedure checkapplicationactive; + function winiddestroyed(const aid: winidty): boolean; + procedure eventloop(const once: boolean = false); + function beginmodal(const sender: twindow; + const showinfo: pshowinfoty): boolean; + //true if modalwindow destroyed + procedure endmodal(const sender: twindow); + procedure stackunder(const sender: twindow; const predecessor: twindow); + procedure stackover(const sender: twindow; const predecessor: twindow); + procedure checkwindowstack; + procedure updatewindowstack; + //reorders windowstack by ow_background,ow_top + procedure checkcursorshape; + + procedure mouseparktimer(const sender: tobject); + procedure removewindowevents(const awindow: winidty; + const aeventkind: eventkindty); + protected + procedure internalpackwindowzorder(); override; + function getevents: integer; override; + //application must be locked + //returns count of queued events + procedure dopostevent(const aevent: tmseevent); override; + procedure flushmousemove; + procedure doterminate(const shutdown: boolean); + procedure checkshortcut(const sender: twindow; const awidget: twidget; + var info: keyeventinfoty); + procedure doeventloop(const once: boolean); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + end; + +var + appinst: tinternalapplication; + +function combineframestateflags( + const disabled,focused,active,mouse,clicked: boolean): framestateflagsty; +begin + result:= []; + if disabled then include(result,fsf_disabled); + if focused then include(result,fsf_focused); + if active then include(result,fsf_active); + if mouse then include(result,fsf_mouse); + if clicked then include(result,fsf_clicked); +end; + +function combineframestateflags( + const astate: shapestatesty): framestateflagsty; +begin + result:= []; + if shs_disabled in astate then begin + include(result,fsf_disabled); + end; + if shs_focused in astate then begin + include(result,fsf_focused); + end; + if shs_active in astate then begin + include(result,fsf_active); + end; + if shs_mouse in astate then begin + include(result,fsf_mouse); + end; + if shs_clicked in astate then begin + include(result,fsf_clicked); + end; +end; + +function wbounds_x(const awidget: twidget): integer; +begin + result:= awidget.fwidgetrect.x; +end; + +procedure wsetbounds_x(const awidget: twidget; const avalue: integer); +begin + awidget.bounds_x:= avalue; +end; + +function wbounds_cx(const awidget: twidget): integer; +begin + result:= awidget.fwidgetrect.cx; +end; + +procedure wsetbounds_cx(const awidget: twidget; const avalue: integer); +begin + awidget.bounds_cx:= avalue; +end; + +procedure wsetanchord_cx(const awidget: twidget; const avalue: integer); +begin + if not wanchbothx(awidget) then begin + awidget.setanchordwidgetsize(ms(avalue,awidget.bounds_cy)); + end; +end; + +function wbounds_y(const awidget: twidget): integer; +begin + result:= awidget.fwidgetrect.y; +end; + +procedure wsetbounds_y(const awidget: twidget; const avalue: integer); +begin + awidget.bounds_y:= avalue; +end; + +function wbounds_cy(const awidget: twidget): integer; +begin + result:= awidget.fwidgetrect.cy; +end; + +procedure wsetanchord_cy(const awidget: twidget; const avalue: integer); +begin + if not wanchbothy(awidget) then begin + awidget.setanchordwidgetsize(ms(awidget.bounds_cx,avalue)); + end; +end; + +procedure wsetbounds_cy(const awidget: twidget; const avalue: integer); +begin + awidget.bounds_cy:= avalue; +end; + +function wstopx(const awidget: twidget): integer; +begin + result:= awidget.bounds_x + awidget.bounds_cx; +end; + +procedure wsetstopx(const awidget: twidget; const avalue: integer); +begin + awidget.bounds_cx:= avalue - awidget.bounds_x; +end; + +function wstopy(const awidget: twidget): integer; +begin + result:= awidget.bounds_y + awidget.bounds_cy; +end; + +procedure wsetstopy(const awidget: twidget; const avalue: integer); +begin + awidget.bounds_cy:= avalue - awidget.bounds_y; +end; + +function wanchstopx(const awidget: twidget): boolean; +begin + result:= an_right in awidget.anchors; +end; + +function wanchstopy(const awidget: twidget): boolean; +begin + result:= an_bottom in awidget.anchors; +end; + +function wanchbothx(const awidget: twidget): boolean; +var + an1: anchorsty; +begin + an1:= [an_left,an_right] * awidget.anchors; + result:= (an1 = []) or (an1 = [an_left,an_right]); +end; + +function wanchbothy(const awidget: twidget): boolean; +var + an1: anchorsty; +begin + an1:= [an_top,an_bottom] * awidget.anchors; + result:= (an1 = []) or (an1 = [an_top,an_bottom]); +end; + +function wbounds_cxmin(const awidget: twidget): integer; +begin + result:= awidget.fminsize.cx; +end; + +procedure wsetbounds_cxmin(const awidget: twidget; const avalue: integer); +begin + awidget.bounds_cxmin:= avalue; +end; + +function wbounds_cymin(const awidget: twidget): integer; +begin + result:= awidget.fminsize.cy; +end; + +procedure wsetbounds_cymin(const awidget: twidget; const avalue: integer); +begin + awidget.bounds_cymin:= avalue; +end; + +function wbounds_cxmax(const awidget: twidget): integer; +begin + result:= awidget.fmaxsize.cx; +end; + +procedure wsetbounds_cxmax(const awidget: twidget; const avalue: integer); +begin + awidget.bounds_cxmax:= avalue; +end; + +function wbounds_cymax(const awidget: twidget): integer; +begin + result:= awidget.fmaxsize.cy; +end; + +procedure wsetbounds_cymax(const awidget: twidget; const avalue: integer); +begin + awidget.bounds_cymax:= avalue; +end; + +function checkshortcut(var info: keyeventinfoty; const caption: msestring; + const checkalt: boolean): boolean; +begin + with info do begin + if (eventstate * [es_processed,es_modal,es_preview] = []) and + (not checkalt and (shiftstate -[ss_alt] = []) or (shiftstate = [ss_alt])) and + (length(info.chars) > 0) then begin + result:= isshortcut(info.chars[1],caption); + if result then begin + include(eventstate,es_processed); + end; + end + else begin + result:= false; + end; + end; +end; + +function checkshortcut(var info: keyeventinfoty; + const key: keyty; const shiftstate: shiftstatesty): boolean; +begin + result:= (key = info.key) and (shiftstate = info.shiftstate); + if result then begin + include(info.eventstate,es_processed); + end; +end; + +procedure translatewidgetpoint1(var point: pointty; + const source,dest: twidget); + //translates from source widget to dest widget, to screen if dest = nil + //source = nil -> screen + +begin + if source <> nil then begin + addpoint1(point,source.screenpos); + end; + if dest <> nil then begin + subpoint1(point,dest.screenpos); + end; +end; + +function translatewidgetpoint(const point: pointty; + const source,dest: twidget): pointty; +begin + result:= point; + translatewidgetpoint1(result,source,dest); +end; + +function getprocesswindow(const procid: integer): winidty; +var + ar1: procidarty; +begin + ar1:= getallprocesschildren(procid); + result:= gui_pidtowinid(ar1); +end; + +function activateprocesswindow(const procid: integer; + const araise: boolean = true): boolean; + //true if ok +var + winid: winidty; +begin + result:= false; + winid:= getprocesswindow(procid); + if winid <> 0 then begin + if gui_showwindow(winid) = gue_ok then begin + if araise and (gui_raisewindow(winid) <> gue_ok) then begin + exit; + end; + if gui_setappfocus(winid) = gue_ok then begin + result:= true; + end; + end; + end; +end; + +function translatewidgetrect(const rect: rectty; + const source,dest: twidget): rectty; +begin + result:= rect; + translatewidgetpoint1(result.pos,source,dest); +end; + +function compx(const l,r): integer; +begin + result:= twidget(l).fwidgetrect.x - twidget(r).fwidgetrect.x; + if result = 0 then begin + result:= twidget(l).fwidgetrect.y - twidget(r).fwidgetrect.y; + end; +end; + +procedure sortwidgetsxorder(var awidgets: widgetarty; const parent: twidget = nil); +var + int1: integer; + ar1,ar2: integerarty; +begin + if parent = nil then begin + sortarray(pointerarty(awidgets),{$ifdef FPC}@{$endif}compx); + end + else begin + setlength(ar1,length(awidgets)); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= translatewidgetpoint(awidgets[int1].pos,awidgets[int1],parent).x; + end; + sortarray(ar1,ar2); + orderarray(ar2,pointerarty(awidgets)); + end; +end; + +function compy(const l,r): integer; +begin + result:= twidget(l).fwidgetrect.y - twidget(r).fwidgetrect.y; + if result = 0 then begin + result:= twidget(l).fwidgetrect.x - twidget(r).fwidgetrect.x; + end; +end; + +procedure sortwidgetsyorder(var awidgets: widgetarty; const parent: twidget = nil); +var + int1: integer; + ar1,ar2: integerarty; +begin + if parent = nil then begin + sortarray(pointerarty(awidgets),{$ifdef FPC}@{$endif}compy); + end + else begin + setlength(ar1,length(awidgets)); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= translatewidgetpoint(awidgets[int1].pos,awidgets[int1],parent).y; + end; + sortarray(ar1,ar2); + orderarray(ar2,pointerarty(awidgets)); + end; +end; + +procedure translatepaintpoint1(var point: pointty; + const source,dest: twidget); + //translates from source widget to dest widget, to screen if dest = nil + //source = nil -> screen + +begin + if source <> nil then begin + addpoint1(point,source.screenpos); + addpoint1(point,source.paintpos); + end; + if dest <> nil then begin + subpoint1(point,dest.screenpos); + subpoint1(point,dest.paintpos); + end; +end; + +function translatepaintpoint(const point: pointty; + const source,dest: twidget): pointty; +begin + result:= point; + translatepaintpoint1(result,source,dest); +end; + +function translatepaintrect(const rect: rectty; + const source,dest: twidget): rectty; +begin + result:= rect; + translatepaintpoint1(result.pos,source,dest); +end; + +procedure translatewidgettopaintpoint1(var point: pointty; + const source,dest: twidget); +begin + if source <> nil then begin + addpoint1(point,source.screenpos); + end; + if dest <> nil then begin + subpoint1(point,dest.screenpos); + subpoint1(point,dest.paintpos); + end; +end; + +function translatewidgettopaintpoint(const point: pointty; + const source,dest: twidget): pointty; +begin + result:= point; + translatewidgettopaintpoint1(result,source,dest); +end; + +function translatewidgettopaintrect(const rect: rectty; + const source,dest: twidget): rectty; +begin + result:= rect; + translatewidgettopaintpoint1(result.pos,source,dest); +end; + +procedure translateclientpoint1(var point: pointty; + const source,dest: twidget); + //translates from source client to dest client, to screen if dest = nil + //source = nil -> screen +begin + if source <> nil then begin + addpoint1(point,source.screenpos); + addpoint1(point,source.clientwidgetpos); + end; + if dest <> nil then begin + subpoint1(point,dest.screenpos); + subpoint1(point,dest.clientwidgetpos); + end; +end; + +function translateclientpoint(const point: pointty; + const source,dest: twidget): pointty; +begin + result:= point; + translateclientpoint1(result,source,dest); +end; + +function translateclientrect(const rect: rectty; + const source,dest: twidget): rectty; +begin + result:= rect; + translateclientpoint1(result.pos,source,dest); +end; + +procedure syncmaxautosize(const widgets: array of twidget); +var + size1,size2: sizety; + int1: integer; + rect1: rectty; + po1: pointty; +begin + size1:= nullsize; + for int1:= high(widgets) downto 0 do begin + with widgets[int1] do begin + size2:= clientsize; + getautopaintsize(size2); + if not (osk_nolayoutcx in optionsskin) then begin + if size2.cx > size1.cx then begin + size1.cx:= size2.cx; + end; + end; + if not (osk_nolayoutcy in optionsskin) then begin + if size2.cy > size1.cy then begin + size1.cy:= size2.cy; + end; + end; + end; + end; + for int1:= 0 to high(widgets) do begin + with widgets[int1] do begin + rect1:= fwidgetrect; + size2:= clientsize; + if not (osk_nolayoutcx in optionsskin) then begin + size2.cx:= size1.cx; + end; + if not (osk_nolayoutcy in optionsskin) then begin + size2.cy:= size1.cy; + end; + clientsize:= size2; + po1:= pos; + if an_right in fanchors then begin + dec(po1.x,fwidgetrect.cx-rect1.cx); + end; + if an_bottom in fanchors then begin + dec(rect1.y,fwidgetrect.cy-rect1.cy); + end; + pos:= po1; + end; + end; +end; + +procedure syncpaintwidth(const awidgets: array of twidget; + const awidgetwidth: integer = -1); +var + int1,int2,int3: integer; + widget1: twidget; +begin + if high(awidgets) >= 0 then begin + int2:= -bigint; + widget1:= awidgets[0]; //compiler warning + for int1:= 0 to high(awidgets) do begin //first widget first + with awidgets[int1] do begin + if fframe = nil then begin + int3:= 0; + end + else begin + int3:= fframe.fouterframe.left + fframe.fouterframe.right; + end; + end; + if int3 > int2 then begin + widget1:= awidgets[int1]; + int2:= int3; + end; + end; + if awidgetwidth >= 0 then begin + with widget1 do begin //biggest frame + if anchors * [an_left,an_right] = [an_right] then begin + bounds_x:= bounds_x - awidgetwidth + bounds_cx; + end; + bounds_cx:= awidgetwidth; + end; + end; + int2:= widget1.bounds_cx - int2; //min frame width + for int1:= high(awidgets) downto 0 do begin + with awidgets[int1] do begin + if fframe = nil then begin + int3:= 0; + end + else begin + int3:= fframe.fouterframe.left + fframe.fouterframe.right; + end; + int3:= int3 + int2; + if anchors * [an_left,an_right] = [an_right] then begin + bounds_x:= bounds_x - int3 + bounds_cx; + end; + bounds_cx:= int3; + end; + end; + end; +end; + +procedure syncpaintheight(const awidgets: array of twidget; + const awidgetheight: integer = -1); +var + int1,int2,int3: integer; + widget1: twidget; +begin + if high(awidgets) >= 0 then begin + int2:= -bigint; + widget1:= awidgets[0]; //compiler warning + for int1:= 0 to high(awidgets) do begin //first widget first + with awidgets[int1] do begin + if fframe = nil then begin + int3:= 0; + end + else begin + int3:= fframe.fouterframe.top + fframe.fouterframe.bottom; + end; + end; + if int3 > int2 then begin + widget1:= awidgets[int1]; + int2:= int3; + end; + end; + if awidgetheight >= 0 then begin + with widget1 do begin + if anchors * [an_top,an_bottom] = [an_bottom] then begin + bounds_y:= bounds_y - awidgetheight + bounds_cy; + end; + bounds_cy:= awidgetheight; + end; + end; + int2:= widget1.bounds_cy - int2; //min frame width + for int1:= high(awidgets) downto 0 do begin + with awidgets[int1] do begin + if fframe = nil then begin + int3:= 0; + end + else begin + int3:= fframe.fouterframe.top + fframe.fouterframe.bottom; + end; + int3:= int3 + int2; + if anchors * [an_top,an_bottom] = [an_bottom] then begin + bounds_y:= bounds_y - int3 + bounds_cy; + end; + bounds_cy:= int3; + end; + end; + end; +end; + +procedure beep; +begin + gui_beep; +end; + +procedure guibeep; +begin + gui_beep; +end; + +procedure disablewidgets(awidgets: array of twidget); +var + int1: integer; +begin + for int1:= 0 to high(awidgets) do begin + awidgets[int1].enabled:= false; + end; +end; + +procedure enablewidgets(awidgets: array of twidget); +var + int1: integer; +begin + for int1:= 0 to high(awidgets) do begin + awidgets[int1].enabled:= true; + end; +end; + +procedure showwidgets(awidgets: array of twidget); +var + int1: integer; +begin + for int1:= 0 to high(awidgets) do begin + awidgets[int1].visible:= false; + end; +end; + +procedure hidewidgets(awidgets: array of twidget); +var + int1: integer; +begin + for int1:= 0 to high(awidgets) do begin + awidgets[int1].visible:= false; + end; +end; + +function showmodalwidget(const aclass: widgetclassty): modalresultty; +var + widget1: twidget; +begin + widget1:= nil; + application.setlinkedvar(aclass.create(nil),tmsecomponent(widget1)); + try + result:= widget1.show(true); + finally + widget1.free; + end; +end; + +function getiassistiveclient(const awidget: twidget): iassistiveclient; +begin + result:= nil; + if awidget <> nil then begin + result:= awidget.getiassistiveclient(); + end; +end; + +procedure designeventloop; +begin + if appinst <> nil then begin + appinst.fdesigning:= true; + tinternalapplication(appinst).eventloop({nil}); + end; +end; + +function needswidgetnamewriting(const ar: widgetarty): boolean; +var + int1: integer; +begin + result:= false; + for int1:= 0 to high(ar) do begin + if ar[int1] <> nil then begin + result:= true; + break; + end; + end; +end; + +function needswidgetnamewriting(const ar1,ar2: widgetarty): boolean; +var + int1: integer; +begin + result:= high(ar1) <> high(ar2); + if not result then begin; + for int1:= 0 to high(ar1) do begin + if (ar1[int1] = nil) or (ar2[int1] = nil) then begin + if (ar1[int1] <> ar2[int1]) then begin + result:= true; + break; + end; + end + else begin + if ar1[int1].name <> ar2[int1].name then begin + result:= true; + break; + end; + end; + end; + end; +end; + +procedure writewidgetnames(const writer: twriter; const ar: widgetarty); +var + int1: integer; +begin + writer.writelistbegin; + for int1:= 0 to high(ar) do begin + if ar[int1] <> nil then begin + writer.writestring(ar[int1].name); + end + else begin + writer.writestring(''); + end; + end; + writer.writelistend; +end; + +function application: tguiapplication; +begin + if appinst = nil then begin + tinternalapplication.create(nil); +// appinst.initialize; + end; + result:= appinst; +end; + +function mousebuttontoshiftstate(button: mousebuttonty): shiftstatesty; +begin + if button = mb_none then begin + result:= []; + end + else begin + result:= [shiftstatety(longword(ss_left) + + longword(button) - longword(mb_left))]; + end; +end; + +function isenterkey(const awidget: twidget; const key: keyty): boolean; +begin + result:= ((awidget = nil) or not + (ow_keyreturntaborder in awidget.optionswidget)) and + ({(key = key_enter) or} (key = key_return)); +end; + +function isdblclick(const ainfo: mouseeventinfoty; + const abutton: mousebuttonty = mb_left): boolean; +begin + with ainfo do begin + result:= (button = abutton) and (eventkind = ek_buttonpress) and + (ss_double in shiftstate); + end; +end; + +function eatdblclick(var ainfo: mouseeventinfoty; + const abutton: mousebuttonty = mb_left): boolean; +begin + result:= isdblclick(ainfo,abutton); + if result then begin + include(ainfo.eventstate,es_processed); + end; +end; + +function simulatemodalresult(const awidget: twidget; + const amodres: modalresultty): boolean; +begin + result:= awidget <> nil; + if result then begin + with awidget.window do begin + fmodalresult:= amodres; + try + result:= awidget.canclose(nil); + if result then begin + awidget.hide; + end; + finally + if fmodalresult = amodres then begin + fmodalresult:= mr_none; + end; + end; + end; + end + else begin + result:= false; + end; +end; + +procedure destroyregion(var region: gdiregionty); +var + info: drawinfoty; +begin + drawinfoinit(info); + with region do begin + if region <> 0 then begin + info.regionoperation.source:= region; + gdi_call(gdf_destroyregion,info,gdi); + region:= 0; + end; + end; +end; + +function createregion(const gdi: pgdifunctionaty): gdiregionty; overload; +var + info: drawinfoty; +begin +{$warnings off} + drawinfoinit(info); + with info.regionoperation do begin + gdi_call(gdf_createemptyregion,info,gdi); + result.region:= dest; + result.gdi:= gdi; + end; +end; +{$warnings on} + +function createregion(const arect: rectty; + const gdi: pgdifunctionaty): gdiregionty; overload; +var + info: drawinfoty; +begin +{$warnings off} + drawinfoinit(info); + with info.regionoperation do begin + rect:= arect; + drawinfoinit(info); + gdi_call(gdf_createrectregion,info,gdi); + result.region:= dest; + result.gdi:= gdi; + end; +end; +{$warnings on} + +function createregion(const rects: rectarty; + const gdi: pgdifunctionaty): gdiregionty; overload; +var + info: drawinfoty; +begin +{$warnings off} + drawinfoinit(info); + with info.regionoperation do begin + rectscount:= length(rects); + if rectscount > 0 then begin + rectspo:= @rects[0]; + gdi_call(gdf_createrectsregion,info,gdi); + result.region:= dest; + result.gdi:= gdi; + end + else begin + result:= createregion(gdi); + end; + end; +end; +{$warnings on} + +procedure regmove(const region: gdiregionty; const dist: pointty); +var + info: drawinfoty; +begin +{$warnings off} + drawinfoinit(info); + with region,info.regionoperation do begin + if region <> 0 then begin + source:= region; + rect.pos:= dist; + gdi_call(gdf_moveregion,info,gdi); + end; + end; +end; +{$warnings on} + +function regcliprect(const region: gdiregionty): rectty; +var + info: drawinfoty; +begin +{$warnings off} + drawinfoinit(info); + with region,info.regionoperation do begin + if region <> 0 then begin + source:= region; + gdi_call(gdf_regionclipbox,info,gdi); + result:= rect; + end + else begin + result:= nullrect; + end; + end; +end; +{$warnings on} + +procedure regintersectrect(const region: gdiregionty; const arect: rectty); +var + info: drawinfoty; +begin +{$warnings off} + drawinfoinit(info); + with region,info.regionoperation do begin + dest:= region; + rect:= arect; + gdi_call(gdf_regintersectrect,info,gdi); + end; +end; +{$warnings on} + +procedure regaddrect(const region: gdiregionty; const arect: rectty); +var + info: drawinfoty; +begin +{$warnings off} + drawinfoinit(info); + with region,info.regionoperation do begin + dest:= region; + rect:= arect; + gdi_call(gdf_regaddrect,info,gdi); + end; +end; +{$warnings on} + +{ twidgetfont} + +class function twidgetfont.getinstancepo(owner: tobject): pfont; +begin + result:= @twidget(owner).ffont; +end; + +{ twidgetfontempty} + +class function twidgetfontempty.getinstancepo(owner: tobject): pfont; +begin + result:= @twidget(owner).ffontempty; +end; + +{ tresizeevent } + +constructor tresizeevent.create(const dest: ievent; const asize: sizety); +begin + inherited create(ek_resize,dest); + size:= asize; +end; + +{ tcustomframe } + +procedure initframeinfo(var info: baseframeinfoty); overload; +begin + with info do begin + colorclient:= cl_default; + colorframe:= cl_default; + colorframeactive:= cl_default; + colorframedisabled:= cl_default; + colorframemouse:= cl_default; + colorframeclicked:= cl_default; + colorframedefault:= cl_default; + colorglyph:= cl_default; + colorpattern:= cl_default; + initdefaultvalues(framecolors.edges); +{ + with framecolors.edges do begin + shadow.effectcolor:= cl_default; + shadow.color:= cl_default; + shadow.effectwidth:= -1; + light.color:= cl_default; + light.effectcolor:= cl_default; + light.effectwidth:= -1; + end; +} + end; +end; + +procedure initframeinfo(var info: captionframeinfoty); overload; +begin + //dummy +end; + +constructor tcustomframe.create(const intf: iframe); +var + ws1: widgetstates1ty; +begin + include(fstate,fs_creating); + fintf:= intf; + ws1:= fintf.getwidget.fwidgetstate1; + if ws1_noframewidgetshift in ws1 then begin + include(fstate,fs_nowidget); + end; + if ws1_framemouse in ws1 then begin + include(fstate,fs_framemouse); + end; + if not (fs_nosetinstance in fstate) then begin + fintf.setframeinstance(self); + end; + initframeinfo(fi); +end; + +destructor tcustomframe.destroy; +begin + if ftemplate <> nil then begin + fintf.getwidget.setlinkedvar(nil,tmsecomponent(ftemplate)); + end; + inherited; +end; + +function tcustomframe.pointinmask(const pos: pointty; + const arect: rectty): boolean; +var + rect1: rectty; + po1: pint16; +begin + result:= true; + if (fi.frameimage_list <> nil) and + fi.frameimage_list.hascornermask then begin + rect1:= arect; + with timagelist1(fi.frameimage_list) do begin + if (pos.x < fcornermaskmaxtopleft) and + (pos.y < rect1.y + length(cornermask_topleft)) then begin + //topleft + po1:= pointer(cornermask_topleft); + result:= pos.x >= rect1.x + po1[pos.y-rect1.y]; + end + else begin + if (pos.x < fcornermaskmaxbottomleft) and + (pos.y >= rect1.y + rect1.cy - + length(cornermask_bottomleft)) then begin + //bottomleft + po1:= pointer(cornermask_bottomleft); + result:= pos.x >= rect1.x + po1[rect1.y + rect1.cy - pos.y -1]; + end + else begin + if (pos.x >= rect1.x + rect1.cx - fcornermaskmaxbottomright) and + (pos.y >= rect1.y + rect1.cy - + length(cornermask_bottomright)) then begin + //bottomright + po1:= pointer(cornermask_bottomright); + result:= pos.x < rect1.x + rect1.cx - + po1[rect1.y + rect1.cy - pos.y -1]; + end + else begin + if (pos.x >= rect1.x + rect1.cx - fcornermaskmaxtopright) and + (pos.y < rect1.y + length(cornermask_topright)) then begin + //topright + po1:= pointer(cornermask_topright); + result:= pos.x < rect1.x + rect1.cx - + po1[pos.y-rect1.y]; + end; + end; + end; + end; + end; + end; +end; + +procedure tcustomframe.updatemousestate(const sender: twidget; + const info: mouseeventinfoty); + +begin + checkstate; + with sender do begin + if not (ow_mousetransparent in foptionswidget) then begin + if pointinrect(info.pos,fpaintrect) and + pointinmask(info.pos, + deflaterect(mr(nullpoint,fintf.getwidgetrect.size),fouterframe)) then begin + fwidgetstate:= fwidgetstate + [ws_mouseinclient,ws_wantmousemove, + ws_wantmousebutton,ws_wantmousefocus]; + end + else begin + if (fs_framemouse in fstate) and + pointinrect(info.pos,mr(nullpoint,fintf.getwidgetrect.size)) then begin + fwidgetstate:= fwidgetstate + [ws_wantmousemove,ws_wantmousebutton]; + + end; + end; + end; + end; +end; + +function tcustomframe.needsactiveinvalidate: boolean; +begin + with fi do begin + result:= (frameimage_list <> nil) and (frameimage_offsetactive <> 0) or + (frameface_list <> nil) and (frameface_offsetactive <> 0) or + (fi.colorframedefault <> cl_default); + end; +end; + +function tcustomframe.needsenabledinvalidate: boolean; +begin + with fi do begin + result:= colorframedisabled <> cl_default; + end; +end; + +function tcustomframe.needsfocusedinvalidate: boolean; +begin + with fi do begin + result:= (frameimage_list <> nil) and (frameimage_offsetactive <> 0) or + (frameface_list <> nil) and (frameface_offsetfocused <> 0) or + (fi.colorframedefault <> cl_default);; + end; +end; + +function tcustomframe.needsmouseinvalidate: boolean; +begin + with fi do begin + result:= + (fs_needsmouseinvalidate in fstate) or + (frameimage_list <> nil) and + ((frameimage_offsetmouse <> 0) or (frameimage_offsetclicked <> 0)) or + (frameface_list <> nil) and + ((frameface_offsetmouse <> 0) or (frameface_offsetclicked <> 0)) or + (colorframeclicked <> cl_default) or + (colorframemouse <> cl_default); + end; +end; + +function tcustomframe.needsclickinvalidate: boolean; +begin + with fi do begin + result:= (frameimage_list <> nil) and (frameimage_offsets.clicked <> 0) or + (frameface_list <> nil) and (frameface_offsets.clicked <> 0) or + (colorframeclicked <> cl_default); + end; +end; + +function tcustomframe.needsmouseenterinvalidate: boolean; +begin + with fi do begin + result:= (frameimage_list <> nil) and (frameimage_offsets.mouse <> 0) or + (frameface_list <> nil) and (frameface_offsets.mouse <> 0) or + (colorframemouse <> cl_default); + end; +end; + +procedure tcustomframe.activechanged; +begin + if needsactiveinvalidate then begin + fintf.getwidget.invalidatewidget; + end; +end; + +procedure tcustomframe.enabledchanged(); +begin + if needsenabledinvalidate then begin + fintf.getwidget.invalidatewidget; + end; +end; + +procedure tcustomframe.focusedchanged; +begin + if needsfocusedinvalidate() then begin + fintf.getwidget.invalidatewidget(); + end; +end; + +function tcustomframe.needsfocuspaint: boolean; +begin + result:= fs_drawfocusrect in fstate; +end; + +function tcustomframe.haspaintrectfocus(): boolean; +begin + result:= not (fs_captionfocus in fstate); +end; + +function tcustomframe.ishintarea(const apos: pointty; var aid: int32): boolean; +begin + result:= pointinrect(apos,fpaintrect) or + (fs_captionhint in fstate) and pointincaption(apos); +end; + +function calcframestateoffs(const astate: framestateflagsty; + const offsets: frameoffsetsty): integer; +begin + with offsets do begin + result:= offset; + if fsf_offset1 in astate then begin + result:= result + offset1; + end; + if fsf_disabled in astate then begin + result:= result + disabled; + end; + if fsf_active in astate then begin + result:= result + active; + end; + if fsf_focused in astate then begin + result:= result + focused; + end; + if fsf_mouse in astate then begin + result:= result + mouse; + end; + if fsf_clicked in astate then begin + result:= result + clicked; + end; + { + else begin + if fsf_active in astate then begin + if fsf_clicked in astate then begin + result:= result + activeclicked; + end + else begin + if fsf_mouse in astate then begin + result:= result + activemouse; + end + else begin + result:= result + active; + end; + end; + end + else begin + if fsf_clicked in astate then begin + result:= result + clicked; + end + else begin + if fsf_mouse in astate then begin + result:= result + mouse; + end; + end; + end; + end; +} + end; +end; + +procedure tcustomframe.paintframeface(const canvas: tcanvas; + const arect: rectty); +var + faceoffs: int32; + rect1: rectty; + reg1: regionty; +begin + if fi.frameface_list <> nil then begin + faceoffs:= fi.frameface_list.lookup( + calcframestateoffs(fintf.getframestateflags, + frameoffsetsty(fi.frameface_offsets))); + if (faceoffs >= 0) and (faceoffs < fi.frameface_list.list.count) then begin + if fso_clientfacerect in optionsskin then begin + reg1:= canvas.copyclipregion; + rect1.x:= arect.x + fclientrect.x; + rect1.y:= arect.y + fclientrect.y; + rect1.cx:= arect.cx + fclientrect.cx - fpaintrect.cx; + rect1.cy:= arect.cy + fclientrect.cy - fpaintrect.cy; + canvas.intersectcliprect(arect); + fi.frameface_list.list[faceoffs].paint(canvas,rect1); + canvas.clipregion:= reg1; + end + else begin + fi.frameface_list.list[faceoffs].paint(canvas,arect); + end; + end; + end; +end; + +function tcustomframe.actualcolorclient(): colorty; +begin + result:= fi.colorclient; + if result = cl_default then begin + result:= cl_transparent; + end; +end; + +procedure tcustomframe.internalpaintbackground(const canvas: tcanvas; + const arect: rectty; const clip: boolean; const move: boolean); +var + rect1: rectty; + cl1: colorty; +begin + rect1:= deflaterect(arect,fpaintframe); + if clip then begin + canvas.intersectcliprect(rect1); + if (fi.frameimage_list <> nil) and + fi.frameimage_list.hascornermask then begin + fi.frameimage_list.clipcornermask(canvas, + deflaterect(arect,fouterframe),fi.hiddenedges); + end; + end; + cl1:= actualcolorclient; + if cl1 <> cl_transparent then begin + canvas.fillrect(rect1,cl1); + end; + if not (fso_faceoverlay in optionsskin) then begin + paintframeface(canvas,rect1); + end; + if move then begin + canvas.move(addpoint(fpaintrect.pos,fclientrect.pos)); + canvas.brushorigin:= nullpoint; + end; +end; + +procedure tcustomframe.paintbackground(const canvas: tcanvas; + const arect: rectty; const clip: boolean; + const move: boolean); +var + bo1: boolean; +begin + if (ftemplate <> nil) then begin + if assigned(tframetemplate(ftemplate.ftemplate). + fonbeforepaintbackground) then begin + bo1:= false; + tframetemplate(ftemplate.ftemplate).fonbeforepaintbackground( + self,canvas,arect,clip,move,bo1); + if not bo1 then begin + internalpaintbackground(canvas,arect,clip,move); + end; + end + else begin + internalpaintbackground(canvas,arect,clip,move); + end; + if assigned(tframetemplate(ftemplate.ftemplate). + fonafterpaintbackground) then begin + tframetemplate(ftemplate.ftemplate).fonafterpaintbackground( + self,canvas,arect,clip,move); + end; + end + else begin + internalpaintbackground(canvas,arect,clip,move); + end; +end; + +class procedure tcustomframe.drawframe(const canvas: tcanvas; + const rect2: rectty; const afi: baseframeinfoty; + const astate: framestateflagsty); +var + imageoffs: integer; + rect1: rectty; + col1: colorty; +// imagesize1: sizety; +begin + rect1:= rect2; + if afi.levelo <> 0 then begin + draw3dframe(canvas,rect1,afi.levelo,afi.framecolors.edges,afi.hiddenedges); + updateedgerect(rect1,abs(afi.levelo),afi.hiddenedges); + end; + if afi.framewidth > 0 then begin + col1:= afi.colorframe; + if (afi.colorframeclicked <> cl_default) and + (fsf_clicked in astate) then begin + col1:= afi.colorframeclicked; + end + else begin + if (afi.colorframemouse <> cl_default) and + (fsf_mouse in astate) then begin + col1:= afi.colorframemouse; + end + else begin + if (afi.colorframeactive <> cl_default) and + (fsf_active in astate) then begin + col1:= afi.colorframeactive; + end + else begin + if (afi.colorframedisabled <> cl_default) and + (fsf_disabled in astate) then begin + col1:= afi.colorframedisabled; + end + else begin + if (afi.colorframedefault <> cl_default) and + (fsf_default in astate) then begin + col1:= afi.colorframedefault; + end + end; + end; + end; + end; + if col1 = cl_default then begin + col1:= defaultframecolors.frame; + end; + canvas.drawframe(rect1,-afi.framewidth,col1,afi.hiddenedges); + updateedgerect(rect1,afi.framewidth,afi.hiddenedges); + end; + if afi.leveli <> 0 then begin + draw3dframe(canvas,rect1,afi.leveli,afi.framecolors.edges,afi.hiddenedges); + end; + if (afi.frameimage_list <> nil) then begin + imageoffs:= calcframestateoffs(astate,frameoffsetsty(afi.frameimage_offsets)); + drawimageframe(canvas,afi.frameimage_list,imageoffs,rect2,afi.hiddenedges); + end; +end; + +function tcustomframe.getassistivecaption(): msestring; +begin + result:= ''; +end; + +procedure tcustomframe.internalpaintoverlay(const canvas: tcanvas; + const arect: rectty); +begin + if fso_faceoverlay in optionsskin then begin + paintframeface(canvas,deflaterect(arect,fpaintframe)); + end; + drawframe(canvas,deflaterect(arect,fouterframe),fi,fintf.getframestateflags); +end; + +procedure tcustomframe.updatehotkeys(); +begin + //dummy +end; + +procedure tcustomframe.paintoverlay(const canvas: tcanvas; + const arect: rectty); +var + bo1: boolean; +begin + if (ftemplate <> nil) then begin + if assigned(tframetemplate(ftemplate.ftemplate). + fonbeforepaintoverlay) then begin + bo1:= false; + tframetemplate(ftemplate.ftemplate).fonbeforepaintoverlay( + self,canvas,arect,bo1); + if not bo1 then begin + internalpaintoverlay(canvas,arect); + end; + end + else begin + internalpaintoverlay(canvas,arect); + end; + if assigned(tframetemplate(ftemplate.ftemplate). + fonafterpaintoverlay) then begin + tframetemplate(ftemplate.ftemplate).fonafterpaintoverlay(self,canvas,arect); + end; + end + else begin + internalpaintoverlay(canvas,arect); + end; +end; + +procedure tcustomframe.dopaintfocusrect(const canvas: tcanvas; + const rect: rectty); +var + rect1: rectty; +begin + rect1:= deflaterect(rect,fpaintframe); + inflaterect1(rect1,-fi.focusrectdist); + drawfocusrect(canvas,rect1); +end; + +function tcustomframe.checkfocusshortcut(var info: keyeventinfoty): boolean; +begin + result:= false; +end; + +procedure tcustomframe.updatewidgetstate; +var + bo1: boolean; +begin + if (fi.colorframeactive <> cl_default) and (fi.framewidth <> 0) then begin + with fintf.getwidget do begin + bo1:= active; + if bo1 xor (fs_widgetactive in fstate) then begin + fintf.invalidatewidget; + if bo1 then begin + include(fstate,fs_widgetactive); + end + else begin + exclude(fstate,fs_widgetactive); + end; + end; + end; + end; +end; + +procedure tcustomframe.updateclientrect; +begin + fclientrect.size:= fpaintrect.size; + fclientrect.pos:= nullpoint; + finnerclientrect:= deflaterect(fclientrect,fi.innerframe); +end; + +class function tcustomframe.calcpaintframe(const afi: baseframeinfoty): framety; +var + int1: integer; +begin + result:= nullframe; + with result do begin + int1:= abs(afi.levelo) + afi.framewidth + abs(afi.leveli); + if not(edg_left in afi.hiddenedges) then begin + left:= int1; + end; + if not(edg_top in afi.hiddenedges) then begin + top:= int1; + end; + if not(edg_right in afi.hiddenedges) then begin + right:= int1; + end; + if not(edg_bottom in afi.hiddenedges) then begin + bottom:= int1; + end; + if afi.frameimage_list <> nil then begin + if not (edg_left in afi.hiddenedges) then begin + int1:= afi.frameimage_list.width + afi.frameimage_left; +// if int1 > left then begin + left:= int1; +// end; + end; + if not (edg_right in afi.hiddenedges) then begin + int1:= afi.frameimage_list.width + afi.frameimage_right; +// if int1 > right then begin + right:= int1; +// end; + end; + if not (edg_top in afi.hiddenedges) then begin + int1:= afi.frameimage_list.height + afi.frameimage_top; +// if int1 > top then begin + top:= int1; +// end; + end; + if not (edg_bottom in afi.hiddenedges) then begin + int1:= afi.frameimage_list.height + afi.frameimage_bottom; +// if int1 > bottom then begin + bottom:= int1; +// end; + end; + end; + end; +end; + +class function tcustomframe.calcinnerframe(const afi: baseframeinfoty): framety; +begin + result:= calcpaintframe(afi); + result.left:= result.left + afi.innerframe.left; + result.top:= result.top + afi.innerframe.top; + result.right:= result.right + afi.innerframe.right; + result.bottom:= result.bottom + afi.innerframe.bottom; +end; + +procedure tcustomframe.calcrects; +begin + fwidth:= calcpaintframe(fi); + fpaintframedelta:= nullframe; + getpaintframe(fpaintframedelta); + fpaintframe:= addframe(fpaintframedelta,fouterframe); + addframe1(fpaintframe,fwidth); + finnerframe:= addframe(fpaintframe,fi.innerframe); + fpaintrect.pos:= pointty(fpaintframe.topleft); + fpaintrect.size:= fintf.getwidgetrect.size; + fpaintrect.cx:= fpaintrect.cx - fpaintframe.left - fpaintframe.right; + fpaintrect.cy:= fpaintrect.cy - fpaintframe.top - fpaintframe.bottom; + if not (fs_paintposinited in fstate) then begin + fpaintposbefore:= fpaintrect.pos; + include(fstate,fs_paintposinited); + end; +end; + +procedure tcustomframe.updaterects; +begin + calcrects; +end; + +procedure tcustomframe.updatestate(); +var + po1: pointty; +begin + include(fstate,fs_rectsvalid); //avoid recursion + updaterects; + if not (fs_widgetregionchanging in fstate) then begin + if not (csreading in fintf.getcomponentstate) and + not (fs_nowidget in fstate) then begin + po1:= subpoint(fpaintrect.pos,fpaintposbefore); + fintf.scrollwidgets(po1); + end; + fpaintposbefore:= fpaintrect.pos; + updateclientrect; + include(fstate,fs_rectsvalid); + if not (fs_clientrectchanging in fstate) then begin + include(fstate,fs_clientrectchanging); + try + fintf.clientrectchanged; + finally + exclude(fstate,fs_clientrectchanging); + end; + end; + end + else begin + updateclientrect(); + include(fstate,fs_rectsvalid); + end; +end; + +procedure tcustomframe.internalupdatestate(); +begin + exclude(fstate,fs_rectsvalid); + if not (csloading in fintf.getcomponentstate) then begin + if not (fs_stateupdating in fstate) then begin + include(fstate,fs_stateupdating); + try + updatestate; + finally + exclude(fstate,fs_stateupdating); + end; + end; + end; + exclude(fstate,fs_creating); +end; + +procedure tcustomframe.checkstate; +begin + if not (fs_rectsvalid in fstate) then begin + updatestate; + end; +end; + +procedure tcustomframe.setlocalprops(const avalue: framelocalpropsty); +var + widget1: twidget; +begin + if flocalprops <> avalue then begin + flocalprops:= avalue; + if ftemplate <> nil then begin + settemplateinfo(ftemplate.template.fi); + end; + if not (frl_nodisable in flocalprops) then begin + widget1:= fintf.getwidget; + if not (csloading in widget1.componentstate) and not widget1.isenabled then begin + setdisabled(true); + end + else begin + setdisabled(false); + end; + end + else begin + setdisabled(false); + end; + end; +end; + +procedure tcustomframe.setlocalprops1(const avalue: framelocalprops1ty); +begin + if flocalprops1 <> avalue then begin + flocalprops1:= avalue; + if ftemplate <> nil then begin + settemplateinfo(ftemplate.template.fi); + end; + end; +end; + +procedure tcustomframe.setlevelo(const Value: integer); +begin + include(flocalprops,frl_levelo); + if fi.levelo <> value then begin + fi.levelo := Value; + internalupdatestate; + end; +end; + +procedure tcustomframe.setleveli(const Value: integer); +begin + include(flocalprops,frl_leveli); + if fi.leveli <> value then begin + fi.leveli := Value; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframewidth(const Value: integer); +begin + include(flocalprops,frl_framewidth); + if fi.framewidth <> value then begin + if value < 0 then begin + fi.framewidth:= 0; + end + else begin + fi.framewidth := Value; + end; + internalupdatestate; + end; +end; +{ +procedure tcustomframe.setextraspace(const avalue: integer); +begin + if fi.extraspace <> avalue then begin + include(flocalprops,frl_extraspace); + fi.extraspace:= avalue; + internalupdatestate; + end; +end; +} +procedure tcustomframe.setframei_left(const Value: integer); +begin + include(flocalprops,frl_fileft); + if fi.innerframe.left <> value then begin + fi.innerframe.left:= Value; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframei_top(const Value: integer); +begin + include(flocalprops,frl_fitop); + if fi.innerframe.top <> value then begin + fi.innerframe.top := Value; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframei_right(const Value: integer); +begin + include(flocalprops,frl_firight); + if fi.innerframe.right <> value then begin + fi.innerframe.right:= Value; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframei_bottom(const Value: integer); +begin + include(flocalprops,frl_fibottom); + if fi.innerframe.bottom <> value then begin + fi.innerframe.bottom:= Value; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframei(const avalue: framety); +begin + fi.innerframe:= avalue; + internalupdatestate; +end; + +procedure tcustomframe.setframeo_left(const Value: integer); +begin + include(flocalprops1,frl1_foleft); + if fi.outerframe.left <> value then begin + fi.outerframe.left:= Value; + internalupdatestate(); + end; +end; + +procedure tcustomframe.setframeo_top(const Value: integer); +begin + include(flocalprops1,frl1_fotop); + if fi.outerframe.top <> value then begin + fi.outerframe.top:= Value; + internalupdatestate(); + end; +end; + +procedure tcustomframe.setframeo_right(const Value: integer); +begin + include(flocalprops1,frl1_foright); + if fi.outerframe.right <> value then begin + fi.outerframe.right:= Value; + internalupdatestate(); + end; +end; + +procedure tcustomframe.setframeo_bottom(const Value: integer); +begin + include(flocalprops1,frl1_fobottom); + if fi.outerframe.bottom <> value then begin + fi.outerframe.bottom:= Value; + internalupdatestate(); + end; +end; + +procedure tcustomframe.setframeo(const avalue: framety); +begin + fi.outerframe:= avalue; + internalupdatestate; +end; + +procedure tcustomframe.setframeimage_list(const avalue: timagelist); +begin + include(flocalprops,frl_frameimagelist); + if fi.frameimage_list <> avalue then begin + fintf.getwidget.setlinkedvar(avalue,tmsecomponent(fi.frameimage_list)); + internalupdatestate; + end; +end; + +procedure tcustomframe.setfocusrectdist(const avalue: int32); +begin + include(flocalprops1,frl1_focusrectdist); + if fi.focusrectdist <> avalue then begin + fi.focusrectdist:= avalue; + internalupdatestate(); + end; +end; + +procedure tcustomframe.setextraspace(const avalue: int32); +begin + include(flocalprops1,frl1_extraspace); + if fi.extraspace <> avalue then begin + fi.extraspace:= avalue; + internalupdatestate(); + end; +end; + +procedure tcustomframe.setimagedist(const avalue: int32); +begin + include(flocalprops1,frl1_imagedist); + if fi.imagedist <> avalue then begin + fi.imagedist:= avalue; + internalupdatestate(); + end; +end; + +procedure tcustomframe.setimagedist1(const avalue: int32); +begin + include(flocalprops1,frl1_imagedist1); + if fi.imagedist1 <> avalue then begin + fi.imagedist1:= avalue; + internalupdatestate(); + end; +end; + +procedure tcustomframe.setimagedist2(const avalue: int32); +begin + include(flocalprops1,frl1_imagedist2); + if fi.imagedist2 <> avalue then begin + fi.imagedist2:= avalue; + internalupdatestate(); + end; +end; + +function tcustomframe.getimagelist: timagelist; +begin + result:= fi.frameimage_list; +end; + +procedure tcustomframe.setframeimage_left(const avalue: integer); +begin + include(flocalprops,frl_frameimageleft); + if fi.frameimage_left <> avalue then begin + fi.frameimage_left:= avalue; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframeimage_right(const avalue: integer); +begin + include(flocalprops,frl_frameimageright); + if fi.frameimage_right <> avalue then begin + fi.frameimage_right:= avalue; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframeimage_top(const avalue: integer); +begin + include(flocalprops,frl_frameimagetop); + if fi.frameimage_top <> avalue then begin + fi.frameimage_top:= avalue; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframeimage_bottom(const avalue: integer); +begin + include(flocalprops,frl_frameimagebottom); + if fi.frameimage_bottom <> avalue then begin + fi.frameimage_bottom:= avalue; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframeimage_offset(const avalue: imagenrty); +begin + include(flocalprops,frl_frameimageoffset); + if fi.frameimage_offsets.offset <> avalue then begin + fi.frameimage_offsets.offset:= avalue; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframeimage_offset1(const avalue: imagenrty); +begin + include(flocalprops,frl_frameimageoffset1); + if fi.frameimage_offsets.offset1 <> avalue then begin + fi.frameimage_offsets.offset1:= avalue; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframeimage_offsetdisabled(const avalue: imagenrty); +begin + include(flocalprops,frl_frameimageoffsetdisabled); + if fi.frameimage_offsets.disabled <> avalue then begin + fi.frameimage_offsets.disabled:= avalue; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframeimage_offsetmouse(const avalue: imagenrty); +begin + include(flocalprops,frl_frameimageoffsetmouse); + if fi.frameimage_offsets.mouse <> avalue then begin + fi.frameimage_offsets.mouse:= avalue; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframeimage_offsetclicked(const avalue: imagenrty); +begin + include(flocalprops,frl_frameimageoffsetclicked); + if fi.frameimage_offsets.clicked <> avalue then begin + fi.frameimage_offsets.clicked:= avalue; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframeimage_offsetfocused(const avalue: imagenrty); +begin + include(flocalprops,frl_frameimageoffsetfocused); + if fi.frameimage_offsets.focused <> avalue then begin + fi.frameimage_offsets.focused:= avalue; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframeimage_offsetactive(const avalue: imagenrty); +begin + include(flocalprops,frl_frameimageoffsetactive); + if fi.frameimage_offsets.active <> avalue then begin + fi.frameimage_offsets.active:= avalue; + internalupdatestate; + end; +end; +{ +procedure tcustomframe.setframeimage_offsetactivemouse(const avalue: imagenrty); +begin + include(flocalprops,frl_frameimageoffsetactivemouse); + if fi.frameimage_offsets.activemouse <> avalue then begin + fi.frameimage_offsets.activemouse:= avalue; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframeimage_offsetactiveclicked(const avalue: imagenrty); +begin + include(flocalprops,frl_frameimageoffsetactiveclicked); + if fi.frameimage_offsets.activeclicked <> avalue then begin + fi.frameimage_offsets.activeclicked:= avalue; + internalupdatestate; + end; +end; +} +procedure tcustomframe.setframeface_list(const avalue: tfacelist); +begin + include(flocalprops1,frl1_framefacelist); + if fi.frameface_list <> avalue then begin + fintf.getwidget.setlinkedvar(avalue,tmsecomponent(fi.frameface_list)); + internalupdatestate; + end; +end; + +procedure tcustomframe.setframeface_offset(const avalue: facenrty); +begin + include(flocalprops1,frl1_framefaceoffset); + if fi.frameface_offsets.offset <> avalue then begin + fi.frameface_offsets.offset:= avalue; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframeface_offset1(const avalue: facenrty); +begin + include(flocalprops1,frl1_framefaceoffset1); + if fi.frameface_offsets.offset1 <> avalue then begin + fi.frameface_offsets.offset1:= avalue; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframeface_offsetdisabled(const avalue: facenrty); +begin + include(flocalprops1,frl1_framefaceoffsetdisabled); + if fi.frameface_offsets.disabled <> avalue then begin + fi.frameface_offsets.disabled:= avalue; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframeface_offsetmouse(const avalue: facenrty); +begin + include(flocalprops1,frl1_framefaceoffsetmouse); + if fi.frameface_offsets.mouse <> avalue then begin + fi.frameface_offsets.mouse:= avalue; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframeface_offsetclicked(const avalue: facenrty); +begin + include(flocalprops1,frl1_framefaceoffsetclicked); + if fi.frameface_offsets.clicked <> avalue then begin + fi.frameface_offsets.clicked:= avalue; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframeface_offsetfocused(const avalue: facenrty); +begin + include(flocalprops1,frl1_framefaceoffsetfocused); + if fi.frameface_offsets.focused <> avalue then begin + fi.frameface_offsets.focused:= avalue; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframeface_offsetactive(const avalue: facenrty); +begin + include(flocalprops1,frl1_framefaceoffsetactive); + if fi.frameface_offsets.active <> avalue then begin + fi.frameface_offsets.active:= avalue; + internalupdatestate; + end; +end; +{ +procedure tcustomframe.setframeface_offsetactivemouse(const avalue: facenrty); +begin + include(flocalprops1,frl1_framefaceoffsetactivemouse); + if fi.frameface_offsets.activemouse <> avalue then begin + fi.frameface_offsets.activemouse:= avalue; + internalupdatestate; + end; +end; + +procedure tcustomframe.setframeface_offsetactiveclicked(const avalue: facenrty); +begin + include(flocalprops1,frl1_framefaceoffsetactiveclicked); + if fi.frameface_offsets.activeclicked <> avalue then begin + fi.frameface_offsets.activeclicked:= avalue; + internalupdatestate; + end; +end; +} +procedure tcustomframe.setoptionsskin(const avalue: frameskinoptionsty); +begin + include(flocalprops,frl_optionsskin); + if fi.optionsskin <> avalue then begin + fi.optionsskin:= avalue; + internalupdatestate; + end; +end; + +procedure tcustomframe.setcolorclient(const value: colorty); +begin + include(flocalprops,frl_colorclient); + if fi.colorclient <> value then begin + fi.colorclient:= value; + fintf.invalidate; + end; +end; + +procedure tcustomframe.setcolorframe(const Value: colorty); +begin + include(flocalprops,frl_colorframe); + if fi.colorframe <> value then begin + fi.colorframe:= Value; + fintf.invalidatewidget; + end; +end; + +procedure tcustomframe.setcolorframeactive(const avalue: colorty); +begin + include(flocalprops,frl_colorframeactive); + if fi.colorframeactive <> avalue then begin + fi.colorframeactive:= avalue; + fintf.invalidatewidget; + end; +end; + + +procedure tcustomframe.setcolorframedisabled(const avalue: colorty); +begin + include(flocalprops1,frl1_colorframedisabled); + if fi.colorframedisabled <> avalue then begin + fi.colorframedisabled:= avalue; + fintf.invalidatewidget; + end; +end; + +procedure tcustomframe.setcolorframemouse(const avalue: colorty); +begin + include(flocalprops1,frl1_colorframemouse); + if fi.colorframemouse <> avalue then begin + fi.colorframemouse:= avalue; + fintf.invalidatewidget; + end; +end; + +procedure tcustomframe.setcolorframeclicked(const avalue: colorty); +begin + include(flocalprops1,frl1_colorframeclicked); + if fi.colorframeclicked <> avalue then begin + fi.colorframeclicked:= avalue; + fintf.invalidatewidget; + end; +end; + +procedure tcustomframe.setcolorframedefault(const avalue: colorty); +begin + include(flocalprops1,frl1_colorframedefault); + if fi.colorframedefault <> avalue then begin + fi.colorframedefault:= avalue; + fintf.invalidatewidget; + end; +end; + +procedure tcustomframe.setcolordkshadow(const avalue: colorty); +begin + include(flocalprops,frl_colordkshadow); + if fi.framecolors.edges.shadow.effectcolor <> avalue then begin + fi.framecolors.edges.shadow.effectcolor:= avalue; + fintf.invalidatewidget; + end; +end; + +procedure tcustomframe.setcolorshadow(const avalue: colorty); +begin + include(flocalprops,frl_colorshadow); + if fi.framecolors.edges.shadow.color <> avalue then begin + fi.framecolors.edges.shadow.color:= avalue; + fintf.invalidatewidget; + end; +end; + +procedure tcustomframe.setcolorlight(const avalue: colorty); +begin + include(flocalprops,frl_colorlight); + if fi.framecolors.edges.light.color <> avalue then begin + fi.framecolors.edges.light.color:= avalue; + fintf.invalidatewidget; + end; +end; + +procedure tcustomframe.setcolorhighlight(const avalue: colorty); +begin + include(flocalprops,frl_colorhighlight); + if fi.framecolors.edges.light.effectcolor <> avalue then begin + fi.framecolors.edges.light.effectcolor:= avalue; + fintf.invalidatewidget; + end; +end; + +procedure tcustomframe.setcolordkwidth(const avalue: integer); +begin + include(flocalprops,frl_colordkwidth); + if fi.framecolors.edges.shadow.effectwidth <> avalue then begin + fi.framecolors.edges.shadow.effectwidth:= avalue; + fintf.invalidatewidget; + end; +end; + +procedure tcustomframe.setcolorhlwidth(const avalue: integer); +begin + include(flocalprops,frl_colorhlwidth); + if fi.framecolors.edges.light.effectwidth <> avalue then begin + fi.framecolors.edges.light.effectwidth:= avalue; + fintf.invalidatewidget; + end; +end; + +procedure tcustomframe.sethiddenedges(const avalue: edgesty); +begin + include(flocalprops,frl_hiddenedges); + if fi.hiddenedges <> avalue then begin + fi.hiddenedges:= avalue; + internalupdatestate; +// fintf.invalidatewidget; + end; +end; + +procedure tcustomframe.settemplate(const avalue: tframecomp); +begin + fintf.getwidget.setlinkedvar(avalue,tmsecomponent(ftemplate)); +// if (avalue <> nil) and not (csloading in avalue.componentstate) then begin + if (avalue <> nil) and not (csreading in avalue.componentstate) then begin + assign(avalue); + end; +end; +{ +function tcustomframe.arepropsstored: boolean; +begin + result:= ftemplate = nil; +end; +} +procedure tcustomframe.settemplateinfo(const ainfo: frameinfoty); +begin + with fi do begin + if not (frl_levelo in flocalprops) then begin + levelo:= ainfo.ba.levelo; + end; + if not (frl_leveli in flocalprops) then begin + leveli:= ainfo.ba.leveli; + end; + if not (frl_framewidth in flocalprops) then begin + framewidth:= ainfo.ba.framewidth; + end; +// if not (frl_extraspace in flocalprops) then begin +// extraspace:= ainfo.extraspace; +// end; + if not (frl_colorframe in flocalprops) then begin + colorframe:= ainfo.ba.colorframe; + end; + if not (frl_colorframeactive in flocalprops) then begin + colorframeactive:= ainfo.ba.colorframeactive; + end; + if not (frl1_colorframedisabled in flocalprops1) then begin + colorframedisabled:= ainfo.ba.colorframedisabled; + end; + if not (frl1_colorframemouse in flocalprops1) then begin + colorframemouse:= ainfo.ba.colorframemouse; + end; + if not (frl1_colorframeclicked in flocalprops1) then begin + colorframeclicked:= ainfo.ba.colorframeclicked; + end; + if not (frl1_colorframedefault in flocalprops1) then begin + colorframedefault:= ainfo.ba.colorframedefault; + end; + with framecolors.edges do begin + if not (frl_colordkshadow in flocalprops) then begin + shadow.effectcolor:= ainfo.ba.framecolors.edges.shadow.effectcolor; + end; + if not (frl_colorshadow in flocalprops) then begin + shadow.color:= ainfo.ba.framecolors.edges.shadow.color; + end; + if not (frl_colorlight in flocalprops) then begin + light.color:= ainfo.ba.framecolors.edges.light.color; + end; + if not (frl_colorhighlight in flocalprops) then begin + light.effectcolor:= ainfo.ba.framecolors.edges.light.effectcolor; + end; + if not (frl_colordkwidth in flocalprops) then begin + shadow.effectwidth:= ainfo.ba.framecolors.edges.shadow.effectwidth; + end; + if not (frl_colorhlwidth in flocalprops) then begin + light.effectwidth:= ainfo.ba.framecolors.edges.light.effectwidth; + end; + end; + if not (frl_hiddenedges in flocalprops) then begin + hiddenedges:= ainfo.ba.hiddenedges; + end; + if not (frl_fileft in flocalprops) then begin + innerframe.left:= ainfo.ba.innerframe.left; + end; + if not (frl_fitop in flocalprops) then begin + innerframe.top:= ainfo.ba.innerframe.top; + end; + if not (frl_firight in flocalprops) then begin + innerframe.right:= ainfo.ba.innerframe.right; + end; + if not (frl_fibottom in flocalprops) then begin + innerframe.bottom:= ainfo.ba.innerframe.bottom; + end; + + if not (frl1_foleft in flocalprops1) then begin + outerframe.left:= ainfo.ba.outerframe.left; + end; + if not (frl1_fotop in flocalprops1) then begin + outerframe.top:= ainfo.ba.outerframe.top; + end; + if not (frl1_foright in flocalprops1) then begin + outerframe.right:= ainfo.ba.outerframe.right; + end; + if not (frl1_fobottom in flocalprops1) then begin + outerframe.bottom:= ainfo.ba.outerframe.bottom; + end; + + if not (frl_frameimagelist in flocalprops) then begin + fintf.getwidget.setlinkedvar(ainfo.ba.frameimage_list, + tmsecomponent(frameimage_list)); + end; + if not (frl_frameimageleft in flocalprops) then begin + frameimage_left:= ainfo.ba.frameimage_left; + end; + if not (frl_frameimageright in flocalprops) then begin + frameimage_right:= ainfo.ba.frameimage_right; + end; + if not (frl_frameimagetop in flocalprops) then begin + frameimage_top:= ainfo.ba.frameimage_top; + end; + if not (frl_frameimagebottom in flocalprops) then begin + frameimage_bottom:= ainfo.ba.frameimage_bottom; + end; + with frameimage_offsets do begin + if not (frl_frameimageoffset in flocalprops) then begin + offset:= ainfo.ba.frameimage_offsets.offset; + end; + if not (frl_frameimageoffsetdisabled in flocalprops) then begin + disabled:= ainfo.ba.frameimage_offsets.disabled; + end; + if not (frl_frameimageoffsetmouse in flocalprops) then begin + mouse:= ainfo.ba.frameimage_offsets.mouse; + end; + if not (frl_frameimageoffsetclicked in flocalprops) then begin + clicked:= ainfo.ba.frameimage_offsets.clicked; + end; + if not (frl_frameimageoffsetfocused in flocalprops) then begin + focused:= ainfo.ba.frameimage_offsets.focused; + end; + if not (frl_frameimageoffsetactive in flocalprops) then begin + active:= ainfo.ba.frameimage_offsets.active; + end; + { + if not (frl_frameimageoffsetactivemouse in flocalprops) then begin + activemouse:= ainfo.ba.frameimage_offsets.activemouse; + end; + if not (frl_frameimageoffsetactiveclicked in flocalprops) then begin + activeclicked:= ainfo.ba.frameimage_offsets.activeclicked; + end; + } + end; + + if not (frl1_framefacelist in flocalprops1) then begin + fintf.getwidget.setlinkedvar(ainfo.ba.frameface_list, + tmsecomponent(frameface_list)); + end; + with frameface_offsets do begin + if not (frl1_framefaceoffset in flocalprops1) then begin + offset:= ainfo.ba.frameface_offsets.offset; + end; + if not (frl1_framefaceoffsetdisabled in flocalprops1) then begin + disabled:= ainfo.ba.frameface_offsets.disabled; + end; + if not (frl1_framefaceoffsetmouse in flocalprops1) then begin + mouse:= ainfo.ba.frameface_offsets.mouse; + end; + if not (frl1_framefaceoffsetclicked in flocalprops1) then begin + clicked:= ainfo.ba.frameface_offsets.clicked; + end; + if not (frl1_framefaceoffsetfocused in flocalprops1) then begin + focused:= ainfo.ba.frameface_offsets.focused; + end; + if not (frl1_framefaceoffsetactive in flocalprops1) then begin + active:= ainfo.ba.frameface_offsets.active; + end; + { + if not (frl1_framefaceoffsetactivemouse in flocalprops1) then begin + activemouse:= ainfo.ba.frameface_offsets.activemouse; + end; + if not (frl1_framefaceoffsetactiveclicked in flocalprops1) then begin + activeclicked:= ainfo.ba.frameface_offsets.activeclicked; + end; + } + end; + + if not (frl1_focusrectdist in flocalprops1) then begin + focusrectdist:= ainfo.ba.focusrectdist; + end; + if not (frl1_extraspace in flocalprops1) then begin + extraspace:= ainfo.ba.extraspace; + end; + if not (frl1_imagedist in flocalprops1) then begin + imagedist:= ainfo.ba.imagedist; + end; + if not (frl1_imagedist1 in flocalprops1) then begin + imagedist1:= ainfo.ba.imagedist1; + end; + if not (frl1_imagedist2 in flocalprops1) then begin + imagedist2:= ainfo.ba.imagedist2; + end; + + if not (frl_optionsskin in flocalprops) then begin + optionsskin:= ainfo.ba.optionsskin; + end; + + if not (frl_colorclient in flocalprops) then begin + colorclient:= ainfo.ba.colorclient; + end; + end; + internalupdatestate; +end; + +procedure tcustomframe.getpaintframe(var frame: framety); +begin + //dummy +end; + +function tcustomframe.outerframedim: sizety; +begin + checkstate(); + result.cx:= fouterframe.left + fouterframe.right; + result.cy:= fouterframe.top + fouterframe.bottom; +end; + +function tcustomframe.outerframecx: int32; +begin + checkstate(); + result:= fouterframe.left + fouterframe.right; +end; + +function tcustomframe.outerframecy: int32; +begin + checkstate(); + result:= fouterframe.top + fouterframe.bottom; +end; + +function tcustomframe.frameframedim: sizety; +begin + checkstate(); + result.cx:= fouterframe.left + fwidth.left + fwidth.right + fouterframe.right; + result.cy:= fouterframe.top + fwidth.top + fwidth.bottom + fouterframe.bottom; +end; + +function tcustomframe.frameframecx: int32; +begin + checkstate(); + result:= fouterframe.left + fwidth.left + fwidth.right + fouterframe.right; +end; + +function tcustomframe.frameframecy: int32; +begin + checkstate(); + result:= fouterframe.top + fwidth.top + fwidth.bottom + fouterframe.bottom; +end; + +function tcustomframe.paintframedim: sizety; +begin + checkstate(); + result.cx:= fpaintframe.left + fpaintframe.right; + result.cy:= fpaintframe.top + fpaintframe.bottom; +end; + +function tcustomframe.paintframecx: int32; +begin + checkstate(); + result:= fpaintframe.left + fpaintframe.right; +end; + +function tcustomframe.paintframecy: int32; +begin + checkstate(); + result:= fpaintframe.top + fpaintframe.bottom; +end; + +function tcustomframe.innerframedim: sizety; +begin + checkstate(); + result.cx:= finnerframe.left + finnerframe.right; + result.cy:= finnerframe.top + finnerframe.bottom; +// result.cx:= fouterframe.left + fpaintframe.left + fi.innerframe.left + +// fpaintframe.right + fouterframe.right + fi.innerframe.right; +// result.cy:= fouterframe.top + fpaintframe.top + fi.innerframe.top + +// fpaintframe.bottom + fouterframe.bottom + fi.innerframe.bottom; +end; + +function tcustomframe.innerframecx: int32; +begin + checkstate(); + result:= finnerframe.left + finnerframe.right; +end; + +function tcustomframe.innerframecy: int32; +begin + checkstate(); + result:= finnerframe.top + finnerframe.bottom; +end; + +function tcustomframe.outerframe: framety; +begin + checkstate; + result:= fouterframe; +end; + +function tcustomframe.paintframe: framety; +begin + checkstate; + result:= fpaintframe; +// result:= addframe(fouterframe,fpaintframe); +end; + +function tcustomframe.paintframedelta: framety; +begin + result:= subframe(paintframe,fouterframe); +end; + +function tcustomframe.innerframe: framety; +begin + checkstate; + result:= finnerframe; +// result:= addframe(fouterframe,fpaintframe); +// addframe1(result,fi.innerframe); +end; + +procedure tcustomframe.checktemplate(const sender: tobject); +begin + if sender = ftemplate then begin + assign(tpersistent(sender)); + end; +end; + +procedure tcustomframe.assign(source: tpersistent); +begin + if source is tcustomframe then begin + if not (csdesigning in fintf.getcomponentstate) then begin + flocalprops:= allframelocalprops; + flocalprops1:= allframelocalprops1; + fi:= tcustomframe(source).fi; + internalupdatestate; + end; + end + else begin + inherited; + end; +end; + +procedure tcustomframe.dokeydown(var info: keyeventinfoty); +begin + //dummy +end; + +procedure tcustomframe.poschanged; +begin + //dummy +end; + +procedure tcustomframe.visiblechanged; +begin + //dummy +end; + +procedure tcustomframe.parentfontchanged; +begin + //dummy +end; + +procedure tcustomframe.setdisabled(const value: boolean); +begin + updatebit({$ifdef FPC}longword{$else}longword{$endif}(fstate), + ord(fs_disabled),value); + with fi do begin + if (frameimage_list <> nil) and (frameimage_offsetdisabled <> 0) or + (frameface_list <> nil) and (frameface_offsetdisabled <> 0) then begin + fintf.getwidget.invalidatewidget; + end; + end; +end; + +function tcustomframe.pointincaption(const point: pointty): boolean; +begin + result:= false; //dummy +end; + +procedure tcustomframe.initgridframe; +begin + leveli:= 0; + levelo:= 0; + colorclient:= cl_transparent; +end; + +function tcustomframe.islevelostored: boolean; +begin + result:= (ftemplate = nil) or (frl_levelo in flocalprops); +end; + +function tcustomframe.islevelistored: boolean; +begin + result:= (ftemplate = nil) or (frl_leveli in flocalprops); +end; + +function tcustomframe.isframewidthstored: boolean; +begin + result:= (ftemplate = nil) or (frl_framewidth in flocalprops); +end; + +function tcustomframe.iscolorframestored: boolean; +begin + result:= (ftemplate = nil) or (frl_colorframe in flocalprops); +end; + +function tcustomframe.iscolorframeactivestored: boolean; +begin + result:= (ftemplate = nil) or (frl_colorframeactive in flocalprops); +end; + +function tcustomframe.iscolorframedisabledstored: boolean; +begin + result:= (ftemplate = nil) or (frl1_colorframedisabled in flocalprops1); +end; + +function tcustomframe.iscolorframemousestored: boolean; +begin + result:= (ftemplate = nil) or (frl1_colorframemouse in flocalprops1); +end; + +function tcustomframe.iscolorframeclickedstored: boolean; +begin + result:= (ftemplate = nil) or (frl1_colorframeclicked in flocalprops1); +end; + +function tcustomframe.iscolorframedefaultstored: boolean; +begin + result:= (ftemplate = nil) or (frl1_colorframedefault in flocalprops1); +end; + +function tcustomframe.iscolordkshadowstored: boolean; +begin + result:= (ftemplate = nil) or (frl_colordkshadow in flocalprops); +end; + +function tcustomframe.iscolorshadowstored: boolean; +begin + result:= (ftemplate = nil) or (frl_colorshadow in flocalprops); +end; + +function tcustomframe.iscolorlightstored: boolean; +begin + result:= (ftemplate = nil) or (frl_colorlight in flocalprops); +end; + +function tcustomframe.iscolorhighlightstored: boolean; +begin + result:= (ftemplate = nil) or (frl_colorhighlight in flocalprops); +end; + +function tcustomframe.iscolordkwidthstored: boolean; +begin + result:= (ftemplate = nil) or (frl_colordkwidth in flocalprops); +end; + +function tcustomframe.iscolorhlwidthstored: boolean; +begin + result:= (ftemplate = nil) or (frl_colorhlwidth in flocalprops); +end; + +function tcustomframe.ishiddenedgesstored: boolean; +begin + result:= (ftemplate = nil) or (frl_hiddenedges in flocalprops); +end; + +function tcustomframe.isfibottomstored: boolean; +begin + result:= (ftemplate = nil) or (frl_fibottom in flocalprops); +end; + +function tcustomframe.isfileftstored: boolean; +begin + result:= (ftemplate = nil) or (frl_fileft in flocalprops); +end; + +function tcustomframe.isfirightstored: boolean; +begin + result:= (ftemplate = nil) or (frl_firight in flocalprops); +end; + +function tcustomframe.isfitopstored: boolean; +begin + result:= (ftemplate = nil) or (frl_fitop in flocalprops); +end; + +function tcustomframe.isfobottomstored: boolean; +begin + result:= (ftemplate = nil) or (frl1_fobottom in flocalprops1); +end; + +function tcustomframe.isfoleftstored: boolean; +begin + result:= (ftemplate = nil) or (frl1_foleft in flocalprops1); +end; + +function tcustomframe.isforightstored: boolean; +begin + result:= (ftemplate = nil) or (frl1_foright in flocalprops1); +end; + +function tcustomframe.isfotopstored: boolean; +begin + result:= (ftemplate = nil) or (frl1_fotop in flocalprops1); +end; + +function tcustomframe.isframeimage_liststored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameimage_list <> nil) or + (frl_frameimagelist in flocalprops); +end; + +function tcustomframe.isframeimage_leftstored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameimage_left <> 0) or + (frl_frameimageleft in flocalprops); +end; + +function tcustomframe.isframeimage_rightstored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameimage_right <> 0) or + (frl_frameimageright in flocalprops); +end; + +function tcustomframe.isframeimage_topstored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameimage_top <> 0) or + (frl_frameimagetop in flocalprops); +end; + +function tcustomframe.isframeimage_bottomstored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameimage_bottom <> 0) or + (frl_frameimagebottom in flocalprops); +end; + +function tcustomframe.isframeimage_offsetstored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameimage_offsets.offset <> 0) or + (frl_frameimageoffset in flocalprops); +end; + +function tcustomframe.isframeimage_offset1stored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameimage_offsets.offset1 <> 0) or + (frl_frameimageoffset1 in flocalprops); +end; + +function tcustomframe.isframeimage_offsetdisabledstored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameimage_offsets.disabled <> 0) or + (frl_frameimageoffsetdisabled in flocalprops); +end; + +function tcustomframe.isframeimage_offsetmousestored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameimage_offsets.mouse <> 0) or + (frl_frameimageoffsetmouse in flocalprops); +end; + +function tcustomframe.isframeimage_offsetclickedstored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameimage_offsets.clicked <> 0) or + (frl_frameimageoffsetclicked in flocalprops); +end; + +function tcustomframe.isframeimage_offsetfocusedstored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameimage_offsets.focused <> 0) or + (frl_frameimageoffsetfocused in flocalprops); +end; + +function tcustomframe.isframeimage_offsetactivestored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameimage_offsets.active <> 0) or + (frl_frameimageoffsetactive in flocalprops); +end; +{ +function tcustomframe.isframeimage_offsetactivemousestored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameimage_offsets.activemouse <> 0) or + (frl_frameimageoffsetactivemouse in flocalprops); +end; + +function tcustomframe.isframeimage_offsetactiveclickedstored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameimage_offsets.activeclicked <> 0) or + (frl_frameimageoffsetactiveclicked in flocalprops); +end; +} +function tcustomframe.isframeface_liststored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameface_list <> nil) or + (frl1_framefacelist in flocalprops1); +end; + +function tcustomframe.isframeface_offsetstored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameface_offsets.offset <> 0) or + (frl1_framefaceoffset in flocalprops1); +end; + +function tcustomframe.isframeface_offset1stored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameface_offsets.offset1 <> 0) or + (frl1_framefaceoffset1 in flocalprops1); +end; + +function tcustomframe.isframeface_offsetdisabledstored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameface_offsets.disabled <> 0) or + (frl1_framefaceoffsetdisabled in flocalprops1); +end; + +function tcustomframe.isframeface_offsetmousestored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameface_offsets.mouse <> 0) or + (frl1_framefaceoffsetmouse in flocalprops1); +end; + +function tcustomframe.isframeface_offsetclickedstored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameface_offsets.clicked <> 0) or + (frl1_framefaceoffsetclicked in flocalprops1); +end; + +function tcustomframe.isframeface_offsetfocusedstored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameface_offsets.focused <> 0) or + (frl1_framefaceoffsetfocused in flocalprops1); +end; + +function tcustomframe.isframeface_offsetactivestored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameface_offsets.active <> 0) or + (frl1_framefaceoffsetactive in flocalprops1); +end; +{ +function tcustomframe.isframeface_offsetactivemousestored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameface_offsets.activemouse <> 0) or + (frl1_framefaceoffsetactivemouse in flocalprops1); +end; + +function tcustomframe.isframeface_offsetactiveclickedstored: boolean; +begin + result:= (ftemplate = nil) and (fi.frameface_offsets.activeclicked <> 0) or + (frl1_framefaceoffsetactiveclicked in flocalprops1); +end; +} +function tcustomframe.isoptionsskinstored: boolean; +begin + result:= (ftemplate = nil) or (frl_optionsskin in flocalprops); +end; + +function tcustomframe.iscolorclientstored: boolean; +begin + result:= (ftemplate = nil) or (frl_colorclient in flocalprops); +end; + +function tcustomframe.isfocusrectdiststored: boolean; +begin + result:= (ftemplate = nil) or (frl1_focusrectdist in flocalprops1); +end; + +function tcustomframe.isextraspacestored: boolean; +begin + result:= (ftemplate = nil) or (frl1_extraspace in flocalprops1); +end; + +function tcustomframe.isimagediststored: boolean; +begin + result:= (ftemplate = nil) or (frl1_imagedist in flocalprops1); +end; + +function tcustomframe.isimagedist1stored: boolean; +begin + result:= (ftemplate = nil) or (frl1_imagedist1 in flocalprops1); +end; + +function tcustomframe.isimagedist2stored: boolean; +begin + result:= (ftemplate = nil) or (frl1_imagedist2 in flocalprops1); +end; + +procedure tcustomframe.changedirection(const oldvalue: graphicdirectionty; + const newvalue: graphicdirectionty); +var + int1,int2: integer; + fra1: framety; +begin + int2:= ord(oldvalue)-ord(newvalue); + for int1:= 0 to 3 do begin + pintegeraty(@fra1)^[int1]:= + pintegeraty(@fi.innerframe)^[(int1+int2) and $3]; + end; + framei_left:= fra1.left; + framei_top:= fra1.top; + framei_right:= fra1.right; + framei_bottom:= fra1.bottom; + for int1:= 0 to 3 do begin + pintegeraty(@fra1)^[int1]:= + pintegeraty(@fi.outerframe)^[(int1+int2) and $3]; + end; + frameo_left:= fra1.left; + frameo_top:= fra1.top; + frameo_right:= fra1.right; + frameo_bottom:= fra1.bottom; +end; + +procedure tcustomframe.scale(const ascale: real); +begin + if ascale <> 1 then begin + with fi do begin + leveli:= round(leveli * ascale); + levelo:= round(levelo * ascale); + framewidth:= round(framewidth * ascale); + // extraspace:= round(extraspace * ascale); + framecolors.edges.shadow.effectwidth:= + round(framecolors.edges.shadow.effectwidth*ascale); + framecolors.edges.light.effectwidth:= + round(framecolors.edges.light.effectwidth*ascale); + framei_left:= round(framei_left * ascale); + framei_top:= round(framei_top * ascale); + framei_right:= round(framei_right * ascale); + framei_bottom:= round(framei_bottom * ascale); + focusrectdist:= round(focusrectdist * ascale); + end; + end; +end; + +procedure tcustomframe.fontcanvaschanged; +begin + //dummy +end; + +function tcustomframe.cellframe: framety; +begin + result.left:= finnerframe.left - fpaintframedelta.left; + result.top:= finnerframe.top - fpaintframedelta.top; + result.right:= finnerframe.right - fpaintframedelta.right; + result.bottom:= finnerframe.bottom - fpaintframedelta.bottom; +end; + +procedure tcustomframe.checkwidgetsize(var asize: sizety); +begin + //dummy +end; + +procedure tcustomframe.showhint(const aid: int32; var info: hintinfoty); +begin + //dummy +end; + +procedure tcustomframe.checkminscrollsize(var asize: sizety); +begin + //dummy +end; + +procedure tcustomframe.checkminclientsize(var asize: sizety); +begin + checkstate; + if not (fs_canclientextendx in fstate) or (asize.cx < fpaintrect.cx) then begin + asize.cx:= fpaintrect.cx; + end; + if not (fs_canclientextendy in fstate) or (asize.cy < fpaintrect.cy) then begin + asize.cy:= fpaintrect.cy; + end; +end; + +procedure tcustomframe.checkminshrinksize(var asize: sizety); +begin + //dummy +end; + +procedure tcustomframe.addscrollbarwidth(var asize: sizety); +begin + //dummy +end; + +procedure tcustomframe.subscrollbarwidth(var asize: sizety); +begin + //dummy +end; + +function tcustomframe.isoptional: boolean; +begin + result:= not fintf.getstaticframe; +end; + +procedure tcustomframe.defineproperties(filer: tfiler); +begin + filer.defineproperty('dummy',@readdummy,nil,false); + filer.defineproperty('frameimage_offsetactivemouse',@readdummy,nil,false); + filer.defineproperty('frameimage_offsetactiveclicked',@readdummy,nil,false); + filer.defineproperty('frameface_offsetactivemouse',@readdummy,nil,false); + filer.defineproperty('frameface_offsetactiveclicked',@readdummy,nil,false); + // inherited; //no dummy necessary because of localprops +end; + +{ tframetemplate } + +constructor tframetemplate.create(const owner: tmsecomponent; + const onchange: notifyeventty); +begin + initframeinfo(fi.ba); + initframeinfo(fi.capt); + inherited; +end; + +destructor tframetemplate.destroy; +begin + inherited; + fi.capt.font.free; +end; + +procedure tframetemplate.setcolorclient(const Value: colorty); +begin + fi.ba.colorclient:= Value; + changed; +end; + +procedure tframetemplate.setcolorframe(const Value: colorty); +begin + fi.ba.colorframe:= Value; + changed; +end; + +procedure tframetemplate.setcolorframeactive(const avalue: colorty); +begin + fi.ba.colorframeactive:= avalue; + changed; +end; + +procedure tframetemplate.setcolorframedisabled(const avalue: colorty); +begin + fi.ba.colorframedisabled:= avalue; + changed; +end; + +procedure tframetemplate.setcolorframemouse(const avalue: colorty); +begin + fi.ba.colorframemouse:= avalue; + changed; +end; + +procedure tframetemplate.setcolorframeclicked(const avalue: colorty); +begin + fi.ba.colorframeclicked:= avalue; + changed; +end; + +procedure tframetemplate.setcolorframedefault(const avalue: colorty); +begin + fi.ba.colorframedefault:= avalue; + changed; +end; + +procedure tframetemplate.setcolordkshadow(const avalue: colorty); +begin + fi.ba.framecolors.edges.shadow.effectcolor:= avalue; + changed; +end; + +procedure tframetemplate.setcolorshadow(const avalue: colorty); +begin + fi.ba.framecolors.edges.shadow.color:= avalue; + changed; +end; + +procedure tframetemplate.setcolorlight(const avalue: colorty); +begin + fi.ba.framecolors.edges.light.color:= avalue; + changed; +end; + +procedure tframetemplate.setcolorhighlight(const avalue: colorty); +begin + fi.ba.framecolors.edges.light.effectcolor:= avalue; + changed; +end; + +procedure tframetemplate.setcolordkwidth(const avalue: integer); +begin + fi.ba.framecolors.edges.shadow.effectwidth:= avalue; + changed; +end; + +procedure tframetemplate.setcolorhlwidth(const avalue: integer); +begin + fi.ba.framecolors.edges.light.effectwidth:= avalue; + changed; +end; + +procedure tframetemplate.setcolorglyph(const avalue: colorty); +begin + fi.ba.colorglyph:= avalue; + changed; +end; + +procedure tframetemplate.setcolorpattern(const avalue: colorty); +begin + fi.ba.colorpattern:= avalue; + changed; +end; + +procedure tframetemplate.sethiddenedges(const avalue: edgesty); +begin + fi.ba.hiddenedges:= avalue; + changed; +end; + +procedure tframetemplate.setframei_bottom(const Value: integer); +begin + fi.ba.innerframe.bottom := Value; + changed; +end; + +procedure tframetemplate.setframei_left(const Value: integer); +begin + fi.ba.innerframe.left := Value; + changed; +end; + +procedure tframetemplate.setframei_right(const Value: integer); +begin + fi.ba.innerframe.right := Value; + changed; +end; + +procedure tframetemplate.setframei_top(const Value: integer); +begin + fi.ba.innerframe.top := Value; + changed; +end; + +procedure tframetemplate.setframeo_bottom(const Value: integer); +begin + fi.ba.outerframe.bottom := Value; + changed; +end; + +procedure tframetemplate.setframeo_left(const Value: integer); +begin + fi.ba.outerframe.left := Value; + changed; +end; + +procedure tframetemplate.setframeo_right(const Value: integer); +begin + fi.ba.outerframe.right := Value; + changed; +end; + +procedure tframetemplate.setframeo_top(const Value: integer); +begin + fi.ba.outerframe.top := Value; + changed; +end; + +procedure tframetemplate.setframewidth(const Value: integer); +begin + fi.ba.framewidth := Value; + changed; +end; + +procedure tframetemplate.setextraspace(const avalue: integer); +begin + fi.ba.extraspace := avalue; + changed; +end; + +procedure tframetemplate.setimagedist(const avalue: integer); +begin + fi.ba.imagedist := avalue; + changed; +end; + +procedure tframetemplate.setimagedist1(const avalue: integer); +begin + fi.ba.imagedist1 := avalue; + changed; +end; + +procedure tframetemplate.setimagedist2(const avalue: integer); +begin + fi.ba.imagedist2 := avalue; + changed; +end; + +procedure tframetemplate.setleveli(const Value: integer); +begin + fi.ba.leveli := Value; + changed; +end; + +procedure tframetemplate.setlevelo(const Value: integer); +begin + fi.ba.levelo := Value; + changed; +end; + +procedure tframetemplate.setframeimage_list(const avalue: timagelist); +begin + setlinkedvar(avalue,tmsecomponent(fi.ba.frameimage_list)); + changed; +end; + +function tframetemplate.getimagelist: timagelist; +begin + result:= fi.ba.frameimage_list; +end; + +procedure tframetemplate.setframeimage_left(const avalue: integer); +begin + fi.ba.frameimage_left:= avalue; + changed; +end; + +procedure tframetemplate.setframeimage_right(const avalue: integer); +begin + fi.ba.frameimage_right:= avalue; + changed; +end; + +procedure tframetemplate.setframeimage_top(const avalue: integer); +begin + fi.ba.frameimage_top:= avalue; + changed; +end; + +procedure tframetemplate.setframeimage_bottom(const avalue: integer); +begin + fi.ba.frameimage_bottom:= avalue; + changed; +end; + +procedure tframetemplate.setframeimage_offset(const avalue: imagenrty); +begin + fi.ba.frameimage_offsets.offset:= avalue; + changed; +end; + +procedure tframetemplate.setframeimage_offset1(const avalue: imagenrty); +begin + fi.ba.frameimage_offsets.offset1:= avalue; + changed; +end; + +procedure tframetemplate.setframeimage_offsetdisabled(const avalue: imagenrty); +begin + fi.ba.frameimage_offsets.disabled:= avalue; + changed; +end; + +procedure tframetemplate.setframeimage_offsetmouse(const avalue: imagenrty); +begin + fi.ba.frameimage_offsets.mouse:= avalue; + changed; +end; + +procedure tframetemplate.setframeimage_offsetclicked(const avalue: imagenrty); +begin + fi.ba.frameimage_offsets.clicked:= avalue; + changed; +end; + +procedure tframetemplate.setframeimage_offsetfocused(const avalue: imagenrty); +begin + fi.ba.frameimage_offsets.focused:= avalue; + changed; +end; + +procedure tframetemplate.setframeimage_offsetactive(const avalue: imagenrty); +begin + fi.ba.frameimage_offsets.active:= avalue; + changed; +end; +{ +procedure tframetemplate.setframeimage_offsetactivemouse(const avalue: imagenrty); +begin + fi.ba.frameimage_offsets.activemouse:= avalue; + changed; +end; + +procedure tframetemplate.setframeimage_offsetactiveclicked(const avalue: imagenrty); +begin + fi.ba.frameimage_offsets.activeclicked:= avalue; + changed; +end; +} +procedure tframetemplate.setframeface_list(const avalue: tfacelist); +begin + setlinkedvar(avalue,tmsecomponent(fi.ba.frameface_list)); + changed; +end; + +procedure tframetemplate.setframeface_offset(const avalue: facenrty); +begin + fi.ba.frameface_offsets.offset:= avalue; + changed; +end; + +procedure tframetemplate.setframeface_offset1(const avalue: facenrty); +begin + fi.ba.frameface_offsets.offset1:= avalue; + changed; +end; + +procedure tframetemplate.setframeface_offsetdisabled(const avalue: facenrty); +begin + fi.ba.frameface_offsets.disabled:= avalue; + changed; +end; + +procedure tframetemplate.setframeface_offsetmouse(const avalue: facenrty); +begin + fi.ba.frameface_offsets.mouse:= avalue; + changed; +end; + +procedure tframetemplate.setframeface_offsetclicked(const avalue: facenrty); +begin + fi.ba.frameface_offsets.clicked:= avalue; + changed; +end; + +procedure tframetemplate.setframeface_offsetfocused(const avalue: facenrty); +begin + fi.ba.frameface_offsets.focused:= avalue; + changed; +end; + +procedure tframetemplate.setframeface_offsetactive(const avalue: facenrty); +begin + fi.ba.frameface_offsets.active:= avalue; + changed; +end; +{ +procedure tframetemplate.setframeface_offsetactivemouse(const avalue: facenrty); +begin + fi.ba.frameface_offsets.activemouse:= avalue; + changed; +end; + +procedure tframetemplate.setframeface_offsetactiveclicked(const avalue: facenrty); +begin + fi.ba.frameface_offsets.activeclicked:= avalue; + changed; +end; +} +procedure tframetemplate.setoptionsskin(const avalue: frameskinoptionsty); +begin + fi.ba.optionsskin:= avalue; + changed; +end; + +function tframetemplate.getinfosize: integer; +begin +// result:= sizeof(fi.ba) - sizeof(fi.ba.frameface_list); + result:= ptruint(@fi.ba.frameface_list) - ptruint(@fi.ba); //copied by move +end; + +function tframetemplate.getinfoad: pointer; +begin + result:= @fi.ba; +end; + +procedure tframetemplate.doassignto(dest: tpersistent); +begin + if dest is tcustomframe then begin + with tcustomframe(dest) do begin + if (cs_loadedproc in fowner.msecomponentstate) or + (csloading in fintf.getcomponentstate) then begin +// if cs_updateskinproc in fintf.getmsecomponentstate then begin +// updatestate; +// end +// else begin + exclude(fstate,fs_paintposinited); +// end; + end; + settemplateinfo(self.fi); + end; +// with tcustomframe(dest) do begin +// fi:= self.fi; +// internalupdatestate; +// end; + end; +end; + +procedure tframetemplate.paintbackgroundframe(const acanvas: tcanvas; + const arect: rectty; const astate: framestateflagsty = []); +var + int1: integer; + +begin + if fi.ba.colorclient <> cl_transparent then begin + acanvas.fillrect(arect,fi.ba.colorclient); + end; + if fi.ba.frameface_list <> nil then begin + int1:= fi.ba.frameface_list.lookup( + calcframestateoffs(astate,frameoffsetsty(fi.ba.frameface_offsets))); + if (int1 >= 0){ and (int1 < fi.ba.frameface_list.list.count)} then begin + fi.ba.frameface_list.list[int1].paint(acanvas,arect); + end; + end; +end; + +procedure tframetemplate.paintoverlayframe(const acanvas: tcanvas; + const arect: rectty; const astate: framestateflagsty = []); +begin + tcustomframe.drawframe(acanvas,arect,fi.ba,astate); +end; + +procedure tframetemplate.paintbackground(const acanvas: tcanvas; + const arect: rectty; const astate: framestateflagsty = []); +var + bo1: boolean; +begin + if assigned(fonbeforetemplatepaintbackground) then begin + bo1:= false; + fonbeforetemplatepaintbackground(self,acanvas,arect,astate,bo1); + if bo1 then begin + paintbackgroundframe(acanvas, + inflaterect(arect,tcustomframe.calcpaintframe(fi.ba)),astate); + end; + if assigned(fonaftertemplatepaintbackground) then begin + fonaftertemplatepaintbackground(self,acanvas,arect,astate); + end; + end + else begin + paintbackgroundframe(acanvas, + inflaterect(arect,tcustomframe.calcpaintframe(fi.ba)),astate); + if assigned(fonaftertemplatepaintbackground) then begin + fonaftertemplatepaintbackground(self,acanvas,arect,astate); + end; + end; +end; + +procedure tframetemplate.paintoverlay(const acanvas: tcanvas; + const arect: rectty; const astate: framestateflagsty = []); +var + bo1: boolean; +begin + if assigned(fonbeforetemplatepaintoverlay) then begin + bo1:= false; + fonbeforetemplatepaintoverlay(self,acanvas,arect,astate,bo1); + if bo1 then begin + paintoverlayframe(acanvas, + inflaterect(arect,tcustomframe.calcpaintframe(fi.ba)),astate); + end; + if assigned(fonaftertemplatepaintoverlay) then begin + fonaftertemplatepaintoverlay(self,acanvas,arect,astate); + end; + end + else begin + paintoverlayframe(acanvas, + inflaterect(arect,tcustomframe.calcpaintframe(fi.ba)),astate); + if assigned(fonaftertemplatepaintoverlay) then begin + fonaftertemplatepaintoverlay(self,acanvas,arect,astate); + end; + end; +end; + +procedure tframetemplate.copyinfo(const source: tpersistenttemplate); +begin + with tframetemplate(source) do begin + setlinkedvar(frameimage_list,tmsecomponent(self.fi.ba.frameimage_list)); + setlinkedvar(frameface_list,tmsecomponent(fi.ba.frameface_list)); + if font <> nil then begin + self.createfont; + self.font.assign(font); + end + else begin + freeandnil(fi.capt.font); + end; + end; +end; + +procedure tframetemplate.readdummy(reader: treader); +begin + reader.readinteger(); +end; + +procedure tframetemplate.readimagedisttop(reader: treader); +begin + fi.ba.imagedist1:= reader.readinteger(); +end; + +procedure tframetemplate.readimagedistbottom(reader: treader); +begin + fi.ba.imagedist2:= reader.readinteger(); +end; + +procedure tframetemplate.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('imagedisttop',@readimagedisttop,nil,false); + filer.defineproperty('imagedistbottom',@readimagedistbottom,nil,false); + filer.defineproperty('frameimage_offsetactivemouse',@readdummy,nil,false); + filer.defineproperty('frameimage_offsetactiveclicked',@readdummy,nil,false); + filer.defineproperty('frameface_offsetactivemouse',@readdummy,nil,false); + filer.defineproperty('frameface_offsetactiveclicked',@readdummy,nil,false); +end; + +function tframetemplate.paintframe: framety; +begin + result:= tcustomframe.calcpaintframe(fi.ba); +end; + +function tframetemplate.innerframe: framety; +begin + result:= tcustomframe.calcinnerframe(fi.ba); +end; + +function tframetemplate.paintframedim: sizety; +var + fr1: framety; +begin + fr1:= tcustomframe.calcpaintframe(fi.ba); + result.cx:= fr1.left + fr1.right; + result.cy:= fr1.top + fr1.bottom; +end; + +function tframetemplate.innerframedim: sizety; +var + fr1: framety; +begin + fr1:= tcustomframe.calcinnerframe(fi.ba); + result.cx:= fr1.left + fr1.right; + result.cy:= fr1.top + fr1.bottom; +end; + +function tframetemplate.getfont: toptionalfont; +begin + fowner.getoptionalobject(fi.capt.font,{$ifdef FPC}@{$endif}createfont); + result:= fi.capt.font; +end; + +procedure tframetemplate.setfont(const avalue: toptionalfont); +begin + if fi.capt.font <> avalue then begin + fowner.setoptionalobject(avalue,fi.capt.font,{$ifdef FPC}@{$endif}createfont); + end; +end; + +procedure tframetemplate.setcaptiondist(const avalue: integer); +begin + fi.capt.captiondist:= avalue; + changed; +end; + +procedure tframetemplate.setcaptionoffset(const avalue: integer); +begin + fi.capt.captionoffset:= avalue; + changed; +end; + +procedure tframetemplate.setfocusrectdist(const avalue: integer); +begin + fi.ba.focusrectdist:= avalue; + changed; +end; + +procedure tframetemplate.createfont; +begin + if fi.capt.font = nil then begin + fi.capt.font:= toptionalfont.create; + fi.capt.font.onchange:= {$ifdef FPC}@{$endif}fontchanged; + end; +end; + +procedure tframetemplate.fontchanged(const sender: tobject); +begin + changed; +end; + +function tframetemplate.isfontstored: boolean; +begin + result:= fi.capt.font <> nil; +end; + +{ tframecomp } + +function tframecomp.gettemplate: tframetemplate; +begin + result:= tframetemplate(ftemplate); +end; + +function tframecomp.gettemplateclass: templateclassty; +begin + result:= tframetemplate; +end; + +procedure tframecomp.settemplate(const Value: tframetemplate); +begin + ftemplate.Assign(value); +end; + + +{ tfacebitmap } + +constructor tfacebitmap.create(const aowner: tcustomface); +begin + fowner:= aowner; + inherited create(bmk_rgb); +end; + +procedure tfacebitmap.setx(const avalue: int32); +begin + if fpos.x <> avalue then begin + setpos(mp(avalue,fpos.y)); + end; +end; + +procedure tfacebitmap.sety(const avalue: int32); +begin + if fpos.y <> avalue then begin + setpos(mp(fpos.x,avalue)); + end; +end; + +procedure tfacebitmap.setpos(const avalue: pointty); +begin + if (avalue.x <> fpos.x) or (avalue.y <> fpos.y) then begin + if (fowner <> nil) then begin + if hasimage() then begin + if (alignment*[al_stretchx,al_stretchy, + al_tiled,al_fit,al_thumbnail] = []) then begin + fowner.fintf.invalidaterect(mr(fpos,fsize),org_paint); + fpos:= avalue; + fowner.fintf.invalidaterect(mr(fpos,fsize),org_paint); + end + else begin + fpos:= avalue; + change(); + end; + end + else begin + fpos:= avalue; + end; + end + else begin + fpos:= avalue; + change(); + end; + end; +end; + +function tfacebitmap.getcenter: pointty; +begin + result.x:= fpos.x - fsize.cx div 2; + result.y:= fpos.y - fsize.cy div 2; +end; + +procedure tfacebitmap.setcenter(avalue: pointty); +begin + avalue.x:= avalue.x - fsize.cx div 2; + avalue.y:= avalue.y - fsize.cy div 2; + pos:= avalue; +end; + +{ tcustomface } + +procedure tcustomface.internalcreate; +begin + fi.image:= tfacebitmap.create(self); + fi.image.onchange:= {$ifdef fpc}@{$endif}imagechanged; + fi.fade_pos:= trealarrayprop.create; + fi.fade_color:= tfadecolorarrayprop.create; + fi.fade_pos.link([fi.fade_color,fi.fade_pos]); + fi.fade_opapos:= trealarrayprop.create; + fi.fade_opacolor:= tfadeopacolorarrayprop.create; + fi.fade_opapos.link([fi.fade_opacolor,fi.fade_opapos]); + fi.fade_opacity:= cl_none; + fi.fade_pos.onchange:= {$ifdef fpc}@{$endif}dochange; + fi.fade_color.onchange:= {$ifdef fpc}@{$endif}dochange; + fi.fade_opapos.onchange:= {$ifdef fpc}@{$endif}dochange; + fi.fade_opacolor.onchange:= {$ifdef fpc}@{$endif}dochange; +end; + +constructor tcustomface.create; +begin + inherited; +// internalcreate; +end; + +constructor tcustomface.create(const owner: twidget); +begin + fintf:= iface(owner); + owner.fface:= self; + internalcreate; +end; + +constructor tcustomface.create(const intf: iface); +begin + fintf:= intf; + internalcreate; +end; + +destructor tcustomface.destroy; +begin + if ftemplate <> nil then begin + fintf.setlinkedvar(nil,tmsecomponent(ftemplate)); + end; + inherited; + fi.image.Free; + fi.fade_pos.Free; + fi.fade_color.free; + fi.fade_opapos.Free; + fi.fade_opacolor.free; + falphabuffer.Free; +end; + +procedure tcustomface.change; +begin + fintf.invalidatewidget(); //face can be element of frame (tcustomstepframe) +end; + +procedure updatefadearray(var fi: faceinfoty; const sender: tarrayprop); +var + ar1: integerarty; +begin + if sender = fi.fade_pos then begin + with trealarrayprop1(fi.fade_pos) do begin + if high(fitems) >= 0 then begin + sortarray(trealarrayprop1(fi.fade_pos).fitems,ar1); + fitems[0]:= 0; + if high(fitems) > 0 then begin + fitems[high(fitems)]:= 1; + end; + fi.fade_color.order(ar1); + end; + end; + end + else begin + if sender = fi.fade_opapos then begin + with trealarrayprop1(fi.fade_opapos) do begin + if high(fitems) >= 0 then begin + sortarray(trealarrayprop1(fi.fade_opapos).fitems,ar1); + fitems[0]:= 0; + if high(fitems) > 0 then begin + fitems[high(fitems)]:= 1; + end; + fi.fade_opacolor.order(ar1); + end; + end; + end; + end; +end; + +procedure tcustomface.dochange(const sender: tarrayprop; const index: integer); +begin + updatefadearray(fi,sender); + change; +end; + +procedure tcustomface.imagechanged(const sender: tobject); +begin + change; + if not (csloading in fintf.getcomponentstate) then begin + include(flocalprops,fal_image); + end; +end; + +procedure tcustomface.checktemplate(const sender: tobject); +begin + if sender = ftemplate then begin + assign(tpersistent(sender)); + end; +end; + +procedure tcustomface.assign(source: tpersistent); +begin + if source is tcustomface then begin + if not (csdesigning in fintf.getcomponentstate) then begin + flocalprops:= allfacelocalprops; + with tcustomface(source) do begin + self.fade_direction:= fade_direction; + self.fade_color:= fade_color; + self.fade_pos:= fade_pos; + self.fade_opacolor:= fade_opacolor; + self.fade_opapos:= fade_opapos; + self.fade_opacity:= fade_opacity; + self.image:= image; + self.options:= options; + self.framei_left:= framei_left; + self.framei_top:= framei_top; + self.framei_right:= framei_right; + self.framei_bottom:= framei_bottom; + end; + end; + end + else begin + inherited; + end; +end; + +procedure facepaint(const canvas: tcanvas; const arect: rectty; + const fi: faceinfoty; const fintf: iface1; + var falphabuffer: tmaskedbitmap; var falphabufferdest: pointty); + +var + rect,rect1: rectty; + + procedure createalphabuffer(const amasked: boolean); + begin + if falphabuffer = nil then begin + falphabuffer:= tmaskedbitmap.create(bmk_rgb); + end; + if amasked then begin + falphabuffer.options:= [bmo_masked,bmo_colormask]; + end; + falphabuffer.size:= rect1.size; + falphabufferdest:= rect1.pos; + falphabuffer.canvas.copyarea(canvas,rect1,nullpoint); + end; + +var + pixelscale: real; + vert: boolean; + alpha: boolean; + startpix,pixcount: integer; + + procedure calcfade(const fadepos: trealarrayprop; + const fadecolor: tcolorarrayprop; const bmp: tbitmap); + var + posar: realarty; + rgbs: array of rgbtriplety; + int1,int2: integer; + po1,pe: prgbtriplety; + pixelstep: real; + pixinc: integer; + curpix,nextpix: integer; + redsum,greensum,bluesum,lengthsum: real; + curnode,nextnode: integer; + rea1,rea2: real; + opar,opag,opab: int32; + co1: rgbtriplety; + col1,col2: prgbtriplety; + + begin + posar:= trealarrayprop1(fadepos).fitems; + with tfadecolorarrayprop(fadecolor) do begin + setlength(rgbs,length(fitems)); + for int1:= 0 to high(rgbs) do begin + rgbs[int1]:= colortorgb(fintf.translatecolor(fitems[int1])); + end; + if alpha then begin + po1:= pointer(rgbs); + pe:= po1+length(rgbs); + while po1 < pe do begin + po1^.red:= 255-po1^.red; + po1^.green:= 255-po1^.green; + po1^.blue:= 255-po1^.blue; + inc(po1); + end; + end; + end; + if fadecolor = fi.fade_opacolor then begin + co1:= colortorgb(fi.fade_opacity); + opar:= (co1.red * 256) div 255; + opag:= (co1.green * 256) div 255; + opab:= (co1.blue * 256) div 255; + end + else begin + opar:= 256; + opag:= 256; + opab:= 256; + end; + if high(rgbs) > 0 then begin + po1:= bmp.scanline[0]; + pixelstep:= 1/pixelscale; + pixinc:= sizeof(rgbtriplety); + if fi.fade_direction in [gd_up,gd_left] then begin //revert + if fi.fade_direction = gd_left then begin + startpix:= rect.x+rect.cx-rect1.x-rect1.cx; + end + else begin + startpix:= rect.y+rect.cy-rect1.y-rect1.cy; + end; + inc(po1,pixcount-1); + pixinc:= -pixinc; + end; + curnode:= 0; + int1:= 0; + while int1 < pixcount do begin + rea1:= (int1+startpix)*pixelstep + 0.000001; + if int1 = 0 then begin + while posar[curnode] < rea1 do begin + inc(curnode); + end; + dec(curnode); + end; + nextnode:= curnode; + rea1:= rea1 + pixelstep; + while (posar[nextnode] < rea1) and (nextnode < high(posar)) do begin + inc(nextnode); + end; + if nextnode > curnode+1 then begin //calc average + redsum:= 0; + greensum:= 0; + bluesum:= 0; + lengthsum:= 0; + for int2:= curnode to nextnode - 2 do begin //todo: optimize + rea1:= posar[int2+1] - posar[int2]; + redsum:= redsum + (rgbs[int2].red+rgbs[int2+1].red)*rea1; + greensum:= greensum + (rgbs[int2].green+rgbs[int2+1].green)*rea1; + bluesum:= bluesum + (rgbs[int2].blue+rgbs[int2+1].blue)*rea1; + lengthsum:= lengthsum + rea1; + end; + if lengthsum > 0 then begin + rea1:= 1/(2*lengthsum); + with po1^ do begin + red:= (round(redsum*rea1)*opar) div 256; + green:= (round(greensum*rea1)*opag) div 256; + blue:= (round(bluesum*rea1)*opab) div 256; + res:= 0; + end; + end + else begin + po1^:= rgbs[curnode]; + end; + dec(nextnode); + end + else begin + nextpix:= trunc(posar[nextnode]*pixelscale)-startpix; + if int1 = nextpix then begin + po1^:= rgbs[curnode]; + end + else begin + curpix:= trunc(posar[curnode]*pixelscale)-startpix; + if nextpix = curpix then begin + rea1:= 1; + end + else begin + rea1:= 1/(nextpix-curpix); + end; + if nextpix > pixcount then begin + nextpix:= pixcount; + end; + col1:= @rgbs[curnode]; + col2:= @rgbs[nextnode]; + for int2:= int1-curpix to nextpix-curpix-1 do begin + rea2:= rea1*int2; + with po1^ do begin + res:= 0; + red:= ((col1^.red + + round((col2^.red-col1^.red)*rea2))*opar) div 256; + green:= ((col1^.green + + round((col2^.green-col1^.green)*rea2))*opag) div 256; + blue:= ((col1^.blue + + round((col2^.blue-col1^.blue)*rea2))*opab) div 256; + end; + inc(pchar(po1),pixinc); + end; + dec(pchar(po1),pixinc); + int1:= nextpix-1; + end; + end; + curnode:= nextnode; + inc(int1); + inc(pchar(po1),pixinc); + end; + end + else begin //count = 1 + co1.red:= (rgbs[0].red*opar) div 256; + co1.green:= (rgbs[0].green*opag) div 256; + co1.blue:= (rgbs[0].blue*opag) div 256; + co1.res:= 0; + if vert then begin + bmp.canvas.drawline(nullpoint,makepoint(0,rect1.cy-1),colorty(co1)); + end + else begin + bmp.canvas.drawline(nullpoint,makepoint(rect1.cx-1,0),colorty(co1)); + end; + end; + end; //calcfade + +var + bmp: tmaskedbitmap; + reg1: regionty; + + procedure paintimage(const canvas: tcanvas); + begin + if fi.image.hasimage then begin + fi.image.paint(canvas,mr(addpoint(rect.pos,fi.image.fpos),rect.size)); + if fao_alphafadeimage in fi.options then begin + if falphabuffer <> nil then begin + falphabuffer.paint(canvas,falphabufferdest); + freeandnil(falphabuffer); + end; + end; + end; + if fi.frameimage_list <> nil then begin + if reg1 <> 0 then begin + canvas.clipregion:= reg1; + reg1:= 0; + end; + fi.frameimage_list.paintlookup(canvas,fi.frameimage_offset,arect.pos); + fi.frameimage_list.paintlookup(canvas,fi.frameimage_offset+1, + makerect(arect.x, + arect.y+fi.frameimage_list.height, + fi.frameimage_list.width, + arect.cy-2*fi.frameimage_list.height),[al_stretchy]); + fi.frameimage_list.paintlookup(canvas,fi.frameimage_offset+2,arect,[al_bottom]); + fi.frameimage_list.paintlookup(canvas,fi.frameimage_offset+3, + makerect(arect.x+fi.frameimage_list.width, + arect.y+arect.cy-fi.frameimage_list.height, + arect.cx-2*fi.frameimage_list.width, + fi.frameimage_list.height),[al_stretchx]); + fi.frameimage_list.paintlookup(canvas,fi.frameimage_offset+4,arect, + [al_bottom,al_right]); + fi.frameimage_list.paintlookup(canvas,fi.frameimage_offset+5, + makerect(arect.x+arect.cx-fi.frameimage_list.width, + arect.y+fi.frameimage_list.height, + fi.frameimage_list.width, + arect.cy-2*fi.frameimage_list.height),[al_stretchy]); + fi.frameimage_list.paintlookup(canvas,fi.frameimage_offset+6,arect,[al_right]); + fi.frameimage_list.paintlookup(canvas,fi.frameimage_offset+7, + makerect(arect.x+fi.frameimage_list.width,arect.y, + arect.cx-2*fi.frameimage_list.width, + fi.frameimage_list.height),[al_stretchx]); + end; + end; //paintimage +begin + reg1:= 0; + rect:= deflaterect(arect,fi.framei); + if intersectrect(rect,canvas.clipbox,rect1) or + testintersectrect(arect,canvas.clipbox) then begin + if (fi.frameimage_list <> nil) and + fi.frameimage_list.hascornermask then begin + reg1:= canvas.copyclipregion(); + fi.frameimage_list.clipcornermask(canvas,arect,[]); + end; + + alpha:= fi.options * faceoptionsmask1 <> []; + if fi.options * [fao_fadeoverlay,fao_alphaimage] = + [fao_fadeoverlay] then begin + paintimage(canvas); + end; + if (fi.fade_color.count > 0) and (rect1.cx > 0) and (rect1.cy > 0) then begin + if (fi.fade_color.count > 1) or + ((fi.fade_opacolor.count > 0) or (fi.fade_opacity <> cl_none)) and + (fi.options * faceoptionsmask1 = []) then begin + case fi.fade_direction of + gd_up,gd_down: begin + pixelscale:= rect.cy; + vert:= true; + startpix:= rect1.y-rect.y; + pixcount:= rect1.cy; + end + else begin //gd_right,gd_left + pixelscale:= rect.cx; + vert:= false; + startpix:= rect1.x-rect.x; + pixcount:= rect1.cx; + end; + end; + bmp:= tmaskedbitmap.create(bmk_rgb); + if vert then begin + bmp.size:= makesize(1,rect1.cy); + end + else begin + bmp.size:= makesize(rect1.cx,1); + end; + calcfade(fi.fade_pos,fi.fade_color,bmp); + if fi.options * faceoptionsmask1 = [] then begin + if fi.fade_opapos.count > 0 then begin + bmp.colormask:= true; + calcfade(fi.fade_opapos,fi.fade_opacolor,bmp.mask); + end + else begin + bmp.opacity:= fi.fade_opacity; + end; + bmp.paint(canvas,rect1,[al_stretchx,al_stretchy]); + end + else begin + createalphabuffer(true); + bmp.paint(falphabuffer.mask.canvas,makerect(nullpoint,rect1.size), + makerect(nullpoint,bmp.size),[al_stretchx,al_stretchy]); + end; + bmp.Free; + end + else begin //fade_color.count = 1 + if alpha then begin + if fao_alphaimage in fi.options then begin + createalphabuffer(true); + falphabuffer.mask.canvas.fillrect(mr(nullpoint,rect1.size), + invertcolor(tfadecolorarrayprop1(fi.fade_color).fitems[0])); + end + else begin + createalphabuffer(false); + falphabuffer.opacity:= + invertcolor(tfadecolorarrayprop1(fi.fade_color).fitems[0]); + end; + end + else begin + canvas.fillrect(rect1,tfadecolorarrayprop1(fi.fade_color).fitems[0]); + end; + end; + end + else begin //fade_color.count = 0 + if alpha then begin + if fao_alphaimage in fi.options then begin + createalphabuffer(true); + falphabuffer.mask.canvas.fillrect(mr(nullpoint,rect1.size), + invertcolor(fi.fade_opacity)); + end + else begin + createalphabuffer(false); + falphabuffer.opacity:= invertcolor(fi.fade_opacity); + end; + end; + end; + if fi.options * [fao_fadeoverlay,fao_alphaimage] = [] then begin + paintimage(canvas); + end; + if (fao_alphaimage in fi.options) and (falphabuffer <> nil) then begin + falphabuffer.mask.canvas.origin:= subpoint(rect.pos,rect1.pos); + paintimage(falphabuffer.mask.canvas); + falphabuffer.mask.canvas.origin:= nullpoint; + end; + end; + if reg1 <> 0 then begin + canvas.clipregion:= reg1; + end; +end; + +procedure tcustomface.internalpaint(const canvas: tcanvas; const arect: rectty); +begin + facepaint(canvas,arect,fi,fintf,falphabuffer,falphabufferdest); +end; + +(* +procedure tcustomface.internalpaint(const canvas: tcanvas; const arect: rectty); + +var + rect,rect1: rectty; + + procedure createalphabuffer(const amasked: boolean); + begin + if falphabuffer = nil then begin + falphabuffer:= tmaskedbitmap.create(bmk_rgb); + end; + if amasked then begin + falphabuffer.options:= [bmo_masked,bmo_colormask]; + end; + falphabuffer.size:= rect1.size; + falphabufferdest:= rect1.pos; + falphabuffer.canvas.copyarea(canvas,rect1,nullpoint); + end; + +var + pixelscale: real; + vert: boolean; + alpha: boolean; + startpix,pixcount: integer; + + procedure calcfade(const fadepos: trealarrayprop; + const fadecolor: tcolorarrayprop; const bmp: tbitmap); + var + posar: realarty; + rgbs: array of rgbtriplety; + int1,int2: integer; + po1,pe: prgbtriplety; + pixelstep: real; + pixinc: integer; + curpix,nextpix: integer; + redsum,greensum,bluesum,lengthsum: real; + curnode,nextnode: integer; + rea1,rea2: real; + opar,opag,opab: int32; + co1: rgbtriplety; + col1,col2: prgbtriplety; + + begin + posar:= trealarrayprop1(fadepos).fitems; + with tfadecolorarrayprop(fadecolor) do begin + setlength(rgbs,length(fitems)); + for int1:= 0 to high(rgbs) do begin + rgbs[int1]:= colortorgb(fintf.translatecolor(fitems[int1])); + end; + if alpha then begin + po1:= pointer(rgbs); + pe:= po1+length(rgbs); + while po1 < pe do begin + po1^.red:= 255-po1^.red; + po1^.green:= 255-po1^.green; + po1^.blue:= 255-po1^.blue; + inc(po1); + end; + end; + end; + if fadecolor = fi.fade_opacolor then begin + co1:= colortorgb(fade_opacity); + opar:= (co1.red * 256) div 255; + opag:= (co1.green * 256) div 255; + opab:= (co1.blue * 256) div 255; + end + else begin + opar:= 256; + opag:= 256; + opab:= 256; + end; + if high(rgbs) > 0 then begin + po1:= bmp.scanline[0]; + pixelstep:= 1/pixelscale; + pixinc:= sizeof(rgbtriplety); + if fi.fade_direction in [gd_up,gd_left] then begin //revert + if fi.fade_direction = gd_left then begin + startpix:= rect.x+rect.cx-rect1.x-rect1.cx; + end + else begin + startpix:= rect.y+rect.cy-rect1.y-rect1.cy; + end; + inc(po1,pixcount-1); + pixinc:= -pixinc; + end; + curnode:= 0; + int1:= 0; + while int1 < pixcount do begin + rea1:= (int1+startpix)*pixelstep + 0.000001; + if int1 = 0 then begin + while posar[curnode] < rea1 do begin + inc(curnode); + end; + dec(curnode); + end; + nextnode:= curnode; + rea1:= rea1 + pixelstep; + while (posar[nextnode] < rea1) and (nextnode < high(posar)) do begin + inc(nextnode); + end; + if nextnode > curnode+1 then begin //calc average + redsum:= 0; + greensum:= 0; + bluesum:= 0; + lengthsum:= 0; + for int2:= curnode to nextnode - 2 do begin //todo: optimize + rea1:= posar[int2+1] - posar[int2]; + redsum:= redsum + (rgbs[int2].red+rgbs[int2+1].red)*rea1; + greensum:= greensum + (rgbs[int2].green+rgbs[int2+1].green)*rea1; + bluesum:= bluesum + (rgbs[int2].blue+rgbs[int2+1].blue)*rea1; + lengthsum:= lengthsum + rea1; + end; + if lengthsum > 0 then begin + rea1:= 1/(2*lengthsum); + with po1^ do begin + red:= (round(redsum*rea1)*opar) div 256; + green:= (round(greensum*rea1)*opag) div 256; + blue:= (round(bluesum*rea1)*opab) div 256; + res:= 0; + end; + end + else begin + po1^:= rgbs[curnode]; + end; + dec(nextnode); + end + else begin + nextpix:= trunc(posar[nextnode]*pixelscale)-startpix; + if int1 = nextpix then begin + po1^:= rgbs[curnode]; + end + else begin + curpix:= trunc(posar[curnode]*pixelscale)-startpix; + if nextpix = curpix then begin + rea1:= 1; + end + else begin + rea1:= 1/(nextpix-curpix); + end; + if nextpix > pixcount then begin + nextpix:= pixcount; + end; + col1:= @rgbs[curnode]; + col2:= @rgbs[nextnode]; + for int2:= int1-curpix to nextpix-curpix-1 do begin + rea2:= rea1*int2; + with po1^ do begin + res:= 0; + red:= ((col1^.red + + round((col2^.red-col1^.red)*rea2))*opar) div 256; + green:= ((col1^.green + + round((col2^.green-col1^.green)*rea2))*opag) div 256; + blue:= ((col1^.blue + + round((col2^.blue-col1^.blue)*rea2))*opab) div 256; + end; + inc(pchar(po1),pixinc); + end; + dec(pchar(po1),pixinc); + int1:= nextpix-1; + end; + end; + curnode:= nextnode; + inc(int1); + inc(pchar(po1),pixinc); + end; + end + else begin //count = 1 + co1.red:= (rgbs[0].red*opar) div 256; + co1.green:= (rgbs[0].green*opag) div 256; + co1.blue:= (rgbs[0].blue*opag) div 256; + co1.res:= 0; + if vert then begin + bmp.canvas.drawline(nullpoint,makepoint(0,rect1.cy-1),colorty(co1)); + end + else begin + bmp.canvas.drawline(nullpoint,makepoint(rect1.cx-1,0),colorty(co1)); + end; + end; + end; //calcfade + +var + bmp: tmaskedbitmap; + reg1: regionty; + + procedure paintimage(const canvas: tcanvas); + begin + if fi.image.hasimage then begin + fi.image.paint(canvas,mr(addpoint(rect.pos,fi.image.fpos),rect.size)); + if fao_alphafadeimage in fi.options then begin + doalphablend(canvas); + end; + end; + if fi.frameimage_list <> nil then begin + if reg1 <> 0 then begin + canvas.clipregion:= reg1; + reg1:= 0; + end; + fi.frameimage_list.paintlookup(canvas,fi.frameimage_offset,arect.pos); + fi.frameimage_list.paintlookup(canvas,fi.frameimage_offset+1, + makerect(arect.x, + arect.y+fi.frameimage_list.height, + fi.frameimage_list.width, + arect.cy-2*fi.frameimage_list.height),[al_stretchy]); + fi.frameimage_list.paintlookup(canvas,fi.frameimage_offset+2,arect,[al_bottom]); + fi.frameimage_list.paintlookup(canvas,fi.frameimage_offset+3, + makerect(arect.x+fi.frameimage_list.width, + arect.y+arect.cy-fi.frameimage_list.height, + arect.cx-2*fi.frameimage_list.width, + fi.frameimage_list.height),[al_stretchx]); + fi.frameimage_list.paintlookup(canvas,fi.frameimage_offset+4,arect, + [al_bottom,al_right]); + fi.frameimage_list.paintlookup(canvas,fi.frameimage_offset+5, + makerect(arect.x+arect.cx-fi.frameimage_list.width, + arect.y+fi.frameimage_list.height, + fi.frameimage_list.width, + arect.cy-2*fi.frameimage_list.height),[al_stretchy]); + fi.frameimage_list.paintlookup(canvas,fi.frameimage_offset+6,arect,[al_right]); + fi.frameimage_list.paintlookup(canvas,fi.frameimage_offset+7, + makerect(arect.x+fi.frameimage_list.width,arect.y, + arect.cx-2*fi.frameimage_list.width, + fi.frameimage_list.height),[al_stretchx]); + end; + end; //paintimage +begin + reg1:= 0; + rect:= deflaterect(arect,fi.framei); + if intersectrect(rect,canvas.clipbox,rect1) or + testintersectrect(arect,canvas.clipbox) then begin + if (fi.frameimage_list <> nil) and + fi.frameimage_list.hascornermask then begin + reg1:= canvas.copyclipregion(); + fi.frameimage_list.clipcornermask(canvas,arect,[]); + end; + + alpha:= fi.options * faceoptionsmask1 <> []; + if options * [fao_fadeoverlay,fao_alphaimage] = [fao_fadeoverlay] then begin + paintimage(canvas); + end; + if (fi.fade_color.count > 0) and (rect1.cx > 0) and (rect1.cy > 0) then begin + if (fi.fade_color.count > 1) or + ((fi.fade_opacolor.count > 0) or (fi.fade_opacity <> cl_none)) and + (fi.options * faceoptionsmask1 = []) then begin + case fi.fade_direction of + gd_up,gd_down: begin + pixelscale:= rect.cy; + vert:= true; + startpix:= rect1.y-rect.y; + pixcount:= rect1.cy; + end + else begin //gd_right,gd_left + pixelscale:= rect.cx; + vert:= false; + startpix:= rect1.x-rect.x; + pixcount:= rect1.cx; + end; + end; + bmp:= tmaskedbitmap.create(bmk_rgb); + if vert then begin + bmp.size:= makesize(1,rect1.cy); + end + else begin + bmp.size:= makesize(rect1.cx,1); + end; + calcfade(fi.fade_pos,fi.fade_color,bmp); + if fi.options * faceoptionsmask1 = [] then begin + if fi.fade_opapos.count > 0 then begin + bmp.colormask:= true; + calcfade(fi.fade_opapos,fi.fade_opacolor,bmp.mask); + end + else begin + bmp.opacity:= fi.fade_opacity; + end; + bmp.paint(canvas,rect1,[al_stretchx,al_stretchy]); + end + else begin + createalphabuffer(true); + bmp.paint(falphabuffer.mask.canvas,makerect(nullpoint,rect1.size), + makerect(nullpoint,bmp.size),[al_stretchx,al_stretchy]); + end; + bmp.Free; + end + else begin //fade_color.count = 1 + if alpha then begin + if fao_alphaimage in fi.options then begin + createalphabuffer(true); + falphabuffer.mask.canvas.fillrect(mr(nullpoint,rect1.size), + invertcolor(tfadecolorarrayprop1(fi.fade_color).fitems[0])); + end + else begin + createalphabuffer(false); + falphabuffer.opacity:= + invertcolor(tfadecolorarrayprop1(fi.fade_color).fitems[0]); + end; + end + else begin + canvas.fillrect(rect1,tfadecolorarrayprop1(fi.fade_color).fitems[0]); + end; + end; + end + else begin //fade_color.count = 0 + if alpha then begin + if fao_alphaimage in fi.options then begin + createalphabuffer(true); + falphabuffer.mask.canvas.fillrect(mr(nullpoint,rect1.size), + invertcolor(fi.fade_opacity)); + end + else begin + createalphabuffer(false); + falphabuffer.opacity:= invertcolor(fi.fade_opacity); + end; + end; + end; + if options * [fao_fadeoverlay,fao_alphaimage] = [] then begin + paintimage(canvas); + end; + if (fao_alphaimage in fi.options) and (falphabuffer <> nil) then begin + falphabuffer.mask.canvas.origin:= subpoint(rect.pos,rect1.pos); + paintimage(falphabuffer.mask.canvas); + falphabuffer.mask.canvas.origin:= nullpoint; + end; + end; + if reg1 <> 0 then begin + canvas.clipregion:= reg1; + end; +end; +*) +procedure tcustomface.paint(const canvas: tcanvas; const arect: rectty); +var + bo1: boolean; +begin + if ftemplate <> nil then begin + if assigned(tfacetemplate(ftemplate.template).fonbeforepaint) then begin + bo1:= false; + tfacetemplate(ftemplate.template).fonbeforepaint(self,canvas,arect,bo1); + if not bo1 then begin + internalpaint(canvas,arect); + end; + end + else begin + internalpaint(canvas,arect); + end; + if assigned(tfacetemplate(ftemplate.template).fonafterpaint) then begin + tfacetemplate(ftemplate.template).fonafterpaint(self,canvas,arect); + end; + end + else begin + internalpaint(canvas,arect); + end; +end; + +procedure tcustomface.doalphablend(const canvas: tcanvas); +begin + if falphabuffer <> nil then begin + falphabuffer.paint(canvas,falphabufferdest); + freeandnil(falphabuffer); + end; +end; + +procedure tcustomface.setimage(const value: tfacebitmap); +begin + fi.image.assign(value); +end; + +procedure tcustomface.setoptions(const avalue: faceoptionsty); +var + optionsbefore: faceoptionsty; +begin + include(flocalprops,fal_options); + if avalue <> fi.options then begin + optionsbefore:= fi.options; + fi.options:= faceoptionsty( + setsinglebit(longword(avalue),longword(fi.options), + [longword(faceoptionsmask1),longword(faceoptionsmask2)])); + if fao_alphafadeall in (faceoptionsty( + {$ifdef FPC}longword{$else}byte{$endif}(optionsbefore) xor + {$ifdef FPC}longword{$else}byte{$endif}(fi.options))) then begin + fintf.widgetregioninvalid; + end; + change; + end; +end; + +procedure tcustomface.setframei_left(const avalue: integer); +begin + include(flocalprops,fal_framei_left); + if fi.framei.left <> avalue then begin + fi.framei.left:= avalue; + change; + end; +end; + +procedure tcustomface.setframei_top(const avalue: integer); +begin + include(flocalprops,fal_framei_top); + if fi.framei.top <> avalue then begin + fi.framei.top:= avalue; + change; + end; +end; + +procedure tcustomface.setframei_right(const avalue: integer); +begin + include(flocalprops,fal_framei_right); + if fi.framei.right <> avalue then begin + fi.framei.right:= avalue; + change; + end; +end; + +procedure tcustomface.setframei_bottom(const avalue: integer); +begin + include(flocalprops,fal_framei_bottom); + if fi.framei.bottom <> avalue then begin + fi.framei.bottom:= avalue; + change; + end; +end; + +procedure tcustomface.setfade_color(const Value: tfadecolorarrayprop); +begin + include(flocalprops,fal_facolor); + fi.fade_color.assign(Value); +end; + +procedure tcustomface.setfade_pos(const Value: trealarrayprop); +begin + include(flocalprops,fal_fapos); + fi.fade_pos.assign(Value); +end; + +procedure tcustomface.setfade_opacolor(const Value: tfadeopacolorarrayprop); +begin + include(flocalprops,fal_faopacolor); + fi.fade_opacolor.assign(Value); +end; + +procedure tcustomface.setfade_opapos(const Value: trealarrayprop); +begin + include(flocalprops,fal_faopapos); + fi.fade_opapos.assign(Value); +end; + +procedure tcustomface.setfade_direction(const Value: graphicdirectionty); +begin + include(flocalprops,fal_fadirection); + if fi.fade_direction <> value then begin + fi.fade_direction:= Value; + change; + end; +end; + +procedure tcustomface.setfade_opacity(avalue: colorty); +begin + if avalue = cl_invalid then begin + avalue:= cl_none; + end; + include(flocalprops,fal_faopacity); + if fi.fade_opacity <> avalue then begin + fi.fade_opacity:= avalue; + change; + end; +end; + +procedure tcustomface.setframeimage_list(const avalue: timagelist); +begin + include(flocalprops,fal_frameimagelist); + if fi.frameimage_list <> avalue then begin + fintf.setlinkedvar(avalue,tmsecomponent(fi.frameimage_list)); + change; + end; +end; + +procedure tcustomface.setframeimage_offset(const avalue: integer); +begin + include(flocalprops,fal_frameimageoffset); + if fi.frameimage_offset <> avalue then begin + fi.frameimage_offset:= avalue; + change; + end; +end; + + +procedure tcustomface.settemplate(const avalue: tfacecomp); +begin + fintf.setlinkedvar(avalue,tmsecomponent(ftemplate)); + if (avalue <> nil) and not (csloading in avalue.componentstate) then begin + assign(avalue); + end; +end; + +procedure tcustomface.settemplateinfo(const ainfo: faceinfoty); +var + localbefore: facelocalpropsty; +begin + localbefore:= flocalprops; + if not (fal_facolor in flocalprops) then begin + fade_color:= ainfo.fade_color; + end; + if not (fal_fapos in flocalprops) then begin + fade_pos:= ainfo.fade_pos; + end; + if not (fal_faopacolor in flocalprops) then begin + fade_opacolor:= ainfo.fade_opacolor; + end; + if not (fal_faopapos in flocalprops) then begin + fade_opapos:= ainfo.fade_opapos; + end; + if not (fal_image in flocalprops) then begin + image:= ainfo.image; + end; + if not (fal_fadirection in flocalprops) then begin + fade_direction:= ainfo.fade_direction; + end; + if not (fal_faopacity in flocalprops) then begin + fade_opacity:= ainfo.fade_opacity; + end; + if not (fal_frameimagelist in flocalprops) then begin + fintf.setlinkedvar(ainfo.frameimage_list, + tmsecomponent(fi.frameimage_list)); + end; + if not (fal_frameimageoffset in flocalprops) then begin + fi.frameimage_offset:= ainfo.frameimage_offset; + end; + if not (fal_framei_left in flocalprops) then begin + fi.framei.left:= ainfo.framei.left; + end; + if not (fal_framei_top in flocalprops) then begin + fi.framei.top:= ainfo.framei.top; + end; + if not (fal_framei_right in flocalprops) then begin + fi.framei.right:= ainfo.framei.right; + end; + if not (fal_framei_bottom in flocalprops) then begin + fi.framei.bottom:= ainfo.framei.bottom; + end; + if not (fal_options in flocalprops) then begin + options:= ainfo.options; + end; + flocalprops:= localbefore; +end; + +procedure tcustomface.setlocalprops(avalue: facelocalpropsty); +begin + if flocalprops <> avalue then begin + if fal_fatransparency in avalue then begin + include(avalue,fal_faopacity); + end; + flocalprops:= avalue - deprecatedfacelocalprops; + if ftemplate <> nil then begin + settemplateinfo(ftemplate.template.fi); + end; + end; +end; + +function tcustomface.isoptionsstored: boolean; +begin + result:= (ftemplate = nil) or (fal_options in flocalprops); +end; + +function tcustomface.isframei_leftstored: boolean; +begin + result:= (ftemplate = nil) or (fal_framei_left in flocalprops); +end; + +function tcustomface.isframei_topstored: boolean; +begin + result:= (ftemplate = nil) or (fal_framei_top in flocalprops); +end; + +function tcustomface.isframei_rightstored: boolean; +begin + result:= (ftemplate = nil) or (fal_framei_right in flocalprops); +end; + +function tcustomface.isframei_bottomstored: boolean; +begin + result:= (ftemplate = nil) or (fal_framei_bottom in flocalprops); +end; + +function tcustomface.isimagestored: boolean; +begin + result:= (ftemplate = nil) or (fal_image in flocalprops); +end; + +function tcustomface.isfacolorstored: boolean; +begin + result:= (ftemplate = nil) or (fal_facolor in flocalprops); +end; + +function tcustomface.isfaposstored: boolean; +begin + result:= (ftemplate = nil) or (fal_fapos in flocalprops); +end; + +function tcustomface.isfaopacolorstored: boolean; +begin + result:= (ftemplate = nil) or (fal_faopacolor in flocalprops); +end; + +function tcustomface.isfaopaposstored: boolean; +begin + result:= (ftemplate = nil) or (fal_faopapos in flocalprops); +end; + +function tcustomface.isfadirectionstored: boolean; +begin + result:= (ftemplate = nil) or (fal_fadirection in flocalprops); +end; + +function tcustomface.isfaopacitystored: boolean; +begin + result:= (ftemplate = nil) or (fal_faopacity in flocalprops); +end; + +function tcustomface.isframeimage_liststored: boolean; +begin + result:= (ftemplate = nil) or (fal_frameimagelist in flocalprops); +end; + +function tcustomface.isframeimage_offsetstored: boolean; +begin + result:= (ftemplate = nil) or (fal_frameimageoffset in flocalprops); +end; + +procedure tcustomface.readtransparency(reader: treader); +begin + fade_opacity:= transparencytoopacity(reader.readinteger); +end; + +procedure tcustomface.defineproperties(filer: tfiler); +begin +// inherited; //no dummy necessary because of localprops + filer.defineproperty('dummy',@readdummy,nil,false); + filer.defineproperty('fade_transparency',@readtransparency,nil,false); +end; + +{ tfacetemplate } + +procedure tfacetemplate.internalcreate; +begin + fi.image:= tfacebitmap.create(nil); + fi.fade_pos:= trealarrayprop.Create; + fi.fade_color:= tfadecolorarrayprop.Create; + fi.fade_pos.link([fi.fade_color,fi.fade_pos]); + fi.fade_opapos:= trealarrayprop.Create; + fi.fade_opacolor:= tfadeopacolorarrayprop.Create; + fi.fade_opapos.link([fi.fade_opacolor,fi.fade_opapos]); + fi.fade_opacity:= cl_none; + fi.image.onchange:= {$ifdef FPC}@{$endif}doimagechange; + fi.fade_pos.onchange:= {$ifdef FPC}@{$endif}dochange; + fi.fade_color.onchange:= {$ifdef FPC}@{$endif}dochange; + fi.fade_opapos.onchange:= {$ifdef FPC}@{$endif}dochange; + fi.fade_opacolor.onchange:= {$ifdef FPC}@{$endif}dochange; +end; + +constructor tfacetemplate.create(const owner: tmsecomponent; + const onchange: notifyeventty); +begin + internalcreate; + inherited; +end; + +destructor tfacetemplate.destroy; +begin + inherited; + fi.image.Free; + fi.fade_pos.Free; + fi.fade_color.Free; + fi.fade_opapos.Free; + fi.fade_opacolor.Free; +end; + +procedure tfacetemplate.paint(const canvas: tcanvas; const arect: rectty); +var + bmp: tmaskedbitmap; + pt1: pointty; +begin + bmp:= nil; + facepaint(canvas,arect,fi,iface1(self),bmp,pt1); + bmp.free; +end; + +procedure tfacetemplate.setfade_direction(const Value: graphicdirectionty); +begin + fi.fade_direction:= Value; + changed; +end; + +procedure tfacetemplate.dochange(const sender: tarrayprop; const index: integer); +begin + updatefadearray(fi,sender); + changed; +end; + +procedure tfacetemplate.doimagechange(const sender: tobject); +begin + changed; +end; + +procedure tfacetemplate.setoptions(const avalue: faceoptionsty); +begin + fi.options:= faceoptionsty(setsinglebit(longword(avalue),longword(fi.options), + [longword(faceoptionsmask1),longword(faceoptionsmask2)])); + changed; +end; + +procedure tfacetemplate.setframei_left(const avalue: integer); +begin + fi.framei.left:= avalue; + changed; +end; + +procedure tfacetemplate.setframei_top(const avalue: integer); +begin + fi.framei.top:= avalue; + changed; +end; + +procedure tfacetemplate.setframei_right(const avalue: integer); +begin + fi.framei.right:= avalue; + changed; +end; + +procedure tfacetemplate.setframei_bottom(const avalue: integer); +begin + fi.framei.bottom:= avalue; + changed; +end; + +procedure tfacetemplate.setfade_color(const Value: tfadecolorarrayprop); +begin + fi.fade_color.Assign(Value); +end; + +procedure tfacetemplate.setfade_pos(const Value: trealarrayprop); +begin + fi.fade_pos.Assign(Value); +end; + +procedure tfacetemplate.setfade_opacolor(const Value: tfadeopacolorarrayprop); +begin + fi.fade_opacolor.Assign(Value); +end; + +procedure tfacetemplate.setfade_opapos(const Value: trealarrayprop); +begin + fi.fade_opapos.Assign(Value); +end; + +procedure tfacetemplate.setfade_opacity(avalue: colorty); +begin + if avalue = cl_invalid then begin + avalue:= cl_none; + end; + fi.fade_opacity:= avalue; + changed; +end; + +procedure tfacetemplate.setimage(const Value: tfacebitmap); +begin + fi.image.assign(value); + changed; +end; + +procedure tfacetemplate.setframeimage_list(const avalue: timagelist); +begin + setlinkedvar(avalue,tmsecomponent(fi.frameimage_list)); + changed; +end; + +procedure tfacetemplate.setframeimage_offset(const avalue: integer); +begin + fi.frameimage_offset:= avalue; + changed; +end; + +procedure tfacetemplate.doassignto(dest: tpersistent); +begin + if dest is tcustomface then begin + tcustomface(dest).settemplateinfo(fi); + end; +end; + +procedure tfacetemplate.copyinfo(const source: tpersistenttemplate); +begin + with tfacetemplate(source) do begin + self.setlinkedvar(frameimage_list,tmsecomponent(self.fi.frameimage_list)); + self.fi.image.assign(image); + self.fi.fade_pos.beginupdate; + self.fi.fade_color.beginupdate; + self.fi.fade_pos.assign(fade_pos); + self.fi.fade_color.assign(fade_color); + self.fi.fade_pos.endupdate(true); + self.fi.fade_color.endupdate; + end; +end; + +function tfacetemplate.getinfosize: integer; +begin + result:= sizeof(integer) + sizeof(fi.fade_direction); +end; + +function tfacetemplate.getinfoad: pointer; +begin + result:= @fi.fade_direction; +end; + +procedure tfacetemplate.readtransparency(reader: treader); +begin + fade_opacity:= transparencytoopacity(reader.readinteger); +end; + +procedure tfacetemplate.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('fade_transparency',@readtransparency,nil,false); +end; + +function tfacetemplate.translatecolor(const acolor: colorty): colorty; +begin + result:= acolor; +end; + +{ tfacecomp } + +function tfacecomp.gettemplate: tfacetemplate; +begin + result:= tfacetemplate(ftemplate); +end; + +procedure tfacecomp.settemplate(const Value: tfacetemplate); +begin + ftemplate.Assign(value); +end; + +function tfacecomp.gettemplateclass: templateclassty; +begin + result:= tfacetemplate; +end; + +{ tfacearrayprop } + +constructor tfacearrayprop.create(const aintf: iface); +begin + fintf:= aintf; +end; + +function tfacearrayprop.getitems(const index: integer): tface; +begin + result:= tface(inherited items[index]); +end; + +procedure tfacearrayprop.createitem(const index: integer; + var item: tpersistent); +begin + item:= tface.create(fintf); +end; + +class function tfacearrayprop.getitemclasstype: persistentclassty; +begin + result:= tface; +end; + +{ tfacelist } + +constructor tfacelist.create(aowner: tcomponent); +begin + flist:= tfacearrayprop.create(iface(self)); + inherited; +end; + +destructor tfacelist.destroy; +begin + inherited; + flist.free; +end; + +procedure tfacelist.paint(const canvas: tcanvas; const aindex: int32; + const dest: rectty); +begin + if (aindex >= 0) and (aindex <= high(flist.fitems)) then begin + tface(flist.fitems[aindex]).paint(canvas,dest); + end; +end; + +function tfacelist.lookup(const aindex: int32): int32; +begin + result:= aindex; + if findexlookup <> '' then begin + result:= -1; + if (aindex >= 0) and (aindex < length(findexlookup)) then begin + result:= pint16(findexlookup)[aindex]; + end; + end; +end; + +procedure tfacelist.setlist(const avalue: tfacearrayprop); +begin + flist.assign(avalue); +end; + +procedure tfacelist.invalidatewidget(); +begin + //dummy +end; + +procedure tfacelist.invalidaterect(const rect: rectty; + const org: originty = org_client; const noclip: boolean = false); +begin + //dummy +end; + +function tfacelist.translatecolor(const acolor: colorty): colorty; +begin + result:= acolor; +end; + +function tfacelist.getclientrect: rectty; +begin + result:= nullrect; +end; + +function tfacelist.getcomponentstate: tcomponentstate; +begin + result:= componentstate; +end; + +procedure tfacelist.widgetregioninvalid; +begin + //dummy +end; + +procedure tfacelist.setindexlookup(const avalue: msestring); +begin + findexlookup:= avalue; +end; + +procedure tfacelist.objectevent(const sender: tobject; + const event: objecteventty); +var + int1: integer; + fa1: tcustomface; +begin + inherited; + if (event = oe_changed) and (sender is tfacecomp) then begin + for int1:= 0 to list.count - 1 do begin + fa1:= tcustomface(flist.fitems[int1]); + if fa1.template = sender then begin + fa1.checktemplate(sender); + end; + end; + end; +end; + +{ twidget } + +constructor twidget.create(aowner: tcomponent); +begin + fnoinvalidate:= 1; + fwidgetstate:= defaultwidgetstates; + foptionsskin:= defaultoptionsskin; + fanchors:= defaultanchors; + foptionswidget:= defaultoptionswidget; + foptionswidget1:= defaultoptionswidget1; + fwidgetrect.cx:= defaultwidgetwidth; + fwidgetrect.cy:= defaultwidgetheight; + fcolor:= defaultwidgetcolor; + inherited; +end; + +constructor twidget.create(const aowner: tcomponent; + const aparentwidget: twidget; const aiswidget: boolean{ = true}); +begin + create(aowner); + setlockedparentwidget(aparentwidget); + if not aiswidget then begin + exclude(fwidgetstate,ws_iswidget); + end; + if (aowner = nil) and (aparentwidget <> nil) and + (csdesigning in aparentwidget.componentstate) then begin + //for streamed widget + setdesignwidget(); + end; +end; + +constructor twidget.createandinit(const aowner: tcomponent; + const aparentwidget: twidget; const aiswidget: boolean); +begin + create(aowner,aparentwidget,aiswidget); + initnewcomponent(1); + initnewwidget(1); +end; + +constructor twidget.create(const aowner: tcomponent; + const aparentwidget: twidget); +begin + if aparentwidget <> nil then begin + parentwidget:= aparentwidget; + end; + create(aowner); +end; + +procedure twidget.afterconstruction; +begin + inherited; + fnoinvalidate:= 0; +end; + +destructor twidget.destroy; +var + widget1: twidget; + window1: twindow; +begin + include(fwidgetstate,ws_destroying); + if (appinst <> nil) then begin + appinst.widgetdestroyed(self); + end; + window1:= fwindow; + widget1:= fparentwidget; + while (window1 = nil) and (widget1 <> nil) do begin + window1:= widget1.fwindow; + widget1:= widget1.fparentwidget; + end; + if window1 <> nil then begin + window1.widgetdestroyed(self); + end; + if fwidgets <> nil then begin + if ow_destroywidgets in foptionswidget then begin + while length(fwidgets) > 0 do begin + with fwidgets[high(fwidgets)] do begin + if ws_iswidget in fwidgetstate then begin + free; + end + else begin + fparentwidget:= nil; + fwindow:= nil; + exclude(fwidgetstate1,ws1_rootvalid); + setlength(self.fwidgets,high(self.fwidgets)); + end; + end; + end; + end + else begin + while length(fwidgets) > 0 do begin + widget1:= fwidgets[high(fwidgets)]; + if not (ow_nohidewidgets in foptionswidget) then begin + widget1.visible:= false; + end; + widget1.parentwidget:= nil; + end; + end; + fwidgets:= nil; + end; + hide; + if fparentwidget <> nil then begin + clearparentwidget; + end; + inherited; + fwindow.Free; + ffont.free; + ffontempty.free; + fframe.free; + fface.free; +// inherited; + destroyregion(fwidgetregion); +end; + +procedure twidget.initnewcomponent(const ascale: real); +begin + inherited; + scale(ascale); +end; + +procedure twidget.initnewwidget(const ascale: real); +begin + synctofontheight; +end; + +procedure twidget.createframe; +begin + if fframe = nil then begin + internalcreateframe; + end; +end; + +procedure twidget.createface; +begin + if fface = nil then begin + internalcreateface; + end; +end; + +procedure twidget.createfont; +begin + if ffont = nil then begin + internalcreatefont; + end; +end; + +procedure twidget.createfontempty; +begin + if ffontempty = nil then begin + internalcreatefontempty; + end; +end; + +function twidget.widgetcount: integer; +begin + result:= length(fwidgets); +end; + +function twidget.getcontainer: twidget; +begin + result:= self; +end; + +function twidget.containeroffset: pointty; +var + widget1: twidget; +begin + widget1:= getcontainer; + if widget1 = self then begin + result:= nullpoint; + end + else begin + result:= widget1.fwidgetrect.pos; + end; +end; + +function twidget.childrencount: integer; +begin + result:= widgetcount; +end; + +function twidget.visiblechildrencount: integer; +var + i1,i2: int32; +begin + i2:= 0; + for i1:= 0 to childrencount - 1 do begin + if children[i1].visible then begin + inc(i2); + end; + end; + result:= i2; +end; + +function twidget.getwidgets(const index: integer): twidget; +begin + if (index < 0) or (index > high(fwidgets)) then begin + tlist.error(slistindexerror,index); + end; + result:= fwidgets[index]; //fwidgets can be nil -> exception +end; + +function twidget.indexofwidget(const awidget: twidget): integer; +var + int1: integer; +begin + result:= -1; + for int1:= 0 to high(fwidgets) do begin + if fwidgets[int1] = awidget then begin + result:= int1; + break; + end; + end; +end; + +procedure twidget.changedirection(const avalue: graphicdirectionty; + var dest: graphicdirectionty); +var + dir1: graphicdirectionty; + int1: integer; +begin + if fface <> nil then begin + fface.fade_direction:= rotatedirection(fface.fade_direction,avalue,dest); + end; + if fframe <> nil then begin + fframe.changedirection(avalue,dest); + end; + dir1:= dest; + dest := avalue; + if (componentstate * [csdesigning,csloading] = [csdesigning]) and + ((dir1 in [gd_right,gd_left]) xor (avalue in [gd_right,gd_left])) then begin + int1:= bounds_cy; + bounds_cy:= bounds_cx; + bounds_cx:= int1; + end; +end; + +procedure twidget.placexorder(const startx: integer; const dist: array of integer; + const awidgets: array of twidget; const endmargin: integer = minint); + //origin = clientpos, endmargin by size adjust of widgets + //with [an_left,an_right], minit -> no change +var + int1,int2,int3,int4,int5: integer; + size1: sizety; + widget1: twidget; + ar1: integerarty; + bo1: boolean; +begin +{$ifdef mse_debuglayout} + debugwriteln('**placexorder '+inttostr(bounds_cx)+' '+name); +{$endif} + if (high(awidgets) >= 0) then begin + widget1:= awidgets[0].fparentwidget; + if widget1 <> nil then begin + setlength(ar1,length(awidgets)); + int2:= startx + widget1.clientwidgetpos.x; + for int1:= 0 to high(awidgets) do begin + ar1[int1]:= int2; + if int1 <= high(dist) then begin + int5:= dist[int1]; + end + else begin + if high(dist) >= 0 then begin + int5:= dist[high(dist)]; + end + else begin + int5:= 0; + end; + end; + int2:= int2 + int5 + awidgets[int1].fwidgetrect.cx; + {$ifdef mse_debuglayout} + debugwriteln(' '+inttostr(ar1[int1])+' '+ + inttostr(awidgets[int1].bounds_cx)+' '+ + inttostr(ar1[int1]+awidgets[int1].bounds_cx)+' '+ + awidgets[int1].name); + {$endif} + end; + if endmargin <> minint then begin + int2:= ar1[high(awidgets)] + awidgets[high(awidgets)].fwidgetrect.cx + + endmargin - (widget1.paintrect.x + widget1.paintrect.cx); + end + else begin + int2:= 0; + end; + int4:= 0; + size1.cy:= 0; + {$ifdef mse_debuglayout} + debugwriteln(' marginsaldo '+inttostr(int2)); + {$endif} + for int1:= 0 to high(awidgets) do begin + with awidgets[int1] do begin + bo1:= ws1_layoutplacing in fwidgetstate1; + try + {$ifdef mse_debuglayout} + debugwriteln(' a '+inttostr(bounds_x)+' '+inttostr(bounds_cx)+' '+ + inttostr(bounds_x+bounds_cx)+' '+name); + {$endif} + include(fwidgetstate1,ws1_layoutplacing); + bounds_x:= ar1[int1] + int4; + if anchors * [an_left,an_right] = [an_left,an_right] then begin + int3:= bounds_cx; + size1.cx:= bounds_cx - int2; + if fframe <> nil then begin + fframe.checkwidgetsize(size1); + end; + bounds_cx:= size1.cx; + int3:= bounds_cx - int3; //delta + int2:= int2 + int3; + int4:= int4 + int3; + end; + {$ifdef mse_debuglayout} + debugwriteln(' b '+inttostr(bounds_x)+' '+inttostr(bounds_cx)+' '+ + inttostr(bounds_x+bounds_cx)+' '+name); + {$endif} + finally + if not bo1 then begin + exclude(fwidgetstate1,ws1_layoutplacing); + end; + end; + end; + end; + end; + end; +end; + +procedure twidget.placeyorder(const starty: integer; const dist: array of integer; + const awidgets: array of twidget; const endmargin: integer = minint); + //origin = clientpos, endmargin by size adjust of widgets + //with [an_top,an_bottom], minit -> no change +var + int1,int2,int3,int4,int5: integer; + size1: sizety; + widget1: twidget; + ar1: integerarty; + bo1: boolean; +begin + if (high(awidgets) >= 0) then begin + widget1:= awidgets[0].fparentwidget; + if widget1 <> nil then begin + setlength(ar1,length(awidgets)); + int2:= starty + widget1.clientwidgetpos.y; + for int1:= 0 to high(awidgets) do begin + ar1[int1]:= int2; + if int1 <= high(dist) then begin + int5:= dist[int1]; + end + else begin + if high(dist) >= 0 then begin + int5:= dist[high(dist)]; + end + else begin + int5:= 0; + end; + end; + int2:= int2 + int5 + awidgets[int1].fwidgetrect.cy; + end; + if endmargin <> minint then begin + int2:= ar1[high(awidgets)] + awidgets[high(awidgets)].fwidgetrect.cy + + endmargin - (widget1.paintrect.y + widget1.paintrect.cy); + end + else begin + int2:= 0; + end; + int4:= 0; + size1.cx:= 0; + for int1:= 0 to high(awidgets) do begin + with awidgets[int1] do begin + bo1:= ws1_layoutplacing in fwidgetstate1; + try + include(fwidgetstate1,ws1_layoutplacing); + bounds_y:= ar1[int1] + int4; + if anchors * [an_top,an_bottom] = [an_top,an_bottom] then begin + int3:= bounds_cy; + size1.cy:= bounds_cy - int2; + if fframe <> nil then begin + fframe.checkwidgetsize(size1); + end; + bounds_cy:= size1.cy; + int3:= bounds_cy - int3; //delta + int2:= int2 + int3; + int4:= int4 + int3; + end; + finally + if not bo1 then begin + exclude(fwidgetstate1,ws1_layoutplacing); + end; + end; + end; + end; + end; + end; +end; + +function twidget.getwidgetrects(const awidgets: array of twidget): rectarty; +var + int1: integer; +begin + setlength(result,length(awidgets)); + for int1:= 0 to high(result) do begin + with awidgets[int1] do begin + result[int1]:= widgetrect; + if parentwidget <> self then begin + translatewidgetpoint1(result[int1].pos,parentwidget,self); + end; + end; + end; +end; + +procedure twidget.setwidgetrects(const awidgets: array of twidget; + const arects: rectarty); +var + int1: integer; + rect1: rectty; +begin + for int1:= 0 to high(awidgets) do begin + with awidgets[int1] do begin + rect1:= arects[int1]; + if parentwidget <> self then begin + translatewidgetpoint1(rect1.pos,self,parentwidget); + end; + widgetrect:= rect1; + end; + end; +end; + +function twidget.alignx(const mode: widgetalignmodety; + const awidgets: array of twidget; + const glue: widgetalignmodety = wam_none; + const margin: integer = 0): integer; + + function getrefpoint(const awidget: twidget): integer; + begin + with awidget do begin + updateroot; + case mode of + wam_start: begin + result:= frootpos.x + framepos.x; + if (fframe <> nil) and not (osk_nopaintref in foptionsskin) then begin + with fframe do begin + checkstate(); + result:= result + fwidth.left; + end; + end; + end; + wam_center: begin + result:= frootpos.x + framepos.x + framesize.cx div 2; + end; + else begin //wam_end + result:= frootpos.x + framepos.x + awidget.framesize.cx; + if (fframe <> nil) and not (osk_nopaintref in foptionsskin) then begin + with fframe do begin + checkstate(); + result:= result - fwidth.right; + end; + end; + end; + end; + end; + end; //getrefpoint + + procedure doshift(const awidget: twidget; const amode: widgetalignmodety; + const ashift: integer; var arect: rectty); + begin + with awidget do begin + if (amode = wam_start) and (an_right in anchors) then begin + arect.cx:= arect.cx - ashift; + end; + if (amode = wam_end) and (an_left in anchors) then begin + arect.cx:= arect.cx + ashift; + end + else begin + arect.x:= arect.x + ashift; + end; + end; + end; //doshift + +var + ref,shift,int1,int2,int3: integer; + ar1: rectarty; + +begin + result:= 0; + if (high(awidgets) >= 0) then begin + beginupdate(); + try + ref:= getrefpoint(awidgets[0]); + with awidgets[0] do begin + if fparentwidget <> nil then begin + result:= ref - fparentwidget.frootpos.x + end + else begin + result:= ref; + end; + end; + ar1:= getwidgetrects(awidgets); + if (mode <> wam_none) and (high(awidgets) > 0) then begin + for int1:= 1 to high(awidgets) do begin + int3:= ref - getrefpoint(awidgets[int1]); + doshift(awidgets[int1],mode,int3,ar1[int1]); + end; + end; + if (glue <> wam_none) then begin + shift:= 0; + case glue of + wam_start: begin + int2:= bigint; + for int1:= 0 to high(awidgets) do begin + int3:= ar1[int1].x; + if int3 < int2 then begin + int2:= int3; + end; + end; + shift:= margin+clientwidgetpos.x-int2; + end; + wam_end: begin + int2:= -bigint; + for int1:= 0 to high(awidgets) do begin + with ar1[int1] do begin + int3:= x+cx; + end; + if int3 > int2 then begin + int2:= int3; + end; + end; + shift:= clientwidgetpos.x+clientwidth - margin - int2; + end; + else begin //wam_center + if length(awidgets) > 0 then begin + with awidgets[0] do begin + shift:= margin + ar1[0].x + framepos.x + (framesize.cx+1) div 2; + end; + shift:= clientwidgetpos.x + clientwidth div 2 - shift; + end; + end; + end; + if shift <> 0 then begin + result:= result+shift; + for int1:= 0 to high(awidgets) do begin + doshift(awidgets[int1],glue,shift,ar1[int1]); + end; + end; + end; + setwidgetrects(awidgets,ar1); + finally + endupdate(); + end; + end; +end; + +function twidget.aligny(const mode: widgetalignmodety; + const awidgets: array of twidget; + const glue: widgetalignmodety = wam_none; + const margin: integer = 0): integer; + + function getrefpoint(const awidget: twidget): integer; + begin + with awidget do begin + updateroot; + case mode of + wam_start: begin + result:= frootpos.y + framepos.y; + if (fframe <> nil) and not (osk_nopaintref in foptionsskin) then begin + with fframe do begin + checkstate(); + result:= result + fwidth.top; + end; + end; + end; + wam_center: begin + result:= frootpos.y + framepos.y + framesize.cy div 2; + end; + else begin //wam_end + result:= frootpos.y + framepos.y + awidget.framesize.cy; + if (fframe <> nil) and not (osk_nopaintref in foptionsskin) then begin + with fframe do begin + checkstate(); + result:= result - fwidth.bottom; + end; + end; + end; + end; + end; + end; //getrefpoint + + procedure doshift(const awidget: twidget; const amode: widgetalignmodety; + const ashift: integer; var arect: rectty); + begin + with awidget do begin + if (amode = wam_start) and (an_bottom in anchors) then begin + arect.cy:= arect.cy - ashift; + end; + if (amode = wam_end) and (an_top in anchors) then begin + arect.cy:= arect.cy + ashift; + end + else begin + arect.y:= arect.y + ashift; + end; + end; + end; //doshift + +var + ref,shift,int1,int2,int3: integer; + ar1: rectarty; + +begin + result:= 0; + if (high(awidgets) >= 0) then begin + beginupdate(); + try + ref:= getrefpoint(awidgets[0]); + with awidgets[0] do begin + if fparentwidget <> nil then begin + result:= ref - fparentwidget.frootpos.y + end + else begin + result:= ref; + end; + end; + ar1:= getwidgetrects(awidgets); + if (mode <> wam_none) and (high(awidgets) > 0) then begin + for int1:= 1 to high(awidgets) do begin + int3:= ref - getrefpoint(awidgets[int1]); + doshift(awidgets[int1],mode,int3,ar1[int1]); + end; + end; + if (glue <> wam_none) then begin + shift:= 0; + case glue of + wam_start: begin + int2:= bigint; + for int1:= 0 to high(awidgets) do begin + int3:= ar1[int1].y; + if int3 < int2 then begin + int2:= int3; + end; + end; + shift:= margin+clientwidgetpos.y-int2; + end; + wam_end: begin + int2:= -bigint; + for int1:= 0 to high(awidgets) do begin + with ar1[int1] do begin + int3:= y+cy; + end; + if int3 > int2 then begin + int2:= int3; + end; + end; + shift:= clientwidgetpos.y+clientheight - margin - int2; + end; + else begin //wam_center + if length(awidgets) > 0 then begin + with awidgets[0] do begin + shift:= margin + ar1[0].y + framepos.y + (framesize.cy+1) div 2; + end; + shift:= clientwidgetpos.y + clientheight div 2 - shift; + end; + end; + end; + if shift <> 0 then begin + result:= result+shift; + for int1:= 0 to high(awidgets) do begin + doshift(awidgets[int1],glue,shift,ar1[int1]); + end; + end; + end; + setwidgetrects(awidgets,ar1); + finally + endupdate(); + end; + end; +end; + +function twidget.getchildwidgets(const index: integer): twidget; +begin + result:= getwidgets(index); +end; + +function compzorder(const l,r): integer; +begin + result:= 0; + if ow_background in twidget(l).foptionswidget then dec(result); + if ow_top in twidget(l).foptionswidget then inc(result); + if ow_background in twidget(r).foptionswidget then inc(result); + if ow_top in twidget(r).foptionswidget then dec(result); +end; + +procedure twidget.sortzorder; +begin + if not isloading then begin + sortarray(pointerarty(fwidgets),{$ifdef FPC}@{$endif}compzorder); + invalidatewidget; + end; +end; + +procedure twidget.registerchildwidget(const child: twidget); +var + flags: rootchangeflagsty; +begin + if indexofwidget(child) >= 0 then begin + guierror(gue_alreadyregistered,self,':'+child.name); + end; + setlength(fwidgets,high(fwidgets)+2); + fwidgets[high(fwidgets)]:= child; + flags:= [rcf_widgetregioninvalid]; + if child.fwindow <> fwindow then begin + flags:= flags + [rcf_windowremove,rcf_windowset]; + end; + child.rootchanged(flags); +// child.updateopaque(true); //for cl_parent + if not isloading then begin + child.updateopaque(true,false); //for cl_parent + child.ftaborder:= high(fwidgets); + sortzorder; + updatetaborder(child); + if child.isvisible then begin + widgetregionchanged(child); + if focused and not child.isloading then begin + checksubfocus(false); + end; + end; + end; +end; + +procedure twidget.unregisterchildwidget(const child: twidget); +begin + if fwidgets <> nil then begin + removeitem(pointerarty(fwidgets),child); + end; + if ffocusedchild = child then begin + ffocusedchild:= nil; + end; + if ffocusedchildbefore = child then begin + ffocusedchildbefore:= nil; + end; + if fdefaultfocuschild = child then begin + fdefaultfocuschild:= nil; + end; + child.rootchanged([rcf_widgetregioninvalid]); + if not isloading then begin + updatetaborder(nil); + if child.isvisible then begin + widgetregionchanged(child); + end; + end; +end; + +procedure twidget.setcolor(const avalue: colorty); +begin + if fcolor <> avalue then begin + fcolor:= avalue; + if not (csloading in componentstate) then begin + colorchanged; + end; + end; +end; + +function twidget.clearparentwidget: twidget; + //returns old parentwidget +begin + result:= fparentwidget; + fparentwidget:= nil; + fwindow:= nil; + result.unregisterchildwidget(self); +end; + +procedure twidget.setparentwidget(const Value: twidget); +var + newpos: pointty; + updatingbefore: boolean; +begin + if fparentwidget <> value then begin + updatingbefore:= ws1_parentupdating in fwidgetstate1; + include(fwidgetstate1,ws1_parentupdating); + try + if entered and (fwindow <> nil) then begin + window.nofocus; + if fwindow.focusedwidget <> nil then begin + exit; + end; + end; + if (value <> nil) then begin + if value = self then begin + raise exception.create('Recursive parent.'); + end; + if (fwindow <> nil) and ownswindow1 then begin + newpos:= translatewidgetpoint(fwidgetrect.pos,nil,value); +// fwindow.fownerwidget:= nil; + freeandnil(fwindow); + end + else begin + newpos:= fwidgetrect.pos; + end; + end + else begin + newpos:= addpoint(rootwidget.fwidgetrect.pos,rootpos); + fcolor:= translatecolor(fcolor); + end; + + if fparentwidget <> nil then begin + clearparentwidget; + end; + if fparentwidget <> nil then begin + exit; //interrupt + end; + fparentwidget:= Value; + fwidgetrect.pos:= newpos; + if fparentwidget <> nil then begin + fparentwidget.registerchildwidget(self); + if not (csloading in componentstate) and + not (ws_loadlock in fwidgetstate) then begin + fparentclientsize:= fparentwidget.minclientsize; + parentclientrectchanged; + end; + end + else begin + if visible and not (ws_destroying in fwidgetstate) and + not (csdestroying in componentstate) then begin + window.show(false); + end; + end; + if not isloading then begin + fontchanged; + colorchanged; + enabledchanged; //-> statechanged + parentchanged; + end; + finally + if not updatingbefore then begin + exclude(fwidgetstate1,ws1_parentupdating); + end; + end; + end; +end; + +procedure twidget.setlockedparentwidget(const avalue: twidget); +var + bo1: boolean; +begin + bo1:= ws_loadlock in fwidgetstate; + include(fwidgetstate,ws_loadlock); + try + setparentwidget(avalue); + finally + if not bo1 then begin + exclude(fwidgetstate,ws_loadlock); + end; + end; +end; + +procedure twidget.checkwidgetsize(var size: sizety); +var + si1: sizety; +begin + si1:= widgetminsize1(); + if si1.cx > 0 then begin + if size.cx < si1.cx then begin + size.cx:= si1.cx; + end; + end; + if si1.cy > 0 then begin + if size.cy < si1.cy then begin + size.cy:= si1.cy; + end; + end; + si1:= widgetmaxsize1(); + if si1.cx > 0 then begin + if size.cx > si1.cx then begin + size.cx:= si1.cx; + end; + end; + if si1.cy > 0 then begin + if size.cy > si1.cy then begin + size.cy:= si1.cy; + end; + end; +end; + +procedure twidget.checksizes(); +begin + if not (ws_minclientsizevalid in fwidgetstate) then begin + include(fwidgetstate,ws_minclientsizevalid); //avoid recursion + + fminscrollsize:= calcminscrollsize; //first + if fframe <> nil then begin + fframe.checkminscrollsize(fminscrollsize); + end; + fminclientsize:= fminscrollsize; + fminshrinksize:= calcminshrinksize(); + if fframe <> nil then begin + fframe.checkminclientsize(fminclientsize); + fframe.checkminshrinksize(fminshrinksize); + end + else begin + fminclientsize:= fwidgetrect.size; + end; + end; +end; + +function twidget.widgetminsize1: sizety; +begin + result:= fminsize; + if fframe <> nil then begin + with fframe do begin + if ow1_clientcxmin in foptionswidget1 then begin + result.cx:= result.cx + fpaintframe.left + fpaintframe.right; + end; + if ow1_clientcymin in foptionswidget1 then begin + result.cy:= result.cy + fpaintframe.left + fpaintframe.right; + end; + end; + end; +end; + +function twidget.widgetmaxsize1: sizety; +begin + result:= fmaxsize; + if fframe <> nil then begin + with fframe do begin + if (fmaxsize.cx > 0) and (ow1_clientcxmax in foptionswidget1) then begin + result.cx:= result.cx + fpaintframe.left + fpaintframe.right; + end; + if (fmaxsize.cy > 0) and (ow1_clientcymax in foptionswidget1) then begin + result.cy:= result.cy + fpaintframe.left + fpaintframe.right; + end; + end; + end; +end; + +function twidget.minclientsize: sizety; +begin + checksizes(); + result:= fminclientsize; +end; + +function twidget.minshrinksize: sizety; +begin + checksizes(); + result:= fminshrinksize; +end; + +function twidget.minscrollsize: sizety; +begin + checksizes(); + result:= fminscrollsize; +end; + +function twidget.calcminshrinksize: sizety; +begin + result:= widgetminsize1(); +{ + if fframe <> nil then begin + fframe.checkminshrinksize(result); + end; +} +end; + +procedure twidget.internalsetwidgetrect(value: rectty; + const windowevent: boolean); + + procedure checkwidgetregionchanged(var achanged: boolean); + var + bo1: boolean; + begin + if achanged then begin + achanged:= false; + if (fparentwidget <> nil) then begin + if fframe <> nil then begin + exclude(fframe.fstate,fs_rectsvalid); + bo1:= fs_widgetregionchanging in fframe.fstate; + include(fframe.fstate,fs_widgetregionchanging); + end; + try + fparentwidget.widgetregionchanged(self); //new position + finally + if fframe <> nil then begin + if not bo1 then begin + exclude(fframe.fstate,fs_widgetregionchanging); + end; + end; + end; + end; + end; + end; //checkwidgetregionchanged + + procedure movewidgetregion(const awidget: twidget; const dist: pointty); + var + int1: integer; + begin + with awidget do begin + if (ws1_widgetregionvalid in fwidgetstate1) then begin + regmove(fwidgetregion,dist); + end; + for int1:= 0 to high(fwidgets) do begin + movewidgetregion(fwidgets[int1],dist); + end; + end; + end; //movewidgetregion + +var + bo1,bo2,poscha,sizecha: boolean; + int1,int2,int3: integer; + setcountbefore: integer; + size1,size2: sizety; + ar1: widgetarty; + ar2,ar3: integerarty; + autosizecha: boolean; + autosi: sizety; + simi,sima: sizety; + rect1: rectty; +begin + autosizecha:= false; + if not (csloading in fcomponentstate) and (fparentwidget <> nil) then begin + if (fanchors * [an_left,an_right] = []) or + (fanchors * [an_top,an_bottom] = []) then begin + //instead of calling parentclientrectchanged() + rect1:= fparentwidget.clientwidgetrect; + if fanchors * [an_left,an_right] = [] then begin + value.x:= rect1.x; + value.cx:= rect1.cx; + end; + if fanchors * [an_top,an_bottom] = [] then begin + value.y:= rect1.y; + value.cy:= rect1.cy; + end; + end; + end; + if ([ow1_autowidth,ow1_autoheight]*foptionswidget1 <> []) and + not (csloading in componentstate) then begin + if not windowevent then begin + checkwidgetsize(value.size); + end; + size1:= value.size; + if fframe <> nil then begin + subsize1(size1,fframe.paintframedim); + end; + getautopaintsize(size1); + if fframe <> nil then begin + addsize1(size1,fframe.paintframedim); + end; + subsize1(size1,value.size); + size2:= value.size; + if not (ow1_autowidth in foptionswidget1) then begin + size1.cx:= 0; + end; + if not (ow1_autoheight in foptionswidget1) then begin + size1.cy:= 0; + end; + autosizecha:= (size1.cx <> 0) or (size1.cy <> 0); + inc(value.cx,size1.cx); + if (ow1_autosizeanright in foptionswidget1) and + not (an_right in fanchors) then begin + dec(value.x,size1.cx); + end; + inc(value.cy,size1.cy); + if (ow1_autosizeanbottom in foptionswidget1) and + not (an_bottom in fanchors) then begin + dec(value.y,size1.cy); + end; + autosi:= value.size; + if not windowevent then begin + checkwidgetsize(value.size); + end; + if (an_right in fanchors) and not + (ow1_noautosizeanright in foptionswidget1) then begin + dec(value.x,value.cx-size2.cx); + end; + if (an_bottom in fanchors) and not + (ow1_noautosizeanbottom in foptionswidget1) then begin + dec(value.y,value.cy-size2.cy); + end; + if ownswindow and windowevent and not (csloading in componentstate) then begin + simi:= widgetminsize1(); + sima:= widgetmaxsize1(); + if ow1_autowidth in foptionswidget1 then begin + simi.cx:= value.cx; + sima.cx:= value.cx; + end; + if ow1_autoheight in foptionswidget1 then begin + simi.cy:= value.cy; + sima.cy:= value.cy; + end; + fwindow.setsizeconstraints(simi,sima); + end; + end + else begin + if not windowevent then begin + checkwidgetsize(value.size); + end; + end; + poscha:= (value.x <> fwidgetrect.x) or (value.y <> fwidgetrect.y); + sizecha:= (value.cx <> fwidgetrect.cx) or (value.cy <> fwidgetrect.cy); + bo1:= (isvisible or (ws1_fakevisible in fwidgetstate1)) and (poscha or sizecha); + bo2:= bo1; //backup because of checkwidgetregionchanged + if bo1 and (fparentwidget <> nil) then begin + invalidatewidget; //old position + end; + if poscha then begin + if (fparentwidget <> nil) and ((fwidgetrect.x <> value.x) or + (fwidgetrect.y <> value.y)) then begin + include(fparentwidget.fwidgetstate1,ws1_childrectchanged); + end; + if fparentwidget <> nil then begin + movewidgetregion(self,subpoint(value.pos,fwidgetrect.pos)); + end; + fwidgetrect.x:= value.x; + fwidgetrect.y:= value.y; + rootchanged([]); + end; + if sizecha then begin + inc(fsetwidgetrectcount); + setcountbefore:= fsetwidgetrectcount; + if (componentstate * [csloading,csdesigning] = []) and + ((value.cx < fwidgetrect.cx) or (value.cy < fwidgetrect.cy)) then begin + int2:= 0; + setlength(ar1,length(fwidgets)); + for int1:= 0 to high(ar1) do begin + if ws1_tryshrink in fwidgets[int1].fwidgetstate1 then begin + ar1[int2]:= fwidgets[int1]; + inc(int2); + end; + end; + if int2 > 0 then begin + setlength(ar1,int2); + setlength(ar2,int2); + for int1:= 0 to int2-1 do begin + ar2[int1]:= ar1[int1].getshrinkpriority; + end; + sortarray(ar2,ar3); + orderarray(ar3,pointerarty(ar1)); + size1:= value.size; + if fframe <> nil then begin + subsize1(size1,fframe.paintframedim); + end; + if fframe <> nil then begin + fframe.checkminscrollsize(size1); + end; + size2:= clientsize; + if (size2.cx > size1.cx) or (size2.cy > size1.cy) then begin + int3:= 0; + repeat + exclude(fwidgetstate1,ws1_childrectchanged); + for int1:= int2-1 downto 0 do begin + ar1[int1].tryshrink(size1); + end; + inc(int3); + until not(ws1_childrectchanged in fwidgetstate1) or (int3 >= 4); + //emergency brake + end; + end; + end; + if (fparentwidget <> nil) and ((fwidgetrect.cx <> value.cx) or + (fwidgetrect.cy <> value.cy)) then begin + include(fparentwidget.fwidgetstate1,ws1_childrectchanged); + end; + fwidgetrect.cx:= value.cx; + fwidgetrect.cy:= value.cy; + invalidateparentminclientsize; + exclude(fwidgetstate,ws_minclientsizevalid); + if not (csloading in componentstate) then begin + checkwidgetregionchanged(bo1); + sizechanged; + if fsetwidgetrectcount <> setcountbefore then begin + if poscha and not (csloading in componentstate) then begin + poschanged; + end; + exit; + end; + end + else begin + if fframe <> nil then begin + exclude(fframe.fstate,fs_rectsvalid); + end; + end; + end; + checkwidgetregionchanged(bo1); + if poscha and not (csloading in componentstate) then begin + poschanged; + end; + if ownswindow1 then begin + if not (windowevent and (fwindow.windowpos in windowmaximizedstates)) then begin + fwindow.fnormalwindowrect:= fwidgetrect; + end; + if bo2 and (tws_windowvisible in fwindow.fstate) then begin + fwindow.checkwindow(windowevent); + end; + end; + if autosizecha and (fwidgetrect.cx = autosi.cx) and + (fwidgetrect.cy = autosi.cy) and (fautosizelevel < 6) then begin + //emergency break + inc(fautosizelevel); + try + internalsetwidgetrect(fwidgetrect,windowevent); + finally + dec(fautosizelevel); + end; + end; +end; + +procedure twidget.setwidgetrect(const Value: rectty); +var + bo1: boolean; +begin + bo1:= ws1_widgetrectsetting in fwidgetstate1; + include(fwidgetstate1,ws1_widgetrectsetting); + try + internalsetwidgetrect(value,false); + finally + if not bo1 then begin + exclude(fwidgetstate1,ws1_widgetrectsetting); + end; + end; +end; + +function twidget.getwidgetrect: rectty; +begin + result:= fwidgetrect; +end; + +function twidget.getright: integer; +begin + result:= fwidgetrect.x + fwidgetrect.cx; +end; + +procedure twidget.setright(const avalue: integer); +begin + if an_left in fanchors then begin + bounds_cx:= avalue - fwidgetrect.x; + end + else begin + bounds_x:= avalue - bounds_cx; + end; +end; + +function twidget.getbottom: integer; +begin + result:= fwidgetrect.y + fwidgetrect.cy; +end; + +procedure twidget.setbottom(const avalue: integer); +begin + if an_top in fanchors then begin + bounds_cy:= avalue - fwidgetrect.y; + end + else begin + bounds_y:= avalue - bounds_cy; + end; +end; + +procedure twidget.setsize(const Value: sizety); +var + rect1: rectty; +begin + rect1.pos:= fwidgetrect.pos; + rect1.size:= value; + internalsetwidgetrect(rect1,false); +end; + +procedure twidget.setpos(const Value: pointty); +var + rect1: rectty; +begin + rect1.size:= fwidgetrect.size; + rect1.pos:= value; + internalsetwidgetrect(rect1,false); +end; + +procedure twidget.setbounds_x(const Value: integer); +var + rect1: rectty; +begin + if fwidgetrect.x <> value then begin + rect1:= fwidgetrect; + rect1.x:= value; + internalsetwidgetrect(rect1,false); + end; +end; + +procedure twidget.setbounds_y(const Value: integer); +var + rect1: rectty; +begin + if fwidgetrect.y <> value then begin + rect1:= fwidgetrect; + rect1.y:= value; + internalsetwidgetrect(rect1,false); + end; +end; + +procedure twidget.setbounds_cx(const Value: integer); +var + rect1: rectty; +begin + if fwidgetrect.cx <> value then begin + rect1:= fwidgetrect; + if value < 0 then begin + rect1.cx:= 0; + end + else begin + rect1.cx:= value; + end; + internalsetwidgetrect(rect1,false); + end; +end; + +procedure twidget.setbounds_cy(const Value: integer); +var + rect1: rectty; +begin + if fwidgetrect.cy <> value then begin + rect1:= fwidgetrect; + if value < 0 then begin + rect1.cy:= 0; + end + else begin + rect1.cy:= value; + end; + internalsetwidgetrect(rect1,false); + end; +end; + +procedure twidget.updatesizerange(value: integer; var dest: integer); +begin + if dest <> value then begin + if value < 0 then begin + value:= 0; + end; + dest:= Value; + if value > 0 then begin + setwidgetrect(fwidgetrect); + end; + if not (csloading in componentstate) and ownswindow1 then begin + fwindow.sizeconstraintschanged; + end; + end; +end; + +procedure twidget.updatesizerange(const value: sizety; var dest: sizety); +begin + updatesizerange(value.cx,dest.cx); + updatesizerange(value.cy,dest.cy); +end; + +procedure twidget.setbounds_cxmin(const Value: integer); +begin + updatesizerange(value,fminsize.cx); +end; + +procedure twidget.setbounds_cymin(const Value: integer); +begin + updatesizerange(value,fminsize.cy); +end; + +procedure twidget.setbounds_cxmax(const Value: integer); +begin + updatesizerange(value,fmaxsize.cx); +end; + +procedure twidget.setbounds_cymax(const Value: integer); +begin + updatesizerange(value,fmaxsize.cy); +end; + +procedure twidget.setminsize(const avalue: sizety); +begin + updatesizerange(avalue,fminsize); +end; + +procedure twidget.setmaxsize(const avalue: sizety); +begin + updatesizerange(avalue,fmaxsize); +end; + +procedure twidget.dobeginread; +begin + if fframe <> nil then begin + exclude(fframe.fstate,fs_paintposinited); + end; + exclude(fwidgetstate1,ws1_parentclientsizeinited); + inherited; +end; + +procedure twidget.doendread; +begin + if fframe <> nil then begin + fframe.calcrects; //rects must be valid for parentfontchanged + end; + inherited; +end; + +procedure twidget.initparentclientsize; +var + int1: integer; +begin + if not (ws1_parentclientsizeinited in fwidgetstate1) then begin + include(fwidgetstate1,ws1_parentclientsizeinited); + if fparentwidget <> nil then begin + fparentclientsize:= fparentwidget.minclientsize; + end + else begin + fparentclientsize:= fwidgetrect.size; + end; + int1:= high(fwidgets); + while int1 >= 0 do begin //keep track of deleted widgets + if int1 <= high(fwidgets) then begin + fwidgets[int1].initparentclientsize; + end; + dec(int1); + end; + { + for int1:= 0 to high(fwidgets) do begin + fwidgets[int1].initparentclientsize; + end; + } + end; +end; + +procedure twidget.loaded; +begin + include(fwidgetstate,ws_loadedproc); + try + exclude(fwidgetstate1,ws1_widgetregionvalid); + initparentclientsize; + inherited; + doloaded; + sortzorder; + updatetaborder(nil); + parentfontchanged; + if ffont <> nil then begin + fontchanged; + end; +// if not (ws1_parentclientsizeinited in fwidgetstate1) then begin +// initparentclientsize; +// end; + sizechanged; + poschanged; + colorchanged; + enabledchanged; //-> statechanged + parentchanged; + visiblepropchanged; + if ownswindow1 and (ws_visible in fwidgetstate) and + (componentstate * [csloading,csinline] = []) then begin + fwindow.show(false); + end; + if showing then begin + doshow; + end; + finally + exclude(fwidgetstate,ws_loadedproc); + end; + updateskin; + if ws1_childscaled in fwidgetstate1 then begin + appinst.postevent(tobjectevent.create(ek_childscaled,ievent(self)), + [peo_local]); + end; +end; + +procedure twidget.setdesigning(value: boolean; + setchildren : boolean = true); +begin + if value then begin + include(fwidgetstate,ws_designing); //for widgetatpos condition + end + else begin + exclude(fwidgetstate,ws_designing); + end; + inherited; +end; + +function twidget.updateopaque(const children: boolean; + const widgetregioncall: boolean): boolean; + //true if widgetregionchanged called +var + bo1,bo2: boolean; + int1: integer; +begin + result:= false; + bo1:= ws_opaque in fwidgetstate; + if isvisible then begin + include(fwidgetstate,ws_isvisible); + if (fparentwidget = nil) or (fwidgetstate * [ws_nopaint] = []) and + (actualcolor <> cl_transparent) then begin + include(fwidgetstate,ws_opaque); + end + else begin + exclude(fwidgetstate,ws_opaque); + end; + end + else begin + fwidgetstate:= fwidgetstate - [ws_opaque,ws_isvisible]; + end; + if (bo1 <> (ws_opaque in fwidgetstate)) and (fparentwidget <> nil) + and not fparentwidget.isloading then begin + if widgetregioncall then begin + fparentwidget.widgetregionchanged(self); + end + else begin + bo2:= ws1_updateopaque in fwidgetstate1; + include(fwidgetstate1,ws1_updateopaque); + try + fparentwidget.widgetregionchanged(self); + finally + if not bo2 then begin + exclude(fwidgetstate1,ws1_updateopaque); + end; + end; + end; + result:= true; + end; + if children then begin + for int1:= 0 to high(fwidgets) do begin + fwidgets[int1].updateopaque(children,false); + end; + end; +end; + +procedure twidget.colorchanged; +var + int1: integer; +begin + updateopaque(true,false); + invalidatewidget; + for int1:= 0 to widgetcount - 1 do begin + with widgets[int1] do begin + if fcolor = cl_parent then begin + colorchanged; + end; + end; + end; +end; + +{$ifdef mse_with_ifi} + +function twidget.getifiwidgetstate: ifiwidgetstatesty; +begin + result:= [iws_loaded]; + if acs_releasing in factstate then begin + include(result,iws_releasing); + end; + if csdestroying in componentstate then begin + include(result,iws_releasing); + include(result,iws_destroying); + end; + if ws_visible in fwidgetstate then begin + include(result,iws_visible); + end; + if ws_enabled in fwidgetstate then begin + include(result,iws_enabled); + end; + if ws_entered in fwidgetstate then begin + include(result,iws_entered); + end; + if ws_focused in fwidgetstate then begin + include(result,iws_focused); + end; + if ws_active in fwidgetstate then begin + include(result,iws_active); + end; +end; + +procedure twidget.ifiwidgetstatechanged; +begin + if fifiserverintf <> nil then begin + fifiserverintf.statechanged(iificlient(self),getifiwidgetstate); + end; +end; + +{$endif} + +procedure twidget.statechanged; +begin + if fframe <> nil then begin + fframe.updatewidgetstate; + end; +{$ifdef mse_with_ifi} + ifiwidgetstatechanged; +{$endif} + if (fparentwidget <> nil) and fparentwidget.focused and canfocus then begin + fparentwidget.checksubfocus(false); + end; +end; + +procedure twidget.enabledchanged; +var + int1: integer; + bo1: boolean; +begin + bo1:= isenabled; + if not bo1 then begin + if focused then begin + window.setfocusedwidget(nil); + end; + end; + if fframe <> nil then begin + if bo1 or not (frl_nodisable in fframe.flocalprops) then begin + fframe.setdisabled(not bo1); + end; + end; + for int1:= 0 to widgetcount - 1 do begin + widgets[int1].enabledchanged; + end; + statechanged; + if (frame <> nil) then begin + fframe.enabledchanged(); + end; +end; + +procedure twidget.activechanged; +begin + statechanged; + if (ws_focused in fwidgetstate) and needsfocuspaint then begin + invalidatewidget; + end; + if (frame <> nil) then begin + fframe.activechanged; + end; +end; + +procedure twidget.visiblepropchanged; +begin + if fframe <> nil then begin + fframe.visiblechanged; + end; +end; + +procedure twidget.visiblechanged; +begin + updateopaque(false,false); + statechanged; +end; + +procedure twidget.poschanged; +begin + if fframe <> nil then begin + fframe.poschanged; + end; + if ownswindow1 then begin + fwindow.poschanged; + end; +end; + +procedure twidget.sizechanged; +var + bo1: boolean; +begin + if fframe <> nil then begin + with fframe do begin + bo1:= fs_stateupdating in fstate; + exclude(fstate,fs_stateupdating); + try + fframe.internalupdatestate(); + finally + if bo1 then begin + include(fstate,fs_stateupdating); + end; + end; + end; + end + else begin + clientrectchanged; + end; + if ownswindow1 then begin + fwindow.sizechanged; + end; +end; + +function twidget.getminshrinkpos: pointty; +begin + result:= fwidgetrect.pos; +// addpoint1(result,fminshrinkposoffset); +end; + +function twidget.getshrinkpriority: integer; +begin + result:= 0; +end; + +procedure twidget.tryshrink(const aclientsize: sizety); +begin + //dummy +end; + +function twidget.calcminscrollsize: sizety; +var + int1,int2: integer; + anch: anchorsty; + indent: framety; + clientorig: pointty; + pt1: pointty; + minsi: sizety; +begin + result:= nullsize; + if fframe <> nil then begin + indent:= fframe.fi.innerframe; + clientorig.x:= -fframe.fpaintrect.x-fframe.fclientrect.x; + clientorig.y:= -fframe.fpaintrect.y-fframe.fclientrect.y; + end + else begin + indent:= nullframe; + clientorig:= nullpoint; + end; + for int1:= 0 to high(fwidgets) do begin + with fwidgets[int1],fwidgetrect do begin + if (visible or (ow1_invisibleparentsizeextend in foptionswidget1)) and + not(ws1_nominsize in fwidgetstate1) or + (csdesigning in componentstate) then begin + pt1:= getminshrinkpos; + minsi:= minshrinksize; + if not (ow1_noparentwidthextend in foptionswidget1) then begin + anch:= fanchors * [an_left,an_right]; + if anch = [an_right] then begin + int2:= fparentclientsize.cx - x + indent.left - clientorig.x; + end + else begin + if anch = [] then begin + int2:= minsi.cx; + end + else begin + if anch = [an_left,an_right] then begin + int2:= fparentclientsize.cx - cx + minsi.cx; + end + else begin //[an_left] + int2:= clientorig.x + pt1.x + cx + indent.right; + end; + end; + end; + if int2 > result.cx then begin + result.cx:= int2; + end; + end; + + if not (ow1_noparentheightextend in foptionswidget1) then begin + anch:= fanchors * [an_top,an_bottom]; + if anch = [an_bottom] then begin + int2:= fparentclientsize.cy - y + indent.top - clientorig.y; + end + else begin + if anch = [] then begin + int2:= minsi.cy; + end + else begin + if anch = [an_top,an_bottom] then begin + int2:= fparentclientsize.cy - cy + minsi.cy; + end + else begin //[an_top] + int2:= clientorig.y + pt1.y + cy + indent.bottom; + end; + end; + end; + if int2 > result.cy then begin + result.cy:= int2; + end; + end; + end; + end; + end; +{ + if fframe <> nil then begin + fframe.checkminscrollsize(result); + end; +} +end; + +procedure twidget.childclientrectchanged(const sender: twidget); +begin + //dummy +end; + +procedure twidget.parentclientrectchanged; +var + size1,delta: sizety; + anch: anchorsty; + rect1: rectty; + int1: integer; + +begin + if ([csloading,csdestroying]*componentstate = []) and (fparentwidget <> nil) and + not (ws1_anchorsizing in fwidgetstate1) then begin + if ws1_scaling in fparentwidget.fwidgetstate1 then begin + fparentclientsize:= fparentwidget.minclientsize; + end + else begin + int1:= 0; //loopcount + repeat + size1:= fparentwidget.minclientsize(); + rect1:= fwidgetrect; + delta:= subsize(size1,fparentclientsize); + if ws1_anchorsetting in fwidgetstate1 then begin + delta:= nullsize; + exclude(fwidgetstate1,ws1_anchorsetting); + end; + anch:= fanchors * [an_left,an_right]; + if anch <> [an_left] then begin + if (anch = [an_left,an_right]) then begin + inc(rect1.cx,delta.cx); + end + else begin + if anch = [an_right] then begin + inc(rect1.x,delta.cx); + end + else begin + if anch = [] then begin + if fparentwidget <> nil then begin + rect1.x:= fparentwidget.clientwidgetpos.x; + rect1.cx:= fparentwidget.clientsize.cx; + end; + end; + end; + end; + end; + anch:= fanchors * [an_top,an_bottom]; + if anch <> [an_top] then begin + if (anch = [an_top,an_bottom]) then begin + inc(rect1.cy,delta.cy); + end + else begin + if anch = [an_bottom] then begin + inc(rect1.y,delta.cy); + end + else begin + if anch = [] then begin + if fparentwidget <> nil then begin + rect1.y:= fparentwidget.clientwidgetpos.y; + rect1.cy:= fparentwidget.clientsize.cy; + end; + end; + end; + end; + end; + fparentclientsize:= size1; + include(fwidgetstate1, ws1_anchorsizing); + try + setwidgetrect(rect1); + finally + exclude(fwidgetstate1, ws1_anchorsizing); + end; + inc(int1); + until sizeisequal(size1,fparentwidget.minclientsize) or (int1 > 5); + end; + end; +end; + +procedure twidget.widgetregioninvalid; +begin + exclude(fwidgetstate1,ws1_widgetregionvalid); + if not (ws_opaque in fwidgetstate) and (fparentwidget <> nil) then begin + fparentwidget.widgetregioninvalid; + end; +end; + +procedure twidget.clientrectchanged; +var + int1: integer; +begin + exclude(fwidgetstate,ws_minclientsizevalid); + widgetregioninvalid(); + if isvisible then begin + invalidatewidget; + reclipcaret; + end; + if (ws_loadedproc in fwidgetstate) then begin + parentclientrectchanged; + end + else begin + checkautosize; + end; + for int1:= 0 to high(fwidgets) do begin + with fwidgets[int1] do begin + if ([csloading,csdestroying] * componentstate = []) then begin + parentclientrectchanged(); + end; + end; + end; + if ([csloading,csdestroying] * componentstate = []) and + (fparentwidget <> nil) then begin + fparentwidget.childclientrectchanged(self); + end; +end; + +procedure twidget.widgetevent(const event: twidgetevent); +var + int1: integer; +begin + with event do begin + if ces_callchildren in state then begin + for int1:= 0 to high(fwidgets) do begin + if ces_processed in state then begin + break; + end; + fwidgets[int1].widgetevent(event); + end; + end; + end; +end; + +procedure twidget.sendwidgetevent(const event: twidgetevent); + //event will be destroyed +begin + try + widgetevent(event); + finally + event.Free1; + end; +end; + +procedure twidget.release(const nomodaldefer: boolean=false); +begin + if ownswindow1 then begin + window.endmodal; + end; + inherited; +end; + +procedure twidget.dobeforepaint(const canvas: tcanvas); +begin + //dummy +end; + +procedure twidget.dobeforepaintforeground(const canvas: tcanvas); +begin + //dummy +end; + +procedure twidget.dopaintforeground(const canvas: tcanvas); +begin + //dummy +end; + +procedure twidget.dopaintbackground(const canvas: tcanvas); +var + colorbefore: colorty; + face1: tcustomface; +begin + if frame <> nil then begin + colorbefore:= canvas.color; + canvas.color:= actualcolor; + fframe.paintbackground(canvas,makerect(nullpoint,fwidgetrect.size),true,true); + canvas.color:= colorbefore; + end; + if not canvas.clipregionisempty then begin + face1:= getactface; + if face1 <> nil then begin + if not (fao_overlay in face1.options) then begin + if fframe <> nil then begin + fframe.checkstate(); + canvas.remove(fframe.fclientrect.pos); + face1.paint(canvas,makerect(nullpoint,fframe.fpaintrect.size)); + canvas.move(fframe.fclientrect.pos); + end + else begin + face1.paint(canvas,makerect(nullpoint,fwidgetrect.size)); + end; + end; + end; + doonpaintbackground(canvas); + end; +end; + +procedure twidget.paintbackground(const canvas: tcanvas; + const arect: rectty); +var + colorbefore: colorty; + face1: tcustomface; + actcolor,col1: colorty; + pt1: pointty; +begin + canvas.save(); + actcolor:= actualcolor; + if (ws_opaque in fwidgetstate) or (actcolor <> cl_transparent) then begin + col1:= actcolor; + if actcolor = cl_transparent then begin + col1:= cl_background; //no parent + end; + canvas.fillrect(arect,col1); + end; + pt1:= canvas.origin; + if frame <> nil then begin + colorbefore:= canvas.color; + canvas.color:= actualcolor; + fframe.paintbackground(canvas,arect,true,true); + canvas.color:= colorbefore; + end; + if not canvas.clipregionisempty then begin + face1:= getactface; + if face1 <> nil then begin + if not (fao_overlay in face1.options) then begin + if fframe <> nil then begin + fframe.checkstate(); + canvas.remove(fframe.fclientrect.pos); + face1.paint(canvas,makerect(nullpoint, + subsize(arect.size,fframe.paintframedim))); + canvas.move(fframe.fclientrect.pos); + end + else begin + face1.paint(canvas,arect); + end; + end; + end; + end; + canvas.origin:= pt1; //no shift to paintrect +end; + +procedure twidget.doonpaintbackground(const canvas: tcanvas); +begin + //dummy +end; + +procedure twidget.dopaint(const canvas: tcanvas); +begin + dopaintbackground(canvas); + if not canvas.clipregionisempty then begin + dobeforepaintforeground(canvas); + dopaintforeground(canvas); + end; +end; + +procedure twidget.doonpaint(const canvas: tcanvas); +begin + //dummy +end; + +procedure twidget.dopaintoverlay(const canvas: tcanvas); +var + face1: tcustomface; +begin + face1:= getactface; + if face1 <> nil then begin + if fao_overlay in face1.options then begin + if fframe <> nil then begin + canvas.move(fframe.fpaintrect.pos); + face1.paint(canvas,makerect(nullpoint,fwidgetrect.size)); + canvas.remove(fframe.fpaintrect.pos); + end + else begin + face1.paint(canvas,makerect(nullpoint,fwidgetrect.size)); + end; + end; + end; + if fframe <> nil then begin + fframe.paintoverlay(canvas,makerect(nullpoint,fwidgetrect.size)); + end; +end; + +procedure twidget.paintoverlay(const canvas: tcanvas; + const arect: rectty); +var + face1: tcustomface; +begin + canvas.restore(); + face1:= getactface; + if face1 <> nil then begin + if fao_overlay in face1.options then begin + if fframe <> nil then begin + face1.paint(canvas,deflaterect(arect,fframe.paintframe)); + end + else begin + face1.paint(canvas,arect); + end; + end; + end; + if fframe <> nil then begin + fframe.paintoverlay(canvas,arect); + end; +end; + +function twidget.isgroupleader: boolean; +begin + result:= false; +end; + +function twidget.needsfocuspaint(): boolean; +begin + result:= (fframe <> nil) and fframe.needsfocuspaint; +end; + +function twidget.needsfocuspaintstate(): boolean; +begin + result:= needsfocuspaint() and (fwidgetstate * [ws_focused,ws_active] = + [ws_focused,ws_active]); +end; + +function twidget.getshowhint: boolean; +begin + result:= (ow_hinton in foptionswidget) or + not (ow_hintoff in foptionswidget) and + ((fparentwidget = nil) or fparentwidget.getshowhint); +end; + +procedure twidget.showhint(const aid: int32; var info: hintinfoty); +var + mstr1: msestring; +begin + if getshowhint and not(csdesigning in componentstate) then begin + if (aid <= hintidframe) and (fframe <> nil) then begin + fframe.showhint(aid,info); + end + else begin + mstr1:= hint; + if mstr1 <> '' then begin + info.caption:= mstr1; + end; + end; + end; +end; + +procedure twidget.doafterpaint(const canvas: tcanvas); +begin + if needsfocuspaintstate() then begin + if fframe <> nil then begin + fframe.dopaintfocusrect(canvas,makerect(nullpoint,fwidgetrect.size)); + end + else begin + drawfocusrect(canvas,makerect(nullpoint,fwidgetrect.size)); + end; + end; +end; + +function twidget.needsdesignframe: boolean; +begin + result:= + (ws_iswidget in fwidgetstate) and + not (ws1_nodesignframe in fwidgetstate1) and + (owner <> nil) and //no frame for toplevel + ( + ((fwidgetrect.cx = 0) or (fwidgetrect.cy = 0)) or + ( + ( + (fcolor = cl_transparent) or + (fparentwidget <> nil) and + (colortopixel(actualopaquecolor) = + colortopixel(fparentwidget.actualopaquecolor{backgroundcolor})) + ) and + ((fframe = nil) or + (fframe.fi.leveli = 0) and (fframe.fi.levelo = 0) and + ((fframe.fi.framewidth = 0) or (frame.fi.colorframe = cl_transparent)) + ) + ) + ); +end; + +procedure twidget.paint(const canvas: tcanvas); +label + endlab; +var + int1,int2: integer; + saveindex: integer; + actcolor: colorty; + col1: colorty; + reg1: gdiregionty; + rect1: rectty; + widget1: twidget; + bo1,bo2: boolean; + face1: tcustomface; + obj1: tobject; +begin + bo2:= ws1_painting in fwidgetstate1; + include(fwidgetstate1,ws1_painting); + canvas.save; + rect1.pos:= nullpoint; + rect1.size:= fwidgetrect.size; + canvas.intersectcliprect(rect1); + if canvas.clipregionisempty then begin + goto endlab; + end; + canvas.save; + if not (ws_nopaint in fwidgetstate) then begin + canvas.brushorigin:= nullpoint; + actcolor:= actualcolor; + saveindex:= canvas.save; + dobeforepaint(canvas); + if (high(fwidgets) >= 0) and + not (ws1_noclipchildren in fwidgetstate1) then begin + updatewidgetregion; + canvas.subclipregion(fwidgetregion.region); + end; + bo1:= not canvas.clipregionisempty; + if bo1 then begin + if (ws_opaque in fwidgetstate) or (actcolor <> cl_transparent) then begin + col1:= actcolor; + if actcolor = cl_transparent then begin + col1:= cl_background; //no parent + end; + canvas.fillrect(rect1,col1); + end; + {$ifdef mse_slowdrawing} + sleep(500); + {$endif} + canvas.font:= getfont; + canvas.color:= actcolor; + canvas.drawinfopo:= nil; + obj1:= canvas.target; + canvas.target:= self; + dopaint(canvas); + if not canvas.clipregionisempty then begin + doonpaint(canvas); + end; + canvas.target:= obj1; + end; + canvas.restore(saveindex); + if bo1 then begin + face1:= getactface; + if (face1 <> nil) and (fao_alphafadenochildren in face1.fi.options) then begin + canvas.move(paintpos); + face1.doalphablend(canvas); + canvas.remove(paintpos); + end; + end; + end + else begin + updatewidgetregion; + end; + if (widgetcount > 0) then begin + if (fframe <> nil) and not (ow_nochildpaintclip in foptionswidget) then begin + fframe.checkstate; + canvas.intersectcliprect(fframe.fpaintrect); + end; + rect1:= canvas.clipbox; + for int1:= 0 to widgetcount-1 do begin + widget1:= twidget(fwidgets[int1]); + with widget1 do begin + if isvisible and testintersectrect(rect1,fwidgetrect) then begin + saveindex:= canvas.save; + if not (ow_nochildclipsiblings in self.foptionswidget) then begin + for int2:= int1 + 1 to self.widgetcount - 1 do begin + with self.fwidgets[int2],tcanvas1(canvas) do begin + if visible and testintersectrect(widget1.fwidgetrect,fwidgetrect) then begin + //clip higher level siblings + if (ws_opaque in fwidgetstate) then begin + subcliprect(fwidgetrect); + end + else begin + reg1:= msegui.createregion(self.window.fgdi); + addopaquechildren(reg1); + subclipregion(reg1.region); + msegui.destroyregion(reg1); + end; + end; + end; + end; + end; + if not canvas.clipregionisempty then begin + canvas.move(fwidgetrect.pos); + paint(canvas); + end; + canvas.restore(saveindex); + end; + end; + end; + end; + canvas.restore; + canvas.brushorigin:= nullpoint; + face1:= getactface; + if (face1 <> nil) and (fao_alphafadeall in face1.fi.options) then begin + canvas.move(paintpos); + fface.doalphablend(canvas); + canvas.remove(paintpos); + end; + dopaintoverlay(canvas); + if (csdesigning in componentstate) and needsdesignframe then begin + canvas.dashes:= #2#3; + canvas.drawrect(makerect(0,0,fwidgetrect.cx-1,fwidgetrect.cy-1),cl_black); + canvas.dashes:= ''; + end; + doafterpaint(canvas); +endlab: + canvas.restore; + if not bo2 then begin + exclude(fwidgetstate1,ws1_painting); + end; +end; + +procedure twidget.parentwidgetregionchanged(const sender: twidget); +begin + //dummy +end; + +procedure twidget.widgetregionchanged(const sender: twidget); +var + int1: integer; +begin + if not (csdestroying in componentstate) then begin + widgetregioninvalid; + if sender = nil then begin + invalidate; + end + else begin + invalidaterect(sender.fwidgetrect,org_widget); + end; + if componentstate * [csloading,csdestroying] = [] then begin + for int1:= 0 to high(fwidgets) do begin + fwidgets[int1].parentwidgetregionchanged(sender); + end; + end; + end; +end; + +procedure twidget.addopaquechildren(var region: gdiregionty); +var + int1: integer; + widget: twidget; + rect1: rectty; +begin + if not ((fface <> nil) and (fao_alphafadeall in fface.fi.options)) then begin + updateroot; + if ws_isvisible in fwidgetstate then begin + rect1:= paintrect; + for int1:= 0 to widgetcount - 1 do begin + widget:= twidget(fwidgets[int1]); + if ws_opaque in widget.fwidgetstate then begin + regaddrect(region,moverect(intersectrect(rect1,widget.fwidgetrect), + frootpos)); + end + else begin + widget.addopaquechildren(region); + end; + end; + end; + end; +end; + +procedure twidget.updatewidgetregion; +begin + if not (ws1_widgetregionvalid in fwidgetstate1) then begin + destroyregion(fwidgetregion); + if widgetcount > 0 then begin + fwidgetregion:= createregion(window.fgdi); + addopaquechildren(fwidgetregion); +{ + if fframe <> nil then begin + frame.checkstate; + regintersectrect(fwidgetregion,makerect(fframe.fpaintrect.x+frootpos.x, + fframe.fpaintrect.y+frootpos.y, + fframe.fpaintrect.cx,fframe.fpaintrect.cy)); + end + else begin + regintersectrect(fwidgetregion,makerect(frootpos,fwidgetrect.size)); + end; +} + end; + include(fwidgetstate1,ws1_widgetregionvalid); + end; +end; + +function twidget.getgdi: pgdifunctionaty; +begin + result:= getdefaultgdifuncs; +end; + +procedure twidget.createwindow; +begin + twindow.create(self,getgdi); //sets fwindow +end; + +procedure twidget.updateroot; +begin + if not (ws1_rootvalid in fwidgetstate1) then begin + if fparentwidget <> nil then begin + fwindow:= fparentwidget.window; + frootpos:= addpoint(fparentwidget.rootpos,fwidgetrect.pos); + end + else begin + frootpos:= nullpoint; + if (fwindow = nil) and not (ws_destroying in fwidgetstate) then begin + createwindow; + invalidatewidget; + if (ws_visible in fwidgetstate) and + (componentstate * [csloading,csinline,csdestroying] = []) then begin + fwindow.show(false); + if not (ws_loadedproc in fwidgetstate) then begin + include(fwidgetstate1,ws1_rootvalid); + doshow(); + end; + end; + end; + end; + include(fwidgetstate1,ws1_rootvalid); + end; +end; + +procedure twidget.rootchanged(const aflags: rootchangeflagsty); +var + int1: integer; +begin + if fparentwidget <> nil then begin + fwindow:= nil; + end; + fwidgetstate1:= fwidgetstate1 - [{ws1_widgetregionvalid,}ws1_rootvalid]; + if rcf_widgetregioninvalid in aflags then begin + exclude(fwidgetstate1,ws1_widgetregionvalid); + end; + for int1:= 0 to high(fwidgets) do begin + fwidgets[int1].rootchanged(aflags); + end; +end; + +procedure twidget.parentchanged; +var + int1: integer; +begin + if not (ws_loadedproc in fwidgetstate) then begin + updateopaque(false,false); + parentfontchanged; + for int1:= 0 to high(fwidgets) do begin + with fwidgets[int1] do begin + parentchanged; + end; + end; + end; +end; + +function twidget.ownswindow1: boolean; +begin + result:= (fwindow <> nil) and (fwindow.fownerwidget = self); +end; + +function twidget.windowallocated: boolean; +begin + result:= (fwindow <> nil) and fwindow.haswinid and + (componentstate * [csloading,csdestroying] = []); + +end; + +function twidget.ownswindow: boolean; +begin + result:= (fwindow <> nil) and (fwindow.fownerwidget = self) and + (fwindow.fwindow.id <> 0); +end; + +function twidget.updaterect: rectty; //invalidated area, origin = clientpos +begin + result:= window.updaterect; + translateclientpoint1(result.pos,rootwidget,self); +end; + +function twidget.window: twindow; +begin + updateroot; + result:= fwindow; +end; + +function twidget.rootpos: pointty; +begin + updateroot; + result:= frootpos; +end; + +function twidget.rootwidgetrect: rectty; +begin + updateroot; + result.pos:= frootpos; + result.size:= fwidgetrect.size; +end; +function twidget.getscreenpos: pointty; +begin + updateroot; + result:= addpoint(frootpos,fwindow.screenpos); +end; + +procedure twidget.setscreenpos(const avalue: pointty); +begin + updateroot; + fwindow.screenpos:= subpoint(avalue,frootpos); +end; + +function twidget.clientpostowidgetpos(const apos: pointty): pointty; +begin + result:= addpoint(apos,clientwidgetpos); +end; + +function twidget.widgetpostoclientpos(const apos: pointty): pointty; +begin + result:= subpoint(apos,clientwidgetpos); +end; + +function twidget.widgetpostopaintpos(const apos: pointty): pointty; +begin + result:= subpoint(apos,paintpos); +end; + +function twidget.paintpostowidgetpos(const apos: pointty): pointty; +begin + result:= addpoint(apos,paintpos); +end; + +function twidget.rootwidget: twidget; +var + wi1,wi2: twidget; +begin + wi1:= self; + repeat + wi2:= wi1; + wi1:= wi2.fparentwidget; + until wi1 = nil; + result:= wi2; +end; + +function twidget.parentofcontainer: twidget; +var + widget1: twidget; +begin + result:= fparentwidget; + if (fparentwidget <> nil) then begin + widget1:= fparentwidget.fparentwidget; + if (widget1 <> nil) and not (ws_iswidget in result.fwidgetstate) then begin + result:= widget1; + end; + end; +end; + +function twidget.calcframewidth(arect: prectty): sizety; +begin + if fframe <> nil then begin + fframe.checkstate; + with arect^ do begin + result.cx:= fwidgetrect.cx - cx; + result.cy:= fwidgetrect.cy - cy; + end; + end + else begin + result:= nullsize; + end; +end; + +function twidget.framedim: sizety; + //widgetrect.size - paintrect.size +begin + {$ifdef FPC} {$checkpointer off} {$endif} + result:= calcframewidth(@fframe.fpaintrect); + {$ifdef FPC} {$checkpointer default} {$endif} +end; + +function twidget.framedimnoscrollbar: sizety; +begin + result:= framedim(); + if fframe <> nil then begin + fframe.addscrollbarwidth(result); + end; +end; + +function twidget.clientframewidth: sizety; + //widgetrect.size - clientrect.size +begin + {$ifdef FPC} {$checkpointer off} {$endif} + result:= calcframewidth(@fframe.fclientrect); + {$ifdef FPC} {$checkpointer default} {$endif} +end; + +function twidget.innerclientframewidth: sizety; + //widgetrect.size - innerclientrect.size +begin + {$ifdef FPC} {$checkpointer off} {$endif} + result:= calcframewidth(@fframe.finnerclientrect); + {$ifdef FPC} {$checkpointer default} {$endif} +end; + +function twidget.innerframewidth: sizety; +begin + if frame <> nil then begin + fframe.checkstate; + result.cx:= fframe.fclientrect.cx - fframe.finnerclientrect.cx; + result.cy:= fframe.fclientrect.cy - fframe.finnerclientrect.cy; + end + else begin + result:= nullsize; + end; +end; + +function twidget.framerect: rectty; +begin + if fframe <> nil then begin + fframe.checkstate; + result.pos:= pointty(fframe.fouterframe.topleft); + result.size:= framesize; + end + else begin + result.pos:= nullpoint; + result.size:= fwidgetrect.size; + end; +end; + +function twidget.framepos: pointty; +begin + if fframe <> nil then begin + fframe.checkstate; + result:= pointty(fframe.fouterframe.topleft); + end + else begin + result:= nullpoint; + end; +end; + +function twidget.frameinnerrect: rectty; +begin + if fframe <> nil then begin + fframe.checkstate; + result:= inflaterect(fframe.fpaintrect,fframe.fpaintframedelta); + end + else begin + result.pos:= nullpoint; + result.size:= fwidgetrect.size; + end; +end; + +function twidget.paintrect: rectty; +begin + if fframe <> nil then begin + fframe.checkstate; + result:= fframe.fpaintrect; + end + else begin + result.pos:= nullpoint; + result.size:= fwidgetrect.size; + end; +end; + +function twidget.paintclientrect: rectty; //origin = clientrect +begin + if fframe <> nil then begin + fframe.checkstate; + result.x:= -fframe.fclientrect.x; + result.y:= -fframe.fclientrect.y; + result.size:= fframe.fpaintrect.size; + end + else begin + result.pos:= nullpoint; + result.size:= fwidgetrect.size; + end; +end; + +function twidget.clippedpaintrect: rectty; //origin = pos, cliped by all parentpaintrects +var + po1: pointty; + widget1: twidget; +begin + result:= paintrect; + po1:= nullpoint; + widget1:= self; + while widget1.fparentwidget <> nil do begin + subpoint1(po1,widget1.fwidgetrect.pos); + widget1:= widget1.fparentwidget; + if not intersectrect(result,moverect(widget1.paintrect,po1),result) then begin + break; + end; + end; +end; + +function twidget.paintpos: pointty; +begin + if fframe <> nil then begin + fframe.checkstate; + result:= fframe.fpaintrect.pos; + end + else begin + result:= nullpoint; + end; +end; + +function twidget.innerpaintrect: rectty; //origin = pos +begin + if fframe <> nil then begin + result:= deflaterect(fframe.fpaintrect,fframe.fi.innerframe); + end + else begin + result.pos:= nullpoint; + result.size:= fwidgetrect.size; + end; +end; + +function twidget.widgetsizerect: rectty; //pos = nullpoint +begin + result.pos:= nullpoint; + result.size:= fwidgetrect.size; +end; + +function twidget.paintsizerect: rectty; //pos = nullpoint +begin + result.pos:= nullpoint; + result.size:= paintsize; +end; + +function twidget.clientsizerect: rectty; //pos = nullpoint +begin + result.pos:= nullpoint; + result.size:= clientsize; +end; + +function twidget.containerclientsizerect: rectty; //pos = nullpoint +begin + result.pos:= nullpoint; + result.size:= container.clientsize; +end; + +function twidget.getclientrect: rectty; +begin + if fframe <> nil then begin + with fframe do begin + checkstate; + result:= fclientrect; + end; + end + else begin + result.pos:= nullpoint; + result.size:= fwidgetrect.size; + end; +end; + +function twidget.windowpo: pwindowty; +begin + window.checkwindowid; + result:= @fwindow.fwindow; +end; + +function twidget.innerclientpos: pointty; +begin + if frame <> nil then begin + with frame do begin + checkstate; + result:= pointty(fi.innerframe.topleft); + end; + end + else begin + result:= nullpoint; + end; +end; + +function twidget.innerclientsize: sizety; +begin + if frame <> nil then begin + with frame do begin + checkstate; + result:= finnerclientrect.size; + end; + end + else begin + result:= fwidgetrect.size; + end; +end; + +function twidget.innerclientrect: rectty; +begin + if frame <> nil then begin + with frame do begin + checkstate; + result:= makerect(pointty(fi.innerframe.topleft),finnerclientrect.size); + end; + end + else begin + result:= clientrect; + end; +end; + +function twidget.innerparentrect: rectty; //origin = parentwidget.pos +begin + result:= innerwidgetrect; + addpoint1(result.pos,fwidgetrect.pos); +end; + +function twidget.innerwidgetrect: rectty; +begin + if fframe <> nil then begin + with frame do begin + checkstate; + result.pos:= addpoint(fpaintrect.pos,finnerclientrect.pos); + result.size:= finnerclientrect.size; + end; + end + else begin + result:= clientrect; + end; +end; + +procedure twidget.internalcreateframe; +begin + tframe.create(iscrollframe(self)); +end; + +function twidget.invalidateneeded: boolean; +begin + result:= showing and (fnoinvalidate = 0) and + not (csloading in componentstate); + if result then begin + updateroot; + end; +end; + +procedure twidget.invalidatewidget; //invalidates the whole widget +begin + if invalidateneeded then begin + fwindow.invalidaterect(makerect(frootpos,fwidgetrect.size),self); + end; +end; + +procedure twidget.invalidate; //invalidates the clientarea +begin + if invalidateneeded then begin + if fframe <> nil then begin + fwindow.invalidaterect(makerect(addpoint(frootpos,fframe.fpaintrect.pos), + fframe.fpaintrect.size),self); + end + else begin + fwindow.invalidaterect(makerect(frootpos,fwidgetrect.size),self); + end; + end; +end; + +procedure twidget.invalidaterect(const rect: rectty; + const org: originty = org_client; const noclip: boolean = false); +var + rect1,rect2: rectty; + po1: prectty; +begin + if invalidateneeded then begin + updateroot; + rect1:= rect; + rect2.pos:= nullpoint; + rect2.size:= fwidgetrect.size; + po1:= @rect2; + case org of + org_paint: begin + if fframe <> nil then begin + inc(rect1.x,fframe.fpaintrect.pos.x); + inc(rect1.y,fframe.fpaintrect.pos.y); + po1:= @fframe.fpaintrect; + end; + end; + org_client: begin + if fframe <> nil then begin + inc(rect1.x,fframe.fclientrect.pos.x); + inc(rect1.x,fframe.fpaintrect.pos.x); + inc(rect1.y,fframe.fclientrect.pos.y); + inc(rect1.y,fframe.fpaintrect.pos.y); + po1:= @fframe.fpaintrect; + end; + end; + org_inner: begin + if fframe <> nil then begin + inc(rect1.x,fframe.finnerclientrect.pos.x); + inc(rect1.y,fframe.finnerclientrect.pos.y); + inc(rect1.x,fframe.fpaintrect.pos.x); + inc(rect1.y,fframe.fpaintrect.pos.y); + po1:= @fframe.fpaintrect; + end; + end; + end; + if not noclip then begin + msegraphutils.intersectrect(rect1,po1^,rect1); + end; + inc(rect1.x,frootpos.x); + inc(rect1.y,frootpos.y); + fwindow.invalidaterect(rect1,self); + end; +end; + +procedure twidget.invalidateframestaterect(const rect: rectty; + const aframe: tcustomframe; const org: originty = org_client); +begin + if (fframe = nil) or (fframe.fi.frameimage_list = nil) then begin + invalidaterect(rect,org,true); + end + else begin + invalidaterect(inflaterect(rect,aframe.innerframe),org,true); +// invalidatewidget; + end; +end; + +procedure twidget.invalidateframestate(); +begin + if (fframe = nil) or ((fframe.fi.frameimage_list = nil) and + (fframe.fi.colorframedefault = cl_default)) then begin + invalidate(); + end + else begin + invalidatewidget(); + end; +end; + +function twidget.hasoverlappingsiblings(arect: rectty): boolean; +var + int1: integer; + widget1: twidget; +begin + result:= false; + if (fparentwidget <> nil) and showing then begin + updateroot; + addpoint1(arect.pos,fwidgetrect.pos); + for int1:= high(fparentwidget.fwidgets) downto 0 do begin + widget1:= fparentwidget.fwidgets[int1]; + if widget1 = self then begin + break; + end; + if intersectrect(widget1.fwidgetrect,arect,arect) and + widget1.showing then begin + result:= true; + exit; + end; + end; + result:= fparentwidget.hasoverlappingsiblings(arect); + end; +end; + +procedure twidget.internalcreateface; +begin + tface.create(self); +end; + +function twidget.widgetatpos(var info: widgetatposinfoty): twidget; +var + int1: integer; + astate: widgetstatesty; + ainfo: mouseeventinfoty; +begin + result:= nil; + with info do begin + if (pos.x < 0) or (pos.y < 0) or (pos.x >= fwidgetrect.cx) or + (pos.y >= fwidgetrect.cy) then begin + exit; + end + else begin + if info.mouseeventinfopo = nil then begin + fillchar(ainfo,sizeof(ainfo),0); + ainfo.pos:= info.pos; + updatemousestate(ainfo); + end + else begin + updatemousestate(info.mouseeventinfopo^); + end; + astate:= fwidgetstate; + if isvisible then begin + include(astate,ws_visible); + end; + if csdesigning in componentstate then begin + include(astate,ws_enabled); + end; + if parentstate * astate <> parentstate then begin + exit; + end; + end; + if (frame = nil) or (ow_nochildpaintclip in foptionswidget) or + pointinrect(pos,fframe.fpaintrect) then begin + for int1:= widgetcount - 1 downto 0 do begin + with widgets[int1] do begin + subpoint1(info.pos,fwidgetrect.pos); + if info.mouseeventinfopo <> nil then begin + info.mouseeventinfopo^.pos:= info.pos; + end; + result:= widgetatpos(info); + addpoint1(info.pos,fwidgetrect.pos); + if info.mouseeventinfopo <> nil then begin + info.mouseeventinfopo^.pos:= info.pos; + end; + if result <> nil then begin + exit; + end; + end; + end; + end; + if childstate * astate = childstate then begin + result:= self; + end; + end; +end; + +function twidget.widgetatpos(const pos: pointty): twidget; +var + info: widgetatposinfoty; +begin + fillchar(info,sizeof(info),0); + info.pos:= pos; + result:= widgetatpos(info); +end; + +function twidget.childatpos(const pos: pointty; const clientorigin: boolean = true): twidget; +var + widget1: twidget; + po1: pointty; + int1: integer; + +begin + widget1:= container; + result:= nil; + po1:= pos; + if clientorigin then begin + addpoint1(po1,clientwidgetpos); + end; + if widget1 <> self then begin + translatewidgetpoint1(po1,self,widget1); + end; + with widget1 do begin + for int1:= high(fwidgets) downto 0 do begin + with fwidgets[int1] do begin + if isvisible and pointinrect(po1,fwidgetrect) then begin + result:= widget1.fwidgets[int1]; + break; + end; + end; + end; + end; +end; + +function compxbanded(const l,r): integer; +begin + result:= (twidget(l).fwidgetrect.y + twidget(l).fwidgetrect.cy) - + twidget(r).fwidgetrect.y - 1; + if result >= 0 then begin + result:= -((twidget(r).fwidgetrect.y + twidget(r).fwidgetrect.cy) - + twidget(l).fwidgetrect.y - 1); + if result <= 0 then begin + result:= twidget(l).fwidgetrect.x - twidget(r).fwidgetrect.x; + end; + end; +end; + +function twidget.getsortxchildren(const banded: boolean = false): widgetarty; +//var +// int1: integer; +begin + result:= copy(container.fwidgets); + if banded then begin + sortarray(pointerarty(result),{$ifdef FPC}@{$endif}compxbanded); + end + else begin + sortwidgetsxorder(result); + end; +end; + +function compybanded(const l,r): integer; +begin + result:= (twidget(l).fwidgetrect.x + twidget(l).fwidgetrect.cx) - + twidget(r).fwidgetrect.x - 1; + if result >= 0 then begin + result:= -((twidget(r).fwidgetrect.x + twidget(r).fwidgetrect.cx) - + twidget(l).fwidgetrect.x - 1); + if result <= 0 then begin + result:= twidget(l).fwidgetrect.y - twidget(r).fwidgetrect.y; + end; + end; +end; + +function twidget.getsortychildren(const banded: boolean = false): widgetarty; +begin + result:= copy(container.fwidgets); + if banded then begin + sortarray(pointerarty(result),{$ifdef FPC}@{$endif}compybanded); + end + else begin + sortwidgetsyorder(result); + end; +end; + +function twidget.widgetatpos(const pos: pointty; const state: widgetstatesty): twidget; +var + info: widgetatposinfoty; +begin + fillchar(info,sizeof(info),0); + info.pos:= pos; + info.parentstate:= state; + info.childstate:= state; + result:= widgetatpos(info); +end; + +function twidget.getlogicalchildren: widgetarty; //children of container +var + int1,int2: integer; +begin + with container do begin + setlength(result,length(fwidgets)); + int2:= 0; + for int1:= 0 to high(result) do begin + result[int2]:= fwidgets[int1]; + if ws_iswidget in result[int2].fwidgetstate then begin + inc(int2); + end; + end; + setlength(result,int2); + end; +end; + +procedure twidget.addlogicalchildren(var achildren: widgetarty); +begin + stackarray(pointerarty(getlogicalchildren),pointerarty(achildren)); +end; + +function twidget.findlogicalchild(const aname: ansistring): twidget; +begin + result:= dofindwidget(getlogicalchildren,aname); +end; + +function twidget.enteredchild(): twidget; +var + i1: int32; +begin + result:= nil; + with container do begin + for i1:= 0 to high(fwidgets) do begin + if ws_entered in fwidgets[i1].fwidgetstate then begin + result:= fwidgets[i1]; + break; + end; + end; + end; +end; + +function twidget.mouseeventwidget(const info: mouseeventinfoty): twidget; +var + findinfo: widgetatposinfoty; +begin + fillchar(findinfo,sizeof(findinfo),0); + with findinfo do begin + pos:= info.pos; + mouseeventinfopo:= @info; + parentstate:= [ws_enabled,ws_isvisible]; + case info.eventkind of + ek_buttonpress,ek_buttonrelease: begin + childstate:= [ws_enabled,ws_isvisible,ws_wantmousebutton]; + end; + ek_mousemove,ek_mousepark: begin + childstate:= [ws_enabled,ws_isvisible,ws_wantmousemove]; + end; + ek_mousewheel: begin + childstate:= [ws_enabled,ws_isvisible{,ws_wantmousewheel}]; + end; + end; + end; + result:= widgetatpos(findinfo); +end; + +procedure twidget.updatemousestate(const info: mouseeventinfoty); +begin + fwidgetstate:= fwidgetstate - + [ws_mouseinclient,ws_wantmousebutton,ws_wantmousemove,ws_wantmousefocus]; + if fframe <> nil then begin + fframe.updatemousestate(self,info); + end + else begin + if not (ow_mousetransparent in foptionswidget) then begin + if (info.pos.x >= 0) and (info.pos.x < fwidgetrect.cx) and + (info.pos.y >= 0) and (info.pos.y < fwidgetrect.cy) then begin + fwidgetstate:= fwidgetstate + + [ws_mouseinclient,ws_wantmousebutton,ws_wantmousemove,ws_wantmousefocus]; + end; + end; + end; +end; + +function twidget.getclientoffset: pointty; +begin + if fframe <> nil then begin + with frame do begin + checkstate; + result:= addpoint(fpaintrect.pos,fclientrect.pos); + end; + end + else begin + result:= nullpoint; + end; +end; + +function twidget.isclientmouseevent(var info: mouseeventinfoty): boolean; +begin + with info do begin + if not (es_processed in eventstate) or + (info.eventkind = ek_mousemove) then begin + updatemousestate(info); + if [ws_mouseinclient,ws_clientmousecaptured] * fwidgetstate <> [] then begin + if (appinst.fclientmousewidget <> self) and not (es_child in eventstate) then begin + //call updaterootwidget + appinst.setclientmousewidget(self,info.pos); + end; + result:= true; + if fframe <> nil then begin + subpoint1(pos,getclientoffset); + end; + end + else begin + appinst.setclientmousewidget(nil,nullpoint); + result:= false; + end; + end + else begin + result:= false; + end; + end; +end; + +function twidget.wantmousefocus(const info: mouseeventinfoty): boolean; +begin + result:= not (es_nofocus in info.eventstate) and {not focused and} + (ws_wantmousefocus in fwidgetstate)and + (ow_mousefocus in foptionswidget) and canfocus; +{ + if result and focused then begin + activate; + result:= false; + end; +} +end; + +procedure twidget.mouseevent(var info: mouseeventinfoty); + + procedure doclientmouseevent; + begin + include(info.eventstate,es_client); + try + clientmouseevent(info); + if canassistive() {and (ws_iswidget in widgetstate)} then begin + assistiveserver.doclientmouseevent(getiassistiveclient(),info); + end; + finally + exclude(info.eventstate,es_client); + end; + end; //doclientmouseevent + +var + clientoffset: pointty; + wi1: twidget; +begin + exclude(fwidgetstate,ws_newmousecapture); + if info.eventstate * [es_child,es_processed] = [] then begin + include(info.eventstate,es_child); + try + childmouseevent(self,info); + finally + exclude(info.eventstate,es_child); + end; + end; + with info do begin + if not (eventkind in mouseregionevents) then begin + if not (ss_left in shiftstate) and + not((eventkind = ek_buttonrelease) and (button = mb_left)) then begin + exclude(fwidgetstate,ws_lclicked); + end; + if not (ss_middle in shiftstate) and + not((eventkind = ek_buttonrelease) and (button = mb_middle)) then begin + exclude(fwidgetstate,ws_mclicked); + end; + if not (ss_right in shiftstate) and + not((eventkind = ek_buttonrelease) and (button = mb_right)) then begin + exclude(fwidgetstate,ws_rclicked); + end; + end; + if not (es_processed in info.eventstate) then begin + clientoffset:= nullpoint; + case eventkind of + ek_mousemove,ek_mousepark: begin + if isclientmouseevent(info) then begin + doclientmouseevent; + clientoffset:= getclientoffset; + end; + end; + ek_mousecaptureend: begin + if ws_clientmousecaptured in fwidgetstate then begin + doclientmouseevent; + end; + end; + ek_clientmouseleave: begin + if (fframe <> nil) and frame.needsmouseenterinvalidate() then begin + invalidatewidget; + end; + if appinst.fmousewidget = self then begin + if fparentwidget <> nil then begin + fparentwidget.updatecursorshape(addpoint(appinst.fmousewidgetpos, + fparentwidget.fwidgetrect.pos)) {(true)}; + end + else begin + appinst.widgetcursorshape:= cr_default; + end; + end; + doclientmouseevent; + end; + ek_clientmouseenter: begin + if (fframe <> nil) and fframe.needsmouseenterinvalidate() then begin + invalidatewidget; + end; + updatecursorshape(info.pos){(true)}; + doclientmouseevent; + end; + ek_buttonpress: begin + if button = mb_left then begin + include(fwidgetstate,ws_lclicked); + if (fframe <> nil) and fframe.needsclickinvalidate() then begin + invalidatewidget; + end; + end; + if button = mb_middle then begin + include(fwidgetstate,ws_mclicked); + end; + if button = mb_right then begin + include(fwidgetstate,ws_rclicked); + end; + if appinst.fmousecapturewidget <> self then begin + include(fwidgetstate,ws_newmousecapture); + end; + appinst.capturemouse(self,true); + if isclientmouseevent(info) then begin + include(fwidgetstate,ws_clientmousecaptured); + doclientmouseevent; + clientoffset:= getclientoffset; + end; + { + wi1:= self; + repeat + with wi1 do begin + if wantmousefocus(info) then begin + if focused then begin + activate; + end + else begin + setfocus; + end; + break; + end; + end; + wi1:= wi1.parentwidget; + until wi1 = nil; + } + end; + ek_buttonrelease: begin + if (button = mb_left) and (fframe <> nil) and + fframe.needsclickinvalidate() then begin + invalidatewidget; + end; + if isclientmouseevent(info) then begin + doclientmouseevent; + clientoffset:= getclientoffset; + end; + end; + end; + addpoint1(pos,clientoffset); + end; + case eventkind of + ek_buttonpress: begin + wi1:= self; + repeat + with wi1 do begin + if wantmousefocus(info) then begin + if focused then begin + activate; + end + else begin + setfocus; + end; + break; + end; + end; + wi1:= wi1.parentwidget; + until wi1 = nil; + end; + ek_buttonrelease: begin + if button = mb_left then begin + exclude(fwidgetstate,ws_lclicked); + end; + if button = mb_middle then begin + exclude(fwidgetstate,ws_mclicked); + end; + if button = mb_right then begin + exclude(fwidgetstate,ws_rclicked); + end; + if (appinst <> nil) and ((shiftstate - mousebuttontoshiftstate(button)) * + mousebuttons = []) and + (appinst.fmousecapturewidget = self) then begin + if not (ws_mousecaptured in fwidgetstate) then begin + appinst.capturemouse(nil,false); + end + else begin + fwidgetstate:= fwidgetstate - [ws_clientmousecaptured]; + // appinst.ungrabpointer; ???? + end; + end; + end; + end; + end; +end; + +procedure twidget.mousepreview(const sender: twidget; + var info: mouseeventinfoty); +begin + if not (es_processed in info.eventstate) then begin + if (fparentwidget <> nil) and (self <> window.fmodalwidget) then begin + fparentwidget.mousepreview(sender,info); + end; + end; +end; + +procedure twidget.childmouseevent(const sender: twidget; + var info: mouseeventinfoty); +begin + if not (es_processed in info.eventstate) then begin + if (fparentwidget <> nil) and (self <> window.fmodalwidget) then begin + fparentwidget.childmouseevent(sender,info); + end; + end; +end; + + +procedure twidget.domousewheelevent(var info: mousewheeleventinfoty); +begin + //dummy +end; + +procedure twidget.mousewheelevent(var info: mousewheeleventinfoty); +var + bo1: boolean; + pt1: pointty; +begin + with info do begin + if not (es_processed in eventstate) then begin + if ow_mousewheel in foptionswidget then begin + domousewheelevent(info); + end; + if not (es_processed in eventstate) and (fparentwidget <> nil) and + (self <> window.fmodalwidget) then begin + pt1:= self.pos; + addpoint1(pos,pt1); + bo1:= es_child in eventstate; + try + include(eventstate,es_child); + fparentwidget.mousewheelevent(info); + finally + subpoint1(pos,pt1); + if not bo1 then begin + exclude(eventstate,es_child); + end; + end; + end; + end; + end; +end; + +procedure twidget.setclientclick; +begin + appinst.capturemouse(self,true); + fwidgetstate:= fwidgetstate + [ws_lclicked,ws_clientmousecaptured]; +end; + +procedure twidget.releasebuttonpressgrab(); +begin + if appinst.fmousecapturewidget = self then begin + appinst.ungrabpointer(); + end; +end; + +procedure twidget.clientmouseevent(var info: mouseeventinfoty); +begin + //dummy +end; + +function twidget.getclientpos: pointty; +begin + if fframe <> nil then begin + with frame do begin + checkstate; + result:= fclientrect.pos; + end + end + else begin + result:= nullpoint; + end; +end; + +function twidget.getclientsize: sizety; +begin + if fframe <> nil then begin + with fframe do begin + checkstate; + result:= fclientrect.size; + end; + end + else begin + result:= fwidgetrect.size; + end; +end; + +procedure twidget.changeclientsize(const delta: sizety); //asynchronouse +begin + application.postevent(tresizeevent.create(ievent(self),delta)); +end; + +procedure twidget.setanchordwidgetsize(const asize: sizety); +var + rect1: rectty; +begin + rect1.pos:= fwidgetrect.pos; + rect1.size:= asize; + if fanchors * [an_left,an_right] = [an_right] then begin + rect1.x:= rect1.x - rect1.cx + fwidgetrect.cx; + end; + if fanchors * [an_top,an_bottom] = [an_bottom] then begin + rect1.y:= rect1.y - rect1.cy + fwidgetrect.cy; + end; + widgetrect:= rect1; +end; + +procedure twidget.setclientsize(const asize: sizety); +begin + setanchordwidgetsize(addsize(asize,clientframewidth)); +end; + +function twidget.getclientwidth: integer; +begin + result:= getclientsize.cx; +end; + +procedure twidget.setclientwidth(const avalue: integer); +begin + setclientsize(makesize(avalue,getclientsize.cy)); +end; + +function twidget.getclientheight: integer; +begin + result:= getclientsize.cy; +end; + +procedure twidget.setclientheight(const avalue: integer); +begin + setclientsize(makesize(getclientsize.cx,avalue)); +end; + +function twidget.getpaintsize: sizety; +begin + if fframe <> nil then begin + fframe.checkstate; + result:= fframe.fpaintrect.size; + end + else begin + result:= fwidgetrect.size; + end; +end; + +procedure twidget.setpaintsize(const avalue: sizety); +begin + setanchordwidgetsize(addsize(avalue,framedim)); +end; + +function twidget.getframesize: sizety; +begin + if fframe <> nil then begin + fframe.checkstate; + with fframe.fouterframe do begin + result.cx:= fwidgetrect.cx - left - right; + result.cy:= fwidgetrect.cy - top - bottom; + end; + end + else begin + result:= fwidgetrect.size; + end; +end; + +procedure twidget.setframesize(const avalue: sizety); +var + si1: sizety; +begin + si1:= avalue; + if fframe <> nil then begin +// fframe.checkstate; + with fframe.fouterframe do begin + si1.cx:= si1.cx + left + right; + si1.cy:= si1.cy + top + bottom; + end; + end; + setanchordwidgetsize(si1); +end; + +procedure twidget.setframewidth(const avalue: integer); +begin + setframesize(ms(avalue,getframesize.cy)); +end; + +procedure twidget.setframeheight(const avalue: integer); +begin + setframesize(ms(getframesize.cx,avalue)); +end; + +procedure twidget.setpaintwidth(const avalue: integer); +begin + setpaintsize(ms(avalue,getpaintsize.cy)); +end; + +procedure twidget.setpaintheight(const avalue: integer); +begin + setpaintsize(ms(getpaintsize.cx,avalue)); +end; + +function twidget.getframeheight: integer; +begin + result:= getframesize.cy; +end; + +function twidget.getpaintwidth: integer; +begin + result:= getpaintsize.cx; +end; + +function twidget.getpaintheight: integer; +begin + result:= getpaintsize.cy; +end; + +function twidget.clientwidgetrect: rectty; //origin = pos +begin + if fframe <> nil then begin + with frame do begin + checkstate; + result:= fclientrect; + addpoint1(result.pos,fpaintrect.pos); + end + end + else begin + result.pos:= nullpoint; + result.size:= fwidgetrect.size; + end; +end; + +function twidget.widgetclientrect: rectty; //origin = clientrect.pos +begin + result.size:= fwidgetrect.size; + if fframe <> nil then begin + with frame do begin + checkstate; + result.x:= fpaintrect.x-fclientrect.x; + result.y:= fpaintrect.y-fclientrect.y; + end + end + else begin + result.pos:= nullpoint; + end; +end; + +function twidget.widgetscreenrect: rectty; //screen origin +begin + result.size:= fwidgetrect.size; + result.pos:= screenpos; +end; + +function twidget.clientwidgetpos: pointty; +begin + if fframe <> nil then begin + with frame do begin + checkstate; + result:= addpoint(fpaintrect.pos,fclientrect.pos); + end + end + else begin + result:= nullpoint; + end; +end; + +function twidget.innerclientpaintpos: pointty; //origin = paintpos +begin + if fframe <> nil then begin + with frame do begin + checkstate; + result:= fframe.finnerclientrect.pos; + end; + end + else begin + result:= nullpoint; + end; +end; + +function twidget.innerclientwidgetpos: pointty; //origin = pos +begin + if fframe <> nil then begin + with frame do begin + checkstate; + result:= addpoint(fpaintrect.pos,fframe.finnerclientrect.pos); + end; + end + else begin + result:= nullpoint; + end; +end; + +procedure twidget.innertopaintsize(var asize: sizety); +begin + if fframe <> nil then begin + with fframe do begin + asize.cx:= asize.cx + framei_left + framei_right; + asize.cy:= asize.cy + framei_top + framei_bottom; + end; + end; +end; + +procedure twidget.outertopaintsize(var asize: sizety); +begin + if fframe <> nil then begin + with fframe do begin + asize.cx:= asize.cx + frameo_left + frameo_right; + asize.cy:= asize.cy + frameo_top + frameo_bottom; + end; + end; +end; + +procedure twidget.painttowidgetsize(var asize: sizety); +begin + if fframe <> nil then begin + with fframe do begin + checkstate; + asize.cx:= asize.cx + fpaintframe.left + fpaintframe.right; + asize.cy:= asize.cy + fpaintframe.top + fpaintframe.bottom; + end; + end; +end; + +procedure twidget.widgettopaintsize(var asize: sizety); +begin + if fframe <> nil then begin + with fframe do begin + checkstate; + asize.cx:= asize.cx - (fpaintframe.left + fpaintframe.right); + asize.cy:= asize.cy - (fpaintframe.top + fpaintframe.bottom); + end; + end; +end; + +function twidget.clientparentpos: pointty; + //origin = parentwidget.pos +begin + result:= addpoint(fwidgetrect.pos,clientwidgetpos); +end; + +function twidget.refpos(const aorigin: originty): pointty; +begin + case aorigin of + org_screen: begin + result:= screenpos; + end; + org_widget: begin + result:= pos; + end; + org_client: begin + result:= parentclientpos; + end; + org_inner: begin + result:= addpoint(parentclientpos,innerclientpos); + end; + else begin + result:= nullpoint; + end; + end; +end; + +function twidget.paintparentrect: rectty; //origin = parentwidget.pos +begin + result:= paintrect; + addpoint1(result.pos,fwidgetrect.pos); +end; + +function twidget.paintparentpos: pointty; //origin = parentwidget.pos +begin + result:= addpoint(fwidgetrect.pos,paintpos); +end; + +function twidget.parentpaintpos: pointty; //origin = parentwidget.paintpos + //nullpoint if parent = nil +begin + if fparentwidget = nil then begin + result:= nullpoint; + end + else begin + result:= subpoint(fwidgetrect.pos,fparentwidget.paintpos); + end; +end; + +function twidget.paintrectparent: rectty; //origin = paintpos, + //nullrect if parent = nil, +begin + if fparentwidget = nil then begin + result:= nullrect; + end + else begin + result:= fparentwidget.paintrect; + subpoint1(result.pos,paintparentpos); + end; +end; + +function twidget.clientrectparent: rectty; //origin = paintpos, + //nullrect if parent = nil, +begin + if fparentwidget = nil then begin + result:= nullrect; + end + else begin + result:= fparentwidget.clientwidgetrect; + subpoint1(result.pos,paintparentpos); + end; +end; + +function twidget.getparentclientpos: pointty; //origin = parentwidget.clientpos +begin + result:= fwidgetrect.pos; + if fparentwidget <> nil then begin + subpoint1(result,fparentwidget.clientwidgetpos); + end; +end; + +procedure twidget.setparentclientpos(const avalue: pointty); +begin + if fparentwidget <> nil then begin + pos:= addpoint(avalue,fparentwidget.clientwidgetpos); + end + else begin + pos:= avalue; + end; +end; + +function twidget.checkdescendent(awidget: twidget): boolean; +begin + result:= false; + while awidget <> nil do begin + if awidget = self then begin + result:= true; + break; + end; + awidget:= awidget.fparentwidget; + end; +end; + +function twidget.checkancestor(awidget: twidget): boolean; + //true if widget is ancestor or self +var + widget1: twidget; +begin + result:= false; + if awidget <> nil then begin + widget1:= self; + while widget1 <> nil do begin + if widget1 = awidget then begin + result:= true; + break; + end; + widget1:= widget1.fparentwidget; + end; + end; +end; + +function twidget.canfocus: boolean; +begin + result:= (fwidgetstate * focusstates = focusstates) and + (componentstate*[csdesigning,csdestroying] = []) and + not releasing and + ((fparentwidget = nil) or fparentwidget.canfocus); +end; + +function twidget.checksubfocus(const aactivate: boolean): boolean; +var + widget1: twidget; +begin + result:= false; + if (ow_subfocus in foptionswidget) then begin + widget1:= ffocusedchild; + if widget1 = nil then begin + widget1:= ffocusedchildbefore; + end; + if (widget1 = nil) or (not widget1.canfocus) then begin + widget1:= defaultfocuschild; + end; + if (widget1 <> nil) and widget1.canfocus then begin + widget1.setfocus(aactivate); + result:= checkdescendent(window.ffocusedwidget); + end; + end; +end; + +function twidget.setfocus(aactivate: boolean = true): boolean; +begin + if not canfocus then begin + guierror(gue_cannotfocus,self); + end; + result:= checksubfocus(aactivate); + if not result then begin + window.setfocusedwidget(self); + //call updaterootwidget + if aactivate then begin + window.activate; + end; + result:= window.ffocusedwidget = self; + end; +end; + +procedure twidget.parentfocus; +var + widget1: twidget; +begin + widget1:= self; + while widget1 <> nil do begin + if widget1.canfocus then begin + widget1.setfocus(false); + break; + end; + widget1:= widget1.fparentwidget; + end; +end; + +function twidget.cantabfocus: boolean; +var + int1: integer; +begin + result:= (ow_tabfocus in foptionswidget) and + (fwidgetstate * focusstates = focusstates); + if result and (ow_subfocus in foptionswidget) then begin + for int1:= 0 to high(fwidgets) do begin + if fwidgets[int1].cantabfocus then begin + exit; + end; + end; + result:= false; + end; +end; + +function twidget.firsttabfocus: twidget; +var + ar1: widgetarty; + int1: integer; +begin + result:= nil; + ar1:= gettaborderedwidgets; + for int1:= 0 to high(ar1) do begin + if ar1[int1].cantabfocus then begin + result:= ar1[int1]; + break; + end; + end; +end; + +function twidget.lasttabfocus: twidget; +var + ar1: widgetarty; + int1: integer; +begin + result:= nil; + ar1:= gettaborderedwidgets; + for int1:= high(ar1) downto 0 do begin + if ar1[int1].cantabfocus then begin + result:= ar1[int1]; + break; + end; + end; +end; + +function twidget.findtabfocus(const ataborder: integer): twidget; +var + int1: integer; +begin + result:= nil; + for int1:= 0 to high(fwidgets) do begin + if (fwidgets[int1].ftaborder = ataborder) then begin + if fwidgets[int1].cantabfocus then begin + result:= fwidgets[int1]; + end; + break; + end; + end; +end; + +function twidget.nexttaborderoverride(const sender: twidget; + const down: boolean = false): twidget; +begin + result:= nil; + if fparentwidget <> nil then begin + result:= fparentwidget.nexttaborderoverride(sender,down); + end; +end; + +function twidget.nexttaborder(const down: boolean = false; + nowrap: boolean = false): twidget; +label + doreturn; +var + int1: integer; +begin + result:= nexttaborderoverride(self,down); + if (result = nil) and (fparentwidget <> nil) and + not (csdestroying in fparentwidget.componentstate) then begin + int1:= ftaborder; + if down then begin + repeat + dec(int1); + with fparentwidget do begin + if int1 < 0 then begin + if (ow_parenttabfocus in foptionswidget) and + (fparentwidget <> nil) then begin + result:= nexttaborder(down); + if result <> nil then begin + goto doreturn; + end; + end; + if nowrap then begin + exit; + end; + int1:= high(fwidgets); + end; + result:= findtabfocus(int1); + end; + until (result <> nil) or (int1 = ftaborder); + end + else begin + repeat + inc(int1); + with fparentwidget do begin + if int1 >= widgetcount then begin + if (ow_parenttabfocus in foptionswidget) and + (fparentwidget <> nil) then begin + result:= nexttaborder(down,nowrap); + if result <> nil then begin + goto doreturn; + end; + end; + if nowrap then begin + exit; + end; + int1:= 0; + end; + result:= findtabfocus(int1); + end; + until (result <> nil) or (int1 = ftaborder); + end; + end; + +doreturn: + if (result <> nil) and (ow_parenttabfocus in result.foptionswidget) then begin + if down then begin + result:= result.container.lasttabfocus; + end + else begin + result:= result.container.firsttabfocus; + end; + end; +end; + +procedure twidget.doenter; +begin + //dummy +end; + +procedure twidget.internaldoenter; +begin +{$ifdef mse_debugwidgetfocus} + if not (ws_entered in fwidgetstate) then begin + debugwriteln(debugwidgetname(self,'!*+internaldoenter new ')); + end + else begin + debugwriteln(debugwidgetname(self,'**+internaldoenter ')); + end; +{$endif} + if not (ws_entered in fwidgetstate) then begin + include(fwidgetstate,ws_entering); + try + if fparentwidget <> nil then begin + with fparentwidget do begin + // if ffocusedchildbefore <> self then begin + ffocusedchildbefore:= ffocusedchild; + // end; + ffocusedchild:= self; + end; + end; + include(fwidgetstate,ws_entered); + if (canassistive()) and (ws_iswidget in widgetstate) then begin + assistiveserver.doenter(getiassistiveclient()); + end; + doenter; + if needsfocuspaint then begin + invalidatewidget; + end; + finally + exclude(fwidgetstate,ws_entering); + end; + end; +end; + +procedure twidget.doexit; +begin + //dummy +end; + +procedure twidget.internaldoexit; +begin +{$ifdef mse_debugwidgetfocus} + if (ws_entered in fwidgetstate) then begin + debugwriteln(debugwidgetname(self,'!*-internaldoexit new ')); + end + else begin + debugwriteln(debugwidgetname(self,'**-internaldoexit ')); + end; +{$endif} + if ws_entered in fwidgetstate then begin + include(fwidgetstate,ws_exiting); + try + ffocusedchildbefore:= ffocusedchild; + ffocusedchild:= nil; + exclude(fwidgetstate,ws_entered); + if needsfocuspaint then begin + invalidatewidget; + end; + if (ow1_canclosenil in foptionswidget1) then begin + if not canclose(nil) then begin + exit; + end; + end; + doexit; + finally + exclude(fwidgetstate,ws_exiting); + end; + end; +end; + +procedure twidget.dofocus; +begin + //dummy +end; + +procedure twidget.internaldofocus; + {$ifdef mse_with_ifi} +var + lwo1: longword; + {$endif} +begin +{$ifdef mse_debugwidgetfocus} + if not (ws_focused in fwidgetstate) then begin + debugwriteln(debugwidgetname(self,'!***+internaldofocus new ')); + end + else begin + debugwriteln(debugwidgetname(self,'****+internaldofocus ')); + end; +{$endif} + if not (ws_focused in fwidgetstate) then begin + include(fwidgetstate,ws_focused); + {$ifdef mse_with_ifi} + lwo1:= window.focuscount; + {$endif} + dofocus; + {$ifdef mse_with_ifi} + if lwo1 = window.focuscount then begin + ifiwidgetstatechanged; + end; + {$endif} + if fparentwidget <> nil then begin + fparentwidget.dochildfocused(self); + end; + if fframe <> nil then begin + fframe.focusedchanged(); + end; + end; +end; + +procedure twidget.dodefocus; +begin + //dummy +end; + +procedure twidget.dochildfocused(const sender: twidget); +begin + //dummy +end; + +procedure twidget.dofocuschanged(const oldwidget,newwidget: twidget); +var + int1: integer; +begin + for int1:= 0 to high(fwidgets) do begin + fwidgets[int1].dofocuschanged(oldwidget,newwidget); + end; +end; + +procedure twidget.internaldodefocus; + {$ifdef mse_with_ifi} +var + lwo1: longword; + {$endif} +begin +{$ifdef mse_debugwidgetfocus} + if (ws_focused in fwidgetstate) then begin + debugwriteln(debugwidgetname(self,'!***-internaldodefocus new ')); + end + else begin + debugwriteln(debugwidgetname(self,'****-internaldodefocus')); + end; +{$endif} + if ws_focused in fwidgetstate then begin + exclude(fwidgetstate,ws_focused); + {$ifdef mse_with_ifi} + lwo1:= window.focuscount; + {$endif} + dodefocus; + {$ifdef mse_with_ifi} + if lwo1 = window.focuscount then begin + ifiwidgetstatechanged; + end; + {$endif} + if fframe <> nil then begin + fframe.focusedchanged(); + end; + end; +end; + +function twidget.focusback(const aactivate: boolean = true): boolean; +begin + if fparentwidget <> nil then begin + with fparentwidget do begin + if (ffocusedchildbefore <> nil) and (ffocusedchildbefore <> self) and + (ffocusedchildbefore.canfocus) then begin + ffocusedchildbefore.setfocus(aactivate); + result:= true; + end + else begin + result:= focusback(aactivate); + end; + end; + end + else begin + result:= false; + end; +end; + +procedure twidget.internaldoactivate; +begin +{$ifdef mse_debugwidgetfocus} + if not (ws_active in fwidgetstate) then begin + debugwriteln(debugwidgetname(self,'!**+internaldoactivate new ')); + end + else begin + debugwriteln(debugwidgetname(self,'***+internaldoactivate ')); + end; +{$endif} + if not (ws_active in fwidgetstate) then begin + include(fwidgetstate,ws_active); + doactivate; + if canassistive() then begin + assistiveserver.doactivate(getiassistiveclient()); + end; + doafteractivate(); + end; +end; + +procedure twidget.internaldodeactivate; +begin +{$ifdef mse_debugwidgetfocus} + if (ws_active in fwidgetstate) then begin + debugwriteln(debugwidgetname(self,'!**-internaldodeactivate new ')); + end + else begin + debugwriteln(debugwidgetname(self,'***-internaldodeactivate ')); + end; +{$endif} + if ws_active in fwidgetstate then begin + exclude(fwidgetstate,ws_active); + dodeactivate; + if canassistive() then begin + assistiveserver.dodeactivate(getiassistiveclient()); + end; + end; +end; + +procedure twidget.doloaded; +begin + //dummy +end; + +procedure twidget.dohide; +var + int1: integer; +begin + visiblechanged; + if appinst.fmousecapturewidget = self then begin + releasemouse; + end; + if appinst.fmousewidget = self then begin + appinst.setmousewidget(nil); + end; + if appinst.fhintforwidget = self then begin + appinst.hidehint; + end; + { + if (window.focusedwidget = self) and + (fparentwidget <> nil) and fparentwidget.visible then begin +// (fwindow.visible or not (ws_visible in fwidgetstate)) then begin + nextfocus; + end; + } + for int1:= 0 to high(fwidgets) do begin + with fwidgets[int1] do begin + if ws_visible in fwidgetstate then begin + dohide; + end; + end; + end; +end; + +procedure twidget.internalhide(const windowevent: boolean); +var + bo1,bo2: boolean; +begin + bo1:= ws_visible in fwidgetstate; + bo2:= false; + if showing then begin + if bo1 and not (csdestroying in componentstate) then begin + updateroot; + window.invalidaterect(makerect(frootpos,fwidgetrect.size),self); + //invalidate old position and size + end; + exclude(fwidgetstate,ws_visible); + dohide; + end + else begin + exclude(fwidgetstate,ws_visible); + bo2:= updateopaque(false,true); + end; + if ws_visible in fwidgetstate then begin + exit; //show called + end; + if bo1 then begin + if not bo2 and (fparentwidget <> nil) and + not (csdestroying in fparentwidget.componentstate) and + not fparentwidget.isloading then begin + fparentwidget.widgetregionchanged(self); + end; + if ownswindow1 then begin + fwindow.hide(windowevent); + end; + if (fwindow <> nil) and (fparentwidget<> nil) and + not (csdestroying in fparentwidget.componentstate) and + checkdescendent(fwindow.focusedwidget) then begin + nextfocus; + if (fwindow <> nil) and checkdescendent(fwindow.focusedwidget) then begin + show; //defocus was not possible + end; + end; + end; +end; + +procedure twidget.hide; +begin + internalhide(false); +end; + +procedure twidget.doshow; +var + int1: integer; +begin + if not (ws_loadedproc in fwidgetstate) then begin + visiblechanged; + for int1:= 0 to widgetcount - 1 do begin + with widgets[int1] do begin + if not (csloading in componentstate) and //doshow from loaded pending + (fwidgetstate * [ws_visible,ws_showproc] = [ws_visible]) then begin + doshow(); + end; + end; + end; + end; +end; + +function twidget.internalshow(const modallevel: modallevelty; + const transientfor: pwindow; //follow linked var state + const windowevent,nomodalforreset: boolean): modalresultty; +var + bo1,bo2: boolean; + modaltransientfor: twindow; +// w1: twidget; + info: showinfoty; +begin + if modallevel = ml_application then begin + modaltransientfor:= nil; + info.transientfor:= nil; + if transientfor^ = nil then begin + setlinkedvar(fwindow.defaulttransientfor,tlinkedobject(info.transientfor)); + modaltransientfor:= info.transientfor; +// transientfor:= fwindow.defaulttransientfor; +// modaltransientfor:= transientfor; + end + else begin + setlinkedvar(transientfor^,tlinkedobject(info.transientfor)); + end; + info.widget:= nil; + setlinkedvar(self,tmsecomponent(info.widget)); + try +// info.transientfor:= transientfor; + info.windowevent:= windowevent; + info.nomodalforreset:= nomodalforreset; + if window.beginmodal(@info) or (info.widget = nil) then begin + result:= mr_windowdestroyed; + exit; + end; + if modaltransientfor <> nil then begin + window.settransientfor(nil,false); + end; + finally + if info.widget <> nil then begin //else self is destroyed + setlinkedvar(nil,tlinkedobject(info.transientfor)); + setlinkedvar(nil,tmsecomponent(info.widget)); + end; + end; + end + else begin + bo1:= not showing; + updateroot; //create window + if fparentwidget <> nil then begin + if not (csdesigning in componentstate) then begin + include(fwidgetstate,ws_showproc); + try + fparentwidget.show(modallevel,transientfor^); + finally + exclude(fwidgetstate,ws_showproc); + end; + end; + end; + include(fwidgetstate,ws_visible); + if bo1 then begin + if not updateopaque(false,true) and (fparentwidget <> nil) then begin + fparentwidget.widgetregionchanged(self); + end; + end; + if ownswindow1 then begin + bo2:= transientfor^ = window; +// if transientfor = window then begin +// transientfor:= nil; +// end; + if not bo2 and (transientfor^ <> nil) and (modallevel = ml_window) then begin + include(fwindow.fstate,tws_modalfor); + end + else begin + if not nomodalforreset then begin + exclude(fwindow.fstate,tws_modalfor); + end; + end; + fwindow.show(windowevent); + if not nomodalforreset and not bo2 then begin + fwindow.settransientfor(transientfor^,windowevent); + end; + if bo1 then begin + doshow; + end; + if (modallevel = ml_window) and (fwindow.modalfor) and + fwindow.ftransientfor.active then begin + fwindow.activate; + end; + end + else begin + if bo1 then begin + doshow; + end; + end; + end; // ml_application + if fwindow <> nil then begin + result:= fwindow.fmodalresult; + end + else begin + result:= mr_none; + end; +end; + +function twidget.show(const modallevel: modallevelty; + const transientfor: twindow = nil): modalresultty; +var + event: twidgetshowevent; +begin + if (modallevel = ml_application) and not application.ismainthread then begin + event:= twidgetshowevent.create(false); + event.fwidget:= self; + event.fmodallevel:= modallevel; +// event.ftransientfor:= transientfor^; dangerouse becouse of lifetime + try + synchronizeevent(event); + result:= event.fmodalresult; + finally + event.free; + end; + end + else begin + result:= internalshow(modallevel,@transientfor,false,false); + end; +end; + +function twidget.show(const modallevel: modallevelty; + const transientfor: twidget): modalresultty; +begin + if transientfor = nil then begin + result:= show(modallevel,twindow(nil)); + end + else begin + result:= show(modallevel,transientfor.window); + end; +end; + +function twidget.show(const modal: boolean = false; + const transientfor: twindow = nil): modalresultty; +begin + if modal then begin + result:= show(ml_application,transientfor); + end + else begin + result:= show(ml_none,transientfor); + end; +end; + +procedure twidget.endmodal; +begin + if window.fmodalwidget = self then begin + fwindow.endmodal; + end; +end; + +procedure twidget.clampinview(const arect: rectty; const bottomright: boolean); +var + rect1: rectty; +begin + if fparentwidget <> nil then begin + rect1:= arect; + addpoint1(rect1.pos,subpoint(paintparentpos,fparentwidget.paintpos)); + fparentwidget.clampinview(rect1,bottomright); + end; +end; + +procedure twidget.doactivate; +var + rect1: rectty; +begin + if (fparentwidget <> nil) and + not (ow1_noclampinview in foptionswidget1) then begin + rect1:= getdisprect; + if rect1.x < 0 then begin + rect1.cx:= rect1.cx + rect1.x; + rect1.x:= 0; + end; + if rect1.x + rect1.cx > fwidgetrect.cx then begin + rect1.cx:= fwidgetrect.cx - rect1.x; + end; + if rect1.y < 0 then begin + rect1.cy:= rect1.cy + rect1.y; + rect1.y:= 0; + end; + if rect1.y + rect1.cy > fwidgetrect.cy then begin + rect1.cy:= fwidgetrect.cy - rect1.y; + end; + addpoint1(rect1.pos,fwidgetrect.pos); + subpoint1(rect1.pos,fparentwidget.paintpos); + fparentwidget.clampinview(rect1,false); + end; + activechanged; +end; + +procedure twidget.doafteractivate(); +begin + //dummy +end; + +procedure twidget.dodeactivate; +begin + activechanged; +end; + +function twidget.navigdistance(var info: naviginfoty; + const nowrap: boolean = false): integer; +const + distweighting = 10; + wrapweighting = 1; + orthoweightingwrap = 10; + orthoweighting = 300; + orthoweightingoverlap = 1; +var + dist: integer; + srect,drect: rectty; + sstart,send,dstart,dend: integer; + i1: int32; + +begin + with info do begin + drect:= navigrect; + addpoint1(drect.pos,rootpos); + srect:= startingrect; + if direction in [gd_right,gd_left] then begin + sstart:= srect.y; + dstart:= drect.y; + send:= srect.y + srect.cy; + dend:= drect.y + drect.cy; + result:= (drect.y + dend - srect.y - send) div 2; + dist:= drect.x - srect.x; + if direction = gd_right then begin + if dist > 0 then begin + i1:= dist - srect.cx; + if (i1 > 0) and (i1 < dist) then begin + dist:= i1; + end; + end; + end + else begin //gd_left + if dist < 0 then begin + i1:= dist + drect.cx; + if (i1 < 0) and (i1 > dist) then begin + dist:= i1; + end; + end; + end; + end + else begin + sstart:= srect.x; + send:= srect.x + srect.cx; + dstart:= drect.x; + dend:= drect.x + drect.cx; + result:= drect.x - srect.x; + dist:= (drect.y + drect.cy div 2) - (srect.y + srect.cy div 2); + end; + result:= abs(result); + if direction in [gd_left,gd_up] then begin + dist:= -dist; + end; + if dist <= 0 then begin + if nowrap then begin + result:= bigint; + exit; + end; + result:= result div orthoweightingwrap; + if direction in [gd_right,gd_left] then begin + dist:= dist + wraprect.cx; + if direction = gd_left then begin + dist:= dist-drect.cx + end; + end + else begin + dist:= dist + wraprect.cy; + end; + dist:= dist * wrapweighting; + result:= result*orthoweightingwrap; + end + else begin +// if (dstart >= sstart) and (dend <= send) or +// (sstart >= dstart) and (send <= dend) then begin + if (dstart >= sstart) and (dstart < send) or + (dend > sstart) and (dend <= send) or + (sstart >= dstart) and (sstart < dend) or + (send > dstart) and (send <= dend) then begin + result:= result * orthoweightingoverlap; + end + else begin + result:= result * orthoweighting; + end; + end; + dist:= dist * distweighting; + if dist < 0 then begin + dist:= bigint div 2; + end; + result:= result + dist; + end; +end; + +function twidget.navigrect: rectty; +begin + result:= paintrect; + if fframe <> nil then begin + inflaterect1(result,fframe.paintframedelta); + end; +end; + +function twidget.navigstartrect: rectty; +begin + result:= navigrect; +end; + +{$ifdef mse_debugnavigdistance} +var + navigrequestlevel: int32; +{$endif} + +procedure twidget.navigrequest(var info: naviginfoty; + const nowrap: boolean = false); +var + int1,int2: integer; + widget1,widget2,wi3: twidget; + bo1: boolean; + rect1,rect2: rectty; +{$ifdef mse_debugnavigdistance} + wi1: twidget; +{$endif} +begin +{$ifdef mse_debugnavigdistance} + inc(navigrequestlevel); + debugwriteln( + debugwidgetname(self,charstring(' ',navigrequestlevel-1)+ + inttostr(navigrequestlevel)+ + '**navigrequest:')+ debugwidgetname(info.sender,' sender ')); +{$endif} + with info do begin + if not down and (ow_arrowfocusout in foptionswidget) and + (fparentwidget <> nil) then begin + widget1:= sender; + sender:= self; + fparentwidget.navigrequest(info); + sender:= widget1; + end; + down:= true; + wi3:= nearest; + {$ifdef mse_debugnavigdistance} + wi1:= nearest; + {$endif} + for int1:= 0 to widgetcount - 1 do begin + widget1:= twidget(fwidgets[int1]); + if (widget1 <> info.sender) and (ow_arrowfocus in widget1.foptionswidget) + and widget1.canfocus then begin + widget2:= nearest; + bo1:= hastarget; + hastarget:= false; + if ow_arrowfocusin in widget1.foptionswidget then begin + widget1.navigrequest(info); + end; + if (nearest = widget2) and not hastarget then begin + hastarget:= true; + int2:= widget1.navigdistance(info,nowrap); + if int2 < distance then begin + nearest:= widget1; + distance:= int2; + end; + {$ifdef mse_debugnavigdistance} + if nearest <> wi1 then begin + debugwrite(' *'); + wi1:= nearest; + end + else begin + debugwrite(' '); + end; + debugwriteln(inttostr(int1)+charstring(' ',navigrequestlevel-1)+ + 'navigdistance '+ + inttostr(int2)+' '+inttostr(distance)+' '+ + debugwidgetname(widget1,' ')+' '+ + debugwidgetname(nearest,'nearest')); + {$endif} + end; + hastarget:= hastarget or bo1; + end; + end; + if (nearest <> wi3) and (nearest <> nil) then begin + rect1:= nearest.navigrect(); + translatewidgetpoint1(rect1.pos,nearest,nil); + rect2:= sender.navigrect(); + translatewidgetpoint1(rect2.pos,sender,nil); + case direction of + gd_up: begin + if rect1.y = rect2.y then begin + nearest:= wi3; //restore + end; + end; + gd_down: begin + if rect1.y + rect1.cy = rect2.y + rect2.cy then begin + nearest:= wi3; //restore + end; + end; + gd_right: begin + if rect1.x = rect2.x then begin + nearest:= wi3; //restore + end; + end; + gd_left: begin + if rect1.x + rect1.cx = rect2.x + rect2.cx then begin + nearest:= wi3; //restore + end; + end; + end; + end; + end; + if canevent(tmethod(fonnavigrequest)) then begin + fonnavigrequest(self,info); + end; +{$ifdef mse_debugnavigdistance} + dec(navigrequestlevel); +{$endif} +end; + +procedure twidget.dokeydown(var info: keyeventinfoty); +var + bo1: boolean; +begin + if fframe <> nil then begin + fframe.dokeydown(info); + end; + with info do begin + if not (es_processed in eventstate) then begin + if (key = key_escape) and (shiftstate = []) and + (ow_focusbackonesc in foptionswidget) then begin + if focusback then begin + include(eventstate,es_processed); + end; + end; + if not (es_processed in eventstate) then begin + if (fparentwidget <> nil) and + (self <> window.fmodalwidget) then begin + bo1:= es_child in eventstate; + include(eventstate,es_child); + fparentwidget.dokeydown1(info); + if not bo1 then begin + exclude(eventstate,es_child); + end; + end; + end; + end; + end; +end; + +procedure twidget.handlenavigkeys(var info: keyeventinfoty; + const nowrap: boolean = false); + + procedure expandwraprect(var wraprect: rectty; const awidget: twidget); + var + i1: int32; + widget1: twidget; + begin + for i1:= 0 to high(awidget.fwidgets) do begin + widget1:= awidget.fwidgets[i1]; + with widget1 do begin + if (ow_arrowfocus in widget1.foptionswidget) and visible then begin + combinerect1(wraprect,rootwidgetrect); + if ow_arrowfocusin in widget1.foptionswidget then begin + expandwraprect(wraprect,widget1); + end; + end; + end; + end; + end; + +var + naviginfo: naviginfoty; + widget1: twidget; + shiftstate1: shiftstatesty; + b1: boolean; + pt1,pt2: pointty; +begin + with info do begin + shiftstate1:= shiftstate * shiftstatesmask; + if not (es_processed in eventstate) then begin + if (ow_keyreturntaborder in foptionswidget) and + ({(key = key_enter) or} (key = key_return)) and + (shiftstate1 - [ss_shift] = []) then begin + include(eventstate,es_processed); + widget1:= nexttaborder(ss_shift in shiftstate1,nowrap); + if widget1 <> nil then begin + widget1.setfocus; + end; + end + else begin + if (shiftstate1 = []) or + (shiftstate1 = [ss_shift]) and (key = key_backtab) then begin + include(eventstate,es_processed); + with naviginfo do begin + direction:= gd_none; + case key of + key_tab,key_backtab: begin + widget1:= nexttaborder(key = key_backtab,nowrap or + (aso_tabnavig in assistiveoptions)); + if widget1 <> nil then begin + widget1.setfocus; + end + else begin + if canassistive() then begin + assistiveserver.dotabordertouched(getiassistiveclient(), + key = key_backtab); + end; + end; + end; + key_right: direction:= gd_right; + key_up: direction:= gd_up; + key_left: direction:= gd_left; + key_down: direction:= gd_down; + else begin + exclude(eventstate,es_processed); + end; + end; + if direction <> gd_none then begin + if fparentwidget <> nil then begin + distance:= bigint; + nearest:= nil; + sender:= self; + down:= false; + startingrect:= navigstartrect; + addpoint1(startingrect.pos,rootpos); + widget1:= fparentwidget; + wraprect:= widget1.rootwidgetrect; + while (ow_arrowfocusout in widget1.foptionswidget) and + (widget1.fparentwidget <> nil) do begin + widget1:= widget1.fparentwidget; //todo: position shift + combinerect1(wraprect,widget1.rootwidgetrect); + end; + expandwraprect(wraprect,widget1); + fparentwidget.navigrequest(naviginfo, + nowrap or + (assistiveoptions*[aso_widgetnavig,aso_nearestortho] = + [aso_widgetnavig,aso_nearestortho])); + if nearest <> nil then begin + b1:= false; + if assistiveoptions*[aso_widgetnavig,aso_nearestortho] = + [aso_widgetnavig] then begin + pt1:= rootpos; + pt2:= nearest.rootpos; + case direction of + gd_left: begin + b1:= pt1.x <= pt2.x; + end; + gd_up: begin + b1:= pt1.y <= pt2.y; + end; + gd_right: begin + b1:= pt1.x >= pt2.x; + end; + gd_down: begin + b1:= pt1.y >= pt2.y; + end; + end; + if b1 and (canassistive()) then begin + assistiveserver.donavigbordertouched(getiassistiveclient(), + direction); + end; + end; + if not b1 then begin + nearest.setfocus(); + end; + end + else begin + if canassistive() then begin + assistiveserver.donavigbordertouched(getiassistiveclient(),direction); + end; + end; + end; + end; + end; + end; + end; + end; + end; +end; + +procedure twidget.dokeydownaftershortcut(var info: keyeventinfoty); +var + bo1: boolean; +begin + with info do begin + handlenavigkeys(info); + if not (es_processed in info.eventstate) and (fparentwidget <> nil) and + (self <> window.fmodalwidget) then begin + bo1:= es_child in eventstate; + include(eventstate,es_child); + fparentwidget.dokeydownaftershortcut(info); + if not bo1 then begin + exclude(eventstate,es_child); + end; + end; + end; +end; + +procedure twidget.dokeydown1(var info: keyeventinfoty); +var + b1: boolean; + w1: twidget; +begin + b1:= canassistive() {and (ws_iswidget in widgetstate)}; + if b1 then begin + w1:= nil; + setlinkedvar(self,tmsecomponent(w1)); //destroy check + end; + try + exclude(fwidgetstate1,ws1_onkeydowncalled); + dokeydown(info); + if b1 and (w1 <> nil) then begin + assistiveserver.dokeydown(getiassistiveclient(),info); + end; + finally + if b1 and (w1 <> nil) then begin //destroy check + setlinkedvar(nil,tmsecomponent(w1)); + end; + end; +end; + +procedure twidget.internalkeydown(var info: keyeventinfoty); +begin + if not (es_processed in info.eventstate) then begin + include(info.eventstate,es_preview); + include(appinst.fstate,aps_shortcutting); + window.fcaller:= nil; + try + doshortcut(info,self); + finally + exclude(info.eventstate,es_preview); + exclude(appinst.fstate,aps_shortcutting); + end; + end; + if not (es_processed in info.eventstate) then begin + dokeydown1(info); + end; + if not (es_processed in info.eventstate) then begin + include(appinst.fstate,aps_shortcutting); + try + doshortcut(info,self); + finally + exclude(appinst.fstate,aps_shortcutting); + end; + end; + if not (es_processed in info.eventstate) then begin + dokeydownaftershortcut(info); + end; +end; + +procedure twidget.dokeyup(var info: keyeventinfoty); +begin + if not (es_processed in info.eventstate) and (fparentwidget <> nil) and + (self <> window.fmodalwidget) then begin + fparentwidget.dokeyup(info); + end; +end; + +procedure twidget.dolayout(const sender: twidget); +begin + if fparentwidget <> nil then begin + fparentwidget.dolayout(sender); + end; +end; + +procedure twidget.updatecursorshape(apos: pointty); +var + widget: twidget; + cursor1: cursorshapety; +begin + widget:= self; + repeat + cursor1:= widget.fcursor; + if cursor1 = cr_default then begin + cursor1:= widget.actualcursor(apos); + end; + addpoint1(apos,widget.fwidgetrect.pos); + widget:= widget.fparentwidget; + until not (cursor1 in [cr_default,cr_parent]) or (widget = nil); + if (widget = nil) and (cursor1 in [cr_default,cr_parent]) then begin + cursor1:= cr_arrow; + end; + appinst.fwidgetcursorshape:= cursor1; +end; + +procedure twidget.cursorchanged; +begin + if not (csloading in componentstate) and (appinst <> nil) and + checkdescendent(appinst.fclientmousewidget) then begin + appinst.fclientmousewidget.updatecursorshape(appinst.fmousewidgetpos); + end; +end; + +procedure twidget.setcursor(const avalue: cursorshapety); +begin + if fcursor <> avalue then begin + fcursor:= avalue; + cursorchanged; + end; +end; + +function twidget.actualcursor(const apos: pointty): cursorshapety; +begin + result:= fcursor; +end; + +function twidget.containswidget(awidget: twidget): boolean; +var + int1: integer; +begin + result:= false; + if awidget <> nil then begin + for int1:= 0 to widgetcount-1 do begin + if twidget(fwidgets[int1]) = awidget then begin + result:= true; + break; + end; + end; + end; +end; + +function twidget.iswidgetclick(const info: mouseeventinfoty; + const caption: boolean = false): boolean; + //true if eventtype = et_butonrelease, button is mb_left, + // clicked and pos in clientrect or in frame.caption if caption = true, + // origin = pos +begin + with info do begin + result:= (button = mb_left) and (ws_lclicked in fwidgetstate) and + (eventkind = ek_buttonrelease) and + (pointinrect(pos,paintrect) or + caption and (fframe <> nil) and fframe.pointincaption(info.pos)); + end; +end; + +function twidget.iswidgetdblclick(const info: mouseeventinfoty; + const caption: boolean = false): boolean; + //true if eventtype = et_butonrelease, button is mb_left, + // clicked and pos in clientrect or in frame.caption if caption = true, + // and timedlay to last buttonpress is short + // origin = pos +begin + with info do begin + result:= (button = mb_left) and + (eventkind = ek_buttonpress) and (ss_double in shiftstate) and + (appinst.fbuttonpresswidgetbefore = self) and + (pointinrect(pos,paintrect) or + caption and (fframe <> nil) and fframe.pointincaption(info.pos)) + end; +end; + +function twidget.iswidgetdblclicked(const info: mouseeventinfoty; + const caption: boolean = false): boolean; + //true if eventkind = ek_buttonrelease, button is mb_left, + // and pos in clientrect or in frame.caption if caption = true + // and timedelay to last buttonrelease is short + // origin = pos +begin + with info do begin + result:= (button = mb_left) and (ss_double in shiftstate) and + ({(eventkind = ek_buttonpress) and (appinst.fbuttonpresswidgetbefore = self) or} + (eventkind = ek_buttonrelease) and + (appinst.fbuttonreleasewidgetbefore = self)) and + (pointinrect(pos,paintrect) or + caption and (fframe <> nil) and fframe.pointincaption(info.pos)); + end; +end; + +function twidget.isclick(const info: mouseeventinfoty): boolean; + //true if eventkind = ek_buttonrelease, button is mb_left, + // clicked and pos in clientrect +begin + with info do begin + result:= (ws_lclicked in fwidgetstate) and (eventkind = ek_buttonrelease) and + (button = mb_left) and pointinrect(pos,clientrect); + end; +end; + +function twidget.isdblclick(const info: mouseeventinfoty): boolean; + //true if eventtype = ek_buttonpress, button is mb_left, pos in clientrect + // and timedelay to last buttonpress is short + // origin = paintrect.pos +begin + with info do begin + result:= (button = mb_left) and pointinrect(pos,clientrect) and + (eventkind = ek_buttonpress) and (ss_double in shiftstate) and + (appinst.fbuttonpresswidgetbefore = self); + end; +end; + +function twidget.isdblclicked(const info: mouseeventinfoty): boolean; + //true if eventkind in [ek_buttonpress,ek_buttonrelease], button is mb_left, + // and timedelay to last same buttonevent is short +begin + with info do begin + result:= (button = mb_left) and (ss_double in shiftstate) and + ((eventkind = ek_buttonpress) and (appinst.fbuttonpresswidgetbefore = self) or + (eventkind = ek_buttonrelease) and (appinst.fbuttonreleasewidgetbefore = self)); + end; +end; + +function twidget.isleftbuttondown(const info: mouseeventinfoty): boolean; +begin + with info do begin + result:= (eventkind = ek_buttonpress) and + (button = mb_left) and pointinrect(pos,clientrect); + end; +end; + +function twidget.isleftbuttondown(const info: mouseeventinfoty; + const akeyshiftstate: shiftstatesty): boolean; +begin + with info do begin + result:= (eventkind = ek_buttonpress) and + (button = mb_left) and pointinrect(pos,clientrect) and ( + shiftstate*keyshiftstatesmask = akeyshiftstate); + end; +end; +{ +function twidget.eatwidgetclick(var info: mouseeventinfoty; + const caption: boolean = false): boolean; +begin + result:= iswidgetclick(info,caption); + if result then begin + include(info.eventstate,es_processed); + end; +end; + +function twidget.eatclick(var info: mouseeventinfoty): boolean; +begin + result:= isclick(info); + if result then begin + include(info.eventstate,es_processed); + end; +end; + +function twidget.eatdblclick(var info: mouseeventinfoty): boolean; +begin + result:= isdblclick(info); + if result then begin + include(info.eventstate,es_processed); + end; +end; + +function twidget.eatdblclicked(var info: mouseeventinfoty): boolean; +begin + result:= isdblclicked(info); + if result then begin + include(info.eventstate,es_processed); + end; +end; + +function twidget.eatleftbuttondown(var info: mouseeventinfoty): boolean; +begin + result:= isleftbuttondown(info); + if result then begin + include(info.eventstate,es_processed); + end; +end; + +function twidget.eatleftbuttondown(var info: mouseeventinfoty; + const akeyshiftstate: shiftstatesty): boolean; +begin + result:= isleftbuttondown(info,akeyshiftstate); + if result then begin + include(info.eventstate,es_processed); + end; +end; +} +function twidget.widgetmousepos(const ainfo: mouseeventinfoty): pointty; + //transaltes to widgetpos if necessary +begin + result:= ainfo.pos; + if es_client in ainfo.eventstate then begin + addpoint1(result,clientwidgetpos); + end; +end; + +function twidget.getrootwidgetpath: widgetarty; +var + count: integer; + widget: twidget; +begin + result:= nil; + count:= 0; + widget:= self; + while widget <> nil do begin + if length(result) <= count then begin + setlength(result,length(result)+32); + end; + result[count]:= widget; + inc(count); + widget:= widget.fparentwidget; + end; + setlength(result,count); +end; + +function twidget.checkfocusshortcut(var info: keyeventinfoty): boolean; +begin + if (fframe <> nil) then begin + result:= fframe.checkfocusshortcut(info) and canfocus; + end + else begin + result:= false; + end; +end; + +procedure twidget.doshortcut(var info: keyeventinfoty; const sender: twidget); + //sender = nil -> broadcast top down +var + int1,int2: integer; + caller1: twidget; +begin + if not (es_processed in info.eventstate) and + (fwidgetstate * [ws_visible, ws_enabled] = + [ws_visible,ws_enabled]) then begin + if (sender <> nil) and (sender.fparentwidget = self) then begin + //neighbors first + int2:= indexofwidget(sender); + for int1:= int2 + 1 to widgetcount - 1 do begin + with widgets[int1] do begin + if not (ow_nosiblingshortcut in foptionswidget) then begin + doshortcut(info,nil); + if es_processed in info.eventstate then begin + break; + end; + end; + end; + end; + if not (es_processed in info.eventstate) then begin + for int1:= 0 to int2 - 1 do begin + with widgets[int1] do begin + if not (ow_nosiblingshortcut in foptionswidget) then begin + doshortcut(info,nil); + if es_processed in info.eventstate then begin + break; + end; + end; + end; + end; + end; + end + else begin + //children + caller1:= window.fcaller; + for int1:= 0 to widgetcount - 1 do begin + if widgets[int1] <> caller1 then begin + with widgets[int1] do begin + if not (ow_noparentshortcut in foptionswidget) then begin + doshortcut(info,nil); + end; + end; + if (es_processed in info.eventstate) then begin + break; + end; + end; + end; + end; + if not (es_processed in info.eventstate) and (sender <> nil) then begin + //parent + if (fparentwidget <> nil) and not (ow_nochildshortcut in foptionswidget) and + (self <> fwindow.fmodalwidget) then begin + fwindow.fcaller:= self; + fparentwidget.doshortcut(info,sender); + end + else begin + window.doshortcut(info,sender) + end; + end; + if not (es_processed in info.eventstate) and canfocus and + checkfocusshortcut(info)then begin + setfocus; + include(info.eventstate,es_processed); + end; + end; +end; + +function twidget.showing: boolean; +begin + result:= isvisible and + ( + (fparentwidget = nil) and ((fwindow <> nil) and + (tws_windowvisible in fwindow.fstate)) or + (fparentwidget <> nil) and fparentwidget.showing + ); +end; + +function twidget.isenabled: boolean; +var + wi1: twidget; +begin + wi1:= self; + repeat + result:= ws_enabled in wi1.fwidgetstate; + wi1:= wi1.fparentwidget; + until not result or (wi1 = nil); +end; + +function twidget.active: boolean; +begin + result:= ws_active in fwidgetstate; +end; + +function twidget.entered: boolean; +begin + result:= ws_entered in fwidgetstate; +end; + +function twidget.activeentered: boolean; +begin + result:= entered and ((appinst.regularactivewindow = window) or + (appinst.finactivewindow = window)); +end; + +function twidget.activefocused: boolean; +begin + result:= (ws_active in fwidgetstate) and (window.focusedwidget = self); +end; + +function twidget.focused: boolean; +begin + result:= ws_focused in fwidgetstate; +end; + +function twidget.clicked: boolean; +begin + result:= ws_lclicked in fwidgetstate; +end; + +function twidget.isvisible: boolean; +begin + result:= ((ws_visible in fwidgetstate) or + ((csdesigning in componentstate) and + not (ws1_nodesignvisible in fwidgetstate1))) and + not (csdestroying in componentstate); +end; + +function twidget.parentisvisible: boolean; //checks visible flags of ancestors +var + widget1: twidget; +begin + result:= true; + widget1:= fparentwidget; + while widget1 <> nil do begin + if not widget1.isvisible then begin + result:= false; + break; + end; + widget1:= widget1.fparentwidget; + end; +end; + +function twidget.parentvisible: boolean; //checks visible flags of ancestors +var + widget1: twidget; +begin + result:= true; + widget1:= fparentwidget; + while widget1 <> nil do begin + if not (ws_visible in widget1.fwidgetstate) then begin + result:= false; + break; + end; + widget1:= widget1.fparentwidget; + end; +end; + +function twidget.getvisible: boolean; +begin + result:= ws_visible in fwidgetstate; +end; + +procedure twidget.setvisible(const avalue: boolean); +begin + if (not (csloading in componentstate) or not avalue) and + (avalue <> getvisible) then begin + if avalue then begin + if parentisvisible then begin + if window.modalfor then begin + show(ml_window,fwindow.ftransientfor); + end + else begin + show(ml_none,fwindow.ftransientfor); + end; + end + else begin + include(fwidgetstate,ws_visible); + end; + end + else begin + hide; + end; + if (ws1_fakevisible in fwidgetstate1) then begin + if not updateopaque(false,true) and (fparentwidget <> nil) then begin + fparentwidget.widgetregionchanged(self); + end; + end; + if not (csdestroying in componentstate) then begin + visiblepropchanged; + end; + end + else begin + if avalue then begin + include(fwidgetstate,ws_visible); + end + else begin + exclude(fwidgetstate,ws_visible); + if not (csloading in componentstate) and ownswindow and + (tws_windowvisible in fwindow.fstate) then begin + gui_hidewindow(fwindow.fwindow.id); + end; + end; + end; +end; + +function twidget.getenabled: boolean; +begin + result:= ws_enabled in fwidgetstate; +end; + +procedure twidget.setenabled(const Value: boolean); +begin + if value <> getenabled then begin + if value then begin + include(fwidgetstate,ws_enabled); + end + else begin + exclude(fwidgetstate,ws_enabled); +// if window.focusedwidget = self then begin + if checkdescendent(window.focusedwidget) then begin + nextfocus; + end; + end; + if not (csloading in componentstate) then begin + enabledchanged; + end; + end; +end; + +function twidget.actualcolor: colorty; +begin + if (fcolor <> cl_parent) and (fcolor <> cl_default) then begin + result:= fcolor; + end + else begin + if fparentwidget <> nil then begin + result:= fparentwidget.actualcolor; + end + else begin + result:= cl_background; + end; + end; +end; + +function twidget.actualopaquecolor: colorty; +begin + if (fcolor <> cl_parent) and (fcolor <> cl_default) and + (fcolor <> cl_transparent)then begin + result:= fcolor; + end + else begin + if fparentwidget <> nil then begin + result:= fparentwidget.actualopaquecolor; + end + else begin + result:= cl_background; + end; + end; +end; + +function twidget.parentcolor: colorty; +begin + if (fcolor <> cl_parent) and (fcolor <> cl_default) then begin + result:= fcolor; + end + else begin + if fparentwidget <> nil then begin + result:= fparentwidget.parentcolor; + end + else begin + result:= cl_background; + end; + end; +end; + +function twidget.backgroundcolor: colorty; +begin + if (fframe = nil) or (fframe.actualcolorclient = cl_transparent) then begin + if fparentwidget = nil then begin + result:= actualopaquecolor; + end + else begin + if (fcolor <> cl_parent) and (fcolor <> cl_default) and + (fcolor <> cl_transparent) then begin + result:= fcolor; + end + else begin + result:= fparentwidget.backgroundcolor; + end; + end; + end + else begin + result:= fframe.actualcolorclient(); + end; +end; + +function twidget.translatecolor(const acolor: colorty): colorty; +begin + if acolor = cl_default then begin + result:= actualcolor; + end + else begin + if acolor = cl_parent then begin + result:= parentcolor; + end + else begin + result:= acolor; + end; + end; +end; + +function twidget.getsize: sizety; +begin + result:= fwidgetrect.size; +end; + +function twidget.clipcaret: rectty; + //origin = pos +var + widget1: twidget; + po1: pointty; +begin + result:= moverect(getcaretcliprect,clientwidgetpos); + widget1:= self; + po1:= nullpoint; + while widget1 <> nil do begin + msegraphutils.intersectrect(result,removerect(widget1.paintrect,po1),result); + addpoint1(po1,widget1.fwidgetrect.pos); + widget1:= widget1.fparentwidget; + end; +end; + +procedure twidget.reclipcaret; +begin + if hascaret then begin + with appinst,fcaret,fcaretwidget do begin + cliprect:= moverect(clipcaret,subpoint(fcaretwidget.frootpos,origin)); + end; + end; +end; + +function twidget.hascaret: boolean; +begin + result:= (appinst <> nil) and checkdescendent(appinst.fcaretwidget) +end; + +function twidget.canwindow: boolean; +begin + result:= (fwindow <> nil) and + not (csdestroying in fwindow.fownerwidget.componentstate) or + (fwindow = nil) and not (csdestroying in rootwidget.componentstate); +end; + +procedure twidget.getcaret; +begin + if (appinst <> nil) then begin + appinst.caret.link(window.fcanvas,addpoint(frootpos,clientwidgetpos), + removerect(clipcaret,clientwidgetpos)); + appinst.fcaretwidget:= self; + end; +end; + +function twidget.mousecaptured: boolean; +begin + result:= application.mousecapturewidget = self; +end; + +function twidget.capturemouse(grab: boolean = true): boolean; +begin + result:= false; + if appinst <> nil then begin + result:= appinst.fmousecapturewidget <> self; + appinst.capturemouse(self,grab); + include(fwidgetstate,ws_mousecaptured); + end; +end; + +procedure twidget.releasemouse(const grab: boolean = false); +begin + if (appinst <> nil) and (appinst.fmousecapturewidget = self) then begin + exclude(fwidgetstate,ws_mousecaptured); + appinst.capturemouse(nil,grab); + end; +end; + +function twidget.capturekeyboard: boolean; +begin + result:= false; + if appinst <> nil then begin + result:= appinst.fkeyboardcapturewidget <> self; + appinst.fkeyboardcapturewidget:= self; + end; +end; + +procedure twidget.releasekeyboard; +begin + if (appinst <> nil) and (appinst.fkeyboardcapturewidget = self) then begin + appinst.fkeyboardcapturewidget:= nil; + end; +end; + +procedure twidget.dragevent(var info: draginfoty); +var + po1: pointty; +begin + if fparentwidget <> nil then begin + po1:= subpoint(clientparentpos,fparentwidget.clientwidgetpos); + addpoint1(info.pos,po1); + fparentwidget.dragevent(info); + subpoint1(info.pos,po1); + end; +end; + +procedure twidget.doscroll(const dist: pointty); +begin + //dummy +end; + +procedure twidget.doscrolled(const dist: pointty); +begin + //dummy +end; + +procedure twidget.scrollwidgets(const dist: pointty); + procedure movereg(const awidget: twidget); + var + int1: integer; + begin + with awidget do begin + if ws1_widgetregionvalid in fwidgetstate1 then begin + regmove(fwidgetregion,dist); + end; + for int1:= 0 to high(fwidgets) do begin + movereg(fwidgets[int1]); + end; + end; + end; +var + int1: integer; + widget1: twidget; +begin + if (dist.x <> 0) or (dist.y <> 0) then begin + if ws1_widgetregionvalid in fwidgetstate1 then begin + regmove(fwidgetregion,dist); + end; + widget1:= self; + while not (ws_opaque in widget1.fwidgetstate) and + (widget1.parentwidget <> nil) do begin + widget1:= widget1.parentwidget; + exclude(widget1.fwidgetstate1,ws1_widgetregionvalid); + end; + for int1:= 0 to widgetcount - 1 do begin + widget1:= fwidgets[int1]; + movereg(widget1); + with widget1 do begin + addpoint1(fwidgetrect.pos,dist); + addpoint1(frootpos,dist); + rootchanged([]); + end; + if appinst.fcaretwidget = widget1 then begin + widget1.reclipcaret; + end; + end; +// widgetregioninvalid; + if fwindow <> nil then begin + fwindow.fscrollnotifylist.notify(self); + end; + end; +end; + +procedure twidget.scrollcaret(const dist: pointty); +begin + if hascaret then begin + tcaret1(appinst.fcaret).scroll(dist,appinst.fcaretwidget <> self); + reclipcaret; + end; +end; + +function twidget.getnoscroll(): boolean; +begin + result:= ow_noscroll in foptionswidget; +end; + +procedure twidget.scrollrect(const dist: pointty; const rect: rectty; + scrollcaret: boolean); + //origin = paintrect.pos +var + rect1,rect2: rectty; + ahascaret: boolean; + + procedure doinvalidate; + begin + fwindow.invalidaterect(intersectrect(rect1,rect2)); + end; + +begin + if (dist.x = 0) and (dist.y = 0) or not showing then begin + exit; + end; + if (fwindow <> nil) {and canpaint} then begin + ahascaret:= hascaret; + if ahascaret then begin + tcaret1(appinst.fcaret).remove; + end; + rect1:= rect; + if fframe <> nil then begin + inc(rect1.x,fframe.fpaintrect.x); + inc(rect1.y,fframe.fpaintrect.y); //widget origin + end; + if getnoscroll() or{and not} + (csdesigning in componentstate) or //restore grid + (tws_painting in fwindow.fstate) or + (abs(dist.x) >= rect.cx) or (abs(dist.y) > rect1.cy) then begin + invalidaterect(rect1,org_widget); + end + else begin + update; + msegraphutils.intersectrect(rect1,clippedpaintrect,rect1); + if hasoverlappingsiblings(rect1) then begin + invalidaterect(rect1,org_widget); + end + else begin + rect2:= rect1; //backup for invalidate + addpoint1(rect2.pos,frootpos); + msegraphutils.intersectrect(rect1,removerect(rect1,dist),rect1); + addpoint1(rect1.pos,frootpos); + fwindow.movewindowrect(dist,rect1); + rect1.y:= rect2.y; + rect1.cy:= rect2.cy; + if dist.x < 0 then begin + rect1.cx:= -dist.x; + rect1.x:= rect2.x + rect2.cx - rect1.cx; + doinvalidate; + end + else begin + if dist.x > 0 then begin + rect1.x:= rect2.x; + rect1.cx:= dist.x; + doinvalidate; + end; + end; + rect1.x:= rect2.x; + rect1.cx:= rect2.cx; + if dist.y < 0 then begin + rect1.cy:= -dist.y; + rect1.y:= rect2.y + rect2.cy - rect1.cy; + doinvalidate; + end + else begin + if dist.y > 0 then begin + rect1.y:= rect2.y; + rect1.cy:= dist.y; + doinvalidate; + end; + end; + end; + end; + if ahascaret then begin + if scrollcaret then begin + tcaret1(appinst.fcaret).scroll(dist,appinst.fcaretwidget <> self); + reclipcaret; + end; + tcaret1(appinst.fcaret).restore; + end; + if (appinst.factmousewindow = fwindow) then begin + with appinst.fmouseparkeventinfo do begin + if pointinrect(pos, + makerect(addpoint(addpoint(rootpos,paintpos),rect.pos),rect.size)) then begin + //replay last mousepos + appinst.eventlist.insert(0,tmouseevent.create(fwindow.winid,false, + mb_none,mw_none,pos,shiftstate,0)); + end; + end; + end; + end; +end; + +procedure twidget.scroll(const dist: pointty); +var + rect1: rectty; +begin + if (dist.x = 0) and (dist.y = 0) then begin + exit; + end; + doscroll(dist); + rect1.pos:= nullpoint; + if fframe <> nil then begin + rect1.size:= fframe.fpaintrect.size; + end + else begin + rect1.size:= fwidgetrect.size; + end; + scrollrect(dist,rect1,true); + scrollwidgets(dist); + doscrolled(dist); +end; + +procedure twidget.update; +begin + if showing then begin + window.update; + end; +end; + +procedure twidget.settaborder(const Value: integer); +begin + if ftaborder <> value then begin + ftaborder := Value; + if (fparentwidget <> nil) then begin + fparentwidget.updatetaborder(self); + end; + end; +end; + +function comparetaborder(const l,r): Integer; +begin + result:= twidget(l).ftaborder - twidget(r).ftaborder; +end; + +function twidget.gettaborderedwidgets: widgetarty; +begin + result:= copy(fwidgets); + sortarray(pointerarty(result),{$ifdef FPC}@{$endif}comparetaborder); +end; + +function twidget.getvisiblewidgets: widgetarty; +var + int1,int2: integer; +begin + setlength(result,length(fwidgets)); + int2:= 0; + for int1:= 0 to high(fwidgets) do begin + if fwidgets[int1].isvisible then begin + result[int2]:= fwidgets[int1]; + inc(int2); + end; + end; + setlength(result,int2); +end; + +function twidget.getcornerwidget(const side: graphicdirectionty; + const visibleonly: boolean): twidget; +var + i1,i2: int32; + po1,pe: pwidget; +begin + result:= nil; + case side of + gd_left: begin + i1:= maxint; + po1:= pointer(fwidgets); + pe:= po1 + length(fwidgets); + while po1 < pe do begin + with po1^ do begin + if not visibleonly or visible then begin + if fwidgetrect.x < i1 then begin + result:= po1^; + i1:= fwidgetrect.x; + end; + end; + end; + inc(po1); + end; + end; + gd_up: begin + i1:= maxint; + po1:= pointer(fwidgets); + pe:= po1 + length(fwidgets); + while po1 < pe do begin + with po1^ do begin + if not visibleonly or visible then begin + if fwidgetrect.y < i1 then begin + result:= po1^; + i1:= fwidgetrect.y; + end; + end; + end; + inc(po1); + end; + end; + gd_right: begin + i1:= minint; + po1:= pointer(fwidgets); + pe:= po1 + length(fwidgets); + while po1 < pe do begin + with po1^ do begin + if not visibleonly or visible then begin + i2:= fwidgetrect.x + fwidgetrect.cx; + if i2 > i1 then begin + result:= po1^; + i1:= i2; + end; + end; + end; + inc(po1); + end; + end; + gd_down: begin + i1:= minint; + po1:= pointer(fwidgets); + pe:= po1 + length(fwidgets); + while po1 < pe do begin + with po1^ do begin + if not visibleonly or visible then begin + i2:= fwidgetrect.y + fwidgetrect.cy; + if i2 > i1 then begin + result:= po1^; + i1:= i2; + end; + end; + end; + inc(po1); + end; + end; + end; +end; + +procedure twidget.updatetaborder(awidget: twidget); +var + int1: integer; + sortlist: widgetarty; + +begin + sortlist:= nil; //compiler warning + if not isloading then begin + if awidget <> nil then begin + for int1:= 0 to widgetcount - 1 do begin + if twidget(fwidgets[int1]) <> awidget then begin + with twidget(fwidgets[int1]) do begin + if ftaborder >= awidget.ftaborder then begin + inc(ftaborder); + end; + end; + end; + end; + end; + sortlist:= gettaborderedwidgets; + + for int1:= 0 to high(sortlist) do begin + twidget(sortlist[int1]).ftaborder:= int1; + end; + end; +end; + +function twidget.getparentcomponent: tcomponent; +begin + result:= parentofcontainer; + if result = nil then begin +// result:= owner; + end + else begin + if (csdesigning in componentstate) and + not(csdesigning in result.componentstate) then begin + result:= nil; //parentwidget is designer + end; + end +end; + +function twidget.hasparent: boolean; +begin + result:= getparentcomponent <> nil; +end; + +procedure twidget.setparentcomponent(value: tcomponent); +begin + if value is twidget then begin + twidget(value).insertwidget(self,fwidgetrect.pos); + end + else begin +// value.insertcomponent(self); + end; +end; + +procedure twidget.setchildorder(child: tcomponent; order: integer); +//var +// comp1: tcomponent; +begin + if not fixupsetchildorder(self,child,order) then begin + with container do begin + if order > high(fwidgets) then begin + inherited setchildorder(child,order-length(fwidgets)); + end; + if removeitem(pointerarty(fwidgets),child) >= 0 then begin + if order < 0 then begin + order:= 0; + end; + if order > length(fwidgets) then begin + order:= length(fwidgets); + end; + insertitem(pointerarty(fwidgets),order,child); + end; + end; + end; +end; + +procedure twidget.getchildren(proc: tgetchildproc; root: tcomponent); +var + int1: integer; + widget: twidget; +begin + for int1:= 0 to high(fwidgets) do begin + widget:= fwidgets[int1]; + if (ws_iswidget in widget.fwidgetstate) and + (widget.owner = root) then begin + proc(widget); + end; + end; +end; + +function twidget.getcanvas(aorigin: originty = org_client): tcanvas; +begin + with tcanvas1(window.fcanvas) do begin + fstate:= fstate - changedmask; //state invalid + end; + result:= fwindow.fasynccanvas; + with result do begin + if active then begin + reset; + save; + end; + font:= getfont; + origin:= rootpos; + case aorigin of + org_widget,org_screen: begin + clipregion:= createregion(makerect(nullpoint,fwidgetrect.size)); + if aorigin = org_screen then begin + remove(screenpos); + end; + end + else begin //org_client,org_inner + clipregion:= createregion(paintrect); + if aorigin = org_client then begin + move(clientwidgetpos); + end + else begin + move(innerclientwidgetpos); + end; + end; + end; + end; +end; + +procedure twidget.updatewindowinfo(var info: windowinfoty); +begin + //dummy +end; + +procedure twidget.windowcreated; +begin + //dummy +end; + +procedure twidget.setfontheight; +begin + if not (csloading in componentstate) then begin + if ow1_fontglyphheight in foptionswidget1 then begin + ffontheight:= getfont.glyphheight; + end; + if ow1_fontlineheight in foptionswidget1 then begin + ffontheight:= getfont.lineheight; + end; + end; +end; + +procedure twidget.setoptionswidget(const avalue: optionswidgetty); +{$ifndef FPC} +const + mask: optionswidgetty = [ow_hinton,ow_hintoff]; +{$endif} +var + value,delta: optionswidgetty; + opt1: optionswidget1ty; +begin + if avalue <> foptionswidget then begin + if csreading in componentstate then begin + opt1:= optionswidget1; + if ow_noautosizing in avalue then begin //don't use deprecated flags + opt1:= opt1 + [ow1_noautosizing]; + end; + if ow_canclosenil in avalue then begin + include(opt1,ow1_canclosenil); + end; + optionswidget1:= opt1; + end; + + value:= optionswidgetty(setsinglebit(longword(avalue), + longword(foptionswidget), + {$ifdef FPC} + longword([ow_hinton,ow_hintoff]))); + {$else} + longword(mask))); + {$endif} + + delta:= optionswidgetty(longword(value) xor longword(foptionswidget)); + foptionswidget:= value - deprecatedoptionswidget; + if (delta * [ow_background,ow_top] <> []) then begin + if fparentwidget <> nil then begin + fparentwidget.sortzorder; + end + else begin + if ownswindow then begin + appinst.updatewindowstack; + end; + end; + end; + { + if delta * [ow_fontlineheight,ow_fontglyphheight] <> [] then begin + updatefontheight; + end; + } + end; +end; + +procedure twidget.setoptionswidget1(const avalue: optionswidget1ty); +{$ifndef FPC} +const + mask1: optionswidget1ty = [ow1_fontglyphheight,ow1_fontlineheight]; + mask2: optionswidget1ty = [ow1_autosizeanright,ow1_noautosizeanright]; + mask3: optionswidget1ty = [ow1_autosizeanbottom,ow1_noautosizeanbottom]; +{$endif} +var + value,delta: optionswidget1ty; +begin +{$ifdef FPC} + value:= optionswidget1ty(setsinglebit(longword(avalue),longword(foptionswidget1), + [longword([ow1_fontglyphheight,ow1_fontlineheight]), + longword([ow1_autosizeanright,ow1_noautosizeanright]), + longword([ow1_autosizeanbottom,ow1_noautosizeanbottom])])); +{$else} + value:= optionswidget1ty(setsinglebitar16(word(avalue),word(foptionswidget1), + [word(mask1),word(mask2),word(mask3)])); +{$endif} + delta:= optionswidget1ty({$ifdef FPC}longword{$else}word{$endif}(value) xor + {$ifdef FPC}longword{$else}word{$endif}(foptionswidget1)); + if delta <> [] then begin + foptionswidget1:= value; + if delta * [ow1_fontlineheight,ow1_fontglyphheight] <> [] then begin + updatefontheight; + end; + if delta * avalue * [ow1_autowidth,ow1_autoheight] <> [] then begin + checkautosize; + end; + if (delta * [ow1_clientcxmin,ow1_clientcxmax, + ow1_clientcymin,ow1_clientcymax] <> []) and + not (csloading in componentstate) then begin + exclude(fwidgetstate,ws_minclientsizevalid); + if ownswindow1 then begin + fwindow.sizeconstraintschanged(); + end; + internalsetwidgetrect(fwidgetrect,false); + end; + end; +end; + +procedure twidget.objectchanged(const sender: tobject); +begin + if fface <> nil then begin + fface.checktemplate(sender); + end; + if fframe <> nil then begin + fframe.checktemplate(sender); + end; +end; + +procedure twidget.objectevent(const sender: tobject; const event: objecteventty); +begin + inherited; + if (event = oe_changed) then begin + objectchanged(sender); + end; +end; + +procedure twidget.receiveevent(const event: tobjectevent); +begin + inherited; + case event.kind of + ek_activate: begin + window.activate; + end; + ek_childscaled: begin + exclude(fwidgetstate1,ws1_childscaled); + dolayout(nil); + end; + ek_resize: begin + clientsize:= addsize(clientsize,tresizeevent(event).size); + end; + end; +end; + +procedure twidget.beforeclosequery(var amodalresult: modalresultty); + //called on top level window +begin + //dummy +end; + +function twidget.canclose(const newfocus: twidget = nil): boolean; +var + int1: integer; +begin + result:= true; + for int1:= 0 to widgetcount - 1 do begin + result:= widgets[int1].canclose(newfocus); + if not result then begin + break; + end; + end; +end; + +function twidget.canparentclose(const newfocus: twidget): boolean; + //window.focusedwidget is first checked +begin + try + if checkdescendent(window.focusedwidget) then begin + result:= window.focusedwidget.canclose(newfocus); + if not result then begin + exit; + end; + end; + result:= canclose(newfocus); + except + result:= false; + application.handleexception; + end; +end; + +function twidget.forceclose: boolean; +var + bo1: boolean; +begin + bo1:= ws1_forceclose in fwidgetstate1; + include(fwidgetstate1,ws1_forceclose); + try + result:= canparentclose(nil); + finally + if not bo1 then begin + exclude(fwidgetstate1,ws1_forceclose); + end; + end; +end; + +function twidget.canparentclose: boolean; +begin + result:= canparentclose(window.focusedwidget); +end; + +function twidget.getcaretcliprect: rectty; + //origin = clientrect.pos +begin + result:= makerect(nullpoint,clientsize); +end; + +procedure twidget.dofontchanged(const sender: tobject); +begin + if not (ws1_scaling in fwidgetstate1) then begin + fontchanged; + end; +end; + +procedure twidget.fontchanged; +var + int1: integer; +begin + if componentstate * [csdestroying,csloading] = [] then begin + invalidate; + if not (ws_loadedproc in fwidgetstate) then begin + for int1:= 0 to high(fwidgets) do begin + fwidgets[int1].parentfontchanged; + end; + end; + updatefontheight; + end; +end; + +function twidget.verticalfontheightdelta: boolean; +begin + result:= false; +end; + +procedure twidget.dofontheightdelta(var delta: integer); +var + bo1: boolean; +begin + if ow1_autoscale in foptionswidget1 then begin + bo1:= ws1_autoscaling in fwidgetstate1; + include(fwidgetstate1,ws1_autoscaling); + try + with fwidgetrect do begin + if verticalfontheightdelta then begin + if fanchors * [an_left,an_right] = [an_right] then begin + setwidgetrect(makerect(x-delta,y,cx+delta,cy)); + end + else begin + if fanchors * [an_left,an_right] = [an_left] then begin + bounds_cx:= cx + delta; + end + end; + end + else begin + if fanchors * [an_top,an_bottom] = [an_bottom] then begin + setwidgetrect(makerect(x,y-delta,cx,cy+delta)); + end + else begin + if fanchors * [an_top,an_bottom] = [an_top] then begin + bounds_cy:= cy + delta; + end; + end; + end; + end; + finally + if not bo1 then begin + exclude(fwidgetstate1,ws1_autoscaling); + end; + end; + end; +end; + +procedure twidget.postchildscaled; +begin + if not (ws1_childscaled in fwidgetstate1) then begin + include(fwidgetstate1,ws1_childscaled); + if not (csloading in componentstate) then begin + appinst.postevent(tobjectevent.create( + ek_childscaled,ievent(self)),[peo_local]); + end; + end; +end; + +procedure twidget.updatefontheight; +var + int1: integer; +begin + if not (csloading in componentstate) and + (foptionswidget1 * [ow1_fontglyphheight,ow1_fontlineheight] <> []) then begin + int1:= ffontheight; + if ow1_fontglyphheight in foptionswidget1 then begin + ffontheight:= getfont.glyphheight; + end + else begin + ffontheight:= getfont.lineheight; + end; + if (int1 <> 0) and not (ws1_scaling in fwidgetstate1) then begin + int1:= ffontheight - int1; + if int1 <> 0 then begin + dofontheightdelta(int1); + if (int1 <> 0) and (fparentwidget <> nil) then begin + fparentwidget.postchildscaled; + end; + end; + end; + end; +end; + +procedure twidget.readfontheight(reader: treader); +begin + ffontheight:= reader.ReadInteger; +end; + +procedure twidget.writefontheight(writer: twriter); +begin + writer.writeinteger(ffontheight); +end; + +procedure twidget.defineproperties(filer: tfiler); +var + bo1: boolean; +begin + inherited; + if filer.ancestor <> nil then begin + bo1:= twidget(filer.ancestor).ffontheight <> ffontheight; + end + else begin + bo1:= foptionswidget1 * [ow1_fontglyphheight,ow1_fontlineheight] <> []; + end; + filer.DefineProperty('reffontheight',{$ifdef FPC}@{$endif}readfontheight, + {$ifdef FPC}@{$endif}writefontheight,bo1); +end; + +procedure twidget.parentfontchanged; +begin + if ffont = nil then begin + fontchanged; + end; + if fframe <> nil then begin + fframe.parentfontchanged; + end; +end; + +procedure twidget.reflectmouseevent(var info: mouseeventinfoty); +var + id: winidty; + po1: pointty; + window1: twindow; +begin + with info do begin + if not (eventkind in mouseregionevents) then begin + po1:= translatewidgetpoint(pos,self,nil); + id:= gui_windowatpos(po1); + if (id = 0) or not appinst.findwindow(id,window1) then begin + window1:= fwindow; + end; + subpoint1(po1,window1.fownerwidget.fwidgetrect.pos); + appinst.eventlist.insert(0,tmouseevent.create(window1.winid, + eventkind = ek_buttonrelease,button,mw_none,po1,shiftstate,info.timestamp, + true)); + end; + end; +end; + +function twidget.getnextfocus: twidget; +var + widget1: twidget; + int1,int2: integer; +begin + result:= nexttaborder; + if (result = self) or (result = nil) then begin + result:= nil; + if fparentwidget <> nil then begin + int2:= parentwidgetindex; + for int1:= int2+1 to fparentwidget.widgetcount - 1 do begin + widget1:= twidget(fparentwidget.fwidgets[int1]); + if widget1.canfocus and (ws_iswidget in widget1.fwidgetstate) then begin + result:= widget1; + break; + end; + end; + if result = nil then begin + for int1:= int2 - 1 downto 0 do begin + widget1:= twidget(fparentwidget.fwidgets[int1]); + if widget1.canfocus and (ws_iswidget in widget1.fwidgetstate) then begin + result:= widget1; + break; + end; + end; + if result = nil then begin + if fparentwidget.canfocus then begin + result:= fparentwidget; + end + else begin + result:= fparentwidget.getnextfocus; + end; + exit; + end; + end; + end; + end; +end; + +procedure twidget.nextfocus; +begin + window.setfocusedwidget(getnextfocus); +end; + +function twidget.getdisprect: rectty; //origin parentwidget.pos, + //clamped in view by activate +begin + result.pos:= nullpoint; + result.size:= fwidgetrect.size; +end; + +function twidget.getdefaultfocuschild: twidget; //returns first focusable widget +var + tabord: integer; + int1: integer; + widget1: twidget; +begin + if (fdefaultfocuschild <> nil) and fdefaultfocuschild.canfocus then begin + result:= fdefaultfocuschild; + end + else begin + result:= nil; + end; + if result = nil then begin + tabord:= bigint; + with container do begin + for int1:= 0 to widgetcount - 1 do begin + widget1:= twidget(fwidgets[int1]); + with widget1 do begin + if (ftaborder < tabord) and (ow_tabfocus in foptionswidget) and canfocus then begin + result:= widget1; + tabord:= ftaborder; + end; + end; + end; + end; + if result = nil then begin + result:= container; + if result = self then begin + result:= nil; + end; + end; + end; +end; + +procedure twidget.setdefaultfocuschild(const value: twidget); +begin + fdefaultfocuschild:= value; +end; + +function twidget.trycancelmodal(const newactive: twindow): boolean; + //called by twindow.internalactivate, true if accepted +begin + result:= false; +end; + +function twidget.parentwidgetindex: integer; +begin + if fparentwidget = nil then begin + result:= -1; + end + else begin + result:= fparentwidget.IndexOfwidget(self); + end; +end; + +procedure twidget.invalidateparentminclientsize; +begin + if fparentwidget <> nil then begin + exclude(fparentwidget.fwidgetstate,ws_minclientsizevalid); + end; +end; + +procedure twidget.setanchors(const Value: anchorsty); +begin + if fanchors <> value then begin + fanchors:= Value; + if not (csloading in componentstate) then begin + invalidateparentminclientsize; + include(fwidgetstate1,ws1_anchorsetting); + try + parentclientrectchanged; + finally + exclude(fwidgetstate1,ws1_anchorsetting); + end; + end; + end; +end; + +function twidget.getzorder: integer; +begin + result:= 0; //!!!!todo +end; + +procedure twidget.setzorder(const value: integer); +begin //!!!!todo + if ownswindow1 then begin + window.setzorder(value); + end; +end; + +function twidget.getfontclass: widgetfontclassty; +begin + result:= twidgetfont; +end; + +function twidget.getfontemptyclass: widgetfontemptyclassty; +begin + result:= twidgetfontempty; +end; + +procedure twidget.internalcreatefont; +begin + if ffont = nil then begin + ffont:= getfontclass.create; + end; + ffont.onchange:= {$ifdef FPC}@{$endif}dofontchanged; +end; + +procedure twidget.internalcreatefontempty; +begin + if ffontempty = nil then begin + ffontempty:= getfontemptyclass.create; + end; + ffontempty.onchange:= {$ifdef FPC}@{$endif}dofontchanged; +end; + +procedure twidget.syncsinglelinefontheight(const lineheight: boolean = false; + const space: integer = 2); +var + int1: integer; +begin + if lineheight then begin + int1:= getfont.lineheight; + end + else begin + int1:= getfont.glyphheight; + end; + if verticalfontheightdelta then begin + if fframe = nil then begin + bounds_cx:= bounds_cx + int1 + space - paintsize.cx + end + else begin + bounds_cx:= bounds_cx + int1 + fframe.framei_left + + fframe.framei_right - paintsize.cx; + end; + end + else begin + if fframe = nil then begin + bounds_cy:= bounds_cy + int1 + space - paintsize.cy + end + else begin + bounds_cy:= bounds_cy + int1 + fframe.framei_top + + fframe.framei_bottom - paintsize.cy; + end; + end; +end; + +procedure twidget.synctofontheight; +begin + setfontheight; +end; + +function twidget.getfont1: twidgetfont; +var + widget1: twidget; +begin + widget1:= self; + repeat + result:= widget1.ffont; + if result <> nil then begin + exit; + end; + widget1:= widget1.fparentwidget; + until widget1 = nil; + result:= stockobjects.fonts[stf_default]; +end; + +function twidget.getfont: twidgetfont; +begin + getoptionalobject(ffont,{$ifdef FPC}@{$endif}internalcreatefont); + result:= getfont1; +end; + +function twidget.getframefont: tfont; +begin + if fparentwidget <> nil then begin + result:= fparentwidget.getfont1; + end + else begin + result:= stockobjects.fonts[stf_default]; + end; +end; + +function twidget.isfontstored: Boolean; +begin + result:= ffont <> nil; +end; + +function twidget.isfontemptystored: Boolean; +begin + result:= ffontempty <> nil; +end; + +procedure twidget.setfont(const avalue: twidgetfont); +begin + if avalue <> ffont then begin + setoptionalobject(avalue,ffont,{$ifdef FPC}@{$endif}internalcreatefont); + fontchanged; + end; +end; + +function twidget.getfontempty1: twidgetfontempty; +var + widget1: twidget; +begin + widget1:= self; + repeat + result:= widget1.ffontempty; + if result <> nil then begin + exit; + end; + widget1:= widget1.fparentwidget; + until widget1 = nil; +{$warnings off} + result:= twidgetfontempty(stockobjects.fonts[stf_empty]); +{$warnings on} +end; + +function twidget.getfontempty: twidgetfontempty; +begin + getoptionalobject(ffontempty,{$ifdef FPC}@{$endif}internalcreatefontempty); + result:= getfontempty1; +end; + +procedure twidget.setfontempty(const avalue: twidgetfontempty); +begin + if avalue <> ffontempty then begin + setoptionalobject(avalue,ffontempty, + {$ifdef FPC}@{$endif}internalcreatefontempty); + fontchanged; + end; +end; + +function twidget.getframe: tcustomframe; +begin + getoptionalobject(fframe,{$ifdef FPC}@{$endif}internalcreateframe); + result:= fframe; +end; + +procedure twidget.setframe(const avalue: tcustomframe); +begin + if (ws_staticframe in fwidgetstate) then begin + if (avalue <> nil) and (pointer(avalue) <> pointer(1)) then begin + fframe.assign(avalue); + end; + end + else begin + setoptionalobject(avalue,fframe,{$ifdef FPC}@{$endif}internalcreateframe); + if (componentstate*[csloading,csdestroying] = []) then begin + clientrectchanged; + end; + end; +end; + +function twidget.getface: tcustomface; +begin + getoptionalobject(fface,{$ifdef FPC}@{$endif}internalcreateface); + result:= fface; +end; + +procedure twidget.setface(const avalue: tcustomface); +begin + if (ws_staticface in fwidgetstate) then begin + if (avalue <> nil) and (pointer(avalue) <> pointer(1)) then begin + fface.assign(avalue); + end; + end + else begin + setoptionalobject(avalue,fface,{$ifdef FPC}@{$endif}internalcreateface); + end; + invalidate; +end; + +function twidget.getcomponentstate: tcomponentstate; +begin + result:= componentstate; +end; + +function twidget.getframestateflags: framestateflagsty; +begin + result:= combineframestateflags(not isenabled,ws_focused in fwidgetstate, + ws_active in fwidgetstate, + appinst.clientmousewidget = self,ws_lclicked in fwidgetstate); +end; + +procedure twidget.setframeinstance(instance: tcustomframe); +begin + fframe:= instance; +end; + +procedure twidget.setstaticframe(value: boolean); +begin + if value then begin + include(fwidgetstate,ws_staticframe); + end + else begin + exclude(fwidgetstate,ws_staticframe); + end; +end; + +function twidget.getstaticframe: boolean; +begin + result:= ws_staticframe in fwidgetstate; +end; + +function twidget.isloading: boolean; +begin + result:= ([csloading,csdestroying] * componentstate <> []) or + (ws_loadlock in fwidgetstate); +end; + +function twidget.widgetstate: widgetstatesty; +begin + result:= fwidgetstate; +end; + +procedure twidget.insertwidget(const awidget: twidget; const apos: pointty); +begin + if (awidget.fparentwidget <> nil) and (awidget.fparentwidget <> self) then begin + awidget.fparentwidget.unregisterchildwidget(awidget); + awidget.fparentwidget:= nil; + end; + if not (csloading in componentstate) then begin + awidget.fparentclientsize:= clientsize; + end; + if awidget.ownswindow1 then begin + awidget.fwidgetrect.pos:= addpoint(screenpos,apos); + end + else begin + awidget.fwidgetrect.pos:= apos; + end; + awidget.parentwidget:= self; +end; + +procedure twidget.insertwidget(const awidget: twidget); +begin + insertwidget(awidget,awidget.fwidgetrect.pos); +end; + +function twidget.getwidget: twidget; +begin + result:= self; +end; + +procedure twidget.activate(const abringtofront: boolean = true; + const aforce: boolean = false); +begin + if abringtofront then begin + window.bringtofront; + end; + if window.modalfor then begin + show(ml_window,window.transientfor); + end + else begin + show(ml_none,window.transientfor); + end; + if aforce then begin + gui_setwindowfocus(window.winid); + end; + if not checkdescendent(window.ffocusedwidget) then begin + setfocus; + end + else begin + fwindow.ffocusedwidget.setfocus; //activate + end; +end; + +procedure twidget.bringtofront; +begin + if fparentwidget <> nil then begin + with fparentwidget do begin + if fwidgets[high(fwidgets)] <> self then begin + removeitem(pointerarty(fwidgets),self); + additem(pointerarty(fwidgets),self); + sortzorder; + end; + end; + end + else begin + window.bringtofront; + end; +end; + +procedure twidget.sendtoback; +begin + if fparentwidget <> nil then begin + with fparentwidget do begin + if fwidgets[0] <> self then begin + removeitem(pointerarty(fwidgets),self); + insertitem(pointerarty(fwidgets),0,pointer(self)); + sortzorder; + end; + end; +// invalidate; + end + else begin + window.sendtoback; + end; +end; + +procedure twidget.stackunder(const predecessor: twidget); +var + int1: integer; +begin + if fparentwidget <> nil then begin + with fparentwidget do begin + removeitem(pointerarty(fwidgets),self); + int1:= indexofwidget(predecessor); + if int1 >0 then begin + int1:= 0; + end; + insertitem(pointerarty(fwidgets),int1,pointer(self)); + end; + invalidate; + end + else begin + window.stackunder(predecessor.window); + end; +end; + +procedure twidget.setchildorder(const achildren: widgetarty); //last is top +var + int1,int2,int3: integer; +begin + int2:= high(fwidgets); + for int1:= high(achildren) downto 0 do begin + if achildren[int1] <> nil then begin + for int3:= int2 downto 0 do begin + if fwidgets[int3] = achildren[int1] then begin + moveitem(pointerarty(fwidgets),int3,int2); + dec(int2); + break; + end; + end; + end; + end; + sortzorder; +end; + +function twidget.gethint: msestring; +begin + result:= fhint; +end; + +procedure twidget.sethint(const Value: msestring); +begin + fhint:= value; +end; + +function twidget.ishintstored: boolean; +begin + result:= fhint <> ''; +end; + +function twidget.findtagchild(const atag: integer; + const aclass: widgetclassty): twidget; +var + int1: integer; +begin + result:= nil; + for int1:= 0 to high(fwidgets) do begin + if (fwidgets[int1].tag = atag) and + ((aclass = nil) or (fwidgets[int1] is aclass)) then begin + result:= fwidgets[int1]; + exit; + end; + end; + if result = nil then begin + for int1:= 0 to high(fwidgets) do begin + result:= fwidgets[int1].findtagchild(atag,aclass); + if result <> nil then begin + exit; + end; + end; + end; +end; + +function twidget.dofindwidget(const awidgets: widgetarty; + aname: ansistring): twidget; +var + int1: integer; +begin + result:= nil; + aname:= struppercase(aname); + for int1:= 0 to high(awidgets) do begin + if stringicompupper(awidgets[int1].name,aname) = 0 then begin + result:= awidgets[int1]; + break; + end; + end; +end; + +function twidget.findchild(const aname: ansistring): twidget; +begin + result:= dofindwidget(container.fwidgets,aname); +end; + +function twidget.gethelpcontext: msestring; +var + widget1: twidget; +begin + result:= fhelpcontext; + if result = '' then begin + if componentstate * [csloading,cswriting,csdesigning] = [] then begin + widget1:= fparentwidget; + while widget1 <> nil do begin + result:= widget1.fhelpcontext; + if result <> '' then begin + break; + end; + widget1:= widget1.fparentwidget; + end; + end; + end; +end; + +class function twidget.classskininfo: skininfoty; +begin + result:= inherited classskininfo; + result.objectkind:= sok_widget; +end; + +procedure twidget.getautopaintsize(var asize: sizety); +begin + painttowidgetsize(asize); + checkwidgetsize(asize); + widgettopaintsize(asize); +end; + +procedure twidget.getautocellsize(const acanvas: tcanvas; + var asize: sizety); +begin + getautopaintsize(asize); + painttowidgetsize(asize); +end; + +procedure twidget.checkautosize(); +begin + if ([csloading,csdestroying] * componentstate = []) and + not (ws1_autosizing in fwidgetstate1)then begin + include(fwidgetstate1,ws1_autosizing); + try + if ([ow1_autowidth,ow1_autoheight]*foptionswidget1 <> []) then begin + internalsetwidgetrect(fwidgetrect,false); + end + else begin + if fparentwidget <> nil then begin + fparentwidget.childautosizechanged(self); + end; + end; + finally + exclude(fwidgetstate1,ws1_autosizing); + end; + end; +end; + +procedure twidget.updatehotkeys(); +begin + if fframe <> nil then begin + fframe.updatehotkeys(); + end; +end; + +procedure twidget.childautosizechanged(const sender: twidget); +begin + //dummy +end; + +procedure twidget.scale(const ascale: real); +var + int1: integer; + rect1: rectty; +begin + include(fwidgetstate1,ws1_scaling); + try + rect1:= fwidgetrect; + if fframe <> nil then begin + fframe.scale(ascale); + end; + if ffont <> nil then begin + ffont.scale(ascale); + end; + for int1:= 0 to high(fwidgets) do begin + fwidgets[int1].scale(ascale); + end; + with rect1 do begin + x:= round(x*ascale); + y:= round(y*ascale); + cx:= round(cx*ascale); + cy:= round(cy*ascale); + end; + with fminsize do begin + cx:= round(cx*ascale); + cy:= round(cy*ascale); + end; + with fmaxsize do begin + cx:= round(cx*ascale); + cy:= round(cy*ascale); + end; + widgetrect:= rect1; + finally + exclude(fwidgetstate1,ws1_scaling); + end; +end; + +function twidget.widgetminsize: sizety; +begin + result:= nullsize; + checkwidgetsize(result); + if fframe <> nil then begin + fframe.checkwidgetsize(result); + end; +end; + +function twidget.widgetmaxsize: sizety; +begin + result.cx:= bigint; + result.cy:= bigint; + checkwidgetsize(result); + if fframe <> nil then begin + fframe.checkwidgetsize(result); + end; + if result.cx = bigint then begin + result.cx:= 0; + end; + if result.cy = bigint then begin + result.cy:= 0; + end; +end; + +function twidget.maxclientsize: sizety; +begin + result:= clientsize; +end; + +procedure twidget.fontcanvaschanged; +var + int1: integer; +begin + for int1:= 0 to high(fwidgets) do begin + fwidgets[int1].fontcanvaschanged; + end; + if frame <> nil then begin + fframe.fontcanvaschanged; + end; + checkautosize; +end; + +function twidget.getactface: tcustomface; +begin + result:= fface; +end; + +function twidget.getdragrect(const apos: pointty): rectty; +begin + with result do begin + x:= apos.x - mindragdist; + y:= apos.y - mindragdist; + cx:= 2 * mindragdist; + cy:= 2 * mindragdist; + end; +end; + +procedure twidget.setoptionsskin(const avalue: optionsskinty); +{$ifndef FPC} +const + mask1: optionsskinty = [osk_skin,osk_noskin]; + mask2: optionsskinty = [osk_colorcaptionframe,osk_nocolorcaptionframe]; +{$endif} +var + {opt1,opt2,}valuebefore: optionsskinty; +begin + valuebefore:= foptionsskin; +// opt1:= optionsskinty(setsinglebit( +// {$ifdef FPC}longword{$else}word{$endif}(avalue), +// {$ifdef FPC}longword{$else}word{$endif}(foptionsskin), +// {$ifdef FPC}longword{$else}word{$endif}(mask1))); +// opt2:= optionsskinty(setsinglebit( +// {$ifdef FPC}longword{$else}word{$endif}(avalue), +// {$ifdef FPC}longword{$else}word{$endif}(foptionsskin), +// {$ifdef FPC}longword{$else}word{$endif}(mask2))); +// foptionsskin:= avalue - (mask1+mask2) + opt1*mask1 + opt2*mask2; + +{$ifdef FPC} + foptionsskin:= optionsskinty(setsinglebit( + longword(avalue),longword(foptionsskin), + [longword([osk_skin,osk_noskin]), + longword([osk_colorcaptionframe,osk_nocolorcaptionframe])])); +{$else} + foptionsskin:= optionsskinty(setsinglebitar16( + word(avalue),word(foptionsskin), + [word(mask1),word(mask2)])); +{$endif} + if (optionsskinty({$ifdef FPC}longword{$else}word{$endif}(valuebefore) xor + {$ifdef FPC}longword{$else}word{$endif}(avalue)) * + [osk_nopropwidth,osk_nopropheight] <> []) and (fparentwidget <> nil) then begin + fparentwidget.scalebasechanged(self); //for tlayouter + end; +end; + +function twidget.skininfo: skininfoty; +var + widget1: twidget; +begin + result:= inherited skininfo; + if osk_container in foptionsskin then begin + include(result.options,sko_container); + end; + widget1:= self; + repeat + result.group:= widget1.fskingroup; + if result.group <> 0 then begin + break; + end; + widget1:= widget1.parentwidget; + until widget1 = nil; +end; + +function twidget.hasskin: boolean; +begin + result:= true; + if not (osk_skin in foptionsskin) then begin + if osk_noskin in foptionsskin then begin + result:= false; + end + else begin + if fparentwidget <> nil then begin + result:= fparentwidget.hasskin; + end; + end; + end; +end; + +function twidget.innerclientframe: framety; +begin + if fframe = nil then begin + result:= nullframe; + end + else begin + result:= fframe.fi.innerframe; + end; +end; + +procedure twidget.scalebasechanged(const sender: twidget); +begin + //dummy +end; + +procedure twidget.setclippedwidgetrect(arect: rectty); +var + rect1: rectty; +begin + if parentwidget = nil then begin + rect1:= application.workarea(window); + if not rectinrect(inflaterect(arect,2),rect1) then begin + clipinrect1(arect,rect1); + gui_setdecoratedwindowrect(window.winid,arect,rect1); + widgetrect:= rect1; + end + else begin + widgetrect:= arect; + end; + end + else begin + clipinrect1(arect,fparentwidget.widgetsizerect); + widgetrect:= arect; + end; +end; + +procedure twidget.dragstarted; +var + int1: integer; +begin + for int1:= 0 to high(fwidgets) do begin + fwidgets[int1].dragstarted; + end; +end; + +function twidget.canmouseinteract: boolean; +begin + result:= not (csdesigning in componentstate) or + (cssubcomponent in componentstyle); +end; + +function twidget.canclose1: boolean; +begin + result:= canclose; +end; + +function twidget.getiassistiveclient(): iassistiveclient; +begin + result:= iassistiveclient(self); +end; + +function twidget.canassistive(): boolean; +begin + result:= (assistiveserver <> nil) and + not (ow1_noassistive in foptionswidget1) and + not (csdesigning in componentstate); +end; + +function twidget.getassistiveparent(): iassistiveclient; +begin + result:= nil; + if fparentwidget <> nil then begin + result:= fparentwidget.getiassistiveclient(); + end; +end; + +function twidget.getassistivewidget: tobject; +begin + result:= self; +end; + +procedure twidget.beginupdate; +begin + if fwidgetupdating = 0 then begin + include(fwidgetstate,ws_loadlock); + inc(fnoinvalidate); + end; + inc(fwidgetupdating); +end; + +procedure twidget.endupdate; +begin + dec(fwidgetupdating); + if fwidgetupdating = 0 then begin + exclude(fwidgetstate,ws_loadlock); + dec(fnoinvalidate); + widgetregionchanged(nil); + end; +end; + +function twidget.getzoomrefframe: framety; +begin + result:= innerclientframe; +end; + +procedure twidget.designmouseevent(var info: moeventinfoty; capture: twidget); +begin + if fparentwidget <> nil then begin + fparentwidget.designmouseevent(info,capture); + end; +end; + +procedure twidget.designkeyevent(const eventkind: eventkindty; + var info: keyeventinfoty); +begin + if fparentwidget <> nil then begin + fparentwidget.designkeyevent(eventkind,info); + end; +end; + +function twidget.isdesignwidget: boolean; +begin + result:= (csdesigning in componentstate) or + (ws1_designwidget in fwidgetstate1); +end; + +procedure twidget.setdesignwidget(); +var + i1: int32; +begin + include(fwidgetstate1,ws1_designwidget); + for i1:= 0 to high(fwidgets) do begin + fwidgets[i1].setdesignwidget(); + end; +end; + +function twidget.getassistivename: msestring; +begin + result:= msestring(name); +end; + +function twidget.getassistivecaption(): msestring; +begin + if fframe <> nil then begin + result:= fframe.getassistivecaption(); + end + else begin + result:= ''; + end; +end; + +function twidget.getassistivetext(): msestring; +begin + result:= ''; +end; + +function twidget.getassistivecaretindex(): int32; +begin + result:= -1; +end; + +function twidget.getassistivehint(): msestring; +begin + result:= hint; +end; + +function twidget.getassistiveflags(): assistiveflagsty; +begin + result:= []; + if not (ws_iswidget in fwidgetstate) then begin + include(result,asf_embedded); + end; + if osk_container in foptionsskin then begin + include(result,asf_container); + end; + if focused then begin + include(result,asf_focused); + end; + if not isenabled then begin + include(result,asf_disabled); + end; + if ownswindow then begin + include(result,asf_toplevel); + end; + if window = application.mainwindow then begin + include(result,asf_mainwindow); + end; +end; + +function twidget.getifidatalinkintf(): iifidatalink; +begin + result:= nil; +end; + +{ twindow } + +constructor twindow.create(const aowner: twidget; const agdi: pgdifunctionaty); +begin + fgdi:= agdi; + if fgdi = nil then begin + fgdi:= getdefaultgdifuncs; + end; + fownerwidget:= aowner; + fownerwidget.fwindow:= self; + fcanvas:= creategdicanvas(fgdi,bmk_rgb,self,icanvas(self)); + fasynccanvas:= creategdicanvas(fgdi,bmk_rgb,self,icanvas(self)); + fscrollnotifylist:= tnotifylist.create; + fopacity:= emptyreal; + inherited create; + fownerwidget.rootchanged([rcf_windowset]); //nil all references +end; + +destructor twindow.destroy; +begin + include(fstate,tws_destroying); + freeandnil(fsysdragobject); + container:= 0; + appinst.twindowdestroyed(self); + if ftransientfor <> nil then begin + dec(ftransientfor.ftransientforcount); + end; + if fownerwidget <> nil then begin + fownerwidget.rootchanged([rcf_windowremove]); + end; + destroywindow; + fcanvas.free; + fasynccanvas.free; + inherited; + destroyregion(fupdateregion); + fscrollnotifylist.free; +end; + +procedure twindow.setasynccanvas(const acanvas: tcanvas); +begin + include(fstate,tws_canvasoverride); + acanvas.initflags(fasynccanvas); + fownerwidget.fontcanvaschanged; +end; + +procedure twindow.releaseasynccanvas; +begin + if tws_canvasoverride in fstate then begin + exclude(fstate,tws_canvasoverride); + fasynccanvas.initflags(fasynccanvas); + end; +end; + +procedure twindow.setsizeconstraints(const amin,amax: sizety); +begin + if fwindow.id <> 0 then begin + guierror(gui_setsizeconstraints( + fwindow.id,amin,amax)); + end; +end; + +procedure twindow.sizeconstraintschanged; +begin + setsizeconstraints(fownerwidget.widgetminsize1(), + fownerwidget.widgetmaxsize1()); +end; + +function twindow.haswinid: boolean; +begin + result:= fwindow.id <> 0; +end; + +procedure twindow.createwindow; +var + gc: gcty; + aoptions: windowinfoty; + aoptions1: internalwindowoptionsty; + event: tcreatewindowevent; +begin + if fwindow.id = 0 then begin + fnormalwindowrect:= fownerwidget.fwidgetrect; + fillchar(aoptions,sizeof(aoptions),0); + fillchar(aoptions1,sizeof(aoptions1),0); + aoptions.groupleader:= application.mainwindow; + aoptions.initialwindowpos:= fwindowpos; + aoptions.transientfor:= ftransientfor; + fownerwidget.updatewindowinfo(aoptions); + foptions:= aoptions.options; + fwindowpos:= aoptions.initialwindowpos; + fwindowposbefore:= fwindowpos; + updatebit({$ifdef FPC}longword{$else}longword{$endif}(fstate), + ord(tws_needsdefaultpos),fwindowpos = wp_default); + with aoptions do begin + buttonendmodal:= wo_buttonendmodal in options; + aoptions1.options:= options; + aoptions1.pos:= fwindowpos; + if transientfor <> ftransientfor then begin + checkrecursivetransientfor(transientfor); + setlinkedvar(transientfor,tlinkedobject(ftransientfor)); + if transientfor <> nil then begin + inc(ftransientfor.ftransientforcount); + aoptions1.transientfor:= transientfor.winid; + end; + end; + aoptions1.icon:= icon; + aoptions1.iconmask:= iconmask; + end; + if (aoptions.groupleader <> nil) and + aoptions.groupleader.fownerwidget.isgroupleader then begin + aoptions1.setgroup:= true; + if aoptions.groupleader <> self then begin + aoptions1.groupleader:= aoptions.groupleader.fwindow.id; + //do not create winid + end; + end; + if application.ismainthread then begin + fcanvas.updatewindowoptions(aoptions1); + guierror(gui_createwindow(fownerwidget.fwidgetrect,aoptions1,fwindow),self); + end + else begin //needed for win32 + event:= tcreatewindowevent.create(false); + with event do begin + fsender:= self; + frect:= fownerwidget.widgetrect; + foptionspo:= @aoptions1; + fwindowpo:= @self.fwindow; + synchronizeevent(event); + free; + end; + if fwindow.id = 0 then begin + abort; + end; + end; + sizeconstraintschanged; + fstate:= fstate - [tws_posvalid,tws_sizevalid]; + fillchar(gc,sizeof(gcty),0); + gc.paintdevicesize:= fownerwidget.fwidgetrect.size; + gc.kind:= bmk_rgb; //todo: what about depht 8? + gdierror(fcanvas.creategc(fwindow.id,gck_screen,gc),self); + gc.paintdevicesize:= fownerwidget.fwidgetrect.size; + fcanvas.linktopaintdevice(fwindow.id,gc{,fowner.fwidgetrect.size},nullpoint); + gdierror(fasynccanvas.creategc(fwindow.id,gck_screen,gc),self); + fasynccanvas.linktopaintdevice(fwindow.id,gc,{fowner.fwidgetrect.size,}nullpoint); + if appinst <> nil then begin + tinternalapplication(application).registerwindow(self); + end; + if fcaption <> '' then begin + gui_setwindowcaption(fwindow.id,fcaption); + end; + if fopacity <> emptyreal then begin + gui_setwindowopacity(fwindow.id,fopacity); + end; + fownerwidget.windowcreated; + end + else begin + guierror(gue_illegalstate,self); + end; +end; + +procedure twindow.destroywindow; +begin + releasemouse; + if appinst <> nil then begin + if appinst.caret.islinkedto(fcanvas) then begin + appinst.caret.hide; + end; + appinst.unregisterwindow(self); + end; + fcanvas.unlink; + fasynccanvas.unlink; + if fwindow.id <> 0 then begin + appinst.windowdestroyed(fwindow.id); + end; +// if application.ismainthread then begin +// if fdestroyevent <> nil then begin +// tdestroywindowevent(fdestroyevent).fwindowpo:= nil; +// end; + gui_destroywindow(fwindow); +// end +// else begin +// if fdestroyevent = nil then begin +// fdestroyevent:= tdestroywindowevent.create(false); +// tdestroywindowevent(fdestroyevent).fwindowpo:= @fwindow; +// synchronizeevent(tdestroywindowevent(fdestroyevent)); +// freeandnil(fdestroyevent); +// end; +// end; + fillchar(fwindow,sizeof(fwindow),0); + exclude(fstate,tws_windowvisible); +end; + +procedure twindow.recreatewindow(); +var + b1: boolean; +begin + b1:= visible; + destroywindow(); + createwindow(); + if b1 then begin + show(false); + end; +end; + +procedure twindow.windowdestroyed; +begin + fwindow.id:= 0; + destroywindow; +end; + +procedure twindow.checkwindowid; +begin + checkwindow(false); +end; + +procedure twindow.checkwindow(windowevent: boolean); +begin + if (appinst <> nil) and (aps_inited in appinst.fstate) then begin + if fwindow.id = 0 then begin + createwindow; + end + else begin + if fstate * [tws_posvalid,tws_sizevalid] <> + [tws_posvalid,tws_sizevalid] then begin + if not windowevent and not (tws_needsdefaultpos in fstate) and + (fmoving <= 0) and (windowpos in [wp_normal,wp_default]) then begin + if not (wo_embedded in foptions) then begin + fnormalwindowrect:= fownerwidget.fwidgetrect; + {$ifdef mse_debugconfigure} + with fnormalwindowrect do begin + if visible then begin + debugwindow('*checkwin visible '+ + inttostr(x)+' '+inttostr(y)+' '+inttostr(cx)+' '+inttostr(cy)+' ', + fwindow.id); + end + else begin + debugwindow('*checkw. invis. '+ + inttostr(x)+' '+inttostr(y)+' '+inttostr(cx)+' '+inttostr(cy)+' ', + fwindow.id); + end; + end; + {$endif} + appinst.removewindowevents(fwindow.id,ek_configure); + guierror(gui_reposwindow(fwindow.id,fnormalwindowrect),self); + end; + fstate:= fstate + [tws_posvalid,tws_sizevalid]; + end; + end; + end; + end; +end; + +function twindow.activating: boolean; //in internalactivate proc +begin + result:= factivating > 0; +end; + +procedure twindow.internalactivate(const windowevent: boolean; + const force: boolean = false); + + procedure setwinfoc; + var + window1: twindow; + focustransientforbefore: twindow; + begin + focustransientforbefore:= appinst.ffocuslocktransientfor; + if (ftransientfor <> nil) and (force or (appinst.ffocuslockwindow = nil)) and + (wo_popup in foptions) then begin + appinst.ffocuslockwindow:= self; + window1:= ftransientfor; + repeat + if window1 = appinst.ffocuslocktransientfor then begin + break; + end; + window1:= window1.ftransientfor; + until window1 = nil; + if window1 = nil then begin + if appinst.ffocuslocktransientfor <> ftransientfor then begin + appinst.ffocuslocktransientfor:= ftransientfor; + exclude(appinst.fstate,aps_restorelocktransientfor); + end; + end; + end + else begin + if not ispopup then begin + appinst.ffocuslocktransientfor:= nil; + end; + end; + if (appinst.ffocuslockwindow <> nil) and + (appinst.ffocuslocktransientfor <> nil) then begin + if (focustransientforbefore <> appinst.ffocuslocktransientfor) or + (aps_restorelocktransientfor in appinst.fstate) then begin + exclude(appinst.fstate,aps_restorelocktransientfor); + guierror(gui_setwindowfocus(appinst.ffocuslocktransientfor.winid),self); + end; + end + else begin + if (appinst.ffocuslockwindow = nil) or + (appinst.ffocuslockwindow = self) then begin + guierror(gui_setwindowfocus(fwindow.id),self); + end; + end; + end; + +var + activecountbefore: longword; + activewindowbefore: twindow; + widgetar: widgetarty; + int1: integer; + b1,b2: boolean; + window1: twindow; + widget1: twidget; + +begin +{$ifdef mse_debugwindowfocus} + debugwindow('*internalactivate ',fwindow.id); + debugwrite(' modalwindow '); + if appinst.fmodalwindow = nil then begin + debugwriteln(' NIL'); + end + else begin + debugwriteln(appinst.fmodalwindow.fownerwidget.name); + end; +{$endif} + inc(factivating); + try + if appinst.finactivewindow = self then begin + appinst.finactivewindow:= nil; + end; + activewindowbefore:= nil; + setlinkedvar(appinst.factivewindow,tlinkedobject(activewindowbefore)); + show(windowevent); + widgetar:= nil; //compilerwarning + if activewindowbefore <> self then begin + b1:= force or (appinst.fmodalwindow = nil) or (appinst.fmodalwindow = self) or + (ftransientfor = appinst.fmodalwindow); + if b1 then begin + if hastransientfor then begin + window1:= topmodaltransientfor; + if window1 <> nil then begin + window1.internalactivate(false,force); + exit; + end; + end; + if (ffocusedwidget = nil) and fownerwidget.canfocus and (ffocusing = 0) then begin + fownerwidget.setfocus(true); + if windowevent and force and not active then begin + internalactivate(true,true); //call by setfocus was without force + end; + exit; + end; + b2:= activewindowbefore <> nil; + if b2 then begin + b1:= tws_activating in activewindowbefore.fstate; + include(fstate,tws_activating); + try + activewindowbefore.deactivate; + finally + if not b1 and (activewindowbefore <> nil) then begin + exclude(activewindowbefore.fstate,tws_activating); + end; + end; + end; + if appinst.factivewindow = nil then begin + if not (ws_active in fownerwidget.fwidgetstate) then begin + inc(factivecount); + activecountbefore:= factivecount; + appinst.factivewindow:= self; + appinst.flastactivewindow:= self; + appinst.checkapplicationactive(); + if not (tws_activatelocked in fstate) then begin + if fownerwidget.canassistive() then begin + assistiveserver.dowindowactivated( + self.fownerwidget.getiassistiveclient()); + end; + if ffocusedwidget <> nil then begin + widgetar:= ffocusedwidget.getrootwidgetpath; + for int1:= high(widgetar) downto 0 do begin + widgetar[int1].internaldoactivate; + if factivecount <> activecountbefore then begin + exit; + end; + end; + end; + end; + gui_setimefocus(fwindow); + if not windowevent then begin + setwinfoc; + end + else begin + if appinst.ffocuslockwindow <> self then begin + appinst.ffocuslockwindow:= nil; + appinst.ffocuslocktransientfor:= nil; + end + else begin + if appinst.ffocuslocktransientfor <> nil then begin + guierror(gui_setwindowfocus(appinst.ffocuslocktransientfor.winid),self); + end; + end; + end; + end; + end; + appinst.fonwindowactivechangelist.dowindowchange(activewindowbefore,self); + if activecountbefore = factivecount then begin + if activewindowbefore = nil then begin + widget1:= nil; + end + else begin + widget1:= activewindowbefore.focusedwidget; + end; + appinst.fonwidgetactivechangelist.dowidgetchange(widget1, + self.focusedwidget); + end; + end + else begin + appinst.fwantedactivewindow:= self; + end; + end + else begin + setwinfoc; + end; + finally + dec(factivating); + setlinkedvar(nil,tlinkedobject(activewindowbefore)); + end; +{$ifdef mse_debugwindowfocus} + debugwindow('-internalactivate ',fwindow.id); +{$endif} +end; + +procedure twindow.noactivewidget; +var + widget: twidget; + activecountbefore: longword; +begin + if ffocusedwidget <> nil then begin + inc(factivecount); + activecountbefore:= factivecount; + widget:= ffocusedwidget; + while widget <> nil do begin + widget.internaldodeactivate; + if factivecount <> activecountbefore then begin + exit; + end; + widget:= widget.fparentwidget; + end; + end + else begin + fownerwidget.internaldodeactivate; + end; +end; + +procedure twindow.lockactivate; +begin + noactivewidget; + include(fstate,tws_activatelocked); +end; + +procedure twindow.unlockactivate; +begin + exclude(fstate,tws_activatelocked); +end; + +procedure twindow.deactivate; +var + activecountbefore: longword; + widget1: twidget; +begin + if appinst.ffocuslockwindow = self then begin + appinst.ffocuslockwindow:= nil; + end; + if ws_active in fownerwidget.fwidgetstate then begin + noactivewidget; + if appinst.factivewindow = self then begin + inc(factivecount); + activecountbefore:= factivecount; + if not (tws_activating in fstate) then begin + appinst.fonwindowactivechangelist.dowindowchange(appinst.factivewindow,nil); + end; + if factivecount = activecountbefore then begin + if fownerwidget.canassistive() then begin + assistiveserver.dowindowdeactivated(self.fownerwidget.getiassistiveclient()); + end; + widget1:= nil; + if appinst.factivewindow <> nil then begin + widget1:= appinst.factivewindow.focusedwidget; + end; + try + if not (tws_activating in fstate) then begin + appinst.fonwidgetactivechangelist.dowidgetchange(widget1,nil); + end; + finally + if factivecount = activecountbefore then begin + appinst.factivewindow:= nil; + gui_unsetimefocus(fwindow); + end; + end; + end; + end; + end + else begin + if appinst.factivewindow = self then begin + appinst.factivewindow:= nil; //should never happen + end; + end; +end; + +function twindow.deactivateintermediate: boolean; +begin + appinst.finactivewindow:= self; + try + deactivate; + finally + if appinst.factivewindow = self then begin + if appinst.finactivewindow = self then begin + appinst.finactivewindow:= nil; + end; + result:= false; + end + else begin + result:= true; + end; + end; +end; + +procedure twindow.reactivate(const force: boolean = false); //clears appinst.finactivewindow +begin + appinst.finactivewindow:= nil; + activate(force); + include(appinst.fstate,aps_needsupdatewindowstack); +end; + +procedure twindow.hide(windowevent: boolean); +var + int1,int2: integer; + window1: twindow; + bo1: boolean; + mini1: boolean; + mydesktop: integer; +begin + releasemouse; + fstate:= fstate - [tws_posvalid,tws_sizevalid,tws_windowshowpending]; +{$ifdef mse_debugconfigure} + if windowevent then begin + debugwindow('*hide windowevent ',fwindow.id); + end + else begin + debugwindow('*hide no windowevent ',fwindow.id); + end; +{$endif} + if not(ws_visible in fownerwidget.fwidgetstate) then begin + mini1:= windowpos = wp_minimized; + if not mini1 then begin + exclude(fstate,tws_modalfor); + end; + if fwindow.id <> 0 then begin + if tws_windowvisible in fstate then begin + exclude(fstate,tws_transientforminimized); + if not windowevent or (appinst.factivewindow = self) then begin + endmodal; + end; + if (fsyscontainer <> sywi_none) or (fcontainer <> 0) then begin + exclude(fstate,tws_windowvisible); + if not windowevent then begin + if (fsyscontainer <> sywi_none) then begin + gui_hidesysdock(fwindow); + end + else begin + gui_hidewindow(fwindow.id); + end; + end; + end + else begin + if (application.fmainwindow = self) and not appinst.terminated then begin + mydesktop:= gui_getwindowdesktop(fwindow.id); + bo1:= gui_grouphideminimizedwindows; + application.sortzorder; + with appinst do begin + setlength(fgroupzorder,length(fwindows)); + int2:= 0; + for int1:= 0 to high(fwindows) do begin + with fwindows[int1] do begin + if (tws_windowvisible in fstate) and + (gui_getwindowdesktop(fwindow.id) = mydesktop) then begin + //don't touch invisible windows or other desktops + fgroupzorder[int2]:= fwindows[int1]; + inc(int2); + end; + end; + end; + if int2 = 1 then begin + fgroupzorder:= nil; //only me + end + else begin + setlength(fgroupzorder,int2); + end; + end; + + fstate:= fstate - [tws_windowvisible,tws_groupmaximized]; + include(fstate,tws_grouphidden); + include(fstate,tws_groupminimized); + if fwindowposbefore = wp_maximized then begin + include(fstate,tws_groupmaximized); + end; + appinst.flockupdatewindowstack:= self; + //lock z-order manipulation until show + + for int1:= 0 to high(appinst.fwindows) do begin + window1:= appinst.fwindows[int1]; + {$ifdef mse_debugwindowfocus} + if (window1.fwindow.id <> 0) and ((window1 = self) or + gui_windowvisible(window1.fwindow.id)) then begin + if window1 = self then begin + debugwrite('* '); + end; + debugwindow('groupminimized ',window1.fwindow.id); + end; + {$endif} + if (window1 <> self) and (window1.fwindow.id <> 0) and + gui_windowvisible(window1.fwindow.id) and + (gui_getwindowdesktop(window1.fwindow.id) = mydesktop) then begin + with window1 do begin + include(fstate,tws_grouphidden); + if tws_windowvisible in fstate then begin + include(fstate,tws_groupminimized); + end; + if windowpos = wp_maximized then begin + include(fstate,tws_groupmaximized); + end + else begin + exclude(fstate,tws_groupmaximized); + end; + gui_setwindowstate(winid,wsi_minimized,false); + if bo1 or (wo_notaskbar in foptions) then begin + gui_hidewindow(winid); + end; + end; + end; + end; + {$ifdef mse_debugwindowfocus} + for int1:= 0 to high(appinst.fgroupzorder) do begin + debugwriteln(' groupzorder '+appinst.fgroupzorder[int1].fownerwidget.name); + end; + {$endif} + if bo1 then begin + gui_minimizeapplication; + end; + end + else begin + exclude(fstate,tws_windowvisible); + if mini1 and (tws_modalfor in fstate) and (ftransientfor <> nil) and + ftransientfor.visible then begin + ftransientfor.windowpos:= wp_minimized; + include(fstate,tws_transientforminimized); + end; + end; + if not windowevent then begin + exclude(fstate,tws_grouphidden); + gui_hidewindow(fwindow.id); + end; + end; + end; + end; + if not fownerwidget.visible and (fownerwidget.canassistive()) then begin + assistiveserver.dowindowdeactivated(self.fownerwidget.getiassistiveclient()); + end; + end; +end; + +procedure twindow.show(windowevent: boolean); +var + int1: integer; + window1: twindow; + size1: windowsizety; + {bo1,}bo2: boolean; + mydesktop: integer; +begin + if (ow_transientformain in fownerwidget.foptionswidget) and + (ftransientfor = nil) and (application.mainwindow <> nil) and + (application.mainwindow <> self) then begin + checkwindowid(); + settransientfor(application.mainwindow,false); + end; + if windowevent then begin + {$ifdef mse_debugconfigure} + debugwindow('*show windowevent ',fwindow.id); + {$endif} + exclude(fstate,tws_windowshowpending); + checkwindowid; //check position + end; + if (ws_visible in fownerwidget.fwidgetstate) then begin + if not visible then begin + if not windowevent then begin + include(fstate,tws_windowshowpending); + end; + include(fstate,tws_windowvisible); + checkwindowid; + {$ifdef mse_debugwindowfocus} + debugwindow('*show ',fwindow.id); + {$endif} + with appinst do begin + if flockupdatewindowstack = self then begin + flockupdatewindowstack:= nil; //enable z-order handling + fwindowstack:= nil; //remove pending + end; + end; + if (fstate * [tws_transientforminimized,tws_modalfor] = + [tws_transientforminimized,tws_modalfor]) and + (ftransientfor <> nil) then begin +// ftransientfor.fowner.internalshow(ml_none,nil,false,true); + ftransientfor.fownerwidget.internalshow(ml_none, + @ftransientfor.ftransientfor,false,true); + end; + exclude(fstate,tws_transientforminimized); + if not (csdesigning in fownerwidget.ComponentState) then begin + if (fsyscontainer <> sywi_none) or (fcontainer <> 0) then begin + if not windowevent then begin + if (fsyscontainer <> sywi_none) then begin + gui_showsysdock(fwindow); + end + else begin + gui_showwindow(fwindow.id); + end; + end; + end + else begin + include(appinst.fstate,aps_needsupdatewindowstack); + if not windowevent then begin + case fwindowpos of + wp_maximized: begin + size1:= wsi_maximized; + end; + wp_fullscreen: begin + size1:= wsi_fullscreen; + end; + wp_fullscreenvirt: begin + size1:= wsi_fullscreenvirt; + end + else begin + size1:= wsi_normal; + end; + end; + gui_setwindowstate(winid,size1,true); + if (fwindowpos = wp_normal) and not (tws_needsdefaultpos in fstate) and + not (wo_embedded in foptions) then begin + gui_reposwindow(fwindow.id,fnormalwindowrect); + end; + fstate:= fstate-[tws_posvalid,tws_sizevalid]; + //possibly wrong window pos because of KDE bug with staticgravity + end; + exclude(fstate,tws_grouphidden); + exclude(fstate,tws_groupminimized); +// bo1:= gui_grouphideminimizedwindows; + mydesktop:= gui_getwindowdesktop(fwindow.id); + bo2:= false; + if not ispopup and not (tws_modalfor in fstate) and + (fmodallevel = 0) then begin + for int1:= 0 to high(appinst.fwindows) do begin + window1:= appinst.fwindows[int1]; + if window1 <> self then begin + with window1 do begin + if (tws_grouphidden in fstate) and (fwindow.id <> 0) and + (gui_getwindowdesktop(fwindow.id) = mydesktop) then begin + size1:= wsi_minimized; + if tws_groupminimized in fstate then begin + size1:= wsi_normal; + if tws_groupmaximized in fstate then begin + size1:= wsi_maximized; + end; + end; + {$ifdef mse_debugwindowfocus} + debugwindow('groupshow '+ + getenumname(typeinfo(windowsizety),integer(size1))+' ',fwindow.id); + {$endif} + if fwindow.id <> 0 then begin + gui_setwindowstate(fwindow.id,size1,true); + end; + bo2:= true; + exclude(fstate,tws_grouphidden); + exclude(fstate,tws_groupminimized); + end; + end; + end; + end; + end; + if (fwindowposbefore = wp_maximized) and + (windowpos <> wp_maximized) then begin + //necessary for win32 show desktop + gui_setwindowstate(winid,wsi_maximized,true); + end; + if {bo1 and} bo2 then begin + window1:= nil; //compiler warning + activate; + with appinst do begin + if fgroupzorder <> nil then begin +// removeitem(pointerarty(fgroupzorder),window1); +// additem(pointerarty(fgroupzorder),window1); + {$ifdef mse_debuggrouprestore} + debugwriteln('*** grouprestorezorder '+fowner.name); + {$endif} + flockupdatewindowstack:= nil; //enable z-order handling + for int1:= 0 to high(fgroupzorder) do begin + if fgroupzorder[int1] = self then begin + moveitem(pointerarty(fgroupzorder),int1,high(fgroupzorder)); + //probably focused, bring to front + break; + end; + end; + fwindowstack:= nil; + setlength(fwindowstack,high(fgroupzorder)); + window1:= fgroupzorder[0]; //lowest + for int1:= 1 to high(fgroupzorder) do begin + if fgroupzorder[int1] = self then begin + moveitem(pointerarty(fgroupzorder),int1,high(fgroupzorder)); + //probably focused, bring to front + end; + {$ifdef mse_debuggrouprestore} + debugwriteln(' '+inttostr(int1)+' '+window1.fowner.name+' '+ + fgroupzorder[int1].fowner.name); + {$endif} + fwindowstack[int1-1].upper:= fgroupzorder[int1]; + fwindowstack[int1-1].lower:= window1; + window1:= fgroupzorder[int1]; + end; + include(fstate,aps_needsupdatewindowstack); + end; + end; + end; + end; + end; + end; + end; +end; + +function twindow.beginmodal(const showinfo: pshowinfoty): boolean; +var + pt1: pointty; + event1: tmouseevent; + win1: winidty; + focusedwidgetbefore: twidget; + window1: twindow; +begin + fmodalresult:= mr_none; + with appinst do begin + deactivatehint; + if (fmousecapturewidget <> nil) and + not ((showinfo <> nil) and + (fmousecapturewidget = showinfo^.widget)) then begin + fmousecapturewidget.releasemouse; + releasemouse; + end; + if fmodalwindow = nil then begin + fwantedactivewindow:= nil; //init for lowest level + end; + focusedwidgetbefore:= nil; + setlinkedvar(ffocusedwidget,tmsecomponent(focusedwidgetbefore)); + try + appinst.cursorshape:= cr_default; + win1:= fmousewinid; + processleavewindow; + fmousewinid:= win1; + result:= beginmodal(self,showinfo); + if (fmodalwindow = nil) then begin + if not (aps_cancelloop in appinst.fstate) then begin + window1:= fwantedactivewindow; + if (window1 = self) or (window1 = nil) and + (focusedwidgetbefore <> nil) then begin + focusedwidgetbefore.parentfocus; + end; + if appinst.active then begin + if fwantedactivewindow <> nil then begin + fwantedactivewindow:= nil; + window1.activate; + end; + end; + end; + end + else begin + if fmodalwindow = fwantedactivewindow then begin + fwantedactivewindow:= nil; + end; + if appinst.active and not (aps_cancelloop in appinst.fstate) then begin + fmodalwindow.activate; + end; + exclude(fmodalwindow.fstate,tws_focusoutpending); + end; + finally + setlinkedvar(nil,tmsecomponent(focusedwidgetbefore)); + end; + if appinst.modallevel = 1 then begin + exclude(appinst.fstate,aps_cancelloop); + end; + if (factivewindow <> nil) and not factivewindow.fownerwidget.releasing then begin + pt1:= mouse.pos; + if pointinrect(pt1,factivewindow.fownerwidget.fwidgetrect) then begin + event1:= tmouseevent.create(factivewindow.winid,false,mb_none,mw_none, + subpoint(pt1,factivewindow.fownerwidget.fwidgetrect.pos), + appinst.lastshiftstate,0,false); + try + appinst.processmouseevent(event1); //simulate mousemove + finally + event1.free1; + end; + end; + end; + end; +end; + +function twindow.beginmodal: boolean; //true if destroyed +begin + result:= beginmodal(nil); +end; + +procedure twindow.endmodal; +begin + appinst.endmodal(self); +end; + +procedure twindow.poschanged; +begin + exclude(fstate,tws_posvalid); + if fobjectlinker <> nil then begin + fobjectlinker.sendevent(oe_changed); + end; +end; + +procedure twindow.sizechanged; +begin + exclude(fstate,tws_sizevalid); + tcanvas1(fcanvas).updatesize(fownerwidget.fwidgetrect.size); + tcanvas1(fasynccanvas).updatesize(fownerwidget.fwidgetrect.size); + if fobjectlinker <> nil then begin + fobjectlinker.sendevent(oe_changed); + end; +end; + +procedure twindow.wmconfigured(const arect: rectty; const aorigin: pointty); +const + maxsizeerrorcount = 4; +var + rect1: rectty; +begin +{$ifdef mse_debugconfigure} + debugwindow('*wmconfigured '+ + inttostr(aorigin.x)+' '+inttostr(aorigin.y)+'|'+ + inttostr(arect.x)+' '+inttostr(arect.y)+ + ' '+inttostr(arect.cx)+' '+inttostr(arect.cy)+' ',fwindow.id); + +{$endif} + if (tws_windowshowpending in fstate) and visible and + gui_windowvisible(fwindow.id) then begin + exclude(fstate,tws_windowshowpending); + end; + rect1:= arect; + if not (wo_embedded in foptions) then begin + addpoint1(rect1.pos,aorigin); + end; + if not (wo_embedded in foptions) and (not visible or + (tws_windowshowpending in fstate)) then begin + //do not accept changes by hiding window (kwin bugs) + if not rectisequal(fownerwidget.fwidgetrect,rect1) then begin + fstate:= fstate - [tws_posvalid,tws_sizevalid]; + end; + end + else begin + if (fstate*[tws_posvalid,tws_sizevalid] <> [tws_posvalid,tws_sizevalid]) and + (windowpos <> wp_maximized) and not (wo_embedded in foptions) then begin + checkwindow(false); + end + else begin + // if tws_needsdefaultpos in fstate then begin + // fnormalwindowrect:= fowner.fwidgetrect; + // end; + fstate:= (fstate + [tws_posvalid,tws_sizevalid]) - [tws_needsdefaultpos]; + if not rectisequal(rect1,fownerwidget.fwidgetrect) then begin + if fsizeerrorcount < maxsizeerrorcount then begin + fownerwidget.checkwidgetsize(rect1.size); + end; + fownerwidget.internalsetwidgetrect(rect1,true); + if pointisequal(rect1.pos,fownerwidget.fwidgetrect.pos) then begin + include(fstate,tws_posvalid); + end; + if sizeisequal(arect.size,fownerwidget.fwidgetrect.size) then begin + include(fstate,tws_sizevalid); + fsizeerrorcount:= 0; + end + else begin + if fsizeerrorcount < maxsizeerrorcount then begin + inc(fsizeerrorcount); + gui_reposwindow(fwindow.id,rect1); + end; + end; + end; + fwindowposbefore:= windowpos; + if not (fwindowposbefore in [wp_minimized]+windowmaximizedstates) then begin + fnormalwindowrect:= fownerwidget.fwidgetrect; + end; + end; + end; +end; + +function twindow.internalupdate: boolean; //false if nothing is painted +var + bo1: boolean; + bmp: tbitmap; + rect1: rectty; + po1: pointty; + reg1: regionty; +begin + result:= false; + if (ws_visible in fownerwidget.fwidgetstate) and (fupdateregion.region <> 0) then begin + checkwindow(false); //ev. reposition window + fcanvas.reset; + fcanvas.clipregion:= fupdateregion.region; //canvas owns the region + { + bo1:= appinst.caret.islinkedto(fcanvas) and + testintersectrect(fcanvas.clipbox,appinst.caret.rootcliprect); + } + bo1:= false; + if appinst.caret.islinkedto(fcanvas) and appinst.fcaret.active and + testintersectrect(fcanvas.clipbox,appinst.caret.rootcliprect) then begin + reg1:= fcanvas.copyclipregion; + fcanvas.regintersectrect(reg1,appinst.caret.rootcliprect); + bo1:= not fcanvas.regionisempty(reg1); + fcanvas.destroyregion(reg1); + if bo1 then begin + tcaret1(appinst.fcaret).remove; + end; + end; + include(fstate,tws_painting); + if flushgdi then begin + try + fupdateregion.region:= 0; + result:= true; + fownerwidget.paint(fcanvas); + finally + if bo1 then begin + tcaret1(appinst.fcaret).restore; + end; + fcanvas.endpaint; + end; + end + else begin + bmp:= tbitmap.create(bmk_rgb,fgdi); + try + if intersectrect(fcanvas.clipbox, + makerect(nullpoint,fownerwidget.widgetrect.size),rect1) then begin + bmp.size:= rect1.size; + bmp.canvas.clipregion:= bmp.canvas.createregion(fupdateregion.region); + po1.x:= -rect1.x; + po1.y:= -rect1.y; + tcanvas1(bmp.canvas).setcliporigin(po1); + bmp.canvas.origin:= nullpoint; + fupdateregion.region:= 0; + result:= true; + fownerwidget.paint(bmp.canvas); + bmp.paint(fcanvas,rect1); + end + else begin + fupdateregion.region:= 0; + end; + finally + bmp.Free; + if bo1 then begin + tcaret1(appinst.fcaret).restore; + end; + end; + end; + exclude(fstate,tws_painting); + end; +end; + +procedure twindow.mouseparked; +var + info: moeventinfoty; +begin + info.mouse:= appinst.fmouseparkeventinfo; + info.mouse.eventkind:= ek_mousepark; + exclude(info.mouse.eventstate,es_processed); + dispatchmouseevent(info,appinst.fmousecapturewidget); +end; + +procedure twindow.checkmousewidget(const info: mouseeventinfoty; + var capture: twidget); +begin + if capture = nil then begin + capture:= fownerwidget.mouseeventwidget(info); + if (fmodalwidget <> nil) and + not fmodalwidget.checkdescendent(capture) then begin + capture:= fmodalwidget; + end; + if (capture = nil) and (tws_grab in fstate) then begin + capture:= fmodalwidget; + if capture = nil then begin + capture:= fownerwidget; + end; + end; + end; + appinst.setmousewidget(capture); +end; + +procedure twindow.dispatchmouseevent(var info: moeventinfoty; capture: twidget); +var + posbefore: pointty; + mousecapturewidgetbefore: twidget; + int1: integer; + po1: peventaty; + self1: tlinkedobject; +begin + if not (es_designcall in info.mouse.eventstate) then begin + //no "inherited" call from designmouseevent + if info.mouse.eventkind = ek_mousewheel then begin + capture:= fownerwidget.mouseeventwidget(info.mouse); + if (capture = nil) and (ftransientfor <> nil) then begin + include(info.mouse.eventstate,es_transientfor); + subpoint1(info.mouse.pos,subpoint( + ftransientfor.fownerwidget.pos,fownerwidget.pos)); + ftransientfor.dispatchmouseevent(info,capture); + exit; + end; + end + else begin + checkmousewidget(info.mouse,capture); + end; + end; + if capture <> nil then begin + if not (es_designcall in info.mouse.eventstate) and + capture.isdesignwidget() then begin + include(info.mouse.eventstate,es_designcall); + capture.designmouseevent(info,capture); + exclude(info.mouse.eventstate,es_designcall); + if es_processed in info.mouse.eventstate then begin + exit; + end; + end; + mousecapturewidgetbefore:= appinst.fmousecapturewidget; + self1:= nil; + setlinkedvar(self,self1); //for destroy check + try + with capture do begin +// absposbefore:= info.mouse.pos; + subpoint1(info.mouse.pos,rootpos); + posbefore:= info.mouse.pos; + appinst.fmousewidgetpos:= posbefore; + appinst.fdelayedmouseshift:= nullpoint; + if info.mouse.eventkind = ek_mousewheel then begin + mousewheelevent(info.wheel); + end + else begin + mousepreview(capture,info.mouse); + if self1 = nil then begin + exit; + end; + if not (es_processed in info.mouse.eventstate) then begin + if (info.mouse.eventkind = ek_buttonpress) and + (tws_buttonendmodal in fstate) and + (fmodalwidget = capture) then begin + endmodal; + exit; + end; + mouseevent(info.mouse); + if self1 = nil then begin + exit; + end; + end; + if (info.mouse.eventkind = ek_buttonpress) and ispopup and + self.fownerwidget.visible and + (ow_mousefocus in self.fownerwidget.foptionswidget) and + not (csdestroying in self.fownerwidget.componentstate) and + not (acs_releasing in self.fownerwidget.factstate) then begin + activate; //possibly not done by windowmanager + end; + end; + if self1 = nil then begin + exit; + end; + posbefore:= subpoint(info.mouse.pos,posbefore); + addpoint1(posbefore,appinst.fdelayedmouseshift); + if (posbefore.x <> 0) or (posbefore.y <> 0) then begin + gui_flushgdi; + with appinst do begin + getevents; + po1:= peventaty(eventlist.datapo); + for int1:= 0 to eventlist.count -1 do begin + if (po1^[int1] <> nil) and (po1^[int1].kind = ek_mousemove) then begin + freeandnil(po1^[int1]); //remove invalid events + end; + end; + mouse.move(posbefore); + end; + end; + end; + with info.mouse do begin + if (eventkind = ek_buttonrelease) and + (appinst.fmousecapturewidget = nil) and + (mousecapturewidgetbefore <> nil) then begin + exclude(eventstate,es_processed); + eventkind:= ek_mousemove; + pos:= translatewidgetpoint(application.mouse.pos,nil,fownerwidget); +// pos:= addpoint(absposbefore,posbefore); + dispatchmouseevent(info,nil); //immediate mouseenter + eventkind:= ek_buttonrelease; + end; + end; + finally + if self1 <> nil then begin + setlinkedvar(nil,self1); + end; + end; + end; +end; + +procedure twindow.dispatchkeyevent(const eventkind: eventkindty; + var info: keyeventinfoty); +var + widget1: twidget; +begin + if appinst.fkeyboardcapturewidget <> nil then begin + widget1:= appinst.fkeyboardcapturewidget; + end + else begin + widget1:= ffocusedwidget; + end; + if widget1 <> nil then begin + if widget1.isdesignwidget() then begin + widget1.designkeyevent(eventkind,info); + if es_processed in info.eventstate then begin + exit; + end; + end; + case eventkind of + ek_keypress: widget1.internalkeydown(info); + ek_keyrelease: widget1.dokeyup(info); + end; + end + else begin + if eventkind = ek_keypress then begin + include(info.eventstate,es_preview); + try + doshortcut(info,fownerwidget); + finally + exclude(info.eventstate,es_preview); + end; + doshortcut(info,fownerwidget); + end; + end; +end; + +procedure twindow.setfocusedwidget(const widget: twidget); +var + focuscountbefore: longword; + focusedwidgetbefore: twidget; + widget1: twidget; + widgetar: widgetarty; + int1,int2,int3: integer; + bo1: boolean; + ass1,ass2: iassistiveclient; +begin + widgetar:= nil; //compiler warning + if (ffocusedwidget <> widget) and ((fmodalwidget = nil) or (widget = nil) or + fmodalwidget.checkdescendent(widget)) then begin + if widget <> nil then begin + inc(ffocusing); + end; + try + inc(ffocuscount); + focuscountbefore:= ffocuscount; + focusedwidgetbefore:= nil; + setlinkedvar(ffocusedwidget,tmsecomponent(focusedwidgetbefore)); + widget1:= ffocusedwidget; + if widget1 <> nil then begin + if not (csdestroying in widget1.componentstate) then begin + bo1:= tws_candefocus in fstate; + try + include(fstate,tws_candefocus); + if not widget1.canclose(widget) then begin + exit; + end; + finally + if not bo1 then begin + exclude(fstate,tws_candefocus); + end; + end; + if (ffocuscount <> focuscountbefore) then begin + exit; + end; + ffocusedwidget:= nil; + widget1.internaldodefocus; + if ffocuscount <> focuscountbefore then begin + exit; + end; + end + else begin + ffocusedwidget:= nil; + end; + while (widget1 <> nil) and (widget1 <> widget) and + not widget1.checkdescendent(widget) do begin + fenteredwidget:= widget1.fparentwidget; + if not (csdestroying in widget1.componentstate) then begin + widget1.internaldodeactivate; + if ffocuscount <> focuscountbefore then begin + exit; + end; + widget1.internaldoexit; + if ffocuscount <> focuscountbefore then begin + exit; + end; + end; + widget1:= fenteredwidget; + end; + end; + if (widget <> nil) and not widget.canfocus then begin + exit; + end; + ffocusedwidget:= widget; + if widget <> nil then begin + widgetar:= widget.getrootwidgetpath; //new focus + int2:= length(widgetar); + int3:= int2; + bo1:= appinst.factivewindow = self; + if widget1 <> nil then begin + if widget1.checkancestor(fenteredwidget) then begin + widget1:= fenteredwidget; + end; + for int1:= 0 to high(widgetar) do begin + if widgetar[int1] = widget1 then begin + int2:= int1; //common ancestor + break; + end; + end; + if bo1 then begin + int3:= length(widgetar); + for int1:= int2 to high(widgetar) do begin + if widgetar[int1].active then begin + int3:= int1; + break; + end; + end; + end; + end; + for int1:= int3-1 downto 0 do begin + if int1 < int2 then begin + fenteredwidget:= widgetar[int1]; + fenteredwidget.internaldoenter; + if ffocuscount <> focuscountbefore then begin + exit; + end; + if int1 = 0 then begin + widgetar[int1].internaldofocus(); + if ffocuscount <> focuscountbefore then begin + exit; + end; + end; + end; + if bo1 then begin + widgetar[int1].internaldoactivate(); + end; + if ffocuscount <> focuscountbefore then begin + exit; + end; + end; +// ffocusedwidget.internaldofocus; + end + else begin + fenteredwidget:= nil; + end; + if fownerwidget.canassistive() then begin + ass1:= nil; + if focusedwidgetbefore <> nil then begin + ass1:= focusedwidgetbefore.getiassistiveclient(); + end; + ass2:= nil; + if focusedwidget <> nil then begin + ass2:= focusedwidget.getiassistiveclient(); + end; + assistiveserver.dofocuschanged(fownerwidget.getiassistiveclient(), + ass1,ass2); + end; + fownerwidget.dofocuschanged(focusedwidgetbefore,ffocusedwidget); + if (appinst.factivewindow = self) and + (focuscount = focuscountbefore) then begin + appinst.fonwidgetactivechangelist.dowidgetchange( + focusedwidgetbefore,ffocusedwidget); + end; + finally + if widget <> nil then begin + dec(ffocusing); + end; + setlinkedvar(nil,tmsecomponent(focusedwidgetbefore)); + end; + end; +end; + +procedure twindow.invalidaterect(const arect: rectty; + const sender: twidget = nil); +var + rect1: rectty; +begin + if (arect.cx > 0) or (arect.cy > 0) then begin + rect1:= intersectrect(arect,mr(nullpoint,fownerwidget.fwidgetrect.size)); + if (sender <> nil) and (sender.fparentwidget <> nil) then begin + rect1:= intersectrect(rect1,moverect(sender.fparentwidget.paintrect, + sender.fparentwidget.rootpos)); + end; + if fupdateregion.region = 0 then begin + fupdateregion:= createregion(rect1,fgdi); + end + else begin + regaddrect(fupdateregion,rect1); + end; + if appinst <> nil then begin + appinst.invalidated; + end; + end; +end; + +procedure twindow.doshortcut(var info: keyeventinfoty; const sender: twidget); +begin + if not (es_broadcast in info.eventstate) then begin + if not (es_processed in info.eventstate) then begin + if fmodallevel > 0 then begin + include(info.eventstate,es_modal); + end; + try + include(info.eventstate,es_local); + try + appinst.fonshortcutlist.dokeyevent(sender,info); + finally + exclude(info.eventstate,es_local); + end; + if not (es_processed in info.eventstate) and + not (tws_localshortcuts in fstate) then begin + appinst.checkshortcut(self,sender,info); + end; + finally + exclude(info.eventstate,es_modal); + end; + end; + end + else begin + if tws_globalshortcuts in fstate then begin + fcaller:= nil; + fownerwidget.doshortcut(info,nil); + end; + end; +end; + +procedure twindow.gcneeded(const sender: tcanvas); +begin + createwindow; +end; +{ +function twindow.getmonochrome: boolean; +begin + result:= false; +end; +} +function twindow.getkind: bitmapkindty; +begin + result:= bmk_rgb; +end; + +procedure twindow.update; +var + int1: integer; + event: twindowrectevent; +begin + if appinst <> nil then begin + if appinst.ismainthread() then begin //avoid possible deadlock in getevents() + gui_flushgdi; + appinst.getevents; + for int1:= 0 to appinst.eventlist.count - 1 do begin + event:= twindowrectevent(appinst.eventlist[int1]); + if (event <> nil) and (event.kind = ek_expose) and + (event.fwinid = fwindow.id) then begin + invalidaterect(event.frect); + appinst.eventlist[int1]:= nil; + event.free1; + end; + end; + end; + internalupdate; + gui_flushgdi; + end; +end; + +procedure twindow.movewindowrect(const dist: pointty; const rect: rectty); +begin + tcanvas1(fcanvas).movewindowrect(dist,rect); +// gui_movewindowrect(fwindow.id,dist,rect); +end; + +function twindow.getsize: sizety; +begin + result:= fownerwidget.getsize; +end; + +function twindow.close: boolean; +begin + if fmodalresult = mr_none then begin + fmodalresult:= mr_windowclosed; + end; + fownerwidget.beforeclosequery(fmodalresult); + result:= (fmodalresult <> mr_none) and fownerwidget.canparentclose(nil); + if result then begin + deactivate; + fownerwidget.hide; + destroywindow; + end + else begin + fmodalresult:= mr_none; + end; +end; + +procedure twindow.bringtofront(); +var + int1: integer; +begin +{$ifdef mse_debugzorder} + debugwriteln('****bringtofront**** "'+fownerwidget.name+'"'); +{$endif} + with appinst do begin + for int1:= high(fwindowstack) downto 0 do begin + if fwindowstack[int1].lower = self then begin + deleteitem(fwindowstack,typeinfo(windowstackinfoarty),int1); + end; + end; + gui_raisewindow(winid,wo_popup in self.foptions); + include(fstate,aps_needsupdatewindowstack); + end; +end; + +procedure twindow.sendtoback(); +var + int1: integer; +begin +{$ifdef mse_debugzorder} + debugwriteln('****sendtoback**** "'+fownerwidget.name+'"'); +{$endif} + with appinst do begin + for int1:= high(fwindowstack) downto 0 do begin + if fwindowstack[int1].upper = self then begin + deleteitem(fwindowstack,typeinfo(windowstackinfoarty),int1); + end; + end; + gui_lowerwindow(winid); + include(fstate,aps_needsupdatewindowstack); + end; +end; + +procedure twindow.bringtofrontlocal; +begin +{$ifdef mse_debugzorder} + debugwriteln('****bringtofrontlocal**** "'+fownerwidget.name+'"'); +{$endif} + include(fstate,tws_raise); + exclude(fstate,tws_lower); + include(appinst.fstate,aps_needsupdatewindowstack); +end; + +procedure twindow.sendtobacklocal; +begin +{$ifdef mse_debugzorder} + debugwriteln('****sendtobacklocal**** "'+fownerwidget.name+'"'); +{$endif} + include(fstate,tws_lower); + exclude(fstate,tws_raise); + include(appinst.fstate,aps_needsupdatewindowstack); +end; + +procedure twindow.stackunder(const predecessor: twindow); +begin + if (predecessor <> self) then begin + appinst.stackunder(self,predecessor); + include(appinst.fstate,aps_needsupdatewindowstack); + end; +end; + +procedure twindow.stackover(const predecessor: twindow); +var + ar1: windowarty; +begin + ar1:= nil; //compiler warning + if predecessor = nil then begin + appinst.sortzorder; + ar1:= appinst.windowar; + if high(ar1) >= 0 then begin + stackunder(ar1[0]); + end; + end + else begin + if (predecessor <> self) and (predecessor <> nil) then begin + appinst.stackover(self,predecessor); + include(appinst.fstate,aps_needsupdatewindowstack); + end; + end; +end; + +function twindow.stackedover(const avisible: boolean = false): twindow; //nil if top +var + ar1: windowarty; + int1,int2: integer; +begin + appinst.sortzorder; + ar1:= appinst.windowar; + result:= nil; + int2:= -1; + for int1:= high(ar1) downto 1 do begin + if ar1[int1] = self then begin + int2:= int1-1; + break; + end; + end; + if int2 >= 0 then begin + if avisible then begin + for int1:= int2 downto 0 do begin + if ar1[int1].visible then begin + result:= ar1[int1]; + break; + end; + end; + end + else begin + result:= ar1[int2]; + end; + end; +end; + +function twindow.stackedunder(const avisible: boolean = false): twindow; + //nil if bottom +var + ar1: windowarty; + int1,int2: integer; +begin + appinst.sortzorder; + ar1:= appinst.windowar; + result:= nil; + int2:= -1; + for int1:= 0 to high(ar1)-1 do begin + if ar1[int1] = self then begin + int2:= int1+1; + break; + end; + end; + if int2 >= 0 then begin + if avisible then begin + for int1:= int2 to high(ar1) do begin + if ar1[int1].visible then begin + result:= ar1[int1]; + break; + end; + end; + end + else begin + result:= ar1[int2]; + end; + end; +end; + +function twindow.hastransientfor: boolean; +begin + result:= ftransientforcount > 0; +end; + +function twindow.istransientfor(const base: twindow): boolean; +var + w1: twindow; +begin + result:= ftransientfor <> nil; + if result and (base <> nil) then begin + w1:= ftransientfor; + while w1 <> nil do begin + if w1 = base then begin + exit; + end; + w1:= w1.ftransientfor; + end; + result:= false; + end; +end; + +function twindow.capturemouse: boolean; +begin + result:= not (tws_grab in fstate); + if appinst.grabpointer(winid) then begin + include(fstate,tws_grab); + end; +end; + +procedure twindow.releasemouse; +begin + if tws_grab in fstate then begin + exclude(fstate,tws_grab); + appinst.ungrabpointer; + end; +end; + +function twindow.mousecaptured: boolean; +begin + result:= tws_grab in fstate; +end; + +procedure twindow.checkrecursivetransientfor(const value: twindow); +var + window1: twindow; +begin + window1:= value; + while window1 <> nil do begin + if window1 = self then begin + guierror(gue_recursivetransientfor); + end; + window1:= window1.ftransientfor; + end; +end; + +procedure twindow.settransientfor(const Value: twindow; + const windowevent: boolean); +begin + if not windowevent then begin + if value = nil then begin + exclude(fstate,tws_modalfor); + end; + if ftransientfor <> value then begin + checkrecursivetransientfor(value); + if ftransientfor <> nil then begin + dec(ftransientfor.ftransientforcount); + end; + setlinkedvar(value,tlinkedobject(ftransientfor)); + if ftransientfor <> nil then begin + inc(ftransientfor.ftransientforcount); + end; + include(appinst.fstate,aps_needsupdatewindowstack); + if fwindow.id <> 0 then begin + if value <> nil then begin + gui_settransientfor(fwindow,value.winid); + end + else begin + gui_settransientfor(fwindow,0); + end; + end; + end; + end; +end; + +function twindow.winid: winidty; +begin + checkwindowid; + result:= fwindow.id; +end; + +procedure twindow.hidden; +begin + if tws_windowvisible in fstate then begin + fownerwidget.internalhide(true); + end; +end; + +procedure twindow.showed; +var + wi1: twindow; +begin + exclude(fstate,tws_windowshowpending); + if not (tws_windowvisible in fstate) then begin + wi1:= nil; + fownerwidget.internalshow(ml_none,@wi1,true,true); + end; +end; + +procedure twindow.activated; +begin + internalactivate(true); +end; + +procedure twindow.deactivated; +begin + deactivate; +end; + +function twindow.canactivate: boolean; +begin + result:= (appinst <> nil) and (appinst.fmodalwindow = nil) or + (appinst.fmodalwindow = self); +end; + +procedure twindow.activate(const force: boolean = false); +begin + if fownerwidget.visible and (force or not active) and + not (tws_focusoutpending in fstate)then begin + internalactivate(false); + end; +end; + +function twindow.active: boolean; +begin + result:= appinst.factivewindow = self; +end; + +procedure twindow.setcaption(const avalue: msestring); +begin + fcaption:= avalue; + if fwindow.id <> 0 then begin + gui_setwindowcaption(fwindow.id,fcaption); + end; +end; + +procedure twindow.widgetdestroyed(widget: twidget); +var + widget1: twidget; +begin + if fmodalwidget = widget then begin + fmodalwidget:= nil; + end; + if ffocusedwidget = widget then begin + widget1:= widget; + repeat + widget1:= widget1.parentwidget; + until (widget1 = nil) or widget1.canfocus; + setfocusedwidget(widget1); + end; +end; + +function twindow.state: windowstatesty; +begin + result:= fstate; +end; + +procedure twindow.registermovenotification(sender: iobjectlink); +begin + getobjectlinker.link(iobjectlink(self),sender); +end; + +procedure twindow.unregistermovenotification(sender: iobjectlink); +begin + if (self <> nil) and (fobjectlinker <> nil) then begin + fobjectlinker.unlink(iobjectlink(self),sender); + end; +end; + +function twindow.close(const amodalresult: modalresultty): boolean; + //true if ok +begin + fmodalresult:= amodalresult; + result:= false; + if (amodalresult <> mr_none) {and (tws_modal in fstate)} then begin + result:= close(); + end; +end; + +procedure twindow.setmodalresult(const Value: modalresultty); +begin + fmodalresult:= Value; + if (value <> mr_none) {and (tws_modal in fstate)} then begin + close(); + end; +end; + +function twindow.candefocus: boolean; +var + b1: boolean; +begin + b1:= tws_candefocus in fstate; + include(fstate,tws_candefocus); + try + result:= (ffocusedwidget = nil) or ffocusedwidget.canclose(nil); + finally; + if not b1 then begin + exclude(fstate,tws_candefocus); + end; + end; +end; + +procedure twindow.nofocus; +begin + setfocusedwidget(nil); +end; + +function twindow.getglobalshortcuts: boolean; +begin + result:= tws_globalshortcuts in fstate; +end; + +procedure twindow.setglobalshortcuts(const Value: boolean); +begin + updatebit({$ifdef FPC}longword{$else} + longword{$endif}(fstate),ord(tws_globalshortcuts),value); +end; + +function twindow.getlocalshortcuts: boolean; +begin + result:= tws_localshortcuts in fstate; +end; + +procedure twindow.setlocalshortcuts(const Value: boolean); +begin + updatebit({$ifdef FPC}longword{$else}longword{$endif}(fstate), + ord(tws_localshortcuts),value); +end; + +function twindow.visible: boolean; +begin + result:= fownerwidget.visible and (tws_windowvisible in fstate) and + (fwindow.id <> 0) and (gui_getwindowsize(fwindow.id) <> wsi_minimized); +end; + +function twindow.normalwindowrect: rectty; +begin + result:= fnormalwindowrect; +end; + +function twindow.getbuttonendmodal: boolean; +begin + result:= tws_buttonendmodal in fstate; +end; + +procedure twindow.setbuttonendmodal(const value: boolean); +begin + if value then begin + include(fstate,tws_buttonendmodal); + end + else begin + exclude(fstate,tws_buttonendmodal); + end; +end; + +procedure twindow.setzorder(const value: integer); +begin + if value = 0 then begin //!!!!todo + gui_lowerwindow(winid); + end + else begin + gui_raisewindow(winid); + end; +end; + +function twindow.getwindowsize: windowsizety; +begin + result:= gui_getwindowsize(winid); +end; + +procedure twindow.setwindowsize(const value: windowsizety); +begin + gui_setwindowstate(winid,value,true); +end; + +function twindow.getwindowpos: windowposty; +var + asize: windowsizety; +begin + if fwindow.id = 0 then begin + result:= fwindowpos; + end + else begin + inc(fmoving); + asize:= gui_getwindowsize(winid); + dec(fmoving); + case asize of + wsi_minimized: begin + result:= wp_minimized; + end; + wsi_maximized: begin + result:= wp_maximized; + end; + wsi_fullscreen: begin + result:= wp_fullscreen; + end; + wsi_fullscreenvirt: begin + result:= wp_fullscreenvirt; + end; + else begin //wsi_normal + if fwindowpos in [wp_minimized,wp_screencentered, + wp_transientforcentered,wp_mainwindowcentered] + + windowmaximizedstates then begin + result:= wp_normal; + end + else begin + result:= fwindowpos; + end; + end; + end; + end; +end; + +procedure twindow.setwindowpos(const Value: windowposty); +var + rect1,rect2: rectty; + bo1: boolean; + wpo1: windowposty; + window1: twindow; +begin + wpo1:= getwindowpos; + if wpo1 <> value then begin + bo1:= (tws_windowvisible in fstate) or (wpo1 = wp_minimized); + window1:= nil; + if value in [wp_screencentered, + wp_transientforcentered,wp_mainwindowcentered] then begin + window1:= nil; + if value = wp_mainwindowcentered then begin + window1:= application.mainwindow; + end; + if window1 = nil then begin + window1:= transientfor; + if window1 = nil then begin + window1:= appinst.activewindow; + if window1 = nil then begin + window1:= self; + end; + end; + end; + end; + case value of + wp_screencentered,wp_screencenteredvirt, + wp_transientforcentered,wp_mainwindowcentered: begin + checkwindowid(); + rect1:= fnormalwindowrect; + gui_setwindowstate(winid,wsi_normal,bo1); + case value of + wp_screencenteredvirt: begin + rect2:= appinst.screenrect(nil); + end; + wp_screencentered: begin + rect2:= appinst.workarea(window1); + end; + else begin + rect2:= window1.fownerwidget.widgetrect; + end; + end; + with fownerwidget do begin + rect1.x:= rect2.x + (rect2.cx - rect1.cx) div 2; + rect1.y:= rect2.y + (rect2.cy - rect1.cy) div 2; + widgetrect:= rect1; + end; + end; + wp_minimized: begin + gui_setwindowstate(winid,wsi_minimized,bo1); + end; + wp_maximized: begin + gui_setwindowstate(winid,wsi_maximized,bo1); + end; + wp_fullscreen: begin + gui_setwindowstate(winid,wsi_fullscreen,bo1); + end; + wp_fullscreenvirt: begin + gui_setwindowstate(winid,wsi_fullscreenvirt,bo1); + end + else begin + gui_setwindowstate(winid,wsi_normal,bo1); + end; + end; + end; + fwindowpos:= value; + fwindowposbefore:= fwindowpos; + if (wpo1 in [wp_fullscreen,wp_fullscreenvirt]) and + (value = wp_normal) then begin + gui_reposwindow(fwindow.id,fnormalwindowrect); + //needed for win32 + end; +end; + +function twindow.updaterect: rectty; +begin + result:= fcanvas.regionclipbox(fupdateregion.region); +end; + +function twindow.defaulttransientfor: twindow; +begin + result:= nil; + if appinst.fmodalwindow = nil then begin + if appinst.fwantedactivewindow <> nil then begin + result:= appinst.fwantedactivewindow; + end + else begin + result:= appinst.factivewindow; + end; + end + else begin + result:= appinst.fmodalwindow; + end; + if result = self then begin + result:= nil; + end; +end; + +function twindow.ispopup: boolean; +begin + result:= wo_popup in foptions; +end; + +function twindow.firstfocuswidget(): twidget; +var + w1,w2: twidget; + i1,i2: int32; +begin + result:= fownerwidget; + if result.canfocus then begin + while ow_subfocus in result.optionswidget do begin + w2:= nil; + i2:= bigint; + for i1:= 0 to high(result.fwidgets) do begin + w1:= result.fwidgets[i1]; + if (w1.ftaborder < i2) and w1.canfocus then begin + w2:= w1; + i2:= w1.ftaborder; + end; + end; + if w2 = nil then begin + break; + end; + result:= w2; + end; + end; +end; + +function twindow.lastfocuswidget(): twidget; +var + w1,w2: twidget; + i1,i2: int32; +begin + result:= fownerwidget; + if result.canfocus then begin + while ow_subfocus in result.optionswidget do begin + w2:= nil; + i2:= -1; + for i1:= high(result.fwidgets) downto 0 do begin + w1:= result.fwidgets[i1]; + if (w1.ftaborder > i2) and w1.canfocus then begin + w2:= w1; + i2:= w1.ftaborder; + end; + end; + if w2 = nil then begin + break; + end; + result:= w2; + end; + end; +end; + +procedure twindow.postkeyevent(const akey: keyty; + const ashiftstate: shiftstatesty = []; const release: boolean = false; + const achars: msestring = ''); +begin + application.postevent(tkeyevent.create(winid,release,akey,akey, + ashiftstate,achars,timestamp,true)); +end; + +procedure twindow.beginmoving; +begin + inc(fmoving); +end; + +procedure twindow.endmoving; +begin + dec(fmoving); + if fmoving = 0 then begin + checkwindow(false); + end; +end; + +procedure twindow.registeronscroll(const method: notifyeventty); +begin + fscrollnotifylist.add(tmethod(method)); +end; + +procedure twindow.unregisteronscroll(const method: notifyeventty); +begin + fscrollnotifylist.remove(tmethod(method)); +end; + +function twindow.getdecoratedwidgetrect: rectty; +begin + guierror(gui_getdecoratedwindowrect(winid,result)); +end; + +procedure twindow.setdecoratedwidgetrect(const avalue: rectty); +var + rect1: rectty; +begin + guierror(gui_setdecoratedwindowrect(winid,avalue,rect1)); +end; + +function twindow.getdecoratedpos: pointty; +begin + result:= decoratedwidgetrect.pos; +end; + +procedure twindow.setdecoratedpos(const avalue: pointty); +var + rect1: rectty; +begin + rect1:= decoratedwidgetrect; + rect1.pos:= avalue; + decoratedwidgetrect:= rect1; +end; + +function twindow.getdecoratedsize: sizety; +begin + result:= decoratedwidgetrect.size; +end; + +procedure twindow.setdecoratedsize(const avalue: sizety); +var + rect1: rectty; +begin + rect1:= decoratedwidgetrect; + rect1.size:= avalue; + decoratedwidgetrect:= rect1; +end; + +function twindow.getdecoratedbounds_x: integer; +begin + result:= decoratedwidgetrect.x; +end; + +procedure twindow.setdecoratedbounds_x(const avalue: integer); +var + rect1: rectty; +begin + rect1:= decoratedwidgetrect; + rect1.x:= avalue; + decoratedwidgetrect:= rect1; +end; + +function twindow.getdecoratedbounds_y: integer; +begin + result:= decoratedwidgetrect.y; +end; + +procedure twindow.setdecoratedbounds_y(const avalue: integer); +var + rect1: rectty; +begin + rect1:= decoratedwidgetrect; + rect1.y:= avalue; + decoratedwidgetrect:= rect1; +end; + +function twindow.getdecoratedbounds_cx: integer; +begin + result:= decoratedwidgetrect.cx; +end; + +procedure twindow.setdecoratedbounds_cx(const avalue: integer); +var + rect1: rectty; +begin + rect1:= decoratedwidgetrect; + rect1.cx:= avalue; + decoratedwidgetrect:= rect1; +end; + +function twindow.getdecoratedbounds_cy: integer; +begin + result:= decoratedwidgetrect.cy; +end; + +procedure twindow.setdecoratedbounds_cy(const avalue: integer); +var + rect1: rectty; +begin + rect1:= decoratedwidgetrect; + rect1.cy:= avalue; + decoratedwidgetrect:= rect1; +end; + +procedure twindow.setcontainer(const avalue: winidty); +begin + syscontainer:= sywi_none; + if fcontainer <> 0 then begin + application.unregisteronwiniddestroyed({$ifdef FPC}@{$endif}containerwindestroyed); + end; + fcontainer:= avalue; + if fcontainer <> 0 then begin + application.registeronwiniddestroyed({$ifdef FPC}@{$endif}containerwindestroyed); + try + include(foptions,wo_embedded); + guierror(gui_reparentwindow(winid,fcontainer,fownerwidget.pos)); + except + container:= 0; + raise; + end; + end + else begin + exclude(foptions,wo_embedded); + if (fwindow.id <> 0) and not (tws_destroying in fstate) then begin + guierror(gui_reparentwindow(winid,0,fownerwidget.pos)); + end; + end; +end; + +procedure twindow.containerwindestroyed(const aid: winidty); +begin + if aid = fcontainer then begin + container:= 0; + end; +end; + +procedure twindow.setsyscontainer(const avalue: syswindowty); +begin + if avalue <> fsyscontainer then begin + if (fsyscontainer <> sywi_none) and (fwindow.id <> 0) then begin + {$ifdef mswindows} + gui_docktosyswindow(fwindow,sywi_none); + {$else} + destroywindow(); //above code does not work with newer wm's + {$endif} + fsyscontainer:= sywi_none; + container:= 0; + if not (tws_destroying in fstate) then begin + {$ifndef mswindows} + createwindow(); + {$endif} + if avalue = sywi_none then begin + if fownerwidget.visible then begin + gui_showwindow(winid); + end; + end; + end; + end; + if avalue <> sywi_none then begin + if fwindow.id = 0 then begin + createwindow; + end; + include(foptions,wo_embedded); + guierror(gui_docktosyswindow(fwindow,avalue)); + fsyscontainer:= avalue; + end; + end; +end; + +function twindow.getscreenpos: pointty; +var + rect1: rectty; +begin + if not (wo_embedded in foptions) then begin + result:= fownerwidget.pos; + end + else begin + guierror(gui_getwindowrect(winid,rect1)); + result:= rect1.pos; + end; +end; + +procedure twindow.setscreenpos(const avalue: pointty); +var + pt1: pointty; +begin + if not (wo_embedded in foptions) then begin + fownerwidget.pos:= avalue; + end + else begin + pt1:= screenpos; + pt1.x:= avalue.x - pt1.x + fownerwidget.bounds_x; + pt1.y:= avalue.y - pt1.y + fownerwidget.bounds_y; + fownerwidget.pos:= pt1; + end; +end; + +function twindow.modal: boolean; +begin + result:= fmodallevel > 0; +end; + +function twindow.modalwindowbefore: twindow; +begin + result:= nil; + if fmodalinfopo <> nil then begin + result:= fmodalinfopo^.modalwindowbefore; + end; +end; + +function twindow.getmodalfor: boolean; +begin + result:= tws_modalfor in fstate; +end; + +procedure twindow.setopacity(const avalue: realty); +begin + if fopacity <> avalue then begin + fopacity:= avalue; + if fwindow.id <> 0 then begin + gui_setwindowopacity(fwindow.id,fopacity); + end; + end; +end; + +function twindow.topmodaltransientfor: twindow; +var + int1: integer; + window1,window2: twindow; +begin + result:= nil; + with appinst do begin + window1:= self; + while (window1 <> nil) and window1.hastransientfor do begin + window2:= nil; + for int1:= 0 to high(fwindows) do begin + if fwindows[int1].ftransientfor = window1 then begin + window2:= fwindows[int1]; + if tws_modalfor in window2.fstate then begin + result:= window2; + end; + if window2 = self then begin + window2:= nil; //recursion + end; + break; + end; + end; + window1:= window2; + end; + end; +end; + +function twindow.transientforstackactive: boolean; +var + window1,window2: twindow; +begin + result:= false; + window1:= appinst.activewindow; + window2:= window1; + if (window1 <> nil) and (window1.ftransientfor <> nil) then begin + while window1 <> nil do begin + if window1 = self then begin + result:= true; + break; + end; + window1:= window1.ftransientfor; + end; + end; + if ftransientfor <> nil then begin + window1:= self; + while window1 <> nil do begin + if window1 = window2 then begin + result:= true; + break; + end; + window1:= window1.ftransientfor; + end; + end; +end; + +procedure twindow.getcanvasimage(const bgr: boolean; var aimage: maskedimagety); +begin + //dummy +end; + +procedure twindow.processsysdnd(const event: twindowevent); +var + wi1: twidget; +// obj1: tsysmimedragobject; + info: draginfoty; + bo1: boolean; +begin + if wo_sysdnd in foptions then begin + with tsysdndevent(event) do begin + if fdndkind = dek_leavesysdnd then begin + freeandnil(fsysdragobject); + end + else begin + subpoint1(fpos,fownerwidget.pos); + wi1:= fownerwidget.widgetatpos(fpos,[ws_visible,ws_enabled]); + if (wi1 = nil) and + (fownerwidget.fwidgetstate*[ws_visible,ws_enabled] = + [ws_visible,ws_enabled]) then begin + wi1:= fownerwidget; + end; + if wi1 <> nil then begin + if fsysdragobject = nil then begin + tsysmimedragobject.create(nil,tdragobject(fsysdragobject),nullpoint, + fformats,fformatistext,factions); + end; + with tsysmimedragobject1(fsysdragobject) do begin + if (fformats <> tsysdndevent(event).fformats) or + (fformatistext <> tsysdndevent(event).fformatistext) or + (fformatindex > high(fformats)) then begin + //missed dek_leave + fformats:= tsysdndevent(event).fformats; + fformatistext:= tsysdndevent(event).fformatistext; + fformatindex:= -1; + end; + factions:= tsysdndevent(event).factions; + end; + fillchar(info,sizeof(info),0); + with info do begin + eventkind:= fdndkind; + pos:= translateclientpoint(fpos,owner,wi1); + dragobjectpo:= @fsysdragobject; + end; + try + wi1.dragevent(info); + finally + if fdndkind = dek_drop then begin + gui_sysdnd(sdnda_finished,isysdnd(tsysmimedragobject(fsysdragobject)), + nullrect,bo1); + end + else begin + if info.accept then begin + gui_sysdnd(sdnda_accept,isysdnd(tsysmimedragobject(fsysdragobject)) + ,nullrect,bo1); + end + else begin + gui_sysdnd(sdnda_reject,isysdnd(tsysmimedragobject(fsysdragobject)), + nullrect,bo1); + end; + end; + // obj1.free; + end; + end; + end; + end; + end; +end; + +{ tonkeyeventlist} + +procedure tonkeyeventlist.dokeyevent(const sender: twidget; var info: keyeventinfoty); +begin + factitem:= 0; + while factitem < fcount do begin + if es_processed in info.eventstate then begin + break; + end; + keyeventty(getitempo(factitem)^)(sender,info); + inc(factitem); + end; +end; + +{ tonwidgetchangelist} + +procedure tonwidgetchangelist.dowidgetchange(const oldwidget,newwidget: twidget); +begin + factitem:= 0; + while factitem < fcount do begin + widgetchangeeventty(getitempo(factitem)^)(oldwidget,newwidget); + inc(factitem); + end; +end; + +{ tonwindowchangelist} + +procedure tonwindowchangelist.dowindowchange(const oldwindow,newwindow: twindow); +begin + factitem:= 0; + while factitem < fcount do begin + windowchangeeventty(getitempo(factitem)^)(oldwindow,newwindow); + inc(factitem); + end; +end; + + {tonwindoweventlist} + +procedure tonwindoweventlist.doevent(const awindow: twindow); +begin + factitem:= 0; + while factitem < fcount do begin + windoweventty(getitempo(factitem)^)(awindow); + inc(factitem); + end; +end; + + {tonwinideventlist} + +procedure tonwinideventlist.doevent(const awinid: winidty); +begin + factitem:= 0; + while factitem < fcount do begin + winideventty(getitempo(factitem)^)(awinid); + inc(factitem); + end; +end; + +{ tonapplicationactivechangedlist } + +procedure tonapplicationactivechangedlist.doevent(const activated: boolean); +begin + factitem:= 0; + while factitem < fcount do begin + booleaneventty(getitempo(factitem)^)(activated); + inc(factitem); + end; +end; + +{ tonhelpeventlist } + +procedure tonhelpeventlist.doevent (const sender: tmsecomponent); +var + bo1: boolean; +begin + factitem:= 0; + bo1:= false; + while (factitem < fcount) and not bo1 do begin + helpeventty(getitempo(factitem)^)(sender,bo1); + inc(factitem); + end; +end; + +{ tonsyseventlist } + +procedure tonsyseventlist.doevent(const awindow: winidty; + var aevent: syseventty; var handled: boolean); +//var +// bo1: boolean; +begin + factitem:= 0; + while (factitem < fcount) and not handled do begin + syseventhandlereventty(getitempo(factitem)^)(awindow,aevent,handled); + inc(factitem); + end; +end; + +{ twindowevent } + +constructor twindowevent.create(akind: eventkindty; winid: winidty); +begin + inherited create(akind); + fwinid:= winid; +end; + +{ twindowrectevent } + +constructor twindowrectevent.create(akind: eventkindty; winid: winidty; + const rect: rectty; const aorigin: pointty); +begin + inherited create(akind,winid); + frect:= rect; + forigin:= aorigin; +end; + +{ tmouseevent } + +constructor tmouseevent.create(const winid: winidty; const release: boolean; + const button: mousebuttonty; const wheel: mousewheelty; + const pos: pointty; const shiftstate: shiftstatesty; + atimestamp: longword; const reflected: boolean = false); +var + eventkind1: eventkindty; +begin + if (atimestamp = 0) and (button <> mb_none) then begin + inc(atimestamp); + end; + ftimestamp:= atimestamp; + if wheel = mw_none then begin + if button = mb_none then begin + eventkind1:= ek_mousemove; + end + else begin + if release then begin + eventkind1:= ek_buttonrelease; + end + else begin + eventkind1:= ek_buttonpress; + end; + end; + end + else begin + eventkind1:= ek_mousewheel; + end; + inherited create(eventkind1,winid); + fbutton:= button; + fwheel:= wheel; + fpos:= pos; + fshiftstate:= shiftstate; + freflected:= reflected; +end; + +{ tkeyevent } + +constructor tkeyevent.create(const winid: winidty; const release: boolean; + const key,keynomod: keyty; const shiftstate: shiftstatesty; + const chars: msestring; const atimestamp: longword; + const posted: boolean = false); +var + eventkind1: eventkindty; +begin + if release then begin + eventkind1:= ek_keyrelease; + end + else begin + eventkind1:= ek_keypress; + end; + inherited create(eventkind1,winid); + fkeynomod:= keynomod; + fkey:= key; + fchars:= chars; + fshiftstate:= shiftstate; + ftimestamp:= atimestamp; + fposted:= posted; +end; + +{ tinternalapplication } + +constructor tinternalapplication.create(aowner: tcomponent); +begin + appinst:= self; +// inherited; + fdblclicktime:= defaultdblclicktime; +// inherited; + fonkeypresslist:= tonkeyeventlist.create; + fonshortcutlist:= tonkeyeventlist.create; + fonwidgetactivechangelist:= tonwidgetchangelist.create; + fonwindowactivechangelist:= tonwindowchangelist.create; + fonwindowdestroyedlist:= tonwindoweventlist.create; + fonwiniddestroyedlist:= tonwinideventlist.create; + fonapplicationactivechangedlist:= tonapplicationactivechangedlist.create; + fonhelp:= tonhelpeventlist.create; + fonsyseventlist:= tonsyseventlist.create; +// fwindows:= tpointerlist.create; + fcaret:= tcaret.create; + fmouse:= tmouse.create(imouse(self)); + fhinttimer:= tsimpletimer.create(0,{$ifdef FPC}@{$endif}hinttimer, + false,[to_single]); + fmouseparktimer:= tsimpletimer.create(0,{$ifdef FPC}@{$endif}mouseparktimer, + false,[to_single]); + inherited; +// initialize; +end; + +destructor tinternalapplication.destroy; +begin + destroyforms; + fmouseparktimer.free; + fhinttimer.free; + fhintwidget.free; + freeandnil(fcaret); + fmouse.free; +// deinitialize; + inherited; +// fwindows.free; + fonkeypresslist.free; + fonshortcutlist.free; + fonwidgetactivechangelist.free; + fonwindowactivechangelist.free; + fonwindowdestroyedlist.free; + fonwiniddestroyedlist.free; + fonapplicationactivechangedlist.free; + fonhelp.free; + fonsyseventlist.free; +end; + +procedure tinternalapplication.twindowdestroyed(const sender: twindow); +var + int1: integer; +begin + fonwindowdestroyedlist.doevent(sender); + for int1:= high(fwindowstack) downto 0 do begin + with fwindowstack[int1] do begin + if (lower = sender) or (upper = sender) then begin + deleteitem(fwindowstack,typeinfo(windowstackinfoarty),int1); +// lower:= nil; + end; + end; + end; + for int1:= high(fgroupzorder) downto 0 do begin + if fgroupzorder[int1] = sender then begin + deleteitem(pointerarty(fgroupzorder),int1); + end; + end; + if factivewindow = sender then begin + factivewindow:= nil; + end; + if flastactivewindow = sender then begin + flastactivewindow:= nil; + end; + if finactivewindow = sender then begin + finactivewindow:= nil; + end; + if fwantedactivewindow = sender then begin + fwantedactivewindow:= nil; + end; + if factmousewindow = sender then begin + factmousewindow:= nil; + end; + if fmainwindow = sender then begin + fmainwindow:= nil; + end; + if ffocuslockwindow = sender then begin + ffocuslockwindow:= nil; + end; + if ffocuslocktransientfor = sender then begin + ffocuslockwindow:= nil; + end; + if flockupdatewindowstack = sender then begin + flockupdatewindowstack:= nil; + end; +end; + +function tinternalapplication.getmousewinid: winidty; +begin + result:= fmousewinid; + if (result <> 0) then begin + exit; + end; + if fmousecapturewidget <> nil then begin +// result:= fmousecapturewidget.window.winid; + result:= fmousecapturewidget.window.fwindow.id; + //do not trigger checkwindow, there could be a pending + //configure event + exit; + end; + if activewindow <> nil then begin + result:= activewindow.fwindow.id; + exit; + end; + if (mainwindow <> nil) and (mainwindow.visible) then begin + result:= mainwindow.fwindow.id; + exit; + end; +end; + +procedure tinternalapplication.processexposeevent(event: twindowrectevent); +var + window: twindow; + parentid: winidty; + pt1: pointty; +begin + with event do begin + if findwindow(fwinid,window) then begin + window.invalidaterect(frect); + end + else begin + if not winiddestroyed(fwinid) then begin + parentid:= gui_getparentwindow(fwinid); //embedded or destroyed window + if parentid <> 0 then begin + if findwindow(parentid,window) and + (gui_getwindowpos(fwinid,pt1) = gue_ok) then begin + addpoint1(frect.pos,pt1); + window.invalidaterect(frect); + end; + end; + end; + end; + end; +end; + +procedure tinternalapplication.processshowingevent(event: twindowevent); +var + window: twindow; +begin + if findwindow(event.fwinid,window) then begin + if event.kind = ek_show then begin + if window.windowpos in windowmaximizedstates then begin + window.fstate:= window.fstate + [tws_posvalid,tws_sizevalid]; + //do not override changing to normal state by window manager + end; + window.showed; + end + else begin + window.hidden; + end; + end; +end; + +procedure tinternalapplication.processconfigureevent(event: twindowrectevent); +var + window: twindow; +begin + with event do begin + if findwindow(fwinid,window) then begin + window.wmconfigured(frect,forigin); + end; + end; +end; + +procedure tinternalapplication.processleavewindow; +begin + fmouseparktimer.enabled:= false; + factmousewindow:= nil; + if fmousecapturewidget = nil then begin + setmousewidget(nil); + widgetcursorshape:= cr_default; + fhintedwidget:= nil; +// cursorshape:= cr_default; + end + else begin + if (fclientmousewidget <> nil) and + not (ws_clientmousecaptured in fclientmousewidget.fwidgetstate) then begin + setclientmousewidget(nil,nullpoint); + end; + end; + fmousewinid:= 0; +end; + +procedure tinternalapplication.processwindowcrossingevent(event: twindowevent); +var + window: twindow; +// info: mouseeventinfoty; +begin + if findwindow(event.fwinid,window) then begin + if event.kind = ek_leavewindow then begin + processleavewindow; + end + else begin + fmousewinid:= event.fwinid; + end; + end; +end; + +procedure tinternalapplication.mouseparktimer(const sender: tobject); +begin + if (factmousewindow <> nil) and ((fmodalwindow = nil) or + (fmodalwindow = factmousewindow)) then begin + factmousewindow.mouseparked; + end; +end; + +procedure tinternalapplication.processmouseevent(event: tmouseevent); +var + window,window1: twindow; + info: moeventinfoty; + shift: shiftstatesty; + abspos: pointty; + int1: integer; + bo1: boolean; + widget1: twidget; + pt1: pointty; + hintid1: int32; +begin + try + with event do begin + if findwindow(fwinid,window) then begin + if window.hastransientfor then begin + window1:= window.topmodaltransientfor; + if window1 <> nil then begin + fpos.x:= fpos.x + window.fownerwidget.bounds_x - + window1.fownerwidget.bounds_x; + fpos.y:= fpos.y + window.fownerwidget.bounds_y - + window1.fownerwidget.bounds_y; + window:= window1; + end; + end; + fillchar(info,sizeof(info),0); + with info.mouse do begin + timestamp:= ftimestamp; + serial:= application.getserial(); + if freflected then begin + include(eventstate,es_reflected); + end; + if kind = ek_enterwindow then begin + eventkind:= ek_mousemove; + end + else begin + eventkind:= kind; + end; + shift:= []; + if kind = ek_mousewheel then begin + fmousewheeleventinfo:= @info; + info.wheel.wheel:= fwheel; + calcmousewheeldelta(info.wheel,fmousewheelfrequmin,fmousewheelfrequmax, + fmousewheeldeltamin,fmousewheeldeltamax); + if ftimestamp <> 0 then begin + flastmousewheeltimestampbefore:= flastmousewheeltimestamp; + flastmousewheeltimestamp:= ftimestamp; + end; + end + else begin + fmouseeventinfo:= @info; + button:= fbutton; + case button of + mb_left: shift:= [ss_left]; + mb_middle: shift:= [ss_middle]; + mb_right: shift:= [ss_right]; + end; + end; + if eventkind = ek_buttonpress then begin + shiftstate:= fshiftstate + shift; + end + else begin + shiftstate:= fshiftstate - shift; + end; + pos:= fpos; + abspos:= addpoint(window.fownerwidget.screenpos,pos); + // abspos:= addpoint(window.fownerwidget.fwidgetrect.pos,pos); + end; + + if (fmodalwindow <> nil) and (window <> fmodalwindow) and + not window.istransientfor(fmodalwindow) then begin + addpoint1(info.mouse.pos, + subpoint(window.screenpos,fmodalwindow.screenpos)); + window:= fmodalwindow; + end; + if (fmousecapturewidget <> nil) and + (fmousecapturewidget.window <> window) then begin + addpoint1(info.mouse.pos,subpoint(window.fownerwidget.fwidgetrect.pos, + fmousecapturewidget.fwindow.fownerwidget.fwidgetrect.pos)); + window:= fmousecapturewidget.fwindow; + end; + if (fmousecapturewidget = nil) and (aps_mousecaptured in fstate) and + (event.fshiftstate * mousebuttons = []) then begin + ungrabpointer; + end; + if (fhintwidget <> nil) and + (fhintinfo.flags*[{hfl_custom,}hfl_noautohidemove] = [{hfl_custom}]) and + ( + (info.mouse.eventkind = ek_buttonpress) or + (info.mouse.eventkind = ek_buttonrelease) or + (info.mouse.eventkind = ek_mousemove) and + (distance(fhintinfo.mouserefpos,abspos) > 3) + ) then begin + bo1:= window = fhintwidget.window; + deactivatehint; + if bo1 then begin + exit; //widow is destroyed + end; + end; + fmouseparkeventinfo:= info.mouse; + factmousewindow:= window; + fmouseparktimer.interval:= mouseparktime; + fmouseparktimer.enabled:= true; + if ftimestamp <> 0 then begin + if (fbutton <> mb_none) then begin + //test reflected event + if kind = ek_buttonpress then begin + if flastbuttonpresstimestamp = ftimestamp then begin + flastbuttonpresstimestamp:= ftimestampbefore; + end; + end + else begin + if kind = ek_buttonrelease then begin + if flastbuttonreleasetimestamp = ftimestamp then begin + flastbuttonreleasetimestamp:= ftimestampbefore; + end; + end; + end; + end; + if kind in [ek_buttonpress,ek_buttonrelease] then begin + int1:= bigint; + if (kind = ek_buttonpress) then begin + if (flastbuttonpresstimestamp <> 0) and (fbutton = flastbuttonpress) then begin + int1:= ftimestamp - flastbuttonpresstimestamp; + end; + end + else begin + if (flastbuttonreleasetimestamp <> 0) and + (fbutton = flastbuttonrelease) then begin + int1:= ftimestamp - flastbuttonreleasetimestamp; + end; + end; + if (int1 >= 0) and (int1 < fdblclicktime) then begin + include(info.mouse.shiftstate,ss_double); + if (kind = ek_buttonpress) then begin + if fdoublemousepress then begin + include(info.mouse.shiftstate,ss_triple); + end; + fdoublemousepress:= true; + end + else begin + if fdoublemouserelease then begin + include(info.mouse.shiftstate,ss_triple); + end; + fdoublemouserelease:= true; + end; + end + else begin + fdoublemousepress:= false; + fdoublemouserelease:= false; + end; + flastbutton:= fbutton; + end; + end; + flastshiftstate:= info.mouse.shiftstate; + window.dispatchmouseevent(info,fmousecapturewidget); + if (ftimestamp <> 0) and (fbutton <> mb_none) then begin + if kind = ek_buttonpress then begin + fbuttonpresswidgetbefore:= fmousewidget; + ftimestampbefore:= flastbuttonpresstimestamp; + flastbuttonpress:= fbutton; + flastbuttonpresstimestamp:= ftimestamp; + end + else begin + if kind = ek_buttonrelease then begin + fbuttonreleasewidgetbefore:= fmousewidget; + ftimestampbefore:= flastbuttonreleasetimestamp; + flastbuttonrelease:= fbutton; + flastbuttonreleasetimestamp:= ftimestamp; + end; + end; + end; + if not (hfl_custom in fhintinfo.flags) then begin + widget1:= fmousewidget; + // widget1:= fmousehintwidget; + if widget1 <> nil then begin + widget1:= widget1.widgetatpos(info.mouse.pos); + //search diabled child + end; + hintid1:= hintidwidget; + while (widget1 <> nil) and + ((ow_mousetransparent in widget1.foptionswidget) or + not widget1.isvisible or + not (widget1.enabled or (ow_disabledhint in widget1.foptionswidget)) + ) do begin + widget1:= widget1.parentwidget; + end; + if widget1 <> nil then begin + if widget1.fframe <> nil then begin + with widget1.fframe do begin + checkstate; + pt1:= translatewidgetpoint(abspos,nil,widget1); + if not ishintarea(pt1,hintid1) then begin + widget1:= nil; + end; + end; + end; + end; + if kind in [ek_buttonpress,ek_buttonrelease] then begin + deactivatehint; //cancel possible hint + end; + if (widget1 <> fhintedwidget) or (hintid1 <> fhintedid) then begin + if (widget1 <> fhintwidget) and + (fhintedwidget <> nil) or (fhintwidget = nil) then begin + deactivatehint; + fhintedwidget:= widget1; + if fhintedwidget <> nil then begin + fhintedid:= hintid1; + fhinttimer.interval:= hintdelaytime; + fhinttimer.enabled:= true; + end; + end; + end + else begin + if (fhintedwidget <> nil) and (fhintwidget = nil) and + (kind = ek_mousemove) then begin + fhinttimer.interval:= hintdelaytime; + if (ow_multiplehint in fhintedwidget.foptionswidget) and + (distance(fhintinfo.mouserefpos,abspos) > 3) then begin + fhinttimer.enabled:= true; + end; + end; + end; + end; + end + else begin + ungrabpointer; + end; + end; + finally + if event.timestamp <> 0 then begin + flastinputtimestamp:= event.timestamp; + end; + fmouseeventinfo:= nil; + fmousewheeleventinfo:= nil; + end; +end; + +procedure tinternalapplication.processkeyevent(event: tkeyevent); +var + window1: twindow; + widget1: twidget; + info: keyeventinfoty; + shift: shiftstatesty; +begin +{$ifdef mse_debugkey} + debugwriteln('*'+getenumname(typeinfo(eventkindty),ord(event.kind))+ + ' "'+ansistring(event.fchars)+'" '+inttostr(ord(event.fkey))); +{$endif} + try + fkeyeventinfo:= @info; + exclude(fstate,aps_clearkeyhistory); + with event do begin + if findwindow(fwinid,window1) then begin + fillchar(info,sizeof(info),0); + with info do begin + eventkind:= fkind; + timestamp:= event.timestamp; + serial:= application.getserial(); + key:= fkey; + keynomod:= fkeynomod; + case key of + key_shift: shift:= [ss_shift]; + key_alt: shift:= [ss_alt]; + key_control: shift:= [ss_ctrl]; + else shift:= []; + end; + if (fkey = key_decimal) and (fchars = '.') then begin + chars:= defaultformatsettingsmse.decimalseparator; + end + else begin + chars:= fchars; + end; + if kind = ek_keypress then begin + shiftstate:= fshiftstate + shift; + end + else begin + shiftstate:= fshiftstate - shift; + end; + flastshiftstate:= shiftstate; + flastkey:= key; + try + if fkeyboardcapturewidget <> nil then begin + window1:= fkeyboardcapturewidget.window; + widget1:= fkeyboardcapturewidget; + end + else begin + window1:= factivewindow; + if window1 <> nil then begin + widget1:= factivewindow.ffocusedwidget; + end + else begin + widget1:= nil; //compiler warning + end; + end; + if window1 <> nil then begin + fmouseparkeventinfo.shiftstate:= shiftstatesty( + replacebits({$ifdef FPC}longword{$else}word{$endif}(shiftstate), + {$ifdef FPC}longword{$else}word{$endif}(fmouseparkeventinfo.shiftstate), + {$ifdef FPC}longword{$else}word{$endif}(keyshiftstatesmask))); + if kind = ek_keypress then begin + fonkeypresslist.dokeyevent(widget1,info); + end; + if not (es_processed in eventstate) and + (not fposted or (fwinid = window1.winid)) then begin + window1.dispatchkeyevent(kind,info); + end; + end; + finally + if (eventkind = ek_keypress) and (key <> key_shift) and + (key <> key_control) and (key <> key_alt) then begin + if length(fkeyhistory) < keyhistorylen then begin + setlength(fkeyhistory,high(fkeyhistory)+2); + end; + if aps_clearkeyhistory in fstate then begin + fkeyhistory:= nil; + end + else begin + move(fkeyhistory[0],fkeyhistory[1],high(fkeyhistory)*sizeof(keyinfoty)); + with fkeyhistory[0] do begin + key:= info.key; + keynomod:= info.keynomod; + shiftstate:= info.shiftstate; + end; + end; + end; + end; + end; + end; + end; + finally + if event.timestamp <> 0 then begin + flastinputtimestamp:= event.timestamp; + end; + exclude(fstate,aps_clearkeyhistory); + fkeyeventinfo:= nil; + end; +end; + +function tinternalapplication.getevents: integer; +var + ev1: tmseevent; +begin + gdi_lock; + if ismainthread then begin //otherwise events of gui_getevent() of mainthread + while gui_hasevent do begin //could be eaten + ev1:= gui_getevent; + if ev1 <> nil then begin + eventlist.add(ev1); + end; + end; + end; + result:= eventlist.count; + gdi_unlock; +end; + +procedure tinternalapplication.waitevent; +begin +{$ifdef mse_debuggdisync} + checkgdiunlocked; +{$endif} + include(fstate,aps_waiting); + while gui_hasevent do begin + eventlist.add(gui_getevent); + end; + if eventlist.count = 0 then begin + incidlecount; + eventlist.add(gui_getevent); + end; + fstate:= fstate - [aps_waiting,aps_woken]; +end; + +procedure tinternalapplication.flushmousemove; +var + int1: integer; + event: tmseevent; +begin + gui_flushgdi; + getevents; + for int1:= 0 to eventlist.count - 1 do begin + event:= tmseevent(eventlist[int1]); + if (event <> nil) and (event.kind = ek_mousemove) then begin + event.free1; + eventlist[int1]:= nil; + end; + end; +end; + +procedure tinternalapplication.windowdestroyed(aid: winidty); +var + int1: integer; + event : tmseevent; +begin + fonwiniddestroyedlist.doevent(aid); + if not terminated then begin + for int1:= 0 to getevents - 1 do begin + event:= tmseevent(eventlist[int1]); + if (event is twindowevent) and (twindowevent(event).fwinid = aid) then begin + { + case event.kind of + ek_focusin: tcaret1(fcaret).restore; + ek_focusout: tcaret1(fcaret).remove; + end; + } + event.Free1; + eventlist[int1]:= nil; + end; + end; + end; + fmouse.windowdestroyed(aid); + if aid = fmousewinid then begin + fmousewinid:= 0; + end; +end; + +procedure tinternalapplication.setwindowfocus(winid: winidty); +var + window: twindow; +begin + if findwindow(winid,window) and (window.fstate*[tws_grouphidden] = []) then begin + try +{$ifdef mse_debugwindowfocus} + debugwriteln('setwindowfocus '+window.fownerwidget.name+' '+hextostr(winid,8)); +{$endif} + exclude(window.fstate,tws_focusoutpending); + if (fmodalwindow = nil) or (fmodalwindow = window) then begin + if wo_noactivate in window.options then begin + if window.transientfor <> nil then begin + gui_setwindowfocus(window.transientfor.winid); + end + else begin + if activewindow <> nil then begin + gui_setwindowfocus(activewindow.winid); + end; + end; + end + else begin + window.activated; + end; + end + else begin + if fmodalwindow.fwindow.id <> 0 then begin +{$ifdef mse_debugwindowfocus} + debugwriteln('call trycancelmodal '+window.fownerwidget.name+' '+hextostr(winid,8)); +{$endif} +{$warnings on} + if {$ifdef mswindows}false{$else} + fmodalwindow.fownerwidget.trycancelmodal(window) + {$endif} then begin +{$warnings off} + {$ifdef mse_debugwindowfocus} + debugwriteln('trycancelmodal true '+window.fownerwidget.name+' '+hextostr(winid,8)); + {$endif} + include(appinst.fstate,aps_cancelloop); + appinst.ffocuslockwindow:= nil; + appinst.ffocuslocktransientfor:= nil; + window.internalactivate(true,true); //force focus + end + else begin + if not fmodalwindow.visible then begin + gui_showwindow(fmodalwindow.fwindow.id); + end; + if ffocuslockwindow <> nil then begin //reactivate modal window + if ffocuslocktransientfor <> nil then begin + gui_setwindowfocus(ffocuslocktransientfor.winid); + end; + end + else begin + gui_setwindowfocus(fmodalwindow.fwindow.id); + end; + gui_raisewindow(fmodalwindow.fwindow.id,wo_popup in fmodalwindow.options); + end; + end; + end; + finally + if not (aps_focused in fstate) then begin + include(fstate,aps_focused); + tcaret1(fcaret).restore; + end; + end; + end{$ifndef mse_debugwindowfocus};{$endif} +{$ifdef mse_debugwindowfocus} + else begin + if not findwindow(winid,window) then begin + debugwriteln('setwindowfocus '+hextostr(winid,8)+' not found'); + end + else begin + debugwriteln('setwindowfocus '+window.fownerwidget.name+' '+ + hextostr(winid,8)+' grouphidden'); + end; + end; +{$endif} + +end; + +procedure tinternalapplication.unsetwindowfocus(winid: winidty); +var + window: twindow; +begin + if aps_focused in fstate then begin + exclude(fstate,aps_focused); + tcaret1(fcaret).remove; + end; + if findwindow(winid,window) then begin +{$ifdef mse_debugwindowfocus} + debugwriteln('unsetwindowfocus '+window.fownerwidget.name+' '+ + hextostr(winid,8)); +{$endif} + exclude(window.fstate,tws_focusoutpending); + if (ffocuslockwindow <> nil) and (factivewindow <> nil) and + (window = ffocuslocktransientfor) then begin + ffocuslockwindow:= nil; + factivewindow.deactivated; + end + else begin + window.deactivated; + end; + end; +end; + +procedure tinternalapplication.registerwindow(awindow: twindow); +begin + lock; + try + if finditem(pointerarty(fwindows),awindow) >= 0 then begin + guierror(gue_alreadyregistered,awindow.fownerwidget.name); + end; + additem(pointerarty(fwindows),awindow); + zorderinvalid(); + {$ifdef mse_debugzorder} + debugwindow('**registerwindow**',awindow); + {$endif} + finally + unlock; + end; +end; + +procedure tinternalapplication.unregisterwindow(awindow: twindow); +var + int1: integer; +begin + lock; + try + {$ifdef mse_debugzorder} + debugwindow('**unregisterwindow**',awindow); + {$endif} + int1:= removeitem(pointerarty(fwindows),awindow); + if (int1 >= 0) and (int1 <= fwindowupdateindex) then begin + dec(fwindowupdateindex); + end; + if awindow.fwindow.id = fmousewinid then begin + fmousewinid:= 0; + end; + finally + unlock; + end; +end; + +procedure tinternalapplication.doterminate(const shutdown: boolean); +begin + if fonterminatequerylist.doterminatequery then begin + if shutdown then begin + include(fstate,aps_terminated); + end + else begin + terminated:= true; + end; + end + else begin + if shutdown then begin + gui_cancelshutdown; + end; + end; +end; + +procedure tinternalapplication.checkshortcut(const sender: twindow; + const awidget: twidget; var info: keyeventinfoty); +var + int1: integer; +begin + include(info.eventstate,es_broadcast); + try + for int1:= high(fwindows) downto 0 do begin + if fwindows[int1] <> sender then begin + fwindows[int1].doshortcut(info,awidget); + if (es_processed in info.eventstate) then begin + break; + end; + end; + end; + if not (es_processed in info.eventstate) then begin + appinst.fonshortcutlist.dokeyevent(awidget,info); + end; + finally + exclude(info.eventstate,es_broadcast); + end; +end; + +procedure tinternalapplication.checkactivewindow; +var + int1: integer; +begin + if factivewindow = nil then begin + if (fmainwindow <> nil) then begin + fmainwindow.fownerwidget.activate; + end + else begin + for int1:= 0 to high(fwindows) do begin + with fwindows[int1].fownerwidget do begin + if visible then begin + activate; + break; + end; + end; + end; + if (factivewindow = nil) and (high(fwindows) >= 0) then begin + fwindows[0].fownerwidget.activate; + end; + end; + end; +end; + +function tinternalapplication.focusinpending: boolean; +var + po1: ^tmseevent; + int1: integer; +begin + gui_flushgdi(true); + getevents; + po1:= pointer(eventlist.datapo); + result:= false; + for int1:= 0 to eventlist.count - 1 do begin + if (po1^ <> nil) and (po1^.kind = ek_focusin) then begin + result:= true; + break; + end; + inc(po1); + end; +end; + +procedure tinternalapplication.checkapplicationactive(); +var + bo1: boolean; +begin + bo1:= (activewindow <> nil) or focusinpending; +{$ifdef mse_debugwindowfocus} + if bo1 then begin + debugwriteln('checkapplicationactive true'); + end + else begin + debugwriteln('checkapplicationactive false'); + end; +{$endif} + if bo1 xor (aps_active in fstate) then begin + if bo1 then begin + include(fstate,aps_active); + end + else begin + exclude(fstate,aps_active); + hidehint; + end; + fonapplicationactivechangedlist.doevent(bo1); + if assistiveserver <> nil then begin + if aps_active in fstate then begin + assistiveserver.doapplicationactivated(); + end + else begin + assistiveserver.doapplicationdeactivated(); + end; + end; + end; +end; + +function tinternalapplication.winiddestroyed(const aid: winidty): boolean; +type + windoweventaty = array[0..0] of twindowevent; + pwindoweventaty = ^windoweventaty; +var + int1: integer; + po1: pwindoweventaty; +begin + result:= false; + getevents; + po1:= pointer(eventlist.datapo); + for int1:= 0 to eventlist.count - 1 do begin + if po1^[int1] <> nil then begin + with po1^[int1] do begin + if (kind = ek_destroy) and (fwinid = aid) then begin + result:= true; + break; + end; + end; + end; + end; +end; + +{$ifdef mse_debug} +procedure debugwindow(const atext: string; const awindow: twindow); +var + str1: string; +begin + if awindow <> nil then begin + str1:= atext+hextostr(awindow.fwindow.id)+' '; + str1:= str1+awindow.owner.name; + end + else begin + str1:= str1+'NIL'; + end; + debugwriteln(str1); +end; + +function debugwindow1(const atext: string; const aid: winidty): string; +var + window1: twindow; +begin + result:= atext+hextostr(aid)+' '; + if appinst.findwindow(aid,window1) then begin + result:= result+window1.owner.name; + end + else begin + result:= result+'NIL'; + end; +end; + +procedure debugwindow(const atext: string; const aid: winidty); +begin + debugwriteln(debugwindow1(atext,aid)); +end; + +procedure debugwindow(const atext: string; const aid1,aid2: winidty); +var + str1: string; + window1: twindow; +begin + str1:= atext+hextostr(aid1)+' '; + if appinst.findwindow(aid1,window1) then begin + str1:= str1+window1.owner.name; + end + else begin + str1:= str1+'NIL'; + end; + str1:= str1+','+hextostr(aid2)+' '; + if appinst.findwindow(aid2,window1) then begin + str1:= str1+window1.owner.name; + end + else begin + str1:= str1+'NIL'; + end; + debugwriteln(str1); +end; + +function checkwindowname(const aid: winidty; const aname: string): boolean; +var + window1: twindow; +begin + result:= appinst.findwindow(aid,window1) and + (window1.fownerwidget.name = aname); +end; + +function debugwidgetname(const awidget: twidget; const atext: string): string; +begin + result:= ''; + if atext <> '' then begin + result:= atext+' '; + end; + if awidget <> nil then begin + result:= result + awidget.name; + end + else begin + result:= result + 'NIL'; + end; +end; + +{$endif} + +procedure tinternalapplication.removewindowevents(const awindow: winidty; + const aeventkind: eventkindty); +var + po1: pwindowevent; + int1: integer; +begin + getevents; + po1:= pointer(eventlist.datapo); + for int1:= 0 to eventlist.count - 1 do begin + if po1^ <> nil then begin + with po1^ do begin + if (kind = ek_configure) and (fwinid = awindow) then begin + po1^.free; + po1^:= nil; + end; + end; + end; + inc(po1); + end; +end; + +procedure tinternalapplication.eventloop(const once: boolean = false); + + function checkiflast(const akind: eventkindty): boolean; + var + po1,po2: ^twindowevent; + int1: integer; + begin + po2:= nil; + po1:= pointer(eventlist.datapo); + for int1:= 0 to eventlist.count - 1 do begin + //check if last + if po1^ <> nil then begin + with po1^ do begin + if (kind = akind) then begin + if po2 <> nil then begin + freeandnil(po2^); + end; + po2:= po1; + end; + end; + end; + inc(po1); + end; + result:= po2 = nil; + end; + + function canuievent: boolean; + begin + result:= not once or (fwaitcount = 0) {or (aps_processmessages in fstate)}; + if not result and (fmousewidget <> nil) then begin + capturemouse(nil,false); + setmousewidget(nil); + end; + end; //canuievent + +var + event: tmseevent; + int1: integer; + bo1,bo2,bo3: boolean; + window: twindow; + id1: winidty; + po1: ^twindowevent; + po2: pmodalinfoty; + waitcountbefore: integer; + ar1: integerarty; + ar2: eventarty; + modalinfo: modalinfoty; + +begin //eventloop + if aps_looplocked in fstate then begin + exit; + end; + if not ismainthread then begin + raise exception.create('Eventloop must be in main thread.'); + end; + + inc(flooplevel); + if fcurrmodalinfo = nil then begin + fillchar(modalinfo,sizeof(modalinfo),0); + fcurrmodalinfo:= @modalinfo; + end; + try + ftimertick:= false; + waitcountbefore:= fwaitcount; + if not once then begin + fwaitcount:= 0; + end; + checkcursorshape; + while not ((fcurrmodalinfo <> nil) and fcurrmodalinfo^.modalend) and + not terminated and (fstate * [aps_exitloop,aps_cancelloop] = []) do begin + //main eventloop + try + if ((fcurrmodalinfo = nil) or (high(fcurrmodalinfo^.events) < 0)) and + (getevents = 0) then begin + checkwindowstack; + int1:= 0; + repeat + bo1:= false; + fwindowupdateindex:= 0; + while fwindowupdateindex <= high(fwindows) do begin + try + bo1:= fwindows[fwindowupdateindex].internalupdate or bo1; + except + handleexception(self); + end; + inc(fwindowupdateindex); + end; + inc(int1); + until not bo1 and not terminated or (int1 > 8); //no more to paint + exclude(fstate,aps_invalidated); + if terminated or (aps_exitloop in fstate) then begin + break; + end; + if not gui_hasevent then begin + try +// if (fcurrmodalinfo{amodalwindow} = nil) and + if (fcurrmodalinfo^.level = 0) and + not (aps_activewindowchecked in fstate) then begin + include(fstate,aps_activewindowchecked); + checkactivewindow; + end; + ftimertick:= false; + msetimer.tick(self); //tick called in every idle + except + handleexception(self); + end; + if not gui_hasevent then begin + try + doidle; + except + handleexception(self); + end; + end; + if terminated then begin + break; + end; + if (aps_needsupdatewindowstack in fstate) and + application.active then begin + updatewindowstack; + exclude(fstate,aps_needsupdatewindowstack); + end + else begin + checkwindowstack; + end; + checkcursorshape; + if once then begin + break; + end; + if gui_hasevent or not (aps_invalidated in fstate) then begin + waitevent; + end; + end; + end; + if terminated then begin + break; + end; + getevents; + if {(fcurrmodalinfo <> nil) and} (high(fcurrmodalinfo^.events) >= 0) then begin + event:= fcurrmodalinfo^.events[0]; + tobjectevent1(event).fmodallevel:= -1; + deleteitem(pointerarty(fcurrmodalinfo^.events),0); + end + else begin + event:= tmseevent(eventlist.getfirst); + end; + if event <> nil then begin + try + try + bo1:= false; + fonapplicationeventlist.doevent(event,bo1); + if not bo1 then begin + case event.kind of + ek_timer: begin + ftimertick:= true; + end; + ek_show,ek_hide: begin + {$ifdef mse_debugwindowfocus} + if event.kind = ek_show then begin + debugwindow('ek_show ',twindowevent(event).fwinid); + end + else begin + debugwindow('ek_hide ',twindowevent(event).fwinid); + end; + {$endif} + processshowingevent(twindowevent(event)); + end; + ek_close: begin + if findwindow(twindowevent(event).fwinid,window) then begin + if (fmodalwindow = nil) or (fmodalwindow = window) then begin + window.close; + end + else begin + fmodalwindow.fownerwidget.canclose(nil); + end; + end; + end; + ek_destroy: begin + if findwindow(twindowevent(event).fwinid,window) then begin + window.windowdestroyed; + end; + windowdestroyed(twindowevent(event).fwinid); + end; + ek_terminate: begin + doterminate(true); + end; + ek_focusin: begin + {$ifdef mse_debugwindowfocus} + debugwindow('ek_focusin ',twindowevent(event).fwinid); + {$endif} + getevents; + bo1:= true; + id1:= twindowevent(event).fwinid; + po1:= pointer(eventlist.datapo); + bo3:= false; + for int1:= 0 to eventlist.count - 1 do begin + if po1^ <> nil then begin //find last focusin + with po1^ do begin + case kind of + ek_focusin: begin + bo3:= false; + id1:= fwinid; + end; + ek_focusout: begin + bo3:= true; + if fwinid = twindowevent(event).fwinid then begin + id1:= 0; + end; + end; + end; + end; + end; + inc(po1); + end; + bo2:= id1 = twindowevent(event).fwinid; //last focus is current window + po1:= pointer(eventlist.datapo); + for int1:= 0 to eventlist.count - 1 do begin + if po1^ <> nil then begin + with po1^ do begin + if (kind = ek_destroy) and + (fwinid = twindowevent(event).fwinid) then begin + bo1:= false; + end; + if bo2 then begin //last focus is current window + if kind in [ek_focusin,ek_focusout] then begin + {$ifdef mse_debugwindowfocus} + debugwindow(' '+getenumname(typeinfo(eventkindty),ord(kind))+ + ' deleted',twindowevent(event).fwinid); + {$endif} + freeandnil(po1^); //ignore + end; + end + else begin + if (kind = ek_focusout) and + (fwinid = twindowevent(event).fwinid) then begin + {$ifdef mse_debugwindowfocus} + debugwindow(' spurious ek_focusout deleted ', + twindowevent(event).fwinid); + {$endif} + bo1:= false; + freeandnil(po1^); + //spurious focus, for instance minimize window group on windows + if bo3 and (factivewindow <> nil) then begin + unsetwindowfocus(factivewindow.fwindow.id); + postevent(tmseevent.create(ek_checkapplicationactive)); + end; + break; + end; + end; + end; + end; + inc(po1); + end; + include(fstate,aps_needsupdatewindowstack); + if bo1 then begin + setwindowfocus(twindowevent(event).fwinid); + checkapplicationactive; + end; + {$ifdef mse_debugwindowfocus} + if not bo1 then begin + debugwriteln(' ek_focusin ignored'); + end; + {$endif} + end; + ek_focusout: begin + {$ifdef mse_debugwindowfocus} + debugwindow('ek_focusout '+hextostr(event)+' ', + twindowevent(event).fwinid); + {$endif} + getevents; + po1:= pointer(@eventlist.datapo^[eventlist.count-1]); + bo1:= true; + for int1:= 0 to eventlist.count - 1 do begin + if po1^ <> nil then begin + with po1^ do begin + case kind of + ek_focusin: begin + {$ifdef mse_debugwindowfocus} + debugwindow(' ek_focusout ignored ',twindowevent(event).fwinid); + {$endif} + bo1:= false; //ignore the event + break; + end; + ek_focusout: begin + break; + end; + end; + end; + end; + dec(po1); + end; + if bo1 then begin + unsetwindowfocus(twindowevent(event).fwinid); + postevent(tmseevent.create(ek_checkapplicationactive)); + end + else begin + include(fstate,aps_restorelocktransientfor); + end; + end; + ek_checkapplicationactive: begin + if checkiflast(ek_checkapplicationactive) then begin + checkapplicationactive; + end; + end; + ek_expose: begin + zorderinvalid(); + processexposeevent(twindowrectevent(event)); + end; + ek_configure: begin + zorderinvalid(); + id1:= twindowrectevent(event).fwinid; + getevents; + po1:= pointer(eventlist.datapo); + for int1:= 0 to eventlist.count - 1 do begin + if po1^ <> nil then begin + //use last configure event for the window + with twindowrectevent(po1^) do begin + if (kind = ek_configure) and (fwinid = id1) then begin + event.free; + event:= po1^; + po1^:= nil; + end; + end; + end; + end; + processconfigureevent(twindowrectevent(event)); + end; + ek_enterwindow: begin + if fmousewinid <> twindowevent(event).fwinid then begin + //there can be an additional enterwindow by mouse click + processwindowcrossingevent(twindowevent(event)); + if canuievent and (event is tmouseenterevent) then begin + processmouseevent(tmouseenterevent(event)); + end; + end; + end; + ek_leavewindow: begin + getevents; + ar1:= nil; + po1:= pointer(eventlist.datapo); + bo1:= true; + for int1:= 0 to eventlist.count - 1 do begin + if po1^ <> nil then begin + with po1^ do begin + if kind in [ek_enterwindow,ek_leavewindow] then begin + additem(ar1,int1); + end; + if (kind = ek_enterwindow) and (fwinid = twindowevent(event).fwinid) then begin + bo1:= false; + //spurious leavewindow + break; + end; + end; + end; + inc(po1); + end; + if bo1 then begin + processwindowcrossingevent(twindowevent(event)) + end + else begin + po1:= pointer(eventlist.datapo); + for int1:= 0 to high(ar1) do begin + freeandnil(pobjectaty(po1)^[ar1[int1]]); + end; + end; + end; + ek_mousemove: begin + if checkiflast(ek_mousemove) and canuievent then begin + processmouseevent(tmouseevent(event)); + end; + end; + ek_buttonpress,ek_buttonrelease,ek_mousewheel: begin + if canuievent then begin + processmouseevent(tmouseevent(event)); + end; + end; + ek_keypress,ek_keyrelease: begin + if canuievent then begin + processkeyevent(tkeyevent(event)); + end; + end; + ek_asyncexec: begin + texecuteevent(event).deliver; + end; + ek_sysdnd: begin + if findwindow(tsysdndevent(event).fwinid,window) then begin + window.processsysdnd(tsysdndevent(event)); + end; + end; + else begin + if event is tobjectevent then begin + with tobjectevent(event) do begin + // if fcurrmodalinfo = nil then begin + // int1:= -modallevel; + // end + // else begin + int1:= fcurrmodalinfo^.level-modallevel; + // end; + if (int1 > 0) and (modallevel >= 0) then begin + po2:= fcurrmodalinfo^.parent; + for int1:= int1 - 2 downto 0 do begin + po2:= po2^.parent; + end; + additem(pointerarty(po2^.events),event); + event:= nil; + end + else begin + deliver; + end; + end; + end; + end; + end; + end; + finally + event.free1; + end; + except + handleexception(self); + end; + checkcursorshape; + end; + except + end; + end; + exclude(fstate,aps_exitloop); + fwaitcount:= waitcountbefore; + if fwaitcount > 0 then begin + mouse.shape:= cr_wait; + end; + checkcursorshape; + + if {(fcurrmodalinfo <> nil) and} (fcurrmodalinfo^.parent <> nil) then begin + stackarray(pointer(fcurrmodalinfo^.events), + pointerarty(fcurrmodalinfo^.parent^.events)); + end + else begin +// if fcurrmodalinfo <> nil then begin + ar2:= fcurrmodalinfo^.events; + fcurrmodalinfo^.events:= nil; +// end +// else begin +// ar2:= nil; +// end; + for int1:= 0 to high(ar2) do begin + if ar2[int1] is tobjectevent then begin + with tobjectevent1(ar2[int1]) do begin + fmodallevel:= -1; + free1; + end; + end + else begin + ar2[int1].free; + end; + end; + end; + finally + dec(flooplevel); + if fcurrmodalinfo = @modalinfo then begin + fcurrmodalinfo:= nil; + end; + end; +end; + +function tinternalapplication.beginmodal(const sender: twindow; + const showinfo: pshowinfoty): boolean; + //true if modalwindow destroyed +var + window1: twindow; + bo1: boolean; + modalwidgetbefore,focusedwidgetbefore: twidget; + modalinfo: modalinfoty; + modalinfobefore: pmodalinfoty; + p1,pe: ^tmseevent; +begin + result:= false; + exclude(fstate,aps_cancelloop); + window1:= nil; + if (factivewindow <> nil) and (factivewindow <> sender) then begin + setlinkedvar(factivewindow,tlinkedobject(window1)); + bo1:= tws_modalcalling in window1.fstate; + include(window1.fstate,tws_modalcalling); + end; + modalwidgetbefore:= nil; + focusedwidgetbefore:= nil; + fillchar(modalinfo,sizeof(modalinfo),0); + if fcurrmodalinfo <> nil then begin + modalinfo.parent:= fcurrmodalinfo; + modalinfo.level:= fcurrmodalinfo^.level+1; + end + else begin + modalinfo.level:= 1; + end; + fcurrmodalinfo:= @modalinfo; + if fmodalwindow <> nil then begin + setlinkedvar(fmodalwindow,tlinkedobject(modalinfo.modalwindowbefore)); + end; + modalinfobefore:= sender.fmodalinfopo; + sender.fmodalinfopo:= @modalinfo; + setlinkedvar(sender,tlinkedobject(fmodalwindow)); + + try + with sender do begin + inc(fmodallevel); + end; + if showinfo <> nil then begin + with showinfo^ do begin + setlinkedvar(widget.window.fmodalwidget,tmsecomponent(modalwidgetbefore)); + if (factivewindow = sender) and (sender.ffocusedwidget <> nil) and + not widget.checkdescendent(sender.ffocusedwidget) then begin + setlinkedvar(sender.ffocusedwidget, + tmsecomponent(focusedwidgetbefore)); + end; + widget.internalshow(ml_none,@transientfor,windowevent,nomodalforreset); + if fstate * [aps_cancelloop,aps_exitloop] <> [] then begin + exit; + end; + widget.activate; + setlinkedvar(sender.fmodalwidget,tmsecomponent(modalwidgetbefore)); + sender.fmodalwidget:= widget; + end; + end; + sender.activate; + if fstate * [aps_cancelloop,aps_exitloop] = [] then begin + try + eventloop; + finally + with showinfo^ do begin + if (widget <> nil) then begin + widget.window.fmodalwidget:= modalwidgetbefore; + end; + end; + if (window1 <> nil) then begin + try + if not (aps_cancelloop in fstate) then begin + if (focusedwidgetbefore <> nil) then begin + focusedwidgetbefore.activate(true,false); + end; + if appinst.active and (appinst.fwantedactivewindow = nil) then begin + p1:= pointer(eventlist.datapo); + pe:= p1 + eventlist.count; + while p1 < pe do begin + if p1^ <> nil then begin + with p1^ do begin + if (kind = ek_focusout) and + (window1.fwindow.id = twindowevent(p1^).fwinid) then begin + include(window1.fstate,tws_focusoutpending); + {$ifdef mse_debugwindowfocus} + debugwindow('focusoutpending ',window1); + {$endif} + break; + end; + end; + end; + inc(p1); + end; + window1.activate(); + end; + end; + finally + if (window1 <> nil) and not bo1 then begin + exclude(window1.fstate,tws_modalcalling); + end; + end; + end; + end; + end; + finally + setlinkedvar(nil,tlinkedobject(window1)); + setlinkedvar(nil,tmsecomponent(modalwidgetbefore)); + setlinkedvar(nil,tmsecomponent(focusedwidgetbefore)); + exclude(fstate,aps_exitloop); + if fmodalwindow <> nil then begin + fmodalwindow.fmodalinfopo:= modalinfobefore{nil}; + end + else begin + result:= true; + end; + if modalinfo.modalwindowbefore <> nil then begin + setlinkedvar(modalinfo.modalwindowbefore,tlinkedobject(fmodalwindow)); + setlinkedvar(nil,tlinkedobject(modalinfo.modalwindowbefore)); + end + else begin + if fmodalwindow <> nil then begin + setlinkedvar(nil,tlinkedobject(fmodalwindow)); + //no lower modalwindow alive + end; + end; + fcurrmodalinfo:= modalinfo.parent; + end; +end; + +procedure tinternalapplication.endmodal(const sender: twindow); +begin + with sender do begin + if fmodallevel > 0 then begin + if not appinst.terminated and (fmodalinfopo <> nil) then begin + fmodalinfopo^.modalend:= true; + end; + dec(fmodallevel); + end; + end; +end; + +{$ifdef mse_debugzorder} +function debugwindowinfo(const awindow: twindow): string; +begin + if awindow = nil then begin + result:= 'nil'; + end + else begin + if awindow = application.activewindow then begin + result:= 'A'; + if awindow.modal then begin + result:= result+'M'; + end; + end + else begin + result:= ''; + end; + result:= result+'"'+awindow.fownerwidget.name+':'+ + awindow.fownerwidget.classname+'"'; + end; +end; + +procedure printwindowstackinfo(const ar3: windowarty); overload; +var + int1: integer; +begin + for int1:= 0 to high(ar3) do begin + if ar3[int1].fownerwidget.visible then begin + debugwrite(inttostr(int1)+'+ '); + end + else begin + debugwrite(inttostr(int1)+'- '); + end; + debugwriteln(debugwindowinfo(ar3[int1])+' transientfor:'+ + debugwindowinfo(ar3[int1].ftransientfor)); + end; +end; + +procedure printwindowstackinfo(const ar3: windowstackinfoarty); overload; +var + int1: integer; +begin + for int1:= 0 to high(ar3) do begin + debugwriteln(debugwindowinfo(ar3[int1].lower)+' '+ + debugwindowinfo(ar3[int1].upper)); + end; +end; + +{$endif} + +procedure tinternalapplication.stackunder(const sender: twindow; + const predecessor: twindow); +begin +{$ifdef mse_debugzorder} + debugwriteln('****stackunder**** '+debugwindowinfo(sender)+' '+ + debugwindowinfo(predecessor)); +{$endif} + setlength(fwindowstack,high(fwindowstack)+2); + with fwindowstack[high(fwindowstack)] do begin + lower:= sender; + upper:= predecessor; + end; +end; + +procedure tinternalapplication.stackover(const sender: twindow; + const predecessor: twindow); +begin +{$ifdef mse_debugzorder} + debugwriteln('****stackover**** '+debugwindowinfo(sender)+' '+ + debugwindowinfo(predecessor)); +{$endif} + setlength(fwindowstack,high(fwindowstack)+2); + with fwindowstack[high(fwindowstack)] do begin + lower:= predecessor; + upper:= sender; + end; +end; + +function cmpwindowstack(const l,r): integer; +begin + result:= windowstackinfoty(l).level - windowstackinfoty(r).level; +end; + +procedure tinternalapplication.checkwindowstack; + + function findlevel(var item: windowstackinfoty): integer; + var + int1: integer; + begin + with item do begin + if (level = 0) and (lower <> nil) and not recursion then begin + if upper = nil then begin + result:= -bigint; + end + else begin + result:= 1; //not found upper + recursion:= true; + for int1:= 0 to high(fwindowstack) do begin + with fwindowstack[int1] do begin + if lower = item.upper then begin + result:= findlevel(fwindowstack[int1]) + 1; + break; + end; + end; + end; + recursion:= false; + end; + end + else begin + result:= level; + end; + level:= result; + end; + end; + +var + int1: integer; +begin + if (fwindowstack <> nil) and (flockupdatewindowstack = nil) then begin + include(fstate,aps_looplocked); //no windows sizing callbacks + try + if not nozorderhandling then begin + {$ifdef mse_debugzorder} + debugwriteln('****checkwindowstack**** fwindowstack'); + printwindowstackinfo(fwindowstack); + {$endif} + for int1:= 0 to high(fwindowstack) do begin + findlevel(fwindowstack[int1]); + end; + sortarray(fwindowstack,sizeof(windowstackinfoty), + {$ifdef FPC}@{$endif}cmpwindowstack); + {$ifdef mse_debugzorder} + debugwriteln('..... after sort'); + printwindowstackinfo(fwindowstack); + {$endif} + if gui_canstackunder then begin + for int1:= 0 to high(fwindowstack) do begin + with fwindowstack[int1] do begin + if lower <> nil then begin + if (upper = nil) then begin + gui_raisewindow(lower.winid); + end + else begin + // if int1 = 0 then begin + // gui_raisewindow(upper.winid); + // end; + gui_stackunderwindow(lower.winid,upper.winid); + end; + end; + end; + end; + end + else begin + for int1:= high(fwindowstack) downto 0 do begin + with fwindowstack[int1] do begin + if (lower <> nil) then begin + gui_raisewindow(fwindowstack[int1].lower.winid); + end; + end; + end; + for int1:= 0 to high(fwindowstack) do begin //raise top level window + with fwindowstack[int1] do begin + if lower <> nil then begin + if upper <> nil then begin + gui_raisewindow(fwindowstack[int1].upper.winid); + end; + break; + end; + end; + end; + end; + zorderinvalid(); + end; + fwindowstack:= nil; + finally + exclude(fstate,aps_looplocked); + end; + end; +end; + +function compwindowzorder(const l,r): integer; +const + raiseweight = 1 shl 1; + lowerweight = raiseweight; + backgroundweight = 1 shl 2; + topweight = backgroundweight; +// popupweight = 1 shl 4; + modalweight = 1 shl 5; +// transientforcountweight = 1 shl 6; +// transientfornotnilweight = 1 shl 7; + transientforactiveweight = 1 shl 8; + transientforweight = 1 shl 9; + invisibleweight = 1 shl 10; + popupweight = 1 shl 11; + ultratopweight = 1 shl 12; +var + window1: twindow; +{$ifdef mse_debugzorder} + ch1: char; +{$endif} +label + endlab; +begin + result:= 0; + if (tws_windowvisible in twindow(l).fstate) and + (twindow(l).syscontainer = sywi_none) then begin + if not (tws_windowvisible in twindow(r).fstate) or + (twindow(r).syscontainer <> sywi_none) then begin + inc(result,invisibleweight); + end + end + else begin + if (tws_windowvisible in twindow(r).fstate) and + (twindow(r).syscontainer = sywi_none)then begin + dec(result,invisibleweight); + end + else begin + goto endlab; //both invisible -> no change in order + end; + end; + if (result = 0) and + ((twindow(l).syscontainer <> sywi_none) or + (twindow(r).syscontainer <> sywi_none) or + (twindow(l).fcontainer <> 0) or + (twindow(r).fcontainer <> 0)) then begin + goto endlab; //don't change order of embedded windows + end; + if tws_raise in twindow(l).fstate then begin + inc(result,raiseweight); + end; + if tws_raise in twindow(r).fstate then begin + dec(result,raiseweight); + end; + if tws_lower in twindow(l).fstate then begin + dec(result,lowerweight); + end; + if tws_lower in twindow(r).fstate then begin + inc(result,lowerweight); + end; + if ow_background in twindow(l).fownerwidget.foptionswidget then begin + dec(result,backgroundweight); + end; + if ow_top in twindow(l).fownerwidget.foptionswidget then begin + inc(result,topweight); + end; + if ow_ultratop in twindow(l).fownerwidget.foptionswidget then begin + inc(result,ultratopweight); + end; + if ow_background in twindow(r).fownerwidget.foptionswidget then begin + inc(result,backgroundweight); + end; + if ow_top in twindow(r).fownerwidget.foptionswidget then begin + dec(result,topweight); + end; + if ow_ultratop in twindow(r).fownerwidget.foptionswidget then begin + dec(result,ultratopweight); + end; + if twindow(l).ispopup then begin + inc(result,popupweight); + end; + if twindow(r).ispopup then begin + dec(result,popupweight); + end; + if twindow(l).fmodallevel > 0 then begin + inc(result,modalweight); + end; + if twindow(r).fmodallevel > 0 then begin + dec(result,modalweight); + end; + if twindow(l).transientforstackactive then begin + inc(result,transientforactiveweight); + end; + if twindow(r).transientforstackactive then begin + dec(result,transientforactiveweight); + end; + { +// if twindow(l).transientforstackactive then begin + if twindow(l).ftransientfor <> nil then begin + inc(result,transientfornotnilweight); + end; + if twindow(l).ftransientforcount > 0 then begin + inc(result,transientforcountweight); + end; +// end; +// if twindow(r).transientforstackactive then begin + if twindow(r).ftransientfor <> nil then begin + dec(result,transientfornotnilweight); + end; + if twindow(r).ftransientforcount > 0 then begin + dec(result,transientforcountweight); + end; +// end; +} + window1:= twindow(l); + while window1.ftransientfor <> nil do begin + if window1.ftransientfor = twindow(r) then begin + inc(result,transientforweight); + goto endlab; + end; + window1:= window1.ftransientfor; + end; + window1:= twindow(r); + while window1.ftransientfor <> nil do begin + if window1.ftransientfor = twindow(l) then begin + dec(result,transientforweight); + goto endlab; + end; + window1:= window1.ftransientfor; + end; +endlab: +{$ifdef mse_debugzorder} + if result < 0 then begin + ch1:= '-'; + end + else begin + ch1:= ' '; + end; + debugwindow('.'+ch1+hextostr(longword(abs(result)),4)+ + ' tract:'+bintostr(ord(twindow(l).transientforstackactive),1)+':'+ + bintostr(ord(twindow(r).transientforstackactive),1)+ + ' trforco:'+inttostr(twindow(l).ftransientforcount)+':'+ + inttostr(twindow(r).ftransientforcount)+ + ' l:',twindow(l).winid, + twindow(r).winid); +{$endif} +end; + +procedure tinternalapplication.updatewindowstack; +var + ar3,ar4: windowarty; + int1,int2: integer; + bo1: boolean; +begin + if flockupdatewindowstack = nil then begin + exclude(fstate,aps_zordervalid); //possible missing configure events + checkwindowstack; + sortzorder; + ar3:= windowar; //refcount 1 + {$ifdef mse_debugzorder} + debugwriteln('*****updatewindowstack***** current order'); + printwindowstackinfo(ar3); + {$endif} + ar4:= copy(ar3); + sortarray(ar3,sizeof(ar3[0]),{$ifdef FPC}@{$endif}compwindowzorder); + for int1:= 0 to high(ar3) do begin + with ar3[int1] do begin + fstate:= fstate - [tws_raise,tws_lower]; + //reset bringtofrontlocal/sendtobacklocal + end; + end; + int2:= -1; + {$ifdef mse_debugzorder} + debugwriteln('++++ after sort'); + printwindowstackinfo(ar3); + {$endif} + for int1:= 0 to high(ar4) do begin + if ar3[int1] <> ar4[int1] then begin + int2:= int1; //invalid stackorder + break; + end; + end; + if int2 >= 0 then begin + {$ifdef mse_debugzorder} + debugwriteln('++++ invalid stackorder ' + inttostr(int2) + + ' high(ar3) ' + inttostr(high(ar3))); + {$endif} + if gui_canstackunder then begin + bo1:= true; + for int1:= int2+1 to high(ar3) do begin + if ar4[int1] <> ar3[int1-1] then begin + bo1:= false; + break; + end; + end; + if bo1 then begin //single local raise + {$ifdef mse_debugzorder} + debugwriteln('++++ single local raise'); + {$endif} + gui_stackoverwindow(ar4[int2].winid,ar4[high(ar4)].winid); + fwindowstack:= nil; + zorderinvalid(); + exit; + end; + end; + inc(int2); + for int1:= high(ar3) downto int2 do begin + if not (tws_windowvisible in ar3[int1-1].fstate) then begin + break; + end; + stackunder(ar3[int1-1],ar3[int1]); + end; + checkwindowstack; + end; + end; +end; + +procedure tinternalapplication.internalpackwindowzorder(); +var + int1: integer; +begin + updatewindowstack(); //handle pending; + sortzorder(); + if high(fwindows) > 1 then begin + setlength(fwindowstack,length(fwindows)); + for int1:= 0 to high(fwindowstack) - 1 do begin + with fwindowstack[int1] do begin + lower:= fwindows[int1]; + upper:= fwindows[int1+1]; + end; + end; + { + with fwindowstack[high(fwindowstack)] do begin + lower:= fwindows[high(fwindowstack)]; + upper:= nil; + end; + } + end; +end; + +procedure tinternalapplication.widgetdestroyed(const widget: twidget); +begin + if fmousecapturewidget = widget then begin + capturemouse(nil,false); + end; + if fkeyboardcapturewidget = widget then begin + fkeyboardcapturewidget:= nil; + end; + if fcaretwidget = widget then begin + caret.hide; + fcaretwidget:= nil; + end; + if fmousewidget = widget then begin + setmousewidget(nil); + end; + if fmousehintwidget = widget then begin + fmousehintwidget:= nil; + end; + if fhintforwidget = widget then begin + deactivatehint; + end; + if fhintedwidget = widget then begin + fhintedwidget:= nil; + end; + if flastshowmenuwidget = widget then begin + flastshowmenuwidget:= nil; + end; + if fclientmousewidget = widget then begin + fclientmousewidget:= nil; + end; + if fbuttonpresswidgetbefore = widget then begin + fbuttonpresswidgetbefore:= nil; + end; + if fbuttonreleasewidgetbefore = widget then begin + fbuttonreleasewidgetbefore:= nil; + end; +end; + +procedure tinternalapplication.checkcursorshape; +begin + if terminated then begin + fmouse.shape:= cr_default; + end + else begin + if not waiting then begin + if fcursorshape = cr_default then begin + fmouse.shape:= fwidgetcursorshape; + end + else begin + fmouse.shape:= fcursorshape; + end; + end + else begin + fmouse.shape:= cr_wait; + end; + end; +end; + +procedure tinternalapplication.dopostevent(const aevent: tmseevent); +begin + gui_postevent(aevent); +end; + +procedure tinternalapplication.doeventloop(const once: boolean); +begin + eventloop(once); +end; + +{ tguiapplication } + +constructor tguiapplication.create(aowner: tcomponent); +begin + fwidgetcursorshape:= cr_default; + fmousewheelsensitivity:= 1; + fmousewheelfrequmin:= 1; + fmousewheelfrequmax:= 100; + fmousewheeldeltamin:= 0.05; + fmousewheeldeltamax:= 30; + fmousewheelaccelerationmax:= 30; + fhintwidgetclass:= thintwidget; + gui_registergdi; + inherited; +end; + +procedure getmseguiarguments(); +var + ar1: msestringarty; + int1,int2: integer; + + procedure deleteitem(); + begin + deletecommandlineargument(int1-int2); + inc(int2); + end; //deleteitem + +begin + ar1:= getcommandlinearguments; + int2:= 0; + for int1:= 1 to high(ar1) do begin + if ar1[int1] = '--TOPLEVELRAISE' then begin + toplevelraise:= true; + deleteitem(); + noreconfigurewmwindow:= true; + norestackwindow:= true; + continue; + end; + if ar1[int1] = '--NOZEROLINES' then begin + zerolineworkaround:= true; + deleteitem(); + continue; + end; + if ar1[int1] = '--NOZORDERHANDLING' then begin + nozorderhandling:= true; + deleteitem(); + continue; + end; + if ar1[int1] = '--NORESTACKWINDOW' then begin + norestackwindow:= true; + deleteitem(); + continue; + end; + if ar1[int1] = '--RESTACKWINDOW' then begin + norestackwindow:= false; + deleteitem(); + continue; + end; + if ar1[int1] = '--NORECONFIGUREWMWINDOW' then begin + noreconfigurewmwindow:= true; + deleteitem(); + continue; + end; + if ar1[int1] = '--RECONFIGUREWMWINDOW' then begin + noreconfigurewmwindow:= false; + deleteitem(); + continue; + end; + if ar1[int1] = '--STACKMODEBELOWWORKAROUND' then begin + stackmodebelowworkaround:= true; + deleteitem(); + continue; + end; + if ar1[int1] = '--NOSTACKMODEBELOWWORKAROUND' then begin + stackmodebelowworkaround:= false; + deleteitem(); + continue; + end; + if ar1[int1] = '--NOSTATICGRAVITY' then begin + nostaticgravity:= true; + deleteitem(); + continue; + end; + { + if ar1[int1] = '--EXABUG' then begin + //workaround for radeon EXA pixmap bug, slows down drawing! + exabug:= true; + deleteitem(); + continue; + end; + } + { + if ar1[int1] = '--NOCREATESTATICGRAVITY' then begin + nocreatestaticgravity:= true; + deleteitem(); + continue; + end; + if ar1[int1] = '--CREATESTATICGRAVITY' then begin + nocreatestaticgravity:= false; + deleteitem(); + continue; + end; + } + end; +end; + +procedure tguiapplication.internalinitialize; +begin + with tinternalapplication(self) do begin + fdesigning:= false; + getmseguiarguments(); + guierror(gui_init,self); + msetimer.init(); + msegraphics.init(); + end; +end; + +procedure tguiapplication.internaldeinitialize; +begin + with tinternalapplication(self) do begin + if fcaret <> nil then begin + fcaret.link(nil,nullpoint,nullrect); + end; + msegraphics.deinit(); + lock(); + gui_flushgdi(); + flusheventbuffer(); + getevents(); + eventlist.clear(); + unlock(); + gui_deinit(); + msetimer.deinit(); + end; + inherited; +end; + +procedure tguiapplication.destroyforms; +begin + while componentcount > 0 do begin + components[componentcount-1].free; //destroy loaded forms + end; + while high(fwindows) >= 0 do begin + fwindows[high(fwindows)].fownerwidget.free; + end; +end; + +procedure tguiapplication.checkwindowrect(winid: winidty; var rect: rectty); +var + window: twindow; +begin + if findwindow(winid,window) then begin + window.fownerwidget.checkwidgetsize(rect.size); + end; +end; + +procedure tguiapplication.setclientmousewidget(const widget: twidget; + const apos: pointty); +var + info: mouseeventinfoty; +begin + if fclientmousewidget <> widget then begin + fillchar(info,sizeof(info),0); + if (fclientmousewidget <> nil) and + not (csdestroying in fclientmousewidget.componentstate) then begin +// exclude(fclientmousewidget.fwidgetstate,ws_mouseinclient); + info.eventkind:= ek_clientmouseleave; + fclientmousewidget.mouseevent(info); + end; + fclientmousewidget:= widget; + if widget <> nil then begin + info.eventkind:= ek_clientmouseenter; + info.pos:= apos; + widget.mouseevent(info); + end; + end; +end; + +procedure tguiapplication.setmousewidget(const widget: twidget); +var + info: mouseeventinfoty; + widget1: twidget; +begin + widget1:= fmousewidget; + fmousewidget:= widget; + if (fclientmousewidget <> nil) and (fclientmousewidget <> widget) then begin + setclientmousewidget(nil,nullpoint); + end; + if widget1 <> widget then begin + if (widget1 <> nil) and + not (csdestroying in widget1.componentstate) then begin + fillchar(info,sizeof(info),0); + info.eventkind:= ek_mouseleave; + widget1.mouseevent(info); + end; + if widget <> nil then begin + finalize(info); + fillchar(info,sizeof(info),0); + info.eventkind:= ek_mouseenter; + widget.mouseevent(info); + end; + end; +end; + +function tguiapplication.grabpointer(const aid: winidty): boolean; +var + int1: integer; +begin + for int1:= 0 to high(fwindows) do begin + with fwindows[int1] do begin + if fwindow.id <> aid then begin + exclude(fstate,tws_grab); + end; + end; + end; + {$ifdef nograbpointer} + result:= true; + {$else} + result:= gui_grabpointer(aid) = gue_ok; + {$endif} + if result then begin + include(fstate,aps_mousecaptured); + end + else begin + exclude(fstate,aps_mousecaptured); + end; +end; + +function tguiapplication.ungrabpointer: boolean; +var + int1: integer; +begin + result:= false; + for int1:= 0 to high(fwindows) do begin + if tws_grab in fwindows[int1].fstate then begin + exit; + end; + end; + gui_ungrabpointer; + exclude(fstate,aps_mousecaptured); + result:= true; +end; + +procedure tguiapplication.capturemouse(const sender: twidget; + const grab: boolean); +var + widget: twidget; + info: mouseeventinfoty; +begin + if fmousecapturewidget <> sender then begin + if (fmousecapturewidget <> nil) and + not (csdestroying in fmousecapturewidget.componentstate) then begin + widget:= fmousecapturewidget; + fmousecapturewidget:= sender; + fillchar(info,sizeof(info),0); + info.eventkind:= ek_mousecaptureend; + widget.mouseevent(info); + if fmousecapturewidget <> sender then begin + exit; + end; + widget.fwidgetstate:= widget.fwidgetstate - + [ws_lclicked,ws_mclicked,ws_rclicked, + ws_mousecaptured,ws_clientmousecaptured]; + if sender <> nil then begin + fwidgetcursorshape:= cr_default; //give up cursor shape + end; + end + else begin + fmousecapturewidget:= sender; + end; + if fmousecapturewidget <> nil then begin + if grab then begin + grabpointer(fmousecapturewidget.window.winid); + end; + setmousewidget(fmousecapturewidget); + end + else begin + if not grab then begin + ungrabpointer; + end; + end; + end; +end; + +function tguiapplication.createform(instanceclass: widgetclassty; + var reference): twidget; +begin + result:= twidget(mseclasses.createmodule(self,instanceclass,reference)); +end; + +procedure tguiapplication.eventloop(const once: boolean = false); + //used in win32 wm_queryendsession and wm_entersizemove +begin + inc(feventlooping); + try + tinternalapplication(self).eventloop(once); + finally + dec(feventlooping); + end; +end; + +procedure tguiapplication.exitloop; //used in win32 cancelshutdown +begin + include(fstate,aps_exitloop); +end; + +procedure tguiapplication.processmessages; +begin + gui_flushgdi; + sys_schedyield; + inherited; +end; + +procedure tguiapplication.invalidated; +begin +// if not (aps_invalidated in fstate) then begin + include(fstate,aps_invalidated); + wakeupmainthread; +// end; +end; + +procedure tguiapplication.showasyncexception(e: exception; + const leadingtext: msestring = ''); +var + mstr1: msestring; +begin + mstr1:= leadingtext + e.Message; + postevent(tasyncmessageevent.create(mstr1,'Exception')); +end; + +procedure tguiapplication.showexception(e: exception; + const leadingtext: msestring = ''); +var + mstr1: msestring; +begin + if not (e is eabort) then begin + if not ismainthread then begin + showasyncexception(e,leadingtext); + end + else begin + mstr1:= leadingtext + e.Message; + showmessage(mstr1,sc(sc_exception){$ifdef FPC},0,lineend+ + getexceptiontext(exceptobject, + exceptaddr,exceptframecount,exceptframes){$endif}); + end; + end; +end; + +procedure tguiapplication.errormessage(const amessage: msestring); +begin + showerror(amessage); +end; + +function tguiapplication.active: boolean; +begin + result:= aps_active in fstate; +end; + +procedure tguiapplication.activate(); +begin + if flastactivewindow <> nil then begin + flastactivewindow.activate(); + end + else begin + if fmainwindow <> nil then begin + fmainwindow.activate(); + end + else begin + if fwindows <> nil then begin + fwindows[0].activate(); + end; + end; + end; +end; + +function tguiapplication.findwindow(aid: winidty; out window: twindow): boolean; +var + int1: integer; +begin + result:= false; + for int1:= 0 to high(fwindows) do begin + if fwindows[int1].fwindow.id = aid then begin + window:= fwindows[int1]; + result:= true; + exit; + end; + end; + window:= nil; +end; + +function tguiapplication.screenrect(const awindow: twindow = nil): rectty; +var + id: winidty; +begin + id:= 0; + if awindow <> nil then begin + id:= awindow.winid; + end; + result:= gui_getscreenrect(id); +end; + +function tguiapplication.workarea(const awindow: twindow = nil): rectty; +var + id: winidty; +begin + id:= 0; + if awindow = nil then begin + if factivewindow <> nil then begin + id:= factivewindow.winid; + end; + end + else begin + id:= awindow.winid; + end; + result:= gui_getworkarea(id); +end; + +function tguiapplication.ppmm(const awindow: twindow = nil): complexty; +var + id: winidty; +begin + id:= 0; + if awindow = nil then begin + if factivewindow <> nil then begin + id:= factivewindow.winid; + end; + end + else begin + id:= awindow.winid; + end; + gui_getppmm(id,result.re,result.im); +end; + +function tguiapplication.normalactivewindow: twindow; +begin + result:= fwantedactivewindow; + if result = nil then begin + result:= factivewindow; + end; +end; + +function tguiapplication.regularactivewindow: twindow; +begin + result:= factivewindow; + while (result <> nil) and (result.ftransientfor <> nil) do begin + result:= result.ftransientfor; + end; +end; + +function tguiapplication.unreleasedactivewindow: twindow; +begin + result:= factivewindow; + while (result <> nil) and (result.fownerwidget.releasing or + not result.fownerwidget.visible) do begin + result:= result.ftransientfor; + end; +end; + +function tguiapplication.activewidget: twidget; +begin + if factivewindow <> nil then begin + result:= factivewindow.ffocusedwidget; + end + else begin + result:= nil; + end; +end; + +function tguiapplication.activerootwidget: twidget; +begin + if factivewindow <> nil then begin + result:= factivewindow.fownerwidget; + end + else begin + result:= nil; + end; +end; + +function tguiapplication.windowatpos(const pos: pointty): twindow; +var + id: winidty; +begin + id:= gui_windowatpos(pos); + if id <> 0 then begin + findwindow(id,result); + end + else begin + result:= nil; + end; +end; + +function tguiapplication.findwidget(const namepath: string; + out awidget: twidget): boolean; + //false if invalid namepath, '' -> nil and true + //last name = '' -> widget.container +var + str1: string; + bo1: boolean; +begin + result:= true; + awidget:= nil; + if namepath <> '' then begin + bo1:= namepath[length(namepath)] = '.'; + if bo1 then begin + str1:= copy(namepath,1,length(namepath)-1); + end + else begin + str1:= namepath; + end; + awidget:= twidget(findcomponentbynamepath(str1)); + if not (awidget is twidget) then begin + result:= false; + awidget:= nil; + end + else begin + if bo1 then begin + awidget:= awidget.container; + end; + end; + end; +end; + +function tguiapplication.windowar: windowarty; +begin + setlength(result,length(fwindows)); + if result <> nil then begin + move(fwindows[0],result[0],length(result)*sizeof(pointer)); + end; +end; + +function tguiapplication.winidar: winidarty; +var + ar1: windowarty; + int1: integer; +begin + ar1:= windowar; + setlength(result,length(ar1)); + for int1:= 0 to high(ar1) do begin + result[int1]:= ar1[int1].winid; + end; +end; + +function tguiapplication.getwindows(const index: integer): twindow; +begin + checkarrayindex(fwindows,index); + result:= fwindows[index]; +end; + +function tguiapplication.windowcount: integer; +begin + result:= length(fwindows); +end; + +function cmpwindowvisibility(const l,r): integer; +begin + if (tws_windowvisible in twindow(l).fstate) and + (twindow(l).syscontainer = sywi_none) then begin + if (tws_windowvisible in twindow(r).fstate) and + (twindow(r).syscontainer = sywi_none) then begin + result:= 0; + end + else begin + result:= 1; + end; + end + else begin + if (tws_windowvisible in twindow(r).fstate) and + (twindow(r).syscontainer = sywi_none) then begin + result:= -1; + end + else begin + result:= 0; + end + end; +end; + +procedure tguiapplication.sortzorder(); + //top is last, invisibles and sycontainer windows first +var + ar1: winidarty; + ar2,ar3: integerarty; +begin + ar1:= nil; //compiler warning +{$ifdef mse_debugzorder} + if aps_zordervalid in fstate then begin + debugwriteln('* sortzorder valid'); + end + else begin + debugwrite('* sortzorder'); + end; +{$endif} + if not (aps_zordervalid in fstate) then begin + ar1:= winidar; + {$ifdef mse_debugzorder} + debugwriteln(' n='+inttostr(length(ar1))); + {$endif} + if high(ar1) >= 0 then begin + gui_getzorder(ar1,ar2); + sortarray(ar2,ar3); + orderarray(ar3,pointerarty(fwindows)); + sortarray(pointerarty(fwindows),{$ifdef FPC}@{$endif}cmpwindowvisibility); + end; + include(fstate,aps_zordervalid); + end; +end; + +procedure tguiapplication.packwindowzorder(); +begin + internalpackwindowzorder(); +end; + + +function tguiapplication.bottomwindow: twindow; + //lowest visible window in stackorder, calls sortzorder +var + int1: integer; +begin + sortzorder; + result:= nil; + for int1:= 0 to windowcount-1 do begin + if windows[int1].visible then begin + result:= windows[int1]; + break; + end; + end; +end; + +function tguiapplication.topwindow: twindow; + //highest visible window in stackorder, calls sortzorder +var + int1: integer; +begin + sortzorder; + result:= nil; + for int1:= windowcount-1 downto 0 do begin + if windows[int1].visible then begin + result:= windows[int1]; + break; + end; + end; +end; + +procedure tguiapplication.internalshowhint(const sender: twidget; + const ahintwidget: twidget); +var + window1: twindow; + widgetclass1: widgetclassty; +begin + fhintforwidget:= sender; + with tinternalapplication(self),fhintinfo do begin + window1:= nil; + if (sender <> nil) and ((activewindow = nil) or + (activewindow = sender.window) and activewindow.modal) then begin + window1:= sender.window; + end; + if ahintwidget = nil then begin + if hintwidgetclass <> nil then begin + widgetclass1:= hintwidgetclass; + end + else begin + widgetclass1:= fhintwidgetclass; + end; + if widgetclass1.inheritsfrom(tcustomhintwidget) then begin + fhintwidget:= hintwidgetclassty(widgetclass1).create( + nil,window1,fhintinfo,sender); + end + else begin + fhintwidget:= widgetclass1.create(nil); + end; + end + else begin + fhintwidget:= ahintwidget; + end; + {$ifdef mse_debugzorder} + debugwriteln('** showhint '+tinternalapplication(self).fhintinfo.caption+' '+ + debugwindowinfo(fhintedwidget.window)); + {$endif} + fhintwidget.show(ml_none,window1); + if showtime <> 0 then begin + fhinttimer.interval:= showtime; + fhinttimer.enabled:= true; + end; + end; +end; + +procedure tguiapplication.inithintinfo(var info: hintinfoty; + const ahintedwidget: twidget); +begin + finalize(info); + fillchar(info,sizeof(info),0); + with info do begin + flags:= defaulthintflags; + if (ahintedwidget <> nil) and + (ow_timedhint in ahintedwidget.foptionswidget) then begin + showtime:= defaulthintshowtime; + end + else begin + showtime:= 0; + end; + mouserefpos:= fmouse.pos; + if ahintedwidget <> nil then begin + posrect.pos:= translateclientpoint(mouserefpos,nil,ahintedwidget); + end + else begin + posrect.pos:= mouserefpos + end;; + posrect.cx:= 24; + posrect.cy:= 24; + placement:= cp_bottomleft; + end; +end; + +procedure tguiapplication.initwidgethintinfo(var info: hintinfoty; + const ahintedwidget: twidget); +begin + inithintinfo(info,ahintedwidget); + if ahintedwidget <> nil then begin + info.posrect:= ahintedwidget.widgetrect; + translatewidgetpoint1(info.posrect.pos,ahintedwidget.parentwidget,nil); + end; +end; + +procedure tguiapplication.showhint(const sender: twidget; const hint: msestring; + const aposrect: rectty; const aplacement: captionposty = cp_bottomleft; + const ashowtime: integer = defaulthintshowtime; //0 -> inifinite, + // -1 defaultshowtime if ow_timedhint in sender.optionswidget + const aflags: hintflagsty = defaulthintflags + ); +begin + deactivatehint; + fhintedwidget:= sender; + with fhintinfo do begin + mouserefpos:= fmouse.pos; + flags:= aflags; + caption:= hint; + if ashowtime < 0 then begin + if ow_timedhint in sender.foptionswidget then begin + showtime:= defaulthintshowtime; + end + else begin + showtime:= 0; + end; + end + else begin + showtime:= ashowtime; + end; + posrect:= aposrect; + if sender <> nil then begin + translateclientpoint1(posrect.pos,sender,nil); + end; + placement:= aplacement; + end; + internalshowhint(sender,nil); +end; + +procedure tguiapplication.showhint(const sender: twidget; const hint: msestring; + const apos: pointty; + const ashowtime: integer = defaulthintshowtime; //0 -> inifinite, + // -1 defaultshowtime if ow_timedhint in sender.optionswidget + const aflags: hintflagsty = defaulthintflags + ); +begin + showhint(sender,hint,makerect(apos,nullsize),cp_bottomleft,ashowtime,aflags); +end; + +procedure tguiapplication.showhint(const sender: twidget; + const info: hintinfoty); +begin + with info do begin + if (hfl_show in flags) or (caption <> '') then begin + showhint(sender,caption,posrect,placement,showtime,flags); + end; + end; +end; + +procedure tguiapplication.showhint(const sender: twidget; + const hint: msestring); +var + info: hintinfoty; +begin + inithintinfo(info,sender); + info.caption:= hint; + showhint(sender,info); +end; + +procedure tguiapplication.showhint(const sender: twidget; + const hintwidget: twidget; + const ashowtime: integer = defaulthintshowtime; //0 -> inifinite, + // -1 defaultshowtime if ow_timedhint in sender.optionswidget + const aflags: hintflagsty = defaulthintflags); +begin + deactivatehint; + fhintedwidget:= sender; + inithintinfo(fhintinfo,sender); + with fhintinfo do begin + flags:= aflags; + if ashowtime >= 0 then begin + showtime:= ashowtime; + end; + end; + internalshowhint(sender,hintwidget); +end; + +procedure tguiapplication.hidehint; +begin + deactivatehint; +end; + +function tguiapplication.hintedwidget: twidget; +begin + result:= fhintedwidget; +end; + +function tguiapplication.activehintedwidget: twidget; +begin + if tinternalapplication(self).fhintwidget = nil then begin + result:= nil; + end + else begin + result:= fhintedwidget; + end; +end; + +procedure tguiapplication.help(const sender: tmsecomponent); +begin + with tinternalapplication(self) do begin + fonhelp.doevent(sender); + end; +end; + +procedure tguiapplication.registerhelphandler(const ahandler: helpeventty); +begin + tinternalapplication(self).fonhelp.add(tmethod(ahandler)); +end; + +procedure tguiapplication.unregisterhelphandler(const ahandler: helpeventty); +begin + tinternalapplication(self).fonhelp.remove(tmethod(ahandler)); +end; + +function tguiapplication.activehelpcontext: msestring; +begin + if activewidget = nil then begin + result:= ''; + end + else begin + result:= activewidget.helpcontext; + end; +end; + +function tguiapplication.mousehelpcontext: msestring; +begin + if mousewidget = nil then begin + result:= ''; + end + else begin + result:= mousewidget.helpcontext; + end; +end; + +procedure tguiapplication.activatehint; +begin + deactivatehint; + if (fhintedwidget <> nil) and + ((factivewindow <> nil) or + (ow_appinactivehint in fhintedwidget.optionswidget) and + (fhintedwidget.window.syscontainer <> sywi_none)) then begin + inithintinfo(fhintinfo,fhintedwidget); + fhintedwidget.showhint(fhintedid,fhintinfo); + with fhintinfo do begin + if (hfl_show in flags) or (caption <> '') then begin + translateclientpoint1(posrect.pos,fhintedwidget,nil); + internalshowhint(fhintedwidget,nil); + end; + end; + end; +end; + +procedure tguiapplication.deactivatehint; +begin + with tinternalapplication(self) do begin + freeandnil(fhintwidget); + fhinttimer.enabled:= false; + finalize(fhintinfo); + fhintinfo.flags:= []; + fhintforwidget:= nil; + end; +end; + +procedure tguiapplication.hinttimer(const sender: tobject); +begin + with tinternalapplication(self) do begin + if fhintwidget = nil then begin + activatehint; + end + else begin + deactivatehint; + end; + end; +end; + +procedure tguiapplication.setmainwindow(const Value: twindow); +var + int1: integer; + id: winidty; +begin + fmainwindow:= value; + if value <> nil then begin + if value.fownerwidget.isgroupleader and value.haswinid then begin + id:= value.winid; + for int1:= 0 to high(fwindows) do begin + with fwindows[int1] do begin + if fwindow.id <> 0 then begin + gui_setwindowgroup(fwindow.id,id); + end; + end; + end; + end; + end; +end; + +procedure tguiapplication.dragstarted; //calls dragstarted of all known widgets +var + int1: integer; +begin + for int1:= 0 to high(fwindows) do begin + fwindows[int1].fownerwidget.dragstarted; + end; +end; + +procedure tguiapplication.mouseparkevent; //simulates mouseparkevent +begin + if fmousewidget <> nil then begin + fmousewidget.window.mouseparked; + end; +end; + +procedure tguiapplication.registeronkeypress(const method: keyeventty); +begin + tinternalapplication(self).fonkeypresslist.add(tmethod(method)); +end; + +procedure tguiapplication.unregisteronkeypress(const method: keyeventty); +begin + tinternalapplication(self).fonkeypresslist.remove(tmethod(method)); +end; + +procedure tguiapplication.registeronshortcut(const method: keyeventty); +begin + tinternalapplication(self).fonshortcutlist.add(tmethod(method)); +end; + +procedure tguiapplication.unregisteronshortcut(const method: keyeventty); +begin + tinternalapplication(self).fonshortcutlist.remove(tmethod(method)); +end; + +procedure tguiapplication.registeronwidgetactivechanged( + const method: widgetchangeeventty); +begin + tinternalapplication(self).fonwidgetactivechangelist.add(tmethod(method)); +end; + +procedure tguiapplication.unregisteronwidgetactivechanged( + const method: widgetchangeeventty); +begin + tinternalapplication(self).fonwidgetactivechangelist.remove(tmethod(method)); +end; + +procedure tguiapplication.registeronwindowactivechanged( + const method: windowchangeeventty); +begin + tinternalapplication(self).fonwindowactivechangelist.add(tmethod(method)); +end; + +procedure tguiapplication.unregisteronwindowactivechanged( + const method: windowchangeeventty); +begin + tinternalapplication(self).fonwindowactivechangelist.remove(tmethod(method)); +end; + +procedure tguiapplication.registeronwindowdestroyed( + const method: windoweventty); +begin + tinternalapplication(self).fonwindowdestroyedlist.add(tmethod(method)); +end; + +procedure tguiapplication.unregisteronwindowdestroyed( + const method: windoweventty); +begin + tinternalapplication(self).fonwindowdestroyedlist.remove(tmethod(method)); +end; + +procedure tguiapplication.registeronwiniddestroyed(const method: winideventty); +begin + tinternalapplication(self).fonwiniddestroyedlist.add(tmethod(method)); +end; + +procedure tguiapplication.unregisteronwiniddestroyed( + const method: winideventty); +begin + tinternalapplication(self).fonwiniddestroyedlist.remove(tmethod(method)); +end; + +procedure tguiapplication.registeronapplicationactivechanged( + const method: booleaneventty); +begin + tinternalapplication(self).fonapplicationactivechangedlist.add( + tmethod(method)); +end; + +procedure tguiapplication.unregisteronapplicationactivechanged( + const method: booleaneventty); +begin + tinternalapplication(self).fonapplicationactivechangedlist.remove( + tmethod(method)); +end; + +procedure tguiapplication.registersyseventhandler( + const method: syseventhandlereventty); +begin + tinternalapplication(self).fonsyseventlist.add(tmethod(method)); +end; + +procedure tguiapplication.unregistersyseventhandler( + const method: syseventhandlereventty); +begin + tinternalapplication(self).fonsyseventlist.remove(tmethod(method)); +end; + +procedure tguiapplication.updatecursorshape; + //restores cursorshape of mousewidget +begin + if fclientmousewidget <> nil then begin + fclientmousewidget.updatecursorshape(fmousewidgetpos){(true)}; + end + else begin + widgetcursorshape:= cr_default; + end; +end; + +procedure tguiapplication.setcursorshape(const avalue: cursorshapety); +begin + if fcursorshape <> avalue then begin + fcursorshape:= avalue; //wanted shape + if not waiting then begin + if fthread <> sys_getcurrentthread then begin + mouse.shape:= fcursorshape; //show new cursor immediately + end + else begin + if avalue = cr_default then begin + updatecursorshape; + end; + end; + end; + end; +end; + +procedure tguiapplication.setwidgetcursorshape(const avalue: cursorshapety); +begin + if fwidgetcursorshape <> avalue then begin + fwidgetcursorshape:= avalue; + if (avalue = cr_default) and (fclientmousewidget <> nil) then begin + fclientmousewidget.updatecursorshape(fmousewidgetpos); + end; + end; +end; + +procedure tguiapplication.beginwait(const aprocessmessages: boolean = false); +begin + lock; + try + if fwaitcount = 0 then begin + gui_resetescapepressed; + end; + inc(fwaitcount); + mouse.shape:= cr_wait; + inherited; + finally + unlock; + end; +end; + +procedure tguiapplication.endwait; +var + int1: integer; + po1: ^tmseevent; +begin + lock; + try + if fwaitcount > 0 then begin + dec(fwaitcount); + if (fwaitcount = 0) and (fnoignorewaitevents = 0) then begin + with tinternalapplication(self) do begin + getevents; + po1:= pointer(eventlist.datapo); + for int1:= 0 to eventlist.count - 1 do begin + if (po1^ <> nil) and (po1^.kind in waitignoreevents) then begin + freeandnil(po1^); + end; + inc(po1); + end; + checkcursorshape; + end; + end; + end; + finally + unlock; + end; +end; + +function tguiapplication.waiting: boolean; +begin + result:= fwaitcount > 0; +end; + +function tguiapplication.waitescaped: boolean; +begin + lock; + result:= waiting; + if result then begin + result:= gui_escapepressed; + if not result then begin + tinternalapplication(self).getevents; + result:= gui_escapepressed; + end; + end; + unlock; +end; + +procedure tguiapplication.langchanged; +begin + inherited; + invalidate; +end; + +function tguiapplication.candefocus(const caller: tobject = nil): boolean; +var + int1: integer; +begin + result:= true; + for int1:= 0 to high(fwindows) do begin + if (fwindows[int1] <> caller) and not fwindows[int1].candefocus then begin + result:= false; + break; + end; + end; +end; + +function tguiapplication.terminating: boolean; +begin + result:= aps_terminating in fstate; +end; + +function tguiapplication.deinitializing: boolean; +begin + result:= aps_deinitializing in fstate; +end; + +function tguiapplication.terminate(const sender: twindow = nil): boolean; +var + int1: integer; +begin + result:= false; + include(fstate,aps_terminating); + try + int1:= 0; + while int1 <= high(fwindows) do begin + if (fwindows[int1] <> sender) and + not fwindows[int1].fownerwidget.canparentclose(nil) then begin + exit; + end; + inc(int1); + end; + tinternalapplication(self).doterminate(false); + finally + exclude(fstate,aps_terminating); + end; + result:= terminated; +end; + +procedure tguiapplication.delayedmouseshift(const ashift: pointty); +begin + addpoint1(fdelayedmouseshift,ashift); +end; + +procedure tguiapplication.calcmousewheeldelta(var info: mousewheeleventinfoty; + const fmin,fmax,deltamin,deltamax: real); +var + frequ: real; +begin + if (flastmousewheeltimestamp <> 0) and + (flastmousewheeltimestamp <> info.timestamp) then begin + frequ:= 1000000/(info.timestamp-flastmousewheeltimestamp); //Hz + if frequ > fmax then begin + frequ:= fmax; + end; + if frequ < fmin then begin + frequ:= fmin; + end; + info.delta:= (frequ*(deltamax-deltamin)+(deltamin*fmax-deltamax*fmin))/ + (fmax-fmin); + end + else begin + info.delta:= deltamin; + end; + if info.wheel = mw_down then begin + info.delta:= - info.delta; + end; + info.delta:= info.delta * fmousewheelsensitivity; +end; + +function tguiapplication.mousewheelacceleration(const avalue: real): real; +var + info: mousewheeleventinfoty; +begin + info.timestamp:= flastmousewheeltimestamp + flastmousewheeltimestamp - + flastmousewheeltimestampbefore; + info.wheel:= mw_up; + calcmousewheeldelta(info,fmousewheelfrequmin,fmousewheelfrequmax,1, + fmousewheelaccelerationmax); + result:= avalue * info.delta; +end; + +function tguiapplication.mousewheelacceleration(const avalue: integer): integer; +begin + result:= round(mousewheelacceleration(avalue*1.0)); +end; + +procedure tguiapplication.clearkeyhistory; +begin + include(fstate,aps_clearkeyhistory); +end; + +procedure tguiapplication.invalidate; +var + int1: integer; +begin + for int1:= 0 to high(fwindows) do begin + fwindows[int1].fownerwidget.invalidate; + end; +end; + +procedure tguiapplication.restarthint(const sender: twidget); +begin + with tinternalapplication(self) do begin + if fhintedwidget = sender then begin + deactivatehint; + fhinttimer.interval:= hintdelaytime; + fhinttimer.enabled:= true; + end; + end; +end; + +procedure tguiapplication.receiveevent(const event: tobjectevent); +begin + if (event.kind = ek_user) then begin + with tuserevent(event) do begin + case tag of + cancelwaittag: begin + cancelwait; + end + else begin + if event is tasyncmessageevent then begin + with tasyncmessageevent(event) do begin + showmessage(fmessage,fcaption); + end; + end; + end; + end; + end; + end; + inherited; +end; + +procedure tguiapplication.dowaitidle(var again: boolean); +begin + with tinternalapplication(self) do begin + if fmodalwindow <> fmodalwindowbeforewaitdialog then begin //wait for message window + unregisteronidle({$ifdef FPC}@{$endif}dowaitidle); + processmessages; + fexecuteaction(self); + end; + end; +end; + +procedure tguiapplication.dowaitidle1(var again: boolean); +begin + if fstate * [aps_waitok,aps_waitcanceled,aps_waitidlelock] = [] then begin + include(fstate,aps_waitidlelock); + fidleaction(self,again); + if fstate * [aps_waitok,aps_waitcanceled] = [] then begin + registeronidle({$ifdef FPC}@{$endif}dowaitidle1); +// again:= true; + exclude(fstate,aps_waitidlelock); + end; + end; +end; + +function tguiapplication.waitdialog(const athread: tthreadcomp = nil; + const atext: msestring = ''; + const caption: msestring = ''; + const acancelaction: notifyeventty = nil; + const aexecuteaction: notifyeventty = nil; + const aidleaction: waitidleeventty = nil; + const acontinueaction: notifyeventty = nil): boolean; +var +// res1: modalresultty; + wo1: longword; +begin + if not ismainthread then begin + raise exception.create('Waitdialog must be called from main thread.'); + end; + result:= false; + wo1:= exceptioncount; + if not (aps_waitstarted in fstate) then begin + with tinternalapplication(self) do begin + fmodalwindowbeforewaitdialog:= fmodalwindow; + resetwaitdialog; + include(fstate,aps_waitstarted); + fexecuteaction:= aexecuteaction; + fidleaction:= aidleaction; + if assigned(aexecuteaction) then begin + registeronidle({$ifdef FPC}@{$endif}dowaitidle); + end; + if assigned(aidleaction) then begin + registeronidle({$ifdef FPC}@{$endif}dowaitidle1); + end; + try + if athread <> nil then begin + fonterminatebefore:= athread.onterminate; + athread.onterminate:= {$ifdef FPC}@{$endif}dothreadterminated; + athread.run; + end; + if assigned(acontinueaction) then begin + repeat + until showmessage(atext,caption,[mr_continue,mr_cancel],mr_continue,[],0, + [acontinueaction,acancelaction]) in [mr_cancel,mr_continue]; + end + else begin + repeat + until showmessage(atext,caption,[mr_cancel],mr_cancel,[],0, + [acancelaction]) = mr_cancel; + end; + if wo1 <> exceptioncount then begin + sysutils.abort; + end; + result:= aps_waitok in fstate; + if not result then begin + include(fstate,aps_waitcanceled); + end + else begin + include(fstate,aps_waitterminated); + end; + if athread <> nil then begin + athread.terminate; + athread.waitfor; + end; + finally + unregisteronidle({$ifdef FPC}@{$endif}dowaitidle); + unregisteronidle({$ifdef FPC}@{$endif}dowaitidle1); + exclude(fstate,aps_waitstarted); + if athread <> nil then begin + athread.onterminate:= fonterminatebefore; + end; + end; + end; + end; +end; + +procedure tguiapplication.cancelwait; +begin + if not ismainthread then begin + postevent(tuserevent.create(ievent(self),cancelwaittag)); + end + else begin + with tinternalapplication(self) do begin + if not waitcanceled and (fmodalwindow <> fmodalwindowbeforewaitdialog) and + (fmodalwindow <> nil) then begin + fmodalwindow.modalresult:= mr_cancel; + end; + end; + end; +end; + +procedure tguiapplication.terminatewait; +begin + lock; + include(fstate,aps_waitok); + cancelwait; + unlock; +end; + +procedure tguiapplication.resetwaitdialog; +begin + lock; + fstate:= fstate - [aps_waitstarted,aps_waitcanceled,aps_waitterminated, + aps_waitok,aps_waitidlelock]; + unlock; +end; + +function tguiapplication.waitstarted: boolean; +begin + lock; + result:= aps_waitstarted in fstate; + unlock; +end; + +function tguiapplication.waitcanceled: boolean; +begin + lock; + result:= aps_waitcanceled in fstate; + unlock; +end; + +function tguiapplication.waitterminated: boolean; +begin + lock; + result:= aps_waitterminated in fstate; + unlock; +end; + +procedure tguiapplication.dothreadterminated(const sender: tthreadcomp); +begin + if not waitcanceled then begin + terminatewait; + end; + if assigned(fonterminatebefore) then begin + fonterminatebefore(sender); + end; +end; + +procedure tguiapplication.sysevent(const awindow: winidty; + var aevent: syseventty; var handled: boolean); +begin + tinternalapplication(self).fonsyseventlist.doevent(awindow,aevent,handled); +end; + +procedure tguiapplication.sethighrestimer(const avalue: boolean); +begin + guierror(gui_sethighrestimer(avalue)); +end; + +procedure tguiapplication.dopostevent(const aevent: tmseevent); +begin + if feventlooping = 0 then begin + gui_postevent(aevent); + end + else begin + eventlist.add(aevent); + end; +end; + +procedure tguiapplication.settimer(const us: integer); +begin + if us <= 0 then begin + inherited; + end + else begin + gui_settimer(us); + end; +end; + +procedure tguiapplication.doafterrun; +begin + if not (apo_noautodestroymodules in foptions) then begin + destroyforms(); //zeos lib unloads libraries -> + //forms must be destroyed before unit finalization + end; +end; + +function tguiapplication.idle: boolean; +begin + result:= inherited idle and not gui_hasevent; +end; + +function tguiapplication.shortcutting: boolean; +begin + result:= aps_shortcutting in fstate; +end; + +function tguiapplication.modallevel: integer; +begin + result:= -1; + if flooplevel > 0 then begin + result:= 0; + if fcurrmodalinfo <> nil then begin + result:= fcurrmodalinfo^.level; + end; + end; +end; + +threadvar + gdilocks: int32; + +function tguiapplication.unlockall: integer; +begin + gdilocks:= gdilocks + gdi_unlockall(); + inherited; +end; + +procedure tguiapplication.relockall(count: integer); +begin + inherited; + gdi_relockall(gdilocks); +end; + +procedure tguiapplication.objecteventdestroyed(const sender: tobjectevent); +var + po1: pmodalinfoty; + int1: integer; +begin + if sender.modallevel >= 0 then begin + lock; + po1:= fcurrmodalinfo; + while po1 <> nil do begin + for int1:= high(po1^.events) downto 0 do begin + if po1^.events[int1] = sender then begin + po1^.events[int1]:= nil; + end; + end; + po1:= po1^.parent; + end; + unlock; + end; +end; + +procedure tguiapplication.beginnoignorewaitevents; +begin + interlockedincrement(fnoignorewaitevents); +end; + +procedure tguiapplication.endnoignorewaitevents; +begin + interlockeddecrement(fnoignorewaitevents); +end; + +procedure tguiapplication.internalpackwindowzorder; +begin + //dummy +end; + +procedure tguiapplication.zorderinvalid(); +begin + exclude(fstate,aps_zordervalid); + if gao_forcezorder in foptionsgui then begin + {$ifdef mse_debugzorder} + debugwriteln('*needsupdatewindowstack'); + {$endif} + include(fstate,aps_needsupdatewindowstack); + end; +end; + +function tguiapplication.getforcezorder: boolean; +begin + result:= gao_forcezorder in foptionsgui; +end; + +procedure tguiapplication.setforcezorder(const avalue: boolean); +begin + if avalue then begin + optionsgui:= optionsgui + [gao_forcezorder]; + end + else begin + optionsgui:= optionsgui - [gao_forcezorder]; + end; +end; + +{ tasyncmessageevent } + +constructor tasyncmessageevent.create(const amessage: msestring; + const acaption: msestring); +begin + fmessage:= amessage; + fcaption:= acaption; + inherited create(ievent(application),0); +end; + +{ tmousenterevent } + +constructor tmouseenterevent.create(const winid: winidty; const pos: pointty; + const shiftstate: shiftstatesty; atimestamp: longword); +begin + inherited create(winid,false,mb_none,mw_none,pos,shiftstate,atimestamp); + fkind:= ek_enterwindow; +end; + +{ twidgetshowevent } + +procedure twidgetshowevent.execute; +begin + fmodalresult:= fwidget.show(fmodallevel,ftransientfor); +end; + +{ tcreatewindowevent } + +procedure tcreatewindowevent.execute; +begin + fsender.fcanvas.updatewindowoptions(foptionspo^); + guierror(gui_createwindow(frect,foptionspo^,fwindowpo^),fsender); +end; + +{ tdestroywindowevent } + +procedure tdestroywindowevent.execute; +begin + if fwindowpo <> nil then begin + gui_destroywindow(fwindowpo^); + end; +end; + +{ tfadecolorarrayprop } + +constructor tfadecolorarrayprop.create; +begin + inherited; + fvaluedefault:= defaultfadecolor; +end; + +{ tfadeopacolorarrayprop } + +constructor tfadeopacolorarrayprop.create; +begin + inherited; + fvaluedefault:= defaultfadeopacolor; +end; + +{ treparentevent } + +constructor treparentevent.create(akind: eventkindty; winid: winidty; + aparent: winidty); +begin + fparent:= aparent; + inherited create(ek_reparent,winid); +end; + +initialization + registerapplicationclass(tinternalapplication); +end. diff --git a/mseide-msegui/lib/common/kernel/mseguiglob.pas b/mseide-msegui/lib/common/kernel/mseguiglob.pas new file mode 100644 index 0000000..b7f0905 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseguiglob.pas @@ -0,0 +1,431 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseguiglob; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface +uses + classes,mclasses,msegraphutils,msetypes,msekeyboard,mseerr,mseevent,msestrings, + mseglob; +{$ifdef FPC} + +{$endif} + +type + unicharty = longword; + + originty = (org_screen,org_widget,org_paint,org_client,org_inner); + captionposty = (cp_center,cp_rightbottom,cp_right,{cp_rightcenter,}cp_righttop, + cp_topright,cp_top,{cp_topcenter,}cp_topleft, + cp_lefttop,cp_left,{cp_leftcenter,}cp_leftbottom, + cp_bottomleft,cp_bottom,{cp_bottomcenter,}cp_bottomright + ); +const + rightcaptionpos = [cp_rightbottom,cp_right,{cp_rightcenter,}cp_righttop]; + bottomcaptionpos = [cp_bottomleft,cp_bottom,{cp_bottomcenter,}cp_bottomright]; +type + imageposty = (ip_center,ip_centervert, //ip_center -> ip_centerhorz + ip_rightbottom,ip_right,{ip_rightcenter,}ip_righttop, + ip_topright,ip_top,{ip_topcenter,}ip_topleft, + ip_lefttop,ip_left,{ip_leftcenter,}ip_leftbottom, + ip_bottomleft,ip_bottom,{ip_bottomcenter,}ip_bottomright + ); +const + horzimagepos = [ip_center,ip_rightbottom,ip_right,{ip_rightcenter,}ip_righttop, + ip_lefttop,ip_left,{ip_leftcenter,}ip_leftbottom]; + vertimagepos = [ip_centervert,ip_topright,ip_top,{ip_topcenter,}ip_topleft, + ip_bottomleft,ip_bottom,{ip_bottomcenter,}ip_bottomright]; + rightimagepos = [ip_rightbottom,ip_right,ip_righttop]; + bottomimagepos = [ip_bottomleft,ip_bottom,ip_bottomright]; +type + mousebuttonty = (mb_none,mb_left,mb_right,mb_middle); + mousewheelty = (mw_none,mw_up,mw_down); + + shiftstatety = (ss_none,ss_shift,ss_alt,ss_ctrl,ss_left,ss_right,ss_middle, + ss_double,ss_triple, + ss_repeat, //repeat keydown + ss_second); //right modifier keys, numpad + shiftstatesty = set of shiftstatety; + clipboardbufferty = (cbb_clipboard,cbb_primary); +const + keyshiftstatesmask = [ss_shift,ss_alt,ss_ctrl]; + keyshiftstatesrepeatmask = keyshiftstatesmask + [ss_repeat]; + buttonshiftstatesmask = [ss_left,ss_right,ss_middle,ss_double,ss_triple]; + shiftstatesmask = [ss_shift,ss_alt,ss_ctrl,ss_left,ss_right,ss_middle]; + shiftstatesrepeatmask = shiftstatesmask + [ss_repeat]; + +type + mouseeventinfoty = record //same layout as mousewheeleventinfoty! + eventkind: eventkindty; + shiftstate: shiftstatesty; + pos: pointty; + eventstate: eventstatesty; + timestamp: longword; //usec, 0 -> invalid + serial: card32; //0 -> invalid + button: mousebuttonty; + end; + pmouseeventinfoty = ^mouseeventinfoty; + + mousewheeleventinfoty = record //same layout as mouseeventinfoty! + eventkind: eventkindty; + shiftstate: shiftstatesty; + pos: pointty; + eventstate: eventstatesty; + timestamp: longword; //usec, 0 -> invalid + serial: card32; //0 -> invalid + wheel: mousewheelty; + delta: real; + end; + pmousewheeleventinfoty = ^mousewheeleventinfoty; + + moeventinfoty = record + case integer of + 0: (mouse: mouseeventinfoty); + 1: (wheel: mousewheeleventinfoty); + end; + + keyeventinfoty = record + eventkind: eventkindty; + key,keynomod: keyty; + chars: msestring; + shiftstate: shiftstatesty; + eventstate: eventstatesty; + timestamp: longword; //usec + serial: card32; //0 -> invalid + end; + pkeyeventinfoty = ^keyeventinfoty; + + stockfontty = (stf_default, //0 numbers used in tskincontroller + stf_empty, //1 + stf_unicode, //2 + stf_menu, //3 + stf_message, //4 + stf_hint, //5 + stf_report, //6 + stf_proportional,//7 + stf_fixed, //8 + stf_helvetica, //9 + stf_roman, //10 + stf_courier); //11 + defaultfontnamesty = array[stockfontty] of string; + +type + windowoptionty = (wo_popup,wo_message, + wo_desktop,wo_dock,wo_toolbar,wo_menu, + wo_utility,wo_splash,wo_dialog,wo_dropdownmenu, + wo_popupmenu,wo_tooltip,wo_notification,wo_combo, + wo_dnd, + wo_noframe, //uses motif hints on linux + wo_noactivate,wo_overrideredirect, + wo_embedded, + wo_buttonendmodal,wo_groupleader, + wo_taskbar, //win32 only + wo_notaskbar, + wo_windowcentermessage, //showmessage centered in window + wo_sysdnd //activate system drag and drop (xdnd on Linux) + ); + windowoptionsty = set of windowoptionty; + windowtypeoptionty = wo_popup..wo_dnd; + +const + windowtypeoptions = [wo_popup,wo_message, + wo_desktop,wo_dock,wo_toolbar,wo_menu, + wo_utility,wo_splash,wo_dialog,wo_dropdownmenu, + wo_popupmenu,wo_tooltip,wo_notification,wo_combo, + wo_dnd]; + noframewindowtypes = [wo_popup,wo_splash,wo_dropdownmenu,wo_popupmenu, + wo_tooltip,wo_combo,wo_noframe,wo_overrideredirect]; +type + windowposty = (wp_normal,wp_screencentered,wp_screencenteredvirt, + wp_transientforcentered,wp_mainwindowcentered, + wp_minimized,wp_maximized,wp_default, + wp_fullscreen,wp_fullscreenvirt); + windowsizety = (wsi_normal,wsi_minimized,wsi_maximized, + wsi_fullscreen,wsi_fullscreenvirt); +const + windowmaximizedstates = [wp_maximized,wp_fullscreen,wp_fullscreenvirt]; + +type + syswindowty = (sywi_none,sywi_tray); + + paintdevicety = ptruint; + fontty = ptruint; + regionty = ptruint; + pixmapty = ptruint; + windowpty = array[0..7] of pointer; + windowty = record + id: winidty; + platformdata: windowpty; + end; + pwindowty = ^windowty; + + internalwindowoptionspty = array[0..3] of pointer; //buffer + + internalwindowoptionsty = record + parent: winidty; + options: windowoptionsty; + pos: windowposty; + transientfor: winidty; + setgroup: boolean; + groupleader: winidty; + icon,iconmask: pixmapty; + platformdata: internalwindowoptionspty; + end; + pinternalwindowoptionsty = ^internalwindowoptionsty; + +const + defaultppmm = 3; //3 pixel per mm + sizingtol = 2; //+- pixel + sizingwidth = 2*sizingtol; + +const + captiontoimagepos: array[captionposty] of imageposty = ( + //cp_center,cp_rightbottom,cp_right, + ip_center,ip_lefttop, ip_left, + //{cp_rightcenter,}cp_righttop, + {ip_leftcenter,} ip_leftbottom, + //cp_topright, cp_top, cp_topcenter, cp_topleft, + ip_bottomleft,ip_bottom,{ip_bottomcenter,}ip_bottomright, + //cp_lefttop, cp_left, cp_leftcenter, cp_leftbottom, + ip_rightbottom,ip_right,{ip_rightcenter,}ip_righttop, + //cp_bottomleft,cp_bottom,cp_bottomcenter,cp_bottomright + ip_topright, ip_top, {ip_topcenter,} ip_topleft + ); + imagetocaptionpos: array[imageposty] of captionposty = ( + //ip_center,ip_centervert,ip_rightbottom,ip_right, + cp_center,cp_center, cp_lefttop, cp_left, + //{ip_rightcenter,}ip_righttop, + {cp_leftcenter,} cp_leftbottom, + //ip_topright, ip_top, ip_topcenter, ip_topleft, + cp_bottomleft,cp_bottom,{cp_bottomcenter,}cp_bottomright, + //ip_lefttop, ip_left, {ip_leftcenter,} ip_leftbottom, + cp_rightbottom,cp_right,{cp_rightcenter,}cp_righttop, + //ip_bottomleft,ip_bottom,ip_bottomcenter,ip_bottomright + cp_topright, cp_top, {cp_topcenter,} cp_topleft + ); + + swapcaptionpos: array[captionposty] of captionposty = + (//cp_center,cp_rightbottom,cp_right,cp_rightcenter,cp_righttop, + cp_center,cp_leftbottom,cp_left,{cp_leftcenter,}cp_lefttop, + //cp_topright,cp_top,cp_topcenter,cp_topleft, + cp_bottomright,cp_bottom,{cp_bottomcenter,}cp_bottomleft, + //cp_lefttop,cp_left,cp_leftcenter,cp_leftbottom, + cp_righttop,cp_right,{cp_rightcenter,}cp_rightbottom, + //cp_bottomleft,cp_bottom,cp_bottomcenter,cp_bottomright + cp_topleft,cp_top,{cp_topcenter,}cp_topright + ); + simplecaptionpos: array[captionposty] of captionposty = + (//cp_center,cp_rightbottom,cp_right,cp_rightcenter,cp_righttop, + cp_center,cp_right, cp_right,{cp_right,} cp_right, + //cp_topright,cp_top,cp_topcenter,cp_topleft, + cp_top, cp_top,{cp_top,} cp_top, + //cp_lefttop,cp_left,cp_leftcenter,cp_leftbottom, + cp_left, cp_left,{cp_left,} cp_left, + //cp_bottomleft,cp_bottom,cp_bottomcenter,cp_bottomright + cp_bottom, cp_bottom, {cp_bottom,} cp_bottom + ); + + swapimagepos: array[imageposty] of imageposty = + (//ip_center,ip_centervert,ip_rightbottom,ip_right,ip_rightcenter,ip_righttop, + ip_centervert,ip_center,ip_leftbottom,ip_left,{ip_leftcenter,}ip_lefttop, + //ip_topright, ip_top, ip_topcenter,ip_topleft, + ip_bottomright,ip_bottom,{ip_bottomcenter,}ip_bottomleft, + //ip_lefttop, ip_left, ip_leftcenter,ip_leftbottom, + ip_righttop,ip_right,{ip_rightcenter,}ip_rightbottom, + //ip_bottomleft,ip_bottom,ip_bottomcenter,ip_bottomright + ip_topleft,ip_top,{ip_topcenter,}ip_topright + ); + simpleimagepos: array[imageposty] of imageposty = + (//ip_center,ip_centervert,ip_rightbottom,ip_right,ip_rightcenter,ip_righttop, + ip_center,ip_centervert, ip_right, ip_right,{ip_right,}ip_right, + //ip_topright,ip_top,ip_topcenter,ip_topleft, + ip_top, ip_top,{ip_top,} ip_top, + //ip_lefttop,ip_left,ip_leftcenter,ip_leftbottom, + ip_left, ip_left,{ip_left,}ip_left, + //ip_bottomleft,ip_bottom,ip_bottomcenter,ip_bottomright + ip_bottom, ip_bottom,{ip_bottom,}ip_bottom + ); + +type + sysdndactionty = (sdnda_reject,sdnda_accept,sdnda_finished, + sdnda_begin,sdnda_check,sdnda_drop,sdnda_destroyed); + dndactionty = (dnda_copy,dnda_move,dnda_link,dnda_ask,dnda_private); + dndactionsty = set of dndactionty; +const + firstdndaction = dnda_copy; +type + isysdnd = interface(iobjectlink) + procedure cancelsysdnd; + function getformats: msestringarty; + function getformatistext: booleanarty; + function getactions: dndactionsty; + function geteventintf: ievent; + function convertmimedata(const atypeindex: integer): string; + function convertmimetext(const atypeindex: integer): msestring; + end; + +type + guierrorty = (gue_ok,gue_error, + gue_alreadyregistered,gue_notregistered, + gue_postevent,gue_timer, + gue_createwindow,gue_resizewindow,gue_destroywindow, + gue_windoworder,gue_windownotfound, + gue_windowfocus,gue_illegalstate, + gue_recursivemodal,gue_notmodaltop, +// gue_creategc,gue_createprintergc,gue_createmetafilegc, + gue_destroygc, + gue_show,gue_hide,gue_modalwindow, + gue_init,gue_deinit,gue_thread, + gue_nodisplay,gue_nocolormap,gue_notruecolor,gue_flushgdi, + gue_cannotfocus,gue_invalidwidget, + gue_cursor,gue_rootwidget, + gue_inputmanager,gue_inputcontext,gue_timerlist, + {gue_resnotfound,}gue_capturemouse,gue_mousepos, + gue_registerclass,gue_scroll,gue_clipboard, + gue_recursivetransientfor,gue_notlocked, + gue_characterencoding,gue_invalidstream,gue_invalidcanvas, + gue_notimplemented,gue_notsupported,gue_getchildren,gue_reparent, + gue_docktosyswindow, + gue_notraywindow,gue_sendevent,gue_noshelllib, + gue_noglx,gue_novisual,gue_rendercontext, + gue_nodragpending,gue_index,gue_lockcounterror + ); + + egui = class(eerror) + private + function geterror: guierrorty; + public + constructor create(aerror: guierrorty; atext: string); + property error: guierrorty read geterror; + end; + +const + E_NOINTERFACE = longword($80004002); +var + zerolineworkaround: boolean; + //use one pixel line width instead of 0-line, new X11 servers don't + //draw 0-line endpixels reliable + nozorderhandling: boolean; + norestackwindow: boolean; + stackmodebelowworkaround: boolean; + noreconfigurewmwindow: boolean; + toplevelraise: boolean; + nostaticgravity: boolean; +// exabug: boolean; +// nocreatestaticgravity: boolean; + +procedure guierror(error: guierrorty; text: string = ''); overload; +procedure guierror(error: guierrorty; sender: tobject; + text: string = ''); overload; + +implementation + +uses + mseclasses,msestreaming{,mseapplication,msegui,mseguiintf}; + +const + errortexts: array[guierrorty] of string = + ('','Error', + 'Already registered', + 'Not registered', + 'Can not post event', + 'Can not set timer', + 'Can not create window', + 'Can not resize window', + 'Can not destroy window', + 'Can not set window order', + 'Window not found', + 'Can not set window focus', + 'Illegal state', + 'Recursive modal', + 'Not modal top', + 'Can not destroy gc', + 'Can not show window', + 'Can not hide window', + 'Can not show modal window', + 'Init failed', + 'Deinit failed', + 'Can not create thread', + 'Can not connect to display', + 'Can not create colormap', + 'Color mode must be "TrueColor", "DirectColor" or 8 bit "PseudoColor"', + 'Can not flush gdi', + 'Can not focus', + 'Invalid widget', + 'Can not create cursor', + 'Invalid rootwidget', + 'Invalid inputmanager', + 'Invalid inputcontext', + 'Corrupted timerlist', +{ 'Resource not found',} + 'Can not capture mouse', + 'Can not set mouse pos', + 'Can not register class', + 'Can not scroll window', + 'Clipboard error', + 'Recursive transientfor window', + 'Application not locked', + 'Error in character encoding', + 'Invalid stream', + 'Invalid canvas', + 'Not implemented.', + 'Not supported.', + 'Can not get children.', + 'Can not reparent window.', + 'Can not dock to syswindow.', + 'No tray window.', + 'Can not send event.', + 'Problem with shell library.', + 'GLX extension not supported.', + 'Could not find visual.', + 'Could not create a rendering context.', + 'No drag operation pending.', + 'Invalid index.', + 'Lock count error.' + ); + + +procedure guierror(error: guierrorty; text: string); overload; +begin + if error = gue_ok then begin + exit; + end; + raise egui.create(error,text); +end; + +procedure guierror(error: guierrorty; sender: tobject; + text: string = ''); overload; +begin + if error = gue_ok then begin + exit; + end; + if sender <> nil then begin + text:= sender.classname + ' ' + text; + if sender is tcomponent then begin + text:= text + fullcomponentname(tcomponent(sender)); + end; + end; + guierror(error,text); +end; + +{ egui } + +constructor egui.create(aerror: guierrorty; atext: string); +begin + inherited create(integer(aerror),atext,errortexts); +end; + +function egui.geterror: guierrorty; +begin + result:= guierrorty(ferror); +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/mseguiinifini.pas b/mseide-msegui/lib/common/kernel/mseguiinifini.pas new file mode 100644 index 0000000..40abddd --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseguiinifini.pas @@ -0,0 +1,19 @@ +{ MSEgui Copyright (c) 2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseguiinifini; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +implementation +uses + msegui,mseapplication; +initialization + application.initialize(); +finalization +end. diff --git a/mseide-msegui/lib/common/kernel/mseguiintf.inc b/mseide-msegui/lib/common/kernel/mseguiintf.inc new file mode 100644 index 0000000..e618b32 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseguiintf.inc @@ -0,0 +1,228 @@ +{ MSEgui Copyright (c) 1999-2015 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +function gui_init: guierrorty; +function gui_deinit: guierrorty; +procedure gui_cancelshutdown; +procedure GUI_DEBUGBEGIN; export; +procedure GUI_DEBUGEND; export; + +function gui_registergdi: guierrorty; +function gui_setmainthread: guierrorty; //set mainthread to currentthread +function gui_sethighrestimer(const avalue: boolean): guierrorty; +function gui_grouphideminimizedwindows: boolean; //true for win32 + +//application has to be locked for all following calls +function gui_postevent(event: tmseevent): guierrorty; +function gui_settimer(us: longword): guierrorty; + //send et_timer event after delay of us (micro seconds) + +procedure gui_disconnectmaineventqueue(); //called by application.lock() +procedure gui_connectmaineventqueue(); //called by application.unlock() +function gui_addpollfd(var id: int32; const afd: int32; + const aflags: pollflagsty; + const acallback: pollcallbackty = nil; + const adata: pointer = nil): guierrorty; +function gui_removepollfd(const id: int32): guierrorty; +function gui_setpollfdactive(const id: int32; + const aactive: boolean): guierrorty; + +function gui_hasevent: boolean; //false if no event pending +function gui_getevent: tmseevent; //can be nil +function gui_escapepressed: boolean; +procedure gui_resetescapepressed; + + +function gui_createwindow(const rect: rectty; + var options: internalwindowoptionsty; + var awindow: windowty): guierrorty; +function gui_destroywindow(var awindow: windowty): guierrorty; + //id can be 0 +function gui_getrootwindow(id: winidty = 0): winidty; +function gui_getparentwindow(const awindow: winidty): winidty; +function gui_reparentwindow(const child: winidty; const parent: winidty; + const pos: pointty): guierrorty; +function gui_getchildren(const id: winidty; out children: winidarty): guierrorty; + +function gui_showsysdock(var awindow: windowty): guierrorty; +function gui_hidesysdock(var awindow: windowty): guierrorty; + +function gui_docktosyswindow(var child: windowty; + const akind: syswindowty): guierrorty; + //hides window +//function gui_undockfromsyswindow(var child: windowty): guierrorty; + //hides window + +function gui_traymessage(var awindow: windowty; const message: msestring; + out messageid: longword; + const timeoutms: longword = 0): guierrorty; +function gui_canceltraymessage(var awindow: windowty; + const messageid: longword): guierrorty; +function gui_settrayicon(var awindow: windowty; + const icon,mask: pixmapty): guierrorty; +function gui_settrayhint(var awindow: windowty; + const hint: msestring): guierrorty; + +//function gui_creategc(paintdevice: paintdevicety; const akind: gckindty; +// var gc: gcty; const aprintername: msestring = ''): guierrorty; +//function gui_destroygc(winid: winidty; var gc: gcty): guierrorty; +function gui_flushgdi(const synchronize: boolean = false): guierrorty; +function gui_showwindow(id: winidty): guierrorty; +function gui_hidewindow(id: winidty): guierrorty; +function gui_raisewindow(id: winidty; const topmost: boolean = false): guierrorty; + //windows only +function gui_lowerwindow(id: winidty; const topmost: boolean = false): guierrorty; + //windows only +function gui_stackunderwindow(id: winidty; predecessor: winidty): guierrorty; +function gui_stackoverwindow(id: winidty; predecessor: winidty): guierrorty; +function gui_canstackunder: boolean; //no way found to change stacking order in KDE +function gui_getzorder(const ids: winidarty; out zorders: integerarty): guierrorty; + //topevel -> highest, numbers have not to be contiguous + +function gui_getwindowrect(id: winidty; out rect: rectty): guierrorty; + //screen coordinates +function gui_getwindowpos(id: winidty; out pos: pointty): guierrorty; + //parent window coordinates +function gui_getwindowsize(id: winidty): windowsizety; +function gui_getwindowdesktop(const id: winidty): integer; +function gui_windowvisible(id: winidty): boolean; +function gui_setwindowstate(id: winidty; size: windowsizety; + visible: boolean): guierrorty; +function gui_setwindowcaption(id: winidty; + const caption: msestring): guierrorty; +function gui_setwindowicon(id: winidty; const icon,mask: pixmapty): guierrorty; +function gui_setwindowopacity(id: winidty; const opacity: real): guierrorty; + //empytyreal -> undefined, 0.0-> transparent, 1.1 -> opaque + +function gui_setsizeconstraints(id: winidty; const min,max: sizety): guierrorty; +function gui_reposwindow(id: winidty; const rect: rectty): guierrorty; +function gui_getdecoratedwindowrect(id: winidty; out arect: rectty): guierrorty; +function gui_setdecoratedwindowrect(id: winidty; const rect: rectty; + out clientrect: rectty): guierrorty; +function gui_setembeddedwindowrect(id: winidty; const rect: rectty): guierrorty; +function gui_setwindowfocus(id: winidty): guierrorty; +function gui_setimefocus(var awindow: windowty): guierrorty; +function gui_unsetimefocus(var awindow: windowty): guierrorty; +{ +function gui_windowgetfocus(var awindow: windowty): guierrorty; +function gui_windowloosefocus(var awindow: windowty): guierrorty; +} +function gui_setappfocus(id: winidty): guierrorty; +function gui_minimizeapplication: guierrorty; +function gui_setwindowgroup(id: winidty; group: winidty): guierrorty; +function gui_settransientfor(var awindow: windowty; + const transientfor: winidty): guierrorty; +function gui_movewindowrect(id: winidty; const dist: pointty; + const rect: rectty): guierrorty; +function gui_windowatpos(const pos: pointty): winidty; +function gui_getscreenrect(const id: winidty): rectty; //0 -> virtual screen +function gui_getworkarea(id: winidty): rectty; +procedure gui_getppmm(id: winidty; out appmmwidth,appmmheight: flo64); + //0.0 if not supported + +function gui_setapplicationicon(const icon,mask: pixmapty): guierrorty; +function gui_pidtowinid(const pids: procidarty): winidty; + +function gui_setcursorshape(winid: winidty; shape: cursorshapety): guierrorty; +function gui_getpointerpos: pointty; +function gui_setpointerpos(const pos: pointty): guierrorty; +function gui_movepointer(const dist: pointty): guierrorty; +function gui_grabpointer(id: winidty): guierrorty; +function gui_ungrabpointer: guierrorty; + +function gui_getpixel(const id: winidty; const pos: pointty; + out pixel: pixelty): guierrorty; +function gui_rgbtopixel(rgb: longword): pixelty; +function gui_pixeltorgb(pixel: pixelty): longword; +function gui_graytopixel(gray: byte): pixelty; +function gui_pixeltogray(pixel: pixelty): byte; +//function gui_rgbtocolormappixel(rgb: longword): pixelty; + //neutralizes color in 8bit coler depth +function gui_initcolormap: guierrorty; + +function gui_regiontorects(const aregion: regionty): rectarty; +//procedure gui_changegc(var drawinfo: drawinfoty; const values: gcvaluesty); + +function gui_getdefaultfontnames: defaultfontnamesty; + +function gui_createpixmap(const size: sizety; winid: winidty = 0; + kind: bitmapkindty = bmk_rgb; copyfrom: pixmapty = 0): pixmapty; overload; +function gui_freepixmap(pixmap: pixmapty): gdierrorty; +function gui_getpixmapinfo(var info: pixmapinfoty): gdierrorty; +function gui_createbitmapfromdata(const size: sizety; datapo: pbyte; + msbitfirst: boolean = false; dwordaligned: boolean = false; + bottomup: boolean = false): pixmapty; +function gui_pixmaptoimage(pixmap: pixmapty; out image: imagety; + gchandle: longword): gdierrorty; + //gchandle is used on win32 to select bitmap out of devicecontext, + //can be 0 +function gui_imagetopixmap(const image: imagety; out pixmap: pixmapty; + gchandle: longword): gdierrorty; + //gchandle is used on win32 to select bitmap out of devicecontext, + //can be 0 +function gui_allocimagemem(length: integer): plongwordaty; +procedure gui_freeimagemem(data: plongwordaty); + +//procedure gui_copyarea(var drawinfo: drawinfoty); + +procedure gui_beep; +function gui_copytoclipboard(const value: msestring; + const buffer: clipboardbufferty): guierrorty; +function gui_pastefromclipboard(out value: msestring; + const buffer: clipboardbufferty): guierrorty; +function gui_canpastefromclipboard(const buffer: clipboardbufferty): boolean; + +function gui_sysdnd(const action: sysdndactionty; + const aintf: isysdnd; const arect: rectty; + out aresult: boolean): guierrorty; + //aintf = nil for read actions +function gui_sysdndreaddata(var adata: string; + const typeindex: integer): guierrorty; +function gui_sysdndreadtext(var atext: msestring; + const typeindex: integer): guierrorty; + +function gui_getgdifuncs: pgdifunctionaty; + +(* +procedure gdi_creategc(var drawinfo: drawinfoty); +procedure gdi_destroygc(var drawinfo: drawinfoty); +procedure gdi_changegc(var drawinfo: drawinfoty); +procedure gdi_drawlines(var drawinfo: drawinfoty); +procedure gdi_drawlinesegments(var drawinfo: drawinfoty); +procedure gdi_drawellipse(var drawinfo: drawinfoty); +procedure gdi_drawarc(var drawinfo: drawinfoty); +procedure gdi_fillrect(var drawinfo: drawinfoty); +procedure gdi_fillellipse(var drawinfo: drawinfoty); +procedure gdi_fillarc(var drawinfo: drawinfoty); +procedure gdi_fillpolygon(var drawinfo: drawinfoty); +procedure gdi_drawstring16(var drawinfo: drawinfoty); +procedure gdi_setcliporigin(var drawinfo: drawinfoty); +procedure gdi_createemptyregion(var drawinfo: drawinfoty); +procedure gdi_createrectregion(var drawinfo: drawinfoty); +procedure gdi_createrectsregion(var drawinfo: drawinfoty); +procedure gdi_destroyregion(var drawinfo: drawinfoty); +procedure gdi_copyregion(var drawinfo: drawinfoty); +procedure gdi_moveregion(var drawinfo: drawinfoty); +procedure gdi_regionisempty(var drawinfo: drawinfoty); +procedure gdi_regionclipbox(var drawinfo: drawinfoty); +procedure gdi_regsubrect(var drawinfo: drawinfoty); +procedure gdi_regsubregion(var drawinfo: drawinfoty); +procedure gdi_regaddrect(var drawinfo: drawinfoty); +procedure gdi_regaddregion(var drawinfo: drawinfoty); +procedure gdi_regintersectrect(var drawinfo: drawinfoty); +procedure gdi_regintersectregion(var drawinfo: drawinfoty); +procedure gdi_copyarea(var drawinfo: drawinfoty); +procedure gdi_fonthasglyph(var drawinfo: drawinfoty); +procedure gdi_getfont(var drawinfo: drawinfoty); +procedure gdi_getfonthighres(var drawinfo: drawinfoty); +procedure gdi_freefontdata(var drawinfo: drawinfoty); +procedure gdi_gettext16width(var drawinfo: drawinfoty); +procedure gdi_getchar16widths(var drawinfo: drawinfoty); +procedure gdi_getfontmetrics(var drawinfo: drawinfoty); +*) diff --git a/mseide-msegui/lib/common/kernel/mseguithreadcomp.pas b/mseide-msegui/lib/common/kernel/mseguithreadcomp.pas new file mode 100644 index 0000000..7d4889f --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseguithreadcomp.pas @@ -0,0 +1,37 @@ +{ MSEgui Copyright (c) 2008 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseguithreadcomp; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msethreadcomp,msegui,msetypes{msestrings}; +type + tguithreadcomp = class(tthreadcomp) + private + fdialogtext: msestring; + fdialogcaption: msestring; + public + function runwithwaitdialog: boolean; + //true if not canceled + published + property dialogtext: msestring read fdialogtext write fdialogtext; + property dialogcaption: msestring read fdialogcaption write fdialogcaption; + end; + +implementation + +{ tguithreadcomp } + +function tguithreadcomp.runwithwaitdialog: boolean; +begin + result:= application.waitdialog(self,fdialogtext,fdialogcaption); +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/mseinterfaces.pas b/mseide-msegui/lib/common/kernel/mseinterfaces.pas new file mode 100644 index 0000000..6e0637b --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseinterfaces.pas @@ -0,0 +1,133 @@ +{ MSEgui Copyright (c) 2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseinterfaces; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface + +//Interface UID's for MSEide+MSEgui +type + mseinterfacenumbers = ( +min_iformdesigner, +min_idbeditfieldlink, +min_idbevent, +min_isqlpropertyeditor, +min_imasterlink, +min_imselocate, +min_idbdata, +min_idbeditinfo, +min_ireccontrol, +min_ipersistentfieldsinfo, +min_idatasetsum, +min_ifieldcomponent, +min_imsefield, +min_igetdscontroller, +min_idbcontroller, +min_ilookupbufferfieldinfo, +min_idbparaminfo, +min_idbcolinfo, +min_iblobconnection, +min_igridwidget, +min_iimagelistinfo, +//min_iimagelistinfo, +min_iifilink, +min_iifiexeclink, +min_iififormlink, +min_iifidialoglink, +min_iifidatalink, +min_iifigridlink, +min_iififieldinfo, +min_iififieldsource, +min_iififieldlinksource, +min_iifidataconnection, +min_iifidbdataconnection, +min_iificlient, +min_iificommand, +min_iifitxaction, +min_iifimodulelink, +min_iactionlink, +min_iactivatorclient, +min_istatfile, +min_ibandparent, +min_idocktarget, +min_itabpage, +min_iassistiveclient, +min_iassistiveserver, +min_irecordfield, +min_irecordvaluefield, +min_idockcontroller, +min_iassistiveclientgrid, +min_iassistiveclientmenu, +min_irichstringprop, +min_iassistiveclientedit, +min_iassistiveclientdata, +min_iassistiveclientgridwidget, +min_igriddatalink +); + +const + miid_iformdesigner = 'AA.mse';{0} + miid_idbeditfieldlink = 'gA.mse';{1} + miid_idbevent = 'QA.mse';{2} + miid_isqlpropertyeditor = 'wA.mse';{3} + miid_imasterlink = 'IA.mse';{4} + miid_imselocate = 'oA.mse';{5} + miid_idbdata = 'YA.mse';{6} + miid_idbeditinfo = '4A.mse';{7} + miid_ireccontrol = 'EA.mse';{8} + miid_ipersistentfieldsinfo = 'kA.mse';{9} + miid_idatasetsum = 'UA.mse';{10} + miid_ifieldcomponent = '0A.mse';{11} + miid_imsefield = 'MA.mse';{12} + miid_igetdscontroller = 'sA.mse';{13} + miid_idbcontroller = 'cA.mse';{14} + miid_ilookupbufferfieldinfo = '8A.mse';{15} + miid_idbparaminfo = 'CA.mse';{16} + miid_idbcolinfo = 'iA.mse';{17} + miid_iblobconnection = 'SA.mse';{18} + miid_igridwidget = 'yA.mse';{19} + miid_iimagelistinfo = 'KA.mse';{20} +// miid_iimagelistinfo = 'qA.mse';{21} + miid_iifilink = 'aA.mse';{22} + miid_iifiexeclink = '6A.mse';{23} + miid_iififormlink = 'GA.mse';{24} + miid_iifidialoglink = 'mA.mse';{25} + miid_iifidatalink = 'WA.mse';{26} + miid_iifigridlink = '2A.mse';{27} + miid_iififieldinfo = 'OA.mse';{28} + miid_iififieldsource = 'uA.mse';{29} + miid_iififieldlinksource = 'eA.mse';{30} + miid_iifidataconnection = '+A.mse';{31} + miid_iifidbdataconnection = 'BA.mse';{32} + miid_iificlient = 'hA.mse';{33} + miid_iificommand = 'RA.mse';{34} + miid_iifitxaction = 'xA.mse';{35} + miid_iifimodulelink = 'JA.mse';{36} + miid_iactionlink = 'pA.mse';{37} + miid_iactivatorclient = 'ZA.mse';{38} + miid_istatfile = '5A.mse';{39} + miid_ibandparent = 'FA.mse';{40} + miid_idocktarget = 'lA.mse';{41} + miid_itabpage = 'VA.mse';{42} + miid_idbdispfieldlink = '1A.mse';{43} + miid_iassistiveclient = 'NA.mse';{44} + miid_iassistiveserver = 'tA.mse';{45} + miid_irecordfield = 'dA.mse';{46} + miid_irecordvaluefield = '9A.mse';{47} + miid_idockcontroller = 'DA.mse';{48} + miid_iassistiveclientgrid = 'jA.mse';{49} + miid_iassistiveclientmenu = 'TA.mse';{50} + miid_irichstringprop = 'zA.mse';{51} + miid_iassistiveclientedit = 'LA.mse';{52} + miid_iassistiveclientdata = 'rA.mse';{53} + miid_iassistiveclientgridwidget = + 'bA.mse';{54} + miid_iggriddatalink = '7A.mse';{55} +implementation +end. diff --git a/mseide-msegui/lib/common/kernel/msekeyboard.pas b/mseide-msegui/lib/common/kernel/msekeyboard.pas new file mode 100644 index 0000000..a3c9127 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msekeyboard.pas @@ -0,0 +1,327 @@ +{ MSEgui Copyright (c) 1999-2010 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msekeyboard; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface +uses + msetypes{,msestrings}; +type + keyty = ( + key_none = $0000, + key_Space = $0020, // 7 bit printable ASCII +{$ifdef FPC}{$notes off}{$endif} + key_Any = Key_Space, +{$ifdef FPC}{$notes on}{$endif} + key_Exclam = $0021, + key_QuoteDbl = $0022, + key_NumberSign = $0023, + key_Dollar = $0024, + key_Percent = $0025, + key_Ampersand = $0026, + key_Apostrophe = $0027, + key_ParenLeft = $0028, + key_ParenRight = $0029, + key_Asterisk = $002a, + key_Plus = $002b, + key_Comma = $002c, + key_Minus = $002d, + key_Period = $002e, + key_Slash = $002f, + key_0 = $0030, + key_1 = $0031, + key_2 = $0032, + key_3 = $0033, + key_4 = $0034, + key_5 = $0035, + key_6 = $0036, + key_7 = $0037, + key_8 = $0038, + key_9 = $0039, + key_Colon = $003a, + key_Semicolon = $003b, + key_Less = $003c, + key_Equal = $003d, + key_Greater = $003e, + key_Question = $003f, + key_At = $0040, + key_A = $0041, + key_B = $0042, + key_C = $0043, + key_D = $0044, + key_E = $0045, + key_F = $0046, + key_G = $0047, + key_H = $0048, + key_I = $0049, + key_J = $004a, + key_K = $004b, + key_L = $004c, + key_M = $004d, + key_N = $004e, + key_O = $004f, + key_P = $0050, + key_Q = $0051, + key_R = $0052, + key_S = $0053, + key_T = $0054, + key_U = $0055, + key_V = $0056, + key_W = $0057, + key_X = $0058, + key_Y = $0059, + key_Z = $005a, + key_BracketLeft = $005b, + key_Backslash = $005c, + key_BracketRight = $005d, + key_AsciiCircum = $005e, + key_Underscore = $005f, + key_QuoteLeft = $0060, + key_BraceLeft = $007b, + key_Bar = $007c, + key_BraceRight = $007d, + key_AsciiTilde = $007e, + + // Latin 1 codes adapted from X: keysymdef.h,v 1.21 94/08/28 16:17:06 + + key_nobreakspace = $00a0, + key_exclamdown = $00a1, + key_cent = $00a2, + key_sterling = $00a3, + key_currency = $00a4, + key_yen = $00a5, + key_brokenbar = $00a6, + key_section = $00a7, + key_diaeresis = $00a8, + key_copyright = $00a9, + key_ordfeminine = $00aa, + key_guillemotleft = $00ab, // left angle quotation mark + key_notsign = $00ac, + key_hyphen = $00ad, + key_registered = $00ae, + key_macron = $00af, + key_degree = $00b0, + key_plusminus = $00b1, + key_twosuperior = $00b2, + key_threesuperior = $00b3, + key_acute = $00b4, + key_mu = $00b5, + key_paragraph = $00b6, + key_periodcentered = $00b7, + key_cedilla = $00b8, + key_onesuperior = $00b9, + key_masculine = $00ba, + key_guillemotright = $00bb, // right angle quotation mark + key_onequarter = $00bc, + key_onehalf = $00bd, + key_threequarters = $00be, + key_questiondown = $00bf, + key_Agrave = $00c0, + key_Aacute = $00c1, + key_Acircumflex = $00c2, + key_Atilde = $00c3, + key_Adiaeresis = $00c4, + key_Aring = $00c5, + key_AE = $00c6, + key_Ccedilla = $00c7, + key_Egrave = $00c8, + key_Eacute = $00c9, + key_Ecircumflex = $00ca, + key_Ediaeresis = $00cb, + key_Igrave = $00cc, + key_Iacute = $00cd, + key_Icircumflex = $00ce, + key_Idiaeresis = $00cf, + key_ETH = $00d0, + key_Ntilde = $00d1, + key_Ograve = $00d2, + key_Oacute = $00d3, + key_Ocircumflex = $00d4, + key_Otilde = $00d5, + key_Odiaeresis = $00d6, +// key_multiply = $00d7, -> key_asterisk + key_Ooblique = $00d8, + key_Ugrave = $00d9, + key_Uacute = $00da, + key_Ucircumflex = $00db, + key_Udiaeresis = $00dc, + key_Yacute = $00dd, + key_THORN = $00de, + key_ssharp = $00df, + key_agrave_lower = $00e0, + key_aacute_lower = $00e1, + key_acircumflex_lower = $00e2, + key_atilde_lower = $00e3, + key_adiaeresis_lower = $00e4, + key_aring_lower = $00e5, + key_ae_lower = $00e6, + key_ccedilla_lower = $00e7, + key_egrave_lower = $00e8, + key_eacute_lower = $00e9, + key_ecircumflex_lower = $00ea, + key_ediaeresis_lower = $00eb, + key_igrave_lower = $00ec, + key_iacute_lower = $00ed, + key_icircumflex_lower = $00ee, + key_idiaeresis_lower = $00ef, + key_eth_lower = $00f0, + key_ntilde_lower = $00f1, + key_ograve_lower = $00f2, + key_oacute_lower = $00f3, + key_ocircumflex_lower = $00f4, + key_otilde_lower = $00f5, + key_odiaeresis_lower = $00f6, + key_division = $00f7, + key_oslash = $00f8, + key_ugrave_lower = $00f9, + key_uacute_lower = $00fa, + key_ucircumflex_lower = $00fb, + key_udiaeresis_lower = $00fc, + key_yacute_lower = $00fd, + key_thorn_lower = $00fe, + key_ydiaeresis = $00ff, + + key_Escape = $0100, // misc keys + key_Tab = $0101, + key_Backtab = $0102, + key_Backspace = $0103, + key_Return = $0104, + // key_Enter = $0105, -> key_return + key_Insert = $0106, + key_Delete = $0107, + key_Pause = $0108, + key_Print = $0109, + key_SysReq = $010a, + key_Home = $0110, // cursor movement + key_End = $0111, + key_Left = $0112, + key_Up = $0113, + key_Right = $0114, + key_Down = $0115, + key_Prior = $0116, + Key_PageUp = Key_Prior, + key_Next = $0117, + Key_PageDown = Key_Next, + key_clear = $0118, + key_decimal = $0119, + + key_Shift = $0120, // modifiers + key_Control = $0121, + key_Meta = $0122, + key_Alt = $0123, + key_CapsLock = $0124, + key_NumLock = $0125, + key_ScrollLock = $0126, + key_AltGr = $0127, + key_F1 = $0130, // function keys + key_F2 = $0131, + key_F3 = $0132, + key_F4 = $0133, + key_F5 = $0134, + key_F6 = $0135, + key_F7 = $0136, + key_F8 = $0137, + key_F9 = $0138, + key_F10 = $0139, + key_F11 = $013a, + key_F12 = $013b, + key_F13 = $013c, + key_F14 = $013d, + key_F15 = $013e, + key_F16 = $013f, + key_F17 = $0140, + key_F18 = $0141, + key_F19 = $0142, + key_F20 = $0143, + key_F21 = $0144, + key_F22 = $0145, + key_F23 = $0146, + key_F24 = $0147, + key_F25 = $0148, // F25 .. F35 only on X11 + key_F26 = $0149, + key_F27 = $014a, + key_F28 = $014b, + key_F29 = $014c, + key_F30 = $014d, + key_F31 = $014e, + key_F32 = $014f, + key_F33 = $0150, + key_F34 = $0151, + key_F35 = $0152, + key_Super = $0153, // extra keys +// key_Super_R = $0154, + key_Menu = $0155, + key_Hyper = $0156, +// key_Hyper_R = $0157, + key_Help = $0158, + +// key_wheelup = $1800, +// key_wheeldown = $1801, + + key_unknown = $ffff + ); +const + key_modpad = $0800; //ored for shortcut in taction + key_modshift = $2000; + key_modctrl = $4000; + key_modshiftctrl = $6000; + key_modalt = $8000; + key_modshiftalt = $a000; + key_modpadshift = $2000 or key_modpad; + key_modpadctrl = $4000 or key_modpad; + key_modpadshiftctrl = $6000 or key_modpad; + key_modpadalt = $8000 or key_modpad; + key_modpadshiftalt = $a000 or key_modpad; + + padcharkeynames: array[key_asterisk..key_slash] of msestring = + ('Asterisk','Plus','Comma','Minus','Period','Slash'); + padspecialkeynames: array[key_decimal..key_decimal] of msestring = + ('Decimal'); + misckeynames: array[key_escape..key_sysreq] of msestring = + ('Escape','Tab','Backtab','Backspace','Return','Enter', + 'Insert','Delete','Pause','Print','SysReq'); + cursorkeynames: array[key_home..key_pagedown] of msestring = + ('Home','End','Left','Up','Right','Down','PageUp','PageDown'); + shortmisckeynames: array[key_escape..key_sysreq] of msestring = + ('Esc','Tab','Backtab','Back','Ret','Enter', + 'Ins','Del','Pause','Print','SysReq'); + shortcursorkeynames: array[key_home..key_pagedown] of msestring = + ('Home','End','Left','Up','Right','Down','PgUp','PgDown'); +type + specialshortcutty = (sso_menu,sso_help,sso_clear); +const + specialkeys: array[specialshortcutty] of keyty = (key_menu,key_help,key_clear); + specialkeynames: array[specialshortcutty] of msestring = ('Menu','Help','Clear'); + spacekeyname = 'Space'; + +function keytomsechar(key: keyty): msechar; //only 0..9, a..z + +implementation + +function keytomsechar(key: keyty): msechar; +begin + if (key >= key_0) and (key <= key_9) then begin + result:= msechar(ord(msechar('0')) + ord(key)-ord(key_0)); + end + else begin + if (key >= key_a) and (key <= key_z) then begin + result:= msechar(ord(msechar('a')) + ord(key)-ord(key_a)); + end + else begin + result:= #0; + end; + end; +end; + +end. + + + diff --git a/mseide-msegui/lib/common/kernel/mselibc.pas b/mseide-msegui/lib/common/kernel/mselibc.pas new file mode 100644 index 0000000..cd6bee5 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mselibc.pas @@ -0,0 +1,3282 @@ +unit mselibc; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + {$ifdef FPC}initc,{$endif}msectypes{$ifndef FPC},msetypes{$endif}; + +//todo: remove not used definitions, use msectypes + +const +{$ifdef FPC} + clib = 'c'; + threadslib = 'pthread'; +{$else} + clib = 'libc.so.6'; + threadslib = 'libpthread.so.0'; +{$endif} + +{$ifdef linux} + shmlib = 'rt'; +{$else} + shmlib = clib; +{$endif} + +{$packrecords c} + +type + +//from bits/typesizes.h + +{$ifdef linux} + __dev_t = __UQUAD_TYPE; +{$else} + __dev_t = cuint32; +{$endif} + __uid_t = __U32_TYPE; + __gid_t = __U32_TYPE; + __ino_t = __ULONGWORD_TYPE; + __ino64_t = __UQUAD_TYPE; + __mode_t = __U32_TYPE; + __nlink_t = __UWORD_TYPE; + __off_t = __SLONGWORD_TYPE; + __off64_t = __SQUAD_TYPE; + __pid_t = __S32_TYPE; + __rlim_t = __ULONGWORD_TYPE; + __rlim64_t = __UQUAD_TYPE; + __blkcnt_t = __SLONGWORD_TYPE; + __blkcnt64_t = __SQUAD_TYPE; + __fsblkcnt_t = __ULONGWORD_TYPE; + __fsblkcnt64_t = __UQUAD_TYPE; + __fsfilcnt_t = __ULONGWORD_TYPE; + __fsfilcnt64_t = __UQUAD_TYPE; + __id_t = __U32_TYPE; + __clock_t = __SLONGWORD_TYPE; +{$ifdef linux} + __time_t = __SLONGWORD_TYPE; +{$else} + {$ifdef CPU64} + __time_t = cint64; + {$else} + __time_t = cint32; + {$endif} +{$endif} + __useconds_t = __U32_TYPE; + __suseconds_t = __SLONGWORD_TYPE; + __daddr_t = __S32_TYPE; + __swblk_t = __SLONGWORD_TYPE; + __key_t = __S32_TYPE; + __clockid_t = __S32_TYPE; + __timer_t = pointer; //void *; + __blksize_t = __SLONGWORD_TYPE; + __fsid_t = record + __val: array[0..1] of longint; + end; +// __struct { int __val[2]; }; + __ssize_t = __SWORD_TYPE; + + __fd_mask = __ULONGWORD_TYPE; //dWord; + {$ifdef CPU64} + __ipc_pid_t = integer; + {$else} + __ipc_pid_t = word; + {$endif} + __caddr_t = ^char; + +type + __ptr_t = Pointer; + P__ptr_t = ^__ptr_t; + ptrdiff_t = Integer; + __long_double_t = Extended; + P__long_double_t = ^__long_double_t; +// size_t = longword; + Psize_t = ^size_t; +// UInt64 = 0..High(Int64); // Must be unsigned. + wchar_t = widechar; + Pwchar_t = ^wchar_t; + PPwchar_t = ^Pwchar_t; + PPByte = ^PByte; + PPPChar = ^PPChar; + + __u_char = byte; + __u_short = word; + __u_int = dword; + __u_long = dword; + __u_quad_t = qword; + __quad_t = int64; + + __int8_t = char; + __uint8_t = byte; + __int16_t = smallint; + __uint16_t = word; + __int32_t = longint; + __uint32_t = dword; + __int64_t = Int64; + __uint64_t = Qword; + + __qaddr_t = __quad_t; +// __dev_t = __u_quad_t; +// __uid_t = __u_int; +// __gid_t = __u_int; +// __ino_t = __u_long; +// __mode_t = __u_int; +// __nlink_t = __u_int; +// __off_t = longint; + __loff_t = __quad_t; +// __pid_t = longint; +// __ssize_t = longint; +// __rlim_t = __u_long; +// __rlim64_t = __u_quad_t; +// __id_t = __u_int; +// __fsid_t = record +// __val : array[0..1] of longint; +// end; + +{ + __daddr_t = longint; + __caddr_t = char; + __time_t = longint; + __useconds_t = dword; + __suseconds_t = longint; + __swblk_t = longint; + __clock_t = longint; + __clockid_t = longint; + __timer_t = longint; + __fd_mask = dWord; +} + int64_t = Int64; + uint8_t = byte; + + uint16_t = word; + uint32_t = dword; + uint64_t = qword; + int_least8_t = char; + int_least16_t = smallint; + int_least32_t = longint; + int_least64_t = int64; + uint_least8_t = byte; + uint_least16_t = word; + uint_least32_t = dword; + uint_least64_t = qword; + + int_fast8_t = shortint; + int_fast16_t = longint; + int_fast32_t = longint; + int_fast64_t = int64; + uint_fast8_t = byte; + + uint_fast16_t = dword; + uint_fast32_t = dword; + uint_fast64_t = qword; + +// intptr_t = longint; +// uintptr_t = dword; + intptr_t = ptrint; + uintptr_t = ptruint; + intmax_t = Int64; + uintmax_t = QWord; + + timespec = record + tv_sec: __time_t; + tv_nsec: clong; + end; + + TTimeSpec = timespec; + PTimeSpec = ^TTimeSpec; + +//ioctrl +const + TCGETS = $5401; + TCSETS = $5402; + TCSETSW = $5403; + TCSETSF = $5404; + TCGETA = $5405; + TCSETA = $5406; + TCSETAW = $5407; + TCSETAF = $5408; + TCSBRK = $5409; + TCXONC = $540A; + TCFLSH = $540B; + TIOCEXCL = $540C; + TIOCNXCL = $540D; + TIOCSCTTY = $540E; + TIOCGPGRP = $540F; + TIOCSPGRP = $5410; + TIOCOUTQ = $5411; + TIOCSTI = $5412; + TIOCGWINSZ = $5413; + TIOCSWINSZ = $5414; + TIOCMGET = $5415; + TIOCMBIS = $5416; + TIOCMBIC = $5417; + TIOCMSET = $5418; + TIOCGSOFTCAR = $5419; + TIOCSSOFTCAR = $541A; + FIONREAD = $541B; + TIOCINQ = FIONREAD; + TIOCLINUX = $541C; + TIOCCONS = $541D; + TIOCGSERIAL = $541E; + TIOCSSERIAL = $541F; + TIOCPKT = $5420; + FIONBIO = $5421; + TIOCNOTTY = $5422; + TIOCSETD = $5423; + TIOCGETD = $5424; + TCSBRKP = $5425; + TIOCTTYGSTRUCT = $5426; + TIOCSBRK = $5427; + TIOCCBRK = $5428; + TIOCGSID = $5429; + +const + FIONCLEX = $5450; + FIOCLEX = $5451; + FIOASYNC = $5452; + TIOCSERCONFIG = $5453; + TIOCSERGWILD = $5454; + TIOCSERSWILD = $5455; + TIOCGLCKTRMIOS = $5456; + TIOCSLCKTRMIOS = $5457; + TIOCSERGSTRUCT = $5458; + TIOCSERGETLSR = $5459; + TIOCSERGETMULTI = $545A; + TIOCSERSETMULTI = $545B; + TIOCMIWAIT = $545C; + TIOCGICOUNT = $545D; + TIOCGHAYESESP = $545E; + TIOCSHAYESESP = $545F; + TIOCPKT_DATA = 0; + TIOCPKT_FLUSHREAD = 1; + TIOCPKT_FLUSHWRITE = 2; + TIOCPKT_STOP = 4; + TIOCPKT_START = 8; + TIOCPKT_NOSTOP = 16; + TIOCPKT_DOSTOP = 32; + TIOCSER_TEMT = $01; + +const + {$ifdef linux} + EPERM = 1; + ENOENT = 2; + ESRCH = 3; + EINTR = 4; + EIO = 5; + ENXIO = 6; + E2BIG = 7; + ENOEXEC = 8; + EBADF = 9; + ECHILD = 10; + EAGAIN = 11; + ENOMEM = 12; + EACCES = 13; + EFAULT = 14; + ENOTBLK = 15; + EBUSY = 16; + EEXIST = 17; + EXDEV = 18; + ENODEV = 19; + ENOTDIR = 20; + EISDIR = 21; + EINVAL = 22; + ENFILE = 23; + EMFILE = 24; + ENOTTY = 25; + ETXTBSY = 26; + EFBIG = 27; + ENOSPC = 28; + ESPIPE = 29; + EROFS = 30; + EMLINK = 31; + EPIPE = 32; + EDOM = 33; + ERANGE = 34; + EDEADLK = 35; + ENAMETOOLONG = 36; + ENOLCK = 37; + ENOSYS = 38; + ENOTEMPTY = 39; + ELOOP = 40; + EWOULDBLOCK = EAGAIN; + ENOMSG = 42; + EIDRM = 43; + ECHRNG = 44; + EL2NSYNC = 45; + EL3HLT = 46; + EL3RST = 47; + ELNRNG = 48; + EUNATCH = 49; + ENOCSI = 50; + EL2HLT = 51; + EBADE = 52; + EBADR = 53; + EXFULL = 54; + ENOANO = 55; + EBADRQC = 56; + EBADSLT = 57; + EDEADLOCK = EDEADLK; + EBFONT = 59; + ENOSTR = 60; + ENODATA = 61; + ETIME = 62; + ENOSR = 63; + ENONET = 64; + ENOPKG = 65; + EREMOTE = 66; + ENOLINK = 67; + EADV = 68; + ESRMNT = 69; + ECOMM = 70; + EPROTO = 71; + EMULTIHOP = 72; + EDOTDOT = 73; + EBADMSG = 74; + EOVERFLOW = 75; + ENOTUNIQ = 76; + EBADFD = 77; + EREMCHG = 78; + ELIBACC = 79; + ELIBBAD = 80; + ELIBSCN = 81; + ELIBMAX = 82; + ELIBEXEC = 83; + EILSEQ = 84; + ERESTART = 85; + ESTRPIPE = 86; + EUSERS = 87; + ENOTSOCK = 88; + EDESTADDRREQ = 89; + EMSGSIZE = 90; + EPROTOTYPE = 91; + ENOPROTOOPT = 92; + EPROTONOSUPPORT = 93; + ESOCKTNOSUPPORT = 94; + EOPNOTSUPP = 95; + EPFNOSUPPORT = 96; + EAFNOSUPPORT = 97; + EADDRINUSE = 98; + EADDRNOTAVAIL = 99; + ENETDOWN = 100; + ENETUNREACH = 101; + ENETRESET = 102; + ECONNABORTED = 103; + ECONNRESET = 104; + ENOBUFS = 105; + EISCONN = 106; + ENOTCONN = 107; + ESHUTDOWN = 108; + ETOOMANYREFS = 109; + ETIMEDOUT = 110; + ECONNREFUSED = 111; + EHOSTDOWN = 112; + EHOSTUNREACH = 113; + EALREADY = 114; + EINPROGRESS = 115; + ESTALE = 116; + EUCLEAN = 117; + ENOTNAM = 118; + ENAVAIL = 119; + EISNAM = 120; + EREMOTEIO = 121; + EDQUOT = 122; + ENOMEDIUM = 123; + EMEDIUMTYPE = 124; + + {$else} + + EPERM = 1; //* Operation not permitted */ + ENOENT = 2; //* No such file or directory */ + ESRCH = 3; //* No such process */ + EINTR = 4; //* Interrupted system call */ + EIO = 5; //* Input/output error */ + ENXIO = 6; //* Device not configured */ + E2BIG = 7; //* Argument list too long */ + ENOEXEC = 8; //* Exec format error */ + EBADF = 9; //* Bad file descriptor */ + ECHILD = 10; //* No child processes */ + EDEADLK = 11; //* Resource deadlock avoided */ + //* 11 was EAGAIN */ + ENOMEM = 12; //* Cannot allocate memory */ + EACCES = 13; //* Permission denied */ + EFAULT = 14; //* Bad address */ +{$ifndef _POSIX_SOURCE} + ENOTBLK = 15; //* Block device required */ +{$endif} + EBUSY = 16; //* Device busy */ + EEXIST = 17; //* File exists */ + EXDEV = 18; //* Cross-device link */ + ENODEV = 19; //* Operation not supported by device */ + ENOTDIR = 20; //* Not a directory */ + EISDIR = 21; //* Is a directory */ + EINVAL = 22; //* Invalid argument */ + ENFILE = 23; //* Too many open files in system */ + EMFILE = 24; //* Too many open files */ + ENOTTY = 25; //* Inappropriate ioctl for device */ +{$ifndef _POSIX_SOURCE} + ETXTBSY = 26; //* Text file busy */ +{$endif} + EFBIG = 27; //* File too large */ + ENOSPC = 28; //* No space left on device */ + ESPIPE = 29; //* Illegal seek */ + EROFS = 30; //* Read-only filesystem */ + EMLINK = 31; //* Too many links */ + EPIPE = 32; //* Broken pipe */ + +//* math software */ + EDOM = 33; //* Numerical argument out of domain */ + ERANGE = 34; //* Result too large */ + +//* non-blocking and interrupt i/o */ + EAGAIN = 35; //* Resource temporarily unavailable */ +{$ifndef _POSIX_SOURCE} + EWOULDBLOCK = EAGAIN; //* Operation would block */ + EINPROGRESS = 36; //* Operation now in progress */ + EALREADY = 37; //* Operation already in progress */ + +//* ipc/network software -- argument errors */ + ENOTSOCK = 38; //* Socket operation on non-socket */ + EDESTADDRREQ = 39; //* Destination address required */ + EMSGSIZE = 40; //* Message too long */ + EPROTOTYPE = 41; //* Protocol wrong type for socket */ + ENOPROTOOPT = 42; //* Protocol not available */ + EPROTONOSUPPORT = 43; //* Protocol not supported */ + ESOCKTNOSUPPORT = 44; //* Socket type not supported */ + EOPNOTSUPP = 45; //* Operation not supported */ + ENOTSUP = EOPNOTSUPP; //* Operation not supported */ + EPFNOSUPPORT = 46; //* Protocol family not supported */ + EAFNOSUPPORT = 47; //* Address family not supported by protocol family */ + EADDRINUSE = 48; //* Address already in use */ + EADDRNOTAVAIL = 49; //* Can't assign requested address */ + +//* ipc/network software -- operational errors */ + ENETDOWN = 50; //* Network is down */ + ENETUNREACH = 51; //* Network is unreachable */ + ENETRESET = 52; //* Network dropped connection on reset */ + ECONNABORTED = 53; //* Software caused connection abort */ + ECONNRESET = 54; //* Connection reset by peer */ + ENOBUFS = 55; //* No buffer space available */ + EISCONN = 56; //* Socket is already connected */ + ENOTCONN = 57; //* Socket is not connected */ + ESHUTDOWN = 58; //* Can't send after socket shutdown */ + ETOOMANYREFS = 59; //* Too many references: can't splice */ + ETIMEDOUT = 60; //* Operation timed out */ + ECONNREFUSED = 61; //* Connection refused */ + + ELOOP = 62; //* Too many levels of symbolic links */ +{$endif /* _POSIX_SOURCE */} + ENAMETOOLONG = 63; //* File name too long */ + +//* should be rearranged */ +{$ifndef _POSIX_SOURCE} + EHOSTDOWN = 64; //* Host is down */ + EHOSTUNREACH = 65; //* No route to host */ +{$endif /* _POSIX_SOURCE */} + ENOTEMPTY = 66; //* Directory not empty */ + +//* quotas & mush */ +{$ifndef _POSIX_SOURCE} + EPROCLIM = 67; //* Too many processes */ + EUSERS = 68; //* Too many users */ + EDQUOT = 69; //* Disc quota exceeded */ + +//* Network File System */ + ESTALE = 70; //* Stale NFS file handle */ + EREMOTE = 71; //* Too many levels of remote in path */ + EBADRPC = 72; //* RPC struct is bad */ + ERPCMISMATCH = 73; //* RPC version wrong */ + EPROGUNAVAIL = 74; //* RPC prog. not avail */ + EPROGMISMATCH = 75; //* Program version wrong */ + EPROCUNAVAIL = 76; //* Bad procedure for program */ +{$endif /* _POSIX_SOURCE */} + + ENOLCK = 77; //* No locks available */ + ENOSYS = 78; //* Function not implemented */ + +{$ifndef _POSIX_SOURCE} + EFTYPE = 79; //* Inappropriate file type or format */ + EAUTH = 80; //* Authentication error */ + ENEEDAUTH = 81; //* Need authenticator */ + EIDRM = 82; //* Identifier removed */ + ENOMSG = 83; //* No message of desired type */ + EOVERFLOW = 84; //* Value too large to be stored in data type */ + ECANCELED = 85; //* Operation canceled */ + EILSEQ = 86; //* Illegal byte sequence */ + ENOATTR = 87; //* Attribute not found */ + + EDOOFUS = 88; //* Programming error */ +{$endif /* _POSIX_SOURCE */} + + EBADMSG = 89; //* Bad message */ + EMULTIHOP = 90; //* Multihop attempted */ + ENOLINK = 91; //* Link has been severed */ + EPROTO = 92; //* Protocol error */ + +{$ifndef _POSIX_SOURCE} + ENOTCAPABLE = 93; //* Capabilities insufficient */ + ECAPMODE = 94; //* Not permitted in capability mode */ + ENOTRECOVERABLE = 95; //* State not recoverable */ + EOWNERDEAD = 96; //* Previous owner died */ +{$endif /* _POSIX_SOURCE */} + +{$ifndef _POSIX_SOURCE} + ELAST = 96; //* Must be equal largest errno */ +{$endif /* _POSIX_SOURCE */} + +{$endif} + + +{$ifdef linux} + O_ACCMODE = $00003; + O_RDONLY = $00000; + O_WRONLY = $00001; + O_RDWR = $00002; + O_CREAT = $00040;//&00100; + O_EXCL = $00080;//&00200; + O_NOCTTY = $00100;//&00400; + O_TRUNC = $00200;//&01000; + O_APPEND = $00400;//&02000; + O_NONBLOCK = $00800;//&04000; + O_NDELAY = O_NONBLOCK; + O_SYNC = $01000;//&010000; + O_FSYNC = O_SYNC; + O_ASYNC = $02000;//&020000; + O_CLOEXEC = $80000; + + O_DIRECT = $04000;//&0040000; + O_DIRECTORY = $10000;//&0200000; + O_NOFOLLOW = $20000;//&0400000; + + O_DSYNC = O_SYNC; + O_RSYNC = O_SYNC; + + O_LARGEFILE = $08000;//&0100000; + +{$else} + O_RDONLY = $0000; //* open for reading only */ + O_WRONLY = $0001; //* open for writing only */ + O_RDWR = $0002; //* open for reading and writing */ + O_ACCMODE = $0003; //* mask for above modes */ + + O_NONBLOCK = $0004; //* no delay */ + O_APPEND = $0008; //* set append mode */ + O_SHLOCK = $0010; //* open with shared file lock */ + O_EXLOCK = $0020; //* open with exclusive file lock */ + O_ASYNC = $0040; //* signal pgrp when data ready */ + O_FSYNC = $0080; //* synchronous writes */ + O_SYNC = $0080; //* POSIX synonym for O_FSYNC */ + O_NOFOLLOW = $0100; //* don't follow symlinks */ + O_CREAT = $0200; //* create if nonexistent */ + O_TRUNC = $0400; //* truncate to zero length */ + O_EXCL = $0800; //* error if already exists */ + +//* Defined by POSIX 1003.1; BSD default, but must be distinct from O_RDONLY. */ + O_NOCTTY = $8000; //* don't assign controlling terminal */ + +//* Attempt to bypass buffer cache */ + O_DIRECT = $00010000; + +//* Defined by POSIX Extended API Set Part 2 */ + O_DIRECTORY = $00020000; //* Fail if not directory */ + O_EXEC = $00040000; //* Open for execute only */ + +//* Defined by POSIX 1003.1-2008; BSD default, but reserve for future use. */ + O_TTY_INIT = $00080000; //* Restore default termios attributes */ + + O_CLOEXEC = $00100000; + +{$endif} + +{$ifdef linux} + F_DUPFD = 0; + F_GETFD = 1; + F_SETFD = 2; + F_GETFL = 3; + F_SETFL = 4; + + F_GETLK = 5; + F_SETLK = 6; + F_SETLKW = 7; + + F_GETLK64 = 12; + F_SETLK64 = 13; + F_SETLKW64 = 14; + + F_SETOWN = 8; + F_GETOWN = 9; + + F_SETSIG = 10; + F_GETSIG = 11; + + F_SETLEASE = 1024; + F_GETLEASE = 1025; + F_NOTIFY = 1026; + + FD_CLOEXEC = 1; + F_RDLCK = 0; + F_WRLCK = 1; + F_UNLCK = 2; + F_EXLCK = 4; + F_SHLCK = 8; + +{$else} + + F_DUPFD = 0; //* duplicate file descriptor */ + F_GETFD = 1; //* get file descriptor flags */ + F_SETFD = 2; //* set file descriptor flags */ + F_GETFL = 3; //* get file status flags */ + F_SETFL = 4; //* set file status flags */ + F_GETOWN = 5; //* get SIGIO/SIGURG proc/pgrp */ + F_SETOWN = 6; //* set SIGIO/SIGURG proc/pgrp */ + F_OGETLK = 7; //* get record locking information */ + F_OSETLK = 8; //* set record locking information */ + F_OSETLKW = 9; //* F_SETLK; wait if blocked */ + F_DUP2FD = 10; //* duplicate file descriptor to arg */ + F_GETLK = 11; //* get record locking information */ + F_SETLK = 12; //* set record locking information */ + F_SETLKW = 13; //* F_SETLK; wait if blocked */ + F_SETLK_REMOTE = 14; //* debugging support for remote locks */ + F_READAHEAD = 15; //* read ahead */ + F_RDAHEAD = 16; //* Darwin compatible read ahead */ + F_DUPFD_CLOEXEC = 17; //* Like F_DUPFD, but FD_CLOEXEC is set */ + F_DUP2FD_CLOEXEC = 18; //* Like F_DUP2FD, but FD_CLOEXEC is set */ + +//* file descriptor flags (F_GETFD, F_SETFD) */ + FD_CLOEXEC = 1; //* close-on-exec flag */ + +//* record locking flags (F_GETLK, F_SETLK, F_SETLKW) */ + F_RDLCK = 1; //* shared or read lock */ + F_UNLCK = 2; //* unlock */ + F_WRLCK = 3; //* exclusive or write lock */ + F_UNLCKSYS = 4; //* purge locks for a given system ID */ + F_CANCEL = 5; //* cancel an async lock request */ + F_WAIT = $010; //* Wait until lock is granted */ + F_FLOCK = $020; //* Use flock(2) semantics for lock */ + F_POSIX = $040; //* Use POSIX semantics for lock */ + F_REMOTE = $080; //* Lock owner is remote NFS client */ + F_NOINTR = $100; //* Ignore signals when waiting */ +{$endif} + +{$ifndef linux} + EVFILT_READ = (-1); + EVFILT_WRITE = (-2); + EVFILT_AIO = (-3); //* attached to aio requests */ + EVFILT_VNODE = (-4); //* attached to vnodes */ + EVFILT_PROC = (-5); //* attached to struct proc */ + EVFILT_SIGNAL = (-6); //* attached to struct proc */ + EVFILT_TIMER = (-7); //* timers */ +//* EVFILT_NETDEV = (-8); / no longer supported */ + EVFILT_FS = (-9); //* filesystem events */ + EVFILT_LIO = (-10); //* attached to lio requests */ + EVFILT_USER = (-11); //* User events */ + EVFILT_SYSCOUNT = 11; + + EV_ADD = $0001; //* add event to kq (implies enable) */ + EV_DELETE = $0002; //* delete event from kq */ + EV_ENABLE = $0004; //* enable event */ + EV_DISABLE = $0008; //* disable event (not reported) */ + +//* flags */ + EV_ONESHOT = $0010; //* only report one occurrence */ + EV_CLEAR = $0020; //* clear event state after reporting */ + EV_RECEIPT = $0040; //* force EV_ERROR on success, data=0 */ + EV_DISPATCH = $0080; //* disable event after reporting */ + + EV_SYSFLAGS = $F000; //* reserved by system */ + EV_DROP = $1000; //* note should be dropped */ + EV_FLAG1 = $2000; //* filter-specific flag */ + +//* returned values */ + EV_EOF = $8000; //* EOF detected */ + EV_ERROR = $4000; //* error, data contains errno */ + + NOTE_FFNOP = $00000000; //* ignore input fflags */ + NOTE_FFAND = $40000000; //* AND fflags */ + NOTE_FFOR = $80000000; //* OR fflags */ + NOTE_FFCOPY = $c0000000; //* copy fflags */ + NOTE_FFCTRLMASK = $c0000000; //* masks for operations */ + NOTE_FFLAGSMASK = $00ffffff; + + NOTE_TRIGGER = $01000000; //* Cause the event to be triggered for output. */ + +//* data/hint flags for EVFILT_{READ|WRITE}, shared with userspace + NOTE_LOWAT = $0001; //* low water mark */ + +//* data/hint flags for EVFILT_VNODE, shared with userspace + NOTE_DELETE = $0001; //* vnode was removed */ + NOTE_WRITE = $0002; //* data contents changed */ + NOTE_EXTEND = $0004; //* size increased */ + NOTE_ATTRIB = $0008; //* attributes changed */ + NOTE_LINK = $0010; //* link count changed */ + NOTE_RENAME = $0020; //* vnode was renamed */ + NOTE_REVOKE = $0040; //* vnode access was revoked */ + + +//* data/hint flags for EVFILT_PROC, shared with userspace + NOTE_EXIT = $80000000; //* process exited */ + NOTE_FORK = $40000000; //* process forked */ + NOTE_EXEC = $20000000; //* process exec'd */ + NOTE_PCTRLMASK = $f0000000; //* mask for hint bits */ + NOTE_PDATAMASK = $000fffff; //* mask for pid */ + +//* additional flags for EVFILT_PROC */ + NOTE_TRACK = $00000001; //* follow across forks */ + NOTE_TRACKERR = $00000002; //* could not track child */ + NOTE_CHILD = $00000004; //* am a child process */ + +type + kevent_t = record + ident: uintptr_t; //* identifier for this event */ + filter: cshort; //* filter for event */ + flags: cushort; + fflags: cuint; + data: intptr_t; + udata: pointer; //* opaque user data identifier */ + end; + pkevent_t = ^kevent_t; + + function kqueue(): cint; cdecl; external clib name 'kqueue'; + function kevent(kq: cint; changelist: pkevent_t; nchanges: cint; + eventlist: pkevent_t; nevents: cint; timeout: ptimespec): cint; + cdecl; external clib name 'kevent'; + const +{$endif} + + LOCK_SH = 1; + LOCK_EX = 2; + LOCK_NB = 4; + LOCK_UN = 8; + + LOCK_MAND = 32; + LOCK_READ = 64; + LOCK_WRITE = 128; + LOCK_RW = 192; + + DN_ACCESS = $00000001; + DN_MODIFY = $00000002; + DN_CREATE = $00000004; + DN_DELETE = $00000008; + DN_RENAME = $00000010; + DN_ATTRIB = $00000020; + DN_MULTISHOT = $80000000; + + __S_ISUID = $800; + __S_ISGID = $400; + __S_ISVTX = $200; + __S_IREAD = $100; + __S_IWRITE = $80; + __S_IEXEC = $40; + + S_ISUID = __S_ISUID; + S_ISGID = __S_ISGID; + S_ISVTX = __S_ISVTX; + + S_IRUSR = __S_IREAD; + S_IWUSR = __S_IWRITE; + S_IXUSR = __S_IEXEC; + S_IRWXU = (__S_IREAD or __S_IWRITE) or __S_IEXEC; + + S_IREAD = S_IRUSR; + S_IWRITE = S_IWUSR; + S_IEXEC = S_IXUSR; + + S_IRGRP = S_IRUSR shr 3; + S_IWGRP = S_IWUSR shr 3; + S_IXGRP = S_IXUSR shr 3; + S_IRWXG = S_IRWXU shr 3; + S_IROTH = S_IRGRP shr 3; + S_IWOTH = S_IWGRP shr 3; + S_IXOTH = S_IXGRP shr 3; + S_IRWXO = S_IRWXG shr 3; + + +const + __FD_SETSIZE = 1024; + __NFDBITS = 8 * sizeof(__fd_mask); + +type +// __key_t = longint; +// __ipc_pid_t = word; +// __blksize_t = longint; +// __blkcnt_t = longint; +// __blkcnt64_t = __quad_t; +// __fsblkcnt_t = __u_long; +// __fsblkcnt64_t = __u_quad_t; +// __fsfilcnt_t = __u_long; +// __fsfilcnt64_t = __u_quad_t; +// __ino64_t = __u_quad_t; +// __off64_t = __loff_t; + __t_scalar_t = longint; + __t_uscalar_t = dword; + __intptr_t = longint; + __socklen_t = dword; + TFileDescriptor = integer; + +{$ifdef CPU64} + P_stat = ^_stat; + PStat = ^_stat; + + {$ifdef linux} + _stat = packed record + st_dev: culong; + st_ino: culong; + st_nlink: culong; + + st_mode: cuint; + st_uid: cuint; + st_gid: cuint; + __pad0: cuint; + st_rdev: culong; + st_size: clong; + st_blksize: clong; + st_blocks: clong; //* Number 512-byte blocks allocated. */ + + st_atime: culong; + st_atime_nsec: culong; + st_mtime: culong; + st_mtime_nsec: culong; + st_ctime: culong; + st_ctime_nsec: culong; + __unused: array[0..2] of clong; + end; + + {$else} //bsd + ino_t = cuint32; + mode_t = cuint16; + n_link_t = cuint16; + uid_t = cuint32; + gid_t = cuint32; + off_t = cint64; + blkcnt_t = cint64; + blksize_t = cuint32; + fflags_t = cuint32; + + _stat = packed record + st_dev: __dev_t; //* inode's device */ + st_ino: ino_t; //* inode's number */ + st_mode: mode_t; //* inode protection mode */ + st_nlink: n_link_t; //* number of hard links */ + st_uid: uid_t; //* user ID of the file's owner */ + st_gid: gid_t; //* group ID of the file's group */ + st_rdev: __dev_t; //* device type */ + st_atime: culong; //* time of last access */ + st_atime_nsec: culong; + st_mtime: culong; //* time of last data modification */ + st_mtime_nsec: culong; + st_ctime: culong; //* time of last file status change */ + st_ctime_nsec: culong; + st_size: off_t; //* file size, in bytes */ + st_blocks: blkcnt_t; //* blocks allocated for file */ + st_blksize: blksize_t; //* optimal blocksize for I/O */ + st_flags: fflags_t; //* user defined flags for file */ + st_gen: cuint32; //* file generation number */ + st_lspare: cint32; + st_birthtim: timespec; //* time of file creation */ + {$ifndef cpu64} + pad: array[0..15-sizeof(timespec)] of byte; + {$endif} + (* + /* + * Explicitly pad st_birthtim to 16 bytes so that the size of + * struct stat is backwards compatible. We use bitfields instead + * of an array of chars so that this doesn't require a C99 compiler + * to compile if the size of the padding is 0. We use 2 bitfields + * to cover up to 64 bits on 32-bit machines. We assume that + * CHAR_BIT is 8... + */ + unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec)); + unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec)); + *) + end; +{$endif} //bsd + + + P_stat64 = ^_stat64; + Pstat64 = ^_stat64; + _stat64 = _stat; +{$else} //cpu32 + + P_stat = ^_stat; + PStat = ^_stat; + {$ifdef linux} + _stat = packed record //probably wrong, not used + st_dev : __dev_t; + __pad1 : word; + __align_pad1 : word; + st_ino : __ino_t; + st_mode : __mode_t; + st_nlink : __nlink_t; + st_uid : __uid_t; + st_gid : __gid_t; + st_rdev : __dev_t; + __pad2 : word; + __align_pad2 : word; + st_size : __off_t; + st_blksize : __blksize_t; + st_blocks : __blkcnt_t; + st_atim: timespec;// __time_t; +// st_atime_nsec : longword; + st_mtim: timespec;// __time_t; +// st_mtime_nsec: longword; + st_ctim: timespec;// __time_t; +// st_ctime_nsec: longword; + __unused4 : dword; + __unused5 : dword; + end; + {$endif} + P_stat64 = ^_stat64; + Pstat64 = ^_stat64; +{$ifndef cpuarm} + {$ifdef linux} + _stat64 = packed record + st_dev: culonglong; // 0 + __pad0: array[0..3] of byte; // 8 + __st_ino: culong; //12 + st_mode: cuint; //16 + st_nlink: cuint; //20 + st_uid: culong; //24 + st_gid: culong; //28 + st_rdev: culonglong; //32 + __pad3: array[0..3] of byte; //40 + st_size: clonglong; //44 + st_blksize: culong; //52 + st_blocks: culonglong; //56 + st_atime: culong; //64 + st_atime_nsec: culong; //68 + st_mtime: culong; //72 + st_mtime_nsec: cuint; //76 + st_ctime: culong; //80 + st_ctime_nsec: culong; //84 + st_ino: culonglong; //88 + //96 + end; + {$else} //bsd + ino_t = cuint32; + mode_t = cuint16; + n_link_t = cuint16; + uid_t = cuint32; + gid_t = cuint32; + off_t = cint64; + blkcnt_t = cint64; + blksize_t = cuint32; + fflags_t = cuint32; + + _stat = packed record + st_dev: __dev_t; //* inode's device */ + st_ino: ino_t; //* inode's number */ + st_mode: mode_t; //* inode protection mode */ + st_nlink: n_link_t; //* number of hard links */ + st_uid: uid_t; //* user ID of the file's owner */ + st_gid: gid_t; //* group ID of the file's group */ + st_rdev: __dev_t; //* device type */ + st_atime: culong; //* time of last access */ + st_atime_nsec: culong; + st_mtime: culong; //* time of last data modification */ + st_mtime_nsec: culong; + st_ctime: culong; //* time of last file status change */ + st_ctime_nsec: culong; + st_size: off_t; //* file size, in bytes */ + st_blocks: blkcnt_t; //* blocks allocated for file */ + st_blksize: blksize_t; //* optimal blocksize for I/O */ + st_flags: fflags_t; //* user defined flags for file */ + st_gen: cuint32; //* file generation number */ + st_lspare: cint32; + st_birthtim: timespec; //* time of file creation */ + {$ifndef cpu64} + pad: array[0..15-sizeof(timespec)] of byte; + {$endif} + (* + /* + * Explicitly pad st_birthtim to 16 bytes so that the size of + * struct stat is backwards compatible. We use bitfields instead + * of an array of chars so that this doesn't require a C99 compiler + * to compile if the size of the padding is 0. We use 2 bitfields + * to cover up to 64 bits on 32-bit machines. We assume that + * CHAR_BIT is 8... + */ + unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec)); + unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec)); + *) + end; + _stat64 = _stat; + {$endif} //bsd +{$else} //cpuarm for raspberry pi + _stat64 = packed record + st_dev: culonglong; //* Device. */ + st_ino: culonglong; //* File serial number. */ + st_mode: cuint; //* File mode. */ + st_nlink: cuint; //* Link count. */ + st_uid: cuint; //* User ID of the file's owner. */ + st_gid: cuint; //* Group ID of the file's group. */ + st_rdev: culonglong; //* Device number, if device. */ + __pad1: culonglong; + st_size: clonglong; //* Size of file, in bytes. */ + st_blksize: cint; //* Optimal block size for I/O. */ + __pad2: cint; + st_blocks: clonglong; //* Number 512-byte blocks allocated. */ + st_atime: cint; //* Time of last access. */ + st_atime_nsec: cuint; + st_mtime: cint; //* Time of last modification. */ + st_mtime_nsec: cuint; + st_ctime: cint; //* Time of last status change. */ + st_ctime_nsec: cuint; + __unused4: cuint; + __unused5: cuint; + end; +{$endif} //cpuarm +{$endif} //cpu32 + + __fd_set = record + fds_bits: packed array[0..(__FD_SETSIZE div __NFDBITS)-1] of __fd_mask; + end; + TFdSet = __fd_set; + PFdSet = ^TFdSet; + + +Const + stdin = 0; + stdout = 1; + stderr = 2; + + +Type + + u_char = __u_char; + u_short = __u_short; + u_int = __u_int; + u_long = __u_long; + quad_t = __quad_t; + u_quad_t = __u_quad_t; + fsid_t = __fsid_t; + loff_t = __loff_t; + ino64_t = __ino64_t; + dev_t = __dev_t; + {$ifdef linux} + ino_t = __ino_t; + gid_t = __gid_t; + mode_t = __mode_t; + uid_t = __uid_t; + off_t = __off_t; + blksize_t = __blksize_t; + blkcnt_t = __blkcnt_t; + {$endif} + nlink_t = __nlink_t; + off64_t = __off64_t; + pid_t = __pid_t; + id_t = __id_t; + ssize_t = __ssize_t; + daddr_t = __daddr_t; + caddr_t = __caddr_t; + key_t = __key_t; + useconds_t = __useconds_t; + suseconds_t = __suseconds_t; + ulong = dword; + ushort = word; + uint = dword; + int8_t = char; + int16_t = smallint; + int32_t = longint; + u_int8_t = byte; + u_int16_t = word; + u_int32_t = dword; + register_t = longint; + fsblkcnt_t = __fsblkcnt_t; + fsfilcnt_t = __fsfilcnt_t; + blkcnt64_t = __blkcnt64_t; + fsblkcnt64_t = __fsblkcnt64_t; + fsfilcnt64_t = __fsfilcnt64_t; + + P__key_t = ^__key_t; + P__ipc_pid_t = ^__ipc_pid_t; + P__blksize_t = ^__blksize_t; + P__blkcnt_t = ^__blkcnt_t; + P__blkcnt64_t = ^__blkcnt64_t; + P__fsblkcnt_t = ^__fsblkcnt_t; + P__fsblkcnt64_t = ^__fsblkcnt64_t; + P__fsfilcnt_t = ^__fsfilcnt_t; + P__fsfilcnt64_t = ^__fsfilcnt64_t; + P__ino64_t = ^__ino64_t; + P__off64_t = ^__off64_t; + P__t_scalar_t = ^__t_scalar_t; + P__t_uscalar_t = ^__t_uscalar_t; + P__intptr_t = ^__intptr_t; + P__socklen_t = ^__socklen_t; + + + Pu_char = ^u_char; + Pu_short = ^u_short; + Pu_int = ^u_int; + Pu_long = ^u_long; + Pquad_t = ^quad_t; + Pu_quad_t = ^u_quad_t; + Pfsid_t = ^fsid_t; + Ploff_t = ^loff_t; + Pino_t = ^ino_t; + Pino64_t = ^ino64_t; + Pdev_t = ^dev_t; + Pgid_t = ^gid_t; + Pmode_t = ^mode_t; + Pnlink_t = ^nlink_t; + Puid_t = ^uid_t; + Poff_t = ^off_t; + Poff64_t = ^off64_t; + Ppid_t = ^pid_t; + Pssize_t = ^ssize_t; + Pdaddr_t = ^daddr_t; + Pcaddr_t = ^caddr_t; + Pkey_t = ^key_t; + Puseconds_t = ^useconds_t; + Psuseconds_t = ^suseconds_t; + Pulong = ^ulong; + Pushort = ^ushort; + Puint = ^uint; + Pint8_t = ^int8_t; + Pint16_t = ^int16_t; + Pint32_t = ^int32_t; + Pu_int8_t = ^u_int8_t; + Pu_int16_t = ^u_int16_t; + Pu_int32_t = ^u_int32_t; + Pregister_t = ^register_t; + Pblksize_t = ^blksize_t; + Pblkcnt_t = ^blkcnt_t; + Pfsblkcnt_t = ^fsblkcnt_t; + Pfsfilcnt_t = ^fsfilcnt_t; + Pblkcnt64_t = ^blkcnt64_t; + Pfsblkcnt64_t = ^fsblkcnt64_t; + Pfsfilcnt64_t = ^fsfilcnt64_t; + + P__qaddr_t = ^__qaddr_t; + P__dev_t = ^__dev_t; + P__uid_t = ^__uid_t; + P__gid_t = ^__gid_t; + P__ino_t = ^__ino_t; + P__mode_t = ^__mode_t; + P__nlink_t = ^__nlink_t; + P__off_t = ^__off_t; + P__loff_t = ^__loff_t; + P__pid_t = ^__pid_t; + P__ssize_t = ^__ssize_t; + P__rlim_t = ^__rlim_t; + P__rlim64_t = ^__rlim64_t; + P__id_t = ^__id_t; + P__fsid_t = ^__fsid_t; + P__daddr_t = ^__daddr_t; + P__caddr_t = ^__caddr_t; + P__time_t = ^__time_t; + P__useconds_t = ^__useconds_t; + P__suseconds_t = ^__suseconds_t; + P__swblk_t = ^__swblk_t; + P__clock_t = ^__clock_t; + P__clockid_t = ^__clockid_t; + P__timer_t = ^__timer_t; + +const +{$ifdef linux} + __LC_CTYPE = 0; + __LC_NUMERIC = 1; + __LC_TIME = 2; + __LC_COLLATE = 3; + __LC_MONETARY = 4; + __LC_MESSAGES = 5; + __LC_ALL = 6; + __LC_PAPER = 7; + __LC_NAME = 8; + __LC_ADDRESS = 9; + __LC_TELEPHONE = 10; + __LC_MEASUREMENT = 11; + __LC_IDENTIFICATION = 12; + + LC_CTYPE = __LC_CTYPE; + LC_NUMERIC = __LC_NUMERIC; + LC_TIME = __LC_TIME; + LC_COLLATE = __LC_COLLATE; + LC_MONETARY = __LC_MONETARY; + LC_MESSAGES = __LC_MESSAGES; + LC_ALL = __LC_ALL; + LC_PAPER = __LC_PAPER; + LC_NAME = __LC_NAME; + LC_ADDRESS = __LC_ADDRESS; + LC_TELEPHONE = __LC_TELEPHONE; + LC_MEASUREMENT = __LC_MEASUREMENT; + LC_IDENTIFICATION = __LC_IDENTIFICATION; + + ABDAY_1 = (__LC_TIME shl 16); + ABDAY_2 = (ABDAY_1)+1; + ABDAY_3 = (ABDAY_1)+2; + ABDAY_4 = (ABDAY_1)+3; + ABDAY_5 = (ABDAY_1)+4; + ABDAY_6 = (ABDAY_1)+5; + ABDAY_7 = (ABDAY_1)+6; + DAY_1 = (ABDAY_1)+7; + DAY_2 = (ABDAY_1)+8; + DAY_3 = (ABDAY_1)+9; + DAY_4 = (ABDAY_1)+10; + DAY_5 = (ABDAY_1)+11; + DAY_6 = (ABDAY_1)+12; + DAY_7 = (ABDAY_1)+13; + ABMON_1 = (ABDAY_1)+14; + ABMON_2 = (ABDAY_1)+15; + ABMON_3 = (ABDAY_1)+16; + ABMON_4 = (ABDAY_1)+17; + ABMON_5 = (ABDAY_1)+18; + ABMON_6 = (ABDAY_1)+19; + ABMON_7 = (ABDAY_1)+20; + ABMON_8 = (ABDAY_1)+21; + ABMON_9 = (ABDAY_1)+22; + ABMON_10 = (ABDAY_1)+23; + ABMON_11 = (ABDAY_1)+24; + ABMON_12 = (ABDAY_1)+25; + MON_1 = (ABDAY_1)+26; + MON_2 = (ABDAY_1)+27; + MON_3 = (ABDAY_1)+28; + MON_4 = (ABDAY_1)+29; + MON_5 = (ABDAY_1)+30; + MON_6 = (ABDAY_1)+31; + MON_7 = (ABDAY_1)+32; + MON_8 = (ABDAY_1)+33; + MON_9 = (ABDAY_1)+34; + MON_10 = (ABDAY_1)+35; + MON_11 = (ABDAY_1)+36; + MON_12 = (ABDAY_1)+37; + AM_STR = (ABDAY_1)+38; + PM_STR = (ABDAY_1)+39; + D_T_FMT = (ABDAY_1)+40; + D_FMT = (ABDAY_1)+41; + T_FMT = (ABDAY_1)+42; + T_FMT_AMPM = (ABDAY_1)+43; + ERA = (ABDAY_1)+44; + __ERA_YEAR = (ABDAY_1)+45; + ERA_D_FMT = (ABDAY_1)+46; + ALT_DIGITS = (ABDAY_1)+47; + ERA_D_T_FMT = (ABDAY_1)+48; + ERA_T_FMT = (ABDAY_1)+49; + _NL_TIME_ERA_NUM_ENTRIES = (ABDAY_1)+50; + _NL_TIME_ERA_ENTRIES = (ABDAY_1)+51; + _NL_WABDAY_1 = (ABDAY_1)+52; + _NL_WABDAY_2 = (ABDAY_1)+53; + _NL_WABDAY_3 = (ABDAY_1)+54; + _NL_WABDAY_4 = (ABDAY_1)+55; + _NL_WABDAY_5 = (ABDAY_1)+56; + _NL_WABDAY_6 = (ABDAY_1)+57; + _NL_WABDAY_7 = (ABDAY_1)+58; + _NL_WDAY_1 = (ABDAY_1)+59; + _NL_WDAY_2 = (ABDAY_1)+60; + _NL_WDAY_3 = (ABDAY_1)+61; + _NL_WDAY_4 = (ABDAY_1)+62; + _NL_WDAY_5 = (ABDAY_1)+63; + _NL_WDAY_6 = (ABDAY_1)+64; + _NL_WDAY_7 = (ABDAY_1)+65; + _NL_WABMON_1 = (ABDAY_1)+66; + _NL_WABMON_2 = (ABDAY_1)+67; + _NL_WABMON_3 = (ABDAY_1)+68; + _NL_WABMON_4 = (ABDAY_1)+69; + _NL_WABMON_5 = (ABDAY_1)+70; + _NL_WABMON_6 = (ABDAY_1)+71; + _NL_WABMON_7 = (ABDAY_1)+72; + _NL_WABMON_8 = (ABDAY_1)+73; + _NL_WABMON_9 = (ABDAY_1)+74; + _NL_WABMON_10 = (ABDAY_1)+75; + _NL_WABMON_11 = (ABDAY_1)+76; + _NL_WABMON_12 = (ABDAY_1)+77; + _NL_WMON_1 = (ABDAY_1)+78; + _NL_WMON_2 = (ABDAY_1)+79; + _NL_WMON_3 = (ABDAY_1)+80; + _NL_WMON_4 = (ABDAY_1)+81; + _NL_WMON_5 = (ABDAY_1)+82; + _NL_WMON_6 = (ABDAY_1)+83; + _NL_WMON_7 = (ABDAY_1)+84; + _NL_WMON_8 = (ABDAY_1)+85; + _NL_WMON_9 = (ABDAY_1)+86; + _NL_WMON_10 = (ABDAY_1)+87; + _NL_WMON_11 = (ABDAY_1)+88; + _NL_WMON_12 = (ABDAY_1)+89; + _NL_WAM_STR = (ABDAY_1)+90; + _NL_WPM_STR = (ABDAY_1)+91; + _NL_WD_T_FMT = (ABDAY_1)+92; + _NL_WD_FMT = (ABDAY_1)+93; + _NL_WT_FMT = (ABDAY_1)+94; + _NL_WT_FMT_AMPM = (ABDAY_1)+95; + _NL_WERA_YEAR = (ABDAY_1)+96; + _NL_WERA_D_FMT = (ABDAY_1)+97; + _NL_WALT_DIGITS = (ABDAY_1)+98; + _NL_WERA_D_T_FMT = (ABDAY_1)+99; + _NL_WERA_T_FMT = (ABDAY_1)+100; + _NL_TIME_WEEK_NDAYS = (ABDAY_1)+101; + _NL_TIME_WEEK_1STDAY = (ABDAY_1)+102; + _NL_TIME_WEEK_1STWEEK = (ABDAY_1)+103; + _NL_TIME_FIRST_WEEKDAY = (ABDAY_1)+104; + _NL_TIME_FIRST_WORKDAY = (ABDAY_1)+105; + _NL_TIME_CAL_DIRECTION = (ABDAY_1)+106; + _NL_TIME_TIMEZONE = (ABDAY_1)+107; + _DATE_FMT = (ABDAY_1)+108; + _NL_W_DATE_FMT = (ABDAY_1)+109; + _NL_TIME_CODESET = (ABDAY_1)+110; + _NL_NUM_LC_TIME = (ABDAY_1)+111; + _NL_COLLATE_NRULES = (__LC_COLLATE shl 16); + _NL_COLLATE_RULESETS = (_NL_COLLATE_NRULES)+1; + _NL_COLLATE_TABLEMB = (_NL_COLLATE_NRULES)+2; + _NL_COLLATE_WEIGHTMB = (_NL_COLLATE_NRULES)+3; + _NL_COLLATE_EXTRAMB = (_NL_COLLATE_NRULES)+4; + _NL_COLLATE_INDIRECTMB = (_NL_COLLATE_NRULES)+5; + _NL_COLLATE_GAP1 = (_NL_COLLATE_NRULES)+6; + _NL_COLLATE_GAP2 = (_NL_COLLATE_NRULES)+7; + _NL_COLLATE_GAP3 = (_NL_COLLATE_NRULES)+8; + _NL_COLLATE_TABLEWC = (_NL_COLLATE_NRULES)+9; + _NL_COLLATE_WEIGHTWC = (_NL_COLLATE_NRULES)+10; + _NL_COLLATE_EXTRAWC = (_NL_COLLATE_NRULES)+11; + _NL_COLLATE_INDIRECTWC = (_NL_COLLATE_NRULES)+12; + _NL_COLLATE_SYMB_HASH_SIZEMB = (_NL_COLLATE_NRULES)+13; + _NL_COLLATE_SYMB_TABLEMB = (_NL_COLLATE_NRULES)+14; + _NL_COLLATE_SYMB_EXTRAMB = (_NL_COLLATE_NRULES)+15; + _NL_COLLATE_COLLSEQMB = (_NL_COLLATE_NRULES)+16; + _NL_COLLATE_COLLSEQWC = (_NL_COLLATE_NRULES)+17; + _NL_COLLATE_CODESET = (_NL_COLLATE_NRULES)+18; + _NL_NUM_LC_COLLATE = (_NL_COLLATE_NRULES)+19; + _NL_CTYPE_CLASS = (__LC_CTYPE shl 16); + _NL_CTYPE_TOUPPER = (_NL_CTYPE_CLASS)+1; + _NL_CTYPE_GAP1 = (_NL_CTYPE_CLASS)+2; + _NL_CTYPE_TOLOWER = (_NL_CTYPE_CLASS)+3; + _NL_CTYPE_GAP2 = (_NL_CTYPE_CLASS)+4; + _NL_CTYPE_CLASS32 = (_NL_CTYPE_CLASS)+5; + _NL_CTYPE_GAP3 = (_NL_CTYPE_CLASS)+6; + _NL_CTYPE_GAP4 = (_NL_CTYPE_CLASS)+7; + _NL_CTYPE_GAP5 = (_NL_CTYPE_CLASS)+8; + _NL_CTYPE_GAP6 = (_NL_CTYPE_CLASS)+9; + _NL_CTYPE_CLASS_NAMES = (_NL_CTYPE_CLASS)+10; + _NL_CTYPE_MAP_NAMES = (_NL_CTYPE_CLASS)+11; + _NL_CTYPE_WIDTH = (_NL_CTYPE_CLASS)+12; + _NL_CTYPE_MB_CUR_MAX = (_NL_CTYPE_CLASS)+13; + _NL_CTYPE_CODESET_NAME = (_NL_CTYPE_CLASS)+14; + CODESET = _NL_CTYPE_CODESET_NAME; + _NL_CTYPE_TOUPPER32 = (_NL_CTYPE_CODESET_NAME)+1; + _NL_CTYPE_TOLOWER32 = (_NL_CTYPE_CODESET_NAME)+2; + _NL_CTYPE_CLASS_OFFSET = (_NL_CTYPE_CODESET_NAME)+3; + _NL_CTYPE_MAP_OFFSET = (_NL_CTYPE_CODESET_NAME)+4; + _NL_CTYPE_INDIGITS_MB_LEN = (_NL_CTYPE_CODESET_NAME)+5; + _NL_CTYPE_INDIGITS0_MB = (_NL_CTYPE_CODESET_NAME)+6; + _NL_CTYPE_INDIGITS1_MB = (_NL_CTYPE_CODESET_NAME)+7; + _NL_CTYPE_INDIGITS2_MB = (_NL_CTYPE_CODESET_NAME)+8; + _NL_CTYPE_INDIGITS3_MB = (_NL_CTYPE_CODESET_NAME)+9; + _NL_CTYPE_INDIGITS4_MB = (_NL_CTYPE_CODESET_NAME)+10; + _NL_CTYPE_INDIGITS5_MB = (_NL_CTYPE_CODESET_NAME)+11; + _NL_CTYPE_INDIGITS6_MB = (_NL_CTYPE_CODESET_NAME)+12; + _NL_CTYPE_INDIGITS7_MB = (_NL_CTYPE_CODESET_NAME)+13; + _NL_CTYPE_INDIGITS8_MB = (_NL_CTYPE_CODESET_NAME)+14; + _NL_CTYPE_INDIGITS9_MB = (_NL_CTYPE_CODESET_NAME)+15; + _NL_CTYPE_INDIGITS_WC_LEN = (_NL_CTYPE_CODESET_NAME)+16; + _NL_CTYPE_INDIGITS0_WC = (_NL_CTYPE_CODESET_NAME)+17; + _NL_CTYPE_INDIGITS1_WC = (_NL_CTYPE_CODESET_NAME)+18; + _NL_CTYPE_INDIGITS2_WC = (_NL_CTYPE_CODESET_NAME)+19; + _NL_CTYPE_INDIGITS3_WC = (_NL_CTYPE_CODESET_NAME)+20; + _NL_CTYPE_INDIGITS4_WC = (_NL_CTYPE_CODESET_NAME)+21; + _NL_CTYPE_INDIGITS5_WC = (_NL_CTYPE_CODESET_NAME)+22; + _NL_CTYPE_INDIGITS6_WC = (_NL_CTYPE_CODESET_NAME)+23; + _NL_CTYPE_INDIGITS7_WC = (_NL_CTYPE_CODESET_NAME)+24; + _NL_CTYPE_INDIGITS8_WC = (_NL_CTYPE_CODESET_NAME)+25; + _NL_CTYPE_INDIGITS9_WC = (_NL_CTYPE_CODESET_NAME)+26; + _NL_CTYPE_OUTDIGIT0_MB = (_NL_CTYPE_CODESET_NAME)+27; + _NL_CTYPE_OUTDIGIT1_MB = (_NL_CTYPE_CODESET_NAME)+28; + _NL_CTYPE_OUTDIGIT2_MB = (_NL_CTYPE_CODESET_NAME)+29; + _NL_CTYPE_OUTDIGIT3_MB = (_NL_CTYPE_CODESET_NAME)+30; + _NL_CTYPE_OUTDIGIT4_MB = (_NL_CTYPE_CODESET_NAME)+31; + _NL_CTYPE_OUTDIGIT5_MB = (_NL_CTYPE_CODESET_NAME)+32; + _NL_CTYPE_OUTDIGIT6_MB = (_NL_CTYPE_CODESET_NAME)+33; + _NL_CTYPE_OUTDIGIT7_MB = (_NL_CTYPE_CODESET_NAME)+34; + _NL_CTYPE_OUTDIGIT8_MB = (_NL_CTYPE_CODESET_NAME)+35; + _NL_CTYPE_OUTDIGIT9_MB = (_NL_CTYPE_CODESET_NAME)+36; + _NL_CTYPE_OUTDIGIT0_WC = (_NL_CTYPE_CODESET_NAME)+37; + _NL_CTYPE_OUTDIGIT1_WC = (_NL_CTYPE_CODESET_NAME)+38; + _NL_CTYPE_OUTDIGIT2_WC = (_NL_CTYPE_CODESET_NAME)+39; + _NL_CTYPE_OUTDIGIT3_WC = (_NL_CTYPE_CODESET_NAME)+40; + _NL_CTYPE_OUTDIGIT4_WC = (_NL_CTYPE_CODESET_NAME)+41; + _NL_CTYPE_OUTDIGIT5_WC = (_NL_CTYPE_CODESET_NAME)+42; + _NL_CTYPE_OUTDIGIT6_WC = (_NL_CTYPE_CODESET_NAME)+43; + _NL_CTYPE_OUTDIGIT7_WC = (_NL_CTYPE_CODESET_NAME)+44; + _NL_CTYPE_OUTDIGIT8_WC = (_NL_CTYPE_CODESET_NAME)+45; + _NL_CTYPE_OUTDIGIT9_WC = (_NL_CTYPE_CODESET_NAME)+46; + _NL_CTYPE_TRANSLIT_TAB_SIZE = (_NL_CTYPE_CODESET_NAME)+47; + _NL_CTYPE_TRANSLIT_FROM_IDX = (_NL_CTYPE_CODESET_NAME)+48; + _NL_CTYPE_TRANSLIT_FROM_TBL = (_NL_CTYPE_CODESET_NAME)+49; + _NL_CTYPE_TRANSLIT_TO_IDX = (_NL_CTYPE_CODESET_NAME)+50; + _NL_CTYPE_TRANSLIT_TO_TBL = (_NL_CTYPE_CODESET_NAME)+51; + _NL_CTYPE_TRANSLIT_DEFAULT_MISSING_LEN = (_NL_CTYPE_CODESET_NAME)+52; + _NL_CTYPE_TRANSLIT_DEFAULT_MISSING = (_NL_CTYPE_CODESET_NAME)+53; + _NL_CTYPE_TRANSLIT_IGNORE_LEN = (_NL_CTYPE_CODESET_NAME)+54; + _NL_CTYPE_TRANSLIT_IGNORE = (_NL_CTYPE_CODESET_NAME)+55; + _NL_CTYPE_EXTRA_MAP_1 = (_NL_CTYPE_CODESET_NAME)+56; + _NL_CTYPE_EXTRA_MAP_2 = (_NL_CTYPE_CODESET_NAME)+57; + _NL_CTYPE_EXTRA_MAP_3 = (_NL_CTYPE_CODESET_NAME)+58; + _NL_CTYPE_EXTRA_MAP_4 = (_NL_CTYPE_CODESET_NAME)+59; + _NL_CTYPE_EXTRA_MAP_5 = (_NL_CTYPE_CODESET_NAME)+60; + _NL_CTYPE_EXTRA_MAP_6 = (_NL_CTYPE_CODESET_NAME)+61; + _NL_CTYPE_EXTRA_MAP_7 = (_NL_CTYPE_CODESET_NAME)+62; + _NL_CTYPE_EXTRA_MAP_8 = (_NL_CTYPE_CODESET_NAME)+63; + _NL_CTYPE_EXTRA_MAP_9 = (_NL_CTYPE_CODESET_NAME)+64; + _NL_CTYPE_EXTRA_MAP_10 = (_NL_CTYPE_CODESET_NAME)+65; + _NL_CTYPE_EXTRA_MAP_11 = (_NL_CTYPE_CODESET_NAME)+66; + _NL_CTYPE_EXTRA_MAP_12 = (_NL_CTYPE_CODESET_NAME)+67; + _NL_CTYPE_EXTRA_MAP_13 = (_NL_CTYPE_CODESET_NAME)+68; + _NL_CTYPE_EXTRA_MAP_14 = (_NL_CTYPE_CODESET_NAME)+69; + _NL_NUM_LC_CTYPE = (_NL_CTYPE_CODESET_NAME)+70; + __INT_CURR_SYMBOL = (__LC_MONETARY shl 16); + __CURRENCY_SYMBOL = (__INT_CURR_SYMBOL)+1; + __MON_DECIMAL_POINT = (__INT_CURR_SYMBOL)+2; + __MON_THOUSANDS_SEP = (__INT_CURR_SYMBOL)+3; + __MON_GROUPING = (__INT_CURR_SYMBOL)+4; + __POSITIVE_SIGN = (__INT_CURR_SYMBOL)+5; + __NEGATIVE_SIGN = (__INT_CURR_SYMBOL)+6; + __INT_FRAC_DIGITS = (__INT_CURR_SYMBOL)+7; + __FRAC_DIGITS = (__INT_CURR_SYMBOL)+8; + __P_CS_PRECEDES = (__INT_CURR_SYMBOL)+9; + __P_SEP_BY_SPACE = (__INT_CURR_SYMBOL)+10; + __N_CS_PRECEDES = (__INT_CURR_SYMBOL)+11; + __N_SEP_BY_SPACE = (__INT_CURR_SYMBOL)+12; + __P_SIGN_POSN = (__INT_CURR_SYMBOL)+13; + __N_SIGN_POSN = (__INT_CURR_SYMBOL)+14; + _NL_MONETARY_CRNCYSTR = (__INT_CURR_SYMBOL)+15; + __INT_P_CS_PRECEDES = (__INT_CURR_SYMBOL)+16; + __INT_P_SEP_BY_SPACE = (__INT_CURR_SYMBOL)+17; + __INT_N_CS_PRECEDES = (__INT_CURR_SYMBOL)+18; + __INT_N_SEP_BY_SPACE = (__INT_CURR_SYMBOL)+19; + __INT_P_SIGN_POSN = (__INT_CURR_SYMBOL)+20; + __INT_N_SIGN_POSN = (__INT_CURR_SYMBOL)+21; + _NL_MONETARY_DUO_INT_CURR_SYMBOL = (__INT_CURR_SYMBOL)+22; + _NL_MONETARY_DUO_CURRENCY_SYMBOL = (__INT_CURR_SYMBOL)+23; + _NL_MONETARY_DUO_INT_FRAC_DIGITS = (__INT_CURR_SYMBOL)+24; + _NL_MONETARY_DUO_FRAC_DIGITS = (__INT_CURR_SYMBOL)+25; + _NL_MONETARY_DUO_P_CS_PRECEDES = (__INT_CURR_SYMBOL)+26; + _NL_MONETARY_DUO_P_SEP_BY_SPACE = (__INT_CURR_SYMBOL)+27; + _NL_MONETARY_DUO_N_CS_PRECEDES = (__INT_CURR_SYMBOL)+28; + _NL_MONETARY_DUO_N_SEP_BY_SPACE = (__INT_CURR_SYMBOL)+29; + _NL_MONETARY_DUO_INT_P_CS_PRECEDES = (__INT_CURR_SYMBOL)+30; + _NL_MONETARY_DUO_INT_P_SEP_BY_SPACE = (__INT_CURR_SYMBOL)+31; + _NL_MONETARY_DUO_INT_N_CS_PRECEDES = (__INT_CURR_SYMBOL)+32; + _NL_MONETARY_DUO_INT_N_SEP_BY_SPACE = (__INT_CURR_SYMBOL)+33; + _NL_MONETARY_DUO_P_SIGN_POSN = (__INT_CURR_SYMBOL)+34; + _NL_MONETARY_DUO_N_SIGN_POSN = (__INT_CURR_SYMBOL)+35; + _NL_MONETARY_DUO_INT_P_SIGN_POSN = (__INT_CURR_SYMBOL)+36; + _NL_MONETARY_DUO_INT_N_SIGN_POSN = (__INT_CURR_SYMBOL)+37; + _NL_MONETARY_UNO_VALID_FROM = (__INT_CURR_SYMBOL)+38; + _NL_MONETARY_UNO_VALID_TO = (__INT_CURR_SYMBOL)+39; + _NL_MONETARY_DUO_VALID_FROM = (__INT_CURR_SYMBOL)+40; + _NL_MONETARY_DUO_VALID_TO = (__INT_CURR_SYMBOL)+41; + _NL_MONETARY_CONVERSION_RATE = (__INT_CURR_SYMBOL)+42; + _NL_MONETARY_DECIMAL_POINT_WC = (__INT_CURR_SYMBOL)+43; + _NL_MONETARY_THOUSANDS_SEP_WC = (__INT_CURR_SYMBOL)+44; + _NL_MONETARY_CODESET = (__INT_CURR_SYMBOL)+45; + _NL_NUM_LC_MONETARY = (__INT_CURR_SYMBOL)+46; + __DECIMAL_POINT = (__LC_NUMERIC shl 16); + RADIXCHAR = __DECIMAL_POINT; + __THOUSANDS_SEP = (__DECIMAL_POINT)+1; + THOUSEP = __THOUSANDS_SEP; + __GROUPING = (__THOUSANDS_SEP)+1; + _NL_NUMERIC_DECIMAL_POINT_WC = (__THOUSANDS_SEP)+2; + _NL_NUMERIC_THOUSANDS_SEP_WC = (__THOUSANDS_SEP)+3; + _NL_NUMERIC_CODESET = (__THOUSANDS_SEP)+4; + _NL_NUM_LC_NUMERIC = (__THOUSANDS_SEP)+5; + __YESEXPR = (__LC_MESSAGES shl 16); + __NOEXPR = ((__LC_MESSAGES shl 16))+1; + __YESSTR = ((__LC_MESSAGES shl 16))+2; + __NOSTR = ((__LC_MESSAGES shl 16))+3; + _NL_MESSAGES_CODESET = ((__LC_MESSAGES shl 16))+4; + _NL_NUM_LC_MESSAGES = ((__LC_MESSAGES shl 16))+5; + _NL_PAPER_HEIGHT = (__LC_PAPER shl 16); + _NL_PAPER_WIDTH = (_NL_PAPER_HEIGHT)+1; + _NL_PAPER_CODESET = (_NL_PAPER_HEIGHT)+2; + _NL_NUM_LC_PAPER = (_NL_PAPER_HEIGHT)+3; + _NL_NAME_NAME_FMT = (__LC_NAME shl 16); + _NL_NAME_NAME_GEN = (_NL_NAME_NAME_FMT)+1; + _NL_NAME_NAME_MR = (_NL_NAME_NAME_FMT)+2; + _NL_NAME_NAME_MRS = (_NL_NAME_NAME_FMT)+3; + _NL_NAME_NAME_MISS = (_NL_NAME_NAME_FMT)+4; + _NL_NAME_NAME_MS = (_NL_NAME_NAME_FMT)+5; + _NL_NAME_CODESET = (_NL_NAME_NAME_FMT)+6; + _NL_NUM_LC_NAME = (_NL_NAME_NAME_FMT)+7; + _NL_ADDRESS_POSTAL_FMT = (__LC_ADDRESS shl 16); + _NL_ADDRESS_COUNTRY_NAME = (_NL_ADDRESS_POSTAL_FMT)+1; + _NL_ADDRESS_COUNTRY_POST = (_NL_ADDRESS_POSTAL_FMT)+2; + _NL_ADDRESS_COUNTRY_AB2 = (_NL_ADDRESS_POSTAL_FMT)+3; + _NL_ADDRESS_COUNTRY_AB3 = (_NL_ADDRESS_POSTAL_FMT)+4; + _NL_ADDRESS_COUNTRY_CAR = (_NL_ADDRESS_POSTAL_FMT)+5; + _NL_ADDRESS_COUNTRY_NUM = (_NL_ADDRESS_POSTAL_FMT)+6; + _NL_ADDRESS_COUNTRY_ISBN = (_NL_ADDRESS_POSTAL_FMT)+7; + _NL_ADDRESS_LANG_NAME = (_NL_ADDRESS_POSTAL_FMT)+8; + _NL_ADDRESS_LANG_AB = (_NL_ADDRESS_POSTAL_FMT)+9; + _NL_ADDRESS_LANG_TERM = (_NL_ADDRESS_POSTAL_FMT)+10; + _NL_ADDRESS_LANG_LIB = (_NL_ADDRESS_POSTAL_FMT)+11; + _NL_ADDRESS_CODESET = (_NL_ADDRESS_POSTAL_FMT)+12; + _NL_NUM_LC_ADDRESS = (_NL_ADDRESS_POSTAL_FMT)+13; + _NL_TELEPHONE_TEL_INT_FMT = (__LC_TELEPHONE shl 16); + _NL_TELEPHONE_TEL_DOM_FMT = (_NL_TELEPHONE_TEL_INT_FMT)+1; + _NL_TELEPHONE_INT_SELECT = (_NL_TELEPHONE_TEL_INT_FMT)+2; + _NL_TELEPHONE_INT_PREFIX = (_NL_TELEPHONE_TEL_INT_FMT)+3; + _NL_TELEPHONE_CODESET = (_NL_TELEPHONE_TEL_INT_FMT)+4; + _NL_NUM_LC_TELEPHONE = (_NL_TELEPHONE_TEL_INT_FMT)+5; + _NL_MEASUREMENT_MEASUREMENT = (__LC_MEASUREMENT shl 16); + _NL_MEASUREMENT_CODESET = (_NL_MEASUREMENT_MEASUREMENT)+1; + _NL_NUM_LC_MEASUREMENT = (_NL_MEASUREMENT_MEASUREMENT)+2; + _NL_IDENTIFICATION_TITLE = (__LC_IDENTIFICATION shl 16); + _NL_IDENTIFICATION_SOURCE = (_NL_IDENTIFICATION_TITLE)+1; + _NL_IDENTIFICATION_ADDRESS = (_NL_IDENTIFICATION_TITLE)+2; + _NL_IDENTIFICATION_CONTACT = (_NL_IDENTIFICATION_TITLE)+3; + _NL_IDENTIFICATION_EMAIL = (_NL_IDENTIFICATION_TITLE)+4; + _NL_IDENTIFICATION_TEL = (_NL_IDENTIFICATION_TITLE)+5; + _NL_IDENTIFICATION_FAX = (_NL_IDENTIFICATION_TITLE)+6; + _NL_IDENTIFICATION_LANGUAGE = (_NL_IDENTIFICATION_TITLE)+7; + _NL_IDENTIFICATION_TERRITORY = (_NL_IDENTIFICATION_TITLE)+8; + _NL_IDENTIFICATION_AUDIENCE = (_NL_IDENTIFICATION_TITLE)+9; + _NL_IDENTIFICATION_APPLICATION = (_NL_IDENTIFICATION_TITLE)+10; + _NL_IDENTIFICATION_ABBREVIATION = (_NL_IDENTIFICATION_TITLE)+11; + _NL_IDENTIFICATION_REVISION = (_NL_IDENTIFICATION_TITLE)+12; + _NL_IDENTIFICATION_DATE = (_NL_IDENTIFICATION_TITLE)+13; + _NL_IDENTIFICATION_CATEGORY = (_NL_IDENTIFICATION_TITLE)+14; + _NL_IDENTIFICATION_CODESET = (_NL_IDENTIFICATION_TITLE)+15; + _NL_NUM_LC_IDENTIFICATION = (_NL_IDENTIFICATION_TITLE)+16; + _NL_NUM = (_NL_IDENTIFICATION_TITLE)+17; + +const + ERA_YEAR = __ERA_YEAR; + INT_CURR_SYMBOL = __INT_CURR_SYMBOL; + CURRENCY_SYMBOL = __CURRENCY_SYMBOL; + MON_DECIMAL_POINT = __MON_DECIMAL_POINT; + MON_THOUSANDS_SEP = __MON_THOUSANDS_SEP; + MON_GROUPING = __MON_GROUPING; + POSITIVE_SIGN = __POSITIVE_SIGN; + NEGATIVE_SIGN = __NEGATIVE_SIGN; + INT_FRAC_DIGITS = __INT_FRAC_DIGITS; + FRAC_DIGITS = __FRAC_DIGITS; + P_CS_PRECEDES = __P_CS_PRECEDES; + P_SEP_BY_SPACE = __P_SEP_BY_SPACE; + N_CS_PRECEDES = __N_CS_PRECEDES; + N_SEP_BY_SPACE = __N_SEP_BY_SPACE; + P_SIGN_POSN = __P_SIGN_POSN; + N_SIGN_POSN = __N_SIGN_POSN; + INT_P_CS_PRECEDES = __INT_P_CS_PRECEDES; + INT_P_SEP_BY_SPACE = __INT_P_SEP_BY_SPACE; + INT_N_CS_PRECEDES = __INT_N_CS_PRECEDES; + INT_N_SEP_BY_SPACE = __INT_N_SEP_BY_SPACE; + INT_P_SIGN_POSN = __INT_P_SIGN_POSN; + INT_N_SIGN_POSN = __INT_N_SIGN_POSN; + DECIMAL_POINT = __DECIMAL_POINT; + THOUSANDS_SEP = __THOUSANDS_SEP; + GROUPING = __GROUPING; + YESSTR = __YESSTR; + NOSTR = __NOSTR; +{$else} //bsd + LC_ALL = 0; + LC_COLLATE = 1; + LC_CTYPE = 2; + LC_MONETARY = 3; + LC_NUMERIC = 4; + LC_TIME = 5; + LC_MESSAGES = 6; + + _LC_LAST = 7; //* marks end */ + + CODESET = 0; //* codeset name */ + D_T_FMT = 1; //* string for formatting date and time */ + D_FMT = 2; //* date format string */ + T_FMT = 3; //* time format string */ + T_FMT_AMPM = 4; //* a.m. or p.m. time formatting string */ + AM_STR = 5; //* Ante Meridian affix */ + PM_STR = 6; //* Post Meridian affix */ + +//* week day names */ + DAY_1 = 7; + DAY_2 = 8; + DAY_3 = 9; + DAY_4 = 10; + DAY_5 = 11; + DAY_6 = 12; + DAY_7 = 13; + +//* abbreviated week day names */ + ABDAY_1 = 14; + ABDAY_2 = 15; + ABDAY_3 = 16; + ABDAY_4 = 17; + ABDAY_5 = 18; + ABDAY_6 = 19; + ABDAY_7 = 20; + +//* month names */ + MON_1 = 21; + MON_2 = 22; + MON_3 = 23; + MON_4 = 24; + MON_5 = 25; + MON_6 = 26; + MON_7 = 27; + MON_8 = 28; + MON_9 = 29; + MON_10 = 30; + MON_11 = 31; + MON_12 = 32; + +//* abbreviated month names */ + ABMON_1 = 33; + ABMON_2 = 34; + ABMON_3 = 35; + ABMON_4 = 36; + ABMON_5 = 37; + ABMON_6 = 38; + ABMON_7 = 39; + ABMON_8 = 40; + ABMON_9 = 41; + ABMON_10 = 42; + ABMON_11 = 43; + ABMON_12 = 44; + + ERA = 45; //* era description segments */ + ERA_D_FMT = 46; //* era date format string */ + ERA_D_T_FMT = 47; //* era date and time format string */ + ERA_T_FMT = 48; //* era time format string */ + ALT_DIGITS = 49; //* alternative symbols for digits */ + + RADIXCHAR = 50; //* radix char */ + DECIMAL_POINT = RADIXCHAR; + MON_DECIMAL_POINT = RADIXCHAR; + THOUSEP = 51; //* separator for thousands */ + THOUSANDS_SEP = THOUSEP; + MON_THOUSANDS_SEP = THOUSEP; + + YESEXPR = 52; //* affirmative response expression */ + NOEXPR = 53; //* negative response expression */ + +//#if __BSD_VISIBLE || __XSI_VISIBLE <= 500 + YESSTR = 54; //* affirmative response for yes/no queries */ + NOSTR = 55; //* negative response for yes/no queries */ +//#endif + + CRNCYSTR = 56; //* currency symbol */ + CURRENCY_SYMBOL = CRNCYSTR; + +//#if __BSD_VISIBLE + D_MD_ORDER = 57; //* month/day order (local extension) */ +//#endif + +//* standalone months forms for %OB */ + ALTMON_1 = 58; + ALTMON_2 = 59; + ALTMON_3 = 60; + ALTMON_4 = 61; + ALTMON_5 = 62; + ALTMON_6 = 63; + ALTMON_7 = 64; + ALTMON_8 = 65; + ALTMON_9 = 66; + ALTMON_10 = 67; + ALTMON_11 = 68; + ALTMON_12 = 69; + +{$endif} +type + Pnl_item = ^nl_item; + nl_item = longint; + +function nl_langinfo(__item: nl_item):Pchar; cdecl; external clib name 'nl_langinfo'; + +type + Psched_param = ^sched_param; + sched_param = record + __sched_priority : longint; + end; + __sched_param = sched_param; + P__sched_param = ^__sched_param; + TSchedParam = __sched_param; + PSchedParam = ^TSchedParam; + +//pthread +type + TStartRoutine = function (_para1:pointer): integer; cdecl;// pthread_create + Ppthread_condattr_t = ^pthread_condattr_t; + pthread_condattr_t = record + __dummy : longint; + end; + TPthreadCondattr = pthread_condattr_t; + PPthreadCondattr = ^TPthreadCondattr; +Const + PTHREAD_CREATE_JOINABLE = 0; + PTHREAD_CREATE_DETACHED = 1; + + PTHREAD_INHERIT_SCHED = 0; + PTHREAD_EXPLICIT_SCHED = 1; + + PTHREAD_SCOPE_SYSTEM = 0; + PTHREAD_SCOPE_PROCESS = 1; + + PTHREAD_MUTEX_TIMED_NP = 0; + PTHREAD_MUTEX_RECURSIVE_NP = 1; + PTHREAD_MUTEX_ERRORCHECK_NP = 2; + PTHREAD_MUTEX_ADAPTIVE_NP = 3; + PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_TIMED_NP; + PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP; + PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP; + PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL; + PTHREAD_MUTEX_FAST_NP = PTHREAD_MUTEX_ADAPTIVE_NP; + + PTHREAD_PROCESS_PRIVATE = 0; + PTHREAD_PROCESS_SHARED = 1; + + PTHREAD_RWLOCK_PREFER_READER_NP = 0; + PTHREAD_RWLOCK_PREFER_WRITER_NP = 1; + PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP = 2; + PTHREAD_RWLOCK_DEFAULT_NP = PTHREAD_RWLOCK_PREFER_WRITER_NP; + + PTHREAD_ONCE_INIT = 0; +type + P_pthread_fastlock = ^_pthread_fastlock; + _pthread_fastlock = record + __status : longint; + __spinlock : longint; + end; + Ppthread_mutexattr_t = ^pthread_mutexattr_t; + + pthread_mutexattr_t = record + case integer of + 0:( __mutexkind : longint); + 1:(buffer: pointer); + end; + + Ppthread_t = ^pthread_t; + pthread_t = culong; + P_pthread_descr = ^_pthread_descr; + _pthread_descr = pointer; // Opaque type. + + P__pthread_attr_s = ^__pthread_attr_s; + __pthread_attr_s = record + __detachstate : longint; + __schedpolicy : longint; + __schedparam : __sched_param; + __inheritsched : longint; + __scope : longint; + __guardsize : size_t; + __stackaddr_set : longint; + __stackaddr : pointer; + __stacksize : size_t; + end; + pthread_attr_t = __pthread_attr_s; + Ppthread_attr_t = ^pthread_attr_t; + +const + __SIZEOF_SEM_T = {$ifdef CPU64}32{$else}16{$endif}; +type +//semaphore + Psem_t = ^sem_t; + sem_t = array[0..__SIZEOF_SEM_T-1] of byte; + { + sem_t = record + __sem_lock : _pthread_fastlock; + __sem_value : longint; + __sem_waiting : _pthread_descr; + end; + } + TSemaphore = sem_t; + PSemaphore = ^TSemaphore; + + Psigval = ^sigval; + sigval = record + case longint of + 0 : ( sival_int : cint ); + 1 : ( sival_ptr : pointer ); + end; + sigval_t = sigval; + Psigval_t = ^sigval_t; + +const + __SI_MAX_SIZE = 128; + {$ifdef CPU64} + __SI_PAD_SIZE = ((__SI_MAX_SIZE div sizeof (cint)) - 4); + {$else} + __SI_PAD_SIZE = ((__SI_MAX_SIZE div sizeof (cint)) - 3); + {$endif} +type + _si_pad = packed array[0..__SI_PAD_SIZE-1] of cint; + + // Borland compatibility types moved here, needed for siginfo + _si_sigchld = record + si_pid: __pid_t; + si_uid: __uid_t; + si_status: cint; + si_utime: __clock_t; + si_stime: __clock_t; + end; + + _si_kill = record + si_pid: __pid_t; + si_uid: __uid_t; + end; + + _si_sigfault = record + si_addr: Pointer; + end; + _si_sigpoll = record + si_band: clong; + si_fd: cint; + end; + _si_timer = record + _timer1: longword; + _timer2: longword; + end; + _si_rt = record + si_pid: __pid_t; + si_uid: __uid_t; + si_sigval: sigval_t; + end; + Psiginfo = ^_siginfo; + _siginfo = record + si_signo : cint; + si_errno : cint; + si_code : cint; + Case integer of + 0: (_pad: _si_pad); + 1: (_kill: _si_kill); + 2: (_timer: _si_timer); + 3: (_rt: _si_rt); + 4: (_sigchld: _si_sigchld); + 5: (_sigfault: _si_sigfault); + 6: (_sigpoll: _si_sigpoll); + end; + siginfo_t = _siginfo; + Psiginfo_t = ^siginfo_t; + Tsiginfo_t = siginfo_t; + + TSigActionHandlerEx = procedure(Signal: Integer; SignalInfo: PSigInfo; + P: Pointer); cdecl; + TRestoreHandler = procedure; cdecl; + +type + P__sig_atomic_t = ^__sig_atomic_t; + __sig_atomic_t = longint; +Const + _SIGSET_NWORDS = 1024 div (8 * (sizeof(dword))); +const +{$ifdef linux} + SA_NOCLDSTOP = 1; + SA_NOCLDWAIT = 2; + SA_SIGINFO = 4; + SA_ONSTACK = $08000000; + SA_RESTART = $10000000; + SA_NODEFER = $40000000; + SA_RESETHAND = $80000000; + + SA_INTERRUPT = $20000000; + SA_NOMASK = SA_NODEFER; + SA_ONESHOT = SA_RESETHAND; + SA_STACK = SA_ONSTACK; +{$else} + SA_ONSTACK = $0001; //* take signal on signal stack */ + SA_RESTART = $0002; //* restart system call on signal return */ + SA_RESETHAND = $0004; //* reset to SIG_DFL when taking signal */ + SA_NODEFER = $0010; //* don't mask the signal we're delivering */ + SA_NOCLDWAIT = $0020; //* don't keep zombies around */ + SA_SIGINFO = $0040; //* signal handler with SA_SIGINFO args */ +{$endif} + +type + P__sigset_t = ^__sigset_t; + __sigset_t = record + __val : array[0..(_SIGSET_NWORDS)-1] of dword; + end; + sigset_t = __sigset_t; + Psigset_t = ^sigset_t; + TSigset = __sigset_t; + PSigset = ^TSigset; + + TSigActionEx = packed record + sa_sigaction: TSigActionHandlerEx; + sa_mask: __sigset_t; + sa_flags: Integer; + sa_restorer: TRestoreHandler; + end; +type + __sighandler_t = procedure(SigNum: Integer); cdecl; + TSignalHandler = __sighandler_t; + P_sigaction = ^_sigaction; + _sigaction = record // Renamed, avoid conflict with sigaction function + case integer of + 1: (sa_handler : __sighandler_t; + sa_mask : __sigset_t; + sa_flags : longint; + sa_restorer : procedure ;cdecl; + ); + // Kylix compatibility + 2: (__sigaction_handler: __sighandler_t); + end; + TSigAction = _sigaction; + PSigAction = ^TSigAction; + __sigaction = _sigaction; + TSigActionHandler = procedure(Signal: Integer); cdecl; + +const + __S_IFMT = $F000; + __S_IFDIR = $4000; + __S_IFCHR = $2000; + __S_IFBLK = $6000; + __S_IFREG = $8000; + __S_IFIFO = $1000; + __S_IFLNK = $A000; + __S_IFSOCK = $C000; + + S_IFMT = __S_IFMT; + S_IFDIR = __S_IFDIR; + S_IFCHR = __S_IFCHR; + S_IFBLK = __S_IFBLK; + S_IFREG = __S_IFREG; + S_IFIFO = __S_IFIFO; + S_IFLNK = __S_IFLNK; + S_IFSOCK = __S_IFSOCK; + +function sigaction(__sig:longint; Const act: _sigaction; + Var oldact: _sigaction):longint; + cdecl;external clib name 'sigaction'; overload; +function sigaction(__sig: longint; Action: PSigAction; + OldAction: PSigAction): Integer; + cdecl;external clib name 'sigaction'; overload; + +//function m_sigprocmask(__how:longint; var SigSet : TSigSet; +// var oldset: Tsigset):longint;cdecl;external clib name 'sigprocmask'; +//function m_sigismember(var SigSet : TSigSet; SigNum : Longint):longint;cdecl;external clib name 'sigismember'; + +const + __SIZEOF_PTHREAD_MUTEX_T = {$ifdef CPU64}40{$else}24{$endif}; +type + Ppthread_mutex_t = ^pthread_mutex_t; + pthread_mutex_t = array[0..__SIZEOF_PTHREAD_MUTEX_T-1] of byte; +{ + pthread_mutex_t = record + __m_reserved : longint; + __m_count : longint; + __m_owner : _pthread_descr; + __m_kind : longint; + __m_lock : _pthread_fastlock; + end; +} + DIR = record end; + __dirstream = DIR; + PDIR = ^DIR; + + TDirectoryStream = DIR; + PDirectoryStream = ^TDirectoryStream; + + Ptimeval = ^timeval; + timeval = record + tv_sec : __time_t; + tv_usec : __suseconds_t; + end; + TTimeVal = timeval; + timezone = record + tz_minuteswest: Integer; + tz_dsttime: Integer; + end; + ptimezone = ^timezone; + + P__timezone_ptr_t = ^__timezone_ptr_t; + __timezone_ptr_t = ^timezone; + + passwd = record + pw_name: pcchar; //* user name */ + pw_passwd: pcchar; //* encrypted password */ + pw_uid: uid_t; //* user uid */ + pw_gid: gid_t; //* user gid */ + pw_change: time_t; //* password change time */ + pw_class: pcchar; //* user access class */ + pw_gecos: pcchar; //* Honeywell login info */ + pw_dir: pcchar; //* home directory */ + pw_shell: pcchar; //* default shell */ + pw_expire: time_t; //* account expiration */ + pw_fields: cint; //* internal: fields filled in */ + end; + ppasswd = ^passwd; + pppasswd = ^ppasswd; + +function getpid:__pid_t;cdecl;external clib name 'getpid'; +function getuid(): uid_t cdecl;external clib name 'getuid'; +function geteuid(): uid_t cdecl;external clib name 'geteuid'; + //function cuserid (_string: pcchar): pcchar; cdecl; external clib name 'cuserid'; + //not available on freebsd +function sscanf(__s:Pchar; __format:Pchar; args:array of const):longint;cdecl;external clib name 'sscanf'; +function sched_yield:longint;cdecl;external clib name 'sched_yield'; +function usleep(__useconds:__useconds_t):longint;cdecl;external clib name 'usleep'; +{$ifdef linux} +function __errno_location: PInteger; cdecl;external clib name '__errno_location'; +{$else} +function __errno_location: PInteger; cdecl;external clib name '__error'; +{$endif} +function strerror_r(__errnum:longint; __buf:Pchar; __buflen:size_t):Pchar;cdecl;external clib name 'strerror_r'; + +var + getpwuid_r: function(uid: uid_t; pwd: ppasswd; buffer: pchar; bufsize: size_t; + _result: pppasswd): cint cdecl; + cuserid: function(_string: pcchar): pcchar cdecl; + +//termios +const + NCCS = 32; +type + Pcc_t = ^cc_t; + cc_t = char; + + Pspeed_t = ^speed_t; + speed_t = dword; + + Ptcflag_t = ^tcflag_t; + tcflag_t = dword; + + Ptermios = ^termios; + termios = record + c_iflag : tcflag_t; + c_oflag : tcflag_t; + c_cflag : tcflag_t; + c_lflag : tcflag_t; + c_line : cc_t; + c_cc : array[0..(NCCS)-1] of cc_t; + c_ispeed : speed_t; + c_ospeed : speed_t; + end; + +const + DT_UNKNOWN = 0; + DT_FIFO = 1; + DT_CHR = 2; + DT_DIR = 4; + DT_BLK = 6; + DT_REG = 8; + DT_LNK = 10; + DT_SOCK = 12; + DT_WHT = 14; +type + Pdirent64 = ^dirent64; +{$ifdef linux} + dirent64 = record + d_ino : __ino64_t; + d_off : __off64_t; + d_reclen : word; + d_type : byte; + d_name : array[0..255] of char; + end; +{$else} + dirent64 = record + d_fileno: cuint32; //* file number of entry */ + d_reclen: cuint16; //* length of this record */ + d_type: cuint8; //* file type, see below */ + d_namlen: cuint8; //* length of string in d_name */ + d_name: array[0..255] of char; //* name must be no longer than this */ + end; +{$endif} + + PPDirEnt64 = ^PDirEnt64; + + time_t = __time_t; + Ptime_t = ^time_t; + + Ptm = ^tm; + tm = record + tm_sec : longint; + tm_min : longint; + tm_hour : longint; + tm_mday : longint; + tm_mon : longint; + tm_year : longint; + tm_wday : longint; + tm_yday : longint; + tm_isdst : longint; + case boolean of + false : (tm_gmtoff : longint;tm_zone : Pchar); + true : (__tm_gmtoff : longint;__tm_zone : Pchar); + end; + TMutexAttribute = pthread_mutexattr_t; + PMutexAttribute = ^TMutexAttribute; + +function pthread_mutexattr_init(var __attr: pthread_mutexattr_t):longint;cdecl; external threadslib; +function pthread_mutexattr_settype(var __attr: pthread_mutexattr_t; Kind: Integer): Integer; cdecl;external threadslib; +function pthread_mutexattr_destroy(var __attr: pthread_mutexattr_t):longint;cdecl; external threadslib; +function __mkdir(__path:Pchar; __mode:__mode_t):longint;cdecl; + external clib name 'mkdir'; +function fcntl(__fd: cint; __cmd: cint; args: array of const): cint; + cdecl; external clib name 'fcntl'; overload; +function fcntl(__fd: cint; __cmd: cint): cint; + cdecl; varargs; external clib name 'fcntl'; overload; +function open(__file:Pchar; __oflag: cint; args:array of const): cint; + cdecl; external clib name 'open'; overload; +function open(__file:Pchar; __oflag: cint): cint; + cdecl; varargs; external clib name 'open'; overload; +function __close(Handle: cint): cint; cdecl;external clib name 'close'; +{$ifdef linux} +function ftruncate64(handle: cint; size: cint64): cint; cdecl; + external clib name 'ftruncate64'; +{$else} +function ftruncate64(handle: cint; size: cint64): cint; cdecl; + external clib name 'ftruncate'; +{$endif} +//from unistd.h +//* Values for the second argument to access. +// These may be OR'd together. */ +const + R_OK = 4; //* Test for read permission. */ + W_OK = 2; //* Test for write permission. */ + X_OK = 1; //* Test for execute permission. */ + F_OK = 0; //* Test for existence. */ + +//* Test for access to NAME using the real UID and real GID. */ +function access(__name: pchar; __type: cint): cint; + cdecl; external clib name 'access'; + +function fsync(__fd: cint): cint; cdecl; external clib name 'fsync'; +function dup(__fd: cint): cint; cdecl; external clib name 'dup'; +function dup2(__fd: cint; __fd2: cint):longint; cdecl; external clib name 'dup2'; +function __read(Handle: cint; var Buffer; Count: size_t): ssize_t; + cdecl; external clib name 'read'; +function __write(Handle: cint; const Buffer; Count: size_t): ssize_t; + cdecl; external clib name 'write'; + +function chmod(__file: pchar;__mode: __mode_t): cint; + cdecl; external clib name 'chmod'; +function fchmod(__fd: cint;__mode: __mode_t): cint; + cdecl; external clib name 'fchmod'; + +function sem_init(__sem:Psem_t; __pshared: cint; __value: cuint): cint; + cdecl; external threadslib name 'sem_init'; overload; +function sem_init(var __sem: sem_t; __pshared: cint; __value: cuint): cint; + cdecl; external threadslib name 'sem_init'; overload; +function sem_destroy(var __sem: sem_t): cint; + cdecl; external threadslib name 'sem_destroy'; +function sem_post(var __sem: sem_t): cint; + cdecl; external threadslib name 'sem_post'; +function sem_wait(var __sem: sem_t): cint; + cdecl; external threadslib name 'sem_wait'; +function sem_trywait(var __sem: sem_t): cint; + cdecl; external threadslib name 'sem_trywait'; +function sem_getvalue(var __sem: sem_t; __sval:Plongint):longint;cdecl;external threadslib name 'sem_getvalue'; + +Const + PTHREAD_CANCEL_ENABLE = 0; + PTHREAD_CANCEL_DISABLE = 1; + + PTHREAD_CANCEL_DEFERRED = 0; + PTHREAD_CANCEL_ASYNCHRONOUS = 1; + + PTHREAD_CANCELED = Pointer(-1); + PTHREAD_BARRIER_SERIAL_THREAD = -1; + + NONRECURSIVE = 0; + {$ifdef linux} + RECURSIVE = 1; + {$else} + RECURSIVE = 2; + {$endif} + +function pthread_setcanceltype(__type:longint; var __oldtype:longint):longint; + cdecl; external threadslib; overload; +function pthread_setcanceltype(__type:longint; __oldtype:Plongint):longint; + cdecl;external threadslib name 'pthread_setcanceltype'; overload; +function pthread_setcancelstate(__state:longint;__oldstate:Plongint):longint; + cdecl;external threadslib name 'pthread_setcancelstate'; +function pthread_equal(__thread1:pthread_t; __thread2:pthread_t):longint; + cdecl;external threadslib name 'pthread_equal'; +function pthread_self:pthread_t;cdecl;external threadslib name 'pthread_self'; + +const + _STAT_VER_LINUX_OLD = 1; + _STAT_VER_KERNEL = 1; + _STAT_VER_SVR4 = 2; +{$ifdef CPU64} + _STAT_VER_LINUX = 1; +{$else} + _STAT_VER_LINUX = 3; +{$endif} + _STAT_VER = _STAT_VER_LINUX; + +{$ifdef linux} + +function __fxstat(__ver:longint; __fildes:longint; __stat_buf:Pstat):longint; + cdecl;external clib name '__fxstat'; +function __xstat(__ver:longint; __filename:Pchar; __stat_buf:Pstat):longint; + cdecl;external clib name '__xstat'; +function __lxstat(__ver:longint; __filename:Pchar; __stat_buf:Pstat):longint; + cdecl;external clib name '__lxstat'; +{$ifndef CPU64} +function __fxstat64(__ver:longint; __fildes:longint; __stat_buf:Pstat64):longint; + cdecl;external clib name '__fxstat64'; +function __xstat64(__ver:longint; __filename:Pchar; __stat_buf:Pstat64):longint; + cdecl;external clib name '__xstat64'; +function __lxstat64(__ver:longint; __filename:Pchar; __stat_buf:Pstat64):longint; + cdecl;external clib name '__lxstat64'; +{$endif} +function stat(__file:Pchar; __buf:Pstat):longint; +function fstat(__fd:longint; __buf:Pstat):longint; + +function stat64(__file:Pchar; __buf:Pstat64):longint; +function fstat64(__fd:longint; __buf:Pstat64):longint; +function lstat(__file:Pchar; __buf:Pstat):longint; +function lstat64(__file:Pchar; __buf:Pstat64):longint; +{$else} //linux +function stat(__file:Pchar; __buf:Pstat):longint; cdecl; + external clib name 'stat'; +function fstat(__fd:longint; __buf:Pstat):longint; cdecl; + external clib name 'fstat'; +function stat64(__file:Pchar; __buf:Pstat64):longint; cdecl; + external clib name 'stat'; +function fstat64(__fd:longint; __buf:Pstat64):longint; cdecl; + external clib name 'fstat'; +function lstat(__file:Pchar; __buf:Pstat):longint; cdecl; + external clib name 'lstat'; +function lstat64(__file:Pchar; __buf:Pstat64):longint; cdecl; + external clib name 'lstat'; +{$endif} //not linux + +function flock(fd: cint; operation: cint): cint; cdecl; + external clib name 'flock'; + +function S_ISDIR(mode : __mode_t) : boolean; + +//function fchmod(__fd: longint; __mode:__mode_t):longint;cdecl;external clib name 'fchmod'; +function __rename(__old: Pchar; __new:Pchar):longint;cdecl;external clib name 'rename'; +function unlink(__name: Pchar): longint;cdecl;external clib name 'unlink'; +function rmdir(__name: Pchar): longint;cdecl;external clib name 'rmdir'; +function getcwd(__buf: Pchar; __size:size_t):Pchar;cdecl;external clib name 'getcwd'; +function getenv(__name: Pchar): Pchar; cdecl; external clib name 'getenv'; +function setenv(envname: pchar; envval: pchar; + overwrite: cint): cint; cdecl; external clib name 'setenv'; +function putenv(astring: Pchar): longint; cdecl; external clib name 'putenv'; +function unsetenv(envname: pchar): cint; cdecl; external clib name 'unsetenv'; + +function __chdir(__path:Pchar):longint;cdecl;external clib name 'chdir'; +function opendir(__name:Pchar):PDIR;cdecl;external clib name 'opendir'; +function closedir(__dirp:PDIR):longint;cdecl;external clib name 'closedir'; + +var + environ : ppchar; cvar; external; + +type + TUnixTime = tm; + PUnixTime = ^TUnixTime; + TTime_T = Time_t; +function __time(var __timer : ttime_t):time_t;cdecl; + external clib name 'time'; overload; +function __time(__timer:Ptime_t):time_t; + cdecl;external clib name 'time'; overload; +function timelocal(var __tp: tm):time_t;cdecl;external clib name 'timelocal'; +function setlocale(__category:longint; __locale:Pchar):Pchar;cdecl; + external clib name 'setlocale'; +var + clock_gettime: function(clk_id: cint; tp: ptimespec): cint; cdecl; + +const +{$ifdef linux} + CLOCK_REALTIME = 0; + CLOCK_MONOTONIC = 1; + CLOCK_PROCESS_CPUTIME_ID = 2; + CLOCK_THREAD_CPUTIME_ID = 3; +{$else} + CLOCK_REALTIME = 0; + CLOCK_VIRTUAL = 1; + CLOCK_PROF = 2; + CLOCK_MONOTONIC = 4; + CLOCK_UPTIME = 5; //* FreeBSD-specific. */ + CLOCK_UPTIME_PRECISE = 7; //* FreeBSD-specific. */ + CLOCK_UPTIME_FAST = 8; //* FreeBSD-specific. */ + CLOCK_REALTIME_PRECISE = 9; //* FreeBSD-specific. */ + CLOCK_REALTIME_FAST = 10; //* FreeBSD-specific. */ + CLOCK_MONOTONIC_PRECISE = 11; //* FreeBSD-specific. */ + CLOCK_MONOTONIC_FAST = 12; //* FreeBSD-specific. */ + CLOCK_SECOND = 13; //* FreeBSD-specific. */ + CLOCK_THREAD_CPUTIME_ID = 14; + CLOCK_PROCESS_CPUTIME_ID = 15; +{$endif} + TIMER_ABSTIME = 1; + +const + SIG_ERR = (-1); + SIG_DFL = (0); + SIG_IGN = (1); + {$ifdef linux} + SIG_HOLD = (2); + {$else} + SIG_HOLD = (3); + {$endif} + {$ifdef linux} + SIGHUP = 1; + SIGINT = 2; + SIGQUIT = 3; + SIGILL = 4; + SIGTRAP = 5; + SIGABRT = 6; + SIGIOT = 6; + SIGBUS = 7; + SIGFPE = 8; + SIGKILL = 9; + SIGUSR1 = 10; + SIGSEGV = 11; + SIGUSR2 = 12; + SIGPIPE = 13; + SIGALRM = 14; + SIGTERM = 15; + SIGSTKFLT = 16; + SIGCHLD = 17; + SIGCLD = SIGCHLD; + SIGCONT = 18; + SIGSTOP = 19; + SIGTSTP = 20; + SIGTTIN = 21; + SIGTTOU = 22; + SIGURG = 23; + SIGXCPU = 24; + SIGXFSZ = 25; + SIGVTALRM = 26; + SIGPROF = 27; + SIGWINCH = 28; + SIGIO = 29; + SIGPOLL = SIGIO; + SIGPWR = 30; + SIGSYS = 31; + SIGUNUSED = 31; + _NSIG = 64; +{$else} + SIGHUP = 1; //* hangup */ + SIGINT = 2; //* interrupt */ + SIGQUIT = 3; //* quit */ + SIGILL = 4; //* illegal instr. (not reset when caught) */ + SIGTRAP = 5; //* trace trap (not reset when caught) */ + SIGABRT = 6; //* abort() */ + SIGIOT = SIGABRT; //* compatibility */ + SIGEMT = 7; //* EMT instruction */ + SIGFPE = 8; //* floating point exception */ + SIGKILL = 9; //* kill (cannot be caught or ignored) */ + SIGBUS = 10; //* bus error */ + SIGSEGV = 11; //* segmentation violation */ + SIGSYS = 12; //* non-existent system call invoked */ + SIGPIPE = 13; //* write on a pipe with no one to read it */ + SIGALRM = 14; //* alarm clock */ + SIGTERM = 15; //* software termination signal from kill */ + SIGURG = 16; //* urgent condition on IO channel */ + SIGSTOP = 17; //* sendable stop signal not from tty */ + SIGTSTP = 18; //* stop signal from tty */ + SIGCONT = 19; //* continue a stopped process */ + SIGCHLD = 20; //* to parent on child stop or exit */ + SIGTTIN = 21; //* to readers pgrp upon background tty read */ + SIGTTOU = 22; //* like TTIN if (tp->t_local<OSTOP) */ + SIGIO = 23; //* input/output possible signal */ + SIGXCPU = 24; //* exceeded CPU time limit */ + SIGXFSZ = 25; //* exceeded file size limit */ + SIGVTALRM = 26; //* virtual time alarm */ + SIGPROF = 27; //* profiling time alarm */ + SIGWINCH = 28; //* window size changes */ + SIGINFO = 29; //* information request */ + SIGUSR1 = 30; //* user defined signal 1 */ + SIGUSR2 = 31; //* user defined signal 2 */ + SIGTHR = 32; //* reserved by thread library. */ + SIGLWP = SIGTHR; + SIGLIBRT = 33; //* reserved by real-time library. */ +{$endif} +type + Psighandler_t = ^sighandler_t; + sighandler_t = __sighandler_t; + + __itimer_which = ( + ITIMER_REAL, // := 0, + ITIMER_VIRTUAL,// := 1, + ITIMER_PROF // := 2 + ); + + Pitimerval = ^itimerval; + itimerval = record + it_interval : timeval; + it_value : timeval; + end; + + P__itimer_which_t = ^__itimer_which_t; + __itimer_which_t = __itimer_which; + +function setitimer(__which: __itimer_which_t; __new:Pitimerval; + __old:Pitimerval):longint;cdecl;external clib name 'setitimer'; +type + wint_t = longword; + __mbstate_t = record + count: Integer; + case { __value } Integer of + 0: (__wch: wint_t); + 1: (__wchb: packed array[0..4 - 1] of Char); + end; + mbstate_t = __mbstate_t; + Pmbstate_t = ^mbstate_t; + +function mbsnrtowcs(__dst:Pwchar_t; __src:PPchar; __nmc:size_t; __len:size_t; __ps:Pmbstate_t):size_t;cdecl;external clib name 'mbsnrtowcs'; + +const + POLLIN = $001; + POLLPRI = $002; + POLLOUT = $004; + + POLLRDNORM = $040; + POLLRDBAND = $080; + POLLWRNORM = $100; + POLLWRBAND = $200; + + POLLMSG = $400; + + POLLERR = $008; + POLLHUP = $010; + POLLNVAL = $020; +type + Pnfds_t = ^nfds_t; + nfds_t = dword; + + Ppollfd = ^pollfd; + pollfd = record + fd : longint; + events : smallint; + revents : smallint; + end; +function poll(__fds: Ppollfd; __nfds:nfds_t; __timeout:longint): cint + cdecl external clib name 'poll'; +function ppoll (__fds: ppollfd;__nfds: nfds_t; __timeout: ptimespec; + __ss: p__sigset_t): cint + cdecl external clib name 'ppoll'; +const +{$ifdef linux} + SIG_BLOCK = 0; + SIG_UNBLOCK = 1; + SIG_SETMASK = 2; +{$else} + SIG_BLOCK = 1; //* block specified signal set */ + SIG_UNBLOCK = 2; //* unblock specified signal set */ + SIG_SETMASK =3; //* set specified signal set */ +{$endif} + +function signal(__sig:longint; __handler:__sighandler_t):__sighandler_t; + cdecl; external clib name 'signal'; +function sigemptyset(var SigSet : TSigSet):longint; + cdecl; external clib name 'sigemptyset'; +function sigfillset(var SigSet : TSigSet):longint; + cdecl; external clib name 'sigfillset'; +function sigaddset(var SigSet : TSigSet; SigNum : Longint):longint; + cdecl; external clib name 'sigaddset'; +function sigdelset(var SigSet : TSigSet; SigNum : Longint):longint; + cdecl; external clib name 'sigdelset'; +function sigismember(var SigSet : TSigSet; SigNum : Longint):longint; + cdecl; external clib name 'sigismember'; +function sigprocmask(__how: cint; sigset: p__sigset_t; + oldset: p__sigset_t):longint; + cdecl; external clib name 'sigprocmask'; +function pthread_sigmask(__how: cint; __newmask: p__sigset_t; + __oldmask: p__sigset_t):longint; cdecl; + external threadslib name 'pthread_sigmask'; + +function kill(__pid:__pid_t; __sig:longint):longint;cdecl; + external clib name 'kill'; +{$ifdef linux} +function getpt:longint;cdecl;external clib name 'getpt'; +{$else} +function posix_openpt(oflag: cint):longint; cdecl; + external clib name 'posix_openpt'; +function getpt(): longint; +{$endif} +function grantpt(__fd:longint):longint;cdecl;external clib name 'grantpt'; +function unlockpt(__fd:longint):longint;cdecl;external clib name 'unlockpt'; +{$ifdef linux} +function ptsname_r(__fd:longint; __buf:Pchar; __buflen:size_t):longint;cdecl;external clib name 'ptsname_r'; +{$else} +function ptsname(fildes: cint): pchar; cdecl; external clib name 'ptsname'; +function ptsname_r(__fd:longint; __buf:Pchar; __buflen:size_t):longint; +{$endif} + +const + VINTR = 0; + VQUIT = 1; + VERASE = 2; + VKILL = 3; + VEOF = 4; + VTIME = 5; + VMIN = 6; + VSWTC = 7; + VSTART = 8; + VSTOP = 9; + VSUSP = 10; + VEOL = 11; + VREPRINT = 12; + VDISCARD = 13; + VWERASE = 14; + VLNEXT = 15; + VEOL2 = 16; + + IGNBRK = $0000001; + BRKINT = $0000002; + IGNPAR = $0000004; + PARMRK = $0000008; + INPCK = $0000010; + ISTRIP = $0000020; + INLCR = $0000040; + IGNCR = $0000080; + ICRNL = $0000100; + IUCLC = $0000200; + IXON = $0000400; + IXANY = $0000800; + IXOFF = $0001000; + IMAXBEL = $0002000; + + OPOST = $0000001; + OLCUC = $0000002; + ONLCR = $0000004; + OCRNL = $0000008; + ONOCR = $0000010; + ONLRET = $0000020; + OFILL = $0000040; + OFDEL = $0000080; + + NLDLY = $0000040; + NL0 = $0000000; + NL1 = $0000100; + CRDLY = $0000600; + CR0 = $0000000; + CR1 = $0000200; + CR2 = $0000400; + CR3 = $0000600; + TABDLY = $0001800; + TAB0 = $0000000; + TAB1 = $0000800; + TAB2 = $0001000; + TAB3 = $0001800; + BSDLY = $0002000; + BS0 = $0000000; + BS1 = $0002000; + FFDLY = $0080000; + FF0 = $0000000; + FF1 = $0010000; + + VTDLY = $0004000; + VT0 = $0000000; + VT1 = $0004000; + + XTABS = $0001800; + + CBAUD = $000100F; + B0 = $0000000; + B50 = $0000001; + B75 = $0000002; + B110 = $0000003; + B134 = $0000004; + B150 = $0000005; + B200 = $0000006; + B300 = $0000007; + B600 = $0000008; + B1200 = $0000009; + B1800 = $000000A; + B2400 = $000000B; + B4800 = $000000C; + B9600 = $000000D; + B19200 = $000000E; + B38400 = $000000F; + + EXTA = B19200; + EXTB = B38400; + + CSIZE = $0000030; + CS5 = $0000000; + CS6 = $0000010; + CS7 = $0000010; + CS8 = $0000030; + CSTOPB = $0000040; + CREAD = $0000080; + PARENB = $0000100; + PARODD = $0000200; + HUPCL = $0000400; + CLOCAL = $0000800; + + CBAUDEX = $0001000; + + B57600 = $0001001; + B115200 = $0001002; + B230400 = $0001003; + B460800 = $0001004; + B500000 = $0001005; + B576000 = $0001006; + B921600 = $0001007; + B1000000 = $0001008; + B1152000 = $0001009; + B1500000 = $000100A; + B2000000 = $000100B; + B2500000 = $000100C; + B3000000 = $000100D; + B3500000 = $000100E; + B4000000 = $000100F; + + CIBAUD = $100F0000; + CRTSCTS = $80000000; + + ISIG = $0000001; + ICANON = $0000002; + + XCASE = $0000004; + + ECHO = $0000008; + ECHOE = $0000010; + ECHOK = $0000020; + ECHONL = $0000040; + NOFLSH = $0000080; + TOSTOP = $0000100; + + ECHOCTL = $0000200; + ECHOPRT = $0000400; + ECHOKE = $0000800; + FLUSHO = $0001000; + PENDIN = $0004000; + + IEXTEN = $0010000; + + + + TCOOFF = 0; + TCOON = 1; + TCIOFF = 2; + TCION = 3; + TCIFLUSH = 0; + TCOFLUSH = 1; + TCIOFLUSH = 2; + TCSANOW = 0; + TCSADRAIN = 1; + TCSAFLUSH = 2; + {$ifdef bsd} + SIGRTMIN = 65; + SIGRTMAX = 126; + {$else} +function SIGRTMIN(): cint; cdecl; external clib name '__libc_current_sigrtmin'; +function SIGRTMAX(): cint; cdecl; external clib name '__libc_current_sigrtmax'; + {$endif} +function ioctl(__fd: cint; __request:dword; args: array of const): cint; + cdecl;external clib name 'ioctl'; overload; +function ioctl(__fd: cint; __request: cuint; args: pointer): cint; + cdecl;external clib name 'ioctl'; overload; +function cfsetispeed(var __termios_p: termios; __speed:speed_t): cint; + cdecl;external clib name 'cfsetispeed'; +function cfsetospeed(var __termios_p: termios; __speed:speed_t): cint; + cdecl;external clib name 'cfsetospeed'; +function isatty(__fd: cint): cint; cdecl; external clib name 'isatty'; +function ttyname(__fd: cint): pchar; cdecl; external clib name 'ttyname'; +function ttyname_r(__fd: cint; buf: pchar; buflen: size_t): cint; + cdecl; external clib name 'ttyname_r'; + +const + TIOCM_LE = $001; + TIOCM_DTR = $002; + TIOCM_RTS = $004; + TIOCM_ST = $008; + TIOCM_SR = $010; + TIOCM_CTS = $020; + TIOCM_CAR = $040; + TIOCM_RNG = $080; + TIOCM_DSR = $100; + TIOCM_CD = TIOCM_CAR; + TIOCM_RI = TIOCM_RNG; + N_TTY = 0; + N_SLIP = 1; + N_MOUSE = 2; + N_PPP = 3; + N_STRIP = 4; + N_AX25 = 5; + N_X25 = 6; + N_6PACK = 7; + N_MASC = 8; + N_R3964 = 9; + N_PROFIBUS_FDL = 10; + N_IRDA = 11; + N_SMSBLOCK = 12; + N_HDLC = 13; + N_SYNC_PPP = 14; + N_HCI = 15; + +function gettimeofday(var __tv: timeval; var _tz: timezone):longint; + cdecl;external clib name 'gettimeofday'; overload; +function gettimeofday(var __tv: timeval; __tz:__timezone_ptr_t):longint; + cdecl;external clib name 'gettimeofday'; overload; +function pthread_kill(__thread:pthread_t; __signo:longint):longint; + cdecl;external threadslib name 'pthread_kill'; +const + WNOHANG = 1; + WUNTRACED = 2; + __WALL = $40000000; + __WCLONE = $80000000; +function waitpid(__pid:__pid_t; __stat_loc:Plongint; __options:longint):__pid_t; + cdecl;external clib name 'waitpid'; overload; +function waitpid(__pid:__pid_t; var __stat_loc:longint; + __options:longint):__pid_t; + cdecl;external clib name 'waitpid'; overload; + +function WEXITSTATUS(status: cint): cint; +function WTERMSIG(status: cint): cint; +function WIFEXITED(status: cint): boolean; +function WIFSIGNALED(status: cint): boolean; + +function __system(__command:Pchar):longint;cdecl;external clib name 'system'; +type + TPipeDescriptors = {packed} record + ReadDes: Integer; + WriteDes: Integer; + end; + PPipeDescriptors = ^TPipeDescriptors; + + TPipes = Array[0..1] of longint; + PPipes = ^TPipes; + +function pipe(var __pipedes: TPipes):longint; + cdecl; external clib name 'pipe'; overload; +function pipe(var PipeDes: TPipeDescriptors): Integer; cdecl; + external clib name 'pipe'; overload; +function pipe2(var PipeDes: TPipeDescriptors; flags: cint): Integer; cdecl; + external clib name 'pipe2'; + +function vfork: __pid_t; cdecl; external clib name 'vfork'; +function fork: __pid_t; cdecl; external clib name 'fork'; +function setsid: __pid_t; cdecl; external clib name 'setsid'; +function getsid(pid: __pid_t): __pid_t; cdecl; external clib name 'getsid'; +function setpgid(__pid:__pid_t; __pgid:__pid_t):longint; cdecl; + external clib name 'setpgid'; +function getpgid(pid: __pid_t): __pid_t; cdecl; external clib name 'getpgid'; + +const + EXIT_FAILURE = 1; + EXIT_SUCCESS = 0; + +procedure _exit (__status : longint); cdecl; external clib name '_exit'; +function execl(__path:Pchar; __arg:Pchar):longint; + cdecl;varargs;external clib name 'execl'; overload; +function execl(__path:Pchar; __arg:Pchar; args:array of const):longint; + cdecl;external clib name 'execl'; overload; +function execv (__path: pcchar; __argv: ppchar): cint; + cdecl;external clib name 'execv'; +function execve(__path: pcchar; __argv: ppchar; __envp:ppchar): cint; + cdecl;external clib name 'execve'; + +Type + error_t = Integer; + +function errno : error_t; +procedure free(__ptr:pointer);cdecl;external clib name 'free'; + +type + Psa_family_t = ^sa_family_t; + sa_family_t = word; + SunB = record + s_b1, + s_b2, + s_b3, + s_b4: u_char; + end; + + SunW = record + s_w1, + s_w2: u_short; + end; + in_addr = record + case Integer of + 0: (S_un_b: SunB); + 1: (S_un_w: SunW); + 2: (S_addr: u_long); + end; + TInAddr = in_addr; + PInAddr = ^TInAddr; + {$ifdef linux} + sockaddr = {packed} record + case Integer of + 0: (sa_family: sa_family_t; + sa_data: packed array[0..13] of Byte); + 1: (sin_family: sa_family_t; + sin_port: u_short; + sin_addr: TInAddr; + sin_zero: packed array[0..7] of Byte); + end; + {$else} + sockaddr = record + sa_len: byte; //* total length */ + case integer of + 0: (sa_family: sa_family_t; //* address family */ + sa_data: packed array[0..13] of Byte); //* actually longer; address value */ + 1: (sin_family: sa_family_t; + sin_port: u_short; + sin_addr: TInAddr; + sin_zero: packed array[0..7] of Byte); + end; + {$endif} + + TSockAddr = sockaddr; + PSockAddr = ^TSockAddr; + + sockaddr_in = sockaddr; + Psockaddr_in = ^sockaddr; + TSockAddrIn = sockaddr_in; + PSockAddrIn = ^TSockAddrIn; + Pin_port_t = ^in_port_t; + in_port_t = uint16_t; + + Pin6_addr = ^in6_addr; + in6_addr = record + case longint of + 0 : ( in6_u : record + case longint of + 0 : ( u6_addr8 : array[0..15] of uint8_t ); + 1 : ( u6_addr16 : array[0..7] of uint16_t ); + 2 : ( u6_addr32 : array[0..3] of uint32_t ); + end;); + 1 : (case Integer of + 0: (s6_addr: packed array [0..16-1] of __uint8_t); + 1: (s6_addr16: packed array [0..8-1] of uint16_t); + 2: (s6_addr32: packed array [0..4-1] of uint32_t); + ); + end; + + + Psockaddr_in6 = ^sockaddr_in6; + sockaddr_in6 = record + sin6_family: sa_family_t; + sin6_port : in_port_t; + sin6_flowinfo : uint32_t; + sin6_addr : in6_addr; + sin6_scope_id : uint32_t; + end; +Const + PF_UNSPEC = 0; + PF_LOCAL = 1; + PF_UNIX = PF_LOCAL; + PF_FILE = PF_LOCAL; + PF_INET = 2; + PF_AX25 = 3; + PF_IPX = 4; + PF_APPLETALK = 5; + PF_NETROM = 6; + PF_BRIDGE = 7; + PF_ATMPVC = 8; + PF_X25 = 9; + PF_INET6 = 10; + PF_ROSE = 11; + PF_DECnet = 12; + PF_NETBEUI = 13; + PF_SECURITY = 14; + PF_KEY = 15; + PF_NETLINK = 16; + PF_ROUTE = PF_NETLINK; + PF_PACKET = 17; + PF_ASH = 18; + PF_ECONET = 19; + PF_ATMSVC = 20; + PF_SNA = 22; + PF_IRDA = 23; + PF_PPPOX = 24; + PF_WANPIPE = 25; + PF_BLUETOOTH = 31; + PF_MAX = 32; + AF_UNSPEC = PF_UNSPEC; + AF_LOCAL = PF_LOCAL; + AF_UNIX = PF_UNIX; + AF_FILE = PF_FILE; + AF_INET = PF_INET; + AF_AX25 = PF_AX25; + AF_IPX = PF_IPX; + AF_APPLETALK = PF_APPLETALK; + AF_NETROM = PF_NETROM; + AF_BRIDGE = PF_BRIDGE; + AF_ATMPVC = PF_ATMPVC; + AF_X25 = PF_X25; + AF_INET6 = PF_INET6; + AF_ROSE = PF_ROSE; + AF_DECnet = PF_DECnet; + AF_NETBEUI = PF_NETBEUI; + AF_SECURITY = PF_SECURITY; + AF_KEY = PF_KEY; + AF_NETLINK = PF_NETLINK; + AF_ROUTE = PF_ROUTE; + AF_PACKET = PF_PACKET; + AF_ASH = PF_ASH; + AF_ECONET = PF_ECONET; + AF_ATMSVC = PF_ATMSVC; + AF_SNA = PF_SNA; + AF_IRDA = PF_IRDA; + AF_PPPOX = PF_PPPOX; + AF_WANPIPE = PF_WANPIPE; + AF_BLUETOOTH = PF_BLUETOOTH; + AF_MAX = PF_MAX; + SOL_RAW = 255; + SOL_DECNET = 261; + SOL_X25 = 262; + SOL_PACKET = 263; + SOL_ATM = 264; + SOL_AAL = 265; + SOL_IRDA = 266; + SOMAXCONN = 128; + +type +{$ifdef FPC} + __socket_type = ( + SOCK_STREAM := 1, + SOCK_DGRAM := 2, + SOCK_RAW := 3, + SOCK_RDM := 4, + SOCK_SEQPACKET := 5, + SOCK_PACKET := 10 + ); + {$else} + __socket_type = type cenum; +const + SOCK_STREAM = 1; + SOCK_DGRAM = 2; + SOCK_RAW = 3; + SOCK_RDM = 4; + SOCK_SEQPACKET = 5; + SOCK_PACKET = 10; +type + {$endif} + TSocket = longint; + SOCKLEN_T = __socklen_t; + PSOCKLEN_T = ^SOCKLEN_T; + + Paddrinfo = ^addrinfo; + addrinfo = record + ai_flags : longint; + ai_family : longint; + ai_socktype : longint; + ai_protocol : longint; + ai_addrlen : socklen_t; + ai_addr : Psockaddr; + ai_canonname : Pchar; + ai_next : Paddrinfo; + end; + PPaddrinfo = ^Paddrinfo; + +const + SOL_SOCKET = 1; + SO_DEBUG = 1; + SO_REUSEADDR = 2; + SO_TYPE = 3; + SO_ERROR = 4; + SO_DONTROUTE = 5; + SO_BROADCAST = 6; + SO_SNDBUF = 7; + SO_RCVBUF = 8; + SO_KEEPALIVE = 9; + SO_OOBINLINE = 10; + SO_NO_CHECK = 11; + SO_PRIORITY = 12; + SO_LINGER = 13; + SO_BSDCOMPAT = 14; + SO_PASSCRED = 16; + SO_PEERCRED = 17; + SO_RCVLOWAT = 18; + SO_SNDLOWAT = 19; + SO_RCVTIMEO = 20; + SO_SNDTIMEO = 21; + SO_SECURITY_AUTHENTICATION = 22; + SO_SECURITY_ENCRYPTION_TRANSPORT = 23; + SO_SECURITY_ENCRYPTION_NETWORK = 24; + SO_BINDTODEVICE = 25; + SO_ATTACH_FILTER = 26; + SO_DETACH_FILTER = 27; + SO_PEERNAME = 28; + SO_TIMESTAMP = 29; + SCM_TIMESTAMP = SO_TIMESTAMP; + SO_ACCEPTCONN = 30; + +function socket(__domain:longint; __type:longint; __protocol:longint):longint; + cdecl;external clib name 'socket'; overload; +{$ifdef FPC} +function socket(__domain: Integer; __type: __socket_type; + __protocol: Integer): TSocket; + cdecl;external clib name 'socket'; overload; +{$endif} +function shutdown(__fd:longint; __how:longint):longint;cdecl;external clib name 'shutdown'; +function connect(__fd:longint; const __addr: sockaddr; + __len:socklen_t):longint;cdecl;external clib name 'connect'; overload; +function connect(__fd:longint; __addr:Psockaddr; + __len:socklen_t):longint;cdecl;external clib name 'connect'; overload; +{$ifdef linux} +function __libc_sa_len(__af: sa_family_t): Integer; cdecl;external clib name '__libc_sa_len'; +{$else} + //use len field of FreeBSD struct +{$endif} +function bind(__fd:longint; __addr:Psockaddr; __len:socklen_t):longint;cdecl;external clib name 'bind'; +//function SA_LEN(const buf): longword; // Untyped buffer; this is *unsafe*. +function listen(__fd:longint; __n:longint):longint;cdecl;external clib name 'listen'; +function accept(__fd:longint; __addr:Psockaddr; __addr_len:Psocklen_t):longint;cdecl;external clib name 'accept'; +function isfdtype(__fd:longint; __fdtype:longint):longint;cdecl;external clib name 'isfdtype'; +function setsockopt(__fd:longint; __level:longint; __optname:longint; __optval:pointer; __optlen:socklen_t):longint;cdecl;external clib name 'setsockopt'; +function getaddrinfo(__name:Pchar; __service:Pchar; __req:Paddrinfo; __pai:PPaddrinfo):longint;cdecl;external clib name 'getaddrinfo'; +function htons(__hostshort:uint16_t):uint16_t;cdecl;external clib name 'htons'; +procedure freeaddrinfo(__ai:Paddrinfo);cdecl;external clib name 'freeaddrinfo'; +function ntohs(__netshort:uint16_t):uint16_t;cdecl;external clib name 'ntohs'; + +function gai_strerror(__ecode:longint):Pchar;cdecl;external clib name 'gai_strerror'; +function syscall(SysNo: Longint): Integer; cdecl; varargs; + external clib name 'syscall'; + + +const + recursiveconst = PTHREAD_MUTEX_RECURSIVE; +// libcmodulename = 'c'; +const + NR_sendfile = 187; + __SIZEOF_PTHREAD_COND_T = {$ifdef CPU64}48{$else}48{$endif}; +type + tcondvar = array[0..__SIZEOF_PTHREAD_COND_T-1] of byte; + +function gettimeofday(__tv:Ptimeval; __tz:ptimezone):longint;cdecl; + external clib name 'gettimeofday'; overload; +function msetcgetattr(filedes: longint; + var msetermios: termios{ty}): longint; + cdecl;external clib name 'tcgetattr'; +function msetcsetattr(filedes: longint; when: longint; + var msetermios: termios{ty}): longint; + cdecl;external clib name 'tcsetattr'; +function tcdrain(filedes: longint): longint;cdecl;external clib name 'tcdrain'; +function tcflush(filedes: longint; queue_selector: longint): longint; + cdecl;external clib name 'tcflush'; + +function pthread_create(__thread:Ppthread_t; __attr:Ppthread_attr_t; + __start_routine:TStartRoutine; __arg:pointer):longint;cdecl; + external threadslib name 'pthread_create'; +function pthread_join(__th:pthread_t; __thread_return:Ppointer):longint;cdecl; + external threadslib name 'pthread_join'; +function pthread_detach(__th:pthread_t):longint;cdecl; + external threadslib name 'pthread_detach'; +function pthread_cancel(__thread: pthread_t):longint; + cdecl;external threadslib name 'pthread_cancel'; + +function pthread_attr_init(var __attr: pthread_attr_t):longint;cdecl; + external threadslib name 'pthread_attr_init'; + +function pthread_cond_init(var Cond: TCondVar; + CondAttr: PPthreadCondattr): Integer; cdecl; + external threadslib name 'pthread_cond_init'; +function pthread_cond_destroy(var Cond: TCondVar): Integer; cdecl; + external threadslib name 'pthread_cond_destroy'; +function pthread_cond_wait(var Cond: TCondVar; + var Mutex: pthread_mutex_t): Integer; cdecl; + external threadslib name 'pthread_cond_wait'; +function pthread_cond_timedwait(var Cond: TCondVar; + var Mutex: pthread_mutex_t; AbsTime: pTimeSpec): Integer; cdecl; + external threadslib name 'pthread_cond_timedwait'; +function pthread_cond_broadcast(var Cond: TCondVar): Integer; cdecl; + external threadslib name 'pthread_cond_broadcast'; +function pthread_cond_signal(var Cond: TCondVar): Integer; cdecl; + external threadslib name 'pthread_cond_signal'; +function sem_timedwait(var __sem: TSemaphore; __abstime: ptimespec): Integer; cdecl; + external threadslib name 'sem_timedwait'; + + +function pthread_mutex_init(__mutex: Ppthread_mutex_t; + __mutex_attr: Ppthread_mutexattr_t): longint; cdecl; + external threadslib name 'pthread_mutex_init'; +function pthread_mutex_destroy(var Mutex: pthread_mutex_t): Integer; cdecl; + external threadslib name 'pthread_mutex_destroy'; +function pthread_mutex_lock(var Mutex: pthread_mutex_t): Integer; cdecl; + external threadslib name 'pthread_mutex_lock'; +function pthread_mutex_trylock(var Mutex: pthread_mutex_t): Integer; cdecl; + external threadslib name 'pthread_mutex_trylock'; +function pthread_mutex_unlock(var Mutex: pthread_mutex_t): Integer; cdecl; + external threadslib name 'pthread_mutex_unlock'; + +{$ifdef linux} +function readdir64_r(__dirp:PDIR; __entry:Pdirent64; + __result:PPdirent64):longint;cdecl;external clib name 'readdir64_r'; +{$else} +function readdir64_r(__dirp:PDIR; __entry:Pdirent64; + __result:PPdirent64):longint;cdecl;external clib name 'readdir_r'; +{$endif} +function localtime_r(__timer:Ptime_t; __tp:Ptm):Ptm;cdecl; + external clib name 'localtime_r'; + +const +//* Protections are chosen from these bits, OR'd together. The +// implementation does not necessarily support PROT_EXEC or PROT_WRITE +// without PROT_READ. The only guarantees are that no writing will be +// allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */ + PROT_READ = $1; //* Page can be read. */ + PROT_WRITE = $2; //* Page can be written. */ + PROT_EXEC = $4; //* Page can be executed. */ + PROT_NONE = $0; //* Page can not be accessed. */ + PROT_GROWSDOWN = $01000000; //* Extend change to start of + //growsdown vma (mprotect only). */ + PROT_GROWSUP = $02000000; //* Extend change to start of + //growsup vma (mprotect only). */ + +//* Sharing types (must choose one and only one of these). */ + MAP_SHARED = $01; //* Share changes. */ + MAP_PRIVATE = $02; //* Changes are private. */ + MAP_TYPE = $0f; //* Mask for type of mapping. */ + +//* Other flags. */ + MAP_FIXED = $10; //* Interpret addr exactly. */ + MAP_FILE = 0; + MAP_ANONYMOUS = $20; //* Don't use a file. */ +//* When MAP_HUGETLB is set bits [26:31] encode the log2 of the huge page size. */ + MAP_HUGE_SHIFT = 26; + MAP_HUGE_MASK = $3f; + + MAP_FAILED = pointer(ptrint(-1)); + +function shm_open(name: pcchar; oflag: cint; mode: mode_t): cint; cdecl; + external shmlib name 'shm_open'; +function shm_unlink(name: pcchar): cint; cdecl; + external shmlib name 'shm_unlink'; +function mmap(addr: pointer; lengthint: size_t; prot: cint; flags: cint; + fd: cint; offset: off_t): pointer; cdecl; + external clib name 'mmap'; +function munmap(addr: pointer; length: size_t): cint; cdecl; + external clib name 'munmap'; + +procedure initlibc(); + +implementation +uses + msedynload{,msesys}; +{$ifndef linux} +function getpt(): longint; +begin + result:= posix_openpt(O_RDWR); +end; + +function ptsname_r(__fd:longint; __buf:Pchar; __buflen:size_t):longint; +var + ps,pd,pend: pcchar; +begin + result:= -1; + if __buf = nil then begin + __errno_location()^:= EINVAL; + end + else begin + PS:= PTSNAME(__FD); + IF PS <> NIL THEN BEGIN + PD:= __BUF; + PEND:= PD + __BUFLEN; + WHILE pd < PEND do begin + pd^:= ps^; + if ps^ = #0 then begin + break; + end; + inc(pd); + inc(ps); + end; + if (pd >= pend) then begin + __errno_location()^:= ERANGE; + end + else begin + result:= 0; + end; + end; + end; +end; + +{$endif} + +function WEXITSTATUS(status: cint): cint; +begin + result:=(status and $ff00) shr 8; +end; + +function WTERMSIG(status: cint): cint; +begin + result:= status and $7f; +end; + +function WIFEXITED(status: cint): boolean; +begin + result:= status and $7f = 0; +end; + +function WIFSIGNALED(status: cint): boolean; +begin + result:= (status and $7f <> $7f) and (status and $7f <> 0); +end; + +function errno: error_t; +begin + result:=__errno_location()^; +end; +{ +function SA_LEN(const Buf): longword; // Untyped buffer; this is *unsafe*. + +begin + Result:=__libc_sa_len(PSockAddr(@Buf)^.sa_family); +end; +} +function S_ISDIR(mode: __mode_t) : boolean; +begin + result:= mode and __S_IFDIR = __S_IFDIR; +end; + +{$ifdef linux} + +function stat(__file:Pchar; __buf: Pstat): longint; +begin + result:= __xstat(_STAT_VER,__file,__buf); +end; + +function fstat(__fd:longint; __buf: Pstat): longint; +begin + result:= __fxstat(_STAT_VER,__fd,__buf); +end; + +function lstat(__file:Pchar; __buf: Pstat): longint; +begin + result:= __lxstat(_STAT_VER,__file,__buf); +end; + +function stat64(__file:Pchar; __buf:Pstat64):longint; +begin +{$ifdef CPU64} + result:= __xstat(_STAT_VER,__file,__buf); +{$else} + result:= __xstat64(_STAT_VER,__file,__buf); +{$endif} +end; + +function fstat64(__fd:longint; __buf:Pstat64):longint; +begin +{$ifdef CPU64} + result:= __fxstat(_STAT_VER,__fd,__buf); +{$else} + result:= __fxstat64(_STAT_VER,__fd,__buf); +{$endif} +end; + +function lstat64(__file:Pchar; __buf:Pstat64):longint; +begin +{$ifdef CPU64} + result:= __lxstat(_STAT_VER,__file,__buf); +{$else} + result:= __lxstat64(_STAT_VER,__file,__buf); +{$endif} +end; + +{$endif} //linux + +var + rtlibinfo: dynlibinfoty; + +procedure initlib; +const + funcs: array[0..2] of funcinfoty = ( + (n: 'clock_gettime'; d: @clock_gettime), //0 + (n: 'getpwuid_r'; d: @getpwuid_r), //1 + (n: 'cuserid'; d: @cuserid) //2 + ); +begin + try + initializedynlib(rtlibinfo,['librt.so.1','librt.so','libc.so.6'],[], + [],funcs); + except + end; +end; + +var + inited: boolean; + +procedure initlibc(); +begin + if not inited then begin + inited:= true; + initializelibinfo(rtlibinfo); + initlib(); + end; +end; + +initialization + initlibc(); +finalization + finalizelibinfo(rtlibinfo); +end. diff --git a/mseide-msegui/lib/common/kernel/msemacros.pas b/mseide-msegui/lib/common/kernel/msemacros.pas new file mode 100644 index 0000000..431623a --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msemacros.pas @@ -0,0 +1,1096 @@ +{ MSEgui Copyright (c) 1999-2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msemacros; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + msestrings,mselist,msearrayutils,msetypes,msestat,msedatalist,mclasses, + mseclasses,msearrayprops; + +type + tmacrolist = class; + macrohandlerty = function(const sender: tmacrolist; + const params: msestringarty): msestring; + macrohandlerarty = array of macrohandlerty; + + macroinfoty = record + name,value: msestring; + handler: macrohandlerty; + expandlevel: integer; + end; + pmacroinfoty = ^macroinfoty; + macroinfoarty = array of macroinfoty; + macroinfoaty = array[0..0] of macroinfoty; + pmacroinfoaty = ^macroinfoaty; + + macrooptionty = (mao_caseinsensitive,mao_curlybraceonly,mao_removeunknown); + macrooptionsty = set of macrooptionty; + + tmacrolist = class(torderedrecordlist,istatupdatevalue) + private + foptions: macrooptionsty; + fpredefined: macroinfoarty; + protected + procedure finalizerecord(var item); override; + procedure copyrecord(var item); override; + function compare(const l,r): integer; + function getcomparefunc: sortcomparemethodty; override; + procedure setrec(const index: integer; const avalue: msestring); + function getrec(const index: integer): msestring; + procedure resetexpandlevel; + function getvalue(const aname: msestring; var aexpandlevel: integer; + out found: pmacroinfoty): msestring; + function callhandler(const aname: msestring;const aparams: msestringarty; + var aexpandlevel: integer; out found: pmacroinfoty): msestring; + //istatupdatevalue + procedure statreadvalue(const aname: msestring; const reader: tstatreader); + procedure statwritevalue(const aname: msestring; const writer: tstatwriter); + procedure internalexpandmacros(var avalue: msestring; expandlevel: integer; + var refindex: integerarty); + public + constructor create(const aoptions: macrooptionsty); + constructor create(const aoptions: macrooptionsty; + const apredefined: array of macroinfoty); + function find(const aname: msestring; + out item: pmacroinfoty): boolean; + //true if found; + function itembyname(const aname: msestring): pmacroinfoty; + function itempo(const index: integer): pmacroinfoty; + procedure add(const avalue: tmacrolist); overload; + procedure add(const avalue: macroinfoty); overload; + procedure add(const avalue: macroinfoarty); overload; + procedure add(const names,values: array of msestring; + const handler: array of macrohandlerty); overload; + + procedure expandmacros1(var avalue: msestring); + function expandmacros(const avalue: msestring): msestring; + procedure expandmacros1(var avalue: msestring; + var refindex: integerarty); + procedure expandmacros1(var avalues: msestringarty); + function asarray: macroinfoarty; + function asarray(const addnames: array of msestring; + const addvalues: array of msestring): macroinfoarty; + procedure asarray(out names,values: msestringarty; + out handler: macrohandlerarty); + procedure setasarray(const avalue: macroinfoarty); + procedure setasarray(const names,values: msestringarty; + const handler: macrohandlerarty); + property options: macrooptionsty read foptions write foptions; + + procedure setpredefined(const avalue: array of macroinfoty); + procedure setpredefined(const avalue: array of macroinfoarty); + property predefined: macroinfoarty read fpredefined write fpredefined; + //appended by setasarray procedures + end; + + tmacroproperty = class; + tmacrostringlist = class(tmsestringdatalist) + private + fmacros: tmacroproperty; + function gettext: msestring; + procedure settext(const avalue: msestring); + procedure readstrings(reader: treader); +// procedure writestrings(writer: twriter); + procedure setmacros(const avalue: tmacroproperty); + protected + procedure defineproperties(filer: tfiler); override; + public + constructor create; override; + destructor destroy; override; + procedure assign(source: tpersistent); override; + function expandmacros(atext: msestring): msestring; + property text: msestring read gettext write settext; + published + property macros: tmacroproperty read fmacros write setmacros; + end; + + tstringlistmacroitem = class; + + tstringlistmacro = class(tmacrostringlist) + private + fowner: tmacrostringlist; + protected + procedure dochange; override; + public + constructor create(const aowner: tmacrostringlist); reintroduce; + end; + + tstringlistmacroitem = class(townedpersistent) + private + fname: msestring; + fvalue: tstringlistmacro; + factive: boolean; + procedure setvalue(const avalue: tstringlistmacro); + procedure setactive(const avalue: boolean); + protected + public + constructor create(aowner: tobject); override; + destructor destroy; override; + procedure assign(source: tpersistent); override; + published + property name: msestring read fname write fname; + property value: tstringlistmacro read fvalue write setvalue; + property active: boolean read factive write setactive default true; + end; + + tmacroproperty = class(townedpersistentarrayprop) + private + foptions: macrooptionsty; + function getitems(const aindex: integer): tstringlistmacroitem; + procedure setitems(const aindex: integer; + const avalue: tstringlistmacroitem); + protected + procedure dochange(const aindex: integer); override; + public + constructor create(const aowner: tmacrostringlist); reintroduce; + property items[const aindex: integer]: tstringlistmacroitem read getitems + write setitems; default; + function itembyname(const aname: msestring): tstringlistmacroitem; + function itembynames(const anames: array of msestring): tstringlistmacroitem; + class function getitemclasstype: persistentclassty; override; + //used in dumpunitgroups + published + property options: macrooptionsty read foptions write foptions + default [mao_caseinsensitive]; + end; + +//function expandmacros(const value: msestring; const macros:macroinfoarty; +// const caseinsensitive: boolean = true): msestring; overload; +function initmacros(const amacros: array of macroinfoty): macroinfoarty; +function initmacros(const anames,avalues: array of msestring; + const ahandler: array of macrohandlerty): macroinfoarty; +function initmacros(const anames,avalues: array of msestringarty; + const ahandler: array of macrohandlerarty): macroinfoarty; +function initmacros(const amacros: array of macroinfoarty): macroinfoarty; + +function expandmacros(const value: msestring; const macros: macroinfoarty; + const options: macrooptionsty = [mao_caseinsensitive]): msestring; +function expandmacros(const value: msestring; + const anames,avalues: array of msestring; + const options: macrooptionsty = [mao_caseinsensitive]): msestring; +function expandmacros1(const value: msestring; + const anames,avalues: array of msestring; + const options: macrooptionsty = [mao_caseinsensitive]): msestring; + +function expandmacros2(const value: msestring; + const anames,avalues: array of msestring; + const ahandler: array of macrohandlerty; + const options: macrooptionsty = [mao_caseinsensitive]): msestring; + +implementation +uses + msestream,sysutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +function initmacros(const amacros: array of macroinfoty): macroinfoarty; +var + int1: integer; +begin + setlength(result,length(amacros)); + for int1:= 0 to high(amacros) do begin + result[int1]:= amacros[int1]; + end; +end; + +function initmacros(const anames,avalues: array of msestring; + const ahandler: array of macrohandlerty): macroinfoarty; +var + int1: integer; +begin + setlength(result,length(anames)); + for int1:= 0 to high(result) do begin + with result[int1] do begin + name:= anames[int1]; + if int1 <= high(avalues) then begin + value:= avalues[int1]; + end; + if int1 <= high(ahandler) then begin + handler:= ahandler[int1]; + end; + end; + end; +end; + +function initmacros(const anames,avalues: array of msestringarty; + const ahandler: array of macrohandlerarty): macroinfoarty; +var + int1,int2,int3: integer; +begin + int3:= 0; + for int1:= 0 to high(anames) do begin + int3:= int3 + length(anames[int1]); + end; + setlength(result,int3); + int3:= 0; + for int1:= 0 to high(anames) do begin + for int2:= 0 to high(anames[int1]) do begin + with result[int3] do begin + name:= anames[int1,int2]; + if int2 <= high(avalues[int1]) then begin + value:= avalues[int1,int2]; + end; + if int2 <= high(ahandler[int1]) then begin + handler:= ahandler[int1,int2]; + end; + end; + inc(int3); + end; + end; +end; + +function initmacros(const amacros: array of macroinfoarty): macroinfoarty; +var + int1,int2,int3: integer; +begin + int2:= 0; + for int1:= 0 to high(amacros) do begin + int2:= int2 + length(amacros[int1]); + end; + setlength(result,int2); + for int1:= high(amacros) downto 0 do begin + for int3:= high(amacros[int1]) downto 0 do begin + dec(int2); + result[int2]:= amacros[int1][int3]; + end; + end; +end; + +function expandmacros(const value: msestring; const macros:macroinfoarty; + const options: macrooptionsty = [mao_caseinsensitive]): msestring; +var + list: tmacrolist; +begin + list:= tmacrolist.create(options); + try + list.add(macros); + result:= value; + list.expandmacros1(result); + finally + list.free; + end; +end; + +function expandmacros(const value: msestring; + const anames,avalues: array of msestring; + const options: macrooptionsty = [mao_caseinsensitive]): msestring; +begin + result:= expandmacros(value,initmacros(anames,avalues,[]),options); +end; + +function expandmacros1(const value: msestring; + const anames,avalues: array of msestring; + const options: macrooptionsty = [mao_caseinsensitive]): msestring; +begin + result:= expandmacros(value,initmacros(anames,avalues,[]),options); +end; + +function expandmacros2(const value: msestring; + const anames,avalues: array of msestring; + const ahandler: array of macrohandlerty; + const options: macrooptionsty = [mao_caseinsensitive]): msestring; +begin + result:= expandmacros(value,initmacros(anames,avalues,ahandler),options); +end; + +{ +function expandmacrosstr(const value: msestring; + const anames,avalues: array of msestring; + const options: macrooptionsty = [mao_caseinsensitive]): msestring; +begin + result:= expandmacros(value,initmacros(anames,avalues,[]),options); +end; +} +{ +function expandmacros(const value: msestring; const macros:macroinfoarty; + const caseinsensitive: boolean = true): msestring; +var + list: tmacrolist; +begin + list:= tmacrolist.create([mao_caseinsensitive]); + try + list.add(macros); + result:= value; + list.expandmacros(result); + finally + list.free; + end; +end; +} +{ tmacrolist } + +constructor tmacrolist.create(const aoptions: macrooptionsty); +begin + foptions:= aoptions; + inherited create(sizeof(macroinfoty),[rels_needsfinalize,rels_needscopy]); +end; + +constructor tmacrolist.create(const aoptions: macrooptionsty; + const apredefined: array of macroinfoty); +begin + create(aoptions); + predefined:= initmacros(apredefined); + add(fpredefined); +end; + +function tmacrolist.itempo(const index: integer): pmacroinfoty; +begin + result:= pmacroinfoty(getitempo(index)); +end; + +procedure tmacrolist.add(const avalue: macroinfoty); +var + info: macroinfoty; +begin + if mao_caseinsensitive in foptions then begin + info.name:= struppercase(avalue.name); + info.value:= avalue.value; + info.handler:= avalue.handler; + inherited add(info); + end + else begin + inherited add(avalue); + end; +end; + +procedure tmacrolist.add(const avalue: macroinfoarty); +var + int1: integer; +begin + sorted:= false; + for int1:= 0 to high(avalue) do begin + add(avalue[int1]); + end; +end; + +procedure tmacrolist.add(const avalue: tmacrolist); +begin + add(avalue.asarray); +end; + +procedure tmacrolist.add(const names,values: array of msestring; + const handler: array of macrohandlerty); +var + int1: integer; + ar1: macroinfoarty; +begin + setlength(ar1,length(names)); + for int1:= 0 to high(names) do begin + ar1[int1].name:= names[int1]; + if int1 <= high(values) then begin + ar1[int1].value:= values[int1]; + end; + if int1 <= high(handler) then begin + ar1[int1].handler:= handler[int1]; + end; + end; + add(ar1); +end; + +procedure tmacrolist.resetexpandlevel; +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + pmacroinfoaty(fdata)^[int1].expandlevel:= bigint; + end; +end; + +function tmacrolist.getvalue(const aname: msestring; + var aexpandlevel: integer; + out found: pmacroinfoty): msestring; +var + info: macroinfoty; + int1: integer; +begin + if mao_caseinsensitive in foptions then begin + info.name:= struppercase(aname); + end + else begin + info.name:= aname; + end; + if internalfind(info,int1) then begin + found:= @pmacroinfoaty(fdata)^[int1]; + with found^ do begin + result:= value; + int1:= expandlevel; + expandlevel:= aexpandlevel; + aexpandlevel:= int1; + end; + end + else begin + result:= ''; + aexpandlevel:= bigint+1; + end; +end; + +function tmacrolist.find(const aname: msestring; + out item: pmacroinfoty): boolean; + //true if found; +var + info: macroinfoty; + int1: integer; +begin + if mao_caseinsensitive in foptions then begin + info.name:= struppercase(aname); + end + else begin + info.name:= aname; + end; + result:= internalfind(info,int1); + if result then begin + item:= @pmacroinfoaty(fdata)^[int1]; + end + else begin + item:= nil; + end; +end; + +function tmacrolist.itembyname(const aname: msestring): pmacroinfoty; +begin + if not find(aname,result) then begin + raise exception.create(ansistring('Macroitem "'+aname+'" not found')); + end; +end; + +function tmacrolist.callhandler(const aname: msestring; + const aparams: msestringarty; var aexpandlevel: integer; + out found: pmacroinfoty): msestring; + +var +// info: macroinfoty; + int1: integer; + +begin +{ + if mao_caseinsensitive in foptions then begin + info.name:= struppercase(aname); + end + else begin + info.name:= aname; + end; + if internalfind(info,int1) then begin +} + if find(aname,found) then begin +// found:= @pmacroinfoaty(fdata)^[int1]; + with found^ do begin + if handler <> nil then begin + result:= handler(self,aparams); + end + else begin + result:= value; + end; + int1:= expandlevel; + expandlevel:= aexpandlevel; + aexpandlevel:= int1; + end; + end + else begin +// found:= nil; + result:= ''; + aexpandlevel:= bigint+1; //not found + end; +end; + +function tmacrolist.compare(const l, r): integer; +begin + result:= msestrcomp(pmsechar(macroinfoty(l).name), + pmsechar(macroinfoty(r).name)); +end; + +function tmacrolist.getcomparefunc: sortcomparemethodty; +begin + result:= {$ifdef FPC}@{$endif}compare; +end; + +procedure tmacrolist.copyrecord(var item); +begin + with macroinfoty(item) do begin + stringaddref(name); + stringaddref(value); + end; +end; + +procedure tmacrolist.finalizerecord(var item); +begin + finalize(macroinfoty(item)); +end; + +procedure tmacrolist.internalexpandmacros(var avalue: msestring; + expandlevel: integer; var refindex: integerarty); + +var + start: pmsechar; + + function checkmacrostart(po: pmsechar): pmsechar; + begin + if mao_curlybraceonly in foptions then begin + repeat + result:= msestrscan(po,msechar('{')); + if result <> nil then begin + if (result = start) then begin + result:= nil; + end + else begin + dec(result); + if result^ = '$' then begin + break; + end; + inc(po); //next curlybrace + end; + end; + until result = nil; + end + else begin + result:= msestrscan(po,msechar('$')) + end; + end; //checkmacrostart + +var + int1,int2,int3,int4: integer; + po1,po2,po3,po4,po5: pmsechar; + str1,str2,str3: msestring; + ar1: msestringarty; + found: pmacroinfoty; + +begin + if avalue <> '' then begin + found:= nil; + str1:= avalue; //copy + po2:= pmsechar(str1); + start:= po2; + po1:= checkmacrostart(po2); + if po1 <> nil then begin + avalue:= ''; + while true do begin + if expandlevel = 0 then begin + resetexpandlevel; + end; + addstringsegment(avalue,po2,po1); + po2:= po1+1; + if (po2)^ = '{' then begin + inc(po2); + int1:= 0; + while po2^ <> #0 do begin + if po2^ = '"' then begin //skip quoted + inc(po2); + while po2^ <> #0 do begin + if po2^ = '"' then begin + break; + end; + inc(po2); + end; + end; + if po2^ = '{' then begin + inc(int1); + end; + if po2^ = '}' then begin + dec(int1); + if int1 < 0 then begin + break; + end; + end; + inc(po2); + end; + if po2^ <> #0 then begin + po3:= po1+2; + str2:= stringsegment(po3,po2); + inc(po2) + end + else begin + addstringsegment(avalue,po1,pmsechar(str1)+length(str1)); + //append the rest for missing } + exit; + end; + end + else begin + po2:= po1; + repeat + inc(po2); + until not ((po2^ = '_') or + (po2^ >= 'a') and (po2^ <= 'z') or + (po2^ >= 'A') and (po2^ <= 'Z') or + (po2^ >= '0') and (po2^ <= '9')); + po3:= po1+1; + str2:= stringsegment(po3,po2); + end; + //po1 = macro def start, po2 = macro def end + if str2 <> '' then begin //macro name + int1:= expandlevel+1; + po4:= po2-1; + if po4^ = '}' then begin + dec(po4); + if (po4)^ = ')' then begin + po5:= po3; + while (po5 < po4) and (po5^ <> '(') do begin + inc(po5); + end; + if po5 < po4 then begin + setlength(str2,po5-po3); + str3:= stringsegment(po5+1,po4); + ar1:= splitstringquoted(str3,',','"'); + for int2:= 0 to high(ar1) do begin + internalexpandmacros(ar1[int2],expandlevel+1,integerarty(nil^)); + end; + int1:= expandlevel+1; + str3:= callhandler(str2,ar1,int1,found); + end + else begin + int1:= bigint+1; //not found + end; + end + else begin + str3:= getvalue(str2,int1,found); + end; + end + else begin + str3:= getvalue(str2,int1,found); + end; + if int1 <= expandlevel then begin + str3:= '!!R*'+str2+'*R!!'; + end + else begin + internalexpandmacros(str3,expandlevel+1,integerarty(nil^)); + end; + if found <> nil then begin + found^.expandlevel:= bigint; //can be reused + end; + if @refindex <> nil then begin + int4:= (po2-po1); + int3:= length(str3) - int4; + int4:= length(avalue) + int4; + for int2:= high(refindex) downto 0 do begin + if refindex[int2] >= int4 then begin + refindex[int2]:= refindex[int2] + int3; + end; + end; + end; + avalue:= avalue + str3; + end + else begin + int1:= bigint+1; + end; + if (int1 > bigint) and not (mao_removeunknown in foptions) then begin + avalue:= avalue + stringsegment(po1,po2); + end; + if po2^ = #0 then begin + break; + end; + po1:= checkmacrostart(po2); + if po1 = nil then begin + addstringsegment(avalue,po2,pmsechar(str1)+length(str1)); + //locks str1 + break; + end; + end; + end; + end; +end; + +procedure tmacrolist.expandmacros1(var avalue: msestring; + var refindex: integerarty); +begin + internalexpandmacros(avalue,0,refindex); +end; + +procedure tmacrolist.expandmacros1(var avalue: msestring); +var + ar1: integerarty; +begin + ar1:= nil; + expandmacros1(avalue,ar1); +end; + +function tmacrolist.expandmacros(const avalue: msestring): msestring; +begin + result:= avalue; + expandmacros1(result); +end; + +procedure tmacrolist.expandmacros1(var avalues: msestringarty); +var + int1: integer; +begin + setlength(avalues,length(avalues)); + for int1:= 0 to high(avalues) do begin + expandmacros1(avalues[int1]); + end; +end; + +procedure tmacrolist.statreadvalue(const aname: msestring; + const reader: tstatreader); +begin + clear; + reader.readrecordarray(aname,@setcount,@setrec); +end; + +procedure tmacrolist.statwritevalue(const aname: msestring; + const writer: tstatwriter); +begin + writer.writerecordarray(aname,count,@getrec); +end; + +function tmacrolist.getrec(const index: integer): msestring; +begin + with itempo(index)^ do begin + result:= encoderecord([name,value]); + end; +end; + +procedure tmacrolist.setrec(const index: integer; const avalue: msestring); +begin + with itempo(index)^ do begin + handler:= nil; + decoderecord(avalue,[@name,@value],'SS'); + end; +end; + +function tmacrolist.asarray: macroinfoarty; +var + po1: pmacroinfoaty; + int1: integer; +begin + setlength(result,count); + po1:= datapo; + for int1:= 0 to count - 1 do begin + result[int1]:= po1^[int1]; + end; +end; + +function tmacrolist.asarray(const addnames: array of msestring; + const addvalues: array of msestring): macroinfoarty; +var + int1,int2,int3: integer; +begin + result:= asarray(); + int1:= length(addnames); + if int1 > length(addvalues) then begin + int1:= length(addvalues); + end; + int2:= length(result); + setlength(result,int2+int1); + int3:= 0; + for int1:= int2 to high(result) do begin + result[int1].name:= addnames[int3]; + result[int1].value:= addvalues[int3]; + inc(int3); + end; +end; + +procedure tmacrolist.asarray(out names, values: msestringarty; + out handler: macrohandlerarty); +var + po1: pmacroinfoaty; + int1: integer; +begin + setlength(names,count); + setlength(values,count); + setlength(handler,count); + po1:= datapo; + for int1:= 0 to count - 1 do begin + names[int1]:= po1^[int1].name; + values[int1]:= po1^[int1].value; + handler[int1]:= po1^[int1].handler; + end; +end; + +procedure tmacrolist.setasarray(const avalue: macroinfoarty); +begin + clear(); + add(fpredefined); + add(avalue); +end; + +procedure tmacrolist.setasarray(const names: msestringarty; + const values: msestringarty; const handler: macrohandlerarty); +begin + clear(); + add(fpredefined); + add(names,values,handler); +end; + +procedure tmacrolist.setpredefined(const avalue: array of macroinfoty); +begin + fpredefined:= initmacros(avalue); +end; + +procedure tmacrolist.setpredefined(const avalue: array of macroinfoarty); +begin + fpredefined:= initmacros(avalue); +end; + +{ tmacrostringlist } + +constructor tmacrostringlist.create; +begin + fmacros:= tmacroproperty.create(self); + inherited; +end; + +destructor tmacrostringlist.destroy; +begin + inherited; + fmacros.free; +end; + +function tmacrostringlist.expandmacros(atext: msestring): msestring; +var + ar1: macroinfoarty; + int1: int32; +begin + result:= atext; + if fmacros.count <> 0 then begin + setlength(ar1,fmacros.count); +// po3:= fmacros.datapo; + for int1:= 0 to high(ar1) do begin + with fmacros[int1] do begin + ar1[int1].name:= name; + if active then begin + ar1[int1].value:= value.text; + end + else begin + ar1[int1].value:= ''; + end; +// value:= po3^.b; +// name:= po3^.a; +// value:= po3^.b; + end; +// inc(po3); + end; + result:= msemacros.expandmacros(result,ar1,fmacros.foptions); + end; +end; + +function tmacrostringlist.gettext: msestring; +var + int1,int2: integer; + po1: pmsestring; + po2: pmsechar; + mstr1: msestring; +// po3: pdoublemsestringty; +begin + result:= ''; + if count > 0 then begin + normalizering; + int2:= 0; + po1:= pointer(fdatapo); + for int1:= 0 to count - 1 do begin + inc(int2,length(pmsestringaty(po1)^[int1])); + end; + mstr1:= lineend; + setlength(result,int2+(count-1)*length(mstr1)); + if result <> '' then begin + int2:= 0; + po2:= pmsechar(result); + for int1:= 0 to count - 2 do begin + move(po1^[1],po2^,length(po1^)*sizeof(msechar)); + inc(po2,length(po1^)); + move(mstr1[1],po2^,length(mstr1)*sizeof(msechar)); + inc(po2,length(mstr1)); + inc(po1); + end; + move(po1^[1],po2^,length(po1^)*sizeof(msechar)); //last line + end; + result:= expandmacros(result); + end; +end; + +procedure tmacrostringlist.settext(const avalue: msestring); +begin + asarray:= breaklines(avalue); +end; + +procedure tmacrostringlist.readstrings(reader: treader); +var + ar1: stringarty; + int1: integer; + bo1: boolean; +begin + reader.readlistbegin; + while not reader.endoflist do begin + additem(ar1,reader.readstring); + end; + reader.readlistend; + bo1:= true; + for int1:= 0 to high(ar1) do begin + if not checkutf8(ar1[int1]) then begin + bo1:= false; + break; + end; + end; + clear; + if bo1 then begin + for int1:= 0 to high(ar1) do begin + add(utf8tostringansi(ar1[int1])); + end; + end + else begin + for int1:= 0 to high(ar1) do begin + add(msestring(ar1[int1])); + end; + end; +end; + +procedure tmacrostringlist.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('Strings',{$ifdef FPC}@{$endif}readstrings, + nil{@writestrings},false); +end; + +procedure tmacrostringlist.setmacros(const avalue: tmacroproperty); +begin + fmacros.assign(avalue); +end; + +procedure tmacrostringlist.assign(source: tpersistent); +begin + beginupdate; + try + inherited; + if source is tmacrostringlist then begin + fmacros.assign(tmacrostringlist(source).macros); + end; + finally + endupdate; + end; +end; + +{ tmacroproperty } + +constructor tmacroproperty.create(const aowner: tmacrostringlist); +begin + fowner:= aowner; + foptions:= [mao_caseinsensitive]; + inherited create(aowner,tstringlistmacroitem); +end; + +procedure tmacroproperty.dochange(const aindex: integer); +begin + inherited; + tmacrostringlist(fowner).dochange; +end; + +function tmacroproperty.getitems(const aindex: integer): tstringlistmacroitem; +begin + result:= tstringlistmacroitem(inherited getitems(aindex)); +end; + +procedure tmacroproperty.setitems(const aindex: integer; + const avalue: tstringlistmacroitem); +begin + inherited; +end; + +class function tmacroproperty.getitemclasstype: persistentclassty; +begin + result:= tstringlistmacroitem; +end; + +function tmacroproperty.itembyname( + const aname: msestring): tstringlistmacroitem; +var + int1: integer; +begin + result:= nil; + for int1:= 0 to high(fitems) do begin + if tstringlistmacroitem(fitems[int1]).name = aname then begin + result:= tstringlistmacroitem(fitems[int1]); + break; + end; + end; + if result = nil then begin + raise exception.create('Macro "'+ansistring(aname)+'" not found.'); + end; +end; + +function tmacroproperty.itembynames( + const anames: array of msestring): tstringlistmacroitem; +var + int1: integer; +begin + result:= nil; + if length(anames) > 0 then begin + result:= itembyname(anames[0]); + for int1:= 1 to high(anames) do begin + result:= result.value.macros.itembyname(anames[int1]); + end; + end; +end; + +{ tstringlistmacro } + +constructor tstringlistmacro.create(const aowner: tmacrostringlist); +begin + fowner:= aowner; + inherited create; +end; + +procedure tstringlistmacro.dochange; +begin + inherited; + fowner.dochange; +end; + +{ tstringlistmacroitem } + +constructor tstringlistmacroitem.create(aowner: tobject); +begin + factive:= true; + fvalue:= tstringlistmacro.create(tmacrostringlist(aowner)); + inherited; +end; + +destructor tstringlistmacroitem.destroy; +begin + fvalue.free; + inherited; +end; + +procedure tstringlistmacroitem.setvalue(const avalue: tstringlistmacro); +begin + fvalue.assign(avalue); +end; + +procedure tstringlistmacroitem.setactive(const avalue: boolean); +begin + if factive <> avalue then begin + factive:= avalue; + tmacrostringlist(fowner).dochange; + end; +end; + +procedure tstringlistmacroitem.assign(source: tpersistent); +begin + if source is tstringlistmacroitem then begin + with tstringlistmacroitem(source) do begin + self.name:= name; + self.value:= value; + self.active:= active; + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/msemenus.pas b/mseide-msegui/lib/common/kernel/msemenus.pas new file mode 100644 index 0000000..a65a9ef --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msemenus.pas @@ -0,0 +1,2436 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msemenus; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} + +interface +uses + mseact,msegui,msearrayprops,mseclasses,msegraphutils, + msedrawtext,msegraphics,mseevent,mseglob,mseguiglob,mseshapes,mserichstring, + msetypes,msestrings,classes,mclasses,msekeyboard,msebitmap, + mseassistiveclient{$ifdef mse_with_ifi},mseificompglob{$endif}; + +type + menuoptionty = (mo_noinsert,mo_stopinsert,mo_insertfirst, + mo_noseparator, + mo_forceseparator, //do not set mao_optional + mo_singleregion,mo_shortcutright,mo_commonwidth, + mo_activate,{mo_noanim,}mo_mainarrow,mo_updateonidle); + menuoptionsty = set of menuoptionty; +const + defaultmenuoptions = [mo_shortcutright]; + defaultmainmenuoptions = defaultmenuoptions + [mo_updateonidle]; + defaultmenuactoptions = [mao_shortcutcaption]; + +type + menuinfoarty = array of actioninfoty; + tmenuitem = class; + + menuitemeventty = procedure(const sender: tmenuitem) of object; + menuitemprocty = procedure(const sender: tmenuitem); + + tmenuitems = class(tpersistentarrayprop,ievent) + private + fowner: tmenuitem; + function getmenuitems(index: integer): tmenuitem; + procedure setmenuitems(index: integer; const Value: tmenuitem); + protected + procedure createitem(const index: integer; var item: tpersistent); override; + procedure dosizechanged; override; + procedure dochange(const aindex: integer); override; + procedure receiveevent(const event: tobjectevent); + public + constructor create(const aowner: tmenuitem); + class function getitemclasstype: persistentclassty; override; + function hasvisibleitem: boolean; + procedure sort; + procedure assign(source: tpersistent); override; + function insert(const index: integer; + const aitem: tmenuitem): integer overload; + //aitem is owned, returns index of new item + //if index > count -> index:= count + function insert(const index: integer; + const aitems: tmenuitems): integer overload; + //items are copied, returns index of first new item + //if index > count -> index:= count + function insert(const index: integer; const captions: array of msestring; + //if index > count -> index:= count + const options: array of menuactionoptionsty; + const states: array of actionstatesty; + const onexecutes: array of notifyeventty): integer overload; + //returns index of first new item + procedure insertseparator(const index: integer; + const aoptional: boolean = false); + //if index > count -> index:= count + property items[index: integer]: tmenuitem read getmenuitems + write setmenuitems; default; + function itembyname(const name: ansistring): tmenuitem; + function itemindexbyname(const name: ansistring): integer; + end; + + tmenufont = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + tmenufontactive = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + tcustommenu = class; + + imenuitem = interface(ievent) + procedure setstate(const avalue: actionstatesty); + function getstate: actionstatesty; + end; + + tmenuitem = class(teventpersistent,iactionlink,imenuitem,iimagelistinfo, + iassistiveclientmenu) + private + fparentmenu: tmenuitem; + fonchange: menuitemeventty; + fname: string; +// fgroup: integer; + fsource: imenuitem; + fcoloractive: colorty; + fcolorglyphactive: colorty; + function getsubmenu: tmenuitems; + procedure setsubmenu(const Value: tmenuitems); + procedure setcaption(const avalue: captionty); + function iscaptionstored: Boolean; + procedure setstate(const avalue: actionstatesty); + function getstate: actionstatesty; + function isstatestored: Boolean; + + procedure resetradiobuttons(); + procedure actionchanged; + procedure checksubmenu; + function getitems(const index: integer): tmenuitem; + procedure setitems(const index: integer; const Value: tmenuitem); + procedure setaction(const avalue: tcustomaction); + function isonexecutestored: Boolean; + function isonbeforeexecutestored: Boolean; + function isonafterexecutestored: Boolean; + function isshortcutstored: Boolean; + procedure setshortcut(const avalue: shortcutty); + function isshortcut1stored: Boolean; + procedure setshortcuts(const avalue: shortcutarty); + procedure setshortcuts1(const avalue: shortcutarty); + function getshortcut: shortcutty; + function getshortcut1: shortcutty; + procedure setshortcut1(const avalue: shortcutty); + procedure setonexecute(const avalue: notifyeventty); + procedure setonbeforeexecute(const avalue: accepteventty); + procedure setonafterexecute(const avalue: notifyeventty); + procedure setoptions(const avalue: menuactionoptionsty); + function istagstored: Boolean; + procedure settag(const avalue: integer); + function isgroupstored: Boolean; + procedure setgroup(const avalue: integer); + function getchecked: boolean; + procedure setchecked(const avalue: boolean); + function getenabled: boolean; + procedure setenabled(const avalue: boolean); + function getvisible: boolean; + procedure setvisible(const avalue: boolean); + function getimagelist: timagelist; + procedure setimagelist(const avalue: timagelist); + function isimageliststored: boolean; + procedure setimagenr(const avalue: imagenrty); + function isimagenrstored: boolean; + procedure setimagenrdisabled(const avalue: imagenrty); + function isimagenrdisabledstored: boolean; + procedure setcolor(const avalue: colorty); + function iscolorstored: boolean; + procedure setcolorglyph(const avalue: colorty); + function iscolorglyphstored: boolean; + + function getfont: tmenufont; + function getfontactive: tmenufontactive; + procedure setfont(const avalue: tmenufont); + procedure setfontactive(const avalue: tmenufontactive); + function isfontstored: boolean; + function isfontactivestored: boolean; + procedure dofontchanged(const sender: tobject); + procedure sethint(const avalue: msestring); + function ishintstored: boolean; + procedure setcoloractive(const avalue: colorty); + function getcheckedtag: integer; + procedure setcheckedtag(const avalue: integer); + procedure readshortcut(reader: treader); + procedure readshortcut1(reader: treader); + procedure readsc(reader: treader); + procedure writesc(writer: twriter); + procedure readsc1(reader: treader); + procedure writesc1(writer: twriter); + procedure setcolorglyphactive(const avalue: colorty); + protected + finfo: actioninfoty; + fowner: tcustommenu; + fsubmenu: tmenuitems; + ffont: tmenufont; + ffontactive: tmenufontactive; + factiveitem: int32; //for iassistiveclient + function getactiveitem(out aitem: tmenuitem): boolean; + procedure updatecaption; + procedure defineproperties(filer: tfiler); override; + procedure befexec; + function doexec: boolean; + + function getiassistiveclient(): iassistiveclientmenu virtual; + //iassistiveclient + function getassistiveparent(): iassistiveclient; + function getassistivewidget(): tobject; + function getassistivename(): msestring; virtual; + function getassistivecaption(): msestring; virtual; + function getassistivetext(): msestring; virtual; + function getassistivecaretindex(): int32; virtual; + function getassistivehint(): msestring; virtual; + function getassistiveflags(): assistiveflagsty; virtual; + {$ifdef mse_with_ifi} + function getifidatalinkintf(): iifidatalink; virtual; + {$endif} + function getassistiveselfcaption(): msestring; + function getassistiveselfname(): msestring; + function getassistiveselfhint(): msestring; + + //iactionlink + function getactioninfopo: pactioninfoty; + function loading: boolean; + function shortcutseparator: msechar; + procedure calccaptiontext(var ainfo: actioninfoty); + + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + procedure receiveevent(const event: tobjectevent); override; + function internalexecute(async: boolean): boolean; + function canshowhint: boolean; + public + constructor create(const parentmenu: tmenuitem = nil; + const aowner: tcustommenu = nil); reintroduce; + destructor destroy; override; + procedure assign(source: tpersistent); override; + procedure beginload; + procedure endload; + procedure doupdate; + procedure updatehotkeys(); + procedure doshortcut(var info: keyeventinfoty); + function count: integer; + function hasvisibleitem: boolean; + function parentmenu: tmenuitem; + function actualcolor: colorty; + function actualcoloractive: colorty; + function actualcolorglyph: colorty; + function actualcolorglyphactive: colorty; + property owner: tcustommenu read fowner; //can be nil + function execute: boolean; //true if onexecute fired + function asyncexecute: boolean; + function canactivate: boolean; + function canshow: boolean; + procedure createfont; + procedure createfontactive; + property onchange: menuitemeventty read fonchange write fonchange; + property items[const index: integer]: tmenuitem read getitems + write setitems; default; + function itembyname(const name: string): tmenuitem; + function itembynames(const names: array of string): tmenuitem; + procedure deleteitembynames(const names: array of string); + function index: integer; //-1 if no parent menu + property checkedtag: integer read getcheckedtag write setcheckedtag; + //-1 if none checked + property checked: boolean read getchecked write setchecked; + property enabled: boolean read getenabled write setenabled; + property visible: boolean read getvisible write setvisible; + property tagpo: pointer read finfo.tagpo write finfo.tagpo; + property tagpointer: pointer read finfo.tagpo write finfo.tagpo; + deprecated 'Use tagpo instead'; + property shortcuts: shortcutarty read finfo.shortcut write setshortcuts; + property shortcuts1: shortcutarty read finfo.shortcut1 write setshortcuts1; + published + property action: tcustomaction read finfo.action write setaction; + property submenu: tmenuitems read getsubmenu write setsubmenu; + property caption: captionty read finfo.captiontext write setcaption + stored iscaptionstored; + property hint: msestring read finfo.hint write sethint stored ishintstored; + property name: string read fname write fname; + property state: actionstatesty read finfo.state write setstate + stored isstatestored default []; + property options: menuactionoptionsty read finfo.options + write setoptions default defaultmenuactoptions; + property shortcut: shortcutty read getshortcut write setshortcut + stored false default 0; + property shortcut1: shortcutty read getshortcut1 write setshortcut1 + stored false default 0; + property tag: integer read finfo.tag write settag stored istagstored default 0; + property group: integer read finfo.group write setgroup + stored isgroupstored default 0; + property imagelist: timagelist read getimagelist write setimagelist + stored isimageliststored; + property imagenr: imagenrty read finfo.imagenr write setimagenr + stored isimagenrstored default -1; + property imagenrdisabled: imagenrty read finfo.imagenrdisabled + write setimagenrdisabled + stored isimagenrdisabledstored default -2; + property color: colorty read finfo.color write setcolor + stored iscolorstored default cl_default; + property coloractive: colorty read fcoloractive write setcoloractive + default cl_default; + //cl_default maps to cl_parent, cl_normal maps to color property + property colorglyph: colorty read finfo.colorglyph write setcolorglyph + stored iscolorglyphstored default cl_default; + //cl_default maps to cl_glyph + property colorglyphactive: colorty read fcolorglyphactive + write setcolorglyphactive default cl_default; + //cl_default maps to cl_glyph + property font: tmenufont read getfont write setfont stored isfontstored; + property fontactive: tmenufontactive read getfontactive write setfontactive + stored isfontactivestored; + property onexecute: notifyeventty read finfo.onexecute + write setonexecute stored isonexecutestored; + property onbeforeexecute: accepteventty read finfo.onbeforeexecute + write setonbeforeexecute stored isonbeforeexecutestored; + property onafterexecute: notifyeventty read finfo.onafterexecute + write setonafterexecute stored isonafterexecutestored; + end; + + pmenuitem = ^tmenuitem; + + menueventty = procedure(const sender: tcustommenu) of object; + + tmenuframetemplate = class(tframetemplate) + public + constructor create(const owner: tmsecomponent; const onchange: notifyeventty); + override; + published + property levelo default 1; + end; + + menutemplatety = record + frame: tframecomp; + face: tfacecomp; + itemframe: tframecomp; + itemface: tfacecomp; + itemframeactive: tframecomp; + itemfaceactive: tfacecomp; + separatorframe: tframecomp; + checkboxframe: tframecomp; + end; + + tcustommenu = class(tmsecomponent) + private + fmenu: tmenuitem; + fonupdate: menueventty; + ftransient: boolean; + fexecitem: tmenuitem; + foptions: menuoptionsty; + ftemplate: menutemplatety; + procedure setmenu(const Value: tmenuitem); + procedure setframetemplate(const avalue: tframecomp); + procedure setfacetemplate(const avalue: tfacecomp); + procedure setitemframetemplate(const avalue: tframecomp); + procedure setitemfacetemplate(const avalue: tfacecomp); + procedure setitemframetemplateactive(const avalue: tframecomp); + procedure setitemfacetemplateactive(const avalue: tfacecomp); + procedure setoptions(const avalue: menuoptionsty); + procedure setseparatorframetemplate(const avalue: tframecomp); + procedure setcheckboxframetemplate(const avalue: tframecomp); + protected + ftransientfor: twidget; + fmouseinfopo: pmouseeventinfoty; + procedure settransientfor(const awidget: twidget); + procedure doidle(var again: boolean); + procedure readstate(reader: treader); override; + procedure loaded; override; + procedure setexecitem(const avalue: tmenuitem); + property execitem: tmenuitem write setexecitem; + procedure assigntemplate(const source: tcustommenu); + procedure templateevent(const sender: tobject; + const event: objecteventty; var template: menutemplatety); + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + function gettemplatefont(const sender: tmenuitem): tmenufont; virtual; + function gettemplatefontactive( + const sender: tmenuitem): tmenufontactive; virtual; + public + constructor create(aowner: tcomponent); overload; override; + constructor createtransient(const atransientfor: twidget; + const amouseinfopo: pmouseeventinfoty); overload; + destructor destroy; override; + function checkexec: boolean; + procedure assign(source: tpersistent); override; + procedure doshortcut(var info: keyeventinfoty); + procedure doupdate; + procedure updatehotkeys(); + function count: integer; + function transientfor: twidget; + function mouseinfopo: pmouseeventinfoty; + function shortcutseparator: msechar; + class function getshortcutseparator(const ainstance: tcustommenu): msechar; + property menu: tmenuitem read fmenu write setmenu; + property frametemplate: tframecomp read ftemplate.frame write setframetemplate; + property facetemplate: tfacecomp read ftemplate.face write setfacetemplate; + property itemframetemplate: tframecomp read ftemplate.itemframe + write setitemframetemplate; + property itemfacetemplate: tfacecomp read ftemplate.itemface + write setitemfacetemplate; + property itemframetemplateactive: tframecomp read ftemplate.itemframeactive + write setitemframetemplateactive; + property itemfacetemplateactive: tfacecomp read ftemplate.itemfaceactive + write setitemfacetemplateactive; + property separatorframetemplate: tframecomp + read ftemplate.separatorframe + write setseparatorframetemplate; + property checkboxframetemplate: tframecomp read ftemplate.checkboxframe + write setcheckboxframetemplate; + property template: menutemplatety read ftemplate; + property options: menuoptionsty read foptions write setoptions + default defaultmenuoptions; + property onupdate: menueventty read fonupdate write fonupdate; + end; + + tmenu = class(tcustommenu) + published + property options; + property onupdate; + property frametemplate; + property facetemplate; + property itemframetemplate; + property itemfacetemplate; + property itemframetemplateactive; + property itemfacetemplateactive; + property separatorframetemplate; + property checkboxframetemplate; + property menu; //last + end; + + tpopupmenu = class(tmenu) + private + protected + class function classskininfo: skininfoty; override; + public + function show(const atransientfor: twidget; + const pos: graphicdirectionty): tmenuitem; overload; + function show(const atransientfor: twidget; + var mouseinfo: mouseeventinfoty): tmenuitem; overload; + function show(const atransientfor: twidget; + const pos: pointty): tmenuitem; overload; + //returns selected item, nil if none + class function additems(var amenu: tpopupmenu; const atransientfor: twidget; + var mouseinfo: mouseeventinfoty; + const captions: array of msestring; + //if index > count -> index:= count + const aoptions: array of menuactionoptionsty; + const states: array of actionstatesty; + const onexecutes: array of notifyeventty; + const aseparator: boolean = true; + const optionalseparator: boolean = true): integer; overload; + //returs index of first added item + class function additems(var amenu: tpopupmenu; const atransientfor: twidget; + var mouseinfo: mouseeventinfoty; const items: tmenuitems; + const aseparator: boolean = true; const first: boolean = false; + const optionalseparator: boolean = true): integer; overload; + //returs index of first added item + class function additems(var amenu: tpopupmenu; const atransientfor: twidget; + var mouseinfo: mouseeventinfoty; const items: tcustommenu{; + const aseparator: boolean = true}): integer; overload; + //returs index of first added item + end; + + tcustommainmenu = class(tcustommenu) + private + fpopuptemplate: menutemplatety; + procedure setpopupframetemplate(const avalue: tframecomp); + procedure setpopupfacetemplate(const avalue: tfacecomp); + procedure setpopupitemframetemplate(const avalue: tframecomp); + procedure setpopupitemfacetemplate(const avalue: tfacecomp); + procedure setpopupitemframetemplateactive(const avalue: tframecomp); + procedure setpopupitemfacetemplateactive(const avalue: tfacecomp); + procedure setpopupseparatorframetemplate(const avalue: tframecomp); + procedure setpopupcheckboxframetemplate(const avalue: tframecomp); + protected + class function classskininfo: skininfoty; override; + procedure menuchanged(const sender: tmenuitem); + function gettemplatefont(const sender: tmenuitem): tmenufont; override; + function gettemplatefontactive( + const sender: tmenuitem): tmenufontactive; override; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property popuptemplate: menutemplatety read fpopuptemplate; + published + property options default defaultmainmenuoptions; + property popupframetemplate: tframecomp read fpopuptemplate.frame + write setpopupframetemplate; + property popupfacetemplate: tfacecomp read fpopuptemplate.face + write setpopupfacetemplate; + property popupitemframetemplate: tframecomp read fpopuptemplate.itemframe + write setpopupitemframetemplate; + property popupitemfacetemplate: tfacecomp read fpopuptemplate.itemface + write setpopupitemfacetemplate; + property popupitemframetemplateactive: tframecomp read fpopuptemplate.itemframeactive + write setpopupitemframetemplateactive; + property popupitemfacetemplateactive: tfacecomp read fpopuptemplate.itemfaceactive + write setpopupitemfacetemplateactive; + property popupseparatorframetemplate: tframecomp + read fpopuptemplate.separatorframe + write setpopupseparatorframetemplate; + property popupcheckboxframetemplate: tframecomp + read fpopuptemplate.checkboxframe + write setpopupcheckboxframetemplate; + end; + + tmainmenu = class(tcustommainmenu) + published + property options; + property onupdate; + property frametemplate; + property facetemplate; + property itemframetemplate; + property itemfacetemplate; + property itemframetemplateactive; + property itemfacetemplateactive; + property separatorframetemplate; + property checkboxframetemplate; + + property popupframetemplate; + property popupfacetemplate; + property popupitemframetemplate; + property popupitemfacetemplate; + property popupitemframetemplateactive; + property popupitemfacetemplateactive; + property popupseparatorframetemplate; + property popupcheckboxframetemplate; + property menu; //last + end; + + twidgetmainmenu = class(tcustommainmenu) + published + property Name stored true; + property options; + property onupdate; +// property frametemplate; +// property facetemplate; + property itemframetemplate; + property itemfacetemplate; + property itemframetemplateactive; + property itemfacetemplateactive; + property separatorframetemplate; + property checkboxframetemplate; + + property popupframetemplate; + property popupfacetemplate; + property popupitemframetemplate; + property popupitemfacetemplate; + property popupitemframetemplateactive; + property popupitemfacetemplateactive; + property popupseparatorframetemplate; + property popupcheckboxframetemplate; + property menu; //last + end; +procedure freetransientmenu(var amenu: tcustommenu); + +implementation +uses + sysutils,msestockobjects,rtlconsts,msebits,msemenuwidgets,msedatalist, + mseactions,msestreaming,msearrayutils,msesysutils; +type + tapplication1 = class(tguiapplication) + end; + +procedure freetransientmenu(var amenu: tcustommenu); +begin + if (amenu <> nil) and amenu.ftransient then begin + freeandnil(amenu); + end; +end; + +{ tmenuframetemplate } + +constructor tmenuframetemplate.create(const owner: tmsecomponent; + const onchange: notifyeventty); +begin + inherited; + fi.ba.levelo:= 1; +end; + +{ tcustommenu } + +constructor tcustommenu.create(aowner: tcomponent); +begin + foptions:= defaultmenuoptions; + inherited; +// include(fmsecomponentstate,cs_hasskin); + fmenu:= tmenuitem.create(nil,self); +end; + +constructor tcustommenu.createtransient(const atransientfor: twidget; + const amouseinfopo: pmouseeventinfoty); +begin + create(nil); + ftransient:= true; + settransientfor(atransientfor); + fmouseinfopo:= amouseinfopo; + updateskin; +end; + +destructor tcustommenu.destroy; +begin + if mo_updateonidle in foptions then begin + application.unregisteronidle({$ifdef FPC}@{$endif}doidle); + end; + fmenu.Free; + inherited; +end; + +function tcustommenu.count: integer; +begin + result:= fmenu.count; +end; + +procedure tcustommenu.setmenu(const Value: tmenuitem); +begin + fmenu.assign(Value); +end; + +procedure tcustommenu.doidle(var again: boolean); +begin + doupdate; +end; + +procedure tcustommenu.readstate(reader: treader); +begin + fmenu.beginload; + inherited; +end; + +procedure tcustommenu.loaded; +begin + fmenu.endload; + inherited; + updateskin; +end; + +procedure tcustommenu.setexecitem(const avalue: tmenuitem); +begin + fexecitem:= avalue; +end; + +function tcustommenu.checkexec: boolean; +begin + result:= fexecitem <> nil; + if result then begin + result:= fexecitem.doexec; +// result:= doactionexecute(fexecitem,fexecitem.finfo,true, +// mao_nocandefocus in fexecitem.options); + end; + fexecitem:= nil; +end; + +procedure tcustommenu.doupdate; +begin + fexecitem:= nil; + fmenu.doupdate; + if canevent(tmethod(fonupdate)) then begin + fonupdate(self); + end; +end; + +procedure tcustommenu.updatehotkeys(); +begin + if fmenu <> nil then begin + fmenu.updatehotkeys(); + end; +end; + +procedure tcustommenu.doshortcut(var info: keyeventinfoty); +begin + fmenu.doshortcut(info); +end; + +procedure tcustommenu.assign(source: tpersistent); +begin + if source is tcustommenu then begin + with tcustommenu(source) do begin + self.onupdate:= onupdate; + self.foptions:= options; + self.fmenu.Assign(fmenu); + end; + end + else begin + inherited; + end; +end; + +function tcustommenu.transientfor: twidget; +begin + result:= ftransientfor; +end; + +function tcustommenu.mouseinfopo: pmouseeventinfoty; +begin + result:= fmouseinfopo; +end; + +function tcustommenu.shortcutseparator: msechar; +begin + if mo_shortcutright in foptions then begin + result:= c_tab; + end + else begin + result:= ' '; + end; +end; + +class function tcustommenu.getshortcutseparator( + const ainstance: tcustommenu): msechar; +begin + if ainstance = nil then begin + result:= c_tab; + end + else begin + result:= ainstance.shortcutseparator; + end; +end; + +procedure tcustommenu.setframetemplate(const avalue: tframecomp); +begin + if avalue <> ftemplate.frame then begin + setlinkedvar(avalue,tmsecomponent(ftemplate.frame)); + sendchangeevent; + end; +end; + +procedure tcustommenu.setfacetemplate(const avalue: tfacecomp); +begin + if avalue <> ftemplate.face then begin + setlinkedvar(avalue,tmsecomponent(ftemplate.face)); + sendchangeevent; + end; +end; + +procedure tcustommenu.setitemframetemplate(const avalue: tframecomp); +begin + if avalue <> ftemplate.itemframe then begin + setlinkedvar(avalue,tmsecomponent(ftemplate.itemframe)); + sendchangeevent; + end; +end; + +procedure tcustommenu.setitemfacetemplate(const avalue: tfacecomp); +begin + if avalue <> ftemplate.itemface then begin + setlinkedvar(avalue,tmsecomponent(ftemplate.itemface)); + sendchangeevent; + end; +end; + +procedure tcustommenu.setitemframetemplateactive(const avalue: tframecomp); +begin + if avalue <> ftemplate.itemframeactive then begin + setlinkedvar(avalue,tmsecomponent(ftemplate.itemframeactive)); + sendchangeevent; + end; +end; + +procedure tcustommenu.setitemfacetemplateactive(const avalue: tfacecomp); +begin + if avalue <> ftemplate.itemfaceactive then begin + setlinkedvar(avalue,tmsecomponent(ftemplate.itemfaceactive)); + sendchangeevent; + end; +end; + +procedure tcustommenu.setseparatorframetemplate(const avalue: tframecomp); +begin + if avalue <> ftemplate.separatorframe then begin + setlinkedvar(avalue,tmsecomponent(ftemplate.separatorframe)); + sendchangeevent; + end; +end; + +procedure tcustommenu.setcheckboxframetemplate(const avalue: tframecomp); +begin + if avalue <> ftemplate.checkboxframe then begin + setlinkedvar(avalue,tmsecomponent(ftemplate.checkboxframe)); + sendchangeevent; + end; +end; + +procedure tcustommenu.settransientfor(const awidget: twidget); +begin + ftransientfor:= awidget; + tapplication1(application).flastshowmenuwidget:= awidget; +end; + +procedure tcustommenu.templateevent(const sender: tobject; + const event: objecteventty; var template: menutemplatety); +begin + case event of + oe_changed,oe_destroyed: begin + if (sender = template.face) or (sender = ftemplate.frame) or + (sender = template.itemface) or (sender = ftemplate.itemframe) or + (sender = template.itemfaceactive) or + (sender = template.itemframeactive) or + (sender = template.separatorframe) or + (sender = template.checkboxframe) then begin + if event = oe_destroyed then begin + if sender = template.face then begin + template.face:= nil; + end; + if sender = template.frame then begin + template.frame:= nil; + end; + if sender = template.itemface then begin + template.itemface:= nil; + end; + if sender = template.itemframe then begin + template.itemframe:= nil; + end; + if sender = template.itemframeactive then begin + template.itemframeactive:= nil; + end; + if sender = template.separatorframe then begin + template.separatorframe:= nil; + end; + if sender = template.checkboxframe then begin + template.checkboxframe:= nil; + end; + end; + sendchangeevent; + end; + end; + end; +end; + +procedure tcustommenu.objectevent(const sender: tobject; + const event: objecteventty); +begin + templateevent(sender,event,ftemplate); + inherited; +end; + +procedure tcustommenu.assigntemplate(const source: tcustommenu); +begin + ftemplate:= source.ftemplate; +end; + +procedure tcustommenu.setoptions(const avalue: menuoptionsty); +var + optionsbefore,delta: menuoptionsty; +begin + if avalue <> foptions then begin + optionsbefore:= foptions; + foptions:= avalue; + delta:= menuoptionsty( + {$ifdef FPC}longword{$else}byte{$endif}(optionsbefore) xor + {$ifdef FPC}longword{$else}byte{$endif}(foptions)); + if not (csreading in componentstate) and + (mo_shortcutright in delta) then begin + fmenu.updatecaption; + end; + if mo_updateonidle in delta then begin + if (mo_updateonidle in foptions) and + not (csdesigning in componentstate) then begin + application.registeronidle({$ifdef FPC}@{$endif}doidle); + end + else begin + application.unregisteronidle({$ifdef FPC}@{$endif}doidle); + end; + end; + sendchangeevent; + end; +end; + +function tcustommenu.gettemplatefont(const sender: tmenuitem): tmenufont; +begin + result:= nil; + if itemframetemplate <> nil then begin +{$warnings off} + result:= tmenufont(itemframetemplate.template.font); +{$warnings on} + end; +{ + if result = nil then begin + result:= tmenufont(pointer(stockobjects.fonts[stf_menu])); + end; +} +end; + +function tcustommenu.gettemplatefontactive( + const sender: tmenuitem): tmenufontactive; +begin + result:= nil; + if itemframetemplateactive <> nil then begin + result:= tmenufontactive(pointer(itemframetemplateactive.template.font)); + end; +end; + +{ tmenufont } + +class function tmenufont.getinstancepo(owner: tobject): pfont; +begin + result:= @(tmenuitem(owner).ffont); +end; + +{ tmenufontactive } + +class function tmenufontactive.getinstancepo(owner: tobject): pfont; +begin + result:= @(tmenuitem(owner).ffontactive); +end; + +{ tmenuitem } + +constructor tmenuitem.create(const parentmenu: tmenuitem = nil; + const aowner: tcustommenu = nil); +begin + fparentmenu:= parentmenu; + if fparentmenu <> nil then begin + fowner:= fparentmenu.fowner; + end + else begin + fowner:= aowner; + end; + initactioninfo(finfo,defaultmenuactoptions); + finfo.color:= cl_default; + finfo.colorglyph:= cl_default; + fcoloractive:= cl_default; + fcolorglyphactive:= cl_default; + inherited create; +end; + +destructor tmenuitem.destroy; +begin +// if fsubmenu <> nil then begin +// fsubmenu.count:= 0; +// end; + if (fparentmenu <> nil) then begin + fparentmenu.fsubmenu.itemdestroyed(self); + end; + fsubmenu.free; + if (fowner = nil) or not fowner.ftransient then begin + ffont.free; + ffontactive.free; + end; + inherited destroy; +end; + +function tmenuitem.count: integer; +begin + if fsubmenu = nil then begin + result:= 0; + end + else begin + result:= fsubmenu.count; + end; +end; + +function tmenuitem.hasvisibleitem: boolean; +begin + result:= (fsubmenu <> nil) and fsubmenu.hasvisibleitem; +end; + +function tmenuitem.getsubmenu: tmenuitems; +begin + if fsubmenu = nil then begin + fsubmenu:= tmenuitems.create(self); + end; + result:= fsubmenu; +end; + +procedure tmenuitem.setsubmenu(const Value: tmenuitems); +begin + if value = nil then begin + freeandnil(fsubmenu); + end + else begin + getsubmenu.Assign(value); + end; +end; + +function tmenuitem.parentmenu: tmenuitem; +begin + result:= fparentmenu; +end; + +procedure tmenuitem.setcaption(const avalue: captionty); +begin + setactioncaption(iactionlink(self),avalue); +end; + +function tmenuitem.iscaptionstored: Boolean; +begin + result:= isactioncaptionstored(finfo); +end; + +procedure tmenuitem.sethint(const avalue: msestring); +begin + setactionhint(iactionlink(self),avalue); +end; + +function tmenuitem.ishintstored: boolean; +begin + result:= isactionhintstored(finfo); +end; + +procedure tmenuitem.setstate(const avalue: actionstatesty); +begin + setactionstate(iactionlink(self),avalue); +end; + +function tmenuitem.isstatestored: Boolean; +begin + result:= isactionstatestored(finfo); +end; + +function tmenuitem.isshortcutstored: Boolean; +begin + result:= isactionshortcutstored(finfo); +end; + +procedure tmenuitem.setshortcut(const avalue: shortcutty); +begin + setactionshortcut(iactionlink(self),avalue); +end; + +function tmenuitem.isshortcut1stored: Boolean; +begin + result:= isactionshortcut1stored(finfo); +end; + +function tmenuitem.getshortcut: shortcutty; +begin + result:= getsimpleshortcut(finfo); +end; + +function tmenuitem.getshortcut1: shortcutty; +begin + result:= getsimpleshortcut1(finfo); +end; + +procedure tmenuitem.setshortcuts(const avalue: shortcutarty); +begin + setactionshortcuts(iactionlink(self),avalue); +end; + +procedure tmenuitem.setshortcuts1(const avalue: shortcutarty); +begin + setactionshortcuts1(iactionlink(self),avalue); +end; + +procedure tmenuitem.setshortcut1(const avalue: shortcutty); +begin + setactionshortcut1(iactionlink(self),avalue); +end; + +function tmenuitem.istagstored: Boolean; +begin + result:= isactiontagstored(finfo); +end; + +procedure tmenuitem.settag(const avalue: integer); +begin + setactiontag(iactionlink(self),avalue); +end; + +function tmenuitem.isgroupstored: Boolean; +begin + result:= isactiongroupstored(finfo); +end; + +procedure tmenuitem.setgroup(const avalue: integer); +begin + setactiongroup(iactionlink(self),avalue); +end; + +procedure tmenuitem.setoptions(const avalue: menuactionoptionsty); +begin + setactionoptions(iactionlink(self),avalue); +end; + +procedure tmenuitem.setonexecute(const avalue: notifyeventty); +begin + setactiononexecute(iactionlink(self),avalue, + (fowner <> nil) and (csloading in fowner.componentstate)); +end; + +procedure tmenuitem.setonbeforeexecute(const avalue: accepteventty); +begin + setactiononbeforeexecute(iactionlink(self),avalue, + (fowner <> nil) and (csloading in fowner.componentstate)); +end; + +procedure tmenuitem.setonafterexecute(const avalue: notifyeventty); +begin + setactiononafterexecute(iactionlink(self),avalue, + (fowner <> nil) and (csloading in fowner.componentstate)); +end; + +function tmenuitem.isonexecutestored: Boolean; +begin + result:= isactiononexecutestored(finfo); +end; + +function tmenuitem.isonbeforeexecutestored: Boolean; +begin + result:= isactiononbeforeexecutestored(finfo); +end; + +function tmenuitem.isonafterexecutestored: Boolean; +begin + result:= isactiononafterexecutestored(finfo); +end; + +procedure tmenuitem.setcoloractive(const avalue: colorty); +begin + if avalue <> fcoloractive then begin + fcoloractive:= avalue; + actionchanged; + end; +end; + +procedure tmenuitem.setcolorglyphactive(const avalue: colorty); +begin + if avalue <> fcolorglyphactive then begin + fcolorglyphactive:= avalue; + actionchanged(); + end; +end; + +function tmenuitem.getitems(const index: integer): tmenuitem; +begin + checksubmenu; + result:= fsubmenu.items[index]; +end; + +procedure tmenuitem.setitems(const index: integer; const Value: tmenuitem); +begin + checksubmenu; + fsubmenu.items[index]:= value; +end; + +function tmenuitem.itembyname(const name: string): tmenuitem; +begin + if fsubmenu = nil then begin + result:= nil; + end + else begin + result:= fsubmenu.itembyname(name); + end; +end; + +function tmenuitem.itembynames(const names: array of string): tmenuitem; +var + int1: integer; + sub1: tmenuitems; +begin + result:= self; + for int1:= 0 to high(names) do begin + sub1:= result.fsubmenu; + if sub1 = nil then begin + break; + end; + result:= sub1.itembyname(names[int1]); + if result = nil then begin + break; + end; + end; +end; + +procedure tmenuitem.deleteitembynames(const names: array of string); +var + item1: tmenuitem; +begin + item1:= itembynames(names); + if item1 <> nil then begin + item1.fparentmenu.submenu.delete(item1.index); + end; +end; + +function tmenuitem.index: integer; //-1 if no parent menu +begin + if fparentmenu = nil then begin + result:= -1; + end + else begin + result:= fparentmenu.fsubmenu.indexof(self); + end; +end; + +procedure tmenuitem.checksubmenu; +begin + if fsubmenu = nil then begin + tlist.Error({$ifndef FPC}@{$endif}SListIndexError, 0); + end; +end; + +procedure tmenuitem.befexec; +begin + if [mao_checkbox,mao_radiobutton] * finfo.options <> [] then begin + if mao_checkbox in finfo.options then begin + checked:= not checked; + end + else begin + checked:= true; + end; + end; +end; + +function tmenuitem.doexec: boolean; +begin + result:= doactionexecute(self,finfo,true, + mao_nocandefocus in finfo.options,@befexec); +end; + +function tmenuitem.getiassistiveclient(): iassistiveclientmenu; +begin + result:= iassistiveclientmenu(self); +end; + +function tmenuitem.getassistiveparent(): iassistiveclient; +begin + result:= nil; + if fparentmenu <> nil then begin + result:= fparentmenu.getiassistiveclient(); + end; +end; + +function tmenuitem.getassistivewidget(): tobject; +begin + result:= nil; +end; + +function tmenuitem.internalexecute(async: boolean): boolean; +begin + result:= canactivate {and assigned(finfo.onexecute)}; + if result then begin + if async then begin + result:= doexec; +// finfo.onexecute(self); + end + else begin + fowner.execitem:= self; + end; + end; +end; + +function tmenuitem.execute: boolean; +begin + result:= internalexecute(false); +end; + +function tmenuitem.asyncexecute: boolean; +begin + result:= canactivate {and assigned(finfo.onexecute)}; + if result then begin + if fsource <> nil then begin + application.postevent(tobjectevent.create(ek_execute,fsource)); + end + else begin + application.postevent(tobjectevent.create(ek_execute,ievent(self))); + end; + end; +end; + +procedure tmenuitem.receiveevent(const event: tobjectevent); +begin + if event.kind = ek_execute then begin + internalexecute(true); + end; +end; + +procedure tmenuitem.setaction(const avalue: tcustomaction); +begin + linktoaction(iactionlink(self),avalue,finfo); +end; + +function tmenuitem.getactioninfopo: pactioninfoty; +begin + result:= @finfo; +end; + +function tmenuitem.loading: boolean; +begin + result:= (fowner <> nil) and (csloading in fowner.componentstate); +end; + +function tmenuitem.shortcutseparator: msechar; +begin + if fowner <> nil then begin + result:= fowner.shortcutseparator; + end + else begin + result:= c_tab; + end; +end; + +procedure tmenuitem.calccaptiontext(var ainfo: actioninfoty); +begin + mseactions.calccaptiontext(ainfo,shortcutseparator); +end; + +procedure tmenuitem.beginload; +var + int1: integer; +begin + actionbeginload(iactionlink(self)); + for int1:= 0 to count - 1 do begin + items[int1].beginload; + end; +end; + +procedure tmenuitem.endload; +var + int1: integer; +begin + actionendload(iactionlink(self)); + for int1:= 0 to count - 1 do begin + items[int1].endload; + end; +end; + +procedure tmenuitem.doupdate; +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + items[int1].doupdate; + end; + if finfo.action <> nil then begin + finfo.action.doupdate; + end; +end; + +procedure tmenuitem.updatehotkeys(); +var + i1: int32; +begin + calccaptiontext(finfo); + for i1:= 0 to count - 1 do begin + items[i1].updatehotkeys(); + end; +end; + +function tmenuitem.canactivate: boolean; +begin + result:= (finfo.state * [as_disabled,as_invisible] = []) and + (finfo.options * [mao_separator] = []); +end; + +function tmenuitem.canshow: boolean; +var + int1: integer; +begin + result:= false; + if enabled and (fsubmenu <> nil) then begin + for int1:= 0 to fsubmenu.count - 1 do begin + if not (as_invisible in fsubmenu[int1].finfo.state) then begin + result:= true; + break; + end; + end; + end; +end; + +procedure tmenuitem.doshortcut(var info: keyeventinfoty); +var + int1: integer; +begin + if doactionshortcut(self,finfo,info,@befexec) then begin + actionchanged; + end + else begin + for int1:= 0 to count -1 do begin + if (es_processed in info.eventstate) then begin + break; + end; + fsubmenu[int1].doshortcut(info); + end; + end; +end; + +procedure tmenuitem.assign(source: tpersistent); +var + action1: tcustomaction; +begin + if source is tmenuitem then begin + fsource:= imenuitem(tmenuitem(source)); + action1:= finfo.action; + with tmenuitem(source) do begin + self.finfo:= finfo; + self.finfo.action:= action1; + self.action:= finfo.action; + self.submenu:= fsubmenu; + self.fcoloractive:= fcoloractive; + if self.fowner.ftransient then begin + self.ffont:= font; + self.ffontactive:= fontactive; + end + else begin + self.font:= font; + self.fontactive:= fontactive; + end; + end; + end; +end; + +function tmenuitem.getchecked: boolean; +begin + result:= as_checked in finfo.state; +end; + +procedure tmenuitem.resetradiobuttons(); +var + int1: integer; + item1: tmenuitem; +begin + if (mao_radiobutton in finfo.options) and (fparentmenu <> nil) then begin + for int1:= 0 to fparentmenu.count-1 do begin + item1:= fparentmenu[int1]; + with item1 do begin + if (mao_radiobutton in finfo.options) and (item1 <> self) and + (finfo.group = self.finfo.group) then begin + setactionchecked(iactionlink(item1),false); + end; + end; + end; + end; +end; + +procedure tmenuitem.setchecked(const avalue: boolean); +begin + if (as_checked in finfo.state) <> avalue then begin + if avalue then begin + resetradiobuttons(); + end; +{ + if avalue and (mao_radiobutton in finfo.options) and (fparentmenu <> nil) then begin + for int1:= 0 to fparentmenu.count-1 do begin + item1:= fparentmenu[int1]; + with item1 do begin + if (mao_radiobutton in finfo.options) and (item1 <> self) and + (finfo.group = self.finfo.group) then begin + setactionchecked(iactionlink(item1),false); + end; + end; + end; + end; +} + setactionchecked(iactionlink(self),avalue); + end; +end; + +procedure tmenuitem.actionchanged; +const + mask: actionstatesty = [as_checked]; +var + state1: actionstatesty; +begin + if as_checked in finfo.state then begin + resetradiobuttons(); + end; + if assigned(fonchange) then begin + fonchange(self); + end; + if (fparentmenu <> nil) and assigned(fparentmenu.fonchange) then begin + fparentmenu.fonchange(self); + end; + if ([mao_checkbox,mao_radiobutton] * finfo.options <> []) and + (fsource <> nil) and (fowner <> nil) and (fowner.ftransient) then begin + state1:= fsource.getstate; + state1:= actionstatesty( + replacebits(longword(state),longword(state1),longword(mask))); + fsource.setstate(state1); + end; +end; + +function tmenuitem.getenabled: boolean; +begin + result:= not (as_disabled in finfo.state); +end; + +procedure tmenuitem.setenabled(const avalue: boolean); +begin + if avalue then begin + state:= state - [as_disabled]; + end + else begin + state:= state + [as_disabled]; + end; +end; + +function tmenuitem.getvisible: boolean; +begin + result:= not (as_invisible in finfo.state); +end; + +procedure tmenuitem.setvisible(const avalue: boolean); +begin + if avalue then begin + state:= state - [as_invisible]; + end + else begin + state:= state + [as_invisible]; + end; +end; + +function tmenuitem.getimagelist: timagelist; +begin + result:= timagelist(finfo.imagelist); +end; + +procedure tmenuitem.setimagelist(const avalue: timagelist); +begin + setactionimagelist(iactionlink(self),avalue); +end; + +function tmenuitem.isimageliststored: Boolean; +begin + result:= isactionimageliststored(finfo); +end; + +procedure tmenuitem.setimagenr(const avalue: imagenrty); +begin + setactionimagenr(iactionlink(self),avalue); +end; + +function tmenuitem.isimagenrstored: Boolean; +begin + result:= isactionimagenrstored(finfo); +end; + +procedure tmenuitem.setimagenrdisabled(const avalue: imagenrty); +begin + setactionimagenrdisabled(iactionlink(self),avalue); +end; + +function tmenuitem.isimagenrdisabledstored: Boolean; +begin + result:= isactionimagenrdisabledstored(finfo); +end; + +procedure tmenuitem.setcolor(const avalue: colorty); +begin + setactioncolor(iactionlink(self),avalue); +end; + +function tmenuitem.iscolorstored: Boolean; +begin + result:= isactioncolorstored(finfo); +end; + +procedure tmenuitem.setcolorglyph(const avalue: colorty); +begin + setactioncolorglyph(iactionlink(self),avalue); +end; + +function tmenuitem.iscolorglyphstored: Boolean; +begin + result:= isactioncolorglyphstored(finfo); +end; + +function tmenuitem.isfontstored: boolean; +begin + result:= ffont <> nil; +end; + +function tmenuitem.isfontactivestored: boolean; +begin + result:= ffontactive <> nil; +end; + +procedure tmenuitem.dofontchanged(const sender: tobject); +begin + actionchanged; +end; + +procedure tmenuitem.createfont; +begin + if ffont = nil then begin + ffont:= tmenufont.create; + ffont.onchange:= {$ifdef FPC}@{$endif}dofontchanged; + end; +end; + +procedure tmenuitem.createfontactive; +begin + if ffontactive = nil then begin + ffontactive:= tmenufontactive.create; + ffontactive.onchange:= {$ifdef FPC}@{$endif}dofontchanged; + end; +end; + +function tmenuitem.getfont: tmenufont; +begin + getoptionalobject(fowner,ffont,{$ifdef FPC}@{$endif}createfont); + if ffont <> nil then begin + result:= ffont; + end + else begin + result:= nil; + if (fowner <> nil) then begin + result:= fowner.gettemplatefont(self); + end; + if (result = nil) then begin + if fparentmenu <> nil then begin + result:= fparentmenu.getfont; + end + else begin + result:= tmenufont(pointer(stockobjects.fonts[stf_menu])); + end; + end; + end; +end; + +function tmenuitem.getfontactive: tmenufontactive; +begin + getoptionalobject(fowner,ffontactive, + {$ifdef FPC}@{$endif}createfontactive); + if ffontactive <> nil then begin + result:= ffontactive; + end + else begin + result:= nil; + if (fowner <> nil) then begin + result:= fowner.gettemplatefontactive(self); + end; + if result = nil then begin + result:= tmenufontactive(pointer(ffont)); + if result = nil then begin + if fparentmenu <> nil then begin + result:= fparentmenu.getfontactive; + end + else begin + result:= tmenufontactive(pointer(stockobjects.fonts[stf_menu])); + end; + end; + end; + end; +end; + +procedure tmenuitem.setfont(const avalue: tmenufont); +begin + if avalue <> ffont then begin + setoptionalobject(fowner,avalue,ffont, + {$ifdef FPC}@{$endif}createfont); + actionchanged; + end; +end; + +procedure tmenuitem.setfontactive(const avalue: tmenufontactive); +begin + if avalue <> ffontactive then begin + setoptionalobject(fowner,avalue,ffontactive, + {$ifdef FPC}@{$endif}createfontactive); + actionchanged; + end; +end; + +procedure tmenuitem.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (event = oe_changed) and (sender = finfo.imagelist) then begin + actionchanged; + end; +end; + +function tmenuitem.canshowhint: boolean; +var + item1: tmenuitem; +begin + result:= false; + if finfo.hint <> '' then begin + result:= true; + item1:= self; + while item1 <> nil do begin + if item1.options * [mao_showhint,mao_noshowhint] <> []then begin + if mao_noshowhint in item1.options then begin + result:= false; + end; + break; + end; + item1:= item1.fparentmenu; + end; + end; +end; + +procedure tmenuitem.readshortcut(reader: treader); +begin + shortcut:= translateshortcut(reader.readinteger); +end; + +procedure tmenuitem.readshortcut1(reader: treader); +begin + shortcut1:= translateshortcut(reader.readinteger); +end; + +procedure tmenuitem.readsc(reader: treader); +begin + shortcuts:= readshortcutarty(reader); +end; + +procedure tmenuitem.writesc(writer: twriter); +begin + writeshortcutarty(writer,finfo.shortcut); +end; + +procedure tmenuitem.readsc1(reader: treader); +begin + shortcuts1:= readshortcutarty(reader); +end; + +procedure tmenuitem.writesc1(writer: twriter); +begin + writeshortcutarty(writer,finfo.shortcut1); +end; + +procedure tmenuitem.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('shortcut',{$ifdef FPC}@{$endif}readshortcut,nil,false); + filer.defineproperty('shortcut1',{$ifdef FPC}@{$endif}readshortcut1,nil,false); + filer.defineproperty('sc',{$ifdef FPC}@{$endif}readsc, + {$ifdef FPC}@{$endif}writesc, + isactionshortcutstored(finfo) and + ((filer.ancestor = nil) and (finfo.shortcut <> nil) or + ((filer.ancestor <> nil) and + not issameshortcut(finfo.shortcut, + tmenuitem(filer.ancestor).shortcuts)))); + filer.defineproperty('sc1',{$ifdef FPC}@{$endif}readsc1, + {$ifdef FPC}@{$endif}writesc1, + isactionshortcut1stored(finfo) and + ((filer.ancestor = nil) and (finfo.shortcut1 <> nil) or + ((filer.ancestor <> nil) and + not issameshortcut(finfo.shortcut, + tmenuitem(filer.ancestor).shortcuts)))); +end; + +procedure tmenuitem.updatecaption; +var + int1: integer; +begin + mseactions.calccaptiontext(finfo,shortcutseparator); + for int1:= 0 to count - 1 do begin + fsubmenu[int1].updatecaption; + end; +end; + +function tmenuitem.actualcolor: colorty; +begin + result:= finfo.color; + if (result = cl_default) or (result = cl_parent) then begin + if fparentmenu = nil then begin + result:= cl_transparent; + end + else begin + result:= fparentmenu.actualcolor; + end; + end; +end; + +function tmenuitem.actualcoloractive: colorty; +begin + result:= fcoloractive; + if (result = cl_default) or (result = cl_parent) then begin + if fparentmenu = nil then begin + result:= actualcolor; + end + else begin + result:= fparentmenu.actualcoloractive; + end; + end + else begin + if result = cl_normal then begin + result:= actualcolor; + end; + end; +end; + +function tmenuitem.actualcolorglyph: colorty; +begin + result:= finfo.colorglyph; + if (result = cl_default) or (result = cl_parent) then begin + if fparentmenu <> nil then begin + result:= fparentmenu.actualcolorglyph; + end + else begin + result:= cl_default; + end; + end; +end; + +function tmenuitem.actualcolorglyphactive: colorty; +begin + result:= fcolorglyphactive; + if (result = cl_default) or (result = cl_parent) then begin + if fparentmenu <> nil then begin + result:= fparentmenu.actualcolorglyphactive; + end + else begin + result:= cl_default; + end; + end; +end; + +function tmenuitem.getstate: actionstatesty; +begin + result:= finfo.state; +end; + +function tmenuitem.getcheckedtag: integer; +var + int1: integer; +begin + result:= -1; + if fparentmenu <> nil then begin + with fparentmenu.fsubmenu do begin + for int1:= 0 to high(fitems) do begin + with tmenuitem(fitems[int1]) do begin + if (mao_radiobutton in finfo.options) and (finfo.group = self.finfo.group) and + checked then begin + result:= finfo.tag; + break; + end; + end; + end; + end; + end; +end; + +procedure tmenuitem.setcheckedtag(const avalue: integer); +var + int1: integer; +begin + if fparentmenu <> nil then begin + with fparentmenu.fsubmenu do begin + for int1:= 0 to high(fitems) do begin + with tmenuitem(fitems[int1]) do begin + if (mao_radiobutton in finfo.options) and + (finfo.group = self.finfo.group) then begin + if finfo.tag = avalue then begin + checked:= true; + break; + end + else begin + checked:= false; + end; + end; + end; + end; + end; + end; +end; + +function tmenuitem.getactiveitem(out aitem: tmenuitem): boolean; +begin + result:= (factiveitem >= 0) and (fsubmenu <> nil) and + (factiveitem < fsubmenu.count); + if result then begin + aitem:= fsubmenu[factiveitem]; + end; +end; + +function tmenuitem.getassistivename: msestring; +var + item1: tmenuitem; +begin + if getactiveitem(item1) then begin + result:= msestring(item1.fname); + end + else begin + result:= ''; + end; + if (result = '') and (fowner <> nil) then begin + result:= msestring(fowner.name); + end; +end; + +function tmenuitem.getassistivecaption(): msestring; +var + item1: tmenuitem; +begin + if getactiveitem(item1) then begin + result:= item1.finfo.captiontext; + end + else begin + result:= ''; + end; +end; + +function tmenuitem.getassistivetext(): msestring; +begin + result:= ''; +end; + +function tmenuitem.getassistivecaretindex(): int32; +begin + result:= -1; +end; + +function tmenuitem.getassistivehint(): msestring; +var + item1: tmenuitem; +begin + if getactiveitem(item1) then begin + result:= item1.finfo.hint; + end + else begin + result:= ''; + end; +end; + +function tmenuitem.getassistiveflags(): assistiveflagsty; +begin + result:= [asf_menu]; +end; + +function tmenuitem.getifidatalinkintf(): iifidatalink; +begin + result:= nil; +end; + +function tmenuitem.getassistiveselfcaption(): msestring; +begin + result:= caption; +end; + +function tmenuitem.getassistiveselfname(): msestring; +begin + result:= msestring(name); +end; + +function tmenuitem.getassistiveselfhint(): msestring; +begin + result:= hint; +end; + +{ tmenuitems } + +constructor tmenuitems.create(const aowner: tmenuitem); +begin + fowner:= aowner; + inherited create(tmenuitem); +end; + +class function tmenuitems.getitemclasstype: persistentclassty; +begin + result:= tmenuitem; +end; + +procedure tmenuitems.assign(source: tpersistent); +var + int1: integer; +begin + if source is tmenuitems then begin + with tmenuitems(source) do begin + self.count:= count; + for int1:= 0 to count - 1 do begin + self.setmenuitems(int1,getmenuitems(int1)); + end; + end; + end + else begin + inherited; + end; +end; + +procedure tmenuitems.createitem(const index: integer; var item: tpersistent); +begin + item:= tmenuitem.create(fowner,fowner.fowner); +end; + +procedure tmenuitems.receiveevent(const event: tobjectevent); +begin + if event.kind = ek_release then begin + destroy; + end; +end; + +procedure tmenuitems.dosizechanged; +begin + inherited; + { too dangerous because of runtime submenu clear in with statement. + if count = 0 then begin + tmenuitem(fowner).fsubmenu:= nil; + fowner:= nil; + application.postevent(tobjectevent.create(ek_release,ievent(self))); + end; + } +end; + +procedure tmenuitems.dochange(const aindex: integer); +var + int1: integer; +begin + if aindex = -1 then begin + for int1:= 0 to count - 1 do begin + items[int1].actionchanged; + end; + end; + if fowner <> nil then begin + fowner.actionchanged; + end; + inherited; +end; + +function tmenuitems.getmenuitems(index: integer): tmenuitem; +begin + result:= tmenuitem(getitems(index)); +end; + +function tmenuitems.insert(const index: integer; const aitem: tmenuitem): integer; +var + int1: integer; +begin + int1:= index; + if index > count then begin + int1:= count; + end; + result:= int1; + beginupdate; + try + insertempty(int1); + aitem.fparentmenu:= fowner; + aitem.fowner:= fowner.fowner; + fitems[int1]:= aitem; + finally + endupdate; + end; +end; + +procedure tmenuitems.insertseparator(const index: integer; + const aoptional: boolean = false); +var + item1: tmenuitem; + opt1: menuactionoptionsty; +begin + item1:= tmenuitem.create; + opt1:= [mao_separator]; + if aoptional then begin + opt1:= [mao_separator,mao_optional]; + end; + item1.options:= item1.options + opt1; + insert(index,item1); +end; + +function tmenuitems.insert(const index: integer; + const aitems: tmenuitems): integer; +var + int1,int2: integer; + item1: tmenuitem; +begin + int1:= index; + if index > count then begin + int1:= count; + end; + result:= int1; + beginupdate; + try + for int2:= 0 to aitems.count - 1 do begin + item1:= tmenuitem.create; + insert(int1,item1); + item1.assign(aitems[int2]); + inc(int1); + end; + finally + endupdate; + end; +end; + +function tmenuitems.insert(const index: integer; + const captions: array of msestring; + //if index > count -> index:= count + const options: array of menuactionoptionsty; + const states: array of actionstatesty; + const onexecutes: array of notifyeventty): integer; +var + int1,int2,int3: integer; + item1: tmenuitem; +begin + int1:= -1; + if high(captions) > int1 then begin + int1:= high(captions); + end; + if high(options) > int1 then begin + int1:= high(options); + end; + if high(states) > int1 then begin + int1:= high(states); + end; + if high(onexecutes) > int1 then begin + int1:= high(onexecutes); + end; + if index > count then begin + int3:= count; + end + else begin + int3:= index; + end; + result:= int3; + beginupdate; + try + for int2:= 0 to int1 do begin + item1:= tmenuitem.create; + if int2 <= high(captions) then begin + item1.caption:= captions[int2]; + end; + if int2 <= high(options) then begin + item1.options:= options[int2]; + end; + if int2 <= high(states) then begin + item1.state:= states[int2]; + end; + if int2 <= high(onexecutes) then begin + item1.onexecute:= onexecutes[int2]; + end; + insert(int3,item1); + inc(int3); + end; + finally + endupdate; + end; +end; + +procedure tmenuitems.setmenuitems(index: integer; const Value: tmenuitem); +begin + tmenuitem(getitems(index)).assign(value); +end; + +function tmenuitems.itemindexbyname(const name: ansistring): integer; +var + int1: integer; + po1: pmenuitem; +begin + result:= -1; + po1:= pointer(fitems); + for int1:= 0 to high(fitems) do begin + if (po1^.fname = name) or + (po1^.finfo.action <> nil) and (po1^.finfo.action.Name = name) then begin + result:= int1; + break; + end; + inc(po1); + end; +end; + +function tmenuitems.itembyname(const name: ansistring): tmenuitem; +var + int1: integer; +begin + int1:= itemindexbyname(name); + if int1 < 0 then begin + result:= nil; + end + else begin + result:= tmenuitem(fitems[int1]); + end; +end; + +function comparemenuitem(const l,r): integer; +begin + result:= msecomparetext(tmenuitem(l).finfo.caption1.text, + tmenuitem(r).finfo.caption1.text); +end; + +procedure tmenuitems.sort; +begin + sortarray(pointerarty(fitems),@comparemenuitem); + dochange(-1); +end; + +function tmenuitems.hasvisibleitem: boolean; +var + int1: integer; +begin + result:= false; + for int1:= 0 to count - 1 do begin + if not (as_invisible in tmenuitem(fitems[int1]).finfo.state) then begin + result:= true; + break; + end; + end; +end; + +{ tpopupmenu } + +class function tpopupmenu.classskininfo: skininfoty; +begin + result:= inherited classskininfo; + result.objectkind:= sok_popupmenu; +end; + +function tpopupmenu.show(const atransientfor: twidget; + const pos: graphicdirectionty): tmenuitem; +begin + settransientfor(atransientfor); + try + doupdate; + result:= showpopupmenu(fmenu,ftransientfor,pos,self); + checkexec; + finally + settransientfor(nil); + end; +end; + +function tpopupmenu.show(const atransientfor: twidget; + var mouseinfo: mouseeventinfoty): tmenuitem; +begin + settransientfor(atransientfor); + fmouseinfopo:= @mouseinfo; + try + doupdate; + result:= showpopupmenu(fmenu,ftransientfor,mouseinfo.pos,self); + include(mouseinfo.eventstate,es_processed); + checkexec; + finally + settransientfor(nil); + fmouseinfopo:= nil; + end; +end; + +function tpopupmenu.show(const atransientfor: twidget; + const pos: pointty): tmenuitem; +begin + settransientfor(atransientfor); + try + doupdate; + result:= showpopupmenu(fmenu,ftransientfor,pos,self); + checkexec; + finally + settransientfor(nil); + end; +end; + +class function tpopupmenu.additems(var amenu: tpopupmenu; + const atransientfor: twidget; + var mouseinfo: mouseeventinfoty; + const captions: array of msestring; + //if index > count -> index:= count + const aoptions: array of menuactionoptionsty; + const states: array of actionstatesty; + const onexecutes: array of notifyeventty; + const aseparator: boolean = true; + const optionalseparator: boolean = true): integer; +begin + if amenu = nil then begin + amenu:= tpopupmenu.createtransient(atransientfor,@mouseinfo); + end; + if aseparator{ and amenu.menu.hasvisibleitem} then begin + amenu.menu.submenu.insertseparator(bigint,optionalseparator); + end; + result:= amenu.menu.submenu.insert(bigint,captions,aoptions,states,onexecutes); +end; + +class function tpopupmenu.additems(var amenu: tpopupmenu; const atransientfor: twidget; + var mouseinfo: mouseeventinfoty; const items: tmenuitems; + const aseparator: boolean = true; + const first: boolean = false; + const optionalseparator: boolean = true): integer; +begin + if amenu = nil then begin + amenu:= tpopupmenu.createtransient(atransientfor,@mouseinfo); + end; + result:= -1; //compiler warning + if items <> nil then begin +// aseparator:= aseparator and items.hasvisibleitem and +// amenu.menu.hasvisibleitem; + if first then begin + result:= amenu.menu.submenu.insert(0,items); + if aseparator then begin + amenu.menu.submenu.insertseparator(items.count,optionalseparator); + end; + end + else begin + if aseparator then begin + amenu.menu.submenu.insertseparator(bigint,optionalseparator); + end; + result:= amenu.menu.submenu.insert(bigint,items); + end; + end; +end; + +class function tpopupmenu.additems(var amenu: tpopupmenu; + const atransientfor: twidget; var mouseinfo: mouseeventinfoty; + const items: tcustommenu): integer; +var + bo1: boolean; + widget1: twidget; + items1: tmenuitems; +begin + items.fmouseinfopo:= @mouseinfo; + widget1:= items.ftransientfor; + items.settransientfor(atransientfor); + try + items.doupdate; + finally + items.settransientfor(widget1); + end; + bo1:= (amenu = nil) or amenu.ftransient; + items1:= nil; + if items.fmenu.visible then begin + items1:= items.fmenu.fsubmenu; + end; + result:= additems(amenu,atransientfor,mouseinfo,items1, + not (mo_noseparator in items.foptions),mo_insertfirst in items.foptions, + not (mo_forceseparator in items.foptions)); + if bo1 then begin + amenu.fmenu.enabled:= items.fmenu.enabled; + amenu.foptions:= items.foptions; + amenu.assigntemplate(items); + amenu.fmenu.ffont:= items.fmenu.ffont; + amenu.fmenu.ffontactive:= items.fmenu.ffontactive; + amenu.fmenu.color:= items.fmenu.color; + amenu.fmenu.coloractive:= items.fmenu.coloractive; + end; +end; + +{ tcustommainmenu } + +constructor tcustommainmenu.create(aowner: tcomponent); +begin + inherited; + include(foptions,mo_updateonidle); + if not (csdesigning in componentstate) then begin + application.registeronidle({$ifdef FPC}@{$endif}doidle); + end; + fmenu.onchange:= {$ifdef FPC}@{$endif}menuchanged; +end; + +destructor tcustommainmenu.destroy; +begin + inherited; +end; + +procedure tcustommainmenu.setpopupframetemplate(const avalue: tframecomp); +begin + if avalue <> fpopuptemplate.frame then begin + setlinkedvar(avalue,tmsecomponent(fpopuptemplate.frame)); + end; +end; + +procedure tcustommainmenu.setpopupfacetemplate(const avalue: tfacecomp); +begin + if avalue <> fpopuptemplate.face then begin + setlinkedvar(avalue,tmsecomponent(fpopuptemplate.face)); + end; +end; + +procedure tcustommainmenu.setpopupitemframetemplate(const avalue: tframecomp); +begin + if avalue <> fpopuptemplate.itemframe then begin + setlinkedvar(avalue,tmsecomponent(fpopuptemplate.itemframe)); + end; +end; + +procedure tcustommainmenu.setpopupitemfacetemplate(const avalue: tfacecomp); +begin + if avalue <> fpopuptemplate.itemface then begin + setlinkedvar(avalue,tmsecomponent(fpopuptemplate.itemface)); + end; +end; + +procedure tcustommainmenu.setpopupitemframetemplateactive( + const avalue: tframecomp); +begin + if avalue <> fpopuptemplate.itemframeactive then begin + setlinkedvar(avalue,tmsecomponent(fpopuptemplate.itemframeactive)); + end; +end; + +procedure tcustommainmenu.setpopupitemfacetemplateactive( + const avalue: tfacecomp); +begin + if avalue <> fpopuptemplate.itemfaceactive then begin + setlinkedvar(avalue,tmsecomponent(fpopuptemplate.itemfaceactive)); + end; +end; + +procedure tcustommainmenu.setpopupseparatorframetemplate( + const avalue: tframecomp); +begin + if avalue <> fpopuptemplate.separatorframe then begin + setlinkedvar(avalue,tmsecomponent(fpopuptemplate.separatorframe)); + end; +end; + +procedure tcustommainmenu.setpopupcheckboxframetemplate( + const avalue: tframecomp); +begin + if avalue <> fpopuptemplate.checkboxframe then begin + setlinkedvar(avalue,tmsecomponent(fpopuptemplate.checkboxframe)); + end; +end; + +class function tcustommainmenu.classskininfo: skininfoty; +begin + result:= inherited classskininfo; + result.objectkind:= sok_mainmenu; +end; + +procedure tcustommainmenu.menuchanged(const sender: tmenuitem); +begin + if (fobjectlinker <> nil) and not (csloading in componentstate) then begin + fobjectlinker.sendevent(oe_changed); + end; +end; + +function tcustommainmenu.gettemplatefont(const sender: tmenuitem): tmenufont; +begin + if (sender.fparentmenu <> nil) and (sender.fparentmenu <> fmenu) then begin + //in popup + result:= nil; + if popupitemframetemplate <> nil then begin +{$warnings off} + result:= tmenufont(popupitemframetemplate.template.font); +{$warnings on} + end; +(* + if result = nil then begin +{$warnings off} + result:= tmenufont(pointer(stockobjects.fonts[stf_menu])); +{$warnings on} + end; +*) + end + else begin + result:= inherited gettemplatefont(sender); + end; +end; + +function tcustommainmenu.gettemplatefontactive( + const sender: tmenuitem): tmenufontactive; +begin + if sender.fparentmenu <> fmenu then begin //in popup + result:= nil; + if popupitemframetemplateactive <> nil then begin + result:= tmenufontactive(pointer(popupitemframetemplateactive.template.font)); + end; + end + else begin + result:= inherited gettemplatefontactive(sender); + end; +end; + +procedure tcustommainmenu.objectevent(const sender: tobject; + const event: objecteventty); +begin + templateevent(sender,event,fpopuptemplate); + inherited; +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/msenogui.pas b/mseide-msegui/lib/common/kernel/msenogui.pas new file mode 100644 index 0000000..f4e8561 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msenogui.pas @@ -0,0 +1,219 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msenogui; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + sysutils,classes,mclasses,mseapplication,mseevent,msesystypes, + msetypes,msestrings; +type + tnoguiapplication = class(tcustomapplication) + private + feventsem: semty; + fmodallevel: integer; + protected + procedure dopostevent(const aevent: tmseevent); override; + procedure doeventloop(const once: boolean); override; + function nextevent: tmseevent; + procedure dobeforerun; override; + procedure doafterrun; override; + procedure internalinitialize; override; + procedure internaldeinitialize; override; + procedure sethighrestimer(const avalue: boolean); override; + function getevents: integer; override; + //application must be locked + //returns count of queued events + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure destroymodules(); + function modallevel: integer; override; + procedure showexception(e: exception; const leadingtext: msestring = ''); + override; + procedure errormessage(const amessage: msestring); override; + procedure settimer(const us: integer); override; + end; + +function application: tnoguiapplication; + +implementation +uses + msesysutils,msesysintf1,msetimer,msenoguiintf,msethread; +var + appinst: tnoguiapplication; + +function application: tnoguiapplication; +begin + if appinst = nil then begin + tnoguiapplication.create(nil); +// appinst.initialize; + end; + result:= appinst; +end; + +{ tnoguiapplication } + +constructor tnoguiapplication.create(aowner: tcomponent); +begin + fmodallevel:= -1; + appinst:= self; + sys_semcreate(feventsem,0); + inherited; +end; + +destructor tnoguiapplication.destroy; +begin + destroymodules(); + inherited; +// deinitialize; + sys_semdestroy(feventsem); +end; + +procedure tnoguiapplication.dopostevent(const aevent: tmseevent); +begin + eventlist.add(aevent); + sys_sempost(feventsem); +end; + +procedure tnoguiapplication.showexception(e: exception; + const leadingtext: msestring = ''); +begin + writestderr('EXCEPTION: '); + writestderr(ansistring(leadingtext)+e.message,true); +end; + +procedure tnoguiapplication.errormessage(const amessage: msestring); +begin + writestderr('ERROR: '); + writestderr(ansistring(amessage),true); +end; + +procedure tnoguiapplication.settimer(const us: integer); +begin + if us <= 0 then begin + inherited; + end + else begin + nogui_settimer(us); + end; +end; + +procedure tnoguiapplication.doeventloop(const once: boolean); +var + event1: tmseevent; + bo1: boolean; +begin +// lock; +// try + inc(fmodallevel); + while not terminated do begin + if eventlist.count = 0 then begin + try + doidle; + except + handleexception(self); + end; + if once then begin + break; + end; + end; + event1:= nextevent; + try + bo1:= false; + fonapplicationeventlist.doevent(event1,bo1); + if not bo1 then begin + case event1.kind of + ek_timer: begin + tick(self); + end; + ek_terminate: begin + terminated:= true; + end; + ek_asyncexec: begin + texecuteevent(event1).deliver; + end; + else begin + if event1 is tobjectevent then begin + with tobjectevent(event1) do begin + deliver; + end; + end; + end; + end; + end; + except + handleexception(self); + end; + event1.free1; //do not destroy synchronizeevent + end; + dec(fmodallevel); +// finally +// unlock; +// end; +end; + +function tnoguiapplication.nextevent: tmseevent; +begin + nogui_waitevent; +// sys_semwait(feventsem,0); + result:= tmseevent(eventlist.getfirst); +end; + +procedure tnoguiapplication.dobeforerun; +begin + if running then begin + raise exception.create('Already running.'); + end; +end; + +procedure tnoguiapplication.internalinitialize; +begin + nogui_init(@feventsem); + msetimer.init; +end; + +procedure tnoguiapplication.internaldeinitialize; +begin + msetimer.deinit; + nogui_deinit; +end; + +procedure tnoguiapplication.destroymodules(); +begin + while componentcount > 0 do begin + components[componentcount-1].free; //destroy loaded modules + end; +end; + +procedure tnoguiapplication.doafterrun; +begin + if not (apo_noautodestroymodules in foptions) then begin + destroymodules(); + end; +end; + +function tnoguiapplication.modallevel: integer; +begin + result:= fmodallevel; +end; + +procedure tnoguiapplication.sethighrestimer(const avalue: boolean); +begin + //dummy +end; + +function tnoguiapplication.getevents: integer; +begin + result:= eventlist.count; +end; + +initialization + registerapplicationclass(tnoguiapplication); +end. diff --git a/mseide-msegui/lib/common/kernel/msenoguiintf.inc b/mseide-msegui/lib/common/kernel/msenoguiintf.inc new file mode 100644 index 0000000..88fdcb3 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msenoguiintf.inc @@ -0,0 +1,4 @@ +procedure nogui_init(const asempo: psemty); +procedure nogui_deinit; +procedure nogui_waitevent; +procedure nogui_settimer(us: longword); diff --git a/mseide-msegui/lib/common/kernel/mseobjecttext.pas b/mseide-msegui/lib/common/kernel/mseobjecttext.pas new file mode 100644 index 0000000..2028307 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseobjecttext.pas @@ -0,0 +1,1646 @@ +{ + This file is part of the Free Component Library (FCL) + Copyright (c) 1999-2000 by Michael Van Canneyt and Florian Klaempfl + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Modified 2010-2013 by Martin Schreiber +} +unit mseobjecttext; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses; + +procedure objectbinarytotextmse(input, output: tstream); +procedure objecttexttobinarymse(input, output: tstream); + +implementation +uses + sysutils,rtlconsts,msestrings,msetypes,msereal,msefloattostr; +{$ifdef FPC} {$define CLASSESINLINE} {$endif} +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{$ifndef FPC} +type + unicodestring = widestring; +resourcestring + SerrInvalidPropertyType = 'Invalid property type from streamed property: %d'; + SParExpected = 'Wrong token type: %s expected'; + SParInvalidFloat = 'Invalid floating point number: %s'; + SParInvalidInteger = 'Invalid integer number: %s'; + SParUnterminatedString = 'Unterminated string'; + SParWrongTokenType = 'Wrong token type: %s expected but %s found'; + SParWrongTokenSymbol = 'Wrong token symbol: %s expected but %s found'; + SParLocInfo = ' (at %d,%d, stream offset %.8x)'; + SParUnterminatedBinValue = 'Unterminated byte value'; +{$endif} + +const + toemptyfloat = Char(6); + ParseBufSize = 4096; + LastSpecialToken = 6; + + TokNames : array[0..LastSpecialToken] of string = + ( + 'EOF', + 'Symbol', + 'String', + 'Integer', + 'Float', + 'WideString', + 'EmptyFloat' + ); + +type +{ TParser } + + TParser = class(TObject) + private + fStream : TStream; + fBuf : pchar; + fBufLen : integer; + fPos : integer; + fDeltaPos : integer; + fFloatType : char; + fSourceLine : integer; + fToken : char; + fEofReached : boolean; + fLastTokenStr : string; + fLastTokenWStr : unicodestring; + function GetTokenName(aTok : char) : string; + procedure LoadBuffer; + procedure CheckLoadBuffer; {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE} + procedure ProcessChar; {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE} + function IsNumber : boolean; {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE} + function IsHexNum : boolean; {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE} + function IsAlpha : boolean; {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE} + function IsAlphaNum : boolean; {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE} + function GetHexValue(c : char) : byte; {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE} + function GetAlphaNum : string; + procedure HandleNewLine; + procedure SkipBOM; + procedure SkipSpaces; + procedure SkipWhitespace; + procedure HandleEof; + procedure HandleAlphaNum; + procedure HandleNumber; + procedure HandleHexNumber; + function HandleQuotedString : string; + procedure HandleDecimalCharacter(var ascii : boolean; + out WideChr: widechar; out StringChr: char); + procedure HandleString; + procedure HandleMinus; + procedure HandleUnknown; + public + constructor Create(Stream: TStream); + destructor Destroy; override; + procedure CheckToken(T: Char); + procedure CheckTokenSymbol(const S: string); + procedure Error(const Ident: string); + procedure ErrorFmt(const Ident: string; const Args: array of const); + procedure ErrorStr(const Message: string); + procedure HexToBinary(Stream: TStream); + function NextToken: Char; + function SourcePos: Longint; + function TokenComponentIdent: string; +{$ifndef FPUNONE} + function TokenFloat: Extended; +{$endif} + function TokenInt: Int64; + function TokenString: string; + function TokenWideString: unicodestring; + function TokenSymbolIs(const S: string): Boolean; + property FloatType: Char read fFloatType; + property SourceLine: Integer read fSourceLine; + property Token: Char read fToken; + end; + +{ Object conversion routines } + +type + TObjectTextEncoding = ( + oteDFM, + oteLFM + ); + CharToOrdFuncty = Function(var charpo: Pointer): Cardinal; + +function CharToOrd(var P: Pointer): Cardinal; +begin + result:= ord(pchar(P)^); + inc(pchar(P)); +end; + +function WideCharToOrd(var P: Pointer): Cardinal; +begin + result:= ord(pwidechar(P)^); + inc(pwidechar(P)); +end; + +function Utf8ToOrd(var P:Pointer): Cardinal; +begin + // Should also check for illegal utf8 combinations + Result := Ord(PChar(P)^); + Inc(pbyte(P)); + if (Result and $80) <> 0 then + if (Ord(Result) and $e0) = $c0 then begin + Result := ((Result and $1f) shl 6) + or (ord(PChar(P)^) and $3f); + Inc(pbyte(P)); + end else if (Ord(Result) and $f0) = $e0 then begin + Result := ((Result and $1f) shl 12) + or ((ord(PChar(P)^) and $3f) shl 6) + or (ord((PChar(P)+1)^) and $3f); + Inc(pbyte(P),2); + end else begin + Result := ((ord(Result) and $1f) shl 18) + or ((ord(PChar(P)^) and $3f) shl 12) + or ((ord((PChar(P)+1)^) and $3f) shl 6) + or (ord((PChar(P)+2)^) and $3f); + Inc(pbyte(P),3); + end; +end; + +procedure ObjectBinaryToText1(Input, Output: TStream; + Encoding: TObjectTextEncoding); + + procedure OutStr(const s: String); + begin + if s <> '' then + Output.Write(pointer(s)^, Length(s)); + end; + + procedure OutLn(const s: String); + begin + OutStr(s + LineEnd); + end; + + procedure Outchars(P, LastP : Pointer; CharToOrdFunc: CharToOrdFuncty; + UseBytes: boolean = false); + + var + res, NewStr: String; + w: Cardinal; + InString, NewInString: Boolean; + begin + if p = nil then begin + res:= ''''''; + end + else + begin + res := ''; + InString := False; + while ptruint(P) < ptruint(LastP) do + begin + NewInString := InString; + w := CharToOrdfunc(P); + if w = ord('''') then + begin //quote char + if not InString then + NewInString := True; + NewStr := ''''''; + end + else if (Ord(w) >= 32) and ((Ord(w) < 127) or (UseBytes and (Ord(w)<256))) then + begin //printable ascii or bytes + if not InString then + NewInString := True; + NewStr := char(w); + end + else + begin //ascii control chars, non ascii + if InString then + NewInString := False; + NewStr := '#' + IntToStr(w); + end; + if NewInString <> InString then + begin + NewStr := '''' + NewStr; + InString := NewInString; + end; + res := res + NewStr; + end; + if InString then + res := res + ''''; + end; + OutStr(res); + end; + + procedure OutString(const s: String); + begin + OutChars(Pointer(S),PChar(S)+Length(S),@CharToOrd,Encoding=oteLFM); + end; + + procedure OutWString(const W: WideString); + begin + OutChars(Pointer(W),pwidechar(W)+Length(W),@WideCharToOrd); + end; + + procedure OutUString(const W: UnicodeString); + begin + OutChars(Pointer(W),pwidechar(W)+Length(W),@WideCharToOrd); + end; + + procedure OutUtf8Str(const s: String); + begin + if Encoding=oteLFM then + OutChars(Pointer(S),PChar(S)+Length(S),@CharToOrd) + else + OutChars(Pointer(S),PChar(S)+Length(S),@Utf8ToOrd); + end; + +{$ifndef FPC} + function readbyte: byte; + begin + input.readbuffer(result,sizeof(result)); + end; +{$endif} + + function ReadWord : word; {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} + begin + {$ifdef FPC} + Result:=Input.ReadWord; + Result:=LEtoN(Result); + {$else} + input.ReadBuffer(result,sizeof(result)); + {$endif} + end; + + function ReadDWord : longword; {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} + begin + {$ifdef FPC} + Result:=Input.ReadDWord; + Result:=LEtoN(Result); + {$else} + input.ReadBuffer(result,sizeof(result)); + {$endif} + end; + + function ReadQWord : qword; {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} + begin + {$ifdef FPC} + Input.ReadBuffer(Result,sizeof(Result)); + Result:=LEtoN(Result); + {$else} + input.ReadBuffer(result,sizeof(result)); + {$endif} + end; +(* +{$ifndef FPUNONE} + {$IFNDEF FPC_HAS_TYPE_EXTENDED} + function ExtendedToDouble(e : pointer) : double; + var mant : qword; + exp : smallint; + sign : boolean; + d : qword; + begin + {$ifdef FPC} + move(pbyte(e)[0],mant,8); //mantissa : bytes 0..7 + move(pbyte(e)[8],exp,2); //exponent and sign: bytes 8..9 + mant:=LEtoN(mant); + exp:=LetoN(word(exp)); + sign:=(exp and $8000)<>0; + if sign then exp:=exp and $7FFF; + case exp of + 0 : mant:=0; //if denormalized, value is too small for double, + //so it's always zero + $7FFF : exp:=2047 //either infinity or NaN + else + begin + dec(exp,16383-1023); + if (exp>=-51) and (exp<=0) then //can be denormalized + begin + mant:=mant shr (-exp); + exp:=0; + end + else + if (exp<-51) or (exp>2046) then //exponent too large. + begin + Result:=0; + exit; + end + else //normalized value + mant:=mant shl 1; //hide most significant bit + end; + end; + d:=word(exp); + d:=d shl 52; + + mant:=mant shr 12; + d:=d or mant; + if sign then d:=d or $8000000000000000; + Result:=pdouble(@d)^; + {$else} + result:= extended(e^); + {$endif} + end; + {$ENDIF} +{$endif} +*) + function ReadInt(ValueType: TValueType): Int64; overload; + begin + result:= 0; + case ValueType of + vaInt8: Result := ShortInt({$ifdef FPC}Input.{$endif}ReadByte); + vaInt16: Result := SmallInt(ReadWord); + vaInt32: Result := LongInt(ReadDWord); + vaInt64: Result := Int64(ReadQWord); + end; + end; + + function ReadInt: Int64; overload; + begin + Result := ReadInt(TValueType({$ifdef FPC}Input.{$endif}ReadByte)); + end; + +{$ifndef FPUNONE} + function ReadExtended : extended; + {$IFNDEF FPC_HAS_TYPE_EXTENDED} + var ext : array[0..9] of byte; + {$ENDIF} + begin + {$IFNDEF FPC_HAS_TYPE_EXTENDED} + Input.ReadBuffer(ext[0],10); + Result:=ExtendedToDouble(@(ext[0])); + {$ELSE} + Input.ReadBuffer(Result,sizeof(Result)); + {$ENDIF} + end; +{$endif} + + function ReadSStr: String; + var + len: Byte; + begin + len := {$ifdef FPC}Input.{$endif}ReadByte; + SetLength(Result, len); + if (len > 0) then + Input.ReadBuffer(Result[1], len); + end; + + function ReadLStr: String; + var + len: DWord; + begin + len := ReadDWord; + SetLength(Result, len); + if (len > 0) then + Input.ReadBuffer(Result[1], len); + end; + + function ReadWStr: WideString; + var + len: DWord; + {$IFDEF ENDIAN_BIG} + i : integer; + {$ENDIF} + begin + len := ReadDWord; + SetLength(Result, len); + if (len > 0) then + begin + Input.ReadBuffer(Pointer(@Result[1])^, len*2); + {$IFDEF ENDIAN_BIG} + for i:=1 to len do + Result[i]:=widechar(SwapEndian(word(Result[i]))); + {$ENDIF} + end; + end; + + function ReadUStr: UnicodeString; + var + len: DWord; + {$IFDEF ENDIAN_BIG} + i : integer; + {$ENDIF} + begin + len := ReadDWord; + SetLength(Result, len); + if (len > 0) then + begin + Input.ReadBuffer(Pointer(@Result[1])^, len*2); + {$IFDEF ENDIAN_BIG} + for i:=1 to len do + Result[i]:=widechar(SwapEndian(word(Result[i]))); + {$ENDIF} + end; + end; + + procedure processstring(const valuetype: tvaluetype); + begin + case valuetype of + vastring: begin + outstring(readsstr); + end; + valstring: begin + outstring(readlstr); + end; + vautf8string: begin + oututf8str(readlstr); + end; + vawstring: begin + outwstring(readwstr); + end; + vaustring: begin + outustring(readustr); + end; + end; + end; //processstring + + procedure ReadPropList(indent: String); + + procedure ProcessValue(ValueType: TValueType; Indent: String); + + procedure ProcessBinary; + var + ToDo, DoNow, i: LongInt; + lbuf: array[0..31] of Byte; + s: String; + begin + ToDo := ReadDWord; + OutLn('{'); + while ToDo > 0 do begin + DoNow := ToDo; + if DoNow > 32 then DoNow := 32; + Dec(ToDo, DoNow); + s := Indent + ' '; + Input.ReadBuffer(lbuf, DoNow); + for i := 0 to DoNow - 1 do + s := s + IntToHex(lbuf[i], 2); + OutLn(s); + end; + OutLn(indent + '}'); + end; + + var + s: String; +{ len: LongInt; } + IsFirst: Boolean; +{$ifndef FPUNONE} + ext: Extended; +{$endif} + + begin + case ValueType of + vaList: begin + OutStr('('); + IsFirst := True; + while True do begin + ValueType := TValueType({$ifdef FPC}Input.{$endif}ReadByte); + if ValueType = vaNull then break; + if IsFirst then begin + OutLn(''); + IsFirst := False; + end; + OutStr(Indent + ' '); + ProcessValue(ValueType, Indent + ' '); + end; + OutLn(Indent + ')'); + end; + vaInt8: OutLn(IntToStr(ShortInt({$ifdef FPC}Input.{$endif}ReadByte))); + vaInt16: OutLn( IntToStr(SmallInt(ReadWord))); + vaInt32: OutLn(IntToStr(LongInt(ReadDWord))); + vaInt64: OutLn(IntToStr(Int64(ReadQWord))); +{$ifndef FPUNONE} + vaExtended: begin + ext:=ReadExtended; + if ext = emptyreal then begin + s:= '-Inf'; + end + else begin + s:= ansistring(doubletostring(ext,0,fsm_default,'.')); +// Str(ext,S);// Do not use localized strings. + end; + OutLn(S); + end; +{$endif} + vaString: begin + OutString(ReadSStr); + OutLn(''); + end; + vaIdent: OutLn(ReadSStr); + vaFalse: OutLn('False'); + vaTrue: OutLn('True'); + vaBinary: ProcessBinary; + vaSet: begin + OutStr('['); + IsFirst := True; + while True do begin + s := ReadSStr; + if Length(s) = 0 then break; + if not IsFirst then OutStr(', '); + IsFirst := False; + OutStr(s); + end; + OutLn(']'); + end; + vaLString: + begin + OutString(ReadLStr); + OutLn(''); + end; + vaWString: + begin + OutWString(ReadWStr); + OutLn(''); + end; + {$ifdef FPC} + vaUString: + begin + OutuString(ReaduStr); + OutLn(''); + end; + {$endif} + vaNil: + OutLn('nil'); + vaNull: + OutLn('null'); + vaCollection: begin + OutStr('<'); + while {$ifdef FPC}Input.{$endif}ReadByte <> 0 do begin + OutLn(Indent); + Input.Seek(-1, soFromCurrent); + OutStr(indent + ' item'); + ValueType:= TValueType({$ifdef FPC}Input.{$endif}ReadByte); + case valuetype of + vaInt8,vaInt16,vaInt32: begin + OutStr('[' + IntToStr(ReadInt(ValueType)) + ']'); + valuetype:= tvaluetype({$ifdef fpc}input.{$endif}readbyte); + end; + vaident: begin + outstr('['+readsstr+']'); + valuetype:= tvaluetype({$ifdef fpc}input.{$endif}readbyte); + end; + end; + if valuetype <> valist then begin + raise ereaderror.createfmt(serrinvalidpropertytype, + [ord(valuetype)]); + end; + OutLn(''); + ReadPropList(indent + ' '); + OutStr(indent + ' end'); + end; + OutLn('>'); + end; + {vaSingle: begin OutLn('!!Single!!'); exit end; + vaCurrency: begin OutLn('!!Currency!!'); exit end; + vaDate: begin OutLn('!!Date!!'); exit end;} + vaUTF8String: begin + OutUtf8Str(ReadLStr); + OutLn(''); + end; + else + Raise EReadError.CreateFmt(SErrInvalidPropertyType,[Ord(ValueType)]); + end; + end; + + begin + while {$ifdef FPC}Input.{$endif}ReadByte <> 0 do begin + Input.Seek(-1, soFromCurrent); + OutStr(indent + ReadSStr + ' = '); + ProcessValue(TValueType({$ifdef FPC}Input.{$endif}ReadByte), Indent); + end; + end; + + procedure ReadObject(indent: String); + var + b: Byte; + ObjClassName, ObjName: String; + ChildPos: LongInt; + begin + childpos:= 0; + // Check for FilerFlags + b := {$ifdef FPC}Input.{$endif}ReadByte; + if (b and $f0) = $f0 then begin + if (b and 2) <> 0 then ChildPos := ReadInt; + end else begin + b := 0; + Input.Seek(-1, soFromCurrent); + end; + + ObjClassName := ReadSStr; + ObjName := ReadSStr; + + OutStr(Indent); + if (b and 1) <> 0 then OutStr('inherited') + else + if (b and 4) <> 0 then OutStr('inline') + else OutStr('object'); + OutStr(' '); + if ObjName <> '' then + OutStr(ObjName + ': '); + OutStr(ObjClassName); + if (b and 2) <> 0 then OutStr('[' + IntToStr(ChildPos) + ']'); + OutLn(''); + + ReadPropList(indent + ' '); + + while {$ifdef FPC}Input.{$endif}ReadByte <> 0 do begin + Input.Seek(-1, soFromCurrent); + ReadObject(indent + ' '); + end; + OutLn(indent + 'end'); + end; + +type + PLongWord = ^LongWord; +const + signature: PChar = 'TPF0'; + +begin + if {$ifdef FPC}Input.{$endif}ReadDWord <> PLongWord(Pointer(signature))^ then + raise EReadError.Create('Illegal stream image' {###SInvalidImage}); + ReadObject(''); +end; + +procedure ObjectBinaryToText(Input, Output: TStream); +begin + ObjectBinaryToText1(Input,Output,oteDFM); +end; + +procedure ObjectTextToBinary(Input, Output: TStream); +var + parser: TParser; + + {$ifndef FPC} + procedure Writebyte(b : byte); {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} + begin + output.WriteBuffer(b,sizeof(b)); + end; + {$endif} + + procedure WriteWord(w : word); {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} + begin + {$ifdef FPC} + w:=NtoLE(w); + Output.WriteWord(w); + {$else} + output.WriteBuffer(w,sizeof(w)); + {$endif} + end; + + procedure WriteDWord(lw : longword); {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} + begin + {$ifdef FPC} + lw:=NtoLE(lw); + Output.WriteDWord(lw); + {$else} + output.WriteBuffer(lw,sizeof(lw)); + {$endif} + end; + + procedure WriteQWord(qw : qword); {$ifdef CLASSESINLINE}inline;{$endif CLASSESINLINE} + begin + {$ifdef FPC} + qw:=NtoLE(qw); + Output.WriteBuffer(qw,sizeof(qword)); + {$else} + output.WriteBuffer(qw,sizeof(qw)); + {$endif} + end; +{$ifndef FPUNONE} +(* + {$IFNDEF FPC_HAS_TYPE_EXTENDED} + procedure DoubleToExtended(d : double; e : pointer); + var mant : qword; + exp : smallint; + sign : boolean; + begin + {$ifdef FPC} + mant:=(qword(d) and $000FFFFFFFFFFFFF) shl 12; + exp :=(qword(d) shr 52) and $7FF; + sign:=(qword(d) and $8000000000000000)<>0; + case exp of + 0 : begin + if mant<>0 then //denormalized value: hidden bit is 0. normalize it + begin + exp:=16383-1022; + while (mant and $8000000000000000)=0 do + begin + dec(exp); + mant:=mant shl 1; + end; + dec(exp); //don't shift, most significant bit is not hidden in extended + end; + end; + 2047 : exp:=$7FFF //either infinity or NaN + else + begin + inc(exp,16383-1023); + mant:=(mant shr 1) or $8000000000000000; //unhide hidden bit + end; + end; + if sign then exp:=exp or $8000; + mant:=NtoLE(mant); + exp:=NtoLE(word(exp)); + move(mant,pbyte(e)[0],8); //mantissa : bytes 0..7 + move(exp,pbyte(e)[8],2); //exponent and sign: bytes 8..9 + {$else} + extended(E^):= d; + {$endif} + end; + {$ENDIF} +*) + procedure WriteExtended(e : extended); + {$IFNDEF FPC_HAS_TYPE_EXTENDED} + var ext : array[0..9] of byte; + {$ENDIF} + begin + {$IFNDEF FPC_HAS_TYPE_EXTENDED} + DoubleToExtended(e,@(ext[0])); + Output.WriteBuffer(ext[0],10); + {$ELSE} + Output.WriteBuffer(e,sizeof(e)); + {$ENDIF} + end; +{$endif} + + procedure WriteString(s: String); + var size : byte; + begin + if length(s)>255 then size:=255 + else size:=length(s); + {$ifdef FPC}Output.{$endif}WriteByte(size); + if Length(s) > 0 then + Output.WriteBuffer(s[1], size); + end; + + procedure WriteLString(Const s: String); + begin + WriteDWord(Length(s)); + if Length(s) > 0 then + Output.WriteBuffer(s[1], Length(s)); + end; + + procedure WriteWString(Const s: unicodestring); + var len : longword; + {$IFDEF ENDIAN_BIG} + i : integer; + ws : unicodestring; + {$ENDIF} + begin + len:=Length(s); + WriteDWord(len); + if len > 0 then + begin + {$IFDEF ENDIAN_BIG} + setlength(ws,len); + for i:=1 to len do + ws[i]:=widechar(SwapEndian(word(s[i]))); + Output.WriteBuffer(ws[1], len*sizeof(widechar)); + {$ELSE} + Output.WriteBuffer(s[1], len*sizeof(widechar)); + {$ENDIF} + end; + end; + + procedure WriteInteger(value: Int64); + begin + if (value >= -128) and (value <= 127) then begin + {$ifdef FPC}Output.{$endif}WriteByte(Ord(vaInt8)); + {$ifdef FPC}Output.{$endif}WriteByte(byte(value)); + end else if (value >= -32768) and (value <= 32767) then begin + {$ifdef FPC}Output.{$endif}WriteByte(Ord(vaInt16)); + WriteWord(word(value)); + {$ifdef FPC} + end else if (value >= -2147483648) and (value <= 2147483647) then begin + {$else} + end else if (value+2147483648>=0) and (value-2147483647<=0) then begin + {$endif} + {$ifdef FPC}Output.{$endif}WriteByte(Ord(vaInt32)); + WriteDWord(longword(value)); + end else begin + {$ifdef FPC}Output.{$endif}WriteByte(ord(vaInt64)); + WriteQWord(qword(value)); + end; + end; + + + procedure ProcessWideString(const left : unicodestring); + var ws : unicodestring; + begin + ws:=left+parser.TokenWideString; + while parser.NextToken = '+' do + begin + parser.NextToken; // Get next string fragment + if not (parser.Token in [toString,toWString]) then + parser.CheckToken(toWString); + ws:=ws+parser.TokenWideString; + end; + {$ifdef FPC}Output.{$endif}WriteByte(Ord(vaustring)); + WriteWString(ws); + end; + + procedure processstring; + var + s: string; + begin + s:= parser.TokenString; + while parser.NextToken = '+' do begin + parser.NextToken; // Get next string fragment + case parser.Token of + toString: begin + s:= s + parser.TokenString; + end; + toWString: begin + ProcessWideString(unicodestring(s)); + exit; + end + else begin + parser.CheckToken(toString); + end; + end; + end; + if (length(S)>255) then begin + {$ifdef FPC}Output.{$endif}WriteByte(Ord(vaLString)); + WriteLString(S); + end + else begin + {$ifdef FPC}Output.{$endif}WriteByte(Ord(vaString)); + WriteString(s); + end; + end; + + procedure ProcessProperty; forward; + + procedure ProcessValue; + var +{$ifndef FPUNONE} + flt: Extended; +{$endif} +// s: String; + stream: TMemoryStream; + begin + case parser.Token of + toInteger: + begin + WriteInteger(parser.TokenInt); + parser.NextToken; + end; +{$ifndef FPUNONE} + toFloat: + begin + {$ifdef FPC}Output.{$endif}WriteByte(Ord(vaExtended)); + flt := Parser.TokenFloat; + WriteExtended(flt); + parser.NextToken; + end; + toemptyfloat: + begin + {$ifdef FPC}Output.{$endif}WriteByte(Ord(vaExtended)); + WriteExtended(emptyreal); + parser.NextToken; + end; +{$endif} + toString: + begin + processstring; + end; + toWString: + ProcessWideString(''); + toSymbol: begin + if CompareText(parser.TokenString, 'True') = 0 then begin + {$ifdef FPC}Output.{$endif}WriteByte(Ord(vaTrue)); + end + else begin + if CompareText(parser.TokenString, 'False') = 0 then begin + {$ifdef FPC}Output.{$endif}WriteByte(Ord(vaFalse)); + end + else begin + if CompareText(parser.TokenString, 'nil') = 0 then begin + {$ifdef FPC}Output.{$endif}WriteByte(Ord(vaNil)); + end + else begin +// (* + if CompareText(parser.TokenString, 'null') = 0 then begin + {$ifdef FPC}Output.{$endif}WriteByte(Ord(vaNull)); + end + else begin +// *) + if CompareText(parser.TokenString, 'NegInf') = 0 then begin + //preliminary, will be removed + {$ifdef FPC}Output.{$endif}WriteByte(Ord(vaExtended)); + Writeextended(emptyreal); + end + else begin + {$ifdef FPC}Output.{$endif}WriteByte(Ord(vaIdent)); + WriteString(parser.TokenComponentIdent); + end; +// { + end; +// } + end; + end; + end; + Parser.NextToken; + end; + // Set + '[': + begin + parser.NextToken; + {$ifdef FPC}Output.{$endif}WriteByte(Ord(vaSet)); + if parser.Token <> ']' then + while True do + begin + parser.CheckToken(toSymbol); + WriteString(parser.TokenString); + parser.NextToken; + if parser.Token = ']' then + break; + parser.CheckToken(','); + parser.NextToken; + end; + {$ifdef FPC}Output.{$endif}WriteByte(0); + parser.NextToken; + end; + // List + '(': + begin + parser.NextToken; + {$ifdef FPC}Output.{$endif}WriteByte(Ord(vaList)); + while parser.Token <> ')' do + ProcessValue; + {$ifdef FPC}Output.{$endif}WriteByte(0); + parser.NextToken; + end; + // Collection + '<': + begin + parser.NextToken; + {$ifdef FPC}Output.{$endif}WriteByte(Ord(vaCollection)); + while parser.Token <> '>' do + begin + parser.CheckTokenSymbol('item'); + parser.NextToken; + if parser.token = '[' then begin + parser.nexttoken; + if parser.token = tosymbol then begin //item name + {$ifdef fpc}output.{$endif}writebyte(ord(vaident)); + writestring(parser.tokencomponentident); + end; + parser.nexttoken; + parser.checktoken(']'); + parser.nexttoken; + end; + // ConvertOrder + {$ifdef FPC}Output.{$endif}WriteByte(Ord(vaList)); + while not parser.TokenSymbolIs('end') do + ProcessProperty; + parser.NextToken; // Skip 'end' + {$ifdef FPC}Output.{$endif}WriteByte(0); + end; + {$ifdef FPC}Output.{$endif}WriteByte(0); + parser.NextToken; + end; + // Binary data + '{': + begin + {$ifdef FPC}Output.{$endif}WriteByte(Ord(vaBinary)); + stream := TMemoryStream.Create; + try + parser.HexToBinary(stream); + WriteDWord(stream.Size); + Output.WriteBuffer(Stream.Memory^, stream.Size); + finally + stream.Free; + end; + parser.NextToken; + end; + else + parser.Error(SInvalidProperty); + end; + end; + + procedure ProcessProperty; + var + name: String; + begin + // Get name of property + parser.CheckToken(toSymbol); + name := parser.TokenString; + while True do begin + parser.NextToken; + if parser.Token <> '.' then break; + parser.NextToken; + parser.CheckToken(toSymbol); + name := name + '.' + parser.TokenString; + end; + WriteString(name); + parser.CheckToken('='); + parser.NextToken; + ProcessValue; + end; + + procedure ProcessObject; + var + Flags: Byte; + ObjectName, ObjectType: String; + ChildPos: Integer; + begin + childpos:= 0; + if parser.TokenSymbolIs('OBJECT') then + Flags :=0 { IsInherited := False } + else begin + if parser.TokenSymbolIs('INHERITED') then + Flags := 1 { IsInherited := True; } + else begin + parser.CheckTokenSymbol('INLINE'); + Flags := 4; + end; + end; + parser.NextToken; + parser.CheckToken(toSymbol); + ObjectName := ''; + ObjectType := parser.TokenString; + parser.NextToken; + if parser.Token = ':' then begin + parser.NextToken; + parser.CheckToken(toSymbol); + ObjectName := ObjectType; + ObjectType := parser.TokenString; + parser.NextToken; + if parser.Token = '[' then begin + parser.NextToken; + ChildPos := parser.TokenInt; + parser.NextToken; + parser.CheckToken(']'); + parser.NextToken; + Flags := Flags or 2; + end; + end; + if Flags <> 0 then begin + {$ifdef FPC}Output.{$endif}WriteByte($f0 or Flags); + if (Flags and 2) <> 0 then + WriteInteger(ChildPos); + end; + WriteString(ObjectType); + WriteString(ObjectName); + + // Convert property list + while not (parser.TokenSymbolIs('END') or + parser.TokenSymbolIs('OBJECT') or + parser.TokenSymbolIs('INHERITED') or + parser.TokenSymbolIs('INLINE')) do + ProcessProperty; + {$ifdef FPC}Output.{$endif}WriteByte(0); // Terminate property list + + // Convert child objects + while not parser.TokenSymbolIs('END') do ProcessObject; + parser.NextToken; // Skip end token + {$ifdef FPC}Output.{$endif}WriteByte(0); // Terminate property list + end; + +const + signature: PChar = 'TPF0'; +begin + parser := TParser.Create(Input); + try + Output.WriteBuffer(signature[0], 4); + ProcessObject; + finally + parser.Free; + end; +end; + +procedure objectbinarytotextmse(input, output: tstream); +begin + objectbinarytotext(input,output); +end; +(* +procedure objectbinarytotextmse(input, output: tstream); + //workaround for FPC bug with localized float strings +{$ifdef FPC} +var + ch1: char; +{$endif} +begin + {$ifdef FPC} + ch1:= defaultformatsettings.decimalseparator; + defaultformatsettings.decimalseparator:= '.'; + try + objectbinarytotext(input,output); + finally + defaultformatsettings.decimalseparator:= ch1; + end; + {$else} + objectbinarytotext(input,output); + {$endif} +end; +*) +procedure objecttexttobinarymse(input, output: tstream); +begin + objecttexttobinary(input,output); +end; + +{ tparser } + +function TParser.GetTokenName(aTok: char): string; +begin + if ord(aTok) <= LastSpecialToken then + Result:=TokNames[ord(aTok)] + else Result:=aTok; +end; + +procedure TParser.LoadBuffer; +var + BytesRead: integer; +begin + BytesRead := FStream.Read(FBuf^, ParseBufSize); + if BytesRead = 0 then + begin + FEofReached := True; + Exit; + end; + FBuf[BytesRead] := #0; + Inc(FDeltaPos, BytesRead); + FPos := 0; + FBufLen := BytesRead; +end; + +procedure TParser.CheckLoadBuffer; {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE} +begin + if fBuf[fPos]=#0 then LoadBuffer; +end; + +procedure TParser.ProcessChar; {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE} +begin + fLastTokenStr:=fLastTokenStr+fBuf[fPos]; + inc(fPos); + CheckLoadBuffer; +end; + +function TParser.IsNumber: boolean; {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE} +begin + Result:=fBuf[fPos] in ['0'..'9']; +end; + +function TParser.IsHexNum: boolean; {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE} +begin + Result:=fBuf[fPos] in ['0'..'9','A'..'F','a'..'f']; +end; + +function TParser.IsAlpha: boolean; {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE} +begin + Result:=fBuf[fPos] in ['_','A'..'Z','a'..'z']; +end; + +function TParser.IsAlphaNum: boolean; {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE} +begin + Result:=IsAlpha or IsNumber; +end; + +function TParser.GetHexValue(c: char): byte; {$ifdef CLASSESINLINE} inline; {$endif CLASSESINLINE} +begin + result:= 0; + case c of + '0'..'9' : Result:=ord(c)-$30; + 'A'..'F' : Result:=ord(c)-$37; //-$41+$0A + 'a'..'f' : Result:=ord(c)-$57; //-$61+$0A + end; +end; + +function TParser.GetAlphaNum: string; +begin + if not IsAlpha then + ErrorFmt(SParExpected,[GetTokenName(toSymbol)]); + Result:=''; + while IsAlphaNum do + begin + Result:=Result+fBuf[fPos]; + inc(fPos); + CheckLoadBuffer; + end; +end; + +procedure TParser.HandleNewLine; +begin + if fBuf[fPos]=#13 then //CR + begin + inc(fPos); + CheckLoadBuffer; + if fBuf[fPos]=#10 then inc(fPos); //CR LF + end + else inc(fPos); //LF + inc(fSourceLine); + fDeltaPos:=-(fPos-1); +end; + +procedure TParser.SkipBOM; +var + i : integer; + bom : string[3]; + backup : integer; +begin + i:=1; + bom:=' '; + backup:=fPos; + while (fBuf[fPos] in [#$BB,#$BF,#$EF]) and (i<=3) do + begin + bom[i]:=fBuf[fPos]; + inc(fPos); + inc(i); + end; + if (bom<>(#$EF+#$BB+#$BF)) then + fPos:=backup; +end; + +procedure TParser.SkipSpaces; +begin + while fBuf[fPos] in [' ',#9] do + inc(fPos); +end; + +procedure TParser.SkipWhitespace; +begin + while true do + begin + CheckLoadBuffer; + case fBuf[fPos] of + ' ',#9 : SkipSpaces; + #10,#13 : HandleNewLine + else break; + end; + end; +end; + +procedure TParser.HandleEof; +begin + fToken:=toEOF; + fLastTokenStr:=''; +end; + +procedure TParser.HandleAlphaNum; +begin + fLastTokenStr:=GetAlphaNum; + fToken:=toSymbol; +end; + +procedure TParser.HandleNumber; +type + floatPunct = (fpDot,fpE); + floatPuncts = set of floatPunct; +var + allowed : floatPuncts; +begin + fLastTokenStr:=''; + while IsNumber do + ProcessChar; + fToken:=toInteger; + if (fBuf[fPos] in ['.','e','E']) then + begin + fToken:=toFloat; + allowed:=[fpDot,fpE]; + while (fBuf[fPos] in ['.','e','E','0'..'9']) do + begin + case fBuf[fPos] of + '.' : if fpDot in allowed then Exclude(allowed,fpDot) else break; + 'E','e' : if fpE in allowed then + begin + allowed:=[]; + ProcessChar; + if (fBuf[fPos] in ['+','-']) then ProcessChar; + if not (fBuf[fPos] in ['0'..'9']) then + ErrorFmt(SParInvalidFloat,[fLastTokenStr+fBuf[fPos]]); + end + else break; + end; + ProcessChar; + end; + end; + if (fBuf[fPos] in ['s','S','d','D','c','C']) then //single, date, currency + begin + fFloatType:=fBuf[fPos]; + inc(fPos); + fToken:=toFloat; + end + else fFloatType:=#0; +end; + +procedure TParser.HandleHexNumber; +var valid : boolean; +begin + fLastTokenStr:='$'; + inc(fPos); + CheckLoadBuffer; + valid:=false; + while IsHexNum do + begin + valid:=true; + ProcessChar; + end; + if not valid then + ErrorFmt(SParInvalidInteger,[fLastTokenStr]); + fToken:=toInteger; +end; + +function TParser.HandleQuotedString: string; +begin + Result:=''; + inc(fPos); + CheckLoadBuffer; + while true do + begin + case fBuf[fPos] of + #0 : ErrorStr(SParUnterminatedString); + #13,#10 : ErrorStr(SParUnterminatedString); + '''' : begin + inc(fPos); + CheckLoadBuffer; + if fBuf[fPos]<>'''' then exit; + end; + end; + Result:=Result+fBuf[fPos]; + inc(fPos); + CheckLoadBuffer; + end; +end; + +procedure TParser.HandleDecimalCharacter(var ascii: boolean; out + WideChr: widechar; out StringChr: char); +var i : integer; +begin + inc(fPos); + CheckLoadBuffer; + // read a word number + i:=0; + while IsNumber and (ihigh(word) then i:=0; + if i>127 then ascii:=false; + WideChr:=widechar(word(i)); + if i<256 then + StringChr:=chr(i) + else + StringChr:=#0; +end; + +procedure TParser.HandleString; +var ascii : boolean; + s: string; + w: WideChar; + c: char; +begin + fLastTokenWStr:=''; + fLastTokenStr:=''; + ascii:=true; + while true do + begin + case fBuf[fPos] of + '''' : + begin + // avoid conversions, + // On some systems conversion from ansistring to widestring and back + // to ansistring does not give the original ansistring. + // See bug http://bugs.freepascal.org/view.php?id=15841 + s:=HandleQuotedString; + fLastTokenWStr:=fLastTokenWStr+unicodestring(s); + fLastTokenStr:=fLastTokenStr+s; + end; + '#' : + begin + HandleDecimalCharacter(ascii,w,c); + fLastTokenWStr:=fLastTokenWStr+w; + fLastTokenStr:=fLastTokenStr+c; + end; + else break; + end; + end; + if ascii then + fToken:=Classes.toString + else + fToken:=toWString; +end; + +procedure TParser.HandleMinus; +var + str1: string; +begin + inc(fPos); + CheckLoadBuffer; + if IsNumber then begin + HandleNumber; + fLastTokenStr:='-'+fLastTokenStr; + end + else begin + if isalpha then begin + str1:= getalphanum; + ftoken:= toemptyfloat; + flasttokenstr:= '-'+str1; + if stringicompupper(str1,'INF') <> 0 then begin + ErrorFmt(SParInvalidFloat,[fLastTokenStr+fBuf[fPos]]); + end; + end + else begin + fToken:='-'; + fLastTokenStr:=fToken; + end; + end; +end; + +procedure TParser.HandleUnknown; +begin + fToken:=fBuf[fPos]; + fLastTokenStr:=fToken; + inc(fPos); +end; + +constructor TParser.Create(Stream: TStream); +begin + fStream:=Stream; + GetMem(fbuf,ParseBufSize+1); + fBufLen:=0; + fPos:=0; + fDeltaPos:=1; + fSourceLine:=1; + fEofReached:=false; + fLastTokenStr:=''; + fLastTokenWStr:=''; + fFloatType:=#0; + fToken:=#0; + LoadBuffer; + SkipBom; + NextToken; +end; + +destructor TParser.Destroy; +begin + fStream.Position:=SourcePos; + FreeMem(fBuf); +end; + +procedure TParser.CheckToken(T: Char); +begin + if fToken<>T then + ErrorFmt(SParWrongTokenType,[GetTokenName(T),GetTokenName(fToken)]); +end; + +procedure TParser.CheckTokenSymbol(const S: string); +begin + CheckToken(toSymbol); + if CompareText(fLastTokenStr,S)<>0 then + ErrorFmt(SParWrongTokenSymbol,[s,fLastTokenStr]); +end; + +procedure TParser.Error(const Ident: string); +begin + ErrorStr(Ident); +end; + +procedure TParser.ErrorFmt(const Ident: string; const Args: array of const); +begin + ErrorStr(Format(Ident,Args)); +end; + +procedure TParser.ErrorStr(const Message: string); +begin + raise EParserError.CreateFmt(Message+SParLocInfo,[SourceLine,fPos+fDeltaPos,SourcePos]); +end; + +procedure TParser.HexToBinary(Stream: TStream); +var outbuf : array[0..ParseBufSize-1] of byte; + b : byte; + i : integer; +begin + i:=0; + SkipWhitespace; + while IsHexNum do + begin + b:=(GetHexValue(fBuf[fPos]) shl 4); + inc(fPos); + CheckLoadBuffer; + if not IsHexNum then + Error(SParUnterminatedBinValue); + b:=b or GetHexValue(fBuf[fPos]); + inc(fPos); + outbuf[i]:=b; + inc(i); + if i>=ParseBufSize then + begin + Stream.WriteBuffer(outbuf[0],i); + i:=0; + end; + SkipWhitespace; + end; + if i>0 then + Stream.WriteBuffer(outbuf[0],i); + NextToken; +end; + +function TParser.NextToken: Char; + +begin + SkipWhiteSpace; + if fEofReached then + HandleEof + else + case fBuf[fPos] of + '_','A'..'Z','a'..'z' : HandleAlphaNum; + '$' : HandleHexNumber; + '-' : HandleMinus; + '0'..'9' : HandleNumber; + '''','#' : HandleString + else + HandleUnknown; + end; + Result:=fToken; +end; + +function TParser.SourcePos: Longint; +begin + Result:=fStream.Position-fBufLen+fPos; +end; + +function TParser.TokenComponentIdent: string; +begin + if fToken<>toSymbol then + ErrorFmt(SParExpected,[GetTokenName(toSymbol)]); + CheckLoadBuffer; + while fBuf[fPos]='.' do + begin + ProcessChar; + fLastTokenStr:=fLastTokenStr+GetAlphaNum; + end; + Result:=fLastTokenStr; +end; + +{$ifndef FPUNONE} +Function TParser.TokenFloat: Extended; + +var +{$ifdef FPC} + errcode : word; +{$else} + errcode: integer; +{$endif} + +begin + Val(fLastTokenStr,Result,errcode); + if errcode<>0 then + ErrorFmt(SParInvalidFloat,[fLastTokenStr]); +end; +{$endif} + +Function TParser.TokenInt: Int64; +begin + if not TryStrToInt64(fLastTokenStr,Result) then begin + {$ifdef FPC} + if not tryStrToQWord(fLastTokenStr,qword(result)) then begin + //second chance for malformed files + ErrorFmt(SParInvalidInteger,[fLastTokenStr]); + end; + {$else} + ErrorFmt(SParInvalidInteger,[fLastTokenStr]); + {$endif} + end; +end; + +function TParser.TokenString: string; +begin + case fToken of + toWString : Result:= ansistring(fLastTokenWStr); + toFloat : if fFloatType<>#0 then + Result:=fLastTokenStr+fFloatType + else Result:=fLastTokenStr + else + Result:=fLastTokenStr; + end; +end; + +function TParser.TokenWideString: unicodestring; +begin + if fToken=toWString then + Result:=fLastTokenWStr + else + Result:= unicodestring(fLastTokenStr); +end; + +function TParser.TokenSymbolIs(const S: string): Boolean; +begin + Result:=(fToken=toSymbol) and (CompareText(fLastTokenStr,S)=0); +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/msepipestream.pas b/mseide-msegui/lib/common/kernel/msepipestream.pas new file mode 100644 index 0000000..7c47711 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msepipestream.pas @@ -0,0 +1,953 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msepipestream; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifndef FPC}{$ifdef linux} {$define UNIX} {$endif}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + msestream,msethread,msesystypes,classes,mclasses,msebits,mseclasses, + msetypes; + +type + + pr_piperesultty = (pr_empty,pr_data,pr_line); + + tpipewriter = class(ttextstream) + private + fconnected: boolean; + function gethandle: integer; + protected + procedure sethandle(value: integer); override; + function dowrite(const buffer; count: longint): longint; virtual; + public + constructor create; reintroduce; +// destructor destroy; override; +{$ifdef FPC} + function Write(const Buffer; Count: Longint): Longint; override; overload; +{$endif} + procedure connect(const ahandle: integer); //does not own handle +// function releasehandle: filehandlety; virtual; + property handle: integer read gethandle write sethandle; //owns handle + end; + + tpipereader = class; + + pipereadereventty = procedure(const sender: tpipereader) of object; + + //todo: no thread.kill, single thread for all pipreaders + bufferty = array[0..defaultbuflen-1] of char; + + pipereaderoptionty = (pro_nolock); + pipereaderoptionsty = set of pipereaderoptionty; + + tpipereader = class(tpipewriter) + private + fpipebuffer: string; + fdatastatus: pr_piperesultty; + foninputavailable: pipereadereventty; + fonpipebroken: pipereadereventty; + finputcond: condty; + fwritehandle: integer; + foverloadsleepus: integer; + foptions: pipereaderoptionsty; + function checkdata: pr_piperesultty; + procedure clearpipebuffer; + function getresponseflag: boolean; + procedure setresponseflag(const Value: boolean); + procedure setwritehandle(const Value: integer); + protected + fthread: tsemthread; //simulate nonblocking pipes on windows + fmsbuf: bufferty; + fmsbufcount: integer; + fowner: tmsecomponent; + function execthread(thread: tmsethread): integer; virtual; + procedure sethandle(value: integer); override; + procedure setbuflen(const Value: integer); override; + function doread(var buf; const acount: integer; out readcount: integer; + const nonblocked: boolean = false): boolean; virtual; + //true of no error + function readbytes(var buf): integer; override; + procedure doinputavailable; + procedure dochange; virtual; + function readbuf: string; + public + constructor create; + destructor destroy; override; + + function releasehandle: filehandlety override; + function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override; + //no seek, result always 0 + function readdatastring: string; override; + procedure appenddatastring(var adata: string; var acount: sizeint); + + function readbuffer: string; //does not try to get additional data + function readuln(var value: string): boolean; + function readuln(var value: string; out hasmoredata: boolean): boolean; + //bringt auch unvollstaendige zeilen, false wenn unvollstaendig + //no decoding + function readstrln(var value: string): boolean; override; + //bringt nur vollstaendige zeilen, sonst false + //no decoding + procedure clear; override; + procedure terminate(const noclosehandle: boolean = false); + procedure terminateandwait(const noclosehandle: boolean = false); + procedure waitfor; + function waitforresponse(timeoutusec: integer = 0; + resetflag: boolean = true): boolean; + //false if timeout or error + function active: boolean; //true if handle set and not eof or error + property responseflag: boolean read getresponseflag write setresponseflag; + property text: string read fpipebuffer; + property writehandle: integer read fwritehandle write setwritehandle; + property overloadsleepus: integer read foverloadsleepus + write foverloadsleepus default -1; + //checks application.checkoverload before calling oninputavaliable + //if >= 0 + property options: pipereaderoptionsty read foptions + write foptions default []; + property oninputavailable: pipereadereventty read foninputavailable + write foninputavailable; + property onpipebroken: pipereadereventty read fonpipebroken + write fonpipebroken; + property owner: tmsecomponent read fowner; +end; + + tpipereadercomp = class(tmsecomponent) + private + fpipereader: tpipereader; + function getoninputavailable: pipereadereventty; + function getonpipebroken: pipereadereventty; + procedure setoninputavailable(const Value: pipereadereventty); + procedure setonpipebroken(const Value: pipereadereventty); + function getoverloadsleepus: integer; + procedure setoverloadsleepus(const avalue: integer); + function getopions: pipereaderoptionsty; + procedure setoptions(const avalue: pipereaderoptionsty); + function getencoding: charencodingty; + procedure setencoding(const avalue: charencodingty); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property pipereader: tpipereader read fpipereader; + published + property options: pipereaderoptionsty read getopions + write setoptions default []; + property encoding: charencodingty read getencoding write setencoding + default ce_locale; + property overloadsleepus: integer read getoverloadsleepus + write setoverloadsleepus default -1; + //checks application.checkoverload before calling oninputavaliable + //if >= 0 + property oninputavailable: pipereadereventty read getoninputavailable write setoninputavailable; + property onpipebroken: pipereadereventty read getonpipebroken write setonpipebroken; + end; + + tpipereaderpers = class(tpersistent) + private + fpipereader: tpipereader; + function getoninputavailable: pipereadereventty; + function getonpipebroken: pipereadereventty; + procedure setoninputavailable(const Value: pipereadereventty); + procedure setonpipebroken(const Value: pipereadereventty); + function getoverloadsleepus: integer; + procedure setoverloadsleepus(const avalue: integer); + function getopions: pipereaderoptionsty; + procedure setoptions(const avalue: pipereaderoptionsty); + function getencoding: charencodingty; + procedure setencoding(const avalue: charencodingty); + public + constructor create(const aowner: tmsecomponent); + destructor destroy; override; + property pipereader: tpipereader read fpipereader; + published + property options: pipereaderoptionsty read getopions + write setoptions default []; + property encoding: charencodingty read getencoding write setencoding + default ce_locale; + property overloadsleepus: integer read getoverloadsleepus + write setoverloadsleepus default -1; + //checks application.checkoverload before calling oninputavaliable + //if >= 0 + property oninputavailable: pipereadereventty read getoninputavailable write setoninputavailable; + property onpipebroken: pipereadereventty read getonpipebroken write setonpipebroken; + end; + + tpipewriterpers = class(tpersistent) + private + fpipewriter: tpipewriter; + function getencoding: charencodingty; + procedure setencoding(const avalue: charencodingty); + public + constructor create(const aowner: tmsecomponent); + destructor destroy; override; + property pipewriter: tpipewriter read fpipewriter; + published + property encoding: charencodingty read getencoding write setencoding + default ce_locale; + end; + +{$ifdef UNIX} +function readfilenonblock(const handle: thandle; var buf; const acount: integer; + const nonblocked: boolean): integer; //-1 on error +{$endif} + +implementation +uses + {$ifdef UNIX}mselibc, {$else}windows, {$endif} + mseapplication,msesysintf1,msesysintf,sysutils,msesysutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{ tpipewriter } + +constructor tpipewriter.create; +begin + inherited create(invalidfilehandle); +end; +{ +destructor tpipewriter.destroy; +begin + sethandle(invalidfilehandle); + inherited; +end; +} +{ +function tpipewriter.releasehandle: filehandlety; +begin + result:= handle; + fhandle:= invalidfilehandle; +end; +} +procedure tpipewriter.connect(const ahandle: integer); +begin + handle:= ahandle; + if ahandle <> invalidfilehandle then begin + fconnected:= true; + end; +end; + +procedure tpipewriter.sethandle(value: integer); +begin + if fconnected then begin + fhandle:= invalidfilehandle; + fconnected:= false; + end; + inherited; + bufoffset:= nil; +end; + +function tpipewriter.dowrite(const buffer; count: longint): longint; +begin + result:= inherited write(buffer,count); +end; + +function tpipewriter.gethandle: integer; +begin + result:= inherited handle; +end; + +{$ifdef FPC} +function tpipewriter.Write(const Buffer; Count: Longint): Longint; +begin + result:= dowrite(buffer,count); +end; +{$endif} + +{ tpipereader } + +constructor tpipereader.create; +begin + sys_condcreate(finputcond); + fwritehandle:= invalidfilehandle; + foverloadsleepus:= -1; + inherited; + include(fstate,tss_notopen); +end; + +destructor tpipereader.destroy; +begin + terminateandwait; + writehandle:= invalidfilehandle; + inherited; + sys_conddestroy(finputcond); +end; + +function tpipereader.releasehandle: filehandlety; +begin + terminateandwait(true); + freeandnil(fthread); + writehandle:= invalidfilehandle; + result:= inherited releasehandle(); +end; + +procedure tpipereader.sethandle(value: integer); +begin + if handle <> invalidfilehandle then begin + terminateandwait; + end; + freeandnil(fthread); + inherited; + if value <> invalidfilehandle then begin + writehandle:= invalidfilehandle; + fstate:= fstate - [tss_notopen,tss_eof,tss_error,tss_pipeactive]; + fmsbufcount:= 0; + fthread:= tsemthread.create({$ifdef FPC}@{$endif}execthread); + end; +end; + +procedure tpipereader.setwritehandle(const Value: integer); +begin + if fwritehandle <> invalidfilehandle then begin + sys_closefile(fwritehandle); + end; + fwritehandle := Value; +end; + +procedure tpipereader.terminate(const noclosehandle: boolean = false); +var + by1: byte; +begin + if fthread <> nil then begin + fthread.terminate; + if fthread.running then begin + fthread.sempost; + if fwritehandle <> invalidfilehandle then begin + by1:= 0; + sys_write(fwritehandle,@by1,1); //wake up thread + end + else begin +// inherited sethandle(invalidfilehandle); + {$ifdef unix} + pthread_kill(fthread.id,sigio); + {$endif} + end; + writehandle:= invalidfilehandle; + end; + end; + if not noclosehandle then begin + inherited sethandle(invalidfilehandle); + end; + include(fstate,tss_notopen); +end; + +procedure tpipereader.terminateandwait(const noclosehandle: boolean = false); +begin + if fthread <> nil then begin + terminate(noclosehandle); + application.waitforthread(fthread); + end; +end; + +procedure tpipereader.waitfor; +begin + if fthread <> nil then begin + application.waitforthread(fthread); + end; +end; + +procedure tpipereader.setbuflen(const Value: integer); +begin + if value < defaultbuflen then begin + inherited setbuflen(defaultbuflen); + end + else begin + inherited; + end; +end; + +{$ifdef UNIX} +function readfilenonblock(const handle: thandle; var buf; const acount: integer; + const nonblocked: boolean): integer; //-1 on error +begin + if nonblocked then begin + setfilenonblock(handle,true); + end; + result:= sys_read(handle,@buf,acount); + if nonblocked then begin + if (result < 0) and (sys_getlasterror = EAGAIN) then begin + result:= 0; + end; + setfilenonblock(handle,false); + end; +end; +{$endif} + +function tpipereader.doread(var buf; const acount: integer; + out readcount: integer; + const nonblocked: boolean = false): boolean; +begin +{$ifdef mswindows} + readcount:= sys_read(Handle,@buf,acount); + if readcount < 0 then begin + result:= false; + end; +// result:= fileRead(Handle,buf,acount) +{$else} + readcount:= readfilenonblock(handle,buf,acount, + nonblocked and not (tss_unblocked in fstate)); +{$endif} + result:= readcount >= 0; + if not result then begin + readcount:= 0; + end; +end; + +function tpipereader.execthread(thread: tmsethread): integer; +var + int1: integer; + {$ifdef unix} + info: pollfd; + {$endif} +begin + fthread:= tsemthread(thread); + {$ifdef unix} + info.fd:= handle; + info.events:= pollin; + {$endif} + with fthread do begin + while not terminated and not (tss_error in fstate) do begin + {$ifdef unix} + if (poll(@info,1,-1) > 0) and not terminated then begin + {$else} + if true then begin + {$endif} + int1:= sys_read(Handle,@fmsBuf,sizeof(fmsbuf)); + if not terminated then begin + if {$ifdef mswindows}int1 < 0{$else}(int1 <= 0){$endif} then begin + //on win32 int1 can be 0 + include(fstate,tss_error); //broken pipe + end + else begin + fmsbufcount:= int1; + end; + if (int1 > 0) or (tss_error in fstate) then begin + include(fstate,tss_pipeactive); + doinputavailable; + if not terminated and not (tss_error in fstate) then begin + semwait; + end; + end; + end; + end; + end; + include(fstate,tss_eof); + end; + result:= 0; +end; + +function tpipereader.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; +begin + inherited seek(offset,origin); + result:= 0; +end; + +procedure tpipereader.doinputavailable; +var + needslock: boolean; +begin + if (tss_haslink in fstate) or + assigned(foninputavailable) or assigned(fonpipebroken) then begin + if foverloadsleepus >= 0 then begin + while not fthread.terminated and application.checkoverload(-1) do begin + sleepus(foverloadsleepus); + end; + end; + needslock:= not (pro_nolock in foptions) and not fthread.terminated; + if needslock then begin + application.lock; + end; + try + if not fthread.terminated then begin + if assigned(foninputavailable) then begin + foninputavailable(self); + end; + if eof and assigned(fonpipebroken) then begin + fonpipebroken(self); + end; + dochange; + end; + finally + if needslock then begin + application.unlock; + end; + end; + end; + sys_condlock(finputcond); + include(fstate,tss_response); + sys_condbroadcast(finputcond); + sys_condunlock(finputcond); +end; + +procedure tpipereader.clearpipebuffer; +begin + fpipebuffer:= ''; + fdatastatus:= pr_empty; +end; + +function tpipereader.readbytes(var buf): integer; + + procedure getmorebytes; +{$ifdef mswindows} + var + int1: integer; +{$endif} + begin + {$ifdef mswindows} + if peeknamedpipe(handle,nil,0,nil,@int1,nil) and (int1 > 0) then begin + if int1 > sizeof(fmsbuf) then begin + int1:= sizeof(fmsbuf); + end; + if not doread(fmsbuf,int1,fmsbufcount) then begin + fstate:= fstate + [tss_error,tss_eof]; + end; + end + else begin + fmsbufcount:= 0; + end; + {$else} + if not doread(fmsbuf,sizeof(fmsbuf),fmsbufcount,true) then begin + fstate:= fstate + [tss_error,tss_eof]; //broken pipe + end; + {$endif} + if fmsbufcount = 0 then begin + exclude(fstate,tss_pipeactive); + fthread.sempost; + end + else begin + include(fstate,tss_pipeactive); + end; + end; + +begin + result:= fmsbufcount; + if result > 0 then begin + move(fmsbuf,buf,fmsbufcount); + getmorebytes; + end + else begin + if sys_getcurrentthread = fthread.id then begin //check again fore more + include(fstate,tss_pipeactive); + if fthread.semcount > 0 then begin + fthread.semwait; //reset semaphore + end; + getmorebytes; + result:= fmsbufcount; + if result > 0 then begin + move(fmsbuf,buf,fmsbufcount); + getmorebytes; + end; + end; + if tss_error in fstate then begin + include(fstate,tss_eof); + end; + end; +end; + +function tpipereader.readbuf: string; +var + int1: integer; +begin + if bufoffset <> nil then begin + int1:= bufend-bufoffset; + setlength(result,int1); + move(bufoffset^,result[1],int1); + bufoffset:= nil; + end + else begin + result:= ''; + end; +end; + +function tpipereader.readbuffer: string; +var + int1: integer; +begin + result:= readbuf; + if fmsbufcount > 0 then begin + int1:= length(result); + setlength(result,int1+fmsbufcount); + move(fmsbuf,result[int1+1],fmsbufcount); + fmsbufcount:= 0; + exclude(fstate,tss_pipeactive); + fthread.sempost; + end; +end; + +function tpipereader.readdatastring: string; +var + int1: integer; + len1: sizeint; +begin + result:= readbuffer; + len1:= length(result); + while true do begin + int1:= readbytes(fbuffer^); + if int1 > 0 then begin + len1:= len1+int1; + if len1 > length(result) then begin + setlength(result,2*len1); + end; + move(fbuffer^,result[len1-int1+1],int1); + end + else begin + break; + end; + end; + setlength(result,len1); +end; + +procedure tpipereader.appenddatastring(var adata: string; var acount: sizeint); +var + len1: sizeint; + i1: int32; +begin + i1:= 0; + if bufoffset <> nil then begin + i1:= bufend - bufoffset; + end; + len1:= acount + i1 + fmsbufcount; + if len1 > length(adata) then begin + setlength(adata,2*len1); + end; + if bufoffset <> nil then begin + move(bufoffset^,(pointer(adata)+acount)^,i1); + bufoffset:= nil; + end; + move(fmsbuf,(pointer(adata)+acount+i1)^,fmsbufcount); + fmsbufcount:= 0; + + repeat + {$ifdef mswindows} + if peeknamedpipe(handle,nil,0,nil,@i1,nil) and (i1 > 0) then begin + if len1+i1 > length(adata) then begin + setlength(adata,2*(len1+i1)); + end; + if not doread((pointer(adata)+len1)^,i1,i1) then begin + fstate:= fstate + [tss_error,tss_eof]; + end; + end + else begin + break; + end; + {$else} + if len1 >= length(adata) then begin + setlength(adata,2*len1+64); + end; + i1:= length(adata) - len1; //fill current buffer + if not doread((pointer(adata)+len1)^,i1,i1,true) then begin + fstate:= fstate + [tss_error,tss_eof]; //broken pipe + end; + if i1 = 0 then begin + break; + end; + {$endif} + len1:= len1 + i1; + until fstate * [tss_error,tss_eof] <> []; + acount:= len1; + exclude(fstate,tss_pipeactive); + fthread.sempost; +end; + +function tpipereader.checkdata: pr_piperesultty; +var + str1: string; + bo1: boolean; +begin + if not (tss_error in fstate) and + ((bufend <> bufoffset) or (tss_pipeactive in fstate) or + (sys_getcurrentthread = fthread.id)) then begin + bo1:= inherited readstrln(str1); + fpipebuffer:= fpipebuffer + str1; + if bo1 then begin + fdatastatus:= pr_line; + end + else begin + if str1 <> '' then begin + fdatastatus:= pr_data; + end; + if not (tss_error in fstate) then begin + exclude(fstate,tss_eof); + end; + bufoffset:= nil; //neu laden + end; + result:= fdatastatus; + end + else begin + result:= pr_empty; + end; +end; + +function tpipereader.readuln(var value: string; + out hasmoredata: boolean): boolean; +begin + value:= ''; + result:= false; +// if (tss_pipeactive in fstate) or (fdatastatus <> pr_empty) then begin + repeat + if fdatastatus = pr_empty then begin + checkdata; + end; + value:= value + fpipebuffer; + result:= fdatastatus = pr_line; + clearpipebuffer; + checkdata; + until result or (fdatastatus = pr_empty); +// end; + hasmoredata:= fdatastatus <> pr_empty; +end; + +function tpipereader.readuln(var value: string): boolean; +var + b1: boolean; +begin + result:= readuln(value,b1); +end; + +function tpipereader.readstrln(var value: string): boolean; +begin + case checkdata of + pr_line: begin + result:= true; + value:= fpipebuffer; + clearpipebuffer; + end; + else begin + result:= false; + value:= ''; + end; + end; +end; + +procedure tpipereader.clear; +begin + clearpipebuffer; + bufoffset:= nil; +end; + +function tpipereader.waitforresponse(timeoutusec: integer = 0; + resetflag: boolean = true): boolean; + //false if timeout or error +begin + sys_condlock(finputcond); + result:= responseflag; + if not result then begin + if not eof then begin + result:= sys_condwait(finputcond,timeoutusec) = sye_ok; + end; + end; + if result and resetflag then begin + responseflag:= false; + end; + sys_condunlock(finputcond); +end; + +function tpipereader.getresponseflag: boolean; +begin + result:= tss_response in fstate; +end; + +procedure tpipereader.setresponseflag(const Value: boolean); +begin + updatebit({$ifdef FPC}longword{$else}byte{$endif}(fstate),ord(tss_response),value); +end; + +function tpipereader.active: boolean; +begin + result:= (handle <> invalidfilehandle) and (fstate * [tss_error,tss_eof] = []); +end; + +procedure tpipereader.dochange; +begin + //dummy +end; + +{ tpipereadercomp } + +constructor tpipereadercomp.create(aowner: tcomponent); +begin + fpipereader:= tpipereader.create; + fpipereader.fowner:= self; + inherited; +end; + +destructor tpipereadercomp.destroy; +begin + fpipereader.free; + inherited; +end; + +function tpipereadercomp.getoninputavailable: pipereadereventty; +begin + result:= fpipereader.foninputavailable; +end; + +function tpipereadercomp.getonpipebroken: pipereadereventty; +begin + result:= fpipereader.fonpipebroken; +end; + +procedure tpipereadercomp.setoninputavailable( + const Value: pipereadereventty); +begin + fpipereader.foninputavailable:= value; +end; + +procedure tpipereadercomp.setonpipebroken(const Value: pipereadereventty); +begin + fpipereader.fonpipebroken:= value; +end; + +function tpipereadercomp.getoverloadsleepus: integer; +begin + result:= fpipereader.overloadsleepus; +end; + +procedure tpipereadercomp.setoverloadsleepus(const avalue: integer); +begin + fpipereader.overloadsleepus:= avalue; +end; + +function tpipereadercomp.getopions: pipereaderoptionsty; +begin + result:= fpipereader.options; +end; + +procedure tpipereadercomp.setoptions(const avalue: pipereaderoptionsty); +begin + fpipereader.options:= avalue; +end; + +function tpipereadercomp.getencoding: charencodingty; +begin + result:= fpipereader.encoding; +end; + +procedure tpipereadercomp.setencoding(const avalue: charencodingty); +begin + fpipereader.encoding:= avalue; +end; + +{ tpipereaderpers } + +constructor tpipereaderpers.create(const aowner: tmsecomponent); +begin + fpipereader:= tpipereader.create; + fpipereader.fowner:= aowner; + inherited create; +end; + +destructor tpipereaderpers.destroy; +begin + fpipereader.free; + inherited; +end; + +function tpipereaderpers.getoninputavailable: pipereadereventty; +begin + result:= fpipereader.foninputavailable; +end; + +function tpipereaderpers.getonpipebroken: pipereadereventty; +begin + result:= fpipereader.fonpipebroken; +end; + +procedure tpipereaderpers.setoninputavailable( + const Value: pipereadereventty); +begin + fpipereader.foninputavailable:= value; +end; + +procedure tpipereaderpers.setonpipebroken(const Value: pipereadereventty); +begin + fpipereader.fonpipebroken:= value; +end; + +function tpipereaderpers.getoverloadsleepus: integer; +begin + result:= fpipereader.overloadsleepus; +end; + +procedure tpipereaderpers.setoverloadsleepus(const avalue: integer); +begin + fpipereader.overloadsleepus:= avalue; +end; + +function tpipereaderpers.getopions: pipereaderoptionsty; +begin + result:= fpipereader.options; +end; + +procedure tpipereaderpers.setoptions(const avalue: pipereaderoptionsty); +begin + fpipereader.options:= avalue; +end; + +function tpipereaderpers.getencoding: charencodingty; +begin + result:= fpipereader.encoding; +end; + +procedure tpipereaderpers.setencoding(const avalue: charencodingty); +begin + fpipereader.encoding:= avalue; +end; + +{ tpipewriterpers } + +constructor tpipewriterpers.create(const aowner: tmsecomponent); +begin + fpipewriter:= tpipewriter.create; + inherited create; +end; + +destructor tpipewriterpers.destroy; +begin + fpipewriter.free; + inherited; +end; + +function tpipewriterpers.getencoding: charencodingty; +begin + result:= fpipewriter.encoding; +end; + +procedure tpipewriterpers.setencoding(const avalue: charencodingty); +begin + fpipewriter.encoding:= avalue; +end; + +{$ifdef UNIX} +var + sigpipebefore: tsignalhandler; +initialization + sigpipebefore:= signal(sigpipe,tsignalhandler(sig_ign)); +finalization + signal(sigpipe,sigpipebefore); +{$endif} + +end. + diff --git a/mseide-msegui/lib/common/kernel/msepointer.pas b/mseide-msegui/lib/common/kernel/msepointer.pas new file mode 100644 index 0000000..4249dd9 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msepointer.pas @@ -0,0 +1,585 @@ +{ MSEgui Copyright (c) 1999-2009 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msepointer; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface +uses + msegraphics,msegraphutils,msetimer,msetypes,mseglob; + +const + defaultcaretblinkperiodetime = 1000000; //us + defaultsizingmargin = 3; +type + + cursorshapety = (cr_default,cr_parent, + cr_none,cr_arrow,cr_cross,cr_wait,cr_ibeam, + cr_sizever,cr_sizehor,cr_sizebdiag,cr_sizefdiag,cr_sizeall, + cr_splitv,cr_splith,cr_pointinghand,cr_forbidden,cr_drag, + cr_topleftcorner,cr_bottomleftcorner, + cr_bottomrightcorner,cr_toprightcorner, + cr_res0,cr_res1,cr_res2,cr_res3,cr_res4,cr_res5,cr_res6,cr_res7, + cr_user); + + sizingkindty = (sik_none,sik_right,sik_topright,sik_top,sik_topleft, + sik_left,sik_bottomleft,sik_bottom,sik_bottomright); +const + sizingcursors: array[sizingkindty] of cursorshapety = + (cr_default,cr_sizehor,cr_toprightcorner,cr_sizever,cr_topleftcorner, + cr_sizehor,cr_bottomleftcorner,cr_sizever,cr_bottomrightcorner); +type + imouse = interface(inullinterface) + function getmousewinid: winidty; + end; + + tmouse = class + private + fshape: cursorshapety; + fwinid: winidty; + fintf: imouse; + procedure setshape(const Value: cursorshapety); + function getpos: pointty; + procedure setpos(const Value: pointty); + public + constructor create(mouseintf: imouse); + procedure move(const dist: pointty); + procedure windowdestroyed(const id: winidty); + property shape: cursorshapety read fshape write setshape; + property pos: pointty read getpos write setpos; + end; + + caretstatety = (cas_active,cas_on,cas_showed); + caretstatesty = set of caretstatety; + + tcaret = class(tnullinterfacedobject{,icaret}) + private + fcanvas: tcanvas; + fcliprect: rectty; + fbounds: rectty; + forigin: pointty; + fstate: caretstatesty; + ftimer: tsimpletimer; + fbackup: tsimplebitmap; + fcaret: tsimplebitmap; + fvisible: integer; + function getheight: integer; + procedure setheight(const Value: integer); + function getpos: pointty; + procedure setpos(const Value: pointty); + function getsize: sizety; + procedure setsize(const Value: sizety); + function getwidth: integer; + procedure setwidth(const Value: integer); + function getx: integer; + procedure setx(const Value: integer); + function gety: integer; + procedure sety(const Value: integer); + function getbounds: rectty; + procedure setbounds(const value: rectty); + function getperiodetime: integer; + procedure setperiodetime(const Value: integer); + procedure updatestate; + procedure restart; + procedure timerevent(const sender: tobject); + function getcliprect: rectty; + procedure setcliprect(const Value: rectty); //no restart of timer + protected + procedure scroll(const dist: pointty; const scrollorigin: boolean); + public + constructor create{(out intf: pointer)}; + destructor destroy; override; + procedure link(canvas: tcanvas; const origin: pointty; + const acliprect: rectty); + function islinkedto(canvas: tcanvas): boolean; + + procedure remove; //recursive + procedure restore; //recursive + procedure hide; //stops timer + procedure show; //restarts timer + procedure move(const dist: pointty); + function active: boolean; + function visible: boolean; + + property origin: pointty read forigin; + property bounds: rectty read getbounds write setbounds; + property cliprect: rectty read getcliprect write setcliprect; + property rootcliprect: rectty read fcliprect; + property x: integer read getx write setx; + property y: integer read gety write sety; + property pos: pointty read getpos write setpos; + property width: integer read getwidth write setwidth; + property height: integer read getheight write setheight; + property size: sizety read getsize write setsize; + property periodetime: integer read getperiodetime write setperiodetime; + end; + +function calcsizingkind(const apos: pointty; const arect: rectty; + const margin: integer = defaultsizingmargin): sizingkindty; +function adjustsizingrect(const arect: rectty; const kind: sizingkindty; + const offset: pointty; const cxmin,cxmax,cymin,cymax: integer): rectty; + +implementation +uses + mseguiintf,msebitmap; + +function calcsizingkind(const apos: pointty; const arect: rectty; + const margin: integer = defaultsizingmargin): sizingkindty; +var + margin2,distright,disttop,distleft,distbottom: integer; +begin + result:= sik_none; + distright:= abs(apos.x - (arect.x+arect.cx)); + disttop:= abs(apos.y - (arect.y)); + distleft:= abs(apos.x - (arect.x)); + distbottom:= abs(apos.y - (arect.y+arect.cy)); + margin2:= 2 * margin; + if disttop < margin then begin + if distleft < margin2 then begin + result:= sik_topleft; + end + else begin + if distright < margin2 then begin + result:= sik_topright; + end + else begin + result:= sik_top; + end; + end; + end + else begin + if distbottom < margin then begin + if distleft < margin2 then begin + result:= sik_bottomleft; + end + else begin + if distright < margin2 then begin + result:= sik_bottomright; + end + else begin + result:= sik_bottom; + end; + end; + end + else begin + if distleft < margin then begin + if disttop < margin2 then begin + result:= sik_topleft; + end + else begin + if distbottom < margin2 then begin + result:= sik_bottomleft; + end + else begin + result:= sik_left; + end; + end + end + else begin + if distright < margin then begin + if disttop < margin2 then begin + result:= sik_topright; + end + else begin + if distbottom < margin2 then begin + result:= sik_bottomright; + end + else begin + result:= sik_right; + end; + end; + end; + end; + end; + end; +end; + +function adjustsizingrect(const arect: rectty; const kind: sizingkindty; + const offset: pointty; const cxmin,cxmax,cymin,cymax: integer): rectty; + procedure adjustright; + begin + result.cx:= result.cx + offset.x; + if (cxmax > 0) and (result.cx > cxmax) then begin + result.cx:= cxmax; + end; + if result.cx < cxmin then begin + result.cx:= cxmin; + end; + end; + procedure adjusttop; + var + int1: integer; + begin + int1:= offset.y; + if (cymax <> 0) and (result.cy - int1 > cymax) then begin + int1:= result.cy - cymax; + end; + if result.cy - int1 < cymin then begin + int1:= result.cy - cymin; + end; + result.y:= result.y + int1; + result.cy:= result.cy - int1; + end; + procedure adjustleft; + var + int1: integer; + begin + int1:= offset.x; + if (cxmax <> 0) and (result.cx - int1 > cxmax) then begin + int1:= result.cx - cxmax; + end; + if result.cx - int1 < cxmin then begin + int1:= result.cx - cxmin; + end; + result.x:= result.x + int1; + result.cx:= result.cx - int1; + end; + procedure adjustbottom; + begin + result.cy:= result.cy + offset.y; + if (cymax > 0) and (result.cy > cymax) then begin + result.cy:= cymax; + end; + if result.cy < cymin then begin + result.cy:= cymin; + end; + end; +begin + result:= arect; + case kind of + sik_right: adjustright; + sik_topright: begin adjusttop; adjustright end; + sik_top: adjusttop; + sik_topleft: begin adjusttop; adjustleft end; + sik_left: adjustleft; + sik_bottomleft: begin adjustbottom; adjustleft end; + sik_bottom: adjustbottom; + sik_bottomright: begin adjustbottom; adjustright end; + end; +end; + +{ tmouse } + +constructor tmouse.create(mouseintf: imouse); +begin + fintf:= mouseintf; +// fwinid:= winidty(-1); +end; + +function tmouse.getpos: pointty; +begin + result:= gui_getpointerpos; +end; + +procedure tmouse.setpos(const Value: pointty); +begin + if not pointisequal(value,getpos) then begin + gui_setpointerpos(value); + end; +end; + +procedure tmouse.move(const dist: pointty); +begin + if (dist.x <> 0) or (dist.y <> 0) then begin + gui_movepointer(dist); + end; +end; + +procedure tmouse.setshape(const Value: cursorshapety); +var + id1: winidty; +begin + id1:= fintf.getmousewinid; + if (fshape <> value) or (id1 <> fwinid) then begin + fwinid:= id1; + fshape := Value; + gui_setcursorshape(id1,value); + end; +end; + +procedure tmouse.windowdestroyed(const id: winidty); +begin + if id = fwinid then begin + fwinid:= winidty(-1); + end; +end; + +{ tcaret } + +constructor tcaret.create{(out intf: pointer)}; +begin +// intf:= pointer(icaret(self)); + ftimer:= tsimpletimer.create(0,{$ifdef FPC}@{$endif}timerevent,false,[]); + fbackup:= tbitmap.create(bmk_rgb); //getcanvasimage possibly used by opengl window + fcaret:= tbitmap.create(bmk_rgb); //getcanvasimage possibly used by opengl window + periodetime:= defaultcaretblinkperiodetime; +end; + +destructor tcaret.destroy; +begin + remove; + ftimer.free; + fbackup.free; + fcaret.free; + inherited; +end; + +function tcaret.getperiodetime: integer; +begin + result:= ftimer.interval * 2; +end; + +procedure tcaret.setperiodetime(const Value: integer); +begin + ftimer.interval:= value div 2; +end; + +function tcaret.getbounds: rectty; +begin + result:= fbounds; + subpoint1(result.pos,forigin); +end; + +procedure tcaret.setbounds(const value: rectty); +begin + if (value.x + forigin.x <> fbounds.x) or (value.y + forigin.y <> fbounds.y) or + (value.cx <> fbounds.cx) or (value.cy <> fbounds.cy) then begin + remove; + if not sizeisequal(fbounds.size,value.size) then begin + fbackup.size:= value.size; + fcaret.size:= value.size; + if not fcaret.isempty then begin + fcaret.init(cl_white); + end; + end; + fbounds:= value; + addpoint1(fbounds.pos,forigin); + restore; + end; +end; + +function tcaret.getpos: pointty; +begin + result:= getbounds.pos; +end; + +procedure tcaret.setpos(const Value: pointty); +var + rect1: rectty; +begin + rect1:= getbounds; + rect1.pos:= value; + setbounds(rect1); +end; + +function tcaret.getx: integer; +begin + result:= getbounds.pos.x; +end; + +procedure tcaret.setx(const Value: integer); +var + rect1: rectty; +begin + rect1:= getbounds; + rect1.pos.x:= value; + setbounds(rect1); +end; + +function tcaret.gety: integer; +begin + result:= getbounds.pos.y; +end; + +procedure tcaret.sety(const Value: integer); +var + rect1: rectty; +begin + rect1:= getbounds; + rect1.pos.y:= value; + setbounds(rect1); +end; + +function tcaret.getsize: sizety; +begin + result:= fbounds.size; +end; + +procedure tcaret.setsize(const Value: sizety); +var + rect1: rectty; +begin + rect1:= getbounds; + rect1.size:= value; + setbounds(rect1); +end; + +function tcaret.getwidth: integer; +begin + result:= fbounds.cx; +end; + +procedure tcaret.setwidth(const Value: integer); +var + rect1: rectty; +begin + rect1:= getbounds; + rect1.cx:= value; + setbounds(rect1); +end; + +function tcaret.getheight: integer; +begin + result:= fbounds.cy; +end; + +procedure tcaret.setheight(const Value: integer); +var + rect1: rectty; +begin + rect1:= getbounds; + rect1.cy:= value; + setbounds(rect1); +end; + +procedure tcaret.updatestate; +begin + if fcanvas <> nil then begin + if (fvisible > 0) and + (([cas_on,cas_active] * fstate = [cas_on,cas_active])) and + not (cas_showed in fstate) then begin + //display caret + if not fcaret.isempty then begin + fcanvas.save; + fcanvas.origin:= nullpoint; + fcanvas.clipregion:= fcanvas.createregion(fcliprect); + fbackup.canvas.copyarea(fcanvas,fbounds,nullpoint); + fcanvas.copyarea(fcaret.canvas,makerect(nullpoint,fbounds.size), + fbounds.pos,rop_xor); + fcanvas.restore; + end; + include(fstate,cas_showed); + end + else begin + if (cas_showed in fstate) then begin + if not fcaret.isempty then begin + //remove caret + fcanvas.save; + fcanvas.origin:= nullpoint; + fcanvas.clipregion:= fcanvas.createregion(fcliprect); + fcanvas.copyarea(fbackup.canvas,makerect(nullpoint, + fbounds.size),fbounds.pos); + fcanvas.restore; + exclude(fstate,cas_showed); + end; + end; + end; + end; +end; + +procedure tcaret.restart; +begin + updatestate; + ftimer.interval:= ftimer.interval; + ftimer.enabled:= true; +end; + +procedure tcaret.timerevent(const sender: tobject); +begin + fstate:= caretstatesty({$ifdef FPC}longword{$else}byte{$endif}(fstate) xor byte(1 shl byte(cas_on))); + updatestate; +end; + +procedure tcaret.remove; +begin + dec(fvisible); + updatestate; +end; + +procedure tcaret.restore; +begin + inc(fvisible); + updatestate; +end; + +procedure tcaret.hide; +begin + fstate:= fstate - [cas_on,cas_active]; + ftimer.enabled:= false; + updatestate; +end; + +procedure tcaret.show; +begin + fstate:= fstate + [cas_on,cas_active]; + restart; +end; + +procedure tcaret.link(canvas: tcanvas; const origin: pointty; + const acliprect: rectty); +begin + hide; + fcanvas:= canvas; + forigin:= origin; + fbounds.pos:= origin; + fcliprect:= moverect(acliprect,origin); + if fcanvas = nil then begin + fstate:= []; + end + else begin + fstate:= [cas_active]; + end; +end; + +function tcaret.getcliprect: rectty; +begin + result:= removerect(fcliprect,forigin); +end; + +procedure tcaret.setcliprect(const Value: rectty); +begin + remove; + fcliprect:= moverect(value,forigin); + restore; +end; + + +function tcaret.islinkedto(canvas: tcanvas): boolean; +begin + result:= (fcanvas <> nil) and (fcanvas = canvas); +end; + +procedure tcaret.scroll(const dist: pointty; const scrollorigin: boolean); +begin + remove; + addpoint1(fbounds.pos,dist); + if scrollorigin then begin + addpoint1(forigin,dist); + addpoint1(fcliprect.pos,dist); + end; + restore; +end; + +procedure tcaret.move(const dist: pointty); +begin + pos:= addpoint(pos,dist); +end; + +function tcaret.active: boolean; +begin + result:= cas_active in fstate; +end; + +function tcaret.visible: boolean; +begin + result:= fvisible > 0; +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/mseprocmonitor.inc b/mseide-msegui/lib/common/kernel/mseprocmonitor.inc new file mode 100644 index 0000000..d073d8e --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseprocmonitor.inc @@ -0,0 +1,22 @@ +{ MSEgui Copyright (c) 2008 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +type + iprocmonitor = interface(inullinterface) + procedure processdied(const aprochandle: prochandlety; + const aexecresult: integer; const adata: pointer); + end; + +function pro_listentoprocess(const aprochandle: prochandlety; + const adest: iprocmonitor; const adata: pointer): boolean; + //false on error, limited to 63 items on windows +procedure pro_unlistentoprocess(const aprochandle: prochandlety; + const adest: iprocmonitor); +procedure pro_killzombie(const aprochandle: prochandlety); + diff --git a/mseide-msegui/lib/common/kernel/msereal.pas b/mseide-msegui/lib/common/kernel/msereal.pas new file mode 100644 index 0000000..c0bd46c --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msereal.pas @@ -0,0 +1,178 @@ +{ MSEgui Copyright (c) 1999-2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msereal; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msetypes{,classes,mclasses},msestrings; + +const + emptyrealstring = ''; //stringsymbol for empty realty + bigreal = 1e38; + +function cmprealty(const a,b: realty): integer; +//function emptyreal: realty; +function isemptyreal(const val: realty): boolean; {$ifdef FPC}inline;{$endif} + deprecated; + //use x = emptyreal instead +function candiv(const val: realty): boolean; //true if not 0.0 or empty: + +function addrealty(const a,b: realty): realty; //result = a - b +function subrealty(const a,b: realty): realty; //result = a + b +function mulrealty(const a,b: realty): realty; //result = a * b + +function applyrange(const avalue: realty; const arange: real; + const astart: real): realty; +function reapplyrange(const avalue: realty; const arange: real; + const astart: real): realty; +function expscale(const value: real; const min: real; const max: real): real; + +implementation +uses + sysutils,{msesys,}sysconst; + +const +{$ifdef FPC_DOUBLE_HILO_SWAPPED} + co1: array[0..7] of byte = (0,0,$f0,$ff,$0,0,0,0); //- inf +{$else} + co1: array[0..7] of byte = ($0,0,0,0,0,0,$f0,$ff); //- inf +{$endif} + +function expscale(const value: real; const min: real; const max: real): real; +var + mi,ma: real; +begin + mi:= ln(min); + ma:= ln(max); + result:= exp(value*(ma-mi)+mi); +end; + +function applyrange(const avalue: realty; const arange: real; + const astart: real): realty; +begin + if (avalue = emptyreal) or (arange = 0) then begin + result:= avalue; + end + else begin + result:= avalue * arange - astart; + end; +end; + +function reapplyrange(const avalue: realty; const arange: real; + const astart: real): realty; +begin + if (avalue = emptyreal) or (arange = 0) then begin + result:= avalue; + end + else begin + result:= (avalue-astart) / arange; + end; +end; + +function addrealty(const a,b: realty): realty; //result = a - b +begin + if a = emptyreal then begin + result:= b; + end + else begin + if b = emptyreal then begin + result:= a; + end + else begin + result:= a + b; + end; + end; +end; + +function subrealty(const a,b: realty): realty; //result = a + b +begin + if a = emptyreal then begin + if b = emptyreal then begin + result:= emptyreal; + end + else begin + result:= -b; + end; + end + else begin + if b = emptyreal then begin + result:= a; + end + else begin + result:= a - b; + end; + end; +end; + +function mulrealty(const a,b: realty): realty; //result = a * b +begin + if not (a = emptyreal) and not (b = emptyreal) then begin + result:= a * b; + end + else begin + result:= emptyreal; + end; +end; + +function isemptyreal(const val: realty): boolean; //true wenn leer +begin + result:= val = emptyreal; +end; + +{ +function emptyreal: realty; +begin + move(co1,result,sizeof(realty)); +// doublepo:= @co1; +// result:= doublepo^; +end; + +function isemptyreal(const val: realty): boolean; //true wenn leer +begin + result:= comparemem(@val,@co1,sizeof(realty)) +end; +} +function candiv(const val: realty): boolean; //true if not 0.0 or empty: +begin + result:= (val <> 0.0) and not comparemem(@val,@co1,sizeof(realty)); +end; + +function cmprealty(const a,b: realty): integer; + //-1 wenn a < b, 0 wenn a = b, 1 wenn a > b +begin + if b = emptyreal then begin + result:= 1; + if a = emptyreal then begin + result:= 0; + end; + end + else begin + if a = emptyreal then begin + result:= -1; + end + else begin + if a > b then begin + result:= 1; + end + else begin + if a < b then begin + result:= -1; + end + else begin + result:= 0; + end; + end; + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/mserichstring.pas b/mseide-msegui/lib/common/kernel/mserichstring.pas new file mode 100644 index 0000000..3c2472e --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mserichstring.pas @@ -0,0 +1,1577 @@ +{ MSEgui Copyright (c) 1999-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mserichstring; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + sysutils,msetypes,msekeyboard,mseevent,msedatalist,msegraphutils, + {classes,}mclasses,msestrings,mseglob,mseinterfaces; + +const + fsboldmask = $01; + fsitalicmask = $02; + fsunderlinemask = $04; + fsstrikeoutmask = $08; + +type + newinfoty = (ni_bold=ord(fs_bold),ni_italic=ord(fs_italic), + ni_underline=ord(fs_underline),ni_strikeout=ord(fs_strikeout), + ni_selected=ord(fs_selected),ni_blank=ord(fs_blank), + //same order as in fontstylety + ni_fontcolor,ni_colorbackground,ni_delete); + newinfosty = set of newinfoty; + +const + fonthandleflags = [ni_bold,ni_italic]; + fontlayoutflags = [ni_bold,ni_italic,ni_blank]; + fontstyleflags = [ni_bold,ni_italic,ni_underline,ni_strikeout,ni_selected, + ni_blank]; + +type + charstylety = record + fontcolor,colorbackground: colorty; //bits inversed, 0 -> not set + fontstyle: fontstylesty; + end; + pcharstylety = ^charstylety; + + charstylearty = array of charstylety; + + formatinfoty = record + index: integer; //0-> from first char + newinfos: newinfosty; + style: charstylety; + end; + + pformatinfoty = ^formatinfoty; + formatinfoarty = array of formatinfoty; + pformatinfoarty = ^formatinfoarty; + + richflagty = (rf_noparagraph); + richflagsty = set of richflagty; + + richstringty = record + text: msestring; + format: formatinfoarty; + flags: richflagsty; + end; + + prichstringty = ^richstringty; + richstringarty = array of richstringty; + + richstringaty = array[0..0] of richstringty; + prichstringaty = ^richstringaty; + + updaterichstringeventty = procedure(const sender: tobject; + var avalue: richstringty) of object; + + irichstringprop = interface(inullinterface)[miid_irichstringprop] + function getrichvalue: richstringty; + procedure setrichvalue(const avalue: richstringty); + end; + + trichstringdatalist = class(tmsestringdatalist) + private + fposition: pointty; + function Getformats(index: integer): formatinfoarty; + procedure Setformats(index: integer; const Value: formatinfoarty); + procedure setnoparagraphs(index: integer; const avalue: boolean); + function getrichitems(index: integer): richstringty; + procedure setrichitems(index: integer; const Value: richstringty); + function getrichitemspo(index: integer): prichstringty; + procedure setasarray(const data: richstringarty); + function getasarray: richstringarty; + procedure setasmsestringarray(const data: msestringarty); + function getasmsestringarray: msestringarty; + protected + function getnoparagraphs(index: integer): boolean; override; + procedure freedata(var data); override; //gibt daten frei + procedure aftercopy(var data); override; + function compare(const l,r): integer; override; + procedure setstatdata(const index: integer; const value: msestring); override; + function getstatdata(const index: integer): msestring; override; + public + constructor create; override; + procedure insert(const index: integer; const item: msestring); override; + function add(const value: msestring): integer; override; + function add(const avalue: msestring; + const anoparagraph: boolean): integer; override; + function nextword(out value: lmsestringty): boolean; + //true bei new line + function getformatpo(index: integer): pformatinfoarty; + function getparagraph(const index: integer; + const aseparator: msestring = ''): msestring; + + property formats[index: integer]: formatinfoarty read Getformats write Setformats; + property noparagraphs[index : integer]: boolean read getnoparagraphs + write setnoparagraphs; + property richitems[index: integer]: richstringty read getrichitems write setrichitems; + property richitemspo[index: integer]: prichstringty read getrichitemspo; + property position: pointty read fposition write fposition; + //x = 0 fuer zeilenbeginn + property asarray: richstringarty read getasarray write setasarray; + property asmsestringarray: msestringarty read getasmsestringarray + write setasmsestringarray; + end; + + tcharstyledatalist = class(tdatalist) + private + function Getitems(index: integer): charstylety; + procedure Setitems(index: integer; const Value: charstylety); + public + constructor create; override; + procedure clear; override; + function add(const value: charstylety): integer; overload; + function add(style: fontstylesty = []; fontcolor: pcolorty = nil; + colorbackground: pcolorty = nil): integer; overload; + function add(const value: string): integer; overload; + //'bius' fontcolor colorbackground + property items[index: integer]: charstylety read Getitems write Setitems; + default; + end; + +const + emptyrichstring: richstringty = (text: ''; format: nil; flags: []); + richlineend: richstringty = (text: lineend; format: nil; flags: []); + +function charstyletocolor(const color: colorty): colorty; +function colortocharstyle(const color: colorty): colorty; + +function setfontcolor1(var formats: formatinfoarty; aindex: integer; + len: halfinteger; color: colorty): boolean; + //true if changed +function setfontcolor(const formats: formatinfoarty; aindex: integer; + len: halfinteger; color: colorty): formatinfoarty; +function setcolorbackground1(var formats: formatinfoarty; aindex: integer; + len: halfinteger; + color: colorty): boolean; + //true if changed +function setcolorbackground(const formats: formatinfoarty; aindex: integer; + len: halfinteger; + color: colorty): formatinfoarty; + +function updatefontstyle1(var formats: formatinfoarty; aindex: integer; + len: halfinteger; + astyle: fontstylety; aset: boolean): boolean; + //true if changed +function updatefontstyle(const formats: formatinfoarty; aindex: integer; + len: halfinteger; + astyle: fontstylety; aset: boolean): formatinfoarty; +function updatefontstyle1(var formats: formatinfoarty; aindex: integer; + len: halfinteger; + astyles: fontstylesty; aset: boolean): boolean; + //true if changed +function updatefontstyle(const formats: formatinfoarty; aindex: integer; + len: halfinteger; + astyles: fontstylesty; aset: boolean): formatinfoarty; + +function setcharstyle1(var formats: formatinfoarty; aindex,len: halfinteger; + const style: charstylety): boolean; + //true if changed +function setcharstyle(const formats: formatinfoarty; aindex,len: halfinteger; + const style: charstylety): formatinfoarty; +function getcharstyle(const formats: formatinfoarty; + const aindex: integer): charstylety; //zero based +function getfontstyle(const formats: formatinfoarty; + const aindex: integer): fontstylesty; //zero based + +procedure setselected1(var text: richstringty; start,len: halfinteger); +function setselected(const text: richstringty; + start,len: halfinteger): richstringty; + +function isequalrichstring(const a,b: richstringty): boolean; +function isemptyrichstring(const value: richstringty): boolean; +function isequalformat(const a,b: formatinfoarty): boolean; +function isequalformatinfo(const a,b: formatinfoty): boolean; + +procedure richdelete(var value: richstringty; aindex,count: integer); +procedure richinsert(const source: msestring; var value: richstringty; + aindex: integer); +function richcopy(const source: richstringty; index, count: halfinteger): richstringty; +function richconcat(const a,b: richstringty): richstringty; overload; +function richconcat(const a: richstringty; const b: msestring; + const fontstyle: fontstylesty = []; + const fontcolor: colorty = cl_none; + const colorbackground: colorty = cl_none): richstringty; overload; +function richconcat(const a: msestring; const b: richstringty; + const fontstyle: fontstylesty = []; + const fontcolor: colorty = cl_none; + const colorbackground: colorty = cl_none): richstringty; overload; +procedure richconcat1(var dest: richstringty; const b: richstringty); overload; +procedure richconcat1(var dest: richstringty; const b: msestring; + const fontstyle: fontstylesty = []; + const fontcolor: colorty = cl_none; + const colorbackground: colorty = cl_none); overload; + + +procedure additem(const value: richstringty; var dest: richstringarty; + var count: integer; step: integer = 32); overload; +function splitrichstring(const avalue: richstringty; const separator: msechar): richstringarty; +function breakrichlines(const source: richstringty): richstringarty; + +procedure captiontorichstring(const caption: captionty; var dest: richstringty); +//procedure captiontorichstring(const caption: captionty; out result: richstringty); +function richstringtocaption(const caption: richstringty): captionty; +function isshortcut(key: keyty; const caption: msestring): boolean; overload; +function isshortcut(key: msechar; const caption: msestring): boolean; overload; +//function checkshortcut(var info: keyeventinfoty; +// const caption: richstringty; const checkalt: boolean): boolean; overload; + //moved to msegui +//function checkshortcut(var info: keyeventinfoty; +// const key: keyty; const shiftstate: shiftstatesty): boolean; overload; + +function expandtabs(const s: richstringty; const tabcharcount: integer): richstringty; + +procedure writerichstring(const writer: twriter; const value: richstringty); +function readrichstring(const reader: treader): richstringty; + +{$ifdef FPC} +function richformatinfotostring(const aformat: formatinfoty): ansistring; +{$endif} + +var + hotkeyfontstylesadd: fontstylesty; //default [fs_underline] + hotkeyfontstylesremove: fontstylesty; //default [] + hotkeycolor: colorty; //default cl_none + hotkeycolorbackground: colorty; //default cl_none + +implementation +uses + typinfo,msearrayutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tpoorstringdatalist1 = class(tpoorstringdatalist); + +{$ifdef FPC} +function richformatinfotostring(const aformat: formatinfoty): ansistring; +begin + with aformat do begin + result:= inttostr(index)+' '+settostring(ptypeinfo(typeinfo(newinfosty)), + integer(newinfos),true)+ + ' ' + settostring(ptypeinfo(typeinfo(fontstylesty)), + integer(style.fontstyle),true); + end; +end; +{$endif} + +procedure writerichstring(const writer: twriter; const value: richstringty); +var + i1: int32; +begin + if value.format = nil then begin + writer.writeunicodestring(value.text); + end + else begin + writer.writelistbegin(); + writer.writeunicodestring(value.text); + writer.writelistbegin(); + for i1:= 0 to high(value.format) do begin + writer.writelistbegin(); + with value.format[i1] do begin + writer.writeinteger(index); + writer.writeset(card32(newinfos),typeinfo(newinfos)); + writer.writeinteger(int32(style.fontcolor)); + writer.writeinteger(int32(style.colorbackground)); + writer.writeset(card32(style.fontstyle),typeinfo(style.fontstyle)); + end; + writer.writelistend(); + end; + writer.writelistend(); + writer.writelistend(); + end; +end; + +function readrichstring(const reader: treader): richstringty; +var + i1: int32; +begin + if not reader.beginoflist then begin + result.format:= nil; + result.text:= reader.readunicodestring(); + end + else begin + reader.readlistbegin(); + result.text:= reader.readunicodestring(); + reader.readlistbegin(); + result.format:= nil; + i1:= 0; + while reader.beginoflist() do begin + reader.readlistbegin(); + msearrayutils.additem(result.format,typeinfo(result.format),i1); + with result.format[i1-1] do begin + index:= reader.readinteger(); + newinfos:= newinfosty(reader.readset(typeinfo(newinfos))); + style.fontcolor:= reader.readinteger(); + style.colorbackground:= reader.readinteger(); + style.fontstyle:= fontstylesty(reader.readset(typeinfo(style.fontstyle))); + end; + reader.readlistend(); + end; + setlength(result.format,i1); + reader.readlistend(); + reader.readlistend(); + end; +end; + +function splitrichstring(const avalue: richstringty; const separator: msechar): richstringarty; +var + int1: integer; + ar1: integerarty; +begin + ar1:= getcharpos(avalue.text,separator); + setlength(result,high(ar1)+2); + if ar1 = nil then begin + result[0].text:= avalue.text; + result[0].format:= copy(avalue.format); + end + else begin + result[0]:= richcopy(avalue,1,ar1[0]-1); + for int1:= 0 to high(ar1) - 1 do begin + result[int1+1]:= richcopy(avalue,ar1[int1]+1,ar1[int1+1]-ar1[int1]-1); + end; + result[high(result)]:= richcopy(avalue,ar1[high(ar1)]+1,bigint); + end; +end; + +function breakrichlines(const source: richstringty): richstringarty; +var + int1,int2: integer; +begin + result:= splitrichstring(source,c_linefeed); + for int1:= 0 to high(result) do begin + int2:= length(result[int1].text); + if (int2 > 0) and (result[int1].text[int2] = c_return) then begin + setlength(result[int1].text,int2-1); + end; + end; +end; + +procedure captiontorichstring(const caption: captionty; var dest: richstringty); +var + int1: integer; + ch1: msechar; + po1: pmsechar; + + procedure sethotstyle(); + begin + with dest do begin + updatefontstyle1(format,po1-pmsechar(pointer(text)),1, + hotkeyfontstylesadd,true); + updatefontstyle1(format,po1-pmsechar(pointer(text)),1, + hotkeyfontstylesremove,false); + if hotkeycolor <> cl_none then begin + setfontcolor1(format,po1-pmsechar(pointer(text)),1,hotkeycolor); + end; + if hotkeycolorbackground <> cl_none then begin + setcolorbackground1(format,po1-pmsechar(pointer(text)),1, + hotkeycolorbackground); + end; + end; + end;//sethotstyle + +begin + with dest do begin + setlength(text,length(caption)); //max + format:= nil; + po1:= pointer(text); + int1:= 1; + while int1 <= length(caption) do begin + ch1:= caption[int1]; + if (ch1 = '&') {and (format = nil)} then begin + if caption[int1+1] = '&' then begin + po1^:= ch1; + inc(int1); + if caption[int1+1] = '&' then begin //there is a trailing #0 + sethotstyle(); + inc(int1); + end; + inc(po1); + end + else begin + sethotstyle(); + end; + end + else begin + po1^:= ch1; + inc(po1); + end; + inc(int1); + end; + setlength(text,po1-pmsechar(pointer(text))); + end; +end; + +function richstringtocaption(const caption: richstringty): captionty; + function checkhotkey(const astyle: charstylety): boolean; + begin + result:= (astyle.fontstyle * hotkeyfontstylesadd = hotkeyfontstylesadd) and + (astyle.fontstyle * hotkeyfontstylesremove = []) and + ((hotkeycolor = cl_none) or (astyle.fontcolor = hotkeycolor)) and + ((hotkeycolorbackground = cl_none) or + (astyle.colorbackground = hotkeycolorbackground)); + ; + end;//checkhotkey + +var + int1: integer; + po1: pmsechar; + ch1: msechar; +begin + with caption do begin + setlength(result,length(text)*2+1); + po1:= pmsechar(pointer(result)); + for int1:= 1 to length(text) do begin +// if fs_underline in getfontstyle(format,int1-1) then begin + if checkhotkey(getcharstyle(format,int1-1)) then begin + po1^:= '&'; + inc(po1); + end; + ch1:= text[int1]; + po1^:= ch1; + inc(po1); + if (ch1 = '&') then begin + po1^:= ch1; + inc(po1); + end; + end; + if checkhotkey(getcharstyle(format,length(text))) then begin + po1^:= '&'; + inc(po1); + end; + end; + setlength(result,po1-pmsechar(pointer(result))); +end; + +function isshortcut(key: msechar; const caption: msestring): boolean; +var + p1: pmsechar; +begin + result:= false; + if caption <> '' then begin + p1:= pointer(caption); + while p1^ <> #0 do begin + if p1^ = '&' then begin + inc(p1); + if (p1^ <> '&') and (p1^ <> ' ') then begin + result:= msecomparetext(p1^,key) = 0; + break; + end; + end; + inc(p1); + end; + end; +{ + with caption do begin + if (format = nil) or (format[0].index >= length(text)) or (length(key) < 1) then begin + result:= false; + end + else begin + result:= mseuppercase(text[format[0].index+1]) = mseuppercase(key); +// result:= charuppercase(text[format[0].index+1]) = charuppercase(key); + end; + end; + } +end; +{ +function isshortcut(key: msechar; const caption: richstringty): boolean; +begin + with caption do begin + if (format = nil) or (format[0].index >= length(text)) or (length(key) < 1) then begin + result:= false; + end + else begin + result:= mseuppercase(text[format[0].index+1]) = mseuppercase(key); +// result:= charuppercase(text[format[0].index+1]) = charuppercase(key); + end; + end; +end; +} +function isshortcut(key: keyty; const caption: msestring): boolean; +begin + result:= isshortcut(keytomsechar(key),caption); +end; + +procedure insertfontinfo(var infoar: formatinfoarty; aindex: integer); +begin + setlength(infoar,length(infoar)+1); + if aindex > 0 then begin + move(infoar[aindex-1],infoar[aindex], + (length(infoar)-aindex)*sizeof(formatinfoty)); + infoar[aindex].newinfos:= []; + end + else begin + move(infoar[aindex],infoar[aindex+1], + (length(infoar)-aindex-1)*sizeof(formatinfoty)); + fillchar(infoar[0],sizeof(formatinfoty),0); + end; +end; + +function getnewfontinfo(var fontinfoar: formatinfoarty; aindex: integer; + out num: integer): pformatinfoty; +var + int1,int2: integer; +begin + int1:= 0; + if length(fontinfoar) = 0 then begin + insertfontinfo(fontinfoar,0); + end + else begin + int2:= high(fontinfoar); + while int1 <= int2 do begin + with fontinfoar[int1] do begin + if index >= aindex then begin + if index > aindex then begin + insertfontinfo(fontinfoar,int1); + end; + break; + end; + end; + inc(int1); + end; + if int1 > int2 then begin + insertfontinfo(fontinfoar,int1); + end; + end; + result:= @fontinfoar[int1]; + result^.index:= aindex; + num:= int1; +end; + +procedure packfontformats(var formats: formatinfoarty); +var + int1,int2: integer; + focopo,bacopo: colorty; + fontstyles,fontstylesdelta: fontstylesty; +begin + int2:= 0; + int1:= 0; + focopo:= 0; + bacopo:= 0; + fontstyles:= []; + while int1 < length(formats) do begin + with formats[int1] do begin + if not(ni_delete in newinfos) then begin + if style.fontcolor = focopo then begin + exclude(newinfos,ni_fontcolor); + end + else begin + include(newinfos,ni_fontcolor); + end; + if style.colorbackground = bacopo then begin + exclude(newinfos,ni_colorbackground); + end + else begin + include(newinfos,ni_colorbackground); + end; + fontstylesdelta:= fontstylesty( + {$ifdef FPC}longword{$else}byte{$endif}(fontstyles) xor + {$ifdef FPC}longword{$else}byte{$endif}(style.fontstyle)); + newinfos:= newinfos - + newinfosty(not + {$ifdef FPC}longword({$else} + word(byte{$endif}(fontstylesdelta))) * fontstyleflags + + newinfosty( + {$ifdef FPC}longword({$else} + word(byte{$endif}(fontstylesdelta))) * fontstyleflags; + if ni_fontcolor in newinfos then begin + focopo:= style.fontcolor; + end; + if ni_colorbackground in newinfos then begin + bacopo:= style.colorbackground; + end; + fontstyles:= fontstylesty({$ifdef FPC}longword{$else}byte{$endif}(fontstyles) xor + {$ifdef FPC}longword{$else}byte{$endif}(fontstylesdelta) and + {$ifdef FPC}longword({$else}byte(word{$endif}(newinfos))); + if newinfos <> [] then begin + if int1 <> int2 then begin + formats[int2]:= formats[int1]; + end; + inc(int2); + end; + end; + end; + inc(int1); + end; + if int1 <> int2 then begin + setlength(formats,int2); + end; +end; + +function setfontinfolen(var formats: formatinfoarty; aindex: integer; len: halfinteger; + const astyle: charstylety; flags: newinfosty): boolean; + //true wenn geaendert + + function updatestyle(var style: charstylety): boolean; + var + afontstyle: fontstylesty; + begin + result:= false; +// style.newinfos:= newinfos+flags; + if ni_fontcolor in flags then begin + result:= result or (style.fontcolor <> astyle.fontcolor); + style.fontcolor:= astyle.fontcolor; + end; + if ni_colorbackground in flags then begin + result:= result or (style.colorbackground <> astyle.colorbackground); + style.colorbackground:= astyle.colorbackground; + end; + afontstyle:= style.fontstyle; + style.fontstyle:= style.fontstyle - + fontstylesty({$ifdef FPC}longword({$else} + byte(word{$endif}(flags * fontstyleflags))) + + astyle.fontstyle * fontstylesty( + {$ifdef FPC}longword({$else}byte(word{$endif}(flags))); + result:= result or (afontstyle <> style.fontstyle); + end; + +var + int1,int2: integer; + isempty: boolean; + lastnum: integer; + bo1: boolean; + +begin + result:= false; + isempty:= length(formats) = 0; + if len > 0 then begin + int2:= high(formats); + getnewfontinfo(formats,aindex,int1); + getnewfontinfo(formats,aindex + len,lastnum); + for int1:= int1 to lastnum - 1 do begin + bo1:= updatestyle(formats[int1].style); + result:= result or bo1; + end; + if result or (high(formats) > int2) then begin + packfontformats(formats); + end; + end; + result:= result and not (isempty and (length(formats) = 0)); +end; + +function charstyletocolor(const color: colorty): colorty; +begin + if color = 0 then begin + result:= cl_default; + end + else begin + result:= not(color); + end; +end; + +function colortocharstyle(const color: colorty): colorty; +begin + if color = cl_default then begin + result:= 0; + end + else begin + result:= not(color); + end; +end; + +function setfontcolor1(var formats: formatinfoarty; aindex: integer; + len: halfinteger; + color: colorty): boolean; + //true if changed +var + style: charstylety; +begin + style.fontcolor:= not color; + result:= setfontinfolen(formats,aindex,len,style,[ni_fontcolor]); +end; + +function setfontcolor(const formats: formatinfoarty; aindex: integer; + len: halfinteger; + color: colorty): formatinfoarty; +begin + result:= copy(formats); + setfontcolor1(result,aindex,len,color); +end; + +function setcolorbackground1(var formats: formatinfoarty; aindex: integer; + len: halfinteger; + color: colorty): boolean; + //true if changed +var + style: charstylety; +begin + style.colorbackground:= not color; + result:= setfontinfolen(formats,aindex,len,style,[ni_colorbackground]); +end; + +function setcolorbackground(const formats: formatinfoarty; aindex: integer; + len: halfinteger; + color: colorty): formatinfoarty; +begin + result:= copy(formats); + setcolorbackground1(result,aindex,len,color); +end; + +procedure setselected1(var text: richstringty; start,len: halfinteger); +begin + updatefontstyle1(text.format,0,bigint,fs_selected,false); + updatefontstyle1(text.format,start,len,fs_selected,true); +end; + +function setselected(const text: richstringty; + start,len: halfinteger): richstringty; +begin + result:= text; + setlength(result.format,length(result.format)); + setselected1(result,start,len); +end; + +function updatefontstyle1(var formats: formatinfoarty; aindex: integer; len: halfinteger; + astyles: fontstylesty; aset: boolean): boolean; + //true if changed +var + style: charstylety; + newinfos: newinfosty; +begin + if aset then begin + style.fontstyle:= astyles; + end + else begin + style.fontstyle:= []; + end; + newinfos:= newinfosty({$ifdef FPC}longword({$else}word(byte{$endif}(astyles))); + result:= setfontinfolen(formats,aindex,len,style,newinfos); +end; + +function updatefontstyle1(var formats: formatinfoarty; aindex: integer; len: halfinteger; + astyle: fontstylety; aset: boolean): boolean; + //true if changed +begin + result:= updatefontstyle1(formats,aindex,len,[astyle],aset); +end; + +function updatefontstyle(const formats: formatinfoarty; aindex: integer; + len: halfinteger; + astyles: fontstylesty; aset: boolean): formatinfoarty; +begin + result:= copy(formats); + updatefontstyle1(result,aindex,len,astyles,aset); +end; + +function updatefontstyle(const formats: formatinfoarty; aindex: integer; + len: halfinteger; + astyle: fontstylety; aset: boolean): formatinfoarty; +begin + result:= updatefontstyle(formats,aindex,len,[astyle],aset); +end; + +function setcharstyle1(var formats: formatinfoarty; + aindex,len: halfinteger; const style: charstylety): boolean; + //true if changed +begin + result:= setfontinfolen(formats,aindex,len,style, + [ni_fontcolor,ni_colorbackground,ni_bold,ni_italic,ni_underline, + ni_strikeout,ni_blank]); +end; + +function setcharstyle(const formats: formatinfoarty; + aindex,len: halfinteger; const style: charstylety): formatinfoarty; +begin + result:= copy(formats); + setcharstyle1(result,aindex,len,style); +end; + +function getcharstyle(const formats: formatinfoarty; + const aindex: integer): charstylety; +var + int1: integer; + foundindex: integer; +begin + if length(formats) > 0 then begin + foundindex:= -1; + for int1:= 0 to high(formats) do begin + with formats[int1] do begin + if index > aindex then begin + foundindex:= int1; + break; + end; + end; + end; + if foundindex >= 0 then begin + if foundindex > 0 then begin + result:= formats[foundindex-1].style; + end + else begin + fillchar(result,sizeof(charstylety),0); + end; + end + else begin + result:= formats[high(formats)].style; + end + end + else begin + fillchar(result,sizeof(charstylety),0); + end; +end; + +function getfontstyle(const formats: formatinfoarty; + const aindex: integer): fontstylesty; +var + int1: integer; + foundindex: integer; +begin + result:= []; + if formats <> nil then begin + foundindex:= -1; + for int1:= 0 to high(formats) do begin + with formats[int1] do begin + if index > aindex then begin + foundindex:= int1; + break; + end; + end; + end; + if foundindex >= 0 then begin + if foundindex > 0 then begin + result:= formats[foundindex-1].style.fontstyle; + end; + end + else begin + result:= formats[high(formats)].style.fontstyle; + end + end; +end; + +function isequalformatinfo(const a,b: formatinfoty): boolean; +begin + result:= (a.index = b.index) and (a.newinfos = b.newinfos) and + (a.style.fontcolor = b.style.fontcolor) and + (a.style.colorbackground = b.style.colorbackground) and + (a.style.fontstyle = b.style.fontstyle); +end; + +function isequalformat(const a,b: formatinfoarty): boolean; +var + int1: integer; +begin + if pointer(a) = pointer(b) then begin + result:= true; + exit; + end; + result:= length(a) = length(b); + if result then begin + for int1:= 0 to high(a) do begin + if not isequalformatinfo(a[int1],b[int1]) then begin + result:= false; + break; + end; + end; +// result:= comparemem(pointer(a),pointer(b),length(a)*sizeof(fontinfoty)); + end; +end; + +function isequalrichstring(const a,b: richstringty): boolean; +begin + result:= (a.text = b.text) and isequalformat(a.format,b.format); +end; + +function isemptyrichstring(const value: richstringty): boolean; +begin + result:= (value.text = '') and (value.format = nil) and (value.flags = []); +end; + +procedure richdelete(var value: richstringty; aindex,count: integer); +var + int1: integer; + needspack,all: boolean; +begin + if (aindex > 0) then begin + delete(value.text,aindex,count); + if length(value.format) > 0 then begin + setlength(value.format,length(value.format)); //unique + needspack:= false; + all:= count >= bigint; + dec(aindex); + for int1:= 0 to high(value.format) do begin + with value.format[int1] do begin + if index >= aindex then begin + index:= index - count; + if all or (index < aindex) then begin + needspack:= true; + newinfos:= [ni_delete]; + end; + end; + end; + end; + if needspack then begin + packfontformats(value.format); + end; + end; + end; +end; + +procedure formatinsertchars(var format: formatinfoarty; const aindex: integer; + const count: integer); +var + int1: integer; +begin + setlength(format,length(format)); //unique + for int1:= 0 to high(format) do begin + with format[int1] do begin + if index >= aindex then begin + index:= index + count; + end; + end; + end; +end; + +function expandtabs(const s: richstringty; const tabcharcount: integer): richstringty; +var + int1,int2,int3,int4: integer; +begin + int1:= tabcharcount; + if int1 <= 0 then begin + int1:= 1; + end; + setlength(result.text,length(s.text)*int1); //max + result.format:= copy(s.format); + int2:= 1; + for int1:= 1 to length(s.text) do begin + if s.text[int1] = c_tab then begin + if tabcharcount > 0 then begin + int3:= tabcharcount - ((int2-1) mod tabcharcount) - 1; + formatinsertchars(result.format,int2,int3); + for int4:= 0 to int3 do begin + result.text[int2]:= ' '; + inc(int2); + end; + end; + end + else begin + result.text[int2]:= s.text[int1]; + inc(int2); + end; + end; + setlength(result.text,int2-1); +end; + +procedure richinsert(const source: msestring; var value: richstringty; aindex: integer); +begin + insert(source,value.text,aindex); + formatinsertchars(value.format,aindex,length(source)); +end; + +function richcopy(const source: richstringty; index, count: halfinteger): richstringty; +var + int1,int2: integer; + startindex,endindex: integer; + res: richstringty; +begin + if count = 0 then begin + result:= emptyrichstring; + end + else begin + res.text:= copy(source.text,index,count); + res.format:= nil; + if length(source.format) > 0 then begin + startindex:= -1; + endindex:= -1; + for int1:= 0 to high(source.format) do begin + if source.format[int1].index >= index then begin + startindex:= int1; + break; + end; + end; + if startindex < 0 then begin + int1:= 0; + end + else begin + int1:= startindex; + end; + for int1:= int1 to high(source.format) do begin + if source.format[int1].index >= index + count then begin + endindex:= int1; + break; + end; + end; + if startindex > 0 then begin + dec(startindex); + end + else begin + startindex:= 0; + end; + if endindex >= 0 then begin + res.format:= copy(source.format,startindex,endindex-startindex); + end + else begin + res.format:= copy(source.format,startindex,bigint); + end; + if length(res.format) > 0 then begin + with res.format[0] do begin + newinfos:= []; + if style.fontcolor <> 0 then include(newinfos,ni_fontcolor); + if style.colorbackground <> 0 then include(newinfos,ni_colorbackground); + if fs_bold in style.fontstyle then include(newinfos,ni_bold); + if fs_italic in style.fontstyle then include(newinfos,ni_italic); + if fs_underline in style.fontstyle then include(newinfos,ni_underline); + if fs_strikeout in style.fontstyle then include(newinfos,ni_strikeout); + if fs_selected in style.fontstyle then include(newinfos,ni_selected); + end; + for int1:= 0 to high(res.format) do begin + int2:= res.format[int1].index - index + 1; + if int2 < 0 then begin + int2:= 0; + end; + res.format[int1].index:= int2; + end; + end; + end; + result:= res; + end; +end; + +function richconcat(const a,b: richstringty): richstringty; +var + i1,i2,i3: integer; + res: richstringty; +begin + res.format:= a.format; + res.text:= a.text + b.text; + i2:= length(res.format); + i3:= length(a.text); + setlength(res.format,i2 + length(b.format)); + for i1:= 0 to high(b.format) do begin + with res.format[i1+i2] do begin + index:= b.format[i1].index + i3; + newinfos:= b.format[i1].newinfos; + style:= b.format[i1].style; + end; + end; + result:= res; +end; + +function richconcat(const a: richstringty; const b: msestring; + const fontstyle: fontstylesty = []; + const fontcolor: colorty = cl_none; + const colorbackground: colorty = cl_none): richstringty; +var + rstr1: richstringty; +begin + if (fontstyle <> []) or (fontcolor <> cl_none) or + (colorbackground <> cl_none) then begin + setlength(rstr1.format,1); + with rstr1.format[0] do begin + index:= 0; + if fontstyle <> [] then begin + style.fontstyle:= fontstyle; + newinfos:= fontstyleflags; + end; + if fontcolor <> cl_none then begin + style.fontcolor:= not fontcolor; + include(newinfos,ni_fontcolor); + end; + if colorbackground <> cl_none then begin + style.colorbackground:= not colorbackground; + include(newinfos,ni_colorbackground); + end; + end + end + else begin + rstr1.format:= nil; + end; + rstr1.text:= b; + result:= richconcat(a,rstr1); +end; + +function richconcat(const a: msestring; const b: richstringty; + const fontstyle: fontstylesty = []; + const fontcolor: colorty = cl_none; + const colorbackground: colorty = cl_none): richstringty; overload; +var + rstr1: richstringty; +begin + if (fontstyle <> []) or (fontcolor <> cl_none) or + (colorbackground <> cl_none) then begin + setlength(rstr1.format,1); + with rstr1.format[0] do begin + index:= 0; + if fontstyle <> [] then begin + style.fontstyle:= fontstyle; + newinfos:= fontstyleflags; + end; + if fontcolor <> cl_none then begin + style.fontcolor:= not fontcolor; + include(newinfos,ni_fontcolor); + end; + if colorbackground <> cl_none then begin + style.colorbackground:= not colorbackground; + include(newinfos,ni_colorbackground); + end; + end + end + else begin + rstr1.format:= nil; + end; + rstr1.text:= a; + result:= richconcat(rstr1,b); +end; + +procedure richconcat1(var dest: richstringty; const b: richstringty); +begin + dest:= richconcat(dest,b); +end; + +procedure richconcat1(var dest: richstringty; const b: msestring; + const fontstyle: fontstylesty = []; + const fontcolor: colorty = cl_none; + const colorbackground: colorty = cl_none); +begin + dest:= richconcat(dest,b,fontstyle,fontcolor,colorbackground); +end; + +{ +function uniqueformatinfoarty(const value: formatinfoarty): formatinfoarty; +begin + result:= value; + setlength(result,length(result)); +end; + +function uniquerichstringty(const value: richstringty): richstringty; +begin + result:= value; + setlength(result.format,length(result.format)); +end; +} +procedure additem(const value: richstringty; var dest: richstringarty; + var count: integer; step: integer = 32); +begin + if length(dest) <= count then begin + setlength(dest,count+step); + end; + dest[count]:= value; + inc(count); +end; + +{ tcharstyledatalist } + +constructor tcharstyledatalist.create; +begin + inherited; + fsize:= sizeof(charstylety); +end; + +function tcharstyledatalist.add(const value: charstylety): integer; +begin + result:= adddata(value); +end; + +function tcharstyledatalist.add(style: fontstylesty = []; fontcolor: pcolorty = nil; + colorbackground: pcolorty = nil): integer; +var + value: charstylety; +begin + value.fontstyle:= style; + if fontcolor = nil then begin + value.fontcolor:= 0; + end + else begin + value.fontcolor:= not fontcolor^; + end; + if colorbackground = nil then begin + value.colorbackground:= 0; + end + else begin + value.colorbackground:= not colorbackground^; + end; +// value.colorbackground:= colorbackground; + result:= add(value); +end; + +function tcharstyledatalist.add(const value: string): integer; + + function getcolor(const name: string): colorty; +// var +// col1: colorty; +// int1,int2: integer; +// po1: pcolorty; + begin + if name = '' then begin + result:= 0; + end + else begin + result:= not stringtocolor(name); + (* + col1:= stringtocolor(name); + for int1:= 0 to high(fcolors) do begin + if fcolors[int1] = col1 then begin + result:= @fcolors[int1]; + exit; + end; + end; + po1:= pointer(fcolors); + for int1:= 1 to length(fcolors) do begin + for int2:= 0 to fcount-1 do begin + with pcharstylety(getitempo(int2))^{licharstylearty(fdaten^)[int2]} do begin + if fontcolor = po1 then begin + fontcolor:= pointer(int1); + end; + if colorbackground = po1 then begin + colorbackground:= pointer(int1); + end; + end; + end; + inc(po1); + end; + setlength(fcolors,length(fcolors)+1); + po1:= pointer(fcolors); + for int1:= 1 to length(fcolors) do begin + for int2:= 0 to fcount-1 do begin + with pcharstylety(getitempo(int2))^{licharstylearty(fdaten^)[int2]} do begin + if fontcolor = pointer(int1) then begin + fontcolor:= po1; + end; + if colorbackground = pointer(int1) then begin + colorbackground:= po1; + end; + end; + end; + inc(po1); + end; + fcolors[high(fcolors)]:= col1; + result:= @fcolors[high(fcolors)]; + *) + end; + end; + +var + lstr1: lstringty; + str1,str2,str3: string; + st: charstylety; +begin + fillchar(st,sizeof(charstylety),0); + stringtolstring(value,lstr1); + nextquotedstring(lstr1,str1); + nextword(lstr1,str2); + nextword(lstr1,str3); + str1:= struppercase(str1); + if strlscan(pointer(str1),'B',length(str1)) <> nil then begin + include(st.fontstyle,fs_bold); + end; + if strlscan(pointer(str1),'I',length(str1)) <> nil then begin + include(st.fontstyle,fs_italic); + end; + if strlscan(pointer(str1),'U',length(str1)) <> nil then begin + include(st.fontstyle,fs_underline); + end; + if strlscan(pointer(str1),'S',length(str1)) <> nil then begin + include(st.fontstyle,fs_strikeout); + end; + st.fontcolor:= getcolor(str2); + st.colorbackground:= getcolor(str3); + result:= add(st); +end; + +function tcharstyledatalist.Getitems(index: integer): charstylety; +begin + internalgetdata(index,result); +// checkindex(index); +// result:= licharstylearty(fdaten^)[index]; +end; + +procedure tcharstyledatalist.Setitems(index: integer; const Value: charstylety); +begin + internalsetdata(index,value); +// checkindex(index); +// licharstylearty(fdaten^)[index]:= value; +end; + +procedure tcharstyledatalist.clear; +begin + inherited; +// fcolors:= nil; +end; + +{ trichstringdatalist } + +constructor trichstringdatalist.create; +begin + inherited; + fsize:= sizeof(richstringty); +end; + +procedure trichstringdatalist.freedata(var data); +begin + inherited; + richstringty(data).format:= nil; +end; + +procedure trichstringdatalist.aftercopy(var data); +begin + inherited; + reallocarray(richstringty(data).format,sizeof(richstringty(data).format[0])); +end; + +function trichstringdatalist.add(const value: msestring): integer; +var + ristr1: richstringty; +begin + ristr1.text:= value; + ristr1.format:= nil; + ristr1.flags:= []; + result:= adddata(ristr1); +end; + +function trichstringdatalist.add(const avalue: msestring; + const anoparagraph: boolean): integer; +begin + result:= inherited add(avalue,anoparagraph); + if anoparagraph then begin + noparagraphs[result]:= true; + end; +end; + +procedure trichstringdatalist.insert(const index: integer; const item: msestring); +var + ristr1: richstringty; +begin + ristr1.text:= item; + ristr1.format:= nil; + ristr1.flags:= []; + insertdata(index,ristr1); +end; + +function trichstringdatalist.compare(const l,r): integer; +begin + result:= msecomparestr(richstringty(l).text,richstringty(r).text); +end; + +function trichstringdatalist.getformatpo(index: integer): pformatinfoarty; +begin + checkindex(index); + result:= @prichstringty(fdatapo+index*sizeof(richstringty))^.format; +end; + +function trichstringdatalist.getparagraph(const index: integer; + const aseparator: msestring = ''): msestring; +var + int1,int2: integer; + start{,stop}: integer; +begin + start:= index; + while start >= 0 do begin + int2:= start; + checkindex(int2); + if not (rf_noparagraph in + prichstringty(fdatapo+int2*sizeof(richstringty))^.flags) then begin + break; + end; + dec(start); + end; + int2:= start; + checkindex(int2); + result:= prichstringty(fdatapo+int2*sizeof(richstringty))^.text; + for int1:= start+1 to count-1 do begin + int2:= int1; + checkindex(int2); + with prichstringty(fdatapo+int2*sizeof(richstringty))^ do begin + if not (rf_noparagraph in flags) then begin + break; + end; + result:= result + aseparator + text; + end; + end; +end; + +function trichstringdatalist.Getformats(index: integer): formatinfoarty; +begin + checkindex(index); + result:= prichstringty(fdatapo+index*sizeof(richstringty))^.format; +end; + +procedure trichstringdatalist.Setformats(index: integer; + const Value: formatinfoarty); +begin + checkindex(index); +// prichstringty(fdatapo+index*sizeof(richstringty))^.format:= uniqueformatinfoarty(value); + prichstringty(fdatapo+index*sizeof(richstringty))^.format:= copy(value); +end; + +function trichstringdatalist.getnoparagraphs(index: integer): boolean; +begin + checkindex(index); + result:= rf_noparagraph in + prichstringty(fdatapo+index*sizeof(richstringty))^.flags; +end; + +procedure trichstringdatalist.setnoparagraphs(index: integer; + const avalue: boolean); +begin + checkindex(index); + if avalue then begin + include(prichstringty(fdatapo+index*sizeof(richstringty))^.flags, + rf_noparagraph); + end + else begin + exclude(prichstringty(fdatapo+index*sizeof(richstringty))^.flags, + rf_noparagraph); + end; +end; + +function trichstringdatalist.getrichitems(index: integer): richstringty; +begin + checkindex(index); + result:= prichstringty(fdatapo+index*sizeof(richstringty))^; +end; + +procedure trichstringdatalist.setrichitems(index: integer; const Value: richstringty); +var + po1: prichstringty; +begin + checkindex(index); + po1:= prichstringty(fdatapo+index*sizeof(richstringty)); + po1^.text:= value.text; + po1^.format:= copy(value.format); +// prichstringty(fdatapo+index*sizeof(richstringty))^:= uniquerichstringty(value); +end; + +function trichstringdatalist.getrichitemspo(index: integer): prichstringty; +begin + checkindex(index); + result:= prichstringty(fdatapo+index*sizeof(richstringty)); +end; + +procedure trichstringdatalist.setasarray(const data: richstringarty); +begin + internalsetasarray(pointer(data),sizeof(richstringty),length(data)); +end; + +function trichstringdatalist.getasarray: richstringarty; +begin + result:= nil; + allocuninitedarray(fcount,sizeof(result[0]),result); +// setlength(result,fcount); + internalgetasarray(pointer(result),sizeof(richstringty)); +end; + +procedure trichstringdatalist.setasmsestringarray(const data: msestringarty); +var + po1: prichstringty; + int1: integer; + s1: integer; +begin + newbuffer(length(data),true,true); + po1:= pointer(fdatapo); + s1:= size; + for int1:= 0 to fcount - 1 do begin + po1^.text:= data[int1]; + po1^.format:= nil; + po1^.flags:= []; + inc(pchar(po1),s1); + end; + change(-1); +end; + +function trichstringdatalist.getasmsestringarray: msestringarty; +var + po1: prichstringty; + int1: integer; +begin + setlength(result,fcount); + po1:= datapo; + for int1:= 0 to fcount - 1 do begin + result[int1]:= po1^.text; + inc(po1); + end; +end; + +function trichstringdatalist.nextword(out value: lmsestringty): boolean; +var + po1: pmsechar; + int1: integer; +begin + if fposition.Y >= fcount then begin + result:= false; + value.po:= nil; + value.len:= 0; + end + else begin + with prichstringty(fdatapo+fposition.y*sizeof(richstringty))^ do begin + int1:= length(text) - fposition.X; + if int1 > 0 then begin + value.po:= msestrlnscan(@text[fposition.x+1],' ',int1); + end + else begin + value.po:= nil; + end; + if value.po = nil then begin + result:= true; + value.len:= 0; + inc(fposition.Y); + fposition.X:= 0; + end + else begin + result:= false; + int1:= length(text)-(value.po - pmsechar(pointer(text))); + po1:= msestrlscan(value.po,' ',int1); + if po1 = nil then begin + value.len:= int1; + end + else begin + value.len:= po1-value.po; + end; + fposition.X:= (value.po - pmsechar(pointer(text))) + value.len; + end; + end; + end; +end; +{ +procedure trichstringdatalist.assign(source: tpersistent); +begin + if not assigndata(source) then begin + if source is tpoorstringdatalist then begin + tpoorstringdatalist1(source).assigntodata(self); + end + else begin + inherited; + end; + end; +end; +} +procedure trichstringdatalist.setstatdata(const index: integer; const value: msestring); +var + po1: prichstringty; +begin + po1:= getitempo(index); + po1^.text:= value; + po1^.format:= nil; +end; + +function trichstringdatalist.getstatdata(const index: integer): msestring; +begin + result:= items[index]; +end; + +initialization + hotkeyfontstylesadd:= [fs_underline]; + hotkeyfontstylesremove:= []; + hotkeycolor:= cl_none; + hotkeycolorbackground:= cl_none; +end. diff --git a/mseide-msegui/lib/common/kernel/mserttistat.pas b/mseide-msegui/lib/common/kernel/mserttistat.pas new file mode 100644 index 0000000..c9aa449 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mserttistat.pas @@ -0,0 +1,1446 @@ +{ MSEgui Copyright (c) 2010-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mserttistat; +{$ifdef FPC} + {$mode objfpc}{$h+} +{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,mseclasses,msestat,msestatfile,msestrings,typinfo,msetypes, + msehash,msemacros; + +type + objectinfoty = record + obj: tobject; + prefix: string; + end; + objectinfoarty = array of objectinfoty; + + getobjecteventty = procedure(const sender: tobject; + var aobject: tobject) of object; + getobjectseventty = procedure(const sender: tobject; + var aobjects: objectinfoarty) of object; + +{$M+} //toptions and toptionsclass needs RTTI + + toptions = class(tobject) + protected + function gett: tobject; virtual; + function gettexp: tobject; virtual; + procedure dostatupdate(const filer: tstatfiler); virtual; + procedure dostatread(const reader: tstatreader); virtual; + procedure dostatwrite(const writer: tstatwriter); virtual; + procedure change() virtual; + public + destructor destroy; override; + procedure readstat(const reader: tstatreader; const prefix: string); + procedure writestat(const writer: tstatwriter; const prefix: string); + {$ifdef mse_with_ifi} + procedure storevalues(const asource: tmsecomponent; + const prefix: string = '') virtual; + procedure loadvalues(const adest: tmsecomponent; + const prefix: string = '') virtual; + {$endif} + procedure expandmacros(const amacrolist: tmacrolist); overload; + procedure expandmacros(const macros: macroinfoarty; + const options: macrooptionsty = + [mao_caseinsensitive]); overload; + procedure expandmacros(const anames,avalues: array of msestring; + const options: macrooptionsty = + [mao_caseinsensitive]); overload; + end; + + tcustomrttistat = class(tmsecomponent,istatfile) + private + fstatfile: tstatfile; + fstatvarname: msestring; + fongetobject: getobjecteventty; + fongetobjects: getobjectseventty; + fonstatupdate: statupdateeventty; + fonstatread: statreadeventty; + fonstatwrite: statwriteeventty; + fonstatbeforeread: notifyeventty; + fonstatafterread: notifyeventty; + {$ifdef mse_with_ifi} + ftargets: tpointeransistringhashdatalist; + {$endif} + fstatpriority: integer; + procedure setstatfile(const avalue: tstatfile); + protected + function getobj(out aobj: objectinfoarty): boolean; + {$ifdef mse_with_ifi} + function findtarget(const aname: string): tobject; + procedure scantargets(const aroot: tcomponent); + {$endif} + //istatfile + procedure dostatread(const reader: tstatreader); virtual; + procedure dostatwrite(const writer: tstatwriter); virtual; + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + public + procedure readstat(const areader: tstatreader); + procedure writestat(const awriter: tstatwriter); + {$ifdef mse_with_ifi} + procedure valuestoobj(const sourceroot: tcomponent); + //reads values from components with matching property-component names + //or statvarnames + procedure objtovalues(const destroot: tcomponent); + //writes values to components with matching property-component names + //or statvarnames + {$endif} + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read fstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + property ongetobject: getobjecteventty read fongetobject write fongetobject; + property ongetobjects: getobjectseventty read fongetobjects + write fongetobjects; + property onstatupdate: statupdateeventty read fonstatupdate + write fonstatupdate; + property onstatread: statreadeventty read fonstatread + write fonstatread; + property onstatwrite: statwriteeventty read fonstatwrite + write fonstatwrite; + property onstatbeforeread: notifyeventty read fonstatbeforeread + write fonstatbeforeread; + property onstatafterread: notifyeventty read fonstatafterread + write fonstatafterread; + end; + + trttistat = class(tcustomrttistat) + protected + published + property statfile; + property statvarname; + property statpriority; + property ongetobject; + property ongetobjects; + property onstatupdate; + property onstatread; + property onstatwrite; + property onstatbeforeread; + property onstatafterread; + end; + +function opentodynarray(const objs: array of tobject; + const prefixes: array of string): objectinfoarty; +function getmsestringar(const aobj: tobject; + const aprop: ppropinfo): msestringarty; +procedure setmsestringar(const aobj: tobject; const aprop: ppropinfo; + const avalue: msestringarty); +procedure addobjectinfoitem(var dest: objectinfoarty; const aobj: tobject; + const aprefix: string = ''); + +{$ifdef mse_with_ifi} +procedure objecttovalues(const source: tobject; const dest: tmsecomponent; + const prefix: string = ''); +procedure valuestoobject(const source: tmsecomponent; const dest: tobject; + const prefix: string = ''); +{$endif} +function dupplicateobject(const source: tobject): tobject; +function dupplicateobjects(const source: objectarty): objectarty; + +implementation +uses + {$ifdef mse_with_ifi}mseificompglob,{$endif}msedatalist,sysutils,msearrayutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + dynarraysetter = procedure(const avalue: pointerarty) of object; + //dummy type + dynarraygetter = function: pointerarty of object; + //dummy type + +procedure addobjectinfoitem(var dest: objectinfoarty; const aobj: tobject; + const aprefix: string = ''); +begin + setlength(dest,high(dest)+2); + with dest[high(dest)] do begin + obj:= aobj; + prefix:= aprefix; + end; +end; + +function opentodynarray(const objs: array of tobject; + const prefixes: array of string): objectinfoarty; +var + int1: integer; +begin + setlength(result,length(objs)); + for int1:= 0 to high(result) do begin + with result[int1] do begin + obj:= objs[int1]; + if int1 <= high(prefixes) then begin + prefix:= prefixes[int1]; + end; + end; + end; +end; +{$ifndef FPC} +const + ptmask = $FF000000; + ptfield = $FF000000; + ptvirtual = $FE000000; +{$endif} + +function getdynarray(const aobj: tobject; const aprop: ppropinfo): pointer; +var + getterkind: integer; + meth1: tmethod; +begin +{$ifdef FPC} + getterkind:= (aprop^.propprocs) and 3; +{$else} + getterkind:= ptruint(aprop^.getproc) and ptmask; +{$endif} + case getterkind of + ptfield: begin + {$ifdef FPC} + result:= ppointer(pointer(aobj) + ptruint(aprop^.getproc))^; + {$else} + result:= ppointer(pchar(aobj) + (ptruint(aprop^.getproc) and not ptmask))^; + {$endif} + exit; + end; + ptvirtual: begin + {$ifdef FPC} + meth1.code:= ppointer(pointer(aobj.classtype) + + ptruint(aprop^.getproc))^; + {$else} + meth1.code:= ppointer(pchar(aobj) + smallint(ptrint(aprop^.getproc)))^; + {$endif} + end; + {$ifdef FPC} + ptstatic: begin + {$else} + else begin + {$endif} + meth1.code:= aprop^.getproc; + end; + {$ifdef FPC} + else begin + result:= nil; + exit; + end; + {$endif} + end; + meth1.data:= aobj; + result:= pointer(dynarraygetter(meth1)()); +end; + +function setdynarray(const aobj: tobject; const aprop: ppropinfo; + const avalue: pointer): pointer; + // returns valuebefore for finalize +var + setterkind: integer; + meth1: tmethod; +begin +{$ifdef FPC} + setterkind:= (aprop^.propprocs shr 2) and 3; +{$else} + setterkind:= ptruint(aprop^.setproc) and ptmask; +{$endif} + result:= nil; + case setterkind of + ptfield: begin + arrayaddref((@avalue)^); + result:= getdynarray(aobj,aprop); + {$ifdef FPC} + ppointer(pointer(aobj) + ptruint(aprop^.setproc))^:= avalue; + {$else} + ppointer(pchar(aobj) + (ptruint(aprop^.setproc) and not ptmask))^:= avalue; + {$endif} + exit; + end; + ptvirtual: begin + {$ifdef FPC} + meth1.code:= ppointer(pointer(aobj.classtype) + + ptruint(aprop^.setproc))^; + {$else} + meth1.code:= ppointer(pchar(aobj) + smallint(ptrint(aprop^.setproc)))^; + {$endif} + end; + {$ifdef FPC} + ptstatic: begin + {$else} + else begin + {$endif} + meth1.code:= aprop^.setproc; + end; + {$ifdef FPC} + else begin + result:= nil; + exit; + end; + {$endif} + end; + meth1.data:= aobj; + dynarraysetter(meth1)(avalue); +end; + +function getintegerar(const aobj: tobject; const aprop: ppropinfo): integerarty; +begin + result:= integerarty(getdynarray(aobj,aprop)); +end; + +{$notes off} //avoid "never used" +procedure setintegerar(const aobj: tobject; const aprop: ppropinfo; + const avalue: integerarty); +var + ar1: integerarty; +begin + pointer(ar1):= setdynarray(aobj,aprop,pointer(avalue)); + ar1:= nil; //finalize +end; +{$notes on} + +function getint64ar(const aobj: tobject; const aprop: ppropinfo): int64arty; +begin + result:= int64arty(getdynarray(aobj,aprop)); +end; + +{$notes off} //avoid "never used" +procedure setint64ar(const aobj: tobject; const aprop: ppropinfo; + const avalue: int64arty); +var + ar1: int64arty; +begin + pointer(ar1):= setdynarray(aobj,aprop,pointer(avalue)); + ar1:= nil; //finalize +end; +{$notes off} + +function getrealar(const aobj: tobject; const aprop: ppropinfo): realarty; +begin + result:= realarty(getdynarray(aobj,aprop)); +end; + +procedure setrealar(const aobj: tobject; const aprop: ppropinfo; + const avalue: realarty); +var + ar1: realarty; +begin + pointer(ar1):= setdynarray(aobj,aprop,pointer(avalue)); + ar1:= nil; //finalize +end; + +function getmsestringar(const aobj: tobject; + const aprop: ppropinfo): msestringarty; +begin + result:= msestringarty(getdynarray(aobj,aprop)); +end; + +function getwidestringar(const aobj: tobject; + const aprop: ppropinfo): widestringarty; +begin + result:= widestringarty(getdynarray(aobj,aprop)); +end; + +{$notes off} //avoid "never used" +procedure setmsestringar(const aobj: tobject; const aprop: ppropinfo; + const avalue: msestringarty); +var + ar1: msestringarty; +begin + pointer(ar1):= setdynarray(aobj,aprop,pointer(avalue)); + ar1:= nil; //finalize +end; +{$notes on} + +{$notes off} //avoid "never used" +procedure setwidestringar(const aobj: tobject; const aprop: ppropinfo; + const avalue: widestringarty); +var + ar1: widestringarty; +begin + pointer(ar1):= setdynarray(aobj,aprop,pointer(avalue)); + ar1:= nil; //finalize +end; +{$notes on} + +function getstringar(const aobj: tobject; + const aprop: ppropinfo): stringarty; +begin + result:= stringarty(getdynarray(aobj,aprop)); +end; + +{$notes off} //avoid "never used" +procedure setstringar(const aobj: tobject; const aprop: ppropinfo; + const avalue: stringarty); +var + ar1: stringarty; +begin + pointer(ar1):= setdynarray(aobj,aprop,pointer(avalue)); + ar1:= nil; //finalize +end; +{$notes on} + +function getbooleanar(const aobj: tobject; + const aprop: ppropinfo): booleanarty; +begin + result:= booleanarty(getdynarray(aobj,aprop)); +end; + +{$notes off} //avoid "never used" +procedure setbooleanar(const aobj: tobject; const aprop: ppropinfo; + const avalue: booleanarty); +var + ar1: booleanarty; +begin + pointer(ar1):= setdynarray(aobj,aprop,pointer(avalue)); + ar1:= nil; //finalize +end; +{$notes on} + +procedure readobjectstat(const reader: tstatreader; const aobj: objectinfoty); +var + ar1: propinfopoarty; + po1: ppropinfo; + po2: ptypeinfo; + po3: ptypedata; + int1: integer; + obj1: tobject; + info1: objectinfoty; +// intf1: istatfile; +// intar: integerarty; +// realar: realarty; + mstr1: msestring; +begin + with aobj do begin + ar1:= getpropinfoar(obj); + for int1 := 0 to high(ar1) do begin + po1:= ar1[int1]; + with po1^ do begin + mstr1:= msestring(prefix+name); + case proptype^.kind of + tkInteger,tkChar,tkEnumeration,tkWChar,tkSet: begin + setordprop(obj,po1,reader.readinteger(mstr1,getordprop(obj,po1))); + end; + tkint64: begin + setint64prop(obj,po1,reader.readint64(mstr1,getint64prop(obj,po1))); + end; + tkfloat: begin + setfloatprop(obj,po1,reader.readreal(mstr1,getfloatprop(obj,po1), + emptyreal,1e300)); + end; + {$ifdef FPC} + tkbool: begin + setordprop(obj,po1, +// ord(longbool(reader.readboolean(mstr1,getordprop(obj,po1) <> 0)))); + ord(reader.readboolean(mstr1,getordprop(obj,po1) <> 0))); + end; + {$endif} + tkwstring: begin + setwidestrprop(obj,po1,reader.readmsestring( + mstr1,getwidestrprop(obj,po1))); + end; + {$ifdef FPC} + tkustring: begin + setunicodestrprop(obj,po1,reader.readmsestring( + mstr1,getunicodestrprop(obj,po1))); + end; + {$endif} + {$ifdef FPC}tkastring,{$endif}tklstring,tkstring: begin + setstrprop(obj,po1,reader.readbinarystring(mstr1,getstrprop(obj,po1))); + end; + //how to reach fpc_DecRef? + tkdynarray: begin + {$ifdef FPC} + po2:= pointer(gettypedata(proptype)^.eltype2); + //wrong define in ttypedata + {$else} + po2:= gettypedata(proptype^)^.eltype2^; + {$endif} + po3:= gettypedata(po2); + case po2^.kind of + tkinteger: begin + setintegerar(obj,po1,reader.readarray(mstr1,getintegerar(obj,po1))); + end; + tkint64: begin + setint64ar(obj,po1,reader.readarray(mstr1,getint64ar(obj,po1))); + end; + tkfloat: begin + if po3^.floattype = ftdouble then begin + setrealar(obj,po1,reader.readarray(mstr1,getrealar(obj,po1))); + end; + end; + tkwstring: begin + setwidestringar(obj,po1,reader.readarray(mstr1,getwidestringar(obj,po1))); + end; + {$ifdef FPC}tkastring{$else}tklstring{$endif}: begin + setstringar(obj,po1,reader.readarray(mstr1,getstringar(obj,po1))); + end; + {$ifdef FPC} + tkustring: begin + setmsestringar(obj,po1,reader.readarray(mstr1,getmsestringar(obj,po1))); + end; + {$endif} + {$ifdef FPC}tkbool{$else}tkenumeration{$endif}: begin + setbooleanar(obj,po1,reader.readarray(mstr1,getbooleanar(obj,po1))); + end; + end; + end; + tkclass: begin + obj1:= tobject(ptruint(getordprop(obj,po1))); + if obj1 is tdatalist then begin + reader.readdatalist(mstr1,tdatalist(obj1)); + end + else begin + info1.obj:= obj1; + info1.prefix:= aobj.prefix; + readobjectstat(reader,info1); + end; + end; + end; + end; + end; + end; +end; + +procedure writeobjectstat(const writer: tstatwriter; const aobj: objectinfoty); +var + ar1: propinfopoarty; + po1: ppropinfo; + po2: ptypeinfo; + po3: ptypedata; + int1: integer; + obj1: tobject; + mstr1: msestring; + info1: objectinfoty; +begin + with aobj do begin + ar1:= getpropinfoar(obj); + for int1 := 0 to high(ar1) do begin + po1:= ar1[int1]; + with po1^ do begin + mstr1:= msestring(prefix+name); + case proptype^.kind of + tkInteger,tkChar,tkEnumeration,tkWChar,tkSet: begin + writer.writeinteger(mstr1,getordprop(obj,po1)); + end; + tkint64: begin + writer.writeint64(mstr1,getint64prop(obj,po1)); + end; + tkfloat: begin + writer.writereal(mstr1,getfloatprop(obj,po1)); + end; + {$ifdef FPC} + tkbool: begin + writer.writeboolean(mstr1,getordprop(obj,po1) <> 0); + end; + tkustring: begin + writer.writemsestring(mstr1,getunicodestrprop(obj,po1)); + end; + {$endif} + tkwstring: begin + writer.writemsestring(mstr1,getwidestrprop(obj,po1)); + end; + {$ifdef FPC}tkastring,{$endif}tklstring,tkstring: begin + writer.writebinarystring(mstr1,getstrprop(obj,po1)); + end; + tkdynarray: begin + {$ifdef FPC} + po2:= pointer(gettypedata(proptype)^.eltype2); + //wrong define in ttypedata + {$else} + po2:= gettypedata(proptype^)^.eltype2^; + {$endif} + po3:= gettypedata(po2); + case po2^.kind of + tkinteger: begin + writer.writearray(mstr1,getintegerar(obj,po1)); + end; + tkint64: begin + writer.writearray(mstr1,getint64ar(obj,po1)); + end; + tkfloat: begin + if po3^.floattype = ftdouble then begin + writer.writearray(mstr1,getrealar(obj,po1)); + end; + end; + {$ifdef FPC}tkastring{$else}tklstring{$endif}: begin + writer.writearray(mstr1,getstringar(obj,po1)); + end; + {$ifdef FPC} + tkustring: begin + writer.writearray(mstr1,getmsestringar(obj,po1)); + end; + {$endif} + {$ifdef FPC}tkbool{$else}tkenumeration{$endif}: begin + writer.writearray(mstr1,getbooleanar(obj,po1)); + end; + end; + end; + tkclass: begin + obj1:= tobject(ptruint(getordprop(obj,po1))); + if obj1 is tdatalist then begin + writer.writedatalist(mstr1,tdatalist(obj1)); + end + else begin + info1.obj:= obj1; + info1.prefix:= aobj.prefix; + writeobjectstat(writer,info1); + end; + end; + end; + end; + end; + end; +end; + +{$ifdef mse_with_ifi} +type + findtargetty = function(const aname: string): tobject of object; + +procedure valuestoobject(const dest: objectinfoty; + const findtarget: findtargetty); +var + comp1: tobject; + ar1: propinfopoarty; + po1,po4: ppropinfo; + po2: ptypeinfo; + int1: integer; + intf1: iifidatalink; + obj1: tobject; + info1: objectinfoty; + bo1: boolean; + list1: tdatalist; +begin + obj1:= nil; + ar1:= getpropinfoar(dest.obj); + for int1 := 0 to high(ar1) do begin + po1:= ar1[int1]; + with po1^ do begin + bo1:= true; + if po1^.proptype^.kind = tkclass then begin + obj1:= tobject(ptruint(getordprop(dest.obj,po1))); + if not (obj1 is tdatalist) then begin + bo1:= false; + info1.obj:= obj1; + info1.prefix:= dest.prefix; + valuestoobject(info1,findtarget); + end; + end; + if bo1 then begin + comp1:= findtarget(dest.prefix+name); + if (comp1 <> nil) and + mseclasses.getcorbainterface(comp1,typeinfo(iifidatalink), + intf1) then begin + po4:= intf1.getvalueprop; + if po4 <> nil then begin + case proptype^.kind of + tkInteger,tkChar,tkEnumeration,tkWChar,tkSet: begin + if po4^.proptype^.kind in + [tkInteger,tkChar,tkEnumeration,tkWChar,tkSet] then begin + setordprop(dest.obj,po1,getordprop(comp1,po4)); + end + else begin + if po4^.proptype^.kind in [tkustring] then begin + setordprop(dest.obj,po1,ord(pmsechar(getunicodestrprop(comp1,po4))^)); + end + else begin + if po4^.proptype^.kind in [tkastring,tklstring,tkstring] then begin + setordprop(dest.obj,po1,ord(pchar(getstrprop(comp1,po4))^)); + end; + end; + end; + end; + tkint64: begin + if po4^.proptype^.kind in + [tkint64] then begin + setint64prop(dest.obj,po1,getint64prop(comp1,po4)); + end; + end; + tkfloat: begin + if po4^.proptype^.kind in + [tkfloat] then begin + setfloatprop(dest.obj,po1,getfloatprop(comp1,po4)); + end; + end; + {$ifdef FPC} + tkbool: begin + if po4^.proptype^.kind in + [tkbool] then begin + setordprop(dest.obj,po1,getordprop(comp1,po4)); + end; + end; + tkustring: begin + if po4^.proptype^.kind in [tkustring] then begin + setunicodestrprop(dest.obj,po1,getunicodestrprop(comp1,po4)); + end; + end; + {$endif} + tkwstring: begin + {$ifdef FPC} + if po4^.proptype^.kind = tkustring then begin + setwidestrprop(dest.obj,po1,getunicodestrprop(comp1,po4)); + end; + {$else} + if po4^.proptype^.kind = tkwstring then begin + setwidestrprop(dest.obj,po1,getwidestrprop(comp1,po4)); + end; + {$endif} + end; + tkastring,tklstring,tkstring: begin + if po4^.proptype^.kind = tkustring then begin + setstrprop(dest.obj,po1,ansistring(getunicodestrprop(comp1,po4))); + end + else begin + if po4^.proptype^.kind in [tkastring,tklstring,tkstring] then begin + setstrprop(dest.obj,po1,getstrprop(comp1,po4)); + end; + end; + end; + tkclass: begin + list1:= intf1.getgriddata; + if list1 <> nil then begin + tdatalist(obj1).assign(list1); + end; + end; + tkdynarray: begin + list1:= intf1.getgriddata; + if list1 <> nil then begin + {$ifdef FPC} + po2:= pointer(gettypedata(proptype)^.eltype2); + //wrong define in ttypedata + {$else} + po2:= gettypedata(proptype^)^.eltype2^; + {$endif} + case po2^.kind of + tkinteger: begin + if list1 is tintegerdatalist then begin + setintegerar(dest.obj,po1,tintegerdatalist(list1).asarray); + end; + end; + tkint64: begin + if list1 is tint64datalist then begin + setint64ar(dest.obj,po1,tint64datalist(list1).asarray); + end; + end; + tkfloat: begin + if list1 is trealdatalist then begin + setrealar(dest.obj,po1,trealdatalist(list1).asarray); + end; + end; + {$ifdef FPC}tkustring{$else}tkwstring{$endif}: begin + if list1 is tpoorstringdatalist then begin + setmsestringar(dest.obj,po1,tpoorstringdatalist(list1).asarray); + end; + end; + {$ifdef FPC}tkastring{$else}tklstring{$endif}: begin + if list1 is tansistringdatalist then begin + setstringar(dest.obj,po1,tansistringdatalist(list1).asarray); + end; + end; + {$ifdef FPC}tkbool{$else}tkenumeration{$endif}: begin + if list1 is tintegerdatalist then begin + setbooleanar(dest.obj,po1,tintegerdatalist(list1).asbooleanarray); + end; + end; + end; + end; + end; + end; + end; + end; + end; + end; + end; +end; + +procedure objecttovalues(const source: objectinfoty; + const findtarget: findtargetty); +var + comp1: tobject; + ar1: propinfopoarty; + po1,po4: ppropinfo; + po2: ptypeinfo; + po3: ptypedata; + int1: integer; + i2: int32; + intf1: iifidatalink; + obj1: tobject; + list1: tdatalist; + bo1: boolean; + info1: objectinfoty; +begin + obj1:= nil; + ar1:= getpropinfoar(source.obj); + for int1 := 0 to high(ar1) do begin + po1:= ar1[int1]; + with po1^ do begin + bo1:= true; + if po1^.proptype^.kind = tkclass then begin + obj1:= tobject(ptruint(getordprop(source.obj,po1))); + if not (obj1 is tdatalist) then begin + bo1:= false; + info1.obj:= obj1; + info1.prefix:= source.prefix; + objecttovalues(info1,findtarget); + end; + end; + if bo1 then begin + comp1:= findtarget(source.prefix+name); + if (comp1 <> nil) and + mseclasses.getcorbainterface(comp1,typeinfo(iifidatalink), + intf1) then begin + po4:= intf1.getvalueprop; + if po4 <> nil then begin + case proptype^.kind of + tkInteger,tkChar,tkEnumeration,tkWChar,tkSet: begin + if po4^.proptype^.kind in + [tkInteger,tkChar,tkEnumeration,tkWChar,tkSet] then begin + setordprop(comp1,po4,getordprop(source.obj,po1)); + end + else begin + if proptype^.kind in [tkchar,tkwchar] then begin + if po4^.proptype^.kind in [tkastring,tklstring,tkstring] then begin + setstrprop(comp1,po4,char(getordprop(source.obj,po1))); + end + else begin + if po4^.proptype^.kind in [tkustring] then begin + setunicodestrprop(comp1,po4,widechar(getordprop(source.obj,po1))); + end; + end; + end; + end; + end; + tkint64: begin + if po4^.proptype^.kind in + [tkint64] then begin + setint64prop(comp1,po4,getint64prop(source.obj,po1)); + end; + end; + tkfloat: begin + if po4^.proptype^.kind in + [tkfloat] then begin + setfloatprop(comp1,po4,getfloatprop(source.obj,po1)); + end; + end; + {$ifdef FPC} + tkbool: begin + if po4^.proptype^.kind in + [tkbool] then begin + setordprop(comp1,po4,getordprop(source.obj,po1)); + end; + end; + tkustring: begin + if po4^.proptype^.kind in [tkustring] then begin + setunicodestrprop(comp1,po4,getunicodestrprop(source.obj,po1)); + end; + end; + {$endif} + tkwstring: begin + {$ifdef FPC} + if po4^.proptype^.kind = tkustring then begin + setunicodestrprop(comp1,po4,getwidestrprop(source.obj,po1)); + end; + {$else} + if po4^.proptype^.kind = tkwstring then begin + setwidestrprop(comp1,po4,getwidestrprop(source.obj,po1)); + end; + {$endif} + end; + tkastring,tklstring,tkstring: begin + if po4^.proptype^.kind = tkustring then begin + setunicodestrprop(comp1,po4,unicodestring(getstrprop(source.obj,po1))); + end + else begin + if po4^.proptype^.kind in [tkastring,tklstring,tkstring] then begin + setstrprop(comp1,po4,getstrprop(source.obj,po1)); + end; + end; + end; + tkdynarray: begin + list1:= intf1.getgriddata; + if list1 <> nil then begin + {$ifdef FPC} + po2:= pointer(gettypedata(proptype)^.eltype2); + //wrong define in ttypedata + {$else} + po2:= gettypedata(proptype^)^.eltype2^; + {$endif} + po3:= gettypedata(po2); + list1.beginupdate(); + try + i2:= list1.count; + case po2^.kind of + tkinteger: begin + if list1 is tintegerdatalist then begin + tintegerdatalist(list1).asarray:= getintegerar(source.obj,po1); + end; + end; + tkint64: begin + if list1 is tint64datalist then begin + tint64datalist(list1).asarray:= getint64ar(source.obj,po1); + end; + end; + tkfloat: begin + if (po3^.floattype = ftdouble) and (list1 is trealdatalist) then begin + trealdatalist(list1).asarray:= getrealar(source.obj,po1); + end; + end; + {$ifdef FPC}tkustring{$else}tkwstring{$endif}: begin + if list1 is tpoorstringdatalist then begin + tpoorstringdatalist(list1).asarray:= getmsestringar(source.obj,po1); + end; + end; + {$ifdef FPC}tkastring{$else}tklstring{$endif}: begin + if list1 is tansistringdatalist then begin + tansistringdatalist(list1).asarray:= getstringar(source.obj,po1); + end; + end; + {$ifdef FPC}tkbool{$else}tkenumeration{$endif}: begin + if list1 is tintegerdatalist then begin + tintegerdatalist(list1).asbooleanarray:= getbooleanar(source.obj,po1); + end; + end; + end; + if (i2 > list1.count) and list1.facultative then begin + list1.count:= i2; + end; + finally + list1.endupdate(); + end; + end; + end; + tkclass: begin + list1:= intf1.getgriddata; + if list1 <> nil then begin + list1.assign(tdatalist(obj1)); + end; + end; + end; + end; + end; + end; + end; + end; +end; + +function dupplicateobject(const source: tobject): tobject; +var + ar1: propinfopoarty; + po1: ppropinfo; + po2: ptypeinfo; + int1: integer; + obj1: tobject; +begin + result:= source.classtype.create(); + ar1:= getpropinfoar(source); + for int1 := 0 to high(ar1) do begin + po1:= ar1[int1]; + with po1^ do begin + case po1^.proptype^.kind of + tkclass: begin + obj1:= tobject(ptruint(getordprop(source,po1))); + setordprop(result,po1,ptruint(obj1)); + end; + tkInteger,tkChar,tkEnumeration,tkWChar,tkSet,tkbool: begin + setordprop(result,po1,getordprop(source,po1)); + end; + tkint64: begin + setint64prop(result,po1,getint64prop(source,po1)); + end; + tkfloat: begin + setfloatprop(result,po1,getfloatprop(source,po1)); + end; + tkustring: begin + setunicodestrprop(result,po1,getunicodestrprop(source,po1)); + end; + tkwstring: begin + setwidestrprop(result,po1,getwidestrprop(source,po1)); + end; + tkastring,tklstring,tkstring: begin + setstrprop(result,po1,getstrprop(source,po1)); + end; + tkdynarray: begin + po2:= pointer(gettypedata(proptype)^.eltype2); + //wrong define in ttypedata + case po2^.kind of + tkinteger: begin + setintegerar(result,po1,getintegerar(source,po1)); + end; + tkint64: begin + setint64ar(result,po1,getint64ar(source,po1)); + end; + tkfloat: begin + setrealar(result,po1,getrealar(source,po1)); + end; + tkustring: begin + setmsestringar(result,po1,getmsestringar(source,po1)); + end; + tkastring: begin + setstringar(result,po1,getstringar(source,po1)); + end; + tkbool: begin + setbooleanar(result,po1,getbooleanar(source,po1)); + end; + end; + end; + end; + end; + end; +end; + +function dupplicateobjects(const source: objectarty): objectarty; +var + i1: int32; +begin + setlength(result,length(source)); + for i1:= 0 to high(result) do begin + result[i1]:= dupplicateobject(source[i1]); + end; +end; + +type + tfindtarg = class + private + fowner: tmsecomponent; + function findcomponenttarget(const aname: string): tobject; + end; + +function tfindtarg.findcomponenttarget(const aname: string): tobject; +begin + result:= fowner.findcomponent(aname); +end; + +procedure valuestoobject(const source: tmsecomponent; const dest: tobject; + const prefix: string = ''); +var + findtarg: tfindtarg; + objinfo: objectinfoty; +begin + objinfo.obj:= dest; + objinfo.prefix:= prefix; + findtarg:= tfindtarg.create(); + try + findtarg.fowner:= source; + valuestoobject(objinfo,@findtarg.findcomponenttarget); + finally + findtarg.destroy(); + end; +end; + +procedure objecttovalues(const source: tobject; const dest: tmsecomponent; + const prefix: string = ''); +var + findtarg: tfindtarg; + objinfo: objectinfoty; +begin + objinfo.obj:= source; + objinfo.prefix:= prefix; + findtarg:= tfindtarg.create(); + try + findtarg.fowner:= dest; + objecttovalues(objinfo,@findtarg.findcomponenttarget); + finally + findtarg.destroy(); + end; +end; + +{$endif} + +{ tcustomrttistat } + +procedure tcustomrttistat.statreading; +var + ar1: objectinfoarty; + intf1: istatfile; + int1: integer; +begin + if assigned(fonstatbeforeread) then begin + fonstatbeforeread(self); + end; + if getobj(ar1) then begin + for int1:= 0 to high(ar1) do begin + if mseclasses.getcorbainterface(ar1[int1].obj,typeinfo(istatfile), + intf1) then begin + intf1.statreading; + end; + end; + end; +end; + +procedure tcustomrttistat.statread; +var + ar1: objectinfoarty; + intf1: istatfile; + int1: integer; +begin + if assigned(fonstatafterread) then begin + fonstatafterread(self); + end; + if getobj(ar1) then begin + for int1:= 0 to high(ar1) do begin + if mseclasses.getcorbainterface(ar1[int1].obj,typeinfo(istatfile), + intf1) then begin + intf1.statread; + end; + end; + end; +end; + +function tcustomrttistat.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +function tcustomrttistat.getobj(out aobj: objectinfoarty): boolean; +var + obj1: tobject; + int1: integer; +begin + obj1:= nil; + aobj:= nil; + if assigned(fongetobject) then begin + fongetobject(self,obj1); + end; + if assigned(fongetobjects) then begin + fongetobjects(self,aobj); + end; + result:= (obj1 <> nil) or (aobj <> nil); + if obj1 <> nil then begin + for int1:= 0 to high(aobj) do begin + if aobj[int1].obj = obj1 then begin + exit; + end; + end; + setlength(aobj,high(aobj)+2); + aobj[high(aobj)].obj:= obj1; + end; +end; + +procedure tcustomrttistat.setstatfile(const avalue: tstatfile); +begin + setstatfilevar(istatfile(self),avalue,fstatfile); +end; + +procedure tcustomrttistat.dostatread(const reader: tstatreader); +var + obj1: objectinfoarty; + intf1: istatfile; + int1: integer; +begin + if getobj(obj1) then begin + for int1:= 0 to high(obj1) do begin + readobjectstat(reader,obj1[int1]); + with obj1[int1] do begin + if mseclasses.getcorbainterface(obj,typeinfo(istatfile),intf1) then begin + intf1.dostatread(reader); + end; + if obj is toptions then begin + toptions(obj).dostatread(reader); + toptions(obj).change(); + end; + end; + end; + end; + if assigned(fonstatupdate) then begin + fonstatupdate(self,reader); + end; + if assigned(fonstatread) then begin + fonstatread(self,reader); + end; +end; + +procedure tcustomrttistat.dostatwrite(const writer: tstatwriter); +var + obj1: objectinfoarty; + int1: integer; + intf1: istatfile; +begin + if getobj(obj1) then begin + for int1:= 0 to high(obj1) do begin + with obj1[int1] do begin + if obj is toptions then begin + toptions(obj).dostatwrite(writer); + end; + if mseclasses.getcorbainterface(obj1[int1].obj,typeinfo(istatfile), + intf1) then begin + intf1.dostatwrite(writer); + end; + end; + writeobjectstat(writer,obj1[int1]); + end; + end; + if assigned(fonstatupdate) then begin + fonstatupdate(self,writer); + end; + if assigned(fonstatwrite) then begin + fonstatwrite(self,writer); + end; +end; + +procedure tcustomrttistat.readstat(const areader: tstatreader); +begin + dostatread(areader); +end; + +procedure tcustomrttistat.writestat(const awriter: tstatwriter); +begin + dostatwrite(awriter); +end; + +{$ifdef mse_with_ifi} + +function tcustomrttistat.findtarget(const aname: string): tobject; +begin + ftargets.find(aname,pointer(result)); +end; + +procedure tcustomrttistat.scantargets(const aroot: tcomponent); + procedure addcomps(const acomp: tcomponent; prefix: string); + var + intf1: istatfile; + str1: string; + int1: integer; + begin + if acomp <> aroot then begin + if prefix <> '' then begin + prefix:= prefix + '_'; + end; + prefix:= prefix + acomp.name; + end; + for int1:= 0 to acomp.componentcount - 1 do begin + addcomps(acomp.components[int1],prefix); + end; + if (acomp <> aroot) and mseclasses.getcorbainterface(acomp, + typeinfo(istatfile),intf1) then begin + str1:= ansistring(intf1.getstatvarname); + if str1 = '' then begin + str1:= prefix; + end; + ftargets.add(str1,acomp); + end; + end; //addcomps + +begin + ftargets:= tpointeransistringhashdatalist.create; + addcomps(aroot,''); +end; + +procedure tcustomrttistat.valuestoobj(const sourceroot: tcomponent); +var + obj1: objectinfoarty; + int1: integer; +begin + if getobj(obj1) then begin + scantargets(sourceroot); + try + for int1:= 0 to high(obj1) do begin + valuestoobject(obj1[int1],{$ifdef FPC}@{$endif}findtarget); + end; + finally + freeandnil(ftargets); + end; + end; +end; + +procedure tcustomrttistat.objtovalues(const destroot: tcomponent); +var + obj1: objectinfoarty; + int1: integer; +begin + if getobj(obj1) then begin + scantargets(destroot); + try + for int1:= 0 to high(obj1) do begin + objecttovalues(obj1[int1],{$ifdef FPC}@{$endif}findtarget); + end; + finally + freeandnil(ftargets); + end; + end; +end; + +{$endif} + +function tcustomrttistat.getstatpriority: integer; +begin + result:= fstatpriority; +end; + + +{ trttistat } + +{ toptions } + +destructor toptions.destroy; +begin + gett.free; + gettexp.free; + inherited; +end; + +procedure toptions.readstat(const reader: tstatreader; const prefix: string); +var + info1: objectinfoty; +begin + info1.obj:= self; + info1.prefix:= prefix; + readobjectstat(reader,info1); + dostatread(reader); + change(); +end; + +procedure toptions.writestat(const writer: tstatwriter; + const prefix: string); +var + info1: objectinfoty; +begin + info1.obj:= self; + info1.prefix:= prefix; + dostatwrite(writer); + writeobjectstat(writer,info1); +end; + +{$ifdef mse_with_ifi} +procedure toptions.storevalues(const asource: tmsecomponent; + const prefix: string = ''); +begin + valuestoobject(asource,self,prefix); + change(); +end; + +procedure toptions.loadvalues(const adest: tmsecomponent; + const prefix: string = ''); +begin + objecttovalues(self,adest,prefix); +end; +{$endif} + +procedure toptions.dostatread(const reader: tstatreader); +begin + //dummy +end; + +procedure toptions.dostatwrite(const writer: tstatwriter); +begin + //dummy +end; + +procedure toptions.change(); +begin + //dummy +end; + +procedure toptions.dostatupdate(const filer: tstatfiler); +begin + if filer.iswriter then begin + dostatwrite(tstatwriter(filer)); + end + else begin + dostatread(tstatreader(filer)); + end; +end; + +procedure toptions.expandmacros(const amacrolist: tmacrolist); +var + ar1: propinfopoarty; + int1,int2: integer; + po1: ptypedata; + mstr1: msestring; + ar2: msestringarty; + t,texp: tobject; +begin + t:= gett; + texp:= gettexp; + if (t <> nil) and (texp <> nil) then begin + ar1:= getpropinfoar(t); + for int1:= 0 to high(ar1) do begin + po1:= gettypedata(ar1[int1]^.proptype{$ifndef FPC}^{$endif}); + case ar1[int1]^.proptype^.kind of + {$ifdef FPC} + tkustring: begin + mstr1:= getunicodestrprop(t,ar1[int1]); + amacrolist.expandmacros1(mstr1); + setunicodestrprop(texp,ar1[int1],mstr1); + {$else} + tkwstring: begin + mstr1:= getwidestrprop(t,ar1[int1]); + amacrolist.expandmacros(mstr1); + setwidestrprop(texp,ar1[int1],mstr1); + {$endif} + end; + tkdynarray: begin + {$ifdef FPC} + if ptypeinfo(pointer(po1^.eltype2))^.kind = tkustring then begin + //wrong define in ttypedata + {$else} + if po1^.eltype2^^.kind = tkwstring then begin + {$endif} + ar2:= copy(getmsestringar(t,ar1[int1])); + for int2:= 0 to high(ar2) do begin + amacrolist.expandmacros1(ar2[int2]); + end; + setmsestringar(texp,ar1[int1],ar2); + end; + end; + end; + end; + end; +end; + +procedure toptions.expandmacros(const macros: macroinfoarty; + const options: macrooptionsty = + [mao_caseinsensitive]); +var + list: tmacrolist; +begin + list:= tmacrolist.create(options); + try + list.add(macros); + expandmacros(list); + finally + list.free; + end; +end; + +procedure toptions.expandmacros(const anames,avalues: array of msestring; + const options: macrooptionsty = + [mao_caseinsensitive]); +begin + expandmacros(initmacros(anames,avalues,[]),options); +end; + +function toptions.gett: tobject; +begin + result:= nil; +end; + +function toptions.gettexp: tobject; +begin + result:= nil; +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/msescrollbar.pas b/mseide-msegui/lib/common/kernel/msescrollbar.pas new file mode 100644 index 0000000..1d1bc58 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msescrollbar.pas @@ -0,0 +1,1921 @@ +{ MSEgui Copyright (c) 1999-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msescrollbar; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface + +uses + mseguiglob,msegraphics,msegraphutils,msetimer,mseevent,mseshapes, + classes,mclasses,msetypes,msegui,mseclasses,mseglob; + +const + defaultscrollbarwidth = 15; + defaultpagesizeconst = 0.1; + defaultpagesize: real = defaultpagesizeconst; + defaultbuttonminlength = 11;//8; + defaultscrollbarcolorpattern = cl_scrollbarpattern; + defaultscrollbarcolorpatternclicked = cl_scrollbarpatternclicked; + repeatdelaytime = 500000; //0.5s + repeatrepeattime = 100000; //0.1 s + +type + + scrollbarareaty = (sbbu_down,sbbu_move,sbbu_up,sba_start,sba_end); +// buttonareaty = (bbu_down,bbu_move,bbu_up); +const + scrollbarclicked = ord(sba_end) + 1; +// areafrombuttonarea: array[buttonareaty] of scrollbarareaty = +// (sbbu_down,sbbu_move,sbbu_up); + +type + scrollbaroptionty = (sbo_thumbtrack,sbo_clicktovalue, + sbo_moveauto,sbo_showauto,sbo_show, + sbo_opposite,sbo_valuekeys,sbo_noarrowkeys,sbo_nopagekeys, + sbo_noreflectedclick{, + sbo_flat,sbo_noanim}); + //sbo_valuekeys -> pageup = valueincrement + scrollbaroptionsty = set of scrollbaroptionty; + +const + firstbutton = sbbu_down; + lastbutton = sbbu_up; + defaultscrollbaroptions = [sbo_moveauto,sbo_showauto]; + +type + tcustomscrollbar = class; + + scrolleventty = (sbe_none,sbe_valuechanged,sbe_setvalue, + sbe_stepup,sbe_stepdown, + sbe_pageup,sbe_pagedown,sbe_wheelup,sbe_wheeldown, + sbe_thumbposition,sbe_thumbtrack); + + iscrollbar = interface(inullinterface) + function getwidget: twidget; + function translatecolor(const acolor: colorty): colorty; + procedure invalidaterect(const rect: rectty; const org: originty; + const noclip: boolean = false); + procedure scrollevent(sender: tcustomscrollbar; event: scrolleventty); + end; + + scrollbardrawinfoty = record + frame: tframe; + outerrect: rectty; + dim: rectty; + scrollrect: rectty; +// buttonareas: array[buttonareaty] of rectty; + areas: array[scrollbarareaty] of shapeinfoty; + end; + + scrollbarstatety = (scs_mousecaptured,scs_streampagesize); + scrollbarstatesty = set of scrollbarstatety; + + beforescrollbareventty = procedure(const sender: tcustomscrollbar; + var akind: scrolleventty; var avalue: real) of object; + scrollbareventty = procedure(const sender: tcustomscrollbar; + const akind: scrolleventty; const avalue: real) of object; + //avalue = step or value + tcustomscrollbar = class(tnullinterfacedpersistent,iframe,iface) + private + forg: originty; +// fdim: rectty; + fdirection: graphicdirectionty; + fcolor: colorty; + fcolorpattern: colorty; + fcolorpatternclicked: colorty; + fvalue: real; + fbuttonlength: integer; + fpagesize: real; + fstepsize: real; + fclickedarea: scrollbarareaty; + frepeater: tsimpletimer; + fpickoffset: integer; + fpickpos: pointty; + fscrollrange: integer; + fbuttonminlength: integer; + fwidth: integer; +// ffacebutton: tface; +// ffaceendbutton: tface; +// fframebutton: tframe; +// fframeendbutton1: tframe; +// fframeendbutton2: tframe; + fface: tface; + fface1: tface; + fface2: tface; + fondimchanged: proceventty; + fbuttonendlength: integer; + fpaintedbutton: scrollbarareaty; + fonbeforeevent: beforescrollbareventty; + fonafterevent: scrollbareventty; + fstepctrlfact: real; + fstepshiftfact: real; + fwheelsensitivity: real; + procedure updatedim; + procedure setdirection(const avalue: graphicdirectionty); + procedure setcolor(const avalue: colorty); + procedure setcolorglyph(const avalue: colorty); + procedure invalidatepos; + procedure invalidateclickedarea; + procedure setvalue(Value: real); + procedure setbuttonlength(const avalue: integer); + procedure setpagesize(avalue: real); + function findarea(const point: pointty): scrollbarareaty; + procedure timer(const sender: tobject); + function dobuttoncommand: boolean; + procedure thumbtrack(var pos: pointty); + procedure setdim(const arect: rectty); + procedure setbuttonminlength(const avalue: integer); + procedure setwidth(const avalue: integer); + procedure setindentstart(const avalue: integer); + procedure setindentend(const avalue: integer); + function getstepsize: real; + procedure dodimchanged; + function clickedareaisvalid: boolean; + procedure setcolorpattern(const avalue: colorty); + procedure setcolorpatternclicked(const avalue: colorty); + function getface(): tface; + procedure setface(const avalue: tface); + function getfacebutton: tface; + procedure setfacebutton(const avalue: tface); + function getfaceendbutton: tface; + procedure setfaceendbutton(const avalue: tface); + procedure setbuttonendlength(const avalue: integer); + function getframebutton: tframe; + procedure setframebutton(const avalue: tframe); + function getframeendbutton1: tframe; + procedure setframeendbutton1(const avalue: tframe); + function getframeendbutton2: tframe; + procedure setframeendbutton2(const avalue: tframe); + procedure readstepsize(reader: treader); + procedure writestepsize(writer: twriter); + procedure readstepctrlfact(reader: treader); + procedure writestepctrlfact(writer: twriter); + procedure readstepshiftfact(reader: treader); + procedure writestepshiftfact(writer: twriter); + procedure readpagesize(reader: treader); + procedure writepagesize(writer: twriter); + procedure readwheelsensitivity(reader: treader); + procedure writewheelsensitivity(writer: twriter); + function getdisabled: boolean; + procedure setdisabled(const avalue: boolean); + function getface1: tface; + procedure setface1(const avalue: tface); + function getface2: tface; + procedure setface2(const avalue: tface); + function getframe: tframe; + procedure setframe(const avalue: tframe); + protected + fstate: scrollbarstatesty; + fintf: iscrollbar; + foptions: scrollbaroptionsty; + fdrawinfo: scrollbardrawinfoty; + findentstart,findentend: integer; + //iface + function translatecolor(const acolor: colorty): colorty; + function getclientrect: rectty; + procedure setlinkedvar(const source: tmsecomponent; var dest: tmsecomponent; + const linkintf: iobjectlink = nil); + procedure widgetregioninvalid; + //iframe + procedure setframeinstance(instance: tcustomframe); + procedure setstaticframe(value: boolean); + function getstaticframe: boolean; + procedure scrollwidgets(const dist: pointty); + procedure clientrectchanged; + function getcomponentstate: tcomponentstate; + function getmsecomponentstate: msecomponentstatesty; + procedure invalidatewidget; + procedure invalidaterect(const rect: rectty; + const org: originty = org_client; const noclip: boolean = false); + function getwidget: twidget; + function getwidgetrect: rectty; + function getframestateflags: framestateflagsty; + function getfocused: boolean; + procedure setfocused(const avalue: boolean); + function getshiftfact(ashiftstate: shiftstatesty; out fact: real): boolean; + //false if not valid + procedure setoptions(const avalue: scrollbaroptionsty); virtual; + procedure invalidate; + procedure dosetvalue(); + procedure dostep(akind: scrolleventty; astep: real); + procedure dothumbevent(const aevent: scrolleventty); + function dostepup(const ashiftstate: shiftstatesty): boolean; + function dostepdown(const ashiftstate: shiftstatesty): boolean; + procedure defineproperties(filer: tfiler); override; + function actualcolorpattern: colorty; + function actualcolorpatternclicked: colorty; +// function getbuttonarea(const apos: pointty): buttonareaty; //-1 -> none + public + tag: integer; + constructor create(intf: iscrollbar; org: originty = org_client; + ondimchanged: proceventty = nil); reintroduce; virtual; + destructor destroy; override; + + procedure createface(); + procedure createface1(); + procedure createface2(); + procedure createfacebutton; + procedure createfaceendbutton; + procedure createframe; + procedure createframebutton; + procedure createframeendbutton1; + procedure createframeendbutton2; + + procedure checktemplate(const sender: tobject); + procedure paint(const canvas: tcanvas; + const acolor: colorty = cl_none); virtual; + //color <> cl_none -> flat paint for grid cell + function wantmouseevent(const apos: pointty): boolean; + function buttonmoving(): boolean; //true if position button clicked + procedure mouseevent(var info: mouseeventinfoty); + procedure mousewheelevent(var info: mousewheeleventinfoty; + const pagingreversed: boolean = false); + procedure keydown(var info: keyeventinfoty); + procedure enter(); + procedure exit(); + property focused: boolean read getfocused write setfocused; + //does not invalidate + property disabled: boolean read getdisabled write setdisabled; + //does not invalidate + function clicked: boolean; + procedure activechanged; + + procedure stepup; + procedure stepdown; + procedure pageup; + procedure pagedown; + procedure wheelup(const shiftstate: shiftstatesty = []); + procedure wheeldown(const shiftstate: shiftstatesty = []); + + property direction: graphicdirectionty read fdirection write setdirection + default gd_right; + property value: real read fvalue write setvalue; + property dim: rectty read fdrawinfo.dim write setdim; + + property width: integer read fwidth write setwidth default defaultscrollbarwidth; + property indentstart: integer read findentstart write setindentstart default 0; + property indentend: integer read findentend write setindentend default 0; + // 0 default behavior (width ident if horz and vert visible), < 0 no ident + property options: scrollbaroptionsty read foptions write setoptions + default defaultscrollbaroptions; + property stepsize: real read getstepsize write fstepsize stored false; + //default = 0 -> pagesize /10 + property stepctrlfact: real read fstepctrlfact + write fstepctrlfact stored false; + //default = 0 -> no ctrl step + property stepshiftfact: real read fstepshiftfact + write fstepshiftfact stored false; + //default = 0 -> no shift step + property pagesize: real read fpagesize write setpagesize stored false; + //default = defaultpagesize + property wheelsensitivity: real read fwheelsensitivity + write fwheelsensitivity stored false; + //default = 1 + property buttonlength: integer read fbuttonlength + write setbuttonlength default 0; + //0 -> proportional -1 -> square + property buttonminlength: integer read fbuttonminlength + write setbuttonminlength default defaultbuttonminlength; + property buttonendlength: integer read fbuttonendlength + write setbuttonendlength default 0; + //0 -> square, -1 -> no endbuttons + property face: tface read getface write setface; + property face1: tface read getface1 write setface1; + property face2: tface read getface2 write setface2; + property facebutton: tface read getfacebutton write setfacebutton; + property faceendbutton: tface read getfaceendbutton write setfaceendbutton; + property frame: tframe read getframe write setframe; + property framebutton: tframe read getframebutton write setframebutton; + property frameendbutton1: tframe read getframeendbutton1 + write setframeendbutton1; + property frameendbutton2: tframe read getframeendbutton2 + write setframeendbutton2; + property color: colorty read fcolor write setcolor default cl_default; + property colorpattern: colorty read fcolorpattern + write setcolorpattern default cl_default; + //cl_none -> no pattern + property colorpatternclicked: colorty read fcolorpatternclicked + write setcolorpatternclicked default cl_default; + //cl_none -> no pattern + property colorglyph: colorty read fdrawinfo.areas[sbbu_down].ca.colorglyph + write setcolorglyph default cl_default; + //cl_none -> no no glyph + property onbeforeevent: beforescrollbareventty read fonbeforeevent + write fonbeforeevent; + property onafterevent: scrollbareventty read fonafterevent + write fonafterevent; + end; + + tcustomnomoveautoscrollbar = class(tcustomscrollbar) + protected + procedure setoptions(const avalue: scrollbaroptionsty); override; + public + constructor create(intf: iscrollbar; org: originty = org_client; + ondimchanged: proceventty = nil); override; + property options default defaultscrollbaroptions-[sbo_moveauto]; + end; + + + tnopagesizescrollbar = class(tcustomscrollbar) + published + property options; + property width; + property indentstart; + property indentend; + property stepctrlfact; + property stepshiftfact; + property wheelsensitivity; + property buttonlength; + property buttonminlength; + property buttonendlength; + property face; + property face1; + property face2; + property facebutton; + property faceendbutton; + property frame; + property framebutton; + property frameendbutton1; + property frameendbutton2; + property color; + property colorpattern; + property colorpatternclicked; + property colorglyph; + property onbeforeevent; + property onafterevent; + end; + + tscrollbar = class(tnopagesizescrollbar) + public + constructor create(intf: iscrollbar; org: originty = org_client; + ondimchanged: proceventty = nil); override; + published + property pagesize; + property stepsize; + end; + + tnomoveautonopagesizescrollbar = class(tcustomnomoveautoscrollbar) + published + property options; + property width; + property indentstart; + property indentend; + property stepctrlfact; + property stepshiftfact; + property wheelsensitivity; + property buttonlength; + property buttonminlength; + property buttonendlength; + property face; + property face1; + property face2; + property facebutton; + property faceendbutton; + property frame; + property framebutton; + property frameendbutton1; + property frameendbutton2; + property color; + property colorpattern; + property colorpatternclicked; + property colorglyph; + property onbeforeevent; + property onafterevent; + end; + + tnomoveautoscrollbar = class(tnomoveautonopagesizescrollbar) + public + constructor create(intf: iscrollbar; org: originty = org_client; + ondimchanged: proceventty = nil); override; + published + property stepsize; + property pagesize; + end; + +implementation + +uses + msestockobjects,sysutils,msekeyboard,msebits,msepointer,mseact; +type + twidget1 = class(twidget); +{ +const + buttonareatoscrollbararea: array[buttonareaty] of scrollbarareaty = + (sbbu_down,sbbu_move,sbbu_up); +} +{ tcustomscrollbar } + +constructor tcustomscrollbar.create(intf: iscrollbar; org: originty = org_client; + ondimchanged: proceventty = nil); +var + bu1: scrollbarareaty; +begin + foptions:= defaultscrollbaroptions; + fintf:= intf; + forg:= org; + fcolor:= cl_default; + fcolorpattern:= cl_default; + fcolorpatternclicked:= cl_default; + fdrawinfo.areas[sbbu_down].ca.colorglyph:= cl_default; + fdrawinfo.areas[sbbu_up].ca.colorglyph:= cl_default; + fclickedarea:= scrollbarareaty(-1); + fbuttonminlength:= defaultbuttonminlength; + fwidth:= defaultscrollbarwidth; + fondimchanged:= ondimchanged; + fpagesize:= defaultpagesize; + fwheelsensitivity:= 1; + for bu1:= low(scrollbarareaty) to high(scrollbarareaty) do begin + fdrawinfo.areas[bu1].color:= cl_transparent; + end; +end; + +procedure tcustomscrollbar.updatedim; +var + width1,scrolllength,buttonlength1: integer; + bu1: scrollbarareaty; + endblen: integer; + minblen: integer; + quadblen: integer; + + procedure checkscrolllength(const alength: integer); + var + int1: integer; + begin + scrolllength:= alength - endblen - endblen; + if (fbuttonlength < 0) then begin + int1:= scrolllength div 2; + if int1 < quadblen then begin + quadblen:= int1; + end; + end; + if scrolllength < 2 * minblen then begin + endblen:= (alength - 2 * minblen) div 2; + if endblen < minblen then begin + endblen:= alength div 4; + minblen:= endblen; + end; + if endblen < quadblen then begin + quadblen:= endblen; + end; + scrolllength:= alength - endblen - endblen; + end; + end; //checkscrollength +{ + procedure updatebutton(const button: scrollbarareaty); + var + po1: pshapeinfoty; + begin + po1:= @fdrawinfo.areas[scrollbarareaty(button)]; + frameskinoptionstoshapestate(po1^.frame,po1^); + end; //updatebutton +} +var + i1: int32; + +begin + scrolllength:= 0; + with fdrawinfo,dim do begin + dim:= outerrect; + if frame <> nil then begin + deflaterect1(dim,frame.innerframe); + end; + minblen:= fbuttonminlength; + areas[sbbu_up].ca.imagelist:= stockobjects.glyphs; + areas[sbbu_down].ca.imagelist:= stockobjects.glyphs; + areas[sbbu_down].imagenrdisabled:= -2; //grayed + areas[sbbu_move].imagenrdisabled:= -2; //grayed + areas[sbbu_up].imagenrdisabled:= -2; //grayed + if fdirection in [gd_right,gd_left] then begin + width1:= cy; + end + else begin + width1:= cx; + end; + quadblen:= width1; + if fbuttonendlength < 0 then begin + endblen:= 0; + end + else begin + if fbuttonendlength = 0 then begin + endblen:= width1; + end + else begin + endblen:= fbuttonendlength; + end; + end; + if fdirection in [gd_right,gd_left] then begin + checkscrolllength(cx); + scrollrect.x:= x + endblen; + scrollrect.y:= y; + scrollrect.cx:= scrolllength; + scrollrect.cy:= width1; + for bu1:= low(scrollbarareaty) to high(scrollbarareaty) do begin + areas[bu1].ca.dim.y:= y; + areas[bu1].ca.dim.cy:= width1; + end; + areas[sbbu_down].ca.dim.cx:= endblen; + areas[sbbu_up].ca.dim.cx:= endblen; + if fdirection = gd_right then begin + areas[sbbu_up].ca.imagenr:= ord(stg_arrowrightsmall); + areas[sbbu_down].ca.imagenr:= ord(stg_arrowleftsmall); + end + else begin + areas[sbbu_down].ca.imagenr:= ord(stg_arrowrightsmall); + areas[sbbu_up].ca.imagenr:= ord(stg_arrowleftsmall); + end; + end + else begin + checkscrolllength(cy); + scrollrect.x:= x; + scrollrect.y:= y + endblen; + scrollrect.cx:= width1; + scrollrect.cy:= scrolllength; + for bu1:= low(scrollbarareaty) to high(scrollbarareaty) do begin + areas[bu1].ca.dim.x:= x; + areas[bu1].ca.dim.cx:= width1; + end; + areas[sbbu_down].ca.dim.cy:= endblen; + areas[sbbu_up].ca.dim.cy:= endblen; + if fdirection = gd_down then begin + areas[sbbu_up].ca.imagenr:= ord(stg_arrowdownsmall); + areas[sbbu_down].ca.imagenr:= ord(stg_arrowupsmall); + end + else begin + areas[sbbu_down].ca.imagenr:= ord(stg_arrowdownsmall); + areas[sbbu_up].ca.imagenr:= ord(stg_arrowupsmall); + end; + end; + if fbuttonlength < 0 then begin + buttonlength1:= quadblen; + end + else begin + if fbuttonlength > 0 then begin + buttonlength1:= fbuttonlength; + end + else begin + buttonlength1:= round(pagesize * scrolllength); + end; + end; + if buttonlength1 < minblen then begin + buttonlength1:= minblen; + end; + if fbuttonlength > 0 then begin + i1:= scrolllength div 2; + if buttonlength1 > i1 then begin + buttonlength1:= i1; + end; + end; + if fdirection in [gd_right,gd_left] then begin + areas[sbbu_move].ca.dim.cx:= buttonlength1; + end + else begin + areas[sbbu_move].ca.dim.cy:= buttonlength1; + end; + fscrollrange:= scrolllength - buttonlength1; + case fdirection of + gd_right: begin + areas[sbbu_down].ca.dim.x:= x; + areas[sbbu_up].ca.dim.x:= x + cx - endblen; + areas[sbbu_move].ca.dim.x:= x + endblen + round(fvalue * fscrollrange); + areas[sba_start].ca.dim.x:= x + endblen; + areas[sba_start].ca.dim.cx:= areas[sbbu_move].ca.dim.x - + areas[sba_start].ca.dim.x; + areas[sba_end].ca.dim.x:= areas[sbbu_move].ca.dim.x + + areas[sbbu_move].ca.dim.cx; + areas[sba_end].ca.dim.cx:= areas[sbbu_up].ca.dim.x - areas[sba_end].ca.dim.x; + end; + gd_left: begin + areas[sbbu_up].ca.dim.x:= x; + areas[sbbu_down].ca.dim.x:= x + cx - endblen; + areas[sbbu_move].ca.dim.x:= x + cx - (endblen + round(fvalue * fscrollrange)) - + buttonlength1; + areas[sba_start].ca.dim.x:= areas[sbbu_move].ca.dim.x + + areas[sbbu_move].ca.dim.cx; + areas[sba_start].ca.dim.cx:= areas[sbbu_down].ca.dim.x - + areas[sba_start].ca.dim.x; + areas[sba_end].ca.dim.x:= x + endblen; + areas[sba_end].ca.dim.cx:= areas[sbbu_move].ca.dim.x - + areas[sba_end].ca.dim.x; + end; + gd_down: begin + areas[sbbu_down].ca.dim.y:= y; + areas[sbbu_up].ca.dim.y:= y + cy - endblen; + areas[sbbu_move].ca.dim.y:= y + endblen + round(fvalue * fscrollrange); + areas[sba_start].ca.dim.y:= y + endblen; + areas[sba_start].ca.dim.cy:= areas[sbbu_move].ca.dim.y - + areas[sba_start].ca.dim.y; + areas[sba_end].ca.dim.y:= areas[sbbu_move].ca.dim.y + + areas[sbbu_move].ca.dim.cy; + areas[sba_end].ca.dim.cy:= areas[sbbu_up].ca.dim.y - areas[sba_end].ca.dim.y; + end; + gd_up: begin + areas[sbbu_up].ca.dim.y:= y; + areas[sbbu_down].ca.dim.y:= y + cy - endblen; + areas[sbbu_move].ca.dim.y:= y + cy - (endblen + round(fvalue * fscrollrange)) - + buttonlength1; + areas[sba_start].ca.dim.y:= areas[sbbu_move].ca.dim.y + + areas[sbbu_move].ca.dim.cy; + areas[sba_start].ca.dim.cy:= areas[sbbu_down].ca.dim.y - + areas[sba_start].ca.dim.y; + areas[sba_end].ca.dim.y:= y + endblen; + areas[sba_end].ca.dim.cy:= areas[sbbu_move].ca.dim.y - + areas[sba_end].ca.dim.y; + end; + end; + end; +end; + +function tcustomscrollbar.findarea(const point: pointty): scrollbarareaty; +var + ar1: scrollbarareaty; +begin + result:= scrollbarareaty(-1); + for ar1:= low(scrollbarareaty) to high(scrollbarareaty) do begin + if pointinshape(point,fdrawinfo.areas[ar1]) then begin + result:= ar1; + break; + end; + end; +end; + +procedure tcustomscrollbar.invalidate; +begin + updatedim; + fintf.invalidaterect(fdrawinfo.outerrect,forg); +end; + +procedure tcustomscrollbar.invalidatepos; +begin + updatedim; + fintf.invalidaterect(fdrawinfo.scrollrect,forg); +end; + +function tcustomscrollbar.clickedareaisvalid: boolean; +begin + result:= (shortint(fclickedarea) >= 0) and + (shortint(fclickedarea) < scrollbarclicked); +end; + +procedure tcustomscrollbar.invalidateclickedarea; +begin + if clickedareaisvalid then begin + fintf.invalidaterect(fdrawinfo.areas[fclickedarea].ca.dim,forg); + end; +end; + +procedure tcustomscrollbar.setdim(const arect: rectty); +begin + fdrawinfo.outerrect:= arect; +// fdim:= arect; + invalidate; +end; + +procedure tcustomscrollbar.setbuttonlength(const avalue: integer); +begin + if fbuttonlength <> avalue then begin + fbuttonlength := avalue; + invalidate; + end; +end; + +procedure tcustomscrollbar.setbuttonendlength(const avalue: integer); +begin + if avalue <> fbuttonendlength then begin + fbuttonendlength := avalue; + invalidate; + end; +end; + +procedure tcustomscrollbar.setbuttonminlength(const avalue: integer); +begin + if fbuttonminlength <> avalue then begin + fbuttonminlength:= avalue; + invalidate; + end; +end; + +procedure tcustomscrollbar.setwidth(const avalue: integer); +begin + if fwidth <> avalue then begin + fwidth := avalue; + dodimchanged; + end; +end; + +procedure tcustomscrollbar.setindentstart(const avalue: integer); +begin + if findentstart <> avalue then begin + findentstart := avalue; + dodimchanged; + end; +end; + +procedure tcustomscrollbar.setindentend(const avalue: integer); +begin + if findentend <> avalue then begin + findentend := avalue; + dodimchanged; + end; +end; + +procedure tcustomscrollbar.setdirection(const avalue: graphicdirectionty); +begin + if fdirection <> avalue then begin + fdirection := avalue; + invalidate; + end; +end; + +procedure tcustomscrollbar.setcolor(const avalue: colorty); +begin + if fcolor <> avalue then begin + fcolor := avalue; + invalidate; + end; +end; + +procedure tcustomscrollbar.setcolorglyph(const avalue: colorty); +begin + if fdrawinfo.areas[sbbu_down].ca.colorglyph <> avalue then begin + fdrawinfo.areas[sbbu_down].ca.colorglyph:= avalue; + fdrawinfo.areas[sbbu_up].ca.colorglyph:= avalue; + invalidate; + end; +end; + +procedure tcustomscrollbar.setcolorpattern(const avalue: colorty); +begin + if fcolorpattern <> avalue then begin + fcolorpattern := avalue; + invalidate; + end; +end; + +procedure tcustomscrollbar.setcolorpatternclicked(const avalue: colorty); +begin + if fcolorpatternclicked <> avalue then begin + fcolorpatternclicked := avalue; + invalidate; + end; +end; + +procedure tcustomscrollbar.paint(const canvas: tcanvas; + const acolor: colorty = cl_none); +var + col1: colorty; + statebefore: shapestatesty; +begin + with canvas,self.fdrawinfo do begin + save(); + if acolor = cl_none then begin + col1:= fcolor; + end + else begin + col1:= acolor; + end; + col1:= fintf.translatecolor(col1); + canvas.fillrect(dim,col1); + if frame <> nil then begin + frame.paintbackground(canvas,outerrect,true,false); + end; + if fface <> nil then begin + fface.paint(canvas,fdrawinfo.scrollrect); + end; + if fface1 <> nil then begin + fface1.paint(canvas,areas[sba_start].ca.dim); + end; + if fface2 <> nil then begin + fface2.paint(canvas,areas[sba_end].ca.dim); + end; + fpaintedbutton:= firstbutton; + while fpaintedbutton <= lastbutton do begin + if acolor <> cl_none then begin + with areas[fpaintedbutton] do begin + statebefore:= state; + state:= state - [shs_mouse,shs_clicked]; + end; + end; +// fillrect(areas[fpaintedbutton].ca.dim,col1); +// areas[fpaintedbutton].color:= col1; + drawtoolbutton(canvas,areas[fpaintedbutton]); + if acolor <> cl_none then begin + areas[fpaintedbutton].state:= statebefore; + end; + inc(fpaintedbutton); + end; + if fface = nil then begin + colorbackground:= col1; + brush:= stockobjects.bitmaps[stb_dens50]; + if fface1 = nil then begin + if fclickedarea = sba_start then begin + color:= actualcolorpatternclicked(); + end + else begin + color:= actualcolorpattern(); + end; + if color <> cl_none then begin + fillrect(areas[sba_start].ca.dim,cl_brushcanvas); + end + else begin +// fillrect(areas[sba_start].ca.dim,col1); + end; + end; + if fface2 = nil then begin + if fclickedarea = sba_end then begin + color:= actualcolorpatternclicked(); + end + else begin + color:= actualcolorpattern(); + end; + if color <> cl_none then begin + fillrect(areas[sba_end].ca.dim,cl_brushcanvas); + end + else begin +// fillrect(areas[sba_end].ca.dim,col1); + end; + end; + end; + restore; + if frame <> nil then begin + frame.paintoverlay(canvas,outerrect); + end; + end; +end; + +procedure tcustomscrollbar.setvalue(Value: real); +begin + if value < 0 then begin + value:= 0; + end + else begin + if value > 1 then begin + value:= 1; + end; + end; + if fvalue <> value then begin + fvalue := Value; + invalidatepos; + fintf.scrollevent(self,sbe_valuechanged); + end; +end; + +procedure tcustomscrollbar.setpagesize(avalue: real); +begin + if avalue < 0 then begin + avalue:= 0; + end; + if avalue > 1 then begin + avalue:= 1; + end; + if fpagesize <> avalue then begin + fpagesize:= avalue; + invalidate; + end; +end; + +procedure tcustomscrollbar.dodimchanged; +begin + if assigned(fondimchanged) then begin + fondimchanged; + end; + invalidate; +end; + +procedure tcustomscrollbar.setoptions(const avalue: scrollbaroptionsty); +var + aoptions: scrollbaroptionsty; +const + mask: scrollbaroptionsty = [sbo_showauto,sbo_show]; +begin + aoptions:= scrollbaroptionsty(setsinglebit( + {$ifdef FPC}longword{$else}word{$endif}(avalue), + {$ifdef FPC}longword{$else}word{$endif}(foptions), + {$ifdef FPC}longword{$else}word{$endif}(mask))); + if aoptions <> foptions then begin + foptions:= aoptions; + dodimchanged; + end; +end; + +function tcustomscrollbar.getstepsize: real; +begin + if fstepsize = 0 then begin + result:= fpagesize / 10; + end + else begin + result:= fstepsize; + end; +end; + +function tcustomscrollbar.dobuttoncommand: boolean; +begin + result:= true; + case fclickedarea of + sbbu_up: begin + result:= dostepup(application.lastshiftstate*keyshiftstatesmask); + end; + sbbu_down: begin + dostepdown(application.lastshiftstate*keyshiftstatesmask); + end; + sba_start: begin + pagedown; + end; + sba_end: begin + pageup; + end; + else begin + result:= false; + end; + end; +end; + +procedure tcustomscrollbar.thumbtrack(var pos: pointty); +var + apos: integer; +begin + if fscrollrange <> 0 then begin + case fdirection of + gd_right: apos:= pos.x + fpickoffset; + gd_up: apos:= fpickoffset - pos.y; + gd_left: apos:= fpickoffset - pos.x; + else apos:= pos.y + fpickoffset; //gd_down + end; + value:= apos / fscrollrange; + end; +end; + +function tcustomscrollbar.wantmouseevent(const apos: pointty): boolean; +begin + result:= (fclickedarea <> scrollbarareaty(-1)) or + (findarea(apos) <> scrollbarareaty(-1)); +end; + +function tcustomscrollbar.buttonmoving(): boolean; +begin + result:= fclickedarea = sbbu_move; +end; + +procedure tcustomscrollbar.mouseevent(var info: mouseeventinfoty); + + procedure releasebutton(const cancel: boolean); + begin + if scs_mousecaptured in fstate then begin + exclude(fstate,scs_mousecaptured); + fintf.getwidget.releasemouse; + end; + freeandnil(frepeater); + if clickedareaisvalid then begin + exclude(fdrawinfo.areas[fclickedarea].state,shs_clicked); + invalidateclickedarea; + end; + if (fclickedarea = sbbu_move) and not cancel then begin + thumbtrack(info.pos); + fintf.scrollevent(self,sbe_thumbposition); + dothumbevent(sbe_thumbposition); + end; + fclickedarea:= scrollbarareaty(-1); + end; + +var + isclicktovalue: boolean; + + procedure mousemove(ar1: scrollbarareaty); + var + ar2: scrollbarareaty; + begin + if ord(ar1) >= 0 then begin + application.widgetcursorshape:= cr_arrow; + end; + if clickedareaisvalid then begin + if (ar1 <> fclickedarea) and (fclickedarea <> sbbu_move) and + ((frepeater = nil) or + not (fclickedarea in[sba_start,sba_end])) then begin + releasebutton(false); + fclickedarea:= scrollbarareaty(scrollbarclicked); + end; + if (fclickedarea = sbbu_move) then begin + ar1:= sbbu_move;{scrollbarareaty(-1);} + if (info.eventkind = ek_mousemove) or isclicktovalue then begin + thumbtrack(info.pos); + if sbo_thumbtrack in foptions then begin + fintf.scrollevent(self,sbe_thumbtrack); + dothumbevent(sbe_thumbtrack); + end; + end; + include(info.eventstate,es_processed); + end; + end; + for ar2:= firstbutton to lastbutton do begin + with fdrawinfo,areas[ar2] do begin + if (ar2 = ar1) then begin + if not (shs_mouse in state) then begin + include(state,shs_mouse); + fintf.invalidaterect(dim,forg); + end; + end + else begin + if shs_mouse in state then begin + exclude(state,shs_mouse); + fintf.invalidaterect(dim,forg); + end; + end; + end; + end; + end; + +var + ar1: scrollbarareaty; +begin + if (info.eventkind in mouseposevents) and (info.shiftstate * + (keyshiftstatesmask + [ss_middle,ss_right]) = []) and + not (info.button in [mb_right,mb_middle]) then begin + ar1:= findarea(info.pos); + if (ar1 = scrollbarareaty(-1)) and clickedareaisvalid then begin + ar1:= scrollbarareaty(scrollbarclicked); + end; + end + else begin + ar1:= scrollbarareaty(-1); + end; + if ar1 <> scrollbarareaty(-1) then begin + include(info.eventstate,es_processed); + end; + if (info.eventkind = ek_clientmouseleave) and (forg = org_client) or + (info.eventkind = ek_mouseleave) and (forg = org_widget) then begin + releasebutton(true); + mousemove(scrollbarareaty(-1)); + end + else begin + case info.eventkind of + ek_mousemove,ek_mousepark: begin + mousemove(ar1); + if fclickedarea = scrollbarareaty(-1) then begin + exclude(info.eventstate,es_processed); + end; + end; + ek_buttonpress: begin + if (info.button = mb_left) and + (not(sbo_noreflectedclick in foptions) or + not (es_reflected in info.eventstate)) then begin + + isclicktovalue:= (ar1 in [sba_start,sba_end,sbbu_move]) and + ((info.shiftstate * keyshiftstatesmask = [ss_ctrl]) or + (sbo_clicktovalue in foptions)); + if isclicktovalue then begin + ar1:= sbbu_move; + end; + fclickedarea:= ar1; + if clickedareaisvalid then begin + include(fdrawinfo.areas[fclickedarea].state,shs_clicked); + with fintf.getwidget do begin + if not mousecaptured then begin + capturemouse(true); + include(fstate,scs_mousecaptured); + end; + end; + end; + invalidateclickedarea; + if dobuttoncommand then begin + frepeater:= tsimpletimer.create(repeatdelaytime, + {$ifdef FPC}@{$endif}timer,true,[to_single]); + end + else begin + if fclickedarea = sbbu_move then begin + fpickpos:= info.pos; + if isclicktovalue then begin + with fdrawinfo.areas[sbbu_move].ca.dim do begin + case fdirection of + gd_right: fpickoffset:=-fdrawinfo.areas[sba_start].ca.dim.x - + cx div 2; + gd_up: fpickoffset:= fdrawinfo.areas[sba_start].ca.dim.cy + y + + cy div 2; + gd_left: fpickoffset:= fdrawinfo.areas[sba_start].ca.dim.cx + x + + cx div 2; + gd_down: fpickoffset:= -fdrawinfo.areas[sba_start].ca.dim.y - + cy div 2 ; + end; + end; + end + else begin + with fdrawinfo.areas[sbbu_move].ca.dim do begin + case fdirection of + gd_right: fpickoffset:= x - info.pos.x - + fdrawinfo.areas[sba_start].ca.dim.x; + gd_up: fpickoffset:= fdrawinfo.areas[sba_start].ca.dim.cy + + info.pos.y; + gd_left: fpickoffset:= fdrawinfo.areas[sba_start].ca.dim.cx + + info.pos.x; + gd_down: fpickoffset:= y - info.pos.y - + fdrawinfo.areas[sba_start].ca.dim.y; + end; + end; + end; + if isclicktovalue then begin + mousemove(ar1); + end; + end; + end; + end; + end; + ek_buttonrelease: begin + if info.button = mb_left then begin + releasebutton(false); + end; + end; + end; + end; +end; + +procedure tcustomscrollbar.mousewheelevent(var info: mousewheeleventinfoty; + const pagingreversed: boolean = false); +begin + with info do begin + include(eventstate,es_processed); + if (wheel = mw_down) xor (fdirection in [gd_right,gd_down]) then begin + if (fstepctrlfact <> 0) or (fstepshiftfact <> 0) then begin + wheeldown(shiftstate); + end + else begin + if (ss_ctrl in shiftstate) xor pagingreversed then begin + pagedown; + end + else begin + wheeldown; + end; + end; + end + else begin + if (fstepctrlfact <> 0) or (fstepshiftfact <> 0) then begin + wheelup(shiftstate); + end + else begin + if (ss_ctrl in shiftstate) xor pagingreversed then begin + pageup; + end + else begin + wheelup; + end; + end; + end; + end; +end; + +function tcustomscrollbar.getshiftfact(ashiftstate: shiftstatesty; + out fact: real): boolean; + //false if not valid +begin + fact:= 1; + ashiftstate:= ashiftstate * shiftstatesmask; + result:= ashiftstate = []; + if not result then begin + if (ashiftstate = [ss_ctrl]) and (fstepctrlfact <> 0) then begin + fact:= fstepctrlfact; + result:= true; + end + else begin + if (ashiftstate = [ss_shift]) and (fstepshiftfact <> 0) then begin + fact:= fstepshiftfact; + result:= true; + end + end; + end; +end; + +function tcustomscrollbar.dostepup(const ashiftstate: shiftstatesty): boolean; +var + fact1: real; +begin + result:= getshiftfact(ashiftstate,fact1); + if result then begin + dostep(sbe_stepup,stepsize*fact1); + end; +end; //dostepup + +function tcustomscrollbar.dostepdown(const ashiftstate: shiftstatesty): boolean; +var + fact1: real; +begin + result:= getshiftfact(ashiftstate,fact1); + if result then begin + dostep(sbe_stepdown,-stepsize*fact1); + end; +end; + +procedure tcustomscrollbar.keydown(var info: keyeventinfoty); + + procedure dopageup; + begin + if info.shiftstate * shiftstatesmask = [ss_ctrl] then begin + value:= 1; + end + else begin + pageup; + end; + end; //dopageup + + procedure dopagedown; + begin + if info.shiftstate * shiftstatesmask = [ss_ctrl] then begin + value:= 0; + end + else begin + pagedown; + end; + end; //dopagedown + +var + bo1: boolean; + +begin + with info do begin + if not (es_processed in eventstate) then begin + if (not (sbo_noarrowkeys in foptions) or + (key <> key_left) and (key <> key_right) and + (key <> key_up) and (key <> key_down)) and + (not (sbo_nopagekeys in foptions) or + (key <> key_pageup) and (key <> key_pagedown)) then begin + bo1:= true; + if sbo_valuekeys in foptions then begin + case info.key of + key_pageup: dopageup; + key_pagedown: dopagedown; + key_up: bo1:= dostepup(info.shiftstate); + key_down: bo1:= dostepdown(info.shiftstate); + else begin + bo1:= false; + end; + end; + end + else begin + case fdirection of + gd_right: begin + case info.key of + key_right: bo1:= dostepup(info.shiftstate); + key_left: bo1:= dostepdown(info.shiftstate); + key_pageup: dopageup; + key_pagedown: dopagedown; + else begin + bo1:= false; + end; + end; + end; + gd_up: begin + case info.key of + key_up: bo1:= dostepdown(info.shiftstate); + key_down: bo1:= dostepup(info.shiftstate); + key_pageup: dopageup; + key_pagedown: dopagedown; + else begin + bo1:= false; + end; + end; + end; + gd_left: begin + case info.key of + key_right: bo1:= dostepdown(info.shiftstate); + key_left: bo1:= dostepup(info.shiftstate); + key_pageup: dopageup; + key_pagedown: dopagedown; + else begin + bo1:= false; + end; + end; + end; + gd_down: begin + case info.key of + key_down: bo1:= dostepup(info.shiftstate); + key_up: bo1:= dostepdown(info.shiftstate); + key_pageup: dopagedown; + key_pagedown: dopageup; + else begin + bo1:= false; + end; + end; + end; + end; + end; + if bo1 then begin + include(eventstate,es_processed); + end; + end; + end; + end; +end; + +procedure tcustomscrollbar.dosetvalue(); +begin + fintf.scrollevent(self,sbe_setvalue); +end; + +procedure tcustomscrollbar.dostep(akind: scrolleventty; astep: real); +begin + if assigned(fonbeforeevent) then begin + fonbeforeevent(self,akind,astep); + end; + if akind <> sbe_none then begin + if sbo_moveauto in foptions then begin + value:= fvalue + astep; + dosetvalue(); + end; + fintf.scrollevent(self,akind); + if assigned(fonafterevent) then begin + fonafterevent(self,akind,astep); + end; + end; +end; + +procedure tcustomscrollbar.dothumbevent(const aevent: scrolleventty); +begin + dosetvalue(); + if assigned(fonafterevent) then begin + fonafterevent(self,aevent,value); + end; +end; + +procedure tcustomscrollbar.pagedown; +begin + dostep(sbe_pagedown,-pagesize); +end; + +procedure tcustomscrollbar.pageup; +begin + dostep(sbe_pageup,pagesize); +end; + +procedure tcustomscrollbar.wheeldown(const shiftstate: shiftstatesty = []); +var + fact1: real; +begin + getshiftfact(shiftstate,fact1); + dostep(sbe_wheeldown, + -application.mousewheelacceleration(stepsize)* + fwheelsensitivity*fact1); +end; + +procedure tcustomscrollbar.wheelup(const shiftstate: shiftstatesty = []); +var + fact1: real; +begin + getshiftfact(shiftstate,fact1); + dostep(sbe_wheelup, + application.mousewheelacceleration(stepsize)* + fwheelsensitivity*fact1); +end; + +procedure tcustomscrollbar.stepdown; +begin + dostep(sbe_stepdown,-stepsize); +end; + +procedure tcustomscrollbar.stepup; +begin + dostep(sbe_stepup,stepsize); +end; + +destructor tcustomscrollbar.destroy; +begin + freeandnil(frepeater); + inherited; + fface.free(); + fface1.free(); + fface2.free(); + fdrawinfo.areas[sbbu_move].face.free; + fdrawinfo.areas[sbbu_up].face.free; + fdrawinfo.frame.free; + fdrawinfo.areas[sbbu_down].frame.free; + fdrawinfo.areas[sbbu_move].frame.free; + fdrawinfo.areas[sbbu_up].frame.free; +// ffacebutton.free; +// ffaceendbutton.free; +// fframebutton.free; +// fframeendbutton1.free; +// fframeendbutton2.free; +end; + +procedure tcustomscrollbar.timer(const sender: tobject); +begin + dobuttoncommand; + with tsimpletimer(sender) do begin + if singleshot then begin + singleshot:= false; + interval:= repeatrepeattime; + enabled:= true; + end; + end; +end; + +procedure tcustomscrollbar.enter; +begin + with fdrawinfo,areas[sbbu_move] do begin + include(state,shs_focused); + fintf.invalidaterect(ca.dim,forg); + end; +end; + +procedure tcustomscrollbar.exit; +begin + with fdrawinfo,areas[sbbu_move] do begin + exclude(fdrawinfo.areas[sbbu_move].state,shs_focused); + fintf.invalidaterect(ca.dim,forg); + end; +end; + +function tcustomscrollbar.getfocused: boolean; +begin + result:= shs_focused in fdrawinfo.areas[sbbu_move].state; +end; + +procedure tcustomscrollbar.setfocused(const avalue: boolean); +begin + if avalue then begin + include(fdrawinfo.areas[sbbu_move].state,shs_focused); + end + else begin + exclude(fdrawinfo.areas[sbbu_move].state,shs_focused); + end; +end; + +function tcustomscrollbar.getdisabled: boolean; +begin + result:= shs_disabled in fdrawinfo.areas[sbbu_move].state; +end; + +procedure tcustomscrollbar.setdisabled(const avalue: boolean); +begin + if avalue then begin + include(fdrawinfo.areas[sbbu_down].state,shs_disabled); + include(fdrawinfo.areas[sbbu_move].state,shs_disabled); + include(fdrawinfo.areas[sbbu_up].state,shs_disabled); + end + else begin + exclude(fdrawinfo.areas[sbbu_down].state,shs_disabled); + exclude(fdrawinfo.areas[sbbu_move].state,shs_disabled); + exclude(fdrawinfo.areas[sbbu_up].state,shs_disabled); + end; +end; + +procedure tcustomscrollbar.createfacebutton; +begin + if fdrawinfo.areas[sbbu_move].face = nil then begin + fdrawinfo.areas[sbbu_move].face:= tface.create(iface(fintf.getwidget)); + end; +end; + +procedure tcustomscrollbar.createface; +begin + if fface = nil then begin + fface:= tface.create(iface(self)); + end; +end; + +procedure tcustomscrollbar.createface1(); +begin + if fface1 = nil then begin + fface1:= tface.create(iface(self)); + end; +end; + +procedure tcustomscrollbar.createface2(); +begin + if fface2 = nil then begin + fface2:= tface.create(iface(self)); + end; +end; + +function tcustomscrollbar.getface: tface; +begin + fintf.getwidget.getoptionalobject(fface, + {$ifdef FPC}@{$endif}createface); + result:= fface; +end; + +procedure tcustomscrollbar.setface(const avalue: tface); +begin + fintf.getwidget.setoptionalobject(avalue,fface, + {$ifdef FPC}@{$endif}createface); + invalidate; +// fface.assign(avalue); +end; + +function tcustomscrollbar.getface1: tface; +begin + fintf.getwidget.getoptionalobject(fface1, + {$ifdef FPC}@{$endif}createface1); + result:= fface1; +end; + +procedure tcustomscrollbar.setface1(const avalue: tface); +begin + fintf.getwidget.setoptionalobject(avalue,fface1, + {$ifdef FPC}@{$endif}createface1); + invalidate; +end; + +function tcustomscrollbar.getface2: tface; +begin + fintf.getwidget.getoptionalobject(fface2, + {$ifdef FPC}@{$endif}createface2); + result:= fface2; +end; + +procedure tcustomscrollbar.setface2(const avalue: tface); +begin + fintf.getwidget.setoptionalobject(avalue,fface2, + {$ifdef FPC}@{$endif}createface2); + invalidate; +end; + +function tcustomscrollbar.getfacebutton: tface; +begin + fintf.getwidget.getoptionalobject(fdrawinfo.areas[sbbu_move].face, + {$ifdef FPC}@{$endif}createfacebutton); + result:= tface(fdrawinfo.areas[sbbu_move].face); +end; + +procedure tcustomscrollbar.setfacebutton(const avalue: tface); +begin + fintf.getwidget.setoptionalobject(avalue,fdrawinfo.areas[sbbu_move].face, + {$ifdef FPC}@{$endif}createfacebutton); + invalidate; +end; + +procedure tcustomscrollbar.createfaceendbutton; +begin + if fdrawinfo.areas[sbbu_up].face = nil then begin + fdrawinfo.areas[sbbu_up].face:= tface.create(iface(fintf.getwidget)); + fdrawinfo.areas[sbbu_down].face:= fdrawinfo.areas[sbbu_up].face; + end; +end; + +function tcustomscrollbar.getfaceendbutton: tface; +begin + fintf.getwidget.getoptionalobject(fdrawinfo.areas[sbbu_up].face, + {$ifdef FPC}@{$endif}createfaceendbutton); + result:= tface(fdrawinfo.areas[sbbu_up].face); +end; + +procedure tcustomscrollbar.setfaceendbutton(const avalue: tface); +begin + fintf.getwidget.setoptionalobject(avalue,fdrawinfo.areas[sbbu_up].face, + {$ifdef FPC}@{$endif}createfaceendbutton); + invalidate; +end; + +procedure tcustomscrollbar.createframe; +begin + if fdrawinfo.frame = nil then begin + fdrawinfo.frame:= tframe.create(iframe(self)); + end; +end; + +procedure tcustomscrollbar.createframebutton; +begin + if fdrawinfo.areas[sbbu_move].frame = nil then begin + fdrawinfo.areas[sbbu_move].frame:= tframe.create(iframe(self)); + end; +end; + +function tcustomscrollbar.getframe: tframe; +begin + fintf.getwidget.getoptionalobject(fdrawinfo.frame,@createframe); + result:= tframe(fdrawinfo.frame); +end; + +procedure tcustomscrollbar.setframe(const avalue: tframe); +begin + fintf.getwidget.setoptionalobject(avalue,fdrawinfo.frame,@createframe); + invalidate; +end; + +function tcustomscrollbar.getframebutton: tframe; +begin + fintf.getwidget.getoptionalobject(fdrawinfo.areas[sbbu_move].frame, + {$ifdef FPC}@{$endif}createframebutton); + result:= tframe(fdrawinfo.areas[sbbu_move].frame); +end; + +procedure tcustomscrollbar.setframebutton(const avalue: tframe); +begin + fintf.getwidget.setoptionalobject(avalue,fdrawinfo.areas[sbbu_move].frame, + {$ifdef FPC}@{$endif}createframebutton); + invalidate; +end; + +procedure tcustomscrollbar.createframeendbutton1; +begin + if fdrawinfo.areas[sbbu_down].frame = nil then begin + fdrawinfo.areas[sbbu_down].frame:= tframe.create(iframe(self)); + end; +end; + +function tcustomscrollbar.getframeendbutton1: tframe; +begin + fintf.getwidget.getoptionalobject(fdrawinfo.areas[sbbu_down].frame, + {$ifdef FPC}@{$endif}createframeendbutton1); + result:= tframe(fdrawinfo.areas[sbbu_down].frame); +end; + +procedure tcustomscrollbar.setframeendbutton1(const avalue: tframe); +begin + fintf.getwidget.setoptionalobject(avalue,fdrawinfo.areas[sbbu_down].frame, + {$ifdef FPC}@{$endif}createframeendbutton1); + invalidate; +end; + +procedure tcustomscrollbar.createframeendbutton2; +begin + if fdrawinfo.areas[sbbu_up].frame = nil then begin + fdrawinfo.areas[sbbu_up].frame:= tframe.create(iframe(self)); + end; +end; + +function tcustomscrollbar.getframeendbutton2: tframe; +begin + fintf.getwidget.getoptionalobject(fdrawinfo.areas[sbbu_up].frame, + {$ifdef FPC}@{$endif}createframeendbutton2); + result:= tframe(fdrawinfo.areas[sbbu_up].frame); +end; + +procedure tcustomscrollbar.setframeendbutton2(const avalue: tframe); +begin + fintf.getwidget.setoptionalobject(avalue,fdrawinfo.areas[sbbu_up].frame, + {$ifdef FPC}@{$endif}createframeendbutton2); + invalidate; +end; + +function tcustomscrollbar.clicked: boolean; +begin + result:= fclickedarea <> scrollbarareaty(-1); +end; + +procedure tcustomscrollbar.checktemplate(const sender: tobject); +begin + if fface <> nil then begin + fface.checktemplate(sender); + end; + if fface1 <> nil then begin + fface1.checktemplate(sender); + end; + if fface2 <> nil then begin + fface2.checktemplate(sender); + end; + if fdrawinfo.areas[sbbu_move].face <> nil then begin + fdrawinfo.areas[sbbu_move].face.checktemplate(sender); + end; + if fdrawinfo.areas[sbbu_down].face <> nil then begin + fdrawinfo.areas[sbbu_down].face.checktemplate(sender); + end; + if fdrawinfo.areas[sbbu_move].frame <> nil then begin + fdrawinfo.areas[sbbu_move].frame.checktemplate(sender); + end; + if fdrawinfo.areas[sbbu_down].frame <> nil then begin + fdrawinfo.areas[sbbu_down].frame.checktemplate(sender); + end; + if fdrawinfo.areas[sbbu_up].frame <> nil then begin + fdrawinfo.areas[sbbu_up].frame.checktemplate(sender); + end; +end; + +procedure tcustomscrollbar.setframeinstance(instance: tcustomframe); +begin + //dummy +end; + +procedure tcustomscrollbar.setstaticframe(value: boolean); +begin + //dummy +end; + +function tcustomscrollbar.getstaticframe: boolean; +begin + result:= false; +end; + +procedure tcustomscrollbar.scrollwidgets(const dist: pointty); +begin + //dumy +end; + +procedure tcustomscrollbar.clientrectchanged; +begin + invalidate; +end; + +function tcustomscrollbar.getcomponentstate: tcomponentstate; +begin + result:= fintf.getwidget.componentstate; +end; + +function tcustomscrollbar.getmsecomponentstate: msecomponentstatesty; +begin + result:= fintf.getwidget.msecomponentstate; +end; + +procedure tcustomscrollbar.invalidatewidget; +begin + invalidate; +end; + +procedure tcustomscrollbar.invalidaterect(const rect: rectty; + const org: originty = org_client; const noclip: boolean = false); +begin + invalidate; +end; + +function tcustomscrollbar.getwidget: twidget; +begin + result:= fintf.getwidget; +end; + +function tcustomscrollbar.getwidgetrect: rectty; +begin + result:= fdrawinfo.outerrect; +// result:= fdim; +end; + +function tcustomscrollbar.getframestateflags: framestateflagsty; +begin + with fdrawinfo.areas[fpaintedbutton],fintf.getwidget do begin + result:= combineframestateflags(not isenabled,focused,active, + shs_mouse in state, shs_clicked in state); + end; +end; + +procedure tcustomscrollbar.activechanged; +begin + if (fdrawinfo.areas[sbbu_down].frame <> nil) or + (fdrawinfo.areas[sbbu_move].frame <> nil) or + (fdrawinfo.areas[sbbu_up].frame <> nil) then begin + invalidate; + end; +end; + +procedure tcustomscrollbar.readstepsize(reader: treader); +begin + stepsize:= reader.readfloat; +end; + +procedure tcustomscrollbar.writestepsize(writer: twriter); +begin + writer.writefloat(stepsize); +end; + +procedure tcustomscrollbar.readstepctrlfact(reader: treader); +begin + stepctrlfact:= reader.readfloat; +end; + +procedure tcustomscrollbar.writestepctrlfact(writer: twriter); +begin + writer.writefloat(stepctrlfact); +end; + +procedure tcustomscrollbar.readstepshiftfact(reader: treader); +begin + stepshiftfact:= reader.readfloat; +end; + +procedure tcustomscrollbar.writestepshiftfact(writer: twriter); +begin + writer.writefloat(stepshiftfact); +end; + +procedure tcustomscrollbar.readpagesize(reader: treader); +begin + pagesize:= reader.readfloat; +end; + +procedure tcustomscrollbar.writepagesize(writer: twriter); +begin + writer.writefloat(pagesize); +end; + +procedure tcustomscrollbar.readwheelsensitivity(reader: treader); +begin + wheelsensitivity:= reader.readfloat; +end; + +procedure tcustomscrollbar.writewheelsensitivity(writer: twriter); +begin + writer.writefloat(wheelsensitivity); +end; + +procedure tcustomscrollbar.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('stepsize',@readstepsize,@writestepsize, + (scs_streampagesize in fstate) and + ((filer.ancestor = nil) and (fstepsize <> 0) or + (filer.ancestor <> nil) and + (tcustomscrollbar(filer.ancestor).fstepsize <> fstepsize))); + filer.defineproperty('stepctrlfact',@readstepctrlfact,@writestepctrlfact, + (filer.ancestor = nil) and (fstepctrlfact <> 0) or + (filer.ancestor <> nil) and + (tcustomscrollbar(filer.ancestor).fstepctrlfact <> fstepctrlfact)); + filer.defineproperty('stepshiftfact',@readstepshiftfact,@writestepshiftfact, + (filer.ancestor = nil) and (fstepshiftfact <> 0) or + (filer.ancestor <> nil) and + (tcustomscrollbar(filer.ancestor).fstepshiftfact <> fstepshiftfact)); + filer.defineproperty('pagesize',@readpagesize,@writepagesize, + (scs_streampagesize in fstate) and + ((filer.ancestor = nil) and (fpagesize <> defaultpagesize) or + (filer.ancestor <> nil) and + (tcustomscrollbar(filer.ancestor).fpagesize <> fpagesize))); + filer.defineproperty('wheelsensitivity',@readwheelsensitivity,@writewheelsensitivity, + (filer.ancestor = nil) and (fwheelsensitivity <> 1) or + (filer.ancestor <> nil) and + (tcustomscrollbar(filer.ancestor).fwheelsensitivity <> fwheelsensitivity)); +end; + +function tcustomscrollbar.actualcolorpattern: colorty; +begin + result:= fcolorpattern; + if result = cl_default then begin + result:= cl_scrollbarpattern; + end; +end; + +function tcustomscrollbar.actualcolorpatternclicked: colorty; +begin + result:= fcolorpatternclicked; + if result = cl_default then begin + result:= cl_scrollbarpatternclicked; + end; +end; +{ +function tcustomscrollbar.getbuttonarea(const apos: pointty): buttonareaty; +var + bu1: buttonareaty; +begin + result:= buttonareaty(-1); //none + for bu1:= low(buttonareaty) to high(buttonareaty) do begin + if pointinrect(apos,fdrawinfo.buttonareas[bu1]) then begin + result:= bu1; + break; + end; + end; +end; +} +function tcustomscrollbar.translatecolor(const acolor: colorty): colorty; +begin + result:= fintf.translatecolor(acolor); +end; + +function tcustomscrollbar.getclientrect: rectty; +begin + result:= fintf.getwidget.clientrect; +end; + +procedure tcustomscrollbar.setlinkedvar(const source: tmsecomponent; + var dest: tmsecomponent; const linkintf: iobjectlink = nil); +begin + twidget1(fintf.getwidget).setlinkedvar(source,dest,linkintf); +end; + +procedure tcustomscrollbar.widgetregioninvalid; +begin + twidget1(fintf.getwidget).widgetregioninvalid; +end; + +{ tcustomnomoveautoscrollbar } + +constructor tcustomnomoveautoscrollbar.create(intf: iscrollbar; + org: originty; ondimchanged: proceventty); +begin + inherited; + foptions:= defaultscrollbaroptions-[sbo_moveauto]; +end; + +procedure tcustomnomoveautoscrollbar.setoptions( + const avalue: scrollbaroptionsty); +begin + inherited setoptions(avalue - [sbo_moveauto]); +end; + +{ tscrollbar } + +constructor tscrollbar.create(intf: iscrollbar; org: originty = org_client; + ondimchanged: proceventty = nil); +begin + inherited; + include(fstate,scs_streampagesize); +end; + +{ tnomoveautoscrollbar } + +constructor tnomoveautoscrollbar.create(intf: iscrollbar; + org: originty = org_client; ondimchanged: proceventty = nil); +begin + inherited; + include(fstate,scs_streampagesize); +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/mseshapes.pas b/mseide-msegui/lib/common/kernel/mseshapes.pas new file mode 100644 index 0000000..bf39356 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseshapes.pas @@ -0,0 +1,1700 @@ +{ MSEgui Copyright (c) 1999-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseshapes; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface +uses + msegraphics,msegraphutils,mseguiglob,msegui,mseevent,mserichstring,msebitmap, + msetypes,mseact,msestrings,msedrawtext; + +type + buttonoptionty = (bo_executeonclick,bo_executeonkey,bo_executeonshortcut, + bo_executedefaultonenterkey, + bo_asyncexecute, + bo_focusonshortcut,bo_focusonactionshortcut, + //for tcustombutton + bo_updateonidle, + bo_shortcutcaption,bo_altshortcut, + {bo_flat,bo_noanim,bo_nofocusrect,bo_nodefaultrect,} + bo_nodefaultframeactive, + bo_coloractive, + bo_ellipsemouse, //mouse area is elliptical + bo_nocandefocus,bo_candefocuswindow, //check own window only + bo_radioitem, //for tdatabutton + bo_radioitemcol, + bo_cantoggle, //for tbooleaneditradio + bo_resetcheckedonrowexit, + //used in tdatabutton + bo_reversed, //for tbooleanedit + bo_noassistivedisabled + ); + buttonoptionsty = set of buttonoptionty; + +const + defaultbuttonoptions = [bo_executeonclick,bo_executeonkey, + bo_executeonshortcut,bo_executedefaultonenterkey]; + + menuarrowwidth = 8; + menuarrowwidthhorz = 15; + menucheckboxwidth = 13; + menucheckboxheight = 13; + defaultshapecaptiondist = 2; + defaultshapefocusrectdist = 1; + defaultcaptiontextflags = [tf_left,tf_xcentered,tf_ycentered]; + +// styleactionstates: actionstatesty = [as_shortcutcaption,as_radiobutton]; +type + buttonedgety = (bedg_none,bedg_right,bedg_top,bedg_left,bedg_bottom); + + tagmouseprocty = procedure (const tag: integer; + const info: mouseeventinfoty) of object; + + captioninfoty = record + dim: rectty; + caption: richstringty; + font: tfont; + textflags: textflagsty; + imagepos: imageposty; + captiondist: integer; + imagenr: imagenrty; + colorglyph: colorty; + imagelist: timagelist; + imagedist: integer; + imagedist1: integer; //left or top + imagedist2: integer; //right or bottom + captionclipped: boolean; + end; + + shapeinfoty = record + ca: captioninfoty; + focusrectdist: integer; + state: shapestatesty; + tabpos: integer; + group: integer; + color: colorty; + coloractive: colorty; + facetemplate: tfacetemplate; + imagenrdisabled: integer; //-2 -> grayed + imagecheckedoffset: integer; + face: tcustomface; + frame: tcustomframe; + checkboxframe: tframetemplate; + mouseframe: framety; + tag: integer; + doexecute: tagmouseprocty; + end; + pshapeinfoty = ^shapeinfoty; + + shapeinfoarty = array of shapeinfoty; + pshapeinfoarty = ^shapeinfoarty; + + getbuttonhintty = function(const aindex: integer): msestring of object; + getbuttonhintposty = function(const aindex: integer): rectty of object; + +procedure updateedgerect(var arect: rectty; const awidth: integer; + const hiddenedges: edgesty); +procedure draw3dframe(const canvas: tcanvas; const arect: rectty; + level: integer; colorinfo: edgecolorpairinfoty; + const hiddenedges: edgesty); +procedure drawimageframe(const canvas: tcanvas; const imagelist: timagelist; + const imageoffs: int32; const dest: rectty; + const hiddenedges: edgesty); +procedure drawfocusrect(const canvas: tcanvas; const arect: rectty); +procedure drawtoolbutton(const canvas: tcanvas; var info: shapeinfoty); +procedure drawbutton(const canvas: tcanvas; const info: shapeinfoty); +procedure drawmenubutton(const canvas: tcanvas; var info: shapeinfoty; + const innerframe: pframety = nil); +procedure drawtab(const canvas: tcanvas; var info: shapeinfoty; + const innerframe: pframety = nil); +function updatemouseshapestate(var info: shapeinfoty; + const mouseevent: mouseeventinfoty; + const widget: twidget; const aframe: tcustomframe; + const infoarpo: pshapeinfoarty = nil; + const canclick: boolean = true): boolean; overload; +function updatemouseshapestate(var infos: shapeinfoarty; + const mouseevent: mouseeventinfoty; + const widget: twidget; var focuseditem: integer; + const aframe: tcustomframe = nil): boolean; overload; + //true on change, calls widget.invalidaterect +function getmouseshape(const infos: shapeinfoarty): integer; + //returns shape index under mouse, -1 if none +function updatewidgetshapestate(var info: shapeinfoty; const widget: twidget; + const adisabled: boolean = false; +// const ainvisible: boolean = false; + const aframe: tcustomframe = nil): boolean; +function findshapeatpos(const infoar: shapeinfoarty; const apos: pointty; + const rejectstates: shapestatesty = + [shs_disabled,shs_invisible]): integer; +function pointinshape(const pos: pointty; const info: shapeinfoty): boolean; +procedure initshapeinfo(var ainfo: shapeinfoty); + +procedure actioninfotoshapeinfo(var actioninfo: actioninfoty; + var shapeinfo: shapeinfoty); overload; +procedure actioninfotoshapeinfo(const sender: twidget; + var actioninfo: actioninfoty; var shapeinfo: shapeinfoty; + const aoptions: buttonoptionsty); +procedure frameskinoptionstoshapestate(const aframe: tcustomframe; + var dest: shapeinfoty{shapestatesty}); +function shapestatetoframestate(const aindex: integer; + const ashapes: shapeinfoarty): framestateflagsty; + +procedure checkbuttonhint(const awidget: twidget; info: mouseeventinfoty; + var hintedbutton: integer; const cells: shapeinfoarty; + const getbuttonhint: getbuttonhintty; + const gethintpos: getbuttonhintposty); + +procedure drawcaption(const acanvas: tcanvas; var ainfo: captioninfoty); +procedure initcaptioninfo(var ainfo: captioninfoty); +function calccaptionsize(const acanvas: tcanvas; const ainfo: captioninfoty; + const captionframe: pframety = nil): sizety; + +//var +// animatemouseenter: boolean = true; + +implementation +uses + classes,msestockobjects,msebits,sysutils,mseassistiveserver; +type + twidget1 = class(twidget); + tframe1 = class(tcustomframe); +var + buttontab: tcustomtabulators; + +procedure frameskinoptionstoshapestate(const aframe: tcustomframe; + var dest: shapeinfoty{shapestatesty}); +begin + if aframe <> nil then begin + updatebit(longword(dest.state),ord(shs_flat),fso_flat in aframe.optionsskin); + updatebit(longword(dest.state),ord(shs_noanimation),fso_noanim in aframe.optionsskin); + updatebit(longword(dest.state),ord(shs_nomouseanimation), + fso_nomouseanim in aframe.optionsskin); + updatebit(longword(dest.state),ord(shs_noclickanimation), + fso_noclickanim in aframe.optionsskin); + updatebit(longword(dest.state),ord(shs_nofocusanimation), + fso_nofocusanim in aframe.optionsskin); + updatebit(longword(dest.state),ord(shs_showfocusrect), + not(fso_nofocusrect in aframe.optionsskin)); + updatebit(longword(dest.state),ord(shs_showdefaultrect), + not (fso_nodefaultrect in aframe.optionsskin)); + updatebit(longword(dest.state),ord(shs_noinnerrect), + fso_noinnerrect in aframe.optionsskin); + if shs_noinnerrect in dest.state then begin + dest.mouseframe:= aframe.frameo; + end + else begin + dest.mouseframe:= nullframe; + end; + if aframe = dest.frame then begin + addframe1(dest.mouseframe,aframe.paintframe); + end; + end + else begin + dest.state:= (dest.state - [shs_flat,shs_noanimation,shs_nomouseanimation, + shs_noclickanimation,shs_nofocusanimation, + shs_noinnerrect]) + + [shs_showfocusrect,shs_showdefaultrect]; + dest.mouseframe:= nullframe; + end; +end; + +procedure checkbuttonhint(const awidget: twidget; info: mouseeventinfoty; + var hintedbutton: integer; const cells: shapeinfoarty; + const getbuttonhint: getbuttonhintty; + const gethintpos: getbuttonhintposty); +var + int1: integer; + mstr1: msestring; +begin + if (info.eventkind = ek_clientmouseleave) then begin + if hintedbutton >= 0 then begin + application.hidehint; + end; + hintedbutton:= -1; + exit; + end; + int1:= getmouseshape(cells); + if (info.eventkind in [ek_buttonpress,ek_buttonrelease]) then begin + if hintedbutton >= 0 then begin + application.hidehint; + hintedbutton:= -(hintedbutton+3); + end + else begin + if int1 >= 0 then begin + hintedbutton:= -(int1+3); + end; + end; + exit; + end; + if (info.eventkind in [ek_mousemove,ek_mousepark]) and + not (csdesigning in awidget.componentstate) then begin + if (int1 >= 0) then begin + if (int1 <> hintedbutton) and (-(int1+3) <> hintedbutton) then begin + if twidget1(awidget).getshowhint and ((info.eventkind = ek_mousepark) or + (hintedbutton >= 0)) + {(application.activehintedwidget = awidget)} then begin + if cells[int1].state * [shs_separator,shs_clicked] = [] then begin + hintedbutton:= int1; + mstr1:= getbuttonhint(int1); + if (mstr1 <> '') and application.active then begin + application.showhint(awidget,mstr1,gethintpos(int1), + cp_bottomleft,-1,[hfl_noautohidemove]); + end + else begin + application.hidehint; + end; + end; + end + else begin + application.hidehint; + end; + end; + end + else begin + if hintedbutton >= 0 then begin + application.hidehint; + hintedbutton:= -1; + end; + end; + end; +end; + +procedure actioninfotoshapeinfo(var actioninfo: actioninfoty; + var shapeinfo: shapeinfoty); +begin + with actioninfo do begin + actionstatestoshapestates(actioninfo,shapeinfo.state); + shapeinfo.ca.caption:= caption1; + shapeinfo.ca.imagelist:= timagelist(imagelist); + shapeinfo.ca.imagenr:= imagenr; + shapeinfo.imagenrdisabled:= imagenrdisabled; + shapeinfo.ca.colorglyph:= colorglyph; + shapeinfo.color:= color; + shapeinfo.imagecheckedoffset:= imagecheckedoffset; + shapeinfo.group:= group; + end; +end; + +procedure actioninfotoshapeinfo(const sender: twidget; + var actioninfo: actioninfoty; var shapeinfo: shapeinfoty; + const aoptions: buttonoptionsty); +var + statebefore: actionstatesty; +begin + if not (csloading in sender.componentstate) then begin + with actioninfo do begin + statebefore:= state; + if (sender.enabled) <> not (as_disabled in state) then begin + if not (as_disabled in state) or + not (as_syncdisabledlocked in state) and + (not (bo_noassistivedisabled in aoptions) or + not sender.canassistive() and + not (csdesigning in sender.componentstate)) then begin + sender.enabled:= not(as_disabled in state); + end; + end; + if (sender.visible) <> not (as_invisible in state) then begin + sender.visible:= not(as_invisible in state); + end; + state:= statebefore; //restore localflag + actioninfotoshapeinfo(actioninfo,shapeinfo); + updatewidgetshapestate(shapeinfo,sender,as_disabled in state, + twidget1(sender).fframe); + //update shs_disabled by isenabled + sender.invalidate; + end; + end; +end; + +procedure initcaptioninfo(var ainfo: captioninfoty); +begin + with ainfo do begin + captiondist:= defaultshapecaptiondist; + textflags:= defaultcaptiontextflags; +// textflags:= [tf_default]; + end; +end; + +procedure initshapeinfo(var ainfo: shapeinfoty); +begin + with ainfo do begin + initcaptioninfo(ainfo.ca); + focusrectdist:= defaultshapefocusrectdist; + end; +end; + +procedure setchecked(var info: shapeinfoty; const value: boolean; + const widget: twidget); +begin + with info do begin + if value xor (shs_checked in state) then begin + widget.invalidaterect(ca.dim); + updatebit({$ifdef FPC}longword{$else}longword{$endif}(info.state), + ord(shs_checked),value); + end; + end; +end; + +function updatewidgetshapestate(var info: shapeinfoty; const widget: twidget; + const adisabled: boolean = false; + const aframe: tcustomframe = nil): boolean; +var + statebefore: shapestatesty; + rect1: rectty; +begin + with info do begin + statebefore:= state; + updatebit(longword(state),ord(shs_disabled),not widget.isenabled or adisabled); + updatebit(longword(state),ord(shs_focused),widget.active); + result:= state <> statebefore; + if result then begin + rect1:= ca.dim; + if (aframe <> nil) and tframe1(aframe).needsactiveinvalidate then begin + inflaterect1(rect1,aframe.innerframe); + end; + if shs_widgetorg in state then begin + widget.invalidaterect(rect1,org_widget); + end + else begin + widget.invalidaterect(rect1); + end; + end; + end; +end; + +procedure updateshapemoveclick(const infoarpo: pshapeinfoarty; value: boolean); +var + int1: integer; +begin + if infoarpo <> nil then begin + for int1:= 0 to high(infoarpo^) do begin + updatebit({$ifdef FPC}longword{$else}longword{$endif}(infoarpo^[int1].state), + ord(shs_moveclick),value); + end; + end; +end; + +function pointinshape(const pos: pointty; const info: shapeinfoty): boolean; +begin + if shs_ellipsemouse in info.state then begin + result:= pointinellipse(pos,deflaterect(info.ca.dim,info.mouseframe)); + end + else begin + result:= pointinrect(pos,deflaterect(info.ca.dim,info.mouseframe)); + end; + if result and (info.frame <> nil) then begin + result:= info.frame.pointinmask(pos,info.ca.dim); + end; +end; + +function updatemouseshapestate(var info: shapeinfoty; + const mouseevent: mouseeventinfoty; + const widget: twidget; const aframe: tcustomframe; + const infoarpo: pshapeinfoarty = nil; + const canclick: boolean = true): boolean; + //true on change +var + statebefore: shapestatesty; + int1: integer; + po1: pshapeinfoty; + bo1: boolean; +// rect1: rectty; + +begin + result:= false; + bo1:= (widget = nil) or widget.isenabled; + with info,mouseevent do begin + statebefore:= state; + if es_drag in eventstate then begin + state:= state - [shs_mouse,shs_clicked]; + updateshapemoveclick(infoarpo,false); + end + else begin + if not (shs_invisible in state) and bo1 then begin + case eventkind of + ek_clientmouseleave,ek_mouseleave: begin + if (eventkind = ek_mouseleave) or not (shs_widgetorg in state) then begin + state:= state - [shs_mouse,shs_clicked]; + end; + end; + ek_mousemove,ek_mousepark: begin +// if pointinrect(pos,ca.dim) then begin + if pointinshape(pos,info) then begin + state:= state + [shs_mouse]; + if (ss_left in shiftstate) and + (state * [shs_disabled,shs_moveclick] = [shs_moveclick]) then begin + state:= state + [shs_clicked]; + end; + end + else begin + state:= state - [shs_mouse,shs_clicked]; + end; + end; + ek_buttonrelease: begin + if button = mb_left then begin + updateshapemoveclick(infoarpo,false); + exclude(state,shs_moveclick); + if not (shs_disabled in state) or + (widget <> nil) and (csdesigning in widget.componentstate) then begin + if state * [shs_clicked,shs_checkbox,shs_radiobutton] = + [shs_clicked,shs_checkbox] then begin + setchecked(info,not (shs_checked in state),widget); + end; + if state * [shs_clicked,shs_radiobutton] = + [shs_clicked,shs_radiobutton] then begin + if [shs_checked,shs_checkbox] * state = + [shs_checked,shs_checkbox] then begin + setchecked(info,false,widget); + end + else begin + if (infoarpo <> nil) then begin + for int1:= 0 to high(infoarpo^) do begin + po1:= @infoarpo^[int1]; + if (po1 <> @info) and (po1^.group = info.group) and + (shs_radiobutton in po1^.state) then begin + setchecked(po1^,false,widget); + end; + end; + setchecked(info,true,widget); + end; + end; + end; + if {(eventkind = ek_buttonrelease) and} (shs_clicked in state) and + assigned(doexecute) then begin + state:= state - [shs_clicked]; + result:= true; //state can be invalid after execute + if widget <> nil then begin //info can be invalid after execute + if (aframe <> nil) and tframe1(aframe).needsmouseinvalidate then begin + widget.invalidaterect(inflaterect(ca.dim,aframe.innerframe)); + end + else begin + widget.invalidaterect(ca.dim); + end; + twidget1(widget).releasebuttonpressgrab(); + end; + doexecute(tag,mouseevent); + exit; + end; + end; + state:= state - [shs_clicked]; + end; + end; + ek_buttonpress: begin + if canclick and (button = mb_left) and + (not(shs_disabled in state) or + (widget <> nil) and (csdesigning in widget.componentstate) and + not (ws1_nodisabledclick in twidget1(widget).fwidgetstate1)) + and pointinshape(pos,info) then begin + state:= state + [shs_clicked,shs_moveclick]; + updateshapemoveclick(infoarpo,true); + end; + end; + end; + end + else begin + state:= state - [shs_mouse,shs_clicked]; + end; + end; + result:= result or (state <> statebefore); + if result and (widget <> nil) then begin + if (aframe <> nil) and tframe1(aframe).needsmouseinvalidate then begin + widget.invalidaterect(inflaterect(ca.dim,aframe.innerframe)); + end + else begin + widget.invalidaterect(ca.dim); + end; + end; + end; +end; + +function updatemouseshapestate(var infos: shapeinfoarty; + const mouseevent: mouseeventinfoty; + const widget: twidget; var focuseditem: integer; + const aframe: tcustomframe = nil): boolean; +var + int1,i2: integer; +begin + result:= false; + i2:= focuseditem; + focuseditem:= -1; //none + for int1:= 0 to high(infos) do begin + result:= updatemouseshapestate(infos[int1],mouseevent,widget, + aframe,@infos) or result; + if shs_mouse in infos[int1].state then begin + focuseditem:= int1; + if i2 <> int1 then begin + { necessary? + if (focuseditem >= 0) and (focuseditem <= high(infos)) then begin + widget.invalidaterect(infos[focuseditem].ca.dim); + end; + } + if (int1 >= 0) and (assistiveserver <> nil) then begin + assistiveserver.doitementer(getiassistiveclient(widget),infos,int1); + end; + end; + end; + end; +end; + +function getmouseshape(const infos: shapeinfoarty): integer; + //returns shape index under mouse, -1 if none +var + int1: integer; +begin + result:= -1; + for int1:= 0 to high(infos) do begin + if shs_mouse in infos[int1].state then begin + result:= int1; + break; + end; + end; +end; + +function findshapeatpos(const infoar: shapeinfoarty; const apos: pointty; + const rejectstates: shapestatesty = + [shs_disabled,shs_invisible]): integer; +var + int1: integer; +begin + result:= -1; + for int1:= 0 to high(infoar) do begin + with infoar[int1] do begin + if (state * rejectstates = []) and pointinrect(apos,ca.dim) then begin + result:= int1; + break; + end; + end; + end; +end; + +function shapestatetoframestate(const aindex: integer; + const ashapes: shapeinfoarty): framestateflagsty; +var + state1: shapestatesty; +begin + result:= []; + if aindex <= high(ashapes) then begin + state1:= ashapes[aindex].state; + if shs_disabled in state1 then begin + include(result,fsf_disabled); + end; + if [shs_active{,shs_focused}] * state1 <> [] then begin + include(result,fsf_active); + end; + if shs_mouse in state1 then begin + include(result,fsf_mouse); + end; + if shs_clicked in state1 then begin + include(result,fsf_clicked); + end; + end; +end; + +procedure updateedgerect(var arect: rectty; const awidth: integer; + const hiddenedges: edgesty); +begin + if not (edg_right in hiddenedges) then begin + dec(arect.cx,awidth); + end; + if not (edg_top in hiddenedges) then begin + inc(arect.y,awidth); + dec(arect.cy,awidth); + end; + if not (edg_left in hiddenedges) then begin + inc(arect.x,awidth); + dec(arect.cx,awidth); + end; + if not (edg_bottom in hiddenedges) then begin + dec(arect.cy,awidth); + end; +end; + +procedure draw3dframe(const canvas: tcanvas; + const arect: rectty; level: integer; + colorinfo: edgecolorpairinfoty; const hiddenedges: edgesty); +//todo: optimize + +type + cornerinfoty = record + col1,col2: colorty; + w1,w2: integer; + end; + pcornerinfoty = ^cornerinfoty; + +var + poly: array[0..5] of pointty; + + procedure drawcorner(const cornerinfo: cornerinfoty; + const firstoff,lastoff,startoff,stopoff: boolean; + const topleft: boolean); + + procedure calculatepoly(w: integer); + begin + poly[3].x:= poly[2].x - w; + poly[3].y:= poly[2].y + w; + poly[4].x:= poly[1].x + w; + poly[4].y:= poly[3].y; + poly[5].x:= poly[4].x; + poly[5].y:= poly[0].y - w; + if (w = 1) and topleft then begin + dec(poly[0].y); + dec(poly[2].x); + end; + if startoff then begin + if topleft then begin + poly[0].y:= arect.y + arect.cy; + if w = 1 then begin + dec(poly[0].y); + end; + end + else begin + poly[0].y:= arect.y; + end; + poly[5].y:= poly[0].y; + end; + if stopoff then begin + if topleft then begin + poly[2].x:= arect.x + arect.cx; + if w = 1 then begin + dec(poly[2].x); + end; + end + else begin + poly[2].x:= arect.x; + end; + poly[3].x:= poly[2].x; + end; + + if firstoff then begin + if topleft then begin + poly[1].x:= arect.x; + poly[4].x:= poly[1].x; + end + else begin + poly[1].x:= arect.x+arect.cx; + if w = 1 then begin + dec(poly[1].x); + end; + poly[4].x:= poly[1].x; + end; + poly[0]:= poly[1]; + poly[5]:= poly[4]; + end; + if lastoff then begin + if topleft then begin + poly[1].y:= arect.y; + poly[4].y:= poly[1].y; + end + else begin + poly[4].y:= arect.y+arect.cy; + if w = 1 then begin + dec(poly[4].y); + end; + poly[1].y:= poly[4].y; + end; + poly[2]:= poly[1]; + poly[3]:= poly[4]; + end; + end; //calculatepoly + + begin + with canvas,cornerinfo do begin + calculatepoly(w1); + if w1 > 0 then begin + if w1 = 1 then begin + drawlines(poly,false,col1,0,3); + end + else begin + fillpolygon(poly,col1); + end; + end; + if w2 > 0 then begin + poly[0]:= poly[5]; + poly[1]:= poly[4]; + poly[2]:= poly[3]; + calculatepoly(w2); + if w2 = 1 then begin + drawlines(poly,false,col2,0,3); + end + else begin + fillpolygon(poly,col2); + end; + end; + end; + end; + +var + lightcorner,shadowcorner: cornerinfoty; + down: boolean; + int1: integer; + po1: pcornerinfoty; +begin + if (level = 0) or (arect.cx = 0) or (arect.cy = 0) then begin + exit; + end; + with colorinfo do begin + if shadow.effectcolor = cl_default then begin + shadow.effectcolor:= defaultframecolors.edges.shadow.effectcolor; + end; + if shadow.color = cl_default then begin + shadow.color:= defaultframecolors.edges.shadow.color; + end; + if light.color = cl_default then begin + light.color:= defaultframecolors.edges.light.color; + end; + if light.effectcolor = cl_default then begin + light.effectcolor:= defaultframecolors.edges.light.effectcolor; + end; + if shadow.effectwidth < 0 then begin + shadow.effectwidth:= defaultframecolors.edges.shadow.effectwidth; + end; + if light.effectwidth < 0 then begin + light.effectwidth:= defaultframecolors.edges.light.effectwidth; + end; + end; + if level < 0 then begin + down:= true; + level:= -level; + end + else begin + down:= false; + end; + + with lightcorner,colorinfo.light do begin + int1:= abs(effectwidth); + if int1 > level then begin + col1:= effectcolor; + w1:= level; + w2:= 0; + end + else begin + if (effectwidth < 0){ xor down} then begin + col1:= effectcolor; + col2:= color; + w1:= int1; + w2:= level - int1; + end + else begin + col1:= color; + col2:= effectcolor; + w1:= level - int1; + w2:= int1; + end; + end; + end; + with shadowcorner,colorinfo.shadow do begin + int1:= abs(effectwidth); + if int1 > level then begin + col1:= color; + w1:= level; + w2:= 0; + end + else begin + if level - int1 < 1 then begin //reduce dkshadow + int1:= level - 1; + end; + if (effectwidth < 0){ xor down} then begin + col1:= effectcolor; + col2:= color; + w1:= int1; + w2:= level-int1; + end + else begin + col1:= color; + col2:= effectcolor; + w1:= level-int1; + w2:= int1; + end; + end; + end; + + with arect do begin + if hiddenedges * [edg_left,edg_top] <> [edg_left,edg_top] then begin + poly[0].x:= x; + poly[0].y:= y + cy; + poly[1]:= pos; + poly[2].x:= x + cx; + poly[2].y:= y; + + if down then begin //topleft + po1:= @shadowcorner; + end + else begin + po1:= @lightcorner; + if (level > 2) and (hiddenedges * [edg_left,edg_top] = []) then begin + canvas.drawline(pos,makepoint(pos.x+level-1,pos.y+level-1), + colorinfo.light.effectcolor); + end; + end; + drawcorner(po1^,edg_left in hiddenedges,edg_top in hiddenedges, + edg_bottom in hiddenedges,edg_right in hiddenedges,true); + if not down and (level > 2) and + (hiddenedges * [edg_left,edg_top] = []) then begin + canvas.drawline(pos,makepoint(pos.x+level-1,pos.y+level-1), + colorinfo.light.effectcolor); + end; + end; + if hiddenedges * [edg_right,edg_bottom] <> [edg_right,edg_bottom] then begin + poly[0].x:= x + cx - level; + poly[0].y:= y + level - 1; + poly[1].x:= poly[0].x; + poly[1].y:= y + cy - level; + poly[2].x:= x + level; + poly[2].y:= poly[1].y; + + if down then begin //bottomright + po1:= @lightcorner; + end + else begin + po1:= @shadowcorner; + end; + drawcorner(po1^,edg_right in hiddenedges,edg_bottom in hiddenedges, + edg_top in hiddenedges,edg_left in hiddenedges,false); + end; + end; +end; + +procedure drawimageframe(const canvas: tcanvas; const imagelist: timagelist; + const imageoffs: int32; const dest: rectty; + const hiddenedges: edgesty); +var + imagesize1: sizety; + rect1: rectty; +begin + if (imageoffs >= -8) and (imagelist.bitmap.hasimage) then begin + imagesize1:= imagelist.size; + if not (edg_left in hiddenedges) then begin + imagelist.paintlookup(canvas,imageoffs+0,dest.pos); //topleft + rect1.x:= dest.x; + rect1.y:= dest.y + imagesize1.cy; + rect1.cx:= imagesize1.cx; + rect1.cy:= dest.cy - imagesize1.cy -imagesize1.cy; + imagelist.paintlookup(canvas,imageoffs+1,rect1,[al_stretchy]); //left + if edg_bottom in hiddenedges then begin + imagelist.paintlookup(canvas,imageoffs+2, + mp(rect1.x,rect1.y+rect1.cy)); //bottomleft + end; + end; + if not (edg_bottom in hiddenedges) then begin + rect1.x:= dest.x; + rect1.y:= dest.y + dest.cy - imagesize1.cy; + imagelist.paintlookup(canvas,imageoffs+2,rect1.pos); //bottomleft + rect1.x:= dest.x + imagesize1.cx; + rect1.cy:= imagesize1.cy; + rect1.cx:= dest.cx - imagesize1.cx -imagesize1.cx; + imagelist.paintlookup(canvas,imageoffs+3,rect1,[al_stretchx]); //bottom + if edg_right in hiddenedges then begin + imagelist.paintlookup(canvas,imageoffs+4, + mp(rect1.x+rect1.cx,rect1.y)); //bottomright + end; + end; + if not (edg_right in hiddenedges) then begin + rect1.x:= dest.x + dest.cx - imagesize1.cx; + rect1.y:= dest.y + dest.cy - imagesize1.cy; + imagelist.paintlookup(canvas,imageoffs+4,rect1.pos); //bottomright + rect1.y:= dest.y + imagesize1.cy; + rect1.cx:= imagesize1.cx; + rect1.cy:= dest.cy - imagesize1.cy - imagesize1.cy; + imagelist.paintlookup(canvas,imageoffs+5,rect1,[al_stretchy]); //right + if edg_top in hiddenedges then begin + imagelist.paintlookup(canvas,imageoffs+6,mp(rect1.x,dest.y)); + //topright + end; + end; + if not (edg_top in hiddenedges) then begin + rect1.x:= dest.x + dest.cx - imagesize1.cx; + rect1.y:= dest.y; + imagelist.paintlookup(canvas,imageoffs+6,rect1.pos); //topright + rect1.x:= dest.x + imagesize1.cx; + rect1.cy:= imagesize1.cy; + rect1.cx:= dest.cx - imagesize1.cx - imagesize1.cx; + imagelist.paintlookup(canvas,imageoffs+7,rect1,[al_stretchx]); //top + if edg_left in hiddenedges then begin + imagelist.paintlookup(canvas,imageoffs+0,mp(dest.x,dest.y)); + //topleft + end; + end; + end; +end; + +procedure drawfocusrect(const canvas: tcanvas; const arect: rectty); +begin + canvas.drawxorframe(arect,-1,stockobjects.bitmaps[stb_block1]); +end; + +function drawbuttonframe(const canvas: tcanvas; const info: shapeinfoty; + out clientrect: rectty; + const hiddenedges: edgesty = []): boolean; + //true if clientrect not empty +var + level: integer; + col1: colorty; + rect1: rectty; +begin + result:= false; + with canvas,info do begin + if shs_separator in state then begin + if not (shs_flat in state) then begin + draw3dframe(canvas,ca.dim,-1,defaultframecolors.edges,[]); + end; + end + else begin + if shs_flat in state then begin + level:= 0; + end + else begin + level:= 1; + end; + if not (shs_noanimation in state) then begin + if not (shs_nomouseanimation in state) and + (shs_mouse in state) and not (shs_disabled in state) or + (state * [shs_nofocusanimation,shs_focused,shs_focusanimation] = + [shs_focused,shs_focusanimation]) then begin + inc(level); + end; + if not (shs_noclickanimation in state) and (shs_clicked in state) or + (state * [shs_checked,shs_checkbutton] = + [shs_checked,shs_checkbutton]) then begin + level:= -1; + end; + end; + clientrect:= ca.dim; + if (state * [shs_focused,shs_showdefaultrect] = + [shs_focused,shs_showdefaultrect]) or + (state * [shs_disabled,shs_default] = [shs_default]) then begin + if not (aso_nodefaultbutton in assistiveoptions) then begin + //no default button if assisted + canvas.drawframe(clientrect,-1,cl_buttondefaultrect); + inflaterect1(clientrect,-1); + end; + end; + rect1:= clientrect; + if (clientrect.cx > 0) and (clientrect.cy > 0) then begin + col1:= color; + if shs_active in state then begin + col1:= coloractive; + end; + if col1 <> cl_transparent then begin + fillrect(clientrect,col1); + end; + if facetemplate <> nil then begin + facetemplate.paint(canvas,clientrect); + end + else begin + if face <> nil then begin + face.paint(canvas,clientrect); + end; + end; + end; + draw3dframe(canvas,rect1,level,defaultframecolors.edges,hiddenedges); + end; + inflaterect1(clientrect,-abs(level),hiddenedges); + result:= (clientrect.cx > 0) and (clientrect.cy > 0); + end; +end; + +function adjustimagerect(const canvas: tcanvas; const info: captioninfoty; + var arect: rectty; out aalign: alignmentsty): rectty; +var + pos: imageposty; + i1,i2: integer; + rect1,rect2: rectty; +begin + result:= arect; + with info do begin + pos:= simpleimagepos[imagepos]; + if pos in (vertimagepos) then begin +// if result.cx < imagelist.width then begin + i1:= result.cx - imagelist.width; + if i1 < 0 then begin + dec(i1); + end; +// end; + inc(result.x,imagedist1 + (i1 - imagedist1 - imagedist2) div 2); + result.cx:= imagelist.width; + end + else begin + i1:= result.cy - imagelist.height; + if i1 < 0 then begin + dec(i1); + end; + inc(result.y,imagedist1 + (i1 - imagedist1 - imagedist2) div 2); + result.cy:= imagelist.height; + end; + + case pos of + ip_right: begin + aalign:= [al_right]; + case imagepos of + ip_righttop: begin + result.y:= arect.y + imagedist1; + end; + ip_rightbottom: begin + result.y:= arect.cy - imagedist2 - imagelist.height; + end; + end; + dec(result.cx,imagedist); + end; + ip_left: begin + aalign:= []; + case imagepos of + ip_lefttop: begin + result.y:= arect.y + imagedist1; + end; + ip_leftbottom: begin + result.y:= arect.cy - imagedist2 - imagelist.height; + end; + end; + inc(result.x,imagedist); + dec(result.cx,imagedist); + end; + ip_bottom: begin + aalign:= [al_bottom]; + case imagepos of + ip_bottomleft: begin + result.x:= arect.x + imagedist1; + end; + ip_bottomright: begin + result.x:= arect.cx - imagedist2 - imagelist.width; + end; + end; + dec(result.cy,imagedist); + end; + ip_top: begin + aalign:= []; + case imagepos of + ip_topleft: begin + result.x:= arect.x + imagedist1; + end; + ip_topright: begin + result.x:= arect.cx - imagedist2 - imagelist.width; + end; + end; + inc(result.y,imagedist); + dec(result.cy,imagedist); + end; + ip_center: begin + aalign:= [al_xcentered,al_ycentered]; + inc(result.x,imagedist); + end; + ip_centervert: begin + aalign:= [al_xcentered,al_ycentered]; + inc(result.y,imagedist); + end; + end; + i1:= imagelist.width + imagedist; + i2:= imagelist.height + imagedist; + case pos of + ip_right: begin + dec(arect.cx,i1); + end; + ip_left: begin + inc(arect.x,i1); + dec(arect.cx,i1); + end; + ip_top: begin + inc(arect.y,i2); + dec(arect.cy,i2); + end; + ip_bottom: begin + dec(arect.cy,i2); + end; + end; + if (tf_glueimage in info.textflags) and + not (pos in [ip_center,ip_centervert]) then begin + rect1:= arect; + if pos in (vertimagepos) then begin + rect1.cy:= rect1.cy - captiondist; + rect2:= textrect(canvas,caption,rect1,textflags,font); + i1:= rect1.cy - rect2.cy; + if i1 > 0 then begin + if tf_ycentered in textflags then begin + i1:= i1 div 2; + if pos in bottomimagepos then begin + result.y:= result.y - i1; + end + else begin + result.y:= result.y + i1; + end; + end + else begin + if tf_bottom in textflags then begin + if not (pos in bottomimagepos) then begin + result.y:= result.y + i1 - imagedist; + end; + end + else begin + if pos in bottomimagepos then begin + result.y:= result.y - i1 + imagedist; + end; + end; + end; + end; + end + else begin + rect1.cx:= rect1.cx - captiondist; + rect2:= textrect(canvas,caption,rect1,textflags,font); + i1:= rect1.cx - rect2.cx; + if i1 > 0 then begin + if tf_xcentered in textflags then begin + i1:= i1 div 2; + if pos in rightimagepos then begin + result.x:= result.x - i1; + end + else begin + result.x:= result.x + i1; + end; + end + else begin + if tf_right in textflags then begin + if not (pos in rightimagepos) then begin + result.x:= result.x + i1 - imagedist; + end; + end + else begin + if pos in rightimagepos then begin + result.x:= result.x - i1 + imagedist; + end; + end; + end; + end; + end; + end; + end; +end; + +function drawbuttonimage(const canvas: tcanvas; const info: shapeinfoty; + var arect: rectty): boolean; +var + align1: alignmentsty; + rect1: rectty; + int1: integer; + reg1: regionty; + co1: colorty; +begin + co1:= 0; + with canvas,info do begin + if (ca.imagelist <> nil) then begin + reg1:= canvas.copyclipregion; + canvas.intersectcliprect(arect); + result:= true; + rect1:= adjustimagerect(canvas,info.ca,arect,align1); + if shs_disabled in state then begin + int1:= imagenrdisabled; + if int1 = -2 then begin + int1:= ca.imagenr; + include(align1,al_grayed); + end; + end + else begin + int1:= ca.imagenr; + end; + if (shs_checked in state) and (int1 >= 0) then begin + inc(int1,imagecheckedoffset); + end; + if state*[shs_focuscolor,shs_focused] = + [shs_focuscolor,shs_focused] then begin + canvas.fillrect(rect1,cl_selectedtextbackground); + co1:= cl_selectedtext; + end + else begin + if ca.colorglyph <> cl_none then begin + co1:= ca.colorglyph; + if co1 = cl_default then begin + co1:= cl_glyph; + end; + end; + end; + ca.imagelist.paint(canvas,int1,rect1,align1,co1); + canvas.clipregion:= reg1; + end + else begin + result:= false; + end; + end; +end; + +procedure drawbuttoncaption(const canvas: tcanvas; const info: shapeinfoty; + const arect: rectty; const pos: imageposty; const outerrect: prectty); +var + textflags: textflagsty; + rect1: rectty; + tab1: tcustomtabulators; +begin + with canvas,info do begin + tab1:= nil; + if ca.caption.text <> '' then begin + rect1:= arect; + if info.frame <> nil then begin + deflaterect1(rect1,info.frame.framei); + end; + textflags:= ca.textflags + [tf_clipi]; + case pos of + ip_left,ip_lefttop,ip_leftbottom: begin + if tf_right in textflags then begin + dec(rect1.x,ca.captiondist); + end + else begin + inc(rect1.x,ca.captiondist); + dec(rect1.cx,ca.captiondist); + end; + if countchars(ca.caption.text,msechar(c_tab)) = 1 then begin + tab1:= buttontab; + tab1[0].pos:= info.tabpos / defaultppmm; + end; + end; + ip_right,ip_righttop,ip_rightbottom: begin + if textflags * [tf_right,tf_xcentered] = [] then begin + inc(rect1.x,ca.captiondist); + end; + dec(rect1.cx,ca.captiondist); + end; + ip_top,ip_topleft,ip_topright: begin + if tf_bottom in textflags then begin + dec(rect1.y,ca.captiondist); + end + else begin + inc(rect1.y,ca.captiondist); + dec(rect1.cy,ca.captiondist); + end; + end; + ip_bottom,ip_bottomleft,ip_bottomright: begin + if textflags * [tf_bottom,tf_ycentered] = [] then begin + inc(rect1.y,ca.captiondist); + end; + dec(rect1.cy,ca.captiondist); + end; + end; + if shs_disabled in state then begin + include(textflags,tf_grayed); + end; + if outerrect <> nil then begin + exclude(textflags,tf_clipi); + include(textflags,tf_clipo); + drawtext(canvas,ca.caption,rect1,outerrect^,textflags,ca.font,tab1); + end + else begin + drawtext(canvas,ca.caption,rect1,arect,textflags,ca.font,tab1); + end; + end; + end; +end; + +procedure drawbutton(const canvas: tcanvas; const info: shapeinfoty); +var + rect1,rect2: rectty; +// pos: captionposty; + pos1: imageposty; +begin + if not (shs_invisible in info.state) and + drawbuttonframe(canvas,info,rect1) then begin + rect2:= rect1; + drawbuttonimage(canvas,info,rect1); + with canvas,info do begin + if state * [shs_focused,shs_showfocusrect] = + [shs_focused,shs_showfocusrect] then begin + drawfocusrect(canvas,inflaterect(rect2,-focusrectdist)); + end; + pos1:= info.ca.imagepos; + if info.ca.imagelist = nil then begin + if tf_right in ca.textflags then begin + pos1:= ip_right; + end + else begin + if (tf_left in ca.textflags) or + (info.ca.textflags * [tf_xcentered,tf_xjustify] = []) then begin + pos1:= ip_left; + end + else begin + if tf_bottom in info.ca.textflags then begin + pos1:= ip_bottom; + end + else begin + if (tf_top in info.ca.textflags) or + (info.ca.textflags * [tf_ycentered] = []) then begin + pos1:= ip_top; + end; + end; + end; + end; + end; + drawbuttoncaption(canvas,info,rect1,pos1,nil); + end; + end; +end; + +procedure drawcaption(const acanvas: tcanvas; var ainfo: captioninfoty); +var + rect1,rect2: rectty; + align1: alignmentsty; + info1: drawtextinfoty; +begin + with ainfo do begin + rect2:= ainfo.dim; + if ainfo.imagelist <> nil then begin + rect1:= adjustimagerect(acanvas,ainfo,rect2,align1); + if colorglyph <> cl_none then begin + imagelist.paint(acanvas,imagenr,rect1,align1,colorglyph); + end; + end; + case imagepos of + ip_left{,ip_leftcenter}: begin + inc(rect2.x,captiondist); + dec(rect2.cx,captiondist); + end; + ip_right{,ip_rightcenter}: begin + dec(rect2.cx,captiondist); + end; + ip_top{,ip_topcenter}: begin + inc(rect2.y,captiondist); + dec(rect2.cy,captiondist); + end; + ip_bottom{,ip_bottomcenter}: begin + dec(rect2.cy,captiondist); + end; + end; + info1.text:= caption; + info1.dest:= rect2; + info1.flags:= textflags - [tf_clipo]; + info1.font:= font; + info1.tabulators:= nil; + drawtext(acanvas,info1); + captionclipped:= (info1.res.cx > rect2.cx) or (info1.res.cy > rect2.cy); + //drawtext(acanvas,caption,rect2,textflags,font); + end; +end; + +function calccaptionsize(const acanvas: tcanvas; + const ainfo: captioninfoty; const captionframe: pframety = nil): sizety; +var + int1: integer; + vertdist: boolean; +begin + with ainfo do begin + result:= textrect(acanvas,caption,textflags,font).size; + if captionframe <> nil then begin + with captionframe^ do begin + result.cx:= result.cx + left + right; + result.cy:= result.cy + top + bottom; + end; + end; + vertdist:= imagepos in vertimagepos; + if vertdist then begin + inc(result.cy,captiondist); + end + else begin + inc(result.cx,captiondist); + end; + if imagelist <> nil then begin + with imagelist do begin + if vertdist then begin + int1:= width + imagedist1 + imagedist2; + if int1 > result.cx then begin + result.cx:= int1; + end; + int1:= height + imagedist; + if imagepos = ip_centervert then begin + int1:= int1 + imagedist; + if int1 > result.cx then begin + result.cy:= int1; + end; + end + else begin + result.cy:= result.cy + int1; + end; + end + else begin + int1:= height + imagedist1 + imagedist2; + if int1 > result.cy then begin + result.cy:= int1; + end; + int1:= width + imagedist; + if imagepos = ip_center then begin + int1:= int1 + imagedist; + if int1 > result.cx then begin + result.cx:= int1; + end; + end + else begin + result.cx:= result.cx + int1; + end; + end; + end; + end; + end; +end; + +procedure drawtoolbutton(const canvas: tcanvas; var info: shapeinfoty); +var + rect1: rectty; + frame1: framety; + co0,co1,co2,co3: colorty; +begin + if not (shs_invisible in info.state) then begin +// frameskinoptionstoshapestate(info.frame,info); + if info.frame <> nil then begin + frameskinoptionstoshapestate(info.frame,info); + canvas.save(); + co1:= info.color; + co2:= info.coloractive; + co3:= tframe1(info.frame).actualcolorclient; + if shs_active in info.state then begin + co0:= co2; + info.coloractive:= cl_transparent; + end + else begin + co0:= co1; + info.color:= cl_transparent; + end; + if co0 <> cl_transparent then begin + if co3 = cl_transparent then begin + tframe1(info.frame).fi.colorclient:= co0; + end; + end; + info.frame.paintbackground(canvas,info.ca.dim,true,false); + frame1:= info.frame.paintframe; + if not (fso_noinnerrect in info.frame.optionsskin) then begin + addframe1(frame1,info.frame.frameo); + end; + { + if not (fso_noinnerrect in info.frame.optionsskin) then begin + frame1:= info.frame.innerframe; + end + else begin + frame1:= info.frame.paintframe; + end; + } + deflaterect1(info.ca.dim,frame1); + end; + if drawbuttonframe(canvas,info,rect1) then begin + info.ca.imagepos:= ip_center; + drawbuttonimage(canvas,info,rect1{,cp_center}); + end; + if info.frame <> nil then begin + canvas.restore(); + inflaterect1(info.ca.dim,frame1); + info.frame.paintoverlay(canvas,info.ca.dim); + if co3 = cl_transparent then begin + info.color:= co1; + info.coloractive:= co2; + tframe1(info.frame).fi.colorclient:= co3; + end; + end; + end; +end; + +function drawbuttoncheckbox(const canvas: tcanvas; const info: shapeinfoty; + var arect: rectty; const pos: imageposty = ip_left): boolean; +var + rect1,rect2: rectty; + align1: alignmentsty; + int1: integer; + co1: colorty; + framestates: framestateflagsty; + size1: sizety; + widthextend: int32; +begin + framestates:= []; + result:= [shs_checkbox,shs_radiobutton] * info.state <> []; + if result then begin + rect1:= arect; + int1:= menucheckboxheight; + widthextend:= menucheckboxwidth; + if info.checkboxframe <> nil then begin + with info.checkboxframe do begin + if fso_flat in optionsskin then begin + dec(int1,2); + dec(widthextend,2); + end; + size1:= innerframedim; + widthextend:= widthextend + frameo_left + frameo_right + size1.cx; + int1:= int1 + size1.cy + frameo_top + frameo_bottom; + end; + end; + rect1.cx:= widthextend; + if int1 < arect.cy then begin + rect1.cy:= int1; + rect1.y:= rect1.y + (arect.cy - int1) div 2; + end; + if pos <> ip_left then begin + inc(rect1.x,arect.cx-rect1.cx); + end; + if info.checkboxframe <> nil then begin + framestates:= combineframestateflags(info.state); + deflaterect1(rect1,info.checkboxframe.frameo); + info.checkboxframe.paintbackgroundframe(canvas,rect1,framestates); + rect2:= deflaterect(rect1,info.checkboxframe.innerframe); + end + else begin + rect2:= rect1; + end; + if (info.checkboxframe = nil) or + not (fso_flat in info.checkboxframe.optionsskin) then begin + draw3dframe(canvas,rect2,-1,defaultframecolors.edges,[]); + end; + if pos = ip_left then begin + inc(arect.x,widthextend); + end; + dec(arect.cx,widthextend); + if shs_checked in info.state then begin + if shs_disabled in info.state then begin + align1:= [al_xcentered,al_ycentered,al_grayed]; + end + else begin + align1:= [al_xcentered,al_ycentered]; + end; + if shs_radiobutton in info.state then begin + int1:= ord(stg_checkedradio); + end + else begin + int1:= ord(stg_checked); + end; + co1:= info.ca.colorglyph; + if (info.checkboxframe <> nil) and + (info.checkboxframe.colorglyph <> cl_default) then begin + co1:= info.checkboxframe.colorglyph; + end; + stockobjects.glyphs.paint(canvas,int1,rect2,align1,co1); + end; + if info.checkboxframe <> nil then begin + info.checkboxframe.paintoverlayframe(canvas,rect1,framestates); + end; + end; +end; + +procedure drawmenuarrow(const canvas: tcanvas; const info: shapeinfoty; + var rect: rectty); +var + alignment: alignmentsty; + int1: integer; + glyph1: stockglyphty; + rect1: rectty; +begin + glyph1:= stg_arrowrightsmall; + if shs_horz in info.state then begin + glyph1:= stg_arrowdownsmall; + int1:= menuarrowwidthhorz; + end + else begin + int1:= menuarrowwidth; + end; + alignment:= [al_xcentered,al_ycentered]; + if shs_disabled in info.state then begin + include(alignment,al_grayed); + inc(int1); + end; + with rect1 do begin + x:= rect.x + rect.cx - int1; + cx:= int1; + y:= rect.y; + cy:= rect.cy; + end; + stockobjects.glyphs.paint(canvas,ord(glyph1),rect1,alignment, + info.ca.colorglyph); + dec(rect.cx,int1); +end; + +procedure drawmenubutton(const canvas: tcanvas; var info: shapeinfoty; + const innerframe: pframety = nil); +var + rect1: rectty; +begin + if not (shs_invisible in info.state) and + drawbuttonframe(canvas,info,rect1) then begin + info.ca.imagepos:= ip_left; + drawbuttonimage(canvas,info,rect1{,cp_left}); + if (shs_menuarrow in info.state) then begin +// if (ss_submenu in info.state) then begin + drawmenuarrow(canvas,info,rect1); + end; + drawbuttoncheckbox(canvas,info,rect1,ip_right); + if innerframe <> nil then begin + deflaterect1(rect1,innerframe^); + end; + drawbuttoncaption(canvas,info,rect1,ip_left,nil); + end; +end; + +procedure drawtab(const canvas: tcanvas; var info: shapeinfoty; + const innerframe: pframety = nil); +var + rect1,rect2,rect3: rectty; + pos1: imageposty; + frame1: framety; + edges1: edgesty; + +begin + with canvas,info do begin + if not (shs_invisible in state) then begin + if frame <> nil then begin + //todo: optimize, move settings to tcustomstepframe updatestate + rect3:= ca.dim; + if not (fso_noinnerrect in frame.optionsskin) then begin + deflaterect1(ca.dim,frame.frameo); + end; + canvas.save; + frame.paintbackground(canvas,info.ca.dim,true,false); + frame1:= frame.paintframe; + deflaterect1(ca.dim,frame1); + frameskinoptionstoshapestate(frame,info); + end; + if shs_opposite in state then begin + if shs_vert in state then begin + edges1:= [edg_left]; + end + else begin + edges1:= [edg_top]; + end; + end + else begin + if shs_vert in state then begin + edges1:= [edg_right]; + end + else begin + edges1:= [edg_bottom]; + end; + end; + if drawbuttonframe(canvas,info,rect1,edges1) then begin + if ca.imagepos = ip_right then begin + pos1:= ip_right; + end + else begin + pos1:= ip_left; + end; + rect2:= rect1; + drawbuttonimage(canvas,info,rect1); + drawbuttoncheckbox(canvas,info,rect1,pos1); + if state * [shs_focused,shs_showfocusrect] = + [shs_focused,shs_showfocusrect] then begin + drawfocusrect(canvas,inflaterect(rect2,-focusrectdist)); + end; + rect2:= rect1; //outerframe + if innerframe <> nil then begin + deflaterect1(rect1,innerframe^); + end; + drawbuttoncaption(canvas,info,rect1,pos1,@rect2); + end; + if frame <> nil then begin + canvas.restore(); + inflaterect1(info.ca.dim,frame1); + frame.paintoverlay(canvas,info.ca.dim); + ca.dim:= rect3; + end; + end; + end; +end; + +initialization + buttontab:= tcustomtabulators.create; + buttontab.add(0,tak_left); +finalization + buttontab.free; +end. diff --git a/mseide-msegui/lib/common/kernel/mseskin.pas b/mseide-msegui/lib/common/kernel/mseskin.pas new file mode 100644 index 0000000..eb15d18 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseskin.pas @@ -0,0 +1,4385 @@ +{ MSEgui Copyright (c) 2008-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseskin; +{$ifdef FPC}{$mode objfpc}{$h+}{$goto on}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses,mseclasses,msegui,msescrollbar,mseedit, + msegraphics,msegraphutils,msebitmap,msestockobjects, + msetabs,msetoolbar,msedataedits,msemenus,msearrayprops,msegraphedits, + msesimplewidgets,mseshapes, + msegrids,msewidgets,msetypes,mseglob,msestrings,msedrawtext,mseguiglob; + +type + scrollbarskininfoty = record + svwidth: int32; //-2 -> default + svcolor: colorty; + svcolorpattern: colorty; + svcolorpatternclicked: colorty; + svcolorglyph: colorty; + svbuttonendlength: int32; //-2 -> default + svbuttonlength: int32; //-2 -> default + svbuttonminlength: int32; //-2 -> default + svindentstart: int32; //0 -> default + svindentend: int32; //0 -> default + svface: tfacecomp; + svface1: tfacecomp; + svface2: tfacecomp; + svfacebu: tfacecomp; + svfaceendbu: tfacecomp; + svframe: tframecomp; + svframebu: tframecomp; + svframeendbu1: tframecomp; + svframeendbu2: tframecomp; + end; + widgetcolorinfoty = record + svcolor: colorty; + svcolorcaptionframe: colorty; + end; + pwidgetcolorinfoty = ^widgetcolorinfoty; + widgetskininfoty = record + svface: tfacecomp; + svframe: tframecomp; + end; + containerskininfoty = record + svwidget: widgetskininfoty; +// face: tfacecomp; +// frame: tframecomp; + end; + groupboxskininfoty = record + svwidget: widgetskininfoty; +// face: tfacecomp; +// frame: tframecomp; + end; + toolbarskininfoty = record + svwidget: widgetskininfoty; +// face: tfacecomp; +// frame: tframecomp; + svbuttonface: tfacecomp; + svbuttonfacechecked: tfacecomp; + svbuttonframe: tframecomp; + svbuttonframechecked: tframecomp; + svbuttonframesep: tframecomp; + end; + gridpropskininfoty = record + svface: tfacecomp; + svframe: tframecomp; + end; + gridskininfoty = record + svwidget: widgetskininfoty; +// face: tfacecomp; +// frame: tframecomp; + svfixrows: gridpropskininfoty; + svfixcols: gridpropskininfoty; + svdatacols: gridpropskininfoty; + end; + buttonskininfoty = record + svcolor: colorty; + svwidget: widgetskininfoty; + svfont: toptionalfont; + svoptionsadd: buttonoptionsty; + svoptionsremove: buttonoptionsty; + end; + sliderskininfoty = record + svcolor: colorty; + svwidget: widgetskininfoty; + svsb_vert: scrollbarskininfoty; + svsb_horz: scrollbarskininfoty; + end; + stepbuttonskininfoty = record + svcolor: colorty; + svface: tfacecomp; + svframe: tframecomp; + end; + framebuttonskininfoty = record + svcolor: colorty; + svcolorglyph: colorty; + svface: tfacecomp; + svframe: tframecomp; + end; + tabsskininfoty = record + svcolor: colorty; + svcoloractive: colorty; + svframe: tframecomp; + svface: tfacecomp; + svfaceactive: tfacecomp; + svshift: integer; + svsedge_level: int32; + svsedge_colordkshadow: colorty; + svsedge_colorshadow: colorty; + svsedge_colorlight: colorty; + svsedge_colorhighlight: colorty; + svsedge_colordkwidth: int32; + svsedge_colorhlwidth: int32; + svsedge_imagelist: timagelist; + svsedge_imageoffset: int32; + svsedge_imagepaintshift: int32; + end; + tabbarskininfoty = record + svwidgethorz: widgetskininfoty; + svwidgetvert: widgetskininfoty; + svwidgethorzopo: widgetskininfoty; + svwidgetvertopo: widgetskininfoty; + svtabhorz: tabsskininfoty; + svtabvert: tabsskininfoty; + svtabhorzopo: tabsskininfoty; + svtabvertopo: tabsskininfoty; + end; + tabpageskininfoty = record + svwidget: widgetskininfoty; + svcolortab: colorty; + svcoloractivetab: colorty; + svfacetab: tfacecomp; + svfaceactivetab: tfacecomp; + svfonttab: tfontcomp; + svfontactivetab: tfontcomp; + end; + menuskininfoty = record + svface: tfacecomp; + svframe: tframecomp; + svitemface: tfacecomp; + svitemframe: tframecomp; + svitemfaceactive: tfacecomp; + svitemframeactive: tframecomp; + svfont: tfontcomp; + svfontactive: tfontcomp; + svseparatorframe: tframecomp; + svcheckboxframe: tframecomp; +// options: skinmenuoptionsty; + end; + mainmenuskininfoty = record + svmain: menuskininfoty; + svpopup: menuskininfoty; + end; + mainmenuwidgetskininfoty = record + svwidget: widgetskininfoty; + svmenu: mainmenuskininfoty; + end; + dispwidgetskininfoty = record + svwidget: widgetskininfoty; + svcolor: widgetcolorinfoty; + end; + editskininfoty = record + svwidget: widgetskininfoty; + svempty_text: msestring; + svempty_textflags: textflagsty; + svempty_textcolor: colorty; + svempty_textcolorbackground: colorty; + svempty_fontstyle: fontstylesty; + svempty_color: colorty; + end; + dataeditskininfoty = record + svedit: editskininfoty; + end; + graphdataeditskininfoty = record + svwidget: widgetskininfoty; + end; + booleaneditskininfoty = record + svgraphdataedit: graphdataeditskininfoty; + svoptionsadd: buttonoptionsty; + svoptionsremove: buttonoptionsty; + end; + splitterskininfoty = record + svwidget: widgetskininfoty; + svcolor: widgetcolorinfoty; + svcolorgrip: colorty; + svgrip: stockbitmapty; + end; + + + tskincolor = class(tvirtualpersistent) + private + fcolor: colorty; + frgb: colorty; + frgbbefore: colorty; + procedure setcolor(const avalue: colorty); + public + constructor create; override; + published + property color: colorty read fcolor write setcolor default cl_none; + property rgb: colorty read frgb write frgb; + end; + + tskincolors = class(tpersistentarrayprop) + private + fframecolors: framecolorinfoty; + fframecolorsbefore: framecolorinfoty; + feditfontcolors: editfontcolorinfoty; + feditfontcolorsbefore: editfontcolorinfoty; + public + constructor create; + class function getitemclasstype: persistentclassty; override; + procedure setcolors; + procedure restorecolors; + published + property colordkshadow: colorty read fframecolors.edges.shadow.effectcolor + write fframecolors.edges.shadow.effectcolor default cl_default; + property colorshadow: colorty read fframecolors.edges.shadow.color + write fframecolors.edges.shadow.color default cl_default; + property colorlight: colorty read fframecolors.edges.light.color + write fframecolors.edges.light.color default cl_default; + property colorhighlight: colorty read fframecolors.edges.light.effectcolor + write fframecolors.edges.light.effectcolor default cl_default; + property colordkwidth: integer read fframecolors.edges.shadow.effectwidth + write fframecolors.edges.shadow.effectwidth default -1; + property colorhlwidth: integer read fframecolors.edges.light.effectwidth + write fframecolors.edges.light.effectwidth default -1; + property colorframe: colorty read fframecolors.frame + write fframecolors.frame default cl_default; + property edittext: colorty read feditfontcolors.text + write feditfontcolors.text default cl_default; + property edittextbackground: colorty read feditfontcolors.textbackground + write feditfontcolors.textbackground default cl_default; + property editselectedtext: colorty read feditfontcolors.selectedtext + write feditfontcolors.selectedtext default cl_default; + property editselectedtextbackground: colorty + read feditfontcolors.selectedtextbackground + write feditfontcolors.selectedtextbackground default cl_default; + end; + + tskinfontalias = class(townedpersistent) + private + fname: string; + falias: string; + fmode: fontaliasmodety; + fheight: integer; + fwidth: integer; + foptions: fontoptionsty; + fancestor: string; + fxscale: real; + ftemplate: tfontcomp; + procedure settemplate(const avalue: tfontcomp); + public + constructor create(aowner: tobject); override; + published + property name: string read fname write fname; + property alias: string read falias write falias; + property ancestor: string read fancestor write fancestor; + property mode: fontaliasmodety read fmode write fmode + default fam_overwrite; + property height: integer read fheight write fheight default 0; + property width: integer read fwidth write fwidth default 0; + property options: fontoptionsty read foptions write foptions default []; + property xscale: real read fxscale write fxscale; + property template: tfontcomp read ftemplate write settemplate; + end; + + tcustomskincontroller = class; + + tskinfontaliass = class(townedpersistentarrayprop) + public + constructor create(const aowner: tcustomskincontroller); reintroduce; + class function getitemclasstype: persistentclassty; override; + procedure setfontalias; + end; + + createprocty = procedure of object; + + beforeskinupdateeventty = procedure(const sender: tcustomskincontroller; + const ainfo: skininfoty; var handled: boolean) of object; + skincontrollereventty = procedure(const sender: tcustomskincontroller; + const ainfo: skininfoty) of object; + + tskinextender = class(tmsecomponent) + private + fmaster: tcustomskincontroller; + procedure setmaster(const avalue: tcustomskincontroller); + protected + procedure doactivate; virtual; + procedure dodeactivate; virtual; + public + destructor destroy; override; + procedure updateskin(const ainfo: skininfoty; var handled: boolean); + reintroduce; virtual; + procedure removeskin(const ainfo: skininfoty; var handled: boolean); virtual; + published + property master: tcustomskincontroller read fmaster write setmaster; + end; + + skinextenderarty = array of tskinextender; + + tskinfont = class(tlinkedpersistent) + private + { + fcolor: colorty; + fshadow_color: colorty; + fshadow_shiftx: integer; + fshadow_shifty: integer; + fgloss_color: colorty; + fgloss_shiftx: integer; + fgloss_shifty: integer; + fgrayed_color: colorty; + fgrayed_colorshadow: colorty; + fgrayed_shiftx: integer; + fgrayed_shifty: integer; + fextraspace: integer; + fstyle: fontstylesty; + fcolorbackground: colorty; + } + ftemplate: tfontcomp; + procedure settemplate(const avalue: tfontcomp); + public +// constructor create; + procedure updatefont(const adest: tfont); + published + { + property color: colorty read fcolor write fcolor default cl_default; + property colorbackground: colorty read fcolorbackground + write fcolorbackground default cl_default; + property shadow_color: colorty read fshadow_color + write fshadow_color default cl_default; + property shadow_shiftx: integer read fshadow_shiftx write + fshadow_shiftx default 1; + property shadow_shifty: integer read fshadow_shifty write + fshadow_shifty default 1; + + property gloss_color: colorty read fgloss_color + write fgloss_color default cl_default; + property gloss_shiftx: integer read fgloss_shiftx write + fgloss_shiftx default -1; + property gloss_shifty: integer read fgloss_shifty write + fgloss_shifty default -1; + + property grayed_color: colorty read fgrayed_color + write fgrayed_color default cl_default; + property grayed_colorshadow: colorty read fgrayed_colorshadow + write fgrayed_colorshadow default cl_default; + property grayed_shiftx: integer read fgrayed_shiftx write + fgrayed_shiftx default 1; + property grayed_shifty: integer read fgrayed_shifty write + fgrayed_shifty default 1; + + property extraspace: integer read fextraspace write fextraspace default 0; + property style: fontstylesty read fstyle write fstyle default []; + } + property template: tfontcomp read ftemplate write settemplate; + end; + + groupinfoty = record + min: integer; + max: integer; + end; + groupinfoarty = array of groupinfoty; + + tcustomskincontroller = class(tmsecomponent) + private + fonbeforeupdate: beforeskinupdateeventty; + fonafterupdate: skincontrollereventty; + fonactivate: notifyeventty; + fondeactivate: notifyeventty; + fcolors: tskincolors; + ffontalias: tskinfontaliass; + fupdating: integer; + factive: boolean; + factivedesign: boolean; + fisactive: boolean; +// fremoving: boolean; + fskinfonts: array[stockfontty] of tskinfont; + fgroupinfo: groupinfoarty; + fgroups: string; + forder: integer; + fhotkey_fontstylesadd: fontstylesty; + fhotkey_fontstylesremove: fontstylesty; + fhotkey_color: colorty; + fhotkey_colorbackground: colorty; + procedure setactive(const avalue: boolean); + procedure setcolors(const avalue: tskincolors); + procedure setfontalias(const avalue: tskinfontaliass); + function getextenders: integer; + procedure setextenders(const avalue: integer); + procedure readextendernames(reader: treader); + procedure writeextendernames(writer: twriter); + procedure readactivedesign(reader: treader); +// procedure setactivedesign(const avalue: boolean); + function getskinfont(const aindex: integer): tskinfont; + procedure setskinfont(const aindex: integer; const avalue: tskinfont); + procedure setgroups(const avalue: string); + procedure checkactive; + procedure sethotkey_fontstylesadd(const avalue: fontstylesty); + procedure sethotkey_fontstylesremove(const avalue: fontstylesty); + procedure sethotkey_colorbackground(const avalue: colorty); + procedure sethotkey_color(const avalue: colorty); + procedure checkhotkey(); + protected + fextendernames: stringarty; + fextenders: skinextenderarty; + fhashotkey: boolean; + function getextendernames: stringarty; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + procedure updateorder; + procedure registerextender(const aextender: tskinextender); + procedure unregisterextender(const aextender: tskinextender); + + procedure doactivate; virtual; + procedure dodeactivate; virtual; + procedure loaded; override; + procedure defineproperties(filer: tfiler); override; + + procedure setfacetemplate(const face: tfacecomp; + const dest: tcustomface); + procedure setframetemplate(const frame: tframecomp; + const dest: tcustomframe); + + procedure setwidgetface(const instance: twidget; const aface: tfacecomp); +// procedure setwidgetfacetemplate(const instance: twidget; +// const aface: tfacecomp);//no face nil test + procedure setwidgetframe(const instance: twidget; const aframe: tframecomp); +// procedure setwidgetframetemplate(const instance: twidget; +// const aframe: tframecomp); //no fram nil check + procedure setwidgetskin(const instance: twidget; + const ainfo: widgetskininfoty); +// procedure setwidgetskintemplate(const instance: twidget; +// const ainfo: widgetskininfoty); + //overrides nil frame and face + procedure setgroupboxskin(const instance: tgroupbox; + const ainfo: groupboxskininfoty); + procedure setgridpropskin(const instance: tgridprop; + const ainfo: gridpropskininfoty); + procedure setgridskin(const instance: tcustomgrid; + const ainfo: gridskininfoty); + procedure seteditskin(const instance: tcustomedit; + const ainfo: editskininfoty); + procedure setdataeditskin(const instance: tdataedit; + const ainfo: dataeditskininfoty); + procedure setgraphdataeditskin(const instance: tgraphdataedit; + const ainfo: graphdataeditskininfoty); + procedure setwidgetfont(const instance: twidget; const afont: tfont); + procedure setwidgetcolor(const instance: twidget; const acolor: colorty); + function setwidgetcolorcaptionframe( + const awidget: twidget; const acolor: colorty): boolean; + procedure setscrollbarskin(const instance: tcustomscrollbar; + const ainfo: scrollbarskininfoty); + procedure setstepbuttonskin(const instance: tcustomstepframe; + const ainfo: stepbuttonskininfoty); + procedure setframebuttonskin(const instance: tframebutton; + const ainfo: framebuttonskininfoty); + procedure settabsskin(const instance: tcustomtabbar; + const ainfo: tabsskininfoty); + procedure setpopupmenuskin(const instance: tpopupmenu; + const ainfo: menuskininfoty); + procedure setmainmenuskin(const instance: tcustommainmenu; + const ainfo: mainmenuskininfoty); + + procedure handlewidget(const askin: skininfoty; + const acolor: pwidgetcolorinfoty = nil); virtual; + procedure handlecontainer(const ainfo: skininfoty); virtual; + procedure handlegroupbox(const ainfo: skininfoty); virtual; + procedure handlesimplebutton(const ainfo: skininfoty); virtual; + procedure handledatabutton(const ainfo: skininfoty); virtual; + procedure handleslider(const ainfo: skininfoty); virtual; + procedure handleuserobject(const ainfo: skininfoty); virtual; + procedure handletabbar(const ainfo: skininfoty); virtual; + procedure handletabpage(const ainfo: skininfoty); virtual; + procedure handletoolbar(const ainfo: skininfoty); virtual; + procedure handlesplitter(const ainfo: skininfoty); virtual; + procedure handledispwidget(const ainfo: skininfoty); virtual; + procedure handleedit(const ainfo: skininfoty); virtual; + procedure handledataedit(const ainfo: skininfoty); virtual; + procedure handlebooleanedit(const ainfo: skininfoty); virtual; + procedure handlemainmenu(const ainfo: skininfoty); virtual; + procedure handlepopupmenu(const ainfo: skininfoty); virtual; + procedure handlemainmenuwidget(const ainfo: skininfoty); virtual; + procedure handlegrid(const ainfo: skininfoty); virtual; + procedure updateskin1(const ainfo: skininfoty; const remove: boolean); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure updateskin(const ainfo: skininfoty); reintroduce; + // procedure removeskin(const ainfo: skininfoty); +// property removing: boolean read fremoving; + published + property order: integer read forder write forder default 0; //first! + //higher order executed first + property active: boolean read factive write setactive default false; +// property activedesign: boolean read factivedesign +// write setactivedesign default false; + //removed, too dangerous + property extenders: integer read getextenders write setextenders; + //hook for object inspector + property groups: string read fgroups write setgroups; + //format [[..]{,[..]}] + //empty -> all + property onbeforeupdate: beforeskinupdateeventty read fonbeforeupdate + write fonbeforeupdate; + property onafterupdate: skincontrollereventty read fonafterupdate + write fonafterupdate; + property onactivate: notifyeventty read fonactivate write fonactivate; + property ondeactivate: notifyeventty read fondeactivate write fondeactivate; + property colors: tskincolors read fcolors write setcolors; + property fontalias: tskinfontaliass read ffontalias write setfontalias; + + property font_default: tskinfont index ord(stf_default) //0 + read getskinfont write setskinfont; + property font_empty: tskinfont index ord(stf_empty) //1 + read getskinfont write setskinfont; + property font_unicode: tskinfont index ord(stf_unicode) //2 + read getskinfont write setskinfont; + property font_menu: tskinfont index ord(stf_menu) //3 + read getskinfont write setskinfont; + property font_message: tskinfont index ord(stf_message) //4 + read getskinfont write setskinfont; + property font_hint: tskinfont index ord(stf_hint) //5 + read getskinfont write setskinfont; + property font_report: tskinfont index ord(stf_report) //6 + read getskinfont write setskinfont; + property font_proportional: tskinfont index ord(stf_proportional) //7 + read getskinfont write setskinfont; + property font_fixed: tskinfont index ord(stf_fixed) //8 + read getskinfont write setskinfont; + property font_helvetica: tskinfont index ord(stf_helvetica) //9 + read getskinfont write setskinfont; + property font_roman: tskinfont index ord(stf_roman) //10 + read getskinfont write setskinfont; + property font_courier: tskinfont index ord(stf_courier) //11 + read getskinfont write setskinfont; + + property hotkey_fontstylesadd: fontstylesty read fhotkey_fontstylesadd + write sethotkey_fontstylesadd default []; + property hotkey_fontstylesremove: fontstylesty read fhotkey_fontstylesremove + write sethotkey_fontstylesremove default []; + property hotkey_color: colorty read fhotkey_color write sethotkey_color + default cl_default; + property hotkey_colorbackground: colorty read fhotkey_colorbackground + write sethotkey_colorbackground default cl_default; + end; + + tskincontroller = class(tcustomskincontroller) + private + fsb_horz: scrollbarskininfoty; + fsb_vert: scrollbarskininfoty; + fgroupbox: groupboxskininfoty; + fgrid: gridskininfoty; + fbutton: buttonskininfoty; + fdatabutton: buttonskininfoty; + fslider: sliderskininfoty; + fstepbutton: stepbuttonskininfoty; + fframebutton: framebuttonskininfoty; + fcontainer: containerskininfoty; + fwidgetcolor: widgetcolorinfoty; + ftabbar: tabbarskininfoty; + ftabpage: tabpageskininfoty; + ftoolbar_horz: toolbarskininfoty; + ftoolbar_vert: toolbarskininfoty; + fpopupmenu: menuskininfoty; + fmainmenu: mainmenuskininfoty; + fmainmenuwidget: mainmenuwidgetskininfoty; + fdispwidget: dispwidgetskininfoty; + fedit: editskininfoty; + fdataedit: dataeditskininfoty; + fbooleanedit: booleaneditskininfoty; + fsplitter: splitterskininfoty; + + procedure setsb_vert_face(const avalue: tfacecomp); + procedure setsb_vert_face1(const avalue: tfacecomp); + procedure setsb_vert_face2(const avalue: tfacecomp); + procedure setsb_vert_facebutton(const avalue: tfacecomp); + procedure setsb_vert_faceendbutton(const avalue: tfacecomp); + procedure setsb_vert_frame(const avalue: tframecomp); + procedure setsb_vert_framebutton(const avalue: tframecomp); + procedure setsb_vert_frameendbutton1(const avalue: tframecomp); + procedure setsb_vert_frameendbutton2(const avalue: tframecomp); + procedure setsb_horz_face(const avalue: tfacecomp); + procedure setsb_horz_face1(const avalue: tfacecomp); + procedure setsb_horz_face2(const avalue: tfacecomp); + procedure setsb_horz_facebutton(const avalue: tfacecomp); + procedure setsb_horz_faceendbutton(const avalue: tfacecomp); + procedure setsb_horz_frame(const avalue: tframecomp); + procedure setsb_horz_framebutton(const avalue: tframecomp); + procedure setsb_horz_frameendbutton1(const avalue: tframecomp); + procedure setsb_horz_frameendbutton2(const avalue: tframecomp); + + procedure setgroupbox_face(const avalue: tfacecomp); + procedure setgroupbox_frame(const avalue: tframecomp); + + procedure setgrid_face(const avalue: tfacecomp); + procedure setgrid_frame(const avalue: tframecomp); + procedure setgrid_fixrows_face(const avalue: tfacecomp); + procedure setgrid_fixrows_frame(const avalue: tframecomp); + procedure setgrid_fixcols_face(const avalue: tfacecomp); + procedure setgrid_fixcols_frame(const avalue: tframecomp); + procedure setgrid_datacols_face(const avalue: tfacecomp); + procedure setgrid_datacols_frame(const avalue: tframecomp); + + procedure setbutton_face(const avalue: tfacecomp); + procedure setbutton_frame(const avalue: tframecomp); + function getbutton_font: toptionalfont; + procedure setbutton_font(const avalue: toptionalfont); + + procedure setdatabutton_face(const avalue: tfacecomp); + procedure setdatabutton_frame(const avalue: tframecomp); + function getdatabutton_font: toptionalfont; + procedure setdatabutton_font(const avalue: toptionalfont); + + procedure setslider_face(const avalue: tfacecomp); + procedure setslider_frame(const avalue: tframecomp); + procedure setssb_vert_face(const avalue: tfacecomp); + procedure setssb_vert_face1(const avalue: tfacecomp); + procedure setssb_vert_face2(const avalue: tfacecomp); + procedure setssb_vert_facebutton(const avalue: tfacecomp); + procedure setssb_vert_faceendbutton(const avalue: tfacecomp); + procedure setssb_vert_frame(const avalue: tframecomp); + procedure setssb_vert_framebutton(const avalue: tframecomp); + procedure setssb_vert_frameendbutton1(const avalue: tframecomp); + procedure setssb_vert_frameendbutton2(const avalue: tframecomp); + procedure setssb_horz_face(const avalue: tfacecomp); + procedure setssb_horz_face1(const avalue: tfacecomp); + procedure setssb_horz_face2(const avalue: tfacecomp); + procedure setssb_horz_facebutton(const avalue: tfacecomp); + procedure setssb_horz_faceendbutton(const avalue: tfacecomp); + procedure setssb_horz_frame(const avalue: tframecomp); + procedure setssb_horz_framebutton(const avalue: tframecomp); + procedure setssb_horz_frameendbutton1(const avalue: tframecomp); + procedure setssb_horz_frameendbutton2(const avalue: tframecomp); + + procedure setframebutton_face(const avalue: tfacecomp); + procedure setframebutton_frame(const avalue: tframecomp); + + procedure setstepbutton_face(const avalue: tfacecomp); + procedure setstepbutton_frame(const avalue: tframecomp); + + procedure setsplitter_face(const avalue: tfacecomp); + procedure setsplitter_frame(const avalue: tframecomp); + + procedure setdispwidget_face(const avalue: tfacecomp); + procedure setdispwidget_frame(const avalue: tframecomp); + + procedure setedit_face(const avalue: tfacecomp); + procedure setedit_frame(const avalue: tframecomp); + + procedure setdataedit_face(const avalue: tfacecomp); + procedure setdataedit_frame(const avalue: tframecomp); + + procedure setbooleanedit_face(const avalue: tfacecomp); + procedure setbooleanedit_frame(const avalue: tframecomp); + + procedure setcontainer_face(const avalue: tfacecomp); + procedure setcontainer_frame(const avalue: tframecomp); + + procedure settabbar_horz_tab_edge_imagelist(const avalue: timagelist); + procedure settabbar_horz_face(const avalue: tfacecomp); + procedure settabbar_horz_frame(const avalue: tframecomp); + procedure settabbar_horz_tab_frame(const avalue: tframecomp); + procedure settabbar_horz_tab_face(const avalue: tfacecomp); + procedure settabbar_horz_tab_faceactive(const avalue: tfacecomp); + procedure settabbar_vert_tab_edge_imagelist(const avalue: timagelist); + procedure settabbar_vert_face(const avalue: tfacecomp); + procedure settabbar_vert_frame(const avalue: tframecomp); + procedure settabbar_vert_tab_frame(const avalue: tframecomp); + procedure settabbar_vert_tab_face(const avalue: tfacecomp); + procedure settabbar_vert_tab_faceactive(const avalue: tfacecomp); + + procedure settabbar_horzopo_tab_edge_imagelist(const avalue: timagelist); + procedure settabbar_horzopo_face(const avalue: tfacecomp); + procedure settabbar_horzopo_frame(const avalue: tframecomp); + procedure settabbar_horzopo_tab_frame(const avalue: tframecomp); + procedure settabbar_horzopo_tab_face(const avalue: tfacecomp); + procedure settabbar_horzopo_tab_faceactive(const avalue: tfacecomp); + procedure settabbar_vertopo_tab_edge_imagelist(const avalue: timagelist); + procedure settabbar_vertopo_face(const avalue: tfacecomp); + procedure settabbar_vertopo_frame(const avalue: tframecomp); + procedure settabbar_vertopo_tab_frame(const avalue: tframecomp); + procedure settabbar_vertopo_tab_face(const avalue: tfacecomp); + procedure settabbar_vertopo_tab_faceactive(const avalue: tfacecomp); + + procedure settabpage_face(const avalue: tfacecomp); + procedure settabpage_facetab(const avalue: tfacecomp); + procedure settabpage_faceactivetab(const avalue: tfacecomp); + procedure settabpage_frame(const avalue: tframecomp); + procedure settabpage_fonttab(const avalue: tfontcomp); + procedure settabpage_fontactivetab(const avalue: tfontcomp); + + procedure settoolbar_horz_face(const avalue: tfacecomp); + procedure settoolbar_horz_frame(const avalue: tframecomp); + procedure settoolbar_horz_buttonface(const avalue: tfacecomp); + procedure settoolbar_horz_buttonfacechecked(const avalue: tfacecomp); + procedure settoolbar_horz_buttonframe(const avalue: tframecomp); + procedure settoolbar_horz_buttonframechecked(const avalue: tframecomp); + procedure settoolbar_horz_buttonframesep(const avalue: tframecomp); + procedure settoolbar_vert_face(const avalue: tfacecomp); + procedure settoolbar_vert_frame(const avalue: tframecomp); + procedure settoolbar_vert_buttonface(const avalue: tfacecomp); + procedure settoolbar_vert_buttonfacechecked(const avalue: tfacecomp); + procedure settoolbar_vert_buttonframe(const avalue: tframecomp); + procedure settoolbar_vert_buttonframechecked(const avalue: tframecomp); + procedure settoolbar_vert_buttonframesep(const avalue: tframecomp); + + + procedure setpopupmenu_face(const avalue: tfacecomp); + procedure setpopupmenu_frame(const avalue: tframecomp); + procedure setpopupmenu_itemface(const avalue: tfacecomp); + procedure setpopupmenu_itemframe(const avalue: tframecomp); + procedure setpopupmenu_itemfaceactive(const avalue: tfacecomp); + procedure setpopupmenu_itemframeactive(const avalue: tframecomp); + procedure setpopupmenu_font(const avalue: tfontcomp); + procedure setpopupmenu_fontactive(const avalue: tfontcomp); + procedure setpopupmenu_separatorframe(const avalue: tframecomp); + procedure setpopupmenu_checkboxframe(const avalue: tframecomp); + + procedure setmainmenu_face(const avalue: tfacecomp); + procedure setmainmenu_frame(const avalue: tframecomp); + procedure setmainmenu_itemface(const avalue: tfacecomp); + procedure setmainmenu_itemframe(const avalue: tframecomp); + procedure setmainmenu_itemfaceactive(const avalue: tfacecomp); + procedure setmainmenu_itemframeactive(const avalue: tframecomp); + procedure setmainmenu_font(const avalue: tfontcomp); + procedure setmainmenu_fontactive(const avalue: tfontcomp); + procedure setmainmenu_separatorframe(const avalue: tframecomp); + procedure setmainmenu_checkboxframe(const avalue: tframecomp); + procedure setmainmenu_popupface(const avalue: tfacecomp); + procedure setmainmenu_popupframe(const avalue: tframecomp); + procedure setmainmenu_popupitemface(const avalue: tfacecomp); + procedure setmainmenu_popupitemframe(const avalue: tframecomp); + procedure setmainmenu_popupitemfaceactive(const avalue: tfacecomp); + procedure setmainmenu_popupitemframeactive(const avalue: tframecomp); + procedure setmainmenu_popupfont(const avalue: tfontcomp); + procedure setmainmenu_popupfontactive(const avalue: tfontcomp); + procedure setmainmenu_popupseparatorframe(const avalue: tframecomp); + procedure setmainmenu_popupcheckboxframe(const avalue: tframecomp); + + procedure setmainmenuwidget_face(const avalue: tfacecomp); + procedure setmainmenuwidget_frame(const avalue: tframecomp); + procedure setmainmenuwidget_itemface(const avalue: tfacecomp); + procedure setmainmenuwidget_itemframe(const avalue: tframecomp); + procedure setmainmenuwidget_itemfaceactive(const avalue: tfacecomp); + procedure setmainmenuwidget_itemframeactive(const avalue: tframecomp); + procedure setmainmenuwidget_font(const avalue: tfontcomp); + procedure setmainmenuwidget_fontactive(const avalue: tfontcomp); + procedure setmainmenuwidget_separatorframe(const avalue: tframecomp); + procedure setmainmenuwidget_checkboxframe(const avalue: tframecomp); + procedure setmainmenuwidget_popupface(const avalue: tfacecomp); + procedure setmainmenuwidget_popupframe(const avalue: tframecomp); + procedure setmainmenuwidget_popupitemface(const avalue: tfacecomp); + procedure setmainmenuwidget_popupitemframe(const avalue: tframecomp); + procedure setmainmenuwidget_popupitemfaceactive(const avalue: tfacecomp); + procedure setmainmenuwidget_popupitemframeactive(const avalue: tframecomp); + procedure setmainmenuwidget_popupfont(const avalue: tfontcomp); + procedure setmainmenuwidget_popupfontactive(const avalue: tfontcomp); + procedure setmainmenuwidget_popupseparatorframe(const avalue: tframecomp); + procedure setmainmenuwidget_popupcheckboxframe(const avalue: tframecomp); + protected + procedure handlewidget(const askin: skininfoty; + const acolor: pwidgetcolorinfoty = nil); override; + procedure handlecontainer(const ainfo: skininfoty); override; + procedure handlegroupbox(const ainfo: skininfoty); override; + procedure handlesimplebutton(const ainfo: skininfoty); override; + procedure handledatabutton(const ainfo: skininfoty); override; + procedure handleslider(const ainfo: skininfoty); override; + procedure handletabbar(const ainfo: skininfoty); override; + procedure handletabpage(const ainfo: skininfoty); override; + procedure handletoolbar(const ainfo: skininfoty); override; + procedure handlesplitter(const ainfo: skininfoty); override; + procedure handledispwidget(const ainfo: skininfoty); override; + procedure handleedit(const ainfo: skininfoty); override; + procedure handledataedit(const ainfo: skininfoty); override; + procedure handlebooleanedit(const ainfo: skininfoty); override; + procedure handlemainmenu(const ainfo: skininfoty); override; + procedure handlepopupmenu(const ainfo: skininfoty); override; + procedure handlemainmenuwidget(const ainfo: skininfoty); override; + procedure handlegrid(const ainfo: skininfoty); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure createbutton_font; + procedure createdatabutton_font; + published + property sb_horz_width: int32 read fsb_horz.svwidth + write fsb_horz.svwidth default -2; + property sb_horz_color: colorty + read fsb_horz.svcolor + write fsb_horz.svcolor default cl_default; + property sb_horz_colorpattern: colorty + read fsb_horz.svcolorpattern + write fsb_horz.svcolorpattern default cl_default; + property sb_horz_colorpatternclicked: colorty + read fsb_horz.svcolorpatternclicked + write fsb_horz.svcolorpatternclicked default cl_default; + property sb_horz_colorglyph: colorty + read fsb_horz.svcolorglyph + write fsb_horz.svcolorglyph default cl_default; + property sb_horz_buttonendlength: int32 read fsb_horz.svbuttonendlength + write fsb_horz.svbuttonendlength default -2; + property sb_horz_buttonlength: int32 read fsb_horz.svbuttonlength + write fsb_horz.svbuttonlength default -2; + property sb_horz_buttonminlength: int32 read fsb_horz.svbuttonminlength + write fsb_horz.svbuttonminlength default -2; + property sb_horz_indentstart: int32 read fsb_horz.svindentstart + write fsb_horz.svindentstart default 0; + property sb_horz_indentend: int32 read fsb_horz.svindentend + write fsb_horz.svindentend default 0; + property sb_horz_face: tfacecomp read fsb_horz.svface + write setsb_horz_face; + property sb_horz_face1: tfacecomp read fsb_horz.svface1 + write setsb_horz_face1; + property sb_horz_face2: tfacecomp read fsb_horz.svface2 + write setsb_horz_face2; + property sb_horz_facebutton: tfacecomp read fsb_horz.svfacebu + write setsb_horz_facebutton; + property sb_horz_faceendbutton: tfacecomp read fsb_horz.svfaceendbu + write setsb_horz_faceendbutton; + property sb_horz_frame: tframecomp read fsb_horz.svframe + write setsb_horz_frame; + property sb_horz_framebutton: tframecomp read fsb_horz.svframebu + write setsb_horz_framebutton; + property sb_horz_frameendbutton1: tframecomp read fsb_horz.svframeendbu1 + write setsb_horz_frameendbutton1; + property sb_horz_frameendbutton2: tframecomp read fsb_horz.svframeendbu2 + write setsb_horz_frameendbutton2; + + property sb_vert_width: int32 read fsb_vert.svwidth + write fsb_vert.svwidth default -2; + property sb_vert_color: colorty read fsb_vert.svcolor + write fsb_vert.svcolor default cl_default; + property sb_vert_colorpattern: colorty read fsb_vert.svcolorpattern + write fsb_vert.svcolorpattern default cl_default; + property sb_vert_colorpatternclicked: colorty + read fsb_vert.svcolorpatternclicked + write fsb_vert.svcolorpatternclicked default cl_default; + property sb_vert_colorglyph: colorty + read fsb_vert.svcolorglyph + write fsb_vert.svcolorglyph default cl_default; + property sb_vert_buttonendlength: int32 read fsb_vert.svbuttonendlength + write fsb_vert.svbuttonendlength default -2; + property sb_vert_buttonlength: int32 read fsb_vert.svbuttonlength + write fsb_vert.svbuttonlength default -2; + property sb_vert_buttonminlength: int32 read fsb_vert.svbuttonminlength + write fsb_vert.svbuttonminlength default -2; + property sb_vert_indentstart: int32 read fsb_vert.svindentstart + write fsb_vert.svindentstart default 0; + property sb_vert_indentend: int32 read fsb_vert.svindentend + write fsb_vert.svindentend default 0; + property sb_vert_face: tfacecomp read fsb_vert.svface + write setsb_vert_face; + property sb_vert_face1: tfacecomp read fsb_vert.svface1 + write setsb_vert_face1; + property sb_vert_face2: tfacecomp read fsb_vert.svface2 + write setsb_vert_face2; + property sb_vert_facebutton: tfacecomp read fsb_vert.svfacebu + write setsb_vert_facebutton; + property sb_vert_faceendbutton: tfacecomp read fsb_vert.svfaceendbu + write setsb_vert_faceendbutton; + property sb_vert_frame: tframecomp read fsb_vert.svframe + write setsb_vert_frame; + property sb_vert_framebutton: tframecomp read fsb_vert.svframebu + write setsb_vert_framebutton; + property sb_vert_frameendbutton1: tframecomp read fsb_vert.svframeendbu1 + write setsb_vert_frameendbutton1; + property sb_vert_frameendbutton2: tframecomp read fsb_vert.svframeendbu2 + write setsb_vert_frameendbutton2; + + property stepbutton_color: colorty read fstepbutton.svcolor + write fstepbutton.svcolor default cl_default; + property stepbutton_frame: tframecomp read fstepbutton.svframe + write setstepbutton_frame; + property stepbutton_face: tfacecomp read fstepbutton.svface + write setstepbutton_face; + + property widget_color: colorty read fwidgetcolor.svcolor + write fwidgetcolor.svcolor default cl_default; + property widget_colorcaptionframe: colorty + read fwidgetcolor.svcolorcaptionframe + write fwidgetcolor.svcolorcaptionframe default cl_default; + //overrides widget_color for widgets with frame caption + + property splitter_color: colorty read fsplitter.svcolor.svcolor + write fsplitter.svcolor.svcolor default cl_default; + property splitter_colorcaptionframe: colorty + read fsplitter.svcolor.svcolorcaptionframe + write fsplitter.svcolor.svcolorcaptionframe default cl_default; + //overrides widget_color for widgets with frame caption + property splitter_colorgrip: colorty read fsplitter.svcolorgrip + write fsplitter.svcolorgrip default cl_default; + property splitter_grip: stockbitmapty read fsplitter.svgrip + write fsplitter.svgrip default stb_default; + property splitter_face: tfacecomp read fsplitter.svwidget.svface + write setsplitter_face; + property splitter_frame: tframecomp read fsplitter.svwidget.svframe + write setsplitter_frame; + + property dispwidget_color: colorty read fdispwidget.svcolor.svcolor + write fdispwidget.svcolor.svcolor default cl_default; + property dispwidget_colorcaptionframe: colorty + read fdispwidget.svcolor.svcolorcaptionframe + write fdispwidget.svcolor.svcolorcaptionframe default cl_default; + //overrides widget_color for widgets with frame caption + property dispwidget_face: tfacecomp read fdispwidget.svwidget.svface + write setdispwidget_face; + property dispwidget_frame: tframecomp read fdispwidget.svwidget.svframe + write setdispwidget_frame; + + property dataedit_face: tfacecomp read fdataedit.svedit.svwidget.svface + write setdataedit_face; + property dataedit_frame: tframecomp read fdataedit.svedit.svwidget.svframe + write setdataedit_frame; + property dataedit_empty_text: msestring read fdataedit.svedit.svempty_text + write fdataedit.svedit.svempty_text; + property dataedit_empty_color: colorty read fdataedit.svedit.svempty_color + write fdataedit.svedit.svempty_color default cl_default; + property dataedit_empty_fontstyle: fontstylesty + read fdataedit.svedit.svempty_fontstyle + write fdataedit.svedit.svempty_fontstyle default []; + property dataedit_empty_textflags: textflagsty + read fdataedit.svedit.svempty_textflags + write fdataedit.svedit.svempty_textflags default []; + property dataedit_empty_textcolor: colorty + read fdataedit.svedit.svempty_textcolor + write fdataedit.svedit.svempty_textcolor default cl_default; + property dataedit_empty_textcolorbackground: colorty + read fdataedit.svedit.svempty_textcolorbackground + write fdataedit.svedit.svempty_textcolorbackground default cl_default; + + property edit_face: tfacecomp read fedit.svwidget.svface + write setedit_face; + property edit_frame: tframecomp read fedit.svwidget.svframe + write setedit_frame; + property edit_empty_text: msestring read fedit.svempty_text + write fedit.svempty_text; + property edit_empty_color: colorty read fedit.svempty_color + write fedit.svempty_color default cl_default; + property edit_empty_fontstyle: fontstylesty + read fedit.svempty_fontstyle + write fedit.svempty_fontstyle default []; + property edit_empty_textflags: textflagsty + read fedit.svempty_textflags + write fedit.svempty_textflags default []; + property edit_empty_textcolor: colorty + read fedit.svempty_textcolor + write fedit.svempty_textcolor default cl_default; + property edit_empty_textcolorbackground: colorty + read fedit.svempty_textcolorbackground + write fedit.svempty_textcolorbackground default cl_default; + + property booleanedit_face: tfacecomp + read fbooleanedit.svgraphdataedit.svwidget.svface + write setbooleanedit_face; + property booleanedit_frame: tframecomp + read fbooleanedit.svgraphdataedit.svwidget.svframe + write setbooleanedit_frame; + property booleanedit_optionsadd: buttonoptionsty + read fbooleanedit.svoptionsadd + write fbooleanedit.svoptionsadd default[]; + property booleanedit_optionsremove: buttonoptionsty + read fbooleanedit.svoptionsremove + write fbooleanedit.svoptionsremove default[]; + + property container_face: tfacecomp read fcontainer.svwidget.svface + write setcontainer_face; + property container_frame: tframecomp read fcontainer.svwidget.svframe + write setcontainer_frame; + property groupbox_face: tfacecomp read fgroupbox.svwidget.svface + write setgroupbox_face; + property groupbox_frame: tframecomp read fgroupbox.svwidget.svframe + write setgroupbox_frame; + + property grid_face: tfacecomp read fgrid.svwidget.svface write setgrid_face; + property grid_frame: tframecomp read fgrid.svwidget.svframe + write setgrid_frame; + property grid_fixrows_face: tfacecomp read fgrid.svfixrows.svface + write setgrid_fixrows_face; + property grid_fixrows_frame: tframecomp read fgrid.svfixrows.svframe + write setgrid_fixrows_frame; + property grid_fixcols_face: tfacecomp read fgrid.svfixcols.svface + write setgrid_fixcols_face; + property grid_fixcols_frame: tframecomp read fgrid.svfixcols.svframe + write setgrid_fixcols_frame; + property grid_datacols_face: tfacecomp read fgrid.svdatacols.svface + write setgrid_datacols_face; + property grid_datacols_frame: tframecomp read fgrid.svdatacols.svframe + write setgrid_datacols_frame; + + property button_color: colorty read fbutton.svcolor write fbutton.svcolor + default cl_default; + property button_face: tfacecomp read fbutton.svwidget.svface + write setbutton_face; + property button_frame: tframecomp read fbutton.svwidget.svframe + write setbutton_frame; + property button_font: toptionalfont read getbutton_font write setbutton_font; + property button_optionsadd: buttonoptionsty read fbutton.svoptionsadd + write fbutton.svoptionsadd default[]; + property button_optionsremove: buttonoptionsty read fbutton.svoptionsremove + write fbutton.svoptionsremove default[]; + + property databutton_color: colorty read fdatabutton.svcolor + write fdatabutton.svcolor default cl_default; + property databutton_face: tfacecomp read fdatabutton.svwidget.svface + write setdatabutton_face; + property databutton_frame: tframecomp read fdatabutton.svwidget.svframe + write setdatabutton_frame; + property databutton_font: toptionalfont read getdatabutton_font + write setdatabutton_font; + property databutton_optionsadd: buttonoptionsty + read fdatabutton.svoptionsadd + write fdatabutton.svoptionsadd default[]; + property databutton_optionsremove: buttonoptionsty + read fbooleanedit.svoptionsremove + write fdatabutton.svoptionsremove default[]; + + property slider_color: colorty read fslider.svcolor + write fslider.svcolor default cl_default; + property slider_face: tfacecomp read fslider.svwidget.svface + write setslider_face; + property slider_frame: tframecomp read fslider.svwidget.svframe + write setslider_frame; + + property slider_sb_horz_width: int32 read fslider.svsb_horz.svwidth + write fslider.svsb_horz.svwidth default -2; + property slider_sb_horz_color: colorty + read fslider.svsb_horz.svcolor + write fslider.svsb_horz.svcolor default cl_default; + property slider_sb_horz_colorpattern: colorty + read fslider.svsb_horz.svcolorpattern + write fslider.svsb_horz.svcolorpattern default cl_default; + property slider_sb_horz_colorpatternclicked: colorty + read fslider.svsb_horz.svcolorpatternclicked + write fslider.svsb_horz.svcolorpatternclicked default cl_default; + property slider_sb_horz_colorglyph: colorty + read fslider.svsb_horz.svcolorglyph + write fslider.svsb_horz.svcolorglyph default cl_default; + property slider_sb_horz_buttonendlength: int32 + read fslider.svsb_horz.svbuttonendlength + write fslider.svsb_horz.svbuttonendlength default -2; + property slider_sb_horz_buttonlength: int32 + read fslider.svsb_horz.svbuttonlength + write fslider.svsb_horz.svbuttonlength default -2; + property slider_sb_horz_buttonminlength: int32 + read fslider.svsb_horz.svbuttonminlength + write fslider.svsb_horz.svbuttonminlength default -2; + property slider_sb_horz_indentstart: int32 + read fslider.svsb_horz.svindentstart + write fslider.svsb_horz.svindentstart default 0; + property slider_sb_horz_indentend: int32 read fslider.svsb_horz.svindentend + write fslider.svsb_horz.svindentend default 0; + property slider_sb_horz_face: tfacecomp + read fslider.svsb_horz.svface + write setssb_horz_face; + property slider_sb_horz_face1: tfacecomp + read fslider.svsb_horz.svface1 + write setssb_horz_face1; + property slider_sb_horz_face2: tfacecomp + read fslider.svsb_horz.svface2 + write setssb_horz_face2; + property slider_sb_horz_facebutton: tfacecomp + read fslider.svsb_horz.svfacebu + write setssb_horz_facebutton; + property slider_sb_horz_faceendbutton: tfacecomp + read fslider.svsb_horz.svfaceendbu + write setssb_horz_faceendbutton; + property slider_sb_horz_frame: tframecomp + read fslider.svsb_horz.svframe + write setssb_horz_frame; + property slider_sb_horz_framebutton: tframecomp + read fslider.svsb_horz.svframebu + write setssb_horz_framebutton; + property slider_sb_horz_frameendbutton1: tframecomp + read fslider.svsb_horz.svframeendbu1 + write setssb_horz_frameendbutton1; + property slider_sb_horz_frameendbutton2: tframecomp + read fslider.svsb_horz.svframeendbu2 + write setssb_horz_frameendbutton2; + + property slider_sb_vert_width: int32 read fslider.svsb_vert.svwidth + write fslider.svsb_vert.svwidth default -2; + property slider_sb_vert_color: colorty + read fslider.svsb_vert.svcolor + write fslider.svsb_vert.svcolor default cl_default; + property slider_sb_vert_colorpattern: colorty + read fslider.svsb_vert.svcolorpattern + write fslider.svsb_vert.svcolorpattern default cl_default; + property slider_sb_vert_colorpatternclicked: colorty + read fslider.svsb_vert.svcolorpatternclicked + write fslider.svsb_vert.svcolorpatternclicked default cl_default; + property slider_sb_vert_colorglyph: colorty + read fslider.svsb_vert.svcolorglyph + write fslider.svsb_vert.svcolorglyph default cl_default; + property slider_sb_vert_buttonendlength: int32 + read fslider.svsb_vert.svbuttonendlength + write fslider.svsb_vert.svbuttonendlength default -2; + property slider_sb_vert_buttonlength: int32 + read fslider.svsb_vert.svbuttonlength + write fslider.svsb_vert.svbuttonlength default -2; + property slider_sb_vert_buttonminlength: int32 + read fslider.svsb_vert.svbuttonminlength + write fslider.svsb_vert.svbuttonminlength default -2; + property slider_sb_vert_indentstart: int32 + read fslider.svsb_vert.svindentstart + write fslider.svsb_horz.svindentstart default 0; + property slider_sb_vert_indentend: int32 read fslider.svsb_vert.svindentend + write fslider.svsb_vert.svindentend default 0; + property slider_sb_vert_face: tfacecomp + read fslider.svsb_vert.svface + write setssb_vert_face; + property slider_sb_vert_face1: tfacecomp + read fslider.svsb_vert.svface1 + write setssb_vert_face1; + property slider_sb_vert_face2: tfacecomp + read fslider.svsb_vert.svface2 + write setssb_vert_face2; + property slider_sb_vert_facebutton: tfacecomp + read fslider.svsb_vert.svfacebu + write setssb_vert_facebutton; + property slider_sb_vert_faceendbutton: tfacecomp + read fslider.svsb_vert.svfaceendbu + write setssb_vert_faceendbutton; + property slider_sb_vert_frame: tframecomp + read fslider.svsb_vert.svframe + write setssb_vert_frame; + property slider_sb_vert_framebutton: tframecomp + read fslider.svsb_vert.svframebu + write setssb_vert_framebutton; + property slider_sb_vert_frameendbutton1: tframecomp + read fslider.svsb_vert.svframeendbu1 + write setssb_vert_frameendbutton1; + property slider_sb_vert_frameendbutton2: tframecomp + read fslider.svsb_vert.svframeendbu2 + write setssb_vert_frameendbutton2; + + + property framebutton_color: colorty read fframebutton.svcolor + write fframebutton.svcolor default cl_default; + property framebutton_colorglyph: colorty read fframebutton.svcolorglyph + write fframebutton.svcolorglyph default cl_default; + property framebutton_face: tfacecomp read fframebutton.svface + write setframebutton_face; + property framebutton_frame: tframecomp read fframebutton.svframe + write setframebutton_frame; + + property tabbar_horz_face: tfacecomp read ftabbar.svwidgethorz.svface + write settabbar_horz_face; + property tabbar_horz_frame: tframecomp read ftabbar.svwidgethorz.svframe + write settabbar_horz_frame; + property tabbar_horz_tab_color: colorty read ftabbar.svtabhorz.svcolor + write ftabbar.svtabhorz.svcolor default cl_default; + property tabbar_horz_tab_coloractive: colorty + read ftabbar.svtabhorz.svcoloractive + write ftabbar.svtabhorz.svcoloractive default cl_default; + property tabbar_horz_tab_frame: tframecomp read ftabbar.svtabhorz.svframe + write settabbar_horz_tab_frame; + property tabbar_horz_tab_face: tfacecomp read ftabbar.svtabhorz.svface + write settabbar_horz_tab_face; + property tabbar_horz_tab_faceactive: tfacecomp + read ftabbar.svtabhorz.svfaceactive + write settabbar_horz_tab_faceactive; + property tabbar_horz_tab_shift: integer read ftabbar.svtabhorz.svshift + write ftabbar.svtabhorz.svshift default defaulttabshift; + property tabbar_horz_tab_edge_level: int32 + read ftabbar.svtabhorz.svsedge_level + write ftabbar.svtabhorz.svsedge_level default defaultedgelevel; + //defaultedgelevel (-100) -> -1 + property tabbar_horz_tab_edge_colordkshadow: colorty + read ftabbar.svtabhorz.svsedge_colordkshadow + write ftabbar.svtabhorz.svsedge_colordkshadow default cl_default; + property tabbar_horz_tab_edge_colorshadow: colorty + read ftabbar.svtabhorz.svsedge_colorshadow + write ftabbar.svtabhorz.svsedge_colorshadow default cl_default; + property tabbar_horz_tab_edge_colorlight: colorty + read ftabbar.svtabhorz.svsedge_colorlight + write ftabbar.svtabhorz.svsedge_colorlight default cl_default; + property tabbar_horz_tab_edge_colorhighlight: colorty + read ftabbar.svtabhorz.svsedge_colorhighlight + write ftabbar.svtabhorz.svsedge_colorhighlight default cl_default; + property tabbar_horz_tab_edge_colordkwidth: int32 + read ftabbar.svtabhorz.svsedge_colordkwidth + write ftabbar.svtabhorz.svsedge_colordkwidth default -1; + //-1 = default + property tabbar_horz_tab_edge_colorhlwidth: int32 + read ftabbar.svtabhorz.svsedge_colorhlwidth + write ftabbar.svtabhorz.svsedge_colorhlwidth default -1; + //-1 = default + property tabbar_horz_tab_edge_imagelist: timagelist + read ftabbar.svtabhorz.svsedge_imagelist + write settabbar_horz_tab_edge_imagelist; + //imagenr 0 -> startpoint, 1 -> edge, imagenr 2 -> endpoint + property tabbar_horz_tab_edge_imageoffset: int32 + read ftabbar.svtabhorz.svsedge_imageoffset + write ftabbar.svtabhorz.svsedge_imageoffset default 0; + property tabbar_horz_tab_edge_imagepaintshift: int32 + read ftabbar.svtabhorz.svsedge_imagepaintshift + write ftabbar.svtabhorz.svsedge_imagepaintshift default 0; + + property tabbar_horzopo_face: tfacecomp read ftabbar.svwidgethorzopo.svface + write settabbar_horzopo_face; + property tabbar_horzopo_frame: tframecomp + read ftabbar.svwidgethorzopo.svframe + write settabbar_horzopo_frame; + property tabbar_horzopo_tab_color: colorty read ftabbar.svtabhorzopo.svcolor + write ftabbar.svtabhorzopo.svcolor default cl_default; + property tabbar_horzopo_tab_coloractive: colorty + read ftabbar.svtabhorzopo.svcoloractive + write ftabbar.svtabhorzopo.svcoloractive default cl_default; + property tabbar_horzopo_tab_frame: tframecomp + read ftabbar.svtabhorzopo.svframe + write settabbar_horzopo_tab_frame; + property tabbar_horzopo_tab_face: tfacecomp read ftabbar.svtabhorzopo.svface + write settabbar_horzopo_tab_face; + property tabbar_horzopo_tab_faceactive: tfacecomp + read ftabbar.svtabhorzopo.svfaceactive + write settabbar_horzopo_tab_faceactive; + property tabbar_horzopo_tab_shift: integer read ftabbar.svtabhorzopo.svshift + write ftabbar.svtabhorzopo.svshift default defaulttabshift; + property tabbar_horzopo_tab_edge_level: int32 + read ftabbar.svtabhorzopo.svsedge_level + write ftabbar.svtabhorzopo.svsedge_level default defaultedgelevel; + //defaultedgelevel (-100) -> -1 + property tabbar_horzopo_tab_edge_colordkshadow: colorty + read ftabbar.svtabhorzopo.svsedge_colordkshadow + write ftabbar.svtabhorzopo.svsedge_colordkshadow default cl_default; + property tabbar_horzopo_tab_edge_colorshadow: colorty + read ftabbar.svtabhorzopo.svsedge_colorshadow + write ftabbar.svtabhorzopo.svsedge_colorshadow default cl_default; + property tabbar_horzopo_tab_edge_colorlight: colorty + read ftabbar.svtabhorzopo.svsedge_colorlight + write ftabbar.svtabhorzopo.svsedge_colorlight default cl_default; + property tabbar_horzopo_tab_edge_colorhighlight: colorty + read ftabbar.svtabhorzopo.svsedge_colorhighlight + write ftabbar.svtabhorzopo.svsedge_colorhighlight default cl_default; + property tabbar_horzopo_tab_edge_colordkwidth: int32 + read ftabbar.svtabhorzopo.svsedge_colordkwidth + write ftabbar.svtabhorzopo.svsedge_colordkwidth default -1; + //-1 = default + property tabbar_horzopo_tab_edge_colorhlwidth: int32 + read ftabbar.svtabhorzopo.svsedge_colorhlwidth + write ftabbar.svtabhorzopo.svsedge_colorhlwidth default -1; + //-1 = default + property tabbar_horzopo_tab_edge_imagelist: timagelist + read ftabbar.svtabhorzopo.svsedge_imagelist + write settabbar_horzopo_tab_edge_imagelist; + //imagenr 0 -> startpoint, 1 -> edge, imagenr 2 -> endpoint + property tabbar_horzopo_tab_edge_imageoffset: int32 + read ftabbar.svtabhorzopo.svsedge_imageoffset + write ftabbar.svtabhorzopo.svsedge_imageoffset default 0; + property tabbar_horzopo_tab_edge_imagepaintshift: int32 + read ftabbar.svtabhorzopo.svsedge_imagepaintshift + write ftabbar.svtabhorzopo.svsedge_imagepaintshift default 0; + + property tabbar_vert_face: tfacecomp read ftabbar.svwidgetvert.svface + write settabbar_vert_face; + property tabbar_vert_frame: tframecomp read ftabbar.svwidgetvert.svframe + write settabbar_vert_frame; + property tabbar_vert_tab_color: colorty read ftabbar.svtabvert.svcolor + write ftabbar.svtabvert.svcolor + default cl_default; + property tabbar_vert_tab_coloractive: colorty + read ftabbar.svtabvert.svcoloractive + write ftabbar.svtabvert.svcoloractive default cl_default; + property tabbar_vert_tab_frame: tframecomp read ftabbar.svtabvert.svframe + write settabbar_vert_tab_frame; + property tabbar_vert_tab_face: tfacecomp read ftabbar.svtabvert.svface + write settabbar_vert_tab_face; + property tabbar_vert_tab_faceactive: tfacecomp + read ftabbar.svtabvert.svfaceactive + write settabbar_vert_tab_faceactive; + property tabbar_vert_tab_shift: integer read ftabbar.svtabvert.svshift + write ftabbar.svtabvert.svshift default defaulttabshift; + property tabbar_vert_tab_edge_level: int32 + read ftabbar.svtabvert.svsedge_level + write ftabbar.svtabvert.svsedge_level default defaultedgelevel; + //defaultedgelevel (-100) -> -1 + property tabbar_vert_tab_edge_colordkshadow: colorty + read ftabbar.svtabvert.svsedge_colordkshadow + write ftabbar.svtabvert.svsedge_colordkshadow default cl_default; + property tabbar_vert_tab_edge_colorshadow: colorty + read ftabbar.svtabvert.svsedge_colorshadow + write ftabbar.svtabvert.svsedge_colorshadow default cl_default; + property tabbar_vert_tab_edge_colorlight: colorty + read ftabbar.svtabvert.svsedge_colorlight + write ftabbar.svtabvert.svsedge_colorlight default cl_default; + property tabbar_vert_tab_edge_colorhighlight: colorty + read ftabbar.svtabvert.svsedge_colorhighlight + write ftabbar.svtabvert.svsedge_colorhighlight default cl_default; + property tabbar_vert_tab_edge_colordkwidth: int32 + read ftabbar.svtabvert.svsedge_colordkwidth + write ftabbar.svtabvert.svsedge_colordkwidth default -1; + //-1 = default + property tabbar_vert_tab_edge_colorhlwidth: int32 + read ftabbar.svtabvert.svsedge_colorhlwidth + write ftabbar.svtabvert.svsedge_colorhlwidth default -1; + //-1 = default + property tabbar_vert_tab_edge_imagelist: timagelist + read ftabbar.svtabvert.svsedge_imagelist + write settabbar_vert_tab_edge_imagelist; + //imagenr 0 -> startpoint, 1 -> edge, imagenr 2 -> endpoint + property tabbar_vert_tab_edge_imageoffset: int32 + read ftabbar.svtabvert.svsedge_imageoffset + write ftabbar.svtabvert.svsedge_imageoffset default 0; + property tabbar_vert_tab_edge_imagepaintshift: int32 + read ftabbar.svtabvert.svsedge_imagepaintshift + write ftabbar.svtabvert.svsedge_imagepaintshift default 0; + + property tabbar_vertopo_face: tfacecomp read ftabbar.svwidgetvertopo.svface + write settabbar_vertopo_face; + property tabbar_vertopo_frame: tframecomp + read ftabbar.svwidgetvertopo.svframe + write settabbar_vertopo_frame; + property tabbar_vertopo_tab_color: colorty read ftabbar.svtabvertopo.svcolor + write ftabbar.svtabvertopo.svcolor default cl_default; + property tabbar_vertopo_tab_coloractive: colorty + read ftabbar.svtabvertopo.svcoloractive + write ftabbar.svtabvertopo.svcoloractive default cl_default; + property tabbar_vertopo_tab_frame: tframecomp + read ftabbar.svtabvertopo.svframe + write settabbar_vertopo_tab_frame; + property tabbar_vertopo_tab_face: tfacecomp + read ftabbar.svtabvertopo.svface + write settabbar_vertopo_tab_face; + property tabbar_vertopo_tab_faceactive: tfacecomp + read ftabbar.svtabvertopo.svfaceactive + write settabbar_vertopo_tab_faceactive; + property tabbar_vertopo_tab_shift: integer read ftabbar.svtabvertopo.svshift + write ftabbar.svtabvertopo.svshift default defaulttabshift; + property tabbar_vertopo_tab_edge_level: int32 + read ftabbar.svtabvertopo.svsedge_level + write ftabbar.svtabvertopo.svsedge_level default defaultedgelevel; + //defaultedgelevel (-100) -> -1 + property tabbar_vertopo_tab_edge_colordkshadow: colorty + read ftabbar.svtabvertopo.svsedge_colordkshadow + write ftabbar.svtabvertopo.svsedge_colordkshadow default cl_default; + property tabbar_vertopo_tab_edge_colorshadow: colorty + read ftabbar.svtabvertopo.svsedge_colorshadow + write ftabbar.svtabvertopo.svsedge_colorshadow default cl_default; + property tabbar_vertopo_tab_edge_colorlight: colorty + read ftabbar.svtabvertopo.svsedge_colorlight + write ftabbar.svtabvertopo.svsedge_colorlight default cl_default; + property tabbar_vertopo_tab_edge_colorhighlight: colorty + read ftabbar.svtabvertopo.svsedge_colorhighlight + write ftabbar.svtabvertopo.svsedge_colorhighlight default cl_default; + property tabbar_vertopo_tab_edge_colordkwidth: int32 + read ftabbar.svtabvertopo.svsedge_colordkwidth + write ftabbar.svtabvertopo.svsedge_colordkwidth default -1; + //-1 = default + property tabbar_vertopo_tab_edge_colorhlwidth: int32 + read ftabbar.svtabvertopo.svsedge_colorhlwidth + write ftabbar.svtabvertopo.svsedge_colorhlwidth default -1; + //-1 = default + property tabbar_vertopo_tab_edge_imagelist: timagelist + read ftabbar.svtabvertopo.svsedge_imagelist + write settabbar_vertopo_tab_edge_imagelist; + //imagenr 0 -> startpoint, 1 -> edge, imagenr 2 -> endpoint + property tabbar_vertopo_tab_edge_imageoffset: int32 + read ftabbar.svtabvertopo.svsedge_imageoffset + write ftabbar.svtabvertopo.svsedge_imageoffset default 0; + property tabbar_vertopo_tab_edge_imagepaintshift: int32 + read ftabbar.svtabvertopo.svsedge_imagepaintshift + write ftabbar.svtabvertopo.svsedge_imagepaintshift default 0; + + property toolbar_horz_face: tfacecomp read ftoolbar_horz.svwidget.svface + write settoolbar_horz_face; + property toolbar_horz_frame: tframecomp read ftoolbar_horz.svwidget.svframe + write settoolbar_horz_frame; + property toolbar_horz_buttonface: tfacecomp read ftoolbar_horz.svbuttonface + write settoolbar_horz_buttonface; + property toolbar_horz_buttonframe: tframecomp + read ftoolbar_horz.svbuttonframe + write settoolbar_horz_buttonframe; + property toolbar_horz_buttonframesep: tframecomp + read ftoolbar_horz.svbuttonframesep + write settoolbar_horz_buttonframesep; + property toolbar_vert_face: tfacecomp read ftoolbar_vert.svwidget.svface + write settoolbar_vert_face; + property toolbar_vert_frame: tframecomp read ftoolbar_vert.svwidget.svframe + write settoolbar_vert_frame; + property toolbar_vert_buttonface: tfacecomp read ftoolbar_vert.svbuttonface + write settoolbar_vert_buttonface; + property toolbar_vert_buttonframe: tframecomp + read ftoolbar_vert.svbuttonframe + write settoolbar_vert_buttonframe; + property toolbar_vert_buttonframesep: tframecomp + read ftoolbar_vert.svbuttonframesep + write settoolbar_vert_buttonframesep; + + property tabpage_face: tfacecomp read ftabpage.svwidget.svface + write settabpage_face; + property tabpage_frame: tframecomp read ftabpage.svwidget.svframe + write settabpage_frame; + property tabpage_colortab: colorty read ftabpage.svcolortab + write ftabpage.svcolortab default cl_default; + property tabpage_coloractive: colorty read ftabpage.svcoloractivetab + write ftabpage.svcoloractivetab default cl_default; + property tabpage_facetab: tfacecomp read ftabpage.svfacetab + write settabpage_facetab; + property tabpage_faceactivetab: tfacecomp read ftabpage.svfaceactivetab + write settabpage_faceactivetab; + property tabpage_fonttab: tfontcomp read ftabpage.svfonttab + write settabpage_fonttab; + property tabpage_fontactivetab: tfontcomp read ftabpage.svfontactivetab + write settabpage_fontactivetab; +{ + property popupmenu_options: skinmenuoptionsty read fpopupmenu.options + write fpopupmenu.options default []; +} + property popupmenu_face: tfacecomp read fpopupmenu.svface + write setpopupmenu_face; + property popupmenu_frame: tframecomp read fpopupmenu.svframe + write setpopupmenu_frame; + property popupmenu_itemface: tfacecomp read fpopupmenu.svitemface + write setpopupmenu_itemface; + property popupmenu_itemframe: tframecomp read fpopupmenu.svitemframe + write setpopupmenu_itemframe; + property popupmenu_itemfaceactive: tfacecomp read fpopupmenu.svitemfaceactive + write setpopupmenu_itemfaceactive; + property popupmenu_itemframeactive: tframecomp + read fpopupmenu.svitemframeactive write setpopupmenu_itemframeactive; + property popupmenu_font: tfontcomp read fpopupmenu.svfont + write setpopupmenu_font; + property popupmenu_fontactive: tfontcomp + read fpopupmenu.svfontactive + write setpopupmenu_fontactive; + property popupmenu_separatorframe: tframecomp read + fpopupmenu.svseparatorframe write setpopupmenu_separatorframe; + property popupmenu_checkboxframe: tframecomp read fpopupmenu.svcheckboxframe + write setpopupmenu_checkboxframe; +{ + property mainmenu_options: skinmenuoptionsty read fmainmenu.ma.options + write fmainmenu.ma.options default []; +} + property mainmenu_face: tfacecomp read fmainmenu.svmain.svface + write setmainmenu_face; + property mainmenu_frame: tframecomp read fmainmenu.svmain.svframe + write setmainmenu_frame; + property mainmenu_itemface: tfacecomp read fmainmenu.svmain.svitemface + write setmainmenu_itemface; + property mainmenu_itemframe: tframecomp read fmainmenu.svmain.svitemframe + write setmainmenu_itemframe; + property mainmenu_itemfaceactive: tfacecomp + read fmainmenu.svmain.svitemfaceactive + write setmainmenu_itemfaceactive; + property mainmenu_itemframeactive: tframecomp + read fmainmenu.svmain.svitemframeactive + write setmainmenu_itemframeactive; + property mainmenu_font: tfontcomp read fmainmenu.svmain.svfont + write setmainmenu_font; + property mainmenu_fontactive: tfontcomp read fmainmenu.svmain.svfontactive + write setmainmenu_fontactive; + property mainmenu_separatorframe: tframecomp + read fmainmenu.svmain.svseparatorframe + write setmainmenu_separatorframe; + property mainmenu_checkboxframe: tframecomp + read fmainmenu.svmain.svcheckboxframe + write setmainmenu_checkboxframe; + + property mainmenu_popupface: tfacecomp read fmainmenu.svpopup.svface + write setmainmenu_popupface; + property mainmenu_popupframe: tframecomp read fmainmenu.svpopup.svframe + write setmainmenu_popupframe; + property mainmenu_popupitemface: tfacecomp read fmainmenu.svpopup.svitemface + write setmainmenu_popupitemface; + property mainmenu_popupitemframe: tframecomp + read fmainmenu.svpopup.svitemframe + write setmainmenu_popupitemframe; + property mainmenu_popupitemfaceactive: tfacecomp + read fmainmenu.svpopup.svitemfaceactive + write setmainmenu_popupitemfaceactive; + property mainmenu_popupitemframeactive: tframecomp + read fmainmenu.svpopup.svitemframeactive + write setmainmenu_popupitemframeactive; + property mainmenu_popupfont: tfontcomp read fmainmenu.svpopup.svfont + write setmainmenu_popupfont; + property mainmenu_popupfontactive: tfontcomp + read fmainmenu.svpopup.svfontactive + write setmainmenu_popupfontactive; + property mainmenu_popupseparatorframe: tframecomp + read fmainmenu.svpopup.svseparatorframe + write setmainmenu_popupseparatorframe; + property mainmenu_popupcheckboxframe: tframecomp + read fmainmenu.svpopup.svcheckboxframe + write setmainmenu_popupcheckboxframe; + + property mainmenuwidget_face: tfacecomp read fmainmenuwidget.svwidget.svface + write setmainmenuwidget_face; + property mainmenuwidget_frame: tframecomp + read fmainmenuwidget.svwidget.svframe + write setmainmenuwidget_frame; + property mainmenuwidget_itemface: tfacecomp read fmainmenuwidget.svmenu.svmain.svitemface + write setmainmenuwidget_itemface; + property mainmenuwidget_itemframe: tframecomp read fmainmenuwidget.svmenu.svmain.svitemframe + write setmainmenuwidget_itemframe; + property mainmenuwidget_itemfaceactive: tfacecomp + read fmainmenuwidget.svmenu.svmain.svitemfaceactive + write setmainmenuwidget_itemfaceactive; + property mainmenuwidget_itemframeactive: tframecomp + read fmainmenuwidget.svmenu.svmain.svitemframeactive + write setmainmenuwidget_itemframeactive; + property mainmenuwidget_font: tfontcomp read fmainmenuwidget.svmenu.svmain.svfont + write setmainmenuwidget_font; + property mainmenuwidget_fontactive: tfontcomp read fmainmenuwidget.svmenu.svmain.svfontactive + write setmainmenuwidget_fontactive; + property mainmenuwidget_separatorframe: tframecomp + read fmainmenuwidget.svmenu.svmain.svseparatorframe + write setmainmenuwidget_separatorframe; + property mainmenuwidget_checkboxframe: tframecomp + read fmainmenuwidget.svmenu.svmain.svcheckboxframe + write setmainmenuwidget_checkboxframe; + + property mainmenuwidget_popupface: tfacecomp read fmainmenuwidget.svmenu.svpopup.svface + write setmainmenuwidget_popupface; + property mainmenuwidget_popupframe: tframecomp read fmainmenuwidget.svmenu.svpopup.svframe + write setmainmenuwidget_popupframe; + property mainmenuwidget_popupitemface: tfacecomp read fmainmenuwidget.svmenu.svpopup.svitemface + write setmainmenuwidget_popupitemface; + property mainmenuwidget_popupitemframe: tframecomp + read fmainmenuwidget.svmenu.svpopup.svitemframe + write setmainmenuwidget_popupitemframe; + property mainmenuwidget_popupitemfaceactive: tfacecomp + read fmainmenuwidget.svmenu.svpopup.svitemfaceactive + write setmainmenuwidget_popupitemfaceactive; + property mainmenuwidget_popupitemframeactive: tframecomp + read fmainmenuwidget.svmenu.svpopup.svitemframeactive + write setmainmenuwidget_popupitemframeactive; + property mainmenuwidget_popupfont: tfontcomp read fmainmenuwidget.svmenu.svpopup.svfont + write setmainmenuwidget_popupfont; + property mainmenuwidget_popupfontactive: tfontcomp + read fmainmenuwidget.svmenu.svpopup.svfontactive + write setmainmenuwidget_popupfontactive; + property mainmenuwidget_popupseparatorframe: tframecomp + read fmainmenuwidget.svmenu.svpopup.svseparatorframe + write setmainmenuwidget_popupseparatorframe; + property mainmenuwidget_popupcheckboxframe: tframecomp + read fmainmenuwidget.svmenu.svpopup.svcheckboxframe + write setmainmenuwidget_popupcheckboxframe; + end; + + skincontrollerarty = array of tcustomskincontroller; + + tskinhandler = class + protected + factiveskincontroller: skincontrollerarty; + procedure setactive(const sender: tcustomskincontroller; + var controllerar: skincontrollerarty; + const handleproc: skineventty; var handlevar: skineventty{; + const removeproc: skineventty; var removevar: skineventty}); + procedure updateactive(const sender: tcustomskincontroller); virtual; + procedure doactivate(const sender: tcustomskincontroller); virtual; + procedure dodeactivate(const sender: tcustomskincontroller); virtual; + procedure updateskin1(const ainfo: skininfoty; + const controllerar: skincontrollerarty); +// procedure removeskin1(const ainfo: skininfoty; +// const controllerar: skincontrollerarty); + procedure updateskin(const ainfo: skininfoty); +// procedure removeskin(const ainfo: skininfoty); + end; + +//function activeskincontroller: skincontrollerarty; +//function activeskincontrollerdesign: skincontrollerarty; +procedure setskinhandler(const avalue: tskinhandler); + +implementation +uses + msetabsglob,sysutils,mseapplication,msearrayutils,msefont,msesplitter, + msemenuwidgets,mserichstring; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + twidget1 = class(twidget); + tframe1 = class(tcustomframe); + tcustomframe1 = class(tcustomframe); + ttabs1 = class(ttabs); + tmenuitem1 = class(tmenuitem); +var + fhandler: tskinhandler; + +procedure setskinhandler(const avalue: tskinhandler); +begin + fhandler.free; + fhandler:= avalue; +end; +{ +function activeskincontroller: skincontrollerarty; +begin + result:= factiveskincontroller; +end; + +function activeskincontrollerdesign: skincontrollerarty; +begin + result:= factiveskincontrollerdesign; +end; +} +{ tskincolor } + +constructor tskincolor.create; +begin + fcolor:= cl_none; +end; + +procedure tskincolor.setcolor(const avalue: colorty); +begin + if not isvalidmapcolor(avalue) then begin + raise exception.create('Invalid map color.'); + end; + fcolor:= avalue; +end; + +{ tskincolors } + +constructor tskincolors.create; +begin + with fframecolors,edges do begin + light.color:= cl_default; + light.effectcolor:= cl_default; + light.effectwidth:= -1; + shadow.color:= cl_default; + shadow.effectcolor:= cl_default; + shadow.effectwidth:= -1; + frame:= cl_default; + end; + with feditfontcolors do begin + text:= cl_default; + textbackground:= cl_default; + selectedtext:= cl_default; + selectedtextbackground:= cl_default; + end; + inherited create(tskincolor); +end; + +class function tskincolors.getitemclasstype: persistentclassty; +begin + result:= tskincolor; +end; + +procedure tskincolors.setcolors; +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + with tskincolor(fitems[int1]) do begin + frgbbefore:= colorty(colortorgb(color)); + setcolormapvalue(fcolor,frgb); + end; + end; + fframecolorsbefore:= defaultframecolors; + with fframecolors.edges.light do begin + if color <> cl_default then begin + defaultframecolors.edges.light.color:= color; + end; + if effectcolor <> cl_default then begin + defaultframecolors.edges.light.effectcolor:= effectcolor; + end; + if effectwidth <> -1 then begin + defaultframecolors.edges.light.effectwidth:= effectwidth; + end; + end; + with fframecolors.edges.shadow do begin + if color <> cl_default then begin + defaultframecolors.edges.shadow.color:= color; + end; + if effectcolor <> cl_default then begin + defaultframecolors.edges.shadow.effectcolor:= effectcolor; + end; + if effectwidth <> -1 then begin + defaultframecolors.edges.shadow.effectwidth:= effectwidth; + end; + end; + if fframecolors.frame <> cl_default then begin + defaultframecolors.frame:= fframecolors.frame; + end; + feditfontcolorsbefore:= defaulteditfontcolors; + if feditfontcolors.text <> cl_default then begin + defaulteditfontcolors.text:= feditfontcolors.text; + end; + if feditfontcolors.textbackground <> cl_default then begin + defaulteditfontcolors.textbackground:= feditfontcolors.textbackground; + end; + if feditfontcolors.selectedtext <> cl_default then begin + defaulteditfontcolors.selectedtext:= feditfontcolors.selectedtext; + end; + if feditfontcolors.selectedtextbackground <> cl_default then begin + defaulteditfontcolors.selectedtextbackground:= + feditfontcolors.selectedtextbackground; + end; +end; + +procedure tskincolors.restorecolors; +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + with tskincolor(fitems[int1]) do begin + setcolormapvalue(fcolor,frgbbefore); + end; + end; + defaultframecolors:= fframecolorsbefore; + defaulteditfontcolors:= feditfontcolorsbefore; +end; + +{ tskinfontaliass } + +constructor tskinfontaliass.create(const aowner: tcustomskincontroller); +begin + inherited create(aowner,tskinfontalias); +end; + +class function tskinfontaliass.getitemclasstype: persistentclassty; +begin + result:= tskinfontalias; +end; + +procedure tskinfontaliass.setfontalias; +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + with tskinfontalias(fitems[int1]) do begin + if fancestor <> '' then begin + registerfontalias(alias,name,mode,height,width,options,xscale, + ancestor,template); + end + else begin + registerfontalias(alias,name,mode,height,width,options,xscale, + defaultfontalias,template); + end; + end; + end; +end; + +{ tcustomskincontroller } + +constructor tcustomskincontroller.create(aowner: tcomponent); +var + fo1: stockfontty; +begin + fcolors:= tskincolors.create; + ffontalias:= tskinfontaliass.create(self); + for fo1:= low(stockfontty) to high(stockfontty) do begin + fskinfonts[fo1]:= tskinfont.create; + end; + fhotkey_color:= cl_default; + fhotkey_colorbackground:= cl_default; + inherited; +end; + +destructor tcustomskincontroller.destroy; +var + fo1: stockfontty; +begin + active:= false; + inherited; + fcolors.free; + ffontalias.free; + for fo1:= low(stockfontty) to high(stockfontty) do begin + fskinfonts[fo1].free; + end; +end; + +procedure tcustomskincontroller.doactivate; +var + int1: integer; + fo1: stockfontty; +begin + fcolors.setcolors; + ffontalias.setfontalias; + for fo1:= low(stockfontty) to high(stockfontty) do begin + fskinfonts[fo1].updatefont(stockobjects.fonts[fo1]); + end; + checkhotkey(); + if canevent(tmethod(fonactivate)) then begin + fonactivate(self); + end; + updateorder; + for int1:= 0 to high(fextenders) do begin + fextenders[int1].doactivate; + end; +end; + +procedure tcustomskincontroller.dodeactivate; +var + int1: integer; +begin + if canevent(tmethod(fondeactivate)) then begin + fondeactivate(self); + end; + updateorder; + for int1:= 0 to high(fextenders) do begin + fextenders[int1].dodeactivate; + end; +end; + +procedure tcustomskincontroller.loaded; +begin + inherited; + if factive and not (csdesigning in componentstate) then begin + doactivate; + end; +end; + +procedure tcustomskincontroller.checkactive; +var + bo1: boolean; +begin + factivedesign:= factivedesign and factive; + bo1:= factive and (factivedesign or not (csdesigning in componentstate)); + if (fisactive <> bo1) and (fhandler <> nil) then begin + fisactive:= bo1; + if not (csloading in componentstate) and not fisactive then begin + dodeactivate; + fhandler.dodeactivate(self); + end; + fhandler.updateactive(self); + if not (csloading in componentstate) and fisactive then begin + doactivate; + fhandler.doactivate(self); + end; + end; +end; + +procedure tcustomskincontroller.sethotkey_fontstylesadd( + const avalue: fontstylesty); +begin + fhotkey_fontstylesadd:= avalue; + checkhotkey(); +end; + +procedure tcustomskincontroller.sethotkey_fontstylesremove( + const avalue: fontstylesty); +begin + fhotkey_fontstylesremove:= avalue; + checkhotkey(); +end; + +procedure tcustomskincontroller.sethotkey_color(const avalue: colorty); +begin + fhotkey_color:= avalue; + checkhotkey(); +end; + +procedure tcustomskincontroller.sethotkey_colorbackground( + const avalue: colorty); +begin + fhotkey_colorbackground:= avalue; + checkhotkey(); +end; + +procedure tcustomskincontroller.checkhotkey(); +begin + fhashotkey:= false; + if factive and + (factivedesign or not (csdesigning in componentstate)) then begin + if fhotkey_fontstylesadd <> [] then begin + hotkeyfontstylesadd:= fhotkey_fontstylesadd; + fhashotkey:= true; + end; + if fhotkey_fontstylesremove <> [] then begin + hotkeyfontstylesremove:= fhotkey_fontstylesremove; + fhashotkey:= true; + end; + if fhotkey_color <> cl_default then begin + hotkeycolor:= fhotkey_color; + fhashotkey:= true; + end; + if fhotkey_colorbackground <> cl_default then begin + hotkeycolorbackground:= fhotkey_colorbackground; + fhashotkey:= true; + end; + end; +end; + +procedure tcustomskincontroller.setactive(const avalue: boolean); +begin + factive:= avalue; + checkactive; +end; +{ +procedure tcustomskincontroller.setactivedesign(const avalue: boolean); +begin + factivedesign:= avalue; + checkactive; +end; +} +procedure tcustomskincontroller.updateskin1(const ainfo: skininfoty; + const remove: boolean); +label + endlab; +var + bo1,bo2: boolean; + int1: integer; +begin + if factive then begin +// fremoving:= remove; + bo1:= false; + if assigned(fonbeforeupdate) then begin + fonbeforeupdate(self,ainfo,bo1); + end; + if not bo1 then begin + if fupdating = 0 then begin + inc(fupdating); + try + bo2:= false; + for int1:= 0 to high(fextenders) do begin + fextenders[int1].updateskin(ainfo,bo2); + end; + finally + dec(fupdating); + end; + if bo2 then begin + goto endlab; + end; + end; + case ainfo.objectkind of //todo: use table + sok_widget: begin + handlewidget(ainfo); + end; + sok_splitter: begin + handlesplitter(ainfo); + end; + sok_dispwidget: begin + handledispwidget(ainfo); + end; + sok_edit: begin + handleedit(ainfo); + end; + sok_dataedit: begin + handledataedit(ainfo); + end; + sok_booleanedit: begin + handlebooleanedit(ainfo); + end; + sok_groupbox: begin + handlegroupbox(ainfo); + end; + sok_simplebutton: begin + handlesimplebutton(ainfo); + end; + sok_databutton: begin + handledatabutton(ainfo); + end; + sok_slider: begin + handleslider(ainfo); + end; + sok_tabbar: begin + handletabbar(ainfo); + end; + sok_tabpage: begin + handletabpage(ainfo); + end; + sok_toolbar: begin + handletoolbar(ainfo); + end; + sok_mainmenu: begin + handlemainmenu(ainfo); + end; + sok_popupmenu: begin + handlepopupmenu(ainfo); + end; + sok_mainmenuwidget: begin + handlemainmenuwidget(ainfo); + end; + sok_grid: begin + handlegrid(ainfo); + end; + sok_user: begin + handleuserobject(ainfo); + end; + end; + if (sko_container in ainfo.options) and + (ainfo.instance is twidget) then begin + handlecontainer(ainfo); + end; + end; +endlab: + if assigned(fonafterupdate) then begin + fonafterupdate(self,ainfo); + end; + end; +end; + +procedure tcustomskincontroller.updateskin(const ainfo: skininfoty); +begin + updateskin1(ainfo,false); +end; +{ +procedure tcustomskincontroller.removeskin(const ainfo: skininfoty); +begin + updateskin1(ainfo,true); +end; +} +procedure tcustomskincontroller.handlewidget(const askin: skininfoty; + const acolor: pwidgetcolorinfoty = nil); +begin + //dummy +end; + +procedure tcustomskincontroller.setfacetemplate(const face: tfacecomp; + const dest: tcustomface); +begin + if (face <> nil) and (dest.template = nil) then begin + dest.template:= face; + end; +end; + +procedure tcustomskincontroller.setframetemplate(const frame: tframecomp; + const dest: tcustomframe); +begin + if (frame <> nil) and (dest.template = nil) then begin + dest.template:= frame; + end; +end; + +procedure tcustomskincontroller.setwidgetface(const instance: twidget; + const aface: tfacecomp); +begin + with instance do begin + if (aface <> nil) and (optionsskin * + [osk_framebuttononly,osk_noface] = []) then begin + createface; + if face.template = nil then begin + face.template:= aface; + end; + end; + end; +end; +{ +procedure tcustomskincontroller.setwidgetfacetemplate(const instance: twidget; + const aface: tfacecomp); +begin + with instance do begin + if (aface <> nil) and not (osk_framebuttononly in optionsskin) then begin + createface; + face.template:= aface; + end; + end; +end; +} +procedure tcustomskincontroller.setwidgetframe(const instance: twidget; + const aframe: tframecomp); +var + size1: sizety; + col1: colorty; + frame1: framety; + opt1: frameskincontrolleroptionsty; +begin + with twidget1(instance) do begin + if (aframe <> nil) and (optionsskin * + [osk_framebuttononly,osk_noframe] = []) then begin + if fframe = nil then begin + createframe; + include(tcustomframe1(fframe).fstate,fs_paintposinited); + end; + if frame.template <> nil then begin + exit; + end; + col1:= frame.colorclient; + size1:= clientsize; + addsize1(size1,aframe.template.clientsizeextend); + with tframe1(frame).fpaintframedelta do begin + size1.cx:= size1.cx + left + right; + size1.cy:= size1.cy + top + bottom; + end; + frame1:= innerclientframe; + fframe.template:= aframe; + opt1:= aframe.template.optionsskincontroller; + if not (fsco_colorclient in opt1) then begin +// tframe1(frame).fi.colorclient:= col1; //restore + frame.colorclient:= col1; + end; + with tframe1(frame).fi.innerframe do begin + if fsco_frameirightsize in opt1 then begin + size1.cx:= size1.cx + right - frame1.right; + end; + if fsco_frameileftsize in opt1 then begin + size1.cx:= size1.cx + left - frame1.left; + end; + if fsco_frameitopsize in opt1 then begin + size1.cy:= size1.cy + top - frame1.top; + end; + if fsco_frameibottomsize in opt1 then begin + size1.cy:= size1.cy + bottom - frame1.bottom; + end; + end; + with tframe1(frame).fpaintframedelta do begin + size1.cx:= size1.cx - left - right; + size1.cy:= size1.cy - top - bottom; + end; + if not (osk_noclientsize in optionsskin) and + not (fsco_noclientsize in opt1) then begin + clientsize:= size1; //same clientsize as before + end; + end; + end; +end; +{ +procedure tcustomskincontroller.setwidgetframetemplate(const instance: twidget; + const aframe: tframecomp); //no frame nil check +var + size1: sizety; + col1: colorty; +begin + with twidget1(instance) do begin + if (aframe <> nil) and not (osk_framebuttononly in optionsskin) then begin + if fframe = nil then begin + createframe; + include(tcustomframe1(fframe).fstate,fs_paintposinited); + end; + if frame.template = nil then begin + col1:= frame.colorclient; + size1:= clientsize; + frame.template:= aframe; + frame.colorclient:= col1; + clientsize:= size1; //same clientsize as before + end; + end; + end; +end; +} +procedure tcustomskincontroller.setwidgetskin(const instance: twidget; + const ainfo: widgetskininfoty); +begin + setwidgetface(instance,ainfo.svface); + setwidgetframe(instance,ainfo.svframe); +// if fhashotkey then begin +// instance.updatehotkeys(); +// end; +end; +{ +procedure tcustomskincontroller.setwidgetskintemplate(const instance: twidget; + const ainfo: widgetskininfoty); +begin + setwidgetfacetemplate(instance,ainfo.fa); + setwidgetframetemplate(instance,ainfo.fra); +end; +} +procedure tcustomskincontroller.setgroupboxskin(const instance: tgroupbox; + const ainfo: groupboxskininfoty); +begin + setwidgetskin(instance,ainfo.svwidget); +// setwidgetface(instance,ainfo.face); +// setwidgetframetemplate(instance,ainfo.frame); +end; + +procedure tcustomskincontroller.setgridpropskin(const instance: tgridprop; + const ainfo: gridpropskininfoty); +begin + if ainfo.svface <> nil then begin + with instance do begin + createface; + setfacetemplate(ainfo.svface,face); + end; + end; + if ainfo.svframe <> nil then begin + with instance do begin + createframe; + setframetemplate(ainfo.svframe,frame); + end; + end; +end; + +procedure tcustomskincontroller.setgridskin(const instance: tcustomgrid; + const ainfo: gridskininfoty); +var + int1{,int2}: integer; +begin + setwidgetskin(instance,ainfo.svwidget); +// setwidgetface(instance,ainfo.face); +// setwidgetframetemplate(instance,ainfo.frame); + with ainfo do begin + for int1:= -1 downto -instance.fixrows.count do begin + setgridpropskin(instance.fixrows[int1],ainfo.svfixrows); + end; + for int1:= -1 downto -instance.fixcols.count do begin + setgridpropskin(instance.fixcols[int1],ainfo.svfixcols); + end; + for int1:= 0 to instance.datacols.count - 1 do begin + setgridpropskin(instance.datacols[int1],ainfo.svdatacols); + end; + end; +end; + +procedure tcustomskincontroller.seteditskin(const instance: tcustomedit; + const ainfo: editskininfoty); +begin + setwidgetskin(instance,ainfo.svwidget); + with instance do begin + if (ainfo.svempty_text <> '') and (empty_text = '') and + (eo_defaulttext in empty_options) then begin + empty_text:= ainfo.svempty_text; + end; + if (ainfo.svempty_textflags <> []) and + not(tf_force in empty_textflags) then begin + empty_textflags:= ainfo.svempty_textflags; + end; + if (ainfo.svempty_textcolor <> cl_default) and + (empty_textcolor = cl_none) then begin + empty_textcolor:= ainfo.svempty_textcolor; + end; + if (ainfo.svempty_textcolorbackground <> cl_default) and + (empty_textcolorbackground = cl_none) then begin + empty_textcolorbackground:= ainfo.svempty_textcolor; + end; + if (ainfo.svempty_fontstyle <> []) and + not(fs_force in empty_fontstyle) then begin + empty_fontstyle:= ainfo.svempty_fontstyle; + end; + if (ainfo.svempty_color <> cl_default) and + (empty_color = cl_none) then begin + empty_color:= ainfo.svempty_color; + end; + end; +end; + +procedure tcustomskincontroller.setdataeditskin(const instance: tdataedit; + const ainfo: dataeditskininfoty); +begin + seteditskin(instance,ainfo.svedit); +end; + +procedure tcustomskincontroller.setgraphdataeditskin( + const instance: tgraphdataedit; const ainfo: graphdataeditskininfoty); +begin + setwidgetskin(instance,ainfo.svwidget); +// setwidgetface(instance,ainfo.face); +// setwidgetframetemplate(instance,ainfo.frame); +end; + +procedure tcustomskincontroller.setwidgetfont(const instance: twidget; + const afont: tfont); +begin + if afont <> nil then begin + with twidget1(instance) do begin + if ffont = nil then begin + createfont; + ffont.assign(afont); + end; + end; + end; +end; + +procedure tcustomskincontroller.setwidgetcolor(const instance: twidget; + const acolor: colorty); +begin + if (acolor <> cl_default) and + not (osk_framebuttononly in instance.optionsskin) and + (instance.color = cl_default) then begin + instance.color:= acolor; + end; +end; + +function tcustomskincontroller.setwidgetcolorcaptionframe( + const awidget: twidget; const acolor: colorty): boolean; +begin + result:= false; + with twidget1(awidget) do begin + if (osk_colorcaptionframe in optionsskin) or + not (osk_nocolorcaptionframe in optionsskin) and + (fframe is tcustomcaptionframe) and + (tcustomcaptionframe(fframe).caption <> '') then begin + setwidgetcolor(awidget,acolor); + result:= true; + end + end; +end; + +procedure tcustomskincontroller.setstepbuttonskin( + const instance: tcustomstepframe; + const ainfo: stepbuttonskininfoty); +begin + with instance,ainfo do begin + if (colorbutton = cl_default) and + (svcolor <> cl_default) then begin + colorbutton:= svcolor; + end; + if svframe <> nil then begin + instance.createbuttonframe; + setframetemplate(svframe,buttonframe); + end; + if svface <> nil then begin + instance.createbuttonface; + setfacetemplate(svface,buttonface); + end; + end; +end; + +procedure tcustomskincontroller.setframebuttonskin(const instance: tframebutton; + const ainfo: framebuttonskininfoty); +begin + with instance,ainfo do begin + if (svcolor <> cl_default) and (color = cl_default) then begin + color:= svcolor; + end; + if (svcolorglyph <> cl_default) and (colorglyph = cl_default) then begin + colorglyph:= svcolorglyph; + end; + if (svface <> nil) {and (face = nil)} then begin + createface; + setfacetemplate(svface,face); +// face.template:= fa; + end; + if (svframe <> nil) {and (frame = nil)} then begin + createframe; + setframetemplate(svframe,frame); +// frame.template:= fra; + end; + end; +end; + +procedure tcustomskincontroller.setscrollbarskin( + const instance: tcustomscrollbar; + const ainfo: scrollbarskininfoty); +begin + with instance,ainfo do begin + if svwidth <> -2 then begin + width:= svwidth; + end; + if (svcolor <> cl_default) and (color = cl_default) then begin + color:= svcolor; + end; + if (svcolorpattern <> cl_default) and (colorpattern = cl_default) then begin + colorpattern:= svcolorpattern; + end; + if (svcolorpatternclicked <> cl_default) and + (colorpatternclicked = cl_default) then begin + colorpatternclicked:= svcolorpatternclicked; + end; + if svcolorglyph <> cl_default then begin + colorglyph:= svcolorglyph; + end; + if svbuttonendlength <> -2 then begin + buttonendlength:= svbuttonendlength; + end; + if svbuttonlength <> -2 then begin + buttonlength:= svbuttonlength; + end; + if svbuttonminlength <> -2 then begin + buttonminlength:= svbuttonminlength; + end; + if svindentstart <> 0 then begin + indentstart:= svindentstart; + end; + if svindentend <> 0 then begin + indentend:= svindentend; + end; + if (svface <> nil) then begin + createface(); + setfacetemplate(svface,face); + end; + if (svface1 <> nil) then begin + createface1(); + setfacetemplate(svface1,face1); + end; + if (svface2 <> nil) then begin + createface2(); + setfacetemplate(svface2,face2); + end; + if (svfacebu <> nil) {and (facebutton = nil)} then begin + createfacebutton; + setfacetemplate(svfacebu,facebutton); +// facebutton.template:= facebu; + end; + if (svfaceendbu <> nil) {and (faceendbutton = nil)} then begin + createfaceendbutton; + setfacetemplate(svfaceendbu,faceendbutton); +// faceendbutton.template:= faceendbu; + end; + if (svframe <> nil) {and (framebutton = nil)} then begin + createframe; + setframetemplate(svframe,frame); +// framebutton.template:= framebu; + end; + if (svframebu <> nil) {and (framebutton = nil)} then begin + createframebutton; + setframetemplate(svframebu,framebutton); +// framebutton.template:= framebu; + end; + if (svframeendbu1 <> nil) {and (frameendbutton1 = nil)} then begin + createframeendbutton1; + setframetemplate(svframeendbu1,frameendbutton1); +// frameendbutton1.template:= frameendbu1; + end; + if (svframeendbu2 <> nil) {and (frameendbutton2 = nil)} then begin + createframeendbutton2; + setframetemplate(svframeendbu2,frameendbutton2); +// frameendbutton2.template:= frameendbu2; + end; + end; +end; + +procedure tcustomskincontroller.settabsskin(const instance: tcustomtabbar; + const ainfo: tabsskininfoty); +var + int1: integer; +begin + with ttabs1(instance.tabs) do begin + inc(fskinupdating); + beginupdate; + try + if (ainfo.svshift <> defaulttabshift) and + (shift = defaulttabshift) then begin + shift:= ainfo.svshift; + end; + if (ainfo.svsedge_level <> defaultedgelevel) and + (edge_level = defaultedgelevel) then begin + edge_level:= ainfo.svsedge_level; + end; + if (ainfo.svsedge_colordkshadow <> cl_default) and + (edge_colordkshadow = cl_default) then begin + edge_colordkshadow:= ainfo.svsedge_colordkshadow; + end; + if (ainfo.svsedge_colorshadow <> cl_default) and + (edge_colorshadow = cl_default) then begin + edge_colorshadow:= ainfo.svsedge_colorshadow; + end; + if (ainfo.svsedge_colorlight <> cl_default) and + (edge_colorlight = cl_default) then begin + edge_colorlight:= ainfo.svsedge_colorlight; + end; + if (ainfo.svsedge_colorhighlight <> cl_default) and + (edge_colorhighlight = cl_default) then begin + edge_colorhighlight:= ainfo.svsedge_colorhighlight; + end; + if (ainfo.svsedge_colordkwidth <> -1) and + (edge_colordkwidth = -1) then begin + edge_colordkwidth:= ainfo.svsedge_colordkwidth; + end; + if (ainfo.svsedge_colorhlwidth <> -1) and + (edge_colorhlwidth = -1) then begin + edge_colorhlwidth:= ainfo.svsedge_colorhlwidth; + end; + if (ainfo.svsedge_imagelist <> nil) and + (edge_imagelist = nil) then begin + edge_imagelist:= ainfo.svsedge_imagelist; + end; + if (ainfo.svsedge_imageoffset <> 0) and + (edge_imageoffset = -1) then begin + edge_imageoffset:= ainfo.svsedge_imageoffset; + end; + if (ainfo.svsedge_imagepaintshift <> 0) and + (edge_imagepaintshift = 0) then begin + edge_imagepaintshift:= ainfo.svsedge_imagepaintshift; + end; + + if {(frame = nil) and} (ainfo.svframe <> nil) then begin + createframe; + setframetemplate(ainfo.svframe,frame); +// frame.template:= ainfo.frame; + end; + if {(face = nil) and} (ainfo.svface <> nil) then begin + createface; + setfacetemplate(ainfo.svface,face); +// face.template:= ainfo.face; + end; + if {(faceactive = nil) and} (ainfo.svfaceactive <> nil) then begin + createfaceactive; + setfacetemplate(ainfo.svfaceactive,faceactive); +// faceactive.template:= ainfo.faceactive; + end; + for int1:= 0 to count - 1 do begin + with items[int1] do begin + if (ainfo.svcolor <> cl_default) and (color = cl_default) then begin + color:= ainfo.svcolor; + end; + if (ainfo.svcoloractive <> cl_default) and + (coloractive = cl_default) then begin + coloractive:= ainfo.svcoloractive; + end; + end; + end; + finally + endupdate; + dec(fskinupdating); + end; + end; +end; + +procedure tcustomskincontroller.setpopupmenuskin(const instance: tpopupmenu; + const ainfo: menuskininfoty); +begin + with instance do begin + { + if smo_noanim in ainfo.options then begin + options:= options + [mo_noanim]; + end + else begin + options:= options - [mo_noanim]; + end; + } + if (ainfo.svface <> nil) and (facetemplate = nil) then begin + facetemplate:= ainfo.svface; + end; + if (ainfo.svframe <> nil) and (frametemplate = nil) then begin + frametemplate:= ainfo.svframe; + end; + if (ainfo.svitemface <> nil) and (itemfacetemplate = nil) then begin + itemfacetemplate:= ainfo.svitemface; + end; + if (ainfo.svitemframe <> nil) and (itemframetemplate = nil) then begin + itemframetemplate:= ainfo.svitemframe; + end; + if (ainfo.svitemfaceactive <> nil) and + (itemfacetemplateactive = nil) then begin + itemfacetemplateactive:= ainfo.svitemfaceactive; + end; + if (ainfo.svitemframeactive <> nil) and + (itemframetemplateactive = nil) then begin + itemframetemplateactive:= ainfo.svitemframeactive; + end; + if menu <> nil then begin + with tmenuitem1(menu) do begin; + if (ainfo.svfont <> nil) and + ((ffont = nil) or (ffont.template = nil)) then begin + createfont(); + ffont.template:= ainfo.svfont; + end; + if (ainfo.svfontactive <> nil) and + ((ffontactive = nil) or (ffontactive.template = nil)) then begin + createfontactive(); + ffontactive.template:= ainfo.svfontactive; + end; + end; + end; + if (ainfo.svseparatorframe <> nil) and + (separatorframetemplate = nil) then begin + separatorframetemplate:= ainfo.svseparatorframe; + end; + if (ainfo.svcheckboxframe <> nil) and + (checkboxframetemplate = nil) then begin + checkboxframetemplate:= ainfo.svcheckboxframe; + end; + end; + if fhashotkey then begin + instance.updatehotkeys(); + end; +end; + +procedure tcustomskincontroller.setmainmenuskin(const instance: tcustommainmenu; + const ainfo: mainmenuskininfoty); +var + i1,i2: int32; +begin +{$warnings off} + setpopupmenuskin(tpopupmenu(instance),ainfo.svmain); +{$warnings on} + with instance,ainfo do begin + if (svpopup.svface <> nil) and (popupfacetemplate = nil) then begin + popupfacetemplate:= svpopup.svface; + end; + if (svpopup.svframe <> nil) and (popupframetemplate = nil) then begin + popupframetemplate:= svpopup.svframe; + end; + if (svpopup.svitemface <> nil) and (popupitemfacetemplate = nil) then begin + popupitemfacetemplate:= svpopup.svitemface; + end; + if (svpopup.svitemframe <> nil) and (popupitemframetemplate = nil) then begin + popupitemframetemplate:= svpopup.svitemframe; + end; + if (svpopup.svitemfaceactive <> nil) and + (popupitemfacetemplateactive = nil) then begin + popupitemfacetemplateactive:= svpopup.svitemfaceactive; + end; + if (svpopup.svitemframeactive <> nil) and + (popupitemframetemplateactive = nil) then begin + popupitemframetemplateactive:= svpopup.svitemframeactive; + end; + if (svpopup.svseparatorframe <> nil) and + (popupseparatorframetemplate = nil) then begin + popupseparatorframetemplate:= svpopup.svseparatorframe; + end; + if (svpopup.svcheckboxframe <> nil) and + (popupcheckboxframetemplate = nil) then begin + popupcheckboxframetemplate:= svpopup.svcheckboxframe; + end; + if menu <> nil then begin + if svpopup.svfont <> nil then begin + for i1:= 0 to menu.count-1 do begin + with tmenuitem1(menu[i1]) do begin; + for i2:= 0 to submenu.count - 1 do begin + with tmenuitem1(submenu[i2]) do begin; + if ((ffont = nil) or (ffont.template = nil)) then begin + createfont(); + ffont.template:= svpopup.svfont; + end; + end; + end; + end; + end; + end; + if svpopup.svfontactive <> nil then begin + for i1:= 0 to menu.count-1 do begin + with tmenuitem1(menu[i1]) do begin; + for i2:= 0 to submenu.count - 1 do begin + with tmenuitem1(submenu[i2]) do begin; + if ((ffontactive = nil) or (ffontactive.template = nil)) then begin + createfontactive(); + ffontactive.template:= svpopup.svfontactive; + end; + end; + end; + end; + end; + end; + end; + end; + if fhashotkey then begin + instance.updatehotkeys(); + end; +end; + +procedure tcustomskincontroller.setcolors(const avalue: tskincolors); +begin + fcolors.assign(avalue); +end; + +procedure tcustomskincontroller.setfontalias(const avalue: tskinfontaliass); +begin + ffontalias.assign(avalue); +end; + +procedure tcustomskincontroller.handlegroupbox(const ainfo: skininfoty); +begin + //dummy +end; + +procedure tcustomskincontroller.handlesimplebutton(const ainfo: skininfoty); +begin + //dummy +end; + +procedure tcustomskincontroller.handledatabutton(const ainfo: skininfoty); +begin + //dummy +end; + +procedure tcustomskincontroller.handleslider(const ainfo: skininfoty); +begin + //dummy +end; + +procedure tcustomskincontroller.handleuserobject(const ainfo: skininfoty); +begin + //dummy +end; + +procedure tcustomskincontroller.handlecontainer(const ainfo: skininfoty); +begin + //dummy +end; + +procedure tcustomskincontroller.handletabbar(const ainfo: skininfoty); +begin + //dummy +end; + +procedure tcustomskincontroller.handletabpage(const ainfo: skininfoty); +begin + //dummy +end; + +procedure tcustomskincontroller.handleedit(const ainfo: skininfoty); +begin + //dummy +end; + +procedure tcustomskincontroller.handledispwidget(const ainfo: skininfoty); +begin + //dummy +end; + +procedure tcustomskincontroller.handledataedit(const ainfo: skininfoty); +begin + //dummy +end; + +procedure tcustomskincontroller.handlebooleanedit(const ainfo: skininfoty); +begin + //dummy +end; + +procedure tcustomskincontroller.handlemainmenu(const ainfo: skininfoty); +begin + //dummy +end; + +procedure tcustomskincontroller.handlepopupmenu(const ainfo: skininfoty); +begin + //dummy +end; + +procedure tcustomskincontroller.handlemainmenuwidget(const ainfo: skininfoty); +begin + //dummy +end; + +procedure tcustomskincontroller.handlegrid(const ainfo: skininfoty); +begin + //dummy +end; + +procedure tcustomskincontroller.handletoolbar(const ainfo: skininfoty); +begin + //dummy +end; + +procedure tcustomskincontroller.handlesplitter(const ainfo: skininfoty); +begin + //dummy +end; + +procedure tcustomskincontroller.updateorder; +begin + updateclientorder(fextendernames,pointerarty(fextenders), + {$ifdef FPC}@{$endif}getextendernames); +end; + +function tcustomskincontroller.getextendernames: stringarty; +var + int1: integer; +begin + setlength(result,length(fextenders)); + for int1:= 0 to high(result) do begin + result[int1]:= getclientname(fextenders[int1],int1); + end; +end; + +function tcustomskincontroller.getextenders: integer; +begin + result:= length(fextenders); +end; + +procedure tcustomskincontroller.setextenders(const avalue: integer); +begin + //dummy +end; + +procedure tcustomskincontroller.readextendernames(reader: treader); +begin + readstringar(reader,fextendernames); +end; + +procedure tcustomskincontroller.writeextendernames(writer: twriter); +begin + writestringar(writer,getextendernames); +end; + +procedure tcustomskincontroller.readactivedesign(reader: treader); +begin + reader.readboolean; //dummy +end; + +procedure tcustomskincontroller.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('extendernames',{$ifdef FPC}@{$endif}readextendernames, + {$ifdef FPC}@{$endif}writeextendernames,high(fextenders) >= 0); + filer.defineproperty('activedesign',{$ifdef FPC}@{$endif}readactivedesign,nil, + false); +end; + +procedure tcustomskincontroller.registerextender(const aextender: tskinextender); +begin + additem(pointerarty(fextenders),aextender); +end; + +procedure tcustomskincontroller.unregisterextender(const aextender: tskinextender); +begin + removeitem(pointerarty(fextenders),aextender); +end; + +procedure tcustomskincontroller.objectevent(const sender: tobject; + const event: objecteventty); +begin + if event = oe_destroyed then begin + removeitem(pointerarty(fextenders),sender); + end; + inherited; +end; + +function tcustomskincontroller.getskinfont(const aindex: integer): tskinfont; +begin + result:= fskinfonts[stockfontty(aindex)]; +end; + +procedure tcustomskincontroller.setskinfont(const aindex: integer; + const avalue: tskinfont); +begin + fskinfonts[stockfontty(aindex)].assign(avalue); +end; + +procedure tcustomskincontroller.setgroups(const avalue: string); +var + ar1: stringarty; + ar2: groupinfoarty; + int1,int2: integer; +begin + if avalue = '' then begin + fgroupinfo:= nil; + end + else begin + ar1:= splitstring(avalue,','); + setlength(ar2,length(ar1)); + for int1:= 0 to high(ar1) do begin +// int2:= msestrings.strscan(ar1[int1],'.'); + int2:= msestrings.findchar(ar1[int1],'.'); + if int2 > 0 then begin + ar2[int1].min:= strtoint(copy(ar1[int1],1,int2-1)); + if ar1[int1][int2+1] <> '.' then begin + raise exception.create('Invalid groups format'); + end; + ar2[int1].max:= strtoint(copy(ar1[int1],int2+2,bigint)); + end + else begin + ar2[int1].min:= strtoint(ar1[int1]); + ar2[int1].max:= ar2[int1].min; + end; + end; + fgroupinfo:= ar2; + end; + fgroups:= avalue; +end; + +{ tskincontroller } + +procedure inittabsskininfo(var info: tabsskininfoty); +begin + info.svcolor:= cl_default; + info.svcoloractive:= cl_default; + info.svshift:= defaulttabshift; + info.svsedge_level:= defaultedgelevel; + info.svsedge_colordkshadow:= cl_default; + info.svsedge_colorshadow:= cl_default; + info.svsedge_colorlight:= cl_default; + info.svsedge_colorhighlight:= cl_default; + info.svsedge_colordkwidth:= -1; + info.svsedge_colorhlwidth:= -1; +end; + +procedure initscrollbarskininfo(var ascrollbar: scrollbarskininfoty); +begin + with ascrollbar do begin + svwidth:= -2; + svcolor:= cl_default; + svcolorpattern:= cl_default; + svcolorpatternclicked:= cl_default; + svcolorglyph:= cl_default; + svbuttonendlength:= -2; + svbuttonlength:= -2; + svbuttonminlength:= -2; +// svindentstart:= -2; //default 0 +// svindentend:= -2; + end; +end; + +constructor tskincontroller.create(aowner: tcomponent); +begin + fwidgetcolor.svcolor:= cl_default; + fwidgetcolor.svcolorcaptionframe:= cl_default; + fstepbutton.svcolor:= cl_default; + + initscrollbarskininfo(fsb_horz); + initscrollbarskininfo(fsb_vert); + + fsplitter.svcolor.svcolor:= cl_default; + fsplitter.svcolor.svcolorcaptionframe:= cl_default; + fsplitter.svcolorgrip:= cl_default; + fsplitter.svgrip:= stb_default; + + fdispwidget.svcolor.svcolor:= cl_default; + fdispwidget.svcolor.svcolorcaptionframe:= cl_default; + + fedit.svempty_color:= cl_default; + fedit.svempty_textcolor:= cl_default; + fedit.svempty_textcolorbackground:= cl_default; + + fdataedit.svedit.svempty_color:= cl_default; + fdataedit.svedit.svempty_textcolor:= cl_default; + fdataedit.svedit.svempty_textcolorbackground:= cl_default; + + fbutton.svcolor:= cl_default; + fdatabutton.svcolor:= cl_default; + fslider.svcolor:= cl_default; + initscrollbarskininfo(fslider.svsb_horz); + initscrollbarskininfo(fslider.svsb_vert); + fframebutton.svcolor:= cl_default; + fframebutton.svcolorglyph:= cl_default; + inittabsskininfo(ftabbar.svtabhorz); + inittabsskininfo(ftabbar.svtabvert); + inittabsskininfo(ftabbar.svtabhorzopo); + inittabsskininfo(ftabbar.svtabvertopo); +{ + ftabbar.svtabhorz.svcolor:= cl_default; + ftabbar.svtabhorz.svcoloractive:= cl_default; + ftabbar.svtabhorz.svshift:= defaulttabshift; + ftabbar.svtabvert.svcolor:= cl_default; + ftabbar.svtabvert.svcoloractive:= cl_default; + ftabbar.svtabvert.svshift:= defaulttabshift; + ftabbar.svtabhorzopo.svcolor:= cl_default; + ftabbar.svtabhorzopo.svcoloractive:= cl_default; + ftabbar.svtabhorzopo.svshift:= defaulttabshift; + ftabbar.svtabvertopo.svcolor:= cl_default; + ftabbar.svtabvertopo.svcoloractive:= cl_default; + ftabbar.svtabvertopo.svshift:= defaulttabshift; +} + ftabpage.svcolortab:= cl_default; + ftabpage.svcoloractivetab:= cl_default; + inherited; +end; + +destructor tskincontroller.destroy; +begin + inherited; + fbutton.svfont.free; +end; + +procedure tskincontroller.setsplitter_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fsplitter.svwidget.svface)); +end; + +procedure tskincontroller.setsplitter_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fsplitter.svwidget.svframe)); +end; + +procedure tskincontroller.setdispwidget_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fdispwidget.svwidget.svface)); +end; + +procedure tskincontroller.setdispwidget_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fdispwidget.svwidget.svframe)); +end; + +procedure tskincontroller.setedit_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fedit.svwidget.svface)); +end; + +procedure tskincontroller.setedit_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fedit.svwidget.svframe)); +end; + +procedure tskincontroller.setdataedit_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fdataedit.svedit.svwidget.svface)); +end; + +procedure tskincontroller.setdataedit_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fdataedit.svedit.svwidget.svframe)); +end; + +procedure tskincontroller.setbooleanedit_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent( + fbooleanedit.svgraphdataedit.svwidget.svface)); +end; + +procedure tskincontroller.setbooleanedit_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent( + fbooleanedit.svgraphdataedit.svwidget.svframe)); +end; + +procedure tskincontroller.setcontainer_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fcontainer.svwidget.svface)); +end; + +procedure tskincontroller.setcontainer_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fcontainer.svwidget.svframe)); +end; + +procedure tskincontroller.settabbar_horz_tab_edge_imagelist( + const avalue: timagelist); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svtabhorz.svsedge_imagelist)); +end; + +procedure tskincontroller.settabbar_vert_tab_edge_imagelist( + const avalue: timagelist); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svtabvert.svsedge_imagelist)); +end; + +procedure tskincontroller.settabbar_horzopo_tab_edge_imagelist( + const avalue: timagelist); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svtabhorzopo.svsedge_imagelist)); +end; + +procedure tskincontroller.settabbar_vertopo_tab_edge_imagelist( + const avalue: timagelist); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svtabvertopo.svsedge_imagelist)); +end; + +procedure tskincontroller.setsb_vert_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fsb_vert.svface)); +end; + +procedure tskincontroller.setsb_vert_face1(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fsb_vert.svface1)); +end; + +procedure tskincontroller.setsb_vert_face2(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fsb_vert.svface2)); +end; + +procedure tskincontroller.setsb_vert_facebutton(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fsb_vert.svfacebu)); +end; + +procedure tskincontroller.setsb_vert_faceendbutton(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fsb_vert.svfaceendbu)); +end; + +procedure tskincontroller.setsb_vert_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fsb_vert.svframe)); +end; + +procedure tskincontroller.setsb_vert_framebutton(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fsb_vert.svframebu)); +end; + +procedure tskincontroller.setsb_vert_frameendbutton1(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fsb_vert.svframeendbu1)); +end; + +procedure tskincontroller.setsb_vert_frameendbutton2(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fsb_vert.svframeendbu2)); +end; + +procedure tskincontroller.setsb_horz_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fsb_horz.svface)); +end; + +procedure tskincontroller.setsb_horz_face1(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fsb_horz.svface1)); +end; + +procedure tskincontroller.setsb_horz_face2(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fsb_horz.svface2)); +end; + +procedure tskincontroller.setsb_horz_facebutton(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fsb_horz.svfacebu)); +end; + +procedure tskincontroller.setsb_horz_faceendbutton(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fsb_horz.svfaceendbu)); +end; + +procedure tskincontroller.setsb_horz_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fsb_horz.svframe)); +end; + +procedure tskincontroller.setsb_horz_framebutton(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fsb_horz.svframebu)); +end; + +procedure tskincontroller.setsb_horz_frameendbutton1(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fsb_horz.svframeendbu1)); +end; + +procedure tskincontroller.setsb_horz_frameendbutton2(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fsb_horz.svframeendbu2)); +end; + +procedure tskincontroller.setgroupbox_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fgroupbox.svwidget.svface)); +end; + +procedure tskincontroller.setgroupbox_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fgroupbox.svwidget.svframe)); +end; + +procedure tskincontroller.setgrid_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fgrid.svwidget.svface)); +end; + +procedure tskincontroller.setgrid_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fgrid.svwidget.svframe)); +end; + +procedure tskincontroller.setgrid_fixrows_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fgrid.svfixrows.svface)); +end; + +procedure tskincontroller.setgrid_fixrows_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fgrid.svfixrows.svframe)); +end; + +procedure tskincontroller.setgrid_fixcols_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fgrid.svfixcols.svface)); +end; + +procedure tskincontroller.setgrid_fixcols_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fgrid.svfixcols.svframe)); +end; + +procedure tskincontroller.setgrid_datacols_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fgrid.svdatacols.svface)); +end; + +procedure tskincontroller.setgrid_datacols_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fgrid.svdatacols.svframe)); +end; + +procedure tskincontroller.setbutton_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fbutton.svwidget.svface)); +end; + +procedure tskincontroller.setbutton_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fbutton.svwidget.svframe)); +end; + +procedure tskincontroller.setdatabutton_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fdatabutton.svwidget.svface)); +end; + +procedure tskincontroller.setdatabutton_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fdatabutton.svwidget.svframe)); +end; + +procedure tskincontroller.setslider_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fslider.svwidget.svface)); +end; + +procedure tskincontroller.setslider_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fslider.svwidget.svframe)); +end; + +procedure tskincontroller.setssb_vert_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fslider.svsb_vert.svface)); +end; + +procedure tskincontroller.setssb_vert_face1(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fslider.svsb_vert.svface1)); +end; + +procedure tskincontroller.setssb_vert_face2(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fslider.svsb_vert.svface2)); +end; + +procedure tskincontroller.setssb_vert_facebutton(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fslider.svsb_vert.svfacebu)); +end; + +procedure tskincontroller.setssb_vert_faceendbutton(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fslider.svsb_vert.svfaceendbu)); +end; + +procedure tskincontroller.setssb_vert_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fslider.svsb_vert.svframe)); +end; + +procedure tskincontroller.setssb_vert_framebutton(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fslider.svsb_vert.svframebu)); +end; + +procedure tskincontroller.setssb_vert_frameendbutton1(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fslider.svsb_vert.svframeendbu1)); +end; + +procedure tskincontroller.setssb_vert_frameendbutton2(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fslider.svsb_vert.svframeendbu2)); +end; + +procedure tskincontroller.setssb_horz_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fslider.svsb_horz.svface)); +end; + +procedure tskincontroller.setssb_horz_face1(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fslider.svsb_horz.svface1)); +end; + +procedure tskincontroller.setssb_horz_face2(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fslider.svsb_horz.svface2)); +end; + +procedure tskincontroller.setssb_horz_facebutton(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fslider.svsb_horz.svfacebu)); +end; + +procedure tskincontroller.setssb_horz_faceendbutton(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fslider.svsb_horz.svfaceendbu)); +end; + +procedure tskincontroller.setssb_horz_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fslider.svsb_horz.svframe)); +end; + +procedure tskincontroller.setssb_horz_framebutton(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fslider.svsb_horz.svframebu)); +end; + +procedure tskincontroller.setssb_horz_frameendbutton1(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fslider.svsb_horz.svframeendbu1)); +end; + +procedure tskincontroller.setssb_horz_frameendbutton2(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fslider.svsb_horz.svframeendbu2)); +end; + +procedure tskincontroller.setframebutton_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fframebutton.svface)); +end; + +procedure tskincontroller.setframebutton_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fframebutton.svframe)); +end; + +procedure tskincontroller.setstepbutton_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fstepbutton.svface)); +end; + +procedure tskincontroller.setstepbutton_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fstepbutton.svframe)); +end; + +procedure tskincontroller.settabbar_horz_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svwidgethorz.svface)); +end; + +procedure tskincontroller.settabbar_horz_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svwidgethorz.svframe)); +end; + +procedure tskincontroller.settabbar_horz_tab_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svtabhorz.svface)); +end; + +procedure tskincontroller.settabbar_horz_tab_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svtabhorz.svframe)); +end; + +procedure tskincontroller.settabbar_horz_tab_faceactive(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svtabhorz.svfaceactive)); +end; + +procedure tskincontroller.settabbar_vert_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svwidgetvert.svface)); +end; + +procedure tskincontroller.settabbar_vert_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svwidgetvert.svframe)); +end; + +procedure tskincontroller.settabbar_vert_tab_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svtabvert.svface)); +end; + +procedure tskincontroller.settabbar_vert_tab_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svtabvert.svframe)); +end; + +procedure tskincontroller.settabbar_vert_tab_faceactive(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svtabvert.svfaceactive)); +end; + +procedure tskincontroller.settabbar_horzopo_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svwidgethorzopo.svface)); +end; + +procedure tskincontroller.settabbar_horzopo_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svwidgethorzopo.svframe)); +end; + +procedure tskincontroller.settabbar_horzopo_tab_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svtabhorzopo.svface)); +end; + +procedure tskincontroller.settabbar_horzopo_tab_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svtabhorzopo.svframe)); +end; + +procedure tskincontroller.settabbar_horzopo_tab_faceactive(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svtabhorzopo.svfaceactive)); +end; + +procedure tskincontroller.settabbar_vertopo_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svwidgetvertopo.svface)); +end; + +procedure tskincontroller.settabbar_vertopo_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svwidgetvertopo.svframe)); +end; + +procedure tskincontroller.settabbar_vertopo_tab_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svtabvertopo.svface)); +end; + +procedure tskincontroller.settabbar_vertopo_tab_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svtabvertopo.svframe)); +end; + +procedure tskincontroller.settabbar_vertopo_tab_faceactive(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabbar.svtabvertopo.svfaceactive)); +end; + +procedure tskincontroller.settabpage_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabpage.svwidget.svface)); +end; + +procedure tskincontroller.settabpage_facetab(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabpage.svfacetab)); +end; + +procedure tskincontroller.settabpage_faceactivetab(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabpage.svfaceactivetab)); +end; + +procedure tskincontroller.settabpage_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabpage.svwidget.svframe)); +end; + +procedure tskincontroller.settabpage_fonttab(const avalue: tfontcomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabpage.svfonttab)); +end; + +procedure tskincontroller.settabpage_fontactivetab(const avalue: tfontcomp); +begin + setlinkedvar(avalue,tmsecomponent(ftabpage.svfontactivetab)); +end; + +procedure tskincontroller.settoolbar_horz_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftoolbar_horz.svwidget.svface)); +end; + +procedure tskincontroller.settoolbar_horz_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftoolbar_horz.svwidget.svframe)); +end; + +procedure tskincontroller.settoolbar_horz_buttonface(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftoolbar_horz.svbuttonface)); +end; + +procedure tskincontroller.settoolbar_horz_buttonfacechecked( + const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftoolbar_horz.svbuttonfacechecked)); +end; + +procedure tskincontroller.settoolbar_horz_buttonframe(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftoolbar_horz.svbuttonframe)); +end; + +procedure tskincontroller.settoolbar_horz_buttonframechecked( + const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftoolbar_horz.svbuttonframechecked)); +end; + +procedure tskincontroller.settoolbar_horz_buttonframesep( + const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftoolbar_horz.svbuttonframesep)); +end; + +procedure tskincontroller.settoolbar_vert_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftoolbar_vert.svwidget.svface)); +end; + +procedure tskincontroller.settoolbar_vert_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftoolbar_vert.svwidget.svframe)); +end; + +procedure tskincontroller.settoolbar_vert_buttonface(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftoolbar_vert.svbuttonface)); +end; + +procedure tskincontroller.settoolbar_vert_buttonfacechecked( + const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftoolbar_vert.svbuttonfacechecked)); +end; + +procedure tskincontroller.settoolbar_vert_buttonframe(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftoolbar_vert.svbuttonframe)); +end; + +procedure tskincontroller.settoolbar_vert_buttonframechecked( + const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftoolbar_vert.svbuttonframechecked)); +end; + +procedure tskincontroller.settoolbar_vert_buttonframesep( + const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftoolbar_vert.svbuttonframesep)); +end; + +procedure tskincontroller.setpopupmenu_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fpopupmenu.svface)); +end; + +procedure tskincontroller.setpopupmenu_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fpopupmenu.svframe)); +end; + +procedure tskincontroller.setpopupmenu_itemface(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fpopupmenu.svitemface)); +end; + +procedure tskincontroller.setpopupmenu_itemframe(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fpopupmenu.svitemframe)); +end; + +procedure tskincontroller.setpopupmenu_itemfaceactive(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fpopupmenu.svitemfaceactive)); +end; + +procedure tskincontroller.setpopupmenu_itemframeactive( + const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fpopupmenu.svitemframeactive)); +end; + +procedure tskincontroller.setpopupmenu_font(const avalue: tfontcomp); +begin + setlinkedvar(avalue,tmsecomponent(fpopupmenu.svfont)); +end; + +procedure tskincontroller.setpopupmenu_fontactive(const avalue: tfontcomp); +begin + setlinkedvar(avalue,tmsecomponent(fpopupmenu.svfontactive)); +end; + +procedure tskincontroller.setpopupmenu_separatorframe(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fpopupmenu.svseparatorframe)); +end; + +procedure tskincontroller.setpopupmenu_checkboxframe(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fpopupmenu.svcheckboxframe)); +end; + +procedure tskincontroller.setmainmenu_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenu.svmain.svface)); +end; + +procedure tskincontroller.setmainmenu_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenu.svmain.svframe)); +end; + +procedure tskincontroller.setmainmenu_itemface(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenu.svmain.svitemface)); +end; + +procedure tskincontroller.setmainmenu_itemframe(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenu.svmain.svitemframe)); +end; + +procedure tskincontroller.setmainmenu_itemfaceactive(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenu.svmain.svitemfaceactive)); +end; + +procedure tskincontroller.setmainmenu_itemframeactive(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenu.svmain.svitemframeactive)); +end; + +procedure tskincontroller.setmainmenu_font(const avalue: tfontcomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenu.svmain.svfont)); +end; + +procedure tskincontroller.setmainmenu_fontactive(const avalue: tfontcomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenu.svmain.svfontactive)); +end; + +procedure tskincontroller.setmainmenu_separatorframe(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenu.svmain.svseparatorframe)); +end; + +procedure tskincontroller.setmainmenu_checkboxframe(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenu.svmain.svcheckboxframe)); +end; + +procedure tskincontroller.setmainmenu_popupface(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenu.svpopup.svface)); +end; + +procedure tskincontroller.setmainmenu_popupframe(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenu.svpopup.svframe)); +end; + +procedure tskincontroller.setmainmenu_popupitemface(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenu.svpopup.svitemface)); +end; + +procedure tskincontroller.setmainmenu_popupitemframe(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenu.svpopup.svitemframe)); +end; + +procedure tskincontroller.setmainmenu_popupitemfaceactive(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenu.svpopup.svitemfaceactive)); +end; + +procedure tskincontroller.setmainmenu_popupitemframeactive(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenu.svpopup.svitemframeactive)); +end; + +procedure tskincontroller.setmainmenu_popupfont(const avalue: tfontcomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenu.svpopup.svfont)); +end; + +procedure tskincontroller.setmainmenu_popupfontactive(const avalue: tfontcomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenu.svpopup.svfontactive)); +end; + +procedure tskincontroller.setmainmenu_popupseparatorframe(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenu.svpopup.svseparatorframe)); +end; + +procedure tskincontroller.setmainmenu_popupcheckboxframe(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenu.svpopup.svcheckboxframe)); +end; + +procedure tskincontroller.setmainmenuwidget_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenuwidget.svwidget.svface)); +end; + +procedure tskincontroller.setmainmenuwidget_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenuwidget.svwidget.svframe)); +end; + +procedure tskincontroller.setmainmenuwidget_itemface(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenuwidget.svmenu.svmain.svitemface)); +end; + +procedure tskincontroller.setmainmenuwidget_itemframe(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenuwidget.svmenu.svmain.svitemframe)); +end; + +procedure tskincontroller.setmainmenuwidget_itemfaceactive(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenuwidget.svmenu.svmain.svitemfaceactive)); +end; + +procedure tskincontroller.setmainmenuwidget_itemframeactive(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenuwidget.svmenu.svmain.svitemframeactive)); +end; + +procedure tskincontroller.setmainmenuwidget_font(const avalue: tfontcomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenuwidget.svmenu.svmain.svfont)); +end; + +procedure tskincontroller.setmainmenuwidget_fontactive(const avalue: tfontcomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenuwidget.svmenu.svmain.svfontactive)); +end; + +procedure tskincontroller.setmainmenuwidget_separatorframe(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenuwidget.svmenu.svmain.svseparatorframe)); +end; + +procedure tskincontroller.setmainmenuwidget_checkboxframe(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenuwidget.svmenu.svmain.svcheckboxframe)); +end; + +procedure tskincontroller.setmainmenuwidget_popupface(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenuwidget.svmenu.svpopup.svface)); +end; + +procedure tskincontroller.setmainmenuwidget_popupframe(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenuwidget.svmenu.svpopup.svframe)); +end; + +procedure tskincontroller.setmainmenuwidget_popupitemface(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenuwidget.svmenu.svpopup.svitemface)); +end; + +procedure tskincontroller.setmainmenuwidget_popupitemframe(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenuwidget.svmenu.svpopup.svitemframe)); +end; + +procedure tskincontroller.setmainmenuwidget_popupitemfaceactive(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenuwidget.svmenu.svpopup.svitemfaceactive)); +end; + +procedure tskincontroller.setmainmenuwidget_popupitemframeactive(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenuwidget.svmenu.svpopup.svitemframeactive)); +end; + +procedure tskincontroller.setmainmenuwidget_popupfont(const avalue: tfontcomp); +begin + setlinkedvar(avalue,tmsecomponent(fmainmenuwidget.svmenu.svpopup.svfont)); +end; + +procedure tskincontroller.setmainmenuwidget_popupfontactive( + const avalue: tfontcomp); +begin + setlinkedvar(avalue,tmsecomponent( + fmainmenuwidget.svmenu.svpopup.svfontactive)); +end; + +procedure tskincontroller.setmainmenuwidget_popupseparatorframe( + const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent( + fmainmenuwidget.svmenu.svpopup.svseparatorframe)); +end; + +procedure tskincontroller.setmainmenuwidget_popupcheckboxframe( + const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent( + fmainmenuwidget.svmenu.svpopup.svcheckboxframe)); +end; + +procedure tskincontroller.handlewidget(const askin: skininfoty; + const acolor: pwidgetcolorinfoty); +var + int1: integer; + wi1: twidget1; + co1,co2: colorty; +begin + if acolor = nil then begin + co1:= fwidgetcolor.svcolor; + co2:= fwidgetcolor.svcolorcaptionframe + end + else begin + co1:= acolor^.svcolor; + if co1 = cl_default then begin + co1:= fwidgetcolor.svcolor; + end; + co2:= acolor^.svcolorcaptionframe; + if co2 = cl_default then begin + co2:= fwidgetcolor.svcolorcaptionframe; + end; + end; + wi1:= twidget1(askin.instance); + with wi1 do begin + if fframe <> nil then begin + if fframe is tcustomscrollframe then begin + setscrollbarskin(tcustomscrollframe(fframe).sbvert,fsb_vert); + setscrollbarskin(tcustomscrollframe(fframe).sbhorz,fsb_horz); + end + else begin + if fframe is tcustombuttonframe then begin + with tcustombuttonframe(fframe) do begin + for int1:= 0 to buttons.count - 1 do begin + setframebuttonskin(buttons[int1],fframebutton); + end; + end; + end + else begin + if fframe is tcustomstepframe then begin + setstepbuttonskin(tcustomstepframe(fframe),fstepbutton); + end; + end; + end; + end; + if not setwidgetcolorcaptionframe(wi1,co2) then begin + setwidgetcolor(wi1,co1); + end; + if fhashotkey then begin + updatehotkeys(); + end; + end; +end; + +procedure tskincontroller.handlegroupbox(const ainfo: skininfoty); +begin + handlewidget(ainfo); + setgroupboxskin(tgroupbox(ainfo.instance),fgroupbox); +end; + +procedure tskincontroller.handlesimplebutton(const ainfo: skininfoty); +begin + handlewidget(ainfo); + setwidgetcolor(twidget(ainfo.instance),fbutton.svcolor); + setwidgetskin(twidget(ainfo.instance),fbutton.svwidget); + setwidgetfont(twidget(ainfo.instance),fbutton.svfont); + with tsimplebutton(ainfo.instance) do begin + if not (osk_nooptions in optionsskin) then begin + if fbutton.svoptionsadd <> [] then begin + options:= options + fbutton.svoptionsadd; + end; + if fbutton.svoptionsremove <> [] then begin + options:= options - fbutton.svoptionsremove; + end; + end; + end; +end; + +procedure tskincontroller.handledatabutton(const ainfo: skininfoty); +begin + handlewidget(ainfo); + setwidgetcolor(twidget(ainfo.instance),fdatabutton.svcolor); + setwidgetskin(twidget(ainfo.instance),fdatabutton.svwidget); + setwidgetfont(twidget(ainfo.instance),fdatabutton.svfont); + with tcustomdatabutton(ainfo.instance) do begin + if not (osk_nooptions in optionsskin) then begin + if fdatabutton.svoptionsadd <> [] then begin + options:= options + fdatabutton.svoptionsadd; + end; + if fdatabutton.svoptionsremove <> [] then begin + options:= options - fdatabutton.svoptionsremove; + end; + end; + end; +end; + +procedure tskincontroller.handleslider(const ainfo: skininfoty); +begin + handlewidget(ainfo); + setwidgetcolor(twidget(ainfo.instance),fslider.svcolor); + setwidgetskin(twidget(ainfo.instance),fslider.svwidget); + with tcustomslider(ainfo.instance) do begin + if direction in [gd_left,gd_right] then begin + setscrollbarskin(scrollbar,fslider.svsb_horz); + end + else begin + setscrollbarskin(scrollbar,fslider.svsb_vert); + end; + end; +end; + +procedure tskincontroller.handlecontainer(const ainfo: skininfoty); +begin + setwidgetskin(twidget(ainfo.instance),fcontainer.svwidget); +end; + +procedure tskincontroller.createbutton_font; +begin + if fbutton.svfont = nil then begin + fbutton.svfont:= toptionalfont.create; + end; +end; + +procedure tskincontroller.setbutton_font(const avalue: toptionalfont); +begin + setoptionalobject(avalue,fbutton.svfont,{$ifdef FPC}@{$endif}createbutton_font); +end; + +function tskincontroller.getbutton_font: toptionalfont; +begin + getoptionalobject(fbutton.svfont,{$ifdef FPC}@{$endif}createbutton_font); + result:= fbutton.svfont; +end; + +procedure tskincontroller.createdatabutton_font; +begin + if fdatabutton.svfont = nil then begin + fdatabutton.svfont:= toptionalfont.create; + end; +end; + +procedure tskincontroller.setdatabutton_font(const avalue: toptionalfont); +begin + setoptionalobject(avalue,fdatabutton.svfont, + {$ifdef FPC}@{$endif}createbutton_font); +end; + +function tskincontroller.getdatabutton_font: toptionalfont; +begin + getoptionalobject(fdatabutton.svfont,{$ifdef FPC}@{$endif}createbutton_font); + result:= fdatabutton.svfont; +end; + +procedure tskincontroller.handletabbar(const ainfo: skininfoty); +var + ta1: tcustomtabbar; +begin + handlewidget(ainfo); + ta1:= tcustomtabbar(ainfo.instance); + if tabo_vertical in ta1.options then begin + if tabo_opposite in ta1.options then begin + setwidgetskin(ta1,ftabbar.svwidgetvertopo); + settabsskin(ta1,ftabbar.svtabvertopo); + end + else begin + setwidgetskin(ta1,ftabbar.svwidgetvert); + settabsskin(ta1,ftabbar.svtabvert); + end; + end + else begin + if tabo_opposite in ta1.options then begin + setwidgetskin(ta1,ftabbar.svwidgethorzopo); + settabsskin(ta1,ftabbar.svtabhorzopo); + end + else begin + setwidgetskin(ta1,ftabbar.svwidgethorz); + settabsskin(ta1,ftabbar.svtabhorz); + end; + end; + setstepbuttonskin(ta1.frame,fstepbutton); +end; + +procedure tskincontroller.handletabpage(const ainfo: skininfoty); +var + intf1: itabpage; + font1: tfont; +begin + handlewidget(ainfo); + setwidgetskin(twidget(ainfo.instance),ftabpage.svwidget); + if {((ftabpage.svcolortab <> cl_default) or + (ftabpage.svcoloractivetab <> cl_default)) and} + twidget(ainfo.instance).getcorbainterface(typeinfo(itabpage), + intf1) then begin + if (ftabpage.svcolortab <> cl_default) and + (intf1.getcolortab = cl_default) then begin + intf1.setcolortab(ftabpage.svcolortab); + end; + if (ftabpage.svcoloractivetab <> cl_default) and + (intf1.getcoloractivetab = cl_default) then begin + intf1.setcoloractivetab(ftabpage.svcoloractivetab); + end; + if (ftabpage.svfacetab <> nil) and (intf1.getfacetab() = nil) then begin + intf1.setfacetab(ftabpage.svfacetab); + end; + if (ftabpage.svfaceactivetab <> nil) and + (intf1.getfaceactivetab() = nil) then begin + intf1.setfaceactivetab(ftabpage.svfaceactivetab); + end; + if (ftabpage.svfonttab <> nil) then begin + font1:= intf1.getfonttab(); + if font1 = nil then begin + intf1.setfonttab(tfont(pointer(1))); //create font + font1:= intf1.getfonttab(); + end; + if font1.template = nil then begin + font1.template:= ftabpage.svfonttab; + end; + end; + if (ftabpage.svfontactivetab <> nil) then begin + font1:= intf1.getfontactivetab(); + if font1 = nil then begin + intf1.setfontactivetab(tfont(pointer(1))); //create font + font1:= intf1.getfontactivetab(); + end; + if font1.template = nil then begin + font1.template:= ftabpage.svfontactivetab; + end; + end; + end; +end; + +procedure tskincontroller.handletoolbar(const ainfo: skininfoty); +var + tb1: tcustomtoolbar; +begin + handlewidget(ainfo); + tb1:= tcustomtoolbar(ainfo.instance); + if ftoolbar_horz.svbuttonframesep <> nil then begin + with tb1.buttons do begin + createframesephorz(); + setframetemplate(ftoolbar_horz.svbuttonframesep,framesephorz); + end; + end; + if ftoolbar_vert.svbuttonframesep <> nil then begin + with tb1.buttons do begin + createframesepvert(); + setframetemplate(ftoolbar_vert.svbuttonframesep,framesepvert); + end; + end; + if tb1.width >= tb1.height then begin + setwidgetskin(tb1,ftoolbar_horz.svwidget); + setstepbuttonskin(tb1.frame,fstepbutton); + if ftoolbar_horz.svbuttonface <> nil then begin + with tb1.buttons do begin + createface(); + setfacetemplate(ftoolbar_horz.svbuttonface,face); + end; + end; + if ftoolbar_horz.svbuttonfacechecked <> nil then begin + with tb1.buttons do begin + createfacechecked(); + setfacetemplate(ftoolbar_horz.svbuttonfacechecked,facechecked); + end; + end; + if ftoolbar_horz.svbuttonframe <> nil then begin + with tb1.buttons do begin + createframe(); + setframetemplate(ftoolbar_horz.svbuttonframe,frame); + end; + end; + if ftoolbar_horz.svbuttonframechecked <> nil then begin + with tb1.buttons do begin + createframechecked(); + setframetemplate(ftoolbar_horz.svbuttonframechecked,framechecked); + end; + end; + end + else begin + setwidgetskin(tb1,ftoolbar_vert.svwidget); + setstepbuttonskin(tb1.frame,fstepbutton); + if ftoolbar_vert.svbuttonface <> nil then begin + with tb1.buttons do begin + createface(); + setfacetemplate(ftoolbar_vert.svbuttonface,face); + end; + end; + if ftoolbar_vert.svbuttonfacechecked <> nil then begin + with tb1.buttons do begin + createfacechecked(); + setfacetemplate(ftoolbar_vert.svbuttonfacechecked,facechecked); + end; + end; + if ftoolbar_vert.svbuttonframe <> nil then begin + with tb1.buttons do begin + createframe(); + setframetemplate(ftoolbar_vert.svbuttonframe,frame); + end; + end; + if ftoolbar_vert.svbuttonframechecked <> nil then begin + with tb1.buttons do begin + createframechecked(); + setframetemplate(ftoolbar_vert.svbuttonframechecked,framechecked); + end; + end; + end; +end; + +procedure tskincontroller.handlesplitter(const ainfo: skininfoty); +begin + handlewidget(ainfo,@fsplitter.svcolor); + setwidgetskin(twidget(ainfo.instance),fsplitter.svwidget); + with fsplitter,tcustomsplitter(ainfo.instance) do begin + if (svcolorgrip <> cl_default) and (colorgrip = cl_default) then begin + colorgrip:= svcolorgrip; + end; + if (svgrip <> stb_default) and (grip = stb_default) then begin + grip:= svgrip; + end; + end; +end; + +procedure tskincontroller.handledispwidget(const ainfo: skininfoty); +begin + handlewidget(ainfo,@fdispwidget.svcolor); + setwidgetskin(twidget(ainfo.instance),fdispwidget.svwidget); +end; + +procedure tskincontroller.handleedit(const ainfo: skininfoty); +begin + handlewidget(ainfo); + seteditskin(tcustomedit(ainfo.instance),fedit); +end; + +procedure tskincontroller.handledataedit(const ainfo: skininfoty); +begin + handlewidget(ainfo); + setdataeditskin(tdataedit(ainfo.instance),fdataedit); +end; + +procedure tskincontroller.handlebooleanedit(const ainfo: skininfoty); +begin + handlewidget(ainfo); + setwidgetskin(twidget(ainfo.instance),fbooleanedit.svgraphdataedit.svwidget); + with tcustombooleanedit(ainfo.instance) do begin + if not (osk_nooptions in optionsskin) then begin + if fbooleanedit.svoptionsadd <> [] then begin + options:= options + fbooleanedit.svoptionsadd; + end; + if fbooleanedit.svoptionsremove <> [] then begin + options:= options - fbooleanedit.svoptionsremove; + end; + end; + end; +// setgraphdataeditskin(tgraphdataedit(ainfo.instance),fbooleanedit); +end; + +procedure tskincontroller.handlemainmenu(const ainfo: skininfoty); +begin + setmainmenuskin(tcustommainmenu(ainfo.instance),fmainmenu); +end; + +procedure tskincontroller.handlepopupmenu(const ainfo: skininfoty); +begin + setpopupmenuskin(tpopupmenu(ainfo.instance),fpopupmenu); +end; + +procedure tskincontroller.handlemainmenuwidget(const ainfo: skininfoty); +begin + handlewidget(ainfo); + setwidgetskin(twidget(ainfo.instance),fmainmenuwidget.svwidget); + setmainmenuskin(tmainmenuwidget(ainfo.instance).menu,fmainmenuwidget.svmenu); +end; + +procedure tskincontroller.handlegrid(const ainfo: skininfoty); +begin + handlewidget(ainfo); + setgridskin(tcustomgrid(ainfo.instance),fgrid); +end; + +{ tskinfontalias } + +constructor tskinfontalias.create(aowner: tobject); +begin + fmode:= fam_overwrite; + fxscale:= 1; + inherited; +end; + +procedure tskinfontalias.settemplate(const avalue: tfontcomp); +begin + tcustomskincontroller(fowner).setlinkedvar(avalue,tmsecomponent(ftemplate)); +end; + +{ tskinextender } + +destructor tskinextender.destroy; +begin + master:= nil; //unlink + inherited; +end; + +procedure tskinextender.setmaster(const avalue: tcustomskincontroller); +begin + if fmaster <> nil then begin + fmaster.unregisterextender(self); + end; + setlinkedvar(avalue,tmsecomponent(fmaster)); + if avalue <> nil then begin + avalue.registerextender(self); + end; +end; + +procedure tskinextender.doactivate; +begin + //dummy +end; + +procedure tskinextender.dodeactivate; +begin + //dummy +end; + +procedure tskinextender.updateskin(const ainfo: skininfoty; + var handled: boolean); +begin + //dummy +end; + +procedure tskinextender.removeskin(const ainfo: skininfoty; + var handled: boolean); +begin + //dummy +end; + +{ tskinfont } +(* +constructor tskinfont.create; +begin +{ + fcolor:= cl_default; + fcolorbackground:= cl_default; + fshadow_color:= cl_default; + fshadow_shiftx:= 1; + fshadow_shifty:= 1; + fgloss_color:= cl_default; + fgloss_shiftx:= -1; + fgloss_shifty:= -1; + fgrayed_color:= cl_default; + fgrayed_colorshadow:= cl_default; + fgrayed_shiftx:= 1; + fgrayed_shifty:= 1; +} +end; +*) +procedure tskinfont.updatefont(const adest: tfont); +begin + if ftemplate <> nil then begin + with adest do begin + if template = nil then begin + template:= ftemplate; + end; + { + if fcolor <> cl_default then begin + color:= fcolor; + end; + if fcolorbackground <> cl_default then begin + colorbackground:= fcolorbackground; + end; + if fshadow_color <> cl_default then begin + shadow_color:= fshadow_color; + end; + if fshadow_shiftx <> 1 then begin + shadow_shiftx:= fshadow_shiftx; + end; + if fshadow_shifty <> 1 then begin + shadow_shifty:= fshadow_shifty; + end; + if fgloss_color <> cl_default then begin + gloss_color:= fgloss_color; + end; + if fgloss_shiftx <> -1 then begin + gloss_shiftx:= fgloss_shiftx; + end; + if fgloss_shifty <> -1 then begin + gloss_shifty:= fgloss_shifty; + end; + if fgrayed_color <> cl_default then begin + grayed_color:= fgrayed_color; + end; + if fgrayed_colorshadow <> cl_default then begin + grayed_colorshadow:= fgrayed_colorshadow; + end; + if fgrayed_shiftx <> 1 then begin + grayed_shiftx:= fgrayed_shiftx; + end; + if fgrayed_shifty <> 1 then begin + grayed_shifty:= fgrayed_shifty; + end; + if fextraspace <> 0 then begin + extraspace:= extraspace; + end; + if fstyle <> [] then begin + style:= fstyle; + end; + } + end; + end; +end; + +procedure tskinfont.settemplate(const avalue: tfontcomp); +begin + setlinkedvar(avalue,tmsecomponent(ftemplate)); +end; + +{ tskinhandler } + +procedure tskinhandler.updateskin1(const ainfo: skininfoty; + const controllerar: skincontrollerarty); +var + int1,int2: integer; +begin + for int1:= 0 to high(controllerar) do begin + if controllerar[int1].fgroupinfo = nil then begin + controllerar[int1].updateskin(ainfo); + end + else begin + for int2:= 0 to high(controllerar[int1].fgroupinfo) do begin + with controllerar[int1].fgroupinfo[int2] do begin + if (ainfo.group >= min) and (ainfo.group <= max) then begin + controllerar[int1].updateskin(ainfo); + break; + end; + end; + end; + end; + end; +end; +{ +procedure tskinhandler.removeskin1(const ainfo: skininfoty; + const controllerar: skincontrollerarty); +var + int1,int2: integer; +begin + for int1:= 0 to high(controllerar) do begin + if controllerar[int1].fgroupinfo = nil then begin + controllerar[int1].removeskin(ainfo); + end + else begin + for int2:= 0 to high(controllerar[int1].fgroupinfo) do begin + with controllerar[int1].fgroupinfo[int2] do begin + if (ainfo.group >= min) and (ainfo.group <= max) then begin + controllerar[int1].removeskin(ainfo); + break; + end; + end; + end; + end; + end; +end; +} +procedure tskinhandler.updateskin(const ainfo: skininfoty); +begin + updateskin1(ainfo,factiveskincontroller); +end; +{ +procedure tskinhandler.removeskin(const ainfo: skininfoty); +begin + removeskin1(ainfo,factiveskincontroller); +end; +} +function comparecontroller(const l,r): integer; +begin + result:= tcustomskincontroller(r).order-tcustomskincontroller(l).order; +end; + +procedure tskinhandler.setactive(const sender: tcustomskincontroller; + var controllerar: skincontrollerarty; + const handleproc: skineventty; var handlevar: skineventty{; + const removeproc: skineventty; var removevar: skineventty}); +begin + with sender do begin + if fisactive then begin + adduniqueitem(pointerarty(controllerar),sender); + sortarray(pointerarty(controllerar),@comparecontroller) + end + else begin + removeitem(pointerarty(controllerar),sender); + end; + if controllerar <> nil then begin + handlevar:= handleproc; +// removevar:= removeproc; + end + else begin + handlevar:= nil; +// removevar:= nil; + end; + end; +end; + +procedure tskinhandler.updateactive(const sender: tcustomskincontroller); +begin + setactive(sender,factiveskincontroller, + {$ifdef FPC}@{$endif}updateskin,oninitskinobject{, + @removeskin,onremoveskinobject}); +end; + +procedure tskinhandler.doactivate(const sender: tcustomskincontroller); +begin + //dummy +end; + +procedure tskinhandler.dodeactivate(const sender: tcustomskincontroller); +begin + //dummy +end; + +initialization + setskinhandler(tskinhandler.create); +finalization + freeandnil(fhandler); +end. diff --git a/mseide-msegui/lib/common/kernel/msesocketintf.inc b/mseide-msegui/lib/common/kernel/msesocketintf.inc new file mode 100644 index 0000000..4c7b6b6 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msesocketintf.inc @@ -0,0 +1,49 @@ +{ MSEgui Copyright (c) 1999-2007 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +function soc_getaddrerrortext(aerror: integer): string; +function soc_geterrortext(aerror: integer): string; + +function soc_open(const kind: socketkindty; const nonblock: boolean; + out handle: integer): syserrorty; +function soc_shutdown(const handle: integer; + const kind: socketshutdownkindty): syserrorty; +function soc_close(const handle: integer): syserrorty; +function soc_connect(const handle: integer; + const addr: socketaddrty; const timeoutms: integer): syserrorty; +function soc_bind(const handle: integer; + const addr: socketaddrty): syserrorty; +function soc_listen(const handle: integer; + const maxconnections: integer): syserrorty; +function soc_accept(const handle: integer; const nonblock: boolean; out conn: integer; + out addr: socketaddrty; const timeoutms: integer): syserrorty; +function soc_urltoaddr(var addr: socketaddrty): syserrorty; +function soc_getaddr(const addr: socketaddrty): string; + //address bytes +function soc_getport(const addr: socketaddrty): integer; +function soc_setnonblock(const handle: integer; + const nonblock: boolean): syserrorty; +function soc_read(const fd: longint; const buf: pointer; + const nbytes: longword; out readbytes: integer; + const timeoutms: integer): syserrorty; + //atimeoutms < 0 -> nonblocked, + //result = 0 -> no data, < 0 - error +function soc_write(const fd: longint; buf: pointer; + nbytes: longword; out writebytes: integer; + const timeoutms: integer): syserrorty; +function soc_setrxtimeout(const handle: integer; const ms: integer): syserrorty; +function soc_settxtimeout(const handle: integer; const ms: integer): syserrorty; + +function soc_poll(const handle: integer; const kind: pollkindsty; + const timeoutms: longword; + out pollres: pollkindsty): syserrorty; + //0 -> no timeout + //for blocking mode + + diff --git a/mseide-msegui/lib/common/kernel/msesonames.pas b/mseide-msegui/lib/common/kernel/msesonames.pas new file mode 100644 index 0000000..f54ff21 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msesonames.pas @@ -0,0 +1,50 @@ +{ MSEgui Copyright (c) 2008 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msesonames; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes; +{$ifdef mswindows} +//const +// sqlite3lib: array[0..0] of filenamety = ('sqlite3.dll'); +// postgreslib: array[0..0] of filenamety = ('libpq.dll'); +// mysqllib: array[0..0] of filenamety = ('libmysql.dll'); +// sslnames: array[0..1] of filenamety = ('ssleay32.dll','libssl32.dll'); +// sslutilnames: array[0..0] of filenamety = ('libeay32.dll'); +// fbembedlib: array[0..0] of filenamety = ('fbembed.dll'); +// fbcgdslib: array[0..1] of filenamety = ('fbclient.dll','gds32.dll'); +{$else} +const + xrendernames: array[0..1] of filenamety = ('libXrender.so.1','libXrender.so'); + xrandrnames: array[0..1] of filenamety = ('libXrandr.so.2','libXrandr.so'); + xftnames: array[0..1] of filenamety = ('libXft.so.2','libXft.so'); + icenames: array[0..1] of filenamety = ('libICE.so.6','libICE.so'); + smnames: array[0..1] of filenamety = ('libSM.so.6','libSM.so'); + +// sqlite3lib: array[0..1] of filenamety = ('libsqlite3.so.0','libsqlite3.so'); +// postgreslib: array[0..2] of filenamety = ('libpq.so.5.1','libpq.so.5','libpq.so'); +// mysqllib: array[0..2] of filenamety = ('libmysqlclient.so.16', +// 'libmysqlclient.so.15','libmysqlclient.so'); +// sslnames: array[0..4] of filenamety = ( +// 'libssl.so.1.0.0','libssl.so.0.9.8','libssl.so.0.9.7','libssl.so.0.9.6', +// 'libssl.so'); +// sslutilnames: array[0..4] of filenamety = ( +// 'libcrypto.so.1.0.0','libcrypto.so.0.9.8','libcrypto.so.0.9.7','libcrypto.so.0.9.6', +// 'libcrypto.so'); +// fbembedlib: array[0..2] of filenamety = ('libfbembed.so.2','libfbembed.so.1', +// 'libfbembed.so'); +// fbcgdslib: array[0..3] of filenamety = ('libfbclient.so.2','libfbclient.so.1', +// 'libfbclient.so','libgds.so'); +{$endif} + +implementation + +end. diff --git a/mseide-msegui/lib/common/kernel/msestat.pas b/mseide-msegui/lib/common/kernel/msestat.pas new file mode 100644 index 0000000..6ad8842 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msestat.pas @@ -0,0 +1,2054 @@ +{ MSEgui Copyright (c) 1999-2015 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msestat; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$goto on}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,mseclasses,mselist,msestream,mseglob,msereal,msetypes, + msestrings,mseinterfaces, + msehash,msedatalist,msesys,mseeditglob; + +const + defaultstatfilename = 'status.sta'; +type + tstatreader = class; + tstatwriter = class; + + statreadeventty = procedure (const reader: tstatreader) of object; + statwriteeventty = procedure (const writer: tstatwriter) of object; + + istatfile = interface(iobjectlink)[miid_istatfile] + procedure dostatread(const reader: tstatreader); + procedure dostatwrite(const writer: tstatwriter); + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + end; + + istatupdatevalue = interface(inullinterface) + procedure statreadvalue(const aname: msestring; const reader: tstatreader); + procedure statwritevalue(const aname: msestring; const writer: tstatwriter); + end; + statfileroptionty = (sfro_nodata,sfro_nooptions,sfro_nostate); + statfileroptionsty = set of statfileroptionty; + + tstatfiler = class + private + fstream: ttextstream; + fownsstream: boolean; + fiswriter: boolean; + flistlevel: integer; + foptions: statfileroptionsty; + protected + fcurrentsection: msestring; + public + constructor create(const astream: ttextstream; + const aencoding: charencodingty = ce_utf8); + destructor destroy; override; + function varname(const intf: istatfile): msestring; + function arrayname(const name: msestring; index: integer): msestring; + function iswriter: boolean; + property stream: ttextstream read fstream; + + procedure setsection(const name: msestring); + property currentsection: msestring read fcurrentsection; + procedure updatevalue(const name: msestring; var value: boolean); overload; + procedure updatevalue(const name: msestring; var value: byte); overload; + procedure updatevalue(const name: msestring; var value: word); overload; + procedure updatevalue(const name: msestring; var value: integer; + const min: integer = -(maxint)-1; const max: integer = maxint); overload; + procedure updatevalue(const name: msestring; var value: real; + const min: real = -bigreal; const max: real = bigreal); overload; + procedure updatevalue(const name: msestring; var value: string); overload; + procedure updatebinaryvalue(const name: msestring; var value: string); + procedure updatevalue(const name: msestring; var value: msestring); overload; + procedure updatevalue(const name: msestring; var value: tdatalist); overload; + procedure updatevalue(const name: msestring; var value: stringarty); overload; + procedure updatevalue(const name: msestring; var value: msestringarty); overload; + procedure updatevalue(const name: msestring; var value: longboolarty); overload; + procedure updatevalue(const name: msestring; var value: integerarty); overload; + procedure updatevalue(const name: msestring; var value: int64arty); overload; + procedure updatevalue(const name: msestring; var value: realarty); overload; + procedure updatevalue(const name: msestring; var value: complexarty); overload; + + procedure updatevalue(const name: msestring; const intf: istatupdatevalue); overload; + procedure updatestat(const intf: istatfile); + procedure updatememorystatstream(const name: msestring; const streamname: msestring); + function beginlist(const name: msestring = ''): boolean; virtual; abstract; + function endlist: boolean; virtual; abstract; + property options: statfileroptionsty read foptions write foptions; + function candata: boolean; + function canstate: boolean; + function canoptions: boolean; + end; + + sectionty = record + fileposition: integer; + names: tpointermsestringhashdatalist; + count: integer; + values: msestringarty; + end; + psectionty = ^sectionty; + sectionarty = array of sectionty; + + recsetcounteventty = procedure(const acount: integer) of object; + recsetcountevent1ty = procedure(const acount: integer); + recstoreeventty = procedure(const aindex: integer; const avalue: msestring) of object; + recstoreevent1ty = procedure(const aindex: integer; const avalue: msestring); + + tstatreader = class(tstatfiler) + private + fsectionlist: tpointermsestringhashdatalist; + fsections: sectionarty; + fsectioncount: integer; + factsection: psectionty; + factitem: integer; + fliststart: integerarty; + fstatend: integer; + procedure checkrealrange(var value: realty; const min,max: realty); + procedure checkintegerrange(var value: integer; const min,max: integer); + procedure checkint64range(var value: int64; const min,max: int64); + protected + procedure readdata; + function findvar(const name: msestring; var value: msestring): boolean; + overload; //true if ok + function findvar(const name: msestring; var value: msestring; + out isarray: boolean): boolean; overload; //true if ok + public + constructor create(const astream: ttextstream; + const aencoding: charencodingty = ce_utf8); overload; + constructor create(const filename: filenamety; + const aencoding: charencodingty = ce_utf8); overload; + destructor destroy; override; + function sections: msestringarty; + function hassection(const name: msestring): boolean; //true if found + function findsection(const name: msestring): boolean; + //switch section, true if found + function checkvar(const name: msestring): boolean; //true if found + function streamdata: string; //returns data after [-] + function streamtext: msestring; //returns text after [-] + + function readboolean(const name: msestring; const default: boolean = false): boolean; + function readbyte(const name: msestring; const default: byte = 0): byte; + function readword(const name: msestring; const default: word = 0): word; + function readinteger(const name: msestring; const default: integer = 0; + const min: integer = -(maxint)-1; const max: integer = maxint): integer; + function readint64(const name: msestring; const default: int64 = 0; + const min: int64 = -(maxint64)-1; const max: int64 = maxint64): int64; + function readreal(const name: msestring; const default: real = 0; + const min: real = -bigreal; const max: real = bigreal; + const acceptempty: boolean = false): realty; + function readstring(const name: msestring; const default: string): string; + function readbinarystring(const name: msestring; const default: string): string; + function readmsestring(const name: msestring; const default: msestring): msestring; + procedure readdatalist(const name: msestring; const value: tdatalist); + function readarray(const name: msestring; const default: stringarty): stringarty; overload; + function readarray(const name: msestring; const default: msestringarty): msestringarty; overload; + function readarray(const name: msestring; const default: widestringarty): widestringarty; overload; + function readarray(const name: msestring; const default: integerarty): integerarty; overload; + function readarray(const name: msestring; const default: int64arty): int64arty; overload; + function readarray(const name: msestring; const default: booleanarty): booleanarty; overload; + function readarray(const name: msestring; const default: longboolarty): longboolarty; overload; + function readarray(const name: msestring; + const default: realarty): realarty; overload; + function readarray(const name: msestring; + const default: complexarty): complexarty; overload; + function readlistitem: msestring; + + procedure readrecord(const name: msestring; const values: array of pointer; + const default: array of const); + procedure readrecordarray(const name: msestring; + setcount: recsetcounteventty; store: recstoreeventty); overload; + procedure readrecordarray(const name: msestring; + setcount: recsetcountevent1ty; store: recstoreevent1ty); overload; + //setcount(0) on error + function beginlist(const name: msestring = ''): boolean; override; + function endlist: boolean; override; + + procedure readvalue(const name: msestring; const intf: istatupdatevalue); + procedure readstat(const intf: istatfile); + procedure readmemorystatstream(const name: msestring; const streamname: msestring); + end; + + recgetrecordeventty = function(const index: integer): msestring of object; + recgetrecordevent1ty = function(const index: integer): msestring; + + tstatwriter = class(tstatfiler) + protected + procedure writeval(const name: msestring; const avalue: msestring); + procedure writemultival(const name: msestring; const avalue: msestring); + procedure writemultilistval(const avalue: msestring); + procedure writelistval(const avalue: msestring); + public + constructor create(const astream: ttextstream; + const aencoding: charencodingty = ce_utf8); overload; + constructor create(const filename: filenamety; + const aencoding: charencodingty = ce_utf8; + const atransaction: boolean = true); overload; + + procedure writesection(const name: msestring); + procedure writeboolean(const name: msestring; const value: boolean); + procedure writebyte(const name: msestring; const value: byte); + procedure writeword(const name: msestring; const value: word); + procedure writeinteger(const name: msestring; const value: integer); + procedure writeint64(const name: msestring; const value: int64); + procedure writereal(const name: msestring; const value: real); + procedure writestring(const name: msestring; const value: string); + procedure writebinarystring(const name: msestring; const value: string); + procedure writemsestring(const name: msestring; const value: msestring); +// procedure writemsestrings(const name: msestring; const value: msestring); +// //handles linebreaks, 'ar' is multiline name extension + procedure writedatalist(const name: msestring; const value: tdatalist); + procedure writearray(const name: msestring; const value: stringarty); overload; + procedure writearray(const name: msestring; const value: msestringarty); overload; + procedure writearray(const name: msestring; const value: integerarty); overload; + procedure writearray(const name: msestring; const value: int64arty); overload; + procedure writearray(const name: msestring; const value: booleanarty); overload; + procedure writearray(const name: msestring; const value: longboolarty); overload; + procedure writearray(const name: msestring; const value: realarty); overload; + procedure writearray(const name: msestring; const value: complexarty); overload; + + procedure writelistitem(const value: msestring); overload; + procedure writelistitem(const value: integer); overload; + procedure writelistitem(const value: realty); overload; + procedure writelistitem(const value: complexty); overload; + + procedure writerecord(const name: msestring; const values: array of const); + procedure writerecordarray(const name: msestring; const count: integer; + get: recgetrecordeventty); overload; + procedure writerecordarray(const name: msestring; const count: integer; + get: recgetrecordevent1ty); overload; + function beginlist(const name: msestring = ''): boolean; override; + function endlist: boolean; override; + + procedure writevalue(const name: msestring; const intf: istatupdatevalue); + procedure writestat(const intf: istatfile); + procedure writememorystatstream(const name: msestring; + const streamname: msestring); + procedure streamdata(const adata: string); + procedure streamtext(const atext: msestring); + end; + + tmemorytextstream = class; + + streaminfoty = record + name: msestring; + data: pointer; + size: integer; + stream: tmemorytextstream; + end; + + tmemorystreams = class; + + tmemorytextstream = class(ttextstream) + private + fname: msestring; + fowner: tmemorystreams; +// findex: integer; + public + constructor create(aowner: tmemorystreams; const name: msestring; + const aopenmode: fileopenmodety; var info: streaminfoty); reintroduce; + destructor destroy; override; + end; + + tmemorystreams = class + private + fstreams: array of streaminfoty; + function findname(const name: msestring): integer; + procedure internaldelete(index: integer); + public + destructor destroy; override; + function open(const streamname: msestring; + const aopenmode: fileopenmodety): ttextstream; + procedure delete(const name: msestring); + function findfiles(const aname: msestring): msestringarty; + end; + +procedure deletememorystatstream(const streamname: msestring); +function memorystatstreams: tmemorystreams; + +function canstatvalue(const editoptions: optionsedit1ty; + const stat: tstatfiler): boolean; +function canstatstate(const editoptions: optionsedit1ty; + const stat: tstatfiler): boolean; +function canstatoptions(const editoptions: optionsedit1ty; + const stat: tstatfiler): boolean; + +procedure readstringar(const reader: treader; out avalue: stringarty); +procedure writestringar(const writer: twriter; const avalue: stringarty); + +function writestat(const asource: array of statwriteeventty; + const section: msestring): string; +procedure readstat(const adest: array of statreadeventty; + const atext: string; const section: msestring); +implementation +uses + sysutils,mseformatstr,msefileutils,msearrayutils,msesystypes; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tdatalist1 = class(tdatalist); + tmemorystreamcracker = class(tcustommemorystream) + private + fcapacity: longint; + end; + +procedure readstringar(const reader: treader; out avalue: stringarty); +var + int1: integer; +begin + reader.readlistbegin; + int1:= 0; + while not reader.endoflist do begin + additem(avalue,reader.readstring,int1); + end; + reader.readlistend; + setlength(avalue,int1); +end; + +procedure writestringar(const writer: twriter; const avalue: stringarty); +var + int1: integer; +begin + writer.writelistbegin; + for int1:= 0 to high(avalue) do begin + writer.writestring(avalue[int1]); + end; + writer.writelistend; +end; + +function writestat(const asource: array of statwriteeventty; + const section: msestring): string; +var + stream1: ttextstringbufferstream; + writer1: tstatwriter = nil; + int1: integer; +begin + stream1:= ttextstringbufferstream.create(''); + try + writer1:= tstatwriter.create(stream1); + writer1.setsection(section); + for int1:= 0 to high(asource) do begin + asource[int1](writer1); + end; + result:= stream1.data; + finally + stream1.destroy(); + writer1.free(); + end; +end; + +procedure readstat(const adest: array of statreadeventty;const atext: string; + const section: msestring); +var + stream1: ttextstringbufferstream; + reader1: tstatreader = nil; + int1: integer; +begin + stream1:= ttextstringbufferstream.create(atext); + try + reader1:= tstatreader.create(stream1); + reader1.setsection(section); + for int1:= 0 to high(adest) do begin + adest[int1](reader1); + end; + finally + stream1.destroy(); + reader1.free(); + end; +end; + +function canstatvalue(const editoptions: optionsedit1ty; + const stat: tstatfiler): boolean; +begin + result:= (oe1_savevalue in editoptions) and stat.candata; +end; + +function canstatstate(const editoptions: optionsedit1ty; + const stat: tstatfiler): boolean; +begin + result:= (oe1_savestate in editoptions) and stat.canstate; +end; + +function canstatoptions(const editoptions: optionsedit1ty; + const stat: tstatfiler): boolean; +begin + result:= (oe1_saveoptions in editoptions) and stat.canoptions; +end; + +var + fmemorystatstreams: tmemorystreams; + +function memorystatstreams: tmemorystreams; +begin + if fmemorystatstreams = nil then begin + fmemorystatstreams:= tmemorystreams.create; + end; + result:= fmemorystatstreams; +end; + +procedure deletememorystatstream(const streamname: msestring); +begin + if fmemorystatstreams <> nil then begin + fmemorystatstreams.delete(streamname); + end; +end; + +{ tstatfiler } + +constructor tstatfiler.create(const astream: ttextstream; + const aencoding: charencodingty = ce_utf8); +begin + fstream:= astream; + if fstream <> nil then begin + fstream.encoding:= aencoding; + end; +end; + +function tstatfiler.arrayname(const name: msestring; index: integer): msestring; +begin + result:= name + '_'+inttostrmse(index); +end; + +destructor tstatfiler.destroy; +begin + if fownsstream then begin + fstream.free; + end; + inherited; +end; + +function tstatfiler.iswriter: boolean; +begin + result:= fiswriter; +end; + +procedure tstatfiler.setsection(const name: msestring); +begin + if fiswriter then begin + tstatwriter(self).writesection(name); + end + else begin + tstatreader(self).findsection(name); + end; +end; + +procedure tstatfiler.updatevalue(const name: msestring; var value: boolean); +begin + if fiswriter then begin + tstatwriter(self).writeboolean(name,value); + end + else begin + value:= tstatreader(self).readboolean(name,value); + end; +end; + +procedure tstatfiler.updatevalue(const name: msestring; var value: byte); +begin + if fiswriter then begin + tstatwriter(self).writebyte(name,value); + end + else begin + value:= tstatreader(self).readbyte(name,value); + end; +end; + +procedure tstatfiler.updatevalue(const name: msestring; var value: word); +begin + if fiswriter then begin + tstatwriter(self).writeword(name,value); + end + else begin + value:= tstatreader(self).readword(name,value); + end; +end; + +procedure tstatfiler.updatevalue(const name: msestring; var value: tdatalist); +begin + if fiswriter then begin + tstatwriter(self).writedatalist(name,value); + end + else begin + tstatreader(self).readdatalist(name,value); + end; +end; + +procedure tstatfiler.updatevalue(const name: msestring; var value: integer; const min, max: integer); +begin + if fiswriter then begin + tstatwriter(self).writeinteger(name,value); + end + else begin + value:= tstatreader(self).readinteger(name,value,min,max); + end; +end; + +procedure tstatfiler.updatevalue(const name: msestring; var value: real; const min, max: real); +begin + if fiswriter then begin + tstatwriter(self).writereal(name,value); + end + else begin + value:= tstatreader(self).readreal(name,value,min,max); + end; +end; + +procedure tstatfiler.updatevalue(const name: msestring; var value: integerarty); +begin + if fiswriter then begin + tstatwriter(self).writearray(name,value); + end + else begin + value:= tstatreader(self).readarray(name,value); + end; +end; + +procedure tstatfiler.updatevalue(const name: msestring; var value: int64arty); +begin + if fiswriter then begin + tstatwriter(self).writearray(name,value); + end + else begin + value:= tstatreader(self).readarray(name,value); + end; +end; + +procedure tstatfiler.updatevalue(const name: msestring; var value: longboolarty); +begin + if fiswriter then begin + tstatwriter(self).writearray(name,value); + end + else begin + value:= tstatreader(self).readarray(name,value); + end; +end; + +procedure tstatfiler.updatevalue(const name: msestring; var value: realarty); +begin + if fiswriter then begin + tstatwriter(self).writearray(name,value); + end + else begin + value:= tstatreader(self).readarray(name,value); + end; +end; + +procedure tstatfiler.updatevalue(const name: msestring; var value: complexarty); +begin + if fiswriter then begin + tstatwriter(self).writearray(name,value); + end + else begin + value:= tstatreader(self).readarray(name,value); + end; +end; + +procedure tstatfiler.updatevalue(const name: msestring; var value: stringarty); +begin + if fiswriter then begin + tstatwriter(self).writearray(name,value); + end + else begin + value:= tstatreader(self).readarray(name,value); + end; +end; + +procedure tstatfiler.updatevalue(const name: msestring; var value: msestringarty); +begin + if fiswriter then begin + tstatwriter(self).writearray(name,value); + end + else begin + value:= tstatreader(self).readarray(name,value); + end; +end; + +procedure tstatfiler.updatevalue(const name: msestring; var value: string); +begin + if fiswriter then begin + tstatwriter(self).writestring(name,value); + end + else begin + value:= tstatreader(self).readstring(name,value); + end; +end; + +procedure tstatfiler.updatebinaryvalue(const name: msestring; var value: string); +begin + if fiswriter then begin + tstatwriter(self).writebinarystring(name,value); + end + else begin + value:= tstatreader(self).readbinarystring(name,value); + end; +end; + +procedure tstatfiler.updatevalue(const name: msestring; var value: msestring); +begin + if fiswriter then begin + tstatwriter(self).writemsestring(name,value); + end + else begin + value:= tstatreader(self).readmsestring(name,value); + end; +end; + +procedure tstatfiler.updatestat(const intf: istatfile); +begin + if fiswriter then begin + tstatwriter(self).writestat(intf); + end + else begin + intf.statreading; + try + tstatreader(self).readstat(intf); + finally + intf.statread; + end; + end; +end; + +procedure tstatfiler.updatevalue(const name: msestring; const intf: istatupdatevalue); +begin + if fiswriter then begin + tstatwriter(self).writevalue(name,intf); + end + else begin + tstatreader(self).readvalue(name,intf); + end; +end; + +procedure tstatfiler.updatememorystatstream(const name: msestring; const streamname: msestring); +begin + if iswriter then begin + tstatwriter(self).writememorystatstream(name,streamname); + end + else begin + tstatreader(self).readmemorystatstream(name,streamname); + end; +end; +{ +procedure tstatfiler.updatestatfile(const name: msestring; const statfile: tstatfile); +begin + if iswriter then begin + tstatwriter(self).writestatfile(name,statfile); + end + else begin + tstatreader(self).readstatfile(name,statfile); + end; +end; +} +function tstatfiler.varname(const intf: istatfile): msestring; +begin + result:= intf.getstatvarname; + if result = '' then begin + result:= msestring(ownernamepath(tcomponent(intf.getinstance))); + end; +end; + +function tstatfiler.candata: boolean; +begin + result:= not (sfro_nodata in foptions); +end; + +function tstatfiler.canstate: boolean; +begin + result:= not (sfro_nostate in foptions); +end; + +function tstatfiler.canoptions: boolean; +begin + result:= not (sfro_nooptions in foptions); +end; + +{ tstatreader } + +constructor tstatreader.create(const astream: ttextstream; + const aencoding: charencodingty = ce_utf8); +begin + inherited; + fsectionlist:= tpointermsestringhashdatalist.create; + readdata; +end; + +constructor tstatreader.create(const filename: filenamety; + const aencoding: charencodingty = ce_utf8); +var + stream1: ttextstream; +begin + fownsstream:= true; + stream1:= ttextstream.Create(filename,fm_read); +// stream1.encoding:= aencoding; + create(stream1,aencoding); +end; + +destructor tstatreader.destroy; +var + int1: integer; +begin + inherited; + for int1:= 0 to fsectioncount - 1 do begin + fsections[int1].names.Free; + end; + fsectionlist.Free; +end; + +procedure tstatreader.readdata; +var + str1: msestring; + int1: integer; +begin + if fstream <> nil then begin + str1:= ''; + while not fstream.eof do begin + while not fstream.eof and not((length(str1) > 0) and (str1[1] = '[')) do begin + try + fstream.readln(str1); + except + on ecrashstatfile do begin + raise; + end; + else begin + exit; + end; + end; + end; + if not fstream.eof then begin + int1:= findchar(str1,msechar(']')); + if int1 > 0 then begin + if int1 = 2 then begin + fstatend:= fstream.position; + exit; + end; + if fsectioncount >= length(fsections) then begin + setlength(fsections,length(fsections)*2+16); + end; + inc(fsectioncount); + fsectionlist.add(copy(str1,2,int1-2),pointer(ptruint(fsectioncount))); + with fsections[fsectioncount-1] do begin + fileposition:= fstream.position; + names:= tpointermsestringhashdatalist.create; + count:= 0; + while fstream.readln(str1) do begin + if (length(str1) > 0) and (str1[1] = '[') then begin + break; + end; + if count >= length(values) then begin + setlength(values,length(values)+16); + end; + inc(count); + if (length(str1) > 0) and (str1[1] <> ' ') and (str1[1] <> '+') then begin + int1:= findchar(str1,msechar('=')); + if int1 > 0 then begin + names.add(copy(str1,1,int1-1),pointer(ptruint(count))); + values[count-1]:= copy(str1,int1+1,bigint); + end + else begin + values[count-1]:= str1; + end; + end + else begin + values[count-1]:= str1; + end; + end; + end; + end + else begin + str1:= ''; + end; + end; + end; + end; +end; + +function tstatreader.findvar(const name: msestring; + var value: msestring): boolean; +var + int1,int2,int3: integer; + ch1: msechar; +begin + if factsection <> nil then begin + with factsection^ do begin + if flistlevel = 0 then begin + factitem:= ptruint(names.find(name)); + if factitem = 0 then begin + result:= false; + end + else begin + dec(factitem); + value:= values[factitem]; + int1:= factitem+1; //check multiline + while (int1 <= high(values)) and (values[int1] <> '') and + (values[int1][1] = '+') do begin + value:= value+lineend+copy(values[int1],2,bigint); + inc(int1); + end; + result:= true; + end; + end + else begin + result:= false; + for int1:= fliststart[flistlevel] to high(values) do begin +// for int1:= fliststart[flistlevel] to high(values) do begin + if length(values[int1]) > flistlevel then begin + ch1:= values[int1][flistlevel+1]; + if ch1 = ')' then begin + break; + end; + if ch1 <> ' ' then begin + int2:= findchar(values[int1],msechar('=')); + if (int2 = flistlevel+length(name)+1) and + (msestrlcomp(pmsechar(values[int1])+flistlevel, + pmsechar(name),length(name)) = 0) then begin + factitem:= int1; + value:= copy(values[int1],int2+1,bigint); + int3:= int1+1; //check multiline + while (int3 <= high(values)) and (length(values[int1]) > flistlevel) and + (values[int3][flistlevel+1] = '+') do begin + value:= value+lineend+copy(values[int3],flistlevel+2,bigint); + inc(int3); + end; + result:= true; + break; + end; + end; + end; + end; + end; + end; + end + else begin + result:= false; + end; +end; + +function tstatreader.findvar(const name: msestring; var value: msestring; + out isarray: boolean): boolean; +begin + result:= findvar(name,value); + isarray:= false; + if result then begin + with factsection^ do begin + if (factitem < count - 1) and (length(values[factitem+1]) > flistlevel) and + (values[factitem+1][flistlevel+1] = ' ') then begin + isarray:= true; + end; + end; + end; +end; + +function tstatreader.checkvar(const name: msestring): boolean; +begin + result:= (factsection <> nil) and (factsection^.names.find(name) <> nil); +end; + +function tstatreader.readboolean(const name: msestring; const default: boolean = false): boolean; +begin + result:= readinteger(name,integer(default)) <> 0; +end; + +function tstatreader.readbyte(const name: msestring; const default: byte = 0): byte; +begin + result:= readinteger(name,default); +end; + +function tstatreader.readword(const name: msestring; const default: word = 0): word; +begin + result:= readinteger(name,default); +end; + +procedure tstatreader.checkintegerrange(var value: integer; const min,max: integer); +begin + if max < min then begin //unsigned + if longword(value) > longword(max) then begin + value:= max; + end + else begin + if longword(value) < longword(min) then begin + value:= min; + end; + end; + end + else begin + if value > max then begin + value:= max; + end + else begin + if value < min then begin + value:= min; + end; + end; + end; +end; + +procedure tstatreader.checkint64range(var value: int64; const min,max: int64); +begin + if max < min then begin //unsigned + {$ifdef FPC} + if qword(value) > qword(max) then begin + value:= max; + end + else begin + if qword(value) < qword(min) then begin + value:= min; + end; + end; + {$else} + //delphi has no unsigned 64 bit type + {$endif} + end + else begin + if value > max then begin + value:= max; + end + else begin + if value < min then begin + value:= min; + end; + end; + end; +end; + +function tstatreader.readinteger(const name: msestring; const default: integer = 0; + const min: integer = -(maxint)-1; const max: integer = maxint): integer; +var + str1: msestring; +begin + if not findvar(name,str1) then begin + result:= default; + end + else begin + if trystrtoint(str1,result) then begin + checkintegerrange(result,min,max); + end + else begin + result:= default; + end; + end; +end; + +function tstatreader.readint64(const name: msestring; const default: int64 = 0; + const min: int64 = -(maxint64)-1; const max: int64 = maxint64): int64; +var + str1: msestring; +begin + if not findvar(name,str1) then begin + result:= default; + end + else begin + if trystrtoint64(str1,result) then begin + checkint64range(result,min,max); + end + else begin + result:= default; + end; + end; +end; + +procedure tstatreader.checkrealrange(var value: realty; const min,max: realty); +begin + if cmprealty(value,max) > 0 then begin + value:= max; + end + else begin + if cmprealty(value,min) < 0 then begin + value:= min; + end; + end; +end; + +function tstatreader.readreal(const name: msestring; const default: real = 0; + const min: real = -bigreal; const max: real = bigreal; + const acceptempty: boolean = false): realty; +var + str1: msestring; +begin + if not findvar(name,str1) then begin + result:= default; + end + else begin + if (str1 = '') and acceptempty then begin + result:= emptyreal; + end + else begin + if trystrtorealtydot(str1,result) then begin + checkrealrange(result,min,max); + end + else begin + result:= default; + end; + end; + end; +end; + +function tstatreader.readstring(const name: msestring; const default: string): string; +var + str1: msestring; +begin + if not findvar(name,str1) then begin + result:= default; + end + else begin + result:= ansistring(str1); + end; +end; + +function tstatreader.readbinarystring(const name: msestring; + const default: string): string; +var + mstr1: msestring; +begin + if not findvar(name,mstr1) then begin + result:= default; + end + else begin + result:= decodebase64(ansistring(mstr1)); + end; +end; + +function tstatreader.readmsestring(const name: msestring; + const default: msestring): msestring; +begin + result:= ''; //compilerwarning + if not findvar(name,result) then begin + result:= default; + end; +end; +(* +function tstatreader.readmsestrings(const name: msestring; + const default: msestring): msestring; +var + ar1: msestringarty; +begin + ar1:= readarray(name+'ar',msestringarty(nil){ar1}); + if high(ar1) >= 0 then begin + result:= concatstrings(ar1,lineend); + end + else begin + result:= readmsestring(name,default); + end; +end; +*) +function tstatreader.readlistitem: msestring; +var + int1,int2: integer; + slen: integer; + po1: pmsecharaty; + bo1: boolean; +begin + result:= ''; + bo1:= false; + while factitem < factsection^.count - 1 do begin + po1:= pointer(factsection^.values[factitem+1]); + slen:= length(msestring(pointer(po1))); + if slen <= flistlevel then begin + exit; + end; + for int1:= 0 to flistlevel-1 do begin + if (po1^[int1] <> ' ') then begin + exit; + end; + end; + if po1^[flistlevel] = '+' then begin + result:= result+lineend; + end + else begin + if bo1 or (po1^[flistlevel] <> ' ') then begin + exit; + end; + end; + int2:= length(result); + int1:= slen-flistlevel-1; + setlength(result,int2+int1); + move(po1^[flistlevel+1],pmsecharaty(pointer(result))^[int2], + int1*sizeof(msechar)); + bo1:= true; + inc(factitem); + end; +end; + +procedure tstatreader.readdatalist(const name: msestring; + const value: tdatalist); +var + str1: msestring; + int1: integer; +begin + if findvar(name,str1) then begin + try + value.beginupdate; + try + if trystrtoint(str1,int1) then begin + tdatalist1(value).readstate(self,int1,name); + tdatalist1(value).readappendix(self,name); + end; + finally + value.endupdate; + end; + except + end; + end; +end; + +function tstatreader.hassection(const name: msestring): boolean; +begin + result:= fsectionlist.find(name) <> nil; +end; + +function tstatreader.findsection(const name: msestring): boolean; +var + int1: integer; +begin + flistlevel:= 0; + int1:= ptruint(fsectionlist.find(name)); + if int1 = 0 then begin + factsection:= nil; + fcurrentsection:= ''; + end + else begin + factsection:= @fsections[int1-1]; + fcurrentsection:= name; + end; + result:= int1 <> 0; +end; + +procedure tstatreader.readstat(const intf: istatfile); +begin + if intf <> nil then begin + findsection(varname(intf)); + intf.dostatread(self); + end; +end; + +procedure tstatreader.readvalue(const name: msestring; const intf: istatupdatevalue); +begin + if intf <> nil then begin + intf.statreadvalue(name,self); + end; +end; + +function tstatreader.readarray(const name: msestring; + const default: msestringarty): msestringarty; +var + str1: msestring; + int1,int2: integer; +begin + if findvar(name,str1) and trystrtoint(str1,int2)then begin + setlength(result,int2); + for int1:= 0 to int2-1 do begin + result[int1]:= readlistitem; + end; + end + else begin + result:= default; + setlength(result,length(result)); + end; +end; + +function tstatreader.readarray(const name: msestring; + const default: widestringarty): widestringarty; +var + str1: msestring; + int1,int2: integer; +begin + if findvar(name,str1) and trystrtoint(str1,int2) then begin + setlength(result,int2); + for int1:= 0 to int2-1 do begin + result[int1]:= readlistitem; + end; + end + else begin + result:= default; + setlength(result,length(result)); + end; +end; + +function tstatreader.readarray(const name: msestring; + const default: stringarty): stringarty; +var + str1: msestring; + int1,int2: integer; +begin + if findvar(name,str1) and trystrtoint(str1,int2) then begin + setlength(result,int2); + for int1:= 0 to int2-1 do begin + result[int1]:= ansistring(readlistitem); + end; + end + else begin + result:= default; + end; +end; + +function tstatreader.readarray(const name: msestring; + const default: integerarty): integerarty; +var + str1: msestring; + int1,int2: integer; +begin + if findvar(name,str1) and trystrtoint(str1,int2) then begin + setlength(result,int2); + for int1:= 0 to int2-1 do begin + if not trystrtoint(readlistitem,result[int1]) then begin + result:= default; + break; + end; + end; + end + else begin + result:= default; + end; +end; + +function tstatreader.readarray(const name: msestring; + const default: int64arty): int64arty; +var + str1: msestring; + int1,int2: integer; +begin + if findvar(name,str1) and trystrtoint(str1,int2) then begin + setlength(result,int2); + for int1:= 0 to int2-1 do begin + if not trystrtoint64(readlistitem,result[int1]) then begin + result:= default; + break; + end; + end; + end + else begin + result:= default; + end; +end; + +function tstatreader.readarray(const name: msestring; + const default: longboolarty): longboolarty; +var + str1: msestring; + int1,int2,int3: integer; +begin + if findvar(name,str1) and trystrtoint(str1,int2) then begin + setlength(result,int2); + for int1:= 0 to int2-1 do begin + if not trystrtoint(readlistitem,int3) then begin + result:= default; + break; + end; + result[int1]:= longbool(int3); + end; + end + else begin + result:= default; + end; +end; + +function tstatreader.readarray(const name: msestring; + const default: booleanarty): booleanarty; +var + str1: msestring; + int1,int2,int3: integer; +begin + if findvar(name,str1) and trystrtoint(str1,int2) then begin + setlength(result,int2); + for int1:= 0 to int2-1 do begin + if not trystrtoint(readlistitem,int3) then begin + result:= default; + break; + end; + result[int1]:= boolean(int3); + end; + end + else begin + result:= default; + end; +end; + +function tstatreader.readarray(const name: msestring; + const default: realarty): realarty; +var + str1: msestring; + int1,int2: integer; +begin + if findvar(name,str1) and trystrtoint(str1,int2) then begin + setlength(result,int2); + for int1:= 0 to int2-1 do begin + if not trystrtorealtydot(readlistitem,result[int1]) then begin + result:= default; + break; + end; + end; + end + else begin + result:= default; + end; +end; + +function tstatreader.readarray(const name: msestring; + const default: complexarty): complexarty; +var + str1: msestring; + int1,int2: integer; +begin + if findvar(name,str1) and trystrtoint(str1,int2) then begin + setlength(result,int2); + for int1:= 0 to int2-1 do begin + if not decoderecord( + readlistitem,[@result[int1].re,@result[int1].im],'rr') then begin + result:= default; + break; + end; + end; + end + else begin + result:= default; + end; +end; + +procedure tstatreader.readrecord(const name: msestring; const values: array of pointer; + const default: array of const); +var + str1: msestring; + str2: string; +begin + str2:= getrecordtypechars(default); + if length(str2) > length(values) then begin + setlength(str2,length(values)); + end; + if not findvar(name,str1) or not decoderecord(str1,values,str2) then begin + copyvariantarray(default,values); + end; +end; + +procedure tstatreader.readrecordarray(const name: msestring; + setcount: recsetcounteventty; store: recstoreeventty); +var + str1: msestring; + int1,int2: integer; +begin + if findvar(name,str1) and trystrtoint(str1,int2) then begin + try + if assigned(setcount) then begin + setcount(int2); + end; + if assigned(store) then begin + for int1:= 0 to int2-1 do begin + store(int1,readlistitem); + end; + end; + except + if assigned(setcount) then begin + setcount(0); + end; + end; + end + else begin + if assigned(setcount) then begin + setcount(0); + end; + end; +end; + +procedure tstatreader.readrecordarray(const name: msestring; + setcount: recsetcountevent1ty; store: recstoreevent1ty); +var + str1: msestring; + int1,int2: integer; +begin + if findvar(name,str1) and trystrtoint(str1,int2) then begin + try + if assigned(setcount) then begin + setcount(int2); + end; + if assigned(store) then begin + for int1:= 0 to int2-1 do begin + store(int1,readlistitem); + end; + end; + except + if assigned(setcount) then begin + setcount(0); + end; + end; + end + else begin + if assigned(setcount) then begin + setcount(0); + end; + end; +end; + +function tstatreader.beginlist(const name: msestring = ''): boolean; +var + str1: msestring; +begin + result:= false; + if factsection <> nil then begin + if (name <> '') and not findvar(name,str1) then begin + exit; + end; + inc(flistlevel); + inc(factitem); + with factsection^ do begin + if (high(values) >= factitem) and (length(values[factitem]) > flistlevel) and + (values[factitem][flistlevel+1] = '(') then begin + result:= true; + if high(fliststart) <= flistlevel then begin + setlength(fliststart,flistlevel+16); + end; + fliststart[flistlevel]:= factitem; + end + else begin + dec(flistlevel); + dec(factitem); + end; + end; + end; +end; + +function tstatreader.endlist: boolean; +var + int1: integer; +begin + result:= false; + if (factsection <> nil) and (flistlevel > 0) then begin + with factsection^ do begin + for int1:= fliststart[flistlevel] to high(values) do begin + if (length(values[int1]) > flistlevel) and + (values[int1][flistlevel+1] = ')') then begin + result:= true; + factitem:= int1; + break; + end; + end; + end; + dec(flistlevel); + end; +end; + +procedure tstatreader.readmemorystatstream(const name, streamname: msestring); +var + ar1: msestringarty; + stream1: ttextstream; +begin + ar1:= readarray(name,msestringarty(nil)); + if high(ar1) >= 0 then begin + stream1:= nil; + try + try + stream1:= memorystatstreams.open(streamname,fm_read); + stream1.encoding:= fstream.encoding; + stream1.size:= 0; + stream1.writemsestrings(ar1); + finally + stream1.Free; + end; + except + end; + end + else begin + memorystatstreams.delete(streamname); + end; +end; + +function tstatreader.sections: msestringarty; +var + int1: integer; +begin + setlength(result,fsectionlist.count); + for int1:= 0 to high(result) do begin + result[int1]:= fsectionlist.next^.data.key; + end; +end; + +function tstatreader.streamdata: string; +begin + result:= ''; + if fstatend > 0 then begin + fstream.position:= fstatend; + result:= fstream.readdatastring; + end; +end; + +function tstatreader.streamtext: msestring; +begin + result:= ''; + if fstatend > 0 then begin + fstream.position:= fstatend; + result:= fstream.readmsedatastring; + end; +end; + +{ +procedure tstatreader.readstatfile(const name: msestring; const statfile: tstatfile); +var + stream: ttextstream; + ar1: msestringarty; +begin + ar1:= readarray(name,msestringarty(nil)); + stream:= ttextstream.Create; + try + stream.writemsestrings(ar1); + stream.Position:= 0; + statfile.readstat(stream); + finally + stream.Free; + end; +end; +} +{ tstatwriter } + +constructor tstatwriter.create(const astream: ttextstream; + const aencoding: charencodingty = ce_utf8); +begin + fiswriter:= true; + inherited; +end; + +constructor tstatwriter.create(const filename: filenamety; + const aencoding: charencodingty = ce_utf8; + const atransaction: boolean = true); +var + stream1: ttextstream; +begin + fownsstream:= true; + if atransaction then begin + stream1:= ttextstream.Createtransaction(filename); + end + else begin + stream1:= ttextstream.Create(filename,fm_create); + end; + create(stream1,aencoding); +end; + +procedure tstatwriter.writesection(const name: msestring); +begin + fcurrentsection:= name; + fstream.writeln(msestring('[')+name+msestring(']')); + flistlevel:= 0; +end; + +procedure tstatwriter.writestat(const intf: istatfile); +begin + if (intf <> nil) and (fstream <> nil) then begin + writesection(varname(intf)); + intf.dostatwrite(self); + end; +end; + +procedure tstatwriter.writevalue(const name: msestring; const intf: istatupdatevalue); +begin + if intf <> nil then begin + intf.statwritevalue(name,self); + end; +end; + +procedure tstatwriter.writeval(const name: msestring; const avalue: msestring); +begin + fstream.writeln(charstring(msechar(' '),flistlevel)+name+'='+avalue); +end; + +procedure tstatwriter.writemultival(const name: msestring; const avalue: msestring); +var + ar1: msestringarty; + int1: integer; +begin + if avalue = '' then begin + fstream.writeln(charstring(msechar(' '),flistlevel)+name+'='); + end + else begin + ar1:= breaklines(avalue); + fstream.writeln(charstring(msechar(' '),flistlevel)+name+'='+ar1[0]); + for int1:= 1 to high(ar1) do begin + fstream.writeln(charstring(msechar(' '),flistlevel)+'+'+ar1[int1]); + end; + end; +end; + +procedure tstatwriter.writeinteger(const name: msestring; const value: integer); +begin + writeval(name,inttostrmse(value)); +end; + +procedure tstatwriter.writeint64(const name: msestring; const value: int64); +begin + writeval(name,inttostrmse(value)); +end; + +procedure tstatwriter.writeboolean(const name: msestring; const value: boolean); +begin + writeinteger(name,integer(value)); +end; + +procedure tstatwriter.writebyte(const name: msestring; const value: byte); +begin + writeinteger(name,value); +end; + +procedure tstatwriter.writeword(const name: msestring; const value: word); +begin + writeinteger(name,value); +end; + +procedure tstatwriter.writereal(const name: msestring; const value: real); +begin + writeval(name,msestring(realtytostrdot(value))); +end; + +procedure tstatwriter.writestring(const name: msestring; const value: string); +begin + writeval(name,msestring(value)); +end; + +procedure tstatwriter.writebinarystring(const name: msestring; + const value: string); +begin + writemsestring(name,msestring(encodebase64(value,76))); +end; + +procedure tstatwriter.writemsestring(const name: msestring; + const value: msestring); +begin + writemultival(name,value); +end; +(* +procedure tstatwriter.writemsestrings(const name: msestring; + const value: msestring); +var + ar1: msestringarty; +begin + writemsestring(name,value); +{ + ar1:= breaklines(value); + if high(ar1) > 0 then begin + writearray(name+'ar',ar1); + end + else begin + writeval(name,value); + end; +} +end; +*) +procedure tstatwriter.writerecord(const name: msestring; + const values: array of const); +begin + writemsestring(name,encoderecord(values)); +end; + +procedure tstatwriter.writerecordarray(const name: msestring; const count: integer; + get: recgetrecordeventty); +var + int1: integer; +begin + writeinteger(name,count); + for int1:= 0 to count - 1 do begin + writelistval(get(int1)); + end; +end; + +procedure tstatwriter.writerecordarray(const name: msestring; const count: integer; + get: recgetrecordevent1ty); +var + int1: integer; +begin + writeinteger(name,count); + for int1:= 0 to count - 1 do begin + writelistval(get(int1)); + end; +end; + +procedure tstatwriter.writemultilistval(const avalue: msestring); +var + ar1: msestringarty; + int1: integer; +begin + ar1:= breaklines(avalue); + if ar1 <> nil then begin + fstream.writeln(charstring(msechar(' '),flistlevel+1)+ar1[0]); + for int1:= 1 to high(ar1) do begin + fstream.writeln(charstring(msechar(' '),flistlevel)+'+'+ar1[int1]); + end; + end; +end; + +procedure tstatwriter.writelistval(const avalue: msestring); +var + po1: pmsechar; +begin + po1:= pointer(avalue); + if po1 <> nil then begin + while (po1^ <> c_linefeed) and (po1^ <> #0) do begin + inc(po1); + end; + if po1^ <> #0 then begin + writemultilistval(avalue); + exit; + end; + end; + fstream.writeln(charstring(msechar(' '),flistlevel+1)+avalue) +end; + +procedure tstatwriter.writelistitem(const value: msestring); +begin + writelistval(value); +end; + +procedure tstatwriter.writelistitem(const value: integer); +begin + writelistval(inttostrmse(value)); +end; + +procedure tstatwriter.writelistitem(const value: realty); +begin + writelistval(msestring(realtytostrdot(value))); +end; + +procedure tstatwriter.writelistitem(const value: complexty); +begin + writelistval(encoderecord([value.re,value.im])); +end; + +procedure tstatwriter.writedatalist(const name: msestring; const value: tdatalist); +begin + tdatalist1(value).writestate(self,name); + tdatalist1(value).writeappendix(self,name); +end; + +procedure tstatwriter.writearray(const name: msestring; const value: msestringarty); +var + int1: integer; +begin + writeinteger(name,length(value)); + for int1:= 0 to high(value) do begin + writelistitem(value[int1]); + end; +end; + +procedure tstatwriter.writearray(const name: msestring; const value: stringarty); +var + int1: integer; +begin + writeinteger(name,length(value)); + for int1:= 0 to high(value) do begin + writelistitem(msestring(value[int1])); + end; +end; + +procedure tstatwriter.writearray(const name: msestring; const value: integerarty); +var + int1: integer; +begin + writeinteger(name,length(value)); + for int1:= 0 to high(value) do begin + writelistitem(value[int1]); + end; +end; + +procedure tstatwriter.writearray(const name: msestring; const value: int64arty); +var + int1: integer; +begin + writeinteger(name,length(value)); + for int1:= 0 to high(value) do begin + writelistitem(value[int1]); + end; +end; + +procedure tstatwriter.writearray(const name: msestring; const value: longboolarty); +var + int1: integer; +begin + writeinteger(name,length(value)); + for int1:= 0 to high(value) do begin + writelistitem(integer(value[int1])); + end; +end; + +procedure tstatwriter.writearray(const name: msestring; const value: booleanarty); +var + int1: integer; +begin + writeinteger(name,length(value)); + for int1:= 0 to high(value) do begin + writelistitem(integer(value[int1])); + end; +end; + +procedure tstatwriter.writearray(const name: msestring; const value: realarty); +var + int1: integer; +begin + writeinteger(name,length(value)); + for int1:= 0 to high(value) do begin + writelistitem(value[int1]); + end; +end; + +procedure tstatwriter.writearray(const name: msestring; const value: complexarty); +var + int1: integer; +begin + writeinteger(name,length(value)); + for int1:= 0 to high(value) do begin + writelistitem(value[int1]); + end; +end; + +function tstatwriter.beginlist(const name: msestring = ''): boolean; +begin + result:= true; + if name <> '' then begin + writestring(name,''); + end; + inc(flistlevel); + fstream.writeln(charstring(msechar(' '),flistlevel)+'('); +end; + +function tstatwriter.endlist: boolean; +begin + if flistlevel > 0 then begin + result:= true; + fstream.writeln(charstring(msechar(' '),flistlevel)+')'); + dec(flistlevel); + end + else begin + result:= false; + end; +end; + +procedure tstatwriter.writememorystatstream(const name,streamname: msestring); +var + stream1: ttextstream; + ar1: msestringarty; +begin + ar1:= nil; //compiler warning + stream1:= memorystatstreams.open(streamname,fm_read); + try + stream1.encoding:= fstream.encoding; + if stream1.Size > 0 then begin + ar1:= stream1.readmsestrings; + writearray(name,ar1); + end; + finally + stream1.Free; + end; +end; + +procedure tstatwriter.streamdata(const adata: string); +begin + writesection(''); + fstream.write(adata); +end; + +procedure tstatwriter.streamtext(const atext: msestring); +begin + writesection(''); + fstream.write(atext); +end; + +{ +procedure tstatwriter.writestatfile(const name: msestring; const statfile: tstatfile); +var + stream: ttextstream; + ar1: msestringarty; +begin + stream:= ttextstream.Create; + try + statfile.writestat(stream); + stream.position:= 0; + ar1:= stream.readmsestrings; + writearray(name,ar1); + finally + stream.Free; + end; +end; +} +{ tmemorytextstream } + +constructor tmemorytextstream.create(aowner: tmemorystreams; const name: msestring; + const aopenmode: fileopenmodety; var info: streaminfoty); +begin + fowner:= aowner; + fname:= name; + info.name:= name; + info.stream:= self; + inherited create; + if info.size > 0 then begin + if aopenmode <> fm_create then begin + {$ifdef mswindows} + {$ifndef FPC} + fmemorystream.SetSize(info.size); + move(info.data^,fmemorystream.memory^,info.size); + //on delphi memory is not on normal heap + freemem(info.data); + {$else} +{$warnings off} + tmemorystreamcracker(fmemorystream).setpointer(info.data,info.size); +{$warnings on} +{$warnings off} + tmemorystreamcracker(fmemorystream).fcapacity:= info.size; +{$warnings on} + {$endif} + {$else} +{$warnings off} + tmemorystreamcracker(fmemorystream).setpointer(info.data,info.size); +{$warnings on} +{$warnings off} + tmemorystreamcracker(fmemorystream).fcapacity:= info.size; +{$warnings on} + {$endif} + end + else begin + freemem(info.data); + end; + end; + info.data:= nil; + info.size:= 0; +end; + +destructor tmemorytextstream.destroy; +var + int1: integer; +begin + flushbuffer; + int1:= fowner.findname(fname); + if int1 >= 0 then begin + with fowner.fstreams[int1] do begin + size:= self.Size; +{$ifdef mswindows} + {$ifndef FPC} + getmem(data,size); + move(fmemorystream.memory^,data^,size); + //on delphi memory is not on normal heap + {$else} + data:= fmemorystream.memory; +{$warnings off} + tmemorystreamcracker(fmemorystream).setpointer(nil,0); +{$warnings on} + reallocmem(data,size); + {$endif} +{$else} + data:= fmemorystream.memory; +{$warnings off} + tmemorystreamcracker(fmemorystream).setpointer(nil,0); +{$warnings on} + reallocmem(data,size); +{$endif} + stream:= nil; + end; + end; + inherited; +end; + +{ tmemorystreams } + +procedure tmemorystreams.internaldelete(index: integer); +begin + if index >= 0 then begin + with fstreams[index] do begin + freeandnil(stream); + if data <> nil then begin + freemem(data); + data:= nil; + end; + size:= 0; + name:= ''; + end; + end; +end; + +procedure tmemorystreams.delete(const name: msestring); +begin + internaldelete(findname(name)); +end; + +destructor tmemorystreams.destroy; +var + int1: integer; +begin + for int1:= 0 to high(fstreams) do begin + internaldelete(int1); + end; + inherited; +end; + +function tmemorystreams.findname(const name: msestring): integer; +var + int1: integer; +begin + result:= -1; + for int1:= 0 to high(fstreams) do begin + if fstreams[int1].name = name then begin + result:= int1; + break; + end; + end; +end; + +function tmemorystreams.open(const streamname: msestring; + const aopenmode: fileopenmodety): ttextstream; +var + int1: integer; +begin + if streamname = '' then begin + raise exception.Create('Invalid memory stream name.'); + end; + int1:= findname(streamname); + if (int1 >= 0) and (fstreams[int1].stream <> nil) then begin + raise exception.Create(ansistring('Memorystream '''+ + streamname+''' allready open.')); + end; + if int1 < 0 then begin + int1:= findname(''); + if int1 < 0 then begin + int1:= length(fstreams); + setlength(fstreams,int1+1); + end; + end; + result:= tmemorytextstream.create(self,streamname,aopenmode,fstreams[int1]); +end; + +function tmemorystreams.findfiles(const aname: msestring): msestringarty; +var + ar1: msestringarty; + int1,int2: integer; +begin + ar1:= nil; + int2:= 0; + splitstringquoted(aname,ar1); + setlength(result,length(fstreams)); //max + for int1:= 0 to high(result) do begin + if checkfilename(fstreams[int1].name,ar1) then begin + result[int2]:= fstreams[int1].name; + inc(int2); + end; + end; + setlength(result,int2); +end; + +initialization +finalization + fmemorystatstreams.free; +end. diff --git a/mseide-msegui/lib/common/kernel/msestatfile.pas b/mseide-msegui/lib/common/kernel/msestatfile.pas new file mode 100644 index 0000000..33aca68 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msestatfile.pas @@ -0,0 +1,843 @@ +{ MSEgui Copyright (c) 1999-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msestatfile; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,msestat,mseapplication,msetypes,msestrings,mseclasses,msestream, + mseglob,msearrayprops; + +type + statupdateeventty = procedure(const sender: tobject; + const filer: tstatfiler) of object; + statreadeventty = procedure(const sender: tobject; + const reader: tstatreader) of object; + statwriteeventty = procedure(const sender: tobject; + const writer: tstatwriter) of object; + + statfileoptionty = (sfo_memory,sfo_deletememorydata, //delete after read + sfo_createpath, + sfo_transaction, //use intermedate file and rename + sfo_savedata,sfo_autoreadstat,sfo_autowritestat, + sfo_activatorread,sfo_activatorwrite, + sfo_nodata,sfo_nostate,sfo_nooptions); + statfileoptionsty = set of statfileoptionty; +const + defaultstatfileoptions = [sfo_activatorread,sfo_activatorwrite,sfo_transaction]; + +type + tstatfile = class; + statfilemissingeventty = procedure (const sender: tstatfile; + const afilename: filenamety; + var astream: ttextstream; var aretry: boolean) of object; + statfilemodety = (sfm_inactive,sfm_reading,sfm_writing); + + statclientinfoty = record + intf: istatfile; + priority: integer; + end; + pstatclientinfoty = ^statclientinfoty; + statclientarty = array of statclientinfoty; + + statfilestatety = (stfs_reading); + statfilestatesty = set of statfilestatety; + + tstatfile = class(tactcomponent,istatfile) + private + ffilename: filenamety; + ffiledir: filenamety; + floadedfile: filenamety; + + fstatvarname: msestring; + fonstatupdate: statupdateeventty; + fonstatread: statreadeventty; + fonstatwrite: statwriteeventty; + fonstatbeforeread: notifyeventty; + fonstatafterread: notifyeventty; + fonstatbeforewrite: notifyeventty; + fonstatafterwrite: notifyeventty; + areader: tstatreader; + awriter: tstatwriter; + aclients: statclientarty; + aclientcount: integer; + foptions: statfileoptionsty; + fencoding: charencodingty; + fstatfile: tstatfile; + fsavedmemoryfiles: msestring; + fonfilemissing: statfilemissingeventty; + fcryptohandler: tcustomcryptohandler; + fnext: tstatfile; + fstatpriority: integer; + procedure dolinkstatread(const info: linkinfoty); + procedure dolinkstatreading(const info: linkinfoty); + procedure dolinkstatreaded(const info: linkinfoty); + procedure dolinkstatwrite(const info: linkinfoty); + procedure setstatfile(const Value: tstatfile); + procedure setfilename(const avalue: filenamety); + procedure setfiledir(const avalue: filenamety); +// procedure setoptions(avalue: statfileoptionsty); + procedure setcryptohandler(const avalue: tcustomcryptohandler); + function getmode: statfilemodety; + procedure setnext(const avalue: tstatfile); + procedure internalreadstat; + procedure internalwritestat; + protected + fstate: statfilestatesty; + procedure objevent(const sender: iobjectlink; + const event: objecteventty); override; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + procedure updateoptions(const afiler: tstatfiler); + function defaultfile(const adirs: filenamearty): filenamety; + + //istatfile + procedure dostatread(const reader: tstatreader); + procedure dostatwrite(const writer: tstatwriter); + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + public + constructor create(aowner: tcomponent); override; + procedure initnewcomponent(const ascale: real); override; + procedure readstat(const stream: ttextstream = nil); overload; + procedure readstat(const afilename: filenamety); overload; //disk file + procedure readstat(const aname: msestring; + const statreader: tstatreader); overload; + procedure writestat(const stream: ttextstream = nil); overload; + procedure writestat(const afilename: filenamety); overload; //disk file + procedure writestat(const aname: msestring; + const statwriter: tstatwriter); overload; + procedure updatestat(const aname: msestring; const statfiler: tstatfiler); + property mode: statfilemodety read getmode; + published + property filename: filenamety read ffilename write setfilename nodefault; + property filedir: filenamety read ffiledir write setfiledir; + property encoding: charencodingty read fencoding write fencoding + default ce_utf8; + property options: statfileoptionsty read foptions write foptions + default defaultstatfileoptions; + property statfile: tstatfile read fstatfile write setstatfile; + //filename is stored in linked statfile, dostatread and dostatwrite are + //called by linked statfile + property savedmemoryfiles: msestring read fsavedmemoryfiles write + fsavedmemoryfiles; + //use quotes for several filenames '"file1.sta" "file2.sta*"', + //'*' and '?' wildcards supported. + property statvarname: msestring read getstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + property cryptohandler: tcustomcryptohandler read fcryptohandler + write setcryptohandler; + property activator; + property next: tstatfile read fnext write setnext; + property onstatupdate: statupdateeventty read fonstatupdate write fonstatupdate; + property onstatread: statreadeventty read fonstatread write fonstatread; + property onstatwrite: statwriteeventty read fonstatwrite write fonstatwrite; + property onstatbeforewrite: notifyeventty read fonstatbeforewrite + write fonstatbeforewrite; + property onstatafterwrite: notifyeventty read fonstatafterwrite + write fonstatafterwrite; + property onstatbeforeread: notifyeventty read fonstatbeforeread + write fonstatbeforeread; + property onstatafterread: notifyeventty read fonstatafterread + write fonstatafterread; + property onfilemissing: statfilemissingeventty read fonfilemissing + write fonfilemissing; + end; + + tstatfileitem = class(tmsecomponentlinkitem) + private + function getstatfile: tstatfile; + procedure setstatfile(const avalue: tstatfile); + published + property statfile: tstatfile read getstatfile write setstatfile; + end; + + tstatfilearrayprop = class(tmsecomponentlinkarrayprop) + private + function getitems(const index: integer): tstatfileitem; + public + constructor create; + class function getitemclasstype: persistentclassty; override; + property items[const index: integer]: tstatfileitem read getitems; default; + end; + +procedure setstatfilevar(const sender: istatfile; const source: tstatfile; + var instance: tstatfile); +implementation +uses + msesystypes,msesys,msefileutils,sysutils,msearrayutils; + +procedure setstatfilevar(const sender: istatfile; const source: tstatfile; + var instance: tstatfile); +var + int1: integer; +begin + if source <> instance then begin + if (instance <> nil) and (stfs_reading in instance.fstate) then begin + for int1:= 0 to high(instance.aclients) do begin + with instance.aclients[int1] do begin + if intf = sender then begin + intf:= nil; + end; + end; + end; + end; + if (source <> nil) and (stfs_reading in source.fstate) then begin + setlength(source.aclients,high(source.aclients)+2); + source.aclients[high(source.aclients)].intf:= sender; + end; + end; + setlinkedcomponent(sender,source,tmsecomponent(instance),typeinfo(istatfile)); +end; + +{ tstatfile } + +constructor tstatfile.create(aowner: tcomponent); +begin +// ffilename:= defaultstatfilename; + fencoding:= ce_utf8; + foptions:= defaultstatfileoptions; + inherited; +end; + +procedure tstatfile.initnewcomponent(const ascale: real); +begin + ffilename:= defaultstatfilename; +end; + +procedure tstatfile.dostatread(const reader: tstatreader); +var + ar1,ar2: stringarty; + ar3: msestringarty; + stream1: ttextstream; + int1: integer; + reader1: tstatreader; +begin + ar1:= nil; //compiler warning + ar2:= nil; //compiler warning + if reader <> areader then begin + if not (sfo_memory in foptions) then begin + if sfo_savedata in foptions then begin + reader1:= areader; + areader:= reader; + try + internalreadstat; + finally; + areader:= reader1; + end; + end + else begin + filename:= reader.readmsestring('filename',ffilename); + end; + end + else begin + if sfo_savedata in foptions then begin + stream1:= memorystatstreams.open(ffilename,fm_read); + try + ar2:= stream1.readstrings; + finally + stream1.free; + end; + ar1:= reader.readarray('data',ar2); + stream1:= memorystatstreams.open(ffilename,fm_create); + try + stream1.writestrings(ar1); + finally + stream1.free; + end; + if sfo_autoreadstat in foptions then begin + readstat; + end; + end; + end; +// statread; + end + else begin + if fsavedmemoryfiles <> '' then begin + ar3:= reader.readarray('savedmemoryfiles',msestringarty(nil)); + for int1:= 0 to high(ar3) do begin + reader.readmemorystatstream(ar3[int1],ar3[int1]); + end; + end; + if assigned(fonstatupdate) then begin + fonstatupdate(self,reader); + end; + if assigned(fonstatread) then begin + fonstatread(self,reader); + end; + end; +end; + +procedure tstatfile.dostatwrite(const writer: tstatwriter); +var + ar1: stringarty; + ar3: msestringarty; + stream1: ttextstream; + int1: integer; + writer1: tstatwriter; +begin + ar1:= nil; //compiler warning + if (writer <> awriter) then begin + if not (sfo_memory in foptions) then begin + if sfo_savedata in foptions then begin + writer1:= awriter; + awriter:= writer; + try + internalwritestat; + finally; + awriter:= writer1; + end; + end + else begin + writer.writemsestring('filename',ffilename); + end; + end + else begin + if sfo_savedata in foptions then begin + if sfo_autowritestat in foptions then begin + writestat; + end; + stream1:= memorystatstreams.open(ffilename,fm_read); + try + ar1:= stream1.readstrings; + finally + stream1.free; + end; + writer.writearray('data',ar1); + end; + end; +// if ffilename <> '' then begin +// writestat; +// end; + end + else begin + if fsavedmemoryfiles <> '' then begin + ar3:= memorystatstreams.findfiles(fsavedmemoryfiles); + writer.writearray('savedmemoryfiles',ar3); + for int1:= 0 to high(ar3) do begin + writer.writememorystatstream(ar3[int1],ar3[int1]); + end; + end; + if assigned(fonstatupdate) then begin + fonstatupdate(self,writer); + end; + if assigned(fonstatwrite) then begin + fonstatwrite(self,writer); + end; + end; +end; + +function tstatfile.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +procedure tstatfile.dolinkstatread(const info: linkinfoty); +begin + areader.readstat(istatfile(info.dest)); +end; + +procedure tstatfile.dolinkstatreading(const info: linkinfoty); +begin + with pstatclientinfoty(additempo(aclients,typeinfo(statclientarty), + aclientcount))^ do begin + intf:= istatfile(info.dest); + priority:= intf.getstatpriority; + end; + istatfile(info.dest).statreading; +end; + +procedure tstatfile.objevent(const sender: iobjectlink; + const event: objecteventty); +var + int1: integer; +begin + if event = oe_destroyed then begin + for int1:= 0 to high(aclients) do begin + if aclients[int1].intf = sender then begin + aclients[int1].intf:= nil; + end; + end; + end; + inherited; +end; + +procedure tstatfile.dolinkstatreaded(const info: linkinfoty); +begin + istatfile(info.dest).statread; +end; + +procedure tstatfile.updateoptions(const afiler: tstatfiler); +var + opt1: statfileroptionsty; +begin + opt1:= afiler.options; + if sfo_nodata in foptions then begin + include(opt1,sfro_nodata); + end; + if sfo_nostate in foptions then begin + include(opt1,sfro_nostate); + end; + if sfo_nooptions in foptions then begin + include(opt1,sfro_nooptions); + end; + afiler.options:= opt1; +end; + +function tstatfile.defaultfile(const adirs: filenamearty): filenamety; +begin + if high(adirs) >= 0 then begin + result:= filepath(adirs[0],ffilename); + end + else begin + result:= filepath(ffilename); + end; +end; + +function cmpclients(const l,r): integer; +begin + result:= statclientinfoty(r).priority - statclientinfoty(l).priority; + //highest priority first +end; + +procedure tstatfile.internalreadstat; +var + int1: integer; +begin + if assigned(fonstatread) or assigned(fonstatupdate) or + (fsavedmemoryfiles <> '') then begin + areader.readstat(istatfile(self)); + end; + if fobjectlinker <> nil then begin + aclients:= nil; + aclientcount:= 0; + fobjectlinker.forall({$ifdef FPC}@{$endif}dolinkstatreading, + typeinfo(istatfile)); + setlength(aclients,aclientcount); + sortarray(aclients,sizeof(statclientinfoty),@cmpclients); + include(fstate,stfs_reading); + try + int1:= 0; + while int1 <= high(aclients) do begin + with aclients[int1] do begin + if intf <> nil then begin + areader.readstat(intf); + end; + end; + inc(int1); + end; +// fobjectlinker.forall({$ifdef FPC}@{$endif}dolinkstatread, +// typeinfo(istatfile)); + finally + exclude(fstate,stfs_reading); + aclients:= nil; + fobjectlinker.forall({$ifdef FPC}@{$endif}dolinkstatreaded, + typeinfo(istatfile)); + end; +// if assigned(fonstatafterread) then begin +// fonstatafterread(self); +// end; + end; +end; + +procedure tstatfile.readstat(const stream: ttextstream = nil); +var + stream1: ttextstream; + ar1: filenamearty; + by1: boolean; +begin + if stfs_reading in fstate then begin + exit; + end; + if assigned(fonstatbeforeread) then begin + fonstatbeforeread(self); + end; + stream1:= stream; + try + if (stream1 = nil) and (filename <> '') then begin + if sfo_memory in foptions then begin + floadedfile:= ''; + stream1:= memorystatstreams.open(ffilename,fm_read); + end + else begin + by1:= false; + repeat + unquotefilename(ffiledir,ar1); + if not findfile(ffilename,ar1,floadedfile) then begin + floadedfile:= ffilename; + end; + if ttextstream.trycreate(stream1,floadedfile,fm_read) <> sye_ok then begin + floadedfile:= defaultfile(ar1); + if assigned(fonfilemissing) then begin + fonfilemissing(self,floadedfile,stream1,by1); + if stream1 <> nil then begin + floadedfile:= ''; + end; + end; + end; + until (stream1 <> nil) or not by1; + if stream1 = nil then begin + floadedfile:= ''; + end; + end; + end; + if (fcryptohandler <> nil) and (stream1 <> nil) then begin + stream1.cryptohandler:= fcryptohandler; + end; + areader:= tstatreader.create(stream1,fencoding); + updateoptions(areader); + try + internalreadstat; + finally + freeandnil(areader); +// areader.free; + end; + finally + if stream = nil then begin + stream1.Free; + if (stream1 <> nil) and (foptions * [sfo_memory,sfo_deletememorydata] = + [sfo_memory,sfo_deletememorydata]) then begin + memorystatstreams.delete(ffilename); + end; + end + else begin + if (fcryptohandler <> nil) and (stream1 <> nil) then begin + stream1.cryptohandler:= nil; + end; + end; + end; + if fnext <> nil then begin + fnext.readstat(nil); + end; + if assigned(fonstatafterread) then begin + fonstatafterread(self); + end; +end; + +procedure tstatfile.readstat(const afilename: filenamety); +var + stream1: ttextstream; +begin + stream1:= ttextstream.create(afilename,fm_read); + try + stream1.encoding:= fencoding; + readstat(stream1); + finally + stream1.free; + end; +end; + +procedure tstatfile.writestat(const afilename: filenamety); +var + stream1: ttextstream; + fname1: filenamety; +begin + fname1:= afilename; + if sfo_transaction in foptions then begin + stream1:= ttextstream.createtransaction(fname1); + end + else begin + stream1:= ttextstream.create(fname1,fm_create); + end; + try + stream1.encoding:= fencoding; + writestat(stream1); + finally + stream1.free; + end; +end; + +procedure tstatfile.statreading; +begin + //dummy +end; + +procedure tstatfile.statread; +begin + //dummy +end; + +procedure tstatfile.dolinkstatwrite(const info: linkinfoty); +begin + awriter.writestat(istatfile(info.dest)); +end; + +procedure tstatfile.internalwritestat; +begin + if assigned(fonstatwrite) or assigned(fonstatupdate) or + (fsavedmemoryfiles <> '') then begin + awriter.writestat(istatfile(self)); + end; + if fobjectlinker <> nil then begin + fobjectlinker.forall({$ifdef FPC}@{$endif}dolinkstatwrite,typeinfo(istatfile)); + end; +end; + +procedure tstatfile.writestat(const stream: ttextstream = nil); +var + stream1: ttextstream; + ar1: filenamearty; +// fname1: filenamety; + bo1: boolean; +begin + if assigned(fonstatbeforewrite) then begin + fonstatbeforewrite(self); + end; + if fnext <> nil then begin + fnext.writestat(nil); + end; + stream1:= stream; + if (stream1 = nil) and (filename <> '') then begin + if sfo_memory in foptions then begin + stream1:= memorystatstreams.open(ffilename,fm_create); + end + else begin + if floadedfile = '' then begin + unquotefilename(ffiledir,ar1); + if not findfile(ffilename,ar1,floadedfile) then begin + floadedfile:= defaultfile(ar1); + end; + if (sfo_createpath in foptions) and not findfile(floadedfile) then begin + createdirpath(msefileutils.filedir(floadedfile)); + end; + end; + try + if sfo_transaction in foptions then begin + stream1:= ttextstream.createtransaction(floadedfile); + end + else begin + stream1:= ttextstream.Create(floadedfile,fm_create); + end; + except + floadedfile:= ''; + raise; + end; + end; +// stream1.encoding:= fencoding; + end; + if stream1 = nil then begin + exit; + end; + try + if (fcryptohandler <> nil) then begin + stream1.cryptohandler:= fcryptohandler; + end; + awriter:= tstatwriter.create(stream1,fencoding); + updateoptions(awriter); + bo1:= false; + try + if (stream1.handle <> invalidfilehandle) and + not stream1.usewritebuffer then begin + bo1:= true; + stream1.usewritebuffer:= true; + end; + internalwritestat; +// if assigned(fonstatafterwrite) then begin +// fonstatafterwrite(self); +// end; + finally + freeandnil(awriter); + if bo1 then begin + stream1.usewritebuffer:= false; + end; + end; + finally + if stream = nil then begin + stream1.Free; + end + else begin + if (fcryptohandler <> nil) then begin + stream1.cryptohandler:= nil; + end; + end; + end; + if assigned(fonstatafterwrite) then begin + fonstatafterwrite(self); + end; +end; + +procedure tstatfile.setstatfile(const Value: tstatfile); +var + sf: tstatfile; +begin + if fstatfile <> value then begin + if value <> nil then begin + sf:= value; + while sf <> nil do begin + if sf = self then begin + raise exception.Create(name+': Recursive statfile'); + end; + sf:= sf.fstatfile; + end; + end; + setstatfilevar(istatfile(self),value,fstatfile); + end; +end; + +procedure tstatfile.setfilename(const avalue: filenamety); +begin + floadedfile:= ''; + ffilename:= avalue; +end; + +procedure tstatfile.setfiledir(const avalue: filenamety); +begin + floadedfile:= ''; + ffiledir:= avalue; +end; +{ +procedure tstatfile.setoptions(avalue: statfileoptionsty); +begin + if not (sfo_memory in avalue) then begin + exclude(avalue,sfo_savedata); + end; + foptions:= avalue; +end; +} +procedure tstatfile.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (sender = activator) and not (csdesigning in componentstate) then begin + case event of + oe_activate: begin + if sfo_activatorwrite in foptions then begin + readstat; + end; + end; + oe_deactivate: begin + if sfo_activatorwrite in foptions then begin + writestat; + end; + end; + end; + end; +end; + +procedure tstatfile.readstat(const aname: msestring; + const statreader: tstatreader); +var + stream: ttextstream; + ar1: msestringarty; +begin + ar1:= statreader.readarray(aname,msestringarty(nil)); + stream:= ttextstream.Create; + stream.encoding:= fencoding; + try + stream.writemsestrings(ar1); + stream.Position:= 0; + readstat(stream); + finally + stream.Free; + end; +end; + +procedure tstatfile.writestat(const aname: msestring; + const statwriter: tstatwriter); +var + stream: ttextstream; + ar1: msestringarty; +begin + stream:= ttextstream.Create; + stream.encoding:= ce_utf8; + try + writestat(stream); + stream.position:= 0; + ar1:= stream.readmsestrings; + statwriter.writearray(aname,ar1); + finally + stream.Free; + end; +end; + +procedure tstatfile.updatestat(const aname: msestring; + const statfiler: tstatfiler); +begin + if statfiler.iswriter then begin + writestat(aname,tstatwriter(statfiler)); + end + else begin + readstat(aname,tstatreader(statfiler)); + end; +end; + +procedure tstatfile.setcryptohandler(const avalue: tcustomcryptohandler); +begin + setlinkedvar(avalue,tmsecomponent(fcryptohandler)); +end; + +function tstatfile.getmode: statfilemodety; +begin + result:= sfm_inactive; + if areader <> nil then begin + result:= sfm_reading; + end + else begin + if awriter <> nil then begin + result:= sfm_writing; + end; + end; +end; + +procedure tstatfile.setnext(const avalue: tstatfile); +var + sf: tstatfile; +begin + if fnext <> avalue then begin + if avalue <> nil then begin + sf:= avalue; + while sf <> nil do begin + if sf = self then begin + raise exception.Create(name+': Recursive next statfile'); + end; + sf:= sf.fnext; + end; + end; + setlinkedvar(avalue,tmsecomponent(fnext)); + end; +end; + +function tstatfile.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +{ tstatfileitem } + +function tstatfileitem.getstatfile: tstatfile; +begin + result:= tstatfile(item); +end; + +procedure tstatfileitem.setstatfile(const avalue: tstatfile); +begin + item:= avalue; +end; + +{ tstatfilearrayprop } + +constructor tstatfilearrayprop.create; +begin + inherited create(tstatfileitem); +end; + +function tstatfilearrayprop.getitems(const index: integer): tstatfileitem; +begin + result:= tstatfileitem(inherited getitems(index)); +end; + +class function tstatfilearrayprop.getitemclasstype: persistentclassty; +begin + result:= tstatfileitem; +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/msestockobjects.mfm b/mseide-msegui/lib/common/kernel/msestockobjects.mfm new file mode 100644 index 0000000..fb627bd --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msestockobjects.mfm @@ -0,0 +1,285 @@ +object stockdata: tstockdata + bounds_cx = 188 + bounds_cy = 85 + left = 129 + top = 57 + moduleclassname = 'tmsedatamodule' + object glyphs: timagelist + width = 15 + height = 15 + options = [bmo_monochrome, bmo_masked] + count = 84 + left = 32 + top = 40 + image = { + 00000000030000009600000096000000B80B0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000800000000002000000000000000000FF81FFC07F8001000000 + 0300000000001803000001818040408003000180030000000000B80370000181 + 80404480078003C003FE0F000000F001F8000181804044800FC007E003FC0700 + 0000E000F8000181BE405F801FE00FF003F803000000F001F800018180404480 + 0FF01FE003F001000000B803700001818040448007F83FC003E0000000001803 + 00000181804040800300008003400000000000000000FF81FFC07F8001000000 + 0300000000000000000000000000008000000000020000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000002000000020000080080011000004 + 08000200000060002000300000800C00130000040E8003008808E00070003800 + 7F800E00170000840FE00300DC1DE001F8003C003E800F001F601BE40FF80300 + 8808E000FC0138001C800E0017601B840FE00300000060000000300008800C00 + 130000040E800300000020000000200000800800110000040800020000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000080000000000000000000000000000 + 00000000001C000000000000700000000000C06030C011000038000010000408 + 700000000000E0E038F017000070000070001C08700000000C0070C01D301EFC + 1FE00000F0017C08FE83FF011E0038800F181CFC1FC00100F007FC09FE83FF01 + 3F601C0007181F0000C00000F0017C08FE83FF817FE00E800F18000000600600 + 70001C08700000C0FFC007C01D1000FC1F3003001000040870000000008003E0 + 383000FC1F9801000000000070000000000001603060000000CC000000000000 + 0000000000000000008000000060000000000000000000000000000000000000 + 0030000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000004000000000000000000000000000000000000 + 000EFF1F780038000280190000000000000000000007060CFC00280006000600 + 000000000000000080030C06860128000E0006000000000000F80300C0011803 + 030328001E0006800400000000400000E000B001030328003E000600030001C0 + 00E00000C000A000030328007E0006C00F8003C000F001009801A00003036C00 + 3E0006000300010000F803003003A0008601C6001E0006800400000000000000 + 6006A000FC0383010E0006000000000000000000C00CA0007887010306000600 + 00000000000000008001E00000CEFF0702801900000000000000000000030000 + 0004000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000FE0FFF87FFC3 + FF01000000000000000000000000FF9FFFCFFFE7FF0300000000000000000000 + 0000039801CC0066000300000000000000000000000003988DCDC06600030000 + 07C0070000F8030000000398DDCDE0661C030E800D600CE003080200F0070398 + F9CC70663E0311C01820082002080200E003039871CC38663E03114010200820 + 02080200C0010398F9CC1C663E0311C0182008200208020080000398DDCD0E66 + 1C030E800D600CE003080200F00703988DCD06660003000007C0070000F80300 + 0000039801CC00660003000000000000000000000000FF9FFFCFFFE7FF030000 + 00000000000000000000FE0FFF87FFC3FF010000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000F80F000000001000000000000200000000040400 + 08080000200038000000040002000010040802000808400070006C0008000400 + 02400420021001000808A000D800C600080004000280024001A0000008081001 + 8C0183013E803FE03F000180004000000808A000D800C6000800040002800240 + 01A000000808400070006C000800040002400420021001000808000020003800 + 000004000200001004080200F80F000000001000000000000200000000040400 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000020000000000000000103021000180300 + 800040007000000000E0FFC0C10F0E70001803004001A000D800FE80FFC060F0 + F13F3EF001180300200210018C014400418031FCFDFFFEF007180300F0070802 + 0603280022001BF0F13F3EF0011803000000FC07FF07100014000EC0C10F0E70 + 0018030000000000000000000800040001030210001803000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000C000000000000000000000000000000000000000C + 004000E0E38363E0FF0000000000000000000006608060E0C1C33150900000E4 + 1FE60F0000040006500451E0E3E3104994FC7F0000E60F000154000358095AE0 + F7F3B1499404400000000000075280034F0A4FA0E3BAFB4890045CE41F000000 + 1F52E001410A490041101FC89FF44B0000E60F007F52D801410A510000000E08 + 80F44B0000E60F001F51F601410A610041001F0880F44BE41F00000007D1B901 + 4F0A4FA0E3823BC89F045C0000000000815054015809D8E0F7C3710880044000 + 00E60F0080005201500450E1E3E3E0C89FFC7FE41FE60F0000006901600060E2 + C173C009800000000000000000002401000000E4E33380F8FF00000000000000 + 000020010000000000000000000000000000000000000000000000F0FFFFFFFF + FFFFFFFFFFFF3F0000000000FF87FFF3A8A8A8A8A8A8A8A8A7A72700FC03AA8A + FFCFFFF7FFFFFFFFFFFFFFFFFFFF3F000402048401CC00F6FFFFFFFFFFFFFFFF + FFFF3F00040208820DCC06F6FFFFFFFF7D7D7DFF23232300E41F10811DCC0EF6 + 000000FF000000FF848404002412A08039CC1CF6FFFFFFFFFFFFFFFFFFFF3F00 + 2412008071CC38F6000000FFA7A7A7FFA8A828002412A080E1CC70F6000000FF + DCDCDCFFF7F73700FC130080C1CDE0F6272727FF878787FFFFFF3F002010A080 + 81CDC0F6FFFFFFFFE0E0E0FFABAB2B002010008001CC00F6FFFFFFFF474747FF + 2C2C2C00E01FA080FFCFFFF7ABABABFFFFFFFFFFFFFF3F0000000000FF87FFF3 + FFFFFFFFFFFFFFFF0000000000000000000000A061616161F7F7F7FF22222200 + 000000FF000000FF303030FFFFFFFFFF27272700878787FFFFFFFFFFFFFFFFFF + FFFFFFFFFFFF3F005A5A5AFF000000FF000000FFC4C4C4FFFFFF3F00474747FF + 2F2F2FFFF8F8F8FF414141FF05050500B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFF + FFFF3F00FFFFFFFF000000FFA7A7A7FFA8A8A8A803030300BCBCBCBCF4F4F4FF + BABABAFFB7B7B7FFC5C50500FFFFFFFF272727FF878787FFFFFFFFFFFFFF3F00 + FFFFFFFFFFFFFFFFB2B2B2FF5F5F5FFF11111100AEAEAEFFFFFFFFFF525252FF + 3A3A3AFFFFFF3F00F2F2F2FF343434FF181818FFFFFFFFFFFFFF3F00FFFFFFFF + FFFFFFFFFFFFFFFF000000FFA7A72700A8A8A8A8000000000707070763636363 + 9C9C1C00A0A0A0A0B2B2B2B2FFFFFFFF272727FF87870700FFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFF3F000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000080 + 0000000002000000000000000000FF81FFC07F80010000000300000000001803 + 000001818040408003000180030000000000B8037000018180404480078003C0 + 03FE0F000000F001F8000181804044800FC007E003FC07000000E000F8000181 + BE405F801FE00FF003F803000000F001F8000181804044800FF01FE003F00100 + 0000B803700001818040448007F83FC003E00000000018030000018180404080 + 0300008003400000000000000000FF81FFC07F80010000000300000000000000 + 0000000000000080000000000200000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000020000000200000800800110000040800020000006000 + 2000300000800C00130000040E8003008808E000700038007F800E0017000084 + 0FE00300DC1DE001F8003C003E800F001F601BE40FF803008808E000FC013800 + 1C800E0017601B840FE00300000060000000300008800C00130000040E800300 + 0000200000002000008008001100000408000200000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000008000000000000000000000000000000000000001C0000 + 00000000700000000000C06030C011000038000010000408700000000000E0E0 + 38F017000070000070001C08700000000C0070C01D301EFC1FE00000F0017C08 + FE83FF011E0038800F181CFC1FC00100F007FC09FE83FF013F601C0007181F00 + 00C00000F0017C08FE83FF817FE00E800F1800000060060070001C08700000C0 + FFC007C01D1000FC1F3003001000040870000000008003E0383000FC1F980100 + 0000000070000000000001603060000000CC0000000000000000000000000000 + 0080000000600000000000000000000000000000000000000030000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000004000000000000000000000000000000000000000EFF1F78003800 + 0280190000000000000000000007060CFC002800060006000000000000000000 + 80030C06860128000E0006000000000000F80300C0011803030328001E000680 + 0400000000400000E000B001030328003E000600030001C000E00000C000A000 + 030328007E0006C00F8003C000F001009801A00003036C003E00060003000100 + 00F803003003A0008601C6001E00068004000000000000006006A000FC038301 + 0E0006000000000000000000C00CA00078870103060006000000000000000000 + 8001E00000CEFF07028019000000000000000000000300000004000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000FE0FFF87FFC3FF01000000000000 + 000000000000FF9FFFCFFFE7FF03000000000000000000000000039801CC0066 + 000300000000000000000000000003988DCDC0660003000007C0070000F80300 + 00000398DDCDE0661C030E800D600CE003080200F0070398F9CC70663E0311C0 + 1820082002080200E003039871CC38663E0311401020082002080200C0010398 + F9CC1C663E0311C0182008200208020080000398DDCD0E661C030E800D600CE0 + 03080200F00703988DCD06660003000007C0070000F803000000039801CC0066 + 0003000000000000000000000000FF9FFFCFFFE7FF0300000000000000000000 + 0000FE0FFF87FFC3FF0100000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000F80F0000000010000000000002000000000404000808000020003800 + 0000040002000010040802000808400070006C00080004000240042002100100 + 0808A000D800C600080004000280024001A00000080810018C0183013E803FE0 + 3F000180004000000808A000D800C600080004000280024001A0000008084000 + 70006C0008000400024004200210010008080000200038000000040002000010 + 04080200F80F0000000010000000000002000000000404000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000200000000000000001030210001803008000400070000000 + 00E0FFC0C10F0E70001803004001A000D800FE80FFC060F0F13F3EF001180300 + 200210018C014400418031FCFDFFFEF007180300F00708020603280022001BF0 + F13F3EF0011803000000FC07FF07100014000EC0C10F0E700018030000000000 + 0000000008000400010302100018030000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000C000000000000000000000000000000000000000C004000E0E38363E0 + FF0000000000000000000006608060E0C1C33150900000E41FE60F0000040006 + 500451E0E3E3104994FC7F0000E60F000154000358095AE0F7F3B14994044000 + 00000000075280034F0A4FA0E3BAFB4890045CE41F0000001F52E001410A4900 + 41101FC89FF44B0000E60F007F52D801410A510000000E0880F44B0000E60F00 + 1F51F601410A610041001F0880F44BE41F00000007D1B9014F0A4FA0E3823BC8 + 9F045C0000000000815054015809D8E0F7C371088004400000E60F0080005201 + 500450E1E3E3E0C89FFC7FE41FE60F0000006901600060E2C173C00980000000 + 0000000000002401000000E4E33380F8FF000000000000000000200100000000 + 00000000000000000000000000000000000000F0FFFFFFFFFFFFFFFFFFFF3F00 + 00000000FF87FFF3FFFFFFFFFFFFFFFFFFFF3F00FC03AA8AFFCFFFF7FFFFFFFF + FFFFFFFFFFFF3F000402048401CC00F6FFFFFFFFFFFFFFFFFFFF3F0004020882 + 0DCC06F6FFFFFFFFFFFFFFFFFFFF3F00E41F10811DCC0EF6FFFFFFFFFFFFFFFF + FFFF3F002412A08039CC1CF6FFFFFFFFFFFFFFFFFFFF3F002412008071CC38F6 + FFFFFFFFFFFFFFFFFFFF3F002412A080E1CC70F6FFFFFFFFFFFFFFFFFFFF3F00 + FC130080C1CDE0F6FFFFFFFFFFFFFFFFFFFF3F002010A08081CDC0F6FFFFFFFF + FFFFFFFFFFFF3F002010008001CC00F6FFFFFFFFFFFFFFFFFFFF3F00E01FA080 + FFCFFFF7FFFFFFFFFFFFFFFFFFFF3F0000000000FF87FFF3FFFFFFFFFFFFFFFF + FFFF3F0000000000000000F0FFFFFFFFFFFFFFFFFFFF3F00FFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFF3F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F00 + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F00FFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFF3F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F00FFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFF3F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFF3F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F00FFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFF3F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F00 + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F00FFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFF3F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F00FFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFF3F00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFF3F00 + } + end + object mseicon: tbitmapcomp + bitmap.transparentcolor = -2147483642 + bitmap.image = { + 00000000000000001800000018000000A8080000000000000000000000000000 + 0000000000000000000000000000000000000000ECECEC01EBEBEB01E9E9E901 + E8E8E801E7E7E701E6E6E601E5E5E501E3E3E301E1DEDD02E0E0E001DFDFDF01 + DDDDDD01DCDCDC01DBDBDB01DADADA01D9D9D901D7D7D701D6D6D601D5D5D501 + D4D4D401D3D3D301D1D1D101D0D0D001ECECEC01EBEBEB01E9E9E901E8E8E801 + E7E7E701E6E6E601E5E5E501E3E3E301D78C6C01D67E5901E1A49001E5A79501 + E3A29001E3A59301DE9D8701D3775001D8B3A401D7D7D701D6D6D601D5D5D501 + D4D4D401D3D3D301D1D1D101D0D0D001ECECEC01EBEBEB01E9E9E901E2C8BD01 + DFC1B401E6E6E601E7D2CB01E7B2A301DA846101FDF9F701D56D4401E0644301 + DF604001D9603A01DD8B6A01F0CDBE01D97D5D01DFAA9B01DAC4BE01D5D5D501 + D4D4D401D3D3D301D1D1D101D0D0D001ECECEC01EBEBEB01E9E9E901D99C8101 + E7B39C01D7835F01E18C7001E4775A01D6683F01FFFEFE01F4DDD301D14A1E01 + D22A0001DF927301FFFFFF01E6AA9101D8522C01DF725501DF937D01DCB4A901 + D4D4D401D3D3D301D1D1D101D0D0D001ECECEC01EBEBEB01E9E9E901E0C2B501 + ECC1B001FEFBFA01E4A38901D35F3501CF3A0E01EBBBA801FFFFFF01E5A68D01 + D04B2001FAEFEA01FFFFFF01DA805D01D4270001D7381101DD5E3E01DF876F01 + D8A08C01D0836101CFA89701D0D0D001ECECEC01EBEBEB01E9E9E901EBC3B701 + D97E5A01FFFFFF02FFFEFE01E0937601D15E3301FEFCFB01FBF3EF01D05D3201 + FFFFFF02D4623C01D45F3801D1481D01D2290001D4613701E29E8301EECBBA01 + CFA79501D0D0D001ECECEC01EBEBEB01EBD5CF01EA9D8801DB613B01E5A58C01 + FFFFFF03D5684301DD866801F8E8E101CF502701D9725101E0947901CF4D2301 + D7795501D0512701DB815F01FBF1ED01FBF3EF01D4744D01D5BFB701D0D0D001 + ECECEC01EBEBEB01ECB7A701E6795C01D3441901CE4B1F01ECBCAA01FFFFFF02 + D3643F01A25F4D01CB5A3701AF47370124E6E00168978D01D0391801D56C4601 + F7E4DC01FFFFFF01FFFDFD01D66E4701DB6D4E01DBA59601D0D0D001ECECEC01 + EDD9D301EA9B8501E0583601D6704901EEC4B401D0572C01E29A8101E5A28B01 + 7B907C010EFFF901639A9701679692010EFFF90130D7D101D6644301FFFFFF03 + DE8D6E01D2300701DB543201DD8D7701D4C1BB01ECECEC01EDC5BA01E7836901 + DA3C1601D1471E01D5633D01CE4A2001D03A1701D03C1C017A7F7A0117F4EE01 + 976E7001D6797C019E6B6D01A1505001B94B3801E7AC9801FFFFFF01E7AC9501 + D13C1801D4250201D73A1301DD795E01D8B0A501ECECEC01E6A58F01D8694201 + D5663E01DE8B6C01E8B09B01F0CEBF01F6E2D901DA806001CE1C1501C2272E01 + D7B5B801D5FFFE01D6A4A8013DC7C40114F8F201B15A4501D1552E01D35F3801 + D9755301DC866501DB826001D56B4301D6907901ECECEC01D0653701F5DFD501 + FFFFFF05D566470130D6D20124E4E001D0737D01D6D6D801D855610151ADAD01 + 16F6F101B6473201E1987C01FFFFFF02FEFAF901EBBCA901D7764F01D78D7501 + ECECEC01E9A28D01D7603701D7704A01F2D4C701FFFFFF02E7AC9701D13C2301 + 19F2EC010EFFF901A249570174808B016D8B9201C9202501C35C4101D5593C01 + D0552E01D5634101D76B4701D14E2501D12E0401DC5D3C01DB9A8801ECECEC01 + EDAF9D01E3674701D4270001D0381101D45F3901D25D3601D25F3801CD532701 + C3282401B44B4001B8433E010EFFF902B3634E01FDF9F701FFFFFF01F5DBD101 + D45F3A01D3270A01D4220301D4270001DC604001DB9D8B01ECECEC01EDB8A901 + E5725401D4270001D4230301D1351301DD856701FDF7F501D25F3801E0907701 + F4DCD101D86C4F01965A6101A8474701D3573401FEFDFC01FFFFFF02FEFDFC01 + E0937701D1451D01D4270001DD694C01DAA59601ECECEC01EDC5BA01E7836901 + DA3C1601D1330B01DF927501FFFFFF01E5A18901D66B4801FFFFFF02F1CFC101 + D1251101DA7E5E01D4633F01D2603B01FAF0EC01FFFFFF03ECC0AE01D4502601 + DD795E01D8B0A501ECECEC01EDD9D301EA9B8501DB573001DC836101FFFFFF01 + FEFBFA01D25C3401F3D6CB01FFFFFF02DE876C01CF240B01E49F8701FEFCFB01 + DB7C5C01D0552C01DA7B5A01E29B8101EDC3B201F5DFD601E4A68C01D6795901 + D4C1BB01ECECEC01EBEBEB01E9B09D01D97F5901FEFBFA01F4DCD201DB826001 + D35F3701FFFFFF02EFC7B901D0542C01D0562F01D9735301FFFFFF02D76D4901 + D51E0601D3240401D02A0201D2441901D5684201D89A8601D0D0D001ECECEC01 + EBEBEB01E2B3A201D6744C01D6633B01D1390D01CF2F0601E9B49F01FFFFFF01 + E6A68F01D1431F01E0927601DC7E5F01D24C2901FDF8F601FFFFFF01DE8A6B01 + D4220401D4240201D4270001DD5E3D01DE917C01D6C0B901D0D0D001ECECEC01 + EBEBEB01E9E9E901EBC3B701E8907801E05B3901D1512601F8E6DF01D5684201 + D22E0D01D13A1601F7E6DF01E0937701D1280701E5A58D01FFFFFF01E8B29C01 + D1290101D4270001DC573501DE876F01DAB3A701D1D1D101D0D0D001ECECEC01 + EBEBEB01E9E9E901E8E8E801EABEB101E7907801D9623C01D2542801D4270001 + D4250201D12D0701E8B29B01D1522801D4220301D35A3101FEFDFC01F0D0C201 + D23A0E01DD5E3E01DF876F01DCAFA201D3D3D301D1D1D101D0D0D001ECECEC01 + EBEBEB01E9E9E901E8E8E801E7E7E701E9C2B601E89C8601E4775A01DE573501 + D93B1501D4270001CF431601D2270001D4270001D22F0501E3A08601EABBA701 + D9674501DF937D01DCB4A901D4D4D401D3D3D301D1D1D101D0D0D001ECECEC01 + EBEBEB01E9E9E901E8E8E801E7E7E701E6E6E601E7D2CB01E7B2A301E6978101 + E4806501E26F5101E0644401DF604001DF634301E06D4F01D66F4801D6785201 + DDA39101DAC4BE01D5D5D501D4D4D401D3D3D301D1D1D101D0D0D001ECECEC01 + EBEBEB01E9E9E901E8E8E801E7E7E701E6E6E601E5E5E501E3E3E301E5D1CB01 + E5BEB201E5B0A101E5A79501E3A29001E3A59301E2AD9D01DEB1A201DAC1B801 + D7D7D701D6D6D601D5D5D501D4D4D401D3D3D301D1D1D101D0D0D001 + } + left = 32 + top = 8 + end +end diff --git a/mseide-msegui/lib/common/kernel/msestockobjects.pas b/mseide-msegui/lib/common/kernel/msestockobjects.pas new file mode 100644 index 0000000..2029c98 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msestockobjects.pas @@ -0,0 +1,544 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msestockobjects; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msetypes,msegraphics,mseglob,msegui,msebitmap,msegraphutils,mseclasses, + msestrings,msedatamodules,mseguiglob; + +const + boxsize = 11; //for treelistitem expand box + checkboxsize = 13; //for listitem checkbox + +type + + stockbitmapty = (stb_default,stb_none, + stb_dens0,stb_dens10,stb_dens25, + stb_dens50,stb_dens75,stb_dens90,stb_dens100, + stb_block2,stb_block3,stb_block4, + stb_hatchup3,stb_hatchup4,stb_hatchup5, + stb_hatchdown3,stb_hatchdown4,stb_hatchdown5, + stb_crosshatch3,stb_crosshatch4,stb_crosshatch5,stb_crosshatch6 + ); +const + stb_block1 = stb_dens50; + +type + stockglyphty = ( //order fix! + // 0 1 2 + stg_none,stg_checked,stg_checkedradio, + // 3 4 5 + stg_box,stg_boxexpanded,stg_boxexpand, + // 6 7 8 9 + stg_arrowright,stg_arrowup,stg_arrowleft,stg_arrowdown, + // 10 + stg_ellipse, + // 11 12 13 14 + stg_arrowrightsmall,stg_arrowupsmall,stg_arrowleftsmall,stg_arrowdownsmall, + // 15 16 + stg_arrowfirstsmall,stg_arrowlastsmall, + // 17 + stg_ellipsesmall, + // 18 19 20 21 22 + stg_dbfirst,stg_dbprior,stg_dbnext,stg_dblast,stg_dbinsert, + // 23 24 25 26 27 + stg_dbdelete,stg_dbedit,stg_dbpost,stg_dbcancel,stg_dbrefresh, + // 28 29 30 31 32 + stg_dbfilter,stg_dbfiltermin,stg_dbfiltermax,stg_dbfilteron,stg_dbfind, + // 33 34 35 36 + stg_dbfilteroff,stg_dbindbrowse,stg_dbindedit,stg_dbindinsert, + // 37 38 39 40 + stg_dot,stg_dotsmall,stg_arrowtopsmall,stg_arrowbottomsmall, + // 41 42 43 44 + stg_checkbox,stg_checkboxchecked,stg_checkboxchildchecked,stg_checkboxradio, + // 45 46 47 + stg_circlesmall,stg_circle,stg_circlebig, + // 48 49 50 + stg_squaresmall,stg_square,stg_squarebig, + // 51 52 53 + stg_diamondsmall,stg_diamond,stg_diamondbig, + // 54 55 56 + stg_crosssmall,stg_cross,stg_crossbig, + // 57 58 59 + stg_diagsmall,stg_diag,stg_diagbig, + // 60 61 62 + stg_triasmall,stg_tria,stg_triabig, + // 63 64 65 + stg_triatopsmall,stg_triatop,stg_triatopbig, + // add by Alexandre Minoshi + // 66 67 68 69 70 + stg_mmprev, stg_mmnext, stg_mmplay, stg_mmpause, stg_mmplayandpause, + // 71 + stg_mmclear, + // 72 73 + stg_sound, stg_soundoff, + // 74 75 76 77 78 79 + stg_fullscreen, stg_settings, stg_save, stg_rename, stg_list, stg_listbold, + // 80 81 82 + stg_doublesquare,stg_dbfilterclear,stg_checkboxparentnotchecked, + // 83 + stg_checkboxchildnotchecked + ); + +const + firsttracesymbol = stg_circlesmall; + lasttracesymbol = stg_triatopbig; + +type + stockcaptionty = (sc_none,sc_is_invalid,sc_Format_error,sc_Value_is_required, + sc_Error,sc_Min,sc_Max,sc_Range_error, + sc_Undohk,sc_Redohk,sc_copyhk,sc_cuthk,sc_pastehk, + sc_select_allhk, + sc_insert_rowhk,sc_append_rowhk,sc_delete_rowhk, + sc_Dirhk,sc_Homehk,sc_Uphk,sc_New_dirhk,sc_Namehk, + sc_Show_hidden_fileshk,sc_Filterhk, + sc_Save,sc_Open, + sc_name,sc_create_new_directory, + sc_back,sc_forward,sc_up, + sc_file,sc_exists_overwrite,sc_is_modified_save, + sc_warningupper,sc_errorupper,sc_exception,sc_system, + sc_does_not_exist, + sc_passwordupper,sc_enterpassword,sc_invalidpassword, + sc_can_not_read_directory, + sc_graphic_format_not_supported,sc_graphic_format_error, + sc_MS_Bitmap,sc_MS_Icon,sc_JPEG_Image,sc_PNG_Image, + sc_XPM_Image,sc_PNM_Image,sc_TARGA_image,sc_TIFF_image, + sc_All, + sc_Confirmation,sc_Delete_record_question, + sc_Copy_record_question, + sc_close_page, +{ + dbnavigbuttonty = (dbnb_first,dbnb_prior,dbnb_next,dbnb_last,dbnb_insert, + dbnb_delete,dbnb_edit, + dbnb_post,dbnb_cancel,dbnb_refresh, + dbnb_filter,dbnb_filtermin,dbnb_filtermax,dbnb_filteronoff,dbnb_find, + dbnb_autoedit,dbnb_copyrecord,dbnb_dialog); +} + sc_first,sc_prior,sc_next,sc_last, + sc_append,sc_delete,sc_edit,sc_post,sc_cancel,sc_refresh, + sc_edit_filter,sc_edit_filter_min,sc_edit_filter_max, + sc_reset_filter, + sc_filter_on,sc_search,sc_auto_edit,sc_copy_record, + sc_dialog, + sc_insert,sc_copy,sc_paste, + sc_row_insert,sc_row_append,sc_row_delete, + sc_undo,sc_redo,sc_cut,sc_select_all, + + sc_filter_off, + sc_portrait,sc_landscape, + sc_Delete_row_question,sc_selected_rows, + sc_Single_item_only,sc_Copy_Cells,sc_Paste_Cells, + sc_close,sc_maximize,sc_normalize,sc_minimize,sc_fix_size, + sc_float,sc_stay_on_top,sc_stay_in_background, + sc_lock_children,sc_no_lock, + sc_input,sc_button,sc_on,sc_off, + sc_leftborder,sc_topborder,sc_rightborder,sc_bottomborder, + sc_beginoftext,sc_endoftext,sc_inputmode,sc_overwrite, + sc_deleted,sc_copied,sc_inserted,sc_pasted,sc_withdrawn, + sc_windowactivated,sc_menu, + sc_bof,sc_eof, + sc_voiceoutput,sc_speakagain, + sc_firstcol,sc_firstrow,sc_lastcol,sc_lastrow, + sc_selection,sc_speakpath,sc_disabledbutton, + sc_firstfield,sc_lastfield, + sc_firstelement,sc_lastelement,sc_slower,sc_faster, + sc_window,sc_area,sc_areaactivated, + sc_volumedown,sc_volumeup,sc_cancelspeech + ); + textgeneratorfuncty = function(const params: array of const): msestring; + textgeneratorty = (tg_delete_n_selected_rows); + + tstockobjects = class + private + fbitmaps: array[stockbitmapty] of tbitmap; + ffonts: array[stockfontty] of twidgetfont; +// fmodalresulttext: array[modalresultty] of msestring; +// fmodalresulttextnoshortcut: array[modalresultty] of msestring; + fglyphs: timagelist; + ffontaliasregistered: boolean; + function getbitmaps(index: stockbitmapty): tbitmap; + function getfonts(index: stockfontty): twidgetfont; + function getmodalresulttext(index: modalresultty): msestring; + function getmodalresulttextnoshortcut(index: modalresultty): msestring; + function getglyphs: timagelist; + procedure fontchanged(const sender: tobject); + function getmseicon: tmaskedbitmap; + function getcaptions(index: stockcaptionty): msestring; + function gettextgenerator(index: textgeneratorty): textgeneratorfuncty; + procedure setmseicon(const avalue: tmaskedbitmap); + public + constructor create; + destructor destroy; override; + procedure paintglyph(const canvas: tcanvas; const glyph: stockglyphty; + const rect: rectty; const grayed: boolean = false; + const color: colorty = cl_glyph; + aalignment: alignmentsty = [al_ycentered,al_xcentered]); + property bitmaps[index: stockbitmapty]: tbitmap read getbitmaps; + property fonts[index: stockfontty]: twidgetfont read getfonts; + property modalresulttext[index: modalresultty]: msestring + read getmodalresulttext; + property modalresulttextnoshortcut[index: modalresultty]: msestring + read getmodalresulttextnoshortcut; + property captions[index: stockcaptionty]: msestring read getcaptions; + property textgenerators[index: textgeneratorty]: textgeneratorfuncty + read gettextgenerator; + property glyphs: timagelist read getglyphs; + property mseicon: tmaskedbitmap read getmseicon write setmseicon; + end; + +type + tstockdata = class(tmsedatamodule) + glyphs: timagelist; + mseicon: tbitmapcomp; + end; + +function stockobjects: tstockobjects; +function sc(const acaption: stockcaptionty): msestring; + +procedure init; +procedure deinit; + +implementation + +uses + sysutils,msestockobjects_mfm,msesysintf1,mseguiintf,typinfo,mseconsts,msefont; +//const +// defaultfontheight = 14; +// defaultfontheight = 26; + +type + twidget1 = class(twidget); + +var + stockdata: tstockdata; + stockobjs: tstockobjects; +// fontheight: integer; + +const + {$ifdef mswindows} + b_none: array[0..0] of byte = ($00); //1*1 + b_0: array[0..0] of byte = ($00); //1*1 + b_10: array[0..3] of byte = ($01,$00,$08,$00); //6*4 + b_25: array[0..1] of byte = ($01,$04); //4*2 + b_50: array[0..1] of byte = ($01,$02); //2*2 + b_75: array[0..1] of byte = ($0e,$0b); //4*2 + b_90: array[0..3] of byte = ($3e,$3f,$37,$3f); //6*4 + b_100: array[0..0] of byte = ($01); //1*1 + b_block2: array[0..3] of byte = ($03,$03,$0c,$0c); //4*4 + b_block3: array[0..5] of byte = ($07,$07,$07,$38,$38,$38); //6*6 + b_block4: array[0..7] of byte = ($0f,$0f,$0f,$0f,$f0,$f0,$f0,$f0); //8*8 + b_hatchup3: array[0..2] of byte = ($04,$02,$01); //3*3 + b_hatchup4: array[0..3] of byte = ($08,$04,$02,$01); //4*4 + b_hatchup5: array[0..4] of byte = ($10,$08,$04,$02,$01); //5*5 + b_hatchdown3: array[0..2] of byte = ($01,$02,$04); //3*3 + b_hatchdown4: array[0..3] of byte = ($01,$02,$04,$08); //4*4 + b_hatchdown5: array[0..4] of byte = ($01,$02,$04,$08,$10); //5*5 + b_crosshatch3: array[0..2] of byte = ($05,$02,$05); //3*3 + b_crosshatch4: array[0..3] of byte = ($08,$05,$02,$05); //4*4 + b_crosshatch5: array[0..4] of byte = ($11,$0a,$04,$0a,$11); //5*5 + b_crosshatch6: array[0..5] of byte = ($20,$11,$0a,$04,$0a,$11); //6*6 + + //win98 can not use patternbrush < 8*8 + + b_none_98: array[0..7] of byte = ($00,$00,$00,$00,$00,$00,$00,$00); //8*8 + b_0_98: array[0..7] of byte = ($00,$00,$00,$00,$00,$00,$00,$00); //8*8 + b_10_98: array[0..15] of byte = ($41,$00,$00,$00,$08,$02,$00,$00, + $41,$00,$00,$00,$08,$02,$00,$00); //12*8 + b_25_98: array[0..7] of byte = ($11,$44,$11,$44,$11,$44,$11,$44); //8*8 + b_50_98: array[0..7] of byte = ($55,$aa,$55,$aa,$55,$aa,$55,$aa); //8*8 + b_75_98: array[0..7] of byte = ($ee,$bb,$ee,$bb,$ee,$bb,$ee,$bb); //8*8 + b_90_98: array[0..15] of byte = ($be,$0f,$ff,$0f,$f7,$0d,$ff,$0f, + $be,$0f,$ff,$0f,$f7,$0d,$ff,$0f); //12*8 + b_100_98: array[0..7] of byte = ($ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff); //8*8 + b_block2_98: array[0..7] of byte = ($33,$33,$cc,$cc,$33,$33,$cc,$cc); //8*8 + b_block3_98: array[0..23] of byte = ($c7,$01,$c7,$01,$c7,$01, + $38,$0e,$38,$0e,$38,$0e, //12*12 + $c7,$01,$c7,$01,$c7,$01, + $38,$0e,$38,$0e,$38,$0e); + b_block4_98: array[0..7] of byte = ($0f,$0f,$0f,$0f,$f0,$f0,$f0,$f0); //8*8 + b_hatchup3_98: array[0..23] of byte = ($24,$09,$92,$04,$49,$02, + $24,$09,$92,$04,$49,$02, + $24,$09,$92,$04,$49,$02, + $24,$09,$92,$04,$49,$02); //12*12 + b_hatchup4_98: array[0..7] of byte = ($88,$44,$22,$11,$88,$44,$22,$11); //8*8 + b_hatchup5_98: array[0..19] of byte = ($10,$02,$08,$01,$84,$00,$42,$00,$21,$00, + $10,$02,$08,$01,$84,$00,$42,$00,$21,$00); //10*10 + b_hatchdown3_98: array[0..17] of byte = ($49,$00,$92,$00,$24,$01, + $49,$00,$92,$00,$24,$01, + $49,$00,$92,$00,$24,$01); //9*9 + b_hatchdown4_98: array[0..7] of byte = ($11,$22,$44,$88,$11,$22,$44,$88); //8*8 + b_hatchdown5_98: array[0..19] of byte = ($21,$00,$42,$00,$84,$00,$08,$01,$10,$02, + $21,$00,$42,$00,$84,$00,$08,$01,$10,$02); //10*10 + b_crosshatch3_98: array[0..23] of byte = ($6d,$01,$92,$00,$6d,$01, + $6d,$01,$92,$00,$6d,$01, + $6d,$01,$92,$00,$6d,$01, + $6d,$01,$92,$00,$6d,$01); //12*12 + b_crosshatch4_98: array[0..7] of byte = ($88,$55,$22,$55,$88,$55,$22,$55); //8*8 + b_crosshatch5_98: array[0..19] of byte = ($31,$02,$4a,$01,$84,$00,$4a,$01,$31,$02, + $31,$02,$4a,$01,$84,$00,$4a,$01,$31,$02); //10*10 + b_crosshatch6_98: array[0..23] of byte = ($20,$08,$51,$04,$8a,$02,$04,$01,$8a,$02,$51,$04, + $20,$08,$51,$04,$8a,$02,$04,$01,$8a,$02,$51,$04); //12*12 + + {$else} + b_none: array[0..0] of byte = ($00); //1*1 + b_0: array[0..0] of byte = ($00); //1*1 + b_10: array[0..3] of byte = ($01,$00,$08,$00); //6*4 + b_25: array[0..1] of byte = ($01,$04); //4*2 + b_50: array[0..1] of byte = ($01,$02); //2*2 + b_75: array[0..1] of byte = ($0e,$0b); //4*2 + b_90: array[0..3] of byte = ($3e,$3f,$37,$3f); //6*4 + b_100: array[0..0] of byte = ($01); //1*1 + b_block2: array[0..3] of byte = ($03,$03,$0c,$0c); //4*4 + b_block3: array[0..5] of byte = ($07,$07,$07,$38,$38,$38); //6*6 + b_block4: array[0..7] of byte = ($0f,$0f,$0f,$0f,$f0,$f0,$f0,$f0); //8*8 + b_hatchup3: array[0..2] of byte = ($04,$02,$01); //3*3 + b_hatchup4: array[0..3] of byte = ($08,$04,$02,$01); //4*4 + b_hatchup5: array[0..4] of byte = ($10,$08,$04,$02,$01); //5*5 + b_hatchdown3: array[0..2] of byte = ($01,$02,$04); //3*3 + b_hatchdown4: array[0..3] of byte = ($01,$02,$04,$08); //4*4 + b_hatchdown5: array[0..4] of byte = ($01,$02,$04,$08,$10); //5*5 + b_crosshatch3: array[0..2] of byte = ($05,$02,$05); //3*3 + b_crosshatch4: array[0..3] of byte = ($08,$05,$02,$05); //4*4 + b_crosshatch5: array[0..4] of byte = ($11,$0a,$04,$0a,$11); //5*5 + b_crosshatch6: array[0..5] of byte = ($20,$11,$0a,$04,$0a,$11); //6*6 + {$endif} + +function stockobjects: tstockobjects; +begin + if stockobjs = nil then begin + stockobjs:= tstockobjects.create; + application.initialize; //stockdata needs initialized application + end; + result:= stockobjs; +end; + +function sc(const acaption: stockcaptionty): msestring; +begin + result:= stockobjects.captions[acaption]; +end; + +procedure init; +begin +// deinit; + if stockdata = nil then begin + stockdata:= tstockdata.create(nil,true); + end; +end; + +procedure deinit; +begin + freeandnil(stockobjs); + freeandnil(stockdata); +end; + +{ tstockobjects } + +constructor tstockobjects.create; +begin + //dummy +end; + +destructor tstockobjects.destroy; +var + bmps: stockbitmapty; + fonts1: stockfontty; +begin + for bmps:= low(stockbitmapty) to high(stockbitmapty) do begin + fbitmaps[bmps].free; + end; + for fonts1:= low(stockfontty) to high(stockfontty) do begin + ffonts[fonts1].Free; + end; + fglyphs.Free; + inherited; +end; + +function tstockobjects.getbitmaps(index: stockbitmapty): tbitmap; +begin + if fbitmaps[index] = nil then begin + fbitmaps[index]:= tbitmap.create(bmk_mono); + {$ifdef mswindows} + if iswin98 then begin + case index of //must be >= 8*8 for win98 + stb_default,stb_none: fbitmaps[index].loaddata(makesize(8,8),@b_none_98); + stb_dens0: fbitmaps[index].loaddata(makesize(8,8),@b_0_98); + stb_dens10: fbitmaps[index].loaddata(makesize(12,8),@b_10_98); + stb_dens25: fbitmaps[index].loaddata(makesize(8,8),@b_25_98); + stb_dens50: fbitmaps[index].loaddata(makesize(8,8),@b_50_98); + stb_dens75: fbitmaps[index].loaddata(makesize(8,8),@b_75_98); + stb_dens90: fbitmaps[index].loaddata(makesize(12,8),@b_90_98); + stb_dens100: fbitmaps[index].loaddata(makesize(8,8),@b_100_98); + stb_block2: fbitmaps[index].loaddata(makesize(8,8),@b_block2_98); + stb_block3: fbitmaps[index].loaddata(makesize(12,12),@b_block3_98); + stb_block4: fbitmaps[index].loaddata(makesize(8,8),@b_block4_98); + stb_hatchup3: fbitmaps[index].loaddata(makesize(12,12),@b_hatchup3_98); + stb_hatchup4: fbitmaps[index].loaddata(makesize(8,8),@b_hatchup4_98); + stb_hatchup5: fbitmaps[index].loaddata(makesize(10,10),@b_hatchup5_98); + stb_hatchdown3: fbitmaps[index].loaddata(makesize(9,9),@b_hatchdown3_98); + stb_hatchdown4: fbitmaps[index].loaddata(makesize(8,8),@b_hatchdown4_98); + stb_hatchdown5: fbitmaps[index].loaddata(makesize(10,10),@b_hatchdown5_98); + stb_crosshatch3: fbitmaps[index].loaddata(makesize(9,9),@b_crosshatch3_98); + stb_crosshatch4: fbitmaps[index].loaddata(makesize(8,8),@b_crosshatch4_98); + stb_crosshatch5: fbitmaps[index].loaddata(makesize(10,10),@b_crosshatch5_98); + stb_crosshatch6: fbitmaps[index].loaddata(makesize(12,12),@b_crosshatch6_98); + end; + end + else begin + case index of + stb_default,stb_none: fbitmaps[index].loaddata(makesize(1,1),@b_none); + stb_dens0: fbitmaps[index].loaddata(makesize(1,1),@b_0); + stb_dens10: fbitmaps[index].loaddata(makesize(6,4),@b_10); + stb_dens25: fbitmaps[index].loaddata(makesize(4,2),@b_25); + stb_dens50: fbitmaps[index].loaddata(makesize(2,2),@b_50); + stb_dens75: fbitmaps[index].loaddata(makesize(4,2),@b_75); + stb_dens90: fbitmaps[index].loaddata(makesize(6,4),@b_90); + stb_dens100: fbitmaps[index].loaddata(makesize(1,1),@b_100); + stb_block2: fbitmaps[index].loaddata(makesize(4,4),@b_block2); + stb_block3: fbitmaps[index].loaddata(makesize(6,6),@b_block3); + stb_block4: fbitmaps[index].loaddata(makesize(8,8),@b_block4); + stb_hatchup3: fbitmaps[index].loaddata(makesize(3,3),@b_hatchup3); + stb_hatchup4: fbitmaps[index].loaddata(makesize(4,4),@b_hatchup4); + stb_hatchup5: fbitmaps[index].loaddata(makesize(5,5),@b_hatchup5); + stb_hatchdown3: fbitmaps[index].loaddata(makesize(3,3),@b_hatchdown3); + stb_hatchdown4: fbitmaps[index].loaddata(makesize(4,4),@b_hatchdown4); + stb_hatchdown5: fbitmaps[index].loaddata(makesize(5,5),@b_hatchdown5); + stb_crosshatch3: fbitmaps[index].loaddata(makesize(3,3),@b_crosshatch3); + stb_crosshatch4: fbitmaps[index].loaddata(makesize(4,4),@b_crosshatch4); + stb_crosshatch5: fbitmaps[index].loaddata(makesize(5,5),@b_crosshatch5); + stb_crosshatch6: fbitmaps[index].loaddata(makesize(6,6),@b_crosshatch6); + end; + end; + {$else} + case index of + stb_default,stb_none: fbitmaps[index].loaddata(makesize(1,1),@b_none); + stb_dens0: fbitmaps[index].loaddata(makesize(1,1),@b_0); + stb_dens10: fbitmaps[index].loaddata(makesize(6,4),@b_10); + stb_dens25: fbitmaps[index].loaddata(makesize(4,2),@b_25); + stb_dens50: fbitmaps[index].loaddata(makesize(2,2),@b_50); + stb_dens75: fbitmaps[index].loaddata(makesize(4,2),@b_75); + stb_dens90: fbitmaps[index].loaddata(makesize(6,4),@b_90); + stb_dens100: fbitmaps[index].loaddata(makesize(1,1),@b_100); + stb_block2: fbitmaps[index].loaddata(makesize(4,4),@b_block2); + stb_block3: fbitmaps[index].loaddata(makesize(6,6),@b_block3); + stb_block4: fbitmaps[index].loaddata(makesize(8,8),@b_block4); + stb_hatchup3: fbitmaps[index].loaddata(makesize(3,3),@b_hatchup3); + stb_hatchup4: fbitmaps[index].loaddata(makesize(4,4),@b_hatchup4); + stb_hatchup5: fbitmaps[index].loaddata(makesize(5,5),@b_hatchup5); + stb_hatchdown3: fbitmaps[index].loaddata(makesize(3,3),@b_hatchdown3); + stb_hatchdown4: fbitmaps[index].loaddata(makesize(4,4),@b_hatchdown4); + stb_hatchdown5: fbitmaps[index].loaddata(makesize(5,5),@b_hatchdown5); + stb_crosshatch3: fbitmaps[index].loaddata(makesize(3,3),@b_crosshatch3); + stb_crosshatch4: fbitmaps[index].loaddata(makesize(4,4),@b_crosshatch4); + stb_crosshatch5: fbitmaps[index].loaddata(makesize(5,5),@b_crosshatch5); + stb_crosshatch6: fbitmaps[index].loaddata(makesize(6,6),@b_crosshatch6); + end; + {$endif} + end; + result:= fbitmaps[index]; +end; + +procedure tstockobjects.fontchanged(const sender: tobject); +var + int1: integer; +begin + with application do begin + for int1:= 0 to windowcount - 1 do begin + with twidget1(windows[int1].owner) do begin + fontchanged; + end; + end; + end; +end; + +function tstockobjects.getfonts(index: stockfontty): twidgetfont; +var + fo1: stockfontty; + str1: string; +begin + if not ffontaliasregistered then begin + for fo1:= low(stockfontty) to high(stockfontty) do begin + case fo1 of + stf_default: begin + str1:= ''; + end; + else begin + str1:= 'stf_default'; + end; + end; + registerfontalias(getenumname(typeinfo(stockfontty),ord(fo1)), + gui_getdefaultfontnames[fo1],fam_nooverwrite,0,0,[],1.0,str1); + end; + ffontaliasregistered:= true; + end; + if ffonts[index] = nil then begin + ffonts[index]:= twidgetfont.create; + ffonts[index].name:= getenumname(typeinfo(stockfontty),ord(index)); + ffonts[index].onchange:= {$ifdef FPC}@{$endif}fontchanged; + end; + result:= ffonts[index]; +end; + +function tstockobjects.getglyphs: timagelist; +begin + result:= stockdata.glyphs; +end; + +function tstockobjects.getmseicon: tmaskedbitmap; +begin + result:= stockdata.mseicon.bitmap; +end; + +procedure tstockobjects.setmseicon(const avalue: tmaskedbitmap); +begin + stockdata.mseicon.bitmap.assign(avalue); +end; + +function tstockobjects.getmodalresulttext(index: modalresultty): msestring; +begin + result:= mseconsts.modalresulttext(index); +// result:= fmodalresulttext[index]; +end; + +function tstockobjects.getmodalresulttextnoshortcut(index: modalresultty): msestring; +begin + result:= mseconsts.modalresulttextnoshortcut(index); +// result:= fmodalresulttextnoshortcut[index]; +end; + +function tstockobjects.getcaptions(index: stockcaptionty): msestring; +begin + result:= stockcaptions(index); +end; + +function tstockobjects.gettextgenerator(index: textgeneratorty): textgeneratorfuncty; +begin + result:= stocktextgenerators(index); +end; + +procedure tstockobjects.paintglyph(const canvas: tcanvas; + const glyph: stockglyphty; const rect: rectty; + const grayed: boolean = false; const color: colorty = cl_glyph; + aalignment: alignmentsty = [al_ycentered,al_xcentered]); +var + colorbefore: colorty; +begin + colorbefore:= canvas.color; + canvas.color:= color; + if grayed then begin + aalignment:= aalignment + [al_grayed]; + end; + glyphs.paint(canvas,integer(glyph),rect,aalignment,color); + canvas.color:= colorbefore; +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/msestockobjects_mfm.pas b/mseide-msegui/lib/common/kernel/msestockobjects_mfm.pas new file mode 100644 index 0000000..0cf3919 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msestockobjects_mfm.pas @@ -0,0 +1,448 @@ +unit msestockobjects_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msestockobjects; + +const + objdata: record size: integer; data: array[0..8604] of byte end = + (size: 8605; data: ( + 84,80,70,48,10,116,115,116,111,99,107,100,97,116,97,9,115,116,111,99, + 107,100,97,116,97,9,98,111,117,110,100,115,95,99,120,3,188,0,9,98, + 111,117,110,100,115,95,99,121,2,85,4,108,101,102,116,3,129,0,3,116, + 111,112,2,57,15,109,111,100,117,108,101,99,108,97,115,115,110,97,109,101, + 6,14,116,109,115,101,100,97,116,97,109,111,100,117,108,101,0,10,116,105, + 109,97,103,101,108,105,115,116,6,103,108,121,112,104,115,5,119,105,100,116, + 104,2,15,6,104,101,105,103,104,116,2,15,7,111,112,116,105,111,110,115, + 11,14,98,109,111,95,109,111,110,111,99,104,114,111,109,101,10,98,109,111, + 95,109,97,115,107,101,100,0,5,99,111,117,110,116,2,84,4,108,101,102, + 116,2,32,3,116,111,112,2,40,5,105,109,97,103,101,10,164,23,0,0, + 0,0,0,0,3,0,0,0,150,0,0,0,150,0,0,0,184,11,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,128,0,0,0,0,2,0,0,0,0,0,0,0,0,0,255,129, + 255,192,127,128,1,0,0,0,3,0,0,0,0,0,24,3,0,0,1,129, + 128,64,64,128,3,0,1,128,3,0,0,0,0,0,184,3,112,0,1,129, + 128,64,68,128,7,128,3,192,3,254,15,0,0,0,240,1,248,0,1,129, + 128,64,68,128,15,192,7,224,3,252,7,0,0,0,224,0,248,0,1,129, + 190,64,95,128,31,224,15,240,3,248,3,0,0,0,240,1,248,0,1,129, + 128,64,68,128,15,240,31,224,3,240,1,0,0,0,184,3,112,0,1,129, + 128,64,68,128,7,248,63,192,3,224,0,0,0,0,24,3,0,0,1,129, + 128,64,64,128,3,0,0,128,3,64,0,0,0,0,0,0,0,0,255,129, + 255,192,127,128,1,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,128,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,32,0, + 0,128,8,0,17,0,0,4,8,0,2,0,0,0,96,0,32,0,48,0, + 0,128,12,0,19,0,0,4,14,128,3,0,136,8,224,0,112,0,56,0, + 127,128,14,0,23,0,0,132,15,224,3,0,220,29,224,1,248,0,60,0, + 62,128,15,0,31,96,27,228,15,248,3,0,136,8,224,0,252,1,56,0, + 28,128,14,0,23,96,27,132,15,224,3,0,0,0,96,0,0,0,48,0, + 8,128,12,0,19,0,0,4,14,128,3,0,0,0,32,0,0,0,32,0, + 0,128,8,0,17,0,0,4,8,0,2,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,28,0,0,0,0,0,0,112,0,0,0, + 0,0,192,96,48,192,17,0,0,56,0,0,16,0,4,8,112,0,0,0, + 0,0,224,224,56,240,23,0,0,112,0,0,112,0,28,8,112,0,0,0, + 12,0,112,192,29,48,30,252,31,224,0,0,240,1,124,8,254,131,255,1, + 30,0,56,128,15,24,28,252,31,192,1,0,240,7,252,9,254,131,255,1, + 63,96,28,0,7,24,31,0,0,192,0,0,240,1,124,8,254,131,255,129, + 127,224,14,128,15,24,0,0,0,96,6,0,112,0,28,8,112,0,0,192, + 255,192,7,192,29,16,0,252,31,48,3,0,16,0,4,8,112,0,0,0, + 0,128,3,224,56,48,0,252,31,152,1,0,0,0,0,0,112,0,0,0, + 0,0,1,96,48,96,0,0,0,204,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,128,0,0,0,96,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,48,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,14,255,31,120,0,56,0, + 2,128,25,0,0,0,0,0,0,0,0,0,0,7,6,12,252,0,40,0, + 6,0,6,0,0,0,0,0,0,0,0,0,128,3,12,6,134,1,40,0, + 14,0,6,0,0,0,0,0,0,248,3,0,192,1,24,3,3,3,40,0, + 30,0,6,128,4,0,0,0,0,64,0,0,224,0,176,1,3,3,40,0, + 62,0,6,0,3,0,1,192,0,224,0,0,192,0,160,0,3,3,40,0, + 126,0,6,192,15,128,3,192,0,240,1,0,152,1,160,0,3,3,108,0, + 62,0,6,0,3,0,1,0,0,248,3,0,48,3,160,0,134,1,198,0, + 30,0,6,128,4,0,0,0,0,0,0,0,96,6,160,0,252,3,131,1, + 14,0,6,0,0,0,0,0,0,0,0,0,192,12,160,0,120,135,1,3, + 6,0,6,0,0,0,0,0,0,0,0,0,128,1,224,0,0,206,255,7, + 2,128,25,0,0,0,0,0,0,0,0,0,0,3,0,0,0,4,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,254,15,255,135,255,195, + 255,1,0,0,0,0,0,0,0,0,0,0,0,0,255,159,255,207,255,231, + 255,3,0,0,0,0,0,0,0,0,0,0,0,0,3,152,1,204,0,102, + 0,3,0,0,0,0,0,0,0,0,0,0,0,0,3,152,141,205,192,102, + 0,3,0,0,7,192,7,0,0,248,3,0,0,0,3,152,221,205,224,102, + 28,3,14,128,13,96,12,224,3,8,2,0,240,7,3,152,249,204,112,102, + 62,3,17,192,24,32,8,32,2,8,2,0,224,3,3,152,113,204,56,102, + 62,3,17,64,16,32,8,32,2,8,2,0,192,1,3,152,249,204,28,102, + 62,3,17,192,24,32,8,32,2,8,2,0,128,0,3,152,221,205,14,102, + 28,3,14,128,13,96,12,224,3,8,2,0,240,7,3,152,141,205,6,102, + 0,3,0,0,7,192,7,0,0,248,3,0,0,0,3,152,1,204,0,102, + 0,3,0,0,0,0,0,0,0,0,0,0,0,0,255,159,255,207,255,231, + 255,3,0,0,0,0,0,0,0,0,0,0,0,0,254,15,255,135,255,195, + 255,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,248,15,0,0,0,0,16,0, + 0,0,0,0,2,0,0,0,0,4,4,0,8,8,0,0,32,0,56,0, + 0,0,4,0,2,0,0,16,4,8,2,0,8,8,64,0,112,0,108,0, + 8,0,4,0,2,64,4,32,2,16,1,0,8,8,160,0,216,0,198,0, + 8,0,4,0,2,128,2,64,1,160,0,0,8,8,16,1,140,1,131,1, + 62,128,63,224,63,0,1,128,0,64,0,0,8,8,160,0,216,0,198,0, + 8,0,4,0,2,128,2,64,1,160,0,0,8,8,64,0,112,0,108,0, + 8,0,4,0,2,64,4,32,2,16,1,0,8,8,0,0,32,0,56,0, + 0,0,4,0,2,0,0,16,4,8,2,0,248,15,0,0,0,0,16,0, + 0,0,0,0,2,0,0,0,0,4,4,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0, + 0,0,0,0,1,3,2,16,0,24,3,0,128,0,64,0,112,0,0,0, + 0,224,255,192,193,15,14,112,0,24,3,0,64,1,160,0,216,0,254,128, + 255,192,96,240,241,63,62,240,1,24,3,0,32,2,16,1,140,1,68,0, + 65,128,49,252,253,255,254,240,7,24,3,0,240,7,8,2,6,3,40,0, + 34,0,27,240,241,63,62,240,1,24,3,0,0,0,252,7,255,7,16,0, + 20,0,14,192,193,15,14,112,0,24,3,0,0,0,0,0,0,0,0,0, + 8,0,4,0,1,3,2,16,0,24,3,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,64,0,224, + 227,131,99,224,255,0,0,0,0,0,0,0,0,0,0,6,96,128,96,224, + 193,195,49,80,144,0,0,228,31,230,15,0,0,4,0,6,80,4,81,224, + 227,227,16,73,148,252,127,0,0,230,15,0,1,84,0,3,88,9,90,224, + 247,243,177,73,148,4,64,0,0,0,0,0,7,82,128,3,79,10,79,160, + 227,186,251,72,144,4,92,228,31,0,0,0,31,82,224,1,65,10,73,0, + 65,16,31,200,159,244,75,0,0,230,15,0,127,82,216,1,65,10,81,0, + 0,0,14,8,128,244,75,0,0,230,15,0,31,81,246,1,65,10,97,0, + 65,0,31,8,128,244,75,228,31,0,0,0,7,209,185,1,79,10,79,160, + 227,130,59,200,159,4,92,0,0,0,0,0,129,80,84,1,88,9,216,224, + 247,195,113,8,128,4,64,0,0,230,15,0,128,0,82,1,80,4,80,225, + 227,227,224,200,159,252,127,228,31,230,15,0,0,0,105,1,96,0,96,226, + 193,115,192,9,128,0,0,0,0,0,0,0,0,0,36,1,0,0,0,228, + 227,51,128,248,255,0,0,0,0,0,0,0,0,0,32,1,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,240, + 255,255,255,255,255,255,255,255,255,255,63,0,0,0,0,0,255,135,255,243, + 168,168,168,168,168,168,168,168,167,167,39,0,252,3,170,138,255,207,255,247, + 255,255,255,255,255,255,255,255,255,255,63,0,4,2,4,132,1,204,0,246, + 255,255,255,255,255,255,255,255,255,255,63,0,4,2,8,130,13,204,6,246, + 255,255,255,255,125,125,125,255,35,35,35,0,228,31,16,129,29,204,14,246, + 0,0,0,255,0,0,0,255,132,132,4,0,36,18,160,128,57,204,28,246, + 255,255,255,255,255,255,255,255,255,255,63,0,36,18,0,128,113,204,56,246, + 0,0,0,255,167,167,167,255,168,168,40,0,36,18,160,128,225,204,112,246, + 0,0,0,255,220,220,220,255,247,247,55,0,252,19,0,128,193,205,224,246, + 39,39,39,255,135,135,135,255,255,255,63,0,32,16,160,128,129,205,192,246, + 255,255,255,255,224,224,224,255,171,171,43,0,32,16,0,128,1,204,0,246, + 255,255,255,255,71,71,71,255,44,44,44,0,224,31,160,128,255,207,255,247, + 171,171,171,255,255,255,255,255,255,255,63,0,0,0,0,0,255,135,255,243, + 255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,160, + 97,97,97,97,247,247,247,255,34,34,34,0,0,0,0,255,0,0,0,255, + 48,48,48,255,255,255,255,255,39,39,39,0,135,135,135,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,63,0,90,90,90,255,0,0,0,255, + 0,0,0,255,196,196,196,255,255,255,63,0,71,71,71,255,47,47,47,255, + 248,248,248,255,65,65,65,255,5,5,5,0,182,182,182,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,63,0,255,255,255,255,0,0,0,255, + 167,167,167,255,168,168,168,168,3,3,3,0,188,188,188,188,244,244,244,255, + 186,186,186,255,183,183,183,255,197,197,5,0,255,255,255,255,39,39,39,255, + 135,135,135,255,255,255,255,255,255,255,63,0,255,255,255,255,255,255,255,255, + 178,178,178,255,95,95,95,255,17,17,17,0,174,174,174,255,255,255,255,255, + 82,82,82,255,58,58,58,255,255,255,63,0,242,242,242,255,52,52,52,255, + 24,24,24,255,255,255,255,255,255,255,63,0,255,255,255,255,255,255,255,255, + 255,255,255,255,0,0,0,255,167,167,39,0,168,168,168,168,0,0,0,0, + 7,7,7,7,99,99,99,99,156,156,28,0,160,160,160,160,178,178,178,178, + 255,255,255,255,39,39,39,255,135,135,7,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,63,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,128,0,0,0,0,2,0,0,0,0,0,0,0,0,0,255,129, + 255,192,127,128,1,0,0,0,3,0,0,0,0,0,24,3,0,0,1,129, + 128,64,64,128,3,0,1,128,3,0,0,0,0,0,184,3,112,0,1,129, + 128,64,68,128,7,128,3,192,3,254,15,0,0,0,240,1,248,0,1,129, + 128,64,68,128,15,192,7,224,3,252,7,0,0,0,224,0,248,0,1,129, + 190,64,95,128,31,224,15,240,3,248,3,0,0,0,240,1,248,0,1,129, + 128,64,68,128,15,240,31,224,3,240,1,0,0,0,184,3,112,0,1,129, + 128,64,68,128,7,248,63,192,3,224,0,0,0,0,24,3,0,0,1,129, + 128,64,64,128,3,0,0,128,3,64,0,0,0,0,0,0,0,0,255,129, + 255,192,127,128,1,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,128,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,32,0, + 0,128,8,0,17,0,0,4,8,0,2,0,0,0,96,0,32,0,48,0, + 0,128,12,0,19,0,0,4,14,128,3,0,136,8,224,0,112,0,56,0, + 127,128,14,0,23,0,0,132,15,224,3,0,220,29,224,1,248,0,60,0, + 62,128,15,0,31,96,27,228,15,248,3,0,136,8,224,0,252,1,56,0, + 28,128,14,0,23,96,27,132,15,224,3,0,0,0,96,0,0,0,48,0, + 8,128,12,0,19,0,0,4,14,128,3,0,0,0,32,0,0,0,32,0, + 0,128,8,0,17,0,0,4,8,0,2,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,28,0,0,0,0,0,0,112,0,0,0, + 0,0,192,96,48,192,17,0,0,56,0,0,16,0,4,8,112,0,0,0, + 0,0,224,224,56,240,23,0,0,112,0,0,112,0,28,8,112,0,0,0, + 12,0,112,192,29,48,30,252,31,224,0,0,240,1,124,8,254,131,255,1, + 30,0,56,128,15,24,28,252,31,192,1,0,240,7,252,9,254,131,255,1, + 63,96,28,0,7,24,31,0,0,192,0,0,240,1,124,8,254,131,255,129, + 127,224,14,128,15,24,0,0,0,96,6,0,112,0,28,8,112,0,0,192, + 255,192,7,192,29,16,0,252,31,48,3,0,16,0,4,8,112,0,0,0, + 0,128,3,224,56,48,0,252,31,152,1,0,0,0,0,0,112,0,0,0, + 0,0,1,96,48,96,0,0,0,204,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,128,0,0,0,96,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,48,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,14,255,31,120,0,56,0, + 2,128,25,0,0,0,0,0,0,0,0,0,0,7,6,12,252,0,40,0, + 6,0,6,0,0,0,0,0,0,0,0,0,128,3,12,6,134,1,40,0, + 14,0,6,0,0,0,0,0,0,248,3,0,192,1,24,3,3,3,40,0, + 30,0,6,128,4,0,0,0,0,64,0,0,224,0,176,1,3,3,40,0, + 62,0,6,0,3,0,1,192,0,224,0,0,192,0,160,0,3,3,40,0, + 126,0,6,192,15,128,3,192,0,240,1,0,152,1,160,0,3,3,108,0, + 62,0,6,0,3,0,1,0,0,248,3,0,48,3,160,0,134,1,198,0, + 30,0,6,128,4,0,0,0,0,0,0,0,96,6,160,0,252,3,131,1, + 14,0,6,0,0,0,0,0,0,0,0,0,192,12,160,0,120,135,1,3, + 6,0,6,0,0,0,0,0,0,0,0,0,128,1,224,0,0,206,255,7, + 2,128,25,0,0,0,0,0,0,0,0,0,0,3,0,0,0,4,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,254,15,255,135,255,195, + 255,1,0,0,0,0,0,0,0,0,0,0,0,0,255,159,255,207,255,231, + 255,3,0,0,0,0,0,0,0,0,0,0,0,0,3,152,1,204,0,102, + 0,3,0,0,0,0,0,0,0,0,0,0,0,0,3,152,141,205,192,102, + 0,3,0,0,7,192,7,0,0,248,3,0,0,0,3,152,221,205,224,102, + 28,3,14,128,13,96,12,224,3,8,2,0,240,7,3,152,249,204,112,102, + 62,3,17,192,24,32,8,32,2,8,2,0,224,3,3,152,113,204,56,102, + 62,3,17,64,16,32,8,32,2,8,2,0,192,1,3,152,249,204,28,102, + 62,3,17,192,24,32,8,32,2,8,2,0,128,0,3,152,221,205,14,102, + 28,3,14,128,13,96,12,224,3,8,2,0,240,7,3,152,141,205,6,102, + 0,3,0,0,7,192,7,0,0,248,3,0,0,0,3,152,1,204,0,102, + 0,3,0,0,0,0,0,0,0,0,0,0,0,0,255,159,255,207,255,231, + 255,3,0,0,0,0,0,0,0,0,0,0,0,0,254,15,255,135,255,195, + 255,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,248,15,0,0,0,0,16,0, + 0,0,0,0,2,0,0,0,0,4,4,0,8,8,0,0,32,0,56,0, + 0,0,4,0,2,0,0,16,4,8,2,0,8,8,64,0,112,0,108,0, + 8,0,4,0,2,64,4,32,2,16,1,0,8,8,160,0,216,0,198,0, + 8,0,4,0,2,128,2,64,1,160,0,0,8,8,16,1,140,1,131,1, + 62,128,63,224,63,0,1,128,0,64,0,0,8,8,160,0,216,0,198,0, + 8,0,4,0,2,128,2,64,1,160,0,0,8,8,64,0,112,0,108,0, + 8,0,4,0,2,64,4,32,2,16,1,0,8,8,0,0,32,0,56,0, + 0,0,4,0,2,0,0,16,4,8,2,0,248,15,0,0,0,0,16,0, + 0,0,0,0,2,0,0,0,0,4,4,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0, + 0,0,0,0,1,3,2,16,0,24,3,0,128,0,64,0,112,0,0,0, + 0,224,255,192,193,15,14,112,0,24,3,0,64,1,160,0,216,0,254,128, + 255,192,96,240,241,63,62,240,1,24,3,0,32,2,16,1,140,1,68,0, + 65,128,49,252,253,255,254,240,7,24,3,0,240,7,8,2,6,3,40,0, + 34,0,27,240,241,63,62,240,1,24,3,0,0,0,252,7,255,7,16,0, + 20,0,14,192,193,15,14,112,0,24,3,0,0,0,0,0,0,0,0,0, + 8,0,4,0,1,3,2,16,0,24,3,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,64,0,224, + 227,131,99,224,255,0,0,0,0,0,0,0,0,0,0,6,96,128,96,224, + 193,195,49,80,144,0,0,228,31,230,15,0,0,4,0,6,80,4,81,224, + 227,227,16,73,148,252,127,0,0,230,15,0,1,84,0,3,88,9,90,224, + 247,243,177,73,148,4,64,0,0,0,0,0,7,82,128,3,79,10,79,160, + 227,186,251,72,144,4,92,228,31,0,0,0,31,82,224,1,65,10,73,0, + 65,16,31,200,159,244,75,0,0,230,15,0,127,82,216,1,65,10,81,0, + 0,0,14,8,128,244,75,0,0,230,15,0,31,81,246,1,65,10,97,0, + 65,0,31,8,128,244,75,228,31,0,0,0,7,209,185,1,79,10,79,160, + 227,130,59,200,159,4,92,0,0,0,0,0,129,80,84,1,88,9,216,224, + 247,195,113,8,128,4,64,0,0,230,15,0,128,0,82,1,80,4,80,225, + 227,227,224,200,159,252,127,228,31,230,15,0,0,0,105,1,96,0,96,226, + 193,115,192,9,128,0,0,0,0,0,0,0,0,0,36,1,0,0,0,228, + 227,51,128,248,255,0,0,0,0,0,0,0,0,0,32,1,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,240, + 255,255,255,255,255,255,255,255,255,255,63,0,0,0,0,0,255,135,255,243, + 255,255,255,255,255,255,255,255,255,255,63,0,252,3,170,138,255,207,255,247, + 255,255,255,255,255,255,255,255,255,255,63,0,4,2,4,132,1,204,0,246, + 255,255,255,255,255,255,255,255,255,255,63,0,4,2,8,130,13,204,6,246, + 255,255,255,255,255,255,255,255,255,255,63,0,228,31,16,129,29,204,14,246, + 255,255,255,255,255,255,255,255,255,255,63,0,36,18,160,128,57,204,28,246, + 255,255,255,255,255,255,255,255,255,255,63,0,36,18,0,128,113,204,56,246, + 255,255,255,255,255,255,255,255,255,255,63,0,36,18,160,128,225,204,112,246, + 255,255,255,255,255,255,255,255,255,255,63,0,252,19,0,128,193,205,224,246, + 255,255,255,255,255,255,255,255,255,255,63,0,32,16,160,128,129,205,192,246, + 255,255,255,255,255,255,255,255,255,255,63,0,32,16,0,128,1,204,0,246, + 255,255,255,255,255,255,255,255,255,255,63,0,224,31,160,128,255,207,255,247, + 255,255,255,255,255,255,255,255,255,255,63,0,0,0,0,0,255,135,255,243, + 255,255,255,255,255,255,255,255,255,255,63,0,0,0,0,0,0,0,0,240, + 255,255,255,255,255,255,255,255,255,255,63,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,63,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,63,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,63,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,63,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,63,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,63,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,63,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,63,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,63,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,63,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,63,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,63,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,63,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,63,0,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,63,0,0,0,11,116,98,105,116,109, + 97,112,99,111,109,112,7,109,115,101,105,99,111,110,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,12,98,105,116,109,97,112,46,105,109,97,103,101,10,220,8,0, + 0,0,0,0,0,0,0,0,0,24,0,0,0,24,0,0,0,168,8,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,236,236,236,1,235,235,235, + 1,233,233,233,1,232,232,232,1,231,231,231,1,230,230,230,1,229,229,229, + 1,227,227,227,1,225,222,221,2,224,224,224,1,223,223,223,1,221,221,221, + 1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215, + 1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,209,209,209, + 1,208,208,208,1,236,236,236,1,235,235,235,1,233,233,233,1,232,232,232, + 1,231,231,231,1,230,230,230,1,229,229,229,1,227,227,227,1,215,140,108, + 1,214,126,89,1,225,164,144,1,229,167,149,1,227,162,144,1,227,165,147, + 1,222,157,135,1,211,119,80,1,216,179,164,1,215,215,215,1,214,214,214, + 1,213,213,213,1,212,212,212,1,211,211,211,1,209,209,209,1,208,208,208, + 1,236,236,236,1,235,235,235,1,233,233,233,1,226,200,189,1,223,193,180, + 1,230,230,230,1,231,210,203,1,231,178,163,1,218,132,97,1,253,249,247, + 1,213,109,68,1,224,100,67,1,223,96,64,1,217,96,58,1,221,139,106, + 1,240,205,190,1,217,125,93,1,223,170,155,1,218,196,190,1,213,213,213, + 1,212,212,212,1,211,211,211,1,209,209,209,1,208,208,208,1,236,236,236, + 1,235,235,235,1,233,233,233,1,217,156,129,1,231,179,156,1,215,131,95, + 1,225,140,112,1,228,119,90,1,214,104,63,1,255,254,254,1,244,221,211, + 1,209,74,30,1,210,42,0,1,223,146,115,1,255,255,255,1,230,170,145, + 1,216,82,44,1,223,114,85,1,223,147,125,1,220,180,169,1,212,212,212, + 1,211,211,211,1,209,209,209,1,208,208,208,1,236,236,236,1,235,235,235, + 1,233,233,233,1,224,194,181,1,236,193,176,1,254,251,250,1,228,163,137, + 1,211,95,53,1,207,58,14,1,235,187,168,1,255,255,255,1,229,166,141, + 1,208,75,32,1,250,239,234,1,255,255,255,1,218,128,93,1,212,39,0, + 1,215,56,17,1,221,94,62,1,223,135,111,1,216,160,140,1,208,131,97, + 1,207,168,151,1,208,208,208,1,236,236,236,1,235,235,235,1,233,233,233, + 1,235,195,183,1,217,126,90,1,255,255,255,2,255,254,254,1,224,147,118, + 1,209,94,51,1,254,252,251,1,251,243,239,1,208,93,50,1,255,255,255, + 2,212,98,60,1,212,95,56,1,209,72,29,1,210,41,0,1,212,97,55, + 1,226,158,131,1,238,203,186,1,207,167,149,1,208,208,208,1,236,236,236, + 1,235,235,235,1,235,213,207,1,234,157,136,1,219,97,59,1,229,165,140, + 1,255,255,255,3,213,104,67,1,221,134,104,1,248,232,225,1,207,80,39, + 1,217,114,81,1,224,148,121,1,207,77,35,1,215,121,85,1,208,81,39, + 1,219,129,95,1,251,241,237,1,251,243,239,1,212,116,77,1,213,191,183, + 1,208,208,208,1,236,236,236,1,235,235,235,1,236,183,167,1,230,121,92, + 1,211,68,25,1,206,75,31,1,236,188,170,1,255,255,255,2,211,100,63, + 1,162,95,77,1,203,90,55,1,175,71,55,1,36,230,224,1,104,151,141, + 1,208,57,24,1,213,108,70,1,247,228,220,1,255,255,255,1,255,253,253, + 1,214,110,71,1,219,109,78,1,219,165,150,1,208,208,208,1,236,236,236, + 1,237,217,211,1,234,155,133,1,224,88,54,1,214,112,73,1,238,196,180, + 1,208,87,44,1,226,154,129,1,229,162,139,1,123,144,124,1,14,255,249, + 1,99,154,151,1,103,150,146,1,14,255,249,1,48,215,209,1,214,100,67, + 1,255,255,255,3,222,141,110,1,210,48,7,1,219,84,50,1,221,141,119, + 1,212,193,187,1,236,236,236,1,237,197,186,1,231,131,105,1,218,60,22, + 1,209,71,30,1,213,99,61,1,206,74,32,1,208,58,23,1,208,60,28, + 1,122,127,122,1,23,244,238,1,151,110,112,1,214,121,124,1,158,107,109, + 1,161,80,80,1,185,75,56,1,231,172,152,1,255,255,255,1,231,172,149, + 1,209,60,24,1,212,37,2,1,215,58,19,1,221,121,94,1,216,176,165, + 1,236,236,236,1,230,165,143,1,216,105,66,1,213,102,62,1,222,139,108, + 1,232,176,155,1,240,206,191,1,246,226,217,1,218,128,96,1,206,28,21, + 1,194,39,46,1,215,181,184,1,213,255,254,1,214,164,168,1,61,199,196, + 1,20,248,242,1,177,90,69,1,209,85,46,1,211,95,56,1,217,117,83, + 1,220,134,101,1,219,130,96,1,213,107,67,1,214,144,121,1,236,236,236, + 1,208,101,55,1,245,223,213,1,255,255,255,5,213,102,71,1,48,214,210, + 1,36,228,224,1,208,115,125,1,214,214,216,1,216,85,97,1,81,173,173, + 1,22,246,241,1,182,71,50,1,225,152,124,1,255,255,255,2,254,250,249, + 1,235,188,169,1,215,118,79,1,215,141,117,1,236,236,236,1,233,162,141, + 1,215,96,55,1,215,112,74,1,242,212,199,1,255,255,255,2,231,172,151, + 1,209,60,35,1,25,242,236,1,14,255,249,1,162,73,87,1,116,128,139, + 1,109,139,146,1,201,32,37,1,195,92,65,1,213,89,60,1,208,85,46, + 1,213,99,65,1,215,107,71,1,209,78,37,1,209,46,4,1,220,93,60, + 1,219,154,136,1,236,236,236,1,237,175,157,1,227,103,71,1,212,39,0, + 1,208,56,17,1,212,95,57,1,210,93,54,1,210,95,56,1,205,83,39, + 1,195,40,36,1,180,75,64,1,184,67,62,1,14,255,249,2,179,99,78, + 1,253,249,247,1,255,255,255,1,245,219,209,1,212,95,58,1,211,39,10, + 1,212,34,3,1,212,39,0,1,220,96,64,1,219,157,139,1,236,236,236, + 1,237,184,169,1,229,114,84,1,212,39,0,1,212,35,3,1,209,53,19, + 1,221,133,103,1,253,247,245,1,210,95,56,1,224,144,119,1,244,220,209, + 1,216,108,79,1,150,90,97,1,168,71,71,1,211,87,52,1,254,253,252, + 1,255,255,255,2,254,253,252,1,224,147,119,1,209,69,29,1,212,39,0, + 1,221,105,76,1,218,165,150,1,236,236,236,1,237,197,186,1,231,131,105, + 1,218,60,22,1,209,51,11,1,223,146,117,1,255,255,255,1,229,161,137, + 1,214,107,72,1,255,255,255,2,241,207,193,1,209,37,17,1,218,126,94, + 1,212,99,63,1,210,96,59,1,250,240,236,1,255,255,255,3,236,192,174, + 1,212,80,38,1,221,121,94,1,216,176,165,1,236,236,236,1,237,217,211, + 1,234,155,133,1,219,87,48,1,220,131,97,1,255,255,255,1,254,251,250, + 1,210,92,52,1,243,214,203,1,255,255,255,2,222,135,108,1,207,36,11, + 1,228,159,135,1,254,252,251,1,219,124,92,1,208,85,44,1,218,123,90, + 1,226,155,129,1,237,195,178,1,245,223,214,1,228,166,140,1,214,121,89, + 1,212,193,187,1,236,236,236,1,235,235,235,1,233,176,157,1,217,127,89, + 1,254,251,250,1,244,220,210,1,219,130,96,1,211,95,55,1,255,255,255, + 2,239,199,185,1,208,84,44,1,208,86,47,1,217,115,83,1,255,255,255, + 2,215,109,73,1,213,30,6,1,211,36,4,1,208,42,2,1,210,68,25, + 1,213,104,66,1,216,154,134,1,208,208,208,1,236,236,236,1,235,235,235, + 1,226,179,162,1,214,116,76,1,214,99,59,1,209,57,13,1,207,47,6, + 1,233,180,159,1,255,255,255,1,230,166,143,1,209,67,31,1,224,146,118, + 1,220,126,95,1,210,76,41,1,253,248,246,1,255,255,255,1,222,138,107, + 1,212,34,4,1,212,36,2,1,212,39,0,1,221,94,61,1,222,145,124, + 1,214,192,185,1,208,208,208,1,236,236,236,1,235,235,235,1,233,233,233, + 1,235,195,183,1,232,144,120,1,224,91,57,1,209,81,38,1,248,230,223, + 1,213,104,66,1,210,46,13,1,209,58,22,1,247,230,223,1,224,147,119, + 1,209,40,7,1,229,165,141,1,255,255,255,1,232,178,156,1,209,41,1, + 1,212,39,0,1,220,87,53,1,222,135,111,1,218,179,167,1,209,209,209, + 1,208,208,208,1,236,236,236,1,235,235,235,1,233,233,233,1,232,232,232, + 1,234,190,177,1,231,144,120,1,217,98,60,1,210,84,40,1,212,39,0, + 1,212,37,2,1,209,45,7,1,232,178,155,1,209,82,40,1,212,34,3, + 1,211,90,49,1,254,253,252,1,240,208,194,1,210,58,14,1,221,94,62, + 1,223,135,111,1,220,175,162,1,211,211,211,1,209,209,209,1,208,208,208, + 1,236,236,236,1,235,235,235,1,233,233,233,1,232,232,232,1,231,231,231, + 1,233,194,182,1,232,156,134,1,228,119,90,1,222,87,53,1,217,59,21, + 1,212,39,0,1,207,67,22,1,210,39,0,1,212,39,0,1,210,47,5, + 1,227,160,134,1,234,187,167,1,217,103,69,1,223,147,125,1,220,180,169, + 1,212,212,212,1,211,211,211,1,209,209,209,1,208,208,208,1,236,236,236, + 1,235,235,235,1,233,233,233,1,232,232,232,1,231,231,231,1,230,230,230, + 1,231,210,203,1,231,178,163,1,230,151,129,1,228,128,101,1,226,111,81, + 1,224,100,68,1,223,96,64,1,223,99,67,1,224,109,79,1,214,111,72, + 1,214,120,82,1,221,163,145,1,218,196,190,1,213,213,213,1,212,212,212, + 1,211,211,211,1,209,209,209,1,208,208,208,1,236,236,236,1,235,235,235, + 1,233,233,233,1,232,232,232,1,231,231,231,1,230,230,230,1,229,229,229, + 1,227,227,227,1,229,209,203,1,229,190,178,1,229,176,161,1,229,167,149, + 1,227,162,144,1,227,165,147,1,226,173,157,1,222,177,162,1,218,193,184, + 1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211, + 1,209,209,209,1,208,208,208,1,4,108,101,102,116,2,32,3,116,111,112, + 2,8,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tstockdata,''); +end. diff --git a/mseide-msegui/lib/common/kernel/msestream.pas b/mseide-msegui/lib/common/kernel/msestream.pas new file mode 100644 index 0000000..98725d3 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msestream.pas @@ -0,0 +1,3172 @@ +{ MSEgui Copyright (c) 1999-2015 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msestream; +{$ifdef FPC} + {$if defined(FPC) and (fpc_fullversion >= 020501)} + {$define mse_fpc_2_6} + {$ifend} + {$ifdef mse_fpc_2_6} + {$define mse_hasvtunicodestring} + {$endif} +{$endif} + +{$ifdef FPC}{$mode objfpc}{$h+}{$goto on}{$endif} +{$ifndef FPC}{$ifdef linux} {$define UNIX} {$endif}{$endif} + + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,sysutils,msestrings,msetypes,msethread,msesystypes,msesys, + msereal,mseevent,mseclasses,mseglob{,mseformatstr}; + +const + defaultfilerights = [s_irusr,s_iwusr,s_irgrp,s_iwgrp,s_iroth,s_iwoth]; + defaultdirrights = [s_irusr,s_iwusr,s_ixusr,s_irgrp,s_iwgrp, + s_ixgrp,s_iroth,s_iwoth,s_ixoth]; +type + + tmsefilestream = class; + + cryptoclientstatety = (ccs_open); + cryptoclientstatesty = set of cryptoclientstatety; + cryptohandlerdataty = array[0..32] of pointer; + + tcustomcryptohandler = class; + cryptoclientinfoty = record + stream: tmsefilestream; + link: tcustomcryptohandler; + linkindex: integer; +// chainend: tcustomcryptohandler; +// chainendindex: integer; + { + linkbuf: pbyte; + linkbufsize: integer; + linkbuflength: integer; + linkbufpos: integer; + } + state: cryptoclientstatesty; + handlerdata: cryptohandlerdataty; + end; + pcryptoclientinfoty = ^cryptoclientinfoty; + cryptoclientinfoarty = array of cryptoclientinfoty; + + tcustomcryptohandler = class(tmsecomponent) + private + fclients: cryptoclientinfoarty; + fchain: tcustomcryptohandler; + procedure setchain(const avalue: tcustomcryptohandler); + protected + fchainend: tcustomcryptohandler; + procedure flush(var aclient: cryptoclientinfoty); overload; virtual; + procedure flushchain(var aclient: cryptoclientinfoty); + procedure writeerror(var aclient: cryptoclientinfoty); + procedure readerror(var aclient: cryptoclientinfoty); + procedure finalizeclient(var aclient: cryptoclientinfoty); virtual; + function checkopen(const aindex: integer): pcryptoclientinfoty; + procedure connect(const aclient: tmsefilestream; + const alink: tcustomcryptohandler; const aindex: integer; + out endhandler: tcustomcryptohandler; out endindex: integer); + procedure disconnect({const aclient: tmsefilestream; + const alink: tcustomcryptohandler} + const aindex: integer); + procedure open(var aclient: cryptoclientinfoty); virtual; + procedure close(var aclient: cryptoclientinfoty); virtual; + function read(var aclient: cryptoclientinfoty; + var buffer; count: longint): longint; virtual; + function write(var aclient: cryptoclientinfoty; + const buffer; count: longint): longint; virtual; + function seek(var aclient: cryptoclientinfoty; + const offset: int64; origin: tseekorigin): int64; virtual; + function getsize(var aclient: cryptoclientinfoty): int64; virtual; + function getclient(const astream: tmsefilestream): pcryptoclientinfoty; +// function getopenclient(const astream: tmsefilestream): pcryptoclientinfoty; + public + destructor destroy; override; + procedure flush(const astream: tmsefilestream); overload; + function encrypt(const adata: string; const base64: boolean = false; + const maxlinelength: integer = defaultbase64linelength): string; + overload; + function encrypt(const adata: pointer; adatalength: integer; + const base64: boolean = false; + const maxlinelength: integer = defaultbase64linelength): string; + overload; + function decrypt(const adata: string; const base64: boolean = false): string; + function encrypttext(const atext: msestring; + const base64: boolean = false; + const maxlinelength: integer = defaultbase64linelength): string; + function decrypttext(const adata: string; + const base64: boolean = false): msestring; + published + property chain: tcustomcryptohandler read fchain write setchain; + end; + + {$warnings off} + tmsefilestream = class(thandlestream) + private + ffilename: filenamety; + fopenmode: fileopenmodety; + ffilerights: filerightsty; + ftransactionname: filenamety; + fcryptohandler: tcustomcryptohandler; + fendhandler: tcustomcryptohandler; + fendindex: integer; + fismemorystream: boolean; +// function getmemory: pointer; + procedure checkmemorystream; + procedure setcryptohandler(const avalue: tcustomcryptohandler); + function getfilerights: filerightsty; + procedure setfilerights(const avalue: filerightsty); + function getcapacity: ptrint; + protected + fmemorystream: tmemorystream; + procedure setcapacity(const avalue: ptrint); virtual; + procedure sethandle(value: integer); virtual; + procedure closehandle(const ahandle: integer); virtual; + constructor internalcreate(const afilename: filenamety; + const aopenmode: fileopenmodety; + const accessmode: fileaccessmodesty; + const rights: filerightsty; + out error: syserrorty); overload; + function getsize: int64; override; + function inheritedgetsize: int64; + function inheritedread(var buffer; count: longint): longint; + function inheritedwrite(const buffer; count: longint): longint; + function inheritedseek(const offset: int64; + origin: tseekorigin): int64; + function getmemory: pointer; override; + public + constructor create(const afilename: filenamety; + const aopenmode: fileopenmodety = fm_read; + const accessmode: fileaccessmodesty = []; + const rights: filerightsty = defaultfilerights); overload; + constructor createtransaction(const afilename: filenamety; + rights: filerightsty = defaultfilerights); overload; + constructor createtempfile(const prefix: filenamety; + out afilename: filenamety); + constructor create(ahandle: integer); overload; virtual; //allways called + constructor create; overload; + //memorystream + constructor create(const aopenmode: fileopenmodety); overload; + //memorystream + constructor createstringcopy(const adata: string); //implies fm_read + destructor destroy; override; + class function trycreate(out ainstance: tmsefilestream; + const afilename: filenamety; + const aopenmode: fileopenmodety = fm_read; + const accessmode: fileaccessmodesty = []; + const rights: filerightsty = defaultfilerights): syserrorty; + function releasehandle(): filehandlety override; + function read(var buffer; count: longint): longint; override; + function write(const buffer; count: longint): longint; override; + function seek(const offset: int64; origin: tseekorigin): int64; override; + function readdatastring: string; override; + //read available data + procedure writedatastring(const value: rawbytestring); override; + function isopen: boolean; + property filename: filenamety read ffilename; + property openmode: fileopenmodety read fopenmode; + property transactionname: filenamety read ftransactionname; + function close: boolean; //false on commit error + procedure cancel; //calls close without commit, removes intermediate file + procedure flushbuffer; virtual; + procedure flush; virtual; + + procedure setsize(const newsize: int64); override; + property ismemorystream: boolean read fismemorystream; + procedure clear; virtual; //only for memorystream + property capacity: ptrint read getcapacity write setcapacity; + //only for memorystream +// property memory: pointer read getmemory; //only for memorystream + property filerights: filerightsty read getfilerights write setfilerights; + property cryptohandler: tcustomcryptohandler read fcryptohandler + write setcryptohandler; + end; + {$warnings on} + +const + defaultbuflen = 2048; + minbuflen = 256; + +type + textstreamstatety = (tss_eof,tss_error,tss_notopen,tss_pipeactive,tss_response, + tss_nosigio,tss_unblocked,tss_haslink); + textstreamstatesty = set of textstreamstatety; + + charencodingty = (ce_locale,ce_utf8,ce_ascii,ce_iso8859_1); + //ce_ascii -> 7Bit, + //string and msestrings -> pascalstrings + + tcustombufstream = class(tmsefilestream) + private + finternalbuffer: string; + fbuflen: integer; + fcachedposition: int64; + + fusewritebuffer: boolean; + procedure setusewritebuffer(const avalue: boolean); + function getbufpo: pchar; + protected + fwriting: boolean; + fbuffer: pchar; + bufoffset, bufend: pchar; + fstate: textstreamstatesty; +// procedure setcapacity(const avalue: ptrint); override; + function getnotopen: boolean; + procedure setbuflen(const Value: integer); virtual; + function geteof: boolean; + function readbytes(var buf): integer; virtual; + //reads max. buflen bytes + procedure fillbuffer(); + procedure checkbuffer(); + procedure internalwritebuffer(const buffer; count: longint); + public + constructor create(ahandle: integer); override; + constructor createdata(const adata: rawbytestring); + procedure clear; override; //only for memorystream + + procedure setsize(const newsize: int64); override; + function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override; + function Read(var Buffer; Count: Longint): Longint; override; + function Write(const Buffer; Count: Longint): Longint; override; + + procedure flushbuffer; override; + + property buflen: integer read fbuflen write setbuflen default defaultbuflen; + property usewritebuffer: boolean read fusewritebuffer + write setusewritebuffer default false; + property eof: boolean read geteof; + property bufpo: pchar read getbufpo; + procedure skip(const adist: integer); //skips characters + end; + + tbufstream = class(tcustombufstream) + public + end; + + eolflagty = (eolf_linefeed,eolf_returnlinefeed); + eolflagsty = set of eolflagty; + eolstylety = (eol_default,eol_system,eol_unix,eol_windows); + + ttextstream = class(tcustombufstream) + private + fposvorher: int64; + fsearchabortpo: pboolean; + fsearchlinestartpos: longword; + fsearchlinenumber: longword; + fsearchpos: longword; + fsearchfoundpos: longword; + fsearchtext: string; + fsearchtextlower: string; + fsearchtextupper: string; + fsearchoptions: searchoptionsty; + fsearchtextvalid: boolean; + feolstyle: eolstylety; + procedure setsearchtext(const Value: string); + function getmsesearchtext: msestring; + procedure setmsesearchtext(const avalue: msestring); + procedure setsearchoptions(const Value: searchoptionsty); + procedure seteolstyle(const avalue: eolstylety); + protected + fencoding: charencodingty; + feolflags: eolflagsty; + feol: string; + feolm: msestring; + function encode(const value: msestring): string; + function decode(const value: string): msestring; + public + constructor create(ahandle: integer); override; + class function trycreate(out ainstance: ttextstream; + const afilename: filenamety; + const aopenmode: fileopenmodety = fm_read; + const accessmode: fileaccessmodesty = []; + const rights: filerightsty = defaultfilerights): syserrorty; + procedure return; //setzt filepointer auf letzte readln position + + procedure writestr(const value: string); //no encoding + procedure writestrln(const value: string); //no encoding + function readstrln(var value: string): boolean; overload; virtual; + //not out, variable address will be checked for nil + //no encoding + procedure writetotext(var dest: text); //no encoding + + procedure write(const value: string); reintroduce; overload; + procedure write(const value: msestring); reintroduce; overload; + procedure write(const value: real); reintroduce; overload; + procedure write(const value: integer); reintroduce; overload; + procedure write(const value: boolean); reintroduce; overload; + procedure write(const values: array of const); reintroduce; overload; + + procedure writeln; overload; + procedure writeln(const value: string); overload; virtual; + procedure writeln(const value: msestring); overload; + procedure writeln(const value: real); overload; + procedure writeln(const value: integer); overload; + procedure writeln(const value: boolean); overload; + procedure writeln(const value: msestringarty); overload; + procedure writeln(const value: stringarty); overload; + procedure writeln(const values: array of const); overload; + + function readln: boolean; overload; + function readln(var value: string): boolean; overload; + //true wenn zeile vollstaendig, sonst eof erreicht + function readln(var value: msestring): boolean; overload; + //true wenn zeile vollstaendig, sonst eof erreicht + function readln(out value: integer): boolean; overload; + //true wenn zeile vollstaendig, sonst eof erreicht + function readln(out value: boolean): boolean; overload; + //true wenn zeile vollstaendig, sonst eof erreicht + function readln(out value: real): boolean; overload; + //true wenn zeile vollstaendig, sonst eof erreicht + function readln(out value: msestringarty): boolean; overload; + //true wenn zeile vollstaendig, sonst eof erreicht + function readln(out value: stringarty): boolean; overload; + //true wenn zeile vollstaendig, sonst eof erreicht + + procedure writestrings(const value: stringarty); + procedure writemsestrings(const value: msestringarty); + function readstrings: stringarty; + function readmsestrings: msestringarty; + function readmsedatastring: msestring; //returns remainig data + function readstring(const default: string): string; + //liest string, bringt defaultwert bei fehler + function readinteger(default: integer; min: integer = minint; + max: integer = maxint): integer; + //liest integer, bringt defaultwert bei fehler + function readboolean(default: boolean): boolean; + //liest boolean, bringt defaultwert bei fehler + function readreal(default: real; min: real = -bigreal; + max: real = bigreal): real; + //liest double, bringt defaultwert bei fehler + // begrenzt wert auf min..max + function findnext(const substring: string): boolean; + //positioiniert filepointer auf erstes vorkommen von substring, true wenn gefunden + //wenn nicht gefunden wird filepointer nicht veraendert + //performance verbesserungswuerdig!! + function linecount: integer; + //zaehlt ab aktueller position anzahl linefeeds bis eof + + procedure resetsearch; + function searchnext: boolean; //true wenn gefunden + property nativesearchtext: string read fsearchtext write setsearchtext; + property msesearchtext: msestring read getmsesearchtext + write setmsesearchtext; + property searchoptions: searchoptionsty read fsearchoptions + write setsearchoptions; + property searchpos: longword read fsearchpos write fsearchpos; + property searchfoundpos: longword read fsearchfoundpos; + property searchlinestartpos: longword read fsearchlinestartpos + write fsearchlinestartpos; + property searchlinenumber: longword read fsearchlinenumber + write fsearchlinenumber; + property searchabortpo: pboolean read fsearchabortpo write fsearchabortpo; + + property notopen: boolean read getnotopen; + property encoding: charencodingty read fencoding write fencoding + default ce_locale; + function foundeolstyle: eolstylety; //found by readln + property eolstyle: eolstylety read feolstyle + write seteolstyle default eol_default; + //for writeln, eol_default -> eol_system + end; + + ttextdatastream = class(ttextstream) + private + fquotechar: msechar; + fseparator: msechar; + fforcequote: boolean; + public + constructor create(ahandle: integer); override; + function readcsvstring(out value: msestring): boolean; + //true if lineend + function readcsvvalues(out values: msestringarty): boolean; + //true if lineend + + procedure writerecord(const fields: array of const); overload; + procedure writerecord(const fields: msestringarty); overload; + procedure writerecord(const fields: stringarty); overload; + procedure writerecord(const fields: integerarty); overload; + procedure writerecord(const fields: realarty); overload; + procedure writerecord(const fields: int64arty); overload; + procedure writerecord(const fields: booleanarty); overload; + function readrecord(fields: array of pointer; types: string): boolean; //true if no error + // b -> boolean + // i -> integer + // I -> int64 + // s -> ansistring + // S -> msestring + // r -> real + property separator: msechar read fseparator write fseparator default ','; + property quotechar: msechar read fquotechar write fquotechar default '"'; + property forcequote: boolean read fforcequote write fforcequote default false; + end; + + tresourcefilestream = class(tmsefilestream) + public + procedure WriteResourceHeader(resourcetyp: word; + const ResName: string; out FixupInfo: Integer); + end; + + tcryptfilestream = class(tfilestream) //seek nicht erlaubt! + //used to obfuscate ini files, obsolete + private + seed: word; + schluesseln: boolean; + procedure krypt16(var buffer; count: integer); + + public + constructor Create(const aFileName: string; Mode: Word); + + function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override; + function Read(var Buffer; Count: Longint): Longint; override; + function Write(const Buffer; Count: Longint): Longint; override; + //buffer wird veraendert! + end; + + tstringcopystream = class(tmemorystream) + private + fdata: string; + protected + function getmemory: pointer; override; + public + constructor create(const adata: string); + destructor destroy; override; + function readdatastring: string; override; + function write(const Buffer; Count: Longint): Longint; override; + end; + + ttextstringcopystream = class(ttextdatastream) + private + fdata: string; + protected + function getmemory: pointer; override; + public + constructor create(const adata: string); + destructor destroy; override; + function write(const Buffer; Count: Longint): Longint; override; + end; + + tmemorycopystream = class(tmemorystream) + private + protected + public + constructor create(const adata: pointer; const asize: integer); + destructor destroy; override; + function write(const Buffer; Count: Longint): Longint; override; + end; + + tstringbufferstream = class(tmemorystream) + private + fdata: string; + function getdata: string; + protected + function realloc(var newcapacity: ptrint): pointer; override; + public + constructor create(const adata: string); + property data: string read getdata; + end; + + ttextstringbufferstream = class(ttextdatastream) + private + function getdata: string; + public + constructor create(const adata: string; + const aopenmode: fileopenmodety = fm_create); + property data: string read getdata; + end; + +function getnextbufferline(var data: pchar; len: integer): string; + //data = nil -> fertig +function getbufferline(const data: pchar; linenr,len: integer): string; + //1. zeile = 0 +function getkeystring(const data: pchar; len: integer; name: string): string; + //bringt nach '=' folgenden text +procedure setfilenonblock(handle: integer; value: boolean); + +procedure copyvariantarray(const source: array of const; const dest: array of pointer); + +function getrecordtypechars(const fields: array of const): string; + // b -> boolean + // i -> integer + // I -> int64 + // s -> ansistring + // S -> msestring + // r -> real + +function encodestring(const value: msestring; + const encoding: charencodingty = ce_utf8): string; +function decodestring(const value: string; + const encoding: charencodingty = ce_utf8): msestring; + +function encoderecord(const fields: array of const; + forcequote: boolean = false; const quotechar: msechar = '"'; + const separator: msechar = ','): msestring; +function decoderecord(const value: msestring; + const fields: array of pointer; const types: string; + const quotechar: msechar = '"'; + const separator: msechar = ','): boolean; overload; + // types: + // b -> boolean + // i -> integer + // I -> int64 + // s -> ansistring + // S -> msestring + // r -> real + +function readstreamdatastring(const astream: tstream): string; + //reads from current pos to eof +function readfiledatastring(const afilename: filenamety): string; +function tryreadfiledatastring(const afilename: filenamety; + out adata: string): syserrorty; +procedure writefiledatastring(const afilename: filenamety; const adata: string); +function trywritefiledatastring(const afilename: filenamety; + const adata: string): syserrorty; + +implementation +uses + msefileutils,msebits,{msegui,}sysconst,msesysutils, + msesysintf1,msesysintf,mseformatstr,msefloattostr, + msedatalist,mseapplication,msearrayutils, + {$ifdef UNIX} mselibc, + {$else} windows, + {$endif} + rtlconsts; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{ + tmemorystreamcracker = class(tcustommemorystream) + private + FCapacity: Longint; + end; +} +{$ifdef FPC} +type + pboolean = ^boolean; +{$endif} + + {$ifdef MSWINDOWS} + + {$else} + + {$ifdef FPC} //bug in bfcntlh.inc + { +const + O_ACCMODE = $3; + O_RDONLY = $0; + O_WRONLY = $1; + O_RDWR = $2; + O_CREAT = $40; + O_EXCL = $80; + O_NOCTTY = $100; + O_TRUNC = $200; + O_APPEND = $400; + O_NONBLOCK = $800; + O_NDELAY = O_NONBLOCK; + O_SYNC = $1000; + O_FSYNC = O_SYNC; + O_ASYNC = $2000; + + O_DIRECT = $4000; + O_DIRECTORY = $10000; + O_NOFOLLOW = $20000; + + O_DSYNC = O_SYNC; + O_RSYNC = O_SYNC; + + O_LARGEFILE = $8000; + } + {$endif} + {$endif} +const + windowseol = #$0d#$0a; + unixeol = #$0a; + +{$ifdef mswindows} + syseol = windowseol; +{$else} + syseol = unixeol; +{$endif} + +(* + windowseol: array[0..1] of char = (#$0d,#$0a); + unixeol: array[0..0] of char = (#$0a); + + {$ifdef mswindows} + syseol: array[0..1] of char = (#$0d,#$0a); + {$else} + syseol: array[0..0] of char = (#$0a); + {$endif} +*) +const + kryptsignatur = $9617ae3c; +type + tstream1 = class(tstream); + tmemorystream1 = class(tmemorystream); + +function readfiledatastring(const afilename: filenamety): string; +var + stream1: tmsefilestream; +begin + stream1:= tmsefilestream.create(afilename); + try + result:= stream1.readdatastring; + finally + stream1.free; + end; +end; + +function tryreadfiledatastring(const afilename: filenamety; + out adata: string): syserrorty; +var + stream1: tmsefilestream; +begin + adata:= ''; + result:= tmsefilestream.trycreate(stream1,afilename); + if result = sye_ok then begin + try + adata:= stream1.readdatastring; + except + result:= sye_read; + end; + stream1.free; + end; +end; + +procedure writefiledatastring(const afilename: filenamety; const adata: string); +var + stream1: tmsefilestream; +begin + stream1:= tmsefilestream.create(afilename,fm_create); + try + stream1.writedatastring(adata); + finally + stream1.free; + end; +end; + +function trywritefiledatastring(const afilename: filenamety; + const adata: string): syserrorty; +var + stream1: tmsefilestream; +begin + result:= tmsefilestream.trycreate(stream1,afilename,fm_create); + if result = sye_ok then begin + try + stream1.writedatastring(adata); + except + result:= sye_write; + end; + stream1.free; + end; +end; + +function readstreamdatastring(const astream: tstream): string; + //reads from current pos to eof +var + size1: ptrint; + pos1: ptrint; + lint1,lint2: ptrint; +begin + size1:= astream.size-astream.position; + if size1 < 256 then begin + size1:= 256; + end; + setlength(result,size1+1); + pos1:= 0; + while true do begin + lint1:= size1-pos1; + lint2:= astream.read((pchar(pointer(result))+pos1)^,lint1+1); + pos1:= pos1+lint2; + if lint2 <= lint1 then begin + setlength(result,pos1); + break; + end; + size1:= size1 * 2; + setlength(result,size1+1); + end; +end; + +procedure streamerror; +begin + syserror(syelasterror,'Streamerror: '); +end; + + {$ifdef UNIX} +procedure setfilenonblock(handle: integer; value: boolean); +var + int1: integer; +begin + int1:= fcntl(handle,f_getfl,[0]); + if int1 = -1 then begin + streamerror; + end; + if value then begin + int1:= int1 or o_nonblock; + end + else begin + int1:= int1 and not o_nonblock; + end; + if fcntl(handle,f_setfl,[int1]) = -1 then begin + streamerror; + end; +end; + {$else} +procedure setfilenonblock(handle: integer; value: boolean); +begin + raise exception.Create('nonblock not supported'); +end; + {$endif} + +function getnextbufferline(var data: pchar; len: integer): string; + //data = nil -> fertig +var + po1: pchar; + int1: integer; +begin + result:= ''; + po1:= data; + int1:= len; + po1:= strlscan(po1,c_linefeed,int1); + if po1 <> nil then begin + int1:= po1-data; + dec(int1); + if (po1+int1)^ = c_return then begin + dec(int1); + end; + if int1 > 0 then begin + setlength(result,int1); + move(data^,result[1],int1) + end; + inc(po1); + end; + data:= po1; +end; + +function getbufferline(const data: pchar; linenr,len: integer): string; + //1. zeile = 0 +var + po1: pchar; + int1: integer; +begin + result:= ''; + po1:= data; + for int1:= 0 to linenr do begin + result:= getnextbufferline(po1,len-(po1-data)); + end; +end; + +function getkeystring(const data: pchar; len: integer; name: string): string; + //bringt nach '=' folgenden text +var + po1: pchar; +begin + result:= ''; + po1:= data; + name:= name+'='; + while po1 <> nil do begin + result:= getnextbufferline(po1,len-(po1-data)); + if pos(name,result) = 1 then begin + result:= copy(result,length(name)+1,length(result)); + break; + end; + end; +end; + +function encodestring(const value: msestring; + const encoding: charencodingty = ce_utf8): string; +begin + case encoding of + ce_ascii: begin + result:= stringtopascalstring(value); + end; + ce_utf8: begin + result:= stringtoutf8ansi(value); + end; + ce_iso8859_1: begin + result:= stringtolatin1(value); + end; + else begin //ce_locale + result:= ansistring(value); + end; + end; +end; + +function decodestring(const value: string; + const encoding: charencodingty = ce_utf8): msestring; +begin + case encoding of + ce_ascii: begin + result:= pascalstringtostring(value); + end; + ce_utf8: begin + result:= utf8tostringansi(value); + end; + ce_iso8859_1: begin + result:= latin1tostring(value); + end; + else begin //ce_ansi or current locale + result:= msestring(value); + end; + end; +end; + +function encoderecord(const fields: array of const; + forcequote: boolean = false; const quotechar: msechar = '"'; + const separator: msechar = ','): msestring; +var + int1: integer; + mstr1: msestring; + first: boolean; + seps: msestring; +begin + first:= true; + seps:= msechar(c_return) + msestring(c_linefeed) + msestring(quotechar) + separator; + result:= ''; + for int1:= 0 to high(fields) do begin + mstr1:= ''; + with tvarrec(fields[int1]) do begin + case vtype of + vtInteger: mstr1:= inttostrmse(VInteger); + vtBoolean: if VBoolean then mstr1:= 'T' else mstr1:= 'F'; + vtChar: mstr1:= msestring(VChar); + vtExtended: if not (vextended^ = emptyreal) then begin + mstr1:= doubletostring(VExtended^); + end; + vtString: mstr1:= msestring(VString^); + vtWideChar: mstr1:= VWideChar; + vtPChar: mstr1:= msestring(string(VPChar)); + vtPWideChar: mstr1:= msestring(VPWideChar); + vtAnsiString: mstr1:= msestring(ansistring(VAnsiString)); + vtCurrency: mstr1:= currencytostrmse(VCurrency^); + vtWideString: mstr1:= msestring(VWideString); + {$ifdef mse_hasvtunicodestring} + vtunicodeString: mstr1:= msestring(VunicodeString); + {$endif} + vtInt64: mstr1:= inttostrmse(VInt64^); + end; + end; +// escapechars(mstr1); + if (mstr1 <> '') and (quotechar <> #0) then begin + if forcequote or (findchars(mstr1,seps) <> 0) then begin + mstr1:= quotestring(mstr1,quotechar); + end; + end; + if not first then begin + result:= result + separator + mstr1; + end + else begin + result:= result + mstr1; + end; + first:= false; + end; +end; + +procedure copyvariantarray(const source: array of const; const dest: array of pointer); +var + int1,int2: integer; +begin + int2:= high(source); + if int2 > high(dest) then begin + int2:= high(dest); + end; + for int1:= 0 to int2 do begin + case source[int1].vtype of + vtInteger: pinteger(dest[int1])^:= source[int1].vinteger; + vtBoolean: pboolean(dest[int1])^:= source[int1].VBoolean; + vtChar: pchar(dest[int1])^:= source[int1].VChar; + vtExtended: preal(dest[int1])^:= source[int1].VExtended^; + vtString: pshortstring(dest[int1])^:= source[int1].VString^; + vtWideChar: pwidechar(dest[int1])^:= source[int1].VWideChar; + vtPChar: ppchar(dest[int1])^:= source[int1].VPChar; + vtPWideChar: ppwidechar(dest[int1])^:= source[int1].VPwideChar; + vtAnsiString: pansistring(dest[int1])^:= ansistring(source[int1].VAnsiString); + vtCurrency: pcurrency(dest[int1])^:= source[int1].Vcurrency^; + vtwidestring: pmsestring(dest[int1])^:= msestring(source[int1].VwideString); + {$ifdef mse_hasvtunicodestring} + vtunicodestring: pmsestring(dest[int1])^:= msestring(source[int1].VunicodeString); + {$endif} + vtInt64: pint64(dest[int1])^:= source[int1].Vint64^; + end; + end; +end; + +function getrecordtypechars(const fields: array of const): string; + // b -> boolean + // i -> integer + // I -> int64 + // s -> ansistring + // S -> msestring + // r -> real +var + int1: integer; + ch1: char; +begin + setlength(result,length(fields)); + for int1:= 0 to high(fields) do begin + ch1:= ' '; + case fields[int1].VType of + vtboolean: begin + ch1:= 'b'; + end; + vtinteger: begin + ch1:= 'i'; + end; + vtint64: begin + ch1:= 'I'; + end; + vtansistring: begin + ch1:= 's'; + end; + {$ifdef mse_hasvtunicodestring} + vtunicodestring, + {$endif} + vtwidestring: begin + ch1:= 'S'; + end; + vtextended: begin + ch1:= 'r'; + end; + end; + result[int1+1]:= ch1; + end; +end; + +function decoderecord(const value: msestring; + const fields: array of pointer; const types: string; + // b -> boolean + // i -> integer + // I -> int64 + // s -> ansistring + // S -> msestring + // r -> real + const quotechar: msechar = '"'; + const separator: msechar = ','): boolean; +var + ar1: msestringarty; + int1: integer; +begin + result:= true; + ar1:= nil; + if quotechar <> #0 then begin + splitstringquoted(value,ar1,quotechar,separator); + end + else begin + splitstring(value,ar1,separator); + end; + for int1:= 0 to length(types) - 1 do begin + if int1 > high(fields) then begin + result:= false; + break; + end; + if int1 > high(ar1) then begin + break; + end; +// unescapechars(ar1[int1]); + if fields[int1] <> nil then begin + case types[int1+1] of + ' ': begin + end; + 'b': begin + if ar1[int1] = 'T' then begin + pboolean(fields[int1])^:= true; + end + else begin + pboolean(fields[int1])^:= false; + end; + end; + 'i': begin + result:= result and trystrtoint(ar1[int1],pinteger(fields[int1])^); + end; + 'I': begin + result:= result and trystrtoint64(ar1[int1],pint64(fields[int1])^); + end; + 'r': begin + if ar1[int1] = '' then begin + preal(fields[int1])^:= emptyreal; + end + else begin + result:= result and trystrtoreal(ar1[int1],preal(fields[int1])^); + end; + end; + 's': begin + pstring(fields[int1])^:= ansistring(ar1[int1]); + end; + 'S': begin + pmsestring(fields[int1])^:= ar1[int1]; + end; + else begin + result:= false; + end; + end; + end; + end; +end; + +{ tmsefilestream } + +constructor tmsefilestream.create(ahandle: integer); //allways called +begin + ffilerights:= defaultfilerights; + inherited create(ahandle); +end; + +constructor tmsefilestream.create; +begin + if fmemorystream = nil then begin + fmemorystream:= tmemorystream.create; + end; + fismemorystream:= true; + create(invalidfilehandle); +end; + +constructor tmsefilestream.create(const aopenmode: fileopenmodety); +begin + fopenmode:= aopenmode; + create; +end; + +constructor tmsefilestream.createstringcopy(const adata: string); +begin + fmemorystream:= tstringcopystream.create(adata); + create(fm_read); +end; + +constructor tmsefilestream.internalcreate(const afilename: filenamety; + const aopenmode: fileopenmodety; + const accessmode: fileaccessmodesty; + const rights: filerightsty; + out error: syserrorty); +var + ahandle: integer; +begin + ffilename:= filepath(afilename); + fopenmode:= aopenmode; + if openmode = fm_append then begin + error:= sys_openfile(ffilename,fm_readwrite,accessmode,rights,ahandle); + if error <> sye_ok then begin + error:= sys_openfile(ffilename,fm_create,accessmode,rights,ahandle); + end; + end + else begin + error:= sys_openfile(ffilename,aopenmode,accessmode,rights,ahandle); + end; + create(ahandle); + if error = sye_ok then begin + if aopenmode = fm_append then begin + position:= size; + end; + end + else begin + end; +end; + +class function tmsefilestream.trycreate(out ainstance: tmsefilestream; + const afilename: filenamety; + const aopenmode: fileopenmodety = fm_read; + const accessmode: fileaccessmodesty = []; + const rights: filerightsty = defaultfilerights): syserrorty; +begin + ainstance:= internalcreate(afilename,aopenmode,accessmode,rights,result); + if result <> sye_ok then begin + freeandnil(ainstance); + (* + {$ifdef FPC} + freeandnil(self); + {$else} + application.releaseobject(self); + {$endif} + *) + end; +end; + +function tmsefilestream.releasehandle(): filehandlety; +begin + flushbuffer(); + result:= inherited releasehandle(); +end; + +constructor tmsefilestream.create(const afilename: filenamety; + const aopenmode: fileopenmodety = fm_read; + const accessmode: fileaccessmodesty = []; + const Rights: filerightsty = defaultfilerights); + //!!!!todo linux lock +var + mstr1: msestring; + error: syserrorty; +begin + internalcreate(afilename,aopenmode,accessmode,rights,error); + if error <> sye_ok then begin + mstr1:= ffilename; + ffilename:= ''; + if aopenmode in [fm_create,fm_append] then begin +{$ifdef FPC} + raise EFCreateError.CreateFmt(SFCreateError+lineend+'%s',[mstr1, + sys_geterrortext(mselasterror)]); +{$else} + + {$if rtlversion > 14.1} + raise EFCreateError.CreateResFmt(@SFCreateErrorEx, + [mstr1, sys_geterrortext(mselasterror)]); + {$else} + raise EFCreateError.CreateResFmt(@SFCreateError, + [mstr1, sys_geterrortext(mselasterror)]); + {$ifend} +{$endif} + end + else begin +{$ifdef FPC} + raise EFCreateError.CreateFmt(SFopenError+lineend+'%s',[mstr1, + sys_geterrortext(mselasterror)]); +{$else} + {$if rtlversion > 14.1} + raise EFOpenError.CreateResFmt(@SFOpenErrorEx, + [mstr1,sys_geterrortext(mselasterror)]); + {$else} + raise EFOpenError.CreateResFmt(@SFOpenError, + [mstr1,sys_geterrortext(mselasterror)]); + {$ifend} +{$endif} + end; + end; +end; + +constructor tmsefilestream.createtransaction(const afilename: filenamety; + rights: filerightsty = defaultfilerights); +begin + if afilename = '' then begin + raise exception.create('No transaction name.'); + end; + ftransactionname:= afilename; + create(intermediatefilename(afilename),fm_create,[fa_denywrite],rights); +end; + +constructor tmsefilestream.createtempfile(const prefix: filenamety; + out afilename: filenamety); +begin + application.lock; + try + create(intermediatefilename(msegettempdir+prefix),fm_create,[], + [msesys.s_irusr,msesys.s_iwusr]); + afilename:= filename; + finally + application.unlock; + end; +end; + +destructor tmsefilestream.Destroy; +begin + close; + cryptohandler:= nil; + inherited Destroy; + fmemorystream.Free; +end; + +procedure tmsefilestream.closehandle(const ahandle: integer); +begin + sys_closefile(ahandle); +end; + +procedure tmsefilestream.sethandle(value: integer); +begin + if value <> handle then begin + if handle <> invalidfilehandle then begin + flushbuffer; + closehandle(handle); + end; + fhandle:= value; + end; +end; + +function tmsefilestream.close: boolean; //false on commit error +begin + result:= true; + if fendhandler <> nil then begin + with fendhandler do begin + if ccs_open in fclients[fendindex].state then begin + try + close(fclients[fendindex]); + except + application.handleexception; + end; + end; + end; + end; + if (handle <> invalidfilehandle) and (ftransactionname <> '') and + (ffilename <> '') then begin + flush; + sethandle(invalidfilehandle); + result:= sys_renamefile(ffilename,ftransactionname) = sye_ok; + end + else begin + sethandle(invalidfilehandle); + end; + ffilename:= ''; + ftransactionname:= ''; +end; + +procedure tmsefilestream.cancel; +var + fstr1: filenamety; +begin + if (ftransactionname <> '') and (ffilename <> '') then begin + fstr1:= ffilename; + ftransactionname:= ''; + close; + sys_deletefile(fstr1); + end + else begin + close; + end; +end; + +procedure tmsefilestream.flush; +begin + if fendhandler <> nil then begin + fendhandler.flushchain(fendhandler.fclients[fendindex]); + end; + flushbuffer; + if handle <> invalidfilehandle then begin + syserror(sys_flushfile(handle)); + end; +end; + +function tmsefilestream.isopen: boolean; +begin + result:= handle <> invalidfilehandle; +end; + +function tmsefilestream.Read(var Buffer; Count: longint): Longint; +begin +// if fmemorystream <> nil then begin +// result:= fmemorystream.Read(buffer,count); +// end +// else begin + if fendhandler <> nil then begin + with fendhandler do begin + result:= read(checkopen(fendindex)^,buffer,count); + end; + end + else begin + result:= inheritedread(buffer,count); + end; +// end; +end; + +function tmsefilestream.Write(const Buffer; Count: longint): Longint; +begin +// if fmemorystream <> nil then begin +// result:= fmemorystream.Write(Buffer,count); +// end +// else begin + if fendhandler <> nil then begin + with fendhandler do begin + result:= write(checkopen(fendindex)^,buffer,count); + end; + end + else begin + result:= inheritedwrite(buffer,count); + end; +// end; +end; + +function tmsefilestream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; +begin +// if fmemorystream <> nil then begin +// result:= fmemorystream.Seek(offset,origin); +// end +// else begin + if fendhandler <> nil then begin + with fendhandler do begin + result:= seek(checkopen(fendindex)^,offset,origin); + end; + end + else begin + result:= inheritedseek(offset,origin); + end; +// end; +end; + +function tmsefilestream.getsize: int64; +begin + if fendhandler <> nil then begin + with fendhandler do begin + result:= getsize(checkopen(fendindex)^); + end; + end + else begin + result:= inherited getsize; + end; +end; + +function tmsefilestream.readdatastring: string; +var + int1,int2,int3: sizeint; + lint1,lint2: int64; +begin + if fcryptohandler = nil then begin + if fmemorystream <> nil then begin + result:= fmemorystream.readdatastring; + end + else begin + result:= inherited readdatastring; + end; + end + else begin + if fmemorystream <> nil then begin + lint1:= fmemorystream.size; + end + else begin + lint1:= position; + lint2:= inheritedseek(0,soend); //file size + inheritedseek(lint1,sobeginning); + lint1:= lint2-lint1; + end; + setlength(result,lint1-position); + if result = '' then begin + setlength(result,256); //possibly buffered block + end; + int1:= 0; + while true do begin + int3:= length(result)-int1; + if int3 <= 0 then begin + break; + end; + int2:= read((pchar(pointer(result))+int1)^,int3); + int1:= int1 + int2; + if int2 < int3 then begin + break; + end; + setlength(result,length(result)*2); //grow buffer + end; + setlength(result,int1); + end; +end; + +procedure tmsefilestream.writedatastring(const value: rawbytestring); +begin + if (value <> '') or (fcryptohandler <> nil) then begin + writebuffer(pointer(value)^,length(value)); + end; +end; + +procedure tmsefilestream.SetSize(const NewSize: Int64); +begin + if fmemorystream <> nil then begin + fmemorystream.SetSize(newsize); + end + else begin + inherited; + end; +end; + +{ +function tmsefilestream.getmemory: pointer; +begin + result:= fmemorystream.memory; +end; +} +procedure tmsefilestream.checkmemorystream; +begin + if fmemorystream = nil then begin + raise exception.create('Must be memory stream.'); + end; +end; + +procedure tmsefilestream.clear; +begin + checkmemorystream; + fmemorystream.clear; +end; + +procedure tmsefilestream.flushbuffer; +begin + //dummy +end; + +procedure tmsefilestream.setcryptohandler(const avalue: tcustomcryptohandler); +begin +// if fcryptohandler <> nil then begin +// fcryptohandler.disconnect(self,nil); +// end; + if fendhandler <> nil then begin + try + fendhandler.disconnect(fendindex); + except + application.handleexception; + end; + fendhandler:= nil; + end; + fcryptohandler:= avalue; + if fcryptohandler <> nil then begin + fcryptohandler.connect(self,nil,-1,fendhandler,fendindex); + end; +end; + +function tmsefilestream.inheritedread(var buffer; count: longint): longint; +begin + if fmemorystream <> nil then begin + result:= fmemorystream.Read(buffer,count); + end + else begin + result:= sys_read(fhandle,@buffer,count); + end; + if result < 0 then begin + result:= 0; + end; +end; + +function tmsefilestream.inheritedwrite(const buffer; count: longint): longint; +begin + if fmemorystream <> nil then begin + result:= fmemorystream.Write(Buffer,count); + end + else begin + result:= sys_write(fhandle,@buffer,count); + end; + if result < 0 then begin + result:= 0; + end; +end; + +function tmsefilestream.inheritedseek(const offset: int64; + origin: tseekorigin): int64; +begin + if fmemorystream <> nil then begin + result:= fmemorystream.Seek(offset,origin); + end + else begin + result:= inherited seek(offset,origin); + end; +end; + +function tmsefilestream.inheritedgetsize: int64; +begin + result:= inherited getsize; +end; + +function tmsefilestream.getmemory: pointer; +begin + if fmemorystream <> nil then begin + result:= fmemorystream.memory; + end + else begin + result:= inherited getmemory; + end; +end; + +function tmsefilestream.getfilerights: filerightsty; +var + stat1: fileinfoty; +begin + if (fhandle <> invalidfilehandle) and sys_getfdinfo(fhandle,stat1) then begin + result:= fileattributestofilerights(stat1.extinfo1.attributes); + end + else begin + result:= ffilerights; + end; +end; + +procedure tmsefilestream.setfilerights(const avalue: filerightsty); +begin + ffilerights:= avalue; + if fhandle <> invalidfilehandle then begin + sys_setfdrights(fhandle,avalue,ffilename); + end; +end; + +function tmsefilestream.getcapacity: ptrint; +begin + checkmemorystream(); + result:= fmemorystream.capacity; +end; + +procedure tmsefilestream.setcapacity(const avalue: ptrint); +begin + checkmemorystream(); + fmemorystream.capacity:= avalue; +end; + +{ tresourcefilestream} + +procedure TresourcefileStream.WriteResourceHeader(resourcetyp: word; + const ResName: string; out FixupInfo: Integer); +var + HeaderSize: Integer; + Header: array[0..79] of Char; +begin + Byte((@Header[0])^) := $FF; + Word((@Header[1])^) := resourcetyp; + HeaderSize := StrLen(StrUpper(StrPLCopy(pchar(@Header[3]), ResName, 63))) + 10; + Word((@Header[HeaderSize - 6])^) := $1030; + Longint((@Header[HeaderSize - 4])^) := 0; + WriteBuffer(Header, HeaderSize); + FixupInfo := Position; +end; + +{ tcustombufstream } + +constructor tcustombufstream.Create(AHandle: integer); +begin +// bufoffset:= nil; + buflen:= defaultbuflen; + inherited; +end; + +constructor tcustombufstream.createdata(const adata: rawbytestring); +begin + create; + writedatastring(adata); + position:= 0; +end; + +procedure tcustombufstream.flushbuffer; +var + po1: pointer; +begin + if fwriting then begin + fwriting:= false; + if bufoffset <> nil then begin + po1:= bufoffset; + bufoffset:= nil; + internalwritebuffer(fbuffer^,po1-fbuffer); + end; + end; +end; + +procedure tcustombufstream.fillbuffer(); +begin + if ismemorystream then begin + bufoffset:= bufend; + end + else begin + bufend:= fbuffer + readbytes(fbuffer^); + bufoffset:= fbuffer; + end; +end; + +procedure tcustombufstream.checkbuffer(); +begin + if ismemorystream then begin + bufoffset:= fmemorystream.memory + fmemorystream.position1; + bufend:= fmemorystream.memory + fmemorystream.size1; + end + else begin + if bufoffset = nil then begin //buffer ungueltig + fillbuffer(); + end; + end; +end; + +procedure tcustombufstream.internalwritebuffer(const buffer; count: longint); +var + int1: integer; +begin + int1:= inherited write(buffer,count); + if not ismemorystream and (int1 >= 0) and (fcachedposition >= 0) then begin + fcachedposition:= fcachedposition + int1; + end; + if int1 <> count then begin + raise ewriteerror.create(swriteerror); + end; +end; + +function tcustombufstream.write(const buffer; count: longint): integer; +begin + if ismemorystream then begin + result:= inherited write(buffer,count); + end + else begin + if fusewritebuffer then begin + result:= count; + if fwriting and (bufoffset <> nil) then begin + if buflen - (bufoffset - fbuffer) < count then begin + flushbuffer; + end; + end; + if (bufoffset = nil) then begin + if (buflen > count) then begin + move(buffer,fbuffer^,count); + bufoffset:= fbuffer+count; + fwriting:= true; + end + else begin + result:= inherited write(buffer,count); + if (result >= 0) and (fcachedposition >= 0) then begin + fcachedposition:= fcachedposition + result; + end; + end; + end + else begin + if buflen - (bufoffset - fbuffer) >= count then begin + move(buffer,bufoffset^,count); + bufoffset:= bufoffset+count; + fwriting:= true; + end + else begin + result:= inherited write(buffer,count); + if (result >= 0) and (fcachedposition >= 0) then begin + fcachedposition:= fcachedposition + result; + end; + end; + end + end + else begin + result:= inherited write(buffer,count); + if (result >= 0) and (fcachedposition >= 0) then begin + fcachedposition:= fcachedposition + result; + end; + end; + end; +end; +{ +function tcustombufstream.Write(const Buffer; Count: Integer): Longint; +begin + flushbuffer; + bufoffset:= nil; + result:= inherited write(buffer,count); +end; +} + +procedure tcustombufstream.setbuflen(const Value: integer); +begin + if (fbuflen <> value) and not ismemorystream then begin + flushbuffer; + fbuflen:= value; + if fbuflen < minbuflen then begin + fbuflen:= minbuflen; + end; + setlength(finternalbuffer,fbuflen); + fbuffer:= pointer(finternalbuffer); + bufoffset:= nil; + end; +end; + +function tcustombufstream.readbytes(var buf): integer; +begin + result:= inherited read(buf,fbuflen); + if result > 0 then begin + exclude(fstate,tss_eof); + if not ismemorystream and (fcachedposition >= 0) then begin + fcachedposition:= fcachedposition + result; + end; + end; +end; + +function tcustombufstream.geteof: boolean; +begin + result:= fstate * [tss_eof,tss_notopen,tss_error] <> []; +end; + +function tcustombufstream.getnotopen: boolean; +begin + result:= tss_notopen in fstate; +end; + +procedure tcustombufstream.setusewritebuffer(const avalue: boolean); +begin + if not ismemorystream then begin + flushbuffer; + fusewritebuffer:= avalue; + end; +end; + +function tcustombufstream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; +begin + if ismemorystream then begin + result:= inherited seek(offset,origin); + if (origin <> socurrent) or (offset <> 0) then begin + exclude(fstate,tss_eof); + end; + end + else begin + if (origin = sobeginning) and (bufoffset <> nil) and + (fcryptohandler = nil) then begin + // result:= inherited seek(0,socurrent); + result:= fcachedposition; + if result >= 0 then begin + result:= seek(offset-result+(bufend-bufoffset),socurrent); + end; + end + else begin + if (origin = socurrent) and (offset = 0) then begin + result:= fcachedposition; + // result:= inherited seek(offset,origin); + if (bufoffset <> nil) and (result >= 0) then begin + result:= result + (bufoffset-bufend); + end; + end + else begin + flushbuffer; + if (origin = socurrent) and (bufoffset <> nil) then begin + if (offset < fbuffer - bufoffset) or + (offset >= bufend-bufoffset) then begin + result:= inherited seek(offset-(bufend-bufoffset),origin); + fcachedposition:= result; + bufoffset:= nil; + end + else begin + bufoffset:= bufoffset + offset; + result:= inherited seek(0,socurrent); + fcachedposition:= result; + if result >= 0 then begin + result:= result + (bufoffset-bufend); + end; + end; + end + else begin + result:= inherited seek(offset,origin); + fcachedposition:= result; + bufoffset:= nil; + end; + exclude(fstate,tss_eof); + end; + end; + end; +end; + +procedure tcustombufstream.skip(const adist: integer); +begin + seek(adist,socurrent); +end; + +function tcustombufstream.Read(var Buffer; Count: Longint): Longint; + +//var +// int1: integer; +label + endlab; +begin + if ismemorystream then begin + result:= inherited read(buffer,count); + if result > 0 then begin + exclude(fstate,tss_eof); + end; + goto endlab; + end + else begin + flushbuffer; + if bufoffset = nil then begin + if count >= buflen then begin + result:= inherited read(buffer,count); + if result > 0 then begin + exclude(fstate,tss_eof); + if fcachedposition >= 0 then begin + fcachedposition:= fcachedposition + result; + end; + end; + goto endlab; + end + else begin + fillbuffer; + if bufend = fbuffer then begin + result:= 0; + goto endlab; + end; + end; + end; + result:= bufend-bufoffset; + if result > count then begin + result:= count; + end; + move(bufoffset^,buffer,result); + inc(bufoffset,result); + if result < count then begin + bufoffset:= nil; + if not eof then begin + result:= result + read((pchar(@buffer)+result)^,count-result); + end; + end; + endlab: + if result < count then begin + include(fstate,tss_eof); + end; + end; +end; + +procedure tcustombufstream.clear; +begin + inherited; + fstate:= []; + bufoffset:= nil; + bufend:= nil; +end; + +function tcustombufstream.getbufpo: pchar; +var + int1: integer; +begin + if not ismemorystream and + ((bufoffset = nil) or (bufoffset = bufend)) then begin + int1:= readbytes(fbuffer^); + if int1 > 0 then begin + bufend:= fbuffer + int1; + bufoffset:= fbuffer; + end; + end; + result:= bufoffset; +end; + +procedure tcustombufstream.setsize(const newsize: int64); +begin + if not ismemorystream then begin + flushbuffer; + if fcachedposition > newsize then begin + fcachedposition:= newsize; + end; + bufoffset:= nil; + end; + inherited; +end; + +{ tbufstream } + + +{ ttextstream } + +constructor ttextstream.create(ahandle: integer); +begin + eolstyle:= eol_default; + inherited; +end; + +function ttextstream.readstrln(var value: string): boolean; + //true wenn zeile vollstaendig + +var + {int1,}int2,int3: integer; + gefunden: boolean; + po1,po2,pe: pchar; + +begin + if (tss_eof in fstate) then begin + raise EInOutError.Create(sendoffile); + end; + flushbuffer; + gefunden:= false; + if @value <> nil then begin + setlength(value,0); + end; + checkbuffer(); + fposvorher:= position{ + (bufend - bufoffset)}; + repeat + po1:= nil; + po2:= bufoffset; + pe:= bufend; + while po2 < pe do begin + if po2^ = c_linefeed then begin + include(feolflags,eolf_linefeed); + po1:= po2; + break; + end; + if (po2^ = c_return) then begin + po1:= po2; + break; + end; + inc(po2); + end; + if po1 <> nil then begin + gefunden:= true; + end + else begin + po1:= bufend; + end; + if @value <> nil then begin + int2:= po1-bufoffset; + if int2 > 0 then begin + int3:= length(value); + setlength(value,int3+int2); + move(bufoffset^,value[int3+1],int2); //anhaengen + end; + end; + if po1 = bufend then begin //noch nicht gefunden + fillbuffer; + end; + until gefunden or (bufoffset = bufend); + + if gefunden then begin + bufoffset:= po1; + end + else begin + bufoffset:= bufend; + end; + + if bufoffset < bufend then begin + inc(bufoffset); + if (bufoffset-1)^ = c_return then begin //return-linefeed entfernen + if bufoffset = bufend then begin + fillbuffer; + end; + if bufoffset < bufend then begin + if bufoffset^ = c_linefeed then begin + include(feolflags,eolf_returnlinefeed); + inc(bufoffset); + if bufoffset = bufend then begin + fillbuffer; + end; + end; + end; + end; + end; + if ismemorystream then begin + fmemorystream.position:= bufoffset-fmemorystream.memory; + end; + result:= gefunden; + updatebit({$ifdef FPC}longword{$else}byte{$endif}(fstate), + ord(tss_eof),not result); +end; + +procedure ttextstream.return; +begin + position:= fposvorher; +end; + +procedure ttextstream.writestr(const value: string); +begin + writebuffer(value[1],length(value)); +end; + +function ttextstream.encode(const value: msestring): string; +begin + result:= msestream.encodestring(value,fencoding); +end; + +function ttextstream.decode(const value: string): msestring; +begin + result:= msestream.decodestring(value,fencoding); +end; + +procedure ttextstream.write(const value: string); +begin + if fencoding = ce_locale then begin + writestr(value); + end + else begin + writestr(encode(msestring(value))); + end; +end; + +procedure ttextstream.write(const value: msestring); +begin + writestr(encode(value)); +end; + +procedure ttextstream.write(const value: real); +begin + write(realtostr(value)); +end; + +procedure ttextstream.write(const value: integer); +begin + write(inttostr(value)); +end; + +procedure ttextstream.write(const value: boolean); +begin + write(booltostr(value)); +end; + +procedure ttextstream.write(const values: array of const); +var + int1: integer; +begin + for int1:= 0 to high(values) do begin + with tvarrec(values[int1]) do begin + case vtype of + vtInteger: write(VInteger); +// vtBoolean : (VBoolean: Boolean); + vtChar: write(string(VChar)); + vtWideChar: write(msestring(VWideChar)); + vtExtended: write(VExtended^); + vtString: write(VString^); +// vtPointer : (VPointer: Pointer); + vtPChar: write(string(VPChar)); +// vtObject : (VObject: TObject); +// vtClass : (VClass: TClass); + vtPWideChar: write(msestring(VPWideChar)); + vtAnsiString: write(string(VAnsiString)); + vtCurrency: write(VCurrency^); + vtVariant: write(msestring(VVariant^)); +// vtInterface : (VInterface: Pointer); + vtWideString: write(msestring(widestring(VWideString))); +// vtInt64 : (VInt64: PInt64); + vtUnicodeString: write(msestring(unicodestring(VUnicodeString))); +// vtQWord : (VQWord: PQWord); + end; + end; + end; +end; + +procedure ttextstream.writeln(const values: array of const); +begin + write(values); + write(feol); +end; + +procedure ttextstream.writestrln(const value: string); +begin + write(value); + write(feol); +end; + +procedure ttextstream.writeln; +begin + write(feol); +end; + +procedure ttextstream.writeln(const value: string); +begin + write(value); + write(feol); +end; + +procedure ttextstream.writeln(const value: msestring); +begin + write(value); + write(feolm); +end; + +procedure ttextstream.writeln(const value: real); +begin + writestrln(realtostr(value)); +end; + +procedure ttextstream.writeln(const value: integer); +begin + writestrln(inttostr(value)); +end; + +procedure ttextstream.writeln(const value: boolean); +begin + writestrln(booltostr(value)); +end; + +procedure ttextstream.writeln(const value: msestringarty); +var + int1: integer; +begin + writeln(length(value)); + for int1:= 0 to high(value) do begin + writeln(value[int1]); + end; +end; + +procedure ttextstream.writeln(const value: stringarty); +var + int1: integer; +begin + writeln(length(value)); + for int1:= 0 to high(value) do begin + writeln(string(value[int1])); + end; +end; + +function ttextstream.readln: boolean; +var + str1: string; +begin + result:= readstrln(str1); +end; + +function ttextstream.readln(var value: string): boolean; +begin + result:= readstrln(value); + if fencoding <> ce_locale then begin + value:= ansistring(decode(value)); + end; +end; + +function ttextstream.readln(var value: msestring): boolean; +var + str1: string; +begin + result:= readstrln(str1); + value:= decode(str1); +end; + +function ttextstream.readln(out value: integer): boolean; +var + str1: string; +begin + result:= readstrln(str1); + value:= strtoint(str1); +end; + +function ttextstream.readln(out value: boolean): boolean; +var + str1: string; +begin + result:= readstrln(str1); + value:= strtobool(str1); +end; + +function ttextstream.readln(out value: real): boolean; +var + str1: string; +begin + result:= readstrln(str1); + value:= strtoreal(str1); +end; + +function ttextstream.readln(out value: msestringarty): boolean; +var + str1: string; + mstr1: msestring; + int1: integer; +begin + result:= readstrln(str1); + if result then begin + int1:= strtoint(str1); + end + else begin + int1:= 0; + end; + setlength(value,int1); + for int1:= 0 to int1-1 do begin + if not result then begin + exit; + end; + result:= readln(mstr1); + value[int1]:= mstr1; + end; +end; + +function ttextstream.readln(out value: stringarty): boolean; +var + str1: string; + int1: integer; +begin + result:= readstrln(str1); + if result then begin + int1:= strtoint(str1); + end + else begin + int1:= 0; + end; + setlength(value,int1); + for int1:= 0 to int1-1 do begin + if not result then begin + exit; + end; + result:= readln(str1); + value[int1]:= str1; + end; +end; + +function ttextstream.readinteger(default: integer; min: integer = minint; + max: integer = maxint): integer; + //liest integer, bringt defaultwert bei fehler +begin + try + readln(result); + if (result < min) then begin + result:= min; + end + else begin + if result > max then begin + result:= max; + end; + end; + except + result:= default; + end; +end; + +function ttextstream.readboolean(default: boolean): boolean; + //liest boolean, bringt defaultwert bei fehler +begin + try + readln(result); + except + result:= default; + end; +end; + +function ttextstream.readreal(default: real; min: real = -bigreal; + max: real = bigreal): real; +begin + try + readln(result); + if (result < min) then begin + result:= min; + end + else begin + if result > max then begin + result:= max; + end; + end; + except + result:= default; + end; +end; + +function ttextstream.readstring(const default: string): string; +begin + try + readln(result); + except + result:= default; + end; +end; + +function ttextstream.findnext(const substring: string): boolean; +var + buffer: string; + int1,len,posstart,posvorher: integer; +begin + len:= length(substring); + result:= false; + posstart:= position; + if len > 0 then begin + setlength(buffer,len); + while true do begin + posvorher:= position; + int1:= read(buffer[1],len); + if int1 < len then begin + position:= posstart; + break; + end; + if buffer = substring then begin + position:= posvorher; + result:= true; + break; + end; + int1:= pos(substring[1],buffer); + if int1 > 0 then begin + position:= posvorher + int1; + end; + end; + end; +end; + +function ttextstream.linecount: integer; +var + po1: ^string; +begin + result:= 0; + po1:= nil; + while readln(string(po1^)) do begin + inc(result); + end; +end; + +function ttextstream.foundeolstyle: eolstylety; +begin + result:= eol_default; + if eolf_linefeed in feolflags then begin + result:= eol_unix; + end; + if eolf_returnlinefeed in feolflags then begin + result:= eol_windows; + end; +end; + +procedure ttextstream.resetsearch; +begin + fsearchlinestartpos:= 0; + fsearchlinenumber:= 0; + fsearchpos:= 0; + fsearchfoundpos:= 0; +end; + +procedure ttextstream.setsearchtext(const Value: string); +begin + fsearchtext := Value; + fsearchtextvalid:= false; +end; + +function ttextstream.getmsesearchtext: msestring; +begin + result:= decode(fsearchtext); +end; + +procedure ttextstream.setmsesearchtext(const avalue: msestring); +begin + setsearchtext(encode(avalue)); +end; + +procedure ttextstream.setsearchoptions(const Value: searchoptionsty); +begin + fsearchoptions := Value; + fsearchtextvalid:= false; +end; + +procedure ttextstream.seteolstyle(const avalue: eolstylety); +begin + case avalue of + eol_unix: begin + feol:= unixeol; + end; + eol_windows: begin + feol:= windowseol; + end; + else begin + feol:= syseol; + end; + end; + feolm:= msestring(feol); +end; + +function ttextstream.searchnext: boolean; +var + bo1: boolean; + ca1: longword; + str1: string; +begin + Position:= fsearchpos; + bo1:= true; + if (so_caseinsensitive in fsearchoptions) and not fsearchtextvalid then begin + fsearchtextupper:= ansiuppercase(fsearchtext); + fsearchtextlower:= ansilowercase(fsearchtext); + fsearchtextvalid:= true; + end; + repeat + if not bo1 then begin + fsearchlinestartpos:= position; + fsearchpos:= fsearchlinestartpos; + inc(fsearchlinenumber); + end + else begin + bo1:= false; + end; +// readln(str1); + readstrln(str1); //no encoding + if so_caseinsensitive in fsearchoptions then begin + ca1:= stringsearch(fsearchtextupper,str1,1,fsearchoptions,fsearchtextlower); + end + else begin + ca1:= stringsearch(fsearchtext,str1,1,fsearchoptions,''); + end; + until (ca1 <> 0) or eof or ((fsearchabortpo <> nil) and fsearchabortpo^); + if ca1 <> 0 then begin + fsearchfoundpos:= fsearchpos + ca1 - 1; + result:= true; + end + else begin + result:= false; + fsearchfoundpos:= Position; + end; + fsearchpos:= fsearchfoundpos + longword(length(fsearchtext)); +end; + +function ttextstream.readstrings: stringarty; +var + int1: integer; + str1: string; +begin + int1:= 0; + result:= nil; + while not eof do begin + if not readln(str1) and (str1 = '') then begin + break; + end; + additem(result,str1,int1); + end; + setlength(result,int1); +end; + +function ttextstream.readmsestrings: msestringarty; +var + int1: integer; + mstr1: msestring; +begin + int1:= 0; + result:= nil; + while not eof do begin + if not readln(mstr1) and (mstr1 = '') then begin + break; + end; + additem(result,mstr1,int1); + end; + setlength(result,int1); +end; + +function ttextstream.readmsedatastring: msestring; //returns remainig data +begin + result:= decode(readdatastring); +end; + +procedure ttextstream.writestrings(const value: stringarty); +var + int1: integer; +begin + for int1:= 0 to high(value) do begin + writeln(string(value[int1])); + end; +end; + +procedure ttextstream.writemsestrings(const value: msestringarty); +var + int1: integer; +begin + for int1:= 0 to high(value) do begin + writeln(value[int1]); + end; +end; + +procedure ttextstream.writetotext(var dest: text); +var + str1: string; +begin + while not eof do begin + readstrln(str1); + system.writeln(dest,str1); + end; +end; + +class function ttextstream.trycreate(out ainstance: ttextstream; + const afilename: filenamety; + const aopenmode: fileopenmodety = fm_read; + const accessmode: fileaccessmodesty = []; + const rights: filerightsty = defaultfilerights): syserrorty; +begin + result:= inherited trycreate(tmsefilestream(ainstance),afilename,aopenmode, + accessmode,rights); +end; + +{ ttextdatastream } + +constructor ttextdatastream.create(ahandle: integer); +begin + fseparator:= ','; + fquotechar:= '"'; + inherited; +end; + +procedure ttextdatastream.writerecord(const fields: array of const); +begin + writeln(encoderecord(fields,fforcequote,fquotechar,fseparator)); +end; + +procedure ttextdatastream.writerecord(const fields: msestringarty); +var + ar1: varrecarty; + int1: integer; +begin + setlength(ar1,length(fields)); + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + {$ifdef mse_hasvtunicodestring} + vtype:= vtunicodestring; + vunicodestring:= pointer(fields[int1]); + {$else} + vtype:= vtwidestring; + vwidestring:= pointer(fields[int1]); + {$endif} + end; + end; + writerecord(ar1); +end; + +procedure ttextdatastream.writerecord(const fields: stringarty); +var + ar1: varrecarty; + int1: integer; +begin + setlength(ar1,length(fields)); + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + vtype:= vtansistring; + vansistring:= pointer(fields[int1]); + end; + end; + writerecord(ar1); +end; + +procedure ttextdatastream.writerecord(const fields: integerarty); +var + ar1: varrecarty; + int1: integer; +begin + setlength(ar1,length(fields)); + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + vtype:= vtinteger; + vinteger:= fields[int1]; + end; + end; + writerecord(ar1); +end; + +procedure ttextdatastream.writerecord(const fields: realarty); +var + ar1: varrecarty; + ar2: array of extended; + int1: integer; +// ext1: extended; +begin + setlength(ar1,length(fields)); + setlength(ar2,length(fields)); + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + ar2[int1]:= fields[int1]; + vtype:= vtextended; + vextended:= @ar2[int1]; + end; + end; + writerecord(ar1); +end; + +procedure ttextdatastream.writerecord(const fields: int64arty); +var + ar1: varrecarty; + int1: integer; +begin + setlength(ar1,length(fields)); + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + vtype:= vtint64; + vint64:= @fields[int1]; + end; + end; + writerecord(ar1); +end; + +procedure ttextdatastream.writerecord(const fields: booleanarty); +var + ar1: varrecarty; + int1: integer; +begin + setlength(ar1,length(fields)); + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + vtype:= vtboolean; + vboolean:= fields[int1]; + end; + end; + writerecord(ar1); +end; + +function ttextdatastream.readcsvstring(out value: msestring): boolean; +var + mstr2: msestring; +begin + result:= readln(value); + if odd(countchars(value,fquotechar)) then begin + while not eof do begin + result:= readln(mstr2); + value:= value+lineend+mstr2; + if odd(countchars(mstr2,fquotechar)) then begin + break; + end; + end; + end; +end; + +function ttextdatastream.readrecord(fields: array of pointer; types: string): boolean; + // b -> boolean + // i -> integer + // I -> int64 + // s -> ansistring + // S -> msestring + // r -> real +var + mstr1: msestring; +begin + result:= false; + if not (not readcsvstring(mstr1) and (mstr1 = '') and eof) then begin + //check terminating linefeed + result:= decoderecord(mstr1,fields,types,fquotechar,fseparator); + end; +end; + +function ttextdatastream.readcsvvalues(out values: msestringarty): boolean; +var + mstr1: msestring; +begin + result:= readcsvstring(mstr1); + splitstringquoted(mstr1,values,fquotechar,fseparator); +end; + +{ tcryptfilestream } + +constructor tcryptfilestream.Create(const aFileName: string; Mode: Word); +const + schluessel = $51b2; +var + wo1: word; + int1: integer; +begin + inherited; + if mode = fmcreate then begin + int1:= integer(kryptsignatur); + writebuffer(int1,4); + randomize; + repeat + wo1:= random($ffff); + until wo1 <> 0; + seed:= wo1; + wo1:= wo1 xor schluessel; + writebuffer(wo1,2); + end + else begin + readbuffer(int1,4); + if int1 <> integer(kryptsignatur) then begin + raise exception.create(afilename + ' falsches Dateiformat!'); + end; + readbuffer(seed,2); + seed:= seed xor schluessel; + end; + schluesseln:= true; +end; + +function tcryptfilestream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; +begin + result:= 0; //compiler warning + raise exception.create('seek nicht erlaubt!'); +end; + +procedure tcryptfilestream.krypt16(var buffer; count: integer); +const + crcpolynom = $a001; +var + int1,int2: integer; + bo1: boolean; + bytepo: ^byte; +begin + bytepo:= @buffer; + for int2:= count-1 downto 0 do begin + for int1:= 0 to 7 do begin + bo1:= odd(seed); + seed:= seed shr 1; + if bo1 then begin + seed:= seed xor crcpolynom; + end; + end; + bytepo^:= bytepo^ xor seed; + inc(bytepo); + end; +end; + +function tcryptfilestream.Read(var Buffer; Count: Integer): Longint; +begin + result:= inherited read(buffer,count); + if schluesseln then begin + krypt16(buffer,result); + end; +end; + +function tcryptfilestream.Write(const Buffer; Count: Integer): Longint; +var + po: pointer; +begin + if schluesseln then begin + po:= @byte(buffer); + krypt16(po^,count); + end; + result:= inherited write(buffer,count); +end; + +{ tstringcopystream } + +constructor tstringcopystream.create(const adata: string); +begin + fdata:= adata; + inherited create({fm_create}); + if adata <> '' then begin + setpointer(pointer(adata),length(adata)); + end; +end; + +destructor tstringcopystream.destroy; +begin + setpointer(nil,0); + inherited; +end; + +function tstringcopystream.write(const Buffer; Count: Longint): Longint; +begin + result:= 0; +end; + +function tstringcopystream.readdatastring: string; +begin + if position = 0 then begin + result:= fdata; + end + else begin + result:= inherited readdatastring; + end; +end; + +function tstringcopystream.getmemory: pointer; +begin + result:= pointer(fdata); +end; + +{ ttextstringcopystream } + +constructor ttextstringcopystream.create(const adata: string); +begin + fdata:= adata; + inherited create(fm_read); + if adata <> '' then begin + tmemorystream1(fmemorystream).setpointer(pointer(adata),length(adata)); + end; +end; + +destructor ttextstringcopystream.destroy; +begin + tmemorystream1(fmemorystream).setpointer(nil,0); + inherited; +end; + +function ttextstringcopystream.write(const Buffer; Count: Longint): Longint; +begin + result:= 0; +end; + +function ttextstringcopystream.getmemory: pointer; +begin + result:= pointer(fdata); +end; + +{ tmemorycopystream } + +constructor tmemorycopystream.create(const adata: pointer; const asize: integer); +begin + inherited create; + setpointer(adata,asize); +end; + +destructor tmemorycopystream.destroy; +begin + setpointer(nil,0); + inherited; +end; + +function tmemorycopystream.write(const Buffer; Count: Longint): Longint; +begin + result:= 0; +end; + +{ tcustomcryptohandler } + +destructor tcustomcryptohandler.destroy; +var + int1: integer; +begin + for int1:= 0 to high(fclients) do begin + chain:= nil; + with fclients[int1] do begin + if (stream <> nil) then begin + if link = nil then begin + with stream do begin + fcryptohandler:= nil; + fendhandler:= nil; +// fcryptoindex:= -1; + end; + end + else begin + link.fchain:= nil; + end; + finalizeclient(fclients[int1]); +// stream:= nil; + end; + end; + end; + inherited; +end; + +procedure tcustomcryptohandler.finalizeclient(var aclient: cryptoclientinfoty); +begin + with aclient do begin + stream:= nil; + end; +end; + +procedure tcustomcryptohandler.connect(const aclient: tmsefilestream; + const alink: tcustomcryptohandler; + const aindex: integer; + out endhandler: tcustomcryptohandler; out endindex: integer); +var + int1,int2,int3: integer; +// ha1: tcustomcryptohandler; +begin + int3:= high(fclients); + int2:= int3+1; + for int1:= 0 to int3 do begin + if fclients[int1].stream = nil then begin + int2:= int1; + break; + end; + end; + if int2 > int3 then begin + setlength(fclients,int2+1); + end; + endindex:= int2; + endhandler:= self; + fillchar(fclients[int2],sizeof(fclients[0]),0); + with fclients[int2] do begin + stream:= aclient; + link:= alink; + linkindex:= aindex; +// state:= []; + end; + if fchain <> nil then begin + fchain.connect(aclient,self,int2,endhandler,endindex); + end; +end; + +procedure tcustomcryptohandler.disconnect({const aclient: tmsefilestream; + const alink: tcustomcryptohandler;} const aindex: integer); +var + po1: pcryptoclientinfoty; +// int1: integer; +begin + po1:= @fclients[aindex]; + with po1^ do begin + if ccs_open in state then begin + close(po1^); + end; + if link <> nil then begin + link.disconnect(linkindex); + end; + finalizeclient(po1^); + end; +(* + if alink = nil then begin + po1:= @fclients[aclient.fcryptoindex]; + with po1^ do begin + if ccs_open in state then begin + close(po1^); + end; + stream:= nil; + end; + fendhandler:= nil; +// aclient.fcryptoindex:= -1; + end + else begin + for int1:= 0 to high(fclients) do begin + with fclients[int1] do begin + if stream = aclient then begin + finalizeclient(fclients[int1]); +// stream:= nil; + end; + end; + end; + if fchain <> nil then begin + fchain.disconnect(aclient,self); + end; + end; + *) +end; + +function tcustomcryptohandler.read(var aclient: cryptoclientinfoty; var buffer; + count: longint): longint; +begin + with aclient do begin + if link = nil then begin + result:= stream.inheritedread(buffer,count); + end + else begin + result:= link.read(link.fclients[linkindex],buffer,count); + end; + end; +end; + +function tcustomcryptohandler.write(var aclient: cryptoclientinfoty; + const buffer; count: longint): longint; +begin + with aclient do begin + if link = nil then begin + result:= stream.inheritedwrite(buffer,count); + end + else begin + result:= link.write(link.fclients[linkindex],buffer,count); + end; + end; +end; + +function tcustomcryptohandler.seek(var aclient: cryptoclientinfoty; + const offset: int64; origin: tseekorigin): int64; +begin + with aclient do begin + if link = nil then begin + result:= stream.inheritedseek(offset,origin); + end + else begin + result:= link.seek(link.fclients[linkindex],offset,origin); + end; + end; +end; + +function tcustomcryptohandler.getsize(var aclient: cryptoclientinfoty): int64; +begin + with aclient do begin + if link = nil then begin + result:= stream.inheritedgetsize; + end + else begin + result:= link.getsize(link.fclients[linkindex]); + end; + end; +end; + +procedure tcustomcryptohandler.open(var aclient: cryptoclientinfoty); +begin + with aclient do begin + include(state,ccs_open); + if link <> nil then begin + link.open(link.fclients[linkindex]); + end; + end; +end; + +procedure tcustomcryptohandler.close(var aclient: cryptoclientinfoty); +begin + with aclient do begin + exclude(state,ccs_open); + if link <> nil then begin + link.close(link.fclients[linkindex]); + end; + end; +end; + +function tcustomcryptohandler.checkopen( + const aindex: integer): pcryptoclientinfoty; +begin + result:= @fclients[aindex]; + with result^ do begin + if not (ccs_open in state) then begin + self.open(result^); + end; + end; +end; + +function tcustomcryptohandler.encrypt(const adata: pointer; + adatalength: integer; const base64: boolean = false; + const maxlinelength: integer = defaultbase64linelength): string; +var + stream1: tmsefilestream; +// str1: string; +begin + stream1:= tmsefilestream.create(fm_write); + try + stream1.cryptohandler:= self; + stream1.write(adata^,adatalength); + stream1.cryptohandler:= nil; //flush + with stream1.fmemorystream do begin + if base64 then begin + result:= encodebase64(memory,size,maxlinelength); + end + else begin + setlength(result,size); + move(memory^,pointer(result)^,length(result)); + end; + end; + finally + stream1.free; + end; +end; + +function tcustomcryptohandler.decrypt(const adata: string; + const base64: boolean = false): string; +var + stream1: ttextstringcopystream; + int1: integer; +begin + if base64 then begin + stream1:= ttextstringcopystream.create(decodebase64(adata)); + end + else begin + stream1:= ttextstringcopystream.create(adata); + end; + try + stream1.cryptohandler:= self; + setlength(result,length(adata)); + int1:= stream1.read(pointer(result)^,length(result)); + setlength(result,int1); + finally + stream1.free; + end; +end; + +function tcustomcryptohandler.encrypt(const adata: string; + const base64: boolean = false; + const maxlinelength: integer = defaultbase64linelength): string; +begin + result:= encrypt(pointer(adata),length(adata),base64,maxlinelength); +end; + +function tcustomcryptohandler.encrypttext(const atext: msestring; + const base64: boolean = false; + const maxlinelength: integer = defaultbase64linelength): string; +begin + result:= encrypt(stringtoutf8ansi(atext),base64,maxlinelength); +end; + +function tcustomcryptohandler.decrypttext(const adata: string; + const base64: boolean = false): msestring; +begin + result:= utf8tostringansi(decrypt(adata,base64)); +end; + +procedure tcustomcryptohandler.setchain(const avalue: tcustomcryptohandler); + + procedure removechain(const ha: tcustomcryptohandler; + const stre: tmsefilestream); + var + int1: integer; + begin + if ha <> nil then begin + with ha do begin + for int1:= 0 to high(fclients) do begin + with fclients[int1] do begin + if stream = stre then begin + stream:= nil; + end; + end; + end; + removechain(ha.chain,stre); + end; + end; + end; + +var + ha1: tcustomcryptohandler; + int1: integer; +begin + ha1:= avalue; + while ha1 <> nil do begin + if ha1 = self then begin + componentexception(self,'Recursive handler chain.'); + end; + ha1:= ha1.chain; + end; + if fchain <> nil then begin + with fchain do begin + for int1:= 0 to high(fclients) do begin + with fclients[int1] do begin + if (stream <> nil) and (link = self) then begin + removechain(fchain,stream); + stream:= nil; + end; + end; + end; + end; + end; + setlinkedvar(avalue,tmsecomponent(fchain)); +end; + +function tcustomcryptohandler.getclient( + const astream: tmsefilestream): pcryptoclientinfoty; +var + ha1: tcustomcryptohandler; + int1: integer; +begin + result:= nil; + ha1:= astream.fendhandler; + int1:= astream.fendindex; + while ha1 <> nil do begin + if ha1 = self then begin + result:= @fclients[int1]; + break; + end; + with ha1.fclients[int1] do begin + ha1:= link; + int1:= linkindex; + end; + end; + if result = nil then begin + componentexception(self,'Client stream not found.'); + end; +end; + +procedure tcustomcryptohandler.writeerror(var aclient: cryptoclientinfoty); +begin + raise ewriteerror.create(swriteerror); +end; + +procedure tcustomcryptohandler.readerror(var aclient: cryptoclientinfoty); +begin + raise ereaderror.create(sreaderror); +end; + +procedure tcustomcryptohandler.flush(var aclient: cryptoclientinfoty); +begin + //dummy +end; + +procedure tcustomcryptohandler.flushchain(var aclient: cryptoclientinfoty); +begin + if ccs_open in aclient.state then begin + flush(aclient); + with aclient do begin + if link <> nil then begin + link.flush(link.fclients[linkindex]); + end; + end; + end; +end; + +procedure tcustomcryptohandler.flush(const astream: tmsefilestream); +var + po1: pcryptoclientinfoty; +begin + po1:= getclient(astream); + if ccs_open in po1^.state then begin + flush(po1^); + end; +end; + +{ tstringbufferstream } + +constructor tstringbufferstream.create(const adata: string); +begin + inherited create(); + fdata:= adata; + setpointer(pointer(fdata),length(fdata)); +end; + +function tstringbufferstream.getdata: string; +begin + capacity:= size; + result:= fdata; +end; + +function tstringbufferstream.realloc(var newcapacity: ptrint): pointer; +begin + if newcapacity > length(fdata) then begin + newcapacity:= 2*newcapacity + 256; + end; + setlength(fdata,newcapacity); + result:= pointer(fdata); +end; + +{ ttextstringbufferstream } + +constructor ttextstringbufferstream.create(const adata: string; + const aopenmode: fileopenmodety = fm_create); +begin + fmemorystream:= tstringbufferstream.create(adata); + inherited create(aopenmode); +end; + +function ttextstringbufferstream.getdata: string; +begin + result:= tstringbufferstream(fmemorystream).data; +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/msestreaming.pas b/mseide-msegui/lib/common/kernel/msestreaming.pas new file mode 100644 index 0000000..f2c2bbf --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msestreaming.pas @@ -0,0 +1,370 @@ +{ MSEgui Copyright (c) 1999-2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msestreaming; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,msetypes,msegraphutils,mseglob; + +type + tasinheritedreader = class; + tasinheritedobjectreader = class(tbinaryobjectreader) + protected +// freader: tasinheritedreader; + procedure findexistingcomponent(child: tcomponent); + public + procedure begincomponent(var flags: tfilerflags; var achildpos: integer; + var compclassname, compname: string); override; + public + constructor create(const areader: tasinheritedreader; const stream: tstream; + const bufsize: integer); + end; + + tasinheritedreader = class(treader) + private + fnewcomp: boolean; + protected + fforceinherited: boolean; + fexistingcomp: tcomponent; + fexistingcompname: string; + function createdriver(stream: tstream; + bufsize: integer): tabstractobjectreader; override; + public + constructor Create(Stream: TStream; BufSize: Integer; + const forceinherited: boolean); + property existingcomp: tcomponent read fexistingcomp; + property newcomp: boolean read fnewcomp write fnewcomp; + end; + +function readshortcutarty(const reader: treader): shortcutarty; +procedure writeshortcutarty(const writer: twriter; const avalue: shortcutarty); +function readrealty(const reader: treader): realty; +//procedure writerealty(const writer: twriter; const value: realty); +function readrectty(const reader: treader): rectty; +procedure writerectty(const writer: twriter; const avalue: rectty); +function readmethod(const reader: treader): tmethod; + +function readrecordcount(const obj: tpersistent; + const recordsize: integer; const stream: tstream): integer; + //erzeugt exception bei ungueltiger laenge; +procedure readrecords(const count,size: integer; const stream: tstream; out data); +procedure writerecords(const count,size: integer; const stream: tstream; const data); + +procedure assignpersistent(source,dest: tpersistent); + //uebertraegt alle published eigenschaften +procedure assigncomponent(source,dest: tcomponent); + //uebertraegt alle published eigenschaften +procedure writecomponentmse(const astream: tstream; const acomp: tcomponent); + +implementation +uses + sysutils,msereal,mseact,mseclasses,msestrings; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +type + tcomponent1 = class(tcomponent); + +{ +function findexistingcomponent(const aname: string; + const aclassname: string; + const areader: tasinheritedreader): boolean; +var + comp1: tcomponent; + ar1: componentarty; + int1: integer; +begin + areader.fexistingcomp:= nil; + comp1:= areader.parent; + if comp1 = nil then begin + comp1:= areader.lookuproot; + end; + if comp1 <> nil then begin + ar1:= getcomponentchildren(comp1,areader.root,true); + for int1:= 0 to high(ar1) do begin + if (ar1[int1].name = aname) and (ar1[int1].classname = aclassname) then begin + areader.fexistingcomp:= ar1[int1]; + break; + end; + end; + end; + result:= areader.fexistingcomp <> nil; +// result:= (areader.lookuproot = nil) or +// (areader.lookuproot.findcomponent(aname) <> nil); +end; +} + +{ tasinheritedobjectreader } + +constructor tasinheritedobjectreader.create(const areader: tasinheritedreader; + const stream: tstream; const bufsize: integer); +begin + freader:= areader; + inherited create(stream,bufsize); +end; + +procedure tasinheritedobjectreader.findexistingcomponent(child: tcomponent); +begin + if (tasinheritedreader(freader).fexistingcomp = nil) and + (stringicompupper(child.name, + tasinheritedreader(freader).fexistingcompname) = 0) then begin + tasinheritedreader(freader).fexistingcomp:= child; + end; +end; + +procedure tasinheritedobjectreader.begincomponent(var flags: tfilerflags; + var achildpos: Integer; var compclassName, compname: string); +var + comp1: tcomponent; +begin + inherited; + tasinheritedreader(freader).fexistingcomp:= nil; + if (tasinheritedreader(freader).lookuproot = nil) or + tasinheritedreader(freader).fforceinherited then begin + include(flags,ffinherited); + end + else begin + comp1:= freader.parent; + tasinheritedreader(freader).fexistingcomp:= nil; + tasinheritedreader(freader).fexistingcompname:= struppercase(compname); + while (tasinheritedreader(freader).fexistingcomp = nil) and (comp1 <> nil) do begin + tcomponent1(freader.parent).getchildren( + {$ifdef FPC}@{$endif}findexistingcomponent,comp1); + if comp1 = freader.root then begin + break; + end; + comp1:= comp1.owner; + end; + if tasinheritedreader(freader).fexistingcomp = nil then begin + tasinheritedreader(freader).fexistingcomp:= freader.lookuproot.findcomponent(compname); + end; + exclude(flags,ffinherited); + if tasinheritedreader(freader).fexistingcomp <> nil then begin + include(flags,ffinherited); + end; + end; +end; + +{ tasinheritedreader } + +constructor tasinheritedreader.Create(Stream: TStream; BufSize: Integer; + const forceinherited: boolean); +begin + fforceinherited:= forceinherited; + inherited create(stream,bufsize); +end; + +function tasinheritedreader.createdriver(stream: tstream; + bufsize: integer): tabstractobjectreader; +begin + result:= tasinheritedobjectreader.create(self,stream, bufsize); +end; + +type + treader1 = class(treader); + twriter1 = class(twriter); + +procedure writecomponentmse(const astream: tstream; const acomp: tcomponent); +var + writer1: twritermse; +begin + writer1:= twritermse.create(astream,4096,false); + try + writer1.writerootcomponent(acomp); + finally + writer1.free; + end; +end; + +function readshortcutarty(const reader: treader): shortcutarty; +var + int1: integer; +begin + reader.readlistbegin; + setlength(result,reader.readinteger); + for int1:= 0 to high(result) do begin + result[int1]:= reader.readinteger; + translateshortcut1(result[int1]); + end; + reader.readlistend; +end; + +procedure writeshortcutarty(const writer: twriter; const avalue: shortcutarty); +var + int1: integer; +begin + writer.writelistbegin; + writer.writeinteger(length(avalue)); + for int1:= 0 to high(avalue) do begin + writer.writeinteger(avalue[int1]); + end; + writer.writelistend; +end; + +function readrealty(const reader: treader): realty; +begin + with reader do begin + if nextvalue = valist then begin + readlistbegin; + result:= readfloat; + if readboolean then begin + result:= emptyreal; + end; + readlistend; + end + else begin + result:= readfloat; + end; + end; +end; + +procedure writerealty(const writer: twriter; const value: realty); +begin + with writer do begin + if value = emptyreal then begin + writelistbegin; + writefloat(0.0); + writeboolean(true); + writelistend; + end + else begin + writefloat(value); + end; + end; +end; + +function readrectty(const reader: treader): rectty; +begin + with reader,result do begin + readlistbegin; + x:= readinteger; + y:= readinteger; + cx:= readinteger; + cy:= readinteger; + readlistend; + end; +end; + +procedure writerectty(const writer: twriter; const avalue: rectty); +begin + with writer,avalue do begin + writelistbegin; + writeinteger(x); + writeinteger(y); + writeinteger(cx); + writeinteger(cy); + writelistend; + end; +end; + +function readmethod(const reader: treader): tmethod; +var + str1: string; +begin + with treader1(reader) do begin + if nextvalue = vanil then begin + result.code:= nil; + result.data:= nil; + readident; + end + else begin + str1:= readident; + result.code:= findmethod(root,str1); + result.data:= root; + end; + end; +end; + +function readrecordcount(const obj: tpersistent; + const recordsize: integer; const stream: tstream): integer; + //erzeugt exception bei ungueltiger laenge; +var + bytecount: longint; +begin + stream.ReadBuffer(bytecount,sizeof(bytecount)); + if bytecount mod recordsize <> 0 then begin + raise ereaderror.Create(obj.GetNamePath+' readrecorderror.'); + end; + result:= bytecount div recordsize; +end; + +procedure readrecords(const count,size: integer; const stream: tstream; out data); +begin + stream.ReadBuffer(data,count*size); +end; + +procedure writerecords(const count,size: integer; const stream: tstream; const data); +var + bytecount: longint; +begin + bytecount:= count*size; + stream.WriteBuffer(bytecount,sizeof(bytecount)); + stream.WriteBuffer(data,bytecount); +end; + +procedure assignpersistent(source,dest: tpersistent); +var + writer: twritermse; + reader: treader; + stream: tmemorystream; +begin + writer:= nil; + reader:= nil; + stream:= tmemorystream.Create; + try + writer:= twritermse.Create(stream,1024,false); + writer.WriteListBegin; +{$warnings off} + twriter1(writer).WriteProperties(source); +{$warnings on} + writer.WriteListEnd; + freeandnil(writer); + stream.Position:= 0; + reader:= treader.Create(stream,1024); + reader.ReadListBegin; + while not reader.endoflist do begin + treader1(reader).Readproperty(dest); + end; + finally + reader.free; + writer.free; + stream.Free; + end; +end; + +procedure assigncomponent(source,dest: tcomponent); +var + stream1: tmemorystream; +begin + stream1:= tmemorystream.Create; + try + writecomponentmse(stream1,source); + stream1.Position:= 0; + stream1.ReadComponent(dest); + finally + stream1.Free; + end; +end; +end. diff --git a/mseide-msegui/lib/common/kernel/msestrings.pas b/mseide-msegui/lib/common/kernel/msestrings.pas new file mode 100644 index 0000000..4d763af --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msestrings.pas @@ -0,0 +1,6254 @@ +{ MSEgui Copyright (c) 1999-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msestrings; +{$ifdef FPC} + {$if defined(FPC) and (fpc_fullversion >= 020501)} + {$define mse_fpc_2_6} + {$ifend} + {$if defined(FPC) and (fpc_fullversion >= 020300)} + {$define mse_fpc_2_3} + {$ifend} + + {$ifdef mse_fpc_2_6} + {$define mse_hasvtunicodestring} + {$endif} + {$ifdef mse_fpc_2_3} + {$define mse_unicodestring} + {$endif} + {$if fpc_fullversion >= 030000} + {$define hascodepage} + {$endif} +{$endif} + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$goto on}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,msetypes{$ifdef FPC},strings{$endif},typinfo,sysutils; +{$ifdef FPC} + {$ifndef mse_nounicodestring} + {$if defined(FPC) and (fpc_fullversion >= 020300)} + {$define mse_unicodestring} + {$ifend} + {$endif} + {$ifndef mse_unicodestring} + {$ifdef FPC_WINLIKEWIDESTRING} + {$define msestringsarenotrefcounted} + {$endif} + {$endif} +{$else} + {$ifdef mswindows} + {$define msestringsarenotrefcounted} + {$endif} +{$endif} + +type + stringposty = (sp_left,sp_center,sp_right); + utfoptionty = (uto_storeinvalid); //store invalid utf8 chars in private area + utfoptionsty = set of utfoptionty; + +const + utf16privatebase = $f800; //used to store invalid utf8 chars in filenamety + utf16private = utf16privatebase + 0; + //prefix for private area codepoint, following word is low byte + utf16invalid = utf16privatebase + 1; + //prefix for invalid utf8 byte, following word is data byte + + utferrorchar = char('?'); //single byte only + + {$ifdef mse_unicodestring} + msestringtypekind = tkustring; + {$else} + msestringtypekind = tkwstring; + {$endif} + defaultdelimchars = ' '+c_tab+c_return+c_linefeed; + defaultmsedelimchars = msestring(defaultdelimchars); + +type + doublestringty = record + a,b: string; + end; + pdoublestringty = ^doublestringty; + doublestringarty = array of doublestringty; + + doublemsestringty = record + a,b: msestring; + end; + pdoublemsestringty = ^doublemsestringty; + doublemsestringarty = array of doublemsestringty; + doublemsestringaty = array[0..0] of doublemsestringty; + pdoublemsestringaty = ^doublemsestringaty; + +const + upperchars: array[char] of char = ( + #$00,#$01,#$02,#$03,#$04,#$05,#$06,#$07,#$08,#$09,#$0a,#$0b,#$0c,#$0d,#$0e,#$0f, + #$10,#$11,#$12,#$13,#$14,#$15,#$16,#$17,#$18,#$19,#$1a,#$1b,#$1c,#$1d,#$1e,#$1f, + #$20,#$21,#$22,#$23,#$24,#$25,#$26,#$27,#$28,#$29,#$2a,#$2b,#$2c,#$2d,#$2e,#$2f, + #$30,#$31,#$32,#$33,#$34,#$35,#$36,#$37,#$38,#$39,#$3a,#$3b,#$3c,#$3d,#$3e,#$3f, + #$40,#$41,#$42,#$43,#$44,#$45,#$46,#$47,#$48,#$49,#$4a,#$4b,#$4c,#$4d,#$4e,#$4f, + #$50,#$51,#$52,#$53,#$54,#$55,#$56,#$57,#$58,#$59,#$5a,#$5b,#$5c,#$5d,#$5e,#$5f, + #$60,'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' ,'Z' ,#$7b,#$7c,#$7d,#$7e,#$7f, + #$80,#$81,#$82,#$83,#$84,#$85,#$86,#$87,#$88,#$89,#$8a,#$8b,#$8c,#$8d,#$8e,#$8f, + #$90,#$91,#$92,#$93,#$94,#$95,#$96,#$97,#$98,#$99,#$9a,#$9b,#$9c,#$9d,#$9e,#$9f, + #$a0,#$a1,#$a2,#$a3,#$a4,#$a5,#$a6,#$a7,#$a8,#$a9,#$aa,#$ab,#$ac,#$ad,#$ae,#$af, + #$b0,#$b1,#$b2,#$b3,#$b4,#$b5,#$b6,#$b7,#$b8,#$b9,#$ba,#$bb,#$bc,#$bd,#$be,#$bf, + #$c0,#$c1,#$c2,#$c3,#$c4,#$c5,#$c6,#$c7,#$c8,#$c9,#$ca,#$cb,#$cc,#$cd,#$ce,#$cf, + #$d0,#$d1,#$d2,#$d3,#$d4,#$d5,#$d6,#$d7,#$d8,#$d9,#$da,#$db,#$dc,#$dd,#$de,#$df, + #$e0,#$e1,#$e2,#$e3,#$e4,#$e5,#$e6,#$e7,#$e8,#$e9,#$ea,#$eb,#$ec,#$ed,#$ee,#$ef, + #$f0,#$f1,#$f2,#$f3,#$f4,#$f5,#$f6,#$f7,#$f8,#$f9,#$fa,#$fb,#$fc,#$fd,#$fe,#$ff); + + lowerchars: array[char] of char = ( + #$00,#$01,#$02,#$03,#$04,#$05,#$06,#$07,#$08,#$09,#$0a,#$0b,#$0c,#$0d,#$0e,#$0f, + #$10,#$11,#$12,#$13,#$14,#$15,#$16,#$17,#$18,#$19,#$1a,#$1b,#$1c,#$1d,#$1e,#$1f, + #$20,#$21,#$22,#$23,#$24,#$25,#$26,#$27,#$28,#$29,#$2a,#$2b,#$2c,#$2d,#$2e,#$2f, + #$30,#$31,#$32,#$33,#$34,#$35,#$36,#$37,#$38,#$39,#$3a,#$3b,#$3c,#$3d,#$3e,#$3f, + #$40,'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' ,'z' ,#$5b,#$5c,#$5d,#$5e,#$5f, + #$60,#$61,#$62,#$63,#$64,#$65,#$66,#$67,#$68,#$69,#$6a,#$6b,#$6c,#$6d,#$6e,#$6f, + #$70,#$71,#$72,#$73,#$74,#$75,#$76,#$77,#$78,#$79,#$7a,#$7b,#$7c,#$7d,#$7e,#$7f, + #$80,#$81,#$82,#$83,#$84,#$85,#$86,#$87,#$88,#$89,#$8a,#$8b,#$8c,#$8d,#$8e,#$8f, + #$90,#$91,#$92,#$93,#$94,#$95,#$96,#$97,#$98,#$99,#$9a,#$9b,#$9c,#$9d,#$9e,#$9f, + #$a0,#$a1,#$a2,#$a3,#$a4,#$a5,#$a6,#$a7,#$a8,#$a9,#$aa,#$ab,#$ac,#$ad,#$ae,#$af, + #$b0,#$b1,#$b2,#$b3,#$b4,#$b5,#$b6,#$b7,#$b8,#$b9,#$ba,#$bb,#$bc,#$bd,#$be,#$bf, + #$c0,#$c1,#$c2,#$c3,#$c4,#$c5,#$c6,#$c7,#$c8,#$c9,#$ca,#$cb,#$cc,#$cd,#$ce,#$cf, + #$d0,#$d1,#$d2,#$d3,#$d4,#$d5,#$d6,#$d7,#$d8,#$d9,#$da,#$db,#$dc,#$dd,#$de,#$df, + #$e0,#$e1,#$e2,#$e3,#$e4,#$e5,#$e6,#$e7,#$e8,#$e9,#$ea,#$eb,#$ec,#$ed,#$ee,#$ef, + #$f0,#$f1,#$f2,#$f3,#$f4,#$f5,#$f6,#$f7,#$f8,#$f9,#$fa,#$fb,#$fc,#$fd,#$fe,#$ff); + +type + lstringty = record + po: pchar; + len: integer; + end; + plstringty = ^lstringty; + + lmsestringty = record + po: pmsechar; + len: integer; + end; + plmsestringty = ^lmsestringty; + + lstringarty = array of lstringty; + lmsestringarty = array of lmsestringty; + + stringheaderty = packed record +{$ifdef hascodepage} + CodePage: TSystemCodePage; + ElementSize: Word; + {$ifdef CPU64} { align fields } + Dummy: DWord; + {$endif CPU64} +{$endif} + ref: sizeint; + len: sizeint; + end; + + pstringheaderty = ^stringheaderty; + +const + emptylstring: lstringty = (po: nil; len: 0); + emptywstring: lmsestringty = (po: nil; len: 0); + +type + tmemorystringstream = class(tmemorystream) + //has room for stringheader + protected + procedure SetCapacity(NewCapacity: PtrInt) override; + function getcapacity: ptrint override; + function getmemory: pointer; override; + Function GetSize : Int64; Override; + function GetPosition: Int64; Override; + public + constructor create; + procedure SetSize({$ifdef CPU64}const{$endif CPU64} NewSize: PtrInt); override; + function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override; + procedure destroyasstring(out data: string); + //calls destroy, not possible to use as destructor in FPC + end; + + searchoptionty = (so_caseinsensitive,so_wholeword,so_wordstart,so_backward); + searchoptionsty = set of searchoptionty; + +procedure trimright1(var s: string); overload; +procedure trimright1(var s: msestring); overload; + +function removechar(const source: string; a: char): string; overload; +function removechar(const source: msestring; a: msechar): msestring; overload; +procedure removechar1(var dest: string; a: char); overload; +procedure removechar1(var dest: msestring; a: msechar); overload; + //removes all a +function printableascii(const source: string): string; overload; + //removes all nonprintablechars and ' ' +function printableascii(const source: msestring): msestring; overload; + //removes all nonprintablechars and ' ' + +function replacechar(const source: string; old,new: char): string; overload; +function replacechar(const source: msestring; old,new: msechar): msestring; overload; +procedure replacechar1(var dest: string; old,new: char); overload; +procedure replacechar1(var dest: msestring; old,new: msechar); overload; + //replaces old by new +function stringfromchar(achar: char; count : integer): string; overload; +function stringfromchar(achar: msechar; count : integer): msestring; overload; + +function replacetext(const source: string; index: integer; + a: string): string; overload; +function replacetext(const source: msestring; index: integer; + a: msestring): msestring; overload; +procedure replacetext1(var dest: string; index: integer; + const a: string); overload; +procedure replacetext1(var dest: msestring; index: integer; const a: msestring); overload; + +procedure addstringsegment(var dest: msestring; const a,b: pmsechar); + //add text from a^ to (b-1)^ to dest +function stringsegment(a,b: pchar): string; +function stringsegment(a,b: pmsechar): msestring; + +function lstringtostring(const value: lmsestringty): msestring; overload; +function lstringtostring(const value: pmsechar; + const len: integer): msestring; overload; +function lstringtostring(const value: lstringty): string; overload; +function lstringtostring(const value: pchar; + const len: integer): string; overload; +procedure stringtolstring(const value: string; + var{out} res: lstringty); inline; //todo!!!!! fpbug 3221 +procedure stringtolstring(const value: msestring; + var{out} res: lmsestringty); inline; +function stringtolstring(const value: string): lstringty; inline; +function stringtolstring(const value: msestring): lmsestringty; inline; +function lstringartostringar(const value: lstringarty): stringarty; + +procedure nextword(const value: msestring; out res: lmsestringty); overload; +procedure nextword(const value: string; out res: lstringty); overload; +procedure nextword(var value: lmsestringty; out res: lmsestringty); overload; +procedure nextword(var value: lstringty; out res: lstringty); overload; +procedure nextword(var value: lstringty; out res: string); overload; +function nextword(var start: pchar): string; overload; +function nextword(var start: pmsechar): msestring; overload; + +function nextquotedstring(var value: lstringty; out res: string): boolean; + //false wenn kein quote vorhanden +procedure lstringgoback(var value: lstringty; const res: lstringty); +function issamelstring(const value: lmsestringty; const key: msestring; + caseinsensitive: boolean = false): boolean; overload; + //nur ascii caseinsens. +function issamelstring(const value: lstringty; const key: string; + caseinsensitive: boolean = false): boolean; overload; + //nur ascii caseinsens. +function lstringcomp(const a,b: lstringty): integer; overload; +function lstringcomp(const a: lstringty; const b: string): integer; overload; +function lstringicomp(const a,b: lstringty): integer; overload; + //ascii case insensitive +function lstringicomp(const a: lstringty; const b: string): integer; overload; + //ascii case insensitive +function lstringicompupper(const a,upper: lstringty): integer; overload; + //ascii case insensitive, upper must be uppercase +function lstringicompupper(const a: lstringty; const upper: string): integer; overload; + //ascii case insensitive, upper must be uppercase + +function stringcomp(const a,b: string): integer; +function stringicomp(const a,b: string): integer; + //ascii case insensitive +function stringicompupper(const a,upstr: string): integer; + //ascii case insensitive, b must be uppercase + +function msestringcomp(const a,b: msestring): integer; +function msestringicomp(const a,b: msestring): integer; + //ascii case insensitive +function msestringicompupper(const a,upstr: msestring): integer; + //ascii case insensitive, upstr must be uppercase + +function comparestrlen(const S1,S2: string): integer; + //case sensitiv, beruecksichtigt nur s1 laenge +function msecomparestrlen(const S1,S2: msestring): integer; + //case sensitiv, beruecksichtigt nur s1 laenge + +function msecomparestr(const S1, S2: msestring): Integer + {$ifdef FPC} inline; {$endif} + //case sensitive +function msecomparetext(const S1, S2: msestring): Integer + {$ifdef FPC} inline; {$endif} + //case insensitive +function msecomparestrnatural(const S1, S2: msestring): Integer + {$ifdef FPC} inline; {$endif} + //case sensitive +function msecomparetextnatural(const S1, S2: msestring): Integer + {$ifdef FPC} inline; {$endif} + //case insensitive +function mseCompareTextlen(const S1, S2: msestring): Integer; + //case insensitiv, beruecksichtigt nur s1 laenge +function mseCompareTextlenupper(const S1, S2: msestring): Integer; + //case insensitiv, checks length s1 only, s1 must be uppercase +function msepartialcomparetext(const s1,s2: msestring): integer; + //case insensitive, checks s1 lenght only +function msepartialcomparestr(const s1,s2: msestring): integer; + //case sensitive, checks s1 lenght only + +function mseissamestrlen(const apartstring,astring: msestring): boolean; +function mseissametextlen(const apartstring,astring: msestring): boolean; + //case insensitive + +function encodesearchoptions(const caseinsensitive: boolean = false; + const wholeword: boolean = false; + const wordstart: boolean = false; + const backward: boolean = false): searchoptionsty; +function msestringsearch(const substring,s: msestring; start: integer; + const options: searchoptionsty; + const substringupcase: msestring = ''): integer; overload; +function stringsearch(const substring,s: string; start: integer; + const options: searchoptionsty; + const substringupcase: string = ''): integer; overload; +function replacestring(const s: msestring; oldsub: msestring; + const newsub: msestring; + const options: searchoptionsty = []): msestring; overload; +function replacestring(const s: string; oldsub: string; + const newsub: string; + const options: searchoptionsty = []): string; overload; + +procedure addeditchars(const source: msestring; var buffer: msestring; + var cursorpos: integer); + //cursorpos nullbased +function processeditchars(var value: msestring; stripcontrolchars: boolean): integer; + //bringt offset durch backspace +function mseextractprintchars(const value: msestring): msestring; + +function findchar(const str: string; achar: char): integer; overload; + //bringt index des ersten vorkommens von zeichen in string, 0 wenn nicht gefunden +function findchar(const str: string; const astart: integer; + achar: char): integer; overload; +function findchar(const str: msestring; achar: msechar): integer; overload; + //bringt index des ersten vorkommens von zeichen in string, 0 wenn nicht gefunden +function findchar(const str: msestring; const astart: integer; + achar: msechar): integer; overload; +function findchar(const str: pchar; achar: char): integer; overload; + //bringt index des ersten vorkommens von zeichen in string, 0 wenn nicht gefunden +function findchar(const str: pmsechar; achar: msechar): integer; overload; + //bringt index des ersten vorkommens von zeichen in string, 0 wenn nicht gefunden +function findchars(const str: string; const achars: string): integer; overload; + //bringt index des ersten vorkommens von zeichen in string, 0 wenn nicht gefunden +function findchars(const str: msestring; const achars: msestring): integer; overload; + //bringt index des ersten vorkommens von zeichen in string, 0 wenn nicht gefunden +function findlastchar(const str: string; achar: char): integer; overload; + //bringt index des letzten vorkommens von zeichen in string, 0 wenn nicht gefunden +function findlastchar(const str: msestring; achar: msechar): integer; overload; + //bringt index des letzten vorkommens von zeichen in string, 0 wenn nicht gefunden +function countchars(const str: string; achar: char): integer; overload; +function countchars(const str: msestring; achar: msechar): integer; overload; +function getcharpos(const str: msestring; achar: msechar): integerarty; + +function strscan(const Str: PChar; Chr: Char): PChar; overload; +//function strscan(const str: string; chr: char): integer; overload; + //use findchar() +function strscan(const str: lmsestringty; const chr: msechar): pmsechar; overload; +function msestrscan(const Str: PmseChar; Chr: mseChar): PmseChar; overload; +//function msestrscan(const str: msestring; chr: msechar): integer; overload; + //use findchar() +procedure mseskipspace(var str: pmsechar); {$ifdef FPC} inline; {$endif} +procedure skipspace(var str: pchar); {$ifdef FPC} inline; {$endif} + +function StrLScan(const Str: PChar; Chr: Char; len: integer): PChar; +function mseStrLScan(const Str: PmseChar; Chr: mseChar; len: integer): PmseChar; + +function StrNScan(const Str: PChar; Chr: Char): PChar; +function StrLNScan(const Str: PChar; Chr: Char; len: integer): PChar; +function mseStrNScan(const Str: PmseChar; Chr: mseChar): PmseChar; +function mseStrLNScan(const Str: PmseChar; Chr: mseChar; len: integer): PmseChar; + +function StrRScan(const Str: PChar; Chr: Char): PChar; +function StrLRScan(const Str: PChar; Chr: Char; len: integer): PChar; +function mseStrRScan(const Str: PmseChar; Chr: mseChar): PmseChar; overload; +function msestrrscan(const str: msestring; chr: msechar): integer; overload; +function mseStrLRScan(const Str: PmseChar; Chr: mseChar; len: integer): PmseChar; + +function mseStrLNRScan(const Str: PmseChar; Chr: mseChar; len: integer): PmseChar; + +function StrLComp(const Str1, Str2: PChar; len: integer): Integer; + +function mseStrComp(const Str1, Str2: PmseChar): Integer; +function mseStrLComp(const Str1, Str2: PmseChar; len: integer): Integer; +function mseStrLIComp(const Str1, upstr: PmseChar; len: integer): Integer; + //ascii caseinsensitive, upstr muss upcase sein +function StrLIComp(const Str1, upstr: PChar; len: integer): Integer; + //ascii caseinsensitive, upstr muss upcase sein +function StrIComp(const Str1, upstr: PChar): Integer; + //ascii caseinsensitive, upstr muss upcase sein + +function startsstr(substring,s: pchar): boolean; overload; +function startsstr(const substring,s: string): boolean; overload; +function msestartsstr(substring,s: pmsechar): boolean; overload; +function msestartsstr(const substring,s: msestring): boolean; overload; + +function msestartsstrcaseinsensitive(substring,s: pmsechar): boolean; + //substring must be uppercase, ASCII caseinsensitve + +function isnullstring(const s: ansistring): boolean; +function isemptystring(const s: pchar): boolean; overload; +function isemptystring(const s: pmsechar): boolean; overload; +function isnamechar(achar: char): boolean; overload; +function isnamechar(achar: msechar): boolean; overload; + //true if achar in 'a'..'z','A'..'Z','0'..'9','_'; +function isnumber(const s: string): boolean; overload; +function isnumber(const s: msestring): boolean; overload; + //true if all characters in '0'..'9' + +function strlcopy(const str: pchar; len: integer): ansistring; + //nicht nullterminiert +function msestrlcopy(const str: pmsechar; len: integer): msestring; + //nicht nullterminiert +function psubstr(const start,stop: pchar): string; overload; +function psubstr(const start,stop: pmsechar): msestring; overload; +function singleline(const start: pchar): string; overload; +function singleline(const start: pmsechar): msestring; overload; + +function msePosEx(const SubStr, S: msestring; Offset: longword = 1): Integer; + +function mselowercase(const s: msestring): msestring; overload; +function mselowercase(const s: msestringarty): msestringarty; overload; +function mseuppercase(const s: msestring): msestring; overload; +function mseuppercase(const s: msestringarty): msestringarty; overload; + +//ascii only +function charuppercase(const c: char): char; overload; + {$ifdef FPC} inline; {$endif} +function charuppercase(const c: msechar): msechar; overload; + {$ifdef FPC} inline; {$endif} +function struppercase(const s: string): string; overload; +function struppercase(const s: msestring): msestring; overload; +function struppercase(const s: lmsestringty): msestring; overload; +function struppercase(const s: lstringty): string; overload; +procedure struppercase1(var s: msestring); overload; + +function charlowercase(const c: char): char; overload; +function charlowercase(const c: msechar): msechar; overload; +function strlowercase(const s: string): string; overload; +function strlowercase(const s: msestring): msestring; overload; +function strlowercase(const s: lmsestringty): msestring; overload; +function strlowercase(const s: lstringty): string; overload; +procedure strlowercase1(var s: msestring); overload; + +//ascii only + +function mseremspace(const s: msestring): msestring; + //entfernt alle space und steuerzeichen +function removelinebreaks(const s: msestring): msestring; + //replaces linebreaks with space +function removelineterminator(const s: msestring): msestring; +procedure removetabterminator(var s: msestring); +function stripescapesequences(avalue: msestring): msestring; + +procedure stringaddref(var str: ansistring); overload; +procedure stringaddref(var str: msestring); overload; +procedure stringsafefree(var str: string; const onlyifunique: boolean); +procedure stringsafefree(var str: msestring; const onlyifunique: boolean); + +procedure reallocstring(var value: ansistring); overload; + //macht datenkopie ohne free +procedure reallocstring(var value: msestring); overload; + //macht datenkopie ohne free +procedure reallocarray(var value; elementsize: integer); overload; + //macht datenkopie ohne free +procedure resizearray(var value; newlength, elementsize: integer); + //ohne finalize + +function lineatindex(const value: msestring; const index: int32): msestring; +procedure wordatindex(const value: msestring; const index: integer; + out first,pastlast: pmsechar; + const delimchars: msestring; + const nodelimstrings: array of msestring); overload; + //index = 0..length(value)-1 +function wordatindex(const value: msestring; const index: integer; + const delimchars: msestring; + const nodelimstrings: array of msestring): msestring; overload; +function checkkeyword(const aname: string; const anames; //stringaty + const ahigh: integer): cardinal; overload; + //scans from 1 to ahigh, 0 -> unknown +function checkkeyword(const aname: msestring; const anames; //msestringaty + const ahigh: integer): cardinal; overload; +function checkkeyword(const aname: pchar; const anames; //stringaty + const ahigh: integer): cardinal; overload; + //scans from 1 to ahigh, 0 -> unknown +function checkkeyword(const aname: pmsechar; const anames; //msestringaty + const ahigh: integer): cardinal; overload; + +function quotestring(value: string; quotechar: char; + const force: boolean = true; + const separator: char = ' '): string; overload; +function quotestring(value: msestring; quotechar: msechar; + const force: boolean = true; + const separator: msechar = ' '): msestring; overload; +function quoteescapedstring(value: string; quotechar: char; + const force: boolean = true; + const separator: char = ' '): string; overload; +function quoteescapedstring(value: msestring; quotechar: msechar; + const force: boolean = true; + const separator: msechar = ' '): msestring; overload; +function unquotestring(value: string; quotechar: char): string; overload; +function unquotestring(value: msestring; quotechar: msechar): msestring; overload; +function extractquotedstr(const value: msestring): msestring; + //entfernt vorhandene paare ' und " + +function checkfirstchar(const value: string; achar: char): pchar; + //nil wenn erster char nicht space <> achar, ^achar sonst +function firstline(const atext: msestring): msestring; +function lastline(const atext: msestring): msestring; +procedure textdim(const atext: msestring; out firstx,lastx,y: integer); + +function shrinkpathellipse(var value: msestring): boolean; +function shrinkstring(const value: msestring; maxcharcount: integer): msestring; +procedure extendstring(var value: string; const mincharcount: integer); +procedure extendstring(var value: msestring; const mincharcount: integer); + +function nullstring(const count: integer): string; +function charstring(ch: char; count: integer): string; overload; +function charstring(ch: msechar; count: integer): msestring; overload; +function countleadingchars(const str: msestring; char: msechar): integer; overload; +function countleadingchars(const str: string; char: char): integer; overload; + //-1 = leer +function fitstring(const source: msestring; const len: integer; + const pos: stringposty = sp_left; + const cutchar: msechar = #0; + const padchar: msechar = ' '): msestring; + //cutchar = 0 -> no cutchar + +function breaklines(const source: string): stringarty; overload; +function breaklines(const source: msestring): msestringarty; overload; +function breaklines(const source: msestring; + maxlength: integer): msestringarty; overload; + +procedure splitstring(source: string; + var dest: stringarty; separator: char = c_tab; + trim: boolean = false); overload; +procedure splitstring(source: msestring; + var dest: msestringarty; separator: msechar = c_tab; + trim: boolean = false); overload; + //length(dest) = 0 -> es werden die noetigen stellen erzeugt + // sonst length(dest) <= length(dest uebergeben), + // ganzer rest im letzten string, falls mehr vorhandene teile als + // uebergebene strings +function splitstring(source: string; separator: char = c_tab; + trim: boolean = false): stringarty; overload; +function splitstring(source: msestring; separator: msechar = c_tab; + trim: boolean = false): msestringarty; overload; +function splitstringquoted(source: string; separator: char = c_tab; + quotechar: char = '"'; + atrim: boolean = false): stringarty; overload; +function splitstringquoted(source: msestring; separator: msechar = c_tab; + quotechar: msechar = '"'; + atrim: boolean = false): msestringarty; overload; + +procedure splitstringquoted(const source: string; out dest: stringarty; + quotechar: char = '"'; separator: char = #0); overload; +procedure splitstringquoted(const source: msestring; out dest: msestringarty; + quotechar: msechar = '"'; separator: msechar = #0); overload; + //separator = #0 -> ' ' and c_tab for separators + +function concatstrings(const source: msestringarty; + const separator: msestring = ' '; + const quotechar: msechar = #0; //#0 -> no quote + const force: boolean = false): msestring; overload; + +function concatstrings(const source: stringarty; + const separator: string = ' '; + const quotechar: char = #0; //#0 -> no quote + const force: boolean = false): string; overload; + +function parsecommandline(const s: pchar): stringarty; overload; +function parsecommandline(const s: pmsechar): msestringarty; overload; +function parsecommandline(const s: string): stringarty; overload; +function parsecommandline(const s: msestring): msestringarty; overload; + +function rs(const resstring: ansistring): msestring; + //converts resourcestring, + // resourcesstring unit must be compiled with {$codepage utf8} +function stringtoutf8(const value: msestring; + const options: utfoptionsty = []): utf8string; +function stringtoutf8ansi(const value: msestring; + const options: utfoptionsty = []): ansistring; +function stringtoutf8(const value: pmsechar; + const count: integer; + const options: utfoptionsty = []): utf8string; +function stringtoutf8ansi(const value: pmsechar; + const count: integer; + const options: utfoptionsty = []): ansistring; +function utf8tostring(const value: pchar; const alength: integer; + const options: utfoptionsty = []): msestring; +function utf8tostring(const value: pchar; + const options: utfoptionsty = []): msestring; +function utf8tostring(const value: lstringty; + const options: utfoptionsty = []): msestring; +function utf8tostring(const value: utf8string; + const options: utfoptionsty = []): msestring; +function utf8tostringansi(const value: ansistring; + const options: utfoptionsty = []): msestring; +function checkutf8(const value: utf8string): boolean; + //true if valid utf8 +function checkutf8ansi(const value: ansistring): boolean; + //true if valid utf8 +function stringtolatin1(const value: msestring): string; +function latin1tostring(const value: string): msestring; +function ucs4tostring(achar: dword): msestring; +function getucs4char(const value: msestring; const aindex: int32): ucs4char; + //returns surrogatevalue if index between high and low codeunit + +function getasciichar(const source: msechar; out dest: char): boolean; + {$ifdef FPC} inline; {$endif} + //true if valid; +function getansichar(const source: msechar; out dest: char): boolean; + {$ifdef FPC} inline; {$endif} + //true if valid; + +function ansistringof(const value: tbytes): ansistring; + +type +// getkeystringfuncty = function (const index: integer; +// var astring: msestring): boolean of object; + //false if no value + getkeystringfuncty = function (const index: integer): msestring of object; + + locatestringoptionty = (lso_casesensitive,lso_posinsensitive,lso_exact, + lso_nodown,lso_noup,lso_noexact, + lso_filterisuppercase); + locatestringoptionsty = set of locatestringoptionty; + +function locatestring(const afilter: msestring; + const getkeystringfunc: getkeystringfuncty; + const options: locatestringoptionsty; + const count: integer; var aindex: integer): boolean; + //true if found + +function getmsestringprop(const ainstance: tobject; + const apropinfo: ppropinfo): msestring; +procedure setmsestringprop(const ainstance: tobject; + const apropinfo: ppropinfo; const avalue: msestring); +function treader_readmsestring(const areader: treader): msestring; +procedure twriter_writemsestring(awriter: twriter; const avalue: msestring); + +implementation +uses + msearrayutils{,msesysintf}; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +type + tmemorystream1 = class(tmemorystream); + +function getmsestringprop(const ainstance: tobject; + const apropinfo: ppropinfo): msestring; +begin +{$ifdef mse_unicodestring} + result:= GetunicodestrProp(ainstance,apropinfo); +{$else} + result:= GetwidestrProp(ainstance,apropinfo); +{$endif} +end; + +procedure twriter_writemsestring(awriter: twriter; const avalue: msestring); +begin +{$ifdef mse_unicodestring} + awriter.writeunicodestring(avalue); +{$else} + awriter.writewidestring(avalue); //msestringimplementation +{$endif} +end; + +procedure setmsestringprop(const ainstance: tobject; + const apropinfo: ppropinfo; const avalue: msestring); +begin +{$ifdef mse_unicodestring} + setunicodestrprop(ainstance,apropinfo,avalue); +{$else} + setwidestrprop(ainstance,apropinfo,avalue); +{$endif} +end; + +function treader_readmsestring(const areader: treader): msestring; +begin +{$ifdef mse_unicodestring} + result:= areader.Readunicodestring; //msestringimplementation +{$else} + result:= areader.Readwidestring; //msestringimplementation +{$endif} +end; + +function locatestring(const afilter: msestring; const getkeystringfunc: getkeystringfuncty; + const options: locatestringoptionsty; + const count: integer; var aindex: integer): boolean; + //true if found +type + locateinfoty = record + filter: msestring; + casesensitive: boolean; + posinsensitive: boolean; + exact: boolean; + result: boolean; + end; + +var + locateinfo: locateinfoty; + +// index1: integer; + + procedure check(index1: integer); + var + str1: msestring; + int1: integer; + + procedure checkexactpos; + var + int2: integer; + begin + result:= (int1 > 0) and ((int1 = 1) or (str1[int1] = ' ')); + if result then begin + int2:= int1 + length(locateinfo.filter); + result:= (int2 = length(str1)) or (str1[int2] = ' '); + end; + end; //checkexactpos + + + begin + str1:= getkeystringfunc(index1); + with locateinfo do begin + if exact then begin + if casesensitive then begin + if posinsensitive then begin + int1:= pos(filter,str1); + checkexactpos; + end + else begin + result:= msecomparestr(filter,str1) = 0; + end; + end + else begin + if posinsensitive then begin + int1:= pos(filter,mseuppercase(str1)); + checkexactpos; + end + else begin + result:= msecomparetext(filter,str1) = 0; + end; + end; + end + else begin + if casesensitive then begin + if posinsensitive then begin + result:= pos(filter,str1) > 0; + end + else begin + result:= msecomparestrlen(filter,str1) = 0; + end; + end + else begin + if posinsensitive then begin + result:= pos(filter,mseuppercase(str1)) > 0; + end + else begin + result:= msecomparetextlen(filter,str1) = 0; + end; + end; + end; + if result then begin + aindex:= index1; + end; + end; + end; //check + +var + int1,int2: integer; +begin + if afilter = '' then begin + result:= count > 0; + if result then begin + if not (lso_nodown in options) then begin + aindex:= 0; + end + else begin + if aindex >= count then begin + aindex:= count-1; + end; + end; + end; + end + else begin + with locateinfo do begin + posinsensitive:= lso_posinsensitive in options; + casesensitive:= lso_casesensitive in options; + filter:= afilter; + if not casesensitive and not (lso_filterisuppercase in options) then begin + filter:= mseuppercase(filter); + end; + result:= false; + int1:= aindex; + if not (lso_noup in options) then begin + if int1 < 0 then begin + int1:= 0; + end; + end; + if not (lso_nodown in options) then begin + if int1 >= count then begin + int1:= count - 1; + end; + end; + if int1 >= 0 then begin + if not (lso_noexact in options) then begin //search whole filtertext + exact:= true; + for int2:= int1 to count - 1 do begin + check(int2); + if result or (lso_noup in options) then begin + break; + end; + end; + if not result then begin + if not (lso_nodown in options) then begin + for int2:= int1-1 downto 0 do begin + check(int2); + if result then begin + break; + end; + end; + end; + end; + end; + if not result and not (lso_exact in options) then begin + //search partial filter text + exact:= false; + for int2:= int1 to count - 1 do begin + check(int2); + if result or (lso_noup in options) then begin + break; + end; + end; + if not result and not (lso_nodown in options) then begin + for int2:= int1 - 1 downto 0 do begin + check(int2); + if result then begin + break; + end; + end; + end; + end; + end; + end; + result:= locateinfo.result; + end; +end; + +procedure dostringtoutf8(const value: pmsechar; + var count: integer; const dest: pointer; + const options: utfoptionsty); +var + ps,pe: pcard16; + pd: pcard8; + ca1: card16; + + procedure store3(); inline; + begin + pd^:= (ca1 shr 12) or $e0; + inc(pd); + pd^:= (ca1 shr 6) and $3f or $80; + inc(pd); + pd^:= ca1 and $3f or $80; + end; //store3 + +begin + pd:= dest; + ps:= pointer(value); + pe:= ps + count; + while ps < pe do begin + ca1:= ps^; + inc(ps); + if ca1 < $80 then begin //1 byte + pd^:= ca1; + end + else begin + if ca1 < $0800 then begin //2byte + pd^:= (ca1 shr 6) or $c0; + inc(pd); + pd^:= (ca1 and $3f) or $80; + end + else begin + if ca1 < $d800 then begin + store3(); + end + else begin + if (ca1 > $dbff) then begin //3 byte + if (uto_storeinvalid in options) then begin + if ca1 = utf16private then begin + ca1:= ca1 or ps^; + store3(); + inc(ps); + end + else begin + if ca1 = utf16invalid then begin + pd^:= ps^; + inc(ps); + end + else begin + store3(); //should not happen + end; + end; + end + else begin + store3(); + end; + end + else begin //surrogate pair + if (ca1 >= $dc00) or (ps = pe) then begin + //missing high or low surrogate + pd^:= card8(utferrorchar); + end; + if ps^ and $fc00 <> $dc00 then begin //invalid low surrogate + pd^:= card8(utferrorchar); + end + else begin + ca1:= ca1 - card16($d800 - $0040); + pd^:= (ca1 shr 8) or $f0; + inc(pd); + pd^:= (ca1 shr 2) and $3f or $80; + inc(pd); + pd^:= ((ca1 shl 4) and $30 or (ps^ shr 6) and $0f) or $80; + inc(pd); + pd^:= ps^ and $3f or $80; + inc(ps); + end; + end; + end; + end; + end; + inc(pd); + end; + count:= pd - pcard8(dest); +end; + +function stringtoutf8(const value: pmsechar; + const count: integer; + const options: utfoptionsty = []): utf8string; +var + i1: int32; +begin + i1:= count; + setlength(result,i1*3); //max + dostringtoutf8(value,i1,pointer(result),options); + setlength(result,i1); +end; + +function stringtoutf8ansi(const value: pmsechar; + const count: integer; + const options: utfoptionsty = []): ansistring; +var + i1: int32; +begin + i1:= count; + setlength(result,i1*3); //max + dostringtoutf8(value,i1,pointer(result),options); + setlength(result,i1); +end; + +function stringtoutf8(const value: msestring; + const options: utfoptionsty = []): utf8string; +var + i1: int32; +begin + i1:= length(value); + setlength(result,i1*3); //max + dostringtoutf8(pointer(value),i1,pointer(result),options); + setlength(result,i1); +end; + +function stringtoutf8ansi(const value: msestring; + const options: utfoptionsty = []): ansistring; +var + i1: int32; +begin + i1:= length(value); + setlength(result,i1*3); //max + dostringtoutf8(pointer(value),i1,pointer(result),options); + setlength(result,i1); +end; + +function utf8tostring(const value: pchar; const alength: integer; + const options: utfoptionsty = []): msestring; +var + by1: card8; + wo1: card16; + pc,pe: pcard8; + pd,pde: pcard16; + storeinvalid: boolean; + p1: pointer; + + procedure seterror(); inline; + begin + if storeinvalid then begin + pd^:= utf16invalid; + inc(pd); + pd^:= by1; + end + else begin + pd^:= card16(utferrorchar); + end; + end; + +begin + storeinvalid:= uto_storeinvalid in options; + setlength(result,alength); //max + pd:= pcard16(pointer(result)); + pde:= pd+alength; + pc:= pointer(value); + pe:= pc+alength; + while pc < pe do begin + by1:= pc^; + inc(pc); + if by1 < $80 then begin //1 byte + pd^:= by1; + end + else begin + if by1 < $e0 then begin //2 byte + if (pc < pe) and (pc^ and $c0 = $80) then begin + wo1:= ((by1 and $1f) shl word(6)) or (pc^ and $3f); + if storeinvalid and (wo1 >= utf16privatebase) and + (wo1 < utf16privatebase + 256) then begin + pd^:= utf16private; + wo1:= wo1 and $00ff; + inc(pd); + end; + pd^:= wo1; + if pd^ < $80 then begin + seterror(); //overlong + end; + inc(pc); + end + else begin + seterror(); + end; + end + else begin + if (by1 < $f0) then begin //3byte + if (pe - pc >= 1) and (pc^ and $c0 = $80) and + ((pc+1)^ and $c0 = $80) then begin + pd^:= (by1 shl word(12)) or + (pc^ and $3f) shl word(6) or ((pc+1)^ and $3f); + if pd^ < $0800 then begin + seterror(); //overlong + end; + inc(pc,2); + end + else begin + seterror(); + end; + end + else begin + if (by1 < $f8) then begin //4byte + if (pe - pc >= 2) and (pc^ and $c0 = $80) and ((pc+1)^ and $c0 = $80) and + ((pc+2)^ and $c0 = $80) then begin + if ((by1 <= $e0) and (pc^ < $90)) then begin //overlong + seterror(); //overlong; + end + else begin + pd^:= (((by1 and $07) shl word(8)) or + ((pc^ and $3f) shl word(2)) or + ((pc+1)^ and $30 shr word(4))) + + (word($d800) - word($10000 shr 10)); + inc(pd); + pd^:= (((pc+1)^ and $0f) shl word(6)) or + ((pc+2)^ and $3f) or word($dc00); + end; + inc(pc,3); + end + else begin + seterror(); + end; + end + else begin + seterror(); + end; + end; + end; + end; + if (pd >= pde) and (pc < pe) then begin //pd should never be bigger than pde, + //there is at most one inc(pd) in loop + p1:= pointer(result); + setlength(result,length(result) + length(result) div 3 + 16); + pointer(pd):= pointer(pd)+(pointer(result)-p1); + pde:= pcard16(pointer(result))+length(result); + end; + inc(pd); + end; + setlength(result,pd-pcard16(pointer(result))); +end; + +function utf8tostring(const value: utf8string; + const options: utfoptionsty = []): msestring; +begin + result:= utf8tostring(pointer(value),length(value),options); +end; + +function utf8tostringansi(const value: ansistring; + const options: utfoptionsty = []): msestring; +begin + result:= utf8tostring(pointer(value),length(value),options); +end; + +function rs(const resstring: ansistring): msestring; + //converts resourcestring, + // resourcesstring unit must be compiled with {$codepage utf8} +begin + result:= utf8tostring(pointer(resstring),length(resstring),[]); +end; + + +function utf8tostring(const value: pchar; + const options: utfoptionsty = []): msestring; +begin + result:= utf8tostring(value,strlen(value),options); +end; + +function utf8tostring(const value: lstringty; + const options: utfoptionsty = []): msestring; +begin + result:= utf8tostring(value.po,value.len,options); +end; + +function docheckutf8(const value: pointer; const count: int32): boolean; + //null terminated +var + po1: pbyte; +begin + result:= true; + if count > 0 then begin + po1:= value; + while po1^ <> $00 do begin + if po1^ >= $80 then begin //2 bytes + if po1^ < $e0 then begin + if po1^ and $1e = 0 then begin + result:= false; //overlong + exit; + end; + inc(po1); + if po1^ and $c0 <> $80 then begin + result:= false; + exit; + end; + end + else begin + if po1^ < $f0 then begin //3 bytes + inc(po1); + if (po1^ and $20 = 0) and ((po1-1)^ and $0f = 0) then begin + result:= false; //overolong + exit; + end; + if po1^ and $c0 <> $80 then begin + result:= false; + exit; + end; + inc(po1); + if po1^ and $c0 <> $80 then begin + result:= false; + exit; + end; + end + else begin + if po1^ < $f8 then begin //4 bytes + inc(po1); + if po1^ and $c0 <> $80 then begin + result:= false; + exit; + end; + if (po1^ and $30 = 0) and ((po1-1)^ and $07 = 0) then begin + result:= false; //overolong + exit; + end; + inc(po1); + if po1^ and $c0 <> $80 then begin + result:= false; + exit; + end; + inc(po1); + if po1^ and $c0 <> $80 then begin + result:= false; + exit; + end; + end + else begin + result:= false; + exit; + end; + end; + end; + end; + inc(po1); + end; + if pointer(po1) <> value + count then begin + result:= false; //#0 in string + end; + end; +end; + +function checkutf8(const value: utf8string): boolean; + //true if valid utf8 +begin + result:= docheckutf8(pointer(value),length(value)); +end; + +function checkutf8ansi(const value: ansistring): boolean; + //true if valid utf8 +begin + result:= docheckutf8(pointer(value),length(value)); +end; + +function stringtolatin1(const value: msestring): string; +var + int1: integer; +begin + setlength(result,length(value)); + for int1:= 0 to length(result)-1 do begin + (pchar(pointer(result))+int1)^:= + char(word((pmsechar(pointer(value))+int1)^)); + end; +end; + +function latin1tostring(const value: string): msestring; +var + int1: integer; +begin + setlength(result,length(value)); + for int1:= 0 to length(result)-1 do begin + (pmsechar(pointer(result))+int1)^:= + msechar(byte((pchar(pointer(value))+int1)^)); + end; +end; + +function ucs4tostring(achar: dword): msestring; +begin + if achar < $10000 then begin + setlength(result,1); + pmsechar(pointer(result))^:= msechar(achar); + end + else begin + setlength(result,2); + achar:= achar - $10000; + pmsechar(pointer(result))^:= + msechar(word((achar shr 10) and $3ff or $d800)); + (pmsechar(pointer(result))+1)^:= msechar(word(achar) and $3ff or $dc00); + end; +end; + +function getucs4char(const value: msestring; const aindex: int32): ucs4char; + //returns surrogatevalue if index between high and low codeunit +begin + result:= 0; + if (aindex > 0) and (aindex <= length(value)) then begin + result:= ord(value[aindex]); + if result and $fc00 = $d800 then begin + result:= ((result - $d800) shl 10) + ord(value[aindex+1]) - $dc00 + $10000; + end + else begin + if (result and $fc00 = $dc00) and (aindex > 1) then begin + result:= result - $dc00 + ((ord(value[aindex-1]) - $d800) shl 10) + $10000; + end; + end; + end; +end; + +function getasciichar(const source: msechar; out dest: char): boolean; + //true if valid; +begin + result:= source < #128; + dest:= char(byte(source)); +end; + +function getansichar(const source: msechar; out dest: char): boolean; + //true if valid; +begin + result:= source < #256; + dest:= char(byte(source)); +end; + +function psubstr(const start,stop: pchar): string; +var + int1: integer; +begin + int1:= stop-start; + if (int1 < 0) or (start = nil) or (stop = nil) then begin + result:= ''; + end + else begin + setlength(result,int1); + move(start^,result[1],int1); + end; +end; + +function ansistringof(const value: tbytes): ansistring; +begin + setlength(result,length(value)); + move(pointer(value)^,pointer(result)^,length(result)); +end; + +function psubstr(const start,stop: pmsechar): msestring; +var + int1: integer; +begin + int1:= stop-start; + if (int1 < 0) or (start = nil) or (stop = nil) then begin + result:= ''; + end + else begin + setlength(result,int1); + move(start^,result[1],int1*sizeof(msechar)); + end; +end; + +function singleline(const start: pchar): string; +var + po1: pchar; +begin + if start = nil then begin + result:= ''; + end + else begin + po1:= start; + while po1^ <> #0 do begin + if (po1^ = c_linefeed) or (po1^ = c_return) then begin + break; + end; + inc(po1); + end; + result:= psubstr(start,po1); + end; +end; + +function singleline(const start: pmsechar): msestring; +var + po1: pmsechar; +begin + if start = nil then begin + result:= ''; + end + else begin + po1:= start; + while po1^ <> msechar(#0) do begin + if (po1^ = msechar(c_linefeed)) or (po1^ = msechar(c_return)) then begin + break; + end; + inc(po1); + end; + result:= psubstr(start,po1); + end; +end; + +function concatstrings(const source: msestringarty; + const separator: msestring = ' '; const quotechar: msechar = #0; + const force: boolean = false): msestring; +var + int1: integer; + sepchar: msechar; +begin + if source = nil then begin + result:= ''; + end + else begin + if quotechar = #0 then begin + result:= source[0]; + for int1:= 1 to high(source) do begin + result:= result + separator + source[int1]; + end; + end + else begin + sepchar:= pmsechar(separator)^; + result:= quotestring(source[0],quotechar,force); + for int1:= 1 to high(source) do begin + result:= result + separator + + quotestring(source[int1],quotechar,force,sepchar); + end; + end; + end; +end; + +function concatstrings(const source: stringarty; + const separator: string = ' '; const quotechar: char = #0; + const force: boolean = false): string; +var + int1: integer; + sepchar: char; +begin + if source = nil then begin + result:= ''; + end + else begin + if quotechar = #0 then begin + result:= source[0]; + for int1:= 1 to high(source) do begin + result:= result + separator + source[int1]; + end; + end + else begin + sepchar:= pchar(separator)^; + result:= quotestring(source[0],quotechar,force); + for int1:= 1 to high(source) do begin + result:= result + separator + + quotestring(source[int1],quotechar,force,sepchar); + end; + end; + end; +end; + +procedure stringaddref(var str: ansistring); +var + po1: psizeint; +begin + if pointer(str) <> nil then begin + po1:= pointer(str)-2*sizeof(sizeint); + if po1^ >= 0 then begin + inc(po1^); + end; + end; +end; + +procedure stringaddref(var str: msestring); +{$ifndef msestringsarenotrefcounted} +var + po1: psizeint; +{$endif} +begin + if pointer(str) <> nil then begin +{$ifndef msestringsarenotrefcounted} + po1:= pointer(str)-2*sizeof(sizeint); + if po1^ >= 0 then begin + inc(po1^); + end; +{$else} + reallocstring(str); //delphi and FPC 2.2 + //widestrings are not refcounted on win32 +{$endif} + end; +end; + +procedure stringsafefree(var str: string; const onlyifunique: boolean); +var + po1: psizeint; +begin + if pointer(str) <> nil then begin + po1:= pointer(str)-2*sizeof(sizeint); + if (po1^ >= 0) and (not onlyifunique or (po1^ = 1)) then begin + fillchar(pointer(str)^,length(str)*sizeof(str[1]),0); + str:= ''; + end; + end; +end; + +procedure stringsafefree(var str: msestring; const onlyifunique: boolean); +var + po1: psizeint; +begin + if pointer(str) <> nil then begin + po1:= pointer(str)-2*sizeof(sizeint); + if (po1^ >= 0) and (not onlyifunique or (po1^ = 1)) then begin + fillchar(pointer(str)^,length(str)*sizeof(str[1]),0); + str:= ''; + end; + end; +end; + +procedure splitstringquoted(const source: string; out dest: stringarty; + quotechar: char = '"'; separator: char = #0); +var + po1,po2: pchar; + count: integer; + str1: string; + + procedure addsubstring; + var + int1: integer; + begin + if po1 <> po2 then begin + int1:= length(str1); + setlength(str1,int1+(po1-po2)); + move(po2^,str1[int1+1],(po1-po2)*sizeof(char)); + end; + end; + +begin + dest:= nil; + po1:= pointer(source); + if po1 <> nil then begin + count:= 0; + while po1^ <> #0 do begin + if separator = #0 then begin + while (po1^ = ' ') or (po1^ = c_tab) do begin + inc(po1); + end; + end + else begin + while true do begin + if po1^ = quotechar then begin + break; + end; + po2:= po1; + while (po1^ <> separator) and (po1^ <> #0) do begin + inc(po1); + end; + setstring(str1,po2,po1-po2); + additem(dest,str1,count); + if po1^ <> #0 then begin + inc(po1); + end + else begin + setlength(dest,count); + exit; + end; + end; + end; + str1:= ''; + if po1^ <> quotechar then begin + po2:= po1; + while (po1^ <> quotechar) and (po1^ <> ' ') and (po1^ <> c_tab) and (po1^ <> #0) do begin + inc(po1); + end; + addsubstring; + end + else begin + while po1^ <> #0 do begin + inc(po1); //po1^ = quotechar + po2:= po1; + while (po1^ <> quotechar) and (po1^ <> #0) do begin + inc(po1); + end; + if po1^ <> #0 then begin // ? + if (po1+1)^ = quotechar then begin// "....""... + inc(po1); // ? + addsubstring; // "....""... + end + else begin // ? + addsubstring; // "....".... + inc(po1); // ? + // "....".... + // "...."..,.. + if (separator <> #0) then begin + while (po1^ <> #0) and (po1^ <> separator) do begin + inc(po1); + end; + // ? + // "...."..,.. + if po1^ = separator then begin + inc(po1); + end; + // ? + // "...."..,.. + end; + break; + end; + end; + end; + end; + additem(dest,str1,count); + end; + setlength(dest,count); + end; +end; + +procedure splitstringquoted(const source: msestring; out dest: msestringarty; + quotechar: msechar = '"'; separator: msechar = #0); +var + po1,po2: pmsechar; + count: integer; + str1: msestring; + + procedure addsubstring; + var + int1: integer; + begin + if po1 <> po2 then begin + int1:= length(str1); + setlength(str1,int1+(po1-po2)); + move(po2^,str1[int1+1],(po1-po2)*sizeof(msechar)); + end; + end; + +begin + dest:= nil; + po1:= pointer(source); + if po1 <> nil then begin + count:= 0; + while po1^ <> #0 do begin + if separator = #0 then begin + while (po1^ = ' ') or (po1^ = c_tab) do begin + inc(po1); + end; + end + else begin + while true do begin + if po1^ = quotechar then begin + break; + end; + po2:= po1; + while (po1^ <> separator) and (po1^ <> #0) do begin + inc(po1); + end; + setstring(str1,po2,po1-po2); + additem(dest,str1,count); + if po1^ <> #0 then begin + inc(po1); + end + else begin + setlength(dest,count); + exit; + end; + end; + end; + str1:= ''; + if po1^ <> quotechar then begin + po2:= po1; + while (po1^ <> quotechar) and (po1^ <> ' ') and (po1^ <> c_tab) and (po1^ <> #0) do begin + inc(po1); + end; + addsubstring; + end + else begin + while po1^ <> #0 do begin + inc(po1); //po1^ = quotechar + po2:= po1; + while (po1^ <> quotechar) and (po1^ <> #0) do begin + inc(po1); + end; + if po1^ <> #0 then begin // ? + if (po1+1)^ = quotechar then begin// "....""... + inc(po1); // ? + addsubstring; // "....""... + end + else begin // ? + addsubstring; // "....".... + inc(po1); // ? + // "....".... + // "...."..,.. + if (separator <> #0) then begin + while (po1^ <> #0) and (po1^ <> separator) do begin + inc(po1); + end; + // ? + // "...."..,.. + if po1^ = separator then begin + inc(po1); + end; + // ? + // "...."..,.. + end; + break; + end; + end; + end; + end; + additem(dest,str1,count); + end; + setlength(dest,count); + end; +end; + +function breaklines(const source: string): stringarty; +var + int1,int2: integer; +begin + result:= nil; + splitstring(source,result,c_linefeed); + for int1:= 0 to high(result) do begin + int2:= length(result[int1]); + if (int2 > 0) and (result[int1][int2] = c_return) then begin + setlength(result[int1],int2-1); + end; + end; +end; + +function breaklines(const source: msestring): msestringarty; +var + int1,int2: integer; +begin + result:= nil; + splitstring(source,result,c_linefeed); + for int1:= 0 to high(result) - 1 do begin + while true do begin + int2:= length(result[int1]); + if (int2 > 0) and (result[int1][int2] = c_return) then begin + setlength(result[int1],int2-1); + end + else begin + break; + end; + end; + end; +end; + +function breaklines(const source: msestring; maxlength: integer): msestringarty; +var + charindex,charindexbefore,rowindex,lineend,lastbreak: integer; + int1,int2,len: integer; + po1: pmsechar; + mch1: msechar; + bo1: boolean; +begin + len:= length(source); + setlength(result,len div 10 + 1); + if source <> '' then begin + if maxlength <= 0 then begin + maxlength:= 1; + end; + rowindex:= 0; + charindex:= 1; + while charindex <= length(source) do begin + if rowindex > high(result) then begin + setlength(result,length(result)*2); + end; + charindexbefore:= charindex; + charindex:= length(source); + lineend:= 0; + lastbreak:= 0; + int2:= 1; + bo1:= false; + for int1:= charindexbefore to len do begin + mch1:= source[int1]; + if bo1 and ((mch1 = ' ') or (mch1 = c_tab)) then begin + lineend:= int1; + charindex:= int1; + end; + if mch1 = c_return then begin + lineend:= int1; + charindex:= int1; + if source[charindex+1] = c_linefeed then begin + inc(charindex); + end; + break; + end; + if mch1 = c_linefeed then begin + lineend:= int1; + charindex:= int1; + break; + end; + if (int2 <= maxlength) and ((mch1 = c_softhyphen) or (mch1 = '-') or + (mch1 = ' ') or (mch1 = c_tab)) then begin + lastbreak:= int1; + end; + if bo1 then begin + break; + end; + if mch1 <> c_softhyphen then begin + inc(int2); + end; + if int2 > maxlength then begin + charindex:= int1; + if int1 = len then begin + lineend:= int1 + 1; + end; + bo1:= true; + end; + end; + inc(charindex); + if lineend = 0 then begin + if int2 <= maxlength then begin + lineend:= charindex; + end + else begin + lineend:= lastbreak; + if lineend = 0 then begin + lineend:= charindex; + end + else begin + charindex:= lineend + 1; + mch1:= source[lineend]; + if (mch1 = c_softhyphen) or (mch1 = '-') then begin + inc(lineend); + end; + end; + end; + end; + setlength(result[rowindex],lineend-charindexbefore); //max + po1:= pointer(result[rowindex]); + if po1 <> nil then begin + for int1:= charindexbefore to lineend - 1 do begin + po1^:= source[int1]; + if po1^ <> c_softhyphen then begin + inc(po1); + end; + end; + if source[lineend-1] = c_softhyphen then begin + inc(po1); + end; + setlength(result[rowindex],po1-pmsechar(result[rowindex])); + end; + inc(rowindex); + end; + setlength(result,rowindex); + end; +end; + +function fitstring(const source: msestring; const len: integer; + const pos: stringposty = sp_left; + const cutchar: msechar = #0; + const padchar: msechar = ' '): msestring; + //cutchar = 0 -> no cutchar + procedure pad(const dest: pmsechar; const count: integer); + var + int1: integer; + ch1: msechar; + begin + ch1:= padchar; + for int1:= 0 to count-1 do begin + {$ifdef FPC} + dest[int1]:= ch1; + {$else} + pmsecharaty(dest)^[int1]:= ch1; + {$endif} + end; + end; + +var + copylen,padlen: integer; + int1: integer; +begin //fitstring + if (length(source) > len) and (cutchar <> #0) then begin + result:= charstring(cutchar,len); + end + else begin + setlength(result,len); + if len > 0 then begin + copylen:= length(source); + padlen:= len - copylen; + if padlen < 0 then begin + copylen:= len; + padlen:= 0; + end; + case pos of + sp_center: begin + int1:= padlen div 2; + move((pmsechar(pointer(source))+(length(source)-copylen) div 2)^, + (pmsechar(pointer(result))+int1)^,copylen*sizeof(msechar)); + pad(pointer(result),int1); + pad(pmsechar(pointer(result))+int1+copylen,len-copylen-int1); + end; + sp_right: begin + move((pmsechar(pointer(source))+length(source)-copylen)^, + (pmsechar(pointer(result))+padlen)^,copylen*sizeof(msechar)); + pad(pmsechar(pointer(result)),padlen); + end; + else begin //sp_left + move(pointer(source)^,pointer(result)^,copylen*sizeof(msechar)); + pad(pmsechar(pointer(result))+copylen,padlen); + end; + end; + end; + end; +end; + +procedure splitstring(source: string; + var dest: stringarty; separator: char = c_tab; + trim: boolean = false); + // dest = [] -> length(dest) = anzahl vorhandene teile + // sonst length(dest) <= length(dest uebergeben), + // ganzer rest im letzten string, fallse mehr vorhandene teile als + // uebergebene strings +var + int2,int3: integer; + po,po1,po2: pchar; + all: boolean; + bo1: boolean; + +begin + all:= length(dest) = 0; + if all then begin + int2:= countchars(source,separator); + setlength(dest,int2+1); //maximale zahl + end + else begin + for int2:= 0 to length(dest)-1 do begin + dest[int2]:= ''; + end; + end; + po:= pchar(source); + int3:= length(source); + bo1:= false; + for int2:= 0 to length(dest) - 1 do begin + if int3 <= 0 then begin + if bo1 and (int2 < length(dest)) then begin + setlength(dest,int2+1); //leerer schluss + end + else begin + setlength(dest,int2); + end; + break; + end; + po2:= po; + po1:= strlscan(po,separator,int3); + if (po1 = nil) or (int2 = high(dest)) then begin + po1:= po + int3; //rest + bo1:= false; + end + else begin + bo1:= true; + end; + if trim then begin + po:= strnscan(po,' '); + end; + if po <> nil then begin + if trim then begin + dest[int2]:= trimright(strlcopy(po,po1-po)); + end + else begin + dest[int2]:= strlcopy(po,po1-po); + end; + end; + if trim and (separator = ' ') then begin + po1:= strlnscan(po1,separator,int3); + if po1 = nil then begin + int3:= 0; + end; + end + else begin + inc(po1); + end; + int3:= int3 - (po1 - po2); + //verbrauchte stringlaenge + po:= po1; + end; +end; + +procedure splitstring(source: msestring; + var dest: msestringarty; separator: msechar = c_tab; + trim: boolean = false); + // dest = [] -> length(dest) = anzahl vorhandene teile + // sonst length(dest) <= length(dest uebergeben), + // ganzer rest im letzten string, fallse mehr vorhandene teile als + // uebergebene strings +var + int2,int3: integer; + po,po1,po2: pmsechar; + all: boolean; + bo1: boolean; + +begin + all:= length(dest) = 0; + if all then begin + int2:= countchars(source,separator); + setlength(dest,int2+1); //maximale zahl + end + else begin + for int2:= 0 to length(dest)-1 do begin + dest[int2]:= ''; + end; + end; + po:= pmsechar(source); + int3:= length(source); + bo1:= false; + for int2:= 0 to length(dest) - 1 do begin + if int3 <= 0 then begin + if bo1 and (int2 < length(dest)) then begin + setlength(dest,int2+1); //leerer schluss + end + else begin + setlength(dest,int2); + end; + break; + end; + po2:= po; + po1:= msestrlscan(po,separator,int3); + if (po1 = nil) or (int2 = high(dest)) then begin + po1:= po + int3; //rest + bo1:= false; + end + else begin + bo1:= true; + end; + if trim then begin + po:= msestrnscan(po,' '); + end; + if po <> nil then begin + if trim then begin + dest[int2]:= trimright(msestrlcopy(po,po1-po)); + end + else begin + dest[int2]:= msestrlcopy(po,po1-po); + end; + end; + if trim and (separator = ' ') then begin + po1:= msestrlnscan(po1,separator,int3); + if po1 = nil then begin + int3:= 0; + end; + end + else begin + inc(po1); + end; + int3:= int3 - (po1 - po2); + //verbrauchte stringlaenge + po:= po1; + end; +end; + +function splitstring(source: string; separator: char = c_tab; + trim: boolean = false): stringarty; +begin + result:= nil; + splitstring(source,result,separator,trim); +end; + +function splitstring(source: msestring; separator: msechar = c_tab; + trim: boolean = false): msestringarty; +begin + result:= nil; + splitstring(source,result,separator,trim); +end; + +function splitstringquoted(source: string; separator: char = c_tab; + quotechar: char = '"'; + atrim: boolean = false): stringarty; +var + int1: integer; +begin + splitstringquoted(source,result,quotechar,separator); + if atrim then begin + for int1:= 0 to high(result) do begin + result[int1]:= trim(result[int1]); + end; + end; +end; + +function splitstringquoted(source: msestring; separator: msechar = c_tab; + quotechar: msechar = '"'; + atrim: boolean = false): msestringarty; overload; +var + int1: integer; +begin + splitstringquoted(source,result,quotechar,separator); + if atrim then begin + for int1:= 0 to high(result) do begin + result[int1]:= trim(result[int1]); + end; + end; +end; + +function stringfromchar(achar: char; count : integer): string; +var + int1: integer; +begin + setlength(result,count); + for int1:= 1 to count do begin + result[int1]:= achar; + end; +end; + +function stringfromchar(achar: msechar; count : integer): msestring; +var + int1: integer; +begin + setlength(result,count); + for int1:= 1 to count do begin + result[int1]:= achar; + end; +end; + +function parsecommandline(const s: pchar): stringarty; +var + po1,po2: pchar; + count: integer; + str1: string; + + procedure addsubstring; + var + int1,int2: integer; + begin + {$ifdef FPC}{$checkpointer off}{$endif} + int1:= po1-po2; + int2:= length(str1); + setlength(str1,int2+int1); + move(po2^,str1[int2+1],int1); + po2:= po1; + {$ifdef FPC}{$checkpointer default}{$endif} + end; + +begin + result:= nil; + count:= 0; + if s <> nil then begin + {$ifdef FPC}{$checkpointer off}{$endif} + po1:= s; + while (po1^ <> #0) and (po1^ = ' ') do begin + inc(po1); + end; + if po1^ <> #0 then begin + po2:= po1; + str1:= ''; + while true do begin + case po1^ of + ' ',#0: begin + addsubstring; + additem(result,str1,count); + str1:= ''; + while (po1^ <> #0) and (po1^ = ' ') do begin + inc(po1); + end; + if po1^ = #0 then begin + break; + end; + po2:= po1; + end; + '"': begin + addsubstring; + po2:= po1 + 1; + repeat + inc(po1); + case po1^ of + '"': begin + addsubstring; + inc(po1); + inc(po2); + break; + end; + { + '\': begin + if (po1+1)^ = '"' then begin + addsubstring; + inc(po1); + inc(po2); + end; + end; + } + end; + until po1^ = #0; + end; + { + '\': begin + if ((po1+1)^ < ' ') or ((po1+1)^ in ['"','\']) then begin + addsubstring; + inc(po1); + if po1^ = #0 then begin + break; + end; + inc(po1); + inc(po2); + end + else begin + inc(po1); + end; + end; + } + else begin + inc(po1); + end; + end; + end; + end; + {$ifdef FPC}{$checkpointer default}{$endif} + setlength(result,count); + end; +end; + +function parsecommandline(const s: pmsechar): msestringarty; +var + po1,po2: pmsechar; + count: integer; + str1: msestring; + + procedure addsubstring; + var + int1,int2: integer; + begin + {$ifdef FPC}{$checkpointer off}{$endif} + int1:= po1-po2; + int2:= length(str1); + setlength(str1,int2+int1); + move(po2^,str1[int2+1],int1*sizeof(msechar)); + po2:= po1; + {$ifdef FPC}{$checkpointer default}{$endif} + end; + +begin + result:= nil; + count:= 0; + if s <> nil then begin + {$ifdef FPC}{$checkpointer off}{$endif} + po1:= s; + while (po1^ <> #0) and (po1^ = ' ') do begin + inc(po1); + end; + if po1^ <> #0 then begin + po2:= po1; + str1:= ''; + while true do begin + case po1^ of + ' ',#0: begin + addsubstring; + additem(result,str1,count); + str1:= ''; + while (po1^ <> #0) and (po1^ = ' ') do begin + inc(po1); + end; + if po1^ = #0 then begin + break; + end; + po2:= po1; + end; + '"': begin + addsubstring; + po2:= po1 + 1; + repeat + inc(po1); + case po1^ of + '"': begin + addsubstring; + inc(po1); + inc(po2); + break; + end; + { + '\': begin + if (po1+1)^ = '"' then begin + addsubstring; + inc(po1); + inc(po2); + end; + end; + } + end; + until po1^ = #0; + end; + { + '\': begin + if ((po1+1)^ < ' ') or ((po1+1)^ in ['"','\']) then begin + addsubstring; + inc(po1); + if po1^ = #0 then begin + break; + end; + inc(po1); + inc(po2); + end + else begin + inc(po1); + end; + end; + } + else begin + inc(po1); + end; + end; + end; + end; + {$ifdef FPC}{$checkpointer default}{$endif} + setlength(result,count); + end; +end; + +function parsecommandline(const s: string): stringarty; +begin + result:= parsecommandline(pchar(s)); +end; + +function parsecommandline(const s: msestring): msestringarty; +begin + result:= parsecommandline(pmsechar(s)); +end; + +procedure trimright1(var s: string); overload; +var + po1,po2: pchar; +begin + if s <> '' then begin + po1:= pointer(s); + po2:= po1+length(s)-1; + while (po2^ <= ' ') do begin + dec(po2); + if po2 < po1 then begin + break; + end; + end; + setlength(s,po2-po1+1); + end; +end; + +procedure trimright1(var s: msestring); overload; +var + po1,po2: pmsechar; +begin + if s <> '' then begin + po1:= pointer(s); + po2:= po1+length(s)-1; + while (po2^ <= ' ') do begin + dec(po2); + if po2 < po1 then begin + break; + end; + end; + setlength(s,po2-po1+1); + end; +end; + +function printableascii(const source: string): string; + //removes all nonprintablechars and ' ' +var + int1,int2: integer; + ca1: char; +begin + setlength(result,length(source)); + int2:= 0; + for int1:= 0 to length(source)-1 do begin + ca1:= pcharaty(source)^[int1]; + if (ca1 > ' ') and (ca1 < #127) then begin + pcharaty(result)^[int2]:= ca1; + inc(int2); + end; + end; + setlength(result,int2); +end; + +function printableascii(const source: msestring): msestring; + //removes all nonprintablechars and ' ' +var + int1,int2: integer; + ca1: msechar; +begin + setlength(result,length(source)); + int2:= 0; + for int1:= 0 to length(source)-1 do begin + ca1:= pmsecharaty(source)^[int1]; + if (ca1 > ' ') and (ca1 < #127) then begin + pmsecharaty(result)^[int2]:= ca1; + inc(int2); + end; + end; + setlength(result,int2); +end; + +function removechar(const source: string; a: char): string; + //removes all a +var + int1,int2: integer; +begin + setlength(result,length(source)); + int2:= 0; + for int1:= 1 to length(source) do begin + if source[int1] <> a then begin + pcharaty(result)^[int2]:= source[int1]; + inc(int2); + end; + end; + setlength(result,int2); +end; + +procedure removechar1(var dest: string; a: char); + //removes all a +begin + dest:= removechar(dest,a); +end; + +function removechar(const source: msestring; a: msechar): msestring; + //removes all a +var + int1,int2: integer; +begin + setlength(result,length(source)); + int2:= 0; + for int1:= 1 to length(source) do begin + if source[int1] <> a then begin + pmsecharaty(result)^[int2]:= source[int1]; + inc(int2); + end; + end; + setlength(result,int2); +end; + +procedure removechar1(var dest: msestring; a: msechar); + //removes all a +begin + dest:= removechar(dest,a); +end; + +function replacechar(const source: string; old,new: char): string; + //replaces a by b +begin + result:= source; + replacechar1(result,old,new); +end; +{ +procedure replacechar1(var dest: string; a,b: char); + //replaces a by b +var + int1: integer; +begin + uniquestring(dest); + for int1:= 0 to length(dest)-1 do begin + if pcharaty(dest)^[int1] = a then begin + pcharaty(dest)^[int1]:= b; + end; + end; +end; +} +procedure replacechar1(var dest: string; old,new: char); + //replaces a by b +var + pd,pe: pchar; +begin + uniquestring(dest); + pd:= pointer(dest); + pe:= pd + length(dest); + while pd < pe do begin + if pd^ = old then begin + pd^:= new; + end; + inc(pd); + end; +end; + +function replacechar(const source: msestring; old,new: msechar): msestring; + //replaces a by b +begin + result:= source; + replacechar1(result,old,new); +end; +{ +procedure replacechar1(var dest: msestring; a,b: msechar); + //replaces a by b +var + int1: integer; +begin + uniquestring(dest); + for int1:= 0 to length(dest)-1 do begin + if pmsecharaty(dest)^[int1] = a then begin + pmsecharaty(dest)^[int1]:= b; + end; + end; +end; +} + +procedure replacechar1(var dest: msestring; old,new: msechar); + //replaces a by b +var + pd,pe: pmsechar; +begin + uniquestring(dest); + pd:= pointer(dest); + pe:= pd + length(dest); + while pd < pe do begin + if pd^ = old then begin + pd^:= new; + end; + inc(pd); + end; +end; + +procedure replacetext1(var dest: string; index: integer; const a: string); + //dest will be extended with spaces if necessary +var + int1,int2: integer; +begin + uniquestring(dest); + if length(dest) < index + length(a) then begin + int1:= length(dest); + setlength(dest,index+length(a)-1); + for int2:= int1 to index - 2 do begin + pcharaty(dest)^[int2]:= ' '; + end; + end; + dec(index); + int1:= length(a); + if index < 0 then begin + int1:= int1 + index; + index:= 0; + end; + for int2:= 0 to int1-1 do begin + pcharaty(dest)^[int2+index]:= pcharaty(a)^[int2]; + end; +end; + +function replacetext(const source: string; index: integer; a: string): string; +begin + result:= source; + replacetext1(result,index,a); +end; + +procedure replacetext1(var dest: msestring; index: integer; const a: msestring); + //dest will be extended with spaces if necessary +var + int1,int2: integer; +begin + uniquestring(dest); + if length(dest) < index + length(a) then begin + int1:= length(dest); + setlength(dest,index+length(a)-1); + for int2:= int1 to index - 2 do begin + pmsecharaty(dest)^[int2]:= ' '; + end; + end; + dec(index); + int1:= length(a); + if index < 0 then begin + int1:= int1 + index; + index:= 0; + end; + for int2:= 0 to int1-1 do begin + pmsecharaty(dest)^[int2+index]:= pmsecharaty(a)^[int2]; + end; +end; + +function replacetext(const source: msestring; index: integer; a: msestring): msestring; +begin + result:= source; + replacetext1(result,index,a); +end; + +procedure addstringsegment(var dest: msestring; const a,b: pmsechar); +var + int1,int2: integer; +begin + int1:= length(dest); + int2:= b-a; + setlength(dest,int1 + int2); + move(a^,dest[int1+1],int2*sizeof(msechar)); +end; + +function stringsegment(a,b: pchar): string; +var + int1: integer; +begin + int1:= b - a; + setlength(result,int1); + move(a^,result[1],int1*sizeof(char)); +end; + +function stringsegment(a,b: pmsechar): msestring; +var + int1: integer; +begin + int1:= b - a; + setlength(result,int1); + move(a^,result[1],int1*sizeof(msechar)); +end; + +function countleadingchars(const str: msestring; char: msechar): integer; +var + int1: integer; + po1,po2: pmsechar; +begin + int1:= length(str); + if int1 > 0 then begin + po1:= pointer(str); + po2:= msestrlnscan(po1,' ',int1); + if po2 = nil then begin + result:= int1; + end + else begin + result:= po2-po1; + end; + end + else begin + result:= -1; //leer + end; +end; + +function countleadingchars(const str: string; char: char): integer; +var + int1: integer; + po1,po2: pchar; +begin + int1:= length(str); + if int1 > 0 then begin + po1:= pointer(str); + po2:= strlnscan(po1,' ',int1); + if po2 = nil then begin + result:= int1; + end + else begin + result:= po2-po1; + end; + end + else begin + result:= -1; //leer + end; +end; + +function nullstring(const count: integer): string; +begin + if count > 0 then begin + setlength(result,count); + fillchar(pointer(result)^,count,#0 ); + end + else begin + result:= ''; + end; +end; + +function charstring(ch: char; count: integer): string; overload; +begin + if count > 0 then begin + setlength(result,count); + for count:= count - 1 downto 0 do begin + (pchar(pointer(result)) + count)^:= ch; + // result[count]:= ch; + end; + end + else begin + result:= ''; + end; +end; + +function charstring(ch: msechar; count: integer): msestring; overload; +begin + if count > 0 then begin + setlength(result,count); + for count:= count - 1 downto 0 do begin + (pmsechar(pointer(result)) + count)^:= ch; + // result[count]:= ch; + end; + end + else begin + result:= ''; + end; +end; +{ +function posmse(substring: pmsechar; const s: lmsestringty): pmsechar; +var + po1: pmsechar; + int1: integer; +begin + if (substring <> nil) and (substring^ <> #0) and + (s.po <> nil) and (s.len > 0) then begin + result:= msestrlscan(s.po,substring^,s.len); + int1:= s.len - (s.po-result) - 1; + if result <> nil then begin + po1:= result; + while (substring^ <> #0) and (int1 > 0) do begin + dec(int1); + inc(substring); + inc(po1); + if po1^ <> substring^ then begin + break; + end; + end; + if po1^ <> #0 then begin + result:= nil; + end; + end; + end + else begin + result:= nil; + end; +end; +} +{ +function msestrpos(const substr: msestring; const s: msestring): integer; +var + po1,po2,po3,po4: pmsechar; +begin + po3:= pmsechar(substr); + if po3^ <> #0 then begin + po4:= pmsechar(s); + repeat + while (po4^ <> #0) and (po4^ <> po3^) do begin + inc(po4); + end; + po1:= po3; + po2:= po4; + while (po1^ <> #0) and (po1^ = po2^) do begin + inc(po1); + inc(po2); + end; + if po1^ = #0 then begin + result:= po4 - pmsechar(s) + 1; + exit; + end; + inc(po4); + until po2^ = #0; + end; + result:= 0; +end; + +function msetextpos1(const substrlower,substrupper: msestring; const s: msestring): integer; +var + po1l,po1u,po2,po3l,po3u,po4: pmsechar; +begin + po3l:= pmsechar(substrlower); + po3u:= pmsechar(substrupper); + if po3l^ <> #0 then begin + po4:= pmsechar(s); + repeat + while (po4^ <> #0) and (po4^ <> po3l^) and (po4^ <> po3u^) do begin + inc(po4); + end; + po1l:= po3l; + po1u:= po3u; + po2:= po4; + while (po1l^ <> #0) and ((po1l^ = po2^) or (po1u^ = po2^)) do begin + inc(po1l); + inc(po1u); + inc(po2); + end; + if po1l^ = #0 then begin + result:= po4 - pmsechar(s) + 1; + exit; + end; + inc(po4); + until po2^ = #0; + end; + result:= 0; +end; + + +function msetextpos(const substr: msestring; const s: msestring): integer; + //substr has to be uppercase +begin + result:= msetextpos1(mseuppercase(substr),mseuppercase(substr),s); +end; +} + +function charuppercase(const c: char): char; +begin + result:= upperchars[c]; +end; + +function charuppercase(const c: msechar): msechar; +begin + if c < #$100 then begin + result:= msechar(byte(upperchars[char(byte(c))])); + end + else begin + result:= c; + end; +end; + +function struppercase(const s: string): string; overload; +var + int1,int2: integer; +begin + int1:= length(s); + setlength(result,int1); + for int2:= int1 - 1 downto 0 do begin + pcharaty(result)^[int2]:= upperchars[pcharaty(s)^[int2]]; + end; +end; + +function struppercase(const s: msestring): msestring; overload; +var + ch1: msechar; + int1: integer; + po1,po2: pmsecharaty; +begin + setlength(result,length(s)); + po1:= pointer(s); + po2:= pointer(result); + for int1:= length(s) - 1 downto 0 do begin + ch1:= po1^[int1]; + if (ch1 >= 'a') and (ch1 <= 'z') then begin + inc(ch1,ord('A') - ord('a')); + end; + po2^[int1]:= ch1; + end; +end; + +procedure struppercase1(var s: msestring); overload; +var + ch1: msechar; + int1: integer; + po1: pmsecharaty; +begin + po1:= pointer(s); + for int1:= 0 to length(s) - 1 do begin + ch1:= po1^[int1]; + if (ch1 >= 'a') and (ch1 <= 'z') then begin + inc(ch1,ord('A') - ord('a')); + end; + po1^[int1]:= ch1; + end; +end; + +function struppercase(const s: lmsestringty): msestring; overload; +var + Ch1: msechar; + int1: Integer; + Source, Dest: Pmsechar; +begin + int1:= s.len; + setlength(result,int1); + Source := s.po; + Dest := Pointer(Result); + while int1 > 0 do begin + Ch1 := Source^; + if (Ch1 >= 'a') and (Ch1 <= 'z') then Dec(Ch1, 32); + Dest^ := Ch1; + Inc(Source); + Inc(Dest); + Dec(int1); + end; +end; + +function struppercase(const s: lstringty): string; overload; +var + int1: integer; +begin + setlength(result,s.len); + for int1:= 0 to s.len - 1 do begin + pcharaty(result)^[int1]:= upperchars[pcharaty(s.po)^[int1]]; + end; +end; + +function charlowercase(const c: char): char; +begin + result:= lowerchars[c]; +end; + +function charlowercase(const c: msechar): msechar; +begin + if ord(c) < $100 then begin + result:= msechar(lowerchars[char(c)]); + end + else begin + result:= c; + end; +end; + +function strlowercase(const s: string): string; overload; +var + int1,int2: integer; +begin + int1:= length(s); + setlength(result,int1); + for int2:= int1 - 1 downto 0 do begin + pcharaty(result)^[int2]:= lowerchars[pcharaty(s)^[int2]]; + end; +end; + +function strlowercase(const s: msestring): msestring; overload; +var + ch1: msechar; + int1: integer; + po1,po2: pmsecharaty; +begin + setlength(result,length(s)); + po1:= pointer(s); + po2:= pointer(result); + for int1:= length(s) - 1 downto 0 do begin + ch1:= po1^[int1]; + if (ch1 >= 'A') and (ch1 <= 'Z') then begin + inc(ch1,ord('a') - ord('A')); + end; + po2^[int1]:= ch1; + end; +end; + +procedure strlowercase1(var s: msestring); overload; +var + ch1: msechar; + int1: integer; + po1: pmsecharaty; +begin + po1:= pointer(s); + for int1:= 0 to length(s) - 1 do begin + ch1:= po1^[int1]; + if (ch1 >= 'A') and (ch1 <= 'Z') then begin + inc(ch1,ord('a') - ord('A')); + end; + po1^[int1]:= ch1; + end; +end; + +function strlowercase(const s: lmsestringty): msestring; overload; +var + Ch1: msechar; + int1: Integer; + Source, Dest: Pmsechar; +begin + int1:= s.len; + setlength(result,int1); + Source := s.po; + Dest := Pointer(Result); + while int1 > 0 do begin + Ch1 := Source^; + if (Ch1 >= 'A') and (Ch1 <= 'Z') then Dec(Ch1, 32); + Dest^ := Ch1; + Inc(Source); + Inc(Dest); + Dec(int1); + end; +end; + +function strlowercase(const s: lstringty): string; overload; +var + int1: integer; +begin + setlength(result,s.len); + for int1:= 0 to s.len - 1 do begin + pcharaty(result)^[int1]:= lowerchars[pcharaty(s.po)^[int1]]; + end; +end; + +function lstringtostring(const value: lmsestringty): msestring; overload; +begin + setlength(result,value.len); + move(value.po^,result[1],value.len*sizeof(msechar)); +end; + +function lstringtostring(const value: pmsechar; + const len: integer): msestring; overload; +begin + setlength(result,len); + move(value^,result[1],len*sizeof(msechar)); +end; + +function lstringtostring(const value: lstringty): string; overload; +begin + setlength(result,value.len); + move(value.po^,result[1],value.len*sizeof(char)); +end; + +function lstringtostring(const value: pchar; + const len: integer): string; overload; +begin + setlength(result,len); + move(value^,result[1],len*sizeof(char)); +end; + +procedure stringtolstring(const value: string; var{out} res: lstringty); +begin + res.po:= pointer(value); + res.len:= length(value); +end; + +procedure stringtolstring(const value: msestring; var{out} res: lmsestringty); + inline; +begin + res.po:= pointer(value); + res.len:= length(value); +end; + +function stringtolstring(const value: string): lstringty; inline; +begin + result.po:= pointer(value); + result.len:= length(value); +end; + +function stringtolstring(const value: msestring): lmsestringty; inline; +begin + result.po:= pointer(value); + result.len:= length(value); +end; + +function lstringartostringar(const value: lstringarty): stringarty; +var + int1: integer; +begin + setlength(result,length(value)); + for int1:= 0 to high(value) do begin + with value[int1] do begin + setstring(result[int1],po,len); + end; + end; +end; + +procedure nextword(const value: msestring; out res: lmsestringty); overload; +var + po1: pmsechar; +begin + res.po:= msestrlscan(pointer(value),' ',length(value)); + res.len:= length(value)-(res.po-pointer(value)); + po1:= msestrlnscan(res.po,' ',res.len); + if po1 <> nil then begin + res.len:= po1-res.po; + end; +end; + +procedure nextword(const value: string; out res: lstringty); overload; +var + po1: pchar; +begin + res.po:= strlnscan(pointer(value),' ',length(value)); + res.len:= length(value)-(res.po-pointer(value)); + po1:= strlscan(res.po,' ',res.len); + if po1 <> nil then begin + res.len:= po1-res.po; + end; +end; + +procedure nextword(var value: lmsestringty; out res: lmsestringty); overload; +var + po1: pmsechar; + int1: integer; +begin + res.po:= msestrlnscan(value.po,' ',value.len); + if res.po = nil then begin + int1:= value.len; + end + else begin + int1:= res.po-value.po; + end; + res.len:= value.len-int1; + po1:= msestrlscan(res.po,' ',res.len); + if po1 <> nil then begin + res.len:= po1-res.po; + end; + int1:= int1 + res.len; + inc(value.po,int1); + dec(value.len,int1); +end; + +procedure nextword(var value: lstringty; out res: lstringty); overload; +var + po1: pchar; + int1: integer; +begin + res.po:= strlnscan(value.po,' ',value.len); + if res.po = nil then begin + int1:= value.len; + end + else begin + int1:= res.po-value.po; + end; + res.len:= value.len-int1; + po1:= strlscan(res.po,' ',res.len); + if po1 <> nil then begin + res.len:= po1-res.po; + end; + int1:= int1 + res.len; + inc(value.po,int1); + dec(value.len,int1); +end; + +procedure nextword(var value: lstringty; out res: string); overload; +var + lstr1: lstringty; +begin + nextword(value,lstr1); + setstring(res,lstr1.po,lstr1.len); +end; + +function nextword(var start: pchar): string; +var + po1,po2: pchar; +begin + po1:= start; + while (po1^ = ' ') and (po1^ <> #0) do begin + inc(po1); + end; + po2:= po1; + while (po2^ <> ' ') and (po2^ <> #0) do begin + inc(po2); + end; + setlength(result,po2-po1); + move(po1^,pchar(pointer(result))^,pchar(pointer(po2))-pchar(pointer(po1))); + start:= po2; +end; + +function nextword(var start: pmsechar): msestring; +var + po1,po2: pmsechar; +begin + po1:= start; + while (po1^ = ' ') and (po1^ <> #0) do begin + inc(po1); + end; + po2:= po1; + while (po2^ <> ' ') and (po2^ <> #0) do begin + inc(po2); + end; + setlength(result,po2-po1); + move(po1^,pmsechar(pointer(result))^,pchar(pointer(po2))-pchar(pointer(po1))); + start:= po2; +end; + +procedure lstringgoback(var value: lstringty; const res: lstringty); +begin + dec(value.po,res.len); + inc(value.len,res.len); +end; + +function nextquotedstring(var value: lstringty; out res: string): boolean; +var + po1: pchar; + int1,int2,int3: integer; +begin + result:= false; + res:= ''; + po1:= strlnscan(value.po,' ',value.len); + if po1 = nil then begin + int1:= value.len; + end + else begin + int1:= po1-value.po; + end; + if (po1 <> nil) and (po1^ = '''') then begin + result:= true; + inc(po1); + int2:= 0; + int3:= value.len-int1; + setlength(res,int3); //maximum + while po1^ <> #0 do begin + if po1^ <> '''' then begin + inc(int2); + res[int2]:= po1^; + end + else begin + inc(po1); + if po1^ = '''' then begin + inc(int2); + res[int2]:= po1^; + end + else begin + break; + end; + end; + inc(po1); + end; + setlength(res,int2); + int1:= po1-value.po; + end; + inc(value.po,int1); + dec(value.len,int1); +end; + +function shrinkpathellipse(var value: msestring): boolean; +const + ellipsis = '...' + pathdelim; +var + po1,po2: pmsechar; + int1,int2: integer; +begin + result:= false; + int1:= pos(ellipsis,value); + if int1 = 0 then begin + int1:= pos(pathdelim,value); + if int1 > 0 then begin + inc(int1); //ellipsenstart + int2:= int1; //ellipsenend; + end + else exit; //shrink unmoeglich + end + else begin + int2:= int1 + length(ellipsis); + end; + po1:= @value[int2]; //ende ellipse + po2:= msestrlscan(po1,pathdelim,length(value)-int2); + if po2 <> nil then begin + inc(po2); + value:= copy(value,1,int1-1) + ellipsis + copy(value,int2 + (po2-po1),bigint); + result:= true; + end; +end; + +function shrinkstring(const value: msestring; maxcharcount: integer): msestring; +begin + result:= value; + repeat + until (length(result) <= maxcharcount) or not shrinkpathellipse(result); +end; + +procedure extendstring(var value: string; const mincharcount: integer); +var + int1: integer; +begin + int1:= length(value); + if int1 < mincharcount then begin + setlength(value,mincharcount); + for int1:= int1 to mincharcount do begin + pchar(pointer(value))[int1]:= ' '; + end; + end; +end; + +procedure extendstring(var value: msestring; const mincharcount: integer); +var + int1: integer; +begin + int1:= length(value); + if int1 < mincharcount then begin + setlength(value,mincharcount); + for int1:= int1 to mincharcount do begin + pmsechar(pointer(value))[int1]:= ' '; + end; + end; +end; + +function checkfirstchar(const value: string; achar: char): pchar; + //nil wenn erster char nicht space <> achar, ^achar sonst +begin + result:= strlnscan(pointer(value),' ',length(value)); + if result <> nil then begin + if result^ <> achar then begin + result:= nil; + end; + end; +end; + +function lastline(const atext: msestring): msestring; +var + po1: pmsechar; + int1: integer; +begin + po1:= msestrlrscan(pmsechar(atext),c_linefeed,length(atext)); + if po1 = nil then begin + result:= atext; + end + else begin + inc(po1); + int1:= length(atext)-(po1-pmsechar(pointer(atext))); + setlength(result,int1); + move(po1^,pointer(result)^,int1*sizeof(msechar)); +// result:= po1; + end; +end; + +function firstline(const atext: msestring): msestring; +var + po1: pmsechar; +begin + if atext <> '' then begin + po1:= pointer(atext); + while (po1^ <> c_linefeed) and (po1^ <> #0) do begin + inc(po1); + end; + if (po1 > pointer(atext)) and ((po1-1)^ = c_return) then begin + dec(po1); + end; + result:= psubstr(pmsechar(pointer(atext)),po1); + end + else begin + result:= ''; + end; +end; +{ +function firstline(atext: msestring): msestring; +var + po1: pmsechar; +begin + po1:= msestrlscan(pmsechar(atext),c_linefeed,length(atext)); + if po1 = nil then begin + result:= atext; + end + else begin + dec(po1); + if po1 >= @atext[1] then begin + if po1^ <> c_return then begin + inc(po1); + end; + end + else begin + inc(po1); + end; + setlength(result,po1-pmsechar(@atext[1])); + move(po1^,result[1],length(result)*sizeof(result[1])); + end; +end; +} +procedure textdim(const atext: msestring; out firstx,lastx,y: integer); +begin + Y:= countchars(atext,c_linefeed); + if Y = 0 then begin + firstx:= length(atext); + lastx:= firstx; + end + else begin + lastx:= length(lastline(atext)); + firstx:= length(firstline(atext)); + end; +end; + +function encodesearchoptions(const caseinsensitive: boolean = false; + const wholeword: boolean = false; + const wordstart: boolean = false; + const backward: boolean = false): searchoptionsty; +begin + result:= []; + if caseinsensitive then include(result,so_caseinsensitive); + if wholeword then include(result,so_wholeword); + if wordstart then include(result,so_wordstart); + if backward then include(result,so_backward); +end; + +function quotestring(value: string; quotechar: char; + const force: boolean = true; + const separator: char = ' '): string; overload; +var + ps,pd,pe: pchar; +begin + if force or (findchar(value,quotechar) > 0) or + (separator <> #0) and (findchar(value,separator) > 0)then begin + setlength(result,length(value)*2+2); //max + pd:= pchar(pointer(result)); + pd^:= quotechar; + inc(pd); + if value <> '' then begin + ps:= pchar(pointer(value)); + pe:= ps+length(value); + while ps < pe do begin + pd^:= ps^; + inc(pd); + if ps^ = quotechar then begin + pd^:= quotechar; + inc(pd); + end; + inc(ps); + end; + end; + pd^:= quotechar; + inc(pd); + setlength(result,pd-pchar(pointer(result))); + end + else begin + result:= value; + end; +end; + +function quotestring(value: msestring; quotechar: msechar; + const force: boolean = true; + const separator: msechar = ' '): msestring; overload; +var + ps,pd,pe: pmsechar; +begin + if force or (findchar(value,quotechar) > 0) or + (separator <> #0) and (findchar(value,separator) > 0) then begin + setlength(result,length(value)*2+2); //max + pd:= pmsechar(pointer(result)); + pd^:= quotechar; + inc(pd); + if value <> '' then begin + ps:= pmsechar(pointer(value)); + pe:= ps+length(value); + while ps < pe do begin + pd^:= ps^; + inc(pd); + if ps^ = quotechar then begin + pd^:= quotechar; + inc(pd); + end; + inc(ps); + end; + end; + pd^:= quotechar; + inc(pd); + setlength(result,pd-pmsechar(pointer(result))); + end + else begin + result:= value; + end; +end; + +function unquotestring(value: string; quotechar: char): string; overload; +var + ps,pd,pe: pchar; +begin + result:= value; + if (value <> '') and (value[1] = quotechar) then begin + ps:= pchar(pointer(value)); + pe:= ps + length(value); + setlength(result,length(value)); //unique, max + pd:= pchar(pointer(result)); + while ps < pe do begin + if ps^ = quotechar then begin + inc(ps); + end; + pd^:= ps^; + inc(ps); + inc(pd); + end; + if ps > pe then begin + dec(pd); //remove trailing quote + end; + setlength(result,pd-pchar(pointer(result))); + end; +end; + +function unquotestring(value: msestring; + quotechar: msechar): msestring; +var + ps,pd,pe: pmsechar; +begin + result:= value; + if (value <> '') and (value[1] = quotechar) then begin + ps:= pmsechar(pointer(value)); + pe:= ps + length(value); + setlength(result,length(value)); //unique, max + pd:= pmsechar(pointer(result)); + while ps < pe do begin + if ps^ = quotechar then begin + inc(ps); + end; + pd^:= ps^; + inc(ps); + inc(pd); + end; + if ps > pe then begin + dec(pd); //remove trailing quote + end; + setlength(result,pd-pmsechar(pointer(result))); + end; +end; + + +const + escapechar = '\'; + +function quoteescapedstring(value: string; quotechar: char; + const force: boolean = true; + const separator: char = ' '): string; +var + ps,pd,pe: pchar; +begin + if force or (findchar(value,quotechar) > 0) or + (separator <> #0) and (findchar(value,separator) > 0) then begin + setlength(result,length(value)*2+2); //max + pd:= pchar(pointer(result)); + pd^:= quotechar; + inc(pd); + if value <> '' then begin + ps:= pchar(pointer(value)); + pe:= ps+length(value); + while ps < pe do begin + pd^:= ps^; + if ps^ = quotechar then begin + pd^:= escapechar; + inc(pd); + pd^:= quotechar; + end; + if ps^ = escapechar then begin + inc(pd); + pd^:= escapechar; + end; + inc(pd); + inc(ps); + end; + end; + pd^:= quotechar; + inc(pd); + setlength(result,pd-pchar(pointer(result))); + end + else begin + result:= value; + end; +end; + +function quoteescapedstring(value: msestring; quotechar: msechar; + const force: boolean = true; + const separator: msechar = ' '): msestring; +var + ps,pd,pe: pmsechar; +begin + if force or (findchar(value,quotechar) > 0) or + (separator <> #0) and (findchar(value,separator) > 0) then begin + setlength(result,length(value)*2+2); //max + pd:= pmsechar(pointer(result)); + pd^:= quotechar; + inc(pd); + if value <> '' then begin + ps:= pmsechar(pointer(value)); + pe:= ps+length(value); + while ps < pe do begin + pd^:= ps^; + if ps^ = quotechar then begin + pd^:= escapechar; + inc(pd); + pd^:= quotechar; + end; + if ps^ = escapechar then begin + inc(pd); + pd^:= escapechar; + end; + inc(pd); + inc(ps); + end; + end; + pd^:= quotechar; + inc(pd); + setlength(result,pd-pmsechar(pointer(result))); + end + else begin + result:= value; + end; +end; + +function extractquotedstr(const value: msestring): msestring; + //entfernt vorhandene paare ' und " +begin + if (value <> '') and ((value[1] = '"') or (value[1] = '''')) then begin + result:= unquotestring(value,value[1]); + end + else begin + result:= value; + end; +end; + +function lineatindex(const value: msestring; const index: int32): msestring; +var + po1,po2,ps,pe: pmsechar; +begin + if value <> '' then begin + ps:= pointer(value); + pe:= ps + length(value); + po1:= ps + index; + po2:= po1; + if (po1^ = c_linefeed) and (po1 > ps) then begin + dec(po1); + end; + if (po1^ = c_return) and (po1 > ps) then begin + dec(po1); + end; + while (po1^ <> c_linefeed) and (po1 > ps) do begin + dec(po1); + end; + if po1^ = c_linefeed then begin + inc(po1); + end; + while not ((po2^ = c_return) or (po2^ = c_linefeed)) and (po2 < pe) do begin + inc(po2); + end; + result:= psubstr(po1,po2); + end + else begin + result:= ''; + end; +end; + +procedure wordatindex(const value: msestring; const index: integer; + out first,pastlast: pmsechar; + const delimchars: msestring; + const nodelimstrings: array of msestring); + + function checkdelimchars(achar: msechar): boolean; + var + po1: pmsechar; + begin + po1:= pmsechar(delimchars); + result:= false; + while po1^ <> #0 do begin + if po1^ = achar then begin + result:= true; + break; + end; + inc(po1); + end; + end; + + function checknodelimstringsdown(var po1: pmsechar; var int1: integer): boolean; + var + {bo1,}bo2: boolean; + int2,int3,int4: integer; + po2: pmsechar; + begin + result:= true; + for int2:= high(nodelimstrings) downto 0 do begin + po2:= po1; + int4:= length(nodelimstrings[int2])-1; + int3:= int1 - int4; + if int3 >= 0 then begin + bo2:= true; + for int3:= int4 downto 0 do begin + if (pmsechar(pointer(nodelimstrings[int2]))+int3)^ <> po2^ then begin + bo2:= false; + break; + end; + dec(po2); + end; + if bo2 then begin + inc(po2); + result:= false; + int1:= int1 - (po1 - po2); + po1:= po2; + break; + end; + end; + end; + end; + + function checknodelimstringsup(var po1: pmsechar; var int3: integer): boolean; + var + int1,int2: integer; + bo1: boolean; + po2: pmsechar; + begin + result:= true; + for int2:= high(nodelimstrings) downto 0 do begin + bo1:= true; + po2:= po1; + for int1:= 0 to length(nodelimstrings[int2]) - 1 do begin + if po2^ <> (pmsechar(pointer(nodelimstrings[int2]))+int1)^ then begin + bo1:= false; + break; + end; + inc(po2); + end; + if bo1 then begin + dec(po2); + int3:= int3 - (po1 - po2); + po1:= po2; + result:= false; + break; + end; + end; + end; + +var + int1: integer; + po1: pmsechar; +// bo1{,bo2}: boolean; +begin + first:= nil; + pastlast:= nil; + if (index >= 0) and (index < length(value)) then begin + first:= pmsechar(pointer(value)) + index; + po1:= first; + int1:= index; + while int1 >= 0 do begin + if checkdelimchars(po1^) and checknodelimstringsdown(po1,int1) then begin + if po1 = first then begin + first:= nil; + exit; + end; + break; + end; + dec(po1); + dec(int1); + end; + pastlast:= first + 1; + first:= po1 + 1; + int1:= length(value) - index - 2; + while int1 >= 0 do begin + if checkdelimchars(pastlast^) and checknodelimstringsup(pastlast,int1) then begin + break; + end; + inc(pastlast); + dec(int1); + end; + end; +end; + +function wordatindex(const value: msestring; const index: integer; + const delimchars: msestring; + const nodelimstrings: array of msestring): msestring; +var + po1,po2: pmsechar; +begin + wordatindex(value,index,po1,po2,delimchars,nodelimstrings); + result:= copy(msestring(po1),1,po2-po1); +end; + +function checkkeyword(const aname: string; const anames; + const ahigh: integer): cardinal; +var + int1: integer; + po1: pchar; +begin + result:= 0; + po1:= pchar(pointer(aname)); + if po1 <> nil then begin + for int1:= 1 to ahigh do begin + if strcomp(po1,pchar(pointer(stringaty(anames)[int1]))) = 0 then begin + result:= int1; + break; + end; + end; + end; +end; + +function checkkeyword(const aname: msestring; const anames; + const ahigh: integer): cardinal; +var + int1: integer; + po1: pmsechar; +begin + result:= 0; + po1:= pmsechar(pointer(aname)); + if po1 <> nil then begin + for int1:= 1 to ahigh do begin + if msestrcomp(po1,pmsechar(pointer(stringaty(anames)[int1]))) = 0 then begin + result:= int1; + break; + end; + end; + end; +end; + +function checkkeyword(const aname: pchar; const anames; + const ahigh: integer): cardinal; +var + int1: integer; + po1: pchar; +begin + result:= 0; + po1:= aname; + if po1 <> nil then begin + for int1:= 1 to ahigh do begin + if strcomp(po1,pchar(pointer(stringaty(anames)[int1]))) = 0 then begin + result:= int1; + break; + end; + end; + end; +end; + +function checkkeyword(const aname: pmsechar; const anames; + const ahigh: integer): cardinal; +var + int1: integer; + po1: pmsechar; +begin + result:= 0; + po1:= aname; + if po1 <> nil then begin + for int1:= 1 to ahigh do begin + if msestrcomp(po1,pmsechar(pointer(stringaty(anames)[int1]))) = 0 then begin + result:= int1; + break; + end; + end; + end; +end; + +//todo: optimise +function msestringsearch(const substring,s: msestring; start: integer; + const options: searchoptionsty; + const substringupcase: msestring = ''): integer; +var + int1,int2: integer; + ch1,ch2: msechar; + str1,str2: msestring; + opt1: searchoptionsty; + slen,sublen: int32; + +begin + result:= 0; + if (length(substring) = 0) or (length(s) = 0) then begin + exit; + end; + sublen:= length(substring); + slen:= length(s); + if so_backward in options then begin //backward search + if start <= 0 then begin + exit; + end; + if start > slen then begin + start:= slen; + end; + if options * [so_wholeword,so_wordstart] <> [] then begin + opt1:= options - [so_wholeword,so_wordstart]; + result:= start; + repeat + result:= msestringsearch(substring,s,result,opt1,substringupcase); + if result <> 0 then begin + if (result = slen) or not isnamechar(s[result+1]) then begin + if not (so_wholeword in options) then begin + break; //so_wordstart + end; + if (result - length(substring) > 0) then begin + break; + end + else begin + if not isnamechar(s[result - length(substring)]) then begin + break; //io + end + else begin + dec(result); //kein ganzes wort + end; + end; + end + else begin + dec(result); + end; + end + else begin + break; + end; + until result < 1; + if result < 1 then begin + result:= 0; + end; + end + else begin + if so_caseinsensitive in options then begin + if substringupcase = '' then begin + str1:= mseuppercase(substring); + str2:= mselowercase(substring); + end + else begin + str1:= substringupcase; + str2:= substring; + end; + ch2:= str1[sublen]; + ch1:= str2[sublen]; + for int1:= start downto sublen do begin + if (s[int1] = ch1) or (s[int1] = ch2) then begin + result:= int1-sublen; + for int2:= sublen downto 1 do begin + if (s[result+int2] <> str1[int2]) and + (s[result+int2] <> str2[int2]) then begin + result:= -1; + break; + end; + end; + inc(result); + end; + if result <> 0 then begin + result:= result+sublen-1; + break; + end; + end + end + else begin + ch1:= substring[sublen]; //casesensitive + for int1:= start downto sublen do begin + if s[int1] = ch1 then begin + result:= int1-sublen; + for int2:= sublen downto 1 do begin + if s[result+int2] <> substring[int2] then begin + result:= -1; + break; + end; + end; + inc(result); + end; + if result <> 0 then begin + result:= result+sublen-1; + break; + end; + end + end; + end; + end + else begin //not backward + if options * [so_wholeword,so_wordstart] <> [] then begin + opt1:= options - [so_wholeword,so_wordstart]; + result:= start; + repeat + result:= msestringsearch(substring,s,result,opt1,substringupcase); + if result <> 0 then begin + if (result = 1) or not isnamechar(s[result-1]) then begin + if not (so_wholeword in options) then begin + break; //so_wordstart + end; + if result + sublen > slen then begin + break; + end + else begin + if not isnamechar(s[result + sublen]) then begin + break; //io + end + else begin + inc(result); //kein ganzes wort + end; + end; + end + else begin + inc(result); + end; + end + else begin + break; + end; + until result > slen; + if result > slen then begin + result:= 0; + end; + end + else begin + if so_caseinsensitive in options then begin + if substringupcase = '' then begin + str1:= mseuppercase(substring); + str2:= mselowercase(substring); + end + else begin + str1:= substringupcase; + str2:= substring; + end; + ch2:= str1[1]; + ch1:= str2[1]; + for int1:= start to slen do begin + if (s[int1] = ch1) or (s[int1] = ch2) then begin + result:= int1-1; + for int2:= 1 to sublen do begin + if (s[result+int2] <> str1[int2]) and + (s[result+int2] <> str2[int2]) then begin + result:= -1; + break; + end; + end; + inc(result); + end; + if result <> 0 then begin + break; + end; + end + end + else begin + ch1:= substring[1]; + for int1:= start to slen do begin + if s[int1] = ch1 then begin + result:= int1-1; + for int2:= 1 to sublen do begin + if s[result+int2] <> substring[int2] then begin + result:= -1; + break; + end; + end; + inc(result); + end; + if result <> 0 then begin + break; + end; + end + end; + end; + end; //not backward +end; + +//todo: optimise +function stringsearch(const substring,s: ansistring; start: integer; + const options: searchoptionsty; + const substringupcase: ansistring = ''): integer; +var + int1,int2: integer; + ch1,ch2: char; + str1,str2: ansistring; + opt1: searchoptionsty; + slen,sublen: int32; + +begin + result:= 0; + if (length(substring) = 0) or (length(s) = 0) then begin + exit; + end; + sublen:= length(substring); + slen:= length(s); + if so_backward in options then begin //backward search + if start <= 0 then begin + exit; + end; + if start > slen then begin + start:= slen; + end; + if options * [so_wholeword,so_wordstart] <> [] then begin + opt1:= options - [so_wholeword,so_wordstart]; + result:= start; + repeat + result:= stringsearch(substring,s,result,opt1,substringupcase); + if result <> 0 then begin + if (result = slen) or not isnamechar(s[result+1]) then begin + if not (so_wholeword in options) then begin + break; //so_wordstart + end; + if (result - length(substring) > 0) then begin + break; + end + else begin + if not isnamechar(s[result - length(substring)]) then begin + break; //io + end + else begin + dec(result); //kein ganzes wort + end; + end; + end + else begin + dec(result); + end; + end + else begin + break; + end; + until result < 1; + if result < 1 then begin + result:= 0; + end; + end + else begin + if so_caseinsensitive in options then begin + if substringupcase = '' then begin + str1:= uppercase(substring); + str2:= lowercase(substring); + end + else begin + str1:= substringupcase; + str2:= substring; + end; + ch2:= str1[sublen]; + ch1:= str2[sublen]; + for int1:= start downto sublen do begin + if (s[int1] = ch1) or (s[int1] = ch2) then begin + result:= int1-sublen; + for int2:= sublen downto 1 do begin + if (s[result+int2] <> str1[int2]) and + (s[result+int2] <> str2[int2]) then begin + result:= -1; + break; + end; + end; + inc(result); + end; + if result <> 0 then begin + result:= result+sublen-1; + break; + end; + end + end + else begin + ch1:= substring[sublen]; //casesensitive + for int1:= start downto sublen do begin + if s[int1] = ch1 then begin + result:= int1-sublen; + for int2:= sublen downto 1 do begin + if s[result+int2] <> substring[int2] then begin + result:= -1; + break; + end; + end; + inc(result); + end; + if result <> 0 then begin + result:= result+sublen-1; + break; + end; + end + end; + end; + end + else begin //not backward + if options * [so_wholeword,so_wordstart] <> [] then begin + opt1:= options - [so_wholeword,so_wordstart]; + result:= start; + repeat + result:= stringsearch(substring,s,result,opt1,substringupcase); + if result <> 0 then begin + if (result = 1) or not isnamechar(s[result-1]) then begin + if not (so_wholeword in options) then begin + break; //so_wordstart + end; + if result + sublen > slen then begin + break; + end + else begin + if not isnamechar(s[result + sublen]) then begin + break; //io + end + else begin + inc(result); //kein ganzes wort + end; + end; + end + else begin + inc(result); + end; + end + else begin + break; + end; + until result > slen; + if result > slen then begin + result:= 0; + end; + end + else begin + if so_caseinsensitive in options then begin + if substringupcase = '' then begin + str1:= uppercase(substring); + str2:= lowercase(substring); + end + else begin + str1:= substringupcase; + str2:= substring; + end; + ch2:= str1[1]; + ch1:= str2[1]; + for int1:= start to slen do begin + if (s[int1] = ch1) or (s[int1] = ch2) then begin + result:= int1-1; + for int2:= 1 to sublen do begin + if (s[result+int2] <> str1[int2]) and + (s[result+int2] <> str2[int2]) then begin + result:= -1; + break; + end; + end; + inc(result); + end; + if result <> 0 then begin + break; + end; + end + end + else begin + ch1:= substring[1]; + for int1:= start to slen do begin + if s[int1] = ch1 then begin + result:= int1-1; + for int2:= 1 to sublen do begin + if s[result+int2] <> substring[int2] then begin + result:= -1; + break; + end; + end; + inc(result); + end; + if result <> 0 then begin + break; + end; + end + end; + end; + end; //not backward +end; + +function replacestring(const s: msestring; oldsub: msestring; + const newsub: msestring; + const options: searchoptionsty = []): msestring; +var + po1,po2,po3,poend: pmsechar; +// pold: pmsechar; + oldhigh,newhigh: integer; + int1,int2: integer; + ch1: msechar; + bo1,bo2,bo3: boolean; + s1: msestring; +begin + int1:= length(s); + if (int1 = 0) or (length(oldsub) = 0) then begin + result:= s; + exit; + end; + oldhigh:= length(oldsub)-1; + newhigh:= length(newsub)-1; + po1:= pointer(s); + poend:= po1; + if so_caseinsensitive in options then begin + s1:= mseuppercase(s); + po3:= pointer(s1); + oldsub:= mseuppercase(oldsub); + end + else begin + po3:= po1; + end; + inc(poend,int1-oldhigh); + if length(newsub) > length(oldsub) then begin + int1:= (int1 div length(oldsub) + 1) * length(newsub); + end; + setlength(result,int1); //max + po2:= pointer(result); + ch1:= oldsub[1]; + bo2:= options*[so_wholeword,so_wordstart] = []; + bo3:= not (so_wholeword in options); + while po1 < poend do begin + bo1:= po3^ = ch1; + if bo1 then begin + for int2:= 0 to oldhigh do begin + if (po3+int2)^ <> (pmsechar(pointer(oldsub))+int2)^ then begin + bo1:= false; + break; + end; + end; + bo1:= bo1 and (bo2 or + (bo3 or not isnamechar((po1+length(oldsub))^)) and + ((po1=pointer(s)) or not isnamechar((po1-1)^))); + if bo1 then begin + for int2:= 0 to newhigh do begin + po2^:= (pmsechar(pointer(newsub))+int2)^; + inc(po2); + end; + inc(po1,oldhigh); + inc(po3,oldhigh); + dec(po2); + end + else begin + po2^:= po1^; + end; + end + else begin + po2^:= po1^; + end; + inc(po1); + inc(po2); + inc(po3); + end; + inc(poend,oldhigh); + while po1 < poend do begin + po2^:= po1^; + inc(po1); + inc(po2); + end; + setlength(result,po2 - pmsechar(pointer(result))); +end; + +function replacestring(const s: string; oldsub: string; + const newsub: string; + const options: searchoptionsty = []): string; +var + po1,po2,po3,poend: pchar; +// pold: pchar; + oldhigh,newhigh: integer; + int1,int2: integer; + ch1: char; + bo1,bo2,bo3: boolean; + s1: string; +begin + int1:= length(s); + if (int1 = 0) or (length(oldsub) = 0) then begin + result:= s; + exit; + end; + oldhigh:= length(oldsub)-1; + newhigh:= length(newsub)-1; + po1:= pointer(s); + poend:= po1; + if so_caseinsensitive in options then begin + s1:= uppercase(s); + po3:= pointer(s1); + oldsub:= uppercase(oldsub); + end + else begin + po3:= po1; + end; + inc(poend,int1-oldhigh); + if length(newsub) > length(oldsub) then begin + int1:= (int1 div length(oldsub) + 1) * length(newsub); + end; + setlength(result,int1); //max + po2:= pointer(result); + ch1:= oldsub[1]; + bo2:= options*[so_wholeword,so_wordstart] = []; + bo3:= not (so_wholeword in options); + while po1 < poend do begin + bo1:= po3^ = ch1; + if bo1 then begin + for int2:= 0 to oldhigh do begin + if (po3+int2)^ <> (pchar(pointer(oldsub))+int2)^ then begin + bo1:= false; + break; + end; + end; + bo1:= bo1 and (bo2 or + (bo3 or not isnamechar((po1+length(oldsub))^)) and + ((po1=pointer(s)) or not isnamechar((po1-1)^))); + if bo1 then begin + for int2:= 0 to newhigh do begin + po2^:= (pchar(pointer(newsub))+int2)^; + inc(po2); + end; + inc(po1,oldhigh); + inc(po3,oldhigh); + dec(po2); + end + else begin + po2^:= po1^; + end; + end + else begin + po2^:= po1^; + end; + inc(po1); + inc(po2); + inc(po3); + end; + inc(poend,oldhigh); + while po1 < poend do begin + po2^:= po1^; + inc(po1); + inc(po2); + end; + setlength(result,po2 - pchar(pointer(result))); +end; + +function msePosEx(const SubStr, S: msestring; Offset: longword = 1): Integer; +//todo: optimize +var + I,X: Integer; + Len, LenSubStr: Integer; +begin + if Offset = 1 then + Result := Pos(SubStr, S) + else + begin + I := Offset; + LenSubStr := Length(SubStr); + Len := Length(S) - LenSubStr + 1; + while I <= Len do + begin + if S[I] = SubStr[1] then + begin + X := 1; + while (X < LenSubStr) and (S[I + X] = SubStr[X + 1]) do + Inc(X); + if (X = LenSubStr) then + begin + Result := I; + exit; + end; + end; + Inc(I); + end; + Result := 0; + end; +end; + +procedure reallocstring(var value: ansistring); + //macht datenkopie ohne free +var + po1: pointer; + int1: sizeint; +begin + po1:= pointer(value); + if po1 <> nil then begin + int1:= length(value); + pointer(value):= nil; + if int1 > 0 then begin + setlength(value,int1); + move(po1^,pointer(value)^,int1); + end; + end; +end; + +procedure reallocstring(var value: msestring); + //macht datenkopie ohne free +var + po1: pointer; + int1: sizeint; +begin + po1:= pointer(value); + if po1 <> nil then begin + int1:= length(value); + pointer(value):= nil; + if int1 > 0 then begin + setlength(value,int1); + move(po1^,pointer(value)^,int1*sizeof(msechar)); + end; + end; +end; + +procedure reallocarray(var value; elementsize: integer); overload; + //macht datenkopie ohne free +var + po1,po2: ^sizeint; + lwo1: longword; +begin + if pointer(value) <> nil then begin + lwo1:= length(bytearty(value))*elementsize + 2*sizeof(sizeint); + getmem(po1,lwo1); + po1^:= 1; //refcount + inc(po1); + po2:= pointer(value); + dec(po2); + move(po2^,po1^,lwo1-sizeof(sizeint)); //size+data + inc(po1); + pointer(value):= po1; + end; +end; + +procedure resizearray(var value; newlength, elementsize: integer); +var + po1: ^sizeint; + lwo1,lwo2: longword; +begin + if pointer(value) <> nil then begin + po1:= pointer(value); + lwo1:= newlength*elementsize; + if po1 <> nil then begin + dec(po1); + {$ifdef FPC} + lwo2:= (po1^+1)*longword(elementsize); + {$else} + lwo2:= po1^*longword(elementsize); + {$endif} + dec(po1); + end + else begin + lwo2:= 0; + end; + if lwo1 = 0 then begin + dispose(po1); + pointer(value):= nil; + end + else begin + reallocmem(po1,lwo1 + 2*sizeof(sizeint)); + inc(po1); + {$ifdef FPC} + po1^:= newlength-1; + {$else} + po1^:= newlength; + {$endif} + inc(po1); + pointer(value):= po1; + if lwo1 > lwo2 then begin + fillchar((pchar(po1)+lwo2)^,lwo1-lwo2,0); + end; + end; + end; +end; + +procedure removereturn(var avalue: msestring; var aindex: integer); +var + s,d: pmsechar; +begin + if avalue <> '' then begin + s:= pmsechar(avalue); + d:= s; + while s^ <> #0 do begin + if s^ <> msechar(c_return) then begin + d^:= s^; + inc(d); + end + else begin + if d - pmsechar(pointer(avalue)) < aindex then begin + dec(aindex); + end; + end; + inc(s); + end; + setlength(avalue,d-pmsechar(pointer(avalue))); + if aindex < 0 then begin + aindex:= 0; + end; + end; +end; + +procedure addeditchars(const source: msestring; var buffer: msestring; + var cursorpos: integer); + //cursorpos nullbased +var + s,d: pmsechar; + len1: integer; + ch1: msechar; + int1,int2: integer; + i: integer; + hasreturn: boolean; +begin + hasreturn:= false; + len1:= length(buffer); + i:= cursorpos; + if i > len1 then begin + i:= len1; + end; + int1:= len1; + int2:= cursorpos + length(source); + if int1 < int2 then begin + int1:= int2; + end; + setlength(buffer,int1); //refcount one + s:= pmsechar(source); + d:= pmsechar(buffer); + while true do begin + ch1:= s^; + if ch1 = #0 then begin + if s - pmsechar(pointer(source)) >= length(source) then begin + break; + end + else begin + ch1:= #$2400; //unicode null glyph + end; + end; + case ch1 of + c_backspace: begin + if i > 0 then begin + dec(i); + dec(len1,2); + end; + end; + c_return: begin + i:= 0; + hasreturn:= true; + end; + else begin + (d+i)^:= ch1; + inc(i); + if i > len1 then begin + len1:= i; + end; + end; + end; + inc(s); + end; + setlength(buffer,len1); + if hasreturn then begin + removereturn(buffer,i); + end; + cursorpos:= i; +end; + +function processeditchars(var value: msestring; stripcontrolchars: boolean): integer; + //bringt -anzahl rueckwaerts gefressene zeichen, + // -grosse zahl bei c_return +var + int1,int2,int3: integer; + str1: msestring; + ch1: msechar; + hasreturn: boolean; +begin + hasreturn:= false; + setlength(str1,length(value)); + int2:= 0; + int3:= 1; + for int1:= 1 to length(value) do begin + ch1:= value[int1]; + if ch1 = c_return then begin + int2:= -bigint div 2; + int3:= 1; + hasreturn:= true; + end + else begin + if ch1 = c_backspace then begin + dec(int3); + if int3 <= 0 then begin + dec(int2); + inc(int3); + end; + end + else begin + if ch1 = #0 then begin + ch1:= #$2400; //unicode null glyph + end; + if not stripcontrolchars or (ord(ch1) >= ord(' ')) or (ch1 = c_tab) then begin + (pmsechar(pointer(str1))+int3)^:= ch1; + inc(int3); + end; + end; + end; + end; + setlength(str1,int3-1); + if hasreturn then begin + int1:= -1; + removereturn(str1,int1); + end; + result:= int2; + value:= str1; +end; + +function mseextractprintchars(const value: msestring): msestring; +var + int1,int2: integer; + ch1: msechar; +begin + setlength(result,length(value)); + int2:= 0; + for int1:= 1 to length(value) do begin + ch1:= value[int1]; + if (ch1 >= ' ') and (ch1 <> c_delete) then begin + pmsecharaty(pointer(result))^[int2]:= ch1; + inc(int2); + end; + end; + setlength(result,int2); +end; + +function countchars(const str: string; achar: char): integer; +var + int1: integer; +begin + result:= 0; + for int1:= 1 to length(str) do begin + if str[int1] = achar then begin + inc(result); + end; + end; +end; + +function countchars(const str: msestring; achar: msechar): integer; +var + int1: integer; +begin + result:= 0; + for int1:= 1 to length(str) do begin + if str[int1] = achar then begin + inc(result); + end; + end; +end; + +function getcharpos(const str: msestring; achar: msechar): integerarty; +var + count: integer; + int1: integer; +begin + result:= nil; + count:= 0; + for int1:= 1 to length(str) do begin + if str[int1] = achar then begin + additem(result,int1,count); + end; + end; + setlength(result,count); +end; + +function findchar(const str: string; achar: char): integer; + //bringt index des ersten vorkommens von zeichen in string, 0 wenn nicht gefunden +var + int1: integer; +begin + result:= 0; + for int1:= 1 to length(str) do begin + if str[int1] = achar then begin + result:= int1; + exit; + end; + end; +end; + +function findchar(const str: string; const astart: integer; achar: char): integer; overload; +var + int1: integer; +begin + result:= 0; + for int1:= astart to length(str) do begin + if str[int1] = achar then begin + result:= int1; + exit; + end; + end; +end; + +function findchar(const str: msestring; achar: msechar): integer; + //bringt index des ersten vorkommens von zeichen in string, 0 wenn nicht gefunden +var + int1: integer; +begin + result:= 0; + for int1:= 1 to length(str) do begin + if str[int1] = achar then begin + result:= int1; + exit; + end; + end; +end; + +function findchar(const str: msestring; const astart: integer; + achar: msechar): integer; overload; +var + int1: integer; +begin + result:= 0; + for int1:= astart to length(str) do begin + if str[int1] = achar then begin + result:= int1; + exit; + end; + end; +end; + +function findchar(const str: pchar; achar: char): integer; + //bringt erstes vorkommens von zeichen in string, 0 wenn nicht gefunden +var + po1: pchar; +begin + result:= 0; + if str <> nil then begin + po1:= str; + while po1^ <> #0 do begin + if po1^ = achar then begin + result:= (po1-pchar(pointer(str)))+1; + break; + end; + inc(po1); + end; + end; +end; + +function findchar(const str: pmsechar; achar: msechar): integer; + //bringt erstes vorkommens von zeichen in string, 0 wenn nicht gefunden +var + po1: pmsechar; +begin + result:= 0; + if str <> nil then begin + po1:= str; + while po1^ <> #0 do begin + if po1^ = achar then begin + result:= (po1-pmsechar(pointer(str)))+1; + break; + end; + inc(po1); + end; + end; +end; + +function findchars(const str: string; const achars: string): integer; + //bringt index des ersten vorkommens von zeichen in string, 0 wenn nicht gefunden +var + int1: integer; + po1: pchar; +begin + result:= 0; + po1:= pchar(str); + while po1^ <> #0 do begin + for int1:= 1 to length(achars) do begin + if achars[int1] = po1^ then begin + result:= po1-pchar(str)+1; + exit; + end; + end; + inc(po1); + end; +end; + +function findchars(const str: msestring; const achars: msestring): integer; + //bringt index des ersten vorkommens von zeichen in string, 0 wenn nicht gefunden +var + int1: integer; + po1: pmsechar; +begin + result:= 0; + po1:= pmsechar(str); + while po1^ <> #0 do begin + for int1:= 1 to length(achars) do begin + if achars[int1] = po1^ then begin + result:= po1-pmsechar(str)+1; + exit; + end; + end; + inc(po1); + end; +end; + +function findlastchar(const str: string; achar: char): integer; + //bringt index des letzten vorkommens von zeichen in string, 0 wenn nicht gefunden +var + int1: integer; +begin + result:= 0; + for int1:= length(str) downto 1 do begin + if str[int1] = achar then begin + result:= int1; + exit; + end; + end; +end; + +function findlastchar(const str: msestring; achar: msechar): integer; + //bringt index des letzten vorkommens von zeichen in string, 0 wenn nicht gefunden +var + int1: integer; +begin + result:= 0; + for int1:= length(str) downto 1 do begin + if str[int1] = achar then begin + result:= int1; + exit; + end; + end; +end; + +procedure mseskipspace(var str: pmsechar); {$ifdef FPC}inline;{$endif} +begin + while str^ = ' ' do begin + inc(str); + end; +end; + +procedure skipspace(var str: pchar); {$ifdef FPC}inline;{$endif} +begin + while str^ = ' ' do begin + inc(str); + end; +end; + +function StrLScan(const Str: PChar; Chr: Char; len: integer): PChar; +var + int1: integer; + po1: pcharaty; +begin + result:= nil; + if str <> nil then begin + po1:= pointer(str); + for int1:= 0 to len - 1 do begin + if po1^[int1] = chr then begin + result:= @(po1^[int1]); + break; + end; + end; + end; +end; + +function mseStrLScan(const Str: PmseChar; Chr: mseChar; len: integer): PmseChar; +var + int1: integer; + po1: pmsecharaty; +begin + result:= nil; + if str <> nil then begin + po1:= pointer(str); + for int1:= 0 to len - 1 do begin + if po1^[int1] = chr then begin + result:= @(po1^[int1]); + break; + end; + end; + end; +end; + +function StrLNScan(const Str: PChar; Chr: Char; len: integer): PChar; +var + int1: integer; + po1: pcharaty; +begin + result:= nil; + if str <> nil then begin + po1:= pointer(str); + for int1:= 0 to len - 1 do begin + if po1^[int1] <> chr then begin + result:= @(po1^[int1]); + break; + end; + end; + end; +end; + +function mseStrLNScan(const Str: PmseChar; Chr: mseChar; len: integer): PmseChar; +var + int1: integer; + po1: pmsecharaty; +begin + result:= nil; + if str <> nil then begin + po1:= pointer(str); + for int1:= 0 to len - 1 do begin + if po1^[int1] <> chr then begin + result:= @(po1^[int1]); + break; + end; + end; + end; +end; +{ +function strscan(const str: string; chr: char): integer; overload; +var + int1: integer; +begin + result:= 0; + for int1:= 1 to length(str) do begin + if str[int1] = chr then begin + result:= int1; + break; + end; + end; +end; + +function msestrscan(const str: msestring; chr: msechar): integer; overload; +var + int1: integer; +begin + result:= 0; + for int1:= 1 to length(str) do begin + if str[int1] = chr then begin + result:= int1; + break; + end; + end; +end; +} +function StrScan(const Str: PChar; Chr: Char): PChar; +var + po1: pchar; +begin + po1:= str; + result:= nil; + if po1 <> nil then begin + while po1^ <> #0 do begin + if po1^ = chr then begin + result:= po1; + break; + end; + inc(po1); + end; + end; +end; + +function strscan(const str: lmsestringty; const chr: msechar): pmsechar; overload; +var + int1: integer; + po1: pmsechar; +begin + po1:= str.po; + for int1:= 0 to str.len-1 do begin + if (po1+int1)^ = chr then begin + result:= po1+int1; + exit; + end; + end; + result:= nil; +end; + +function mseStrScan(const Str: PmseChar; Chr: mseChar): Pmsechar; +var + po1: pmsechar; +begin + po1:= str; + result:= nil; + if po1 <> nil then begin + while po1^ <> #0 do begin + if po1^ = chr then begin + result:= po1; + break; + end; + inc(po1); + end; + end; +end; + +function StrNScan(const Str: PChar; Chr: Char): PChar; +var + po1: pchar; +begin + po1:= str; + result:= nil; + if po1 <> nil then begin + while po1^ <> #0 do begin + if po1^ <> chr then begin + result:= po1; + break; + end; + inc(po1); + end; + end; +end; + +function mseStrNScan(const Str: PmseChar; Chr: mseChar): Pmsechar; +var + po1: pmsechar; +begin + po1:= str; + result:= nil; + if po1 <> nil then begin + while po1^ <> #0 do begin + if po1^ <> chr then begin + result:= po1; + break; + end; + inc(po1); + end; + end; +end; + +function StrRScan(const Str: PChar; Chr: Char): PChar; +var + po1: pchar; +begin + po1:= str; + result:= nil; + if po1 <> nil then begin + while po1^ <> #0 do begin + inc(po1); + end; + while po1 > str do begin + dec(po1); + if po1^ = chr then begin + result:= po1; + break; + end; + end; + end; +end; + +function mseStrRScan(const Str: PmseChar; Chr: mseChar): PmseChar; +var + po1: pmsechar; +begin + po1:= str; + result:= nil; + if po1 <> nil then begin + while po1^ <> #0 do begin + inc(po1); + end; + while po1 > str do begin + dec(po1); + if po1^ = chr then begin + result:= po1; + break; + end; + end; + end; +end; + +function msestrrscan(const str: msestring; chr: msechar): integer; +var + int1: integer; +begin + result:= 0; + for int1:= length(str) downto 1 do begin + if str[int1] = chr then begin + result:= int1; + break; + end; + end; +end; + +function StrLRScan(const Str: PChar; Chr: Char; len: integer): PChar; +var + po1: pchar; +begin + result:= nil; + if str <> nil then begin + po1:= str+len; + while po1 > str do begin + dec(po1); + if po1^ = chr then begin + result:= po1; + break; + end; + end; + end; +end; + +function mseStrLRScan(const Str: PmseChar; Chr: mseChar; len: integer): PmseChar; +var + po1: pmsechar; +begin + result:= nil; + if str <> nil then begin + po1:= str+len; + while po1 > str do begin + dec(po1); + if po1^ = chr then begin + result:= po1; + break; + end; + end; + end; +end; + +function mseStrLNRScan(const Str: PmseChar; Chr: mseChar; len: integer): PmseChar; +var + po1: pmsechar; +begin + result:= nil; + if str <> nil then begin + po1:= str+len; + while po1 > str do begin + dec(po1); + if po1^ <> chr then begin + result:= po1; + break; + end; + end; + end; +end; + +function mseStrComp(const Str1, Str2: PmseChar): Integer; +var + po1,po2: pmsechar; + wo1: word; +begin + po1:= str1; + po2:= str2; + if po1 <> po2 then begin + repeat + wo1:= word(po1^) - word(po2^); + if po2^ = #0 then begin + break; + end; + inc(po1); + inc(po2); + until (wo1 <> 0); + result:= smallint(wo1); + end + else begin + result:= 0; + end; +end; + +function StrLComp(const Str1, Str2: PChar; len: integer): Integer; +var + po1,po2: pchar; + by1: byte; +begin + by1:= 0; + if len > 0 then begin + po1:= str1; + po2:= str2; + repeat + by1:= byte(po1^) - byte(po2^); + if po2^ = #0 then begin + break; + end; + inc(po1); + inc(po2); + dec(len); + until (len <= 0) or (by1 <> 0); + end; + result:= shortint(by1); +end; + +function mseStrLComp(const Str1, Str2: PmseChar; len: integer): Integer; +var + po1,po2: pmsechar; + wo1: word; +begin + wo1:= 0; + if len > 0 then begin + po1:= str1; + po2:= str2; + repeat + wo1:= word(po1^) - word(po2^); + if po2^ = #0 then begin + break; + end; + inc(po1); + inc(po2); + dec(len); + until (len <= 0) or (wo1 <> 0); + end; + result:= smallint(wo1); +end; + +function StrLIComp(const Str1, upstr: PChar; len: integer): Integer; + //ascii caseinsensitive, str2 muss upcase sein +var + po1,po2: pcharaty; + int1: integer; + by1: byte; +begin + by1:= 0; + if not((len = 0) or (str1 = upstr)) then begin + po1:= pointer(str1); + po2:= pointer(upstr); + for int1:= 0 to len - 1 do begin + by1:= ord(upperchars[po1^[int1]])-ord(po2^[int1]); + if (by1 <> 0) then begin + break; + end; + end; + end; + result:= shortint(by1); +end; + +function StrIComp(const Str1, upstr: PChar): Integer; + //ascii caseinsensitive, upstr muss upcase sein +var + po1,po2: pchar; + by1: byte; +begin + by1:= 0; + if str1 <> upstr then begin + po1:= pointer(str1); + po2:= pointer(upstr); + repeat + by1:= ord(upperchars[po1^])-ord(po2^); + inc(po1); + inc(po2); + until (by1 <> 0) or (po1^ = #0); + end; + result:= shortint(by1); +end; + +function mseStrLIComp(const Str1, upstr: PmseChar; len: integer): Integer; + //ascii caseinsensitive, str2 muss upcase sein +var + po1,po2: pmsecharaty; + int1: integer; + ch1: msechar; + wo1: word; +begin + wo1:= 0; + if not((len = 0) or (str1 = upstr)) then begin + po1:= pointer(str1); + po2:= pointer(upstr); + for int1:= 0 to len - 1 do begin + ch1:= po1^[int1]; + if (ch1 >= 'a') and (ch1 <= 'z') then begin + inc(ch1,ord('A')-ord('a')); + end; + wo1:= ord(ch1)-ord(po2^[int1]); + if (wo1 <> 0) then begin + break; + end; + end; + end; + result:= smallint(wo1); +end; + +function issamelstring(const value: lmsestringty; const key: msestring; + caseinsensitive: boolean = false): boolean; + //nur ascii caseinsens., key muss upcase sein +begin + if caseinsensitive then begin + result:= msestrlicomp(value.po,pointer(key),value.len) = 0; + end + else begin + result:= msestrlcomp(value.po,pointer(key),value.len) = 0; + end; +end; + +function issamelstring(const value: lstringty; const key: string; + caseinsensitive: boolean = false): boolean; + //nur ascii caseinsens., key muss upcase sein +begin + if caseinsensitive then begin + result:= strlicomp(value.po,pointer(key),value.len) = 0; + end + else begin + result:= strlcomp(value.po,pointer(key),value.len) = 0; + end; +end; + +function minhigh(const a,b: lstringty): integer; overload; +begin + if a.len < b.len then begin + result:= a.len; + end + else begin + result:= b.len; + end; + dec(result); +end; + +function minhigh(const a: lstringty; const b: string): integer; overload; +begin + if a.len < length(b) then begin + result:= a.len; + end + else begin + result:= length(b); + end; + dec(result); +end; + +function minhigh(const a,b: string): integer; overload; +begin + if length(a) < length(b) then begin + result:= length(a); + end + else begin + result:= length(b); + end; + dec(result); +end; + +function minhigh(const a,b: msestring): integer; overload; +begin + if length(a) < length(b) then begin + result:= length(a); + end + else begin + result:= length(b); + end; + dec(result); +end; + +function lstringcomp(const a,b: lstringty): integer; +var + int1: integer; + by1: byte; + po1,po2: pcharaty; +begin + po1:= pointer(a.po); + po2:= pointer(b.po); + by1:= 0; + for int1:= 0 to minhigh(a,b) do begin + by1:= byte(po1^[int1]) - byte(po2^[int1]); + if by1 <> 0 then begin + break; + end; + end; + if by1 = 0 then begin + result:= a.len - b.len; + end + else begin + result:= shortint(by1); + end; +end; + +function lstringcomp(const a: lstringty; const b: string): integer; +var + int1: integer; + by1: byte; + po1,po2: pcharaty; +begin + po1:= pointer(a.po); + po2:= pointer(b); + by1:= 0; + for int1:= 0 to minhigh(a,b) do begin + by1:= byte(po1^[int1]) - byte(po2^[int1]); + if by1 <> 0 then begin + break; + end; + end; + if by1 = 0 then begin + result:= a.len - length(b); + end + else begin + result:= shortint(by1); + end; +end; + +function lstringicompupper(const a,upper: lstringty): integer; + //case insensitive, upper must be uppercase +var + int1: integer; + by1: byte; + po1,po2: pcharaty; +begin + po1:= pointer(a.po); + po2:= pointer(upper.po); + by1:= 0; + for int1:= 0 to minhigh(a,upper) do begin + by1:= byte(upperchars[po1^[int1]]) - byte(po2^[int1]); + if by1 <> 0 then begin + break; + end; + end; + if by1 = 0 then begin + result:= a.len - upper.len; + end + else begin + result:= shortint(by1); + end; +end; + +function lstringicompupper(const a: lstringty; const upper: string): integer; overload; + //ansi case insensitive, upper must be uppercase +var + int1: integer; + by1: byte; + po1,po2: pcharaty; +begin + po1:= pointer(a.po); + po2:= pointer(upper); + by1:= 0; + for int1:= 0 to minhigh(a,upper) do begin + by1:= byte(upperchars[po1^[int1]]) - byte(po2^[int1]); + if by1 <> 0 then begin + break; + end; + end; + if by1 = 0 then begin + result:= a.len - length(upper); + end + else begin + result:= shortint(by1); + end; +end; + +function lstringicomp(const a,b: lstringty): integer; + //case insensitive +var + int1: integer; + by1: byte; + po1,po2: pcharaty; +begin + po1:= pointer(a.po); + po2:= pointer(b.po); + by1:= 0; + for int1:= 0 to minhigh(a,b) do begin + by1:= byte(upperchars[po1^[int1]]) - byte(upperchars[po2^[int1]]); + if by1 <> 0 then begin + break; + end; + end; + if by1 = 0 then begin + result:= a.len - b.len; + end + else begin + result:= shortint(by1); + end; +end; + +function lstringicomp(const a: lstringty; const b: string): integer; + //case insensitive, +var + int1: integer; + by1: byte; + po1,po2: pcharaty; +begin + po1:= pointer(a.po); + po2:= pointer(b); + by1:= 0; + for int1:= 0 to minhigh(a,b) do begin + by1:= byte(upperchars[po1^[int1]]) - byte(upperchars[po2^[int1]]); + if by1 <> 0 then begin + break; + end; + end; + if by1 = 0 then begin + result:= a.len - length(b); + end + else begin + result:= shortint(by1); + end; +end; + +{ +function stringcomp(const a,b: string): integer; +var + int1: integer; + by1: byte; + po1,po2: pcharaty; +begin + po1:= pointer(a); + po2:= pointer(b); + by1:= 0; + for int1:= 0 to minhigh(a,b) do begin + by1:= byte(po1^[int1]) - byte(po2^[int1]); + if by1 <> 0 then begin + break; + end; + end; + if by1 = 0 then begin + result:= length(a) - length(b); + end + else begin + result:= shortint(by1); + end; +end; + +function stringicomp(const a,b: string): integer; + //case insensitive +var + int1: integer; + by1: byte; + po1,po2: pcharaty; +begin + po1:= pointer(a); + po2:= pointer(b); + by1:= 0; + for int1:= 0 to minhigh(a,b) do begin + by1:= byte(upperchars[po1^[int1]]) - byte(upperchars[po2^[int1]]); + if by1 <> 0 then begin + break; + end; + end; + if by1 = 0 then begin + result:= length(a) - length(b); + end + else begin + result:= shortint(by1); + end; +end; +} + +function stringcomp(const a,b: string): integer; +var + by1: byte; + po1,po2: pchar; +begin + po1:= pointer(a); + po2:= pointer(b); + if po1 = nil then begin + if po2 = nil then begin + result:= 0; + exit; + end; + result:= -1; + exit; + end; + if po2 = nil then begin + result:= 1; + exit; + end; + while true do begin + by1:= byte(po1^)-byte(po2^); + if (by1 <> 0) or (po1^ = #0) or (po2^=#0) then begin + break; + end; + inc(po1); + inc(po2); + end; + result:= shortint(by1); +end; + +function stringicomp(const a,b: string): integer; +var + by1: byte; + po1,po2: pchar; +begin + po1:= pointer(a); + po2:= pointer(b); + if po1 = nil then begin + if po2 = nil then begin + result:= 0; + exit; + end; + result:= -1; + exit; + end; + if po2 = nil then begin + result:= 1; + exit; + end; + while true do begin + by1:= byte(upperchars[po1^])-byte(upperchars[po2^]); + if (by1 <> 0) or (po1^ = #0) or (po2^=#0) then begin + break; + end; + inc(po1); + inc(po2); + end; + result:= shortint(by1); +end; + +function stringicompupper(const a,upstr: string): integer; + //case insensitive, b must be uppercase +var + int1: integer; + by1: byte; + po1,po2: pcharaty; +begin + po1:= pointer(a); + po2:= pointer(upstr); + by1:= 0; + for int1:= 0 to minhigh(a,upstr) do begin + by1:= byte(upperchars[po1^[int1]]) - byte(po2^[int1]); + if by1 <> 0 then begin + break; + end; + end; + if by1 = 0 then begin + result:= length(a) - length(upstr); + end + else begin + result:= shortint(by1); + end; +end; + +function msestringcomp(const a,b: msestring): integer; +var + int1: integer; + wo1: word; + po1,po2: pmsecharaty; +begin + po1:= pointer(a); + po2:= pointer(b); + wo1:= 0; + for int1:= 0 to minhigh(a,b) do begin + wo1:= word(po1^[int1]) - word(po2^[int1]); + if wo1 <> 0 then begin + break; + end; + end; + if wo1 = 0 then begin + result:= length(a) - length(b); + end + else begin + result:= smallint(wo1); + end; +end; + +function msestringicomp(const a,b: msestring): integer; + //ascii case insensitive +var + int1: integer; + wo1: word; + ch1,ch2: msechar; + po1,po2: pmsecharaty; +begin + po1:= pointer(a); + po2:= pointer(b); + wo1:= 0; + for int1:= 0 to minhigh(a,b) do begin + ch1:= po1^[int1]; + if (ch1 >= 'a') and (ch1 <= 'z') then begin + inc(ch1,ord('A')-ord('a')); + end; + ch2:= po2^[int1]; + if (ch2 >= 'a') and (ch2 <= 'z') then begin + inc(ch2,ord('A')-ord('a')); + end; + wo1:= word(ch1) - word(ch2); + if wo1 <> 0 then begin + break; + end; + end; + if wo1 = 0 then begin + result:= length(a) - length(b); + end + else begin + result:= smallint(wo1); + end; +end; + +function msestringicompupper(const a,upstr: msestring): integer; + //case insensitive, b must be uppercase +var + int1: integer; + wo1: word; + ch1: msechar; + po1,po2: pmsecharaty; +begin + po1:= pointer(a); + po2:= pointer(upstr); + wo1:= 0; + for int1:= 0 to minhigh(a,upstr) do begin + ch1:= po1^[int1]; + if (ch1 >= 'a') and (ch1 <= 'z') then begin + inc(ch1,ord('A')-ord('a')); + end; + wo1:= word(ch1) - word(po2^[int1]); + if wo1 <> 0 then begin + break; + end; + end; + if wo1 = 0 then begin + result:= length(a) - length(upstr); + end + else begin + result:= smallint(wo1); + end; +end; + +function isnullstring(const s: ansistring): boolean; +var + int1: integer; +begin + result:= true; + for int1:= 1 to length(s) do begin + if s[int1] <> #0 then begin + result:= false; + break; + end; + end; +end; + +function isemptystring(const s: pchar): boolean; +begin + result:= (s = nil) or (s^ = char(0)); +end; + +function isemptystring(const s: pmsechar): boolean; +begin + result:= (s = nil) or (s^ = msechar(0)); +end; + +function isnamechar(achar: char): boolean; + //true if achar in 'a'..'z','A'..'Z','0'..'9','_'; +begin + result:= (achar >= 'a') and (achar <= 'z') or (achar >= 'A') and (achar <= 'Z') or + (achar >= '0') and (achar <= '9') or (achar = '_'); +end; + +function isnamechar(achar: msechar): boolean; + //true if achar in 'a'..'z','A'..'Z','0'..'9','_'; +begin + result:= (achar >= 'a') and (achar <= 'z') or (achar >= 'A') and (achar <= 'Z') or + (achar >= '0') and (achar <= '9') or (achar = '_'); +end; + +function isnumber(const s: string): boolean; +var + int1: integer; + ch1: char; +begin + if s = '' then begin + result:= false; + end + else begin + result:= true; + for int1:= length(s)-1 downto 0 do begin + ch1:= (pchar(pointer(s))+int1)^; + if (ch1 < '0') or (ch1 > '9') then begin + result:= false; + break; + end; + end; + end; +end; + +function isnumber(const s: msestring): boolean; +var + int1: integer; + ch1: msechar; +begin + if s = '' then begin + result:= false; + end + else begin + result:= true; + for int1:= length(s)-1 downto 0 do begin + ch1:= (pmsechar(pointer(s))+int1)^; + if (ch1 < '0') or (ch1 > '9') then begin + result:= false; + break; + end; + end; + end; +end; + +function startsstr(substring: pchar; s: pchar): boolean; +begin + result:= substring = s; + if not result then begin + if (substring <> nil) and (s <> nil) then begin + while (substring^ = s^) and (substring^ <> #0) do begin + inc(substring); + inc(s); + end; + result:= substring^= #0; + end + else begin + result:= isemptystring(substring) and isemptystring(s); + end; + end; +end; + +function StartsStr(const substring,s: string): boolean; +begin + result:= startsstr(pchar(substring),pchar(s)); +end; + +function msestartsstr(substring: pmsechar; s: pmsechar): boolean; +begin + result:= substring = s; + if not result then begin + if (substring <> nil) and (s <> nil) then begin + while (substring^ = s^) and (substring^ <> #0) do begin + inc(substring); + inc(s); + end; + result:= substring^= #0; + end + else begin + result:= isemptystring(substring) and isemptystring(s); + end; + end; +end; + +function msestartsstrcaseinsensitive(substring: pmsechar; s: pmsechar): boolean; +begin + result:= substring = s; + if not result then begin + if (substring <> nil) and (s <> nil) then begin + while (substring^ = charuppercase(s^)) and (substring^ <> #0) do begin + inc(substring); + inc(s); + end; + result:= substring^= #0; + end + else begin + result:= isemptystring(substring) and isemptystring(s); + end; + end; +end; + +function mseStartsStr(const substring,s: msestring): boolean; +begin + result:= msestartsstr(pmsechar(substring),pmsechar(s)); +end; + +function strlcopy(const str: pchar; len: integer): ansistring; + //nicht nullterminiert +begin + setlength(result,len); + move(str^,result[1],len*sizeof(char)); +end; + +function msestrlcopy(const str: pmsechar; len: integer): msestring; + //nicht nullterminiert +begin + setlength(result,len); + move(str^,result[1],len*sizeof(msechar)); +end; + +function comparestrlen(const S1,S2: string): integer; + //case sensitiv, beruecksichtigt nur s1 laenge +begin + if (length(s1) = 0) or (pointer(s1) = pointer(s2)) then begin + result:= 0; + exit; + end; + if length(s2) = 0 then begin + result:= 1; + exit; + end + else begin + result:= strlcomp(pointer(s1),pointer(s2),length(s1)); + end; +end; + +function msecomparestrlen(const S1,S2: msestring): integer; + //case sensitiv, beruecksichtigt nur s1 laenge +begin + if (length(s1) = 0) or (pointer(s1) = pointer(s2)) then begin + result:= 0; + exit; + end; + if length(s2) = 0 then begin + result:= 1; + exit; + end + else begin + result:= msestrlcomp(pointer(s1),pointer(s2),length(s1)); + end; +end; + +function msecomparestr(const S1, S2: msestring): Integer; +begin +{$ifdef FPC} + result:= unicodecomparestr(s1,s2); +// {$ifdef mswindows} +// if iswin95 then begin +// result:= comparestr(s1,s2); +// end +// else begin +// result:= unicodecomparestr(s1,s2); +// end; +// {$else} +// result:= unicodecomparestr(s1,s2); +// {$endif} +{$else} + result:= widecomparestr(s1,s2); +{$endif} +end; + +function msecomparetext(const S1, S2: msestring): Integer; +begin +{$ifdef FPC} +// {$ifdef mswindows} +// if iswin95 then begin +// result:= comparetext(s1,s2); +// end +// else begin +// result:= unicodecomparetext(s1,s2); +// end; +// {$else} + result:= unicodecomparetext(s1,s2); +// {$endif} +{$else} + result:= widecomparetext(s1,s2); +{$endif} +end; + +function comparenatural(const s1,s2: msestring; + const caseinsensitive: boolean): int32; +var + p1,p2: pmsechar; + pa,pb: pmsechar; + i1,ia,ib: int32; + si0,si1,si2: sizeint; + c1,c2: msechar; + b1: boolean; +begin + b1:= false; + if (s1 <> '') and (s2 <> '') and (pointer(s1) <> pointer(s2)) then begin + p1:= pmsechar(pointer(s1)) + (length(s1) - 1); + pa:= p1; + while pa >= pointer(s1) do begin + if (pa^ > '9') or (pa^ < '0') then begin + break; + end; + dec(pa); + end; + if pa <> p1 then begin + p2:= pmsechar(pointer(s2)) + (length(s2) - 1); + pb:= p2; + while pb >= pointer(s2) do begin + if (pb^ > '9') or (pb^ < '0') then begin + break; + end; + dec(pb); + end; + if pb <> p2 then begin + si0:= pa - pmsechar(pointer(s1)); + if si0 = pb - pmsechar(pointer(s2)) then begin + inc(si0); + i1:= 1; + ia:= 0; + while p1 > pa do begin + ia:= ia + i1 * (card16(p1^)-card16('0')); + i1:= i1 * 10; + dec(p1); + end; + i1:= 1; + ib:= 0; + while p2 > pb do begin + ib:= ib + i1 * (card16(p2^)-card16('0')); + i1:= i1 * 10; + dec(p2); + end; + si1:= length(s1); + si2:= length(s2); + (psizeint(pointer(s1))-1)^:= si0; + (psizeint(pointer(s2))-1)^:= si0; + inc(pa); + c1:= pa^; + pa^:= #0; + inc(pb); + c2:= pb^; + pb^:= #0; + if caseinsensitive then begin + result:= msecomparetext(s1,s2); + end + else begin + result:= msecomparestr(s1,s2); + end; + if result = 0 then begin + result:= ia - ib; + end; + (psizeint(pointer(s1))-1)^:= si1; + (psizeint(pointer(s2))-1)^:= si2; + pa^:= c1; + pb^:= c2; + b1:= true; + end; + end; + end; + end; + if not b1 then begin + if caseinsensitive then begin + result:= msecomparetext(s1,s2); + end + else begin + result:= msecomparestr(s1,s2); + end; + end; +end; + +function msecomparestrnatural(const S1, S2: msestring): Integer; + //case sensitive +begin + result:= comparenatural(s1,s2,false); +end; + +function msecomparetextnatural(const S1, S2: msestring): Integer; + //case insensitive +begin + result:= comparenatural(s1,s2,true); +end; + +function mseCompareTextlen(const S1, S2: msestring): Integer; + //case insensitiv, beruecksichtigt nur s1 laenge +var + str1: msestring; +begin + str1:= copy(s2,1,length(s1)); //todo: optimize + result:= msecomparetext(s1,str1); +end; + +function msepartialcomparestr(const s1,s2: msestring): integer; +var + mstr1: msestring; +begin + mstr1:= copy(s2,1,length(s1)); + result:= msecomparestr(s1,mstr1); + if (result <> 0) and (length(s2) > length(s1)) then begin + if msecomparestr(s1+'A',mstr1+'Z') < + msecomparestr(s1+'Z',mstr1+'A') then begin + result:= 0; + end; + end; +end; + +function msepartialcomparetext(const s1,s2: msestring): integer; +var + mstr1: msestring; +begin + mstr1:= copy(s2,1,length(s1)); + result:= msecomparetext(s1,mstr1); + if (result <> 0) and (length(s2) > length(s1)) then begin + if msecomparetext(s1+'A',mstr1+'Z') < + msecomparetext(s1+'Z',mstr1+'A') then begin + result:= 0; + end; + end; +end; + +function mseCompareTextlenupper(const S1, S2: msestring): Integer; + //case insensitiv, checks length s1 only, s1 must be uppercase +var + str1: msestring; +begin + str1:= mseuppercase(copy(s2,1,length(s1))); //todo: optimize + result:= msecomparestr(s1,str1); +end; + +function mseissamestrlen(const apartstring,astring: msestring): boolean; +var + po1,po2: pmsechar; +begin + result:= pointer(apartstring) = pointer(astring); + if not result then begin + po1:= pmsechar(apartstring); + po2:= pmsechar(astring); + while po1^ <> #0 do begin + if po1^ <> po2^ then begin + exit; + end; + inc(po1); + inc(po2); + end; + end; + result:= true; +end; + +function mseissametextlen(const apartstring,astring: msestring): boolean; + //case insensitive +begin + result:= mseissamestrlen(mseuppercase(apartstring),mseuppercase(astring)); +end; + +function mselowercase(const s: msestring): msestring; +begin +{$ifdef FPC} +// {$ifdef mswindows} +// if iswin95 then begin +// result:= lowercase(s); +// end +// else begin +// result:= unicodelowercase(s); +// end; +// {$else} + result:= unicodelowercase(s); +// {$endif} +{$else} + result:= widelowercase(s); +{$endif} +end; + +function mseuppercase(const s: msestring): msestring; +begin +{$ifdef FPC} +// {$ifdef mswindows} +// if iswin95 then begin +// result:= ansiuppercase(s); +// end +// else begin +// result:= unicodeuppercase(s); +// end; +// {$else} + result:= unicodeuppercase(s); +// {$endif} +{$else} + result:= wideuppercase(s); +{$endif} +end; + +function mselowercase(const s: msestringarty): msestringarty; +var + int1: integer; +begin + setlength(result,length(s)); + for int1:= high(s) downto 0 do begin + result[int1]:= mselowercase(s[int1]); + end; +end; + +function mseuppercase(const s: msestringarty): msestringarty; +var + int1: integer; +begin + setlength(result,length(s)); + for int1:= high(s) downto 0 do begin + result[int1]:= mseuppercase(s[int1]); + end; +end; + +function msestartstr(const atext: msestring; trenner: msechar): msestring; +var + po1: pmsechar; +begin + po1:= msestrlscan(pmsechar(atext),trenner,length(atext)); + if po1 = nil then begin + result:= atext; + end + else begin + result:= copy(atext,1,po1-pmsechar(atext)); + end; +end; + +function mseremspace(const s: msestring): msestring; +var + int1,int2: integer; + ch: msechar; +begin + int2:= 0; + setlength(result,length(s)); + for int1:= 1 to length(s) do begin + ch:= s[int1]; + if ch > ' ' then begin + inc(int2); + pmsecharaty(result)^[int2]:= ch; + end; + end; + setlength(result,int2); +end; + +function removelinebreaks(const s: msestring): msestring; + //replaces linebreaks with space +begin + result:= concatstrings(breaklines(s),' '); +end; + +function removelineterminator(const s: msestring): msestring; +var + int1: integer; +begin + int1:= length(s); + if int1 > 0 then begin + if s[int1] = c_linefeed then begin + dec(int1); + end; + if (int1 > 0) and (s[int1] = c_return) then begin + dec(int1); + end; + end; + result:= copy(s,1,int1); +end; + +procedure removetabterminator(var s: msestring); +var + int1: integer; +begin + int1:= length(s); + if (int1 > 0) and (s[int1] = c_tab) then begin + setlength(s,int1-1); + end; +end; + +function stripescapesequences(avalue: msestring): msestring; +label + lab1; +var + s,d,e: pmsechar; +begin + if avalue <> '' then begin + setlength(result,length(avalue)); + s:= pointer(avalue); + d:= pointer(result); + e:= s+length(avalue); + while s < e do begin + if s^ = c_esc then begin + inc(s); + case s^ of + '[': begin + inc(s); + if (s^ >= '0') and (s^ <= '9') then begin + inc(s); +lab1: + while (s^ >= '0') and (s^ <= '9') do begin + inc(s); + end; + if s^ = ';' then begin + inc(s); + goto lab1; //multiple attributes + end; + if not (char(word(s^)) in ['n','h','l','H','A','B','C','D', + 'f','r','g','K','J','i','m']) then begin + dec(s); + end; + end + else begin + if not (char(word(s^)) in ['c','s','u','r','g','K','J','i','m']) then begin + dec(s); + end; + end; + end; + else begin + if not (char(word(s^)) in ['c','(',')','7','8','D','M','H']) then begin + dec(s); + end; + end; + end; + end + else begin + d^:= s^; + inc(d); + end; + inc(s); + end; + setlength(result,d-pmsechar(pointer(result))); + end + else begin + result:= ''; + end; +end; + + +{ tmemorystringstream } +const + stringheadersize = sizeof(stringheaderty); + +constructor tmemorystringstream.create; +//var +// header: stringheaderty; +begin + inherited; + setcapacity(0); + fposition:= stringheadersize; +// fillchar(header,sizeof(header),0); +// writebuffer(header,sizeof(header)); +end; + +procedure tmemorystringstream.SetCapacity(NewCapacity: PtrInt); +begin + inherited setcapacity(newcapacity + stringheadersize); +end; + +function tmemorystringstream.getcapacity: ptrint; +begin + result:= inherited getcapacity - stringheadersize; +end; + +function tmemorystringstream.Seek(const Offset: Int64; + Origin: TSeekOrigin): Int64; +begin + Case Word(Origin) of + soFromBeginning : FPosition:=Offset+stringheadersize; + soFromEnd : FPosition:=FSize+Offset; + soFromCurrent : FPosition:=FPosition+Offset; + end; + Result:=FPosition; + {$IFDEF DEBUG} + if Result < stringheadersize then + raise Exception.Create('TCustomMemoryStream'); + {$ENDIF} +end; + +function tmemorystringstream.getmemory: pointer; +begin + result:= fmemory + stringheadersize; +end; + +function tmemorystringstream.GetSize: Int64; +begin + result:= fsize - stringheadersize; +end; + +function tmemorystringstream.GetPosition: Int64; +begin + result:= fposition - stringheadersize; +end; + +procedure tmemorystringstream.SetSize( + {$ifdef CPU64}const{$endif CPU64} NewSize: PtrInt); +begin + inherited setsize(newsize + stringheadersize); +end; + +procedure tmemorystringstream.destroyasstring(out data: string); +var + ch1: char; +begin + data:= ''; //decref + if size > 0 then begin + with pstringheaderty(fmemory)^ do begin + {$ifdef hascodepage} + codepage:= cp_acp; + elementsize:= 1; + {$ifdef cpu64} + dummy:= 0; + {$endif} + {$endif} + ref:= 1; + len:= size; + end; + ch1:= #0; + position:= size; + writebuffer(ch1,sizeof(ch1)); + pointer(data):= memory; //pointer(ptruint(memory) + sizeof(stringheaderty)); + setpointer(nil,0); + end; + // destroy; //destroy does not free memory??? + free(); +end; + +end. + + diff --git a/mseide-msegui/lib/common/kernel/msesys.pas b/mseide-msegui/lib/common/kernel/msesys.pas new file mode 100644 index 0000000..ae43418 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msesys.pas @@ -0,0 +1,569 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msesys; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + {$ifdef mswindows}windows,{$endif}mseerr,msetypes,msestrings,msesystypes, + sysutils + {$ifdef FPC},dynlibs{$endif}; + +type + internalthreadprocty = function(): integer of object; + + procitemty = record + pid,ppid: procidty; + children: procidarty; + end; + procitemarty = array of procitemty; + + threadinfoty = record + id: threadty; + threadproc: internalthreadprocty; + stacksize: ptruint; + platformdata: array[0..3] of pointer; + end; + + socketkindty = (sok_local,sok_inet,sok_inet6); + socketshutdownkindty = (ssk_rx,ssk_tx,ssk_both); + pollkindty = (poka_read,poka_write,poka_except); + pollkindsty = set of pollkindty; + + + socketaddrty = record + kind: socketkindty; + url: filenamety; + port: integer; + size: integer; + platformdata: array[0..32] of longword; + end; + +type + fileopenmodety = (fm_none,fm_read,fm_write,fm_readwrite,fm_create,fm_append); + fileaccessmodety = (fa_denywrite,fa_denyread); + fileaccessmodesty = set of fileaccessmodety; + filerightty = (s_irusr,s_iwusr,s_ixusr, + s_irgrp,s_iwgrp,s_ixgrp, + s_iroth,s_iwoth,s_ixoth, + s_isuid,s_isgid,s_isvtx); + filerightsty = set of filerightty; + filetypety = (ft_unknown,ft_dir,ft_blk,ft_chr,ft_reg,ft_lnk,ft_sock,ft_fifo); + fileattributety = (fa_rusr,fa_wusr,fa_xusr, + fa_rgrp,fa_wgrp,fa_xgrp, + fa_roth,fa_woth,fa_xoth, + fa_suid,fa_sgid,fa_svtx, + fa_dir, + fa_archive,fa_compressed,fa_encrypted,fa_hidden, + fa_offline,fa_reparsepoint,fa_sparsefile,fa_system, + fa_temporary, + fa_all); + fileattributesty = set of fileattributety; + accessmodety = (am_read,am_write,am_execute,am_exist); + accessmodesty = set of accessmodety; + + pollflagty = (pf_in, //POLLIN = $001; + pf_pri, //POLLPRI = $002; + pf_out, //POLLOUT = $004; + pf_err, //POLLERR = $008; + pf_hup, //POLLHUP = $010; + pf_nval //POLLNVAL = $020; + ); + pollflagsty = set of pollflagty; + ppollflagsty = ^pollflagsty; + pollcallbackty = procedure(const aflags: pollflagsty; + const adata: pointer) of object; + + +const + filerightattributes = [fa_rusr,fa_wusr,fa_xusr, + fa_rgrp,fa_wgrp,fa_xgrp, + fa_roth,fa_woth,fa_xoth, + fa_suid,fa_sgid,fa_svtx]; +type + ext1fileinfoty = record + filetype: filetypety; + attributes: fileattributesty; + size: int64; + modtime: tdatetime; + accesstime: tdatetime; + ctime: tdatetime; + end; + + ext2fileinfoty = record + id: int64; + owner: longword; + group: longword; + end; + + fileinfostatety = (fis_typevalid,fis_extinfo1valid,fis_extinfo2valid, + fis_diropen,fis_hasentry); + fileinfostatesty = set of fileinfostatety; + + fileinfoty = record + name: filenamety; + state: fileinfostatesty; + extinfo1: ext1fileinfoty; + extinfo2: ext2fileinfoty; + end; + pfileinfoty = ^fileinfoty; + + fileinfolevelty = (fil_name,fil_type, //fa_dir and fa_hidden + fil_ext1,fil_ext2); + dirstreamoptionty = (dso_casesensitive,dso_caseinsensitive); + //platform default if empty, + // same layout as filelistviewoptionty + dirstreamoptionsty = set of dirstreamoptionty; + + dirstreaminfoty = record + dirname: filenamety; + mask: filenamearty; + include,exclude: fileattributesty; + infolevel: fileinfolevelty; + options: dirstreamoptionsty; + caseinsensitive: boolean; + end; + + dirstreampty = array[0..7] of pointer; + dirstreamty = record +// checkcallback: dirstreamcheckeventty; + dirinfo: dirstreaminfoty; + platformdata: dirstreampty; + end; + + esys = class(eerror) + private + function geterror: syserrorty; + public + constructor create(aerror: syserrorty; atext: string); + property error: syserrorty read geterror; + end; + +var + defaultprintcommand: msestring; + +function fileattributestofilerights( + const attributes: fileattributesty): filerightsty; + +procedure checkdirstreamdata(var adata: dirstreamty); + +procedure syserror(const error: syserrorty; const text: msestring = ''); overload; +procedure syserror(const error: syserrorty; + const sender: tobject; text: msestring = ''); overload; + +function syelasterror: syserrorty; //returns sye_lasterror, sets mselasterror +function syeseterror(aerror: integer): syserrorty; + //if aerror <> 0 -> returns sye_lasterror, sets mselasterror, + // returns sye_ok otherwise +function syesetextendederror(const aerrormessage: msestring): syserrorty; +function buildsyserrormessage(const error: syserrorty; + const text: msestring = ''): msestring; +function buildsyserrormessage(const error: syserrorty; const sender: tobject; + text: msestring = ''): msestring; + +function getcommandlinearguments: msestringarty; + //refcount of result = 1 +function getcommandlineargument(const index: integer): msestring; +procedure deletecommandlineargument(const index: integer); + //index 1..argumentcount-1, no action otherwise + +{$ifdef FPC} +function getexceptiontext(obj: tobject; addr: pointer; framecount: longint; + frames: ppointer): msestring; +{$endif} +threadvar + mselasterror: integer; + mselasterrormessage: msestring; + +procedure saveformatsettings; +procedure initdefaultformatsettings; + //initialization order is wrong, FPC bug? +implementation +uses + classes,mclasses,msesysintf1,msesysintf,msearrayutils, + mseglob,msesysutils,mseformatstr; +{$ifdef FPC} + {$ifdef MSWINDOWS} +Procedure CatchUnhandledException (Obj : TObject; Addr: Pointer; + FrameCount: Longint; Frames: PPointer); + external name 'FPC_BREAK_UNHANDLED_EXCEPTION'; + //[public,alias:'FPC_BREAK_UNHANDLED_EXCEPTION']; + {$endif} +{$endif} + +function fileattributestofilerights( + const attributes: fileattributesty): filerightsty; +begin + result:= filerightsty(attributes*filerightattributes); +end; + +procedure checkdirstreamdata(var adata: dirstreamty); +var + int1: integer; +begin + with adata.dirinfo do begin + caseinsensitive:= sys_filesystemiscaseinsensitive; + if dso_caseinsensitive in options then begin + caseinsensitive:= true; + end; + if dso_casesensitive in options then begin + caseinsensitive:= false; + end; + if caseinsensitive then begin + setlength(mask,length(mask)); //unique + for int1:= 0 to high(mask) do begin + mask[int1]:= mseuppercase(mask[int1]); + end; + end; + end; +end; + +const + errortexts: array[syserrorty] of string = + ('','','','Busy','Dirstream','Network error','Write error','Read error', + 'Thread error', + 'Mutex error', + 'Semaphore error', + 'Condition error', + 'Time out', + 'Copy file error', + 'Can not create directory', + 'No console', + 'Not implemented', + 'Socket address error', + 'Socket error', + 'File is directory.' + ); + +var + commandlineargs: msestringarty; + +procedure initcommandlineargs; +begin + if commandlineargs = nil then begin + commandlineargs:= sys_getcommandlinearguments; + end; +end; + +function getcommandlineargument(const index: integer): msestring; +begin + initcommandlineargs; + if index > high(commandlineargs) then begin + result:= ''; + end + else begin + result:= commandlineargs[index]; + end; +end; + +function getcommandlinearguments: msestringarty; +begin + initcommandlineargs; + result:= copy(commandlineargs); +end; + +procedure deletecommandlineargument(const index: integer); +begin + initcommandlineargs; + if (index > 0) and (index <= high(commandlineargs)) then begin + deleteitem(commandlineargs,index); + end; +end; + +function syeseterror(aerror: integer): syserrorty; + //if aerror <> 0 -> returns sye_lasterror, sets mselasterror, + // returns sye_ok othrewise +begin + if aerror <> 0 then begin + result:= sye_lasterror; + mselasterror:= aerror; + end + else begin + result:= sye_ok; + end; +end; + +function syesetextendederror(const aerrormessage: msestring): syserrorty; +begin + mselasterrormessage:= aerrormessage; + result:= sye_extendederror; +end; + +function syelasterror: syserrorty; //returns sye_lasterror, sets mselasterror +begin + result:= sye_lasterror; + mselasterror:= sys_getlasterror; +end; + +function buildsyserrormessage(const error: syserrorty; + const text: msestring = ''): msestring; +begin + result:= ''; + if error = sye_lasterror then begin + result:= text + msestring(sys_geterrortext(mselasterror)); + end + else begin + if error = sye_extendederror then begin + result:= text + mselasterrormessage; + end + else begin + result:= text; + end; + end; +end; + +function buildsyserrormessage(const error: syserrorty; const sender: tobject; + text: msestring = ''): msestring; +begin + result:= ''; + if error <> sye_ok then begin + if sender <> nil then begin + text:= msestring(sender.classname) + ' ' + text; + if sender is tcomponent then begin + text:= text + msestring(fullcomponentname(tcomponent(sender))); + end; + end; + result:= buildsyserrormessage(error,text); + end; +end; + +procedure syserror(const error: syserrorty; const text: msestring); overload; +begin + if error = sye_ok then begin + exit; + end; + raise esys.create(error,ansistring(buildsyserrormessage(error,text))); +end; + +procedure syserror(const error: syserrorty; const sender: tobject; + text: msestring = ''); overload; +begin + if error = sye_ok then begin + exit; + end; + esys.create(error,ansistring(buildsyserrormessage(error,sender,text))); +{ + if sender <> nil then begin + text:= sender.classname + ' ' + text; + if sender is tcomponent then begin + text:= text + fullcomponentname(tcomponent(sender)); + end; + end; + syserror(error,text); +} +end; + +{ esys } + +constructor esys.create(aerror: syserrorty; atext: string); +begin + inherited create(integer(aerror),atext,errortexts); +end; + +function esys.geterror: syserrorty; +begin + result:= syserrorty(ferror); +end; + +var + defaultformatset: boolean = false; + +procedure initdefaultformatsettings; +var + int1: integer; +begin + if not defaultformatset then begin + defaultformatset:= true; + defaultformatsettingsmse.CurrencyFormat:= + {$ifdef FPC}defaultformatsettings.{$endif}CurrencyFormat; + defaultformatsettingsmse.NegCurrFormat:= + {$ifdef FPC}defaultformatsettings.{$endif}NegCurrFormat; + defaultformatsettingsmse.ThousandSeparator:= widechar( + {$ifdef FPC}defaultformatsettings.{$endif}ThousandSeparator); + defaultformatsettingsmse.DecimalSeparator:= widechar( + {$ifdef FPC}defaultformatsettings.{$endif}DecimalSeparator); + defaultformatsettingsmse.CurrencyDecimals:= + {$ifdef FPC}defaultformatsettings.{$endif}CurrencyDecimals; + defaultformatsettingsmse.DateSeparator:= widechar( + {$ifdef FPC}defaultformatsettings.{$endif}DateSeparator); + defaultformatsettingsmse.TimeSeparator:= widechar( + {$ifdef FPC}defaultformatsettings.{$endif}TimeSeparator); + defaultformatsettingsmse.ListSeparator:= widechar( + {$ifdef FPC}defaultformatsettings.{$endif}ListSeparator); + defaultformatsettingsmse.CurrencyString:= + msestring({$ifdef FPC}defaultformatsettings.{$endif}CurrencyString); + defaultformatsettingsmse.ShortDateFormat:= + msestring({$ifdef FPC}defaultformatsettings.{$endif}ShortDateFormat); + defaultformatsettingsmse.LongDateFormat:= + msestring({$ifdef FPC}defaultformatsettings.{$endif}LongDateFormat); + defaultformatsettingsmse.TimeAMString:= + msestring({$ifdef FPC}defaultformatsettings.{$endif}TimeAMString); + defaultformatsettingsmse.TimePMString:= + msestring({$ifdef FPC}defaultformatsettings.{$endif}TimePMString); + defaultformatsettingsmse.ShortTimeFormat:= + msestring({$ifdef FPC}defaultformatsettings.{$endif}ShortTimeFormat); + defaultformatsettingsmse.LongTimeFormat:= + msestring({$ifdef FPC}defaultformatsettings.{$endif}LongTimeFormat); + for int1:= low(tmonthnamearraymse) to high(tmonthnamearraymse) do begin + defaultformatsettingsmse.ShortMonthNames[int1]:= + msestring({$ifdef FPC}defaultformatsettings.{$endif}ShortMonthNames[int1]); + end; + for int1:= low(tmonthnamearraymse) to high(tmonthnamearraymse) do begin + defaultformatsettingsmse.LongMonthNames[int1]:= + msestring({$ifdef FPC}defaultformatsettings.{$endif}LongMonthNames[int1]); + end; + for int1:= low(tweeknamearraymse) to high(tweeknamearraymse) do begin + defaultformatsettingsmse.ShortDayNames[int1]:= + msestring({$ifdef FPC}defaultformatsettings.{$endif}ShortDayNames[int1]); + end; + for int1:= low(tweeknamearraymse) to high(tweeknamearraymse) do begin + defaultformatsettingsmse.LongDayNames[int1]:= + msestring({$ifdef FPC}defaultformatsettings.{$endif}LongDayNames[int1]); + end; + defaultformatsettingsmse.TwoDigitYearCenturyWindow:= + {$ifdef FPC}defaultformatsettings.{$endif}TwoDigitYearCenturyWindow; + end; +end; + +procedure saveformatsettings; +var + int1: integer; +begin + {$ifdef FPC}defaultformatsettings.{$endif}CurrencyFormat:= + defaultformatsettingsmse.CurrencyFormat; + {$ifdef FPC}defaultformatsettings.{$endif}NegCurrFormat:= + defaultformatsettingsmse.NegCurrFormat; + {$ifdef FPC}defaultformatsettings.{$endif}ThousandSeparator:= + char(defaultformatsettingsmse.ThousandSeparator); + {$ifdef FPC}defaultformatsettings.{$endif}DecimalSeparator:= + char(defaultformatsettingsmse.DecimalSeparator); + {$ifdef FPC}defaultformatsettings.{$endif}CurrencyDecimals:= + defaultformatsettingsmse.CurrencyDecimals; + {$ifdef FPC}defaultformatsettings.{$endif}DateSeparator:= + char(defaultformatsettingsmse.DateSeparator); + {$ifdef FPC}defaultformatsettings.{$endif}TimeSeparator:= + char(defaultformatsettingsmse.TimeSeparator); + {$ifdef FPC}defaultformatsettings.{$endif}ListSeparator:= + char(defaultformatsettingsmse.ListSeparator); + {$ifdef FPC}defaultformatsettings.{$endif}CurrencyString:= + ansistring(defaultformatsettingsmse.CurrencyString); + {$ifdef FPC}defaultformatsettings.{$endif}ShortDateFormat:= + ansistring(defaultformatsettingsmse.ShortDateFormat); + {$ifdef FPC}defaultformatsettings.{$endif}LongDateFormat:= + ansistring(defaultformatsettingsmse.LongDateFormat); + {$ifdef FPC}defaultformatsettings.{$endif}TimeAMString:= + ansistring(defaultformatsettingsmse.TimeAMString); + {$ifdef FPC}defaultformatsettings.{$endif}TimePMString:= + ansistring(defaultformatsettingsmse.TimePMString); + {$ifdef FPC}defaultformatsettings.{$endif}ShortTimeFormat:= + ansistring(defaultformatsettingsmse.ShortTimeFormat); + {$ifdef FPC}defaultformatsettings.{$endif}LongTimeFormat:= + ansistring(defaultformatsettingsmse.LongTimeFormat); + for int1:= low(tmonthnamearraymse) to high(tmonthnamearraymse) do begin + {$ifdef FPC}defaultformatsettings.{$endif}ShortMonthNames[int1]:= + ansistring(defaultformatsettingsmse.ShortMonthNames[int1]); + end; + for int1:= low(tmonthnamearraymse) to high(tmonthnamearraymse) do begin + {$ifdef FPC}defaultformatsettings.{$endif}LongMonthNames[int1]:= + ansistring(defaultformatsettingsmse.LongMonthNames[int1]); + end; + for int1:= low(tweeknamearraymse) to high(tweeknamearraymse) do begin + {$ifdef FPC}defaultformatsettings.{$endif}ShortDayNames[int1]:= + ansistring(defaultformatsettingsmse.ShortDayNames[int1]); + end; + for int1:= low(tweeknamearraymse) to high(tweeknamearraymse) do begin + {$ifdef FPC}defaultformatsettings.{$endif}LongDayNames[int1]:= + ansistring(defaultformatsettingsmse.LongDayNames[int1]); + end; + {$ifdef FPC}defaultformatsettings.{$endif}TwoDigitYearCenturyWindow:= + defaultformatsettingsmse.TwoDigitYearCenturyWindow; +end; + +{$ifdef FPC} + + {$ifopt S+} + {$define STACKCHECK_WAS_ON} + {$S-} + {$endif OPT S } + +function getexceptionstack(obj: tobject; addr: pointer; framecount: longint; + frames: ppointer): msestring; +Var + i: longint; +begin + if Obj is exception then begin + result:= msestring(Exception(Obj).ClassName)+' : '+ + msestring(Exception(Obj).Message)+ lineend; + end + else begin + result:= 'Exception object '+msestring(Obj.ClassName)+ + ' is not of class Exception.'+lineend; + end; + result:= result + msestring(BackTraceStrFunc(Addr))+lineend; + if (FrameCount>0) then begin + for i:=0 to FrameCount-1 do begin + result:= result+msestring(BackTraceStrFunc(Frames[i]))+lineend; + end; + end; +end; + +function getexceptiontext(obj: tobject; addr: pointer; framecount: longint; + frames: ppointer): msestring; +begin + result:= 'An exception occurred at $'+ + hextostrmse(Addr)+' :' + lineend; + result:= result + getexceptionstack(obj,addr,framecount,frames); +end; + +procedure listexceptionstack(Obj: TObject; Addr:Pointer; FrameCount: Longint; + Frames: PPointer); +begin + debugwriteln(ansistring(getexceptionstack(obj,addr,framecount,frames))); +end; + +Procedure CatchUnhandledExcept(Obj : TObject; Addr: Pointer; FrameCount: Longint; + Frames: PPointer); +begin + {$ifdef MSWINDOWS} + if getstdhandle(std_error_handle) <= 0 then begin + catchunhandledexception(obj,addr,framecount,frames); + end + else begin + {$endif} + debugWriteln('An unhandled exception occurred at $'+ + HexStr(Ptrint(Addr),sizeof(PtrInt)*2)+' :'); + listexceptionstack(obj,addr,framecount,frames); + {$ifdef MSWINDOWS} + end; + {$endif} +end; + +{$ifdef mse_debugexception} +procedure raisepro(obj: tobject; addr: pointer; framecount: longint; + frames: ppointer); +begin + debugWriteln('An exception occurred at $'+ + HexStr(Ptrint(Addr),sizeof(PtrInt)*2)+' :'); + listexceptionstack(obj,addr,framecount,frames); +end; +{$endif} + +initialization + exceptproc:= @catchunhandledexcept; +{$ifdef mse_debugexception} + raiseproc:= @raisepro; + raisemaxframecount:= 100; +{$endif} +{$else} //fpc +initialization +{$endif} //delphi + initdefaultformatsettings; +end. diff --git a/mseide-msegui/lib/common/kernel/msesysintf.inc b/mseide-msegui/lib/common/kernel/msesysintf.inc new file mode 100644 index 0000000..4623d0b --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msesysintf.inc @@ -0,0 +1,92 @@ +{ MSEgui Copyright (c) 1999-2015 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} + +function sys_gettimeus: longword; + //systemtime in microseconds, origin undefined +function sys_getpid: procidty; +function sys_getprocesses: procitemarty; +function sys_terminateprocess(const proc: prochandlety): syserrorty; +function sys_killprocess(const proc: prochandlety): syserrorty; + +function sys_threadcreate(var info: threadinfoty): syserrorty; +function sys_threadwaitfor(var info: threadinfoty): syserrorty; +function sys_threaddestroy(var info: threadinfoty): syserrorty; +function sys_threadschedyield: syserrorty; +function sys_getcurrentthread: threadty; +function sys_issamethread(const a,b: threadty): boolean; +function sys_getapplicationpath: filenamety; +function sys_getcommandlinearguments: msestringarty; +procedure sys_getenvvars(out names: msestringarty; out values: msestringarty); +function sys_getenv(const aname: msestring; out avalue: msestring): boolean; + //true if found +function sys_setenv(const aname: msestring; + const avalue: msestring): syserrorty; +function sys_unsetenv(const aname: msestring): syserrorty; + +function sys_filesystemiscaseinsensitive: boolean; +function sys_tosysfilepath(var path: filenamety): syserrorty; + + //all filenames below are in mseformat! +function sys_getcurrentdir: filenamety; +function sys_getapphomedir: filenamety; +function sys_getuserhomedir: filenamety; +function sys_getusername: msestring; +function sys_gettempdir: filenamety; +function sys_setcurrentdir(const dirname: filenamety): syserrorty; +function sys_copyfile(const oldfile,newfile: filenamety): syserrorty; +function sys_deletefile(const filename: filenamety): syserrorty; +function sys_deletedir(const filename: filenamety): syserrorty; +function sys_renamefile(const oldname,newname: filenamety): syserrorty; +function sys_createdir(const path: msestring; + const rights: filerightsty): syserrorty; + +function sys_openfile(const path: filenamety; const openmode: fileopenmodety; + const accessmode: fileaccessmodesty; + const rights: filerightsty; out handle: integer): syserrorty; +function sys_closefile(const handle: integer): syserrorty; +function sys_flushfile(const handle: integer): syserrorty; +function sys_dup(const source: integer; out dest: integer): syserrorty; +function sys_truncatefile(const handle: integer; const size: int64): syserrorty; + +function sys_access(const path: filenamety; + const accessmodes: accessmodesty): syserrorty; +function sys_setfilerights(const path: filenamety; + const rights: filerightsty): syserrorty; +function sys_setfdrights(const fd: longint; + const rights: filerightsty; + const filename: filenamety = ''): syserrorty; + //filename necessary on windows +function sys_read(fd: longint; buf: pointer; nbytes: longword): integer; +function sys_write(fd: longint; buf: pointer; nbytes: longword): integer; +function sys_errorout(const atext: string): syserrorty; +function sys_stdin: integer; +function sys_stdout: integer; +function sys_stderr: integer; + +function sys_getfileinfo(const path: filenamety; var info: fileinfoty): boolean; +function sys_getfdinfo(const fd: longint; var info: fileinfoty): boolean; +function sys_opendirstream(var stream: dirstreamty): syserrorty; +function sys_closedirstream(var stream: dirstreamty): syserrorty; +function sys_readdirstream(var stream: dirstreamty; + var info: fileinfoty): boolean; + //true if valid + +procedure sys_usleep(const us: longword); +procedure sys_schedyield; + +function sys_getutctime: tdatetime; +function sys_getlocaltime: tdatetime; +function sys_localtimeoffset: tdatetime; +function sys_getlangname: string; +function sys_getprintcommand: msestring; +(* +function sys_utctolocaltime(const value: tdatetime): tdatetime; +function sys_localtimetoutc(const value: tdatetime): tdatetime; +*) diff --git a/mseide-msegui/lib/common/kernel/msesysintf1.inc b/mseide-msegui/lib/common/kernel/msesysintf1.inc new file mode 100644 index 0000000..5f8953f --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msesysintf1.inc @@ -0,0 +1,49 @@ +{ MSEgui Copyright (c) 1999-2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} + +function sys_getlasterror: integer; +procedure sys_setlasterror(const avalue: integer); +function sys_geterrortext(aerror: integer): string; + +function sys_mutexcreate(out mutex: mutexty): syserrorty; +function sys_mutexdestroy(var mutex: mutexty): syserrorty; +function sys_mutexlock(var mutex: mutexty): syserrorty; +function sys_mutextrylock(var mutex: mutexty): syserrorty; + //sye_ok if calling thread has lock, sye_busy if already locked by other thread +function sys_mutexunlock(var mutex: mutexty): syserrorty; + +function sys_semcreate(out sem: semty; count: integer): syserrorty; +function sys_semdestroy(var sem: semty): syserrorty; +//function sys_semreset(var sem: semty): syserrorty; //call from single thread! +function sys_sempost(var sem: semty): syserrorty; +function sys_semwait(var sem: semty; timeoutusec: integer): syserrorty; + //timeoutusec <= 0 -> no timeout + //sye_ok -> semaphore signaled + //sye_timeout -> timeout + //sye_semaphore -> error +function sys_semtrywait(var sem: semty): boolean; +function sys_semcount(var sem: semty): integer; + +function sys_condcreate(out cond: condty): syserrorty; +function sys_conddestroy(var cond: condty): syserrorty; +function sys_condlock(var cond: condty): syserrorty; +function sys_condunlock(var cond: condty): syserrorty; +function sys_condsignal(var cond: condty): syserrorty; +function sys_condbroadcast(var cond: condty): syserrorty; +function sys_condwait(var cond: condty; timeoutusec: integer): syserrorty; + //timeoutusec = 0 -> no timeout + //sye_ok -> condition signaled + //sye_timeout -> timeout + //sye_cond -> error + +function sys_utctolocaltime(const value: tdatetime): tdatetime; +function sys_localtimetoutc(const value: tdatetime): tdatetime; + + diff --git a/mseide-msegui/lib/common/kernel/msesystypes.pas b/mseide-msegui/lib/common/kernel/msesystypes.pas new file mode 100644 index 0000000..5c585d0 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msesystypes.pas @@ -0,0 +1,47 @@ +{ MSEgui Copyright (c) 1999-2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msesystypes; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,sysutils; +type + {$ifndef FPC} + tlibhandle = thandle; + {$endif} + threadty = ptruint; + procidty = ptrint; + pprocidty = ^procidty; + procidarty = array of procidty; //same item size as winidarty! + prochandlety = type ptrint; + pprochandlety = ^prochandlety; + + mutexty = array[0..9] of pointer; + semty = array[0..7] of pointer; + psemty = ^semty; + condty = array[0..31] of pointer; + + syserrorty = (sye_ok,sye_lasterror,sye_extendederror,sye_busy,sye_dirstream, + sye_network,sye_write,sye_read, + sye_thread,sye_mutex,sye_semaphore,sye_cond,sye_timeout, + sye_copyfile,sye_createdir,sye_noconsole,sye_notimplemented, + sye_sockaddr,sye_socket,sye_isdir + ); + + ecrashstatfile = class(exception) + end; + +const + invalidprocid = -1; + invalidprochandle = -1; + invalidfilehandle = -1; + +implementation +end. diff --git a/mseide-msegui/lib/common/kernel/msesysutils.pas b/mseide-msegui/lib/common/kernel/msesysutils.pas new file mode 100644 index 0000000..ddea3e0 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msesysutils.pas @@ -0,0 +1,404 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msesysutils; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifndef FPC}{$ifdef linux} {$define UNIX} {$endif}{$endif} + +interface +uses + mclasses,sysutils,msesystypes; + +type + eoserror = class(exception) + public + error: integer; + constructor create(const leadingtext: string = ''); overload; + constructor create(const errno: integer; const leadingtext: string = ''); overload; + //shows getlasterror + end; + + einternalerror = class(exception) + end; + +{$ifdef mswindows} +type + timeval = record + tv_sec: longword; + tv_usec: longword; + end; +{$endif} + +function stdinputhandle: integer; +function stdoutputhandle: integer; +function stderrorhandle: integer; +procedure writestdout(value: string; newline: boolean = false); +procedure writestderr(value: string; newline: boolean = false); +procedure errorhalt(errortext: string; exitcode: integer = 1); +procedure debugwrite(const value: string); +procedure debugwriteln(const value: string); +procedure debugwritestack(const acount: integer = 30); +procedure debugout(const sender: tcomponent; const atext: ansistring); overload; +procedure debugout(const sender: tobject; const atext: ansistring); overload; +procedure debugoutstart(out ts: longword; + const sender: tcomponent; const atext: ansistring); overload; +procedure debugoutend(const ts: longword; + const sender: tcomponent; const atext: ansistring); overload; +procedure internalerror(const text: string); + +function getlasterror: integer; +function getlasterrortext: string; +function syserrortext(const aerror: syserrorty): string; + //returns getlasterortext for sye_lasterror + +function later(ref,act: longword): boolean; + //true if act > ref, with overflowcorrection +function laterorsame(ref,act: longword): boolean; + //true if act >= ref, with overflowcorrection + +procedure sleepus(const us: longword); +procedure waitus(us: integer); +function timestamp: longword; //us, 0 never reported +function timestep(us: longword): longword; //bringt aktzeit + us +function timeout(time: longword): boolean; + +function createguidstring: string; + +procedure reallocmemandinit(var p: pointer; const newsize: sizeint); + +implementation +uses +{$ifdef mswindows} + windows, +{$else} + mselibc, +{$endif} + msesysintf1,msesysintf,msestrings,mseformatstr,msetypes,msesys, + typinfo; + +function createguidstring: string; +var + id: tguid; +begin + createguid(id); + result:= guidtostring(id); +end; + +{ eoserror } + +constructor eoserror.create(const errno: integer; const leadingtext: string = ''); +begin + error:= errno; + inherited create(leadingtext + 'OSError ' + inttostr(error) + ': ' + + sys_geterrortext(error)); +end; + +constructor eoserror.create(const leadingtext: string); +begin + create(getlasterror,leadingtext); +end; + +function timestamp: longword; +begin + result:= sys_gettimeus; + if result = 0 then begin + result:= 1; + end; +end; + + {$ifdef UNIX} +{ +function timestamp: longword; +var + t1: timeval; +begin + gettimeofday(t1,ptimezone(nil)^); + result:= t1.tv_sec * 1000000 + t1.tv_usec; + if result = 0 then begin + result:= 1; + end; +end; +} +procedure waitus(us: integer); +var + time: longword; +begin + time:= timestep(us); + repeat + until timeout(time); +end; + +{$endif unix} + +{$ifdef mswindows} +{ +function timestamp: longword; +begin + result:= gettickcount * 1000; + if result = 0 then begin + result:= 1; + end; +end; +} +procedure waitperformancecounter(time: int64); +var + time1: int64; + len: longword; + +begin + if queryperformancecounter(time1) then begin + len:= time1 + time; + repeat + queryperformancecounter(time1); + until integer(dword(time1)-len) > 0; //rollup + end; +end; + +procedure waitus(us: integer); +var + freq: int64; +begin + if us > 0 then begin + queryperformancefrequency(freq); + waitperformancecounter((freq*us) div 1000000); + end; +end; + +{$endif} + +function timestep(us: longword): longword; //bringt aktzeit + us +begin + result:= timestamp + us; +end; + +function timeout(time: longword): boolean; +begin + result:= laterorsame(time,timestamp); +end; + +function later(ref,act: longword): boolean; +var + ca1: longword; +begin + ca1:= act-ref; + result:= integer(ca1) > 0; +// result:= integer(act-ref) > 0; //FPC bug 4768 +end; + +function laterorsame(ref,act: longword): boolean; +var + ca1: longword; +begin + ca1:= act-ref; + result:= integer(ca1) >= 0; +// result:= integer(act-ref) > 0; //FPC bug 4768 +end; + +procedure sleepus(const us: longword); +begin + sys_usleep(us); +end; + +{$ifdef mswindows} +function stdinputhandle: integer; +begin + result:= getstdhandle(std_input_handle); + if result <= 0 then begin + result:= invalidfilehandle; + end; +end; + +function stdoutputhandle: integer; +begin + result:= getstdhandle(std_output_handle); + if result <= 0 then begin + result:= invalidfilehandle; + end; +end; + +function stderrorhandle: integer; +begin + result:= getstdhandle(std_error_handle); + if result <= 0 then begin + result:= invalidfilehandle; + end; +end; + +{$else} + +function stdinputhandle: integer; +begin + result:= 0; +end; + +function stdoutputhandle: integer; +begin + result:= 1; +end; + +function stderrorhandle: integer; +begin + result:= 2; +end; + +{$endif} +procedure writestdout(value: string; newline: boolean = false); + {$ifdef mswindows} +var + ca1: longword; + {$endif} +begin + if newline then begin + value:= value + lineend; + end; + {$ifdef UNIX} + sys_write(1,pointer(value),length(value)); + {$else} + if getstdhandle(std_output_handle) <= 0 then begin + allocconsole; + end; + writefile(getstdhandle(std_output_handle),pointer(value)^,length(value),ca1,nil); + {$endif} +end; + +procedure writestderr(value: string; newline: boolean = false); + {$ifdef mswindows} +var + ca1: longword; + {$endif} +begin + if newline then begin + value:= value + lineend; + end; + {$ifdef UNIX} + sys_write(2,pointer(value),length(value)); + {$else} + if getstdhandle(std_error_handle) <= 0 then begin + allocconsole; + end; + writefile(getstdhandle(std_error_handle),pointer(value)^,length(value),ca1,nil); + {$endif} +end; + +procedure debugwrite(const value: string); +begin + writestderr(value,false); +end; + +procedure debugwriteln(const value: string); +begin + writestderr(value,true); +end; + +procedure debugwritestack(const acount: integer = 30); +var + int1: integer; +begin +{$ifdef FPC} + int1:= raisemaxframecount; + raisemaxframecount:= acount; + try + raise exception.create(''); + except + debugwriteln(ansistring(getexceptiontext(exceptobject, + exceptaddr,exceptframecount,exceptframes))); + end; + raisemaxframecount:= int1; +{$endif} +end; + +procedure debugout(const sender: tcomponent; const atext: ansistring); +begin + if sender = nil then begin + debugwriteln('NIL '+atext); + end + else begin + debugwriteln(hextostr(ptruint(sender),8)+' '+ + sender.name+':'+sender.classname+' '+atext); + end; +end; + +procedure debugout(const sender: tobject; const atext: ansistring); +begin + if sender = nil then begin + debugwriteln('NIL '+atext); + end + else begin + debugwriteln(hextostr(ptruint(sender),8)+' '+ + sender.classname+' '+atext); + end; +end; + +procedure debugoutstart(out ts: longword; + const sender: tcomponent; const atext: ansistring); +begin + ts:= timestamp; + debugout(sender,'*start '+atext); +end; + +procedure debugoutend(const ts: longword; + const sender: tcomponent; const atext: ansistring); +begin + debugout(sender,ansistring('**end '+formatfloatmse( + (timestamp-ts)/1000000,'0.000000')+'s '+ + msestring(atext))); +end; + +procedure internalerror(const text: string); +begin + raise einternalerror.create('Internal error '+text); +end; + +procedure errorhalt(errortext: string; exitcode: integer = 1); +begin + writestderr(errortext,true); + halt(exitcode); +end; + +function getlasterror: integer; +begin + result:= sys_getlasterror; +end; + +function getlasterrortext: string; +var + int1: integer; +begin + int1:= sys_getlasterror; + result:= inttostr(int1) + ': ' + sys_geterrortext(int1); +end; + +function syserrortext(const aerror: syserrorty): string; + //returns getlasterortext for sye_lasterror +begin + case aerror of + sye_lasterror: begin + result:= getlasterrortext(); + end; + else begin + result:= getenumname(typeinfo(syserrorty),integer(aerror)); + end; + end; +end; + +procedure reallocmemandinit(var p: pointer; const newsize: sizeint); +var + oldsize: ptrint; +begin + oldsize:= 0; + if p <> nil then begin + oldsize:= memsize(p); + end; + reallocmem(p,newsize); + fillchar((p+oldsize)^,newsize-oldsize,0); +end; + +end. + diff --git a/mseide-msegui/lib/common/kernel/msethread.pas b/mseide-msegui/lib/common/kernel/msethread.pas new file mode 100644 index 0000000..d44a8d2 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msethread.pas @@ -0,0 +1,478 @@ +{ MSEgui Copyright (c) 1999-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msethread; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +{$ifndef FPC}{$ifdef linux} {$define UNIX} {$endif}{$endif} + +interface +uses + {$ifdef FPC}{$ifdef UNIX}cthreads,{$endif}classes{$else}Classes{$endif}, + mseclasses,mselist,mseevent,msesystypes,msesys,msetypes,sysutils; + +{$ifndef FPC} +const + DefaultStackSize = 4*1024*1024; +{$endif} +type + tmsethread = class; + + threadprocty = function(thread: tmsethread): integer of object; + + threadstatety = (ts_started,ts_running,ts_terminated,ts_freeonterminate, + ts_norun); //no run by create() + threadstatesty = set of threadstatety; + + tmsethread = class + protected + finfo: threadinfoty; + fthreadproc: threadprocty; + fexecresult: integer; + fstate: threadstatesty; + fwaitforsem: semty; + function internalthreadproc: integer; + function getrunning: boolean; + function getterminated: boolean; + function getfreeonterminate: boolean; + procedure setfreeonterminate(const avalue: boolean); + function execute(thread: tmsethread): integer; virtual; + procedure run(); virtual; + public + constructor create; overload; + constructor create(const afreeonterminate: boolean; + const astacksizekb: integer = 0); overload; + constructor create(const athreadproc: threadprocty; + const afreeonterminate: boolean = false; + const astacksizekb: integer = 0); overload; virtual; + destructor destroy; override; + procedure afterconstruction; override; + function waitfor: integer; virtual; + procedure terminate; virtual; + procedure kill; //killing a running thread will loose resources! + property running: boolean read getrunning; + property terminated: boolean read getterminated; + property id: threadty read finfo.id; + property freeonterminate: boolean read getfreeonterminate + write setfreeonterminate; + //do not change the value if the thread is running + end; + + tmutexthread = class(tmsethread) + protected + fmutex: mutexty; + public + constructor create(const athreadproc: threadprocty; + const afreeonterminate: boolean = false; + const astacksizekb: integer = 0); override; + destructor destroy; override; + function lock: boolean; //true if ok + procedure unlock; + end; + + tsemthread = class(tmutexthread) + protected + fsem: semty; + public + constructor create(const athreadproc: threadprocty; + const afreeonterminate: boolean = false; + const astacksizekb: integer = 0); override; + destructor destroy; override; + function semwait(const atimeoutus: integer = 0): boolean; + function sempost: boolean; //true if not destroyed + function semtrywait: boolean; + function semcount: integer; + end; + + teventthread = class(tsemthread) + protected + feventlist: teventqueue; + public + constructor create(const athreadproc: threadprocty; + const afreeonterminate: boolean = false; + const astacksizekb: integer = 0); overload; override; + destructor destroy(); override; + procedure terminate(); override; + procedure postevent(event: tmseevent); + procedure clearevents(); + function waitevent(const timeoutus: integer = -1): tmseevent; + // -1 infinite, 0 no block + function eventcount(): integer; + property eventlist: teventqueue read feventlist; + end; + + tsynchronizeevent = class(texecuteevent) + protected + fsem: semty; + fsuccess: boolean; + fexceptionclass: exceptclass; + fexceptionmessage: string; + fquiet: boolean; + procedure internalfree1; override; + public + constructor create(const aquiet: boolean); + //quiet -> show no exceptions + destructor destroy; override; + procedure deliver; override; + function waitfor: boolean; + property quiet: boolean read fquiet; + property success: boolean read fsuccess; + property exeptionclass: exceptclass read fexceptionclass; + property exceptionmessage: string read fexceptionmessage; + end; + +function synchronizeevent(const aevent: tsynchronizeevent; + const aoptions: posteventoptionsty = []): boolean; + //true if not aborted, does not free aevent + +implementation + +uses + msesysintf1,msesysintf,mseapplication; + +function synchronizeevent(const aevent: tsynchronizeevent; + const aoptions: posteventoptionsty = []): boolean; + //true if not aborted, does not free aevent +var + int1: integer; +begin + if not application.terminated then begin + if application.ismainthread then begin + try + aevent.execute; + result:= true; + except + if not aevent.quiet then begin + raise; + end; + result:= false; + end; + end + else begin + result:= false; + int1:= application.unlockall; + try + application.postevent(aevent,aoptions); + result:= aevent.waitfor and aevent.success; + //wait until main eventloop calls tevent.free1 + finally + application.relockall(int1); + end; + end; + end; +end; + +procedure createthread(var info: threadinfoty); +begin + syserror(sys_threadcreate(info)); +end; + +{ tsynchronizeevent } + +constructor tsynchronizeevent.create(const aquiet: boolean); +begin + fquiet:= aquiet; + sys_semcreate(fsem,0); + inherited create; +end; + +destructor tsynchronizeevent.destroy; +begin + sys_semdestroy(fsem); + inherited; +end; + +procedure tsynchronizeevent.deliver; +begin + try + inherited; +// execute; + fsuccess:= true; + except + on e: exception do begin + fexceptionclass:= exceptclass(e.classinfo); + fexceptionmessage:= e.message; + if not fquiet then begin +// sys_sempost(fsem); + raise; + end; + end; + end; +// sys_sempost(fsem); +end; + +function tsynchronizeevent.waitfor: boolean; +begin + result:= sys_semwait(fsem,0) = sye_ok; +end; + +procedure tsynchronizeevent.internalfree1; +begin + sys_sempost(fsem); //no inherited, don't free in main eventloop +end; + +{ tmsethread } + +constructor tmsethread.create; +begin + create(false); +end; + +constructor tmsethread.create(const afreeonterminate: boolean; + const astacksizekb: integer = 0); +begin + create({$ifdef FPC}@{$endif}execute,afreeonterminate,astacksizekb); +end; + +constructor tmsethread.create(const athreadproc: threadprocty; + const afreeonterminate: boolean = false; + const astacksizekb: integer = 0); +begin + sys_semcreate(fwaitforsem,0); + fthreadproc:= athreadproc; +// fstate:= [ts_running,ts_started]; + if afreeonterminate then begin + include(fstate,ts_freeonterminate); + end; + with finfo do begin + if astacksizekb = 0 then begin + stacksize:= defaultstacksize; + end + else begin + stacksize:= astacksizekb * 1024; + end; + threadproc:= {$ifdef FPC}@{$endif}internalthreadproc; + end; +{ + if not (ts_norun in fstate) then begin + run(); + end; +} +end; + +procedure tmsethread.afterconstruction; +begin + if not (ts_norun in fstate) then begin + run(); + end; + if ts_freeonterminate in fstate then begin + sys_sempost(fwaitforsem); + end; +end; + +procedure tmsethread.run(); +begin + fstate:= fstate + [ts_running,ts_started]; + createthread(finfo); +end; + +destructor tmsethread.destroy; +begin + if finfo.id <> 0 then begin + terminate; + waitfor; + sys_threadwaitfor(finfo); + kill; + end; + inherited; +end; + +procedure tmsethread.terminate; +begin + include(fstate,ts_terminated); +end; + +function tmsethread.waitfor: integer; +begin + if ts_started in fstate then begin + if ts_freeonterminate in fstate then begin + raise exception.create('No waitfor() if ts_freeonterminate set.'); + end; + exclude(fstate,ts_started); + sys_semwait(fwaitforsem,0); + end; + result:= fexecresult; +end; + +procedure tmsethread.kill; +begin + if (self <> nil) and (finfo.id <> 0) then begin + exclude(fstate,ts_running); + sys_threaddestroy(finfo); + finfo.id:= 0; + sys_semdestroy(fwaitforsem); + end; +end; + +function tmsethread.getrunning: boolean; +begin + result:= ts_running in fstate; +end; + +function tmsethread.getterminated: boolean; +begin + result:= ts_terminated in fstate; +end; + +function tmsethread.execute(thread: tmsethread): integer; +begin + result:= 0; +end; + +function tmsethread.internalthreadproc: integer; +var + info1: threadinfoty; +begin + try + result:= fthreadproc(self); + except + result:= -1; + application.handleexception(self); + end; + fexecresult:= result; + exclude(fstate,ts_running); + if not freeonterminate then begin + sys_sempost(fwaitforsem); + end + else begin + sys_semwait(fwaitforsem,0); + info1:= finfo; + finfo.id:= 0; + free(); + sys_threaddestroy(info1); + end; +end; + +function tmsethread.getfreeonterminate: boolean; +begin + result:= ts_freeonterminate in fstate; +end; + +procedure tmsethread.setfreeonterminate(const avalue: boolean); +begin + if avalue then begin + include(fstate,ts_freeonterminate); + sys_semtrywait(fwaitforsem); //remove possible afterconstruction post + end + else begin + exclude(fstate,ts_freeonterminate); + end; +end; + +{ tmutexthread } + +constructor tmutexthread.create(const athreadproc: threadprocty; + const afreeonterminate: boolean = false; + const astacksizekb: integer = 0); +begin + syserror(sys_mutexcreate(fmutex),self); + inherited; +end; + +destructor tmutexthread.destroy; +begin + inherited; + sys_mutexdestroy(fmutex); +end; + +function tmutexthread.lock: boolean; +begin + result:= sys_mutexlock(fmutex) = sye_ok; +end; + +procedure tmutexthread.unlock; +begin + sys_mutexunlock(fmutex); +end; + +{ teventthread } + +constructor teventthread.create(const athreadproc: threadprocty; + const afreeonterminate: boolean = false; + const astacksizekb: integer = 0); +begin + feventlist:= teventqueue.create(true); + inherited; +end; + +destructor teventthread.destroy; +begin + inherited; + feventlist.Free; +end; + +function teventthread.eventcount: integer; +begin + feventlist.lock(); + result:= feventlist.count; + feventlist.unlock(); +end; + +procedure teventthread.postevent(event: tmseevent); +begin + feventlist.post(event); +end; + +procedure teventthread.terminate; +begin + inherited; + postevent(tmseevent.create(ek_terminate)); +end; + +function teventthread.waitevent(const timeoutus: integer = -1): tmseevent; +begin + result:= feventlist.wait(timeoutus); + if (result <> nil) and (result.kind = ek_terminate) then begin + freeandnil(result); + end; +end; + +procedure teventthread.clearevents(); +begin + feventlist.clear; +end; + +{ tsemthread } + +constructor tsemthread.create(const athreadproc: threadprocty; + const afreeonterminate: boolean = false; + const astacksizekb: integer = 0); +begin + sys_semcreate(fsem,0); + inherited; +end; + +destructor tsemthread.destroy; +begin + terminate; + sys_semdestroy(fsem); + inherited; +end; + +function tsemthread.semcount: integer; +begin + result:= sys_semcount(fsem); +end; + +function tsemthread.sempost: boolean; +begin + result:= sys_sempost(fsem) = sye_ok; +end; + +function tsemthread.semtrywait: boolean; +begin + result:= sys_semtrywait(fsem); +end; + +function tsemthread.semwait(const atimeoutus: integer = 0): boolean; +begin + result:= sys_semwait(fsem,atimeoutus) = sye_ok; +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/msethreadcomp.pas b/mseide-msegui/lib/common/kernel/msethreadcomp.pas new file mode 100644 index 0000000..4e62fd7 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msethreadcomp.pas @@ -0,0 +1,227 @@ +{ MSEgui Copyright (c) 1999-2009 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msethreadcomp; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseclasses,msethread,classes,mclasses,mseevent,msetypes,msestrings,mseapplication; + +type + tthreadcomp = class; + threadcompeventty = procedure(const sender: tthreadcomp) of object; + threadcompoption = (tco_autorelease); + threadcompoptionsty = set of threadcompoption; + + tthreadcomp = class(tactcomponent) + private + fthread: teventthread; + fonstart: threadcompeventty; + fonterminate: threadcompeventty; + fonexecute: threadcompeventty; + factive: boolean; + fdatapo: pointer; + foptions: threadcompoptionsty; + fstacksizekb: integer; + fonterminated: threadcompeventty; + function getthread: teventthread; + function getterminated: boolean; + function threadproc(sender: tmsethread): integer; + procedure terminateandwait; + function getactive: boolean; + procedure doterminated; + protected + procedure setactive(const Value: boolean); override; + procedure loaded; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + + property datapo: pointer read fdatapo; + procedure run(const adatapo: pointer = nil); + procedure terminate; + procedure waitfor; //does unlock,relock before waiting + + function lock: boolean; + procedure unlock; + procedure postevent(event: tmseevent); + function waitevent(const timeoutus: integer = -1): tmseevent; + // -1 infinite, 0 no block + + property thread: teventthread read getthread; + property terminated: boolean read getterminated; + + published + property options: threadcompoptionsty read foptions write foptions default []; + property stacksizekb: integer read fstacksizekb write fstacksizekb default 0; + property active: boolean read getactive write setactive default false; + property onstart: threadcompeventty read fonstart write fonstart; + property onexecute: threadcompeventty read fonexecute write fonexecute; + property onterminate: threadcompeventty read fonterminate write fonterminate; + property onterminated: threadcompeventty read fonterminated write fonterminated; + //runs in main thread + end; + +implementation +uses + sysutils{,mseapplication},msesystypes,msesys; + +{ tthreadcomp } + +constructor tthreadcomp.create(aowner: tcomponent); +begin + inherited; +end; + +destructor tthreadcomp.destroy; +begin + terminateandwait; + inherited; +end; + +procedure tthreadcomp.terminateandwait; +begin + if fthread <> nil then begin + terminate; + waitfor; + end; + fthread.free; + fthread:= nil; +end; + +procedure tthreadcomp.run(const adatapo: pointer = nil); +begin + terminateandwait; + factive:= true; + fdatapo:= adatapo; +// fthread:= teventthread.create({$ifdef FPC}@{$endif}threadproc,false, +// fstacksizekb); + fthread:= teventthread(teventthread.newinstance); + fthread.create({$ifdef FPC}@{$endif}threadproc,false, + fstacksizekb); +end; + +function tthreadcomp.lock: boolean; +begin + result:= thread.lock; +end; + +procedure tthreadcomp.unlock; +begin + thread.unlock; +end; + +function tthreadcomp.threadproc(sender: tmsethread): integer; +begin +// fthread:= teventthread(sender); + try + if assigned(fonstart) then begin + application.lock; + try + fonstart(self); + finally + application.unlock; + end; + end; + if assigned(fonexecute) then begin + fonexecute(self); + end; + if assigned(fonterminate) then begin + application.lock; + try + fonterminate(self); + finally + application.unlock; + end; + end; + if assigned(fonterminated) then begin + application.synchronize({$ifdef FPC}@{$endif}doterminated); + end; + result:= 0; + finally + if tco_autorelease in foptions then begin + release; + end; + end; +end; + +function tthreadcomp.getthread: teventthread; +begin + if fthread = nil then begin + syserror(sye_thread,self); + end; + result:= fthread; +end; + +function tthreadcomp.getterminated: boolean; +begin + result:= thread.terminated; +end; + +procedure tthreadcomp.terminate; +begin + if fthread <> nil then begin + fthread.terminate; + end; +end; + +procedure tthreadcomp.waitfor; +begin + if fthread <> nil then begin + application.waitforthread(thread); + end; +end; + +procedure tthreadcomp.postevent(event: tmseevent); +begin + thread.postevent(event); +end; + +function tthreadcomp.waitevent(const timeoutus: integer = -1): tmseevent; +begin + result:= thread.waitevent(timeoutus); +end; + +function tthreadcomp.getactive: boolean; +begin + result:= factive; +end; + +procedure tthreadcomp.loaded; +begin + inherited; + if not (csdesigning in componentstate) and factive and (fthread = nil) then begin + run; + end; +end; + +procedure tthreadcomp.setactive(const Value: boolean); +begin + if factive <> value then begin + factive:= value; + if not value then begin + terminateandwait; + end + else begin + if componentstate * [csloading,csdesigning] = [] then begin + run; + end; + end; + end; +end; + +procedure tthreadcomp.doterminated; +begin + fonterminated(self); +end; + +end. + diff --git a/mseide-msegui/lib/common/kernel/msetimer.pas b/mseide-msegui/lib/common/kernel/msetimer.pas new file mode 100644 index 0000000..fc3f588 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msetimer.pas @@ -0,0 +1,1426 @@ +{ MSEgui Copyright (c) 1999-2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msetimer; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$goto on}{$endif} + +interface +uses + classes,mclasses,msetypes,mseevent,mseclasses,mseglob; + +type + timeroptionty = (to_single, //single shot + to_leak, //do not catch up missed timeouts + to_highres, //call application.beginhighrestimer/ + //endhighrestimer, necessary on windows in order + //to get 1ms jitter + to_absolute, //use absolute time (timestamp()) for to_single + //disabled for ttimer + to_autostart);//set enabled for to_single by setting interval, + //disabled for ttimer + timeroptionsty = set of timeroptionty; + + tsimpletimer = class(tnullinterfacedobject) + private + fenabled: boolean; + finterval: longword; + fontimer: notifyeventty; + foptions: timeroptionsty; +// fpending: boolean; + procedure setenabled(const Value: boolean); + procedure setinterval(const avalue: longword); + function getsingleshot: boolean; + procedure setsingleshot(const avalue: boolean); + procedure setoptions(const avalue: timeroptionsty); + function gethighres: boolean; + procedure sethighres(const avalue: boolean); + function getleak: boolean; + procedure setleak(const avalue: boolean); + protected + procedure dotimer; virtual; + public + constructor create(const interval: longword = 0; + const ontimer: notifyeventty = nil; + const active: boolean = false; + const aoptions: timeroptionsty = []); + //activates timer + destructor destroy; override; + procedure firependingandstop; + procedure fireandstop; + procedure fire; + procedure restart; + property interval: longword read finterval write setinterval; + //in microseconds, max +2000 seconds + //restarts timer if enabled + //0 -> fire once in mainloop idle + property options: timeroptionsty read foptions write setoptions; + property singleshot: boolean read getsingleshot write setsingleshot; + property highres: boolean read gethighres write sethighres; + property leak: boolean read getleak write setleak; + property ontimer: notifyeventty read fontimer write fontimer; + property enabled: boolean read fenabled write setenabled default true; + //last! + end; + + trepeater = class(tsimpletimer) + private + finterval2: longword; + protected + procedure dotimer; override; + public + constructor create(const adelay: longword; const ainterval: longword; + const aontimer: notifyeventty); + end; + + ttimer = class(tmsecomponent) + private + ftimer: tsimpletimer; + fenabled: boolean; //for design +// foptions: timeroptionsty; + fontimer: notifyeventty; + function getenabled: boolean; + procedure setenabled(const avalue: boolean); + function getinterval: integer; + procedure setinterval(avalue: integer); + function getontimer: notifyeventty; + procedure setontimer(const Value: notifyeventty); + function getoptions: timeroptionsty; + procedure setoptions(const avalue: timeroptionsty); + function getsingleshot: boolean; + procedure setsingleshot(const avalue: boolean); + procedure dotimer(const sender: tobject); + protected + procedure doasyncevent(var atag: integer); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure restart; + procedure firependingandstop; + procedure fireandstop; + procedure fire; + property singleshot: boolean read getsingleshot write setsingleshot; + published + property interval: integer read getinterval write setinterval default 1000000; + //in microseconds, max 2000 seconds + //restarts timer if enabled + //0 -> fire once in main loop idle + property options: timeroptionsty read getoptions write setoptions default []; + property ontimer: notifyeventty read fontimer write fontimer; + property enabled: boolean read getenabled write setenabled default false; + //last! + end; + +const + defaultanimtick = 100000; //microseconds + +type + animkindty = (ank_single,ank_sawtooth,ank_triangle); + animoptionty = (ano_enabled, + ano_autodestroy //animitem destroyed if enable set to false + //or ank_single terminates + ); + animoptionsty = set of animoptionty; + + tanimtimer = class; + tanimitem = class; + + animtickeventty = procedure(const sender: tanimitem; + const avalue: flo64) of object; + animstatety = (ans_down,ans_finished); + animstatesty = set of animstatety; + + tanimitem = class(tlinkedobject) + private + fontick: animtickeventty; + fonstart: notifyeventty; + fonstop: notifyeventty; + procedure setenabled(const avalue: boolean); + procedure settickus(const avalue: int32); + procedure setkind(const avalue: animkindty); + procedure setoptions(const avalue: animoptionsty); + function getdown: boolean; + procedure setdown(const avalue: boolean); + function getvalue: flo64; + protected + fowner: tobject; + ftimer: tanimtimer; + fenabled: boolean; + fref: card32; + fnexttick: card32; + ftickus: int32; + ftickref: card32; + fkind: animkindty; + fstate: animstatesty; + foptions: animoptionsty; + finterval: flo64; + ftime: flo64; + procedure tick(); virtual; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + procedure settimer(const atimer: tanimtimer); + procedure setnexttick(); + procedure setnexttick1(); + public + constructor create(const aowner: iobjectlink; const atimer: tanimtimer; + const aontick: animtickeventty; + const ainterval: flo64; //seconds + const akind: animkindty = ank_single; + const aoptions: animoptionsty = [ano_enabled]; + const atickus: int32 = 0); //0 = default + constructor create(const aowner: tmsecomponent; const atimer: tanimtimer; + const aontick: animtickeventty; + const ainterval: flo64; //seconds + const akind: animkindty = ank_single; + const aoptions: animoptionsty = [ano_enabled]; + const atickus: int32 = 0); //0 = default + destructor destroy(); override; + procedure reset(); + procedure restart(); + property kind: animkindty read fkind write setkind; + property options: animoptionsty read foptions write setoptions; + property enabled: boolean read fenabled write setenabled; + property tickus: int32 read ftickus write settickus default 0; + property time: flo64 read ftime write ftime; + property down: boolean read getdown write setdown; + property value: flo64 read getvalue; + property interval: flo64 read finterval write finterval; //seconds + property timer: tanimtimer read ftimer write settimer; + property ontick: animtickeventty read fontick write fontick; + property onstart: notifyeventty read fonstart write fonstart; + property onstop: notifyeventty read fonstop write fonstop; + end; + panimitem = ^tanimitem; + animitemarty = array of tanimitem; + + tanimtimer = class(tmsecomponent) + private + ftouched: boolean; + function gettickus: int32; + procedure settickus(const avalue: int32); + function gethighres: boolean; + procedure sethighres(const avalue: boolean); + procedure setenabled(const avalue: boolean); + protected + fenabledcount: int32; + fitems: animitemarty; + ftimer: tsimpletimer; + fenabled: boolean; + procedure dotimer(const sender: tobject); + procedure add(const aitem: tanimitem); + procedure remove(const aitem: tanimitem); + procedure itemenabled(const avalue: boolean); + procedure checkenabled(); + procedure loaded() override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property enabledcount: int32 read fenabledcount; + published + property tickus: int32 read gettickus write settickus default defaultanimtick; + property highres: boolean read gethighres write sethighres default false; + property enabled: boolean read fenabled write setenabled default false; + end; + + tanimitemcomp = class(tmsecomponent) + private + fitem: tanimitem; + fenabled: boolean; + function getkind: animkindty; + procedure setkind(const avalue: animkindty); + function getoptions: animoptionsty; + procedure setoptions(const avalue: animoptionsty); + function gettimer: tanimtimer; + procedure settimer(const avalue: tanimtimer); + function getenabled: boolean; + procedure setenabled(const avalue: boolean); + function gettickus: int32; + procedure settickus(const avalue: int32); + function gettime: flo64; + procedure settime(const avalue: flo64); + function getontick: animtickeventty; + procedure setontick(const avalue: animtickeventty); + function getonstop: notifyeventty; + procedure setonstop(const avalue: notifyeventty); + function getinterval: flo64; + procedure setinterval(const avalue: flo64); + function getonstart: notifyeventty; + procedure setonstart(const avalue: notifyeventty); + function getdown: boolean; + procedure setdown(const avalue: boolean); + protected + procedure loaded() override; + public + constructor create(aowner: tcomponent); override; + destructor destroy(); override; + procedure reset(); + procedure restart(); + property time: flo64 read gettime write settime; + property down: boolean read getdown write setdown; + published + property kind: animkindty read getkind write setkind default ank_single; +// property options: animoptionsty read getoptions write setoptions; + property interval: flo64 read getinterval write setinterval; //seconds + property enabled: boolean read getenabled write setenabled default false; + property timer: tanimtimer read gettimer write settimer; + property tickus: int32 read gettickus write settickus default 0; + property ontick: animtickeventty read getontick write setontick; + property onstart: notifyeventty read getonstart write setonstart; + property onstop: notifyeventty read getonstop write setonstop; + end; + +procedure tick(sender: tobject); +procedure init; +procedure deinit; + +implementation +uses + msesysintf1,msesysintf,SysUtils,mseapplication,msesystypes,msesysutils, + msearrayutils, + mseformatstr{$ifndef mswindows},mselibc{$endif}; + +const + enabletimertag = 8346320; + +type + tapplication1 = class(tcustomapplication); + ptimerinfoty = ^timerinfoty; + timerinfoty = record + nexttime: longword; + interval: longword; + prevpo,nextpo: ptimerinfoty; + ontimer: proceventty; + options: timeroptionsty + {$ifdef mse_debugtimer} + ;checked: boolean + {$endif} + end; + +var + first: ptimerinfoty; + mutex: mutexty; +{$ifdef mse_debugtimer} + timeitemcount: integer; + +procedure checktimer; +var + int1: integer; + po1,po2: ptimerinfoty; +begin + int1:= 0; + po1:= first; + while po1 <> nil do begin + inc(int1); + if po1^.checked then begin + raise exception.create('Recursion in timer list.'); + end; + po1^.checked := true; + if (po1^.nextpo <> nil) and (po1^.nextpo^.prevpo <> po1) then begin + raise exception.create('Invalid back link in timer list'); + end; + po1:= po1^.nextpo; + end; + if int1 <> timeitemcount then begin + raise exception.create('Invalid timer item count.'); + end; + po1:= first; + while po1 <> nil do begin + po1^.checked:= false; + po1:= po1^.nextpo; + end; +end; +{$endif} + +var + timeraccesscount: integer; + +procedure extract(po: ptimerinfoty); + //mutex has to be locked +begin + if not application.ismainthread then begin + inc(timeraccesscount); + end; + if first = po then begin + first:= po^.nextpo; + if first <> nil then begin + first^.prevpo:= nil; + end; + end; + if po^.prevpo <> nil then begin + po^.prevpo^.nextpo:= po^.nextpo; + end; + if po^.nextpo <> nil then begin + po^.nextpo^.prevpo:= po^.prevpo; + end; +{$ifdef mse_debugtimer} + dec(timeitemcount); + checktimer; + inc(timeitemcount); +{$endif} +end; + +procedure insert(po: ptimerinfoty); //mutex has to be locked +var + po1,po2: ptimerinfoty; + ca1: longword; +begin + if not application.ismainthread then begin + inc(timeraccesscount); + end; + ca1:= po^.nexttime; + po2:= po; + po1:= po^.nextpo; + if po1 = nil then begin + po1:= first; + end; +// while (po1 <> nil) and (integer(po1^.nexttime-ca1) < 0) do begin //todo!!!!!: FPC bug 4768 + while (po1 <> nil) and later(po1^.nexttime,ca1) do begin + po2:= po1; + po1:= po1^.nextpo; + end; + if po1 = nil then begin //last + if po2 = po then begin //single + po^.prevpo:= nil; + first:= po; + end + else begin //last + po^.prevpo:= po2; + po2^.nextpo:= po; + end; + po^.nextpo:= nil; + end + else begin + if po1^.prevpo = nil then begin //first + po^.prevpo:= nil; + po1^.prevpo:= po; + first:= po; + po^.nextpo:= po1; + end + else begin + po^.prevpo:= po1^.prevpo; + po^.prevpo^.nextpo:= po; + po1^.prevpo:= po; + po^.nextpo:= po1; + end; + end; +{$ifdef mse_debugtimer} + checktimer; +{$endif} +end; + +procedure killtimertick(aontimer: proceventty); +var + po1{,po2}: ptimerinfoty; +begin + sys_mutexlock(mutex); + po1:= first; + while po1 <> nil do begin + if issamemethod(tmethod(po1^.ontimer),tmethod(aontimer)) then begin + po1^.ontimer:= nil; + end; + po1:= po1^.nextpo; + end; + sys_mutexunlock(mutex); +end; + +procedure starttimer(const reftime: longword); +var + int1: integer; +begin + int1:= first^.nexttime-reftime; + application.settimer(int1); +end; + +procedure settimertick(ainterval: integer; + const aontimer: proceventty; const aoptions: timeroptionsty); +var + po: ptimerinfoty; + time: longword; +begin + new(po); + sys_mutexlock(mutex); + {$ifdef mse_debugtimer} + inc(timeitemcount); +{$endif} + time:= sys_gettimeus; + if to_absolute in aoptions then begin + ainterval:= ainterval - time; + if integer(ainterval) < 0 then begin + ainterval:= 0; //on idle + end; + end; + fillchar(po^,sizeof(timerinfoty),0); + with po^ do begin + nexttime:= time + longword(ainterval); + interval:= ainterval; + options:= aoptions; + if ainterval = 0 then begin + include(options,to_leak); //on idle + end; +// if to_single in aoptions{ainterval < 0} then begin +// interval:= 0; +// end; + ontimer:= aontimer; + end; + insert(po); + if first = po then begin + starttimer(time); + end + else begin + if later(first^.nexttime,time) then begin + application.postevent(tmseevent.create(ek_timer)); + //timerevent is possibly lost + end; + end; + sys_mutexunlock(mutex); +end; + +var + timebefore: longword; + +procedure tick(sender: tobject); +var + time: longword; + ca1: longword; + po,po2: ptimerinfoty; + ontimer: proceventty; + int1: integer; + timeraccesscountbefore: integer; +label + endlab; +begin + sys_mutexlock(mutex); + tapplication1(application).resettimertrigger; + if first <> nil then begin +{$ifdef mse_debugtimer} + checktimer; +{$endif} + time:= sys_gettimeus; + inc(timeraccesscount); + timeraccesscountbefore:= timeraccesscount; + ca1:= time-timebefore; + timebefore:= time; + if integer(ca1) < 0 then begin //clock has been changed + po:= first; + while po <> nil do begin + po^.nexttime:= po^.nexttime + ca1; //shift timeouts + po:= po^.nextpo; + end; + end; + po:= first; + while (po <> nil) and laterorsame(po^.nexttime,time) do begin + extract(po); + ontimer:= po^.ontimer; + po2:= po^.nextpo; + if (to_single in po^.options) or not assigned(ontimer) then begin + //single shot or killed, remove item + dispose(po); + {$ifdef mse_debugtimer} + dec(timeitemcount); + {$endif} + if assigned(ontimer) then begin + sys_mutexunlock(mutex); + try + ontimer; + except + application.handleexception(sender); + end; + sys_mutexlock(mutex); + if timeraccesscount <> timeraccesscountbefore then begin + goto endlab; //processmessages called + end; + end; + end + else begin + if to_leak in po^.options then begin + int1:= 1; + inc(po^.nexttime,po^.interval); + if later(po^.nexttime,time) then begin + po^.nexttime:= time + po^.interval; + end; + end + else begin + int1:= 0; + repeat + inc(int1); + inc(po^.nexttime,po^.interval) + until later(time,po^.nexttime); + end; + insert(po); + for int1:= int1 - 1 downto 0 do begin + if assigned(po^.ontimer) then begin + sys_mutexunlock(mutex); + try + po^.ontimer; + except + application.handleexception(sender); + end; + sys_mutexlock(mutex); + if timeraccesscount <> timeraccesscountbefore then begin + goto endlab; //processmessages called, + // tick leak possible for current item + end; + end; + end; + end; + po:= po2; + end; + if first <> nil then begin + starttimer(time); + end; + end; +endlab: +{$ifdef mse_debugtimer} + checktimer; +{$endif} + sys_mutexunlock(mutex); +end; + +procedure init; +begin + sys_mutexcreate(mutex); +end; + +procedure deinit; +var + po1,po2: ptimerinfoty; +begin + sys_mutexlock(mutex); + po1:= first; + while po1 <> nil do begin + po2:= po1; + po1:= po1^.nextpo; + dispose(po2); + end; + first:= nil; + sys_mutexunlock(mutex); + sys_mutexdestroy(mutex); +end; + +{ tsimpletimer } + +constructor tsimpletimer.create(const interval: longword; + const ontimer: notifyeventty; const active: boolean; + const aoptions: timeroptionsty); +begin + finterval:= interval; + fontimer:= ontimer; + foptions:= aoptions; + setenabled(active); +end; + +destructor tsimpletimer.destroy; +begin + enabled:= false; + inherited; +end; + +procedure tsimpletimer.dotimer; +begin + if (to_single in foptions) {or (finterval = 0)} then begin + fenabled:= false; + end; +// if finterval <= 0 then begin +// fenabled:= false; +// end; + if assigned(fontimer) then begin + fontimer(self); + end; +end; + +procedure tsimpletimer.setenabled(const Value: boolean); +begin + if fenabled <> value then begin + sys_mutexlock(mutex); + fenabled:= Value; + if not value then begin + if to_highres in foptions then begin + application.endhighrestimer(); + end; + killtimertick({$ifdef FPC}@{$endif}dotimer); + end + else begin + if to_highres in foptions then begin + application.beginhighrestimer(); + end; + settimertick(finterval,{$ifdef FPC}@{$endif}dotimer,foptions); + end; + sys_mutexunlock(mutex); + end; +end; + +procedure tsimpletimer.setinterval(const avalue: longword); +begin + if not (to_absolute in foptions) and (avalue > 2000000000) then begin + raise exception.create('Invalid timer interval ' + inttostr(avalue)); + end; + finterval:= avalue; + if fenabled then begin + sys_mutexlock(mutex); + killtimertick({$ifdef FPC}@{$endif}dotimer); + settimertick(finterval,{$ifdef FPC}@{$endif}dotimer,foptions); + sys_mutexunlock(mutex); + end + else begin + if foptions * [to_single,to_autostart] = [to_single,to_autostart] then begin + enabled:= true; + end; + end; +end; + +procedure tsimpletimer.firependingandstop; +begin + if fenabled then begin + enabled:= false; + dotimer; + end; +end; + +procedure tsimpletimer.fireandstop; +begin + enabled:= false; + dotimer; +end; + +procedure tsimpletimer.fire; +begin + if assigned(fontimer) then begin //do not clear fenabled + fontimer(self); + end; +end; + +procedure tsimpletimer.restart; +begin + interval:= interval; + enabled:= true; +end; + +function tsimpletimer.getsingleshot: boolean; +begin + result:= to_single in foptions; +end; + +procedure tsimpletimer.setsingleshot(const avalue: boolean); +begin + if avalue then begin + options:= options + [to_single]; + end + else begin + options:= options - [to_single]; + end; +end; + +procedure tsimpletimer.setoptions(const avalue: timeroptionsty); +var + opt1: timeroptionsty; +begin + opt1:= foptions >< avalue; + if opt1 <> [] then begin + foptions:= avalue; + if enabled then begin + if to_highres in opt1 then begin + if to_highres in avalue then begin + application.beginhighrestimer(); + end + else begin + application.endhighrestimer(); + end; + end; + end; + end; +end; + +function tsimpletimer.gethighres: boolean; +begin + result:= to_highres in foptions; +end; + +procedure tsimpletimer.sethighres(const avalue: boolean); +begin + if avalue then begin + options:= foptions + [to_highres]; + end + else begin + options:= foptions - [to_highres]; + end; +end; + +function tsimpletimer.getleak: boolean; +begin + result:= to_leak in foptions; +end; + +procedure tsimpletimer.setleak(const avalue: boolean); +begin + if avalue then begin + options:= foptions + [to_leak]; + end + else begin + options:= foptions - [to_leak]; + end; +end; + +{ ttimer } + +constructor ttimer.create(aowner: tcomponent); +begin + ftimer:= tsimpletimer.create(1000000,{$ifdef FPC}@{$endif}dotimer,false,[]); + inherited; +end; + +destructor ttimer.destroy; +begin + ftimer.Free; + inherited; +end; + +function ttimer.getenabled: boolean; +begin + if csdesigning in componentstate then begin + result:= fenabled; + end + else begin + result:= ftimer.enabled; + end; +end; + +procedure ttimer.setenabled(const avalue: boolean); +begin + if not (csdesigning in componentstate) then begin + if not application.ismainthread then begin + sys_mutexlock(mutex); + fenabled:= avalue; + if avalue and not ftimer.enabled then begin + asyncevent(enabletimertag); //win32 settimer must be in mainthread + sys_mutexunlock(mutex); + end + else begin + sys_mutexunlock(mutex); + ftimer.enabled:= avalue; + end; + end + else begin + ftimer.enabled:= avalue; + end; + end + else begin + fenabled:= avalue; + end; +end; + +procedure ttimer.doasyncevent(var atag: integer); +begin + if fenabled and (atag = enabletimertag) then begin + ftimer.enabled:= true; + end; +end; + +function ttimer.getinterval: integer; +begin + result:= ftimer.interval; +end; + +procedure ttimer.setinterval(avalue: integer); +begin + if avalue < 0 then begin + include(ftimer.foptions,to_single); + avalue:= -avalue; + end; + if not application.ismainthread and ftimer.enabled then begin + enabled:= false; + ftimer.interval:= avalue; //win32 settimer must be in main thread + enabled:= true; + end + else begin + ftimer.interval:= avalue; + end; +end; + +function ttimer.getontimer: notifyeventty; +begin + result:= ftimer.ontimer; +end; + +procedure ttimer.setontimer(const Value: notifyeventty); +begin + ftimer.ontimer:= value; +end; + +procedure ttimer.restart; +begin + interval:= ftimer.interval; + enabled:= true; +end; + +procedure ttimer.firependingandstop; +begin + ftimer.firependingandstop; +end; + +procedure ttimer.fireandstop; +begin + ftimer.fireandstop; +end; + +procedure ttimer.fire; +begin + ftimer.fire; +end; + +function ttimer.getoptions: timeroptionsty; +begin + result:= ftimer.options; +end; + +procedure ttimer.setoptions(const avalue: timeroptionsty); +begin + ftimer.options:= avalue - [to_autostart,to_absolute]; +end; + +function ttimer.getsingleshot: boolean; +begin + result:= ftimer.singleshot; +end; + +procedure ttimer.setsingleshot(const avalue: boolean); +begin + ftimer.singleshot:= avalue; +end; + +procedure ttimer.dotimer(const sender: tobject); +begin + if canevent(tmethod(fontimer)) then begin + fontimer(self); + end; +end; + +{ trepeater } + +constructor trepeater.create(const adelay: longword; const ainterval: longword; + const aontimer: notifyeventty); +begin + finterval2:= ainterval; + inherited create(adelay,aontimer,true,[]); +end; + +procedure trepeater.dotimer; +begin + if finterval <> finterval2 then begin + interval:= finterval2; + end; + inherited; +end; + +{ tanimitem } + +constructor tanimitem.create(const aowner: iobjectlink; + const atimer: tanimtimer; + const aontick: animtickeventty; + const ainterval: flo64; + const akind: animkindty = ank_single; + const aoptions: animoptionsty = [ano_enabled]; + const atickus: int32 = 0); +begin + ftickus:= atickus; + fontick:= aontick; + finterval:= ainterval; + fkind:= akind; + foptions:= aoptions; + if aowner <> nil then begin + fowner:= aowner.getinstance(); + getobjectlinker.link(iobjectlink(self),aowner); + end; + settimer(atimer); + inherited create(); + enabled:= ano_enabled in aoptions; +end; + +constructor tanimitem.create(const aowner: tmsecomponent; + const atimer: tanimtimer; + const aontick: animtickeventty; + const ainterval: flo64; + const akind: animkindty = ank_single; + const aoptions: animoptionsty = [ano_enabled]; + const atickus: int32 = 0); +var + ev1: ievent; +begin + ev1:= nil; + if aowner <> nil then begin + ev1:= ievent(aowner); + end; + create(ev1,atimer,aontick,ainterval,akind,aoptions,atickus); +end; + +destructor tanimitem.destroy(); +begin + settimer(nil); + inherited; +end; + +procedure tanimitem.reset(); +begin + ftime:= 0; + fstate:= fstate - [ans_down,ans_finished]; +end; + +procedure tanimitem.restart(); +begin + reset(); + if enabled then begin + if assigned(fonstart) then begin + fonstart(self); + end; + end + else begin + enabled:= true; + end; +end; + +procedure tanimitem.setnexttick(); +begin + fref:= timebefore; + setnexttick1; +end; + +procedure tanimitem.setnexttick1(); +begin + if ftickus = 0 then begin + fnexttick:= timebefore+ftimer.tickus; + end + else begin + fnexttick:= timebefore+ftickus; + end; +end; + +function tanimitem.getvalue: flo64; +begin + if (fkind = ank_triangle) and (ans_down in fstate) then begin + result:= 1-ftime; + end + else begin + result:= ftime; + end; +end; + +procedure tanimitem.tick(); +var + c1: card32; + b1: boolean; +begin + if (ftickus = 0) or (ftickus = ftimer.tickus) or + laterorsame(fnexttick,timebefore) then begin + c1:= timebefore-fref; +// if int32(c1) >= 0 then begin + if finterval > 0 then begin + ftime:= ftime + (c1/1000000)/finterval; //seconds + end; + b1:= false; + while ftime > 1 do begin + if fkind = ank_single then begin + b1:= true; + ftime:= 1; + break; + end; + ftime:= ftime-1; + fstate:= fstate >< [ans_down]; + end; + fref:= timebefore; + setnexttick1(); + if assigned(fontick) then begin + fontick(self,getvalue); + end; + if b1 then begin + enabled:= false; + include(fstate,ans_finished); + end; +// end +// else begin + setnexttick1; +// end; + end; +end; + +procedure tanimitem.objectevent(const sender: tobject; + const event: objecteventty); +begin + if (event = oe_destroyed) then begin + if sender = ftimer then begin + ftimer:= nil; + end; + if sender = fowner then begin + destroy(); + end; + end; +end; + +procedure tanimitem.setenabled(const avalue: boolean); +begin + if fenabled <> avalue then begin + if not avalue or not(ans_finished in fstate) then begin + fenabled:= avalue; + if ftimer <> nil then begin + ftimer.itemenabled(avalue); + end; + if not enabled then begin + if assigned(fonstop) then begin + fonstop(self); + end; + if ano_autodestroy in foptions then begin + destroy(); + end; + end + else begin + if assigned(fonstart) then begin + fonstart(self); + end; + fref:= timebefore; + fnexttick:= fref; + tick(); //immediately + end; + end; + end; +end; + +procedure tanimitem.settickus(const avalue: int32); +begin + if ftickus <> avalue then begin + ftickus:= avalue; + setnexttick(); + end; +end; + +procedure tanimitem.setkind(const avalue: animkindty); +begin + fkind:= avalue; +end; + +procedure tanimitem.setoptions(const avalue: animoptionsty); +begin + foptions:= avalue; +end; + +function tanimitem.getdown: boolean; +begin + result:= ans_down in fstate; +end; + +procedure tanimitem.setdown(const avalue: boolean); +begin + if avalue then begin + include(fstate,ans_down); + end + else begin + exclude(fstate,ans_down); + end; +end; + +procedure tanimitem.settimer(const atimer: tanimtimer); +begin + if ftimer <> atimer then begin + if ftimer <> nil then begin + ftimer.remove(self); + end; + ftimer:= atimer; + if ftimer <> nil then begin + ftimer.add(self); + end; + end; +end; + +{ tanimtimer } + +constructor tanimtimer.create(aowner: tcomponent); +begin + ftimer:= tsimpletimer.create(defaultanimtick,@dotimer,false,[to_leak]); + inherited; +end; + +destructor tanimtimer.destroy; +begin + enabled:= false; + ftimer.free; + inherited; +end; + +function tanimtimer.gettickus: int32; +begin + result:= ftimer.interval; +end; + +procedure tanimtimer.settickus(const avalue: int32); +begin + ftimer.interval:= avalue; +end; + +function tanimtimer.gethighres: boolean; +begin + result:= ftimer.highres; +end; + +procedure tanimtimer.sethighres(const avalue: boolean); +begin + ftimer.highres:= avalue; +end; + +procedure tanimtimer.setenabled(const avalue: boolean); +begin + fenabled:= avalue; + if not (csreading in componentstate) then begin + checkenabled(); + end; +end; + +procedure tanimtimer.dotimer(const sender: tobject); +var + p1,pe: panimitem; + i1: int32; +label + loopstart; +begin + i1:= 0; + while i1 < 8 do begin //emergency brake +loopstart: + if fenabledcount > 0 then begin + p1:= pointer(fitems); + pe:= p1+high(fitems); + while p1 <= pe do begin + if p1^.enabled then begin + ftouched:= false; + p1^.tick(); + if ftouched then begin + goto loopstart; + end; + end; + inc(p1); + end; + break; + end + else begin + break; + end; + inc(i1); + end; +end; + +procedure tanimtimer.add(const aitem: tanimitem); +begin + if addnewitem(pointerarty(fitems),aitem) >= 0 then begin + ftouched:= true; + aitem.getobjectlinker.link(self); + if aitem.enabled then begin + itemenabled(true); + end; + end; +end; + +procedure tanimtimer.remove(const aitem: tanimitem); +begin + if removeitem(pointerarty(fitems),aitem) >= 0 then begin + ftouched:= true; + aitem.getobjectlinker.unlink(self); + if aitem.enabled then begin + itemenabled(false); + end; + end; +end; + +procedure tanimtimer.itemenabled(const avalue: boolean); +begin + if avalue then begin + inc(fenabledcount); + checkenabled(); + end + else begin + dec(fenabledcount); + if fenabledcount <= 0 then begin + ftimer.enabled:= false; + end; + end; +end; + +procedure tanimtimer.checkenabled(); +var + p1,pe: panimitem; +begin + if fenabled and (fenabledcount > 0) then begin + if not ftimer.enabled then begin + p1:= pointer(fitems); + pe:= p1+high(fitems); + while p1 <= pe do begin + if p1^.enabled then begin + p1^.setnexttick(); + end; + inc(p1); + end; + ftimer.enabled:= true; + end; + end + else begin + ftimer.enabled:= false; + end; +end; + +procedure tanimtimer.loaded(); +begin + inherited; + checkenabled(); +end; + +{ tanimitemcomp } + +constructor tanimitemcomp.create(aowner: tcomponent); +begin + fitem:= tanimitem.create(self,nil,nil,1.0,ank_single,[],0); + inherited; +end; + +destructor tanimitemcomp.destroy(); +begin + fitem.free; + inherited; +end; + +function tanimitemcomp.getkind: animkindty; +begin + result:= fitem.kind; +end; + +procedure tanimitemcomp.setkind(const avalue: animkindty); +begin + fitem.kind:= avalue; +end; + +function tanimitemcomp.getoptions: animoptionsty; +begin + result:= fitem.options; +end; + +procedure tanimitemcomp.setoptions(const avalue: animoptionsty); +begin + fitem.options:= avalue - [ano_autodestroy]; +end; + +function tanimitemcomp.gettimer: tanimtimer; +begin + result:= fitem.timer; +end; + +procedure tanimitemcomp.settimer(const avalue: tanimtimer); +begin + fitem.timer:= avalue; +end; + +function tanimitemcomp.getenabled: boolean; +begin + result:= fenabled; +end; + +procedure tanimitemcomp.setenabled(const avalue: boolean); +begin + fenabled:= avalue; + if not (csreading in componentstate) then begin + fitem.enabled:= avalue; + end; +end; + +function tanimitemcomp.gettickus: int32; +begin + result:= fitem.tickus; +end; + +procedure tanimitemcomp.settickus(const avalue: int32); +begin + fitem.tickus:= avalue; +end; + +function tanimitemcomp.gettime: flo64; +begin + result:= fitem.time; +end; + +procedure tanimitemcomp.settime(const avalue: flo64); +begin + fitem.time:= avalue; +end; + +function tanimitemcomp.getontick: animtickeventty; +begin + result:= fitem.ontick; +end; + +procedure tanimitemcomp.setontick(const avalue: animtickeventty); +begin + fitem.ontick:= avalue; +end; + +function tanimitemcomp.getonstart: notifyeventty; +begin + result:= fitem.onstart; +end; + +procedure tanimitemcomp.setonstart(const avalue: notifyeventty); +begin + fitem.onstart:= avalue; +end; + +function tanimitemcomp.getdown: boolean; +begin + result:= fitem.down; +end; + +procedure tanimitemcomp.setdown(const avalue: boolean); +begin + fitem.down:= avalue; +end; + +function tanimitemcomp.getonstop: notifyeventty; +begin + result:= fitem.onstop; +end; + +procedure tanimitemcomp.setonstop(const avalue: notifyeventty); +begin + fitem.onstop:= avalue; +end; + +function tanimitemcomp.getinterval: flo64; +begin + result:= fitem.interval; +end; + +procedure tanimitemcomp.setinterval(const avalue: flo64); +begin + fitem.interval:= avalue; +end; + +procedure tanimitemcomp.reset(); +begin + fitem.reset; +end; + +procedure tanimitemcomp.restart(); +begin + fitem.restart(); +end; + +procedure tanimitemcomp.loaded(); +begin + inherited; + if fenabled then begin + fitem.enabled:= true; + end; +end; + +initialization +{$ifndef mswindows} + initlibc(); //clock_gettime must be inited +{$endif} + timebefore:= sys_gettimeus; +end. diff --git a/mseide-msegui/lib/common/kernel/msetmpmodules.pas b/mseide-msegui/lib/common/kernel/msetmpmodules.pas new file mode 100644 index 0000000..787013e --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msetmpmodules.pas @@ -0,0 +1,100 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msetmpmodules; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,mseclasses; + +procedure beginloadtmpmodule; +procedure endloadtmpmodule; +procedure addtmpmodule(const amodule: tmsecomponent); + +function createtmpmodule(const aclassname: string; + const aobjdata: tstream; + const onloaded: msecomponenteventty = nil): tmsecomponent; + +implementation +uses + sysutils,mseapplication; +type + tmsecomponent1 = class(tmsecomponent); + +var + ftmpmodules: tmodulelist; + +function createtmpmodule(const aclassname: string; + const aobjdata: tstream; + const onloaded: msecomponenteventty = nil): tmsecomponent; +var + class1: tpersistentclass; +begin + class1:= findclass(aclassname); + if not class1.inheritsfrom(tmsecomponent) then begin + raise exception.create('Class "'+aclassname+ + '" must inherit from tmsecomponent.'); + end; + result:= tmsecomponent(class1.newinstance); + with tmsecomponent1(result) do begin + fmsecomponentstate:= fmsecomponentstate + [cs_noload,cs_tmpmodule]; + try + beginloadtmpmodule; + try + create(nil); //destoyed by modulelist + exclude(fmsecomponentstate,cs_noload); + aobjdata.readcomponent(result); + if assigned(onloaded) then begin + onloaded(result); + end; + addtmpmodule(result); + finally + endloadtmpmodule; + end; + except + result.free; + raise; + end; + end; +end; + +function findtmpmodulebyname(const name: string): tcomponent; +begin + result:= ftmpmodules.findmodulebyname(name); +end; + +procedure beginloadtmpmodule; +begin + lockfindglobalcomponent; + ftmpmodules.unlock; + begingloballoading; +end; + +procedure endloadtmpmodule; +begin + endgloballoading; + ftmpmodules.lock; + unlockfindglobalcomponent; +end; + +procedure addtmpmodule(const amodule: tmsecomponent); +begin + ftmpmodules.add(amodule); + globalfixupreferences; + notifygloballoading; + tmsecomponent1(amodule).doafterload; +end; + +initialization + ftmpmodules:= tmodulelist.create(true); + ftmpmodules.lock; + registerfindglobalcomponentproc({$ifdef FPC}@{$endif}findtmpmodulebyname); +finalization + freeandnil(ftmpmodules); +end. diff --git a/mseide-msegui/lib/common/kernel/msetypes.pas b/mseide-msegui/lib/common/kernel/msetypes.pas new file mode 100644 index 0000000..aaea3be --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msetypes.pas @@ -0,0 +1,532 @@ +{ MSEgui Copyright (c) 1999-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msetypes; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + SysUtils; + +type +{$ifdef FPC} + {$ifndef mse_nounicodestring} + {$if defined(FPC) and (fpc_fullversion >= 020300)} + {$define mse_unicodestring} + {$ifend} + {$endif} + {$ifndef mse_unicodestring} + {$ifdef FPC_WINLIKEWIDESTRING} + {$define msestringsarenotrefcounted} + {$endif} + {$endif} +{$else} + {$ifdef mswindows} + {$define msestringsarenotrefcounted} + {$endif} +{$endif} + +{$ifdef FPC} + {$if defined(FPC) and (fpc_fullversion >= 020300)} + {$define mse_fpc_2_3_0} + {$ifend} + {$if defined(FPC) and (fpc_fullversion >= 020402)} + {$define mse_fpc_2_4_2} + {$ifend} + + {$ifdef mse_fpc_2_3_0}{$define longwordbyteset}{$endif} + + {$ifdef longwordbyteset} + byteset = byte; + wordset = word; + longwordset = longword; + {$else} + byteset = longword; + wordset = longword; + longwordset = longword; + {$endif} +{$else} + byteset = byte; + wordset = word; + longwordset = longword; +{$endif} + + //MSElang types + card8 = byte; + pcard8 = ^card8; + card8arty = array of card8; + pcard8arty = ^card8arty; + card8ararty = array of card8arty; + pcard8ararty = ^card8ararty; + card16 = word; + pcard16 = ^card16; + card16arty = array of card16; + pcard16arty = ^card16arty; + card16ararty = array of card16arty; + pcard16ararty = ^card16ararty; + card32 = longword; + pcard32 = ^card32; + card32arty = array of card32; + pcard32arty = ^card32arty; + card32ararty = array of card32arty; + pcard32ararty = ^card32ararty; + card64 = qword; + pcard64 = ^card64; + card64arty = array of card64; + pcard64arty = ^card64arty; + card64ararty = array of card64arty; + pcard64ararty = ^card64ararty; + int8 = shortint; + pint8 = ^int8; + int8arty = array of int8; + pint8arty = ^int8arty; + int8ararty = array of int8arty; + pint8ararty = ^int8ararty; + int16 = smallint; + pint16 = ^int16; + int16arty = array of int16; + pint16arty = ^int16arty; + int16ararty = array of int16arty; + pint16ararty = ^int16ararty; + int32 = integer; + pint32 = ^int32; + int32arty = array of int32; + pint32arty = ^int32arty; + int32ararty = array of int32arty; + pint32ararty = ^int32ararty; +// int64 = int64; +// pint64 = ^int64; + int64arty = array of int64; + pint64arty = ^int64arty; + int64ararty = array of int64arty; + pint64ararty = ^int64ararty; + + flo32 = single; + pflo32 = ^flo32; + flo32arty = array of flo32; + pflo32arty = ^flo32arty; + flo32ararty = array of flo32arty; + pflo32ararty = ^flo32ararty; + + flo64 = double; + pflo64 = ^flo64; + flo64arty = array of flo64; + pflo64arty = ^flo64arty; + flo64ararty = array of flo64arty; + pflo64ararty = ^flo64ararty; + + float32 = single; //todo: remove + pfloat32 = ^float32; + float32arty = array of float32; + pfloat32arty = ^float32arty; + float64 = double; + pfloat64 = ^float64; + float64arty = array of float64; + pfloat64arty = ^float64arty; + float = float64; + pfloat = ^float; + floatarty = array of float; + pfloatarty = ^floatarty; + + uint8 = byte; + puint8 = ^uint8; + uint16 = word; + puint16 = ^uint16; + uint32 = longword; + puint32 = ^uint32; + uint64 = qword; + puint64 = ^uint64; + sint8 = shortint; + psint8 = ^sint8; + sint16 = smallint; + psint16 = ^sint16; + sint32 = integer; + psint32 = ^sint32; + sint64 = int64; + psint64 = ^sint64; + + char8 = char; + pchar8 = ^char8; + char16 = unicodechar; + pchar16 = ^char16; + char32 = ucs4char; + pchar32 = ^char32; + +{$ifndef FPC} //delphi + {$ifndef mswindows} + uint64 = type int64; //kylix + {$endif} + DWord = Longword; + pdword = ^dword; + SizeInt = Longint; + psizeint = ^sizeint; + SizeUInt = DWord; + psizeuint = ^sizeuint; + plongbool = ^longbool; + ppdouble = ^pdouble; + + PtrInt = Longint; + PPtrInt = ^PtrInt; + PtrUInt = DWord; + PPtrUInt = ^PtrUInt; + ValSInt = Longint; + ValUInt = Cardinal; + qword = uint64; + pqword = ^qword; + size_t = dword; + unicodestring = widestring; + unicodechar = widechar; + WINBOOL = longbool; +{$else} + {$ifndef mse_fpc_2_4_2} + ppdouble = ^pdouble; + {$endif} +{$endif} + {$ifdef VER2_2_0} + PPtrUInt = ^PtrUInt; + {$endif} + + ppsizeint = ^psizeint; + ppppointer = ^pppointer; + preal = ^real; + realty = type double; + prealty = ^realty; + + datetimekindty = (dtk_date,dtk_time,dtk_datetime); + dayofweekty = (dw_sun,dw_mon,dw_tue,dw_wed,dw_thu,dw_fri,dw_sat); + +const + maxdatasize = $7fffffff; + {$ifdef mswindows} + pathdelim = '\'; + lineend = #$0d#$0a; + {$else} + pathdelim = '/'; + lineend = #$0a; + {$endif} + + c_dle = #$10; + c_stx = #$02; + c_etx = #$03; + c_linefeed = #$0a; + c_formfeed = #$0c; + c_return = #$0d; + c_tab = #$09; + c_backspace = #$08; + c_esc = #$1b; + c_delete = #$7f; + c_softhyphen = #$ad; + +type + {$ifdef mse_unicodestring} + msestring = unicodestring; + msechar = unicodechar; + pmsechar = punicodechar; + {$else} + msestring = widestring; + msechar = widechar; + pmsechar = pwidechar; + {$endif} + + pmsestring = ^msestring; + msestringarty = array of msestring; + pmsestringarty = ^msestringarty; + msestringaty = array[0..0] of msestring; + pmsestringaty = ^msestringaty; + msestringararty = array of msestringarty; + + widestringarty = array of widestring; +// charaty = array[0..maxdatasize-1] of char; +// pcharaty = ^charaty; + msecharaty = array[0..maxdatasize div sizeof(msechar)-1] of msechar; + pmsecharaty = ^msecharaty; + captionty = msestring; + filenamety = msestring; + pfilenamety = ^filenamety; + filenamearty = msestringarty; + filenamechar = msechar; + pfilenamechar = ^filenamechar; + +const +{$ifndef FPC} + emptyreal = -1/0; +{$else} + emptyreal = real(-1/0); + emptydouble = double(-1/0); + emptyfloat64 = float64(-1/0); +{$endif} + emptydatetime = emptyreal; + +// emptytime = 0.0; +// nulltime = 1.0; //fuer tdateeditmse +// emptydate = 0.0; + maxint64 = $7fffffffffffffff; + minint = low(integer); + bigint = maxint div 2; + nullmethod: tmethod = (code: nil; data: nil); +{$ifdef cpu64} + pointeralignmask = ptruint($ffffffffffffffff) - $7; +{$else} + pointeralignmask = ptruint($ffffffff) - $3; +{$endif} + +type + halfinteger = -bigint..bigint; + posinteger = 0..maxint; + + pobject = ^tobject; + pmethod = ^tmethod; + + booleanarty = array of boolean; + pbooleanarty = ^booleanarty; + longboolarty = array of longbool; + bytearty = array of byte; + pbytearty = ^bytearty; + wordarty = array of word; + pwordarty = ^wordarty; + smallintarty = array of smallint; + psmallintarty = ^smallintarty; + longwordarty = array of longword; + plongwordarty = ^longwordarty; + integerarty = array of integer; + pintegerarty = ^integerarty; + cardinalarty = array of cardinal; + pcardinalarty = ^cardinalarty; + pointerarty = array of pointer; + ppointerarty = ^pointerarty; + pointerararty = array of pointerarty; + objectarty = array of tobject; + pobjectarty = ^objectarty; + classarty = array of tclass; + pclassarty = ^classarty; + + realarty = array of realty; + prealarty = ^realarty; + realararty = array of realarty; + + singlearty = array of single; + singlepoarty = array of psingle; + psinglearty = ^singlearty; + singleararty = array of singlearty; + + doublearty = array of double; + doublepoarty = array of pdouble; + pdoublearty = ^doublearty; + doubleararty = array of doublearty; + + currencyarty = array of currency; + pcurrencyarty = ^currencyarty; + datetimearty = array of tdatetime; + pdatetimearty = ^datetimearty; + datetimeaty = array[0..0] of tdatetime; + pdatetimeaty = ^datetimeaty; + ptrintarty = array of ptrint; + pptrintarty = ^ptrintarty; + ptruintarty = array of ptruint; + pptruintarty = ^ptruintarty; + qwordarty = array of qword; + pqwordarty = ^qwordarty; + + pdatetime = ^tdatetime; + ppvariant = ^pvariant; + + complexty = record re,im: real; end; + pcomplexty = ^complexty; + complexarty = array of complexty; + pcomplexarty = ^complexarty; + complexararty = array of complexarty; + stringarty = array of string; + pstringarty = ^stringarty; + stringararty = array of stringarty; + pstringararty = ^stringararty; + ansistringarty = array of ansistring; + pansistringarty = ^ansistringarty; + ansistringararty = array of ansistringarty; + pansistringararty = ^ansistringararty; + + pointeraty = array[0..0] of pointer; + ppointeraty = ^pointeraty; + charpoaty = array[0..0] of pchar; + pcharpoaty = ^charpoaty; + byteaty = array[0..0] of byte; + pbyteaty = ^byteaty; + wordaty = array[0..0] of word; + pwordaty = ^wordaty; + integeraty = array[0..0] of integer; + pintegeraty = ^integeraty; + longwordaty = array[0..0] of longword; + plongwordaty = ^longwordaty; + cardinalaty = array[0..0] of cardinal; + pcardinalaty = ^cardinalaty; + longboolaty = array[0..0] of longbool; + qwordaty = array[0..0] of qword; + pqwordaty = ^qwordaty; + plongboolaty = ^longboolaty; + ptrintaty = array[0..0] of ptrint; + pptrintaty = ^ptrintaty; + ptruintaty = array[0..0] of ptruint; + pptruintaty = ^ptruintaty; + complexaty = array[0..0] of complexty; + pcomplexaty = ^complexaty; + + methodaty = array[0..0] of tmethod; + pmethodaty = ^methodaty; + stringaty = array[0..0] of string; + pstringaty = ^stringaty; + widestringaty = array[0..0] of widestring; + pwidestringaty = ^widestringaty; + ansistringaty = array[0..0] of ansistring; + pansistringaty = ^ansistringaty; + + charaty = array[0..0] of char; + pcharaty = ^charaty; + + widecharaty = array[0..0] of widechar; + pwidecharaty = ^widecharaty; + + objectaty = array[0..0] of tobject; + pobjectaty = ^objectaty; + + procty = procedure; + proceventty = procedure of object; + proceventarty = array of proceventty; + tageventtyty = procedure (const tag: integer) of object; + + integerararty = array of integerarty; + + varrecarty = array of tvarrec; + + gridcoordty = record + col,row: integer; + end; + gridcoordarty = array of gridcoordty; + + gridsizety = record + colcount,rowcount: integer; + end; + + gridrectty = record + case integer of + 0:( + col,row: integer; + colcount,rowcount: integer; + ); + 1:( + pos: gridcoordty; + size: gridsizety; + ) + end; + +// winidty = cardinal; + winidty = type ptruint; //used in published event properties + winidarty = array of winidty; + winidaty = array[0..0] of winidty; + pwinidaty = ^winidaty; + winidararty = array of winidarty; + filehandlety = longint; + + procedurety = procedure; + +const + nullcomplex: complexty = (re: 0; im: 0); + bigdatetime = 401768.99999; //2999-12-31 + +function mergevarrec(a,b: array of const): varrecarty; +function issamemethod(const method1,method2: tmethod): boolean; +function isemptydatetime(const avalue: tdatetime): boolean; + {$ifdef FPC}inline;{$endif} deprecated; + //use x = emptydatetime instead +//function emptydatetime: tdatetime; +function makecomplex(const are: real; aim: real): complexty; + {$ifdef FPC} inline; {$endif} +function mc(const are: real; aim: real): complexty; + {$ifdef FPC} inline; {$endif} +//procedure splitcomplexar(const acomplex: complexarty; out re,im: realarty); + +implementation +//uses +// msearrayutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +(* +const +{$ifdef FPC_DOUBLE_HILO_SWAPPED} + co1: array[0..7] of byte = (0,0,$f0,$ff,$0,0,0,0); //- inf +{$else} + co1: array[0..7] of byte = ($0,0,0,0,0,0,$f0,$ff); //- inf +{$endif} +*) +{ +function emptydatetime: tdatetime; +begin + result:= tdatetime(co1); +end; +} +function isemptydatetime(const avalue: tdatetime): boolean; +begin + result:= avalue = emptydatetime; +// result:= avalue = real(co1); +end; + +function mergevarrec(a,b: array of const): varrecarty; +begin + setlength(result,length(a)); + if result <> nil then begin + move(a[0],result[0],length(a)*sizeof(tvarrec)); + end; + if high(b) >= 0 then begin + setlength(result,high(result) + high(b) + 2); + move(b[0],result[length(a)],length(b)*sizeof(tvarrec)); + end; +end; + +function issamemethod(const method1,method2: tmethod): boolean; +begin + result:= (method1.Code = method2.code) and (method1.Data = method2.Data); +end; + +function makecomplex(const are: real; aim: real): complexty; +begin + result.re:= are; + result.im:= aim; +end; + +function mc(const are: real; aim: real): complexty; +begin + result.re:= are; + result.im:= aim; +end; + +end. + + + + + + + + + + diff --git a/mseide-msegui/lib/common/kernel/mseunicodeps.pas b/mseide-msegui/lib/common/kernel/mseunicodeps.pas new file mode 100644 index 0000000..48b9316 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseunicodeps.pas @@ -0,0 +1,581 @@ +unit mseunicodeps; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface + +uses + msetypes,msestrings; + +type + unicodepagety = (ucp_00,ucp_01,ucp_02,ucp_03,ucp_04,ucp_05,ucp_06, + ucp_1e, + ucp_20,ucp_21,ucp_22,ucp_23,ucp_25,ucp_26); + encodingty = record + codepage: integer; + name: string; + glyphnames: string; + end; + encodingsty = array[unicodepagety] of encodingty; + +const + nl = lineend; + encodings: encodingsty = ( + ( + codepage: $00; + name: 'E00'; //latin1 + glyphnames: +'/uni0000 /uni0001 /uni0002 /uni0003 /uni0004 /uni0005 /uni0006 /uni0007 '+nl+ //00 +'/uni0008 /uni0009 /uni000A /uni000B /uni000C /uni000D /uni000E /uni000F '+nl+ //08 +'/uni0010 /uni0011 /uni0012 /uni0013 /uni0014 /uni0015 /uni0016 /uni0017 '+nl+ //10 +'/uni0018 /uni0019 /uni001A /uni001B /uni001C /uni001D /uni001E /uni001F '+nl+ //18 +'/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle '+nl+ //20 +'/parenleft /parenright /asterisk /plus /comma /hyphen /period /slash '+nl+ //28 +'/zero /one /two /three /four /five /six /seven '+nl+ //30 +'/eight /nine /colon /semicolon /less /equal /greater /question '+nl+ //38 +'/at /A /B /C /D /E /F /G '+nl+ //40 +'/H /I /J /K /L /M /N /O '+nl+ //48 +'/P /Q /R /S /T /U /V /W '+nl+ //50 +'/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore '+nl+ //58 +'/grave /a /b /c /d /e /f /g '+nl+ //60 +'/h /i /j /k /l /m /n /o '+nl+ //68 +'/p /q /r /s /t /u /v /w '+nl+ //70 +'/x /y /z /braceleft /bar /braceright /asciitilde /uni007F '+nl+ //78 +'/uni0080 /uni0081 /uni0082 /uni0083 /uni0084 /uni0085 /uni0086 /uni0087 '+nl+ //80 +'/uni0088 /uni0089 /uni008A /uni008B /uni008C /uni008D /uni008E /uni008F '+nl+ //88 +'/uni0090 /uni0091 /uni0092 /uni0093 /uni0094 /uni0095 /uni0096 /uni0097 '+nl+ //90 +'/uni0098 /uni0099 /uni009A /uni009B /uni009C /uni009D /uni009E /uni009F '+nl+ //98 +'/uni00A0 /exclamdown /cent /sterling /currency /yen /brokenbar /section '+nl+ //A0 +'/dieresis /copyright /ordfeminine /guillemotleft /logicalnot /uni00AD /registered /macron '+nl+ //A8 +'/degree /plusminus /uni00B2 /uni00B3 /acute /uni00B5 /paragraph /periodcentered '+nl+ //B0 +'/cedilla /uni00B9 /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown '+nl+ //B8 +'/Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla '+nl+ //C0 +'/Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis '+nl+ //C8 +'/Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply '+nl+ //D0 +'/Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls '+nl+ //D8 +'/agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla '+nl+ //E0 +'/egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis '+nl+ //E8 +'/eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide '+nl+ //F0 +'/oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis '+nl //F8 + ), + ( + codepage: $01; + name: 'E01'; //latin extended A + glyphnames: +'/Amacron /amacron /Abreve /abreve /Aogonek /aogonek /Cacute /cacute '+nl+ //00 +'/Ccircumflex /ccircumflex /Cdotaccent /cdotaccent /Ccaron /ccaron /Dcaron /dcaron '+nl+ //08 +'/Dcroat /dcroat /Emacron /emacron /Ebreve /ebreve /Edotaccent /edotaccent '+nl+ //10 +'/Eogonek /eogonek /Ecaron /ecaron /Gcircumflex /gcircumflex /Gbreve /gbreve '+nl+ //18 +'/Gdotaccent /gdotaccent /Gcommaaccent /gcommaaccent /Hcircumflex /hcircumflex /Hbar /hbar '+nl+ //20 +'/Itilde /itilde /Imacron /imacron /Ibreve /ibreve /Iogonek /iogonek '+nl+ //28 +'/Idotaccent /dotlessi /IJ /ij /Jcircumflex /jcircumflex /Kcommaaccent /kcommaaccent '+nl+ //30 +'/kgreenlandic /Lacute /lacute /Lcommaaccent /lcommaaccent /Lcaron /lcaron /Ldot '+nl+ //38 +'/ldot /Lslash /lslash /Nacute /nacute /Ncommaaccent /ncommaaccent /Ncaron '+nl+ //40 +'/ncaron /napostrophe /Eng /eng /Omacron /omacron /Obreve /obreve '+nl+ //48 +'/Ohungarumlaut /ohungarumlaut /OE /oe /Racute /racute /Rcommaaccent /rcommaaccent '+nl+ //50 +'/Rcaron /rcaron /Sacute /sacute /Scircumflex /scircumflex /Scedilla /scedilla '+nl+ //58 +'/Scaron /scaron /Tcommaaccent /tcommaaccent /Tcaron /tcaron /Tbar /tbar '+nl+ //60 +'/Utilde /utilde /Umacron /umacron /Ubreve /ubreve /Uring /uring '+nl+ //68 +'/Uhungarumlaut /uhungarumlaut /Uogonek /uogonek /Wcircumflex /wcircumflex /Ycircumflex /ycircumflex '+nl+ //70 +'/Ydieresis /Zacute /zacute /Zdotaccent /zdotaccent /Zcaron /zcaron /longs '+nl+ //78 +'/uni0180 /uni0181 /uni0182 /uni0183 /uni0184 /uni0185 /uni0186 /uni0187 '+nl+ //80 +'/uni0188 /uni0189 /uni018A /uni018B /uni018C /uni018D /uni018E /uni018F '+nl+ //88 +'/uni0190 /uni0191 /florin /uni0193 /uni0194 /uni0195 /uni0196 /uni0197 '+nl+ //90 +'/uni0198 /uni0199 /uni019A /uni019B /uni019C /uni019D /uni019E /uni019F '+nl+ //98 +'/Ohorn /ohorn /uni01A2 /uni01A3 /uni01A4 /uni01A5 /uni01A6 /uni01A7 '+nl+ //A0 +'/uni01A8 /uni01A9 /uni01AA /uni01AB /uni01AC /uni01AD /uni01AE /Uhorn '+nl+ //A8 +'/uhorn /uni01B1 /uni01B2 /uni01B3 /uni01B4 /uni01B5 /uni01B6 /uni01B7 '+nl+ //B0 +'/uni01B8 /uni01B9 /uni01BA /uni01BB /uni01BC /uni01BD /uni01BE /uni01BF '+nl+ //B8 +'/uni01C0 /uni01C1 /uni01C2 /uni01C3 /uni01C4 /uni01C5 /uni01C6 /uni01C7 '+nl+ //C0 +'/uni01C8 /uni01C9 /uni01CA /uni01CB /uni01CC /uni01CD /uni01CE /uni01CF '+nl+ //C8 +'/uni01D0 /uni01D1 /uni01D2 /uni01D3 /uni01D4 /uni01D5 /uni01D6 /uni01D7 '+nl+ //D0 +'/uni01D8 /uni01D9 /uni01DA /uni01DB /uni01DC /uni01DD /uni01DE /uni01DF '+nl+ //D8 +'/uni01E0 /uni01E1 /uni01E2 /uni01E3 /uni01E4 /uni01E5 /Gcaron /gcaron '+nl+ //E0 +'/uni01E8 /uni01E9 /uni01EA /uni01EB /uni01EC /uni01ED /uni01EE /uni01EF '+nl+ //E8 +'/uni01F0 /uni01F1 /uni01F2 /uni01F3 /uni01F4 /uni01F5 /uni01F6 /uni01F7 '+nl+ //F0 +'/uni01F8 /uni01F9 /Aringacute /aringacute /AEacute /aeacute /Oslashacute /oslashacute '+nl //F8 + ), + ( + codepage: $02; + name: 'E02'; //latin extended B + glyphnames: +'/uni0200 /uni0201 /uni0202 /uni0203 /uni0204 /uni0205 /uni0206 /uni0207 '+nl+ //00 +'/uni0208 /uni0209 /uni020A /uni020B /uni020C /uni020D /uni020E /uni020F '+nl+ //08 +'/uni0210 /uni0211 /uni0212 /uni0213 /uni0214 /uni0215 /uni0216 /uni0217 '+nl+ //10 +'/Scommaaccent /scommaaccent /uni021A /uni021B /uni021C /uni021D /uni021E /uni021F '+nl+ //18 +'/uni0220 /uni0221 /uni0222 /uni0223 /uni0224 /uni0225 /uni0226 /uni0227 '+nl+ //20 +'/uni0228 /uni0229 /uni022A /uni022B /uni022C /uni022D /uni022E /uni022F '+nl+ //28 +'/uni0230 /uni0231 /uni0232 /uni0233 /uni0234 /uni0235 /uni0236 /uni0237 '+nl+ //30 +'/uni0238 /uni0239 /uni023A /uni023B /uni023C /uni023D /uni023E /uni023F '+nl+ //38 +'/uni0240 /uni0241 /uni0242 /uni0243 /uni0244 /uni0245 /uni0246 /uni0247 '+nl+ //40 +'/uni0248 /uni0249 /uni024A /uni024B /uni024C /uni024D /uni024E /uni024F '+nl+ //48 +'/uni0250 /uni0251 /uni0252 /uni0253 /uni0254 /uni0255 /uni0256 /uni0257 '+nl+ //50 +'/uni0258 /uni0259 /uni025A /uni025B /uni025C /uni025D /uni025E /uni025F '+nl+ //58 +'/uni0260 /uni0261 /uni0262 /uni0263 /uni0264 /uni0265 /uni0266 /uni0267 '+nl+ //60 +'/uni0268 /uni0269 /uni026A /uni026B /uni026C /uni026D /uni026E /uni026F '+nl+ //68 +'/uni0270 /uni0271 /uni0272 /uni0273 /uni0274 /uni0275 /uni0276 /uni0277 '+nl+ //70 +'/uni0278 /uni0279 /uni027A /uni027B /uni027C /uni027D /uni027E /uni027F '+nl+ //78 +'/uni0280 /uni0281 /uni0282 /uni0283 /uni0284 /uni0285 /uni0286 /uni0287 '+nl+ //80 +'/uni0288 /uni0289 /uni028A /uni028B /uni028C /uni028D /uni028E /uni028F '+nl+ //88 +'/uni0290 /uni0291 /uni0292 /uni0293 /uni0294 /uni0295 /uni0296 /uni0297 '+nl+ //90 +'/uni0298 /uni0299 /uni029A /uni029B /uni029C /uni029D /uni029E /uni029F '+nl+ //98 +'/uni02A0 /uni02A1 /uni02A2 /uni02A3 /uni02A4 /uni02A5 /uni02A6 /uni02A7 '+nl+ //A0 +'/uni02A8 /uni02A9 /uni02AA /uni02AB /uni02AC /uni02AD /uni02AE /uni02AF '+nl+ //A8 +'/uni02B0 /uni02B1 /uni02B2 /uni02B3 /uni02B4 /uni02B5 /uni02B6 /uni02B7 '+nl+ //B0 +'/uni02B8 /uni02B9 /uni02BA /uni02BB /afii57929 /afii64937 /uni02BE /uni02BF '+nl+ //B8 +'/uni02C0 /uni02C1 /uni02C2 /uni02C3 /uni02C4 /uni02C5 /circumflex /caron '+nl+ //C0 +'/uni02C8 /uni02C9 /uni02CA /uni02CB /uni02CC /uni02CD /uni02CE /uni02CF '+nl+ //C8 +'/uni02D0 /uni02D1 /uni02D2 /uni02D3 /uni02D4 /uni02D5 /uni02D6 /uni02D7 '+nl+ //D0 +'/breve /dotaccent /ring /ogonek /tilde /hungarumlaut /uni02DE /uni02DF '+nl+ //D8 +'/uni02E0 /uni02E1 /uni02E2 /uni02E3 /uni02E4 /uni02E5 /uni02E6 /uni02E7 '+nl+ //E0 +'/uni02E8 /uni02E9 /uni02EA /uni02EB /uni02EC /uni02ED /uni02EE /uni02EF '+nl+ //E8 +'/uni02F0 /uni02F1 /uni02F2 /uni02F3 /uni02F4 /uni02F5 /uni02F6 /uni02F7 '+nl+ //F0 +'/uni02F8 /uni02F9 /uni02FA /uni02FB /uni02FC /uni02FD /uni02FE /uni02FF '+nl //F8 + ), + ( + codepage: $03; + name: 'E03'; //greek + glyphnames: +'/gravecomb /acutecomb /uni0302 /tildecomb /uni0304 /uni0305 /uni0306 /uni0307 '+nl+ //00 +'/uni0308 /hookabovecomb /uni030A /uni030B /uni030C /uni030D /uni030E /uni030F '+nl+ //08 +'/uni0310 /uni0311 /uni0312 /uni0313 /uni0314 /uni0315 /uni0316 /uni0317 '+nl+ //10 +'/uni0318 /uni0319 /uni031A /uni031B /uni031C /uni031D /uni031E /uni031F '+nl+ //18 +'/uni0320 /uni0321 /uni0322 /dotbelowcomb /uni0324 /uni0325 /uni0326 /uni0327 '+nl+ //20 +'/uni0328 /uni0329 /uni032A /uni032B /uni032C /uni032D /uni032E /uni032F '+nl+ //28 +'/uni0330 /uni0331 /uni0332 /uni0333 /uni0334 /uni0335 /uni0336 /uni0337 '+nl+ //30 +'/uni0338 /uni0339 /uni033A /uni033B /uni033C /uni033D /uni033E /uni033F '+nl+ //38 +'/uni0340 /uni0341 /uni0342 /uni0343 /uni0344 /uni0345 /uni0346 /uni0347 '+nl+ //40 +'/uni0348 /uni0349 /uni034A /uni034B /uni034C /uni034D /uni034E /uni034F '+nl+ //48 +'/uni0350 /uni0351 /uni0352 /uni0353 /uni0354 /uni0355 /uni0356 /uni0357 '+nl+ //50 +'/uni0358 /uni0359 /uni035A /uni035B /uni035C /uni035D /uni035E /uni035F '+nl+ //58 +'/uni0360 /uni0361 /uni0362 /uni0363 /uni0364 /uni0365 /uni0366 /uni0367 '+nl+ //60 +'/uni0368 /uni0369 /uni036A /uni036B /uni036C /uni036D /uni036E /uni036F '+nl+ //68 +'/uni0370 /uni0371 /uni0372 /uni0373 /uni0374 /uni0375 /uni0376 /uni0377 '+nl+ //70 +'/uni0378 /uni0379 /uni037A /uni037B /uni037C /uni037D /uni037E /uni037F '+nl+ //78 +'/uni0380 /uni0381 /uni0382 /uni0383 /tonos /dieresistonos /Alphatonos /anoteleia '+nl+ //80 +'/Epsilontonos /Etatonos /Iotatonos /uni038B /Omicrontonos /uni038D /Upsilontonos /Omegatonos '+nl+ //88 +'/iotadieresistonos /Alpha /Beta /Gamma /Delta /Epsilon /Zeta /Eta '+nl+ //90 +'/Theta /Iota /Kappa /Lambda /Mu /Nu /Xi /Omicron '+nl+ //98 +'/Pi /Rho /uni03A2 /Sigma /Tau /Upsilon /Phi /Chi '+nl+ //A0 +'/Psi /Omega /Iotadieresis /Upsilondieresis /alphatonos /epsilontonos /etatonos /iotatonos '+nl+ //A8 +'/upsilondieresistonos /alpha /beta /gamma /delta /epsilon /zeta /eta '+nl+ //B0 +'/theta /iota /kappa /lambda /mu /nu /xi /omicron '+nl+ //B8 +'/pi /rho /sigma1 /sigma /tau /upsilon /phi /chi '+nl+ //C0 +'/psi /omega /iotadieresis /upsilondieresis /omicrontonos /upsilontonos /omegatonos /uni03CF '+nl+ //C8 +'/uni03D0 /theta1 /Upsilon1 /uni03D3 /uni03D4 /phi1 /omega1 /uni03D7 '+nl+ //D0 +'/uni03D8 /uni03D9 /uni03DA /uni03DB /uni03DC /uni03DD /uni03DE /uni03DF '+nl+ //D8 +'/uni03E0 /uni03E1 /uni03E2 /uni03E3 /uni03E4 /uni03E5 /uni03E6 /uni03E7 '+nl+ //E0 +'/uni03E8 /uni03E9 /uni03EA /uni03EB /uni03EC /uni03ED /uni03EE /uni03EF '+nl+ //E8 +'/uni03F0 /uni03F1 /uni03F2 /uni03F3 /uni03F4 /uni03F5 /uni03F6 /uni03F7 '+nl+ //F0 +'/uni03F8 /uni03F9 /uni03FA /uni03FB /uni03FC /uni03FD /uni03FE /uni03FF '+nl //F8 + ), + ( + codepage: $04; + name: 'E04'; //cyrillic + glyphnames: +'/uni0400 /afii10023 /afii10051 /afii10052 /afii10053 /afii10054 /afii10055 /afii10056 '+nl+ //00 +'/afii10057 /afii10058 /afii10059 /afii10060 /afii10061 /uni040D /afii10062 /afii10145 '+nl+ //08 +'/afii10017 /afii10018 /afii10019 /afii10020 /afii10021 /afii10022 /afii10024 /afii10025 '+nl+ //10 +'/afii10026 /afii10027 /afii10028 /afii10029 /afii10030 /afii10031 /afii10032 /afii10033 '+nl+ //18 +'/afii10034 /afii10035 /afii10036 /afii10037 /afii10038 /afii10039 /afii10040 /afii10041 '+nl+ //20 +'/afii10042 /afii10043 /afii10044 /afii10045 /afii10046 /afii10047 /afii10048 /afii10049 '+nl+ //28 +'/afii10065 /afii10066 /afii10067 /afii10068 /afii10069 /afii10070 /afii10072 /afii10073 '+nl+ //30 +'/afii10074 /afii10075 /afii10076 /afii10077 /afii10078 /afii10079 /afii10080 /afii10081 '+nl+ //38 +'/afii10082 /afii10083 /afii10084 /afii10085 /afii10086 /afii10087 /afii10088 /afii10089 '+nl+ //40 +'/afii10090 /afii10091 /afii10092 /afii10093 /afii10094 /afii10095 /afii10096 /afii10097 '+nl+ //48 +'/uni0450 /afii10071 /afii10099 /afii10100 /afii10101 /afii10102 /afii10103 /afii10104 '+nl+ //50 +'/afii10105 /afii10106 /afii10107 /afii10108 /afii10109 /uni045D /afii10110 /afii10193 '+nl+ //58 +'/uni0460 /uni0461 /afii10146 /afii10194 /uni0464 /uni0465 /uni0466 /uni0467 '+nl+ //60 +'/uni0468 /uni0469 /uni046A /uni046B /uni046C /uni046D /uni046E /uni046F '+nl+ //68 +'/uni0470 /uni0471 /afii10147 /afii10195 /afii10148 /afii10196 /uni0476 /uni0477 '+nl+ //70 +'/uni0478 /uni0479 /uni047A /uni047B /uni047C /uni047D /uni047E /uni047F '+nl+ //78 +'/uni0480 /uni0481 /uni0482 /uni0483 /uni0484 /uni0485 /uni0486 /uni0487 '+nl+ //80 +'/uni0488 /uni0489 /uni048A /uni048B /uni048C /uni048D /uni048E /uni048F '+nl+ //88 +'/afii10050 /afii10098 /uni0492 /uni0493 /uni0494 /uni0495 /uni0496 /uni0497 '+nl+ //90 +'/uni0498 /uni0499 /uni049A /uni049B /uni049C /uni049D /uni049E /uni049F '+nl+ //98 +'/uni04A0 /uni04A1 /uni04A2 /uni04A3 /uni04A4 /uni04A5 /uni04A6 /uni04A7 '+nl+ //A0 +'/uni04A8 /uni04A9 /uni04AA /uni04AB /uni04AC /uni04AD /uni04AE /uni04AF '+nl+ //A8 +'/uni04B0 /uni04B1 /uni04B2 /uni04B3 /uni04B4 /uni04B5 /uni04B6 /uni04B7 '+nl+ //B0 +'/uni04B8 /uni04B9 /uni04BA /uni04BB /uni04BC /uni04BD /uni04BE /uni04BF '+nl+ //B8 +'/uni04C0 /uni04C1 /uni04C2 /uni04C3 /uni04C4 /uni04C5 /uni04C6 /uni04C7 '+nl+ //C0 +'/uni04C8 /uni04C9 /uni04CA /uni04CB /uni04CC /uni04CD /uni04CE /uni04CF '+nl+ //C8 +'/uni04D0 /uni04D1 /uni04D2 /uni04D3 /uni04D4 /uni04D5 /uni04D6 /uni04D7 '+nl+ //D0 +'/uni04D8 /afii10846 /uni04DA /uni04DB /uni04DC /uni04DD /uni04DE /uni04DF '+nl+ //D8 +'/uni04E0 /uni04E1 /uni04E2 /uni04E3 /uni04E4 /uni04E5 /uni04E6 /uni04E7 '+nl+ //E0 +'/uni04E8 /uni04E9 /uni04EA /uni04EB /uni04EC /uni04ED /uni04EE /uni04EF '+nl+ //E8 +'/uni04F0 /uni04F1 /uni04F2 /uni04F3 /uni04F4 /uni04F5 /uni04F6 /uni04F7 '+nl+ //F0 +'/uni04F8 /uni04F9 /uni04FA /uni04FB /uni04FC /uni04FD /uni04FE /uni04FF '+nl //F8 + ), + ( + codepage: $05; + name: 'E05'; //cyrillic supplement + glyphnames: +'/uni0500 /uni0501 /uni0502 /uni0503 /uni0504 /uni0505 /uni0506 /uni0507 '+nl+ //00 +'/uni0508 /uni0509 /uni050A /uni050B /uni050C /uni050D /uni050E /uni050F '+nl+ //08 +'/uni0510 /uni0511 /uni0512 /uni0513 /uni0514 /uni0515 /uni0516 /uni0517 '+nl+ //10 +'/uni0518 /uni0519 /uni051A /uni051B /uni051C /uni051D /uni051E /uni051F '+nl+ //18 +'/uni0520 /uni0521 /uni0522 /uni0523 /uni0524 /uni0525 /uni0526 /uni0527 '+nl+ //20 +'/uni0528 /uni0529 /uni052A /uni052B /uni052C /uni052D /uni052E /uni052F '+nl+ //28 +'/uni0530 /uni0531 /uni0532 /uni0533 /uni0534 /uni0535 /uni0536 /uni0537 '+nl+ //30 +'/uni0538 /uni0539 /uni053A /uni053B /uni053C /uni053D /uni053E /uni053F '+nl+ //38 +'/uni0540 /uni0541 /uni0542 /uni0543 /uni0544 /uni0545 /uni0546 /uni0547 '+nl+ //40 +'/uni0548 /uni0549 /uni054A /uni054B /uni054C /uni054D /uni054E /uni054F '+nl+ //48 +'/uni0550 /uni0551 /uni0552 /uni0553 /uni0554 /uni0555 /uni0556 /uni0557 '+nl+ //50 +'/uni0558 /uni0559 /uni055A /uni055B /uni055C /uni055D /uni055E /uni055F '+nl+ //58 +'/uni0560 /uni0561 /uni0562 /uni0563 /uni0564 /uni0565 /uni0566 /uni0567 '+nl+ //60 +'/uni0568 /uni0569 /uni056A /uni056B /uni056C /uni056D /uni056E /uni056F '+nl+ //68 +'/uni0570 /uni0571 /uni0572 /uni0573 /uni0574 /uni0575 /uni0576 /uni0577 '+nl+ //70 +'/uni0578 /uni0579 /uni057A /uni057B /uni057C /uni057D /uni057E /uni057F '+nl+ //78 +'/uni0580 /uni0581 /uni0582 /uni0583 /uni0584 /uni0585 /uni0586 /uni0587 '+nl+ //80 +'/uni0588 /uni0589 /uni058A /uni058B /uni058C /uni058D /uni058E /uni058F '+nl+ //88 +'/uni0590 /uni0591 /uni0592 /uni0593 /uni0594 /uni0595 /uni0596 /uni0597 '+nl+ //90 +'/uni0598 /uni0599 /uni059A /uni059B /uni059C /uni059D /uni059E /uni059F '+nl+ //98 +'/uni05A0 /uni05A1 /uni05A2 /uni05A3 /uni05A4 /uni05A5 /uni05A6 /uni05A7 '+nl+ //A0 +'/uni05A8 /uni05A9 /uni05AA /uni05AB /uni05AC /uni05AD /uni05AE /uni05AF '+nl+ //A8 +'/afii57799 /afii57801 /afii57800 /afii57802 /afii57793 /afii57794 /afii57795 /afii57798 '+nl+ //B0 +'/afii57797 /afii57806 /uni05BA /afii57796 /afii57807 /afii57839 /afii57645 /afii57841 '+nl+ //B8 +'/afii57842 /afii57804 /afii57803 /afii57658 /uni05C4 /uni05C5 /uni05C6 /uni05C7 '+nl+ //C0 +'/uni05C8 /uni05C9 /uni05CA /uni05CB /uni05CC /uni05CD /uni05CE /uni05CF '+nl+ //C8 +'/afii57664 /afii57665 /afii57666 /afii57667 /afii57668 /afii57669 /afii57670 /afii57671 '+nl+ //D0 +'/afii57672 /afii57673 /afii57674 /afii57675 /afii57676 /afii57677 /afii57678 /afii57679 '+nl+ //D8 +'/afii57680 /afii57681 /afii57682 /afii57683 /afii57684 /afii57685 /afii57686 /afii57687 '+nl+ //E0 +'/afii57688 /afii57689 /afii57690 /uni05EB /uni05EC /uni05ED /uni05EE /uni05EF '+nl+ //E8 +'/afii57716 /afii57717 /afii57718 /uni05F3 /uni05F4 /uni05F5 /uni05F6 /uni05F7 '+nl+ //F0 +'/uni05F8 /uni05F9 /uni05FA /uni05FB /uni05FC /uni05FD /uni05FE /uni05FF '+nl //F8 + ), + ( + codepage: $06; + name: 'E06'; //arabic + glyphnames: +'/uni0600 /uni0601 /uni0602 /uni0603 /uni0604 /uni0605 /uni0606 /uni0607 '+nl+ //00 +'/uni0608 /uni0609 /uni060A /uni060B /afii57388 /uni060D /uni060E /uni060F '+nl+ //08 +'/uni0610 /uni0611 /uni0612 /uni0613 /uni0614 /uni0615 /uni0616 /uni0617 '+nl+ //10 +'/uni0618 /uni0619 /uni061A /afii57403 /uni061C /uni061D /uni061E /afii57407 '+nl+ //18 +'/uni0620 /afii57409 /afii57410 /afii57411 /afii57412 /afii57413 /afii57414 /afii57415 '+nl+ //20 +'/afii57416 /afii57417 /afii57418 /afii57419 /afii57420 /afii57421 /afii57422 /afii57423 '+nl+ //28 +'/afii57424 /afii57425 /afii57426 /afii57427 /afii57428 /afii57429 /afii57430 /afii57431 '+nl+ //30 +'/afii57432 /afii57433 /afii57434 /uni063B /uni063C /uni063D /uni063E /uni063F '+nl+ //38 +'/afii57440 /afii57441 /afii57442 /afii57443 /afii57444 /afii57445 /afii57446 /afii57470 '+nl+ //40 +'/afii57448 /afii57449 /afii57450 /afii57451 /afii57452 /afii57453 /afii57454 /afii57455 '+nl+ //48 +'/afii57456 /afii57457 /afii57458 /uni0653 /uni0654 /uni0655 /uni0656 /uni0657 '+nl+ //50 +'/uni0658 /uni0659 /uni065A /uni065B /uni065C /uni065D /uni065E /uni065F '+nl+ //58 +'/afii57392 /afii57393 /afii57394 /afii57395 /afii57396 /afii57397 /afii57398 /afii57399 '+nl+ //60 +'/afii57400 /afii57401 /afii57381 /uni066B /uni066C /afii63167 /uni066E /uni066F '+nl+ //68 +'/uni0670 /uni0671 /uni0672 /uni0673 /uni0674 /uni0675 /uni0676 /uni0677 '+nl+ //70 +'/uni0678 /afii57511 /uni067A /uni067B /uni067C /uni067D /afii57506 /uni067F '+nl+ //78 +'/uni0680 /uni0681 /uni0682 /uni0683 /uni0684 /uni0685 /afii57507 /uni0687 '+nl+ //80 +'/afii57512 /uni0689 /uni068A /uni068B /uni068C /uni068D /uni068E /uni068F '+nl+ //88 +'/uni0690 /afii57513 /uni0692 /uni0693 /uni0694 /uni0695 /uni0696 /uni0697 '+nl+ //90 +'/afii57508 /uni0699 /uni069A /uni069B /uni069C /uni069D /uni069E /uni069F '+nl+ //98 +'/uni06A0 /uni06A1 /uni06A2 /uni06A3 /afii57505 /uni06A5 /uni06A6 /uni06A7 '+nl+ //A0 +'/uni06A8 /uni06A9 /uni06AA /uni06AB /uni06AC /uni06AD /uni06AE /afii57509 '+nl+ //A8 +'/uni06B0 /uni06B1 /uni06B2 /uni06B3 /uni06B4 /uni06B5 /uni06B6 /uni06B7 '+nl+ //B0 +'/uni06B8 /uni06B9 /afii57514 /uni06BB /uni06BC /uni06BD /uni06BE /uni06BF '+nl+ //B8 +'/uni06C0 /uni06C1 /uni06C2 /uni06C3 /uni06C4 /uni06C5 /uni06C6 /uni06C7 '+nl+ //C0 +'/uni06C8 /uni06C9 /uni06CA /uni06CB /uni06CC /uni06CD /uni06CE /uni06CF '+nl+ //C8 +'/uni06D0 /uni06D1 /afii57519 /uni06D3 /uni06D4 /afii57534 /uni06D6 /uni06D7 '+nl+ //D0 +'/uni06D8 /uni06D9 /uni06DA /uni06DB /uni06DC /uni06DD /uni06DE /uni06DF '+nl+ //D8 +'/uni06E0 /uni06E1 /uni06E2 /uni06E3 /uni06E4 /uni06E5 /uni06E6 /uni06E7 '+nl+ //E0 +'/uni06E8 /uni06E9 /uni06EA /uni06EB /uni06EC /uni06ED /uni06EE /uni06EF '+nl+ //E8 +'/uni06F0 /uni06F1 /uni06F2 /uni06F3 /uni06F4 /uni06F5 /uni06F6 /uni06F7 '+nl+ //F0 +'/uni06F8 /uni06F9 /uni06FA /uni06FB /uni06FC /uni06FD /uni06FE /uni06FF '+nl //F8 + ), + ( + codepage: $1E; + name: 'E1E'; //latin extended additional + glyphnames: +'/uni1E00 /uni1E01 /uni1E02 /uni1E03 /uni1E04 /uni1E05 /uni1E06 /uni1E07 '+nl+ //00 +'/uni1E08 /uni1E09 /uni1E0A /uni1E0B /uni1E0C /uni1E0D /uni1E0E /uni1E0F '+nl+ //08 +'/uni1E10 /uni1E11 /uni1E12 /uni1E13 /uni1E14 /uni1E15 /uni1E16 /uni1E17 '+nl+ //10 +'/uni1E18 /uni1E19 /uni1E1A /uni1E1B /uni1E1C /uni1E1D /uni1E1E /uni1E1F '+nl+ //18 +'/uni1E20 /uni1E21 /uni1E22 /uni1E23 /uni1E24 /uni1E25 /uni1E26 /uni1E27 '+nl+ //20 +'/uni1E28 /uni1E29 /uni1E2A /uni1E2B /uni1E2C /uni1E2D /uni1E2E /uni1E2F '+nl+ //28 +'/uni1E30 /uni1E31 /uni1E32 /uni1E33 /uni1E34 /uni1E35 /uni1E36 /uni1E37 '+nl+ //30 +'/uni1E38 /uni1E39 /uni1E3A /uni1E3B /uni1E3C /uni1E3D /uni1E3E /uni1E3F '+nl+ //38 +'/uni1E40 /uni1E41 /uni1E42 /uni1E43 /uni1E44 /uni1E45 /uni1E46 /uni1E47 '+nl+ //40 +'/uni1E48 /uni1E49 /uni1E4A /uni1E4B /uni1E4C /uni1E4D /uni1E4E /uni1E4F '+nl+ //48 +'/uni1E50 /uni1E51 /uni1E52 /uni1E53 /uni1E54 /uni1E55 /uni1E56 /uni1E57 '+nl+ //50 +'/uni1E58 /uni1E59 /uni1E5A /uni1E5B /uni1E5C /uni1E5D /uni1E5E /uni1E5F '+nl+ //58 +'/uni1E60 /uni1E61 /uni1E62 /uni1E63 /uni1E64 /uni1E65 /uni1E66 /uni1E67 '+nl+ //60 +'/uni1E68 /uni1E69 /uni1E6A /uni1E6B /uni1E6C /uni1E6D /uni1E6E /uni1E6F '+nl+ //68 +'/uni1E70 /uni1E71 /uni1E72 /uni1E73 /uni1E74 /uni1E75 /uni1E76 /uni1E77 '+nl+ //70 +'/uni1E78 /uni1E79 /uni1E7A /uni1E7B /uni1E7C /uni1E7D /uni1E7E /uni1E7F '+nl+ //78 +'/Wgrave /wgrave /Wacute /wacute /Wdieresis /wdieresis /uni1E86 /uni1E87 '+nl+ //80 +'/uni1E88 /uni1E89 /uni1E8A /uni1E8B /uni1E8C /uni1E8D /uni1E8E /uni1E8F '+nl+ //88 +'/uni1E90 /uni1E91 /uni1E92 /uni1E93 /uni1E94 /uni1E95 /uni1E96 /uni1E97 '+nl+ //90 +'/uni1E98 /uni1E99 /uni1E9A /uni1E9B /uni1E9C /uni1E9D /uni1E9E /uni1E9F '+nl+ //98 +'/uni1EA0 /uni1EA1 /uni1EA2 /uni1EA3 /uni1EA4 /uni1EA5 /uni1EA6 /uni1EA7 '+nl+ //A0 +'/uni1EA8 /uni1EA9 /uni1EAA /uni1EAB /uni1EAC /uni1EAD /uni1EAE /uni1EAF '+nl+ //A8 +'/uni1EB0 /uni1EB1 /uni1EB2 /uni1EB3 /uni1EB4 /uni1EB5 /uni1EB6 /uni1EB7 '+nl+ //B0 +'/uni1EB8 /uni1EB9 /uni1EBA /uni1EBB /uni1EBC /uni1EBD /uni1EBE /uni1EBF '+nl+ //B8 +'/uni1EC0 /uni1EC1 /uni1EC2 /uni1EC3 /uni1EC4 /uni1EC5 /uni1EC6 /uni1EC7 '+nl+ //C0 +'/uni1EC8 /uni1EC9 /uni1ECA /uni1ECB /uni1ECC /uni1ECD /uni1ECE /uni1ECF '+nl+ //C8 +'/uni1ED0 /uni1ED1 /uni1ED2 /uni1ED3 /uni1ED4 /uni1ED5 /uni1ED6 /uni1ED7 '+nl+ //D0 +'/uni1ED8 /uni1ED9 /uni1EDA /uni1EDB /uni1EDC /uni1EDD /uni1EDE /uni1EDF '+nl+ //D8 +'/uni1EE0 /uni1EE1 /uni1EE2 /uni1EE3 /uni1EE4 /uni1EE5 /uni1EE6 /uni1EE7 '+nl+ //E0 +'/uni1EE8 /uni1EE9 /uni1EEA /uni1EEB /uni1EEC /uni1EED /uni1EEE /uni1EEF '+nl+ //E8 +'/uni1EF0 /uni1EF1 /Ygrave /ygrave /uni1EF4 /uni1EF5 /uni1EF6 /uni1EF7 '+nl+ //F0 +'/uni1EF8 /uni1EF9 /uni1EFA /uni1EFB /uni1EFC /uni1EFD /uni1EFE /uni1EFF '+nl //F8 + ), + ( + codepage: $20; + name: 'E20'; //punctuation, currency + glyphnames: +'/uni2000 /uni2001 /uni2002 /uni2003 /uni2004 /uni2005 /uni2006 /uni2007 '+nl+ //00 +'/uni2008 /uni2009 /uni200A /uni200B /afii61664 /afii301 /afii299 /afii300 '+nl+ //08 +'/uni2010 /uni2011 /figuredash /endash /emdash /afii00208 /uni2016 /underscoredbl '+nl+ //10 +'/quoteleft /quoteright /quotesinglbase /quotereversed /quotedblleft /quotedblright /quotedblbase /uni201F '+nl+ //18 +'/dagger /daggerdbl /bullet /uni2023 /onedotenleader /twodotenleader /ellipsis /uni2027 '+nl+ //20 +'/uni2028 /uni2029 /uni202A /uni202B /afii61573 /afii61574 /afii61575 /uni202F '+nl+ //28 +'/perthousand /uni2031 /minute /second /uni2034 /uni2035 /uni2036 /uni2037 '+nl+ //30 +'/uni2038 /guilsinglleft /guilsinglright /uni203B /exclamdbl /uni203D /uni203E /uni203F '+nl+ //38 +'/uni2040 /uni2041 /uni2042 /uni2043 /fraction /uni2045 /uni2046 /uni2047 '+nl+ //40 +'/uni2048 /uni2049 /uni204A /uni204B /uni204C /uni204D /uni204E /uni204F '+nl+ //48 +'/uni2050 /uni2051 /uni2052 /uni2053 /uni2054 /uni2055 /uni2056 /uni2057 '+nl+ //50 +'/uni2058 /uni2059 /uni205A /uni205B /uni205C /uni205D /uni205E /uni205F '+nl+ //58 +'/uni2060 /uni2061 /uni2062 /uni2063 /uni2064 /uni2065 /uni2066 /uni2067 '+nl+ //60 +'/uni2068 /uni2069 /uni206A /uni206B /uni206C /uni206D /uni206E /uni206F '+nl+ //68 +'/uni2070 /uni2071 /uni2072 /uni2073 /uni2074 /uni2075 /uni2076 /uni2077 '+nl+ //70 +'/uni2078 /uni2079 /uni207A /uni207B /uni207C /uni207D /uni207E /uni207F '+nl+ //78 +'/uni2080 /uni2081 /uni2082 /uni2083 /uni2084 /uni2085 /uni2086 /uni2087 '+nl+ //80 +'/uni2088 /uni2089 /uni208A /uni208B /uni208C /uni208D /uni208E /uni208F '+nl+ //88 +'/uni2090 /uni2091 /uni2092 /uni2093 /uni2094 /uni2095 /uni2096 /uni2097 '+nl+ //90 +'/uni2098 /uni2099 /uni209A /uni209B /uni209C /uni209D /uni209E /uni209F '+nl+ //98 +'/uni20A0 /colonmonetary /uni20A2 /franc /lira /uni20A5 /uni20A6 /peseta '+nl+ //A0 +'/uni20A8 /uni20A9 /afii57636 /dong /Euro /uni20AD /uni20AE /uni20AF '+nl+ //A8 +'/uni20B0 /uni20B1 /uni20B2 /uni20B3 /uni20B4 /uni20B5 /uni20B6 /uni20B7 '+nl+ //B0 +'/uni20B8 /uni20B9 /uni20BA /uni20BB /uni20BC /uni20BD /uni20BE /uni20BF '+nl+ //B8 +'/uni20C0 /uni20C1 /uni20C2 /uni20C3 /uni20C4 /uni20C5 /uni20C6 /uni20C7 '+nl+ //C0 +'/uni20C8 /uni20C9 /uni20CA /uni20CB /uni20CC /uni20CD /uni20CE /uni20CF '+nl+ //C8 +'/uni20D0 /uni20D1 /uni20D2 /uni20D3 /uni20D4 /uni20D5 /uni20D6 /uni20D7 '+nl+ //D0 +'/uni20D8 /uni20D9 /uni20DA /uni20DB /uni20DC /uni20DD /uni20DE /uni20DF '+nl+ //D8 +'/uni20E0 /uni20E1 /uni20E2 /uni20E3 /uni20E4 /uni20E5 /uni20E6 /uni20E7 '+nl+ //E0 +'/uni20E8 /uni20E9 /uni20EA /uni20EB /uni20EC /uni20ED /uni20EE /uni20EF '+nl+ //E8 +'/uni20F0 /uni20F1 /uni20F2 /uni20F3 /uni20F4 /uni20F5 /uni20F6 /uni20F7 '+nl+ //F0 +'/uni20F8 /uni20F9 /uni20FA /uni20FB /uni20FC /uni20FD /uni20FE /uni20FF '+nl //F8 + ), + ( + codepage: $21; + name: 'E21'; //letterlike symbols + glyphnames: +'/uni2100 /uni2101 /uni2102 /uni2103 /uni2104 /afii61248 /uni2106 /uni2107 '+nl+ //00 +'/uni2108 /uni2109 /uni210A /uni210B /uni210C /uni210D /uni210E /uni210F '+nl+ //08 +'/uni2110 /Ifraktur /uni2112 /afii61289 /uni2114 /uni2115 /afii61352 /uni2117 '+nl+ //10 +'/weierstrass /uni2119 /uni211A /uni211B /Rfraktur /uni211D /prescription /uni211F '+nl+ //18 +'/uni2120 /uni2121 /trademark /uni2123 /uni2124 /uni2125 /uni2126 /uni2127 '+nl+ //20 +'/uni2128 /uni2129 /uni212A /uni212B /uni212C /uni212D /estimated /uni212F '+nl+ //28 +'/uni2130 /uni2131 /uni2132 /uni2133 /uni2134 /aleph /uni2136 /uni2137 '+nl+ //30 +'/uni2138 /uni2139 /uni213A /uni213B /uni213C /uni213D /uni213E /uni213F '+nl+ //38 +'/uni2140 /uni2141 /uni2142 /uni2143 /uni2144 /uni2145 /uni2146 /uni2147 '+nl+ //40 +'/uni2148 /uni2149 /uni214A /uni214B /uni214C /uni214D /uni214E /uni214F '+nl+ //48 +'/uni2150 /uni2151 /uni2152 /onethird /twothirds /uni2155 /uni2156 /uni2157 '+nl+ //50 +'/uni2158 /uni2159 /uni215A /oneeighth /threeeighths /fiveeighths /seveneighths /uni215F '+nl+ //58 +'/uni2160 /uni2161 /uni2162 /uni2163 /uni2164 /uni2165 /uni2166 /uni2167 '+nl+ //60 +'/uni2168 /uni2169 /uni216A /uni216B /uni216C /uni216D /uni216E /uni216F '+nl+ //68 +'/uni2170 /uni2171 /uni2172 /uni2173 /uni2174 /uni2175 /uni2176 /uni2177 '+nl+ //70 +'/uni2178 /uni2179 /uni217A /uni217B /uni217C /uni217D /uni217E /uni217F '+nl+ //78 +'/uni2180 /uni2181 /uni2182 /uni2183 /uni2184 /uni2185 /uni2186 /uni2187 '+nl+ //80 +'/uni2188 /uni2189 /uni218A /uni218B /uni218C /uni218D /uni218E /uni218F '+nl+ //88 +'/arrowleft /arrowup /arrowright /arrowdown /arrowboth /arrowupdn /uni2196 /uni2197 '+nl+ //90 +'/uni2198 /uni2199 /uni219A /uni219B /uni219C /uni219D /uni219E /uni219F '+nl+ //98 +'/uni21A0 /uni21A1 /uni21A2 /uni21A3 /uni21A4 /uni21A5 /uni21A6 /uni21A7 '+nl+ //A0 +'/arrowupdnbse /uni21A9 /uni21AA /uni21AB /uni21AC /uni21AD /uni21AE /uni21AF '+nl+ //A8 +'/uni21B0 /uni21B1 /uni21B2 /uni21B3 /uni21B4 /carriagereturn /uni21B6 /uni21B7 '+nl+ //B0 +'/uni21B8 /uni21B9 /uni21BA /uni21BB /uni21BC /uni21BD /uni21BE /uni21BF '+nl+ //B8 +'/uni21C0 /uni21C1 /uni21C2 /uni21C3 /uni21C4 /uni21C5 /uni21C6 /uni21C7 '+nl+ //C0 +'/uni21C8 /uni21C9 /uni21CA /uni21CB /uni21CC /uni21CD /uni21CE /uni21CF '+nl+ //C8 +'/arrowdblleft /arrowdblup /arrowdblright /arrowdbldown /arrowdblboth /uni21D5 /uni21D6 /uni21D7 '+nl+ //D0 +'/uni21D8 /uni21D9 /uni21DA /uni21DB /uni21DC /uni21DD /uni21DE /uni21DF '+nl+ //D8 +'/uni21E0 /uni21E1 /uni21E2 /uni21E3 /uni21E4 /uni21E5 /uni21E6 /uni21E7 '+nl+ //E0 +'/uni21E8 /uni21E9 /uni21EA /uni21EB /uni21EC /uni21ED /uni21EE /uni21EF '+nl+ //E8 +'/uni21F0 /uni21F1 /uni21F2 /uni21F3 /uni21F4 /uni21F5 /uni21F6 /uni21F7 '+nl+ //F0 +'/uni21F8 /uni21F9 /uni21FA /uni21FB /uni21FC /uni21FD /uni21FE /uni21FF '+nl //F8 + ), + ( + codepage: $22; + name: 'E22'; //mathematical operators + glyphnames: +'/universal /uni2201 /partialdiff /existential /uni2204 /emptyset /uni2206 /gradient '+nl+ //00 +'/element /notelement /uni220A /suchthat /uni220C /uni220D /uni220E /product '+nl+ //08 +'/uni2210 /summation /minus /uni2213 /uni2214 /uni2215 /uni2216 /asteriskmath '+nl+ //10 +'/uni2218 /uni2219 /radical /uni221B /uni221C /proportional /infinity /orthogonal '+nl+ //18 +'/angle /uni2221 /uni2222 /uni2223 /uni2224 /uni2225 /uni2226 /logicaland '+nl+ //20 +'/logicalor /intersection /union /integral /uni222C /uni222D /uni222E /uni222F '+nl+ //28 +'/uni2230 /uni2231 /uni2232 /uni2233 /therefore /uni2235 /uni2236 /uni2237 '+nl+ //30 +'/uni2238 /uni2239 /uni223A /uni223B /similar /uni223D /uni223E /uni223F '+nl+ //38 +'/uni2240 /uni2241 /uni2242 /uni2243 /uni2244 /congruent /uni2246 /uni2247 '+nl+ //40 +'/approxequal /uni2249 /uni224A /uni224B /uni224C /uni224D /uni224E /uni224F '+nl+ //48 +'/uni2250 /uni2251 /uni2252 /uni2253 /uni2254 /uni2255 /uni2256 /uni2257 '+nl+ //50 +'/uni2258 /uni2259 /uni225A /uni225B /uni225C /uni225D /uni225E /uni225F '+nl+ //58 +'/notequal /equivalence /uni2262 /uni2263 /lessequal /greaterequal /uni2266 /uni2267 '+nl+ //60 +'/uni2268 /uni2269 /uni226A /uni226B /uni226C /uni226D /uni226E /uni226F '+nl+ //68 +'/uni2270 /uni2271 /uni2272 /uni2273 /uni2274 /uni2275 /uni2276 /uni2277 '+nl+ //70 +'/uni2278 /uni2279 /uni227A /uni227B /uni227C /uni227D /uni227E /uni227F '+nl+ //78 +'/uni2280 /uni2281 /propersubset /propersuperset /notsubset /uni2285 /reflexsubset /reflexsuperset '+nl+ //80 +'/uni2288 /uni2289 /uni228A /uni228B /uni228C /uni228D /uni228E /uni228F '+nl+ //88 +'/uni2290 /uni2291 /uni2292 /uni2293 /uni2294 /circleplus /uni2296 /circlemultiply '+nl+ //90 +'/uni2298 /uni2299 /uni229A /uni229B /uni229C /uni229D /uni229E /uni229F '+nl+ //98 +'/uni22A0 /uni22A1 /uni22A2 /uni22A3 /uni22A4 /perpendicular /uni22A6 /uni22A7 '+nl+ //A0 +'/uni22A8 /uni22A9 /uni22AA /uni22AB /uni22AC /uni22AD /uni22AE /uni22AF '+nl+ //A8 +'/uni22B0 /uni22B1 /uni22B2 /uni22B3 /uni22B4 /uni22B5 /uni22B6 /uni22B7 '+nl+ //B0 +'/uni22B8 /uni22B9 /uni22BA /uni22BB /uni22BC /uni22BD /uni22BE /uni22BF '+nl+ //B8 +'/uni22C0 /uni22C1 /uni22C2 /uni22C3 /uni22C4 /dotmath /uni22C6 /uni22C7 '+nl+ //C0 +'/uni22C8 /uni22C9 /uni22CA /uni22CB /uni22CC /uni22CD /uni22CE /uni22CF '+nl+ //C8 +'/uni22D0 /uni22D1 /uni22D2 /uni22D3 /uni22D4 /uni22D5 /uni22D6 /uni22D7 '+nl+ //D0 +'/uni22D8 /uni22D9 /uni22DA /uni22DB /uni22DC /uni22DD /uni22DE /uni22DF '+nl+ //D8 +'/uni22E0 /uni22E1 /uni22E2 /uni22E3 /uni22E4 /uni22E5 /uni22E6 /uni22E7 '+nl+ //E0 +'/uni22E8 /uni22E9 /uni22EA /uni22EB /uni22EC /uni22ED /uni22EE /uni22EF '+nl+ //E8 +'/uni22F0 /uni22F1 /uni22F2 /uni22F3 /uni22F4 /uni22F5 /uni22F6 /uni22F7 '+nl+ //F0 +'/uni22F8 /uni22F9 /uni22FA /uni22FB /uni22FC /uni22FD /uni22FE /uni22FF '+nl //F8 + ), + ( + codepage: $23; + name: 'E23'; //technical symbols + glyphnames: +'/uni2300 /uni2301 /house /uni2303 /uni2304 /uni2305 /uni2306 /uni2307 '+nl+ //00 +'/uni2308 /uni2309 /uni230A /uni230B /uni230C /uni230D /uni230E /uni230F '+nl+ //08 +'/revlogicalnot /uni2311 /uni2312 /uni2313 /uni2314 /uni2315 /uni2316 /uni2317 '+nl+ //10 +'/uni2318 /uni2319 /uni231A /uni231B /uni231C /uni231D /uni231E /uni231F '+nl+ //18 +'/integraltp /integralbt /uni2322 /uni2323 /uni2324 /uni2325 /uni2326 /uni2327 '+nl+ //20 +'/uni2328 /angleleft /angleright /uni232B /uni232C /uni232D /uni232E /uni232F '+nl+ //28 +'/uni2330 /uni2331 /uni2332 /uni2333 /uni2334 /uni2335 /uni2336 /uni2337 '+nl+ //30 +'/uni2338 /uni2339 /uni233A /uni233B /uni233C /uni233D /uni233E /uni233F '+nl+ //38 +'/uni2340 /uni2341 /uni2342 /uni2343 /uni2344 /uni2345 /uni2346 /uni2347 '+nl+ //40 +'/uni2348 /uni2349 /uni234A /uni234B /uni234C /uni234D /uni234E /uni234F '+nl+ //48 +'/uni2350 /uni2351 /uni2352 /uni2353 /uni2354 /uni2355 /uni2356 /uni2357 '+nl+ //50 +'/uni2358 /uni2359 /uni235A /uni235B /uni235C /uni235D /uni235E /uni235F '+nl+ //58 +'/uni2360 /uni2361 /uni2362 /uni2363 /uni2364 /uni2365 /uni2366 /uni2367 '+nl+ //60 +'/uni2368 /uni2369 /uni236A /uni236B /uni236C /uni236D /uni236E /uni236F '+nl+ //68 +'/uni2370 /uni2371 /uni2372 /uni2373 /uni2374 /uni2375 /uni2376 /uni2377 '+nl+ //70 +'/uni2378 /uni2379 /uni237A /uni237B /uni237C /uni237D /uni237E /uni237F '+nl+ //78 +'/uni2380 /uni2381 /uni2382 /uni2383 /uni2384 /uni2385 /uni2386 /uni2387 '+nl+ //80 +'/uni2388 /uni2389 /uni238A /uni238B /uni238C /uni238D /uni238E /uni238F '+nl+ //88 +'/uni2390 /uni2391 /uni2392 /uni2393 /uni2394 /uni2395 /uni2396 /uni2397 '+nl+ //90 +'/uni2398 /uni2399 /uni239A /uni239B /uni239C /uni239D /uni239E /uni239F '+nl+ //98 +'/uni23A0 /uni23A1 /uni23A2 /uni23A3 /uni23A4 /uni23A5 /uni23A6 /uni23A7 '+nl+ //A0 +'/uni23A8 /uni23A9 /uni23AA /uni23AB /uni23AC /uni23AD /uni23AE /uni23AF '+nl+ //A8 +'/uni23B0 /uni23B1 /uni23B2 /uni23B3 /uni23B4 /uni23B5 /uni23B6 /uni23B7 '+nl+ //B0 +'/uni23B8 /uni23B9 /uni23BA /uni23BB /uni23BC /uni23BD /uni23BE /uni23BF '+nl+ //B8 +'/uni23C0 /uni23C1 /uni23C2 /uni23C3 /uni23C4 /uni23C5 /uni23C6 /uni23C7 '+nl+ //C0 +'/uni23C8 /uni23C9 /uni23CA /uni23CB /uni23CC /uni23CD /uni23CE /uni23CF '+nl+ //C8 +'/uni23D0 /uni23D1 /uni23D2 /uni23D3 /uni23D4 /uni23D5 /uni23D6 /uni23D7 '+nl+ //D0 +'/uni23D8 /uni23D9 /uni23DA /uni23DB /uni23DC /uni23DD /uni23DE /uni23DF '+nl+ //D8 +'/uni23E0 /uni23E1 /uni23E2 /uni23E3 /uni23E4 /uni23E5 /uni23E6 /uni23E7 '+nl+ //E0 +'/uni23E8 /uni23E9 /uni23EA /uni23EB /uni23EC /uni23ED /uni23EE /uni23EF '+nl+ //E8 +'/uni23F0 /uni23F1 /uni23F2 /uni23F3 /uni23F4 /uni23F5 /uni23F6 /uni23F7 '+nl+ //F0 +'/uni23F8 /uni23F9 /uni23FA /uni23FB /uni23FC /uni23FD /uni23FE /uni23FF '+nl //F8 + ), + ( + codepage: $25; + name: 'E25'; //box drawing + glyphnames: +'/SF100000 /uni2501 /SF110000 /uni2503 /uni2504 /uni2505 /uni2506 /uni2507 '+nl+ //00 +'/uni2508 /uni2509 /uni250A /uni250B /SF010000 /uni250D /uni250E /uni250F '+nl+ //08 +'/SF030000 /uni2511 /uni2512 /uni2513 /SF020000 /uni2515 /uni2516 /uni2517 '+nl+ //10 +'/SF040000 /uni2519 /uni251A /uni251B /SF080000 /uni251D /uni251E /uni251F '+nl+ //18 +'/uni2520 /uni2521 /uni2522 /uni2523 /SF090000 /uni2525 /uni2526 /uni2527 '+nl+ //20 +'/uni2528 /uni2529 /uni252A /uni252B /SF060000 /uni252D /uni252E /uni252F '+nl+ //28 +'/uni2530 /uni2531 /uni2532 /uni2533 /SF070000 /uni2535 /uni2536 /uni2537 '+nl+ //30 +'/uni2538 /uni2539 /uni253A /uni253B /SF050000 /uni253D /uni253E /uni253F '+nl+ //38 +'/uni2540 /uni2541 /uni2542 /uni2543 /uni2544 /uni2545 /uni2546 /uni2547 '+nl+ //40 +'/uni2548 /uni2549 /uni254A /uni254B /uni254C /uni254D /uni254E /uni254F '+nl+ //48 +'/SF430000 /SF240000 /SF510000 /SF520000 /SF390000 /SF220000 /SF210000 /SF250000 '+nl+ //50 +'/SF500000 /SF490000 /SF380000 /SF280000 /SF270000 /SF260000 /SF360000 /SF370000 '+nl+ //58 +'/SF420000 /SF190000 /SF200000 /SF230000 /SF470000 /SF480000 /SF410000 /SF450000 '+nl+ //60 +'/SF460000 /SF400000 /SF540000 /SF530000 /SF440000 /uni256D /uni256E /uni256F '+nl+ //68 +'/uni2570 /uni2571 /uni2572 /uni2573 /uni2574 /uni2575 /uni2576 /uni2577 '+nl+ //70 +'/uni2578 /uni2579 /uni257A /uni257B /uni257C /uni257D /uni257E /uni257F '+nl+ //78 +'/upblock /uni2581 /uni2582 /uni2583 /dnblock /uni2585 /uni2586 /uni2587 '+nl+ //80 +'/block /uni2589 /uni258A /uni258B /lfblock /uni258D /uni258E /uni258F '+nl+ //88 +'/rtblock /ltshade /shade /dkshade /uni2594 /uni2595 /uni2596 /uni2597 '+nl+ //90 +'/uni2598 /uni2599 /uni259A /uni259B /uni259C /uni259D /uni259E /uni259F '+nl+ //98 +'/filledbox /H22073 /uni25A2 /uni25A3 /uni25A4 /uni25A5 /uni25A6 /uni25A7 '+nl+ //A0 +'/uni25A8 /uni25A9 /H18543 /H18551 /filledrect /uni25AD /uni25AE /uni25AF '+nl+ //A8 +'/uni25B0 /uni25B1 /triagup /uni25B3 /uni25B4 /uni25B5 /uni25B6 /uni25B7 '+nl+ //B0 +'/uni25B8 /uni25B9 /triagrt /uni25BB /triagdn /uni25BD /uni25BE /uni25BF '+nl+ //B8 +'/uni25C0 /uni25C1 /uni25C2 /uni25C3 /triaglf /uni25C5 /uni25C6 /uni25C7 '+nl+ //C0 +'/uni25C8 /uni25C9 /lozenge /circle /uni25CC /uni25CD /uni25CE /H18533 '+nl+ //C8 +'/uni25D0 /uni25D1 /uni25D2 /uni25D3 /uni25D4 /uni25D5 /uni25D6 /uni25D7 '+nl+ //D0 +'/invbullet /invcircle /uni25DA /uni25DB /uni25DC /uni25DD /uni25DE /uni25DF '+nl+ //D8 +'/uni25E0 /uni25E1 /uni25E2 /uni25E3 /uni25E4 /uni25E5 /openbullet /uni25E7 '+nl+ //E0 +'/uni25E8 /uni25E9 /uni25EA /uni25EB /uni25EC /uni25ED /uni25EE /uni25EF '+nl+ //E8 +'/uni25F0 /uni25F1 /uni25F2 /uni25F3 /uni25F4 /uni25F5 /uni25F6 /uni25F7 '+nl+ //F0 +'/uni25F8 /uni25F9 /uni25FA /uni25FB /uni25FC /uni25FD /uni25FE /uni25FF '+nl //F8 + ), + ( + codepage: $26; + name: 'E26'; //miscellaneous symbols + glyphnames: +'/uni2600 /uni2601 /uni2602 /uni2603 /uni2604 /uni2605 /uni2606 /uni2607 '+nl+ //00 +'/uni2608 /uni2609 /uni260A /uni260B /uni260C /uni260D /uni260E /uni260F '+nl+ //08 +'/uni2610 /uni2611 /uni2612 /uni2613 /uni2614 /uni2615 /uni2616 /uni2617 '+nl+ //10 +'/uni2618 /uni2619 /uni261A /uni261B /uni261C /uni261D /uni261E /uni261F '+nl+ //18 +'/uni2620 /uni2621 /uni2622 /uni2623 /uni2624 /uni2625 /uni2626 /uni2627 '+nl+ //20 +'/uni2628 /uni2629 /uni262A /uni262B /uni262C /uni262D /uni262E /uni262F '+nl+ //28 +'/uni2630 /uni2631 /uni2632 /uni2633 /uni2634 /uni2635 /uni2636 /uni2637 '+nl+ //30 +'/uni2638 /uni2639 /smileface /invsmileface /sun /uni263D /uni263E /uni263F '+nl+ //38 +'/female /uni2641 /male /uni2643 /uni2644 /uni2645 /uni2646 /uni2647 '+nl+ //40 +'/uni2648 /uni2649 /uni264A /uni264B /uni264C /uni264D /uni264E /uni264F '+nl+ //48 +'/uni2650 /uni2651 /uni2652 /uni2653 /uni2654 /uni2655 /uni2656 /uni2657 '+nl+ //50 +'/uni2658 /uni2659 /uni265A /uni265B /uni265C /uni265D /uni265E /uni265F '+nl+ //58 +'/spade /uni2661 /uni2662 /club /uni2664 /heart /diamond /uni2667 '+nl+ //60 +'/uni2668 /uni2669 /musicalnote /musicalnotedbl /uni266C /uni266D /uni266E /uni266F '+nl+ //68 +'/uni2670 /uni2671 /uni2672 /uni2673 /uni2674 /uni2675 /uni2676 /uni2677 '+nl+ //70 +'/uni2678 /uni2679 /uni267A /uni267B /uni267C /uni267D /uni267E /uni267F '+nl+ //78 +'/uni2680 /uni2681 /uni2682 /uni2683 /uni2684 /uni2685 /uni2686 /uni2687 '+nl+ //80 +'/uni2688 /uni2689 /uni268A /uni268B /uni268C /uni268D /uni268E /uni268F '+nl+ //88 +'/uni2690 /uni2691 /uni2692 /uni2693 /uni2694 /uni2695 /uni2696 /uni2697 '+nl+ //90 +'/uni2698 /uni2699 /uni269A /uni269B /uni269C /uni269D /uni269E /uni269F '+nl+ //98 +'/uni26A0 /uni26A1 /uni26A2 /uni26A3 /uni26A4 /uni26A5 /uni26A6 /uni26A7 '+nl+ //A0 +'/uni26A8 /uni26A9 /uni26AA /uni26AB /uni26AC /uni26AD /uni26AE /uni26AF '+nl+ //A8 +'/uni26B0 /uni26B1 /uni26B2 /uni26B3 /uni26B4 /uni26B5 /uni26B6 /uni26B7 '+nl+ //B0 +'/uni26B8 /uni26B9 /uni26BA /uni26BB /uni26BC /uni26BD /uni26BE /uni26BF '+nl+ //B8 +'/uni26C0 /uni26C1 /uni26C2 /uni26C3 /uni26C4 /uni26C5 /uni26C6 /uni26C7 '+nl+ //C0 +'/uni26C8 /uni26C9 /uni26CA /uni26CB /uni26CC /uni26CD /uni26CE /uni26CF '+nl+ //C8 +'/uni26D0 /uni26D1 /uni26D2 /uni26D3 /uni26D4 /uni26D5 /uni26D6 /uni26D7 '+nl+ //D0 +'/uni26D8 /uni26D9 /uni26DA /uni26DB /uni26DC /uni26DD /uni26DE /uni26DF '+nl+ //D8 +'/uni26E0 /uni26E1 /uni26E2 /uni26E3 /uni26E4 /uni26E5 /uni26E6 /uni26E7 '+nl+ //E0 +'/uni26E8 /uni26E9 /uni26EA /uni26EB /uni26EC /uni26ED /uni26EE /uni26EF '+nl+ //E8 +'/uni26F0 /uni26F1 /uni26F2 /uni26F3 /uni26F4 /uni26F5 /uni26F6 /uni26F7 '+nl+ //F0 +'/uni26F8 /uni26F9 /uni26FA /uni26FB /uni26FC /uni26FD /uni26FE /uni26FF '+nl //F8 + ) + ); +{ + undefmap: encodingty = ( + codepage: -1; + name: 'Exx'; + glyphnames: +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //00 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //08 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //10 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //18 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //20 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //28 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //30 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //38 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //40 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //48 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //50 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //58 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //60 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //68 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //70 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //78 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //80 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //88 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //90 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //98 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //a0 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //a8 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //b0 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //b8 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //c0 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //c8 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //d0 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //d8 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //e0 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //e8 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl+ //f0 +'/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef '+nl //f8 + ); +} +implementation +end. diff --git a/mseide-msegui/lib/common/kernel/mseuniintf.inc b/mseide-msegui/lib/common/kernel/mseuniintf.inc new file mode 100644 index 0000000..3020fe1 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/mseuniintf.inc @@ -0,0 +1,12 @@ +{ MSEgui Copyright (c) 1999-2007 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} + +function uni_getfontwithglyph(var drawinfo: drawinfoty): boolean; + diff --git a/mseide-msegui/lib/common/kernel/msevariants.pas b/mseide-msegui/lib/common/kernel/msevariants.pas new file mode 100644 index 0000000..b81c0b8 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/msevariants.pas @@ -0,0 +1,86 @@ +{ MSEgui Copyright (c) 2010 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msevariants; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + msetypes,msestrings; +type + variantarty = array of variant; + variantaty = array[0..0] of variant; + pvariantaty = ^variantaty; + variantararty = array of variantarty; + vardataaty = array[0..0] of tvardata; + pvardataaty = ^vardataaty; + +function mseVarTypeIsValidArrayType(const aVarType: TVarType): Boolean; +function mseVarArrayCreate(const Bounds: PVarArrayBoundArray; Dims : SizeInt; + aVarType: TVarType): Variant; +function vartomsestring(const avalue: variant): msestring; + +implementation +uses + variants,varutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +function vartomsestring(const avalue: variant): msestring; +begin + result:= ''; + if not varisnull(avalue) then begin + result:= avalue; + end; +end; + +//allow int64 arrays + +function mseVarTypeIsValidArrayType(const aVarType: TVarType): Boolean; + begin + Result:=aVarType in [varSmallInt,varInteger, +{$ifndef FPUNONE} + varSingle,varDouble,varDate, +{$endif} + varCurrency,varOleStr,varDispatch,varError,varBoolean, + varVariant,varUnknown,varShortInt,varByte,varWord,varLongWord, + varint64]; + end; + +function mseVarArrayCreate(const Bounds: PVarArrayBoundArray; + Dims : SizeInt; aVarType: TVarType): Variant; + var + p : pvararray; + begin + if not(mseVarTypeIsValidArrayType(aVarType)) then + VarArrayCreateError; + finalize(Result); + + p:=SafeArrayCreate(aVarType,Dims,Bounds^); + + if not(assigned(p)) then + VarArrayCreateError; + + TVarData(Result).vType:=aVarType or varArray; + TVarData(Result).vArray:=p; + end; +end. diff --git a/mseide-msegui/lib/common/kernel/windows/mseguiintf.pas b/mseide-msegui/lib/common/kernel/windows/mseguiintf.pas new file mode 100644 index 0000000..f14618c --- /dev/null +++ b/mseide-msegui/lib/common/kernel/windows/mseguiintf.pas @@ -0,0 +1,3531 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseguiintf; //i386-win32 + +{$ifdef FPC}{$mode objfpc}{$h+}{$goto on}{$endif} + +interface +uses + windows,messages,mseapplication,msetypes,msegraphutils,msesys, + mseevent,msepointer,mseguiglob,msegraphics, + msethread,mseformatstr,{msesysintf,}msestrings,msesystypes,msewinglob; + +type + syseventty = record + hwnd: hwnd; + umsg: uint; + wparam: wparam; + lparam: lparam; + lresult: lresult; + end; + +const +// pixel0 = $000000; +// pixel1 = $ffffff; + pixel0 = $ffffff; //select colorbackground + pixel1 = $000000; //select colorforeground + +{$ifdef FPC} +{$include ..\mseguiintf.inc} +{$else} +{$include mseguiintf.inc} +{$endif} + +function getapplicationwindow: hwnd; +procedure recttowinrect(const rect: rectty); overload; +procedure recttowinrect(po: prectty; count: integer); overload; +procedure winrecttorect(const rect: rectty); overload; +procedure winrecttorect(po: prectty; count: integer); overload; +function mrect(aleft,atop,aright,abottom: integer): trect; +function createbitmapdata(const size: sizety; const kind: bitmapkindty; + out data: pointer): hbitmap; + +procedure beginsdndwrite(const athread: threadty); +procedure endsdndwrite; +function nestedwindowproc(): boolean; //window frame clicked + +{$ifdef mse_debuggdi} +var + pixmapcount: integer; + fontcount: integer; + windowcount: integer; + regioncount: integer; + gccount: integer; +{$endif} + +implementation +//todo: 19.10.03 rasterops for textout +uses + sysutils,mselist,msekeyboard,msebits,msearrayutils,msesysutils,msegui, + msesystimer,msegdi32gdi,msesysintf1,msedynload,msewindnd,msebitmap + {$ifdef mse_debugzorder},typinfo{$endif} ; + +type + + trayinfoty = record + end; + win32windowdty = record + trayinfo: trayinfoty; + istaskbar: boolean; + end; + win32windowty = record + case integer of + 0: (d: win32windowdty;); + 1: (_bufferspace: windowpty;); + end; + + wndextrainfoty = record + flags: longword; + stylebackup: longword; +// l,t,r,b: integer; + end; +{$ifndef FPC} + winbool = bool; +{$endif} + +const + MAPVK_VK_TO_VSC = 0; + flagsoffs = 0*sizeof(integer); //for setwindowlong + stylebackupoffs = 1*sizeof(integer); +// loffs = 2*sizeof(integer); +// toffs = 3*sizeof(integer); +// roffs = 4*sizeof(integer); +// boffs = 5*sizeof(integer); + + widgetclassname = 'msetoplevelwidget'; + childwidgetclassname = 'msechildwidget'; + wndextrabytes = sizeof(wndextrainfoty); + + mouseidletime = 100; //milliseconds + { + cursorshapety = (cr_default,cr_none,cr_arrow,cr_cross,cr_wait,cr_ibeam, + cr_sizever,cr_sizehor,cr_sizebdiag,cr_sizefdiag,cr_sizeall, + cr_splitv,cr_splith,cr_pointinghand,cr_forbidden, + cr_topleftcorner,cr_bottomleftcorner, + cr_bottomrightcorner,cr_toprightcorner, + cr_res0,cr_res1,cr_res2,cr_res3,cr_res4,cr_res5,cr_res6,cr_res7, + cr_user); + } + {$ifdef FPC} + IDC_ARROW = pchar(32512); + IDC_IBEAM = pchar(32513); + IDC_WAIT = pchar(32514); + IDC_CROSS = pchar(32515); + IDC_UPARROW = pchar(32516); + IDC_SIZE = pchar(32640); + IDC_ICON = pchar(32641); + IDC_SIZENWSE = pchar(32642); + IDC_SIZENESW = pchar(32643); + IDC_SIZEWE = pchar(32644); + IDC_SIZENS = pchar(32645); + IDC_SIZEALL = pchar(32646); + IDC_NO = pchar(32648); + IDC_HAND = pchar(32649); + IDC_APPSTARTING = pchar(32650); + IDC_HELP = pchar(32651); + + VK_LWIN = 91; + VK_RWIN = 92; + {$endif} + + VK_OEM_PLUS = $BB; // '+' any country + VK_OEM_COMMA = $BC; // ',' any country + VK_OEM_MINUS = $BD; // '-' any country + VK_OEM_PERIOD = $BE; // '.' any coun {$endif} + + standardcursors: array[cursorshapety] of pchar{makeintresource} = + (idc_arrow,idc_arrow,idc_arrow,idc_arrow, + idc_cross,idc_wait,idc_ibeam, + idc_sizens,idc_sizewe,idc_sizenesw,idc_sizenwse,idc_sizeall, + idc_arrow,idc_arrow,idc_hand,idc_no, + idc_arrow, //cr_drag + idc_sizenwse,idc_sizenesw, + idc_sizenwse,idc_sizenesw, + idc_arrow,idc_arrow,idc_arrow,idc_arrow, + idc_arrow,idc_arrow,idc_arrow,idc_arrow, + idc_arrow); +{ // |not dest and source + rasteropty = ( rop_clear, rop_and, rop_andnot, rop_copy, + // |not source and dest + rop_notand, rop_nop, rop_xor, rop_or, + rop_nor, rop_notxor, rop_not, rop_ornot, + rop_notcopy, rop_notor, rop_nand, rop_set); + + source 1 1 0 0 + dest 1 0 1 0 + result x x x x code = result + 1 + copy 1 1 0 0 + 1 = 13 + and 1 0 0 0 + 1 = 9 + } + + + col0: tagrgbquad = (rgbblue: $ff; rgbgreen: $ff; rgbred: $ff; rgbreserved: $00); + col1: tagrgbquad = (rgbblue: 0; rgbgreen: 0; rgbred: 0; rgbreserved: $00); +// col0: tagrgbquad = (rgbblue: 0; rgbgreen: 0; rgbred: 0); +// col1: tagrgbquad = (rgbblue: $ff; rgbgreen: $ff; rgbred: $ff); + + MONITOR_DEFAULTTONULL = 0; + MONITOR_DEFAULTTOPRIMARY = 1; + MONITOR_DEFAULTTONEAREST = 2; + SM_XVIRTUALSCREEN = 76; + SM_YVIRTUALSCREEN = 77; + SM_CXVIRTUALSCREEN = 78; + SM_CYVIRTUALSCREEN = 79; + +type + hmonitor = thandle; + tMONITORINFO = record + cbSize: DWORD ; + rcMonitor: tRECT ; + rcWork: tRECT; + dwFlags: DWORD; + end; + pmonitorinfo = ^tmonitorinfo; + +{$ifdef FPC} +type + TKeyboardState = array[0..255] of Byte; +{$else} +function GetCharacterPlacementW(DC: HDC; p2: PWideChar; p3, p4: Integer; + var p5: TGCPResultsw; p6: DWORD): DWORD; stdcall; + external gdi32 name 'GetCharacterPlacementW'; + +{$endif} + +var + canshutdown: integer; + widgetclass: atom; + childwidgetclass: atom; + applicationwindow: winidty; + desktopwindow: hwnd; + eventlist: tobjectqueue; +// timer: longword; + mouseidletimer: ptruint; + mainthread: threadty; + mousewindow: hwnd; + lastfocuswindow: hwnd; + groupleaderwindow: hwnd; + mousecursor: hcursor; + keystate: tkeyboardstate; + charbuffer: msestring; + shiftstate: shiftstatesty; + primarybuffer: msestring; + + cursors: array[cursorshapety] of longword; + +type + tapplication1 = class(tguiapplication); + tsimplebitmap1 = class(tsimplebitmap); + tcanvas1 = class(tcanvas); +{ + gdimonochromebitmapinfoty = packed record + bmiheader: tbitmapinfoheader; + bmicolors: array[0..1] of trgbquad; + end; +} + gdibitmapinfoty = packed record + bmiheader: tbitmapinfoheader; + bmicolors: array[0..255] of trgbquad; //maximum size + end; + + bitmapinfoty = packed record + bmiheader: bitmapinfoheader; + col0: longword; + col1: longword; + end; + +{$ifdef FPC} +function GetNextWindow(hWnd: HWND; uCmd: UINT): HWND; stdcall; + external user32 name 'GetWindow'; +function winScrollWindowEx(hWnd: HWND; dx, dy: Integer; + prcScroll, prcClip: PRect; + hrgnUpdate: HRGN; prcUpdate: PRect; flags: UINT): BOOL; stdcall; + external user32 name 'ScrollWindowEx'; + +function PeekMessage(var lpMsg: TMsg; hWnd: HWND; + wMsgFilterMin, wMsgFilterMax, wRemoveMsg: UINT): BOOL; stdcall; + external user32 name 'PeekMessageA'; +function TranslateMessage(const lpMsg: TMsg): BOOL; stdcall; + external user32 name 'TranslateMessage'; +function DispatchMessage(const lpMsg: TMsg): Longint; stdcall; + external user32 name 'DispatchMessageA'; +{$endif} + +function GetMonitorInfo(hmomitor: hmonitor; lpmu: pmonitorinfo): BOOL; stdcall; + external user32 name 'GetMonitorInfoA'; +function MonitorFromWindow(hwnd: HWND; dwFlags: DWORD): HMONITOR; stdcall; + external user32 name 'MonitorFromWindow'; + +type +{$ifndef FPC} + POINT = tpoint; + RECT = trect; + {$endif} + HIMC = DWORD; + tagCOMPOSITIONFORM = record + dwStyle: DWORD; + ptCurrentPos: POINT; + rcArea: RECT; + end; + COMPOSITIONFORM = tagCOMPOSITIONFORM; + PCOMPOSITIONFORM = ^COMPOSITIONFORM; + NPCOMPOSITIONFORM = ^COMPOSITIONFORM; + LPCOMPOSITIONFORM = ^COMPOSITIONFORM; + +const +// bit field for IMC_SETCOMPOSITIONWINDOW, IMC_SETCANDIDATEWINDOW + CFS_DEFAULT = $0000; + CFS_RECT = $0001; + CFS_POINT = $0002; + CFS_FORCE_POSITION = $0020; + CFS_CANDIDATEPOS = $0040; + CFS_EXCLUDE = $0080; + +var + hasimm32: boolean; + ImmGetContext: function(_hwnd: HWND): HIMC; stdcall; + ImmReleaseContext: function(_hwnd: HWND; _himc: HIMC): BOOL; stdcall; + ImmSetCompositionWindow: function(_himc: HIMC; + lpCompForm: LPCOMPOSITIONFORM): BOOL; stdcall; + + haslayeredwindows: boolean; + SetLayeredWindowAttributes: + function(_hwnd: HWND; crKey: COLORREF; bAlpha: BYTE; + dwFLAGS: DWORD): BOOL; stdcall; +{ + UpdateLayeredWindow: + function(_hwnd: HWND; hdcDst: HDC; pptDst: pPOINT; psize: pSIZE; + hdcSrc: HDC; pptSrc: pPOINT; crKey: COLORREF; + pblend: pBLENDFUNCTION; dwFlags: DWORD): BOOL; stdcall; +} +function getapplicationwindow: hwnd; +begin + result:= applicationwindow; +end; + +{$ifndef FPC} +type + _NOTIFYICONDATAA = record + cbSize: DWORD; + Wnd: HWND; + uID: UINT; + uFlags: UINT; + uCallbackMessage: UINT; + hIcon: HICON; + szTip: array [0..63] of Char; + end; + _NOTIFYICONDATA = _NOTIFYICONDATAA; + + _NOTIFYICONDATAW = record + cbSize: DWORD; + Wnd: HWND; + uID: UINT; + uFlags: UINT; + uCallbackMessage: UINT; + hIcon: HICON; + szTip: array [0..63] of Word; + end; + TNotifyIconDataA = _NOTIFYICONDATAA; + TNotifyIconDataW = _NOTIFYICONDATAW; + TNotifyIconData = TNotifyIconDataA; + NOTIFYICONDATAA = _NOTIFYICONDATAA; + NOTIFYICONDATAW = _NOTIFYICONDATAW; + NOTIFYICONDATA = NOTIFYICONDATAA; + PNotifyIconDataA = ^TNotifyIconDataA; + PNotifyIconDataW = ^TNotifyIconDataW; + PNotifyIconData = PNotifyIconDataA; + +function Shell_NotifyIconA(dwMessage: DWORD; lpData: PNotifyIconDataA): BOOL; + external 'shell32.dll' name 'Shell_NotifyIconA'; +function Shell_NotifyIconW(dwMessage: DWORD; lpData: PNotifyIconDataW): BOOL; + external 'shell32.dll' name 'Shell_NotifyIconW'; +{$endif} +{ +var + Shell_NotifyIconA: function (dwMessage: DWORD; lpData: PNotifyIconDataA): BOOL; + Shell_NotifyIconW: function (dwMessage: DWORD; lpData: PNotifyIconDataW): BOOL; + + shellinterfaceerror: guierrorty = gue_noshelllib; + shellinterfacechecked: boolean; + +function checkshellinterface: guierrorty; +var + bo1: boolean; +begin + if (shellinterfaceerror <> gue_ok) and not shellinterfacechecked then begin + shellinterfacechecked:= true; + if iswin95 then begin + bo1:= checkprocaddresses(['shell32.dll'], + ['Shell_NotifyIconA' + ], + [@Shell_NotifyIconA + ]); + end + else begin + bo1:= checkprocaddresses(['shell32.dll'], + ['Shell_NotifyIconW' + ], + [@Shell_NotifyIconW + ]); + end; + if bo1 then begin + shellinterfaceerror:= gue_ok; + end; + end; + result:= shellinterfaceerror; +end; +} + +procedure useproc; //no "not used" message +begin + if (childwidgetclass = 0) and (desktopwindow = 0) then begin + end; +end; + +function checkshellinterface: guierrorty; +begin + result:= gue_ok; +end; + +function mrect(aleft,atop,aright,abottom: integer): trect; +begin + with result do begin + left:= aleft; + top:= atop; + right:= aright; + bottom:= abottom; + end; +end; + +function gui_sethighrestimer(const avalue: boolean): guierrorty; +begin + if setmmtimer(avalue) then begin + result:= gue_ok; + end + else begin + result:= gue_timer; + end; +end; + +function gui_grouphideminimizedwindows: boolean; +begin + result:= true; +end; + +function gui_setimefocus(var awindow: windowty): guierrorty; +begin + result:= gue_ok; +end; + +function gui_unsetimefocus(var awindow: windowty): guierrorty; +begin + result:= gue_ok; +end; + +function gui_regiontorects(const aregion: regionty): rectarty; +var + int1: integer; + po1: prgndata; + po2: prect; +begin + result:= nil; + if aregion <> 0 then begin + int1:= getregiondata(aregion,0,nil); + getmem(po1,int1); + if getregiondata(aregion,int1,po1) <> 0 then begin + setlength(result,po1^.rdh.ncount); + po2:= @po1^.buffer; + for int1:= 0 to high(result) do begin + with result[int1],po2^ do begin + x:= left; + y:= top; + cx:= right - left; + cy:= bottom - top; + end; + inc(po2); + end; + end; + freemem(po1); + end; +end; + +function gui_getdefaultfontnames: defaultfontnamesty; +begin + result:= gdi32getdefaultfontnames; +end; + +function gui_canstackunder: boolean; +begin + result:= true; +end; + +procedure gui_cancelshutdown; +begin + if canshutdown <> 0 then begin + tapplication1(application).exitloop; + end; + canshutdown:= 0; +end; + +function gui_copytoclipboard(const value: msestring; + const buffer: clipboardbufferty): guierrorty; + //todo: copy msechars to clipboard, win95? +var + mem: thandle; + po1: pchar; + po2: pwidechar; + str1: string; +begin + if buffer = cbb_primary then begin + result:= gue_ok; + primarybuffer:= value; + end + else begin + result:= gue_clipboard; + if openclipboard(0) then begin + if emptyclipboard then begin + if iswin95 then begin + str1:= ansistring(value); + mem:= globalalloc(GMEM_MOVEABLE or GMEM_DDESHARE,length(str1)+1); //nullterminator + if mem <> 0 then begin + po1:= globallock(mem); + if po1 <> nil then begin + move(pchar(str1)^,po1^,length(str1)+1); + globalunlock(mem); + if setclipboarddata(cf_text,longword(mem)) <> 0 then begin + result:= gue_ok; + end; + end + else begin + globalfree(mem); + end; + end; + end + else begin + mem:= globalalloc(GMEM_MOVEABLE or GMEM_DDESHARE,(length(value)+1)*2); + //nullterminator + if mem <> 0 then begin + po2:= globallock(mem); + if po2 <> nil then begin + move(pwidechar(value)^,po2^,(length(value)+1)*2); + globalunlock(mem); + if setclipboarddata(cf_unicodetext,longword(mem)) <> 0 then begin + result:= gue_ok; + end; + end + else begin + globalfree(mem); + end; + end; + end; + end; + closeclipboard; + end; + end; +end; + +function gui_canpastefromclipboard( + const buffer: clipboardbufferty): boolean; +begin + if buffer = cbb_primary then begin + result:= primarybuffer <> ''; + end + else begin + result:= isclipboardformatavailable(cf_text); + end; +end; + +function gui_sysdnd(const action: sysdndactionty; + const aintf: isysdnd; const arect: rectty; + out aresult: boolean): guierrorty; +begin + result:= sysdnd(action,aintf,arect,aresult); +end; + +function gui_sysdndreaddata(var adata: string; + const typeindex: integer): guierrorty; +begin + result:= sysdndreaddata(adata,typeindex); +end; + +function gui_sysdndreadtext(var atext: msestring; + const typeindex: integer): guierrorty; +begin + result:= sysdndreadtext(atext,typeindex); +end; + +function gui_pastefromclipboard(out value: msestring; + const buffer: clipboardbufferty): guierrorty; +var //todo: get msechars from clipboard, win95? + data: thandle; + po1: pointer; + str1: string; +begin + result:= gue_clipboard; + if buffer = cbb_primary then begin + value:= primarybuffer; + if value <> '' then begin + result:= gue_ok; + end; + end + else begin + value:= ''; + if openclipboard(0) then begin + if iswin95 then begin + data:= getclipboarddata(cf_text); + end + else begin + data:= getclipboarddata(cf_unicodetext); + end; + closeclipboard; + if data <> 0 then begin + po1:= globallock(data); + if po1 <> nil then begin + if iswin95 then begin + setlength(str1,globalsize(data)); + if length(str1) > 0 then begin + move(po1^,str1[1],length(str1)); + result:= gue_ok; + setlength(str1,length(pchar(str1))); + end; + value:= msestring(str1); + end + else begin + setlength(value,globalsize(data) div 2); + if length(value) > 0 then begin + move(po1^,value[1],length(value)*2); + result:= gue_ok; + setlength(value,length(pwidechar(value))); + if (value <> '') and (value[length(value)] = #$0d) then begin + setlength(value,length(value)-1); + end; + end; + end; + globalunlock(data); + end; + end; + end; + end; +end; + +function gui_getwindowsize(id: winidty): windowsizety; +var + placement: twindowplacement; +begin + case getwindowlong(id,flagsoffs) of + 1: begin + result:= wsi_fullscreen; + end; + 2: begin + result:= wsi_fullscreenvirt; + end; + else begin + result:= wsi_normal; + placement.length:= sizeof(placement); + if getwindowplacement(id,{$ifndef FPC}@{$endif}placement) then begin + case placement.showcmd of + sw_showmaximized: result:= wsi_maximized; + sw_showminimized: result:= wsi_minimized; + end; + end; + end; + end; +end; + +function gui_getwindowdesktop(const id: winidty): integer; +begin + result:= 0; //todo +end; + +function gui_windowvisible(id: winidty): boolean; +begin + result:= iswindowvisible(id); +end; + +function gui_setwindowstate(id: winidty; size: windowsizety; + visible: boolean): guierrorty; +var + int1,int2: integer; + wo1: longword; +// placement: twindowplacement; +begin + result:= gue_ok; + int1:= getwindowlong(id,flagsoffs); + int2:= 0; + if size in [wsi_fullscreen,wsi_fullscreenvirt] then begin + case size of + wsi_fullscreen: int2:= 1; + wsi_fullscreenvirt: int2:= 2; + end; + if int1 <> int2 then begin + setwindowlong(id,flagsoffs,int2); + if int1 = 0 then begin + wo1:= getwindowlong(id,gwl_style); + setwindowlong(id,stylebackupoffs,wo1); + wo1:= wo1 and not + (ws_border or ws_dlgframe or ws_overlapped or ws_thickframe) or (ws_popup); + setwindowlong(id,gwl_style,wo1); + end; + if size = wsi_fullscreen then begin + setwindowpos(id,0,0,0,getsystemmetrics(sm_cxscreen), + getsystemmetrics(sm_cyscreen), + swp_framechanged {or swp_nomove or swp_nosize} + or swp_nozorder or swp_noownerzorder or swp_noactivate); + end + else begin + setwindowpos(id,0,getsystemmetrics(sm_xvirtualscreen), + getsystemmetrics(sm_yvirtualscreen), + getsystemmetrics(sm_cxvirtualscreen), + getsystemmetrics(sm_cyvirtualscreen), + swp_framechanged {or swp_nomove or swp_nosize} + or swp_nozorder or swp_noownerzorder or swp_noactivate); + end; + end; + if visible then begin + showwindow(id,sw_shownoactivate); + end; + end + else begin + if int1 <> 0 then begin + wo1:= getwindowlong(id,stylebackupoffs); + setwindowlong(id,gwl_style,getwindowlong(id,stylebackupoffs)); + setwindowpos(id,0,0,0,0,0, + swp_framechanged or swp_nomove or swp_nosize or swp_nozorder or + swp_noownerzorder or swp_noactivate); + setwindowlong(id,flagsoffs,int2); + end; + case size of + wsi_maximized: begin + int1:= sw_maximize; + end; + wsi_minimized: begin + int1:= sw_minimize; + end; + else begin + int1:= sw_shownoactivate; + end; + end; + if visible or (size = wsi_minimized) then begin + showwindow(id,int1); + end; + end; +end; + +function gui_getpointerpos: pointty; +begin + windows.getcursorpos(tpoint(result)); +end; + +function gui_setpointerpos(const pos: pointty): guierrorty; +begin + if windows.SetCursorPos(pos.x,pos.y) then begin + result:= gue_ok; + end + else begin + result:= gue_mousepos; + end; +end; + +function gui_movepointer(const dist: pointty): guierrorty; +var + po1: tpoint; +begin + result:= gue_mousepos; + if windows.getcursorpos(po1) then begin + if windows.setcursorpos(po1.x+dist.x,po1.y+dist.y) then begin + result:= gue_ok; + end; + end; +end; + +function gui_grabpointer(id: winidty): guierrorty; +begin + setcapture(id); + if getcapture = id then begin +{$ifdef mse_debugwindowfocus} + debugwindow('grabpointer OK ',id); +{$endif} + result:= gue_ok; + end + else begin +{$ifdef mse_debugwindowfocus} + debugwindow('grabpointer error ',id); +{$endif} + result:= gue_capturemouse; + end; +end; + +function gui_ungrabpointer: guierrorty; +begin +{$ifdef mse_debugwindowfocus} + debugwriteln('ungrabpointer'); +{$endif} + releasecapture; + result:= gue_ok; +end; + +function gui_createpixmap(const size: sizety; winid: winidty = 0; + kind: bitmapkindty = bmk_rgb; + copyfrom: pixmapty = 0): pixmapty; + //copyfrom does not work if selected in dc! +var + dc,dc1: hdc; + po1: pointer; +begin + po1:= nil; + case kind of + bmk_mono: begin + result:= createbitmap(size.cx,size.cy,1,1,nil); + end; + bmk_gray: begin + result:= createbitmapdata(size,kind,po1); +// result:= createbitmap(size.cx,size.cy,1,8,nil); + end + else begin + dc:= getdc(winid); + result:= createcompatiblebitmap(dc,size.cx,size.cy); + releasedc(winid,dc); + end; + end; +{$ifdef mse_debuggdi} + if result <> 0 then begin + inc(pixmapcount); + end; +{$endif} + if (result <> 0) and (copyfrom <> 0) then begin + dc:= createcompatibledc(0); + dc1:= createcompatibledc(0); + selectobject(dc,result); + selectobject(dc1,copyfrom); + bitblt(dc,0,0,size.cx,size.cy,dc1,0,0,srccopy); + deletedc(dc); + deletedc(dc1); + { + dc:= getdc(winid); + fillchar(bitmapinfo,sizeof(bitmapinfo),0); + bitmapinfo.bmiHeader.bisize:= sizeof(bitmapinfo.bmiheader); + if getdibits(dc,copyfrom,0,size.cy,nil, + windows.bitmapinfo(pointer(@bitmapinfo)^),dib_rgb_colors) <> 0 then begin + with bitmapinfo.bmiHeader do begin + if bisizeimage = 0 then begin + if monochrome then begin + bisizeimage:= ((size.cx+31) div 32) * 4 * size.cy; + end + else begin + bisizeimage:= size.cx*size.cy*4; + end; + end; + po1:= pointer(localalloc(LMEM_FIXED,bisizeimage)); + getdibits(dc,copyfrom,0,size.cy,po1, + windows.bitmapinfo(pointer(@bitmapinfo)^),dib_rgb_colors); + setdibits(dc,result,0,size.cy,po1, + windows.bitmapinfo(pointer(@bitmapinfo)^),dib_rgb_colors); + localfree(longword(po1)); + end; + end; + releasedc(winid,dc); + } + end; +end; + +procedure initbitmapinfo(kind: bitmapkindty; bottomup: boolean; + const size: sizety; const setpalette: boolean; + out bitmapinfo: gdibitmapinfoty); +var + lwo1: longword; +begin + fillchar(bitmapinfo,sizeof(bitmapinfo),0); + with bitmapinfo.bmiHeader do begin + bisize:= sizeof(tbitmapinfoheader); + biwidth:= size.cx; + if bottomup then begin + biheight:= size.cy; + end + else begin + biheight:= -size.cy; + end; + biplanes:= 1; + case kind of + bmk_mono: begin + bibitcount:= 1; + bitmapinfo.bmicolors[0]:= col0; + bitmapinfo.bmicolors[1]:= col1; + // bitmapinfo.bmicolors[0]:= col0; + // bitmapinfo.bmicolors[1]:= col1; + end; + bmk_gray: begin + bibitcount:= 8; + if setpalette then begin + for lwo1:= 0 to high(bitmapinfo.bmicolors) do begin + bitmapinfo.bmicolors[lwo1]:= + rgbquad(lwo1 or (lwo1 shl 8) or (lwo1 shl 16)); + end; + end + else begin + biclrused:= 1; + bitmapinfo.bmicolors[0]:= col0;; + end; + end; + else begin + bibitcount:= 32; + end; + end; + end; +end; + +function createbitmapdata(const size: sizety; const kind: bitmapkindty; + out data: pointer): hbitmap; +var + info: gdibitmapinfoty; +begin + initbitmapinfo(kind,false,size,true,info); + result:= createdibsection(0,bitmapinfo((@info)^),dib_rgb_colors,data,0,0); +end; + +function gui_createbitmapfromdata(const size: sizety; datapo: pbyte; + msbitfirst: boolean = false; dwordaligned: boolean = false; + bottomup: boolean = false): pixmapty; +var + po1,po2: pbyte; + bytesperline: integer; + int1,int2,int3: integer; + bitmapinfo: gdibitmapinfoty; + dc: hdc; + +begin + {$ifdef FPC}{$checkpointer off}{$endif} + bytesperline:= ((size.cx+31) div 32)*4; + int3:= bytesperline*size.cy; //total bytecount + po1:= pointer(localalloc(LMEM_FIXED,int3)); + fillchar(po1^,int3,0); + if dwordaligned then begin + move(datapo^,po1^,int3); + end + else begin + int2:= (size.cx+7) div 8; //source bytesperline + po2:= po1; + for int1:= 0 to size.cy - 1 do begin + move(datapo^,po2^,int2); + inc(po2,bytesperline); + inc(datapo,int2); + end; + end; + if not msbitfirst then begin + po2:= po1; + for int1:= 0 to int3-1 do begin + po2^:= bitreverse[po2^]; + inc(po2); + end; + end; + initbitmapinfo(bmk_mono,bottomup,size,true,bitmapinfo); + result:= createbitmap(size.cx,size.cy,1,1,nil); + dc:= getdc(0); + setdibits(dc,result,0,size.cy,po1,windows.bitmapinfo(pointer(@bitmapinfo)^),dib_rgb_colors); + releasedc(0,dc); + localfree(ptruint(po1)); +// localfree(longword(po1)); + {$ifdef FPC}{$checkpointer default}{$endif} +end; + +function gui_freepixmap(pixmap: pixmapty): gdierrorty; +begin + if not deleteobject(pixmap) then begin + result:= gde_freepixmap; + end + else begin +{$ifdef mse_debuggdi} + dec(pixmapcount); +{$endif} + result:= gde_ok; + end; +end; + +function gui_getpixmapinfo(var info: pixmapinfoty): gdierrorty; +var + bmp: bitmap; +begin + with info do begin + if getobject(handle,sizeof(bmp),@bmp) = 0 then begin + result:= gde_pixmap; + end + else begin + result:= gde_ok; + size.cx:= bmp.bmwidth; + size.cy:= bmp.bmheight; + depth:= bmp.bmbitspixel; + end; + end; +end; + +procedure transformimageformat(const image: imagety; inverse: boolean = true); +var + po1: pbyte; + int1: integer; +begin + {$ifdef FPC}{$checkpointer off}{$endif} +// if image.monochrome then begin + if image.kind = bmk_mono then begin + po1:= pointer(image.pixels); + if inverse then begin + for int1:= 0 to image.length*4-1 do begin + po1^:= not bitreverse[po1^]; + inc(po1); + end; + end + else begin + for int1:= 0 to image.length*4-1 do begin + po1^:= bitreverse[po1^]; + inc(po1); + end; + end; + end; + {$ifdef FPC}{$checkpointer default}{$endif} + { + else begin + for int1:= 0 to high(image.pixels) do begin + swaprgb1(image.pixels[int1]); + end; + end; + } +end; + +var + imagememalloc: integer; + +function gui_allocimagemem(length: integer): plongwordaty; +begin + if length = 0 then begin + result:= nil; + end + else begin + inc(imagememalloc); + result:= pointer(localalloc(LMEM_FIXED,length*sizeof(longword))); + //getdibits, setdeibits do not work with normal heap + if result = nil then begin + raise exception.Create('Out of memory.'); + end; + end; +end; + +procedure gui_freeimagemem(data: plongwordaty); +begin + dec(imagememalloc); + localfree(ptruint(data)); +end; + +function gui_pixmaptoimage(pixmap: pixmapty; out image: imagety; + gchandle: longword): gdierrorty; +var + info: pixmapinfoty; + bitmapinfo: gdibitmapinfoty; + dc: hdc; + int1: integer; +// bmp1,bmpbefore: hbitmap; + kind1: bitmapkindty; + +begin +{ + if gchandle <> 0 then begin + bmp1:= createcompatiblebitmap(gchandle,0,0); + bmpbefore:= selectobject(gchandle,bmp1); + end + else begin + bmp1:= 0; //compiler warning + end; +} + if gchandle <> 0 then begin + dc:= gchandle; + end + else begin + dc:= getdc(0); + end; + info.handle:= pixmap; + result:= gui_getpixmapinfo(info); + if result = gde_ok then begin + result:= gde_image; + case info.depth of + 1: begin + kind1:= bmk_mono; + end; + 8: begin + kind1:= bmk_gray; + end; + else begin + kind1:= bmk_rgb; + end; + end; + initbitmapinfo(kind1,false,info.size,false,bitmapinfo); + allocimage(image,info.size,kind1); +// dc:= getdc(0); + int1:= getdibits(dc,pixmap,0,info.size.cy,image.pixels, + pbitmapinfo(@bitmapinfo)^,dib_rgb_colors); +// releasedc(0,dc); + if int1 <> 0 then begin + transformimageformat(image); + result:= gde_ok; + end; + end; + if gchandle = 0 then begin + releasedc(0,dc); + end; + { + if gchandle <> 0 then begin + selectobject(gchandle,bmpbefore); +// selectobject(gchandle,pixmap); + deleteobject(bmp1); + end; + } +end; + +function gui_getpixel(const id: winidty; const pos: pointty; + out pixel: pixelty): guierrorty; +var + dc: hdc; +begin + result:= gue_error; + dc:= getdc(id); + pixel:= windows.getpixel(dc,pos.x,pos.y); + releasedc(id,dc); + if pixel <> clr_invalid then begin + result:= gue_ok; + end; +end; + +function gui_imagetopixmap(const image: imagety; out pixmap: pixmapty; + gchandle: longword): gdierrorty; +var + int1: integer; + bitmapinfo: gdibitmapinfoty; + dc: hdc; +// bmp1,bmpbefore: hbitmap; +begin +// bmp1:= 0; //compiler warning + result:= gde_pixmap; + if gchandle <> 0 then begin + dc:= gchandle; + end + else begin + dc:= getdc(0); + end; + { + if gchandle <> 0 then begin + bmp1:= createcompatiblebitmap(gchandle,0,0); + bmpbefore:= selectobject(gchandle,bmp1); + end; + } + pixmap:= gui_createpixmap(image.size,0,image.kind); + if pixmap <> 0 then begin + transformimageformat(image,false); //setdibits reverses image!?!?! + initbitmapinfo(image.kind,false,image.size,true,bitmapinfo); +// dc:= getdc(0); + int1:= setdibits(dc,pixmap,0,image.size.cy,image.pixels, + tbitmapinfo(pbitmapinfo(@bitmapinfo)^),dib_rgb_colors); +// releasedc(0,dc); + transformimageformat(image,false); //restore orginal bitorder + if int1 <> 0 then begin + result:= gde_ok; + end; + end; + if gchandle <> 0 then begin + deleteobject(selectobject(gchandle,pixmap)); + end + else begin + releasedc(0,dc); + end; +{ + if gchandle <> 0 then begin +// selectobject(gchandle,bmpbefore); + selectobject(gchandle,pixmap); + deleteobject(bmp1); + end; +} +end; + +function gui_setwindowfocus(id: winidty): guierrorty; +begin +// setforegroundwindow(applicationwindow); + setforegroundwindow(id); + setfocus(id); + result:= gue_ok; +end; + +function gui_setappfocus(id: winidty): guierrorty; +var + selfthread,otherthread: threadty; +begin + result:= gue_error; + selfthread:= threadty(getcurrentthreadid); + otherthread:= threadty(getwindowthreadprocessid(id,nil)); + if otherthread <> 0 then begin + if attachthreadinput(selfthread,otherthread,true) then begin + if windows.setfocus(id) <> 0 then begin + result:= gue_ok; + end; + attachthreadinput(selfthread,otherthread,false) + end; + end; +end; + +function gui_minimizeapplication: guierrorty; +begin + result:= gue_ok; + if iswindowvisible(applicationwindow) then begin + showwindow(applicationwindow,sw_minimize); + end; +end; + +const + curwidth = 32; + curheight = 32; + curlength = ((curwidth+15) div 16)*2*curheight; + curdragxor: array[0..curlength-1] of byte = + ( + $00,$00,$00,$00, + $40,$00,$00,$00, + $60,$00,$00,$00, + $70,$00,$00,$00, + $78,$00,$00,$00, + $7c,$00,$00,$00, + $7e,$00,$00,$00, + $7f,$00,$00,$00, + $7f,$80,$00,$00, + $7f,$80,$00,$00, + $7f,$00,$00,$00, + $7e,$00,$00,$00, + $6e,$00,$00,$00, + $46,$00,$00,$00, + $06,$Fc,$00,$00, + $03,$7c,$00,$00, + $03,$7c,$00,$00, + $05,$bc,$00,$00, + $05,$bc,$00,$00, + $06,$7c,$00,$00, + $07,$Fc,$00,$00, + $07,$Fc,$00,$00, + $07,$Fc,$00,$00, + $07,$Fc,$00,$00, + $07,$Fc,$00,$00, + $00,$00,$00,$00, + $00,$00,$00,$00, + $00,$00,$00,$00, + $00,$00,$00,$00, + $00,$00,$00,$00, + $00,$00,$00,$00, + $00,$00,$00,$00); + curdragand: array[0..curlength-1] of byte = + ( + $3f,$ff,$ff,$ff, + $1f,$ff,$ff,$ff, + $0f,$ff,$ff,$ff, + $07,$ff,$ff,$ff, + $03,$ff,$ff,$ff, + $01,$ff,$ff,$ff, + $00,$ff,$ff,$ff, + $00,$7f,$ff,$ff, + $00,$3f,$ff,$ff, + $00,$1f,$ff,$ff, + $00,$0f,$ff,$ff, + $00,$ff,$ff,$ff, + $00,$ff,$ff,$ff, + $10,$01,$ff,$ff, + $30,$01,$ff,$ff, + $70,$01,$ff,$ff, + $f0,$01,$ff,$ff, + $f0,$01,$ff,$ff, + $f0,$01,$ff,$ff, + $f0,$01,$ff,$ff, + $f0,$01,$ff,$ff, + $f0,$01,$ff,$ff, + $f0,$01,$ff,$ff, + $f0,$01,$ff,$ff, + $f0,$01,$ff,$ff, + $f0,$01,$ff,$ff, + $ff,$ff,$ff,$ff, + $ff,$ff,$ff,$ff, + $ff,$ff,$ff,$ff, + $ff,$ff,$ff,$ff, + $ff,$ff,$ff,$ff, + $ff,$ff,$ff,$ff + ); + +function gui_setcursorshape(winid: winidty; shape: cursorshapety): guierrorty; +var + cursor: hcursor; +begin + case shape of + cr_none: begin + cursor:= 0; + end; + cr_drag: begin + if cursors[cr_drag] = 0 then begin + cursors[cr_drag]:= createcursor(hinstance,0,0,curwidth,curheight, + @curdragand,@curdragxor); + end; + cursor:= cursors[cr_drag]; + end; + else begin + cursor:= windows.LoadCursor(0,standardcursors[shape]); + end; + end; + windows.SetCursor(cursor); + mousecursor:= cursor; + result:= gue_ok; +end; +{ +procedure killtimer; +begin + if timer <> 0 then begin + windows.killtimer(0,timer); + timer:= 0; + end; +end; + +procedure TimerProc(hwnd: hwnd; uMsg: longword; idEvent: longword; + dwTime: longword); stdcall; +begin + killtimer; + eventlist.add(tmseevent.create(ek_timer)); +end; + +function gui_settimer(us: longword): guierrorty; + //send et_timer event after delay or us (micro seconds) +begin + killtimer; + timer:= windows.settimer(0,0,us div 1000,@timerproc); + if timer = 0 then begin + result:= gue_timer; + end + else begin + result:= gue_ok; + end; +end; +} +function gui_settimer(us: longword): guierrorty; + //send et_timer event after delay or us (micro seconds) +begin + result:= setsystimer(us); +end; + +procedure gui_beep; +begin + windows.MessageBeep($ffffffff); +end; + +procedure winrecttorect(const rect: rectty); overload; +begin + dec(pinteger(@rect.cx)^,rect.x); + dec(pinteger(@rect.cy)^,rect.y); +end; + +procedure winrecttorect(po: prectty; count: integer); overload; +begin + while count > 0 do begin + dec(po^.cx,po^.x); + dec(po^.cy,po^.y); + inc(po); + dec(count); + end; +end; + +procedure recttowinrect(const rect: rectty); overload; +begin + inc(pinteger(@rect.cx)^,rect.x); + inc(pinteger(@rect.cy)^,rect.y); +end; + +procedure recttowinrect(po: prectty; count: integer); overload; +begin + while count > 0 do begin + inc(po^.cx,po^.x); + inc(po^.cy,po^.y); + inc(po); + dec(count); + end; +end; +{ +function gui_creategc(paintdevice: paintdevicety; const akind: gckindty; + var gc: gcty; const aprintername: msestring = ''): guierrorty; +begin + result:= gdi32creategc(paintdevice,akind,gc,aprintername); +end; +} +function gui_flushgdi(const synchronize: boolean = false): guierrorty; +begin + gui_hasevent; //dispachevents + gdiflush; + result:= gue_ok; +end; + +procedure windowdestroyed(id: winidty); +begin + if mousewindow = id then begin + mousewindow:= 0; + end; + if lastfocuswindow = id then begin + lastfocuswindow:= 0; + end; + if groupleaderwindow = id then begin + groupleaderwindow:= 0; + end; +end; + +type + setwindowownerinfoty = record + oldowner,newowner: winidty; + end; + psetwindowownerinfoty = ^setwindowownerinfoty; + +function setwindowowner(id: hwnd; param: lparam): winbool; stdcall; + +begin + with psetwindowownerinfoty(ptruint(param))^ do begin + {$ifdef cpu64} + if getwindowlongptr(id,gwlp_hwndparent) = oldowner then begin + setwindowlongptr(id,gwlp_hwndparent,newowner); + end; + {$else} + if getwindowlong(id,gwl_hwndparent) = oldowner then begin + setwindowlong(id,gwl_hwndparent,newowner); + end; + {$endif} + end; + result:= true; +end; + +function gui_destroywindow(var awindow: windowty): guierrorty; +var + ico1: hicon; +// id1: winidty; + info: setwindowownerinfoty; +begin + with awindow do begin + if id <> 0 then begin +{$ifdef mse_debugwindowdestroy} + debugwindow('*gui_destroywindow ',awindow.id); +{$endif} + ico1:= sendmessage(id,wm_seticon,icon_big,0); + if ico1 <> 0 then begin + destroyicon(ico1); + end; + info.oldowner:= id; + {$ifdef cpu64} + info.newowner:= getwindowlongptr(id,gwlp_hwndparent); + {$else} + info.newowner:= getwindowlong(id,gwl_hwndparent); + {$endif} + enumwindows(@setwindowowner,ptruint(@info)); + //do not destroy children + if windows.DestroyWindow(id) then begin +{$ifdef mse_debuggdi} + dec(windowcount); +{$endif} + result:= gue_ok; + end + else begin //foreign thread + if windows.postthreadmessage(mainthread,destroymessage,id,0) then begin + result:= gue_ok; + end + else begin + result:= gue_destroywindow; + end; + end; + windowdestroyed(id); + end; + end; +end; + +function gui_showwindow(id: winidty): guierrorty; +begin + windows.showwindow(id,sw_shownoactivate); + result:= gue_ok; +end; + +function gui_hidewindow(id: winidty): guierrorty; +begin + windows.showwindow(id,sw_hide); + result:= gue_ok; +end; + +function gui_raisewindow(id: winidty; + const topmost: boolean = false): guierrorty; +var + w1: hwnd; +begin +{$ifdef mse_debugzorder} + if hwndtopmost then begin + debugwindow('gui_raisewindow topmost ',id); + end + else begin + debugwindow('gui_raisewindow ',id); + end; +{$endif} + if topmost then begin + w1:= hwnd_topmost; + end + else begin + w1:= hwnd_top; + end; + windows.SetWindowPos(id,w1,0,0,0,0,swp_noactivate or swp_nomove or + swp_noownerzorder or swp_nosize); + result:= gue_ok; +end; + +function gui_lowerwindow(id: winidty; const topmost: boolean): guierrorty; +var + w1: hwnd; +begin +{$ifdef mse_debugzorder} + if topmost then begin + debugwindow('gui_lowerwindow topmost ',id); + end + else begin + debugwindow('gui_lowerwindow ',id); + end; +{$endif} + if topmost then begin + w1:= hwnd_notopmost; + end + else begin + w1:= hwnd_bottom; + end; + windows.SetWindowPos(id,w1,0,0,0,0,swp_noactivate or swp_nomove or + swp_noownerzorder or swp_nosize); + result:= gue_ok; +end; + +function gui_stackunderwindow(id: winidty; predecessor: winidty): guierrorty; +begin +{$ifdef mse_debugzorder} + debugwindow('gui_stackunderwindow ',id,predecessor); +{$endif} + if id <> predecessor then begin + windows.SetWindowPos(id,predecessor,0,0,0,0,swp_noactivate or swp_nomove or + swp_noownerzorder or swp_nosize); + end; + result:= gue_ok; +end; + +function gui_stackoverwindow(id: winidty; predecessor: winidty): guierrorty; +var + id1: winidty; +begin +{$ifdef mse_debugzorder} + debugwindow('gui_stackoverwindow ',id,predecessor); +{$endif} + if id <> predecessor then begin + id1:= windows.GetWindow(predecessor,gw_hwndprev); + if id1 = 0 then begin + id1:= hwnd_top; + end; + windows.SetWindowPos(id,id1,0,0,0,0,swp_noactivate or swp_nomove or + swp_noownerzorder or swp_nosize); + end; + result:= gue_ok; +end; + +function gui_getzorder(const ids: winidarty; out zorders: integerarty): guierrorty; + //topevel -> highest, numbers must not be contiguous +var + int1,foundcount: integer; + id1: winidty; +begin + setlength(zorders,length(ids)); + foundcount:= 0; + id1:= gettopwindow(0); + while (foundcount <= high(ids)) and (id1 <> 0) do begin + for int1:= 0 to high(ids) do begin + if ids[int1] = id1 then begin + zorders[int1]:= -foundcount; + inc(foundcount); + break; + end; + end; + id1:= getnextwindow(id1,gw_hwndnext); + end; + if foundcount - 1 = high(ids) then begin + result:= gue_ok + end + else begin + result:= gue_windownotfound; + end; +{$ifdef mse_debugzorder} + debugwriteln('gui_getzorder '+getenumname(typeinfo(result),ord(result))); + for int1:= 0 to high(ids) do begin + debugwindow(inttostr(zorders[int1])+' ',ids[int1]); + end; +{$endif} +end; + +function gui_setwindowcaption(id: winidty; const caption: msestring): guierrorty; + procedure setcap(const id: winidty); + var + str1: string; + begin + if iswin95 then begin + str1:= ansistring(caption); + if windows.SetWindowTextA(id,pchar(str1)) then begin + result:= gue_ok; + end + end + else begin + if windows.SetWindowTextW(id,pwidechar(caption)) then begin + result:= gue_ok; + end + end; + end; +begin + result:= gue_error; + setcap(id); + if (id = groupleaderwindow) and (result = gue_ok) then begin + setcap(applicationwindow); + end; +end; + +function composeicon(const icon,mask: pixmapty): hicon; +var + iconinfo1: iconinfo; + maskbmp,iconbmp: hbitmap; + dc1,dc2,dc3: hdc; + bmpinfo: bitmapinfo; + bru1: hbrush; + rect1: trect; + info: pixmapinfoty; + mask1: pixmapty; + bmp1: tbitmap; +label + endlab; +begin + result:= 0; + if icon <> 0 then begin + mask1:= mask; + if mask1 <> 0 then begin + info.handle:= mask1; + if (gui_getpixmapinfo(info) = gde_ok) and (info.depth <> 1) then begin + bmp1:= tbitmap.create(bmk_mono); + try + bmp1.handle:= mask1; + bmp1.colorbackground:= cl_black; + bmp1.kind:= bmk_mono; + mask1:= bmp1.handle; + bmp1.releasehandle; + finally + bmp1.free; + end; + end; + end; + fillchar(bmpinfo,sizeof(bmpinfo),0); + with bmpinfo.bmiHeader do begin + bisize:= sizeof(bmpinfo.bmiheader); + dc1:= createcompatibledc(0); + if getdibits(dc1,icon,0,0,nil,bmpinfo,dib_rgb_colors) <> 0 then begin + dc2:= createcompatibledc(0); + maskbmp:= createbitmap(biwidth,biheight,1,1,nil); + selectobject(dc1,maskbmp); + if mask1 = 0 then begin + bru1:= createsolidbrush(0); + rect1.Left:= 0; + rect1.top:= 0; + rect1.right:= biwidth; + rect1.bottom:= 0; + fillrect(dc1,rect1,bru1); + deleteobject(bru1); + end + else begin + selectobject(dc2,mask1); //should not be selected in another dc + bitblt(dc1,0,0,biwidth,biheight,dc2,0,0,rasterops3[rop_copy]); + deletedc(dc2); + dc2:= createcompatibledc(0); + end; + end + else begin + deletedc(dc1); + goto endlab; + end; + dc3:= createcompatibledc(0); + selectobject(dc3,icon); //should not be selected in another dc + iconbmp:= createcompatiblebitmap(dc3,biwidth,biheight); + selectobject(dc2,iconbmp); + bitblt(dc2,0,0,biwidth,biheight,dc3,0,0,rasterops3[rop_copy]); + deletedc(dc3); + bitblt(dc2,0,0,biwidth,biheight,dc1,0,0,rasterops3[rop_notand]); + //icon out of mask1 -> 0; + deletedc(dc1); + deletedc(dc2); + with iconinfo1 do begin + ficon:= true; + xhotspot:= 0; + yhotspot:= 0; + hbmmask:= maskbmp; + hbmcolor:= iconbmp; + end; + result:= createiconindirect(iconinfo1); + deleteobject(maskbmp); + deleteobject(iconbmp); + end; +endlab: + if (mask1 <> mask) and (mask1 <> 0) then begin + deleteobject(mask1); + end; + end + else begin + result:= 0; + end; +end; + +function gui_setwindowicon(id: winidty; const icon,mask: pixmapty): guierrorty; +var + ico,ico1: hicon; +begin + result:= gue_error; + if icon <> 0 then begin + ico:= composeicon(icon,mask); + if ico = 0 then begin + exit; + end; + end + else begin + ico:= 0; + end; + ico1:= sendmessage(id,wm_seticon,icon_big,ico); + if ico1 <> 0 then begin + destroyicon(ico1); + end; + result:= gue_ok; +end; + +function gui_setwindowopacity(id: winidty; const opacity: real): guierrorty; +var + lo1: LONG; + f1: flo64; +begin + result:= gue_notsupported; + if haslayeredwindows then begin + lo1:= getwindowlong(id,gwl_exstyle); + if opacity = emptyreal then begin + lo1:= lo1 and not(ws_ex_layered); + setwindowlong(id,gwl_exstyle,lo1); + end + else begin + lo1:= lo1 or ws_ex_layered; + setwindowlong(id,gwl_exstyle,lo1); + f1:= opacity; + if f1 < 0 then begin + f1:= 0; + end + else begin + if f1 > 1 then begin + f1:= 1; + end; + end; + setlayeredwindowattributes(id,0,round(255*f1),LWA_ALPHA); + end; + result:= gue_ok; + end; +end; + +function gui_setapplicationicon(const icon,mask: pixmapty): guierrorty; +begin + result:= gui_setwindowicon(applicationwindow,icon,mask); +end; + +type + pidinfoty = record + pids: procidarty; + winid: winidty; + end; + ppidinfoty = ^pidinfoty; + +function checkproc(awinid: hwnd; po: ptrint): bool; stdcall; +var + pid: integer; + int1: integer; +begin + result:= true; + if getwindowlong(awinid,gwl_style) and windows.ws_visible <> 0 then begin + getwindowthreadprocessid(awinid,@pid); + with ppidinfoty(po)^ do begin + for int1:= 0 to high(pids) do begin + if pids[int1] = pid then begin + result:= false; + winid:= awinid; + break; + end; + end; + end; + end; +end; + +function gui_pidtowinid(const pids: procidarty): winidty; +var + info: pidinfoty; +begin + info.pids:= pids; + info.winid:= 0; + enumwindows(@checkproc,ptrint(@info)); + result:= info.winid; +end; + +function gui_rgbtopixel(rgb: longword): pixelty; +begin + result:= swaprgb(rgb); +end; + +function gui_pixeltorgb(pixel: pixelty): longword; +begin + result:= swaprgb(pixel); +end; + +function gui_graytopixel(gray: byte): pixelty; +var + lwo1: longword; +begin + lwo1:= gray; + result:= lwo1 or (lwo1 shl 8) or (lwo1 shl 16); +end; + +function gui_pixeltogray(pixel: pixelty): byte; +begin + result:= ((pixel and $ff) + ((pixel and $ff00) shr 8) + + ((pixel and $ff0000) shr 16)) div 3; +end; + +function winmousekeyflagstoshiftstate(keys: longword): shiftstatesty; +begin + result:= []; + if keys and mk_control <> 0 then begin + include(result,ss_ctrl); + end; + if keys and mk_lbutton <> 0 then begin + include(result,ss_left); + end; + if keys and mk_mbutton <> 0 then begin + include(result,ss_middle); + end; + if keys and mk_rbutton <> 0 then begin + include(result,ss_right); + end; + if keys and mk_shift <> 0 then begin + include(result,ss_shift); + end; + if getkeystate(vk_menu) < 0 then begin + include(result,ss_alt); + end; +end; + +function shiftstatetowinmousekeyflags(shiftstate: shiftstatesty): longword; +begin + result:= 0; + if ss_ctrl in shiftstate then begin + result:= result or mk_control; + end; + if ss_left in shiftstate then begin + result:= result or mk_lbutton; + end; + if ss_middle in shiftstate then begin + result:= result or mk_mbutton; + end; + if ss_right in shiftstate then begin + result:= result or mk_rbutton; + end; + if ss_shift in shiftstate then begin + result:= result or mk_shift; + end; +end; + +function winmousepostopoint(pos: longword): pointty; +begin + result.x:= smallint(loword(pos)); + result.y:= smallint(hiword(pos)); +end; + +function pointtowinmousepos(pos: pointty): longword; +begin + result:= word(pos.x) + (word(pos.y) shl 16); +end; + +function winkeytokey(key: longword; lparam: longword; + var shift: shiftstatesty): keyty; +var + second: boolean; +begin + second:= mapvirtualkey(key,mapvk_vk_to_vsc) <> (lparam shr 16) and $1ff; + + case key of + vk_back: result:= key_backspace; + vk_tab: begin + if ss_shift in shift then begin + result:= key_backtab; + end + else begin + result:= key_tab; + end; + end; + vk_clear: result:= key_clear; + vk_return: begin + result:= key_return; + if second then begin + include(shiftstate,ss_second); + end; + end; + vk_shift: begin + result:= key_shift; + if second then begin + include(shiftstate,ss_second); + end; + end; + vk_control: begin + result:= key_control; + if second then begin + include(shiftstate,ss_second); + end; + end; + vk_menu: begin + result:= key_alt; + if second then begin + include(shiftstate,ss_second); + end; + end; + vk_pause: result:= key_pause; + vk_capital: result:= key_capslock; + vk_escape: result:= key_escape; + vk_space: result:= key_space; + vk_prior: result:= key_pageup; + vk_next: result:= key_pagedown; + vk_end: result:= key_end; + vk_home: result:= key_home; + vk_left: result:= key_left; + vk_up: result:= key_up; + vk_right: result:= key_right; + vk_down: result:= key_down; + // vk_select: result:= key_select; + vk_execute: result:= key_sysreq; + vk_snapshot: result:= key_print; + vk_insert: result:= key_insert; + vk_delete: result:= key_delete; + vk_help: result:= key_help; + longword('0')..longword('9'): result:= keyty(key); + longword('A')..longword('Z'): result:= keyty(key); + vk_lwin: result:= key_super; + vk_rwin: begin + result:= key_super; + include(shiftstate,ss_second); + end; + vk_apps: result:= key_menu; + vk_oem_plus: result:= key_plus; + vk_oem_comma: result:= key_comma; + vk_oem_minus: result:= key_minus; + vk_oem_period: result:= key_period; + vk_numpad0..vk_numpad9: begin + result:= keyty(longword(key_0) + key - vk_numpad0); + include(shiftstate,ss_second); + end; + vk_add: begin + result:= key_plus; + include(shiftstate,ss_second); + end; + vk_separator: begin + result:= key_comma; + include(shiftstate,ss_second); + end; + vk_subtract: begin + result:= key_minus; + include(shiftstate,ss_second); + end; + vk_decimal: begin + result:= key_decimal; + include(shiftstate,ss_second); + end; + vk_multiply: begin + result:= key_asterisk; + include(shiftstate,ss_second); + end; + vk_divide: begin + result:= key_slash; + include(shiftstate,ss_second); + end; + vk_f1..vk_f24: result:= keyty(longword(key_f1) + key - vk_f1); + vk_numlock: result:= key_numlock; + vk_scroll: result:= key_scrolllock; + + else begin + result:= key_unknown; + end; + end; +end; + +function winkeystatetoshiftstate(keystate: longword): shiftstatesty; +begin + result:= []; + if $20000000 and keystate <> 0 then begin + include(result,ss_alt); + end; + if getkeystate(vk_shift) < 0 then begin + include(result,ss_shift); + end; + if getkeystate(vk_control) < 0 then begin + include(result,ss_ctrl); + end; + if getkeystate(vk_lbutton) < 0 then begin + include(result,ss_left); + end; + if getkeystate(vk_mbutton) < 0 then begin + include(result,ss_middle); + end; + if getkeystate(vk_rbutton) < 0 then begin + include(result,ss_right); + end; +end; + +function wheelkeystatetoshiftstate(keystate: longword): shiftstatesty; +var + wo1: word; +begin + result:= []; + wo1:= loword(keystate); + if mk_control and wo1 <> 0 then begin + include(result,ss_ctrl); + end; + if mk_lbutton and wo1 <> 0 then begin + include(result,ss_left); + end; + if mk_mbutton and wo1 <> 0 then begin + include(result,ss_middle); + end; + if mk_rbutton and wo1 <> 0 then begin + include(result,ss_right); + end; + if mk_shift and wo1 <> 0 then begin + include(result,ss_shift); + end; + if getkeystate(vk_menu) < 0 then begin + include(result,ss_alt); + end; +end; + +function windowvisible(handle: hwnd): boolean; +var + rect1: trect; +begin + windows.getclientrect(handle,rect1); + result:= iswindowvisible(handle) and + not ((rect1.Left = 0) and (rect1.Top = 0) + and (rect1.Bottom = 0) and (rect1.Right = 0)) and + (gui_getwindowsize(handle) <> wsi_minimized); +end; + +procedure checkmousewindow(window: hwnd; const pos: pointty); forward; + +procedure mouseidleproc(ahwnd: hwnd; uMsg: longword; idEvent: ptruint; + dwTime: longword); stdcall; +var + po1: tpoint; + win1: hwnd; +begin + windows.KillTimer(0,mouseidletimer); + mouseidletimer:= 0; + if mousewindow <> 0 then begin + if windows.GetCursorPos(po1) then begin + win1:= windowfrompoint(po1); + if (win1 <> mousewindow) and (getparent(win1) <> mousewindow) then begin + eventlist.add(twindowevent.create(ek_leavewindow,mousewindow)); + end + else begin + if windows.screentoclient(mousewindow,po1) then begin + checkmousewindow(mousewindow,pointty(po1)); + end; + end; + end; + end; +end; + +procedure killmouseidletimer(restart: boolean = false); +begin + if mouseidletimer <> 0 then begin + windows.KillTimer(0,mouseidletimer); + end; + if restart then begin + mouseidletimer:= windows.settimer(0,0,mouseidletime,@mouseidleproc); + end + else begin + mouseidletimer:= 0; + end; +end; + +procedure checkmousewindow(window: hwnd; const pos: pointty); +var + rect1: trect; +begin + killmouseidletimer(true); + if (window <> 0) then begin + windows.getclientrect(window,rect1); + if (pos.x < 0) or (pos.x >= rect1.Right) or (pos.y < 0) or + (pos.y > rect1.Bottom) then begin + window:= 0; + end + end; + if mousewindow <> window then begin + if mousewindow <> 0 then begin + eventlist.add(twindowevent.create(ek_leavewindow,mousewindow)); + end; + if window <> 0 then begin + eventlist.add(twindowevent.create(ek_enterwindow,window)); + end; + mousewindow:= window; + end + else begin + if mousecursor <> 0 then begin + windows.SetCursor(mousecursor); //possible missed et_exitwindow + end; + end; +end; + +function gui_movewindowrect(id: winidty; const dist: pointty; + const rect: rectty): guierrorty; +var + rect1,rect2: rectty; +begin + rect1:= rect; + recttowinrect(rect1); + if iswin95 then begin + rect2.x:= -32000; //trect + rect2.y:= -32000; + rect2.cx:= 32000; + rect2.cy:= 32000; + end + else begin + rect2.x:= -100000; //trect + rect2.y:= -100000; + rect2.cx:= 100000; + rect2.cy:= 100000; + end; + {$ifdef FPC} + winscrollwindowex(id,dist.x,dist.y,@rect1,@rect2,0,nil,sw_invalidate); + {$else} + scrollwindowex(id,dist.x,dist.y,@rect1,@rect2,0,nil,sw_invalidate); + {$endif} + result:= gue_ok; +end; + +procedure getframe(const outerrect,innerrect: trect; out frame: framety); +var + int1: integer; +begin + int1:= (outerrect.Right - outerrect.Left - innerrect.Right + + innerrect.left) div 2; //i hope so + with frame do begin + left:= int1; + bottom:= int1; + right:= int1; + top:= outerrect.Bottom - outerrect.top - + innerrect.Bottom + innerrect.Top - int1; + end; +end; + +function getclientrect(hwnd: hwnd; windowrect: prectty = nil): rectty; + //screen origin +var + rect1,rect2: trect; + frame: framety; +begin + if windows.GetWindowRect(hwnd,rect1) then begin + if windows.getclientrect(hwnd,rect2) then begin + getframe(rect1,rect2,frame); + if windowrect = nil then begin + result.x:= rect1.left + frame.left; + result.y:= rect1.top + frame.top; + result.size:= sizety(rect2.BottomRight); + end + else begin + with windowrect^ do begin + result.x:= x + frame.left; + result.y:= y + frame.top; + result.cx:= cx - frame.left - frame.right; + result.cy:= cy - frame.top - frame.bottom; + end; + end; + end + else begin + result:= nullrect; + end; + end + else begin + result:= nullrect; + end; +end; + +procedure getwindowrectpa(id: winidty; out rect: rectty; out origin: pointty); + //parent origin +var +// rect1: rectty; + win1: winidty; +begin + rect:= getclientrect(id); + win1:= getancestor(id,ga_parent); + if win1 <> 0 then begin + origin:= getclientrect(win1).pos; + subpoint1(rect.pos,origin); + end + else begin + origin:= nullpoint; + end; +end; + +function gui_getwindowrect(id: winidty; out rect: rectty): guierrorty; + //screen origin +begin + rect:= getclientrect(id); + result:= gue_ok; +end; + +function gui_getwindowpos(id: winidty; out pos: pointty): guierrorty; +var + rect1: trect; +begin + result:= gue_error; + if windows.GetWindowRect(id,rect1) then begin + pos.x:= rect1.left; + pos.y:= rect1.top; + result:= gue_ok; + end; +end; + +var + configuredwindow: winidty; + +procedure postconfigureevent(const id: winidty); +var + rect1: rectty; + pt1: pointty; +begin + configuredwindow:= id; + if gui_getwindowsize(id) <> wsi_minimized then begin + getwindowrectpa(id,rect1,pt1); + {$ifdef mse_debugconfigure} + debugwindow('*postconfigureevent x:'+inttostr(rect1.x)+' y:'+inttostr(rect1.y)+ + ' cx:'+inttostr(rect1.cx)+' cy:'+inttostr(rect1.cy)+ + ' ox:'+inttostr(pt1.x)+' oy:'+inttostr(pt1.y)+' ',id); + {$endif} + eventlist.add(twindowrectevent.create(ek_configure,id, + rect1,pt1)); + end + else begin + eventlist.add(twindowevent.create(ek_hide,id)); + end; +end; + +function gui_reposwindow(id: winidty; const rect: rectty): guierrorty; +var + rect1,rect2: trect; + arect: rectty; + frame: framety; +begin + result:= gue_resizewindow; + if windows.getwindowrect(id,rect1) then begin + if windows.GetclientRect(id,rect2) then begin + getframe(rect1,rect2,frame); + arect:= inflaterect(rect,frame); + {$ifdef mse_debugconfigure} + debugwindow('*reposwindow rect x:'+inttostr(rect.x)+' y:'+inttostr(rect.y)+ + ' cx:'+inttostr(rect.cx)+' cy:'+inttostr(rect.cy)+' ',id); + debugwriteln(' setwindowpos x:'+inttostr(arect.x)+' y:'+inttostr(arect.y)+ + ' cx:'+inttostr(arect.cx)+' cy:'+inttostr(arect.cy)+ + ' ancestor:'+inttostr(getancestor(id,ga_parent))+ + ' root:'+inttostr(getancestor(id,ga_root))); + {$endif} + configuredwindow:= 0; + if windows.SetWindowPos(id,0,arect.x,arect.y,arect.cx,arect.cy, + swp_nozorder or swp_noactivate) then begin + {$ifdef mse_debugconfigure} + windows.getwindowrect(id,@arect); + winrecttorect(arect); + debugwriteln(' getwindowpos x:'+inttostr(arect.x)+' y:'+inttostr(arect.y)+ + ' cx:'+inttostr(arect.cx)+' cy:'+inttostr(arect.cy)); + {$endif} + result:= gue_ok; + end; + end; + if configuredwindow <> id then begin + postconfigureevent(id); + end; + end; +end; + +function gui_getdecoratedwindowrect(id: winidty; out arect: rectty): guierrorty; +begin + if windows.getwindowrect(id,trect(arect)) then begin + winrecttorect(arect); + result:= gue_ok; + end + else begin + result:= gue_error; + end; +end; + +function gui_setdecoratedwindowrect(id: winidty; const rect: rectty; + out clientrect: rectty): guierrorty; +//var +// rect1: rectty; +begin + result:= gue_resizewindow; + clientrect:= rect; + if windows.SetWindowPos(id,0,rect.x,rect.y,rect.cx,rect.cy, + swp_nozorder or swp_noactivate) then begin + clientrect:= getclientrect(id); + result:= gue_ok; + end +end; + +function gui_setembeddedwindowrect(id: winidty; const rect: rectty): guierrorty; +begin + result:= gue_resizewindow; + if windows.SetWindowPos(id,0,rect.x,rect.y,rect.cx,rect.cy, + swp_nozorder or swp_noactivate) then begin + result:= gue_ok; + end +end; + +var + mousewheelpos: integer; + sizingwindow: hwnd; + eventlooping: integer; + escapepressed: boolean; + +function nestedwindowproc(): boolean; //window frame clicked +begin + result:= eventlooping > 0; +end; + +procedure gui_wakeup; +begin + windows.postmessage(applicationwindow,wakeupmessage,0,0); +// windows.postthreadmessage(mainthread,wakeupmessage,0,0); +end; + +function gui_postevent(event: tmseevent): guierrorty; +//var +// int1: integer; +begin + if windows.postmessage(applicationwindow,msemessage,ptruint(event),0) then begin + result:= gue_ok; + end + else begin + result:= gue_postevent; + end; +{ + if eventlooping > 0 then begin + result:= gue_ok; + eventlist.add(event); //threadmessages are lost while window sizing + end + else begin + result:= gue_postevent; + for int1:= 0 to 15 do begin + if windows.postthreadmessage(mainthread,msemessage,longword(event),0) then begin + result:= gue_ok; + break; + end; + sys_threadschedyield; + end; + end; + } +end; + +function gui_escapepressed: boolean; +begin + result:= escapepressed; +end; + +procedure gui_resetescapepressed; +begin + escapepressed:= false; +end; + +function WindowProc(ahWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; + + function checkbutton(const amessage: UINT): mousebuttonty; + begin + result:= mb_none; + case amessage of + wm_lbuttondown,wm_lbuttonup: result:= mb_left; + wm_mbuttondown,wm_mbuttonup: result:= mb_middle; + wm_rbuttondown,wm_rbuttonup: result:= mb_right; + end; + end; + + procedure inittraycallback(const reposition: boolean; out cursorpos: pointty; + out shiftstate: uint); + var + rect1: rectty; + pt1: pointty; + begin + shiftstate:= 0; + if getkeystate(vk_control) < 0 then begin + shiftstate:= shiftstate or mk_control; + end; + if getkeystate(vk_shift) < 0 then begin + shiftstate:= shiftstate or mk_shift; + end; + if getkeystate(vk_lbutton) < 0 then begin + shiftstate:= shiftstate or mk_lbutton; + end; + if getkeystate(vk_mbutton) < 0 then begin + shiftstate:= shiftstate or mk_mbutton; + end; + if getkeystate(vk_rbutton) < 0 then begin + shiftstate:= shiftstate or mk_rbutton; + end; + + windows.getcursorpos(tpoint(pt1)); + gui_getwindowrect(ahwnd,rect1); + {$ifdef mse_debugconfigure} + debugwindow('*inittraycallback ',ahwnd); + debugwriteln(' cursor x:'+inttostr(pt1.x)+' y:'+inttostr(pt1.y)); + {$endif} + cursorpos.x:= rect1.cx div 2; + cursorpos.y:= rect1.cy div 2; + if reposition then begin + gui_reposwindow(ahwnd,makerect(pt1.x-cursorpos.x,pt1.y-cursorpos.y, + rect1.cx,rect1.cy)); + //shift widget center to mousepos +// setforegroundwindow(applicationwindow); + end; + end; + +const + wheelstep = 120; +var + rect1,rect2,rect3: rectty; + pt1{,pt2}: pointty; + size1: sizety; + button: mousebuttonty; + key1: keyty; + str1: string; +// int1: integer; + bo1: boolean; + sysevent: syseventty; + shiftstate1: uint; + imc: himc; + imminfo: compositionform; + ev1: tmseevent; +label + nodefwindowproclab; +begin + if application.ismainthread then begin + sysevent.hwnd:= ahwnd; + sysevent.umsg:= msg; + sysevent.wparam:= wparam; + sysevent.lparam:= lparam; + sysevent.lresult:= 0; + bo1:= false; + tapplication1(application).sysevent(ahwnd,sysevent,bo1); + if bo1 then begin + result:= sysevent.lresult; + exit; + end; + end; + result:= 1; + case msg of + msemessage: begin + eventlist.add(tmseevent(wparam)); + exit; + end; + wakeupmessage: begin + eventlist.add(nil); + exit; + end; + timermessage: begin + eventlist.add(tmseevent.create(ek_timer)); + exit; + end; + traycallbackmessage: begin + case lparam and $ffff of + wm_lbuttondown,wm_mbuttondown,wm_rbuttondown: begin + inittraycallback(true,pt1,shiftstate1); + windowproc(ahwnd,lparam and $ffff,shiftstate1,pointtowinmousepos(pt1)); + end; + wm_lbuttonup,wm_mbuttonup,wm_rbuttonup: begin + inittraycallback(true,pt1,shiftstate1); + windowproc(ahwnd,lparam and $ffff,shiftstate1,pointtowinmousepos(pt1)); + end; + end; + end; + wm_ime_char: begin + if iswin95 then begin + str1:= char(wparam); + if wparam and $ff00 <> 0 then begin + str1:= char(wparam shr 8) + str1; + end; + charbuffer:= charbuffer + msestring(str1); + end + else begin + charbuffer:= charbuffer + ucs4tostring(wparam); + end; + eventlist.add(tkeyevent.create(ahwnd,false,key_none,key_none,shiftstate, + charbuffer,timestamp)); + charbuffer:= ''; + end; + wm_close: begin + if ahwnd = applicationwindow then begin + eventlist.add(tmseevent.create(ek_terminate)); + end + else begin + eventlist.add(twindowevent.create(ek_close,ahwnd)); + result:= 0; + end; + exit; + end; + wm_queryendsession: begin + canshutdown:= 1; + eventlist.add(tmseevent.create(ek_terminate)); + tapplication1(application).eventloop; + result:= canshutdown; + exit; + end; + wm_destroy: begin + {$ifdef mse_debugwindowfocus} + debugwindow('wm_destroy ',ahwnd); + {$endif} + {$ifdef mse_debugwindowdestroy} + debugwindow('*wm_destroy ',ahwnd); + {$endif} + windowdestroyed(ahwnd); + eventlist.add(twindowevent.create(ek_destroy,ahwnd)); + end; + wm_setfocus: begin + if (ahwnd = applicationwindow) and (lastfocuswindow <> 0) then begin + {$ifdef mse_debugwindowfocus} + debugwindow('wm_setfocus applicationwindow ',ahwnd); + {$endif} + if windowvisible(lastfocuswindow) then begin + setfocus(lastfocuswindow); + end + else begin + if application.activewindow <> nil then begin + setfocus(application.activewindow.winid); + end + else begin + if application.mainwindow <> nil then begin + setfocus(application.mainwindow.winid); + end; + end; + end; + end + else begin + if windowvisible(ahwnd) then begin + {$ifdef mse_debugwindowfocus} + debugwindow('wm_setfocus ',ahwnd); + {$endif} + lastfocuswindow:= ahwnd; + eventlist.add(twindowevent.create(ek_focusin,ahwnd)); + end{$ifndef mse_debugwindowfocus};{$endif} + {$ifdef mse_debugwindowfocus} + else begin + debugwindow('wm_setfocus invisible ',ahwnd); + end; + {$endif} + end; + end; + wm_killfocus: begin + ev1:= twindowevent.create(ek_focusout,ahwnd); + eventlist.add(ev1); + {$ifdef mse_debugwindowfocus} + debugwindow('wm_killfocus '+hextostr(ev1)+' ',ahwnd); + {$endif} + end; + wm_paint: begin + if getupdaterect(ahwnd,trect(rect1),false) then begin + winrecttorect(rect1); + eventlist.add(twindowrectevent.create(ek_expose,ahwnd,rect1,nullpoint)); +// exit; + end; + end; + wm_entersizemove: begin + sizingwindow:= ahwnd; + end; + wm_exitsizemove: begin + sizingwindow:= 0; + end; + wm_sizing: begin + rect1:= rectty(prect(lparam)^); + winrecttorect(rect1); + rect2:= getclientrect(ahwnd,@rect1); + rect3:= rect2; + application.checkwindowrect(ahwnd,rect2); + size1:= subsize(rect3.size,rect2.size); + if (wparam = wmsz_topleft) or (wparam = wmsz_left) or + (wparam = wmsz_bottomleft) then begin + inc(rect1.x,size1.cx); + end; + dec(rect1.cx,size1.cx); + if (wparam = wmsz_topleft) or (wparam = wmsz_top) or + (wparam = wmsz_topright) then begin + inc(rect1.y,size1.cy); + end; + dec(rect1.cy,size1.cy); + recttowinrect(rect1); + rect2:= rectty(prect(lparam)^); + rectty(prect(lparam)^):= rect1; + if not rectisequal(rect2,rectty(prect(lparam)^)) then begin + exit; + end; + end; + wm_move,wm_size: begin + postconfigureevent(ahwnd); + end; + wm_queryopen: begin + eventlist.add(twindowevent.create(ek_show,ahwnd)); + end; + wm_windowposchanged: begin + with pwindowpos(lparam)^ do begin + if swp_hidewindow and flags <> 0 then begin + {$ifdef mse_debugwindowfocus} + debugwindow('wm_windowposchanged hide ',ahwnd); + {$endif} + eventlist.add(twindowevent.create(ek_hide,ahwnd)); + end; + if (swp_showwindow and flags <> 0) and (gui_getwindowsize(ahwnd) <> wsi_minimized) then begin + {$ifdef mse_debugwindowfocus} + debugwindow('wm_windowposchanged show ',ahwnd); + {$endif} + eventlist.add(twindowevent.create(ek_show,ahwnd)); + end; + if (((swp_nomove or swp_nosize) and flags <> (swp_nomove or swp_nosize)) or + (flags and swp_nozorder = 0)) and + windowvisible(ahwnd) then begin + postconfigureevent(ahwnd); +// getwindowrectpa(ahwnd,rect1,pt1); +// eventlist.add(twindowrectevent.create(ek_configure,ahwnd,rect1,pt1)); + result:= 0; + exit; + end; + end; + end; + wm_mousewheel: begin + if mousewindow <> 0 then begin + shiftstate:= wheelkeystatetoshiftstate(wparam); + pt1:= winmousepostopoint(lparam); + subpoint1(pt1,getclientrect(mousewindow).pos); + inc(mousewheelpos,smallint(hiword(wparam))); + while mousewheelpos >= wheelstep do begin + eventlist.add(tmouseevent.create(mousewindow,false,mb_none,mw_up,pt1, + winmousekeyflagstoshiftstate(wparam),timestamp)); + dec(mousewheelpos,wheelstep); + end; + while mousewheelpos <= -wheelstep do begin + eventlist.add(tmouseevent.create(mousewindow,false,mb_none,mw_down,pt1, + winmousekeyflagstoshiftstate(wparam),timestamp)); + inc(mousewheelpos,wheelstep); + end; + result:= 0; + exit; + end; + end; + wm_mousemove, + wm_lbuttondown,wm_mbuttondown,wm_rbuttondown, + wm_lbuttonup,wm_mbuttonup,wm_rbuttonup: begin + pt1:= winmousepostopoint(lparam); + checkmousewindow(ahwnd,pt1); + button:= checkbutton(msg); + eventlist.add(tmouseevent.create(ahwnd, + (msg = wm_lbuttonup) or (msg = wm_mbuttonup) or (msg = wm_rbuttonup), + button,mw_none,pt1, + winmousekeyflagstoshiftstate(wparam),timestamp)); + result:= 0; + exit; + end; + wm_keydown,wm_syskeydown: begin + shiftstate:= winkeystatetoshiftstate(lparam); + if lparam and $40000000 <> 0 then begin + include(shiftstate,ss_repeat); + end; + key1:= winkeytokey(wparam,lparam,shiftstate); + if key1 = key_escape then begin + escapepressed:= true; + end; + eventlist.add(tkeyevent.create(ahwnd,false,key1,key1,shiftstate, + charbuffer,timestamp)); + charbuffer:= ''; + if (shiftstate = []) and (key1 = key_f10) then begin + goto nodefwindowproclab; //no windows menu activation + end; + end; + wm_keyup,wm_syskeyup: begin + shiftstate:= winkeystatetoshiftstate(lparam); + key1:= winkeytokey(wparam,lparam,shiftstate); + if charbuffer <> '' then begin + eventlist.add(tkeyevent.create(ahwnd,false,key_none,key_none,shiftstate, + charbuffer,timestamp)); + charbuffer:= ''; + end; + eventlist.add(tkeyevent.create(ahwnd,true,key1,key1,shiftstate,'',timestamp)); + end; + wm_ime_startcomposition: begin + if hasimm32 and (application.activewidget <> nil) and + application.activewidget.hascaret then begin + imc:= immgetcontext(ahwnd); + fillchar(imminfo,sizeof(imminfo),0); + with imminfo,application do begin + dwstyle:= cfs_point; + ptcurrentpos.x:= caret.pos.x + caret.origin.x; + ptcurrentpos.y:= caret.pos.y + caret.origin.y{ + caret.size.cy}; +// ptcurrentpos.x:= caret.pos.x + activewidget.rootpos.x; +// ptcurrentpos.y:= activewidget.rootpos.y + activewidget.bounds_cy; + immsetcompositionwindow(imc,@imminfo); + end; + immreleasecontext(ahwnd,imc); + end; + end; + end; + if iswin95 then begin + result:= defwindowproca(ahwnd,msg,wparam,lparam); + end + else begin + result:= defwindowprocw(ahwnd,msg,wparam,lparam); + end; +nodefwindowproclab: + if ahwnd = sizingwindow then begin + inc(eventlooping); + try + tapplication1(application).eventloop(true); + finally + dec(eventlooping); + end; + end; +end; + +function childWindowProc(ahWnd: HWND; Msg: UINT; wParam: WPARAM; + lParam: LPARAM): LRESULT; stdcall; +var + parent: hwnd; + pt1: pointty; + rect1: trect; + rect2: rectty; +begin + parent:= getparent(ahwnd); + case msg of + wm_destroy: begin + windowdestroyed(ahwnd); + eventlist.add(twindowevent.create(ek_destroy,ahwnd)); + end; + wm_mousemove, + wm_lbuttondown,wm_mbuttondown,wm_rbuttondown, + wm_lbuttonup,wm_mbuttonup,wm_rbuttonup, + wm_mousewheel: begin + getwindowrect(ahwnd,rect1); + rect2:= getclientrect(parent); + pt1.x:= rect1.left - rect2.x; + pt1.y:= rect1.top - rect2.y; + pt1:= addpoint(winmousepostopoint(lparam),pt1); + result:= windowproc(parent,msg,wparam,pointtowinmousepos(pt1)); + exit; + end; + end; + if iswin95 then begin + result:= defwindowproca(ahwnd,msg,wparam,lparam); + end + else begin + result:= defwindowprocw(ahwnd,msg,wparam,lparam); + end; +end; + +var + sdndthread: threadty; + +procedure beginsdndwrite(const athread: threadty); +begin + application.lock; + sdndthread:= athread; + application.unlock; +end; + +procedure endsdndwrite; +begin + application.lock; + sdndthread:= 0; + application.unlock; +end; + +procedure dispatchevents; +var + msg,msg1: tmsg; + str1: string; +begin + if eventlooping > 0 then begin + exit; + end; + if iswin95 then begin + while peekmessagea(msg,0,0,0,pm_remove) do begin + if sdndthread <> 0 then begin + postthreadmessagea(sdndthread,msg.message,msg.wparam,msg.lparam); + end; + with msg do begin + case message of + destroymessage: begin + windows.destroywindow(msg.wparam); + end; + wm_keydown,wm_keyup,wm_syskeydown,wm_syskeyup: begin + translatemessage(msg); + str1:= ''; + while peekmessagea(msg1,msg.hwnd,wm_char,wm_char,pm_remove) do begin + str1:= str1 + char(msg1.wparam); + end; + while peekmessagea(msg1,msg.hwnd,wm_syschar,wm_syschar,pm_remove) do begin + str1:= str1 + char(msg1.wparam); + end; + charbuffer:= charbuffer + msestring(str1); + dispatchmessagea(msg); + end + else begin + dispatchmessagea(msg); + end; + end; + end; + end; + end + else begin + while peekmessagew(msg,0,0,0,pm_remove) do begin + if sdndthread <> 0 then begin + postthreadmessagew(sdndthread,msg.message,msg.wparam,msg.lparam); + end; + with msg do begin + case message of + destroymessage: begin + {$ifdef mse_debugwindowdestroy} + debugwindow('*destroymessage ',msg.wparam); + {$endif} + windows.destroywindow(msg.wparam); + end; + wm_keydown,wm_keyup,wm_syskeydown,wm_syskeyup: begin + translatemessage(msg); + while peekmessagew(msg1,msg.hwnd,wm_char,wm_char,pm_remove) do begin + charbuffer:= charbuffer + msechar(msg1.wparam); + end; + while peekmessagew(msg1,msg.hwnd,wm_syschar,wm_syschar,pm_remove) do begin + charbuffer:= charbuffer + msechar(msg1.wparam); + end; + dispatchmessagew(msg); + end + else begin + dispatchmessagew(msg); + end; + end; + end; + end; + end; +end; + +function gui_hasevent: boolean; +begin + dispatchevents; + result:= eventlist.count > 0; +end; + +function gui_getevent: tmseevent; +begin + result:= nil; + while true do begin + dispatchevents; + if eventlist.count > 0 then begin + result:= tmseevent(eventlist.getfirst); + break; + end + else begin + if not application.unlock then begin + guierror(gue_notlocked); + end; + windows.waitmessage; + application.lock; + end; + end; +end; + +procedure gui_disconnectmaineventqueue(); //called by application.lock() +begin + //dummy +end; + +procedure gui_connectmaineventqueue(); //called by application.unlock() +begin + //dummy +end; + +function gui_addpollfd(var id: int32; const afd: int32; + const aflags: pollflagsty; + const acallback: pollcallbackty = nil; + const adata: pointer = nil): guierrorty; +begin + result:= gue_notimplemented; +end; + +function gui_removepollfd(const id: int32): guierrorty; +begin + result:= gue_notimplemented; +end; + +function gui_setpollfdactive(const id: int32; + const aactive: boolean): guierrorty; +begin + result:= gue_notimplemented; +end; + +function createapphandle(out id: winidty): guierrorty; +var + str1: string; + menu1: hmenu; +begin + str1:= ansistring(application.applicationname); + id:= windows.CreateWindow(widgetclassname,pchar(str1), + WS_POPUP or WS_CAPTION or WS_CLIPSIBLINGS or + WS_SYSMENU or WS_MINIMIZEBOX,0,0,0,0,0,0,hinstance,nil); +{$ifdef mse_debugwindowdestroy} + debugwindow('ceateapphandle ',id); +{$endif} + menu1:= getsystemmenu(id,false); + deletemenu(menu1,sc_maximize,mf_bycommand); + deletemenu(menu1,sc_size,mf_bycommand); + deletemenu(menu1,sc_move,mf_bycommand); + showwindow(id,sw_shownoactivate); + +// id:= windows.CreateWindowex(ws_ex_appwindow,widgetclassname,pchar(str1), +// ws_overlappedwindow,0,0,0,0,0,0,hinstance,nil); + if id = 0 then begin + result:= gue_createwindow; + end + else begin + result:= gue_ok; + end; +end; + +function gui_settransientfor(var awindow: windowty; + const transientfor: winidty): guierrorty; +begin + with awindow,win32windowty(platformdata).d do begin + if not istaskbar then begin + {$ifdef cpu64} + setwindowlongptr(id,gwlp_hwndparent,transientfor); + //no taskbar widget if called! + {$else} + setwindowlong(id,gwl_hwndparent,transientfor); //no taskbar widget if called! + {$endif} +// transientfor can be destroyed + end; + end; + result:= gue_ok; +end; + +function gui_windowatpos(const pos: pointty): winidty; +begin + result:= windowfrompoint(tpoint(pos)); +end; + +function gui_setsizeconstraints(id: winidty; const min,max: sizety): guierrorty; +begin + result:= gue_ok; //nothing to do on win32 +end; + +function gui_setwindowgroup(id: winidty; group: winidty): guierrorty; +begin + result:= gue_ok; +end; + +function gui_createwindow(const rect: rectty; + var options: internalwindowoptionsty; + var awindow: windowty): guierrorty; +var + windowstyle,windowstyleex,ca2: longword; + rect1: rectty; + classname: string; + ownerwindow: winidty; +begin + fillchar(awindow,sizeof(awindow),0); + with awindow,win32windowty(awindow.platformdata).d,options do begin + ownerwindow:= applicationwindow; + windowstyleex:= 0; + { + if wo_popup in options then begin //does not work in win2000 + windowstyleex:= windowstyleex or ws_ex_noactivate; + end; + } + if wo_notaskbar in options then begin + showwindow(applicationwindow,sw_hide); + end; + if options * noframewindowtypes <> [] then begin + windowstyle:= ws_popup; +// windowstyleex:= windowstyleex or ws_ex_toolwindow; + end + else begin + if wo_message in options then begin + windowstyle:= ws_overlappedwindow; + windowstyleex:= windowstyleex or ws_ex_toolwindow; + end + else begin + windowstyle:= ws_overlappedwindow; + if wo_taskbar in options then begin + istaskbar:= true; + windowstyleex:= windowstyleex or ws_ex_appwindow; + showwindow(applicationwindow,sw_hide); + ownerwindow:= 0; + end; + end; + if wo_embedded in options then begin + windowstyle:= ws_child; + end; + end; + if pos = wp_default then begin + rect1.x:= integer(cw_usedefault); + rect1.y:= integer(cw_usedefault); + rect1.cx:= integer(cw_usedefault); + rect1.cy:= integer(cw_usedefault); + end + else begin + rect1:= rect; + end; + windowstyle:= windowstyle or ws_clipchildren; + if (transientfor <> 0) or (options * [wo_popup,wo_message,wo_notaskbar] <> []) then begin + if transientfor <> 0 then begin + ownerwindow:= transientfor; + end; + id:= windows.CreateWindowex(windowstyleex,widgetclassname,nil,windowstyle, + rect1.x,rect1.y,rect1.cx,rect1.cy,ownerwindow{transientfor},0,hinstance,nil); + if transientfor = 0 then begin +{$ifdef mse_debugzorder} + debugwriteln('gui_createwindow hwnd_top '+hextostr(id)); +{$endif} + setwindowpos(id,hwnd_top,0,0,0,0,swp_noactivate or swp_nomove or + swp_nosize or swp_noownerzorder); + end; + end + else begin + if parent <> 0 then begin + ca2:= parent; + windowstyle:= ws_child; + classname:= childwidgetclassname; + end + else begin + ca2:= ownerwindow; + classname:= widgetclassname; + end; + id:= windows.CreateWindowex(windowstyleex,pchar(classname),nil, + windowstyle,rect1.x,rect1.y,rect1.cx,rect1.cy,ca2,0,hinstance,nil); + if setgroup and (groupleader = 0) or (wo_groupleader in options) then begin + groupleaderwindow:= id; + end; + end; + if id = 0 then begin + result:= gue_createwindow; + end + else begin +{$ifdef mse_debugwindowdestroy} + debugwindow('gui_createwindow ',id); +{$endif} +{$ifdef mse_debuggdi} + inc(windowcount); +{$endif} + if not (pos = wp_default) and (parent = 0) then begin + result:= gui_reposwindow(id,rect); + end + else begin + result:= gue_ok; + end; + end; + if icon <> 0 then begin + gui_setwindowicon(id,icon,iconmask); + if (groupleaderwindow = id) then begin + gui_setwindowicon(applicationwindow,icon,iconmask); + end; + end; + if wo_sysdnd in options then begin + regsysdndwindow(id); + end; + end; +end; + +function gui_getrootwindow(id: winidty = 0): winidty; +begin + result:= 0; +end; + +function gui_getparentwindow(const awindow: winidty): winidty; +begin +// result:= getparent(awindow); + result:= getancestor(awindow,ga_parent); +end; + +function gui_reparentwindow(const child: winidty; const parent: winidty; + const pos: pointty): guierrorty; +var + rect1: rectty; +begin + result:= gue_reparent; + if setparent(child,parent) <> 0 then begin + if parent = 0 then begin + result:= gui_getwindowrect(child,rect1); + if result = gue_ok then begin + rect1.pos:= pos; + result:= gui_reposwindow(child,rect1); + end; + end + else begin + if setwindowpos(child,0,pos.x,pos.y,0,0,swp_nosize or swp_nozorder or + swp_noownerzorder or swp_noactivate) then begin + result:= gue_ok; + end; + end; + end; +end; + +type + enumchildinfoty = record + childlist: winidarty; + count: integer; + parent: winidty; + end; + penumchildinfoty = ^enumchildinfoty; + +function getchildren(child: hwnd; data: lparam): winbool; stdcall; +begin + with penumchildinfoty(data)^ do begin + if gui_getparentwindow(child) = parent then begin + additem(childlist,winidty(child),count); + end; + end; + result:= true; +end; + +function gui_getchildren(const id: winidty; out children: winidarty): guierrorty; +var + info: enumchildinfoty; +begin + fillchar(info,sizeof(info),0); + with info do begin + parent:= id; + enumchildwindows(id,@getchildren,ptruint(@info)); + setlength(childlist,count); + children:= childlist; + end; + result:= gue_ok; +end; + +function gui_setmainthread: guierrorty; //set mainthread to currentthread +begin + mainthread:= threadty(getcurrentthreadid); + result:= gue_ok; +end; + +function gui_getscreenrect(const id: winidty): rectty; //0 -> virtual screen +var + info: tmonitorinfo; +begin + info.cbsize:= sizeof(info); + if (id = 0) or not getmonitorinfo(monitorfromwindow(id,monitor_defaulttonearest), + @info) then begin + result.x:= getsystemmetrics(sm_xvirtualscreen); + result.y:= getsystemmetrics(sm_yvirtualscreen); + result.cx:= getsystemmetrics(sm_cxvirtualscreen); + result.cy:= getsystemmetrics(sm_cyvirtualscreen); + if result.cx = 0 then begin + result.cx:= getsystemmetrics(sm_cxscreen) + end; + if result.cy = 0 then begin + result.cy:= getsystemmetrics(sm_cyscreen) + end; + end + else begin + result:= rectty(info.rcmonitor); + winrecttorect(result); + end; +end; + +function gui_getworkarea(id: winidty): rectty; +var + info: tmonitorinfo; +begin +// if systemparametersinfo(spi_getworkarea,0,@result,0) then begin + info.cbsize:= sizeof(info); + if getmonitorinfo(monitorfromwindow(id,monitor_defaulttonearest), + @info) then begin + result:= rectty(info.rcwork); + winrecttorect(result); + end + else begin + result:= nullrect; + end; +end; + +procedure gui_getppmm(id: winidty; out appmmwidth,appmmheight: flo64); + //0.0 if not supported +var + dc: hdc; +begin + appmmwidth:= 0; + appmmheight:= 0; + dc:= getdc(id); + if dc <> 0 then begin + appmmwidth:= getdevicecaps(dc,logpixelsx) / 25.4; + appmmheight:= getdevicecaps(dc,logpixelsy) / 25.4; + releasedc(id,dc); + end; +end; + +const + NIF_MESSAGE = $00000001; + NIF_ICON = $00000002; + NIF_TIP = $00000004; + NIF_STATE = $00000008; + NIF_INFO = $00000010; + NIF_GUID = $00000020; + + NIIF_NONE = $00000000; + NIIF_INFO = $00000001; + NIIF_WARNING = $00000002; + NIIF_ERROR = $00000003; + NIIF_USER = $00000004; + NIIF_NOSOUND = $00000010; + NIIF_LARGE_ICON = $00000010; + NIIF_RESPECT_QUIET_TIME = $00000080; + NIIF_ICON_MASK = $0000000F; + + NIM_ADD = $00000000; + NIM_MODIFY = $00000001; + NIM_DELETE = $00000002; + NIM_SETFOCUS = $00000003; + NIM_SETVERSION = $00000004; + +type + iconunionty = record + case boolean of + false: (uTimeout: UINT); + true: (uVersion: UINT); // Used with Shell_NotifyIcon flag NIM_SETVERSION. + end; + NOTIFYICONDATAW_2 = record + cbSize: DWORD; + Wnd: HWND; + uID: UINT; + uFlags: UINT; + uCallbackMessage: UINT; + hIcon: HICON; + szTip: array [0..127] of widechar; + dwState: DWORD; + dwStateMask: DWORD; + szInfo: array[0..255] of widechar; + u: iconunionty; + szInfoTitle: array[0..63] of widechar; + dwInfoFlags: DWORD; + end; + +function traycommand(var child: windowty; + const command: integer; const flags: integer = 0; + const CallbackMessage: UINT = 0; + const Icon: HICON = 0; + const Tip: msestring = ''; + const State: DWORD = 0; + const StateMask: DWORD = 0; + const Info: msestring = ''; + const Timeout: UINT = 0; + const Version: UINT = 0; + const InfoTitle: msestring = ''; + const InfoFlags: DWORD = 0): guierrorty; + +// traycommand(child,command,flags,0,0,'',0,0,'',0,0,'',0); + + procedure movestr(const source: msestring; var dest; const acount: integer); + var + int1: integer; + begin + int1:= length(source); + if int1 > acount then begin + int1:= acount; + end; + move(source[1],dest,int1*sizeof(widechar)); + end; + +var +// dataa: notifyicondataa; + dataw: notifyicondataw_2; +// int1: integer; +begin + result:= checkshellinterface; + if result = gue_ok then begin + result:= gue_notraywindow; + if iswin95 then begin + end + else begin + fillchar(dataw,sizeof(dataw),0); + with dataw do begin + cbsize:= sizeof(dataw); + wnd:= child.id; + uflags:= flags; + uCallbackMessage:= CallbackMessage; + hIcon:= Icon; + movestr(tip,szTip,sizeof(szTip)); + dwState:= State; + dwStateMask:= StateMask; + movestr(Info,szInfo,256); + if command = nim_setversion then begin + u.uVersion:= version; + end + else begin + u.uTimeout:= Timeout; + end; + movestr(InfoTitle,szInfoTitle,64); + dwInfoFlags:= InfoFlags; + end; + if shell_notifyiconw(command,@dataw) then begin + result:= gue_ok; + end; + end; + end; +end; + +function docktotray(var child: windowty): guierrorty; +begin + result:= traycommand(child,nim_add,nif_message,traycallbackmessage); + if result = gue_ok then begin + result:= traycommand(child,nim_setversion,0,0,0,'',0,0,'',0,0); + end; +end; + +function undockfromtray(var child: windowty): guierrorty; +begin + result:= traycommand(child,nim_delete); +end; + +function gui_showsysdock(var awindow: windowty): guierrorty; +begin + result:= gui_hidewindow(awindow.id); +end; + +function gui_hidesysdock(var awindow: windowty): guierrorty; +begin + result:= gui_hidewindow(awindow.id); +end; + +function gui_docktosyswindow(var child: windowty; + const akind: syswindowty): guierrorty; +var + rect1: rectty; + pt1: pointty; +begin + gui_hidewindow(child.id); + if akind = sywi_none then begin + result:= undockfromtray(child); + getwindowrectpa(child.id,rect1,pt1); + result:= gui_reparentwindow(child.id,0,subpoint(rect1.pos,pt1)); + end + else begin + result:= gue_windownotfound; + case akind of + sywi_tray: begin + result:= docktotray(child); + end; + end; + end; +end; +{ +function gui_undockfromsyswindow(var child: windowty): guierrorty; + //hides window +begin + gui_hidewindow(child.id); + result:= undockfromtray(child); +end; +} +function gui_traymessage(var awindow: windowty; const message: msestring; + out messageid: longword; + const timeoutms: longword = 0): guierrorty; +var + int1: integer; +begin + messageid:= 1; + int1:= timeoutms; + if timeoutms = 0 then begin + int1:= bigint; + end; + result:= traycommand(awindow,nim_modify,nif_info,0,0,'',0,0, + message,int1,0,'',0); +end; + +function gui_canceltraymessage(var awindow: windowty; + const messageid: longword): guierrorty; +begin + result:= traycommand(awindow,nim_modify,nif_info,0,0,'',0,0, + '',0,0,'',0); +end; + +function gui_settrayicon(var awindow: windowty; + const icon,mask: pixmapty): guierrorty; +var + ico{,ico1}: hicon; +begin + ico:= 0; + if icon <> 0 then begin + ico:= composeicon(icon,mask); + if ico = 0 then begin + exit; + end; + end; + result:= traycommand(awindow,nim_modify,nif_icon,0,ico); +end; + +function gui_settrayhint(var awindow: windowty; + const hint: msestring): guierrorty; +begin + result:= traycommand(awindow,nim_modify,nif_tip,0,0,hint); +end; + +function gui_initcolormap: guierrorty; +begin + result:= gue_ok; //dummy +end; + +function gui_init: guierrorty; +const +// classstyle = cs_owndc; //not possible with layered windows + classstyle = 0; + childclassstyle = 0; +var + classinfow: twndclassw; + classinfoa: twndclassa; +// hres1: hresult; + +begin + mousewindow:= 0; + mousecursor:= 0; + applicationwindow:= 0; + fillchar(keystate,sizeof(keystate),0); + shiftstate:= []; + charbuffer:= ''; + gui_setmainthread; + eventlist:= tobjectqueue.create(true); + desktopwindow:= getdesktopwindow; + + msegdi32gdi.init; + + fillchar(classinfoa,sizeof(classinfoa),0); + if iswin95 then begin + with classinfoa do begin + lpszclassname:= childwidgetclassname; + lpfnwndproc:= @childwindowproc; + hinstance:= {$ifdef FPC}system{$else}sysinit{$endif}.HInstance; + style:= childclassstyle; + cbwndextra:= wndextrabytes; + end; + childwidgetclass:= registerclassa(classinfoa); + fillchar(classinfoa,sizeof(classinfoa),0); + with classinfoa do begin + lpszclassname:= widgetclassname; + lpfnwndproc:= @windowproc; + hinstance:= {$ifdef FPC}system{$else}sysinit{$endif}.HInstance; + style:= classstyle; + cbwndextra:= wndextrabytes; + end; + widgetclass:= registerclassa(classinfoa); + end + else begin + fillchar(classinfow,sizeof(classinfow),0); + with classinfow do begin + lpszclassname:= childwidgetclassname; + lpfnwndproc:= @childwindowproc; + hinstance:= {$ifdef FPC}system{$else}sysinit{$endif}.HInstance; + style:= childclassstyle; + cbwndextra:= wndextrabytes; +// hbrbackground:= getstockobject(hollow_brush); + end; + childwidgetclass:= registerclassw(classinfow); + fillchar(classinfow,sizeof(classinfow),0); + with classinfow do begin + lpszclassname:= widgetclassname; + lpfnwndproc:= @windowproc; + hinstance:= {$ifdef FPC}system{$else}sysinit{$endif}.HInstance; + style:= classstyle; + cbwndextra:= wndextrabytes; + end; + widgetclass:= registerclassw(classinfow); + end; + if widgetclass = 0 then begin + result:= gue_registerclass; + end + else begin + result:= gue_ok; + end; + if applicationallocated then begin + createapphandle(applicationwindow); + end; + systimerinit(eventlist,applicationwindow); +end; + +function gui_deinit: guierrorty; +var + acursor: cursorshapety; + +begin + primarybuffer:= ''; + windnddeinit; + systimerdeinit; +// killtimer; + killmouseidletimer; + if applicationwindow <> 0 then begin + destroywindow(applicationwindow); + applicationwindow:= 0; + end; + freeandnil(eventlist); + unregisterclass(widgetclassname,hinstance); + widgetclass:= 0; + + msegdi32gdi.deinit; + + result:= gue_ok; + mainthread:= 0; + mousewindow:= 0; + mousecursor:= 0; + for acursor:= low(acursor) to high(acursor) do begin + if cursors[acursor] <> 0 then begin + destroycursor(cursors[acursor]); + cursors[acursor]:= 0; + end; + end; +end; + +function gui_getgdifuncs: pgdifunctionaty; +begin + result:= gdi32getgdifuncs; +end; + +procedure GUI_DEBUGBEGIN; +begin +// setactivewindow(0); +end; + +procedure GUI_DEBUGEND; +begin +end; + +function gui_registergdi: guierrorty; +begin + registergdi(gdi32getgdifuncs); + result:= gue_ok; +end; + +procedure initlibs; +begin + hasimm32:= checkprocaddresses(['Imm32.dll'], + ['ImmGetContext', + 'ImmReleaseContext', + 'ImmSetCompositionWindow'], + [@ImmGetContext, + @ImmReleaseContext, + @ImmSetCompositionWindow]); + haslayeredwindows:= checkprocaddresses(['User32.dll'], + ['SetLayeredWindowAttributes'], + [@SetLayeredWindowAttributes]); +end; + +initialization + initlibs; + gdi32initdefaultfont; +end. diff --git a/mseide-msegui/lib/common/kernel/windows/msenoguiintf.pas b/mseide-msegui/lib/common/kernel/windows/msenoguiintf.pas new file mode 100644 index 0000000..d88a16d --- /dev/null +++ b/mseide-msegui/lib/common/kernel/windows/msenoguiintf.pas @@ -0,0 +1,167 @@ +{ MSEgui Copyright (c) 1999-2010 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msenoguiintf; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msesystypes; + +{$include ..\msenoguiintf.inc} + +implementation +uses + windows,{$ifndef FPC}messages,{$endif}msesysintf1,msesysintf,msenogui,mseevent, + mseapplication; +type + tapplication1 = class(tnoguiapplication); +const + widgetclassname = 'msenonguiwindow'; +var + widgetclass: atom; + sempo: psemty; + applicationwindow: hwnd; + timer: cardinal; + timerevent: boolean; + terminated: boolean; + +procedure killtimer; +begin + if timer <> 0 then begin + windows.killtimer(0,timer); + timer:= 0; + end; +end; + +procedure nogui_settimer(us: cardinal); +begin + killtimer; + timer:= windows.settimer(applicationwindow,0,us div 1000,nil); +end; + +function WindowProc(ahWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; +begin + if ahwnd = applicationwindow then begin + result:= 0; + case msg of + wm_timer: begin + timerevent:= true; + end; + wm_close,wm_destroy: begin + terminated:= true; + end; + else begin + result:= 1; + end; + end; + end + else begin + result:= 1; + end; + if result <> 0 then begin + if iswin95 then begin + result:= defwindowproca(ahwnd,msg,wparam,lparam); + end + else begin + result:= defwindowprocw(ahwnd,msg,wparam,lparam); + end; + end; +end; + +procedure nogui_waitevent; + procedure checkevents; + begin + if timerevent then begin + timerevent:= false; + application.postevent(tmseevent.create(ek_timer)); + end; + if terminated then begin + timerevent:= false; + application.postevent(tmseevent.create(ek_terminate)); + end; + end; + +var + msg1: {$ifdef FPC}msg{$else}tmsg{$endif}; + +begin + with tapplication1(application) do begin + include(fstate,aps_waiting); + checkevents; + while eventlist.count = 0 do begin + application.unlock; + with win32semty(sempo^) do begin + if interlockeddecrement(semacount) < 0 then begin + msgwaitformultipleobjects(1,{$ifdef FPC}@{$endif}event, + false,infinite,qs_allinput); + end; + end; + application.lock; + if iswin95 then begin + while peekmessagea(msg1,0,0,0,pm_remove) do begin + dispatchmessagea(msg1); + end; + end + else begin + while peekmessagew(msg1,0,0,0,pm_remove) do begin + dispatchmessagew(msg1); + end; + end; + checkevents; + end; + fstate:= fstate -[aps_waiting,aps_woken]; + end; +end; + +procedure nogui_init(const asempo: psemty); +const + classstyle = cs_owndc; +var + classinfow: twndclassw; + classinfoa: twndclassa; + str1: string; +begin + sempo:= asempo; + if iswin95 then begin + fillchar(classinfoa,sizeof(classinfoa),0); + with classinfoa do begin + lpszclassname:= widgetclassname; + lpfnwndproc:= @windowproc; + hinstance:= {$ifdef FPC}system{$else}sysinit{$endif}.HInstance; + style:= classstyle; +// cbwndextra:= wndextrabytes; + end; + widgetclass:= registerclassa(classinfoa); + end + else begin + fillchar(classinfow,sizeof(classinfow),0); + with classinfow do begin + lpszclassname:= widgetclassname; + lpfnwndproc:= @windowproc; + hinstance:= {$ifdef FPC}system{$else}sysinit{$endif}.HInstance; + style:= classstyle; +// cbwndextra:= wndextrabytes; + end; + widgetclass:= registerclassw(classinfow); + end; + str1:= application.applicationname; + applicationwindow:= windows.CreateWindowex(ws_ex_appwindow,widgetclassname,pchar(str1), + ws_overlappedwindow,0,0,0,0,0,0,hinstance,nil); +end; + +procedure nogui_deinit; +begin + killtimer; + destroywindow(applicationwindow); + applicationwindow:= 0; + unregisterclass(widgetclassname,hinstance); +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/windows/mseprocmonitor.pas b/mseide-msegui/lib/common/kernel/windows/mseprocmonitor.pas new file mode 100644 index 0000000..7b35546 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/windows/mseprocmonitor.pas @@ -0,0 +1,182 @@ +{ MSEgui Copyright (c) 2008 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseprocmonitor; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +interface +uses + msesystypes,mseglob; +{$ifdef FPC} + {$include ..\mseprocmonitor.inc} +{$else} + {$include mseprocmonitor.inc} +{$endif} + +implementation +uses + msethread,msetypes,windows,sysutils,msearrayutils,mseapplication; +type + handlearty = array of thandle; + + tprocmonitor = class(tmutexthread) + private + fwakeupevent: thandle; + fhandles: handlearty; + fcallbacks: array of iprocmonitor; + fdata: pointerarty; +// fcount: integer; + procedure wakeup; + public + constructor create(const athreadproc: threadprocty; + const afreeonterminate: boolean = false; + const astacksizekb: integer = 0); override; + destructor destroy; override; + function listentoprocess(const prochandle: prochandlety; + const dest: iprocmonitor; + const data: pointer): boolean; + procedure unlistentoprocess(const prochandle: prochandlety; + const dest: iprocmonitor); + function execute(thread: tmsethread): integer; override; + end; + +var + monitor: tprocmonitor; + +procedure checkinit; +begin + if monitor = nil then begin + monitor:= tprocmonitor.create; + end; +end; + +function pro_listentoprocess(const aprochandle: prochandlety; + const adest: iprocmonitor; + const adata: pointer): boolean; +begin + checkinit; + result:= monitor.listentoprocess(aprochandle,adest,adata); +end; + +procedure pro_unlistentoprocess(const aprochandle: prochandlety; + const adest: iprocmonitor); +begin + if monitor <> nil then begin + monitor.unlistentoprocess(aprochandle,adest); + end; +end; + +{ tprocmonitor } + +constructor tprocmonitor.create(const athreadproc: threadprocty; + const afreeonterminate: boolean = false; + const astacksizekb: integer = 0); +begin + fwakeupevent:= createevent(nil,false,false,nil); + setlength(fhandles,1); + fhandles[0]:= fwakeupevent; + inherited; +end; + +destructor tprocmonitor.destroy; +begin + terminate; + setevent(fwakeupevent); + inherited; + closehandle(fwakeupevent); +end; + +procedure tprocmonitor.wakeup; +begin + setevent(fwakeupevent); +end; + +function tprocmonitor.execute(thread: tmsethread): integer; +var +// event: tmseevent; + int1: integer; + handles1: handlearty; + handle1: thandle; + execresult1: integer; +begin + with tprocmonitor(thread) do begin + repeat + lock; + handles1:= copy(fhandles); + unlock; + int1:= waitformultipleobjects(length(handles1), + pwohandlearray(handles1),false,INFINITE); + if not terminated then begin + int1:= int1 - wait_object_0; + if (int1 > 0) and (int1 <= high(handles1)) then begin + handle1:= fhandles[int1]; + getexitcodeprocess(handle1,longword(execresult1)); + lock; + for int1:= high(fhandles) downto 1 do begin + if fhandles[int1] = handle1 then begin + fcallbacks[int1-1].processdied(handle1,execresult1,fdata[int1-1]); +// application.postevent(tchildprocevent.create(fcallbacks[int1-1],handle1, +// execresult1,fdata[int1-1])); + deleteitem(pointerarty(fcallbacks),int1-1); + deleteitem(fhandles,typeinfo(handlearty),int1); + deleteitem(fdata,int1-1); + end; + end; + closehandle(handle1); + unlock; + end; + end; + until terminated; + end; + result:= 0; +end; + +function tprocmonitor.listentoprocess(const prochandle: prochandlety; + const dest: iprocmonitor; const data: pointer): boolean; +begin + result:= false; + lock; + if length(fhandles) < maximum_wait_objects then begin + setlength(fhandles,high(fhandles)+2); + fhandles[high(fhandles)]:= prochandle; + setlength(fcallbacks,high(fhandles)); + fcallbacks[high(fcallbacks)]:= dest; + setlength(fdata,high(fhandles)); + fdata[high(fdata)]:= data; + result:= true; + end; + wakeup; + unlock; +end; + +procedure tprocmonitor.unlistentoprocess(const prochandle: prochandlety; + const dest: iprocmonitor); +var + int1: integer; +begin + lock; + for int1:= high(fcallbacks) downto 0 do begin + if (fcallbacks[int1] = dest) and (fhandles[int1+1] = cardinal(prochandle)) then begin + deleteitem(pointerarty(fcallbacks),int1); + deleteitem(fhandles,typeinfo(handlearty),int1+1); + deleteitem(fdata,int1); + end; + end; + wakeup; + unlock; +end; + +procedure pro_killzombie(const aprochandle: prochandlety); +begin + closehandle(aprochandle); +end; + +initialization +finalization + freeandnil(monitor); +end. diff --git a/mseide-msegui/lib/common/kernel/windows/msesocketintf.pas b/mseide-msegui/lib/common/kernel/windows/msesocketintf.pas new file mode 100644 index 0000000..e46c4c6 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/windows/msesocketintf.pas @@ -0,0 +1,426 @@ +{ MSEgui Copyright (c) 1999-2007 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msesocketintf; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msesystypes,msesys; +{$include ..\msesocketintf.inc} + +implementation +uses + {$ifdef FPC}winsock2{$else}winsock2_del{$endif},sysutils,msestrings,msetypes; +type + paddrinfo = ^addrinfo; + addrinfo = record + ai_flags: longint; + ai_family: longint; + ai_socktype: longint; + ai_protocol: longint; + ai_addrlen: size_t; + ai_addr: psockaddr; + ai_canonname: pchar; + ai_next: paddrinfo; + end; + ppaddrinfo= ^paddrinfo; + + datarecty = record + //dummy + end; + + win32sockadty = record + case integer of + 0: (addr: sockaddr_in); + 1: (addr6: sockaddr_in6); + end; + + win32sockaddrty = record + ad: win32sockadty; + platformdata: array[7..32] of longword; + end; + +//function getaddrinfo(__name:Pchar; __service:Pchar; __req:Paddrinfo; +// __pai:PPaddrinfo):longint; stdcall;external WINSOCK2_DLL name 'getaddrinfo'; +//procedure freeaddrinfo(__ai:Paddrinfo); stdcall;external WINSOCK2_DLL name 'freeaddrinfo'; + +function setsocketerror: syserrorty; +begin + result:= sye_socket; + mselasterror:= wsagetlasterror; +end; + +function checkerror(const aerror: integer): syserrorty; +begin + if aerror = 0 then begin + result:= sye_ok; + end + else begin + result:= setsocketerror; + end; +end; + +function sa_len(const family: integer): integer; +begin + case family of + af_inet: begin + result:= sizeof(tsockaddrin); +// result:= sizeof(tsockaddrin.sin_family) + sizeof(tsockaddrin.sin_port) + +// sizeof(tinaddr); + end; + af_inet6: begin + result:= sizeof(tsockaddrin6); +// result:= sizeof(tsockaddrin6.sin6_family) + sizeof(tsockaddrin6.sin6_port) + +// sizeof(tsockaddrin6.sin6_flowinfo) + +// sizeof(tin6addr); + end; + else begin + result:= 0; + end; + end; +end; + +function soc_geterrortext(aerror: integer): string; +begin + result:= inttostr(aerror); +end; + +function soc_getaddrerrortext(aerror: integer): string; +begin + result:= inttostr(aerror); +end; + +function soc_open(const kind: socketkindty; const nonblock: boolean; + out handle: integer): syserrorty; +var + af1: integer; + type1: integer; +// protocol1: integer; + +begin + result:= sye_ok; + type1:= sock_stream; + case kind of + sok_inet: begin + af1:= af_inet; + end; + sok_inet6: begin + af1:= af_inet6; + end; + else begin + result:= sye_notimplemented; + exit; + end; + end; + handle:= socket(af1,type1,ipproto_tcp); + if handle = integer(invalid_socket) then begin + handle:= invalidfilehandle; + result:= setsocketerror; + end + else begin + result:= soc_setnonblock(handle,nonblock); + end; +end; + +function soc_shutdown(const handle: integer; + const kind: socketshutdownkindty): syserrorty; +begin + result:= checkerror(shutdown(handle,ord(kind))); +end; + +function soc_close(const handle: integer): syserrorty; +begin + if closesocket(handle) <> 0 then begin + result:= setsocketerror; + end + else begin + result:= sye_ok; + end; +end; + +function soc_bind(const handle: integer; + const addr: socketaddrty): syserrorty; +begin + if addr.kind in [sok_inet,sok_inet6] then begin + with win32sockaddrty(addr.platformdata) do begin + result:= checkerror(bind(handle,@ad,sa_len(ad.addr.sin_family))); + end; + end + else begin + result:= sye_notimplemented; + end; +end; + +function soc_connect(const handle: integer; const addr: socketaddrty; + const timeoutms: integer): syserrorty; +var +// str1: string; + int1{,int2}: integer; + pollres: pollkindsty; +begin + result:= sye_ok; + with addr do begin + if kind = sok_local then begin + result:= sye_notimplemented; + end + else begin + with win32sockaddrty(platformdata) do begin + int1:= sa_len(ad.addr.sa_family); + if connect(handle,ad.addr,int1) <> 0 then begin + if wsagetlasterror = wsaewouldblock then begin + result:= soc_poll(handle,[poka_write,poka_except],timeoutms,pollres); + if (result = sye_ok) and (poka_except in pollres) then begin +// connect(handle,ad.addr,int1); + result:= setsocketerror; + end; + end + else begin + result:= setsocketerror; + end; + end; + end; + end; + end; +end; + +function soc_read(const fd: longint; const buf: pointer; + const nbytes: longword; out readbytes: integer; + const timeoutms: integer): syserrorty; +var + pollres: pollkindsty; +// err: integer; +begin + result:= sye_ok; + if timeoutms >= 0 then begin + result:= soc_poll(fd,[poka_read],timeoutms,pollres); + end; + if result = sye_ok then begin + readbytes:= recv(fd,buf^,nbytes,0); + if readbytes < 0 then begin + result:= setsocketerror; + end; + end + else begin + readbytes:= -1; + end; +end; + +function soc_write(const fd: longint; buf: pointer; + nbytes: longword; out writebytes: integer; + const timeoutms: integer): syserrorty; +var //todo: correct timeout value for multiple runs + int1,int2: integer; + pollres: pollkindsty; +begin + writebytes:= -1; + int2:= 0; + repeat + result:= soc_poll(fd,[poka_write],timeoutms,pollres); + if result <> sye_ok then begin + exit; + end; + int1:= send(fd,buf,nbytes,0); + if int1 <= 0 then begin + writebytes:= int1; + break; + end; + inc(int2,int1); + inc(pchar(buf),int1); + dec(nbytes,int1); + until integer(nbytes) <= 0; + if nbytes = 0 then begin + result:= sye_ok; + writebytes:= int2; + end + else begin + result:= setsocketerror; + end; +end; + +function soc_listen(const handle: integer; const maxconnections: integer): syserrorty; +begin + result:= checkerror(listen(handle,maxconnections)); +end; + +function soc_accept(const handle: integer; const nonblock: boolean; + out conn: integer; out addr: socketaddrty; + const timeoutms: integer): syserrorty; +var + pollres: pollkindsty; +begin + result:= soc_poll(handle,[poka_read],timeoutms,pollres); + if result = sye_ok then begin + addr.size:= sizeof(win32sockadty); + conn:= accept(handle,@addr.platformdata,@addr.size); + if conn = -1 then begin + result:= syelasterror; + end + else begin + result:= soc_setnonblock(conn,nonblock); + end; + end; +end; + +function soc_urltoaddr(var addr: socketaddrty): syserrorty; +//todo: name resolution, inet6 +var + str1: string; + int1,int2,int3: integer; + ar1: stringarty; + bo1: boolean; +begin + result:= sye_sockaddr; + with addr,win32sockaddrty(platformdata) do begin + if kind = sok_inet then begin + str1:= ansistring(url); + ar1:= splitstring(str1,'.'); + if high(ar1) = 3 then begin + bo1:= true; + int2:= 0; + for int1:= 0 to 3 do begin + try + int3:= strtoint(ar1[int1]); + except + bo1:= false; + break; + end; + if (int3 < 0) or (int3 > 255) then begin + bo1:= false; + break; + end; + int2:= (int2 shl 8) or int3; + end; + if bo1 then begin + fillchar(ad,sizeof(ad),0); + with ad.addr do begin + sin_family:= af_inet; + sin_port:= htons(port); + sin_addr.s_addr:= htonl(int2); + end; + size:= sizeof(ad.addr); + result:= sye_ok; + end; + end; + end; + end; +end; + +function soc_getaddr(const addr: socketaddrty): string; +begin + result:= ''; //todo +end; + +function soc_getport(const addr: socketaddrty): integer; +begin + result:= 0; //todo +end; + +function soc_setnonblock(const handle: integer; const nonblock: boolean): syserrorty; +var + int1: u_long; +begin + result:= sye_ok; + if nonblock then begin + int1:= 1; + end + else begin + int1:= 0; + end; + if ioctlsocket(tsocket(handle),longint(fionbio),pu_long(@int1)) <> 0 then begin + result:= setsocketerror; + end; +end; + +function soc_setrxtimeout(const handle: integer; const ms: integer): syserrorty; +begin + result:= sye_notimplemented; +end; + +function soc_settxtimeout(const handle: integer; const ms: integer): syserrorty; +begin + result:= sye_notimplemented; +end; + +function soc_poll(const handle: integer; const kind: pollkindsty; + const timeoutms: longword; + out pollres: pollkindsty): syserrorty; + //0 -> no timeout + //for blocking mode +var + rset,wset,eset: tfdset; + prset,pwset,peset: pfdset; + ti: timeval; + pti: ptimeval; + int1: integer; +begin + pollres:= []; + if timeoutms <> 0 then begin + ti.tv_sec:= timeoutms div 1000; + ti.tv_usec:= (timeoutms mod 1000) * 1000; + pti:= @ti; + end + else begin + pti:= nil; + end; + if poka_read in kind then begin + fd_zero(rset); + fd_set(handle,rset); + prset:= @rset; + end + else begin + prset:= nil; + end; + if poka_write in kind then begin + fd_zero(wset); + fd_set(handle,wset); + pwset:= @wset; + end + else begin + pwset:= nil; + end; + if poka_except in kind then begin + fd_zero(eset); + fd_set(handle,eset); + peset:= @eset; + end + else begin + peset:= nil; + end; + int1:= select(0,prset,pwset,peset,pti); + if int1 > 0 then begin + if (poka_read in kind) and fd_isset(handle,rset) then begin + include(pollres,poka_read); + end; + if (poka_write in kind) and fd_isset(handle,wset) then begin + include(pollres,poka_write); + end; + if (poka_except in kind) and fd_isset(handle,eset) then begin + include(pollres,poka_except); + end; + result:= sye_ok; + end + else begin + if int1 = 0 then begin + result:= sye_timeout; + end + else begin + result:= setsocketerror; + end; + end; +end; + +var + wsadata: twsadata; + +initialization + wsastartup((2 shl 8) or 2,wsadata); +finalization + wsacleanup; +end. diff --git a/mseide-msegui/lib/common/kernel/windows/msesysintf.pas b/mseide-msegui/lib/common/kernel/windows/msesysintf.pas new file mode 100644 index 0000000..2a3833e --- /dev/null +++ b/mseide-msegui/lib/common/kernel/windows/msesysintf.pas @@ -0,0 +1,1999 @@ +{ MSEgui Copyright (c) 1999-2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msesysintf; //i386-win32 + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msesys,{msethread,}msetypes,msesystypes,msestrings,windows,msectypes; + +{$include ..\msesysintf.inc} + +type + NTSTATUS = longword; + +const + ASFW_ANY = dword(-1); + //PROCESSINFOCLASS + ProcessBasicInformation = 0; + ProcessDebugPort = 7; + ProcessWow64Information = 26; + ProcessImageFileName = 27; + ProcessBreakOnTermination = 29; + +var + AllowSetForegroundWindow: function(dwProcessId: DWORD):WINBOOL; stdcall; + +function procidfromprochandle(const ahandle: prochandlety): procidty; + +implementation +uses + sysutils,msebits,msefileutils,{msedatalist,}dateutils, + msesystimer,msearrayutils,msesysintf1,msedynload; + +//todo: correct unicode implementation, long filepaths, stubs for win95 +type +{$packrecords c} + PROCESS_BASIC_INFORMATION = record + Reserved1: PVOID; + PebBaseAddress: pointer;//PPEB; + Reserved2: array[0..1] of PVOID; + UniqueProcessId: ULONG_PTR; + Reserved3: PVOID; + end; + pPROCESS_BASIC_INFORMATION = ^PROCESS_BASIC_INFORMATION; + +var + ZwQueryInformationProcess: function(ProcessHandle: HANDLE; + ProcessInformationClass: cint{PROCESSINFOCLASS}; + ProcessInformation: PVOID; + ProcessInformationLength: ULONG; + ReturnLength: PULONG): NTSTATUS; stdcall; + NtQueryInformationProcess: function( + ProcessHandle: HANDLE; + ProcessInformationClass: cint{PROCESSINFOCLASS}; + ProcessInformation: PVOID; + ProcessInformationLength: cULONG; + ReturnLength: PULONG): NTSTATUS; stdcall; + GetProcessId: function(Process: HANDLE): DWORD; stdcall; + +function procidfromprochandle(const ahandle: prochandlety): procidty; +var + info: PROCESS_BASIC_INFORMATION; + len1: culong; +begin + result:= invalidprocid; + if getprocessid <> nil then begin + result:= getprocessid(ahandle); + end + else begin + if NtQueryInformationProcess <> nil then begin + if NtQueryInformationProcess(ahandle,processbasicinformation,@info, + sizeof(info),@len1) = 0 then begin + result:= info.uniqueprocessid; + end; + end + else begin + if ZwQueryInformationProcess <> nil then begin + if ZwQueryInformationProcess(ahandle,processbasicinformation,@info, + sizeof(info),@len1) = 0 then begin + result:= info.uniqueprocessid; + end; + end; + end; + end; +end; + +var + apphomedir: filenamety; + userhomedir: filenamety; + +const + FILE_ATTRIBUTE_ENCRYPTED = $0040; + FILE_ATTRIBUTE_REPARSE_POINT = $0400; + FILE_ATTRIBUTE_SPARSE_FILE = $0200; + {$ifdef FPC} + FILE_ATTRIBUTE_OFFLINE = $00001000; + {$endif} + filetimeoffset = -109205.0; + +type + win32threadinfoty = record //64bit + handle: thandle; //8 + platformdata: array[1..3] of pointer; + end; + + winfileinfoty = record + dwFileAttributes: DWORD; + ftCreationTime: TFileTime; + ftLastAccessTime: TFileTime; + ftLastWriteTime: TFileTime; + end; + winfilesizety = record + nFileSizeHigh: DWORD; + nFileSizeLow: DWORD; + end; + winfilenameaty = array[0..MAX_PATH - 1] of Char; + pwinfilenameaty = ^winfilenameaty; + WIN32_FIND_DATAA = record + winfo: winfileinfoty; + wsize: winfilesizety; + dwReserved0: DWORD; + dwReserved1: DWORD; + cFileName: winfilenameaty; + cAlternateFileName: array[0..13] of Char; + end; + pwin32_find_dataa = ^win32_find_dataa; + WIN32_FIND_DATAW = record + winfo: winfileinfoty; + wsize: winfilesizety; + dwReserved0: DWORD; + dwReserved1: DWORD; + cFileName: array[0..MAX_PATH - 1] of WideChar; + cAlternateFileName: array[0..13] of WideChar; + end; + pwin32_find_dataw = ^win32_find_dataw; + + BY_HANDLE_FILE_INFORMATION = record + winfo: winfileinfoty; + dwVolumeSerialNumber: DWORD; + wsize: winfilesizety; + nNumberOfLinks: DWORD; + nFileIndexHigh: DWORD; + nFileIndexLow: DWORD; + end; + + dirstreamwin32ty = record //64bit + handle: thandle; //8 + finddatapo: pwin32_find_dataw; //8 + last: boolean; //4 + drivenum: integer; //for root directory //4 total 24 + {$ifdef cpu64} //platformdata = 64 + platformdata: array[3..7] of pointer; + {$else} + platformdata: array[4..7] of pointer; + {$endif} + end; + +const + TH32CS_SNAPHEAPLIST = $00000001; + TH32CS_SNAPPROCESS = $00000002; + TH32CS_SNAPTHREAD = $00000004; + TH32CS_SNAPMODULE = $00000008; + TH32CS_SNAPALL = TH32CS_SNAPHEAPLIST or TH32CS_SNAPPROCESS or + TH32CS_SNAPTHREAD or TH32CS_SNAPMODULE; + TH32CS_INHERIT = $80000000; +type + {$ifndef FPC} + LONG = integer; + {$endif} + PROCESSENTRY32 = record + dwSize: DWORD; + cntUsage: DWORD; + th32ProcessID: DWORD; + th32DefaultHeapID: pointer; + th32ModuleID: DWORD; + cntThreads: DWORD; + th32ParentProcessID: DWORD; + pcPriClassBase: LONG; + dwFlags: DWORD; + szExeFile: array[0..MAX_PATH-1] of char; + end; + PPROCESSENTRY32 = ^PROCESSENTRY32; + +function CreateToolhelp32Snapshot(dwFlags: dword; th32ProcessId: dword): thandle; + stdcall; external kernel32 name 'CreateToolhelp32Snapshot'; +function Process32First(hSnapshot: thandle; lppe: PPROCESSENTRY32): BOOL; + stdcall; external kernel32 name 'Process32First'; +function Process32Next(hSnapshot: thandle; lppe: PPROCESSENTRY32): BOOL; + stdcall; external kernel32 name 'Process32Next'; +function GetFileInformationByHandle(hFile: THandle; + var lpFileInformation: By_Handle_File_Information): BOOL; + stdcall; external 'kernel32' name 'GetFileInformationByHandle'; + +var + GetLongPathNameW: function(lpszShortPath: LPCWSTR; lpszLongPath: LPCWSTR; + cchBuffer: DWORD):DWORD; stdcall; + +function sys_getpid: procidty; +begin + result:= getcurrentprocessid; +end; + +function sys_terminateprocess(const proc: prochandlety): syserrorty; +begin + result:= sye_notimplemented; +end; + +function sys_killprocess(const proc: prochandlety): syserrorty; +begin + result:= sye_ok; + if not windows.terminateprocess(proc,0) then begin + result:= syelasterror; + end; +end; + +function sys_stdin: integer; +begin + result:= getstdhandle(std_input_handle); +end; + +function sys_stdout: integer; +begin + result:= getstdhandle(std_output_handle); +end; + +function sys_stderr: integer; +begin + result:= getstdhandle(std_error_handle); +end; + +function sys_getprintcommand: msestring; +begin + result:= defaultprintcommand; + if result = '' then begin + result:= 'gswin32c.exe -dNOPAUSE -sDEVICE=mswinpr2 -'; + end; +end; + +{ +function sys_towupper(char: msechar): msechar; +begin + result:= windows.charupperw(ord(char)); //win95? +end; + +function sys_toupper(char: char): char; +begin + result:= windows.charupper(ord(char)); +end; +} + +function sys_getprocesses: procitemarty; +var + int1: integer; + th: thandle; + info: processentry32; +begin + result:= nil; + th:= createtoolhelp32snapshot(th32cs_snapprocess,0); + int1:= 0; + if th <> invalid_handle_value then begin + info.dwsize:= sizeof(info); + if process32first(th,@info) then begin + repeat + additem(result,typeinfo(procitemarty),int1); + with result[int1-1] do begin + pid:= info.th32processid; + ppid:= info.th32parentprocessid; + end; + until not process32next(th,@info); + end; + closehandle(th); + setlength(result,int1); + end; +end; + +procedure sys_schedyield; +begin + windows.sleep(0); +end; + +procedure sys_usleep(const us: cardinal); +begin + windows.sleep(us div 1000); +end; + +function sys_getapplicationpath: filenamety; +const + bufsize = 1024; +var + int1: integer; + str1: string; +begin + setlength(str1,bufsize); + int1:= getmodulefilename(hinstance,@str1[1],bufsize-1); + setlength(str1,int1); + result:= tomsefilepath(msestring(str1)); +end; + +function sys_getcommandlinearguments: msestringarty; +begin + {$ifdef FPC}{$checkpointer off}{$endif} + result:= parsecommandline(msestring(cmdline)); //todo: use unicode + {$ifdef FPC}{$checkpointer default}{$endif} +end; + +procedure sys_getenvvars(out names: msestringarty; out values: msestringarty); +var + po0,po1,po2,po3: pmsechar; + po0a,po1a,po2a,po3a: pchar; + str1: ansistring; +begin + if iswin95 then begin + po0a:= getenvironmentstringsa(); + po1a:= po0a; + while po1a^ <> #0 do begin + po2a:= po1a; + while po2a^ <> #0 do begin + inc(po2a); + end; + po3a:= po1a; + while (po3a^ <> '=') and (po3a < po2a) do begin + inc(po3a); + end; + str1:= psubstr(po1a,po3a); + oemtoansibuff(pointer(str1),pointer(str1),length(str1)); + additem(names,msestring(str1)); + str1:= psubstr(po3a+1,po2a); + oemtoansibuff(pointer(str1),pointer(str1),length(str1)); + additem(values,msestring(str1)); + po1a:= po2a+1; + end; + freeenvironmentstringsa(po0a); + end + else begin + po0:= getenvironmentstringsw(); + po1:= po0; + while po1^ <> #0 do begin + po2:= po1; + while po2^ <> #0 do begin + inc(po2); + end; + po3:= po1; + while (po3^ <> '=') and (po3 < po2) do begin + inc(po3); + end; + additem(names,psubstr(po1,po3)); + additem(values,psubstr(po3+1,po2)); + po1:= po2+1; + end; + freeenvironmentstringsw(po0); + end; +end; + +function sys_getenv(const aname: msestring; out avalue: msestring): boolean; + //true if found +var + str1,str2: string; + lwo1: longword; +begin + avalue:= ''; + if iswin95 then begin + str2:= ansistring(aname); + lwo1:= getenvironmentvariablea(pchar(str2),nil,0); + result:= lwo1 > 0; + if result then begin + if lwo1 > 1 then begin + setlength(str1,lwo1-1); + lwo1:= getenvironmentvariablea(pchar(str2),pointer(str1),lwo1); + result:= lwo1 > 0; + setlength(str1,lwo1); + avalue:= msestring(str1); + end; + end; + end + else begin + lwo1:= getenvironmentvariablew(pmsechar(aname),nil,0); + result:= lwo1 > 0; + if result then begin + if lwo1 > 1 then begin + setlength(avalue,lwo1-1); + lwo1:= getenvironmentvariablew(pmsechar(aname),pointer(avalue),lwo1); + result:= lwo1 > 0; + setlength(avalue,lwo1); + end; + end; + end; +end; + +function sys_setenv(const aname: msestring; const avalue: msestring): syserrorty; +begin + result:= sye_ok; + if iswin95 then begin + if not setenvironmentvariablea(pchar(ansistring(aname)), + pchar(ansistring(avalue))) then begin + result:= syelasterror; + end; + end + else begin + if not setenvironmentvariablew(pmsechar(aname), + pmsechar(avalue)) then begin + result:= syelasterror; + end; + end; +end; + +function sys_unsetenv(const aname: msestring): syserrorty; +begin + result:= sye_ok; + if iswin95 then begin + if not setenvironmentvariablea(pchar(ansistring(aname)),nil) then begin + result:= syelasterror; + end; + end + else begin + if not setenvironmentvariablew(pmsechar(aname),nil) then begin + result:= syelasterror; + end; + end; +end; + +function winfilepath(dirname,filename: msestring): msestring; +begin + replacechar1(dirname,msechar('/'),msechar('\')); + replacechar1(filename,msechar('/'),msechar('\')); + if (length(dirname) >= 3) and (dirname[1] = '\') and (dirname[3] = ':') then begin + dirname[1]:= dirname[2]; // '/c:' -> 'c:\' + dirname[2]:= ':'; + dirname[3]:= '\'; + if (length(dirname) > 3) and (dirname[4] = '\') then begin + move(dirname[5],dirname[4],(length(dirname) - 4)*sizeof(msechar)); + setlength(dirname,length(dirname) - 1); + end; + end; + if filename <> '' then begin + if dirname = '' then begin + result:= '.\'+filename; + end + else begin + if dirname[length(dirname)] <> '\' then begin + result:= dirname + '\' + filename; + end + else begin + result:= dirname + filename; + end; + end; + end + else begin + result:= dirname; + end; +end; + +function sys_filesystemiscaseinsensitive: boolean; +begin + result:= true; +end; + +function sys_tosysfilepath(var path: msestring): syserrorty; +begin + path:= winfilepath(path,''); + result:= sye_ok; +end; + +function sys_read(fd:longint; buf:pointer; nbytes: dword): integer; +begin + result:= -1; //compilerwarning; + if not windows.readfile(fd,buf^,nbytes,dword(result),nil) then begin + result:= -1; + end; + { + if nbytes > 0 then begin + repeat + if not windows.readfile(fd,buf^,nbytes,dword(result),nil) then begin + result:= -1; + end; + until result <> 0; + end + else begin + result:= 0; + end; + } +end; + +function sys_write(fd:longint; buf:pointer; nbytes: dword): integer; +begin + result:= -1; //compilerwarning; + if nbytes > 0 then begin + repeat + if not windows.WriteFile(fd,buf^,nbytes,dword(result),nil) then begin + result:= -1; + end; + until result <> 0; + end + else begin + result:= 0; + end; +end; + +function sys_errorout(const atext: string): syserrorty; +var + ca1: cardinal; +begin + if length(atext) > 0 then begin + if isconsole then begin + if windows.writefile(getstdhandle(std_input_handle),pchar(atext)^, + length(atext),ca1,nil) then begin + result:= sye_ok; + end + else begin + result:= syelasterror; + end; + end + else begin + result:= sye_noconsole; + end; + end + else begin + result:= sye_ok; + end; +end; + +function sys_openfile(const path: msestring; const openmode: fileopenmodety; + const accessmode: fileaccessmodesty; + const rights: filerightsty; out handle: integer): syserrorty; +const + openmodes: array[fileopenmodety] of cardinal = +// fm_none,fm_read, fm_write, fm_readwrite, + (0, generic_read,generic_write,generic_read or generic_write, +// fm_create, fm_append + generic_read or generic_write,generic_read or generic_write); +var + ca1: cardinal; + str1: string; + mstr2: msestring; + +begin + if not (fa_denyread in accessmode) then begin + ca1:= file_share_read; + end + else begin + ca1:= 0; + end; + if not (fa_denywrite in accessmode) then begin + ca1:= ca1 or file_share_write; + end; + + mstr2:= winfilepath(path,''); + if iswin95 then begin + str1:= ansistring(mstr2); + if openmode = fm_Create then begin + handle:= CreateFilea(PChar(str1),openmodes[openmode], //todo: rights -> securityattributes + ca1, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); + end + else begin + handle:= CreateFilea(PChar(str1),openmodes[openmode], + ca1, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); + end; + end + else begin + if openmode = fm_Create then begin + handle:= CreateFilew(PmseChar(mstr2),openmodes[openmode], //todo: rights -> securityattributes + ca1, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); + end + else begin + handle:= CreateFilew(PmseChar(mstr2),openmodes[openmode], + ca1, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); + end; + end; + if handle = invalidfilehandle then begin + result:= syelasterror; + end + else begin + result:= sye_ok; + end; +end; + +function sys_closefile(const handle: integer): syserrorty; +begin + if (handle = invalidfilehandle) or closehandle(handle) then begin + result:= sye_ok; + end + else begin + result:= syelasterror; + end; +end; + +function sys_flushfile(const handle: integer): syserrorty; +begin + if flushfilebuffers(handle) then begin + result:= sye_ok; + end + else begin + result:= syelasterror; + end; +end; + +function sys_dup(const source: integer; out dest: integer): syserrorty; +begin + result:= sye_notimplemented; +end; + +const + invalid_set_file_pointer = dword(-1); + +function sys_truncatefile(const handle: integer; const size: int64): syserrorty; +var + res: dword; + lo1: clong; +begin + result:= sye_ok; + lo1:= size shr 32; + res:= setfilepointer(handle,size,@lo1,file_begin); + if (res = invalid_set_file_pointer) and (getlasterror <> no_error) then begin + result:= syelasterror; + end; +end; + +function sys_poll(const handle: integer; const kind: pollkindsty; + const timeoutms: longword): syserrorty; + //0 -> no timeout + //for blocking mode +begin + result:= sye_notimplemented; +end; + +function sys_copyfile(const oldfile,newfile: msestring): syserrorty; +var + str1,str2: string; +begin + if iswin95 then begin + str1:= ansistring(winfilepath(oldfile,'')); + str2:= ansistring(winfilepath(newfile,'')); + if windows.copyfilea(pchar(str1),pchar(str2),false) then begin + result:= sye_ok; + end + else begin + result:= syelasterror; + end; + end + else begin + if windows.copyfilew(pmsechar(winfilepath(oldfile,'')), + pmsechar(winfilepath(newfile,'')),false) then begin + result:= sye_ok; + end + else begin + result:= syelasterror; + end; + end; +end; + +function sys_renamefile(const oldname,newname: filenamety): syserrorty; +var + str1,str2: string; +begin + if iswin95 then begin + str1:= ansistring(winfilepath(oldname,'')); + str2:= ansistring(winfilepath(newname,'')); + if windows.copyfilea(pchar(str1),pchar(str2),false) then begin + if windows.deletefilea(pchar(str1)) then begin + result:= sye_ok; + end + else begin + result:= syelasterror; + end; + end + else begin + result:= syelasterror; + end; + end + else begin + if windows.movefileexw(pmsechar(winfilepath(oldname,'')), + pmsechar(winfilepath(newname,'')),movefile_replace_existing) then begin + result:= sye_ok; + end + else begin + result:= syelasterror; + end; + end; +end; + +function sys_deletefile(const filename: filenamety): syserrorty; +var + str1: string; +begin + if iswin95 then begin + str1:= ansistring(winfilepath(filename,'')); + if windows.deletefilea(pchar(str1)) then begin + result:= sye_ok; + end + else begin + result:= syelasterror; + end; + end + else begin + if windows.deletefilew(pmsechar(winfilepath(filename,''))) then begin + result:= sye_ok; + end + else begin + result:= syelasterror; + end; + end; +end; + +function sys_deletedir(const filename: filenamety): syserrorty; +var + str1: string; +begin + if iswin95 then begin + str1:= ansistring(winfilepath(filename,'')); + if windows.removedirectorya(pchar(str1)) then begin + result:= sye_ok; + end + else begin + result:= syelasterror; + end; + end + else begin + if windows.removedirectoryw(pmsechar(winfilepath(filename,''))) then begin + result:= sye_ok; + end + else begin + result:= syelasterror; + end; + end; +end; + + +function sys_createdir(const path: msestring; + const rights: filerightsty): syserrorty; +var + str1: string; + str2: msestring; + bo1: boolean; +begin + if iswin95 then begin + str1:= ansistring(winfilepath(path,'')); + bo1:= windows.createdirectorya(pchar(str1),nil); + //todo: rights -> securityattributes + end + else begin + str2:= winfilepath(path,''); + bo1:= windows.createdirectoryw(pmsechar(str2),nil); + //todo: rights -> securityattributes + end; + if bo1 then begin + result:= sye_ok; + end + else begin + result:= syelasterror; + end; +end; + +function sys_gettimeus: longword; +begin + result:= systimerus; +// result:= gettickcount * 1000; +end; +{ +function sys_getlastsyserror: integer; +begin + result:= getlasterror; +end; +} +{$ifdef FPC} + +function threadexec(infopo : pointer) : ptrint; +begin +//result:= 0; +//exit; + threadinfoty(infopo^).id:= threadty(getcurrentthreadid); + result:= threadinfoty(infopo^).threadproc(); + endthread(); +end; + +{$else} + +function threadexec(infopo: pointer): integer; stdcall; +begin + threadinfoty(infopo^).id:= threadty(getcurrentthreadid); + result:= threadinfoty(infopo^).threadproc(); +end; + +{$endif} + +function sys_threadcreate(var info: threadinfoty): syserrorty; +begin +{$ifdef FPC} + with info,win32threadinfoty(platformdata) do begin + handle:= beginthread(@threadexec,@info,id,stacksize); + if handle = 0 then begin + result:= sye_thread; + end + else begin + result:= sye_ok; + end; + end; +{$else} + ismultithread:= true; + with info,win32threadinfoty(platformdata) do begin + handle:= windows.CreateThread(nil,info.stacksize,@threadexec,@info,0,id); + if handle = 0 then begin + result:= sye_thread; + id:= 0; + end + else begin + result:= sye_ok; + end; + end; +{$endif} +end; + +function sys_threadwaitfor(var info: threadinfoty): syserrorty; +begin + with info,win32threadinfoty(platformdata) do begin + if waitforsingleobject(handle,infinite) = wait_object_0 then begin + result:= sye_ok; + end + else begin + result:= sye_thread; + end; + end; +end; + +function sys_getcurrentthread: threadty; +begin + result:= threadty(getcurrentthreadid); +end; + +function sys_issamethread(const a,b: threadty): boolean; +begin + result:= a = b; +end; + +function sys_threaddestroy(var info: threadinfoty): syserrorty; +var + ca1: cardinal; +begin + result:= sye_ok; + with win32threadinfoty(info.platformdata) do begin + if getexitcodethread(handle,ca1) then begin + if ca1 = still_active then begin + terminatethread(handle,exitcode); + end; + end; + closehandle(handle); + end; +end; + +function sys_threadschedyield: syserrorty; +begin + result:= sye_ok; + windows.sleep(0); +end; + +function filetimetotime(const wtime: tfiletime): tdatetime; +begin + with wtime do begin + if (dwLowDateTime = 0) and (dwhighdatetime = 0) then begin + result:= 0; + end + else begin + result:= (dwhighdatetime*twoexp32 + dwLowDateTime) / + (24.0*60.0*60.0*1000000.0*10.0) + filetimeoffset; + end; + end; +end; + +function sys_getutctime: tdatetime; +var + ft1: tfiletime; +begin + getsystemtimeasfiletime(ft1); + result:= filetimetotime(ft1); +end; + +var + lastlocaltime: integer; + gmtoff: real; + +function sys_localtimeoffset: tdatetime; +var + tinfo: time_zone_information; + int1: integer; +begin + with tinfo do begin + {$ifdef FPC} + case gettimezoneinformation(@tinfo) of + {$else} + case gettimezoneinformation(tinfo) of + {$endif} + time_zone_id_unknown: int1:= bias; + time_zone_id_standard: int1:= bias + standardbias; + time_zone_id_daylight: int1:= bias + daylightbias; + else int1:= 0; + end; + end; + result:= -int1 / (24*60.0); +end; + +function sys_getlocaltime: tdatetime; +var + ft1: tfiletime; + lint1: int64; + lwo1: longword; +begin + getsystemtimeasfiletime(ft1); + lint1:= (int64(ft1.dwhighdatetime) shl 32) + ft1.dwlowdatetime; + lwo1:= lint1 div 10000000; //seconds + if lwo1 <> longword(lastlocaltime) then begin + lastlocaltime:= lwo1; + gmtoff:= sys_localtimeoffset; + end; + {$ifdef FPC} + result:= real(lint1)/(24.0*60.0*60.0*1000000.0*10.0) + filetimeoffset + gmtoff; + {$else} + result:= lint1/(24.0*60.0*60.0*1000000.0*10.0) + filetimeoffset + gmtoff; + {$endif} +end; +{ +function sys_getlocaltime: tdatetime; +var + ti1: tsystemtime; +begin + getlocaltime(ti1); + result:= systemtimetodatetime(ti1); +end; +} +(* +function sys_localtimeoffset: tdatetime; +var + ti1,ti2: tfiletime; +begin + ti1.dwhighdatetime:= $40000000; + ti1.dwlowdatetime:= 0; + {$ifdef FPC} + filetimetolocalfiletime(@ti1,@ti2); + {$else} + filetimetolocalfiletime(ti1,ti2); + {$endif} + ti2.dwhighdatetime:= ti2.dwhighdatetime - $40000000; + result:= int64(ti2) / (24*60*60*1e7); //100ns +end; +*) +{ +function sys_localtimeoffset: tdatetime; +var + info: _time_zone_information; +begin + if gettimezoneinformation(info) = $ffffffff then begin + result:= 0; + end + else begin + result:= - info.Bias / (24.0*60.0); //does not check daylightsaving + end; +end; +} +function sys_getlangname: string; +type + langty = + (L_AFRIKAANS,L_ALBANIAN,L_ARABIC,L_ARMENIAN,L_ASSAMESE, + L_AZERI,L_BASQUE,L_BELARUSIAN,L_BENGALI,L_BULGARIAN, + L_CATALAN,L_CHINESE,L_CROATIAN,L_CZECH,L_DANISH, + L_DIVEHI,L_DUTCH,L_ENGLISH,L_ESTONIAN,L_FAEROESE, + L_FARSI,L_FINNISH,L_FRENCH,L_GALICIAN,L_GEORGIAN, + L_GERMAN,L_GREEK,L_GUJARATI,L_HEBREW,L_HINDI, + L_HUNGARIAN,L_ICELANDIC,L_INDONESIAN,L_ITALIAN, + L_JAPANESE,L_KANNADA,L_KASHMIRI,L_KAZAK,L_KONKANI, + L_KOREAN,L_KYRGYZ,L_LATVIAN,L_LITHUANIAN,L_MACEDONIAN, + L_MALAY,L_MALAYALAM,L_MANIPURI,L_MARATHI,L_MONGOLIAN, + L_NEPALI,L_NORWEGIAN,L_ORIYA,L_POLISH,L_PORTUGUESE, + L_PUNJABI,L_ROMANIAN,L_RUSSIAN,L_SANSKRIT,L_SERBIAN, + L_SINDHI,L_SLOVAK,L_SLOVENIAN,L_SPANISH,L_SWAHILI, + L_SWEDISH,L_SYRIAC,L_TAMIL,L_TATAR,L_TELUGU,L_THAI, + L_TURKISH,L_UKRAINIAN,L_URDU,L_UZBEK,L_VIETNAMESE); + + langinfoty = record + lang: word; name: string; + end; +const +{$ifndef FPC} + LANG_AFRIKAANS = $36; + LANG_ALBANIAN = $1c; + LANG_ARABIC = $01; + LANG_ARMENIAN = $2b; + LANG_ASSAMESE = $4d; + LANG_AZERI = $2c; + LANG_BASQUE = $2d; + LANG_BELARUSIAN = $23; + LANG_BENGALI = $45; + LANG_BULGARIAN = $02; + LANG_CATALAN = $03; + LANG_CHINESE = $04; + LANG_CROATIAN = $1a; + LANG_CZECH = $05; + LANG_DANISH = $06; + LANG_DIVEHI = $65; + LANG_DUTCH = $13; + LANG_ENGLISH = $09; + LANG_ESTONIAN = $25; + LANG_FAEROESE = $38; + LANG_FARSI = $29; + LANG_FINNISH = $0b; + LANG_FRENCH = $0c; + LANG_GALICIAN = $56; + LANG_GEORGIAN = $37; + LANG_GERMAN = $07; + LANG_GREEK = $08; + LANG_GUJARATI = $47; + LANG_HEBREW = $0d; + LANG_HINDI = $39; + LANG_HUNGARIAN = $0e; + LANG_ICELANDIC = $0f; + LANG_INDONESIAN = $21; + LANG_ITALIAN = $10; + LANG_JAPANESE = $11; + LANG_KANNADA = $4b; + LANG_KASHMIRI = $60; + LANG_KAZAK = $3f; + LANG_KONKANI = $57; + LANG_KOREAN = $12; + LANG_KYRGYZ = $40; + LANG_LATVIAN = $26; + LANG_LITHUANIAN = $27; + LANG_MACEDONIAN = $2f; + LANG_MALAY = $3e; + LANG_MALAYALAM = $4c; + LANG_MANIPURI = $58; + LANG_MARATHI = $4e; + LANG_MONGOLIAN = $50; + LANG_NEPALI = $61; + LANG_NORWEGIAN = $14; + LANG_ORIYA = $48; + LANG_POLISH = $15; + LANG_PORTUGUESE = $16; + LANG_PUNJABI = $46; + LANG_ROMANIAN = $18; + LANG_RUSSIAN = $19; + LANG_SANSKRIT = $4f; + LANG_SERBIAN = $1a; + LANG_SINDHI = $59; + LANG_SLOVAK = $1b; + LANG_SLOVENIAN = $24; + LANG_SPANISH = $0a; + LANG_SWAHILI = $41; + LANG_SWEDISH = $1d; + LANG_SYRIAC = $5a; + LANG_TAMIL = $49; + LANG_TATAR = $44; + LANG_TELUGU = $4a; + LANG_THAI = $1e; + LANG_TURKISH = $1f; + LANG_UKRAINIAN = $22; + LANG_URDU = $20; + LANG_UZBEK = $43; + LANG_VIETNAMESE = $2a; + +function PRIMARYLANGID(LangId: WORD): WORD; +begin + PRIMARYLANGID := LangId and $3FF; +end; + +const +{$endif} + + langs: array[langty] of langinfoty = ( + (lang: LANG_AFRIKAANS; name: 'af'), + (lang: LANG_ALBANIAN; name: 'sq'), + (lang: LANG_ARABIC; name: 'ar'), + (lang: LANG_ARMENIAN; name: 'hy'), + (lang: LANG_ASSAMESE; name: 'as'), + (lang: LANG_AZERI; name: 'az'), + (lang: LANG_BASQUE; name: 'eu'), + (lang: LANG_BELARUSIAN; name: 'be'), + (lang: LANG_BENGALI; name: 'bn'), + (lang: LANG_BULGARIAN; name: 'bg'), + (lang: LANG_CATALAN; name: 'ca'), + (lang: LANG_CHINESE; name: 'zh'), + (lang: LANG_CROATIAN; name: 'hr'), + (lang: LANG_CZECH; name: 'cs'), + (lang: LANG_DANISH; name: 'da'), + (lang: LANG_DIVEHI; name: 'dv'), + (lang: LANG_DUTCH; name: 'nl'), + (lang: LANG_ENGLISH; name: 'en'), + (lang: LANG_ESTONIAN; name: 'et'), + (lang: LANG_FAEROESE; name: 'fo'), + (lang: LANG_FARSI; name: 'fa'), + (lang: LANG_FINNISH; name: 'fi'), + (lang: LANG_FRENCH; name: 'fr'), + (lang: LANG_GALICIAN; name: 'gl'), + (lang: LANG_GEORGIAN; name: 'ka'), + (lang: LANG_GERMAN; name: 'de'), + (lang: LANG_GREEK; name: 'el'), + (lang: LANG_GUJARATI; name: 'gu'), + (lang: LANG_HEBREW; name: 'he'), + (lang: LANG_HINDI; name: 'hi'), + (lang: LANG_HUNGARIAN; name: 'hu'), + (lang: LANG_ICELANDIC; name: 'is'), + (lang: LANG_INDONESIAN; name: 'id'), + (lang: LANG_ITALIAN; name: 'it'), + (lang: LANG_JAPANESE; name: 'ja'), + (lang: LANG_KANNADA; name: 'kn'), + (lang: LANG_KASHMIRI; name: '??'), + (lang: LANG_KAZAK; name: 'kk'), + (lang: LANG_KONKANI; name: 'kok'), + (lang: LANG_KOREAN; name: 'ko'), + (lang: LANG_KYRGYZ; name: 'ky'), + (lang: LANG_LATVIAN; name: 'lv'), + (lang: LANG_LITHUANIAN; name: 'lt'), + (lang: LANG_MACEDONIAN; name: 'mk'), + (lang: LANG_MALAY; name: 'ms'), + (lang: LANG_MALAYALAM; name: 'ml'), + (lang: LANG_MANIPURI; name: '??'), + (lang: LANG_MARATHI; name: 'mr'), + (lang: LANG_MONGOLIAN; name: 'mn'), + (lang: LANG_NEPALI; name: 'ne'), + (lang: LANG_NORWEGIAN; name: 'no'), + (lang: LANG_ORIYA; name: 'or'), + (lang: LANG_POLISH; name: 'pl'), + (lang: LANG_PORTUGUESE; name: 'pt'), + (lang: LANG_PUNJABI; name: 'pa'), + (lang: LANG_ROMANIAN; name: 'ro'), + (lang: LANG_RUSSIAN; name: 'ru'), + (lang: LANG_SANSKRIT; name: 'sa'), + (lang: LANG_SERBIAN; name: 'sr'), + (lang: LANG_SINDHI; name: '??'), + (lang: LANG_SLOVAK; name: 'sk'), + (lang: LANG_SLOVENIAN; name: 'sl'), + (lang: LANG_SPANISH; name: 'es'), + (lang: LANG_SWAHILI; name: 'sw'), + (lang: LANG_SWEDISH; name: 'sv'), + (lang: LANG_SYRIAC; name: 'syr'), + (lang: LANG_TAMIL; name: 'ta'), + (lang: LANG_TATAR; name: 'tt'), + (lang: LANG_TELUGU; name: 'te'), + (lang: LANG_THAI; name: 'th'), + (lang: LANG_TURKISH; name: 'tr'), + (lang: LANG_UKRAINIAN; name: 'uk'), + (lang: LANG_URDU; name: 'ur'), + (lang: LANG_UZBEK; name: 'uz'), + (lang: LANG_VIETNAMESE; name: 'vi')); +var + id: word; + l1: langty; +begin + result:= ''; + id:= primarylangid(getuserdefaultlangid); + for l1:= low(langty) to high(langty) do begin + if langs[l1].lang = id then begin + result:= langs[l1].name; + break; + end; + end; +end; + +procedure winfileinfotofileinfo(const winfo: winfileinfoty; + const wsize: winfilesizety; var info: fileinfoty); +begin + with winfo,info,extinfo1 do begin + if file_attribute_directory and dwfileattributes <> 0 then begin + info.extinfo1.filetype:= ft_dir; + end + else begin + info.extinfo1.filetype:= ft_reg; + end; + state:= state + [fis_typevalid,fis_extinfo1valid]; + if filetype = ft_dir then begin + attributes:= [fa_dir]; + end + else begin + attributes:= []; + end; + if file_attribute_archive and dwfileattributes <> 0 then begin + include(attributes,fa_archive); + end; + if file_attribute_compressed and dwfileattributes <> 0 then begin + include(attributes,fa_compressed); + end; + if file_attribute_encrypted and dwfileattributes <> 0 then begin + include(attributes,fa_encrypted); + end; + if file_attribute_hidden and dwfileattributes <> 0 then begin + include(attributes,fa_hidden); + end; + if file_attribute_offline and dwfileattributes <> 0 then begin + include(attributes,fa_offline); + end; + attributes:= attributes + [fa_rusr,fa_xusr,fa_rgrp,fa_xgrp,fa_roth,fa_xoth]; + if file_attribute_readonly and dwfileattributes = 0 then begin + attributes:= attributes + [fa_wusr,fa_wgrp,fa_woth]; + end; + if file_attribute_reparse_point and dwfileattributes <> 0 then begin + include(attributes,fa_reparsepoint); + end; + if file_attribute_sparse_file and dwfileattributes <> 0 then begin + include(attributes,fa_sparsefile); + end; + if file_attribute_system and dwfileattributes <> 0 then begin + include(attributes,fa_system); + end; + if file_attribute_temporary and dwfileattributes <> 0 then begin + include(attributes,fa_temporary); + end; + with int64recty(size) do begin + lsw:= wsize.nfilesizelow; + msw:= wsize.nfilesizehigh; + end; + modtime:= filetimetotime(ftlastwritetime); + accesstime:= filetimetotime(ftlastaccesstime); + ctime:= filetimetotime(ftcreationtime); + end; +end; + +function rembackslash(po: pchar): pchar; +begin + result:= po; + while result^ = '\' do begin + inc(result); + end; +end; + +//todo: network errormessages +function networkerror(const aerror: longword): syserrorty; +var + wo1,wo2: dword; + buffer1,buffer2: array[0..1024] of msechar; +begin + if aerror = error_extended_error then begin + wo1:= wnetgetlasterrorw({$ifdef FPC}@{$endif}wo2,@buffer1,1024,@buffer2,1024); + if wo1 = no_error then begin + result:= syesetextendederror(pmsechar(@buffer2)+': '+ + pmsechar(@buffer1)); + end + else begin + result:= sye_network; + end; + end + else begin + result:= syeseterror(aerror); + end; +end; + +function findservers(const resource: pnetresource; var names: msestringarty): syserrorty; +var + wo1: longword; + handle: thandle; + po1: pnetresource; + ca1,ca2: cardinal; +begin + result:= sye_network; + wo1:= wnetopenenum(resource_globalnet,resourcetype_disk,0,resource,handle); + if wo1 <> no_error then begin + result:= networkerror(wo1); + exit; + end; + getmem(po1,sizeof(tnetresource)); + ca2:= sizeof(tnetresource); + wo1:= 0; //compilerwarning + repeat + while true do begin + ca1:= 1; + wo1:= wnetenumresource(handle,ca1,po1,ca2); + if wo1 = error_more_data then begin + reallocmem(po1,ca2); + end + else begin + break; + end; + end; + if wo1 = no_error then begin + if (po1^.dwtype = resourcetype_disk) and + (po1^.dwdisplaytype = resourcedisplaytype_server) and + (po1^.lpRemoteName <> nil) then begin + setlength(names,high(names)+2); + names[high(names)]:= rembackslash(po1^.lpRemoteName); + result:= sye_ok; + end + else begin + if po1^.dwUsage and resourceusage_container <> 0 then begin + if findservers(po1,names) = sye_ok then begin + result:= sye_ok; + end; + end + end; + end + else begin + result:= networkerror(wo1); + end; + until wo1 <> no_error; + wnetcloseenum(handle); + freemem(po1); +// result:= sye_ok; +end; + +function findserver(const name: string; var resource: pnetresource): syserrorty; + +var + wo1: longword; + handle: thandle; + ca1,ca2: cardinal; + po1: pnetresource; +begin + result:= sye_network; + wo1:= wnetopenenum(resource_globalnet,resourcetype_disk,0,resource,handle); + resource:= nil; + if wo1 <> no_error then begin + result:= networkerror(wo1); + exit; + end; + getmem(po1,sizeof(tnetresource)); + ca2:= sizeof(tnetresource); + wo1:= 0; //compilerwarning + repeat + while true do begin + ca1:= 1; + wo1:= wnetenumresource(handle,ca1,po1,ca2); + if wo1 = error_more_data then begin + reallocmem(po1,ca2); + end + else begin + break; + end; + end; + if wo1 = no_error then begin + if (po1^.dwtype = resourcetype_disk) and (po1^.lpremotename <> nil) and + (strcomp(pchar(name),rembackslash(po1^.lpremotename)) = 0) then begin + resource:= po1; + result:= sye_ok; + break; + end + else begin + if po1^.dwUsage and resourceusage_container <> 0 then begin + resource:= po1; + result:= findserver(name,resource); + end + end; + end + else begin + result:= networkerror(wo1); + end; + until (wo1 <> no_error) or (result = sye_ok); + wnetcloseenum(handle); + if resource <> po1 then begin + freemem(po1); + end; +end; + +function sys_opendirstream(var stream: dirstreamty): syserrorty; +var + wo1: longword; + int1: integer; +begin + with stream,dirinfo,dirstreamwin32ty(platformdata) do begin + checkdirstreamdata(stream); + result:= sye_ok; + if dirname <> '/' then begin + if msestartsstr('//',dirname) then begin //UNC + if length(dirname) = 2 then begin + finddatapo:= nil; + result:= findservers(nil,msestringarty(finddatapo)); + if finddatapo <> nil then begin + result:= sye_ok; + end; + drivenum:= -3; //network root + handle:= 0; + { + wo1:= wnetopenenum(resource_globalnet,resourcetype_disk,0,nil,handle); + if wo1 <> no_error then begin + result:= sye_dirstream; + end; + } + exit; + end + else begin + if countchars(dirname,msechar('/')) = 2 then begin //list shares + drivenum:= -2; + finddatapo:= nil; + result:= findserver(copy(ansiuppercase(ansistring(dirname)),3,bigint), + pnetresource(finddatapo)); + if finddatapo <> nil then begin + result:= sye_ok; + end; + if result = sye_ok then begin + wo1:= wnetopenenum(resource_globalnet,resourcetype_disk,0, + pnetresource(finddatapo),handle); + if wo1 <> no_error then begin + result:= networkerror(wo1); + end; + freemem(finddatapo); + end; + exit; + end; + end; + end; + drivenum:= -1; + last:= true; + new(finddatapo); + if iswin95 then begin + handle:= findfirstfilea(pchar(string(winfilepath(stream.dirinfo.dirname,'*'))), + {$ifdef FPC} + lpwin32_find_data(finddatapo)); + {$else} + _win32_find_dataa(pointer(finddatapo)^)); + {$endif} + end + else begin + handle:= findfirstfilew(pmsechar(winfilepath(stream.dirinfo.dirname,'*')), + {$ifdef FPC} + lpwin32_find_dataw(finddatapo)); + {$else} + _win32_find_dataw(finddatapo^)); + {$endif} + end; + if handle = invalid_handle_value then begin + int1:= getlasterror; + if int1 <> error_file_not_found then begin + dispose(finddatapo); + setlasterror(int1); + result:= syelasterror; + end; + end + else begin + last:= false; + end; + end; + end; +end; + +function sys_closedirstream(var stream: dirstreamty): syserrorty; +begin + with dirstreamwin32ty(stream.platformdata) do begin + case drivenum of + -3: begin + finalize(msestringarty(finddatapo)); + end; + -2: begin + wnetcloseenum(handle); + end; + -1: begin + dispose(finddatapo); + if handle <> invalid_handle_value then begin + windows.findclose(handle); + end; + end; + end; + end; + result:= sye_ok; +end; + +function sys_readdirstream(var stream: dirstreamty; var info: fileinfoty): boolean; + + procedure checkinfo; + begin + result:= ((fa_all in stream.dirinfo.include) or + (info.extinfo1.attributes * stream.dirinfo.include <> [])) and + (info.extinfo1.attributes * stream.dirinfo.exclude = []) and + checkfilename(info.name,stream); + end; + +var + ca1,ca2: cardinal; + wo1: longword; + po1: pnetresource; + po2: pchar; + +begin + with stream,dirinfo,dirstreamwin32ty(platformdata),finddatapo^,winfo do begin + result:= false; + if (include <> []) and not (fa_all in exclude) then begin + case drivenum of + -3: begin //network root + info.state:= [fis_typevalid,fis_extinfo1valid]; + info.extinfo1.attributes:= [fa_dir]; + info.extinfo1.filetype:= ft_dir; + if integer(handle) <= high(msestringarty(finddatapo)) then begin + repeat + info.name:= msestringarty(finddatapo)[handle]; + checkinfo; + inc(handle); + until result or (integer(handle) > high(msestringarty(finddatapo))); + end; + end; + -2: begin //network share + info.state:= [fis_typevalid,fis_extinfo1valid]; + info.extinfo1.attributes:= [fa_dir]; + info.extinfo1.filetype:= ft_dir; + getmem(po1,sizeof(tnetresource)); + fillchar(po1^,sizeof(tnetresource),0); + ca2:= sizeof(tnetresource); + wo1:= 0; //compilerwarning + repeat + while true do begin + ca1:= 1; + wo1:= wnetenumresource(handle,ca1,po1,ca2); + if wo1 = error_more_data then begin + reallocmem(po1,ca2); + end + else begin + break; + end; + end; + if wo1 = no_error then begin + po2:= strrscan(po1^.lpRemoteName,'\'); + if po2 <> nil then begin + info.name:= msestring( + copy(po1^.lpRemoteName,po2-po1^.lpRemoteName+2,bigint)); + checkinfo; + end + else begin + break; + end; + end + else begin + break; + end; + until result; + freemem(po1); + end; + -1: begin //local root dir + if not last then begin + repeat + if iswin95 then begin + info.name:= pwinfilenameaty(@cfilename)^; + end + else begin + info.name:= cfilename; + end; +{ + if file_attribute_directory and dwfileattributes <> 0 then begin + info.extinfo1.filetype:= ft_dir; + end + else begin + info.extinfo1.filetype:= ft_reg; + end; +} + winfileinfotofileinfo(winfo,wsize,info); + if infolevel = fil_ext2 then begin + //read security level + end; + checkinfo; + if iswin95 then begin + last:= not findnextfilea(handle, + {$ifdef FPC} + lpwin32_find_data(finddatapo)); + {$else} + _win32_find_dataa(pointer(finddatapo)^)); + {$endif} + end + else begin + last:= not findnextfilew(handle, + {$ifdef FPC} + lpwin32_find_dataw(finddatapo)); + {$else} + _win32_find_dataw(finddatapo^)); + {$endif} + end; + until result or last; + end; + end + else begin + ca1:= getlogicaldrives; + info.extinfo1.filetype:= ft_dir; + info.state:= info.state + [fis_typevalid,fis_extinfo1valid]; + info.extinfo1.attributes:= [fa_dir]; + while (drivenum < 32) and not result do begin + if ca1 and bits[drivenum] <> 0 then begin + setlength(info.name,2); + info.name[1]:= msechar(ord('A') + drivenum); + info.name[2]:= ':'; + checkinfo; + end; + inc(drivenum); + end; + end; + end; + end; + end; +end; + +function sys_getfileinfo(const path: filenamety; var info: fileinfoty): boolean; +var + handle: integer; + wstr1: filenamety; + finddata: win32_find_dataw; + lwo1: longword; +begin + clearfileinfo(info); + wstr1:= tosysfilepath(path); + if iswin95 then begin + handle:= findfirstfilea(pchar(string(wstr1)), + {$ifdef FPC}@win32_find_dataa + {$else}twin32finddataa{$endif}(pointer(@finddata)^)); + end + else begin + handle:= findfirstfilew(pmsechar(wstr1), + {$ifdef FPC}@finddata + {$else}twin32finddataw(finddata){$endif}); + end; + if thandle(handle) <> invalid_handle_value then begin + with win32_find_dataw(finddata) do begin +{ + if winfo.dwfileattributes and file_attribute_directory <> 0 then begin + info.extinfo1.filetype:= ft_dir; + end + else begin + info.extinfo1.filetype:= ft_reg; + end; +} + winfileinfotofileinfo(winfo,wsize,info); + if iswin95 then begin + info.name:= pwinfilenameaty(@cfilename)^; + end + else begin + info.name:= cfilename; + end; + end; + windows.findclose(handle); + result:= true; + end + else begin //possibly a drive name + if iswin95 then begin + lwo1:= getfileattributes(pchar(string(wstr1))); + end + else begin + lwo1:= getfileattributesw(pmsechar(wstr1)); + end; + if lwo1 = $ffffffff then begin + result:= false; + end + else begin + if lwo1 and file_attribute_directory <> 0 then begin + info.extinfo1.filetype:= ft_dir; + end + else begin + info.extinfo1.filetype:= ft_reg; + end; + result:= true; + end; + end; +end; + +function sys_getfdinfo(const fd: longint; var info: fileinfoty): boolean; +var + info1: by_handle_file_information; +begin + clearfileinfo(info); + result:= getfileinformationbyhandle(fd,info1); + if result then begin + winfileinfotofileinfo(info1.winfo,info1.wsize,info); + end; +end; + +function sys_setfdrights(const fd: longint; + const rights: filerightsty; + const filename: filenamety = ''): syserrorty; +var //todo: use security attributes + info1: by_handle_file_information; + fname: filenamety; + bo1: boolean; + { + fmap: thandle; + pmem: pointer; + abuf: array[0..max_path] of char; + wbuf: array[0..max_path] of widechar; + dwo1: dword; + } +begin + if getfileinformationbyhandle(fd,info1) then begin + if s_iwusr in rights then begin + info1.winfo.dwfileattributes:= info1.winfo.dwfileattributes and + not file_attribute_readonly; + end + else begin + info1.winfo.dwfileattributes:= info1.winfo.dwfileattributes or + file_attribute_readonly; + end; + { + fmap:= createfilemapping(fd,nil,page_readonly,0,1,nil); + if fmap = 0 then begin + result:= syelasterror(); + end + else begin + pmem:= mapviewoffile(fmap,file_map_read,0,0,1); + if pmem = nil then begin + result:= syelasterror(); + end + else begin + if iswin95 then begin + dwo1:= getmappedfilenamea(getcurrentprocess(),pmem,@abuf,max_path); + end + else begin + dwo1:= getmappedfilenamew(getcurrentprocess(),pmem,@wbuf,max_path); + end; + if dwo1 = 0 then begin + result:= syelasterror(); + end + else begin + + end; + unmapviewoffile(pmem); + end; + closehandle(fmap); + end; + //how to set file attributes from handle on pre XP? + } + fname:= tosysfilepath(filename); + if iswin95 then begin + bo1:= setfileattributesa(pchar(string(fname)),info1.winfo.dwfileattributes); + end + else begin + bo1:= setfileattributesw(pwidechar(fname),info1.winfo.dwfileattributes); + end; + if not bo1 then begin + result:= syelasterror(); + end + else begin + result:= sye_ok; + end; + end + else begin + result:= syelasterror(); + end; +end; + +function sys_access(const path: filenamety; + const accessmodes: accessmodesty): syserrorty; +begin + result:= sye_notimplemented; +end; + +function sys_setfilerights(const path: filenamety; + const rights: filerightsty): syserrorty; +var + fname: filenamety; + dwo1: dword; + bo1: boolean; +begin + fname:= tosysfilepath(path); + if iswin95 then begin + dwo1:= getfileattributesa(pchar(string(fname))); + end + else begin + dwo1:= getfileattributesw(pwidechar(fname)); + end; + if dwo1 = 0 then begin + result:= syelasterror(); + end + else begin + if s_iwusr in rights then begin + dwo1:= dwo1 and not file_attribute_readonly; + end + else begin + dwo1:= dwo1 or file_attribute_readonly; + end; + if iswin95 then begin + bo1:= setfileattributesa(pchar(string(fname)),dwo1); + end + else begin + bo1:= setfileattributesw(pwidechar(fname),dwo1); + end; + if not bo1 then begin + result:= syelasterror(); + end + else begin + result:= sye_ok; + end; + end; +end; +{ +function sys_setfdrights(const rights: filerightsty; + const fd: longint): syserrorty; +begin +end; +} +function sys_getcurrentdir: msestring; +var + ca1: cardinal; + str1: string; +begin + if iswin95 then begin + repeat + ca1:= getcurrentdirectorya(0,nil); + setlength(str1,ca1-1); + until (ca1 < 2) or (getcurrentdirectorya(ca1,@str1[1]) = ca1-1); + result:= msestring(str1); + end + else begin + repeat + ca1:= getcurrentdirectoryw(0,nil); + setlength(result,ca1-1); + until (ca1 < 2) or (getcurrentdirectoryw(ca1,@result[1]) = ca1-1); + end; + tomsefilepath1(result); +end; + +function sys_getapphomedir: filenamety; +begin + result:= apphomedir; +end; + +function sys_getuserhomedir: filenamety; +begin + result:= userhomedir; +end; + +function sys_getusername: msestring; +var + s1: ansistring; + ms1: msestring; + i1: DWORD; +begin + result:= ''; + i1:= 256; + if iswin95 then begin + setlength(s1,i1); + if getusernamea(pointer(s1),@i1) then begin + setlength(s1,i1-1); + result:= msestring(s1); + end; + end + else begin + setlength(ms1,i1); + if getusernamew(pointer(ms1),@i1) then begin + setlength(ms1,i1-1); + result:= ms1; + end; + end; +end; + + +function sys_gettempdir: filenamety; +var + int1: integer; + fna1: filenamety; +// po1: pfilenamechar; +begin + setlength(fna1,max_path+10); + fna1[1]:= #0; + int1:= gettemppathw(length(fna1),pointer(fna1)); + if int1 > length(fna1) then begin + setlength(result,int1); + int1:= gettemppathw(length(fna1),pointer(fna1)); + end; + if assigned(getlongpathnamew) then begin + setlength(result,max_path+10); + int1:= getlongpathnamew(pointer(fna1),pointer(result),length(result)); + if int1 > length(result) then begin + setlength(result,int1); + int1:= getlongpathnamew(pointer(fna1),pointer(result),length(result)); + end; + setlength(result,int1); + end + else begin + setlength(fna1,int1); + result:= fna1; + end; + tomsefilepath1(result); +end; + +function sys_setcurrentdir(const dirname: filenamety): syserrorty; +var + str1: string; +begin + if iswin95 then begin + str1:= ansistring(tosysfilepath(dirname)); + if not setcurrentdirectorya(pchar(str1)) then begin + result:= syelasterror; + end + else begin + result:= sye_ok; + end; + end + else begin + if not setcurrentdirectoryw(pmsechar(tosysfilepath(dirname))) then begin + result:= syelasterror; + end + else begin + result:= sye_ok; + end; + end; +end; + +const + CSIDL_PROGRAMS = $0002; { %SYSTEMDRIVE%\Program Files } + CSIDL_PERSONAL = $0005; { %USERPROFILE%\My Documents } + CSIDL_FAVORITES = $0006; { %USERPROFILE%\Favorites } + CSIDL_STARTUP = $0007; { %USERPROFILE%\Start menu\Programs\Startup } + CSIDL_RECENT = $0008; { %USERPROFILE%\Recent } + CSIDL_SENDTO = $0009; { %USERPROFILE%\Sendto } + CSIDL_STARTMENU = $000B; { %USERPROFILE%\Start menu } + CSIDL_MYMUSIC = $000D; { %USERPROFILE%\Documents\My Music } + CSIDL_MYVIDEO = $000E; { %USERPROFILE%\Documents\My Videos } + CSIDL_DESKTOPDIRECTORY = $0010; { %USERPROFILE%\Desktop } + CSIDL_NETHOOD = $0013; { %USERPROFILE%\NetHood } + CSIDL_TEMPLATES = $0015; { %USERPROFILE%\Templates } + CSIDL_COMMON_STARTMENU = $0016; { %PROFILEPATH%\All users\Start menu } + CSIDL_COMMON_PROGRAMS = $0017; { %PROFILEPATH%\All users\Start menu\Programs } + CSIDL_COMMON_STARTUP = $0018; { %PROFILEPATH%\All users\Start menu\Programs\Startup } + CSIDL_COMMON_DESKTOPDIRECTORY = $0019; { %PROFILEPATH%\All users\Desktop } + CSIDL_APPDATA = $001A; { %USERPROFILE%\Application Data (roaming) } + CSIDL_PRINTHOOD = $001B; { %USERPROFILE%\Printhood } + CSIDL_LOCAL_APPDATA = $001C; { %USERPROFILE%\Local Settings\Application Data (non roaming) } + CSIDL_COMMON_FAVORITES = $001F; { %PROFILEPATH%\All users\Favorites } + CSIDL_INTERNET_CACHE = $0020; { %USERPROFILE%\Local Settings\Temporary Internet Files } + CSIDL_COOKIES = $0021; { %USERPROFILE%\Cookies } + CSIDL_HISTORY = $0022; { %USERPROFILE%\Local settings\History } + CSIDL_COMMON_APPDATA = $0023; { %PROFILESPATH%\All Users\Application Data } + CSIDL_WINDOWS = $0024; { %SYSTEMROOT% } + CSIDL_SYSTEM = $0025; { %SYSTEMROOT%\SYSTEM32 (may be system on 95/98/ME) } + CSIDL_PROGRAM_FILES = $0026; { %SYSTEMDRIVE%\Program Files } + CSIDL_MYPICTURES = $0027; { %USERPROFILE%\My Documents\My Pictures } + CSIDL_PROFILE = $0028; { %USERPROFILE% } + CSIDL_PROGRAM_FILES_COMMON = $002B; { %SYSTEMDRIVE%\Program Files\Common } + CSIDL_COMMON_TEMPLATES = $002D; { %PROFILEPATH%\All Users\Templates } + CSIDL_COMMON_DOCUMENTS = $002E; { %PROFILEPATH%\All Users\Documents } + CSIDL_COMMON_ADMINTOOLS = $002F; { %PROFILEPATH%\All Users\Start Menu\Programs\Administrative Tools } + CSIDL_ADMINTOOLS = $0030; { %USERPROFILE%\Start Menu\Programs\Administrative Tools } + CSIDL_COMMON_MUSIC = $0035; { %PROFILEPATH%\All Users\Documents\my music } + CSIDL_COMMON_PICTURES = $0036; { %PROFILEPATH%\All Users\Documents\my pictures } + CSIDL_COMMON_VIDEO = $0037; { %PROFILEPATH%\All Users\Documents\my videos } + CSIDL_CDBURN_AREA = $003B; { %USERPROFILE%\Local Settings\Application Data\Microsoft\CD Burning } + CSIDL_PROFILES = $003E; { %PROFILEPATH% } + + CSIDL_FLAG_CREATE = $8000; { (force creation of requested folder if it doesn't exist yet) } + +type + SHGetFolderPathW = function (hwndowner: HWND; nFolder: integer; hToken: thandle; + dwFlags: DWORD; pszPath: LPTSTR): HRESULT; stdcall; +procedure doinit; +var + libhandle: thandle; + po1: SHGetFolderPathW; + buffer: array[0..max_path] of widechar; +// int1: integer; + +begin + gmtoff:= sys_localtimeoffset; + po1:= nil; //compiler warning + libhandle:= loadlibrary('shell32.dll'); + if libhandle <> 0 then begin + {$ifdef FPC}pointer(po1){$else}po1{$endif}:= + getprocaddress(libhandle,'SHGetFolderPathW'); + if not assigned(po1) then begin + freelibrary(libhandle); + libhandle:= loadlibrary('shfolder.dll'); + if libhandle <> 0 then begin + {$ifdef FPC}pointer(po1){$else}po1{$endif}:= + getprocaddress(libhandle,'SHGetFolderPathW'); + end; + end; + end; + if libhandle <> 0 then begin + if assigned(po1) then begin + if po1(0,CSIDL_APPDATA or CSIDL_FLAG_CREATE,0,0,@buffer) = 0 then begin + apphomedir:= filepath(buffer,fk_file); + end; + if po1(0,CSIDL_PROFILE or CSIDL_FLAG_CREATE,0,0,@buffer) = 0 then begin + userhomedir:= filepath(buffer,fk_file); + end; + end; + freelibrary(libhandle); + end; + checkprocaddresses(['kernel32.dll'], + ['GetLongPathNameW'], + [{$ifndef FPC}@{$endif}@GetLongPathNameW]); + checkprocaddresses(['user32.dll'], + ['AllowSetForegroundWindow'], + [{$ifndef FPC}@{$endif}@AllowSetForegroundWindow]); + checkprocaddresses(['ntdll.dll'],['ZwQueryInformationProcess'], + [@ZwQueryInformationProcess]); + checkprocaddresses(['ntdll.dll'],['NtQueryInformationProcess'], + [@NtQueryInformationProcess]); + checkprocaddresses(['kernel32.dll'],['GetProcessId'], + [@GetProcessId]); +end; +{ +procedure initformatsettings; +begin + thousandseparatormse:= thousandseparator; + decimalseparatormse:= decimalseparator; + dateseparatormse:= dateseparator; + timeseparatormse:= timeseparator; +end; +} +initialization +{$ifdef FPC} +// winwidestringalloc:= false; + {$endif} +// initformatsettings; + doinit; +//iswin95:= true; +//iswin98:= true; +end. diff --git a/mseide-msegui/lib/common/kernel/windows/msesysintf1.pas b/mseide-msegui/lib/common/kernel/windows/msesysintf1.pas new file mode 100644 index 0000000..2b05eb0 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/windows/msesysintf1.pas @@ -0,0 +1,577 @@ +{ MSEgui Copyright (c) 1999-2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msesysintf1; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$if fpc_fullversion >= 30001} + {$define hascompareoptions} +{$endif} +interface +uses + msesystypes; +var + iswin95: boolean; + iswin98: boolean; + cancleartype: boolean; + +{$include ..\msesysintf1.inc} + +type + win32semty = record //64 bit + event: thandle; //8 + semacount: integer; //4 + destroyed: integer; //4 total 16 + {$ifdef cpu64} //semty = 64 + platformdata: array[2..7] of pointer; + {$else} + platformdata: array[3..7] of pointer; + {$endif} + end; + +implementation +uses + windows,sysutils,dateutils,msedynload; + +type + {$ifdef FPC} + PCRITICAL_SECTION_DEBUG = ^CRITICAL_SECTION_DEBUG; + //bug in struct.inc + CRITICAL_SECTION = record + DebugInfo : PCRITICAL_SECTION_DEBUG; + LockCount : LONG; + RecursionCount : LONG; + OwningThread : HANDLE; + LockSemaphore : HANDLE; + Reserved : DWORD; + end; + {$endif} + win32mutexty = record //64bit + mutex: trtlcriticalsection; //40 bytes + trycount: integer; //4 + lockco: integer; //4 + owningth: threadty; //8 total 56 + {$ifdef cpu64} //mutexty = 80 + platformdata: array[7..9] of pointer; // 24 + {$else} + platformdata: array[7..7] of pointer; + {$endif} + end; + + condeventsty = (ce_signal,ce_broadcast); + win32condty = record //64bit + events: array[condeventsty] of thandle; //16 + waiterscountlock: trtlcriticalsection; //40 + mutex: trtlcriticalsection; //40 total 100 + waiterscount: integer; //4 + {$ifdef cpu64} //condty = 256 + platformdata: array[25..63] of cardinal; // 156 + {$else} + platformdata: array[15..31] of pointer; + {$endif} + end; + +var + TryEnterCriticalSection: function ( + var lpCriticalSection: TRTLCriticalSection): BOOL; stdcall; + +function sys_getlasterror: Integer; +begin + result:= windows.GetLastError; +end; + +procedure sys_setlasterror(const avalue: integer); +begin + windows.setlasterror(avalue); +end; + +function sys_geterrortext(aerror: integer): string; +const + maxlen = 1024; +var + int1: integer; +begin + setlength(result,maxlen); + int1:= formatmessage(format_message_from_system,nil,aerror,0,pchar(result),maxlen,nil); + setlength(result,int1); +end; + +function sys_mutexcreate(out mutex: mutexty): syserrorty; +begin + with win32mutexty(mutex) do begin + windows.initializecriticalsection(mutex); + trycount:= 0; + lockco:= 0; + owningth:= 0; + end; + result:= sye_ok; +end; + +function sys_mutexdestroy(var mutex: mutexty): syserrorty; +begin + result:= sye_ok; + windows.deletecriticalsection(win32mutexty(mutex).mutex); +end; + +function lockmutex(var mutex: mutexty; const noblock: boolean): syserrorty; +var +// bo1: boolean; + id: threadty; +begin + with win32mutexty(mutex) do begin + if not iswin95 then begin + if noblock then begin + if not tryentercriticalsection(mutex) then begin + result:= sye_busy; + exit; + end; + end + else begin + windows.entercriticalsection(mutex); + end; + end + else begin + while interlockedincrement(trycount) > 1 do begin + interlockeddecrement(trycount); + windows.sleep(0); + end; + id:= threadty(windows.getcurrentthreadid); + if noblock and not((lockco = 0) or (owningth = id)) then begin + interlockeddecrement(trycount); + result:= sye_busy; + exit; + end; + inc(lockco); + interlockeddecrement(trycount); + windows.entercriticalsection(mutex); + owningth:= id; + end; + end; + result:= sye_ok; +end; + +function sys_mutexlock(var mutex: mutexty): syserrorty; +begin + result:= lockmutex(mutex,false); +end; + +function sys_mutextrylock(var mutex: mutexty): syserrorty; +begin + result:= lockmutex(mutex,true); +end; + +function sys_mutexunlock(var mutex: mutexty): syserrorty; +begin + with win32mutexty(mutex) do begin + if iswin95 then begin + while interlockedincrement(trycount) > 1 do begin + interlockeddecrement(trycount); + windows.sleep(0); + end; + dec(lockco); + if lockco = 0 then begin + owningth:= 0; + end; + interlockeddecrement(trycount); + end; + windows.leavecriticalsection(mutex); + end; + result:= sye_ok; +end; + +function sys_semcreate(out sem: semty; count: integer): syserrorty; +begin + fillchar(sem,sizeof(sem),0); + with win32semty(sem) do begin + semacount:= count; + event:= createevent(nil,false,false,nil); + result:= sye_ok; + end; +end; + +function sempost1(var sem: semty): syserrorty; +begin + with win32semty(sem) do begin + if interlockedincrement(semacount) <= 0 then begin + setevent(event); + end; + result:= sye_ok; + end; +end; + +function sys_sempost(var sem: semty): syserrorty; +begin + with win32semty(sem) do begin + if destroyed <> 0 then begin + result:= sye_semaphore; + exit; + end; + end; + result:= sempost1(sem); +end; + +function sys_semdestroy(var sem: semty): syserrorty; +var + int1: integer; + +begin + with win32semty(sem) do begin + int1:= interlockedincrement(destroyed); + if int1 = 1 then begin + while semacount < 0 do begin + sempost1(sem); + end; + closehandle(event); + end; + end; + result:= sye_ok; +end; + +function sys_semwait(var sem: semty; timeoutusec: integer): syserrorty; +var + int1: integer; +begin + result:= sye_semaphore; + with win32semty(sem) do begin + if destroyed <> 0 then begin + exit; + end; + if interlockeddecrement(semacount) < 0 then begin + if timeoutusec <= 0 then begin + timeoutusec:= integer(infinite); + end + else begin + timeoutusec:= timeoutusec div 1000; + end; + int1:= waitforsingleobject(event,timeoutusec); + if int1 = wait_object_0 then begin + result:= sye_ok; + end + else begin + if int1 = wait_timeout then begin + result:= sye_timeout; + end; + end; + end + else begin + result:= sye_ok; + end; + end; +end; + +function sys_semcount(var sem: semty): integer; +begin + with win32semty(sem) do begin + result:= semacount; + if result < 0 then begin + result:= 0; + end; + end; +end; + +function sys_semtrywait(var sem: semty): boolean; +begin + with win32semty(sem) do begin + if destroyed <> 0 then begin + result:= false; + exit; + end; + result:= semacount > 0; + if result then begin + result:= interlockeddecrement(semacount) >= 0; + if not result then begin + interlockeddecrement(semacount); + end; + end; + end; +end; + +function sys_condcreate(out cond: condty): syserrorty; +begin + with win32condty(cond) do begin + waiterscount:= 0; + windows.initializecriticalsection({$ifdef FPC}@{$endif}waiterscountlock); + windows.initializecriticalsection({$ifdef FPC}@{$endif}mutex); + events[ce_signal]:= createevent(nil,false,false,nil); + events[ce_broadcast]:= createevent(nil,true,false,nil); + end; + result:= sye_ok; +end; + +function sys_conddestroy(var cond: condty): syserrorty; +begin + with win32condty(cond) do begin + closehandle(events[ce_signal]); + closehandle(events[ce_broadcast]); + windows.deletecriticalsection({$ifdef FPC}@{$endif}waiterscountlock); + windows.deletecriticalsection({$ifdef FPC}@{$endif}mutex); + end; + result:= sye_ok; +end; + +function sys_condlock(var cond: condty): syserrorty; +begin + with win32condty(cond) do begin + windows.entercriticalsection({$ifdef FPC}@{$endif}mutex); + end; + result:= sye_ok; +end; + +function sys_condunlock(var cond: condty): syserrorty; +begin + with win32condty(cond) do begin + windows.leavecriticalsection({$ifdef FPC}@{$endif}mutex); + end; + result:= sye_ok; +end; + +function sys_condsignal(var cond: condty): syserrorty; +var + bo1: boolean; +begin + with win32condty(cond) do begin + windows.entercriticalsection({$ifdef FPC}@{$endif}waiterscountlock); + bo1:= waiterscount > 0; + windows.leavecriticalsection({$ifdef FPC}@{$endif}waiterscountlock); + if bo1 then begin + setevent(events[ce_signal]); + end; + end; + result:= sye_ok; +end; + +function sys_condbroadcast(var cond: condty): syserrorty; +var + bo1: boolean; +begin + with win32condty(cond) do begin + windows.entercriticalsection({$ifdef FPC}@{$endif}waiterscountlock); + bo1:= waiterscount > 0; + windows.leavecriticalsection({$ifdef FPC}@{$endif}waiterscountlock); + if bo1 then begin + setevent(events[ce_broadcast]); + end; + end; + result:= sye_ok; +end; + +function sys_condwait(var cond: condty; timeoutusec: integer): syserrorty; + //timeoutusec = 0 -> no timeout + //sye_ok -> condition signaled + //sye_timeout -> timeout + //sye_cond -> error +var + int1: integer; + bo1: boolean; + +begin + result:= sye_cond; + with win32condty(cond) do begin + windows.entercriticalsection({$ifdef FPC}@{$endif}waiterscountlock); + inc(waiterscount); + windows.leavecriticalsection({$ifdef FPC}@{$endif}waiterscountlock); + windows.leavecriticalsection({$ifdef FPC}@{$endif}mutex); + if timeoutusec = 0 then begin + timeoutusec:= integer(infinite); + end + else begin + timeoutusec:= timeoutusec div 1000; + end; + int1:= waitformultipleobjects(2,@events,false,timeoutusec); + windows.entercriticalsection({$ifdef FPC}@{$endif}waiterscountlock); + dec(waiterscount); + bo1:= (int1 = wait_object_0 + ord(ce_broadcast)) and (waiterscount = 0); + windows.leavecriticalsection({$ifdef FPC}@{$endif}waiterscountlock); + if bo1 then begin + resetevent(events[ce_broadcast]); + end; + if int1 = wait_timeout then begin + result:= sye_timeout; + end + else begin + if (int1 < wait_abandoned_0) or (int1 > wait_abandoned_0 + 1) then begin + result:= sye_ok; + end; + end; + windows.entercriticalsection({$ifdef FPC}@{$endif}mutex); + end; +end; + +function localtimeshift(value: tdatetime; const tolocal: boolean) : integer; + //todo: optimize + function systitodatetime(const ayear: word; const systi: systemtime): tdatetime; + var + wo1,wo2,wo3: word; + dt1: tdatetime; + int1: integer; + begin + with systi do begin + dt1:= encodedate(ayear,wmonth,1); + wo1:= dayoftheweek(dt1); + if wo1 = 7 then begin + wo1:= 0; //0 -> so + end; + wo2:= wday; //n't occurence + wo3:= 0; //compiler warning + for int1:= 1 to daysinamonth(ayear,wmonth) do begin + if wo1 = wdayofweek then begin + wo3:= int1; + dec(wo2); + if wo2 = 0 then begin + break; + end; + end; + wo1:= (wo1 + 1) mod 7; + end; + result:= encodedate(ayear,wmonth,wo3) + encodetime(whour,wminute,0,0); + end; + end; + +var + tinfo: time_zone_information; + year: word; + stddate,dldate: tdatetime; + bo1: boolean; +begin + {$ifdef FPC} + if gettimezoneinformation(@tinfo) = time_zone_id_invalid then begin + {$else} + if gettimezoneinformation(tinfo) = time_zone_id_invalid then begin + {$endif} + result:= 0; + end + else begin + with tinfo do begin + result:= bias; + if tolocal then begin + value:= incminute(value,-bias); //->localtime + end; + if (standarddate.wmonth <> daylightdate.wmonth) and (value > 0) then begin + try + year:= yearof(value); + stddate:= systitodatetime(year,standarddate); + dldate:= systitodatetime(year,daylightdate); + if stddate > dldate then begin + bo1:= (value >= dldate) and (value < stddate); + end + else begin + bo1:= (value <= dldate) and (value > stddate); + end; + if bo1 then begin + result:= result + daylightbias; + end + else begin + result:= result + standardbias; + end; + except + end; + end; + end; + end; + if tolocal then begin + result:= -result; + end; +end; + +function sys_utctolocaltime(const value: tdatetime): tdatetime; +begin + result:= incminute(value,localtimeshift(value,true)); +// result:= value + sys_localtimeoffset; //todo +end; + +function sys_localtimetoutc(const value: tdatetime): tdatetime; +begin + result:= incminute(value,localtimeshift(value,false)); +// result:= value - sys_localtimeoffset; //todo +end; + +{$ifdef FPC} +function DoCompareStringA(const s1, s2: unicodestring; Flags: DWORD): PtrInt; + var + a1, a2: AnsiString; + begin + a1:=ansistring(s1); + a2:=ansistring(s2); + SetLastError(0); + Result:=CompareStringA(LOCALE_USER_DEFAULT,Flags,pchar(a1), + length(a1),pchar(a2),length(a2))-2; + end; + +function DoCompareStringW(const s1, s2: unicodestring; Flags: DWORD): PtrInt; + begin + SetLastError(0); + Result:=CompareStringW(LOCALE_USER_DEFAULT,Flags,pwidechar(s1), + length(s1),pwidechar(s2),length(s2))-2; + if GetLastError=0 then + Exit; + if GetLastError=ERROR_CALL_NOT_IMPLEMENTED then // Win9x case + Result:=DoCompareStringA(s1, s2, Flags); + if GetLastError<>0 then + RaiseLastOSError; + end; + {$ifdef hascompareoptions} +function win32compareunicodestring(const s1, s2 : unicodestring; + options : tcompareoptions): ptrint; +var + flags: dword; +begin + flags:= 0; + if coignorecase in options then begin + flags:= norm_ignorecase; + end; + result:= docomparestringw(s1, s2, flags); +end; + {$else} +function Win32CompareUnicodeString(const s1, s2 : unicodestring) : PtrInt; + begin + Result:=DoCompareStringW(s1, s2, 0); + end; + +function Win32CompareTextunicodeString(const s1, s2 : unicodestring) : PtrInt; + begin + Result:=DoCompareStringW(s1, s2, NORM_IGNORECASE); + end; + {$endif} +{$endif} + +procedure doinit; +var + info: osversioninfo; + int1: integer; + +begin +{$ifdef FPC} + {$ifdef hascompareoptions} + widestringmanager.CompareUnicodeStringProc:=@win32CompareUnicodeString; + {$else} + widestringmanager.CompareUnicodeStringProc:=@win32CompareUnicodeString; + widestringmanager.CompareTextUnicodeStringProc:=@win32CompareTextUnicodeString; + {$endif} +{$endif} + + info.dwOSVersionInfoSize:= sizeof(info); + if getversionex(info) then begin + with info do begin + int1:= dwmajorversion*1000+dwminorversion; + cancleartype:= int1 >= 5001; + iswin95:= dwPlatformId = ver_platform_win32_windows; + if iswin95 then begin + iswin98:= (dwMajorVersion >= 4) or + (dwMajorVersion = 4) and (dwminorVersion > 0); + end; + end; + end; + checkprocaddresses(['kernel32.dll'], + ['TryEnterCriticalSection'], + [{$ifndef FPC}@{$endif}@TryEnterCriticalSection]); + +end; + +initialization + doinit; +end. diff --git a/mseide-msegui/lib/common/kernel/windows/msesystimer.pas b/mseide-msegui/lib/common/kernel/windows/msesystimer.pas new file mode 100644 index 0000000..700f201 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/windows/msesystimer.pas @@ -0,0 +1,198 @@ +{ MSEgui Copyright (c) 2010-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msesystimer; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseguiglob,mselist,msetypes,windows; + +function setsystimer(us: longword): guierrorty; + //send et_timer event after delay or us (micro seconds) +procedure systimerinit(const aeventlist: tobjectqueue; const apphandle: hwnd); +procedure systimerdeinit; +function systimerus: longword; +function setmmtimer(const avalue: boolean): boolean; + +implementation +uses + msewinglob,mseevent,msesys,msedynload{,mseguiintf},msedate; + +const + MMSYSERR_NOERROR = 0; + + TIME_ONESHOT = 0; { program timer for single event } + TIME_PERIODIC = 1; { program for continuous periodic event } + TIME_CALLBACK_FUNCTION = $0000; { callback is function } + TIME_CALLBACK_EVENT_SET = $0010; { callback is event - use SetEvent } + TIME_CALLBACK_EVENT_PULSE = $0020; { callback is event - use PulseEvent } + +type + MMRESULT = Longint; + PTimeCaps = ^TTimeCaps; + timecaps_tag = record + wPeriodMin: UINT; { minimum period supported } + wPeriodMax: UINT; { maximum period supported } + end; + TTimeCaps = timecaps_tag; + TIMECAPS = timecaps_tag; + TFNTimeCallBack = procedure(uTimerID, uMessage: UINT; + dwUser, dw1, dw2: DWORD) stdcall; +var + timeKillEvent: function (uTimerID: UINT): MMRESULT; stdcall; + timeGetDevCaps: function (lpTimeCaps: PTimeCaps; + uSize: UINT): MMRESULT; stdcall; + timeBeginPeriod: function (uPeriod: UINT): MMRESULT; stdcall; + timeEndPeriod: function (uPeriod: UINT): MMRESULT; stdcall; + timeSetEvent: function (uDelay, uResolution: UINT; + lpFunction: TFNTimeCallBack; dwUser: DWORD; uFlags: UINT): MMRESULT; stdcall; + timeGetTime: function: DWORD; stdcall; + +var + eventlist: tobjectqueue; + applicationhandle: hwnd; + + timer: longword; + mmtimer: mmresult; + usemmtimer: boolean = false; + hasmmtimer: boolean = false; + mmtimerchecked: boolean = false; +// mmtimershift: longword; + ticaps: ttimecaps; +// perfref: qword; +// perffrequ: qword; + +function checkmmtimer: boolean; +begin + result:= hasmmtimer; + if not result and not mmtimerchecked then begin + mmtimerchecked:= true; + hasmmtimer:= checkprocaddresses(['winmm.dll'], + ['timeKillEvent', + 'timeGetDevCaps', + 'timeBeginPeriod', + 'timeEndPeriod', + 'timeSetEvent', + 'timeGetTime'], + [{$ifndef FPC}@{$endif}@timeKillEvent, + {$ifndef FPC}@{$endif}@timeGetDevCaps, + {$ifndef FPC}@{$endif}@timeBeginPeriod, + {$ifndef FPC}@{$endif}@timeEndPeriod, + {$ifndef FPC}@{$endif}@timeSetEvent, + {$ifndef FPC}@{$endif}@timeGetTime]); + result:= hasmmtimer and + (timegetdevcaps(@ticaps,sizeof(timecaps)) = MMSYSERR_NOERROR); + end; +end; + +function setmmtimer(const avalue: boolean): boolean; +begin + result:= true; + if avalue then begin + if not usemmtimer then begin + result:= checkmmtimer; + if result then begin + usemmtimer:= true; + timebeginperiod(ticaps.wperiodmin); + end; + end; + end + else begin + if usemmtimer then begin + timeendperiod(ticaps.wperiodmin); + usemmtimer:= false; + end; + end; +end; + +function systimerus: longword; +begin + if usemmtimer then begin + result:= timegettime() * 1000; + end + else begin + result:= gettickcount * 1000; + end; +end; + +procedure killtimer; +begin + if timer <> 0 then begin + windows.killtimer(0,timer); + timer:= 0; + end; + if mmtimer <> 0 then begin + timekillevent(mmtimer); + mmtimer:= 0; + end; +end; + +procedure TimerProc(hwnd: hwnd; uMsg: longword; idEvent: ptruint; + dwTime: longword); stdcall; +begin + killtimer; + eventlist.add(tmseevent.create(ek_timer)); +end; + +procedure mmtimerproc(uTimerID, uMessage: UINT; + dwUser, dw1, dw2: DWORD); stdcall; +begin + killtimer; + windows.postmessage(applicationhandle,timermessage,0,0); +end; + +function setsystimer(us: longword): guierrorty; +var + ms: longword; +begin + killtimer; + if usemmtimer then begin + ms:= us div 1000; + if ms < ticaps.wperiodmin then begin + ms:= ticaps.wperiodmin; + end; + mmtimer:= timesetevent(ms,1,@mmtimerproc,0,time_oneshot); + //1ms resolution + if mmtimer = 0 then begin + result:= gue_timer; + end + else begin + result:= gue_ok; + end; + end + else begin + timer:= windows.settimer(0,0,us div 1000,@timerproc); + if timer = 0 then begin + result:= gue_timer; + end + else begin + result:= gue_ok; + end; + end; +end; + +procedure systimerdeinit; +begin + killtimer; + eventlist:= nil; +end; + +procedure systimerinit(const aeventlist: tobjectqueue; const apphandle: hwnd); +begin + eventlist:= aeventlist; + applicationhandle:= apphandle; +end; + +initialization +finalization + if usemmtimer then begin + timeendperiod(ticaps.wperiodmin); + usemmtimer:= false; + end; +end. diff --git a/mseide-msegui/lib/common/kernel/windows/mseuniintf.pas b/mseide-msegui/lib/common/kernel/windows/mseuniintf.pas new file mode 100644 index 0000000..e7524c8 --- /dev/null +++ b/mseide-msegui/lib/common/kernel/windows/mseuniintf.pas @@ -0,0 +1,27 @@ +{ MSEgui Copyright (c) 1999-2007 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseuniintf; //i386-win32 +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msegraphics; + +{$include ..\mseuniintf.inc} + +implementation +uses + mseguiintf; + +function uni_getfontwithglyph(var drawinfo: drawinfoty): boolean; +begin + result:= false; +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/windows/msewindnd.pas b/mseide-msegui/lib/common/kernel/windows/msewindnd.pas new file mode 100644 index 0000000..b788a7d --- /dev/null +++ b/mseide-msegui/lib/common/kernel/windows/msewindnd.pas @@ -0,0 +1,1048 @@ +{ MSEgui Copyright (c) 2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msewindnd; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + windows,msetypes,msegui,mseguiintf,mseguiglob,msegraphutils,msestrings, + mseclasses,activex,mseglob,msedragglob; + +type + {$ifndef FPC} + WINOLEAPI = HResult; + HMetaFilePict = Pointer; + OleChar = WChar; + HALFPARAM = WORD; + HALFLRESULT = WORD; + LPOLESTR = ^OLECHAR; + tmessage = tmsg; + const + WM_QUIT = 18; + WM_USER = 1024; +type + {$endif} + + TagSTGMEDIUM = Record + Tymed : DWord; + Case Integer Of + 0: (dummy: pointer; + PUnkForRelease: Pointer {IUnknown}); + 1: (HBITMAP : hBitmap); + 2: (HMETAFILEPICT : hMetaFilePict); + 3: (HENHMETAFILE : hEnhMetaFile); + 4: (HGLOBAL : hGlobal); + 5: (lpszFileName : LPOLESTR); + 6: (pstm : Pointer{IStream}); + 7: (pstg : Pointer{IStorage}); + End; + USTGMEDIUM = TagSTGMEDIUM; + STGMEDIUM = USTGMEDIUM; + TStgMedium = TagSTGMEDIUM; + PStgMedium = ^TStgMedium; + + IDropSource = interface(IUnknown) + ['{00000121-0000-0000-C000-000000000046}'] + function QueryContinueDrag(fEscapePressed: BOOL; + grfKeyState: DWORD):HResult;StdCall; + function GiveFeedback(dwEffect: DWORD): HResult;StdCall; + end; + + ienumformatetc = interface(iunknown)['{00000103-0000-0000-c000-000000000046}'] + function next(celt: ulong; out rgelt: formatetc; + pceltfetched:pulong = nil): hresult; stdcall; + function skip(celt: ulong): hresult; stdcall; + function reset: hresult; stdcall; + function clone(out penum: ienumformatetc): hresult; stdcall; + end; + + idataobject = interface (iunknown) ['{0000010e-0000-0000-c000-000000000046}'] + function getdata(const formatetcin: formatetc; + out medium: stgmedium): hresult; stdcall; + function getdatahere(const pformatetc: formatetc; + var medium: stgmedium): hresult; stdcall; + function querygetdata(const pformatetc: formatetc): hresult; stdcall; + function getcanonicalformatetc(const pformatetcin: formatetc; + out pformatetcout: formatetc): hresult; stdcall; + function setdata (const pformatetc: formatetc; + const medium:stgmedium; frelease: bool): hresult; stdcall; + function enumformatetc(dwdirection : dword; + out enumformatetcpara: ienumformatetc): hresult; stdcall; + function dadvise(const formatetc : formatetc; advf: dword; + const advsink: iadvisesink; + out dwconnection: dword): hresult; stdcall; + function dunadvise(dwconnection: dword): hresult; stdcall; + function enumdadvise(out enumadvise: ienumstatdata): hresult; stdcall; + end; + + idroptarget = interface(iunknown) ['{00000122-0000-0000-c000-000000000046}'] + function dragenter(const dataobj: idataobject; grfkeystate: dword; + pt: tpoint; var dweffect: dword): hresult; stdcall; + function dragover(grfkeystate: dword; pt: tpoint; + var dweffect: dword): hresult; stdcall; + function dragleave: hresult;stdcall; + function drop(const dataobj: idataobject; grfkeystate: dword; pt: tpoint; + var dweffect: dword):hresult; stdcall; + end; + +function RegisterDragDrop(hwnd:HWND; pDropTarget: IDropTarget): WINOLEAPI; + stdcall; external 'ole32.dll' name 'RegisterDragDrop'; +function RevokeDragDrop(hwnd:HWND):WINOLEAPI; + stdcall; external 'ole32.dll' name 'RevokeDragDrop'; +function DoDragDrop(pDataObj: IDataObject; pDropSource: IDropSource; + dwOKEffects: DWORD; pdwEffect: LPDWORD): WINOLEAPI; + stdcall; external 'ole32.dll' name 'DoDragDrop'; +procedure ReleaseStgMedium(var _para1:STGMEDIUM);stdcall; + external 'ole32.dll' name 'ReleaseStgMedium'; + +procedure regsysdndwindow(const awindow: winidty); +procedure windnddeinit; +function sysdnd(const action: sysdndactionty; + const aintf: isysdnd; const arect: rectty; + out aresult: boolean): guierrorty; +function sysdndreaddata(var adata: string; + const typeindex: integer): guierrorty; +function sysdndreadtext(var atext: msestring; + const typeindex: integer): guierrorty; +//todo: scrolling + +implementation +uses + msethread,msesysutils,sysutils,mseevent,msesysdnd; +type + sdndeventkindty = (sdndk_regwindow,sdndk_unregwindow,sdndk_reject,sdndk_accept, + sdndk_finished,sdndk_readdataortext, + sdndk_writebegin,sdndk_writecheck,sdndk_writeend); + + tsdndevent = class(tmseevent) + private + fsdndkind: sdndeventkindty; + fwinid: winidty; + factions: dndactionsty; + fintf: isysdnd; + frect: rectty; + findex: integer; + fdatapo: pstring; + ftextpo: pmsestring; + public + property sdndkind: sdndeventkindty read fsdndkind; + constructor create(const akind: sdndeventkindty; + const awinid: winidty = 0; + const aactions: dndactionsty = []; + const aintf: isysdnd = nil; + const arect: prectty = nil; + const aindex: integer = -1; + const adatapo: pstring = nil; + const atextpo: pmsestring = nil); + end; + + tdataobject = class(tlinkedobject,idataobject,idropsource) + private + fcheckpending: integer; + protected + fdata: stringarty; + ftext: msestringarty; + findex: integer; + fintf: isysdnd; + factions: dndactionsty; + ftargetactions: dndactionsty; + fformats: msestringarty; + fformatistext: booleanarty; + fcformats: integerarty; + fdrop: boolean; + fcancel: boolean; + ffinished: boolean; + function checkformat(const aformat: formatetc): hresult; + function getdatasize(out apo: pointer): integer; + function dogetdata(var medium: stgmedium): hresult; + procedure begindrag(const aevent: tsdndevent); + + //idataobject + function getdata(const formatetcin: formatetc; + out medium: stgmedium): hresult; stdcall; + function getdatahere(const pformatetc: formatetc; + var medium: stgmedium): hresult; stdcall; + function querygetdata(const pformatetc: formatetc): hresult; stdcall; + function getcanonicalformatetc(const pformatetcin : formatetc; + out pformatetcout: formatetc): hresult; stdcall; + function setdata (const pformatetc: formatetc; + const medium: stgmedium; frelease: bool): hresult; stdcall; + function enumformatetc(dwdirection: dword; + out enumformatetcpara: ienumformatetc): hresult; stdcall; + function dadvise(const formatetc: formatetc; advf: dword; + const advsink: iadvisesink; out dwconnection: dword): hresult; stdcall; + function dunadvise(dwconnection: dword): hresult; stdcall; + function enumdadvise(out enumadvise: ienumstatdata): hresult; stdcall; + //idropsource + function querycontinuedrag(fescapepressed: bool; + grfkeystate: dword):hresult; stdcall; + function givefeedback(dweffect: dword): hresult; stdcall; + end; + + writestatety = (ws_active,{ws_cancel,ws_drop,}ws_checking); + writestatesty = set of writestatety; + + oleformatarty = array of tformatetc; + tsysdndhandler = class(teventthread,idroptarget) + protected + fdragwinid: winidty; + fdataobject: idataobject; + foleformats: oleformatarty; + fformats: msestringarty; + fformatistext: booleanarty; + fdata: tdataobject; +// fdestaction: dndactionsty; + fwritestate: writestatesty; + function execute(thread: tmsethread): integer; override; + function getwinid(const apos: pointty): winidty; + procedure clearformats; + procedure writecheck(const aactions: dndactionsty; var aresult: boolean); + + //iunknown + function queryinterface({$ifdef fpc_has_constref}constref{$else}const{$endif} + iid: tguid; out obj): hresult; virtual; stdcall; + function _addref: integer; stdcall; + function _release: integer; stdcall; + //idroptarget + function dragenter(const dataobj: idataobject; grfkeystate: dword; + pt: tpoint; var dweffect: dword): hresult; stdcall; + function dragover(grfkeystate: dword; pt: tpoint; + var dweffect: dword): hresult; stdcall; + function dragleave: hresult; stdcall; + function drop(const dataobj: idataobject; grfkeystate: dword; pt: tpoint; + var dweffect: dword):hresult; stdcall; + public + constructor create; + destructor destroy; override; + procedure terminate; override; + procedure postevent(event: tsdndevent; const aquit: boolean); + function waitevent(const timeoutus: integer = -1): tsdndevent; + procedure regsysdndwindow(const awindow: winidty); + end; + + tenumformatetc = class(tinterfacedobject,ienumformatetc) + private + fdataobj: tdataobject; + findex: integer; + protected + function next(celt: ulong; out rgelt: formatetc; + pceltfetched:pulong = nil): hresult; stdcall; + function skip(celt: ulong): hresult; stdcall; + function reset: hresult; stdcall; + function clone(out penum: ienumformatetc): hresult; stdcall; + public + constructor create(const adataobj: tdataobject); + end; + +const + timeout = 500000; //us + predefclipboardnames: array[1..16] of msestring = ( + 'CF_TEXT', //1 + 'CF_BITMAP', //2 + 'CF_METAFILEPICT',//3 + 'CF_SYLK', //4 + 'CF_DIF', //5 + 'CF_TIFF', //6 + 'CF_OEMTEXT', //7 + 'CF_DIB', //8 + 'CF_PALETTE', //9 + 'CF_PENDATA', //10 + 'CF_RIFF', //11 + 'CF_WAVE', //12 + 'CF_UNICODETEXT', //13 + 'CF_ENHMETAFILE', //14 + 'CF_HDROP', //15 + 'CF_LOCALE' //16 + ); + +var + cannotole: boolean; + sysdndhandler: tsysdndhandler; + +function winactiontoaction(const aaction: dword): dndactionsty; +begin + result:= []; + if aaction and dropeffect_copy <> 0 then begin + include(result,dnda_copy); + end; + if aaction and dropeffect_move <> 0 then begin + include(result,dnda_move); + end; + if aaction and dropeffect_link <> 0 then begin + include(result,dnda_link); + end; +end; + +function actiontowinaction(const aaction: dndactionsty): dword; +begin + result:= 0; + if dnda_copy in aaction then begin + result:= result or dropeffect_copy; + end; + if dnda_move in aaction then begin + result:= result or dropeffect_move; + end; + if dnda_link in aaction then begin + result:= result or dropeffect_link; + end; +end; + +function wintoshiftstate(const aflags: longword): shiftstatesty; +const + mk_alt = $20; //who knows... +begin + result:= []; + if aflags and mk_control <> 0 then begin + include(result,ss_ctrl); + end; + if aflags and mk_shift <> 0 then begin + include(result,ss_shift); + end; + if aflags and mk_alt <> 0 then begin + include(result,ss_alt); + end; + if aflags and mk_lbutton <> 0 then begin + include(result,ss_left); + end; + if aflags and mk_mbutton <> 0 then begin + include(result,ss_middle); + end; + if aflags and mk_rbutton <> 0 then begin + include(result,ss_right); + end; +end; + +function sysdnd(const action: sysdndactionty; + const aintf: isysdnd; const arect: rectty; + out aresult: boolean): guierrorty; +var + act1: dndactionsty; +begin + aresult:= false; + if (sysdndhandler = nil) then begin + result:= gue_nodragpending; + end + else begin + result:= gue_ok; + if aintf <> nil then begin + act1:= aintf.getactions; + end; + with sysdndhandler do begin + case action of + sdnda_reject: begin + postevent(tsdndevent.create(sdndk_reject),false); + end; + sdnda_accept: begin + postevent(tsdndevent.create(sdndk_accept,0,act1),false); + end; + sdnda_finished: begin + postevent(tsdndevent.create(sdndk_finished),true); + end; + sdnda_begin: begin + postevent(tsdndevent.create(sdndk_writebegin,0,act1,aintf),true); + semwait; + end; + sdnda_check: begin + writecheck(act1,aresult); + end; + sdnda_drop,sdnda_destroyed: begin + if action = sdnda_drop then begin + fdata.fdrop:= true; //dndthread in blocking dodragdrop + end + else begin + fdata.fcancel:= true; //dndthread in blocking dodragdrop + end; + postevent(tsdndevent.create(sdndk_writeend,0,act1,aintf), + action = sdnda_destroyed); + end; + else begin + result:= gue_notimplemented; + end; + end; + end; + end; +end; + +function sysdndreaddata(var adata: string; + const typeindex: integer): guierrorty; +begin + if (sysdndhandler = nil) then begin + result:= gue_nodragpending; + end + else begin + result:= gue_ok; + with sysdndhandler do begin + postevent(tsdndevent.create(sdndk_readdataortext,0,[],nil,nil, + typeindex,@adata,nil),false); + semwait; + end; + end; +end; + +function sysdndreadtext(var atext: msestring; + const typeindex: integer): guierrorty; +begin + if (sysdndhandler = nil) then begin + result:= gue_nodragpending; + end + else begin + result:= gue_ok; + with sysdndhandler do begin + postevent(tsdndevent.create(sdndk_readdataortext,0,[],nil,nil, + typeindex,nil,@atext),false); + semwait; + end; + end; +end; + +procedure regsysdndwindow(const awindow: winidty); +begin + if (sysdndhandler = nil) and not cannotole then begin + sysdndhandler:= tsysdndhandler.create; + sysdndhandler.semwait; + if cannotole then begin + freeandnil(sysdndhandler); + exit; + end; + end; + sysdndhandler.regsysdndwindow(awindow); +end; + +procedure windnddeinit; +begin + freeandnil(sysdndhandler); +end; + + +{ tenumformatetc } + +constructor tenumformatetc.create(const adataobj: tdataobject); +begin + fdataobj:= adataobj; +end; + +function tenumformatetc.next(celt: ulong; out rgelt: formatetc; + pceltfetched: pulong = nil): hresult; stdcall; +var + int1: integer; + po1: pformatetc; +begin + int1:= celt; + if int1 + findex > high(fdataobj.fcformats) then begin + int1:= length(fdataobj.fcformats) - findex; + end; + if int1 < 0 then begin + int1:= 0; + end; + po1:= @rgelt; + if int1 < celt then begin + result:= s_false; + end + else begin + result:= s_ok; + end; + for int1:= 0 to int1-1 do begin + fillchar(po1^,sizeof(po1^),0); + with po1^ do begin + cfformat:= fdataobj.fcformats[findex]; + tymed:= tymed_hglobal; + end; + inc(findex); + inc(po1); + end; +end; + +function tenumformatetc.skip(celt: ulong): hresult; stdcall; +begin + result:= s_ok; + findex:= findex + celt; + if findex > high(fdataobj.fcformats) then begin + findex:= length(fdataobj.fcformats); + result:= s_false; + end; +end; + +function tenumformatetc.reset: hresult; stdcall; +begin + findex:= 0; + result:= s_ok; +end; + +function tenumformatetc.clone(out penum: ienumformatetc): hresult; stdcall; +var + inst: tenumformatetc; +begin + inst:= tenumformatetc.create(fdataobj); + inst.findex:= findex; + penum:= ienumformatetc(inst); + result:= s_ok; +end; + +{ tsdndevent } + +constructor tsdndevent.create(const akind: sdndeventkindty; + const awinid: winidty = 0; + const aactions: dndactionsty = []; + const aintf: isysdnd = nil; + const arect: prectty = nil; + const aindex: integer = -1; + const adatapo: pstring = nil; + const atextpo: pmsestring = nil); + +begin + fsdndkind:= akind; + fwinid:= awinid; + factions:= aactions; + fintf:= aintf; + if arect = nil then begin + frect:= nullrect; + end + else begin + frect:= arect^; + end; + findex:= aindex; + fdatapo:= adatapo; + ftextpo:= atextpo; + inherited create(ek_mse); +end; + +{ tdataobject } + +function tdataobject.checkformat(const aformat: formatetc): hresult; +var + int1: integer; +begin + result:= dv_e_formatetc; + findex:= -1; + for int1:= 0 to high(fcformats) do begin + if fcformats[int1] = aformat.cfformat then begin + findex:= int1; + result:= s_ok; + break; + end; + end; +end; + +function tdataobject.getdatasize(out apo: pointer): integer; +begin + application.lock; + if fformatistext[findex] then begin + if ftext[findex] = '' then begin + if fintf <> nil then begin + ftext[findex]:= fintf.convertmimetext(findex); + end; + end; + result:= length(ftext[findex]) * sizeof(msechar); + apo:= pointer(ftext[findex]); + end + else begin + if fdata[findex] = '' then begin + if fintf <> nil then begin + fdata[findex]:= fintf.convertmimedata(findex); + end; + end; + result:= length(fdata[findex]); + apo:= pointer(fdata[findex]); + end; + application.unlock; +end; + +function tdataobject.dogetdata(var medium: stgmedium): hresult; +var + po1,po2: pointer; + int1: integer; +begin + if medium.tymed <> tymed_hglobal then begin + result:= dv_e_tymed; + end + else begin + po1:= globallock(medium.hglobal); + if po1 = nil then begin + result:= e_unexpected; + end + else begin + int1:= getdatasize(po2); + if globalsize(medium.hglobal) < int1 then begin + result:= stg_e_mediumfull; + end + else begin + move(po2^,po1^,int1); + medium.punkforrelease:= nil; + result:= s_ok; + end; + globalunlock(medium.hglobal); + end; + end; +end; + +function tdataobject.getdata(const formatetcin: formatetc; + out medium: stgmedium): hresult; stdcall; +var + po1: pointer; +begin + result:= checkformat(formatetcin); + if result = s_ok then begin + medium.tymed:= tymed_hglobal; + medium.hglobal:= globalalloc(gmem_moveable,getdatasize(po1)); + if medium.hglobal = 0 then begin + result:= e_outofmemory; + end + else begin + result:= dogetdata(medium); + end; + end; +end; + +function tdataobject.getdatahere(const pformatetc: formatetc; + var medium: stgmedium): hresult; stdcall; +begin + result:= checkformat(pformatetc); + if result = s_ok then begin + result:= dogetdata(medium); + end; +end; + +function tdataobject.querygetdata( + const pformatetc: formatetc): hresult; stdcall; +begin + result:= checkformat(pformatetc); +end; + +function tdataobject.getcanonicalformatetc(const pformatetcin: formatetc; + out pformatetcout: formatetc): hresult; stdcall; +begin + pformatetcout:= pformatetcin; + pformatetcout.ptd:= nil; + result:= data_s_sameformatetc; +end; + +function tdataobject.setdata(const pformatetc: formatetc; + const medium: stgmedium; frelease: bool): hresult; stdcall; +begin + result:= e_notimpl; +end; + +function tdataobject.enumformatetc(dwdirection: dword; + out enumformatetcpara: ienumformatetc): hresult; stdcall; +begin + if dwdirection = datadir_set then begin + result:= e_notimpl; + end + else begin + result:= s_ok; + enumformatetcpara:= tenumformatetc.create(self); + end; +end; + +function tdataobject.dadvise(const formatetc: formatetc; advf: dword; + const advsink: iadvisesink; + out dwconnection: dword): hresult; stdcall; +begin + result:= e_notimpl; +end; + +function tdataobject.dunadvise(dwconnection: dword): hresult; stdcall; +begin + result:= ole_e_advisenotsupported; +end; + +function tdataobject.enumdadvise( + out enumadvise: ienumstatdata): hresult; stdcall; +begin + enumadvise:= nil; + result:= ole_e_advisenotsupported; +end; + +function getclipformatid(const aname: msestring): integer; +var + int1: integer; +begin + result:= 0; + for int1:= low(predefclipboardnames) to high(predefclipboardnames) do begin + if predefclipboardnames[int1] = aname then begin + result:= int1; + break; + end; + end; + if result = 0 then begin + result:= registerclipboardformatw(pwidechar(pmsechar(aname))); + end; +end; + +procedure tdataobject.begindrag(const aevent: tsdndevent); +var + int1: integer; +begin + getobjectlinker.setlinkedvar(iobjectlink(self),aevent.fintf, + iobjectlink(fintf)); + ftext:= nil; + fdata:= nil; + fcheckpending:= 0; + fdrop:= false; + fcancel:= false; + ffinished:= false; + factions:= fintf.getactions; + fformats:= fintf.getformats; + fformatistext:= fintf.getformatistext; + setlength(fformatistext,length(fformats)); + setlength(ftext,length(fformats)); + setlength(fdata,length(fformats)); + fcformats:= nil; + setlength(fcformats,length(fformats)); + for int1:= 0 to high(fformats) do begin + fcformats[int1]:= getclipformatid(fformats[int1]); + end; +end; + +function tdataobject.querycontinuedrag(fescapepressed: bool; + grfkeystate: dword): hresult; stdcall; +begin + application.lock; + result:= s_ok; + if (fintf = nil) or fcancel then begin + result:= dragdrop_s_cancel; + ffinished:= true; + end + else begin + if fdrop then begin + result:= dragdrop_s_drop; + ffinished:= true; + end; + end; + application.unlock; +end; + +function tdataobject.givefeedback(dweffect: dword): hresult; stdcall; +begin + if interlockeddecrement(fcheckpending) >= 0 then begin + application.lock; + if fintf <> nil then begin + ftargetactions:= winactiontoaction(dweffect); + application.postevent(tsysdndstatusevent.create( + fintf.geteventintf,ftargetactions <> [])); + end; + application.unlock; + end + else begin + interlockedincrement(fcheckpending); + end; + result:= s_ok; +end; + +{ tsysdndhandler } + +constructor tsysdndhandler.create; +begin + fdata:= tdataobject.create; + inherited create; +end; + +destructor tsysdndhandler.destroy; +begin + fdata.free; + inherited; +end; + +procedure tsysdndhandler.clearformats; +var + int1: integer; +begin + for int1:= 0 to high(foleformats) do begin + if foleformats[int1].ptd <> nil then begin + cotaskmemfree(foleformats[int1].ptd); + end; + end; + foleformats:= nil; + fformats:= nil; +end; + +procedure tsysdndhandler.postevent(event: tsdndevent; const aquit: boolean); +begin + inherited postevent(event); + if aquit then begin + postthreadmessage(id,wm_quit,0,0); //wakeup thread, cancel dodragdrop + end + else begin + postthreadmessage(id,wm_user,0,0); //wakeup thread + end; +end; + +procedure tsysdndhandler.terminate; +begin + inherited; + postthreadmessage(id,wm_quit,0,0); //wakeup thread +// postthreadmessage(id,wm_user,0,0); //wakeup thread +end; + +function tsysdndhandler.execute(thread: tmsethread): integer; +var + hres1: hresult; + ev1: tsdndevent; + int1: integer; + msg: tmessage; + medium: tstgmedium; + po1: pointer; + lwo1: longword; +begin + hres1:= oleinitialize(nil); + cannotole:= not((hres1 = s_ok) or (hres1 = s_false)); + sempost; + if not cannotole then begin + repeat + try + int1:= integer(getmessage({$ifdef FPC}@{$endif}msg,0,0,0)); + if int1 <> -1 then begin + translatemessage({$ifdef FPC}@{$endif}msg); + dispatchmessage({$ifdef FPC}@{$endif}msg); + end; + repeat + ev1:= tsdndevent(waitevent(0)); + if ev1 <> nil then begin + case ev1.sdndkind of + sdndk_regwindow: begin + registerdragdrop(ev1.fwinid,idroptarget(self)); + end; + sdndk_unregwindow: begin + revokedragdrop(ev1.fwinid); + end; + sdndk_finished: begin + fdataobject:= nil; + clearformats; + end; + sdndk_readdataortext: begin + if (ev1.findex >= 0) and (ev1.findex <= high(foleformats)) and + (fdataobject <> nil) then begin + fillchar(medium,sizeof(medium),0); + with medium do begin + tymed:= tymed_hglobal; + if fdataobject.getdata(foleformats[ev1.findex], + medium) = s_ok then begin + int1:= globalsize(hglobal); + po1:= globallock(hglobal); + if ev1.ftextpo <> nil then begin + setlength(ev1.ftextpo^,(int1+1) div 2); + move(po1^,ev1.ftextpo^[1],int1); + end + else begin + setlength(ev1.fdatapo^,int1); + move(po1^,ev1.fdatapo^[1],int1); + end; + globalunlock(hglobal); + releasestgmedium(medium); + end; + end; + end; + sempost; + end; + sdndk_writebegin: begin + clearformats; +// fcheckpending:= 0; + fwritestate:= [ws_active]; + fdata.begindrag(ev1); + sempost; +// dodragdrop(idataobject(fdata),idropsource(self), +// actiontowinaction(ev1.factions),@lwo1); + end; + sdndk_writecheck: begin + if ws_active in fwritestate then begin + if fdata.fintf = nil then begin + sempost; + end + else begin + include(fwritestate,ws_checking); + sempost; + beginsdndwrite(id); + hres1:= dodragdrop(idataobject(fdata),idropsource(fdata), + actiontowinaction(fdata.factions),@lwo1); //blocking + exclude(fwritestate,ws_checking); + endsdndwrite; +// application.lock; +// try +// if (fdata.fintf <> nil) and fdata.ffinished then begin +// fdata.fintf.cancelsysdnd; +// end; +// finally +// application.unlock; +// end; + end; + end; + end; + end; + ev1.free; + end; + until (ev1 = nil) or terminated; + except + application.handleexception; + end; + until terminated; + clearformats; + oleuninitialize; + end; + result:= 0; +end; + +procedure tsysdndhandler.regsysdndwindow(const awindow: winidty); +begin + postevent(tsdndevent.create(sdndk_regwindow,awindow),false); +end; + +function tsysdndhandler._addref: integer; stdcall; +begin + result:= -1; +end; + +function tsysdndhandler._release: integer; stdcall; +begin + result:= -1; +end; + +function tsysdndhandler.queryinterface( + {$ifdef fpc_has_constref}constref{$else}const{$endif} iid: tguid; + out obj): hresult; stdcall; +begin + if getinterface(iid, obj) then begin + result:=0 + end + else begin + result:= integer(e_nointerface); + end; +end; + +function tsysdndhandler.dragenter(const dataobj: idataobject; + grfkeystate: dword; pt: tpoint; var dweffect: dword): hresult; stdcall; +const + chunkcount = 16; +var + ev1: tsdndevent; + effect1: dword; + enumformat: ienumformatetc; + count1: integer; + lwo1: longword; + int1,int2: integer; + buffer: array[0..max_path] of msechar; +begin + fdragwinid:= getwinid(pointty(pt)); + effect1:= dropeffect_none; + clearevents; + if fdragwinid <> 0 then begin + fdataobject:= dataobj; + clearformats; + if fdataobject.enumformatetc(datadir_get,enumformat) = s_ok then begin + setlength(foleformats,chunkcount); + count1:= 0; + lwo1:= 0; + while enumformat.next(chunkcount,foleformats[count1],@lwo1) = s_ok do begin + setlength(foleformats,length(foleformats)+chunkcount); + count1:= count1 + lwo1; + end; + count1:= count1 + lwo1; + setlength(foleformats,count1); + setlength(fformats,length(foleformats)); + for int1:= 0 to high(fformats) do begin + with foleformats[int1] do begin + int2:= getclipboardformatnamew(cfformat,@buffer,max_path); + if int2 > 0 then begin + fformats[int1]:= buffer; + end + else begin + if (cfformat >= low(predefclipboardnames)) and + (cfformat <= high(predefclipboardnames)) then begin + fformats[int1]:= predefclipboardnames[cfformat]; + end; + end; + end; + end; + application.postevent(tsysdndevent.create(dek_check,fdragwinid,pointty(pt), + wintoshiftstate(grfkeystate),false,fformats,fformatistext, + winactiontoaction(dweffect))); + ev1:= waitevent(timeout); + if (ev1 <> nil) and (ev1.sdndkind = sdndk_accept) then begin + effect1:= actiontowinaction(ev1.factions) + end; + ev1.free; + end; + end; + dweffect:= effect1; + result:= s_ok; +end; + +function tsysdndhandler.dragover(grfkeystate: dword; pt: tpoint; + var dweffect: dword): hresult; stdcall; +var + ev1: tsdndevent; + effect1: dword; +begin + effect1:= dropeffect_none; + if fdragwinid <> 0 then begin + application.postevent(tsysdndevent.create(dek_check,fdragwinid,pointty(pt), + wintoshiftstate(grfkeystate),false,fformats,fformatistext, + winactiontoaction(dweffect))); + ev1:= waitevent(timeout); + if (ev1 <> nil) and (ev1.sdndkind = sdndk_accept) then begin + effect1:= actiontowinaction(ev1.factions) + end; + ev1.free; + end; + dweffect:= effect1; + result:= s_ok; +end; + +function tsysdndhandler.dragleave: hresult; stdcall; +begin + if fdragwinid <> 0 then begin + application.postevent(tsysdndevent.create(dek_leavesysdnd,fdragwinid, + nullpoint,[],false,nil,nil,[])); + fdataobject:= nil; + fdragwinid:= 0; + clearformats; + end; + result:= s_ok; +end; + +function tsysdndhandler.drop(const dataobj: idataobject; grfkeystate: dword; + pt: tpoint; var dweffect: dword): hresult; stdcall; +begin + if fdragwinid <> 0 then begin + application.postevent(tsysdndevent.create(dek_drop,fdragwinid,pointty(pt), + wintoshiftstate(grfkeystate),false,fformats,fformatistext, + winactiontoaction(dweffect))); + end; + result:= s_ok; +end; + +function tsysdndhandler.getwinid(const apos: pointty): winidty; +var + window1: twindow; +begin + result:= 0; + application.lock; + window1:= application.windowatpos(apos); + if (window1 <> nil) and window1.haswinid then begin //do not create winid + result:= window1.winid; + end; + application.unlock; +end; + +function tsysdndhandler.waitevent(const timeoutus: integer = -1): tsdndevent; +begin + result:= tsdndevent(inherited waitevent(timeoutus)); +end; + +procedure tsysdndhandler.writecheck(const aactions: dndactionsty; + var aresult: boolean); +begin + if not (ws_checking in fwritestate) then begin + postevent(tsdndevent.create(sdndk_writecheck,0,aactions),false); + semwait; + end; + aresult:= fdata.ftargetactions * aactions <> []; + interlockedincrement(fdata.fcheckpending); +end; + +end. diff --git a/mseide-msegui/lib/common/kernel/windows/msewinglob.pas b/mseide-msegui/lib/common/kernel/windows/msewinglob.pas new file mode 100644 index 0000000..264514f --- /dev/null +++ b/mseide-msegui/lib/common/kernel/windows/msewinglob.pas @@ -0,0 +1,24 @@ +{ MSEgui Copyright (c) 1999-2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msewinglob; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + windows{$ifndef FPC},messages{$endif}; + +const + msemessage = wm_user + $3694; + wakeupmessage = msemessage + 1; + destroymessage = msemessage + 2; + traycallbackmessage = msemessage + 3; + timermessage = msemessage + 4; + +implementation +end. diff --git a/mseide-msegui/lib/common/math/msefft.pas b/mseide-msegui/lib/common/math/msefft.pas new file mode 100644 index 0000000..2de9c78 --- /dev/null +++ b/mseide-msegui/lib/common/math/msefft.pas @@ -0,0 +1,287 @@ +{ MSEide Copyright (c) 2010 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit msefft; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + mseclasses,msetypes,msefftw; + +type + + fftstatety = (ffs_inited,ffs_windowvalid); + fftstatesty = set of fftstatety; + + windowfuncty = (wf_rectangular,wf_hann,wf_hamming); + + tfft = class(tmsecomponent) + private + fplan: fftw_plan; + finpreal: pdouble; + finpcomplex: pcomplexty; + foutreal: pdouble; + foutcomplex: pcomplexty; + finprealar: realarty; + finpcomplexar: complexarty; + fn: integer; + fnout: integer; + fwindowdata: doublearty; + fwindowfunc: windowfuncty; + fwindowfuncpar0: double; + fwindowfuncpar1: double; + procedure setinpreal(const avalue: realarty); + procedure setinpcomplex(const avalue: complexarty); + function getoutreal: realarty; + function getoutcomplex: complexarty; + procedure setwindowfunc(const avalue: windowfuncty); + procedure setwindowfuncpar0(const avalue: double); + procedure setwindowfuncpar1(const avalue: double); + protected + fstate: fftstatesty; + procedure checkwindowfunc; + procedure checkinit; + procedure resetwindowdata; + public + destructor destroy; override; + procedure clear; + property inpreal: realarty write setinpreal; + property inpcomplex: complexarty write setinpcomplex; + property outreal: realarty read getoutreal; + property outcomplex: complexarty read getoutcomplex; + published + property windowfunc: windowfuncty read fwindowfunc + write setwindowfunc default wf_rectangular; + property windowfuncpar0: double read fwindowfuncpar0 + write setwindowfuncpar0; + property windowfuncpar1: double read fwindowfuncpar1 + write setwindowfuncpar1; + end; + +implementation +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{ tfft } + +destructor tfft.destroy; +begin + clear; + if ffs_inited in fstate then begin + releasefftw; + end; + inherited; +end; + +procedure tfft.clear; +begin + if ffs_inited in fstate then begin + if fplan <> nil then begin + fftw_destroy_plan(fplan); + fplan:= nil; + end; + fftw_freemem(pointer(finpreal)); + fftw_freemem(pointer(finpcomplex)); + fftw_freemem(pointer(foutreal)); + fftw_freemem(pointer(foutcomplex)); + fn:= 0; + resetwindowdata; + end; +end; + +procedure tfft.checkwindowfunc; +var + nminus1: double; + int1: integer; +begin + if not (ffs_windowvalid in fstate) then begin + nminus1:= fn-1; + setlength(fwindowdata,fn); + case fwindowfunc of + wf_hann: begin + for int1:= 0 to high(fwindowdata) do begin + fwindowdata[int1]:= 0.5 * (1-cos((2*pi*int1)/nminus1)); + end; + end; + wf_hamming: begin + for int1:= 0 to high(fwindowdata) do begin + fwindowdata[int1]:= 0.54 - 0.46 * cos((2*pi*int1)/nminus1); + end; + end; + else begin + for int1:= 0 to high(fwindowdata) do begin + fwindowdata[int1]:= 1; + end; + end; + end; + include(fstate,ffs_windowvalid); + end; +end; + +function tfft.getoutreal: realarty; +var + po1: pcomplexty; + int1: integer; + do1: double; + po2: pdouble; +begin + checkinit; + if (finpcomplexar <> nil) then begin + if (foutcomplex <> nil) then begin + clear; + end; + if fn <> (length(finpcomplexar)-1)*2 then begin + clear; + end; //frequ -> time + if fplan = nil then begin + fn:= (length(finpcomplexar)-1)*2; + fftw_getmem(pointer(finpcomplex),(fn div 2 + 1) * sizeof(complexty)); + fftw_getmem(pointer(foutreal),fn * sizeof(double)); + fplan:= fftw_plan_dft_c2r_1d(fn,finpcomplex,foutreal,[fftw_estimate]); + end; + move(pointer(finpcomplexar)^,finpcomplex^,(fn div 2 + 1)*sizeof(complexty)); + fftw_execute(fplan); + setlength(result,fn); + move(foutreal^,pointer(result)^,fn*sizeof(double)); + end + else begin //time -> frequ + if (foutreal <> nil) then begin + clear; + end; + if fn <> length(finprealar) then begin + clear; + end; + result:= nil; + if finprealar <> nil then begin + if fplan = nil then begin + fn:= length(finprealar); + fftw_getmem(pointer(finpreal),fn * sizeof(double)); + fftw_getmem(pointer(foutcomplex),(fn div 2 + 1) * sizeof(complexty)); + fplan:= fftw_plan_dft_r2c_1d(fn,finpreal,foutcomplex,[fftw_estimate]); + end; + move(pointer(finprealar)^,finpreal^,fn*sizeof(double)); + if fwindowfunc <> wf_rectangular then begin + checkwindowfunc; + po2:= finpreal; + for int1:= 0 to high(fwindowdata) do begin + po2^:= po2^ * fwindowdata[int1]; + inc(po2); + end; + end; + fftw_execute(fplan); + setlength(result,fn div 2 + 1); + po1:= foutcomplex; + do1:= fn/2; + for int1:= 0 to high(result) do begin + result[int1]:= sqrt(po1^.re*po1^.re+po1^.im*po1^.im)/do1; + inc(po1); + end; + result[0]:= result[0]/2; //dc + end; + end; + fnout:= length(result); +end; + +function tfft.getoutcomplex: complexarty; +begin + checkinit; + if (foutreal <> nil) then begin + clear; + end; + if (finpcomplexar <> nil) then begin + if fn <> length(finpcomplexar) then begin + clear; + end; + end + else begin + if fn <> length(finprealar) then begin + clear; + end; + end; + result:= nil; //todo +end; + +procedure tfft.setinpreal(const avalue: realarty); +begin + if finpcomplexar <> nil then begin + clear; + finpcomplexar:= nil; + end; + finprealar:= avalue; +end; + +procedure tfft.setinpcomplex(const avalue: complexarty); +begin + if finprealar <> nil then begin + clear; + finprealar:= nil; + end; + finpcomplexar:= avalue; +end; + +procedure tfft.checkinit; +begin + if not (ffs_inited in fstate) then begin + initializefftw([]); + include(fstate,ffs_inited); + end; +end; + +procedure tfft.setwindowfunc(const avalue: windowfuncty); +begin + if avalue <> fwindowfunc then begin + fwindowfunc:= avalue; + resetwindowdata; + end; +end; + +procedure tfft.setwindowfuncpar0(const avalue: double); +begin + if avalue <> fwindowfuncpar0 then begin + fwindowfuncpar0:= avalue; + resetwindowdata; + end; +end; + +procedure tfft.setwindowfuncpar1(const avalue: double); +begin + if avalue <> fwindowfuncpar1 then begin + fwindowfuncpar1:= avalue; + resetwindowdata; + end; +end; + +procedure tfft.resetwindowdata; +begin + fwindowdata:= nil; + exclude(fstate,ffs_windowvalid); +end; + +end. diff --git a/mseide-msegui/lib/common/math/msefftw.pas b/mseide-msegui/lib/common/math/msefftw.pas new file mode 100644 index 0000000..d1c5dd1 --- /dev/null +++ b/mseide-msegui/lib/common/math/msefftw.pas @@ -0,0 +1,233 @@ +unit msefftw; +{ + FFTW - Fastest Fourier Transform in the West library + + This interface unit is (C) 2005 by Daniel Mantione + member of the Free Pascal development team. + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This file carries, as a independend work calling a well + documented binary interface, the Free Pascal LGPL license + with static linking exception. + + Note that the FFTW library itself carries the GPL license + and can therefore not be used in non-GPL software. + + Modified 2010 by Martin Schreiber +} + +interface +{$ifdef FPC} +{$mode objfpc}{$h+}{$interfaces corba} +{$MACRO on} +{$INLINE on} +{$endif} +uses + msetypes,msestrings; + +const +{$ifdef mswindows} + fftwlib: array[0..1] of filenamety = ('fftw3.dll','libfftw3-3.dll'); +{$else} + fftwlib: array[0..1] of filenamety = ('libfftw3.so.3','libfftw3.so'); +{$endif} + +{$IFDEF Unix} +//const +// fftwlib = 'fftw3f'; +{$ELSE} +//const +// fftwlib = 'libfftw3f'; +{$ENDIF} + +type // complex_single=record + // re,im:single; + // end; + // Pcomplex_single=^complex_single; + + fftw_plan = type pointer; + + fftw_sign = (fftw_forward = -1, fftw_backward = 1); + + fftw_flag = (fftw_measure, {generated optimized algorithm} + fftw_destroy_input, {default} + fftw_unaligned, {data is unaligned} + fftw_conserve_memory, {needs no explanation} + fftw_exhaustive, {search optimal algorithm} + fftw_preserve_input, {don't overwrite input} + fftw_patient, {generate highly optimized alg.} + fftw_estimate); {don't optimize, just use an alg.} + fftw_flagset = set of fftw_flag; + +var +{Complex to complex transformations.} +fftw_plan_dft_1d: function(n: cardinal; i,o: Pcomplexty; + sign: fftw_sign; flags: fftw_flagset): fftw_plan; cdecl; +fftw_plan_dft_2d: function(nx,ny: cardinal; i,o: Pcomplexty; + sign: fftw_sign; flags: fftw_flagset): fftw_plan; cdecl; +fftw_plan_dft_3d: function(nx,ny,nz: cardinal; i,o: Pcomplexty; + sign: fftw_sign; flags: fftw_flagset): fftw_plan; cdecl; + +fftw_plan_dft: function(rank: cardinal; n: Pcardinal; i,o: Pcomplexty; + sign: fftw_sign; flags: fftw_flagset): fftw_plan; cdecl; + +{Real to complex transformations.} +fftw_plan_dft_r2c_1d: function(n: cardinal; i:Pdouble; o: Pcomplexty; + flags:fftw_flagset): fftw_plan; cdecl; +fftw_plan_dft_r2c_2d: function(nx,ny: cardinal; i: Pdouble; o:Pcomplexty; + flags:fftw_flagset):fftw_plan; cdecl; +fftw_plan_dft_r2c_3d: function(nx,ny,nz: cardinal; i: Psingle; o: Pcomplexty; + flags: fftw_flagset): fftw_plan; cdecl; +fftw_plan_dft_r2c: function(rank:cardinal;n:Pcardinal;i:Psingle;o:Pcomplexty; + flags:fftw_flagset):fftw_plan; cdecl; + +{Complex to real transformations.} +fftw_plan_dft_c2r_1d: function(n: cardinal; i: Pcomplexty; o: Pdouble; + flags:fftw_flagset): fftw_plan; cdecl; +fftw_plan_dft_c2r_2d: function(nx,ny:cardinal; i: Pcomplexty; o:Pdouble; + flags: fftw_flagset): fftw_plan; cdecl; +fftw_plan_dft_c2r_3d: function(nx,ny,nz: cardinal; i: Pcomplexty; o: Pdouble; + flags: fftw_flagset): fftw_plan; cdecl; +fftw_plan_dft_c2r: function(rank: cardinal; n:Pcardinal; i:Pcomplexty; o: Pdouble; + flags: fftw_flagset):fftw_plan; cdecl; + + +fftw_destroy_plan: procedure(plan: fftw_plan); cdecl; +fftw_execute: procedure(plan: fftw_plan); cdecl; + +//{$calling register} {Back to normal!} +procedure fftw_getmem(var p: pointer; size: sizeint); +procedure fftw_freemem(var p: pointer);{$ifdef FPC}inline;{$endif} + +procedure initializefftw(const sonames: array of filenamety); + //[] = default +procedure releasefftw; + +implementation +uses + msedynload,msesys,sysutils; + +var + libinfo: dynlibinfoty; + +//{$ifndef Windows} +//{$LINKLIB fftw3f} +//{$endif} + +{Required libraries by libfftw3} +{ $LINKLIB gcc} +{ $LINKLIB c} +{ $LINKLIB m} + +{Better don't use fftw_malloc and fftw_free, but provide Pascal replacements.} + +{$IF defined(cpui386) or defined(cpupowerpc)} + {$DEFINE align:=16} +//{$ENDIF} +{$IFEND} + +procedure fftw_getmem(var p:pointer; size: sizeint); + +{$IFDEF align} +var + originalptr:pointer; +begin + { We allocate additional "align-1" bytes to be able to align. + And we allocate additional "SizeOf(Pointer)" to always have space to store + the value of the original pointer. } + getmem(originalptr,size + align-1 + SizeOf(Pointer)); + ptruint(p):=(ptruint(originalptr) + SizeOf(Pointer)); + ptruint(p):=(ptruint(p)+align-1) and not (align-1); + PPointer(ptruint(ptruint(p) - SizeOf(Pointer)))^:= originalptr; +{$ELSE} +begin + getmem(p,size); +{$ENDIF} +end; + +procedure fftw_freemem(var p: pointer); {$ifdef FPC}inline;{$endif} + +begin + if p <> nil then begin +{$IFDEF align} + freemem(PPointer(ptruint(ptruint(p) - SizeOf(Pointer)))^); +{$ELSE} + freemem(p); +{$ENDIF} + p:= nil; + end; +end; + +{$ifndef FPC} +var + funcs: array[0..13] of funcinfoty = ( + (n: 'fftw_plan_dft_1d'; d: nil), + (n: 'fftw_plan_dft_2d'; d: nil), + (n: 'fftw_plan_dft_3d'; d: nil), + (n: 'fftw_plan_dft'; d: nil), + (n: 'fftw_plan_dft_r2c_1d'; d: nil), + (n: 'fftw_plan_dft_r2c_2d'; d: nil), + (n: 'fftw_plan_dft_r2c_3d'; d: nil), + (n: 'fftw_plan_dft_r2c'; d: nil), + (n: 'fftw_plan_dft_c2r_1d'; d: nil), + (n: 'fftw_plan_dft_c2r_2d'; d: nil), + (n: 'fftw_plan_dft_c2r_3d'; d: nil), + (n: 'fftw_plan_dft_c2r'; d: nil), + (n: 'fftw_destroy_plan'; d: nil), + (n: 'fftw_execute'; d: nil)); +{$endif} +procedure initializefftw(const sonames: array of filenamety); + //[] = default +{$ifdef FPC} +const + funcs: array[0..13] of funcinfoty = ( + (n: 'fftw_plan_dft_1d'; d: @fftw_plan_dft_1d), + (n: 'fftw_plan_dft_2d'; d: @fftw_plan_dft_2d), + (n: 'fftw_plan_dft_3d'; d: @fftw_plan_dft_3d), + (n: 'fftw_plan_dft'; d: @fftw_plan_dft), + (n: 'fftw_plan_dft_r2c_1d'; d: @fftw_plan_dft_r2c_1d), + (n: 'fftw_plan_dft_r2c_2d'; d: @fftw_plan_dft_r2c_2d), + (n: 'fftw_plan_dft_r2c_3d'; d: @fftw_plan_dft_r2c_3d), + (n: 'fftw_plan_dft_r2c'; d: @fftw_plan_dft_r2c), + (n: 'fftw_plan_dft_c2r_1d'; d: @fftw_plan_dft_c2r_1d), + (n: 'fftw_plan_dft_c2r_2d'; d: @fftw_plan_dft_c2r_2d), + (n: 'fftw_plan_dft_c2r_3d'; d: @fftw_plan_dft_c2r_3d), + (n: 'fftw_plan_dft_c2r'; d: @fftw_plan_dft_c2r), + (n: 'fftw_destroy_plan'; d: @fftw_destroy_plan), + (n: 'fftw_execute'; d: @fftw_execute)); +{$endif} +const + errormessage = 'Can not load FFTW library. '; +begin +{$ifndef FPC} + funcs[0].d:= @fftw_plan_dft_1d; + funcs[1].d:= @fftw_plan_dft_2d; + funcs[2].d:= @fftw_plan_dft_3d; + funcs[3].d:= @fftw_plan_dft; + funcs[4].d:= @fftw_plan_dft_r2c_1d; + funcs[5].d:= @fftw_plan_dft_r2c_2d; + funcs[6].d:= @fftw_plan_dft_r2c_3d; + funcs[7].d:= @fftw_plan_dft_r2c; + funcs[8].d:= @fftw_plan_dft_c2r_1d; + funcs[9].d:= @fftw_plan_dft_c2r_2d; + funcs[1].d:= @fftw_plan_dft_c2r_3d; + funcs[11].d:= @fftw_plan_dft_c2r; + funcs[12].d:= @fftw_destroy_plan; + funcs[13].d:= @fftw_execute; +{$endif} + + initializedynlib(libinfo,sonames,fftwlib,funcs,[],errormessage); +end; + +procedure releasefftw; +begin + releasedynlib(libinfo); +end; + +initialization + initializelibinfo(libinfo); +finalization + finalizelibinfo(libinfo); +end. diff --git a/mseide-msegui/lib/common/math/msefilter.pas b/mseide-msegui/lib/common/math/msefilter.pas new file mode 100644 index 0000000..3ba962e --- /dev/null +++ b/mseide-msegui/lib/common/math/msefilter.pas @@ -0,0 +1,1253 @@ +{ MSEgui Copyright (c) 2010-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} + +// +// experimental +// + +unit msefilter; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + mseclasses,msedatalist,classes,mclasses,msetypes,msesignal,msearrayprops, + msereal; +type + + tdoublefiltercomp = class; + + tsections = class(tintegerarrayprop) + protected + fowner: tdoublefiltercomp; + function calccoeffcount: integer; + procedure dochange(const aindex: integer); override; +// procedure updatecoeffcount; + public + constructor create(const aowner: tdoublefiltercomp); + end; + + tdoublefiltercomp = class(tdoublezcomp) + private + fsections: tsections; + procedure setcoeff(const avalue: tdatalist); + procedure setsections(const avalue: tsections); + protected + fcoeff: tdatalist; + fcoeffchecking: boolean; + procedure coeffchanged(const sender: tdatalist; + const aindex: integer); override; + procedure createcoeff; virtual; abstract; + procedure zcountchanged; override; + procedure checkcoeffs; virtual; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property sections: tsections read fsections write setsections; + //array of coeffcount + end; + +// >---+-->(z)---+-->(z)---+-->(z)---+ +// b0 b1 b2 bN-1 +// +---------+---------+---------+---> +// + tsigfir = class(tdoublefiltercomp) + private + function getcoeff: trealcoeff; + procedure setcoeff(const avalue: trealcoeff); + protected + procedure createcoeff; override; +// procedure processinout(const acount: integer; +// var ainp,aoutp: pdouble); override; +// function getzcount: integer; override; + //isigclient + function gethandler: sighandlerprocty; override; + procedure sighandler(const ainfo: psighandlerinfoty); + published + property coeff: trealcoeff read getcoeff write setcoeff; + end; +// +---------+---------+---------+---> +// | -a1 -a2 -aN-1 +// +---(z)<--+---(z)<--+---(z)<--+ +// b0 b1 b2 bN-1 +// >---+---------+---------+---------+ +// + tsigiir = class(tdoublefiltercomp) + private + fcoeffsetting: boolean; + forigcoeff: tcomplexdatalist; + function getcoeff: tcomplexcoeff; + procedure setcoeff(const avalue: tcomplexcoeff); + procedure origcoeffchanged(const sender: tobject); + procedure setorigcoeff(const avalue: tcomplexdatalist); + protected + procedure createcoeff; override; + procedure checkcoeffs; override; + procedure defineproperties(filer: tfiler); override; +// procedure processinout(const acount: integer; +// var ainp,aoutp: pdouble); override; +// function getzcount: integer; override; + //isigclient + function gethandler: sighandlerprocty; override; + procedure sighandler(const ainfo: psighandlerinfoty); + public + constructor create(aowner: tcomponent); override; + destructor destroy(); override; + property origcoeff: tcomplexdatalist read forigcoeff write setorigcoeff; + published + property coeff: tcomplexcoeff read getcoeff write setcoeff; + end; + + sigfilterkindty = (sfk_lp1bilinear,sfk_lp1impulseinvariant, + sfk_lp2bilinear,sfk_bp2bilinear,sfk_bs2bilinear); + sigfilteroptionty = (sfo_passgainfix,sfo_noprewarp); + sigfilteroptionsty = set of sigfilteroptionty; + + tsigfilter = class(tsigmultiinpout) //todo: speed optimized prewarp + private + ffrequencypo: psigvaluety; + ffrequfactpo: psigvaluety; + fqfactorpo: psigvaluety; + famplitudepo: psigvaluety; + fgain: double; + fz1: double; + fz2: double; + fb0: double; + fb1: double; + fb2: double; + fa1: double; + fa2: double; + ffrequency: tdoubleinputconn; + fqfactor: tdoubleinputconn; + fkind: sigfilterkindty; + foptions: sigfilteroptionsty; + famplitude: tdoubleinputconn; + ffrequfact: tdoubleinputconn; + procedure setfrequency(const avalue: tdoubleinputconn); + procedure setqfactor(const avalue: tdoubleinputconn); + procedure setkind(const avalue: sigfilterkindty); + procedure setoptions(const avalue: sigfilteroptionsty); + procedure setamplitude(const avalue: tdoubleinputconn); + procedure setfrequfact(const avalue: tdoubleinputconn); + protected + procedure sighandlerlp1inv(const ainfo: psighandlerinfoty); + procedure sighandlerlp1bi(const ainfo: psighandlerinfoty); + procedure sighandlerlp2bi(const ainfo: psighandlerinfoty); + procedure sighandlerb2bi; + procedure sighandlerbp2bi(const ainfo: psighandlerinfoty); + procedure sighandlerbs2bi(const ainfo: psighandlerinfoty); + + //isigclient + function getinputar: inputconnarty; override; + function gethandler: sighandlerprocty; override; + procedure initmodel; override; + public + constructor create(aowner: tcomponent); override; + procedure clear; override; + published + property frequency: tdoubleinputconn read ffrequency + write setfrequency; + property frequfact: tdoubleinputconn read ffrequfact write setfrequfact; + property qfactor: tdoubleinputconn read fqfactor + write setqfactor; + property amplitude: tdoubleinputconn read famplitude + write setamplitude; + property kind: sigfilterkindty read fkind write setkind + default sfk_lp1bilinear; + property options: sigfilteroptionsty read foptions + write setoptions default []; + end; + + tfilterbanksection = class(townedpersistent) + private + ffrequfact: tdoubleinputconn; + fqfactor: tdoubleinputconn; + famplitude: tdoubleinputconn; + procedure setfrequfact(const avalue: tdoubleinputconn); + procedure setqfactor(const avalue: tdoubleinputconn); + procedure setamplitude(const avalue: tdoubleinputconn); + public + constructor create(aowner: tobject); override; + destructor destroy; override; + published + property frequfact: tdoubleinputconn read ffrequfact + write setfrequfact; + property qfactor: tdoubleinputconn read fqfactor + write setqfactor; + property amplitude: tdoubleinputconn read famplitude + write setamplitude; + end; + + tfilterbanksections = class(townedpersistentarrayprop) + private + protected + procedure getinputar(var inputs: inputconnarty); + procedure dosizechanged; override; + public + constructor create(const aowner: tcomponent); reintroduce; + class function getitemclasstype: persistentclassty; override; + //used in dumpunitgroups + published + end; + + filterinfoty = record + ffrequfactpo: psigvaluety; + fqfactorpo: psigvaluety; + famplitudepo: psigvaluety; + fa1: double; + fa2: double; + fb0: double; + fb1: double; + fb2: double; + z1: double; + z2: double; + end; + pfilterinfoty = ^filterinfoty; + filterinfoarty = array of filterinfoty; + + tsigfilterbank = class(tsigmultiinpout) //todo: speed optimized prewarp + private + fsections: tfilterbanksections; + ffrequency: tdoubleinputconn; + foptions: sigfilteroptionsty; + finfos: filterinfoarty; + finfohigh: integer; + fz1: double; + fz2: double; + ffrequencypo: psigvaluety; + famplitudepo: psigvaluety; + fbaseamplitudepo: psigvaluety; + famplitude: tdoubleinputconn; + fbaseamplitude: tdoubleinputconn; + procedure setfrequency(const avalue: tdoubleinputconn); + procedure setoptions(const avalue: sigfilteroptionsty); + procedure setsections(const avalue: tfilterbanksections); + procedure setamplitude(const avalue: tdoubleinputconn); + procedure setbaseamplitude(const avalue: tdoubleinputconn); + protected + //isigclient + procedure initmodel; override; + function getinputar: inputconnarty; override; + function gethandler: sighandlerprocty; override; + procedure sighandler(const ainfo: psighandlerinfoty); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure clear; override; + published + property frequency: tdoubleinputconn read ffrequency write setfrequency; + property amplitude: tdoubleinputconn read famplitude write setamplitude; + property baseamplitude: tdoubleinputconn read fbaseamplitude + write setbaseamplitude; + property options: sigfilteroptionsty read foptions + write setoptions default []; + property sections: tfilterbanksections read fsections write setsections; + end; + +implementation +uses + sysutils,math,msearrayutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tdoubleinputconn1 = class(tdoubleinputconn); + tcomplexdatalist1 = class(tcomplexdatalist); + +{ tdoublefiltercomp } + +constructor tdoublefiltercomp.create(aowner: tcomponent); +begin + fsections:= tsections.create(self); + createcoeff; + inherited; +end; + +destructor tdoublefiltercomp.destroy; +begin + inherited; + fcoeff.free; + fsections.free; +end; + +procedure tdoublefiltercomp.zcountchanged; +begin + inherited; + fcoeff.count:= fzcount; +end; + +procedure tdoublefiltercomp.setcoeff(const avalue: tdatalist); +begin + fcoeff.assign(avalue); +end; + +procedure tdoublefiltercomp.coeffchanged(const sender: tdatalist; + const aindex: integer); +begin + if not fcoeffchecking and (aindex < 0) then begin + fcoeffchecking:= true; + try + sender.count:= fzcount; + checkcoeffs; + finally + fcoeffchecking:= false; + end; +// setzcount(sender.count); +// fsections.updatecoeffcount; + end; +end; + +procedure tdoublefiltercomp.setsections(const avalue: tsections); +begin + fsections.assign(avalue); +end; + +procedure tdoublefiltercomp.checkcoeffs; +begin + //dummy +end; + +{ tsigfir } + +procedure tsigfir.createcoeff; +begin + fcoeff:= trealcoeff.create(self); + trealcoeff(fcoeff).defaultzero:= true; + trealcoeff(fcoeff).min:= -bigreal; +end; + +function tsigfir.getcoeff: trealcoeff; +begin + result:= trealcoeff(fcoeff); +end; + +procedure tsigfir.setcoeff(const avalue: trealcoeff); +begin + inherited setcoeff(avalue); +end; +(* +procedure tsigfir.processinout(const acount: integer; var ainp, aoutp: pdouble); +var //todo: optimize + int1,int2,int3: integer; + ar1: doublearty; + i,o: double; + po1: pdouble; + inp1,outp1: pdouble; + startindex1,endindex1,endindex2: integer; +begin + if fzcount > 0 then begin + inp1:= ainp; + outp1:= aoutp; + for int1:= acount-1 downto 0 do begin + po1:= fcoeff.datapo; + i:= ainp^; + startindex1:= fzindex; + for int3:= 0 to high(fsections.fitems) do begin + endindex1:= startindex1 + fsections.fitems[int3] - 1; + if endindex1 > fzhigh then begin + endindex2:= endindex1-fzhigh-1; + endindex1:= fzhigh; + end + else begin + endindex2:= -1; + end; + + fdoublez[startindex1]:= i; + o:= 0; + for int2:= startindex1 to endindex1 do begin + o:= o + fdoublez[int2] * po1^; + inc(po1); + end; + for int2:= 0 to endindex2 do begin + o:= o + fdoublez[int2] * po1^; + inc(po1); + end; + startindex1:= startindex1 + fsections.fitems[int3]; + if startindex1 >= fzcount then begin + startindex1:= startindex1 - fzcount; + end; + i:= o; + end; + outp1^:= o; + dec(fzindex); + if fzindex < 0 then begin + fzindex:= fzhigh; + end; + inc(outp1); + inc(inp1); + end; + ainp:= inp1; + aoutp:= outp1; + end + else begin + inc(ainp,acount); + inc(aoutp,acount); + end; +end; +*) +function tsigfir.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}sighandler; +end; + +procedure tsigfir.sighandler(const ainfo: psighandlerinfoty); +var //todo: optimize + {int1,}int2,int3: integer; +// ar1: doublearty; + i,o: double; + po1: pdouble; +// inp1,outp1: pdouble; + startindex1,endindex1,endindex2: integer; +begin + po1:= fcoeff.datapo; + i:= finput.value; + o:= 0; + startindex1:= fzindex; //ringbuffer + for int3:= 0 to high(fsections.fitems) do begin + endindex1:= startindex1 + fsections.fitems[int3] - 1; + if endindex1 > fzhigh then begin + endindex2:= endindex1-fzhigh-1; + endindex1:= fzhigh; + end + else begin + endindex2:= -1; + end; + + fdoublez[startindex1]:= i; + o:= 0; + for int2:= startindex1 to endindex1 do begin + o:= o + fdoublez[int2] * po1^; + inc(po1); + end; + for int2:= 0 to endindex2 do begin + o:= o + fdoublez[int2] * po1^; + inc(po1); + end; + startindex1:= startindex1 + fsections.fitems[int3]; + if startindex1 >= fzcount then begin + startindex1:= startindex1 - fzcount; + end; + i:= o; + end; + foutputpo^:= o; + dec(fzindex); + if fzindex < 0 then begin + fzindex:= fzhigh; + end; +end; +{ +function tsigfir.getzcount: integer; +var + int1,int2,int3: integer; +begin + result:= 0; + int3:= 0; + for int1:= 0 to fsections.count -1 do begin + for int2:= 0 to fsections[int1]-1 do begin + if int3 >= coeff.count then begin + exit; + end; + if coeff[int3] = 0 then begin + inc(result); + inc(int3); + end + else begin + int3:= int3 + fsections[int1]-int2; + break; + end; + end; + end; +end; +} +{ tsigiir } + +constructor tsigiir.create(aowner: tcomponent); +begin + forigcoeff:= tcomplexdatalist.create; + forigcoeff.onchange:= @origcoeffchanged; + inherited; +end; + +destructor tsigiir.destroy; +begin + inherited; + forigcoeff.free; +end; + +procedure tsigiir.createcoeff; +begin + fcoeff:= tcomplexcoeff.create(self); + tcomplexcoeff(fcoeff).defaultzero:= true; + tcomplexcoeff(fcoeff).min:= -bigreal; +end; + +function tsigiir.getcoeff: tcomplexcoeff; +begin + result:= tcomplexcoeff(fcoeff); +end; + +procedure tsigiir.setcoeff(const avalue: tcomplexcoeff); +begin + inherited setcoeff(avalue); +end; + +procedure tsigiir.origcoeffchanged(const sender: tobject); +var + int1,int2: integer; + norm: double; + ps,pd: pcomplexty; +begin + if not fcoeffsetting then begin + ps:= forigcoeff.datapo; + pd:= fcoeff.datapo; + for int1:= 0 to fsections.count-1 do begin + norm:= ps^.re; + if norm = 0 then begin + ps^.re:= 1.0; + norm:= 1.0; + end; + for int2:= 0 to fsections.fitems[int1]-1 do begin + pd^.re:= ps^.re/norm; + pd^.im:= ps^.im/norm; + inc(ps); + inc(pd); + end; + end; + end; +end; + +procedure tsigiir.setorigcoeff(const avalue: tcomplexdatalist); +begin + forigcoeff.assign(avalue); +end; + +procedure tsigiir.defineproperties(filer: tfiler); +begin + inherited; + tcomplexdatalist1(forigcoeff).defineproperties('origcoeff',filer); +end; + +(* +procedure tsigiir.processinout(const acount: integer; var ainp: pdouble; + var aoutp: pdouble); +var + int1,int2,int3: integer; + inp1,outp1: pdouble; + i,o: double; + po0: pcomplexty; + po1: pcomplexty; //todo: optimize +begin + if fzcount > 0 then begin + inp1:= ainp; + outp1:= aoutp; + po0:= fcoeff.datapo; + for int1:= acount-1 downto 0 do begin + po1:= po0; + i:= inp1^; + o:= i*po1^.im+fdoublez[0]; + int3:= 0; + for int2:= 1 to fzhigh do begin + inc(po1); + if int2 = fsections.fitems[int3] then begin + i:= o; + o:= i*po1^.im+fdoublez[int2]; + end + else begin + fdoublez[int2-1]:= fdoublez[int2] + i*po1^.im - o*po1^.re; + end; + end; + outp1^:= o; + inc(outp1); + inc(inp1); + end; + ainp:= inp1; + aoutp:= outp1; + end + else begin + inc(ainp,acount); + inc(aoutp,acount); + end; +end; +*) +function tsigiir.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}sighandler; +end; + +procedure tsigiir.sighandler(const ainfo: psighandlerinfoty); +var + {int1,}int2,int3,int4: integer; +// inp1,outp1: pdouble; + i,o: double; + po1: pcomplexty; //todo: optimize +begin + po1:= fcoeff.datapo; + i:= finput.value; + o:= i*po1^.im+fdoublez[0]; + int3:= 0; + int4:= fsections.fitems[0]; + for int2:= 1 to fzhigh do begin + inc(po1); + if int2 = int4 then begin //next section + inc(int3); + int4:= int4 + fsections.fitems[int3]; + i:= o; + o:= i*po1^.im+fdoublez[int2]; + end + else begin + fdoublez[int2-1]:= fdoublez[int2] + i*po1^.im - o*po1^.re; + end; + end; + foutputpo^:= o; +end; + +procedure tsigiir.checkcoeffs; +var + int1,int2: integer; + po1: pcomplexty; +begin + int2:= 0; + po1:= fcoeff.datapo; + for int1:= 0 to fsections.count-1 do begin + po1[int2].re:= 1.0; + int2:= int2 + fsections.fitems[int1]; + end; + if not fcoeffsetting then begin + fcoeffsetting:= true; + try + forigcoeff.assign(fcoeff); + finally + fcoeffsetting:= false; + end; + end; +end; + +{ +function tsigiir.getzcount: integer; +var + int1,int2,int3: integer; +begin + result:= 0; + int3:= 0; + for int1:= 0 to fsections.count -1 do begin + for int2:= 0 to fsections[int1]-1 do begin + if int3 >= coeff.count then begin + exit; + end; + if coeff[int3].im = 0 then begin + inc(result); + inc(int3); + end + else begin + int3:= int3 + fsections[int1]-int2; + break; + end; + end; + end; +end; +} +{ tsections } + +constructor tsections.create(const aowner: tdoublefiltercomp); +begin + fowner:= aowner; + inherited create; +end; + +function tsections.calccoeffcount: integer; +var + int1: integer; +begin + result:= 0; + for int1:= 0 to high(fitems) do begin + result:= result + fitems[int1]; + end; +end; + +procedure tsections.dochange(const aindex: integer); +begin + fowner.setzcount(calccoeffcount); +end; +{ +procedure tsections.updatecoeffcount; +var + int1: integer; +begin + if not (csloading in fowner.componentstate) then begin + int1:= fowner.zcount-calccoeffcount; + if int1 <> 0 then begin + beginupdate; + try + if int1 > 0 then begin //add + if fitems = nil then begin + setlength(fitems,1); + end; + fitems[high(fitems)]:= fitems[high(fitems)] + int1; + end + else begin + while int1 < 0 do begin //remove + fitems[high(fitems)]:= fitems[high(fitems)] + int1; + if fitems[high(fitems)] > 0 then begin + break; + end; + int1:= fitems[high(fitems)]; + setlength(fitems,high(fitems)); + end; + end; + finally + endupdate; + end; + end; + end; +end; +} +{ tsigfilter } + +constructor tsigfilter.create(aowner: tcomponent); +begin + ffrequency:= tdoubleinputconn.create(self,isigclient(self)); + ffrequency.name:= 'frequeny'; + ffrequency.value:= 0.01; + ffrequfact:= tdoubleinputconn.create(self,isigclient(self)); + ffrequfact.name:= 'frequfact'; + ffrequfact.value:= 1; + fqfactor:= tdoubleinputconn.create(self,isigclient(self)); + fqfactor.name:= 'qfactor'; + fqfactor.value:= 1; + famplitude:= tdoubleinputconn.create(self,isigclient(self)); + famplitude.name:= 'amplitude'; + famplitude.value:= 1; + inherited; +end; + +function tsigfilter.gethandler: sighandlerprocty; +begin + case fkind of + sfk_lp1impulseinvariant: begin + result:= {$ifdef FPC}@{$endif}sighandlerlp1inv; + end; + sfk_lp2bilinear: begin + result:= {$ifdef FPC}@{$endif}sighandlerlp2bi; + end; + sfk_bp2bilinear: begin + result:= {$ifdef FPC}@{$endif}sighandlerbp2bi; + end; + sfk_bs2bilinear: begin + result:= {$ifdef FPC}@{$endif}sighandlerbs2bi; + end; + else begin //sfk_lp1bilinear + result:= {$ifdef FPC}@{$endif}sighandlerlp1bi; + end; + end; +end; + +// +---------+---------+---------+---> o +// | -a1 -a2 -aN-1 +// +---(z)<--+---(z)<--+---(z)<--+ +// b0 b1 b2 bN-1 +// i >---+---------+---------+---------+ +// + +procedure tsigfilter.sighandlerlp1inv(const ainfo: psighandlerinfoty); +var + i,o,do1: double; + int1: integer; +begin + if (ffrequencypo^.changed <> []) or (ffrequfactpo^.changed <> []) then begin + exclude(ffrequencypo^.changed,sic_value); + exclude(ffrequfactpo^.changed,sic_value); + do1:= ffrequencypo^.value*ffrequfactpo^.value; + if do1 > 0 then begin + fb0:= 2*pi*do1; + fa1:= exp(-fb0); + end; + end; + i:= 0; + for int1:= 0 to finphigh do begin + i:= i+finps[int1]^.value; + end; + o:= i*fb0 + fz1; + foutputpo^:= o*famplitudepo^.value; + fz1:= o*fa1; +end; + +procedure tsigfilter.sighandlerlp1bi(const ainfo: psighandlerinfoty); +var + i,o: double; + do1: double; + int1: integer; +begin + if (ffrequencypo^.changed <> []) or (ffrequfactpo^.changed <> []) then begin + exclude(ffrequencypo^.changed,sic_value); + exclude(ffrequfactpo^.changed,sic_value); + do1:= ffrequencypo^.value*ffrequfactpo^.value; + if do1 > 0 then begin + do1:= 2*pi*do1; + fb0:= do1/(do1+2); + fb1:= fb0; + fa1:= (do1-2)/(do1+2); + end; + end; + i:= 0; + for int1:= 0 to finphigh do begin + i:= i+finps[int1]^.value; + end; + o:= i*fb0 + fz1; + foutputpo^:= o*famplitudepo^.value; + fz1:= i*fb1-fa1*o; +end; + +procedure tsigfilter.sighandlerlp2bi(const ainfo: psighandlerinfoty); +var + QfT_4,fT2_4,den: double; + i,o,do1: double; + int1: integer; +begin + if (ffrequencypo^.changed <> []) or (ffrequfactpo^.changed <> []) or + (fqfactorpo^.changed <> []) then begin + exclude(ffrequencypo^.changed,sic_value); + exclude(ffrequfactpo^.changed,sic_value); + exclude(fqfactorpo^.changed,sic_value); + do1:= ffrequencypo^.value*ffrequfactpo^.value; + if do1 > 0 then begin +// if (fqfactorpo^ <> fqfactorbefore) or (do1 <> ffrequencybefore) then begin +// ffrequencybefore:= do1; +// fqfactorbefore:= fqfactorpo^; + fT2_4:= do1*2*pi; // fT + if not (sfo_noprewarp in foptions) then begin + fT2_4:= 2*tan(0.5*fT2_4); + end; + if sfo_passgainfix in foptions then begin + fgain:= 1; + end + else begin + fgain:= (1/sqrt(sqrt(2)))/sqrt(fqfactorpo^.value); + end; + QfT_4:= 4/(fqfactorpo^.value*fT2_4); // 4/(Q*fT) + fT2_4:= 4/(fT2_4*fT2_4); // 4/fT^2 + den:= 1 + QfT_4 + fT2_4; // 1 + 4/(Q*fT) + 4/fT^2 + fb0:= fgain/den; + fb1:= 2*fb0; + fb2:= fb0; + fa1:= 2*(1-fT2_4)/den; + fa2:= (1-QfT_4+fT2_4)/den; + end; + end; + i:= 0; + for int1:= 0 to finphigh do begin + i:= i+finps[int1]^.value; + end; + o:= fz1+i*fb0; + fz1:= fz2-o*fa1+i*fb1; + fz2:= i*fb2-o*fa2; + foutputpo^:= o*famplitudepo^.value; +end; + +procedure tsigfilter.sighandlerb2bi; +var + fT,QfT_4,fT2_4,den,do1: double; +begin + if (ffrequencypo^.changed <> []) or (ffrequfactpo^.changed <> []) or + (fqfactorpo^.changed <> []) then begin + exclude(ffrequencypo^.changed,sic_value); + exclude(ffrequfactpo^.changed,sic_value); + exclude(fqfactorpo^.changed,sic_value); + do1:= ffrequencypo^.value*ffrequfactpo^.value; + if do1 > 0 then begin +// do1:= ffrequencypo^*ffrequfactpo^; +// if do1 > 0 then begin +// if (fqfactorpo^ <> fqfactorbefore) or (do1 <> ffrequencybefore) then begin +// ffrequencybefore:= do1; +// fqfactorbefore:= fqfactorpo^; + fT:= do1*2*pi; // fT + if not (sfo_noprewarp in foptions) then begin + fT:= 2*tan(0.5*fT); + end; + if (sfo_passgainfix in foptions) or (fkind = sfk_bs2bilinear) then begin + fgain:= 4/(fT*fqfactorpo^.value); + end + else begin + fgain:= 4/(fT*sqrt(fqfactorpo^.value)); + end; + QfT_4:= 4/(fqfactorpo^.value*fT); // 4/(Q*fT) + fT2_4:= 4/(fT*fT); // 4/fT^2 + den:= 1 + QfT_4 + fT2_4; // 1 + 4/(Q*fT) + 4/fT^2 + fb0:= fgain/den; + fb1:= 0; + fb2:= -fb0; + fa1:= 2*(1-fT2_4)/den; + fa2:= (1-QfT_4+fT2_4)/den; + end; + end; +end; + +procedure tsigfilter.sighandlerbp2bi(const ainfo: psighandlerinfoty); +var + i,o: double; + int1: integer; +begin + sighandlerb2bi; + i:= 0; + for int1:= 0 to finphigh do begin + i:= i+finps[int1]^.value; + end; + o:= fz1+i*fb0; + fz1:= fz2-o*fa1+i*fb1; + fz2:= i*fb2-o*fa2; + foutputpo^:= o*famplitudepo^.value; +end; + +procedure tsigfilter.sighandlerbs2bi(const ainfo: psighandlerinfoty); +var + i,o: double; + int1: integer; +begin + sighandlerb2bi; + i:= 0; + for int1:= 0 to finphigh do begin + i:= i+finps[int1]^.value; + end; + o:= fz1+i*fb0; + fz1:= fz2-o*fa1+i*fb1; + fz2:= i*fb2-o*fa2; + foutputpo^:= (i-o)*famplitudepo^.value; +end; + +procedure tsigfilter.clear; +begin + inherited; +// ffrequencybefore:= -1; +// fqfactorbefore:= -1; +end; + +procedure tsigfilter.initmodel; +begin +// finppo:= @tdoubleinputconn1(finput).fvalue; + ffrequencypo:= @tdoubleinputconn1(ffrequency).fv; + ffrequfactpo:= @tdoubleinputconn1(ffrequfact).fv; + fqfactorpo:= @tdoubleinputconn1(fqfactor).fv; + famplitudepo:= @tdoubleinputconn1(famplitude).fv; + inherited; +end; + +procedure tsigfilter.setfrequency(const avalue: tdoubleinputconn); +begin + ffrequency.assign(avalue); +end; + +function tsigfilter.getinputar: inputconnarty; +begin + setlength(result,4); + result[0]:= ffrequency; + result[1]:= ffrequfact; + result[2]:= fqfactor; + result[3]:= famplitude; + stackarray(pointerarty(inherited getinputar),pointerarty(result)); +end; + +procedure tsigfilter.setqfactor(const avalue: tdoubleinputconn); +begin + fqfactor.assign(avalue); +end; + +procedure tsigfilter.setkind(const avalue: sigfilterkindty); +begin + if fkind <> avalue then begin + lock; + fkind:= avalue; + modelchange; + unlock; + end; +end; + +procedure tsigfilter.setoptions(const avalue: sigfilteroptionsty); +begin + if foptions <> avalue then begin + lock; + foptions:= avalue; + modelchange; + unlock; + end; +end; + +procedure tsigfilter.setamplitude(const avalue: tdoubleinputconn); +begin + famplitude.assign(avalue); +end; + +procedure tsigfilter.setfrequfact(const avalue: tdoubleinputconn); +begin + ffrequfact.assign(avalue); +end; + +{ tfilterbanksection } + +constructor tfilterbanksection.create(aowner: tobject); +begin + inherited; + ffrequfact:= tdoubleinputconn.create(nil,isigclient(tsigfilterbank(aowner))); + ffrequfact.name:= 'frequfact'; + ffrequfact.value:= 1; + fqfactor:= tdoubleinputconn.create(nil,isigclient(tsigfilterbank(aowner))); + fqfactor.name:= 'qfactor'; + fqfactor.value:= 1; + famplitude:= tdoubleinputconn.create(nil,isigclient(tsigfilterbank(aowner))); + famplitude.name:= 'amplitude'; + famplitude.value:= 1; +end; + +destructor tfilterbanksection.destroy; +begin + ffrequfact.free; + fqfactor.free; + famplitude.free; + inherited; +end; + +procedure tfilterbanksection.setfrequfact(const avalue: tdoubleinputconn); +begin + ffrequfact.assign(avalue); +end; + +procedure tfilterbanksection.setqfactor(const avalue: tdoubleinputconn); +begin + fqfactor.assign(avalue); +end; + +procedure tfilterbanksection.setamplitude(const avalue: tdoubleinputconn); +begin + famplitude.assign(avalue); +end; + +{ tfilterbanksections } + +constructor tfilterbanksections.create(const aowner: tcomponent); +begin + inherited create(aowner,tfilterbanksection); +end; + +procedure tfilterbanksections.getinputar(var inputs: inputconnarty); +var + int1,int2{,int3}: integer; +begin + int1:= length(inputs); + setlength(inputs,int1+count*3); + for int2:= 0 to count - 1 do begin + with tfilterbanksection(fitems[int2]) do begin + inputs[int1]:= ffrequfact; + inc(int1); + inputs[int1]:= fqfactor; + inc(int1); + inputs[int1]:= famplitude; + inc(int1); + end; + end; +end; + +procedure tfilterbanksections.dosizechanged; +begin + inherited; + tsigfilterbank(fowner).modelchange; +end; + +class function tfilterbanksections.getitemclasstype: persistentclassty; +begin + result:= tfilterbanksection; +end; + +{ tsigfilterbank } + +constructor tsigfilterbank.create(aowner: tcomponent); +begin + fsections:= tfilterbanksections.create(self); + ffrequency:= tdoubleinputconn.create(nil,isigclient(self)); + ffrequency.name:= 'frequency'; + ffrequency.value:= 0.01; + famplitude:= tdoubleinputconn.create(nil,isigclient(self)); + famplitude.name:= 'amplitude'; + famplitude.value:= 1; + fbaseamplitude:= tdoubleinputconn.create(nil,isigclient(self)); + fbaseamplitude.name:= 'baseamplitude'; + fbaseamplitude.value:= 1; + inherited; +end; + +destructor tsigfilterbank.destroy; +begin + inherited; + fsections.free; + ffrequency.free; + famplitude.free; + fbaseamplitude.free; +end; + +procedure tsigfilterbank.setsections(const avalue: tfilterbanksections); +begin + fsections.assign(avalue); +end; + +procedure tsigfilterbank.setfrequency(const avalue: tdoubleinputconn); +begin + ffrequency.assign(avalue); +end; + +procedure tsigfilterbank.setoptions(const avalue: sigfilteroptionsty); +begin + if foptions <> avalue then begin + lock; + foptions:= avalue; + modelchange; + unlock; + end; +end; + +function tsigfilterbank.getinputar: inputconnarty; +begin + result:= inherited getinputar; + setlength(result,high(result)+4); + result[high(result)-2]:= ffrequency; + result[high(result)-1]:= famplitude; + result[high(result)]:= fbaseamplitude; + fsections.getinputar(result); +end; + +function tsigfilterbank.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}sighandler; +end; + +procedure tsigfilterbank.sighandler(const ainfo: psighandlerinfoty); + + procedure setupparams(const asection: pfilterinfoty); + var + fT,QfT_4,fT2_4,den,do1,fgain: double; + begin + with asection^ do begin + exclude(ffrequfactpo^.changed,sic_value); + exclude(fqfactorpo^.changed,sic_value); + do1:= ffrequencypo^.value*ffrequfactpo^.value; + if do1 > 0 then begin + fT:= do1*2*pi; // fT + if not (sfo_noprewarp in foptions) then begin + fT:= 2*tan(0.5*fT); + end; +// if (sfo_passgainfix in foptions) or (fkind = sfk_bs2bilinear) then begin + fgain:= 4/(fT*fqfactorpo^.value); +// end +// else begin +// fgain:= 4/(fT*sqrt(fqfactorpo^.value)); +// end; + QfT_4:= 4/(fqfactorpo^.value*fT); // 4/(Q*fT) + fT2_4:= 4/(fT*fT); // 4/fT^2 + den:= 1 + QfT_4 + fT2_4; // 1 + 4/(Q*fT) + 4/fT^2 + fb0:= fgain/den; + fb1:= 0; + fb2:= -fb0; + fa1:= 2*(1-fT2_4)/den; + fa2:= (1-QfT_4+fT2_4)/den; + end; + end; + end; //setupparams() + +var + i,o,ot: double; + int1: integer; + po1: pfilterinfoty; +begin + if (ffrequencypo^.changed <> []) then begin + exclude(ffrequencypo^.changed,sic_value); + po1:= pointer(finfos); + for int1:= finfohigh downto 0 do begin + setupparams(po1); + inc(po1); + end; + end; + i:= 0; + for int1:= 0 to finphigh do begin + i:= i+finps[int1]^.value; + end; + ot:= 0; + po1:= pointer(finfos); + for int1:= finfohigh downto 0 do begin + with po1^ do begin + if (ffrequfactpo^.changed <> []) or (fqfactorpo^.changed <> []) then begin + setupparams(po1); + end; + o:= i*fb0+fz1*fb1+fz2*fb2-z1*fa1-z2*fa2; + z2:= z1; + z1:= o; + ot:= ot+o*famplitudepo^.value; + end; + inc(po1); + end; + fz2:= fz1; + fz1:= i; + foutputpo^:= (i*fbaseamplitudepo^.value+ot)*famplitudepo^.value; +end; + +procedure tsigfilterbank.initmodel; +var + int1: integer; +begin + inherited; + ffrequencypo:= @tdoubleinputconn1(ffrequency).fv; + famplitudepo:= @tdoubleinputconn1(famplitude).fv; + fbaseamplitudepo:= @tdoubleinputconn1(fbaseamplitude).fv; + setlength(finfos,fsections.count); + finfohigh:= high(finfos); + for int1:= finfohigh downto 0 do begin + with finfos[int1],tfilterbanksection(fsections.fitems[int1]) do begin + ffrequfactpo:= @tdoubleinputconn1(ffrequfact).fv; + fqfactorpo:= @tdoubleinputconn1(fqfactor).fv; + famplitudepo:= @tdoubleinputconn1(famplitude).fv; + end; + end; +end; + +procedure tsigfilterbank.clear; +var + int1: integer; +begin + inherited; + fz1:= 0; + fz2:= 0; + for int1:= high(finfos) downto 0 do begin + with finfos[int1] do begin + z1:= 0; + z2:= 0; + end; + end; +end; + +procedure tsigfilterbank.setamplitude(const avalue: tdoubleinputconn); +begin + famplitude.assign(avalue); +end; + +procedure tsigfilterbank.setbaseamplitude(const avalue: tdoubleinputconn); +begin + fbaseamplitude.assign(avalue); +end; + +end. diff --git a/mseide-msegui/lib/common/math/mselfsr.pas b/mseide-msegui/lib/common/math/mselfsr.pas new file mode 100644 index 0000000..0bf92b2 --- /dev/null +++ b/mseide-msegui/lib/common/math/mselfsr.pas @@ -0,0 +1,45 @@ +{ MSEgui Copyright (c) 2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mselfsr; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes; + +//32 bit lfsr x^32+x^30+x^26+x^25+1 + +function lfsr32(var sr: card32): card32; +procedure lfsr321(var sr: card32); + +implementation +const + feedbacktable: array[0..255] of byte = ( + 0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0, + 1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1, + 0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0, + 1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1, + 1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1, + 0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0, + 1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1, + 0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0 + ); + +function lfsr32(var sr: card32): card32; +begin + sr:= feedbacktable[sr shr 24] + (sr shl 1); + result:= sr; +end; + +procedure lfsr321(var sr: card32); +begin + sr:= feedbacktable[sr shr 24] + (sr shl 1); +end; + +end. diff --git a/mseide-msegui/lib/common/math/msenoise.pas b/mseide-msegui/lib/common/math/msenoise.pas new file mode 100644 index 0000000..8799dd1 --- /dev/null +++ b/mseide-msegui/lib/common/math/msenoise.pas @@ -0,0 +1,115 @@ +{ MSEgui Copyright (c) 2013-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msenoise; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes; +const + defaultmwcseedw = 521288629; + defaultmwcseedz = 362436069; +type + mwcinfoty = record + fw,fz: card32; //call checkmwcseed() after init + end; + + tmwcnoisegen = class + private + fw: card32; + fz: card32; + public + constructor create; + procedure init(const w: card32 = 0; const z: card32 = 0); + function next: card32; + end; + +function mwcnoise(var state: mwcinfoty): card32; overload; +function mwcnoise: card32; overload; +procedure mwcnoiseinit(const w: card32 = 0; const z: card32 = 0); +procedure checkmwcseed(var w: card32; var z: card32); + //0 -> use random +procedure checkmwcseed(var state: mwcinfoty); + +implementation + +var + fw: card32 = defaultmwcseedw; //"random" seed + fz: card32 = defaultmwcseedz; //"random" seed + +procedure checkmwcseed(var w: card32; var z: card32); +begin + if w = 0 then begin + w:= random($9068fffe)+1; + end + else begin + if w mod $9068ffff = 0 then begin + w:= (w xor $ffffffff) mod $9068ffff; + end; + end; + if z = 0 then begin + z:= random($464ffffe)+1; + end + else begin + if z mod $464fffff = 0 then begin + z:= (z xor $ffffffff) mod $464fffff; + end; + end; +end; + +procedure checkmwcseed(var state: mwcinfoty); +begin + checkmwcseed(state.fw,state.fz); +end; + +procedure mwcnoiseinit(const w: card32 = 0; const z: card32 = 0); +begin + fw:= w; + fz:= z; + checkmwcseed(fw,fz); +end; + +function mwcnoise: card32; +begin + fz:= 36969 * (fz and $ffff) + (fz shr 16); + fw:= 18000 * (fw and $ffff) + (fw shr 16); + result:= fz shl 16 + fw; +end; + +function mwcnoise(var state: mwcinfoty): card32; +begin + with state do begin + fz:= 36969 * (fz and $ffff) + (fz shr 16); + fw:= 18000 * (fw and $ffff) + (fw shr 16); + result:= fz shl 16 + fw; + end; +end; + +{ tmwcnoisegen } + +constructor tmwcnoisegen.create; +begin + init; +end; + +procedure tmwcnoisegen.init(const w: card32 = 0; const z: card32 = 0); +begin + fw:= w; + fz:= z; + checkmwcseed(fw,fz); +end; + +function tmwcnoisegen.next: card32; +begin + fz:= 36969 * (fz and $ffff) + (fz shr 16); + fw:= 18000 * (fw and $ffff) + (fw shr 16); + result:= fz shl 16 + fw; +end; + +end. diff --git a/mseide-msegui/lib/common/math/msesigaudio.pas b/mseide-msegui/lib/common/math/msesigaudio.pas new file mode 100644 index 0000000..bb09fd7 --- /dev/null +++ b/mseide-msegui/lib/common/math/msesigaudio.pas @@ -0,0 +1,499 @@ +{ MSEgui Copyright (c) 2010-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msesigaudio; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseaudio,msesignal,classes,mclasses,msethread,msetypes,msestrings; + +const + defaultblocksize = 1000; + +type + tsigoutaudio = class; + + tsigaudioout = class(tcustomaudioout) + private + protected + fsigout: tsigoutaudio; + fblocksize: integer; + fbuffer: bytearty; + function threadproc(sender: tmsethread): integer; override; + procedure run; override; + procedure stop; override; + procedure initnames; override; + public + constructor create(const aowner: tsigoutaudio); reintroduce; + published + property blocksize: integer read fblocksize write fblocksize + default defaultblocksize; + property active; + property server; + property dev; + property appname; + property streamname; +// property channels; + property format; + property rate; + property latency; + property stacksizekb; +// property onsend; +// property onerror; + + end; + + tsigoutaudio = class(tsigmultiinp) + private + faudio: tsigaudioout; + fbuffer: doublearty; + fbufpo: pdouble; + procedure setaudio(const avalue: tsigaudioout); + protected + //isigclient + function gethandler: sighandlerprocty; override; + procedure sighandler(const ainfo: psighandlerinfoty); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property audio: tsigaudioout read faudio write setaudio; + end; + +implementation +uses + msesysintf,msepulsesimple,sysutils{$ifndef FPC},classes_del{$endif}; + +{ tsigaudioout } + +constructor tsigaudioout.create(const aowner: tsigoutaudio); +begin + fblocksize:= defaultblocksize; + fsigout:= aowner; + inherited create(aowner); + setsubcomponent(true); +end; + +type + convertinfoty = record + source: pdouble; + dest: pointer; + valuehigh: integer; + end; + convertprocty = procedure(var info: convertinfoty); + +procedure convert8(var info: convertinfoty); +var + int1: integer; + do1: double; +begin + with info do begin + for int1:= valuehigh downto 0 do begin + do1:= source^; + if do1 > 1 then begin + do1:= 1; + end; + if do1 < -1 then begin + do1:= -1; + end; + pbyte(dest)^:= $80+round(do1*$7f); + inc(source); + inc(pbyte(dest)); + end; + end; +end; + +procedure convert16(var info: convertinfoty); +var + int1: integer; + do1: double; +begin + with info do begin + for int1:= valuehigh downto 0 do begin + do1:= source^; + if do1 > 1 then begin + do1:= 1; + end; + if do1 < -1 then begin + do1:= -1; + end; + psmallint(dest)^:= round(do1*$7fff); + inc(source); + inc(psmallint(dest)); + end; + end; +end; + +procedure convert24(var info: convertinfoty); +var + int1: integer; + do1: double; + int2: integer; +begin + with info do begin + for int1:= valuehigh downto 0 do begin + do1:= source^; + if do1 > 1 then begin + do1:= 1; + end; + if do1 < -1 then begin + do1:= -1; + end; + int2:= round(do1*$7fffff); + {$ifdef FPC} + pbyte(dest)[0]:= pbyte(@int2)[0]; + pbyte(dest)[1]:= pbyte(@int2)[1]; + pbyte(dest)[2]:= pbyte(@int2)[2]; + {$else} + pchar(dest)[0]:= pchar(@int2)[0]; + pchar(dest)[1]:= pchar(@int2)[1]; + pchar(dest)[2]:= pchar(@int2)[2]; + {$endif} + inc(source); + inc(pbyte(dest),3); + end; + end; +end; + +procedure convert32(var info: convertinfoty); +var + int1: integer; + do1: double; +begin + with info do begin + for int1:= valuehigh downto 0 do begin + do1:= source^; + if do1 > 1 then begin + do1:= 1; + end; + if do1 < -1 then begin + do1:= -1; + end; + pinteger(dest)^:= round(do1*$7fffffff); + inc(source); + inc(pinteger(dest)); + end; + end; +end; + +procedure convert32f(var info: convertinfoty); +var + int1: integer; +begin + with info do begin + for int1:= valuehigh downto 0 do begin + psingle(dest)^:= source^; + inc(source); + inc(psingle(dest)); + end; + end; +end; + +procedure convert2432(var info: convertinfoty); +var + int1: integer; + do1: double; +begin + with info do begin + for int1:= valuehigh downto 0 do begin + do1:= source^; + if do1 > 1 then begin + do1:= 1; + end; + if do1 < -1 then begin + do1:= -1; + end; + pinteger(dest)^:= round(do1*$7fffff); + inc(source); + inc(pinteger(dest)); + end; + end; +end; + +procedure convert16swap(var info: convertinfoty); +var + int1: integer; + do1: double; +begin + with info do begin + for int1:= valuehigh downto 0 do begin + do1:= source^; + if do1 > 1 then begin + do1:= 1; + end; + if do1 < -1 then begin + do1:= -1; + end; + psmallint(dest)^:= swapendian(smallint(round(do1*$7fff))); + inc(source); + inc(psmallint(dest)); + end; + end; +end; + +procedure convert24swap(var info: convertinfoty); +var + int1: integer; + do1: double; + int2: integer; +begin + with info do begin + for int1:= valuehigh downto 0 do begin + do1:= source^; + if do1 > 1 then begin + do1:= 1; + end; + if do1 < -1 then begin + do1:= -1; + end; + int2:= round(do1*$7fffff); + {$ifdef FPC} + pbyte(dest)[0]:= pbyte(@int2)[2]; + pbyte(dest)[1]:= pbyte(@int2)[1]; + pbyte(dest)[2]:= pbyte(@int2)[0]; + {$else} + pchar(dest)[0]:= pchar(@int2)[2]; + pchar(dest)[1]:= pchar(@int2)[1]; + pchar(dest)[2]:= pchar(@int2)[0]; + {$endif} + inc(source); + inc(pbyte(dest),3); + end; + end; +end; + +procedure convert32swap(var info: convertinfoty); +var + int1: integer; + do1: double; +begin + with info do begin + for int1:= valuehigh downto 0 do begin + do1:= source^; + if do1 > 1 then begin + do1:= 1; + end; + if do1 < -1 then begin + do1:= -1; + end; + pinteger(dest)^:= swapendian(integer(round(do1*$7fffffff))); + inc(source); + inc(pinteger(dest)); + end; + end; +end; + +procedure convert32fswap(var info: convertinfoty); +var + int1: integer; + si1: single; +begin + with info do begin + for int1:= valuehigh downto 0 do begin + {$ifdef FPC} + si1:= single(source^); + {$else} + si1:= source^; + {$endif} + plongword(dest)^:= swapendian(longword(plongword(@si1)^)); + inc(source); + inc(psingle(dest)); + end; + end; +end; + +procedure convert2432swap(var info: convertinfoty); +var + int1: integer; + do1: double; +begin + with info do begin + for int1:= valuehigh downto 0 do begin + do1:= source^; + if do1 > 1 then begin + do1:= 1; + end; + if do1 < -1 then begin + do1:= -1; + end; + pinteger(dest)^:= swapendian(integer(round(do1*$7fffff))); + inc(source); + inc(pinteger(dest)); + end; + end; +end; + +function tsigaudioout.threadproc(sender: tmsethread): integer; +var +// data: pointer; + int1: integer; + datasize1,blocksize1,bufferlength1,valuehigh1: integer; + controller1: tsigcontroller; +// po1: pointer; +// po2: pdouble; +// do1: double; + convert: convertprocty; + info: convertinfoty; +begin + result:= 0; + controller1:= fsigout.controller; + if controller1 <> nil then begin + factive:= true; + datasize1:= samplebuffersizematrix[fformat]; + blocksize1:= fblocksize; + valuehigh1:= fsigout.inputs.count*blocksize1; + bufferlength1:= datasize1*valuehigh1; + dec(valuehigh1); + info.valuehigh:= valuehigh1; + setlength(fbuffer,bufferlength1); + case fformat of + sfm_u8,sfm_8alaw,sfm_8ulaw: begin + convert:= @convert8; + end; + sfm_s16{$ifdef endian_little},sfm_s16le{$else},sfm_s16be{$endif}: begin + convert:= @convert16; + end; + sfm_s24{$ifdef endian_little},sfm_s24le{$else},sfm_s24be{$endif}: begin + convert:= @convert24; + end; + sfm_s32{$ifdef endian_little},sfm_s32le{$else},sfm_s32be{$endif}: begin + convert:= @convert32; + end; + sfm_f32{$ifdef endian_little},sfm_f32le{$else},sfm_f32be{$endif}: begin + convert:= @convert32f; + end; + smf_s2432{$ifdef endian_little},smf_s2432le{$else},smf_s2432be{$endif}: begin + convert:= @convert2432; + end; + {$ifdef endian_little} + sfm_s16be: begin + convert:= @convert16swap; + end; + sfm_s24be: begin + convert:= @convert24swap; + end; + sfm_s32be: begin + convert:= @convert32swap; + end; + sfm_f32be: begin + convert:= @convert32fswap; + end; + smf_s2432be: begin + convert:= @convert2432swap; + end; + {$else} + sfm_s16le: begin + convert:= @convert16swap; + end; + sfm_s24le: begin + convert:= @convert24swap; + end; + sfm_s32le: begin + convert:= @convert32swap; + end; + sfm_f32le: begin + convert:= @convert32fswap; + end; + smf_s2432le: begin + convert:= @convert2432swap; + end; + {$endif} + else begin + exit; + end; + end; + + while not sender.terminated do begin + controller1.lock; + try + fsigout.fbufpo:= pointer(fsigout.fbuffer); + controller1.step(blocksize1); + info.source:= pointer(fsigout.fbuffer); + info.dest:= pointer(fbuffer); + convert(info); + finally + controller1.unlock; + end; + if pa_simple_write(fpulsestream,pointer(fbuffer), + bufferlength1,@int1) <> 0 then begin + doerror(int1); + break; + end; + end; + end; +end; + +procedure tsigaudioout.run; +var + int1: integer; +begin + int1:= fsigout.inputs.count; + channels:= int1; + setlength(fsigout.fbuffer,int1*fblocksize); + inherited; +end; + +procedure tsigaudioout.stop; +begin + inherited; + fsigout.fbufpo:= nil; +end; + +procedure tsigaudioout.initnames; +begin + inherited; + if fstreamname = '' then begin + fstreamname:= msestring(fsigout.name); + end; +end; + +{ tsigoutaudio } + +constructor tsigoutaudio.create(aowner: tcomponent); +begin + faudio:= tsigaudioout.create(self); + inherited; +// finputs:= taudioinpconnarrayprop.create(self); +end; + +destructor tsigoutaudio.destroy; +begin + faudio.free; + inherited; +// finputs.free; +end; +{ +procedure tsigoutaudio.setinputs(const avalue: taudioinpconnarrayprop); +begin + finputs.assign(avalue); +end; +} +procedure tsigoutaudio.setaudio(const avalue: tsigaudioout); +begin + faudio.assign(avalue); +end; + +function tsigoutaudio.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}sighandler; +end; + +procedure tsigoutaudio.sighandler(const ainfo: psighandlerinfoty); +var + int1: integer; +begin + if fbufpo <> nil then begin + for int1:= 0 to finphigh do begin + fbufpo^:= finps[int1]^.value; + inc(fbufpo); + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/math/msesigfft.pas b/mseide-msegui/lib/common/math/msesigfft.pas new file mode 100644 index 0000000..aadbb85 --- /dev/null +++ b/mseide-msegui/lib/common/math/msesigfft.pas @@ -0,0 +1,483 @@ +{ MSEgui Copyright (c) 2010-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} + +// +// experimental +// + +unit msesigfft; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msesignal,msefft,classes,mclasses,msetypes,mseglob; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + + tbufferdoublesigcomp = class; + + sigbuffereventty = procedure of object; + + tbufferdoubleoutputconn = class(tdoubleoutputconn) + private + fonoutputburst: sigoutbursteventty; + procedure setsamplecount(avalue: integer); + protected + fsignal: doublearty; + fsamplecount: integer; + findex: integer; + procedure clear; + property samplecount: integer read fsamplecount + write setsamplecount default 1; + public + constructor create(const aowner: tcomponent; + const asigintf: isigclient; const aeventdriven: boolean); override; + published + property onoutputburst: sigoutbursteventty read fonoutputburst + write fonoutputburst; + end; + + tbufferdoubleinputconn = class(tdoubleinputconn) + private + fonsigbufferfull: sigbuffereventty; + procedure setsamplecount(avalue: integer); + protected + foutput: tbufferdoubleoutputconn; + fsignal: doublearty; + fsamplecount: integer; + findex: integer; + procedure sighandler(const ainfo: psighandlerinfoty); + procedure clear; + property samplecount: integer read fsamplecount + write setsamplecount default 1; + public + constructor create(const aowner: tbufferdoublesigcomp; + const aonsigbufferfull: sigbuffereventty); reintroduce; + end; + + tbufferdoublesigcomp = class(tdoublesigcomp) + private + finput: tbufferdoubleinputconn; + foutput: tbufferdoubleoutputconn; + procedure setoutput(const avalue: tbufferdoubleoutputconn); + procedure setinput(const avalue: tbufferdoubleinputconn); + function getonoutputburst: sigoutbursteventty; + procedure setonoutputburst(const avalue: sigoutbursteventty); + protected + procedure sigbufferfull; virtual; + //isigclient + function getinputar: inputconnarty; override; + function getoutputar: outputconnarty; override; + function gethandler: sighandlerprocty; override; + public + constructor create(aowner: tcomponent); override; + procedure clear; override; + property output: tbufferdoubleoutputconn read foutput write setoutput; + published + property input: tbufferdoubleinputconn read finput write setinput; + property onoutputburst: sigoutbursteventty read getonoutputburst + write setonoutputburst; + end; + + tsigfft = class(tbufferdoublesigcomp) + private + ffft: tfft; + fsamplecount: integer; + procedure setsamplecount(avalue: integer); + function getwindowfunc: windowfuncty; + procedure setwindowfunc(const avalue: windowfuncty); + function getwindowfuncpar0: double; + procedure setwindowfuncpar0(const avalue: double); + function getwindowfuncpar1: double; + procedure setwindowfuncpar1(const avalue: double); + protected + procedure sigbufferfull; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property samplecount: integer read fsamplecount + write setsamplecount default 256; + property windowfunc: windowfuncty read getwindowfunc + write setwindowfunc default wf_rectangular; + property windowfuncpar0: double read getwindowfuncpar0 + write setwindowfuncpar0; + property windowfuncpar1: double read getwindowfuncpar1 + write setwindowfuncpar1; + end; + + tsigsamplerfft = class; + samplerffteventty = procedure(const sender: tsigsamplerfft; + const abuffer: samplerbufferty) of object; + + tsigsamplerfft = class(tsigsampler) + private + ffft: tfft; + fonfft: samplerffteventty; + function getwindowfunc: windowfuncty; + procedure setwindowfunc(const avalue: windowfuncty); + function getwindowfuncpar0: double; + procedure setwindowfuncpar0(const avalue: double); + function getwindowfuncpar1: double; + procedure setwindowfuncpar1(const avalue: double); + protected + ffftbuffer: samplerbufferty; + faveragecount: int32; + procedure dobufferfull; override; + procedure initmodel; override; + procedure updateoptions(var avalue: sigsampleroptionsty); override; + procedure setoptions(const avalue: sigsampleroptionsty) override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure clear override; + procedure clearaverage(); + property averagecount: int32 read faveragecount; + published + property windowfunc: windowfuncty read getwindowfunc + write setwindowfunc default wf_rectangular; + property windowfuncpar0: double read getwindowfuncpar0 + write setwindowfuncpar0; + property windowfuncpar1: double read getwindowfuncpar1 + write setwindowfuncpar1; + property onfft: samplerffteventty read fonfft write fonfft; + end; + +implementation +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +{ tbufferdoubleinputconn } + +constructor tbufferdoubleinputconn.create(const aowner: tbufferdoublesigcomp; + const aonsigbufferfull: sigbuffereventty); +begin + samplecount:= 1; + fonsigbufferfull:= aonsigbufferfull; + foutput:= aowner.foutput; + inherited create(aowner,isigclient(aowner)); +end; + +procedure tbufferdoubleinputconn.sighandler(const ainfo: psighandlerinfoty); +begin + fsignal[findex]:= fv.value; + inc(findex); + if findex = fsamplecount then begin + findex:= 0; + fonsigbufferfull; + with foutput do begin + findex:= 0; + if assigned(fonoutputburst) then begin + fonoutputburst(self,realarty(fsignal)); + end; + end; + end; + with foutput do begin + fvalue:= fsignal[findex]; + inc(findex); + if findex = fsamplecount then begin + dec(findex); + end; + end; +end; + +procedure tbufferdoubleinputconn.clear; +begin +end; + +procedure tbufferdoubleinputconn.setsamplecount(avalue: integer); +begin + if avalue < 1 then begin + avalue:= 1; + end; + fsamplecount:= avalue; + findex:= 0; + setlength(fsignal,avalue); +end; + +{ tbufferdoubleoutputconn } + +constructor tbufferdoubleoutputconn.create(const aowner: tcomponent; + const asigintf: isigclient; const aeventdriven: boolean); +begin + samplecount:= 1; + inherited; +end; + +procedure tbufferdoubleoutputconn.clear; +begin +end; + +procedure tbufferdoubleoutputconn.setsamplecount(avalue: integer); +begin + if avalue < 1 then begin + avalue:= 1; + end; + fsamplecount:= avalue; + findex:= 0; + setlength(fsignal,avalue); +end; + +{ tbufferdoublesigcomp } + +constructor tbufferdoublesigcomp.create(aowner: tcomponent); +begin + foutput:= tbufferdoubleoutputconn.create(self,isigclient(self),false); + finput:= tbufferdoubleinputconn.create(self,{$ifdef FPC}@{$endif}sigbufferfull); + inherited; +end; + +function tbufferdoublesigcomp.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}finput.sighandler; +end; + +procedure tbufferdoublesigcomp.setoutput(const avalue: tbufferdoubleoutputconn); +begin + foutput.assign(avalue); +end; + +procedure tbufferdoublesigcomp.setinput(const avalue: tbufferdoubleinputconn); +begin + finput.assign(avalue); +end; + +function tbufferdoublesigcomp.getinputar: inputconnarty; +begin + setlength(result,1); + result[0]:= finput; +end; + +function tbufferdoublesigcomp.getoutputar: outputconnarty; +begin + setlength(result,1); + result[0]:= foutput; +end; + +procedure tbufferdoublesigcomp.sigbufferfull; +begin + //dummy +end; + +procedure tbufferdoublesigcomp.clear; +begin + inherited; + finput.clear; + foutput.clear; +end; + +function tbufferdoublesigcomp.getonoutputburst: sigoutbursteventty; +begin + result:= foutput.onoutputburst; +end; + +procedure tbufferdoublesigcomp.setonoutputburst(const avalue: sigoutbursteventty); +begin + foutput.onoutputburst:= avalue; +end; + +{ tsigfft } + +constructor tsigfft.create(aowner: tcomponent); +begin + ffft:= tfft.create(nil); + inherited; + samplecount:= 256; +end; + +destructor tsigfft.destroy; +begin + ffft.free; + inherited; +end; + +procedure tsigfft.setsamplecount(avalue: integer); +begin + if avalue < 2 then begin + avalue:= 2; + end; + if fsamplecount <> avalue then begin + fsamplecount:= avalue; + finput.samplecount:= avalue; + foutput.samplecount:= avalue div 2 + 1; + end; +end; + +procedure tsigfft.sigbufferfull; +begin + ffft.inpreal:= realarty(finput.fsignal); + foutput.fsignal:= doublearty(ffft.outreal); +end; + +function tsigfft.getwindowfunc: windowfuncty; +begin + result:= ffft.windowfunc; +end; + +procedure tsigfft.setwindowfunc(const avalue: windowfuncty); +begin + ffft.windowfunc:= avalue; +end; + +function tsigfft.getwindowfuncpar0: double; +begin + result:= ffft.windowfuncpar0; +end; + +procedure tsigfft.setwindowfuncpar0(const avalue: double); +begin + ffft.windowfuncpar0:= avalue; +end; + +function tsigfft.getwindowfuncpar1: double; +begin + result:= ffft.windowfuncpar1; +end; + +procedure tsigfft.setwindowfuncpar1(const avalue: double); +begin + ffft.windowfuncpar1:= avalue; +end; + +{ tsigsamplerfft } + +constructor tsigsamplerfft.create(aowner: tcomponent); +begin + inherited; + ffft:= tfft.create(nil); +end; + +destructor tsigsamplerfft.destroy; +begin + ffft.free; + inherited; +end; + +procedure tsigsamplerfft.clear; +begin + inherited; + clearaverage(); +end; + +procedure tsigsamplerfft.clearaverage(); +begin + faveragecount:= 0; +end; + +function tsigsamplerfft.getwindowfunc: windowfuncty; +begin + result:= ffft.windowfunc; +end; + +procedure tsigsamplerfft.setwindowfunc(const avalue: windowfuncty); +begin + ffft.windowfunc:= avalue; +end; + +function tsigsamplerfft.getwindowfuncpar0: double; +begin + result:= ffft.windowfuncpar0; +end; + +procedure tsigsamplerfft.setwindowfuncpar0(const avalue: double); +begin + ffft.windowfuncpar0:= avalue; +end; + +function tsigsamplerfft.getwindowfuncpar1: double; +begin + result:= ffft.windowfuncpar1; +end; + +procedure tsigsamplerfft.setwindowfuncpar1(const avalue: double); +begin + ffft.windowfuncpar1:= avalue; +end; + +procedure tsigsamplerfft.dobufferfull; +var + i1: int32; + f1,f2: flo64; + p1,p2,pe: pflo64; + ar1: realarty; +begin + inherited; + if sso_fftmag in options then begin + if sso_average in options then begin + for i1:= 0 to high(ffftbuffer) do begin + ffft.inpreal:= realarty(fsigbuffer[i1]); + if faveragecount = 0 then begin + ffftbuffer[i1]:= doublearty(ffft.outreal); + end + else begin + f1:= faveragecount; + f2:= faveragecount+1; + p1:= @ffftbuffer[i1][0]; + ar1:= ffft.outreal; + p2:= @ar1[0]; + pe:= p1 + length(ffftbuffer[i1]); + while p1 < pe do begin + p1^:= (p1^*f1+p2^)/f2; + inc(p1); + inc(p2); + end; + end; + end; + inc(faveragecount); + end + else begin + for i1:= 0 to high(ffftbuffer) do begin + ffft.inpreal:= realarty(fsigbuffer[i1]); + ffftbuffer[i1]:= doublearty(ffft.outreal); + end; + end; + if assigned(fonfft) then begin + fonfft(self,ffftbuffer); + end; + end; +end; + +procedure tsigsamplerfft.initmodel; +//var +// int1: integer; +begin + inherited; + ffftbuffer:= nil; + setlength(ffftbuffer,inputs.count); + faveragecount:= 0; +end; + +procedure tsigsamplerfft.updateoptions(var avalue: sigsampleroptionsty); +begin + //dummy +end; + +procedure tsigsamplerfft.setoptions(const avalue: sigsampleroptionsty); +begin + if (avalue >< foptions) * [sso_average] <> [] then begin + clearaverage(); + end; + inherited; +end; + +end. diff --git a/mseide-msegui/lib/common/math/msesigfftgui.pas b/mseide-msegui/lib/common/math/msesigfftgui.pas new file mode 100644 index 0000000..59a8687 --- /dev/null +++ b/mseide-msegui/lib/common/math/msesigfftgui.pas @@ -0,0 +1,156 @@ +{ MSEgui Copyright (c) 20010-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} + +// +// experimental +// + +unit msesigfftgui; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msesignal,msechart,classes,mclasses,msesigfft,msegui,msegraphutils,msemenus, + msegraphics,mseguiglob,mseclasses,msetypes; + +type + tsigscopefft = class; + tscopesamplerfft = class(tsigsamplerfft) + private + fscope: tsigscopefft; + protected + procedure dobufferfull; override; + public + constructor create(const aowner: tsigscopefft); reintroduce; + end; + + tsigscopefft = class(tchart) + private + fsampler: tscopesamplerfft; + ffftfirst: integer; + ffftcount: integer; + fslave: tsigscopefft; + procedure setsampler(const avalue: tscopesamplerfft); + procedure setslave(const avalue: tsigscopefft); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property sampler: tscopesamplerfft read fsampler write setsampler; + property fftfirst: integer read ffftfirst write ffftfirst default 0; + property fftcount: integer read ffftcount write ffftcount default 0; + //0 -> all + property slave: tsigscopefft read fslave write setslave; + end; + +implementation +uses + sysutils; + +{ tsigscopefft } + +constructor tsigscopefft.create(aowner: tcomponent); +begin + fsampler:= tscopesamplerfft.create(self); + inherited; +end; + +destructor tsigscopefft.destroy; +begin + fsampler.free; + inherited; +end; + +procedure tsigscopefft.setsampler(const avalue: tscopesamplerfft); +begin + fsampler.assign(avalue); +end; + +procedure tsigscopefft.setslave(const avalue: tsigscopefft); +var + slave1: tsigscopefft; +begin + slave1:= avalue; + while slave1 <> nil do begin + if slave1 = self then begin + raise exception.create(name+': recursive slave '+avalue.name+'.'); + end; + slave1:= slave1.slave; + end; + setlinkedvar(tmsecomponent(avalue),tmsecomponent(fslave)); +end; + +{ tscopesamplerfft } + +constructor tscopesamplerfft.create(const aowner: tsigscopefft); +begin + fscope:= aowner; + inherited create(aowner); + setsubcomponent(true); + name:= 'sampler'; +end; + +procedure tscopesamplerfft.dobufferfull; + + procedure handleslave(const asampler: tscopesamplerfft; + const asig,afft: samplerbufferty); + //todo: optimize slave handling, no additional buffer copy + var + buf1: samplerbufferty; + int1: integer; + int2: integer; + begin + with asampler do begin + if sso_fftmag in options then begin + with fscope do begin + if (ffftfirst = 0) and (ffftcount = 0) then begin + buf1:= afft; + end + else begin + int2:= ffftcount; + if int2 = 0 then begin + int2:= bigint; + end; + setlength(buf1,length(afft)); + for int1:= 0 to high(buf1) do begin + buf1[int1]:= copy(afft[int1],fftfirst,int2); + end; + end; + end; + end + else begin + buf1:= copy(asig); + end; + lockapplication; + try + with fscope.traces do begin + for int1:= 0 to high(buf1) do begin + if int1 >= count then begin + break; + end; + items[int1].ydata:= realarty(buf1[int1]); + end; + end; + finally + unlockapplication; + end; + end; + end; //handleslave() +var + slave: tsigscopefft; +begin + inherited; + slave:= self.fscope; + while slave <> nil do begin + handleslave(slave.fsampler,fsigbuffer,ffftbuffer); + slave:= slave.slave; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/math/msesiggui.pas b/mseide-msegui/lib/common/math/msesiggui.pas new file mode 100644 index 0000000..b3d0e54 --- /dev/null +++ b/mseide-msegui/lib/common/math/msesiggui.pas @@ -0,0 +1,2028 @@ +{ MSEgui Copyright (c) 2011-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msesiggui; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,msegraphedits,msesignal,mseguiglob,mseevent,msechartedit, + msetypes, + msechart,mseclasses,msefft,msewidgets,msegraphics,msegraphutils,msedial, + msesplitter,msegui,msestat,msestatfile,msestrings,msestockobjects, + msemenus,mseact,msedataedits,msereal,mseedit; + +type + sigeditoptionty = (sieo_exp,sieo_expzero); + sigeditoptionsty = set of sigeditoptionty; + +const + defaultffttableeditoptions = [ceo_noinsert,ceo_nodelete]; + defaultkeywidth = 8; + defaultenvsplitteroptions = defaultsplitteroptions+[spo_hmove,spo_hprop]; + defaultsigkeyboardoptions = [sieo_exp]; + +type + + tsigslider = class(tslider,isigclient) + private + foutput: tdoubleoutputconn; + foutputpo: pdouble; + fcontroller: tsigcontroller; + fsigclientinfo: sigclientinfoty; + fontransformvalue: sigineventty; + fmin: real; + fmax: real; + foptions: sigeditoptionsty; + procedure setoutput(const avalue: tdoubleoutputconn); + procedure setcontroller(const avalue: tsigcontroller); + procedure setmin(const avalue: real); + procedure setmax(const avalue: real); + procedure setoptions(const avalue: sigeditoptionsty); + protected + fsigvalue: real; + procedure updatesigvalue; + procedure dochange; override; + procedure sighandler(const ainfo: psighandlerinfoty); + //isigclient + procedure initmodel; + procedure sigtick; virtual; + function getinputar: inputconnarty; + function getoutputar: outputconnarty; + function gethandler: sighandlerprocty; + function getzcount: integer; + procedure clear; + procedure modelchange; + function getsigcontroller: tsigcontroller; + function getsigclientinfopo: psigclientinfoty; + function getsigoptions: sigclientoptionsty; + procedure lock; + procedure unlock; + public + constructor create(aowner: tcomponent); override; + property output: tdoubleoutputconn read foutput write setoutput; + published + property controller: tsigcontroller read fcontroller write setcontroller; + property ontransformvalue: sigineventty read fontransformvalue + write fontransformvalue; + property min: real read fmin write setmin; + property max: real read fmax write setmax; + property options: sigeditoptionsty read foptions write setoptions default []; + end; + + tsigrealedit = class(trealedit,isigclient) + private + foutput: tdoubleoutputconn; + foutputpo: pdouble; + fcontroller: tsigcontroller; + fontransformvalue: sigineventty; + foptions: sigeditoptionsty; + fsigclientinfo: sigclientinfoty; +// foffset: real; + procedure setoutput(const avalue: tdoubleoutputconn); + procedure setcontroller(const avalue: tsigcontroller); + procedure setoptions(const avalue: sigeditoptionsty); +// procedure setoffset(const avalue: real); + protected + fsigvalue: real; + foutmin: real; + foutmax: real; + procedure setoutmin(const avalue: real); + procedure setoutmax(const avalue: real); + procedure setvaluemin(const avalue: realty); override; + procedure setvaluemax(const avalue: realty); override; + + procedure updatesigvalue; + procedure dochange; override; + procedure sighandler(const ainfo: psighandlerinfoty); + //isigclient + procedure initmodel; + procedure sigtick; virtual; + function getinputar: inputconnarty; + function getoutputar: outputconnarty; + function gethandler: sighandlerprocty; + function getzcount: integer; + procedure clear; + procedure modelchange; + function getsigcontroller: tsigcontroller; + function getsigclientinfopo: psigclientinfoty; + function getsigoptions: sigclientoptionsty; + procedure lock; + procedure unlock; + public + constructor create(aowner: tcomponent); override; + property output: tdoubleoutputconn read foutput write setoutput; + published + property controller: tsigcontroller read fcontroller write setcontroller; + property ontransformvalue: sigineventty read fontransformvalue + write fontransformvalue; +// property offset: real read foffset write setoffset; + property outmin: real read foutmin write setoutmin; + property outmax: real read foutmax write setoutmax; + property options: sigeditoptionsty read foptions write setoptions default []; + end; + + sigkeyinfoty = record + sigvalue: double; + eventvalue: double; + key: integer; + pressed: boolean; + timestamp: longword; + outpo: pdouble; + trigoutpo: pdouble; + end; + sigkeyinfoarty = array of sigkeyinfoty; + + tsigkeyboard = class(trealgraphdataedit,isigclient) + private + foutput: tdoubleoutconnarrayprop; + ftrigout: tdoubleoutconnarrayprop; + fcontroller: tsigcontroller; + fsigclientinfo: sigclientinfoty; + fontransformvalue: sigineventty; + fmin: real; + foptions: sigeditoptionsty; + fkeywidth: integer; + fkey: integer; + flastkey: integer; + fkeypressed: boolean; + foutputcount: integer; + foutputhigh: integer; + procedure setoutput(const avalue: tdoubleoutconnarrayprop); + procedure settrigout(const avalue: tdoubleoutconnarrayprop); + procedure setcontroller(const avalue: tsigcontroller); + procedure setmin(const avalue: real); + procedure setoptions(const avalue: sigeditoptionsty); + procedure setkeywidth(const avalue: integer); + procedure setoutputcount(const avalue: integer); + protected + fdummy: double; + fkeyinfos: sigkeyinfoarty; + procedure updatesigvalue(const akey: integer; const apressed: boolean); + procedure dochange; override; + procedure sighandler(const ainfo: psighandlerinfoty); + procedure paintglyph(const canvas: tcanvas; const acolorglyph: colorty; + const avalue; const arect: rectty); override; + procedure clientmouseevent(var info: mouseeventinfoty); override; + procedure dokeydown(var info: keyeventinfoty); override; + procedure dokeyup(var info: keyeventinfoty); override; + procedure doexit; override; + + //isigclient + procedure initmodel; + procedure sigtick; virtual; + function getinputar: inputconnarty; + function getoutputar: outputconnarty; + function gethandler: sighandlerprocty; + function getzcount: integer; + procedure clear; + procedure modelchange; + function getsigcontroller: tsigcontroller; + function getsigclientinfopo: psigclientinfoty; + function getsigoptions: sigclientoptionsty; + procedure lock; + procedure unlock; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property output: tdoubleoutconnarrayprop read foutput write setoutput; + property trigout: tdoubleoutconnarrayprop read ftrigout write settrigout; + //1 -> key down, -1 key up, 0 none + published + property keywidth: integer read fkeywidth write setkeywidth default defaultkeywidth; + property controller: tsigcontroller read fcontroller write setcontroller; + property ontransformvalue: sigineventty read fontransformvalue + write fontransformvalue; + property min: real read fmin write setmin; +// property max: real read fmax write setmax; + property options: sigeditoptionsty read foptions write setoptions + default defaultsigkeyboardoptions; + property outputcount: integer read foutputcount write setoutputcount default 1; + end; + + optionwavetablety = (owt_rotate,owt_mirror,owt_nodc); + optionswavetablety = set of optionwavetablety; + + twavetableedit = class(torderedxychartedit) + private + fwave: tsigwavetable; + fsamplecount: integer; + foptionswave: optionswavetablety; + procedure setwave(const avalue: tsigwavetable); + procedure setsamplecount(const avalue: integer); + procedure setoptionswave(const avalue: optionswavetablety); + protected + procedure sample; + procedure dochange; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property samplecount: integer read fsamplecount + write setsamplecount default defaultsamplecount; + property wave: tsigwavetable read fwave write setwave; + property optionswave: optionswavetablety read foptionswave + write setoptionswave default []; + end; + + optionfuncteditty = (ofe_rotate,ofe_mirror); + optionsfuncteditty = set of optionfuncteditty; + + tfuncttableedit = class(torderedxychartedit) + private + ffunct: tsigfuncttable; + foptionsfunct: optionsfuncteditty; + procedure setfunct(const avalue: tsigfuncttable); + procedure setoptionsfunct(const avalue: optionsfuncteditty); + protected + procedure dochange; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property funct: tsigfuncttable read ffunct write setfunct; + property optionsfunct: optionsfuncteditty read foptionsfunct + write setoptionsfunct default []; + end; + + ffteditoptionty = (feo_exp); + ffteditoptionsty = set of ffteditoptionty; +const + defaultffteditoptions = [feo_exp]; + +type + tffttableedit = class(txserieschartedit) + private + fwave: tsigwavetable; + fsamplecount: integer; + ffft: tfft; + ffft_harmonicscount: integer; + ffft_options: ffteditoptionsty; + ffft_expmin: real; + ffft_max: real; + procedure setwave(const avalue: tsigwavetable); + procedure setsamplecount(const avalue: integer); + procedure setfft_harmonicscount(const avalue: integer); + procedure setfft_options(const avalue: ffteditoptionsty); + procedure setfft_expmin(const avalue: real); + procedure setfft_max(const avalue: real); + protected + procedure sample; + procedure dochange; override; + procedure doclear; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property samplecount: integer read fsamplecount + write setsamplecount default defaultsamplecount; + property fft_harmonicscount: integer read ffft_harmonicscount + write setfft_harmonicscount default defaultharmonicscount; + property fft_options: ffteditoptionsty read ffft_options + write setfft_options default defaultffteditoptions; + property fft_expmin: real read ffft_expmin write setfft_expmin; + property fft_max: real read ffft_max write setfft_max; + property wave: tsigwavetable read fwave write setwave; + property options default defaultffttableeditoptions; + end; + + tenvelopeedit = class; + + tenvelopechartedit = class(tcustomorderedxychartedit) + protected + fenvelope: tenvelopeedit; + procedure dochange; override; + procedure domarkerchange; override; + procedure drawcrosshaircursor(const canvas: tcanvas; + const center: pointty); override; + public + constructor create(aowner: tcomponent); override; + published + property traces; + property colorchart; + property xstart; + property ystart; + property xrange; + property yrange; + property xdials; + property ydials; +// property statfile; +// property statvarname; + property onbeforepaint; + property onpaintbackground; + property onpaint; + property onafterpaint; + + property ondataentered; + property onsetvalue; + property activetrace; + property optionsedit; + property snapdist; + property options; + property onchange; + end; + + tenvelopesplitter = class(tcustomsplitter) + public + constructor create(aowner: tcomponent); override; + published + property options default defaultenvsplitteroptions; + property shrinkpriority; +// property linkleft; +// property linktop; +// property linkright; +// property linkbottom; + + property grip; + property colorgrip; +// property statfile; +// property statvarname; + property onupdatelayout; + end; + + tenvelopeedit = class(tpublishedwidget,istatfile) + private + fstatvarname: msestring; + fstatfile: tstatfile; + fattack: tenvelopechartedit; + fdecay: tenvelopechartedit; + frelease: tenvelopechartedit; + fsplitter1: tenvelopesplitter; + fsplitter2: tenvelopesplitter; +// finnerframebefore: framety; + fenvelope: tsigenvelope; + fupdating: integer; + factivetrace: integer; + fmenustart: integer; + fstatpriority: integer; + procedure setenvelope(const avalue: tsigenvelope); + procedure setattack(const avalue: tenvelopechartedit); + procedure setdecay(const avalue: tenvelopechartedit); + procedure setrelease(const avalue: tenvelopechartedit); + procedure setsplitter1(const avalue: tenvelopesplitter); + procedure setsplitter2(const avalue: tenvelopesplitter); + procedure setstatfile(const avalue: tstatfile); + //istatfile + procedure dostatread(const reader: tstatreader); + procedure dostatwrite(const writer: tstatwriter); + procedure statreading; virtual; + procedure statread; virtual; + function getstatvarname: msestring; + function getstatpriority: integer; + procedure setactivetrace(avalue: integer); + protected + procedure updatelayout; + procedure clientrectchanged; override; + procedure dochange; + procedure updatevalues; + procedure updatepopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); override; + procedure doafterpopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); override; + + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure beginupdate; + procedure endupdate; + published + property attack: tenvelopechartedit read fattack write setattack; + property decay: tenvelopechartedit read fdecay write setdecay; + property release: tenvelopechartedit read frelease write setrelease; + property splitter1: tenvelopesplitter read fsplitter1 write setsplitter1; + property splitter2: tenvelopesplitter read fsplitter2 write setsplitter2; + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read getstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + property envelope: tsigenvelope read fenvelope write setenvelope; + property optionswidget default defaultoptionswidgetmousewheel; + property activetrace: integer read factivetrace + write setactivetrace default 0; + end; +(* + tenvelopeedit1 = class(torderedxychartedit) + private + fenvelope: tsigenvelope; + procedure setenvelope(const avalue: tsigenvelope); + protected + procedure updatevalues; + procedure dochange; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property envelope: tsigenvelope read fenvelope write setenvelope; + end; +*) + tsigscope = class; + tscopesampler = class(tsigsampler) + private + fscope: tsigscope; + protected + procedure dobufferfull; override; + public + constructor create(const aowner: tsigscope); reintroduce; + end; + + tsigscope = class(tchart) + private + fsampler: tscopesampler; + procedure setsampler(const avalue: tscopesampler); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property sampler: tscopesampler read fsampler write setsampler; + end; + +implementation +uses + math,msekeyboard,msebits,msesysutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tsigcontroller1 = class(tsigcontroller); + tsigenvelope1 = class(tsigenvelope); + tdoubleoutputconn1 = class(tdoubleoutputconn); + +{ tsigrealedit } + +constructor tsigrealedit.create(aowner: tcomponent); +begin + foutput:= tdoubleoutputconn.create(self,isigclient(self),true); + inherited; + fvalue:= 0; + fvaluedefault:= 0; + fvaluemin:= -bigreal; + foutmax:= 1; +end; + +procedure tsigrealedit.setoutput(const avalue: tdoubleoutputconn); +begin + foutput.assign(avalue); +end; + +procedure tsigrealedit.setcontroller(const avalue: tsigcontroller); +begin + setsigcontroller(getobjectlinker,isigclient(self),avalue,fcontroller); +end; + +procedure tsigrealedit.setoptions(const avalue: sigeditoptionsty); +begin + if options <> avalue then begin + foptions:= avalue; + updatesigvalue; + end; +end; + +procedure tsigrealedit.initmodel; +begin + foutputpo:= @foutput.value; +end; + +function tsigrealedit.getinputar: inputconnarty; +begin + result:= nil; +end; + +function tsigrealedit.getoutputar: outputconnarty; +begin + setlength(result,1); + result[0]:= foutput; +end; + +function tsigrealedit.getzcount: integer; +begin + result:= 0; +end; + +procedure tsigrealedit.clear; +begin + //dummy +end; + +procedure tsigrealedit.modelchange; +begin + //dummy +end; + +function tsigrealedit.getsigcontroller: tsigcontroller; +begin + result:= fcontroller; +end; + +procedure tsigrealedit.updatesigvalue; +var + do1: double; +begin + if componentstate * [csdesigning,csloading] = [] then begin + if (sieo_exp in foptions) and (foutmin > 0) and (foutmax > 0) then begin + if (sieo_expzero in foptions) and (fvalue <= 0) then begin + do1:= 0; + end + else begin + do1:= foutmin*exp(fvalue*(ln(foutmax)-ln(foutmin))); + end; + end + else begin + do1:= fvalue*(foutmax-foutmin)+foutmin; + end; + if canevent(tmethod(fontransformvalue)) then begin + fontransformvalue(self,real(do1)); + end; + lock; + try + fsigvalue:= do1; + if fcontroller <> nil then begin + tsigcontroller1(fcontroller).execevent(isigclient(self)); + end; + finally + unlock; + end; + end; +end; + +procedure tsigrealedit.dochange; +begin + inherited; + updatesigvalue; +end; + +procedure tsigrealedit.sighandler(const ainfo: psighandlerinfoty); +begin + foutputpo^:= fsigvalue; +end; + +function tsigrealedit.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}sighandler; +end; + +procedure tsigrealedit.setoutmin(const avalue: real); +begin + foutmin:= avalue; + updatesigvalue; +end; + +procedure tsigrealedit.setoutmax(const avalue: real); +begin + foutmax:= avalue; + updatesigvalue; +end; + +function tsigrealedit.getsigclientinfopo: psigclientinfoty; +begin + result:= @fsigclientinfo; +end; + +procedure tsigrealedit.sigtick; +begin + //dummy +end; + +function tsigrealedit.getsigoptions: sigclientoptionsty; +begin + result:= []; +end; + +procedure tsigrealedit.lock; +begin + if fcontroller <> nil then begin + fcontroller.lock; + end; +end; + +procedure tsigrealedit.unlock; +begin + if fcontroller <> nil then begin + fcontroller.unlock; + end; +end; +{ +procedure tsigrealedit.setoffset(const avalue: real); +begin + foffset:= avalue; + updatesigvalue; +end; +} +procedure tsigrealedit.setvaluemin(const avalue: realty); +begin + inherited; + updatesigvalue; +end; + +procedure tsigrealedit.setvaluemax(const avalue: realty); +begin + inherited; + updatesigvalue; +end; + +{ tsigslider } + +constructor tsigslider.create(aowner: tcomponent); +begin + foutput:= tdoubleoutputconn.create(self,isigclient(self),true); + fmax:= 1; + inherited; +end; + +procedure tsigslider.setcontroller(const avalue: tsigcontroller); +begin + setsigcontroller(getobjectlinker,isigclient(self),avalue,fcontroller); +end; + +procedure tsigslider.initmodel; +begin + foutputpo:= @tdoubleoutputconn1(foutput).fvalue; +end; + +function tsigslider.getinputar: inputconnarty; +begin + result:= nil; +end; + +function tsigslider.getoutputar: outputconnarty; +begin + setlength(result,1); + result[0]:= foutput; +end; + +function tsigslider.getzcount: integer; +begin + result:= 0; +end; + +procedure tsigslider.clear; +begin + //dummy +end; + +procedure tsigslider.setoutput(const avalue: tdoubleoutputconn); +begin + foutput.assign(avalue); +end; + +procedure tsigslider.modelchange; +begin + //dummy +end; + +function tsigslider.getsigcontroller: tsigcontroller; +begin + result:= fcontroller; +end; + +procedure tsigslider.updatesigvalue; +var + do1: double; +begin + if componentstate * [csdesigning,csloading] = [] then begin + if (sieo_exp in foptions) and (fmin > 0) and (fmax > 0) then begin + if (sieo_expzero in foptions) and (fvalue <= 0) then begin + do1:= 0; + end + else begin + do1:= fmin*exp(fvalue*(ln(fmax)-ln(fmin))); + end; + end + else begin + do1:= fvalue*(fmax-fmin)+fmin; + end; + if canevent(tmethod(fontransformvalue)) then begin + fontransformvalue(self,real(do1)); + end; + lock; + try + fsigvalue:= do1; + if fcontroller <> nil then begin + tsigcontroller1(fcontroller).execevent(isigclient(self)); + end; + finally + unlock; + end; + end; +end; + +procedure tsigslider.dochange; +begin + inherited; + updatesigvalue; +end; + +procedure tsigslider.sighandler(const ainfo: psighandlerinfoty); +begin + foutputpo^:= fsigvalue; +end; + +function tsigslider.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}sighandler; +end; + +procedure tsigslider.setmin(const avalue: real); +begin + fmin:= avalue; + updatesigvalue; +end; + +procedure tsigslider.setmax(const avalue: real); +begin + fmax:= avalue; + updatesigvalue; +end; + +procedure tsigslider.setoptions(const avalue: sigeditoptionsty); +begin + if options <> avalue then begin + foptions:= avalue; + updatesigvalue; + end; +end; + +function tsigslider.getsigclientinfopo: psigclientinfoty; +begin + result:= @fsigclientinfo; +end; + +procedure tsigslider.sigtick; +begin + //dummy +end; + +function tsigslider.getsigoptions: sigclientoptionsty; +begin + result:= []; +end; + +procedure tsigslider.lock; +begin + if fcontroller <> nil then begin + fcontroller.lock; + end; +end; + +procedure tsigslider.unlock; +begin + if fcontroller <> nil then begin + fcontroller.unlock; + end; +end; + +{ tsigkeyboard } + +constructor tsigkeyboard.create(aowner: tcomponent); +begin + foptions:= defaultsigkeyboardoptions; + fkey:= -1; + ftrigout:= tdoubleoutconnarrayprop.create(self,'trigout',isigclient(self),true); +// ftrigout.name:= 'trigout'; + foutput:= tdoubleoutconnarrayprop.create(self,'output',isigclient(self),true); + fmin:= 0.001; +// fmax:= 1; + fkeywidth:= defaultkeywidth; + inherited; + outputcount:= 1; +end; + +destructor tsigkeyboard.destroy; +begin + ftrigout.free; + foutput.free; + inherited; +end; + +procedure tsigkeyboard.setcontroller(const avalue: tsigcontroller); +begin + setsigcontroller(getobjectlinker,isigclient(self),avalue,fcontroller); +end; + +procedure tsigkeyboard.initmodel; +var + int1: integer; + ti1: longword; +begin + ti1:= timestamp; + for int1:= 0 to foutputhigh do begin + with fkeyinfos[int1] do begin + timestamp:= ti1; + eventvalue:= 0; + sigvalue:= fmin; + key:= -1; + if int1 < output.count then begin + outpo:= @tdoubleoutputconn1(output[int1]).fvalue; + end + else begin + outpo:= @fdummy; + end; + if int1 < trigout.count then begin + trigoutpo:= @tdoubleoutputconn1(trigout[int1]).fvalue; + end + else begin + trigoutpo:= @fdummy; + end; + end; + end; +end; + +function tsigkeyboard.getinputar: inputconnarty; +begin + result:= nil; +end; + +function tsigkeyboard.getoutputar: outputconnarty; +var + int1,int2: integer; +begin + setlength(result,foutput.count+ftrigout.count); + int2:= foutput.count; + for int1:= 0 to int2-1 do begin + result[int1]:= foutput[int1]; + end; + for int1:= 0 to ftrigout.count - 1 do begin + result[int1+int2]:= ftrigout[int1]; + end; +end; + +function tsigkeyboard.getzcount: integer; +begin + result:= 0; +end; + +procedure tsigkeyboard.clear; +begin + //dummy +end; + +procedure tsigkeyboard.setoutput(const avalue: tdoubleoutconnarrayprop); +begin + foutput.assign(avalue); +end; + +procedure tsigkeyboard.settrigout(const avalue: tdoubleoutconnarrayprop); +begin + ftrigout.assign(avalue); +end; + +procedure tsigkeyboard.modelchange; +begin + //dummy +end; + +function tsigkeyboard.getsigcontroller: tsigcontroller; +begin + result:= fcontroller; +end; + +procedure tsigkeyboard.updatesigvalue(const akey: integer; + const apressed: boolean); +var + do1,do2: double; + int1,int2: integer; + ind1,oldest: integer; + ti1,ti2: longword; +begin + if foutputcount > 0 then begin + ind1:= -1; + ti1:= timestamp; + ti2:= 0; + oldest:= 0; + lock; + try + for int1:= 0 to foutputhigh do begin + with fkeyinfos[int1] do begin + int2:= ti1 - timestamp; + if int2 > ti2 then begin + ti2:= int2; + oldest:= int1; + end; + if key = akey then begin + ind1:= int1; + end; + end; + end; + if ind1 < 0 then begin + ind1:= oldest; + end; + with fkeyinfos[ind1] do begin + key:= akey; + timestamp:= ti1; + pressed:= apressed; + if not apressed then begin + do1:= sigvalue; + do2:= -1; + end + else begin + do2:= 1; + if (sieo_exp in foptions) then begin + do1:= intpower(2.0,key div 12) * chromaticscale[key mod 12] * fmin; + end + else begin + do1:= fkey/12.0 + fmin; + end; + end; + if canevent(tmethod(fontransformvalue)) then begin + fontransformvalue(self,real(do1)); + end; + sigvalue:= do1; + eventvalue:= do2; + end; + if fcontroller <> nil then begin + tsigcontroller1(fcontroller).execevent(isigclient(self)); + end; + finally + unlock; //todo: single event for current output only + end; + end; +end; + +procedure tsigkeyboard.dochange; +begin + inherited; + updatesigvalue(-1,false); +end; + +procedure tsigkeyboard.sighandler(const ainfo: psighandlerinfoty); +var + int1: integer; +begin + if foutputcount > 0 then begin +// ainfo^.dest^:= fkeyinfos[0].sigvalue; + for int1:= 0 to foutputhigh do begin + with fkeyinfos[int1] do begin + outpo^:= sigvalue; + trigoutpo^:= eventvalue; + eventvalue:= 0; + end; + end; + end; +end; + +function tsigkeyboard.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}sighandler; +end; + +procedure tsigkeyboard.setmin(const avalue: real); +var + int1: integer; +begin + lock; + fmin:= avalue; + for int1:= 0 to foutputhigh do begin + with fkeyinfos[int1] do begin + if sigvalue < fmin then begin + sigvalue:= fmin; + end; + end; + end; + updatesigvalue(-1,false); + unlock; +end; +{ +procedure tsigkeyboard.setmax(const avalue: real); +begin + fmax:= avalue; + updatesigvalue; +end; +} +procedure tsigkeyboard.setoptions(const avalue: sigeditoptionsty); +begin + if options <> avalue then begin + lock; + foptions:= avalue; + updatesigvalue(-1,false); + unlock; + end; +end; + +function tsigkeyboard.getsigclientinfopo: psigclientinfoty; +begin + result:= @fsigclientinfo; +end; + +procedure tsigkeyboard.paintglyph(const canvas: tcanvas; + const acolorglyph: colorty; const avalue; const arect: rectty); +var +// pt1: pointty; + ar1: segmentarty; + int1,int2,int3,int4: integer; + rect1: rectty; +begin + setlength(ar1,arect.cx div fkeywidth + 1); + int2:= arect.y + arect.cy; + int3:= arect.x; + for int1:= 0 to high(ar1) do begin + with(ar1[int1]) do begin + a.x:= int3; + a.y:= arect.y; + b.x:= int3; + b.y:= int2; + end; + inc(int3,fkeywidth); + end; + canvas.drawlinesegments(ar1,colorglyph); + int4:= (fkeywidth*2+1) div 3 + 1; //width of black keys + rect1.x:= arect.x + (fkeywidth - int4 div 2); + rect1.y:= arect.y; + rect1.cx:= int4+1; + rect1.cy:= arect.cy div 2; + for int1:= 0 to high(ar1) do begin + int3:= int1 mod 7; + if (int3 <> 2) and (int3 <> 6) then begin + canvas.fillrect(rect1,colorglyph); + end; + inc(rect1.x,fkeywidth); + end; +end; + +procedure tsigkeyboard.setkeywidth(const avalue: integer); +begin + if avalue <> fkeywidth then begin + fkeywidth:= avalue; + if fkeywidth < 4 then begin + fkeywidth:= 4; + end; + invalidate; + end; +end; + +const + whitekeys: array[0..6] of integer = (0,2,4,5,7,9,11); + blackkeys: array[0..6] of integer = (-1,1,3,-1,6,8,10); + +procedure tsigkeyboard.clientmouseevent(var info: mouseeventinfoty); +var + keybefore: integer; + keynumber,key: integer; + rect1: rectty; +begin + keybefore:= fkey; + if not (csdesigning in componentstate) and + (info.eventkind in mouseposevents) then begin + if (ss_left in info.shiftstate) or fkeypressed then begin + rect1:= innerclientrect; + if pointinrect(info.pos,rect1) then begin + if info.pos.y >= rect1.y + rect1.cy div 2 then begin //white keys + keynumber:= (info.pos.x - rect1.x) div fkeywidth; + key:= whitekeys[keynumber mod 7]; + end + else begin + keynumber:= (info.pos.x - rect1.x + fkeywidth div 2) div fkeywidth; + key:= blackkeys[keynumber mod 7]; + if key < 0 then begin + keynumber:= (info.pos.x - rect1.x) div fkeywidth; + key:= whitekeys[keynumber mod 7]; + end; + end; + fkey:= (keynumber div 7)*12+key; + flastkey:= fkey; + end + else begin + if not fkeypressed then begin + fkey:= -1; + end; + end; + end + else begin + if not fkeypressed then begin + fkey:= -1; + end; + end; + end + else begin + if not fkeypressed and + (info.eventkind in [ek_mouseleave,ek_clientmouseleave]) then begin + fkey:= -1; + end; + end; + if keybefore <> fkey then begin + include(info.eventstate,es_processed); + if fkey = -1 then begin + updatesigvalue(keybefore,false); + end + else begin + if keybefore >= 0 then begin + updatesigvalue(keybefore,false); + end; + updatesigvalue(fkey,true); + end; + end + else begin + inherited; + end; +end; + +procedure tsigkeyboard.dokeydown(var info: keyeventinfoty); +begin + if (info.key = key_space) and not (ss_repeat in info.shiftstate) and + (flastkey <> fkey) then begin + fkey:= flastkey; + include(info.eventstate,es_processed); + fkeypressed:= true; + updatesigvalue(fkey,true); + end + else begin + inherited; + end; +end; + +procedure tsigkeyboard.dokeyup(var info: keyeventinfoty); +begin + if (info.key = key_space) and + not (ss_repeat in info.shiftstate) and (fkey >= 0) then begin + include(info.eventstate,es_processed); + updatesigvalue(fkey,false); + fkey:= -1; + fkeypressed:= false; + end + else begin + inherited; + end; +end; + +procedure tsigkeyboard.doexit; +begin + fkeypressed:= false; + inherited; +end; + +procedure tsigkeyboard.sigtick; +begin + //dummy +end; + +function tsigkeyboard.getsigoptions: sigclientoptionsty; +begin + result:= []; +end; + +procedure tsigkeyboard.setoutputcount(const avalue: integer); +begin + foutputcount:= avalue; + foutputhigh:= avalue-1; + output.count:= avalue; + trigout.count:= avalue; + setlength(fkeyinfos,avalue); +end; + +procedure tsigkeyboard.lock; +begin + if fcontroller <> nil then begin + fcontroller.lock; + end; +end; + +procedure tsigkeyboard.unlock; +begin + if fcontroller <> nil then begin + fcontroller.unlock; + end; +end; + +{ twavetableedit } + +constructor twavetableedit.create(aowner: tcomponent); +begin + fsamplecount:= defaultsamplecount; + inherited; + fwave:= tsigwavetable.create(self); + fwave.name:= 'wave'; + fwave.setsubcomponent(true); +end; + +destructor twavetableedit.destroy; +begin + fwave.free; + inherited; +end; + +procedure twavetableedit.setwave(const avalue: tsigwavetable); +begin + fwave.assign(avalue); +end; + +procedure twavetableedit.sample; + + function intpol(const ax: double): double; + var + int1,int2: integer; + rea1: real; + begin + int2:= -1; + for int1:= 0 to high(fvalue) do begin + if fvalue[int1].re >= ax then begin + int2:= int1; + break; + end; + end; + if int2 < 0 then begin + result:= fvalue[high(fvalue)].im; + end + else begin + result:= fvalue[int2].im; + if int2 > 0 then begin + rea1:= fvalue[int2].re-fvalue[int2-1].re; + if rea1 = 0 then begin + rea1:= 0.5; + end + else begin + rea1:= (fvalue[int2].re-ax)/rea1; + end; + result:= result + (fvalue[int2-1].im - result) * rea1; + end; + end; + end; //intpol + +var + ar1: doublearty; + int1,int2,int3: integer; + sampco,start: integer; + do1: double; +begin + if foptionswave * [owt_rotate,owt_mirror] = [] then begin + sampco:= fsamplecount; + start:= 0; + end + else begin + sampco:= (fsamplecount+1) div 2; + start:= fsamplecount div 2; + end; + setlength(ar1,fsamplecount); + if (sampco > 0) and (high(fvalue) >= 0) then begin + do1:= 1/sampco; + for int1:= 0 to sampco - 1 do begin + ar1[int1+start]:= intpol(do1*int1); + end; + end; + int2:= fsamplecount and 1; //odd + int3:= start+start+int2-1; + if owt_rotate in foptionswave then begin + for int1:= start+int2 to int3 do begin + ar1[int3-int1]:= - ar1[int1]; + end; + end + else begin + if owt_mirror in foptionswave then begin + for int1:= start+int2 to int3 do begin + ar1[int3-int1]:= ar1[int1]; + end; + end; + end; + if (owt_nodc in foptionswave) and (ar1 <> nil) then begin + do1:= 0; + for int1:= 0 to high(ar1) do begin + do1:= do1 + ar1[int1]; + end; + do1:= do1 / length(ar1); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= ar1[int1] - do1;; + end; + end; + fwave.table:= ar1; +end; + +procedure twavetableedit.dochange; +begin + sample; + inherited; +end; + +procedure twavetableedit.setsamplecount(const avalue: integer); +begin + if avalue <> fsamplecount then begin + fsamplecount:= avalue; + if not (csloading in componentstate) then begin + dochange; + end; + end; +end; + +procedure twavetableedit.setoptionswave(const avalue: optionswavetablety); +const + mask: optionswavetablety = [owt_rotate,owt_mirror]; +begin + if foptionswave <> avalue then begin + foptionswave:= optionswavetablety(setsinglebit( + {$ifdef FPC}longword{$else}byte{$endif}(avalue), + {$ifdef FPC}longword{$else}byte{$endif}(foptionswave), + {$ifdef FPC}longword{$else}byte{$endif}(mask))); + if not (csloading in componentstate) then begin + dochange; + end; + end; +end; + +{ tfuncttableedit } + +constructor tfuncttableedit.create(aowner: tcomponent); +begin + inherited; + ffunct:= tsigfuncttable.create(self); + ffunct.name:= 'funct'; + ffunct.setsubcomponent(true); +end; + +destructor tfuncttableedit.destroy; +begin + ffunct.free; + inherited; +end; + +procedure tfuncttableedit.setfunct(const avalue: tsigfuncttable); +begin + ffunct.assign(avalue); +end; + +procedure tfuncttableedit.dochange; +var + ar1: complexarty; + int1,int2: integer; +begin + if ofe_rotate in foptionsfunct then begin + int2:= length(fvalue); + setlength(ar1,int2*2); + for int1:= 0 to high(fvalue) do begin + ar1[int2+int1]:= fvalue[int1]; + with ar1[int2-int1-1] do begin + re:= -fvalue[int1].re; + im:= -fvalue[int1].im; + end; + end; + ffunct.table:= ar1; + end + else begin + if ofe_mirror in foptionsfunct then begin + int2:= length(fvalue); + setlength(ar1,int2*2); + for int1:= 0 to high(fvalue) do begin + ar1[int2+int1]:= fvalue[int1]; + with ar1[int2-int1-1] do begin + re:= -fvalue[int1].re; + im:= fvalue[int1].im; + end; + end; + ffunct.table:= ar1; + end + else begin + ffunct.table:= fvalue; + end; + end; + inherited; +end; + +procedure tfuncttableedit.setoptionsfunct(const avalue: optionsfuncteditty); +const + mask: optionsfuncteditty = [ofe_rotate,ofe_mirror]; +begin + if foptionsfunct <> avalue then begin + foptionsfunct:= optionsfuncteditty(setsinglebit( + {$ifdef FPC}longword{$else}byte{$endif}(avalue), + {$ifdef FPC}longword{$else}byte{$endif}(foptionsfunct), + {$ifdef FPC}longword{$else}byte{$endif}(mask))); + if not (csloading in componentstate) then begin + dochange; + end; + end; +end; + +{ tffttableedit } + +constructor tffttableedit.create(aowner: tcomponent); +begin + fsamplecount:= defaultsamplecount; + ffft_options:= defaultffteditoptions; + ffft_expmin:= 0.001; //-60dB + ffft_max:= 1; + inherited; + ffft:= tfft.create(nil); + fwave:= tsigwavetable.create(self); + fwave.name:= 'wave'; + fwave.setsubcomponent(true); + fft_harmonicscount:= defaultharmonicscount; + options:= defaultffttableeditoptions; +end; + +destructor tffttableedit.destroy; +begin + fwave.free; + ffft.free; + inherited; +end; + +procedure tffttableedit.setwave(const avalue: tsigwavetable); +begin + fwave.assign(avalue); +end; + +procedure tffttableedit.sample; +const + scale1 = 1/2; +var + ar1: complexarty; + int1,int2: integer; + rea1,rea2,rea3: real; +begin + setlength(ar1,fsamplecount div 2 + 1); + int2:= high(fvalue); + if int2 >= high(ar1) then begin + int2:= high(ar1)-1; + end; + rea3:= ffft_max*scale1; + if (feo_exp in ffft_options) and (ffft_expmin > 0) and (ffft_max > 0) then begin + rea1:= ln(ffft_max) - ln(ffft_expmin); + for int1:= 0 to int2 do begin + rea2:= fvalue[int1]; + if rea2 > 0 then begin + ar1[int1+1].im:= exp((rea2-1)*rea1)*rea3; + end; + end; + end + else begin + for int1:= 1 to int2 do begin + ar1[int1].im:= fvalue[int1-1]*rea3; + end; + end; + ffft.inpcomplex:= ar1; + fwave.table:= doublearty(ffft.outreal); +end; + +procedure tffttableedit.dochange; +begin + sample; + inherited; +end; + +procedure tffttableedit.setsamplecount(const avalue: integer); +begin + if avalue <> fsamplecount then begin + fsamplecount:= avalue; + sample; + end; +end; + +procedure tffttableedit.setfft_harmonicscount(const avalue: integer); +begin + ffft_harmonicscount:= avalue; + setlength(fvalue,avalue); + change; +end; + +procedure tffttableedit.doclear; +begin + fvalue:= nil; + setlength(fvalue,ffft_harmonicscount); +end; + +procedure tffttableedit.setfft_options(const avalue: ffteditoptionsty); +begin + if ffft_options <> avalue then begin + ffft_options:= avalue; + change; + end; +end; + +procedure tffttableedit.setfft_expmin(const avalue: real); +begin + if avalue <> ffft_expmin then begin + ffft_expmin:= avalue; + change; + end; +end; + +procedure tffttableedit.setfft_max(const avalue: real); +begin + if avalue <> ffft_max then begin + ffft_max:= avalue; + change; + end; +end; + +{ tenvelopeedit1 } +(* +constructor tenvelopeedit1.create(aowner: tcomponent); +begin + inherited; + xdials.count:= 1; + with xdials[0] do begin + markers.count:= 2; + with markers[0] do begin //loop start + value:= 0; + color:= cl_red; + options:= [dmo_ordered,dmo_savevalue]; + end; + with markers[1] do begin //decay + value:= 1; + color:= cl_green; + options:= [dmo_ordered,dmo_savevalue]; + end; + end; + fenvelope:= tsigenvelope.create(self); + fenvelope.name:= 'envelope'; + fenvelope.setsubcomponent(true); +end; + +destructor tenvelopeedit1.destroy; +begin + fenvelope.free; + inherited; +end; + +procedure tenvelopeedit1.setenvelope(const avalue: tsigenvelope); +begin + fenvelope.assign(avalue); +end; + +procedure tenvelopeedit1.dochange; +begin + inherited; + updatevalues; +end; + +procedure tenvelopeedit1.updatevalues; +begin + with fenvelope do begin + beginupdate; + values:= activetraceitem.xydata; + if xdials.count > 0 then begin + with xdials[0] do begin + if markers.count > 0 then begin + loopstart:= markers[0].value; + end + else begin + loopstart:= 0; + end; + if markers.count > 1 then begin + decaystart:= markers[1].value; + end + else begin + decaystart:= 1; + end + end; + end; + endupdate; + end; +end; +*) +{ tenvelopeedit } + +constructor tenvelopeedit.create(aowner: tcomponent); +const + splitterwidth = 4; +var + int1: integer; +begin + include(fwidgetstate1,ws1_noframewidgetshift); + inherited; + optionswidget:= defaultoptionswidgetmousewheel; + fenvelope:= tsigenvelope.create(self); + fenvelope.setsubcomponent(true); + fenvelope.name:= 'envelope'; + fattack:= tenvelopechartedit.create(self,self,false); + fdecay:= tenvelopechartedit.create(self,self,false); + frelease:= tenvelopechartedit.create(self,self,false); + fsplitter1:= tenvelopesplitter.create(self,self,false); + fsplitter2:= tenvelopesplitter.create(self,self,false); + width:= 3*30+2*splitterwidth; + int1:= (fwidgetrect.cx - splitterwidth*2) div 3; + fattack.bounds_cx:= int1; + fdecay.bounds_cx:= int1; + frelease.bounds_cx:= int1; + fsplitter1.bounds_cx:= splitterwidth; + fsplitter2.bounds_cx:= splitterwidth; + fsplitter1.bounds_x:= fattack.bounds_x + fattack.bounds_cx; + fsplitter2.bounds_x:= fsplitter1.bounds_x + fsplitter1.bounds_cx + + fdecay.bounds_cx; + updatelayout; + fsplitter1.linkleft:= fattack; + fsplitter1.linkright:= fdecay; + fsplitter2.linkleft:= fdecay; + fsplitter2.linkright:= frelease; + + with fdecay do begin + xdials.count:= 1; + xdials[0].markers.count:= 1; + with xdials[0].markers[0] do begin + value:= 10; + color:= cl_red; + options:= [dmo_savevalue]; + end; + end; + fattack.xrange:= 0.1; + fdecay.xrange:= 10; + frelease.xrange:= 1; +end; + +destructor tenvelopeedit.destroy; +begin + fattack.free; + fdecay.free; + frelease.free; + fenvelope.free; + inherited; +end; + +procedure tenvelopeedit.setattack(const avalue: tenvelopechartedit); +begin + fattack.assign(avalue); +end; + +procedure tenvelopeedit.setdecay(const avalue: tenvelopechartedit); +begin + fdecay.assign(avalue); +end; + +procedure tenvelopeedit.setrelease(const avalue: tenvelopechartedit); +begin + frelease.assign(avalue); +end; + +procedure tenvelopeedit.setsplitter1(const avalue: tenvelopesplitter); +begin + fsplitter1.assign(avalue); +end; + +procedure tenvelopeedit.setsplitter2(const avalue: tenvelopesplitter); +begin + fsplitter2.assign(avalue); +end; + +procedure tenvelopeedit.updatelayout; +var + rect1: rectty; + rect2: rectty; +// fr1,fr2: framety; +begin + rect1:= innerwidgetrect; + with rect1 do begin + rect2.pos:= pos; + rect2.cy:= cy; + rect2.cx:= fattack.bounds_cx - x + fattack.bounds_x; + fattack.widgetrect:= rect2; + rect2.x:= fsplitter1.bounds_x; + rect2.cx:= fsplitter1.bounds_cx; + fsplitter1.widgetrect:= rect2; + rect2.x:= fsplitter2.bounds_x; + rect2.cx:= fsplitter2.bounds_cx; + fsplitter2.widgetrect:= rect2; + rect2.x:= fsplitter1.bounds_x+fsplitter1.bounds_cx; + rect2.cx:= fdecay.bounds_cx; + fdecay.widgetrect:= rect2; + rect2.x:= fsplitter2.bounds_x+fsplitter2.bounds_cx; + rect2.cx:= cx - rect2.x; + frelease.widgetrect:= rect2; + end; +end; + +procedure tenvelopeedit.clientrectchanged; +begin + inherited; + updatelayout; +end; + +procedure tenvelopeedit.setstatfile(const avalue: tstatfile); +begin + setstatfilevar(istatfile(self),avalue,fstatfile); +end; + +procedure tenvelopeedit.dostatread(const reader: tstatreader); +var + mstr1: msestring; +begin + mstr1:= reader.varname(istatfile(self)); + beginupdate; + try + if reader.findsection(mstr1+'.0') then begin + fattack.dostatread(reader); + end; + if reader.findsection(mstr1+'.1') then begin + fsplitter1.dostatread(reader); + end; + if reader.findsection(mstr1+'.2') then begin + fdecay.dostatread(reader); + end; + if reader.findsection(mstr1+'.3') then begin + fsplitter2.dostatread(reader); + end; + if reader.findsection(mstr1+'.4') then begin + frelease.dostatread(reader); + end; + finally + endupdate; + end; +end; + +procedure tenvelopeedit.dostatwrite(const writer: tstatwriter); +var + mstr1: msestring; +begin + mstr1:= writer.varname(istatfile(self)); + writer.writesection(mstr1+'.0'); + fattack.dostatwrite(writer); + writer.writesection(mstr1+'.1'); + fsplitter1.dostatwrite(writer); + writer.writesection(mstr1+'.2'); + fdecay.dostatwrite(writer); + writer.writesection(mstr1+'.3'); + fsplitter2.dostatwrite(writer); + writer.writesection(mstr1+'.4'); + frelease.dostatwrite(writer); +end; + +procedure tenvelopeedit.statreading; +begin + fattack.statreading; + fdecay.statreading; + frelease.statreading; + fsplitter1.statreading; + fsplitter2.statreading; +end; + +procedure tenvelopeedit.statread; +begin + fattack.statread; + fdecay.statread; + frelease.statread; + fsplitter1.statread; + fsplitter2.statread; +end; + +function tenvelopeedit.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +procedure tenvelopeedit.updatevalues; + + procedure setva(const aindex: integer); + begin + with fenvelope do begin + attack_values[aindex]:= fattack.traces[aindex].xydata; + with fdecay do begin + decay_values[aindex]:= traces[aindex].xydata; + if xdials.count > 0 then begin + with xdials[0] do begin + if markers.count > 0 then begin + if markers[0].value < start+range then begin + loopstart[aindex]:= markers[0].value; + end + else begin + loopstart[aindex]:= -1; + end; + end + else begin + loopstart[aindex]:= -1; + end; + end; + end; + end; + release_values[aindex]:= frelease.traces[aindex].xydata; + end; + end; //setva() + +begin + fenvelope.beginupdate; + setva(0); + setva(1); + fenvelope.endupdate; +end; + +procedure tenvelopeedit.dochange; +begin + if fupdating >= 0 then begin + updatevalues; + end; +end; + +procedure tenvelopeedit.setenvelope(const avalue: tsigenvelope); +begin + fenvelope.assign(avalue); +end; + +procedure tenvelopeedit.beginupdate; +begin + inc(fupdating); +end; + +procedure tenvelopeedit.endupdate; +begin + dec(fupdating); + if fupdating = 0 then begin + dochange; + end; +end; + +procedure tenvelopeedit.setactivetrace(avalue: integer); +begin + if avalue < 0 then begin + avalue:= 0; + end; + if avalue > 1 then begin + avalue:= 1; + end; + factivetrace:= avalue; + fattack.activetrace:= avalue; + fdecay.activetrace:= avalue; + frelease.activetrace:= avalue; +end; + +procedure tenvelopeedit.updatepopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); +var + st1: actionstatesarty; +begin + inherited; + setlength(st1,2); + st1[factivetrace]:= [as_checked]; + fmenustart:= tpopupmenu.additems(amenu,self,mouseinfo,['Main Trace','Secondary Trace'], + [[mao_radiobutton],[mao_radiobutton]],st1,[]); +end; + +procedure tenvelopeedit.doafterpopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); +begin + inherited; + if amenu.menu.submenu[fmenustart].checked then begin + activetrace:= 0; + end + else begin + activetrace:= 1; + end; +end; + +function tenvelopeedit.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +{ tenvelopechartedit } + +constructor tenvelopechartedit.create(aowner: tcomponent); +begin + fenvelope:= tenvelopeedit(aowner); + if csdesigning in aowner.componentstate then begin + setdesigning(true); + end; + inherited create(nil); + setsubcomponent(true); + traces.count:= 2; + traces.options:= traces.options + [cto_stockglyphs]; +// traces.image_list:= stockobjects.glyphs; + with traces[0] do begin + imagenr:= ord(stg_circlesmall); + end; + with traces[1]do begin + imagenr:= ord(stg_squaresmall); + color:= cl_red; + end; + with frame do begin + optionsscroll:= optionsscroll + + [oscr_zoomheight,oscr_zoomwidth,oscr_drag,oscr_mousewheel]; + zoomwidthstep:= 1.5; + end; +end; + +procedure tenvelopechartedit.dochange; +begin + inherited; + fenvelope.dochange; +end; + +procedure tenvelopechartedit.domarkerchange; +begin + inherited; + fenvelope.dochange; +end; + +procedure tenvelopechartedit.drawcrosshaircursor(const canvas: tcanvas; + const center: pointty); + procedure drawyline(const dest: tenvelopechartedit; + const sourceoptions,destoptions: sigenveloperangeoptionsty); + var + co1: complexty; + pt1: pointty; + begin + co1:= tracecoordxy(0,center); + if (sero_exp in sourceoptions) xor (sero_exp in destoptions) then begin + if (sero_exp in sourceoptions) then begin + tsigenvelope1(fenvelope.fenvelope).exptolin(double(co1.im)); + end + else begin + tsigenvelope1(fenvelope.fenvelope).lintoexp(double(co1.im)); + end; + end; + pt1:= dest.chartcoordxy(0,co1); + canvas.drawvect(subpoint( + makepoint(dest.paintparentpos.x-paintparentpos.x,pt1.y),clientpos), + gd_right,dest.paintsize.cx); + end; //drawyline + +begin + inherited; + canvas.save; + canvas.clipregion:= 0; + with fenvelope,fenvelope do begin + if self = fattack then begin + drawyline(fdecay,attack_options,decay_options); + drawyline(frelease,attack_options,release_options); + end + else begin + if self = fdecay then begin + drawyline(fattack,decay_options,attack_options); + drawyline(frelease,decay_options,release_options); + end + else begin //release + drawyline(fattack,release_options,attack_options); + drawyline(fdecay,release_options,decay_options); + end; + end; + end; + canvas.restore; +end; + +{ tenvelopesplitter } + +constructor tenvelopesplitter.create(aowner: tcomponent); +begin + if csdesigning in aowner.componentstate then begin + setdesigning(true); + end; + inherited; //owner needed because of csreading and csloading +// inherited create(nil); + options:= defaultenvsplitteroptions; + setsubcomponent(true); +end; + +{ tscopesampler } + +constructor tscopesampler.create(const aowner: tsigscope); +begin + fscope:= aowner; + inherited create(aowner); + setsubcomponent(true); + name:= 'sampler'; +end; + +procedure tscopesampler.dobufferfull; +var + buf1: samplerbufferty; + int1: integer; +begin + inherited; + buf1:= copy(fsigbuffer); + lockapplication; + try + with fscope.traces do begin + for int1:= 0 to high(buf1) do begin + if int1 >= count then begin + break; + end; + items[int1].ydata:= realarty(buf1[int1]); + end; + end; + finally + unlockapplication; + end; +end; + +{ tsigscope } + +constructor tsigscope.create(aowner: tcomponent); +begin + fsampler:= tscopesampler.create(self); + inherited; +end; + +destructor tsigscope.destroy; +begin + fsampler.free; + inherited; +end; + +procedure tsigscope.setsampler(const avalue: tscopesampler); +begin + fsampler.assign(avalue); +end; + +end. diff --git a/mseide-msegui/lib/common/math/msesigmidi.pas b/mseide-msegui/lib/common/math/msesigmidi.pas new file mode 100644 index 0000000..fe1af9d --- /dev/null +++ b/mseide-msegui/lib/common/math/msesigmidi.pas @@ -0,0 +1,1213 @@ +{ MSEgui Copyright (c) 2010-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msesigmidi; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + msesignal,classes,mclasses,msemidi,msetypes,mseclasses,msedatamodules, + msearrayprops,msehash,msesercomm; +const + defaultmidiattackvalueoptions = [vso_exp,vso_null]; + defaultmidiattackvaluemin = 0.1; //20 dB + defaultmidireleasevalueoptions = []; + defaultmidireleasevaluemin = 0; + defaultmidipressurevalueoptions = []; + defaultmidipressurevaluemin = 0; + defaultmidivaluemax = 1; + paramscale = 1/127; //0..1 + defaultconnectorname = 'midiconn'; + channelmaxcount = 16; + channelmask = channelmaxcount - 1; + +type + tsigmidisource = class; + + tsigmidiconnector = class(tsigeventconnector) + private + ffrequout: tdoubleoutputconn; +// ffrequoutpo: pdouble; + ftrigout: tdoubleoutputconn; + // ftrigoutpo: pdouble; + ffrequ_min: double; + fattack: doublescaleinfoty; + fpressure: doublescaleinfoty; + frelease: doublescaleinfoty; + fsource: tsigmidisource; + fchannel: integer; + fattackout: tdoubleoutputconn; + fpressureout: tdoubleoutputconn; + freleaseout: tdoubleoutputconn; + fattackoutlin: tdoubleoutputconn; + ffrequoutlin: tdoubleoutputconn; + fpressureoutlin: tdoubleoutputconn; + freleaseoutlin: tdoubleoutputconn; + procedure setfrequout(const avalue: tdoubleoutputconn); + procedure settrigout(const avalue: tdoubleoutputconn); + procedure setsource(const avalue: tsigmidisource); + procedure setchannel(const avalue: integer); + procedure setattack_min(const avalue: double); + procedure setattack_max(const avalue: double); + procedure setattack_options(const avalue: valuescaleoptionsty); + procedure setpressure_min(const avalue: double); + procedure setpressure_max(const avalue: double); + procedure setpressure_options(const avalue: valuescaleoptionsty); + procedure setrelease_min(const avalue: double); + procedure setrelease_max(const avalue: double); + procedure setrelease_options(const avalue: valuescaleoptionsty); + procedure setattackout(const avalue: tdoubleoutputconn); + procedure setpressureout(const avalue: tdoubleoutputconn); + procedure setreleaseout(const avalue: tdoubleoutputconn); + procedure setattackoutlin(const avalue: tdoubleoutputconn); + procedure setfrequoutlin(const avalue: tdoubleoutputconn); + procedure setpressureoutlin(const avalue: tdoubleoutputconn); + procedure setreleaseoutlin(const avalue: tdoubleoutputconn); + protected + ftrigvalue: double; +// procedure initmodel; override; + procedure sighandler(const ainfo: psighandlerinfoty); + function getoutputar: outputconnarty; override; + function gethandler: sighandlerprocty; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure midievent(const ainfo: midieventinfoty); + property frequout: tdoubleoutputconn read ffrequout write setfrequout; + property frequoutlin: tdoubleoutputconn read ffrequoutlin + write setfrequoutlin; + property trigout: tdoubleoutputconn read ftrigout write settrigout; + property attackout: tdoubleoutputconn read fattackout write setattackout; + property attackoutlin: tdoubleoutputconn read fattackoutlin + write setattackoutlin; + property pressureout: tdoubleoutputconn read fpressureout + write setpressureout; + property pressureoutlin: tdoubleoutputconn read fpressureoutlin + write setpressureoutlin; + property releaseout: tdoubleoutputconn read freleaseout write setreleaseout; + property releaseoutlin: tdoubleoutputconn read freleaseoutlin + write setreleaseoutlin; + published + property frequ_min: double read ffrequ_min write ffrequ_min; + property attack_min: double read fattack.min write setattack_min; + property attack_max: double read fattack.max write setattack_max; + property attack_options: valuescaleoptionsty read fattack.options + write setattack_options default defaultmidiattackvalueoptions; + + property pressure_min: double read fpressure.min write setpressure_min; + property pressure_max: double read fpressure.max write setpressure_max; + property pressure_options: valuescaleoptionsty read fpressure.options + write setpressure_options default defaultmidipressurevalueoptions; + + property release_min: double read frelease.min write setrelease_min; + property release_max: double read frelease.max write setrelease_max; + property release_options: valuescaleoptionsty read frelease.options + write setrelease_options default defaultmidireleasevalueoptions; + + property source: tsigmidisource read fsource write setsource; + property channel: integer read fchannel write setchannel default 0; + end; + sigmidiconnectorarty = array of tsigmidiconnector; + + channelinfoty = record + + end; + + sigmidisourcestatety = (smss_patchvalid); + sigmidisourcestatesty = set of sigmidisourcestatety; + + pconnectioninfoty = ^connectioninfoty; + connectioninfoty = record + dest: tsigmidiconnector; + prev: pconnectioninfoty; + next: pconnectioninfoty; + key: byte; + active: boolean; + end; + connectioninfoarty = array of connectioninfoty; + + sigchannelinfoty = record + connections: connectioninfoarty; + first,last: pconnectioninfoty; + end; + + sigchannelinfoarty = array of sigchannelinfoty; + + patchinfoty = record + channel: integer; + track: integer; + notemin: integer; + notemax: integer; + midichannel: midichannelty; + end; + ppatchinfoty = ^patchinfoty; + + patchty = record + info: patchinfoty; + index: integer; + end; + ppatchty = ^patchty; + patchdataty = record + header: ptruintdataty; + data: patchty; + end; + patchhashdataty = record + header: hashheaderty; + data: patchdataty; + end; + ppatchhashdataty = ^patchhashdataty; + + tmidipatch = class(townedpersistent) + private + finfo: patchinfoty; + procedure setchannel(const avalue: integer); + procedure settrack(const avalue: integer); + procedure setnotemin(const avalue: integer); + procedure setnotemax(const avalue: integer); + procedure setmidichannel(const avalue: midichannelty); + protected + procedure changed; + public + constructor create(aowner: tobject); override; + published + property channel: integer read finfo.channel write setchannel default 0; + property track: integer read finfo.track write settrack default -1; + //-1 -> all + property midichannel: midichannelty read finfo.midichannel + write setmidichannel default mic_0; + property notemin: integer read finfo.notemin write setnotemin default 0; + property notemax: integer read finfo.notemax write setnotemax default 127; + end; + + tmidipatches = class(townedpersistentarrayprop) + protected + public + constructor create(const aowner: tsigmidisource); reintroduce; + class function getitemclasstype: persistentclassty; override; + //used in dumpunitgroups + end; + + tpatchinfolist = class(tptruinthashdatalist) + private + findexresult: integer; + fnote: byte; + fnoterange: integer; + procedure checkeventindex(const aitem: phashdataty; var accept: boolean); + protected + function getrecordsize(): int32 override; + public +// constructor create; + function add(const apatch: tmidipatch): ppatchhashdataty; + function geteventindex(const aevent: midieventinfoty): integer; + end; + + mididecodestatety = (mds_start,mds_readbytes,mds_eventcomplete); + + tsigmidisource = class(tmidisource,icommclient) + private + fconnections: sigmidiconnectorarty; + fpatches: tmidipatches; + fpatchpanel: tpatchinfolist; + fsercomm: tcustomcommcomp; + fserverintf: icommserver; + fdecodestate: mididecodestatety; + fbytecount: integer; + fbyteindex: integer; + fnextstate: mididecodestatety; + procedure setpatches(const avalue: tmidipatches); + procedure setsercomm(const avalue: tcustomcommcomp); + protected + fbytebuffer: array[0..15] of byte; + fsigstate: sigmidisourcestatesty; + fchannels: sigchannelinfoarty; + procedure registerconnector(const avalue: tsigmidiconnector); + procedure unregisterconnector(const avalue: tsigmidiconnector); + procedure dotrackevent; override; + procedure updatepatch; + procedure patchchanged; + //icommclient + procedure setcommserverintf(const aintf: icommserver); + procedure dorxchange(const areader: tcommreader); + public + constructor create(avalue: tcomponent); override; + destructor destroy; override; + published + property patches: tmidipatches read fpatches write setpatches; + property sercomm: tcustomcommcomp read fsercomm write setsercomm; + end; + + tsigmidimulticonnector = class; + getvoiceclasseventty = procedure(const sender: tobject; + var avoiceclass: datamoduleclassty) of object; + initvoiceeventty = procedure(const sender: tsigmidimulticonnector; + const aindex: integer; const avoice: tmsedatamodule) of object; + + tdoubleoutmultiinpconn = class(tdoubleoutputconn) + private + finputs: tdoubleinpconnarrayprop; + public + constructor create(const aowner: tcomponent; + const asigintf: isigclient; const aeventdriven: boolean); override; + destructor destroy; override; + property inputs: tdoubleinpconnarrayprop read finputs; + end; + + tmidiconnoutputarrayprop = class(tdoubleoutconnarrayprop) + private + function getitems(const index: integer): tdoubleoutmultiinpconn; + protected + procedure createitem(const index: integer; var item: tpersistent); override; + public + property items[const index: integer]: tdoubleoutmultiinpconn + read getitems; default; + end; + + tsigmidimulticonnector = class(tdoublesigcomp,isigclient) + private + fongetvoiceclass: getvoiceclasseventty; + fconnectorname: string; + finputcount: integer; + fpendinginputcount: integer; +// foutputcount: integer; + fvoices: msedatamodulearty; + fconnectors: sigmidiconnectorarty; + foninitvoice: initvoiceeventty; + foutputs: tmidiconnoutputarrayprop; + finps: sigvaluepoarty; + fouts: doublepoarty; + foutputhigh,finputhigh: integer; + fsource: tsigmidisource; + fchannel: integer; + function getitems(const index: integer): tmsedatamodule; + procedure setitems(const index: integer; const avalue: tmsedatamodule); + procedure setinputcount(const avalue: integer); + function getoutputcount: integer; + procedure setoutputcount(const avalue: integer); + procedure setsource(const avalue: tsigmidisource); + procedure updatesource; + procedure setchannel(const avalue: integer); + protected + procedure doinitvoice(const aindex: integer); + procedure loaded; override; + //isigclient + procedure initmodel; override; + function gethandler: sighandlerprocty; override; + procedure sighandler(const ainfo: psighandlerinfoty); + function getinputar: inputconnarty; override; + function getoutputar: outputconnarty; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property items[const index: integer]: tmsedatamodule read getitems + write setitems; default; + property outputs: tmidiconnoutputarrayprop read foutputs; + published + property inputcount: integer read finputcount write setinputcount default 0; + property outputcount: integer read getoutputcount + write setoutputcount default 0; + property source: tsigmidisource read fsource write setsource; + property channel: integer read fchannel write setchannel default 0; + property connectorname: string read fconnectorname write fconnectorname; + //'' -> defaultconnectorname + property ongetvoiceclass: getvoiceclasseventty read fongetvoiceclass + write fongetvoiceclass; + property oninitvoice: initvoiceeventty read foninitvoice write foninitvoice; + end; + +implementation +uses + math,msearrayutils,sysutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tsigcontroller1 = class(tsigcontroller); + tdoubleoutputconn1 = class(tdoubleoutputconn); + tdoubleinputconn1 = class(tdoubleinputconn); + +{ tsigmidiconnector } + +constructor tsigmidiconnector.create(aowner: tcomponent); +begin + initscale(defaultmidiattackvaluemin,defaultmidivaluemax, + defaultmidiattackvalueoptions,fattack); + initscale(defaultmidireleasevaluemin,defaultmidivaluemax, + defaultmidireleasevalueoptions,frelease); + initscale(defaultmidipressurevaluemin,defaultmidivaluemax, + defaultmidipressurevalueoptions,fpressure); + ffrequ_min:= 0.001; + ffrequout:= tdoubleoutputconn.create(self,isigclient(self),true); + ffrequout.name:= 'frequout'; + ffrequoutlin:= tdoubleoutputconn.create(self,isigclient(self),true); + ffrequoutlin.name:= 'frequoutlin'; + ftrigout:= tdoubleoutputconn.create(self,isigclient(self),true); + ftrigout.name:= 'trigout'; + fattackout:= tdoubleoutputconn.create(self,isigclient(self),true); + fattackout.name:= 'attackout'; + fattackoutlin:= tdoubleoutputconn.create(self,isigclient(self),true); + fattackoutlin.name:= 'attackoutlin'; + fpressureout:= tdoubleoutputconn.create(self,isigclient(self),true); + fpressureout.name:= 'pressureout'; + fpressureoutlin:= tdoubleoutputconn.create(self,isigclient(self),true); + fpressureoutlin.name:= 'pressureoutlin'; + freleaseout:= tdoubleoutputconn.create(self,isigclient(self),true); + freleaseout.name:= 'releaseout'; + freleaseoutlin:= tdoubleoutputconn.create(self,isigclient(self),true); + freleaseoutlin.name:= 'releaseoutlin'; + inherited; +end; + +destructor tsigmidiconnector.destroy; +begin + source:= nil; + inherited; +end; + +procedure tsigmidiconnector.sighandler(const ainfo: psighandlerinfoty); +//var +// int1: integer; +begin + //dummy +// ftrigoutpo^:= ftrigvalue; +end; + +function tsigmidiconnector.getoutputar: outputconnarty; +begin + setlength(result,9); + result[0]:= ftrigout; + result[1]:= ffrequout; + result[2]:= ffrequoutlin; + result[3]:= fattackout; + result[4]:= fattackoutlin; + result[5]:= fpressureout; + result[6]:= fpressureoutlin; + result[7]:= freleaseout; + result[8]:= freleaseoutlin; +end; + +function tsigmidiconnector.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}sighandler; +end; + +procedure tsigmidiconnector.setfrequout(const avalue: tdoubleoutputconn); +begin + ffrequout.assign(avalue); +end; + +procedure tsigmidiconnector.settrigout(const avalue: tdoubleoutputconn); +begin + ftrigout.assign(avalue); +end; + +procedure tsigmidiconnector.midievent(const ainfo: midieventinfoty); +begin + lock; + try + with ainfo do begin + case kind of + mmk_notepressure: begin + fpressure.value:= par2*paramscale; + tdoubleoutputconn1(fpressureoutlin).fvalue:= fpressure.value; + tdoubleoutputconn1(fpressureout).fvalue:= scalevalue(fpressure); + end; + mmk_noteon: begin + tdoubleoutputconn1(ffrequoutlin).fvalue:= par1*paramscale; + tdoubleoutputconn1(ffrequout).fvalue:= intpower(2.0,par1 div 12) * + chromaticscale[par1 mod 12] * ffrequ_min; + if par2 = 0 then begin + ftrigvalue:= -1; + frelease.value:= 0; + tdoubleoutputconn1(freleaseoutlin).fvalue:= frelease.value; + tdoubleoutputconn1(freleaseout).fvalue:= scalevalue(frelease); + end + else begin + ftrigvalue:= 1; + fattack.value:= par2*paramscale; + tdoubleoutputconn1(fattackoutlin).fvalue:= fattack.value; + tdoubleoutputconn1(fattackout).fvalue:= scalevalue(fattack); + end; + tdoubleoutputconn1(ftrigout).fvalue:= ftrigvalue; + end; + mmk_noteoff: begin + ftrigvalue:= -1; + frelease.value:= par2*paramscale; + tdoubleoutputconn1(freleaseoutlin).fvalue:= frelease.value; + tdoubleoutputconn1(freleaseout).fvalue:= scalevalue(frelease); + end; + end; + end; + if fcontroller <> nil then begin + tsigcontroller1(fcontroller).execevent(isigclient(self)); + end; + finally + unlock; + end; +end; + +procedure tsigmidiconnector.setsource(const avalue: tsigmidisource); +begin + if fsource <> avalue then begin + if fsource <> nil then begin + fsource.unregisterconnector(self); + end; + fsource:= avalue; + if fsource <> nil then begin + fsource.registerconnector(self); + end; + end; +end; + +procedure tsigmidiconnector.setchannel(const avalue: integer); +begin + if fchannel <> avalue then begin + fchannel:= avalue; + if fsource <> nil then begin + fsource.patchchanged; + end; + end; +end; + +procedure tsigmidiconnector.setattack_min(const avalue: double); +begin + fattack.min:= avalue; + updatescale(fattack); +end; + +procedure tsigmidiconnector.setattack_max(const avalue: double); +begin + fattack.max:= avalue; + updatescale(fattack); +end; + +procedure tsigmidiconnector.setattack_options(const avalue: valuescaleoptionsty); +begin + fattack.options:= avalue; + updatescale(fattack); +end; + +procedure tsigmidiconnector.setpressure_min(const avalue: double); +begin + fpressure.min:= avalue; + updatescale(fpressure); +end; + +procedure tsigmidiconnector.setpressure_max(const avalue: double); +begin + fpressure.max:= avalue; + updatescale(fpressure); +end; + +procedure tsigmidiconnector.setpressure_options(const avalue: valuescaleoptionsty); +begin + fpressure.options:= avalue; + updatescale(fpressure); +end; + +procedure tsigmidiconnector.setrelease_min(const avalue: double); +begin + frelease.min:= avalue; + updatescale(frelease); +end; + +procedure tsigmidiconnector.setrelease_max(const avalue: double); +begin + frelease.max:= avalue; + updatescale(frelease); +end; + +procedure tsigmidiconnector.setrelease_options(const avalue: valuescaleoptionsty); +begin + frelease.options:= avalue; + updatescale(frelease); +end; + +procedure tsigmidiconnector.setattackout(const avalue: tdoubleoutputconn); +begin + fattackout.assign(avalue); +end; + +procedure tsigmidiconnector.setpressureout(const avalue: tdoubleoutputconn); +begin + fpressureout.assign(avalue); +end; + +procedure tsigmidiconnector.setreleaseout(const avalue: tdoubleoutputconn); +begin + freleaseout.assign(avalue); +end; + +procedure tsigmidiconnector.setattackoutlin(const avalue: tdoubleoutputconn); +begin + fattackoutlin.assign(avalue); +end; + +procedure tsigmidiconnector.setfrequoutlin(const avalue: tdoubleoutputconn); +begin + ffrequoutlin.assign(avalue); +end; + +procedure tsigmidiconnector.setpressureoutlin(const avalue: tdoubleoutputconn); +begin + fpressureoutlin.assign(avalue); +end; + +procedure tsigmidiconnector.setreleaseoutlin(const avalue: tdoubleoutputconn); +begin + freleaseoutlin.assign(avalue); +end; + +{ tsigmidisource } + +constructor tsigmidisource.create(avalue: tcomponent); +begin + fpatches:= tmidipatches.create(self); + fpatchpanel:= tpatchinfolist.create; + inherited; +end; + +destructor tsigmidisource.destroy; +var + int1: integer; +begin + sercomm:= nil; + for int1:= 0 to high(fconnections) do begin + fconnections[int1].fsource:= nil; + end; + inherited; + fpatchpanel.free; + fpatches.free; +end; + +procedure tsigmidisource.patchchanged; +begin + exclude(fsigstate,smss_patchvalid); +end; + +procedure tsigmidisource.registerconnector(const avalue: tsigmidiconnector); +begin + additem(pointerarty(fconnections),avalue); + patchchanged; +end; + +procedure tsigmidisource.unregisterconnector(const avalue: tsigmidiconnector); +begin + removeitem(pointerarty(fconnections),avalue); + patchchanged; +end; + +procedure tsigmidisource.dotrackevent; +var + int1: integer; + po1: pconnectioninfoty; + by1: byte; +begin + inherited; + if not (smss_patchvalid in fsigstate) then begin + updatepatch; + end; + if ftrackevent.event.kind in [mmk_noteon,mmk_noteoff,mmk_notepressure] then begin + by1:= 0; //compiler warning + int1:= fpatchpanel.geteventindex(ftrackevent.event); + if int1 >= 0 then begin + with fchannels[int1] do begin + if connections <> nil then begin + po1:= first; + if po1 <> last then begin + by1:= ftrackevent.event.par1; + repeat + if po1^.key = by1 then begin + break; + end; + po1:= po1^.next; + until po1 = nil; + if po1 = nil then begin + po1:= last; + while po1 <> nil do begin + if not po1^.active then begin + break; + end; + po1:= po1^.prev; + end; + end; + if po1 <> first then begin + if po1 = nil then begin + po1:= last; + end; + if po1^.prev <> nil then begin + po1^.prev^.next:= po1^.next; + end; + if (po1^.next <> nil) then begin + po1^.next^.prev:= po1^.prev; + end; + first^.prev:= po1; + po1^.next:= first; + first:= po1; + if po1 = last then begin + last:= po1^.prev; + end; + po1^.prev:= nil; + end; + end; + po1^.key:= by1; + po1^.active:= (ftrackevent.event.kind = mmk_noteon) and + (ftrackevent.event.par2 <> 0) or + (ftrackevent.event.kind = mmk_notepressure); + po1^.dest.midievent(ftrackevent.event); + end; + end; + end; + end; +end; + +procedure tsigmidisource.updatepatch; +var + int1,int2: integer; + destlist: tpointerptruinthashdatalist; + patch1: tmidipatch; +// po1: ppatchty; + po2: pointer; +begin + fchannels:= nil; + fpatchpanel.clear; + destlist:= tpointerptruinthashdatalist.create; + int2:= 0; + for int1:= 0 to high(fconnections) do begin + if not destlist.addunique(fconnections[int1].channel,pointer(ptrint(int2))) then begin + inc(int2); + end; + end; + setlength(fchannels,int2); + for int1:= 0 to high(fconnections) do begin + with fchannels[ptruint(destlist.find(fconnections[int1].channel))] do begin + int2:= high(connections)+1; + setlength(connections,int2+1); + connections[int2].dest:= fconnections[int1]; + end; + end; + for int1:= 0 to fpatches.count - 1 do begin + patch1:= tmidipatch(fpatches.fitems[int1]); + if destlist.find(patch1.channel,po2) then begin + fpatchpanel.add(patch1)^.data.data.index:= ptrint(po2); + end; + end; + destlist.free; + for int2:= 0 to high(fchannels) do begin + with fchannels[int2] do begin + first:= nil; + last:= nil; + if high(connections) >= 0 then begin + first:= @connections[0]; + last:= @connections[high(connections)]; + for int1:= 0 to high(connections) do begin + with connections[int1] do begin +// dest:= fconnections[int1]; + if int1 < high(connections) then begin + next:= @connections[int1+1]; + end; + if int1 > 0 then begin + prev:= @connections[int1-1]; + end; + end; + end; + end; + end; + end; + include(fsigstate,smss_patchvalid); +end; + +procedure tsigmidisource.setpatches(const avalue: tmidipatches); +begin + fpatches.assign(avalue); +end; + +procedure tsigmidisource.setsercomm(const avalue: tcustomcommcomp); +begin + if fsercomm <> avalue then begin + setcomcomp(icommclient(self),avalue,fsercomm); + end; +end; + +procedure tsigmidisource.setcommserverintf(const aintf: icommserver); +begin + fserverintf:= aintf; +end; + +procedure tsigmidisource.dorxchange(const areader: tcommreader); + + procedure readbytes(const acount : integer; const nextstate: mididecodestatety); + begin + fbytecount:= acount; + fnextstate:= nextstate; + fdecodestate:= mds_readbytes; + fbyteindex:= 0; + end; //readbytes() + +var + po1: pchar; +begin + with ftrackevent.event do begin + while true do begin + po1:= areader.bufpo; + if po1 = nil then begin + break; + end; + if fdecodestate = mds_readbytes then begin + if po1 >= #$80 then begin + fdecodestate:= mds_start; //cancel byte read + end + else begin + if fbytecount > 0 then begin + fbytebuffer[fbyteindex]:= byte(po1^); + inc(fbyteindex); + if fbyteindex = fbytecount then begin + fdecodestate:= fnextstate; + end; + end; + areader.skip(1); + end; + end; + if fdecodestate <> mds_readbytes then begin + case fdecodestate of + mds_start: begin + if po1^ >= #$80 then begin //commandstart + fillchar(ftrackevent,sizeof(ftrackevent),0); + kind:= midimessagetable[(byte(po1^) shr 4) and $7]; + if kind in midichannelmessages then begin + channel:= byte(po1^) and $0f; + readbytes(midiparcount[kind],mds_eventcomplete); + end + else begin + end; + areader.skip(1); + end + else begin + areader.skip(1); + end; + end; + mds_eventcomplete: begin + ftrackevent.event.par1:= fbytebuffer[0]; + ftrackevent.event.par2:= fbytebuffer[1]; + readbytes(midiparcount[kind],mds_eventcomplete); + //prepare for next event with same state + dotrackevent; + end; + else begin + areader.skip(1); + end; + end; + end; + end; + end; +end; + +{ tdoubleoutmultiinpconn } + +constructor tdoubleoutmultiinpconn.create(const aowner: tcomponent; + const asigintf: isigclient; const aeventdriven: boolean); +begin + finputs:= tdoubleinpconnarrayprop.create(asigintf); + inherited; +end; + +destructor tdoubleoutmultiinpconn.destroy; +begin + finputs.free; + inherited; +end; + +{ tmidiconnoutputarrayprop } + +function tmidiconnoutputarrayprop.getitems(const index: integer): + tdoubleoutmultiinpconn; +begin + result:= tdoubleoutmultiinpconn(inherited getitems(index)); +end; + +procedure tmidiconnoutputarrayprop.createitem(const index: integer; + var item: tpersistent); +begin + item:= tdoubleoutmultiinpconn.create(fowner,fsigintf,feventdriven); + tdoubleoutputconn(item).name:= fname+inttostr(index); +end; + +{ tsigmidimulticonnector } + +constructor tsigmidimulticonnector.create(aowner: tcomponent); +begin + foutputs:= tmidiconnoutputarrayprop.create(self,'output', + isigclient(self),false); + inherited; +end; + +destructor tsigmidimulticonnector.destroy; +begin + inputcount:= 0; + foutputs.free; + inherited; +end; + +function tsigmidimulticonnector.getitems(const index: integer): tmsedatamodule; +begin + checkarrayindex(fvoices,index); + result:= fvoices[index]; +end; + +procedure tsigmidimulticonnector.setitems(const index: integer; + const avalue: tmsedatamodule); +begin + checkarrayindex(fvoices,index); + fvoices[index].assign(avalue); +end; + +procedure tsigmidimulticonnector.doinitvoice(const aindex: integer); +begin + lock; + try + with fconnectors[aindex] do begin + channel:= self.fchannel; + source:= self.fsource; + end; + if assigned(foninitvoice) then begin + foninitvoice(self,aindex,fvoices[aindex]); + end; + finally + unlock; + end; +end; + +procedure tsigmidimulticonnector.setinputcount(const avalue: integer); +var + int1: integer; + class1: datamoduleclassty; + str1: string; + voice1: tmsedatamodule; + conn1: tcomponent; +begin + if finputcount <> avalue then begin + if csloading in componentstate then begin + fpendinginputcount:= avalue; + end + else begin + if csdesigning in componentstate then begin + finputcount:= avalue; + end + else begin + lock; + try + if avalue <> finputcount then begin + if avalue < finputcount then begin + for int1:= finputcount-1 downto avalue do begin + fvoices[int1].free; + dec(finputcount); + end; + end + else begin + if not assigned(fongetvoiceclass) then begin + raise exception.create('ongetvoiceclass not assigned.'); + end; + class1:= nil; + fongetvoiceclass(self,class1); + if class1 = nil then begin + raise exception.create('Voiceclass not set.'); + end; + str1:= fconnectorname; + if str1 = '' then begin + str1:= defaultconnectorname; + end; + setlength(fvoices,avalue); //max + setlength(fconnectors,avalue); //max + for int1:= 0 to foutputs.count - 1 do begin + foutputs[int1].inputs.count:= avalue; //max + end; + for int1:= finputcount to avalue - 1 do begin + voice1:= class1.create(nil); + conn1:= voice1.findcomponent(str1); + if not (conn1 is tsigmidiconnector) then begin + voice1.free; + raise exception.create('tmidiconnector "'+str1+'" not found.'); + end; + fvoices[int1]:= voice1; + fconnectors[int1]:= tsigmidiconnector(conn1); + inc(finputcount); + doinitvoice(int1); + end; + end; + end; + finally + setlength(fvoices,finputcount); + setlength(fconnectors,finputcount); + for int1:= 0 to foutputs.count - 1 do begin + foutputs[int1].inputs.count:= finputcount; + end; + unlock; + end; + end; + end; + end; +end; + +procedure tsigmidimulticonnector.initmodel; +var + int1,int2,int3: integer; +begin + setlength(fouts,foutputs.count); + setlength(finps,finputcount*foutputs.count); + finputhigh:= finputcount-1; + foutputhigh:= foutputs.count-1; + int3:= 0; + for int1:= 0 to foutputhigh do begin + with foutputs[int1] do begin + fouts[int1]:= @fvalue; + for int2:= 0 to finputhigh do begin + finps[int3]:= @tdoubleinputconn1(inputs[int2]).fv; + inc(int3); + end; + end; + end; + inherited; +end; + +function tsigmidimulticonnector.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}sighandler; +end; + +procedure tsigmidimulticonnector.sighandler(const ainfo: psighandlerinfoty); +var + int1,int2: integer; + po1: ppdouble; + do1: double; +begin + po1:= ppdouble(finps); + if po1 <> nil then begin + for int1:= 0 to foutputhigh do begin + do1:= 0; + for int2:= finputhigh downto 0 do begin + do1:= do1 + po1^^; + inc(po1); + end; + fouts[int1]^:= do1; + end; + { + if fouts <> nil then begin + ainfo^.dest^:= ppdouble(fouts)^^; + end; + } + end; +end; + +function tsigmidimulticonnector.getinputar: inputconnarty; +var + int1,int2,int3: integer; +begin + setlength(result,finputcount*foutputs.count); + int3:= 0; + for int1:= 0 to foutputs.count - 1 do begin + with foutputs[int1] do begin + for int2:= 0 to finputcount - 1 do begin + result[int3]:= inputs[int2]; + inc(int3); + end; + end; + end; +end; + +function tsigmidimulticonnector.getoutputar: outputconnarty; +begin + result:= outputconnarty(copy(foutputs.fitems)); +end; + +function tsigmidimulticonnector.getoutputcount: integer; +begin + result:= foutputs.count; +end; + +procedure tsigmidimulticonnector.setoutputcount(const avalue: integer); +begin + foutputs.count:= avalue; +end; + +procedure tsigmidimulticonnector.setsource(const avalue: tsigmidisource); +begin + if avalue <> fsource then begin + setlinkedvar(tmsecomponent(avalue),tmsecomponent(fsource)); + updatesource; + end; +end; + +procedure tsigmidimulticonnector.updatesource; +var + int1: integer; +begin + lock; + try + for int1:= 0 to high(fconnectors) do begin + with fconnectors[int1] do begin + channel:= self.fchannel; + source:= self.fsource; + end; + end; + finally + unlock; + end; +end; + +procedure tsigmidimulticonnector.setchannel(const avalue: integer); +begin + if fchannel <> avalue then begin + fchannel:= avalue; + updatesource; + end; +end; + +procedure tsigmidimulticonnector.loaded; +begin + inherited; + lock; + try + inputcount:= fpendinginputcount; + finally + unlock; + end; +end; + +{ tmidipatches } + +constructor tmidipatches.create(const aowner: tsigmidisource); +begin + inherited create(aowner,tmidipatch); +end; + +class function tmidipatches.getitemclasstype: persistentclassty; +begin + result:= tmidipatch; +end; + +{ tmidipatch } + +constructor tmidipatch.create(aowner: tobject); +begin + finfo.track:= -1; + finfo.notemax:= 127; + inherited; +end; + +procedure tmidipatch.changed; +begin + tsigmidisource(fowner).patchchanged; +end; + +procedure tmidipatch.setchannel(const avalue: integer); +begin + if finfo.channel <> avalue then begin + finfo.channel:= avalue and channelmask; + changed; + end; +end; + +procedure tmidipatch.setmidichannel(const avalue: midichannelty); +begin + if finfo.midichannel <> avalue then begin + finfo.midichannel:= avalue; + changed; + end; +end; + +procedure tmidipatch.settrack(const avalue: integer); +begin + if finfo.track <> avalue then begin + finfo.track:= avalue; + changed; + end; +end; + +procedure tmidipatch.setnotemin(const avalue: integer); +begin + if finfo.notemin <> avalue then begin + finfo.notemin:= avalue; + changed; + end; +end; + +procedure tmidipatch.setnotemax(const avalue: integer); +begin + if finfo.notemax <> avalue then begin + finfo.notemax:= avalue; + changed; + end; +end; + +{ tpatchinfolist } +{ +constructor tpatchinfolist.create; +begin + inherited create(sizeof(patchty)); +end; +} +function tpatchinfolist.getrecordsize(): int32; +begin + result:= sizeof(patchhashdataty); +end; + +function tpatchinfolist.add(const apatch: tmidipatch): ppatchhashdataty; +begin + with apatch do begin + result:= ppatchhashdataty(inherited add((track shl 5) or ord(midichannel))); + result^.data.data.info:= finfo; + end; +end; + +function tpatchinfolist.geteventindex(const aevent: midieventinfoty): integer; +var + puint1: ptruint; +begin + findexresult:= -1; + fnote:= aevent.par1 and $7f; + fnoterange:= bigint; + puint1:= (aevent.track shl 5) or aevent.channel; + internalfind(puint1,{$ifdef FPC}@{$endif}checkeventindex); + if findexresult = -1 then begin + puint1:= puint1 or ($ffffffff shl 5); //-1 + internalfind(puint1,{$ifdef FPC}@{$endif}checkeventindex); + end; + result:= findexresult; +end; + +procedure tpatchinfolist.checkeventindex(const aitem: phashdataty; + var accept: boolean); +var + int1: integer; +begin + with ppatchhashdataty(aitem)^.data.data,info do begin + if (fnote >= notemin) and (fnote <= notemax) then begin + int1:= notemax - notemin; + if int1 < fnoterange then begin + findexresult:= index; + fnoterange:= int1; + end; + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/math/msesignal.pas b/mseide-msegui/lib/common/math/msesignal.pas new file mode 100644 index 0000000..6891a0b --- /dev/null +++ b/mseide-msegui/lib/common/math/msesignal.pas @@ -0,0 +1,4991 @@ +{ MSEgui Copyright (c) 2010-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} + +// +// todo: optimize for realtime, remove the OOP approach where +// it degrades performance, use SSE. +// + +unit msesignal; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + msedatalist,mseclasses,classes,mclasses,msetypes,msearrayprops,mseevent,msehash, + msesystypes,msereal,msetimer,mseglob; + +const + defaultsamplefrequ = 44100; //Hz + defaultstepcount = 4096; + defaultenvelopesubsampling = 8; + defaulttickdiv = 200; + defaultsamplecount = 4096; + defaultharmonicscount = 16; + functionsegmentcount = 32; +{$ifdef FPC} + semitoneln = ln(2)/12; + chromaticscale: array[0..12] of double = + (1.0,exp(1*semitoneln),exp(2*semitoneln),exp(3*semitoneln),exp(4*semitoneln), + exp(5*semitoneln),exp(6*semitoneln),exp(7*semitoneln),exp(8*semitoneln), + exp(9*semitoneln),exp(10*semitoneln),exp(11*semitoneln),2.0); +{$else} + semitoneln = 5.77622650467e-2; + chromaticscale: array[0..12] of double = + (1.0,1.05946309436,1.12246204831,1.189207115, + 1.2599210499,1.33483985417,1.41421356237,1.49830707688, + 1.58740105197,1.6817928179283051,1.78179743628,1.88774862536,2.0); +{$endif} + +type + siginchangeflagty = (sic_value,sic_stream); + siginchangeflagsty = set of siginchangeflagty; + psiginchangeflagsty = ^siginchangeflagsty; +const + siginchangeresetflags = [sic_value]; + +type + sigsampleroptionty = (sso_fulltick,sso_negtrig,sso_autorun, + sso_fftmag,sso_average); //used by tsigsamplerfft + sigsampleroptionsty = set of sigsampleroptionty; + +const + defaultsigsampleroptions = [sso_fulltick]; +type + tcustomsigcomp = class; + tdoublesigcomp = class; + tsigcontroller = class; + + tcustomsigcomp = class(tmsecomponent) + protected + fupdating: integer; + procedure coeffchanged(const sender: tdatalist; + const aindex: integer); virtual; + procedure update; virtual; + public + procedure beginupdate; + procedure endupdate; + end; + + tsigcomp = class(tcustomsigcomp) + + end; + + tdoubleinputconn = class; + tdoubleoutputconn = class; + + inputconnarty = array of tdoubleinputconn; + outputconnarty = array of tdoubleoutputconn; + + psighandlerinfoty = ^sighandlerinfoty; + sighandlerprocty = procedure(const ainfo: psighandlerinfoty) of object; + + psiginfoty = ^siginfoty; + sigclientinfoty = record + infopo: psiginfoty; + end; + psigclientinfoty = ^sigclientinfoty; + + sigclientoptionty = (sco_tick,sco_fulltick); + sigclientoptionsty = set of sigclientoptionty; + + isigclient = interface(ievent) + procedure initmodel; + procedure clear; + function getinputar: inputconnarty; + function getoutputar: outputconnarty; + function gethandler: sighandlerprocty; + function getzcount: integer; + function getcomponent: tcomponent; + procedure modelchange; + function getsigcontroller: tsigcontroller; + function getsigclientinfopo: psigclientinfoty; + function getsigoptions: sigclientoptionsty; + {$ifdef FPC} + procedure sigtick; + {$else} + procedure sigtick(); + {$endif} + end; + sigclientintfarty = array of isigclient; + + tdoublesigcomp = class(tsigcomp,isigclient) + private + fsigclientinfo: sigclientinfoty; + procedure setcontroller(const avalue: tsigcontroller); + protected + fcontroller: tsigcontroller; + procedure modelchange; + procedure loaded; override; + procedure lock; + procedure unlock; + + //isigclient + procedure initmodel; virtual; + procedure sigtick; virtual; + function getinputar: inputconnarty; virtual; + function getoutputar: outputconnarty; virtual; + function gethandler: sighandlerprocty; virtual; abstract; + function getzcount: integer; virtual; + function getsigcontroller: tsigcontroller; + function getsigclientinfopo: psigclientinfoty; + function getsigoptions: sigclientoptionsty; virtual; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure clear; virtual; + procedure lockapplication; //releases controller lock, can not be nested, + //call from locked signal thread only + procedure unlockapplication;//acquires controller lock + published + property controller: tsigcontroller read fcontroller write setcontroller; + end; + + tsigconn = class(tmsecomponent) + //no solution found to link to streamed tpersistent or tobject, + //fork of classes.pp necessary. :-( + end; + + tdoubleconn = class(tsigconn) + protected + fsigintf: isigclient; + function getcontroller: tsigcontroller; + procedure lock; + procedure unlock; + public + constructor create(const aowner: tcomponent; + const asigintf: isigclient); reintroduce; virtual; + property controller: tsigcontroller read getcontroller; + end; + + valuescaleoptionty = (vso_exp,vso_null); //out:= 0 for inp <= 0 + valuescaleoptionsty = set of valuescaleoptionty; + doublescaleinfoty = record + value: double; + min: double; + max: double; + options: valuescaleoptionsty; + gain,offset: double; + end; + + doubleinputconnarty = array of tdoubleinputconn; + + outputconnstatety = (ocs_eventdriven); + outputconnstatesty = set of outputconnstatety; + + tdoubleoutputconn = class(tdoubleconn) + private + function geteventdriven: boolean; + procedure seteventdriven(const avalue: boolean); + protected + fstate: outputconnstatesty; + fdestinations: doubleinputconnarty; + fvalue: double; + property eventdriven: boolean read geteventdriven write seteventdriven; + public + constructor create(const aowner: tcomponent; + const asigintf: isigclient; const aeventdriven: boolean); + reintroduce; virtual; + property value: double read fvalue write fvalue; + end; + +// siginpoptionty = (sio_exp); +// siginpoptionsty = set of siginpoptionty; + + inpscaleinfoty = record + offset: double; + gain: double; + hasscale: boolean; + hasmin: boolean; + hasmax: boolean; + isexp: boolean; + end; + + sigvaluety = record + value: double; + changed: siginchangeflagsty; + end; + psigvaluety = ^sigvaluety; + sigvaluepoarty = array of psigvaluety; + + tdoubleinputconn = class(tdoubleconn) + private + fsource: tdoubleoutputconn; + foffset: double; + fgain: double; + fmin: realty; + fmax: realty; + fexpstart: realty; + fexpend: realty; +// foptions: siginpoptionsty; + procedure setsource(const avalue: tdoubleoutputconn); + procedure setoffset(const avalue: double); + procedure setgain(const avalue: double); + procedure setvalue(const avalue: double); virtual; + procedure setmin(const avalue: realty); + procedure setmax(const avalue: realty); + procedure setexpstart(const avalue: realty); + procedure setexpend(const avalue: realty); + protected + fsca: inpscaleinfoty; + fv: sigvaluety; + public + constructor create(const aowner: tcomponent; + const asigintf: isigclient); override; + destructor destroy; override; + published + property source: tdoubleoutputconn read fsource write setsource; + property offset: double read foffset write setoffset; + property gain: double read fgain write setgain; + property min: realty read fmin write setmin; + property max: realty read fmax write setmax; + property expstart: realty read fexpstart write setexpstart; + property expend: realty read fexpend write setexpend; + property value: double read fv.value write setvalue; +// property options: siginpoptionsty read foptions write setoptions; + end; + + tlimitinputconn = class(tdoubleinputconn) + public + constructor create(const aowner: tcomponent; + const asigintf: isigclient); override; + //deafault min = 0, default max = 1 + end; + + tchangedoubleinputconn = class(tdoubleinputconn) + private + fonchange: notifyeventty; + protected + procedure setvalue(const avalue: double); override; + public + constructor create(const aowner: tcomponent; const asigintf: isigclient; + const aonchange: notifyeventty); reintroduce; + end; + + sighandlerinfoty = record +// dest: pdouble; + discard: boolean; + end; + + siginfopoarty = array of psiginfoty; + signahdlerprocty = procedure(siginfo: psiginfoty); + + siginfostatety = (sis_checked,sis_eventchecked,sis_touched, + sis_input,sis_output, + sis_eventoutput,sis_eventinput,sis_fulltick,sis_sighandler); + siginfostatesty = set of siginfostatety; + + inputstatety = (ins_checked,ins_recursive); + inputstatesty = set of inputstatety; + + inputinfoty = record + input: tdoubleinputconn; + source: psiginfoty; + state: inputstatesty; + end; + inputinfoarty = array of inputinfoty; + + sigdestinfoty = record + outputindex: integer; + destinput: tdoubleinputconn; + end; + sigdestinfoarty = array of sigdestinfoty; + + siginfoty = record + intf: isigclient; + options: sigclientoptionsty; + handler: sighandlerprocty; + zcount: integer; + inputs: inputinfoarty; + outputs: outputconnarty; + destinations: sigdestinfoarty; + eventdestinations: siginfopoarty; + state: siginfostatesty; + prev: siginfopoarty; + connectedcount: integer; + next: siginfopoarty; + end; + siginfoarty = array of siginfoty; + + destinfoty = record + source: pdouble; + dest: pdouble; + min: double; + max: double; + sca: inpscaleinfoty; + end; + destinfoarty = array of destinfoty; + + sighandlernodeinfoty = record + handlerinfo: sighandlerinfoty; + handler: sighandlerprocty; +// firstdest: destinfoty; + dest: destinfoarty; + desthigh: integer; + end; + psighandlernodeinfoty = ^sighandlernodeinfoty; + sighandlernodeinfoarty = array of sighandlernodeinfoty; + + tsigconnection = class(tdoublesigcomp) + end; + + sigineventty = procedure(const sender: tobject; + var sig: real) of object; + siginbursteventty = procedure(const sender: tobject; + var sig: realarty) of object; + sigincomplexeventty = procedure(const sender: tobject; + var sig: complexty) of object; + sigincomplexbursteventty = procedure(const sender: tobject; + var sig: complexarty) of object; + + tsigin = class(tsigconnection) + private + foutput: tdoubleoutputconn; + foutputpo: pdouble; + fvalue: double; + finp: doublearty; + foninput: sigineventty; + foninputburst: siginbursteventty; + finpindex: integer; + procedure setvalue(const avalue: double); + protected + function getoutputar: outputconnarty; override; + //isigclient + procedure initmodel; override; + function gethandler: sighandlerprocty; override; + procedure sighandler(const ainfo: psighandlerinfoty); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure siginput(const asource: doublearty); + procedure clear; override; + property output: tdoubleoutputconn read foutput; + published + property value: double read fvalue write setvalue; + property oninput: sigineventty read foninput write foninput; + property oninputburst: siginbursteventty read foninputburst write foninputburst; + end; + + sigouteventty = procedure(const sender: tobject; + const sig: real) of object; + sigoutbursteventty = procedure(const sender: tobject; + const sig: realarty) of object; + + tsigout = class(tsigconnection) + private + finput: tdoubleinputconn; + finputpo: psigvaluety; + fonoutput: sigouteventty; + fvalue: double; + fonoutputburst: sigoutbursteventty; + foutp: doublearty; + foutpindex: integer; + fbuffersize: integer; + procedure setinput(const avalue: tdoubleinputconn); + function getinput: tdoubleinputconn; + procedure setbuffersize(const avalue: integer); + function getvalue: double; + protected + function getinputar: inputconnarty; override; + //isigclient + function gethandler: sighandlerprocty; override; + procedure sighandler(const ainfo: psighandlerinfoty); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure clear; override; + procedure sigoutput1(var adest: doublearty); //returns a data copy + function sigoutput: doublearty; + property value: double read getvalue; + published + property input: tdoubleinputconn read getinput write setinput; + property buffersize: integer read fbuffersize + write setbuffersize default 0; + property onoutput: sigouteventty read fonoutput write fonoutput; + property onoutputburst: sigoutbursteventty read fonoutputburst + write fonoutputburst; + end; + + trealcoeff = class(trealdatalist) + protected + fowner: tcustomsigcomp; + procedure doitemchange(const aindex: integer); override; + public + constructor create(const aowner: tcustomsigcomp); reintroduce; + end; + + tcomplexcoeff = class(tcomplexdatalist) + protected + fowner: tcustomsigcomp; + procedure doitemchange(const aindex: integer); override; + public + constructor create(const aowner: tcustomsigcomp); reintroduce; + end; + + tdoublezcomp = class(tdoublesigcomp) //single input, single output + private + procedure setinput(const avalue: tdoubleinputconn); + procedure setoutput(const avalue: tdoubleoutputconn); + protected + fzcount: integer; + fzhigh: integer; + fdoublez: doublearty; + fzindex: integer; + finputindex: integer; + fdoubleinputdata: doubleararty; + finput: tdoubleinputconn; + foutput: tdoubleoutputconn; + foutputpo: pdouble; + function getinputar: inputconnarty; override; + function getoutputar: outputconnarty; override; + procedure setzcount(const avalue: integer); + function getzcount: integer; override; + procedure zcountchanged; virtual; + procedure initmodel; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure clear; override; + property zcount: integer read getzcount default 0; + property output: tdoubleoutputconn read foutput write setoutput; + published + property input: tdoubleinputconn read finput write setinput; + end; + + tdoubleinpconnarrayprop = class(tpersistentarrayprop) + private + fsigintf: isigclient; + function getitems(const index: integer): tdoubleinputconn; + protected + procedure createitem(const index: integer; var item: tpersistent); override; + procedure dosizechanged; override; + public + constructor create(const asigintf: isigclient); reintroduce; + class function getitemclasstype: persistentclassty; override; + //used in dumpunitgroups + property items[const index: integer]: tdoubleinputconn read getitems; default; + end; + + tdoubleoutconnarrayprop = class(tpersistentarrayprop) + private + function getitems(const index: integer): tdoubleoutputconn; + protected + fsigintf: isigclient; + fname: string; + fowner: tcomponent; + feventdriven: boolean; + procedure createitem(const index: integer; var item: tpersistent); override; + procedure dosizechanged; override; + public + constructor create(const aowner: tcomponent; const aname: string; + const asigintf: isigclient; const aeventdriven: boolean); reintroduce; + class function getitemclasstype: persistentclassty; override; + //used in dumpunitgroups + property items[const index: integer]: tdoubleoutputconn read getitems; default; + end; + + tsigmultiinp = class(tdoublesigcomp) + private + finputs: tdoubleinpconnarrayprop; + procedure setinputs(const avalue: tdoubleinpconnarrayprop); + protected + finps: sigvaluepoarty; + finphigh: integer; + function getinputar: inputconnarty; override; + procedure initmodel; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property inputs: tdoubleinpconnarrayprop read finputs write setinputs; + end; + + tsigsampler = class; + samplerbufferty = array of doublearty; + samplerbufferfulleventty = procedure(const sender: tsigsampler; + const abuffer: samplerbufferty) of object; + + tsigsampler = class(tsigmultiinp) + private + fbufferlength: integer; + fbufpo: integer; + ftrigger: tchangedoubleinputconn; + ftriggerlevel: tchangedoubleinputconn; + fonbufferfull: samplerbufferfulleventty; + ftimer: tsimpletimer; + frefreshus: integer; + procedure setbufferlength(const avalue: integer); + procedure settrigger(const avalue: tchangedoubleinputconn); + procedure settriggerlevel(const avalue: tchangedoubleinputconn); + procedure setrefreshus(const avalue: integer); + protected + foptions: sigsampleroptionsty; + fnegtrig: boolean; + fstarted: boolean; + fstartpending: boolean; + fpretrigger: boolean; + frunning: boolean; + fsigbuffer: samplerbufferty; + procedure setoptions(const avalue: sigsampleroptionsty) virtual; + procedure updateoptions(var avalue: sigsampleroptionsty); virtual; + procedure dotimer(const sender: tobject); + procedure dotriggerchange(const sender: tobject); + procedure dobufferfull; virtual; + procedure loaded; override; + procedure checkautostart; + //isigclient + function getsigoptions: sigclientoptionsty; override; + function gethandler: sighandlerprocty; override; + procedure sighandler(const ainfo: psighandlerinfoty); + procedure initmodel; override; + function getinputar: inputconnarty; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure clear; override; + procedure start; + published + property bufferlength: integer read fbufferlength + write setbufferlength default defaultsamplecount; + property trigger: tchangedoubleinputconn read ftrigger write settrigger; + property triggerlevel: tchangedoubleinputconn read ftriggerlevel + write settriggerlevel; + property options: sigsampleroptionsty read foptions + write setoptions default defaultsigsampleroptions; + property onbufferfull: samplerbufferfulleventty read fonbufferfull + write fonbufferfull; + property refreshus: integer read frefreshus write setrefreshus default -1; + //micro seconds, -1 -> off, 0 -> on idle + end; + + tsigmultiinpout = class(tsigmultiinp) + private + //local variables +// dar: doublearty; +// pdar: doublepoarty; + procedure setoutput(const avalue: tdoubleoutputconn); + protected + foutput: tdoubleoutputconn; + foutputpo: pdouble; + function getoutputar: outputconnarty; override; + procedure initmodel; override; + public + constructor create(aowner: tcomponent); override; +// destructor destroy; override; + property output: tdoubleoutputconn read foutput write setoutput; + end; + + tsigadd = class(tsigmultiinpout) + protected +// procedure processinout(const acount: integer; +// var ainp: doublepoarty; var aoutp: pdouble); override; + //isigclient + function gethandler: sighandlerprocty; override; + procedure sighandler(const ainfo: psighandlerinfoty); + end; + + tsigdelay = class(tsigadd) + private + protected + fz: double; + function getzcount: integer; override; + //isigclient + function gethandler: sighandlerprocty; override; + procedure sighandler(const ainfo: psighandlerinfoty); + public + procedure clear; override; + end; + + tcustomsigdelay = class(tsigadd) + private + fdelay: integer; + finppo: integer; + procedure setdelay(const avalue: integer); + protected + fz: doublearty; + procedure initmodel; override; + function getzcount: integer; override; + //isigclient + function gethandler: sighandlerprocty; override; + procedure sighandler(const ainfo: psighandlerinfoty); + + property delay: integer read fdelay write setdelay default 1; + public + constructor create(aowner: tcomponent); override; + procedure clear; override; + end; + + tsigdelayn = class(tcustomsigdelay) + published + property delay; + end; + + tsigdelayvar = class(tcustomsigdelay) + private + fdelayinp: tdoubleinputconn; + fdelayinppo: pdouble; + function getdelaymax: integer; + procedure setdelaymax(const avalue: integer); + procedure setdelayinp(const avalue: tdoubleinputconn); + protected + function getinputar: inputconnarty; override; + procedure initmodel; override; + //isigclient + function gethandler: sighandlerprocty; override; + procedure sighandler(const ainfo: psighandlerinfoty); + public + constructor create(aowner: tcomponent); override; + published + property delaymax: integer read getdelaymax write setdelaymax default 1; + property delay: tdoubleinputconn read fdelayinp write setdelayinp; + end; + + tdoublesigoutcomp = class(tdoublesigcomp) + private + procedure setoutput(const avalue: tdoubleoutputconn); + procedure seteventdriven(const avalue: boolean); + protected + foutput: tdoubleoutputconn; + foutputpo: pdouble; + feventdriven: boolean; + function getoutputar: outputconnarty; override; + procedure initmodel; override; + property eventdriven: boolean read feventdriven write seteventdriven; + public + constructor create(aowner: tcomponent); override; + property output: tdoubleoutputconn read foutput write setoutput; + published + end; + + tdoublesiginoutcomp = class(tdoublesigoutcomp) + private + procedure setinput(const avalue: tdoubleinputconn); + protected + finput: tdoubleinputconn; + finputpo: psigvaluety; + function getinputar: inputconnarty; override; + public + constructor create(aowner: tcomponent); override; + published + property input: tdoubleinputconn read finput write setinput; + end; + + tsigconnector = class(tdoublesiginoutcomp) + protected + function gethandler: sighandlerprocty; override; + procedure sighandler(const ainfo: psighandlerinfoty); + end; + + ttrigconnector = class(tsigconnector) + public + constructor create(aowner: tcomponent); override; + end; + + tsigeventconnector = class(tdoublesigcomp) + end; + + sigwavetableoptionty = (siwto_intpol); + sigwavetableoptionsty = set of sigwavetableoptionty; + + tsigwavetable = class(tdoublesigoutcomp) + private + ffrequency: tdoubleinputconn; + ffrequfact: tdoubleinputconn; + fphase: tdoubleinputconn; + famplitude: tdoubleinputconn; + ftable: doublearty; + ftablelength: integer; + ftime: double; + ffrequencypo: psigvaluety; + ffrequfactpo: psigvaluety; + fphasepo: psigvaluety; + famplitudepo: psigvaluety; + foninittable: siginbursteventty; + foptions: sigwavetableoptionsty; + fmaster: tsigwavetable; + procedure setfrequency(const avalue: tdoubleinputconn); + procedure setfrequfact(const avalue: tdoubleinputconn); + procedure setphase(const avalue: tdoubleinputconn); + procedure setamplitude(const avalue: tdoubleinputconn); + procedure settable(const avalue: doublearty); + procedure setoptions(const avalue: sigwavetableoptionsty); + procedure setmaster(const avalue: tsigwavetable); + protected + procedure checktable; + procedure sighandler(const ainfo: psighandlerinfoty); + procedure sighandlerintpol(const ainfo: psighandlerinfoty); + procedure objectevent(const sender: tobject; const event: objecteventty); override; + //isigclient + function gethandler: sighandlerprocty; override; + procedure initmodel; override; + function getinputar: inputconnarty; override; + function getzcount: integer; override; + public + constructor create(aowner: tcomponent); override; + procedure clear; override; + property table: doublearty read ftable write settable; + published + property master: tsigwavetable read fmaster write setmaster; + property frequency: tdoubleinputconn read ffrequency write setfrequency; + property frequfact: tdoubleinputconn read ffrequfact write setfrequfact; + property phase: tdoubleinputconn read fphase write setphase; + property amplitude: tdoubleinputconn read famplitude write setamplitude; + property oninittable: siginbursteventty read foninittable write foninittable; + property options: sigwavetableoptionsty read foptions + write setoptions default []; + end; + + functionnodety = record + xend: double; + offs: double; + ramp: double; + end; + functionnodearty = array of functionnodety; + functionsegmentty = record + defaultnode: functionnodety; + nodes: functionnodearty; + end; + pfunctionsegmentty = ^functionsegmentty; + functionsegmentsty = array[0..functionsegmentcount-1] of functionsegmentty; + + tsigfuncttable = class(tsigmultiinpout) + private + famplitude: tdoubleinputconn; + foninittable: sigincomplexbursteventty; + ftable: complexarty; + fsegments: functionsegmentsty; + finpmin: double; + finpmax: double; + finpfact: double; //map input value to segmentindex + famplitudepo: psigvaluety; + fmaster: tsigfuncttable; + procedure setamplitude(const avalue: tdoubleinputconn); + procedure settable(const avalue: complexarty); + procedure setmaster(const avalue: tsigfuncttable); + protected + procedure checktable; + procedure sighandler(const ainfo: psighandlerinfoty); + procedure objectevent(const sender: tobject; const event: objecteventty); override; + //isigclient + function gethandler: sighandlerprocty; override; + procedure initmodel; override; + function getinputar: inputconnarty; override; + function getzcount: integer; override; + public + constructor create(aowner: tcomponent); override; + procedure clear; override; + property table: complexarty read ftable write settable; + //must be ordered by re values + published + property master: tsigfuncttable read fmaster write setmaster; + property amplitude: tdoubleinputconn read famplitude write setamplitude; + property oninittable: sigincomplexbursteventty read foninittable + write foninittable; + end; + + tsigmult = class(tsigmultiinpout) + protected +// procedure processinout(const acount: integer; +// var ainp: doublepoarty; var aoutp: pdouble); override; + //isigclient + function gethandler: sighandlerprocty; override; + procedure sighandler(const ainfo: psighandlerinfoty); + end; + + sigenveloperangeoptionty = (sero_exp,sero_mix); + sigenveloperangeoptionsty = set of sigenveloperangeoptionty; + + sigenvelopeoptionty = (seo_eventoutput,seo_negtrig,seo_nozero); + sigenvelopeoptionsty = set of sigenvelopeoptionty; + envproginfoty = record + startval: double; + ramp: double; + starttime: integer; + endtime: integer; + offset,scale: double; + isexp: boolean; + maxeventdelay: integer; + end; + envproginfoarty = array of envproginfoty; + + envelopeinfoty = record + floopstart: real; + floopstartindex: integer; + floopendindex: integer; + freleasestart: real; + fattack_values: complexarty; + attack_valuespo: pcomplexarty; + fdecay_values: complexarty; + decay_valuespo: pcomplexarty; + frelease_values: complexarty; + release_valuespo: pcomplexarty; + fprog: envproginfoarty; + findex: integer; + findexhigh: integer; + fdest: double; + + fcurrval: double; + fcurrvalbefore: double; + fcurrisexp: boolean; + fattackval: double; + fattackramp: double; + freleaseindex: integer; + freleaseval: double; + freleaseramp: double; + floopindex: integer; + floopval: double; + floopramp: double; + end; + + tsigenvelope = class(tdoublesigoutcomp) + private + ftrigger: tchangedoubleinputconn; + famplitudepo: psigvaluety; + fmixpo: psigvaluety; + + fhasmix: boolean; + ftime: integer; + foptions: sigenvelopeoptionsty; + ftimescale: real; +// fscale: real; +// foffset: real; + fmin: real; + fmax: real; + finfos: array [0..1] of envelopeinfoty; + feventthreshold: real; + + fattack_options: sigenveloperangeoptionsty; + fdecay_options: sigenveloperangeoptionsty; + frelease_options: sigenveloperangeoptionsty; + fmaster: tsigenvelope; + famplitude: tdoubleinputconn; + fmix: tlimitinputconn; + fattack_maxeventtime: real; + fdecay_maxeventtime: real; + frelease_maxeventtime: real; + function getattack_values(const index: integer): complexarty; + procedure setattack_values(const index: integer; const avalue: complexarty); + function getdecay_values(const index: integer): complexarty; + procedure setdecay_values(const index: integer; const avalue: complexarty); + function getrelease_values(const index: integer): complexarty; + procedure setrelease_values(const index: integer; const avalue: complexarty); + function getloopstart(const index: integer): real; + procedure setloopstart(const index: integer; const avalue: real); + + procedure settrigger(const avalue: tchangedoubleinputconn); + procedure setmin(const avalue: real); + procedure setmax(const avalue: real); + procedure setoptions(const avalue: sigenvelopeoptionsty); + procedure setattack_options(const avalue: sigenveloperangeoptionsty); + procedure setdecay_options(const avalue: sigenveloperangeoptionsty); + procedure setrelease_options(const avalue: sigenveloperangeoptionsty); + procedure setmaster(const avalue: tsigenvelope); + procedure setamplitude(const avalue: tdoubleinputconn); + procedure dosync; + procedure setmix(const avalue: tlimitinputconn); + procedure setsubsampling(avalue: integer); + protected + fattackpending: boolean; + freleasepending: boolean; + ffinished: boolean; + fsubsampling: integer; + fsamplecount: integer; + feventtime: integer; + fmaxeventdelay: integer; + procedure sighandler(const ainfo: psighandlerinfoty); + procedure updatevalues(var ainfo: envelopeinfoty); + procedure updatevalueindex(const aindex: integer); + procedure updatevaluesx; + + procedure objectevent(const sender: tobject; const event: objecteventty); override; + procedure initmodel; override; + function getinputar: inputconnarty; override; + function getzcount: integer; override; + function gethandler: sighandlerprocty; override; + procedure dotriggerchange(const sender: tobject); + procedure update; override; + procedure lintoexp(var avalue: double); + procedure exptolin(var avalue: double); + procedure checkindex(const index: integer); + function getsigoptions: sigclientoptionsty; override; + public + constructor create(aowner: tcomponent); override; + procedure start; + procedure stop; + property attack_values[const index: integer]: complexarty + read getattack_values write setattack_values; + property decay_values[const index: integer]: complexarty + read getdecay_values write setdecay_values; + property release_values[const index: integer]: complexarty + read getrelease_values write setrelease_values; + property loopstart[const index: integer]: real + read getloopstart write setloopstart; + //<0 -> inactive + published + property master: tsigenvelope read fmaster write setmaster; + property trigger: tchangedoubleinputconn read ftrigger write settrigger; + //1 -> start, -1 -> stop + property amplitude: tdoubleinputconn read famplitude write setamplitude; + property mix: tlimitinputconn read fmix write setmix; + property options: sigenvelopeoptionsty read foptions + write setoptions default []; + property timescale: real read ftimescale write ftimescale; //default 1s + property subsampling: integer read fsubsampling write setsubsampling + default defaultenvelopesubsampling; + property min: real read fmin write setmin; + property max: real read fmax write setmax; + property eventthreshold: real read feventthreshold write feventthreshold; + property attack_options: sigenveloperangeoptionsty read fattack_options + write setattack_options default []; + property attack_maxeventtime: real read fattack_maxeventtime + write fattack_maxeventtime; //default 0 + property decay_options: sigenveloperangeoptionsty read fdecay_options + write setdecay_options default [sero_exp]; + property decay_maxeventtime: real read fdecay_maxeventtime + write fdecay_maxeventtime; //default 0 + property release_options: sigenveloperangeoptionsty read frelease_options + write setrelease_options default [sero_exp]; + property release_maxeventtime: real read frelease_maxeventtime + write frelease_maxeventtime; //default 0 + end; + + sigcontrollerstatety = (scs_modelvalid,scs_hastick); + sigcontrollerstatesty = set of sigcontrollerstatety; + + tsiginfohash = class(tpointerptruinthashdatalist) + end; + + beforestepeventty = procedure(const sender: tsigcontroller; + var acount: integer; var handled: boolean) of object; + afterstepeventty = procedure(const sender: tsigcontroller; + const acount: integer) of object; + sigcontrolleroptionty = (sico_freerun,sico_autorun); + sigcontrolleroptionsty = set of sigcontrolleroptionty; + + tsigcontroller = class(tmsecomponent) + private + finphash: tsiginfohash; + foutphash: tsiginfohash; +// fvaluedummy: double; + fmutex: mutexty; + flockcount: integer; + flockapplocks: integer; + fticktime: integer; + ftickdiv: integer; + fonbeforetick: notifyeventty; + fonaftertick: notifyeventty; + fonbeforestep: beforestepeventty; + fonbeforeupdatemodel: notifyeventty; + fonafterupdatemodel: notifyeventty; + fonafterstep: afterstepeventty; + fsamplefrequ: real; + foptions: sigcontrolleroptionsty; + fstepcount: integer; + ftimer: tsimpletimer; + procedure settickdiv(const avalue: integer); + procedure setonbeforetick(const avalue: notifyeventty); + procedure setonaftertick(const avalue: notifyeventty); + procedure setoptions(const avalue: sigcontrolleroptionsty); + procedure setsamplefrequ(const avalue: real); + function getfreerun: boolean; + procedure setfreerun(const avalue: boolean); + function getautorun: boolean; + procedure setautorun(const avalue: boolean); + procedure setstepcount(const avalue: integer); + protected + fstate: sigcontrollerstatesty; + fclients: sigclientintfarty; + fticks: proceventarty; + finfos: siginfoarty; + finputnodes: siginfopoarty; +// foutputnodes: siginfopoarty; + fexecinfo: sighandlernodeinfoarty; + fexechigh: integer; + {$ifdef mse_debugsignal} + procedure debugnodeinfo(const atext: string; const anode: psiginfoty); + procedure debugpointer(const atext: string; const apointer: pointer); + {$endif} + procedure addclient(const aintf: isigclient); + procedure removeclient(const aintf: isigclient); + procedure updatemodel; + function findinplink(const dest,source: psiginfoty): integer; + procedure internalstep; + procedure loaded; override; + function findinp(const aconn: tsigconn): psiginfoty; + function findoutp(const aconn: tsigconn): psiginfoty; + procedure internalexecevent(const ainfopo: psiginfoty); + procedure dispatcheventoutput(const ainfopo: psiginfoty); + procedure execevent(const aintf: isigclient); //must be locked + procedure checktick; + procedure dotick; + function getnodenamepath(const aintf: isigclient): string; + procedure checkoptions(); + procedure stopautorun; + procedure doidle(var again: boolean); + procedure doautotick(const sender: tobject); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure lockapplication; //releases controller lock, can not be nested + //call from locked signal thread only + procedure unlockapplication;//acquires controller lock + procedure modelchange; + procedure checkmodel; + procedure step(acount: integer=1); + procedure clear; + procedure lock; + procedure unlock; + property freerun: boolean read getfreerun write setfreerun; + property autorun: boolean read getautorun write setautorun; + published + property options: sigcontrolleroptionsty read foptions + write setoptions default []; + property stepcount: integer read fstepcount + write setstepcount default defaultstepcount; + property samplefrequ: real read fsamplefrequ write setsamplefrequ; + //default 44100 + property tickdiv: integer read ftickdiv write settickdiv + default defaulttickdiv; + property onbeforetick: notifyeventty read fonbeforetick + write setonbeforetick; + property onaftertick: notifyeventty read fonaftertick + write setonaftertick; + property onbeforestep: beforestepeventty read fonbeforestep + write fonbeforestep; + property onafterstep: afterstepeventty read fonafterstep + write fonafterstep; + + property onbeforeupdatemodel: notifyeventty read fonbeforeupdatemodel + write fonbeforeupdatemodel; //application.locked + property onafterupdatemodel: notifyeventty read fonafterupdatemodel + write fonafterupdatemodel; //application.locked + end; + +procedure createsigbuffer(var abuffer: doublearty; const asize: integer); +procedure createsigarray(out abuffer: doublearty; const asize: integer); +procedure setsourceconn(const sender: tmsecomponent; + const avalue: tdoubleoutputconn; var dest: tdoubleoutputconn); +procedure setsigcontroller(const linker: tobjectlinker; + const intf: isigclient; + const source: tsigcontroller; var dest: tsigcontroller); +procedure initscale(const amin,amax: double; const aoptions: valuescaleoptionsty; + out ainfo: doublescaleinfoty); +procedure updatescale(var ainfo: doublescaleinfoty); +function scalevalue(const ainfo: doublescaleinfoty): double; + +implementation +uses + sysutils,mseformatstr,msesysutils,msesysintf1,mseapplication,msearrayutils, + msesys,msebits; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tmsecomponent1 = class(tmsecomponent); + +procedure initscale(const amin,amax: double; const aoptions: valuescaleoptionsty; + out ainfo: doublescaleinfoty); +begin + with ainfo do begin + min:= amin; + max:= amax; + options:= aoptions; + updatescale(ainfo); + end; +end; + +procedure updatescale(var ainfo: doublescaleinfoty); +begin + with ainfo do begin + if (vso_exp in options) and (min > 0) and (max > 0) then begin + offset:= ln(min); + gain:= ln(max)-ln(min); + end + else begin + offset:= min; + gain:= max-min; + end; + end; +end; + +function scalevalue(const ainfo: doublescaleinfoty): double; +begin + with ainfo do begin + if (vso_null in options) and (value <= 0) then begin + result:= 0; + end + else begin + result:= value*gain+offset; + if vso_exp in options then begin + result:= exp(result); + end; + end; + end; +end; + +procedure createsigbuffer(var abuffer: doublearty; const asize: integer); +begin + if (length(abuffer) < asize) or + (psizeint(pchar(pointer(abuffer))-2*sizeof(sizeint))^ > 1) then begin + abuffer:= nil; + allocuninitedarray(asize,sizeof(double),abuffer); + end + else begin + setlength(abuffer,asize); + end; +end; + +procedure createsigarray(out abuffer: doublearty; const asize: integer); +begin + abuffer:= nil; + allocuninitedarray(asize,sizeof(double),abuffer); +end; + +procedure setsourceconn(const sender: tmsecomponent; + const avalue: tdoubleoutputconn; var dest: tdoubleoutputconn); +begin + if dest <> nil then begin + if csdestroying in dest.componentstate then begin + dest.fdestinations:= nil; + end + else begin + removeitem(pointerarty(dest.fdestinations),sender); + end; + end; + tmsecomponent1(sender).setlinkedvar(avalue,tmsecomponent(dest)); + if dest <> nil then begin + additem(pointerarty(dest.fdestinations),sender); + end; +end; + +{ trealcoeff } + +constructor trealcoeff.create(const aowner: tcustomsigcomp); +begin + fowner:= aowner; + inherited create; +end; + +procedure trealcoeff.doitemchange(const aindex: integer); +begin + fowner.coeffchanged(self,aindex); + inherited; +end; + +{ tcomplexcoeff } + +constructor tcomplexcoeff.create(const aowner: tcustomsigcomp); +begin + fowner:= aowner; + inherited create; +end; + +procedure tcomplexcoeff.doitemchange(const aindex: integer); +begin + fowner.coeffchanged(self,aindex); + inherited; +end; + +{ tcustomsigcomp } + +procedure tcustomsigcomp.coeffchanged(const sender: tdatalist; + const aindex: integer); +begin + //dummy +end; + +procedure tcustomsigcomp.update; +begin + //dummy +end; + +procedure tcustomsigcomp.beginupdate; +begin + inc(fupdating); +end; + +procedure tcustomsigcomp.endupdate; +begin + dec(fupdating); + if fupdating = 0 then begin + update; + end; +end; + +{ tdoublconn } + +constructor tdoubleconn.create(const aowner: tcomponent; + const asigintf: isigclient); +begin + fsigintf:= asigintf; + inherited create(aowner); + setsubcomponent(true); +end; + +//{$ifndef FPC} +function tdoubleconn.getcontroller: tsigcontroller; +begin + result:= fsigintf.getsigcontroller; +end; + +procedure tdoubleconn.lock; +var + cont1: tsigcontroller; +begin + cont1:= fsigintf.getsigcontroller; + if cont1 <> nil then begin + cont1.lock; + end; +end; + +procedure tdoubleconn.unlock; +var + cont1: tsigcontroller; +begin + cont1:= fsigintf.getsigcontroller; + if cont1 <> nil then begin + cont1.unlock; + end; +end; +//{$endif} + +{ tdoubleoutputconn } + +constructor tdoubleoutputconn.create(const aowner: tcomponent; + const asigintf: isigclient; const aeventdriven: boolean); +begin + inherited create(aowner,asigintf); + if aeventdriven then begin + include(fstate,ocs_eventdriven); + end; + include (fmsecomponentstate,cs_subcompref); + name:= 'output'; +end; + +function tdoubleoutputconn.geteventdriven: boolean; +begin + result:= ocs_eventdriven in fstate; +end; + +procedure tdoubleoutputconn.seteventdriven(const avalue: boolean); +begin + if avalue then begin + include(fstate,ocs_eventdriven); + end + else begin + exclude(fstate,ocs_eventdriven); + end; +end; +{ +procedure tdoubleoutputconn.setsig1(var asource: doublearty); +var + int1: integer; +begin + int1:= high(fdestinations); + if int1 = 0 then begin + fdestinations[0].setsig1(asource); + end + else begin + for int1:= 0 to int1 do begin + fdestinations[int1].setsig(asource); + end; + end; +end; + +procedure tdoubleoutputconn.setsig(const asource: doublearty); +var + int1: integer; +begin + for int1:= 0 to high(fdestinations) do begin + fdestinations[int1].setsig(asource); + end; +end; +} +{ tdoubleinputconn } + +constructor tdoubleinputconn.create(const aowner: tcomponent; + const asigintf: isigclient); +begin + fgain:= 1; + fmin:= emptyreal; + fmax:= emptyreal; + fexpstart:= emptyreal; + fexpend:= emptyreal; + fv.changed:= siginchangeresetflags; + inherited; + name:= 'input'; +end; + +destructor tdoubleinputconn.destroy; +begin + source:= nil; + inherited; +end; + +procedure tdoubleinputconn.setsource(const avalue: tdoubleoutputconn); +begin + if fsource <> avalue then begin + setsourceconn(self,avalue,fsource); + fsigintf.modelchange; + end; +end; + +procedure tdoubleinputconn.setoffset(const avalue: double); +begin + lock; + foffset:= avalue; + unlock; +end; + +procedure tdoubleinputconn.setgain(const avalue: double); +begin + lock; + fgain:= avalue; + unlock; +end; + +procedure tdoubleinputconn.setvalue(const avalue: double); +begin + lock; + fv.value:= avalue; + include(fv.changed,sic_value); + unlock; +end; + +procedure tdoubleinputconn.setmin(const avalue: realty); +begin + lock; + fmin:= avalue; + unlock; +end; + +procedure tdoubleinputconn.setmax(const avalue: realty); +begin + lock; + fmax:= avalue; + unlock; +end; + +procedure tdoubleinputconn.setexpstart(const avalue: realty); +begin + lock; + fexpstart:= avalue; + unlock; +end; + +procedure tdoubleinputconn.setexpend(const avalue: realty); +begin + lock; + fexpend:= avalue; + unlock; +end; +{ +procedure tdoubleinputconn.setoptions(const avalue: siginpoptionsty); +begin + lock; + foptions:= avalue; + unlock; +end; +} +{ +procedure tdoubleinputconn.setsig1(var asource: doublearty); +begin + fowner.setsig1(self,asource); +end; + +procedure tdoubleinputconn.setsig(const asource: doublearty); +begin + fowner.setsig(self,asource); +end; +} +{ tdoublesigcomp } + +constructor tdoublesigcomp.create(aowner: tcomponent); +begin + inherited; +end; + +destructor tdoublesigcomp.destroy; +begin + controller:= nil; + clear; + inherited; +end; + +procedure tdoublesigcomp.clear; +begin + //dummy +end; +(* +procedure tdoublesigcomp.setsig1(const sender: tdoubleinputconn; + var asource: doublearty); +begin + //dummy +end; + +procedure tdoublesigcomp.setsig(const sender: tdoubleinputconn; + const asource: doublearty); +begin + //dummy +end; +*) +procedure setsigcontroller(const linker: tobjectlinker; + const intf: isigclient; + const source: tsigcontroller; var dest: tsigcontroller); +begin + if dest <> nil then begin + dest.removeclient(intf); + end; + linker.setlinkedvar(intf,source,tmsecomponent(dest)); + if dest <> nil then begin + dest.addclient(intf); + end; +end; + +procedure tdoublesigcomp.setcontroller(const avalue: tsigcontroller); +begin + setsigcontroller(getobjectlinker,isigclient(self),avalue,fcontroller); +end; + +procedure tdoublesigcomp.modelchange; +begin + if ([csdestroying,csloading]*componentstate = []) then begin + if (fcontroller <> nil) then begin + if ([csdestroying,csloading]*fcontroller.componentstate = []) then begin + fcontroller.lock; + fcontroller.modelchange; + fcontroller.unlock; + end; + end + end; +end; + +function tdoublesigcomp.getinputar: inputconnarty; +begin + result:= nil; +end; + +function tdoublesigcomp.getoutputar: outputconnarty; +begin + result:= nil; +end; + +procedure tdoublesigcomp.loaded; +begin + inherited; + modelchange; + update; +end; + +procedure tdoublesigcomp.initmodel; +begin + //dummy +end; + +function tdoublesigcomp.getzcount: integer; +begin + result:= 0; +end; + +function tdoublesigcomp.getsigcontroller: tsigcontroller; +begin + result:= fcontroller; +end; + +procedure tdoublesigcomp.lock; +begin + if fcontroller <> nil then begin + fcontroller.lock; + end; +end; + +procedure tdoublesigcomp.unlock; +begin + if fcontroller <> nil then begin + fcontroller.unlock; + end; +end; + +function tdoublesigcomp.getsigclientinfopo: psigclientinfoty; +begin + result:= @fsigclientinfo; +end; + +procedure tdoublesigcomp.sigtick; +begin + //dummy +end; + +function tdoublesigcomp.getsigoptions: sigclientoptionsty; +begin + result:= []; +end; + +procedure tdoublesigcomp.lockapplication; +begin + if fcontroller <> nil then begin + fcontroller.lockapplication; + end; +end; + +procedure tdoublesigcomp.unlockapplication; +begin + if fcontroller <> nil then begin + fcontroller.unlockapplication; + end; +end; + +{ tdoublezcomp } + +constructor tdoublezcomp.create(aowner: tcomponent); +begin + fzhigh:= -1; + finput:= tdoubleinputconn.create(self,isigclient(self)); + foutput:= tdoubleoutputconn.create(self,isigclient(self),false); + inherited; +end; + +destructor tdoublezcomp.destroy; +begin + inherited; +end; + +procedure tdoublezcomp.zcountchanged; +begin + //dummy +end; + +procedure tdoublezcomp.clear; +begin + inherited; + fdoubleinputdata:= nil; + finputindex:= 0; + fillchar(pointer(fdoublez)^,fzcount*sizeof(double),0); + fzindex:= 0; +end; +{ +procedure tdoublezcomp.setsig(const source: doublearty); +begin + if finputindex > high(fdoubleinputdata) then begin + setlength(fdoubleinputdata,finputindex+1); + end; + fdoubleinputdata[finputindex]:= source; + inc(finputindex); +end; + +procedure tdoublezcomp.updatesig(var inout: doublearty); +var + po1,po2: pdouble; +begin + po1:= pointer(inout); + po2:= po1; + processinout(length(inout),po1,po2); +end; + +procedure tdoublezcomp.getsig1(var dest: doublearty); +var + int1,int3: integer; + po1,po2: pdouble; +begin + int3:= 0; + for int1:= 0 to finputindex-1 do begin + int3:= int3 + high(fdoubleinputdata[int1]); + end; + int3:= int3 + finputindex; + createsigbuffer(dest,int3); + po2:= pointer(dest); + for int1:= 0 to finputindex-1 do begin + po1:= pointer(fdoubleinputdata[int1]); + processinout(length(fdoubleinputdata[int1]),po1,po2); + end; + for int1:= 0 to finputindex-1 do begin + fdoubleinputdata[int1]:= nil; + end; + finputindex:= 0; +end; + +function tdoublezcomp.getsig: doublearty; +begin + getsig1(result); +end; + +procedure tdoublezcomp.setsig1(const sender: tdoubleinputconn; + var asource: doublearty); +var + po1,po2: pdouble; +begin + po1:= pointer(asource); + po2:= po1; + processinout(length(asource),po1,po2); + foutput.setsig1(asource); +end; + +procedure tdoublezcomp.setsig(const sender: tdoubleinputconn; + const asource: doublearty); +var + int1: integer; + ar1: doublearty; + po1,po2: pdouble; +begin + int1:= length(asource); + createsigarray(ar1,int1); + po1:= pointer(asource); + po2:= pointer(ar1); + processinout(int1,po1,po2); + foutput.setsig1(ar1); +end; +} +procedure tdoublezcomp.setzcount(const avalue: integer); +begin + if fzcount <> avalue then begin + if avalue < 0 then begin + raise exception.create('Invalid coeffcount.'); + end; + clear; + fzcount:= avalue; + fzhigh:= avalue - 1; + setlength(fdoublez,avalue); + zcountchanged; + end; +end; + +procedure tdoublezcomp.setinput(const avalue: tdoubleinputconn); +begin + finput.assign(avalue); +end; + +procedure tdoublezcomp.setoutput(const avalue: tdoubleoutputconn); +begin + foutput.assign(avalue); +end; + +function tdoublezcomp.getinputar: inputconnarty; +begin + setlength(result,1); + result[0]:= finput; +end; + +function tdoublezcomp.getoutputar: outputconnarty; +begin + setlength(result,1); + result[0]:= foutput; +end; + +procedure tdoublezcomp.initmodel; +begin + inherited; + foutputpo:= @foutput.fvalue; +end; + +function tdoublezcomp.getzcount: integer; +begin + result:= fzcount; +end; + +{ tsigout } + +constructor tsigout.create(aowner: tcomponent); +begin + finput:= tdoubleinputconn.create(self,isigclient(self)); + finputpo:= @finput; + inherited; +end; + +destructor tsigout.destroy; +begin + inherited; +end; + +procedure tsigout.setinput(const avalue: tdoubleinputconn); +begin + finput.assign(avalue); +end; + +function tsigout.getinput: tdoubleinputconn; +begin + result:= finput; +end; +{ +procedure tsigout.setsig1(const sender: tdoubleinputconn; + var asource: doublearty); +begin + foutp:= asource; + if assigned(fonoutput) then begin + fonoutput(self,foutp); + end; +end; + +procedure tsigout.setsig(const sender: tdoubleinputconn; + const asource: doublearty); +begin + foutp:= asource; + if assigned(fonoutput) then begin + fonoutput(self,foutp); + end; +end; +} +function tsigout.getinputar: inputconnarty; +begin + setlength(result,1); + result[0]:= finput; +end; + +function tsigout.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}sighandler; +end; + +procedure tsigout.sighandler(const ainfo: psighandlerinfoty); +var + po1: psizeint; +begin + fvalue:= finputpo^.value; + if assigned(fonoutput) then begin + fonoutput(self,fvalue); + end; + if fbuffersize > 0 then begin + if foutpindex = fbuffersize then begin + foutpindex:= 0; + end; + po1:= psizeint(pchar(foutp)-2*sizeof(sizeint)); + if po1^ > 1 then begin //new buffer necessary + dec(po1^); //no thread safety + (* + {$ifdef CPU64} + interlockeddecrement64(po1^); + {$else} + interlockeddecrement(po1^); + {$endif} + if po1^ = 0 then begin + freemem(po1); + end; + *) + getmem(po1,fbuffersize * sizeof(double) + 2 * sizeof(sizeint)); + po1^:= 1; //refcount + inc(po1); + {$ifdef FPC} + po1^:= fbuffersize - 1; //high + {$else} + po1^:= fbuffersize; //count + {$endif} + inc(po1); + if foutpindex > 0 then begin + move(foutp[0],po1^,foutpindex*sizeof(double)); + end; + pointer(foutp):= po1; + end; + foutp[foutpindex]:= fvalue; + inc(foutpindex); + if foutpindex = fbuffersize then begin +// foutpindex:= 0; + if assigned(fonoutputburst) then begin + fonoutputburst(self,realarty(foutp)); + end; + end; + end; +end; + +procedure tsigout.sigoutput1(var adest: doublearty); +var + po1: psizeint; +begin + if foutpindex > 0 then begin + if adest = nil then begin + getmem(po1,foutpindex * sizeof(double) + 2 * sizeof(sizeint)); + po1^:= 1; //referencount; + inc(po1); + {$ifdef FPC} + po1^:= foutpindex-1; //high + {$else} + po1^:= foutpindex; //length + {$endif} + inc(po1); + pointer(adest):= po1; + end + else begin + po1:= psizeint(pchar(adest)-2*sizeof(sizeint)); + if po1^ = 1 then begin + {$ifdef FPC} + if psizeint(pchar(po1)+1*sizeof(sizeint))^ < foutpindex - 1 then begin + {$else} + if psizeint(pchar(po1)+1*sizeof(sizeint))^ < foutpindex then begin + {$endif} + freemem(po1); //new buffer + getmem(po1,foutpindex * sizeof(double) + 2 * sizeof(sizeint)); + po1^:= 1; //referencount; + inc(po1); + {$ifdef FPC} + po1^:= foutpindex-1; //high + {$else} + po1^:= foutpindex; //length + {$endif} + inc(po1); + pointer(adest):= po1; + end + else begin //reduce buffer + {$ifdef FPC} + if psizeint(pchar(po1)+1*sizeof(sizeint))^ > foutpindex - 1 then begin + {$else} + if psizeint(pchar(po1)+1*sizeof(sizeint))^ > foutpindex then begin + {$endif} + reallocmem(po1,foutpindex * sizeof(double) + 2 * sizeof(sizeint)); + pointer(adest):= pchar(po1)+2*sizeof(sizeint); + end; + end; + end + else begin + getmem(po1,foutpindex * sizeof(double) + 2 * sizeof(sizeint)); //new buffer + po1^:= 1; //referencount; + inc(po1); + {$ifdef FPC} + po1^:= foutpindex-1; //high + {$else} + po1^:= foutpindex; //length + {$endif} + inc(po1); + pointer(adest):= po1; + end; + end; + move(foutp[0],adest[0],foutpindex*sizeof(double)); + end + else begin + adest:= nil; + end; +end; + +function tsigout.sigoutput: doublearty; +begin + sigoutput1(result); +end; + +procedure tsigout.setbuffersize(const avalue: integer); +begin + if fbuffersize <> avalue then begin + fbuffersize:= avalue; + clear; + end; +end; + +procedure tsigout.clear; +begin + inherited; + setlength(foutp,fbuffersize); + foutpindex:= 0; +end; + +function tsigout.getvalue: double; +begin + lock; + result:= fvalue; + unlock; +end; + +{ tsigin } + +constructor tsigin.create(aowner: tcomponent); +begin + foutput:= tdoubleoutputconn.create(self,isigclient(self),false); + inherited; +end; + +destructor tsigin.destroy; +begin + inherited; +end; + +procedure tsigin.siginput(const asource: doublearty); +var + int1,int2,int3: integer; + po1: psizeint; +begin + int1:= length(finp); + if int1 = 0 then begin + finp:= asource; + end + else begin + int1:= int1 - finpindex; + if int1 > 0 then begin + setlength(finp,length(finp)); //unique reference + move(finp[finpindex],finp[0],int1*sizeof(double)); + end; + finpindex:= 0; + if asource <> finp then begin + int2:= length(asource); + int3:= int1+int2; + po1:= psizeint(pchar(finp)-2*sizeof(sizeint)); + if po1^ <> 1 then begin + dec(po1^); //no thread safety + getmem(po1,int3*sizeof(double)+2*sizeof(sizeint)); + po1^:= 1; + move(finp[0],(pchar(po1)+2*sizeof(sizeint))^,int1*sizeof(double)); + end + else begin + {$ifdef FPC} + if psizeint(pchar(po1)+sizeof(sizeint))^ <> int3-1 then begin + {$else} + if psizeint(pchar(po1)+sizeof(sizeint))^ <> int3 then begin + {$endif} + reallocmem(po1,int3*sizeof(double)+2*sizeof(sizeint)); + end; + end; + inc(po1); + {$ifdef FPC} + po1^:= int3-1; //high + {$else} + po1^:= int3; //length + {$endif} + inc(po1); + pointer(finp):= po1; + move(asource[0],finp[int1],int2*sizeof(double)); + end; + end; +// foutput.setsig(asource); +end; +{ +procedure tsigin.setsig1(var asource: doublearty); +begin + foutput.setsig1(asource); +end; +} +function tsigin.getoutputar: outputconnarty; +begin + setlength(result,1); + result[0]:= foutput; +end; + +function tsigin.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}sighandler; +end; + +procedure tsigin.sighandler(const ainfo: psighandlerinfoty); +begin + if finpindex <= high(finp) then begin + fvalue:= finp[finpindex]; + inc(finpindex); + end + else begin + if assigned(foninputburst) then begin + foninputburst(self,realarty(finp)); + finpindex:= 0; + if finp <> nil then begin + fvalue:= finp[0]; + inc(finpindex); + end; + end; + end; + if assigned(foninput) then begin + foninput(self,real(fvalue)); + end; + foutputpo^:= fvalue; +end; + +procedure tsigin.clear; +begin + inherited; + finp:= nil; + finpindex:= 0; +end; + +procedure tsigin.setvalue(const avalue: double); +begin + lock; + fvalue:= avalue; + unlock; +end; + +procedure tsigin.initmodel; +begin + inherited; + foutputpo:= @foutput.value; +end; + +{ tsigmultiinp } + +constructor tsigmultiinp.create(aowner: tcomponent); +begin +// foutput:= tdoubleoutputconn.create(self); + inherited; + finputs:= tdoubleinpconnarrayprop.create(self); +end; + +destructor tsigmultiinp.destroy; +begin + inherited; + finputs.free; +end; +(* +procedure tsigmultiinp.clear; +//var +// int1: integer; +begin + dar:= nil; + pdar:= nil; +// finpdatacount:= 0; + inherited; + { + for int1:= 0 to high(finputs.fitems) do begin + tdoubleinputconn(finputs.fitems[int1]).fbuffer:= nil; + end; + } +end; +*) + +procedure tsigmultiinp.setinputs(const avalue: tdoubleinpconnarrayprop); +begin + finputs.assign(avalue); +end; + +{ +procedure tsigmultiinp.setsig(const sender: tdoubleinputconn; + const asource: doublearty); +begin + dar:= copy(asource); + setsig1(sender,dar); +end; + +procedure tsigmultiinp.setsig1(const sender: tdoubleinputconn; + var asource: doublearty); +var + int1,int2,int3: integer; + po1: pdouble; +begin +//todo: optimize + stackarray(realarty(asource),realarty(sender.fbuffer)); + if not sender.fhasdata then begin + sender.fhasdata:= true; + inc(finpdatacount); + if finpdatacount >= finputs.count then begin + int2:= bigint; + setlength(pdar,finputs.count); + for int1:= 0 to high(finputs.fitems) do begin + with tdoubleinputconn(finputs.fitems[int1]) do begin + int3:= high(fbuffer); + if int3 < int2 then begin + int2:= int3; + end; + pdar[int1]:= pointer(fbuffer); + end; + end; + inc(int2); +// createsigbuffer(asource,int2); + po1:= pointer(asource); + processinout(int2,pdar,po1); + for int1:= 0 to high(finputs.fitems) do begin + with tdoubleinputconn(finputs.fitems[int1]) do begin + if length(fbuffer) <= int2 then begin + fbuffer:= nil; + fhasdata:= false; + dec(finpdatacount); + end + else begin + move(fbuffer[int2],fbuffer[0],(length(fbuffer)-int2)*sizeof(double)); + end; + end; + end; + foutput.setsig1(asource); + end; + end; +end; +} +function tsigmultiinp.getinputar: inputconnarty; +begin + result:= inputconnarty(finputs.fitems); +end; + +procedure tsigmultiinp.initmodel; +var + int1: integer; +begin + finphigh:= finputs.count-1; + setlength(finps,finphigh+1); + for int1:= 0 to finphigh do begin + finps[int1]:= @tdoubleinputconn(finputs.fitems[int1]).value; + end; +end; + +{ tsigmultiinpout } + +constructor tsigmultiinpout.create(aowner: tcomponent); +begin + foutput:= tdoubleoutputconn.create(self,isigclient(self),false); + inherited; +end; + +procedure tsigmultiinpout.setoutput(const avalue: tdoubleoutputconn); +begin + foutput.assign(avalue); +end; + +function tsigmultiinpout.getoutputar: outputconnarty; +begin + setlength(result,1); + result[0]:= foutput; +end; + +procedure tsigmultiinpout.initmodel; +begin + inherited; + foutputpo:= @foutput.value; +end; + +{ tdoublesigoutcomp } + +constructor tdoublesigoutcomp.create(aowner: tcomponent); +begin + foutput:= tdoubleoutputconn.create(self,isigclient(self),feventdriven); + inherited; +end; + +procedure tdoublesigoutcomp.setoutput(const avalue: tdoubleoutputconn); +begin + foutput.assign(avalue); +end; + +function tdoublesigoutcomp.getoutputar: outputconnarty; +begin + setlength(result,1); + result[0]:= foutput; +end; + +procedure tdoublesigoutcomp.initmodel; +begin + inherited; + foutputpo:= @foutput.value; +end; + +procedure tdoublesigoutcomp.seteventdriven(const avalue: boolean); +begin + if feventdriven <> avalue then begin + feventdriven:= avalue; + foutput.eventdriven:= avalue; + modelchange; + end; +end; + +{ tdoubleinpconnarrayprop } + +constructor tdoubleinpconnarrayprop.create(const asigintf: isigclient); +begin + fsigintf:= asigintf; + inherited create(nil); +end; + +procedure tdoubleinpconnarrayprop.createitem(const index: integer; + var item: tpersistent); +begin + item:= tdoubleinputconn.create(nil,fsigintf); +end; + +function tdoubleinpconnarrayprop.getitems(const index: integer): tdoubleinputconn; +begin + result:= tdoubleinputconn(inherited getitems(index)); +end; + +procedure tdoubleinpconnarrayprop.dosizechanged; +begin + inherited; + fsigintf.modelchange; +end; + +class function tdoubleinpconnarrayprop.getitemclasstype: persistentclassty; +begin + result:= tdoubleinputconn; +end; + +{ tdoubleoutconnarrayprop } + +constructor tdoubleoutconnarrayprop.create(const aowner: tcomponent; + const aname: string; const asigintf: isigclient; + const aeventdriven: boolean); +begin + fsigintf:= asigintf; + fowner:= aowner; + fname:= aname; + feventdriven:= aeventdriven; + inherited create(nil); +end; + +procedure tdoubleoutconnarrayprop.createitem(const index: integer; + var item: tpersistent); +begin + item:= tdoubleoutputconn.create(fowner,fsigintf,feventdriven); + tdoubleoutputconn(item).name:= fname+inttostr(index); +end; + +function tdoubleoutconnarrayprop.getitems( + const index: integer): tdoubleoutputconn; +begin + result:= tdoubleoutputconn(inherited getitems(index)); +end; + +procedure tdoubleoutconnarrayprop.dosizechanged; +begin + inherited; + fsigintf.modelchange; +end; + +class function tdoubleoutconnarrayprop.getitemclasstype: persistentclassty; +begin + result:= tdoubleoutputconn; +end; + +{ tsigadd } + +function tsigadd.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}sighandler; +end; + +procedure tsigadd.sighandler(const ainfo: psighandlerinfoty); +var + int1: integer; + do1: double; +begin + do1:= 0; + for int1:= 0 to finphigh do begin + do1:= do1 + finps[int1]^.value; + end; + foutputpo^:= do1; +end; + +{ tsigdelay } + +function tsigdelay.getzcount: integer; +begin + result:= 1; +end; + +function tsigdelay.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}sighandler; +end; + +procedure tsigdelay.sighandler(const ainfo: psighandlerinfoty); +var + int1: integer; + do1: double; +begin + foutputpo^:= fz; + do1:= 0; + for int1:= 0 to finphigh do begin + do1:= do1 + finps[int1]^.value; + end; + fz:= do1; +end; + +procedure tsigdelay.clear; +begin + fz:= 0; +end; + +{ tcustomsigdelay } + +constructor tcustomsigdelay.create(aowner: tcomponent); +begin + fdelay:= 1; + inherited; +end; + +procedure tcustomsigdelay.initmodel; +begin + inherited; + finppo:= 0; + setlength(fz,fdelay); +end; + +procedure tcustomsigdelay.clear; +begin + inherited; + fillchar(fz[0],sizeof(fz[0])*length(fz),0); +end; + +function tcustomsigdelay.getzcount: integer; +begin + result:= fdelay; +end; + +function tcustomsigdelay.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}sighandler; +end; + +procedure tcustomsigdelay.sighandler(const ainfo: psighandlerinfoty); +var + int1: integer; + po1: pdouble; + do1: double; +begin + if fdelay = 0 then begin + do1:= 0; + for int1:= 0 to finphigh do begin + do1:= do1 + finps[int1]^.value; + end; + foutputpo^:= do1; + end + else begin + do1:= 0; + for int1:= 0 to finphigh do begin + do1:= do1 + finps[int1]^.value; + end; + po1:= @fz[finppo]; + foutputpo^:= po1^; + po1^:= do1; + inc(finppo); + if finppo = fdelay then begin + finppo:= 0; + end; + end; +end; + +procedure tcustomsigdelay.setdelay(const avalue: integer); +begin + if fdelay <> avalue then begin + lock; + modelchange; + fdelay:= avalue; + unlock; + end; +end; + +{ tsigdelayvar } + +constructor tsigdelayvar.create(aowner: tcomponent); +begin + inherited; + fdelayinp:= tdoubleinputconn.create(self,isigclient(self)); +end; + +function tsigdelayvar.getdelaymax: integer; +begin + result:= inherited delay; +end; + +procedure tsigdelayvar.setdelaymax(const avalue: integer); +begin + inherited delay:= avalue; +end; + +procedure tsigdelayvar.setdelayinp(const avalue: tdoubleinputconn); +begin + fdelayinp.assign(avalue); +end; + +function tsigdelayvar.getinputar: inputconnarty; +begin + result:= inherited getinputar; + setlength(result,high(result)+2); + result[high(result)]:= fdelayinp; +end; + +function tsigdelayvar.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}sighandler; +end; + +procedure tsigdelayvar.sighandler(const ainfo: psighandlerinfoty); +var + int1,int2: integer; + po1: pdouble; + do1: double; +begin + if fdelay = 0 then begin + do1:= 0; + for int1:= 0 to finphigh do begin + do1:= do1 + finps[int1]^.value; + end; + foutputpo^:= do1; + end + else begin + po1:= @fz[finppo]; + po1^:= 0; + for int1:= 0 to finphigh do begin + po1^:= po1^ + finps[int1]^.value; + end; + do1:= fdelayinppo^; + if do1 < 0 then begin + do1:= 0; + end; + if do1 >= fdelay then begin + do1:= fdelay; + end; + int1:= finppo-trunc(do1); + if int1 < 0 then begin + int1:= int1 + fdelay; + end; + if int1 = 0 then begin + int2:= fdelay-1; + end + else begin + int2:= int1-1; + end; + do1:= frac(do1); + foutputpo^:= fz[int1]*(1-do1) + fz[int2]*do1; + inc(finppo); + if finppo = fdelay then begin + finppo:= 0; + end; + end; +end; + +procedure tsigdelayvar.initmodel; +begin + fdelayinppo:= @fdelayinp.value; + inherited; +end; + +{ tsigdelayvar } + +{ tsigmult } +{ +procedure tsigmult.processinout(const acount: integer; var ainp: doublepoarty; + var aoutp: pdouble); +var + int1,int2: integer; + rea1: real; +begin + for int1:= 0 to acount - 1 do begin + rea1:= 1; + for int2:= 0 to high(ainp) do begin + rea1:= rea1 * ainp[int2]^; + inc(ainp[int2]); + end; + aoutp^:= rea1; + inc(aoutp); + end; +end; +} +function tsigmult.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}sighandler; +end; + +procedure tsigmult.sighandler(const ainfo: psighandlerinfoty); +var + int1: integer; + do1: double; +begin + do1:= 1; + for int1:= 0 to finphigh do begin + do1:= do1 * finps[int1]^.value; + end; + foutputpo^:= do1; +end; + +{ tsigcontroller } + +constructor tsigcontroller.create(aowner: tcomponent); +begin + fsamplefrequ:= defaultsamplefrequ; + fstepcount:= defaultstepcount; + ftickdiv:= defaulttickdiv; + syserror(sys_mutexcreate(fmutex),self); + finphash:= tsiginfohash.create; + foutphash:= tsiginfohash.create; + inherited; +end; + +destructor tsigcontroller.destroy; +begin + stopautorun(); + inherited; + finphash.free; + foutphash.free; + sys_mutexdestroy(fmutex); +end; + +procedure tsigcontroller.addclient(const aintf: isigclient); +begin + lock; + adduniqueitem(pointerarty(fclients),pointer(aintf)); + modelchange; + unlock; +end; + +procedure tsigcontroller.removeclient(const aintf: isigclient); +begin + lock; + removeitem(pointerarty(fclients),pointer(aintf)); + modelchange; + unlock; +end; + +procedure tsigcontroller.modelchange; +begin + exclude(fstate,scs_modelvalid); +end; + +function tsigcontroller.findinp(const aconn: tsigconn): psiginfoty; +begin + result:= finphash.find(ptruint(aconn)); +end; + +function tsigcontroller.findoutp(const aconn: tsigconn): psiginfoty; +begin + result:= foutphash.find(ptruint(aconn)); +end; + + {$ifdef mse_debugsignal} +procedure tsigcontroller.debugnodeinfo(const atext: string; + const anode: psiginfoty); +var + str1: string; +begin + if anode = nil then begin + str1:= ''; + end + else begin + str1:= getnodenamepath(anode^.intf) + + ' conncount: '+inttostr(anode^.connectedcount); + end; + debugwriteln(atext+str1); +end; + +procedure tsigcontroller.debugpointer(const atext: string; + const apointer: pointer); +begin + debugwriteln(atext+hextostr(apointer)); +end; +{$endif} + +function tsigcontroller.findinplink(const dest,source: psiginfoty): integer; +var + int1: integer; +begin + result:= -1; + for int1:= 0 to high(dest^.inputs) do begin + if dest^.inputs[int1].source = source then begin + result:= int1; + break; + end; + end; +end; +//{$checkpointer on} + +procedure tsigcontroller.updatemodel; +{$ifdef mse_debugsignal} +var + indent: string; +{$endif} + + procedure resetchecked; + var + int1,int2: integer; + begin + for int1:= 0 to high(finfos) do begin + with finfos[int1] do begin + exclude(state,sis_checked); + for int2:= 0 to high(inputs) do begin + exclude(inputs[int2].state,ins_checked); + end; + end; + end; + end; //resetchecked + +var + visited: pointerarty; + + procedure checkrecursion(const anode: psiginfoty); + var + int1,int2: integer; + po1: psiginfoty; + visitedbefore: pointerarty; + {$ifdef mse_debugsignal} + indentbefore: string; + {$endif} + begin + {$ifdef mse_debugsignal} + indentbefore:= indent; + indent:= indent+' '; + debugnodeinfo(indent+'node ',anode); + {$endif} + additem(visited,anode); + visitedbefore:= visited; + with anode^ do begin + for int1:= 0 to high(destinations) do begin + visited:= visitedbefore; + po1:= findinp(destinations[int1].destinput); + int2:= findinplink(po1,anode); + if finditem(visited,po1) >= 0 then begin + if zcount = 0 then begin + raise exception.create('No Z-delay in recursion node '+ + getnodenamepath(intf)+ + ' -> '+getnodenamepath(po1^.intf)+'.'); + end + else begin + include(po1^.inputs[int2].state,ins_recursive); + dec(po1^.connectedcount); + end; + end + else begin + include(po1^.inputs[int2].state,ins_checked); + checkrecursion(po1); + end; + end; + end; + visited:= visitedbefore; + {$ifdef mse_debugsignal} + indent:= indentbefore; + {$endif} + end; //checkrecursion + +var + execorder: siginfopoarty; + execindex: integer; + + procedure processcalcorder(const anode: psiginfoty); + var + int1: integer; + po1: psiginfoty; + {$ifdef mse_debugsignal} + indentbefore: string; + {$endif} + begin + {$ifdef mse_debugsignal} + indentbefore:= indent; + indent:= indent+' '; + debugnodeinfo(inttostr(execindex)+indent+'calcnode ',anode); + {$endif} + if execindex > high(execorder) then begin + internalerror('SIG20100916-0'); + end; + execorder[execindex]:= anode; + inc(execindex); + with anode^ do begin + state:= state + [sis_checked,sis_sighandler]; + for int1:= 0 to high(next) do begin + po1:= next[int1]; + {$ifdef mse_debugsignal} + debugnodeinfo(indent+' dest '+booltostr(sis_checked in po1^.state)+' ',po1); + {$endif} + if not (sis_checked in po1^.state) then begin + if not (ins_recursive in po1^.inputs[findinplink(po1,anode)].state) then begin + dec(po1^.connectedcount); + if po1^.connectedcount <= 0 then begin + processcalcorder(po1); + end; + end; + end; + end; + end; + {$ifdef mse_debugsignal} + indent:= indentbefore; + {$endif} + end; //processcalcorder() + + procedure updatesca(const ainput: tdoubleinputconn; var sca: inpscaleinfoty); + var + a,b: double; + begin + sca.offset:= ainput.offset; + sca.gain:= ainput.gain; + sca.hasmin:= not (ainput.min = emptyreal); + sca.hasmax:= not (ainput.max = emptyreal); + sca.isexp:= (ainput.expstart > 0) and (ainput.expend > 0) and + (ainput.expend > ainput.expstart); + if sca.isexp then begin + b:= ln(ainput.expstart); + a:= ln(ainput.expend) - b; + sca.offset:= b+a*sca.offset; + sca.gain:= a*sca.gain; + end; + sca.hasscale:= sca.hasmin or sca.hasmax or sca.isexp or + (sca.offset <> 0) or (sca.gain <> 1); + end; //updatesca() + + procedure initinput(const ainput: tdoubleinputconn); + begin + with ainput do begin + updatesca(ainput,fsca); + fv.changed:= [sic_value]; + end; + end; //initinput() + + procedure updatedestinfo(const ainput: tdoubleinputconn; + const asource: pdouble; var ainfo: destinfoty); + begin + with ainfo do begin + source:= asource; + dest:= @ainput.fv.value; + min:= ainput.min; + max:= ainput.max; + sca:= ainput.fsca; +// updatesca(ainput,sca); + end; + end; //updatedestinfo + + function isopeninput(const ainputs: inputinfoarty): boolean; + var + int1: integer; + begin + result:= true; + for int1:= 0 to high(ainputs) do begin + with ainputs[int1] do begin + if (source <> nil) then begin + result:= false; + break; + end; + end; + end; + end; + + procedure touchnode(const anode: psiginfoty); + var + int1: integer; + begin + with anode^ do begin + include(state,sis_touched); + for int1:= 0 to high(next) do begin + if not (sis_touched in next[int1]^.state) then begin + touchnode(next[int1]); + end; + end; + end; + end; + + function isopenoutput(const aoutputs: outputconnarty): boolean; + var + int1: integer; + begin + result:= true; + for int1:= 0 to high(aoutputs) do begin + with aoutputs[int1] do begin + if not (ocs_eventdriven in fstate) and (fdestinations <> nil) then begin + result:= false; + break; + end; + end; + end; + end; + +var + int1,int2,int3,int4: integer; + po1,po2: psiginfoty; + inputnodecount: integer; + notconnectedcount: integer; +// fulltickcount: integer; +// outputnodecount: integer; +// recursivenodecount: integer; +// ar1,ar2: siginfopoarty; + ar3: inputconnarty; +begin + if assigned(fonbeforeupdatemodel) then begin + application.lock; + try + fonbeforeupdatemodel(self); + finally + application.unlock; + end; + end; + finfos:= nil; + finphash.clear; + foutphash.clear; + fticks:= nil; + finputnodes:= nil; +// foutputnodes:= nil; + fexecinfo:= nil; +// outputnodecount:= 0; + inputnodecount:= 0; + notconnectedcount:= 0; +// fulltickcount:= 0; + setlength(finfos,length(fclients)); +{$ifdef mse_debugsignal} + debugwriteln('**updatemodel '+name); + debugwriteln('*get info'); +{$endif} + + for int1:= 0 to high(fclients) do begin //get basic info + po1:= @finfos[int1]; + po1^.options:= fclients[int1].getsigoptions; + if sco_tick in po1^.options then begin + setlength(fticks,high(fticks)+2); + {$ifdef FPC} + fticks[high(fticks)]:= @fclients[int1].sigtick; + {$else} + fticks[high(fticks)]:= nil;//fclients[int1].sigtick; //todo:!!! + {$endif} + end; + fclients[int1].getsigclientinfopo^.infopo:= po1; + with po1^ do begin + intf:= fclients[int1]; + handler:= intf.gethandler; + intf.initmodel; + intf.clear; + zcount:= intf.getzcount; + {$ifdef mse_debugsignal} + debugwriteln('client '+getnodenamepath(intf)); + {$endif} + ar3:= fclients[int1].getinputar; + setlength(inputs,length(ar3)); + for int2:= 0 to high(ar3) do begin + inputs[int2].input:= ar3[int2]; + end; + outputs:= fclients[int1].getoutputar; + destinations:= nil; + for int2:= 0 to high(inputs) do begin + {$ifdef mse_debugsignal} + debugpointer(' inp ',inputs[int2].input); + {$endif} + finphash.add(ptruint(inputs[int2].input),po1); + initinput(inputs[int2].input); + end; + for int2:= 0 to high(outputs) do begin + {$ifdef mse_debugsignal} + debugpointer(' outp ',outputs[int2]); + {$endif} + foutphash.add(ptruint(outputs[int2]),po1); + with outputs[int2] do begin + if ocs_eventdriven in fstate then begin + include(po1^.state,sis_eventoutput); + end; + int3:= length(po1^.destinations); + setlength(po1^.destinations,int3+length(fdestinations)); + for int4:= 0 to high(fdestinations) do begin + with po1^.destinations[int3+int4] do begin + outputindex:= int2; + destinput:= fdestinations[int4]; + end; + end; +// stackarray(pointerarty(fdestinations),pointerarty(po1^.destinations)); + {$ifdef mse_debugsignal} + for int3:= 0 to high(fdestinations) do begin + debugpointer(' dest ',fdestinations[int3]); + end; + {$endif} + end; + end; + end; + end; + +{$ifdef mse_debugsignal} + debugwriteln('*link items'); +{$endif} + for int1:= 0 to high(fclients) do begin //link the items + po1:= @finfos[int1]; + with po1^ do begin + if not (sis_checked in state) then begin + {$ifdef mse_debugsignal} + debugnodeinfo('node ',po1); + {$endif} + include(state,sis_checked); + for int2:= 0 to high(outputs) do begin + with outputs[int2] do begin + for int3:= 0 to high(fdestinations) do begin + {$ifdef mse_debugsignal} + debugpointer('lookup inp ',fdestinations[int3]); + {$endif} + po2:= findinp(fdestinations[int3]); + {$ifdef mse_debugsignal} + debugnodeinfo(' ',po2); + {$endif} + if po2 = nil then begin + raise exception.create( + 'Destination not found. Controller: '+self.name+ ', Node: '+ + getnodenamepath(fclients[int1]) + + ', Dest: '+fdestinations[int3].fsigintf.getcomponent.name+'.'); + end; + if not (ocs_eventdriven in fstate) then begin + if finditem(pointerarty(po2^.prev),po1) < 0 then begin + inc(po2^.connectedcount); + {$ifdef mse_debugsignal} + debugnodeinfo(' new link ',po2); + {$endif} + additem(pointerarty(po2^.prev),po1); + additem(pointerarty(po1^.next),po2); + end; + for int4:= 0 to high(po2^.inputs) do begin + if po2^.inputs[int4].input = fdestinations[int3] then begin + with po2^.inputs[int4] do begin + source:= po1; + include(input.fv.changed,sic_stream); + end; + break; + end; + end; + end; + end; + end; + end; + end; + end; + end; + +{$ifdef mse_debugsignal} + debugwriteln('*check input/output'); +{$endif} + for int1:= 0 to high(fclients) do begin + po1:= @finfos[int1]; + with po1^ do begin +// state:= []; + if not isopenoutput(outputs) then begin + include(state,sis_output); + end + else begin + {$ifdef mse_debugsignal} + debugnodeinfo(' output node ',po1); + {$endif} + end; + if not isopeninput(inputs) then begin + include(state,sis_input); + end + else begin + if sis_output in state then begin + additem(pointerarty(finputnodes),po1,inputnodecount); + touchnode(po1); + {$ifdef mse_debugsignal} + debugnodeinfo(' input node ',po1); + {$endif} + end + else begin + inc(notconnectedcount); + {$ifdef mse_debugsignal} + debugnodeinfo(' not connected node ',po1); + {$endif} + end; + end; + end; + end; + +{$ifdef mse_debugsignal} + debugwriteln('*check event connections'); +{$endif} + for int1:= 0 to high(finfos) do begin + with finfos[int1] do begin + if not (sis_eventchecked in state) then begin + for int2:= 0 to high(outputs) do begin + with outputs[int2] do begin + for int3:= 0 to high(fdestinations) do begin + po2:= findinp(fdestinations[int3]); + if not (sis_input in po2^.state) then begin + {$ifdef mse_debugsignal} + debugnodeinfo('event source ',@finfos[int1]); + debugpointer(' lookup inp ',fdestinations[int3]); + debugnodeinfo(' event ',po2); + {$endif} + if sis_eventchecked in po2^.state then begin + raise exception.create( + 'Recursive event connection: '+self.name+ ', Node: '+ + getnodenamepath(finfos[int1].intf) + + ', Dest: '+getnodenamepath(po2^.intf)+'.'); + end; + adduniqueitem(pointerarty(eventdestinations),po2); + include(po2^.state,sis_eventinput); + include(state,sis_eventchecked); + end; + end; + end; + end; + end; + end; + end; + +{$ifdef mse_debugsignal} + debugwriteln('*check recursive without inputs'); +{$endif} + for int1:= 0 to high(fclients) do begin + po1:= @finfos[int1]; + with po1^ do begin + if state * [sis_input,sis_output,sis_touched,sis_eventchecked] = [sis_output] then begin + additem(pointerarty(finputnodes),po1,inputnodecount); + {$ifdef mse_debugsignal} + debugnodeinfo(' recursive circle start ',po1); + {$endif} + touchnode(po1); + end + else begin + if (state * [sis_input,sis_output,sis_touched] = []) and + (sco_fulltick in options) then begin + include(state,sis_fulltick); + additem(pointerarty(finputnodes),po1,inputnodecount); + dec(notconnectedcount); + {$ifdef mse_debugsignal} + debugnodeinfo(' fulltick ',po1); + {$endif} + touchnode(po1); + end; + end; + end; + end; + + setlength(finputnodes,inputnodecount); + +{$ifdef mse_debugsignal} + debugwriteln('*check recursion'); +{$endif} + + for int1:= 0 to high(finputnodes) do begin //check recursion + {$ifdef mse_debugsignal} + debugnodeinfo('input ',finputnodes[int1]); + {$endif} + if not (sis_fulltick in finputnodes[int1]^.state) then begin + visited:= nil; + checkrecursion(finputnodes[int1]); + end; + end; + +{$ifdef mse_debugsignal} + debugwriteln('*processcalcorder'); +{$endif} + setlength(execorder,length(finfos)); + execindex:= 0; +// resetchecked; + for int1:= 0 to high(finputnodes) do begin + {$ifdef mse_debugsignal} + debugnodeinfo('input ',finputnodes[int1]); + {$endif} + resetchecked; + processcalcorder(finputnodes[int1]); + end; + +{$ifdef mse_debugsignal} + debugwriteln('*execorder '+inttostr(length(execorder))+' '+inttostr(execindex)); + for int1:= 0 to high(execorder) do begin + debugnodeinfo(' ',execorder[int1]); + end; + for int1:= 0 to high(finfos) do begin + po1:= @finfos[int1]; + with po1^ do begin + if connectedcount <> 0 then begin + debugnodeinfo('! '+inttostr(connectedcount)+ ' ',po1); + end; + end; + end; +{$endif} + if execindex+notconnectedcount <> length(execorder) then begin + internalerror('SIG20100916-2'); //unprocessed nodes + end; + setlength(fexecinfo,execindex); + fexechigh:= execindex-1; + for int1:= 0 to high(fexecinfo) do begin + po1:= execorder[int1]; + with fexecinfo[int1] do begin + handler:= po1^.handler; + desthigh:= high(po1^.destinations); +// handlerinfo.dest:= @fvaluedummy; + if length(po1^.destinations) > 0 then begin + setlength(dest,desthigh+1); + for int2:= 0 to desthigh do begin + int3:= po1^.destinations[int2].outputindex; + updatedestinfo(po1^.destinations[int2].destinput, + @po1^.outputs[int3].fvalue,dest[int2]); + end; + end; + (* + handler:= po1^.handler; + desthigh:= high(po1^.destinations)-1; + handlerinfo.dest:= @fvaluedummy; + if length(po1^.destinations) > 0 then begin + int3:= po1^.destinations[0].outputindex; + updatedestinfo(po1^.destinations[0].destinput,handlerinfo.dest,firstdest); + //setup hasscale + if (int3 = 0) and (desthigh < 0) or not firstdest.sca.hasscale then begin + handlerinfo.dest:= @po1^.destinations[0].destinput.fv.value; + end; + if int3 = 0 then begin //setup again with correct dest + updatedestinfo(po1^.destinations[0].destinput,handlerinfo.dest,firstdest); + end + else begin + updatedestinfo(po1^.destinations[0].destinput, + @po1^.outputs[int3].fvalue,firstdest); + end; + + setlength(dest,desthigh+1); + for int2:= 0 to desthigh do begin + int3:= po1^.destinations[int2+1].outputindex; + if int3 > 0 then begin //additional output + updatedestinfo(po1^.destinations[int2+1].destinput, + @po1^.outputs[int3].fvalue,dest[int2]); + end + else begin + updatedestinfo(po1^.destinations[int2+1].destinput,handlerinfo.dest, + dest[int2]); + end; + end; + end; + *) + end; + end; + include(fstate,scs_modelvalid); + clear; + checktick; +{$ifdef mse_debugsignal} + debugwriteln('*execute event start nodes'); +{$endif} + po1:= pointer(finfos); + for int1:= 0 to high(finfos) do begin + if (po1^.state * [sis_eventoutput,sis_eventinput] = [sis_eventoutput]) and + not (sco_fulltick in po1^.options) then begin + {$ifdef mse_debugsignal} + debugnodeinfo(' exec ',po1); + {$endif} + internalexecevent(po1); + end; + inc(po1); + end; + if assigned(fonafterupdatemodel) then begin + application.lock; + try + fonafterupdatemodel(self); + finally + application.unlock; + end; + end; +end; + +//{$checkpointer default} +procedure tsigcontroller.internalstep; +var + int1,int2: integer; + po1: psighandlernodeinfoty; +begin + po1:= pointer(fexecinfo); + for int1:= 0 to fexechigh do begin + po1^.handler(psighandlerinfoty(po1)); + if not po1^.handlerinfo.discard then begin + { + with po1^.firstdest do begin + if sca.hasscale then begin + dest^:= source^*sca.gain+sca.offset; + if sca.isexp then begin + dest^:= exp(dest^); + end; + if sca.hasmin and (dest^ < min) then begin + dest^:= min; + end; + if sca.hasmax and (dest^ > max) then begin + dest^:= max; + end; + end; + end; + } + for int2:= 0 to po1^.desthigh do begin + with po1^.dest[int2] do begin + dest^:= source^; + if sca.hasscale then begin + dest^:= dest^*sca.gain+sca.offset; + if sca.isexp then begin + dest^:= exp(dest^); + end; + if sca.hasmin and (dest^ < min) then begin + dest^:= min; + end; + if sca.hasmax and (dest^ > max) then begin + dest^:= max; + end; + end; + end; + end; + end; + inc(po1); + end; +end; + +procedure tsigcontroller.step(acount: integer); +var + int1: integer; + bo1: boolean; +begin + if not (scs_modelvalid in fstate) then begin + updatemodel; + end; + bo1:= false; + if assigned(fonbeforestep) then begin + fonbeforestep(self,acount,bo1); + end; + if not bo1 then begin + if scs_hastick in fstate then begin + fticktime:= fticktime + acount; + while fticktime > 0 do begin + dotick; + dec(fticktime,ftickdiv); + end; + end; + lock; + try + for int1:= acount-1 downto 0 do begin + internalstep; + end; + finally + unlock; + end; + if assigned(fonafterstep) then begin + fonafterstep(self,acount); + end; + end; +end; + +procedure tsigcontroller.checkmodel; +begin + if not (scs_modelvalid in fstate) then begin + updatemodel; + end; +end; + +procedure tsigcontroller.loaded; +begin + inherited; + modelchange(); + checkoptions(); +end; + +procedure tsigcontroller.clear; +var + int1: integer; +begin + for int1:= 0 to high(fclients) do begin + fclients[int1].clear; + end; +end; + +procedure tsigcontroller.lock; +begin + sys_mutexlock(fmutex); + inc(flockcount); +end; + +procedure tsigcontroller.unlock; +begin + dec(flockcount); + sys_mutexunlock(fmutex); +end; + +procedure tsigcontroller.internalexecevent(const ainfopo: psiginfoty); +var +// po1: psiginfoty; + handlerinfo: sighandlerinfoty; +// do1: double; + int1: integer; +begin + with ainfopo^ do begin + if not (sis_sighandler in state) then begin +// handlerinfo.dest:= @do1; + handler(@handlerinfo); + for int1:= 0 to high(destinations) do begin + with destinations[int1] do begin + with destinput do begin + include(fv.changed,sic_value); + fv.value:= outputs[outputindex].fvalue*fsca.gain+fsca.offset; + if fsca.isexp then begin + fv.value:= exp(fv.value); + end; + if fsca.hasmin and (fv.value < min) then begin + fv.value:= min; + end; + if fsca.hasmax and (fv.value > max) then begin + fv.value:= max; + end; + end; + end; + end; + for int1:= 0 to high(eventdestinations) do begin + internalexecevent(eventdestinations[int1]); + end; + end; + end; +end; + +procedure tsigcontroller.dispatcheventoutput(const ainfopo: psiginfoty); +var +// po1: psiginfoty; +// handlerinfo: sighandlerinfoty; + int1: integer; +begin + with ainfopo^ do begin + for int1:= 0 to high(destinations) do begin + with destinations[int1] do begin + with destinput do begin + include(fv.changed,sic_value); + fv.value:= outputs[outputindex].fvalue*fsca.gain+fsca.offset; + if fsca.isexp then begin + fv.value:= exp(fv.value); + end; + if fsca.hasmin and (fv.value < min) then begin + fv.value:= min; + end; + if fsca.hasmax and (fv.value > max) then begin + fv.value:= max; + end; + end; + end; + end; + for int1:= 0 to high(eventdestinations) do begin + internalexecevent(eventdestinations[int1]); + end; + end; +end; + +procedure tsigcontroller.execevent(const aintf: isigclient); +begin +// lock; + checkmodel; +// try + internalexecevent(aintf.getsigclientinfopo^.infopo); +// finally +// unlock; +// end; +end; + +procedure tsigcontroller.settickdiv(const avalue: integer); +begin + ftickdiv:= avalue; + if ftickdiv <= 0 then begin + ftickdiv:= 0; + end; +end; + +procedure tsigcontroller.checktick; +begin + if (fticks <> nil) or assigned(fonbeforetick) or assigned(fonaftertick) then begin + include(fstate,scs_hastick); + end + else begin + exclude(fstate,scs_hastick); + end; +end; + +procedure tsigcontroller.dotick; +var + int1: integer; +begin + if assigned(fonbeforetick) then begin + fonbeforetick(self); + end; + for int1:= high(fticks) downto 0 do begin + fticks[int1]; + end; + if assigned(fonaftertick) then begin + fonaftertick(self); + end; +end; + +procedure tsigcontroller.setonbeforetick(const avalue: notifyeventty); +begin + fonbeforetick:= avalue; + checktick; +end; + +procedure tsigcontroller.setonaftertick(const avalue: notifyeventty); +begin + fonaftertick:= avalue; + checktick; +end; + +procedure tsigcontroller.lockapplication; +var + int1: integer; +begin + flockapplocks:= flockcount; + for int1:= flockcount - 1 downto 0 do begin + unlock; + end; + application.lock; +end; + +procedure tsigcontroller.unlockapplication; +var + int1: integer; +begin + application.unlock; + for int1:= flockapplocks - 1 downto 0 do begin + lock; + end; +end; + +function tsigcontroller.getnodenamepath(const aintf: isigclient): string; +begin + result:= ownernamepath(aintf.getcomponent); +end; + +procedure tsigcontroller.setoptions(const avalue: sigcontrolleroptionsty); +begin + if foptions <> avalue then begin + foptions:= sigcontrolleroptionsty(setsinglebit(longword(avalue), + longword(foptions),longword([sico_freerun,sico_autorun]))); + if not (csloading in componentstate) then begin + checkoptions(); + end; + end; +end; + +procedure tsigcontroller.setsamplefrequ(const avalue: real); +begin + if fsamplefrequ <> avalue then begin + fsamplefrequ:= avalue; + end; +end; + +procedure tsigcontroller.checkoptions; +begin + stopautorun(); + if not (csdesigning in componentstate) then begin + if (fstepcount > 0) and (fsamplefrequ > 0) then begin + if sico_freerun in foptions then begin + application.registeronidle(@doidle); + end + else begin + if sico_autorun in foptions then begin + ftimer:= tsimpletimer.create(round(1000000.0*fstepcount/fsamplefrequ), + @doautotick,true,[to_leak]); + end; + end; + end; + end; +end; + +function tsigcontroller.getfreerun: boolean; +begin + result:= sico_freerun in options; +end; + +procedure tsigcontroller.setfreerun(const avalue: boolean); +begin + if avalue then begin + options:= options + [sico_freerun]; + end + else begin + options:= options - [sico_freerun]; + end; +end; + +procedure tsigcontroller.stopautorun; +begin + application.unregisteronidle(@doidle); + freeandnil(ftimer); +end; + +function tsigcontroller.getautorun: boolean; +begin + result:= sico_autorun in options; +end; + +procedure tsigcontroller.setautorun(const avalue: boolean); +begin + if avalue then begin + options:= options + [sico_autorun]; + end + else begin + options:= options - [sico_autorun]; + end; +end; + +procedure tsigcontroller.setstepcount(const avalue: integer); +begin + if fstepcount <> avalue then begin + fstepcount:= avalue; + if not (csloading in componentstate) then begin + checkoptions(); + end; + end; +end; + +procedure tsigcontroller.doautotick(const sender: tobject); +begin + step(fstepcount); +end; + +procedure tsigcontroller.doidle(var again: boolean); +begin + step(fstepcount); + again:= true; +end; + +{ tsigwavetable } + +constructor tsigwavetable.create(aowner: tcomponent); +begin + inherited; + ffrequency:= tdoubleinputconn.create(self,isigclient(self)); + ffrequency.name:= 'frequency'; + ffrequency.fv.value:= 0.01; + ffrequfact:= tdoubleinputconn.create(self,isigclient(self)); + ffrequfact.name:= 'frequfact'; + ffrequfact.fv.value:= 1; + fphase:= tdoubleinputconn.create(self,isigclient(self)); + fphase.name:= 'phase'; + famplitude:= tdoubleinputconn.create(self,isigclient(self)); + famplitude.name:= 'amplitude'; + famplitude.fv.value:= 1; +end; + +procedure tsigwavetable.setfrequency(const avalue: tdoubleinputconn); +begin + ffrequency.assign(avalue); +end; + +procedure tsigwavetable.setfrequfact(const avalue: tdoubleinputconn); +begin + ffrequfact.assign(avalue); +end; + +procedure tsigwavetable.setphase(const avalue: tdoubleinputconn); +begin + fphase.assign(avalue); +end; + +procedure tsigwavetable.setamplitude(const avalue: tdoubleinputconn); +begin + famplitude.assign(avalue); +end; + +function tsigwavetable.gethandler: sighandlerprocty; +begin + if siwto_intpol in foptions then begin + result:= {$ifdef FPC}@{$endif}sighandlerintpol; + end + else begin + result:= {$ifdef FPC}@{$endif}sighandler; + end; +end; + +procedure tsigwavetable.sighandler(const ainfo: psighandlerinfoty); +var + int1: integer; +begin + int1:= trunc((ftime+fphasepo^.value)*ftablelength) mod ftablelength; + if int1 < 0 then begin + int1:= int1 + ftablelength; + end; + foutputpo^:= ftable[int1] * famplitudepo^.value; + ftime:= frac(ftime+ffrequencypo^.value*ffrequfactpo^.value); +end; + +procedure tsigwavetable.sighandlerintpol(const ainfo: psighandlerinfoty); +var + int1: integer; + do1: double; +begin + do1:= (ftime+fphasepo^.value)*ftablelength; + int1:= trunc(do1) mod ftablelength; + if int1 < 0 then begin + int1:= int1 + ftablelength; + end; + foutputpo^:= (ftable[int1] + + (ftable[(int1+1) mod ftablelength] - ftable[int1]) * + ((do1-int1)/ftablelength) + ) * famplitudepo^.value; + ftime:= frac(ftime+ffrequencypo^.value*ffrequfactpo^.value); +end; + + +procedure tsigwavetable.settable(const avalue: doublearty); +begin + ftable:= avalue; + checktable; +end; + +procedure tsigwavetable.clear; +begin + inherited; + lock; + try + if canevent(tmethod(foninittable)) then begin + foninittable(self,realarty(ftable)); + end; + checktable; + finally + unlock; + end; +end; + +procedure tsigwavetable.checktable; +begin + lock; + try + ftime:= 0; + if ftable = nil then begin + setlength(ftable,1); + end; + ftablelength:= length(ftable); + sendchangeevent; + finally + unlock; + end; +end; + +procedure tsigwavetable.initmodel; +begin + ffrequencypo:= @ffrequency.fv; + ffrequfactpo:= @ffrequfact.fv; + fphasepo:= @fphase.fv; + famplitudepo:= @famplitude.fv; + inherited; +end; + +function tsigwavetable.getinputar: inputconnarty; +begin + setlength(result,4); + result[0]:= ffrequency; + result[1]:= ffrequfact; + result[2]:= fphase; + result[3]:= famplitude; +end; + +function tsigwavetable.getzcount: integer; +begin + result:= 1; +end; + +procedure tsigwavetable.setoptions(const avalue: sigwavetableoptionsty); +begin + if avalue <> foptions then begin + foptions:= avalue; + if fcontroller <> nil then begin + fcontroller.modelchange; + end; + end; +end; + +procedure tsigwavetable.setmaster(const avalue: tsigwavetable); +var + tab1: tsigwavetable; +begin + if avalue <> fmaster then begin + tab1:= avalue; + while tab1 <> nil do begin + if tab1 = self then begin + raise exception.create('Recursive master.'); + end; + tab1:= tab1.master; + end; + setlinkedvar(tmsecomponent(avalue),tmsecomponent(fmaster)); + if avalue <> nil then begin + table:= avalue.table; + end; + end; +end; + +procedure tsigwavetable.objectevent(const sender: tobject; + const event: objecteventty); +begin + if (event = oe_changed) and (sender <> nil) and (sender = master) then begin + table:= master.table; + end; +end; + +{ tsigfuncttable } + +constructor tsigfuncttable.create(aowner: tcomponent); +begin + inherited; + famplitude:= tdoubleinputconn.create(self,isigclient(self)); + famplitude.name:= 'amplitude'; + famplitudepo:= @famplitude.fv; +// finput:= tdoubleinputconn.create(self,isigclient(self)); +// finput.name:= 'input'; +end; +{ +procedure tsigfuncttable.setinput(const avalue: tdoubleinputconn); +begin + finput.assign(avalue); +end; +} +procedure tsigfuncttable.setamplitude(const avalue: tdoubleinputconn); +begin + famplitude.assign(avalue); +end; + +function tsigfuncttable.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}sighandler; +end; + +procedure tsigfuncttable.initmodel; +begin + inherited; +end; + +function tsigfuncttable.getinputar: inputconnarty; +begin + setlength(result,1); +// result[0]:= finput; + result[0]:= famplitude; + stackarray(pointerarty(inherited getinputar),pointerarty(result)); +end; + +function tsigfuncttable.getzcount: integer; +begin + result:= 1; +end; + +procedure tsigfuncttable.clear; +begin + inherited; + lock; + try + if canevent(tmethod(foninittable)) then begin + foninittable(self,ftable); + end; + checktable; + finally + unlock; + end; +end; + +procedure tsigfuncttable.settable(const avalue: complexarty); +begin + ftable:= avalue; + checktable; +end; + +procedure tsigfuncttable.sighandler(const ainfo: psighandlerinfoty); +var + int1,int2: integer; + do1: double; +begin + do1:= 0; + for int1:= 0 to finphigh do begin + do1:= do1 + finps[int1]^.value; + end; + if do1 <= finpmin then begin + with fsegments[0].defaultnode do begin + foutputpo^:= (offs + do1 * ramp)*famplitudepo^.value; + end; + exit; + end + else begin + if do1 >= finpmax then begin + with fsegments[functionsegmentcount-1] do begin + if nodes <> nil then begin + with nodes[high(nodes)] do begin + foutputpo^:= (offs + do1 * ramp)*famplitudepo^.value; + end; + end + else begin + with defaultnode do begin + foutputpo^:= (offs + do1 * ramp)*famplitudepo^.value; + end; + end; + end; + exit; + end + else begin + int1:= trunc((do1-finpmin)*finpfact); + end; + end; + with fsegments[int1] do begin + if do1 <= defaultnode.xend then begin + with defaultnode do begin + foutputpo^:= (offs + do1 * ramp)*famplitudepo^.value; + end; + end + else begin + for int2:= 0 to high(nodes) do begin + with nodes[int2] do begin + if do1 <= xend then begin + foutputpo^:= (offs + do1 * ramp)*famplitudepo^.value; + break; + end; + end; + end; + end; + end; +end; + +procedure tsigfuncttable.checktable; + procedure calc(const index: integer; out node: functionnodety); + var + den1: double; + begin + if index = high(ftable) then begin + if index = 0 then begin + den1:= 0; + end + else begin + den1:= ftable[index].re - ftable[index-1].re; + end; + end + else begin + den1:= ftable[index+1].re - ftable[index].re; + end; + with node do begin + if index >= high(ftable) then begin + xend:= bigreal; + end + else begin + xend:= ftable[index+1].re; + end; + if den1 = 0 then begin + offs:= ftable[index].im; + ramp:= 0; + end + else begin + if index = high(ftable) then begin + ramp:= (ftable[index].im - ftable[index-1].im)/den1; + end + else begin + ramp:= (ftable[index+1].im - ftable[index].im)/den1; + end; + offs:= ftable[index].im - ftable[index].re*ramp; + end; + end; + end; +var + int1,int2: integer; + ar1: booleanarty; + po1: pfunctionsegmentty; +begin + lock; + try + finalize(fsegments); + fillchar(fsegments,sizeof(fsegments),0); + finpmin:= 0; + finpmax:= 0; + finpfact:= 0; + if high(ftable) >= 0 then begin + finpmin:= bigreal; + finpmax:= -bigreal; + for int1:= 0 to high(ftable) do begin + with ftable[int1] do begin + if (int1 > 0) and (re < ftable[int1-1].re) then begin + raise exception.create('Invalid table order'); + end; + if re < finpmin then begin + finpmin:= re; + end; + if re > finpmax then begin + finpmax:= re; + end; + end; + end; + finpfact:= finpmax-finpmin; + if finpfact > 0 then begin + finpfact:= functionsegmentcount/finpfact; + end + else begin + finpfact:= 0; + end; + setlength(ar1,functionsegmentcount); + for int1:= 0 to high(ftable) do begin + int2:= trunc((ftable[int1].re-finpmin)*finpfact); + if int2 >= functionsegmentcount then begin + int2:= functionsegmentcount-1; + end; + if int2 < 0 then begin + int2:= 0; + end; + with fsegments[int2] do begin + if ar1[int2] or (int2 > 0) then begin //multiple nodes + setlength(nodes,high(nodes)+2); + calc(int1,nodes[high(nodes)]); + end + else begin + calc(int1,defaultnode); + end; + ar1[int2]:= true; + end; + end; + po1:= @fsegments[0]; + for int1:= 1 to high(fsegments) do begin + if po1^.nodes = nil then begin + fsegments[int1].defaultnode:= po1^.defaultnode; + end + else begin + fsegments[int1].defaultnode:= po1^.nodes[high(po1^.nodes)]; + end; + inc(po1); + end; + end; + sendchangeevent; + finally + unlock; + end; +end; + +procedure tsigfuncttable.setmaster(const avalue: tsigfuncttable); +var + tab1: tsigfuncttable; +begin + if avalue <> fmaster then begin + tab1:= avalue; + while tab1 <> nil do begin + if tab1 = self then begin + raise exception.create('Recursive master.'); + end; + tab1:= tab1.master; + end; + setlinkedvar(tmsecomponent(avalue),tmsecomponent(fmaster)); + if avalue <> nil then begin + table:= avalue.table; + end; + end; +end; + +procedure tsigfuncttable.objectevent(const sender: tobject; + const event: objecteventty); +begin + if (event = oe_changed) and (sender <> nil) and (sender = master) then begin + table:= master.table; + end; +end; + +{ tsigenvelope } + +constructor tsigenvelope.create(aowner: tcomponent); + + procedure initinfo(var ainfo: envelopeinfoty); + begin + with ainfo do begin + freleasestart:= 1; + ftimescale:= 1; + floopstart:= -1; + end; + end; //initinfo() + +begin +// feventdriven:= true; + fsubsampling:= defaultenvelopesubsampling; + fmin:= 0.001; + fmax:= 1; + feventthreshold:= 0.1; +// fdecay_maxeventtime:= 0.02; + initinfo(finfos[0]); + initinfo(finfos[1]); + fdecay_options:= [sero_exp]; + frelease_options:= [sero_exp]; + inherited; + ftrigger:= tchangedoubleinputconn.create(self,isigclient(self), + {$ifdef fpc}@{$endif}dotriggerchange); + ftrigger.name:= 'trigger'; + famplitude:= tdoubleinputconn.create(self,isigclient(self)); + famplitude.name:= 'amplitude'; + famplitude.value:= 1; + fmix:= tlimitinputconn.create(self,isigclient(self)); + fmix.name:= 'mix'; +end; + +procedure tsigenvelope.lintoexp(var avalue: double); +var + scale,offset: double; + do1: double; +begin + if (fmin > 0) and (fmax > 0) then begin + offset:= ln(fmin); + scale:= ln(fmax)-offset; + if scale <> 0 then begin + do1:= avalue*(fmax-fmin)+fmin; + if do1 > 0 then begin + avalue:= (ln(do1) - offset)/scale; + end; + end; + end; +end; + +procedure tsigenvelope.exptolin(var avalue: double); +var + scale,offset: double; + do1: double; +begin + if (fmin > 0) and (fmax > 0) then begin + offset:= ln(fmin); + scale:= ln(fmax)-offset; + do1:= fmax-fmin; + if do1 <> 0 then begin + avalue:= (exp(avalue*scale+offset)-fmin)/do1; + end; + end; +end; + +procedure tsigenvelope.updatevalues(var ainfo: envelopeinfoty); +var + timsca: double; + timoffs: double; + eventtimescale: real; + isexpbefore: boolean; + isexpbeforeset: boolean; + + procedure setscale(const options: sigenveloperangeoptionsty; + const progindex: integer; var sta: double); +// var +// do1: double; + begin + with ainfo.fprog[progindex] do begin + isexp:= sero_exp in options; + if isexp then begin + if (fmin > 0) and (fmax > 0) then begin + offset:= ln(fmin); + scale:= ln(fmax)-offset; + end + else begin + scale:= 1; //invalid + offset:= 0; + end; + if isexpbeforeset and not isexpbefore then begin + lintoexp(sta); + end; + end + else begin + offset:= fmin; + scale:= fmax-fmin; + if isexpbeforeset and isexpbefore then begin + exptolin(sta); + end; + end; + isexpbefore:= isexp; + isexpbeforeset:= true; + end; + end; //setscale + + procedure setend(const options: sigenveloperangeoptionsty; + var progindex: integer; var ti: integer; var sta: double); + begin + setscale(options,progindex,double(sta)); + with ainfo.fprog[progindex] do begin //end item + startval:= sta; + ramp:= 0; + starttime:= ti; + endtime:= -1; + inc(progindex); + end; + end; //setend + + procedure calc(const options: sigenveloperangeoptionsty; + const maxeventtime: double; + const valueitem: complexty; var progindex: integer; + var ti: integer; var sta: double); + var + int3: integer; + begin + setscale(options,progindex,double(sta)); + with ainfo.fprog[progindex] do begin + maxeventdelay:= round(maxeventtime*eventtimescale); + starttime:= ti; + startval:= sta; + int3:= ti; + ti:= round((valueitem.re+timoffs)*timsca); + endtime:= ti; + if int3 >= ti then begin + int3:= ti-1; + end; + ramp:= (valueitem.im - sta)/(ti-int3); + sta:= valueitem.im; + end; + inc(progindex); + end; //calc + + +var + int1,int2,int3: integer; + ti: integer; + sta: double; + do1: double; + aftertrigvalues: complexarty; + decaystart: double; + opt1: sigenveloperangeoptionsty; + +begin + if fupdating > 0 then begin + exit; + end; + lock; + try + ffinished:= false; + if fcontroller <> nil then begin + do1:= fcontroller.samplefrequ; + end + else begin + do1:= 44100; + end; + eventtimescale:= do1/fsubsampling; + fhasmix:= (sero_mix in fattack_options) or (sero_mix in fdecay_options) or + (sero_mix in frelease_options); + with ainfo do begin + isexpbefore:= false; + isexpbeforeset:= false; + attack_valuespo:= @fattack_values; + decay_valuespo:= @fdecay_values; + release_valuespo:= @frelease_values; + if @ainfo = @finfos[1] then begin + if not(sero_mix in fattack_options) then begin + attack_valuespo:= @finfos[0].fattack_values; + end; + if not(sero_mix in fdecay_options) then begin + decay_valuespo:= @finfos[0].fdecay_values; + end; + if not(sero_mix in frelease_options) then begin + release_valuespo:= @finfos[0].frelease_values; + end; + end; + + int1:= high(attack_valuespo^); + allocuninitedarray(int1+high(decay_valuespo^)+2,sizeof(complexty), + aftertrigvalues); + for int2:= 0 to int1 do begin + aftertrigvalues[int2]:= attack_valuespo^[int2]; + end; + if int1 >= 0 then begin + decaystart:= attack_valuespo^[int1].re; + end + else begin + decaystart:= 0; + end; + inc(int1); + for int2:= 0 to high(decay_valuespo^) do begin + with aftertrigvalues[int2+int1] do begin + re:= decay_valuespo^[int2].re + decaystart; + im:= decay_valuespo^[int2].im; + end; + end; + fprog:= nil; + timoffs:= 0; + timsca:= ftimescale/fsubsampling; + if fcontroller <> nil then begin + timsca:= timsca * fcontroller.samplefrequ; + end; + ftime:= 0; + fattackval:= 0; + fattackramp:= 0; + floopstartindex:= -1; + floopendindex:= -1; + floopval:= 0; + floopramp:= 1; + freleaseindex:= -1; + freleaseval:= 0; + freleaseramp:= 0; + + int1:= high(aftertrigvalues) + 2; //+ enditem + if floopstart >= 0 then begin + for int2:= 0 to high(decay_valuespo^) do begin + if decay_valuespo^[int2].re >= floopstart then begin + floopstartindex:= int2+length(attack_valuespo^); //fvaluestrig index + floopendindex:= length(aftertrigvalues); + break; + end; + end; + end; + if high(aftertrigvalues) >= 0 then begin + fattackval:= aftertrigvalues[0].im; + freleasestart:= aftertrigvalues[high(aftertrigvalues)].re; + end; + + if high(release_valuespo^) >= 0 then begin + int1:= int1 + high(release_valuespo^) + 2; //+enditem + freleaseval:= release_valuespo^[0].im; + freleaseramp:= release_valuespo^[0].re; + if freleaseramp > 0 then begin + freleaseramp:= 1/(freleaseramp*timsca); + end; + end; + setlength(fprog,int1); + findex:= high(fprog); //init inactive + findexhigh:= findex; + ti:= 0; + sta:= fattackval; + int1:= 0; + int3:= high(aftertrigvalues); + for int2:= 0 to high(attack_valuespo^) do begin + calc(fattack_options,fattack_maxeventtime,aftertrigvalues[int2],int1,ti,sta); + end; + for int2:= length(attack_valuespo^) to int3 do begin + calc(fdecay_options,fdecay_maxeventtime,aftertrigvalues[int2],int1,ti,sta); + end; + if floopstartindex >= 0 then begin + do1:= sta; + calc(fdecay_options,fdecay_maxeventtime,makecomplex( + aftertrigvalues[int3].re+aftertrigvalues[floopstartindex].re-floopstart, + aftertrigvalues[floopstartindex].im),int1,ti,sta); + sta:= do1; + inc(floopstartindex); //fprog index + end + else begin + opt1:= fdecay_options; + if (decay_valuespo^ = nil) and (attack_valuespo^ <> nil) then begin + opt1:= fattack_options; + end; + setend(opt1,int1,ti,sta); + end; + if high(release_valuespo^) >= 0 then begin + ti:= 0; + freleaseindex:= int1; //prog index + for int2:= 0 to high(release_valuespo^) do begin + calc(frelease_options,frelease_maxeventtime,release_valuespo^[int2], + int1,ti,sta); + end; + setend(frelease_options,int1,ti,sta); + end; + if fprog[0].endtime > 0 then begin + fattackramp:= 1/fprog[0].endtime; + end; + sendchangeevent; + end; + finally + unlock; + end; +end; + +{ +function tsigenvelope.getsigoptions: sigclientoptionsty; +begin + result:= [sco_tick]; +end; + +procedure tsigenvelope.sigtick; +begin + fcontroller.execevent(isigclient(self)); +end; +} +procedure tsigenvelope.sighandler(const ainfo: psighandlerinfoty); + + procedure startattack(var ainfo: envelopeinfoty); + begin + with ainfo do begin + ftime:= 0; + findex:= 0; + with fprog[0] do begin + if fcurrisexp and not isexp then begin + exptolin(fcurrval); + end; + if not fcurrisexp and isexp then begin + lintoexp(fcurrval); + end; + ramp:= (fattackval-fcurrval)*fattackramp; + if ramp = 0 then begin + startval:= fattackval; + end + else begin + startval:= fcurrval; + end; + end; + end; + end; //startattack() + + procedure startrelease(var ainfo: envelopeinfoty); + begin + with ainfo do begin + if freleaseindex >= 0 then begin + ftime:= 0; + findex:= freleaseindex; + with fprog[findex] do begin + if fcurrisexp and not isexp then begin + exptolin(fcurrval); + end; + if not fcurrisexp and isexp then begin + lintoexp(fcurrval); + end; + ramp:= (freleaseval-fcurrval)*freleaseramp; + if ramp = 0 then begin + startval:= freleaseval; + end + else begin + startval:= fcurrval; + end; + end; + end; + end; + end; //startrelease() + + procedure calc(var ainfo: envelopeinfoty); + begin + with ainfo do begin + with fprog[findex] do begin + fcurrisexp:= isexp; + fcurrval:= startval+ramp*(ftime-starttime); + if isexp then begin + if (fcurrval <= 0) and not (seo_nozero in foptions) then begin + fdest:= 0; + end + else begin + fdest:= exp(fcurrval*scale + offset)*famplitudepo^.value; + end; + end + else begin + fdest:= (fcurrval*scale + offset)*famplitudepo^.value; + end; + if endtime >= 0 then begin + inc(ftime); + if (ftime > endtime) then begin + if findex = floopendindex then begin + findex:= floopstartindex; + ftime:= fprog[floopstartindex].starttime; + end + else begin + inc(findex); + end; + end; + end; + end; + end; + end; //calc() + +var + bo1: boolean; + int1: integer; +begin + if fattackpending or (ftrigger.fv.value = 1) then begin + ftrigger.fv.value:= 0; + fattackpending:= false; + ffinished:= false; + startattack(finfos[0]); + startattack(finfos[1]); + end; + if freleasepending or (ftrigger.fv.value = -1) then begin + ftrigger.fv.value:= 0; + freleasepending:= false; + ffinished:= false; + startrelease(finfos[0]); + startrelease(finfos[1]); + end; + ainfo^.discard:= true; + if fsamplecount = 0 then begin + fsamplecount:= fsubsampling; + if feventdriven then begin + calc(finfos[0]); + with finfos[0] do begin + fmaxeventdelay:= fprog[findex].maxeventdelay; + bo1:= false; + if fhasmix then begin + calc(finfos[1]); + with finfos[1] do begin + int1:= fprog[findex].maxeventdelay; + if int1 < fmaxeventdelay then begin + fmaxeventdelay:= int1; + end; + bo1:= (feventtime >= fmaxeventdelay) or + (abs(fcurrval-fcurrvalbefore) > feventthreshold); + end; + end; + bo1:= bo1 or (feventtime >= fmaxeventdelay) or + (abs(fcurrval-fcurrvalbefore) > feventthreshold); + if bo1 then begin + fcurrvalbefore:= fcurrval; + end; + end; + if fhasmix then begin + calc(finfos[1]); + with finfos[1] do begin + if bo1 then begin + fcurrvalbefore:= fcurrval; + foutputpo^:= finfos[1].fdest * fmixpo^.value + + finfos[0].fdest * (1-fmixpo^.value); + end; + end; + end + else begin + if bo1 then begin + foutputpo^:= finfos[0].fdest; + end; + end; + if bo1 then begin + feventtime:= 0; + fcontroller.dispatcheventoutput(fsigclientinfo.infopo); + end; + inc(feventtime); + end + else begin + ainfo^.discard:= false; + calc(finfos[0]); + ffinished:= finfos[0].findex = finfos[0].findexhigh; + if fhasmix then begin + calc(finfos[1]); + ffinished:= ffinished and (finfos[1].findex = finfos[1].findexhigh); + foutputpo^:= finfos[1].fdest * fmixpo^.value + + finfos[0].fdest * (1-fmixpo^.value); + end + else begin + foutputpo^:= finfos[0].fdest; + end; + end; + end; + if not ffinished then begin + dec(fsamplecount); + end; +end; + +function tsigenvelope.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}sighandler; +end; + +procedure tsigenvelope.checkindex(const index: integer); +begin + if (index < 0) or (index > 1) then begin + raise exception.create(ownernamepath(self)+': Invalid array index '+ + inttostr(index)+'.'); + end; +end; + +procedure tsigenvelope.updatevalueindex(const aindex: integer); +begin + updatevalues(finfos[aindex]); + if aindex = 0 then begin + updatevalues(finfos[1]); //affects both + end; +end; + +function tsigenvelope.getattack_values(const index: integer): complexarty; +begin + checkindex(index); + result:= finfos[index].fattack_values; +end; + +procedure tsigenvelope.setattack_values(const index: integer; + const avalue: complexarty); +begin + checkindex(index); + finfos[index].fattack_values:= avalue; + updatevalueindex(index); +end; + +function tsigenvelope.getdecay_values(const index: integer): complexarty; +begin + checkindex(index); + result:= finfos[index].fdecay_values; +end; + +procedure tsigenvelope.setdecay_values(const index: integer; + const avalue: complexarty); +begin + checkindex(index); + finfos[index].fdecay_values:= avalue; + updatevalueindex(index); +end; + +function tsigenvelope.getrelease_values(const index: integer): complexarty; +begin + checkindex(index); + result:= finfos[index].frelease_values; +end; + +procedure tsigenvelope.setrelease_values(const index: integer; + const avalue: complexarty); +begin + checkindex(index); + finfos[index].frelease_values:= avalue; + updatevalueindex(index); +end; + +function tsigenvelope.getloopstart(const index: integer): real; +begin + checkindex(index); + result:= finfos[index].floopstart; +end; + +procedure tsigenvelope.setloopstart(const index: integer; + const avalue: real); +begin + checkindex(index); + finfos[index].floopstart:= avalue; + updatevalues(finfos[index]); +end; + +{ +procedure tsigenvelope.setdecaystart(const avalue: real); +begin + fdecaystart:= avalue; + updatevalues; +end; +} +{ +procedure tsigenvelope.setaftertrigvalues(const avalue: complexarty); +begin + faftertrigvalues:= avalue; + updatevalues; +end; +} + +procedure tsigenvelope.settrigger(const avalue: tchangedoubleinputconn); +begin + ftrigger.assign(avalue); +end; + +function tsigenvelope.getinputar: inputconnarty; +begin + setlength(result,3); + result[0]:= ftrigger; + result[1]:= famplitude; + result[2]:= fmix; +end; + +function tsigenvelope.getzcount: integer; +begin + result:= 1; +end; + +procedure tsigenvelope.initmodel; +begin + inherited; + famplitudepo:= @famplitude.fv; + fmixpo:= @fmix.fv; + updatevaluesx; +end; + +procedure tsigenvelope.setmin(const avalue: real); +begin + fmin:= avalue; + updatevaluesx; +end; + +procedure tsigenvelope.setmax(const avalue: real); +begin + fmax:= avalue; + updatevaluesx; +end; + +procedure tsigenvelope.setoptions(const avalue: sigenvelopeoptionsty); +begin + if avalue <> foptions then begin + eventdriven:= seo_eventoutput in avalue; + foptions:= avalue; + updatevaluesx; + end; +end; + +procedure tsigenvelope.dotriggerchange(const sender: tobject); +begin + if ftrigger.fv.value = 1 then begin + fattackpending:= true; + end; + if ftrigger.fv.value = -1 then begin + freleasepending:= true; + end; + ftrigger.fv.value:= 0; +end; + +procedure tsigenvelope.start; +begin + lock; + fattackpending:= true; + unlock; +end; + +procedure tsigenvelope.stop; +begin + lock; + freleasepending:= true; + unlock; +end; + +procedure tsigenvelope.update; +begin + inherited; + updatevaluesx; +end; + +procedure tsigenvelope.setattack_options(const avalue: sigenveloperangeoptionsty); +begin + if fattack_options <> avalue then begin + fattack_options:= avalue; + updatevaluesx; + end; +end; + +procedure tsigenvelope.setdecay_options(const avalue: sigenveloperangeoptionsty); +begin + if fdecay_options <> avalue then begin + fdecay_options:= avalue; + updatevaluesx; + end; +end; + +procedure tsigenvelope.setrelease_options(const avalue: sigenveloperangeoptionsty); +begin + if frelease_options <> avalue then begin + frelease_options:= avalue; + updatevaluesx; + end; +end; + +procedure tsigenvelope.dosync; + + procedure setval(const aindex: integer); + begin + attack_values[aindex]:= master.attack_values[aindex]; + decay_values[aindex]:= master.decay_values[aindex]; + release_values[aindex]:= master.release_values[aindex]; + loopstart[aindex]:= master.loopstart[aindex]; + end; //setval() + +begin + beginupdate; + setval(0); + setval(1); + endupdate; +end; + +procedure tsigenvelope.setmaster(const avalue: tsigenvelope); +var + env1: tsigenvelope; +begin + if avalue <> fmaster then begin + env1:= avalue; + while env1 <> nil do begin + if env1 = self then begin + raise exception.create('Recursive master.'); + end; + env1:= env1.master; + end; + setlinkedvar(tmsecomponent(avalue),tmsecomponent(fmaster)); + if avalue <> nil then begin + dosync; + end; + end; +end; + +procedure tsigenvelope.objectevent(const sender: tobject; + const event: objecteventty); +begin + if (event = oe_changed) and (sender <> nil) and (sender = master) then begin + dosync; + end; +end; + +procedure tsigenvelope.setamplitude(const avalue: tdoubleinputconn); +begin + famplitude.assign(avalue); +end; + +procedure tsigenvelope.updatevaluesx; +begin + updatevalues(finfos[0]); + updatevalues(finfos[1]); +end; + +procedure tsigenvelope.setmix(const avalue: tlimitinputconn); +begin + fmix.assign(avalue); +end; + +function tsigenvelope.getsigoptions: sigclientoptionsty; +begin + result:= inherited getsigoptions; + if feventdriven then begin + result:= result + [sco_fulltick]; + end; +end; + +procedure tsigenvelope.setsubsampling(avalue: integer); +begin + if avalue < 1 then begin + avalue:= 1; + end; + fsubsampling:= avalue; +end; + +{ tchangedoubleinputconn } + +constructor tchangedoubleinputconn.create(const aowner: tcomponent; + const asigintf: isigclient; const aonchange: notifyeventty); +begin + fonchange:= aonchange; + inherited create(aowner,asigintf); +end; + +procedure tchangedoubleinputconn.setvalue(const avalue: double); +begin + lock; + inherited; + if tmsecomponent(owner).canevent(tmethod(fonchange)) then begin + try + fonchange(self); + finally + unlock + end; + end + else begin + unlock; + end; +end; + +{ tsigsampler } + +constructor tsigsampler.create(aowner: tcomponent); +begin + fbufferlength:= defaultsamplecount; + frefreshus:= -1; + foptions:= defaultsigsampleroptions; + inherited; + ftrigger:= tchangedoubleinputconn.create(self,isigclient(self), + {$ifdef FPC}@{$endif}dotriggerchange); + ftrigger.name:= 'trigger'; + ftriggerlevel:= tchangedoubleinputconn.create(self,isigclient(self), + {$ifdef FPC}@{$endif}dotriggerchange); + ftriggerlevel.name:= 'triggerlevel'; + ftimer:= tsimpletimer.create(0,{$ifdef FPC}@{$endif}dotimer,false,[to_leak]); +end; + +destructor tsigsampler.destroy; +begin + ftimer.free; + inherited; +end; + +function tsigsampler.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}sighandler; +end; + +procedure tsigsampler.sighandler(const ainfo: psighandlerinfoty); +var + int1: integer; + do1: double; +begin + if not frunning and fstarted then begin + if sso_autorun in foptions then begin + do1:= 1; + end + else begin + if fnegtrig then begin + do1:= ftriggerlevel.value-ftrigger.value; + end + else begin + do1:= ftrigger.value-ftriggerlevel.value; + end; + end; + if do1 >{=} 0 then begin +// if do1 = 0 then begin +// fpretrigger:= true; +// end; + if fpretrigger then begin + fbufpo:= 0; + frunning:= true; + fstarted:= false; + end; + end + else begin + fpretrigger:= true; + end; + end; + if frunning then begin + for int1:= 0 to high(fsigbuffer) do begin + fsigbuffer[int1][fbufpo]:= finps[int1]^.value; + end; + inc(fbufpo); + if fbufpo = fbufferlength then begin + frunning:= false; + dobufferfull; + checkautostart; + end; + end + else begin + if fstartpending then begin + fstartpending:= false; + start; + end; + end; +end; + +procedure tsigsampler.clear; +begin +// fstarted:= false; + frunning:= false; + inherited; +end; + +procedure tsigsampler.setbufferlength(const avalue: integer); +begin + if fbufferlength <> avalue then begin + lock; + if avalue = 0 then begin + fbufferlength:= 1; + end + else begin + fbufferlength:= avalue; + end; + modelchange; + unlock; + end; +end; + +procedure tsigsampler.initmodel; +var + int1: integer; +begin + inherited; + fsigbuffer:= nil; + setlength(fsigbuffer,finputs.count); + for int1:= 0 to high(fsigbuffer) do begin + setlength(fsigbuffer[int1],fbufferlength); + end; + checkautostart(); +end; + +procedure tsigsampler.settrigger(const avalue: tchangedoubleinputconn); +begin + ftrigger.assign(avalue); +end; + +procedure tsigsampler.settriggerlevel(const avalue: tchangedoubleinputconn); +begin + ftriggerlevel.assign(avalue); +end; + +procedure tsigsampler.dotriggerchange(const sender: tobject); +begin + //dummy +end; + +procedure tsigsampler.start; +begin + lock; + fstarted:= true; + frunning:= false; + fpretrigger:= sso_autorun in foptions; + unlock; +end; + +procedure tsigsampler.dobufferfull; +begin + if assigned(fonbufferfull) then begin + fonbufferfull(self,fsigbuffer); + end; +end; + +function tsigsampler.getinputar: inputconnarty; +begin + setlength(result,2); + result[0]:= ftrigger; + result[1]:= ftriggerlevel; + stackarray(pointerarty(inherited getinputar),pointerarty(result)); +end; + +procedure tsigsampler.checkautostart; +begin + if (sso_autorun in foptions) and (frefreshus < 0) and + (componentstate * [csloading,csdesigning] = []) then begin + start; + end; +end; + +procedure tsigsampler.setoptions(const avalue: sigsampleroptionsty); +var + optionsbefore: sigsampleroptionsty; +begin + if foptions <> avalue then begin + optionsbefore:= foptions; + foptions:= avalue; + updateoptions(foptions); + fnegtrig:= sso_negtrig in foptions; + if (sso_fulltick in foptions) xor (sso_fulltick in optionsbefore) then begin + modelchange; + end; + if not (sso_autorun in optionsbefore) then begin + checkautostart; + end; + end; +end; + +procedure tsigsampler.setrefreshus(const avalue: integer); +begin + if frefreshus <> avalue then begin + frefreshus:= avalue; + if avalue < 0 then begin + ftimer.enabled:= false; + checkautostart; + end + else begin + ftimer.interval:= avalue; + if componentstate * [csloading,csdesigning] = [] then begin + ftimer.enabled:= true; + end; + end; + end; +end; + +procedure tsigsampler.dotimer(const sender: tobject); +begin + lock; + if not fstarted and not frunning then begin + start; + end + else begin + fstartpending:= true; + end; + unlock; +end; + +procedure tsigsampler.loaded; +begin + inherited; + if not (csdesigning in componentstate) then begin + if (frefreshus >= 0) then begin + ftimer.enabled:= true; + end + else begin + checkautostart; + end; + end; +end; + +procedure tsigsampler.updateoptions(var avalue: sigsampleroptionsty); +begin + exclude(avalue,sso_fftmag); +end; + +function tsigsampler.getsigoptions: sigclientoptionsty; +begin + result:= inherited getsigoptions; + if sso_fulltick in foptions then begin + include(result,sco_fulltick); + end; +end; + +{ tdoublesiginoutcomp } + +constructor tdoublesiginoutcomp.create(aowner: tcomponent); +begin + finput:= tdoubleinputconn.create(self,isigclient(self)); + finputpo:= @finput.fv; + inherited; +end; + +procedure tdoublesiginoutcomp.setinput(const avalue: tdoubleinputconn); +begin + finput.assign(avalue); +end; + +function tdoublesiginoutcomp.getinputar: inputconnarty; +begin + setlength(result,1); + result[0]:= finput; +end; + +{ tsigconnector } + +function tsigconnector.gethandler: sighandlerprocty; +begin + result:= {$ifdef FPC}@{$endif}sighandler; +end; + +procedure tsigconnector.sighandler(const ainfo: psighandlerinfoty); +begin + foutputpo^:= finputpo^.value; +end; + +{ ttrigconnector } + +constructor ttrigconnector.create(aowner: tcomponent); +begin + inherited; + include(foutput.fstate,ocs_eventdriven); +end; + +{ tlimitinputconn } + +constructor tlimitinputconn.create(const aowner: tcomponent; + const asigintf: isigclient); +begin + inherited; + fmin:= 0; + fmax:= 1; +end; + +end. diff --git a/mseide-msegui/lib/common/math/msesignoise.pas b/mseide-msegui/lib/common/math/msesignoise.pas new file mode 100644 index 0000000..220b136 --- /dev/null +++ b/mseide-msegui/lib/common/math/msesignoise.pas @@ -0,0 +1,316 @@ +{ MSEgui Copyright (c) 2010-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} + +unit msesignoise; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + msesignal,classes,mclasses; + +type + noisekindty = (nk_white,nk_pink,nk_brown); + + tsignoise = class(tdoublesigoutcomp) + private + famplitudepo: psigvaluety; + foffsetpo: psigvaluety; + famplitude: tdoubleinputconn; + foffset: tdoubleinputconn; + fw,fz: longword; //random seeds + fscale: double; + fsamplehigh: integer; + fsamplecount: integer; + fkind: noisekindty; + fcutofffrequ: real; + fsum: real; + fb0,fb1,fb2,fb3,fb4,fb5,fb6: double; + fsumfact: real; + procedure setamplitude(const avalue: tdoubleinputconn); + procedure setoffset(const avalue: tdoubleinputconn); + procedure setsamplecount(const avalue: integer); + procedure setkind(const avalue: noisekindty); + procedure setcutofffrequ(const avalue: real); + protected + procedure sighandlerbrown1(const ainfo: psighandlerinfoty); + procedure sighandlerbrownn(const ainfo: psighandlerinfoty); + procedure sighandlerpink1(const ainfo: psighandlerinfoty); + procedure sighandlerpinkn(const ainfo: psighandlerinfoty); + procedure sighandler1(const ainfo: psighandlerinfoty); + procedure sighandlern(const ainfo: psighandlerinfoty); + //isigclient + function gethandler: sighandlerprocty; override; + procedure initmodel; override; + function getinputar: inputconnarty; override; + function getzcount: integer; override; + public + constructor create(aowner: tcomponent); override; + procedure clear; override; + published + property amplitude: tdoubleinputconn read famplitude write setamplitude; + property offset: tdoubleinputconn read foffset write setoffset; + property samplecount: integer read fsamplecount + write setsamplecount default 1; + //1 -> uniform distribution + property kind: noisekindty read fkind write setkind default nk_white; + property cutofffrequ: real read fcutofffrequ write setcutofffrequ; + //nk_pink only, default 0.001 + end; + +implementation +uses + msenoise; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tdoubleinputconn1 = class(tdoubleinputconn); + +{ tsignoise } + +constructor tsignoise.create(aowner: tcomponent); +begin + fcutofffrequ:= 0.001; + samplecount:= 1; + inherited; + famplitude:= tdoubleinputconn.create(self,isigclient(self)); + famplitude.name:= 'amplitude'; + famplitude.value:= 1; + foffset:= tdoubleinputconn.create(self,isigclient(self)); + foffset.name:= 'offset'; +end; + +procedure tsignoise.clear; +begin + fz:= 0; + fw:= 0; + checkmwcseed(fz,fw); + fsum:= 0; + fb0:= 0; + fb1:= 0; + fb2:= 0; + fb3:= 0; + fb4:= 0; + fb5:= 0; + fb6:= 0; + inherited; +end; + +function tsignoise.gethandler: sighandlerprocty; +begin + if fsamplecount = 1 then begin + case fkind of + nk_pink: begin + result:= {$ifdef FPC}@{$endif}sighandlerpink1; + end; + nk_brown: begin + result:= {$ifdef FPC}@{$endif}sighandlerbrown1; + end; + else begin //nk_white + result:= {$ifdef FPC}@{$endif}sighandler1; + end; + end; + end + else begin + case fkind of + nk_pink: begin + result:= {$ifdef FPC}@{$endif}sighandlerpinkn; + end; + nk_brown: begin + result:= {$ifdef FPC}@{$endif}sighandlerbrownn; + end; + else begin //nk_white + result:= {$ifdef FPC}@{$endif}sighandlern; + end; + end; + end; +end; + +procedure tsignoise.initmodel; +var + do1: double; +begin + do1:= fcutofffrequ*2*pi; + fsamplehigh:= fsamplecount - 1; + fscale:= maxint * sqrt(fsamplecount); + if do1 > 0 then begin + case fkind of + nk_pink: begin + fscale:= fscale*4; + end; + nk_brown: begin + fscale:= fscale/sqrt(do1); + end; + end; + end; + fsumfact:= exp(-do1); + famplitudepo:= @tdoubleinputconn1(famplitude).fv; + foffsetpo:= @tdoubleinputconn1(foffset).fv; + inherited; +end; + +function tsignoise.getinputar: inputconnarty; +begin + setlength(result,2); + result[0]:= famplitude; + result[1]:= foffset; +end; + +function tsignoise.getzcount: integer; +begin + result:= 1; +end; + +procedure tsignoise.sighandler1(const ainfo: psighandlerinfoty); +begin + fz:= 36969 * (fz and $ffff) + (fz shr 16); //mwc by George Marsaglia + fw:= 18000 * (fw and $ffff) + (fw shr 16); + foutputpo^:= (integer((fz shl 16) + fw)/fscale)*famplitudepo^.value+ + foffsetpo^.value; +end; + +procedure tsignoise.sighandlern(const ainfo: psighandlerinfoty); +var + int1: integer; + do1: double; +begin + do1:= 0; + for int1:= 0 to fsamplehigh do begin //mwc by George Marsaglia + fz:= 36969 * (fz and $ffff) + (fz shr 16); + fw:= 18000 * (fw and $ffff) + (fw shr 16); + do1:= do1 + integer((fz shl 16) + fw); + end; + foutputpo^:= (do1*famplitudepo^.value)/fscale+foffsetpo^.value; +end; + +procedure tsignoise.sighandlerpink1(const ainfo: psighandlerinfoty); +var + white: double; +begin + fz:= 36969 * (fz and $ffff) + (fz shr 16); //mwc by George Marsaglia + fw:= 18000 * (fw and $ffff) + (fw shr 16); + white:= (integer((fz shl 16) + fw)/fscale); + + fb0:= 0.99886 * fb0 + white * 0.0555179; //filter by Paul Kellet + fb1:= 0.99332 * fb1 + white * 0.0750759; + fb2:= 0.96900 * fb2 + white * 0.1538520; + fb3:= 0.86650 * fb3 + white * 0.3104856; + fb4:= 0.55000 * fb4 + white * 0.5329522; + fb5:= -0.7616 * fb5 - white * 0.0168980; + foutputpo^:= (fb0+fb1+fb2+fb3+fb4+fb5+fb6+white*0.5362) * + famplitudepo^.value + foffsetpo^.value; + fb6:= white * 0.115926; +end; + +procedure tsignoise.sighandlerpinkn(const ainfo: psighandlerinfoty); +var + int1: integer; + white: double; +begin + white:= 0; + for int1:= 0 to fsamplehigh do begin //mwc by george marsaglia + fz:= 36969 * (fz and $ffff) + (fz shr 16); + fw:= 18000 * (fw and $ffff) + (fw shr 16); + white:= white + integer((fz shl 16) + fw); + end; +//filter by Paul Kellet + + fb0:= 0.99886 * fb0 + white * 0.0555179; + fb1:= 0.99332 * fb1 + white * 0.0750759; + fb2:= 0.96900 * fb2 + white * 0.1538520; + fb3:= 0.86650 * fb3 + white * 0.3104856; + fb4:= 0.55000 * fb4 + white * 0.5329522; + fb5:= -0.7616 * fb5 - white * 0.0168980; + foutputpo^:= ((fb0+fb1+fb2+fb3+fb4+fb5+fb6+white*0.5362) * + famplitudepo^.value)/fscale + foffsetpo^.value; + fb6:= white * 0.115926; +end; + +procedure tsignoise.sighandlerbrown1(const ainfo: psighandlerinfoty); +begin + fz:= 36969 * (fz and $ffff) + (fz shr 16); //mwc by George Marsaglia + fw:= 18000 * (fw and $ffff) + (fw shr 16); + fsum:= fsum*fsumfact + integer((fz shl 16) + fw)/fscale; + foutputpo^:= fsum*famplitudepo^.value+foffsetpo^.value; +end; + +procedure tsignoise.sighandlerbrownn(const ainfo: psighandlerinfoty); +var + int1: integer; + do1: double; +begin + do1:= 0; + for int1:= 0 to fsamplehigh do begin //mwc by George Marsaglia + fz:= 36969 * (fz and $ffff) + (fz shr 16); + fw:= 18000 * (fw and $ffff) + (fw shr 16); + do1:= do1 + integer((fz shl 16) + fw); + end; + fsum:= fsum*fsumfact+do1; + foutputpo^:= (fsum*famplitudepo^.value)/fscale+foffsetpo^.value; +end; + +procedure tsignoise.setamplitude(const avalue: tdoubleinputconn); +begin + famplitude.assign(avalue); +end; + +procedure tsignoise.setoffset(const avalue: tdoubleinputconn); +begin + foffset.assign(avalue); +end; + +procedure tsignoise.setsamplecount(const avalue: integer); +begin + if fsamplecount <> avalue then begin + lock; + fsamplecount:= avalue; + if fsamplecount <= 0 then begin + fsamplecount:= 1; + end; + modelchange; + unlock; + end; +end; + +procedure tsignoise.setkind(const avalue: noisekindty); +begin + if fkind <> avalue then begin + lock; + fkind:= avalue; + modelchange; + unlock; + end; +end; + +procedure tsignoise.setcutofffrequ(const avalue: real); +begin + if fcutofffrequ <> avalue then begin + lock; + fcutofffrequ:= avalue; + modelchange; + unlock; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/opengl/mseftgl.pas b/mseide-msegui/lib/common/opengl/mseftgl.pas new file mode 100644 index 0000000..607130a --- /dev/null +++ b/mseide-msegui/lib/common/opengl/mseftgl.pas @@ -0,0 +1,420 @@ +{ MSEgui Copyright (c) 2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +{ +/* + * FTGL - OpenGL font library + * + * Copyright (c) 2001-2004 Henry Maddocks + * Copyright (c) 2008 Sam Hocevar + * Copyright (c) 2008 Sean Morrison + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + } +unit mseftgl; +// +//under construction +// +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msectypes,msetypes,msestrings; + +const +{$ifdef mswindows} + ftgllib: array[0..0] of filenamety = ('FTGL.dll'); +{$else} + ftgllib: array[0..1] of filenamety = ('libftgl.so.2','libftgl.so'); +{$endif} + +type + size_t = ptruint; + FT_Error = cint; +const + FT_ENCODING_NONE = 0; + + FT_ENCODING_MS_SYMBOL = (ord('s') shl 24) or + (ord('y') shl 16) or + (ord('m') shl 8) or + ord('b'); + FT_ENCODING_UNICODE = (ord('u') shl 24) or + (ord('n') shl 16) or + (ord('i') shl 8) or + ord('c'); + FT_ENCODING_SJIS = (ord('s') shl 24) or + (ord('j') shl 16) or + (ord('i') shl 8) or + ord('s'); + FT_ENCODING_GB2312 = (ord('g') shl 24) or + (ord('b') shl 16) or + (ord(' ') shl 8) or + ord(' '); + FT_ENCODING_BIG5 = (ord('b') shl 24) or + (ord('i') shl 16) or + (ord('g') shl 8) or + ord('5'); + FT_ENCODING_WANSUNG = (ord('w') shl 24) or + (ord('a') shl 16) or + (ord('n') shl 8) or + ord('s'); + FT_ENCODING_JOHAB = (ord('j') shl 24) or + (ord('o') shl 16) or + (ord('h') shl 8) or + ord('a'); + +// /* for backwards compatibility */ + FT_ENCODING_MS_SJIS = FT_ENCODING_SJIS; + FT_ENCODING_MS_GB2312 = FT_ENCODING_GB2312; + FT_ENCODING_MS_BIG5 = FT_ENCODING_BIG5; + FT_ENCODING_MS_WANSUNG = FT_ENCODING_WANSUNG; + FT_ENCODING_MS_JOHAB = FT_ENCODING_JOHAB; + + FT_ENCODING_ADOBE_STANDARD = (ord('A') shl 24) or + (ord('D') shl 16) or + (ord('O') shl 8) or + ord('B'); + FT_ENCODING_ADOBE_EXPERT = (ord('A') shl 24) or + (ord('D') shl 16) or + (ord('B') shl 8) or + ord('E'); + FT_ENCODING_ADOBE_CUSTOM = (ord('A') shl 24) or + (ord('D') shl 16) or + (ord('B') shl 8) or + ord('C'); + FT_ENCODING_ADOBE_LATIN_1 = (ord('l') shl 24) or + (ord('a') shl 16) or + (ord('t') shl 8) or + ord('1'); + + FT_ENCODING_OLD_LATIN_2 = (ord('l') shl 24) or + (ord('a') shl 16) or + (ord('t') shl 8) or + ord('2'); + + FT_ENCODING_APPLE_ROMAN = (ord('a') shl 24) or + (ord('r') shl 16) or + (ord('m') shl 8) or + ord('n'); + + FTGL_RENDER_FRONT = $0001; + FTGL_RENDER_BACK = $0002; + FTGL_RENDER_SIDE = $0004; + FTGL_RENDER_ALL = $ffff; + + FTGL_ALIGN_LEFT = 0; + FTGL_ALIGN_CENTER = 1; + FTGL_ALIGN_RIGHT = 2; + FTGL_ALIGN_JUSTIFY = 3; + + +{/** FTFont.h + * FTGLfont is the public interface for the FTGL library. + * + * It is good practice after using these functions to test the error + * code returned. FT_Error Error(). Check the freetype file + * fterrdef.h for error definitions. + */} +type + FT_GlyphSlotRec = record end; //opaque + FT_GlyphSlot = ^FT_GlyphSlotRec; + FTGLfont = record end; //opaque + pFTGLfont = ^FTGLfont; + FTGLglyph = record end; //opaque + pFTGLglyph = ^FTGLglyph; + + makeglyphcallbackty = function(par1: FT_GlyphSlot; par2: pointer): pFTGLglyph; + cdecl; +// boundsty = array[0..5] of cfloat; + boundsty = packed record + lower,left,near,upper,right,far: cfloat; + end; + +var + +{/** + * Create a custom FTGL font object. + * + * @param fontFilePath The font file name. + * @param data A pointer to private data that will be passed to callbacks. + * @param makeglyphCallback A glyph-making callback function. + * @return An FTGLfont* object. + */} + ftglCreateCustomFont: function(fontFilePath: pchar; data: pointer; + makeglyphCallback: makeglyphcallbackty): pFTGLfont; cdecl; +{/** + * Create a specialised FTGLfont object for handling bitmap fonts. + * + */} + ftglCreateBitmapFont: function(_file: pchar): pFTGLfont; cdecl; +{/** + * Create a specialised FTGLfont object for handling pixmap (grey scale) fonts. + */} + ftglCreatePixmapFont: function(_file: pchar): pFTGLfont; cdecl; +{/** + * Create a specialised FTGLfont object for handling vector outline fonts. + */} + ftglCreateOutlineFont: function(_file: pchar): pFTGLfont; cdecl; +{/** + * Create a specialised FTGLfont object for handling tesselated polygon + * mesh fonts. + */} + ftglCreatePolygonFont: function(_file: pchar): pFTGLfont; cdecl; +{/** + * Create a specialised FTGLfont object for handling texture-mapped fonts. + */} + ftglCreateTextureFont: function(_file: pchar): pFTGLfont; cdecl; +{/** + * Create a specialised FTGLfont object for handling memory buffer fonts. + */} + ftglCreateBufferFont: function(_file: pchar): pFTGLfont; cdecl; + + +{/** + * Destroy an FTGL font object. + * + * @param font An FTGLfont* object. + */} + ftglDestroyFont: procedure(font: pFTGLfont); cdecl; + +{/** + * Attach auxilliary file to font e.g. font metrics. + * + * Note: not all font formats implement this function. + * + * @param font An FTGLfont* object. + * @param path Auxilliary font file path. + * @return 1 if file has been attached successfully. + */} + ftglAttachFile: function(font: pFTGLfont; path: pchar): cint; cdecl; + +{/** + * Attach auxilliary data to font, e.g. font metrics, from memory. + * + * Note: not all font formats implement this function. + * + * @param font An FTGLfont* object. + * @param data The in-memory buffer. + * @param size The length of the buffer in bytes. + * @return 1 if file has been attached successfully. + */} + ftglAttachData: function(font: pFTGLfont; data: pbyte; + size: size_t): cint; cdecl; + +{/** + * Set the character map for the face. + * + * @param font An FTGLfont* object. + * @param encoding Freetype enumerate for char map code. + * @return 1 if charmap was valid and set correctly. + */} + ftglSetFontCharMap: function(font: pFTGLfont; + encoding: cint): cint; cdecl; + +{/** + * Get the number of character maps in this face. + * + * @param font An FTGLfont* object. + * @return character map count. + */} + ftglGetFontCharMapCount: function(font: pFTGLfont): cuint; cdecl; + +{/** + * Get a list of character maps in this face. + * + * @param font An FTGLfont* object. + * @return pointer to the first encoding. + */} + ftglGetFontCharMapList: function(font: pFTGLfont): pcint; cdecl; + +{/** + * Set the char size for the current face. + * + * @param font An FTGLfont* object. + * @param size The face size in points (1/72 inch). + * @param res The resolution of the target device, or 0 to use the default + * value of 72. + * @return 1 if size was set correctly. + */} + ftglSetFontFaceSize: function(font: pFTGLfont; size: cuint; + res: cuint): cint; cdecl; + +{/** + * Get the current face size in points (1/72 inch). + * + * @param font An FTGLfont* object. + * @return face size + */} + ftglGetFontFaceSize: function(font: pFTGLfont): cuint; cdecl; + +{/** + * Set the extrusion distance for the font. Only implemented by + * FTExtrudeFont. + * + * @param font An FTGLfont* object. + * @param depth The extrusion distance. + */} + ftglSetFontDepth: procedure(font: pFTGLfont; depth: cfloat); cdecl; + +{/** + * Set the outset distance for the font. Only FTOutlineFont, FTPolygonFont + * and FTExtrudeFont implement front outset. Only FTExtrudeFont implements + * back outset. + * + * @param font An FTGLfont* object. + * @param front The front outset distance. + * @param back The back outset distance. + */} + ftglSetFontOutset: procedure(font: pFTGLfont; front: cfloat; + back: cfloat); cdecl; + +{/** + * Enable or disable the use of Display Lists inside FTGL. + * + * @param font An FTGLfont* object. + * @param useList 1 turns ON display lists. + * 0 turns OFF display lists. + */} + ftglSetFontDisplayList: procedure(font: pFTGLfont; useList: cint); cdecl; + +{/** + * Get the global ascender height for the face. + * + * @param font An FTGLfont* object. + * @return Ascender height + */} + ftglGetFontAscender: function(font: pFTGLfont): cfloat; cdecl; + +{/** + * Gets the global descender height for the face. + * + * @param font An FTGLfont* object. + * @return Descender height + */} + ftglGetFontDescender: function(font: pFTGLfont): cfloat; cdecl; + +{/** + * Gets the line spacing for the font. + * + * @param font An FTGLfont* object. + * @return Line height + */} + ftglGetFontLineHeight: function(font: pFTGLfont): cfloat; cdecl; + +{/** + * Get the bounding box for a string. + * + * @param font An FTGLfont* object. + * @param string A char buffer + * @param len The length of the string. If < 0 then all characters will be + * checked until a null character is encountered (optional). + * @param bounds An array of 6 float values where the bounding box's lower + * left near and upper right far 3D coordinates will be stored. + */} + ftglGetFontBBox: procedure(font: pFTGLfont; _string: pchar; + len: cint; out bounds: boundsty); cdecl; + +{/** + * Get the advance width for a string. + * + * @param font An FTGLfont* object. + * @param string A char string. + * @return Advance width + */} + ftglGetFontAdvance: function(font: pFTGLfont; _string: pchar): cfloat; cdecl; + +{/** + * Render a string of characters. + * + * @param font An FTGLfont* object. + * @param string Char string to be output. + * @param mode Render mode to display. + */} + ftglRenderFont: procedure(font: pFTGLfont; _string: pchar; mode: cint); cdecl; + +{/** + * Query a font for errors. + * + * @param font An FTGLfont* object. + * @return The current error code. + */} + ftglGetFontError: function(font: pFTGLfont): FT_Error; cdecl; + +procedure initializeftgl(const sonames: array of filenamety); +procedure releaseftgl; + +implementation +uses + msedynload,msesys,sysutils; +var + libinfo: dynlibinfoty; + +procedure releaseftgl; +begin + releasedynlib(libinfo); +end; + +procedure initializeftgl(const sonames: array of filenamety); +const + funcs: array[0..24] of funcinfoty = ( + (n: 'ftglCreateCustomFont'; d: @ftglCreateCustomFont), + (n: 'ftglCreateBitmapFont'; d: @ftglCreateBitmapFont), + (n: 'ftglCreatePixmapFont'; d: @ftglCreatePixmapFont), + (n: 'ftglCreateOutlineFont'; d: @ftglCreateOutlineFont), + (n: 'ftglCreatePolygonFont'; d: @ftglCreatePolygonFont), + (n: 'ftglCreateTextureFont'; d: @ftglCreateTextureFont), + (n: 'ftglCreateBufferFont'; d: @ftglCreateBufferFont), + (n: 'ftglDestroyFont'; d: @ftglDestroyFont), + (n: 'ftglAttachFile'; d: @ftglAttachFile), + (n: 'ftglAttachData'; d: @ftglAttachData), + (n: 'ftglSetFontCharMap'; d: @ftglSetFontCharMap), + (n: 'ftglGetFontCharMapCount'; d: @ftglGetFontCharMapCount), + (n: 'ftglGetFontCharMapList'; d: @ftglGetFontCharMapList), + (n: 'ftglSetFontFaceSize'; d: @ftglSetFontFaceSize), + (n: 'ftglGetFontFaceSize'; d: @ftglGetFontFaceSize), + (n: 'ftglSetFontDepth'; d: @ftglSetFontDepth), + (n: 'ftglSetFontOutset'; d: @ftglSetFontOutset), + (n: 'ftglSetFontDisplayList'; d: @ftglSetFontDisplayList), + (n: 'ftglGetFontAscender'; d: @ftglGetFontAscender), + (n: 'ftglGetFontDescender'; d: @ftglGetFontDescender), + (n: 'ftglGetFontLineHeight'; d: @ftglGetFontLineHeight), + (n: 'ftglGetFontBBox'; d: @ftglGetFontBBox), + (n: 'ftglGetFontAdvance'; d: @ftglGetFontAdvance), + (n: 'ftglRenderFont'; d: @ftglRenderFont), + (n: 'ftglGetFontError'; d: @ftglGetFontError) + ); + errormessage = 'Can not load FTGL library. '; + +begin + initializedynlib(libinfo,sonames,ftgllib,funcs,[],errormessage); +end; + +initialization + initializelibinfo(libinfo); +finalization + finalizelibinfo(libinfo); +end. diff --git a/mseide-msegui/lib/common/opengl/msegl.pas b/mseide-msegui/lib/common/opengl/msegl.pas new file mode 100644 index 0000000..a3961cd --- /dev/null +++ b/mseide-msegui/lib/common/opengl/msegl.pas @@ -0,0 +1,1987 @@ +(* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: This software was created using the +** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has +** not been independently verified as being compliant with the OpenGL(R) +** version 1.2.1 Specification. +** +** (this unit actually only contains the 1.1 parts of the specification, +** the parts from the subsequence versions are in glext.pp) +*) + +{******************************************************************************} +{ Converted to Delphi by Tom Nuydens (tom@delphi3d.net) } +{******************************************************************************} + +{ modified 2011-2018 by Martin Schreiber } + + +{******************************************************************************} +{ Converted to Delphi by Tom Nuydens (tom@delphi3d.net) } +{ For the latest updates, visit Delphi3D: http://www.delphi3d.net } +{******************************************************************************} + +//{$MODE Delphi} +{$ifdef FPC}{$mode objfpc} {$h+}{$endif} +//{$macro on} +{$ifdef mswindows} + {$define wincall} +// {$define extdecl := stdcall} +{$else} +// {$define extdecl := cdecl} +{$endif} + +unit msegl; + +interface + +uses + SysUtils,msetypes,msestrings{$ifdef mswindows},windows{$endif}, + msedynload,mseglextglob; + +const +{$ifdef mswindows} + opengllib: array[0..0] of filenamety = ('opengl32.dll'); +{$else} + opengllib: array[0..1] of filenamety = ('libGL.so.1','libGL.so'); +{$endif} + +type + GLenum = Cardinal; PGLenum = ^GLenum; + GLboolean = Byte; PGLboolean = ^GLboolean; + GLbitfield = Cardinal; PGLbitfield = ^GLbitfield; + GLbyte = ShortInt; PGLbyte = ^GLbyte; + GLshort = SmallInt; PGLshort = ^GLshort; + GLint = Integer; PGLint = ^GLint; + GLsizei = Integer; PGLsizei = ^GLsizei; + GLubyte = Byte; PGLubyte = ^GLubyte; + GLushort = Word; PGLushort = ^GLushort; + GLuint = Cardinal; PGLuint = ^GLuint; + GLfloat = Single; PGLfloat = ^GLfloat; + GLclampf = Single; PGLclampf = ^GLclampf; + GLdouble = Double; PGLdouble = ^GLdouble; + GLclampd = Double; PGLclampd = ^GLclampd; +{ GLvoid = void; } PGLvoid = Pointer; + PPGLvoid = ^PGLvoid; + + TGLenum = GLenum; + TGLboolean = GLboolean; + TGLbitfield = GLbitfield; + TGLbyte = GLbyte; + TGLshort = GLshort; + TGLint = GLint; + TGLsizei = GLsizei; + TGLubyte = GLubyte; + TGLushort = GLushort; + TGLuint = GLuint; + TGLfloat = GLfloat; + TGLclampf = GLclampf; + TGLdouble = GLdouble; + TGLclampd = GLclampd; + +{******************************************************************************} + +const + // Version + GL_VERSION_1_1 = 1; + + // AccumOp + GL_ACCUM = $0100; + GL_LOAD = $0101; + GL_RETURN = $0102; + GL_MULT = $0103; + GL_ADD = $0104; + + // AlphaFunction + GL_NEVER = $0200; + GL_LESS = $0201; + GL_EQUAL = $0202; + GL_LEQUAL = $0203; + GL_GREATER = $0204; + GL_NOTEQUAL = $0205; + GL_GEQUAL = $0206; + GL_ALWAYS = $0207; + + // AttribMask + GL_CURRENT_BIT = $00000001; + GL_POINT_BIT = $00000002; + GL_LINE_BIT = $00000004; + GL_POLYGON_BIT = $00000008; + GL_POLYGON_STIPPLE_BIT = $00000010; + GL_PIXEL_MODE_BIT = $00000020; + GL_LIGHTING_BIT = $00000040; + GL_FOG_BIT = $00000080; + GL_DEPTH_BUFFER_BIT = $00000100; + GL_ACCUM_BUFFER_BIT = $00000200; + GL_STENCIL_BUFFER_BIT = $00000400; + GL_VIEWPORT_BIT = $00000800; + GL_TRANSFORM_BIT = $00001000; + GL_ENABLE_BIT = $00002000; + GL_COLOR_BUFFER_BIT = $00004000; + GL_HINT_BIT = $00008000; + GL_EVAL_BIT = $00010000; + GL_LIST_BIT = $00020000; + GL_TEXTURE_BIT = $00040000; + GL_SCISSOR_BIT = $00080000; + GL_ALL_ATTRIB_BITS = $000FFFFF; + + // BeginMode + GL_POINTS = $0000; + GL_LINES = $0001; + GL_LINE_LOOP = $0002; + GL_LINE_STRIP = $0003; + GL_TRIANGLES = $0004; + GL_TRIANGLE_STRIP = $0005; + GL_TRIANGLE_FAN = $0006; + GL_QUADS = $0007; + GL_QUAD_STRIP = $0008; + GL_POLYGON = $0009; + + // BlendingFactorDest + GL_ZERO = 0; + GL_ONE = 1; + GL_SRC_COLOR = $0300; + GL_ONE_MINUS_SRC_COLOR = $0301; + GL_SRC_ALPHA = $0302; + GL_ONE_MINUS_SRC_ALPHA = $0303; + GL_DST_ALPHA = $0304; + GL_ONE_MINUS_DST_ALPHA = $0305; + + // BlendingFactorSrc + // GL_ZERO + // GL_ONE + GL_DST_COLOR = $0306; + GL_ONE_MINUS_DST_COLOR = $0307; + GL_SRC_ALPHA_SATURATE = $0308; + // GL_SRC_ALPHA + // GL_ONE_MINUS_SRC_ALPHA + // GL_DST_ALPHA + // GL_ONE_MINUS_DST_ALPHA + + // Boolean + GL_TRUE = 1; + GL_FALSE = 0; + + // ClearBufferMask + // GL_COLOR_BUFFER_BIT + // GL_ACCUM_BUFFER_BIT + // GL_STENCIL_BUFFER_BIT + // GL_DEPTH_BUFFER_BIT + + // ClientArrayType + // GL_VERTEX_ARRAY + // GL_NORMAL_ARRAY + // GL_COLOR_ARRAY + // GL_INDEX_ARRAY + // GL_TEXTURE_COORD_ARRAY + // GL_EDGE_FLAG_ARRAY + + // ClipPlaneName + GL_CLIP_PLANE0 = $3000; + GL_CLIP_PLANE1 = $3001; + GL_CLIP_PLANE2 = $3002; + GL_CLIP_PLANE3 = $3003; + GL_CLIP_PLANE4 = $3004; + GL_CLIP_PLANE5 = $3005; + + // ColorMaterialFace + // GL_FRONT + // GL_BACK + // GL_FRONT_AND_BACK + + // ColorMaterialParameter + // GL_AMBIENT + // GL_DIFFUSE + // GL_SPECULAR + // GL_EMISSION + // GL_AMBIENT_AND_DIFFUSE + + // ColorPointerType + // GL_BYTE + // GL_UNSIGNED_BYTE + // GL_SHORT + // GL_UNSIGNED_SHORT + // GL_INT + // GL_UNSIGNED_INT + // GL_FLOAT + // GL_DOUBLE + + // CullFaceMode + // GL_FRONT + // GL_BACK + // GL_FRONT_AND_BACK + + // DataType + GL_BYTE = $1400; + GL_UNSIGNED_BYTE = $1401; + GL_SHORT = $1402; + GL_UNSIGNED_SHORT = $1403; + GL_INT = $1404; + GL_UNSIGNED_INT = $1405; + GL_FLOAT = $1406; + GL_2_BYTES = $1407; + GL_3_BYTES = $1408; + GL_4_BYTES = $1409; + GL_DOUBLE = $140A; + + // DepthFunction + // GL_NEVER + // GL_LESS + // GL_EQUAL + // GL_LEQUAL + // GL_GREATER + // GL_NOTEQUAL + // GL_GEQUAL + // GL_ALWAYS + + // DrawBufferMode + GL_NONE = 0; + GL_FRONT_LEFT = $0400; + GL_FRONT_RIGHT = $0401; + GL_BACK_LEFT = $0402; + GL_BACK_RIGHT = $0403; + GL_FRONT = $0404; + GL_BACK = $0405; + GL_LEFT = $0406; + GL_RIGHT = $0407; + GL_FRONT_AND_BACK = $0408; + GL_AUX0 = $0409; + GL_AUX1 = $040A; + GL_AUX2 = $040B; + GL_AUX3 = $040C; + + // Enable + // GL_FOG + // GL_LIGHTING + // GL_TEXTURE_1D + // GL_TEXTURE_2D + // GL_LINE_STIPPLE + // GL_POLYGON_STIPPLE + // GL_CULL_FACE + // GL_ALPHA_TEST + // GL_BLEND + // GL_INDEX_LOGIC_OP + // GL_COLOR_LOGIC_OP + // GL_DITHER + // GL_STENCIL_TEST + // GL_DEPTH_TEST + // GL_CLIP_PLANE0 + // GL_CLIP_PLANE1 + // GL_CLIP_PLANE2 + // GL_CLIP_PLANE3 + // GL_CLIP_PLANE4 + // GL_CLIP_PLANE5 + // GL_LIGHT0 + // GL_LIGHT1 + // GL_LIGHT2 + // GL_LIGHT3 + // GL_LIGHT4 + // GL_LIGHT5 + // GL_LIGHT6 + // GL_LIGHT7 + // GL_TEXTURE_GEN_S + // GL_TEXTURE_GEN_T + // GL_TEXTURE_GEN_R + // GL_TEXTURE_GEN_Q + // GL_MAP1_VERTEX_3 + // GL_MAP1_VERTEX_4 + // GL_MAP1_COLOR_4 + // GL_MAP1_INDEX + // GL_MAP1_NORMAL + // GL_MAP1_TEXTURE_COORD_1 + // GL_MAP1_TEXTURE_COORD_2 + // GL_MAP1_TEXTURE_COORD_3 + // GL_MAP1_TEXTURE_COORD_4 + // GL_MAP2_VERTEX_3 + // GL_MAP2_VERTEX_4 + // GL_MAP2_COLOR_4 + // GL_MAP2_INDEX + // GL_MAP2_NORMAL + // GL_MAP2_TEXTURE_COORD_1 + // GL_MAP2_TEXTURE_COORD_2 + // GL_MAP2_TEXTURE_COORD_3 + // GL_MAP2_TEXTURE_COORD_4 + // GL_POINT_SMOOTH + // GL_LINE_SMOOTH + // GL_POLYGON_SMOOTH + // GL_SCISSOR_TEST + // GL_COLOR_MATERIAL + // GL_NORMALIZE + // GL_AUTO_NORMAL + // GL_VERTEX_ARRAY + // GL_NORMAL_ARRAY + // GL_COLOR_ARRAY + // GL_INDEX_ARRAY + // GL_TEXTURE_COORD_ARRAY + // GL_EDGE_FLAG_ARRAY + // GL_POLYGON_OFFSET_POINT + // GL_POLYGON_OFFSET_LINE + // GL_POLYGON_OFFSET_FILL + + // ErrorCode + GL_NO_ERROR = 0; + GL_INVALID_ENUM = $0500; + GL_INVALID_VALUE = $0501; + GL_INVALID_OPERATION = $0502; + GL_STACK_OVERFLOW = $0503; + GL_STACK_UNDERFLOW = $0504; + GL_OUT_OF_MEMORY = $0505; + + // FeedBackMode + GL_2D = $0600; + GL_3D = $0601; + GL_3D_COLOR = $0602; + GL_3D_COLOR_TEXTURE = $0603; + GL_4D_COLOR_TEXTURE = $0604; + + // FeedBackToken + GL_PASS_THROUGH_TOKEN = $0700; + GL_POINT_TOKEN = $0701; + GL_LINE_TOKEN = $0702; + GL_POLYGON_TOKEN = $0703; + GL_BITMAP_TOKEN = $0704; + GL_DRAW_PIXEL_TOKEN = $0705; + GL_COPY_PIXEL_TOKEN = $0706; + GL_LINE_RESET_TOKEN = $0707; + + // FogMode + // GL_LINEAR + GL_EXP = $0800; + GL_EXP2 = $0801; + + // FogParameter + // GL_FOG_COLOR + // GL_FOG_DENSITY + // GL_FOG_END + // GL_FOG_INDEX + // GL_FOG_MODE + // GL_FOG_START + + // FrontFaceDirection + GL_CW = $0900; + GL_CCW = $0901; + + // GetMapTarget + GL_COEFF = $0A00; + GL_ORDER = $0A01; + GL_DOMAIN = $0A02; + + // GetPixelMap + // GL_PIXEL_MAP_I_TO_I + // GL_PIXEL_MAP_S_TO_S + // GL_PIXEL_MAP_I_TO_R + // GL_PIXEL_MAP_I_TO_G + // GL_PIXEL_MAP_I_TO_B + // GL_PIXEL_MAP_I_TO_A + // GL_PIXEL_MAP_R_TO_R + // GL_PIXEL_MAP_G_TO_G + // GL_PIXEL_MAP_B_TO_B + // GL_PIXEL_MAP_A_TO_A + + // GetPointerTarget + // GL_VERTEX_ARRAY_POINTER + // GL_NORMAL_ARRAY_POINTER + // GL_COLOR_ARRAY_POINTER + // GL_INDEX_ARRAY_POINTER + // GL_TEXTURE_COORD_ARRAY_POINTER + // GL_EDGE_FLAG_ARRAY_POINTER + + // GetTarget + GL_CURRENT_COLOR = $0B00; + GL_CURRENT_INDEX = $0B01; + GL_CURRENT_NORMAL = $0B02; + GL_CURRENT_TEXTURE_COORDS = $0B03; + GL_CURRENT_RASTER_COLOR = $0B04; + GL_CURRENT_RASTER_INDEX = $0B05; + GL_CURRENT_RASTER_TEXTURE_COORDS = $0B06; + GL_CURRENT_RASTER_POSITION = $0B07; + GL_CURRENT_RASTER_POSITION_VALID = $0B08; + GL_CURRENT_RASTER_DISTANCE = $0B09; + GL_POINT_SMOOTH = $0B10; + GL_POINT_SIZE = $0B11; + GL_POINT_SIZE_RANGE = $0B12; + GL_POINT_SIZE_GRANULARITY = $0B13; + GL_LINE_SMOOTH = $0B20; + GL_LINE_WIDTH = $0B21; + GL_LINE_WIDTH_RANGE = $0B22; + GL_LINE_WIDTH_GRANULARITY = $0B23; + GL_LINE_STIPPLE = $0B24; + GL_LINE_STIPPLE_PATTERN = $0B25; + GL_LINE_STIPPLE_REPEAT = $0B26; + GL_LIST_MODE = $0B30; + GL_MAX_LIST_NESTING = $0B31; + GL_LIST_BASE = $0B32; + GL_LIST_INDEX = $0B33; + GL_POLYGON_MODE = $0B40; + GL_POLYGON_SMOOTH = $0B41; + GL_POLYGON_STIPPLE = $0B42; + GL_EDGE_FLAG = $0B43; + GL_CULL_FACE = $0B44; + GL_CULL_FACE_MODE = $0B45; + GL_FRONT_FACE = $0B46; + GL_LIGHTING = $0B50; + GL_LIGHT_MODEL_LOCAL_VIEWER = $0B51; + GL_LIGHT_MODEL_TWO_SIDE = $0B52; + GL_LIGHT_MODEL_AMBIENT = $0B53; + GL_SHADE_MODEL = $0B54; + GL_COLOR_MATERIAL_FACE = $0B55; + GL_COLOR_MATERIAL_PARAMETER = $0B56; + GL_COLOR_MATERIAL = $0B57; + GL_FOG = $0B60; + GL_FOG_INDEX = $0B61; + GL_FOG_DENSITY = $0B62; + GL_FOG_START = $0B63; + GL_FOG_END = $0B64; + GL_FOG_MODE = $0B65; + GL_FOG_COLOR = $0B66; + GL_DEPTH_RANGE = $0B70; + GL_DEPTH_TEST = $0B71; + GL_DEPTH_WRITEMASK = $0B72; + GL_DEPTH_CLEAR_VALUE = $0B73; + GL_DEPTH_FUNC = $0B74; + GL_ACCUM_CLEAR_VALUE = $0B80; + GL_STENCIL_TEST = $0B90; + GL_STENCIL_CLEAR_VALUE = $0B91; + GL_STENCIL_FUNC = $0B92; + GL_STENCIL_VALUE_MASK = $0B93; + GL_STENCIL_FAIL = $0B94; + GL_STENCIL_PASS_DEPTH_FAIL = $0B95; + GL_STENCIL_PASS_DEPTH_PASS = $0B96; + GL_STENCIL_REF = $0B97; + GL_STENCIL_WRITEMASK = $0B98; + GL_MATRIX_MODE = $0BA0; + GL_NORMALIZE = $0BA1; + GL_VIEWPORT = $0BA2; + GL_MODELVIEW_STACK_DEPTH = $0BA3; + GL_PROJECTION_STACK_DEPTH = $0BA4; + GL_TEXTURE_STACK_DEPTH = $0BA5; + GL_MODELVIEW_MATRIX = $0BA6; + GL_PROJECTION_MATRIX = $0BA7; + GL_TEXTURE_MATRIX = $0BA8; + GL_ATTRIB_STACK_DEPTH = $0BB0; + GL_CLIENT_ATTRIB_STACK_DEPTH = $0BB1; + GL_ALPHA_TEST = $0BC0; + GL_ALPHA_TEST_FUNC = $0BC1; + GL_ALPHA_TEST_REF = $0BC2; + GL_DITHER = $0BD0; + GL_BLEND_DST = $0BE0; + GL_BLEND_SRC = $0BE1; + GL_BLEND = $0BE2; + GL_LOGIC_OP_MODE = $0BF0; + GL_INDEX_LOGIC_OP = $0BF1; + GL_COLOR_LOGIC_OP = $0BF2; + GL_AUX_BUFFERS = $0C00; + GL_DRAW_BUFFER = $0C01; + GL_READ_BUFFER = $0C02; + GL_SCISSOR_BOX = $0C10; + GL_SCISSOR_TEST = $0C11; + GL_INDEX_CLEAR_VALUE = $0C20; + GL_INDEX_WRITEMASK = $0C21; + GL_COLOR_CLEAR_VALUE = $0C22; + GL_COLOR_WRITEMASK = $0C23; + GL_INDEX_MODE = $0C30; + GL_RGBA_MODE = $0C31; + GL_DOUBLEBUFFER = $0C32; + GL_STEREO = $0C33; + GL_RENDER_MODE = $0C40; + GL_PERSPECTIVE_CORRECTION_HINT = $0C50; + GL_POINT_SMOOTH_HINT = $0C51; + GL_LINE_SMOOTH_HINT = $0C52; + GL_POLYGON_SMOOTH_HINT = $0C53; + GL_FOG_HINT = $0C54; + GL_TEXTURE_GEN_S = $0C60; + GL_TEXTURE_GEN_T = $0C61; + GL_TEXTURE_GEN_R = $0C62; + GL_TEXTURE_GEN_Q = $0C63; + GL_PIXEL_MAP_I_TO_I = $0C70; + GL_PIXEL_MAP_S_TO_S = $0C71; + GL_PIXEL_MAP_I_TO_R = $0C72; + GL_PIXEL_MAP_I_TO_G = $0C73; + GL_PIXEL_MAP_I_TO_B = $0C74; + GL_PIXEL_MAP_I_TO_A = $0C75; + GL_PIXEL_MAP_R_TO_R = $0C76; + GL_PIXEL_MAP_G_TO_G = $0C77; + GL_PIXEL_MAP_B_TO_B = $0C78; + GL_PIXEL_MAP_A_TO_A = $0C79; + GL_PIXEL_MAP_I_TO_I_SIZE = $0CB0; + GL_PIXEL_MAP_S_TO_S_SIZE = $0CB1; + GL_PIXEL_MAP_I_TO_R_SIZE = $0CB2; + GL_PIXEL_MAP_I_TO_G_SIZE = $0CB3; + GL_PIXEL_MAP_I_TO_B_SIZE = $0CB4; + GL_PIXEL_MAP_I_TO_A_SIZE = $0CB5; + GL_PIXEL_MAP_R_TO_R_SIZE = $0CB6; + GL_PIXEL_MAP_G_TO_G_SIZE = $0CB7; + GL_PIXEL_MAP_B_TO_B_SIZE = $0CB8; + GL_PIXEL_MAP_A_TO_A_SIZE = $0CB9; + GL_UNPACK_SWAP_BYTES = $0CF0; + GL_UNPACK_LSB_FIRST = $0CF1; + GL_UNPACK_ROW_LENGTH = $0CF2; + GL_UNPACK_SKIP_ROWS = $0CF3; + GL_UNPACK_SKIP_PIXELS = $0CF4; + GL_UNPACK_ALIGNMENT = $0CF5; + GL_PACK_SWAP_BYTES = $0D00; + GL_PACK_LSB_FIRST = $0D01; + GL_PACK_ROW_LENGTH = $0D02; + GL_PACK_SKIP_ROWS = $0D03; + GL_PACK_SKIP_PIXELS = $0D04; + GL_PACK_ALIGNMENT = $0D05; + GL_MAP_COLOR = $0D10; + GL_MAP_STENCIL = $0D11; + GL_INDEX_SHIFT = $0D12; + GL_INDEX_OFFSET = $0D13; + GL_RED_SCALE = $0D14; + GL_RED_BIAS = $0D15; + GL_ZOOM_X = $0D16; + GL_ZOOM_Y = $0D17; + GL_GREEN_SCALE = $0D18; + GL_GREEN_BIAS = $0D19; + GL_BLUE_SCALE = $0D1A; + GL_BLUE_BIAS = $0D1B; + GL_ALPHA_SCALE = $0D1C; + GL_ALPHA_BIAS = $0D1D; + GL_DEPTH_SCALE = $0D1E; + GL_DEPTH_BIAS = $0D1F; + GL_MAX_EVAL_ORDER = $0D30; + GL_MAX_LIGHTS = $0D31; + GL_MAX_CLIP_PLANES = $0D32; + GL_MAX_TEXTURE_SIZE = $0D33; + GL_MAX_PIXEL_MAP_TABLE = $0D34; + GL_MAX_ATTRIB_STACK_DEPTH = $0D35; + GL_MAX_MODELVIEW_STACK_DEPTH = $0D36; + GL_MAX_NAME_STACK_DEPTH = $0D37; + GL_MAX_PROJECTION_STACK_DEPTH = $0D38; + GL_MAX_TEXTURE_STACK_DEPTH = $0D39; + GL_MAX_VIEWPORT_DIMS = $0D3A; + GL_MAX_CLIENT_ATTRIB_STACK_DEPTH = $0D3B; + GL_SUBPIXEL_BITS = $0D50; + GL_INDEX_BITS = $0D51; + GL_RED_BITS = $0D52; + GL_GREEN_BITS = $0D53; + GL_BLUE_BITS = $0D54; + GL_ALPHA_BITS = $0D55; + GL_DEPTH_BITS = $0D56; + GL_STENCIL_BITS = $0D57; + GL_ACCUM_RED_BITS = $0D58; + GL_ACCUM_GREEN_BITS = $0D59; + GL_ACCUM_BLUE_BITS = $0D5A; + GL_ACCUM_ALPHA_BITS = $0D5B; + GL_NAME_STACK_DEPTH = $0D70; + GL_AUTO_NORMAL = $0D80; + GL_MAP1_COLOR_4 = $0D90; + GL_MAP1_INDEX = $0D91; + GL_MAP1_NORMAL = $0D92; + GL_MAP1_TEXTURE_COORD_1 = $0D93; + GL_MAP1_TEXTURE_COORD_2 = $0D94; + GL_MAP1_TEXTURE_COORD_3 = $0D95; + GL_MAP1_TEXTURE_COORD_4 = $0D96; + GL_MAP1_VERTEX_3 = $0D97; + GL_MAP1_VERTEX_4 = $0D98; + GL_MAP2_COLOR_4 = $0DB0; + GL_MAP2_INDEX = $0DB1; + GL_MAP2_NORMAL = $0DB2; + GL_MAP2_TEXTURE_COORD_1 = $0DB3; + GL_MAP2_TEXTURE_COORD_2 = $0DB4; + GL_MAP2_TEXTURE_COORD_3 = $0DB5; + GL_MAP2_TEXTURE_COORD_4 = $0DB6; + GL_MAP2_VERTEX_3 = $0DB7; + GL_MAP2_VERTEX_4 = $0DB8; + GL_MAP1_GRID_DOMAIN = $0DD0; + GL_MAP1_GRID_SEGMENTS = $0DD1; + GL_MAP2_GRID_DOMAIN = $0DD2; + GL_MAP2_GRID_SEGMENTS = $0DD3; + GL_TEXTURE_1D = $0DE0; + GL_TEXTURE_2D = $0DE1; + GL_FEEDBACK_BUFFER_POINTER = $0DF0; + GL_FEEDBACK_BUFFER_SIZE = $0DF1; + GL_FEEDBACK_BUFFER_TYPE = $0DF2; + GL_SELECTION_BUFFER_POINTER = $0DF3; + GL_SELECTION_BUFFER_SIZE = $0DF4; + // GL_TEXTURE_BINDING_1D + // GL_TEXTURE_BINDING_2D + // GL_VERTEX_ARRAY + // GL_NORMAL_ARRAY + // GL_COLOR_ARRAY + // GL_INDEX_ARRAY + // GL_TEXTURE_COORD_ARRAY + // GL_EDGE_FLAG_ARRAY + // GL_VERTEX_ARRAY_SIZE + // GL_VERTEX_ARRAY_TYPE + // GL_VERTEX_ARRAY_STRIDE + // GL_NORMAL_ARRAY_TYPE + // GL_NORMAL_ARRAY_STRIDE + // GL_COLOR_ARRAY_SIZE + // GL_COLOR_ARRAY_TYPE + // GL_COLOR_ARRAY_STRIDE + // GL_INDEX_ARRAY_TYPE + // GL_INDEX_ARRAY_STRIDE + // GL_TEXTURE_COORD_ARRAY_SIZE + // GL_TEXTURE_COORD_ARRAY_TYPE + // GL_TEXTURE_COORD_ARRAY_STRIDE + // GL_EDGE_FLAG_ARRAY_STRIDE + // GL_POLYGON_OFFSET_FACTOR + // GL_POLYGON_OFFSET_UNITS + + // GetTextureParameter + // GL_TEXTURE_MAG_FILTER + // GL_TEXTURE_MIN_FILTER + // GL_TEXTURE_WRAP_S + // GL_TEXTURE_WRAP_T + GL_TEXTURE_WIDTH = $1000; + GL_TEXTURE_HEIGHT = $1001; + GL_TEXTURE_INTERNAL_FORMAT = $1003; + GL_TEXTURE_BORDER_COLOR = $1004; + GL_TEXTURE_BORDER = $1005; + // GL_TEXTURE_RED_SIZE + // GL_TEXTURE_GREEN_SIZE + // GL_TEXTURE_BLUE_SIZE + // GL_TEXTURE_ALPHA_SIZE + // GL_TEXTURE_LUMINANCE_SIZE + // GL_TEXTURE_INTENSITY_SIZE + // GL_TEXTURE_PRIORITY + // GL_TEXTURE_RESIDENT + + // HintMode + GL_DONT_CARE = $1100; + GL_FASTEST = $1101; + GL_NICEST = $1102; + + // HintTarget + // GL_PERSPECTIVE_CORRECTION_HINT + // GL_POINT_SMOOTH_HINT + // GL_LINE_SMOOTH_HINT + // GL_POLYGON_SMOOTH_HINT + // GL_FOG_HINT + + // IndexPointerType + // GL_SHORT + // GL_INT + // GL_FLOAT + // GL_DOUBLE + + // LightModelParameter + // GL_LIGHT_MODEL_AMBIENT + // GL_LIGHT_MODEL_LOCAL_VIEWER + // GL_LIGHT_MODEL_TWO_SIDE + + // LightName + GL_LIGHT0 = $4000; + GL_LIGHT1 = $4001; + GL_LIGHT2 = $4002; + GL_LIGHT3 = $4003; + GL_LIGHT4 = $4004; + GL_LIGHT5 = $4005; + GL_LIGHT6 = $4006; + GL_LIGHT7 = $4007; + + // LightParameter + GL_AMBIENT = $1200; + GL_DIFFUSE = $1201; + GL_SPECULAR = $1202; + GL_POSITION = $1203; + GL_SPOT_DIRECTION = $1204; + GL_SPOT_EXPONENT = $1205; + GL_SPOT_CUTOFF = $1206; + GL_CONSTANT_ATTENUATION = $1207; + GL_LINEAR_ATTENUATION = $1208; + GL_QUADRATIC_ATTENUATION = $1209; + + // InterleavedArrays + // GL_V2F + // GL_V3F + // GL_C4UB_V2F + // GL_C4UB_V3F + // GL_C3F_V3F + // GL_N3F_V3F + // GL_C4F_N3F_V3F + // GL_T2F_V3F + // GL_T4F_V4F + // GL_T2F_C4UB_V3F + // GL_T2F_C3F_V3F + // GL_T2F_N3F_V3F + // GL_T2F_C4F_N3F_V3F + // GL_T4F_C4F_N3F_V4F + + // ListMode + GL_COMPILE = $1300; + GL_COMPILE_AND_EXECUTE = $1301; + + // ListNameType + // GL_BYTE + // GL_UNSIGNED_BYTE + // GL_SHORT + // GL_UNSIGNED_SHORT + // GL_INT + // GL_UNSIGNED_INT + // GL_FLOAT + // GL_2_BYTES + // GL_3_BYTES + // GL_4_BYTES + + // LogicOp + GL_CLEAR = $1500; + GL_AND = $1501; + GL_AND_REVERSE = $1502; + GL_COPY = $1503; + GL_AND_INVERTED = $1504; + GL_NOOP = $1505; + GL_XOR = $1506; + GL_OR = $1507; + GL_NOR = $1508; + GL_EQUIV = $1509; + GL_INVERT = $150A; + GL_OR_REVERSE = $150B; + GL_COPY_INVERTED = $150C; + GL_OR_INVERTED = $150D; + GL_NAND = $150E; + GL_SET = $150F; + + // MapTarget + // GL_MAP1_COLOR_4 + // GL_MAP1_INDEX + // GL_MAP1_NORMAL + // GL_MAP1_TEXTURE_COORD_1 + // GL_MAP1_TEXTURE_COORD_2 + // GL_MAP1_TEXTURE_COORD_3 + // GL_MAP1_TEXTURE_COORD_4 + // GL_MAP1_VERTEX_3 + // GL_MAP1_VERTEX_4 + // GL_MAP2_COLOR_4 + // GL_MAP2_INDEX + // GL_MAP2_NORMAL + // GL_MAP2_TEXTURE_COORD_1 + // GL_MAP2_TEXTURE_COORD_2 + // GL_MAP2_TEXTURE_COORD_3 + // GL_MAP2_TEXTURE_COORD_4 + // GL_MAP2_VERTEX_3 + // GL_MAP2_VERTEX_4 + + // MaterialFace + // GL_FRONT + // GL_BACK + // GL_FRONT_AND_BACK + + // MaterialParameter + GL_EMISSION = $1600; + GL_SHININESS = $1601; + GL_AMBIENT_AND_DIFFUSE = $1602; + GL_COLOR_INDEXES = $1603; + // GL_AMBIENT + // GL_DIFFUSE + // GL_SPECULAR + + // MatrixMode + GL_MODELVIEW = $1700; + GL_PROJECTION = $1701; + GL_TEXTURE = $1702; + + // MeshMode1 + // GL_POINT + // GL_LINE + + // MeshMode2 + // GL_POINT + // GL_LINE + // GL_FILL + + // NormalPointerType + // GL_BYTE + // GL_SHORT + // GL_INT + // GL_FLOAT + // GL_DOUBLE + + // PixelCopyType + GL_COLOR = $1800; + GL_DEPTH = $1801; + GL_STENCIL = $1802; + + // PixelFormat + GL_COLOR_INDEX = $1900; + GL_STENCIL_INDEX = $1901; + GL_DEPTH_COMPONENT = $1902; + GL_RED = $1903; + GL_GREEN = $1904; + GL_BLUE = $1905; + GL_ALPHA = $1906; + GL_RGB = $1907; + GL_RGBA = $1908; + GL_LUMINANCE = $1909; + GL_LUMINANCE_ALPHA = $190A; + + // PixelMap + // GL_PIXEL_MAP_I_TO_I + // GL_PIXEL_MAP_S_TO_S + // GL_PIXEL_MAP_I_TO_R + // GL_PIXEL_MAP_I_TO_G + // GL_PIXEL_MAP_I_TO_B + // GL_PIXEL_MAP_I_TO_A + // GL_PIXEL_MAP_R_TO_R + // GL_PIXEL_MAP_G_TO_G + // GL_PIXEL_MAP_B_TO_B + // GL_PIXEL_MAP_A_TO_A + + // PixelStore + // GL_UNPACK_SWAP_BYTES + // GL_UNPACK_LSB_FIRST + // GL_UNPACK_ROW_LENGTH + // GL_UNPACK_SKIP_ROWS + // GL_UNPACK_SKIP_PIXELS + // GL_UNPACK_ALIGNMENT + // GL_PACK_SWAP_BYTES + // GL_PACK_LSB_FIRST + // GL_PACK_ROW_LENGTH + // GL_PACK_SKIP_ROWS + // GL_PACK_SKIP_PIXELS + // GL_PACK_ALIGNMENT + + // PixelTransfer + // GL_MAP_COLOR + // GL_MAP_STENCIL + // GL_INDEX_SHIFT + // GL_INDEX_OFFSET + // GL_RED_SCALE + // GL_RED_BIAS + // GL_GREEN_SCALE + // GL_GREEN_BIAS + // GL_BLUE_SCALE + // GL_BLUE_BIAS + // GL_ALPHA_SCALE + // GL_ALPHA_BIAS + // GL_DEPTH_SCALE + // GL_DEPTH_BIAS + + // PixelType + GL_BITMAP = $1A00; + // GL_BYTE + // GL_UNSIGNED_BYTE + // GL_SHORT + // GL_UNSIGNED_SHORT + // GL_INT + // GL_UNSIGNED_INT + // GL_FLOAT + + // PolygonMode + GL_POINT = $1B00; + GL_LINE = $1B01; + GL_FILL = $1B02; + + // ReadBufferMode + // GL_FRONT_LEFT + // GL_FRONT_RIGHT + // GL_BACK_LEFT + // GL_BACK_RIGHT + // GL_FRONT + // GL_BACK + // GL_LEFT + // GL_RIGHT + // GL_AUX0 + // GL_AUX1 + // GL_AUX2 + // GL_AUX3 + + // RenderingMode + GL_RENDER = $1C00; + GL_FEEDBACK = $1C01; + GL_SELECT = $1C02; + + // ShadingModel + GL_FLAT = $1D00; + GL_SMOOTH = $1D01; + + // StencilFunction + // GL_NEVER + // GL_LESS + // GL_EQUAL + // GL_LEQUAL + // GL_GREATER + // GL_NOTEQUAL + // GL_GEQUAL + // GL_ALWAYS + + // StencilOp + // GL_ZERO + GL_KEEP = $1E00; + GL_REPLACE = $1E01; + GL_INCR = $1E02; + GL_DECR = $1E03; + // GL_INVERT + + // StringName + GL_VENDOR = $1F00; + GL_RENDERER = $1F01; + GL_VERSION = $1F02; + GL_EXTENSIONS = $1F03; + + // TextureCoordName + GL_S = $2000; + GL_T = $2001; + GL_R = $2002; + GL_Q = $2003; + + // TexCoordPointerType + // GL_SHORT + // GL_INT + // GL_FLOAT + // GL_DOUBLE + + // TextureEnvMode + GL_MODULATE = $2100; + GL_DECAL = $2101; + // GL_BLEND + // GL_REPLACE + + // TextureEnvParameter + GL_TEXTURE_ENV_MODE = $2200; + GL_TEXTURE_ENV_COLOR = $2201; + + // TextureEnvTarget + GL_TEXTURE_ENV = $2300; + + // TextureGenMode + GL_EYE_LINEAR = $2400; + GL_OBJECT_LINEAR = $2401; + GL_SPHERE_MAP = $2402; + + // TextureGenParameter + GL_TEXTURE_GEN_MODE = $2500; + GL_OBJECT_PLANE = $2501; + GL_EYE_PLANE = $2502; + + // TextureMagFilter + GL_NEAREST = $2600; + GL_LINEAR = $2601; + + // TextureMinFilter + // GL_NEAREST + // GL_LINEAR + GL_NEAREST_MIPMAP_NEAREST = $2700; + GL_LINEAR_MIPMAP_NEAREST = $2701; + GL_NEAREST_MIPMAP_LINEAR = $2702; + GL_LINEAR_MIPMAP_LINEAR = $2703; + + // TextureParameterName + GL_TEXTURE_MAG_FILTER = $2800; + GL_TEXTURE_MIN_FILTER = $2801; + GL_TEXTURE_WRAP_S = $2802; + GL_TEXTURE_WRAP_T = $2803; + // GL_TEXTURE_BORDER_COLOR + // GL_TEXTURE_PRIORITY + + // TextureTarget + // GL_TEXTURE_1D + // GL_TEXTURE_2D + // GL_PROXY_TEXTURE_1D + // GL_PROXY_TEXTURE_2D + + // TextureWrapMode + GL_CLAMP = $2900; + GL_REPEAT = $2901; + + // VertexPointerType + // GL_SHORT + // GL_INT + // GL_FLOAT + // GL_DOUBLE + + // ClientAttribMask + GL_CLIENT_PIXEL_STORE_BIT = $00000001; + GL_CLIENT_VERTEX_ARRAY_BIT = $00000002; + GL_CLIENT_ALL_ATTRIB_BITS = $FFFFFFFF; + + // polygon_offset + GL_POLYGON_OFFSET_FACTOR = $8038; + GL_POLYGON_OFFSET_UNITS = $2A00; + GL_POLYGON_OFFSET_POINT = $2A01; + GL_POLYGON_OFFSET_LINE = $2A02; + GL_POLYGON_OFFSET_FILL = $8037; + + // texture + GL_ALPHA4 = $803B; + GL_ALPHA8 = $803C; + GL_ALPHA12 = $803D; + GL_ALPHA16 = $803E; + GL_LUMINANCE4 = $803F; + GL_LUMINANCE8 = $8040; + GL_LUMINANCE12 = $8041; + GL_LUMINANCE16 = $8042; + GL_LUMINANCE4_ALPHA4 = $8043; + GL_LUMINANCE6_ALPHA2 = $8044; + GL_LUMINANCE8_ALPHA8 = $8045; + GL_LUMINANCE12_ALPHA4 = $8046; + GL_LUMINANCE12_ALPHA12 = $8047; + GL_LUMINANCE16_ALPHA16 = $8048; + GL_INTENSITY = $8049; + GL_INTENSITY4 = $804A; + GL_INTENSITY8 = $804B; + GL_INTENSITY12 = $804C; + GL_INTENSITY16 = $804D; + GL_R3_G3_B2 = $2A10; + GL_RGB4 = $804F; + GL_RGB5 = $8050; + GL_RGB8 = $8051; + GL_RGB10 = $8052; + GL_RGB12 = $8053; + GL_RGB16 = $8054; + GL_RGBA2 = $8055; + GL_RGBA4 = $8056; + GL_RGB5_A1 = $8057; + GL_RGBA8 = $8058; + GL_RGB10_A2 = $8059; + GL_RGBA12 = $805A; + GL_RGBA16 = $805B; + GL_TEXTURE_RED_SIZE = $805C; + GL_TEXTURE_GREEN_SIZE = $805D; + GL_TEXTURE_BLUE_SIZE = $805E; + GL_TEXTURE_ALPHA_SIZE = $805F; + GL_TEXTURE_LUMINANCE_SIZE = $8060; + GL_TEXTURE_INTENSITY_SIZE = $8061; + GL_PROXY_TEXTURE_1D = $8063; + GL_PROXY_TEXTURE_2D = $8064; + + // texture_object + GL_TEXTURE_PRIORITY = $8066; + GL_TEXTURE_RESIDENT = $8067; + GL_TEXTURE_BINDING_1D = $8068; + GL_TEXTURE_BINDING_2D = $8069; + + // vertex_array + GL_VERTEX_ARRAY = $8074; + GL_NORMAL_ARRAY = $8075; + GL_COLOR_ARRAY = $8076; + GL_INDEX_ARRAY = $8077; + GL_TEXTURE_COORD_ARRAY = $8078; + GL_EDGE_FLAG_ARRAY = $8079; + GL_VERTEX_ARRAY_SIZE = $807A; + GL_VERTEX_ARRAY_TYPE = $807B; + GL_VERTEX_ARRAY_STRIDE = $807C; + GL_NORMAL_ARRAY_TYPE = $807E; + GL_NORMAL_ARRAY_STRIDE = $807F; + GL_COLOR_ARRAY_SIZE = $8081; + GL_COLOR_ARRAY_TYPE = $8082; + GL_COLOR_ARRAY_STRIDE = $8083; + GL_INDEX_ARRAY_TYPE = $8085; + GL_INDEX_ARRAY_STRIDE = $8086; + GL_TEXTURE_COORD_ARRAY_SIZE = $8088; + GL_TEXTURE_COORD_ARRAY_TYPE = $8089; + GL_TEXTURE_COORD_ARRAY_STRIDE = $808A; + GL_EDGE_FLAG_ARRAY_STRIDE = $808C; + GL_VERTEX_ARRAY_POINTER = $808E; + GL_NORMAL_ARRAY_POINTER = $808F; + GL_COLOR_ARRAY_POINTER = $8090; + GL_INDEX_ARRAY_POINTER = $8091; + GL_TEXTURE_COORD_ARRAY_POINTER = $8092; + GL_EDGE_FLAG_ARRAY_POINTER = $8093; + GL_V2F = $2A20; + GL_V3F = $2A21; + GL_C4UB_V2F = $2A22; + GL_C4UB_V3F = $2A23; + GL_C3F_V3F = $2A24; + GL_N3F_V3F = $2A25; + GL_C4F_N3F_V3F = $2A26; + GL_T2F_V3F = $2A27; + GL_T4F_V4F = $2A28; + GL_T2F_C4UB_V3F = $2A29; + GL_T2F_C3F_V3F = $2A2A; + GL_T2F_N3F_V3F = $2A2B; + GL_T2F_C4F_N3F_V3F = $2A2C; + GL_T4F_C4F_N3F_V4F = $2A2D; + + // Extensions + GL_EXT_vertex_array = 1; + GL_WIN_swap_hint = 1; + GL_EXT_bgra = 1; + GL_EXT_paletted_texture = 1; + + // EXT_vertex_array + GL_VERTEX_ARRAY_EXT = $8074; + GL_NORMAL_ARRAY_EXT = $8075; + GL_COLOR_ARRAY_EXT = $8076; + GL_INDEX_ARRAY_EXT = $8077; + GL_TEXTURE_COORD_ARRAY_EXT = $8078; + GL_EDGE_FLAG_ARRAY_EXT = $8079; + GL_VERTEX_ARRAY_SIZE_EXT = $807A; + GL_VERTEX_ARRAY_TYPE_EXT = $807B; + GL_VERTEX_ARRAY_STRIDE_EXT = $807C; + GL_VERTEX_ARRAY_COUNT_EXT = $807D; + GL_NORMAL_ARRAY_TYPE_EXT = $807E; + GL_NORMAL_ARRAY_STRIDE_EXT = $807F; + GL_NORMAL_ARRAY_COUNT_EXT = $8080; + GL_COLOR_ARRAY_SIZE_EXT = $8081; + GL_COLOR_ARRAY_TYPE_EXT = $8082; + GL_COLOR_ARRAY_STRIDE_EXT = $8083; + GL_COLOR_ARRAY_COUNT_EXT = $8084; + GL_INDEX_ARRAY_TYPE_EXT = $8085; + GL_INDEX_ARRAY_STRIDE_EXT = $8086; + GL_INDEX_ARRAY_COUNT_EXT = $8087; + GL_TEXTURE_COORD_ARRAY_SIZE_EXT = $8088; + GL_TEXTURE_COORD_ARRAY_TYPE_EXT = $8089; + GL_TEXTURE_COORD_ARRAY_STRIDE_EXT = $808A; + GL_TEXTURE_COORD_ARRAY_COUNT_EXT = $808B; + GL_EDGE_FLAG_ARRAY_STRIDE_EXT = $808C; + GL_EDGE_FLAG_ARRAY_COUNT_EXT = $808D; + GL_VERTEX_ARRAY_POINTER_EXT = $808E; + GL_NORMAL_ARRAY_POINTER_EXT = $808F; + GL_COLOR_ARRAY_POINTER_EXT = $8090; + GL_INDEX_ARRAY_POINTER_EXT = $8091; + GL_TEXTURE_COORD_ARRAY_POINTER_EXT = $8092; + GL_EDGE_FLAG_ARRAY_POINTER_EXT = $8093; + GL_DOUBLE_EXT = GL_DOUBLE; + + // EXT_bgra + GL_BGR_EXT = $80E0; + GL_BGRA_EXT = $80E1; + + // EXT_paletted_texture + + // These must match the GL_COLOR_TABLE_*_SGI enumerants + GL_COLOR_TABLE_FORMAT_EXT = $80D8; + GL_COLOR_TABLE_WIDTH_EXT = $80D9; + GL_COLOR_TABLE_RED_SIZE_EXT = $80DA; + GL_COLOR_TABLE_GREEN_SIZE_EXT = $80DB; + GL_COLOR_TABLE_BLUE_SIZE_EXT = $80DC; + GL_COLOR_TABLE_ALPHA_SIZE_EXT = $80DD; + GL_COLOR_TABLE_LUMINANCE_SIZE_EXT = $80DE; + GL_COLOR_TABLE_INTENSITY_SIZE_EXT = $80DF; + + GL_COLOR_INDEX1_EXT = $80E2; + GL_COLOR_INDEX2_EXT = $80E3; + GL_COLOR_INDEX4_EXT = $80E4; + GL_COLOR_INDEX8_EXT = $80E5; + GL_COLOR_INDEX12_EXT = $80E6; + GL_COLOR_INDEX16_EXT = $80E7; + + // For compatibility with OpenGL v1.0 + GL_LOGIC_OP = GL_INDEX_LOGIC_OP; + GL_TEXTURE_COMPONENTS = GL_TEXTURE_INTERNAL_FORMAT; + +{******************************************************************************} + +{$IFDEF MORPHOS} + +{ MorphOS GL works differently due to different dynamic-library handling on Amiga-like } +{ systems, so its headers are included here. } +{$INCLUDE tinyglh.inc} + +{$ELSE MORPHOS} +var + glAccum: procedure(op: GLenum; value: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glAlphaFunc: procedure(func: GLenum; ref: GLclampf); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glAreTexturesResident: function (n: GLsizei; const textures: PGLuint; residences: PGLboolean): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glArrayElement: procedure(i: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBegin: procedure(mode: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBindTexture: procedure(target: GLenum; texture: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBitmap: procedure (width, height: GLsizei; xorig, yorig: GLfloat; xmove, ymove: GLfloat; const bitmap: PGLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBlendFunc: procedure(sfactor, dfactor: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCallList: procedure(list: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCallLists: procedure(n: GLsizei; atype: GLenum; const lists: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glClear: procedure(mask: GLbitfield); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glClearAccum: procedure(red, green, blue, alpha: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glClearColor: procedure(red, green, blue, alpha: GLclampf); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glClearDepth: procedure(depth: GLclampd); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glClearIndex: procedure(c: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glClearStencil: procedure(s: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glClipPlane: procedure(plane: GLenum; const equation: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor3b: procedure(red, green, blue: GLbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor3bv: procedure(const v: PGLbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor3d: procedure(red, green, blue: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor3dv: procedure(const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor3f: procedure(red, green, blue: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor3fv: procedure(const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor3i: procedure(red, green, blue: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor3iv: procedure(const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor3s: procedure(red, green, blue: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor3sv: procedure(const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor3ub: procedure(red, green, blue: GLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor3ubv: procedure(const v: PGLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor3ui: procedure(red, green, blue: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor3uiv: procedure(const v: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor3us: procedure(red, green, blue: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor3usv: procedure(const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4b: procedure(red, green, blue, alpha: GLbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4bv: procedure(const v: PGLbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4d: procedure(red, green, blue, alpha: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4dv: procedure(const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4f: procedure(red, green, blue, alpha: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4fv: procedure(const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4i: procedure(red, green, blue, alpha: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4iv: procedure(const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4s: procedure(red, green, blue, alpha: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4sv: procedure(const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4ub: procedure(red, green, blue, alpha: GLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4ubv: procedure(const v: PGLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4ui: procedure(red, green, blue, alpha: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4uiv: procedure(const v: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4us: procedure(red, green, blue, alpha: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4usv: procedure(const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColorMask: procedure(red, green, blue, alpha: GLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColorMaterial: procedure(face, mode: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColorPointer: procedure(size: GLint; atype: GLenum; stride: GLsizei; const pointer: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCopyPixels: procedure(x, y: GLint; width, height: GLsizei; atype: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCopyTexImage1D: procedure (target: GLenum; level: GLint; internalFormat: GLenum; x, y: GLint; width: GLsizei; border: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCopyTexImage2D: procedure(target: GLenum; level: GLint; internalFormat: GLenum; x, y: GLint; width, height: GLsizei; border: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCopyTexSubImage1D: procedure(target: GLenum; level, xoffset, x, y: GLint; width: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCopyTexSubImage2D: procedure(target: GLenum; level, xoffset, yoffset, x, y: GLint; width, height: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCullFace: procedure(mode: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteLists: procedure(list: GLuint; range: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteTextures: procedure(n: GLsizei; const textures: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDepthFunc: procedure(func: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDepthMask: procedure(flag: GLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDepthRange: procedure(zNear, zFar: GLclampd); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDisable: procedure(cap: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDisableClientState: procedure(aarray: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDrawArrays: procedure(mode: GLenum; first: GLint; count: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDrawBuffer: procedure(mode: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDrawElements: procedure(mode: GLenum; count: GLsizei; atype: GLenum; const indices: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDrawPixels: procedure(width, height: GLsizei; format, atype: GLenum; const pixels: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEdgeFlag: procedure(flag: GLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEdgeFlagPointer: procedure(stride: GLsizei; const pointer: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEdgeFlagv: procedure(const flag: PGLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEnable: procedure(cap: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEnableClientState: procedure(aarray: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEnd: procedure; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEndList: procedure; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEvalCoord1d: procedure(u: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEvalCoord1dv: procedure(const u: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEvalCoord1f: procedure(u: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEvalCoord1fv: procedure(const u: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEvalCoord2d: procedure(u, v: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEvalCoord2dv: procedure(const u: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEvalCoord2f: procedure(u, v: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEvalCoord2fv: procedure(const u: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEvalMesh1: procedure(mode: GLenum; i1, i2: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEvalMesh2: procedure(mode: GLenum; i1, i2, j1, j2: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEvalPoint1: procedure(i: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEvalPoint2: procedure(i, j: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFeedbackBuffer: procedure(size: GLsizei; atype: GLenum; buffer: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFinish: procedure; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFlush: procedure; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFogf: procedure(pname: GLenum; param: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFogfv: procedure(pname: GLenum; const params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFogi: procedure(pname: GLenum; param: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFogiv: procedure(pname: GLenum; const params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFrontFace: procedure(mode: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFrustum: procedure(left, right, bottom, top, zNear, zFar: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGenLists: function(range: GLsizei): GLuint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGenTextures: procedure(n: GLsizei; textures: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetBooleanv: procedure(pname: GLenum; params: PGLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetClipPlane: procedure(plane: GLenum; equation: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetDoublev: procedure(pname: GLenum; params: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetError: function: GLenum; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetFloatv: procedure(pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetIntegerv: procedure(pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetLightfv: procedure(light, pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetLightiv: procedure(light, pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetMapdv: procedure(target, query: GLenum; v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetMapfv: procedure(target, query: GLenum; v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetMapiv: procedure(target, query: GLenum; v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetMaterialfv: procedure(face, pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetMaterialiv: procedure(face, pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetPixelMapfv: procedure(map: GLenum; values: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetPixelMapuiv: procedure(map: GLenum; values: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetPixelMapusv: procedure(map: GLenum; values: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetPointerv: procedure(pname: GLenum; params: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetPolygonStipple: procedure(mask: PGLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetString: function(name: GLenum): PChar; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetTexEnvfv: procedure(target, pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetTexEnviv: procedure(target, pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetTexGendv: procedure(coord, pname: GLenum; params: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetTexGenfv: procedure(coord, pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetTexGeniv: procedure(coord, pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetTexImage: procedure(target: GLenum; level: GLint; format: GLenum; atype: GLenum; pixels: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetTexLevelParameterfv: procedure(target: GLenum; level: GLint; pname: GLenum; params: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetTexLevelParameteriv: procedure(target: GLenum; level: GLint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetTexParameterfv: procedure(target, pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetTexParameteriv: procedure(target, pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glHint: procedure(target, mode: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIndexMask: procedure(mask: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIndexPointer: procedure(atype: GLenum; stride: GLsizei; const pointer: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIndexd: procedure(c: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIndexdv: procedure(const c: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIndexf: procedure(c: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIndexfv: procedure(const c: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIndexi: procedure(c: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIndexiv: procedure(const c: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIndexs: procedure(c: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIndexsv: procedure(const c: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIndexub: procedure(c: GLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIndexubv: procedure(const c: PGLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glInitNames: procedure; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glInterleavedArrays: procedure(format: GLenum; stride: GLsizei; const pointer: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsEnabled: function(cap: GLenum): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsList: function(list: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsTexture: function(texture: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLightModelf: procedure(pname: GLenum; param: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLightModelfv: procedure(pname: GLenum; const params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLightModeli: procedure(pname: GLenum; param: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLightModeliv: procedure(pname: GLenum; const params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLightf: procedure(light, pname: GLenum; param: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLightfv: procedure(light, pname: GLenum; const params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLighti: procedure(light, pname: GLenum; param: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLightiv: procedure(light, pname: GLenum; const params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLineStipple: procedure(factor: GLint; pattern: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLineWidth: procedure(width: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glListBase: procedure(base: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLoadIdentity: procedure; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLoadMatrixd: procedure(const m: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLoadMatrixf: procedure(const m: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLoadName: procedure(name: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLogicOp: procedure(opcode: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMap1d: procedure(target: GLenum; u1, u2: GLdouble; stride, order: GLint; const points: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMap1f: procedure(target: GLenum; u1, u2: GLfloat; stride, order: GLint; const points: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMap2d: procedure(target: GLenum; u1, u2: GLdouble; ustride, uorder: GLint; v1, v2: GLdouble; vstride, vorder: GLint; const points: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMap2f: procedure(target: GLenum; u1, u2: GLfloat; ustride, uorder: GLint; v1, v2: GLfloat; vstride, vorder: GLint; const points: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMapGrid1d: procedure(un: GLint; u1, u2: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMapGrid1f: procedure(un: GLint; u1, u2: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMapGrid2d: procedure(un: GLint; u1, u2: GLdouble; vn: GLint; v1, v2: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMapGrid2f: procedure(un: GLint; u1, u2: GLfloat; vn: GLint; v1, v2: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMaterialf: procedure(face, pname: GLenum; param: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMaterialfv: procedure(face, pname: GLenum; const params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMateriali: procedure(face, pname: GLenum; param: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMaterialiv: procedure(face, pname: GLenum; const params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMatrixMode: procedure(mode: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultMatrixd: procedure(const m: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultMatrixf: procedure(const m: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNewList: procedure(list: GLuint; mode: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormal3b: procedure(nx, ny, nz: GLbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormal3bv: procedure(const v: PGLbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormal3d: procedure(nx, ny, nz: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormal3dv: procedure(const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormal3f: procedure(nx, ny, nz: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormal3fv: procedure(const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormal3i: procedure(nx, ny, nz: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormal3iv: procedure(const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormal3s: procedure(nx, ny, nz: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormal3sv: procedure(const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormalPointer: procedure(atype: GLenum; stride: GLsizei; const pointer: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glOrtho: procedure(left, right, bottom, top, zNear, zFar: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPassThrough: procedure(token: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPixelMapfv: procedure(map: GLenum; mapsize: GLsizei; const values: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPixelMapuiv: procedure(map: GLenum; mapsize: GLsizei; const values: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPixelMapusv: procedure(map: GLenum; mapsize: GLsizei; const values: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPixelStoref: procedure(pname: GLenum; param: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPixelStorei: procedure(pname: GLenum; param: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPixelTransferf: procedure(pname: GLenum; param: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPixelTransferi: procedure(pname: GLenum; param: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPixelZoom: procedure(xfactor, yfactor: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPointSize: procedure(size: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPolygonMode: procedure(face, mode: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPolygonOffset: procedure(factor, units: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPolygonStipple: procedure(const mask: PGLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPopAttrib: procedure; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPopClientAttrib: procedure; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPopMatrix: procedure; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPopName: procedure; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPrioritizeTextures: procedure(n: GLsizei; const textures: PGLuint; const priorities: PGLclampf); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPushAttrib: procedure(mask: GLbitfield); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPushClientAttrib: procedure(mask: GLbitfield); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPushMatrix: procedure; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPushName: procedure(name: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos2d: procedure(x, y: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos2dv: procedure(const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos2f: procedure(x, y: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos2fv: procedure(const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos2i: procedure(x, y: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos2iv: procedure(const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos2s: procedure(x, y: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos2sv: procedure(const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos3d: procedure(x, y, z: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos3dv: procedure(const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos3f: procedure(x, y, z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos3fv: procedure(const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos3i: procedure(x, y, z: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos3iv: procedure(const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos3s: procedure(x, y, z: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos3sv: procedure(const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos4d: procedure(x, y, z, w: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos4dv: procedure(const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos4f: procedure(x, y, z, w: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos4fv: procedure(const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos4i: procedure(x, y, z, w: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos4iv: procedure(const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos4s: procedure(x, y, z, w: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRasterPos4sv: procedure(const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glReadBuffer: procedure(mode: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glReadPixels: procedure(x, y: GLint; width, height: GLsizei; format, atype: GLenum; pixels: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRectd: procedure(x1, y1, x2, y2: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRectdv: procedure(const v1: PGLdouble; const v2: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRectf: procedure(x1, y1, x2, y2: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRectfv: procedure(const v1: PGLfloat; const v2: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRecti: procedure(x1, y1, x2, y2: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRectiv: procedure(const v1: PGLint; const v2: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRects: procedure(x1, y1, x2, y2: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRectsv: procedure(const v1: PGLshort; const v2: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRenderMode: function(mode: GLint): GLint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRotated: procedure(angle, x, y, z: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRotatef: procedure(angle, x, y, z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glScaled: procedure(x, y, z: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glScalef: procedure(x, y, z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glScissor: procedure(x, y: GLint; width, height: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSelectBuffer: procedure(size: GLsizei; buffer: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glShadeModel: procedure(mode: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glStencilFunc: procedure(func: GLenum; ref: GLint; mask: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glStencilMask: procedure(mask: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glStencilOp: procedure(fail, zfail, zpass: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord1d: procedure(s: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord1dv: procedure(const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord1f: procedure(s: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord1fv: procedure(const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord1i: procedure(s: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord1iv: procedure(const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord1s: procedure(s: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord1sv: procedure(const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord2d: procedure(s, t: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord2dv: procedure(const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord2f: procedure(s, t: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord2fv: procedure(const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord2i: procedure(s, t: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord2iv: procedure(const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord2s: procedure(s, t: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord2sv: procedure(const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord3d: procedure(s, t, r: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord3dv: procedure(const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord3f: procedure(s, t, r: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord3fv: procedure(const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord3i: procedure(s, t, r: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord3iv: procedure(const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord3s: procedure(s, t, r: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord3sv: procedure(const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord4d: procedure(s, t, r, q: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord4dv: procedure(const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord4f: procedure(s, t, r, q: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord4fv: procedure(const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord4i: procedure(s, t, r, q: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord4iv: procedure(const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord4s: procedure(s, t, r, q: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord4sv: procedure(const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoordPointer: procedure(size: GLint; atype: GLenum; stride: GLsizei; const pointer: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexEnvf: procedure(target: GLenum; pname: GLenum; param: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexEnvfv: procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexEnvi: procedure(target: GLenum; pname: GLenum; param: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexEnviv: procedure(target: GLenum; pname: GLenum; const params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexGend: procedure(coord: GLenum; pname: GLenum; param: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexGendv: procedure(coord: GLenum; pname: GLenum; const params: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexGenf: procedure(coord: GLenum; pname: GLenum; param: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexGenfv: procedure(coord: GLenum; pname: GLenum; const params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexGeni: procedure(coord: GLenum; pname: GLenum; param: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexGeniv: procedure(coord: GLenum; pname: GLenum; const params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexImage1D: procedure(target: GLenum; level, internalformat: GLint; width: GLsizei; border: GLint; format, atype: GLenum; const pixels: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexImage2D: procedure(target: GLenum; level, internalformat: GLint; width, height: GLsizei; border: GLint; format, atype: GLenum; const pixels: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexParameterf: procedure(target: GLenum; pname: GLenum; param: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexParameterfv: procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexParameteri: procedure(target: GLenum; pname: GLenum; param: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexParameteriv: procedure(target: GLenum; pname: GLenum; const params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexSubImage1D: procedure(target: GLenum; level, xoffset: GLint; width: GLsizei; format, atype: GLenum; const pixels: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexSubImage2D: procedure(target: GLenum; level, xoffset, yoffset: GLint; width, height: GLsizei; format, atype: GLenum; const pixels: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTranslated: procedure(x, y, z: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTranslatef: procedure(x, y, z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex2d: procedure(x, y: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex2dv: procedure(const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex2f: procedure(x, y: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex2fv: procedure(const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex2i: procedure(x, y: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex2iv: procedure(const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex2s: procedure(x, y: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex2sv: procedure(const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex3d: procedure(x, y, z: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex3dv: procedure(const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex3f: procedure(x, y, z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex3fv: procedure(const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex3i: procedure(x, y, z: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex3iv: procedure(const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex3s: procedure(x, y, z: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex3sv: procedure(const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex4d: procedure(x, y, z, w: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex4dv: procedure(const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex4f: procedure(x, y, z, w: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex4fv: procedure(const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex4i: procedure(x, y, z, w: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex4iv: procedure(const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex4s: procedure(x, y, z, w: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex4sv: procedure(const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexPointer: procedure(size: GLint; atype: GLenum; stride: GLsizei; const pointer: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glViewport: procedure(x, y: GLint; width, height: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + {$IFDEF msWindows} + ChoosePixelFormat: function(DC: HDC; p2: PPixelFormatDescriptor): Integer; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + {$ENDIF} +{$ENDIF MORPHOS} + +type + // EXT_vertex_array + PFNGLARRAYELEMENTEXTPROC = procedure(i: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + PFNGLDRAWARRAYSEXTPROC = procedure(mode: GLenum; first: GLint; count: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + PFNGLVERTEXPOINTEREXTPROC = procedure(size: GLint; atype: GLenum; + stride, count: GLsizei; const pointer: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + PFNGLNORMALPOINTEREXTPROC = procedure(atype: GLenum; stride, count: GLsizei; + const pointer: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + PFNGLCOLORPOINTEREXTPROC = procedure(size: GLint; atype: GLenum; stride, count: GLsizei; + const pointer: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + PFNGLINDEXPOINTEREXTPROC = procedure(atype: GLenum; stride, count: GLsizei; + const pointer: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + PFNGLTEXCOORDPOINTEREXTPROC = procedure(size: GLint; atype: GLenum; + stride, count: GLsizei; const pointer: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + PFNGLEDGEFLAGPOINTEREXTPROC = procedure(stride, count: GLsizei; + const pointer: PGLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + PFNGLGETPOINTERVEXTPROC = procedure(pname: GLenum; params: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + PFNGLARRAYELEMENTARRAYEXTPROC = procedure(mode: GLenum; count: GLsizei; + const pi: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + // WIN_swap_hint + PFNGLADDSWAPHINTRECTWINPROC = procedure(x, y: GLint; width, height: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + // EXT_paletted_texture + PFNGLCOLORTABLEEXTPROC = procedure(target, internalFormat: GLenum; width: GLsizei; + format, atype: GLenum; const data: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + PFNGLCOLORSUBTABLEEXTPROC = procedure(target: GLenum; start, count: GLsizei; + format, atype: GLenum; const data: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + PFNGLGETCOLORTABLEEXTPROC = procedure(target, format, atype: GLenum; data: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + PFNGLGETCOLORTABLEPARAMETERIVEXTPROC = procedure(target, pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + PFNGLGETCOLORTABLEPARAMETERFVEXTPROC = procedure(target, pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +//procedure LoadOpenGL(const dll: String); +//procedure FreeOpenGL; + +procedure initializeopengl(const sonames: array of filenamety); //[] = default +procedure releaseopengl; +procedure regglinit(const initproc: dynlibprocty); +procedure reggldeinit(const deinitproc: dynlibprocty); + +implementation +uses +{$if defined(cpui386) or defined(cpux86_64)} + math, +{$ifend} + msesys,msedatalist{$ifdef mswindows}{$else}{$endif}{, + mseglextglob}; + +{$ifdef mswindows} +function WinChoosePixelFormat(DC: HDC; p2: PPixelFormatDescriptor): Integer; + {$ifdef wincall}stdcall{$else}cdecl{$endif} + ; external 'gdi32' name 'ChoosePixelFormat'; +{$endif} + +var + libinfo: dynlibinfoty; + +procedure regglinit(const initproc: dynlibprocty); +begin + regdynlibinit(libinfo,initproc); +end; + +procedure reggldeinit(const deinitproc: dynlibprocty); +begin + regdynlibdeinit(libinfo,deinitproc); +end; + +procedure init(const data: pointer); +begin + { according to bug 7570, this is necessary on all x86 platforms, + maybe we've to fix the sse control word as well } + { Yes, at least for darwin/x86_64 (JM) } +{$if defined(cpui386) or defined(cpux86_64)} + SetExceptionMask([exInvalidOp, exDenormalized, exZeroDivide,exOverflow, + exUnderflow, exPrecision]); +{$ifend} +{$ifdef mswindows} +{$else} + if not mseglloadextensions([gle_glx]) then begin + raise exception.create('Can not load glx.'); + end; +{$endif} + mseglloadextensions([gle_gl_version_1_5]); +end; + +procedure deinit(const data: pointer); +begin + //dummy +end; + +procedure initializeopengl(const sonames: array of filenamety); //[] = default +const + funcs: array[0..335] of funcinfoty = ( + (n: 'glAccum'; d: {$ifndef FPC}@{$endif}@glAccum), + (n: 'glAlphaFunc'; d: {$ifndef FPC}@{$endif}@glAlphaFunc), + (n: 'glAreTexturesResident'; d: {$ifndef FPC}@{$endif}@glAreTexturesResident), + (n: 'glArrayElement'; d: {$ifndef FPC}@{$endif}@glArrayElement), + (n: 'glBegin'; d: {$ifndef FPC}@{$endif}@glBegin), + (n: 'glBindTexture'; d: {$ifndef FPC}@{$endif}@glBindTexture), + (n: 'glBitmap'; d: {$ifndef FPC}@{$endif}@glBitmap), + (n: 'glBlendFunc'; d: {$ifndef FPC}@{$endif}@glBlendFunc), + (n: 'glCallList'; d: {$ifndef FPC}@{$endif}@glCallList), + (n: 'glCallLists'; d: {$ifndef FPC}@{$endif}@glCallLists), + (n: 'glClear'; d: {$ifndef FPC}@{$endif}@glClear), + (n: 'glClearAccum'; d: {$ifndef FPC}@{$endif}@glClearAccum), + (n: 'glClearColor'; d: {$ifndef FPC}@{$endif}@glClearColor), + (n: 'glClearDepth'; d: {$ifndef FPC}@{$endif}@glClearDepth), + (n: 'glClearIndex'; d: {$ifndef FPC}@{$endif}@glClearIndex), + (n: 'glClearStencil'; d: {$ifndef FPC}@{$endif}@glClearStencil), + (n: 'glClipPlane'; d: {$ifndef FPC}@{$endif}@glClipPlane), + (n: 'glColor3b'; d: {$ifndef FPC}@{$endif}@glColor3b), + (n: 'glColor3bv'; d: {$ifndef FPC}@{$endif}@glColor3bv), + (n: 'glColor3d'; d: {$ifndef FPC}@{$endif}@glColor3d), + (n: 'glColor3dv'; d: {$ifndef FPC}@{$endif}@glColor3dv), + (n: 'glColor3f'; d: {$ifndef FPC}@{$endif}@glColor3f), + (n: 'glColor3fv'; d: {$ifndef FPC}@{$endif}@glColor3fv), + (n: 'glColor3i'; d: {$ifndef FPC}@{$endif}@glColor3i), + (n: 'glColor3iv'; d: {$ifndef FPC}@{$endif}@glColor3iv), + (n: 'glColor3s'; d: {$ifndef FPC}@{$endif}@glColor3s), + (n: 'glColor3sv'; d: {$ifndef FPC}@{$endif}@glColor3sv), + (n: 'glColor3ub'; d: {$ifndef FPC}@{$endif}@glColor3ub), + (n: 'glColor3ubv'; d: {$ifndef FPC}@{$endif}@glColor3ubv), + (n: 'glColor3ui'; d: {$ifndef FPC}@{$endif}@glColor3ui), + (n: 'glColor3uiv'; d: {$ifndef FPC}@{$endif}@glColor3uiv), + (n: 'glColor3us'; d: {$ifndef FPC}@{$endif}@glColor3us), + (n: 'glColor3usv'; d: {$ifndef FPC}@{$endif}@glColor3usv), + (n: 'glColor4b'; d: {$ifndef FPC}@{$endif}@glColor4b), + (n: 'glColor4bv'; d: {$ifndef FPC}@{$endif}@glColor4bv), + (n: 'glColor4d'; d: {$ifndef FPC}@{$endif}@glColor4d), + (n: 'glColor4dv'; d: {$ifndef FPC}@{$endif}@glColor4dv), + (n: 'glColor4f'; d: {$ifndef FPC}@{$endif}@glColor4f), + (n: 'glColor4fv'; d: {$ifndef FPC}@{$endif}@glColor4fv), + (n: 'glColor4i'; d: {$ifndef FPC}@{$endif}@glColor4i), + (n: 'glColor4iv'; d: {$ifndef FPC}@{$endif}@glColor4iv), + (n: 'glColor4s'; d: {$ifndef FPC}@{$endif}@glColor4s), + (n: 'glColor4sv'; d: {$ifndef FPC}@{$endif}@glColor4sv), + (n: 'glColor4ub'; d: {$ifndef FPC}@{$endif}@glColor4ub), + (n: 'glColor4ubv'; d: {$ifndef FPC}@{$endif}@glColor4ubv), + (n: 'glColor4ui'; d: {$ifndef FPC}@{$endif}@glColor4ui), + (n: 'glColor4uiv'; d: {$ifndef FPC}@{$endif}@glColor4uiv), + (n: 'glColor4us'; d: {$ifndef FPC}@{$endif}@glColor4us), + (n: 'glColor4usv'; d: {$ifndef FPC}@{$endif}@glColor4usv), + (n: 'glColorMask'; d: {$ifndef FPC}@{$endif}@glColorMask), + (n: 'glColorMaterial'; d: {$ifndef FPC}@{$endif}@glColorMaterial), + (n: 'glColorPointer'; d: {$ifndef FPC}@{$endif}@glColorPointer), + (n: 'glCopyPixels'; d: {$ifndef FPC}@{$endif}@glCopyPixels), + (n: 'glCopyTexImage1D'; d: {$ifndef FPC}@{$endif}@glCopyTexImage1D), + (n: 'glCopyTexImage2D'; d: {$ifndef FPC}@{$endif}@glCopyTexImage2D), + (n: 'glCopyTexSubImage1D'; d: {$ifndef FPC}@{$endif}@glCopyTexSubImage1D), + (n: 'glCopyTexSubImage2D'; d: {$ifndef FPC}@{$endif}@glCopyTexSubImage2D), + (n: 'glCullFace'; d: {$ifndef FPC}@{$endif}@glCullFace), + (n: 'glDeleteLists'; d: {$ifndef FPC}@{$endif}@glDeleteLists), + (n: 'glDeleteTextures'; d: {$ifndef FPC}@{$endif}@glDeleteTextures), + (n: 'glDepthFunc'; d: {$ifndef FPC}@{$endif}@glDepthFunc), + (n: 'glDepthMask'; d: {$ifndef FPC}@{$endif}@glDepthMask), + (n: 'glDepthRange'; d: {$ifndef FPC}@{$endif}@glDepthRange), + (n: 'glDisable'; d: {$ifndef FPC}@{$endif}@glDisable), + (n: 'glDisableClientState'; d: {$ifndef FPC}@{$endif}@glDisableClientState), + (n: 'glDrawArrays'; d: {$ifndef FPC}@{$endif}@glDrawArrays), + (n: 'glDrawBuffer'; d: {$ifndef FPC}@{$endif}@glDrawBuffer), + (n: 'glDrawElements'; d: {$ifndef FPC}@{$endif}@glDrawElements), + (n: 'glDrawPixels'; d: {$ifndef FPC}@{$endif}@glDrawPixels), + (n: 'glEdgeFlag'; d: {$ifndef FPC}@{$endif}@glEdgeFlag), + (n: 'glEdgeFlagPointer'; d: {$ifndef FPC}@{$endif}@glEdgeFlagPointer), + (n: 'glEdgeFlagv'; d: {$ifndef FPC}@{$endif}@glEdgeFlagv), + (n: 'glEnable'; d: {$ifndef FPC}@{$endif}@glEnable), + (n: 'glEnableClientState'; d: {$ifndef FPC}@{$endif}@glEnableClientState), + (n: 'glEnd'; d: {$ifndef FPC}@{$endif}@glEnd), + (n: 'glEndList'; d: {$ifndef FPC}@{$endif}@glEndList), + (n: 'glEvalCoord1d'; d: {$ifndef FPC}@{$endif}@glEvalCoord1d), + (n: 'glEvalCoord1dv'; d: {$ifndef FPC}@{$endif}@glEvalCoord1dv), + (n: 'glEvalCoord1f'; d: {$ifndef FPC}@{$endif}@glEvalCoord1f), + (n: 'glEvalCoord1fv'; d: {$ifndef FPC}@{$endif}@glEvalCoord1fv), + (n: 'glEvalCoord2d'; d: {$ifndef FPC}@{$endif}@glEvalCoord2d), + (n: 'glEvalCoord2dv'; d: {$ifndef FPC}@{$endif}@glEvalCoord2dv), + (n: 'glEvalCoord2f'; d: {$ifndef FPC}@{$endif}@glEvalCoord2f), + (n: 'glEvalCoord2fv'; d: {$ifndef FPC}@{$endif}@glEvalCoord2fv), + (n: 'glEvalMesh1'; d: {$ifndef FPC}@{$endif}@glEvalMesh1), + (n: 'glEvalMesh2'; d: {$ifndef FPC}@{$endif}@glEvalMesh2), + (n: 'glEvalPoint1'; d: {$ifndef FPC}@{$endif}@glEvalPoint1), + (n: 'glEvalPoint2'; d: {$ifndef FPC}@{$endif}@glEvalPoint2), + (n: 'glFeedbackBuffer'; d: {$ifndef FPC}@{$endif}@glFeedbackBuffer), + (n: 'glFinish'; d: {$ifndef FPC}@{$endif}@glFinish), + (n: 'glFlush'; d: {$ifndef FPC}@{$endif}@glFlush), + (n: 'glFogf'; d: {$ifndef FPC}@{$endif}@glFogf), + (n: 'glFogfv'; d: {$ifndef FPC}@{$endif}@glFogfv), + (n: 'glFogi'; d: {$ifndef FPC}@{$endif}@glFogi), + (n: 'glFogiv'; d: {$ifndef FPC}@{$endif}@glFogiv), + (n: 'glFrontFace'; d: {$ifndef FPC}@{$endif}@glFrontFace), + (n: 'glFrustum'; d: {$ifndef FPC}@{$endif}@glFrustum), + (n: 'glGenLists'; d: {$ifndef FPC}@{$endif}@glGenLists), + (n: 'glGenTextures'; d: {$ifndef FPC}@{$endif}@glGenTextures), + (n: 'glGetBooleanv'; d: {$ifndef FPC}@{$endif}@glGetBooleanv), + (n: 'glGetClipPlane'; d: {$ifndef FPC}@{$endif}@glGetClipPlane), + (n: 'glGetDoublev'; d: {$ifndef FPC}@{$endif}@glGetDoublev), + (n: 'glGetError'; d: {$ifndef FPC}@{$endif}@glGetError), + (n: 'glGetFloatv'; d: {$ifndef FPC}@{$endif}@glGetFloatv), + (n: 'glGetIntegerv'; d: {$ifndef FPC}@{$endif}@glGetIntegerv), + (n: 'glGetLightfv'; d: {$ifndef FPC}@{$endif}@glGetLightfv), + (n: 'glGetLightiv'; d: {$ifndef FPC}@{$endif}@glGetLightiv), + (n: 'glGetMapdv'; d: {$ifndef FPC}@{$endif}@glGetMapdv), + (n: 'glGetMapfv'; d: {$ifndef FPC}@{$endif}@glGetMapfv), + (n: 'glGetMapiv'; d: {$ifndef FPC}@{$endif}@glGetMapiv), + (n: 'glGetMaterialfv'; d: {$ifndef FPC}@{$endif}@glGetMaterialfv), + (n: 'glGetMaterialiv'; d: {$ifndef FPC}@{$endif}@glGetMaterialiv), + (n: 'glGetPixelMapfv'; d: {$ifndef FPC}@{$endif}@glGetPixelMapfv), + (n: 'glGetPixelMapuiv'; d: {$ifndef FPC}@{$endif}@glGetPixelMapuiv), + (n: 'glGetPixelMapusv'; d: {$ifndef FPC}@{$endif}@glGetPixelMapusv), + (n: 'glGetPointerv'; d: {$ifndef FPC}@{$endif}@glGetPointerv), + (n: 'glGetPolygonStipple'; d: {$ifndef FPC}@{$endif}@glGetPolygonStipple), + (n: 'glGetString'; d: {$ifndef FPC}@{$endif}@glGetString), + (n: 'glGetTexEnvfv'; d: {$ifndef FPC}@{$endif}@glGetTexEnvfv), + (n: 'glGetTexEnviv'; d: {$ifndef FPC}@{$endif}@glGetTexEnviv), + (n: 'glGetTexGendv'; d: {$ifndef FPC}@{$endif}@glGetTexGendv), + (n: 'glGetTexGenfv'; d: {$ifndef FPC}@{$endif}@glGetTexGenfv), + (n: 'glGetTexGeniv'; d: {$ifndef FPC}@{$endif}@glGetTexGeniv), + (n: 'glGetTexImage'; d: {$ifndef FPC}@{$endif}@glGetTexImage), + (n: 'glGetTexLevelParameterfv'; d: {$ifndef FPC}@{$endif}@glGetTexLevelParameterfv), + (n: 'glGetTexLevelParameteriv'; d: {$ifndef FPC}@{$endif}@glGetTexLevelParameteriv), + (n: 'glGetTexParameterfv'; d: {$ifndef FPC}@{$endif}@glGetTexParameterfv), + (n: 'glGetTexParameteriv'; d: {$ifndef FPC}@{$endif}@glGetTexParameteriv), + (n: 'glHint'; d: {$ifndef FPC}@{$endif}@glHint), + (n: 'glIndexMask'; d: {$ifndef FPC}@{$endif}@glIndexMask), + (n: 'glIndexPointer'; d: {$ifndef FPC}@{$endif}@glIndexPointer), + (n: 'glIndexd'; d: {$ifndef FPC}@{$endif}@glIndexd), + (n: 'glIndexdv'; d: {$ifndef FPC}@{$endif}@glIndexdv), + (n: 'glIndexf'; d: {$ifndef FPC}@{$endif}@glIndexf), + (n: 'glIndexfv'; d: {$ifndef FPC}@{$endif}@glIndexfv), + (n: 'glIndexi'; d: {$ifndef FPC}@{$endif}@glIndexi), + (n: 'glIndexiv'; d: {$ifndef FPC}@{$endif}@glIndexiv), + (n: 'glIndexs'; d: {$ifndef FPC}@{$endif}@glIndexs), + (n: 'glIndexsv'; d: {$ifndef FPC}@{$endif}@glIndexsv), + (n: 'glIndexub'; d: {$ifndef FPC}@{$endif}@glIndexub), + (n: 'glIndexubv'; d: {$ifndef FPC}@{$endif}@glIndexubv), + (n: 'glInitNames'; d: {$ifndef FPC}@{$endif}@glInitNames), + (n: 'glInterleavedArrays'; d: {$ifndef FPC}@{$endif}@glInterleavedArrays), + (n: 'glIsEnabled'; d: {$ifndef FPC}@{$endif}@glIsEnabled), + (n: 'glIsList'; d: {$ifndef FPC}@{$endif}@glIsList), + (n: 'glIsTexture'; d: {$ifndef FPC}@{$endif}@glIsTexture), + (n: 'glLightModelf'; d: {$ifndef FPC}@{$endif}@glLightModelf), + (n: 'glLightModelfv'; d: {$ifndef FPC}@{$endif}@glLightModelfv), + (n: 'glLightModeli'; d: {$ifndef FPC}@{$endif}@glLightModeli), + (n: 'glLightModeliv'; d: {$ifndef FPC}@{$endif}@glLightModeliv), + (n: 'glLightf'; d: {$ifndef FPC}@{$endif}@glLightf), + (n: 'glLightfv'; d: {$ifndef FPC}@{$endif}@glLightfv), + (n: 'glLighti'; d: {$ifndef FPC}@{$endif}@glLighti), + (n: 'glLightiv'; d: {$ifndef FPC}@{$endif}@glLightiv), + (n: 'glLineStipple'; d: {$ifndef FPC}@{$endif}@glLineStipple), + (n: 'glLineWidth'; d: {$ifndef FPC}@{$endif}@glLineWidth), + (n: 'glListBase'; d: {$ifndef FPC}@{$endif}@glListBase), + (n: 'glLoadIdentity'; d: {$ifndef FPC}@{$endif}@glLoadIdentity), + (n: 'glLoadMatrixd'; d: {$ifndef FPC}@{$endif}@glLoadMatrixd), + (n: 'glLoadMatrixf'; d: {$ifndef FPC}@{$endif}@glLoadMatrixf), + (n: 'glLoadName'; d: {$ifndef FPC}@{$endif}@glLoadName), + (n: 'glLogicOp'; d: {$ifndef FPC}@{$endif}@glLogicOp), + (n: 'glMap1d'; d: {$ifndef FPC}@{$endif}@glMap1d), + (n: 'glMap1f'; d: {$ifndef FPC}@{$endif}@glMap1f), + (n: 'glMap2d'; d: {$ifndef FPC}@{$endif}@glMap2d), + (n: 'glMap2f'; d: {$ifndef FPC}@{$endif}@glMap2f), + (n: 'glMapGrid1d'; d: {$ifndef FPC}@{$endif}@glMapGrid1d), + (n: 'glMapGrid1f'; d: {$ifndef FPC}@{$endif}@glMapGrid1f), + (n: 'glMapGrid2d'; d: {$ifndef FPC}@{$endif}@glMapGrid2d), + (n: 'glMapGrid2f'; d: {$ifndef FPC}@{$endif}@glMapGrid2f), + (n: 'glMaterialf'; d: {$ifndef FPC}@{$endif}@glMaterialf), + (n: 'glMaterialfv'; d: {$ifndef FPC}@{$endif}@glMaterialfv), + (n: 'glMateriali'; d: {$ifndef FPC}@{$endif}@glMateriali), + (n: 'glMaterialiv'; d: {$ifndef FPC}@{$endif}@glMaterialiv), + (n: 'glMatrixMode'; d: {$ifndef FPC}@{$endif}@glMatrixMode), + (n: 'glMultMatrixd'; d: {$ifndef FPC}@{$endif}@glMultMatrixd), + (n: 'glMultMatrixf'; d: {$ifndef FPC}@{$endif}@glMultMatrixf), + (n: 'glNewList'; d: {$ifndef FPC}@{$endif}@glNewList), + (n: 'glNormal3b'; d: {$ifndef FPC}@{$endif}@glNormal3b), + (n: 'glNormal3bv'; d: {$ifndef FPC}@{$endif}@glNormal3bv), + (n: 'glNormal3d'; d: {$ifndef FPC}@{$endif}@glNormal3d), + (n: 'glNormal3dv'; d: {$ifndef FPC}@{$endif}@glNormal3dv), + (n: 'glNormal3f'; d: {$ifndef FPC}@{$endif}@glNormal3f), + (n: 'glNormal3fv'; d: {$ifndef FPC}@{$endif}@glNormal3fv), + (n: 'glNormal3i'; d: {$ifndef FPC}@{$endif}@glNormal3i), + (n: 'glNormal3iv'; d: {$ifndef FPC}@{$endif}@glNormal3iv), + (n: 'glNormal3s'; d: {$ifndef FPC}@{$endif}@glNormal3s), + (n: 'glNormal3sv'; d: {$ifndef FPC}@{$endif}@glNormal3sv), + (n: 'glNormalPointer'; d: {$ifndef FPC}@{$endif}@glNormalPointer), + (n: 'glOrtho'; d: {$ifndef FPC}@{$endif}@glOrtho), + (n: 'glPassThrough'; d: {$ifndef FPC}@{$endif}@glPassThrough), + (n: 'glPixelMapfv'; d: {$ifndef FPC}@{$endif}@glPixelMapfv), + (n: 'glPixelMapuiv'; d: {$ifndef FPC}@{$endif}@glPixelMapuiv), + (n: 'glPixelMapusv'; d: {$ifndef FPC}@{$endif}@glPixelMapusv), + (n: 'glPixelStoref'; d: {$ifndef FPC}@{$endif}@glPixelStoref), + (n: 'glPixelStorei'; d: {$ifndef FPC}@{$endif}@glPixelStorei), + (n: 'glPixelTransferf'; d: {$ifndef FPC}@{$endif}@glPixelTransferf), + (n: 'glPixelTransferi'; d: {$ifndef FPC}@{$endif}@glPixelTransferi), + (n: 'glPixelZoom'; d: {$ifndef FPC}@{$endif}@glPixelZoom), + (n: 'glPointSize'; d: {$ifndef FPC}@{$endif}@glPointSize), + (n: 'glPolygonMode'; d: {$ifndef FPC}@{$endif}@glPolygonMode), + (n: 'glPolygonOffset'; d: {$ifndef FPC}@{$endif}@glPolygonOffset), + (n: 'glPolygonStipple'; d: {$ifndef FPC}@{$endif}@glPolygonStipple), + (n: 'glPopAttrib'; d: {$ifndef FPC}@{$endif}@glPopAttrib), + (n: 'glPopClientAttrib'; d: {$ifndef FPC}@{$endif}@glPopClientAttrib), + (n: 'glPopMatrix'; d: {$ifndef FPC}@{$endif}@glPopMatrix), + (n: 'glPopName'; d: {$ifndef FPC}@{$endif}@glPopName), + (n: 'glPrioritizeTextures'; d: {$ifndef FPC}@{$endif}@glPrioritizeTextures), + (n: 'glPushAttrib'; d: {$ifndef FPC}@{$endif}@glPushAttrib), + (n: 'glPushClientAttrib'; d: {$ifndef FPC}@{$endif}@glPushClientAttrib), + (n: 'glPushMatrix'; d: {$ifndef FPC}@{$endif}@glPushMatrix), + (n: 'glPushName'; d: {$ifndef FPC}@{$endif}@glPushName), + (n: 'glRasterPos2d'; d: {$ifndef FPC}@{$endif}@glRasterPos2d), + (n: 'glRasterPos2dv'; d: {$ifndef FPC}@{$endif}@glRasterPos2dv), + (n: 'glRasterPos2f'; d: {$ifndef FPC}@{$endif}@glRasterPos2f), + (n: 'glRasterPos2fv'; d: {$ifndef FPC}@{$endif}@glRasterPos2fv), + (n: 'glRasterPos2i'; d: {$ifndef FPC}@{$endif}@glRasterPos2i), + (n: 'glRasterPos2iv'; d: {$ifndef FPC}@{$endif}@glRasterPos2iv), + (n: 'glRasterPos2s'; d: {$ifndef FPC}@{$endif}@glRasterPos2s), + (n: 'glRasterPos2sv'; d: {$ifndef FPC}@{$endif}@glRasterPos2sv), + (n: 'glRasterPos3d'; d: {$ifndef FPC}@{$endif}@glRasterPos3d), + (n: 'glRasterPos3dv'; d: {$ifndef FPC}@{$endif}@glRasterPos3dv), + (n: 'glRasterPos3f'; d: {$ifndef FPC}@{$endif}@glRasterPos3f), + (n: 'glRasterPos3fv'; d: {$ifndef FPC}@{$endif}@glRasterPos3fv), + (n: 'glRasterPos3i'; d: {$ifndef FPC}@{$endif}@glRasterPos3i), + (n: 'glRasterPos3iv'; d: {$ifndef FPC}@{$endif}@glRasterPos3iv), + (n: 'glRasterPos3s'; d: {$ifndef FPC}@{$endif}@glRasterPos3s), + (n: 'glRasterPos3sv'; d: {$ifndef FPC}@{$endif}@glRasterPos3sv), + (n: 'glRasterPos4d'; d: {$ifndef FPC}@{$endif}@glRasterPos4d), + (n: 'glRasterPos4dv'; d: {$ifndef FPC}@{$endif}@glRasterPos4dv), + (n: 'glRasterPos4f'; d: {$ifndef FPC}@{$endif}@glRasterPos4f), + (n: 'glRasterPos4fv'; d: {$ifndef FPC}@{$endif}@glRasterPos4fv), + (n: 'glRasterPos4i'; d: {$ifndef FPC}@{$endif}@glRasterPos4i), + (n: 'glRasterPos4iv'; d: {$ifndef FPC}@{$endif}@glRasterPos4iv), + (n: 'glRasterPos4s'; d: {$ifndef FPC}@{$endif}@glRasterPos4s), + (n: 'glRasterPos4sv'; d: {$ifndef FPC}@{$endif}@glRasterPos4sv), + (n: 'glReadBuffer'; d: {$ifndef FPC}@{$endif}@glReadBuffer), + (n: 'glReadPixels'; d: {$ifndef FPC}@{$endif}@glReadPixels), + (n: 'glRectd'; d: {$ifndef FPC}@{$endif}@glRectd), + (n: 'glRectdv'; d: {$ifndef FPC}@{$endif}@glRectdv), + (n: 'glRectf'; d: {$ifndef FPC}@{$endif}@glRectf), + (n: 'glRectfv'; d: {$ifndef FPC}@{$endif}@glRectfv), + (n: 'glRecti'; d: {$ifndef FPC}@{$endif}@glRecti), + (n: 'glRectiv'; d: {$ifndef FPC}@{$endif}@glRectiv), + (n: 'glRects'; d: {$ifndef FPC}@{$endif}@glRects), + (n: 'glRectsv'; d: {$ifndef FPC}@{$endif}@glRectsv), + (n: 'glRenderMode'; d: {$ifndef FPC}@{$endif}@glRenderMode), + (n: 'glRotated'; d: {$ifndef FPC}@{$endif}@glRotated), + (n: 'glRotatef'; d: {$ifndef FPC}@{$endif}@glRotatef), + (n: 'glScaled'; d: {$ifndef FPC}@{$endif}@glScaled), + (n: 'glScalef'; d: {$ifndef FPC}@{$endif}@glScalef), + (n: 'glScissor'; d: {$ifndef FPC}@{$endif}@glScissor), + (n: 'glSelectBuffer'; d: {$ifndef FPC}@{$endif}@glSelectBuffer), + (n: 'glShadeModel'; d: {$ifndef FPC}@{$endif}@glShadeModel), + (n: 'glStencilFunc'; d: {$ifndef FPC}@{$endif}@glStencilFunc), + (n: 'glStencilMask'; d: {$ifndef FPC}@{$endif}@glStencilMask), + (n: 'glStencilOp'; d: {$ifndef FPC}@{$endif}@glStencilOp), + (n: 'glTexCoord1d'; d: {$ifndef FPC}@{$endif}@glTexCoord1d), + (n: 'glTexCoord1dv'; d: {$ifndef FPC}@{$endif}@glTexCoord1dv), + (n: 'glTexCoord1f'; d: {$ifndef FPC}@{$endif}@glTexCoord1f), + (n: 'glTexCoord1fv'; d: {$ifndef FPC}@{$endif}@glTexCoord1fv), + (n: 'glTexCoord1i'; d: {$ifndef FPC}@{$endif}@glTexCoord1i), + (n: 'glTexCoord1iv'; d: {$ifndef FPC}@{$endif}@glTexCoord1iv), + (n: 'glTexCoord1s'; d: {$ifndef FPC}@{$endif}@glTexCoord1s), + (n: 'glTexCoord1sv'; d: {$ifndef FPC}@{$endif}@glTexCoord1sv), + (n: 'glTexCoord2d'; d: {$ifndef FPC}@{$endif}@glTexCoord2d), + (n: 'glTexCoord2dv'; d: {$ifndef FPC}@{$endif}@glTexCoord2dv), + (n: 'glTexCoord2f'; d: {$ifndef FPC}@{$endif}@glTexCoord2f), + (n: 'glTexCoord2fv'; d: {$ifndef FPC}@{$endif}@glTexCoord2fv), + (n: 'glTexCoord2i'; d: {$ifndef FPC}@{$endif}@glTexCoord2i), + (n: 'glTexCoord2iv'; d: {$ifndef FPC}@{$endif}@glTexCoord2iv), + (n: 'glTexCoord2s'; d: {$ifndef FPC}@{$endif}@glTexCoord2s), + (n: 'glTexCoord2sv'; d: {$ifndef FPC}@{$endif}@glTexCoord2sv), + (n: 'glTexCoord3d'; d: {$ifndef FPC}@{$endif}@glTexCoord3d), + (n: 'glTexCoord3dv'; d: {$ifndef FPC}@{$endif}@glTexCoord3dv), + (n: 'glTexCoord3f'; d: {$ifndef FPC}@{$endif}@glTexCoord3f), + (n: 'glTexCoord3fv'; d: {$ifndef FPC}@{$endif}@glTexCoord3fv), + (n: 'glTexCoord3i'; d: {$ifndef FPC}@{$endif}@glTexCoord3i), + (n: 'glTexCoord3iv'; d: {$ifndef FPC}@{$endif}@glTexCoord3iv), + (n: 'glTexCoord3s'; d: {$ifndef FPC}@{$endif}@glTexCoord3s), + (n: 'glTexCoord3sv'; d: {$ifndef FPC}@{$endif}@glTexCoord3sv), + (n: 'glTexCoord4d'; d: {$ifndef FPC}@{$endif}@glTexCoord4d), + (n: 'glTexCoord4dv'; d: {$ifndef FPC}@{$endif}@glTexCoord4dv), + (n: 'glTexCoord4f'; d: {$ifndef FPC}@{$endif}@glTexCoord4f), + (n: 'glTexCoord4fv'; d: {$ifndef FPC}@{$endif}@glTexCoord4fv), + (n: 'glTexCoord4i'; d: {$ifndef FPC}@{$endif}@glTexCoord4i), + (n: 'glTexCoord4iv'; d: {$ifndef FPC}@{$endif}@glTexCoord4iv), + (n: 'glTexCoord4s'; d: {$ifndef FPC}@{$endif}@glTexCoord4s), + (n: 'glTexCoord4sv'; d: {$ifndef FPC}@{$endif}@glTexCoord4sv), + (n: 'glTexCoordPointer'; d: {$ifndef FPC}@{$endif}@glTexCoordPointer), + (n: 'glTexEnvf'; d: {$ifndef FPC}@{$endif}@glTexEnvf), + (n: 'glTexEnvfv'; d: {$ifndef FPC}@{$endif}@glTexEnvfv), + (n: 'glTexEnvi'; d: {$ifndef FPC}@{$endif}@glTexEnvi), + (n: 'glTexEnviv'; d: {$ifndef FPC}@{$endif}@glTexEnviv), + (n: 'glTexGend'; d: {$ifndef FPC}@{$endif}@glTexGend), + (n: 'glTexGendv'; d: {$ifndef FPC}@{$endif}@glTexGendv), + (n: 'glTexGenf'; d: {$ifndef FPC}@{$endif}@glTexGenf), + (n: 'glTexGenfv'; d: {$ifndef FPC}@{$endif}@glTexGenfv), + (n: 'glTexGeni'; d: {$ifndef FPC}@{$endif}@glTexGeni), + (n: 'glTexGeniv'; d: {$ifndef FPC}@{$endif}@glTexGeniv), + (n: 'glTexImage1D'; d: {$ifndef FPC}@{$endif}@glTexImage1D), + (n: 'glTexImage2D'; d: {$ifndef FPC}@{$endif}@glTexImage2D), + (n: 'glTexParameterf'; d: {$ifndef FPC}@{$endif}@glTexParameterf), + (n: 'glTexParameterfv'; d: {$ifndef FPC}@{$endif}@glTexParameterfv), + (n: 'glTexParameteri'; d: {$ifndef FPC}@{$endif}@glTexParameteri), + (n: 'glTexParameteriv'; d: {$ifndef FPC}@{$endif}@glTexParameteriv), + (n: 'glTexSubImage1D'; d: {$ifndef FPC}@{$endif}@glTexSubImage1D), + (n: 'glTexSubImage2D'; d: {$ifndef FPC}@{$endif}@glTexSubImage2D), + (n: 'glTranslated'; d: {$ifndef FPC}@{$endif}@glTranslated), + (n: 'glTranslatef'; d: {$ifndef FPC}@{$endif}@glTranslatef), + (n: 'glVertex2d'; d: {$ifndef FPC}@{$endif}@glVertex2d), + (n: 'glVertex2dv'; d: {$ifndef FPC}@{$endif}@glVertex2dv), + (n: 'glVertex2f'; d: {$ifndef FPC}@{$endif}@glVertex2f), + (n: 'glVertex2fv'; d: {$ifndef FPC}@{$endif}@glVertex2fv), + (n: 'glVertex2i'; d: {$ifndef FPC}@{$endif}@glVertex2i), + (n: 'glVertex2iv'; d: {$ifndef FPC}@{$endif}@glVertex2iv), + (n: 'glVertex2s'; d: {$ifndef FPC}@{$endif}@glVertex2s), + (n: 'glVertex2sv'; d: {$ifndef FPC}@{$endif}@glVertex2sv), + (n: 'glVertex3d'; d: {$ifndef FPC}@{$endif}@glVertex3d), + (n: 'glVertex3dv'; d: {$ifndef FPC}@{$endif}@glVertex3dv), + (n: 'glVertex3f'; d: {$ifndef FPC}@{$endif}@glVertex3f), + (n: 'glVertex3fv'; d: {$ifndef FPC}@{$endif}@glVertex3fv), + (n: 'glVertex3i'; d: {$ifndef FPC}@{$endif}@glVertex3i), + (n: 'glVertex3iv'; d: {$ifndef FPC}@{$endif}@glVertex3iv), + (n: 'glVertex3s'; d: {$ifndef FPC}@{$endif}@glVertex3s), + (n: 'glVertex3sv'; d: {$ifndef FPC}@{$endif}@glVertex3sv), + (n: 'glVertex4d'; d: {$ifndef FPC}@{$endif}@glVertex4d), + (n: 'glVertex4dv'; d: {$ifndef FPC}@{$endif}@glVertex4dv), + (n: 'glVertex4f'; d: {$ifndef FPC}@{$endif}@glVertex4f), + (n: 'glVertex4fv'; d: {$ifndef FPC}@{$endif}@glVertex4fv), + (n: 'glVertex4i'; d: {$ifndef FPC}@{$endif}@glVertex4i), + (n: 'glVertex4iv'; d: {$ifndef FPC}@{$endif}@glVertex4iv), + (n: 'glVertex4s'; d: {$ifndef FPC}@{$endif}@glVertex4s), + (n: 'glVertex4sv'; d: {$ifndef FPC}@{$endif}@glVertex4sv), + (n: 'glVertexPointer'; d: {$ifndef FPC}@{$endif}@glVertexPointer), + (n: 'glViewport'; d: {$ifndef FPC}@{$endif}@glViewport) + ); +{$ifdef mswindows} + funcsopt: array[0..0] of funcinfoty = ( + (n: 'ChoosePixelFormat'; d: {$ifndef FPC}@{$endif}@ChoosePixelFormat) + ); +{$endif} +const + errormessage = 'Can not load OpenGL library. '; + +begin + initializedynlib(libinfo,sonames,opengllib,funcs, + {$ifdef mswindows}funcsopt{$else}[]{$endif},errormessage,@init); +{$ifdef mswindows} + if {$ifndef FPC}@{$endif}ChoosePixelFormat = nil then begin + ChoosePixelFormat:= @WinChoosePixelFormat; + end; +{$endif} +end; + +procedure releaseopengl; +begin + releasedynlib(libinfo,@deinit); +end; + +initialization + initializelibinfo(libinfo); + mseglextglob.init(); +finalization + finalizelibinfo(libinfo); +end. diff --git a/mseide-msegui/lib/common/opengl/mseglext.pas b/mseide-msegui/lib/common/opengl/mseglext.pas new file mode 100644 index 0000000..140efb6 --- /dev/null +++ b/mseide-msegui/lib/common/opengl/mseglext.pas @@ -0,0 +1,8268 @@ +{ + + Adaption of the delphi3d.net OpenGL units to FreePascal + Sebastian Guenther (sg@freepascal.org) in 2002 + These units are free to use +} + +{ modified 2011-2013 by Martin Schreiber } + +unit mseglext; +{$ifdef FPC}{$MACRO ON}{$mode objfpc} {$h+}{$endif} +{$IFDEF msWindows} + {$define wincall} +// {$DEFINE extdecl:=stdcall } +{$ELSE} +// {$DEFINE extdecl:=cdecl } +{$ENDIF} + +(************************************************** + * OpenGL extension loading library * + * Generated by MetaGLext, written by Tom Nuydens * + * (tom@delphi3d.net -- http://www.delphi3d.net * + **************************************************) + +//*** Generated on 10/11/2002 + +interface + +uses + SysUtils, + {$IFDEF msWindows} + Windows, + {$ELSE} + {$ifdef FPC}dynlibs,{$endif} + {$ENDIF} + msegl,mseglextglob{$ifndef FPC},msetypes{$endif}; + +{$IFDEF msWindows} +{ Declared in Windows unit as well in FPC; but declared here as well, to be + fully compatible to upstream version - sg } +function wglGetProcAddress(proc: PChar): Pointer; {$ifdef wincall}stdcall{$else}cdecl{$endif}; external 'OpenGL32.dll'; +{$ENDIF} +(* +// Test if the given extension name is present in the given extension string. +function glext_ExtensionSupported(const extension: String; const searchIn: String): Boolean; + +// Load the extension with the given name. +function glext_LoadExtension(ext: String): Boolean; +*) +type + GLcharARB = Char; + TGLcharARB = GLcharARB; + PGLcharARB = ^GLcharARB; + PPGLchar = ^PGLchar; + + GLhandleARB = Cardinal; + TGLhandleARB = GLhandleARB; + PGLhandleARB = ^GLhandleARB; + + GLintptr = PtrInt; + TGLintptr = GLintptr; + PGLintptr = ^GLintptr; + + GLsizeiptr = PtrInt; + TGLsizeiptr = GLsizeiptr; + PGLsizeiptr = ^GLsizeiptr; + + GLchar = Char; + TGLchar = GLchar; + PGLchar = Pchar; + + GLint64 = Int64; + TGLint64 = GLint64; + PGLint64 = ^GLint64; + + GLuint64 = QWord; + TGLuint64 = GLuint64; + PGLuint64 = ^GLuint64; + + +//***** GL_version_1_2 *****// +const + GL_UNSIGNED_BYTE_3_3_2 = $8032; + GL_UNSIGNED_SHORT_4_4_4_4 = $8033; + GL_UNSIGNED_SHORT_5_5_5_1 = $8034; + GL_UNSIGNED_INT_8_8_8_8 = $8035; + GL_UNSIGNED_INT_10_10_10_2 = $8036; + GL_RESCALE_NORMAL = $803A; + GL_UNSIGNED_BYTE_2_3_3_REV = $8362; + GL_UNSIGNED_SHORT_5_6_5 = $8363; + GL_UNSIGNED_SHORT_5_6_5_REV = $8364; + GL_UNSIGNED_SHORT_4_4_4_4_REV = $8365; + GL_UNSIGNED_SHORT_1_5_5_5_REV = $8366; + GL_UNSIGNED_INT_8_8_8_8_REV = $8367; + GL_UNSIGNED_INT_2_10_10_10_REV = $8368; + GL_BGR = $80E0; + GL_BGRA = $80E1; + GL_MAX_ELEMENTS_VERTICES = $80E8; + GL_MAX_ELEMENTS_INDICES = $80E9; + GL_CLAMP_TO_EDGE = $812F; + GL_TEXTURE_MIN_LOD = $813A; + GL_TEXTURE_MAX_LOD = $813B; + GL_TEXTURE_BASE_LEVEL = $813C; + GL_TEXTURE_MAX_LEVEL = $813D; + GL_LIGHT_MODEL_COLOR_CONTROL = $81F8; + GL_SINGLE_COLOR = $81F9; + GL_SEPARATE_SPECULAR_COLOR = $81FA; + GL_SMOOTH_POINT_SIZE_RANGE = $0B12; + GL_SMOOTH_POINT_SIZE_GRANULARITY = $0B13; + GL_SMOOTH_LINE_WIDTH_RANGE = $0B22; + GL_SMOOTH_LINE_WIDTH_GRANULARITY = $0B23; + GL_ALIASED_POINT_SIZE_RANGE = $846D; + GL_ALIASED_LINE_WIDTH_RANGE = $846E; + GL_PACK_SKIP_IMAGES = $806B; + GL_PACK_IMAGE_HEIGHT = $806C; + GL_UNPACK_SKIP_IMAGES = $806D; + GL_UNPACK_IMAGE_HEIGHT = $806E; + GL_TEXTURE_3D = $806F; + GL_PROXY_TEXTURE_3D = $8070; + GL_TEXTURE_DEPTH = $8071; + GL_TEXTURE_WRAP_R = $8072; + GL_MAX_3D_TEXTURE_SIZE = $8073; +var + glBlendColor: procedure(red: GLclampf; green: GLclampf; blue: GLclampf; alpha: GLclampf); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBlendEquation: procedure(mode: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDrawRangeElements: procedure(mode: GLenum; start: GLuint; _end: GLuint; count: GLsizei; _type: GLenum; const indices: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColorTable: procedure(target: GLenum; internalformat: GLenum; width: GLsizei; format: GLenum; _type: GLenum; const table: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColorTableParameterfv: procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColorTableParameteriv: procedure(target: GLenum; pname: GLenum; const params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCopyColorTable: procedure(target: GLenum; internalformat: GLenum; x: GLint; y: GLint; width: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetColorTable: procedure(target: GLenum; format: GLenum; _type: GLenum; table: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetColorTableParameterfv: procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetColorTableParameteriv: procedure(target: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColorSubTable: procedure(target: GLenum; start: GLsizei; count: GLsizei; format: GLenum; _type: GLenum; const data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCopyColorSubTable: procedure(target: GLenum; start: GLsizei; x: GLint; y: GLint; width: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glConvolutionFilter1D: procedure(target: GLenum; internalformat: GLenum; width: GLsizei; format: GLenum; _type: GLenum; const image: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glConvolutionFilter2D: procedure(target: GLenum; internalformat: GLenum; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; const image: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glConvolutionParameterf: procedure(target: GLenum; pname: GLenum; params: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glConvolutionParameterfv: procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glConvolutionParameteri: procedure(target: GLenum; pname: GLenum; params: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glConvolutionParameteriv: procedure(target: GLenum; pname: GLenum; const params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCopyConvolutionFilter1D: procedure(target: GLenum; internalformat: GLenum; x: GLint; y: GLint; width: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCopyConvolutionFilter2D: procedure(target: GLenum; internalformat: GLenum; x: GLint; y: GLint; width: GLsizei; height: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetConvolutionFilter: procedure(target: GLenum; format: GLenum; _type: GLenum; image: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetConvolutionParameterfv: procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetConvolutionParameteriv: procedure(target: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetSeparableFilter: procedure(target: GLenum; format: GLenum; _type: GLenum; row: PGLvoid; column: PGLvoid; span: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSeparableFilter2D: procedure(target: GLenum; internalformat: GLenum; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; const row: PGLvoid; const column: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetHistogram: procedure(target: GLenum; reset: GLboolean; format: GLenum; _type: GLenum; values: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetHistogramParameterfv: procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetHistogramParameteriv: procedure(target: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetMinmax: procedure(target: GLenum; reset: GLboolean; format: GLenum; _type: GLenum; values: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetMinmaxParameterfv: procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetMinmaxParameteriv: procedure(target: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glHistogram: procedure(target: GLenum; width: GLsizei; internalformat: GLenum; sink: GLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMinmax: procedure(target: GLenum; internalformat: GLenum; sink: GLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glResetHistogram: procedure(target: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glResetMinmax: procedure(target: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexImage3D: procedure(target: GLenum; level: GLint; internalformat: GLint; width: GLsizei; height: GLsizei; depth: GLsizei; border: GLint; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexSubImage3D: procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; zoffset: GLint; width: GLsizei; height: GLsizei; depth: GLsizei; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCopyTexSubImage3D: procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; zoffset: GLint; x: GLint; y: GLint; width: GLsizei; height: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_version_1_2: Boolean; + +//***** GL_ARB_imaging *****// +const + GL_CONSTANT_COLOR = $8001; + GL_ONE_MINUS_CONSTANT_COLOR = $8002; + GL_CONSTANT_ALPHA = $8003; + GL_ONE_MINUS_CONSTANT_ALPHA = $8004; + GL_BLEND_COLOR = $8005; + GL_FUNC_ADD = $8006; + GL_MIN = $8007; + GL_MAX = $8008; + GL_BLEND_EQUATION = $8009; + GL_FUNC_SUBTRACT = $800A; + GL_FUNC_REVERSE_SUBTRACT = $800B; + GL_CONVOLUTION_1D = $8010; + GL_CONVOLUTION_2D = $8011; + GL_SEPARABLE_2D = $8012; + GL_CONVOLUTION_BORDER_MODE = $8013; + GL_CONVOLUTION_FILTER_SCALE = $8014; + GL_CONVOLUTION_FILTER_BIAS = $8015; + GL_REDUCE = $8016; + GL_CONVOLUTION_FORMAT = $8017; + GL_CONVOLUTION_WIDTH = $8018; + GL_CONVOLUTION_HEIGHT = $8019; + GL_MAX_CONVOLUTION_WIDTH = $801A; + GL_MAX_CONVOLUTION_HEIGHT = $801B; + GL_POST_CONVOLUTION_RED_SCALE = $801C; + GL_POST_CONVOLUTION_GREEN_SCALE = $801D; + GL_POST_CONVOLUTION_BLUE_SCALE = $801E; + GL_POST_CONVOLUTION_ALPHA_SCALE = $801F; + GL_POST_CONVOLUTION_RED_BIAS = $8020; + GL_POST_CONVOLUTION_GREEN_BIAS = $8021; + GL_POST_CONVOLUTION_BLUE_BIAS = $8022; + GL_POST_CONVOLUTION_ALPHA_BIAS = $8023; + GL_HISTOGRAM = $8024; + GL_PROXY_HISTOGRAM = $8025; + GL_HISTOGRAM_WIDTH = $8026; + GL_HISTOGRAM_FORMAT = $8027; + GL_HISTOGRAM_RED_SIZE = $8028; + GL_HISTOGRAM_GREEN_SIZE = $8029; + GL_HISTOGRAM_BLUE_SIZE = $802A; + GL_HISTOGRAM_ALPHA_SIZE = $802B; + GL_HISTOGRAM_LUMINANCE_SIZE = $802C; + GL_HISTOGRAM_SINK = $802D; + GL_MINMAX = $802E; + GL_MINMAX_FORMAT = $802F; + GL_MINMAX_SINK = $8030; + GL_TABLE_TOO_LARGE = $8031; + GL_COLOR_MATRIX = $80B1; + GL_COLOR_MATRIX_STACK_DEPTH = $80B2; + GL_MAX_COLOR_MATRIX_STACK_DEPTH = $80B3; + GL_POST_COLOR_MATRIX_RED_SCALE = $80B4; + GL_POST_COLOR_MATRIX_GREEN_SCALE = $80B5; + GL_POST_COLOR_MATRIX_BLUE_SCALE = $80B6; + GL_POST_COLOR_MATRIX_ALPHA_SCALE = $80B7; + GL_POST_COLOR_MATRIX_RED_BIAS = $80B8; + GL_POST_COLOR_MATRIX_GREEN_BIAS = $80B9; + GL_POST_COLOR_MATRIX_BLUE_BIAS = $80BA; + GL_POST_COLOR_MATIX_ALPHA_BIAS = $80BB; + GL_COLOR_TABLE = $80D0; + GL_POST_CONVOLUTION_COLOR_TABLE = $80D1; + GL_POST_COLOR_MATRIX_COLOR_TABLE = $80D2; + GL_PROXY_COLOR_TABLE = $80D3; + GL_PROXY_POST_CONVOLUTION_COLOR_TABLE = $80D4; + GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE = $80D5; + GL_COLOR_TABLE_SCALE = $80D6; + GL_COLOR_TABLE_BIAS = $80D7; + GL_COLOR_TABLE_FORMAT = $80D8; + GL_COLOR_TABLE_WIDTH = $80D9; + GL_COLOR_TABLE_RED_SIZE = $80DA; + GL_COLOR_TABLE_GREEN_SIZE = $80DB; + GL_COLOR_TABLE_BLUE_SIZE = $80DC; + GL_COLOR_TABLE_ALPHA_SIZE = $80DD; + GL_COLOR_TABLE_LUMINANCE_SIZE = $80DE; + GL_COLOR_TABLE_INTENSITY_SIZE = $80DF; + GL_IGNORE_BORDER = $8150; + GL_CONSTANT_BORDER = $8151; + GL_WRAP_BORDER = $8152; + GL_REPLICATE_BORDER = $8153; + GL_CONVOLUTION_BORDER_COLOR = $8154; + +function Load_GL_ARB_imaging: Boolean; + +//***** GL_version_1_3 *****// +const + GL_TEXTURE0 = $84C0; + GL_TEXTURE1 = $84C1; + GL_TEXTURE2 = $84C2; + GL_TEXTURE3 = $84C3; + GL_TEXTURE4 = $84C4; + GL_TEXTURE5 = $84C5; + GL_TEXTURE6 = $84C6; + GL_TEXTURE7 = $84C7; + GL_TEXTURE8 = $84C8; + GL_TEXTURE9 = $84C9; + GL_TEXTURE10 = $84CA; + GL_TEXTURE11 = $84CB; + GL_TEXTURE12 = $84CC; + GL_TEXTURE13 = $84CD; + GL_TEXTURE14 = $84CE; + GL_TEXTURE15 = $84CF; + GL_TEXTURE16 = $84D0; + GL_TEXTURE17 = $84D1; + GL_TEXTURE18 = $84D2; + GL_TEXTURE19 = $84D3; + GL_TEXTURE20 = $84D4; + GL_TEXTURE21 = $84D5; + GL_TEXTURE22 = $84D6; + GL_TEXTURE23 = $84D7; + GL_TEXTURE24 = $84D8; + GL_TEXTURE25 = $84D9; + GL_TEXTURE26 = $84DA; + GL_TEXTURE27 = $84DB; + GL_TEXTURE28 = $84DC; + GL_TEXTURE29 = $84DD; + GL_TEXTURE30 = $84DE; + GL_TEXTURE31 = $84DF; + GL_ACTIVE_TEXTURE = $84E0; + GL_CLIENT_ACTIVE_TEXTURE = $84E1; + GL_MAX_TEXTURE_UNITS = $84E2; + GL_TRANSPOSE_MODELVIEW_MATRIX = $84E3; + GL_TRANSPOSE_PROJECTION_MATRIX = $84E4; + GL_TRANSPOSE_TEXTURE_MATRIX = $84E5; + GL_TRANSPOSE_COLOR_MATRIX = $84E6; + GL_MULTISAMPLE = $809D; + GL_SAMPLE_ALPHA_TO_COVERAGE = $809E; + GL_SAMPLE_ALPHA_TO_ONE = $809F; + GL_SAMPLE_COVERAGE = $80A0; + GL_SAMPLE_BUFFERS = $80A8; + GL_SAMPLES = $80A9; + GL_SAMPLE_COVERAGE_VALUE = $80AA; + GL_SAMPLE_COVERAGE_INVERT = $80AB; + GL_MULTISAMPLE_BIT = $20000000; + GL_NORMAL_MAP = $8511; + GL_REFLECTION_MAP = $8512; + GL_TEXTURE_CUBE_MAP = $8513; + GL_TEXTURE_BINDING_CUBE_MAP = $8514; + GL_TEXTURE_CUBE_MAP_POSITIVE_X = $8515; + GL_TEXTURE_CUBE_MAP_NEGATIVE_X = $8516; + GL_TEXTURE_CUBE_MAP_POSITIVE_Y = $8517; + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y = $8518; + GL_TEXTURE_CUBE_MAP_POSITIVE_Z = $8519; + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z = $851A; + GL_PROXY_TEXTURE_CUBE_MAP = $851B; + GL_MAX_CUBE_MAP_TEXTURE_SIZE = $851C; + GL_COMPRESSED_ALPHA = $84E9; + GL_COMPRESSED_LUMINANCE = $84EA; + GL_COMPRESSED_LUMINANCE_ALPHA = $84EB; + GL_COMPRESSED_INTENSITY = $84EC; + GL_COMPRESSED_RGB = $84ED; + GL_COMPRESSED_RGBA = $84EE; + GL_TEXTURE_COMPRESSION_HINT = $84EF; + GL_TEXTURE_COMPRESSED_IMAGE_SIZE = $86A0; + GL_TEXTURE_COMPRESSED = $86A1; + GL_NUM_COMPRESSED_TEXTURE_FORMATS = $86A2; + GL_COMPRESSED_TEXTURE_FORMATS = $86A3; + GL_CLAMP_TO_BORDER = $812D; + GL_CLAMP_TO_BORDER_SGIS = $812D; + GL_COMBINE = $8570; + GL_COMBINE_RGB = $8571; + GL_COMBINE_ALPHA = $8572; + GL_SOURCE0_RGB = $8580; + GL_SOURCE1_RGB = $8581; + GL_SOURCE2_RGB = $8582; + GL_SOURCE0_ALPHA = $8588; + GL_SOURCE1_ALPHA = $8589; + GL_SOURCE2_ALPHA = $858A; + GL_OPERAND0_RGB = $8590; + GL_OPERAND1_RGB = $8591; + GL_OPERAND2_RGB = $8592; + GL_OPERAND0_ALPHA = $8598; + GL_OPERAND1_ALPHA = $8599; + GL_OPERAND2_ALPHA = $859A; + GL_RGB_SCALE = $8573; + GL_ADD_SIGNED = $8574; + GL_INTERPOLATE = $8575; + GL_SUBTRACT = $84E7; + GL_CONSTANT = $8576; + GL_PRIMARY_COLOR = $8577; + GL_PREVIOUS = $8578; + GL_DOT3_RGB = $86AE; + GL_DOT3_RGBA = $86AF; +var + glActiveTexture: procedure(texture: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glClientActiveTexture: procedure(texture: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord1d: procedure(target: GLenum; s: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord1dv: procedure(target: GLenum; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord1f: procedure(target: GLenum; s: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord1fv: procedure(target: GLenum; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord1i: procedure(target: GLenum; s: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord1iv: procedure(target: GLenum; const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord1s: procedure(target: GLenum; s: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord1sv: procedure(target: GLenum; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord2d: procedure(target: GLenum; s: GLdouble; t: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord2dv: procedure(target: GLenum; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord2f: procedure(target: GLenum; s: GLfloat; t: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord2fv: procedure(target: GLenum; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord2i: procedure(target: GLenum; s: GLint; t: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord2iv: procedure(target: GLenum; const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord2s: procedure(target: GLenum; s: GLshort; t: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord2sv: procedure(target: GLenum; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord3d: procedure(target: GLenum; s: GLdouble; t: GLdouble; r: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord3dv: procedure(target: GLenum; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord3f: procedure(target: GLenum; s: GLfloat; t: GLfloat; r: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord3fv: procedure(target: GLenum; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord3i: procedure(target: GLenum; s: GLint; t: GLint; r: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord3iv: procedure(target: GLenum; const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord3s: procedure(target: GLenum; s: GLshort; t: GLshort; r: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord3sv: procedure(target: GLenum; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord4d: procedure(target: GLenum; s: GLdouble; t: GLdouble; r: GLdouble; q: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord4dv: procedure(target: GLenum; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord4f: procedure(target: GLenum; s: GLfloat; t: GLfloat; r: GLfloat; q: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord4fv: procedure(target: GLenum; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord4i: procedure(target: GLenum; s: GLint; t: GLint; r: GLint; q: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord4iv: procedure(target: GLenum; const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord4s: procedure(target: GLenum; s: GLshort; t: GLshort; r: GLshort; q: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord4sv: procedure(target: GLenum; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLoadTransposeMatrixf: procedure(const m: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLoadTransposeMatrixd: procedure(const m: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultTransposeMatrixf: procedure(const m: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultTransposeMatrixd: procedure(const m: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSampleCoverage: procedure(value: GLclampf; invert: GLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCompressedTexImage3D: procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; height: GLsizei; depth: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCompressedTexImage2D: procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; height: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCompressedTexImage1D: procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCompressedTexSubImage3D: procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; zoffset: GLint; width: GLsizei; height: GLsizei; depth: GLsizei; format: GLenum; imageSize: GLsizei; const data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCompressedTexSubImage2D: procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; width: GLsizei; height: GLsizei; format: GLenum; imageSize: GLsizei; const data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCompressedTexSubImage1D: procedure(target: GLenum; level: GLint; xoffset: GLint; width: GLsizei; format: GLenum; imageSize: GLsizei; const data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetCompressedTexImage: procedure(target: GLenum; level: GLint; img: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_version_1_3: Boolean; + +//***** GL_ARB_multitexture *****// +const + GL_TEXTURE0_ARB = $84C0; + GL_TEXTURE1_ARB = $84C1; + GL_TEXTURE2_ARB = $84C2; + GL_TEXTURE3_ARB = $84C3; + GL_TEXTURE4_ARB = $84C4; + GL_TEXTURE5_ARB = $84C5; + GL_TEXTURE6_ARB = $84C6; + GL_TEXTURE7_ARB = $84C7; + GL_TEXTURE8_ARB = $84C8; + GL_TEXTURE9_ARB = $84C9; + GL_TEXTURE10_ARB = $84CA; + GL_TEXTURE11_ARB = $84CB; + GL_TEXTURE12_ARB = $84CC; + GL_TEXTURE13_ARB = $84CD; + GL_TEXTURE14_ARB = $84CE; + GL_TEXTURE15_ARB = $84CF; + GL_TEXTURE16_ARB = $84D0; + GL_TEXTURE17_ARB = $84D1; + GL_TEXTURE18_ARB = $84D2; + GL_TEXTURE19_ARB = $84D3; + GL_TEXTURE20_ARB = $84D4; + GL_TEXTURE21_ARB = $84D5; + GL_TEXTURE22_ARB = $84D6; + GL_TEXTURE23_ARB = $84D7; + GL_TEXTURE24_ARB = $84D8; + GL_TEXTURE25_ARB = $84D9; + GL_TEXTURE26_ARB = $84DA; + GL_TEXTURE27_ARB = $84DB; + GL_TEXTURE28_ARB = $84DC; + GL_TEXTURE29_ARB = $84DD; + GL_TEXTURE30_ARB = $84DE; + GL_TEXTURE31_ARB = $84DF; + GL_ACTIVE_TEXTURE_ARB = $84E0; + GL_CLIENT_ACTIVE_TEXTURE_ARB = $84E1; + GL_MAX_TEXTURE_UNITS_ARB = $84E2; +var + glActiveTextureARB: procedure(texture: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glClientActiveTextureARB: procedure(texture: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord1dARB: procedure(target: GLenum; s: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord1dvARB: procedure(target: GLenum; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord1fARB: procedure(target: GLenum; s: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord1fvARB: procedure(target: GLenum; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord1iARB: procedure(target: GLenum; s: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord1ivARB: procedure(target: GLenum; const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord1sARB: procedure(target: GLenum; s: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord1svARB: procedure(target: GLenum; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord2dARB: procedure(target: GLenum; s: GLdouble; t: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord2dvARB: procedure(target: GLenum; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord2fARB: procedure(target: GLenum; s: GLfloat; t: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord2fvARB: procedure(target: GLenum; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord2iARB: procedure(target: GLenum; s: GLint; t: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord2ivARB: procedure(target: GLenum; const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord2sARB: procedure(target: GLenum; s: GLshort; t: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord2svARB: procedure(target: GLenum; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord3dARB: procedure(target: GLenum; s: GLdouble; t: GLdouble; r: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord3dvARB: procedure(target: GLenum; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord3fARB: procedure(target: GLenum; s: GLfloat; t: GLfloat; r: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord3fvARB: procedure(target: GLenum; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord3iARB: procedure(target: GLenum; s: GLint; t: GLint; r: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord3ivARB: procedure(target: GLenum; const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord3sARB: procedure(target: GLenum; s: GLshort; t: GLshort; r: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord3svARB: procedure(target: GLenum; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord4dARB: procedure(target: GLenum; s: GLdouble; t: GLdouble; r: GLdouble; q: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord4dvARB: procedure(target: GLenum; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord4fARB: procedure(target: GLenum; s: GLfloat; t: GLfloat; r: GLfloat; q: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord4fvARB: procedure(target: GLenum; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord4iARB: procedure(target: GLenum; s: GLint; t: GLint; r: GLint; q: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord4ivARB: procedure(target: GLenum; const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord4sARB: procedure(target: GLenum; s: GLshort; t: GLshort; r: GLshort; q: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord4svARB: procedure(target: GLenum; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_multitexture: Boolean; + +//***** GL_ARB_transpose_matrix *****// +const + GL_TRANSPOSE_MODELVIEW_MATRIX_ARB = $84E3; + GL_TRANSPOSE_PROJECTION_MATRIX_ARB = $84E4; + GL_TRANSPOSE_TEXTURE_MATRIX_ARB = $84E5; + GL_TRANSPOSE_COLOR_MATRIX_ARB = $84E6; +var + glLoadTransposeMatrixfARB: procedure(m: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLoadTransposeMatrixdARB: procedure(m: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultTransposeMatrixfARB: procedure(m: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultTransposeMatrixdARB: procedure(m: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_transpose_matrix: Boolean; + +//***** GL_ARB_multisample *****// +const + WGL_SAMPLE_BUFFERS_ARB = $2041; + WGL_SAMPLES_ARB = $2042; + GL_MULTISAMPLE_ARB = $809D; + GL_SAMPLE_ALPHA_TO_COVERAGE_ARB = $809E; + GL_SAMPLE_ALPHA_TO_ONE_ARB = $809F; + GL_SAMPLE_COVERAGE_ARB = $80A0; + GL_MULTISAMPLE_BIT_ARB = $20000000; + GL_SAMPLE_BUFFERS_ARB = $80A8; + GL_SAMPLES_ARB = $80A9; + GL_SAMPLE_COVERAGE_VALUE_ARB = $80AA; + GL_SAMPLE_COVERAGE_INVERT_ARB = $80AB; +var + glSampleCoverageARB: procedure(value: GLclampf; invert: GLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_multisample: Boolean; + +//***** GL_ARB_texture_env_add *****// + +function Load_GL_ARB_texture_env_add: Boolean; + +{$IFDEF msWindows} +//***** WGL_ARB_extensions_string *****// +var + wglGetExtensionsStringARB: function(hdc: HDC): Pchar; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_WGL_ARB_extensions_string: Boolean; + +//***** WGL_ARB_buffer_region *****// +const + WGL_FRONT_COLOR_BUFFER_BIT_ARB = $0001; + WGL_BACK_COLOR_BUFFER_BIT_ARB = $0002; + WGL_DEPTH_BUFFER_BIT_ARB = $0004; + WGL_STENCIL_BUFFER_BIT_ARB = $0008; +var + wglCreateBufferRegionARB: function(hDC: HDC; iLayerPlane: GLint; uType: GLuint): THandle; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglDeleteBufferRegionARB: procedure(hRegion: THandle); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglSaveBufferRegionARB: function(hRegion: THandle; x: GLint; y: GLint; width: GLint; height: GLint): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglRestoreBufferRegionARB: function(hRegion: THandle; x: GLint; y: GLint; width: GLint; height: GLint; xSrc: GLint; ySrc: GLint): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_WGL_ARB_buffer_region: Boolean; +{$ENDIF} + +//***** GL_ARB_texture_cube_map *****// +const + GL_NORMAL_MAP_ARB = $8511; + GL_REFLECTION_MAP_ARB = $8512; + GL_TEXTURE_CUBE_MAP_ARB = $8513; + GL_TEXTURE_BINDING_CUBE_MAP_ARB = $8514; + GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB = $8515; + GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB = $8516; + GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB = $8517; + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB = $8518; + GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB = $8519; + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB = $851A; + GL_PROXY_TEXTURE_CUBE_MAP_ARB = $851B; + GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB = $851C; + +function Load_GL_ARB_texture_cube_map: Boolean; + +//***** GL_ARB_depth_texture *****// +const + GL_DEPTH_COMPONENT16_ARB = $81A5; + GL_DEPTH_COMPONENT24_ARB = $81A6; + GL_DEPTH_COMPONENT32_ARB = $81A7; + GL_TEXTURE_DEPTH_SIZE_ARB = $884A; + GL_DEPTH_TEXTURE_MODE_ARB = $884B; + +function Load_GL_ARB_depth_texture: Boolean; + +//***** GL_ARB_point_parameters *****// +const + GL_POINT_SIZE_MIN_ARB = $8126; + GL_POINT_SIZE_MAX_ARB = $8127; + GL_POINT_FADE_THRESHOLD_SIZE_ARB = $8128; + GL_POINT_DISTANCE_ATTENUATION_ARB = $8129; +var + glPointParameterfARB: procedure(pname: GLenum; param: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPointParameterfvARB: procedure(pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_point_parameters: Boolean; + +//***** GL_ARB_shadow *****// +const + GL_TEXTURE_COMPARE_MODE_ARB = $884C; + GL_TEXTURE_COMPARE_FUNC_ARB = $884D; + GL_COMPARE_R_TO_TEXTURE_ARB = $884E; + +function Load_GL_ARB_shadow: Boolean; + +//***** GL_ARB_shadow_ambient *****// +const + GL_TEXTURE_COMPARE_FAIL_VALUE_ARB = $80BF; + +function Load_GL_ARB_shadow_ambient: Boolean; + +//***** GL_ARB_texture_border_clamp *****// +const + GL_CLAMP_TO_BORDER_ARB = $812D; + +function Load_GL_ARB_texture_border_clamp: Boolean; + +//***** GL_ARB_texture_compression *****// +const + GL_COMPRESSED_ALPHA_ARB = $84E9; + GL_COMPRESSED_LUMINANCE_ARB = $84EA; + GL_COMPRESSED_LUMINANCE_ALPHA_ARB = $84EB; + GL_COMPRESSED_INTENSITY_ARB = $84EC; + GL_COMPRESSED_RGB_ARB = $84ED; + GL_COMPRESSED_RGBA_ARB = $84EE; + GL_TEXTURE_COMPRESSION_HINT_ARB = $84EF; + GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB = $86A0; + GL_TEXTURE_COMPRESSED_ARB = $86A1; + GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB = $86A2; + GL_COMPRESSED_TEXTURE_FORMATS_ARB = $86A3; +var + glCompressedTexImage3DARB: procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; height: GLsizei; depth: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCompressedTexImage2DARB: procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; height: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCompressedTexImage1DARB: procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCompressedTexSubImage3DARB: procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; zoffset: GLint; width: GLsizei; height: GLsizei; depth: GLsizei; format: GLenum; imageSize: GLsizei; const data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCompressedTexSubImage2DARB: procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; width: GLsizei; height: GLsizei; format: GLenum; imageSize: GLsizei; const data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCompressedTexSubImage1DARB: procedure(target: GLenum; level: GLint; xoffset: GLint; width: GLsizei; format: GLenum; imageSize: GLsizei; const data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetCompressedTexImageARB: procedure(target: GLenum; lod: GLint; img: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_texture_compression: Boolean; + +//***** GL_ARB_texture_env_combine *****// +const + GL_COMBINE_ARB = $8570; + GL_COMBINE_RGB_ARB = $8571; + GL_COMBINE_ALPHA_ARB = $8572; + GL_SOURCE0_RGB_ARB = $8580; + GL_SOURCE1_RGB_ARB = $8581; + GL_SOURCE2_RGB_ARB = $8582; + GL_SOURCE0_ALPHA_ARB = $8588; + GL_SOURCE1_ALPHA_ARB = $8589; + GL_SOURCE2_ALPHA_ARB = $858A; + GL_OPERAND0_RGB_ARB = $8590; + GL_OPERAND1_RGB_ARB = $8591; + GL_OPERAND2_RGB_ARB = $8592; + GL_OPERAND0_ALPHA_ARB = $8598; + GL_OPERAND1_ALPHA_ARB = $8599; + GL_OPERAND2_ALPHA_ARB = $859A; + GL_RGB_SCALE_ARB = $8573; + GL_ADD_SIGNED_ARB = $8574; + GL_INTERPOLATE_ARB = $8575; + GL_SUBTRACT_ARB = $84E7; + GL_CONSTANT_ARB = $8576; + GL_PRIMARY_COLOR_ARB = $8577; + GL_PREVIOUS_ARB = $8578; + +function Load_GL_ARB_texture_env_combine: Boolean; + +//***** GL_ARB_texture_env_crossbar *****// + +function Load_GL_ARB_texture_env_crossbar: Boolean; + +//***** GL_ARB_texture_env_dot3 *****// +const + GL_DOT3_RGB_ARB = $86AE; + GL_DOT3_RGBA_ARB = $86AF; + +function Load_GL_ARB_texture_env_dot3: Boolean; + +//***** GL_ARB_texture_mirrored_repeat *****// +const + GL_MIRRORED_REPEAT_ARB = $8370; + +function Load_GL_ARB_texture_mirrored_repeat: Boolean; + +//***** GL_ARB_vertex_blend *****// +const + GL_MAX_VERTEX_UNITS_ARB = $86A4; + GL_ACTIVE_VERTEX_UNITS_ARB = $86A5; + GL_WEIGHT_SUM_UNITY_ARB = $86A6; + GL_VERTEX_BLEND_ARB = $86A7; + GL_MODELVIEW0_ARB = $1700; + GL_MODELVIEW1_ARB = $850A; + GL_MODELVIEW2_ARB = $8722; + GL_MODELVIEW3_ARB = $8723; + GL_MODELVIEW4_ARB = $8724; + GL_MODELVIEW5_ARB = $8725; + GL_MODELVIEW6_ARB = $8726; + GL_MODELVIEW7_ARB = $8727; + GL_MODELVIEW8_ARB = $8728; + GL_MODELVIEW9_ARB = $8729; + GL_MODELVIEW10_ARB = $872A; + GL_MODELVIEW11_ARB = $872B; + GL_MODELVIEW12_ARB = $872C; + GL_MODELVIEW13_ARB = $872D; + GL_MODELVIEW14_ARB = $872E; + GL_MODELVIEW15_ARB = $872F; + GL_MODELVIEW16_ARB = $8730; + GL_MODELVIEW17_ARB = $8731; + GL_MODELVIEW18_ARB = $8732; + GL_MODELVIEW19_ARB = $8733; + GL_MODELVIEW20_ARB = $8734; + GL_MODELVIEW21_ARB = $8735; + GL_MODELVIEW22_ARB = $8736; + GL_MODELVIEW23_ARB = $8737; + GL_MODELVIEW24_ARB = $8738; + GL_MODELVIEW25_ARB = $8739; + GL_MODELVIEW26_ARB = $873A; + GL_MODELVIEW27_ARB = $873B; + GL_MODELVIEW28_ARB = $873C; + GL_MODELVIEW29_ARB = $873D; + GL_MODELVIEW30_ARB = $873E; + GL_MODELVIEW31_ARB = $873F; + GL_CURRENT_WEIGHT_ARB = $86A8; + GL_WEIGHT_ARRAY_TYPE_ARB = $86A9; + GL_WEIGHT_ARRAY_STRIDE_ARB = $86AA; + GL_WEIGHT_ARRAY_SIZE_ARB = $86AB; + GL_WEIGHT_ARRAY_POINTER_ARB = $86AC; + GL_WEIGHT_ARRAY_ARB = $86AD; +var + glWeightbvARB: procedure(size: GLint; weights: PGLbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWeightsvARB: procedure(size: GLint; weights: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWeightivARB: procedure(size: GLint; weights: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWeightfvARB: procedure(size: GLint; weights: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWeightdvARB: procedure(size: GLint; weights: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWeightvARB: procedure(size: GLint; weights: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWeightubvARB: procedure(size: GLint; weights: PGLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWeightusvARB: procedure(size: GLint; weights: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWeightuivARB: procedure(size: GLint; weights: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWeightPointerARB: procedure(size: GLint; _type: GLenum; stride: GLsizei; pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexBlendARB: procedure(count: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_vertex_blend: Boolean; + +//***** GL_ARB_vertex_program *****// +const + GL_VERTEX_PROGRAM_ARB = $8620; + GL_VERTEX_PROGRAM_POINT_SIZE_ARB = $8642; + GL_VERTEX_PROGRAM_TWO_SIDE_ARB = $8643; + GL_COLOR_SUM_ARB = $8458; + GL_PROGRAM_FORMAT_ASCII_ARB = $8875; + GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB = $8622; + GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB = $8623; + GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB = $8624; + GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB = $8625; + GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB = $886A; + GL_CURRENT_VERTEX_ATTRIB_ARB = $8626; + GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB = $8645; + GL_PROGRAM_LENGTH_ARB = $8627; + GL_PROGRAM_FORMAT_ARB = $8876; + GL_PROGRAM_BINDING_ARB = $8677; + GL_PROGRAM_INSTRUCTIONS_ARB = $88A0; + GL_MAX_PROGRAM_INSTRUCTIONS_ARB = $88A1; + GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB = $88A2; + GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB = $88A3; + GL_PROGRAM_TEMPORARIES_ARB = $88A4; + GL_MAX_PROGRAM_TEMPORARIES_ARB = $88A5; + GL_PROGRAM_NATIVE_TEMPORARIES_ARB = $88A6; + GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB = $88A7; + GL_PROGRAM_PARAMETERS_ARB = $88A8; + GL_MAX_PROGRAM_PARAMETERS_ARB = $88A9; + GL_PROGRAM_NATIVE_PARAMETERS_ARB = $88AA; + GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB = $88AB; + GL_PROGRAM_ATTRIBS_ARB = $88AC; + GL_MAX_PROGRAM_ATTRIBS_ARB = $88AD; + GL_PROGRAM_NATIVE_ATTRIBS_ARB = $88AE; + GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB = $88AF; + GL_PROGRAM_ADDRESS_REGISTERS_ARB = $88B0; + GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB = $88B1; + GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB = $88B2; + GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB = $88B3; + GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB = $88B4; + GL_MAX_PROGRAM_ENV_PARAMETERS_ARB = $88B5; + GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB = $88B6; + GL_PROGRAM_STRING_ARB = $8628; + GL_PROGRAM_ERROR_POSITION_ARB = $864B; + GL_CURRENT_MATRIX_ARB = $8641; + GL_TRANSPOSE_CURRENT_MATRIX_ARB = $88B7; + GL_CURRENT_MATRIX_STACK_DEPTH_ARB = $8640; + GL_MAX_VERTEX_ATTRIBS_ARB = $8869; + GL_MAX_PROGRAM_MATRICES_ARB = $862F; + GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB = $862E; + GL_PROGRAM_ERROR_STRING_ARB = $8874; + GL_MATRIX0_ARB = $88C0; + GL_MATRIX1_ARB = $88C1; + GL_MATRIX2_ARB = $88C2; + GL_MATRIX3_ARB = $88C3; + GL_MATRIX4_ARB = $88C4; + GL_MATRIX5_ARB = $88C5; + GL_MATRIX6_ARB = $88C6; + GL_MATRIX7_ARB = $88C7; + GL_MATRIX8_ARB = $88C8; + GL_MATRIX9_ARB = $88C9; + GL_MATRIX10_ARB = $88CA; + GL_MATRIX11_ARB = $88CB; + GL_MATRIX12_ARB = $88CC; + GL_MATRIX13_ARB = $88CD; + GL_MATRIX14_ARB = $88CE; + GL_MATRIX15_ARB = $88CF; + GL_MATRIX16_ARB = $88D0; + GL_MATRIX17_ARB = $88D1; + GL_MATRIX18_ARB = $88D2; + GL_MATRIX19_ARB = $88D3; + GL_MATRIX20_ARB = $88D4; + GL_MATRIX21_ARB = $88D5; + GL_MATRIX22_ARB = $88D6; + GL_MATRIX23_ARB = $88D7; + GL_MATRIX24_ARB = $88D8; + GL_MATRIX25_ARB = $88D9; + GL_MATRIX26_ARB = $88DA; + GL_MATRIX27_ARB = $88DB; + GL_MATRIX28_ARB = $88DC; + GL_MATRIX29_ARB = $88DD; + GL_MATRIX30_ARB = $88DE; + GL_MATRIX31_ARB = $88DF; +var + glVertexAttrib1sARB: procedure(index: GLuint; x: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib1fARB: procedure(index: GLuint; x: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib1dARB: procedure(index: GLuint; x: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib2sARB: procedure(index: GLuint; x: GLshort; y: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib2fARB: procedure(index: GLuint; x: GLfloat; y: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib2dARB: procedure(index: GLuint; x: GLdouble; y: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib3sARB: procedure(index: GLuint; x: GLshort; y: GLshort; z: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib3fARB: procedure(index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib3dARB: procedure(index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4sARB: procedure(index: GLuint; x: GLshort; y: GLshort; z: GLshort; w: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4fARB: procedure(index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4dARB: procedure(index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4NubARB: procedure(index: GLuint; x: GLubyte; y: GLubyte; z: GLubyte; w: GLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib1svARB: procedure(index: GLuint; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib1fvARB: procedure(index: GLuint; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib1dvARB: procedure(index: GLuint; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib2svARB: procedure(index: GLuint; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib2fvARB: procedure(index: GLuint; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib2dvARB: procedure(index: GLuint; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib3svARB: procedure(index: GLuint; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib3fvARB: procedure(index: GLuint; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib3dvARB: procedure(index: GLuint; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4bvARB: procedure(index: GLuint; const v: PGLbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4svARB: procedure(index: GLuint; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4ivARB: procedure(index: GLuint; const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4ubvARB: procedure(index: GLuint; const v: PGLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4usvARB: procedure(index: GLuint; const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4uivARB: procedure(index: GLuint; const v: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4fvARB: procedure(index: GLuint; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4dvARB: procedure(index: GLuint; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4NbvARB: procedure(index: GLuint; const v: PGLbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4NsvARB: procedure(index: GLuint; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4NivARB: procedure(index: GLuint; const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4NubvARB: procedure(index: GLuint; const v: PGLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4NusvARB: procedure(index: GLuint; const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4NuivARB: procedure(index: GLuint; const v: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribPointerARB: procedure(index: GLuint; size: GLint; _type: GLenum; normalized: GLboolean; stride: GLsizei; const pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEnableVertexAttribArrayARB: procedure(index: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDisableVertexAttribArrayARB: procedure(index: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramStringARB: procedure(target: GLenum; format: GLenum; len: GLsizei; const _string: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBindProgramARB: procedure(target: GLenum; _program: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteProgramsARB: procedure(n: GLsizei; const programs: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGenProgramsARB: procedure(n: GLsizei; programs: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramEnvParameter4dARB: procedure(target: GLenum; index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramEnvParameter4dvARB: procedure(target: GLenum; index: GLuint; const params: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramEnvParameter4fARB: procedure(target: GLenum; index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramEnvParameter4fvARB: procedure(target: GLenum; index: GLuint; const params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramLocalParameter4dARB: procedure(target: GLenum; index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramLocalParameter4dvARB: procedure(target: GLenum; index: GLuint; const params: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramLocalParameter4fARB: procedure(target: GLenum; index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramLocalParameter4fvARB: procedure(target: GLenum; index: GLuint; const params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetProgramEnvParameterdvARB: procedure(target: GLenum; index: GLuint; params: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetProgramEnvParameterfvARB: procedure(target: GLenum; index: GLuint; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetProgramLocalParameterdvARB: procedure(target: GLenum; index: GLuint; params: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetProgramLocalParameterfvARB: procedure(target: GLenum; index: GLuint; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetProgramivARB: procedure(target: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetProgramStringARB: procedure(target: GLenum; pname: GLenum; _string: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVertexAttribdvARB: procedure(index: GLuint; pname: GLenum; params: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVertexAttribfvARB: procedure(index: GLuint; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVertexAttribivARB: procedure(index: GLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVertexAttribPointervARB: procedure(index: GLuint; pname: GLenum; pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsProgramARB: function(_program: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_vertex_program: Boolean; + +//***** GL_ARB_window_pos *****// +var + glWindowPos2dARB: procedure(x: GLdouble; y: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2fARB: procedure(x: GLfloat; y: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2iARB: procedure(x: GLint; y: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2sARB: procedure(x: GLshort; y: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2dvARB: procedure(const p: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2fvARB: procedure(const p: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2ivARB: procedure(const p: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2svARB: procedure(const p: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3dARB: procedure(x: GLdouble; y: GLdouble; z: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3fARB: procedure(x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3iARB: procedure(x: GLint; y: GLint; z: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3sARB: procedure(x: GLshort; y: GLshort; z: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3dvARB: procedure(const p: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3fvARB: procedure(const p: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3ivARB: procedure(const p: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3svARB: procedure(const p: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_window_pos: Boolean; + +//***** GL_EXT_422_pixels *****// +const + GL_422_EXT = $80CC; + GL_422_REV_EXT = $80CD; + GL_422_AVERAGE_EXT = $80CE; + GL_422_REV_AVERAGE_EXT = $80CF; + +function Load_GL_EXT_422_pixels: Boolean; + +//***** GL_EXT_abgr *****// +const + GL_ABGR_EXT = $8000; + +function Load_GL_EXT_abgr: Boolean; + +//***** GL_EXT_bgra *****// +const + GL_BGR_EXT = $80E0; + GL_BGRA_EXT = $80E1; + +function Load_GL_EXT_bgra: Boolean; + +//***** GL_EXT_blend_color *****// +const + GL_CONSTANT_COLOR_EXT = $8001; + GL_ONE_MINUS_CONSTANT_COLOR_EXT = $8002; + GL_CONSTANT_ALPHA_EXT = $8003; + GL_ONE_MINUS_CONSTANT_ALPHA_EXT = $8004; + GL_BLEND_COLOR_EXT = $8005; +var + glBlendColorEXT: procedure(red: GLclampf; green: GLclampf; blue: GLclampf; alpha: GLclampf); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_blend_color: Boolean; + +//***** GL_EXT_blend_func_separate *****// +const + GL_BLEND_DST_RGB_EXT = $80C8; + GL_BLEND_SRC_RGB_EXT = $80C9; + GL_BLEND_DST_ALPHA_EXT = $80CA; + GL_BLEND_SRC_ALPHA_EXT = $80CB; +var + glBlendFuncSeparateEXT: procedure(sfactorRGB: GLenum; dfactorRGB: GLenum; sfactorAlpha: GLenum; dfactorAlpha: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_blend_func_separate: Boolean; + +//***** GL_EXT_blend_logic_op *****// + +function Load_GL_EXT_blend_logic_op: Boolean; + +//***** GL_EXT_blend_minmax *****// +const + GL_FUNC_ADD_EXT = $8006; + GL_MIN_EXT = $8007; + GL_MAX_EXT = $8008; + GL_BLEND_EQUATION_EXT = $8009; +var + glBlendEquationEXT: procedure(mode: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_blend_minmax: Boolean; + +//***** GL_EXT_blend_subtract *****// +const + GL_FUNC_SUBTRACT_EXT = $800A; + GL_FUNC_REVERSE_SUBTRACT_EXT = $800B; + +function Load_GL_EXT_blend_subtract: Boolean; + +//***** GL_EXT_clip_volume_hint *****// +const + GL_CLIP_VOLUME_CLIPPING_HINT_EXT = $80F0; + +function Load_GL_EXT_clip_volume_hint: Boolean; + +//***** GL_EXT_color_subtable *****// +var + glColorSubTableEXT: procedure(target: GLenum; start: GLsizei; count: GLsizei; format: GLenum; _type: GLenum; const data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCopyColorSubTableEXT: procedure(target: GLenum; start: GLsizei; x: GLint; y: GLint; width: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_color_subtable: Boolean; + +//***** GL_EXT_compiled_vertex_array *****// +const + GL_ARRAY_ELEMENT_LOCK_FIRST_EXT = $81A8; + GL_ARRAY_ELEMENT_LOCK_COUNT_EXT = $81A9; +var + glLockArraysEXT: procedure(first: GLint; count: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUnlockArraysEXT: procedure(); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_compiled_vertex_array: Boolean; + +//***** GL_EXT_convolution *****// +const + GL_CONVOLUTION_1D_EXT = $8010; + GL_CONVOLUTION_2D_EXT = $8011; + GL_SEPARABLE_2D_EXT = $8012; + GL_CONVOLUTION_BORDER_MODE_EXT = $8013; + GL_CONVOLUTION_FILTER_SCALE_EXT = $8014; + GL_CONVOLUTION_FILTER_BIAS_EXT = $8015; + GL_REDUCE_EXT = $8016; + GL_CONVOLUTION_FORMAT_EXT = $8017; + GL_CONVOLUTION_WIDTH_EXT = $8018; + GL_CONVOLUTION_HEIGHT_EXT = $8019; + GL_MAX_CONVOLUTION_WIDTH_EXT = $801A; + GL_MAX_CONVOLUTION_HEIGHT_EXT = $801B; + GL_POST_CONVOLUTION_RED_SCALE_EXT = $801C; + GL_POST_CONVOLUTION_GREEN_SCALE_EXT = $801D; + GL_POST_CONVOLUTION_BLUE_SCALE_EXT = $801E; + GL_POST_CONVOLUTION_ALPHA_SCALE_EXT = $801F; + GL_POST_CONVOLUTION_RED_BIAS_EXT = $8020; + GL_POST_CONVOLUTION_GREEN_BIAS_EXT = $8021; + GL_POST_CONVOLUTION_BLUE_BIAS_EXT = $8022; + GL_POST_CONVOLUTION_ALPHA_BIAS_EXT = $8023; +var + glConvolutionFilter1DEXT: procedure(target: GLenum; internalformat: GLenum; width: GLsizei; format: GLenum; _type: GLenum; const image: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glConvolutionFilter2DEXT: procedure(target: GLenum; internalformat: GLenum; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; const image: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCopyConvolutionFilter1DEXT: procedure(target: GLenum; internalformat: GLenum; x: GLint; y: GLint; width: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCopyConvolutionFilter2DEXT: procedure(target: GLenum; internalformat: GLenum; x: GLint; y: GLint; width: GLsizei; height: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetConvolutionFilterEXT: procedure(target: GLenum; format: GLenum; _type: GLenum; image: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSeparableFilter2DEXT: procedure(target: GLenum; internalformat: GLenum; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; const row: PGLvoid; const column: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetSeparableFilterEXT: procedure(target: GLenum; format: GLenum; _type: GLenum; row: PGLvoid; column: PGLvoid; span: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glConvolutionParameteriEXT: procedure(target: GLenum; pname: GLenum; param: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glConvolutionParameterivEXT: procedure(target: GLenum; pname: GLenum; const params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glConvolutionParameterfEXT: procedure(target: GLenum; pname: GLenum; param: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glConvolutionParameterfvEXT: procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetConvolutionParameterivEXT: procedure(target: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetConvolutionParameterfvEXT: procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_convolution: Boolean; + +//***** GL_EXT_fog_coord *****// +const + GL_FOG_COORDINATE_SOURCE_EXT = $8450; + GL_FOG_COORDINATE_EXT = $8451; + GL_FRAGMENT_DEPTH_EXT = $8452; + GL_CURRENT_FOG_COORDINATE_EXT = $8453; + GL_FOG_COORDINATE_ARRAY_TYPE_EXT = $8454; + GL_FOG_COORDINATE_ARRAY_STRIDE_EXT = $8455; + GL_FOG_COORDINATE_ARRAY_POINTER_EXT = $8456; + GL_FOG_COORDINATE_ARRAY_EXT = $8457; +var + glFogCoordfEXT: procedure(coord: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFogCoorddEXT: procedure(coord: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFogCoordfvEXT: procedure(coord: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFogCoorddvEXT: procedure(coord: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFogCoordPointerEXT: procedure(_type: GLenum; stride: GLsizei; pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_fog_coord: Boolean; + +//***** GL_EXT_histogram *****// +const + GL_HISTOGRAM_EXT = $8024; + GL_PROXY_HISTOGRAM_EXT = $8025; + GL_HISTOGRAM_WIDTH_EXT = $8026; + GL_HISTOGRAM_FORMAT_EXT = $8027; + GL_HISTOGRAM_RED_SIZE_EXT = $8028; + GL_HISTOGRAM_GREEN_SIZE_EXT = $8029; + GL_HISTOGRAM_BLUE_SIZE_EXT = $802A; + GL_HISTOGRAM_ALPHA_SIZE_EXT = $802B; + GL_HISTOGRAM_LUMINANCE_SIZE_EXT = $802C; + GL_HISTOGRAM_SINK_EXT = $802D; + GL_MINMAX_EXT = $802E; + GL_MINMAX_FORMAT_EXT = $802F; + GL_MINMAX_SINK_EXT = $8030; +var + glHistogramEXT: procedure(target: GLenum; width: GLsizei; internalformat: GLenum; sink: GLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glResetHistogramEXT: procedure(target: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetHistogramEXT: procedure(target: GLenum; reset: GLboolean; format: GLenum; _type: GLenum; values: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetHistogramParameterivEXT: procedure(target: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetHistogramParameterfvEXT: procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMinmaxEXT: procedure(target: GLenum; internalformat: GLenum; sink: GLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glResetMinmaxEXT: procedure(target: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetMinmaxEXT: procedure(target: GLenum; reset: GLboolean; format: GLenum; _type: GLenum; values: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetMinmaxParameterivEXT: procedure(target: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetMinmaxParameterfvEXT: procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_histogram: Boolean; + +//***** GL_EXT_multi_draw_arrays *****// +var + glMultiDrawArraysEXT: procedure(mode: GLenum; first: PGLint; count: PGLsizei; primcount: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiDrawElementsEXT: procedure(mode: GLenum; count: PGLsizei; _type: GLenum; const indices: PGLvoid; primcount: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_multi_draw_arrays: Boolean; + +//***** GL_EXT_packed_depth_stencil *****// +const + GL_DEPTH_STENCIL_EXT = $84F9; + GL_UNSIGNED_INT_24_8_EXT = $84FA; + GL_DEPTH24_STENCIL8_EXT = $88F0; + GL_TEXTURE_STENCIL_SIZE_EXT = $88F1; + +function Load_GL_EXT_packed_depth_stencil: Boolean; + +//***** GL_EXT_packed_pixels *****// +const + GL_UNSIGNED_BYTE_3_3_2_EXT = $8032; + GL_UNSIGNED_SHORT_4_4_4_4_EXT = $8033; + GL_UNSIGNED_SHORT_5_5_5_1_EXT = $8034; + GL_UNSIGNED_INT_8_8_8_8_EXT = $8035; + GL_UNSIGNED_INT_10_10_10_2_EXT = $8036; + +function Load_GL_EXT_packed_pixels: Boolean; + +//***** GL_EXT_paletted_texture *****// +const + GL_COLOR_INDEX1_EXT = $80E2; + GL_COLOR_INDEX2_EXT = $80E3; + GL_COLOR_INDEX4_EXT = $80E4; + GL_COLOR_INDEX8_EXT = $80E5; + GL_COLOR_INDEX12_EXT = $80E6; + GL_COLOR_INDEX16_EXT = $80E7; + GL_COLOR_TABLE_FORMAT_EXT = $80D8; + GL_COLOR_TABLE_WIDTH_EXT = $80D9; + GL_COLOR_TABLE_RED_SIZE_EXT = $80DA; + GL_COLOR_TABLE_GREEN_SIZE_EXT = $80DB; + GL_COLOR_TABLE_BLUE_SIZE_EXT = $80DC; + GL_COLOR_TABLE_ALPHA_SIZE_EXT = $80DD; + GL_COLOR_TABLE_LUMINANCE_SIZE_EXT = $80DE; + GL_COLOR_TABLE_INTENSITY_SIZE_EXT = $80DF; + GL_TEXTURE_INDEX_SIZE_EXT = $80ED; + GL_TEXTURE_1D = $0DE0; + GL_TEXTURE_2D = $0DE1; + GL_TEXTURE_3D_EXT = $806F; + // GL_TEXTURE_CUBE_MAP_ARB { already defined } + GL_PROXY_TEXTURE_1D = $8063; + GL_PROXY_TEXTURE_2D = $8064; + GL_PROXY_TEXTURE_3D_EXT = $8070; + // GL_PROXY_TEXTURE_CUBE_MAP_ARB { already defined } + // GL_TEXTURE_1D { already defined } + // GL_TEXTURE_2D { already defined } + // GL_TEXTURE_3D_EXT { already defined } + // GL_TEXTURE_CUBE_MAP_ARB { already defined } +var + glColorTableEXT: procedure(target: GLenum; internalFormat: GLenum; width: GLsizei; format: GLenum; _type: GLenum; const data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + // glColorSubTableEXT { already defined } + glGetColorTableEXT: procedure(target: GLenum; format: GLenum; _type: GLenum; data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetColorTableParameterivEXT: procedure(target: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetColorTableParameterfvEXT: procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_paletted_texture: Boolean; + +//***** GL_EXT_point_parameters *****// +const + GL_POINT_SIZE_MIN_EXT = $8126; + GL_POINT_SIZE_MAX_EXT = $8127; + GL_POINT_FADE_THRESHOLD_SIZE_EXT = $8128; + GL_DISTANCE_ATTENUATION_EXT = $8129; +var + glPointParameterfEXT: procedure(pname: GLenum; param: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPointParameterfvEXT: procedure(pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_point_parameters: Boolean; + +//***** GL_EXT_polygon_offset *****// +const + GL_POLYGON_OFFSET_EXT = $8037; + GL_POLYGON_OFFSET_FACTOR_EXT = $8038; + GL_POLYGON_OFFSET_BIAS_EXT = $8039; +var + glPolygonOffsetEXT: procedure(factor: GLfloat; bias: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_polygon_offset: Boolean; + +//***** GL_EXT_secondary_color *****// +const + GL_COLOR_SUM_EXT = $8458; + GL_CURRENT_SECONDARY_COLOR_EXT = $8459; + GL_SECONDARY_COLOR_ARRAY_SIZE_EXT = $845A; + GL_SECONDARY_COLOR_ARRAY_TYPE_EXT = $845B; + GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT = $845C; + GL_SECONDARY_COLOR_ARRAY_POINTER_EXT = $845D; + GL_SECONDARY_COLOR_ARRAY_EXT = $845E; +var + glSecondaryColor3bEXT: procedure(components: GLbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3sEXT: procedure(components: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3iEXT: procedure(components: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3fEXT: procedure(components: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3dEXT: procedure(components: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3ubEXT: procedure(components: GLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3usEXT: procedure(components: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3uiEXT: procedure(components: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3bvEXT: procedure(components: GLbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3svEXT: procedure(components: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3ivEXT: procedure(components: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3fvEXT: procedure(components: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3dvEXT: procedure(components: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3ubvEXT: procedure(components: GLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3usvEXT: procedure(components: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3uivEXT: procedure(components: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColorPointerEXT: procedure(size: GLint; _type: GLenum; stride: GLsizei; pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_secondary_color: Boolean; + +//***** GL_EXT_separate_specular_color *****// +const + GL_LIGHT_MODEL_COLOR_CONTROL_EXT = $81F8; + GL_SINGLE_COLOR_EXT = $81F9; + GL_SEPARATE_SPECULAR_COLOR_EXT = $81FA; + +function Load_GL_EXT_separate_specular_color: Boolean; + +//***** GL_EXT_shadow_funcs *****// + +function Load_GL_EXT_shadow_funcs: Boolean; + +//***** GL_EXT_shared_texture_palette *****// +const + GL_SHARED_TEXTURE_PALETTE_EXT = $81FB; + +function Load_GL_EXT_shared_texture_palette: Boolean; + +//***** GL_EXT_stencil_two_side *****// +const + GL_STENCIL_TEST_TWO_SIDE_EXT = $8910; + GL_ACTIVE_STENCIL_FACE_EXT = $8911; +var + glActiveStencilFaceEXT: procedure(face: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_stencil_two_side: Boolean; + +//***** GL_EXT_stencil_wrap *****// +const + GL_INCR_WRAP_EXT = $8507; + GL_DECR_WRAP_EXT = $8508; + +function Load_GL_EXT_stencil_wrap: Boolean; + +//***** GL_EXT_subtexture *****// +var + glTexSubImage1DEXT: procedure(target: GLenum; level: GLint; xoffset: GLint; width: GLsizei; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexSubImage2DEXT: procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexSubImage3DEXT: procedure(target: GLenum; level: GLint; xoffset: GLint; yoffset: GLint; zoffset: GLint; width: GLsizei; height: GLsizei; depth: GLsizei; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_subtexture: Boolean; + +//***** GL_EXT_texture3D *****// +const + GL_PACK_SKIP_IMAGES_EXT = $806B; + GL_PACK_IMAGE_HEIGHT_EXT = $806C; + GL_UNPACK_SKIP_IMAGES_EXT = $806D; + GL_UNPACK_IMAGE_HEIGHT_EXT = $806E; + // GL_TEXTURE_3D_EXT { already defined } + // GL_PROXY_TEXTURE_3D_EXT { already defined } + GL_TEXTURE_DEPTH_EXT = $8071; + GL_TEXTURE_WRAP_R_EXT = $8072; + GL_MAX_3D_TEXTURE_SIZE_EXT = $8073; +var + glTexImage3DEXT: procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; height: GLsizei; depth: GLsizei; border: GLint; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_texture3D: Boolean; + +//***** GL_EXT_texture_compression_s3tc *****// +const + GL_COMPRESSED_RGB_S3TC_DXT1_EXT = $83F0; + GL_COMPRESSED_RGBA_S3TC_DXT1_EXT = $83F1; + GL_COMPRESSED_RGBA_S3TC_DXT3_EXT = $83F2; + GL_COMPRESSED_RGBA_S3TC_DXT5_EXT = $83F3; + +function Load_GL_EXT_texture_compression_s3tc: Boolean; + +//***** GL_EXT_texture_env_add *****// + +function Load_GL_EXT_texture_env_add: Boolean; + +//***** GL_EXT_texture_env_combine *****// +const + GL_COMBINE_EXT = $8570; + GL_COMBINE_RGB_EXT = $8571; + GL_COMBINE_ALPHA_EXT = $8572; + GL_SOURCE0_RGB_EXT = $8580; + GL_SOURCE1_RGB_EXT = $8581; + GL_SOURCE2_RGB_EXT = $8582; + GL_SOURCE0_ALPHA_EXT = $8588; + GL_SOURCE1_ALPHA_EXT = $8589; + GL_SOURCE2_ALPHA_EXT = $858A; + GL_OPERAND0_RGB_EXT = $8590; + GL_OPERAND1_RGB_EXT = $8591; + GL_OPERAND2_RGB_EXT = $8592; + GL_OPERAND0_ALPHA_EXT = $8598; + GL_OPERAND1_ALPHA_EXT = $8599; + GL_OPERAND2_ALPHA_EXT = $859A; + GL_RGB_SCALE_EXT = $8573; + GL_ADD_SIGNED_EXT = $8574; + GL_INTERPOLATE_EXT = $8575; + GL_CONSTANT_EXT = $8576; + GL_PRIMARY_COLOR_EXT = $8577; + GL_PREVIOUS_EXT = $8578; + +function Load_GL_EXT_texture_env_combine: Boolean; + +//***** GL_EXT_texture_env_dot3 *****// +const + GL_DOT3_RGB_EXT = $8740; + GL_DOT3_RGBA_EXT = $8741; + +function Load_GL_EXT_texture_env_dot3: Boolean; + +//***** GL_EXT_texture_filter_anisotropic *****// +const + GL_TEXTURE_MAX_ANISOTROPY_EXT = $84FE; + GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT = $84FF; + +function Load_GL_EXT_texture_filter_anisotropic: Boolean; + +//***** GL_EXT_texture_lod_bias *****// +const + GL_TEXTURE_FILTER_CONTROL_EXT = $8500; + GL_TEXTURE_LOD_BIAS_EXT = $8501; + GL_MAX_TEXTURE_LOD_BIAS_EXT = $84FD; + +function Load_GL_EXT_texture_lod_bias: Boolean; + +//***** GL_EXT_texture_object *****// +const + GL_TEXTURE_PRIORITY_EXT = $8066; + GL_TEXTURE_RESIDENT_EXT = $8067; + GL_TEXTURE_1D_BINDING_EXT = $8068; + GL_TEXTURE_2D_BINDING_EXT = $8069; + GL_TEXTURE_3D_BINDING_EXT = $806A; +var + glGenTexturesEXT: procedure(n: GLsizei; textures: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteTexturesEXT: procedure(n: GLsizei; const textures: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBindTextureEXT: procedure(target: GLenum; texture: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPrioritizeTexturesEXT: procedure(n: GLsizei; const textures: PGLuint; const priorities: PGLclampf); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glAreTexturesResidentEXT: function(n: GLsizei; const textures: PGLuint; residences: PGLboolean): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsTextureEXT: function(texture: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_texture_object: Boolean; + +//***** GL_EXT_vertex_array *****// +const + GL_VERTEX_ARRAY_EXT = $8074; + GL_NORMAL_ARRAY_EXT = $8075; + GL_COLOR_ARRAY_EXT = $8076; + GL_INDEX_ARRAY_EXT = $8077; + GL_TEXTURE_COORD_ARRAY_EXT = $8078; + GL_EDGE_FLAG_ARRAY_EXT = $8079; + GL_DOUBLE_EXT = $140A; + GL_VERTEX_ARRAY_SIZE_EXT = $807A; + GL_VERTEX_ARRAY_TYPE_EXT = $807B; + GL_VERTEX_ARRAY_STRIDE_EXT = $807C; + GL_VERTEX_ARRAY_COUNT_EXT = $807D; + GL_NORMAL_ARRAY_TYPE_EXT = $807E; + GL_NORMAL_ARRAY_STRIDE_EXT = $807F; + GL_NORMAL_ARRAY_COUNT_EXT = $8080; + GL_COLOR_ARRAY_SIZE_EXT = $8081; + GL_COLOR_ARRAY_TYPE_EXT = $8082; + GL_COLOR_ARRAY_STRIDE_EXT = $8083; + GL_COLOR_ARRAY_COUNT_EXT = $8084; + GL_INDEX_ARRAY_TYPE_EXT = $8085; + GL_INDEX_ARRAY_STRIDE_EXT = $8086; + GL_INDEX_ARRAY_COUNT_EXT = $8087; + GL_TEXTURE_COORD_ARRAY_SIZE_EXT = $8088; + GL_TEXTURE_COORD_ARRAY_TYPE_EXT = $8089; + GL_TEXTURE_COORD_ARRAY_STRIDE_EXT = $808A; + GL_TEXTURE_COORD_ARRAY_COUNT_EXT = $808B; + GL_EDGE_FLAG_ARRAY_STRIDE_EXT = $808C; + GL_EDGE_FLAG_ARRAY_COUNT_EXT = $808D; + GL_VERTEX_ARRAY_POINTER_EXT = $808E; + GL_NORMAL_ARRAY_POINTER_EXT = $808F; + GL_COLOR_ARRAY_POINTER_EXT = $8090; + GL_INDEX_ARRAY_POINTER_EXT = $8091; + GL_TEXTURE_COORD_ARRAY_POINTER_EXT = $8092; + GL_EDGE_FLAG_ARRAY_POINTER_EXT = $8093; +var + glArrayElementEXT: procedure(i: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDrawArraysEXT: procedure(mode: GLenum; first: GLint; count: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexPointerEXT: procedure(size: GLint; _type: GLenum; stride: GLsizei; count: GLsizei; const pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormalPointerEXT: procedure(_type: GLenum; stride: GLsizei; count: GLsizei; const pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColorPointerEXT: procedure(size: GLint; _type: GLenum; stride: GLsizei; count: GLsizei; const pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIndexPointerEXT: procedure(_type: GLenum; stride: GLsizei; count: GLsizei; const pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoordPointerEXT: procedure(size: GLint; _type: GLenum; stride: GLsizei; count: GLsizei; const pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEdgeFlagPointerEXT: procedure(stride: GLsizei; count: GLsizei; const pointer: PGLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetPointervEXT: procedure(pname: GLenum; params: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_vertex_array: Boolean; + +//***** GL_EXT_vertex_shader *****// +const + GL_VERTEX_SHADER_EXT = $8780; + GL_VARIANT_VALUE_EXT = $87E4; + GL_VARIANT_DATATYPE_EXT = $87E5; + GL_VARIANT_ARRAY_STRIDE_EXT = $87E6; + GL_VARIANT_ARRAY_TYPE_EXT = $87E7; + GL_VARIANT_ARRAY_EXT = $87E8; + GL_VARIANT_ARRAY_POINTER_EXT = $87E9; + GL_INVARIANT_VALUE_EXT = $87EA; + GL_INVARIANT_DATATYPE_EXT = $87EB; + GL_LOCAL_CONSTANT_VALUE_EXT = $87EC; + GL_LOCAL_CONSTANT_DATATYPE_EXT = $87ED; + GL_OP_INDEX_EXT = $8782; + GL_OP_NEGATE_EXT = $8783; + GL_OP_DOT3_EXT = $8784; + GL_OP_DOT4_EXT = $8785; + GL_OP_MUL_EXT = $8786; + GL_OP_ADD_EXT = $8787; + GL_OP_MADD_EXT = $8788; + GL_OP_FRAC_EXT = $8789; + GL_OP_MAX_EXT = $878A; + GL_OP_MIN_EXT = $878B; + GL_OP_SET_GE_EXT = $878C; + GL_OP_SET_LT_EXT = $878D; + GL_OP_CLAMP_EXT = $878E; + GL_OP_FLOOR_EXT = $878F; + GL_OP_ROUND_EXT = $8790; + GL_OP_EXP_BASE_2_EXT = $8791; + GL_OP_LOG_BASE_2_EXT = $8792; + GL_OP_POWER_EXT = $8793; + GL_OP_RECIP_EXT = $8794; + GL_OP_RECIP_SQRT_EXT = $8795; + GL_OP_SUB_EXT = $8796; + GL_OP_CROSS_PRODUCT_EXT = $8797; + GL_OP_MULTIPLY_MATRIX_EXT = $8798; + GL_OP_MOV_EXT = $8799; + GL_OUTPUT_VERTEX_EXT = $879A; + GL_OUTPUT_COLOR0_EXT = $879B; + GL_OUTPUT_COLOR1_EXT = $879C; + GL_OUTPUT_TEXTURE_COORD0_EXT = $879D; + GL_OUTPUT_TEXTURE_COORD1_EXT = $879E; + GL_OUTPUT_TEXTURE_COORD2_EXT = $879F; + GL_OUTPUT_TEXTURE_COORD3_EXT = $87A0; + GL_OUTPUT_TEXTURE_COORD4_EXT = $87A1; + GL_OUTPUT_TEXTURE_COORD5_EXT = $87A2; + GL_OUTPUT_TEXTURE_COORD6_EXT = $87A3; + GL_OUTPUT_TEXTURE_COORD7_EXT = $87A4; + GL_OUTPUT_TEXTURE_COORD8_EXT = $87A5; + GL_OUTPUT_TEXTURE_COORD9_EXT = $87A6; + GL_OUTPUT_TEXTURE_COORD10_EXT = $87A7; + GL_OUTPUT_TEXTURE_COORD11_EXT = $87A8; + GL_OUTPUT_TEXTURE_COORD12_EXT = $87A9; + GL_OUTPUT_TEXTURE_COORD13_EXT = $87AA; + GL_OUTPUT_TEXTURE_COORD14_EXT = $87AB; + GL_OUTPUT_TEXTURE_COORD15_EXT = $87AC; + GL_OUTPUT_TEXTURE_COORD16_EXT = $87AD; + GL_OUTPUT_TEXTURE_COORD17_EXT = $87AE; + GL_OUTPUT_TEXTURE_COORD18_EXT = $87AF; + GL_OUTPUT_TEXTURE_COORD19_EXT = $87B0; + GL_OUTPUT_TEXTURE_COORD20_EXT = $87B1; + GL_OUTPUT_TEXTURE_COORD21_EXT = $87B2; + GL_OUTPUT_TEXTURE_COORD22_EXT = $87B3; + GL_OUTPUT_TEXTURE_COORD23_EXT = $87B4; + GL_OUTPUT_TEXTURE_COORD24_EXT = $87B5; + GL_OUTPUT_TEXTURE_COORD25_EXT = $87B6; + GL_OUTPUT_TEXTURE_COORD26_EXT = $87B7; + GL_OUTPUT_TEXTURE_COORD27_EXT = $87B8; + GL_OUTPUT_TEXTURE_COORD28_EXT = $87B9; + GL_OUTPUT_TEXTURE_COORD29_EXT = $87BA; + GL_OUTPUT_TEXTURE_COORD30_EXT = $87BB; + GL_OUTPUT_TEXTURE_COORD31_EXT = $87BC; + GL_OUTPUT_FOG_EXT = $87BD; + GL_SCALAR_EXT = $87BE; + GL_VECTOR_EXT = $87BF; + GL_MATRIX_EXT = $87C0; + GL_VARIANT_EXT = $87C1; + GL_INVARIANT_EXT = $87C2; + GL_LOCAL_CONSTANT_EXT = $87C3; + GL_LOCAL_EXT = $87C4; + GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT = $87C5; + GL_MAX_VERTEX_SHADER_VARIANTS_EXT = $87C6; + GL_MAX_VERTEX_SHADER_INVARIANTS_EXT = $87C7; + GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT = $87C8; + GL_MAX_VERTEX_SHADER_LOCALS_EXT = $87C9; + GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT = $87CA; + GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT = $87CB; + GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT = $87CC; + GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT = $87CD; + GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT = $87CE; + GL_VERTEX_SHADER_INSTRUCTIONS_EXT = $87CF; + GL_VERTEX_SHADER_VARIANTS_EXT = $87D0; + GL_VERTEX_SHADER_INVARIANTS_EXT = $87D1; + GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT = $87D2; + GL_VERTEX_SHADER_LOCALS_EXT = $87D3; + GL_VERTEX_SHADER_BINDING_EXT = $8781; + GL_VERTEX_SHADER_OPTIMIZED_EXT = $87D4; + GL_X_EXT = $87D5; + GL_Y_EXT = $87D6; + GL_Z_EXT = $87D7; + GL_W_EXT = $87D8; + GL_NEGATIVE_X_EXT = $87D9; + GL_NEGATIVE_Y_EXT = $87DA; + GL_NEGATIVE_Z_EXT = $87DB; + GL_NEGATIVE_W_EXT = $87DC; + GL_ZERO_EXT = $87DD; + GL_ONE_EXT = $87DE; + GL_NEGATIVE_ONE_EXT = $87DF; + GL_NORMALIZED_RANGE_EXT = $87E0; + GL_FULL_RANGE_EXT = $87E1; + GL_CURRENT_VERTEX_EXT = $87E2; + GL_MVP_MATRIX_EXT = $87E3; +var + glBeginVertexShaderEXT: procedure(); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEndVertexShaderEXT: procedure(); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBindVertexShaderEXT: procedure(id: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGenVertexShadersEXT: function(range: GLuint): GLuint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteVertexShaderEXT: procedure(id: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glShaderOp1EXT: procedure(op: GLenum; res: GLuint; arg1: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glShaderOp2EXT: procedure(op: GLenum; res: GLuint; arg1: GLuint; arg2: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glShaderOp3EXT: procedure(op: GLenum; res: GLuint; arg1: GLuint; arg2: GLuint; arg3: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSwizzleEXT: procedure(res: GLuint; _in: GLuint; outX: GLenum; outY: GLenum; outZ: GLenum; outW: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWriteMaskEXT: procedure(res: GLuint; _in: GLuint; outX: GLenum; outY: GLenum; outZ: GLenum; outW: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glInsertComponentEXT: procedure(res: GLuint; src: GLuint; num: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glExtractComponentEXT: procedure(res: GLuint; src: GLuint; num: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGenSymbolsEXT: function(datatype: GLenum; storagetype: GLenum; range: GLenum; components: GLuint): GLuint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSetInvariantEXT: procedure(id: GLuint; _type: GLenum; addr: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSetLocalConstantEXT: procedure(id: GLuint; _type: GLenum; addr: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVariantbvEXT: procedure(id: GLuint; addr: PGLbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVariantsvEXT: procedure(id: GLuint; addr: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVariantivEXT: procedure(id: GLuint; addr: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVariantfvEXT: procedure(id: GLuint; addr: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVariantdvEXT: procedure(id: GLuint; addr: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVariantubvEXT: procedure(id: GLuint; addr: PGLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVariantusvEXT: procedure(id: GLuint; addr: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVariantuivEXT: procedure(id: GLuint; addr: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVariantPointerEXT: procedure(id: GLuint; _type: GLenum; stride: GLuint; addr: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEnableVariantClientStateEXT: procedure(id: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDisableVariantClientStateEXT: procedure(id: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBindLightParameterEXT: function(light: GLenum; value: GLenum): GLuint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBindMaterialParameterEXT: function(face: GLenum; value: GLenum): GLuint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBindTexGenParameterEXT: function(_unit: GLenum; coord: GLenum; value: GLenum): GLuint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBindTextureUnitParameterEXT: function(_unit: GLenum; value: GLenum): GLuint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBindParameterEXT: function(value: GLenum): GLuint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsVariantEnabledEXT: function(id: GLuint; cap: GLenum): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVariantBooleanvEXT: procedure(id: GLuint; value: GLenum; data: PGLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVariantIntegervEXT: procedure(id: GLuint; value: GLenum; data: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVariantFloatvEXT: procedure(id: GLuint; value: GLenum; data: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVariantPointervEXT: procedure(id: GLuint; value: GLenum; data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetInvariantBooleanvEXT: procedure(id: GLuint; value: GLenum; data: PGLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetInvariantIntegervEXT: procedure(id: GLuint; value: GLenum; data: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetInvariantFloatvEXT: procedure(id: GLuint; value: GLenum; data: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetLocalConstantBooleanvEXT: procedure(id: GLuint; value: GLenum; data: PGLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetLocalConstantIntegervEXT: procedure(id: GLuint; value: GLenum; data: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetLocalConstantFloatvEXT: procedure(id: GLuint; value: GLenum; data: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_vertex_shader: Boolean; + +//***** GL_EXT_vertex_weighting *****// +const + GL_VERTEX_WEIGHTING_EXT = $8509; + GL_MODELVIEW0_EXT = $1700; + GL_MODELVIEW1_EXT = $850A; + GL_MODELVIEW0_MATRIX_EXT = $0BA6; + GL_MODELVIEW1_MATRIX_EXT = $8506; + GL_CURRENT_VERTEX_WEIGHT_EXT = $850B; + GL_VERTEX_WEIGHT_ARRAY_EXT = $850C; + GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT = $850D; + GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT = $850E; + GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT = $850F; + GL_MODELVIEW0_STACK_DEPTH_EXT = $0BA3; + GL_MODELVIEW1_STACK_DEPTH_EXT = $8502; + GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT = $8510; +var + glVertexWeightfEXT: procedure(weight: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexWeightfvEXT: procedure(weight: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexWeightPointerEXT: procedure(size: GLint; _type: GLenum; stride: GLsizei; pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_vertex_weighting: Boolean; + +//***** GL_HP_occlusion_test *****// +const + GL_OCCLUSION_TEST_HP = $8165; + GL_OCCLUSION_TEST_RESULT_HP = $8166; + +function Load_GL_HP_occlusion_test: Boolean; + +//***** GL_NV_blend_square *****// + +function Load_GL_NV_blend_square: Boolean; + +//***** GL_NV_copy_depth_to_color *****// +const + GL_DEPTH_STENCIL_TO_RGBA_NV = $886E; + GL_DEPTH_STENCIL_TO_BGRA_NV = $886F; + +function Load_GL_NV_copy_depth_to_color: Boolean; + +//***** GL_NV_depth_clamp *****// +const + GL_DEPTH_CLAMP_NV = $864F; + +function Load_GL_NV_depth_clamp: Boolean; + +//***** GL_NV_evaluators *****// +const + GL_EVAL_2D_NV = $86C0; + GL_EVAL_TRIANGULAR_2D_NV = $86C1; + GL_MAP_TESSELLATION_NV = $86C2; + GL_MAP_ATTRIB_U_ORDER_NV = $86C3; + GL_MAP_ATTRIB_V_ORDER_NV = $86C4; + GL_EVAL_FRACTIONAL_TESSELLATION_NV = $86C5; + GL_EVAL_VERTEX_ATTRIB0_NV = $86C6; + GL_EVAL_VERTEX_ATTRIB1_NV = $86C7; + GL_EVAL_VERTEX_ATTRIB2_NV = $86C8; + GL_EVAL_VERTEX_ATTRIB3_NV = $86C9; + GL_EVAL_VERTEX_ATTRIB4_NV = $86CA; + GL_EVAL_VERTEX_ATTRIB5_NV = $86CB; + GL_EVAL_VERTEX_ATTRIB6_NV = $86CC; + GL_EVAL_VERTEX_ATTRIB7_NV = $86CD; + GL_EVAL_VERTEX_ATTRIB8_NV = $86CE; + GL_EVAL_VERTEX_ATTRIB9_NV = $86CF; + GL_EVAL_VERTEX_ATTRIB10_NV = $86D0; + GL_EVAL_VERTEX_ATTRIB11_NV = $86D1; + GL_EVAL_VERTEX_ATTRIB12_NV = $86D2; + GL_EVAL_VERTEX_ATTRIB13_NV = $86D3; + GL_EVAL_VERTEX_ATTRIB14_NV = $86D4; + GL_EVAL_VERTEX_ATTRIB15_NV = $86D5; + GL_MAX_MAP_TESSELLATION_NV = $86D6; + GL_MAX_RATIONAL_EVAL_ORDER_NV = $86D7; +var + glMapControlPointsNV: procedure(target: GLenum; index: GLuint; _type: GLenum; ustride: GLsizei; vstride: GLsizei; uorder: GLint; vorder: GLint; _packed: GLboolean; const points: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMapParameterivNV: procedure(target: GLenum; pname: GLenum; const params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMapParameterfvNV: procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetMapControlPointsNV: procedure(target: GLenum; index: GLuint; _type: GLenum; ustride: GLsizei; vstride: GLsizei; _packed: GLboolean; points: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetMapParameterivNV: procedure(target: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetMapParameterfvNV: procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetMapAttribParameterivNV: procedure(target: GLenum; index: GLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetMapAttribParameterfvNV: procedure(target: GLenum; index: GLuint; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEvalMapsNV: procedure(target: GLenum; mode: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_NV_evaluators: Boolean; + +//***** GL_NV_fence *****// +const + GL_ALL_COMPLETED_NV = $84F2; + GL_FENCE_STATUS_NV = $84F3; + GL_FENCE_CONDITION_NV = $84F4; +var + glGenFencesNV: procedure(n: GLsizei; fences: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteFencesNV: procedure(n: GLsizei; const fences: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSetFenceNV: procedure(fence: GLuint; condition: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTestFenceNV: function(fence: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFinishFenceNV: procedure(fence: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsFenceNV: function(fence: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetFenceivNV: procedure(fence: GLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_NV_fence: Boolean; + +//***** GL_NV_fog_distance *****// +const + GL_FOG_DISTANCE_MODE_NV = $855A; + GL_EYE_RADIAL_NV = $855B; + GL_EYE_PLANE_ABSOLUTE_NV = $855C; + +function Load_GL_NV_fog_distance: Boolean; + +//***** GL_NV_light_max_exponent *****// +const + GL_MAX_SHININESS_NV = $8504; + GL_MAX_SPOT_EXPONENT_NV = $8505; + +function Load_GL_NV_light_max_exponent: Boolean; + +//***** GL_NV_multisample_filter_hint *****// +const + GL_MULTISAMPLE_FILTER_HINT_NV = $8534; + +function Load_GL_NV_multisample_filter_hint: Boolean; + +//***** GL_NV_occlusion_query *****// + // GL_OCCLUSION_TEST_HP { already defined } + // GL_OCCLUSION_TEST_RESULT_HP { already defined } +const + GL_PIXEL_COUNTER_BITS_NV = $8864; + GL_CURRENT_OCCLUSION_QUERY_ID_NV = $8865; + GL_PIXEL_COUNT_NV = $8866; + GL_PIXEL_COUNT_AVAILABLE_NV = $8867; +var + glGenOcclusionQueriesNV: procedure(n: GLsizei; ids: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteOcclusionQueriesNV: procedure(n: GLsizei; const ids: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsOcclusionQueryNV: function(id: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBeginOcclusionQueryNV: procedure(id: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEndOcclusionQueryNV: procedure(); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetOcclusionQueryivNV: procedure(id: GLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetOcclusionQueryuivNV: procedure(id: GLuint; pname: GLenum; params: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_NV_occlusion_query: Boolean; + +//***** GL_NV_packed_depth_stencil *****// +const + GL_DEPTH_STENCIL_NV = $84F9; + GL_UNSIGNED_INT_24_8_NV = $84FA; + +function Load_GL_NV_packed_depth_stencil: Boolean; + +//***** GL_NV_point_sprite *****// +const + GL_POINT_SPRITE_NV = $8861; + GL_COORD_REPLACE_NV = $8862; + GL_POINT_SPRITE_R_MODE_NV = $8863; +var + glPointParameteriNV: procedure(pname: GLenum; param: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPointParameterivNV: procedure(pname: GLenum; const params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_NV_point_sprite: Boolean; + +//***** GL_NV_register_combiners *****// +const + GL_REGISTER_COMBINERS_NV = $8522; + GL_COMBINER0_NV = $8550; + GL_COMBINER1_NV = $8551; + GL_COMBINER2_NV = $8552; + GL_COMBINER3_NV = $8553; + GL_COMBINER4_NV = $8554; + GL_COMBINER5_NV = $8555; + GL_COMBINER6_NV = $8556; + GL_COMBINER7_NV = $8557; + GL_VARIABLE_A_NV = $8523; + GL_VARIABLE_B_NV = $8524; + GL_VARIABLE_C_NV = $8525; + GL_VARIABLE_D_NV = $8526; + GL_VARIABLE_E_NV = $8527; + GL_VARIABLE_F_NV = $8528; + GL_VARIABLE_G_NV = $8529; + GL_CONSTANT_COLOR0_NV = $852A; + GL_CONSTANT_COLOR1_NV = $852B; + GL_PRIMARY_COLOR_NV = $852C; + GL_SECONDARY_COLOR_NV = $852D; + GL_SPARE0_NV = $852E; + GL_SPARE1_NV = $852F; + GL_UNSIGNED_IDENTITY_NV = $8536; + GL_UNSIGNED_INVERT_NV = $8537; + GL_EXPAND_NORMAL_NV = $8538; + GL_EXPAND_NEGATE_NV = $8539; + GL_HALF_BIAS_NORMAL_NV = $853A; + GL_HALF_BIAS_NEGATE_NV = $853B; + GL_SIGNED_IDENTITY_NV = $853C; + GL_SIGNED_NEGATE_NV = $853D; + GL_E_TIMES_F_NV = $8531; + GL_SPARE0_PLUS_SECONDARY_COLOR_NV = $8532; + GL_SCALE_BY_TWO_NV = $853E; + GL_SCALE_BY_FOUR_NV = $853F; + GL_SCALE_BY_ONE_HALF_NV = $8540; + GL_BIAS_BY_NEGATIVE_ONE_HALF_NV = $8541; + GL_DISCARD_NV = $8530; + GL_COMBINER_INPUT_NV = $8542; + GL_COMBINER_MAPPING_NV = $8543; + GL_COMBINER_COMPONENT_USAGE_NV = $8544; + GL_COMBINER_AB_DOT_PRODUCT_NV = $8545; + GL_COMBINER_CD_DOT_PRODUCT_NV = $8546; + GL_COMBINER_MUX_SUM_NV = $8547; + GL_COMBINER_SCALE_NV = $8548; + GL_COMBINER_BIAS_NV = $8549; + GL_COMBINER_AB_OUTPUT_NV = $854A; + GL_COMBINER_CD_OUTPUT_NV = $854B; + GL_COMBINER_SUM_OUTPUT_NV = $854C; + GL_NUM_GENERAL_COMBINERS_NV = $854E; + GL_COLOR_SUM_CLAMP_NV = $854F; + GL_MAX_GENERAL_COMBINERS_NV = $854D; +var + glCombinerParameterfvNV: procedure(pname: GLenum; const params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCombinerParameterivNV: procedure(pname: GLenum; const params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCombinerParameterfNV: procedure(pname: GLenum; param: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCombinerParameteriNV: procedure(pname: GLenum; param: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCombinerInputNV: procedure(stage: GLenum; portion: GLenum; variable: GLenum; input: GLenum; mapping: GLenum; componentUsage: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCombinerOutputNV: procedure(stage: GLenum; portion: GLenum; abOutput: GLenum; cdOutput: GLenum; sumOutput: GLenum; scale: GLenum; bias: GLenum; abDotProduct: GLboolean; cdDotProduct: GLboolean; muxSum: GLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFinalCombinerInputNV: procedure(variable: GLenum; input: GLenum; mapping: GLenum; componentUsage: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetCombinerInputParameterfvNV: procedure(stage: GLenum; portion: GLenum; variable: GLenum; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetCombinerInputParameterivNV: procedure(stage: GLenum; portion: GLenum; variable: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetCombinerOutputParameterfvNV: procedure(stage: GLenum; portion: GLenum; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetCombinerOutputParameterivNV: procedure(stage: GLenum; portion: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetFinalCombinerInputParameterfvNV: procedure(variable: GLenum; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetFinalCombinerInputParameterivNV: procedure(variable: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_NV_register_combiners: Boolean; + +//***** GL_NV_register_combiners2 *****// +const + GL_PER_STAGE_CONSTANTS_NV = $8535; +var + glCombinerStageParameterfvNV: procedure(stage: GLenum; pname: GLenum; const params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetCombinerStageParameterfvNV: procedure(stage: GLenum; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_NV_register_combiners2: Boolean; + +//***** GL_NV_texgen_emboss *****// +const + GL_EMBOSS_MAP_NV = $855F; + GL_EMBOSS_LIGHT_NV = $855D; + GL_EMBOSS_CONSTANT_NV = $855E; + +function Load_GL_NV_texgen_emboss: Boolean; + +//***** GL_NV_texgen_reflection *****// +const + GL_NORMAL_MAP_NV = $8511; + GL_REFLECTION_MAP_NV = $8512; + +function Load_GL_NV_texgen_reflection: Boolean; + +//***** GL_NV_texture_compression_vtc *****// + // GL_COMPRESSED_RGB_S3TC_DXT1_EXT { already defined } + // GL_COMPRESSED_RGBA_S3TC_DXT1_EXT { already defined } + // GL_COMPRESSED_RGBA_S3TC_DXT3_EXT { already defined } + // GL_COMPRESSED_RGBA_S3TC_DXT5_EXT { already defined } + +function Load_GL_NV_texture_compression_vtc: Boolean; + +//***** GL_NV_texture_env_combine4 *****// +const + GL_COMBINE4_NV = $8503; + GL_SOURCE3_RGB_NV = $8583; + GL_SOURCE3_ALPHA_NV = $858B; + GL_OPERAND3_RGB_NV = $8593; + GL_OPERAND3_ALPHA_NV = $859B; + +function Load_GL_NV_texture_env_combine4: Boolean; + +//***** GL_NV_texture_rectangle *****// +const + GL_TEXTURE_RECTANGLE_NV = $84F5; + GL_TEXTURE_BINDING_RECTANGLE_NV = $84F6; + GL_PROXY_TEXTURE_RECTANGLE_NV = $84F7; + GL_MAX_RECTANGLE_TEXTURE_SIZE_NV = $84F8; + +function Load_GL_NV_texture_rectangle: Boolean; + +//***** GL_NV_texture_shader *****// +const + GL_TEXTURE_SHADER_NV = $86DE; + GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV = $86D9; + GL_SHADER_OPERATION_NV = $86DF; + GL_CULL_MODES_NV = $86E0; + GL_OFFSET_TEXTURE_MATRIX_NV = $86E1; + GL_OFFSET_TEXTURE_SCALE_NV = $86E2; + GL_OFFSET_TEXTURE_BIAS_NV = $86E3; + GL_PREVIOUS_TEXTURE_INPUT_NV = $86E4; + GL_CONST_EYE_NV = $86E5; + GL_SHADER_CONSISTENT_NV = $86DD; + GL_PASS_THROUGH_NV = $86E6; + GL_CULL_FRAGMENT_NV = $86E7; + GL_OFFSET_TEXTURE_2D_NV = $86E8; + GL_OFFSET_TEXTURE_RECTANGLE_NV = $864C; + GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV = $864D; + GL_DEPENDENT_AR_TEXTURE_2D_NV = $86E9; + GL_DEPENDENT_GB_TEXTURE_2D_NV = $86EA; + GL_DOT_PRODUCT_NV = $86EC; + GL_DOT_PRODUCT_DEPTH_REPLACE_NV = $86ED; + GL_DOT_PRODUCT_TEXTURE_2D_NV = $86EE; + GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV = $864E; + GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV = $86F0; + GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV = $86F1; + GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV = $86F2; + GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV = $86F3; + GL_HILO_NV = $86F4; + GL_DSDT_NV = $86F5; + GL_DSDT_MAG_NV = $86F6; + GL_DSDT_MAG_VIB_NV = $86F7; + GL_UNSIGNED_INT_S8_S8_8_8_NV = $86DA; + GL_UNSIGNED_INT_8_8_S8_S8_REV_NV = $86DB; + GL_SIGNED_RGBA_NV = $86FB; + GL_SIGNED_RGBA8_NV = $86FC; + GL_SIGNED_RGB_NV = $86FE; + GL_SIGNED_RGB8_NV = $86FF; + GL_SIGNED_LUMINANCE_NV = $8701; + GL_SIGNED_LUMINANCE8_NV = $8702; + GL_SIGNED_LUMINANCE_ALPHA_NV = $8703; + GL_SIGNED_LUMINANCE8_ALPHA8_NV = $8704; + GL_SIGNED_ALPHA_NV = $8705; + GL_SIGNED_ALPHA8_NV = $8706; + GL_SIGNED_INTENSITY_NV = $8707; + GL_SIGNED_INTENSITY8_NV = $8708; + GL_SIGNED_RGB_UNSIGNED_ALPHA_NV = $870C; + GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV = $870D; + GL_HILO16_NV = $86F8; + GL_SIGNED_HILO_NV = $86F9; + GL_SIGNED_HILO16_NV = $86FA; + GL_DSDT8_NV = $8709; + GL_DSDT8_MAG8_NV = $870A; + GL_DSDT_MAG_INTENSITY_NV = $86DC; + GL_DSDT8_MAG8_INTENSITY8_NV = $870B; + GL_HI_SCALE_NV = $870E; + GL_LO_SCALE_NV = $870F; + GL_DS_SCALE_NV = $8710; + GL_DT_SCALE_NV = $8711; + GL_MAGNITUDE_SCALE_NV = $8712; + GL_VIBRANCE_SCALE_NV = $8713; + GL_HI_BIAS_NV = $8714; + GL_LO_BIAS_NV = $8715; + GL_DS_BIAS_NV = $8716; + GL_DT_BIAS_NV = $8717; + GL_MAGNITUDE_BIAS_NV = $8718; + GL_VIBRANCE_BIAS_NV = $8719; + GL_TEXTURE_BORDER_VALUES_NV = $871A; + GL_TEXTURE_HI_SIZE_NV = $871B; + GL_TEXTURE_LO_SIZE_NV = $871C; + GL_TEXTURE_DS_SIZE_NV = $871D; + GL_TEXTURE_DT_SIZE_NV = $871E; + GL_TEXTURE_MAG_SIZE_NV = $871F; + +function Load_GL_NV_texture_shader: Boolean; + +//***** GL_NV_texture_shader2 *****// +const + GL_DOT_PRODUCT_TEXTURE_3D_NV = $86EF; + // GL_HILO_NV { already defined } + // GL_DSDT_NV { already defined } + // GL_DSDT_MAG_NV { already defined } + // GL_DSDT_MAG_VIB_NV { already defined } + // GL_UNSIGNED_INT_S8_S8_8_8_NV { already defined } + // GL_UNSIGNED_INT_8_8_S8_S8_REV_NV { already defined } + // GL_SIGNED_RGBA_NV { already defined } + // GL_SIGNED_RGBA8_NV { already defined } + // GL_SIGNED_RGB_NV { already defined } + // GL_SIGNED_RGB8_NV { already defined } + // GL_SIGNED_LUMINANCE_NV { already defined } + // GL_SIGNED_LUMINANCE8_NV { already defined } + // GL_SIGNED_LUMINANCE_ALPHA_NV { already defined } + // GL_SIGNED_LUMINANCE8_ALPHA8_NV { already defined } + // GL_SIGNED_ALPHA_NV { already defined } + // GL_SIGNED_ALPHA8_NV { already defined } + // GL_SIGNED_INTENSITY_NV { already defined } + // GL_SIGNED_INTENSITY8_NV { already defined } + // GL_SIGNED_RGB_UNSIGNED_ALPHA_NV { already defined } + // GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV { already defined } + // GL_HILO16_NV { already defined } + // GL_SIGNED_HILO_NV { already defined } + // GL_SIGNED_HILO16_NV { already defined } + // GL_DSDT8_NV { already defined } + // GL_DSDT8_MAG8_NV { already defined } + // GL_DSDT_MAG_INTENSITY_NV { already defined } + // GL_DSDT8_MAG8_INTENSITY8_NV { already defined } + +function Load_GL_NV_texture_shader2: Boolean; + +//***** GL_NV_texture_shader3 *****// +const + GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV = $8850; + GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV = $8851; + GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV = $8852; + GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV = $8853; + GL_OFFSET_HILO_TEXTURE_2D_NV = $8854; + GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV = $8855; + GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV = $8856; + GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV = $8857; + GL_DEPENDENT_HILO_TEXTURE_2D_NV = $8858; + GL_DEPENDENT_RGB_TEXTURE_3D_NV = $8859; + GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV = $885A; + GL_DOT_PRODUCT_PASS_THROUGH_NV = $885B; + GL_DOT_PRODUCT_TEXTURE_1D_NV = $885C; + GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV = $885D; + GL_HILO8_NV = $885E; + GL_SIGNED_HILO8_NV = $885F; + GL_FORCE_BLUE_TO_ONE_NV = $8860; + +function Load_GL_NV_texture_shader3: Boolean; + +//***** GL_NV_vertex_array_range *****// +const + GL_VERTEX_ARRAY_RANGE_NV = $851D; + GL_VERTEX_ARRAY_RANGE_LENGTH_NV = $851E; + GL_VERTEX_ARRAY_RANGE_VALID_NV = $851F; + GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV = $8520; + GL_VERTEX_ARRAY_RANGE_POINTER_NV = $8521; +var + glVertexArrayRangeNV: procedure(length: GLsizei; pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFlushVertexArrayRangeNV: procedure(); {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{$IFDEF msWindows} + wglAllocateMemoryNV: function(size: GLsizei; readFrequency: GLfloat; writeFrequency: GLfloat; priority: GLfloat): PGLvoid; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglFreeMemoryNV: procedure(pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{$ENDIF} + +function Load_GL_NV_vertex_array_range: Boolean; + +//***** GL_NV_vertex_array_range2 *****// +const + GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV = $8533; + +function Load_GL_NV_vertex_array_range2: Boolean; + +//***** GL_NV_vertex_program *****// +const + GL_VERTEX_PROGRAM_NV = $8620; + GL_VERTEX_PROGRAM_POINT_SIZE_NV = $8642; + GL_VERTEX_PROGRAM_TWO_SIDE_NV = $8643; + GL_VERTEX_STATE_PROGRAM_NV = $8621; + GL_ATTRIB_ARRAY_SIZE_NV = $8623; + GL_ATTRIB_ARRAY_STRIDE_NV = $8624; + GL_ATTRIB_ARRAY_TYPE_NV = $8625; + GL_CURRENT_ATTRIB_NV = $8626; + GL_PROGRAM_PARAMETER_NV = $8644; + GL_ATTRIB_ARRAY_POINTER_NV = $8645; + GL_PROGRAM_TARGET_NV = $8646; + GL_PROGRAM_LENGTH_NV = $8627; + GL_PROGRAM_RESIDENT_NV = $8647; + GL_PROGRAM_STRING_NV = $8628; + GL_TRACK_MATRIX_NV = $8648; + GL_TRACK_MATRIX_TRANSFORM_NV = $8649; + GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV = $862E; + GL_MAX_TRACK_MATRICES_NV = $862F; + GL_CURRENT_MATRIX_STACK_DEPTH_NV = $8640; + GL_CURRENT_MATRIX_NV = $8641; + GL_VERTEX_PROGRAM_BINDING_NV = $864A; + GL_PROGRAM_ERROR_POSITION_NV = $864B; + GL_MODELVIEW_PROJECTION_NV = $8629; + GL_MATRIX0_NV = $8630; + GL_MATRIX1_NV = $8631; + GL_MATRIX2_NV = $8632; + GL_MATRIX3_NV = $8633; + GL_MATRIX4_NV = $8634; + GL_MATRIX5_NV = $8635; + GL_MATRIX6_NV = $8636; + GL_MATRIX7_NV = $8637; + GL_IDENTITY_NV = $862A; + GL_INVERSE_NV = $862B; + GL_TRANSPOSE_NV = $862C; + GL_INVERSE_TRANSPOSE_NV = $862D; + GL_VERTEX_ATTRIB_ARRAY0_NV = $8650; + GL_VERTEX_ATTRIB_ARRAY1_NV = $8651; + GL_VERTEX_ATTRIB_ARRAY2_NV = $8652; + GL_VERTEX_ATTRIB_ARRAY3_NV = $8653; + GL_VERTEX_ATTRIB_ARRAY4_NV = $8654; + GL_VERTEX_ATTRIB_ARRAY5_NV = $8655; + GL_VERTEX_ATTRIB_ARRAY6_NV = $8656; + GL_VERTEX_ATTRIB_ARRAY7_NV = $8657; + GL_VERTEX_ATTRIB_ARRAY8_NV = $8658; + GL_VERTEX_ATTRIB_ARRAY9_NV = $8659; + GL_VERTEX_ATTRIB_ARRAY10_NV = $865A; + GL_VERTEX_ATTRIB_ARRAY11_NV = $865B; + GL_VERTEX_ATTRIB_ARRAY12_NV = $865C; + GL_VERTEX_ATTRIB_ARRAY13_NV = $865D; + GL_VERTEX_ATTRIB_ARRAY14_NV = $865E; + GL_VERTEX_ATTRIB_ARRAY15_NV = $865F; + GL_MAP1_VERTEX_ATTRIB0_4_NV = $8660; + GL_MAP1_VERTEX_ATTRIB1_4_NV = $8661; + GL_MAP1_VERTEX_ATTRIB2_4_NV = $8662; + GL_MAP1_VERTEX_ATTRIB3_4_NV = $8663; + GL_MAP1_VERTEX_ATTRIB4_4_NV = $8664; + GL_MAP1_VERTEX_ATTRIB5_4_NV = $8665; + GL_MAP1_VERTEX_ATTRIB6_4_NV = $8666; + GL_MAP1_VERTEX_ATTRIB7_4_NV = $8667; + GL_MAP1_VERTEX_ATTRIB8_4_NV = $8668; + GL_MAP1_VERTEX_ATTRIB9_4_NV = $8669; + GL_MAP1_VERTEX_ATTRIB10_4_NV = $866A; + GL_MAP1_VERTEX_ATTRIB11_4_NV = $866B; + GL_MAP1_VERTEX_ATTRIB12_4_NV = $866C; + GL_MAP1_VERTEX_ATTRIB13_4_NV = $866D; + GL_MAP1_VERTEX_ATTRIB14_4_NV = $866E; + GL_MAP1_VERTEX_ATTRIB15_4_NV = $866F; + GL_MAP2_VERTEX_ATTRIB0_4_NV = $8670; + GL_MAP2_VERTEX_ATTRIB1_4_NV = $8671; + GL_MAP2_VERTEX_ATTRIB2_4_NV = $8672; + GL_MAP2_VERTEX_ATTRIB3_4_NV = $8673; + GL_MAP2_VERTEX_ATTRIB4_4_NV = $8674; + GL_MAP2_VERTEX_ATTRIB5_4_NV = $8675; + GL_MAP2_VERTEX_ATTRIB6_4_NV = $8676; + GL_MAP2_VERTEX_ATTRIB7_4_NV = $8677; + GL_MAP2_VERTEX_ATTRIB8_4_NV = $8678; + GL_MAP2_VERTEX_ATTRIB9_4_NV = $8679; + GL_MAP2_VERTEX_ATTRIB10_4_NV = $867A; + GL_MAP2_VERTEX_ATTRIB11_4_NV = $867B; + GL_MAP2_VERTEX_ATTRIB12_4_NV = $867C; + GL_MAP2_VERTEX_ATTRIB13_4_NV = $867D; + GL_MAP2_VERTEX_ATTRIB14_4_NV = $867E; + GL_MAP2_VERTEX_ATTRIB15_4_NV = $867F; +var + glBindProgramNV: procedure(target: GLenum; id: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteProgramsNV: procedure(n: GLsizei; const ids: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glExecuteProgramNV: procedure(target: GLenum; id: GLuint; const params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGenProgramsNV: procedure(n: GLsizei; ids: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glAreProgramsResidentNV: function(n: GLsizei; const ids: PGLuint; residences: PGLboolean): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRequestResidentProgramsNV: procedure(n: GLsizei; ids: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetProgramParameterfvNV: procedure(target: GLenum; index: GLuint; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetProgramParameterdvNV: procedure(target: GLenum; index: GLuint; pname: GLenum; params: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetProgramivNV: procedure(id: GLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetProgramStringNV: procedure(id: GLuint; pname: GLenum; _program: PGLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetTrackMatrixivNV: procedure(target: GLenum; address: GLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVertexAttribdvNV: procedure(index: GLuint; pname: GLenum; params: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVertexAttribfvNV: procedure(index: GLuint; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVertexAttribivNV: procedure(index: GLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVertexAttribPointervNV: procedure(index: GLuint; pname: GLenum; pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsProgramNV: function(id: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLoadProgramNV: procedure(target: GLenum; id: GLuint; len: GLsizei; const _program: PGLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramParameter4fNV: procedure(target: GLenum; index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramParameter4fvNV: procedure(target: GLenum; index: GLuint; const params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramParameters4dvNV: procedure(target: GLenum; index: GLuint; num: GLuint; const params: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramParameters4fvNV: procedure(target: GLenum; index: GLuint; num: GLuint; const params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTrackMatrixNV: procedure(target: GLenum; address: GLuint; matrix: GLenum; transform: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribPointerNV: procedure(index: GLuint; size: GLint; _type: GLenum; stride: GLsizei; const pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib1sNV: procedure(index: GLuint; x: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib1fNV: procedure(index: GLuint; x: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib1dNV: procedure(index: GLuint; x: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib2sNV: procedure(index: GLuint; x: GLshort; y: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib2fNV: procedure(index: GLuint; x: GLfloat; y: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib2dNV: procedure(index: GLuint; x: GLdouble; y: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib3sNV: procedure(index: GLuint; x: GLshort; y: GLshort; z: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib3fNV: procedure(index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib3dNV: procedure(index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4sNV: procedure(index: GLuint; x: GLshort; y: GLshort; z: GLshort; w: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4fNV: procedure(index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4dNV: procedure(index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4ubNV: procedure(index: GLuint; x: GLubyte; y: GLubyte; z: GLubyte; w: GLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib1svNV: procedure(index: GLuint; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib1fvNV: procedure(index: GLuint; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib1dvNV: procedure(index: GLuint; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib2svNV: procedure(index: GLuint; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib2fvNV: procedure(index: GLuint; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib2dvNV: procedure(index: GLuint; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib3svNV: procedure(index: GLuint; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib3fvNV: procedure(index: GLuint; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib3dvNV: procedure(index: GLuint; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4svNV: procedure(index: GLuint; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4fvNV: procedure(index: GLuint; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4dvNV: procedure(index: GLuint; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4ubvNV: procedure(index: GLuint; const v: PGLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribs1svNV: procedure(index: GLuint; n: GLsizei; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribs1fvNV: procedure(index: GLuint; n: GLsizei; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribs1dvNV: procedure(index: GLuint; n: GLsizei; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribs2svNV: procedure(index: GLuint; n: GLsizei; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribs2fvNV: procedure(index: GLuint; n: GLsizei; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribs2dvNV: procedure(index: GLuint; n: GLsizei; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribs3svNV: procedure(index: GLuint; n: GLsizei; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribs3fvNV: procedure(index: GLuint; n: GLsizei; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribs3dvNV: procedure(index: GLuint; n: GLsizei; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribs4svNV: procedure(index: GLuint; n: GLsizei; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribs4fvNV: procedure(index: GLuint; n: GLsizei; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribs4dvNV: procedure(index: GLuint; n: GLsizei; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribs4ubvNV: procedure(index: GLuint; n: GLsizei; const v: PGLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_NV_vertex_program: Boolean; + +//***** GL_NV_vertex_program1_1 *****// + +function Load_GL_NV_vertex_program1_1: Boolean; + +//***** GL_ATI_element_array *****// +const + GL_ELEMENT_ARRAY_ATI = $8768; + GL_ELEMENT_ARRAY_TYPE_ATI = $8769; + GL_ELEMENT_ARRAY_POINTER_ATI = $876A; +var + glElementPointerATI: procedure(_type: GLenum; const pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDrawElementArrayATI: procedure(mode: GLenum; count: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDrawRangeElementArrayATI: procedure(mode: GLenum; start: GLuint; _end: GLuint; count: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ATI_element_array: Boolean; + +//***** GL_ATI_envmap_bumpmap *****// +const + GL_BUMP_ROT_MATRIX_ATI = $8775; + GL_BUMP_ROT_MATRIX_SIZE_ATI = $8776; + GL_BUMP_NUM_TEX_UNITS_ATI = $8777; + GL_BUMP_TEX_UNITS_ATI = $8778; + GL_DUDV_ATI = $8779; + GL_DU8DV8_ATI = $877A; + GL_BUMP_ENVMAP_ATI = $877B; + GL_BUMP_TARGET_ATI = $877C; +var + glTexBumpParameterivATI: procedure(pname: GLenum; param: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexBumpParameterfvATI: procedure(pname: GLenum; param: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetTexBumpParameterivATI: procedure(pname: GLenum; param: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetTexBumpParameterfvATI: procedure(pname: GLenum; param: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ATI_envmap_bumpmap: Boolean; + +//***** GL_ATI_fragment_shader *****// +const + GL_FRAGMENT_SHADER_ATI = $8920; + GL_REG_0_ATI = $8921; + GL_REG_1_ATI = $8922; + GL_REG_2_ATI = $8923; + GL_REG_3_ATI = $8924; + GL_REG_4_ATI = $8925; + GL_REG_5_ATI = $8926; + GL_CON_0_ATI = $8941; + GL_CON_1_ATI = $8942; + GL_CON_2_ATI = $8943; + GL_CON_3_ATI = $8944; + GL_CON_4_ATI = $8945; + GL_CON_5_ATI = $8946; + GL_CON_6_ATI = $8947; + GL_CON_7_ATI = $8948; + GL_MOV_ATI = $8961; + GL_ADD_ATI = $8963; + GL_MUL_ATI = $8964; + GL_SUB_ATI = $8965; + GL_DOT3_ATI = $8966; + GL_DOT4_ATI = $8967; + GL_MAD_ATI = $8968; + GL_LERP_ATI = $8969; + GL_CND_ATI = $896A; + GL_CND0_ATI = $896B; + GL_DOT2_ADD_ATI = $896C; + GL_SECONDARY_INTERPOLATOR_ATI = $896D; + GL_SWIZZLE_STR_ATI = $8976; + GL_SWIZZLE_STQ_ATI = $8977; + GL_SWIZZLE_STR_DR_ATI = $8978; + GL_SWIZZLE_STQ_DQ_ATI = $8979; + GL_RED_BIT_ATI = $0001; + GL_GREEN_BIT_ATI = $0002; + GL_BLUE_BIT_ATI = $0004; + GL_2X_BIT_ATI = $0001; + GL_4X_BIT_ATI = $0002; + GL_8X_BIT_ATI = $0004; + GL_HALF_BIT_ATI = $0008; + GL_QUARTER_BIT_ATI = $0010; + GL_EIGHTH_BIT_ATI = $0020; + GL_SATURATE_BIT_ATI = $0040; + // GL_2X_BIT_ATI { already defined } + GL_COMP_BIT_ATI = $0002; + GL_NEGATE_BIT_ATI = $0004; + GL_BIAS_BIT_ATI = $0008; +var + glGenFragmentShadersATI: function(range: GLuint): GLuint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBindFragmentShaderATI: procedure(id: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteFragmentShaderATI: procedure(id: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBeginFragmentShaderATI: procedure(); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEndFragmentShaderATI: procedure(); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPassTexCoordATI: procedure(dst: GLuint; coord: GLuint; swizzle: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSampleMapATI: procedure(dst: GLuint; interp: GLuint; swizzle: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColorFragmentOp1ATI: procedure(op: GLenum; dst: GLuint; dstMask: GLuint; dstMod: GLuint; arg1: GLuint; arg1Rep: GLuint; arg1Mod: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColorFragmentOp2ATI: procedure(op: GLenum; dst: GLuint; dstMask: GLuint; dstMod: GLuint; arg1: GLuint; arg1Rep: GLuint; arg1Mod: GLuint; arg2: GLuint; arg2Rep: GLuint; arg2Mod: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColorFragmentOp3ATI: procedure(op: GLenum; dst: GLuint; dstMask: GLuint; dstMod: GLuint; arg1: GLuint; arg1Rep: GLuint; arg1Mod: GLuint; arg2: GLuint; arg2Rep: GLuint; arg2Mod: GLuint; arg3: GLuint; arg3Rep: GLuint; arg3Mod: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glAlphaFragmentOp1ATI: procedure(op: GLenum; dst: GLuint; dstMod: GLuint; arg1: GLuint; arg1Rep: GLuint; arg1Mod: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glAlphaFragmentOp2ATI: procedure(op: GLenum; dst: GLuint; dstMod: GLuint; arg1: GLuint; arg1Rep: GLuint; arg1Mod: GLuint; arg2: GLuint; arg2Rep: GLuint; arg2Mod: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glAlphaFragmentOp3ATI: procedure(op: GLenum; dst: GLuint; dstMod: GLuint; arg1: GLuint; arg1Rep: GLuint; arg1Mod: GLuint; arg2: GLuint; arg2Rep: GLuint; arg2Mod: GLuint; arg3: GLuint; arg3Rep: GLuint; arg3Mod: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSetFragmentShaderConstantATI: procedure(dst: GLuint; const value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ATI_fragment_shader: Boolean; + +//***** GL_ATI_pn_triangles *****// +const + GL_PN_TRIANGLES_ATI = $87F0; + GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI = $87F1; + GL_PN_TRIANGLES_POINT_MODE_ATI = $87F2; + GL_PN_TRIANGLES_NORMAL_MODE_ATI = $87F3; + GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI = $87F4; + GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI = $87F5; + GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI = $87F6; + GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI = $87F7; + GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI = $87F8; +var + glPNTrianglesiATI: procedure(pname: GLenum; param: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPNTrianglesfATI: procedure(pname: GLenum; param: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ATI_pn_triangles: Boolean; + +//***** GL_ATI_texture_mirror_once *****// +const + GL_MIRROR_CLAMP_ATI = $8742; + GL_MIRROR_CLAMP_TO_EDGE_ATI = $8743; + +function Load_GL_ATI_texture_mirror_once: Boolean; + +//***** GL_ATI_vertex_array_object *****// +const + GL_STATIC_ATI = $8760; + GL_DYNAMIC_ATI = $8761; + GL_PRESERVE_ATI = $8762; + GL_DISCARD_ATI = $8763; + GL_OBJECT_BUFFER_SIZE_ATI = $8764; + GL_OBJECT_BUFFER_USAGE_ATI = $8765; + GL_ARRAY_OBJECT_BUFFER_ATI = $8766; + GL_ARRAY_OBJECT_OFFSET_ATI = $8767; +var + glNewObjectBufferATI: function(size: GLsizei; const pointer: PGLvoid; usage: GLenum): GLuint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsObjectBufferATI: function(buffer: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUpdateObjectBufferATI: procedure(buffer: GLuint; offset: GLuint; size: GLsizei; const pointer: PGLvoid; preserve: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetObjectBufferfvATI: procedure(buffer: GLuint; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetObjectBufferivATI: procedure(buffer: GLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteObjectBufferATI: procedure(buffer: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glArrayObjectATI: procedure(_array: GLenum; size: GLint; _type: GLenum; stride: GLsizei; buffer: GLuint; offset: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetArrayObjectfvATI: procedure(_array: GLenum; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetArrayObjectivATI: procedure(_array: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVariantArrayObjectATI: procedure(id: GLuint; _type: GLenum; stride: GLsizei; buffer: GLuint; offset: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVariantArrayObjectfvATI: procedure(id: GLuint; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVariantArrayObjectivATI: procedure(id: GLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ATI_vertex_array_object: Boolean; + +//***** GL_ATI_vertex_streams *****// +const + GL_MAX_VERTEX_STREAMS_ATI = $876B; + GL_VERTEX_STREAM0_ATI = $876C; + GL_VERTEX_STREAM1_ATI = $876D; + GL_VERTEX_STREAM2_ATI = $876E; + GL_VERTEX_STREAM3_ATI = $876F; + GL_VERTEX_STREAM4_ATI = $8770; + GL_VERTEX_STREAM5_ATI = $8771; + GL_VERTEX_STREAM6_ATI = $8772; + GL_VERTEX_STREAM7_ATI = $8773; + GL_VERTEX_SOURCE_ATI = $8774; +var + glVertexStream1s: procedure(stream: GLenum; coords: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream1i: procedure(stream: GLenum; coords: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream1f: procedure(stream: GLenum; coords: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream1d: procedure(stream: GLenum; coords: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream1sv: procedure(stream: GLenum; coords: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream1iv: procedure(stream: GLenum; coords: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream1fv: procedure(stream: GLenum; coords: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream1dv: procedure(stream: GLenum; coords: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream2s: procedure(stream: GLenum; coords: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream2i: procedure(stream: GLenum; coords: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream2f: procedure(stream: GLenum; coords: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream2d: procedure(stream: GLenum; coords: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream2sv: procedure(stream: GLenum; coords: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream2iv: procedure(stream: GLenum; coords: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream2fv: procedure(stream: GLenum; coords: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream2dv: procedure(stream: GLenum; coords: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream3s: procedure(stream: GLenum; coords: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream3i: procedure(stream: GLenum; coords: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream3f: procedure(stream: GLenum; coords: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream3d: procedure(stream: GLenum; coords: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream3sv: procedure(stream: GLenum; coords: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream3iv: procedure(stream: GLenum; coords: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream3fv: procedure(stream: GLenum; coords: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream3dv: procedure(stream: GLenum; coords: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream4s: procedure(stream: GLenum; coords: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream4i: procedure(stream: GLenum; coords: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream4f: procedure(stream: GLenum; coords: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream4d: procedure(stream: GLenum; coords: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream4sv: procedure(stream: GLenum; coords: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream4iv: procedure(stream: GLenum; coords: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream4fv: procedure(stream: GLenum; coords: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexStream4dv: procedure(stream: GLenum; coords: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormalStream3b: procedure(stream: GLenum; coords: GLbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormalStream3s: procedure(stream: GLenum; coords: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormalStream3i: procedure(stream: GLenum; coords: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormalStream3f: procedure(stream: GLenum; coords: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormalStream3d: procedure(stream: GLenum; coords: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormalStream3bv: procedure(stream: GLenum; coords: GLbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormalStream3sv: procedure(stream: GLenum; coords: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormalStream3iv: procedure(stream: GLenum; coords: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormalStream3fv: procedure(stream: GLenum; coords: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormalStream3dv: procedure(stream: GLenum; coords: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glClientActiveVertexStream: procedure(stream: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexBlendEnvi: procedure(pname: GLenum; param: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexBlendEnvf: procedure(pname: GLenum; param: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ATI_vertex_streams: Boolean; + +{$IFDEF msWindows} +//***** WGL_I3D_image_buffer *****// +const + WGL_IMAGE_BUFFER_MIN_ACCESS_I3D = $0001; + WGL_IMAGE_BUFFER_LOCK_I3D = $0002; +var + wglCreateImageBufferI3D: function(hDC: HDC; dwSize: DWORD; uFlags: UINT): PGLvoid; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglDestroyImageBufferI3D: function(hDC: HDC; pAddress: PGLvoid): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglAssociateImageBufferEventsI3D: function(hdc: HDC; pEvent: PHandle; pAddress: PGLvoid; pSize: PDWORD; count: UINT): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglReleaseImageBufferEventsI3D: function(hdc: HDC; pAddress: PGLvoid; count: UINT): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_WGL_I3D_image_buffer: Boolean; + +//***** WGL_I3D_swap_frame_lock *****// +var + wglEnableFrameLockI3D: function(): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglDisableFrameLockI3D: function(): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglIsEnabledFrameLockI3D: function(pFlag: PBOOL): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglQueryFrameLockMasterI3D: function(pFlag: PBOOL): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_WGL_I3D_swap_frame_lock: Boolean; + +//***** WGL_I3D_swap_frame_usage *****// +var + wglGetFrameUsageI3D: function(pUsage: PGLfloat): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglBeginFrameTrackingI3D: function(): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglEndFrameTrackingI3D: function(): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglQueryFrameTrackingI3D: function(pFrameCount: PDWORD; pMissedFrames: PDWORD; pLastMissedUsage: PGLfloat): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_WGL_I3D_swap_frame_usage: Boolean; +{$ENDIF} + +//***** GL_3DFX_texture_compression_FXT1 *****// +const + GL_COMPRESSED_RGB_FXT1_3DFX = $86B0; + GL_COMPRESSED_RGBA_FXT1_3DFX = $86B1; + +function Load_GL_3DFX_texture_compression_FXT1: Boolean; + +//***** GL_IBM_cull_vertex *****// +const + GL_CULL_VERTEX_IBM = $1928A; + +function Load_GL_IBM_cull_vertex: Boolean; + +//***** GL_IBM_multimode_draw_arrays *****// +var + glMultiModeDrawArraysIBM: procedure(mode: PGLenum; first: PGLint; count: PGLsizei; primcount: GLsizei; modestride: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiModeDrawElementsIBM: procedure(mode: PGLenum; count: PGLsizei; _type: GLenum; const indices: PGLvoid; primcount: GLsizei; modestride: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_IBM_multimode_draw_arrays: Boolean; + +//***** GL_IBM_raster_pos_clip *****// +const + GL_RASTER_POSITION_UNCLIPPED_IBM = $19262; + +function Load_GL_IBM_raster_pos_clip: Boolean; + +//***** GL_IBM_texture_mirrored_repeat *****// +const + GL_MIRRORED_REPEAT_IBM = $8370; + +function Load_GL_IBM_texture_mirrored_repeat: Boolean; + +//***** GL_IBM_vertex_array_lists *****// +const + GL_VERTEX_ARRAY_LIST_IBM = $1929E; + GL_NORMAL_ARRAY_LIST_IBM = $1929F; + GL_COLOR_ARRAY_LIST_IBM = $192A0; + GL_INDEX_ARRAY_LIST_IBM = $192A1; + GL_TEXTURE_COORD_ARRAY_LIST_IBM = $192A2; + GL_EDGE_FLAG_ARRAY_LIST_IBM = $192A3; + GL_FOG_COORDINATE_ARRAY_LIST_IBM = $192A4; + GL_SECONDARY_COLOR_ARRAY_LIST_IBM = $192A5; + GL_VERTEX_ARRAY_LIST_STRIDE_IBM = $192A8; + GL_NORMAL_ARRAY_LIST_STRIDE_IBM = $192A9; + GL_COLOR_ARRAY_LIST_STRIDE_IBM = $192AA; + GL_INDEX_ARRAY_LIST_STRIDE_IBM = $192AB; + GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM = $192AC; + GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM = $192AD; + GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM = $192AE; + GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM = $192AF; +var + glColorPointerListIBM: procedure(size: GLint; _type: GLenum; stride: GLint; const pointer: PGLvoid; ptrstride: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColorPointerListIBM: procedure(size: GLint; _type: GLenum; stride: GLint; const pointer: PGLvoid; ptrstride: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEdgeFlagPointerListIBM: procedure(stride: GLint; const pointer: PGLboolean; ptrstride: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFogCoordPointerListIBM: procedure(_type: GLenum; stride: GLint; const pointer: PGLvoid; ptrstride: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormalPointerListIBM: procedure(_type: GLenum; stride: GLint; const pointer: PGLvoid; ptrstride: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoordPointerListIBM: procedure(size: GLint; _type: GLenum; stride: GLint; const pointer: PGLvoid; ptrstride: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexPointerListIBM: procedure(size: GLint; _type: GLenum; stride: GLint; const pointer: PGLvoid; ptrstride: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_IBM_vertex_array_lists: Boolean; + +//***** GL_MESA_resize_buffers *****// +var + glResizeBuffersMESA: procedure(); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_MESA_resize_buffers: Boolean; + +//***** GL_MESA_window_pos *****// +var + glWindowPos2dMESA: procedure(x: GLdouble; y: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2fMESA: procedure(x: GLfloat; y: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2iMESA: procedure(x: GLint; y: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2sMESA: procedure(x: GLshort; y: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2ivMESA: procedure(const p: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2svMESA: procedure(const p: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2fvMESA: procedure(const p: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2dvMESA: procedure(const p: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3iMESA: procedure(x: GLint; y: GLint; z: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3sMESA: procedure(x: GLshort; y: GLshort; z: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3fMESA: procedure(x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3dMESA: procedure(x: GLdouble; y: GLdouble; z: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3ivMESA: procedure(const p: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3svMESA: procedure(const p: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3fvMESA: procedure(const p: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3dvMESA: procedure(const p: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos4iMESA: procedure(x: GLint; y: GLint; z: GLint; w: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos4sMESA: procedure(x: GLshort; y: GLshort; z: GLshort; w: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos4fMESA: procedure(x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos4dMESA: procedure(x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos4ivMESA: procedure(const p: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos4svMESA: procedure(const p: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos4fvMESA: procedure(const p: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos4dvMESA: procedure(const p: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_MESA_window_pos: Boolean; + +//***** GL_OML_interlace *****// +const + GL_INTERLACE_OML = $8980; + GL_INTERLACE_READ_OML = $8981; + +function Load_GL_OML_interlace: Boolean; + +//***** GL_OML_resample *****// +const + GL_PACK_RESAMPLE_OML = $8984; + GL_UNPACK_RESAMPLE_OML = $8985; + GL_RESAMPLE_REPLICATE_OML = $8986; + GL_RESAMPLE_ZERO_FILL_OML = $8987; + GL_RESAMPLE_AVERAGE_OML = $8988; + GL_RESAMPLE_DECIMATE_OML = $8989; + // GL_RESAMPLE_AVERAGE_OML { already defined } + +function Load_GL_OML_resample: Boolean; + +//***** GL_OML_subsample *****// +const + GL_FORMAT_SUBSAMPLE_24_24_OML = $8982; + GL_FORMAT_SUBSAMPLE_244_244_OML = $8983; + +function Load_GL_OML_subsample: Boolean; + +//***** GL_SGIS_generate_mipmap *****// +const + GL_GENERATE_MIPMAP_SGIS = $8191; + GL_GENERATE_MIPMAP_HINT_SGIS = $8192; + +function Load_GL_SGIS_generate_mipmap: Boolean; + +//***** GL_SGIS_multisample *****// +const + GLX_SAMPLE_BUFFERS_SGIS = $186A0; + GLX_SAMPLES_SGIS = $186A1; + GL_MULTISAMPLE_SGIS = $809D; + GL_SAMPLE_ALPHA_TO_MASK_SGIS = $809E; + GL_SAMPLE_ALPHA_TO_ONE_SGIS = $809F; + GL_SAMPLE_MASK_SGIS = $80A0; + GL_MULTISAMPLE_BIT_EXT = $20000000; + GL_1PASS_SGIS = $80A1; + GL_2PASS_0_SGIS = $80A2; + GL_2PASS_1_SGIS = $80A3; + GL_4PASS_0_SGIS = $80A4; + GL_4PASS_1_SGIS = $80A5; + GL_4PASS_2_SGIS = $80A6; + GL_4PASS_3_SGIS = $80A7; + GL_SAMPLE_BUFFERS_SGIS = $80A8; + GL_SAMPLES_SGIS = $80A9; + GL_SAMPLE_MASK_VALUE_SGIS = $80AA; + GL_SAMPLE_MASK_INVERT_SGIS = $80AB; + GL_SAMPLE_PATTERN_SGIS = $80AC; +var + glSampleMaskSGIS: procedure(value: GLclampf; invert: GLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSamplePatternSGIS: procedure(pattern: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_SGIS_multisample: Boolean; + +//***** GL_SGIS_pixel_texture *****// +const + GL_PIXEL_TEXTURE_SGIS = $8353; + GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS = $8354; + GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS = $8355; + GL_PIXEL_GROUP_COLOR_SGIS = $8356; +var + glPixelTexGenParameteriSGIS: procedure(pname: GLenum; param: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPixelTexGenParameterfSGIS: procedure(pname: GLenum; param: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetPixelTexGenParameterivSGIS: procedure(pname: GLenum; params: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetPixelTexGenParameterfvSGIS: procedure(pname: GLenum; params: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_SGIS_pixel_texture: Boolean; + +//***** GL_SGIS_texture_border_clamp *****// + // GL_CLAMP_TO_BORDER_SGIS { already defined } + +function Load_GL_SGIS_texture_border_clamp: Boolean; + +//***** GL_SGIS_texture_color_mask *****// +const + GL_TEXTURE_COLOR_WRITEMASK_SGIS = $81EF; +var + glTextureColorMaskSGIS: procedure(r: GLboolean; g: GLboolean; b: GLboolean; a: GLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_SGIS_texture_color_mask: Boolean; + +//***** GL_SGIS_texture_edge_clamp *****// +const + GL_CLAMP_TO_EDGE_SGIS = $812F; + +function Load_GL_SGIS_texture_edge_clamp: Boolean; + +//***** GL_SGIS_texture_lod *****// +const + GL_TEXTURE_MIN_LOD_SGIS = $813A; + GL_TEXTURE_MAX_LOD_SGIS = $813B; + GL_TEXTURE_BASE_LEVEL_SGIS = $813C; + GL_TEXTURE_MAX_LEVEL_SGIS = $813D; + +function Load_GL_SGIS_texture_lod: Boolean; + +//***** GL_SGIS_depth_texture *****// +const + GL_DEPTH_COMPONENT16_SGIX = $81A5; + GL_DEPTH_COMPONENT24_SGIX = $81A6; + GL_DEPTH_COMPONENT32_SGIX = $81A7; + +function Load_GL_SGIS_depth_texture: Boolean; + +//***** GL_SGIX_fog_offset *****// +const + GL_FOG_OFFSET_SGIX = $8198; + GL_FOG_OFFSET_VALUE_SGIX = $8199; + +function Load_GL_SGIX_fog_offset: Boolean; + +//***** GL_SGIX_interlace *****// +const + GL_INTERLACE_SGIX = $8094; + +function Load_GL_SGIX_interlace: Boolean; + +//***** GL_SGIX_shadow_ambient *****// +const + GL_SHADOW_AMBIENT_SGIX = $80BF; + +function Load_GL_SGIX_shadow_ambient: Boolean; + +//***** GL_SGI_color_matrix *****// +const + GL_COLOR_MATRIX_SGI = $80B1; + GL_COLOR_MATRIX_STACK_DEPTH_SGI = $80B2; + GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI = $80B3; + GL_POST_COLOR_MATRIX_RED_SCALE_SGI = $80B4; + GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI = $80B5; + GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI = $80B6; + GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI = $80B7; + GL_POST_COLOR_MATRIX_RED_BIAS_SGI = $80B8; + GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI = $80B9; + GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI = $80BA; + GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI = $80BB; + +function Load_GL_SGI_color_matrix: Boolean; + +//***** GL_SGI_color_table *****// +const + GL_COLOR_TABLE_SGI = $80D0; + GL_POST_CONVOLUTION_COLOR_TABLE_SGI = $80D1; + GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI = $80D2; + GL_PROXY_COLOR_TABLE_SGI = $80D3; + GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI = $80D4; + GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI = $80D5; + GL_COLOR_TABLE_SCALE_SGI = $80D6; + GL_COLOR_TABLE_BIAS_SGI = $80D7; + GL_COLOR_TABLE_FORMAT_SGI = $80D8; + GL_COLOR_TABLE_WIDTH_SGI = $80D9; + GL_COLOR_TABLE_RED_SIZE_SGI = $80DA; + GL_COLOR_TABLE_GREEN_SIZE_SGI = $80DB; + GL_COLOR_TABLE_BLUE_SIZE_SGI = $80DC; + GL_COLOR_TABLE_ALPHA_SIZE_SGI = $80DD; + GL_COLOR_TABLE_LUMINANCE_SIZE_SGI = $80DE; + GL_COLOR_TABLE_INTENSITY_SIZE_SGI = $80DF; +var + glColorTableSGI: procedure(target: GLenum; internalformat: GLenum; width: GLsizei; format: GLenum; _type: GLenum; const table: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCopyColorTableSGI: procedure(target: GLenum; internalformat: GLenum; x: GLint; y: GLint; width: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColorTableParameterivSGI: procedure(target: GLenum; pname: GLenum; const params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColorTableParameterfvSGI: procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetColorTableSGI: procedure(target: GLenum; format: GLenum; _type: GLenum; table: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetColorTableParameterivSGI: procedure(target: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetColorTableParameterfvSGI: procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_SGI_color_table: Boolean; + +//***** GL_SGI_texture_color_table *****// +const + GL_TEXTURE_COLOR_TABLE_SGI = $80BC; + GL_PROXY_TEXTURE_COLOR_TABLE_SGI = $80BD; + +function Load_GL_SGI_texture_color_table: Boolean; + +//***** GL_SUN_vertex *****// +var + glColor4ubVertex2fSUN: procedure(r: GLubyte; g: GLubyte; b: GLubyte; a: GLubyte; x: GLfloat; y: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4ubVertex2fvSUN: procedure(const c: PGLubyte; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4ubVertex3fSUN: procedure(r: GLubyte; g: GLubyte; b: GLubyte; a: GLubyte; x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4ubVertex3fvSUN: procedure(const c: PGLubyte; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor3fVertex3fSUN: procedure(r: GLfloat; g: GLfloat; b: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor3fVertex3fvSUN: procedure(const c: PGLfloat; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormal3fVertex3fSUN: procedure(nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormal3fVertex3fvSUN: procedure(const n: PGLfloat; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4fNormal3fVertex3fSUN: procedure(r: GLfloat; g: GLfloat; b: GLfloat; a: GLfloat; nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4fNormal3fVertex3fvSUN: procedure(const c: PGLfloat; const n: PGLfloat; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord2fVertex3fSUN: procedure(s: GLfloat; t: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord2fVertex3fvSUN: procedure(const tc: PGLfloat; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord4fVertex4fSUN: procedure(s: GLfloat; t: GLfloat; p: GLfloat; q: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord4fVertex4fvSUN: procedure(const tc: PGLfloat; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord2fColor4ubVertex3fSUN: procedure(s: GLfloat; t: GLfloat; r: GLubyte; g: GLubyte; b: GLubyte; a: GLubyte; x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord2fColor4ubVertex3fvSUN: procedure(const tc: PGLfloat; const c: PGLubyte; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord2fColor3fVertex3fSUN: procedure(s: GLfloat; t: GLfloat; r: GLfloat; g: GLfloat; b: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord2fColor3fVertex3fvSUN: procedure(const tc: PGLfloat; const c: PGLfloat; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord2fNormal3fVertex3fSUN: procedure(s: GLfloat; t: GLfloat; nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord2fNormal3fVertex3fvSUN: procedure(const tc: PGLfloat; const n: PGLfloat; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord2fColor4fNormal3fVertex3fSUN: procedure(s: GLfloat; t: GLfloat; r: GLfloat; g: GLfloat; b: GLfloat; a: GLfloat; nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord2fColor4fNormal3fVertex3fvSUN: procedure(const tc: PGLfloat; const c: PGLfloat; const n: PGLfloat; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord4fColor4fNormal3fVertex4fSUN: procedure(s: GLfloat; t: GLfloat; p: GLfloat; q: GLfloat; r: GLfloat; g: GLfloat; b: GLfloat; a: GLfloat; nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord4fColor4fNormal3fVertex4fvSUN: procedure(const tc: PGLfloat; const c: PGLfloat; const n: PGLfloat; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glReplacementCodeuiVertex3fSUN: procedure(rc: GLuint; x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glReplacementCodeuiVertex3fvSUN: procedure(const rc: PGLuint; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glReplacementCodeuiColor4ubVertex3fSUN: procedure(rc: GLuint; r: GLubyte; g: GLubyte; b: GLubyte; a: GLubyte; x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glReplacementCodeuiColor4ubVertex3fvSUN: procedure(const rc: PGLuint; const c: PGLubyte; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glReplacementCodeuiColor3fVertex3fSUN: procedure(rc: GLuint; r: GLfloat; g: GLfloat; b: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glReplacementCodeuiColor3fVertex3fvSUN: procedure(const rc: PGLuint; const c: PGLfloat; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glReplacementCodeuiNormal3fVertex3fSUN: procedure(rc: GLuint; nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glReplacementCodeuiNormal3fVertex3fvSUN: procedure(const rc: PGLuint; const n: PGLfloat; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glReplacementCodeuiColor4fNormal3fVertex3fSUN: procedure(rc: GLuint; r: GLfloat; g: GLfloat; b: GLfloat; a: GLfloat; nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glReplacementCodeuiColor4fNormal3fVertex3fvSUN: procedure(const rc: PGLuint; const c: PGLfloat; const n: PGLfloat; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glReplacementCodeuiTexCoord2fVertex3fSUN: procedure(rc: GLuint; s: GLfloat; t: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glReplacementCodeuiTexCoord2fVertex3fvSUN: procedure(const rc: PGLuint; const tc: PGLfloat; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN: procedure(rc: GLuint; s: GLfloat; t: GLfloat; nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN: procedure(const rc: PGLuint; const tc: PGLfloat; const n: PGLfloat; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN: procedure(rc: GLuint; s: GLfloat; t: GLfloat; r: GLfloat; g: GLfloat; b: GLfloat; a: GLfloat; nx: GLfloat; ny: GLfloat; nz: GLfloat; x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN: procedure(const rc: PGLuint; const tc: PGLfloat; const c: PGLfloat; const n: PGLfloat; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_SUN_vertex: Boolean; + +//***** GL_ARB_fragment_program *****// +const + GL_FRAGMENT_PROGRAM_ARB = $8804; + // GL_PROGRAM_FORMAT_ASCII_ARB { already defined } + // GL_PROGRAM_LENGTH_ARB { already defined } + // GL_PROGRAM_FORMAT_ARB { already defined } + // GL_PROGRAM_BINDING_ARB { already defined } + // GL_PROGRAM_INSTRUCTIONS_ARB { already defined } + // GL_MAX_PROGRAM_INSTRUCTIONS_ARB { already defined } + // GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB { already defined } + // GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB { already defined } + // GL_PROGRAM_TEMPORARIES_ARB { already defined } + // GL_MAX_PROGRAM_TEMPORARIES_ARB { already defined } + // GL_PROGRAM_NATIVE_TEMPORARIES_ARB { already defined } + // GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB { already defined } + // GL_PROGRAM_PARAMETERS_ARB { already defined } + // GL_MAX_PROGRAM_PARAMETERS_ARB { already defined } + // GL_PROGRAM_NATIVE_PARAMETERS_ARB { already defined } + // GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB { already defined } + // GL_PROGRAM_ATTRIBS_ARB { already defined } + // GL_MAX_PROGRAM_ATTRIBS_ARB { already defined } + // GL_PROGRAM_NATIVE_ATTRIBS_ARB { already defined } + // GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB { already defined } + // GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB { already defined } + // GL_MAX_PROGRAM_ENV_PARAMETERS_ARB { already defined } + // GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB { already defined } + GL_PROGRAM_ALU_INSTRUCTIONS_ARB = $8805; + GL_PROGRAM_TEX_INSTRUCTIONS_ARB = $8806; + GL_PROGRAM_TEX_INDIRECTIONS_ARB = $8807; + GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB = $8808; + GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB = $8809; + GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB = $880A; + GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB = $880B; + GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB = $880C; + GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB = $880D; + GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB = $880E; + GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB = $880F; + GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB = $8810; + // GL_PROGRAM_STRING_ARB { already defined } + // GL_PROGRAM_ERROR_POSITION_ARB { already defined } + // GL_CURRENT_MATRIX_ARB { already defined } + // GL_TRANSPOSE_CURRENT_MATRIX_ARB { already defined } + // GL_CURRENT_MATRIX_STACK_DEPTH_ARB { already defined } + // GL_MAX_PROGRAM_MATRICES_ARB { already defined } + // GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB { already defined } + GL_MAX_TEXTURE_COORDS_ARB = $8871; + GL_MAX_TEXTURE_IMAGE_UNITS_ARB = $8872; + // GL_PROGRAM_ERROR_STRING_ARB { already defined } + // GL_MATRIX0_ARB { already defined } + // GL_MATRIX1_ARB { already defined } + // GL_MATRIX2_ARB { already defined } + // GL_MATRIX3_ARB { already defined } + // GL_MATRIX4_ARB { already defined } + // GL_MATRIX5_ARB { already defined } + // GL_MATRIX6_ARB { already defined } + // GL_MATRIX7_ARB { already defined } + // GL_MATRIX8_ARB { already defined } + // GL_MATRIX9_ARB { already defined } + // GL_MATRIX10_ARB { already defined } + // GL_MATRIX11_ARB { already defined } + // GL_MATRIX12_ARB { already defined } + // GL_MATRIX13_ARB { already defined } + // GL_MATRIX14_ARB { already defined } + // GL_MATRIX15_ARB { already defined } + // GL_MATRIX16_ARB { already defined } + // GL_MATRIX17_ARB { already defined } + // GL_MATRIX18_ARB { already defined } + // GL_MATRIX19_ARB { already defined } + // GL_MATRIX20_ARB { already defined } + // GL_MATRIX21_ARB { already defined } + // GL_MATRIX22_ARB { already defined } + // GL_MATRIX23_ARB { already defined } + // GL_MATRIX24_ARB { already defined } + // GL_MATRIX25_ARB { already defined } + // GL_MATRIX26_ARB { already defined } + // GL_MATRIX27_ARB { already defined } + // GL_MATRIX28_ARB { already defined } + // GL_MATRIX29_ARB { already defined } + // GL_MATRIX30_ARB { already defined } + // GL_MATRIX31_ARB { already defined } + // glProgramStringARB { already defined } + // glBindProgramARB { already defined } + // glDeleteProgramsARB { already defined } + // glGenProgramsARB { already defined } + // glProgramEnvParameter4dARB { already defined } + // glProgramEnvParameter4dvARB { already defined } + // glProgramEnvParameter4fARB { already defined } + // glProgramEnvParameter4fvARB { already defined } + // glProgramLocalParameter4dARB { already defined } + // glProgramLocalParameter4dvARB { already defined } + // glProgramLocalParameter4fARB { already defined } + // glProgramLocalParameter4fvARB { already defined } + // glGetProgramEnvParameterdvARB { already defined } + // glGetProgramEnvParameterfvARB { already defined } + // glGetProgramLocalParameterdvARB { already defined } + // glGetProgramLocalParameterfvARB { already defined } + // glGetProgramivARB { already defined } + // glGetProgramStringARB { already defined } + // glIsProgramARB { already defined } + +function Load_GL_ARB_fragment_program: Boolean; + +{***** GL_ATI_text_fragment_shader *****} +const + GL_TEXT_FRAGMENT_SHADER_ATI = $8200; + +function Load_GL_ATI_text_fragment_shader: Boolean; + +{***** GL_ARB_vertex_buffer_object *****} +const + GL_BUFFER_SIZE_ARB = $8764; + GL_BUFFER_USAGE_ARB = $8765; + GL_ARRAY_BUFFER_ARB = $8892; + GL_ELEMENT_ARRAY_BUFFER_ARB = $8893; + GL_ARRAY_BUFFER_BINDING_ARB = $8894; + GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB = $8895; + GL_VERTEX_ARRAY_BUFFER_BINDING_ARB = $8896; + GL_NORMAL_ARRAY_BUFFER_BINDING_ARB = $8897; + GL_COLOR_ARRAY_BUFFER_BINDING_ARB = $8898; + GL_INDEX_ARRAY_BUFFER_BINDING_ARB = $8899; + GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB = $889A; + GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB = $889B; + GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB = $889C; + GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB = $889D; + GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB = $889E; + GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB = $889F; + GL_READ_ONLY_ARB = $88B8; + GL_WRITE_ONLY_ARB = $88B9; + GL_READ_WRITE_ARB = $88BA; + GL_BUFFER_ACCESS_ARB = $88BB; + GL_BUFFER_MAPPED_ARB = $88BC; + GL_BUFFER_MAP_POINTER_ARB = $88BD; + GL_STREAM_DRAW_ARB = $88E0; + GL_STREAM_READ_ARB = $88E1; + GL_STREAM_COPY_ARB = $88E2; + GL_STATIC_DRAW_ARB = $88E4; + GL_STATIC_READ_ARB = $88E5; + GL_STATIC_COPY_ARB = $88E6; + GL_DYNAMIC_DRAW_ARB = $88E8; + GL_DYNAMIC_READ_ARB = $88E9; + GL_DYNAMIC_COPY_ARB = $88EA; + +var + glBindBufferARB : procedure(target : GLenum; buffer: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteBuffersARB : procedure(n : GLsizei; buffers : PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGenBuffersARB : procedure(n : GLsizei; buffers : PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsBufferARB : function (buffer : GLuint) :GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBufferDataARB : procedure(target : GLenum; size:GLsizei; data:PGLvoid;usage: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBufferSubDataARB : procedure(target : GLenum; offset :GLint; size : GLsizei; data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetBufferSubDataARB : procedure(target : GLenum; offset :GLint; size : GLsizei; data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMapBufferARB : function (target :GLenum; access: GLenum) : PGLvoid; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUnmapBufferARB : function (target :GLenum) :GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetBufferParameterivARB:procedure(target:GLenum; pname:GLenum; params:PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetBufferPointervARB : procedure(target: GLenum; pname:GLenum; params: PPGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; +function Load_GL_ARB_vertex_buffer_object : boolean; + +//***** GL_APPLE_client_storage *****// +const + GL_UNPACK_CLIENT_STORAGE_APPLE = $85B2; + +function Load_GL_APPLE_client_storage: Boolean; + +//***** GL_APPLE_element_array *****// +const + GL_ELEMENT_ARRAY_APPLE = $8768; + GL_ELEMENT_ARRAY_TYPE_APPLE = $8769; + GL_ELEMENT_ARRAY_POINTER_APPLE = $876A; +var + glElementPointerAPPLE: procedure(_type: GLenum; const pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDrawElementArrayAPPLE: procedure(mode: GLenum; first: GLint; count: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDrawRangeElementArrayAPPLE: procedure(mode: GLenum; start: GLuint; _end: GLuint; first: GLint; count: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiDrawElementArrayAPPLE: procedure(mode: GLenum; const first: PGLint; const count: PGLsizei; primcount: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiDrawRangeElementArrayAPPLE: procedure(mode: GLenum; start: GLuint; _end: GLuint; const first: PGLint; const count: PGLsizei; primcount: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_APPLE_element_array: Boolean; + +//***** GL_APPLE_fence *****// +const + GL_DRAW_PIXELS_APPLE = $8A0A; + GL_FENCE_APPLE = $8A0B; +var + glGenFencesAPPLE: procedure(n: GLsizei; fences: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteFencesAPPLE: procedure(n: GLsizei; const fences: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSetFenceAPPLE: procedure(fence: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsFenceAPPLE: function(fence: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTestFenceAPPLE: function(fence: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFinishFenceAPPLE: procedure(fence: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTestObjectAPPLE: function(_object: GLenum; name: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFinishObjectAPPLE: procedure(_object: GLenum; name: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_APPLE_fence: Boolean; + +//***** GL_APPLE_vertex_array_object *****// +const + GL_VERTEX_ARRAY_BINDING_APPLE = $85B5; +var + glBindVertexArrayAPPLE: procedure(_array: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteVertexArraysAPPLE: procedure(n: GLsizei; const arrays: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGenVertexArraysAPPLE: procedure(n: GLsizei; const arrays: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsVertexArrayAPPLE: function(_array: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_APPLE_vertex_array_object: Boolean; + +//***** GL_APPLE_vertex_array_range *****// +const + GL_VERTEX_ARRAY_RANGE_APPLE = $851D; + GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE = $851E; + GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_APPLE = $8520; + GL_VERTEX_ARRAY_RANGE_POINTER_APPLE = $8521; + GL_VERTEX_ARRAY_STORAGE_HINT_APPLE = $851F; + GL_STORAGE_CACHED_APPLE = $85BE; + GL_STORAGE_SHARED_APPLE = $85BF; +var + glVertexArrayRangeAPPLE: procedure(length: GLsizei; pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFlushVertexArrayRangeAPPLE: procedure(length: GLsizei; pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexArrayParameteriAPPLE: procedure(pname: GLenum; param: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_APPLE_vertex_array_range: Boolean; + +{$IFDEF msWindows} +//***** WGL_ARB_pixel_format *****// +const + WGL_NUMBER_PIXEL_FORMATS_ARB = $2000; + WGL_DRAW_TO_WINDOW_ARB = $2001; + WGL_DRAW_TO_BITMAP_ARB = $2002; + WGL_ACCELERATION_ARB = $2003; + WGL_NEED_PALETTE_ARB = $2004; + WGL_NEED_SYSTEM_PALETTE_ARB = $2005; + WGL_SWAP_LAYER_BUFFERS_ARB = $2006; + WGL_SWAP_METHOD_ARB = $2007; + WGL_NUMBER_OVERLAYS_ARB = $2008; + WGL_NUMBER_UNDERLAYS_ARB = $2009; + WGL_TRANSPARENT_ARB = $200A; + WGL_TRANSPARENT_RED_VALUE_ARB = $2037; + WGL_TRANSPARENT_GREEN_VALUE_ARB = $2038; + WGL_TRANSPARENT_BLUE_VALUE_ARB = $2039; + WGL_TRANSPARENT_ALPHA_VALUE_ARB = $203A; + WGL_TRANSPARENT_INDEX_VALUE_ARB = $203B; + WGL_SHARE_DEPTH_ARB = $200C; + WGL_SHARE_STENCIL_ARB = $200D; + WGL_SHARE_ACCUM_ARB = $200E; + WGL_SUPPORT_GDI_ARB = $200F; + WGL_SUPPORT_OPENGL_ARB = $2010; + WGL_DOUBLE_BUFFER_ARB = $2011; + WGL_STEREO_ARB = $2012; + WGL_PIXEL_TYPE_ARB = $2013; + WGL_COLOR_BITS_ARB = $2014; + WGL_RED_BITS_ARB = $2015; + WGL_RED_SHIFT_ARB = $2016; + WGL_GREEN_BITS_ARB = $2017; + WGL_GREEN_SHIFT_ARB = $2018; + WGL_BLUE_BITS_ARB = $2019; + WGL_BLUE_SHIFT_ARB = $201A; + WGL_ALPHA_BITS_ARB = $201B; + WGL_ALPHA_SHIFT_ARB = $201C; + WGL_ACCUM_BITS_ARB = $201D; + WGL_ACCUM_RED_BITS_ARB = $201E; + WGL_ACCUM_GREEN_BITS_ARB = $201F; + WGL_ACCUM_BLUE_BITS_ARB = $2020; + WGL_ACCUM_ALPHA_BITS_ARB = $2021; + WGL_DEPTH_BITS_ARB = $2022; + WGL_STENCIL_BITS_ARB = $2023; + WGL_AUX_BUFFERS_ARB = $2024; + WGL_NO_ACCELERATION_ARB = $2025; + WGL_GENERIC_ACCELERATION_ARB = $2026; + WGL_FULL_ACCELERATION_ARB = $2027; + WGL_SWAP_EXCHANGE_ARB = $2028; + WGL_SWAP_COPY_ARB = $2029; + WGL_SWAP_UNDEFINED_ARB = $202A; + WGL_TYPE_RGBA_ARB = $202B; + WGL_TYPE_COLORINDEX_ARB = $202C; +var + wglGetPixelFormatAttribivARB: function(hdc: HDC; iPixelFormat: GLint; iLayerPlane: GLint; nAttributes: GLuint; const piAttributes: PGLint; piValues: PGLint): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglGetPixelFormatAttribfvARB: function(hdc: HDC; iPixelFormat: GLint; iLayerPlane: GLint; nAttributes: GLuint; const piAttributes: PGLint; pfValues: PGLfloat): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglChoosePixelFormatARB: function(hdc: HDC; const piAttribIList: PGLint; const pfAttribFList: PGLfloat; nMaxFormats: GLuint; piFormats: PGLint; nNumFormats: PGLuint): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_WGL_ARB_pixel_format: Boolean; + +//***** WGL_ARB_make_current_read *****// +const + WGL_ERROR_INVALID_PIXEL_TYPE_ARB = $2043; + WGL_ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB = $2054; +var + wglMakeContextCurrentARB: function(hDrawDC: HDC; hReadDC: HDC; hglrc: HGLRC): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglGetCurrentReadDCARB: function(): HDC; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_WGL_ARB_make_current_read: Boolean; + +//***** WGL_ARB_pbuffer *****// +const + WGL_DRAW_TO_PBUFFER_ARB = $202D; + // WGL_DRAW_TO_PBUFFER_ARB { already defined } + WGL_MAX_PBUFFER_PIXELS_ARB = $202E; + WGL_MAX_PBUFFER_WIDTH_ARB = $202F; + WGL_MAX_PBUFFER_HEIGHT_ARB = $2030; + WGL_PBUFFER_LARGEST_ARB = $2033; + WGL_PBUFFER_WIDTH_ARB = $2034; + WGL_PBUFFER_HEIGHT_ARB = $2035; + WGL_PBUFFER_LOST_ARB = $2036; +var + wglCreatePbufferARB: function(hDC: HDC; iPixelFormat: GLint; iWidth: GLint; iHeight: GLint; const piAttribList: PGLint): THandle; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglGetPbufferDCARB: function(hPbuffer: THandle): HDC; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglReleasePbufferDCARB: function(hPbuffer: THandle; hDC: HDC): GLint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglDestroyPbufferARB: function(hPbuffer: THandle): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglQueryPbufferARB: function(hPbuffer: THandle; iAttribute: GLint; piValue: PGLint): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_WGL_ARB_pbuffer: Boolean; + +//***** WGL_EXT_swap_control *****// +var + wglSwapIntervalEXT: function(interval: GLint): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglGetSwapIntervalEXT: function(): GLint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_WGL_EXT_swap_control: Boolean; + +//***** WGL_ARB_render_texture *****// +const + WGL_BIND_TO_TEXTURE_RGB_ARB = $2070; + WGL_BIND_TO_TEXTURE_RGBA_ARB = $2071; + WGL_TEXTURE_FORMAT_ARB = $2072; + WGL_TEXTURE_TARGET_ARB = $2073; + WGL_MIPMAP_TEXTURE_ARB = $2074; + WGL_TEXTURE_RGB_ARB = $2075; + WGL_TEXTURE_RGBA_ARB = $2076; + WGL_NO_TEXTURE_ARB = $2077; + WGL_TEXTURE_CUBE_MAP_ARB = $2078; + WGL_TEXTURE_1D_ARB = $2079; + WGL_TEXTURE_2D_ARB = $207A; + // WGL_NO_TEXTURE_ARB { already defined } + WGL_MIPMAP_LEVEL_ARB = $207B; + WGL_CUBE_MAP_FACE_ARB = $207C; + WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB = $207D; + WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB = $207E; + WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB = $207F; + WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB = $2080; + WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB = $2081; + WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB = $2082; + WGL_FRONT_LEFT_ARB = $2083; + WGL_FRONT_RIGHT_ARB = $2084; + WGL_BACK_LEFT_ARB = $2085; + WGL_BACK_RIGHT_ARB = $2086; + WGL_AUX0_ARB = $2087; + WGL_AUX1_ARB = $2088; + WGL_AUX2_ARB = $2089; + WGL_AUX3_ARB = $208A; + WGL_AUX4_ARB = $208B; + WGL_AUX5_ARB = $208C; + WGL_AUX6_ARB = $208D; + WGL_AUX7_ARB = $208E; + WGL_AUX8_ARB = $208F; + WGL_AUX9_ARB = $2090; +var + wglBindTexImageARB: function(hPbuffer: THandle; iBuffer: GLint): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglReleaseTexImageARB: function(hPbuffer: THandle; iBuffer: GLint): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglSetPbufferAttribARB: function(hPbuffer: THandle; const piAttribList: PGLint): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_WGL_ARB_render_texture: Boolean; + +//***** WGL_EXT_extensions_string *****// +var + wglGetExtensionsStringEXT: function(): Pchar; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_WGL_EXT_extensions_string: Boolean; + +//***** WGL_EXT_make_current_read *****// +var + wglMakeContextCurrentEXT: function(hDrawDC: HDC; hReadDC: HDC; hglrc: HGLRC): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglGetCurrentReadDCEXT: function(): HDC; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_WGL_EXT_make_current_read: Boolean; + +//***** WGL_EXT_pbuffer *****// +const + WGL_DRAW_TO_PBUFFER_EXT = $202D; + WGL_MAX_PBUFFER_PIXELS_EXT = $202E; + WGL_MAX_PBUFFER_WIDTH_EXT = $202F; + WGL_MAX_PBUFFER_HEIGHT_EXT = $2030; + WGL_OPTIMAL_PBUFFER_WIDTH_EXT = $2031; + WGL_OPTIMAL_PBUFFER_HEIGHT_EXT = $2032; + WGL_PBUFFER_LARGEST_EXT = $2033; + WGL_PBUFFER_WIDTH_EXT = $2034; + WGL_PBUFFER_HEIGHT_EXT = $2035; +var + wglCreatePbufferEXT: function(hDC: HDC; iPixelFormat: GLint; iWidth: GLint; iHeight: GLint; const piAttribList: PGLint): THandle; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglGetPbufferDCEXT: function(hPbuffer: THandle): HDC; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglReleasePbufferDCEXT: function(hPbuffer: THandle; hDC: HDC): GLint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglDestroyPbufferEXT: function(hPbuffer: THandle): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglQueryPbufferEXT: function(hPbuffer: THandle; iAttribute: GLint; piValue: PGLint): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_WGL_EXT_pbuffer: Boolean; + +//***** WGL_EXT_pixel_format *****// +const + WGL_NUMBER_PIXEL_FORMATS_EXT = $2000; + WGL_DRAW_TO_WINDOW_EXT = $2001; + WGL_DRAW_TO_BITMAP_EXT = $2002; + WGL_ACCELERATION_EXT = $2003; + WGL_NEED_PALETTE_EXT = $2004; + WGL_NEED_SYSTEM_PALETTE_EXT = $2005; + WGL_SWAP_LAYER_BUFFERS_EXT = $2006; + WGL_SWAP_METHOD_EXT = $2007; + WGL_NUMBER_OVERLAYS_EXT = $2008; + WGL_NUMBER_UNDERLAYS_EXT = $2009; + WGL_TRANSPARENT_EXT = $200A; + WGL_TRANSPARENT_VALUE_EXT = $200B; + WGL_SHARE_DEPTH_EXT = $200C; + WGL_SHARE_STENCIL_EXT = $200D; + WGL_SHARE_ACCUM_EXT = $200E; + WGL_SUPPORT_GDI_EXT = $200F; + WGL_SUPPORT_OPENGL_EXT = $2010; + WGL_DOUBLE_BUFFER_EXT = $2011; + WGL_STEREO_EXT = $2012; + WGL_PIXEL_TYPE_EXT = $2013; + WGL_COLOR_BITS_EXT = $2014; + WGL_RED_BITS_EXT = $2015; + WGL_RED_SHIFT_EXT = $2016; + WGL_GREEN_BITS_EXT = $2017; + WGL_GREEN_SHIFT_EXT = $2018; + WGL_BLUE_BITS_EXT = $2019; + WGL_BLUE_SHIFT_EXT = $201A; + WGL_ALPHA_BITS_EXT = $201B; + WGL_ALPHA_SHIFT_EXT = $201C; + WGL_ACCUM_BITS_EXT = $201D; + WGL_ACCUM_RED_BITS_EXT = $201E; + WGL_ACCUM_GREEN_BITS_EXT = $201F; + WGL_ACCUM_BLUE_BITS_EXT = $2020; + WGL_ACCUM_ALPHA_BITS_EXT = $2021; + WGL_DEPTH_BITS_EXT = $2022; + WGL_STENCIL_BITS_EXT = $2023; + WGL_AUX_BUFFERS_EXT = $2024; + WGL_NO_ACCELERATION_EXT = $2025; + WGL_GENERIC_ACCELERATION_EXT = $2026; + WGL_FULL_ACCELERATION_EXT = $2027; + WGL_SWAP_EXCHANGE_EXT = $2028; + WGL_SWAP_COPY_EXT = $2029; + WGL_SWAP_UNDEFINED_EXT = $202A; + WGL_TYPE_RGBA_EXT = $202B; + WGL_TYPE_COLORINDEX_EXT = $202C; +var + wglGetPixelFormatAttribivEXT: function(hdc: HDC; iPixelFormat: GLint; iLayerPlane: GLint; nAttributes: GLuint; piAttributes: PGLint; piValues: PGLint): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglGetPixelFormatAttribfvEXT: function(hdc: HDC; iPixelFormat: GLint; iLayerPlane: GLint; nAttributes: GLuint; piAttributes: PGLint; pfValues: PGLfloat): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglChoosePixelFormatEXT: function(hdc: HDC; const piAttribIList: PGLint; const pfAttribFList: PGLfloat; nMaxFormats: GLuint; piFormats: PGLint; nNumFormats: PGLuint): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_WGL_EXT_pixel_format: Boolean; + +//***** WGL_I3D_digital_video_control *****// +const + WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D = $2050; + WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D = $2051; + WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D = $2052; + WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D = $2053; +var + wglGetDigitalVideoParametersI3D: function(hDC: HDC; iAttribute: GLint; piValue: PGLint): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglSetDigitalVideoParametersI3D: function(hDC: HDC; iAttribute: GLint; const piValue: PGLint): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_WGL_I3D_digital_video_control: Boolean; + +//***** WGL_I3D_gamma *****// +const + WGL_GAMMA_TABLE_SIZE_I3D = $204E; + WGL_GAMMA_EXCLUDE_DESKTOP_I3D = $204F; + // WGL_GAMMA_EXCLUDE_DESKTOP_I3D { already defined } +var + wglGetGammaTableParametersI3D: function(hDC: HDC; iAttribute: GLint; piValue: PGLint): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglSetGammaTableParametersI3D: function(hDC: HDC; iAttribute: GLint; const piValue: PGLint): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglGetGammaTableI3D: function(hDC: HDC; iEntries: GLint; puRed: PGLUSHORT; puGreen: PGLUSHORT; puBlue: PGLUSHORT): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglSetGammaTableI3D: function(hDC: HDC; iEntries: GLint; const puRed: PGLUSHORT; const puGreen: PGLUSHORT; const puBlue: PGLUSHORT): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_WGL_I3D_gamma: Boolean; + +//***** WGL_I3D_genlock *****// +const + WGL_GENLOCK_SOURCE_MULTIVIEW_I3D = $2044; + WGL_GENLOCK_SOURCE_EXTERNAL_SYNC_I3D = $2045; + WGL_GENLOCK_SOURCE_EXTERNAL_FIELD_I3D = $2046; + WGL_GENLOCK_SOURCE_EXTERNAL_TTL_I3D = $2047; + WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D = $2048; + WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D = $2049; + WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D = $204A; + WGL_GENLOCK_SOURCE_EDGE_RISING_I3D = $204B; + WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D = $204C; +var + wglEnableGenlockI3D: function(hDC: HDC): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglDisableGenlockI3D: function(hDC: HDC): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglIsEnabledGenlockI3D: function(hDC: HDC; pFlag: PBOOL): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglGenlockSourceI3D: function(hDC: HDC; uSource: GLUINT): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglGetGenlockSourceI3D: function(hDC: HDC; uSource: PGLUINT): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglGenlockSourceEdgeI3D: function(hDC: HDC; uEdge: GLUINT): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglGetGenlockSourceEdgeI3D: function(hDC: HDC; uEdge: PGLUINT): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglGenlockSampleRateI3D: function(hDC: HDC; uRate: GLUINT): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglGetGenlockSampleRateI3D: function(hDC: HDC; uRate: PGLUINT): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglGenlockSourceDelayI3D: function(hDC: HDC; uDelay: GLUINT): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglGetGenlockSourceDelayI3D: function(hDC: HDC; uDelay: PGLUINT): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + wglQueryGenlockMaxSourceDelayI3D: function(hDC: HDC; uMaxLineDelay: PGLUINT; uMaxPixelDelay: PGLUINT): BOOL; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_WGL_I3D_genlock: Boolean; +{$ENDIF} + +//***** GL_ARB_matrix_palette *****// +const + GL_MATRIX_PALETTE_ARB = $8840; + GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB = $8841; + GL_MAX_PALETTE_MATRICES_ARB = $8842; + GL_CURRENT_PALETTE_MATRIX_ARB = $8843; + GL_MATRIX_INDEX_ARRAY_ARB = $8844; + GL_CURRENT_MATRIX_INDEX_ARB = $8845; + GL_MATRIX_INDEX_ARRAY_SIZE_ARB = $8846; + GL_MATRIX_INDEX_ARRAY_TYPE_ARB = $8847; + GL_MATRIX_INDEX_ARRAY_STRIDE_ARB = $8848; + GL_MATRIX_INDEX_ARRAY_POINTER_ARB = $8849; +var + glCurrentPaletteMatrixARB: procedure(index: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMatrixIndexubvARB: procedure(size: GLint; indices: PGLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMatrixIndexusvARB: procedure(size: GLint; indices: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMatrixIndexuivARB: procedure(size: GLint; indices: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMatrixIndexPointerARB: procedure(size: GLint; _type: GLenum; stride: GLsizei; pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_matrix_palette: Boolean; + +//***** GL_NV_element_array *****// +const + GL_ELEMENT_ARRAY_TYPE_NV = $8769; + GL_ELEMENT_ARRAY_POINTER_NV = $876A; +var + glElementPointerNV: procedure(_type: GLenum; const pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDrawElementArrayNV: procedure(mode: GLenum; first: GLint; count: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDrawRangeElementArrayNV: procedure(mode: GLenum; start: GLuint; _end: GLuint; first: GLint; count: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiDrawElementArrayNV: procedure(mode: GLenum; const first: PGLint; const count: PGLsizei; primcount: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiDrawRangeElementArrayNV: procedure(mode: GLenum; start: GLuint; _end: GLuint; const first: PGLint; const count: PGLsizei; primcount: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_NV_element_array: Boolean; + +//***** GL_NV_float_buffer *****// +const + GL_FLOAT_R_NV = $8880; + GL_FLOAT_RG_NV = $8881; + GL_FLOAT_RGB_NV = $8882; + GL_FLOAT_RGBA_NV = $8883; + GL_FLOAT_R16_NV = $8884; + GL_FLOAT_R32_NV = $8885; + GL_FLOAT_RG16_NV = $8886; + GL_FLOAT_RG32_NV = $8887; + GL_FLOAT_RGB16_NV = $8888; + GL_FLOAT_RGB32_NV = $8889; + GL_FLOAT_RGBA16_NV = $888A; + GL_FLOAT_RGBA32_NV = $888B; + GL_TEXTURE_FLOAT_COMPONENTS_NV = $888C; + GL_FLOAT_CLEAR_COLOR_VALUE_NV = $888D; + GL_FLOAT_RGBA_MODE_NV = $888E; +{$IFDEF msWindows} + WGL_FLOAT_COMPONENTS_NV = $20B0; + WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV = $20B1; + WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV = $20B2; + WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV = $20B3; + WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV = $20B4; + WGL_TEXTURE_FLOAT_R_NV = $20B5; + WGL_TEXTURE_FLOAT_RG_NV = $20B6; + WGL_TEXTURE_FLOAT_RGB_NV = $20B7; + WGL_TEXTURE_FLOAT_RGBA_NV = $20B8; +{$ENDIF} + +function Load_GL_NV_float_buffer: Boolean; + +//***** GL_NV_fragment_program *****// +const + GL_FRAGMENT_PROGRAM_NV = $8870; + GL_MAX_TEXTURE_COORDS_NV = $8871; + GL_MAX_TEXTURE_IMAGE_UNITS_NV = $8872; + GL_FRAGMENT_PROGRAM_BINDING_NV = $8873; + GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV = $8868; + GL_PROGRAM_ERROR_STRING_NV = $8874; +var + glProgramNamedParameter4fNV: procedure(id: GLuint; len: GLsizei; const name: PGLubyte; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramNamedParameter4dNV: procedure(id: GLuint; len: GLsizei; const name: PGLubyte; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetProgramNamedParameterfvNV: procedure(id: GLuint; len: GLsizei; const name: PGLubyte; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetProgramNamedParameterdvNV: procedure(id: GLuint; len: GLsizei; const name: PGLubyte; params: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + // glProgramLocalParameter4dARB { already defined } + // glProgramLocalParameter4dvARB { already defined } + // glProgramLocalParameter4fARB { already defined } + // glProgramLocalParameter4fvARB { already defined } + // glGetProgramLocalParameterdvARB { already defined } + // glGetProgramLocalParameterfvARB { already defined } + +function Load_GL_NV_fragment_program: Boolean; + +//***** GL_NV_primitive_restart *****// +const + GL_PRIMITIVE_RESTART_NV = $8558; + GL_PRIMITIVE_RESTART_INDEX_NV = $8559; +var + glPrimitiveRestartNV: procedure(); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPrimitiveRestartIndexNV: procedure(index: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_NV_primitive_restart: Boolean; + +//***** GL_NV_vertex_program2 *****// + +function Load_GL_NV_vertex_program2: Boolean; + +{$IFDEF msWindows} +//***** WGL_NV_render_texture_rectangle *****// +const + WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV = $20A0; + WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV = $20A1; + WGL_TEXTURE_RECTANGLE_NV = $20A2; + +function Load_WGL_NV_render_texture_rectangle: Boolean; +{$ENDIF} + +//***** GL_NV_pixel_data_range *****// +const + GL_WRITE_PIXEL_DATA_RANGE_NV = $8878; + GL_READ_PIXEL_DATA_RANGE_NV = $8879; + GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV = $887A; + GL_READ_PIXEL_DATA_RANGE_LENGTH_NV = $887B; + GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV = $887C; + GL_READ_PIXEL_DATA_RANGE_POINTER_NV = $887D; +var + glPixelDataRangeNV: procedure(target: GLenum; length: GLsizei; pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFlushPixelDataRangeNV: procedure(target: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + // wglAllocateMemoryNV { already defined } + // wglFreeMemoryNV { already defined } + +function Load_GL_NV_pixel_data_range: Boolean; + +//***** GL_EXT_texture_rectangle *****// +const + GL_TEXTURE_RECTANGLE_EXT = $84F5; + GL_TEXTURE_BINDING_RECTANGLE_EXT = $84F6; + GL_PROXY_TEXTURE_RECTANGLE_EXT = $84F7; + GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT = $84F8; + +function Load_GL_EXT_texture_rectangle: Boolean; + +//***** GL_S3_s3tc *****// +const + GL_RGB_S3TC = $83A0; + GL_RGB4_S3TC = $83A1; + GL_RGBA_S3TC = $83A2; + GL_RGBA4_S3TC = $83A3; + +function Load_GL_S3_s3tc: Boolean; + +//***** GL_ATI_draw_buffers *****// +const + GL_MAX_DRAW_BUFFERS_ATI = $8824; + GL_DRAW_BUFFER0_ATI = $8825; + GL_DRAW_BUFFER1_ATI = $8826; + GL_DRAW_BUFFER2_ATI = $8827; + GL_DRAW_BUFFER3_ATI = $8828; + GL_DRAW_BUFFER4_ATI = $8829; + GL_DRAW_BUFFER5_ATI = $882A; + GL_DRAW_BUFFER6_ATI = $882B; + GL_DRAW_BUFFER7_ATI = $882C; + GL_DRAW_BUFFER8_ATI = $882D; + GL_DRAW_BUFFER9_ATI = $882E; + GL_DRAW_BUFFER10_ATI = $882F; + GL_DRAW_BUFFER11_ATI = $8830; + GL_DRAW_BUFFER12_ATI = $8831; + GL_DRAW_BUFFER13_ATI = $8832; + GL_DRAW_BUFFER14_ATI = $8833; + GL_DRAW_BUFFER15_ATI = $8834; +var + glDrawBuffersATI: procedure(n: GLsizei; const bufs: PGLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ATI_draw_buffers: Boolean; + +{$IFDEF msWindows} +//***** WGL_ATI_pixel_format_float *****// +const + WGL_RGBA_FLOAT_MODE_ATI = $8820; + WGL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI = $8835; + WGL_TYPE_RGBA_FLOAT_ATI = $21A0; + +function Load_WGL_ATI_pixel_format_float: Boolean; +{$ENDIF} + +//***** GL_ATI_texture_env_combine3 *****// +const + GL_MODULATE_ADD_ATI = $8744; + GL_MODULATE_SIGNED_ADD_ATI = $8745; + GL_MODULATE_SUBTRACT_ATI = $8746; + +function Load_GL_ATI_texture_env_combine3: Boolean; + +//***** GL_ATI_texture_float *****// +const + GL_RGBA_FLOAT32_ATI = $8814; + GL_RGB_FLOAT32_ATI = $8815; + GL_ALPHA_FLOAT32_ATI = $8816; + GL_INTENSITY_FLOAT32_ATI = $8817; + GL_LUMINANCE_FLOAT32_ATI = $8818; + GL_LUMINANCE_ALPHA_FLOAT32_ATI = $8819; + GL_RGBA_FLOAT16_ATI = $881A; + GL_RGB_FLOAT16_ATI = $881B; + GL_ALPHA_FLOAT16_ATI = $881C; + GL_INTENSITY_FLOAT16_ATI = $881D; + GL_LUMINANCE_FLOAT16_ATI = $881E; + GL_LUMINANCE_ALPHA_FLOAT16_ATI = $881F; + +function Load_GL_ATI_texture_float: Boolean; + +//***** GL_NV_texture_expand_normal *****// +const + GL_TEXTURE_UNSIGNED_REMAP_MODE_NV = $888F; + +function Load_GL_NV_texture_expand_normal: Boolean; + +//***** GL_NV_half_float *****// +const + GL_HALF_FLOAT_NV = $140B; +var + glVertex2hNV: procedure(x: GLushort; y: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex2hvNV: procedure(const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex3hNV: procedure(x: GLushort; y: GLushort; z: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex3hvNV: procedure(const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex4hNV: procedure(x: GLushort; y: GLushort; z: GLushort; w: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertex4hvNV: procedure(const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormal3hNV: procedure(nx: GLushort; ny: GLushort; nz: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormal3hvNV: procedure(const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor3hNV: procedure(red: GLushort; green: GLushort; blue: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor3hvNV: procedure(const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4hNV: procedure(red: GLushort; green: GLushort; blue: GLushort; alpha: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColor4hvNV: procedure(const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord1hNV: procedure(s: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord1hvNV: procedure(const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord2hNV: procedure(s: GLushort; t: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord2hvNV: procedure(const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord3hNV: procedure(s: GLushort; t: GLushort; r: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord3hvNV: procedure(const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord4hNV: procedure(s: GLushort; t: GLushort; r: GLushort; q: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoord4hvNV: procedure(const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord1hNV: procedure(target: GLenum; s: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord1hvNV: procedure(target: GLenum; const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord2hNV: procedure(target: GLenum; s: GLushort; t: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord2hvNV: procedure(target: GLenum; const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord3hNV: procedure(target: GLenum; s: GLushort; t: GLushort; r: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord3hvNV: procedure(target: GLenum; const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord4hNV: procedure(target: GLenum; s: GLushort; t: GLushort; r: GLushort; q: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoord4hvNV: procedure(target: GLenum; const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFogCoordhNV: procedure(fog: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFogCoordhvNV: procedure(const fog: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3hNV: procedure(red: GLushort; green: GLushort; blue: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3hvNV: procedure(const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexWeighthNV: procedure(weight: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexWeighthvNV: procedure(const weight: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib1hNV: procedure(index: GLuint; x: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib1hvNV: procedure(index: GLuint; const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib2hNV: procedure(index: GLuint; x: GLushort; y: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib2hvNV: procedure(index: GLuint; const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib3hNV: procedure(index: GLuint; x: GLushort; y: GLushort; z: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib3hvNV: procedure(index: GLuint; const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4hNV: procedure(index: GLuint; x: GLushort; y: GLushort; z: GLushort; w: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4hvNV: procedure(index: GLuint; const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribs1hvNV: procedure(index: GLuint; n: GLsizei; const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribs2hvNV: procedure(index: GLuint; n: GLsizei; const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribs3hvNV: procedure(index: GLuint; n: GLsizei; const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribs4hvNV: procedure(index: GLuint; n: GLsizei; const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_NV_half_float: Boolean; + +//***** GL_ATI_map_object_buffer *****// +var + glMapObjectBufferATI: function(buffer: GLuint): PGLvoid; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUnmapObjectBufferATI: procedure(buffer: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ATI_map_object_buffer: Boolean; + +//***** GL_ATI_separate_stencil *****// +const + GL_KEEP = $1E00; + GL_ZERO = $0000; + GL_REPLACE = $1E01; + GL_INCR = $1E02; + GL_DECR = $1E03; + GL_INVERT = $150A; + GL_NEVER = $0200; + GL_LESS = $0201; + GL_LEQUAL = $0203; + GL_GREATER = $0204; + GL_GEQUAL = $0206; + GL_EQUAL = $0202; + GL_NOTEQUAL = $0205; + GL_ALWAYS = $0207; + GL_FRONT = $0404; + GL_BACK = $0405; + GL_FRONT_AND_BACK = $0408; + GL_STENCIL_BACK_FUNC_ATI = $8800; + GL_STENCIL_BACK_FAIL_ATI = $8801; + GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI = $8802; + GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI = $8803; +var + glStencilOpSeparateATI: procedure(face: GLenum; sfail: GLenum; dpfail: GLenum; dppass: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glStencilFuncSeparateATI: procedure(frontfunc: GLenum; backfunc: GLenum; ref: GLint; mask: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ATI_separate_stencil: Boolean; + +//***** GL_ATI_vertex_attrib_array_object *****// +var + glVertexAttribArrayObjectATI: procedure(index: GLuint; size: GLint; _type: GLenum; normalized: GLboolean; stride: GLsizei; buffer: GLuint; offset: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVertexAttribArrayObjectfvATI: procedure(index: GLuint; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVertexAttribArrayObjectivATI: procedure(index: GLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ATI_vertex_attrib_array_object: Boolean; + +//***** GL_ARB_occlusion_query *****// +const + GL_SAMPLES_PASSED_ARB = $8914; + GL_QUERY_COUNTER_BITS_ARB = $8864; + GL_CURRENT_QUERY_ARB = $8865; + GL_QUERY_RESULT_ARB = $8866; + GL_QUERY_RESULT_AVAILABLE_ARB = $8867; +var + glGenQueriesARB: procedure(n: GLsizei; ids: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteQueriesARB: procedure(n: GLsizei; const ids: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsQueryARB: function(id: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBeginQueryARB: procedure(target: GLenum; id: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEndQueryARB: procedure(target: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetQueryivARB: procedure(target: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetQueryObjectivARB: procedure(id: GLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetQueryObjectuivARB: procedure(id: GLuint; pname: GLenum; params: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_occlusion_query: Boolean; + +//***** GL_ARB_shader_objects *****// +const + GL_PROGRAM_OBJECT_ARB = $8B40; + GL_OBJECT_TYPE_ARB = $8B4E; + GL_OBJECT_SUBTYPE_ARB = $8B4F; + GL_OBJECT_DELETE_STATUS_ARB = $8B80; + GL_OBJECT_COMPILE_STATUS_ARB = $8B81; + GL_OBJECT_LINK_STATUS_ARB = $8B82; + GL_OBJECT_VALIDATE_STATUS_ARB = $8B83; + GL_OBJECT_INFO_LOG_LENGTH_ARB = $8B84; + GL_OBJECT_ATTACHED_OBJECTS_ARB = $8B85; + GL_OBJECT_ACTIVE_UNIFORMS_ARB = $8B86; + GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB = $8B87; + GL_OBJECT_SHADER_SOURCE_LENGTH_ARB = $8B88; + GL_SHADER_OBJECT_ARB = $8B48; + GL_FLOAT = $1406; + GL_FLOAT_VEC2_ARB = $8B50; + GL_FLOAT_VEC3_ARB = $8B51; + GL_FLOAT_VEC4_ARB = $8B52; + GL_INT = $1404; + GL_INT_VEC2_ARB = $8B53; + GL_INT_VEC3_ARB = $8B54; + GL_INT_VEC4_ARB = $8B55; + GL_BOOL_ARB = $8B56; + GL_BOOL_VEC2_ARB = $8B57; + GL_BOOL_VEC3_ARB = $8B58; + GL_BOOL_VEC4_ARB = $8B59; + GL_FLOAT_MAT2_ARB = $8B5A; + GL_FLOAT_MAT3_ARB = $8B5B; + GL_FLOAT_MAT4_ARB = $8B5C; +var + glDeleteObjectARB: procedure(obj: GLhandleARB); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetHandleARB: function(pname: GLenum): GLhandleARB; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDetachObjectARB: procedure(containerObj: GLhandleARB; attachedObj: GLhandleARB); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCreateShaderObjectARB: function(shaderType: GLenum): GLhandleARB; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glShaderSourceARB: procedure(shaderObj: GLhandleARB; count: GLsizei; const _string: PGLvoid; const length: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCompileShaderARB: procedure(shaderObj: GLhandleARB); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCreateProgramObjectARB: function(): GLhandleARB; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glAttachObjectARB: procedure(containerObj: GLhandleARB; obj: GLhandleARB); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLinkProgramARB: procedure(programObj: GLhandleARB); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUseProgramObjectARB: procedure(programObj: GLhandleARB); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glValidateProgramARB: procedure(programObj: GLhandleARB); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform1fARB: procedure(location: GLint; v0: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform2fARB: procedure(location: GLint; v0: GLfloat; v1: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform3fARB: procedure(location: GLint; v0: GLfloat; v1: GLfloat; v2: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform4fARB: procedure(location: GLint; v0: GLfloat; v1: GLfloat; v2: GLfloat; v3: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform1iARB: procedure(location: GLint; v0: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform2iARB: procedure(location: GLint; v0: GLint; v1: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform3iARB: procedure(location: GLint; v0: GLint; v1: GLint; v2: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform4iARB: procedure(location: GLint; v0: GLint; v1: GLint; v2: GLint; v3: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform1fvARB: procedure(location: GLint; count: GLsizei; value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform2fvARB: procedure(location: GLint; count: GLsizei; value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform3fvARB: procedure(location: GLint; count: GLsizei; value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform4fvARB: procedure(location: GLint; count: GLsizei; value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform1ivARB: procedure(location: GLint; count: GLsizei; value: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform2ivARB: procedure(location: GLint; count: GLsizei; value: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform3ivARB: procedure(location: GLint; count: GLsizei; value: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform4ivARB: procedure(location: GLint; count: GLsizei; value: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformMatrix2fvARB: procedure(location: GLint; count: GLsizei; transpose: GLboolean; value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformMatrix3fvARB: procedure(location: GLint; count: GLsizei; transpose: GLboolean; value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformMatrix4fvARB: procedure(location: GLint; count: GLsizei; transpose: GLboolean; value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetObjectParameterfvARB: procedure(obj: GLhandleARB; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetObjectParameterivARB: procedure(obj: GLhandleARB; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetInfoLogARB: procedure(obj: GLhandleARB; maxLength: GLsizei; length: PGLsizei; infoLog: PGLcharARB); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetAttachedObjectsARB: procedure(containerObj: GLhandleARB; maxCount: GLsizei; count: PGLsizei; obj: PGLhandleARB); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetUniformLocationARB: function(programObj: GLhandleARB; const name: PGLcharARB): GLint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetActiveUniformARB: procedure(programObj: GLhandleARB; index: GLuint; maxLength: GLsizei; length: PGLsizei; size: PGLint; _type: PGLenum; name: PGLcharARB); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetUniformfvARB: procedure(programObj: GLhandleARB; location: GLint; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetUniformivARB: procedure(programObj: GLhandleARB; location: GLint; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetShaderSourceARB: procedure(obj: GLhandleARB; maxLength: GLsizei; length: PGLsizei; source: PGLcharARB); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_shader_objects: Boolean; + +//***** GL_ARB_vertex_shader *****// +const + GL_VERTEX_SHADER_ARB = $8B31; + GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB = $8B4A; + GL_MAX_VARYING_FLOATS_ARB = $8B4B; + // GL_MAX_VERTEX_ATTRIBS_ARB { already defined } + // GL_MAX_TEXTURE_IMAGE_UNITS_ARB { already defined } + GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB = $8B4C; + GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB = $8B4D; + // GL_MAX_TEXTURE_COORDS_ARB { already defined } + // GL_VERTEX_PROGRAM_POINT_SIZE_ARB { already defined } + // GL_VERTEX_PROGRAM_TWO_SIDE_ARB { already defined } + // GL_OBJECT_TYPE_ARB { already defined } + // GL_OBJECT_SUBTYPE_ARB { already defined } + GL_OBJECT_ACTIVE_ATTRIBUTES_ARB = $8B89; + GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB = $8B8A; + // GL_SHADER_OBJECT_ARB { already defined } + // GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB { already defined } + // GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB { already defined } + // GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB { already defined } + // GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB { already defined } + // GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB { already defined } + // GL_CURRENT_VERTEX_ATTRIB_ARB { already defined } + // GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB { already defined } + // GL_FLOAT { already defined } + // GL_FLOAT_VEC2_ARB { already defined } + // GL_FLOAT_VEC3_ARB { already defined } + // GL_FLOAT_VEC4_ARB { already defined } + // GL_FLOAT_MAT2_ARB { already defined } + // GL_FLOAT_MAT3_ARB { already defined } + // GL_FLOAT_MAT4_ARB { already defined } + // glVertexAttrib1fARB { already defined } + // glVertexAttrib1sARB { already defined } + // glVertexAttrib1dARB { already defined } + // glVertexAttrib2fARB { already defined } + // glVertexAttrib2sARB { already defined } + // glVertexAttrib2dARB { already defined } + // glVertexAttrib3fARB { already defined } + // glVertexAttrib3sARB { already defined } + // glVertexAttrib3dARB { already defined } + // glVertexAttrib4fARB { already defined } + // glVertexAttrib4sARB { already defined } + // glVertexAttrib4dARB { already defined } + // glVertexAttrib4NubARB { already defined } + // glVertexAttrib1fvARB { already defined } + // glVertexAttrib1svARB { already defined } + // glVertexAttrib1dvARB { already defined } + // glVertexAttrib2fvARB { already defined } + // glVertexAttrib2svARB { already defined } + // glVertexAttrib2dvARB { already defined } + // glVertexAttrib3fvARB { already defined } + // glVertexAttrib3svARB { already defined } + // glVertexAttrib3dvARB { already defined } + // glVertexAttrib4fvARB { already defined } + // glVertexAttrib4svARB { already defined } + // glVertexAttrib4dvARB { already defined } + // glVertexAttrib4ivARB { already defined } + // glVertexAttrib4bvARB { already defined } + // glVertexAttrib4ubvARB { already defined } + // glVertexAttrib4usvARB { already defined } + // glVertexAttrib4uivARB { already defined } + // glVertexAttrib4NbvARB { already defined } + // glVertexAttrib4NsvARB { already defined } + // glVertexAttrib4NivARB { already defined } + // glVertexAttrib4NubvARB { already defined } + // glVertexAttrib4NusvARB { already defined } + // glVertexAttrib4NuivARB { already defined } + // glVertexAttribPointerARB { already defined } + // glEnableVertexAttribArrayARB { already defined } + // glDisableVertexAttribArrayARB { already defined } +var + glBindAttribLocationARB: procedure(programObj: GLhandleARB; index: GLuint; const name: PGLcharARB); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetActiveAttribARB: procedure(programObj: GLhandleARB; index: GLuint; maxLength: GLsizei; length: PGLsizei; size: PGLint; _type: PGLenum; name: PGLcharARB); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetAttribLocationARB: function(programObj: GLhandleARB; const name: PGLcharARB): GLint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + // glGetVertexAttribdvARB { already defined } + // glGetVertexAttribfvARB { already defined } + // glGetVertexAttribivARB { already defined } + // glGetVertexAttribPointervARB { already defined } + +function Load_GL_ARB_vertex_shader: Boolean; + +//***** GL_ARB_fragment_shader *****// +const + GL_FRAGMENT_SHADER_ARB = $8B30; + GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB = $8B49; + // GL_MAX_TEXTURE_COORDS_ARB { already defined } + // GL_MAX_TEXTURE_IMAGE_UNITS_ARB { already defined } + // GL_OBJECT_TYPE_ARB { already defined } + // GL_OBJECT_SUBTYPE_ARB { already defined } + // GL_SHADER_OBJECT_ARB { already defined } + +function Load_GL_ARB_fragment_shader: Boolean; + +//***** GL_ARB_shading_language_100 *****// + +function Load_GL_ARB_shading_language_100: Boolean; + +//***** GL_ARB_texture_non_power_of_two *****// + +function Load_GL_ARB_texture_non_power_of_two: Boolean; + +//***** GL_ARB_point_sprite *****// +const + GL_POINT_SPRITE_ARB = $8861; + GL_COORD_REPLACE_ARB = $8862; + +function Load_GL_ARB_point_sprite: Boolean; + +//***** GL_EXT_depth_bounds_test *****// +const + GL_DEPTH_BOUNDS_TEST_EXT = $8890; + GL_DEPTH_BOUNDS_EXT = $8891; +var + glDepthBoundsEXT: procedure(zmin: GLclampd; zmax: GLclampd); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_depth_bounds_test: Boolean; + +//***** GL_EXT_texture_mirror_clamp *****// +const + GL_MIRROR_CLAMP_EXT = $8742; + GL_MIRROR_CLAMP_TO_EDGE_EXT = $8743; + GL_MIRROR_CLAMP_TO_BORDER_EXT = $8912; + +function Load_GL_EXT_texture_mirror_clamp: Boolean; + +//***** GL_EXT_blend_equation_separate *****// +const + GL_BLEND_EQUATION_RGB_EXT = $8009; + GL_BLEND_EQUATION_ALPHA_EXT = $883D; +var + glBlendEquationSeparateEXT: procedure(modeRGB: GLenum; modeAlpha: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_blend_equation_separate: Boolean; + +//***** GL_MESA_pack_invert *****// +const + GL_PACK_INVERT_MESA = $8758; + +function Load_GL_MESA_pack_invert: Boolean; + +//***** GL_MESA_ycbcr_texture *****// +const + GL_YCBCR_MESA = $8757; + GL_UNSIGNED_SHORT_8_8_MESA = $85BA; + GL_UNSIGNED_SHORT_8_8_REV_MESA = $85BB; + +function Load_GL_MESA_ycbcr_texture: Boolean; + +//***** GL_ARB_fragment_program_shadow *****// + +function Load_GL_ARB_fragment_program_shadow: Boolean; + +//***** GL_NV_fragment_program_option *****// + +function Load_GL_NV_fragment_program_option: Boolean; + +//***** GL_EXT_pixel_buffer_object *****// +const + GL_PIXEL_PACK_BUFFER_EXT = $88EB; + GL_PIXEL_UNPACK_BUFFER_EXT = $88EC; + GL_PIXEL_PACK_BUFFER_BINDING_EXT = $88ED; + GL_PIXEL_UNPACK_BUFFER_BINDING_EXT = $88EF; + +function Load_GL_EXT_pixel_buffer_object: Boolean; + +//***** GL_NV_fragment_program2 *****// +const + GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV = $88F4; + GL_MAX_PROGRAM_CALL_DEPTH_NV = $88F5; + GL_MAX_PROGRAM_IF_DEPTH_NV = $88F6; + GL_MAX_PROGRAM_LOOP_DEPTH_NV = $88F7; + GL_MAX_PROGRAM_LOOP_COUNT_NV = $88F8; + +function Load_GL_NV_fragment_program2: Boolean; + +//***** GL_NV_vertex_program2_option *****// + // GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV { already defined } + // GL_MAX_PROGRAM_CALL_DEPTH_NV { already defined } + +function Load_GL_NV_vertex_program2_option: Boolean; + +//***** GL_NV_vertex_program3 *****// + // GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB { already defined } + +function Load_GL_NV_vertex_program3: Boolean; + +//***** GL_ARB_draw_buffers *****// +const + GL_MAX_DRAW_BUFFERS_ARB = $8824; + GL_DRAW_BUFFER0_ARB = $8825; + GL_DRAW_BUFFER1_ARB = $8826; + GL_DRAW_BUFFER2_ARB = $8827; + GL_DRAW_BUFFER3_ARB = $8828; + GL_DRAW_BUFFER4_ARB = $8829; + GL_DRAW_BUFFER5_ARB = $882A; + GL_DRAW_BUFFER6_ARB = $882B; + GL_DRAW_BUFFER7_ARB = $882C; + GL_DRAW_BUFFER8_ARB = $882D; + GL_DRAW_BUFFER9_ARB = $882E; + GL_DRAW_BUFFER10_ARB = $882F; + GL_DRAW_BUFFER11_ARB = $8830; + GL_DRAW_BUFFER12_ARB = $8831; + GL_DRAW_BUFFER13_ARB = $8832; + GL_DRAW_BUFFER14_ARB = $8833; + GL_DRAW_BUFFER15_ARB = $8834; +var + glDrawBuffersARB: procedure(n: GLsizei; const bufs: PGLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_draw_buffers: Boolean; + +//***** GL_ARB_texture_rectangle *****// +const + GL_TEXTURE_RECTANGLE_ARB = $84F5; + GL_TEXTURE_BINDING_RECTANGLE_ARB = $84F6; + GL_PROXY_TEXTURE_RECTANGLE_ARB = $84F7; + GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB = $84F8; + +function Load_GL_ARB_texture_rectangle: Boolean; + +//***** GL_ARB_color_buffer_float *****// +const + GL_RGBA_FLOAT_MODE_ARB = $8820; + GL_CLAMP_VERTEX_COLOR_ARB = $891A; + GL_CLAMP_FRAGMENT_COLOR_ARB = $891B; + GL_CLAMP_READ_COLOR_ARB = $891C; + GL_FIXED_ONLY_ARB = $891D; + WGL_TYPE_RGBA_FLOAT_ARB = $21A0; +var + glClampColorARB: procedure(target: GLenum; clamp: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_color_buffer_float: Boolean; + +//***** GL_ARB_half_float_pixel *****// +const + GL_HALF_FLOAT_ARB = $140B; + +function Load_GL_ARB_half_float_pixel: Boolean; + +//***** GL_ARB_texture_float *****// +const + GL_TEXTURE_RED_TYPE_ARB = $8C10; + GL_TEXTURE_GREEN_TYPE_ARB = $8C11; + GL_TEXTURE_BLUE_TYPE_ARB = $8C12; + GL_TEXTURE_ALPHA_TYPE_ARB = $8C13; + GL_TEXTURE_LUMINANCE_TYPE_ARB = $8C14; + GL_TEXTURE_INTENSITY_TYPE_ARB = $8C15; + GL_TEXTURE_DEPTH_TYPE_ARB = $8C16; + GL_UNSIGNED_NORMALIZED_ARB = $8C17; + GL_RGBA32F_ARB = $8814; + GL_RGB32F_ARB = $8815; + GL_ALPHA32F_ARB = $8816; + GL_INTENSITY32F_ARB = $8817; + GL_LUMINANCE32F_ARB = $8818; + GL_LUMINANCE_ALPHA32F_ARB = $8819; + GL_RGBA16F_ARB = $881A; + GL_RGB16F_ARB = $881B; + GL_ALPHA16F_ARB = $881C; + GL_INTENSITY16F_ARB = $881D; + GL_LUMINANCE16F_ARB = $881E; + GL_LUMINANCE_ALPHA16F_ARB = $881F; + +function Load_GL_ARB_texture_float: Boolean; + +//***** GL_EXT_texture_compression_dxt1 *****// + // GL_COMPRESSED_RGB_S3TC_DXT1_EXT { already defined } + // GL_COMPRESSED_RGBA_S3TC_DXT1_EXT { already defined } + +function Load_GL_EXT_texture_compression_dxt1: Boolean; + +//***** GL_ARB_pixel_buffer_object *****// +const + GL_PIXEL_PACK_BUFFER_ARB = $88EB; + GL_PIXEL_UNPACK_BUFFER_ARB = $88EC; + GL_PIXEL_PACK_BUFFER_BINDING_ARB = $88ED; + GL_PIXEL_UNPACK_BUFFER_BINDING_ARB = $88EF; + +function Load_GL_ARB_pixel_buffer_object: Boolean; + +//***** GL_EXT_framebuffer_object *****// +const + GL_FRAMEBUFFER_EXT = $8D40; + GL_RENDERBUFFER_EXT = $8D41; + GL_STENCIL_INDEX_EXT = $8D45; + GL_STENCIL_INDEX1_EXT = $8D46; + GL_STENCIL_INDEX4_EXT = $8D47; + GL_STENCIL_INDEX8_EXT = $8D48; + GL_STENCIL_INDEX16_EXT = $8D49; + GL_RENDERBUFFER_WIDTH_EXT = $8D42; + GL_RENDERBUFFER_HEIGHT_EXT = $8D43; + GL_RENDERBUFFER_INTERNAL_FORMAT_EXT = $8D44; + GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT = $8CD0; + GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT = $8CD1; + GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT = $8CD2; + GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT = $8CD3; + GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT = $8CD4; + GL_COLOR_ATTACHMENT0_EXT = $8CE0; + GL_COLOR_ATTACHMENT1_EXT = $8CE1; + GL_COLOR_ATTACHMENT2_EXT = $8CE2; + GL_COLOR_ATTACHMENT3_EXT = $8CE3; + GL_COLOR_ATTACHMENT4_EXT = $8CE4; + GL_COLOR_ATTACHMENT5_EXT = $8CE5; + GL_COLOR_ATTACHMENT6_EXT = $8CE6; + GL_COLOR_ATTACHMENT7_EXT = $8CE7; + GL_COLOR_ATTACHMENT8_EXT = $8CE8; + GL_COLOR_ATTACHMENT9_EXT = $8CE9; + GL_COLOR_ATTACHMENT10_EXT = $8CEA; + GL_COLOR_ATTACHMENT11_EXT = $8CEB; + GL_COLOR_ATTACHMENT12_EXT = $8CEC; + GL_COLOR_ATTACHMENT13_EXT = $8CED; + GL_COLOR_ATTACHMENT14_EXT = $8CEE; + GL_COLOR_ATTACHMENT15_EXT = $8CEF; + GL_DEPTH_ATTACHMENT_EXT = $8D00; + GL_STENCIL_ATTACHMENT_EXT = $8D20; + GL_FRAMEBUFFER_COMPLETE_EXT = $8CD5; + GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT = $8CD6; + GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT = $8CD7; + GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT = $8CD8; + GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT = $8CD9; + GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT = $8CDA; + GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT = $8CDB; + GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT = $8CDC; + GL_FRAMEBUFFER_UNSUPPORTED_EXT = $8CDD; + GL_FRAMEBUFFER_STATUS_ERROR_EXT = $8CDE; + GL_FRAMEBUFFER_BINDING_EXT = $8CA6; + GL_RENDERBUFFER_BINDING_EXT = $8CA7; + GL_MAX_COLOR_ATTACHMENTS_EXT = $8CDF; + GL_MAX_RENDERBUFFER_SIZE_EXT = $84E8; + GL_INVALID_FRAMEBUFFER_OPERATION_EXT = $0506; +var + glIsRenderbufferEXT: function(renderbuffer: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBindRenderbufferEXT: procedure(target: GLenum; renderbuffer: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteRenderbuffersEXT: procedure(n: GLsizei; const renderbuffers: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGenRenderbuffersEXT: procedure(n: GLsizei; renderbuffers: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRenderbufferStorageEXT: procedure(target: GLenum; internalformat: GLenum; width: GLsizei; height: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetRenderbufferParameterivEXT: procedure(target: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsFramebufferEXT: function(framebuffer: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBindFramebufferEXT: procedure(target: GLenum; framebuffer: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteFramebuffersEXT: procedure(n: GLsizei; const framebuffers: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGenFramebuffersEXT: procedure(n: GLsizei; framebuffers: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCheckFramebufferStatusEXT: function(target: GLenum): GLenum; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFramebufferTexture1DEXT: procedure(target: GLenum; attachment: GLenum; textarget: GLenum; texture: GLuint; level: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFramebufferTexture2DEXT: procedure(target: GLenum; attachment: GLenum; textarget: GLenum; texture: GLuint; level: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFramebufferTexture3DEXT: procedure(target: GLenum; attachment: GLenum; textarget: GLenum; texture: GLuint; level: GLint; zoffset: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFramebufferRenderbufferEXT: procedure(target: GLenum; attachment: GLenum; renderbuffertarget: GLenum; renderbuffer: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetFramebufferAttachmentParameterivEXT: procedure(target: GLenum; attachment: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGenerateMipmapEXT: procedure(target: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_EXT_framebuffer_object: Boolean; + +//**** GL_ARB_framebuffer_object *****// +const + GL_INVALID_FRAMEBUFFER_OPERATION = $0506; + GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING = $8210; + GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE = $8211; + GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE = $8212; + GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE = $8213; + GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE = $8214; + GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE = $8215; + GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE = $8216; + GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE = $8217; + GL_FRAMEBUFFER_DEFAULT = $8218; + GL_FRAMEBUFFER_UNDEFINED = $8219; + GL_DEPTH_STENCIL_ATTACHMENT = $821A; + GL_MAX_RENDERBUFFER_SIZE = $84E8; + GL_DEPTH_STENCIL = $84F9; + GL_UNSIGNED_INT_24_8 = $84FA; + GL_DEPTH24_STENCIL8 = $88F0; + GL_TEXTURE_STENCIL_SIZE = $88F1; + GL_TEXTURE_RED_TYPE = $8C10; + GL_TEXTURE_GREEN_TYPE = $8C11; + GL_TEXTURE_BLUE_TYPE = $8C12; + GL_TEXTURE_ALPHA_TYPE = $8C13; + GL_TEXTURE_DEPTH_TYPE = $8C16; + GL_UNSIGNED_NORMALIZED = $8C17; + GL_FRAMEBUFFER_BINDING = $8CA6; + GL_DRAW_FRAMEBUFFER_BINDING = GL_FRAMEBUFFER_BINDING; + GL_RENDERBUFFER_BINDING = $8CA7; + GL_READ_FRAMEBUFFER = $8CA8; + GL_DRAW_FRAMEBUFFER = $8CA9; + GL_READ_FRAMEBUFFER_BINDING = $8CAA; + GL_RENDERBUFFER_SAMPLES = $8CAB; + GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE = $8CD0; + GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME = $8CD1; + GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL = $8CD2; + GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE = $8CD3; + GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER = $8CD4; + GL_FRAMEBUFFER_COMPLETE = $8CD5; + GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT = $8CD6; + GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = $8CD7; + GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER = $8CDB; + GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER = $8CDC; + GL_FRAMEBUFFER_UNSUPPORTED = $8CDD; + GL_MAX_COLOR_ATTACHMENTS = $8CDF; + GL_COLOR_ATTACHMENT0 = $8CE0; + GL_COLOR_ATTACHMENT1 = $8CE1; + GL_COLOR_ATTACHMENT2 = $8CE2; + GL_COLOR_ATTACHMENT3 = $8CE3; + GL_COLOR_ATTACHMENT4 = $8CE4; + GL_COLOR_ATTACHMENT5 = $8CE5; + GL_COLOR_ATTACHMENT6 = $8CE6; + GL_COLOR_ATTACHMENT7 = $8CE7; + GL_COLOR_ATTACHMENT8 = $8CE8; + GL_COLOR_ATTACHMENT9 = $8CE9; + GL_COLOR_ATTACHMENT10 = $8CEA; + GL_COLOR_ATTACHMENT11 = $8CEB; + GL_COLOR_ATTACHMENT12 = $8CEC; + GL_COLOR_ATTACHMENT13 = $8CED; + GL_COLOR_ATTACHMENT14 = $8CEE; + GL_COLOR_ATTACHMENT15 = $8CEF; + GL_DEPTH_ATTACHMENT = $8D00; + GL_STENCIL_ATTACHMENT = $8D20; + GL_FRAMEBUFFER = $8D40; + GL_RENDERBUFFER = $8D41; + GL_RENDERBUFFER_WIDTH = $8D42; + GL_RENDERBUFFER_HEIGHT = $8D43; + GL_RENDERBUFFER_INTERNAL_FORMAT = $8D44; + GL_STENCIL_INDEX1 = $8D46; + GL_STENCIL_INDEX4 = $8D47; + GL_STENCIL_INDEX8 = $8D48; + GL_STENCIL_INDEX16 = $8D49; + GL_RENDERBUFFER_RED_SIZE = $8D50; + GL_RENDERBUFFER_GREEN_SIZE = $8D51; + GL_RENDERBUFFER_BLUE_SIZE = $8D52; + GL_RENDERBUFFER_ALPHA_SIZE = $8D53; + GL_RENDERBUFFER_DEPTH_SIZE = $8D54; + GL_RENDERBUFFER_STENCIL_SIZE = $8D55; + GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE = $8D56; + GL_MAX_SAMPLES = $8D57; +var + glIsRenderbuffer: function(renderbuffer: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBindRenderbuffer: procedure(target: GLenum; renderbuffer: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteRenderbuffers: procedure(n: GLsizei; const renderbuffers: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGenRenderbuffers: procedure(n: GLsizei; renderbuffers: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRenderbufferStorage: procedure(target: GLenum; internalformat: GLenum; width: GLsizei; height: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetRenderbufferParameteriv: procedure(target: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsFramebuffer: function(framebuffer: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBindFramebuffer: procedure(target: GLenum; framebuffer: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteFramebuffers: procedure(n: GLsizei; const framebuffers: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGenFramebuffers: procedure(n: GLsizei; framebuffers: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCheckFramebufferStatus: function(target: GLenum): GLenum; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFramebufferTexture1D: procedure(target: GLenum; attachment: GLenum; textarget: GLenum; texture: GLuint; level: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFramebufferTexture2D: procedure(target: GLenum; attachment: GLenum; textarget: GLenum; texture: GLuint; level: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFramebufferTexture3D: procedure(target: GLenum; attachment: GLenum; textarget: GLenum; texture: GLuint; level: GLint; zoffset: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFramebufferRenderbuffer: procedure(target: GLenum; attachment: GLenum; renderbuffertarget: GLenum; renderbuffer: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetFramebufferAttachmentParameteriv: procedure(target: GLenum; attachment: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGenerateMipmap: procedure(target: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBlitFramebuffer: procedure(srcX0: GLint; srcY0: GLint; srcX1: GLint; srcY1: GLint; dstX0: GLint; dstY0: GLint; dstX1: GLint; dstY1: GLint; mask: GLbitfield; filter: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glRenderbufferStorageMultisample: procedure(target: GLenum; samples: GLsizei; internalformat: GLenum; width: GLsizei; height: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFramebufferTextureLayer: procedure(target: GLenum; attachment: GLenum; texture: GLuint; level: GLint; layer: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_framebuffer_object(): Boolean; + +//**** GL_ARB_framebuffer_object DEPRECATED *****// +const + GL_INDEX = $8222; + GL_TEXTURE_LUMINANCE_TYPE = $8C14; + GL_TEXTURE_INTENSITY_TYPE = $8C15; + + +//**** GL_ARB_map_buffer_range *****// +const + GL_MAP_READ_BIT = $0001; + GL_MAP_WRITE_BIT = $0002; + GL_MAP_INVALIDATE_RANGE_BIT = $0004; + GL_MAP_INVALIDATE_BUFFER_BIT = $0008; + GL_MAP_FLUSH_EXPLICIT_BIT = $0010; + GL_MAP_UNSYNCHRONIZED_BIT = $0020; +var + glMapBufferRange: function(target: GLenum; offset: GLintptr; length: GLsizeiptr; access: GLbitfield): PGLvoid; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFlushMappedBufferRange: procedure(target: GLenum; offset: GLintptr; length: GLsizeiptr); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_map_buffer_range(): Boolean; + +//**** GL_ARB_vertex_array_object *****// +const + GL_VERTEX_ARRAY_BINDING = $85B5; +var + glBindVertexArray: procedure(_array: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteVertexArrays: procedure(n: GLsizei; const arrays: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGenVertexArrays: procedure(n: GLsizei; arrays: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsVertexArray: function(_array: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_vertex_array_object(): Boolean; + +//**** GL_ARB_copy_buffer *****// +const + GL_COPY_READ_BUFFER = $8F36; + GL_COPY_WRITE_BUFFER = $8F37; +var + glCopyBufferSubData: procedure(readTarget: GLenum; writeTarget: GLenum; readOffset: GLintptr; writeOffset: GLintptr; size: GLsizeiptr); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_copy_buffer(): Boolean; + +//**** GL_ARB_uniform_buffer_object *****// +const + GL_UNIFORM_BUFFER = $8A11; + GL_UNIFORM_BUFFER_BINDING = $8A28; + GL_UNIFORM_BUFFER_START = $8A29; + GL_UNIFORM_BUFFER_SIZE = $8A2A; + GL_MAX_VERTEX_UNIFORM_BLOCKS = $8A2B; + GL_MAX_GEOMETRY_UNIFORM_BLOCKS = $8A2C; + GL_MAX_FRAGMENT_UNIFORM_BLOCKS = $8A2D; + GL_MAX_COMBINED_UNIFORM_BLOCKS = $8A2E; + GL_MAX_UNIFORM_BUFFER_BINDINGS = $8A2F; + GL_MAX_UNIFORM_BLOCK_SIZE = $8A30; + GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS = $8A31; + GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS = $8A32; + GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS = $8A33; + GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT = $8A34; + GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH = $8A35; + GL_ACTIVE_UNIFORM_BLOCKS = $8A36; + GL_UNIFORM_TYPE = $8A37; + GL_UNIFORM_SIZE = $8A38; + GL_UNIFORM_NAME_LENGTH = $8A39; + GL_UNIFORM_BLOCK_INDEX = $8A3A; + GL_UNIFORM_OFFSET = $8A3B; + GL_UNIFORM_ARRAY_STRIDE = $8A3C; + GL_UNIFORM_MATRIX_STRIDE = $8A3D; + GL_UNIFORM_IS_ROW_MAJOR = $8A3E; + GL_UNIFORM_BLOCK_BINDING = $8A3F; + GL_UNIFORM_BLOCK_DATA_SIZE = $8A40; + GL_UNIFORM_BLOCK_NAME_LENGTH = $8A41; + GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS = $8A42; + GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES = $8A43; + GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER = $8A44; + GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER = $8A45; + GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER = $8A46; + GL_INVALID_INDEX = DWord($FFFFFFFF); +var + glGetUniformIndices: procedure(_program: GLuint; uniformCount: GLsizei; const uniformNames: PPGLchar; uniformIndices: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetActiveUniformsiv: procedure(_program: GLuint; uniformCount: GLsizei; const uniformIndices: PGLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetActiveUniformName: procedure(_program: GLuint; uniformIndex: GLuint; bufSize: GLsizei; length: PGLsizei; uniformName: PGLchar); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetUniformBlockIndex: function(_program: GLuint; const uniformBlockName: PGLchar): GLuint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetActiveUniformBlockiv: procedure(_program: GLuint; uniformBlockIndex: GLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetActiveUniformBlockName: procedure(_program: GLuint; uniformBlockIndex: GLuint; bufSize: GLsizei; length: PGLsizei; uniformBlockName: PGLchar); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformBlockBinding: procedure(_program: GLuint; uniformBlockIndex: GLuint; uniformBlockBinding: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_uniform_buffer_object(): Boolean; + +//**** GL_ARB_draw_elements_base_vertex *****// +var + glDrawElementsBaseVertex: procedure(mode: GLenum; count: GLsizei; _type: GLenum; const indices: PGLvoid; basevertex: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDrawRangeElementsBaseVertex: procedure(mode: GLenum; start: GLuint; _end: GLuint; count: GLsizei; _type: GLenum; const indices: PGLvoid; basevertex: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDrawElementsInstancedBaseVertex: procedure(mode: GLenum; count: GLsizei; _type: GLenum; const indices: PGLvoid; primcount: GLsizei; basevertex: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiDrawElementsBaseVertex: procedure(mode: GLenum; const count: PGLsizei; _type: GLenum; const indices: PPGLvoid; primcount: GLsizei; const basevertex: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_draw_elements_base_vertex(): Boolean; + +//**** GL_ARB_provoking_vertex *****// +const + GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION = $8E4C; + GL_FIRST_VERTEX_CONVENTION = $8E4D; + GL_LAST_VERTEX_CONVENTION = $8E4E; + GL_PROVOKING_VERTEX = $8E4F; +var + glProvokingVertex: procedure(mode: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_provoking_vertex(): Boolean; + +//**** GL_ARB_sync *****// +type + GLsync = Pointer; + TGLsync = GLSync; + PGLsync = ^GLSync; + +const + GL_MAX_SERVER_WAIT_TIMEOUT = $9111; + GL_OBJECT_TYPE = $9112; + GL_SYNC_CONDITION = $9113; + GL_SYNC_STATUS = $9114; + GL_SYNC_FLAGS = $9115; + GL_SYNC_FENCE = $9116; + GL_SYNC_GPU_COMMANDS_COMPLETE = $9117; + GL_UNSIGNALED = $9118; + GL_SIGNALED = $9119; + GL_ALREADY_SIGNALED = $911A; + GL_TIMEOUT_EXPIRED = $911B; + GL_CONDITION_SATISFIED = $911C; + GL_WAIT_FAILED = $911D; + GL_SYNC_FLUSH_COMMANDS_BIT = $00000001; + GL_TIMEOUT_IGNORED = QWord($FFFFFFFFFFFFFFFF); +var + glFenceSync: function(condition: GLenum; flags: GLbitfield): GLsync; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsSync: function(sync: GLsync): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteSync: procedure(sync: GLsync); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glClientWaitSync: function(sync: GLsync; flags: GLbitfield; timeout: GLuint64): GLenum; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWaitSync: procedure(sync: GLsync; flags: GLbitfield; timeout: GLuint64); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetInteger64v: procedure(pname: GLenum; params: PGLint64); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetSynciv: procedure(sync: GLsync; pname: GLenum; bufSize: GLsizei; length: PGLsizei; values: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_sync(): Boolean; + +//**** GL_ARB_texture_multisample *****// +const + GL_SAMPLE_POSITION = $8E50; + GL_SAMPLE_MASK = $8E51; + GL_SAMPLE_MASK_VALUE = $8E52; + GL_MAX_SAMPLE_MASK_WORDS = $8E59; + GL_TEXTURE_2D_MULTISAMPLE = $9100; + GL_PROXY_TEXTURE_2D_MULTISAMPLE = $9101; + GL_TEXTURE_2D_MULTISAMPLE_ARRAY = $9102; + GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY = $9103; + GL_TEXTURE_BINDING_2D_MULTISAMPLE = $9104; + GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY = $9105; + GL_TEXTURE_SAMPLES = $9106; + GL_TEXTURE_FIXED_SAMPLE_LOCATIONS = $9107; + GL_SAMPLER_2D_MULTISAMPLE = $9108; + GL_INT_SAMPLER_2D_MULTISAMPLE = $9109; + GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE = $910A; + GL_SAMPLER_2D_MULTISAMPLE_ARRAY = $910B; + GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY = $910C; + GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY = $910D; + GL_MAX_COLOR_TEXTURE_SAMPLES = $910E; + GL_MAX_DEPTH_TEXTURE_SAMPLES = $910F; + GL_MAX_INTEGER_SAMPLES = $9110; +var + glTexImage2DMultisample: procedure(target: GLenum; samples: GLsizei; internalformat: GLint; width: GLsizei; height: GLsizei; fixedsamplelocations: GLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexImage3DMultisample: procedure(target: GLenum; samples: GLsizei; internalformat: GLint; width: GLsizei; height: GLsizei; depth: GLsizei; fixedsamplelocations: GLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetMultisamplefv: procedure(pname: GLenum; index: GLuint; val: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSampleMaski: procedure(index: GLuint; mask: GLbitfield); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_texture_multisample(): Boolean; + +//**** GL_ARB_blend_func_extended *****// +const + GL_SRC1_COLOR = $88F9; +// reuse GL_SRC1_ALPHA +const + GL_ONE_MINUS_SRC1_COLOR = $88FA; + GL_ONE_MINUS_SRC1_ALPHA = $88FB; + GL_MAX_DUAL_SOURCE_DRAW_BUFFERS = $88FC; +var + glBindFragDataLocationIndexed: procedure(_program: GLuint; colorNumber: GLuint; index: GLuint; const name: PGLchar); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetFragDataIndex: function(_program: GLuint; const name: PGLchar): GLint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_blend_func_extended(): Boolean; + +//**** GL_ARB_sampler_objects *****// +const + GL_SAMPLER_BINDING = $8919; +var + glGenSamplers: procedure(count: GLsizei; samplers: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteSamplers: procedure(count: GLsizei; const samplers: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsSampler: function(sampler: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBindSampler: procedure(_unit: GLenum; sampler: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSamplerParameteri: procedure(sampler: GLuint; pname: GLenum; param: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSamplerParameteriv: procedure(sampler: GLuint; pname: GLenum; const param: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSamplerParameterf: procedure(sampler: GLuint; pname: GLenum; param: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSamplerParameterfv: procedure(sampler: GLuint; pname: GLenum; const param: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSamplerParameterIiv: procedure(sampler: GLuint; pname: GLenum; const param: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSamplerParameterIuiv: procedure(sampler: GLuint; pname: GLenum; const param: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetSamplerParameteriv: procedure(sampler: GLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetSamplerParameterIiv: procedure(sampler: GLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetSamplerParameterfv: procedure(sampler: GLuint; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetSamplerParameterIfv: procedure(sampler: GLuint; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_sampler_objects(): Boolean; + +//**** GL_ARB_timer_query *****// +const + GL_TIME_ELAPSED = $88BF; + GL_TIMESTAMP = $8E28; +var + glQueryCounter: procedure(id: GLuint; target: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetQueryObjecti64v: procedure(id: GLuint; pname: GLenum; params: PGLint64); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetQueryObjectui64v: procedure(id: GLuint; pname: GLenum; params: PGLuint64); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_timer_query(): Boolean; + +//**** GL_ARB_vertex_type_2_10_10_10_rev *****// + +const + GL_INT_2_10_10_10_REV = $8D9F; +var + glVertexP2ui: procedure(_type: GLenum; value: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexP2uiv: procedure(_type: GLenum; const value: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexP3ui: procedure(_type: GLenum; value: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexP3uiv: procedure(_type: GLenum; const value: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexP4ui: procedure(_type: GLenum; value: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexP4uiv: procedure(_type: GLenum; const value: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoordP1ui: procedure(_type: GLenum; coords: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoordP1uiv: procedure(_type: GLenum; const coords: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoordP2ui: procedure(_type: GLenum; coords: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoordP2uiv: procedure(_type: GLenum; const coords: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoordP3ui: procedure(_type: GLenum; coords: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoordP3uiv: procedure(_type: GLenum; const coords: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoordP4ui: procedure(_type: GLenum; coords: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexCoordP4uiv: procedure(_type: GLenum; const coords: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoordP1ui: procedure(texture: GLenum; _type: GLenum; coords: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoordP1uiv: procedure(texture: GLenum; _type: GLenum; const coords: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoordP2ui: procedure(texture: GLenum; _type: GLenum; coords: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoordP2uiv: procedure(texture: GLenum; _type: GLenum; const coords: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoordP3ui: procedure(texture: GLenum; _type: GLenum; coords: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoordP3uiv: procedure(texture: GLenum; _type: GLenum; const coords: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoordP4ui: procedure(texture: GLenum; _type: GLenum; coords: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiTexCoordP4uiv: procedure(texture: GLenum; _type: GLenum; const coords: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormalP3ui: procedure(_type: GLenum; coords: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glNormalP3uiv: procedure(_type: GLenum; const coords: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColorP3ui: procedure(_type: GLenum; color: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColorP3uiv: procedure(_type: GLenum; const color: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColorP4ui: procedure(_type: GLenum; color: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glColorP4uiv: procedure(_type: GLenum; const color: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColorP3ui: procedure(_type: GLenum; color: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColorP3uiv: procedure(_type: GLenum; const color: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribP1ui: procedure(index: GLuint; _type: GLenum; normalized: GLboolean; value: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribP1uiv: procedure(index: GLuint; _type: GLenum; normalized: GLboolean; const value: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribP2ui: procedure(index: GLuint; _type: GLenum; normalized: GLboolean; value: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribP2uiv: procedure(index: GLuint; _type: GLenum; normalized: GLboolean; const value: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribP3ui: procedure(index: GLuint; _type: GLenum; normalized: GLboolean; value: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribP3uiv: procedure(index: GLuint; _type: GLenum; normalized: GLboolean; const value: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribP4ui: procedure(index: GLuint; _type: GLenum; normalized: GLboolean; value: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribP4uiv: procedure(index: GLuint; _type: GLenum; normalized: GLboolean; const value: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_vertex_type_2_10_10_10_rev(): Boolean; + +//**** GL_ARB_gpu_shader_fp64 *****// +// reuse GL_DOUBLE +const + GL_DOUBLE_VEC2 = $8FFC; + GL_DOUBLE_VEC3 = $8FFD; + GL_DOUBLE_VEC4 = $8FFE; + GL_DOUBLE_MAT2 = $8F46; + GL_DOUBLE_MAT3 = $8F47; + GL_DOUBLE_MAT4 = $8F48; + GL_DOUBLE_MAT2x3 = $8F49; + GL_DOUBLE_MAT2x4 = $8F4A; + GL_DOUBLE_MAT3x2 = $8F4B; + GL_DOUBLE_MAT3x4 = $8F4C; + GL_DOUBLE_MAT4x2 = $8F4D; + GL_DOUBLE_MAT4x3 = $8F4E; +var + glUniform1d: procedure(location: GLint; x: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform2d: procedure(location: GLint; x: GLdouble; y: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform3d: procedure(location: GLint; x: GLdouble; y: GLdouble; z: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform4d: procedure(location: GLint; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform1dv: procedure(location: GLint; count: GLsizei; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform2dv: procedure(location: GLint; count: GLsizei; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform3dv: procedure(location: GLint; count: GLsizei; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform4dv: procedure(location: GLint; count: GLsizei; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformMatrix2dv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformMatrix3dv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformMatrix4dv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformMatrix2x3dv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformMatrix2x4dv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformMatrix3x2dv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformMatrix3x4dv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformMatrix4x2dv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformMatrix4x3dv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetUniformdv: procedure(_program: GLuint; location: GLint; params: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramUniform1dEXT: procedure(_program: GLuint; location: GLint; x: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramUniform2dEXT: procedure(_program: GLuint; location: GLint; x: GLdouble; y: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramUniform3dEXT: procedure(_program: GLuint; location: GLint; x: GLdouble; y: GLdouble; z: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramUniform4dEXT: procedure(_program: GLuint; location: GLint; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramUniform1dvEXT: procedure(_program: GLuint; location: GLint; count: GLsizei; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramUniform2dvEXT: procedure(_program: GLuint; location: GLint; count: GLsizei; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramUniform3dvEXT: procedure(_program: GLuint; location: GLint; count: GLsizei; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramUniform4dvEXT: procedure(_program: GLuint; location: GLint; count: GLsizei; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramUniformMatrix2dvEXT: procedure(_program: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramUniformMatrix3dvEXT: procedure(_program: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramUniformMatrix4dvEXT: procedure(_program: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramUniformMatrix2x3dvEXT: procedure(_program: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramUniformMatrix2x4dvEXT: procedure(_program: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramUniformMatrix3x2dvEXT: procedure(_program: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramUniformMatrix3x4dvEXT: procedure(_program: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramUniformMatrix4x2dvEXT: procedure(_program: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramUniformMatrix4x3dvEXT: procedure(_program: GLuint; location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_gpu_shader_fp64(): Boolean; + +//**** GL_ARB_shader_subroutine *****// +const + GL_ACTIVE_SUBROUTINES = $8DE5; + GL_ACTIVE_SUBROUTINE_UNIFORMS = $8DE6; + GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS = $8E47; + GL_ACTIVE_SUBROUTINE_MAX_LENGTH = $8E48; + GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH = $8E49; + GL_MAX_SUBROUTINES = $8DE7; + GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS = $8DE8; + GL_NUM_COMPATIBLE_SUBROUTINES = $8E4A; + GL_COMPATIBLE_SUBROUTINES = $8E4B; + +var + glGetSubroutineUniformLocation: function(_program: GLuint; shadertype: GLenum; const name: PGLchar): GLint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetSubroutineIndex: function(_program: GLuint; shadertype: GLenum; const name: PGLchar): GLuint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetActiveSubroutineUniformiv: procedure(_program: GLuint; shadertype: GLenum; index: GLuint; pname: GLenum; values: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetActiveSubroutineUniformName: procedure(_program: GLuint; shadertype: GLenum; index: GLuint; bufsize: GLsizei; length: PGLsizei; name: PGLchar); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetActiveSubroutineName: procedure(_program: GLuint; shadertype: GLenum; index: GLuint; bufsize: GLsizei; length: PGLsizei; name: PGLchar); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformSubroutinesuiv: procedure(shadertype: GLenum; count: GLsizei; const indices: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetUniformSubroutineuiv: procedure(shadertype: GLenum; location: GLint; params: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetProgramStageiv: procedure(_program: GLuint; shadertype: GLenum; pname: GLenum; values: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_shader_subroutine(): Boolean; + +//**** GL_ARB_tessellation_shader *****// +const + GL_PATCHES = $000E; + GL_PATCH_VERTICES = $8E72; + GL_PATCH_DEFAULT_INNER_LEVEL = $8E73; + GL_PATCH_DEFAULT_OUTER_LEVEL = $8E74; + GL_TESS_CONTROL_OUTPUT_VERTICES = $8E75; + GL_TESS_GEN_MODE = $8E76; + GL_TESS_GEN_SPACING = $8E77; + GL_TESS_GEN_VERTEX_ORDER = $8E78; + GL_TESS_GEN_POINT_MODE = $8E79; +// reuse GL_TRIANGLES +// reuse GL_QUADS +const + GL_ISOLINES = $8E7A; +// reuse GL_EQUAL +const + GL_FRACTIONAL_ODD = $8E7B; + GL_FRACTIONAL_EVEN = $8E7C; +// reuse GL_CCW +// reuse GL_CW +const + GL_MAX_PATCH_VERTICES = $8E7D; + GL_MAX_TESS_GEN_LEVEL = $8E7E; + GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS = $8E7F; + GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS = $8E80; + GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS = $8E81; + GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS = $8E82; + GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS = $8E83; + GL_MAX_TESS_PATCH_COMPONENTS = $8E84; + GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS = $8E85; + GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS = $8E86; + GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS = $8E89; + GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS = $8E8A; + GL_MAX_TESS_CONTROL_INPUT_COMPONENTS = $886C; + GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS = $886D; + GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS = $8E1E; + GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS = $8E1F; + GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER = $84F0; + GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER = $84F1; + GL_TESS_EVALUATION_SHADER = $8E87; + GL_TESS_CONTROL_SHADER = $8E88; +var + glPatchParameteri: procedure(pname: GLenum; value: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPatchParameterfv: procedure(pname: GLenum; const values: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_tessellation_shader(): Boolean; + +//**** GL_ARB_transform_feedback2 *****// +const + GL_TRANSFORM_FEEDBACK = $8E22; + GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED = $8E23; + GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE = $8E24; + GL_TRANSFORM_FEEDBACK_BINDING = $8E25; +var + glBindTransformFeedback: procedure(target: GLenum; id: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteTransformFeedbacks: procedure(n: GLsizei; const ids: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGenTransformFeedbacks: procedure(n: GLsizei; ids: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsTransformFeedback: function(id: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPauseTransformFeedback: procedure(); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glResumeTransformFeedback: procedure(); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDrawTransformFeedback: procedure(mode: GLenum; id: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_transform_feedback2(): Boolean; + +//**** GL_ARB_transform_feedback3 *****// +const + GL_MAX_TRANSFORM_FEEDBACK_BUFFERS = $8E70; +var + glDrawTransformFeedbackStream: procedure(mode: GLenum; id: GLuint; stream: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBeginQueryIndexed: procedure(target: GLenum; index: GLuint; id: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEndQueryIndexed: procedure(target: GLenum; index: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetQueryIndexediv: procedure(target: GLenum; index: GLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_ARB_transform_feedback3(): Boolean; + + +//***** GL_version_1_4 *****// +const + GL_BLEND_DST_RGB = $80C8; + GL_BLEND_SRC_RGB = $80C9; + GL_BLEND_DST_ALPHA = $80CA; + GL_BLEND_SRC_ALPHA = $80CB; + GL_POINT_SIZE_MIN = $8126; + GL_POINT_SIZE_MAX = $8127; + GL_POINT_FADE_THRESHOLD_SIZE = $8128; + GL_POINT_DISTANCE_ATTENUATION = $8129; + GL_GENERATE_MIPMAP = $8191; + GL_GENERATE_MIPMAP_HINT = $8192; + GL_DEPTH_COMPONENT16 = $81A5; + GL_DEPTH_COMPONENT24 = $81A6; + GL_DEPTH_COMPONENT32 = $81A7; + GL_MIRRORED_REPEAT = $8370; + GL_FOG_COORDINATE_SOURCE = $8450; + GL_FOG_COORDINATE = $8451; + GL_FRAGMENT_DEPTH = $8452; + GL_CURRENT_FOG_COORDINATE = $8453; + GL_FOG_COORDINATE_ARRAY_TYPE = $8454; + GL_FOG_COORDINATE_ARRAY_STRIDE = $8455; + GL_FOG_COORDINATE_ARRAY_POINTER = $8456; + GL_FOG_COORDINATE_ARRAY = $8457; + GL_COLOR_SUM = $8458; + GL_CURRENT_SECONDARY_COLOR = $8459; + GL_SECONDARY_COLOR_ARRAY_SIZE = $845A; + GL_SECONDARY_COLOR_ARRAY_TYPE = $845B; + GL_SECONDARY_COLOR_ARRAY_STRIDE = $845C; + GL_SECONDARY_COLOR_ARRAY_POINTER = $845D; + GL_SECONDARY_COLOR_ARRAY = $845E; + GL_MAX_TEXTURE_LOD_BIAS = $84FD; + GL_TEXTURE_FILTER_CONTROL = $8500; + GL_TEXTURE_LOD_BIAS = $8501; + GL_INCR_WRAP = $8507; + GL_DECR_WRAP = $8508; + GL_TEXTURE_DEPTH_SIZE = $884A; + GL_DEPTH_TEXTURE_MODE = $884B; + GL_TEXTURE_COMPARE_MODE = $884C; + GL_TEXTURE_COMPARE_FUNC = $884D; + GL_COMPARE_R_TO_TEXTURE = $884E; +var + glBlendFuncSeparate: procedure(sfactorRGB: GLenum; dfactorRGB: GLenum; sfactorAlpha: GLenum; dfactorAlpha: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFogCoordf: procedure(coord: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFogCoordfv: procedure(const coord: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFogCoordd: procedure(coord: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFogCoorddv: procedure(const coord: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFogCoordPointer: procedure(_type: GLenum; stride: GLsizei; const pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiDrawArrays: procedure(mode: GLenum; first: PGLint; count: PGLsizei; primcount: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMultiDrawElements: procedure(mode: GLenum; const count: PGLsizei; _type: GLenum; const indices: PGLvoid; primcount: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPointParameterf: procedure(pname: GLenum; param: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPointParameterfv: procedure(pname: GLenum; const params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPointParameteri: procedure(pname: GLenum; param: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPointParameteriv: procedure(pname: GLenum; const params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3b: procedure(red: GLbyte; green: GLbyte; blue: GLbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3bv: procedure(const v: PGLbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3d: procedure(red: GLdouble; green: GLdouble; blue: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3dv: procedure(const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3f: procedure(red: GLfloat; green: GLfloat; blue: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3fv: procedure(const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3i: procedure(red: GLint; green: GLint; blue: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3iv: procedure(const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3s: procedure(red: GLshort; green: GLshort; blue: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3sv: procedure(const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3ub: procedure(red: GLubyte; green: GLubyte; blue: GLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3ubv: procedure(const v: PGLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3ui: procedure(red: GLuint; green: GLuint; blue: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3uiv: procedure(const v: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3us: procedure(red: GLushort; green: GLushort; blue: GLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColor3usv: procedure(const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glSecondaryColorPointer: procedure(size: GLint; _type: GLenum; stride: GLsizei; const pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2d: procedure(x: GLdouble; y: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2dv: procedure(const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2f: procedure(x: GLfloat; y: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2fv: procedure(const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2i: procedure(x: GLint; y: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2iv: procedure(const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2s: procedure(x: GLshort; y: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos2sv: procedure(const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3d: procedure(x: GLdouble; y: GLdouble; z: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3dv: procedure(const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3f: procedure(x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3fv: procedure(const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3i: procedure(x: GLint; y: GLint; z: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3iv: procedure(const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3s: procedure(x: GLshort; y: GLshort; z: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glWindowPos3sv: procedure(const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_version_1_4: Boolean; + +//***** GL_version_1_5 *****// +const + GL_BUFFER_SIZE = $8764; + GL_BUFFER_USAGE = $8765; + GL_QUERY_COUNTER_BITS = $8864; + GL_CURRENT_QUERY = $8865; + GL_QUERY_RESULT = $8866; + GL_QUERY_RESULT_AVAILABLE = $8867; + GL_ARRAY_BUFFER = $8892; + GL_ELEMENT_ARRAY_BUFFER = $8893; + GL_ARRAY_BUFFER_BINDING = $8894; + GL_ELEMENT_ARRAY_BUFFER_BINDING = $8895; + GL_VERTEX_ARRAY_BUFFER_BINDING = $8896; + GL_NORMAL_ARRAY_BUFFER_BINDING = $8897; + GL_COLOR_ARRAY_BUFFER_BINDING = $8898; + GL_INDEX_ARRAY_BUFFER_BINDING = $8899; + GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING = $889A; + GL_EDGE_FLAG_ARRAY_BUFFER_BINDING = $889B; + GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING = $889C; + GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING = $889D; + GL_WEIGHT_ARRAY_BUFFER_BINDING = $889E; + GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = $889F; + GL_READ_ONLY = $88B8; + GL_WRITE_ONLY = $88B9; + GL_READ_WRITE = $88BA; + GL_BUFFER_ACCESS = $88BB; + GL_BUFFER_MAPPED = $88BC; + GL_BUFFER_MAP_POINTER = $88BD; + GL_STREAM_DRAW = $88E0; + GL_STREAM_READ = $88E1; + GL_STREAM_COPY = $88E2; + GL_STATIC_DRAW = $88E4; + GL_STATIC_READ = $88E5; + GL_STATIC_COPY = $88E6; + GL_DYNAMIC_DRAW = $88E8; + GL_DYNAMIC_READ = $88E9; + GL_DYNAMIC_COPY = $88EA; + GL_SAMPLES_PASSED = $8914; + GL_FOG_COORD_SRC = $8450; + GL_FOG_COORD = $8451; + GL_CURRENT_FOG_COORD = $8453; + GL_FOG_COORD_ARRAY_TYPE = $8454; + GL_FOG_COORD_ARRAY_STRIDE = $8455; + GL_FOG_COORD_ARRAY_POINTER = $8456; + GL_FOG_COORD_ARRAY = $8457; + GL_FOG_COORD_ARRAY_BUFFER_BINDING = $889D; + GL_SRC0_RGB = $8580; + GL_SRC1_RGB = $8581; + GL_SRC2_RGB = $8582; + GL_SRC0_ALPHA = $8588; + GL_SRC1_ALPHA = $8589; + GL_SRC2_ALPHA = $858A; +var + glGenQueries: procedure(n: GLsizei; ids: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteQueries: procedure(n: GLsizei; const ids: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsQuery: function(id: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBeginQuery: procedure(target: GLenum; id: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEndQuery: procedure(target: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetQueryiv: procedure(target: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetQueryObjectiv: procedure(id: GLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetQueryObjectuiv: procedure(id: GLuint; pname: GLenum; params: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBindBuffer: procedure(target: GLenum; buffer: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteBuffers: procedure(n: GLsizei; const buffers: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGenBuffers: procedure(n: GLsizei; buffers: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsBuffer: function(buffer: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBufferData: procedure(target: GLenum; size: GLsizeiptr; const data: PGLvoid; usage: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBufferSubData: procedure(target: GLenum; offset: GLintptr; size: GLsizeiptr; const data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetBufferSubData: procedure(target: GLenum; offset: GLintptr; size: GLsizeiptr; data: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glMapBuffer: function(target: GLenum; access: GLenum): PGLvoid; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUnmapBuffer: function(target: GLenum): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetBufferParameteriv: procedure(target: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetBufferPointerv: procedure(target: GLenum; pname: GLenum; params: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_version_1_5: Boolean; + +//***** GL_version_2_0 *****// +const + GL_BLEND_EQUATION_RGB = $8009; + GL_VERTEX_ATTRIB_ARRAY_ENABLED = $8622; + GL_VERTEX_ATTRIB_ARRAY_SIZE = $8623; + GL_VERTEX_ATTRIB_ARRAY_STRIDE = $8624; + GL_VERTEX_ATTRIB_ARRAY_TYPE = $8625; + GL_CURRENT_VERTEX_ATTRIB = $8626; + GL_VERTEX_PROGRAM_POINT_SIZE = $8642; + GL_VERTEX_PROGRAM_TWO_SIDE = $8643; + GL_VERTEX_ATTRIB_ARRAY_POINTER = $8645; + GL_STENCIL_BACK_FUNC = $8800; + GL_STENCIL_BACK_FAIL = $8801; + GL_STENCIL_BACK_PASS_DEPTH_FAIL = $8802; + GL_STENCIL_BACK_PASS_DEPTH_PASS = $8803; + GL_MAX_DRAW_BUFFERS = $8824; + GL_DRAW_BUFFER0 = $8825; + GL_DRAW_BUFFER1 = $8826; + GL_DRAW_BUFFER2 = $8827; + GL_DRAW_BUFFER3 = $8828; + GL_DRAW_BUFFER4 = $8829; + GL_DRAW_BUFFER5 = $882A; + GL_DRAW_BUFFER6 = $882B; + GL_DRAW_BUFFER7 = $882C; + GL_DRAW_BUFFER8 = $882D; + GL_DRAW_BUFFER9 = $882E; + GL_DRAW_BUFFER10 = $882F; + GL_DRAW_BUFFER11 = $8830; + GL_DRAW_BUFFER12 = $8831; + GL_DRAW_BUFFER13 = $8832; + GL_DRAW_BUFFER14 = $8833; + GL_DRAW_BUFFER15 = $8834; + GL_BLEND_EQUATION_ALPHA = $883D; + GL_POINT_SPRITE = $8861; + GL_COORD_REPLACE = $8862; + GL_MAX_VERTEX_ATTRIBS = $8869; + GL_VERTEX_ATTRIB_ARRAY_NORMALIZED = $886A; + GL_MAX_TEXTURE_COORDS = $8871; + GL_MAX_TEXTURE_IMAGE_UNITS = $8872; + GL_FRAGMENT_SHADER = $8B30; + GL_VERTEX_SHADER = $8B31; + GL_MAX_FRAGMENT_UNIFORM_COMPONENTS = $8B49; + GL_MAX_VERTEX_UNIFORM_COMPONENTS = $8B4A; + GL_MAX_VARYING_FLOATS = $8B4B; + GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS = $8B4C; + GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS = $8B4D; + GL_SHADER_TYPE = $8B4F; + GL_FLOAT_VEC2 = $8B50; + GL_FLOAT_VEC3 = $8B51; + GL_FLOAT_VEC4 = $8B52; + GL_INT_VEC2 = $8B53; + GL_INT_VEC3 = $8B54; + GL_INT_VEC4 = $8B55; + GL_BOOL = $8B56; + GL_BOOL_VEC2 = $8B57; + GL_BOOL_VEC3 = $8B58; + GL_BOOL_VEC4 = $8B59; + GL_FLOAT_MAT2 = $8B5A; + GL_FLOAT_MAT3 = $8B5B; + GL_FLOAT_MAT4 = $8B5C; + GL_SAMPLER_1D = $8B5D; + GL_SAMPLER_2D = $8B5E; + GL_SAMPLER_3D = $8B5F; + GL_SAMPLER_CUBE = $8B60; + GL_SAMPLER_1D_SHADOW = $8B61; + GL_SAMPLER_2D_SHADOW = $8B62; + GL_DELETE_STATUS = $8B80; + GL_COMPILE_STATUS = $8B81; + GL_LINK_STATUS = $8B82; + GL_VALIDATE_STATUS = $8B83; + GL_INFO_LOG_LENGTH = $8B84; + GL_ATTACHED_SHADERS = $8B85; + GL_ACTIVE_UNIFORMS = $8B86; + GL_ACTIVE_UNIFORM_MAX_LENGTH = $8B87; + GL_SHADER_SOURCE_LENGTH = $8B88; + GL_ACTIVE_ATTRIBUTES = $8B89; + GL_ACTIVE_ATTRIBUTE_MAX_LENGTH = $8B8A; + GL_FRAGMENT_SHADER_DERIVATIVE_HINT = $8B8B; + GL_SHADING_LANGUAGE_VERSION = $8B8C; + GL_CURRENT_PROGRAM = $8B8D; + GL_POINT_SPRITE_COORD_ORIGIN = $8CA0; + GL_LOWER_LEFT = $8CA1; + GL_UPPER_LEFT = $8CA2; + GL_STENCIL_BACK_REF = $8CA3; + GL_STENCIL_BACK_VALUE_MASK = $8CA4; + GL_STENCIL_BACK_WRITEMASK = $8CA5; +var + glBlendEquationSeparate: procedure(modeRGB: GLenum; modeAlpha: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDrawBuffers: procedure(n: GLsizei; const bufs: PGLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glStencilOpSeparate: procedure(face: GLenum; sfail: GLenum; dpfail: GLenum; dppass: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glStencilFuncSeparate: procedure(frontfunc: GLenum; backfunc: GLenum; ref: GLint; mask: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glStencilMaskSeparate: procedure(face: GLenum; mask: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glAttachShader: procedure(_program: GLuint; shader: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBindAttribLocation: procedure(_program: GLuint; index: GLuint; const name: PGLchar); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCompileShader: procedure(shader: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCreateProgram: function(): GLuint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glCreateShader: function(_type: GLenum): GLuint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteProgram: procedure(_program: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDeleteShader: procedure(shader: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDetachShader: procedure(_program: GLuint; shader: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDisableVertexAttribArray: procedure(index: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEnableVertexAttribArray: procedure(index: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetActiveAttrib: procedure(_program: GLuint; index: GLuint; bufSize: GLsizei; length: PGLsizei; size: PGLint; _type: PGLenum; name: PGLchar); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetActiveUniform: procedure(_program: GLuint; index: GLuint; bufSize: GLsizei; length: PGLsizei; size: PGLint; _type: PGLenum; name: PGLchar); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetAttachedShaders: procedure(_program: GLuint; maxCount: GLsizei; count: PGLsizei; obj: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetAttribLocation: function(_program: GLuint; const name: PGLchar): GLint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetProgramiv: procedure(_program: GLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetProgramInfoLog: procedure(_program: GLuint; bufSize: GLsizei; length: PGLsizei; infoLog: PGLchar); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetShaderiv: procedure(shader: GLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetShaderInfoLog: procedure(shader: GLuint; bufSize: GLsizei; length: PGLsizei; infoLog: PGLchar); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetShaderSource: procedure(shader: GLuint; bufSize: GLsizei; length: PGLsizei; source: PGLchar); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetUniformLocation: function(_program: GLuint; const name: PGLchar): GLint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetUniformfv: procedure(_program: GLuint; location: GLint; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetUniformiv: procedure(_program: GLuint; location: GLint; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVertexAttribdv: procedure(index: GLuint; pname: GLenum; params: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVertexAttribfv: procedure(index: GLuint; pname: GLenum; params: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVertexAttribiv: procedure(index: GLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVertexAttribPointerv: procedure(index: GLuint; pname: GLenum; pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsProgram: function(_program: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsShader: function(shader: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glLinkProgram: procedure(_program: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glShaderSource: procedure(shader: GLuint; count: GLsizei; const _string: PGLchar; const length: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUseProgram: procedure(_program: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform1f: procedure(location: GLint; v0: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform2f: procedure(location: GLint; v0: GLfloat; v1: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform3f: procedure(location: GLint; v0: GLfloat; v1: GLfloat; v2: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform4f: procedure(location: GLint; v0: GLfloat; v1: GLfloat; v2: GLfloat; v3: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform1i: procedure(location: GLint; v0: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform2i: procedure(location: GLint; v0: GLint; v1: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform3i: procedure(location: GLint; v0: GLint; v1: GLint; v2: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform4i: procedure(location: GLint; v0: GLint; v1: GLint; v2: GLint; v3: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform1fv: procedure(location: GLint; count: GLsizei; const value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform2fv: procedure(location: GLint; count: GLsizei; const value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform3fv: procedure(location: GLint; count: GLsizei; const value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform4fv: procedure(location: GLint; count: GLsizei; const value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform1iv: procedure(location: GLint; count: GLsizei; const value: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform2iv: procedure(location: GLint; count: GLsizei; const value: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform3iv: procedure(location: GLint; count: GLsizei; const value: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform4iv: procedure(location: GLint; count: GLsizei; const value: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformMatrix2fv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformMatrix3fv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformMatrix4fv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glValidateProgram: procedure(_program: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib1d: procedure(index: GLuint; x: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib1dv: procedure(index: GLuint; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib1f: procedure(index: GLuint; x: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib1fv: procedure(index: GLuint; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib1s: procedure(index: GLuint; x: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib1sv: procedure(index: GLuint; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib2d: procedure(index: GLuint; x: GLdouble; y: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib2dv: procedure(index: GLuint; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib2f: procedure(index: GLuint; x: GLfloat; y: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib2fv: procedure(index: GLuint; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib2s: procedure(index: GLuint; x: GLshort; y: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib2sv: procedure(index: GLuint; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib3d: procedure(index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib3dv: procedure(index: GLuint; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib3f: procedure(index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib3fv: procedure(index: GLuint; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib3s: procedure(index: GLuint; x: GLshort; y: GLshort; z: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib3sv: procedure(index: GLuint; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4Nbv: procedure(index: GLuint; const v: PGLbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4Niv: procedure(index: GLuint; const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4Nsv: procedure(index: GLuint; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4Nub: procedure(index: GLuint; x: GLubyte; y: GLubyte; z: GLubyte; w: GLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4Nubv: procedure(index: GLuint; const v: PGLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4Nuiv: procedure(index: GLuint; const v: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4Nusv: procedure(index: GLuint; const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4bv: procedure(index: GLuint; const v: PGLbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4d: procedure(index: GLuint; x: GLdouble; y: GLdouble; z: GLdouble; w: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4dv: procedure(index: GLuint; const v: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4f: procedure(index: GLuint; x: GLfloat; y: GLfloat; z: GLfloat; w: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4fv: procedure(index: GLuint; const v: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4iv: procedure(index: GLuint; const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4s: procedure(index: GLuint; x: GLshort; y: GLshort; z: GLshort; w: GLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4sv: procedure(index: GLuint; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4ubv: procedure(index: GLuint; const v: PGLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4uiv: procedure(index: GLuint; const v: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttrib4usv: procedure(index: GLuint; const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribPointer: procedure(index: GLuint; size: GLint; _type: GLenum; normalized: GLboolean; stride: GLsizei; const pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_version_2_0: Boolean; + +//**** GL_VERSION_2_1 *****// +const + GL_PIXEL_PACK_BUFFER = $88EB; + GL_PIXEL_UNPACK_BUFFER = $88EC; + GL_PIXEL_PACK_BUFFER_BINDING = $88ED; + GL_PIXEL_UNPACK_BUFFER_BINDING = $88EF; + GL_FLOAT_MAT2x3 = $8B65; + GL_FLOAT_MAT2x4 = $8B66; + GL_FLOAT_MAT3x2 = $8B67; + GL_FLOAT_MAT3x4 = $8B68; + GL_FLOAT_MAT4x2 = $8B69; + GL_FLOAT_MAT4x3 = $8B6A; + GL_SRGB = $8C40; + GL_SRGB8 = $8C41; + GL_SRGB_ALPHA = $8C42; + GL_SRGB8_ALPHA8 = $8C43; + GL_COMPRESSED_SRGB = $8C48; + GL_COMPRESSED_SRGB_ALPHA = $8C49; +var + glUniformMatrix2x3fv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformMatrix3x2fv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformMatrix2x4fv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformMatrix4x2fv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformMatrix3x4fv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniformMatrix4x3fv: procedure(location: GLint; count: GLsizei; transpose: GLboolean; const value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_VERSION_2_1(): Boolean; + +//**** GL_VERSION_2_1 DEPRECATED *****// +const + GL_CURRENT_RASTER_SECONDARY_COLOR = $845F; + GL_SLUMINANCE_ALPHA = $8C44; + GL_SLUMINANCE8_ALPHA8 = $8C45; + GL_SLUMINANCE = $8C46; + GL_SLUMINANCE8 = $8C47; + GL_COMPRESSED_SLUMINANCE = $8C4A; + GL_COMPRESSED_SLUMINANCE_ALPHA = $8C4B; + +//**** GL_VERSION_3_0 *****// + +const + GL_COMPARE_REF_TO_TEXTURE = $884E; + GL_CLIP_DISTANCE0 = $3000; + GL_CLIP_DISTANCE1 = $3001; + GL_CLIP_DISTANCE2 = $3002; + GL_CLIP_DISTANCE3 = $3003; + GL_CLIP_DISTANCE4 = $3004; + GL_CLIP_DISTANCE5 = $3005; + GL_CLIP_DISTANCE6 = $3006; + GL_CLIP_DISTANCE7 = $3007; + GL_MAX_CLIP_DISTANCES = $0D32; + GL_MAJOR_VERSION = $821B; + GL_MINOR_VERSION = $821C; + GL_NUM_EXTENSIONS = $821D; + GL_CONTEXT_FLAGS = $821E; + GL_DEPTH_BUFFER = $8223; + GL_STENCIL_BUFFER = $8224; + GL_COMPRESSED_RED = $8225; + GL_COMPRESSED_RG = $8226; + GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT = $0001; + GL_RGBA32F = $8814; + GL_RGB32F = $8815; + GL_RGBA16F = $881A; + GL_RGB16F = $881B; + GL_VERTEX_ATTRIB_ARRAY_INTEGER = $88FD; + GL_MAX_ARRAY_TEXTURE_LAYERS = $88FF; + GL_MIN_PROGRAM_TEXEL_OFFSET = $8904; + GL_MAX_PROGRAM_TEXEL_OFFSET = $8905; + GL_CLAMP_READ_COLOR = $891C; + GL_FIXED_ONLY = $891D; + GL_MAX_VARYING_COMPONENTS = $8B4B; + GL_TEXTURE_1D_ARRAY = $8C18; + GL_PROXY_TEXTURE_1D_ARRAY = $8C19; + GL_TEXTURE_2D_ARRAY = $8C1A; + GL_PROXY_TEXTURE_2D_ARRAY = $8C1B; + GL_TEXTURE_BINDING_1D_ARRAY = $8C1C; + GL_TEXTURE_BINDING_2D_ARRAY = $8C1D; + GL_R11F_G11F_B10F = $8C3A; + GL_UNSIGNED_INT_10F_11F_11F_REV = $8C3B; + GL_RGB9_E5 = $8C3D; + GL_UNSIGNED_INT_5_9_9_9_REV = $8C3E; + GL_TEXTURE_SHARED_SIZE = $8C3F; + GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH = $8C76; + GL_TRANSFORM_FEEDBACK_BUFFER_MODE = $8C7F; + GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS = $8C80; + GL_TRANSFORM_FEEDBACK_VARYINGS = $8C83; + GL_TRANSFORM_FEEDBACK_BUFFER_START = $8C84; + GL_TRANSFORM_FEEDBACK_BUFFER_SIZE = $8C85; + GL_PRIMITIVES_GENERATED = $8C87; + GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN = $8C88; + GL_RASTERIZER_DISCARD = $8C89; + GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS = $8C8A; + GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS = $8C8B; + GL_INTERLEAVED_ATTRIBS = $8C8C; + GL_SEPARATE_ATTRIBS = $8C8D; + GL_TRANSFORM_FEEDBACK_BUFFER = $8C8E; + GL_TRANSFORM_FEEDBACK_BUFFER_BINDING = $8C8F; + GL_RGBA32UI = $8D70; + GL_RGB32UI = $8D71; + GL_RGBA16UI = $8D76; + GL_RGB16UI = $8D77; + GL_RGBA8UI = $8D7C; + GL_RGB8UI = $8D7D; + GL_RGBA32I = $8D82; + GL_RGB32I = $8D83; + GL_RGBA16I = $8D88; + GL_RGB16I = $8D89; + GL_RGBA8I = $8D8E; + GL_RGB8I = $8D8F; + GL_RED_INTEGER = $8D94; + GL_GREEN_INTEGER = $8D95; + GL_BLUE_INTEGER = $8D96; + GL_RGB_INTEGER = $8D98; + GL_RGBA_INTEGER = $8D99; + GL_BGR_INTEGER = $8D9A; + GL_BGRA_INTEGER = $8D9B; + GL_SAMPLER_1D_ARRAY = $8DC0; + GL_SAMPLER_2D_ARRAY = $8DC1; + GL_SAMPLER_1D_ARRAY_SHADOW = $8DC3; + GL_SAMPLER_2D_ARRAY_SHADOW = $8DC4; + GL_SAMPLER_CUBE_SHADOW = $8DC5; + GL_UNSIGNED_INT_VEC2 = $8DC6; + GL_UNSIGNED_INT_VEC3 = $8DC7; + GL_UNSIGNED_INT_VEC4 = $8DC8; + GL_INT_SAMPLER_1D = $8DC9; + GL_INT_SAMPLER_2D = $8DCA; + GL_INT_SAMPLER_3D = $8DCB; + GL_INT_SAMPLER_CUBE = $8DCC; + GL_INT_SAMPLER_1D_ARRAY = $8DCE; + GL_INT_SAMPLER_2D_ARRAY = $8DCF; + GL_UNSIGNED_INT_SAMPLER_1D = $8DD1; + GL_UNSIGNED_INT_SAMPLER_2D = $8DD2; + GL_UNSIGNED_INT_SAMPLER_3D = $8DD3; + GL_UNSIGNED_INT_SAMPLER_CUBE = $8DD4; + GL_UNSIGNED_INT_SAMPLER_1D_ARRAY = $8DD6; + GL_UNSIGNED_INT_SAMPLER_2D_ARRAY = $8DD7; + GL_QUERY_WAIT = $8E13; + GL_QUERY_NO_WAIT = $8E14; + GL_QUERY_BY_REGION_WAIT = $8E15; + GL_QUERY_BY_REGION_NO_WAIT = $8E16; + GL_BUFFER_ACCESS_FLAGS = $911F; + GL_BUFFER_MAP_LENGTH = $9120; + GL_BUFFER_MAP_OFFSET = $9121; + +var + glColorMaski: procedure(index: GLuint; r: GLboolean; g: GLboolean; b: GLboolean; a: GLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetBooleani_v: procedure(target: GLenum; index: GLuint; data: PGLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetIntegeri_v: procedure(target: GLenum; index: GLuint; data: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; (* Also used in GL_ARB_uniform_buffer_object *) + glEnablei: procedure(target: GLenum; index: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDisablei: procedure(target: GLenum; index: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glIsEnabledi: function(target: GLenum; index: GLuint): GLboolean; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBeginTransformFeedback: procedure(primitiveMode: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEndTransformFeedback: procedure(); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBindBufferRange: procedure(target: GLenum; index: GLuint; buffer: GLuint; offset: GLintptr; size: GLsizeiptr); {$ifdef wincall}stdcall{$else}cdecl{$endif}; (* Also used in GL_ARB_uniform_buffer_object *) + glBindBufferBase: procedure(target: GLenum; index: GLuint; buffer: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; (* Also used in GL_ARB_uniform_buffer_object *) + glTransformFeedbackVaryings: procedure(_program: GLuint; count: GLsizei; const varyings: PPGLchar; bufferMode: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetTransformFeedbackVarying: procedure(_program: GLuint; index: GLuint; bufSize: GLsizei; length: PGLsizei; size: PGLsizei; _type: PGLenum; name: PGLchar); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glClampColor: procedure(target: GLenum; clamp: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBeginConditionalRender: procedure(id: GLuint; mode: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glEndConditionalRender: procedure(); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribIPointer: procedure(index: GLuint; size: GLint; _type: GLenum; stride: GLsizei; const _pointer: PGLvoid); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVertexAttribIiv: procedure(index: GLuint; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetVertexAttribIuiv: procedure(index: GLuint; pname: GLenum; params: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribI1i: procedure(index: GLuint; x: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribI2i: procedure(index: GLuint; x: GLint; y: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribI3i: procedure(index: GLuint; x: GLint; y: GLint; z: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribI4i: procedure(index: GLuint; x: GLint; y: GLint; z: GLint; w: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribI1ui: procedure(index: GLuint; x: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribI2ui: procedure(index: GLuint; x: GLuint; y: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribI3ui: procedure(index: GLuint; x: GLuint; y: GLuint; z: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribI4ui: procedure(index: GLuint; x: GLuint; y: GLuint; z: GLuint; w: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribI1iv: procedure(index: GLuint; const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribI2iv: procedure(index: GLuint; const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribI3iv: procedure(index: GLuint; const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribI4iv: procedure(index: GLuint; const v: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribI1uiv: procedure(index: GLuint; const v: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribI2uiv: procedure(index: GLuint; const v: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribI3uiv: procedure(index: GLuint; const v: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribI4uiv: procedure(index: GLuint; const v: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribI4bv: procedure(index: GLuint; const v: PGLbyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribI4sv: procedure(index: GLuint; const v: PGLshort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribI4ubv: procedure(index: GLuint; const v: PGLubyte); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glVertexAttribI4usv: procedure(index: GLuint; const v: PGLushort); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetUniformuiv: procedure(_program: GLuint; location: GLint; params: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glBindFragDataLocation: procedure(_program: GLuint; color: GLuint; const name: PGLchar); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetFragDataLocation: function(_program: GLuint; const name: PGLchar): GLint; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform1ui: procedure(location: GLint; v0: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform2ui: procedure(location: GLint; v0: GLuint; v1: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform3ui: procedure(location: GLint; v0: GLuint; v1: GLuint; v2: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform4ui: procedure(location: GLint; v0: GLuint; v1: GLuint; v2: GLuint; v3: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform1uiv: procedure(location: GLint; count: GLsizei; const value: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform2uiv: procedure(location: GLint; count: GLsizei; const value: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform3uiv: procedure(location: GLint; count: GLsizei; const value: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glUniform4uiv: procedure(location: GLint; count: GLsizei; const value: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexParameterIiv: procedure(target: GLenum; pname: GLenum; const params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexParameterIuiv: procedure(target: GLenum; pname: GLenum; const params: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetTexParameterIiv: procedure(target: GLenum; pname: GLenum; params: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetTexParameterIuiv: procedure(target: GLenum; pname: GLenum; params: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glClearBufferiv: procedure(buffer: GLenum; drawbuffer: GLint; const value: PGLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glClearBufferuiv: procedure(buffer: GLenum; drawbuffer: GLint; const value: PGLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glClearBufferfv: procedure(buffer: GLenum; drawbuffer: GLint; const value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glClearBufferfi: procedure(buffer: GLenum; drawbuffer: GLint; depth: GLfloat; stencil: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetStringi: function(name: GLenum; index: GLuint): PGLubyte; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_VERSION_3_0(): Boolean; + +//**** GL_VERSION_3_0 DEPRECATED *****// +const + GL_CLAMP_VERTEX_COLOR = $891A; + GL_CLAMP_FRAGMENT_COLOR = $891B; + GL_ALPHA_INTEGER = $8D97; + +//**** GL_VERSION_3_1 *****// +const + GL_SAMPLER_2D_RECT = $8B63; + GL_SAMPLER_2D_RECT_SHADOW = $8B64; + GL_SAMPLER_BUFFER = $8DC2; + GL_INT_SAMPLER_2D_RECT = $8DCD; + GL_INT_SAMPLER_BUFFER = $8DD0; + GL_UNSIGNED_INT_SAMPLER_2D_RECT = $8DD5; + GL_UNSIGNED_INT_SAMPLER_BUFFER = $8DD8; + GL_TEXTURE_BUFFER = $8C2A; + GL_MAX_TEXTURE_BUFFER_SIZE = $8C2B; + GL_TEXTURE_BINDING_BUFFER = $8C2C; + GL_TEXTURE_BUFFER_DATA_STORE_BINDING = $8C2D; + GL_TEXTURE_BUFFER_FORMAT = $8C2E; + GL_TEXTURE_RECTANGLE = $84F5; + GL_TEXTURE_BINDING_RECTANGLE = $84F6; + GL_PROXY_TEXTURE_RECTANGLE = $84F7; + GL_MAX_RECTANGLE_TEXTURE_SIZE = $84F8; + GL_RED_SNORM = $8F90; + GL_RG_SNORM = $8F91; + GL_RGB_SNORM = $8F92; + GL_RGBA_SNORM = $8F93; + GL_R8_SNORM = $8F94; + GL_RG8_SNORM = $8F95; + GL_RGB8_SNORM = $8F96; + GL_RGBA8_SNORM = $8F97; + GL_R16_SNORM = $8F98; + GL_RG16_SNORM = $8F99; + GL_RGB16_SNORM = $8F9A; + GL_RGBA16_SNORM = $8F9B; + GL_SIGNED_NORMALIZED = $8F9C; + GL_PRIMITIVE_RESTART = $8F9D; + GL_PRIMITIVE_RESTART_INDEX = $8F9E; + +var + glDrawArraysInstanced: procedure(mode: GLenum; first: GLint; count: GLsizei; primcount: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glDrawElementsInstanced: procedure(mode: GLenum; count: GLsizei; _type: GLenum; const indices: PGLvoid; primcount: GLsizei); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glTexBuffer: procedure(target: GLenum; internalformat: GLenum; buffer: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glPrimitiveRestartIndex: procedure(index: GLuint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_VERSION_3_1(): Boolean; + +//**** GL_VERSION_3_2 *****// +const + GL_CONTEXT_CORE_PROFILE_BIT = $00000001; + GL_CONTEXT_COMPATIBILITY_PROFILE_BIT = $00000002; + GL_LINES_ADJACENCY = $000A; + GL_LINE_STRIP_ADJACENCY = $000B; + GL_TRIANGLES_ADJACENCY = $000C; + GL_TRIANGLE_STRIP_ADJACENCY = $000D; + GL_PROGRAM_POINT_SIZE = $8642; + GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS = $8C29; + GL_FRAMEBUFFER_ATTACHMENT_LAYERED = $8DA7; + GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS = $8DA8; + GL_GEOMETRY_SHADER = $8DD9; + GL_GEOMETRY_VERTICES_OUT = $8916; + GL_GEOMETRY_INPUT_TYPE = $8917; + GL_GEOMETRY_OUTPUT_TYPE = $8918; + GL_MAX_GEOMETRY_UNIFORM_COMPONENTS = $8DDF; + GL_MAX_GEOMETRY_OUTPUT_VERTICES = $8DE0; + GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS = $8DE1; + GL_MAX_VERTEX_OUTPUT_COMPONENTS = $9122; + GL_MAX_GEOMETRY_INPUT_COMPONENTS = $9123; + GL_MAX_GEOMETRY_OUTPUT_COMPONENTS = $9124; + GL_MAX_FRAGMENT_INPUT_COMPONENTS = $9125; + GL_CONTEXT_PROFILE_MASK = $9126; + +var + glGetInteger64i_v: procedure(target: GLenum; index: GLuint; data: PGLint64); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glGetBufferParameteri64v: procedure(target: GLenum; pname: GLenum; params: PGLint64); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glProgramParameteri: procedure(_program: GLuint; pname: GLenum; value: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + glFramebufferTexture: procedure(target: GLenum; attachment: GLenum; texture: GLuint; level: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function Load_GL_VERSION_3_2(): Boolean; + +//**** GL_VERSION_3_3 *****// + +function Load_GL_VERSION_3_3(): Boolean; + +//**** GL_VERSION_4_0 *****// + +function Load_GL_VERSION_4_0(): Boolean; + +implementation +uses + msedynload,msesys{$ifdef mswindows}{$ifdef FPC},dynlibs{$endif}{$endif} + {$ifndef FPC},classes_del{$endif}; + +function getprocaddresses(const lib: tlibhandle; + const procedures: array of funcinfoty): boolean; +var + int1: integer; +begin + result:= true; + for int1:= 0 to high(procedures) do begin + with procedures[int1] do begin + {$ifdef mswindows} + d^:= wglgetprocaddress(pansichar(n)); + {$else} + d^:= getprocaddress(libgl,pansichar(n)); + {$endif} + if (d^ = nil) then begin + result:= false; + end; + end; + end; +end; +(* +function glext_ExtensionSupported(const extension: String; const searchIn: String): Boolean; +var + extensions: PChar; + start: PChar; + where, terminator: PChar; +begin + + if (Pos(' ', extension) <> 0) or (extension = '') then + begin + Result := FALSE; + Exit; + end; + + if searchIn = '' then extensions := PChar(glGetString(GL_EXTENSIONS)) + else extensions := PChar(searchIn); + start := extensions; + while TRUE do + begin + where := StrPos(start, PChar(extension)); + if where = nil then Break; + terminator := Pointer(PtrUInt(where) + Length(extension)); + if (where = start) or (PChar(PtrUInt(where) - 1)^ = ' ') then + begin + if (terminator^ = ' ') or (terminator^ = #0) then + begin + Result := TRUE; + Exit; + end; + end; + start := terminator; + end; + Result := FALSE; + +end; +*) + +function Load_GL_version_1_2: Boolean; +const + funcs: array[0..5] of funcinfoty = + ( + (n: 'glBlendColor'; d: {$ifndef FPC}@{$endif}@glBlendColor), + (n: 'glBlendEquation'; d: {$ifndef FPC}@{$endif}@glBlendEquation), + (n: 'glDrawRangeElements'; d: {$ifndef FPC}@{$endif}@glDrawRangeElements), + (n: 'glTexImage3D'; d: {$ifndef FPC}@{$endif}@glTexImage3D), + (n: 'glTexSubImage3D'; d: {$ifndef FPC}@{$endif}@glTexSubImage3D), + (n: 'glCopyTexSubImage3D'; d: {$ifndef FPC}@{$endif}@glCopyTexSubImage3D) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_imaging: Boolean; +const + funcs: array[0..31] of funcinfoty = + ( + (n: 'glColorTable'; d: {$ifndef FPC}@{$endif}@glColorTable), + (n: 'glColorTableParameterfv'; d: {$ifndef FPC}@{$endif}@glColorTableParameterfv), + (n: 'glColorTableParameteriv'; d: {$ifndef FPC}@{$endif}@glColorTableParameteriv), + (n: 'glCopyColorTable'; d: {$ifndef FPC}@{$endif}@glCopyColorTable), + (n: 'glGetColorTable'; d: {$ifndef FPC}@{$endif}@glGetColorTable), + (n: 'glGetColorTableParameterfv'; d: {$ifndef FPC}@{$endif}@glGetColorTableParameterfv), + (n: 'glGetColorTableParameteriv'; d: {$ifndef FPC}@{$endif}@glGetColorTableParameteriv), + (n: 'glColorSubTable'; d: {$ifndef FPC}@{$endif}@glColorSubTable), + (n: 'glCopyColorSubTable'; d: {$ifndef FPC}@{$endif}@glCopyColorSubTable), + (n: 'glConvolutionFilter1D'; d: {$ifndef FPC}@{$endif}@glConvolutionFilter1D), + (n: 'glConvolutionFilter2D'; d: {$ifndef FPC}@{$endif}@glConvolutionFilter2D), + (n: 'glConvolutionParameterf'; d: {$ifndef FPC}@{$endif}@glConvolutionParameterf), + (n: 'glConvolutionParameterfv'; d: {$ifndef FPC}@{$endif}@glConvolutionParameterfv), + (n: 'glConvolutionParameteri'; d: {$ifndef FPC}@{$endif}@glConvolutionParameteri), + (n: 'glConvolutionParameteriv'; d: {$ifndef FPC}@{$endif}@glConvolutionParameteriv), + (n: 'glCopyConvolutionFilter1D'; d: {$ifndef FPC}@{$endif}@glCopyConvolutionFilter1D), + (n: 'glCopyConvolutionFilter2D'; d: {$ifndef FPC}@{$endif}@glCopyConvolutionFilter2D), + (n: 'glGetConvolutionFilter'; d: {$ifndef FPC}@{$endif}@glGetConvolutionFilter), + (n: 'glGetConvolutionParameterfv'; d: {$ifndef FPC}@{$endif}@glGetConvolutionParameterfv), + (n: 'glGetConvolutionParameteriv'; d: {$ifndef FPC}@{$endif}@glGetConvolutionParameteriv), + (n: 'glGetSeparableFilter'; d: {$ifndef FPC}@{$endif}@glGetSeparableFilter), + (n: 'glSeparableFilter2D'; d: {$ifndef FPC}@{$endif}@glSeparableFilter2D), + (n: 'glGetHistogram'; d: {$ifndef FPC}@{$endif}@glGetHistogram), + (n: 'glGetHistogramParameterfv'; d: {$ifndef FPC}@{$endif}@glGetHistogramParameterfv), + (n: 'glGetHistogramParameteriv'; d: {$ifndef FPC}@{$endif}@glGetHistogramParameteriv), + (n: 'glGetMinmax'; d: {$ifndef FPC}@{$endif}@glGetMinmax), + (n: 'glGetMinmaxParameterfv'; d: {$ifndef FPC}@{$endif}@glGetMinmaxParameterfv), + (n: 'glGetMinmaxParameteriv'; d: {$ifndef FPC}@{$endif}@glGetMinmaxParameteriv), + (n: 'glHistogram'; d: {$ifndef FPC}@{$endif}@glHistogram), + (n: 'glMinmax'; d: {$ifndef FPC}@{$endif}@glMinmax), + (n: 'glResetHistogram'; d: {$ifndef FPC}@{$endif}@glResetHistogram), + (n: 'glResetMinmax'; d: {$ifndef FPC}@{$endif}@glResetMinmax) + ); + +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_version_1_3: Boolean; +const + funcs: array[0..45] of funcinfoty = + ( + (n: 'glActiveTexture'; d: {$ifndef FPC}@{$endif}@glActiveTexture), + (n: 'glClientActiveTexture'; d: {$ifndef FPC}@{$endif}@glClientActiveTexture), + (n: 'glMultiTexCoord1d'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord1d), + (n: 'glMultiTexCoord1dv'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord1dv), + (n: 'glMultiTexCoord1f'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord1f), + (n: 'glMultiTexCoord1fv'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord1fv), + (n: 'glMultiTexCoord1i'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord1i), + (n: 'glMultiTexCoord1iv'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord1iv), + (n: 'glMultiTexCoord1s'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord1s), + (n: 'glMultiTexCoord1sv'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord1sv), + (n: 'glMultiTexCoord2d'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord2d), + (n: 'glMultiTexCoord2dv'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord2dv), + (n: 'glMultiTexCoord2f'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord2f), + (n: 'glMultiTexCoord2fv'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord2fv), + (n: 'glMultiTexCoord2i'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord2i), + (n: 'glMultiTexCoord2iv'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord2iv), + (n: 'glMultiTexCoord2s'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord2s), + (n: 'glMultiTexCoord2sv'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord2sv), + (n: 'glMultiTexCoord3d'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord3d), + (n: 'glMultiTexCoord3dv'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord3dv), + (n: 'glMultiTexCoord3f'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord3f), + (n: 'glMultiTexCoord3fv'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord3fv), + (n: 'glMultiTexCoord3i'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord3i), + (n: 'glMultiTexCoord3iv'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord3iv), + (n: 'glMultiTexCoord3s'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord3s), + (n: 'glMultiTexCoord3sv'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord3sv), + (n: 'glMultiTexCoord4d'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord4d), + (n: 'glMultiTexCoord4dv'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord4dv), + (n: 'glMultiTexCoord4f'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord4f), + (n: 'glMultiTexCoord4fv'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord4fv), + (n: 'glMultiTexCoord4i'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord4i), + (n: 'glMultiTexCoord4iv'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord4iv), + (n: 'glMultiTexCoord4s'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord4s), + (n: 'glMultiTexCoord4sv'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord4sv), + (n: 'glLoadTransposeMatrixf'; d: {$ifndef FPC}@{$endif}@glLoadTransposeMatrixf), + (n: 'glLoadTransposeMatrixd'; d: {$ifndef FPC}@{$endif}@glLoadTransposeMatrixd), + (n: 'glMultTransposeMatrixf'; d: {$ifndef FPC}@{$endif}@glMultTransposeMatrixf), + (n: 'glMultTransposeMatrixd'; d: {$ifndef FPC}@{$endif}@glMultTransposeMatrixd), + (n: 'glSampleCoverage'; d: {$ifndef FPC}@{$endif}@glSampleCoverage), + (n: 'glCompressedTexImage3D'; d: {$ifndef FPC}@{$endif}@glCompressedTexImage3D), + (n: 'glCompressedTexImage2D'; d: {$ifndef FPC}@{$endif}@glCompressedTexImage2D), + (n: 'glCompressedTexImage1D'; d: {$ifndef FPC}@{$endif}@glCompressedTexImage1D), + (n: 'glCompressedTexSubImage3D'; d: {$ifndef FPC}@{$endif}@glCompressedTexSubImage3D), + (n: 'glCompressedTexSubImage2D'; d: {$ifndef FPC}@{$endif}@glCompressedTexSubImage2D), + (n: 'glCompressedTexSubImage1D'; d: {$ifndef FPC}@{$endif}@glCompressedTexSubImage1D), + (n: 'glGetCompressedTexImage'; d: {$ifndef FPC}@{$endif}@glGetCompressedTexImage) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_multitexture: Boolean; +const + funcs: array[0..33] of funcinfoty = + ( + (n: 'glActiveTextureARB'; d: {$ifndef FPC}@{$endif}@glActiveTextureARB), + (n: 'glClientActiveTextureARB'; d: {$ifndef FPC}@{$endif}@glClientActiveTextureARB), + (n: 'glMultiTexCoord1dARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord1dARB), + (n: 'glMultiTexCoord1dvARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord1dvARB), + (n: 'glMultiTexCoord1fARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord1fARB), + (n: 'glMultiTexCoord1fvARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord1fvARB), + (n: 'glMultiTexCoord1iARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord1iARB), + (n: 'glMultiTexCoord1ivARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord1ivARB), + (n: 'glMultiTexCoord1sARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord1sARB), + (n: 'glMultiTexCoord1svARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord1svARB), + (n: 'glMultiTexCoord2dARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord2dARB), + (n: 'glMultiTexCoord2dvARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord2dvARB), + (n: 'glMultiTexCoord2fARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord2fARB), + (n: 'glMultiTexCoord2fvARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord2fvARB), + (n: 'glMultiTexCoord2iARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord2iARB), + (n: 'glMultiTexCoord2ivARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord2ivARB), + (n: 'glMultiTexCoord2sARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord2sARB), + (n: 'glMultiTexCoord2svARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord2svARB), + (n: 'glMultiTexCoord3dARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord3dARB), + (n: 'glMultiTexCoord3dvARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord3dvARB), + (n: 'glMultiTexCoord3fARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord3fARB), + (n: 'glMultiTexCoord3fvARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord3fvARB), + (n: 'glMultiTexCoord3iARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord3iARB), + (n: 'glMultiTexCoord3ivARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord3ivARB), + (n: 'glMultiTexCoord3sARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord3sARB), + (n: 'glMultiTexCoord3svARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord3svARB), + (n: 'glMultiTexCoord4dARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord4dARB), + (n: 'glMultiTexCoord4dvARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord4dvARB), + (n: 'glMultiTexCoord4fARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord4fARB), + (n: 'glMultiTexCoord4fvARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord4fvARB), + (n: 'glMultiTexCoord4iARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord4iARB), + (n: 'glMultiTexCoord4ivARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord4ivARB), + (n: 'glMultiTexCoord4sARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord4sARB), + (n: 'glMultiTexCoord4svARB'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord4svARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_transpose_matrix: Boolean; +const + funcs: array[0..3] of funcinfoty = + ( + (n: 'glLoadTransposeMatrixfARB'; d: {$ifndef FPC}@{$endif}@glLoadTransposeMatrixfARB), + (n: 'glLoadTransposeMatrixdARB'; d: {$ifndef FPC}@{$endif}@glLoadTransposeMatrixdARB), + (n: 'glMultTransposeMatrixfARB'; d: {$ifndef FPC}@{$endif}@glMultTransposeMatrixfARB), + (n: 'glMultTransposeMatrixdARB'; d: {$ifndef FPC}@{$endif}@glMultTransposeMatrixdARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_multisample: Boolean; +const + funcs: array[0..0] of funcinfoty = + ( + (n: 'glSampleCoverageARB'; d: {$ifndef FPC}@{$endif}@glSampleCoverageARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_texture_env_add: Boolean; +begin + result:= true; //no procs +end; + +{$IFDEF msWindows} +function Load_WGL_ARB_extensions_string: Boolean; +const + funcs: array[0..0] of funcinfoty = + ( + (n: 'wglGetExtensionsStringARB'; d: {$ifndef FPC}@{$endif}@wglGetExtensionsStringARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_WGL_ARB_buffer_region: Boolean; +const + funcs: array[0..3] of funcinfoty = + ( + (n: 'wglCreateBufferRegionARB'; d: {$ifndef FPC}@{$endif}@wglCreateBufferRegionARB), + (n: 'wglDeleteBufferRegionARB'; d: {$ifndef FPC}@{$endif}@wglDeleteBufferRegionARB), + (n: 'wglSaveBufferRegionARB'; d: {$ifndef FPC}@{$endif}@wglSaveBufferRegionARB), + (n: 'wglRestoreBufferRegionARB'; d: {$ifndef FPC}@{$endif}@wglRestoreBufferRegionARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; +{$ENDIF} + +function Load_GL_ARB_texture_cube_map: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ARB_depth_texture: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ARB_point_parameters: Boolean; +const + funcs: array[0..1] of funcinfoty = + ( + (n: 'glPointParameterfARB'; d: {$ifndef FPC}@{$endif}@glPointParameterfARB), + (n: 'glPointParameterfvARB'; d: {$ifndef FPC}@{$endif}@glPointParameterfvARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_shadow: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ARB_shadow_ambient: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ARB_texture_border_clamp: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ARB_texture_compression: Boolean; +const + funcs: array[0..6] of funcinfoty = + ( + (n: 'glCompressedTexImage3DARB'; d: {$ifndef FPC}@{$endif}@glCompressedTexImage3DARB), + (n: 'glCompressedTexImage2DARB'; d: {$ifndef FPC}@{$endif}@glCompressedTexImage2DARB), + (n: 'glCompressedTexImage1DARB'; d: {$ifndef FPC}@{$endif}@glCompressedTexImage1DARB), + (n: 'glCompressedTexSubImage3DARB'; d: {$ifndef FPC}@{$endif}@glCompressedTexSubImage3DARB), + (n: 'glCompressedTexSubImage2DARB'; d: {$ifndef FPC}@{$endif}@glCompressedTexSubImage2DARB), + (n: 'glCompressedTexSubImage1DARB'; d: {$ifndef FPC}@{$endif}@glCompressedTexSubImage1DARB), + (n: 'glGetCompressedTexImageARB'; d: {$ifndef FPC}@{$endif}@glGetCompressedTexImageARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_texture_env_combine: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ARB_texture_env_crossbar: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ARB_texture_env_dot3: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ARB_texture_mirrored_repeat: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ARB_vertex_blend: Boolean; +const + funcs: array[0..10] of funcinfoty = + ( + (n: 'glWeightbvARB'; d: {$ifndef FPC}@{$endif}@glWeightbvARB), + (n: 'glWeightsvARB'; d: {$ifndef FPC}@{$endif}@glWeightsvARB), + (n: 'glWeightivARB'; d: {$ifndef FPC}@{$endif}@glWeightivARB), + (n: 'glWeightfvARB'; d: {$ifndef FPC}@{$endif}@glWeightfvARB), + (n: 'glWeightdvARB'; d: {$ifndef FPC}@{$endif}@glWeightdvARB), + (n: 'glWeightvARB'; d: {$ifndef FPC}@{$endif}@glWeightvARB), + (n: 'glWeightubvARB'; d: {$ifndef FPC}@{$endif}@glWeightubvARB), + (n: 'glWeightusvARB'; d: {$ifndef FPC}@{$endif}@glWeightusvARB), + (n: 'glWeightuivARB'; d: {$ifndef FPC}@{$endif}@glWeightuivARB), + (n: 'glWeightPointerARB'; d: {$ifndef FPC}@{$endif}@glWeightPointerARB), + (n: 'glVertexBlendARB'; d: {$ifndef FPC}@{$endif}@glVertexBlendARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_vertex_program: Boolean; +const + funcs: array[0..61] of funcinfoty = + ( + (n: 'glVertexAttrib1sARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1sARB), + (n: 'glVertexAttrib1fARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1fARB), + (n: 'glVertexAttrib1dARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1dARB), + (n: 'glVertexAttrib2sARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2sARB), + (n: 'glVertexAttrib2fARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2fARB), + (n: 'glVertexAttrib2dARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2dARB), + (n: 'glVertexAttrib3sARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3sARB), + (n: 'glVertexAttrib3fARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3fARB), + (n: 'glVertexAttrib3dARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3dARB), + (n: 'glVertexAttrib4sARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4sARB), + (n: 'glVertexAttrib4fARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4fARB), + (n: 'glVertexAttrib4dARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4dARB), + (n: 'glVertexAttrib4NubARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4NubARB), + (n: 'glVertexAttrib1svARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1svARB), + (n: 'glVertexAttrib1fvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1fvARB), + (n: 'glVertexAttrib1dvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1dvARB), + (n: 'glVertexAttrib2svARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2svARB), + (n: 'glVertexAttrib2fvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2fvARB), + (n: 'glVertexAttrib2dvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2dvARB), + (n: 'glVertexAttrib3svARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3svARB), + (n: 'glVertexAttrib3fvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3fvARB), + (n: 'glVertexAttrib3dvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3dvARB), + (n: 'glVertexAttrib4bvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4bvARB), + (n: 'glVertexAttrib4svARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4svARB), + (n: 'glVertexAttrib4ivARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4ivARB), + (n: 'glVertexAttrib4ubvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4ubvARB), + (n: 'glVertexAttrib4usvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4usvARB), + (n: 'glVertexAttrib4uivARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4uivARB), + (n: 'glVertexAttrib4fvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4fvARB), + (n: 'glVertexAttrib4dvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4dvARB), + (n: 'glVertexAttrib4NbvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4NbvARB), + (n: 'glVertexAttrib4NsvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4NsvARB), + (n: 'glVertexAttrib4NivARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4NivARB), + (n: 'glVertexAttrib4NubvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4NubvARB), + (n: 'glVertexAttrib4NusvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4NusvARB), + (n: 'glVertexAttrib4NuivARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4NuivARB), + (n: 'glVertexAttribPointerARB'; d: {$ifndef FPC}@{$endif}@glVertexAttribPointerARB), + (n: 'glEnableVertexAttribArrayARB'; d: {$ifndef FPC}@{$endif}@glEnableVertexAttribArrayARB), + (n: 'glDisableVertexAttribArrayARB'; d: {$ifndef FPC}@{$endif}@glDisableVertexAttribArrayARB), + (n: 'glProgramStringARB'; d: {$ifndef FPC}@{$endif}@glProgramStringARB), + (n: 'glBindProgramARB'; d: {$ifndef FPC}@{$endif}@glBindProgramARB), + (n: 'glDeleteProgramsARB'; d: {$ifndef FPC}@{$endif}@glDeleteProgramsARB), + (n: 'glGenProgramsARB'; d: {$ifndef FPC}@{$endif}@glGenProgramsARB), + (n: 'glProgramEnvParameter4dARB'; d: {$ifndef FPC}@{$endif}@glProgramEnvParameter4dARB), + (n: 'glProgramEnvParameter4dvARB'; d: {$ifndef FPC}@{$endif}@glProgramEnvParameter4dvARB), + (n: 'glProgramEnvParameter4fARB'; d: {$ifndef FPC}@{$endif}@glProgramEnvParameter4fARB), + (n: 'glProgramEnvParameter4fvARB'; d: {$ifndef FPC}@{$endif}@glProgramEnvParameter4fvARB), + (n: 'glProgramLocalParameter4dARB'; d: {$ifndef FPC}@{$endif}@glProgramLocalParameter4dARB), + (n: 'glProgramLocalParameter4dvARB'; d: {$ifndef FPC}@{$endif}@glProgramLocalParameter4dvARB), + (n: 'glProgramLocalParameter4fARB'; d: {$ifndef FPC}@{$endif}@glProgramLocalParameter4fARB), + (n: 'glProgramLocalParameter4fvARB'; d: {$ifndef FPC}@{$endif}@glProgramLocalParameter4fvARB), + (n: 'glGetProgramEnvParameterdvARB'; d: {$ifndef FPC}@{$endif}@glGetProgramEnvParameterdvARB), + (n: 'glGetProgramEnvParameterfvARB'; d: {$ifndef FPC}@{$endif}@glGetProgramEnvParameterfvARB), + (n: 'glGetProgramLocalParameterdvARB'; d: {$ifndef FPC}@{$endif}@glGetProgramLocalParameterdvARB), + (n: 'glGetProgramLocalParameterfvARB'; d: {$ifndef FPC}@{$endif}@glGetProgramLocalParameterfvARB), + (n: 'glGetProgramivARB'; d: {$ifndef FPC}@{$endif}@glGetProgramivARB), + (n: 'glGetProgramStringARB'; d: {$ifndef FPC}@{$endif}@glGetProgramStringARB), + (n: 'glGetVertexAttribdvARB'; d: {$ifndef FPC}@{$endif}@glGetVertexAttribdvARB), + (n: 'glGetVertexAttribfvARB'; d: {$ifndef FPC}@{$endif}@glGetVertexAttribfvARB), + (n: 'glGetVertexAttribivARB'; d: {$ifndef FPC}@{$endif}@glGetVertexAttribivARB), + (n: 'glGetVertexAttribPointervARB'; d: {$ifndef FPC}@{$endif}@glGetVertexAttribPointervARB), + (n: 'glIsProgramARB'; d: {$ifndef FPC}@{$endif}@glIsProgramARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_window_pos: Boolean; +const + funcs: array[0..15] of funcinfoty = + ( + (n: 'glWindowPos2dARB'; d: {$ifndef FPC}@{$endif}@glWindowPos2dARB), + (n: 'glWindowPos2fARB'; d: {$ifndef FPC}@{$endif}@glWindowPos2fARB), + (n: 'glWindowPos2iARB'; d: {$ifndef FPC}@{$endif}@glWindowPos2iARB), + (n: 'glWindowPos2sARB'; d: {$ifndef FPC}@{$endif}@glWindowPos2sARB), + (n: 'glWindowPos2dvARB'; d: {$ifndef FPC}@{$endif}@glWindowPos2dvARB), + (n: 'glWindowPos2fvARB'; d: {$ifndef FPC}@{$endif}@glWindowPos2fvARB), + (n: 'glWindowPos2ivARB'; d: {$ifndef FPC}@{$endif}@glWindowPos2ivARB), + (n: 'glWindowPos2svARB'; d: {$ifndef FPC}@{$endif}@glWindowPos2svARB), + (n: 'glWindowPos3dARB'; d: {$ifndef FPC}@{$endif}@glWindowPos3dARB), + (n: 'glWindowPos3fARB'; d: {$ifndef FPC}@{$endif}@glWindowPos3fARB), + (n: 'glWindowPos3iARB'; d: {$ifndef FPC}@{$endif}@glWindowPos3iARB), + (n: 'glWindowPos3sARB'; d: {$ifndef FPC}@{$endif}@glWindowPos3sARB), + (n: 'glWindowPos3dvARB'; d: {$ifndef FPC}@{$endif}@glWindowPos3dvARB), + (n: 'glWindowPos3fvARB'; d: {$ifndef FPC}@{$endif}@glWindowPos3fvARB), + (n: 'glWindowPos3ivARB'; d: {$ifndef FPC}@{$endif}@glWindowPos3ivARB), + (n: 'glWindowPos3svARB'; d: {$ifndef FPC}@{$endif}@glWindowPos3svARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_422_pixels: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_abgr: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_bgra: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_blend_color: Boolean; +const + funcs: array[0..0] of funcinfoty = + ( + (n: 'glBlendColorEXT'; d: {$ifndef FPC}@{$endif}@glBlendColorEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_blend_func_separate: Boolean; +const + funcs: array[0..0] of funcinfoty = + ( + (n: 'glBlendFuncSeparateEXT'; d: {$ifndef FPC}@{$endif}@glBlendFuncSeparateEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_blend_logic_op: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_blend_minmax: Boolean; +const + funcs: array[0..0] of funcinfoty = + ( + (n: 'glBlendEquationEXT'; d: {$ifndef FPC}@{$endif}@glBlendEquationEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_blend_subtract: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_clip_volume_hint: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_color_subtable: Boolean; +const + funcs: array[0..1] of funcinfoty = + ( + (n: 'glColorSubTableEXT'; d: {$ifndef FPC}@{$endif}@glColorSubTableEXT), + (n: 'glCopyColorSubTableEXT'; d: {$ifndef FPC}@{$endif}@glCopyColorSubTableEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_compiled_vertex_array: Boolean; +const + funcs: array[0..1] of funcinfoty = + ( + (n: 'glLockArraysEXT'; d: {$ifndef FPC}@{$endif}@glLockArraysEXT), + (n: 'glUnlockArraysEXT'; d: {$ifndef FPC}@{$endif}@glUnlockArraysEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_convolution: Boolean; +const + funcs: array[0..12] of funcinfoty = + ( + (n: 'glConvolutionFilter1DEXT'; d: {$ifndef FPC}@{$endif}@glConvolutionFilter1DEXT), + (n: 'glConvolutionFilter2DEXT'; d: {$ifndef FPC}@{$endif}@glConvolutionFilter2DEXT), + (n: 'glCopyConvolutionFilter1DEXT'; d: {$ifndef FPC}@{$endif}@glCopyConvolutionFilter1DEXT), + (n: 'glCopyConvolutionFilter2DEXT'; d: {$ifndef FPC}@{$endif}@glCopyConvolutionFilter2DEXT), + (n: 'glGetConvolutionFilterEXT'; d: {$ifndef FPC}@{$endif}@glGetConvolutionFilterEXT), + (n: 'glSeparableFilter2DEXT'; d: {$ifndef FPC}@{$endif}@glSeparableFilter2DEXT), + (n: 'glGetSeparableFilterEXT'; d: {$ifndef FPC}@{$endif}@glGetSeparableFilterEXT), + (n: 'glConvolutionParameteriEXT'; d: {$ifndef FPC}@{$endif}@glConvolutionParameteriEXT), + (n: 'glConvolutionParameterivEXT'; d: {$ifndef FPC}@{$endif}@glConvolutionParameterivEXT), + (n: 'glConvolutionParameterfEXT'; d: {$ifndef FPC}@{$endif}@glConvolutionParameterfEXT), + (n: 'glConvolutionParameterfvEXT'; d: {$ifndef FPC}@{$endif}@glConvolutionParameterfvEXT), + (n: 'glGetConvolutionParameterivEXT'; d: {$ifndef FPC}@{$endif}@glGetConvolutionParameterivEXT), + (n: 'glGetConvolutionParameterfvEXT'; d: {$ifndef FPC}@{$endif}@glGetConvolutionParameterfvEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_fog_coord: Boolean; +const + funcs: array[0..4] of funcinfoty = + ( + (n: 'glFogCoordfEXT'; d: {$ifndef FPC}@{$endif}@glFogCoordfEXT), + (n: 'glFogCoorddEXT'; d: {$ifndef FPC}@{$endif}@glFogCoorddEXT), + (n: 'glFogCoordfvEXT'; d: {$ifndef FPC}@{$endif}@glFogCoordfvEXT), + (n: 'glFogCoorddvEXT'; d: {$ifndef FPC}@{$endif}@glFogCoorddvEXT), + (n: 'glFogCoordPointerEXT'; d: {$ifndef FPC}@{$endif}@glFogCoordPointerEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_histogram: Boolean; +const + funcs: array[0..9] of funcinfoty = + ( + (n: 'glHistogramEXT'; d: {$ifndef FPC}@{$endif}@glHistogramEXT), + (n: 'glResetHistogramEXT'; d: {$ifndef FPC}@{$endif}@glResetHistogramEXT), + (n: 'glGetHistogramEXT'; d: {$ifndef FPC}@{$endif}@glGetHistogramEXT), + (n: 'glGetHistogramParameterivEXT'; d: {$ifndef FPC}@{$endif}@glGetHistogramParameterivEXT), + (n: 'glGetHistogramParameterfvEXT'; d: {$ifndef FPC}@{$endif}@glGetHistogramParameterfvEXT), + (n: 'glMinmaxEXT'; d: {$ifndef FPC}@{$endif}@glMinmaxEXT), + (n: 'glResetMinmaxEXT'; d: {$ifndef FPC}@{$endif}@glResetMinmaxEXT), + (n: 'glGetMinmaxEXT'; d: {$ifndef FPC}@{$endif}@glGetMinmaxEXT), + (n: 'glGetMinmaxParameterivEXT'; d: {$ifndef FPC}@{$endif}@glGetMinmaxParameterivEXT), + (n: 'glGetMinmaxParameterfvEXT'; d: {$ifndef FPC}@{$endif}@glGetMinmaxParameterfvEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_multi_draw_arrays: Boolean; +const + funcs: array[0..1] of funcinfoty = + ( + (n: 'glMultiDrawArraysEXT'; d: {$ifndef FPC}@{$endif}@glMultiDrawArraysEXT), + (n: 'glMultiDrawElementsEXT'; d: {$ifndef FPC}@{$endif}@glMultiDrawElementsEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_packed_depth_stencil: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_packed_pixels: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_paletted_texture: Boolean; +const + funcs: array[0..4] of funcinfoty = + ( + (n: 'glColorTableEXT'; d: {$ifndef FPC}@{$endif}@glColorTableEXT), + (n: 'glColorSubTableEXT'; d: {$ifndef FPC}@{$endif}@glColorSubTableEXT), + (n: 'glGetColorTableEXT'; d: {$ifndef FPC}@{$endif}@glGetColorTableEXT), + (n: 'glGetColorTableParameterivEXT'; d: {$ifndef FPC}@{$endif}@glGetColorTableParameterivEXT), + (n: 'glGetColorTableParameterfvEXT'; d: {$ifndef FPC}@{$endif}@glGetColorTableParameterfvEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_point_parameters: Boolean; +const + funcs: array[0..1] of funcinfoty = + ( + (n: 'glPointParameterfEXT'; d: {$ifndef FPC}@{$endif}@glPointParameterfEXT), + (n: 'glPointParameterfvEXT'; d: {$ifndef FPC}@{$endif}@glPointParameterfvEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_polygon_offset: Boolean; +const + funcs: array[0..0] of funcinfoty = + ( + (n: 'glPolygonOffsetEXT'; d: {$ifndef FPC}@{$endif}@glPolygonOffsetEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_secondary_color: Boolean; +const + funcs: array[0..16] of funcinfoty = + ( + (n: 'glSecondaryColor3bEXT'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3bEXT), + (n: 'glSecondaryColor3sEXT'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3sEXT), + (n: 'glSecondaryColor3iEXT'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3iEXT), + (n: 'glSecondaryColor3fEXT'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3fEXT), + (n: 'glSecondaryColor3dEXT'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3dEXT), + (n: 'glSecondaryColor3ubEXT'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3ubEXT), + (n: 'glSecondaryColor3usEXT'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3usEXT), + (n: 'glSecondaryColor3uiEXT'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3uiEXT), + (n: 'glSecondaryColor3bvEXT'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3bvEXT), + (n: 'glSecondaryColor3svEXT'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3svEXT), + (n: 'glSecondaryColor3ivEXT'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3ivEXT), + (n: 'glSecondaryColor3fvEXT'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3fvEXT), + (n: 'glSecondaryColor3dvEXT'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3dvEXT), + (n: 'glSecondaryColor3ubvEXT'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3ubvEXT), + (n: 'glSecondaryColor3usvEXT'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3usvEXT), + (n: 'glSecondaryColor3uivEXT'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3uivEXT), + (n: 'glSecondaryColorPointerEXT'; d: {$ifndef FPC}@{$endif}@glSecondaryColorPointerEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_separate_specular_color: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_shadow_funcs: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_shared_texture_palette: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_stencil_two_side: Boolean; +const + funcs: array[0..0] of funcinfoty = + ( + (n: 'glActiveStencilFaceEXT'; d: {$ifndef FPC}@{$endif}@glActiveStencilFaceEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_stencil_wrap: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_subtexture: Boolean; +const + funcs: array[0..2] of funcinfoty = + ( + (n: 'glTexSubImage1DEXT'; d: {$ifndef FPC}@{$endif}@glTexSubImage1DEXT), + (n: 'glTexSubImage2DEXT'; d: {$ifndef FPC}@{$endif}@glTexSubImage2DEXT), + (n: 'glTexSubImage3DEXT'; d: {$ifndef FPC}@{$endif}@glTexSubImage3DEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_texture3D: Boolean; +const + funcs: array[0..0] of funcinfoty = + ( + (n: 'glTexImage3DEXT'; d: {$ifndef FPC}@{$endif}@glTexImage3DEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_texture_compression_s3tc: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_texture_env_add: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_texture_env_combine: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_texture_env_dot3: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_texture_filter_anisotropic: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_texture_lod_bias: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_texture_object: Boolean; +const + funcs: array[0..5] of funcinfoty = + ( + (n: 'glGenTexturesEXT'; d: {$ifndef FPC}@{$endif}@glGenTexturesEXT), + (n: 'glDeleteTexturesEXT'; d: {$ifndef FPC}@{$endif}@glDeleteTexturesEXT), + (n: 'glBindTextureEXT'; d: {$ifndef FPC}@{$endif}@glBindTextureEXT), + (n: 'glPrioritizeTexturesEXT'; d: {$ifndef FPC}@{$endif}@glPrioritizeTexturesEXT), + (n: 'glAreTexturesResidentEXT'; d: {$ifndef FPC}@{$endif}@glAreTexturesResidentEXT), + (n: 'glIsTextureEXT'; d: {$ifndef FPC}@{$endif}@glIsTextureEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_vertex_array: Boolean; +const + funcs: array[0..8] of funcinfoty = + ( + (n: 'glArrayElementEXT'; d: {$ifndef FPC}@{$endif}@glArrayElementEXT), + (n: 'glDrawArraysEXT'; d: {$ifndef FPC}@{$endif}@glDrawArraysEXT), + (n: 'glVertexPointerEXT'; d: {$ifndef FPC}@{$endif}@glVertexPointerEXT), + (n: 'glNormalPointerEXT'; d: {$ifndef FPC}@{$endif}@glNormalPointerEXT), + (n: 'glColorPointerEXT'; d: {$ifndef FPC}@{$endif}@glColorPointerEXT), + (n: 'glIndexPointerEXT'; d: {$ifndef FPC}@{$endif}@glIndexPointerEXT), + (n: 'glTexCoordPointerEXT'; d: {$ifndef FPC}@{$endif}@glTexCoordPointerEXT), + (n: 'glEdgeFlagPointerEXT'; d: {$ifndef FPC}@{$endif}@glEdgeFlagPointerEXT), + (n: 'glGetPointervEXT'; d: {$ifndef FPC}@{$endif}@glGetPointervEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_vertex_shader: Boolean; +const + funcs: array[0..41] of funcinfoty = + ( + (n: 'glBeginVertexShaderEXT'; d: {$ifndef FPC}@{$endif}@glBeginVertexShaderEXT), + (n: 'glEndVertexShaderEXT'; d: {$ifndef FPC}@{$endif}@glEndVertexShaderEXT), + (n: 'glBindVertexShaderEXT'; d: {$ifndef FPC}@{$endif}@glBindVertexShaderEXT), + (n: 'glGenVertexShadersEXT'; d: {$ifndef FPC}@{$endif}@glGenVertexShadersEXT), + (n: 'glDeleteVertexShaderEXT'; d: {$ifndef FPC}@{$endif}@glDeleteVertexShaderEXT), + (n: 'glShaderOp1EXT'; d: {$ifndef FPC}@{$endif}@glShaderOp1EXT), + (n: 'glShaderOp2EXT'; d: {$ifndef FPC}@{$endif}@glShaderOp2EXT), + (n: 'glShaderOp3EXT'; d: {$ifndef FPC}@{$endif}@glShaderOp3EXT), + (n: 'glSwizzleEXT'; d: {$ifndef FPC}@{$endif}@glSwizzleEXT), + (n: 'glWriteMaskEXT'; d: {$ifndef FPC}@{$endif}@glWriteMaskEXT), + (n: 'glInsertComponentEXT'; d: {$ifndef FPC}@{$endif}@glInsertComponentEXT), + (n: 'glExtractComponentEXT'; d: {$ifndef FPC}@{$endif}@glExtractComponentEXT), + (n: 'glGenSymbolsEXT'; d: {$ifndef FPC}@{$endif}@glGenSymbolsEXT), + (n: 'glSetInvariantEXT'; d: {$ifndef FPC}@{$endif}@glSetInvariantEXT), + (n: 'glSetLocalConstantEXT'; d: {$ifndef FPC}@{$endif}@glSetLocalConstantEXT), + (n: 'glVariantbvEXT'; d: {$ifndef FPC}@{$endif}@glVariantbvEXT), + (n: 'glVariantsvEXT'; d: {$ifndef FPC}@{$endif}@glVariantsvEXT), + (n: 'glVariantivEXT'; d: {$ifndef FPC}@{$endif}@glVariantivEXT), + (n: 'glVariantfvEXT'; d: {$ifndef FPC}@{$endif}@glVariantfvEXT), + (n: 'glVariantdvEXT'; d: {$ifndef FPC}@{$endif}@glVariantdvEXT), + (n: 'glVariantubvEXT'; d: {$ifndef FPC}@{$endif}@glVariantubvEXT), + (n: 'glVariantusvEXT'; d: {$ifndef FPC}@{$endif}@glVariantusvEXT), + (n: 'glVariantuivEXT'; d: {$ifndef FPC}@{$endif}@glVariantuivEXT), + (n: 'glVariantPointerEXT'; d: {$ifndef FPC}@{$endif}@glVariantPointerEXT), + (n: 'glEnableVariantClientStateEXT'; d: {$ifndef FPC}@{$endif}@glEnableVariantClientStateEXT), + (n: 'glDisableVariantClientStateEXT'; d: {$ifndef FPC}@{$endif}@glDisableVariantClientStateEXT), + (n: 'glBindLightParameterEXT'; d: {$ifndef FPC}@{$endif}@glBindLightParameterEXT), + (n: 'glBindMaterialParameterEXT'; d: {$ifndef FPC}@{$endif}@glBindMaterialParameterEXT), + (n: 'glBindTexGenParameterEXT'; d: {$ifndef FPC}@{$endif}@glBindTexGenParameterEXT), + (n: 'glBindTextureUnitParameterEXT'; d: {$ifndef FPC}@{$endif}@glBindTextureUnitParameterEXT), + (n: 'glBindParameterEXT'; d: {$ifndef FPC}@{$endif}@glBindParameterEXT), + (n: 'glIsVariantEnabledEXT'; d: {$ifndef FPC}@{$endif}@glIsVariantEnabledEXT), + (n: 'glGetVariantBooleanvEXT'; d: {$ifndef FPC}@{$endif}@glGetVariantBooleanvEXT), + (n: 'glGetVariantIntegervEXT'; d: {$ifndef FPC}@{$endif}@glGetVariantIntegervEXT), + (n: 'glGetVariantFloatvEXT'; d: {$ifndef FPC}@{$endif}@glGetVariantFloatvEXT), + (n: 'glGetVariantPointervEXT'; d: {$ifndef FPC}@{$endif}@glGetVariantPointervEXT), + (n: 'glGetInvariantBooleanvEXT'; d: {$ifndef FPC}@{$endif}@glGetInvariantBooleanvEXT), + (n: 'glGetInvariantIntegervEXT'; d: {$ifndef FPC}@{$endif}@glGetInvariantIntegervEXT), + (n: 'glGetInvariantFloatvEXT'; d: {$ifndef FPC}@{$endif}@glGetInvariantFloatvEXT), + (n: 'glGetLocalConstantBooleanvEXT'; d: {$ifndef FPC}@{$endif}@glGetLocalConstantBooleanvEXT), + (n: 'glGetLocalConstantIntegervEXT'; d: {$ifndef FPC}@{$endif}@glGetLocalConstantIntegervEXT), + (n: 'glGetLocalConstantFloatvEXT'; d: {$ifndef FPC}@{$endif}@glGetLocalConstantFloatvEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_vertex_weighting: Boolean; +const + funcs: array[0..2] of funcinfoty = + ( + (n: 'glVertexWeightfEXT'; d: {$ifndef FPC}@{$endif}@glVertexWeightfEXT), + (n: 'glVertexWeightfvEXT'; d: {$ifndef FPC}@{$endif}@glVertexWeightfvEXT), + (n: 'glVertexWeightPointerEXT'; d: {$ifndef FPC}@{$endif}@glVertexWeightPointerEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_HP_occlusion_test: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_blend_square: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_copy_depth_to_color: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_depth_clamp: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_evaluators: Boolean; +const + funcs: array[0..8] of funcinfoty = + ( + (n: 'glMapControlPointsNV'; d: {$ifndef FPC}@{$endif}@glMapControlPointsNV), + (n: 'glMapParameterivNV'; d: {$ifndef FPC}@{$endif}@glMapParameterivNV), + (n: 'glMapParameterfvNV'; d: {$ifndef FPC}@{$endif}@glMapParameterfvNV), + (n: 'glGetMapControlPointsNV'; d: {$ifndef FPC}@{$endif}@glGetMapControlPointsNV), + (n: 'glGetMapParameterivNV'; d: {$ifndef FPC}@{$endif}@glGetMapParameterivNV), + (n: 'glGetMapParameterfvNV'; d: {$ifndef FPC}@{$endif}@glGetMapParameterfvNV), + (n: 'glGetMapAttribParameterivNV'; d: {$ifndef FPC}@{$endif}@glGetMapAttribParameterivNV), + (n: 'glGetMapAttribParameterfvNV'; d: {$ifndef FPC}@{$endif}@glGetMapAttribParameterfvNV), + (n: 'glEvalMapsNV'; d: {$ifndef FPC}@{$endif}@glEvalMapsNV) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_NV_fence: Boolean; +const + funcs: array[0..6] of funcinfoty = + ( + (n: 'glGenFencesNV'; d: {$ifndef FPC}@{$endif}@glGenFencesNV), + (n: 'glDeleteFencesNV'; d: {$ifndef FPC}@{$endif}@glDeleteFencesNV), + (n: 'glSetFenceNV'; d: {$ifndef FPC}@{$endif}@glSetFenceNV), + (n: 'glTestFenceNV'; d: {$ifndef FPC}@{$endif}@glTestFenceNV), + (n: 'glFinishFenceNV'; d: {$ifndef FPC}@{$endif}@glFinishFenceNV), + (n: 'glIsFenceNV'; d: {$ifndef FPC}@{$endif}@glIsFenceNV), + (n: 'glGetFenceivNV'; d: {$ifndef FPC}@{$endif}@glGetFenceivNV) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_NV_fog_distance: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_light_max_exponent: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_multisample_filter_hint: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_occlusion_query: Boolean; +const + funcs: array[0..6] of funcinfoty = + ( + (n: 'glGenOcclusionQueriesNV'; d: {$ifndef FPC}@{$endif}@glGenOcclusionQueriesNV), + (n: 'glDeleteOcclusionQueriesNV'; d: {$ifndef FPC}@{$endif}@glDeleteOcclusionQueriesNV), + (n: 'glIsOcclusionQueryNV'; d: {$ifndef FPC}@{$endif}@glIsOcclusionQueryNV), + (n: 'glBeginOcclusionQueryNV'; d: {$ifndef FPC}@{$endif}@glBeginOcclusionQueryNV), + (n: 'glEndOcclusionQueryNV'; d: {$ifndef FPC}@{$endif}@glEndOcclusionQueryNV), + (n: 'glGetOcclusionQueryivNV'; d: {$ifndef FPC}@{$endif}@glGetOcclusionQueryivNV), + (n: 'glGetOcclusionQueryuivNV'; d: {$ifndef FPC}@{$endif}@glGetOcclusionQueryuivNV) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_NV_packed_depth_stencil: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_point_sprite: Boolean; +const + funcs: array[0..1] of funcinfoty = + ( + (n: 'glPointParameteriNV'; d: {$ifndef FPC}@{$endif}@glPointParameteriNV), + (n: 'glPointParameterivNV'; d: {$ifndef FPC}@{$endif}@glPointParameterivNV) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_NV_register_combiners: Boolean; +const + funcs: array[0..12] of funcinfoty = + ( + (n: 'glCombinerParameterfvNV'; d: {$ifndef FPC}@{$endif}@glCombinerParameterfvNV), + (n: 'glCombinerParameterivNV'; d: {$ifndef FPC}@{$endif}@glCombinerParameterivNV), + (n: 'glCombinerParameterfNV'; d: {$ifndef FPC}@{$endif}@glCombinerParameterfNV), + (n: 'glCombinerParameteriNV'; d: {$ifndef FPC}@{$endif}@glCombinerParameteriNV), + (n: 'glCombinerInputNV'; d: {$ifndef FPC}@{$endif}@glCombinerInputNV), + (n: 'glCombinerOutputNV'; d: {$ifndef FPC}@{$endif}@glCombinerOutputNV), + (n: 'glFinalCombinerInputNV'; d: {$ifndef FPC}@{$endif}@glFinalCombinerInputNV), + (n: 'glGetCombinerInputParameterfvNV'; d: {$ifndef FPC}@{$endif}@glGetCombinerInputParameterfvNV), + (n: 'glGetCombinerInputParameterivNV'; d: {$ifndef FPC}@{$endif}@glGetCombinerInputParameterivNV), + (n: 'glGetCombinerOutputParameterfvNV'; d: {$ifndef FPC}@{$endif}@glGetCombinerOutputParameterfvNV), + (n: 'glGetCombinerOutputParameterivNV'; d: {$ifndef FPC}@{$endif}@glGetCombinerOutputParameterivNV), + (n: 'glGetFinalCombinerInputParameterfvNV'; d: {$ifndef FPC}@{$endif}@glGetFinalCombinerInputParameterfvNV), + (n: 'glGetFinalCombinerInputParameterivNV'; d: {$ifndef FPC}@{$endif}@glGetFinalCombinerInputParameterivNV) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_NV_register_combiners2: Boolean; +const + funcs: array[0..1] of funcinfoty = + ( + (n: 'glCombinerStageParameterfvNV'; d: {$ifndef FPC}@{$endif}@glCombinerStageParameterfvNV), + (n: 'glGetCombinerStageParameterfvNV'; d: {$ifndef FPC}@{$endif}@glGetCombinerStageParameterfvNV) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_NV_texgen_emboss: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_texgen_reflection: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_texture_compression_vtc: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_texture_env_combine4: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_texture_rectangle: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_texture_shader: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_texture_shader2: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_texture_shader3: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_vertex_array_range: Boolean; +const + funcs: array[0..{$ifdef mswindows}3{$else}1{$endif}] of funcinfoty = + ( + (n: 'glVertexArrayRangeNV'; d: {$ifndef FPC}@{$endif}@glVertexArrayRangeNV), + (n: 'glFlushVertexArrayRangeNV'; d: {$ifndef FPC}@{$endif}@glFlushVertexArrayRangeNV) +{$IFDEF msWindows} + , + (n: 'wglAllocateMemoryNV'; d: {$ifndef FPC}@{$endif}@wglAllocateMemoryNV), + (n: 'wglFreeMemoryNV'; d: {$ifndef FPC}@{$endif}@wglFreeMemoryNV) +{$ENDIF} + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_NV_vertex_array_range2: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_vertex_program: Boolean; +const + funcs: array[0..61] of funcinfoty = + ( + (n: 'glBindProgramNV'; d: {$ifndef FPC}@{$endif}@glBindProgramNV), + (n: 'glDeleteProgramsNV'; d: {$ifndef FPC}@{$endif}@glDeleteProgramsNV), + (n: 'glExecuteProgramNV'; d: {$ifndef FPC}@{$endif}@glExecuteProgramNV), + (n: 'glGenProgramsNV'; d: {$ifndef FPC}@{$endif}@glGenProgramsNV), + (n: 'glAreProgramsResidentNV'; d: {$ifndef FPC}@{$endif}@glAreProgramsResidentNV), + (n: 'glRequestResidentProgramsNV'; d: {$ifndef FPC}@{$endif}@glRequestResidentProgramsNV), + (n: 'glGetProgramParameterfvNV'; d: {$ifndef FPC}@{$endif}@glGetProgramParameterfvNV), + (n: 'glGetProgramParameterdvNV'; d: {$ifndef FPC}@{$endif}@glGetProgramParameterdvNV), + (n: 'glGetProgramivNV'; d: {$ifndef FPC}@{$endif}@glGetProgramivNV), + (n: 'glGetProgramStringNV'; d: {$ifndef FPC}@{$endif}@glGetProgramStringNV), + (n: 'glGetTrackMatrixivNV'; d: {$ifndef FPC}@{$endif}@glGetTrackMatrixivNV), + (n: 'glGetVertexAttribdvNV'; d: {$ifndef FPC}@{$endif}@glGetVertexAttribdvNV), + (n: 'glGetVertexAttribfvNV'; d: {$ifndef FPC}@{$endif}@glGetVertexAttribfvNV), + (n: 'glGetVertexAttribivNV'; d: {$ifndef FPC}@{$endif}@glGetVertexAttribivNV), + (n: 'glGetVertexAttribPointervNV'; d: {$ifndef FPC}@{$endif}@glGetVertexAttribPointervNV), + (n: 'glIsProgramNV'; d: {$ifndef FPC}@{$endif}@glIsProgramNV), + (n: 'glLoadProgramNV'; d: {$ifndef FPC}@{$endif}@glLoadProgramNV), + (n: 'glProgramParameter4fNV'; d: {$ifndef FPC}@{$endif}@glProgramParameter4fNV), + (n: 'glProgramParameter4fvNV'; d: {$ifndef FPC}@{$endif}@glProgramParameter4fvNV), + (n: 'glProgramParameters4dvNV'; d: {$ifndef FPC}@{$endif}@glProgramParameters4dvNV), + (n: 'glProgramParameters4fvNV'; d: {$ifndef FPC}@{$endif}@glProgramParameters4fvNV), + (n: 'glTrackMatrixNV'; d: {$ifndef FPC}@{$endif}@glTrackMatrixNV), + (n: 'glVertexAttribPointerNV'; d: {$ifndef FPC}@{$endif}@glVertexAttribPointerNV), + (n: 'glVertexAttrib1sNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1sNV), + (n: 'glVertexAttrib1fNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1fNV), + (n: 'glVertexAttrib1dNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1dNV), + (n: 'glVertexAttrib2sNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2sNV), + (n: 'glVertexAttrib2fNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2fNV), + (n: 'glVertexAttrib2dNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2dNV), + (n: 'glVertexAttrib3sNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3sNV), + (n: 'glVertexAttrib3fNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3fNV), + (n: 'glVertexAttrib3dNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3dNV), + (n: 'glVertexAttrib4sNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4sNV), + (n: 'glVertexAttrib4fNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4fNV), + (n: 'glVertexAttrib4dNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4dNV), + (n: 'glVertexAttrib4ubNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4ubNV), + (n: 'glVertexAttrib1svNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1svNV), + (n: 'glVertexAttrib1fvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1fvNV), + (n: 'glVertexAttrib1dvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1dvNV), + (n: 'glVertexAttrib2svNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2svNV), + (n: 'glVertexAttrib2fvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2fvNV), + (n: 'glVertexAttrib2dvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2dvNV), + (n: 'glVertexAttrib3svNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3svNV), + (n: 'glVertexAttrib3fvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3fvNV), + (n: 'glVertexAttrib3dvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3dvNV), + (n: 'glVertexAttrib4svNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4svNV), + (n: 'glVertexAttrib4fvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4fvNV), + (n: 'glVertexAttrib4dvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4dvNV), + (n: 'glVertexAttrib4ubvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4ubvNV), + (n: 'glVertexAttribs1svNV'; d: {$ifndef FPC}@{$endif}@glVertexAttribs1svNV), + (n: 'glVertexAttribs1fvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttribs1fvNV), + (n: 'glVertexAttribs1dvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttribs1dvNV), + (n: 'glVertexAttribs2svNV'; d: {$ifndef FPC}@{$endif}@glVertexAttribs2svNV), + (n: 'glVertexAttribs2fvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttribs2fvNV), + (n: 'glVertexAttribs2dvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttribs2dvNV), + (n: 'glVertexAttribs3svNV'; d: {$ifndef FPC}@{$endif}@glVertexAttribs3svNV), + (n: 'glVertexAttribs3fvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttribs3fvNV), + (n: 'glVertexAttribs3dvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttribs3dvNV), + (n: 'glVertexAttribs4svNV'; d: {$ifndef FPC}@{$endif}@glVertexAttribs4svNV), + (n: 'glVertexAttribs4fvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttribs4fvNV), + (n: 'glVertexAttribs4dvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttribs4dvNV), + (n: 'glVertexAttribs4ubvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttribs4ubvNV) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_NV_vertex_program1_1: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ATI_element_array: Boolean; +const + funcs: array[0..2] of funcinfoty = + ( + (n: 'glElementPointerATI'; d: {$ifndef FPC}@{$endif}@glElementPointerATI), + (n: 'glDrawElementArrayATI'; d: {$ifndef FPC}@{$endif}@glDrawElementArrayATI), + (n: 'glDrawRangeElementArrayATI'; d: {$ifndef FPC}@{$endif}@glDrawRangeElementArrayATI) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ATI_envmap_bumpmap: Boolean; +const + funcs: array[0..3] of funcinfoty = + ( + (n: 'glTexBumpParameterivATI'; d: {$ifndef FPC}@{$endif}@glTexBumpParameterivATI), + (n: 'glTexBumpParameterfvATI'; d: {$ifndef FPC}@{$endif}@glTexBumpParameterfvATI), + (n: 'glGetTexBumpParameterivATI'; d: {$ifndef FPC}@{$endif}@glGetTexBumpParameterivATI), + (n: 'glGetTexBumpParameterfvATI'; d: {$ifndef FPC}@{$endif}@glGetTexBumpParameterfvATI) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ATI_fragment_shader: Boolean; +const + funcs: array[0..13] of funcinfoty = + ( + (n: 'glGenFragmentShadersATI'; d: {$ifndef FPC}@{$endif}@glGenFragmentShadersATI), + (n: 'glBindFragmentShaderATI'; d: {$ifndef FPC}@{$endif}@glBindFragmentShaderATI), + (n: 'glDeleteFragmentShaderATI'; d: {$ifndef FPC}@{$endif}@glDeleteFragmentShaderATI), + (n: 'glBeginFragmentShaderATI'; d: {$ifndef FPC}@{$endif}@glBeginFragmentShaderATI), + (n: 'glEndFragmentShaderATI'; d: {$ifndef FPC}@{$endif}@glEndFragmentShaderATI), + (n: 'glPassTexCoordATI'; d: {$ifndef FPC}@{$endif}@glPassTexCoordATI), + (n: 'glSampleMapATI'; d: {$ifndef FPC}@{$endif}@glSampleMapATI), + (n: 'glColorFragmentOp1ATI'; d: {$ifndef FPC}@{$endif}@glColorFragmentOp1ATI), + (n: 'glColorFragmentOp2ATI'; d: {$ifndef FPC}@{$endif}@glColorFragmentOp2ATI), + (n: 'glColorFragmentOp3ATI'; d: {$ifndef FPC}@{$endif}@glColorFragmentOp3ATI), + (n: 'glAlphaFragmentOp1ATI'; d: {$ifndef FPC}@{$endif}@glAlphaFragmentOp1ATI), + (n: 'glAlphaFragmentOp2ATI'; d: {$ifndef FPC}@{$endif}@glAlphaFragmentOp2ATI), + (n: 'glAlphaFragmentOp3ATI'; d: {$ifndef FPC}@{$endif}@glAlphaFragmentOp3ATI), + (n: 'glSetFragmentShaderConstantATI'; d: {$ifndef FPC}@{$endif}@glSetFragmentShaderConstantATI) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ATI_pn_triangles: Boolean; +const + funcs: array[0..1] of funcinfoty = + ( + (n: 'glPNTrianglesiATI'; d: {$ifndef FPC}@{$endif}@glPNTrianglesiATI), + (n: 'glPNTrianglesfATI'; d: {$ifndef FPC}@{$endif}@glPNTrianglesfATI) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ATI_texture_mirror_once: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ATI_vertex_array_object: Boolean; +const + funcs: array[0..11] of funcinfoty = + ( + (n: 'glNewObjectBufferATI'; d: {$ifndef FPC}@{$endif}@glNewObjectBufferATI), + (n: 'glIsObjectBufferATI'; d: {$ifndef FPC}@{$endif}@glIsObjectBufferATI), + (n: 'glUpdateObjectBufferATI'; d: {$ifndef FPC}@{$endif}@glUpdateObjectBufferATI), + (n: 'glGetObjectBufferfvATI'; d: {$ifndef FPC}@{$endif}@glGetObjectBufferfvATI), + (n: 'glGetObjectBufferivATI'; d: {$ifndef FPC}@{$endif}@glGetObjectBufferivATI), + (n: 'glDeleteObjectBufferATI'; d: {$ifndef FPC}@{$endif}@glDeleteObjectBufferATI), + (n: 'glArrayObjectATI'; d: {$ifndef FPC}@{$endif}@glArrayObjectATI), + (n: 'glGetArrayObjectfvATI'; d: {$ifndef FPC}@{$endif}@glGetArrayObjectfvATI), + (n: 'glGetArrayObjectivATI'; d: {$ifndef FPC}@{$endif}@glGetArrayObjectivATI), + (n: 'glVariantArrayObjectATI'; d: {$ifndef FPC}@{$endif}@glVariantArrayObjectATI), + (n: 'glGetVariantArrayObjectfvATI'; d: {$ifndef FPC}@{$endif}@glGetVariantArrayObjectfvATI), + (n: 'glGetVariantArrayObjectivATI'; d: {$ifndef FPC}@{$endif}@glGetVariantArrayObjectivATI) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ATI_vertex_streams: Boolean; +const + funcs: array[0..44] of funcinfoty = + ( + (n: 'glVertexStream1s'; d: {$ifndef FPC}@{$endif}@glVertexStream1s), + (n: 'glVertexStream1i'; d: {$ifndef FPC}@{$endif}@glVertexStream1i), + (n: 'glVertexStream1f'; d: {$ifndef FPC}@{$endif}@glVertexStream1f), + (n: 'glVertexStream1d'; d: {$ifndef FPC}@{$endif}@glVertexStream1d), + (n: 'glVertexStream1sv'; d: {$ifndef FPC}@{$endif}@glVertexStream1sv), + (n: 'glVertexStream1iv'; d: {$ifndef FPC}@{$endif}@glVertexStream1iv), + (n: 'glVertexStream1fv'; d: {$ifndef FPC}@{$endif}@glVertexStream1fv), + (n: 'glVertexStream1dv'; d: {$ifndef FPC}@{$endif}@glVertexStream1dv), + (n: 'glVertexStream2s'; d: {$ifndef FPC}@{$endif}@glVertexStream2s), + (n: 'glVertexStream2i'; d: {$ifndef FPC}@{$endif}@glVertexStream2i), + (n: 'glVertexStream2f'; d: {$ifndef FPC}@{$endif}@glVertexStream2f), + (n: 'glVertexStream2d'; d: {$ifndef FPC}@{$endif}@glVertexStream2d), + (n: 'glVertexStream2sv'; d: {$ifndef FPC}@{$endif}@glVertexStream2sv), + (n: 'glVertexStream2iv'; d: {$ifndef FPC}@{$endif}@glVertexStream2iv), + (n: 'glVertexStream2fv'; d: {$ifndef FPC}@{$endif}@glVertexStream2fv), + (n: 'glVertexStream2dv'; d: {$ifndef FPC}@{$endif}@glVertexStream2dv), + (n: 'glVertexStream3s'; d: {$ifndef FPC}@{$endif}@glVertexStream3s), + (n: 'glVertexStream3i'; d: {$ifndef FPC}@{$endif}@glVertexStream3i), + (n: 'glVertexStream3f'; d: {$ifndef FPC}@{$endif}@glVertexStream3f), + (n: 'glVertexStream3d'; d: {$ifndef FPC}@{$endif}@glVertexStream3d), + (n: 'glVertexStream3sv'; d: {$ifndef FPC}@{$endif}@glVertexStream3sv), + (n: 'glVertexStream3iv'; d: {$ifndef FPC}@{$endif}@glVertexStream3iv), + (n: 'glVertexStream3fv'; d: {$ifndef FPC}@{$endif}@glVertexStream3fv), + (n: 'glVertexStream3dv'; d: {$ifndef FPC}@{$endif}@glVertexStream3dv), + (n: 'glVertexStream4s'; d: {$ifndef FPC}@{$endif}@glVertexStream4s), + (n: 'glVertexStream4i'; d: {$ifndef FPC}@{$endif}@glVertexStream4i), + (n: 'glVertexStream4f'; d: {$ifndef FPC}@{$endif}@glVertexStream4f), + (n: 'glVertexStream4d'; d: {$ifndef FPC}@{$endif}@glVertexStream4d), + (n: 'glVertexStream4sv'; d: {$ifndef FPC}@{$endif}@glVertexStream4sv), + (n: 'glVertexStream4iv'; d: {$ifndef FPC}@{$endif}@glVertexStream4iv), + (n: 'glVertexStream4fv'; d: {$ifndef FPC}@{$endif}@glVertexStream4fv), + (n: 'glVertexStream4dv'; d: {$ifndef FPC}@{$endif}@glVertexStream4dv), + (n: 'glNormalStream3b'; d: {$ifndef FPC}@{$endif}@glNormalStream3b), + (n: 'glNormalStream3s'; d: {$ifndef FPC}@{$endif}@glNormalStream3s), + (n: 'glNormalStream3i'; d: {$ifndef FPC}@{$endif}@glNormalStream3i), + (n: 'glNormalStream3f'; d: {$ifndef FPC}@{$endif}@glNormalStream3f), + (n: 'glNormalStream3d'; d: {$ifndef FPC}@{$endif}@glNormalStream3d), + (n: 'glNormalStream3bv'; d: {$ifndef FPC}@{$endif}@glNormalStream3bv), + (n: 'glNormalStream3sv'; d: {$ifndef FPC}@{$endif}@glNormalStream3sv), + (n: 'glNormalStream3iv'; d: {$ifndef FPC}@{$endif}@glNormalStream3iv), + (n: 'glNormalStream3fv'; d: {$ifndef FPC}@{$endif}@glNormalStream3fv), + (n: 'glNormalStream3dv'; d: {$ifndef FPC}@{$endif}@glNormalStream3dv), + (n: 'glClientActiveVertexStream'; d: {$ifndef FPC}@{$endif}@glClientActiveVertexStream), + (n: 'glVertexBlendEnvi'; d: {$ifndef FPC}@{$endif}@glVertexBlendEnvi), + (n: 'glVertexBlendEnvf'; d: {$ifndef FPC}@{$endif}@glVertexBlendEnvf) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +{$IFDEF msWindows} +function Load_WGL_I3D_image_buffer: Boolean; +const + funcs: array[0..3] of funcinfoty = + ( + (n: 'wglCreateImageBufferI3D'; d: {$ifndef FPC}@{$endif}@wglCreateImageBufferI3D), + (n: 'wglDestroyImageBufferI3D'; d: {$ifndef FPC}@{$endif}@wglDestroyImageBufferI3D), + (n: 'wglAssociateImageBufferEventsI3D'; d: {$ifndef FPC}@{$endif}@wglAssociateImageBufferEventsI3D), + (n: 'wglReleaseImageBufferEventsI3D'; d: {$ifndef FPC}@{$endif}@wglReleaseImageBufferEventsI3D) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_WGL_I3D_swap_frame_lock: Boolean; +const + funcs: array[0..3] of funcinfoty = + ( + (n: 'wglEnableFrameLockI3D'; d: {$ifndef FPC}@{$endif}@wglEnableFrameLockI3D), + (n: 'wglDisableFrameLockI3D'; d: {$ifndef FPC}@{$endif}@wglDisableFrameLockI3D), + (n: 'wglIsEnabledFrameLockI3D'; d: {$ifndef FPC}@{$endif}@wglIsEnabledFrameLockI3D), + (n: 'wglQueryFrameLockMasterI3D'; d: {$ifndef FPC}@{$endif}@wglQueryFrameLockMasterI3D) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_WGL_I3D_swap_frame_usage: Boolean; +const + funcs: array[0..3] of funcinfoty = + ( + (n: 'wglGetFrameUsageI3D'; d: {$ifndef FPC}@{$endif}@wglGetFrameUsageI3D), + (n: 'wglBeginFrameTrackingI3D'; d: {$ifndef FPC}@{$endif}@wglBeginFrameTrackingI3D), + (n: 'wglEndFrameTrackingI3D'; d: {$ifndef FPC}@{$endif}@wglEndFrameTrackingI3D), + (n: 'wglQueryFrameTrackingI3D'; d: {$ifndef FPC}@{$endif}@wglQueryFrameTrackingI3D) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; +{$ENDIF} + +function Load_GL_3DFX_texture_compression_FXT1: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_IBM_cull_vertex: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_IBM_multimode_draw_arrays: Boolean; +const + funcs: array[0..1] of funcinfoty = + ( + (n: 'glMultiModeDrawArraysIBM'; d: {$ifndef FPC}@{$endif}@glMultiModeDrawArraysIBM), + (n: 'glMultiModeDrawElementsIBM'; d: {$ifndef FPC}@{$endif}@glMultiModeDrawElementsIBM) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_IBM_raster_pos_clip: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_IBM_texture_mirrored_repeat: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_IBM_vertex_array_lists: Boolean; +const + funcs: array[0..6] of funcinfoty = + ( + (n: 'glColorPointerListIBM'; d: {$ifndef FPC}@{$endif}@glColorPointerListIBM), + (n: 'glSecondaryColorPointerListIBM'; d: {$ifndef FPC}@{$endif}@glSecondaryColorPointerListIBM), + (n: 'glEdgeFlagPointerListIBM'; d: {$ifndef FPC}@{$endif}@glEdgeFlagPointerListIBM), + (n: 'glFogCoordPointerListIBM'; d: {$ifndef FPC}@{$endif}@glFogCoordPointerListIBM), + (n: 'glNormalPointerListIBM'; d: {$ifndef FPC}@{$endif}@glNormalPointerListIBM), + (n: 'glTexCoordPointerListIBM'; d: {$ifndef FPC}@{$endif}@glTexCoordPointerListIBM), + (n: 'glVertexPointerListIBM'; d: {$ifndef FPC}@{$endif}@glVertexPointerListIBM) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_MESA_resize_buffers: Boolean; +const + funcs: array[0..0] of funcinfoty = + ( + (n: 'glResizeBuffersMESA'; d: {$ifndef FPC}@{$endif}@glResizeBuffersMESA) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_MESA_window_pos: Boolean; +const + funcs: array[0..23] of funcinfoty = + ( + (n: 'glWindowPos2dMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos2dMESA), + (n: 'glWindowPos2fMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos2fMESA), + (n: 'glWindowPos2iMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos2iMESA), + (n: 'glWindowPos2sMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos2sMESA), + (n: 'glWindowPos2ivMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos2ivMESA), + (n: 'glWindowPos2svMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos2svMESA), + (n: 'glWindowPos2fvMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos2fvMESA), + (n: 'glWindowPos2dvMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos2dvMESA), + (n: 'glWindowPos3iMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos3iMESA), + (n: 'glWindowPos3sMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos3sMESA), + (n: 'glWindowPos3fMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos3fMESA), + (n: 'glWindowPos3dMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos3dMESA), + (n: 'glWindowPos3ivMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos3ivMESA), + (n: 'glWindowPos3svMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos3svMESA), + (n: 'glWindowPos3fvMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos3fvMESA), + (n: 'glWindowPos3dvMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos3dvMESA), + (n: 'glWindowPos4iMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos4iMESA), + (n: 'glWindowPos4sMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos4sMESA), + (n: 'glWindowPos4fMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos4fMESA), + (n: 'glWindowPos4dMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos4dMESA), + (n: 'glWindowPos4ivMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos4ivMESA), + (n: 'glWindowPos4svMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos4svMESA), + (n: 'glWindowPos4fvMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos4fvMESA), + (n: 'glWindowPos4dvMESA'; d: {$ifndef FPC}@{$endif}@glWindowPos4dvMESA) + ); +begin + result:= getprocaddresses(libgl,funcs); + +end; + +function Load_GL_OML_interlace: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_OML_resample: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_OML_subsample: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_SGIS_generate_mipmap: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_SGIS_multisample: Boolean; +const + funcs: array[0..1] of funcinfoty = + ( + (n: 'glSampleMaskSGIS'; d: {$ifndef FPC}@{$endif}@glSampleMaskSGIS), + (n: 'glSamplePatternSGIS'; d: {$ifndef FPC}@{$endif}@glSamplePatternSGIS) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_SGIS_pixel_texture: Boolean; +const + funcs: array[0..3] of funcinfoty = + ( + (n: 'glPixelTexGenParameteriSGIS'; d: {$ifndef FPC}@{$endif}@glPixelTexGenParameteriSGIS), + (n: 'glPixelTexGenParameterfSGIS'; d: {$ifndef FPC}@{$endif}@glPixelTexGenParameterfSGIS), + (n: 'glGetPixelTexGenParameterivSGIS'; d: {$ifndef FPC}@{$endif}@glGetPixelTexGenParameterivSGIS), + (n: 'glGetPixelTexGenParameterfvSGIS'; d: {$ifndef FPC}@{$endif}@glGetPixelTexGenParameterfvSGIS) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_SGIS_texture_border_clamp: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_SGIS_texture_color_mask: Boolean; +const + funcs: array[0..0] of funcinfoty = + ( + (n: 'glTextureColorMaskSGIS'; d: {$ifndef FPC}@{$endif}@glTextureColorMaskSGIS) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_SGIS_texture_edge_clamp: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_SGIS_texture_lod: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_SGIS_depth_texture: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_SGIX_fog_offset: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_SGIX_interlace: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_SGIX_shadow_ambient: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_SGI_color_matrix: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_SGI_color_table: Boolean; +const + funcs: array[0..6] of funcinfoty = + ( + (n: 'glColorTableSGI'; d: {$ifndef FPC}@{$endif}@glColorTableSGI), + (n: 'glCopyColorTableSGI'; d: {$ifndef FPC}@{$endif}@glCopyColorTableSGI), + (n: 'glColorTableParameterivSGI'; d: {$ifndef FPC}@{$endif}@glColorTableParameterivSGI), + (n: 'glColorTableParameterfvSGI'; d: {$ifndef FPC}@{$endif}@glColorTableParameterfvSGI), + (n: 'glGetColorTableSGI'; d: {$ifndef FPC}@{$endif}@glGetColorTableSGI), + (n: 'glGetColorTableParameterivSGI'; d: {$ifndef FPC}@{$endif}@glGetColorTableParameterivSGI), + (n: 'glGetColorTableParameterfvSGI'; d: {$ifndef FPC}@{$endif}@glGetColorTableParameterfvSGI) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_SGI_texture_color_table: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_SUN_vertex: Boolean; +const + funcs: array[0..39] of funcinfoty = + ( + (n: 'glColor4ubVertex2fSUN'; d: {$ifndef FPC}@{$endif}@glColor4ubVertex2fSUN), + (n: 'glColor4ubVertex2fvSUN'; d: {$ifndef FPC}@{$endif}@glColor4ubVertex2fvSUN), + (n: 'glColor4ubVertex3fSUN'; d: {$ifndef FPC}@{$endif}@glColor4ubVertex3fSUN), + (n: 'glColor4ubVertex3fvSUN'; d: {$ifndef FPC}@{$endif}@glColor4ubVertex3fvSUN), + (n: 'glColor3fVertex3fSUN'; d: {$ifndef FPC}@{$endif}@glColor3fVertex3fSUN), + (n: 'glColor3fVertex3fvSUN'; d: {$ifndef FPC}@{$endif}@glColor3fVertex3fvSUN), + (n: 'glNormal3fVertex3fSUN'; d: {$ifndef FPC}@{$endif}@glNormal3fVertex3fSUN), + (n: 'glNormal3fVertex3fvSUN'; d: {$ifndef FPC}@{$endif}@glNormal3fVertex3fvSUN), + (n: 'glColor4fNormal3fVertex3fSUN'; d: {$ifndef FPC}@{$endif}@glColor4fNormal3fVertex3fSUN), + (n: 'glColor4fNormal3fVertex3fvSUN'; d: {$ifndef FPC}@{$endif}@glColor4fNormal3fVertex3fvSUN), + (n: 'glTexCoord2fVertex3fSUN'; d: {$ifndef FPC}@{$endif}@glTexCoord2fVertex3fSUN), + (n: 'glTexCoord2fVertex3fvSUN'; d: {$ifndef FPC}@{$endif}@glTexCoord2fVertex3fvSUN), + (n: 'glTexCoord4fVertex4fSUN'; d: {$ifndef FPC}@{$endif}@glTexCoord4fVertex4fSUN), + (n: 'glTexCoord4fVertex4fvSUN'; d: {$ifndef FPC}@{$endif}@glTexCoord4fVertex4fvSUN), + (n: 'glTexCoord2fColor4ubVertex3fSUN'; d: {$ifndef FPC}@{$endif}@glTexCoord2fColor4ubVertex3fSUN), + (n: 'glTexCoord2fColor4ubVertex3fvSUN'; d: {$ifndef FPC}@{$endif}@glTexCoord2fColor4ubVertex3fvSUN), + (n: 'glTexCoord2fColor3fVertex3fSUN'; d: {$ifndef FPC}@{$endif}@glTexCoord2fColor3fVertex3fSUN), + (n: 'glTexCoord2fColor3fVertex3fvSUN'; d: {$ifndef FPC}@{$endif}@glTexCoord2fColor3fVertex3fvSUN), + (n: 'glTexCoord2fNormal3fVertex3fSUN'; d: {$ifndef FPC}@{$endif}@glTexCoord2fNormal3fVertex3fSUN), + (n: 'glTexCoord2fNormal3fVertex3fvSUN'; d: {$ifndef FPC}@{$endif}@glTexCoord2fNormal3fVertex3fvSUN), + (n: 'glTexCoord2fColor4fNormal3fVertex3fSUN'; d: {$ifndef FPC}@{$endif}@glTexCoord2fColor4fNormal3fVertex3fSUN), + (n: 'glTexCoord2fColor4fNormal3fVertex3fvSUN'; d: {$ifndef FPC}@{$endif}@glTexCoord2fColor4fNormal3fVertex3fvSUN), + (n: 'glTexCoord4fColor4fNormal3fVertex4fSUN'; d: {$ifndef FPC}@{$endif}@glTexCoord4fColor4fNormal3fVertex4fSUN), + (n: 'glTexCoord4fColor4fNormal3fVertex4fvSUN'; d: {$ifndef FPC}@{$endif}@glTexCoord4fColor4fNormal3fVertex4fvSUN), + (n: 'glReplacementCodeuiVertex3fSUN'; d: {$ifndef FPC}@{$endif}@glReplacementCodeuiVertex3fSUN), + (n: 'glReplacementCodeuiVertex3fvSUN'; d: {$ifndef FPC}@{$endif}@glReplacementCodeuiVertex3fvSUN), + (n: 'glReplacementCodeuiColor4ubVertex3fSUN'; d: {$ifndef FPC}@{$endif}@glReplacementCodeuiColor4ubVertex3fSUN), + (n: 'glReplacementCodeuiColor4ubVertex3fvSUN'; d: {$ifndef FPC}@{$endif}@glReplacementCodeuiColor4ubVertex3fvSUN), + (n: 'glReplacementCodeuiColor3fVertex3fSUN'; d: {$ifndef FPC}@{$endif}@glReplacementCodeuiColor3fVertex3fSUN), + (n: 'glReplacementCodeuiColor3fVertex3fvSUN'; d: {$ifndef FPC}@{$endif}@glReplacementCodeuiColor3fVertex3fvSUN), + (n: 'glReplacementCodeuiNormal3fVertex3fSUN'; d: {$ifndef FPC}@{$endif}@glReplacementCodeuiNormal3fVertex3fSUN), + (n: 'glReplacementCodeuiNormal3fVertex3fvSUN'; d: {$ifndef FPC}@{$endif}@glReplacementCodeuiNormal3fVertex3fvSUN), + (n: 'glReplacementCodeuiColor4fNormal3fVertex3fSUN'; d: {$ifndef FPC}@{$endif}@glReplacementCodeuiColor4fNormal3fVertex3fSUN), + (n: 'glReplacementCodeuiColor4fNormal3fVertex3fvSUN'; d: {$ifndef FPC}@{$endif}@glReplacementCodeuiColor4fNormal3fVertex3fvSUN), + (n: 'glReplacementCodeuiTexCoord2fVertex3fSUN'; d: {$ifndef FPC}@{$endif}@glReplacementCodeuiTexCoord2fVertex3fSUN), + (n: 'glReplacementCodeuiTexCoord2fVertex3fvSUN'; d: {$ifndef FPC}@{$endif}@glReplacementCodeuiTexCoord2fVertex3fvSUN), + (n: 'glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN'; d: {$ifndef FPC}@{$endif}@glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN), + (n: 'glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN'; d: {$ifndef FPC}@{$endif}@glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN), + (n: 'glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN'; d: {$ifndef FPC}@{$endif}@glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN), + (n: 'glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN'; d: {$ifndef FPC}@{$endif}@glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_fragment_program: Boolean; +const + funcs: array[0..18] of funcinfoty = + ( + (n: 'glProgramStringARB'; d: {$ifndef FPC}@{$endif}@glProgramStringARB), + (n: 'glBindProgramARB'; d: {$ifndef FPC}@{$endif}@glBindProgramARB), + (n: 'glDeleteProgramsARB'; d: {$ifndef FPC}@{$endif}@glDeleteProgramsARB), + (n: 'glGenProgramsARB'; d: {$ifndef FPC}@{$endif}@glGenProgramsARB), + (n: 'glProgramEnvParameter4dARB'; d: {$ifndef FPC}@{$endif}@glProgramEnvParameter4dARB), + (n: 'glProgramEnvParameter4dvARB'; d: {$ifndef FPC}@{$endif}@glProgramEnvParameter4dvARB), + (n: 'glProgramEnvParameter4fARB'; d: {$ifndef FPC}@{$endif}@glProgramEnvParameter4fARB), + (n: 'glProgramEnvParameter4fvARB'; d: {$ifndef FPC}@{$endif}@glProgramEnvParameter4fvARB), + (n: 'glProgramLocalParameter4dARB'; d: {$ifndef FPC}@{$endif}@glProgramLocalParameter4dARB), + (n: 'glProgramLocalParameter4dvARB'; d: {$ifndef FPC}@{$endif}@glProgramLocalParameter4dvARB), + (n: 'glProgramLocalParameter4fARB'; d: {$ifndef FPC}@{$endif}@glProgramLocalParameter4fARB), + (n: 'glProgramLocalParameter4fvARB'; d: {$ifndef FPC}@{$endif}@glProgramLocalParameter4fvARB), + (n: 'glGetProgramEnvParameterdvARB'; d: {$ifndef FPC}@{$endif}@glGetProgramEnvParameterdvARB), + (n: 'glGetProgramEnvParameterfvARB'; d: {$ifndef FPC}@{$endif}@glGetProgramEnvParameterfvARB), + (n: 'glGetProgramLocalParameterdvARB'; d: {$ifndef FPC}@{$endif}@glGetProgramLocalParameterdvARB), + (n: 'glGetProgramLocalParameterfvARB'; d: {$ifndef FPC}@{$endif}@glGetProgramLocalParameterfvARB), + (n: 'glGetProgramivARB'; d: {$ifndef FPC}@{$endif}@glGetProgramivARB), + (n: 'glGetProgramStringARB'; d: {$ifndef FPC}@{$endif}@glGetProgramStringARB), + (n: 'glIsProgramARB'; d: {$ifndef FPC}@{$endif}@glIsProgramARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ATI_text_fragment_shader: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_APPLE_client_storage: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_APPLE_element_array: Boolean; +const + funcs: array[0..4] of funcinfoty = + ( + (n: 'glElementPointerAPPLE'; d: {$ifndef FPC}@{$endif}@glElementPointerAPPLE), + (n: 'glDrawElementArrayAPPLE'; d: {$ifndef FPC}@{$endif}@glDrawElementArrayAPPLE), + (n: 'glDrawRangeElementArrayAPPLE'; d: {$ifndef FPC}@{$endif}@glDrawRangeElementArrayAPPLE), + (n: 'glMultiDrawElementArrayAPPLE'; d: {$ifndef FPC}@{$endif}@glMultiDrawElementArrayAPPLE), + (n: 'glMultiDrawRangeElementArrayAPPLE'; d: {$ifndef FPC}@{$endif}@glMultiDrawRangeElementArrayAPPLE) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_APPLE_fence: Boolean; +const + funcs: array[0..7] of funcinfoty = + ( + (n: 'glGenFencesAPPLE'; d: {$ifndef FPC}@{$endif}@glGenFencesAPPLE), + (n: 'glDeleteFencesAPPLE'; d: {$ifndef FPC}@{$endif}@glDeleteFencesAPPLE), + (n: 'glSetFenceAPPLE'; d: {$ifndef FPC}@{$endif}@glSetFenceAPPLE), + (n: 'glIsFenceAPPLE'; d: {$ifndef FPC}@{$endif}@glIsFenceAPPLE), + (n: 'glTestFenceAPPLE'; d: {$ifndef FPC}@{$endif}@glTestFenceAPPLE), + (n: 'glFinishFenceAPPLE'; d: {$ifndef FPC}@{$endif}@glFinishFenceAPPLE), + (n: 'glTestObjectAPPLE'; d: {$ifndef FPC}@{$endif}@glTestObjectAPPLE), + (n: 'glFinishObjectAPPLE'; d: {$ifndef FPC}@{$endif}@glFinishObjectAPPLE) + ); +begin + result:= getprocaddresses(libgl,funcs); + +end; + +function Load_GL_APPLE_vertex_array_object: Boolean; +const + funcs: array[0..3] of funcinfoty = + ( + (n: 'glBindVertexArrayAPPLE'; d: {$ifndef FPC}@{$endif}@glBindVertexArrayAPPLE), + (n: 'glDeleteVertexArraysAPPLE'; d: {$ifndef FPC}@{$endif}@glDeleteVertexArraysAPPLE), + (n: 'glGenVertexArraysAPPLE'; d: {$ifndef FPC}@{$endif}@glGenVertexArraysAPPLE), + (n: 'glIsVertexArrayAPPLE'; d: {$ifndef FPC}@{$endif}@glIsVertexArrayAPPLE) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_APPLE_vertex_array_range: Boolean; +const + funcs: array[0..2] of funcinfoty = + ( + (n: 'glVertexArrayRangeAPPLE'; d: {$ifndef FPC}@{$endif}@glVertexArrayRangeAPPLE), + (n: 'glFlushVertexArrayRangeAPPLE'; d: {$ifndef FPC}@{$endif}@glFlushVertexArrayRangeAPPLE), + (n: 'glVertexArrayParameteriAPPLE'; d: {$ifndef FPC}@{$endif}@glVertexArrayParameteriAPPLE) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + + +function load_GL_ARB_vertex_buffer_object : boolean; +const + funcs: array[0..10] of funcinfoty = + ( + (n: 'glBindBufferARB'; d: {$ifndef FPC}@{$endif}@glBindBufferARB), + (n: 'glDeleteBuffersARB'; d: {$ifndef FPC}@{$endif}@glDeleteBuffersARB), + (n: 'glGenBuffersARB'; d: {$ifndef FPC}@{$endif}@glGenBuffersARB), + (n: 'glIsBufferARB'; d: {$ifndef FPC}@{$endif}@glIsBufferARB), + (n: 'glBufferDataARB'; d: {$ifndef FPC}@{$endif}@glBufferDataARB), + (n: 'glBufferSubDataARB'; d: {$ifndef FPC}@{$endif}@glBufferSubDataARB), + (n: 'glGetBufferSubDataARB'; d: {$ifndef FPC}@{$endif}@glGetBufferSubDataARB), + (n: 'glMapBufferARB'; d: {$ifndef FPC}@{$endif}@glMapBufferARB), + (n: 'glUnmapBufferARB'; d: {$ifndef FPC}@{$endif}@glUnmapBufferARB), + (n: 'glGetBufferParameterivARB'; d: {$ifndef FPC}@{$endif}@glGetBufferParameterivARB), + (n: 'glGetBufferPointervARB'; d: {$ifndef FPC}@{$endif}@glGetBufferPointervARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +{$IFDEF msWindows} +function Load_WGL_ARB_pixel_format: Boolean; +const + funcs: array[0..2] of funcinfoty = + ( + (n: 'wglGetPixelFormatAttribivARB'; d: {$ifndef FPC}@{$endif}@wglGetPixelFormatAttribivARB), + (n: 'wglGetPixelFormatAttribfvARB'; d: {$ifndef FPC}@{$endif}@wglGetPixelFormatAttribfvARB), + (n: 'wglChoosePixelFormatARB'; d: {$ifndef FPC}@{$endif}@wglChoosePixelFormatARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_WGL_ARB_make_current_read: Boolean; +const + funcs: array[0..1] of funcinfoty = + ( + (n: 'wglMakeContextCurrentARB'; d: {$ifndef FPC}@{$endif}@wglMakeContextCurrentARB), + (n: 'wglGetCurrentReadDCARB'; d: {$ifndef FPC}@{$endif}@wglGetCurrentReadDCARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_WGL_ARB_pbuffer: Boolean; +const + funcs: array[0..4] of funcinfoty = + ( + (n: 'wglCreatePbufferARB'; d: {$ifndef FPC}@{$endif}@wglCreatePbufferARB), + (n: 'wglGetPbufferDCARB'; d: {$ifndef FPC}@{$endif}@wglGetPbufferDCARB), + (n: 'wglReleasePbufferDCARB'; d: {$ifndef FPC}@{$endif}@wglReleasePbufferDCARB), + (n: 'wglDestroyPbufferARB'; d: {$ifndef FPC}@{$endif}@wglDestroyPbufferARB), + (n: 'wglQueryPbufferARB'; d: {$ifndef FPC}@{$endif}@wglQueryPbufferARB) + ); +begin + result:= getprocaddresses(libgl,funcs); + +end; + +function Load_WGL_EXT_swap_control: Boolean; +const + funcs: array[0..1] of funcinfoty = + ( + (n: 'wglSwapIntervalEXT'; d: {$ifndef FPC}@{$endif}@wglSwapIntervalEXT), + (n: 'wglGetSwapIntervalEXT'; d: {$ifndef FPC}@{$endif}@wglGetSwapIntervalEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_WGL_ARB_render_texture: Boolean; +const + funcs: array[0..2] of funcinfoty = + ( + (n: 'wglBindTexImageARB'; d: {$ifndef FPC}@{$endif}@wglBindTexImageARB), + (n: 'wglReleaseTexImageARB'; d: {$ifndef FPC}@{$endif}@wglReleaseTexImageARB), + (n: 'wglSetPbufferAttribARB'; d: {$ifndef FPC}@{$endif}@wglSetPbufferAttribARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_WGL_EXT_extensions_string: Boolean; +const + funcs: array[0..0] of funcinfoty = + ( + (n: 'wglGetExtensionsStringEXT'; d: {$ifndef FPC}@{$endif}@wglGetExtensionsStringEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_WGL_EXT_make_current_read: Boolean; +const + funcs: array[0..1] of funcinfoty = + ( + (n: 'wglMakeContextCurrentEXT'; d: {$ifndef FPC}@{$endif}@wglMakeContextCurrentEXT), + (n: 'wglGetCurrentReadDCEXT'; d: {$ifndef FPC}@{$endif}@wglGetCurrentReadDCEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_WGL_EXT_pbuffer: Boolean; +const + funcs: array[0..4] of funcinfoty = + ( + (n: 'wglCreatePbufferEXT'; d: {$ifndef FPC}@{$endif}@wglCreatePbufferEXT), + (n: 'wglGetPbufferDCEXT'; d: {$ifndef FPC}@{$endif}@wglGetPbufferDCEXT), + (n: 'wglReleasePbufferDCEXT'; d: {$ifndef FPC}@{$endif}@wglReleasePbufferDCEXT), + (n: 'wglDestroyPbufferEXT'; d: {$ifndef FPC}@{$endif}@wglDestroyPbufferEXT), + (n: 'wglQueryPbufferEXT'; d: {$ifndef FPC}@{$endif}@wglQueryPbufferEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_WGL_EXT_pixel_format: Boolean; +const + funcs: array[0..2] of funcinfoty = + ( + (n: 'wglGetPixelFormatAttribivEXT'; d: {$ifndef FPC}@{$endif}@wglGetPixelFormatAttribivEXT), + (n: 'wglGetPixelFormatAttribfvEXT'; d: {$ifndef FPC}@{$endif}@wglGetPixelFormatAttribfvEXT), + (n: 'wglChoosePixelFormatEXT'; d: {$ifndef FPC}@{$endif}@wglChoosePixelFormatEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_WGL_I3D_digital_video_control: Boolean; +const + funcs: array[0..1] of funcinfoty = + ( + (n: 'wglGetDigitalVideoParametersI3D'; d: {$ifndef FPC}@{$endif}@wglGetDigitalVideoParametersI3D), + (n: 'wglSetDigitalVideoParametersI3D'; d: {$ifndef FPC}@{$endif}@wglSetDigitalVideoParametersI3D) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_WGL_I3D_gamma: Boolean; +const + funcs: array[0..3] of funcinfoty = + ( + (n: 'wglGetGammaTableParametersI3D'; d: {$ifndef FPC}@{$endif}@wglGetGammaTableParametersI3D), + (n: 'wglSetGammaTableParametersI3D'; d: {$ifndef FPC}@{$endif}@wglSetGammaTableParametersI3D), + (n: 'wglGetGammaTableI3D'; d: {$ifndef FPC}@{$endif}@wglGetGammaTableI3D), + (n: 'wglSetGammaTableI3D'; d: {$ifndef FPC}@{$endif}@wglSetGammaTableI3D) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_WGL_I3D_genlock: Boolean; +const + funcs: array[0..11] of funcinfoty = + ( + (n: 'wglEnableGenlockI3D'; d: {$ifndef FPC}@{$endif}@wglEnableGenlockI3D), + (n: 'wglDisableGenlockI3D'; d: {$ifndef FPC}@{$endif}@wglDisableGenlockI3D), + (n: 'wglIsEnabledGenlockI3D'; d: {$ifndef FPC}@{$endif}@wglIsEnabledGenlockI3D), + (n: 'wglGenlockSourceI3D'; d: {$ifndef FPC}@{$endif}@wglGenlockSourceI3D), + (n: 'wglGetGenlockSourceI3D'; d: {$ifndef FPC}@{$endif}@wglGetGenlockSourceI3D), + (n: 'wglGenlockSourceEdgeI3D'; d: {$ifndef FPC}@{$endif}@wglGenlockSourceEdgeI3D), + (n: 'wglGetGenlockSourceEdgeI3D'; d: {$ifndef FPC}@{$endif}@wglGetGenlockSourceEdgeI3D), + (n: 'wglGenlockSampleRateI3D'; d: {$ifndef FPC}@{$endif}@wglGenlockSampleRateI3D), + (n: 'wglGetGenlockSampleRateI3D'; d: {$ifndef FPC}@{$endif}@wglGetGenlockSampleRateI3D), + (n: 'wglGenlockSourceDelayI3D'; d: {$ifndef FPC}@{$endif}@wglGenlockSourceDelayI3D), + (n: 'wglGetGenlockSourceDelayI3D'; d: {$ifndef FPC}@{$endif}@wglGetGenlockSourceDelayI3D), + (n: 'wglQueryGenlockMaxSourceDelayI3D'; d: {$ifndef FPC}@{$endif}@wglQueryGenlockMaxSourceDelayI3D) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; +{$ENDIF} + +function Load_GL_ARB_matrix_palette: Boolean; +const + funcs: array[0..4] of funcinfoty = + ( + (n: 'glCurrentPaletteMatrixARB'; d: {$ifndef FPC}@{$endif}@glCurrentPaletteMatrixARB), + (n: 'glMatrixIndexubvARB'; d: {$ifndef FPC}@{$endif}@glMatrixIndexubvARB), + (n: 'glMatrixIndexusvARB'; d: {$ifndef FPC}@{$endif}@glMatrixIndexusvARB), + (n: 'glMatrixIndexuivARB'; d: {$ifndef FPC}@{$endif}@glMatrixIndexuivARB), + (n: 'glMatrixIndexPointerARB'; d: {$ifndef FPC}@{$endif}@glMatrixIndexPointerARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_NV_element_array: Boolean; +const + funcs: array[0..4] of funcinfoty = + ( + (n: 'glElementPointerNV'; d: {$ifndef FPC}@{$endif}@glElementPointerNV), + (n: 'glDrawElementArrayNV'; d: {$ifndef FPC}@{$endif}@glDrawElementArrayNV), + (n: 'glDrawRangeElementArrayNV'; d: {$ifndef FPC}@{$endif}@glDrawRangeElementArrayNV), + (n: 'glMultiDrawElementArrayNV'; d: {$ifndef FPC}@{$endif}@glMultiDrawElementArrayNV), + (n: 'glMultiDrawRangeElementArrayNV'; d: {$ifndef FPC}@{$endif}@glMultiDrawRangeElementArrayNV) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_NV_float_buffer: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_fragment_program: Boolean; +const + funcs: array[0..9] of funcinfoty = + ( + (n: 'glProgramNamedParameter4fNV'; d: {$ifndef FPC}@{$endif}@glProgramNamedParameter4fNV), + (n: 'glProgramNamedParameter4dNV'; d: {$ifndef FPC}@{$endif}@glProgramNamedParameter4dNV), + (n: 'glGetProgramNamedParameterfvNV'; d: {$ifndef FPC}@{$endif}@glGetProgramNamedParameterfvNV), + (n: 'glGetProgramNamedParameterdvNV'; d: {$ifndef FPC}@{$endif}@glGetProgramNamedParameterdvNV), + (n: 'glProgramLocalParameter4dARB'; d: {$ifndef FPC}@{$endif}@glProgramLocalParameter4dARB), + (n: 'glProgramLocalParameter4dvARB'; d: {$ifndef FPC}@{$endif}@glProgramLocalParameter4dvARB), + (n: 'glProgramLocalParameter4fARB'; d: {$ifndef FPC}@{$endif}@glProgramLocalParameter4fARB), + (n: 'glProgramLocalParameter4fvARB'; d: {$ifndef FPC}@{$endif}@glProgramLocalParameter4fvARB), + (n: 'glGetProgramLocalParameterdvARB'; d: {$ifndef FPC}@{$endif}@glGetProgramLocalParameterdvARB), + (n: 'glGetProgramLocalParameterfvARB'; d: {$ifndef FPC}@{$endif}@glGetProgramLocalParameterfvARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_NV_primitive_restart: Boolean; +const + funcs: array[0..1] of funcinfoty = + ( + (n: 'glPrimitiveRestartNV'; d: {$ifndef FPC}@{$endif}@glPrimitiveRestartNV), + (n: 'glPrimitiveRestartIndexNV'; d: {$ifndef FPC}@{$endif}@glPrimitiveRestartIndexNV) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_NV_vertex_program2: Boolean; +begin + result:= true; //no procs +end; + +{$IFDEF msWindows} +function Load_WGL_NV_render_texture_rectangle: Boolean; +begin + result:= true; //no procs +end; +{$ENDIF} + +function Load_GL_NV_pixel_data_range: Boolean; +const + funcs: array[0..{$ifdef mswindows}3{$else}1{$endif}] of funcinfoty = + ( + (n: 'glPixelDataRangeNV'; d: {$ifndef FPC}@{$endif}@glPixelDataRangeNV), + (n: 'glFlushPixelDataRangeNV'; d: {$ifndef FPC}@{$endif}@glFlushPixelDataRangeNV) + {$IFDEF msWindows} + , + (n: 'wglAllocateMemoryNV'; d: {$ifndef FPC}@{$endif}@wglAllocateMemoryNV), + (n: 'wglFreeMemoryNV'; d: {$ifndef FPC}@{$endif}@wglFreeMemoryNV) + {$ENDIF} + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_texture_rectangle: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_S3_s3tc: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ATI_draw_buffers: Boolean; +const + funcs: array[0..0] of funcinfoty = + ( + (n: 'glDrawBuffersATI'; d: {$ifndef FPC}@{$endif}@glDrawBuffersATI) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +{$IFDEF msWindows} +function Load_WGL_ATI_pixel_format_float: Boolean; +begin + result:= true; //no procs +end; +{$ENDIF} + +function Load_GL_ATI_texture_env_combine3: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ATI_texture_float: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_texture_expand_normal: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_half_float: Boolean; +const + funcs: array[0..45] of funcinfoty = + ( + (n: 'glVertex2hNV'; d: {$ifndef FPC}@{$endif}@glVertex2hNV), + (n: 'glVertex2hvNV'; d: {$ifndef FPC}@{$endif}@glVertex2hvNV), + (n: 'glVertex3hNV'; d: {$ifndef FPC}@{$endif}@glVertex3hNV), + (n: 'glVertex3hvNV'; d: {$ifndef FPC}@{$endif}@glVertex3hvNV), + (n: 'glVertex4hNV'; d: {$ifndef FPC}@{$endif}@glVertex4hNV), + (n: 'glVertex4hvNV'; d: {$ifndef FPC}@{$endif}@glVertex4hvNV), + (n: 'glNormal3hNV'; d: {$ifndef FPC}@{$endif}@glNormal3hNV), + (n: 'glNormal3hvNV'; d: {$ifndef FPC}@{$endif}@glNormal3hvNV), + (n: 'glColor3hNV'; d: {$ifndef FPC}@{$endif}@glColor3hNV), + (n: 'glColor3hvNV'; d: {$ifndef FPC}@{$endif}@glColor3hvNV), + (n: 'glColor4hNV'; d: {$ifndef FPC}@{$endif}@glColor4hNV), + (n: 'glColor4hvNV'; d: {$ifndef FPC}@{$endif}@glColor4hvNV), + (n: 'glTexCoord1hNV'; d: {$ifndef FPC}@{$endif}@glTexCoord1hNV), + (n: 'glTexCoord1hvNV'; d: {$ifndef FPC}@{$endif}@glTexCoord1hvNV), + (n: 'glTexCoord2hNV'; d: {$ifndef FPC}@{$endif}@glTexCoord2hNV), + (n: 'glTexCoord2hvNV'; d: {$ifndef FPC}@{$endif}@glTexCoord2hvNV), + (n: 'glTexCoord3hNV'; d: {$ifndef FPC}@{$endif}@glTexCoord3hNV), + (n: 'glTexCoord3hvNV'; d: {$ifndef FPC}@{$endif}@glTexCoord3hvNV), + (n: 'glTexCoord4hNV'; d: {$ifndef FPC}@{$endif}@glTexCoord4hNV), + (n: 'glTexCoord4hvNV'; d: {$ifndef FPC}@{$endif}@glTexCoord4hvNV), + (n: 'glMultiTexCoord1hNV'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord1hNV), + (n: 'glMultiTexCoord1hvNV'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord1hvNV), + (n: 'glMultiTexCoord2hNV'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord2hNV), + (n: 'glMultiTexCoord2hvNV'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord2hvNV), + (n: 'glMultiTexCoord3hNV'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord3hNV), + (n: 'glMultiTexCoord3hvNV'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord3hvNV), + (n: 'glMultiTexCoord4hNV'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord4hNV), + (n: 'glMultiTexCoord4hvNV'; d: {$ifndef FPC}@{$endif}@glMultiTexCoord4hvNV), + (n: 'glFogCoordhNV'; d: {$ifndef FPC}@{$endif}@glFogCoordhNV), + (n: 'glFogCoordhvNV'; d: {$ifndef FPC}@{$endif}@glFogCoordhvNV), + (n: 'glSecondaryColor3hNV'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3hNV), + (n: 'glSecondaryColor3hvNV'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3hvNV), + (n: 'glVertexWeighthNV'; d: {$ifndef FPC}@{$endif}@glVertexWeighthNV), + (n: 'glVertexWeighthvNV'; d: {$ifndef FPC}@{$endif}@glVertexWeighthvNV), + (n: 'glVertexAttrib1hNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1hNV), + (n: 'glVertexAttrib1hvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1hvNV), + (n: 'glVertexAttrib2hNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2hNV), + (n: 'glVertexAttrib2hvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2hvNV), + (n: 'glVertexAttrib3hNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3hNV), + (n: 'glVertexAttrib3hvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3hvNV), + (n: 'glVertexAttrib4hNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4hNV), + (n: 'glVertexAttrib4hvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4hvNV), + (n: 'glVertexAttribs1hvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttribs1hvNV), + (n: 'glVertexAttribs2hvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttribs2hvNV), + (n: 'glVertexAttribs3hvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttribs3hvNV), + (n: 'glVertexAttribs4hvNV'; d: {$ifndef FPC}@{$endif}@glVertexAttribs4hvNV) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ATI_map_object_buffer: Boolean; +const + funcs: array[0..1] of funcinfoty = + ( + (n: 'glMapObjectBufferATI'; d: {$ifndef FPC}@{$endif}@glMapObjectBufferATI), + (n: 'glUnmapObjectBufferATI'; d: {$ifndef FPC}@{$endif}@glUnmapObjectBufferATI) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ATI_separate_stencil: Boolean; +const + funcs: array[0..1] of funcinfoty = + ( + (n: 'glStencilOpSeparateATI'; d: {$ifndef FPC}@{$endif}@glStencilOpSeparateATI), + (n: 'glStencilFuncSeparateATI'; d: {$ifndef FPC}@{$endif}@glStencilFuncSeparateATI) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ATI_vertex_attrib_array_object: Boolean; +const + funcs: array[0..2] of funcinfoty = + ( + (n: 'glVertexAttribArrayObjectATI'; d: {$ifndef FPC}@{$endif}@glVertexAttribArrayObjectATI), + (n: 'glGetVertexAttribArrayObjectfvATI'; d: {$ifndef FPC}@{$endif}@glGetVertexAttribArrayObjectfvATI), + (n: 'glGetVertexAttribArrayObjectivATI'; d: {$ifndef FPC}@{$endif}@glGetVertexAttribArrayObjectivATI) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_occlusion_query: Boolean; +const + funcs: array[0..7] of funcinfoty = + ( + (n: 'glGenQueriesARB'; d: {$ifndef FPC}@{$endif}@glGenQueriesARB), + (n: 'glDeleteQueriesARB'; d: {$ifndef FPC}@{$endif}@glDeleteQueriesARB), + (n: 'glIsQueryARB'; d: {$ifndef FPC}@{$endif}@glIsQueryARB), + (n: 'glBeginQueryARB'; d: {$ifndef FPC}@{$endif}@glBeginQueryARB), + (n: 'glEndQueryARB'; d: {$ifndef FPC}@{$endif}@glEndQueryARB), + (n: 'glGetQueryivARB'; d: {$ifndef FPC}@{$endif}@glGetQueryivARB), + (n: 'glGetQueryObjectivARB'; d: {$ifndef FPC}@{$endif}@glGetQueryObjectivARB), + (n: 'glGetQueryObjectuivARB'; d: {$ifndef FPC}@{$endif}@glGetQueryObjectuivARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_shader_objects: Boolean; +const + funcs: array[0..38] of funcinfoty = + ( + (n: 'glDeleteObjectARB'; d: {$ifndef FPC}@{$endif}@glDeleteObjectARB), + (n: 'glGetHandleARB'; d: {$ifndef FPC}@{$endif}@glGetHandleARB), + (n: 'glDetachObjectARB'; d: {$ifndef FPC}@{$endif}@glDetachObjectARB), + (n: 'glCreateShaderObjectARB'; d: {$ifndef FPC}@{$endif}@glCreateShaderObjectARB), + (n: 'glShaderSourceARB'; d: {$ifndef FPC}@{$endif}@glShaderSourceARB), + (n: 'glCompileShaderARB'; d: {$ifndef FPC}@{$endif}@glCompileShaderARB), + (n: 'glCreateProgramObjectARB'; d: {$ifndef FPC}@{$endif}@glCreateProgramObjectARB), + (n: 'glAttachObjectARB'; d: {$ifndef FPC}@{$endif}@glAttachObjectARB), + (n: 'glLinkProgramARB'; d: {$ifndef FPC}@{$endif}@glLinkProgramARB), + (n: 'glUseProgramObjectARB'; d: {$ifndef FPC}@{$endif}@glUseProgramObjectARB), + (n: 'glValidateProgramARB'; d: {$ifndef FPC}@{$endif}@glValidateProgramARB), + (n: 'glUniform1fARB'; d: {$ifndef FPC}@{$endif}@glUniform1fARB), + (n: 'glUniform2fARB'; d: {$ifndef FPC}@{$endif}@glUniform2fARB), + (n: 'glUniform3fARB'; d: {$ifndef FPC}@{$endif}@glUniform3fARB), + (n: 'glUniform4fARB'; d: {$ifndef FPC}@{$endif}@glUniform4fARB), + (n: 'glUniform1iARB'; d: {$ifndef FPC}@{$endif}@glUniform1iARB), + (n: 'glUniform2iARB'; d: {$ifndef FPC}@{$endif}@glUniform2iARB), + (n: 'glUniform3iARB'; d: {$ifndef FPC}@{$endif}@glUniform3iARB), + (n: 'glUniform4iARB'; d: {$ifndef FPC}@{$endif}@glUniform4iARB), + (n: 'glUniform1fvARB'; d: {$ifndef FPC}@{$endif}@glUniform1fvARB), + (n: 'glUniform2fvARB'; d: {$ifndef FPC}@{$endif}@glUniform2fvARB), + (n: 'glUniform3fvARB'; d: {$ifndef FPC}@{$endif}@glUniform3fvARB), + (n: 'glUniform4fvARB'; d: {$ifndef FPC}@{$endif}@glUniform4fvARB), + (n: 'glUniform1ivARB'; d: {$ifndef FPC}@{$endif}@glUniform1ivARB), + (n: 'glUniform2ivARB'; d: {$ifndef FPC}@{$endif}@glUniform2ivARB), + (n: 'glUniform3ivARB'; d: {$ifndef FPC}@{$endif}@glUniform3ivARB), + (n: 'glUniform4ivARB'; d: {$ifndef FPC}@{$endif}@glUniform4ivARB), + (n: 'glUniformMatrix2fvARB'; d: {$ifndef FPC}@{$endif}@glUniformMatrix2fvARB), + (n: 'glUniformMatrix3fvARB'; d: {$ifndef FPC}@{$endif}@glUniformMatrix3fvARB), + (n: 'glUniformMatrix4fvARB'; d: {$ifndef FPC}@{$endif}@glUniformMatrix4fvARB), + (n: 'glGetObjectParameterfvARB'; d: {$ifndef FPC}@{$endif}@glGetObjectParameterfvARB), + (n: 'glGetObjectParameterivARB'; d: {$ifndef FPC}@{$endif}@glGetObjectParameterivARB), + (n: 'glGetInfoLogARB'; d: {$ifndef FPC}@{$endif}@glGetInfoLogARB), + (n: 'glGetAttachedObjectsARB'; d: {$ifndef FPC}@{$endif}@glGetAttachedObjectsARB), + (n: 'glGetUniformLocationARB'; d: {$ifndef FPC}@{$endif}@glGetUniformLocationARB), + (n: 'glGetActiveUniformARB'; d: {$ifndef FPC}@{$endif}@glGetActiveUniformARB), + (n: 'glGetUniformfvARB'; d: {$ifndef FPC}@{$endif}@glGetUniformfvARB), + (n: 'glGetUniformivARB'; d: {$ifndef FPC}@{$endif}@glGetUniformivARB), + (n: 'glGetShaderSourceARB'; d: {$ifndef FPC}@{$endif}@glGetShaderSourceARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_vertex_shader: Boolean; +const + funcs: array[0..45] of funcinfoty = + ( + (n: 'glVertexAttrib1fARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1fARB), + (n: 'glVertexAttrib1sARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1sARB), + (n: 'glVertexAttrib1dARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1dARB), + (n: 'glVertexAttrib2fARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2fARB), + (n: 'glVertexAttrib2sARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2sARB), + (n: 'glVertexAttrib2dARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2dARB), + (n: 'glVertexAttrib3fARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3fARB), + (n: 'glVertexAttrib3sARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3sARB), + (n: 'glVertexAttrib3dARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3dARB), + (n: 'glVertexAttrib4fARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4fARB), + (n: 'glVertexAttrib4sARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4sARB), + (n: 'glVertexAttrib4dARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4dARB), + (n: 'glVertexAttrib4NubARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4NubARB), + (n: 'glVertexAttrib1fvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1fvARB), + (n: 'glVertexAttrib1svARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1svARB), + (n: 'glVertexAttrib1dvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1dvARB), + (n: 'glVertexAttrib2fvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2fvARB), + (n: 'glVertexAttrib2svARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2svARB), + (n: 'glVertexAttrib2dvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2dvARB), + (n: 'glVertexAttrib3fvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3fvARB), + (n: 'glVertexAttrib3svARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3svARB), + (n: 'glVertexAttrib3dvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3dvARB), + (n: 'glVertexAttrib4fvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4fvARB), + (n: 'glVertexAttrib4svARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4svARB), + (n: 'glVertexAttrib4dvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4dvARB), + (n: 'glVertexAttrib4ivARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4ivARB), + (n: 'glVertexAttrib4bvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4bvARB), + (n: 'glVertexAttrib4ubvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4ubvARB), + (n: 'glVertexAttrib4usvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4usvARB), + (n: 'glVertexAttrib4uivARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4uivARB), + (n: 'glVertexAttrib4NbvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4NbvARB), + (n: 'glVertexAttrib4NsvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4NsvARB), + (n: 'glVertexAttrib4NivARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4NivARB), + (n: 'glVertexAttrib4NubvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4NubvARB), + (n: 'glVertexAttrib4NusvARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4NusvARB), + (n: 'glVertexAttrib4NuivARB'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4NuivARB), + (n: 'glVertexAttribPointerARB'; d: {$ifndef FPC}@{$endif}@glVertexAttribPointerARB), + (n: 'glEnableVertexAttribArrayARB'; d: {$ifndef FPC}@{$endif}@glEnableVertexAttribArrayARB), + (n: 'glDisableVertexAttribArrayARB'; d: {$ifndef FPC}@{$endif}@glDisableVertexAttribArrayARB), + (n: 'glBindAttribLocationARB'; d: {$ifndef FPC}@{$endif}@glBindAttribLocationARB), + (n: 'glGetActiveAttribARB'; d: {$ifndef FPC}@{$endif}@glGetActiveAttribARB), + (n: 'glGetAttribLocationARB'; d: {$ifndef FPC}@{$endif}@glGetAttribLocationARB), + (n: 'glGetVertexAttribdvARB'; d: {$ifndef FPC}@{$endif}@glGetVertexAttribdvARB), + (n: 'glGetVertexAttribfvARB'; d: {$ifndef FPC}@{$endif}@glGetVertexAttribfvARB), + (n: 'glGetVertexAttribivARB'; d: {$ifndef FPC}@{$endif}@glGetVertexAttribivARB), + (n: 'glGetVertexAttribPointervARB'; d: {$ifndef FPC}@{$endif}@glGetVertexAttribPointervARB) + ); + +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_fragment_shader: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ARB_shading_language_100: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ARB_texture_non_power_of_two: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ARB_point_sprite: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_depth_bounds_test: Boolean; +const + funcs: array[0..0] of funcinfoty = + ( + (n: 'glDepthBoundsEXT'; d: {$ifndef FPC}@{$endif}@glDepthBoundsEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_EXT_texture_mirror_clamp: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_blend_equation_separate: Boolean; +const + funcs: array[0..0] of funcinfoty = + ( + (n: 'glBlendEquationSeparateEXT'; d: {$ifndef FPC}@{$endif}@glBlendEquationSeparateEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_MESA_pack_invert: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_MESA_ycbcr_texture: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ARB_fragment_program_shadow: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_fragment_program_option: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_pixel_buffer_object: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_fragment_program2: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_vertex_program2_option: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_NV_vertex_program3: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ARB_draw_buffers: Boolean; +const + funcs: array[0..0] of funcinfoty = + ( + (n: 'glDrawBuffersARB'; d: {$ifndef FPC}@{$endif}@glDrawBuffersARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_texture_rectangle: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ARB_color_buffer_float: Boolean; +const + funcs: array[0..0] of funcinfoty = + ( + (n: 'glClampColorARB'; d: {$ifndef FPC}@{$endif}@glClampColorARB) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_half_float_pixel: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ARB_texture_float: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_texture_compression_dxt1: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_ARB_pixel_buffer_object: Boolean; +begin + result:= true; //no procs +end; + +function Load_GL_EXT_framebuffer_object: Boolean; +const + funcs: array[0..16] of funcinfoty = + ( + (n: 'glIsRenderbufferEXT'; d: {$ifndef FPC}@{$endif}@glIsRenderbufferEXT), + (n: 'glBindRenderbufferEXT'; d: {$ifndef FPC}@{$endif}@glBindRenderbufferEXT), + (n: 'glDeleteRenderbuffersEXT'; d: {$ifndef FPC}@{$endif}@glDeleteRenderbuffersEXT), + (n: 'glGenRenderbuffersEXT'; d: {$ifndef FPC}@{$endif}@glGenRenderbuffersEXT), + (n: 'glRenderbufferStorageEXT'; d: {$ifndef FPC}@{$endif}@glRenderbufferStorageEXT), + (n: 'glGetRenderbufferParameterivEXT'; d: {$ifndef FPC}@{$endif}@glGetRenderbufferParameterivEXT), + (n: 'glIsFramebufferEXT'; d: {$ifndef FPC}@{$endif}@glIsFramebufferEXT), + (n: 'glBindFramebufferEXT'; d: {$ifndef FPC}@{$endif}@glBindFramebufferEXT), + (n: 'glDeleteFramebuffersEXT'; d: {$ifndef FPC}@{$endif}@glDeleteFramebuffersEXT), + (n: 'glGenFramebuffersEXT'; d: {$ifndef FPC}@{$endif}@glGenFramebuffersEXT), + (n: 'glCheckFramebufferStatusEXT'; d: {$ifndef FPC}@{$endif}@glCheckFramebufferStatusEXT), + (n: 'glFramebufferTexture1DEXT'; d: {$ifndef FPC}@{$endif}@glFramebufferTexture1DEXT), + (n: 'glFramebufferTexture2DEXT'; d: {$ifndef FPC}@{$endif}@glFramebufferTexture2DEXT), + (n: 'glFramebufferTexture3DEXT'; d: {$ifndef FPC}@{$endif}@glFramebufferTexture3DEXT), + (n: 'glFramebufferRenderbufferEXT'; d: {$ifndef FPC}@{$endif}@glFramebufferRenderbufferEXT), + (n: 'glGetFramebufferAttachmentParameterivEXT'; d: {$ifndef FPC}@{$endif}@glGetFramebufferAttachmentParameterivEXT), + (n: 'glGenerateMipmapEXT'; d: {$ifndef FPC}@{$endif}@glGenerateMipmapEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_framebuffer_object(): Boolean; +const + funcs: array[0..19] of funcinfoty = + ( + (n: 'glIsRenderbuffer'; d: {$ifndef FPC}@{$endif}@glIsRenderbuffer), + (n: 'glBindRenderbuffer'; d: {$ifndef FPC}@{$endif}@glBindRenderbuffer), + (n: 'glDeleteRenderbuffers'; d: {$ifndef FPC}@{$endif}@glDeleteRenderbuffers), + (n: 'glGenRenderbuffers'; d: {$ifndef FPC}@{$endif}@glGenRenderbuffers), + (n: 'glRenderbufferStorage'; d: {$ifndef FPC}@{$endif}@glRenderbufferStorage), + (n: 'glGetRenderbufferParameteriv'; d: {$ifndef FPC}@{$endif}@glGetRenderbufferParameteriv), + (n: 'glIsFramebuffer'; d: {$ifndef FPC}@{$endif}@glIsFramebuffer), + (n: 'glBindFramebuffer'; d: {$ifndef FPC}@{$endif}@glBindFramebuffer), + (n: 'glDeleteFramebuffers'; d: {$ifndef FPC}@{$endif}@glDeleteFramebuffers), + (n: 'glGenFramebuffers'; d: {$ifndef FPC}@{$endif}@glGenFramebuffers), + (n: 'glCheckFramebufferStatus'; d: {$ifndef FPC}@{$endif}@glCheckFramebufferStatus), + (n: 'glFramebufferTexture1D'; d: {$ifndef FPC}@{$endif}@glFramebufferTexture1D), + (n: 'glFramebufferTexture2D'; d: {$ifndef FPC}@{$endif}@glFramebufferTexture2D), + (n: 'glFramebufferTexture3D'; d: {$ifndef FPC}@{$endif}@glFramebufferTexture3D), + (n: 'glFramebufferRenderbuffer'; d: {$ifndef FPC}@{$endif}@glFramebufferRenderbuffer), + (n: 'glGetFramebufferAttachmentParameteriv'; d: {$ifndef FPC}@{$endif}@glGetFramebufferAttachmentParameteriv), + (n: 'glGenerateMipmap'; d: {$ifndef FPC}@{$endif}@glGenerateMipmap), + (n: 'glBlitFramebuffer'; d: {$ifndef FPC}@{$endif}@glBlitFramebuffer), + (n: 'glRenderbufferStorageMultisample'; d: {$ifndef FPC}@{$endif}@glRenderbufferStorageMultisample), + (n: 'glFramebufferTextureLayer'; d: {$ifndef FPC}@{$endif}@glFramebufferTextureLayer) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_map_buffer_range(): Boolean; +const + funcs: array[0..1] of funcinfoty = + ( + (n: 'glMapBufferRange'; d: {$ifndef FPC}@{$endif}@glMapBufferRange), + (n: 'glFlushMappedBufferRange'; d: {$ifndef FPC}@{$endif}@glFlushMappedBufferRange) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_vertex_array_object(): Boolean; +const + funcs: array[0..3] of funcinfoty = + ( + (n: 'glBindVertexArray'; d: {$ifndef FPC}@{$endif}@glBindVertexArray), + (n: 'glDeleteVertexArrays'; d: {$ifndef FPC}@{$endif}@glDeleteVertexArrays), + (n: 'glGenVertexArrays'; d: {$ifndef FPC}@{$endif}@glGenVertexArrays), + (n: 'glIsVertexArray'; d: {$ifndef FPC}@{$endif}@glIsVertexArray) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_copy_buffer(): Boolean; +const + funcs: array[0..0] of funcinfoty = + ( + (n: 'glCopyBufferSubData'; d: {$ifndef FPC}@{$endif}@glCopyBufferSubData) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_uniform_buffer_object(): Boolean; +const + funcs: array[0..9] of funcinfoty = + ( + (n: 'glGetUniformIndices'; d: {$ifndef FPC}@{$endif}@glGetUniformIndices), + (n: 'glGetActiveUniformsiv'; d: {$ifndef FPC}@{$endif}@glGetActiveUniformsiv), + (n: 'glGetActiveUniformName'; d: {$ifndef FPC}@{$endif}@glGetActiveUniformName), + (n: 'glGetUniformBlockIndex'; d: {$ifndef FPC}@{$endif}@glGetUniformBlockIndex), + (n: 'glGetActiveUniformBlockiv'; d: {$ifndef FPC}@{$endif}@glGetActiveUniformBlockiv), + (n: 'glGetActiveUniformBlockName'; d: {$ifndef FPC}@{$endif}@glGetActiveUniformBlockName), + (n: 'glUniformBlockBinding'; d: {$ifndef FPC}@{$endif}@glUniformBlockBinding), + (n: 'glBindBufferRange'; d: {$ifndef FPC}@{$endif}@glBindBufferRange), + (n: 'glBindBufferBase'; d: {$ifndef FPC}@{$endif}@glBindBufferBase), + (n: 'glGetIntegeri_v'; d: {$ifndef FPC}@{$endif}@glGetIntegeri_v) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_draw_elements_base_vertex(): Boolean; +const + funcs: array[0..3] of funcinfoty = + ( + (n: 'glDrawElementsBaseVertex'; d: {$ifndef FPC}@{$endif}@glDrawElementsBaseVertex), + (n: 'glDrawRangeElementsBaseVertex'; d: {$ifndef FPC}@{$endif}@glDrawRangeElementsBaseVertex), + (n: 'glDrawElementsInstancedBaseVertex'; d: {$ifndef FPC}@{$endif}@glDrawElementsInstancedBaseVertex), + (n: 'glMultiDrawElementsBaseVertex'; d: {$ifndef FPC}@{$endif}@glMultiDrawElementsBaseVertex) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_provoking_vertex(): Boolean; +const + funcs: array[0..0] of funcinfoty = + ( + (n: 'glProvokingVertex'; d: {$ifndef FPC}@{$endif}@glProvokingVertex) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_sync(): Boolean; +const + funcs: array[0..6] of funcinfoty = + ( + (n: 'glFenceSync'; d: {$ifndef FPC}@{$endif}@glFenceSync), + (n: 'glIsSync'; d: {$ifndef FPC}@{$endif}@glIsSync), + (n: 'glDeleteSync'; d: {$ifndef FPC}@{$endif}@glDeleteSync), + (n: 'glClientWaitSync'; d: {$ifndef FPC}@{$endif}@glClientWaitSync), + (n: 'glWaitSync'; d: {$ifndef FPC}@{$endif}@glWaitSync), + (n: 'glGetInteger64v'; d: {$ifndef FPC}@{$endif}@glGetInteger64v), + (n: 'glGetSynciv'; d: {$ifndef FPC}@{$endif}@glGetSynciv) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_texture_multisample(): Boolean; +const + funcs: array[0..3] of funcinfoty = + ( + (n: 'glTexImage2DMultisample'; d: {$ifndef FPC}@{$endif}@glTexImage2DMultisample), + (n: 'glTexImage3DMultisample'; d: {$ifndef FPC}@{$endif}@glTexImage3DMultisample), + (n: 'glGetMultisamplefv'; d: {$ifndef FPC}@{$endif}@glGetMultisamplefv), + (n: 'glSampleMaski'; d: {$ifndef FPC}@{$endif}@glSampleMaski) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_sampler_objects(): Boolean; +const + funcs: array[0..13] of funcinfoty = + ( + (n: 'glGenSamplers'; d: {$ifndef FPC}@{$endif}@glGenSamplers), + (n: 'glDeleteSamplers'; d: {$ifndef FPC}@{$endif}@glDeleteSamplers), + (n: 'glIsSampler'; d: {$ifndef FPC}@{$endif}@glIsSampler), + (n: 'glBindSampler'; d: {$ifndef FPC}@{$endif}@glBindSampler), + (n: 'glSamplerParameteri'; d: {$ifndef FPC}@{$endif}@glSamplerParameteri), + (n: 'glSamplerParameteriv'; d: {$ifndef FPC}@{$endif}@glSamplerParameteriv), + (n: 'glSamplerParameterf'; d: {$ifndef FPC}@{$endif}@glSamplerParameterf), + (n: 'glSamplerParameterfv'; d: {$ifndef FPC}@{$endif}@glSamplerParameterfv), + (n: 'glSamplerParameterIiv'; d: {$ifndef FPC}@{$endif}@glSamplerParameterIiv), + (n: 'glSamplerParameterIuiv'; d: {$ifndef FPC}@{$endif}@glSamplerParameterIuiv), + (n: 'glGetSamplerParameteriv'; d: {$ifndef FPC}@{$endif}@glGetSamplerParameteriv), + (n: 'glGetSamplerParameterIiv'; d: {$ifndef FPC}@{$endif}@glGetSamplerParameterIiv), + (n: 'glGetSamplerParameterfv'; d: {$ifndef FPC}@{$endif}@glGetSamplerParameterfv), + (n: 'glGetSamplerParameterIfv'; d: {$ifndef FPC}@{$endif}@glGetSamplerParameterIfv) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_blend_func_extended(): Boolean; +const + funcs: array[0..1] of funcinfoty = + ( + (n: 'glBindFragDataLocationIndexed'; d: {$ifndef FPC}@{$endif}@glBindFragDataLocationIndexed), + (n: 'glGetFragDataIndex'; d: {$ifndef FPC}@{$endif}@glGetFragDataIndex) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_timer_query(): Boolean; +const + funcs: array[0..2] of funcinfoty = + ( + (n: 'glQueryCounter'; d: {$ifndef FPC}@{$endif}@glQueryCounter), + (n: 'glGetQueryObjecti64v'; d: {$ifndef FPC}@{$endif}@glGetQueryObjecti64v), + (n: 'glGetQueryObjectui64v'; d: {$ifndef FPC}@{$endif}@glGetQueryObjectui64v) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_vertex_type_2_10_10_10_rev(): Boolean; +const + funcs: array[0..37] of funcinfoty = + ( + (n: 'glVertexP2ui'; d: {$ifndef FPC}@{$endif}@glVertexP2ui), + (n: 'glVertexP2uiv'; d: {$ifndef FPC}@{$endif}@glVertexP2uiv), + (n: 'glVertexP3ui'; d: {$ifndef FPC}@{$endif}@glVertexP3ui), + (n: 'glVertexP3uiv'; d: {$ifndef FPC}@{$endif}@glVertexP3uiv), + (n: 'glVertexP4ui'; d: {$ifndef FPC}@{$endif}@glVertexP4ui), + (n: 'glVertexP4uiv'; d: {$ifndef FPC}@{$endif}@glVertexP4uiv), + (n: 'glTexCoordP1ui'; d: {$ifndef FPC}@{$endif}@glTexCoordP1ui), + (n: 'glTexCoordP1uiv'; d: {$ifndef FPC}@{$endif}@glTexCoordP1uiv), + (n: 'glTexCoordP2ui'; d: {$ifndef FPC}@{$endif}@glTexCoordP2ui), + (n: 'glTexCoordP2uiv'; d: {$ifndef FPC}@{$endif}@glTexCoordP2uiv), + (n: 'glTexCoordP3ui'; d: {$ifndef FPC}@{$endif}@glTexCoordP3ui), + (n: 'glTexCoordP3uiv'; d: {$ifndef FPC}@{$endif}@glTexCoordP3uiv), + (n: 'glTexCoordP4ui'; d: {$ifndef FPC}@{$endif}@glTexCoordP4ui), + (n: 'glTexCoordP4uiv'; d: {$ifndef FPC}@{$endif}@glTexCoordP4uiv), + (n: 'glMultiTexCoordP1ui'; d: {$ifndef FPC}@{$endif}@glMultiTexCoordP1ui), + (n: 'glMultiTexCoordP1uiv'; d: {$ifndef FPC}@{$endif}@glMultiTexCoordP1uiv), + (n: 'glMultiTexCoordP2ui'; d: {$ifndef FPC}@{$endif}@glMultiTexCoordP2ui), + (n: 'glMultiTexCoordP2uiv'; d: {$ifndef FPC}@{$endif}@glMultiTexCoordP2uiv), + (n: 'glMultiTexCoordP3ui'; d: {$ifndef FPC}@{$endif}@glMultiTexCoordP3ui), + (n: 'glMultiTexCoordP3uiv'; d: {$ifndef FPC}@{$endif}@glMultiTexCoordP3uiv), + (n: 'glMultiTexCoordP4ui'; d: {$ifndef FPC}@{$endif}@glMultiTexCoordP4ui), + (n: 'glMultiTexCoordP4uiv'; d: {$ifndef FPC}@{$endif}@glMultiTexCoordP4uiv), + (n: 'glNormalP3ui'; d: {$ifndef FPC}@{$endif}@glNormalP3ui), + (n: 'glNormalP3uiv'; d: {$ifndef FPC}@{$endif}@glNormalP3uiv), + (n: 'glColorP3ui'; d: {$ifndef FPC}@{$endif}@glColorP3ui), + (n: 'glColorP3uiv'; d: {$ifndef FPC}@{$endif}@glColorP3uiv), + (n: 'glColorP4ui'; d: {$ifndef FPC}@{$endif}@glColorP4ui), + (n: 'glColorP4uiv'; d: {$ifndef FPC}@{$endif}@glColorP4uiv), + (n: 'glSecondaryColorP3ui'; d: {$ifndef FPC}@{$endif}@glSecondaryColorP3ui), + (n: 'glSecondaryColorP3uiv'; d: {$ifndef FPC}@{$endif}@glSecondaryColorP3uiv), + (n: 'glVertexAttribP1ui'; d: {$ifndef FPC}@{$endif}@glVertexAttribP1ui), + (n: 'glVertexAttribP1uiv'; d: {$ifndef FPC}@{$endif}@glVertexAttribP1uiv), + (n: 'glVertexAttribP2ui'; d: {$ifndef FPC}@{$endif}@glVertexAttribP2ui), + (n: 'glVertexAttribP2uiv'; d: {$ifndef FPC}@{$endif}@glVertexAttribP2uiv), + (n: 'glVertexAttribP3ui'; d: {$ifndef FPC}@{$endif}@glVertexAttribP3ui), + (n: 'glVertexAttribP3uiv'; d: {$ifndef FPC}@{$endif}@glVertexAttribP3uiv), + (n: 'glVertexAttribP4ui'; d: {$ifndef FPC}@{$endif}@glVertexAttribP4ui), + (n: 'glVertexAttribP4uiv'; d: {$ifndef FPC}@{$endif}@glVertexAttribP4uiv) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_gpu_shader_fp64(): Boolean; +const + funcs: array[0..34] of funcinfoty = + ( + (n: 'glUniform1d'; d: {$ifndef FPC}@{$endif}@glUniform1d), + (n: 'glUniform2d'; d: {$ifndef FPC}@{$endif}@glUniform2d), + (n: 'glUniform3d'; d: {$ifndef FPC}@{$endif}@glUniform3d), + (n: 'glUniform4d'; d: {$ifndef FPC}@{$endif}@glUniform4d), + (n: 'glUniform1dv'; d: {$ifndef FPC}@{$endif}@glUniform1dv), + (n: 'glUniform2dv'; d: {$ifndef FPC}@{$endif}@glUniform2dv), + (n: 'glUniform3dv'; d: {$ifndef FPC}@{$endif}@glUniform3dv), + (n: 'glUniform4dv'; d: {$ifndef FPC}@{$endif}@glUniform4dv), + (n: 'glUniformMatrix2dv'; d: {$ifndef FPC}@{$endif}@glUniformMatrix2dv), + (n: 'glUniformMatrix3dv'; d: {$ifndef FPC}@{$endif}@glUniformMatrix3dv), + (n: 'glUniformMatrix4dv'; d: {$ifndef FPC}@{$endif}@glUniformMatrix4dv), + (n: 'glUniformMatrix2x3dv'; d: {$ifndef FPC}@{$endif}@glUniformMatrix2x3dv), + (n: 'glUniformMatrix2x4dv'; d: {$ifndef FPC}@{$endif}@glUniformMatrix2x4dv), + (n: 'glUniformMatrix3x2dv'; d: {$ifndef FPC}@{$endif}@glUniformMatrix3x2dv), + (n: 'glUniformMatrix3x4dv'; d: {$ifndef FPC}@{$endif}@glUniformMatrix3x4dv), + (n: 'glUniformMatrix4x2dv'; d: {$ifndef FPC}@{$endif}@glUniformMatrix4x2dv), + (n: 'glUniformMatrix4x3dv'; d: {$ifndef FPC}@{$endif}@glUniformMatrix4x3dv), + (n: 'glGetUniformdv'; d: {$ifndef FPC}@{$endif}@glGetUniformdv), + (n: 'glProgramUniform1dEXT'; d: {$ifndef FPC}@{$endif}@glProgramUniform1dEXT), + (n: 'glProgramUniform2dEXT'; d: {$ifndef FPC}@{$endif}@glProgramUniform2dEXT), + (n: 'glProgramUniform3dEXT'; d: {$ifndef FPC}@{$endif}@glProgramUniform3dEXT), + (n: 'glProgramUniform4dEXT'; d: {$ifndef FPC}@{$endif}@glProgramUniform4dEXT), + (n: 'glProgramUniform1dvEXT'; d: {$ifndef FPC}@{$endif}@glProgramUniform1dvEXT), + (n: 'glProgramUniform2dvEXT'; d: {$ifndef FPC}@{$endif}@glProgramUniform2dvEXT), + (n: 'glProgramUniform3dvEXT'; d: {$ifndef FPC}@{$endif}@glProgramUniform3dvEXT), + (n: 'glProgramUniform4dvEXT'; d: {$ifndef FPC}@{$endif}@glProgramUniform4dvEXT), + (n: 'glProgramUniformMatrix2dvEXT'; d: {$ifndef FPC}@{$endif}@glProgramUniformMatrix2dvEXT), + (n: 'glProgramUniformMatrix3dvEXT'; d: {$ifndef FPC}@{$endif}@glProgramUniformMatrix3dvEXT), + (n: 'glProgramUniformMatrix4dvEXT'; d: {$ifndef FPC}@{$endif}@glProgramUniformMatrix4dvEXT), + (n: 'glProgramUniformMatrix2x3dvEXT'; d: {$ifndef FPC}@{$endif}@glProgramUniformMatrix2x3dvEXT), + (n: 'glProgramUniformMatrix2x4dvEXT'; d: {$ifndef FPC}@{$endif}@glProgramUniformMatrix2x4dvEXT), + (n: 'glProgramUniformMatrix3x2dvEXT'; d: {$ifndef FPC}@{$endif}@glProgramUniformMatrix3x2dvEXT), + (n: 'glProgramUniformMatrix3x4dvEXT'; d: {$ifndef FPC}@{$endif}@glProgramUniformMatrix3x4dvEXT), + (n: 'glProgramUniformMatrix4x2dvEXT'; d: {$ifndef FPC}@{$endif}@glProgramUniformMatrix4x2dvEXT), + (n: 'glProgramUniformMatrix4x3dvEXT'; d: {$ifndef FPC}@{$endif}@glProgramUniformMatrix4x3dvEXT) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_shader_subroutine(): Boolean; +const + funcs: array[0..7] of funcinfoty = + ( + (n: 'glGetSubroutineUniformLocation'; d: {$ifndef FPC}@{$endif}@glGetSubroutineUniformLocation), + (n: 'glGetSubroutineIndex'; d: {$ifndef FPC}@{$endif}@glGetSubroutineIndex), + (n: 'glGetActiveSubroutineUniformiv'; d: {$ifndef FPC}@{$endif}@glGetActiveSubroutineUniformiv), + (n: 'glGetActiveSubroutineUniformName'; d: {$ifndef FPC}@{$endif}@glGetActiveSubroutineUniformName), + (n: 'glGetActiveSubroutineName'; d: {$ifndef FPC}@{$endif}@glGetActiveSubroutineName), + (n: 'glUniformSubroutinesuiv'; d: {$ifndef FPC}@{$endif}@glUniformSubroutinesuiv), + (n: 'glGetUniformSubroutineuiv'; d: {$ifndef FPC}@{$endif}@glGetUniformSubroutineuiv), + (n: 'glGetProgramStageiv'; d: {$ifndef FPC}@{$endif}@glGetProgramStageiv) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_tessellation_shader(): Boolean; +const + funcs: array[0..1] of funcinfoty = + ( + (n: 'glPatchParameteri'; d: {$ifndef FPC}@{$endif}@glPatchParameteri), + (n: 'glPatchParameterfv'; d: {$ifndef FPC}@{$endif}@glPatchParameterfv) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_transform_feedback2(): Boolean; +const + funcs: array[0..6] of funcinfoty = + ( + (n: 'glBindTransformFeedback'; d: {$ifndef FPC}@{$endif}@glBindTransformFeedback), + (n: 'glDeleteTransformFeedbacks'; d: {$ifndef FPC}@{$endif}@glDeleteTransformFeedbacks), + (n: 'glGenTransformFeedbacks'; d: {$ifndef FPC}@{$endif}@glGenTransformFeedbacks), + (n: 'glIsTransformFeedback'; d: {$ifndef FPC}@{$endif}@glIsTransformFeedback), + (n: 'glPauseTransformFeedback'; d: {$ifndef FPC}@{$endif}@glPauseTransformFeedback), + (n: 'glResumeTransformFeedback'; d: {$ifndef FPC}@{$endif}@glResumeTransformFeedback), + (n: 'glDrawTransformFeedback'; d: {$ifndef FPC}@{$endif}@glDrawTransformFeedback) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_ARB_transform_feedback3(): Boolean; +const + funcs: array[0..3] of funcinfoty = + ( + (n: 'glDrawTransformFeedbackStream'; d: {$ifndef FPC}@{$endif}@glDrawTransformFeedbackStream), + (n: 'glBeginQueryIndexed'; d: {$ifndef FPC}@{$endif}@glBeginQueryIndexed), + (n: 'glEndQueryIndexed'; d: {$ifndef FPC}@{$endif}@glEndQueryIndexed), + (n: 'glGetQueryIndexediv'; d: {$ifndef FPC}@{$endif}@glGetQueryIndexediv) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_version_1_4: Boolean; +const + funcs: array[0..44] of funcinfoty = + ( + (n: 'glBlendFuncSeparate'; d: {$ifndef FPC}@{$endif}@glBlendFuncSeparate), + (n: 'glFogCoordf'; d: {$ifndef FPC}@{$endif}@glFogCoordf), + (n: 'glFogCoordfv'; d: {$ifndef FPC}@{$endif}@glFogCoordfv), + (n: 'glFogCoordd'; d: {$ifndef FPC}@{$endif}@glFogCoordd), + (n: 'glFogCoorddv'; d: {$ifndef FPC}@{$endif}@glFogCoorddv), + (n: 'glFogCoordPointer'; d: {$ifndef FPC}@{$endif}@glFogCoordPointer), + (n: 'glMultiDrawArrays'; d: {$ifndef FPC}@{$endif}@glMultiDrawArrays), + (n: 'glMultiDrawElements'; d: {$ifndef FPC}@{$endif}@glMultiDrawElements), + (n: 'glPointParameterf'; d: {$ifndef FPC}@{$endif}@glPointParameterf), + (n: 'glPointParameterfv'; d: {$ifndef FPC}@{$endif}@glPointParameterfv), + (n: 'glPointParameteri'; d: {$ifndef FPC}@{$endif}@glPointParameteri), + (n: 'glPointParameteriv'; d: {$ifndef FPC}@{$endif}@glPointParameteriv), + (n: 'glSecondaryColor3b'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3b), + (n: 'glSecondaryColor3bv'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3bv), + (n: 'glSecondaryColor3d'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3d), + (n: 'glSecondaryColor3dv'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3dv), + (n: 'glSecondaryColor3f'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3f), + (n: 'glSecondaryColor3fv'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3fv), + (n: 'glSecondaryColor3i'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3i), + (n: 'glSecondaryColor3iv'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3iv), + (n: 'glSecondaryColor3s'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3s), + (n: 'glSecondaryColor3sv'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3sv), + (n: 'glSecondaryColor3ub'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3ub), + (n: 'glSecondaryColor3ubv'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3ubv), + (n: 'glSecondaryColor3ui'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3ui), + (n: 'glSecondaryColor3uiv'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3uiv), + (n: 'glSecondaryColor3us'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3us), + (n: 'glSecondaryColor3usv'; d: {$ifndef FPC}@{$endif}@glSecondaryColor3usv), + (n: 'glSecondaryColorPointer'; d: {$ifndef FPC}@{$endif}@glSecondaryColorPointer), + (n: 'glWindowPos2d'; d: {$ifndef FPC}@{$endif}@glWindowPos2d), + (n: 'glWindowPos2dv'; d: {$ifndef FPC}@{$endif}@glWindowPos2dv), + (n: 'glWindowPos2f'; d: {$ifndef FPC}@{$endif}@glWindowPos2f), + (n: 'glWindowPos2fv'; d: {$ifndef FPC}@{$endif}@glWindowPos2fv), + (n: 'glWindowPos2i'; d: {$ifndef FPC}@{$endif}@glWindowPos2i), + (n: 'glWindowPos2iv'; d: {$ifndef FPC}@{$endif}@glWindowPos2iv), + (n: 'glWindowPos2s'; d: {$ifndef FPC}@{$endif}@glWindowPos2s), + (n: 'glWindowPos2sv'; d: {$ifndef FPC}@{$endif}@glWindowPos2sv), + (n: 'glWindowPos3d'; d: {$ifndef FPC}@{$endif}@glWindowPos3d), + (n: 'glWindowPos3dv'; d: {$ifndef FPC}@{$endif}@glWindowPos3dv), + (n: 'glWindowPos3f'; d: {$ifndef FPC}@{$endif}@glWindowPos3f), + (n: 'glWindowPos3fv'; d: {$ifndef FPC}@{$endif}@glWindowPos3fv), + (n: 'glWindowPos3i'; d: {$ifndef FPC}@{$endif}@glWindowPos3i), + (n: 'glWindowPos3iv'; d: {$ifndef FPC}@{$endif}@glWindowPos3iv), + (n: 'glWindowPos3s'; d: {$ifndef FPC}@{$endif}@glWindowPos3s), + (n: 'glWindowPos3sv'; d: {$ifndef FPC}@{$endif}@glWindowPos3sv) + ); +begin + result:= getprocaddresses(libgl,funcs); + +end; + +function Load_GL_version_1_5: Boolean; +const + funcs: array[0..18] of funcinfoty = + ( + (n: 'glGenQueries'; d: {$ifndef FPC}@{$endif}@glGenQueries), + (n: 'glDeleteQueries'; d: {$ifndef FPC}@{$endif}@glDeleteQueries), + (n: 'glIsQuery'; d: {$ifndef FPC}@{$endif}@glIsQuery), + (n: 'glBeginQuery'; d: {$ifndef FPC}@{$endif}@glBeginQuery), + (n: 'glEndQuery'; d: {$ifndef FPC}@{$endif}@glEndQuery), + (n: 'glGetQueryiv'; d: {$ifndef FPC}@{$endif}@glGetQueryiv), + (n: 'glGetQueryObjectiv'; d: {$ifndef FPC}@{$endif}@glGetQueryObjectiv), + (n: 'glGetQueryObjectuiv'; d: {$ifndef FPC}@{$endif}@glGetQueryObjectuiv), + (n: 'glBindBuffer'; d: {$ifndef FPC}@{$endif}@glBindBuffer), + (n: 'glDeleteBuffers'; d: {$ifndef FPC}@{$endif}@glDeleteBuffers), + (n: 'glGenBuffers'; d: {$ifndef FPC}@{$endif}@glGenBuffers), + (n: 'glIsBuffer'; d: {$ifndef FPC}@{$endif}@glIsBuffer), + (n: 'glBufferData'; d: {$ifndef FPC}@{$endif}@glBufferData), + (n: 'glBufferSubData'; d: {$ifndef FPC}@{$endif}@glBufferSubData), + (n: 'glGetBufferSubData'; d: {$ifndef FPC}@{$endif}@glGetBufferSubData), + (n: 'glMapBuffer'; d: {$ifndef FPC}@{$endif}@glMapBuffer), + (n: 'glUnmapBuffer'; d: {$ifndef FPC}@{$endif}@glUnmapBuffer), + (n: 'glGetBufferParameteriv'; d: {$ifndef FPC}@{$endif}@glGetBufferParameteriv), + (n: 'glGetBufferPointerv'; d: {$ifndef FPC}@{$endif}@glGetBufferPointerv) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_version_2_0: Boolean; +const + funcs: array[0..92] of funcinfoty = + ( + (n: 'glBlendEquationSeparate'; d: {$ifndef FPC}@{$endif}@glBlendEquationSeparate), + (n: 'glDrawBuffers'; d: {$ifndef FPC}@{$endif}@glDrawBuffers), + (n: 'glStencilOpSeparate'; d: {$ifndef FPC}@{$endif}@glStencilOpSeparate), + (n: 'glStencilFuncSeparate'; d: {$ifndef FPC}@{$endif}@glStencilFuncSeparate), + (n: 'glStencilMaskSeparate'; d: {$ifndef FPC}@{$endif}@glStencilMaskSeparate), + (n: 'glAttachShader'; d: {$ifndef FPC}@{$endif}@glAttachShader), + (n: 'glBindAttribLocation'; d: {$ifndef FPC}@{$endif}@glBindAttribLocation), + (n: 'glCompileShader'; d: {$ifndef FPC}@{$endif}@glCompileShader), + (n: 'glCreateProgram'; d: {$ifndef FPC}@{$endif}@glCreateProgram), + (n: 'glCreateShader'; d: {$ifndef FPC}@{$endif}@glCreateShader), + (n: 'glDeleteProgram'; d: {$ifndef FPC}@{$endif}@glDeleteProgram), + (n: 'glDeleteShader'; d: {$ifndef FPC}@{$endif}@glDeleteShader), + (n: 'glDetachShader'; d: {$ifndef FPC}@{$endif}@glDetachShader), + (n: 'glDisableVertexAttribArray'; d: {$ifndef FPC}@{$endif}@glDisableVertexAttribArray), + (n: 'glEnableVertexAttribArray'; d: {$ifndef FPC}@{$endif}@glEnableVertexAttribArray), + (n: 'glGetActiveAttrib'; d: {$ifndef FPC}@{$endif}@glGetActiveAttrib), + (n: 'glGetActiveUniform'; d: {$ifndef FPC}@{$endif}@glGetActiveUniform), + (n: 'glGetAttachedShaders'; d: {$ifndef FPC}@{$endif}@glGetAttachedShaders), + (n: 'glGetAttribLocation'; d: {$ifndef FPC}@{$endif}@glGetAttribLocation), + (n: 'glGetProgramiv'; d: {$ifndef FPC}@{$endif}@glGetProgramiv), + (n: 'glGetProgramInfoLog'; d: {$ifndef FPC}@{$endif}@glGetProgramInfoLog), + (n: 'glGetShaderiv'; d: {$ifndef FPC}@{$endif}@glGetShaderiv), + (n: 'glGetShaderInfoLog'; d: {$ifndef FPC}@{$endif}@glGetShaderInfoLog), + (n: 'glGetShaderSource'; d: {$ifndef FPC}@{$endif}@glGetShaderSource), + (n: 'glGetUniformLocation'; d: {$ifndef FPC}@{$endif}@glGetUniformLocation), + (n: 'glGetUniformfv'; d: {$ifndef FPC}@{$endif}@glGetUniformfv), + (n: 'glGetUniformiv'; d: {$ifndef FPC}@{$endif}@glGetUniformiv), + (n: 'glGetVertexAttribdv'; d: {$ifndef FPC}@{$endif}@glGetVertexAttribdv), + (n: 'glGetVertexAttribfv'; d: {$ifndef FPC}@{$endif}@glGetVertexAttribfv), + (n: 'glGetVertexAttribiv'; d: {$ifndef FPC}@{$endif}@glGetVertexAttribiv), + (n: 'glGetVertexAttribPointerv'; d: {$ifndef FPC}@{$endif}@glGetVertexAttribPointerv), + (n: 'glIsProgram'; d: {$ifndef FPC}@{$endif}@glIsProgram), + (n: 'glIsShader'; d: {$ifndef FPC}@{$endif}@glIsShader), + (n: 'glLinkProgram'; d: {$ifndef FPC}@{$endif}@glLinkProgram), + (n: 'glShaderSource'; d: {$ifndef FPC}@{$endif}@glShaderSource), + (n: 'glUseProgram'; d: {$ifndef FPC}@{$endif}@glUseProgram), + (n: 'glUniform1f'; d: {$ifndef FPC}@{$endif}@glUniform1f), + (n: 'glUniform2f'; d: {$ifndef FPC}@{$endif}@glUniform2f), + (n: 'glUniform3f'; d: {$ifndef FPC}@{$endif}@glUniform3f), + (n: 'glUniform4f'; d: {$ifndef FPC}@{$endif}@glUniform4f), + (n: 'glUniform1i'; d: {$ifndef FPC}@{$endif}@glUniform1i), + (n: 'glUniform2i'; d: {$ifndef FPC}@{$endif}@glUniform2i), + (n: 'glUniform3i'; d: {$ifndef FPC}@{$endif}@glUniform3i), + (n: 'glUniform4i'; d: {$ifndef FPC}@{$endif}@glUniform4i), + (n: 'glUniform1fv'; d: {$ifndef FPC}@{$endif}@glUniform1fv), + (n: 'glUniform2fv'; d: {$ifndef FPC}@{$endif}@glUniform2fv), + (n: 'glUniform3fv'; d: {$ifndef FPC}@{$endif}@glUniform3fv), + (n: 'glUniform4fv'; d: {$ifndef FPC}@{$endif}@glUniform4fv), + (n: 'glUniform1iv'; d: {$ifndef FPC}@{$endif}@glUniform1iv), + (n: 'glUniform2iv'; d: {$ifndef FPC}@{$endif}@glUniform2iv), + (n: 'glUniform3iv'; d: {$ifndef FPC}@{$endif}@glUniform3iv), + (n: 'glUniform4iv'; d: {$ifndef FPC}@{$endif}@glUniform4iv), + (n: 'glUniformMatrix2fv'; d: {$ifndef FPC}@{$endif}@glUniformMatrix2fv), + (n: 'glUniformMatrix3fv'; d: {$ifndef FPC}@{$endif}@glUniformMatrix3fv), + (n: 'glUniformMatrix4fv'; d: {$ifndef FPC}@{$endif}@glUniformMatrix4fv), + (n: 'glValidateProgram'; d: {$ifndef FPC}@{$endif}@glValidateProgram), + (n: 'glVertexAttrib1d'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1d), + (n: 'glVertexAttrib1dv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1dv), + (n: 'glVertexAttrib1f'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1f), + (n: 'glVertexAttrib1fv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1fv), + (n: 'glVertexAttrib1s'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1s), + (n: 'glVertexAttrib1sv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib1sv), + (n: 'glVertexAttrib2d'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2d), + (n: 'glVertexAttrib2dv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2dv), + (n: 'glVertexAttrib2f'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2f), + (n: 'glVertexAttrib2fv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2fv), + (n: 'glVertexAttrib2s'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2s), + (n: 'glVertexAttrib2sv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib2sv), + (n: 'glVertexAttrib3d'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3d), + (n: 'glVertexAttrib3dv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3dv), + (n: 'glVertexAttrib3f'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3f), + (n: 'glVertexAttrib3fv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3fv), + (n: 'glVertexAttrib3s'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3s), + (n: 'glVertexAttrib3sv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib3sv), + (n: 'glVertexAttrib4Nbv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4Nbv), + (n: 'glVertexAttrib4Niv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4Niv), + (n: 'glVertexAttrib4Nsv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4Nsv), + (n: 'glVertexAttrib4Nub'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4Nub), + (n: 'glVertexAttrib4Nubv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4Nubv), + (n: 'glVertexAttrib4Nuiv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4Nuiv), + (n: 'glVertexAttrib4Nusv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4Nusv), + (n: 'glVertexAttrib4bv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4bv), + (n: 'glVertexAttrib4d'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4d), + (n: 'glVertexAttrib4dv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4dv), + (n: 'glVertexAttrib4f'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4f), + (n: 'glVertexAttrib4fv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4fv), + (n: 'glVertexAttrib4iv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4iv), + (n: 'glVertexAttrib4s'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4s), + (n: 'glVertexAttrib4sv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4sv), + (n: 'glVertexAttrib4ubv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4ubv), + (n: 'glVertexAttrib4uiv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4uiv), + (n: 'glVertexAttrib4usv'; d: {$ifndef FPC}@{$endif}@glVertexAttrib4usv), + (n: 'glVertexAttribPointer'; d: {$ifndef FPC}@{$endif}@glVertexAttribPointer) + ); +begin + result:= getprocaddresses(libgl,funcs); + +end; +(* +function glext_LoadExtension(ext: String): Boolean; +begin + + Result := FALSE; + + if ext = 'GL_version_1_2' then Result := Load_GL_version_1_2 + else if ext = 'GL_ARB_imaging' then Result := Load_GL_ARB_imaging + else if ext = 'GL_version_1_3' then Result := Load_GL_version_1_3 + else if ext = 'GL_ARB_multitexture' then Result := Load_GL_ARB_multitexture + else if ext = 'GL_ARB_transpose_matrix' then Result := Load_GL_ARB_transpose_matrix + else if ext = 'GL_ARB_multisample' then Result := Load_GL_ARB_multisample + else if ext = 'GL_ARB_texture_env_add' then Result := Load_GL_ARB_texture_env_add +{$IFDEF msWindows} + else if ext = 'WGL_ARB_extensions_string' then Result := Load_WGL_ARB_extensions_string + else if ext = 'WGL_ARB_buffer_region' then Result := Load_WGL_ARB_buffer_region +{$ENDIF} + else if ext = 'GL_ARB_texture_cube_map' then Result := Load_GL_ARB_texture_cube_map + else if ext = 'GL_ARB_depth_texture' then Result := Load_GL_ARB_depth_texture + else if ext = 'GL_ARB_point_parameters' then Result := Load_GL_ARB_point_parameters + else if ext = 'GL_ARB_shadow' then Result := Load_GL_ARB_shadow + else if ext = 'GL_ARB_shadow_ambient' then Result := Load_GL_ARB_shadow_ambient + else if ext = 'GL_ARB_texture_border_clamp' then Result := Load_GL_ARB_texture_border_clamp + else if ext = 'GL_ARB_texture_compression' then Result := Load_GL_ARB_texture_compression + else if ext = 'GL_ARB_texture_env_combine' then Result := Load_GL_ARB_texture_env_combine + else if ext = 'GL_ARB_texture_env_crossbar' then Result := Load_GL_ARB_texture_env_crossbar + else if ext = 'GL_ARB_texture_env_dot3' then Result := Load_GL_ARB_texture_env_dot3 + else if ext = 'GL_ARB_texture_mirrored_repeat' then Result := Load_GL_ARB_texture_mirrored_repeat + else if ext = 'GL_ARB_vertex_blend' then Result := Load_GL_ARB_vertex_blend + else if ext = 'GL_ARB_vertex_program' then Result := Load_GL_ARB_vertex_program + else if ext = 'GL_ARB_window_pos' then Result := Load_GL_ARB_window_pos + else if ext = 'GL_EXT_422_pixels' then Result := Load_GL_EXT_422_pixels + else if ext = 'GL_EXT_abgr' then Result := Load_GL_EXT_abgr + else if ext = 'GL_EXT_bgra' then Result := Load_GL_EXT_bgra + else if ext = 'GL_EXT_blend_color' then Result := Load_GL_EXT_blend_color + else if ext = 'GL_EXT_blend_func_separate' then Result := Load_GL_EXT_blend_func_separate + else if ext = 'GL_EXT_blend_logic_op' then Result := Load_GL_EXT_blend_logic_op + else if ext = 'GL_EXT_blend_minmax' then Result := Load_GL_EXT_blend_minmax + else if ext = 'GL_EXT_blend_subtract' then Result := Load_GL_EXT_blend_subtract + else if ext = 'GL_EXT_clip_volume_hint' then Result := Load_GL_EXT_clip_volume_hint + else if ext = 'GL_EXT_color_subtable' then Result := Load_GL_EXT_color_subtable + else if ext = 'GL_EXT_compiled_vertex_array' then Result := Load_GL_EXT_compiled_vertex_array + else if ext = 'GL_EXT_convolution' then Result := Load_GL_EXT_convolution + else if ext = 'GL_EXT_fog_coord' then Result := Load_GL_EXT_fog_coord + else if ext = 'GL_EXT_histogram' then Result := Load_GL_EXT_histogram + else if ext = 'GL_EXT_multi_draw_arrays' then Result := Load_GL_EXT_multi_draw_arrays + else if ext = 'GL_EXT_packed_pixels' then Result := Load_GL_EXT_packed_pixels + else if ext = 'GL_EXT_paletted_texture' then Result := Load_GL_EXT_paletted_texture + else if ext = 'GL_EXT_point_parameters' then Result := Load_GL_EXT_point_parameters + else if ext = 'GL_EXT_polygon_offset' then Result := Load_GL_EXT_polygon_offset + else if ext = 'GL_EXT_secondary_color' then Result := Load_GL_EXT_secondary_color + else if ext = 'GL_EXT_separate_specular_color' then Result := Load_GL_EXT_separate_specular_color + else if ext = 'GL_EXT_shadow_funcs' then Result := Load_GL_EXT_shadow_funcs + else if ext = 'GL_EXT_shared_texture_palette' then Result := Load_GL_EXT_shared_texture_palette + else if ext = 'GL_EXT_stencil_two_side' then Result := Load_GL_EXT_stencil_two_side + else if ext = 'GL_EXT_stencil_wrap' then Result := Load_GL_EXT_stencil_wrap + else if ext = 'GL_EXT_subtexture' then Result := Load_GL_EXT_subtexture + else if ext = 'GL_EXT_texture3D' then Result := Load_GL_EXT_texture3D + else if ext = 'GL_EXT_texture_compression_s3tc' then Result := Load_GL_EXT_texture_compression_s3tc + else if ext = 'GL_EXT_texture_env_add' then Result := Load_GL_EXT_texture_env_add + else if ext = 'GL_EXT_texture_env_combine' then Result := Load_GL_EXT_texture_env_combine + else if ext = 'GL_EXT_texture_env_dot3' then Result := Load_GL_EXT_texture_env_dot3 + else if ext = 'GL_EXT_texture_filter_anisotropic' then Result := Load_GL_EXT_texture_filter_anisotropic + else if ext = 'GL_EXT_texture_lod_bias' then Result := Load_GL_EXT_texture_lod_bias + else if ext = 'GL_EXT_texture_object' then Result := Load_GL_EXT_texture_object + else if ext = 'GL_EXT_vertex_array' then Result := Load_GL_EXT_vertex_array + else if ext = 'GL_EXT_vertex_shader' then Result := Load_GL_EXT_vertex_shader + else if ext = 'GL_EXT_vertex_weighting' then Result := Load_GL_EXT_vertex_weighting + else if ext = 'GL_HP_occlusion_test' then Result := Load_GL_HP_occlusion_test + else if ext = 'GL_NV_blend_square' then Result := Load_GL_NV_blend_square + else if ext = 'GL_NV_copy_depth_to_color' then Result := Load_GL_NV_copy_depth_to_color + else if ext = 'GL_NV_depth_clamp' then Result := Load_GL_NV_depth_clamp + else if ext = 'GL_NV_evaluators' then Result := Load_GL_NV_evaluators + else if ext = 'GL_NV_fence' then Result := Load_GL_NV_fence + else if ext = 'GL_NV_fog_distance' then Result := Load_GL_NV_fog_distance + else if ext = 'GL_NV_light_max_exponent' then Result := Load_GL_NV_light_max_exponent + else if ext = 'GL_NV_multisample_filter_hint' then Result := Load_GL_NV_multisample_filter_hint + else if ext = 'GL_NV_occlusion_query' then Result := Load_GL_NV_occlusion_query + else if ext = 'GL_NV_packed_depth_stencil' then Result := Load_GL_NV_packed_depth_stencil + else if ext = 'GL_NV_point_sprite' then Result := Load_GL_NV_point_sprite + else if ext = 'GL_NV_register_combiners' then Result := Load_GL_NV_register_combiners + else if ext = 'GL_NV_register_combiners2' then Result := Load_GL_NV_register_combiners2 + else if ext = 'GL_NV_texgen_emboss' then Result := Load_GL_NV_texgen_emboss + else if ext = 'GL_NV_texgen_reflection' then Result := Load_GL_NV_texgen_reflection + else if ext = 'GL_NV_texture_compression_vtc' then Result := Load_GL_NV_texture_compression_vtc + else if ext = 'GL_NV_texture_env_combine4' then Result := Load_GL_NV_texture_env_combine4 + else if ext = 'GL_NV_texture_rectangle' then Result := Load_GL_NV_texture_rectangle + else if ext = 'GL_NV_texture_shader' then Result := Load_GL_NV_texture_shader + else if ext = 'GL_NV_texture_shader2' then Result := Load_GL_NV_texture_shader2 + else if ext = 'GL_NV_texture_shader3' then Result := Load_GL_NV_texture_shader3 + else if ext = 'GL_NV_vertex_array_range' then Result := Load_GL_NV_vertex_array_range + else if ext = 'GL_NV_vertex_array_range2' then Result := Load_GL_NV_vertex_array_range2 + else if ext = 'GL_NV_vertex_program' then Result := Load_GL_NV_vertex_program + else if ext = 'GL_NV_vertex_program1_1' then Result := Load_GL_NV_vertex_program1_1 + else if ext = 'GL_ATI_element_array' then Result := Load_GL_ATI_element_array + else if ext = 'GL_ATI_envmap_bumpmap' then Result := Load_GL_ATI_envmap_bumpmap + else if ext = 'GL_ATI_fragment_shader' then Result := Load_GL_ATI_fragment_shader + else if ext = 'GL_ATI_pn_triangles' then Result := Load_GL_ATI_pn_triangles + else if ext = 'GL_ATI_texture_mirror_once' then Result := Load_GL_ATI_texture_mirror_once + else if ext = 'GL_ATI_vertex_array_object' then Result := Load_GL_ATI_vertex_array_object + else if ext = 'GL_ATI_vertex_streams' then Result := Load_GL_ATI_vertex_streams +{$IFDEF msWindows} + else if ext = 'WGL_I3D_image_buffer' then Result := Load_WGL_I3D_image_buffer + else if ext = 'WGL_I3D_swap_frame_lock' then Result := Load_WGL_I3D_swap_frame_lock + else if ext = 'WGL_I3D_swap_frame_usage' then Result := Load_WGL_I3D_swap_frame_usage +{$ENDIF} + else if ext = 'GL_3DFX_texture_compression_FXT1' then Result := Load_GL_3DFX_texture_compression_FXT1 + else if ext = 'GL_IBM_cull_vertex' then Result := Load_GL_IBM_cull_vertex + else if ext = 'GL_IBM_multimode_draw_arrays' then Result := Load_GL_IBM_multimode_draw_arrays + else if ext = 'GL_IBM_raster_pos_clip' then Result := Load_GL_IBM_raster_pos_clip + else if ext = 'GL_IBM_texture_mirrored_repeat' then Result := Load_GL_IBM_texture_mirrored_repeat + else if ext = 'GL_IBM_vertex_array_lists' then Result := Load_GL_IBM_vertex_array_lists + else if ext = 'GL_MESA_resize_buffers' then Result := Load_GL_MESA_resize_buffers + else if ext = 'GL_MESA_window_pos' then Result := Load_GL_MESA_window_pos + else if ext = 'GL_OML_interlace' then Result := Load_GL_OML_interlace + else if ext = 'GL_OML_resample' then Result := Load_GL_OML_resample + else if ext = 'GL_OML_subsample' then Result := Load_GL_OML_subsample + else if ext = 'GL_SGIS_generate_mipmap' then Result := Load_GL_SGIS_generate_mipmap + else if ext = 'GL_SGIS_multisample' then Result := Load_GL_SGIS_multisample + else if ext = 'GL_SGIS_pixel_texture' then Result := Load_GL_SGIS_pixel_texture + else if ext = 'GL_SGIS_texture_border_clamp' then Result := Load_GL_SGIS_texture_border_clamp + else if ext = 'GL_SGIS_texture_color_mask' then Result := Load_GL_SGIS_texture_color_mask + else if ext = 'GL_SGIS_texture_edge_clamp' then Result := Load_GL_SGIS_texture_edge_clamp + else if ext = 'GL_SGIS_texture_lod' then Result := Load_GL_SGIS_texture_lod + else if ext = 'GL_SGIS_depth_texture' then Result := Load_GL_SGIS_depth_texture + else if ext = 'GL_SGIX_fog_offset' then Result := Load_GL_SGIX_fog_offset + else if ext = 'GL_SGIX_interlace' then Result := Load_GL_SGIX_interlace + else if ext = 'GL_SGIX_shadow_ambient' then Result := Load_GL_SGIX_shadow_ambient + else if ext = 'GL_SGI_color_matrix' then Result := Load_GL_SGI_color_matrix + else if ext = 'GL_SGI_color_table' then Result := Load_GL_SGI_color_table + else if ext = 'GL_SGI_texture_color_table' then Result := Load_GL_SGI_texture_color_table + else if ext = 'GL_SUN_vertex' then Result := Load_GL_SUN_vertex + else if ext = 'GL_ARB_fragment_program' then Result := Load_GL_ARB_fragment_program + else if ext = 'GL_ATI_text_fragment_shader' then Result := Load_GL_ATI_text_fragment_shader + else if ext = 'GL_APPLE_client_storage' then Result := Load_GL_APPLE_client_storage + else if ext = 'GL_APPLE_element_array' then Result := Load_GL_APPLE_element_array + else if ext = 'GL_APPLE_fence' then Result := Load_GL_APPLE_fence + else if ext = 'GL_APPLE_vertex_array_object' then Result := Load_GL_APPLE_vertex_array_object + else if ext = 'GL_APPLE_vertex_array_range' then Result := Load_GL_APPLE_vertex_array_range +{$IFDEF msWindows} + else if ext = 'WGL_ARB_pixel_format' then Result := Load_WGL_ARB_pixel_format + else if ext = 'WGL_ARB_make_current_read' then Result := Load_WGL_ARB_make_current_read + else if ext = 'WGL_ARB_pbuffer' then Result := Load_WGL_ARB_pbuffer + else if ext = 'WGL_EXT_swap_control' then Result := Load_WGL_EXT_swap_control + else if ext = 'WGL_ARB_render_texture' then Result := Load_WGL_ARB_render_texture + else if ext = 'WGL_EXT_extensions_string' then Result := Load_WGL_EXT_extensions_string + else if ext = 'WGL_EXT_make_current_read' then Result := Load_WGL_EXT_make_current_read + else if ext = 'WGL_EXT_pbuffer' then Result := Load_WGL_EXT_pbuffer + else if ext = 'WGL_EXT_pixel_format' then Result := Load_WGL_EXT_pixel_format + else if ext = 'WGL_I3D_digital_video_control' then Result := Load_WGL_I3D_digital_video_control + else if ext = 'WGL_I3D_gamma' then Result := Load_WGL_I3D_gamma + else if ext = 'WGL_I3D_genlock' then Result := Load_WGL_I3D_genlock +{$ENDIF} + else if ext = 'GL_ARB_matrix_palette' then Result := Load_GL_ARB_matrix_palette + else if ext = 'GL_NV_element_array' then Result := Load_GL_NV_element_array + else if ext = 'GL_NV_float_buffer' then Result := Load_GL_NV_float_buffer + else if ext = 'GL_NV_fragment_program' then Result := Load_GL_NV_fragment_program + else if ext = 'GL_NV_primitive_restart' then Result := Load_GL_NV_primitive_restart + else if ext = 'GL_NV_vertex_program2' then Result := Load_GL_NV_vertex_program2 + {$IFDEF msWindows} + else if ext = 'WGL_NV_render_texture_rectangle' then Result := Load_WGL_NV_render_texture_rectangle + {$ENDIF} + else if ext = 'GL_NV_pixel_data_range' then Result := Load_GL_NV_pixel_data_range + else if ext = 'GL_EXT_texture_rectangle' then Result := Load_GL_EXT_texture_rectangle + else if ext = 'GL_S3_s3tc' then Result := Load_GL_S3_s3tc + else if ext = 'GL_ATI_draw_buffers' then Result := Load_GL_ATI_draw_buffers + {$IFDEF msWindows} + else if ext = 'WGL_ATI_pixel_format_float' then Result := Load_WGL_ATI_pixel_format_float + {$ENDIF} + else if ext = 'GL_ATI_texture_env_combine3' then Result := Load_GL_ATI_texture_env_combine3 + else if ext = 'GL_ATI_texture_float' then Result := Load_GL_ATI_texture_float + else if ext = 'GL_NV_texture_expand_normal' then Result := Load_GL_NV_texture_expand_normal + else if ext = 'GL_NV_half_float' then Result := Load_GL_NV_half_float + else if ext = 'GL_ATI_map_object_buffer' then Result := Load_GL_ATI_map_object_buffer + else if ext = 'GL_ATI_separate_stencil' then Result := Load_GL_ATI_separate_stencil + else if ext = 'GL_ATI_vertex_attrib_array_object' then Result := Load_GL_ATI_vertex_attrib_array_object + else if ext = 'GL_ARB_vertex_buffer_object' then Result := Load_GL_ARB_vertex_buffer_object + else if ext = 'GL_ARB_occlusion_query' then Result := Load_GL_ARB_occlusion_query + else if ext = 'GL_ARB_shader_objects' then Result := Load_GL_ARB_shader_objects + else if ext = 'GL_ARB_vertex_shader' then Result := Load_GL_ARB_vertex_shader + else if ext = 'GL_ARB_fragment_shader' then Result := Load_GL_ARB_fragment_shader + else if ext = 'GL_ARB_shading_language_100' then Result := Load_GL_ARB_shading_language_100 + else if ext = 'GL_ARB_texture_non_power_of_two' then Result := Load_GL_ARB_texture_non_power_of_two + else if ext = 'GL_ARB_point_sprite' then Result := Load_GL_ARB_point_sprite + else if ext = 'GL_EXT_depth_bounds_test' then Result := Load_GL_EXT_depth_bounds_test + else if ext = 'GL_EXT_texture_mirror_clamp' then Result := Load_GL_EXT_texture_mirror_clamp + else if ext = 'GL_EXT_blend_equation_separate' then Result := Load_GL_EXT_blend_equation_separate + else if ext = 'GL_MESA_pack_invert' then Result := Load_GL_MESA_pack_invert + else if ext = 'GL_MESA_ycbcr_texture' then Result := Load_GL_MESA_ycbcr_texture + else if ext = 'GL_ARB_fragment_program_shadow' then Result := Load_GL_ARB_fragment_program_shadow + else if ext = 'GL_NV_fragment_program_option' then Result := Load_GL_NV_fragment_program_option + else if ext = 'GL_EXT_pixel_buffer_object' then Result := Load_GL_EXT_pixel_buffer_object + else if ext = 'GL_NV_fragment_program2' then Result := Load_GL_NV_fragment_program2 + else if ext = 'GL_NV_vertex_program2_option' then Result := Load_GL_NV_vertex_program2_option + else if ext = 'GL_NV_vertex_program3' then Result := Load_GL_NV_vertex_program3 + else if ext = 'GL_ARB_draw_buffers' then Result := Load_GL_ARB_draw_buffers + else if ext = 'GL_ARB_texture_rectangle' then Result := Load_GL_ARB_texture_rectangle + else if ext = 'GL_ARB_color_buffer_float' then Result := Load_GL_ARB_color_buffer_float + else if ext = 'GL_ARB_half_float_pixel' then Result := Load_GL_ARB_half_float_pixel + else if ext = 'GL_ARB_texture_float' then Result := Load_GL_ARB_texture_float + else if ext = 'GL_EXT_texture_compression_dxt1' then Result := Load_GL_EXT_texture_compression_dxt1 + else if ext = 'GL_ARB_pixel_buffer_object' then Result := Load_GL_ARB_pixel_buffer_object + else if ext = 'GL_EXT_framebuffer_object' then Result := Load_GL_EXT_framebuffer_object + else if ext = 'GL_version_1_4' then Result := Load_GL_version_1_4 + else if ext = 'GL_version_1_5' then Result := Load_GL_version_1_5 + else if ext = 'GL_version_2_0' then Result := Load_GL_version_2_0 + +end; +*) + +function Load_GL_VERSION_2_1(): Boolean; +const + funcs: array[0..5] of funcinfoty = + ( + (n: 'glUniformMatrix2x3fv'; d: {$ifndef FPC}@{$endif}@glUniformMatrix2x3fv), + (n: 'glUniformMatrix3x2fv'; d: {$ifndef FPC}@{$endif}@glUniformMatrix3x2fv), + (n: 'glUniformMatrix2x4fv'; d: {$ifndef FPC}@{$endif}@glUniformMatrix2x4fv), + (n: 'glUniformMatrix4x2fv'; d: {$ifndef FPC}@{$endif}@glUniformMatrix4x2fv), + (n: 'glUniformMatrix3x4fv'; d: {$ifndef FPC}@{$endif}@glUniformMatrix3x4fv), + (n: 'glUniformMatrix4x3fv'; d: {$ifndef FPC}@{$endif}@glUniformMatrix4x3fv) + ); +begin + result:= getprocaddresses(libgl,funcs); +end; + +function Load_GL_VERSION_3_0(): Boolean; +const + funcs: array[0..57] of funcinfoty = + ( + (n: 'glColorMaski'; d: {$ifndef FPC}@{$endif}@glColorMaski), + (n: 'glGetBooleani_v'; d: {$ifndef FPC}@{$endif}@glGetBooleani_v), + (n: 'glGetIntegeri_v'; d: {$ifndef FPC}@{$endif}@glGetIntegeri_v), + (n: 'glEnablei'; d: {$ifndef FPC}@{$endif}@glEnablei), + (n: 'glDisablei'; d: {$ifndef FPC}@{$endif}@glDisablei), + (n: 'glIsEnabledi'; d: {$ifndef FPC}@{$endif}@glIsEnabledi), + (n: 'glBeginTransformFeedback'; d: {$ifndef FPC}@{$endif}@glBeginTransformFeedback), + (n: 'glEndTransformFeedback'; d: {$ifndef FPC}@{$endif}@glEndTransformFeedback), + (n: 'glBindBufferRange'; d: {$ifndef FPC}@{$endif}@glBindBufferRange), + (n: 'glBindBufferBase'; d: {$ifndef FPC}@{$endif}@glBindBufferBase), + (n: 'glTransformFeedbackVaryings'; d: {$ifndef FPC}@{$endif}@glTransformFeedbackVaryings), + (n: 'glGetTransformFeedbackVarying'; d: {$ifndef FPC}@{$endif}@glGetTransformFeedbackVarying), + (n: 'glClampColor'; d: {$ifndef FPC}@{$endif}@glClampColor), + (n: 'glBeginConditionalRender'; d: {$ifndef FPC}@{$endif}@glBeginConditionalRender), + (n: 'glEndConditionalRender'; d: {$ifndef FPC}@{$endif}@glEndConditionalRender), + (n: 'glVertexAttribIPointer'; d: {$ifndef FPC}@{$endif}@glVertexAttribIPointer), + (n: 'glGetVertexAttribIiv'; d: {$ifndef FPC}@{$endif}@glGetVertexAttribIiv), + (n: 'glGetVertexAttribIuiv'; d: {$ifndef FPC}@{$endif}@glGetVertexAttribIuiv), + (n: 'glVertexAttribI1i'; d: {$ifndef FPC}@{$endif}@glVertexAttribI1i), + (n: 'glVertexAttribI2i'; d: {$ifndef FPC}@{$endif}@glVertexAttribI2i), + (n: 'glVertexAttribI3i'; d: {$ifndef FPC}@{$endif}@glVertexAttribI3i), + (n: 'glVertexAttribI4i'; d: {$ifndef FPC}@{$endif}@glVertexAttribI4i), + (n: 'glVertexAttribI1ui'; d: {$ifndef FPC}@{$endif}@glVertexAttribI1ui), + (n: 'glVertexAttribI2ui'; d: {$ifndef FPC}@{$endif}@glVertexAttribI2ui), + (n: 'glVertexAttribI3ui'; d: {$ifndef FPC}@{$endif}@glVertexAttribI3ui), + (n: 'glVertexAttribI4ui'; d: {$ifndef FPC}@{$endif}@glVertexAttribI4ui), + (n: 'glVertexAttribI1iv'; d: {$ifndef FPC}@{$endif}@glVertexAttribI1iv), + (n: 'glVertexAttribI2iv'; d: {$ifndef FPC}@{$endif}@glVertexAttribI2iv), + (n: 'glVertexAttribI3iv'; d: {$ifndef FPC}@{$endif}@glVertexAttribI3iv), + (n: 'glVertexAttribI4iv'; d: {$ifndef FPC}@{$endif}@glVertexAttribI4iv), + (n: 'glVertexAttribI1uiv'; d: {$ifndef FPC}@{$endif}@glVertexAttribI1uiv), + (n: 'glVertexAttribI2uiv'; d: {$ifndef FPC}@{$endif}@glVertexAttribI2uiv), + (n: 'glVertexAttribI3uiv'; d: {$ifndef FPC}@{$endif}@glVertexAttribI3uiv), + (n: 'glVertexAttribI4uiv'; d: {$ifndef FPC}@{$endif}@glVertexAttribI4uiv), + (n: 'glVertexAttribI4bv'; d: {$ifndef FPC}@{$endif}@glVertexAttribI4bv), + (n: 'glVertexAttribI4sv'; d: {$ifndef FPC}@{$endif}@glVertexAttribI4sv), + (n: 'glVertexAttribI4ubv'; d: {$ifndef FPC}@{$endif}@glVertexAttribI4ubv), + (n: 'glVertexAttribI4usv'; d: {$ifndef FPC}@{$endif}@glVertexAttribI4usv), + (n: 'glGetUniformuiv'; d: {$ifndef FPC}@{$endif}@glGetUniformuiv), + (n: 'glBindFragDataLocation'; d: {$ifndef FPC}@{$endif}@glBindFragDataLocation), + (n: 'glGetFragDataLocation'; d: {$ifndef FPC}@{$endif}@glGetFragDataLocation), + (n: 'glUniform1ui'; d: {$ifndef FPC}@{$endif}@glUniform1ui), + (n: 'glUniform2ui'; d: {$ifndef FPC}@{$endif}@glUniform2ui), + (n: 'glUniform3ui'; d: {$ifndef FPC}@{$endif}@glUniform3ui), + (n: 'glUniform4ui'; d: {$ifndef FPC}@{$endif}@glUniform4ui), + (n: 'glUniform1uiv'; d: {$ifndef FPC}@{$endif}@glUniform1uiv), + (n: 'glUniform2uiv'; d: {$ifndef FPC}@{$endif}@glUniform2uiv), + (n: 'glUniform3uiv'; d: {$ifndef FPC}@{$endif}@glUniform3uiv), + (n: 'glUniform4uiv'; d: {$ifndef FPC}@{$endif}@glUniform4uiv), + (n: 'glTexParameterIiv'; d: {$ifndef FPC}@{$endif}@glTexParameterIiv), + (n: 'glTexParameterIuiv'; d: {$ifndef FPC}@{$endif}@glTexParameterIuiv), + (n: 'glGetTexParameterIiv'; d: {$ifndef FPC}@{$endif}@glGetTexParameterIiv), + (n: 'glGetTexParameterIuiv'; d: {$ifndef FPC}@{$endif}@glGetTexParameterIuiv), + (n: 'glClearBufferiv'; d: {$ifndef FPC}@{$endif}@glClearBufferiv), + (n: 'glClearBufferuiv'; d: {$ifndef FPC}@{$endif}@glClearBufferuiv), + (n: 'glClearBufferfv'; d: {$ifndef FPC}@{$endif}@glClearBufferfv), + (n: 'glClearBufferfi'; d: {$ifndef FPC}@{$endif}@glClearBufferfi), + (n: 'glGetStringi'; d: {$ifndef FPC}@{$endif}@glGetStringi) + ); +begin + result:= getprocaddresses(libgl,funcs); + result:= result and mseglloadextensions([ + gle_GL_ARB_framebuffer_object, + gle_GL_ARB_map_buffer_range, + gle_GL_ARB_vertex_array_object]); +end; + +function Load_GL_VERSION_3_1(): Boolean; +const + funcs: array[0..3] of funcinfoty = + ( + (n: 'glDrawArraysInstanced'; d: {$ifndef FPC}@{$endif}@glDrawArraysInstanced), + (n: 'glDrawElementsInstanced'; d: {$ifndef FPC}@{$endif}@glDrawElementsInstanced), + (n: 'glTexBuffer'; d: {$ifndef FPC}@{$endif}@glTexBuffer), + (n: 'glPrimitiveRestartIndex'; d: {$ifndef FPC}@{$endif}@glPrimitiveRestartIndex) + ); +begin + result:= getprocaddresses(libgl,funcs); + result:= result and mseglloadextensions([ + gle_GL_ARB_copy_buffer, + gle_GL_ARB_uniform_buffer_object]); +end; + +function Load_GL_VERSION_3_2(): Boolean; +const + funcs: array[0..3] of funcinfoty = + ( + (n: 'glGetInteger64i_v'; d: {$ifndef FPC}@{$endif}@glGetInteger64i_v), + (n: 'glGetBufferParameteri64v'; d: {$ifndef FPC}@{$endif}@glGetBufferParameteri64v), + (n: 'glProgramParameteri'; d: {$ifndef FPC}@{$endif}@glProgramParameteri), + (n: 'glFramebufferTexture'; d: {$ifndef FPC}@{$endif}@glFramebufferTexture) + ); +begin + result:= getprocaddresses(libgl,funcs); + result:= result and mseglloadextensions([ + gle_GL_ARB_draw_elements_base_vertex, + gle_GL_ARB_provoking_vertex, + gle_GL_ARB_sync, + gle_GL_ARB_texture_multisample]); +end; + +function Load_GL_VERSION_3_3(): Boolean; +begin + result:= mseglloadextensions([ + gle_GL_ARB_blend_func_extended, + gle_GL_ARB_sampler_objects, + gle_GL_ARB_timer_query, + gle_GL_ARB_vertex_type_2_10_10_10_rev]); +end; + +function Load_GL_VERSION_4_0(): Boolean; +begin + result:= mseglloadextensions([ + gle_GL_ARB_gpu_shader_fp64, + gle_GL_ARB_shader_subroutine, + gle_GL_ARB_tessellation_shader, + gle_GL_ARB_transform_feedback2, + gle_GL_ARB_transform_feedback3]); +end; + +end. diff --git a/mseide-msegui/lib/common/opengl/mseglextglob.pas b/mseide-msegui/lib/common/opengl/mseglextglob.pas new file mode 100644 index 0000000..8cabad7 --- /dev/null +++ b/mseide-msegui/lib/common/opengl/mseglextglob.pas @@ -0,0 +1,653 @@ +{ MSEgui Copyright (c) 2011-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseglextglob; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msedynload,{msegl,}msesys,{$ifdef FPC}dynlibs,{$else}classes_del,{$endif} + msegraphics,msetypes; + +type + glextensionty = ( + {$ifdef mswindows} + {$else} + gle_glx, + gle_glx_mesa, + {$endif} + gle_GL_version_1_2, + gle_GL_ARB_imaging, + gle_GL_version_1_3, + gle_GL_ARB_multitexture, + gle_GL_ARB_transpose_matrix, + gle_GL_ARB_multisample, + gle_GL_ARB_texture_env_add, +{$IFDEF msWindows} + gle_WGL_ARB_extensions_string, + gle_WGL_ARB_buffer_region, +{$ENDIF} + gle_GL_ARB_texture_cube_map, + gle_GL_ARB_depth_texture, + gle_GL_ARB_point_parameters, + gle_GL_ARB_shadow, + gle_GL_ARB_shadow_ambient, + gle_GL_ARB_texture_border_clamp, + gle_GL_ARB_texture_compression, + gle_GL_ARB_texture_env_combine, + gle_GL_ARB_texture_env_crossbar, + gle_GL_ARB_texture_env_dot3, + gle_GL_ARB_texture_mirrored_repeat, + gle_GL_ARB_vertex_blend, + gle_GL_ARB_vertex_program, + gle_GL_ARB_window_pos, + gle_GL_EXT_422_pixels, + gle_GL_EXT_abgr, + gle_GL_EXT_bgra, + gle_GL_EXT_blend_color, + gle_GL_EXT_blend_func_separate, + gle_GL_EXT_blend_logic_op, + gle_GL_EXT_blend_minmax, + gle_GL_EXT_blend_subtract, + gle_GL_EXT_clip_volume_hint, + gle_GL_EXT_color_subtable, + gle_GL_EXT_compiled_vertex_array, + gle_GL_EXT_convolution, + gle_GL_EXT_fog_coord, + gle_GL_EXT_histogram, + gle_GL_EXT_multi_draw_arrays, + gle_GL_EXT_packed_pixels, + gle_GL_EXT_paletted_texture, + gle_GL_EXT_point_parameters, + gle_GL_EXT_polygon_offset, + gle_GL_EXT_secondary_color, + gle_GL_EXT_separate_specular_color, + gle_GL_EXT_shadow_funcs, + gle_GL_EXT_shared_texture_palette, + gle_GL_EXT_stencil_two_side, + gle_GL_EXT_stencil_wrap, + gle_GL_EXT_subtexture, + gle_GL_EXT_texture3D, + gle_GL_EXT_texture_compression_s3tc, + gle_GL_EXT_texture_env_add, + gle_GL_EXT_texture_env_combine, + gle_GL_EXT_texture_env_dot3, + gle_GL_EXT_texture_filter_anisotropic, + gle_GL_EXT_texture_lod_bias, + gle_GL_EXT_texture_object, + gle_GL_EXT_vertex_array, + gle_GL_EXT_vertex_shader, + gle_GL_EXT_vertex_weighting, + gle_GL_HP_occlusion_test, + gle_GL_NV_blend_square, + gle_GL_NV_copy_depth_to_color, + gle_GL_NV_depth_clamp, + gle_GL_NV_evaluators, + gle_GL_NV_fence, + gle_GL_NV_fog_distance, + gle_GL_NV_light_max_exponent, + gle_GL_NV_multisample_filter_hint, + gle_GL_NV_occlusion_query, + gle_GL_NV_packed_depth_stencil, + gle_GL_NV_point_sprite, + gle_GL_NV_register_combiners, + gle_GL_NV_register_combiners2, + gle_GL_NV_texgen_emboss, + gle_GL_NV_texgen_reflection, + gle_GL_NV_texture_compression_vtc, + gle_GL_NV_texture_env_combine4, + gle_GL_NV_texture_rectangle, + gle_GL_NV_texture_shader, + gle_GL_NV_texture_shader2, + gle_GL_NV_texture_shader3, + gle_GL_NV_vertex_array_range, + gle_GL_NV_vertex_array_range2, + gle_GL_NV_vertex_program, + gle_GL_NV_vertex_program1_1, + gle_GL_ATI_element_array, + gle_GL_ATI_envmap_bumpmap, + gle_GL_ATI_fragment_shader, + gle_GL_ATI_pn_triangles, + gle_GL_ATI_texture_mirror_once, + gle_GL_ATI_vertex_array_object, + gle_GL_ATI_vertex_streams, +{$IFDEF msWindows} + gle_WGL_I3D_image_buffer, + gle_WGL_I3D_swap_frame_lock, + gle_WGL_I3D_swap_frame_usage, +{$ENDIF} + gle_GL_3DFX_texture_compression_FXT1, + gle_GL_IBM_cull_vertex, + gle_GL_IBM_multimode_draw_arrays, + gle_GL_IBM_raster_pos_clip, + gle_GL_IBM_texture_mirrored_repeat, + gle_GL_IBM_vertex_array_lists, + gle_GL_MESA_resize_buffers, + gle_GL_MESA_window_pos, + gle_GL_OML_interlace, + gle_GL_OML_resample, + gle_GL_OML_subsample, + gle_GL_SGIS_generate_mipmap, + gle_GL_SGIS_multisample, + gle_GL_SGIS_pixel_texture, + gle_GL_SGIS_texture_border_clamp, + gle_GL_SGIS_texture_color_mask, + gle_GL_SGIS_texture_edge_clamp, + gle_GL_SGIS_texture_lod, + gle_GL_SGIS_depth_texture, + gle_GL_SGIX_fog_offset, + gle_GL_SGIX_interlace, + gle_GL_SGIX_shadow_ambient, + gle_GL_SGI_color_matrix, + gle_GL_SGI_color_table, + gle_GL_SGI_texture_color_table, + gle_GL_SUN_vertex, + gle_GL_ARB_fragment_program, + gle_GL_ATI_text_fragment_shader, + gle_GL_APPLE_client_storage, + gle_GL_APPLE_element_array, + gle_GL_APPLE_fence, + gle_GL_APPLE_vertex_array_object, + gle_GL_APPLE_vertex_array_range, +{$IFDEF msWindows} + gle_WGL_ARB_pixel_format, + gle_WGL_ARB_make_current_read, + gle_WGL_ARB_pbuffer, + gle_WGL_EXT_swap_control, + gle_WGL_ARB_render_texture, + gle_WGL_EXT_extensions_string, + gle_WGL_EXT_make_current_read, + gle_WGL_EXT_pbuffer, + gle_WGL_EXT_pixel_format, + gle_WGL_I3D_digital_video_control, + gle_WGL_I3D_gamma, + gle_WGL_I3D_genlock, +{$ENDIF} + gle_GL_ARB_matrix_palette, + gle_GL_NV_element_array, + gle_GL_NV_float_buffer, + gle_GL_NV_fragment_program, + gle_GL_NV_primitive_restart, + gle_GL_NV_vertex_program2, + {$IFDEF msWindows} + gle_WGL_NV_render_texture_rectangle, + {$ENDIF} + gle_GL_NV_pixel_data_range, + gle_GL_EXT_texture_rectangle, + gle_GL_S3_s3tc, + gle_GL_ATI_draw_buffers, + {$IFDEF msWindows} + gle_WGL_ATI_pixel_format_float, + {$ENDIF} + gle_GL_ATI_texture_env_combine3, + gle_GL_ATI_texture_float, + gle_GL_NV_texture_expand_normal, + gle_GL_NV_half_float, + gle_GL_ATI_map_object_buffer, + gle_GL_ATI_separate_stencil, + gle_GL_ATI_vertex_attrib_array_object, + gle_GL_ARB_vertex_buffer_object, + gle_GL_ARB_occlusion_query, + gle_GL_ARB_shader_objects, + gle_GL_ARB_vertex_shader, + gle_GL_ARB_fragment_shader, + gle_GL_ARB_shading_language_100, + gle_GL_ARB_texture_non_power_of_two, + gle_GL_ARB_point_sprite, + gle_GL_EXT_depth_bounds_test, + gle_GL_EXT_texture_mirror_clamp, + gle_GL_EXT_blend_equation_separate, + gle_GL_MESA_pack_invert, + gle_GL_MESA_ycbcr_texture, + gle_GL_ARB_fragment_program_shadow, + gle_GL_NV_fragment_program_option, + gle_GL_EXT_pixel_buffer_object, + gle_GL_NV_fragment_program2, + gle_GL_NV_vertex_program2_option, + gle_GL_NV_vertex_program3, + gle_GL_ARB_draw_buffers, + gle_GL_ARB_texture_rectangle, + gle_GL_ARB_color_buffer_float, + gle_GL_ARB_half_float_pixel, + gle_GL_ARB_texture_float, + gle_GL_EXT_texture_compression_dxt1, + gle_GL_ARB_pixel_buffer_object, + gle_GL_EXT_framebuffer_object, + gle_GL_ARB_framebuffer_object, + gle_GL_ARB_map_buffer_range, + gle_GL_ARB_vertex_array_object, + gle_GL_ARB_copy_buffer, + gle_GL_ARB_uniform_buffer_object, + gle_GL_ARB_draw_elements_base_vertex, + gle_GL_ARB_provoking_vertex, + gle_GL_ARB_sync, + gle_GL_ARB_texture_multisample, + gle_GL_ARB_blend_func_extended, + gle_GL_ARB_sampler_objects, + gle_GL_ARB_timer_query, + gle_GL_ARB_vertex_type_2_10_10_10_rev, + gle_GL_ARB_gpu_shader_fp64, + gle_GL_ARB_shader_subroutine, + gle_GL_ARB_tessellation_shader, + gle_GL_ARB_transform_feedback2, + gle_GL_ARB_transform_feedback3, + gle_GL_version_1_4, + gle_GL_version_1_5, + gle_GL_version_2_0, + gle_GL_version_2_1, + gle_GL_version_3_0, + gle_GL_version_3_1, + gle_GL_version_3_2, + gle_GL_version_3_3, + gle_GL_version_4_0 + ); + glextensionsty = set of glextensionty; + +function mseglparseextensions(const astr: pchar): glextensionsty; +function gldeviceextensions(const device: ptruint): glextensionsty; +function mseglloadextensions(const extensions: array of glextensionty): boolean; + //true if ok +var + libgl: tlibhandle; + +procedure init(); //do not use, automatically called by msegl + +implementation +uses + msegl,mseglext,msestrings{$ifdef mswindows}{$else}, + mseglx,mseguiintf{$endif}, + mseglu; + +type + glextloaderty = function: boolean; + + glextensioninfoty = record + name: string; + loader: glextloaderty; + end; +var + loadedextensions: glextensionsty; + badextensions: glextensionsty; + +function gldeviceextensions(const device: ptruint): glextensionsty; +begin + result:= []; +{$ifdef mswindows} + if mseglloadextensions([gle_WGL_EXT_extensions_string]) then begin + result:= result + mseglparseextensions(wglGetExtensionsStringEXT()); + end; + if mseglloadextensions([gle_WGL_ARB_extensions_string]) then begin + result:= result + mseglparseextensions(wglGetExtensionsStringARB(device)); + end; +{$else} + if {$ifndef FPC}@{$endif}glxqueryextensionsstring <> nil then begin + result:= mseglparseextensions( + glxqueryextensionsstring(msedisplay,msedefaultscreenno)); + end; +{$endif} +end; + +procedure initglext(const ainfo: dynlibinfoty); +begin + libgl:= ainfo.libhandle; + initializeglu([]); +end; + +procedure deinitglext(const ainfo: dynlibinfoty); +begin + loadedextensions:= []; + badextensions:= []; + releaseglu; +end; + +function l_GL_version_1_2: boolean; +begin + result:= load_GL_version_1_2; +end; + +function l_GL_version_1_3: boolean; +begin + result:= mseglloadextensions([gle_GL_version_1_2]) and load_GL_version_1_3; +end; + +function l_GL_version_1_4: boolean; +begin + result:= mseglloadextensions([gle_GL_version_1_3]) and load_GL_version_1_4; +end; + +function l_GL_version_1_5: boolean; +begin + result:= mseglloadextensions([gle_GL_version_1_4]) and load_GL_version_1_5; +end; + +function l_GL_version_2_0: boolean; +begin + result:= mseglloadextensions([gle_GL_version_1_5]) and load_GL_version_2_0; +end; + +function l_GL_version_2_1: boolean; +begin + result:= mseglloadextensions([gle_GL_version_2_0]) and load_GL_version_2_1; +end; + +function l_GL_version_3_0: boolean; +begin + result:= mseglloadextensions([gle_GL_version_2_1]) and load_GL_version_3_0; +end; + +function l_GL_version_3_1: boolean; +begin + result:= mseglloadextensions([gle_GL_version_3_0]) and load_GL_version_3_1; +end; + +function l_GL_version_3_2: boolean; +begin + result:= mseglloadextensions([gle_GL_version_3_1]) and load_GL_version_3_2; +end; + +function l_GL_version_3_3: boolean; +begin + result:= mseglloadextensions([gle_GL_version_3_2]) and load_GL_version_3_3; +end; + +function l_GL_version_4_0: boolean; +begin + result:= mseglloadextensions([gle_GL_version_3_3]) and load_GL_version_4_0; +end; + +const + glextensions: array[glextensionty] of glextensioninfoty = + ( + {$ifdef mswindows} + {$else} + (name: 'glx'; loader: {$ifdef FPC}@{$endif}load_glx), + (name: 'glx_mesa'; loader: {$ifdef FPC}@{$endif}load_glx_mesa), + {$endif} + (name: 'GL_version_1_2'; loader: {$ifdef FPC}@{$endif}l_GL_version_1_2), + (name: 'GL_ARB_imaging'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_imaging), + (name: 'GL_version_1_3'; loader: {$ifdef FPC}@{$endif}l_GL_version_1_3), + (name: 'GL_ARB_multitexture'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_multitexture), + (name: 'GL_ARB_transpose_matrix'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_transpose_matrix), + (name: 'GL_ARB_multisample'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_multisample), + (name: 'GL_ARB_texture_env_add'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_texture_env_add), +{$IFDEF msWindows} + (name: 'WGL_ARB_extensions_string'; loader: {$ifdef FPC}@{$endif}load_WGL_ARB_extensions_string), + (name: 'WGL_ARB_buffer_region'; loader: {$ifdef FPC}@{$endif}load_WGL_ARB_buffer_region), +{$ENDIF} + (name: 'GL_ARB_texture_cube_map'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_texture_cube_map), + (name: 'GL_ARB_depth_texture'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_depth_texture), + (name: 'GL_ARB_point_parameters'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_point_parameters), + (name: 'GL_ARB_shadow'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_shadow), + (name: 'GL_ARB_shadow_ambient'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_shadow_ambient), + (name: 'GL_ARB_texture_border_clamp'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_texture_border_clamp), + (name: 'GL_ARB_texture_compression'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_texture_compression), + (name: 'GL_ARB_texture_env_combine'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_texture_env_combine), + (name: 'GL_ARB_texture_env_crossbar'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_texture_env_crossbar), + (name: 'GL_ARB_texture_env_dot3'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_texture_env_dot3), + (name: 'GL_ARB_texture_mirrored_repeat'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_texture_mirrored_repeat), + (name: 'GL_ARB_vertex_blend'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_vertex_blend), + (name: 'GL_ARB_vertex_program'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_vertex_program), + (name: 'GL_ARB_window_pos'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_window_pos), + (name: 'GL_EXT_422_pixels'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_422_pixels), + (name: 'GL_EXT_abgr'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_abgr), + (name: 'GL_EXT_bgra'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_bgra), + (name: 'GL_EXT_blend_color'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_blend_color), + (name: 'GL_EXT_blend_func_separate'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_blend_func_separate), + (name: 'GL_EXT_blend_logic_op'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_blend_logic_op), + (name: 'GL_EXT_blend_minmax'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_blend_minmax), + (name: 'GL_EXT_blend_subtract'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_blend_subtract), + (name: 'GL_EXT_clip_volume_hint'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_clip_volume_hint), + (name: 'GL_EXT_color_subtable'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_color_subtable), + (name: 'GL_EXT_compiled_vertex_array'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_compiled_vertex_array), + (name: 'GL_EXT_convolution'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_convolution), + (name: 'GL_EXT_fog_coord'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_fog_coord), + (name: 'GL_EXT_histogram'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_histogram), + (name: 'GL_EXT_multi_draw_arrays'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_multi_draw_arrays), + (name: 'GL_EXT_packed_pixels'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_packed_pixels), + (name: 'GL_EXT_paletted_texture'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_paletted_texture), + (name: 'GL_EXT_point_parameters'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_point_parameters), + (name: 'GL_EXT_polygon_offset'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_polygon_offset), + (name: 'GL_EXT_secondary_color'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_secondary_color), + (name: 'GL_EXT_separate_specular_color'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_separate_specular_color), + (name: 'GL_EXT_shadow_funcs'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_shadow_funcs), + (name: 'GL_EXT_shared_texture_palette'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_shared_texture_palette), + (name: 'GL_EXT_stencil_two_side'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_stencil_two_side), + (name: 'GL_EXT_stencil_wrap'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_stencil_wrap), + (name: 'GL_EXT_subtexture'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_subtexture), + (name: 'GL_EXT_texture3D'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_texture3D), + (name: 'GL_EXT_texture_compression_s3tc'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_texture_compression_s3tc), + (name: 'GL_EXT_texture_env_add'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_texture_env_add), + (name: 'GL_EXT_texture_env_combine'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_texture_env_combine), + (name: 'GL_EXT_texture_env_dot3'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_texture_env_dot3), + (name: 'GL_EXT_texture_filter_anisotropic'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_texture_filter_anisotropic), + (name: 'GL_EXT_texture_lod_bias'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_texture_lod_bias), + (name: 'GL_EXT_texture_object'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_texture_object), + (name: 'GL_EXT_vertex_array'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_vertex_array), + (name: 'GL_EXT_vertex_shader'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_vertex_shader), + (name: 'GL_EXT_vertex_weighting'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_vertex_weighting), + (name: 'GL_HP_occlusion_test'; loader: {$ifdef FPC}@{$endif}load_GL_HP_occlusion_test), + (name: 'GL_NV_blend_square'; loader: {$ifdef FPC}@{$endif}load_GL_NV_blend_square), + (name: 'GL_NV_copy_depth_to_color'; loader: {$ifdef FPC}@{$endif}load_GL_NV_copy_depth_to_color), + (name: 'GL_NV_depth_clamp'; loader: {$ifdef FPC}@{$endif}load_GL_NV_depth_clamp), + (name: 'GL_NV_evaluators'; loader: {$ifdef FPC}@{$endif}load_GL_NV_evaluators), + (name: 'GL_NV_fence'; loader: {$ifdef FPC}@{$endif}load_GL_NV_fence), + (name: 'GL_NV_fog_distance'; loader: {$ifdef FPC}@{$endif}load_GL_NV_fog_distance), + (name: 'GL_NV_light_max_exponent'; loader: {$ifdef FPC}@{$endif}load_GL_NV_light_max_exponent), + (name: 'GL_NV_multisample_filter_hint'; loader: {$ifdef FPC}@{$endif}load_GL_NV_multisample_filter_hint), + (name: 'GL_NV_occlusion_query'; loader: {$ifdef FPC}@{$endif}load_GL_NV_occlusion_query), + (name: 'GL_NV_packed_depth_stencil'; loader: {$ifdef FPC}@{$endif}load_GL_NV_packed_depth_stencil), + (name: 'GL_NV_point_sprite'; loader: {$ifdef FPC}@{$endif}load_GL_NV_point_sprite), + (name: 'GL_NV_register_combiners'; loader: {$ifdef FPC}@{$endif}load_GL_NV_register_combiners), + (name: 'GL_NV_register_combiners2'; loader: {$ifdef FPC}@{$endif}load_GL_NV_register_combiners2), + (name: 'GL_NV_texgen_emboss'; loader: {$ifdef FPC}@{$endif}load_GL_NV_texgen_emboss), + (name: 'GL_NV_texgen_reflection'; loader: {$ifdef FPC}@{$endif}load_GL_NV_texgen_reflection), + (name: 'GL_NV_texture_compression_vtc'; loader: {$ifdef FPC}@{$endif}load_GL_NV_texture_compression_vtc), + (name: 'GL_NV_texture_env_combine4'; loader: {$ifdef FPC}@{$endif}load_GL_NV_texture_env_combine4), + (name: 'GL_NV_texture_rectangle'; loader: {$ifdef FPC}@{$endif}load_GL_NV_texture_rectangle), + (name: 'GL_NV_texture_shader'; loader: {$ifdef FPC}@{$endif}load_GL_NV_texture_shader), + (name: 'GL_NV_texture_shader2'; loader: {$ifdef FPC}@{$endif}load_GL_NV_texture_shader2), + (name: 'GL_NV_texture_shader3'; loader: {$ifdef FPC}@{$endif}load_GL_NV_texture_shader3), + (name: 'GL_NV_vertex_array_range'; loader: {$ifdef FPC}@{$endif}load_GL_NV_vertex_array_range), + (name: 'GL_NV_vertex_array_range2'; loader: {$ifdef FPC}@{$endif}load_GL_NV_vertex_array_range2), + (name: 'GL_NV_vertex_program'; loader: {$ifdef FPC}@{$endif}load_GL_NV_vertex_program), + (name: 'GL_NV_vertex_program1_1'; loader: {$ifdef FPC}@{$endif}load_GL_NV_vertex_program1_1), + (name: 'GL_ATI_element_array'; loader: {$ifdef FPC}@{$endif}load_GL_ATI_element_array), + (name: 'GL_ATI_envmap_bumpmap'; loader: {$ifdef FPC}@{$endif}load_GL_ATI_envmap_bumpmap), + (name: 'GL_ATI_fragment_shader'; loader: {$ifdef FPC}@{$endif}load_GL_ATI_fragment_shader), + (name: 'GL_ATI_pn_triangles'; loader: {$ifdef FPC}@{$endif}load_GL_ATI_pn_triangles), + (name: 'GL_ATI_texture_mirror_once'; loader: {$ifdef FPC}@{$endif}load_GL_ATI_texture_mirror_once), + (name: 'GL_ATI_vertex_array_object'; loader: {$ifdef FPC}@{$endif}load_GL_ATI_vertex_array_object), + (name: 'GL_ATI_vertex_streams'; loader: {$ifdef FPC}@{$endif}load_GL_ATI_vertex_streams), +{$IFDEF msWindows} + (name: 'WGL_I3D_image_buffer'; loader: {$ifdef FPC}@{$endif}load_WGL_I3D_image_buffer), + (name: 'WGL_I3D_swap_frame_lock'; loader: {$ifdef FPC}@{$endif}load_WGL_I3D_swap_frame_lock), + (name: 'WGL_I3D_swap_frame_usage'; loader: {$ifdef FPC}@{$endif}load_WGL_I3D_swap_frame_usage), +{$ENDIF} + (name: 'GL_3DFX_texture_compression_FXT1'; loader: {$ifdef FPC}@{$endif}load_GL_3DFX_texture_compression_FXT1), + (name: 'GL_IBM_cull_vertex'; loader: {$ifdef FPC}@{$endif}load_GL_IBM_cull_vertex), + (name: 'GL_IBM_multimode_draw_arrays'; loader: {$ifdef FPC}@{$endif}load_GL_IBM_multimode_draw_arrays), + (name: 'GL_IBM_raster_pos_clip'; loader: {$ifdef FPC}@{$endif}load_GL_IBM_raster_pos_clip), + (name: 'GL_IBM_texture_mirrored_repeat'; loader: {$ifdef FPC}@{$endif}load_GL_IBM_texture_mirrored_repeat), + (name: 'GL_IBM_vertex_array_lists'; loader: {$ifdef FPC}@{$endif}load_GL_IBM_vertex_array_lists), + (name: 'GL_MESA_resize_buffers'; loader: {$ifdef FPC}@{$endif}load_GL_MESA_resize_buffers), + (name: 'GL_MESA_window_pos'; loader: {$ifdef FPC}@{$endif}load_GL_MESA_window_pos), + (name: 'GL_OML_interlace'; loader: {$ifdef FPC}@{$endif}load_GL_OML_interlace), + (name: 'GL_OML_resample'; loader: {$ifdef FPC}@{$endif}load_GL_OML_resample), + (name: 'GL_OML_subsample'; loader: {$ifdef FPC}@{$endif}load_GL_OML_subsample), + (name: 'GL_SGIS_generate_mipmap'; loader: {$ifdef FPC}@{$endif}load_GL_SGIS_generate_mipmap), + (name: 'GL_SGIS_multisample'; loader: {$ifdef FPC}@{$endif}load_GL_SGIS_multisample), + (name: 'GL_SGIS_pixel_texture'; loader: {$ifdef FPC}@{$endif}load_GL_SGIS_pixel_texture), + (name: 'GL_SGIS_texture_border_clamp'; loader: {$ifdef FPC}@{$endif}load_GL_SGIS_texture_border_clamp), + (name: 'GL_SGIS_texture_color_mask'; loader: {$ifdef FPC}@{$endif}load_GL_SGIS_texture_color_mask), + (name: 'GL_SGIS_texture_edge_clamp'; loader: {$ifdef FPC}@{$endif}load_GL_SGIS_texture_edge_clamp), + (name: 'GL_SGIS_texture_lod'; loader: {$ifdef FPC}@{$endif}load_GL_SGIS_texture_lod), + (name: 'GL_SGIS_depth_texture'; loader: {$ifdef FPC}@{$endif}load_GL_SGIS_depth_texture), + (name: 'GL_SGIX_fog_offset'; loader: {$ifdef FPC}@{$endif}load_GL_SGIX_fog_offset), + (name: 'GL_SGIX_interlace'; loader: {$ifdef FPC}@{$endif}load_GL_SGIX_interlace), + (name: 'GL_SGIX_shadow_ambient'; loader: {$ifdef FPC}@{$endif}load_GL_SGIX_shadow_ambient), + (name: 'GL_SGI_color_matrix'; loader: {$ifdef FPC}@{$endif}load_GL_SGI_color_matrix), + (name: 'GL_SGI_color_table'; loader: {$ifdef FPC}@{$endif}load_GL_SGI_color_table), + (name: 'GL_SGI_texture_color_table'; loader: {$ifdef FPC}@{$endif}load_GL_SGI_texture_color_table), + (name: 'GL_SUN_vertex'; loader: {$ifdef FPC}@{$endif}load_GL_SUN_vertex), + (name: 'GL_ARB_fragment_program'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_fragment_program), + (name: 'GL_ATI_text_fragment_shader'; loader: {$ifdef FPC}@{$endif}load_GL_ATI_text_fragment_shader), + (name: 'GL_APPLE_client_storage'; loader: {$ifdef FPC}@{$endif}load_GL_APPLE_client_storage), + (name: 'GL_APPLE_element_array'; loader: {$ifdef FPC}@{$endif}load_GL_APPLE_element_array), + (name: 'GL_APPLE_fence'; loader: {$ifdef FPC}@{$endif}load_GL_APPLE_fence), + (name: 'GL_APPLE_vertex_array_object'; loader: {$ifdef FPC}@{$endif}load_GL_APPLE_vertex_array_object), + (name: 'GL_APPLE_vertex_array_range'; loader: {$ifdef FPC}@{$endif}load_GL_APPLE_vertex_array_range), +{$IFDEF msWindows} + (name: 'WGL_ARB_pixel_format'; loader: {$ifdef FPC}@{$endif}load_WGL_ARB_pixel_format), + (name: 'WGL_ARB_make_current_read'; loader: {$ifdef FPC}@{$endif}load_WGL_ARB_make_current_read), + (name: 'WGL_ARB_pbuffer'; loader: {$ifdef FPC}@{$endif}load_WGL_ARB_pbuffer), + (name: 'WGL_EXT_swap_control'; loader: {$ifdef FPC}@{$endif}load_WGL_EXT_swap_control), + (name: 'WGL_ARB_render_texture'; loader: {$ifdef FPC}@{$endif}load_WGL_ARB_render_texture), + (name: 'WGL_EXT_extensions_string'; loader: {$ifdef FPC}@{$endif}load_WGL_EXT_extensions_string), + (name: 'WGL_EXT_make_current_read'; loader: {$ifdef FPC}@{$endif}load_WGL_EXT_make_current_read), + (name: 'WGL_EXT_pbuffer'; loader: {$ifdef FPC}@{$endif}load_WGL_EXT_pbuffer), + (name: 'WGL_EXT_pixel_format'; loader: {$ifdef FPC}@{$endif}load_WGL_EXT_pixel_format), + (name: 'WGL_I3D_digital_video_control'; loader: {$ifdef FPC}@{$endif}load_WGL_I3D_digital_video_control), + (name: 'WGL_I3D_gamma'; loader: {$ifdef FPC}@{$endif}load_WGL_I3D_gamma), + (name: 'WGL_I3D_genlock'; loader: {$ifdef FPC}@{$endif}load_WGL_I3D_genlock), +{$ENDIF} + (name: 'GL_ARB_matrix_palette'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_matrix_palette), + (name: 'GL_NV_element_array'; loader: {$ifdef FPC}@{$endif}load_GL_NV_element_array), + (name: 'GL_NV_float_buffer'; loader: {$ifdef FPC}@{$endif}load_GL_NV_float_buffer), + (name: 'GL_NV_fragment_program'; loader: {$ifdef FPC}@{$endif}load_GL_NV_fragment_program), + (name: 'GL_NV_primitive_restart'; loader: {$ifdef FPC}@{$endif}load_GL_NV_primitive_restart), + (name: 'GL_NV_vertex_program2'; loader: {$ifdef FPC}@{$endif}load_GL_NV_vertex_program2), + {$IFDEF msWindows} + (name: 'WGL_NV_render_texture_rectangle'; loader: {$ifdef FPC}@{$endif}load_WGL_NV_render_texture_rectangle), + {$ENDIF} + (name: 'GL_NV_pixel_data_range'; loader: {$ifdef FPC}@{$endif}load_GL_NV_pixel_data_range), + (name: 'GL_EXT_texture_rectangle'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_texture_rectangle), + (name: 'GL_S3_s3tc'; loader: {$ifdef FPC}@{$endif}load_GL_S3_s3tc), + (name: 'GL_ATI_draw_buffers'; loader: {$ifdef FPC}@{$endif}load_GL_ATI_draw_buffers), + {$IFDEF msWindows} + (name: 'WGL_ATI_pixel_format_float'; loader: {$ifdef FPC}@{$endif}load_WGL_ATI_pixel_format_float), + {$ENDIF} + (name: 'GL_ATI_texture_env_combine3'; loader: {$ifdef FPC}@{$endif}load_GL_ATI_texture_env_combine3), + (name: 'GL_ATI_texture_float'; loader: {$ifdef FPC}@{$endif}load_GL_ATI_texture_float), + (name: 'GL_NV_texture_expand_normal'; loader: {$ifdef FPC}@{$endif}load_GL_NV_texture_expand_normal), + (name: 'GL_NV_half_float'; loader: {$ifdef FPC}@{$endif}load_GL_NV_half_float), + (name: 'GL_ATI_map_object_buffer'; loader: {$ifdef FPC}@{$endif}load_GL_ATI_map_object_buffer), + (name: 'GL_ATI_separate_stencil'; loader: {$ifdef FPC}@{$endif}load_GL_ATI_separate_stencil), + (name: 'GL_ATI_vertex_attrib_array_object'; loader: {$ifdef FPC}@{$endif}load_GL_ATI_vertex_attrib_array_object), + (name: 'GL_ARB_vertex_buffer_object'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_vertex_buffer_object), + (name: 'GL_ARB_occlusion_query'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_occlusion_query), + (name: 'GL_ARB_shader_objects'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_shader_objects), + (name: 'GL_ARB_vertex_shader'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_vertex_shader), + (name: 'GL_ARB_fragment_shader'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_fragment_shader), + (name: 'GL_ARB_shading_language_100'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_shading_language_100), + (name: 'GL_ARB_texture_non_power_of_two'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_texture_non_power_of_two), + (name: 'GL_ARB_point_sprite'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_point_sprite), + (name: 'GL_EXT_depth_bounds_test'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_depth_bounds_test), + (name: 'GL_EXT_texture_mirror_clamp'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_texture_mirror_clamp), + (name: 'GL_EXT_blend_equation_separate'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_blend_equation_separate), + (name: 'GL_MESA_pack_invert'; loader: {$ifdef FPC}@{$endif}load_GL_MESA_pack_invert), + (name: 'GL_MESA_ycbcr_texture'; loader: {$ifdef FPC}@{$endif}load_GL_MESA_ycbcr_texture), + (name: 'GL_ARB_fragment_program_shadow'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_fragment_program_shadow), + (name: 'GL_NV_fragment_program_option'; loader: {$ifdef FPC}@{$endif}load_GL_NV_fragment_program_option), + (name: 'GL_EXT_pixel_buffer_object'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_pixel_buffer_object), + (name: 'GL_NV_fragment_program2'; loader: {$ifdef FPC}@{$endif}load_GL_NV_fragment_program2), + (name: 'GL_NV_vertex_program2_option'; loader: {$ifdef FPC}@{$endif}load_GL_NV_vertex_program2_option), + (name: 'GL_NV_vertex_program3'; loader: {$ifdef FPC}@{$endif}load_GL_NV_vertex_program3), + (name: 'GL_ARB_draw_buffers'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_draw_buffers), + (name: 'GL_ARB_texture_rectangle'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_texture_rectangle), + (name: 'GL_ARB_color_buffer_float'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_color_buffer_float), + (name: 'GL_ARB_half_float_pixel'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_half_float_pixel), + (name: 'GL_ARB_texture_float'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_texture_float), + (name: 'GL_EXT_texture_compression_dxt1'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_texture_compression_dxt1), + (name: 'GL_ARB_pixel_buffer_object'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_pixel_buffer_object), + (name: 'GL_EXT_framebuffer_object'; loader: {$ifdef FPC}@{$endif}load_GL_EXT_framebuffer_object), + (name: 'GL_ARB_framebuffer_object'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_framebuffer_object), + (name: 'GL_ARB_map_buffer_range'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_map_buffer_range), + (name: 'GL_ARB_vertex_array_object'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_vertex_array_object), + (name: 'GL_ARB_copy_buffer'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_copy_buffer), + (name: 'GL_ARB_uniform_buffer_object'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_uniform_buffer_object), + (name: 'GL_ARB_draw_elements_base_vertex'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_draw_elements_base_vertex), + (name: 'GL_ARB_provoking_vertex'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_provoking_vertex), + (name: 'GL_ARB_sync'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_sync), + (name: 'GL_ARB_texture_multisample'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_texture_multisample), + (name: 'GL_ARB_blend_func_extended'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_blend_func_extended), + (name: 'GL_ARB_sampler_objects'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_sampler_objects), + (name: 'GL_ARB_timer_query'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_timer_query), + (name: 'GL_ARB_vertex_type_2_10_10_10_rev'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_vertex_type_2_10_10_10_rev), + (name: 'GL_ARB_gpu_shader_fp64'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_gpu_shader_fp64), + (name: 'GL_ARB_shader_subroutine'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_shader_subroutine), + (name: 'GL_ARB_tessellation_shader'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_tessellation_shader), + (name: 'GL_ARB_transform_feedback2'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_transform_feedback2), + (name: 'GL_ARB_transform_feedback3'; loader: {$ifdef FPC}@{$endif}load_GL_ARB_transform_feedback3), + (name: 'GL_version_1_4'; loader: {$ifdef FPC}@{$endif}l_GL_version_1_4), + (name: 'GL_version_1_5'; loader: {$ifdef FPC}@{$endif}l_GL_version_1_5), + (name: 'GL_version_2_0'; loader: {$ifdef FPC}@{$endif}l_GL_version_2_0), + (name: 'GL_version_2_1'; loader: {$ifdef FPC}@{$endif}l_GL_version_2_1), + (name: 'GL_version_3_0'; loader: {$ifdef FPC}@{$endif}l_GL_version_3_0), + (name: 'GL_version_3_1'; loader: {$ifdef FPC}@{$endif}l_GL_version_3_1), + (name: 'GL_version_3_2'; loader: {$ifdef FPC}@{$endif}l_GL_version_3_2), + (name: 'GL_version_3_3'; loader: {$ifdef FPC}@{$endif}l_GL_version_3_3), + (name: 'GL_version_4_0'; loader: {$ifdef FPC}@{$endif}l_GL_version_4_0) + ); + +function mseglparseextensions(const astr: pchar): glextensionsty; +var + ar1: stringarty; + int1: integer; + str1: string; + ext1: glextensionty; +begin + result:= []; + ar1:= splitstring(astr,' '); + for int1:= 0 to high(ar1) do begin + for ext1:= low(ext1) to high(ext1) do begin + pointer(str1):= pointer(ar1[int1]); //no refcount + if glextensions[ext1].name = str1 then begin + include(result,ext1); + break; + end; + end; + end; +end; + +function mseglloadextensions(const extensions: array of glextensionty): boolean; +var + int1: integer; + ext: glextensionty; +begin + result:= true; + for int1:= 0 to high(extensions) do begin + ext:= extensions[int1]; + if ext in badextensions then begin + result:= false; + end + else begin + if not (ext in loadedextensions) then begin + if glextensions[ext].loader() then begin + include(loadedextensions,ext); + end + else begin + include(badextensions,ext); + result:= false; + end; + end; + end; + end; +end; + +procedure init(); +begin + regglinit(@initglext); + reggldeinit(@deinitglext); +end; + +initialization +// regglinit(@initglext); //msegl not yet initialized +// reggldeinit(@deinitglext); +end. \ No newline at end of file diff --git a/mseide-msegui/lib/common/opengl/mseglu.pas b/mseide-msegui/lib/common/opengl/mseglu.pas new file mode 100644 index 0000000..9e08c5b --- /dev/null +++ b/mseide-msegui/lib/common/opengl/mseglu.pas @@ -0,0 +1,487 @@ +{ + + Adaption of the delphi3d.net OpenGL units to FreePascal + Sebastian Guenther (sg@freepascal.org) in 2002 + These units are free to use +} +// +// modified 2011 by Martin Schreiber +// +{*++ BUILD Version: 0004 // Increment this if a change has global effects + +Copyright (c) 1985-95, Microsoft Corporation + +Module Name: + + glu.h + +Abstract: + + Procedure declarations, constant definitions and macros for the OpenGL + Utility Library. + +--*} + +{* +** Copyright 1991-1993, Silicon Graphics, Inc. +** All Rights Reserved. +** +** This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.; +** the contents of this file may not be disclosed to third parties, copied or +** duplicated in any form, in whole or in part, without the prior written +** permission of Silicon Graphics, Inc. +** +** RESTRICTED RIGHTS LEGEND: +** Use, duplication or disclosure by the Government is subject to restrictions +** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data +** and Computer Software clause at DFARS 252.227-7013, and/or in similar or +** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished - +** rights reserved under the Copyright Laws of the United States. +*} + +{* +** Return the error string associated with a particular error code. +** This will return 0 for an invalid error code. +** +** The generic function prototype that can be compiled for ANSI or Unicode +** is defined as follows: +** +** LPCTSTR APIENTRY gluErrorStringWIN (GLenum errCode); +*} + +{******************************************************************************} +{ Converted to Delphi by Tom Nuydens (tom@delphi3d.net) } +{ For the latest updates, visit Delphi3D: http://www.delphi3d.net } +{******************************************************************************} + +{$ifdef FPC}{$mode objfpc} {$h+}{$MACRO ON}{$endif} +//{$MODE Delphi} +{$IFDEF msWindows} + {$define wincall} +// {$DEFINE extdecl := stdcall} +{$ELSE} +// {$DEFINE extdecl := cdecl} +{$ENDIF} + +{$IFDEF MORPHOS} +{$INLINE ON} +{$DEFINE GLU_UNIT} +{$ENDIF} + +unit mseglu; + +interface + +uses + SysUtils, + {$IFDEF msWindows} + Windows, + {$ELSE} + {$IFDEF MORPHOS} + TinyGL, + {$ENDIF} + {$ENDIF} + msegl,msetypes{,msestrings}; + +const +{$ifdef mswindows} + glulib: array[0..0] of filenamety = ('glu32.dll'); +{$else} + glulib: array[0..1] of filenamety = ('libGLU.so.1','libGLU.so.'); +{$endif} + +type + TViewPortArray = array [0..3] of GLint; + T16dArray = array [0..15] of GLdouble; + TCallBack = procedure; + T3dArray = array [0..2] of GLdouble; + p3darray = ^t3darray; + T4pArray = array [0..3] of Pointer; + T4fArray = array [0..3] of GLfloat; + PPointer = ^Pointer; + +type + GLUnurbs = record end; PGLUnurbs = ^GLUnurbs; + GLUquadric = record end; PGLUquadric = ^GLUquadric; + GLUtesselator = record end; PGLUtesselator = ^GLUtesselator; + + // backwards compatibility: + GLUnurbsObj = GLUnurbs; PGLUnurbsObj = PGLUnurbs; + GLUquadricObj = GLUquadric; PGLUquadricObj = PGLUquadric; + GLUtesselatorObj = GLUtesselator; PGLUtesselatorObj = PGLUtesselator; + GLUtriangulatorObj = GLUtesselator; PGLUtriangulatorObj = PGLUtesselator; + + TGLUnurbs = GLUnurbs; + TGLUquadric = GLUquadric; + TGLUtesselator = GLUtesselator; + + TGLUnurbsObj = GLUnurbsObj; + TGLUquadricObj = GLUquadricObj; + TGLUtesselatorObj = GLUtesselatorObj; + TGLUtriangulatorObj = GLUtriangulatorObj; + +{$IFDEF MORPHOS} + +{ MorphOS GL works differently due to different dynamic-library handling on Amiga-like } +{ systems, so its headers are included here. } +{$INCLUDE tinyglh.inc} + +{$ELSE MORPHOS} +var + gluErrorString: function(errCode: GLenum): PChar; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluErrorUnicodeStringEXT: function(errCode: GLenum): PWideChar; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + //not on linux + gluGetString: function(name: GLenum): PChar; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluOrtho2D: procedure(left,right, bottom, top: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluPerspective: procedure(fovy, aspect, zNear, zFar: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluPickMatrix: procedure(x, y, width, height: GLdouble; var viewport: TViewPortArray); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluLookAt: procedure(eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluProject: function(objx, objy, objz: GLdouble; var modelMatrix, projMatrix: T16dArray; var viewport: TViewPortArray; winx, winy, winz: PGLdouble): Integer; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluUnProject: function(winx, winy, winz: GLdouble; var modelMatrix, projMatrix: T16dArray; var viewport: TViewPortArray; objx, objy, objz: PGLdouble): Integer; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluScaleImage: function(format: GLenum; widthin, heightin: GLint; typein: GLenum; const datain: Pointer; widthout, heightout: GLint; typeout: GLenum; dataout: Pointer): Integer; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluBuild1DMipmaps: function(target: GLenum; components, width: GLint; format, atype: GLenum; const data: Pointer): Integer; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluBuild2DMipmaps: function(target: GLenum; components, width, height: GLint; format, atype: GLenum; const data: Pointer): Integer; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +var + gluNewQuadric: function: PGLUquadric; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluDeleteQuadric: procedure(state: PGLUquadric); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluQuadricNormals: procedure(quadObject: PGLUquadric; normals: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluQuadricTexture: procedure(quadObject: PGLUquadric; textureCoords: GLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluQuadricOrientation: procedure(quadObject: PGLUquadric; orientation: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluQuadricDrawStyle: procedure(quadObject: PGLUquadric; drawStyle: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluCylinder: procedure(qobj: PGLUquadric; baseRadius, topRadius, height: GLdouble; slices, stacks: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluDisk: procedure(qobj: PGLUquadric; innerRadius, outerRadius: GLdouble; slices, loops: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluPartialDisk: procedure(qobj: PGLUquadric; innerRadius, outerRadius: GLdouble; slices, loops: GLint; startAngle, sweepAngle: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluSphere: procedure(qobj: PGLuquadric; radius: GLdouble; slices, stacks: GLint); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluQuadricCallback: procedure(qobj: PGLUquadric; which: GLenum; fn: TCallBack); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluNewTess: function: PGLUtesselator; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluDeleteTess: procedure(tess: PGLUtesselator); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluTessBeginPolygon: procedure(tess: PGLUtesselator; polygon_data: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluTessBeginContour: procedure(tess: PGLUtesselator); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluTessVertex: procedure(tess: PGLUtesselator; var coords: T3dArray; data: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluTessEndContour: procedure(tess: PGLUtesselator); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluTessEndPolygon: procedure(tess: PGLUtesselator); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluTessProperty: procedure(tess: PGLUtesselator; which: GLenum; value: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluTessNormal: procedure(tess: PGLUtesselator; x, y, z: GLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluTessCallback: procedure(tess: PGLUtesselator; which: GLenum;fn: TCallBack); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluGetTessProperty: procedure(tess: PGLUtesselator; which: GLenum; value: PGLdouble); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluNewNurbsRenderer: function: PGLUnurbs; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluDeleteNurbsRenderer: procedure(nobj: PGLUnurbs); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluBeginSurface: procedure(nobj: PGLUnurbs); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluBeginCurve: procedure(nobj: PGLUnurbs); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluEndCurve: procedure(nobj: PGLUnurbs); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluEndSurface: procedure(nobj: PGLUnurbs); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluBeginTrim: procedure(nobj: PGLUnurbs); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluEndTrim: procedure(nobj: PGLUnurbs); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluPwlCurve: procedure(nobj: PGLUnurbs; count: GLint; aarray: PGLfloat; stride: GLint; atype: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluNurbsCurve: procedure(nobj: PGLUnurbs; nknots: GLint; knot: PGLfloat; stride: GLint; ctlarray: PGLfloat; order: GLint; atype: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluNurbsSurface: procedure(nobj: PGLUnurbs; sknot_count: GLint; sknot: PGLfloat; tknot_count: GLint; tknot: PGLfloat; s_stride, t_stride: GLint; ctlarray: PGLfloat; sorder, torder: GLint; atype: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluLoadSamplingMatrices: procedure(nobj: PGLUnurbs; var modelMatrix, projMatrix: T16dArray; var viewport: TViewPortArray); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluNurbsProperty: procedure(nobj: PGLUnurbs; aproperty: GLenum; value: GLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluGetNurbsProperty: procedure(nobj: PGLUnurbs; aproperty: GLenum; value: PGLfloat); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluNurbsCallback: procedure(nobj: PGLUnurbs; which: GLenum; fn: TCallBack); {$ifdef wincall}stdcall{$else}cdecl{$endif}; +{$ENDIF MORPHOS} + +(**** Callback function prototypes ****) + +type + // gluQuadricCallback + GLUquadricErrorProc = procedure(p: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + // gluTessCallback + GLUtessBeginProc = procedure(p: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + GLUtessEdgeFlagProc = procedure(p: GLboolean); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + GLUtessVertexProc = procedure(p: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + GLUtessEndProc = procedure; {$ifdef wincall}stdcall{$else}cdecl{$endif}; + GLUtessErrorProc = procedure(p: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + GLUtessCombineProc = procedure(var p1: T3dArray; p2: T4pArray; p3: T4fArray; p4: PPointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + GLUtessBeginDataProc = procedure(p1: GLenum; p2: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + GLUtessEdgeFlagDataProc = procedure(p1: GLboolean; p2: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + GLUtessVertexDataProc = procedure(p1, p2: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + GLUtessEndDataProc = procedure(p: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + GLUtessErrorDataProc = procedure(p1: GLenum; p2: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + GLUtessCombineDataProc = procedure(var p1: T3dArray; var p2: T4pArray; var p3: T4fArray; + p4: PPointer; p5: Pointer); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + // gluNurbsCallback + GLUnurbsErrorProc = procedure(p: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + +//*** Generic constants ****/ + +const + // Version + GLU_VERSION_1_1 = 1; + GLU_VERSION_1_2 = 1; + + // Errors: (return value 0 = no error) + GLU_INVALID_ENUM = 100900; + GLU_INVALID_VALUE = 100901; + GLU_OUT_OF_MEMORY = 100902; + GLU_INCOMPATIBLE_GL_VERSION = 100903; + + // StringName + GLU_VERSION = 100800; + GLU_EXTENSIONS = 100801; + + // Boolean + GLU_TRUE = GL_TRUE; + GLU_FALSE = GL_FALSE; + + + //*** Quadric constants ****/ + + // QuadricNormal + GLU_SMOOTH = 100000; + GLU_FLAT = 100001; + GLU_NONE = 100002; + + // QuadricDrawStyle + GLU_POINT = 100010; + GLU_LINE = 100011; + GLU_FILL = 100012; + GLU_SILHOUETTE = 100013; + + // QuadricOrientation + GLU_OUTSIDE = 100020; + GLU_INSIDE = 100021; + + // Callback types: + // GLU_ERROR = 100103; + + + //*** Tesselation constants ****/ + + GLU_TESS_MAX_COORD = 1.0e150; + + // TessProperty + GLU_TESS_WINDING_RULE = 100140; + GLU_TESS_BOUNDARY_ONLY = 100141; + GLU_TESS_TOLERANCE = 100142; + + // TessWinding + GLU_TESS_WINDING_ODD = 100130; + GLU_TESS_WINDING_NONZERO = 100131; + GLU_TESS_WINDING_POSITIVE = 100132; + GLU_TESS_WINDING_NEGATIVE = 100133; + GLU_TESS_WINDING_ABS_GEQ_TWO = 100134; + + // TessCallback + GLU_TESS_BEGIN = 100100; // void (CALLBACK*)(GLenum type) + GLU_TESS_VERTEX = 100101; // void (CALLBACK*)(void *data) + GLU_TESS_END = 100102; // void (CALLBACK*)(void) + GLU_TESS_ERROR = 100103; // void (CALLBACK*)(GLenum errno) + GLU_TESS_EDGE_FLAG = 100104; // void (CALLBACK*)(GLboolean boundaryEdge) + GLU_TESS_COMBINE = 100105; { void (CALLBACK*)(GLdouble coords[3], + void *data[4], + GLfloat weight[4], + void **dataOut) } + GLU_TESS_BEGIN_DATA = 100106; { void (CALLBACK*)(GLenum type, + void *polygon_data) } + GLU_TESS_VERTEX_DATA = 100107; { void (CALLBACK*)(void *data, + void *polygon_data) } + GLU_TESS_END_DATA = 100108; // void (CALLBACK*)(void *polygon_data) + GLU_TESS_ERROR_DATA = 100109; { void (CALLBACK*)(GLenum errno, + void *polygon_data) } + GLU_TESS_EDGE_FLAG_DATA = 100110; { void (CALLBACK*)(GLboolean boundaryEdge, + void *polygon_data) } + GLU_TESS_COMBINE_DATA = 100111; { void (CALLBACK*)(GLdouble coords[3], + void *data[4], + GLfloat weight[4], + void **dataOut, + void *polygon_data) } + + // TessError + GLU_TESS_ERROR1 = 100151; + GLU_TESS_ERROR2 = 100152; + GLU_TESS_ERROR3 = 100153; + GLU_TESS_ERROR4 = 100154; + GLU_TESS_ERROR5 = 100155; + GLU_TESS_ERROR6 = 100156; + GLU_TESS_ERROR7 = 100157; + GLU_TESS_ERROR8 = 100158; + + GLU_TESS_MISSING_BEGIN_POLYGON = GLU_TESS_ERROR1; + GLU_TESS_MISSING_BEGIN_CONTOUR = GLU_TESS_ERROR2; + GLU_TESS_MISSING_END_POLYGON = GLU_TESS_ERROR3; + GLU_TESS_MISSING_END_CONTOUR = GLU_TESS_ERROR4; + GLU_TESS_COORD_TOO_LARGE = GLU_TESS_ERROR5; + GLU_TESS_NEED_COMBINE_CALLBACK = GLU_TESS_ERROR6; + + //*** NURBS constants ****/ + + // NurbsProperty + GLU_AUTO_LOAD_MATRIX = 100200; + GLU_CULLING = 100201; + GLU_SAMPLING_TOLERANCE = 100203; + GLU_DISPLAY_MODE = 100204; + GLU_PARAMETRIC_TOLERANCE = 100202; + GLU_SAMPLING_METHOD = 100205; + GLU_U_STEP = 100206; + GLU_V_STEP = 100207; + + // NurbsSampling + GLU_PATH_LENGTH = 100215; + GLU_PARAMETRIC_ERROR = 100216; + GLU_DOMAIN_DISTANCE = 100217; + + + // NurbsTrim + GLU_MAP1_TRIM_2 = 100210; + GLU_MAP1_TRIM_3 = 100211; + + // NurbsDisplay + // GLU_FILL = 100012; + GLU_OUTLINE_POLYGON = 100240; + GLU_OUTLINE_PATCH = 100241; + + // NurbsCallback + // GLU_ERROR = 100103; + + // NurbsErrors + GLU_NURBS_ERROR1 = 100251; + GLU_NURBS_ERROR2 = 100252; + GLU_NURBS_ERROR3 = 100253; + GLU_NURBS_ERROR4 = 100254; + GLU_NURBS_ERROR5 = 100255; + GLU_NURBS_ERROR6 = 100256; + GLU_NURBS_ERROR7 = 100257; + GLU_NURBS_ERROR8 = 100258; + GLU_NURBS_ERROR9 = 100259; + GLU_NURBS_ERROR10 = 100260; + GLU_NURBS_ERROR11 = 100261; + GLU_NURBS_ERROR12 = 100262; + GLU_NURBS_ERROR13 = 100263; + GLU_NURBS_ERROR14 = 100264; + GLU_NURBS_ERROR15 = 100265; + GLU_NURBS_ERROR16 = 100266; + GLU_NURBS_ERROR17 = 100267; + GLU_NURBS_ERROR18 = 100268; + GLU_NURBS_ERROR19 = 100269; + GLU_NURBS_ERROR20 = 100270; + GLU_NURBS_ERROR21 = 100271; + GLU_NURBS_ERROR22 = 100272; + GLU_NURBS_ERROR23 = 100273; + GLU_NURBS_ERROR24 = 100274; + GLU_NURBS_ERROR25 = 100275; + GLU_NURBS_ERROR26 = 100276; + GLU_NURBS_ERROR27 = 100277; + GLU_NURBS_ERROR28 = 100278; + GLU_NURBS_ERROR29 = 100279; + GLU_NURBS_ERROR30 = 100280; + GLU_NURBS_ERROR31 = 100281; + GLU_NURBS_ERROR32 = 100282; + GLU_NURBS_ERROR33 = 100283; + GLU_NURBS_ERROR34 = 100284; + GLU_NURBS_ERROR35 = 100285; + GLU_NURBS_ERROR36 = 100286; + GLU_NURBS_ERROR37 = 100287; + +//*** Backwards compatibility for old tesselator ****/ + +var + gluBeginPolygon: procedure(tess: PGLUtesselator); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluNextContour: procedure(tess: PGLUtesselator; atype: GLenum); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + gluEndPolygon: procedure(tess: PGLUtesselator); {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +const + // Contours types -- obsolete! + GLU_CW = 100120; + GLU_CCW = 100121; + GLU_INTERIOR = 100122; + GLU_EXTERIOR = 100123; + GLU_UNKNOWN = 100124; + + // Names without "TESS_" prefix + GLU_BEGIN = GLU_TESS_BEGIN; + GLU_VERTEX = GLU_TESS_VERTEX; + GLU_END = GLU_TESS_END; + GLU_ERROR = GLU_TESS_ERROR; + GLU_EDGE_FLAG = GLU_TESS_EDGE_FLAG; + +//procedure LoadGLu(const dll: String); +//procedure FreeGLu; + +procedure initializeglu(const sonames: array of filenamety); //[] = default +procedure releaseglu; + +implementation +uses + msedynload,msesys; +var + libinfo: dynlibinfoty; + +procedure initializeglu(const sonames: array of filenamety); //[] = default +const + funcs: array[0..50] of funcinfoty = ( + (n: 'gluErrorString'; d: {$ifndef FPC}@{$endif}@gluErrorString), + (n: 'gluGetString'; d: {$ifndef FPC}@{$endif}@gluGetString), + (n: 'gluOrtho2D'; d: {$ifndef FPC}@{$endif}@gluOrtho2D), + (n: 'gluPerspective'; d: {$ifndef FPC}@{$endif}@gluPerspective), + (n: 'gluPickMatrix'; d: {$ifndef FPC}@{$endif}@gluPickMatrix), + (n: 'gluLookAt'; d: {$ifndef FPC}@{$endif}@gluLookAt), + (n: 'gluProject'; d: {$ifndef FPC}@{$endif}@gluProject), + (n: 'gluUnProject'; d: {$ifndef FPC}@{$endif}@gluUnProject), + (n: 'gluScaleImage'; d: {$ifndef FPC}@{$endif}@gluScaleImage), + (n: 'gluBuild1DMipmaps'; d: {$ifndef FPC}@{$endif}@gluBuild1DMipmaps), + (n: 'gluBuild2DMipmaps'; d: {$ifndef FPC}@{$endif}@gluBuild2DMipmaps), + (n: 'gluNewQuadric'; d: {$ifndef FPC}@{$endif}@gluNewQuadric), + (n: 'gluDeleteQuadric'; d: {$ifndef FPC}@{$endif}@gluDeleteQuadric), + (n: 'gluQuadricNormals'; d: {$ifndef FPC}@{$endif}@gluQuadricNormals), + (n: 'gluQuadricTexture'; d: {$ifndef FPC}@{$endif}@gluQuadricTexture), + (n: 'gluQuadricOrientation'; d: {$ifndef FPC}@{$endif}@gluQuadricOrientation), + (n: 'gluQuadricDrawStyle'; d: {$ifndef FPC}@{$endif}@gluQuadricDrawStyle), + (n: 'gluCylinder'; d: {$ifndef FPC}@{$endif}@gluCylinder), + (n: 'gluDisk'; d: {$ifndef FPC}@{$endif}@gluDisk), + (n: 'gluPartialDisk'; d: {$ifndef FPC}@{$endif}@gluPartialDisk), + (n: 'gluSphere'; d: {$ifndef FPC}@{$endif}@gluSphere), + (n: 'gluQuadricCallback'; d: {$ifndef FPC}@{$endif}@gluQuadricCallback), + (n: 'gluNewTess'; d: {$ifndef FPC}@{$endif}@gluNewTess), + (n: 'gluDeleteTess'; d: {$ifndef FPC}@{$endif}@gluDeleteTess), + (n: 'gluTessBeginPolygon'; d: {$ifndef FPC}@{$endif}@gluTessBeginPolygon), + (n: 'gluTessBeginContour'; d: {$ifndef FPC}@{$endif}@gluTessBeginContour), + (n: 'gluTessVertex'; d: {$ifndef FPC}@{$endif}@gluTessVertex), + (n: 'gluTessEndContour'; d: {$ifndef FPC}@{$endif}@gluTessEndContour), + (n: 'gluTessEndPolygon'; d: {$ifndef FPC}@{$endif}@gluTessEndPolygon), + (n: 'gluTessProperty'; d: {$ifndef FPC}@{$endif}@gluTessProperty), + (n: 'gluTessNormal'; d: {$ifndef FPC}@{$endif}@gluTessNormal), + (n: 'gluTessCallback'; d: {$ifndef FPC}@{$endif}@gluTessCallback), + (n: 'gluGetTessProperty'; d: {$ifndef FPC}@{$endif}@gluGetTessProperty), + (n: 'gluNewNurbsRenderer'; d: {$ifndef FPC}@{$endif}@gluNewNurbsRenderer), + (n: 'gluDeleteNurbsRenderer'; d: {$ifndef FPC}@{$endif}@gluDeleteNurbsRenderer), + (n: 'gluBeginSurface'; d: {$ifndef FPC}@{$endif}@gluBeginSurface), + (n: 'gluBeginCurve'; d: {$ifndef FPC}@{$endif}@gluBeginCurve), + (n: 'gluEndCurve'; d: {$ifndef FPC}@{$endif}@gluEndCurve), + (n: 'gluEndSurface'; d: {$ifndef FPC}@{$endif}@gluEndSurface), + (n: 'gluBeginTrim'; d: {$ifndef FPC}@{$endif}@gluBeginTrim), + (n: 'gluEndTrim'; d: {$ifndef FPC}@{$endif}@gluEndTrim), + (n: 'gluPwlCurve'; d: {$ifndef FPC}@{$endif}@gluPwlCurve), + (n: 'gluNurbsCurve'; d: {$ifndef FPC}@{$endif}@gluNurbsCurve), + (n: 'gluNurbsSurface'; d: {$ifndef FPC}@{$endif}@gluNurbsSurface), + (n: 'gluLoadSamplingMatrices'; d: {$ifndef FPC}@{$endif}@gluLoadSamplingMatrices), + (n: 'gluNurbsProperty'; d: {$ifndef FPC}@{$endif}@gluNurbsProperty), + (n: 'gluGetNurbsProperty'; d: {$ifndef FPC}@{$endif}@gluGetNurbsProperty), + (n: 'gluNurbsCallback'; d: {$ifndef FPC}@{$endif}@gluNurbsCallback), + (n: 'gluBeginPolygon'; d: {$ifndef FPC}@{$endif}@gluBeginPolygon), + (n: 'gluNextContour'; d: {$ifndef FPC}@{$endif}@gluNextContour), + (n: 'gluEndPolygon'; d: {$ifndef FPC}@{$endif}@gluEndPolygon) + ); + funcsopt: array[0..0] of funcinfoty = ( + (n: 'gluErrorUnicodeStringEXT'; d: {$ifndef FPC}@{$endif}@gluErrorUnicodeStringEXT) + ); + errormessage = 'Can not load glu library'; +begin + initializedynlib(libinfo,sonames,glulib,funcs,funcsopt,errormessage); +end; + +procedure releaseglu; +begin + releasedynlib(libinfo,nil,true); +//used in xclosedisplay? +end; + +initialization + initializelibinfo(libinfo); +finalization + finalizelibinfo(libinfo); +end. diff --git a/mseide-msegui/lib/common/opengl/mseglx.pas b/mseide-msegui/lib/common/opengl/mseglx.pas new file mode 100644 index 0000000..e496ea9 --- /dev/null +++ b/mseide-msegui/lib/common/opengl/mseglx.pas @@ -0,0 +1,225 @@ +{ + + Translation of the Mesa GLX headers for FreePascal + Copyright (C) 1999 Sebastian Guenther + + + Mesa 3-D graphics library + Version: 3.0 + Copyright (C) 1995-1998 Brian Paul + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +// +// modified 2011 by Martin Schreiber +// +//{$MODE delphi} // objfpc would not work because of direct proc var assignments + +{You have to enable Macros (compiler switch "-Sm") for compiling this unit! + This is necessary for supporting different platforms with different calling + conventions via a single unit.} + +{$ifdef FPC}{$mode objfpc} {$h+}{$endif} + +unit mseglx; + +interface +{$ifdef linux}{$define unix}{$endif} +{$IFDEF Unix} + uses + {$ifdef FPC}X,{$endif} XLib,{$ifdef FPC} XUtil,{$endif}mseglextglob; + {$DEFINE HasGLX} // Activate GLX stuff +{$ELSE} + {$MESSAGE Unsupported platform.} +{$ENDIF} + +{$IFNDEF HasGLX} + {$MESSAGE GLX not present on this platform.} +{$ENDIF} + + +//*) +// ======================================================= +// GLX consts, types and functions +// ======================================================= + +// Tokens for glXChooseVisual and glXGetConfig: +const + GLX_USE_GL = 1; + GLX_BUFFER_SIZE = 2; + GLX_LEVEL = 3; + GLX_RGBA = 4; + GLX_DOUBLEBUFFER = 5; + GLX_STEREO = 6; + GLX_AUX_BUFFERS = 7; + GLX_RED_SIZE = 8; + GLX_GREEN_SIZE = 9; + GLX_BLUE_SIZE = 10; + GLX_ALPHA_SIZE = 11; + GLX_DEPTH_SIZE = 12; + GLX_STENCIL_SIZE = 13; + GLX_ACCUM_RED_SIZE = 14; + GLX_ACCUM_GREEN_SIZE = 15; + GLX_ACCUM_BLUE_SIZE = 16; + GLX_ACCUM_ALPHA_SIZE = 17; + + // GLX_EXT_visual_info extension + GLX_X_VISUAL_TYPE_EXT = $22; + GLX_TRANSPARENT_TYPE_EXT = $23; + GLX_TRANSPARENT_INDEX_VALUE_EXT = $24; + GLX_TRANSPARENT_RED_VALUE_EXT = $25; + GLX_TRANSPARENT_GREEN_VALUE_EXT = $26; + GLX_TRANSPARENT_BLUE_VALUE_EXT = $27; + GLX_TRANSPARENT_ALPHA_VALUE_EXT = $28; + + + // Error codes returned by glXGetConfig: + GLX_BAD_SCREEN = 1; + GLX_BAD_ATTRIBUTE = 2; + GLX_NO_EXTENSION = 3; + GLX_BAD_VISUAL = 4; + GLX_BAD_CONTEXT = 5; + GLX_BAD_VALUE = 6; + GLX_BAD_ENUM = 7; + + // GLX 1.1 and later: + GLX_VENDOR = 1; + GLX_VERSION = 2; + GLX_EXTENSIONS = 3; + + // GLX_visual_info extension + GLX_TRUE_COLOR_EXT = $8002; + GLX_DIRECT_COLOR_EXT = $8003; + GLX_PSEUDO_COLOR_EXT = $8004; + GLX_STATIC_COLOR_EXT = $8005; + GLX_GRAY_SCALE_EXT = $8006; + GLX_STATIC_GRAY_EXT = $8007; + GLX_NONE_EXT = $8000; + GLX_TRANSPARENT_RGB_EXT = $8008; + GLX_TRANSPARENT_INDEX_EXT = $8009; + +type +{$ifndef FPC} + txid = xid; +{$endif} + // From XLib: + XPixmap = TXID; + XFont = TXID; + XColormap = TXID; + + GLXContext = Pointer; + GLXPixmap = TXID; + GLXDrawable = TXID; + GLXContextID = TXID; + + TXPixmap = XPixmap; + TXFont = XFont; + TXColormap = XColormap; + + TGLXContext = GLXContext; + TGLXPixmap = GLXPixmap; + TGLXDrawable = GLXDrawable; + TGLXContextID = GLXContextID; + +var + glXChooseVisual: function(dpy: PDisplay; screen: Integer; attribList: PInteger): PXVisualInfo; cdecl; + glXCreateContext: function(dpy: PDisplay; vis: PXVisualInfo; shareList: GLXContext; direct: Boolean): GLXContext; cdecl; + glXDestroyContext: procedure(dpy: PDisplay; ctx: GLXContext); cdecl; + glXMakeCurrent: function(dpy: PDisplay; drawable: GLXDrawable; ctx: GLXContext): Boolean; cdecl; + glXCopyContext: procedure(dpy: PDisplay; src, dst: GLXContext; mask: LongWord); cdecl; + glXSwapBuffers: procedure(dpy: PDisplay; drawable: GLXDrawable); cdecl; + glXCreateGLXPixmap: function(dpy: PDisplay; visual: PXVisualInfo; pixmap: XPixmap): GLXPixmap; cdecl; + glXDestroyGLXPixmap: procedure(dpy: PDisplay; pixmap: GLXPixmap); cdecl; + glXQueryExtension: function(dpy: PDisplay; var errorb, event: Integer): Boolean; cdecl; + glXQueryVersion: function(dpy: PDisplay; var maj, min: Integer): Boolean; cdecl; + glXIsDirect: function(dpy: PDisplay; ctx: GLXContext): Boolean; cdecl; + glXGetConfig: function(dpy: PDisplay; visual: PXVisualInfo; attrib: Integer; var value: Integer): Integer; cdecl; + glXGetCurrentContext: function: GLXContext; cdecl; + glXGetCurrentDrawable: function: GLXDrawable; cdecl; + glXWaitGL: procedure; cdecl; + glXWaitX: procedure; cdecl; + glXUseXFont: procedure(font: XFont; first, count, list: Integer); cdecl; + + // GLX 1.1 and later + glXQueryExtensionsString: function(dpy: PDisplay; screen: Integer): PChar; cdecl; + glXQueryServerString: function(dpy: PDisplay; screen, name: Integer): PChar; cdecl; + glXGetClientString: function(dpy: PDisplay; name: Integer): PChar; cdecl; + + // Mesa GLX Extensions + glXCreateGLXPixmapMESA: function(dpy: PDisplay; visual: PXVisualInfo; pixmap: XPixmap; cmap: XColormap): GLXPixmap; cdecl; + glXReleaseBufferMESA: function(dpy: PDisplay; d: GLXDrawable): Boolean; cdecl; + glXCopySubBufferMESA: procedure(dpy: PDisplay; drawbale: GLXDrawable; x, y, width, height: Integer); cdecl; + glXGetVideoSyncSGI: function(var counter: LongWord): Integer; cdecl; + glXWaitVideoSyncSGI: function(divisor, remainder: Integer; var count: LongWord): Integer; cdecl; + + +// ======================================================= +// +// ======================================================= + +function load_glx: boolean; +function load_glx_mesa: boolean; + +implementation +{$ifdef FPC}{$LINKLIB m}{$endif} + +uses + msegl,msedynload,msesys{$ifdef FPC},dynlibs{$endif}; + +function load_glx: boolean; +const + funcs: array[0..19] of funcinfoty = + ( + (n: 'glXChooseVisual'; d: {$ifndef FPC}@{$endif}@glXChooseVisual), + (n: 'glXCreateContext'; d: {$ifndef FPC}@{$endif}@glXCreateContext), + (n: 'glXDestroyContext'; d: {$ifndef FPC}@{$endif}@glXDestroyContext), + (n: 'glXMakeCurrent'; d: {$ifndef FPC}@{$endif}@glXMakeCurrent), + (n: 'glXCopyContext'; d: {$ifndef FPC}@{$endif}@glXCopyContext), + (n: 'glXSwapBuffers'; d: {$ifndef FPC}@{$endif}@glXSwapBuffers), + (n: 'glXCreateGLXPixmap'; d: {$ifndef FPC}@{$endif}@glXCreateGLXPixmap), + (n: 'glXDestroyGLXPixmap'; d: {$ifndef FPC}@{$endif}@glXDestroyGLXPixmap), + (n: 'glXQueryExtension'; d: {$ifndef FPC}@{$endif}@glXQueryExtension), + (n: 'glXQueryVersion'; d: {$ifndef FPC}@{$endif}@glXQueryVersion), + (n: 'glXIsDirect'; d: {$ifndef FPC}@{$endif}@glXIsDirect), + (n: 'glXGetConfig'; d: {$ifndef FPC}@{$endif}@glXGetConfig), + (n: 'glXGetCurrentContext'; d: {$ifndef FPC}@{$endif}@glXGetCurrentContext), + (n: 'glXGetCurrentDrawable'; d: {$ifndef FPC}@{$endif}@glXGetCurrentDrawable), + (n: 'glXWaitGL'; d: {$ifndef FPC}@{$endif}@glXWaitGL), + (n: 'glXWaitX'; d: {$ifndef FPC}@{$endif}@glXWaitX), + (n: 'glXUseXFont'; d: {$ifndef FPC}@{$endif}@glXUseXFont), + // GLX 1.1 and later + (n: 'glXQueryExtensionsString'; d: {$ifndef FPC}@{$endif}@glXQueryExtensionsString), + (n: 'glXQueryServerString'; d: {$ifndef FPC}@{$endif}@glXQueryServerString), + (n: 'glXGetClientString'; d: {$ifndef FPC}@{$endif}@glXGetClientString) + ); +begin + result:= getprocaddresses(libgl,funcs,true); +end; + +function load_glx_mesa: boolean; +const + funcs: array[0..4] of funcinfoty = + ( + (n: 'glXCreateGLXPixmapMESA'; d: {$ifndef FPC}@{$endif}@glXCreateGLXPixmapMESA), + (n: 'glXReleaseBufferMESA'; d: {$ifndef FPC}@{$endif}@glXReleaseBufferMESA), + (n: 'glXCopySubBufferMESA'; d: {$ifndef FPC}@{$endif}@glXCopySubBufferMESA), + (n: 'glXGetVideoSyncSGI'; d: {$ifndef FPC}@{$endif}@glXGetVideoSyncSGI), + (n: 'glXWaitVideoSyncSGI'; d: {$ifndef FPC}@{$endif}@glXWaitVideoSyncSGI) + ); +begin + result:= getprocaddresses(libgl,funcs,true); +end; + +end. diff --git a/mseide-msegui/lib/common/opengl/mseopengl.pas b/mseide-msegui/lib/common/opengl/mseopengl.pas new file mode 100644 index 0000000..a85e32b --- /dev/null +++ b/mseide-msegui/lib/common/opengl/mseopengl.pas @@ -0,0 +1,255 @@ +{ MSEgui Copyright (c) 2007-2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseopengl; +// +// under construction +// +{$ifdef FPC}{$mode objfpc}{$h+}{$INTERFACES CORBA}{$endif} + +interface +uses + msegl,{$ifdef unix}mseglx,x,xlib,xutil,{$else}windows,{$endif} + msegraphics,msetypes,mseguiglob,msegraphutils,mseopenglgdi; + +type + topenglcanvas = class(tcanvas) + private + fviewport: rectty; + procedure setviewport(const avalue: rectty); + protected + fcontextinfo: contextinfoty; + function lock: boolean; override; + function getcontextinfopo: pointer; override; + procedure updatesize(const asize: sizety); override; +// procedure linktopaintdevice(apaintdevice: paintdevicety; const gc: gcty; +// {const size: sizety;} const cliporigin: pointty); override; + public + constructor create(const user: tobject; const intf: icanvas); override; + destructor destroy; override; + class function getclassgdifuncs: pgdifunctionaty; override; + + procedure updatewindowoptions(var aoptions: internalwindowoptionsty); override; + procedure init(const acolor: colorty = cl_none); //cl_none -> colorbackground + procedure swapbuffers; + property viewport: rectty read fviewport write setviewport; + end; + + topenglbitmapcanvas = class(topenglcanvas) + end; + + topenglwindowcanvas = class(topenglcanvas) + public + procedure linktopaintdevice(apaintdevice: paintdevicety; const gc: gcty; + {const size: sizety;} const cliporigin: pointty); override; + end; + +implementation +uses + mseguiintf; +type + tsimplebitmap1 = class(tsimplebitmap); + +const + defaultcontextattributes: contextattributesty = + (buffersize: -1; + level: 0; + doublebuffer: false; + rgba: true; + stereo: false; + auxbuffers: -1; + redsize: 8; + greensize: 8; + bluesize: 8; + alphasize: -1; + depthsize: -1; + stencilsize: 2; + accumredsize: -1; + accumgreensize: -1; + accumbluesize: -1; + accumalphasize: -1 + ); + defaultmonocontextattributes: contextattributesty = + (buffersize: -1; + level: 0; + doublebuffer: false; + rgba: true; + stereo: false; + auxbuffers: -1; + redsize: 8; + greensize: 8; + bluesize: 8; + alphasize: -1; + depthsize: -1; + stencilsize: 2; + accumredsize: -1; + accumgreensize: -1; + accumbluesize: -1; + accumalphasize: -1 + ); +{$ifdef unix} + defaultvisualattributes: array[0..8] of integer = + (GLX_RGBA,GLX_RED_SIZE,8,GLX_GREEN_SIZE,8,GLX_BLUE_SIZE,8, + GLX_DOUBLEBUFFER,none); +{$endif} + +{ topenglcanvas } + +constructor topenglcanvas.create(const user: tobject; const intf: icanvas); +begin + if user is tsimplebitmap then begin + with tsimplebitmap1(user) do begin + include(fstate,pms_staticcanvas); //opengl gc creation is expensive + end; + end; + initializeopengl([]); +// fgdinum:= openglgetgdinum; + fcontextinfo.attrib:= defaultcontextattributes; +{$ifdef unix} + fcontextinfo.visualattributes:= defaultvisualattributes; +{$endif} + inherited; +end; + +destructor topenglcanvas.destroy; +begin + inherited; + releaseopengl; +end; + +class function topenglcanvas.getclassgdifuncs: pgdifunctionaty; +begin + result:= openglgetgdifuncs; +end; + +procedure topenglcanvas.setviewport(const avalue: rectty); +var + bo1: boolean; +begin + fviewport:= avalue; + fdrawinfo.gc.paintdevicesize:= fviewport.size; + if fdrawinfo.gc.handle <> 0 then begin + bo1:= lock; + fdrawinfo.rect.rect:= @fviewport; + gdi_setviewport(fdrawinfo); + if bo1 then begin + unlock; + end; + end; +end; + +procedure topenglcanvas.swapbuffers; +var + bo1: boolean; +begin + bo1:= lock; + gdi_swapbuffers(fdrawinfo); + if bo1 then begin + unlock; + end; +end; + +procedure topenglcanvas.init(const acolor: colorty = cl_none); +var + bo1: boolean; +begin + bo1:= lock; + if acolor = cl_none then begin + fdrawinfo.color.color:= colorbackground; + end + else begin + fdrawinfo.color.color:= acolor; + end; + gdi_clear(fdrawinfo); + if flushgdi then begin + doflush; + end; + if bo1 then begin + unlock; + end; +end; + +function topenglcanvas.lock: boolean; +begin + result:= inherited lock; + if fdrawinfo.gc.handle = 0 then begin + checkgcstate([cs_gc]); + end; + if fdrawinfo.paintdevice <> 0 then begin + gdi_makecurrent(fdrawinfo); + end; +end; + +function topenglcanvas.getcontextinfopo: pointer; +begin + if df_canvasismonochrome in fdrawinfo.gc.drawingflags then begin + result:= @defaultmonocontextattributes; + end + else begin + result:= @fcontextinfo; + end; +end; + +procedure topenglcanvas.updatewindowoptions(var aoptions: internalwindowoptionsty); +var + gc1: gcty; +begin + inherited; + fillchar(gc1,sizeof(gc1),0); + gdi_choosevisual(gc1,fcontextinfo); +{$ifdef unix} + with x11internalwindowoptionsty(aoptions.platformdata).d, + oglgcty(gc1.platformdata).d do begin + if fvisinfo <> nil then begin + depth:= fvisinfo^.depth; + visual:= fvisinfo^.visual; + colormap:= fcolormap; + xfree(fvisinfo); + fvisinfo:= nil; + end + else begin + depth:= 0; + visual:= nil; + colormap:= 0; + end; + end; +{$endif} +end; + +procedure topenglcanvas.updatesize(const asize: sizety); +//var +// gc1: gcty; +begin + with fdrawinfo.gc do begin + oglgcty(platformdata).d.top:= asize.cy+gltopshift; + if (handle <> 0) and not sizeisequal(asize,paintdevicesize) then begin + viewport:= mr(fviewport.pos,asize); + { + fillchar(gc1,sizeof(gc1),0); + gc1.paintdevicesize:= asize; + linktopaintdevice(fdrawinfo.paintdevice,gc1,nullpoint); + creategc(fdrawinfo.paintdevice,gck_screen,fdrawinfo.gc,''); + } + end + else begin + inherited; + end; + end; +end; + +{ topenglwindowcanvas } + +procedure topenglwindowcanvas.linktopaintdevice(apaintdevice: paintdevicety; + const gc: gcty; const cliporigin: pointty); +begin + inherited; + viewport:= mr(nullpoint,gc.paintdevicesize); +end; + +end. diff --git a/mseide-msegui/lib/common/opengl/mseopenglcanvaswidget.pas b/mseide-msegui/lib/common/opengl/mseopenglcanvaswidget.pas new file mode 100644 index 0000000..da553f0 --- /dev/null +++ b/mseide-msegui/lib/common/opengl/mseopenglcanvaswidget.pas @@ -0,0 +1,254 @@ +{ MSEgui Copyright (c) 2011-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseopenglcanvaswidget; +// +// under construction +// +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msewindowwidget,msegraphics,mseopengl,classes,mclasses,mseclasses, + msegraphutils, + msegui,msemenus,mseguiglob,msetypes; + +type + + topenglwidgetcanvas = class(topenglcanvas) + protected + procedure linktopaintdevice(const aparent: winidty; + const awindowrect: rectty; out aid: winidty); reintroduce; + public + constructor create(const user: tobject; const intf: icanvas); override; + published + property options; + { + property monochrome; + property color; + property colorbackground; + property rasterop; + property font; + property brush; + + property linewidth; + property linewidthmm; + + property dashes; + //last byte 0 -> opaque dash //todo: dashoffset + property capstyle; + property joinstyle; + property lineoptions; + + property ppmm; + //used for linewidth mm, value not saved/restored + } + end; + + topenglcanvaswidget = class; + openglcanvasrendereventty = procedure(const sender: topenglcanvaswidget; + const aupdaterect: rectty) of object; + + topenglcanvaswidget = class(tcustomwindowwidget,icanvas) + private + fcanvas: topenglwidgetcanvas; + fonrender: openglcanvasrendereventty; + procedure setcanvas(const avalue: topenglwidgetcanvas); + protected + procedure readstate(reader: treader); override; + procedure doclientrectchanged; override; + procedure docreatewinid(const aparent: winidty; const awidgetrect: rectty; + var aid: winidty); override; + procedure dodestroywinid; override; + function canclientpaint: boolean; override; + procedure doclientpaint(const aupdaterect: rectty); override; + procedure updateviewport(const arect: rectty); override; + //icanvas + procedure gcneeded(const sender: tcanvas); +// function getmonochrome: boolean; + function getkind: bitmapkindty; + function getsize: sizety; + procedure getcanvasimage(const bgr: boolean; var aimage: maskedimagety); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property canvas: topenglwidgetcanvas read fcanvas write setcanvas; + property onrender: openglcanvasrendereventty read fonrender write fonrender; + property optionswidget; + property optionsskin; + property bounds_x; + property bounds_y; + property bounds_cx; + property bounds_cy; + property bounds_cxmin; + property bounds_cymin; + property bounds_cxmax; + property bounds_cymax; + property color; + property cursor; + property frame; + property face; + property anchors; + property taborder; + property hint; + property popupmenu; + property onpopup; + property onshowhint; + property enabled; + property visible; + property oncreatewinid; + property ondestroywinid; +// property onclientpaint; + property onclientrectchanged; + property onwindowmouseevent; + property onwindowmousewheelevent; + property ondestroy; + end; + +implementation +uses + mseopenglgdi,msegl; + +type + topenglcanvas1 = class(topenglcanvas); + +{ topenglcanvaswidget } + +constructor topenglcanvaswidget.create(aowner: tcomponent); +begin + fcanvas:= topenglwidgetcanvas.create(self,icanvas(self)); + inherited; +end; + +destructor topenglcanvaswidget.destroy; +begin + inherited; + fcanvas.free; +end; + +procedure topenglcanvaswidget.setcanvas(const avalue: topenglwidgetcanvas); +begin + fcanvas.assign(avalue); +end; + +procedure topenglcanvaswidget.gcneeded(const sender: tcanvas); +begin + checkclientwinid; +end; +{ +function topenglcanvaswidget.getmonochrome: boolean; +begin + result:= false; +end; +} +function topenglcanvaswidget.getkind: bitmapkindty; +begin + result:= bmk_rgb; +end; + +function topenglcanvaswidget.getsize: sizety; +begin + result:= paintsize; +end; + +procedure topenglcanvaswidget.docreatewinid(const aparent: winidty; + const awidgetrect: rectty; var aid: winidty); +begin + initializeopengl([]); + fcanvas.linktopaintdevice(aparent,awidgetrect,aid); + checkwindowrect; +end; + +procedure topenglcanvaswidget.updateviewport(const arect: rectty); +begin + fcanvas.viewport:= arect; + inherited; +end; + +procedure topenglcanvaswidget.doclientrectchanged; +begin + fcanvas.updatesize(innerpaintrect.size); + inherited; +end; + +procedure topenglcanvaswidget.dodestroywinid; +begin + fcanvas.unlink; + inherited; + releaseopengl; +end; + +procedure topenglcanvaswidget.doclientpaint(const aupdaterect: rectty); +begin + if canevent(tmethod(fonrender)) then begin + fcanvas.reset; + fonrender(self,aupdaterect); + fcanvas.endpaint; + end; +end; + +function topenglcanvaswidget.canclientpaint: boolean; +begin + result:= assigned(fonrender); +end; + +procedure topenglcanvaswidget.getcanvasimage(const bgr: boolean; + var aimage: maskedimagety); +begin + //dummy +end; + +procedure topenglcanvaswidget.readstate(reader: treader); +begin + fcanvas.beforeread; + try + inherited; + finally + fcanvas.afterread; + end; +end; + +{ topenglwidgetcanvas } + +procedure topenglwidgetcanvas.linktopaintdevice(const aparent: winidty; + const awindowrect: rectty; out aid: winidty); +var + gc1: gcty; + info: drawinfoty; +begin + fillchar(gc1,sizeof(gc1),0); + fillchar(info,sizeof(info),0); + gc1.kind:= bmk_rgb; + with info.creategc do begin + gcpo:= @gc1; + contextinfopo:= @fcontextinfo; + windowrect:= @awindowrect; + parent:= aparent; + kind:= gck_screen; + createpaintdevice:= true; + gdi_lock; + fdrawinfo.gc.gdifuncs^[gdf_creategc](info); + gdi_unlock; + aid:= paintdevice; + end; + gc1.paintdevicesize:= awindowrect.size; + inherited linktopaintdevice(paintdevicety(aid),gc1,nullpoint); +end; + +constructor topenglwidgetcanvas.create(const user: tobject; + const intf: icanvas); +begin + inherited; +// if not flushgdi then begin +// fcontextinfo.attrib.doublebuffer:= true; +// end; +end; + +end. diff --git a/mseide-msegui/lib/common/opengl/mseopenglgdi.pas b/mseide-msegui/lib/common/opengl/mseopenglgdi.pas new file mode 100644 index 0000000..8121049 --- /dev/null +++ b/mseide-msegui/lib/common/opengl/mseopenglgdi.pas @@ -0,0 +1,1977 @@ +{ MSEgui Copyright (c) 2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseopenglgdi; +// +//under construction +// + +//todo: optimize pixmap and brush handling, use server side buffers + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msegl,mseglext,mseglu,{$ifdef unix}mseglx,x,xlib,xutil,msectypes, + {$else}windows,{$endif} + msegraphics,msetypes,msegraphutils,mseguiglob,mseglextglob; +{ +const + GL_BGRA = GL_BGRA_EXT; +} +const + glpixelshift = -0.5; + gltopshift = -1; + +type + contextattributesty = record + buffersize: integer; + level: integer; + doublebuffer: boolean; + rgba: boolean; + stereo: boolean; + auxbuffers: integer; + redsize: integer; + greensize: integer; + bluesize: integer; + alphasize: integer; + depthsize: integer; + stencilsize: integer; + accumredsize: integer; + accumgreensize: integer; + accumbluesize: integer; + accumalphasize: integer; + end; + + contextinfoty = record +// viewport: rectty; + attrib: contextattributesty; + {$ifdef unix} + visualattributes: integerarty; + {$endif} + end; + pcontextinfoty = ^contextinfoty; + + oglgcstatety = (ogcs_hastexture,ogcs_needsblend,ogcs_hasclipreg); + oglgcstatesty = set of oglgcstatety; + oglgcdty = record + fkind: gckindty; + {$ifdef unix} + fcontext: glxcontext; + fdpy: pdisplay; + fcolormap: tcolormap; + fscreen: integer; + fvisinfo: pxvisualinfo; + {$else} + fdc: hdc; + fcontext: hglrc; + doublebuf: boolean; + {$endif} + pd: paintdevicety; + extensions: glextensionsty; + top: integer; //y 0 coord value + glfont: fontty; + tess: pglutesselator; + texture: gluint; + brushsize: sizety; + gcstate: oglgcstatesty; + glcolorforeground: rgbtriplety; + glcolorbackground: rgbtriplety; + gcrasterop: rasteropty; + gcoptions: canvasoptionsty; + gcdrawingflags: drawingflagsty; + gcbrushorigin: pointty; + end; + + {$if sizeof(oglgcdty) > sizeof(gcpty)} {$error 'buffer overflow'}{$endif} + + oglgcty = record + case integer of + 0: (d: oglgcdty;); + 1: (_bufferspace: gcpty;); + end; + poglgcty = ^oglgcty; + +{ +function createrendercontext(const aparent: winidty; const windowrect: rectty; + const ainfo: contextinfoty; + var gc: gcty; out aid: winidty): guierrorty; +} +function openglgetgdifuncs: pgdifunctionaty; +//function openglgetgdinum: integer; + +function gdi_choosevisual(var gc: gcty; + const contextinfo: contextinfoty): gdierrorty; +procedure gdi_makecurrent(var drawinfo: drawinfoty); +procedure gdi_setviewport(var drawinfo: drawinfoty); +procedure gdi_swapbuffers(var drawinfo: drawinfoty); +procedure gdi_clear(var drawinfo: drawinfoty); + +implementation +uses + mseguiintf,{mseftgl,}msegenericgdi,msestrings,msehash,sysutils, + mseformatstr,msefontcache,mseftfontcache,mseopengl,msebits; +type + tcanvas1 = class(tcanvas); + + gluvertexty = packed record + x: double; + y: double; + z: double; + end; + pgluvertexty = ^gluvertexty; + ppgluvertexty = ^pgluvertexty; +{ + ftglfontty = record + handle: pftglfont; + end; + pftglfontty = ^ftglfontty; +} +{ + cachefontty = record + end; + pcachefontty = ^cachefontty; +} +{ + fontcachehdataty = record + height: integer; + name: string; + end; +} + tglftfontcache = class(tftfontcache) + protected + procedure drawglyph(var drawinfo: drawinfoty; const pos: pointty; + const bitmap: pbitmapdataty); override; + public + procedure drawstring16(var drawinfo: drawinfoty; + const afont: fontty); override; + end; + +var + ffontcache: tglftfontcache; +// stockgc: gcty; +// gdinumber: integer; + +function checkerror: glenum; +begin + glfinish(); + result:= glgeterror(); + if result <> gl_no_error then begin + repeat + until glgeterror() = gl_no_error; + end; +end; + +function fontcache: tglftfontcache; +begin + if ffontcache = nil then begin + tglftfontcache.create(tftfontcache(ffontcache)); + end; + result:= ffontcache; +end; + +type + glcolorty = record + r,g,b,a: glclampf; + end; + +procedure putboolean(var ar1: integerarty; var index: integer; + const atag: integer; const avalue: boolean); +begin + if avalue then begin + if index > high(ar1) then begin + setlength(ar1,19+high(ar1)*2); + end; + ar1[index]:= atag; + inc(index); + end; +end; + +procedure putvalue(var ar1: integerarty; var index: integer; + const atag,avalue,defaultvalue: integer); +begin + if avalue <> defaultvalue then begin + if index > high(ar1) then begin + setlength(ar1,19+high(ar1)*2); + end; + ar1[index]:= atag; + inc(index); + ar1[index]:= avalue; + inc(index); + end; +end; + +procedure makecurrent(const gc: gcty); +begin + with oglgcty(gc.platformdata).d do begin +{$ifdef unix} + glxmakecurrent(fdpy,pd,fcontext); +{$else} + wglmakecurrent(fdc,fcontext); +{$endif} + end; +end; + +procedure setviewport(const agc: gcty; const arect: rectty); +//var +// int1: integer; +begin + with arect do begin + glviewport(x,oglgcty(agc.platformdata).d.top-gltopshift-y-cy,cx,cy); + glloadidentity; + if (cx > 0) and (cy > 0) then begin + glortho(glpixelshift,cx+glpixelshift,glpixelshift,cy+glpixelshift,-1,1); +// glortho(0,cx,0,cy,-1,1); +// glortho(-0.5,cx-0.5,-0.5,cy-1,-1,1); +// glortho(-1,cx-1,cy-1,-1,-1,1); + end; + end; +end; + +procedure gdi_setviewport(var drawinfo: drawinfoty); +begin + setviewport(drawinfo.gc,drawinfo.rect.rect^); +end; + +procedure initcontext(const winid: winidty; var gc: gcty; + const sourceviewport: rectty); +begin + gc.gdifuncs:= openglgetgdifuncs; + if winid <> 0 then begin + with oglgcty(gc.platformdata).d do begin + // pd:= winid; + top:= sourceviewport.cy+gltopshift; + tess:= glunewtess(); + makecurrent(gc); + glclearstencil(0); + glclear(gl_stencil_buffer_bit); + setviewport(gc,sourceviewport); + glpushattrib(gl_color_buffer_bit); //no mesa glflush until the first glpopattrib? + glpopattrib(); + glgentextures(1,@texture); + end; + end; +end; + +var + gccount: integer; + +function gdi_choosevisual(var gc: gcty; + const contextinfo: contextinfoty): gdierrorty; +{$ifdef unix} +var + index: integer; + ar1: integerarty; + int1,int2: integer; +{$endif} +begin + result:= gde_ok; + with oglgcty(gc.platformdata).d do begin +{$ifdef unix} + fvisinfo:= nil; + fdpy:= msedisplay; + fscreen:= msedefaultscreenno;//defaultscreen(fdpy); + if not glxqueryextension(fdpy,int1,int2) then begin + result:= gde_noglx; + exit; + end; + index:= 0; + with contextinfo.attrib do begin + putvalue(ar1,index,glx_level,level,0); + if not (df_canvasispixmap in gc.drawingflags) then begin + if doublebuffer then begin + include(gc.drawingflags,df_doublebuffer); + putboolean(ar1,index,glx_doublebuffer,doublebuffer); + end; + end; + putvalue(ar1,index,glx_buffer_size,buffersize,-1); +// putvalue(ar1,index,glx_level,level,0); + putboolean(ar1,index,glx_rgba,rgba); + putboolean(ar1,index,glx_stereo,stereo); + putvalue(ar1,index,glx_aux_buffers,auxbuffers,-1); + putvalue(ar1,index,glx_red_size,redsize,-1); + putvalue(ar1,index,glx_green_size,greensize,-1); + putvalue(ar1,index,glx_blue_size,bluesize,-1); + putvalue(ar1,index,glx_alpha_size,alphasize,-1); + putvalue(ar1,index,glx_depth_size,depthsize,-1); + putvalue(ar1,index,glx_stencil_size,stencilsize,-1); + putvalue(ar1,index,glx_accum_red_size,accumredsize,-1); + putvalue(ar1,index,glx_accum_green_size,accumgreensize,-1); + putvalue(ar1,index,glx_accum_blue_size,accumbluesize,-1); + putvalue(ar1,index,glx_accum_alpha_size,accumalphasize,-1); + setlength(ar1,index+1); //none + fvisinfo:= glxchoosevisual(fdpy,fscreen,pinteger(ar1)); + end; +// fvisinfo:= glxchoosevisual(fdpy,fscreen,pinteger(ar1)); + if fvisinfo = nil then begin + result:= gde_novisual; + exit; + end; + fcolormap:= xcreatecolormap(fdpy,gui_getrootwindow,fvisinfo^.visual,allocnone); +{$else} + with contextinfo.attrib do begin + doublebuf:= doublebuffer; + end; +{$endif} + end; +end; +(* +{$ifdef unix} + +function createrendercontext(const aparent: winidty; const windowrect: rectty; + const ainfo: contextinfoty; + var gc: gcty; out aid: winidty): guierrorty; +var + attributes: txsetwindowattributes; + err: gdierrorty; + +begin + result:= gue_ok; + with oglgcty(gc.platformdata).d do begin + err:= gdi_choosevisual(gc,ainfo); + if err <> gde_ok then begin + case err of + gde_noglx: begin + result:= gue_noglx; + end; + end; + exit; + end; + if fvisinfo = nil then begin + result:= gue_novisual; + exit; + end; + try + fcontext:= glxcreatecontext(fdpy,fvisinfo,nil,true); + if fcontext = nil then begin + result:= gue_rendercontext; + exit; + end; + gc.handle:= ptruint(fcontext); +// fcolormap:= xcreatecolormap(fdpy,mserootwindow,fvisinfo^.visual,allocnone); + attributes.colormap:= fcolormap; + with windowrect do begin + aid:= xcreatewindow(fdpy,aparent,x,y,cx,cy,0,fvisinfo^.depth, + inputoutput,fvisinfo^.visual,cwcolormap,@attributes); + xselectinput(fdpy,aid,exposuremask); //will be mapped to parent + end; + if aid = 0 then begin + result:= gue_createwindow; + exit; + end; + pd:= aid; + // fwin:= aid; + finally + xfree(fvisinfo); + fvisinfo:= nil; + end; + end; + initcontext(aid,gc,windowrect); +end; +{$endif} + +{$ifdef mswindows} +function createrendercontext(const aparent: winidty; const windowrect: rectty; + const ainfo: contextinfoty; + var gc: gcty; out aid: winidty): guierrorty; +var + pixeldesc: tpixelformatdescriptor; + int1: integer; + options1: internalwindowoptionsty; + wi1: windowty; +begin + result:= gue_ok; + fillchar(options1,sizeof(options1),0); + options1.parent:= aparent; + guierror(gui_createwindow(windowrect,options1,wi1)); + aid:= wi1.id; + if aid = 0 then begin + result:= gue_createwindow; + exit; + end; + with oglgcty(gc.platformdata).d do begin + pd:= aid; + fdc:= getdc(aid); + fillchar(pixeldesc,sizeof(pixeldesc),0); + with pixeldesc do begin + nsize:= sizeof(pixeldesc); + nversion:= 1; + dwflags:= pfd_draw_to_window or pfd_support_opengl or pfd_doublebuffer; + ipixeltype:= pfd_type_rgba; + ccolorbits:= 24; + cdepthbits:= 32; + end; + int1:= choosepixelformat(fdc,@pixeldesc); + setpixelformat(fdc,int1,@pixeldesc); + fcontext:= wglcreatecontext(fdc); + if fcontext = 0 then begin + result:= gue_rendercontext; + exit; + end; + gc.handle:= ptruint(fcontext); + end; + initcontext(aid,gc,windowrect); +end; +{$endif} +*) + +procedure colortogl(const source: colorty; out dest: glcolorty); +var + co1: rgbtriplety; +begin + co1:= colortorgb(source); + dest.r:= co1.red/255; + dest.g:= co1.green/255; + dest.b:= co1.blue/255; + dest.a:= 0; +end; + +procedure sendrect(const drawinfo: drawinfoty; const arect: rectty); +var + startx,starty,endx,endy: real; + texstartx,texstarty,texendx,texendy: real; + +begin + with drawinfo,oglgcty(gc.platformdata).d,arect do begin + startx:= (x+origin.x)+glpixelshift; + endx:= startx+cx; + starty:= (top-gltopshift-(y+origin.y))+glpixelshift; + endy:= starty-cy; + if ogcs_hastexture in gcstate then begin + texstartx:= (x+origin.x+gcbrushorigin.x)/brushsize.cx; + texendx:= texstartx + cx/brushsize.cx; + texstarty:= (y+origin.y+gcbrushorigin.y)/brushsize.cy; + texendy:= texstarty + cy/brushsize.cy; +// texstartx:= 0; +// texendx:= 1; +// texstarty:= -1; +// texendy:= 0; + gltexcoord2d(texstartx,texstarty); + glvertex2d(startx,starty); + gltexcoord2d(texendx,texstarty); + glvertex2d(endx,starty); + gltexcoord2d(texendx,texendy); + glvertex2d(endx,endy); + gltexcoord2d(texstartx,texendy); + glvertex2d(startx,endy); + end + else begin + glvertex2f(startx,starty); + glvertex2f(endx,starty); + glvertex2f(endx,endy); + glvertex2f(startx,endy); + end; + end; +end; + +procedure gdi_makecurrent(var drawinfo: drawinfoty); +begin + with oglgcty(drawinfo.gc.platformdata).d do begin +{$ifdef unix} +// glxmakecurrent(fdpy,drawinfo.paintdevice,fcontext); + glxmakecurrent(fdpy,pd,fcontext); +{$else} + wglmakecurrent(fdc,fcontext); +{$endif} + end; +end; + +{$ifdef unix} +var + linkgc: glxcontext; +{$endif} +var + screenextensions: glextensionsty; + screenextensionschecked: boolean; + pixmapextensions: glextensionsty; + pixmapextensionschecked: boolean; + +procedure gdi_createpixmap(var drawinfo: drawinfoty); //gdifunc +{$ifdef mswindows} +var + info: tbitmapinfo; + dc: hdc; +// po1: pointer; +{$endif} +begin + with drawinfo.createpixmap do begin + {$ifdef mswindows} + with info.bmiheader do begin + bisize:= sizeof(info.bmiheader); + biwidth:= size.cx; + biheight:= -size.cy; + biplanes:= 1; + bibitcount:= 32; + bicompression:= bi_rgb; + bisizeimage:= 0; + bixpelspermeter:= 3000; + biypelspermeter:= 3000; + biclrused:= 0; + biclrimportant:= 0; + end; + dc:= getdc(0); +// pixmap:= createdibsection(dc,info,dib_rgb_colors,po1,0,0); + pixmap:= createdibitmap(dc,info.bmiheader,0,nil,info,dib_rgb_colors); + releasedc(0,dc); + {$else} + pixmap:= gui_createpixmap(size,0,bmk_rgb{false},copyfrom); + //depht 1 not supported by glx ??? + {$endif} + end; +end; + +procedure gdi_creategc(var drawinfo: drawinfoty); //gdifunc +var + device1: ptruint; //used for extension query +{$ifdef unix} + attributes: txsetwindowattributes; +{$else} + pixeldesc: tpixelformatdescriptor; + int1: integer; + options1: internalwindowoptionsty; + wi1: windowty; +{$endif} +begin + if gccount = 0 then begin + initializeopengl([]); + end; + with drawinfo.creategc,oglgcty(gcpo^.platformdata).d do begin + error:= gdi_choosevisual(gcpo^,pcontextinfoty(contextinfopo)^); + if error <> gde_ok then begin + exit; + end; + {$ifdef unix} + if fvisinfo = nil then begin + error:= gde_novisual; + exit; + end; + if linkgc = nil then begin + linkgc:= glxcreatecontext(fdpy,fvisinfo,nil,true); + end; + try + fcontext:= glxcreatecontext(fdpy,fvisinfo,nil,true); + (* + fcontext:= glxcreatecontext(fdpy,visinfo,linkgc,false{kind <> gck_pixmap}{true}); + //crashes on suse 11.1 with true on pixmap + *) + if fcontext = nil then begin + error:= gde_rendercontext; + exit; + end; + device1:= 0; //not used + inc(gccount); + gcpo^.handle:= ptruint(fcontext); + fkind:= kind; + if kind = gck_pixmap then begin + pd:= 0; + pd:= glxcreateglxpixmap(fdpy,fvisinfo,paintdevice); + if pd = 0 then begin + error:= gde_glxpixmap; + end; + end + else begin + if paintdevice = 0 then begin + if createpaintdevice then begin + with windowrect^ do begin + fcolormap:= xcreatecolormap(fdpy,gui_getrootwindow,fvisinfo^.visual, + allocnone); + attributes.colormap:= fcolormap; + paintdevice:= xcreatewindow(fdpy,parent,x,y,cx,cy,0,fvisinfo^.depth, + inputoutput,fvisinfo^.visual,cwcolormap,@attributes); + if paintdevice = 0 then begin + error:= gde_createwindow; + exit; + end; + xselectinput(fdpy,paintdevice,exposuremask); //will be mapped to parent + gcpo^.paintdevicesize:= size; + end; + end; + end + else begin + fcolormap:= xcreatecolormap(fdpy,gui_getrootwindow,fvisinfo^.visual,allocnone); + xsetwindowcolormap(fdpy,paintdevice,fcolormap); + end; + pd:= paintdevice; + end; + finally + xfree(fvisinfo); + end; + {$else} + error:= gde_ok; +// fkind:= kind; + if paintdevice = 0 then begin + if createpaintdevice then begin + fillchar(options1,sizeof(options1),0); + options1.parent:= parent; + if gui_createwindow(windowrect^,options1,wi1) <> gue_ok then begin + error:= gde_createwindow; + exit; + end; + paintdevice:= wi1.id; + gcpo^.paintdevicesize:= windowrect^.size; + end; + end; + pd:= paintdevice; + fkind:= kind; + if kind = gck_pixmap then begin + fdc:= createcompatibledc(0); + selectobject(fdc,paintdevice); + end + else begin + fdc:= getdc(pd); + end; + device1:= fdc; + fillchar(pixeldesc,sizeof(pixeldesc),0); + with pixeldesc do begin + nsize:= sizeof(pixeldesc); + nversion:= 1; + dwflags:= pfd_support_opengl; + if doublebuf then begin + dwflags:= dwflags or pfd_doublebuffer; + end; + if kind = gck_pixmap then begin + dwflags:= dwflags or pfd_draw_to_bitmap; + end + else begin + dwflags:= dwflags or pfd_draw_to_window; + end; + ipixeltype:= pfd_type_rgba; + ccolorbits:= 32; + cdepthbits:= 16; + cstencilbits:= 8; + end; + fcontext:= 0; + int1:= choosepixelformat(fdc,@pixeldesc); + if int1 <> 0 then begin + if setpixelformat(fdc,int1,@pixeldesc) then begin + fcontext:= wglcreatecontext(fdc); + end + end; + if fcontext = 0 then begin + error:= gde_rendercontext; + exit; + end; + inc(gccount); + gcpo^.handle:= ptruint(fcontext); + {$endif} + if error = gde_ok then begin + initcontext(paintdevice,gcpo^,mr(nullpoint,gcpo^.paintdevicesize)); + if paintdevice <> 0 then begin + if (kind = gck_pixmap) then begin + if not pixmapextensionschecked then begin + makecurrent(gcpo^); + pixmapextensions:= gldeviceextensions(device1) + + mseglparseextensions(glgetstring(gl_extensions)); + pixmapextensionschecked:= true; + end; + extensions:= pixmapextensions; + end + else begin + if not screenextensionschecked then begin + makecurrent(gcpo^); + screenextensions:= gldeviceextensions(device1) + + mseglparseextensions(glgetstring(gl_extensions)); + screenextensionschecked:= true; + end; + extensions:= screenextensions; + end; + end; + end; + end; +end; + +procedure destroygc(var gc: gcty; const paintdevice: paintdevicety); +begin + with oglgcty(gc.platformdata).d do begin + if tess <> nil then begin + gludeletetess(tess); + end; +{$ifdef unix} + glxmakecurrent(fdpy,0,nil); + gldeletetextures(1,@texture); + glxdestroycontext(fdpy,fcontext); + if paintdevice <> 0 then begin + if fkind = gck_pixmap then begin + glxdestroyglxpixmap(fdpy,pd); + pd:= 0; + end + else begin + xfreecolormap(fdpy,fcolormap); + end; + end; + dec(gccount); + if (gccount = 0) and (linkgc <> nil) then begin + glxdestroycontext(fdpy,linkgc); + linkgc:= nil; + end; +{$else} + wglmakecurrent(0,0); + gldeletetextures(1,@texture); + wgldeletecontext(fcontext); + if fkind = gck_pixmap then begin + deletedc(fdc); + end + else begin + releasedc(paintdevice,fdc); + end; + dec(gccount); +{$endif} + if gccount = 0 then begin + releaseopengl(); + screenextensionschecked:= false; + pixmapextensionschecked:= false; + end; + end; +end; + + +procedure gdi_destroygc(var drawinfo: drawinfoty); //gdifunc +begin + destroygc(drawinfo.gc,drawinfo.paintdevice); +end; + +procedure gdi_swapbuffers(var drawinfo: drawinfoty); +begin + with oglgcty(drawinfo.gc.platformdata).d do begin + {$ifdef unix} + glxswapbuffers(fdpy,drawinfo.paintdevice); + {$else} + swapbuffers(fdc); + {$endif} + end; +end; + +procedure gdi_clear(var drawinfo: drawinfoty); +var + co1: glcolorty; +begin + with oglgcty(drawinfo.gc.platformdata).d do begin + colortogl(drawinfo.color.color,co1); + glclearcolor(co1.r,co1.g,co1.b,co1.a); + glclear(gl_color_buffer_bit); + + end; +end; + +{***************} + +const + rops: array[rasteropty] of integer = ( + //rop_clear, rop_and, rop_andnot, rop_copy, + gl_clear, gl_and, gl_and_reverse, gl_copy, + //rop_notand, rop_nop, rop_xor, rop_or, + gl_and_inverted, gl_noop, gl_xor, gl_or, + //rop_nor, rop_notxor, rop_not, rop_ornot, + gl_nor, gl_equiv, gl_invert, gl_or_reverse, + //rop_notcopy, rop_notor, rop_nand, rop_set + gl_copy_inverted, gl_or_inverted, gl_nand, gl_set + ); + +procedure setlogicop(const rasterop: rasteropty; const gc: gcty); +begin + if rasterop = rop_copy then begin + gllogicop(gl_copy); + if df_canvasismonochrome in gc.drawingflags then begin + gldisable(gl_index_logic_op); + end + else begin + gldisable(gl_color_logic_op); + end; + end + else begin +// gllogicop(rops[rasterop]); + if df_canvasismonochrome in gc.drawingflags then begin + glenable(gl_index_logic_op); + end + else begin + glenable(gl_color_logic_op); + end; + gllogicop(rops[rasterop]); + end; +end; + +//todo: optimize +function scaletopowerof2(const source: maskedimagety; + out dest: imagety): boolean; +//true if data copied +var + ps,pd: plongword; + pm: prgbtriplety; + int1,int2: integer; + scxw,scx,dcx,scy,dcy: integer; + xintp,yintp: integer; + lwos,lwod: longword; +begin + dest:= source.image; + result:= false; + if source.image.length > 0 then begin + with dest do begin + size.cx:= nextpowerof2(source.image.size.cx); + size.cy:= nextpowerof2(source.image.size.cy); + result:= (source.mask.pixels <> nil) and (source.mask.kind <> bmk_mono) + or (size.cx <> source.image.size.cx) or + (size.cy <> source.image.size.cy); + if result then begin + dcx:= size.cx; + dcy:= size.cy; + scx:= source.image.size.cx; + scy:= source.image.size.cy; + allocimage(dest,source.image.size,source.image.kind); + scxw:= dest.linelength; + { + if source.image.monochrome then begin + scxw:= ((dcx+31) div 32); + dest.pixels:= gui_allocimagemem(scxw*dcy); + end + else begin + dest.pixels:= gui_allocimagemem(dcx*dcy); + end; + } + ps:= pointer(source.image.pixels); + pd:= pointer(dest.pixels); + yintp:= dcy; + if (source.mask.pixels <> nil) and (source.mask.kind <> bmk_mono) then begin + //color mask + pm:= pointer(source.mask.pixels); + for int1:= dcy-1 downto 0 do begin + xintp:= dcx; + for int2:= dcx-1 downto 0 do begin + pd^:= ps^; + prgbtriplety(pd)^.res:= (word(pm^.red)+pm^.green+pm^.blue) div 3; + inc(pd); + dec(xintp,scx); + if xintp <= 0 then begin + inc(ps); + inc(pm); + inc(xintp,dcx); + end; + end; + dec(yintp,scy); + if yintp <= 0 then begin + inc(yintp,dcy); + end + else begin + dec(ps,scx); //duplicate row + dec(pm,scx); //duplicate row + end; + end; + end + else begin + if source.image.kind = bmk_mono then begin + //mask in monochrome not supported + for int1:= dcy-1 downto 0 do begin + xintp:= dcx; + pd^:= 0; + lwos:= 1; + lwod:= 1; + for int2:= dcx-1 downto 0 do begin + if ps^ and lwos <> 0 then begin + pd^:= pd^ or lwod; + end; + lwod:= lwod shl 1; + if lwod = 0 then begin + inc(pd); + lwod:= 1; + end; + dec(xintp,scx); + if xintp <= 0 then begin + lwos:= lwos shl 1; + if lwos = 0 then begin + inc(ps); + lwos:= 1; + end; + inc(xintp,dcx); + end; + end; + if lwod <> 1 then begin + inc(pd); + end; + if lwos <> 0 then begin + inc(ps); + end; + dec(yintp,scy); + if yintp <= 0 then begin + inc(yintp,dcy); + end + else begin + dec(ps,scxw); //duplicate row + end; + end; + end + else begin //rgb + for int1:= dcy-1 downto 0 do begin + xintp:= dcx; + for int2:= dcx-1 downto 0 do begin + pd^:= ps^; + inc(pd); + dec(xintp,scx); + if xintp <= 0 then begin + inc(ps); + inc(xintp,dcx); + end; + end; + dec(yintp,scy); + if yintp <= 0 then begin + inc(yintp,dcy); + end + else begin + dec(ps,scx); //duplicate row + end; + end; + end; + end; + end; + end; + end; +end; + +procedure settexture(const gc: gcty; const apixmap: tsimplebitmap); +var + mode,datatype: glenum; + im1: maskedimagety; + im2: imagety; + bo1: boolean; + map: array[0..1] of glfloat; +begin + with oglgcty(gc.platformdata).d do begin + glbindtexture(gl_texture_2d,texture); + mode:= gl_rgba; + if gle_gl_ext_bgra in extensions then begin + mode:= gl_bgra; + end; + im1:= tcanvas1(apixmap.canvas).getimage(mode = gl_rgba); + makecurrent(gc); //possibly changed by getimage + brushsize:= im1.image.size; + if (brushsize.cx = 0) or (brushsize.cy = 0) then begin + glteximage2d(gl_texture_2d,0,4,0,0,0,mode,gl_unsigned_byte,nil); + gldisable(gl_texture_2d); + exclude(gcstate,ogcs_hastexture); + exit; + end; + bo1:= scaletopowerof2(im1,im2); + if im1.mask.pixels <> nil then begin + include(gcstate,ogcs_needsblend); + end; + glpushclientattrib(gl_client_pixel_store_bit); + glpushattrib(gl_pixel_mode_bit); + if im2.kind = bmk_mono then begin + map[0]:= glcolorbackground.red/255; + map[1]:= glcolorforeground.red/255; + glpixelmapfv(gl_pixel_map_i_to_r,2,@map); + map[0]:= glcolorbackground.green/255; + map[1]:= glcolorforeground.green/255; + glpixelmapfv(gl_pixel_map_i_to_g,2,@map); + map[0]:= glcolorbackground.blue/255; + map[1]:= glcolorforeground.blue/255; + glpixelmapfv(gl_pixel_map_i_to_b,2,@map); + if df_opaque in gc.drawingflags then begin + map[0]:= 1; + end + else begin + map[0]:= 0; + include(gcstate,ogcs_needsblend); + end; + map[1]:= 1; + glpixelmapfv(gl_pixel_map_i_to_a,2,@map); + mode:= gl_color_index; + datatype:= gl_bitmap; + glpixelstorei(gl_unpack_lsb_first,1); + end + else begin + datatype:= gl_unsigned_byte; + if im1.mask.pixels = nil then begin + glpixeltransferf(gl_alpha_scale,0); + glpixeltransferf(gl_alpha_bias,1); + end; + end; + with im2 do begin + glteximage2d(gl_texture_2d,0,4,size.cx,size.cy,0,mode,datatype,pixels); + end; + if bo1 then begin + gui_freeimagemem(im2.pixels); + end; + glpopattrib; + glpopclientattrib; + gltexenvi(gl_texture_env,gl_texture_env_mode,gl_replace); + gltexparameteri(gl_texture_2d, gl_texture_wrap_s, gl_repeat); + gltexparameteri (gl_texture_2d, gl_texture_wrap_t, gl_repeat); + gltexparameteri (gl_texture_2d, gl_texture_mag_filter, gl_nearest); + gltexparameteri (gl_texture_2d, gl_texture_min_filter, gl_nearest); + end; +end; + +procedure gdi_changegc(var drawinfo: drawinfoty); +var + po1: pstripety; + int1,int2,int3,int4: integer; + y1,x1: integer; + statebefore: oglgcstatesty; +begin + with drawinfo.gcvalues^,drawinfo.gc,oglgcty(platformdata).d do begin + statebefore:= gcstate; + if gvm_colorforeground in mask then begin + glcolorforeground:= colortorgb(drawinfo.acolorforeground); + with glcolorforeground do begin + glcolor3ub(red,green,blue); + end; + end; + if gvm_colorbackground in mask then begin + glcolorbackground:= colortorgb(drawinfo.acolorbackground); + //rgbtriplety(colorbackground); + end; + if gvm_rasterop in mask then begin + setlogicop(rasterop,drawinfo.gc); + gcrasterop:= rasterop; + end; + if gvm_brush in mask then begin + settexture(drawinfo.gc,brush); + end; + if gvm_brushorigin in mask then begin + gcbrushorigin:= brushorigin; + end; + if drawingflagsty((longword(drawingflags) xor + longword(gcdrawingflags))) * [df_brush]{fillmodeinfoflags} <> [] then begin + updatebit1(longword(gcstate),ord(ogcs_hastexture), + (df_brush in drawingflags) and + (brushsize.cx > 0) and (brushsize.cy > 0)); + end; + gcdrawingflags:= drawingflags; + if gvm_options in mask then begin + if (cao_smooth in options) xor + (cao_smooth in gcoptions) then begin + if cao_smooth in options then begin + glenable(gl_line_smooth); + glenable(gl_polygon_smooth); + glenable(gl_blend); + glblendfunc(gl_src_alpha,gl_one_minus_src_alpha); + end + else begin + gldisable(gl_line_smooth); + gldisable(gl_polygon_smooth); + gldisable(gl_blend); + end; + end; + gcoptions:= options; + end; + + if gvm_font in mask then begin +// ftglfont:= pftglfontty(font)^; + glfont:= font; + end; + if gvm_clipregion in mask then begin + if clipregion = 0 then begin + gldisable(gl_stencil_test); + exclude(gcstate,ogcs_hasclipreg); + end + else begin + include(gcstate,ogcs_hasclipreg); + glclearstencil(0); + glclear(gl_stencil_buffer_bit); + glenable(gl_stencil_test); + glstencilfunc(gl_never,1,1); + glstencilop(gl_replace,gl_keep,gl_keep); + with pregioninfoty(clipregion)^ do begin + if rectcount > 0 then begin + glbegin(gl_quads); + y1:= top-(stripestart+cliporigin.y); + po1:= datapo; + for int1:= stripecount-1 downto 0 do begin + int3:= y1; + x1:= cliporigin.x; + y1:= y1 - po1^.header.height; //next stripe + int2:= po1^.header.rectcount -1; + po1:= @po1^.data; + for int2:= int2 downto 0 do begin + x1:= x1 + prectextentty(po1)^; //gap + glvertex2i(x1,int3); + inc(prectextentty(po1)); + int4:= x1; + x1:= x1 + prectextentty(po1)^; + glvertex2i(x1,int3); + glvertex2i(x1,y1); + glvertex2i(int4,y1); + inc(prectextentty(po1)); + end; + end; + glend; + end; + end; + glstencilop(gl_keep,gl_keep,gl_keep); + glstencilfunc(gl_equal,1,1); + end; + end; + statebefore:= oglgcstatesty(longword(statebefore) xor longword(gcstate)); + if ogcs_hastexture in statebefore then begin + if ogcs_hastexture in gcstate then begin + glenable(gl_texture_2d); + end + else begin + gldisable(gl_texture_2d); + end; + end; + if ogcs_needsblend in statebefore then begin + if ogcs_needsblend in gcstate then begin + glenable(gl_blend); + glblendfunc(gl_src_alpha,gl_one_minus_src_alpha); + end + else begin + gldisable(gl_blend); + end; + end; + end; +end; + +procedure gdi_getcanvasclass(var drawinfo: drawinfoty); //gdifunc +begin + with drawinfo.getcanvasclass do begin +// if not monochrome then begin + canvasclass:= topenglwindowcanvas; +// end; + end; +end; + +procedure gdi_endpaint(var drawinfo: drawinfoty); //gdifunc +begin + if df_doublebuffer in drawinfo.gc.drawingflags then begin + gdi_swapbuffers(drawinfo); + end + else begin + glflush(); + end; +end; + +procedure gdi_flush(var drawinfo: drawinfoty); //gdifunc +begin + glflush(); +end; + +procedure gdi_drawlines(var drawinfo: drawinfoty); +var + po1: ppointty; + int1,int2: integer; +begin + int2:= oglgcty(drawinfo.gc.platformdata).d.top; + with drawinfo,points do begin + if closed then begin + glbegin(gl_line_loop); + end + else begin + glbegin(gl_line_strip); + end; + po1:= points; + for int1:= count-1 downto 0 do begin + glvertex2i(po1^.x+origin.x,int2-(po1^.y+origin.y)); + inc(po1); + end; + end; + glend; +end; + +procedure gdi_drawlinesegments(var drawinfo: drawinfoty); +var + po1: ppointty; + int1,int2: integer; +begin + int2:= oglgcty(drawinfo.gc.platformdata).d.top; + glbegin(gl_lines); + with drawinfo,points do begin + po1:= points; + for int1:= count-1 downto 0 do begin + glvertex2i(po1^.x+origin.x,int2-(po1^.y+origin.y)); + inc(po1); + end; + end; + glend; +end; + +procedure drawlines(const gc: gcty; const points: pfpointty; + const count: integer; const close: boolean); +var + po1: pfpointty; + int1,int2: integer; +begin + int2:= oglgcty(gc.platformdata).d.top; + if close then begin + int1:= gl_line_loop; + end + else begin + int1:= gl_line; + end; + glbegin(int1); + po1:= points; + for int1:= count-1 downto 0 do begin + glvertex2f(po1^.x,int2-po1^.y); + inc(po1); + end; + glend; +end; + +procedure gdi_drawellipse(var drawinfo: drawinfoty); +begin + segmentellipsef(drawinfo,@drawlines); +end; + +procedure gdi_drawarc(var drawinfo: drawinfoty); +begin + gdinotimplemented; +end; + +procedure gdi_fillrect(var drawinfo: drawinfoty); +begin + glbegin(gl_quads); + sendrect(drawinfo,drawinfo.rect.rect^); + glend; +end; + +procedure gdi_fillellipse(var drawinfo: drawinfoty); +begin + gdinotimplemented; +end; + +procedure gdi_fillarc(var drawinfo: drawinfoty); +begin + gdinotimplemented; +end; + +procedure tesserror(err: glenum); {$ifdef mswindows}stdcall;{$else}cdecl;{$endif} +begin +end; + +type + vertexpoar4ty = array[0..3] of pgluvertexty; + pvertexpoar4ty = ^vertexpoar4ty; + glfloatar4ty = array[0..3] of glfloat; + pglfloatar4ty = ^glfloatar4ty; + +var + tessbuffer: array of pgluvertexty; + tessbufferindex: integer; + +function gettessbuffer: pgluvertexty; +var + int1: integer; +begin + if tessbufferindex > high(tessbuffer) then begin + setlength(tessbuffer,high(tessbuffer)*2+32); + for int1:= tessbufferindex to high(tessbuffer) do begin + getmem(tessbuffer[int1],sizeof(gluvertexty)); + end; + result:= tessbuffer[tessbufferindex]; + end; + result:= tessbuffer[tessbufferindex]; + inc(tessbufferindex); +end; + +procedure freebuffers; +var + int1: integer; +begin + for int1:= high(tessbuffer) downto 0 do begin + freemem(tessbuffer[int1]); + end; + { + if stockpixmapgc <> 0 then begin + glxdestroycontext(msedisplay,stockpixmapgc); + end; + } +end; +{ +procedure checkstockpixmapgc; +begin + if stockpixmapgc = 0 then begin + + fillchar(stockgc,sizeof(stockgc),0); + fillchar(info,sizeof(drawinfoty),0); + with info.creategc do begin + kind:= gck_pixmap; + contextinfopo:= @defaultcontextattributes; + end; +end; +} +procedure tesscombine(coords: pgluvertexty; + vertex_data: pvertexpoar4ty; + weight: pglfloatar4ty; + outdata: ppgluvertexty; + polygon_data: pointer); + {$ifdef mswindows}stdcall;{$else}cdecl;{$endif} +//var +// po1: pgluvertexty; +begin +// po1:= gettessbuffer; //not used +// po1^:= coords^; +// outdata^:= po1; + outdata^:= coords; +end; + +procedure gdi_fillpolygon(var drawinfo: drawinfoty); +var + int1: integer; + do1: double; +// vertex: gluvertexty; + po1: ppointty; + po2: pgluvertexty; +begin + with drawinfo,points,oglgcty(drawinfo.gc.platformdata).d do begin + glutesscallback(tess, glu_tess_error, tcallback(@tesserror)); + glutesscallback(tess, glu_tess_begin, tcallback(glbegin)); + glutesscallback(tess, glu_tess_vertex, tcallback(glvertex3dv)); + glutesscallback(tess, glu_tess_combine_data, tcallback(@tesscombine)); + glutesscallback(tess, glu_tess_end, tcallback(glend)); + po1:= points; + allocbuffer(drawinfo.buffer,count*sizeof(gluvertexty)); + tessbufferindex:= 0; + po2:= drawinfo.buffer.buffer; + do1:= top; + glutessbeginpolygon(tess,@drawinfo.gc); + glutessbegincontour(tess); + for int1:= count-1 downto 0 do begin + with po2^ do begin + x:= po1^.x+origin.x; + y:= do1-(po1^.y+origin.y); + z:= 0; + end; + glutessvertex(tess,p3darray(po2)^,po2); + inc(po1); + inc(po2); + end; + glutessendcontour(tess); + glutessendpolygon(tess); + end; +end; + +procedure gdi_drawstring16(var drawinfo: drawinfoty); +begin + fontcache.drawstring16(drawinfo, + oglgcty(drawinfo.gc.platformdata).d.glfont); +end; + +procedure gdi_setcliporigin(var drawinfo: drawinfoty); +begin +end; + +procedure setrasterpos(const agc: gcty; const apos: pointty); +begin + glrasterpos2f(0.999*glpixelshift,0.999*glpixelshift); + glbitmap(0,0,0,0,apos.x,oglgcty(agc.platformdata).d.top-apos.y,nil); +end; + +procedure copyareaself(var drawinfo: drawinfoty); +var + xscale,yscale: real; +begin + with drawinfo.copyarea,oglgcty(drawinfo.gc.platformdata).d do begin + with destrect^ do begin + glpushattrib(gl_pixel_mode_bit); + xscale:= cx/sourcerect^.cx; + yscale:= cy/sourcerect^.cy; + setrasterpos(drawinfo.gc,mp(x,y+cy)); +// glrasterpos2i(x,(top-y-cy)); + glpixelzoom(xscale,yscale); + with sourcerect^ do begin + glcopypixels(x,top-y-cy,cx,cy,gl_color); + end; + glpopattrib; + end; + end; +end; + +procedure gdi_movewindowrect(var drawinfo: drawinfoty); //gdifunc +begin + glpushattrib(gl_enable_bit); + gldisable(gl_stencil_test); + gldisable(gl_blend); + with drawinfo.moverect,oglgcty(drawinfo.gc.platformdata).d do begin + with rect^ do begin + setrasterpos(drawinfo.gc,mp(x+dist^.x,y+dist^.y+cy)); + glcopypixels(x,top-y-cy,cx,cy,gl_color); + end; + end; + glpopattrib; +end; + +procedure copyareagl(var drawinfo: drawinfoty); +//todo: use persistent pixmap or texture buffer +//suse 11.4 crashes with dri shared buffers and does +//not support non dri shared buffers... +//suse 11.1 crashes with dri pixmaps... + +var +// buf: gluint; + xscale,yscale: real; +// ar1: rgbtriplearty; +// l,t,r,b,w,h: integer; +// pt1: pointty; + int1: integer; + po1: prgbtriplety; + po2: pbyte; + size1: integer; + transparentcolor1: pixelty; +const + co0: rgbtriplety = (blue: $00; green: $00; red: $00; res: $ff); + co1: rgbtriplety = (blue: $ff; green: $ff; red: $ff; res: $ff); +begin + with drawinfo.copyarea,oglgcty(drawinfo.gc.platformdata).d do begin + makecurrent(tcanvas1(source).fdrawinfo.gc); + with sourcerect^ do begin + size1:= cx*cy; + getmem(po1,size1*sizeof(rgbtriplety)); +// setlength(ar1,cx*cy); + glreadpixels(x, + oglgcty(tcanvas1(source).fdrawinfo.gc.platformdata).d.top-y-cy+1, + cx,cy,gl_rgba,gl_unsigned_byte,po1); + if mask <> nil then begin + tcanvas1(mask.canvas).checkgcstate([cs_gc]); + makecurrent(tcanvas1(mask.canvas).fdrawinfo.gc); + getmem(po2,cx*cy); + glpushclientattrib(gl_client_pixel_store_bit); + glpixelstorei(gl_pack_alignment,1); + glreadpixels(x, + oglgcty(tcanvas1(source).fdrawinfo.gc.platformdata).d.top-y-cy+1, + cx,cy,gl_luminance,gl_unsigned_byte,po2); + glpopclientattrib; + for int1:= cx*cy-1 downto 0 do begin + prgbtripleaty(po1)^[int1].res:= pbyteaty(po2)^[int1]; + end; + end; + end; + makecurrent(drawinfo.gc); + int1:= gl_pixel_mode_bit; + if mask <> nil then begin + int1:= int1 or gl_color_buffer_bit; + end; + glpushattrib(int1); + if df_colorconvert in drawinfo.gc.drawingflags then begin + if df_canvasismonochrome in + tcanvas1(source).fdrawinfo.gc.drawingflags then begin + glpixeltransferf(gl_red_bias,glcolorbackground.red/255); + glpixeltransferf(gl_red_scale, + (glcolorforeground.red-glcolorbackground.red)/255); + glpixeltransferf(gl_green_bias,glcolorbackground.green/255); + glpixeltransferf(gl_green_scale, + (glcolorforeground.green-glcolorbackground.green)/255); + glpixeltransferf(gl_blue_bias,glcolorbackground.blue/255); + glpixeltransferf(gl_blue_scale, + (glcolorforeground.blue-glcolorbackground.blue)/255); + end + else begin + transparentcolor1:= transparentcolor; + rgbtriplety(transparentcolor1).res:= $ff; + for int1:= size1-1 downto 0 do begin + if ppixelaty(po1)^[int1] = transparentcolor1 then begin + plongwordaty(po1)^[int1]:= pixelty(co0); + end + else begin + plongwordaty(po1)^[int1]:= pixelty(co1); + end; + end; + end; + end; + if mask <> nil then begin + glenable(gl_blend); + glblendfunc(gl_src_alpha,gl_one_minus_src_alpha); + end; + with destrect^ do begin + xscale:= cx/sourcerect^.cx; + yscale:= cy/sourcerect^.cy; + glpixelzoom(xscale,yscale); + setrasterpos(drawinfo.gc,mp(x,y+cy-1)); + gldrawpixels(sourcerect^.cx,sourcerect^.cy,gl_rgba,gl_unsigned_byte,po1); + end; + glpopattrib; + freemem(po1); + if mask <> nil then begin + freemem(po2); + end; + end; +(* buffer objects are unreliable + with drawinfo.copyarea,oglgcty(drawinfo.gc.platformdata).d do begin + makecurrent(tcanvas1(source).fdrawinfo.gc); + glgenbuffers(1,@buf); + glpushclientattrib(gl_client_pixel_store_bit); + glpushattrib(gl_pixel_mode_bit); + glpixeltransferf(gl_alpha_scale,0); + glpixeltransferf(gl_alpha_bias,1); + with sourcerect^ do begin + glbufferdata(gl_pixel_pack_buffer,cx*cy*sizeof(rgbtriplety),nil,gl_stream_draw); + glbindbuffer(gl_pixel_pack_buffer,buf); + glreadpixels(x,sourceheight-y-cy,cx,cy,gl_bgra,gl_unsigned_byte,nil); + end; + glbindbuffer(gl_pixel_pack_buffer,0); + makecurrent(drawinfo.gc); + glbindbuffer(gl_pixel_unpack_buffer,buf); + with destrect^ do begin + xscale:= cx/sourcerect^.cx; + yscale:= cy/sourcerect^.cy; + glrasterpos2i(x,(sourceheight-y-cy)); + glpixelzoom(xscale,yscale); + end; + with sourcerect^ do begin +//glbindbuffer(gl_pixel_unpack_buffer,0); + + gldrawpixels(cx,cy,gl_bgra,gl_unsigned_byte,nil); + end; + glbindbuffer(gl_pixel_unpack_buffer,0); + + glpopclientattrib; + glpopattrib; + gldeletebuffers(1,@buf); + end; + *) +end; + +//todo: optimize, use data window + +procedure gdi_copyarea(var drawinfo: drawinfoty); +var + im1: maskedimagety; + mode,datatype: glenum; + map: array[0..1] of glfloat; + opacity1: glfloat; +// monomask: boolean; + ps1,pd1: prgbtripleaty; +// ps2: plongword; +// pd2: prgbtriplety; + int1: integer; + wo1: word; +// lwo1: longword; + +begin + with drawinfo.copyarea,oglgcty(drawinfo.gc.platformdata).d do begin + if copymode <> gcrasterop then begin + setlogicop(copymode,drawinfo.gc); + end; + end; + + if tcanvas1(drawinfo.copyarea.source).fdrawinfo.gc.handle = + drawinfo.gc.handle then begin + copyareaself(drawinfo); + end + else begin + if tcanvas1(drawinfo.copyarea.source).fdrawinfo.gc.gdifuncs = + drawinfo.gc.gdifuncs then begin + copyareagl(drawinfo); + end + else begin //foreign gdi + with drawinfo.copyarea,oglgcty(drawinfo.gc.platformdata).d do begin + mode:= gl_rgba; + if gle_gl_ext_bgra in extensions then begin + mode:= gl_bgra; + end; + im1:= tcanvas1(source).getimage(mode = gl_rgba); + makecurrent(drawinfo.gc); + if (im1.image.size.cx = 0) or (im1.image.size.cy = 0) then begin + exit; + end; + glpushclientattrib(gl_client_pixel_store_bit); + glpushattrib(gl_pixel_mode_bit or gl_color_buffer_bit or + gl_stencil_buffer_bit); + wo1:= word(opacity.red)+opacity.blue+opacity.red+opacity.blue; + if wo1 = 3*255 then begin + opacity1:= 1; + end + else begin + opacity1:= wo1/(3*255); + end; + with sourcerect^ do begin + glpixelzoom(destrect^.cx/cx,-destrect^.cy/cy); + glpixelstorei(gl_unpack_row_length,im1.image.size.cx); + glpixelstorei(gl_unpack_skip_pixels,x); + glpixelstorei(gl_unpack_skip_rows,y); + end; + setrasterpos(drawinfo.gc,destrect^.pos); + glpixelstorei(gl_unpack_lsb_first,1); + if (im1.mask.kind = bmk_mono) and (im1.mask.pixels <> nil) then begin + glstencilmask(2); + glpixeltransferi(gl_index_shift,1); + with sourcerect^ do begin + gldrawpixels(cx,cy,gl_stencil_index,gl_bitmap,im1.mask.pixels); + end; + glpixeltransferi(gl_index_shift,0); + if ogcs_hasclipreg in gcstate then begin + int1:= 3; //combine mask and clipregion + end + else begin + int1:= 2; + glenable(gl_stencil_test); + end; + glstencilfunc(gl_equal,int1,int1); + end; + if im1.image.kind = bmk_mono then begin + datatype:= gl_bitmap; + mode:= gl_color_index; + map[0]:= glcolorbackground.red/255; + map[1]:= glcolorforeground.red/255; + glpixelmapfv(gl_pixel_map_i_to_r,2,@map); + map[0]:= glcolorbackground.green/255; + map[1]:= glcolorforeground.green/255; + glpixelmapfv(gl_pixel_map_i_to_g,2,@map); + map[0]:= glcolorbackground.blue/255; + map[1]:= glcolorforeground.blue/255; + glpixelmapfv(gl_pixel_map_i_to_b,2,@map); + if df_opaque in drawinfo.gc.drawingflags then begin + map[0]:= opacity1; + if opacity1 < 1 then begin + glenable(gl_blend); + glblendfunc(gl_src_alpha,gl_one_minus_src_alpha); + end; + end + else begin + map[0]:= 0; + glenable(gl_blend); + glblendfunc(gl_src_alpha,gl_one_minus_src_alpha); + end; + map[1]:= opacity1; + glpixelmapfv(gl_pixel_map_i_to_a,2,@map); + end + else begin + if (im1.mask.pixels <> nil) and (im1.mask.kind <> bmk_mono) then begin + { + if im1.mask.monochrome then begin + pd2:= prgbtriplety(im1.image.pixels); + ps2:= plongword(im1.mask.pixels); + for int1:= 0 to im1.image.size.cy - 1 do begin + lwo1:= 1; + for int2:= 0 to im1.image.size.cx - 1 do begin + if ps2^ and lwo1 <> 0 then begin + pd2^.res:= $ff; + end + else begin + pd2^.res:= $00; + end; + lwo1:= lwo1 shl 1; + if lwo1 = 0 then begin + inc(ps2); + lwo1:= 1; + end; + end; + if lwo1 <> 1 then begin + inc(ps2); + end; + end; + end + else begin + } + pd1:= prgbtripleaty(im1.image.pixels); + ps1:= prgbtripleaty(im1.mask.pixels); + for int1:= im1.image.length-1 downto 0 do begin + with ps1^[int1] do begin + pd1^[int1].res:= (word(red)+green+blue) div 3; + end; + end; + glenable(gl_blend); + glblendfunc(gl_src_alpha,gl_one_minus_src_alpha); + end + else begin + glpixeltransferf(gl_alpha_scale,0); + glpixeltransferf(gl_alpha_bias,1); + end; + datatype:= gl_unsigned_byte; + end; + with sourcerect^ do begin + gldrawpixels(cx,cy,mode,datatype,im1.image.pixels); + end; + glpopclientattrib; + glpopattrib; + end; + end; + end; + with drawinfo.copyarea,oglgcty(drawinfo.gc.platformdata).d do begin + if copymode <> gcrasterop then begin + setlogicop(gcrasterop,drawinfo.gc); + end; + end; +end; + +procedure getimage(var drawinfo: drawinfoty; var image: imagety); + +//todo: optimize +var + int1,int2,int3: integer; + po1,ps1,pd1: pchar; + pd2: plongword; + lwo1: longword; + mode,datatype: glenum; +begin + with drawinfo,oglgcty(drawinfo.gc.platformdata).d do begin + with image do begin + if kind = bmk_mono then begin + datatype:= gl_unsigned_byte; + mode:= gl_luminance; + getmem(po1,size.cx*size.cy); + glpushclientattrib(gl_client_pixel_store_bit); + glpixelstorei(gl_pack_alignment,1); + glreadpixels(0,0,size.cx,size.cy,mode,datatype,po1); + glpopclientattrib; + ps1:= pointer(pchar(po1)+(size.cy-1)*size.cx); //top row + pd2:= pointer(pixels); + for int1:= size.cy-1 downto 0 do begin + pd2^:= 0; + lwo1:= 1; + for int3:= size.cx-1 downto 0 do begin + if ps1^ <> #0 then begin + pd2^:= pd2^ or lwo1; + end; + inc(ps1); + lwo1:= lwo1 shl 1; + if lwo1 = 0 then begin + inc(pd2); + lwo1:= 1; + end; + end; + dec(ps1,2*size.cx); //next row + if lwo1 <> 1 then begin + inc(pd2); + end; + end; + freemem(po1); + end + else begin + glpushattrib(gl_pixel_mode_bit); + + glpixeltransferf(gl_alpha_scale,0); + glpixeltransferf(gl_alpha_bias,0); + datatype:= gl_unsigned_byte; + if not bgr and (gle_GL_EXT_bgra in extensions) then begin + mode:= gl_bgra; + end + else begin + mode:= gl_rgba; + bgr:= true; + end; + if gle_gl_mesa_pack_invert in extensions then begin + glpushclientattrib(gl_client_pixel_store_bit); + glpixelstorei(gl_pack_invert_mesa,1); + glreadpixels(0,0,size.cx,size.cy,mode,datatype,pixels); + glpopclientattrib; + end + else begin + getmem(po1,length*sizeof(rgbtriplety)); + glreadpixels(0,0,size.cx,size.cy,mode,datatype,po1); + int2:= sizeof(rgbtriplety)*size.cx; + ps1:= pointer(pchar(po1)+(size.cy-1)*int2); //top row + pd1:= pointer(pixels); + for int1:= size.cy-1 downto 0 do begin + move(ps1^,pd1^,int2); + dec(ps1,int2); + inc(pd1,int2); + end; + freemem(po1); + end; + glpopattrib; + end; + end; + end; +end; + +procedure gdi_getimage(var drawinfo: drawinfoty); +begin + getimage(drawinfo,drawinfo.getimage.image.image); + drawinfo.getimage.error:= gde_ok; +end; + +procedure gdi_pixmaptoimage(var drawinfo: drawinfoty); //gdifunc +begin + with drawinfo.pixmapimage do begin + if drawinfo.gc.handle <> 0 then begin + allocimage(image,drawinfo.gc.paintdevicesize,drawinfo.gc.kind); + getimage(drawinfo,image); + end + else begin + gui_pixmaptoimage(pixmap,image,drawinfo.gc.handle); + end; + end; +end; + +procedure gdi_imagetopixmap(var drawinfo: drawinfoty); //gdifunc +var + im1: imagety; + ps1,pd1: plongword; + int1,int2: integer; + lwo1: longword; +begin + with drawinfo.pixmapimage do begin + if image.kind = bmk_mono then begin + with image do begin + allocimage(im1,size,bmk_rgb); + ps1:= pointer(pixels); +// pd1:= plongword(im1.pixels)+(size.cy-1)*size.cx; //top row + pd1:= pointer(im1.pixels); + for int1:= size.cy-1 downto 0 do begin + lwo1:= 1; + for int2:= size.cx-1 downto 0 do begin + if ps1^ and lwo1 <> 0 then begin + pd1^:= $00ffffff; + end + else begin + pd1^:= $00000000; + end; + inc(pd1); + lwo1:= lwo1 shl 1; + if lwo1 = 0 then begin + inc(ps1); + lwo1:= 1; + end; + end; +// dec(pd1,2*size.cx); //next row + if lwo1 <> 1 then begin + inc(ps1); + end; + end; + end; + error:= gui_imagetopixmap(im1,pixmap,0); + gui_freeimagemem(im1.pixels); + end + else begin + error:= gui_imagetopixmap(image,pixmap,0); + end; + end; +end; + +procedure gdi_fonthasglyph(var drawinfo: drawinfoty); +begin + gdinotimplemented; +end; + +procedure gdi_getfont(var drawinfo: drawinfoty); +begin + fontcache.getfont(drawinfo); +end; + +procedure gdi_getfonthighres(var drawinfo: drawinfoty); +begin + gdinotimplemented; +end; + +procedure gdi_freefontdata(var drawinfo: drawinfoty); +begin + if ffontcache <> nil then begin + fontcache.freefontdata(drawinfo); + end; +end; + +procedure gdi_gettext16width(var drawinfo: drawinfoty); +begin + fontcache.gettext16width(drawinfo); +end; + +procedure gdi_getchar16widths(var drawinfo: drawinfoty); +begin + fontcache.getchar16widths(drawinfo); +end; + +procedure gdi_getfontmetrics(var drawinfo: drawinfoty); +begin + fontcache.getfontmetrics(drawinfo); +end; + +const + gdifunctions: gdifunctionaty = ( + {$ifdef FPC}@{$endif}gdi_creategc, + {$ifdef FPC}@{$endif}gdi_destroygc, + {$ifdef FPC}@{$endif}gdi_changegc, + {$ifdef FPC}@{$endif}gdi_createpixmap, + {$ifdef FPC}@{$endif}gdi_pixmaptoimage, + {$ifdef FPC}@{$endif}gdi_imagetopixmap, + {$ifdef FPC}@{$endif}gdi_getcanvasclass, + {$ifdef FPC}@{$endif}gdi_endpaint, + {$ifdef FPC}@{$endif}gdi_flush, + {$ifdef FPC}@{$endif}gdi_movewindowrect, + {$ifdef FPC}@{$endif}gdi_drawlines, + {$ifdef FPC}@{$endif}gdi_drawlinesegments, + {$ifdef FPC}@{$endif}gdi_drawellipse, + {$ifdef FPC}@{$endif}gdi_drawarc, + {$ifdef FPC}@{$endif}gdi_fillrect, + {$ifdef FPC}@{$endif}gdi_fillellipse, + {$ifdef FPC}@{$endif}gdi_fillarc, + {$ifdef FPC}@{$endif}gdi_fillpolygon, + {$ifdef FPC}@{$endif}gdi_drawstring16, + {$ifdef FPC}@{$endif}gdi_setcliporigin, + {$ifdef FPC}@{$endif}msegenericgdi.gdi_createemptyregion, + {$ifdef FPC}@{$endif}msegenericgdi.gdi_createrectregion, + {$ifdef FPC}@{$endif}msegenericgdi.gdi_createrectsregion, + {$ifdef FPC}@{$endif}msegenericgdi.gdi_destroyregion, + {$ifdef FPC}@{$endif}msegenericgdi.gdi_copyregion, + {$ifdef FPC}@{$endif}msegenericgdi.gdi_moveregion, + {$ifdef FPC}@{$endif}msegenericgdi.gdi_regionisempty, + {$ifdef FPC}@{$endif}msegenericgdi.gdi_regionclipbox, + {$ifdef FPC}@{$endif}msegenericgdi.gdi_regsubrect, + {$ifdef FPC}@{$endif}msegenericgdi.gdi_regsubregion, + {$ifdef FPC}@{$endif}msegenericgdi.gdi_regaddrect, + {$ifdef FPC}@{$endif}msegenericgdi.gdi_regaddregion, + {$ifdef FPC}@{$endif}msegenericgdi.gdi_regintersectrect, + {$ifdef FPC}@{$endif}msegenericgdi.gdi_regintersectregion, + {$ifdef FPC}@{$endif}gdi_copyarea, + {$ifdef FPC}@{$endif}gdi_getimage, + {$ifdef FPC}@{$endif}gdi_fonthasglyph, + {$ifdef FPC}@{$endif}gdi_getfont, + {$ifdef FPC}@{$endif}gdi_getfonthighres, + {$ifdef FPC}@{$endif}gdi_freefontdata, + {$ifdef FPC}@{$endif}gdi_gettext16width, + {$ifdef FPC}@{$endif}gdi_getchar16widths, + {$ifdef FPC}@{$endif}gdi_getfontmetrics +); + +function openglgetgdifuncs: pgdifunctionaty; +begin + result:= @gdifunctions; +end; + +{ tglftfontcache } + +procedure tglftfontcache.drawglyph(var drawinfo: drawinfoty; const pos: pointty; + const bitmap: pbitmapdataty); +begin + setrasterpos(drawinfo.gc,pos); + with bitmap^ do begin + gldrawpixels(width,height,gl_alpha,gl_unsigned_byte,@data); + end; +end; + +procedure tglftfontcache.drawstring16(var drawinfo: drawinfoty; + const afont: fontty); +var + rect1: rectty; +begin + with oglgcty(drawinfo.gc.platformdata).d do begin + if df_opaque in drawinfo.gc.drawingflags then begin + if textbackgroundrect(drawinfo,afont,rect1) then begin + with glcolorbackground do begin + glcolor3ub(red,green,blue); + end; + glbegin(gl_quads); + sendrect(drawinfo,rect1); + glend; + end; + end; + glpushclientattrib(gl_client_pixel_store_bit); + glpushattrib(gl_pixel_mode_bit or gl_color_buffer_bit); + glpixelstorei(gl_unpack_row_length, 0); + glpixelstorei(gl_unpack_alignment, 1); + glenable(gl_blend); + glblendfunc(gl_src_alpha,gl_one_minus_src_alpha); + with glcolorforeground do begin + glpixeltransferf(gl_red_scale,0); + glpixeltransferf(gl_red_bias,red/255); + glpixeltransferf(gl_green_scale,0); + glpixeltransferf(gl_green_bias,green/255); + glpixeltransferf(gl_blue_scale,0); + glpixeltransferf(gl_blue_bias,blue/255); + end; + end; + inherited; + glpopattrib; + glpopclientattrib; +end; +{ +initialization + gdinumber:= registergdi(openglgetgdifuncs); +} +finalization + freebuffers; +end. diff --git a/mseide-msegui/lib/common/opengl/mseopenglgdiinit.pas b/mseide-msegui/lib/common/opengl/mseopenglgdiinit.pas new file mode 100644 index 0000000..3035e0e --- /dev/null +++ b/mseide-msegui/lib/common/opengl/mseopenglgdiinit.pas @@ -0,0 +1,18 @@ +{ MSEgui Copyright (c) 2011 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseopenglgdiinit; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +implementation +uses + mseopenglgdi,msegraphics; +initialization + registergdi(openglgetgdifuncs); +end. diff --git a/mseide-msegui/lib/common/opengl/mseopenglwidget.pas b/mseide-msegui/lib/common/opengl/mseopenglwidget.pas new file mode 100644 index 0000000..ce10bdb --- /dev/null +++ b/mseide-msegui/lib/common/opengl/mseopenglwidget.pas @@ -0,0 +1,407 @@ +{ MSEgui Copyright (c) 2007-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseopenglwidget; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifdef linux} {$define unix}{$endif} +interface +uses + classes,mclasses,msewindowwidget,msegl, + {$ifdef unix}mseglx,{$ifdef FPC}x,{$endif}xlib,{$else}windows,{$endif} + mseguiintf,msetypes,mseguiglob,mseclasses,msemenus,mseevent,msegui,msegraphics, + msegraphutils; + +{$ifdef unix} +{$ifdef FPC} + {$macro on} + {$define xchar2b:=txchar2b} + {$define xcharstruct:=txcharstruct} + {$define xfontstruct:=txfontstruct} + {$define xfontprop:=txfontprop} + {$define xpoint:=txpoint} + {$define xgcvalues:=txgcvalues} + {$define region:=tregion} + {$define ximage:=tximage} + {$define xwindowattributes:=txwindowattributes} + {$define xclientmessageevent:=txclientmessageevent} + {$define xtype:=_type} + {$define xrectangle:=txrectangle} + {$define keysym:=tkeysym} + {$define xsetwindowattributes:=txsetwindowattributes} + {$define xwindowchanges:=txwindowchanges} + {$define xevent:=txevent} + {$define xfunction:=_function} + {$define xwindow:=window} + {$define xlookupkeysym_:=xlookupkeysymval} + {$define c_class:= _class} + {$define xtextproperty:= txtextproperty} +{$endif} +const + defaultvisualattributes: array[0..8] of integer = + (GLX_RGBA,GLX_RED_SIZE,8,GLX_GREEN_SIZE,8,GLX_BLUE_SIZE,8, + GLX_DOUBLEBUFFER,none); +{$endif} + +type + tcustomopenglwidget = class; + openglwidgeteventty = procedure(const sender: tcustomopenglwidget) of object; + openglrendereventty = procedure(const sender: tcustomopenglwidget; + const aupdaterect: rectty) of object; + + tcustomopenglwidget = class(tcustomwindowwidget) + private + {$ifdef unix} + fcontext: glxcontext; + fdpy: pdisplay; + fcolormap: tcolormap; + fscreen: integer; + {$else} + fdc: hdc; + fcontext: hglrc; + {$endif} + fwin: winidty; + fonrender: openglrendereventty; + {$ifdef unix} + fvisualattributes: integerarty; + {$endif} + fattrib_buffersize: integer; + fattrib_level: integer; + fattrib_rgba: boolean; + fattrib_doublebuffer: boolean; + fattrib_dri: boolean; + fattrib_stereo: boolean; + fattrib_auxbuffers: integer; + fattrib_redsize: integer; + fattrib_greensize: integer; + fattrib_bluesize: integer; + fattrib_alphasize: integer; + fattrib_depthsize: integer; + fattrib_stencilsize: integer; + fattrib_accumredsize: integer; + fattrib_accumgreensize: integer; + fattrib_accumbluesize: integer; + fattrib_accumalphasize: integer; + function setcurrent: boolean; + protected + procedure doclientrectchanged; override; + procedure docreatewinid(const aparent: winidty; const awidgetrect: rectty; + var aid: winidty); override; + procedure dodestroywinid; override; + function canclientpaint: boolean; override; + procedure doclientpaint(const aupdaterect: rectty); override; + procedure updateviewport(const arect: rectty); override; + public + constructor create(aowner: tcomponent); override; + {$ifdef unix} + property visualattributes: integerarty read fvisualattributes + write fvisualattributes; + {$endif} + published + property onrender: openglrendereventty read fonrender write fonrender; + property attrib_buffersize: integer read fattrib_buffersize + write fattrib_buffersize default -1; + property attrib_level: integer read fattrib_level + write fattrib_level default 0; + property attrib_rgba: boolean read fattrib_rgba + write fattrib_rgba default true; + property attrib_doublebuffer: boolean read fattrib_doublebuffer + write fattrib_doublebuffer default true; + property attrib_dri: boolean read fattrib_dri + write fattrib_dri default true; + property attrib_stereo: boolean read fattrib_stereo + write fattrib_stereo default false; + property attrib_auxbuffers: integer read fattrib_auxbuffers + write fattrib_auxbuffers default -1; + property attrib_redsize: integer read fattrib_redsize + write fattrib_redsize default 8; + property attrib_greensize: integer read fattrib_greensize + write fattrib_greensize default 8; + property attrib_bluesize: integer read fattrib_bluesize + write fattrib_bluesize default 8; + property attrib_alphasize: integer read fattrib_alphasize + write fattrib_alphasize default -1; + property attrib_depthsize: integer read fattrib_depthsize + write fattrib_depthsize default -1; + property attrib_stencilsize: integer read fattrib_stencilsize + write fattrib_stencilsize default -1; + property attrib_accumredsize: integer read fattrib_accumredsize + write fattrib_accumredsize default -1; + property attrib_accumgreensize: integer read fattrib_accumgreensize + write fattrib_accumgreensize default -1; + property attrib_accumbluesize: integer read fattrib_accumbluesize + write fattrib_accumbluesize default -1; + property attrib_accumalphasize: integer read fattrib_accumalphasize + write fattrib_accumalphasize default -1; + end; + + topenglwidget = class(tcustomopenglwidget) + published + property onrender; + property optionswidget; + property optionsskin; + property bounds_x; + property bounds_y; + property bounds_cx; + property bounds_cy; + property bounds_cxmin; + property bounds_cymin; + property bounds_cxmax; + property bounds_cymax; + property color; + property cursor; + property frame; + property face; + property anchors; + property taborder; + property hint; + property popupmenu; + property onpopup; + property onshowhint; + property enabled; + property visible; + property fpsmax; + property oncreatewinid; + property ondestroywinid; +// property onclientpaint; + property onclientrectchanged; + property onwindowmouseevent; + property onwindowmousewheelevent; + property ondestroy; + end; + +implementation +uses + sysutils{$ifdef unix}{$ifdef FPC},xutil{$endif}{$endif},mseglextglob; + +{ tcustomopenglwidget } + +constructor tcustomopenglwidget.create(aowner: tcomponent); +begin + fattrib_buffersize:= -1; + fattrib_level:= 0; + fattrib_rgba:= true; + fattrib_doublebuffer:= true; + fattrib_dri:= true; + fattrib_stereo:= false; + fattrib_auxbuffers:= -1; + fattrib_redsize:= 8; + fattrib_greensize:= 8; + fattrib_bluesize:= 8; + fattrib_alphasize:= -1; + fattrib_depthsize:= -1; + fattrib_stencilsize:= -1; + fattrib_accumredsize:= -1; + fattrib_accumgreensize:= -1; + fattrib_accumbluesize:= -1; + fattrib_accumalphasize:= -1; + inherited; +end; + +procedure tcustomopenglwidget.dodestroywinid; +begin + {$ifdef unix} + if fcontext <> nil then begin + glxmakecurrent(fdpy,0,nil); + glxdestroycontext(fdpy,fcontext); + fcontext:= nil; + xfreecolormap(fdpy,fcolormap); + end; + {$else} + if fcontext <> 0 then begin + wglmakecurrent(0,0); + wgldeletecontext(fcontext); + releasedc(fwin,fdc); + end; + {$endif} + inherited; + releaseopengl; +end; + +{ +procedure tcustomopenglwidget.clientrectchanged; +begin + inherited; + checkviewport; +end; +} +procedure tcustomopenglwidget.docreatewinid(const aparent: winidty; + const awidgetrect: rectty; var aid: winidty); +{$ifdef unix} +var + index: integer; + ar1: integerarty; + + procedure putboolean(const atag: integer; avalue: boolean); + begin + if index > high(ar1) then begin + setlength(ar1,19+high(ar1)*2); + end; + if avalue then begin + ar1[index]:= atag; + inc(index); + end; + end; + + procedure putvalue(const atag,avalue,defaultvalue: integer); + begin + if index > high(ar1) then begin + setlength(ar1,19+high(ar1)*2); + end; + if avalue <> defaultvalue then begin + ar1[index]:= atag; + inc(index); + ar1[index]:= avalue; + inc(index); + end; + end; + +var + int1,int2: integer; + visinfo: pxvisualinfo; + attributes: xsetwindowattributes; + +begin + fdpy:= msedisplay; + fscreen:= xdefaultscreen(fdpy); + initializeopengl([]); + if not glxqueryextension(fdpy,int1,int2) then begin + raise exception.create('GLX extension not supported.'); + end; + if fvisualattributes = nil then begin + setlength(ar1,34); + index:= 0; + putboolean(glx_doublebuffer,fattrib_doublebuffer); + putvalue(glx_buffer_size,fattrib_buffersize,-1); + putvalue(glx_level,fattrib_level,0); + putboolean(glx_rgba,fattrib_rgba); + putboolean(glx_stereo,fattrib_stereo); + putvalue(glx_aux_buffers,fattrib_auxbuffers,-1); + putvalue(glx_red_size,fattrib_redsize,-1); + putvalue(glx_green_size,fattrib_greensize,-1); + putvalue(glx_blue_size,fattrib_bluesize,-1); + putvalue(glx_alpha_size,fattrib_alphasize,-1); + putvalue(glx_depth_size,fattrib_depthsize,-1); + putvalue(glx_stencil_size,fattrib_stencilsize,-1); + putvalue(glx_accum_red_size,fattrib_accumredsize,-1); + putvalue(glx_accum_green_size,fattrib_accumgreensize,-1); + putvalue(glx_accum_blue_size,fattrib_accumbluesize,-1); + putvalue(glx_accum_alpha_size,fattrib_accumalphasize,-1); + setlength(ar1,index+1); //none + end + else begin + ar1:= copy(fvisualattributes); + setlength(ar1,high(ar1)+3); //add security nulls + end; + visinfo:= glxchoosevisual(fdpy,fscreen,pinteger(ar1)); + if visinfo = nil then begin + raise exception.create('Could not find visual.'); + end; + fcontext:= glxcreatecontext(fdpy,visinfo,nil,true); + fcolormap:= xcreatecolormap(fdpy,gui_getrootwindow(), + visinfo^.visual,allocnone); + attributes.colormap:= fcolormap; + with awidgetrect do begin + aid:= xcreatewindow(fdpy,aparent,x,y,cx,cy,0,visinfo^.depth, + inputoutput,visinfo^.visual,cwcolormap,@attributes); + xselectinput(fdpy,aid,exposuremask); //will be mapped to parent + end; + fwin:= aid; + xfree(visinfo); + if fcontext = nil then begin +{$else} +var + pixeldesc: tpixelformatdescriptor; + int1: integer; +begin + initializeopengl([]); + aid:= createchildwindow; + fwin:= aid; + fdc:= getdc(fwin); + fillchar(pixeldesc,sizeof(pixeldesc),0); + with pixeldesc do begin + nsize:= sizeof(pixeldesc); + nversion:= 1; + dwflags:= pfd_draw_to_window or pfd_support_opengl; + if fattrib_doublebuffer then begin + dwflags:= dwflags or pfd_doublebuffer; + end; + ipixeltype:= pfd_type_rgba; + ccolorbits:= 24; + cdepthbits:= 32; + end; + int1:= choosepixelformat(fdc,@pixeldesc); + setpixelformat(fdc,int1,@pixeldesc); + fcontext:= wglcreatecontext(fdc); + if fcontext = 0 then begin +{$endif} + raise exception.create('Could not create an OpenGL rendering context.'); + end; + setcurrent; + inherited; +// checkviewport; +end; + +function tcustomopenglwidget.setcurrent: boolean; +begin +{$ifdef unix} + result:= fcontext <> nil; +{$else} + result:= fcontext <> 0; +{$endif} + if result then begin + {$ifdef unix} + glxmakecurrent(fdpy,fwin,fcontext); + {$else} + wglmakecurrent(fdc,fcontext); + {$endif} + end; +end; + +procedure tcustomopenglwidget.updateviewport(const arect: rectty); +begin + if setcurrent then begin + with arect do begin + glviewport(x,y,cx,cy); + end; + end; +end; + +procedure tcustomopenglwidget.doclientpaint(const aupdaterect: rectty); +begin + setcurrent; + if canevent(tmethod(fonrender)) then begin + fonrender(self,aupdaterect); + end; +// glflush; + if fattrib_doublebuffer then begin + {$ifdef unix} + glxswapbuffers(fdpy,fwin); + {$else} + swapbuffers(fdc); + {$endif} + end + else begin + glflush; +// glfinish; + end; +end; + +procedure tcustomopenglwidget.doclientrectchanged; +begin + setcurrent; + inherited; +end; + +function tcustomopenglwidget.canclientpaint: boolean; +begin + result:= assigned(fonrender); +end; + +end. + \ No newline at end of file diff --git a/mseide-msegui/lib/common/pascalscript/msepascalscript.pas b/mseide-msegui/lib/common/pascalscript/msepascalscript.pas new file mode 100644 index 0000000..ece577b --- /dev/null +++ b/mseide-msegui/lib/common/pascalscript/msepascalscript.pas @@ -0,0 +1,435 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msepascalscript; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,uPSComponent,uPSCompiler,uPSRuntime,msestrings,mseforms, + mseclasses,typinfo,mselist,uPSPreProcessor; + +type + + tpasc = class(tpsscript) + public + function compilermessagetext: msestring; + function compilermessagear: msestringarty; + end; + + ttestobj = class(tcomponent) + private + fprop: string; + public + constructor create; reintroduce; + procedure testproc; + procedure testproc1; virtual; + property prop: string read fprop write fprop; + end; + + tformscript = class(tpasc) + private + fownercomp: tmsecomponent; + protected + procedure docompimport(Sender: TObject; x: TPSPascalCompiler); + procedure docompile(sender: tpsscript); + procedure doexecimport(Sender: TObject; se: TPSExec; + x: TPSRuntimeClassImporter); + procedure doexecute(sender: tpsscript); + public + constructor create(aowner: tmsecomponent); reintroduce; + end; + + methpropinfoty = record + propinfo: ppropinfo; + instance: tobject; + name: string; + end; + pmethpropinfoty = ^methpropinfoty; + + tmethproplist = class(trecordlist) + protected + procedure finalizerecord(var item); override; + procedure copyrecord(var item); override; + procedure dosetmethodprop(Reader: TReader; Instance: TPersistent; + PropInfo: PPropInfo; const TheMethodName: string; + var Handled: boolean); + public + constructor create; + procedure additem(const apropinfo: ppropinfo; const ainstance: tobject; + const aname: string); + procedure linkmethods(const ascript: tpasc); + end; + + tpascform = class(tmseform) + private + fscript: tformscript; + fmethlist: tmethproplist; + function getpasc_script: tstrings; + procedure setpasc_script(const avalue: tstrings); + function getpasc_plugins: tpsplugins; + procedure setpasc_plugins(const avalue: tpsplugins); + protected + class function getmoduleclassname: string; override; + class function hasresource: boolean; override; + procedure readstate(reader: treader); override; + procedure doafterload; override; + function isscript: boolean; + public + constructor create(aowner: tcomponent; load: boolean); override; + destructor destroy; override; + property script: tformscript read fscript; + published + property pasc_script: tstrings read getpasc_script write setpasc_script; + property pasc_plugins: tpsplugins read getpasc_plugins write setpasc_plugins; + end; + + pascformclassty = class of tpascform; + +function createpascform(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; +function loadpascform(const filename: filenamety): tpascform; + +implementation +uses + msestream,msegui,msesys,sysutils,msetmpmodules,mseobjecttext; + +type + tmsecomponent1 = class(tmsecomponent); + +function loadpascform(const filename: filenamety): tpascform; +var + stream1: ttextstream; + stream2: tmemorystream; +// reader1: treader; +begin + stream1:= nil; + stream2:= nil; + try +// result:= tpascform.create(application,false); + stream1:= ttextstream.create(filename,fm_read); + stream2:= tmemorystream.create; + objecttexttobinarymse(stream1,stream2); + stream2.position:= 0; + result:= tpascform(createtmpmodule('tpascform',stream2)); + finally + stream1.free; + stream2.free; + end; +end; +{ +function loadpascform(const filename: filenamety): tpascform; +var + methlist: tmethproplist; + stream1: ttextstream; + stream2: tmemorystream; + reader1: treader; +begin + methlist:= tmethproplist.create; + stream1:= nil; + stream2:= nil; + reader1:= nil; + beginloadtmpmodule; + try + try + result:= tpascform.create(application,false); + stream1:= ttextstream.create(filename,fm_read); + stream2:= tmemorystream.create; + objecttexttobinarymse(stream1,stream2); + stream2.position:= 0; + reader1:= treader.create(stream2,4048); + reader1.onsetmethodproperty:= @methlist.dosetmethodprop; + reader1.readrootcomponent(result); + if not result.fscript.compile then begin + raise exception.create('Error compiling script of '+result.name+':'+lineend+ + result.fscript.compilermessagetext); + end; + methlist.linkmethods(result.fscript); + addtmpmodule(result); + except + result.free; + raise; + end; + finally + endloadtmpmodule; + reader1.free; + stream1.free; + stream2.free; + methlist.free; + end; +end; +} +function createpascform(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; +begin + result:= pascformclassty(aclass).create(nil,false); + tmsecomponent1(result).factualclassname:= aclassname; +end; + +{ tmethproplist } + +constructor tmethproplist.create; +begin + inherited create(sizeof(methpropinfoty),[rels_needsfinalize,rels_needscopy]); +end; + +procedure tmethproplist.additem(const apropinfo: ppropinfo; + const ainstance: tobject; const aname: string); +var + info: methpropinfoty; +begin + with info do begin + propinfo:= apropinfo; + instance:= ainstance; + name:= aname; + end; + add(info); +end; + +procedure tmethproplist.dosetmethodprop(Reader: TReader; Instance: TPersistent; + PropInfo: PPropInfo; const TheMethodName: string; + var Handled: boolean); +begin + additem(propinfo,instance,themethodname); + handled:= true; +end; + +procedure tmethproplist.finalizerecord(var item); +begin + finalize(methpropinfoty(item)); +end; + +procedure tmethproplist.copyrecord(var item); +begin + with methpropinfoty(item) do begin + stringaddref(name); + end; +end; + +procedure tmethproplist.linkmethods(const ascript: tpasc); +var + int1: integer; + meth1: tmethod; +begin + for int1:= 0 to count - 1 do begin + with pmethpropinfoty(fdata)[int1] do begin + meth1:= ascript.getprocmethod(struppercase(name)); + setmethodprop(instance,propinfo,meth1); + end; + end; +end; + +{ tpasc } + +function tpasc.compilermessagetext: msestring; +var + int1: integer; +begin + result:= ''; + for int1:= 0 to compilermessagecount - 1 do begin + result:= result+compilermessages[int1].messagetostring + lineend; + end; + if result <> '' then begin + setlength(result,length(result)-length(lineend)); + end; +end; + +function tpasc.compilermessagear: msestringarty; +var + int1: integer; +begin + result:= nil; + setlength(result,compilermessagecount); + for int1:= 0 to compilermessagecount - 1 do begin + result[int1]:= compilermessages[int1].messagetostring; + end; +end; + +{ tpascform } + +constructor tpascform.create(aowner: tcomponent; load: boolean); +begin + fscript:= tformscript.create(self{nil}); + fscript.setsubcomponent(true); + inherited; +end; + +destructor tpascform.destroy; +begin + fmethlist.free; + fscript.free; + inherited; +end; + +function tpascform.isscript: boolean; +begin + result:= (cs_tmpmodule in fmsecomponentstate) and + not (csdesigning in componentstate); +end; + +procedure tpascform.readstate(reader: treader); +begin + if isscript then begin + freeandnil(fmethlist); + fmethlist:= tmethproplist.create; +// try + reader.onsetmethodproperty:= @fmethlist.dosetmethodprop; + inherited; + { + if not fscript.compile then begin + raise exception.create('Error compiling script of '+name+':'+lineend+ + fscript.compilermessagetext); + end; + methlist.linkmethods(fscript); + finally + methlist.free; + end; + } + end + else begin + inherited; + end; +end; + +procedure tpascform.doafterload; +begin + if isscript then begin + try + if not fscript.compile then begin + raise exception.create('Error compiling script of '+name+':'+lineend+ + fscript.compilermessagetext); + end; + fmethlist.linkmethods(fscript); + finally + freeandnil(fmethlist); + end; + end; + inherited; +end; + +class function tpascform.getmoduleclassname: string; +begin + result:= 'tpascform'; +end; + +class function tpascform.hasresource: boolean; +begin + result:= self <> tpascform; +end; + +function tpascform.getpasc_script: tstrings; +begin + result:= fscript.script; +end; + +procedure tpascform.setpasc_script(const avalue: tstrings); +begin + fscript.script.assign(avalue); +end; + +function tpascform.getpasc_plugins: tpsplugins; +begin + result:= fscript.plugins; +end; + +procedure tpascform.setpasc_plugins(const avalue: tpsplugins); +begin + fscript.plugins.assign(avalue); +end; + +{ tformscript } + +constructor tformscript.create(aowner: tmsecomponent); +begin + fownercomp:= aowner; + inherited create(nil); + compileroptions:= [icAllowNoBegin,icAllowNoEnd,icBooleanShortCircuit]; + oncompimport:= @docompimport; + oncompile:= @docompile; + onexecimport:= @doexecimport; + onexecute:= @doexecute; +end; + +procedure tformscript.docompimport(Sender: TObject; x: TPSPascalCompiler); +var + int1: integer; +begin + with fownercomp do begin + with x.addclassn(x.findclass('TCOMPONENT'),'ttestobj') do begin + registermethod('procedure testproc;'); + registermethod('procedure testproc1;'); + registermethod('constructor create;'); + end; + for int1:= 0 to componentcount - 1 do begin + with components[int1] do begin + if x.findclass(classname) = nil then begin + x.addclassn(x.findclass('TCOMPONENT'),classname); + end; + end; + end; + end; +end; + +procedure tformscript.docompile(sender: tpsscript); +var + int1: integer; +begin + with fownercomp do begin + for int1:= 0 to componentcount - 1 do begin + with components[int1] do begin + sender.addregisteredvariable(name,classname); + end; + end; + end; +end; + +procedure tformscript.doexecimport(Sender: TObject; se: TPSExec; + x: TPSRuntimeClassImporter); +begin + with x.add(ttestobj) do begin + registermethod(@ttestobj.testproc,'TESTPROC'); + registervirtualmethod(@ttestobj.testproc1,'TESTPROC1'); + registerconstructor(@ttestobj.create,'CREATE'); + end; +end; + +procedure tformscript.doexecute(sender: tpsscript); +var + int1: integer; + comp1: tcomponent; +begin + with sender do begin + setvartoinstance('SELF',owner); + with fownercomp do begin + for int1:= 0 to componentcount - 1 do begin + comp1:= components[int1]; + setvartoinstance(struppercase(comp1.name),comp1); + end; + end; + end; +end; + +{ ttestobj } + +procedure ttestobj.testproc; +begin + msegui.beep; +end; + +procedure ttestobj.testproc1; +begin + msegui.beep; +end; + +constructor ttestobj.create; +begin + inherited create(nil); + name:= 'qwertz'; +end; + +end. diff --git a/mseide-msegui/lib/common/pascalscript/msepascimport.pas b/mseide-msegui/lib/common/pascalscript/msepascimport.pas new file mode 100644 index 0000000..78c26e9 --- /dev/null +++ b/mseide-msegui/lib/common/pascalscript/msepascimport.pas @@ -0,0 +1,11 @@ +unit msepascimport; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + upscomponent,upscomponent_default; +type + tpascdllplugin = class(tpsdllplugin); + tpascimport_classes = class(tpsimport_classes); + tpascimport_dateutils = class(tpsimport_dateutils); +implementation +end. diff --git a/mseide-msegui/lib/common/pascalscript/msepascimportmsegui.pas b/mseide-msegui/lib/common/pascalscript/msepascimportmsegui.pas new file mode 100644 index 0000000..4e46da0 --- /dev/null +++ b/mseide-msegui/lib/common/pascalscript/msepascimportmsegui.pas @@ -0,0 +1,51 @@ +unit msepascimportmsegui; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + upscomponent,upscompiler,upsruntime; +type + tpascimportmsegui = class(tpsplugin) + protected + procedure CompOnUses(CompExec: TPSScript); override; + procedure ExecOnUses(CompExec: TPSScript); override; + end; + +procedure registermsegui_c(s: tpspascalcompiler); +procedure registermsegui_r(s: tpsexec); + +implementation +uses + msewidgets,upsutils,msegui; + +procedure registermsegui_c(s: tpspascalcompiler); +begin + with s do begin + addtype('msestring',btwidestring); + adddelphifunction( + 'procedure showmessage1(const atext: msestring; const caption: msestring);'); + adddelphifunction('procedure beep;'); + end; +end; + +procedure registermsegui_r(s: tpsexec); +begin + with s do begin + registerdelphifunction(@showmessage1,'SHOWMESSAGE1',cdregister); + registerdelphifunction(@msegui.beep,'BEEP',cdregister); + end; +end; + +{ tpascimportmsegui } + +procedure tpascimportmsegui.CompOnUses(CompExec: TPSScript); +begin + registermsegui_c(compexec.comp); +end; + +procedure tpascimportmsegui.ExecOnUses(CompExec: TPSScript); +begin + registermsegui_r(compexec.exec); +end; + +end. + diff --git a/mseide-msegui/lib/common/printer/msegdiprint.pas b/mseide-msegui/lib/common/printer/msegdiprint.pas new file mode 100644 index 0000000..9b41567 --- /dev/null +++ b/mseide-msegui/lib/common/printer/msegdiprint.pas @@ -0,0 +1,625 @@ +{ MSEgui Copyright (c) 2007-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msegdiprint; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +// *********************************************************** +// WARNING +// +// tgdiprinter and twmfprinter are not recommended for production use, +// there are many issues with win32 printing and metafiles. +// Please use tpostscriptprinter instead. +// +// *********************************************************** + +interface +uses + classes,mclasses,mseprinter,msegraphics,msegraphutils,msetypes,msestrings,msedrawtext, + msegui,mseguiglob{$ifdef mswindows},windows{$endif}; +const + mmtoinch = 1/25.4; + defaultgdiprintppmm = mseguiglob.defaultppmm; + screenrefprintername = 'ScreeN'; + +type + {$ifndef mswindows} + henhmetafile = longword; + {$endif} + + tgdiprintcanvas = class(tprintercanvas) + protected + procedure beginpage; override; + procedure endpage; override; + procedure checkgcstate(state: canvasstatesty); override; + function didprint: boolean; virtual; + public + constructor create(const user: tcustomprinter; const intf: icanvas); + procedure drawtext(var info: drawtextinfoty); override; + end; + + tcustomgdiprinter = class(tprinter,icanvas) + private + fppinchx: real; + fppinchy: real; + fpoffsetx: real; + fpoffsety: real; + fprintername: msestring; + protected + function actprintername: msestring; virtual; + procedure creategc(var agc: gcty; const aname: msestring); virtual; + procedure initdevicecaps(const agc: gcty); virtual; + //icanvas + procedure gcneeded(const sender: tcanvas); +// function getmonochrome: boolean; + function getkind: bitmapkindty; + procedure getcanvasimage(const bgr: boolean; var aimage: maskedimagety); + public + constructor create(aowner: tcomponent); override; + procedure beginprint(const adryrun: boolean = false); override; + procedure endprint; override; + end; + + tgdiprinter = class(tcustomgdiprinter) + published + property printername: msestring read fprintername write fprintername; + //'' -> default printer + end; + +//{$ifdef mswindows} + + twmfprintcanvas = class(tgdiprintcanvas) + private + {$ifdef mswindows} + ffilehandle: henhmetafile; + {$endif} + function getenhmetafile: henhmetafile; + protected + function didprint: boolean; override; + public + constructor create(const user: tcustomprinter; const intf: icanvas); + procedure linktopaintdevice(apaintdevice: paintdevicety; const gc: gcty; + {const size: sizety;} const cliporigin: pointty); override; + property metafilehandle: henhmetafile read getenhmetafile; + end; + + twmfprinter = class(tcustomgdiprinter) + private + frefprintername: msestring; + function getcanvas: twmfprintcanvas; + procedure setcanvas(const avalue: twmfprintcanvas); + protected + function actprintername: msestring; override; + procedure creategc(var agc: gcty; const aname: msestring); override; + function getwindowsize: sizety; override; + procedure initdevicecaps(const agc: gcty); override; + public + constructor create(aowner: tcomponent); override; + published + property canvas: twmfprintcanvas read getcanvas write setcanvas; + property filename: msestring read fprintername write fprintername; + //'' -> memory + property refprintername: msestring read frefprintername write frefprintername; + //'' -> defaultprinter, 'ScreeN' -> default dc + end; + +//{$endif} + +function defaultprinter: msestring; + +implementation +uses + mseguiintf,msedynload,sysutils,msesysintf1,msesys; +var + hasgdiprint: boolean; + +{$ifdef mswindows} +type + WINBOOL = longbool; + DOCINFOW = record + cbSize: longint; + lpszDocName: LPCWSTR; + lpszOutput: LPCWSTR; + lpszDatatype: LPCWSTR; + fwType: DWORD; + end; + TDOCINFOW = DOCINFOW; + PDOCINFOW = ^DOCINFOW; +var + SetWorldTransform: function(_para1:HDC; var _para2:XFORM):WINBOOL; stdcall; + StartDocW: function(_para1:HDC; _para2:PDOCINFOW):longint; stdcall; + GetDefaultPrinterW: function(pszBuffer: pwidechar; + pcchBuffer: pdword): WINBOOL; stdcall; +{$endif} + +{$ifdef mswindows} +procedure checkprinterror(const aresult: integer; const atext: msestring = ''); +begin + if aresult <= 0 then begin + syserror(syelasterror,atext); + end; +end; + +procedure checkprintboolerror(const aresult: boolean; + const atext: msestring = ''); +begin + if not aresult then begin + syserror(syelasterror,atext); + end; +end; +{$endif} + +procedure checkgdiprint; +begin + if not hasgdiprint then begin + exception.create('GDI printing not supported.'); + end; +end; + +{ tgdiprintcanvas } + +constructor tgdiprintcanvas.create(const user: tcustomprinter; + const intf: icanvas); +begin + inherited; + exclude(fstate,cs_internaldrawtext); +end; + +procedure tgdiprintcanvas.drawtext(var info: drawtextinfoty); +begin + if cs_inactive in fstate then exit; + msedrawtext.drawtext(self,info); +end; + +procedure tgdiprintcanvas.beginpage; +begin + initgcvalues; + exclude(fpstate,pcs_matrixvalid); + include(fstate,cs_inactive); + if not (pcs_dryrun in fpstate) and active then begin + exclude(fstate,cs_inactive); + end; + if not (cs_inactive in fstate) then begin + include(fstate,cs_pagestarted); + {$ifdef mswindows} + if not (cs_metafile in fstate) then begin + checkprinterror(startpage(gchandle)); + end; + {$endif} + end; + inherited; +end; + +procedure tgdiprintcanvas.endpage; +begin + inherited; + if not (cs_inactive in fstate) and (cs_pagestarted in fstate) then begin + exclude(fstate,cs_pagestarted); + {$ifdef mswindows} + if not (cs_metafile in fstate) then begin + checkprinterror(windows.endpage(gchandle)); + end; + {$endif} + end; +end; + +procedure tgdiprintcanvas.checkgcstate(state: canvasstatesty); +{$ifdef mswindows} +var + mat1: txform; +{$endif} +begin + inherited; + if not (pcs_matrixvalid in fpstate) then begin +{$ifdef mswindows} + fillchar(mat1,sizeof(mat1),0); + with mat1,tcustomgdiprinter(fprinter) do begin + if printorientation = pao_landscape then begin + em21:= (fppinchx*mmtoinch) / ppmm; + em12:= -(fppinchy*mmtoinch) / ppmm; + edx:= -fpoffsetx + pa_frametop*mmtoinch*fppinchx; + edy:= -fpoffsety + (pa_height - pa_frameleft)*mmtoinch*fppinchy; + end + else begin + em11:= (fppinchx*mmtoinch) / ppmm; + em22:= (fppinchy*mmtoinch) / ppmm; + edx:= -fpoffsetx + pa_frameleft*mmtoinch*fppinchx; + edy:= -fpoffsety + pa_frametop*mmtoinch*fppinchy; + end; + checkprintboolerror(setworldtransform(fdrawinfo.gc.handle,mat1)); + end; +{$endif} + include(fpstate,pcs_matrixvalid); + end; +end; + +function tgdiprintcanvas.didprint: boolean; +begin + result:= fdrawinfo.gc.handle <> 0; +end; + + +{ tcustomgdiprinter } + +constructor tcustomgdiprinter.create(aowner: tcomponent); +begin + if fcanvas = nil then begin +{$warnings off} + fcanvas:= tgdiprintcanvas.create(self,icanvas(self)); +{$warnings on} + end; + inherited; + fcanvas.ppmm:= defaultgdiprintppmm; +end; +{ +function tcustomgdiprinter.getmonochrome: boolean; +begin + result:= false; +end; +} +function tcustomgdiprinter.getkind: bitmapkindty; +begin + result:= bmk_rgb; +end; + +{$ifdef mswindows} + +function tcustomgdiprinter.actprintername: msestring; +begin + if fprintername = '' then begin + result:= defaultprinter; + end + else begin + result:= fprintername; + end; +end; + +procedure tcustomgdiprinter.creategc(var agc: gcty; const aname: msestring); +begin + gdierror(fcanvas.creategc(0,gck_printer,agc,aname),'for "'+aname+'"'); +// gdierror(gui_creategc(0,gck_printer,agc,aname),'for "'+aname+'"'); +end; + +procedure tcustomgdiprinter.initdevicecaps(const agc: gcty); +begin + fppinchx:= getdevicecaps(agc.handle,logpixelsx); + fppinchy:= getdevicecaps(agc.handle,logpixelsy); + fpoffsetx:= getdevicecaps(agc.handle,physicaloffsetx); + fpoffsety:= getdevicecaps(agc.handle,physicaloffsety); +end; + +procedure tcustomgdiprinter.gcneeded(const sender: tcanvas); +var + gc1: gcty; +// mat1: txform; + mstr1: msestring; +begin + checkgdiprint; + if not (sender is tgdiprintcanvas) then begin + guierror(gue_invalidcanvas); + end; + mstr1:= actprintername; + with tgdiprintcanvas(sender) do begin + exclude(fstate,cs_pagestarted); + fillchar(gc1,sizeof(gc1),0); + gc1.paintdevicesize:= getwindowsize; + gc1.kind:= bmk_rgb; + gc1.ppmm:= ppmm; + include(gc1.drawingflags,df_highresfont); + self.creategc(gc1,mstr1); + checkprinterror(setgraphicsmode(gc1.handle,gm_advanced)); + initdevicecaps(gc1); + linktopaintdevice(ptrint(self),gc1,{getwindowsize,}nullpoint); + end; +end; + +procedure tcustomgdiprinter.beginprint(const adryrun: boolean = false); +var + info: tdocinfow; +begin + checkgdiprint; + endprint; + with tgdiprintcanvas(fcanvas) do begin + if adryrun then begin + include(fpstate,pcs_dryrun) + end + else begin + exclude(fpstate,pcs_dryrun); + end; + initprinting; + if not (pcs_dryrun in fpstate) then begin + if not (cs_metafile in fstate) then begin + fillchar(info,sizeof(info),0); + info.cbsize:= sizeof(info); + info.lpszdocname:= pwidechar(fcanvas.title); + checkprinterror(startdocw(fcanvas.gchandle,@info), + 'Can not start print job for "'+fcanvas.title+'".'); + end; + beginpage; + end; + end; +end; + +function defaultprinter: msestring; +const + maxlen = 2048; +var + int1: integer; +begin + checkgdiprint; + int1:= maxlen; + setlength(result,int1); + checkprintboolerror(getdefaultprinterw(pwidechar(result),@int1)); + setlength(result,int1-1); +end; + +{$else} +procedure tcustomgdiprinter.beginprint(const adryrun: boolean = false); +begin + inherited; + checkgdiprint; +end; + +procedure tcustomgdiprinter.gcneeded(const sender: tcanvas); +begin + checkgdiprint; +end; + +function defaultprinter: msestring; +begin + checkgdiprint; + result:= ''; +end; + +function tcustomgdiprinter.actprintername: msestring; +begin + checkgdiprint; + result:= ''; +end; + +procedure tcustomgdiprinter.initdevicecaps(const agc: gcty); +begin + checkgdiprint; +end; + +procedure tcustomgdiprinter.creategc(var agc: gcty; const aname: msestring); +begin + checkgdiprint; +end; + +{$endif} + +procedure tcustomgdiprinter.endprint; +begin + checkgdiprint; + with tgdiprintcanvas(fcanvas) do begin + if didprint then begin + try + try + {$ifdef mswindows} + endpage; + if not (pcs_dryrun in fpstate) then begin + if not (cs_metafile in fstate) then begin + enddoc(gchandle); + end; + end; + {$endif} + finally + unlink; + end; + except + end; + end; + end; + inherited; +end; + +procedure tcustomgdiprinter.getcanvasimage(const bgr: boolean; + var aimage: maskedimagety); +begin + //dummy +end; + +procedure doinit; +var + haserror: boolean; +begin +{$ifdef FPC} + haserror:= false; + {$ifdef mswindows} + if not iswin95 then begin + try + getprocaddresses(getmodulehandle('gdi32'), + [ + 'SetWorldTransform', //0 + 'StartDocW' //1 + ], + [ + {$ifndef FPC}@{$endif}@SetWorldTransform, //0 + {$ifndef FPC}@{$endif}@StartDocW //1 + ]); + except begin + haserror:= true; + end; + end; + if not haserror then begin + try + getprocaddresses(['WINSPOOL.DRV'], + [ + 'GetDefaultPrinterW' //0 + ], + [ + {$ifndef FPC}@{$endif}@GetDefaultPrinterW //0 + ]); + except begin + haserror:= true; + end; + end; + end; + end + else begin + haserror:= true; + end; + {$endif} +{$else} //delphi can not call the correct procedures + haserror:= true; +{$endif} + hasgdiprint:= not haserror; +end; + +{$ifdef mswindows} + +{ twmfprintcanvas } + +constructor twmfprintcanvas.create(const user: tcustomprinter; + const intf: icanvas); +begin + include(fstate,cs_metafile); + inherited; +end; + +procedure twmfprintcanvas.linktopaintdevice(apaintdevice: paintdevicety; + const gc: gcty;{ const size: sizety;} const cliporigin: pointty); +begin + if ffilehandle <> 0 then begin + deleteenhmetafile(ffilehandle); + ffilehandle:= 0; + end; + inherited; +end; + +function twmfprintcanvas.getenhmetafile: henhmetafile; +begin + if ffilehandle = 0 then begin + ffilehandle:= closeenhmetafile(gchandle); + fdrawinfo.gc.handle:= 0; + gdi(gdf_destroygc); + end; + result:= ffilehandle; +end; + +function twmfprintcanvas.didprint: boolean; +begin + result:= (ffilehandle <> 0) or inherited didprint; +end; + +{$else} //mswindows + +constructor twmfprintcanvas.create(const user: tcustomprinter; + const intf: icanvas); +begin + include(fstate,cs_metafile); + inherited; +end; + +procedure twmfprintcanvas.linktopaintdevice(apaintdevice: paintdevicety; + const gc: gcty;{ const size: sizety;} const cliporigin: pointty); +begin + checkgdiprint; +end; + +function twmfprintcanvas.getenhmetafile: henhmetafile; +begin + checkgdiprint; + result:= 0; +end; + +function twmfprintcanvas.didprint: boolean; +begin + checkgdiprint; + result:= false; +end; +{$endif} //not mswindows + +{ twmfprinter } + +constructor twmfprinter.create(aowner: tcomponent); +begin + if fcanvas = nil then begin +{$warnings off} + fcanvas:= twmfprintcanvas.create(self,icanvas(self)); +{$warnings on} + end; + inherited; +end; + +function twmfprinter.getcanvas: twmfprintcanvas; +begin + result:= twmfprintcanvas(fcanvas); +end; + +procedure twmfprinter.setcanvas(const avalue: twmfprintcanvas); +begin + fcanvas.assign(avalue); +end; + +function twmfprinter.getwindowsize: sizety; +begin + result.cx:= round(pa_width*fcanvas.ppmm); + result.cy:= round(pa_height*fcanvas.ppmm); +end; + +procedure twmfprinter.initdevicecaps(const agc: gcty); +begin + inherited; + fpoffsetx:= 0; + fpoffsety:= 0; + exit; + fppinchx:= fppinchx * fcanvas.ppmm/mmtoinch; //paint device is virtual screen + fppinchy:= fppinchx; + fpoffsetx:= 0; + fpoffsety:= 0; +end; + +function twmfprinter.actprintername: msestring; +begin + result:= fprintername; +end; + +{$ifdef mswindows} + +procedure twmfprinter.creategc(var agc: gcty; const aname: msestring); +var + str1: ansistring; +begin + if frefprintername <> screenrefprintername then begin + if frefprintername = '' then begin + str1:= ansistring(defaultprinter); + end + else begin + str1:= ansistring(frefprintername); + end; + end; + agc.refgc:= createdc('WINSPOOL',pansichar(str1),nil,nil); +// agc.refgc:= getdc(0); + try +// guierror(gui_creategc(0,gck_metafile,agc,aname),'for "'+aname+'"'); + gdierror(fcanvas.creategc(0,gck_metafile,agc,aname),'for "'+aname+'"'); + finally + if agc.refgc <> 0 then begin +// releasedc(0,agc.refgc); + deletedc(agc.refgc); + agc.refgc:= 0; + end; + end; +end; + +{$else} //mswindows + +procedure twmfprinter.creategc(var agc: gcty; const aname: msestring); +begin + checkgdiprint; +end; + + +{$endif} //not mswindows + +initialization + doinit; +end. diff --git a/mseide-msegui/lib/common/printer/msepostscriptprinter.pas b/mseide-msegui/lib/common/printer/msepostscriptprinter.pas new file mode 100644 index 0000000..0448b3a --- /dev/null +++ b/mseide-msegui/lib/common/printer/msepostscriptprinter.pas @@ -0,0 +1,2693 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msepostscriptprinter; +{$ifdef FPC}{$mode objfpc}{$h+}{$GOTO ON}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + msegraphics,mseclasses,classes,mclasses,msegraphutils, + msestream,msestrings,msetypes, + msedrawtext,mserichstring,mseprinter,mseguiglob; + +const + defaultimagecachesize = 500000; + defaultimagecachemaxitemsize = 100000; + +type + pspointty = record + x: real; + y: real; + end; + psmatrixty = array [0..2] of array [0..1] of real; + +const + psunitymatrix: psmatrixty = ((1,0), //1 0 0 + (0,1), //0 1 0 + (0,0)); //0 0 1 + +type + tpostscriptcanvas = class; + + tpostscriptprinter = class(tstreamprinter,icanvas) + private + function getcanvas: tpostscriptcanvas; + //icanvas + procedure gcneeded(const sender: tcanvas); + function getkind: bitmapkindty; + procedure getcanvasimage(const bgr: boolean; var aimage: maskedimagety); + public + constructor create(aowner: tcomponent); override; + property canvas: tpostscriptcanvas read getcanvas; + published + property options default [pro_tempfile]; + end; + + psfontinfoty = record + handle: fontnumty; + namenum: integer; + size: integer; + scalestring1: ansistring; + scalestringfull: ansistring; + rotated: boolean; + codepages: integerarty; + end; + psfontinfoarty = array of psfontinfoty; + + psalignty = (pa_center,pa_lefttop,pa_top,pa_righttop,pa_right, + pa_rightbottom,pa_bottom,pa_leftbottom,pa_left); + pslevelty = (psl_1,psl_2,psl_3); + + imagecachekindty = (ick_1,ick_2,ick_3,ick_4); + imagecachety = record + source: tcanvas; + mask: tcanvas; + kind: imagecachekindty; + sourcerect: rectty; + bytecount: integer; +// rowbytes: integer; + statestamp: longword; + maskstatestamp: longword; + end; + imagecachearty = array of imagecachety; + + tpostscriptcanvas = class(tstreamprintercanvas) + private + ffonts: psfontinfoarty; + ffontnames: stringarty; + fps_pagenumber: integer; + fmapnames: array[0..255] of string; + factfont,factcodepage: integer; +// fstarted: boolean; + flandscape: boolean; + fpslevel: pslevelty; + fimagecache: imagecachearty; + fcacheorder: integerarty; + fimagecacheused: integer; + fimagecachesize: integer; + fimagecachemaxitemsize: integer; + procedure setimagecachesize(const avalue: integer); + procedure setimagecachemaxitemsize(const avalue: integer); + protected + fhaspage: boolean; + procedure gcdestroyed(const sender: tcanvas); override; + procedure freeimagecache(const index: integer); + procedure touchimagecache(const index: integer); + function getimagecache(const akind: imagecachekindty; const asource: tcanvas; + const asourcerect: rectty; out varname: string{; + out arowbytes: integer}): boolean; + //true if found + function setimagecache(const akind: imagecachekindty; + const asource: tcanvas; + const asourcerect: rectty; out varname: string; + const bytes: bytearty; {const arowbytes: integer;} + const amask: tcanvas = nil): boolean; + //true if stored + + function getgdifuncs: pgdifunctionaty; override; + procedure updatescale; override; + procedure initgcstate; override; + procedure initgcvalues; override; + procedure finalizegcstate; override; + procedure checkgcstate(state: canvasstatesty) override; + procedure checkscale; + function encodefontname(const namenum,codepage: integer): string; + function checkfont(const afont: fontnumty; const acodepage: integer): integer; + //returns index in ffonts + function getscalestring(const astyle: fontstylesty): ansistring; + procedure selectfont(const afont: fontnumty; const acodepage: integer); + procedure definefont(const adata: fontnumty; const acodepage: integer); + procedure setpslinewidth(const avalue: integer); + function strokestr: string; + function rectscalestring(const arect: rectty): string; + //transform unity cell to arect + function imagematrixstring(const asize: sizety): string; + + function getcolorstring(const acolor: colorty): string; + function setcolorstring(const acolor: colorty): string; + procedure writebinhex(const data: bytearty); + function psencode(const text: pchar; const count: integer): string; + function getshowstring(const avalue: pmsechar; const count: integer; + fontneeded: boolean = false; + const acolor: colorty = cl_none; + const acolorbackground: colorty = cl_none; + const fontstyle: fontstylesty = []): string; + function createpattern(const sourcerect,destrect: rectty; + const acolorbackground,acolorforeground: colorty; + const acanvas: tcanvas; +// const pixmap: pixmapty; const agchandle: ptruint; + const patname: string): boolean; + //true if ok + procedure handlepoly(const points: ppointty; const lastpoint: integer; + const closed: boolean; const fill: boolean); + procedure handleellipse(const rect: rectty; const fill: boolean); + procedure checkcolorspace; + procedure ps_drawstring16; + procedure ps_drawarc; + procedure ps_destroygc; + procedure ps_changegc; + procedure ps_drawlines; + procedure ps_drawlinesegments; + + procedure ps_fillpolygon; + procedure ps_fillarc; + procedure ps_fillrect; + procedure ps_copyarea; + procedure textout(const text: richstringty; const dest: rectty; + const flags: textflagsty; const tabdist: real); override; + procedure begintextclip(const arect: rectty); override; + procedure endtextclip; override; + procedure beginpage; override; + procedure endpage; override; + function registermap(const acodepage: integer): string; + //returns mapname ('E00' for latin 1) + procedure checkmap(const acodepage: integer); + function gcposstring(const apos: pointty): string; + public + constructor create(const user: tprinter; const intf: icanvas); + + function devpos(const apos: pointty): pspointty; + function posstring(const apos: pointty): string; + function matrixstring(const mat: psmatrixty): string; + function transrotate(const sourcecenter,destcenter: pointty; + const angle: real): string; + function diststring(const adist: integer): string; + function rectsizestring(const asize: sizety): string; + function sizestring(const asize: sizety): string; + function rectstring(const arect: rectty): string; + procedure pscommandbegin(); + procedure pscommandwrite(const atext: string); + procedure pscommandend(); + procedure pscommand(const atext: string); + // writes atext to postscript stream + published + property pslevel: pslevelty read fpslevel write fpslevel default psl_3; + property imagecachesize: integer read fimagecachesize write setimagecachesize + default defaultimagecachesize; + property imagecachemaxitemsize: integer read fimagecachemaxitemsize + write setimagecachemaxitemsize + default defaultimagecachemaxitemsize; + end; + +function psrealtostr(const avalue: real): string; +procedure pstranslate(var mat: psmatrixty; const dist: pspointty); +procedure psretranslate(var mat: psmatrixty; const dist: pspointty); +procedure psscale(var mat: psmatrixty; const scale: pspointty); +procedure psscale(var mat: psmatrixty; const scale: flo64); +procedure psscalex(var mat: psmatrixty; const scale: flo64); +procedure psscaley(var mat: psmatrixty; const scale: flo64); +procedure psrotate(var mat: psmatrixty; const angle: real); //radiant +function pstransform(const mat: psmatrixty; + const apoint: pspointty): pspointty; overload; +function pstransform(const mat: psmatrixty; + const apoint: pointty): pspointty; overload; +function psdist(const source,dest: pspointty): pspointty; overload; +//function psdist(const source,dest: pointty): pspointty; overload; +function pspoint(const apoint: pointty): pspointty; +procedure psnormalizerect(var ll,ur: pspointty); + +implementation +uses + msegui,msesys,sysutils,msedatalist,mseformatstr,mseunicodeps, + mseguiintf,msebits,msefloattostr,msefont,msearrayutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tsimplebitmap1 = class(tsimplebitmap); + tcanvas1 = class(tcanvas); +var + gdifuncs: pgdifunctionaty; + +procedure pstranslate(var mat: psmatrixty; const dist: pspointty); +begin + mat[2,0]:= mat[2,0] + dist.x; + mat[2,1]:= mat[2,1] + dist.y; +end; + +procedure psretranslate(var mat: psmatrixty; const dist: pspointty); +begin + mat[2,0]:= mat[2,0] - dist.x; + mat[2,1]:= mat[2,1] - dist.y; +end; + +procedure psscalex(var mat: psmatrixty; const scale: flo64); +begin + mat[0,0]:= mat[0,0] * scale; + mat[1,0]:= mat[1,0] * scale; + mat[2,0]:= mat[2,0] * scale; +end; + +procedure psscaley(var mat: psmatrixty; const scale: flo64); +begin + mat[0,1]:= mat[0,1] * scale; + mat[1,1]:= mat[1,1] * scale; + mat[2,1]:= mat[2,1] * scale; +end; + +procedure psscale(var mat: psmatrixty; const scale: pspointty); +begin + mat[0,0]:= mat[0,0] * scale.x; + mat[1,0]:= mat[1,0] * scale.x; + mat[2,0]:= mat[2,0] * scale.x; + mat[0,1]:= mat[0,1] * scale.y; + mat[1,1]:= mat[1,1] * scale.y; + mat[2,1]:= mat[2,1] * scale.y; +end; + +procedure psscale(var mat: psmatrixty; const scale: flo64); +begin + mat[0,0]:= mat[0,0] * scale; + mat[1,0]:= mat[1,0] * scale; + mat[2,0]:= mat[2,0] * scale; + mat[0,1]:= mat[0,1] * scale; + mat[1,1]:= mat[1,1] * scale; + mat[2,1]:= mat[2,1] * scale; +end; + +procedure psrotate(var mat: psmatrixty; const angle: real); //radiant +var + si,co: real; + m00,m01,m10,m11,m20,m21: real; +begin + si:= sin(angle); + co:= cos(angle); + m00:= mat[0,0]*co+mat[0,1]*-si; + m01:= mat[0,0]*si+mat[0,1]*co; + m10:= mat[1,0]*co+mat[1,1]*-si; + m11:= mat[1,0]*si+mat[1,1]*co; + m20:= mat[2,0]*co+mat[2,1]*-si; + m21:= mat[2,0]*si+mat[2,1]*co; + mat[0,0]:= m00; + mat[0,1]:= m01; + mat[1,0]:= m10; + mat[1,1]:= m11; + mat[2,0]:= m20; + mat[2,1]:= m21; +end; + +function pstransform(const mat: psmatrixty; const apoint: pspointty): pspointty; +begin + result.x:= mat[0,0]*apoint.x + mat[1,0]*apoint.y + mat[2,0]; + result.y:= mat[0,1]*apoint.x + mat[1,1]*apoint.y + mat[2,1]; +end; + +function pstransform(const mat: psmatrixty; const apoint: pointty): pspointty; +begin + result.x:= mat[0,0]*apoint.x + mat[1,0]*apoint.y + mat[2,0]; + result.y:= mat[0,1]*apoint.x + mat[1,1]*apoint.y + mat[2,1]; +end; + +function psdist(const source,dest: pspointty): pspointty; +begin + result.x:= dest.x - source.x; + result.y:= dest.y - source.y; +end; +{ +function psdist(const source,dest: pointty): pspointty; +begin + result.x:= dest.x - source.x; + result.y:= dest.y - source.y; +end; +} +function pspoint(const apoint: pointty): pspointty; +begin + result.x:= apoint.x; + result.y:= apoint.y; +end; + +procedure psnormalizerect(var ll,ur: pspointty); +var + f1: flo64; +begin + if ll.x > ur.x then begin + f1:= ll.x; + ll.x:= ur.x; + ur.x:= f1; + end; + if ll.y > ur.y then begin + f1:= ll.y; + ll.y:= ur.y; + ur.y:= f1; + end; +end; + +const + pageorientations: array[pageorientationty] of string = ('Portrait','Landscape'); + + imagepatname = 'impat'; + patpatname = 'pat'; + radtodeg = 360/(2*pi); + nl = lineend; + maxlinecharcount = 80; + preamble = +'/rf {'+nl+ //register font: alias,encoding,origname-> +'findfont'+nl+ //alias,encoding,font +'dup length dict '+ //alias,encoding,font,dict +'begin '+nl+ //alias,encoding,font dict is on top of dictstack + '{ 1 index /FID ne'+nl+ //alias,encoding,font,key,value + '{def}'+nl+ //alias,encoding,font + '{pop pop}'+nl+ //alias,encoding,font + 'ifelse'+nl+ + '} forall'+nl+ //alias,encoding + '/Encoding exch def'+nl+ //alias + 'currentdict'+nl+ //alias,dict +'end'+nl+ //alias,dict dict is removed from dictstack +'definefont '+ //dict +'pop'+nl+ // +'} bind def'+nl+ + // +'/sf {'+nl+ //select font: |-> optional + //[alias,scale(x),scaley,rotation,underline,stroke]-> +'dup'+ //[bak],[alias,scale(x),scaley,rotation] +' length 2 ge' + //[bak], length >= 2 + ' {dup'+ //[bak][alias,scale(x),scaley] + ' dup length 3 ge'+nl+ //[bak],[alias,scale(x),scaley],length >= 3 + '{1 2 getinterval aload pop}'+ //[bak],scalex,scaley + ' {1 get dup}'+ //[bak],scale,scale + ' ifelse'+nl+ + 'matrix scale'+ //[bak],smatrix + ' }'+ + ' {matrix}'+ //[bak],umatrix +' ifelse'+nl+ + +' 1 index'+ //[bak],smatrix,[alias,scale(x),scaley,rotation] +' length 4 ge'+ //[bak],smatrix, length >= 4 + ' {1 index'+ //[bak],smatrix,[alias,scale(x),scaley,rotation] + ' 3 get'+ //[bak],smatrix,rotation + ' matrix rotate'+ //[bak],smatrix,rmatrix + ' matrix concatmatrix}'+ +' if'+nl+ + +'1 index'+ //[bak],rmatrix,[alias,scale(x),scaley,rotation,underline,stroke] +' dup length 5 ge' + //[bak],rmatrix, + //[alias,scale(x),scaley,rotation,underline,stroke], length >= 5 +' {dup 4 get}'+ //[bak],rmatrix,[bak],underline +' {0} ifelse'+ //[bak],rmatrix,[bak],0 +' /uli exch def'+nl+ +'dup length 6 ge' + //[bak],rmatrix,[bak] + //[alias,scale(x),scaley,rotation,underline,stroke], length >= 6 +' {5 get}'+ //[bak],rmatrix,strokeout +' {pop 0} ifelse'+ //[bak],rmatrix,0 +' /sou exch def'+nl+ // + +'exch '+ //matrix,[alias] +' 0 get'+ //matrix,alias +' findfont'+ //matrix,font +' exch makefont'+ //font +' dup /FontMatrix get exch'+ //matrix,font +' dup /FontBBox get'+nl+ + //matrix,font,bbox +'aload pop'+ //matrix,font,llx,lly,urx,ury +' 5 index'+ //matrix,font,llx,lly,urx,ury,matrix +' transform'+ //matrix,font,llx,lly,urx',ury' +' /asc exch def pop'+ //matrix,font,llx,lly +' 3 index'+ //matrix,font,llx,lly,matrix +' transform'+ //matrix,font,llx',lly' +' -1 mul'+nl+' /desc exch def pop'+ //matrix,font +' setfont pop'+nl+ +'} bind def'+nl+ + +'/w {'+nl+ //[[text,[font],color,colorbackground],...]-> cx + //[[text,[font],color],...]-> cx + //[[text,[font]],...]-> cx + //[[text],...]-> cx + //calc stringwidth +' currentfont exch'+ //fontbak,inputarray +' 0 exch'+ //fontback,0,inputarray +' {'+ //fontback,sum,[text,[font],color,colorbackground] + ' dup length 2 ge'+ //fontback,sum,[text,[font],color,colorbackground],length>=2 + '{ dup 1 get sf}'+nl+ + 'if'+ //fontback,sum,[text,[font],color,colorbackground] + //set font + ' 0 get'+ //fontback,sum,text + ' stringwidth pop add'+//fontback,sum +' } forall'+ +' exch setfont'+nl+ +'} bind def'+nl+ + +'/s {'+nl+ //[[text,[font],color,colorbackground],...]-> cx + //[[text,[font],color,colorbackground],...]-> cx + //[[text,[font],color],...]-> cx + //[[text,[font]],...]-> cx + //[[text],...]-> cx + //select font, print text, ... +' {'+ + ' currentpoint /ay exch def /ax exch def'+ //backup for underline + ' dup'+ + ' dup length 3 ge'+nl+ //[bak], + //[text,[font],color,colorbackground],length >= 3 + '{dup 2 get'+ //[bak], + //[text,[font],color,colorbackground],[color] + ' aload pop setcolor'+ //[bak], + //[text,[font],color,colorbackground] + ' 0 2 getinterval'+ //[bak], + //[text,[font]] remove color + ' } if'+nl+ + ' dup length 2 eq'+ //array,arraylength = 5 + ' {aload pop sf}'+ //[bak],text + ' {aload pop}'+ //[bak],text + ' ifelse '+nl+ + + ' exch dup length 4 eq'+ //text,[bak],length = 4 + ' {'+ //text,[text,[font],color,colorbackground] + ' [currentcolor] exch'+ //text,[colbackup],[text,[font],color,colorbackground] + ' 3 get'+ //text,[colbackup],[colorbackground] + ' aload pop setcolor exch'+ //[colbackup],text + ' dup stringwidth pop'+nl+//[colbackup],text,width + ' currentpoint currentpoint asc add'+nl+ //[colbackup],text,width,x,y,x,y+asc + ' newpath moveto'+ //[colbackup],text,width,x,y + ' 2 index 0 rlineto'+ + ' 0 0 asc sub desc sub rlineto'+ + ' 0 3 index sub 0 rlineto'+nl+ + ' closepath fill'+ //[colbackup],text,width,x,y + ' moveto'+ //[colbackup],text,width + ' pop'+ //[colbackup],text + ' exch aload pop setcolor'+ //text + ' show'+ + ' }'+nl+ + ' {'+ //text,[text,font,rot,scalex,scaley,color] + ' pop'+ //text + ' show'+ + ' }'+ + ' ifelse'+nl+ + ' uli 0 ne {ul} if'+ //underline + ' sou 0 ne {so} if'+ //strokeout +' } forall'+nl+ +'} bind def'+nl+ + +'/slt {'+nl+ //print lefttop text,llx,lly,urx,ury -> +' asc sub'+ //text,llx,lly,urx,ury-asc +' 3 index'+ //text,llx,lly,urx,ury-asc,llx +' exch moveto currentpoint /ay exch def /ax exch def'+ //backup for underline + //text,llx,lly,urx +' pop pop pop s'+nl+ +'} bind def'+nl+ + +'/cy {'+nl+ //center y text,llx,lly,urx,ury-> text,llx,lly,urx,centeredy +' 2 index sub'+ //text,llx,lly,urx,ury-lly +' dup 0 eq'+nl+ //text,llx,lly,urx,ury-lly,bool + +' {pop 1 index}'+nl+ //text,llx,lly,urx,lly + +' {asc sub desc sub'+//text,llx,lly,urx,ury-lly-asc-desc +' 2 div 2 index'+//text,llx,lly,urx,ury-lly-asc-desc/2,lly +' add desc add}'+nl+ //text,llx,lly,urx,ury-lly-asc-desc/2+lly+desc + +' ifelse'+ +'} bind def'+nl+ + +'/sl {'+nl+ //print left text,llx,lly,urx,ury +' cy'+ //text,llx,lly,urx,centeredy +' 3 index exch'+ //text,llx,lly,urx,llx,ury-lly-asc-desc/2+lly+desc +' moveto '+nl+ +//' currentpoint /ay exch def /ax exch def'+ //backup for underline + //text,llx,lly,urx +' pop pop pop s'+nl+ +'} bind def'+nl+ + +'/sr {'+ //print right text: text,llx,lly,urx,ury-> +' cy'+ //text,llx,lly,urx,centeredy +' exch'+ //text,llx,lly,newy,urx +' 4 index'+nl+ //text,llx,lly,newy,urx,text +' w'+ //text,llx,lly,newy,urx,cx +' sub'+ //text,llx,lly,newy,urx-cx +' exch moveto'+ //text,llx,lly +//' currentpoint /ay exch def /ax exch def'+ //text,llx,lly +' pop pop s'+nl+ +'} bind def'+nl+ + +'/sc {'+nl+ //print center text: text,llx,lly,urx,ury -> +' cy'+ //text,llx,lly,urx,centeredy +' 4 index'+ //text,llx,lly,urx,centeredy,text +' w'+ //text,llx,lly,urx,centeredy,cx +' 4 index'+ //text,llx,lly,urx,centeredy,cx,llx +' 3 index'+ //text,llx,lly,urx,centeredy,cx,llx,urx +' exch sub'+ //text,llx,lly,urx,centeredy,cx,urx-llx +' exch sub'+ //text,llx,lly,urx,centeredy,urx-llx-cx +' 2 div'+ //text,llx,lly,urx,centeredy,(urx-llx-cx)/2 +' 4 index add'+nl+ //text,llx,lly,urx,centeredy,(urx-llx-cx)/2+llx +' exch'+ //text,llx,lly,urx,newx,centeredy +' moveto'+nl+ //text,llx,lly,urx +//' currentpoint /ay exch def /ax exch def'+ //text,llx,lly,urx +' pop pop pop s'+nl+ +' } bind def'+nl+ + +'/slb {'+nl+ //print lefttop text,llx,lly,urx,ury -> +' pop pop'+ //text,llx,lly +' desc add'+ //text,llx,lly+desc +' moveto'+ +//' currentpoint /ay exch def /ax exch def'+ //backup for underline + //text +' s'+nl+ +'} bind def'+nl+ + +'/srb {'+nl+ //print rightbottom text: text,llx,lly,urx,ury -> +' 4 index'+ //text,llx,lly,urx,ury,text +' w'+ //text,llx,lly,urx,ury,cx +' 2 index'+ //text,llx,lly,urx,ury,cx,urx +' exch'+ //text,llx,lly,urx,ury,urx,cx +' sub'+ //text,llx,lly,urx,ury,urx-cx +' 3 index'+ //text,llx,lly,urx,ury,urx-cx,lly +' desc add'+ //text,llx,lly,urx,ury,urx-cx,lly+desc +' moveto'+nl+ +//' currentpoint /ay exch def /ax exch def'+ //text,llx,lly,urx,ury +' pop pop pop pop s'+ +'} bind def'+nl+ + +'/srt {'+nl+ //print righttoptext: text,llx,lly,urx,ury -> +' 4 index'+ //text,llx,lly,urx,ury,text +' w'+ //text,llx,lly,urx,ury,cx +' 2 index'+ //text,llx,lly,urx,ury,cx,urx +' exch'+ //text,llx,lly,urx,ury,urx,cx +' sub'+ //text,llx,lly,urx,ury,urx-cx +' exch'+ //text,llx,lly,urx,urx-cx,ury +' asc sub'+ //text,llx,lly,urx,urx-cx,ury-asc +' moveto'+nl+ +//' currentpoint /ay exch def /ax exch def'+ //text,llx,lly,urx +' pop pop pop s'+ +'} bind def'+nl+ + +'/st {'+nl+ //print top text: text,llx,lly,urx,ury -> +' 4 index'+ //text,llx,lly,urx,ury,text +' w'+ //text,llx,lly,urx,ury,cx +' 4 index'+ //text,llx,lly,urx,ury,cx,llx +' 3 index'+ //text,llx,lly,urx,ury,cx,llx,urx +' exch sub'+ //text,llx,lly,urx,ury,cx,urx-llx +' exch sub'+ //text,llx,lly,urx,ury,urx-llx-cx +' 2 div'+ //text,llx,lly,urx,ury,(urx-llx-cx)/2 +' 4 index add'+nl+//text,llx,lly,urx,ury,(urx-llx-cx)/2+llx +' exch'+ //text,llx,lly,urx,newx,ury +' asc sub'+ //text,llx,lly,urx,newx,ury-asc +' moveto'+ //text,llx,lly,urx +//' currentpoint /ay exch def /ax exch def'+ //text,llx,lly,urx +' pop pop pop s'+nl+ +'} bind def'+nl+ + +'/sb {'+nl+ //print bottom text: text,llx,lly,urx,ury -> +' 4 index'+ //text,llx,lly,urx,ury,text +' w'+ //text,llx,lly,urx,ury,cx +' 4 index'+ //text,llx,lly,urx,ury,cx,llx +' 3 index'+ //text,llx,lly,urx,ury,cx,llx,urx +' exch sub'+ //text,llx,lly,urx,ury,cx,urx-llx +' exch sub'+ //text,llx,lly,urx,ury,urx-llx-cx +' 2 div'+ //text,llx,lly,urx,ury,(urx-llx-cx)/2 +' 4 index add'+nl+ //text,llx,lly,urx,ury,(urx-llx-cx)/2+llx +' 3 index'+ //text,llx,lly,urx,ury,newx,lly +' desc add'+ //text,llx,lly,urx,ury,newx,lly+desc +' moveto'+ //text,llx,lly,urx,ury +//' currentpoint /ay exch def /ax exch def'+ //text,llx,lly,urx,ury +' pop pop pop pop s'+nl+ +'} bind def'+nl+ + +'/ul {'+nl+ //underline +' gsave'+ +' desc 4 div setlinewidth'+ +' 0 setlinecap'+ +' [] 0 setdash'+ +' currentpoint'+ //x,y +' desc 2 div sub'+nl+ //x,y-desc/2 +' dup'+ //x,newy,newy +' 2 index exch'+ //x,newy,x,newy +' moveto'+ //x,newy +' ax exch'+ //x,ax,newy +' lineto stroke'+ //x +' pop'+ +' grestore'+ +'} bind def'+nl+ + +'/so {'+ //strokeout +' gsave'+ +' desc 4 div setlinewidth'+ +' 0 setlinecap'+ +' [] 0 setdash'+ +' currentpoint'+nl+ //x,y +' asc desc add 2 div add desc sub'+ //x,y+asc+desc/2-desc +' dup'+ //x,newy,newy +' 2 index exch'+ //x,newy,x,newy +' moveto'+ //x,newy +' ax exch'+ //x,ax,newy +' lineto stroke'+ //x +' pop'+ +' grestore'+nl+ +'} bind def'+nl+ + +'/tab {'+ //get tabulatorpos: taboffset,tabwidth -> tabx +' currentpoint'+ //o,w,x,y +' pop 2 index sub'+ //o,w,x-o +' 1 index 0.01 add'+ //o,w,x-o,w+0.01 force overflow on equal pos +' add '+ //o,w,x-o+w+0.01 +' 1 index div floor'+ //o,w,tabnum +' mul add'+nl+ //tabbedx +'} bind def'+nl+ + nl; + + alignmentsubs: array[psalignty] of string = ( + //pa_center,pa_lefttop,pa_top,pa_righttop,pa_right, + 'sc', 'slt', 'st', 'srt', 'sr', + //pa_rightbottom,pa_bottom,pa_leftbottom,pa_left + 'srb', 'sb', 'slb', 'sl'); + + tftopa: array [0..15] of psalignty = (//tf_xcentered,tf_right,tf_ycentered,tf_bottom, + pa_lefttop, // 0 0 0 0 + pa_top, // 1 0 0 0 + pa_righttop, // 0 1 0 0 + pa_center, //invalid // 1 1 0 0 + pa_left, // 0 0 1 0 + pa_center, // 1 0 1 0 + pa_right, // 0 1 1 0 + pa_center, //invalid // 1 1 1 0 + pa_leftbottom, // 0 0 0 1 + pa_bottom, // 1 0 0 1 + pa_rightbottom, // 0 1 0 1 + pa_center, //invalid // 1 1 0 1 + pa_center, //invalid // 0 0 1 1 + pa_center, //invalid // 1 0 1 1 + pa_center, //invalid // 0 1 1 1 + pa_center //invalid // 1 1 1 1 + ); + +type + postscriptgcdty = record + canvas: tpostscriptcanvas; + end; + postscriptgcty = record + case integer of + 0: (d: postscriptgcdty); + 1: (_bufferspace: gcpty;); +// res: array[1..23] of longword; + end; + + +procedure gdi_destroygc(var drawinfo: drawinfoty); +begin + try + postscriptgcty(drawinfo.gc.platformdata).d.canvas.ps_destroygc; + except //trap for stream write errors + end; +end; + +procedure gdi_changegc(var drawinfo: drawinfoty); +begin + postscriptgcty(drawinfo.gc.platformdata).d.canvas.ps_changegc; +end; + +procedure gdi_drawlines(var drawinfo: drawinfoty); +begin + postscriptgcty(drawinfo.gc.platformdata).d.canvas.ps_drawlines; +end; + +procedure gdi_drawlinesegments(var drawinfo: drawinfoty); +begin + postscriptgcty(drawinfo.gc.platformdata).d.canvas.ps_drawlinesegments; +end; + +procedure gdi_drawellipse(var drawinfo: drawinfoty); +begin + postscriptgcty(drawinfo.gc.platformdata).d.canvas.handleellipse( + drawinfo.rect.rect^,false); +end; + +procedure gdi_drawarc(var drawinfo: drawinfoty); +begin + postscriptgcty(drawinfo.gc.platformdata).d.canvas.ps_drawarc; +end; + +procedure gdi_fillrect(var drawinfo: drawinfoty); +begin + postscriptgcty(drawinfo.gc.platformdata).d.canvas.ps_fillrect; +end; + +procedure gdi_fillellipse(var drawinfo: drawinfoty); +begin + postscriptgcty(drawinfo.gc.platformdata).d.canvas.handleellipse( + drawinfo.rect.rect^,true); +end; + +procedure gdi_fillarc(var drawinfo: drawinfoty); +begin + postscriptgcty(drawinfo.gc.platformdata).d.canvas.ps_fillarc; +end; + +procedure gdi_fillpolygon(var drawinfo: drawinfoty); +begin + postscriptgcty(drawinfo.gc.platformdata).d.canvas.ps_fillpolygon; +end; + +procedure gdi_drawstring16(var drawinfo: drawinfoty); +begin + postscriptgcty(drawinfo.gc.platformdata).d.canvas.ps_drawstring16; +end; + +procedure gdi_setcliporigin(var drawinfo: drawinfoty); +begin +// gdierror(gde_notimplemented); +end; + +procedure gdi_copyarea(var drawinfo: drawinfoty); +begin + postscriptgcty(drawinfo.gc.platformdata).d.canvas.ps_copyarea; +end; + +var + gdifunctions: gdifunctionaty; + +function psrealtostr(const avalue: real): string; +begin +// result:= replacechar(formatfloat('0.###',avalue),decimalseparator,'.'); + //todo: optimize + result:= ansistring(doubletostring(avalue,-3,fsm_default,'.',#0)); +// result:= formatfloatmse(avalue,'0.000'); +end; + +{ tpostscriptcanvas } + +constructor tpostscriptcanvas.create(const user: tprinter; const intf: icanvas); +begin + fimagecachesize:= defaultimagecachesize; + fimagecachemaxitemsize:= defaultimagecachemaxitemsize; + fpslevel:= psl_3; + inherited create(user,intf); + fdrawinfo.gc.fontgdifuncs:= tcanvas.getclassgdifuncs; +end; + +function tpostscriptcanvas.getgdifuncs: pgdifunctionaty; +begin + result:= @gdifunctions; +end; + +procedure tpostscriptcanvas.checkscale; +begin + if fhaspage then begin + if (printorientation = pao_landscape) xor flandscape then begin + if flandscape then begin + streamwriteln('-90 rotate'); + end + else begin + streamwriteln('90 rotate'); + end; + flandscape:= not flandscape; + end; +{ + streamwrite('initmatrix '); + if printorientation = pao_landscape then begin + streamwrite(' 90 rotate'); + end; + streamwriteln(''); +} + end; +end; + +procedure tpostscriptcanvas.initgcstate; +begin + updatescale; + fps_pagenumber:= 0; + ffonts:= nil; + ffontnames:= nil; + finalize(fmapnames); + with postscriptgcty(fdrawinfo.gc.platformdata).d do begin + canvas:= self; + end; + inherited; + streamwrite( +'%!PS-Adobe-3.0'+nl+ +'%%BoundingBox: '+inttostr(fboundingbox.left)+' '+ + inttostr(fboundingbox.bottom)+' '+ + inttostr(fboundingbox.right)+' '+ + inttostr(fboundingbox.top)+nl+ +'%%Creator: '+ansistring(application.applicationname)+nl+ +'%%Title: '+ansistring(ftitle)+nl+ +'%%DocumentMedia: '+stdpagesizes[fprinter.pa_size].name+' '+ + inttostr(fpapersize.cx)+' '+ + inttostr(fpapersize.cy)+' 0 () ()'+nl+ +'%%Pages: (atend)'+nl+ +'%%PageOrder: Ascend'+nl+ +'%%EndComments'+nl+ +'%%BeginProlog'+nl+ + preamble+fpreamble+nl,true); + if fdeststream = fpreamblestream then begin + streamwrite( +'%%EndProlog'+nl,true); + end; + fpreamble:= ''; + fhaspage:= false; +// fstarted:= true; +// beginpage; +end; + +procedure tpostscriptcanvas.initgcvalues; +begin + inherited; + fimagecache:= nil; +end; + +procedure tpostscriptcanvas.finalizegcstate; +begin + if fdeststream <> fpreamblestream then begin + streamwrite( +'%%EndProlog'+nl,true); + end; + fhaspage:= false; +// fstarted:= false; + inherited; +end; + +procedure tpostscriptcanvas.checkgcstate(state: canvasstatesty); +begin + if (state - [cs_gc] <> []) and not fhaspage then begin + beginpage(); + end; + inherited; +end; + +function tpostscriptcanvas.encodefontname(const namenum,codepage: integer): string; +begin + result:= '/F' + hextostr(longword(codepage),2)+inttostr(namenum)+' '; +end; + +procedure tpostscriptcanvas.definefont(const adata: fontnumty; + const acodepage: integer); +var + str1: string; + int1,int2: integer; + rea1: real; +begin + with getfontdata(adata)^,realfont do begin + str1:= name; + if (str1 = '') or (h.name = 'stf_default') and (str1 = 'sans') then begin + str1:= 'Helvetica'; + end + else begin + str1:= psencode(pchar(str1),length(str1)); + end; + if d.style * [fs_bold,fs_italic] <> [] then begin + str1:= str1 + '-'; + if fs_bold in d.style then begin + str1:= str1 + 'Bold'; + end; + if fs_italic in d.style then begin + str1:= str1 + 'Italic'; + end; + end; + int2:= -1; + for int1:= 0 to high(ffontnames) do begin + if ffontnames[int1] = str1 then begin + int2:= int1; + break; + end; + end; + if int2 < 0 then begin + checkmap(acodepage); + additem(ffontnames,str1); + int2:= high(ffontnames); + //alias,encoding,origname + streamwrite(encodefontname(int2,acodepage)+fmapnames[acodepage]+ + ' ('+str1+') rf' + nl,true); + //register font + end; + setlength(ffonts,high(ffonts)+2); + with ffonts[high(ffonts)] do begin + handle:= adata; + namenum:= int2; + additem(codepages,acodepage); + if d.height = 0 then begin + size:= round(defaultfontheight*ppmm); + end + else begin + size:= (d.height + fontsizeroundvalue) shr fontsizeshift; + end; + rea1:= (size / ppmm) * mmtoprintscale; + scalestring1:= psrealtostr(rea1 * d.xscale); //xscale + scalestringfull:= scalestring1; + str1:= ' ' + psrealtostr(rea1); //yscale + scalestringfull:= scalestringfull + str1; + if (d.xscale <> 1) or (d.rotation <> 0) then begin + scalestring1:= scalestring1 + str1; + end; + str1:= ' ' + psrealtostr(d.rotation*radtodeg); + scalestringfull:= scalestringfull + str1; + if d.rotation <> 0 then begin + scalestring1:= scalestring1 + str1; + end; + end; + end; +end; + +function tpostscriptcanvas.checkfont(const afont: fontnumty; + const acodepage: integer): integer; +var + int1,int2: integer; + bo1: boolean; +begin + int2:= -1; + for int1:= 0 to high(ffonts) do begin + if ffonts[int1].handle = afont then begin + int2:= int1; + break; + end; + end; + if int2 < 0 then begin + definefont(afont,acodepage); + int2:= high(ffonts); + end + else begin + with ffonts[int2] do begin + bo1:= false; + for int1:= 0 to high(codepages) do begin + if codepages[int1] = acodepage then begin + bo1:= true; + break; + end; + end; + if not bo1 then begin + checkmap(acodepage); + streamwrite(encodefontname(namenum,acodepage)+fmapnames[acodepage]+ + ' ('+ffontnames[namenum]+') rf' + nl,true); + //register font + additem(codepages,acodepage); + end; + end; + end; + result:= int2; + factfont:= int2; + factcodepage:= acodepage; +end; + +function tpostscriptcanvas.getscalestring(const astyle: fontstylesty): ansistring; +begin + with ffonts[factfont] do begin + if (astyle * [fs_underline,fs_strikeout] <> []) then begin + result:= scalestringfull; + if fs_underline in astyle then begin + result:= result + ' 1'; + end + else begin + result:= result + ' 0'; + end; + if fs_strikeout in astyle then begin + result:= result + ' 1'; + end; + end + else begin + result:= scalestring1; + end; + end; +end; + +procedure tpostscriptcanvas.selectfont(const afont: fontnumty; const acodepage: integer); +begin + checkfont(afont,acodepage); + streamwrite('['+encodefontname(ffonts[factfont].namenum,acodepage)+ + getscalestring(font.style) + '] sf'+nl); +end; + +procedure tpostscriptcanvas.ps_destroygc; +begin + endpage; + streamwrite( + '%%Trailer'+nl+ + '%%Pages: '+inttostr(fps_pagenumber)+nl+ + '%%EOF'+nl); +end; + +procedure tpostscriptcanvas.ps_changegc; +var + str1: string; + int1,int2: integer; + rect1,rect2: rectty; + ar1: rectarty; +begin + ar1:= nil; //compiler warning + with fdrawinfo,gcvalues^ do begin + if gvm_dashes in mask then begin + int2:= length(lineinfo.dashes); + if (int2 > 0) and (lineinfo.dashes[int2] = #0) then begin + dec(int2); + end; + str1:= '['; + for int1:= 1 to int2 do begin + str1:= str1 + + psrealtostr(mmtoprintscale*(byte(lineinfo.dashes[int1])/ppmm))+' '; + end; + str1:= str1+'] 0 setdash'+nl; + streamwrite(str1); + end; + if (self.brush <> nil) and + ([gvm_brush,gvm_brushorigin] * mask <> []) then begin + with tsimplebitmap1(self.brush) do begin + rect1:= makerect(nullpoint,size); + rect2:= makerect(self.brushorigin,size); + if createpattern(rect1,rect2,acolorbackground,acolorforeground, + canvas{handle,canvas.gchandle},patpatname) then begin + streamwrite('/bru exch def'+nl); + end; + end; + end; + if df_brush in gc.drawingflags then begin + streamwrite('bru setpattern'+nl); + end + else begin + if gvm_colorforeground in mask then begin + streamwrite(setcolorstring(acolorforeground)+nl); + end; + end; + if gvm_font in mask then begin + selectfont(fontnum,0); + end; + if gvm_linewidth in mask then begin + setpslinewidth(lineinfo.width); + end; + if gvm_capstyle in mask then begin + case lineinfo.capstyle of + cs_round: str1:= '1'; + cs_projecting: str1:= '2'; + else str1:= '0'; //cs_butt + end; + streamwrite(str1+' setlinecap'+nl); + end; + if gvm_joinstyle in mask then begin + case lineinfo.joinstyle of + js_round: str1:= '1'; + js_bevel: str1:= '2'; + else str1:= '0'; //js_miter + end; + streamwrite(str1+' setlinejoin'+nl); + end; + if gvm_clipregion in mask then begin + str1:= 'initclip'; + if clipregion <> 0 then begin + ar1:= gui_regiontorects(clipregion); + str1:= str1 + ' ['; + int2:= 3; + for int1:= 0 to high(ar1) do begin + str1:= str1 + ' '+ + gcposstring(addpoint(ar1[int1].pos,gc.cliporigin)) + + ' ' + rectsizestring(ar1[int1].size); + dec(int2); + if int2 <= 0 then begin + int2:= 3; + str1:= str1 + nl; + end; + end; + str1:= str1 + '] rectclip'; + end; + streamwrite(str1+nl); + end; + end; +end; + +function tpostscriptcanvas.gcposstring(const apos: pointty): string; +begin + result:= + psrealtostr(apos.x*fgcscale+fgcoffsetx)+' '+ + psrealtostr(fgcoffsety-apos.y*fgcscale); +end; + +function tpostscriptcanvas.devpos(const apos: pointty): pspointty; +begin + if not (cs_origin in fstate) then begin + checkgcstate([cs_origin]); + end; + result.x:= apos.x*fgcscale+foriginx; + result.y:= foriginy-apos.y*fgcscale; +end; + +function tpostscriptcanvas.posstring(const apos: pointty): string; +var + pt1: pspointty; +begin + pt1:= devpos(apos); + result:= psrealtostr(pt1.x)+' '+ psrealtostr(pt1.y); +end; + +function tpostscriptcanvas.matrixstring(const mat: psmatrixty): string; +begin + result:= '['+psrealtostr(mat[0,0])+' '+psrealtostr(mat[0,1])+' '+ + psrealtostr(mat[1,0])+' '+psrealtostr(mat[1,1])+' '+ + psrealtostr(mat[2,0])+' '+psrealtostr(mat[2,1])+']'; +end; + +function tpostscriptcanvas.transrotate(const sourcecenter,destcenter: pointty; + const angle: real): string; +var + mat1: psmatrixty; +begin + mat1:= psunitymatrix; + psrotate(mat1,angle); + pstranslate(mat1,psdist(pstransform(mat1,devpos(sourcecenter)), + devpos(destcenter))); + result:= matrixstring(mat1) + ' concat'; +end; + +function tpostscriptcanvas.diststring(const adist: integer): string; +begin + result:= psrealtostr(adist*fgcscale); +end; + +function tpostscriptcanvas.sizestring(const asize: sizety): string; +begin + result:= psrealtostr(asize.cx*fgcscale)+' '+psrealtostr(asize.cy*fgcscale); +end; + +function tpostscriptcanvas.rectsizestring(const asize: sizety): string; +begin + result:= psrealtostr(asize.cx*fgcscale)+' '+psrealtostr(-asize.cy*fgcscale); +end; + +function tpostscriptcanvas.rectstring(const arect: rectty): string; +begin + with arect do begin + result:= + psrealtostr(x*fgcscale+foriginx)+' '+ + psrealtostr(foriginy-y*fgcscale)+' '+ + psrealtostr(cx*fgcscale)+' '+psrealtostr(-cy*fgcscale) + end; +end; + +function tpostscriptcanvas.getcolorstring(const acolor: colorty): string; +var + co1: rgbtriplety; +begin + co1:= colortorgb(acolor); + if fcolorspace = cos_rgb then begin + result:= psrealtostr(co1.red/255)+' '+psrealtostr(co1.green/255)+' '+ + psrealtostr(co1.blue/255); + end + else begin + result:= psrealtostr((word(co1.red)+co1.green+co1.blue)/(3.0*255)); + end; +end; + +function tpostscriptcanvas.setcolorstring(const acolor: colorty): string; +begin + if fcolorspace = cos_rgb then begin + result:= getcolorstring(acolor)+' setrgbcolor'; + end + else begin + result:= getcolorstring(acolor)+' setgray'; + end; +end; + +function tpostscriptcanvas.psencode(const text: pchar; const count: integer): string; +var + int1,int2: integer; + ch1: char; + po1: pchar; +begin + setlength(result,count*4); //max + po1:= pchar(pointer(result)); + int2:= 0; + for int1:= 0 to count-1 do begin + ch1:= (text+int1)^; + if (ch1 >= #128) or (ch1 < #32) then begin + if ch1 = #0 then begin + dec(int2); //remove zeroes + end + else begin + (po1+int2)^:= '\'; //octal + (po1+int2+3)^:= char((byte(ch1) and $07) + ord('0')); + ch1:= char(byte(ch1) shr 3); + (po1+int2+2)^:= char((byte(ch1) and $07) + ord('0')); + ch1:= char(byte(ch1) shr 3); + (po1+int2+1)^:= char((byte(ch1) and $03) + ord('0')); + inc(int2,3); + end; + end + else begin + case ch1 of + '\','(',')': begin + (po1+int2)^:= '\'; + inc(int2); + (po1+int2)^:= ch1; + end; + else begin + (po1+int2)^:= ch1; + end; + end; + end; + inc(int2); + end; + setlength(result,int2); +end; + +function tpostscriptcanvas.getshowstring(const avalue: pmsechar; + const count: integer; fontneeded: boolean = false; + const acolor: colorty = cl_none; + const acolorbackground: colorty = cl_none; + const fontstyle: fontstylesty = []): string; +var + int1: integer; + wo1,wo2: word; + po1,po2: pchar; + colback: colorty; + + procedure pushsubstring; + begin + result:= result + '[('+psencode(po2,po1-po2)+')'; + if fontneeded then begin + with ffonts[factfont] do begin +// result:= result + ' ['+encodefontname(namenum,factcodepage) + scalestring1+']'; + result:= result + ' ['+encodefontname(namenum,factcodepage) + + getscalestring(fontstyle)+']'; + end; + end; + if acolor <> cl_none then begin + result:= result+'['+getcolorstring(acolor)+']'; + end; + if colback <> cl_transparent then begin + if acolor = cl_none then begin + result:= result + '[currentcolor]'; + end; + result:= result+'['+getcolorstring(colback)+']'; + end; + result:= result +']'; + po1:= po2; + end; + +begin + if acolorbackground <> cl_none then begin + colback:= acolorbackground; + end + else begin + colback:= font.colorbackground; + end; + if (acolor <> cl_none) or (colback <> cl_transparent) then begin + fontneeded:= true; + end; + getmem(po1,count); + po2:= po1; + wo1:= factcodepage shl 8; + result:= ''; + for int1:= 0 to count -1 do begin + wo2:= word(pmsecharaty(avalue)^[int1]); + if (wo2 xor wo1) and $ff00 <> 0 then begin + if int1 <> 0 then begin + pushsubstring; + end; + fontneeded:= true; + wo1:= wo2 and $ff00; + checkfont(ffonts[factfont].handle,wo1 shr 8); + end; + po1^:= char(wo2); + inc(po1); + end; + pushsubstring; + freemem(po2); +end; + +procedure tpostscriptcanvas.ps_drawstring16; +begin + if active then begin + with fdrawinfo.text16pos do begin + streamwrite(posstring(pos^)+' moveto ['+getshowstring(text,count)+'] s'+nl); + end; + end; +end; + +procedure tpostscriptcanvas.textout(const text: richstringty; const dest: rectty; + const flags: textflagsty; const tabdist: real); +const + fontstylemask{: newinfosty} = [ni_bold,ni_italic,ni_underline,ni_strikeout]; + mask1 = [tf_xcentered,tf_right]; + mask2 = [tf_ycentered,tf_bottom]; +var + str1: ansistring; + int1,int2,int3: integer; + co1,co2: colorty; + colorchanged: boolean; + style1: fontstylesty; + lastbreak: integer; + rect1: rectty; + + procedure addstring(const astring: ansistring); + begin + if (length(str1) - lastbreak) + length(astring) > maxlinecharcount then begin + str1:= str1+ nl; + lastbreak:= length(str1); + end; + str1:= str1+astring; + end; +var + pt1: pointty; + rea1: real; +begin + if not active {or (text.text = '')} then begin + exit; + end; + colorchanged:= false; + str1:= ''; + if flags * [tf_rotate90,tf_rotate180] <> [] then begin + str1:= 'matrix currentmatrix'+nl; //backup + pt1:= dest.pos; + if tf_rotate90 in flags then begin + if tf_rotate180 in flags then begin + rea1:= pi*3.0/2.0; + pt1.x:= pt1.x+dest.cx; + end + else begin + rea1:= pi/2.0; + pt1.y:= pt1.y+dest.cy; + end; + end + else begin + rea1:= pi; + pt1.x:= pt1.x+dest.cx; + pt1.y:= pt1.y+dest.cy; + end; + str1:= str1+transrotate(dest.pos,pt1,rea1)+nl; + end; + lastbreak:= 0; + str1:= str1+'['; + if (text.format = nil) or (text.text = '') then begin + addstring(getshowstring(pmsechar(text.text),length(text.text), + true,cl_none,cl_none,font.style)+'] '); + end + else begin + gcfonthandle1:= 0; //invalid after print + with text.format[0] do begin + if index > 0 then begin + addstring(getshowstring(pmsechar(pointer(text.text)),index)); + end; + end; + co1:= cl_none; + co2:= cl_none; + style1:= font.style; + for int1:= 0 to high(text.format) do begin + with text.format[int1] do begin + if int1 = high(text.format) then begin + int3:= bigint; + end + else begin + int3:= text.format[int1+1].index; + end; + if int3 > length(text.text) then begin + int3:= length(text.text); + end; + int2:= index + 1; + if int2 > length(text.text) then begin + int2:= length(text.text); + end; + if newinfos * fontstylemask <> [] then begin + style1:= style1 * fontstylesty( + {$ifndef FPC}byte({$endif} + not {$ifdef FPC}longword{$else}word{$endif}(newinfos)) + {$ifndef FPC}){$endif} + style.fontstyle; + end; + font.style:= style1; + checkfont(font.handle,(word(text.text[int2]) and $ff00) shr 8); + int2:= int3 - index; + if int2 > 0 then begin + if ni_fontcolor in newinfos then begin + if style.fontcolor = 0 then begin + co1:= font.color; + colorchanged:= false; + end + else begin + co1:= not style.fontcolor; + colorchanged:= true; + end; + end; + if ni_colorbackground in newinfos then begin + if style.colorbackground = 0 then begin + co2:= cl_none; + end + else begin + co2:= not style.colorbackground; + end; + end; + addstring(getshowstring(pmsechar(pointer(text.text))+index,int2,true,co1,co2, + style1)); + end; + end; + end; + str1:= str1 + '] '; + end; + if tf_rotate90 in flags then begin + rect1.pos:= dest.pos; + rect1.cx:= dest.cy; + rect1.cy:= dest.cx; + end + else begin + rect1:= dest; + end; + if tabdist = 0 then begin + str1:= str1 + posstring(makepoint(rect1.x,rect1.y+rect1.cy))+' '+ //lower left + posstring(makepoint(rect1.x+rect1.cx,rect1.y))+ ' '; //upper right + end + else begin + if tabdist < 0 then begin //last pos + str1:= str1 + 'currentpoint pop '; //oldx (llx) + end + else begin //defaulttab + str1:= str1 + psrealtostr(foriginx)+' '+psrealtostr(tabdist) + ' tab '; + //tabbedx (llx) + end; + str1:= str1 + psrealtostr(foriginy-(rect1.y+rect1.cy)*fgcscale)+ + //llx,lly + ' 1 index '+ //llx,lly,urx + psrealtostr(foriginy-(rect1.y)*fgcscale)+' '; //llx,lly,urx,ury + end; + int1:= (longword(flags*mask1) shr 1) or + (longword(flags*mask2) shr 3); + //remove tf_left, tf_xjustify and tf_top + str1:= str1+alignmentsubs[tftopa[int1]]; +{ + if fs_underline in font.style then begin + str1:= str1 + ' ul'; + end; + if fs_strikeout in font.style then begin + str1:= str1 + ' so'; + end; +} + if colorchanged then begin + str1:= str1 + ' '+setcolorstring(font.color); + end; + if flags * [tf_rotate90,tf_rotate180] <> [] then begin + str1:= str1+nl+'setmatrix'; //restore CTM + end; + streamwrite(str1+nl); +end; + +procedure tpostscriptcanvas.begintextclip(const arect: rectty); +begin + streamwrite('gsave '+rectstring(arect)+' rectclip'+nl); +end; + +procedure tpostscriptcanvas.endtextclip; +begin + streamwrite('grestore'+nl); +end; + +procedure tpostscriptcanvas.setpslinewidth(const avalue: integer); +var + rea1: real; +begin + if avalue = 0 then begin + rea1:= nulllinewidth; + end + else begin + rea1:= avalue/(ppmm*(1 shl linewidthshift)) * mmtoprintscale; + end; + streamwrite(psrealtostr(rea1)+' setlinewidth'+nl); +end; + +function tpostscriptcanvas.strokestr: string; +begin + if (length(dashes) > 0) and (df_opaque in fdrawinfo.gc.drawingflags) then begin + //(dashes[length(dashes)] = #0) then begin + result:= 'gsave [] 0 setdash ' + setcolorstring(fdrawinfo.acolorbackground) + + ' stroke grestore stroke'; //draw background + end + else begin + result:= 'stroke'; + end; +end; + +procedure tpostscriptcanvas.handlepoly(const points: ppointty; + const lastpoint: integer; const closed: boolean; const fill: boolean); +var + int1: integer; + str1,str2: string; +begin + if active then begin + str1:= ''; + str2:= 'newpath '+ posstring(points^) + ' moveto '+nl; + for int1:= 1 to lastpoint do begin + if length(str1) > 80 then begin + str2:= str2 + str1 + nl; + str1:= ''; + end; + str1:= str1 + posstring(ppointaty(points)^[int1])+' lineto '; + end; + str2:= str2 + str1 + nl; + if closed then begin + str2:= str2 + 'closepath '; + end; + if fill then begin + str2:= str2 + 'fill'; + end + else begin + str2:= str2 + strokestr; + end; + streamwrite(str2+nl); + end; +end; + +procedure tpostscriptcanvas.handleellipse(const rect: rectty; const fill: boolean); +var + str1: string; +begin + with rect do begin + str1:= 'newpath '; + if cy = cx then begin + str1:= str1+posstring(pos)+' '+diststring(cx div 2)+' 0 360 arc '; + end + else begin + str1:= str1 + 'matrix currentmatrix '+ posstring(pos) + ' translate '+nl+ + sizestring(size)+' scale 0 0 0.5 0 360 arc setmatrix '; + end; + end; + str1:= str1 + 'closepath '; + if fill then begin + str1:= str1 + 'fill'; + end + else begin + str1:= str1 + strokestr; + end; + streamwrite(str1+nl); +end; + +procedure tpostscriptcanvas.ps_drawarc; +var + str1: string; +begin + with fdrawinfo.arc,rect^ do begin + str1:= 'newpath '; + if cy = cx then begin + str1:= str1+posstring(pos)+' '+diststring(cx div 2)+' '+ + psrealtostr(startang*radtodeg)+' '+psrealtostr((startang+extentang)*radtodeg)+ + ' arc '; + end + else begin + str1:= str1 + 'matrix currentmatrix '+ posstring(pos) + ' translate '+nl+ + sizestring(size)+' scale 0 0 0.5 '+ + psrealtostr(startang*radtodeg)+' '+psrealtostr((startang+extentang)*radtodeg)+ + ' arc setmatrix '; + end; + end; + str1:= str1 + strokestr; + streamwrite(str1+nl); +end; + +procedure tpostscriptcanvas.ps_fillarc; +var + str1: string; +begin + with fdrawinfo.arc,rect^ do begin + str1:= 'newpath '; + if pieslice then begin + str1:= str1+posstring(pos)+' moveto '; + end; + if cy = cx then begin + str1:= str1+posstring(pos)+' '+diststring(cx div 2)+' '+ + psrealtostr(startang*radtodeg)+' '+psrealtostr((startang+extentang)*radtodeg)+ + ' arc '; + end + else begin + str1:= str1 + 'matrix currentmatrix '+ posstring(pos) + ' translate '+nl+ + sizestring(size)+' scale 0 0 0.5 '+ + psrealtostr(startang*radtodeg)+' '+psrealtostr((startang+extentang)*radtodeg)+ + ' arc setmatrix '; + end; + end; + str1:= str1 + 'closepath fill'; + streamwrite(str1+nl); +end; + +procedure tpostscriptcanvas.ps_drawlines; +begin + with fdrawinfo.points do begin + handlepoly(points,count-1,closed,false); + end; +end; + +procedure tpostscriptcanvas.ps_drawlinesegments; +var + int1: integer; +begin + with fdrawinfo.points do begin + for int1:= 0 to count div 2 - 1 do begin + handlepoly(points,1,false,false); + inc(points,2); + end; + end; +end; + +procedure tpostscriptcanvas.ps_fillpolygon; +begin + with fdrawinfo.points do begin + handlepoly(points,count-1,true,true); + end; +end; + +procedure tpostscriptcanvas.ps_fillrect; +var + points1: array[0..3] of pointty; +begin + with fdrawinfo.rect.rect^ do begin + points1[0].x:= x; + points1[0].y:= y; + points1[1].x:= x+cx; + points1[1].y:= y; + points1[2].x:= x+cx; + points1[2].y:= y+cy; + points1[3].x:= x; + points1[3].y:= y+cy; + handlepoly(@points1,high(points1),true,true); + end; +end; + +procedure tpostscriptcanvas.writebinhex(const data: bytearty); +var + int1,int2,int3: integer; + po1: pbyte; + po2: pchar; + str1: string; +begin + po1:= pointer(data); + int2:= length(data); + setlength(str1,80); + repeat + int1:= 40; + if int1 > int2 then begin + int1:= int2; + setlength(str1,2*int1); + end; + po2:= pchar(str1); + for int3:= int1 - 1 downto 0 do begin + po2^:= charhex[po1^ shr 4]; + inc(po2); + po2^:= charhex[po1^ and $0f]; + inc(po2); + inc(po1); + end; + dec(int2,40); + streamwriteln(str1); + until int2 <= 0; +end; + +function tpostscriptcanvas.rectscalestring(const arect: rectty): string; + //transform unity cell to arect +begin + with arect do begin + result:= psrealtostr(x*fgcscale+foriginx)+' '+ + psrealtostr(foriginy-(y+cy{-1})*fgcscale)+' translate '+ + psrealtostr(cx*fgcscale)+' '+psrealtostr(cy*fgcscale)+' scale'; + end; +end; + +function tpostscriptcanvas.imagematrixstring(const asize: sizety): string; +var + str1: string; +begin + with asize do begin + str1:= inttostr(cy); + result:= '['+inttostr(cx)+' 0 0 -'+str1+' 0 '+str1+']'; + end; +end; + +const + unityrectpath = 'newpath 0 0 moveto 1 0 lineto 1 1 lineto 0 1 lineto closepath'; + +procedure convertrgb(const sourcerect: rectty; const image: imagety; + out data: bytearty; out rowbytes: integer); +var + po1: prgbtriplety; + po2,po3: pbyte; + int1,int2: integer; +begin + with sourcerect do begin + rowbytes:= cx*3; + setlength(data,rowbytes*cy); + po2:= pointer(data); + if image.kind = bmk_rgb then begin + for int1:= y to y + cy - 1 do begin + po1:= @image.pixels^[int1*image.size.cx+x]; + for int2:= x to x + cx - 1 do begin + po2^:= po1^.red; + inc(po2); + po2^:= po1^.green; + inc(po2); + po2^:= po1^.blue; + inc(po2); + inc(po1); + end; + end; + end + else begin //bmk_gray + for int1:= y to y + cy - 1 do begin + po3:= pointer(image.pixels)+ int1*image.linebytes + x; + for int2:= x to x + cx - 1 do begin + po2^:= po3^; + inc(po2); + po2^:= po3^; + inc(po2); + po2^:= po3^; + inc(po2); + inc(po3); + end; + end; + end; + end; +end; + +procedure convertgray(const sourcerect: rectty; const image: imagety; + out data: bytearty; out rowbytes: integer); +var + po1: prgbtriplety; + po2,po3: pbyte; + int1,int2: integer; +begin + with sourcerect do begin + rowbytes:= cx; + setlength(data,rowbytes*cy); + po2:= pointer(data); + if image.kind = bmk_rgb then begin + for int1:= y to y + cy - 1 do begin + po1:= @image.pixels^[int1*image.size.cx+x]; + for int2:= x to x + cx - 1 do begin + po2^:= (po1^.red + po1^.green + po1^.blue) div 3; + inc(po2); + inc(po1); + end; + end; + end + else begin //bmk_gray + for int1:= y to y + cy - 1 do begin + po3:= pointer(image.pixels) + int1*image.linebytes + x; + for int2:= x to x + cx - 1 do begin + po2^:= po3^; + inc(po2); + inc(po3); + end; + end; + end; + end; +end; + +procedure convertmono(const sourcerect: rectty; const image: imagety; + out data: bytearty; out rowbytes: integer); +var + sourcerowstep: integer; + rowshiftleft,rowshiftright: byte; + po1,po2: pbyte; + int1,int2: integer; +begin + with sourcerect do begin + rowbytes:= (cx + 7) div 8; + setlength(data,rowbytes*cy); + rowshiftright:= x and $7; + rowshiftleft:= 8-rowshiftright; + sourcerowstep:= ((image.size.cx + 31) div 32)*4; + po1:= @pbyteaty(image.pixels)^[y * sourcerowstep + x div 8]; + sourcerowstep:= sourcerowstep - rowbytes; + po2:= pointer(data); + for int1:= cy - 1 downto 0 do begin + for int2:= rowbytes - 1 downto 0 do begin + po2^:= (po1^ shr rowshiftright); + inc(po1); + po2^:= bitreverse[po2^ or byte(po1^ shl rowshiftleft)]; + //byte(... needed for FPC! + inc(po2); + end; + inc(po1,sourcerowstep); + end; + end; +end; + +procedure convertmonotogray(const sourcerect: rectty; var image: imagety; + out data: bytearty; out rowbytes: integer; + const colorforeground,colorbackground: colorty); +var + grf,grb: byte; + po1: pbyte; + po2: pbyte; + int1,int2: integer; + ar1: bytearty; + rowb: integer; + by1: byte; +begin + convertmono(sourcerect,image,ar1,rowb); +// image.monochrome:= false; + image.kind:= bmk_rgb; + with colortorgb(colorforeground) do begin + grf:= (red + green + blue) div 3; + end; + with colortorgb(colorbackground) do begin + grb:= (red + green + blue) div 3; + end; + with sourcerect do begin + rowbytes:= cx; + setlength(data,rowbytes*cy); + po2:= pointer(data); + for int1:= 0 to cy - 1 do begin + po1:= @ar1[int1*rowb]; + for int2:= 0 to cx - 1 do begin + by1:= bytebitsreverse[int2 and $7]; + if po1^ and by1 = 0 then begin + po2^:= grb; + end + else begin + po2^:= grf; + end; + inc(po2); + if by1 = $01 then begin + inc(po1); + end; + end; + end; + end; +end; + +procedure convertmonotorgb(const sourcerect: rectty; var image: imagety; + out data: bytearty; out rowbytes: integer; + const colorforeground,colorbackground: colorty); +var + rgbf,rgbb: rgbtriplety; + po1: pbyte; + po2: pbyte; + int1,int2: integer; + ar1: bytearty; + rowb: integer; + by1: byte; + po3: prgbtriplety; +begin + convertmono(sourcerect,image,ar1,rowb); +// image.monochrome:= false; + image.kind:= bmk_rgb; + rgbf:= colortorgb(colorforeground); + rgbb:= colortorgb(colorbackground); + with sourcerect do begin + rowbytes:= cx*3; + setlength(data,rowbytes*cy); + po2:= pointer(data); + for int1:= 0 to cy - 1 do begin + po1:= @ar1[int1*rowb]; + for int2:= 0 to cx - 1 do begin + by1:= bytebitsreverse[int2 and $7]; + if po1^ and by1 = 0 then begin + po3:= @rgbb; + end + else begin + po3:= @rgbf; + end; + po2^:= po3^.red; + inc(po2); + po2^:= po3^.green; + inc(po2); + po2^:= po3^.blue; + inc(po2); + if by1 = $01 then begin + inc(po1); + end; + end; + end; + end; +end; + +function tpostscriptcanvas.createpattern(const sourcerect,destrect: rectty; + const acolorbackground,acolorforeground: colorty; + const acanvas: tcanvas; + {const pixmap: pixmapty; const agchandle: ptruint;} + const patname: string): boolean; + //returns pattern dict on ps stack +var + ar1: bytearty; + str1: string; +// components: integer; + rowbytes: integer; + varname: string; + image: imagety; + cached: boolean; +begin + result:= true; + rowbytes:= 0; + ar1:= nil; + cached:= getimagecache(ick_3,acanvas,sourcerect,varname{,rowbytes}); + if not cached then begin + gdi_lock; + // result:= gdi_pixmaptoimage(pixmap,image,agchandle) = gde_ok; + result:= gui_pixmaptoimage(acanvas.paintdevice,image,acanvas.gchandle) = gde_ok; + gdi_unlock; + if not result then begin + exit; + end; +// components:= 1; + if acanvas.kind = bmk_mono then begin + convertmono(sourcerect,image,ar1,rowbytes); + end + else begin + if colorspace = cos_gray then begin + convertgray(sourcerect,image,ar1,rowbytes); + end + else begin +// components:= 3; + convertrgb(sourcerect,image,ar1,rowbytes); + end; + end; + gui_freeimagemem(image.pixels); + if length(ar1) > 60000 then begin + result:= false; + exit; + end; + cached:= setimagecache(ick_3,acanvas,sourcerect,varname,ar1{,rowbytes}); + end; + if cached then begin + str1:= '/'+patname+' '+varname+' def '; + end + else begin + str1:= '/'+patname+' '+inttostr(rowbytes*sourcerect.cy)+' string def'+nl+ + 'currentfile '+patname+' readhexstring'+nl; + streamwrite(str1); + writebinhex(ar1); + str1:= 'pop pop '; + end; + str1:= str1+'gsave '+rectscalestring(destrect)+nl+ +'<< /PatternType 1 /PaintType 1 /TilingType 1 /BBox [0 0 1 1] /XStep 1 /YStep 1'+nl+ +'/PaintProc {' + nl; + if acanvas.kind = bmk_mono then begin + if acolorbackground <> cl_transparent then begin + str1:= str1 + unityrectpath + nl + + setcolorstring(acolorbackground) + ' fill '; + end; + str1:= str1 + setcolorstring(acolorforeground) + nl; + end; + str1:= str1 + + inttostr(sourcerect.size.cx) + ' ' + inttostr(sourcerect.size.cy); + if acanvas.kind = bmk_mono then begin + str1:= str1 + ' true '; + end + else begin + str1:= str1 + ' 8'; + end; + str1:= str1 + imagematrixstring(sourcerect.size)+ ' '+patname+' '; + if acanvas.kind = bmk_mono then begin + str1:= str1 + 'imagemask'; + end + else begin + if colorspace = cos_gray then begin + str1:= str1 + 'image'; + end + else begin + str1:= str1 + 'false 3 colorimage'; + end; + end; + str1:= str1+' } bind >> matrix makepattern grestore'+nl; + streamwrite(str1); +end; + +procedure tpostscriptcanvas.checkcolorspace; +begin + if not (cs_acolorforeground in fstate) then begin + streamwrite(setcolorstring(color)+nl); //init colorspace + include(fstate,cs_acolorforeground); + end; +end; + +procedure tpostscriptcanvas.ps_copyarea; +var + mono: boolean; + cached: boolean; + varname: string; + + function imagedict: string; + begin + with fdrawinfo.copyarea.sourcerect^ do begin + result:= setcolorstring(fdrawinfo.acolorforeground)+nl+ + ' << /ImageType 1 /Width '+inttostr(size.cx)+ + ' /Height '+inttostr(size.cy)+' /ImageMatrix '+imagematrixstring(size)+nl; + if cached then begin + result:= result + '/DataSource '+varname+nl; + end + else begin + result:= result + '/DataSource {currentfile picstr readhexstring pop}'+nl; + end; + result:= result + '/BitsPerComponent '; + end; + if mono{image.monochrome} then begin + result:= result+'1 '; + end + else begin + result:= result+'8 '; + end; + result:= result+'/Decode '; + if mono{image.monochrome} then begin + result:= result + '[1 0] '; + end + else begin + if colorspace = cos_gray then begin + result:= result + '[0 1] '; + end + else begin + result:= result + '[0 1 0 1 0 1] '; + end; + end; + if al_intpol in fdrawinfo.copyarea.alignment then begin + result:= result + '/Interpolate true '; + end; + result:= result + '>>'+nl; + end; + +var + ar1,ar2,ar3: bytearty; + str1: string; +// components: integer; + rowbytes,maskrowbytes: integer; + masked: boolean; + maskcopy: boolean; + maskbefore: tsimplebitmap; + po1,po2,po3: pbyte; + int1: integer; + image: imagety; +label + endlab; +begin + with fdrawinfo,copyarea do begin + if not (df_canvasispixmap in tcanvas1(source).fdrawinfo.gc.drawingflags) then begin + exit; + end; + mono:= source.kind = bmk_mono; + subpoint1(destrect^.pos,origin); //map to pd origin + maskcopy:= mono and (mask <> nil) and (mask.kind = bmk_mono) and + ((acolorforeground = cl_transparent) or + (acolorbackground = cl_transparent)); + maskbefore:= mask; //compiler warning + if maskcopy then begin + mask:= tsimplebitmap.create(bmk_mono{true}); + mask.size:= sourcerect^.size; + mask.canvas.copyarea(maskbefore.canvas,sourcerect^,nullpoint); + if acolorbackground = cl_transparent then begin + mask.canvas.copyarea(source,sourcerect^,nullpoint,rop_and); + end; + if acolorforeground = cl_transparent then begin + mask.canvas.copyarea(source,sourcerect^,nullpoint,rop_notand); + end; + end; + try + checkcolorspace; + masked:= (mask <> nil) and ((mask.kind = bmk_mono) {or (fpslevel >= psl_3)}); + //color masks not implemented in postscript + if masked then begin + if (fpslevel >= psl_3) then begin + cached:= not maskcopy and getimagecache(ick_4,source,sourcerect^,varname); + if not cached then begin + with tcanvas1(source).fdrawinfo do begin + gdi_lock; + if gui_pixmaptoimage(tsimplebitmap1(mask).handle,image, + mask.canvas.gchandle) <> gde_ok then begin + goto endlab; + end; + gdi_unlock; + if mask.kind = bmk_mono then begin + convertmono(sourcerect^,image,ar2,maskrowbytes); + end + else begin + if colorspace = cos_gray then begin + convertgray(sourcerect^,image,ar2,maskrowbytes); + end + else begin + convertrgb(sourcerect^,image,ar2,maskrowbytes); + end; + end; + gui_freeimagemem(image.pixels); + gdi_lock; + if gui_pixmaptoimage(paintdevice,image,gc.handle) <> gde_ok then begin + goto endlab; + end; + gdi_unlock; + end; + if mono{image.monochrome} then begin + if colorspace = cos_gray then begin + convertmonotogray(sourcerect^,image,ar3,rowbytes, + acolorforeground,acolorbackground); + end + else begin + convertmonotorgb(sourcerect^,image,ar3,rowbytes, + acolorforeground,acolorbackground); + end; + end + else begin + if colorspace = cos_gray then begin + convertgray(sourcerect^,image,ar3,rowbytes); + end + else begin + convertrgb(sourcerect^,image,ar3,rowbytes); + end; + end; + gui_freeimagemem(image.pixels); + setlength(ar1,length(ar2)+length(ar3)); + po1:= pointer(ar1); + po2:= pointer(ar2); + po3:= pointer(ar3); + for int1:= sourcerect^.cy - 1 downto 0 do begin + system.move(po2^,po1^,maskrowbytes); + inc(po1,maskrowbytes); + inc(po2,maskrowbytes); + system.move(po3^,po1^,rowbytes); + inc(po1,rowbytes); + inc(po3,rowbytes); + end; + rowbytes:= rowbytes + maskrowbytes; + cached:= not maskcopy and setimagecache(ick_4,source,sourcerect^,varname, + ar1,mask.canvas); + end; + mono:= false; //has been converted to color + str1:= 'gsave '; + if not cached then begin + str1:= str1 + '/picstr '+inttostr(rowbytes)+' string def '; + end; + str1:= str1 + rectscalestring(destrect^) + nl; + str1:= str1 + '/imdict '+imagedict+' def '; + with sourcerect^ do begin + str1:= str1 + '/madict << /ImageType 1 /Width '+inttostr(size.cx)+ + ' /Height '+inttostr(size.cy)+' /ImageMatrix '+imagematrixstring(size)+nl; + if mask.kind = bmk_mono then begin + str1:= str1 + '/BitsPerComponent 1 /Decode [1 0] '; + end + else begin + if colorspace = cos_gray then begin + str1:= str1 + '/BitsPerComponent 8 /Decode [0 1] '; + end + else begin + str1:= str1 + '/BitsPerComponent 1 /Decode [0 1 0 1 0 1] '; + end; + end; + end; + if al_intpol in alignment then begin + str1:= str1 + '/Interpolate true '; + end; + str1:= str1 + ' >> def'+nl+ + '<< /ImageType 3 /DataDict imdict /MaskDict madict /InterleaveType 2 >>'+nl; + str1:= str1 + 'image'; + end + else begin + cached:= not maskcopy and getimagecache(ick_2,mask.canvas,sourcerect^,varname); + gdi_lock; + if not (createpattern(sourcerect^,destrect^,acolorbackground,acolorforeground, + source,imagepatname) and + (cached or (gui_pixmaptoimage(tsimplebitmap1(mask).handle,image, + mask.canvas.gchandle) = gde_ok))) then begin + goto endlab; + end; + gdi_unlock; + if not cached then begin + convertmono(sourcerect^,image,ar1,rowbytes); + gui_freeimagemem(image.pixels); + cached:= not maskcopy and + setimagecache(ick_2,mask.canvas,sourcerect^,varname,ar1); + end; + str1:= 'gsave setpattern'; + if cached then begin + str1:= str1 + ' /bo1 0 def '; + end + else begin + str1:= str1 + ' /picstr ' + inttostr(rowbytes) + ' string def '; + end; + str1:= str1 + rectscalestring(destrect^) + nl; + str1:= str1 + inttostr(sourcerect^.size.cx) + ' ' + + inttostr(sourcerect^.size.cy); + str1:= str1 + ' true '; + str1:= str1 + imagematrixstring(sourcerect^.size)+nl; + if cached then begin + str1:= str1 + '{bo1 0 ne{()}{/b1 1 def '+varname+'}ifelse} '; + end + else begin + str1:= str1 + '{currentfile picstr readhexstring pop} '; + end; + str1:= str1 + 'imagemask' + nl; + streamwrite(str1); + if cached then begin + str1:= '/bo1 null def '; + end + else begin + writebinhex(ar1); + str1:= '/picstr null def ' + end; + str1:= str1+'/'+imagepatname+' null def grestore'+nl; + streamwrite(str1); + exit; + end; + end + else begin + cached:= getimagecache(ick_1,source,sourcerect^,varname{,rowbytes}); + if not cached then begin + with tcanvas1(source).fdrawinfo do begin + gdi_lock; + if gui_pixmaptoimage(paintdevice,image,gc.handle) <> gde_ok then begin + goto endlab; + end; + gdi_unlock; + end; +// components:= 1; + if mono{image.monochrome} then begin + convertmono(sourcerect^,image,ar1,rowbytes); + end + else begin + if colorspace = cos_gray then begin + convertgray(sourcerect^,image,ar1,rowbytes); + end + else begin +// components:= 3; + convertrgb(sourcerect^,image,ar1,rowbytes); + end; + end; + gui_freeimagemem(image.pixels); + cached:= setimagecache(ick_1,source,sourcerect^,varname, + ar1{,rowbytes}); + end; + str1:= 'gsave '; + if not cached then begin + str1:= str1 + '/picstr '+inttostr(rowbytes)+' string def '; + end; + str1:= str1 + rectscalestring(destrect^) + nl; + if mono{image.monochrome} then begin + if acolorbackground <> cl_transparent then begin + str1:= str1 + unityrectpath + nl + + setcolorstring(acolorbackground) + ' fill '; + end; + end; + if fpslevel >= psl_2 then begin + str1:= str1 + imagedict; + if mono{image.monochrome} then begin + str1:= str1 + 'imagemask'; + end + else begin + str1:= str1 + 'image'; + end; + end + else begin + if cached then begin + str1:= str1 + '/bo1 0 def '; + end; + str1:= str1 + setcolorstring(acolorforeground) + nl; + with sourcerect^ do begin + str1:= str1 + + inttostr(size.cx) + ' ' + inttostr(size.cy); + if mono{image.monochrome} then begin + str1:= str1 + ' true '; + end + else begin + str1:= str1 + ' 8'; + end; + str1:= str1 + imagematrixstring(size)+nl; + if cached then begin + str1:= str1 + '{bo1 0 ne{()}{/b1 1 def '+varname+'}ifelse} '; + end + else begin + str1:= str1 + '{currentfile picstr readhexstring pop} '; + end; + end; + if mono{image.monochrome} then begin + str1:= str1 + 'imagemask'; + end + else begin + if colorspace = cos_gray then begin + str1:= str1 + 'image'; + end + else begin + str1:= str1 + 'false 3 colorimage'; + end; + end; + if cached then begin + str1:= str1 + ' /bo1 null def'; + end; + end; + end; + streamwrite(str1+nl); + if cached then begin + str1:= ''; + end + else begin + writebinhex(ar1); + str1:= '/picstr null def '; + end; + str1:= str1 + 'grestore'; + if masked then begin + str1:= str1 + ' /imdict null def /madict null def '; + end; + streamwrite(str1+nl); + exit; +endlab: + gdi_unlock; + finally + addpoint1(destrect^.pos,origin); //map to origin + if maskcopy then begin + mask.free; + mask:= maskbefore; + end; + end; + end; +end; + +procedure tpostscriptcanvas.beginpage; +var + str1: string; +begin + initgcvalues; //init state on every page, necessary for gv + if active then begin + str1:= ' '+inttostr(fps_pagenumber+1); + streamwrite('%%Page:'+str1+str1+nl+ + '%%PageOrientation: '+pageorientations[printorientation]+nl); + streamwriteln('gsave'); + flandscape:= false; + fhaspage:= true; + checkscale; + end; + inherited; +end; + +procedure tpostscriptcanvas.endpage; +var + int1: integer; +begin + inherited; + if active then begin + for int1:= 0 to high(fimagecache) do begin + freeimagecache(int1); + end; + streamwriteln('grestore'); + streamwrite('showpage'+nl); + fhaspage:= false; + inc(fps_pagenumber); + end; +end; + +function tpostscriptcanvas.registermap(const acodepage: integer): string; + + procedure defpage(const glyphnames: string); + begin + streamwrite('/'+result+' ['+nl+glyphnames+'] def'+nl,true); + end; + +var + map1: unicodepagety; + str1: string; + int1,int2,int3: integer; +begin + result:= ''; + for map1:= low(unicodepagety) to high(unicodepagety) do begin + with encodings[map1] do begin + if codepage = acodepage then begin + result:= name; + defpage(encodings[map1].glyphnames); + break; + end; + end; + end; + if result = '' then begin + result:= 'E'+hextostr(longword(acodepage),2); + int3:= 256*acodepage; + str1:= ''; + for int1:= 0 to 31 do begin + for int2:= 0 to 7 do begin + str1:= str1 + '/uni'+hextostr(longword(int3),4)+' '; + inc(int3); + end; + if int1 = 31 then begin + setlength(str1,length(str1)-1); //remove last comma + end; + str1:= str1 + nl; + end; + defpage(str1); + end; +end; + +procedure tpostscriptcanvas.checkmap(const acodepage: integer); +begin + if fmapnames[acodepage] = '' then begin + fmapnames[acodepage]:= registermap(acodepage); + end; +end; + +procedure tpostscriptcanvas.updatescale; +begin + inherited; + checkscale; +end; + +procedure tpostscriptcanvas.pscommandbegin(); +begin + fdrawinfo.acolorforeground:= color; + fdrawinfo.acolorbackground:= colorbackground; + checkgcstate(changedmask); +end; + +procedure tpostscriptcanvas.pscommandwrite(const atext: string); +begin + streamwrite(atext); +end; + +procedure tpostscriptcanvas.pscommandend(); +begin + initgcvalues; +end; + +procedure tpostscriptcanvas.pscommand(const atext: string); +begin + pscommandbegin(); + pscommandwrite(atext); + pscommandend() +end; + +procedure tpostscriptcanvas.freeimagecache(const index: integer); +begin + with fimagecache[index] do begin + if source <> nil then begin + streamwrite('/'+'picstr'+inttostr(index)+' null def'+nl); + //delete dict entry + unregistergclink(source); + if mask <> nil then begin + unregistergclink(mask); + mask:= nil; + end; + source:= nil; + fimagecacheused:= fimagecacheused - bytecount; + end; + end; + removeitem(fcacheorder,index); +end; + +procedure tpostscriptcanvas.touchimagecache(const index: integer); +var + int1: integer; +begin + for int1:= high(fcacheorder) - 1 downto 0 do begin + if fcacheorder[int1] = index then begin + system.move(fcacheorder[int1+1],fcacheorder[int1], + (high(fcacheorder)-index)*sizeof(integer)); + fcacheorder[high(fcacheorder)]:= index; + end; + end; +end; + +procedure tpostscriptcanvas.gcdestroyed(const sender: tcanvas); +var + int1: integer; +begin + for int1:= 0 to high(fimagecache) do begin + with fimagecache[int1] do begin + if (source = sender) or (mask = sender) then begin + freeimagecache(int1); + break; + end; + end; + end; +end; + +function tpostscriptcanvas.getimagecache(const akind: imagecachekindty; + const asource: tcanvas; + const asourcerect: rectty; out varname: string{; + out arowbytes: integer}): boolean; +var + int1: integer; +begin + result:= false; + for int1:= 0 to high(fimagecache) do begin + with fimagecache[int1] do begin + if (kind = akind) and (source = asource) and + rectisequal(sourcerect,asourcerect) then begin + varname:= 'picstr'+inttostr(int1); + result:= (statestamp = asource.statestamp) and + ((mask = nil) or (maskstatestamp = mask.statestamp)); + if not result then begin + freeimagecache(int1); + end + else begin + touchimagecache(int1); + end; + end; + end; + end; +end; + +function tpostscriptcanvas.setimagecache(const akind: imagecachekindty; + const asource: tcanvas; + const asourcerect: rectty; out varname: string; + const bytes: bytearty; {const arowbytes: integer;} + const amask: tcanvas = nil): boolean; +var + int1,int2: integer; + str1: string; +begin + result:= (fimagecachemaxitemsize > 0) and (high(bytes) < fimagecachemaxitemsize); + if result then begin + int1:= fimagecachesize - length(bytes); + while (fimagecacheused > int1) do begin + freeimagecache(fcacheorder[0]); + end; + int2:= length(fimagecache); + for int1:= 0 to high(fimagecache) do begin + if fimagecache[int1].source = nil then begin + int2:= int1; + break; + end; + end; + if int2 = length(fimagecache) then begin + setlength(fimagecache,int2 + 1); + end; + varname:= 'picstr'+inttostr(int2); + additem(fcacheorder,int2); + with fimagecache[int2] do begin + kind:= akind; + source:= asource; + mask:= amask; + sourcerect:= asourcerect; + statestamp:= asource.statestamp; + bytecount:= length(bytes); +// rowbytes:= arowbytes; + fimagecacheused:= fimagecacheused + bytecount; + end; + if asource <> nil then begin + registergclink(asource); +// tcanvas1(asource).registergclink(self); + end; + if amask <> nil then begin + registergclink(amask); +// tcanvas1(amask).registergclink(self); + end; + str1:='/'+varname+' '+inttostr(length(bytes))+' string def currentfile '+ + varname + ' readhexstring'+nl; + streamwrite(str1); + writebinhex(bytes); + streamwrite('pop pop'+nl); + end; +end; + +procedure tpostscriptcanvas.setimagecachesize(const avalue: integer); +begin + fimagecachesize:= avalue; + if fimagecachemaxitemsize < avalue then begin + fimagecachemaxitemsize:= avalue; + end; +end; + +procedure tpostscriptcanvas.setimagecachemaxitemsize(const avalue: integer); +begin + fimagecachemaxitemsize:= avalue; + if fimagecachesize < avalue then begin + fimagecachesize:= avalue; + end; +end; + +{ tpostscriptprinter } + +constructor tpostscriptprinter.create(aowner: tcomponent); +begin + fcanvas:= tpostscriptcanvas.create(self,icanvas(self)); + inherited; + options:= [pro_tempfile]; +end; + +function tpostscriptprinter.getcanvas: tpostscriptcanvas; +begin + result:= tpostscriptcanvas(fcanvas); +end; + +procedure tpostscriptprinter.gcneeded(const sender: tcanvas); +var + gc1: gcty; +begin + if not (sender is tpostscriptcanvas) then begin + guierror(gue_invalidcanvas); + end; + with tpostscriptcanvas(sender) do begin + fillchar(gc1,sizeof(gc1),0); + gc1.kind:= bmk_rgb; + gc1.handle:= invalidgchandle; + gc1.drawingflags:= [df_highresfont]; + gc1.paintdevicesize:= getwindowsize; + linktopaintdevice(ptrint(self),gc1,{getwindowsize,}nullpoint); + end; +end; +{ +function tpostscriptprinter.getmonochrome: boolean; +begin + result:= false; +end; +} +function tpostscriptprinter.getkind: bitmapkindty; +begin + result:= bmk_rgb; +end; +procedure tpostscriptprinter.getcanvasimage(const bgr: boolean; + var aimage: maskedimagety); +begin + //dummy +end; + +initialization + gdifuncs:= gui_getgdifuncs; + gdifunctions:= gdifuncs^; //default + gdifunctions[gdf_destroygc]:= {$ifdef FPC}@{$endif}gdi_destroygc; + gdifunctions[gdf_changegc]:= {$ifdef FPC}@{$endif}gdi_changegc; + gdifunctions[gdf_drawlines]:= {$ifdef FPC}@{$endif}gdi_drawlines; + gdifunctions[gdf_drawlinesegments]:= {$ifdef FPC}@{$endif}gdi_drawlinesegments; + gdifunctions[gdf_drawellipse]:= {$ifdef FPC}@{$endif}gdi_drawellipse; + gdifunctions[gdf_drawarc]:= {$ifdef FPC}@{$endif}gdi_drawarc; + gdifunctions[gdf_fillrect]:= {$ifdef FPC}@{$endif}gdi_fillrect; + gdifunctions[gdf_fillellipse]:= {$ifdef FPC}@{$endif}gdi_fillellipse; + gdifunctions[gdf_fillarc]:= {$ifdef FPC}@{$endif}gdi_fillarc; + gdifunctions[gdf_fillpolygon]:= {$ifdef FPC}@{$endif}gdi_fillpolygon; + gdifunctions[gdf_drawstring16]:= {$ifdef FPC}@{$endif}gdi_drawstring16; + gdifunctions[gdf_setcliporigin]:= {$ifdef FPC}@{$endif}gdi_setcliporigin; + +// gdifunctions[gdf_createemptyregion]:= {$ifdef FPC}@{$endif}gdi_createemptyregion; +// gdifunctions[gdf_createrectregion]:= {$ifdef FPC}@{$endif}gdi_createrectregion; +// gdifunctions[gdf_createrectsregion]:= {$ifdef FPC}@{$endif}gdi_createrectsregion; +// gdifunctions[gdf_destroyregion]:= {$ifdef FPC}@{$endif}gdi_destroyregion; +// gdifunctions[gdf_copyregion]:= {$ifdef FPC}@{$endif}gdi_copyregion; +// gdifunctions[gdf_moveregion]:= {$ifdef FPC}@{$endif}gdi_moveregion; +// gdifunctions[gdf_regionisempty]:= {$ifdef FPC}@{$endif}gdi_regionisempty; +// gdifunctions[gdf_regionclipbox]:= {$ifdef FPC}@{$endif}gdi_regionclipbox; +// gdifunctions[gdf_regsubrect]:= {$ifdef FPC}@{$endif}gdi_regsubrect; +// gdifunctions[gdf_regsubregion]:= {$ifdef FPC}@{$endif}gdi_regsubregion; +// gdifunctions[gdf_regaddrect]:= {$ifdef FPC}@{$endif}gdi_regaddrect; +// gdifunctions[gdf_regaddregion]:= {$ifdef FPC}@{$endif}gdi_regaddregion; +// gdifunctions[gdf_regintersectrect]:= {$ifdef FPC}@{$endif}gdi_regintersectrect; +// gdifunctions[gdf_regintersectregion]:= {$ifdef FPC}@{$endif}gdi_regintersectregion; + + gdifunctions[gdf_copyarea]:= {$ifdef FPC}@{$endif}gdi_copyarea; + +// gdifunctions[gdf_fonthasglyph]:= {$ifdef FPC}@{$endif}gdi_fonthasglyph; +// gdifunctions[gdf_getfont]:= {$ifdef FPC}@{$endif}gdi_getfont; +// gdifunctions[gdf_getfonthighres]:= {$ifdef FPC}@{$endif}gdi_getfonthighres; +// gdifunctions[gdf_freefontdata]:= {$ifdef FPC}@{$endif}gdi_freefontdata; +// gdifunctions[gdf_gettext16width]:= {$ifdef FPC}@{$endif}gdi_gettext16width; +// gdifunctions[gdf_getchar16widths]:= {$ifdef FPC}@{$endif}gdi_getchar16widths; +// gdifunctions[gdf_gdi_getfontmetrics]:= {$ifdef FPC}@{$endif}gdi_getfontmetrics + + {$if high(gdifuncty) <> gdf_getfontmetrics} + {$error missing gdi function} + {$ifend} +end. diff --git a/mseide-msegui/lib/common/printer/mseprinter.pas b/mseide-msegui/lib/common/printer/mseprinter.pas new file mode 100644 index 0000000..e18f005 --- /dev/null +++ b/mseide-msegui/lib/common/printer/mseprinter.pas @@ -0,0 +1,2049 @@ +{ MSEgui Copyright (c) 1999-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseprinter; +{$ifdef FPC}{$mode objfpc}{$h+}{$GOTO ON}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + mseclasses,msegraphics,msegraphutils,msestrings,msestream,msedrawtext, + mserichstring,classes,mclasses,msetypes,msestat,msestatfile, + msedataedits,msedropdownlist, + mseevent,mseglob,mseguiglob,msemenus,mseedit,msegui,sysutils; + +const + defaultppmm = 10; + defaultpagewidth = 210; //A4 mm + defaultpageheight = 297; //A4 mm + defaultframe = 10; //mm + defaultfontheight = 3.527; //*ppmm -> 10 point + +// gcscale = 4096; + printunit = 25.4/72; //point + mmtoprintscale = 1/printunit; + nulllinewidth = 0.2*mmtoprintscale; + +type + stdpagesizety = (sps_user, + sps_a0,sps_a1,sps_a2,sps_a3,sps_a4,sps_a5,sps_a6,sps_a7,sps_a8,sps_a9, + sps_b0,sps_b1,sps_b2,sps_b3,sps_b4,sps_b5,sps_b6,sps_b7,sps_b8,sps_b9,sps_b10, + sps_c5e,sps_comm10e,sps_dle,sps_executive,sps_folio,sps_ledger,sps_legal, + sps_letter,sps_tabloid); + + stdpagety = record + name: string; + width,height: real //mm + end; + +const + stdpagesizes: array[stdpagesizety] of stdpagety = ( + (name: 'User'; width: 0; height: 0), + (name: 'A0'; width: 841; height: 1189), + (name: 'A1'; width: 594; height: 841), + (name: 'A2'; width: 420; height: 594), + (name: 'A3'; width: 297; height: 420), + (name: 'A4'; width: 210; height: 297), + (name: 'A5'; width: 148; height: 210), + (name: 'A6'; width: 105; height: 148), + (name: 'A7'; width: 74; height: 105), + (name: 'A8'; width: 52; height: 74), + (name: 'A9'; width: 37; height: 52), + (name: 'B0'; width: 1030; height: 1456), + (name: 'B1'; width: 728; height: 1030), + (name: 'B2'; width: 515; height: 728), + (name: 'B3'; width: 364; height: 515), + (name: 'B4'; width: 257; height: 364), + (name: 'B5'; width: 182; height: 257), + (name: 'B6'; width: 128; height: 182), + (name: 'B7'; width: 91; height: 128), + (name: 'B8'; width: 64; height: 91), + (name: 'B9'; width: 45; height: 64), + (name: 'B10'; width: 32; height: 45), + (name: 'C5E'; width: 163; height: 229), + (name: 'Comm10E'; width: 105; height: 241), + (name: 'DLE'; width: 110; height: 220), + (name: 'Executive'; width: 191; height: 254), + (name: 'Folio'; width: 210; height: 330), + (name: 'Ledger'; width: 432; height: 279), + (name: 'Legal'; width: 216; height: 356), + (name: 'Letter'; width: 216; height: 279), + (name: 'Tabloid'; width: 279; height: 432) + ); + +type + printeroptionty = (pro_inactivewindow,//win32: start exe with inactive window + pro_tempfile); //use temp file for prolog building + printeroptionsty = set of printeroptionty; +const + defaultprinteroptions = [pro_inactivewindow]; +type + tcustomprinter = class; + tcustomprintercanvas = class; + tprintercanvas = class; + printereventty = procedure(const sender: tcustomprinter) of object; + + tprintertabulators = class(tcustomtabulators) + published + property defaultdist; + end; + colorspacety = (cos_gray,cos_rgb); + pageorientationty = (pao_portrait,pao_landscape); + + exceptioneventty = procedure(const sender: tobject; var e: exception; + var again: boolean) of object; + + tcustomprinter = class(tmsecomponent,istatfile) + private + fonpagestart: printereventty; + fonpageend: printereventty; + fpa_size: stdpagesizety; + fpa_width: real; + fpa_height: real; + fpa_frameleft: real; + fpa_frametop: real; + fpa_frameright: real; + fpa_framebottom: real; + ftabulators: tprintertabulators; +// fppmm: real; + fstatfile: tstatfile; + fstatvarname: msestring; + fpa_orientation: pageorientationty; + foptions: printeroptionsty; + fonerror: exceptioneventty; + fstatpriority: integer; + procedure settabulators(const avalue: tprintertabulators); +// procedure setppmm(const avalue: real); + procedure setpa_frameleft(const avalue: real); + procedure setpa_frametop(const avalue: real); + procedure setpa_frameright(const avalue: real); + procedure setpa_framebottom(const avalue: real); + procedure writepa_frameleft(writer: twriter); + procedure writepa_frametop(writer: twriter); + procedure writepa_frameright(writer: twriter); + procedure writepa_framebottom(writer: twriter); + procedure readpa_frameleft(reader: treader); + procedure readpa_frametop(reader: treader); + procedure readpa_frameright(reader: treader); + procedure readpa_framebottom(reader: treader); +// function getcolorspace: colorspacety; +// procedure setcolorspace(const avalue: colorspacety); + procedure setstatfile(const avalue: tstatfile); + procedure setpa_size(const avalue: stdpagesizety); + procedure setpa_width(const avalue: real); + procedure setpa_height(const avalue: real); + procedure pagesizechanged; + procedure setpa_orientation(const avalue: pageorientationty); + procedure setcanvas(const avalue: tprintercanvas); + function getclientwidth: real; + function getclientheight: real; + protected + fcanvas: tprintercanvas; + fcanceled: boolean; + function handleexception(const e: exception; out again: boolean): boolean; + //true if raise wanted + procedure loaded; override; + function getwindowsize: sizety; virtual; + procedure defineproperties(filer: tfiler); override; + procedure readstate(reader: treader); override; + + //istatfile + procedure dostatread(const reader: tstatreader); virtual; + procedure dostatwrite(const writer: tstatwriter); virtual; + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + + property onerror: exceptioneventty read fonerror write fonerror; + //call abort for quiet cancel + + //icanvas + function getsize: sizety; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + + procedure beginprint(const adryrun: boolean = false); virtual; + procedure endprint; virtual; + property canvas: tprintercanvas read fcanvas write setcanvas; + property onpagestart: printereventty read fonpagestart write fonpagestart; + property onpageend: printereventty read fonpageend write fonpageend; + property pa_width: real read fpa_width write setpa_width; + property pa_height: real read fpa_height write setpa_height; + property pa_size: stdpagesizety read fpa_size write setpa_size nodefault; + property pa_orientation: pageorientationty read fpa_orientation + write setpa_orientation default pao_portrait; + + property pa_frameleft: real read fpa_frameleft + write setpa_frameleft stored false; //mm, default 10 + property pa_frametop: real read fpa_frametop + write setpa_frametop stored false; //mm, default 10 + property pa_frameright: real read fpa_frameright + write setpa_frameright stored false; //mm, default 10 + property pa_framebottom: real read fpa_framebottom + write setpa_framebottom stored false; //mm, default 10 + property clientwidth: real read getclientwidth; //mm + property clientheight: real read getclientheight; //mm + + property tabulators: tprintertabulators read ftabulators write settabulators; +// property ppmm: real read fppmm write setppmm; //pixel per mm, default 10 +// property colorspace: colorspacety read getcolorspace write setcolorspace; + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read fstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + property options: printeroptionsty read foptions write foptions + default defaultprinteroptions; + end; + + tprinter = class(tcustomprinter) + published + property canvas; + property onpagestart; + property onpageend; + property pa_width; + property pa_height; + property pa_size; + property pa_orientation; + + property pa_frameleft; //mm, default 10 + property pa_frametop; //mm, default 10 + property pa_frameright; //mm, default 10 + property pa_framebottom; //mm, default 10 + property tabulators; +// property ppmm: real read fppmm write setppmm; //pixel per mm, default 10 +// property colorspace: colorspacety read getcolorspace write setcolorspace; + property statfile; + property statvarname; + property statpriority; + end; + + tstreamprinter = class; +// updateprinteransistringeventty = procedure(const sender: tstreamprinter; +// var avalue: ansistring) of object; + updateprinterstringeventty = procedure(const sender: tstreamprinter; + var avalue: msestring) of object; + tstreamprinter = class(tprinter) + private + fprintcommand: msestring; + fonupdateprintcommand: updateprinterstringeventty; + procedure setstream(const avalue: ttextstream); + protected + procedure dostatread(const reader: tstatreader); override; + procedure dostatwrite(const writer: tstatwriter); override; + procedure doupdateprintcommand(const adata: pointer); + public + constructor create(aowner: tcomponent); override; + procedure beginprint(command: msestring = ''; + const apreamble: string = ''); overload; + procedure beginprint(const astream: ttextstream; + const apreamble: string = ''); overload; + //printer owns the stream, nil -> dummy mode + procedure endprint; override; + published + property printcommand: msestring read fprintcommand write fprintcommand; + property options; + property onerror; //call abort for quiet cancel + property onupdateprintcommand: updateprinterstringeventty + read fonupdateprintcommand write fonupdateprintcommand; + //runs in main thread + end; + + tprinterfont = class(tcanvasfont) + end; + + pageskindty = (pk_all,pk_even,pk_odd); + + pagerangety = record + first,last: integer; + end; + pagerangearty = array of pagerangety; + + printercanvasstatety = (pcs_matrixvalid,pcs_dryrun); + printercanvasstatesty = set of printercanvasstatety; + + tcustomprintercanvas = class(tcanvas) + private + fheaderheight: integer; + ffooterheight: integer; + fpagenumber: integer; + findentx: integer; + findenty: integer; + fprintorientation: pageorientationty; + fpagechanging: integer; + fpages: pagerangearty; + fpagesstring: msestring; + fpageskind: pageskindty; + procedure setcolorspace(const avalue: colorspacety); + function getliney: integer; + procedure setprintorientation(const avalue: pageorientationty); + procedure setliney(const avalue: integer); + procedure setpages(const avalue: pagerangearty); + protected + fpstate: printercanvasstatesty; + fgcoffsetx: real; + fgcoffsety: real; + fgcscale: real; + foriginx,foriginy: real; + fscale: real; + foffset: pointty; + fclientrect: rectty; + fpapersize: sizety; + fboundingbox: framety; + ftitle: msestring; + flinenumber: integer; + fpagelinenumber: integer; + fliney: integer; + fprinter: tcustomprinter; + fcolorspace: colorspacety; + fpreamble: string; + function createfont: tcanvasfont; override; + procedure initprinting(const apreamble: string = ''); + procedure checkgcstate(state: canvasstatesty); override; + function getfitrect: rectty; override; + procedure setppmm(avalue: real); override; + function defaultcliprect: rectty; override; + procedure updatescale; virtual; + procedure updateframe; + procedure beginpage; virtual; + procedure endpage; virtual; + procedure dotextout(const text: richstringty; const dest: rectty; + const flags: textflagsty; + const tabdist: real; afontcolorshadow: colorty); + procedure textout(const text: richstringty; const dest: rectty; + const flags: textflagsty; + const tabdist: real); virtual; abstract; + //tabdist < 0 -> lastx + procedure begintextclip(const arect: rectty); virtual; abstract; + procedure endtextclip; virtual; abstract; + procedure checknextpage; + procedure internalwriteln(const avalue: richstringty); + procedure setpagesstring(const avalue: msestring); + procedure internaldrawtext(var info); override; + //info = drawtextinfoty + public + constructor create(const user: tcustomprinter; + const intf: icanvas); reintroduce; + procedure initflags(const dest: tcanvas); override; + + // if cy of destrect = 0 and tf_ycentered in textflags -> place on baseline + procedure drawtext(var info: drawtextinfoty); overload; virtual; + procedure drawtext(const atext: richstringty; + const adest: rectty; aflags: textflagsty = []; + afont: tfont = nil; atabulators: ttabulators = nil); overload; + procedure drawtext(const atext: richstringty; + const adest,aclip: rectty; aflags: textflagsty = []; + afont: tfont = nil; atabulators: ttabulators = nil); overload; + procedure drawtext(const atext: msestring; + const adest: rectty; aflags: textflagsty = []; + afont: tfont = nil; atabulators: ttabulators = nil); overload; + procedure writeln(const avalue: msestring = ''); overload; + procedure writeln(const avalue: richstringty); overload; + procedure writelines(const alines: array of msestring); overload; + procedure writelines(const alines: msestringarty); overload; + procedure writelines(const alines: richstringarty); overload; + + property indentx: integer read findentx write findentx; + //pixels + property indenty: integer read findenty write findenty; + //pixels + property headerheight: integer read fheaderheight write fheaderheight; + //pixels + property footerheight: integer read ffooterheight write ffooterheight; + //pixels + property linenumber: integer read flinenumber; + property pagelinenumber: integer read fpagelinenumber; + function remaininglines: integer; + function liney1: integer; //no checknextpage call + property liney: integer read getliney write setliney; + function lineheight: integer; //pixels + + procedure nextpage; override; + function active: boolean; + //checks pages + + property title: msestring read ftitle write ftitle; + //used as print job lable + property clientrect: rectty read fclientrect; + property clientpos: pointty read fclientrect.pos; + property clientsize: sizety read fclientrect.size; + property clientleft: integer read fclientrect.x; + property clienttop: integer read fclientrect.y; + property clientwidth: integer read fclientrect.cx; + property clientheight: integer read fclientrect.cy; + property colorspace: colorspacety read fcolorspace + write setcolorspace default cos_gray; + property pagenumber: integer read fpagenumber; + property pageskind: pageskindty read fpageskind write fpageskind; + //null based + property pages: pagerangearty read fpages write setpages; + //all if nil, null based + property pagesstring: msestring read fpagesstring write setpagesstring; + //one based, example: '1-5,7,9,11-13', all if '' + + property printorientation: pageorientationty read fprintorientation + write setprintorientation default pao_portrait; + end; + + tprintercanvas = class(tcustomprintercanvas) + published + property font; + property printorientation; + property colorspace; + property title; + property ppmm; //default 10 + end; + + tstreamprintercanvas = class(tprintercanvas) + protected + fdeststream: ttextstream; + fpreamblestream: ttextstream; + fbodystream: ttextstream; + procedure streamwrite(const atext: string; const apreamble: boolean = false); + //checks fstream = nil + procedure streamwriteln(const atext: string; const apreamble: boolean = false); + //checks fstream = nil + public +// procedure reset; override; + end; + + tprintervalueselector = class(tcustomselector) + private + fprinter: tcustomprinter; + procedure setprinter(const avalue: tcustomprinter); + procedure printerchanged; virtual; abstract; + protected + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + public + constructor create(aowner: tcomponent); override; + published +{$ifdef mse_with_ifi} + property ifilink; +{$endif} + property dropdown; + property ondataentered; + property printer: tcustomprinter read fprinter write setprinter; + end; + + pagesizeeventty = procedure(const sender: tobject; + var avalue: stdpagesizety; var accept: boolean) of object; + + tpagesizeselector = class(tprintervalueselector) + private + fpagewidth: real; + fpageheight: real; + feditwidth: tcustomrealedit; + feditheight: tcustomrealedit; + fupdatesize: boolean; + function getvalue: stdpagesizety; + procedure setvalue(const avalue: stdpagesizety); + procedure printerchanged; override; + procedure setpagewidth(const avalue: real); + procedure setpageheight(const avalue: real); + function getonsetvalue: pagesizeeventty; + procedure setongetvalue(const avalue: pagesizeeventty); + procedure seteditwidth(const avalue: tcustomrealedit); + procedure seteditheight(const avalue: tcustomrealedit); + protected + procedure getdropdowninfo(var aenums: integerarty; + const names: tdropdowndatacols); override; + procedure dochange; override; + procedure checkpagedim; + procedure updateedits(); + procedure objevent(const sender: iobjectlink; + const event: objecteventty) override; + public + constructor create(aowner: tcomponent); override; + procedure updatesize(); + function pagesizename: msestring; + property pagewidth: real read fpagewidth write setpagewidth; + property pageheight: real read fpageheight write setpageheight; + published + property value: stdpagesizety read getvalue write setvalue default sps_a4; + property editwidth: tcustomrealedit read feditwidth + write seteditwidth; + //set optionsedit1 oe1_sendchangeeventbycheckvalue in editwidget + property editheight: tcustomrealedit read feditheight + write seteditheight; + //set optionsedit1 oe1_sendchangeeventbycheckvalue in editwidget + property onsetvalue: pagesizeeventty read getonsetvalue + write setongetvalue; + end; + + pageorientationeventty = procedure(const sender: tobject; + var avalue: pageorientationty; var accept: boolean) of object; + + tpageorientationselector = class(tprintervalueselector) + private + function getvalue: pageorientationty; + procedure setvalue(const avalue: pageorientationty); + procedure printerchanged; override; + function getonsetvalue: pageorientationeventty; + procedure setongetvalue(const avalue: pageorientationeventty); + protected + procedure getdropdowninfo(var aenums: integerarty; + const names: tdropdowndatacols); override; + procedure dochange; override; + public + constructor create(aowner: tcomponent); override; + published + property value: pageorientationty read getvalue + write setvalue default pao_portrait; + property onsetvalue: pageorientationeventty read getonsetvalue + write setongetvalue; + end; + +function stringtopages(const avalue: msestring): pagerangearty; + //one based, example: '1-5,7,9,11-13' +function checkstdpagesize(const awidth,aheight: flo64): stdpagesizety; + +implementation +uses + mseprocutils,msepipestream,msesysintf,msestockobjects,mseconsts,msesys, + mseformatstr; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tfont1 = class(tfont); + tcanvas1 = class(tcanvas); + +function checkstdpagesize(const awidth,aheight: flo64): stdpagesizety; +var + wi1,he1: currency; + pa1: stdpagesizety; +begin + wi1:= awidth; + he1:= aheight; + for pa1:= stdpagesizety(1) to high(stdpagesizety) do begin + with stdpagesizes[pa1] do begin + if (currency(width) = wi1) and (currency(height) = he1) then begin + result:= pa1; + exit; + end; + end; + end; + result:= sps_user; +end; + +function stringtopages(const avalue: msestring): pagerangearty; +var + ar1,ar2: msestringarty; + int1,int2: integer; + ar3: pagerangearty; +begin + ar1:= nil; //compiler warning + ar2:= nil; //compiler warning + if avalue = '' then begin + result:= nil; + end + else begin + try + ar1:= splitstring(avalue,widechar(',')); + setlength(ar3,length(avalue)); //max + int2:= 0; + for int1:= high(ar1) downto 0 do begin + ar2:= splitstring(ar1[int1],widechar('-')); + if high(ar2) = 1 then begin + ar3[int2].first:= strtoint(ar2[0]); + ar3[int2].last:= strtoint(ar2[1]); + end + else begin + if high(ar2) = 0 then begin + ar3[int2].first:= strtoint(ar2[0]); + ar3[int2].last:= ar3[int2].first; + end + else begin + raise exception.create(''); + end; + end; + with ar3[int2] do begin + if (first <= 0) or (last <= 0) or (last < first) then begin + raise exception.create(''); + end; + dec(first); + dec(last); + end; + inc(int2); + end; + except + raise exception.create(ansistring('Invalid pages: '''+avalue+'''.'+lineend+ + 'Example: ''1-5,7,9,11-13''')); + end; + setlength(ar3,int2); + result:= ar3; + end; +end; + +{ tprintertabulators } + +{ tcustomprinter } + +constructor tcustomprinter.create(aowner: tcomponent); +begin +// fppmm:= defaultppmm; + foptions:= defaultprinteroptions; + fpa_size:= sps_a4; + with stdpagesizes[fpa_size] do begin + fpa_width:= width; + fpa_height:= height; + end; + fpa_frameleft:= defaultframe; + fpa_frametop:= defaultframe; + fpa_frameright:= defaultframe; + fpa_framebottom:= defaultframe; + ftabulators:= tprintertabulators.create; + inherited; + fcanvas.ppmm:= defaultppmm; +end; + +destructor tcustomprinter.destroy; +begin + endprint; + fcanvas.free; + ftabulators.free; + inherited; +end; + +procedure tcustomprinter.loaded; +begin + inherited; + pagesizechanged; + fcanvas.updatescale; +end; + +function tcustomprinter.handleexception(const e: exception; + out again: boolean): boolean; +var + e1: exception; +begin + result:= true; + again:= false; + if canevent(tmethod(fonerror)) then begin + e1:= e; + fcanceled:= true; + application.lock; + try + fonerror(self,e1,again); + finally + application.unlock; + end; + result:= not again and (e1 = e); + if not result and not again and (e1 <> nil) then begin + raise e1; + end; + fcanceled:= result; + end; +end; + +function tcustomprinter.getwindowsize: sizety; +var + rea1: real; +begin + if pa_width > pa_height then begin //quadratic for landscape/portrait switching + rea1:= pa_width; + end + else begin + rea1:= pa_height; + end; + result.cx:= round(rea1*fcanvas.ppmm); + result.cy:= result.cx; +end; + +procedure tcustomprinter.settabulators(const avalue: tprintertabulators); +begin + ftabulators.assign(avalue); +end; + +procedure tcustomprinter.pagesizechanged; +begin + if fpa_size <> sps_user then begin + with stdpagesizes[fpa_size] do begin + if fpa_orientation = pao_portrait then begin + fpa_width:= width; + fpa_height:= height; + end + else begin + fpa_width:= height; + fpa_height:= width; + end; + end; + end + else begin + if fpa_orientation = pao_portrait then begin + fpa_size:= checkstdpagesize(fpa_width,fpa_height); + end + else begin + fpa_size:= checkstdpagesize(fpa_height,fpa_width); + end; + end; + if not (csloading in componentstate) then begin + sendchangeevent; + fcanvas.updateframe; + end; +end; + +procedure tcustomprinter.setpa_width(const avalue: real); +begin + fpa_width:= avalue; + fpa_size:= sps_user; + pagesizechanged; +end; + +procedure tcustomprinter.setpa_height(const avalue: real); +begin + fpa_height:= avalue; + fpa_size:= sps_user; + pagesizechanged; +end; + +procedure tcustomprinter.setpa_size(const avalue: stdpagesizety); +begin + fpa_size:= avalue; + pagesizechanged; +end; + +procedure tcustomprinter.setpa_orientation(const avalue: pageorientationty); +begin + fpa_orientation:= avalue; + pagesizechanged; +end; +{ +procedure tcustomprinter.setppmm(const avalue: real); +begin + fppmm:= avalue; + ftabulators.ppmm:= avalue; + fcanvas.updatescale; +end; +} +procedure tcustomprinter.setpa_frameleft(const avalue: real); +begin + fpa_frameleft:= avalue; + fcanvas.updateframe; +end; + +procedure tcustomprinter.setpa_frametop(const avalue: real); +begin + fpa_frametop:= avalue; + fcanvas.updateframe; +end; + +procedure tcustomprinter.setpa_frameright(const avalue: real); +begin + fpa_frameright:= avalue; + fcanvas.updateframe; +end; + +procedure tcustomprinter.setpa_framebottom(const avalue: real); +begin + fpa_framebottom:= avalue; + fcanvas.updateframe; +end; + +function tcustomprinter.getclientwidth: real; +begin + result:= fpa_width - fpa_frameleft - fpa_frameright; +end; + +function tcustomprinter.getclientheight: real; +begin + result:= fpa_height - fpa_frametop - fpa_framebottom; +end; + + +{ +function tcustomprinter.getcolorspace: colorspacety; +begin + result:= fcanvas.colorspace; +end; + +procedure tcustomprinter.setcolorspace(const avalue: colorspacety); +begin + fcanvas.colorspace:= avalue; +end; +} +procedure tcustomprinter.dostatread(const reader: tstatreader); +begin + with reader do begin + pa_width:= readreal('width',fpa_width); + pa_height:= readreal('height',fpa_height); + pa_size:= stdpagesizety(readinteger('size',ord(fpa_size),0, + ord(high(stdpagesizety)))); + pa_orientation:= pageorientationty(readinteger('orientation', + ord(fpa_orientation),0,ord(high(pageorientationty)))); + fpa_frameleft:= readreal('frameleft',fpa_frameleft); + fpa_frametop:= readreal('frametop',fpa_frametop); + fpa_frameright:= readreal('frameright',fpa_frameright); + fpa_framebottom:= readreal('framebottom',fpa_framebottom); + fcanvas.colorspace:= colorspacety(readinteger('colorspace', + ord(fcanvas.colorspace),0,ord(high(colorspacety)))); + end; +end; + +procedure tcustomprinter.dostatwrite(const writer: tstatwriter); +begin + with writer do begin + writereal('width',fpa_width); + writereal('height',fpa_height); + writeinteger('size',ord(fpa_size)); + writeinteger('orientation',ord(fpa_orientation)); + writereal('frameleft',fpa_frameleft); + writereal('frametop',fpa_frametop); + writereal('frameright',fpa_frameright); + writereal('framebottom',fpa_framebottom); + writeinteger('colorspace',ord(fcanvas.colorspace)); + end; +end; + +procedure tcustomprinter.statreading; +begin + //dummy +end; + +procedure tcustomprinter.statread; +begin + //dummy +end; + +function tcustomprinter.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +procedure tcustomprinter.setstatfile(const avalue: tstatfile); +begin + setstatfilevar(istatfile(self),avalue,fstatfile); +end; + +procedure tcustomprinter.setcanvas(const avalue: tprintercanvas); +begin + fcanvas.assign(avalue); +end; + +function tcustomprinter.getsize: sizety; +begin + result:= fcanvas.fdrawinfo.gc.paintdevicesize; +end; + +procedure tcustomprinter.beginprint(const adryrun: boolean = false); +begin + //dummy +end; + +procedure tcustomprinter.endprint; +begin + //dummy +end; + +procedure tcustomprinter.writepa_frameleft(writer: twriter); +begin + writer.writefloat(fpa_frameleft); +end; + +procedure tcustomprinter.writepa_frametop(writer: twriter); +begin + writer.writefloat(fpa_frametop); +end; + +procedure tcustomprinter.writepa_frameright(writer: twriter); +begin + writer.writefloat(fpa_frameright); +end; + +procedure tcustomprinter.writepa_framebottom(writer: twriter); +begin + writer.writefloat(fpa_framebottom); +end; + +procedure tcustomprinter.readpa_frameleft(reader: treader); +begin + fpa_frameleft:= reader.readfloat; +end; + +procedure tcustomprinter.readpa_frametop(reader: treader); +begin + fpa_frametop:= reader.readfloat; +end; + +procedure tcustomprinter.readpa_frameright(reader: treader); +begin + fpa_frameright:= reader.readfloat; +end; + +procedure tcustomprinter.readpa_framebottom(reader: treader); +begin + fpa_framebottom:= reader.readfloat; +end; + +procedure tcustomprinter.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('pa_frameleft',{$ifdef FPC}@{$endif}readpa_frameleft, + {$ifdef FPC}@{$endif}writepa_frameleft, + (filer.ancestor = nil) and (fpa_frameleft <> defaultframe) or + (filer.ancestor <> nil) and + (tcustomprinter(filer.ancestor).fpa_frameleft <> fpa_frameleft)); + filer.defineproperty('pa_frametop',{$ifdef FPC}@{$endif}readpa_frametop, + {$ifdef FPC}@{$endif}writepa_frametop, + (filer.ancestor = nil) and (fpa_frametop <> defaultframe) or + (filer.ancestor <> nil) and + (tcustomprinter(filer.ancestor).fpa_frametop <> fpa_frametop)); + filer.defineproperty('pa_frameright',{$ifdef FPC}@{$endif}readpa_frameright, + {$ifdef FPC}@{$endif}writepa_frameright, + (filer.ancestor = nil) and (fpa_frameright <> defaultframe) or + (filer.ancestor <> nil) and + (tcustomprinter(filer.ancestor).fpa_frameright <> fpa_frameright)); + filer.defineproperty('pa_framebottom',{$ifdef FPC}@{$endif}readpa_framebottom, + {$ifdef FPC}@{$endif}writepa_framebottom, + (filer.ancestor = nil) and (fpa_framebottom <> defaultframe) or + (filer.ancestor <> nil) and + (tcustomprinter(filer.ancestor).fpa_framebottom <> fpa_framebottom)); +end; + +procedure tcustomprinter.readstate(reader: treader); +begin + fcanvas.beforeread; + try + inherited; + finally + fcanvas.afterread; + end; +end; + +function tcustomprinter.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +{ tcustomprintercanvas } + +constructor tcustomprintercanvas.create(const user: tcustomprinter; + const intf: icanvas); +begin + fprinter:= user; + inherited create(user,intf); + fstate:= fstate+[cs_highresdevice,cs_internaldrawtext]; +end; + +procedure tcustomprintercanvas.initflags(const dest: tcanvas); +begin + inherited; + include(tcanvas1(dest).fdrawinfo.gc.drawingflags,df_highresfont); +end; + +function tcustomprintercanvas.createfont: tcanvasfont; +begin + result:= tprinterfont.create(self); +end; + +procedure tcustomprintercanvas.initprinting(const apreamble: string = ''); +begin + fpreamble:= apreamble; + fpagenumber:= 0; + fpagelinenumber:= 0; + fliney:= 0; + reset; +end; + +function tcustomprintercanvas.defaultcliprect: rectty; +begin + result.pos:= nullpoint; + result.size:= fdrawinfo.gc.paintdevicesize; + with result do begin + if cx > cy then begin + //quadratic because of cliprectinit with later orientation switch + cy:= cx; + end + else begin + cx:= cy; + end; + end; +end; + +procedure tcustomprintercanvas.updatescale; +begin + if not (csloading in fprinter.componentstate) then begin + exclude(fstate,cs_origin); + exclude(fpstate,pcs_matrixvalid); + with fprinter do begin + fgcscale:= mmtoprintscale/ppmm; //map to printerunits + + if fprintorientation = pao_landscape then begin + fdrawinfo.gc.paintdevicesize.cx:= round(fpa_height * ppmm); + fdrawinfo.gc.paintdevicesize.cy:= round(fpa_width * ppmm); + fgcoffsetx:= mmtoprintscale * fpa_frameleft; + fgcoffsety:= - fpa_frametop*mmtoprintscale; + end + else begin + fdrawinfo.gc.paintdevicesize.cx:= round(fpa_width * ppmm); + fdrawinfo.gc.paintdevicesize.cy:= round(fpa_height * ppmm); + fgcoffsetx:= mmtoprintscale * fpa_frameleft; + fgcoffsety:= (fpa_height-fpa_frametop)*mmtoprintscale; + end; + + if fprintorientation = pao_landscape then begin + fpapersize.cx:= round((fdrawinfo.gc.paintdevicesize.cy/ppmm)*mmtoprintscale); + fpapersize.cy:= round((fdrawinfo.gc.paintdevicesize.cx/ppmm)*mmtoprintscale); + fboundingbox.left:= round(fpa_frametop*mmtoprintscale); + fboundingbox.bottom:= round(fpa_frameleft*mmtoprintscale); + fboundingbox.right:= round( + (fdrawinfo.gc.paintdevicesize.cy/ppmm-fpa_framebottom)*mmtoprintscale); + fboundingbox.top:= round( + (fdrawinfo.gc.paintdevicesize.cx/ppmm-fpa_frameright)*mmtoprintscale); + end + else begin + fpapersize.cx:= round((fdrawinfo.gc.paintdevicesize.cx/ppmm)*mmtoprintscale); + fpapersize.cy:= round((fdrawinfo.gc.paintdevicesize.cy/ppmm)*mmtoprintscale); + fboundingbox.left:= round(fpa_frameleft*mmtoprintscale); + fboundingbox.bottom:= round(fpa_framebottom*mmtoprintscale); + fboundingbox.right:= round( + (fdrawinfo.gc.paintdevicesize.cx/ppmm-fpa_frameright)*mmtoprintscale); + fboundingbox.top:= round( + (fdrawinfo.gc.paintdevicesize.cy/ppmm-fpa_frametop)*mmtoprintscale); + end; + fclientrect.x:= round(fpa_frameleft*ppmm); + fclientrect.y:= round(fpa_frametop*ppmm); + fclientrect.cx:= fdrawinfo.gc.paintdevicesize.cx - + round((fpa_frameleft+fpa_frameright)*ppmm); + fclientrect.cy:= fdrawinfo.gc.paintdevicesize.cy - round( + (fpa_frametop+fpa_framebottom)*ppmm); + end; + end; +end; + +procedure tcustomprintercanvas.checkgcstate(state: canvasstatesty); +begin + if not (cs_origin in fstate) then begin + foriginx:= fgcoffsetx + mmtoprintscale * (origin.x/ppmm); + foriginy:= fgcoffsety - mmtoprintscale * (origin.y/ppmm); + end; + inherited; +end; + +procedure tcustomprintercanvas.updateframe; +begin + updatescale; +end; + +procedure tcustomprintercanvas.beginpage; +begin + fpagelinenumber:= 0; + fliney:= 0; + with fprinter do begin + if canevent(tmethod(fonpagestart)) then begin + fonpagestart(fprinter); + end; + end; +end; + +procedure tcustomprintercanvas.endpage; +begin + checkgcstate([cs_gc]); //could be an empty page + with fprinter do begin + if canevent(tmethod(fonpageend)) then begin + fonpageend(fprinter); + end; + end; +end; + +//todo: full support of shadow_*/gloss_* + +procedure tcustomprintercanvas.dotextout(const text: richstringty; + const dest: rectty; const flags: textflagsty; + const tabdist: real; afontcolorshadow: colorty); +var + col1: colorty; +begin + if tf_grayed in flags then begin + afontcolorshadow:= cl_white; + end; + col1:= fdrawinfo.acolorforeground; + if afontcolorshadow <> cl_none then begin + fdrawinfo.acolorforeground:= afontcolorshadow; + checkgcstate([cs_acolorforeground]); + textout(text,moverect(dest,makepoint(1,1)),flags,tabdist); + if tf_grayed in flags then begin + fdrawinfo.acolorforeground:= cl_dkgray; + end + else begin + fdrawinfo.acolorforeground:= col1; + end; + checkgcstate([cs_acolorforeground]); + end; + textout(text,dest,flags,tabdist); + if tf_grayed in flags then begin + fdrawinfo.acolorforeground:= col1; + checkgcstate([cs_acolorforeground]); + end; +end; + +procedure tcustomprintercanvas.drawtext(var info: drawtextinfoty); +// colorbackground gap filling not supported. +var + acolorshadow: colorty; + tab1: tcustomtabulators; + ar1: richstringarty; + int1,int2,int3,int4,int5,int6: integer; + rea1: real; + curflags,flags1,flags2: textflagsty; + rstr1: richstringty; + layoutinfo: layoutinfoty; + rect1,rect2: rectty; + backup: msestring; + lihi: integer; +label + endlab; +begin + if cs_inactive in fstate then exit; + save; + layouttext(self,info,layoutinfo); + if pcs_dryrun in fpstate then begin + goto endlab; + end; + ar1:= nil; //compiler warning + with fdrawinfo do begin + afonthandle1:= tfont1(font).gethandle; + with {fvaluepo^.}font do begin + acolorforeground:= color; + if acolorforeground = cl_default then begin + acolorforeground:= cl_text; + end; + acolorbackground:= colorbackground; + if acolorbackground = cl_default then begin + acolorbackground:= cl_transparent; + end; + acolorshadow:= shadow_color; + end; + checkgcstate([cs_font,cs_acolorforeground,cs_acolorbackground]); + end; + with info do begin + if tf_clipi in flags then begin + begintextclip(dest); + end + else begin + if tf_clipo in flags then begin + begintextclip(clip); + end; + end; + backup:= text.text; + try + with layoutinfo do begin + curflags:= flags; + if (tf_ycentered in curflags) and (curflags*[tf_top,tf_bottom] <> []) and + (not xyswapped and (info.res.cy > dest.cy) or + xyswapped and (info.res.cx > dest.cx))then begin + exclude(curflags,tf_ycentered); + end; + if tf_softhyphen in flags then begin + for int1:= 0 to high(lineinfos) do begin + with lineinfos[int1] do begin + for int2:= 0 to high(tabchars) do begin + if text.text[tabchars[int2].index] = c_softhyphen then begin + text.text[tabchars[int2].index]:= #0; //will be removed in printing routine + end; + end; + end; + end; + end; + text.text:= replacechar(text.text,c_softhyphen,'-'); + if high(lineinfos) > 0 then begin + rect1:= dest; +// flags1:= curflags; + flags2:= curflags - [tf_xcentered,tf_right,tf_xjustify]; + lihi:= font.lineheight; + int1:= 0; +// int2:= lihi; + if reversed then begin + lihi:= - lihi; + int1:= lihi; +// int2:= 0; + end; + if xyswapped then begin + rect1.cx:= font.lineheight; + if tf_ycentered in curflags then begin + rect1.x:= dest.x + (dest.cx - length(lineinfos) * lihi) div 2 + int1; + end + else begin + if tf_bottom in curflags then begin + if reversed then begin + rect1.x:= dest.x - high(lineinfos) * lihi; + end + else begin + rect1.x:= dest.x + dest.cx - length(lineinfos) * lihi; + end; + end; + end; + end + else begin + rect1.cy:= font.lineheight; + if tf_ycentered in curflags then begin + rect1.y:= dest.y + (dest.cy - length(lineinfos) * lihi) div 2 + int1; + end + else begin + if tf_bottom in curflags then begin + if reversed then begin + rect1.y:= dest.y - high(lineinfos) * lihi; + end + else begin + rect1.y:= dest.y + dest.cy - length(lineinfos) * lihi; + end; + end; + end; + end; + for int1:= 0 to high(lineinfos) do begin + with lineinfos[int1] do begin + if (tf_xjustify in curflags) and (high(justifychars) >= 0) and + ((int1 < high(lineinfos)) or + (tf_wordbreak in curflags) and (int1 = high(lineinfos))) then begin + rstr1:= richcopy(text,liindex,justifychars[0].index-liindex); + dotextout(rstr1,rect1,flags2,0,acolorshadow); //first word + rea1:= (dest.cx - liwidth + getstringwidth(' ') * + length(justifychars)) / + length(justifychars); //gap width + rect2:= rect1; //x justify text + if xyswapped then begin + rect2.cy:= 0; + int3:= dest.y; + end + else begin + rect2.cx:= 0; + int3:= dest.x; + end; + for int2:= liindex - 1 to justifychars[0].index - 2 do begin + inc(int3,charwidths[int2]); //end of first word + end; + for int2:= 0 to high(justifychars) - 1 do begin + int5:= 0; + for int4:= justifychars[int2].index to justifychars[int2+1].index - 2 do begin + inc(int5,charwidths[int4]); //width of actual word + end; + int6:= round(int3 + (int2 + 1) * rea1 + int5 div 2); + if xyswapped then begin + rect2.y:= int6; + end + else begin + rect2.x:= int6; + end; + int3:= int3 + int5; + rstr1:= richcopy(text,justifychars[int2].index+1, + justifychars[int2+1].index - justifychars[int2].index - 1); + dotextout(rstr1,rect2,flags2 + [tf_xcentered],0,acolorshadow); + end; + rstr1:= richcopy(text,justifychars[high(justifychars)].index+1, + liindex+licount-justifychars[high(justifychars)].index-1); + dotextout(rstr1,rect1,flags2+[tf_right],0,acolorshadow); //last word + end + else begin + rstr1:= richcopy(text,liindex,licount); + flags1:= curflags; + if (tf_xcentered in flags1) and + (curflags*[tf_left,tf_right] <> []) and + (liwidth > dest.cx) then begin + exclude(flags1,tf_xcentered); + end; + dotextout(rstr1,rect1,flags1,0,acolorshadow); + end; + if xyswapped then begin + inc(rect1.x,lihi); + end + else begin + inc(rect1.y,lihi); + end; + end; + end; + end + else begin //single line + if countchars(text.text,c_tab) = 0 then begin + flags1:= curflags; + if (tf_xcentered in flags1) and (curflags*[tf_left,tf_right] <> []) and + (not xyswapped and (info.res.cx > dest.cx) or + xyswapped and (info.res.cy > dest.cy))then begin + exclude(flags1,tf_xcentered); + end; + dotextout(text,dest,flags1,0,acolorshadow); + end + else begin + if tabulators = nil then begin + tab1:= fprinter.ftabulators; + end + else begin + tab1:= tabulators; + end; + if tab1.count = 0 then begin + if tab1.defaultdist = 0 then begin //has no tabs + replacechar(text.text,c_tab,' '); + dotextout(text,dest,curflags,0,acolorshadow); + end + else begin + ar1:= splitrichstring(text,c_tab); + dotextout(ar1[0],dest,curflags,0,acolorshadow); + rea1:= tab1.defaultdist*mmtoprintscale; + for int1:= 1 to high(ar1) do begin + dotextout(ar1[int1],dest,curflags,rea1,acolorshadow); + end; + end; + end + else begin + ar1:= splitrichstring(text,c_tab); + dotextout(ar1[0],dest,curflags,0,acolorshadow); + for int1:= 1 to high(ar1) do begin + if int1 > tab1.count then begin + rstr1.text:= ' '; + rstr1.format:= nil; + rstr1:= richconcat(rstr1,ar1[int1]); + for int2:= int1+1 to high(ar1) do begin + rstr1:= richconcat(rstr1,' '); + rstr1:= richconcat(rstr1,ar1[int2]); + end; + dotextout(rstr1,dest,curflags-[tf_right,tf_xcentered],-1,acolorshadow); + //print rest of string + break; + end; + flags1:= curflags - [tf_xcentered,tf_right]; + with tab1[int1-1] do begin + case kind of + tak_right,tak_decimal: flags1:= flags1 + [tf_right]; + tak_centered: flags1:= flags1 + [tf_xcentered]; + end; + if kind = tak_decimal then begin + int2:= msestrrscan(ar1[int1].text, + defaultformatsettingsmse.decimalseparator); + if int2 > 0 then begin + dotextout(richcopy(ar1[int1],1,int2-1), + makerect(round(pos*ppmm),dest.y,0, + dest.cy),flags1,0,acolorshadow); //int + dotextout(richcopy(ar1[int1],int2,bigint),makerect(0,dest.y,0, + dest.cy),flags1-[tf_right],-1,acolorshadow); //frac + end + else begin + dotextout(ar1[int1],makerect(round(pos*ppmm),dest.y,0, + dest.cy),flags1,0,acolorshadow); //no frac + end; + end + else begin + dotextout(ar1[int1],makerect(round(pos*ppmm),dest.y,0,dest.cy),flags1, + 0,acolorshadow); + end; + end; + end; + end; + end; + end; + end; //with layoutinfo + finally + text.text:= backup; + if flags * [tf_clipi,tf_clipo] <> [] then begin + endtextclip; + end; + end; + end; +endlab: + restore; +end; + +procedure tcustomprintercanvas.drawtext(const atext: richstringty; + const adest: rectty; aflags: textflagsty = []; + afont: tfont = nil; atabulators: ttabulators = nil); +var + info: drawtextinfoty; +begin + fillchar(info,sizeof(info),0); + with info do begin + text:= atext; + dest:= adest; + flags:= aflags; + font:= afont; + tabulators:= atabulators; + end; + drawtext(info); +end; + +procedure tcustomprintercanvas.drawtext(const atext: richstringty; + const adest,aclip: rectty; aflags: textflagsty = []; + afont: tfont = nil; atabulators: ttabulators = nil); +var + info: drawtextinfoty; +begin + fillchar(info,sizeof(info),0); + with info do begin + text:= atext; + dest:= adest; + clip:= aclip; + flags:= aflags; + font:= afont; + tabulators:= atabulators; + end; + drawtext(info); +end; + +procedure tcustomprintercanvas.drawtext(const atext: msestring; + const adest: rectty; aflags: textflagsty = []; + afont: tfont = nil; atabulators: ttabulators = nil); +var + info: drawtextinfoty; +begin + fillchar(info,sizeof(info),0); + with info do begin + text.text:= atext; + dest:= adest; + flags:= aflags; + font:= afont; + tabulators:= atabulators; + end; + drawtext(info); +end; + +procedure tcustomprintercanvas.checknextpage; +begin + if fpagechanging = 0 then begin + if remaininglines <= 0 then begin + inc(fpagechanging); + try + nextpage; + finally + dec(fpagechanging); + end; + end; + end; +end; + +procedure tcustomprintercanvas.writeln(const avalue: msestring = ''); +var + rstr1: richstringty; +begin + rstr1.format:= nil; + rstr1.text:= avalue; + writeln(rstr1); +end; + +procedure tcustomprintercanvas.internalwriteln(const avalue: richstringty); +begin + checknextpage; + if avalue.text <> '' then begin + drawtext(avalue,makerect(findentx,fliney + fheaderheight + findenty,0,0)); + end; + inc(fpagelinenumber); + inc(flinenumber); + fliney:= fliney + lineheight; +end; + +procedure tcustomprintercanvas.writeln(const avalue: richstringty); +var + ar1: richstringarty; + int1: integer; +begin + ar1:= breakrichlines(avalue); + for int1:= 0 to high(ar1) do begin + internalwriteln(ar1[int1]); + end; +end; + +procedure tcustomprintercanvas.writelines(const alines: array of msestring); +var + int1: integer; + rstr1: richstringty; +begin + rstr1.format:= nil; + for int1:= 0 to high(alines) do begin + rstr1.text:= alines[int1]; + internalwriteln(rstr1); + end; +end; + +procedure tcustomprintercanvas.writelines(const alines: msestringarty); +var + int1: integer; + rstr1: richstringty; +begin + rstr1.format:= nil; + for int1:= 0 to high(alines) do begin + rstr1.text:= alines[int1]; + internalwriteln(rstr1); + end; +end; + +procedure tcustomprintercanvas.writelines(const alines: richstringarty); +var + int1: integer; +begin + for int1:= 0 to high(alines) do begin + internalwriteln(alines[int1]); + end; +end; + +function tcustomprintercanvas.lineheight: integer; +begin + result:= font.height; + if result = 0 then begin + result:= round(defaultfontheight*ppmm); + end; + result:= result + font.extraspace; +end; + +function tcustomprintercanvas.remaininglines: integer; +begin + checkgcstate([cs_gc]); //init all values + result:= (fclientrect.cy - fheaderheight - ffooterheight - fliney - findenty - + origin.y) div lineheight; +end; + +procedure tcustomprintercanvas.nextpage; +begin + endpage; + inc(fpagenumber); + beginpage; +end; + +procedure tcustomprintercanvas.setcolorspace(const avalue: colorspacety); +begin + if fcolorspace <> avalue then begin + fcolorspace:= avalue; + exclude(fstate,cs_acolorforeground); +// valueschanged([cs_color,cs_colorbackground]); + end; +end; + +function tcustomprintercanvas.active: boolean; +var + int1: integer; +begin + result:= fpages = nil; + if not result then begin + for int1:= high(fpages) downto 0 do begin + with fpages[int1] do begin + if (fpagenumber >= first) and (fpagenumber <= last) then begin + result:= true; + break; + end; + end; + end; + end; + if result then begin + result:= (fpageskind = pk_all) or ((fpageskind = pk_even) xor odd(fpagenumber)); + end; +end; + +function tcustomprintercanvas.liney1: integer; +begin + result:= fliney + fheaderheight; +end; + +function tcustomprintercanvas.getliney: integer; +begin + checknextpage; + result:= liney1; +end; + +procedure tcustomprintercanvas.setliney(const avalue: integer); +begin + checknextpage; + fliney:= avalue - fheaderheight; +end; + +procedure tcustomprintercanvas.setprintorientation( + const avalue: pageorientationty); +begin + if avalue <> fprintorientation then begin + fprintorientation:= avalue; + updatescale; + end; +end; + +procedure tcustomprintercanvas.setppmm(avalue: real); +begin + inherited; + fprinter.ftabulators.ppmm:= avalue; + updatescale; +end; + +procedure tcustomprintercanvas.setpages(const avalue: pagerangearty); +begin + fpages:= copy(avalue); +end; + +procedure tcustomprintercanvas.setpagesstring(const avalue: msestring); +begin + pages:= stringtopages(avalue); + fpagesstring:= avalue; +end; + +procedure tcustomprintercanvas.internaldrawtext(var info); +begin + drawtext(drawtextinfoty(info)); +end; + +function tcustomprintercanvas.getfitrect: rectty; +begin + result:= fclientrect; +end; + +{ tprintervalueselector } + +constructor tprintervalueselector.create(aowner: tcomponent); +begin + inherited; + dropdown.cols.nostreaming:= true; +end; + +procedure tprintervalueselector.setprinter(const avalue: tcustomprinter); +begin + setlinkedvar(avalue,tmsecomponent(fprinter)); + printerchanged; +end; + +procedure tprintervalueselector.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (event = oe_changed) and (sender = fprinter) then begin + printerchanged; + end; +end; + +{ tpagesizeselector } + +constructor tpagesizeselector.create(aowner: tcomponent); +var + pa1: stdpagesizety; +begin + inherited; + dropdown.cols.beginupdate(); + for pa1:= low(stdpagesizety) to high(stdpagesizety) do begin + addrow([msestring(stdpagesizes[pa1].name)]); + end; + dropdown.cols.endupdate(); + inherited value:= integer(sps_a4); +end; + +procedure tpagesizeselector.getdropdowninfo(var aenums: integerarty; + const names: tdropdowndatacols); +var + pa1: stdpagesizety; +begin + setlength(aenums,ord(high(stdpagesizety))); + names.clear; + for pa1:= stdpagesizety(1) to high(stdpagesizety) do begin + with stdpagesizes[pa1] do begin + names.addrow([msestring(name+' ('+formatfloat('0',width)+'*'+ + formatfloat('0',height)+' mm2)')]); + end; + aenums[ord(pa1)-1]:= ord(pa1); + end; +end; + +procedure tpagesizeselector.dochange; +begin + if fprinter <> nil then begin + fprinter.pa_size:= value; + end; + if value <> sps_user then begin + with stdpagesizes[value] do begin + fpagewidth:= width; + fpageheight:= height; + end; + updateedits(); + end; + inherited; +end; + +function tpagesizeselector.getvalue: stdpagesizety; +begin + result:= stdpagesizety(inherited value); +end; + +procedure tpagesizeselector.setvalue(const avalue: stdpagesizety); +begin + if value <> avalue then begin + inherited setvalue(integer(avalue)); + end; +end; + +procedure tpagesizeselector.printerchanged; +begin + if fprinter <> nil then begin + value:= fprinter.pa_size; + end; +end; + +function tpagesizeselector.pagesizename: msestring; +begin + result:= msestring(stdpagesizes[value].name); +end; + +procedure tpagesizeselector.setpagewidth(const avalue: real); +begin + if fpagewidth <> avalue then begin + fpagewidth:= avalue; + checkpagedim; + end; +end; + +procedure tpagesizeselector.setpageheight(const avalue: real); +begin + if fpageheight <> avalue then begin + fpageheight:= avalue; + checkpagedim; + end; +end; + +procedure tpagesizeselector.checkpagedim; +begin + updateedits(); + value:= checkstdpagesize(fpagewidth,fpageheight); + +end; + +procedure tpagesizeselector.updateedits(); +begin + if (componentstate * [csloading,csdestroying] = []) and + not fupdatesize then begin + fupdatesize:= true; + try + if (feditwidth <> nil) and not + (csdestroying in feditwidth.componentstate) then begin + feditwidth.value:= fpagewidth; + end; + if (feditheight <> nil) and not + (csdestroying in feditheight.componentstate) then begin + feditheight.value:= fpageheight; + end; + finally + fupdatesize:= false; + end; + end; +end; + +procedure tpagesizeselector.updatesize(); +begin + if not fupdatesize then begin + fupdatesize:= true; + try + if (feditwidth <> nil) and (feditwidth.value <> emptyreal) then begin + pagewidth:= feditwidth.value; + end; + if (feditheight <> nil) and (feditheight.value <> emptyreal) then begin + pageheight:= feditheight.value; + end; + finally + fupdatesize:= false; + end; + end; +end; + +procedure tpagesizeselector.objevent(const sender: iobjectlink; + const event: objecteventty); +var + inst1: tobject; +begin + inherited; + if (event = oe_changed) then begin + inst1:= sender.getinstance(); + if (inst1 <> nil) and + ((inst1 = feditwidth) or (inst1 = feditheight)) then begin + updatesize(); + end; + end; +end; + +function tpagesizeselector.getonsetvalue: pagesizeeventty; +begin + result:= pagesizeeventty(fonsetvalue1); +end; + +procedure tpagesizeselector.setongetvalue(const avalue: pagesizeeventty); +begin + pagesizeeventty(fonsetvalue1):= avalue; +end; + +procedure tpagesizeselector.seteditwidth(const avalue: tcustomrealedit); +begin + if avalue <> feditwidth then begin + setlinkedvar(avalue,tmsecomponent(feditwidth)); + updateedits(); + end; +end; + +procedure tpagesizeselector.seteditheight(const avalue: tcustomrealedit); +begin + if avalue <> feditheight then begin + setlinkedvar(avalue,tmsecomponent(feditheight)); + updateedits(); + end; +end; + +{ tpageorientationselector } + +constructor tpageorientationselector.create(aowner: tcomponent); +begin + inherited; + addrow([stockcaptions(sc_portrait)]); + addrow([stockcaptions(sc_landscape)]); +end; + +function tpageorientationselector.getvalue: pageorientationty; +begin + result:= pageorientationty(inherited value); +end; + +procedure tpageorientationselector.setvalue(const avalue: pageorientationty); +begin + if value <> avalue then begin + inherited setvalue(integer(avalue)); + end; +end; + +procedure tpageorientationselector.printerchanged; +begin + if fprinter <> nil then begin + value:= fprinter.pa_orientation; + end; +end; + +procedure tpageorientationselector.getdropdowninfo(var aenums: integerarty; + const names: tdropdowndatacols); +begin + names.clear; + names.addrow([stockcaptions(sc_portrait)]); + names.addrow([stockcaptions(sc_landscape)]); +end; + +procedure tpageorientationselector.dochange; +begin + if fprinter <> nil then begin + fprinter.pa_orientation:= value; + end; + inherited; +end; + +function tpageorientationselector.getonsetvalue: pageorientationeventty; +begin + result:= pageorientationeventty(fonsetvalue1); +end; + +procedure tpageorientationselector.setongetvalue(const avalue: pageorientationeventty); +begin + pageorientationeventty(fonsetvalue1):= avalue; +end; + +{ tstreamprinter } + +constructor tstreamprinter.create(aowner: tcomponent); +begin +// fprintcommand:= sys_getprintcommand; + inherited; +end; + +procedure tstreamprinter.doupdateprintcommand(const adata: pointer); +begin + if canevent(tmethod(fonupdateprintcommand)) then begin + fonupdateprintcommand(self,pmsestring(adata)^); + end; +end; + +procedure tstreamprinter.beginprint(command: msestring = ''; + const apreamble: string = ''); +var + pip1: tpipewriter; + opt1: execoptionsty; +begin + if command = '' then begin + command:= fprintcommand; + end; + if command = '' then begin + command:= msestring(sys_getprintcommand()); + end; + if canevent(tmethod(fonupdateprintcommand)) then begin + application.synchronize({$ifdef FPC}@{$endif}doupdateprintcommand,@command); + end; + pip1:= tpipewriter.create; + try + opt1:= []; + if pro_inactivewindow in foptions then begin + include(opt1,exo_inactive); + end; + execmse2(command,pip1,nil,nil,{false,}-1,opt1 + {pro_inactivewindow in foptions}); + except + pip1.free; + raise; + end; + beginprint(pip1,apreamble); +end; + +procedure tstreamprinter.beginprint(const astream: ttextstream; + const apreamble: string = ''); +begin + with tstreamprintercanvas(fcanvas) do begin + if astream = nil then begin + include(fpstate,pcs_dryrun); + end + else begin + exclude(fpstate,pcs_dryrun); + end; + endprint; + setstream(astream); + initprinting(apreamble); + end; +end; + +procedure tstreamprinter.endprint; +begin + try + setstream(nil); + finally + fcanceled:= false; + end; +end; + +procedure tstreamprinter.setstream(const avalue: ttextstream); +var + fna1: filenamety; +begin + with tstreamprintercanvas(fcanvas) do begin + try + unlink; + except + end; + try + if (fdeststream <> fpreamblestream) and (fpreamblestream <> nil) then begin + fna1:= fpreamblestream.filename; + fpreamblestream.position:= 0; + fdeststream.copyfrom(fpreamblestream,0); + freeandnil(fpreamblestream); + sys_deletefile(fna1); + end; + if (fdeststream <> fbodystream) and (fbodystream <> nil) then begin + fna1:= fbodystream.filename; + fbodystream.position:= 0; + fdeststream.copyfrom(fbodystream,0); + freeandnil(fbodystream); + sys_deletefile(fna1); + end; + freeandnil(fdeststream); + fdeststream:= avalue; + if (pro_tempfile in foptions) and (avalue <> nil) then begin + fpreamblestream:= ttextstream.createtempfile('msepspreamble',fna1); + fbodystream:= ttextstream.createtempfile('msepsbody',fna1); + fpreamblestream.usewritebuffer:= true; + fbodystream.usewritebuffer:= true; + end + else begin + if avalue <> nil then begin + avalue.usewritebuffer:= true; + end; + fpreamblestream:= avalue; + fbodystream:= avalue; + end; + except + if fdeststream <> fpreamblestream then begin + freeandnil(fpreamblestream); + freeandnil(fbodystream); + end; + freeandnil(fdeststream); + raise; + end; + end; +end; + +procedure tstreamprinter.dostatread(const reader: tstatreader); +begin + inherited; + with reader do begin + printcommand:= readmsestring('printcommand',printcommand); + end; +end; + +procedure tstreamprinter.dostatwrite(const writer: tstatwriter); +begin + inherited; + with writer do begin + writemsestring('printcommand',printcommand); + end; +end; + +{ tstreamprintercanvas } +{ +procedure tstreamprintercanvas.reset; +begin +// restore(1); //do not change the streamed values +// save; + inherited; + clipregion:= 0; //?? + origin:= nullpoint; //?? +end; +} +procedure tstreamprintercanvas.streamwrite(const atext: string; + const apreamble: boolean = false); +var + bo1: boolean; +begin + if (fdeststream <> nil) and not fprinter.fcanceled then begin + bo1:= false; + repeat + try + if apreamble then begin + fpreamblestream.write(atext); + end + else begin + fbodystream.write(atext); + end; + except + on e: exception do begin + if fprinter.handleexception(e,bo1) then begin + raise; + end; + end; + end; + until not bo1; + end; +end; + +procedure tstreamprintercanvas.streamwriteln(const atext: string; + const apreamble: boolean = false); +var + bo1: boolean; +begin + if (fdeststream <> nil) and not fprinter.fcanceled then begin + bo1:= false; + repeat + try + if apreamble then begin + fpreamblestream.writeln(atext); + end + else begin + fbodystream.writeln(atext); + end; + except + on e: exception do begin + if fprinter.handleexception(e,bo1) then begin + raise; + end; + end; + end; + until not bo1; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/regcomponents/designer_bmp.pas b/mseide-msegui/lib/common/regcomponents/designer_bmp.pas new file mode 100644 index 0000000..0a253f9 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/designer_bmp.pas @@ -0,0 +1,119 @@ +unit designer_bmp; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msebitmap; + +const + objdata_TComponent: record size: integer; data: array[0..2033] of byte end = + (size: 2034; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,84,67,111, + 109,112,111,110,101,110,116,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,124,7,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,144,3,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,255,255,255,27,28,228,242,1,46,237,253,1, + 47,236,252,1,41,237,254,1,26,233,250,1,12,227,243,1,9,145,154,1, + 0,0,0,2,255,255,255,14,55,235,252,1,76,239,254,1,88,240,255,1, + 89,240,255,1,81,240,255,1,63,239,255,1,39,238,255,1,13,231,247,1, + 9,169,181,1,0,0,0,2,255,255,255,12,60,240,255,1,87,239,254,1, + 113,241,255,1,128,241,255,1,131,241,255,1,119,241,255,1,97,240,255,1, + 68,239,255,1,35,238,255,1,13,228,244,1,4,65,69,1,0,0,0,1, + 255,255,255,12,80,238,253,1,115,241,255,1,147,242,255,1,168,242,255,1, + 172,242,255,1,155,242,255,1,127,241,255,1,92,240,255,1,55,239,255,1, + 16,238,255,1,9,179,191,1,0,0,0,2,255,255,255,11,93,238,252,1, + 135,241,255,1,173,242,255,1,205,243,255,1,208,244,255,1,185,243,255,1, + 148,242,255,1,108,240,255,1,67,239,255,1,27,238,255,1,11,210,225,1, + 0,0,0,2,255,255,255,11,99,239,254,1,140,241,255,1,182,243,255,1, + 208,246,255,1,208,248,255,1,196,243,255,1,154,242,255,1,113,241,255,1, + 71,239,255,1,30,238,255,1,12,232,248,1,0,0,0,2,255,255,255,11, + 90,236,251,1,131,241,255,1,168,242,255,1,198,243,255,1,203,243,255,1, + 179,243,255,1,144,242,255,1,105,240,255,1,65,239,255,1,25,238,255,1, + 11,209,224,1,0,0,0,2,255,255,255,2,0,0,252,1,0,0,239,1, + 0,0,0,1,255,255,255,6,72,229,244,1,110,241,255,1,140,241,255,1, + 160,242,255,1,163,242,255,1,148,242,255,1,121,241,255,1,87,240,255,1, + 51,239,255,1,13,238,255,1,9,168,179,1,0,0,0,2,255,255,255,1, + 0,0,255,1,0,0,253,1,0,0,248,1,0,0,29,1,0,0,0,1, + 255,255,255,5,30,161,171,1,79,233,248,1,105,240,255,1,119,241,255,1, + 122,241,255,1,111,241,255,1,90,240,255,1,62,239,255,1,30,238,255,1, + 13,225,241,1,2,30,32,1,0,0,0,2,255,255,255,1,0,0,251,1, + 0,0,255,2,0,0,177,1,0,0,0,2,255,255,255,4,0,0,0,1, + 35,180,193,1,64,230,245,1,79,240,255,1,80,240,255,1,72,239,255,1, + 55,239,255,1,31,238,255,1,13,225,241,1,5,88,95,1,0,0,0,3, + 0,0,255,1,0,0,254,1,0,0,255,2,0,0,249,1,0,0,75,1, + 0,0,0,1,255,255,255,5,0,0,0,1,10,78,83,1,29,183,196,1, + 35,211,227,1,31,232,248,1,15,209,225,1,9,169,181,1,2,31,32,1, + 0,0,0,3,255,255,255,1,0,0,252,1,0,0,255,4,0,0,209,1, + 0,0,0,2,255,255,255,4,0,0,0,11,0,0,253,1,0,0,255,6, + 0,0,127,1,0,0,0,1,255,255,255,4,0,0,0,9,255,255,255,1, + 0,0,255,1,0,0,253,1,0,0,255,6,0,0,234,1,0,0,18,1, + 0,0,0,1,255,255,255,2,255,0,0,9,0,0,0,2,0,0,252,1, + 0,0,255,8,0,0,171,1,0,0,0,2,255,255,255,1,255,0,0,9, + 0,0,0,1,0,0,185,1,0,0,255,9,0,0,248,1,0,0,73,1, + 0,0,0,1,255,255,255,1,254,0,0,1,255,0,0,8,0,0,0,1, + 0,0,244,1,0,0,254,1,0,0,252,2,0,0,253,3,0,0,254,3, + 0,0,255,1,0,0,205,1,0,0,0,1,255,255,255,1,254,0,0,1, + 255,0,0,8,0,0,0,14,255,255,255,1,254,0,0,1,255,0,0,8, + 0,0,0,14,255,255,255,1,254,0,0,1,255,0,0,8,0,0,0,2, + 255,255,255,13,254,0,0,1,255,0,0,8,0,0,0,2,255,255,255,13, + 254,0,0,1,255,0,0,8,0,0,0,2,255,255,255,13,254,0,0,1, + 255,0,0,8,0,0,0,2,255,255,255,13,0,0,0,11,255,255,255,12, + 180,3,0,0,0,0,0,27,18,18,18,1,143,143,143,1,205,205,205,1, + 243,243,243,1,207,207,207,1,149,149,149,1,28,28,28,1,3,3,3,1, + 1,1,1,1,0,0,0,14,61,61,61,1,231,231,231,1,255,255,255,5, + 237,237,237,1,84,84,84,1,8,8,8,1,1,1,1,1,0,0,0,12, + 17,17,17,1,231,231,231,1,255,255,255,7,241,241,241,1,63,63,63,1, + 8,8,8,1,0,0,0,12,143,143,143,1,255,255,255,9,190,190,190,1, + 31,31,31,1,3,3,3,1,0,0,0,11,205,205,205,1,255,255,255,9, + 230,230,230,1,75,75,75,1,10,10,10,1,0,0,0,11,243,243,243,1, + 255,255,255,9,249,249,249,1,101,101,101,1,15,15,15,1,0,0,0,11, + 206,206,206,1,255,255,255,9,231,231,231,1,112,112,112,1,16,16,16,1, + 0,0,0,2,69,69,69,1,71,71,71,1,6,6,6,1,0,0,0,6, + 148,148,148,1,255,255,255,9,202,202,202,1,97,97,97,1,14,14,14,1, + 0,0,0,1,6,6,6,1,218,218,218,1,220,220,220,1,44,44,44,1, + 7,7,7,1,0,0,0,5,25,25,25,1,237,237,237,1,255,255,255,7, + 244,244,244,1,136,136,136,1,68,68,68,1,9,9,9,1,0,0,0,1, + 123,123,123,1,255,255,255,2,167,167,167,1,35,35,35,1,3,3,3,1, + 0,0,0,4,2,2,2,1,79,79,79,1,240,240,240,1,255,255,255,5, + 244,244,244,1,162,162,162,1,100,100,100,1,25,25,25,1,2,2,2,1, + 31,31,31,1,246,246,246,1,255,255,255,2,249,249,249,1,89,89,89,1, + 13,13,13,1,0,0,0,5,5,5,5,1,52,52,52,1,185,185,185,1, + 228,228,228,1,249,249,249,1,231,231,231,1,200,200,200,1,134,134,134,1, + 97,97,97,1,38,38,38,1,5,5,5,1,0,0,0,1,178,178,178,1, + 255,255,255,4,203,203,203,1,42,42,42,1,6,6,6,1,0,0,0,4, + 1,1,1,1,5,5,5,1,23,23,23,1,60,60,60,1,84,84,84,1, + 96,96,96,1,84,84,84,1,60,60,60,1,23,23,23,1,5,5,5,1, + 1,1,1,1,76,76,76,1,255,255,255,6,128,128,128,1,21,21,21,1, + 0,0,0,4,1,1,1,2,3,3,3,1,9,9,9,1,14,14,14,1, + 16,16,16,1,14,14,14,1,9,9,9,1,3,3,3,1,0,0,0,1, + 8,8,8,1,222,222,222,1,255,255,255,6,231,231,231,1,55,55,55,1, + 9,9,9,1,0,0,0,2,248,248,248,1,255,255,255,8,23,23,23,1, + 3,3,3,1,130,130,130,1,255,255,255,8,169,169,169,1,33,33,33,1, + 2,2,2,1,0,0,0,1,248,248,248,1,255,255,255,8,105,105,105,1, + 50,50,50,1,248,248,248,1,255,255,255,8,248,248,248,1,84,84,84,1, + 13,13,13,1,0,0,0,1,249,249,249,1,255,255,255,8,121,121,121,1, + 183,183,183,1,250,250,250,1,252,252,252,1,253,253,253,3,254,254,254,3, + 255,255,255,2,202,202,202,1,47,47,47,1,0,0,0,1,249,249,249,1, + 255,255,255,8,122,122,122,1,30,30,30,1,65,65,65,1,97,97,97,1, + 109,109,109,1,105,105,105,1,110,110,110,1,104,104,104,1,109,109,109,1, + 106,106,106,1,109,109,109,1,107,107,107,1,102,102,102,1,54,54,54,1, + 0,0,0,1,249,249,249,1,255,255,255,8,121,121,121,1,21,21,21,1, + 17,17,17,1,27,27,27,1,25,25,25,1,26,26,26,2,25,25,25,1, + 24,24,24,1,27,27,27,1,26,26,26,1,27,27,27,2,18,18,18,1, + 0,0,0,1,249,249,249,1,255,255,255,8,121,121,121,1,19,19,19,1, + 0,0,0,13,249,249,249,1,255,255,255,8,121,121,121,1,19,19,19,1, + 0,0,0,13,249,249,249,1,255,255,255,8,121,121,121,1,19,19,19,1, + 0,0,0,13,249,249,249,1,255,255,255,8,120,120,120,1,19,19,19,1, + 0,0,0,13,15,15,15,1,96,96,96,1,114,114,114,1,115,115,115,6, + 99,99,99,1,16,16,16,1,0,0,0,12,0,0) + ); + +initialization + registerobjectdata(@objdata_TComponent,tbitmapcomp,'TComponent'); +end. diff --git a/mseide-msegui/lib/common/regcomponents/regcrypto.pas b/mseide-msegui/lib/common/regcomponents/regcrypto.pas new file mode 100644 index 0000000..4aa60b8 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regcrypto.pas @@ -0,0 +1,38 @@ +{ MSEide Copyright (c) 2012 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regcrypto; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +implementation +uses + msedesignintf,msecryptohandler,msessl,msepropertyeditors,msestream,msezstream, + regcrypto_bmp; + +procedure Register; +begin + registercomponents('Cryp',[tdummycryptohandler,tdigesthandler,tbase64handler, + tzstreamhandler, + tsymciphercryptohandler,tasymciphercryptohandler]); + registerpropertyeditor(typeinfo(tcustomcryptohandler),nil,'', + tlinkcomponentpropertyeditor); + registercomponenttabhints(['Cryp'], + ['Components for tmsefilestream.criptohandler, zlib, openssl, base64']); +end; + +initialization + register; +end. diff --git a/mseide-msegui/lib/common/regcomponents/regcrypto_bmp.pas b/mseide-msegui/lib/common/regcomponents/regcrypto_bmp.pas new file mode 100644 index 0000000..e301054 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regcrypto_bmp.pas @@ -0,0 +1,693 @@ +unit regcrypto_bmp; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msebitmap; + +const + objdata_tdummycryptohandler: record size: integer; data: array[0..2186] of byte end = + (size: 2187; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,100,117, + 109,109,121,99,114,121,112,116,111,104,97,110,100,108,101,114,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,12,8,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,132,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,4,208,208,208, + 2,0,0,0,4,208,208,208,1,0,0,0,3,208,208,208,22,0,0,0, + 1,208,208,208,23,0,0,0,1,208,208,208,2,0,0,0,4,208,208,208, + 18,0,0,0,1,208,208,208,1,0,0,0,5,208,208,208,17,0,0,0, + 1,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208, + 1,0,0,0,1,208,208,208,1,0,0,0,9,208,208,208,2,0,0,0, + 1,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208, + 2,0,0,0,3,208,208,208,1,0,0,0,12,208,208,208,1,0,0,0, + 1,208,208,208,2,0,0,0,2,208,208,208,2,0,0,0,3,208,208,208, + 1,0,0,0,12,208,208,208,1,0,0,0,1,208,208,208,2,0,0,0, + 2,208,208,208,2,0,0,0,3,208,208,208,1,0,0,0,3,208,208,208, + 1,0,0,0,8,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0, + 2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,1,208,208,208, + 1,0,0,0,3,208,208,208,1,0,0,0,4,208,208,208,1,0,0,0, + 2,208,208,208,3,0,0,0,1,208,208,208,1,0,0,0,5,208,208,208, + 1,0,0,0,5,208,208,208,1,0,0,0,4,208,208,208,1,0,0,0, + 2,208,208,208,3,0,0,0,1,208,208,208,8,0,0,0,1,208,208,208, + 9,0,0,0,2,208,208,208,2,0,0,0,2,208,208,208,17,0,0,0, + 2,208,208,208,3,0,0,0,1,208,208,208,18,0,0,0,2,208,208,208, + 3,0,0,0,1,208,208,208,23,0,0,0,2,208,208,208,1,0,0,0, + 11,208,208,208,2,0,0,0,7,208,208,208,2,0,0,0,4,208,208,208, + 1,0,0,0,8,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0, + 6,208,208,208,1,0,0,0,3,208,208,208,4,0,0,0,2,208,208,208, + 2,0,0,0,5,208,208,208,1,0,0,0,2,208,208,208,2,0,0,0, + 7,208,208,208,1,0,0,0,4,208,208,208,3,0,0,0,4,208,208,208, + 1,0,0,0,2,208,208,208,1,0,0,0,4,208,208,208,2,0,0,0, + 7,208,208,208,3,0,0,0,3,208,208,208,2,0,0,0,5,208,208,208, + 1,0,0,0,1,208,208,208,4,0,0,0,1,208,208,208,7,0,0,0, + 3,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,2,208,208,208, + 10,0,0,0,3,208,208,208,3,0,0,0,2,208,208,208,5,0,0,0, + 1,208,208,208,22,0,0,0,3,208,208,208,2,0,0,0,3,208,208,208, + 2,0,0,0,4,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0, + 3,80,5,0,0,240,240,240,2,210,210,210,1,0,0,0,2,60,60,60, + 1,240,240,240,2,150,150,150,1,0,0,0,2,120,120,120,1,240,240,240, + 2,90,90,90,1,0,0,0,2,187,187,187,1,240,240,240,2,22,22,22, + 1,0,0,0,1,7,7,7,1,240,240,240,1,52,52,52,1,0,0,0, + 22,240,240,240,1,0,0,0,23,202,202,202,1,0,0,0,2,18,18,18, + 1,72,72,72,1,69,69,69,1,32,32,32,1,0,0,0,18,217,217,217, + 1,0,0,0,1,64,64,64,1,197,197,197,1,154,154,154,1,204,204,204, + 1,94,94,94,1,0,0,0,17,240,240,240,1,0,0,0,1,64,64,64, + 1,111,111,111,1,0,0,0,1,11,11,11,1,197,197,197,1,0,0,0, + 1,49,49,49,1,0,0,0,1,29,29,29,1,18,18,18,1,42,42,42, + 1,44,44,44,1,54,54,54,1,1,1,1,1,57,57,57,1,1,1,1, + 1,51,51,51,1,0,0,0,2,47,47,47,1,0,0,0,1,75,75,75, + 1,225,225,225,1,0,0,0,1,64,64,64,1,111,111,111,1,0,0,0, + 2,169,169,169,1,21,21,21,1,176,176,176,1,0,0,0,1,103,103,103, + 1,64,64,64,1,170,170,170,1,150,150,150,1,198,198,198,1,144,144,144, + 1,150,150,150,1,91,91,91,1,147,147,147,1,33,33,33,1,26,26,26, + 1,141,141,141,1,0,0,0,1,240,240,240,1,0,0,0,2,64,64,64, + 1,111,111,111,1,0,0,0,2,144,144,144,1,41,41,41,1,176,176,176, + 1,0,0,0,1,103,103,103,1,64,64,64,1,180,180,180,1,5,5,5, + 1,109,109,109,1,92,92,92,1,27,27,27,1,141,141,141,1,76,76,76, + 1,101,101,101,1,95,95,95,1,71,71,71,1,0,0,0,1,240,240,240, + 1,0,0,0,2,64,64,64,1,111,111,111,1,0,0,0,2,173,173,173, + 1,20,20,20,1,176,176,176,1,0,0,0,1,106,106,106,1,64,64,64, + 1,168,168,168,1,0,0,0,1,102,102,102,1,65,65,65,1,22,22,22, + 1,145,145,145,1,11,11,11,1,162,162,162,1,157,157,157,1,9,9,9, + 1,0,0,0,1,135,135,135,1,45,45,45,1,0,0,0,1,64,64,64, + 1,111,111,111,1,0,0,0,1,34,34,34,1,195,195,195,1,0,0,0, + 1,181,181,181,1,0,0,0,1,144,144,144,1,64,64,64,1,168,168,168, + 1,0,0,0,1,102,102,102,1,65,65,65,1,22,22,22,1,145,145,145, + 1,0,0,0,1,165,165,165,1,156,156,156,1,0,0,0,3,240,240,240, + 1,0,0,0,1,64,64,64,1,233,233,233,1,218,218,218,1,208,208,208, + 1,50,50,50,1,0,0,0,1,150,150,150,1,174,174,174,1,158,158,158, + 1,64,64,64,1,168,168,168,1,0,0,0,1,102,102,102,1,65,65,65, + 1,22,22,22,1,145,145,145,1,0,0,0,1,119,119,119,1,118,118,118, + 1,0,0,0,3,240,240,240,1,0,0,0,8,9,9,9,1,0,0,0, + 9,119,119,119,1,43,43,43,1,0,0,0,2,135,135,135,1,165,165,165, + 1,0,0,0,17,93,93,93,1,184,184,184,1,0,0,0,3,240,240,240, + 1,0,0,0,18,9,9,9,1,5,5,5,1,0,0,0,3,240,240,240, + 1,0,0,0,23,75,75,75,1,105,105,105,1,0,0,0,1,52,52,52, + 1,159,159,159,1,168,168,168,1,124,124,124,1,5,5,5,1,65,65,65, + 1,119,119,119,1,176,176,176,1,125,125,125,1,160,160,160,1,27,27,27, + 1,0,0,0,2,143,143,143,1,37,37,37,1,137,137,137,1,107,107,107, + 1,167,167,167,1,161,161,161,1,55,55,55,1,0,0,0,2,240,240,240, + 1,30,30,30,1,237,237,237,1,41,41,41,1,0,0,0,1,124,124,124, + 1,84,84,84,1,95,95,95,1,229,229,229,1,34,34,34,1,22,22,22, + 1,133,133,133,1,140,140,140,1,0,0,0,1,51,51,51,1,206,206,206, + 1,0,0,0,1,199,199,199,1,162,162,162,1,8,8,8,1,35,35,35, + 1,234,234,234,1,27,27,27,1,0,0,0,1,240,240,240,1,90,90,90, + 1,184,184,184,1,0,0,0,4,95,95,95,1,169,169,169,1,0,0,0, + 2,21,21,21,1,231,231,231,1,15,15,15,1,169,169,169,1,85,85,85, + 1,0,0,0,1,199,199,199,1,64,64,64,1,0,0,0,2,183,183,183, + 1,86,86,86,1,202,202,202,1,97,97,97,1,27,27,27,1,224,224,224, + 1,1,1,1,1,0,0,0,1,76,76,76,1,100,100,100,1,95,95,95, + 1,160,160,160,1,0,0,0,3,144,144,144,1,136,136,136,1,212,212,212, + 1,2,2,2,1,0,0,0,1,199,199,199,1,108,108,108,1,0,0,0, + 1,5,5,5,1,235,235,235,1,43,43,43,1,240,240,240,1,0,0,0, + 2,112,112,112,1,168,168,168,1,155,155,155,1,180,180,180,1,27,27,27, + 1,95,95,95,1,160,160,160,1,0,0,0,3,27,27,27,1,247,247,247, + 1,96,96,96,1,0,0,0,2,199,199,199,1,196,196,196,1,165,165,165, + 1,199,199,199,1,114,114,114,1,0,0,0,1,240,240,240,1,0,0,0, + 4,7,7,7,1,0,0,0,7,33,33,33,1,213,213,213,1,4,4,4, + 1,0,0,0,2,199,199,199,1,64,64,64,1,10,10,10,1,1,1,1, + 1,0,0,0,2,7,7,7,1,172,172,172,1,0,0,0,10,119,119,119, + 1,198,198,198,1,55,55,55,1,0,0,0,3,156,156,156,1,50,50,50, + 1,0,0,0,5,240,240,240,1,0,0,0,22,22,22,22,1,240,240,240, + 1,37,37,37,1,0,0,0,2,232,232,232,1,240,240,240,1,210,210,210, + 1,0,0,0,2,60,60,60,1,240,240,240,2,150,150,150,1,0,0,0, + 2,120,120,120,1,240,240,240,2,90,90,90,1,0,0,0,2,187,187,187, + 1,240,240,240,2,0,0) + ); + +const + objdata_tbase64handler: record size: integer; data: array[0..2177] of byte end = + (size: 2178; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,98,97, + 115,101,54,52,104,97,110,100,108,101,114,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,8,8,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,68,2,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,208,208,208,2, + 0,0,0,4,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,4, + 208,208,208,1,0,0,0,3,208,208,208,22,0,0,0,1,208,208,208,23, + 0,0,0,1,208,208,208,1,0,0,0,4,208,208,208,11,0,0,0,2, + 208,208,208,2,0,0,0,2,208,208,208,2,0,0,0,6,208,208,208,9, + 0,0,0,3,208,208,208,2,0,0,0,2,208,208,208,2,0,0,0,3, + 208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,3,208,208,208,1, + 0,0,0,5,208,208,208,1,0,0,0,1,208,208,208,1,0,0,0,3, + 208,208,208,1,0,0,0,19,208,208,208,1,0,0,0,3,208,208,208,1, + 0,0,0,1,208,208,208,1,0,0,0,21,208,208,208,1,0,0,0,1, + 208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,6,208,208,208,1, + 0,0,0,5,208,208,208,1,0,0,0,10,208,208,208,1,0,0,0,8, + 208,208,208,1,0,0,0,3,208,208,208,1,0,0,0,6,208,208,208,1, + 0,0,0,14,208,208,208,1,0,0,0,3,208,208,208,2,0,0,0,2, + 208,208,208,2,0,0,0,1,208,208,208,6,0,0,0,2,208,208,208,3, + 0,0,0,1,208,208,208,3,0,0,0,1,208,208,208,6,0,0,0,2, + 208,208,208,22,0,0,0,1,208,208,208,23,0,0,0,1,208,208,208,23, + 0,0,0,2,208,208,208,1,0,0,0,11,208,208,208,2,0,0,0,7, + 208,208,208,2,0,0,0,4,208,208,208,1,0,0,0,8,208,208,208,1, + 0,0,0,2,208,208,208,1,0,0,0,6,208,208,208,1,0,0,0,3, + 208,208,208,4,0,0,0,2,208,208,208,2,0,0,0,5,208,208,208,1, + 0,0,0,2,208,208,208,2,0,0,0,7,208,208,208,1,0,0,0,4, + 208,208,208,3,0,0,0,4,208,208,208,1,0,0,0,2,208,208,208,1, + 0,0,0,4,208,208,208,2,0,0,0,7,208,208,208,3,0,0,0,3, + 208,208,208,2,0,0,0,5,208,208,208,1,0,0,0,1,208,208,208,4, + 0,0,0,1,208,208,208,7,0,0,0,3,208,208,208,2,0,0,0,4, + 208,208,208,2,0,0,0,2,208,208,208,10,0,0,0,3,208,208,208,3, + 0,0,0,2,208,208,208,5,0,0,0,1,208,208,208,22,0,0,0,3, + 208,208,208,2,0,0,0,3,208,208,208,2,0,0,0,4,208,208,208,2, + 0,0,0,4,208,208,208,2,0,0,0,3,140,5,0,0,240,240,240,2, + 210,210,210,1,0,0,0,2,60,60,60,1,240,240,240,2,150,150,150,1, + 0,0,0,2,120,120,120,1,240,240,240,2,90,90,90,1,0,0,0,2, + 187,187,187,1,240,240,240,2,22,22,22,1,0,0,0,1,7,7,7,1, + 240,240,240,1,52,52,52,1,0,0,0,22,240,240,240,1,0,0,0,23, + 202,202,202,1,0,0,0,1,8,8,8,1,72,72,72,1,71,71,71,1, + 36,36,36,1,0,0,0,11,44,44,44,1,1,1,1,1,0,0,0,2, + 2,2,2,1,41,41,41,1,0,0,0,2,217,217,217,1,30,30,30,1, + 210,210,210,1,153,153,153,1,201,201,201,1,82,82,82,1,0,0,0,9, + 148,148,148,1,142,142,142,1,154,154,154,1,0,0,0,2,90,90,90,1, + 149,149,149,1,0,0,0,2,240,240,240,1,30,30,30,1,145,145,145,1, + 0,0,0,1,21,21,21,1,162,162,162,1,0,0,0,1,28,28,28,1, + 83,83,83,1,26,26,26,1,0,0,0,1,36,36,36,1,82,82,82,1, + 13,13,13,1,40,40,40,1,128,128,128,1,0,0,0,1,89,89,89,1, + 0,0,0,1,4,4,4,1,173,173,173,1,149,149,149,1,0,0,0,1, + 75,75,75,1,225,225,225,1,30,30,30,1,169,169,169,1,57,57,57,1, + 118,118,118,1,102,102,102,1,13,13,13,1,191,191,191,1,113,113,113,1, + 197,197,197,1,6,6,6,1,192,192,192,1,112,112,112,1,162,162,162,1, + 82,82,82,1,127,127,127,1,155,155,155,1,45,45,45,1,0,0,0,1, + 102,102,102,1,79,79,79,1,149,149,149,1,0,0,0,1,240,240,240,1, + 0,0,0,1,30,30,30,1,217,217,217,1,168,168,168,1,200,200,200,1, + 87,87,87,1,16,16,16,1,37,37,37,1,31,31,31,1,198,198,198,1, + 11,11,11,1,194,194,194,1,42,42,42,1,27,27,27,1,98,98,98,1, + 187,187,187,1,53,53,53,1,180,180,180,1,8,8,8,1,157,157,157,1, + 18,18,18,1,149,149,149,1,0,0,0,1,240,240,240,1,0,0,0,1, + 30,30,30,1,145,145,145,1,0,0,0,1,2,2,2,1,189,189,189,1, + 18,18,18,1,195,195,195,1,156,156,156,1,204,204,204,1,0,0,0,1, + 78,78,78,1,202,202,202,1,155,155,155,1,61,61,61,1,102,102,102,1, + 0,0,0,1,155,155,155,1,106,106,106,1,183,183,183,1,151,151,151,1, + 209,209,209,1,43,43,43,1,135,135,135,1,45,45,45,1,30,30,30,1, + 145,145,145,1,0,0,0,1,13,13,13,1,195,195,195,1,80,80,80,1, + 100,100,100,1,1,1,1,1,209,209,209,1,23,23,23,1,96,96,96,1, + 0,0,0,1,187,187,187,1,13,13,13,1,135,135,135,1,0,0,0,1, + 179,179,179,1,30,30,30,1,64,64,64,1,77,77,77,1,176,176,176,1, + 19,19,19,1,0,0,0,1,240,240,240,1,30,30,30,1,238,238,238,1, + 215,215,215,1,216,216,216,1,83,83,83,1,24,24,24,1,195,195,195,1, + 173,173,173,1,195,195,195,1,23,23,23,1,164,164,164,1,184,184,184,1, + 144,144,144,1,0,0,0,1,127,127,127,1,186,186,186,1,129,129,129,1, + 0,0,0,2,18,18,18,1,149,149,149,1,0,0,0,2,240,240,240,1, + 0,0,0,6,6,6,6,2,0,0,0,3,12,12,12,1,0,0,0,3, + 8,8,8,1,0,0,0,6,135,135,135,1,165,165,165,1,0,0,0,22, + 240,240,240,1,0,0,0,23,240,240,240,1,0,0,0,23,75,75,75,1, + 105,105,105,1,0,0,0,1,52,52,52,1,159,159,159,1,168,168,168,1, + 124,124,124,1,5,5,5,1,65,65,65,1,119,119,119,1,176,176,176,1, + 125,125,125,1,160,160,160,1,27,27,27,1,0,0,0,2,143,143,143,1, + 37,37,37,1,137,137,137,1,107,107,107,1,167,167,167,1,161,161,161,1, + 55,55,55,1,0,0,0,2,240,240,240,1,30,30,30,1,237,237,237,1, + 41,41,41,1,0,0,0,1,124,124,124,1,84,84,84,1,95,95,95,1, + 229,229,229,1,34,34,34,1,22,22,22,1,133,133,133,1,140,140,140,1, + 0,0,0,1,51,51,51,1,206,206,206,1,0,0,0,1,199,199,199,1, + 162,162,162,1,8,8,8,1,35,35,35,1,234,234,234,1,27,27,27,1, + 0,0,0,1,240,240,240,1,90,90,90,1,184,184,184,1,0,0,0,4, + 95,95,95,1,169,169,169,1,0,0,0,2,21,21,21,1,231,231,231,1, + 15,15,15,1,169,169,169,1,85,85,85,1,0,0,0,1,199,199,199,1, + 64,64,64,1,0,0,0,2,183,183,183,1,86,86,86,1,202,202,202,1, + 97,97,97,1,27,27,27,1,224,224,224,1,1,1,1,1,0,0,0,1, + 76,76,76,1,100,100,100,1,95,95,95,1,160,160,160,1,0,0,0,3, + 144,144,144,1,136,136,136,1,212,212,212,1,2,2,2,1,0,0,0,1, + 199,199,199,1,108,108,108,1,0,0,0,1,5,5,5,1,235,235,235,1, + 43,43,43,1,240,240,240,1,0,0,0,2,112,112,112,1,168,168,168,1, + 155,155,155,1,180,180,180,1,27,27,27,1,95,95,95,1,160,160,160,1, + 0,0,0,3,27,27,27,1,247,247,247,1,96,96,96,1,0,0,0,2, + 199,199,199,1,196,196,196,1,165,165,165,1,199,199,199,1,114,114,114,1, + 0,0,0,1,240,240,240,1,0,0,0,4,7,7,7,1,0,0,0,7, + 33,33,33,1,213,213,213,1,4,4,4,1,0,0,0,2,199,199,199,1, + 64,64,64,1,10,10,10,1,1,1,1,1,0,0,0,2,7,7,7,1, + 172,172,172,1,0,0,0,10,119,119,119,1,198,198,198,1,55,55,55,1, + 0,0,0,3,156,156,156,1,50,50,50,1,0,0,0,5,240,240,240,1, + 0,0,0,22,22,22,22,1,240,240,240,1,37,37,37,1,0,0,0,2, + 232,232,232,1,240,240,240,1,210,210,210,1,0,0,0,2,60,60,60,1, + 240,240,240,2,150,150,150,1,0,0,0,2,120,120,120,1,240,240,240,2, + 90,90,90,1,0,0,0,2,187,187,187,1,240,240,240,2,0,0) + ); + +const + objdata_tsymciphercryptohandler: record size: integer; data: array[0..2182] of byte end = + (size: 2183; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,23,116,115,121, + 109,99,105,112,104,101,114,99,114,121,112,116,111,104,97,110,100,108,101,114, + 23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99, + 111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116, + 105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111, + 95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105, + 109,97,103,101,10,4,8,0,0,0,0,0,0,6,0,0,0,24,0,0, + 0,24,0,0,0,92,2,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,3,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0, + 4,208,208,208,2,0,0,0,4,208,208,208,1,0,0,0,3,208,208,208, + 22,0,0,0,1,208,208,208,23,0,0,0,1,208,208,208,2,0,0,0, + 4,208,208,208,1,0,0,0,3,208,208,208,3,0,0,0,4,208,208,208, + 3,0,0,0,3,208,208,208,1,0,0,0,7,208,208,208,1,0,0,0, + 2,208,208,208,2,0,0,0,6,208,208,208,2,0,0,0,3,208,208,208, + 1,0,0,0,3,208,208,208,2,0,0,0,2,208,208,208,1,0,0,0, + 6,208,208,208,1,0,0,0,3,208,208,208,2,0,0,0,10,208,208,208, + 3,0,0,0,4,208,208,208,2,0,0,0,3,208,208,208,1,0,0,0, + 5,208,208,208,2,0,0,0,5,208,208,208,3,0,0,0,3,208,208,208, + 2,0,0,0,9,208,208,208,1,0,0,0,2,208,208,208,2,0,0,0, + 3,208,208,208,2,0,0,0,2,208,208,208,3,0,0,0,13,208,208,208, + 1,0,0,0,3,208,208,208,2,0,0,0,2,208,208,208,3,0,0,0, + 5,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,7,208,208,208, + 3,0,0,0,2,208,208,208,3,0,0,0,2,208,208,208,1,0,0,0, + 2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,1,208,208,208, + 3,0,0,0,1,208,208,208,18,0,0,0,2,208,208,208,22,0,0,0, + 1,208,208,208,23,0,0,0,1,208,208,208,23,0,0,0,2,208,208,208, + 1,0,0,0,11,208,208,208,2,0,0,0,7,208,208,208,2,0,0,0, + 4,208,208,208,1,0,0,0,8,208,208,208,1,0,0,0,2,208,208,208, + 1,0,0,0,6,208,208,208,1,0,0,0,3,208,208,208,4,0,0,0, + 2,208,208,208,2,0,0,0,5,208,208,208,1,0,0,0,2,208,208,208, + 2,0,0,0,7,208,208,208,1,0,0,0,4,208,208,208,3,0,0,0, + 4,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,4,208,208,208, + 2,0,0,0,7,208,208,208,3,0,0,0,3,208,208,208,2,0,0,0, + 5,208,208,208,1,0,0,0,1,208,208,208,4,0,0,0,1,208,208,208, + 7,0,0,0,3,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0, + 2,208,208,208,10,0,0,0,3,208,208,208,3,0,0,0,2,208,208,208, + 5,0,0,0,1,208,208,208,22,0,0,0,3,208,208,208,2,0,0,0, + 3,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,4,208,208,208, + 2,0,0,0,3,112,5,0,0,240,240,240,2,210,210,210,1,0,0,0, + 2,60,60,60,1,240,240,240,2,150,150,150,1,0,0,0,2,120,120,120, + 1,240,240,240,2,90,90,90,1,0,0,0,2,187,187,187,1,240,240,240, + 2,22,22,22,1,0,0,0,1,7,7,7,1,240,240,240,1,52,52,52, + 1,0,0,0,22,240,240,240,1,0,0,0,23,202,202,202,1,0,0,0, + 2,6,6,6,1,67,67,67,1,88,88,88,1,36,36,36,1,0,0,0, + 1,7,7,7,1,71,71,71,1,3,3,3,1,0,0,0,3,55,55,55, + 1,25,25,25,1,50,50,50,1,56,56,56,1,0,0,0,3,6,6,6, + 1,72,72,72,1,17,17,17,1,0,0,0,1,217,217,217,1,5,5,5, + 1,196,196,196,1,168,168,168,1,133,133,133,1,211,211,211,1,107,107,107, + 1,0,0,0,1,174,174,174,1,118,118,118,1,0,0,0,2,50,50,50, + 1,216,216,216,1,12,12,12,1,179,179,179,1,243,243,243,1,11,11,11, + 1,0,0,0,2,80,80,80,1,255,255,255,1,60,60,60,1,0,0,0, + 1,240,240,240,1,57,57,57,1,193,193,193,1,0,0,0,2,30,30,30, + 1,183,183,183,1,0,0,0,1,22,22,22,1,227,227,227,1,39,39,39, + 1,5,5,5,1,205,205,205,1,58,58,58,1,0,0,0,1,179,179,179, + 1,196,196,196,1,87,87,87,1,0,0,0,2,167,167,167,1,203,203,203, + 1,60,60,60,1,75,75,75,1,225,225,225,1,12,12,12,1,216,216,216, + 1,153,153,153,1,65,65,65,1,5,5,5,1,0,0,0,3,86,86,86, + 1,190,190,190,1,118,118,118,1,133,133,133,1,0,0,0,2,179,179,179, + 1,109,109,109,1,174,174,174,1,0,0,0,1,11,11,11,1,188,188,188, + 1,171,171,171,1,60,60,60,1,240,240,240,1,0,0,0,2,19,19,19, + 1,112,112,112,1,192,192,192,1,236,236,236,1,107,107,107,1,0,0,0, + 3,171,171,171,1,203,203,203,1,5,5,5,1,0,0,0,2,179,179,179, + 1,60,60,60,1,209,209,209,1,13,13,13,1,89,89,89,1,109,109,109, + 1,171,171,171,1,60,60,60,1,240,240,240,1,0,0,0,1,47,47,47, + 1,42,42,42,1,0,0,0,2,26,26,26,1,226,226,226,1,25,25,25, + 1,0,0,0,2,100,100,100,1,139,139,139,1,0,0,0,3,179,179,179, + 1,60,60,60,1,131,131,131,1,92,92,92,1,174,174,174,1,23,23,23, + 1,171,171,171,1,60,60,60,1,135,135,135,1,45,45,45,1,80,80,80, + 1,189,189,189,1,9,9,9,1,0,0,0,1,13,13,13,1,216,216,216, + 1,17,17,17,1,0,0,0,2,100,100,100,1,139,139,139,1,0,0,0, + 3,179,179,179,1,60,60,60,1,45,45,45,1,187,187,187,1,179,179,179, + 1,0,0,0,1,171,171,171,1,60,60,60,1,0,0,0,1,240,240,240, + 1,2,2,2,1,134,134,134,1,223,223,223,1,202,202,202,1,220,220,220, + 1,93,93,93,1,0,0,0,3,100,100,100,1,139,139,139,1,0,0,0, + 3,179,179,179,1,60,60,60,1,0,0,0,1,214,214,214,1,97,97,97, + 1,0,0,0,1,171,171,171,1,60,60,60,1,0,0,0,1,240,240,240, + 1,0,0,0,3,20,20,20,1,0,0,0,18,135,135,135,1,165,165,165, + 1,0,0,0,22,240,240,240,1,0,0,0,23,240,240,240,1,0,0,0, + 23,75,75,75,1,105,105,105,1,0,0,0,1,52,52,52,1,159,159,159, + 1,168,168,168,1,124,124,124,1,5,5,5,1,65,65,65,1,119,119,119, + 1,176,176,176,1,125,125,125,1,160,160,160,1,27,27,27,1,0,0,0, + 2,143,143,143,1,37,37,37,1,137,137,137,1,107,107,107,1,167,167,167, + 1,161,161,161,1,55,55,55,1,0,0,0,2,240,240,240,1,30,30,30, + 1,237,237,237,1,41,41,41,1,0,0,0,1,124,124,124,1,84,84,84, + 1,95,95,95,1,229,229,229,1,34,34,34,1,22,22,22,1,133,133,133, + 1,140,140,140,1,0,0,0,1,51,51,51,1,206,206,206,1,0,0,0, + 1,199,199,199,1,162,162,162,1,8,8,8,1,35,35,35,1,234,234,234, + 1,27,27,27,1,0,0,0,1,240,240,240,1,90,90,90,1,184,184,184, + 1,0,0,0,4,95,95,95,1,169,169,169,1,0,0,0,2,21,21,21, + 1,231,231,231,1,15,15,15,1,169,169,169,1,85,85,85,1,0,0,0, + 1,199,199,199,1,64,64,64,1,0,0,0,2,183,183,183,1,86,86,86, + 1,202,202,202,1,97,97,97,1,27,27,27,1,224,224,224,1,1,1,1, + 1,0,0,0,1,76,76,76,1,100,100,100,1,95,95,95,1,160,160,160, + 1,0,0,0,3,144,144,144,1,136,136,136,1,212,212,212,1,2,2,2, + 1,0,0,0,1,199,199,199,1,108,108,108,1,0,0,0,1,5,5,5, + 1,235,235,235,1,43,43,43,1,240,240,240,1,0,0,0,2,112,112,112, + 1,168,168,168,1,155,155,155,1,180,180,180,1,27,27,27,1,95,95,95, + 1,160,160,160,1,0,0,0,3,27,27,27,1,247,247,247,1,96,96,96, + 1,0,0,0,2,199,199,199,1,196,196,196,1,165,165,165,1,199,199,199, + 1,114,114,114,1,0,0,0,1,240,240,240,1,0,0,0,4,7,7,7, + 1,0,0,0,7,33,33,33,1,213,213,213,1,4,4,4,1,0,0,0, + 2,199,199,199,1,64,64,64,1,10,10,10,1,1,1,1,1,0,0,0, + 2,7,7,7,1,172,172,172,1,0,0,0,10,119,119,119,1,198,198,198, + 1,55,55,55,1,0,0,0,3,156,156,156,1,50,50,50,1,0,0,0, + 5,240,240,240,1,0,0,0,22,22,22,22,1,240,240,240,1,37,37,37, + 1,0,0,0,2,232,232,232,1,240,240,240,1,210,210,210,1,0,0,0, + 2,60,60,60,1,240,240,240,2,150,150,150,1,0,0,0,2,120,120,120, + 1,240,240,240,2,90,90,90,1,0,0,0,2,187,187,187,1,240,240,240, + 2,0,0) + ); + +const + objdata_tasymciphercryptohandler: record size: integer; data: array[0..2275] of byte end = + (size: 2276; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,24,116,97,115, + 121,109,99,105,112,104,101,114,99,114,121,112,116,111,104,97,110,100,108,101, + 114,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116, + 99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112, + 116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109, + 111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46, + 105,109,97,103,101,10,96,8,0,0,0,0,0,0,6,0,0,0,24,0, + 0,0,24,0,0,0,132,2,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,3,208,208,208,2,0,0,0,4,208,208,208,2,0,0, + 0,4,208,208,208,2,0,0,0,4,208,208,208,1,0,0,0,3,208,208, + 208,22,0,0,0,1,208,208,208,23,0,0,0,1,208,208,208,3,0,0, + 0,2,208,208,208,2,0,0,0,3,208,208,208,1,0,0,0,2,208,208, + 208,2,0,0,0,4,208,208,208,2,0,0,0,2,208,208,208,1,0,0, + 0,1,208,208,208,2,0,0,0,2,208,208,208,2,0,0,0,6,208,208, + 208,1,0,0,0,5,208,208,208,1,0,0,0,3,208,208,208,1,0,0, + 0,1,208,208,208,1,0,0,0,3,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,2,208,208,208,1,0,0,0,7,208,208,208,1,0,0, + 0,5,208,208,208,1,0,0,0,4,208,208,208,1,0,0,0,3,208,208, + 208,2,0,0,0,7,208,208,208,1,0,0,0,4,208,208,208,2,0,0, + 0,4,208,208,208,1,0,0,0,4,208,208,208,2,0,0,0,2,208,208, + 208,1,0,0,0,8,208,208,208,1,0,0,0,7,208,208,208,1,0,0, + 0,2,208,208,208,2,0,0,0,2,208,208,208,1,0,0,0,11,208,208, + 208,2,0,0,0,3,208,208,208,1,0,0,0,2,208,208,208,2,0,0, + 0,2,208,208,208,1,0,0,0,7,208,208,208,1,0,0,0,3,208,208, + 208,2,0,0,0,6,208,208,208,2,0,0,0,2,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,4,208,208,208,1,0,0,0,1,208,208, + 208,7,0,0,0,2,208,208,208,13,0,0,0,2,208,208,208,22,0,0, + 0,1,208,208,208,23,0,0,0,1,208,208,208,23,0,0,0,2,208,208, + 208,1,0,0,0,11,208,208,208,2,0,0,0,7,208,208,208,2,0,0, + 0,4,208,208,208,1,0,0,0,8,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,6,208,208,208,1,0,0,0,3,208,208,208,4,0,0, + 0,2,208,208,208,2,0,0,0,5,208,208,208,1,0,0,0,2,208,208, + 208,2,0,0,0,7,208,208,208,1,0,0,0,4,208,208,208,3,0,0, + 0,4,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,4,208,208, + 208,2,0,0,0,7,208,208,208,3,0,0,0,3,208,208,208,2,0,0, + 0,5,208,208,208,1,0,0,0,1,208,208,208,4,0,0,0,1,208,208, + 208,7,0,0,0,3,208,208,208,2,0,0,0,4,208,208,208,2,0,0, + 0,2,208,208,208,10,0,0,0,3,208,208,208,3,0,0,0,2,208,208, + 208,5,0,0,0,1,208,208,208,22,0,0,0,3,208,208,208,2,0,0, + 0,3,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,4,208,208, + 208,2,0,0,0,3,164,5,0,0,240,240,240,2,210,210,210,1,0,0, + 0,2,60,60,60,1,240,240,240,2,150,150,150,1,0,0,0,2,120,120, + 120,1,240,240,240,2,90,90,90,1,0,0,0,2,187,187,187,1,240,240, + 240,2,22,22,22,1,0,0,0,1,7,7,7,1,240,240,240,1,52,52, + 52,1,0,0,0,22,240,240,240,1,0,0,0,23,202,202,202,1,0,0, + 0,3,47,47,47,1,12,12,12,1,0,0,0,2,12,12,12,1,82,82, + 82,1,53,53,53,1,0,0,0,1,37,37,37,1,22,22,22,1,0,0, + 0,2,40,40,40,1,21,21,21,1,72,72,72,1,4,4,4,1,0,0, + 0,2,63,63,63,1,6,6,6,1,0,0,0,1,217,217,217,1,0,0, + 0,2,200,200,200,1,94,94,94,1,0,0,0,2,179,179,179,1,144,144, + 144,1,189,189,189,1,95,95,95,1,53,53,53,1,160,160,160,1,0,0, + 0,1,3,3,3,1,195,195,195,1,17,17,17,1,254,254,254,1,57,57, + 57,1,0,0,0,1,15,15,15,1,252,252,252,1,23,23,23,1,0,0, + 0,1,240,240,240,1,0,0,0,1,32,32,32,1,142,142,142,1,163,163, + 163,1,0,0,0,1,16,16,16,1,168,168,168,1,0,0,0,1,11,11, + 11,1,145,145,145,1,0,0,0,1,179,179,179,1,33,33,33,1,90,90, + 90,1,109,109,109,1,8,8,8,1,211,211,211,1,120,120,120,1,0,0, + 0,1,78,78,78,1,217,217,217,1,23,23,23,1,75,75,75,1,225,225, + 225,1,0,0,0,1,104,104,104,1,68,68,68,1,173,173,173,1,7,7, + 7,1,0,0,0,1,202,202,202,1,116,116,116,1,18,18,18,1,0,0, + 0,2,57,57,57,1,149,149,149,1,179,179,179,1,7,7,7,1,8,8, + 8,1,168,168,168,1,162,162,162,1,0,0,0,1,136,136,136,1,160,160, + 160,1,23,23,23,1,240,240,240,1,0,0,0,2,166,166,166,1,7,7, + 7,1,114,114,114,1,72,72,72,1,0,0,0,1,27,27,27,1,144,144, + 144,1,229,229,229,1,96,96,96,1,0,0,0,2,184,184,184,1,102,102, + 102,1,0,0,0,1,8,8,8,1,167,167,167,1,158,158,158,1,4,4, + 4,1,144,144,144,1,152,152,152,1,23,23,23,1,240,240,240,1,0,0, + 0,1,6,6,6,1,225,225,225,1,208,208,208,1,210,210,210,1,150,150, + 150,1,25,25,25,1,39,39,39,1,0,0,0,1,13,13,13,1,193,193, + 193,1,0,0,0,2,135,135,135,1,48,48,48,1,0,0,0,1,8,8, + 8,1,167,167,167,1,106,106,106,1,78,78,78,1,122,122,122,1,152,152, + 152,1,23,23,23,1,135,135,135,1,45,45,45,1,66,66,66,1,121,121, + 121,1,0,0,0,2,199,199,199,1,33,33,33,1,171,171,171,1,0,0, + 0,1,6,6,6,1,178,178,178,1,0,0,0,2,135,135,135,1,48,48, + 48,1,0,0,0,1,8,8,8,1,167,167,167,1,41,41,41,1,200,200, + 200,1,57,57,57,1,152,152,152,1,23,23,23,1,0,0,0,1,240,240, + 240,1,138,138,138,1,51,51,51,1,0,0,0,2,155,155,155,1,50,50, + 50,1,136,136,136,1,213,213,213,1,216,216,216,1,84,84,84,1,0,0, + 0,2,135,135,135,1,48,48,48,1,0,0,0,1,8,8,8,1,167,167, + 167,1,0,0,0,1,219,219,219,1,4,4,4,1,152,152,152,1,23,23, + 23,1,0,0,0,1,240,240,240,1,0,0,0,7,9,9,9,1,6,6, + 6,1,0,0,0,13,135,135,135,1,165,165,165,1,0,0,0,22,240,240, + 240,1,0,0,0,23,240,240,240,1,0,0,0,23,75,75,75,1,105,105, + 105,1,0,0,0,1,52,52,52,1,159,159,159,1,168,168,168,1,124,124, + 124,1,5,5,5,1,65,65,65,1,119,119,119,1,176,176,176,1,125,125, + 125,1,160,160,160,1,27,27,27,1,0,0,0,2,143,143,143,1,37,37, + 37,1,137,137,137,1,107,107,107,1,167,167,167,1,161,161,161,1,55,55, + 55,1,0,0,0,2,240,240,240,1,30,30,30,1,237,237,237,1,41,41, + 41,1,0,0,0,1,124,124,124,1,84,84,84,1,95,95,95,1,229,229, + 229,1,34,34,34,1,22,22,22,1,133,133,133,1,140,140,140,1,0,0, + 0,1,51,51,51,1,206,206,206,1,0,0,0,1,199,199,199,1,162,162, + 162,1,8,8,8,1,35,35,35,1,234,234,234,1,27,27,27,1,0,0, + 0,1,240,240,240,1,90,90,90,1,184,184,184,1,0,0,0,4,95,95, + 95,1,169,169,169,1,0,0,0,2,21,21,21,1,231,231,231,1,15,15, + 15,1,169,169,169,1,85,85,85,1,0,0,0,1,199,199,199,1,64,64, + 64,1,0,0,0,2,183,183,183,1,86,86,86,1,202,202,202,1,97,97, + 97,1,27,27,27,1,224,224,224,1,1,1,1,1,0,0,0,1,76,76, + 76,1,100,100,100,1,95,95,95,1,160,160,160,1,0,0,0,3,144,144, + 144,1,136,136,136,1,212,212,212,1,2,2,2,1,0,0,0,1,199,199, + 199,1,108,108,108,1,0,0,0,1,5,5,5,1,235,235,235,1,43,43, + 43,1,240,240,240,1,0,0,0,2,112,112,112,1,168,168,168,1,155,155, + 155,1,180,180,180,1,27,27,27,1,95,95,95,1,160,160,160,1,0,0, + 0,3,27,27,27,1,247,247,247,1,96,96,96,1,0,0,0,2,199,199, + 199,1,196,196,196,1,165,165,165,1,199,199,199,1,114,114,114,1,0,0, + 0,1,240,240,240,1,0,0,0,4,7,7,7,1,0,0,0,7,33,33, + 33,1,213,213,213,1,4,4,4,1,0,0,0,2,199,199,199,1,64,64, + 64,1,10,10,10,1,1,1,1,1,0,0,0,2,7,7,7,1,172,172, + 172,1,0,0,0,10,119,119,119,1,198,198,198,1,55,55,55,1,0,0, + 0,3,156,156,156,1,50,50,50,1,0,0,0,5,240,240,240,1,0,0, + 0,22,22,22,22,1,240,240,240,1,37,37,37,1,0,0,0,2,232,232, + 232,1,240,240,240,1,210,210,210,1,0,0,0,2,60,60,60,1,240,240, + 240,2,150,150,150,1,0,0,0,2,120,120,120,1,240,240,240,2,90,90, + 90,1,0,0,0,2,187,187,187,1,240,240,240,2,0,0) + ); + +const + objdata_tzstreamhandler: record size: integer; data: array[0..1834] of byte end = + (size: 1835; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,122,115, + 116,114,101,97,109,104,97,110,100,108,101,114,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,176,6,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,252,1,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,208,208,208, + 2,0,0,0,4,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0, + 4,208,208,208,1,0,0,0,3,208,208,208,22,0,0,0,1,208,208,208, + 23,0,0,0,1,208,208,208,6,0,0,0,10,208,208,208,8,0,0,0, + 1,208,208,208,5,0,0,0,10,208,208,208,8,0,0,0,1,208,208,208, + 7,0,0,0,2,208,208,208,1,0,0,0,6,208,208,208,6,0,0,0, + 2,208,208,208,6,0,0,0,3,208,208,208,1,0,0,0,7,208,208,208, + 5,0,0,0,1,208,208,208,7,0,0,0,2,208,208,208,2,0,0,0, + 7,208,208,208,5,0,0,0,1,208,208,208,6,0,0,0,3,208,208,208, + 2,0,0,0,7,208,208,208,5,0,0,0,2,208,208,208,5,0,0,0, + 2,208,208,208,3,0,0,0,7,208,208,208,6,0,0,0,1,208,208,208, + 5,0,0,0,12,208,208,208,6,0,0,0,1,208,208,208,14,0,0,0, + 2,208,208,208,6,0,0,0,2,208,208,208,22,0,0,0,1,208,208,208, + 23,0,0,0,1,208,208,208,23,0,0,0,2,208,208,208,1,0,0,0, + 11,208,208,208,2,0,0,0,7,208,208,208,2,0,0,0,4,208,208,208, + 1,0,0,0,8,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0, + 6,208,208,208,1,0,0,0,3,208,208,208,4,0,0,0,2,208,208,208, + 2,0,0,0,5,208,208,208,1,0,0,0,2,208,208,208,2,0,0,0, + 7,208,208,208,1,0,0,0,4,208,208,208,3,0,0,0,4,208,208,208, + 1,0,0,0,2,208,208,208,1,0,0,0,4,208,208,208,2,0,0,0, + 7,208,208,208,3,0,0,0,3,208,208,208,2,0,0,0,5,208,208,208, + 1,0,0,0,1,208,208,208,4,0,0,0,1,208,208,208,7,0,0,0, + 3,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,2,208,208,208, + 10,0,0,0,3,208,208,208,3,0,0,0,2,208,208,208,5,0,0,0, + 1,208,208,208,22,0,0,0,3,208,208,208,2,0,0,0,3,208,208,208, + 2,0,0,0,4,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0, + 3,124,4,0,0,240,240,240,2,210,210,210,1,0,0,0,2,60,60,60, + 1,240,240,240,2,150,150,150,1,0,0,0,2,120,120,120,1,240,240,240, + 2,90,90,90,1,0,0,0,2,187,187,187,1,240,240,240,2,22,22,22, + 1,0,0,0,1,7,7,7,1,240,240,240,1,52,52,52,1,0,0,0, + 22,240,240,240,1,0,0,0,23,202,202,202,1,0,0,0,6,43,43,43, + 1,72,72,72,3,17,17,17,1,49,49,49,1,21,21,21,1,26,26,26, + 1,44,44,44,1,2,2,2,1,0,0,0,8,217,217,217,1,0,0,0, + 5,91,91,91,1,152,152,152,2,228,228,228,1,48,48,48,1,175,175,175, + 1,56,56,56,1,69,69,69,1,158,158,158,1,9,9,9,1,0,0,0, + 8,240,240,240,1,0,0,0,7,53,53,53,1,175,175,175,1,0,0,0, + 1,175,175,175,1,21,21,21,1,26,26,26,1,158,158,158,1,28,28,28, + 1,62,62,62,1,0,0,0,6,75,75,75,1,225,225,225,1,0,0,0, + 6,1,1,1,1,193,193,193,1,34,34,34,1,0,0,0,1,175,175,175, + 1,75,75,75,1,92,92,92,1,158,158,158,1,164,164,164,1,170,170,170, + 1,83,83,83,1,0,0,0,5,240,240,240,1,0,0,0,7,98,98,98, + 1,129,129,129,1,0,0,0,2,175,175,175,1,75,75,75,1,92,92,92, + 1,158,158,158,1,38,38,38,1,23,23,23,1,168,168,168,1,0,0,0, + 5,240,240,240,1,0,0,0,6,15,15,15,1,201,201,201,1,9,9,9, + 1,0,0,0,2,175,175,175,1,75,75,75,1,92,92,92,1,157,157,157, + 1,5,5,5,1,2,2,2,1,170,170,170,1,0,0,0,5,135,135,135, + 1,45,45,45,1,0,0,0,5,144,144,144,1,79,79,79,1,0,0,0, + 3,175,175,175,1,75,75,75,1,92,92,92,1,158,158,158,1,48,48,48, + 1,44,44,44,1,119,119,119,1,0,0,0,6,240,240,240,1,0,0,0, + 5,231,231,231,1,216,216,216,3,71,71,71,1,175,175,175,1,75,75,75, + 1,92,92,92,1,154,154,154,1,161,161,161,1,184,184,184,1,34,34,34, + 1,0,0,0,6,240,240,240,1,0,0,0,14,1,1,1,1,4,4,4, + 1,0,0,0,6,135,135,135,1,165,165,165,1,0,0,0,22,240,240,240, + 1,0,0,0,23,240,240,240,1,0,0,0,23,75,75,75,1,105,105,105, + 1,0,0,0,1,52,52,52,1,159,159,159,1,168,168,168,1,124,124,124, + 1,5,5,5,1,65,65,65,1,119,119,119,1,176,176,176,1,125,125,125, + 1,160,160,160,1,27,27,27,1,0,0,0,2,143,143,143,1,37,37,37, + 1,137,137,137,1,107,107,107,1,167,167,167,1,161,161,161,1,55,55,55, + 1,0,0,0,2,240,240,240,1,30,30,30,1,237,237,237,1,41,41,41, + 1,0,0,0,1,124,124,124,1,84,84,84,1,95,95,95,1,229,229,229, + 1,34,34,34,1,22,22,22,1,133,133,133,1,140,140,140,1,0,0,0, + 1,51,51,51,1,206,206,206,1,0,0,0,1,199,199,199,1,162,162,162, + 1,8,8,8,1,35,35,35,1,234,234,234,1,27,27,27,1,0,0,0, + 1,240,240,240,1,90,90,90,1,184,184,184,1,0,0,0,4,95,95,95, + 1,169,169,169,1,0,0,0,2,21,21,21,1,231,231,231,1,15,15,15, + 1,169,169,169,1,85,85,85,1,0,0,0,1,199,199,199,1,64,64,64, + 1,0,0,0,2,183,183,183,1,86,86,86,1,202,202,202,1,97,97,97, + 1,27,27,27,1,224,224,224,1,1,1,1,1,0,0,0,1,76,76,76, + 1,100,100,100,1,95,95,95,1,160,160,160,1,0,0,0,3,144,144,144, + 1,136,136,136,1,212,212,212,1,2,2,2,1,0,0,0,1,199,199,199, + 1,108,108,108,1,0,0,0,1,5,5,5,1,235,235,235,1,43,43,43, + 1,240,240,240,1,0,0,0,2,112,112,112,1,168,168,168,1,155,155,155, + 1,180,180,180,1,27,27,27,1,95,95,95,1,160,160,160,1,0,0,0, + 3,27,27,27,1,247,247,247,1,96,96,96,1,0,0,0,2,199,199,199, + 1,196,196,196,1,165,165,165,1,199,199,199,1,114,114,114,1,0,0,0, + 1,240,240,240,1,0,0,0,4,7,7,7,1,0,0,0,7,33,33,33, + 1,213,213,213,1,4,4,4,1,0,0,0,2,199,199,199,1,64,64,64, + 1,10,10,10,1,1,1,1,1,0,0,0,2,7,7,7,1,172,172,172, + 1,0,0,0,10,119,119,119,1,198,198,198,1,55,55,55,1,0,0,0, + 3,156,156,156,1,50,50,50,1,0,0,0,5,240,240,240,1,0,0,0, + 22,22,22,22,1,240,240,240,1,37,37,37,1,0,0,0,2,232,232,232, + 1,240,240,240,1,210,210,210,1,0,0,0,2,60,60,60,1,240,240,240, + 2,150,150,150,1,0,0,0,2,120,120,120,1,240,240,240,2,90,90,90, + 1,0,0,0,2,187,187,187,1,240,240,240,2,0,0) + ); + +const + objdata_tdigesthandler: record size: integer; data: array[0..2201] of byte end = + (size: 2202; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,100,105, + 103,101,115,116,104,97,110,100,108,101,114,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,32,8,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,76,2,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,208,208,208,2, + 0,0,0,4,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,4, + 208,208,208,1,0,0,0,3,208,208,208,22,0,0,0,1,208,208,208,23, + 0,0,0,1,208,208,208,4,0,0,0,4,208,208,208,13,0,0,0,1, + 208,208,208,2,0,0,0,1,208,208,208,3,0,0,0,4,208,208,208,12, + 0,0,0,2,208,208,208,2,0,0,0,1,208,208,208,2,0,0,0,9, + 208,208,208,1,0,0,0,2,208,208,208,2,0,0,0,2,208,208,208,1, + 0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,20, + 208,208,208,1,0,0,0,1,208,208,208,2,0,0,0,7,208,208,208,1, + 0,0,0,12,208,208,208,1,0,0,0,1,208,208,208,2,0,0,0,1, + 208,208,208,1,0,0,0,5,208,208,208,1,0,0,0,12,208,208,208,1, + 0,0,0,2,208,208,208,1,0,0,0,20,208,208,208,2,0,0,0,1, + 208,208,208,1,0,0,0,20,208,208,208,2,0,0,0,1,208,208,208,2, + 0,0,0,1,208,208,208,4,0,0,0,1,208,208,208,1,0,0,0,2, + 208,208,208,2,0,0,0,1,208,208,208,2,0,0,0,2,208,208,208,2, + 0,0,0,1,208,208,208,1,0,0,0,2,208,208,208,7,0,0,0,4, + 208,208,208,11,0,0,0,1,208,208,208,9,0,0,0,2,208,208,208,12, + 0,0,0,1,208,208,208,23,0,0,0,2,208,208,208,1,0,0,0,11, + 208,208,208,2,0,0,0,7,208,208,208,2,0,0,0,4,208,208,208,1, + 0,0,0,8,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,6, + 208,208,208,1,0,0,0,3,208,208,208,4,0,0,0,2,208,208,208,2, + 0,0,0,5,208,208,208,1,0,0,0,2,208,208,208,2,0,0,0,7, + 208,208,208,1,0,0,0,4,208,208,208,3,0,0,0,4,208,208,208,1, + 0,0,0,2,208,208,208,1,0,0,0,4,208,208,208,2,0,0,0,7, + 208,208,208,3,0,0,0,3,208,208,208,2,0,0,0,5,208,208,208,1, + 0,0,0,1,208,208,208,4,0,0,0,1,208,208,208,7,0,0,0,3, + 208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,2,208,208,208,10, + 0,0,0,3,208,208,208,3,0,0,0,2,208,208,208,5,0,0,0,1, + 208,208,208,22,0,0,0,3,208,208,208,2,0,0,0,3,208,208,208,2, + 0,0,0,4,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,3, + 156,5,0,0,240,240,240,2,210,210,210,1,0,0,0,2,60,60,60,1, + 240,240,240,2,150,150,150,1,0,0,0,2,120,120,120,1,240,240,240,2, + 90,90,90,1,0,0,0,2,187,187,187,1,240,240,240,2,22,22,22,1, + 0,0,0,1,7,7,7,1,240,240,240,1,52,52,52,1,0,0,0,22, + 240,240,240,1,0,0,0,23,202,202,202,1,0,0,0,4,3,3,3,1, + 43,43,43,1,25,25,25,1,21,21,21,1,0,0,0,13,1,1,1,1, + 0,0,0,2,217,217,217,1,0,0,0,3,12,12,12,1,155,155,155,1, + 69,69,69,1,56,56,56,1,0,0,0,12,77,77,77,1,60,60,60,1, + 0,0,0,2,240,240,240,1,0,0,0,2,58,58,58,1,48,48,48,1, + 155,155,155,1,25,25,25,1,21,21,21,1,2,2,2,1,63,63,63,1, + 17,17,17,1,36,36,36,1,0,0,0,1,23,23,23,1,41,41,41,1, + 0,0,0,2,66,66,66,1,65,65,65,1,0,0,0,1,141,141,141,1, + 109,109,109,1,0,0,0,1,75,75,75,1,225,225,225,1,0,0,0,1, + 88,88,88,1,164,164,164,1,177,177,177,1,155,155,155,1,92,92,92,1, + 75,75,75,1,122,122,122,1,145,145,145,1,179,179,179,1,129,129,129,1, + 52,52,52,1,170,170,170,1,151,151,151,1,88,88,88,1,74,74,74,1, + 158,158,158,1,157,157,157,1,82,82,82,1,161,161,161,1,135,135,135,1, + 0,0,0,1,240,240,240,1,0,0,0,2,174,174,174,1,13,13,13,1, + 52,52,52,1,155,155,155,1,92,92,92,1,75,75,75,1,186,186,186,1, + 0,0,0,1,75,75,75,1,129,129,129,1,125,125,125,1,63,63,63,1, + 32,32,32,1,152,152,152,1,93,93,93,1,139,139,139,1,24,24,24,1, + 18,18,18,1,105,105,105,1,62,62,62,1,0,0,0,1,240,240,240,1, + 0,0,0,2,179,179,179,1,0,0,0,1,17,17,17,1,155,155,155,1, + 92,92,92,1,75,75,75,1,175,175,175,1,0,0,0,1,46,46,46,1, + 129,129,129,1,165,165,165,1,155,155,155,1,152,152,152,1,130,130,130,1, + 4,4,4,1,129,129,129,1,222,222,222,1,78,78,78,1,105,105,105,1, + 62,62,62,1,0,0,0,1,135,135,135,1,45,45,45,1,0,0,0,1, + 159,159,159,1,33,33,33,1,58,58,58,1,155,155,155,1,92,92,92,1, + 75,75,75,1,161,161,161,1,13,13,13,1,104,104,104,1,129,129,129,1, + 112,112,112,1,54,54,54,1,8,8,8,1,113,113,113,1,77,77,77,1, + 38,38,38,1,31,31,31,1,156,156,156,1,103,103,103,1,64,64,64,1, + 0,0,0,2,240,240,240,1,0,0,0,1,45,45,45,1,208,208,208,1, + 154,154,154,1,155,155,155,1,92,92,92,1,75,75,75,1,48,48,48,1, + 183,183,183,1,165,165,165,1,121,121,121,1,30,30,30,1,178,178,178,1, + 188,188,188,1,76,76,76,1,34,34,34,1,192,192,192,1,196,196,196,1, + 69,69,69,1,68,68,68,1,207,207,207,1,0,0,0,2,240,240,240,1, + 0,0,0,2,7,7,7,1,0,0,0,4,80,80,80,1,0,0,0,1, + 72,72,72,1,95,95,95,1,0,0,0,2,8,8,8,1,0,0,0,2, + 2,2,2,1,10,10,10,1,0,0,0,2,5,5,5,1,0,0,0,1, + 135,135,135,1,165,165,165,1,0,0,0,7,102,102,102,1,175,175,175,1, + 192,192,192,1,20,20,20,1,0,0,0,11,240,240,240,1,0,0,0,9, + 11,11,11,1,1,1,1,1,0,0,0,12,240,240,240,1,0,0,0,23, + 75,75,75,1,105,105,105,1,0,0,0,1,52,52,52,1,159,159,159,1, + 168,168,168,1,124,124,124,1,5,5,5,1,65,65,65,1,119,119,119,1, + 176,176,176,1,125,125,125,1,160,160,160,1,27,27,27,1,0,0,0,2, + 143,143,143,1,37,37,37,1,137,137,137,1,107,107,107,1,167,167,167,1, + 161,161,161,1,55,55,55,1,0,0,0,2,240,240,240,1,30,30,30,1, + 237,237,237,1,41,41,41,1,0,0,0,1,124,124,124,1,84,84,84,1, + 95,95,95,1,229,229,229,1,34,34,34,1,22,22,22,1,133,133,133,1, + 140,140,140,1,0,0,0,1,51,51,51,1,206,206,206,1,0,0,0,1, + 199,199,199,1,162,162,162,1,8,8,8,1,35,35,35,1,234,234,234,1, + 27,27,27,1,0,0,0,1,240,240,240,1,90,90,90,1,184,184,184,1, + 0,0,0,4,95,95,95,1,169,169,169,1,0,0,0,2,21,21,21,1, + 231,231,231,1,15,15,15,1,169,169,169,1,85,85,85,1,0,0,0,1, + 199,199,199,1,64,64,64,1,0,0,0,2,183,183,183,1,86,86,86,1, + 202,202,202,1,97,97,97,1,27,27,27,1,224,224,224,1,1,1,1,1, + 0,0,0,1,76,76,76,1,100,100,100,1,95,95,95,1,160,160,160,1, + 0,0,0,3,144,144,144,1,136,136,136,1,212,212,212,1,2,2,2,1, + 0,0,0,1,199,199,199,1,108,108,108,1,0,0,0,1,5,5,5,1, + 235,235,235,1,43,43,43,1,240,240,240,1,0,0,0,2,112,112,112,1, + 168,168,168,1,155,155,155,1,180,180,180,1,27,27,27,1,95,95,95,1, + 160,160,160,1,0,0,0,3,27,27,27,1,247,247,247,1,96,96,96,1, + 0,0,0,2,199,199,199,1,196,196,196,1,165,165,165,1,199,199,199,1, + 114,114,114,1,0,0,0,1,240,240,240,1,0,0,0,4,7,7,7,1, + 0,0,0,7,33,33,33,1,213,213,213,1,4,4,4,1,0,0,0,2, + 199,199,199,1,64,64,64,1,10,10,10,1,1,1,1,1,0,0,0,2, + 7,7,7,1,172,172,172,1,0,0,0,10,119,119,119,1,198,198,198,1, + 55,55,55,1,0,0,0,3,156,156,156,1,50,50,50,1,0,0,0,5, + 240,240,240,1,0,0,0,22,22,22,22,1,240,240,240,1,37,37,37,1, + 0,0,0,2,232,232,232,1,240,240,240,1,210,210,210,1,0,0,0,2, + 60,60,60,1,240,240,240,2,150,150,150,1,0,0,0,2,120,120,120,1, + 240,240,240,2,90,90,90,1,0,0,0,2,187,187,187,1,240,240,240,2, + 0,0) + ); + +initialization + registerobjectdata(@objdata_tdummycryptohandler,tbitmapcomp,'tdummycryptohandler'); + registerobjectdata(@objdata_tbase64handler,tbitmapcomp,'tbase64handler'); + registerobjectdata(@objdata_tsymciphercryptohandler,tbitmapcomp,'tsymciphercryptohandler'); + registerobjectdata(@objdata_tasymciphercryptohandler,tbitmapcomp,'tasymciphercryptohandler'); + registerobjectdata(@objdata_tzstreamhandler,tbitmapcomp,'tzstreamhandler'); + registerobjectdata(@objdata_tdigesthandler,tbitmapcomp,'tdigesthandler'); +end. diff --git a/mseide-msegui/lib/common/regcomponents/regdb.pas b/mseide-msegui/lib/common/regcomponents/regdb.pas new file mode 100644 index 0000000..8265e26 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regdb.pas @@ -0,0 +1,1757 @@ +{ MSEide Copyright (c) 1999-2017 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regdb; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + classes,mclasses,typinfo,msesqldb,msedbedit,msepropertyeditors,msedb, + mseclasses,msetypes,msestrings, + mseglob,mseguiglob,msegui,msedatabase,msesqlresult,msedesignintf; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tdbfieldnamepropertyeditor = class(tstringpropertyeditor) + private + fnocalc: boolean; + protected + fdbeditinfointf: idbeditinfo; + function getdefaultstate: propertystatesty; override; + public + function getvalues: msestringarty; override; + end; + + tdbfieldnamenocalcpropertyeditor = class(tdbfieldnamepropertyeditor) + public + constructor create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypeinfo: ptypeinfo); override; + end; + + tdbcolnamepropertyeditor = class(tstringpropertyeditor) + protected + fdbcolinfointf: idbcolinfo; + function getdefaultstate: propertystatesty; override; + public + function getvalues: msestringarty; override; + end; + + tdbcolnamearraypropertyeditor = class(tstringarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + + tdbparampropertyeditor = class(tclasspropertyeditor) + public + function getvalue: msestring; override; + end; + + tmseparampropertyeditor = class(tclasspropertyeditor) + public + function getvalue: msestring; override; + end; + + tdbparamnamepropertyeditor = class(tstringpropertyeditor) + protected + fdbparaminfointf: idbparaminfo; + function getdefaultstate: propertystatesty; override; + public + function getvalues: msestringarty; override; + end; + + tdbfieldnamearraypropertyeditor = class(tstringarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + tsqlpropertyeditor = class(ttextstringspropertyeditor) + private + factivebefore: boolean; + fdbactivebefore: boolean; + fintf: isqlpropertyeditor; + protected + function nocheck: boolean; virtual; + function getsyntaxindex: integer; override; + procedure doafterclosequery(var amodalresult: modalresultty); override; + function gettestbutton: boolean; override; + function getutf8: boolean; override; + function getcaption: msestring; override; + public + procedure edit; override; + end; + + tmsesqlpropertyeditor = class(tsqlpropertyeditor) + protected + function ismsestring: boolean; override; + end; + + tsqlnocheckpropertyeditor = class(tsqlpropertyeditor) + protected + function nocheck: boolean; override; + end; + + tmsesqlnocheckpropertyeditor = class(tmsesqlpropertyeditor) + protected + function nocheck: boolean; override; + end; +{ + tlbdropdowncolitemeditor = class(tclasselementeditor) + public + function getvalue: msestring; override; + end; +} + tlbdropdowncolseditor = class(tpersistentarraypropertyeditor) + protected + function itemgetvalue(const sender: tarrayelementeditor): msestring; + override; +// function geteditorclass: propertyeditorclassty; override; + end; +{ + tdbdropdowncolitemeditor = class(tclasselementeditor) + public + function getvalue: msestring; override; + end; +} + tdbdropdowncolseditor = class(tpersistentarraypropertyeditor) + protected + function itemgetvalue(const sender: tarrayelementeditor): msestring; + override; +// function geteditorclass: propertyeditorclassty; override; + end; +{ + tsqlmacroitemeditor = class(tclasselementeditor) + public + function getvalue: msestring; override; + end; +} + +implementation +uses + {$ifdef FPC}dbconst{$else} dbconst_del,classes_del{$endif},mdb, + mseibconnection,msefb3connection,msefbservice,msefb3service, + msepqconnection,mseodbcconn,{sqldb,} + mselookupbuffer,mselocaldataset, + msearrayutils,msedbfieldeditor,sysutils,msetexteditor, + msedbdispwidgets,msedbgraphics,regdb_bmp,msedbdialog,msegrids, + msedbcalendardatetimeedit,msemacros, + regwidgets,msebufdataset,msedbevents,msesqlite3conn,msqldb,msemysqlconn, + msedblookup; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tpropertyeditor1 = class(tpropertyeditor); + tlbdropdowncol1 = class(tlbdropdowncol); + tarrayelementeditor1 = class(tarrayelementeditor); + + tdatalinkpropertyeditor = class(tclasspropertyeditor) + public + function getvalue: msestring; override; + end; + + tfielddatalinkpropertyeditor = class(tdatalinkpropertyeditor) + public + function getvalue: msestring; override; + end; + + tnolistdropdowncolpropertyeditor = class(tarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + tpersistentfieldelementeditor = class(tclasselementeditor) + public + function getvalue: msestring; override; + end; + + tpersistentfieldspropertyeditor = class(tpersistentarraypropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + function geteditorclass: propertyeditorclassty; override; + public + procedure edit; override; + end; + + tfieldfieldnamepropertyeditor = class(tstringpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + function getvalues: msestringarty; override; + procedure setvalue(const value: msestring); override; + end; + + tfielddatasetpropertyeditor = class(tcomponentpropertyeditor) + protected + procedure checkcomponent(const avalue: tcomponent); override; + end; + + tonfilterpropertyeditor = class(tmethodpropertyeditor) + public + function getdefaultstate: propertystatesty; override; + procedure setvalue(const value: msestring); override; + end; + + toptionlbpropertyeditor = class(tsetelementeditor) + public + function getdefaultstate: propertystatesty; override; + procedure setvalue(const value: msestring); override; + end; + + toptionslbpropertyeditor = class(tsetpropertyeditor) + public + constructor create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypeinfo: ptypeinfo); override; + function getdefaultstate: propertystatesty; override; + procedure setvalue(const value: msestring); override; + end; + + tfielddefpropertyeditor = class(tclasspropertyeditor) + public + function getvalue: msestring; override; + end; + + tfielddefspropertyeditor = class(tcollectionpropertyeditor) + public + procedure setvalue(const value: msestring); override; + end; + + tdatasetactivepropertyeditor = class(tbooleanpropertyeditor) + public + function getdefaultstate: propertystatesty; override; + end; + + tdbstringcoleditor = class(tdatacoleditor) + public + function getvalue: msestring; override; + end; + + tdbstringcolseditor = class(tdatacolseditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + tindexfieldnamepropertyeditor = class(tstringpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + function getvalues: msestringarty; override; + end; + + tindexfieldpropertyeditor = class(tclasselementeditor) + protected + function getdefaultstate: propertystatesty; override; + public + function getvalue: msestring; override; + end; + + tindexfieldspropertyeditor = class(tpersistentarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + tlocalindexpropertyeditor = class(tclasselementeditor) + protected + function getdefaultstate: propertystatesty; override; + public + function getvalue: msestring; override; + end; + + tlocalindexespropertyeditor = class(tpersistentarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; +{ + tslaveparampropertyeditor = class(tclasselementeditor) + protected + function getdefaultstate: propertystatesty; override; + public + function getvalue: msestring; override; + end; +} + tslaveparamspropertyeditor = class(tpersistentarraypropertyeditor) + protected + function itemgetdefaultstate( + const sender: tarrayelementeditor): propertystatesty; override; + function itemgetvalue( + const sender: tarrayelementeditor): msestring; override; + // function geteditorclass: propertyeditorclassty; override; + end; + + tslavefieldspropertyeditor = class(tpersistentarraypropertyeditor) + protected + function itemgetdefaultstate( + const sender: tarrayelementeditor): propertystatesty; override; + function itemgetvalue( + const sender: tarrayelementeditor): msestring; override; + // function geteditorclass: propertyeditorclassty; override; + end; + + tlookupbufferfieldnopropertyeditor = class(tordinalpropertyeditor) + private + fintf: ilookupbufferfieldinfo; + flbdatakind: lbdatakindty; + protected + function getdefaultstate: propertystatesty; override; + function getnames: msestringarty; + public + constructor create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypeinfo: ptypeinfo); override; + function getvalues: msestringarty; override; + function getvalue: msestring; override; + procedure setvalue(const value: msestring); override; + end; + + tparamvaluepropertyeditor = class(tvariantpropertyeditor) + public + procedure setvalue(const value: msestring); override; + end; + + tlookupfieldnamepropertyeditor = class(tstringpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + function getvalues: msestringarty; override; + end; + + tdatasetoptionspropertyeditor = class(tsetpropertyeditor) + protected + function getinvisibleitems: tintegerset; override; + public + end; + + tsqlresconncolnamepropertyeditor = class(tstringpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + function getvalues: msestringarty; override; + end; + +procedure Register; +begin + registercomponents('DB',[ + tmseibconnection,tfbservice,tfb3service,tfb3connection, + tmsepqconnection,tsqlite3connection,tmseodbcconnection, + tmsemysqlconnection, + + tmsesqltransaction,tmsesqlquery, + tlocaldataset, + + tmsedatasource, + + tsqlstatement,tmsesqlscript,tsqlresult, + tsqllookupbuffer,tlookupbuffer,tdblookupbuffer,tdbmemolookupbuffer, + + tdbnavigator,tdbstringgrid + ]); + registercomponenttabhints(['DB'],['Database components']); + + registercomponents('DBe',[tdbwidgetgrid, + tdbstringedit,tdbmemoedit, + tdbintegeredit,tdbrealedit,tdbrealspinedit, + tdbdatetimeedit,tdbcalendardatetimeedit, + tdbbooleantextedit, + tdbbooleanedit,tdbbooleaneditradio, + tdbdatabutton, + tdbdataicon,tdbdataimage, + tdbprogressbar,tdbslider, + + tdbdropdownlistedit,tdbdropdownlisteditdb,tdbdropdownlisteditlb, + + tdbenumedit,tdbenumeditdb,tdbenumeditlb, + tdbenum64editdb,tdbenum64editlb, + tdbkeystringedit,tdbkeystringeditdb,tdbkeystringeditlb, + + tdbdialogstringedit,tdbmemodialogedit, + tdbdialogintegeredit,tdbdialogrealedit, + tdbdialogdatetimeedit, + tdbfilenameedit,tdbremotefilenameedit,tdbcoloredit, + + tdropdownlisteditdb,tdropdownlisteditlb, + tenumeditdb,tenumeditlb, + tenum64editdb,tenum64editlb, + tkeystringeditdb,tkeystringeditlb + + ]); + registercomponenttabhints(['DBe'], + ['Data edit widgets, can be placed in tdbwidgetgrid']); + + registercomponents('DBl',[ + tdbstringlookupdb,tdbintegerlookupdb,tdbreallookupdb, + tdbdatetimelookupdb, + tdbstringlookup64db,tdbintegerlookup64db,tdbreallookup64db, + tdbdatetimelookup64db, + tdbstringlookupstrdb,tdbintegerlookupstrdb,tdbreallookupstrdb, + tdbdatetimelookupstrdb, + tdbstringlookuplb,tdbintegerlookuplb,tdbreallookuplb, + tdbdatetimelookuplb, + tdbstringlookup64lb,tdbintegerlookup64lb,tdbreallookup64lb, + tdbdatetimelookup64lb, + tdbstringlookupstrlb,tdbintegerlookupstrlb,tdbreallookupstrlb, + tdbdatetimelookupstrlb]); + registercomponenttabhints(['DBl'], + ['Data lookup widgets, can be placed in tdbwidgetgrid']); + + registercomponents('DBf',[ + tmsestringfield,tmselongintfield,tmselargeintfield,tmsesmallintfield, + tmsewordfield,tmseautoincfield,tmsefloatfield,tmsecurrencyfield, + tmsebooleanfield,tmsedatetimefield,tmsedatefield,tmsetimefield, + tmsebinaryfield,tmsebytesfield,tmsevarbytesfield, + tmsebcdfield,tmseblobfield,tmsememofield,tmsegraphicfield, + tmsevariantfield,tmseguidfield, + tfieldparamlink,tfieldlink,ttimestampfieldlink,tfieldfieldlink, + tsequencelink,tdbevent,tparamconnector,tsqlresultconnector, + tdblabel,tdbstringdisp,tdbintegerdisp,tdbbooleandisp, + tdbrealdisp,tdbdatetimedisp, + tdbstringdisplb,tdbintegerdisplb,tdbrealdisplb,tdbdatetimedisplb, + tdbbarcode + ]); + registercomponenttabhints(['DBf'],['Datafield and data display components']); + registerunitgroup(['msesqldb'],['msebufdataset']); + + registerpropertyeditor(typeinfo(tdatalink),nil,'',tdatalinkpropertyeditor); + registerpropertyeditor(typeinfo(tfielddatalink),nil,'', + tfielddatalinkpropertyeditor); + registerpropertyeditor(typeinfo(datasetoptionsty),nil,'', + tdatasetoptionspropertyeditor); + registerpropertyeditor(typeinfo(variant),tmseparam,'value', + tparamvaluepropertyeditor); + registerpropertyeditor(typeinfo(tnolistdropdowncol),nil,'', + tclasspropertyeditor); + registerpropertyeditor(typeinfo(tnolistdropdowncols),nil,'', + tnolistdropdowncolpropertyeditor); + registerpropertyeditor(typeinfo(string),nil,'datafield', + tdbfieldnamepropertyeditor); + registerpropertyeditor(typeinfo(string),nil,'fieldname', + tdbfieldnamepropertyeditor); + registerpropertyeditor(typeinfo(string),tfield,'KeyFields', + tlookupfieldnamepropertyeditor); + registerpropertyeditor(typeinfo(string),tfield,'LookupKeyFields', + tlookupfieldnamepropertyeditor); + registerpropertyeditor(typeinfo(string),tfield,'LookupResultField', + tlookupfieldnamepropertyeditor); + registerpropertyeditor(typeinfo(string),teditwidgetdatalink,'fieldnametext', + tdbfieldnamenocalcpropertyeditor); + registerpropertyeditor(typeinfo(string),tfieldfieldlink,'fieldname', + tdbfieldnamepropertyeditor); + registerpropertyeditor(typeinfo(string),tfieldfieldlink,'destdatafield', + tdbfieldnamenocalcpropertyeditor); + registerpropertyeditor(typeinfo(string),tlookupdbdispfielddatalink, + 'lookupkeyfield',tdbfieldnamenocalcpropertyeditor); + registerpropertyeditor(typeinfo(string),tlookupdbdispfielddatalink, + 'lookupvaluefield',tdbfieldnamenocalcpropertyeditor); + registerpropertyeditor(typeinfo(string),tfieldlink,'destdatafield', + tdbfieldnamepropertyeditor); + registerpropertyeditor(typeinfo(string),tdestfield,'destfieldname', + tdbfieldnamepropertyeditor); + registerpropertyeditor(typeinfo(string),tfieldparamlink,'fieldname', + tdbfieldnamenocalcpropertyeditor); + registerpropertyeditor(typeinfo(string),nil,'keyfield', + tdbfieldnamepropertyeditor); + registerpropertyeditor(typeinfo(string),tgriddatalink,'', + tdbfieldnamepropertyeditor); + registerpropertyeditor(typeinfo(tdbfieldnamearrayprop),nil,'', + tdbfieldnamearraypropertyeditor); + registerpropertyeditor(typeinfo(tdbcolnamearrayprop),nil,'', + tdbcolnamearraypropertyeditor); + registerpropertyeditor(typeinfo(tpersistentfields),nil,'', + tpersistentfieldspropertyeditor); + registerpropertyeditor(typeinfo(string),tfield,'FieldName', + tfieldfieldnamepropertyeditor); + registerpropertyeditor(typeinfo(tcomponent),tfield,'Dataset', + tfielddatasetpropertyeditor); + registerpropertyeditor(typeinfo(string),tfieldparamlink,'paramname', + tdbparamnamepropertyeditor); + registerpropertyeditor(typeinfo(string),tdestparam,'paramname', + tdbparamnamepropertyeditor); + registerpropertyeditor(typeinfo(tdestparams),nil,'', + tslaveparamspropertyeditor); + registerpropertyeditor(typeinfo(tdestfields),nil,'', + tslavefieldspropertyeditor); + registerpropertyeditor(typeinfo(tstrings),nil,'SQL', + tsqlpropertyeditor); + registerpropertyeditor(typeinfo(tsqlstringlist),nil,'', + tmsesqlpropertyeditor); + registerpropertyeditor(typeinfo(tsqlstringlist),nil,'SQLupdate', + tmsesqlnocheckpropertyeditor); + registerpropertyeditor(typeinfo(tsqlstringlist),nil,'SQLinsert', + tmsesqlnocheckpropertyeditor); + registerpropertyeditor(typeinfo(tsqlstringlist),nil,'SQLdelete', + tmsesqlnocheckpropertyeditor); +{ + registerpropertyeditor(typeinfo(tmsestringdatalist),nil,'SQL', + tmsesqlpropertyeditor); + registerpropertyeditor(typeinfo(tstringlist),tsqlquery,'SQLupdate', + tsqlnocheckpropertyeditor); + registerpropertyeditor(typeinfo(tstringlist),tsqlquery,'SQLinsert', + tsqlnocheckpropertyeditor); + registerpropertyeditor(typeinfo(tstringlist),tsqlquery,'SQLdelete', + tsqlnocheckpropertyeditor); +} + registerpropertyeditor(typeinfo(tdataset),nil,'', + tcomponentpropertyeditor); + registerpropertyeditor(typeinfo(tdataset),tfield,'dataset', + tlocalcomponentpropertyeditor); + registerpropertyeditor(typeinfo(lbfiltereventty),tcustomlbdropdownlistcontroller, + 'onfilter',tonfilterpropertyeditor); + registerpropertyeditor(typeinfo(optionslbty),tcustomlbdropdownlistcontroller, + 'optionslb',toptionslbpropertyeditor); + registerpropertyeditor(typeinfo(tfielddefs),tdataset,'', + tfielddefspropertyeditor); + registerpropertyeditor(typeinfo(boolean),tdataset,'Active', + tdatasetactivepropertyeditor); + registerpropertyeditor(typeinfo(boolean),tsqlresult,'active', + tdatasetactivepropertyeditor); + registerpropertyeditor(typeinfo(string),tsqlresultconnector,'colname', + tsqlresconncolnamepropertyeditor); + registerpropertyeditor(typeinfo(tfielddef),nil,'',tfielddefpropertyeditor); + registerpropertyeditor(typeinfo(tparam),nil,'',tdbparampropertyeditor); + registerpropertyeditor(typeinfo(tmseparam),nil,'',tmseparampropertyeditor); + registerpropertyeditor(typeinfo(tdbstringcols),nil,'',tdbstringcolseditor); + registerpropertyeditor(typeinfo(string),tindexfield,'fieldname', + tindexfieldnamepropertyeditor); + registerpropertyeditor(typeinfo(tindexfields),nil,'', + tindexfieldspropertyeditor); + registerpropertyeditor(typeinfo(tlocalindexes),nil,'', + tlocalindexespropertyeditor); + registerpropertyeditor(typeinfo(lookupbufferfieldnoty),nil,'', + tlookupbufferfieldnopropertyeditor); + registerpropertyeditor(typeinfo(tlbdropdowncols),nil,'', + tlbdropdowncolseditor); + registerpropertyeditor(typeinfo(tdbdropdowncols),nil,'', + tdbdropdowncolseditor); +end; + + +{ tnolistdropdowncolpropertyeditor } + +function tnolistdropdowncolpropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tclasspropertyeditor; +end; + +{ tdbparamnamepropertyeditor } + +function tdbparamnamepropertyeditor.getdefaultstate: propertystatesty; +var + obj1: tobject; +begin + result:= inherited getdefaultstate; + if fremote <> nil then begin + obj1:= tobject(tpropertyeditor1(fremote.getparenteditor).getpointervalue); + if obj1 <> nil then begin + getcorbainterface(obj1,typeinfo(idbparaminfo),fdbparaminfointf); + end; + end + else begin + if (high(fprops) = 0) then begin + with fprops[0] do begin + getcorbainterface(instance,typeinfo(idbparaminfo),fdbparaminfointf); + end; + end; + end; + if (fdbparaminfointf <> nil) and (fdbparaminfointf.getdestdataset <> nil) then begin + result:= result + [ps_valuelist,ps_sortlist]; + end; +end; + +function tdbparamnamepropertyeditor.getvalues: msestringarty; +var + int1: integer; +begin + with fdbparaminfointf.getdestdataset.params do begin + for int1:= 0 to count - 1 do begin + additem(result,msestring(items[int1].name)); + end; + end; +end; + +{ tdbfieldnamepropertyeditor } + +function tdbfieldnamepropertyeditor.getdefaultstate: propertystatesty; +var + obj1: tobject; + ar1: stringarty; + ar2: fieldtypesarty; + int1,int2: integer; +begin + result:= inherited getdefaultstate; + if (high(fprops) = 0) then begin + with fprops[0] do begin + getcorbainterface(instance,typeinfo(idbeditinfo),fdbeditinfointf); + end; + end; + if (fdbeditinfointf = nil) and (fremote <> nil) then begin + obj1:= tobject(tpropertyeditor1(fremote.getparenteditor).getpointervalue); + if obj1 <> nil then begin + getcorbainterface(obj1,typeinfo(idbeditinfo),fdbeditinfointf); + end; + end; + if fdbeditinfointf <> nil then begin + fdbeditinfointf.getfieldtypes(ar1,ar2); + int2:= 0; + for int1:= 0 to high(ar1) do begin + if msestring(ar1[int1]) = name then begin + int2:= int1; + break; + end; + end; + if fdbeditinfointf.getdataset(int2) <> nil then begin + result:= result + [ps_valuelist,ps_sortlist]; + end; + end; +end; + +function tdbfieldnamepropertyeditor.getvalues: msestringarty; +var + propertynames: stringarty; + fieldtypes: fieldtypesarty; + ft: fieldtypesty; + int1,int2: integer; + ds: tdataset; + +begin + result:= nil; + if (fdbeditinfointf <> nil) then begin + int2:= 0; + fdbeditinfointf.getfieldtypes(propertynames,fieldtypes); + if high(propertynames) >= 0 then begin + for int1:= 0 to high(propertynames) do begin + if msestring(propertynames[int1]) = fname then begin + int2:= int1; + break; + end; + end; + end; + if int2 <= high(fieldtypes) then begin + ft:= fieldtypes[int2]; + end + else begin + ft:= []; + end; + ds:= fdbeditinfointf.getdataset(int2); + if ds <> nil then begin + if ds.active or (ds.fields.count > 0) then begin + for int1:= 0 to ds.fields.count -1 do begin + with ds.fields[int1] do begin + if ((ft = []) or (datatype = ftunknown) or (datatype in ft)) and + (not fnocalc or (fieldkind <> fkcalculated)) then begin + additem(result,msestring(fieldname)); + end; + end; + end; + end + else begin + for int1:= 0 to ds.fielddefs.count -1 do begin + with ds.fielddefs[int1] do begin + if (ft = []) or (datatype = ftunknown) or (datatype in ft) then begin + additem(result,msestring(name)); + end; + end; + end; + end; + end; + end; +end; + +{ tdbcolnamepropertyeditor } + +function tdbcolnamepropertyeditor.getdefaultstate: propertystatesty; +var + sqlresult1: tsqlresult; + obj1: tobject; + ar1: stringarty; + ar2: fieldtypesarty; + int1,int2: integer; +begin + result:= inherited getdefaultstate; + if fremote <> nil then begin + obj1:= tobject(tpropertyeditor1(fremote.getparenteditor).getpointervalue); + if obj1 <> nil then begin + getcorbainterface(obj1,typeinfo(idbcolinfo),fdbcolinfointf); + end; + end + else begin + if (high(fprops) = 0) then begin + with fprops[0] do begin + getcorbainterface(instance,typeinfo(idbcolinfo),fdbcolinfointf); + end; + end; + end; + if fdbcolinfointf <> nil then begin + fdbcolinfointf.getfieldtypes(ar1,ar2); + int2:= 0; + for int1:= 0 to high(ar1) do begin + if msestring(ar1[int1]) = name then begin + int2:= int1; + break; + end; + end; + sqlresult1:= fdbcolinfointf.getsqlresult(int2); + if (sqlresult1 <> nil) {and (sqlresult1.active)} then begin + result:= result + [ps_valuelist,ps_sortlist]; + end; + end; +end; + +function tdbcolnamepropertyeditor.getvalues: msestringarty; +var + propertynames: stringarty; + fieldtypes: fieldtypesarty; + ft: fieldtypesty; + int1,int2: integer; + sqlresult1: tsqlresult; + +begin + result:= nil; + if (fdbcolinfointf <> nil) then begin + int2:= 0; + fdbcolinfointf.getfieldtypes(propertynames,fieldtypes); + if high(propertynames) >= 0 then begin + for int1:= 0 to high(propertynames) do begin + if msestring(propertynames[int1]) = fname then begin + int2:= int1; + break; + end; + end; + end; + if int2 <= high(fieldtypes) then begin + ft:= fieldtypes[int2]; + end + else begin + ft:= []; + end; + sqlresult1:= fdbcolinfointf.getsqlresult(int2); + if sqlresult1 <> nil then begin + if {sqlresult1.active or} (sqlresult1.datacols.count > 0) then begin + for int1:= 0 to sqlresult1.datacols.count -1 do begin + with sqlresult1.cols[int1] do begin + if (ft = []) or (datatype = ftunknown) or (datatype in ft) then begin + additem(result,msestring(fieldname)); + end; + end; + end; + end + else begin + if sqlresult1.fielddefs.count > 0 then begin + for int1:= 0 to sqlresult1.fielddefs.count -1 do begin + with sqlresult1.fielddefs[int1] do begin + if (ft = []) or (datatype = ftunknown) or (datatype in ft) then begin + additem(result,msestring(name)); + end; + end; + end; + end + end; + end; + end; +end; + +{ tdbfieldnamearraypropertyeditor } + +function tdbfieldnamearraypropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tdbfieldnamepropertyeditor; +end; + +{ tdbcolnamearraypropertyeditor } + +function tdbcolnamearraypropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tdbcolnamepropertyeditor; +end; + +{ tpersistentfieldelementeditor } + +function tpersistentfieldelementeditor.getvalue: msestring; +begin + result:= msestring('<'+tfield(getpointervalue).fieldname+'>') + + inherited getvalue; +end; + +{ tpersistentfieldspropertyeditor } + +function tpersistentfieldspropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tpersistentfieldelementeditor; +end; + +function tpersistentfieldspropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_noadditems,ps_dialog]; +end; + +procedure tpersistentfieldspropertyeditor.edit; +begin + if editpersistentfields(tpersistentfields(getpointervalue)) then begin + modified; + end; +end; + +{ tfieldfieldnamepropertyeditor } + +function tfieldfieldnamepropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_valuelist,ps_sortlist]; +end; + +function tfieldfieldnamepropertyeditor.getvalues: msestringarty; +var + ds: tdataset; + int1,int2: integer; + ar1,ar2,ar3: stringarty; + intf: ipersistentfieldsinfo; + fclass: tclass; +begin + result:= nil; + ds:= tfield(fprops[0].instance).dataset; + if ds <> nil then begin + setlength(ar1,ds.fielddefs.count); + setlength(ar3,length(ar1)); + for int1:= 0 to high(ar1) do begin + ar3[int1]:= ds.fielddefs[int1].name; + ar1[int1]:= uppercase(ar3[int1]); + end; + setlength(ar2,ds.fields.count); + for int1:= 0 to high(ar2) do begin + ar2[int1]:= uppercase(ds.fields[int1].fieldname); + end; + for int1:= 0 to high(ar1) do begin + for int2:= 0 to high(ar2) do begin + if ar1[int1] = ar2[int2] then begin + ar1[int1]:= ''; + break; + end; + end; + end; + if getcorbainterface(fprops[0].instance, + typeinfo(ipersistentfieldsinfo),intf) then begin + ar2:= intf.getfieldnames; + for int1:= 0 to high(ar2) do begin + ar2[int1]:= uppercase(ar2[int1]); + end; + for int1:= 0 to high(ar1) do begin + for int2:= 0 to high(ar2) do begin + if ar1[int1] = ar2[int2] then begin + ar1[int1]:= ''; + break; + end; + end; + end; + end; + fclass:= tfield(fprops[0].instance).classtype; + for int1:= 0 to high(ar1) do begin + if (ar1[int1] <> '') and + (fclass.inheritsfrom(ds.fielddefs[int1].fieldclass) or + (fclass.inheritsfrom(tmsebooleanfield)) and + (ds.fielddefs[int1].fieldclass.inheritsfrom(tlongintfield))) then begin + additem(result,msestring(ar3[int1])); + end; + end; + end; +end; + +procedure tfieldfieldnamepropertyeditor.setvalue(const value: msestring); +var + ds: tdataset; +begin + ds:= tfield(fprops[0].instance).dataset; + if (ds <> nil) and (ds.findfield(ansistring(value)) <> nil) then begin + raise exception.create('Field '''+ansistring(value)+ + ''' exists in '+ds.name+'.'); + end; + inherited; +end; + +{ tfielddatasetpropertyeditor } + +procedure tfielddatasetpropertyeditor.checkcomponent(const avalue: tcomponent); +var + str1: string; +begin + if avalue is tdataset then begin + str1:= tfield(fprops[0].instance).fieldname; + with tdataset(avalue) do begin + if findfield(str1) <> nil then begin + raise exception.create('Field '''+str1+''' exists in '+name+'.'); + end; + end; + end; +end; + +const + sqlsyntax = +'caseinsensitive'+lineend+ +'styles'+lineend+ +' default '''''+lineend+ +' words ''b'''+lineend+ +' comment ''i'' cl_dkblue'+lineend+ +' option ''b'' cl_dkblue'+lineend+ +' string '''' cl_dkblue'+lineend+ +' '+lineend+ +'keyworddefs sql'+lineend+ +' ''ACTION'' ''ACTIVE'' ''ADD'' ''ADMIN'' ''AFTER'' ''ALL'' ''ALTER'' ''AND'''+lineend+ +' ''ANY'' ''AS'' ''ASC'''+lineend+ +' ''ASCENDING'' ''AT'' ''AUTO'' ''AUTODDL'''+lineend+ +' ''AVG'' ''BASED'' ''BASENAME'' ''BASE_NAME'' ''BEFORE'' ''BEGIN'' ''BETWEEN'''+lineend+ +' ''BLOB'' '+lineend+ +' ''BLOBEDIT'' ''BUFFER'' ''BY'' ''CACHE'''+lineend+ +' ''CASCADE'' ''CASE'' ''CAST'' ''CHAR'' ''CHARACTER'' ''CHARACTER_LENGTH'''+lineend+ +' ''CHAR_LENGTH'' ''CHECK'' '+lineend+ +' ''CHECK_POINT_LEN'''+lineend+ +' ''CHECK_POINT_LENGTH'' ''COLLATE'' ''COLLATION'' ''COLUMN'' ''COMMIT'''+lineend+ +' ''COMMITTED'' '+lineend+ +' ''COMPILETIME'''+lineend+ +' ''COMPUTED'' ''CLOSE'' ''CONDITIONAL'' ''CONNECT'' ''CONSTRAINT'''+lineend+ +' ''CONTAINING'' ''CONTINUE'' '+lineend+ +' ''COUNT'' ''CREATE'''+lineend+ +' ''CSTRING'' ''CURRENT'' ''CURRENT_DATE'' ''CURRENT_TIME'''+lineend+ +' ''CURRENT_TIMESTAMP'' ''CURSOR'''+lineend+ +' ''DATABASE'' ''DATE'' ''DAY'' ''DB_KEY'' ''DEBUG'' ''DEC'' ''DECIMAL'''+lineend+ +' ''DECLARE'' ''DEFAULT'' '+lineend+ +' ''DELETE'' ''DESC'' ''DESCENDING'''+lineend+ +' ''DESCRIBE'' ''DESCRIPTOR'' ''DISCONNECT'' ''DISPLAY'' ''DISTINCT'' ''DO'''+lineend+ +' ''DOMAIN'' '+lineend+ +' ''DOUBLE'' ''DROP'''+lineend+ +' ''ECHO'' ''EDIT'' ''ELSE'' ''END'' ''ENTRY_POINT'' ''ESCAPE'' ''EVENT'''+lineend+ +' ''EXCEPTION'' ''EXECUTE'''+lineend+ +' ''EXISTS'' ''EXIT'' ''EXTERN'' ''EXTERNAL'' ''EXTRACT'' ''FETCH'' ''FILE'''+lineend+ +' ''FILTER'' ''FLOAT'' '+lineend+ +' ''FOR'' ''FOREIGN'' ''FOUND'''+lineend+ +' ''FREE_IT'' ''FROM'' ''FULL'' ''FUNCTION'' ''GDSCODE'' ''GENERATOR'''+lineend+ +' ''GEN_ID'' ''GLOBAL'' '+lineend+ +' ''GOTO'''+lineend+ +' ''GRANT'' ''GROUP'' ''GROUP_COMMIT_WAIT'' ''GROUP_COMMIT_'' ''WAIT_TIME'''+lineend+ +' ''HAVING'' ''HELP'' '+lineend+ +' ''HOUR'' ''IF'''+lineend+ +' ''IMMEDIATE'' ''IN'' ''INACTIVE'' ''INDEX'' ''INDICATOR'' ''INIT'' ''INNER'''+lineend+ +' ''INPUT'' '+lineend+ +' ''INPUT_TYPE'''+lineend+ +' ''INSERT'' ''INT'' ''INTEGER'' ''INTO'' ''IS'' ''ISOLATION'' ''ISQL'''+lineend+ +' ''JOIN'' ''KEY'' '+lineend+ +' ''LC_MESSAGES'' ''LC_TYPE'' ''LEFT'''+lineend+ +' ''LENGTH'' ''LEV'' ''LEVEL'' ''LIKE'' ''LIMIT'''+lineend+ +' ''LOGFILE'' ''LOG_BUFFER_SIZE'''+lineend+ +' ''LOG_BUF_SIZE'' '+lineend+ +' ''LONG'' ''MANUAL'''+lineend+ +' ''MAX'' ''MAXIMUM'' ''MAXIMUM_SEGMENT'' ''MAX_SEGMENT'' ''MERGE'''+lineend+ +' ''MESSAGE'' ''MIN'' '+lineend+ +' ''MINIMUM'' ''MINUTE'''+lineend+ +' ''MODULE_NAME'' ''MONTH'' ''NAMES'' ''NATIONAL'' ''NATURAL'' ''NCHAR'''+lineend+ +' ''NO'' ''NOAUTO'' '+lineend+ +' ''NOT'''+lineend+ +' ''NULL'' ''NUMERIC'' ''NUM_LOG_BUFS'' ''NUM_LOG_BUFFERS'' ''OCTET_LENGTH'''+lineend+ +' ''OF'' ''ON'' '+lineend+ +' ''ONLY'' ''OPEN'''+lineend+ +' ''OPTION'' ''OR'' ''ORDER'' ''OUTER'' ''OUTPUT'' ''OUTPUT_TYPE'' ''OVERFLOW'''+lineend+ +' ''PAGE'' '+lineend+ +' ''PAGELENGTH'''+lineend+ +' ''PAGES'' ''PAGE_SIZE'' ''PARAMETER'' ''PASSWORD'' ''PLAN'' ''POSITION'''+lineend+ +' ''POST_EVENT'' '+lineend+ +' ''PRECISION'' ''PREPARE'''+lineend+ +' ''PROCEDURE'' ''PROTECTED'' ''PRIMARY'' ''PRIVILEGES'' ''PUBLIC'' ''QUIT'''+lineend+ +' ''RAW_PARTITIONS'' ''RDB$DB_KEY'' ''READ'' ''REAL'' ''RECORD_VERSION'''+lineend+ +' ''REFERENCES'''+lineend+ +' ''RELEASE'' ''RESERV'' ''RESERVING'' ''RESTRICT'' ''RETAIN'' ''RETURN'''+lineend+ +' ''RETURNING_VALUES'' ''RETURNS'' ''REVOKE'' ''RIGHT'' ''ROLE'' ''ROLLBACK'''+lineend+ +' ''RUNTIME'' '+lineend+ +' ''SCHEMA'' ''SECOND'''+lineend+ +' ''SEGMENT'' ''SELECT'' ''SET'' ''SHADOW'' ''SHARED'' ''SHELL'' ''SHOW'''+lineend+ +' ''SINGULAR'' ''SIZE'''+lineend+ +' ''SMALLINT'' ''SNAPSHOT'' ''SOME'' ''SORT'' ''SQLCODE'' ''SQLERROR'''+lineend+ +' ''SQLWARNING'' '+lineend+ +' ''STABILITY'' ''STARTING'''+lineend+ +' ''STARTS'' ''STATEMENT'' ''STATIC'' ''STATISTICS'' ''SUB_TYPE'' ''SUM'''+lineend+ +' ''SUSPEND'' '+lineend+ +' ''TABLE'' ''TERMINATOR'''+lineend+ +' ''THEN'' ''TIME'' ''TIMESTAMP'' ''TO'' ''TRANSACTION'' ''TRANSLATE'''+lineend+ +' ''TRANSLATION'' '+lineend+ +' ''TRIGGER'' ''TRIM'''+lineend+ +' ''TYPE'' ''UNCOMMITTED'' ''UNION'' ''UNIQUE'' ''UPDATE'' ''UPPER'' ''USER'''+lineend+ +' ''USING'' '+lineend+ +' ''VALUE'+lineend+ +' ''VALUES'' ''VARCHAR'' ''VARIABLE'' ''VARYING'' ''VERSION'' ''VIEW'' ''WAIT'''+lineend+ +' ''WEEKDAY'' '+lineend+ +' ''WHEN'''+lineend+ +' ''WHENEVER'' ''WHERE'' ''WHILE'' ''WITH'' ''WORK'' ''WRITE'' ''YEAR'''+lineend+ +' ''YEARDAY'''+lineend+ +''+lineend+ +'scope comment1 comment'+lineend+ +' endtokens'+lineend+ +' ''*/'''+lineend+ +' '+lineend+ +'scope comment2 comment'+lineend+ +' endtokens'+lineend+ +' '''''+lineend+ +' '+lineend+ +'scope string string'+lineend+ +' endtokens'+lineend+ +' '''''''' '''''+lineend+ +' '+lineend+ +'scope main'+lineend+ +''+lineend+ +' keywords words'+lineend+ +' sql'+lineend+ +' calltokens'+lineend+ +' ''/*'' comment1'+lineend+ +' ''--'' comment2'+lineend+ +' '''''''' string'+lineend; + +var + sqlindex: integer = -1; + +{ tsqlpropertyeditor } + +function tsqlpropertyeditor.getsyntaxindex: integer; +begin + if sqlindex < 0 then begin + sqlindex:= msetexteditor.syntaxpainter.readdeffile(sqlsyntax); + end; + result:= sqlindex; +end; + +procedure tsqlpropertyeditor.doafterclosequery( + var amodalresult: modalresultty); +begin + if amodalresult = mr_canclose then begin + if fintf <> nil then begin + fintf.setactive(true); + if not factivebefore then begin + fintf.setactive(false); //avoid exception by empty original statement + end; + end; + end; +end; + +function tsqlpropertyeditor.gettestbutton: boolean; +begin + result:= fintf <> nil; +end; + +function tsqlpropertyeditor.getutf8: boolean; +begin + result:= (fintf <> nil) and fintf.isutf8; +end; + +procedure tsqlpropertyeditor.edit; +begin + if not nocheck and getcorbainterface(fprops[0].instance, + typeinfo(isqlpropertyeditor),fintf) then begin + factivebefore:= fintf.getactive; + fdbactivebefore:= (fintf.getdatabase() = nil) or + fintf.getdatabase.connected; + end + else begin + fintf:= nil; + end; + inherited; + if fintf <> nil then begin + if not factivebefore then begin + fintf.setactive(false); + end; + if not fdbactivebefore and (fintf.getdatabase <> nil) then begin + fintf.getdatabase.connected:= false; + end; + end; +end; + +function tsqlpropertyeditor.getcaption: msestring; +begin + result:= 'SQL Editor'; +end; + +function tsqlpropertyeditor.nocheck: boolean; +begin + result:= false; +end; + +{ tmsesqlpropertyeditor } + +function tmsesqlpropertyeditor.ismsestring: boolean; +begin + result:= true; +end; + +{ tsqlnocheckpropertyeditor } + +function tsqlnocheckpropertyeditor.nocheck: boolean; +begin + result:= true; +end; + +{ tmsesqlnocheckpropertyeditor } + +function tmsesqlnocheckpropertyeditor.nocheck: boolean; +begin + result:= true; +end; + +{ tonfilterpropertyeditor } + +function tonfilterpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_volatile]; +end; + +procedure tonfilterpropertyeditor.setvalue(const value: msestring); + +begin + inherited; + with tcustomlbdropdownlistcontroller(fprops[0].instance) do begin + if not (olb_copyitems in optionslb) then begin + if getmethodvalue.data <> nil then begin + if buttonlength = 0 then begin + buttonlength:= -1; + end; + end + else begin + if buttonlength = -1 then begin + buttonlength:= 0; + end; + end; + end; + end; +end; + +procedure checkonfilter(const acontroller: tcustomlbdropdownlistcontroller; + const optbefore: optionslbty); +begin + with acontroller do begin + if (olb_copyitems in (optbefore >< optionslb)) and + (tmethod(onfilter).data <> nil) then begin + if olb_copyitems in optbefore then begin + if buttonlength = 0 then begin + buttonlength:= -1; + end; + end + else begin + if buttonlength = -1 then begin + buttonlength:= 0; + end; + end; + end; + end; +end; + +{ toptionlbpropertyeditor } + +function toptionlbpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_volatile]; +end; + +procedure toptionlbpropertyeditor.setvalue(const value: msestring); +var + opt1: optionslbty; + cont1: tcustomlbdropdownlistcontroller; +begin + cont1:= tcustomlbdropdownlistcontroller(fprops[0].instance); + opt1:= cont1.optionslb; + inherited; + checkonfilter(cont1,opt1); +end; + +{ toptionslbpropertyeditor } + +constructor toptionslbpropertyeditor.create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypeinfo: ptypeinfo); +begin + felementeditorclass:= toptionlbpropertyeditor; + inherited; +end; + +function toptionslbpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_volatile]; +end; + +procedure toptionslbpropertyeditor.setvalue(const value: msestring); +var + opt1: optionslbty; + cont1: tcustomlbdropdownlistcontroller; +begin + cont1:= tcustomlbdropdownlistcontroller(fprops[0].instance); + opt1:= cont1.optionslb; + inherited; + checkonfilter(cont1,opt1); +end; + +{ tfielddefspropertyeditor } + +procedure tfielddefspropertyeditor.setvalue(const value: msestring); +var + int1: integer; +begin + for int1:= 0 to high(fprops) do begin + tdataset(fprops[int1].instance).active:= false; + end; + inherited; +end; + +{ tdatasetactivepropertyeditor } + +function tdatasetactivepropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_volatile]; +end; + +{ tfielddefpropertyeditor } + +function tfielddefpropertyeditor.getvalue: msestring; +begin + with tfielddef(fprops[0].instance) do begin + result:= msestring('<'+name+'><'+ + getenumname(typeinfo(tfieldtype),ord(datatype))+'>'); + end; +end; + +{ tdbparampropertyeditor } + +function tdbparampropertyeditor.getvalue: msestring; +begin + with tparam(fprops[0].instance) do begin + result:= msestring('<'+name+'><'+ + getenumname(typeinfo(tfieldtype),ord(datatype)))+ + {'><'+getenumname(typeinfo(tparamtype),ord(paramtype))+}'>'; + end; +end; + +{ tmseparampropertyeditor } + +function tmseparampropertyeditor.getvalue: msestring; +begin + with tmseparam(fprops[0].instance) do begin + result:= msestring('<'+name+'><'+fieldname+'><'); + if connector <> nil then begin + result:= result+msestring(connector.name); + end; + result:= result+'>'; + end; +end; + +{ tdbstringcoleditor } + +function tdbstringcoleditor.getvalue: msestring; +begin + result:= inherited getvalue + + msestring('<'+tdbstringcol(getpointervalue).datafield+'>'); +end; + +{ tdbstringcolseditor } + +function tdbstringcolseditor.geteditorclass: propertyeditorclassty; +begin + result:= tdbstringcoleditor; +end; + +{ tindexfieldnamepropertyeditor } + +function tindexfieldnamepropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_valuelist,ps_sortlist]; +end; + +function tindexfieldnamepropertyeditor.getvalues: msestringarty; +var + int1: integer; +begin + result:= nil; + if high(fprops) = 0 then begin + with tmsebufdataset(fcomponent) do begin + if active or (fields.count > 0) then begin + for int1:= 0 to fields.count -1 do begin + with fields[int1] do begin + if (datatype in indexfieldtypes) and + (fieldkind in [fkdata,fkinternalcalc,fklookup]) then begin + additem(result,msestring(fieldname)); + end; + end; + end; + end + else begin + for int1:= 0 to fielddefs.count -1 do begin + with fielddefs[int1] do begin + if (datatype in indexfieldtypes) then begin + additem(result,msestring(name)); + end; + end; + end; + end; + end; + end; +end; + +{ tindexfieldpropertyeditor } + +function tindexfieldpropertyeditor.getvalue: msestring; +begin + result:= msestring('<'+tindexfield(getpointervalue).fieldname+'>'); +end; + +function tindexfieldpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_refresh] +end; + +{ tindexfieldspropertyeditor } + +function tindexfieldspropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tindexfieldpropertyeditor; +end; + +{ tlocalindexpropertyeditor } + +function tlocalindexpropertyeditor.getvalue: msestring; +var + int1: integer; +begin + with tlocalindex(getpointervalue),fields do begin + result:= msestring('<'+name+'><'); + if count > 0 then begin + for int1:= 0 to count - 1 do begin + result:= result + msestring(items[int1].fieldname+','); + end; + setlength(result,length(result)-1); + end; + end; + result:= result + '>'; +end; + +function tlocalindexpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_refresh]; +end; + +{ tlocalindexespropertyeditor } + +function tlocalindexespropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tlocalindexpropertyeditor; +end; + +{ tdbfieldnamenocalcpropertyeditor } + +constructor tdbfieldnamenocalcpropertyeditor.create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypeinfo: ptypeinfo); +begin + fnocalc:= true; + inherited; +end; + +{ tlookupbufferfieldnopropertyeditor } + +constructor tlookupbufferfieldnopropertyeditor.create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypeinfo: ptypeinfo); +begin + getcorbainterface(aprops[0].instance,typeinfo(ilookupbufferfieldinfo),fintf); + if fintf <> nil then begin + flbdatakind:= fintf.getlbdatakind(aprops[0].propinfo^.name); + if fintf.getlookupbuffer = nil then begin + flbdatakind:= lbdk_none; + end; + end; + inherited; +end; + +function tlookupbufferfieldnopropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate; + if flbdatakind <> lbdk_none then begin + result:= result + [ps_valuelist,ps_sortlist]; + end; +end; + +function tlookupbufferfieldnopropertyeditor.getnames: msestringarty; +var + lb1: tcustomlookupbuffer; + ar1: stringarty; + int1: integer; +begin + ar1:= nil; + if fintf <> nil then begin + lb1:= fintf.getlookupbuffer; + if lb1 <> nil then begin + case flbdatakind of + lbdk_integer: begin + ar1:= lb1.fieldnamesinteger; + end; + lbdk_int64: begin + ar1:= lb1.fieldnamesint64; + end; + lbdk_float: begin + ar1:= lb1.fieldnamesfloat; + end; + lbdk_text: begin + ar1:= lb1.fieldnamestext; + end; + end; + end; + end; + setlength(result,length(ar1)); + for int1:= 0 to high(ar1) do begin + result[int1]:= msestring(ar1[int1]); + end; +end; + +function tlookupbufferfieldnopropertyeditor.getvalues: msestringarty; +begin + result:= getnames; +end; + +procedure tlookupbufferfieldnopropertyeditor.setvalue(const value: msestring); +var + ar1: msestringarty; + int1: integer; +begin + if value <> '' then begin + ar1:= getnames; + for int1:= 0 to high(ar1) do begin + if value = ar1[int1] then begin + setordvalue(int1); + exit; + end; + end; + end; + inherited; +end; + +function tlookupbufferfieldnopropertyeditor.getvalue: msestring; +var + ar1: msestringarty; + int1: integer; +begin + result:= inherited getvalue; + if fintf <> nil then begin + int1:= getordvalue; + ar1:= getnames; + if (int1 >= 0) and (int1 <= high(ar1)) then begin + result:= result+'<'+ar1[int1]+'>'; + end + else begin + result:= result+'<>'; + end; + end; +end; + +{ tlbdropdowncolitemeditor } +{ +function tlbdropdowncolitemeditor.getvalue: msestring; +var + lb1: tcustomlookupbuffer; + ar1: stringarty; +begin + result:= '<>'; + with tlbdropdowncol1(getpointervalue) do begin + lb1:= getlookupbuffer; + if lb1 <> nil then begin + ar1:= lb1.fieldnamestext; + if (fieldno >= 0) and (fieldno <= high(ar1)) then begin + result:= '<'+ar1[fieldno]+'>'; + end; + end; + end; +end; +} +{ tlbdropdowncolseditor } +{ +function tlbdropdowncolseditor.geteditorclass: propertyeditorclassty; +begin + result:= tlbdropdowncolitemeditor; +end; +} +function tlbdropdowncolseditor.itemgetvalue( + const sender: tarrayelementeditor): msestring; +var + lb1: tcustomlookupbuffer; + ar1: stringarty; +begin + result:= '<>'; + with tlbdropdowncol1(tarrayelementeditor1(sender).getpointervalue) do begin + lb1:= getlookupbuffer; + if lb1 <> nil then begin + ar1:= lb1.fieldnamestext; + if (fieldno >= 0) and (fieldno <= high(ar1)) then begin + result:= msestring('<'+ar1[fieldno]+'>'); + end; + end; + end; +end; + +{ tdbdropdowncolitemeditor } +{ +function tdbdropdowncolitemeditor.getvalue: msestring; +begin + result:= '<'+tdbdropdowncol(getpointervalue).datafield+'>'; +end; +} +{ tdbdropdowncolseditor } +{ +function tdbdropdowncolseditor.geteditorclass: propertyeditorclassty; +begin + result:= tdbdropdowncolitemeditor; +end; +} +function tdbdropdowncolseditor.itemgetvalue( + const sender: tarrayelementeditor): msestring; +begin + result:= msestring('<'+tdbdropdowncol( + tarrayelementeditor1(sender).getpointervalue).datafield+'>'); +end; + +{ tparamvaluepropertyeditor } + +procedure tparamvaluepropertyeditor.setvalue(const value: msestring); +var + var1: variant; +begin + fillchar(var1,sizeof(var1),0); + if value = '' then begin + setvariantvalue(var1); + end + else begin + var1:= value; + case tmseparam(instance).datatype of + ftBoolean: setvariantvalue(boolean(var1)); + ftsmallint: setvariantvalue(word(var1)); + ftinteger: setvariantvalue(integer(var1)); +{$ifdef FPC} + ftlargeint: setvariantvalue(int64(var1)); +{$else} + ftlargeint: setvariantvalue(integer(var1)); +{$endif} + ftcurrency: setvariantvalue(currency(var1)); + ftfloat: setvariantvalue(double(var1)); + ftdatetime: setvariantvalue(tdatetime(var1)); + else begin + setvariantvalue(value); + end; + end; + end; +end; + +{ tslaveparampropertyeditor } +{ +function tslaveparampropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate+[ps_refresh]; +end; + +function tslaveparampropertyeditor.getvalue: msestring; +begin + with tdestparam(getpointervalue) do begin + result:= '<'; + if datasource <> nil then begin + result:= result + datasource.name; + end; + result:= result+'.'+fieldname+'>'+'<'+paramname+'>'; + end; +end; +} +{ tslaveparamspropertyeditor } +{ +function tslaveparamspropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tslaveparampropertyeditor; +end; +} +function tslaveparamspropertyeditor.itemgetvalue( + const sender: tarrayelementeditor): msestring; +begin + with tdestparam(tarrayelementeditor1(sender).getpointervalue) do begin + result:= '<'; + if datasource <> nil then begin + result:= result + msestring(datasource.name); + end; + result:= result+msestring('.'+fieldname+'>'+'<'+paramname+'>'); + end; +end; + +function tslaveparamspropertyeditor.itemgetdefaultstate( + const sender: tarrayelementeditor): propertystatesty; +begin + result:= inherited itemgetdefaultstate(sender)+[ps_refresh]; +end; + +{ tslavefieldspropertyeditor } + +function tslavefieldspropertyeditor.itemgetdefaultstate( + const sender: tarrayelementeditor): propertystatesty; +begin + result:= inherited itemgetdefaultstate(sender)+[ps_refresh]; +end; + +function tslavefieldspropertyeditor.itemgetvalue( + const sender: tarrayelementeditor): msestring; +begin + with tdestfield(tarrayelementeditor1(sender).getpointervalue) do begin + result:= '<'; + if datasource <> nil then begin + result:= result + msestring(datasource.name); + end; + result:= result+msestring('.'+fieldname+'>'+'<'+destfieldname+'>'); + end; +end; + +{ tsqlmacroitemeditor } +{ +function tsqlmacroitemeditor.getvalue: msestring; +begin + with tsqlmacroitem(getpointervalue) do begin + result:= '<'+name+'>'; + end; +end; +} +{ +function tsqlmacroseditor.geteditorclass: propertyeditorclassty; +begin + result:= tsqlmacroitemeditor; +end; +} +{ tlookupfieldnamepropertyeditor } + +function tlookupfieldnamepropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_valuelist,ps_sortlist]; +end; + +function getfieldnames(const adataset: tdataset): msestringarty; +var + int1: integer; +begin + result:= nil; + if adataset <> nil then begin + with adataset.fields do begin + setlength(result,count); + for int1:= 0 to high(result) do begin + result[int1]:= msestring(fields[int1].fieldname); + end; + end; + if result = nil then begin + with adataset.fielddefs do begin + setlength(result,count); + for int1:= 0 to high(result) do begin + result[int1]:= msestring(items[int1].name); + end; + end; + end; + end; +end; + +function tlookupfieldnamepropertyeditor.getvalues: msestringarty; +begin + result:= nil; + if name = 'KeyFields' then begin + result:= getfieldnames(tfield(instance).dataset); + end + else begin + result:= getfieldnames(tfield(instance).lookupdataset); + end; +end; + +{ tdatasetoptionspropertyeditor } + +function tdatasetoptionspropertyeditor.getinvisibleitems: tintegerset; +begin + result:= tintegerset(card32([dso_refreshwaitcursor]+deprecatedbdsoptions)); +end; + +{ tdatalinkpropertyeditor } + +function tdatalinkpropertyeditor.getvalue: msestring; +var + inst: tdatalink; +begin + inst:= tdatalink(getpointervalue()); + if (inst <> nil) and (inst.datasource <> nil) then begin + result:= '<'+getcomponentpropname(inst.datasource)+'>'; + end + else begin + result:= inherited getvalue; + end; +end; + +{ tfielddatalinkpropertyeditor } + +function tfielddatalinkpropertyeditor.getvalue: msestring; +var + inst: tfielddatalink; +begin + inst:= tfielddatalink(getpointervalue()); + result:= inherited getvalue(); + if inst.fieldname <> '' then begin + result:= '<'+msestring(inst.fieldname)+'>'+result; + end; +end; + +{ tsqlresconncolnamepropertyeditor } + +function tsqlresconncolnamepropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate; + with tsqlresultconnector(fcomponent) do begin + if source <> nil then begin + result:= result + [ps_valuelist,ps_sortlist]; + end; + end; +end; + +function tsqlresconncolnamepropertyeditor.getvalues: msestringarty; +var + i1: int32; +begin + result:= nil; + with tsqlresultconnector(fcomponent) do begin + if source <> nil then begin + with source do begin + setlength(result,fielddefs.count); + for i1:= 0 to high(result) do begin + result[i1]:= msestring(fielddefs[i1].name); + end; + end; + end; + end; +end; + +initialization + register; +end. diff --git a/mseide-msegui/lib/common/regcomponents/regdb_bmp.pas b/mseide-msegui/lib/common/regcomponents/regdb_bmp.pas new file mode 100644 index 0000000..1c5eb78 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regdb_bmp.pas @@ -0,0 +1,9441 @@ +unit regdb_bmp; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msebitmap; + +const + objdata_tlocaldataset: record size: integer; data: array[0..1972] of byte end = + (size: 1973; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,108,111, + 99,97,108,100,97,116,97,115,101,116,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,60,7,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,248,6,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,132,255,255,1,135,255,255,1,138, + 255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,152, + 255,255,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166, + 255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1,180, + 255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194, + 255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1,140, + 255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,152,255,255,1,155, + 255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169, + 255,255,1,172,255,255,1,174,255,255,1,177,255,255,1,180,255,255,1,183, + 255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,197, + 255,255,1,132,255,255,1,135,255,255,1,138,255,255,1,0,0,0,1,143, + 255,255,1,146,255,255,1,149,255,255,1,152,255,255,1,145,238,238,1,43, + 70,70,1,6,9,9,1,49,76,76,1,157,241,241,1,169,255,255,1,172, + 255,255,1,166,243,243,1,60,87,87,1,7,10,10,1,30,42,42,1,157, + 215,215,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,132, + 255,255,1,135,255,255,1,138,255,255,1,0,0,0,1,143,255,255,1,146, + 255,255,1,149,255,255,1,152,255,255,1,63,103,103,1,90,146,146,1,156, + 249,249,1,102,159,159,1,71,109,109,1,169,255,255,1,172,255,255,1,74, + 109,109,1,126,181,181,1,177,251,251,1,105,146,146,1,43,59,59,1,189, + 255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1,135, + 255,255,1,138,255,255,1,0,0,0,1,143,255,255,1,146,255,255,1,149, + 255,255,1,152,255,255,1,15,25,25,1,148,240,240,1,160,255,255,1,148, + 232,232,1,19,29,29,1,169,255,255,1,172,255,255,1,18,26,26,1,158, + 228,228,1,180,255,255,1,180,251,251,1,149,204,204,1,189,255,255,1,191, + 255,255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,138, + 255,255,1,0,0,0,1,143,255,255,1,146,255,255,1,149,255,255,1,152, + 255,255,1,2,3,3,1,156,254,254,1,160,255,255,1,161,252,252,1,3, + 5,5,1,169,255,255,1,172,255,255,1,3,5,5,1,175,252,252,1,180, + 255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194, + 255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1,0, + 0,0,1,143,255,255,1,146,255,255,1,149,255,255,1,152,255,255,1,16, + 26,26,1,149,242,242,1,160,255,255,1,153,240,240,1,18,27,27,1,169, + 255,255,1,172,255,255,1,20,29,29,1,158,228,228,1,180,255,255,1,174, + 243,243,1,101,138,138,1,189,255,255,1,191,255,255,1,194,255,255,1,197, + 255,255,1,132,255,255,1,135,255,255,1,138,255,255,1,0,0,0,1,143, + 255,255,1,146,255,255,1,149,255,255,1,152,255,255,1,65,107,107,1,87, + 142,142,1,154,245,245,1,90,141,141,1,70,107,107,1,169,255,255,1,172, + 255,255,1,73,107,107,1,124,178,178,1,176,250,250,1,90,126,126,1,53, + 72,72,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,132, + 255,255,1,135,255,255,1,138,255,255,1,0,0,0,4,152,255,255,1,146, + 240,240,1,46,74,74,1,6,9,9,1,47,74,74,1,156,239,239,1,169, + 255,255,1,172,255,255,1,163,239,239,1,51,73,73,1,6,8,8,1,36, + 50,50,1,161,221,221,1,189,255,255,1,191,255,255,1,194,255,255,1,197, + 255,255,1,132,255,255,1,135,255,255,1,138,255,255,1,140,255,255,1,143, + 255,255,1,146,255,255,1,149,255,255,1,152,255,255,1,155,255,255,1,157, + 255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172, + 255,255,1,174,255,255,1,177,255,255,1,180,255,255,1,183,255,255,1,186, + 255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,132, + 255,255,1,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146, + 255,255,1,149,255,255,1,152,255,255,1,155,255,255,1,157,255,255,1,160, + 255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174, + 255,255,1,177,255,255,1,180,255,255,1,183,255,255,1,186,255,255,1,189, + 255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,128,128,128,25,135, + 255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149, + 255,255,1,128,128,128,1,155,255,255,1,157,255,255,1,160,255,255,1,163, + 255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,128, + 128,128,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191, + 255,255,1,194,255,255,1,128,128,128,2,135,255,255,1,138,255,255,1,140, + 255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,128,128,128,1,155, + 255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169, + 255,255,1,172,255,255,1,174,255,255,1,128,128,128,1,180,255,255,1,183, + 255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,128, + 128,128,26,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146, + 255,255,1,149,255,255,1,128,128,128,1,155,255,255,1,157,255,255,1,160, + 255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174, + 255,255,1,128,128,128,1,180,255,255,1,183,255,255,1,186,255,255,1,189, + 255,255,1,191,255,255,1,194,255,255,1,128,128,128,2,135,255,255,1,138, + 255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,128, + 128,128,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166, + 255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,128,128,128,1,180, + 255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194, + 255,255,1,128,128,128,26,135,255,255,1,138,255,255,1,140,255,255,1,143, + 255,255,1,146,255,255,1,149,255,255,1,128,128,128,1,155,255,255,1,157, + 255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172, + 255,255,1,174,255,255,1,128,128,128,1,180,255,255,1,183,255,255,1,186, + 255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,128,128,128,2,135, + 255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149, + 255,255,1,128,128,128,1,155,255,255,1,157,255,255,1,160,255,255,1,163, + 255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,128, + 128,128,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191, + 255,255,1,194,255,255,1,128,128,128,26,135,255,255,1,138,255,255,1,140, + 255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,128,128,128,1,155, + 255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169, + 255,255,1,172,255,255,1,174,255,255,1,128,128,128,1,180,255,255,1,183, + 255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,128, + 128,128,2,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146, + 255,255,1,149,255,255,1,128,128,128,1,155,255,255,1,157,255,255,1,160, + 255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174, + 255,255,1,128,128,128,1,180,255,255,1,183,255,255,1,186,255,255,1,189, + 255,255,1,191,255,255,1,194,255,255,1,128,128,128,25,12,0,0,0,255, + 255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tmsesqlquery: record size: integer; data: array[0..1963] of byte end = + (size: 1964; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,109,115, + 101,115,113,108,113,117,101,114,121,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,52,7,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,240,6,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,132,255,255,1,135,255,255,1,138,255, + 255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,152,255, + 255,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255, + 255,1,169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1,180,255, + 255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255, + 255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1,140,255, + 255,1,143,255,255,1,146,255,255,1,149,255,255,1,152,255,255,1,155,255, + 255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255, + 255,1,172,255,255,1,174,255,255,1,177,255,255,1,180,255,255,1,183,255, + 255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255, + 255,1,132,255,255,1,135,255,255,1,97,179,179,1,20,36,36,1,3,5, + 5,1,26,46,46,1,113,193,193,1,152,255,255,1,155,255,255,1,154,250, + 250,1,72,115,115,1,12,18,18,2,76,114,114,1,169,250,250,1,174,255, + 255,1,177,255,255,1,0,0,0,1,183,255,255,1,186,255,255,1,189,255, + 255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255, + 255,1,11,21,21,1,103,187,187,1,140,249,249,1,101,176,176,1,18,30, + 30,1,152,255,255,1,155,255,255,1,79,129,129,1,80,127,127,1,156,244, + 244,1,154,236,236,1,89,134,134,1,84,124,124,1,174,255,255,1,177,255, + 255,1,0,0,0,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255, + 255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,25,46, + 46,1,83,152,152,1,135,240,240,1,146,255,255,1,149,255,255,1,152,255, + 255,1,155,255,255,1,20,33,33,1,148,236,236,1,163,255,255,1,166,255, + 255,1,169,255,255,1,20,29,29,1,174,255,255,1,177,255,255,1,0,0, + 0,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255, + 255,1,197,255,255,1,132,255,255,1,135,255,255,1,127,234,234,1,68,124, + 124,1,30,54,54,1,33,58,58,1,115,196,196,1,152,255,255,1,155,255, + 255,1,3,5,5,1,159,253,253,1,163,255,255,1,166,255,255,1,168,253, + 253,1,4,6,6,1,174,255,255,1,177,255,255,1,0,0,0,1,183,255, + 255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255, + 255,1,132,255,255,1,135,255,255,1,138,255,255,1,140,255,255,1,143,255, + 255,1,123,214,214,1,15,26,26,1,152,255,255,1,155,255,255,1,19,31, + 31,1,147,235,235,1,163,255,255,1,130,200,200,1,143,216,216,1,30,45, + 45,1,174,255,255,1,177,255,255,1,0,0,0,1,183,255,255,1,186,255, + 255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255, + 255,1,135,255,255,1,16,29,29,1,96,174,174,1,140,250,250,1,116,203, + 203,1,16,27,27,1,152,255,255,1,155,255,255,1,78,126,126,1,78,125, + 125,1,156,244,244,1,48,73,73,1,30,46,46,1,119,177,177,1,174,255, + 255,1,177,255,255,1,0,0,0,1,183,255,255,1,186,255,255,1,189,255, + 255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255, + 255,1,103,191,191,1,25,45,45,1,3,5,5,1,21,37,37,1,110,188, + 188,1,152,255,255,1,155,255,255,1,154,250,250,1,69,110,110,1,10,15, + 15,1,13,20,20,1,38,58,58,1,42,63,63,1,174,255,255,1,177,255, + 255,1,0,0,0,5,194,255,255,1,197,255,255,1,132,255,255,1,135,255, + 255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255, + 255,1,152,255,255,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255, + 255,1,166,255,255,1,169,255,255,1,135,200,200,1,174,255,255,1,177,255, + 255,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255, + 255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255, + 255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,152,255, + 255,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255, + 255,1,169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1,180,255, + 255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255, + 255,1,197,255,255,1,128,128,128,25,135,255,255,1,138,255,255,1,140,255, + 255,1,143,255,255,1,146,255,255,1,149,255,255,1,128,128,128,1,155,255, + 255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255, + 255,1,172,255,255,1,174,255,255,1,128,128,128,1,180,255,255,1,183,255, + 255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,128,128, + 128,2,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255, + 255,1,149,255,255,1,128,128,128,1,155,255,255,1,157,255,255,1,160,255, + 255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255, + 255,1,128,128,128,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255, + 255,1,191,255,255,1,194,255,255,1,128,128,128,26,135,255,255,1,138,255, + 255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,128,128, + 128,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255, + 255,1,169,255,255,1,172,255,255,1,174,255,255,1,128,128,128,1,180,255, + 255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255, + 255,1,128,128,128,2,135,255,255,1,138,255,255,1,140,255,255,1,143,255, + 255,1,146,255,255,1,149,255,255,1,128,128,128,1,155,255,255,1,157,255, + 255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255, + 255,1,174,255,255,1,128,128,128,1,180,255,255,1,183,255,255,1,186,255, + 255,1,189,255,255,1,191,255,255,1,194,255,255,1,128,128,128,26,135,255, + 255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255, + 255,1,128,128,128,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255, + 255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,128,128, + 128,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255, + 255,1,194,255,255,1,128,128,128,2,135,255,255,1,138,255,255,1,140,255, + 255,1,143,255,255,1,146,255,255,1,149,255,255,1,128,128,128,1,155,255, + 255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255, + 255,1,172,255,255,1,174,255,255,1,128,128,128,1,180,255,255,1,183,255, + 255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,128,128, + 128,26,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255, + 255,1,149,255,255,1,128,128,128,1,155,255,255,1,157,255,255,1,160,255, + 255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255, + 255,1,128,128,128,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255, + 255,1,191,255,255,1,194,255,255,1,128,128,128,2,135,255,255,1,138,255, + 255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,128,128, + 128,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255, + 255,1,169,255,255,1,172,255,255,1,174,255,255,1,128,128,128,1,180,255, + 255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255, + 255,1,128,128,128,25,12,0,0,0,255,255,255,255,255,255,255,255,255,255, + 255,66,0,0) + ); + +const + objdata_tmsesqltransaction: record size: integer; data: array[0..2325] of byte end = + (size: 2326; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,18,116,109,115, + 101,115,113,108,116,114,97,110,115,97,99,116,105,111,110,23,98,105,116,109, + 97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4, + 6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11, + 10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111, + 114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10, + 152,8,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0, + 84,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,255,255,1, + 135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1, + 149,255,255,1,152,255,255,1,155,255,255,1,157,255,255,1,160,255,255,1, + 163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1, + 177,255,255,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1, + 191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1, + 138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1, + 152,255,255,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1, + 166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1, + 180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1, + 194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,97,179,179,1, + 20,36,36,1,3,5,5,1,26,46,46,1,113,193,193,1,152,255,255,1, + 155,255,255,1,154,250,250,1,72,115,115,1,12,18,18,2,76,114,114,1, + 169,250,250,1,174,255,255,1,177,255,255,1,0,0,0,1,183,255,255,1, + 186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1, + 132,255,255,1,135,255,255,1,11,21,21,1,103,187,187,1,140,249,249,1, + 101,176,176,1,18,30,30,1,152,255,255,1,155,255,255,1,79,129,129,1, + 80,127,127,1,156,244,244,1,154,236,236,1,89,134,134,1,84,124,124,1, + 174,255,255,1,177,255,255,1,0,0,0,1,183,255,255,1,186,255,255,1, + 189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1, + 135,255,255,1,25,46,46,1,83,152,152,1,135,240,240,1,146,255,255,1, + 149,255,255,1,152,255,255,1,155,255,255,1,20,33,33,1,148,236,236,1, + 163,255,255,1,166,255,255,1,169,255,255,1,20,29,29,1,174,255,255,1, + 177,255,255,1,0,0,0,1,183,255,255,1,186,255,255,1,189,255,255,1, + 191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1, + 127,234,234,1,68,124,124,1,30,54,54,1,33,58,58,1,115,196,196,1, + 152,255,255,1,155,255,255,1,3,5,5,1,159,253,253,1,163,255,255,1, + 166,255,255,1,168,253,253,1,4,6,6,1,174,255,255,1,177,255,255,1, + 0,0,0,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1, + 194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1, + 140,255,255,1,143,255,255,1,123,214,214,1,15,26,26,1,152,255,255,1, + 155,255,255,1,19,31,31,1,147,235,235,1,163,255,255,1,130,200,200,1, + 143,216,216,1,30,45,45,1,174,255,255,1,177,255,255,1,0,0,0,1, + 183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1, + 197,255,255,1,132,255,255,1,135,255,255,1,16,29,29,1,96,174,174,1, + 140,250,250,1,116,203,203,1,16,27,27,1,152,255,255,1,155,255,255,1, + 78,126,126,1,78,125,125,1,156,244,244,1,48,73,73,1,30,46,46,1, + 119,177,177,1,174,255,255,1,177,255,255,1,0,0,0,1,183,255,255,1, + 186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1, + 132,255,255,1,135,255,255,1,103,191,191,1,25,45,45,1,3,5,5,1, + 21,37,37,1,110,188,188,1,152,255,255,1,155,255,255,1,154,250,250,1, + 69,110,110,1,10,15,15,1,13,20,20,1,38,58,58,1,42,63,63,1, + 174,255,255,1,177,255,255,1,0,0,0,5,194,255,255,1,197,255,255,1, + 132,255,255,1,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1, + 146,255,255,1,149,255,255,1,152,255,255,1,155,255,255,1,157,255,255,1, + 160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,135,200,200,1, + 174,255,255,1,177,255,255,1,180,255,255,1,183,255,255,1,186,255,255,1, + 189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1, + 135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1, + 149,255,255,1,152,255,255,1,155,255,255,1,157,255,255,1,160,255,255,1, + 163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1, + 177,255,255,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1, + 191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,253,253,1, + 133,192,192,1,130,150,150,1,128,129,129,1,128,128,128,14,129,129,129,1, + 139,150,150,1,160,192,192,1,193,253,253,1,197,255,255,1,132,253,253,1, + 130,156,156,1,131,169,169,1,137,227,227,1,143,252,252,1,146,255,255,1, + 149,255,255,1,152,255,255,1,155,255,255,1,157,255,255,1,160,255,255,1, + 163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1, + 177,255,255,1,180,255,255,1,183,255,255,1,184,252,252,1,176,227,227,1, + 148,169,169,1,142,156,156,1,196,253,253,1,130,192,192,1,130,169,169,1, + 138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1, + 152,255,255,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1, + 166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1, + 180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1, + 149,169,169,1,163,192,192,1,129,150,150,1,133,227,227,1,0,0,0,5, + 152,255,255,1,155,255,255,1,0,0,0,3,11,17,17,1,99,150,150,1, + 172,255,255,1,174,255,255,1,177,255,255,1,128,182,182,1,0,0,0,1, + 133,182,182,1,189,255,255,1,191,255,255,1,180,227,227,1,140,150,150,1, + 128,129,129,1,135,252,252,1,138,255,255,1,140,255,255,1,0,0,0,1, + 146,255,255,1,149,255,255,1,152,255,255,1,155,255,255,1,0,0,0,1, + 160,255,255,1,163,255,255,1,130,200,200,1,13,19,19,1,172,255,255,1, + 174,255,255,1,177,255,255,1,53,75,75,1,76,106,106,1,55,76,76,1, + 189,255,255,1,191,255,255,1,192,252,252,1,129,129,129,1,128,128,128,1, + 135,255,255,1,138,255,255,1,140,255,255,1,0,0,0,1,146,255,255,1, + 149,255,255,1,152,255,255,1,155,255,255,1,0,0,0,1,160,255,255,1, + 163,255,255,1,131,202,202,1,15,22,22,1,172,255,255,1,174,255,255,1, + 154,222,222,1,25,36,36,1,180,251,251,1,27,37,37,1,165,223,223,1, + 191,255,255,1,194,255,255,1,128,128,128,2,135,255,255,1,138,255,255,1, + 140,255,255,1,0,0,0,1,146,255,255,1,149,255,255,1,152,255,255,1, + 155,255,255,1,0,0,0,3,12,19,19,1,109,164,164,1,172,255,255,1, + 174,255,255,1,81,117,117,1,97,138,138,1,183,255,255,1,101,138,138,1, + 87,118,118,1,191,255,255,1,194,255,255,1,128,128,128,2,135,255,255,1, + 138,255,255,1,140,255,255,1,0,0,0,1,146,255,255,1,149,255,255,1, + 152,255,255,1,155,255,255,1,0,0,0,1,160,255,255,1,137,214,214,1, + 39,60,60,1,157,237,237,1,172,255,255,1,169,247,247,1,13,19,19,1, + 0,0,0,3,14,19,19,1,185,247,247,1,194,255,255,1,128,128,128,1, + 128,129,129,1,135,252,252,1,138,255,255,1,140,255,255,1,0,0,0,1, + 146,255,255,1,149,255,255,1,152,255,255,1,155,255,255,1,0,0,0,1, + 160,255,255,1,163,255,255,1,104,159,159,1,64,96,96,1,172,255,255,1, + 108,159,159,1,65,93,93,1,180,255,255,1,183,255,255,1,186,255,255,1, + 69,93,93,1,120,160,160,1,192,252,252,1,129,129,129,1,129,150,150,1, + 133,227,227,1,138,255,255,1,140,255,255,1,0,0,0,1,146,255,255,1, + 149,255,255,1,152,255,255,1,155,255,255,1,0,0,0,1,160,255,255,1, + 163,255,255,1,165,254,254,1,37,56,56,1,137,203,203,1,35,52,52,1, + 140,201,201,1,180,255,255,1,183,255,255,1,186,255,255,1,149,201,201,1, + 40,53,53,1,180,227,227,1,140,150,150,1,130,192,192,1,130,169,169,1, + 138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1, + 152,255,255,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1, + 166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1, + 180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1, + 149,169,169,1,163,192,192,1,132,253,253,1,130,156,156,1,131,169,169,1, + 137,227,227,1,143,252,252,1,146,255,255,1,149,255,255,1,152,255,255,1, + 155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1, + 169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1,180,255,255,1, + 183,255,255,1,184,252,252,1,176,227,227,1,148,169,169,1,142,156,156,1, + 196,253,253,1,132,255,255,1,135,253,253,1,133,192,192,1,130,150,150,1, + 128,129,129,1,128,128,128,14,129,129,129,1,139,150,150,1,160,192,192,1, + 193,253,253,1,197,255,255,1,12,0,0,0,255,255,255,255,255,255,255,255, + 255,255,255,66,0,0) + ); + +const + objdata_tmseibconnection: record size: integer; data: array[0..2563] of byte end = + (size: 2564; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,109,115, + 101,105,98,99,111,110,110,101,99,116,105,111,110,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,136,9, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,196,4, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,208,208,208,30,20,20, + 255,1,17,66,255,1,15,101,255,1,16,89,255,1,18,60,255,1,208,208, + 208,2,17,66,255,1,15,105,255,1,15,104,255,1,18,48,255,1,208,208, + 208,12,17,72,255,1,13,128,255,1,12,150,255,1,14,113,255,1,18,57, + 255,1,208,208,208,3,20,20,255,1,17,64,255,1,15,104,255,1,15,97, + 255,1,14,118,255,1,17,73,255,1,208,208,208,8,20,20,255,1,15,94, + 255,1,12,154,255,1,15,97,255,1,18,46,255,1,208,208,208,8,20,20, + 255,1,15,101,255,1,12,151,255,1,15,99,255,1,20,20,255,1,208,208, + 208,5,20,20,255,1,15,100,255,1,10,186,255,1,16,95,255,1,208,208, + 208,12,16,82,255,1,11,182,255,1,14,116,255,1,20,20,255,1,208,208, + 208,4,16,94,255,1,10,194,255,1,16,96,255,1,208,208,208,3,20,20, + 255,1,15,104,255,1,15,110,255,1,17,77,255,1,20,28,255,1,208,208, + 208,6,15,99,255,1,9,205,255,1,15,108,255,1,20,20,255,1,208,208, + 208,2,17,69,255,1,12,167,255,1,15,104,255,1,20,20,255,1,208,208, + 208,2,20,20,255,2,11,177,254,1,8,194,239,1,9,202,254,1,12,159, + 255,1,14,127,255,1,14,115,255,1,15,105,255,1,16,88,255,1,20,20, + 255,1,208,208,208,1,20,20,255,1,14,130,255,1,9,202,255,1,16,93, + 255,1,208,208,208,1,20,20,255,1,14,122,255,1,12,158,255,1,18,51, + 255,1,208,208,208,2,15,98,255,1,11,168,255,1,11,175,255,1,8,187, + 239,1,0,0,0,1,8,191,239,1,9,204,255,1,13,134,255,1,14,127, + 255,1,13,140,255,1,13,138,255,1,20,20,255,1,208,208,208,2,16,87, + 255,1,9,203,255,1,13,130,255,1,208,208,208,1,18,56,255,1,11,181, + 255,1,15,103,255,1,208,208,208,3,15,109,255,1,10,202,255,2,11,185, + 254,1,9,186,239,1,10,201,254,1,10,202,255,1,10,196,255,1,14,135, + 255,1,17,66,255,1,20,20,255,2,208,208,208,2,19,41,255,1,13,155, + 255,1,11,179,255,1,18,57,255,1,16,94,255,1,12,172,255,1,19,37, + 255,1,208,208,208,3,18,52,255,1,15,110,255,1,16,91,255,1,18,53, + 255,1,15,107,255,1,10,200,255,4,15,117,255,1,208,208,208,5,13,140, + 255,1,10,200,255,1,17,82,255,1,15,118,255,1,12,166,255,1,20,20, + 255,1,208,208,208,5,20,20,255,1,208,208,208,1,17,78,255,1,10,190, + 255,1,10,198,255,3,13,150,255,1,20,20,255,1,208,208,208,3,20,20, + 255,1,13,144,255,1,10,198,255,1,15,106,255,1,14,126,255,1,12,163, + 255,1,20,20,255,1,208,208,208,4,18,51,255,1,17,87,255,1,15,119, + 255,1,12,175,255,1,11,196,255,4,15,125,255,1,208,208,208,4,20,20, + 255,1,13,160,255,1,11,196,255,1,15,111,255,1,15,119,255,1,13,156, + 255,1,20,20,255,1,208,208,208,3,17,74,255,1,13,152,255,1,11,194, + 255,6,11,193,255,1,16,95,255,1,208,208,208,4,16,90,255,1,11,191, + 255,1,11,194,255,1,16,96,255,1,15,109,255,1,12,161,255,1,17,70, + 255,1,208,208,208,2,19,40,255,1,14,142,255,1,11,191,255,7,15,121, + 255,1,19,35,255,1,208,208,208,3,18,49,255,1,13,145,255,1,11,191, + 255,2,17,78,255,1,16,88,255,1,12,149,255,1,15,95,255,1,208,208, + 208,2,17,75,255,1,11,188,255,1,11,189,255,6,13,149,255,1,17,68, + 255,1,208,208,208,3,19,44,255,1,15,105,255,1,11,189,255,2,11,183, + 255,1,18,61,255,1,17,61,255,1,13,134,255,1,14,120,255,1,18,47, + 255,1,208,208,208,1,16,99,255,1,12,174,255,7,15,112,255,1,208,208, + 208,3,18,55,255,1,15,112,255,1,12,174,255,3,13,150,255,1,19,36, + 255,2,14,99,255,1,13,118,255,1,16,76,255,1,20,26,255,1,16,88, + 255,1,12,153,255,7,13,142,255,1,15,97,255,1,15,95,255,1,15,105, + 255,1,13,130,255,1,12,153,255,4,16,88,255,1,208,208,208,2,17,57, + 255,1,13,102,255,2,17,58,255,1,18,59,255,1,13,132,255,15,15,106, + 255,1,18,44,255,1,208,208,208,2,19,31,255,1,16,68,255,1,14,86, + 255,1,15,74,255,1,19,34,255,1,14,97,255,1,13,111,255,13,13,110, + 255,1,17,57,255,1,208,208,208,4,18,40,255,1,14,69,255,1,14,70, + 255,1,18,41,255,1,17,56,255,1,14,89,255,13,17,60,255,1,20,20, + 255,1,208,208,208,4,20,20,255,1,18,34,255,1,16,51,255,1,17,41, + 255,1,18,32,255,1,15,61,255,1,14,68,255,10,14,67,255,1,17,45, + 255,1,19,30,255,1,208,208,208,7,18,26,255,1,17,32,255,1,18,27, + 255,1,18,30,255,1,16,42,255,1,15,47,255,8,16,42,255,1,18,31, + 255,1,20,20,255,1,208,208,208,9,20,20,255,1,19,21,255,1,20,20, + 255,1,19,22,255,1,17,24,255,1,15,26,255,5,16,25,255,1,18,23, + 255,1,19,21,255,1,208,208,208,15,20,20,255,1,19,19,255,2,18,18, + 255,1,19,19,255,2,20,20,255,1,208,208,208,8,140,4,0,0,0,0, + 0,30,6,6,6,1,86,86,86,1,138,138,138,1,189,189,189,1,131,131, + 131,1,0,0,0,2,172,172,172,1,188,188,188,1,136,136,136,1,37,37, + 37,1,0,0,0,12,64,64,64,1,199,199,199,1,232,232,232,1,157,157, + 157,1,53,53,53,1,0,0,0,3,1,1,1,1,64,64,64,1,140,140, + 140,1,209,209,209,1,172,172,172,1,73,73,73,1,0,0,0,8,1,1, + 1,1,136,136,136,1,236,236,236,1,155,155,155,1,21,21,21,1,0,0, + 0,8,8,8,8,1,146,146,146,1,234,234,234,1,150,150,150,1,5,5, + 5,1,0,0,0,5,5,5,5,1,166,166,166,1,251,251,251,1,146,146, + 146,1,0,0,0,12,98,98,98,1,247,247,247,1,185,185,185,1,11,11, + 11,1,0,0,0,4,140,140,140,1,254,254,254,1,155,155,155,1,0,0, + 0,3,23,23,23,1,163,163,163,1,153,153,153,1,111,111,111,1,22,22, + 22,1,0,0,0,6,155,155,155,1,255,255,255,1,180,180,180,1,4,4, + 4,1,0,0,0,2,54,54,54,1,235,235,235,1,170,170,170,1,1,1, + 1,1,0,0,0,2,31,31,31,1,73,73,73,1,255,255,255,3,238,238, + 238,1,195,195,195,1,167,167,167,1,151,151,151,1,137,137,137,1,15,15, + 15,1,0,0,0,1,6,6,6,1,200,200,200,1,255,255,255,1,139,139, + 139,1,0,0,0,1,2,2,2,1,190,190,190,1,231,231,231,1,31,31, + 31,1,0,0,0,2,160,160,160,1,249,249,249,1,255,255,255,5,238,238, + 238,1,214,214,214,1,229,229,229,1,247,247,247,1,40,40,40,1,0,0, + 0,2,126,126,126,1,255,255,255,1,204,204,204,1,0,0,0,1,70,70, + 70,1,253,253,253,1,152,152,152,1,0,0,0,3,172,172,172,1,255,255, + 255,7,219,219,219,1,62,62,62,1,27,27,27,1,6,6,6,1,0,0, + 0,2,24,24,24,1,238,238,238,1,251,251,251,1,60,60,60,1,140,140, + 140,1,255,255,255,1,51,51,51,1,0,0,0,3,30,30,30,1,178,178, + 178,1,173,173,173,1,68,68,68,1,189,189,189,1,255,255,255,4,167,167, + 167,1,0,0,0,5,217,217,217,1,255,255,255,1,119,119,119,1,187,187, + 187,1,255,255,255,1,40,40,40,1,0,0,0,5,11,11,11,1,0,0, + 0,1,150,150,150,1,255,255,255,4,235,235,235,1,17,17,17,1,0,0, + 0,3,4,4,4,1,232,232,232,1,255,255,255,1,145,145,145,1,210,210, + 210,1,255,255,255,1,40,40,40,1,0,0,0,4,47,47,47,1,132,132, + 132,1,180,180,180,1,247,247,247,1,255,255,255,4,199,199,199,1,0,0, + 0,4,27,27,27,1,247,247,247,1,255,255,255,1,149,149,149,1,208,208, + 208,1,255,255,255,1,40,40,40,1,0,0,0,3,73,73,73,1,232,232, + 232,1,255,255,255,7,137,137,137,1,0,0,0,4,127,127,127,1,255,255, + 255,2,131,131,131,1,206,206,206,1,255,255,255,1,110,110,110,1,0,0, + 0,2,31,31,31,1,224,224,224,1,255,255,255,7,202,202,202,1,11,11, + 11,1,0,0,0,3,27,27,27,1,224,224,224,1,255,255,255,2,115,115, + 115,1,174,174,174,1,255,255,255,1,189,189,189,1,0,0,0,2,111,111, + 111,1,255,255,255,7,227,227,227,1,49,49,49,1,0,0,0,3,20,20, + 20,1,189,189,189,1,255,255,255,3,91,91,91,1,130,130,130,1,255,255, + 255,1,248,248,248,1,64,64,64,1,0,0,0,1,149,149,149,1,255,255, + 255,7,191,191,191,1,0,0,0,3,55,55,55,1,206,206,206,1,255,255, + 255,3,250,250,250,1,47,47,47,1,46,46,46,1,242,242,242,1,255,255, + 255,1,199,199,199,1,15,15,15,1,152,152,152,1,255,255,255,7,252,252, + 252,1,193,193,193,1,167,167,167,1,209,209,209,1,246,246,246,1,255,255, + 255,4,175,175,175,1,0,0,0,2,162,162,162,1,255,255,255,2,175,175, + 175,1,119,119,119,1,255,255,255,15,231,231,231,1,41,41,41,1,0,0, + 0,2,28,28,28,1,226,226,226,1,255,255,255,1,243,243,243,1,87,87, + 87,1,249,249,249,1,255,255,255,14,136,136,136,1,0,0,0,4,129,129, + 129,1,255,255,255,2,142,142,142,1,180,180,180,1,255,255,255,13,203,203, + 203,1,7,7,7,1,0,0,0,4,5,5,5,1,157,157,157,1,248,248, + 248,1,209,209,209,1,71,71,71,1,246,246,246,1,255,255,255,11,187,187, + 187,1,27,27,27,1,0,0,0,7,106,106,106,1,223,223,223,1,163,163, + 163,1,121,121,121,1,237,237,237,1,255,255,255,8,239,239,239,1,152,152, + 152,1,5,5,5,1,0,0,0,9,6,6,6,1,94,94,94,1,20,20, + 20,1,75,75,75,1,218,218,218,1,255,255,255,5,236,236,236,1,161,161, + 161,1,49,49,49,1,0,0,0,15,20,20,20,1,86,86,86,1,118,118, + 118,1,134,134,134,1,119,119,119,1,89,89,89,1,26,26,26,1,0,0, + 0,8,0,0) + ); + +const + objdata_tfb3connection: record size: integer; data: array[0..2705] of byte end = + (size: 2706; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,102,98, + 51,99,111,110,110,101,99,116,105,111,110,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,24,10,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,200,4,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,30,0,0,255,1, + 17,72,255,1,14,111,255,1,15,95,255,1,17,70,255,1,0,0,0,2, + 17,62,255,1,15,96,255,1,15,104,255,1,7,24,97,1,0,0,0,12, + 17,85,255,1,14,138,255,1,13,153,255,1,16,114,255,1,15,54,255,1, + 0,0,0,4,17,55,255,1,13,99,255,1,9,64,155,1,6,43,92,1, + 16,76,255,1,0,0,0,8,0,0,255,1,16,96,255,1,12,163,255,1, + 15,98,255,1,12,35,255,1,0,0,0,8,0,0,255,1,14,88,255,1, + 13,148,255,1,15,100,255,1,0,0,255,1,0,0,0,5,0,0,255,1, + 15,100,255,1,11,180,255,1,14,89,255,1,0,0,0,12,10,44,135,1, + 2,33,49,1,1,11,26,1,0,0,0,5,16,97,255,1,11,193,255,1, + 17,96,255,1,0,0,0,3,24,24,255,1,15,98,255,1,15,109,255,1, + 16,80,255,1,24,36,255,1,0,0,0,6,14,68,193,1,8,155,196,1, + 6,47,103,1,0,0,0,3,19,78,255,1,11,182,255,1,15,101,255,1, + 0,0,255,1,0,0,0,2,20,20,255,1,23,23,255,1,13,158,255,1, + 9,196,242,1,10,203,255,1,13,160,255,1,13,130,255,1,16,121,255,1, + 16,108,255,1,15,86,231,1,9,9,132,1,0,0,0,1,0,0,255,1, + 16,128,255,1,10,204,255,1,3,20,50,1,0,0,0,1,0,0,255,1, + 15,126,255,1,14,143,255,1,12,36,255,1,0,0,0,2,15,105,255,1, + 11,167,255,1,13,156,255,1,9,192,242,1,0,0,0,1,9,195,242,1, + 10,205,255,1,13,143,255,1,14,130,255,1,13,145,255,1,5,53,94,1, + 0,0,3,1,0,0,0,2,16,74,255,1,10,192,253,1,2,25,45,1, + 0,0,1,1,18,65,255,1,11,184,255,1,17,94,255,1,0,0,0,3, + 16,118,255,1,10,203,255,1,10,199,255,1,11,173,255,1,9,189,242,1, + 10,203,255,2,10,202,255,1,14,145,255,1,17,72,255,1,10,10,111,1, + 0,0,1,1,0,0,0,2,0,0,8,1,3,32,54,1,1,18,25,1, + 10,29,133,1,15,107,255,1,12,168,255,1,18,36,255,1,0,0,0,3, + 15,54,255,1,15,111,255,1,15,91,255,1,21,28,255,1,16,93,255,1, + 10,197,255,1,10,201,255,3,16,126,255,1,0,0,0,5,9,86,164,1, + 10,195,248,1,15,80,255,1,14,123,255,1,13,142,255,1,28,28,255,1, + 0,0,0,4,0,0,255,1,21,21,255,1,0,0,0,1,16,73,255,1, + 11,187,255,1,11,198,255,3,13,158,255,1,23,23,255,1,0,0,0,4, + 15,134,255,1,11,198,255,1,16,102,255,1,14,130,255,1,15,136,255,1, + 0,0,255,1,0,0,0,4,19,61,255,1,17,94,255,1,14,115,255,1, + 13,170,255,1,11,196,255,4,14,132,255,1,0,0,255,1,0,0,0,3, + 16,16,255,1,14,151,255,1,11,196,255,1,16,111,255,1,15,125,255,1, + 14,148,255,1,20,20,255,1,0,0,0,3,18,84,255,1,13,158,255,1, + 11,194,255,6,11,192,255,1,17,94,255,1,0,0,0,4,17,81,255,1, + 12,190,255,1,11,194,255,1,16,110,255,2,13,160,255,1,18,63,255,1, + 0,0,0,2,14,43,255,1,14,149,255,1,12,192,255,7,15,119,255,1, + 21,43,255,1,0,0,0,3,13,38,255,1,14,133,255,1,12,192,255,2, + 15,105,255,1,17,94,255,1,13,150,255,1,17,87,255,1,0,0,0,2, + 17,86,255,1,12,190,255,7,15,145,255,1,23,68,255,1,0,0,0,3, + 36,36,255,1,15,100,255,1,12,189,255,1,12,190,255,2,17,79,255,1, + 16,69,255,1,13,134,255,1,14,114,255,1,18,45,255,1,0,0,0,1, + 16,102,255,1,12,175,255,7,15,108,255,1,0,0,0,3,21,53,255,1, + 16,101,255,1,12,172,255,1,12,175,255,2,13,155,255,1,22,48,255,1, + 20,40,255,1,15,101,255,1,14,118,255,1,17,75,255,1,28,28,255,1, + 16,91,255,1,13,153,255,7,14,141,255,1,16,91,255,2,16,99,255,1, + 15,128,255,1,13,153,255,4,16,96,255,1,0,0,0,2,17,64,255,1, + 14,103,255,1,14,102,255,1,17,62,255,1,17,68,255,1,13,132,255,15, + 13,123,255,1,16,52,255,1,0,0,0,2,20,40,255,1,15,75,255,1, + 14,87,255,1,16,70,255,1,21,35,255,1,14,99,255,1,14,111,255,14, + 16,61,255,1,0,0,255,1,0,0,0,3,18,41,255,1,15,69,255,1, + 16,70,255,1,18,36,255,1,17,60,255,1,14,90,255,13,17,63,255,1, + 14,28,255,1,0,0,0,4,0,0,255,1,18,36,255,1,15,54,255,1, + 18,41,255,1,19,36,255,1,14,63,255,1,15,69,255,10,15,68,255,1, + 18,47,255,1,15,29,255,1,0,0,0,6,0,0,255,1,18,28,255,1, + 17,34,255,1,17,27,255,1,18,31,255,1,16,46,255,1,15,48,255,8, + 16,43,255,1,18,32,255,1,26,26,255,1,0,0,0,9,20,20,255,1, + 19,21,255,1,14,14,255,1,18,22,255,1,17,26,255,1,16,27,255,5, + 17,26,255,1,19,24,255,1,19,23,255,1,0,0,0,15,23,23,255,1, + 20,20,255,1,19,19,255,4,18,18,255,1,0,0,0,8,24,5,0,0, + 0,0,0,17,60,60,60,1,176,176,176,1,221,221,221,1,228,228,228,1, + 193,193,193,1,91,91,91,1,0,0,0,7,6,6,6,1,89,89,89,1, + 143,143,143,1,193,193,193,1,132,132,132,1,0,0,0,2,169,169,169,1, + 189,189,189,1,140,140,140,1,108,108,108,1,250,250,250,1,133,133,133,1, + 25,25,25,1,16,16,16,1,98,98,98,1,253,253,253,1,98,98,98,1, + 0,0,0,5,90,90,90,1,207,207,207,1,231,231,231,1,157,157,157,1, + 52,52,52,1,0,0,0,4,46,46,46,1,134,134,134,1,224,224,224,1, + 228,228,228,1,81,81,81,1,0,0,0,3,215,215,215,1,176,176,176,1, + 0,0,0,3,1,1,1,1,141,141,141,1,239,239,239,1,149,149,149,1, + 22,22,22,1,0,0,0,8,4,4,4,1,127,127,127,1,231,231,231,1, + 151,151,151,1,5,5,5,1,62,62,62,1,249,249,249,1,109,109,109,1, + 0,0,0,2,5,5,5,1,166,166,166,1,247,247,247,1,129,129,129,1, + 0,0,0,12,127,127,127,1,252,252,252,1,246,246,246,1,253,253,253,1, + 116,116,116,1,0,0,0,3,155,155,155,1,254,254,254,1,149,149,149,1, + 0,0,0,3,21,21,21,1,169,169,169,1,157,157,157,1,109,109,109,1, + 21,21,21,1,0,0,0,5,10,10,10,1,149,149,149,1,255,255,255,1, + 226,226,226,1,248,248,248,1,93,93,93,1,0,0,0,1,92,92,92,1, + 248,248,248,1,170,170,170,1,1,1,1,1,0,0,0,2,25,25,25,1, + 22,22,22,1,237,237,237,1,255,255,255,2,237,237,237,1,191,191,191,1, + 164,164,164,1,147,147,147,1,137,137,137,1,27,27,27,1,0,0,0,1, + 4,4,4,1,195,195,195,1,255,255,255,1,220,220,220,1,222,222,222,1, + 3,3,3,1,199,199,199,1,218,218,218,1,21,21,21,1,0,0,0,2, + 170,170,170,1,245,245,245,1,236,236,236,1,255,255,255,4,242,242,242,1, + 216,216,216,1,228,228,228,1,252,252,252,1,238,238,238,1,13,13,13,1, + 0,0,0,1,97,97,97,1,254,254,254,1,247,247,247,1,196,196,196,1, + 86,86,86,1,253,253,253,1,138,138,138,1,0,0,0,3,179,179,179,1, + 255,255,255,2,253,253,253,1,255,255,255,4,221,221,221,1,74,74,74,1, + 53,53,53,1,216,216,216,1,218,218,218,1,134,134,134,1,132,132,132,1, + 249,249,249,1,255,255,255,1,98,98,98,1,157,157,157,1,250,250,250,1, + 42,42,42,1,0,0,0,3,33,33,33,1,184,184,184,1,165,165,165,1, + 37,37,37,1,162,162,162,1,255,255,255,4,197,197,197,1,0,0,0,1, + 2,2,2,1,69,69,69,1,110,110,110,1,112,112,112,1,222,222,222,1, + 255,255,255,1,118,118,118,1,195,195,195,1,233,233,233,1,9,9,9,1, + 0,0,0,4,1,1,1,1,12,12,12,1,0,0,0,1,112,112,112,1, + 255,255,255,4,242,242,242,1,22,22,22,1,0,0,0,4,209,209,209,1, + 255,255,255,1,145,145,145,1,215,215,215,1,228,228,228,1,4,4,4,1, + 0,0,0,4,54,54,54,1,135,135,135,1,177,177,177,1,244,244,244,1, + 255,255,255,4,216,216,216,1,1,1,1,1,0,0,0,3,16,16,16,1, + 237,237,237,1,255,255,255,1,158,158,158,1,220,220,220,1,245,245,245,1, + 26,26,26,1,0,0,0,3,100,100,100,1,236,236,236,1,255,255,255,7, + 146,146,146,1,0,0,0,4,120,120,120,1,255,255,255,2,157,157,157,1, + 208,208,208,1,255,255,255,1,101,101,101,1,0,0,0,2,36,36,36,1, + 230,230,230,1,255,255,255,7,201,201,201,1,12,12,12,1,0,0,0,3, + 20,20,20,1,214,214,214,1,255,255,255,2,151,151,151,1,181,181,181,1, + 255,255,255,1,170,170,170,1,0,0,0,2,133,133,133,1,255,255,255,7, + 223,223,223,1,45,45,45,1,0,0,0,3,7,7,7,1,181,181,181,1, + 255,255,255,3,119,119,119,1,141,141,141,1,255,255,255,1,242,242,242,1, + 57,57,57,1,0,0,0,1,162,162,162,1,255,255,255,7,181,181,181,1, + 0,0,0,3,48,48,48,1,189,189,189,1,255,255,255,3,251,251,251,1, + 58,58,58,1,51,51,51,1,244,244,244,1,255,255,255,1,197,197,197,1, + 9,9,9,1,163,163,163,1,255,255,255,7,250,250,250,1,179,179,179,1, + 160,160,160,1,194,194,194,1,242,242,242,1,255,255,255,4,192,192,192,1, + 0,0,0,2,175,175,175,1,255,255,255,2,161,161,161,1,138,138,138,1, + 255,255,255,15,252,252,252,1,98,98,98,1,0,0,0,2,63,63,63,1, + 239,239,239,1,255,255,255,1,228,228,228,1,72,72,72,1,250,250,250,1, + 255,255,255,14,175,175,175,1,1,1,1,1,0,0,0,3,144,144,144,1, + 255,255,255,2,112,112,112,1,194,194,194,1,255,255,255,13,208,208,208,1, + 18,18,18,1,0,0,0,4,5,5,5,1,171,171,171,1,255,255,255,1, + 204,204,204,1,92,92,92,1,247,247,247,1,255,255,255,11,200,200,200,1, + 35,35,35,1,0,0,0,6,3,3,3,1,127,127,127,1,227,227,227,1, + 167,167,167,1,138,138,138,1,250,250,250,1,255,255,255,8,243,243,243,1, + 158,158,158,1,10,10,10,1,0,0,0,9,25,25,25,1,133,133,133,1, + 18,18,18,1,125,125,125,1,230,230,230,1,255,255,255,5,239,239,239,1, + 178,178,178,1,67,67,67,1,0,0,0,15,22,22,22,1,104,104,104,1, + 134,134,134,1,146,146,146,1,131,131,131,1,105,105,105,1,29,29,29,1, + 0,0,0,8,0,0) + ); + +const + objdata_tfbservice: record size: integer; data: array[0..2921] of byte end = + (size: 2922; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,102,98, + 115,101,114,118,105,99,101,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,244,10,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,188,5,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,30,0,0,255,1,17,72,255,1, + 14,111,255,1,15,95,255,1,17,70,255,1,0,0,0,2,17,62,255,1, + 15,96,255,1,15,104,255,1,18,59,255,1,0,0,0,12,17,85,255,1, + 14,138,255,1,13,153,255,1,16,114,255,1,15,54,255,1,0,0,0,4, + 17,55,255,1,13,99,255,1,15,104,255,1,15,119,255,1,16,76,255,1, + 0,0,0,8,0,0,255,1,16,96,255,1,12,163,255,1,15,98,255,1, + 12,35,255,1,0,0,0,8,0,0,255,1,14,88,255,1,13,148,255,1, + 15,100,255,1,0,0,255,1,0,0,0,5,0,0,142,1,15,100,255,1, + 11,180,255,1,14,89,255,1,0,0,0,12,17,84,255,1,12,174,255,1, + 13,115,255,1,13,38,255,1,0,0,0,4,3,22,57,1,3,53,70,1, + 10,61,162,1,0,0,0,3,1,1,10,1,3,25,63,1,15,109,253,1, + 1,7,21,1,1,1,10,1,0,0,0,6,17,91,255,1,10,202,255,1, + 14,118,255,1,32,32,255,1,0,0,0,2,7,30,97,1,11,182,255,1, + 13,89,226,1,0,0,0,3,20,20,255,1,23,23,255,1,13,158,255,1, + 9,196,242,1,1,30,38,1,13,160,255,1,13,130,255,1,6,47,98,1, + 7,51,120,1,16,95,255,1,17,17,255,1,0,0,0,1,0,0,255,1, + 16,128,255,1,10,204,255,1,16,99,255,1,0,0,0,1,0,0,7,1, + 3,23,46,1,10,100,178,1,12,35,243,1,0,0,0,2,1,10,26,1, + 9,132,202,1,11,122,201,1,8,169,213,1,0,0,0,1,1,29,36,1, + 10,205,255,1,13,143,255,1,5,51,101,1,9,89,156,1,14,143,255,1, + 20,20,255,1,0,0,0,2,16,74,255,1,10,194,255,1,14,138,255,1, + 0,0,255,1,18,65,255,1,9,150,208,1,5,26,69,1,0,0,0,3, + 1,8,17,1,5,108,136,1,5,106,136,1,8,123,183,1,9,189,242,1, + 1,24,30,1,3,68,85,1,2,39,49,1,5,50,87,1,17,70,245,1, + 20,20,255,1,0,0,255,1,0,0,0,2,32,32,255,1,13,148,255,1, + 11,183,255,1,20,57,255,1,8,64,152,1,11,160,242,1,18,36,255,1, + 0,0,0,3,0,1,7,1,15,111,255,1,15,91,255,1,21,28,255,1, + 16,93,255,1,1,29,38,1,10,201,255,1,8,161,204,1,3,60,76,1, + 16,126,255,1,0,0,0,5,14,134,255,1,10,201,255,1,15,80,255,1, + 7,57,119,1,5,56,100,1,5,5,34,1,0,0,0,4,0,0,4,1, + 3,3,30,1,0,0,0,1,16,72,248,1,2,28,38,1,11,198,255,2, + 4,68,87,1,9,116,185,1,23,23,255,1,0,0,0,4,15,134,255,1, + 11,198,255,1,16,102,255,1,14,130,255,1,10,97,179,1,0,0,4,1, + 0,0,0,4,3,12,50,1,7,36,96,1,6,51,113,1,13,166,249,1, + 7,118,154,1,11,196,255,2,10,171,223,1,9,86,167,1,0,0,255,1, + 0,0,0,3,16,16,255,1,14,151,255,1,11,196,255,1,16,111,255,1, + 15,125,255,1,14,148,255,1,20,20,255,1,0,0,0,3,18,84,255,1, + 13,158,255,1,11,194,255,6,11,192,255,1,17,94,255,1,0,0,0,4, + 17,81,255,1,12,190,255,1,11,194,255,1,16,110,255,2,13,160,255,1, + 18,63,255,1,0,0,0,2,14,43,255,1,14,149,255,1,12,192,255,7, + 15,119,255,1,21,43,255,1,0,0,0,3,13,38,255,1,14,133,255,1, + 12,192,255,2,15,105,255,1,3,17,46,1,12,136,232,1,17,87,255,1, + 0,0,0,2,9,46,135,1,6,90,121,1,9,139,187,1,12,190,255,1, + 8,124,167,1,3,45,61,1,4,57,76,1,4,70,94,1,15,142,249,1, + 8,23,85,1,0,0,0,3,0,0,6,1,15,100,255,1,12,189,255,1, + 12,190,255,2,17,79,255,1,7,26,99,1,8,78,148,1,14,114,255,1, + 17,43,246,1,0,0,0,1,15,97,241,1,5,77,112,1,9,125,182,1, + 11,158,230,1,2,35,51,1,12,170,247,1,12,175,255,1,6,89,129,1, + 9,57,134,1,0,0,0,3,21,53,255,1,16,101,255,1,12,172,255,1, + 12,175,255,2,13,155,255,1,22,48,255,1,14,24,161,1,3,24,61,1, + 14,118,255,1,12,52,177,1,0,0,5,1,16,91,255,1,6,67,112,1, + 9,109,182,1,9,103,171,1,6,72,120,1,13,153,255,2,12,147,245,1, + 13,131,236,1,10,59,164,1,3,23,63,1,12,74,192,1,11,101,202,1, + 12,142,237,1,13,153,255,3,16,96,255,1,0,0,0,2,3,13,54,1, + 12,91,225,1,6,41,102,1,11,42,170,1,17,68,255,1,6,58,112,1, + 9,94,182,1,8,84,162,1,7,68,131,1,13,132,255,4,9,95,184,1, + 3,27,52,1,6,62,119,2,11,107,207,1,13,132,255,2,13,123,255,1, + 16,52,255,1,0,0,0,2,6,12,80,1,7,38,129,1,3,18,53,1, + 16,70,254,1,21,35,255,1,6,43,111,1,10,79,182,1,11,84,194,1, + 5,43,98,1,14,111,255,2,11,90,206,1,10,82,188,1,10,80,184,1, + 6,48,111,1,14,111,255,5,16,61,255,1,0,0,255,1,0,0,0,3, + 1,2,16,1,8,35,128,1,16,70,255,1,18,36,255,1,7,22,95,1, + 10,64,182,1,14,89,253,1,3,22,61,1,9,61,173,1,11,74,209,1, + 4,24,67,1,11,72,204,1,10,65,184,1,5,31,88,1,11,72,204,2, + 12,76,214,1,14,90,255,1,17,63,255,1,14,28,255,1,0,0,0,4, + 0,0,9,1,16,30,217,1,15,54,255,1,18,41,255,1,9,19,128,1, + 12,54,220,1,15,69,255,1,14,65,241,1,8,38,142,1,7,34,124,1, + 12,55,203,1,15,69,255,1,13,60,222,1,8,37,136,3,9,43,160,1, + 18,47,255,1,15,29,255,1,0,0,0,6,0,0,255,1,18,28,255,1, + 17,34,255,1,17,27,255,1,18,31,255,1,16,46,255,1,15,48,255,8, + 16,43,255,1,18,32,255,1,26,26,255,1,0,0,0,9,20,20,255,1, + 19,21,255,1,14,14,255,1,18,22,255,1,17,26,255,1,16,27,255,5, + 17,26,255,1,19,24,255,1,19,23,255,1,0,0,0,15,23,23,255,1, + 20,20,255,1,19,19,255,4,18,18,255,1,0,0,0,8,0,5,0,0, + 0,0,0,30,6,6,6,1,89,89,89,1,143,143,143,1,193,193,193,1, + 132,132,132,1,0,0,0,2,169,169,169,1,189,189,189,1,140,140,140,1, + 56,56,56,1,0,0,0,12,90,90,90,1,207,207,207,1,231,231,231,1, + 157,157,157,1,52,52,52,1,0,0,0,4,46,46,46,1,134,134,134,1, + 208,208,208,1,193,193,193,1,81,81,81,1,0,0,0,8,1,1,1,1, + 141,141,141,1,239,239,239,1,149,149,149,1,22,22,22,1,0,0,0,8, + 4,4,4,1,127,127,127,1,231,231,231,1,151,151,151,1,5,5,5,1, + 0,0,0,5,9,9,9,1,166,166,166,1,247,247,247,1,129,129,129,1, + 0,0,0,12,88,88,88,1,240,240,240,1,189,189,189,1,20,20,20,1, + 0,0,0,2,26,26,26,1,184,184,184,1,222,222,222,1,255,255,255,1, + 176,176,176,1,7,7,7,1,226,226,226,1,170,170,170,1,177,177,177,1, + 226,226,226,1,157,157,157,1,230,230,230,1,177,177,177,2,168,168,168,1, + 10,10,10,1,0,0,0,3,132,132,132,1,255,255,255,1,194,194,194,1, + 8,8,8,1,0,0,0,1,128,128,128,1,152,152,152,1,248,248,248,1, + 177,177,177,1,175,175,175,1,7,7,7,1,209,209,209,1,25,25,25,1, + 22,22,22,1,237,237,237,1,255,255,255,2,237,237,237,1,191,191,191,1, + 210,210,210,1,189,189,189,1,131,131,131,1,15,15,15,1,0,0,0,1, + 4,4,4,1,195,195,195,1,255,255,255,1,142,142,142,1,0,0,0,1, + 74,74,74,1,242,242,242,1,228,228,228,1,22,22,22,1,0,0,0,1, + 7,7,7,1,243,243,243,1,247,247,247,1,240,240,240,1,255,255,255,4, + 242,242,242,1,238,238,238,2,248,248,248,1,38,38,38,1,0,0,0,2, + 97,97,97,1,254,254,254,1,214,214,214,1,3,3,3,1,86,86,86,1, + 253,253,253,1,207,207,207,1,206,206,206,1,60,60,60,1,7,7,7,1, + 248,248,248,1,255,255,255,2,254,254,254,1,255,255,255,4,242,242,242,1, + 76,76,76,1,26,26,26,1,5,5,5,1,0,0,0,2,8,8,8,1, + 228,228,228,1,252,252,252,1,63,63,63,1,186,186,186,1,250,250,250,1, + 42,42,42,1,24,24,24,1,204,204,204,1,7,7,7,1,215,215,215,1, + 184,184,184,1,165,165,165,1,37,37,37,1,162,162,162,1,255,255,255,4, + 197,197,197,1,0,0,0,5,207,207,207,1,255,255,255,1,118,118,118,1, + 223,223,223,1,246,246,246,1,53,53,53,1,98,98,98,1,175,175,175,1, + 7,7,7,1,221,221,221,1,69,69,69,1,77,77,77,1,68,68,68,1, + 114,114,114,1,255,255,255,4,245,245,245,1,22,22,22,1,0,0,0,4, + 209,209,209,1,255,255,255,1,145,145,145,1,215,215,215,1,235,235,235,1, + 129,129,129,1,104,104,104,1,12,12,12,1,3,3,3,1,119,119,119,1, + 148,148,148,1,191,191,191,1,213,213,213,1,244,244,244,1,255,255,255,4, + 228,228,228,1,1,1,1,1,0,0,0,3,16,16,16,1,237,237,237,1, + 255,255,255,1,158,158,158,1,220,220,220,1,245,245,245,1,26,26,26,1, + 0,0,0,3,100,100,100,1,236,236,236,1,255,255,255,7,146,146,146,1, + 0,0,0,4,120,120,120,1,255,255,255,2,157,157,157,1,208,208,208,1, + 255,255,255,1,101,101,101,1,0,0,0,2,36,36,36,1,230,230,230,1, + 255,255,255,7,201,201,201,1,12,12,12,1,0,0,0,3,20,20,20,1, + 214,214,214,1,255,255,255,2,151,151,151,1,237,237,237,1,255,255,255,1, + 170,170,170,1,0,0,0,1,137,137,137,1,172,172,172,1,255,255,255,7, + 224,224,224,1,99,99,99,1,209,209,209,1,170,170,170,2,131,131,131,1, + 181,181,181,1,255,255,255,3,119,119,119,1,194,194,194,1,255,255,255,1, + 242,242,242,1,59,59,59,1,215,215,215,1,165,165,165,1,255,255,255,7, + 210,210,210,1,71,71,71,1,144,144,144,1,0,0,0,1,48,48,48,1, + 189,189,189,1,255,255,255,3,251,251,251,1,58,58,58,1,73,73,73,1, + 252,252,252,1,255,255,255,1,212,212,212,1,159,159,159,1,163,163,163,1, + 255,255,255,7,250,250,250,1,200,200,200,1,222,222,222,1,206,206,206,1, + 245,245,245,1,255,255,255,4,192,192,192,1,0,0,0,2,232,232,232,1, + 255,255,255,2,183,183,183,1,138,138,138,1,255,255,255,15,252,252,252,1, + 98,98,98,1,0,0,0,2,131,131,131,1,247,247,247,1,255,255,255,1, + 228,228,228,1,72,72,72,1,253,253,253,1,255,255,255,14,175,175,175,1, + 1,1,1,1,0,0,0,2,10,10,10,1,244,244,244,1,255,255,255,2, + 112,112,112,1,228,228,228,1,255,255,255,13,208,208,208,1,18,18,18,1, + 0,0,0,4,88,88,88,1,180,180,180,1,255,255,255,1,204,204,204,1, + 135,135,135,1,248,248,248,1,255,255,255,11,200,200,200,1,35,35,35,1, + 0,0,0,6,3,3,3,1,127,127,127,1,227,227,227,1,167,167,167,1, + 138,138,138,1,250,250,250,1,255,255,255,8,243,243,243,1,158,158,158,1, + 10,10,10,1,0,0,0,9,25,25,25,1,133,133,133,1,18,18,18,1, + 125,125,125,1,230,230,230,1,255,255,255,5,239,239,239,1,178,178,178,1, + 67,67,67,1,0,0,0,15,22,22,22,1,104,104,104,1,134,134,134,1, + 146,146,146,1,131,131,131,1,105,105,105,1,29,29,29,1,0,0,0,8, + 0,0) + ); + +const + objdata_tfb3service: record size: integer; data: array[0..3034] of byte end = + (size: 3035; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,102,98, + 51,115,101,114,118,105,99,101,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,100,11,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,188,5,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,30,0,0,255,1,17,72,255, + 1,14,111,255,1,15,95,255,1,17,70,255,1,0,0,0,2,17,62,255, + 1,15,96,255,1,15,104,255,1,7,20,91,1,0,0,0,12,17,85,255, + 1,14,138,255,1,13,153,255,1,16,114,255,1,15,54,255,1,0,0,0, + 4,17,55,255,1,13,99,255,1,9,68,167,1,6,50,107,1,16,75,252, + 1,0,0,0,8,0,0,255,1,16,96,255,1,12,163,255,1,15,98,255, + 1,12,35,255,1,0,0,0,8,0,0,255,1,14,88,255,1,13,148,255, + 1,15,100,255,1,0,0,213,1,0,0,0,5,0,0,142,1,15,100,255, + 1,11,180,255,1,14,89,255,1,0,0,0,12,10,44,137,1,1,22,32, + 1,0,4,8,1,0,0,0,5,3,22,57,1,3,53,70,1,10,57,150, + 1,0,0,0,3,1,1,10,1,3,25,63,1,14,101,236,1,2,8,27, + 1,1,1,10,1,0,0,0,6,15,80,224,1,9,176,222,1,7,62,132, + 1,0,0,0,3,6,25,82,1,11,182,255,1,15,94,237,1,0,0,0, + 3,20,20,255,1,23,23,255,1,13,158,255,1,9,196,242,1,2,33,42, + 1,13,158,251,1,13,130,255,1,8,54,114,1,7,44,104,1,12,78,212, + 1,6,6,81,1,0,0,0,1,0,0,255,1,16,128,255,1,10,204,255, + 1,4,23,59,1,0,0,0,1,0,0,9,1,2,21,43,1,9,96,171, + 1,11,33,233,1,0,0,0,2,1,9,23,1,9,132,202,1,11,122,201, + 1,8,166,210,1,0,0,0,1,1,32,40,1,10,202,251,1,13,143,255, + 1,6,59,117,1,7,80,140,1,6,62,109,1,0,0,2,1,0,0,0, + 2,16,74,255,1,10,191,251,1,2,23,42,1,0,0,1,1,18,65,255, + 1,9,155,215,1,5,27,75,1,0,0,0,3,1,8,19,1,5,108,136, + 1,5,106,136,1,8,119,176,1,9,189,242,1,2,33,42,1,3,67,84, + 1,2,44,55,1,4,43,75,1,16,69,235,1,12,12,149,1,0,0,1, + 1,0,0,0,2,0,0,5,1,2,21,38,1,2,28,40,1,11,33,150, + 1,10,67,159,1,11,156,236,1,18,36,255,1,0,0,0,3,0,1,6, + 1,15,111,255,1,15,91,255,1,21,28,255,1,16,93,255,1,2,32,42, + 1,10,198,251,1,9,171,217,1,2,50,63,1,16,126,255,1,0,0,0, + 5,11,100,190,1,10,200,254,1,15,80,255,1,8,65,135,1,4,49,88, + 1,5,5,32,1,0,0,0,4,0,0,4,1,3,3,30,1,0,0,0, + 1,15,68,237,1,2,31,42,1,11,195,251,1,11,198,255,1,4,79,102, + 1,8,105,169,1,23,23,255,1,0,0,0,4,15,134,255,1,11,198,255, + 1,16,102,255,1,14,130,255,1,11,100,187,1,0,0,4,1,0,0,0, + 4,3,12,50,1,7,36,96,1,6,51,113,1,11,161,241,1,7,120,156, + 1,11,194,253,1,11,196,255,1,10,177,230,1,9,82,158,1,0,0,255, + 1,0,0,0,3,16,16,255,1,14,151,255,1,11,196,255,1,16,111,255, + 1,15,125,255,1,14,148,255,1,20,20,255,1,0,0,0,3,18,84,255, + 1,13,158,255,1,11,194,255,6,11,192,255,1,17,94,255,1,0,0,0, + 4,17,81,255,1,12,190,255,1,11,194,255,1,16,110,255,2,13,160,255, + 1,18,63,255,1,0,0,0,2,14,43,255,1,14,149,255,1,12,192,255, + 7,15,119,255,1,21,43,255,1,0,0,0,3,13,38,255,1,14,133,255, + 1,12,192,255,2,15,105,255,1,3,21,58,1,11,129,219,1,17,87,255, + 1,0,0,0,2,9,40,118,1,6,102,137,1,8,128,172,1,12,190,255, + 1,8,133,178,1,3,46,62,1,4,57,77,1,4,64,86,1,14,139,244, + 1,9,29,106,1,0,0,0,3,0,0,5,1,15,100,255,1,12,189,255, + 1,12,190,255,2,17,79,255,1,7,31,115,1,7,69,132,1,14,114,255, + 1,18,45,255,1,0,0,0,1,14,91,228,1,6,88,128,1,8,114,166, + 1,11,165,240,1,2,31,45,1,11,167,243,1,12,175,255,1,7,100,145, + 1,7,50,117,1,0,0,0,3,21,53,255,1,16,101,255,1,12,172,255, + 1,12,175,255,2,13,155,255,1,22,48,255,1,16,28,191,1,3,20,50, + 1,14,118,255,1,12,58,195,1,0,0,4,1,16,91,255,1,7,77,128, + 1,8,100,166,1,10,112,187,1,5,62,104,1,13,153,255,2,13,148,247, + 1,13,130,234,1,12,65,183,1,3,19,54,1,12,74,192,1,11,101,202, + 1,12,140,234,1,13,153,255,3,16,96,255,1,0,0,0,2,4,17,66, + 1,12,85,211,1,6,47,117,1,11,36,151,1,17,68,255,1,7,66,128, + 1,8,86,166,1,9,92,178,1,6,60,115,1,13,132,255,4,10,104,200, + 1,2,23,44,1,6,62,119,2,10,103,199,1,13,132,255,2,13,123,255, + 1,16,52,255,1,0,0,0,2,9,15,96,1,7,34,118,1,3,18,53, + 1,16,69,249,1,21,35,255,1,7,50,126,1,9,72,166,1,11,91,209, + 1,4,36,82,1,14,111,255,2,12,93,214,1,10,78,180,1,11,87,200, + 1,5,41,95,1,14,111,255,5,16,61,255,1,0,0,255,1,0,0,0, + 3,1,3,21,1,7,30,112,1,16,70,255,1,18,36,255,1,8,26,110, + 1,9,59,166,1,14,90,255,1,4,25,70,1,9,58,164,1,12,75,212, + 1,4,26,75,1,10,67,191,1,11,71,200,1,4,27,76,1,11,72,204, + 2,12,74,211,1,14,90,255,1,17,63,255,1,14,28,255,1,0,0,0, + 4,0,0,10,1,14,29,207,1,15,54,255,1,18,41,255,1,10,20,139, + 1,12,52,213,1,15,69,255,1,14,67,246,1,9,40,146,1,7,33,123, + 1,11,53,195,1,15,69,255,1,13,62,229,1,8,37,136,3,9,41,152, + 1,18,47,255,1,15,29,255,1,0,0,0,6,0,0,255,1,18,28,255, + 1,17,34,255,1,17,27,255,1,18,31,255,1,16,46,255,1,15,48,255, + 8,16,43,255,1,18,32,255,1,26,26,255,1,0,0,0,9,20,20,255, + 1,19,21,255,1,14,14,255,1,18,22,255,1,17,26,255,1,16,27,255, + 5,17,26,255,1,19,24,255,1,19,23,255,1,0,0,0,15,23,23,255, + 1,20,20,255,1,19,19,255,4,18,18,255,1,0,0,0,8,112,5,0, + 0,0,0,0,17,76,76,76,1,197,197,197,1,242,242,242,2,220,220,220, + 1,120,120,120,1,2,2,2,1,0,0,0,6,6,6,6,1,89,89,89, + 1,143,143,143,1,193,193,193,1,132,132,132,1,0,0,0,2,169,169,169, + 1,189,189,189,1,140,140,140,1,112,112,112,1,253,253,253,1,115,115,115, + 1,4,4,4,1,0,0,0,1,68,68,68,1,248,248,248,1,119,119,119, + 1,0,0,0,5,90,90,90,1,207,207,207,1,231,231,231,1,157,157,157, + 1,52,52,52,1,0,0,0,4,46,46,46,1,134,134,134,1,222,222,222, + 1,225,225,225,1,82,82,82,1,0,0,0,3,208,208,208,1,185,185,185, + 1,0,0,0,3,1,1,1,1,141,141,141,1,239,239,239,1,149,149,149, + 1,22,22,22,1,0,0,0,8,4,4,4,1,127,127,127,1,231,231,231, + 1,151,151,151,1,6,6,6,1,82,82,82,1,249,249,249,1,101,101,101, + 1,0,0,0,2,9,9,9,1,166,166,166,1,247,247,247,1,129,129,129, + 1,0,0,0,12,127,127,127,1,253,253,253,1,252,252,252,1,253,253,253, + 1,119,119,119,1,0,0,0,1,19,19,19,1,180,180,180,1,223,223,223, + 1,255,255,255,1,180,180,180,1,0,0,0,1,222,222,222,1,170,170,170, + 1,177,177,177,1,226,226,226,1,162,162,162,1,223,223,223,1,178,178,178, + 1,175,175,175,1,174,174,174,1,16,16,16,1,0,0,0,2,5,5,5, + 1,140,140,140,1,255,255,255,1,219,219,219,1,247,247,247,1,119,119,119, + 1,112,112,112,1,162,162,162,1,248,248,248,1,174,174,174,1,183,183,183, + 1,0,0,0,1,216,216,216,1,25,25,25,1,22,22,22,1,237,237,237, + 1,255,255,255,2,237,237,237,1,191,191,191,1,204,204,204,1,196,196,196, + 1,143,143,143,1,41,41,41,1,0,0,0,1,4,4,4,1,195,195,195, + 1,255,255,255,1,215,215,215,1,231,231,231,1,60,60,60,1,244,244,244, + 1,229,229,229,1,23,23,23,1,0,0,0,2,244,244,244,1,247,247,247, + 1,240,240,240,1,255,255,255,4,242,242,242,1,236,236,236,1,239,239,239, + 1,252,252,252,1,246,246,246,1,26,26,26,1,0,0,0,1,97,97,97, + 1,254,254,254,1,247,247,247,1,195,195,195,1,86,86,86,1,253,253,253, + 1,205,205,205,1,208,208,208,1,71,71,71,1,0,0,0,1,248,248,248, + 1,255,255,255,2,254,254,254,1,255,255,255,4,244,244,244,1,78,78,78, + 1,41,41,41,1,190,190,190,1,236,236,236,1,162,162,162,1,154,154,154, + 1,251,251,251,1,255,255,255,1,92,92,92,1,184,184,184,1,250,250,250, + 1,42,42,42,1,17,17,17,1,211,211,211,1,0,0,0,1,221,221,221, + 1,184,184,184,1,165,165,165,1,37,37,37,1,162,162,162,1,255,255,255, + 4,197,197,197,1,0,0,0,2,44,44,44,1,85,85,85,1,92,92,92, + 1,217,217,217,1,255,255,255,1,118,118,118,1,219,219,219,1,247,247,247, + 1,55,55,55,1,88,88,88,1,188,188,188,1,0,0,0,1,224,224,224, + 1,69,69,69,1,77,77,77,1,68,68,68,1,116,116,116,1,255,255,255, + 4,246,246,246,1,22,22,22,1,0,0,0,4,209,209,209,1,255,255,255, + 1,145,145,145,1,215,215,215,1,235,235,235,1,127,127,127,1,109,109,109, + 1,16,16,16,1,0,0,0,1,115,115,115,1,148,148,148,1,191,191,191, + 1,213,213,213,1,245,245,245,1,255,255,255,4,229,229,229,1,1,1,1, + 1,0,0,0,3,16,16,16,1,237,237,237,1,255,255,255,1,158,158,158, + 1,220,220,220,1,245,245,245,1,26,26,26,1,0,0,0,3,100,100,100, + 1,236,236,236,1,255,255,255,7,146,146,146,1,0,0,0,4,120,120,120, + 1,255,255,255,2,157,157,157,1,208,208,208,1,255,255,255,1,101,101,101, + 1,0,0,0,2,36,36,36,1,230,230,230,1,255,255,255,7,201,201,201, + 1,12,12,12,1,0,0,0,3,20,20,20,1,214,214,214,1,255,255,255, + 2,151,151,151,1,234,234,234,1,255,255,255,1,170,170,170,1,0,0,0, + 1,122,122,122,1,179,179,179,1,255,255,255,7,224,224,224,1,87,87,87, + 1,213,213,213,1,170,170,170,2,142,142,142,1,181,181,181,1,255,255,255, + 3,119,119,119,1,187,187,187,1,255,255,255,1,242,242,242,1,57,57,57, + 1,209,209,209,1,169,169,169,1,255,255,255,7,215,215,215,1,55,55,55, + 1,160,160,160,1,0,0,0,1,48,48,48,1,189,189,189,1,255,255,255, + 3,251,251,251,1,58,58,58,1,64,64,64,1,253,253,253,1,255,255,255, + 1,208,208,208,1,175,175,175,1,163,163,163,1,255,255,255,7,250,250,250, + 1,195,195,195,1,227,227,227,1,206,206,206,1,245,245,245,1,255,255,255, + 4,192,192,192,1,0,0,0,2,228,228,228,1,255,255,255,2,189,189,189, + 1,138,138,138,1,255,255,255,15,252,252,252,1,98,98,98,1,0,0,0, + 2,119,119,119,1,247,247,247,1,255,255,255,1,229,229,229,1,72,72,72, + 1,252,252,252,1,255,255,255,14,175,175,175,1,1,1,1,1,0,0,0, + 2,4,4,4,1,239,239,239,1,255,255,255,2,112,112,112,1,224,224,224, + 1,255,255,255,13,208,208,208,1,18,18,18,1,0,0,0,4,80,80,80, + 1,182,182,182,1,255,255,255,1,204,204,204,1,130,130,130,1,248,248,248, + 1,255,255,255,11,200,200,200,1,35,35,35,1,0,0,0,6,3,3,3, + 1,127,127,127,1,227,227,227,1,167,167,167,1,138,138,138,1,250,250,250, + 1,255,255,255,8,243,243,243,1,158,158,158,1,10,10,10,1,0,0,0, + 9,25,25,25,1,133,133,133,1,18,18,18,1,125,125,125,1,230,230,230, + 1,255,255,255,5,239,239,239,1,178,178,178,1,67,67,67,1,0,0,0, + 15,22,22,22,1,104,104,104,1,134,134,134,1,146,146,146,1,131,131,131, + 1,105,105,105,1,29,29,29,1,0,0,0,8,0,0) + ); + +const + objdata_tdatasource: record size: integer; data: array[0..911] of byte end = + (size: 912; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,100,97, + 116,97,115,111,117,114,99,101,12,98,105,116,109,97,112,46,105,109,97,103, + 101,10,96,3,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0, + 0,0,44,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0, + 255,49,137,134,136,1,130,127,129,1,129,126,128,1,137,134,136,1,130,127, + 129,1,137,134,136,1,131,128,130,1,136,133,135,1,139,136,138,1,136,133, + 135,1,135,130,132,1,130,129,131,1,131,136,139,1,126,131,134,1,135,130, + 132,1,255,0,255,9,134,131,133,1,202,199,201,1,205,202,204,1,192,189, + 191,1,198,195,197,2,189,186,188,1,193,190,192,1,194,191,193,2,195,192, + 194,1,198,197,199,1,192,193,197,1,189,191,192,1,129,124,126,1,255,0, + 255,9,126,123,125,1,136,133,135,1,128,127,129,1,135,134,136,2,126,125, + 127,1,134,133,135,1,139,138,140,1,137,136,138,1,134,133,135,1,128,127, + 129,1,130,129,131,1,137,134,136,1,136,133,135,1,139,134,136,1,255,0, + 255,9,135,132,134,1,247,244,246,1,255,254,255,2,242,241,243,1,214,213, + 215,1,250,249,251,1,251,250,252,1,253,252,254,1,255,254,255,1,254,253, + 255,1,255,254,255,1,255,252,254,1,255,254,255,1,133,127,128,1,255,0, + 255,4,31,31,224,1,255,0,255,4,133,130,132,1,255,254,255,1,208,207, + 209,1,185,184,186,1,255,254,255,1,199,198,200,1,236,238,239,1,205,207, + 208,1,191,193,194,1,193,195,196,1,192,194,195,1,197,196,198,1,199,197, + 197,1,255,250,251,1,142,136,137,1,255,0,255,4,31,31,224,2,255,0, + 255,3,134,131,133,1,255,253,255,1,252,251,253,1,255,254,255,1,252,251, + 253,1,190,189,191,1,253,255,255,1,250,252,253,2,253,255,255,2,252,251, + 253,1,255,255,255,1,254,252,252,1,141,136,135,1,255,0,255,1,31,31, + 224,6,255,0,255,2,132,129,131,1,253,250,252,1,205,204,206,1,192,191, + 193,1,255,254,255,1,190,189,191,1,255,254,255,1,195,194,196,2,196,195, + 197,1,197,196,198,1,195,194,196,1,255,255,255,2,129,125,124,1,255,0, + 255,4,31,31,224,2,255,0,255,3,132,129,131,1,255,254,255,1,243,242, + 244,1,255,254,255,2,195,194,196,1,242,241,243,1,255,254,255,3,255,253, + 255,1,255,254,255,1,244,244,244,1,255,255,255,1,138,136,136,1,255,0, + 255,4,31,31,224,1,255,0,255,4,135,132,134,1,255,252,254,1,213,210, + 212,1,191,188,190,1,249,246,248,1,204,201,203,1,255,254,255,1,191,188, + 190,1,201,196,198,1,194,191,193,1,191,186,188,1,202,199,201,2,255,255, + 255,1,126,124,124,1,255,0,255,9,140,137,139,1,248,245,247,1,255,252, + 254,1,255,254,255,2,193,188,190,1,255,254,255,1,255,253,255,1,255,252, + 255,1,255,253,255,1,255,249,252,1,255,254,255,1,255,253,255,1,255,254, + 255,1,131,128,130,1,255,0,255,9,129,126,128,1,137,134,136,1,134,129, + 131,1,142,137,139,1,135,130,132,1,141,134,137,1,132,125,128,1,137,128, + 131,2,131,122,125,1,134,125,128,1,137,128,131,1,139,133,138,1,131,126, + 128,1,131,124,127,1,255,0,255,41,31,31,224,1,255,0,255,6,31,31, + 224,1,255,0,255,16,31,31,224,1,255,0,255,7,31,31,224,1,255,0, + 255,15,31,31,224,1,255,0,255,8,31,31,224,1,255,0,255,2,31,31, + 224,1,255,0,255,11,31,31,224,1,255,0,255,9,31,31,224,3,255,0, + 255,11,31,31,224,1,255,0,255,9,31,31,224,3,255,0,255,9,31,31, + 224,5,255,0,255,6,31,31,224,4,255,0,255,10,31,31,224,3,255,0, + 255,22,31,31,224,1,255,0,255,62,0,0) + ); + +const + objdata_tdbnavigator: record size: integer; data: array[0..460] of byte end = + (size: 461; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,100,98, + 110,97,118,105,103,97,116,111,114,12,98,105,116,109,97,112,46,105,109,97, + 103,101,10,156,1,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24, + 0,0,0,104,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255, + 0,255,192,255,255,255,23,128,128,128,1,255,255,255,1,255,0,255,22,128, + 128,128,1,255,255,255,1,255,0,255,22,128,128,128,1,255,255,255,1,0, + 0,0,1,255,0,255,2,0,0,0,1,255,0,255,3,0,0,0,1,255, + 0,255,1,0,0,0,1,255,0,255,3,0,0,0,1,255,0,255,2,0, + 0,0,1,255,0,255,5,128,128,128,1,255,255,255,1,0,0,0,1,255, + 0,255,1,0,0,0,2,255,0,255,2,0,0,0,2,255,0,255,1,0, + 0,0,2,255,0,255,2,0,0,0,2,255,0,255,1,0,0,0,1,255, + 0,255,2,0,0,0,1,255,0,255,2,128,128,128,1,255,255,255,1,0, + 0,0,4,255,0,255,1,0,0,0,3,255,0,255,1,0,0,0,3,255, + 0,255,1,0,0,0,4,255,0,255,1,0,0,0,3,255,0,255,1,128, + 128,128,1,255,255,255,1,0,0,0,1,255,0,255,1,0,0,0,2,255, + 0,255,2,0,0,0,2,255,0,255,1,0,0,0,2,255,0,255,2,0, + 0,0,2,255,0,255,1,0,0,0,1,255,0,255,2,0,0,0,1,255, + 0,255,2,128,128,128,1,255,255,255,1,0,0,0,1,255,0,255,2,0, + 0,0,1,255,0,255,3,0,0,0,1,255,0,255,1,0,0,0,1,255, + 0,255,3,0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,5,128, + 128,128,1,255,255,255,1,255,0,255,22,128,128,128,1,255,255,255,1,255, + 0,255,22,128,128,128,1,255,255,255,1,128,128,128,23,255,0,255,120,0, + 0) + ); + +const + objdata_tdbstringedit: record size: integer; data: array[0..824] of byte end = + (size: 825; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,100,98, + 115,116,114,105,110,103,101,100,105,116,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,192,2,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,120,2,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,255,255,255,120,128,128,128,25,0, + 0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,20,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,7,17, + 23,23,1,184,255,255,9,0,0,0,1,184,255,255,1,0,0,0,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,7,17, + 23,23,1,184,255,255,10,0,0,0,1,184,255,255,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,133,184,184,1,42, + 58,58,1,43,60,60,1,34,47,47,1,154,213,213,1,184,255,255,1,14, + 20,20,1,61,84,84,1,42,58,58,1,44,61,61,1,154,213,213,1,150, + 208,208,1,42,58,58,1,44,61,61,1,55,76,76,1,175,242,242,1,184, + 255,255,1,0,0,0,1,184,255,255,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,184,255,255,1,105,145,145,1,165,229,229,1,184, + 255,255,1,97,134,134,1,95,132,132,1,184,255,255,1,8,11,11,1,136, + 189,189,1,184,255,255,1,141,196,196,1,42,58,58,2,146,203,203,1,184, + 255,255,1,118,164,164,1,143,198,198,1,184,255,255,1,0,0,0,1,184, + 255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184, + 255,255,1,123,171,171,1,60,83,83,1,69,96,96,1,50,69,69,1,92, + 127,127,1,184,255,255,1,12,16,16,1,184,255,255,2,183,254,254,1,15, + 21,21,1,17,23,23,1,184,255,255,5,0,0,0,1,184,255,255,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,13, + 18,18,1,176,244,244,1,184,255,255,1,75,104,104,1,92,127,127,1,184, + 255,255,1,8,11,11,1,145,201,201,1,184,255,255,1,137,190,190,1,47, + 65,65,1,38,53,53,1,152,211,211,1,184,255,255,1,106,147,147,1,118, + 164,164,1,184,255,255,1,0,0,0,1,184,255,255,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,82,113,113,1,34, + 47,47,1,53,74,74,1,80,111,111,1,74,103,103,1,184,255,255,1,23, + 32,32,1,58,81,81,1,43,60,60,1,48,66,66,1,159,220,220,1,147, + 204,204,1,40,55,55,1,43,60,60,1,58,80,80,1,176,244,244,1,184, + 255,255,1,0,0,0,1,184,255,255,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,184,255,255,17,0,0,0,1,184,255,255,1,0, + 0,0,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184, + 255,255,20,224,224,224,1,255,255,255,1,128,128,128,1,224,224,224,22,255, + 255,255,145,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255,81,0, + 0,0,120,0,0) + ); + +const + objdata_tdropdownlisteditdb: record size: integer; data: array[0..1402] of byte end = + (size: 1403; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,100,114, + 111,112,100,111,119,110,108,105,115,116,101,100,105,116,100,98,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,252,4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,184,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128, + 25,255,255,255,2,165,165,165,1,0,0,0,1,165,165,165,1,255,255,255, + 2,0,0,0,1,1,1,1,1,75,75,75,1,255,255,255,4,0,0,0, + 1,231,231,231,1,0,0,0,1,255,255,255,6,128,128,128,1,255,255,255, + 2,88,88,88,1,75,75,75,1,89,89,89,1,255,255,255,2,0,0,0, + 1,234,234,234,1,70,70,70,1,255,255,255,5,0,0,0,1,255,255,255, + 2,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255, + 1,251,251,251,1,21,21,21,1,221,221,221,1,20,20,20,1,251,251,251, + 1,255,255,255,1,0,0,0,2,117,117,117,1,255,255,255,5,0,0,0, + 1,255,255,255,2,0,0,0,3,128,128,128,1,255,255,255,1,128,128,128, + 1,255,255,255,1,191,191,191,1,0,0,0,3,191,191,191,1,255,255,255, + 1,0,0,0,1,243,243,243,1,11,11,11,1,255,255,255,5,0,0,0, + 1,255,255,255,2,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128, + 1,255,255,255,1,128,128,128,1,255,255,255,1,114,114,114,1,141,141,141, + 1,255,255,255,1,141,141,141,1,115,115,115,1,255,255,255,1,0,0,0, + 1,235,235,235,1,19,19,19,1,255,255,255,3,252,252,252,1,231,231,231, + 1,0,0,0,1,247,247,247,1,255,255,255,1,208,208,208,3,128,128,128, + 1,255,255,255,1,128,128,128,1,255,255,255,1,37,37,37,1,217,217,217, + 1,255,255,255,1,217,217,217,1,38,38,38,1,255,255,255,1,0,0,0, + 1,3,3,3,1,124,124,124,1,255,255,255,3,223,223,223,1,0,0,0, + 1,223,223,223,1,0,0,0,1,128,128,128,5,255,255,255,25,0,0,0, + 25,184,255,255,17,255,255,255,5,0,0,0,2,184,255,255,2,119,165,165, + 1,0,0,0,1,119,165,165,1,184,255,255,2,0,0,0,1,1,1,1, + 1,54,75,75,1,184,255,255,1,167,232,232,1,56,77,77,1,6,9,9, + 1,27,38,38,1,146,203,203,1,184,255,255,1,255,255,255,1,208,208,208, + 1,0,0,0,1,208,208,208,1,128,128,128,1,0,0,0,2,184,255,255, + 2,63,88,88,1,54,75,75,1,64,89,89,1,184,255,255,2,0,0,0, + 1,169,234,234,1,51,70,70,1,184,255,255,1,59,82,82,1,85,118,118, + 1,177,245,245,1,120,166,166,1,38,53,53,1,184,255,255,1,255,255,255, + 1,0,0,0,3,128,128,128,1,0,0,0,2,184,255,255,1,181,251,251, + 1,15,21,21,1,159,221,221,1,14,20,20,1,181,251,251,1,184,255,255, + 1,0,0,0,2,84,117,117,1,184,255,255,1,9,12,12,1,174,241,241, + 1,184,255,255,4,255,255,255,1,208,208,208,3,128,128,128,1,0,0,0, + 2,184,255,255,1,138,191,191,1,0,0,0,3,138,191,191,1,184,255,255, + 1,0,0,0,1,175,243,243,1,8,11,11,1,184,255,255,1,10,14,14, + 1,174,241,241,1,184,255,255,1,182,252,252,1,152,210,210,1,184,255,255, + 1,128,128,128,5,0,0,0,2,184,255,255,1,82,114,114,1,102,141,141, + 1,184,255,255,1,102,141,141,1,83,115,115,1,184,255,255,1,0,0,0, + 1,170,235,235,1,14,19,19,1,184,255,255,1,60,83,83,1,89,124,124, + 1,177,245,245,1,105,145,145,1,41,57,57,1,184,255,255,1,255,255,255, + 1,212,212,212,1,252,252,252,1,208,208,208,1,255,255,255,1,0,0,0, + 2,184,255,255,1,27,37,37,1,157,217,217,1,184,255,255,1,157,217,217, + 1,27,38,38,1,184,255,255,1,0,0,0,1,2,3,3,1,89,124,124, + 1,184,255,255,1,164,227,227,1,45,63,63,1,5,7,7,1,31,43,43, + 1,154,213,213,1,184,255,255,1,255,255,255,4,128,128,128,1,0,0,0, + 2,184,255,255,17,255,255,255,1,128,128,128,4,0,0,0,2,184,255,255, + 2,0,0,0,2,4,5,5,1,126,174,174,1,184,255,255,11,208,208,208, + 1,255,255,255,1,211,211,211,1,255,255,255,1,208,208,208,1,0,0,0, + 2,184,255,255,2,0,0,0,1,184,255,255,1,126,174,174,1,4,5,5, + 1,184,255,255,1,110,152,152,1,8,11,11,1,115,159,159,1,184,255,255, + 7,255,255,255,2,252,252,252,1,255,255,255,2,0,0,0,2,184,255,255, + 2,0,0,0,1,184,255,255,2,0,0,0,1,184,255,255,1,21,29,29, + 1,142,197,197,1,27,37,37,1,184,255,255,7,255,255,255,1,208,208,208, + 3,128,128,128,1,0,0,0,2,184,255,255,2,0,0,0,1,184,255,255, + 2,0,0,0,1,184,255,255,1,1,2,2,1,0,0,0,1,2,3,3, + 1,184,255,255,7,255,255,255,1,0,0,0,3,128,128,128,1,0,0,0, + 2,184,255,255,2,0,0,0,1,184,255,255,1,126,174,174,1,4,5,5, + 1,184,255,255,1,18,25,25,1,163,226,226,1,184,255,255,8,255,255,255, + 1,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,0,0,0, + 2,184,255,255,2,0,0,0,2,4,5,5,1,126,174,174,1,184,255,255, + 1,105,146,146,1,6,9,9,1,71,98,98,1,184,255,255,7,128,128,128, + 5,0,0,0,25,12,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 66,0,0) + ); + +const + objdata_tdropdownlisteditlb: record size: integer; data: array[0..1402] of byte end = + (size: 1403; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,100,114, + 111,112,100,111,119,110,108,105,115,116,101,100,105,116,108,98,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,252,4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,184,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128, + 25,255,255,255,2,165,165,165,1,0,0,0,1,165,165,165,1,255,255,255, + 2,0,0,0,1,1,1,1,1,75,75,75,1,255,255,255,4,0,0,0, + 1,231,231,231,1,0,0,0,1,255,255,255,6,128,128,128,1,255,255,255, + 2,88,88,88,1,75,75,75,1,89,89,89,1,255,255,255,2,0,0,0, + 1,234,234,234,1,70,70,70,1,255,255,255,5,0,0,0,1,255,255,255, + 2,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255, + 1,251,251,251,1,21,21,21,1,221,221,221,1,20,20,20,1,251,251,251, + 1,255,255,255,1,0,0,0,2,117,117,117,1,255,255,255,5,0,0,0, + 1,255,255,255,2,0,0,0,3,128,128,128,1,255,255,255,1,128,128,128, + 1,255,255,255,1,191,191,191,1,0,0,0,3,191,191,191,1,255,255,255, + 1,0,0,0,1,243,243,243,1,11,11,11,1,255,255,255,5,0,0,0, + 1,255,255,255,2,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128, + 1,255,255,255,1,128,128,128,1,255,255,255,1,114,114,114,1,141,141,141, + 1,255,255,255,1,141,141,141,1,115,115,115,1,255,255,255,1,0,0,0, + 1,235,235,235,1,19,19,19,1,255,255,255,3,252,252,252,1,231,231,231, + 1,0,0,0,1,247,247,247,1,255,255,255,1,208,208,208,3,128,128,128, + 1,255,255,255,1,128,128,128,1,255,255,255,1,37,37,37,1,217,217,217, + 1,255,255,255,1,217,217,217,1,38,38,38,1,255,255,255,1,0,0,0, + 1,3,3,3,1,124,124,124,1,255,255,255,3,223,223,223,1,0,0,0, + 1,223,223,223,1,0,0,0,1,128,128,128,5,255,255,255,25,0,0,0, + 25,201,201,255,17,255,255,255,5,0,0,0,2,201,201,255,2,130,130,165, + 1,0,0,0,1,130,130,165,1,201,201,255,2,0,0,0,1,1,1,1, + 1,59,59,75,1,201,201,255,1,183,183,232,1,61,61,77,1,7,7,9, + 1,30,30,38,1,160,160,203,1,201,201,255,1,255,255,255,1,208,208,208, + 1,0,0,0,1,208,208,208,1,128,128,128,1,0,0,0,2,201,201,255, + 2,69,69,88,1,59,59,75,1,70,70,89,1,201,201,255,2,0,0,0, + 1,184,184,234,1,55,55,70,1,201,201,255,1,65,65,82,1,93,93,118, + 1,193,193,245,1,131,131,166,1,42,42,53,1,201,201,255,1,255,255,255, + 1,0,0,0,3,128,128,128,1,0,0,0,2,201,201,255,1,198,198,251, + 1,17,17,21,1,174,174,221,1,16,16,20,1,198,198,251,1,201,201,255, + 1,0,0,0,2,92,92,117,1,201,201,255,1,9,9,12,1,190,190,241, + 1,201,201,255,4,255,255,255,1,208,208,208,3,128,128,128,1,0,0,0, + 2,201,201,255,1,151,151,191,1,0,0,0,3,151,151,191,1,201,201,255, + 1,0,0,0,1,192,192,243,1,9,9,11,1,201,201,255,1,11,11,14, + 1,190,190,241,1,201,201,255,1,199,199,252,1,166,166,210,1,201,201,255, + 1,128,128,128,5,0,0,0,2,201,201,255,1,90,90,114,1,111,111,141, + 1,201,201,255,1,111,111,141,1,91,91,115,1,201,201,255,1,0,0,0, + 1,185,185,235,1,15,15,19,1,201,201,255,1,65,65,83,1,98,98,124, + 1,193,193,245,1,114,114,145,1,45,45,57,1,201,201,255,1,255,255,255, + 1,212,212,212,1,252,252,252,1,208,208,208,1,255,255,255,1,0,0,0, + 2,201,201,255,1,29,29,37,1,171,171,217,1,201,201,255,1,171,171,217, + 1,30,30,38,1,201,201,255,1,0,0,0,1,2,2,3,1,98,98,124, + 1,201,201,255,1,179,179,227,1,50,50,63,1,6,6,7,1,34,34,43, + 1,168,168,213,1,201,201,255,1,255,255,255,4,128,128,128,1,0,0,0, + 2,201,201,255,17,255,255,255,1,128,128,128,4,0,0,0,2,201,201,255, + 2,0,0,0,2,4,4,5,1,137,137,174,1,201,201,255,11,208,208,208, + 1,255,255,255,1,211,211,211,1,255,255,255,1,208,208,208,1,0,0,0, + 2,201,201,255,2,0,0,0,1,201,201,255,1,137,137,174,1,4,4,5, + 1,201,201,255,1,120,120,152,1,9,9,11,1,125,125,159,1,201,201,255, + 7,255,255,255,2,252,252,252,1,255,255,255,2,0,0,0,2,201,201,255, + 2,0,0,0,1,201,201,255,2,0,0,0,1,201,201,255,1,23,23,29, + 1,155,155,197,1,29,29,37,1,201,201,255,7,255,255,255,1,208,208,208, + 3,128,128,128,1,0,0,0,2,201,201,255,2,0,0,0,1,201,201,255, + 2,0,0,0,1,201,201,255,1,2,2,2,1,0,0,0,1,2,2,3, + 1,201,201,255,7,255,255,255,1,0,0,0,3,128,128,128,1,0,0,0, + 2,201,201,255,2,0,0,0,1,201,201,255,1,137,137,174,1,4,4,5, + 1,201,201,255,1,20,20,25,1,178,178,226,1,201,201,255,8,255,255,255, + 1,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,0,0,0, + 2,201,201,255,2,0,0,0,2,4,4,5,1,137,137,174,1,201,201,255, + 1,115,115,146,1,7,7,9,1,77,77,98,1,201,201,255,7,128,128,128, + 5,0,0,0,25,12,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 66,0,0) + ); + +const + objdata_tdbdropdownlistedit: record size: integer; data: array[0..1370] of byte end = + (size: 1371; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,100,98, + 100,114,111,112,100,111,119,110,108,105,115,116,101,100,105,116,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,220,4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,152,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128, + 25,184,255,255,2,119,165,165,1,0,0,0,1,119,165,165,1,184,255,255, + 2,0,0,0,1,1,1,1,1,54,75,75,1,184,255,255,4,0,0,0, + 1,167,231,231,1,0,0,0,1,255,255,255,6,128,128,128,1,184,255,255, + 2,63,88,88,1,54,75,75,1,64,89,89,1,184,255,255,2,0,0,0, + 1,169,234,234,1,51,70,70,1,184,255,255,5,0,0,0,1,184,255,255, + 1,255,255,255,1,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128, + 1,184,255,255,1,181,251,251,1,15,21,21,1,159,221,221,1,14,20,20, + 1,181,251,251,1,184,255,255,1,0,0,0,2,84,117,117,1,184,255,255, + 5,0,0,0,1,184,255,255,1,255,255,255,1,0,0,0,3,128,128,128, + 1,255,255,255,1,128,128,128,1,184,255,255,1,138,191,191,1,0,0,0, + 3,138,191,191,1,184,255,255,1,0,0,0,1,175,243,243,1,8,11,11, + 1,184,255,255,5,0,0,0,1,184,255,255,1,255,255,255,1,208,208,208, + 1,0,0,0,1,208,208,208,1,128,128,128,1,255,255,255,1,128,128,128, + 1,184,255,255,1,82,114,114,1,102,141,141,1,184,255,255,1,102,141,141, + 1,83,115,115,1,184,255,255,1,0,0,0,1,170,235,235,1,14,19,19, + 1,184,255,255,3,182,252,252,1,167,231,231,1,0,0,0,1,178,247,247, + 1,255,255,255,1,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128, + 1,184,255,255,1,27,37,37,1,157,217,217,1,184,255,255,1,157,217,217, + 1,27,38,38,1,184,255,255,1,0,0,0,1,2,3,3,1,89,124,124, + 1,184,255,255,3,161,223,223,1,0,0,0,1,161,223,223,1,0,0,0, + 1,128,128,128,5,255,255,255,25,0,0,0,25,255,255,255,22,0,0,0, + 2,255,255,255,2,165,165,165,1,0,0,0,1,165,165,165,1,255,255,255, + 2,0,0,0,1,1,1,1,1,75,75,75,1,255,255,255,1,232,232,232, + 1,77,77,77,1,9,9,9,1,38,38,38,1,203,203,203,1,255,255,255, + 2,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,0,0,0, + 2,255,255,255,2,88,88,88,1,75,75,75,1,89,89,89,1,255,255,255, + 2,0,0,0,1,234,234,234,1,70,70,70,1,255,255,255,1,82,82,82, + 1,118,118,118,1,245,245,245,1,166,166,166,1,53,53,53,1,255,255,255, + 2,0,0,0,3,128,128,128,1,0,0,0,2,255,255,255,1,251,251,251, + 1,21,21,21,1,221,221,221,1,20,20,20,1,251,251,251,1,255,255,255, + 1,0,0,0,2,117,117,117,1,255,255,255,1,12,12,12,1,241,241,241, + 1,255,255,255,5,208,208,208,3,128,128,128,1,0,0,0,2,255,255,255, + 1,191,191,191,1,0,0,0,3,191,191,191,1,255,255,255,1,0,0,0, + 1,243,243,243,1,11,11,11,1,255,255,255,1,14,14,14,1,241,241,241, + 1,255,255,255,1,252,252,252,1,210,210,210,1,255,255,255,1,128,128,128, + 5,0,0,0,2,255,255,255,1,114,114,114,1,141,141,141,1,255,255,255, + 1,141,141,141,1,115,115,115,1,255,255,255,1,0,0,0,1,235,235,235, + 1,19,19,19,1,255,255,255,1,83,83,83,1,124,124,124,1,245,245,245, + 1,145,145,145,1,57,57,57,1,255,255,255,2,212,212,212,1,252,252,252, + 1,208,208,208,1,255,255,255,1,0,0,0,2,255,255,255,1,37,37,37, + 1,217,217,217,1,255,255,255,1,217,217,217,1,38,38,38,1,255,255,255, + 1,0,0,0,1,3,3,3,1,124,124,124,1,255,255,255,1,227,227,227, + 1,63,63,63,1,7,7,7,1,43,43,43,1,213,213,213,1,255,255,255, + 5,128,128,128,1,0,0,0,2,255,255,255,18,128,128,128,4,0,0,0, + 2,255,255,255,2,0,0,0,2,5,5,5,1,174,174,174,1,255,255,255, + 11,208,208,208,1,255,255,255,1,211,211,211,1,255,255,255,1,208,208,208, + 1,0,0,0,2,255,255,255,2,0,0,0,1,255,255,255,1,174,174,174, + 1,5,5,5,1,255,255,255,1,152,152,152,1,11,11,11,1,159,159,159, + 1,255,255,255,9,252,252,252,1,255,255,255,2,0,0,0,2,255,255,255, + 2,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,1,29,29,29, + 1,197,197,197,1,37,37,37,1,255,255,255,8,208,208,208,3,128,128,128, + 1,0,0,0,2,255,255,255,2,0,0,0,1,255,255,255,2,0,0,0, + 1,255,255,255,1,2,2,2,1,0,0,0,1,3,3,3,1,255,255,255, + 8,0,0,0,3,128,128,128,1,0,0,0,2,255,255,255,2,0,0,0, + 1,255,255,255,1,174,174,174,1,5,5,5,1,255,255,255,1,25,25,25, + 1,226,226,226,1,255,255,255,9,208,208,208,1,0,0,0,1,208,208,208, + 1,128,128,128,1,0,0,0,2,255,255,255,2,0,0,0,2,5,5,5, + 1,174,174,174,1,255,255,255,1,146,146,146,1,9,9,9,1,98,98,98, + 1,255,255,255,7,128,128,128,5,0,0,0,25,12,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tdbdropdownlisteditdb: record size: integer; data: array[0..1416] of byte end = + (size: 1417; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,21,116,100,98, + 100,114,111,112,100,111,119,110,108,105,115,116,101,100,105,116,100,98,23,98, + 105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108, + 111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111, + 110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99, + 111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97, + 103,101,10,8,5,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24, + 0,0,0,196,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128, + 128,128,25,184,255,255,2,119,165,165,1,0,0,0,1,119,165,165,1,184, + 255,255,2,0,0,0,1,1,1,1,1,54,75,75,1,184,255,255,4,0, + 0,0,1,167,231,231,1,0,0,0,1,255,255,255,6,128,128,128,1,184, + 255,255,2,63,88,88,1,54,75,75,1,64,89,89,1,184,255,255,2,0, + 0,0,1,169,234,234,1,51,70,70,1,184,255,255,5,0,0,0,1,184, + 255,255,1,255,255,255,1,208,208,208,3,128,128,128,1,255,255,255,1,128, + 128,128,1,184,255,255,1,181,251,251,1,15,21,21,1,159,221,221,1,14, + 20,20,1,181,251,251,1,184,255,255,1,0,0,0,2,84,117,117,1,184, + 255,255,5,0,0,0,1,184,255,255,1,255,255,255,1,0,0,0,3,128, + 128,128,1,255,255,255,1,128,128,128,1,184,255,255,1,138,191,191,1,0, + 0,0,3,138,191,191,1,184,255,255,1,0,0,0,1,175,243,243,1,8, + 11,11,1,184,255,255,5,0,0,0,1,184,255,255,1,255,255,255,1,208, + 208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,255,255,255,1,128, + 128,128,1,184,255,255,1,82,114,114,1,102,141,141,1,184,255,255,1,102, + 141,141,1,83,115,115,1,184,255,255,1,0,0,0,1,170,235,235,1,14, + 19,19,1,184,255,255,3,182,252,252,1,167,231,231,1,0,0,0,1,178, + 247,247,1,255,255,255,1,208,208,208,3,128,128,128,1,255,255,255,1,128, + 128,128,1,184,255,255,1,27,37,37,1,157,217,217,1,184,255,255,1,157, + 217,217,1,27,38,38,1,184,255,255,1,0,0,0,1,2,3,3,1,89, + 124,124,1,184,255,255,3,161,223,223,1,0,0,0,1,161,223,223,1,0, + 0,0,1,128,128,128,5,255,255,255,25,0,0,0,25,184,255,255,17,255, + 255,255,5,0,0,0,2,184,255,255,2,119,165,165,1,0,0,0,1,119, + 165,165,1,184,255,255,2,0,0,0,1,1,1,1,1,54,75,75,1,184, + 255,255,1,167,232,232,1,56,77,77,1,6,9,9,1,27,38,38,1,146, + 203,203,1,184,255,255,1,255,255,255,1,208,208,208,1,0,0,0,1,208, + 208,208,1,128,128,128,1,0,0,0,2,184,255,255,2,63,88,88,1,54, + 75,75,1,64,89,89,1,184,255,255,2,0,0,0,1,169,234,234,1,51, + 70,70,1,184,255,255,1,59,82,82,1,85,118,118,1,177,245,245,1,120, + 166,166,1,38,53,53,1,184,255,255,1,255,255,255,1,0,0,0,3,128, + 128,128,1,0,0,0,2,184,255,255,1,181,251,251,1,15,21,21,1,159, + 221,221,1,14,20,20,1,181,251,251,1,184,255,255,1,0,0,0,2,84, + 117,117,1,184,255,255,1,9,12,12,1,174,241,241,1,184,255,255,4,255, + 255,255,1,208,208,208,3,128,128,128,1,0,0,0,2,184,255,255,1,138, + 191,191,1,0,0,0,3,138,191,191,1,184,255,255,1,0,0,0,1,175, + 243,243,1,8,11,11,1,184,255,255,1,10,14,14,1,174,241,241,1,184, + 255,255,1,182,252,252,1,152,210,210,1,184,255,255,1,128,128,128,5,0, + 0,0,2,184,255,255,1,82,114,114,1,102,141,141,1,184,255,255,1,102, + 141,141,1,83,115,115,1,184,255,255,1,0,0,0,1,170,235,235,1,14, + 19,19,1,184,255,255,1,60,83,83,1,89,124,124,1,177,245,245,1,105, + 145,145,1,41,57,57,1,184,255,255,1,255,255,255,1,212,212,212,1,252, + 252,252,1,208,208,208,1,255,255,255,1,0,0,0,2,184,255,255,1,27, + 37,37,1,157,217,217,1,184,255,255,1,157,217,217,1,27,38,38,1,184, + 255,255,1,0,0,0,1,2,3,3,1,89,124,124,1,184,255,255,1,164, + 227,227,1,45,63,63,1,5,7,7,1,31,43,43,1,154,213,213,1,184, + 255,255,1,255,255,255,4,128,128,128,1,0,0,0,2,184,255,255,17,255, + 255,255,1,128,128,128,4,0,0,0,2,184,255,255,2,0,0,0,2,4, + 5,5,1,126,174,174,1,184,255,255,11,208,208,208,1,255,255,255,1,211, + 211,211,1,255,255,255,1,208,208,208,1,0,0,0,2,184,255,255,2,0, + 0,0,1,184,255,255,1,126,174,174,1,4,5,5,1,184,255,255,1,110, + 152,152,1,8,11,11,1,115,159,159,1,184,255,255,7,255,255,255,2,252, + 252,252,1,255,255,255,2,0,0,0,2,184,255,255,2,0,0,0,1,184, + 255,255,2,0,0,0,1,184,255,255,1,21,29,29,1,142,197,197,1,27, + 37,37,1,184,255,255,7,255,255,255,1,208,208,208,3,128,128,128,1,0, + 0,0,2,184,255,255,2,0,0,0,1,184,255,255,2,0,0,0,1,184, + 255,255,1,1,2,2,1,0,0,0,1,2,3,3,1,184,255,255,7,255, + 255,255,1,0,0,0,3,128,128,128,1,0,0,0,2,184,255,255,2,0, + 0,0,1,184,255,255,1,126,174,174,1,4,5,5,1,184,255,255,1,18, + 25,25,1,163,226,226,1,184,255,255,8,255,255,255,1,208,208,208,1,0, + 0,0,1,208,208,208,1,128,128,128,1,0,0,0,2,184,255,255,2,0, + 0,0,2,4,5,5,1,126,174,174,1,184,255,255,1,105,146,146,1,6, + 9,9,1,71,98,98,1,184,255,255,7,128,128,128,5,0,0,0,25,12, + 0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tdbdropdownlisteditlb: record size: integer; data: array[0..1416] of byte end = + (size: 1417; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,21,116,100,98, + 100,114,111,112,100,111,119,110,108,105,115,116,101,100,105,116,108,98,23,98, + 105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108, + 111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111, + 110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99, + 111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97, + 103,101,10,8,5,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24, + 0,0,0,196,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128, + 128,128,25,184,255,255,2,119,165,165,1,0,0,0,1,119,165,165,1,184, + 255,255,2,0,0,0,1,1,1,1,1,54,75,75,1,184,255,255,4,0, + 0,0,1,167,231,231,1,0,0,0,1,255,255,255,6,128,128,128,1,184, + 255,255,2,63,88,88,1,54,75,75,1,64,89,89,1,184,255,255,2,0, + 0,0,1,169,234,234,1,51,70,70,1,184,255,255,5,0,0,0,1,184, + 255,255,1,255,255,255,1,208,208,208,3,128,128,128,1,255,255,255,1,128, + 128,128,1,184,255,255,1,181,251,251,1,15,21,21,1,159,221,221,1,14, + 20,20,1,181,251,251,1,184,255,255,1,0,0,0,2,84,117,117,1,184, + 255,255,5,0,0,0,1,184,255,255,1,255,255,255,1,0,0,0,3,128, + 128,128,1,255,255,255,1,128,128,128,1,184,255,255,1,138,191,191,1,0, + 0,0,3,138,191,191,1,184,255,255,1,0,0,0,1,175,243,243,1,8, + 11,11,1,184,255,255,5,0,0,0,1,184,255,255,1,255,255,255,1,208, + 208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,255,255,255,1,128, + 128,128,1,184,255,255,1,82,114,114,1,102,141,141,1,184,255,255,1,102, + 141,141,1,83,115,115,1,184,255,255,1,0,0,0,1,170,235,235,1,14, + 19,19,1,184,255,255,3,182,252,252,1,167,231,231,1,0,0,0,1,178, + 247,247,1,255,255,255,1,208,208,208,3,128,128,128,1,255,255,255,1,128, + 128,128,1,184,255,255,1,27,37,37,1,157,217,217,1,184,255,255,1,157, + 217,217,1,27,38,38,1,184,255,255,1,0,0,0,1,2,3,3,1,89, + 124,124,1,184,255,255,3,161,223,223,1,0,0,0,1,161,223,223,1,0, + 0,0,1,128,128,128,5,255,255,255,25,0,0,0,25,201,201,255,17,255, + 255,255,5,0,0,0,2,201,201,255,2,130,130,165,1,0,0,0,1,130, + 130,165,1,201,201,255,2,0,0,0,1,1,1,1,1,59,59,75,1,201, + 201,255,1,183,183,232,1,61,61,77,1,7,7,9,1,30,30,38,1,160, + 160,203,1,201,201,255,1,255,255,255,1,208,208,208,1,0,0,0,1,208, + 208,208,1,128,128,128,1,0,0,0,2,201,201,255,2,69,69,88,1,59, + 59,75,1,70,70,89,1,201,201,255,2,0,0,0,1,184,184,234,1,55, + 55,70,1,201,201,255,1,65,65,82,1,93,93,118,1,193,193,245,1,131, + 131,166,1,42,42,53,1,201,201,255,1,255,255,255,1,0,0,0,3,128, + 128,128,1,0,0,0,2,201,201,255,1,198,198,251,1,17,17,21,1,174, + 174,221,1,16,16,20,1,198,198,251,1,201,201,255,1,0,0,0,2,92, + 92,117,1,201,201,255,1,9,9,12,1,190,190,241,1,201,201,255,4,255, + 255,255,1,208,208,208,3,128,128,128,1,0,0,0,2,201,201,255,1,151, + 151,191,1,0,0,0,3,151,151,191,1,201,201,255,1,0,0,0,1,192, + 192,243,1,9,9,11,1,201,201,255,1,11,11,14,1,190,190,241,1,201, + 201,255,1,199,199,252,1,166,166,210,1,201,201,255,1,128,128,128,5,0, + 0,0,2,201,201,255,1,90,90,114,1,111,111,141,1,201,201,255,1,111, + 111,141,1,91,91,115,1,201,201,255,1,0,0,0,1,185,185,235,1,15, + 15,19,1,201,201,255,1,65,65,83,1,98,98,124,1,193,193,245,1,114, + 114,145,1,45,45,57,1,201,201,255,1,255,255,255,1,212,212,212,1,252, + 252,252,1,208,208,208,1,255,255,255,1,0,0,0,2,201,201,255,1,29, + 29,37,1,171,171,217,1,201,201,255,1,171,171,217,1,30,30,38,1,201, + 201,255,1,0,0,0,1,2,2,3,1,98,98,124,1,201,201,255,1,179, + 179,227,1,50,50,63,1,6,6,7,1,34,34,43,1,168,168,213,1,201, + 201,255,1,255,255,255,4,128,128,128,1,0,0,0,2,201,201,255,17,255, + 255,255,1,128,128,128,4,0,0,0,2,201,201,255,2,0,0,0,2,4, + 4,5,1,137,137,174,1,201,201,255,11,208,208,208,1,255,255,255,1,211, + 211,211,1,255,255,255,1,208,208,208,1,0,0,0,2,201,201,255,2,0, + 0,0,1,201,201,255,1,137,137,174,1,4,4,5,1,201,201,255,1,120, + 120,152,1,9,9,11,1,125,125,159,1,201,201,255,7,255,255,255,2,252, + 252,252,1,255,255,255,2,0,0,0,2,201,201,255,2,0,0,0,1,201, + 201,255,2,0,0,0,1,201,201,255,1,23,23,29,1,155,155,197,1,29, + 29,37,1,201,201,255,7,255,255,255,1,208,208,208,3,128,128,128,1,0, + 0,0,2,201,201,255,2,0,0,0,1,201,201,255,2,0,0,0,1,201, + 201,255,1,2,2,2,1,0,0,0,1,2,2,3,1,201,201,255,7,255, + 255,255,1,0,0,0,3,128,128,128,1,0,0,0,2,201,201,255,2,0, + 0,0,1,201,201,255,1,137,137,174,1,4,4,5,1,201,201,255,1,20, + 20,25,1,178,178,226,1,201,201,255,8,255,255,255,1,208,208,208,1,0, + 0,0,1,208,208,208,1,128,128,128,1,0,0,0,2,201,201,255,2,0, + 0,0,2,4,4,5,1,137,137,174,1,201,201,255,1,115,115,146,1,7, + 7,9,1,77,77,98,1,201,201,255,7,128,128,128,5,0,0,0,25,12, + 0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tdbbooleantextedit: record size: integer; data: array[0..1157] of byte end = + (size: 1158; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,18,116,100,98, + 98,111,111,108,101,97,110,116,101,120,116,101,100,105,116,23,98,105,116,109, + 97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4, + 6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11, + 10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111, + 114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10, + 8,4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0, + 196,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25, + 184,255,255,14,0,0,0,1,169,234,234,1,17,23,23,1,255,255,255,6, + 128,128,128,1,184,255,255,15,0,0,0,1,184,255,255,1,255,255,255,1, + 208,208,208,3,128,128,128,1,255,255,255,1,128,128,128,1,184,255,255,15, + 0,0,0,1,184,255,255,1,255,255,255,1,0,0,0,3,128,128,128,1, + 255,255,255,1,128,128,128,1,184,255,255,15,0,0,0,1,184,255,255,1, + 255,255,255,1,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1, + 255,255,255,1,128,128,128,1,184,255,255,13,182,252,252,1,167,231,231,1, + 0,0,0,1,178,247,247,1,255,255,255,1,208,208,208,3,128,128,128,1, + 255,255,255,1,128,128,128,1,184,255,255,13,161,223,223,1,0,0,0,1, + 161,223,223,1,0,0,0,1,128,128,128,5,255,255,255,25,0,0,0,25, + 255,255,255,22,0,0,0,7,255,255,255,13,208,208,208,1,0,0,0,1, + 208,208,208,1,128,128,128,1,0,0,0,2,255,255,255,2,0,0,0,1, + 255,255,255,3,0,0,0,1,71,71,71,1,255,255,255,1,0,0,0,2, + 255,255,255,1,152,152,152,1,11,11,11,1,159,159,159,1,255,255,255,3, + 0,0,0,3,128,128,128,1,0,0,0,2,255,255,255,2,0,0,0,1, + 255,255,255,3,0,0,0,1,213,213,213,1,255,255,255,1,0,0,0,2, + 255,255,255,1,29,29,29,1,197,197,197,1,37,37,37,1,255,255,255,3, + 208,208,208,3,128,128,128,1,0,0,0,2,255,255,255,2,0,0,0,1, + 255,255,255,3,0,0,0,1,254,254,254,1,255,255,255,1,0,0,0,2, + 255,255,255,1,2,2,2,1,0,0,0,1,3,3,3,1,255,255,255,2, + 128,128,128,5,0,0,0,2,255,255,255,2,0,0,0,1,255,255,255,3, + 0,0,0,1,255,255,255,2,5,5,5,1,0,0,0,1,255,255,255,1, + 25,25,25,1,226,226,226,1,255,255,255,4,212,212,212,1,252,252,252,1, + 208,208,208,1,255,255,255,1,0,0,0,2,255,255,255,2,0,0,0,1, + 255,255,255,3,0,0,0,1,255,255,255,2,215,215,215,1,5,5,5,1, + 255,255,255,1,146,146,146,1,9,9,9,1,98,98,98,1,255,255,255,6, + 128,128,128,1,0,0,0,2,255,255,255,18,128,128,128,4,0,0,0,2, + 255,255,255,1,0,0,0,3,255,255,255,6,0,0,0,1,255,255,255,6, + 208,208,208,1,255,255,255,1,211,211,211,1,255,255,255,1,208,208,208,1, + 0,0,0,2,255,255,255,1,0,0,0,1,255,255,255,3,108,108,108,1, + 14,14,14,1,7,7,7,1,88,88,88,1,255,255,255,1,0,0,0,1, + 174,174,174,1,5,5,5,1,80,80,80,1,255,255,255,1,152,152,152,1, + 11,11,11,1,159,159,159,1,255,255,255,1,252,252,252,1,255,255,255,2, + 0,0,0,2,255,255,255,1,0,0,0,3,255,255,255,3,220,220,220,1, + 1,1,1,1,255,255,255,1,0,0,0,1,39,39,39,1,55,55,55,1, + 255,255,255,2,29,29,29,1,197,197,197,1,37,37,37,1,208,208,208,3, + 128,128,128,1,0,0,0,2,255,255,255,1,0,0,0,1,255,255,255,3, + 177,177,177,1,76,76,76,1,31,31,31,1,0,0,0,1,255,255,255,1, + 0,0,0,1,218,218,218,1,30,30,30,1,195,195,195,1,255,255,255,1, + 2,2,2,1,0,0,0,1,3,3,3,1,0,0,0,3,128,128,128,1, + 0,0,0,2,255,255,255,1,0,0,0,1,255,255,255,3,13,13,13,1, + 175,175,175,1,158,158,158,1,0,0,0,1,255,255,255,1,0,0,0,1, + 25,25,25,1,51,51,51,1,19,19,19,1,255,255,255,1,25,25,25,1, + 226,226,226,1,255,255,255,1,208,208,208,1,0,0,0,1,208,208,208,1, + 128,128,128,1,0,0,0,2,255,255,255,1,0,0,0,1,255,255,255,3, + 94,94,94,1,8,8,8,1,112,112,112,1,0,0,0,1,255,255,255,1, + 0,0,0,1,140,140,140,1,10,10,10,1,174,174,174,1,255,255,255,1, + 146,146,146,1,9,9,9,1,49,49,49,1,128,128,128,4,0,0,0,25, + 12,0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tdbmemoedit: record size: integer; data: array[0..1354] of byte end = + (size: 1355; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,100,98, + 109,101,109,111,101,100,105,116,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,212,4,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,136,4,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,128,128,128,25,0,0,0,22,255,255,255, + 1,128,128,128,1,0,0,0,1,184,255,255,20,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,184,255,255,20,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,184,255,255,2,8,11,11,1,66,91,91, + 1,184,255,255,3,90,125,125,1,8,11,11,1,184,255,255,11,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,2,16,22,22, + 1,31,43,43,1,178,246,246,1,184,255,255,2,42,58,58,1,15,21,21, + 1,184,255,255,11,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,2,17,23,23,1,86,119,119,1,123,170,170,1,184,255,255, + 1,141,196,196,1,82,113,113,1,17,23,23,1,184,255,255,1,157,217,217, + 1,46,64,64,1,42,58,58,1,40,56,56,1,147,204,204,1,184,255,255, + 5,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 2,17,23,23,1,151,209,209,1,59,82,82,1,184,255,255,1,75,104,104, + 1,148,205,205,1,17,23,23,1,184,255,255,1,44,61,61,1,141,195,195, + 1,184,255,255,1,153,212,212,1,30,42,42,1,184,255,255,5,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,2,17,23,23, + 1,184,255,255,1,38,52,52,1,170,235,235,1,43,60,60,1,184,255,255, + 1,17,23,23,1,184,255,255,1,13,18,18,1,45,63,63,3,24,33,33, + 1,180,249,249,1,184,255,255,4,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,184,255,255,2,17,23,23,1,184,255,255,1,97,135,135, + 1,61,85,85,1,96,133,133,1,184,255,255,1,17,23,23,1,184,255,255, + 1,41,57,57,1,154,214,214,1,184,255,255,1,167,231,231,1,95,132,132, + 1,184,255,255,5,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,2,17,23,23,1,184,255,255,1,162,225,225,1,1,2,2, + 1,162,224,224,1,184,255,255,1,17,23,23,1,184,255,255,1,153,212,212, + 1,46,64,64,1,44,61,61,1,38,53,53,1,128,177,177,1,184,255,255, + 5,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 20,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 20,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 2,8,11,11,1,66,91,91,1,184,255,255,3,90,125,125,1,8,11,11, + 1,184,255,255,7,0,0,0,1,184,255,255,1,0,0,0,1,184,255,255, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 2,16,22,22,1,31,43,43,1,178,246,246,1,184,255,255,2,42,58,58, + 1,15,21,21,1,184,255,255,8,0,0,0,1,184,255,255,2,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,2,17,23,23, + 1,86,119,119,1,123,170,170,1,184,255,255,1,141,196,196,1,82,113,113, + 1,17,23,23,1,184,255,255,1,152,210,210,1,42,58,58,1,41,57,57, + 1,42,58,58,1,152,210,210,1,184,255,255,2,0,0,0,1,184,255,255, + 2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 2,17,23,23,1,151,209,209,1,59,82,82,1,184,255,255,1,75,104,104, + 1,148,205,205,1,17,23,23,1,184,255,255,1,40,56,56,1,141,196,196, + 1,184,255,255,1,140,194,194,1,40,55,55,1,184,255,255,2,0,0,0, + 1,184,255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,2,17,23,23,1,184,255,255,1,38,52,52,1,170,235,235, + 1,43,60,60,1,184,255,255,1,17,23,23,1,184,255,255,1,14,20,20, + 1,184,255,255,2,183,254,254,1,15,21,21,1,184,255,255,2,0,0,0, + 1,184,255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,2,17,23,23,1,184,255,255,1,97,135,135,1,61,85,85, + 1,96,133,133,1,184,255,255,1,17,23,23,1,184,255,255,1,40,55,55, + 1,142,197,197,1,184,255,255,1,141,195,195,1,40,55,55,1,184,255,255, + 2,0,0,0,1,184,255,255,2,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,184,255,255,2,17,23,23,1,184,255,255,1,162,225,225, + 1,1,2,2,1,162,224,224,1,184,255,255,1,17,23,23,1,184,255,255, + 1,150,208,208,1,41,57,57,1,42,58,58,1,43,59,59,1,151,209,209, + 1,184,255,255,2,0,0,0,1,184,255,255,2,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,184,255,255,16,0,0,0,1,184,255,255, + 1,0,0,0,1,184,255,255,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,184,255,255,20,224,224,224,1,255,255,255,1,128,128,128, + 1,224,224,224,22,255,255,255,25,20,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,42,128,128,128,1,255,255,255,23,0,0) + ); + +const + objdata_tdbintegeredit: record size: integer; data: array[0..829] of byte end = + (size: 830; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,100,98, + 105,110,116,101,103,101,114,101,100,105,116,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,196,2,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,124,2,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,120,128,128,128,25, + 0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,20, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,2, + 180,249,249,1,20,28,28,1,184,255,255,2,128,177,177,1,40,56,56,1, + 32,45,45,1,124,172,172,1,184,255,255,1,135,187,187,1,39,54,54,1, + 33,46,46,1,112,155,155,1,184,255,255,2,0,0,0,1,184,255,255,1, + 0,0,0,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 184,255,255,1,144,200,200,1,28,39,39,1,0,0,0,1,184,255,255,2, + 45,62,62,1,180,249,249,1,159,221,221,1,17,24,24,1,184,255,255,1, + 54,75,75,1,175,242,242,1,167,231,231,1,9,13,13,1,184,255,255,3, + 0,0,0,1,184,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,184,255,255,1,182,252,252,1,178,247,247,1,0,0,0,1, + 184,255,255,2,118,163,163,1,184,255,255,1,169,234,234,1,9,12,12,1, + 184,255,255,1,149,207,207,1,183,254,254,1,142,197,197,1,27,37,37,1, + 184,255,255,3,0,0,0,1,184,255,255,1,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,184,255,255,3,0,0,0,1,184,255,255,3, + 167,232,232,1,47,65,65,1,91,126,126,1,184,255,255,2,103,143,143,1, + 0,0,0,1,108,150,150,1,184,255,255,3,0,0,0,1,184,255,255,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3, + 0,0,0,1,184,255,255,2,149,206,206,1,32,44,44,1,119,165,165,1, + 183,254,254,1,184,255,255,1,173,240,240,1,183,254,254,1,144,199,199,1, + 12,16,16,1,184,255,255,3,0,0,0,1,184,255,255,1,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,0,0,0,1, + 184,255,255,2,51,70,70,1,163,226,226,1,184,255,255,3,45,63,63,1, + 181,251,251,1,165,228,228,1,14,19,19,1,184,255,255,3,0,0,0,1, + 184,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 184,255,255,3,0,0,0,1,184,255,255,1,172,238,238,1,11,15,15,1, + 37,51,51,3,184,255,255,1,115,159,159,1,39,54,54,1,32,45,45,1, + 118,164,164,1,184,255,255,3,0,0,0,1,184,255,255,1,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,17,0,0,0,1, + 184,255,255,1,0,0,0,1,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,184,255,255,20,224,224,224,1,255,255,255,1,128,128,128,1, + 224,224,224,22,255,255,255,145,16,0,0,0,0,0,0,120,255,255,255,255, + 255,255,255,81,0,0,0,120,0,0) + ); + +const + objdata_tdbbooleanedit: record size: integer; data: array[0..490] of byte end = + (size: 491; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,100,98, + 98,111,111,108,101,97,110,101,100,105,116,12,98,105,116,109,97,112,46,105, + 109,97,103,101,10,184,1,0,0,0,0,0,0,0,0,0,0,24,0,0, + 0,24,0,0,0,132,1,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,255,0,255,125,128,128,128,14,255,0,255,10,128,128,128,1,0,0,0, + 12,255,255,255,1,255,0,255,10,128,128,128,1,0,0,0,1,190,255,255, + 10,192,192,192,1,255,255,255,1,255,0,255,10,128,128,128,1,0,0,0, + 1,190,255,255,1,0,0,0,2,190,255,255,4,0,0,0,2,190,255,255, + 1,192,192,192,1,255,255,255,1,255,0,255,10,128,128,128,1,0,0,0, + 1,190,255,255,1,0,0,0,3,190,255,255,2,0,0,0,3,190,255,255, + 1,192,192,192,1,255,255,255,1,255,0,255,10,128,128,128,1,0,0,0, + 1,190,255,255,2,0,0,0,6,190,255,255,2,192,192,192,1,255,255,255, + 1,255,0,255,10,128,128,128,1,0,0,0,1,190,255,255,3,0,0,0, + 4,190,255,255,3,192,192,192,1,255,255,255,1,255,0,255,10,128,128,128, + 1,0,0,0,1,190,255,255,3,0,0,0,4,190,255,255,3,192,192,192, + 1,255,255,255,1,255,0,255,10,128,128,128,1,0,0,0,1,190,255,255, + 2,0,0,0,6,190,255,255,2,192,192,192,1,255,255,255,1,255,0,255, + 10,128,128,128,1,0,0,0,1,190,255,255,1,0,0,0,3,190,255,255, + 2,0,0,0,3,190,255,255,1,192,192,192,1,255,255,255,1,255,0,255, + 10,128,128,128,1,0,0,0,1,190,255,255,1,0,0,0,2,190,255,255, + 4,0,0,0,2,190,255,255,1,192,192,192,1,255,255,255,1,255,0,255, + 10,128,128,128,1,0,0,0,1,190,255,255,10,192,192,192,1,255,255,255, + 1,255,0,255,10,128,128,128,1,192,192,192,12,255,255,255,1,255,0,255, + 10,255,255,255,14,255,0,255,125,0,0) + ); + +const + objdata_tdbdataicon: record size: integer; data: array[0..1322] of byte end = + (size: 1323; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,100,98, + 100,97,116,97,105,99,111,110,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,180,4,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,88,3,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,171,171,171,1,128,128,128,1,171,171,171, + 20,128,128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128,128,128, + 1,171,171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171, + 2,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128,128,128, + 1,171,171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171,171,171, + 20,128,128,128,1,171,171,171,1,128,128,128,24,171,171,171,1,128,128,128, + 1,184,255,255,20,128,128,128,1,171,171,171,2,128,128,128,1,184,255,255, + 5,200,244,240,1,223,228,218,1,233,213,198,1,236,201,182,1,240,186,164, + 1,236,180,153,1,227,181,155,1,219,183,159,1,208,197,178,1,193,230,222, + 1,184,255,254,1,184,255,255,4,128,128,128,1,171,171,171,2,128,128,128, + 1,184,255,255,3,202,243,239,1,245,214,198,1,250,200,179,1,246,192,169, + 1,243,184,159,1,239,176,149,1,235,168,139,1,231,160,129,1,227,152,119, + 1,223,144,109,1,219,136,98,1,215,128,88,1,209,137,101,1,190,219,208, + 1,184,255,255,3,128,128,128,1,171,171,171,2,128,128,128,1,184,255,255, + 2,210,238,231,1,249,200,181,1,247,192,170,1,243,184,160,1,239,177,150, + 1,235,168,140,1,231,161,129,1,227,153,119,1,223,145,109,1,220,137,99, + 1,216,129,89,1,212,121,79,1,208,113,69,1,204,105,58,1,199,98,50, + 1,188,194,176,1,184,255,255,2,128,128,128,1,171,171,171,2,128,128,128, + 1,184,255,255,2,236,203,185,1,243,185,160,1,239,177,150,1,235,169,140, + 1,231,161,130,1,228,153,120,1,224,145,110,1,220,137,100,1,216,129,89, + 1,212,121,79,1,208,113,69,1,204,105,59,1,200,97,49,1,197,89,39, + 1,193,82,29,1,188,104,59,1,184,255,255,2,128,128,128,1,171,171,171, + 2,128,128,128,1,184,255,255,2,226,196,176,1,236,169,141,1,232,162,131, + 1,228,154,120,1,224,146,110,1,220,138,100,1,216,130,90,1,212,122,80, + 1,208,114,70,1,205,106,60,1,201,98,50,1,197,90,39,1,193,82,29, + 1,189,74,19,1,185,66,9,1,183,107,62,1,184,255,255,2,128,128,128, + 1,171,171,171,2,128,128,128,1,184,255,255,2,196,231,223,1,225,160,128, + 1,224,146,111,1,220,138,101,1,216,130,91,1,213,122,81,1,209,114,70, + 1,205,106,60,1,201,98,50,1,197,90,40,1,193,82,30,1,189,74,20, + 1,185,67,10,1,182,59,0,1,182,70,14,1,183,205,190,1,184,255,255, + 2,128,128,128,1,171,171,171,2,128,128,128,1,184,255,255,3,188,240,235, + 1,208,166,138,1,213,125,84,1,209,115,71,1,205,107,61,1,201,99,51, + 1,197,91,41,1,193,83,31,1,189,75,20,1,186,67,10,1,182,59,0, + 1,182,62,4,1,183,115,73,1,184,230,222,1,184,255,255,3,128,128,128, + 1,171,171,171,2,128,128,128,1,184,255,255,5,185,244,241,1,191,196,179, + 1,191,162,134,1,191,141,107,1,188,118,76,1,185,111,68,1,183,126,87, + 1,183,144,111,1,184,181,159,1,184,240,236,1,184,255,255,5,128,128,128, + 1,171,171,171,2,128,128,128,1,184,255,255,20,128,128,128,1,171,171,171, + 1,128,128,128,24,171,171,171,1,128,128,128,1,171,171,171,20,128,128,128, + 1,171,171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171, + 2,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128,128,128, + 1,171,171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171,171,171, + 20,128,128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128,128,128, + 1,171,171,171,1,36,1,0,0,0,0,0,1,255,255,255,1,0,0,0, + 20,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255,255,255, + 1,0,0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0, + 2,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255,255,255, + 1,0,0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0, + 20,255,255,255,1,0,0,0,1,255,255,255,24,0,0,0,1,255,255,255, + 22,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0, + 2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255, + 22,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0, + 2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,1,255,255,255, + 24,0,0,0,1,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0, + 2,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255,255,255, + 1,0,0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0, + 20,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255,255,255, + 1,0,0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0, + 1,0,0) + ); + +const + objdata_tdbbooleaneditradio: record size: integer; data: array[0..447] of byte end = + (size: 448; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,100,98, + 98,111,111,108,101,97,110,101,100,105,116,114,97,100,105,111,12,98,105,116, + 109,97,112,46,105,109,97,103,101,10,136,1,0,0,0,0,0,0,0,0, + 0,0,24,0,0,0,24,0,0,0,84,1,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,255,0,255,125,128,128,128,14,255,0,255,10,128,128, + 128,1,0,0,0,12,255,255,255,1,255,0,255,10,128,128,128,1,0,0, + 0,1,190,255,255,10,192,192,192,1,255,255,255,1,255,0,255,10,128,128, + 128,1,0,0,0,1,190,255,255,10,192,192,192,1,255,255,255,1,255,0, + 255,10,128,128,128,1,0,0,0,1,190,255,255,4,0,0,0,2,190,255, + 255,4,192,192,192,1,255,255,255,1,255,0,255,10,128,128,128,1,0,0, + 0,1,190,255,255,3,0,0,0,4,190,255,255,3,192,192,192,1,255,255, + 255,1,255,0,255,10,128,128,128,1,0,0,0,1,190,255,255,2,0,0, + 0,6,190,255,255,2,192,192,192,1,255,255,255,1,255,0,255,10,128,128, + 128,1,0,0,0,1,190,255,255,2,0,0,0,6,190,255,255,2,192,192, + 192,1,255,255,255,1,255,0,255,10,128,128,128,1,0,0,0,1,190,255, + 255,3,0,0,0,4,190,255,255,3,192,192,192,1,255,255,255,1,255,0, + 255,10,128,128,128,1,0,0,0,1,190,255,255,4,0,0,0,2,190,255, + 255,4,192,192,192,1,255,255,255,1,255,0,255,10,128,128,128,1,0,0, + 0,1,190,255,255,10,192,192,192,1,255,255,255,1,255,0,255,10,128,128, + 128,1,0,0,0,1,190,255,255,10,192,192,192,1,255,255,255,1,255,0, + 255,10,128,128,128,1,192,192,192,12,255,255,255,1,255,0,255,10,255,255, + 255,14,255,0,255,125,0,0) + ); + +const + objdata_tdbrealedit: record size: integer; data: array[0..706] of byte end = + (size: 707; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,100,98, + 114,101,97,108,101,100,105,116,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,76,2,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,4,2,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,255,255,255,120,128,128,128,25,0,0,0, + 22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,20,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,2,180,249,249, + 1,20,28,28,1,184,255,255,6,128,177,177,1,40,56,56,1,32,45,45, + 1,124,172,172,1,184,255,255,3,0,0,0,1,184,255,255,1,0,0,0, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 1,144,200,200,1,28,39,39,1,0,0,0,1,184,255,255,6,45,62,62, + 1,180,249,249,1,159,221,221,1,17,24,24,1,184,255,255,4,0,0,0, + 1,184,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,1,182,252,252,1,178,247,247,1,0,0,0,1,184,255,255, + 6,118,163,163,1,184,255,255,1,169,234,234,1,9,12,12,1,184,255,255, + 4,0,0,0,1,184,255,255,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,184,255,255,3,0,0,0,1,184,255,255,7,167,232,232, + 1,47,65,65,1,91,126,126,1,184,255,255,4,0,0,0,1,184,255,255, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 3,0,0,0,1,184,255,255,6,149,206,206,1,32,44,44,1,119,165,165, + 1,183,254,254,1,184,255,255,4,0,0,0,1,184,255,255,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,0,0,0, + 1,184,255,255,3,181,251,251,1,184,255,255,2,51,70,70,1,163,226,226, + 1,184,255,255,6,0,0,0,1,184,255,255,1,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,184,255,255,3,0,0,0,1,184,255,255, + 3,0,0,0,1,184,255,255,1,172,238,238,1,11,15,15,1,37,51,51, + 3,184,255,255,4,0,0,0,1,184,255,255,1,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,184,255,255,17,0,0,0,1,184,255,255, + 1,0,0,0,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,20,224,224,224,1,255,255,255,1,128,128,128,1,224,224,224, + 22,255,255,255,145,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255, + 81,0,0,0,120,0,0) + ); + +const + objdata_tdbrealspinedit: record size: integer; data: array[0..710] of byte end = + (size: 711; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,100,98, + 114,101,97,108,115,112,105,110,101,100,105,116,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,76,2,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,4,2,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,120,128,128,128, + 25,0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 15,208,208,208,5,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,2,180,249,249,1,20,28,28,1,184,255,255,6,128,177,177, + 1,40,56,56,1,32,45,45,1,124,172,172,1,184,255,255,1,208,208,208, + 2,0,0,0,1,208,208,208,2,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,184,255,255,1,144,200,200,1,28,39,39,1,0,0,0, + 1,184,255,255,6,45,62,62,1,180,249,249,1,159,221,221,1,17,24,24, + 1,184,255,255,1,208,208,208,1,0,0,0,3,208,208,208,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,182,252,252, + 1,178,247,247,1,0,0,0,1,184,255,255,6,118,163,163,1,184,255,255, + 1,169,234,234,1,9,12,12,1,184,255,255,1,0,0,0,5,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,0,0,0, + 1,184,255,255,7,167,232,232,1,47,65,65,1,91,126,126,1,184,255,255, + 1,208,208,208,5,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,3,0,0,0,1,184,255,255,6,149,206,206,1,32,44,44, + 1,119,165,165,1,183,254,254,1,184,255,255,1,208,208,208,5,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,0,0,0, + 1,184,255,255,3,181,251,251,1,184,255,255,2,51,70,70,1,163,226,226, + 1,184,255,255,3,0,0,0,5,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,184,255,255,3,0,0,0,1,184,255,255,3,0,0,0, + 1,184,255,255,1,172,238,238,1,11,15,15,1,37,51,51,3,184,255,255, + 1,208,208,208,1,0,0,0,3,208,208,208,1,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,184,255,255,15,208,208,208,2,0,0,0, + 1,208,208,208,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,15,208,208,208,5,224,224,224,1,255,255,255,1,128,128,128, + 1,224,224,224,22,255,255,255,145,16,0,0,0,0,0,0,120,255,255,255, + 255,255,255,255,81,0,0,0,120,0,0) + ); + +const + objdata_tdbdatetimeedit: record size: integer; data: array[0..686] of byte end = + (size: 687; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,100,98, + 100,97,116,101,116,105,109,101,101,100,105,116,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,52,2,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,236,1,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,120,128,128,128, + 25,0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 20,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 1,0,0,0,3,4,5,5,1,126,174,174,1,184,255,255,4,0,0,0, + 5,184,255,255,2,0,0,0,1,184,255,255,1,0,0,0,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,0,0,0, + 1,184,255,255,2,126,174,174,1,4,5,5,1,184,255,255,6,0,0,0, + 1,184,255,255,5,0,0,0,1,184,255,255,1,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,184,255,255,1,0,0,0,1,184,255,255, + 3,0,0,0,1,184,255,255,2,0,0,0,1,184,255,255,3,0,0,0, + 1,184,255,255,5,0,0,0,1,184,255,255,1,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,184,255,255,1,0,0,0,1,184,255,255, + 3,0,0,0,1,184,255,255,6,0,0,0,1,184,255,255,5,0,0,0, + 1,184,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,1,0,0,0,1,184,255,255,3,0,0,0,1,184,255,255, + 6,0,0,0,1,184,255,255,5,0,0,0,1,184,255,255,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,0,0,0, + 1,184,255,255,2,126,174,174,1,4,5,5,1,184,255,255,6,0,0,0, + 1,184,255,255,5,0,0,0,1,184,255,255,1,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,184,255,255,1,0,0,0,3,4,5,5, + 1,126,174,174,1,184,255,255,2,0,0,0,1,184,255,255,3,0,0,0, + 1,184,255,255,5,0,0,0,1,184,255,255,1,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,184,255,255,17,0,0,0,1,184,255,255, + 1,0,0,0,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,20,224,224,224,1,255,255,255,1,128,128,128,1,224,224,224, + 22,255,255,255,145,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255, + 81,0,0,0,120,0,0) + ); + +const + objdata_tdbenumedit: record size: integer; data: array[0..1394] of byte end = + (size: 1395; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,100,98, + 101,110,117,109,101,100,105,116,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,252,4,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,184,4,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,128,128,128,25,184,255,255,1,172,238,238, + 1,21,29,29,1,184,255,255,1,124,172,172,1,15,21,21,1,13,18,18, + 1,107,148,148,1,83,115,115,1,11,15,15,2,92,128,128,1,184,255,255, + 2,0,0,0,1,169,234,234,1,17,23,23,1,255,255,255,6,128,128,128, + 1,184,255,255,1,71,98,98,1,0,0,0,1,184,255,255,1,21,29,29, + 1,145,201,201,1,151,209,209,1,7,10,10,1,184,255,255,2,140,194,194, + 1,12,17,17,1,184,255,255,3,0,0,0,1,184,255,255,1,255,255,255, + 1,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128,1,184,255,255, + 1,178,247,247,1,0,0,0,1,184,255,255,3,148,205,205,1,49,68,68, + 1,184,255,255,1,118,164,164,1,3,4,4,1,74,103,103,1,184,255,255, + 3,0,0,0,1,184,255,255,1,255,255,255,1,0,0,0,3,128,128,128, + 1,255,255,255,1,128,128,128,1,184,255,255,2,0,0,0,1,184,255,255, + 2,162,224,224,1,51,70,70,1,167,232,232,1,184,255,255,2,154,214,214, + 1,7,10,10,1,184,255,255,3,0,0,0,1,184,255,255,1,255,255,255, + 1,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,255,255,255, + 1,128,128,128,1,184,255,255,2,0,0,0,1,184,255,255,1,119,165,165, + 1,56,77,77,1,170,235,235,1,184,255,255,1,23,32,32,1,164,227,227, + 1,169,234,234,1,17,24,24,1,184,255,255,1,182,252,252,1,167,231,231, + 1,0,0,0,1,178,247,247,1,255,255,255,1,208,208,208,3,128,128,128, + 1,255,255,255,1,128,128,128,1,184,255,255,2,0,0,0,1,184,255,255, + 1,14,19,19,1,0,0,0,3,128,177,177,1,14,19,19,1,17,24,24, + 1,129,179,179,1,184,255,255,1,161,223,223,1,0,0,0,1,161,223,223, + 1,0,0,0,1,128,128,128,5,255,255,255,25,0,0,0,25,255,255,255, + 22,0,0,0,2,255,255,255,2,165,165,165,1,0,0,0,1,165,165,165, + 1,255,255,255,2,0,0,0,1,1,1,1,1,75,75,75,1,255,255,255, + 1,232,232,232,1,77,77,77,1,9,9,9,1,38,38,38,1,203,203,203, + 1,255,255,255,2,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128, + 1,0,0,0,2,255,255,255,2,88,88,88,1,75,75,75,1,89,89,89, + 1,255,255,255,2,0,0,0,1,234,234,234,1,70,70,70,1,255,255,255, + 1,82,82,82,1,118,118,118,1,245,245,245,1,166,166,166,1,53,53,53, + 1,255,255,255,2,0,0,0,3,128,128,128,1,0,0,0,2,255,255,255, + 1,251,251,251,1,21,21,21,1,221,221,221,1,20,20,20,1,251,251,251, + 1,255,255,255,1,0,0,0,2,117,117,117,1,255,255,255,1,12,12,12, + 1,241,241,241,1,255,255,255,5,208,208,208,3,128,128,128,1,0,0,0, + 2,255,255,255,1,191,191,191,1,0,0,0,3,191,191,191,1,255,255,255, + 1,0,0,0,1,243,243,243,1,11,11,11,1,255,255,255,1,14,14,14, + 1,241,241,241,1,255,255,255,1,252,252,252,1,210,210,210,1,255,255,255, + 1,128,128,128,5,0,0,0,2,255,255,255,1,114,114,114,1,141,141,141, + 1,255,255,255,1,141,141,141,1,115,115,115,1,255,255,255,1,0,0,0, + 1,235,235,235,1,19,19,19,1,255,255,255,1,83,83,83,1,124,124,124, + 1,245,245,245,1,145,145,145,1,57,57,57,1,255,255,255,2,212,212,212, + 1,252,252,252,1,208,208,208,1,255,255,255,1,0,0,0,2,255,255,255, + 1,37,37,37,1,217,217,217,1,255,255,255,1,217,217,217,1,38,38,38, + 1,255,255,255,1,0,0,0,1,3,3,3,1,124,124,124,1,255,255,255, + 1,227,227,227,1,63,63,63,1,7,7,7,1,43,43,43,1,213,213,213, + 1,255,255,255,5,128,128,128,1,0,0,0,2,255,255,255,18,128,128,128, + 4,0,0,0,2,255,255,255,2,0,0,0,2,5,5,5,1,174,174,174, + 1,255,255,255,11,208,208,208,1,255,255,255,1,211,211,211,1,255,255,255, + 1,208,208,208,1,0,0,0,2,255,255,255,2,0,0,0,1,255,255,255, + 1,174,174,174,1,5,5,5,1,255,255,255,1,152,152,152,1,11,11,11, + 1,159,159,159,1,255,255,255,9,252,252,252,1,255,255,255,2,0,0,0, + 2,255,255,255,2,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255, + 1,29,29,29,1,197,197,197,1,37,37,37,1,255,255,255,8,208,208,208, + 3,128,128,128,1,0,0,0,2,255,255,255,2,0,0,0,1,255,255,255, + 2,0,0,0,1,255,255,255,1,2,2,2,1,0,0,0,1,3,3,3, + 1,255,255,255,8,0,0,0,3,128,128,128,1,0,0,0,2,255,255,255, + 2,0,0,0,1,255,255,255,1,174,174,174,1,5,5,5,1,255,255,255, + 1,25,25,25,1,226,226,226,1,255,255,255,9,208,208,208,1,0,0,0, + 1,208,208,208,1,128,128,128,1,0,0,0,2,255,255,255,2,0,0,0, + 2,5,5,5,1,174,174,174,1,255,255,255,1,146,146,146,1,9,9,9, + 1,98,98,98,1,255,255,255,7,128,128,128,5,0,0,0,25,12,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tdbenumeditdb: record size: integer; data: array[0..1436] of byte end = + (size: 1437; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,100,98, + 101,110,117,109,101,100,105,116,100,98,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,36,5,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,224,4,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,184,255,255,1,172, + 238,238,1,21,29,29,1,184,255,255,1,124,172,172,1,15,21,21,1,13, + 18,18,1,107,148,148,1,83,115,115,1,11,15,15,2,92,128,128,1,184, + 255,255,2,0,0,0,1,169,234,234,1,17,23,23,1,255,255,255,6,128, + 128,128,1,184,255,255,1,71,98,98,1,0,0,0,1,184,255,255,1,21, + 29,29,1,145,201,201,1,151,209,209,1,7,10,10,1,184,255,255,2,140, + 194,194,1,12,17,17,1,184,255,255,3,0,0,0,1,184,255,255,1,255, + 255,255,1,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128,1,184, + 255,255,1,178,247,247,1,0,0,0,1,184,255,255,3,148,205,205,1,49, + 68,68,1,184,255,255,1,118,164,164,1,3,4,4,1,74,103,103,1,184, + 255,255,3,0,0,0,1,184,255,255,1,255,255,255,1,0,0,0,3,128, + 128,128,1,255,255,255,1,128,128,128,1,184,255,255,2,0,0,0,1,184, + 255,255,2,162,224,224,1,51,70,70,1,167,232,232,1,184,255,255,2,154, + 214,214,1,7,10,10,1,184,255,255,3,0,0,0,1,184,255,255,1,255, + 255,255,1,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,255, + 255,255,1,128,128,128,1,184,255,255,2,0,0,0,1,184,255,255,1,119, + 165,165,1,56,77,77,1,170,235,235,1,184,255,255,1,23,32,32,1,164, + 227,227,1,169,234,234,1,17,24,24,1,184,255,255,1,182,252,252,1,167, + 231,231,1,0,0,0,1,178,247,247,1,255,255,255,1,208,208,208,3,128, + 128,128,1,255,255,255,1,128,128,128,1,184,255,255,2,0,0,0,1,184, + 255,255,1,14,19,19,1,0,0,0,3,128,177,177,1,14,19,19,1,17, + 24,24,1,129,179,179,1,184,255,255,1,161,223,223,1,0,0,0,1,161, + 223,223,1,0,0,0,1,128,128,128,5,255,255,255,25,0,0,0,25,184, + 255,255,17,255,255,255,5,0,0,0,2,184,255,255,2,119,165,165,1,0, + 0,0,1,119,165,165,1,184,255,255,2,0,0,0,1,1,1,1,1,54, + 75,75,1,184,255,255,1,167,232,232,1,56,77,77,1,6,9,9,1,27, + 38,38,1,146,203,203,1,184,255,255,1,255,255,255,1,208,208,208,1,0, + 0,0,1,208,208,208,1,128,128,128,1,0,0,0,2,184,255,255,2,63, + 88,88,1,54,75,75,1,64,89,89,1,184,255,255,2,0,0,0,1,169, + 234,234,1,51,70,70,1,184,255,255,1,59,82,82,1,85,118,118,1,177, + 245,245,1,120,166,166,1,38,53,53,1,184,255,255,1,255,255,255,1,0, + 0,0,3,128,128,128,1,0,0,0,2,184,255,255,1,181,251,251,1,15, + 21,21,1,159,221,221,1,14,20,20,1,181,251,251,1,184,255,255,1,0, + 0,0,2,84,117,117,1,184,255,255,1,9,12,12,1,174,241,241,1,184, + 255,255,4,255,255,255,1,208,208,208,3,128,128,128,1,0,0,0,2,184, + 255,255,1,138,191,191,1,0,0,0,3,138,191,191,1,184,255,255,1,0, + 0,0,1,175,243,243,1,8,11,11,1,184,255,255,1,10,14,14,1,174, + 241,241,1,184,255,255,1,182,252,252,1,152,210,210,1,184,255,255,1,128, + 128,128,5,0,0,0,2,184,255,255,1,82,114,114,1,102,141,141,1,184, + 255,255,1,102,141,141,1,83,115,115,1,184,255,255,1,0,0,0,1,170, + 235,235,1,14,19,19,1,184,255,255,1,60,83,83,1,89,124,124,1,177, + 245,245,1,105,145,145,1,41,57,57,1,184,255,255,2,206,212,212,1,185, + 252,252,1,208,208,208,1,184,255,255,1,0,0,0,2,184,255,255,1,27, + 37,37,1,157,217,217,1,184,255,255,1,157,217,217,1,27,38,38,1,184, + 255,255,1,0,0,0,1,2,3,3,1,89,124,124,1,184,255,255,1,164, + 227,227,1,45,63,63,1,5,7,7,1,31,43,43,1,154,213,213,1,184, + 255,255,1,255,255,255,4,128,128,128,1,0,0,0,2,184,255,255,17,255, + 255,255,1,128,128,128,4,0,0,0,2,184,255,255,2,0,0,0,2,4, + 5,5,1,126,174,174,1,184,255,255,11,208,208,208,1,184,255,255,1,207, + 211,211,1,184,255,255,1,208,208,208,1,0,0,0,2,184,255,255,2,0, + 0,0,1,184,255,255,1,126,174,174,1,4,5,5,1,184,255,255,1,110, + 152,152,1,8,11,11,1,115,159,159,1,184,255,255,7,255,255,255,2,252, + 252,252,1,255,255,255,2,0,0,0,2,184,255,255,2,0,0,0,1,184, + 255,255,2,0,0,0,1,184,255,255,1,21,29,29,1,142,197,197,1,27, + 37,37,1,184,255,255,7,255,255,255,1,208,208,208,3,128,128,128,1,0, + 0,0,2,184,255,255,2,0,0,0,1,184,255,255,2,0,0,0,1,184, + 255,255,1,1,2,2,1,0,0,0,1,2,3,3,1,184,255,255,7,255, + 255,255,1,0,0,0,3,128,128,128,1,0,0,0,2,184,255,255,2,0, + 0,0,1,184,255,255,1,126,174,174,1,4,5,5,1,184,255,255,1,18, + 25,25,1,163,226,226,1,184,255,255,8,255,255,255,1,208,208,208,1,0, + 0,0,1,208,208,208,1,128,128,128,1,0,0,0,2,184,255,255,2,0, + 0,0,2,4,5,5,1,126,174,174,1,184,255,255,1,105,146,146,1,6, + 9,9,1,71,98,98,1,184,255,255,7,128,128,128,5,0,0,0,25,12, + 0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tdbenum64editdb: record size: integer; data: array[0..1386] of byte end = + (size: 1387; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,100,98, + 101,110,117,109,54,52,101,100,105,116,100,98,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,240,4,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,172,4,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,184,255,255, + 1,172,238,238,1,21,29,29,1,184,255,255,1,124,172,172,1,15,21,21, + 1,13,18,18,1,107,148,148,1,83,115,115,1,11,15,15,2,92,128,128, + 1,184,255,255,2,0,0,0,1,169,234,234,1,17,23,23,1,255,255,255, + 6,128,128,128,1,184,255,255,1,71,98,98,1,0,0,0,1,184,255,255, + 1,21,29,29,1,145,201,201,1,151,209,209,1,7,10,10,1,184,255,255, + 2,140,194,194,1,12,17,17,1,184,255,255,3,0,0,0,1,184,255,255, + 1,255,255,255,1,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128, + 1,184,255,255,1,178,247,247,1,0,0,0,1,184,255,255,3,148,205,205, + 1,49,68,68,1,184,255,255,1,118,164,164,1,3,4,4,1,74,103,103, + 1,184,255,255,3,0,0,0,1,184,255,255,1,255,255,255,1,0,0,0, + 3,128,128,128,1,255,255,255,1,128,128,128,1,184,255,255,2,0,0,0, + 1,184,255,255,2,162,224,224,1,51,70,70,1,167,232,232,1,184,255,255, + 2,154,214,214,1,7,10,10,1,184,255,255,3,0,0,0,1,184,255,255, + 1,255,255,255,1,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128, + 1,255,255,255,1,128,128,128,1,184,255,255,2,0,0,0,1,184,255,255, + 1,119,165,165,1,56,77,77,1,170,235,235,1,184,255,255,1,23,32,32, + 1,164,227,227,1,169,234,234,1,17,24,24,1,184,255,255,1,182,252,252, + 1,167,231,231,1,0,0,0,1,178,247,247,1,255,255,255,1,208,208,208, + 3,128,128,128,1,255,255,255,1,128,128,128,1,184,255,255,2,0,0,0, + 1,184,255,255,1,14,19,19,1,0,0,0,3,128,177,177,1,14,19,19, + 1,17,24,24,1,129,179,179,1,184,255,255,1,161,223,223,1,0,0,0, + 1,161,223,223,1,0,0,0,1,128,128,128,5,255,255,255,25,0,0,0, + 25,184,255,255,17,255,255,255,5,0,0,0,2,184,255,255,17,255,255,255, + 1,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,0,0,0, + 2,184,255,255,2,183,253,253,1,96,133,133,1,17,24,24,1,4,5,5, + 1,53,73,73,1,166,230,230,1,184,255,255,5,131,182,182,1,1,2,2, + 1,184,255,255,2,255,255,255,1,0,0,0,3,128,128,128,1,0,0,0, + 2,184,255,255,2,102,142,142,1,22,30,30,1,126,174,174,1,139,193,193, + 1,47,65,65,1,56,77,77,1,184,255,255,4,155,215,215,1,10,14,14, + 1,0,0,0,1,184,255,255,2,255,255,255,1,208,208,208,3,128,128,128, + 1,0,0,0,2,184,255,255,1,183,254,254,1,22,30,30,1,130,180,180, + 1,184,255,255,2,168,233,233,1,127,176,176,1,184,255,255,3,172,238,238, + 1,26,36,36,1,82,114,114,1,0,0,0,1,184,255,255,2,128,128,128, + 5,0,0,0,2,184,255,255,1,169,234,234,1,0,0,0,1,108,149,149, + 1,19,27,27,1,6,8,8,1,61,84,84,1,171,237,237,1,184,255,255, + 2,181,251,251,1,50,69,69,1,79,109,109,1,155,215,215,1,0,0,0, + 1,184,255,255,2,255,255,255,1,212,212,212,1,252,252,252,1,208,208,208, + 1,255,255,255,1,0,0,0,2,184,255,255,1,156,216,216,1,0,0,0, + 1,35,49,49,1,136,188,188,1,141,195,195,1,40,55,55,1,58,81,81, + 1,184,255,255,2,80,111,111,1,48,67,67,1,180,250,250,1,155,215,215, + 1,0,0,0,1,184,255,255,2,255,255,255,4,128,128,128,1,0,0,0, + 2,184,255,255,1,159,221,221,1,0,0,0,1,152,210,210,1,184,255,255, + 2,153,212,212,1,1,1,1,1,173,240,240,1,115,160,160,1,25,35,35, + 1,171,237,237,1,184,255,255,1,155,215,215,1,0,0,0,1,184,255,255, + 2,255,255,255,1,128,128,128,4,0,0,0,2,184,255,255,1,175,242,242, + 1,0,0,0,1,180,249,249,1,184,255,255,2,180,249,249,1,0,0,0, + 1,159,220,220,1,66,91,91,1,0,0,0,6,77,107,107,1,208,208,208, + 1,255,255,255,1,211,211,211,1,255,255,255,1,208,208,208,1,0,0,0, + 2,184,255,255,2,29,40,40,1,141,195,195,1,184,255,255,2,144,200,200, + 1,5,7,7,1,178,246,246,1,165,229,229,1,155,215,215,3,131,181,181, + 1,0,0,0,1,155,215,215,1,167,231,231,1,255,255,255,2,252,252,252, + 1,255,255,255,2,0,0,0,2,184,255,255,2,104,144,144,1,25,35,35, + 1,130,180,180,1,131,182,182,1,29,40,40,1,76,106,106,1,184,255,255, + 5,155,215,215,1,0,0,0,1,184,255,255,2,255,255,255,1,208,208,208, + 3,128,128,128,1,0,0,0,2,184,255,255,2,182,252,252,1,81,112,112, + 1,9,12,12,1,11,15,15,1,76,106,106,1,178,247,247,1,184,255,255, + 5,155,215,215,1,0,0,0,1,184,255,255,2,255,255,255,1,0,0,0, + 3,128,128,128,1,0,0,0,2,184,255,255,17,255,255,255,1,208,208,208, + 1,0,0,0,1,208,208,208,1,128,128,128,1,0,0,0,2,184,255,255, + 17,128,128,128,5,0,0,0,25,12,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,66,0,0) + ); + +const + objdata_tdbenumeditlb: record size: integer; data: array[0..1440] of byte end = + (size: 1441; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,100,98, + 101,110,117,109,101,100,105,116,108,98,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,40,5,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,228,4,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,184,255,255,1,172, + 238,238,1,21,29,29,1,184,255,255,1,124,172,172,1,15,21,21,1,13, + 18,18,1,107,148,148,1,83,115,115,1,11,15,15,2,92,128,128,1,184, + 255,255,2,0,0,0,1,169,234,234,1,17,23,23,1,255,255,255,6,128, + 128,128,1,184,255,255,1,71,98,98,1,0,0,0,1,184,255,255,1,21, + 29,29,1,145,201,201,1,151,209,209,1,7,10,10,1,184,255,255,2,140, + 194,194,1,12,17,17,1,184,255,255,3,0,0,0,1,184,255,255,1,255, + 255,255,1,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128,1,184, + 255,255,1,178,247,247,1,0,0,0,1,184,255,255,3,148,205,205,1,49, + 68,68,1,184,255,255,1,118,164,164,1,3,4,4,1,74,103,103,1,184, + 255,255,3,0,0,0,1,184,255,255,1,255,255,255,1,0,0,0,3,128, + 128,128,1,255,255,255,1,128,128,128,1,184,255,255,2,0,0,0,1,184, + 255,255,2,162,224,224,1,51,70,70,1,167,232,232,1,184,255,255,2,154, + 214,214,1,7,10,10,1,184,255,255,3,0,0,0,1,184,255,255,1,255, + 255,255,1,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,255, + 255,255,1,128,128,128,1,184,255,255,2,0,0,0,1,184,255,255,1,119, + 165,165,1,56,77,77,1,170,235,235,1,184,255,255,1,23,32,32,1,164, + 227,227,1,169,234,234,1,17,24,24,1,184,255,255,1,182,252,252,1,167, + 231,231,1,0,0,0,1,178,247,247,1,255,255,255,1,208,208,208,3,128, + 128,128,1,255,255,255,1,128,128,128,1,184,255,255,2,0,0,0,1,184, + 255,255,1,14,19,19,1,0,0,0,3,128,177,177,1,14,19,19,1,17, + 24,24,1,129,179,179,1,184,255,255,1,161,223,223,1,0,0,0,1,161, + 223,223,1,0,0,0,1,128,128,128,5,255,255,255,25,0,0,0,25,201, + 201,255,17,255,255,255,5,0,0,0,2,201,201,255,2,130,130,165,1,0, + 0,0,1,130,130,165,1,201,201,255,2,0,0,0,1,1,1,1,1,59, + 59,75,1,201,201,255,1,183,183,232,1,61,61,77,1,7,7,9,1,30, + 30,38,1,160,160,203,1,201,201,255,1,255,255,255,1,208,208,208,1,0, + 0,0,1,208,208,208,1,128,128,128,1,0,0,0,2,201,201,255,2,69, + 69,88,1,59,59,75,1,70,70,89,1,201,201,255,2,0,0,0,1,184, + 184,234,1,55,55,70,1,201,201,255,1,65,65,82,1,93,93,118,1,193, + 193,245,1,131,131,166,1,42,42,53,1,201,201,255,1,255,255,255,1,0, + 0,0,3,128,128,128,1,0,0,0,2,201,201,255,1,198,198,251,1,17, + 17,21,1,174,174,221,1,16,16,20,1,198,198,251,1,201,201,255,1,0, + 0,0,2,92,92,117,1,201,201,255,1,9,9,12,1,190,190,241,1,201, + 201,255,4,255,255,255,1,208,208,208,3,128,128,128,1,0,0,0,2,201, + 201,255,1,151,151,191,1,0,0,0,3,151,151,191,1,201,201,255,1,0, + 0,0,1,192,192,243,1,9,9,11,1,201,201,255,1,11,11,14,1,190, + 190,241,1,201,201,255,1,199,199,252,1,166,166,210,1,201,201,255,1,128, + 128,128,5,0,0,0,2,201,201,255,1,90,90,114,1,111,111,141,1,201, + 201,255,1,111,111,141,1,91,91,115,1,201,201,255,1,0,0,0,1,185, + 185,235,1,15,15,19,1,201,201,255,1,65,65,83,1,98,98,124,1,193, + 193,245,1,114,114,145,1,45,45,57,1,201,201,255,1,255,255,255,1,212, + 212,212,1,252,252,252,1,208,208,208,1,255,255,255,1,0,0,0,2,201, + 201,255,1,29,29,37,1,171,171,217,1,201,201,255,1,171,171,217,1,30, + 30,38,1,201,201,255,1,0,0,0,1,2,2,3,1,98,98,124,1,201, + 201,255,1,179,179,227,1,50,50,63,1,6,6,7,1,34,34,43,1,168, + 168,213,1,201,201,255,1,255,255,255,4,128,128,128,1,0,0,0,2,201, + 201,255,17,255,255,255,1,128,128,128,4,0,0,0,2,201,201,255,2,0, + 0,0,2,4,4,5,1,137,137,174,1,201,201,255,11,208,208,208,1,255, + 255,255,1,211,211,211,1,255,255,255,1,208,208,208,1,0,0,0,2,201, + 201,255,2,0,0,0,1,201,201,255,1,137,137,174,1,4,4,5,1,201, + 201,255,1,120,120,152,1,9,9,11,1,125,125,159,1,201,201,255,7,255, + 255,255,2,252,252,252,1,255,255,255,2,0,0,0,2,201,201,255,2,0, + 0,0,1,201,201,255,2,0,0,0,1,201,201,255,1,23,23,29,1,155, + 155,197,1,29,29,37,1,201,201,255,7,255,255,255,1,208,208,208,3,128, + 128,128,1,0,0,0,2,201,201,255,2,0,0,0,1,201,201,255,2,0, + 0,0,1,201,201,255,1,2,2,2,1,0,0,0,1,2,2,3,1,201, + 201,255,7,255,255,255,1,0,0,0,3,128,128,128,1,0,0,0,2,201, + 201,255,2,0,0,0,1,201,201,255,1,137,137,174,1,4,4,5,1,201, + 201,255,1,20,20,25,1,178,178,226,1,201,201,255,8,255,255,255,1,208, + 208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,0,0,0,2,201, + 201,255,2,0,0,0,2,4,4,5,1,137,137,174,1,201,201,255,1,115, + 115,146,1,7,7,9,1,77,77,98,1,201,201,255,7,128,128,128,5,0, + 0,0,25,12,0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0, + 0) + ); + +const + objdata_tdbenum64editlb: record size: integer; data: array[0..1386] of byte end = + (size: 1387; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,100,98, + 101,110,117,109,54,52,101,100,105,116,108,98,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,240,4,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,172,4,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,184,255,255, + 1,172,238,238,1,21,29,29,1,184,255,255,1,124,172,172,1,15,21,21, + 1,13,18,18,1,107,148,148,1,83,115,115,1,11,15,15,2,92,128,128, + 1,184,255,255,2,0,0,0,1,169,234,234,1,17,23,23,1,255,255,255, + 6,128,128,128,1,184,255,255,1,71,98,98,1,0,0,0,1,184,255,255, + 1,21,29,29,1,145,201,201,1,151,209,209,1,7,10,10,1,184,255,255, + 2,140,194,194,1,12,17,17,1,184,255,255,3,0,0,0,1,184,255,255, + 1,255,255,255,1,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128, + 1,184,255,255,1,178,247,247,1,0,0,0,1,184,255,255,3,148,205,205, + 1,49,68,68,1,184,255,255,1,118,164,164,1,3,4,4,1,74,103,103, + 1,184,255,255,3,0,0,0,1,184,255,255,1,255,255,255,1,0,0,0, + 3,128,128,128,1,255,255,255,1,128,128,128,1,184,255,255,2,0,0,0, + 1,184,255,255,2,162,224,224,1,51,70,70,1,167,232,232,1,184,255,255, + 2,154,214,214,1,7,10,10,1,184,255,255,3,0,0,0,1,184,255,255, + 1,255,255,255,1,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128, + 1,255,255,255,1,128,128,128,1,184,255,255,2,0,0,0,1,184,255,255, + 1,119,165,165,1,56,77,77,1,170,235,235,1,184,255,255,1,23,32,32, + 1,164,227,227,1,169,234,234,1,17,24,24,1,184,255,255,1,182,252,252, + 1,167,231,231,1,0,0,0,1,178,247,247,1,255,255,255,1,208,208,208, + 3,128,128,128,1,255,255,255,1,128,128,128,1,184,255,255,2,0,0,0, + 1,184,255,255,1,14,19,19,1,0,0,0,3,128,177,177,1,14,19,19, + 1,17,24,24,1,129,179,179,1,184,255,255,1,161,223,223,1,0,0,0, + 1,161,223,223,1,0,0,0,1,128,128,128,5,255,255,255,25,0,0,0, + 25,201,201,255,17,255,255,255,5,0,0,0,2,201,201,255,17,255,255,255, + 1,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,0,0,0, + 2,201,201,255,2,199,199,253,1,105,105,133,1,19,19,24,1,4,4,5, + 1,58,58,73,1,181,181,230,1,201,201,255,5,143,143,182,1,2,2,2, + 1,201,201,255,2,255,255,255,1,0,0,0,3,128,128,128,1,0,0,0, + 2,201,201,255,2,112,112,142,1,24,24,30,1,137,137,174,1,152,152,193, + 1,51,51,65,1,61,61,77,1,201,201,255,4,169,169,215,1,11,11,14, + 1,0,0,0,1,201,201,255,2,255,255,255,1,208,208,208,3,128,128,128, + 1,0,0,0,2,201,201,255,1,200,200,254,1,24,24,30,1,142,142,180, + 1,201,201,255,2,184,184,233,1,139,139,176,1,201,201,255,3,188,188,238, + 1,28,28,36,1,90,90,114,1,0,0,0,1,201,201,255,2,128,128,128, + 5,0,0,0,2,201,201,255,1,184,184,234,1,0,0,0,1,117,117,149, + 1,21,21,27,1,6,6,8,1,66,66,84,1,187,187,237,1,201,201,255, + 2,198,198,251,1,54,54,69,1,86,86,109,1,169,169,215,1,0,0,0, + 1,201,201,255,2,255,255,255,1,212,212,212,1,252,252,252,1,208,208,208, + 1,255,255,255,1,0,0,0,2,201,201,255,1,170,170,216,1,0,0,0, + 1,39,39,49,1,148,148,188,1,154,154,195,1,43,43,55,1,64,64,81, + 1,201,201,255,2,87,87,111,1,53,53,67,1,197,197,250,1,169,169,215, + 1,0,0,0,1,201,201,255,2,255,255,255,4,128,128,128,1,0,0,0, + 2,201,201,255,1,174,174,221,1,0,0,0,1,166,166,210,1,201,201,255, + 2,167,167,212,1,1,1,1,1,189,189,240,1,126,126,160,1,28,28,35, + 1,187,187,237,1,201,201,255,1,169,169,215,1,0,0,0,1,201,201,255, + 2,255,255,255,1,128,128,128,4,0,0,0,2,201,201,255,1,191,191,242, + 1,0,0,0,1,196,196,249,1,201,201,255,2,196,196,249,1,0,0,0, + 1,173,173,220,1,72,72,91,1,0,0,0,6,84,84,107,1,208,208,208, + 1,255,255,255,1,211,211,211,1,255,255,255,1,208,208,208,1,0,0,0, + 2,201,201,255,2,32,32,40,1,154,154,195,1,201,201,255,2,158,158,200, + 1,6,6,7,1,194,194,246,1,181,181,229,1,169,169,215,3,143,143,181, + 1,0,0,0,1,169,169,215,1,182,182,231,1,255,255,255,2,252,252,252, + 1,255,255,255,2,0,0,0,2,201,201,255,2,114,114,144,1,28,28,35, + 1,142,142,180,1,143,143,182,1,32,32,40,1,84,84,106,1,201,201,255, + 5,169,169,215,1,0,0,0,1,201,201,255,2,255,255,255,1,208,208,208, + 3,128,128,128,1,0,0,0,2,201,201,255,2,199,199,252,1,88,88,112, + 1,9,9,12,1,12,12,15,1,84,84,106,1,195,195,247,1,201,201,255, + 5,169,169,215,1,0,0,0,1,201,201,255,2,255,255,255,1,0,0,0, + 3,128,128,128,1,0,0,0,2,201,201,255,17,255,255,255,1,208,208,208, + 1,0,0,0,1,208,208,208,1,128,128,128,1,0,0,0,2,201,201,255, + 17,128,128,128,5,0,0,0,25,12,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,66,0,0) + ); + +const + objdata_tdbkeystringedit: record size: integer; data: array[0..1191] of byte end = + (size: 1192; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,100,98, + 107,101,121,115,116,114,105,110,103,101,100,105,116,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,44,4, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,232,3, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,184,255, + 255,2,119,165,165,1,0,0,0,1,119,165,165,1,184,255,255,2,0,0, + 0,1,1,1,1,1,54,75,75,1,184,255,255,4,0,0,0,1,169,234, + 234,1,17,23,23,1,255,255,255,6,128,128,128,1,184,255,255,2,63,88, + 88,1,54,75,75,1,64,89,89,1,184,255,255,2,0,0,0,1,169,234, + 234,1,51,70,70,1,184,255,255,5,0,0,0,1,184,255,255,1,255,255, + 255,1,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128,1,184,255, + 255,1,181,251,251,1,15,21,21,1,159,221,221,1,14,20,20,1,181,251, + 251,1,184,255,255,1,0,0,0,2,84,117,117,1,184,255,255,5,0,0, + 0,1,184,255,255,1,255,255,255,1,0,0,0,3,128,128,128,1,255,255, + 255,1,128,128,128,1,184,255,255,1,138,191,191,1,0,0,0,3,138,191, + 191,1,184,255,255,1,0,0,0,1,175,243,243,1,8,11,11,1,184,255, + 255,5,0,0,0,1,184,255,255,1,255,255,255,1,208,208,208,1,0,0, + 0,1,208,208,208,1,128,128,128,1,255,255,255,1,128,128,128,1,184,255, + 255,1,82,114,114,1,102,141,141,1,184,255,255,1,102,141,141,1,83,115, + 115,1,184,255,255,1,0,0,0,1,170,235,235,1,14,19,19,1,184,255, + 255,3,182,252,252,1,167,231,231,1,0,0,0,1,178,247,247,1,255,255, + 255,1,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128,1,184,255, + 255,1,27,37,37,1,157,217,217,1,184,255,255,1,157,217,217,1,27,38, + 38,1,184,255,255,1,0,0,0,1,2,3,3,1,89,124,124,1,184,255, + 255,3,161,223,223,1,0,0,0,1,161,223,223,1,0,0,0,1,128,128, + 128,5,255,255,255,25,0,0,0,25,255,255,255,22,0,0,0,2,255,255, + 255,18,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,0,0, + 0,2,255,255,255,18,0,0,0,3,128,128,128,1,0,0,0,2,255,255, + 255,1,0,0,0,1,255,255,255,2,157,157,157,1,102,102,102,1,255,255, + 255,12,208,208,208,3,128,128,128,1,0,0,0,2,255,255,255,1,0,0, + 0,1,255,255,255,1,201,201,201,1,65,65,65,1,249,249,249,1,255,255, + 255,11,128,128,128,5,0,0,0,2,255,255,255,1,0,0,0,1,233,233, + 233,1,53,53,53,1,230,230,230,1,255,255,255,1,186,186,186,1,25,25, + 25,2,195,195,195,1,255,255,255,1,52,52,52,1,203,203,203,1,255,255, + 255,1,204,204,204,1,50,50,50,1,255,255,255,2,212,212,212,1,252,252, + 252,1,208,208,208,1,255,255,255,1,0,0,0,2,255,255,255,1,0,0, + 0,1,62,62,62,1,124,124,124,1,255,255,255,2,39,39,39,1,194,194, + 194,1,197,197,197,1,50,50,50,1,255,255,255,1,157,157,157,1,97,97, + 97,1,255,255,255,1,102,102,102,1,152,152,152,1,255,255,255,5,128,128, + 128,1,0,0,0,2,255,255,255,1,0,0,0,1,146,146,146,1,57,57, + 57,1,208,208,208,1,255,255,255,1,3,3,3,1,0,0,0,2,4,4, + 4,1,255,255,255,1,246,246,246,1,27,27,27,1,226,226,226,1,25,25, + 25,1,242,242,242,1,255,255,255,2,128,128,128,4,0,0,0,2,255,255, + 255,1,0,0,0,1,255,255,255,1,217,217,217,1,51,51,51,1,244,244, + 244,1,34,34,34,1,195,195,195,1,255,255,255,4,113,113,113,1,55,55, + 55,1,99,99,99,1,255,255,255,2,208,208,208,1,255,255,255,1,211,211, + 211,1,255,255,255,1,208,208,208,1,0,0,0,2,255,255,255,1,0,0, + 0,1,255,255,255,2,161,161,161,1,94,94,94,1,179,179,179,1,23,23, + 23,1,13,13,13,1,120,120,120,1,255,255,255,2,217,217,217,1,0,0, + 0,1,201,201,201,1,255,255,255,4,252,252,252,1,255,255,255,2,0,0, + 0,2,255,255,255,12,202,202,202,1,41,41,41,1,255,255,255,4,208,208, + 208,3,128,128,128,1,0,0,0,2,255,255,255,12,12,12,12,1,168,168, + 168,1,255,255,255,4,0,0,0,3,128,128,128,1,0,0,0,2,255,255, + 255,18,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,0,0, + 0,2,255,255,255,17,128,128,128,5,0,0,0,25,12,0,0,0,255,255, + 255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tdbkeystringeditdb: record size: integer; data: array[0..1237] of byte end = + (size: 1238; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,18,116,100,98, + 107,101,121,115,116,114,105,110,103,101,100,105,116,100,98,23,98,105,116,109, + 97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4, + 6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11, + 10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111, + 114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10, + 88,4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0, + 20,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25, + 184,255,255,2,119,165,165,1,0,0,0,1,119,165,165,1,184,255,255,2, + 0,0,0,1,1,1,1,1,54,75,75,1,184,255,255,4,0,0,0,1, + 169,234,234,1,17,23,23,1,255,255,255,6,128,128,128,1,184,255,255,2, + 63,88,88,1,54,75,75,1,64,89,89,1,184,255,255,2,0,0,0,1, + 169,234,234,1,51,70,70,1,184,255,255,5,0,0,0,1,184,255,255,1, + 255,255,255,1,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128,1, + 184,255,255,1,181,251,251,1,15,21,21,1,159,221,221,1,14,20,20,1, + 181,251,251,1,184,255,255,1,0,0,0,2,84,117,117,1,184,255,255,5, + 0,0,0,1,184,255,255,1,255,255,255,1,0,0,0,3,128,128,128,1, + 255,255,255,1,128,128,128,1,184,255,255,1,138,191,191,1,0,0,0,3, + 138,191,191,1,184,255,255,1,0,0,0,1,175,243,243,1,8,11,11,1, + 184,255,255,5,0,0,0,1,184,255,255,1,255,255,255,1,208,208,208,1, + 0,0,0,1,208,208,208,1,128,128,128,1,255,255,255,1,128,128,128,1, + 184,255,255,1,82,114,114,1,102,141,141,1,184,255,255,1,102,141,141,1, + 83,115,115,1,184,255,255,1,0,0,0,1,170,235,235,1,14,19,19,1, + 184,255,255,3,182,252,252,1,167,231,231,1,0,0,0,1,178,247,247,1, + 255,255,255,1,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128,1, + 184,255,255,1,27,37,37,1,157,217,217,1,184,255,255,1,157,217,217,1, + 27,38,38,1,184,255,255,1,0,0,0,1,2,3,3,1,89,124,124,1, + 184,255,255,3,161,223,223,1,0,0,0,1,161,223,223,1,0,0,0,1, + 128,128,128,5,255,255,255,25,0,0,0,25,184,255,255,17,255,255,255,5, + 0,0,0,2,184,255,255,17,255,255,255,1,208,208,208,1,0,0,0,1, + 208,208,208,1,128,128,128,1,0,0,0,2,184,255,255,17,255,255,255,1, + 0,0,0,3,128,128,128,1,0,0,0,2,184,255,255,1,0,0,0,1, + 184,255,255,2,113,157,157,1,74,102,102,1,184,255,255,11,255,255,255,1, + 208,208,208,3,128,128,128,1,0,0,0,2,184,255,255,1,0,0,0,1, + 184,255,255,1,145,201,201,1,47,65,65,1,180,249,249,1,184,255,255,11, + 128,128,128,5,0,0,0,2,184,255,255,1,0,0,0,1,168,233,233,1, + 38,53,53,1,166,230,230,1,184,255,255,1,134,186,186,1,18,25,25,2, + 141,195,195,1,184,255,255,1,38,52,52,1,146,203,203,1,184,255,255,1, + 147,204,204,1,36,50,50,1,184,255,255,1,255,255,255,1,212,212,212,1, + 252,252,252,1,208,208,208,1,255,255,255,1,0,0,0,2,184,255,255,1, + 0,0,0,1,45,62,62,1,89,124,124,1,184,255,255,2,28,39,39,1, + 140,194,194,1,142,197,197,1,36,50,50,1,184,255,255,1,113,157,157,1, + 70,97,97,1,184,255,255,1,74,102,102,1,110,152,152,1,184,255,255,1, + 255,255,255,4,128,128,128,1,0,0,0,2,184,255,255,1,0,0,0,1, + 105,146,146,1,41,57,57,1,150,208,208,1,184,255,255,1,2,3,3,1, + 0,0,0,2,3,4,4,1,184,255,255,1,178,246,246,1,19,27,27,1, + 163,226,226,1,18,25,25,1,175,242,242,1,184,255,255,1,255,255,255,1, + 128,128,128,4,0,0,0,2,184,255,255,1,0,0,0,1,184,255,255,1, + 157,217,217,1,37,51,51,1,176,244,244,1,25,34,34,1,141,195,195,1, + 184,255,255,4,82,113,113,1,40,55,55,1,71,99,99,1,184,255,255,2, + 208,208,208,1,255,255,255,1,211,211,211,1,255,255,255,1,208,208,208,1, + 0,0,0,2,184,255,255,1,0,0,0,1,184,255,255,2,116,161,161,1, + 68,94,94,1,129,179,179,1,17,23,23,1,9,13,13,1,87,120,120,1, + 184,255,255,2,157,217,217,1,0,0,0,1,145,201,201,1,184,255,255,2, + 255,255,255,2,252,252,252,1,255,255,255,2,0,0,0,2,184,255,255,12, + 146,202,202,1,30,41,41,1,184,255,255,3,255,255,255,1,208,208,208,3, + 128,128,128,1,0,0,0,2,184,255,255,12,9,12,12,1,121,168,168,1, + 184,255,255,3,255,255,255,1,0,0,0,3,128,128,128,1,0,0,0,2, + 184,255,255,17,255,255,255,1,208,208,208,1,0,0,0,1,208,208,208,1, + 128,128,128,1,0,0,0,2,184,255,255,17,128,128,128,5,0,0,0,25, + 12,0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tdbkeystringeditlb: record size: integer; data: array[0..1237] of byte end = + (size: 1238; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,18,116,100,98, + 107,101,121,115,116,114,105,110,103,101,100,105,116,108,98,23,98,105,116,109, + 97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4, + 6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11, + 10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111, + 114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10, + 88,4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0, + 20,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25, + 184,255,255,2,119,165,165,1,0,0,0,1,119,165,165,1,184,255,255,2, + 0,0,0,1,1,1,1,1,54,75,75,1,184,255,255,4,0,0,0,1, + 169,234,234,1,17,23,23,1,255,255,255,6,128,128,128,1,184,255,255,2, + 63,88,88,1,54,75,75,1,64,89,89,1,184,255,255,2,0,0,0,1, + 169,234,234,1,51,70,70,1,184,255,255,5,0,0,0,1,184,255,255,1, + 255,255,255,1,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128,1, + 184,255,255,1,181,251,251,1,15,21,21,1,159,221,221,1,14,20,20,1, + 181,251,251,1,184,255,255,1,0,0,0,2,84,117,117,1,184,255,255,5, + 0,0,0,1,184,255,255,1,255,255,255,1,0,0,0,3,128,128,128,1, + 255,255,255,1,128,128,128,1,184,255,255,1,138,191,191,1,0,0,0,3, + 138,191,191,1,184,255,255,1,0,0,0,1,175,243,243,1,8,11,11,1, + 184,255,255,5,0,0,0,1,184,255,255,1,255,255,255,1,208,208,208,1, + 0,0,0,1,208,208,208,1,128,128,128,1,255,255,255,1,128,128,128,1, + 184,255,255,1,82,114,114,1,102,141,141,1,184,255,255,1,102,141,141,1, + 83,115,115,1,184,255,255,1,0,0,0,1,170,235,235,1,14,19,19,1, + 184,255,255,3,182,252,252,1,167,231,231,1,0,0,0,1,178,247,247,1, + 255,255,255,1,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128,1, + 184,255,255,1,27,37,37,1,157,217,217,1,184,255,255,1,157,217,217,1, + 27,38,38,1,184,255,255,1,0,0,0,1,2,3,3,1,89,124,124,1, + 184,255,255,3,161,223,223,1,0,0,0,1,161,223,223,1,0,0,0,1, + 128,128,128,5,255,255,255,25,0,0,0,25,201,201,255,17,255,255,255,5, + 0,0,0,2,201,201,255,17,255,255,255,1,208,208,208,1,0,0,0,1, + 208,208,208,1,128,128,128,1,0,0,0,2,201,201,255,17,255,255,255,1, + 0,0,0,3,128,128,128,1,0,0,0,2,201,201,255,1,0,0,0,1, + 201,201,255,2,124,124,157,1,80,80,102,1,201,201,255,11,255,255,255,1, + 208,208,208,3,128,128,128,1,0,0,0,2,201,201,255,1,0,0,0,1, + 201,201,255,1,158,158,201,1,51,51,65,1,196,196,249,1,201,201,255,11, + 128,128,128,5,0,0,0,2,201,201,255,1,0,0,0,1,184,184,233,1, + 42,42,53,1,181,181,230,1,201,201,255,1,147,147,186,1,20,20,25,2, + 154,154,195,1,201,201,255,1,41,41,52,1,160,160,203,1,201,201,255,1, + 161,161,204,1,39,39,50,1,201,201,255,1,255,255,255,1,212,212,212,1, + 252,252,252,1,208,208,208,1,255,255,255,1,0,0,0,2,201,201,255,1, + 0,0,0,1,49,49,62,1,98,98,124,1,201,201,255,2,31,31,39,1, + 153,153,194,1,155,155,197,1,39,39,50,1,201,201,255,1,124,124,157,1, + 76,76,97,1,201,201,255,1,80,80,102,1,120,120,152,1,201,201,255,1, + 255,255,255,4,128,128,128,1,0,0,0,2,201,201,255,1,0,0,0,1, + 115,115,146,1,45,45,57,1,164,164,208,1,201,201,255,1,2,2,3,1, + 0,0,0,2,3,3,4,1,201,201,255,1,194,194,246,1,21,21,27,1, + 178,178,226,1,20,20,25,1,191,191,242,1,201,201,255,1,255,255,255,1, + 128,128,128,4,0,0,0,2,201,201,255,1,0,0,0,1,201,201,255,1, + 171,171,217,1,40,40,51,1,192,192,244,1,27,27,34,1,154,154,195,1, + 201,201,255,4,89,89,113,1,43,43,55,1,78,78,99,1,201,201,255,2, + 208,208,208,1,255,255,255,1,211,211,211,1,255,255,255,1,208,208,208,1, + 0,0,0,2,201,201,255,1,0,0,0,1,201,201,255,2,127,127,161,1, + 74,74,94,1,141,141,179,1,18,18,23,1,10,10,13,1,95,95,120,1, + 201,201,255,2,171,171,217,1,0,0,0,1,158,158,201,1,201,201,255,2, + 255,255,255,2,252,252,252,1,255,255,255,2,0,0,0,2,201,201,255,12, + 159,159,202,1,32,32,41,1,201,201,255,3,255,255,255,1,208,208,208,3, + 128,128,128,1,0,0,0,2,201,201,255,12,9,9,12,1,132,132,168,1, + 201,201,255,3,255,255,255,1,0,0,0,3,128,128,128,1,0,0,0,2, + 201,201,255,17,255,255,255,1,208,208,208,1,0,0,0,1,208,208,208,1, + 128,128,128,1,0,0,0,2,201,201,255,17,128,128,128,5,0,0,0,25, + 12,0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tdbstringlookuplb: record size: integer; data: array[0..948] of byte end = + (size: 949; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,100,98, + 115,116,114,105,110,103,108,111,111,107,117,112,108,98,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,56, + 3,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,244, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,0, + 0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,7,176, + 244,244,1,175,243,243,1,184,255,255,9,188,241,255,1,196,214,255,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,7,98, + 136,136,1,92,127,127,1,184,255,255,7,188,241,255,1,196,214,255,1,201, + 201,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184, + 255,255,7,98,136,136,1,92,127,127,1,184,255,255,5,188,241,255,1,196, + 214,255,1,201,201,255,4,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,184,255,255,1,151,209,209,1,45,62,62,1,26,36,36,1,22, + 31,31,1,113,156,156,1,184,255,255,1,98,136,136,1,63,87,87,1,61, + 85,85,1,22,30,30,1,95,131,131,1,188,241,255,1,196,214,255,1,137, + 137,174,1,37,37,47,1,35,35,45,1,97,97,123,1,201,201,255,2,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,63, + 88,88,1,126,174,174,1,184,255,255,1,145,201,201,1,12,17,17,1,184, + 255,255,1,98,136,136,1,19,27,27,1,160,222,222,1,170,217,230,1,27, + 29,35,1,149,149,189,1,171,171,217,1,15,15,19,1,169,169,214,1,198, + 198,251,1,56,56,71,1,153,153,194,1,201,201,255,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,183,254,254,1,141, + 196,196,1,105,145,145,1,68,94,94,1,0,0,0,1,184,255,255,1,98, + 136,136,1,77,98,104,1,196,214,255,1,201,201,255,1,88,88,112,1,97, + 97,123,1,125,125,158,1,61,61,78,1,201,201,255,5,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,55,76,76,2,109, + 151,151,1,142,197,197,1,0,0,0,1,188,241,255,1,105,114,136,1,95, + 95,121,1,201,201,255,2,94,94,119,1,95,95,121,1,114,114,144,1,70, + 70,89,1,201,201,255,2,191,191,242,1,193,193,245,1,201,201,255,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,179,248,248,1,4, + 6,6,1,172,239,239,1,184,255,255,1,124,159,168,1,0,0,0,1,198, + 198,251,1,107,107,136,1,42,42,53,1,189,189,240,1,193,193,245,1,32, + 32,40,1,144,144,183,1,157,157,199,1,20,20,25,1,192,192,243,1,201, + 201,255,1,68,68,86,1,135,135,171,1,201,201,255,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,89,123,123,1,36, + 46,49,1,51,56,67,1,79,79,100,1,22,22,28,1,176,176,223,1,107, + 107,136,1,65,65,82,1,54,54,68,1,38,38,48,1,110,110,139,1,201, + 201,255,2,117,117,148,1,42,42,53,1,44,44,56,1,76,76,96,1,200, + 200,254,1,201,201,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,188,241,255,1,196,214,255,1,194,194,246,1,195,195,247,1,201, + 201,255,5,199,199,253,1,196,196,249,1,201,201,255,4,200,200,254,1,194, + 194,246,1,201,201,255,3,224,224,224,1,255,255,255,1,128,128,128,1,224, + 224,224,22,255,255,255,25,208,208,208,240,12,0,0,0,255,255,255,255,255, + 255,255,81,0,0,0,240,0,0) + ); + +const + objdata_tdbstringlookupdb: record size: integer; data: array[0..968] of byte end = + (size: 969; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,100,98, + 115,116,114,105,110,103,108,111,111,107,117,112,100,98,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,76, + 3,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,8, + 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,0, + 0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,7,176, + 244,244,1,175,243,243,1,184,255,255,7,174,249,255,1,97,202,255,1,18, + 153,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184, + 255,255,7,98,136,136,1,92,127,127,1,184,255,255,5,174,249,255,1,97, + 202,255,1,18,153,255,2,97,202,255,1,174,249,255,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,184,255,255,7,98,136,136,1,92, + 127,127,1,184,255,255,3,174,249,255,1,97,202,255,1,18,153,255,2,97, + 202,255,1,174,249,255,1,184,255,255,2,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,184,255,255,1,151,209,209,1,45,62,62,1,26, + 36,36,1,22,31,31,1,113,156,156,1,184,255,255,1,98,136,136,1,63, + 87,87,1,61,85,85,1,20,29,30,1,50,104,131,1,18,153,255,2,66, + 138,174,1,32,46,47,1,32,45,45,1,89,123,123,1,184,255,255,2,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,63, + 88,88,1,126,174,174,1,184,255,255,1,145,201,201,1,12,17,17,1,184, + 255,255,1,98,136,136,1,18,26,27,1,84,176,222,1,16,138,230,1,2, + 21,35,1,72,150,189,1,148,212,217,1,14,19,19,1,154,214,214,1,181, + 251,251,1,51,71,71,1,140,194,194,1,184,255,255,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,183,254,254,1,141, + 196,196,1,105,145,145,1,68,94,94,1,0,0,0,1,174,249,255,1,52, + 108,136,1,7,62,104,1,18,153,255,1,97,202,255,1,76,109,112,1,89, + 123,123,1,114,158,158,1,56,78,78,1,184,255,255,5,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,55,76,76,2,109, + 151,151,1,134,192,197,1,0,0,0,1,18,153,255,1,10,82,136,1,46, + 96,121,1,174,249,255,1,184,255,255,1,86,119,119,1,87,121,121,1,104, + 144,144,1,64,89,89,1,184,255,255,2,175,242,242,1,177,245,245,1,184, + 255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,179, + 248,248,1,4,6,6,1,163,233,239,1,97,202,255,1,12,101,168,1,0, + 0,0,1,95,199,251,1,93,133,136,1,38,53,53,1,173,240,240,1,177, + 245,245,1,29,40,40,1,132,183,183,1,144,199,199,1,18,25,25,1,175, + 243,243,1,184,255,255,1,62,86,86,1,123,171,171,1,184,255,255,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,174,249,255,1,47, + 97,123,1,3,29,49,1,5,40,67,1,38,79,100,1,19,27,28,1,161, + 223,223,1,98,136,136,1,59,82,82,1,49,68,68,1,35,48,48,1,100, + 139,139,1,184,255,255,2,107,148,148,1,38,53,53,1,40,56,56,1,69, + 96,96,1,183,254,254,1,184,255,255,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,18,153,255,2,94,195,246,1,169,241,247,1,184, + 255,255,5,183,253,253,1,180,249,249,1,184,255,255,4,183,254,254,1,178, + 246,246,1,184,255,255,3,224,224,224,1,255,255,255,1,128,128,128,1,224, + 224,224,22,255,255,255,25,208,208,208,240,12,0,0,0,255,255,255,255,255, + 255,255,81,0,0,0,240,0,0) + ); + +const + objdata_tdbintegerlookuplb: record size: integer; data: array[0..957] of byte end = + (size: 958; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,18,116,100,98, + 105,110,116,101,103,101,114,108,111,111,107,117,112,108,98,23,98,105,116,109, + 97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4, + 6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11, + 10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111, + 114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10, + 64,3,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0, + 252,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25, + 0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,4, + 168,233,233,1,184,255,255,4,179,248,248,1,182,252,252,1,184,255,255,4, + 182,252,252,1,178,246,246,1,184,255,255,1,188,241,255,1,196,214,255,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3, + 103,143,143,1,51,71,71,1,184,255,255,2,181,251,251,1,69,95,95,1, + 35,48,48,1,31,43,43,1,87,121,121,1,184,255,255,2,105,145,145,1, + 34,47,47,1,33,43,45,1,79,86,103,1,198,198,251,1,201,201,255,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1, + 175,242,242,1,75,104,104,1,13,18,18,1,51,71,71,1,184,255,255,2, + 118,164,164,1,62,86,86,1,184,255,255,1,180,250,250,1,32,44,44,1, + 147,204,204,1,159,221,221,1,23,29,31,1,190,207,247,1,201,201,255,1, + 43,43,55,1,142,142,180,1,201,201,255,1,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,184,255,255,1,142,197,197,1,92,127,127,1, + 126,175,175,1,51,71,71,1,184,255,255,2,154,214,214,1,162,225,225,1, + 184,255,255,2,51,71,71,1,116,149,158,1,196,214,255,1,188,188,238,1, + 201,201,255,1,199,199,252,1,32,32,40,1,143,143,181,1,201,201,255,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3, + 132,183,183,1,51,71,71,1,184,255,255,5,137,176,186,1,21,23,27,1, + 187,187,237,1,201,201,255,2,139,139,176,1,19,19,24,1,66,66,84,1, + 201,201,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 184,255,255,3,132,183,183,1,51,71,71,1,184,255,255,3,188,241,255,1, + 135,148,176,1,20,20,26,1,160,160,203,1,201,201,255,3,188,188,238,1, + 163,163,207,1,50,50,63,1,114,114,144,1,201,201,255,1,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,132,183,183,1, + 51,71,71,1,184,255,255,1,188,241,255,1,196,214,255,1,130,130,165,1, + 26,26,33,1,168,168,213,1,201,201,255,2,188,188,238,1,175,175,222,1, + 201,201,255,2,137,137,174,1,49,49,62,1,201,201,255,1,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,132,183,183,1, + 52,67,71,1,196,214,255,1,201,201,255,1,148,148,188,1,31,31,39,1, + 181,181,229,1,201,201,255,3,169,169,214,1,27,27,34,1,197,197,250,1, + 201,201,255,1,81,81,103,1,107,107,136,1,201,201,255,1,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,2,188,241,255,1, + 141,154,183,1,56,56,71,1,201,201,255,2,48,48,61,1,2,2,3,1, + 6,6,7,3,110,110,139,1,201,201,255,1,107,107,136,1,37,37,47,1, + 41,41,52,1,76,76,96,1,188,188,239,1,201,201,255,1,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,188,241,255,1,196,214,255,1, + 201,201,255,13,198,198,251,1,192,192,244,1,201,201,255,3,224,224,224,1, + 255,255,255,1,128,128,128,1,224,224,224,22,255,255,255,25,208,208,208,240, + 12,0,0,0,255,255,255,255,255,255,255,81,0,0,0,240,0,0) + ); + +const + objdata_tdbintegerlookupdb: record size: integer; data: array[0..989] of byte end = + (size: 990; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,18,116,100,98, + 105,110,116,101,103,101,114,108,111,111,107,117,112,100,98,23,98,105,116,109, + 97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4, + 6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11, + 10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111, + 114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10, + 96,3,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0, + 28,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25, + 0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,4, + 168,233,233,1,184,255,255,4,179,248,248,1,182,252,252,1,184,255,255,4, + 182,252,252,1,168,240,246,1,97,202,255,1,18,153,255,2,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,103,143,143,1, + 51,71,71,1,184,255,255,2,181,251,251,1,69,95,95,1,35,48,48,1, + 31,43,43,1,87,121,121,1,184,255,255,2,99,142,145,1,18,37,47,1, + 3,27,45,1,7,62,103,1,95,199,251,1,174,249,255,1,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,175,242,242,1, + 75,104,104,1,13,18,18,1,51,71,71,1,184,255,255,2,118,164,164,1, + 62,86,86,1,184,255,255,1,180,250,250,1,32,44,44,1,139,199,204,1, + 84,175,221,1,2,19,31,1,17,148,247,1,97,202,255,1,38,54,55,1, + 130,180,180,1,184,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,184,255,255,1,142,197,197,1,92,127,127,1,126,175,175,1, + 51,71,71,1,184,255,255,2,154,214,214,1,162,225,225,1,184,255,255,1, + 174,249,255,1,27,56,71,1,11,95,158,1,18,153,255,1,91,189,238,1, + 174,249,255,1,182,252,252,1,29,40,40,1,131,181,181,1,184,255,255,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3, + 132,183,183,1,51,71,71,1,184,255,255,3,174,249,255,1,97,202,255,1, + 13,112,186,1,2,16,27,1,90,188,237,1,174,249,255,1,184,255,255,1, + 127,176,176,1,17,24,24,1,61,84,84,1,184,255,255,2,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,132,183,183,1, + 51,71,71,1,184,255,255,1,174,249,255,1,97,202,255,1,18,153,255,1, + 12,106,176,1,10,21,26,1,139,198,203,1,184,255,255,3,172,238,238,1, + 149,207,207,1,45,63,63,1,104,144,144,1,184,255,255,1,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,132,183,183,1, + 48,69,71,1,97,202,255,1,18,153,255,2,63,131,165,1,23,32,33,1, + 154,213,213,1,184,255,255,2,172,238,238,1,160,222,222,1,184,255,255,2, + 126,174,174,1,45,62,62,1,184,255,255,1,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,184,255,255,2,174,249,255,1,70,145,183,1, + 5,43,71,1,18,153,255,1,97,202,255,1,128,184,188,1,28,39,39,1, + 165,229,229,1,184,255,255,3,154,214,214,1,25,34,34,1,180,250,250,1, + 184,255,255,1,74,103,103,1,98,136,136,1,184,255,255,1,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,174,249,255,1,97,202,255,1, + 18,153,255,1,13,110,183,1,27,56,71,1,174,249,255,1,184,255,255,1, + 44,61,61,1,2,3,3,1,5,7,7,3,100,139,139,1,184,255,255,1, + 98,136,136,1,34,47,47,1,38,52,52,1,69,96,96,1,172,239,239,1, + 184,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 18,153,255,2,97,202,255,1,174,249,255,1,184,255,255,11,181,251,251,1, + 176,244,244,1,184,255,255,3,224,224,224,1,255,255,255,1,128,128,128,1, + 224,224,224,22,255,255,255,25,208,208,208,240,12,0,0,0,255,255,255,255, + 255,255,255,81,0,0,0,240,0,0) + ); + +const + objdata_tdbreallookuplb: record size: integer; data: array[0..870] of byte end = + (size: 871; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,100,98, + 114,101,97,108,108,111,111,107,117,112,108,98,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,236,2,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,168,2,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,0,0,0, + 22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,168,233,233, + 1,184,255,255,7,182,252,252,1,179,248,248,1,184,255,255,5,181,232,246, + 1,186,203,242,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,2,103,143,143,1,51,71,71,1,184,255,255,6,84,116,116, + 1,33,46,46,1,32,45,45,1,72,100,100,1,181,251,251,1,184,255,255, + 1,188,241,255,1,194,211,252,1,54,54,69,1,117,117,149,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,175,242,242,1,75,104,104, + 1,13,18,18,1,51,71,71,1,184,255,255,5,142,197,197,1,40,55,55, + 1,182,252,252,1,183,254,254,1,54,75,75,1,125,161,170,1,196,214,255, + 1,169,169,214,1,45,45,57,1,13,13,17,1,117,117,149,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,142,197,197,1,92,127,127, + 1,126,175,175,1,51,71,71,1,184,255,255,5,162,224,224,1,155,215,215, + 1,184,255,255,1,188,241,255,1,81,88,105,1,98,98,124,1,201,201,255, + 1,114,114,145,1,135,135,171,1,84,84,106,1,117,117,149,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,2,132,183,183, + 1,51,71,71,1,184,255,255,6,188,241,255,1,196,214,255,1,164,164,208, + 1,19,19,24,1,172,172,218,1,201,201,255,3,84,84,106,1,117,117,149, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 2,132,183,183,1,51,71,71,1,184,255,255,4,188,241,255,1,196,214,255, + 1,201,201,255,1,158,158,200,1,20,20,26,1,142,142,180,1,201,201,255, + 4,84,84,106,1,117,117,149,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,184,255,255,2,132,183,183,1,51,71,71,1,184,255,255, + 2,188,241,255,1,196,214,255,1,201,201,255,2,151,151,191,1,22,22,28, + 1,151,151,192,1,201,201,255,5,84,84,106,1,117,117,149,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,2,132,183,183, + 1,51,71,71,1,188,241,255,1,196,214,255,1,197,197,250,1,177,177,225, + 1,201,201,255,1,169,169,215,1,22,22,28,1,168,168,213,1,201,201,255, + 6,84,84,106,1,117,117,149,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,184,255,255,2,135,173,183,1,55,60,71,1,201,201,255, + 2,164,164,208,1,12,12,15,1,201,201,255,1,74,74,94,1,2,2,2, + 1,6,6,7,3,84,84,106,1,201,201,255,3,84,84,106,1,117,117,149, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,188,241,255, + 1,196,214,255,1,201,201,255,18,224,224,224,1,255,255,255,1,128,128,128, + 1,224,224,224,22,255,255,255,25,208,208,208,240,12,0,0,0,255,255,255, + 255,255,255,255,81,0,0,0,240,0,0) + ); + +const + objdata_tdbreallookupdb: record size: integer; data: array[0..898] of byte end = + (size: 899; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,100,98, + 114,101,97,108,108,111,111,107,117,112,100,98,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,8,3,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,196,2,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,0,0,0, + 22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,168,233,233, + 1,184,255,255,7,182,252,252,1,179,248,248,1,184,255,255,3,174,249,255, + 1,97,202,255,1,17,148,246,1,17,145,242,1,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,184,255,255,2,103,143,143,1,51,71,71, + 1,184,255,255,6,84,116,116,1,33,46,46,1,32,45,45,1,72,100,100, + 1,171,245,251,1,97,202,255,1,18,153,255,1,18,151,252,1,26,55,69, + 1,102,145,149,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,175,242,242,1,75,104,104,1,13,18,18,1,51,71,71,1,184,255,255, + 5,142,197,197,1,40,55,55,1,182,252,252,1,173,248,254,1,29,59,75, + 1,12,102,170,1,18,153,255,1,81,170,214,1,39,56,57,1,12,17,17, + 1,108,149,149,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,142,197,197,1,92,127,127,1,126,175,175,1,51,71,71,1,184,255,255, + 5,162,224,224,1,147,210,215,1,97,202,255,1,18,153,255,1,7,63,105, + 1,47,98,124,1,174,249,255,1,105,145,145,1,123,171,171,1,76,106,106, + 1,108,149,149,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,2,132,183,183,1,51,71,71,1,184,255,255,4,174,249,255, + 1,97,202,255,1,18,153,255,2,79,165,208,1,16,23,24,1,157,218,218, + 1,184,255,255,3,76,106,106,1,108,149,149,1,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,184,255,255,2,132,183,183,1,51,71,71, + 1,184,255,255,2,174,249,255,1,97,202,255,1,18,153,255,2,97,202,255, + 1,136,195,200,1,19,26,26,1,130,180,180,1,184,255,255,4,76,106,106, + 1,108,149,149,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,2,132,183,183,1,51,71,71,1,174,249,255,1,97,202,255, + 1,18,153,255,2,97,202,255,1,174,249,255,1,138,191,191,1,20,28,28, + 1,139,192,192,1,184,255,255,5,76,106,106,1,108,149,149,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,2,125,179,183, + 1,27,56,71,1,18,153,255,2,95,198,250,1,154,220,225,1,184,255,255, + 1,155,215,215,1,20,28,28,1,154,213,213,1,184,255,255,6,76,106,106, + 1,108,149,149,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,174,249,255,1,97,202,255,1,13,110,183,1,5,43,71,1,97,202,255, + 1,174,249,255,1,150,208,208,1,11,15,15,1,184,255,255,1,68,94,94, + 1,1,2,2,1,5,7,7,3,76,106,106,1,184,255,255,3,76,106,106, + 1,108,149,149,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,18,153,255,2,97,202,255,1,174,249,255,1,184,255,255,16,224,224,224, + 1,255,255,255,1,128,128,128,1,224,224,224,22,255,255,255,25,208,208,208, + 240,12,0,0,0,255,255,255,255,255,255,255,81,0,0,0,240,0,0) + ); + +const + objdata_tdbdatetimelookuplb: record size: integer; data: array[0..870] of byte end = + (size: 871; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,100,98, + 100,97,116,101,116,105,109,101,108,111,111,107,117,112,108,98,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,232,2,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,164,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128, + 25,0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 1,179,248,248,1,167,231,231,2,170,235,235,1,182,252,252,1,184,255,255, + 6,173,240,240,1,167,231,231,5,175,224,237,1,196,214,255,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,127,176,176, + 1,5,7,7,1,22,31,31,1,19,27,27,1,5,7,7,1,60,83,83, + 1,168,233,233,1,184,255,255,4,80,111,111,1,22,31,31,2,1,1,1, + 1,21,26,28,1,24,26,31,1,67,67,85,1,201,201,255,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,127,176,176, + 1,45,63,63,1,184,255,255,2,180,250,250,1,66,92,92,1,56,78,78, + 1,184,255,255,6,188,241,255,1,8,8,10,1,181,181,229,1,201,201,255, + 3,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 1,127,176,176,1,45,63,63,1,184,255,255,3,175,242,242,1,1,2,2, + 1,162,224,224,1,184,255,255,1,29,40,40,1,165,228,228,1,188,241,255, + 1,196,214,255,1,201,201,255,1,8,8,10,1,181,181,229,1,201,201,255, + 3,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 1,127,176,176,1,45,63,63,1,184,255,255,4,30,42,42,1,128,178,178, + 1,184,255,255,1,136,174,184,1,189,206,246,1,201,201,255,3,8,8,10, + 1,181,181,229,1,201,201,255,3,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,184,255,255,1,127,176,176,1,45,63,63,1,184,255,255, + 4,31,43,43,1,132,169,179,1,196,214,255,1,201,201,255,5,8,8,10, + 1,181,181,229,1,201,201,255,3,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,184,255,255,1,127,176,176,1,45,63,63,1,184,255,255, + 3,177,227,240,1,7,8,9,1,174,174,221,1,201,201,255,6,8,8,10, + 1,181,181,229,1,201,201,255,3,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,184,255,255,1,127,176,176,1,45,63,63,1,184,255,255, + 1,188,241,255,1,178,195,232,1,69,69,88,1,64,64,81,1,201,201,255, + 2,177,177,224,1,198,198,251,1,201,201,255,3,8,8,10,1,181,181,229, + 1,201,201,255,3,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,1,127,176,176,1,1,1,1,1,5,6,7,1,6,6,7, + 1,17,17,22,1,78,78,99,1,192,192,243,1,201,201,255,2,1,1,1, + 1,175,175,222,1,201,201,255,3,8,8,10,1,181,181,229,1,201,201,255, + 3,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,188,241,255, + 1,196,214,255,1,201,201,255,18,224,224,224,1,255,255,255,1,128,128,128, + 1,224,224,224,22,255,255,255,25,208,208,208,240,12,0,0,0,255,255,255, + 255,255,255,255,81,0,0,0,240,0,0) + ); + +const + objdata_tdbdatetimelookupdb: record size: integer; data: array[0..926] of byte end = + (size: 927; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,100,98, + 100,97,116,101,116,105,109,101,108,111,111,107,117,112,100,98,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,32,3,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,220,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128, + 25,0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 1,179,248,248,1,167,231,231,2,170,235,235,1,182,252,252,1,184,255,255, + 6,173,240,240,1,167,231,231,3,158,226,231,1,88,183,231,1,17,142,237, + 1,18,153,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,1,127,176,176,1,5,7,7,1,22,31,31,1,19,27,27, + 1,5,7,7,1,60,83,83,1,168,233,233,1,184,255,255,4,80,111,111, + 1,22,31,31,1,21,30,31,1,0,1,1,1,2,17,28,1,2,19,31, + 1,32,67,85,1,174,249,255,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,184,255,255,1,127,176,176,1,45,63,63,1,184,255,255, + 2,180,250,250,1,66,92,92,1,56,78,78,1,184,255,255,4,174,249,255, + 1,97,202,255,1,18,153,255,1,1,6,10,1,87,181,229,1,174,249,255, + 1,184,255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,1,127,176,176,1,45,63,63,1,184,255,255,3,175,242,242, + 1,1,2,2,1,162,224,224,1,184,255,255,1,27,39,40,1,87,181,228, + 1,18,153,255,2,97,202,255,1,7,10,10,1,165,229,229,1,184,255,255, + 3,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 1,127,176,176,1,45,63,63,1,184,255,255,4,30,42,42,1,121,174,178, + 1,97,202,255,1,13,110,184,1,17,148,246,1,97,202,255,1,174,249,255, + 1,184,255,255,1,7,10,10,1,165,229,229,1,184,255,255,3,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,127,176,176, + 1,45,63,63,1,184,255,255,3,174,249,255,1,16,34,43,1,13,107,179, + 1,18,153,255,1,97,202,255,1,174,249,255,1,184,255,255,3,7,10,10, + 1,165,229,229,1,184,255,255,3,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,184,255,255,1,127,176,176,1,45,63,63,1,184,255,255, + 1,174,249,255,1,97,202,255,1,17,144,240,1,1,5,9,1,84,175,221, + 1,174,249,255,1,184,255,255,5,7,10,10,1,165,229,229,1,184,255,255, + 3,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 1,127,176,176,1,43,62,63,1,97,202,255,1,18,153,255,1,16,139,232, + 1,33,70,88,1,55,79,81,1,184,255,255,2,162,224,224,1,181,251,251, + 1,184,255,255,3,7,10,10,1,165,229,229,1,184,255,255,3,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,174,249,255,1,67,139,176, + 1,0,1,1,1,0,4,7,1,3,6,7,1,15,21,22,1,71,99,99, + 1,175,243,243,1,184,255,255,2,1,1,1,1,160,222,222,1,184,255,255, + 3,7,10,10,1,165,229,229,1,184,255,255,3,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,18,153,255,2,97,202,255,1,174,249,255, + 1,184,255,255,16,224,224,224,1,255,255,255,1,128,128,128,1,224,224,224, + 22,255,255,255,25,208,208,208,240,12,0,0,0,255,255,255,255,255,255,255, + 81,0,0,0,240,0,0) + ); + +const + objdata_tdbstringlookup64lb: record size: integer; data: array[0..1466] of byte end = + (size: 1467; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,100,98, + 115,116,114,105,110,103,108,111,111,107,117,112,54,52,108,98,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,60,5,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,140,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128, + 25,0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 7,176,244,244,1,175,243,243,1,184,255,255,9,188,241,255,1,196,214,255, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 7,98,136,136,1,92,127,127,1,184,255,255,7,188,241,255,1,196,214,255, + 1,201,201,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,7,98,136,136,1,92,127,127,1,184,255,255,5,188,241,255, + 1,196,214,255,1,201,201,255,4,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,184,255,255,1,151,209,209,1,45,62,62,1,26,36,36, + 1,22,31,31,1,113,156,156,1,184,255,255,1,98,136,136,1,63,87,87, + 1,61,85,85,1,22,30,30,1,95,131,131,1,188,241,255,1,196,214,255, + 1,137,137,174,1,37,37,47,1,35,35,45,1,97,97,123,1,201,201,255, + 2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 1,63,88,88,1,126,174,174,1,184,255,255,1,145,201,201,1,12,17,17, + 1,184,255,255,1,98,136,136,1,19,27,27,1,160,222,222,1,170,217,230, + 1,27,29,35,1,149,149,189,1,171,171,217,1,15,15,19,1,169,169,214, + 1,198,198,251,1,56,56,71,1,153,153,194,1,201,201,255,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,183,254,254, + 1,141,196,196,1,105,145,145,1,68,94,94,1,0,0,0,1,184,255,255, + 1,98,136,136,1,77,98,104,1,196,214,255,1,201,201,255,1,88,88,112, + 1,97,97,123,1,125,125,158,1,61,61,78,1,201,201,255,5,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,55,76,76, + 2,109,151,151,1,142,197,197,1,0,0,0,1,188,241,255,1,105,114,136, + 1,95,95,121,1,201,201,255,2,94,94,119,1,95,95,121,1,114,114,144, + 1,70,70,89,1,201,201,255,2,191,191,242,1,193,193,245,1,201,201,255, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,179,248,248, + 1,4,6,6,1,172,239,239,1,184,255,255,1,124,159,168,1,0,0,0, + 1,198,198,251,1,107,107,136,1,42,42,53,1,189,189,240,1,193,193,245, + 1,32,32,40,1,144,144,183,1,157,157,199,1,20,20,25,1,192,192,243, + 1,201,201,255,1,68,68,86,1,135,135,171,1,201,201,255,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,89,123,123, + 1,36,46,49,1,51,56,67,1,79,79,100,1,22,22,28,1,176,176,223, + 1,107,107,136,1,65,65,82,1,54,54,68,1,38,38,48,1,110,110,139, + 1,201,201,255,2,117,117,148,1,42,42,53,1,44,44,56,1,76,76,96, + 1,200,200,254,1,201,201,255,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,188,241,255,1,196,214,255,1,194,194,246,1,195,195,247, + 1,201,201,255,5,199,199,253,1,196,196,249,1,201,201,255,4,200,200,254, + 1,194,194,246,1,201,201,255,3,224,224,224,1,255,255,255,1,128,128,128, + 1,224,224,224,22,255,255,255,25,208,208,208,7,0,0,0,2,208,208,208, + 6,0,0,0,1,208,208,208,14,0,0,0,5,208,208,208,3,0,0,0, + 2,208,208,208,13,0,0,0,3,208,208,208,1,0,0,0,2,208,208,208, + 2,0,0,0,3,208,208,208,13,0,0,0,4,208,208,208,4,0,0,0, + 3,208,208,208,13,0,0,0,6,208,208,208,1,0,0,0,4,208,208,208, + 13,0,0,0,3,208,208,208,1,0,0,0,7,208,208,208,13,0,0,0, + 2,208,208,208,2,0,0,0,8,208,208,208,12,0,0,0,3,208,208,208, + 1,0,0,0,8,208,208,208,13,0,0,0,5,208,208,208,3,0,0,0, + 2,208,208,208,32,120,1,0,0,255,255,255,255,255,255,255,81,0,0,0, + 7,1,1,1,1,13,13,13,1,0,0,0,6,20,20,20,1,0,0,0, + 14,86,86,86,1,218,218,218,1,205,205,205,1,181,181,181,1,7,7,7, + 1,0,0,0,3,74,74,74,1,239,239,239,1,0,0,0,13,18,18,18, + 1,225,225,225,1,29,29,29,1,0,0,0,1,148,148,148,1,95,95,95, + 1,0,0,0,2,21,21,21,1,210,210,210,1,240,240,240,1,0,0,0, + 13,95,95,95,1,155,155,155,1,11,11,11,1,37,37,37,1,0,0,0, + 4,175,175,175,1,80,80,80,1,240,240,240,1,0,0,0,13,124,124,124, + 1,183,183,183,1,218,218,218,1,199,199,199,1,191,191,191,1,19,19,19, + 1,0,0,0,1,101,101,101,1,142,142,142,1,15,15,15,1,240,240,240, + 1,0,0,0,13,135,135,135,1,225,225,225,1,5,5,5,1,0,0,0, + 1,147,147,147,1,109,109,109,1,36,36,36,1,201,201,201,1,8,8,8, + 1,15,15,15,1,240,240,240,1,0,0,0,13,110,110,110,1,161,161,161, + 1,0,0,0,2,85,85,85,1,174,174,174,1,141,141,141,1,234,234,234, + 1,216,216,216,1,218,218,218,1,253,253,253,1,216,216,216,1,0,0,0, + 12,39,39,39,1,220,220,220,1,15,15,15,1,0,0,0,1,163,163,163, + 1,123,123,123,1,8,8,8,1,16,16,16,2,30,30,30,1,241,241,241, + 1,16,16,16,1,0,0,0,13,108,108,108,1,219,219,219,1,210,210,210, + 1,178,178,178,1,8,8,8,1,0,0,0,3,15,15,15,1,240,240,240, + 1,0,0,0,32,0,0) + ); + +const + objdata_tdbstringlookup64db: record size: integer; data: array[0..1486] of byte end = + (size: 1487; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,100,98, + 115,116,114,105,110,103,108,111,111,107,117,112,54,52,100,98,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,80,5,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,160,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128, + 25,0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 7,176,244,244,1,175,243,243,1,184,255,255,7,174,249,255,1,97,202,255, + 1,18,153,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,7,98,136,136,1,92,127,127,1,184,255,255,5,174,249,255, + 1,97,202,255,1,18,153,255,2,97,202,255,1,174,249,255,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,7,98,136,136, + 1,92,127,127,1,184,255,255,3,174,249,255,1,97,202,255,1,18,153,255, + 2,97,202,255,1,174,249,255,1,184,255,255,2,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,184,255,255,1,151,209,209,1,45,62,62, + 1,26,36,36,1,22,31,31,1,113,156,156,1,184,255,255,1,98,136,136, + 1,63,87,87,1,61,85,85,1,20,29,30,1,50,104,131,1,18,153,255, + 2,66,138,174,1,32,46,47,1,32,45,45,1,89,123,123,1,184,255,255, + 2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 1,63,88,88,1,126,174,174,1,184,255,255,1,145,201,201,1,12,17,17, + 1,184,255,255,1,98,136,136,1,18,26,27,1,84,176,222,1,16,138,230, + 1,2,21,35,1,72,150,189,1,148,212,217,1,14,19,19,1,154,214,214, + 1,181,251,251,1,51,71,71,1,140,194,194,1,184,255,255,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,183,254,254, + 1,141,196,196,1,105,145,145,1,68,94,94,1,0,0,0,1,174,249,255, + 1,52,108,136,1,7,62,104,1,18,153,255,1,97,202,255,1,76,109,112, + 1,89,123,123,1,114,158,158,1,56,78,78,1,184,255,255,5,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,55,76,76, + 2,109,151,151,1,134,192,197,1,0,0,0,1,18,153,255,1,10,82,136, + 1,46,96,121,1,174,249,255,1,184,255,255,1,86,119,119,1,87,121,121, + 1,104,144,144,1,64,89,89,1,184,255,255,2,175,242,242,1,177,245,245, + 1,184,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,179,248,248,1,4,6,6,1,163,233,239,1,97,202,255,1,12,101,168, + 1,0,0,0,1,95,199,251,1,93,133,136,1,38,53,53,1,173,240,240, + 1,177,245,245,1,29,40,40,1,132,183,183,1,144,199,199,1,18,25,25, + 1,175,243,243,1,184,255,255,1,62,86,86,1,123,171,171,1,184,255,255, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,174,249,255, + 1,47,97,123,1,3,29,49,1,5,40,67,1,38,79,100,1,19,27,28, + 1,161,223,223,1,98,136,136,1,59,82,82,1,49,68,68,1,35,48,48, + 1,100,139,139,1,184,255,255,2,107,148,148,1,38,53,53,1,40,56,56, + 1,69,96,96,1,183,254,254,1,184,255,255,1,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,18,153,255,2,94,195,246,1,169,241,247, + 1,184,255,255,5,183,253,253,1,180,249,249,1,184,255,255,4,183,254,254, + 1,178,246,246,1,184,255,255,3,224,224,224,1,255,255,255,1,128,128,128, + 1,224,224,224,22,255,255,255,25,208,208,208,7,0,0,0,2,208,208,208, + 6,0,0,0,1,208,208,208,14,0,0,0,5,208,208,208,3,0,0,0, + 2,208,208,208,13,0,0,0,3,208,208,208,1,0,0,0,2,208,208,208, + 2,0,0,0,3,208,208,208,13,0,0,0,4,208,208,208,4,0,0,0, + 3,208,208,208,13,0,0,0,6,208,208,208,1,0,0,0,4,208,208,208, + 13,0,0,0,3,208,208,208,1,0,0,0,7,208,208,208,13,0,0,0, + 2,208,208,208,2,0,0,0,8,208,208,208,12,0,0,0,3,208,208,208, + 1,0,0,0,8,208,208,208,13,0,0,0,5,208,208,208,3,0,0,0, + 2,208,208,208,32,120,1,0,0,255,255,255,255,255,255,255,81,0,0,0, + 7,1,1,1,1,13,13,13,1,0,0,0,6,20,20,20,1,0,0,0, + 14,86,86,86,1,218,218,218,1,205,205,205,1,181,181,181,1,7,7,7, + 1,0,0,0,3,74,74,74,1,239,239,239,1,0,0,0,13,18,18,18, + 1,225,225,225,1,29,29,29,1,0,0,0,1,148,148,148,1,95,95,95, + 1,0,0,0,2,21,21,21,1,210,210,210,1,240,240,240,1,0,0,0, + 13,95,95,95,1,155,155,155,1,11,11,11,1,37,37,37,1,0,0,0, + 4,175,175,175,1,80,80,80,1,240,240,240,1,0,0,0,13,124,124,124, + 1,183,183,183,1,218,218,218,1,199,199,199,1,191,191,191,1,19,19,19, + 1,0,0,0,1,101,101,101,1,142,142,142,1,15,15,15,1,240,240,240, + 1,0,0,0,13,135,135,135,1,225,225,225,1,5,5,5,1,0,0,0, + 1,147,147,147,1,109,109,109,1,36,36,36,1,201,201,201,1,8,8,8, + 1,15,15,15,1,240,240,240,1,0,0,0,13,110,110,110,1,161,161,161, + 1,0,0,0,2,85,85,85,1,174,174,174,1,141,141,141,1,234,234,234, + 1,216,216,216,1,218,218,218,1,253,253,253,1,216,216,216,1,0,0,0, + 12,39,39,39,1,220,220,220,1,15,15,15,1,0,0,0,1,163,163,163, + 1,123,123,123,1,8,8,8,1,16,16,16,2,30,30,30,1,241,241,241, + 1,16,16,16,1,0,0,0,13,108,108,108,1,219,219,219,1,210,210,210, + 1,178,178,178,1,8,8,8,1,0,0,0,3,15,15,15,1,240,240,240, + 1,0,0,0,32,0,0) + ); + +const + objdata_tdbintegerlookup64lb: record size: integer; data: array[0..1475] of byte end = + (size: 1476; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,20,116,100,98, + 105,110,116,101,103,101,114,108,111,111,107,117,112,54,52,108,98,23,98,105, + 116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111, + 114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110, + 115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111, + 108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103, + 101,10,68,5,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0, + 0,0,148,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128, + 128,25,0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255, + 255,4,168,233,233,1,184,255,255,4,179,248,248,1,182,252,252,1,184,255, + 255,4,182,252,252,1,178,246,246,1,184,255,255,1,188,241,255,1,196,214, + 255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255, + 255,3,103,143,143,1,51,71,71,1,184,255,255,2,181,251,251,1,69,95, + 95,1,35,48,48,1,31,43,43,1,87,121,121,1,184,255,255,2,105,145, + 145,1,34,47,47,1,33,43,45,1,79,86,103,1,198,198,251,1,201,201, + 255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255, + 255,1,175,242,242,1,75,104,104,1,13,18,18,1,51,71,71,1,184,255, + 255,2,118,164,164,1,62,86,86,1,184,255,255,1,180,250,250,1,32,44, + 44,1,147,204,204,1,159,221,221,1,23,29,31,1,190,207,247,1,201,201, + 255,1,43,43,55,1,142,142,180,1,201,201,255,1,224,224,224,1,255,255, + 255,1,128,128,128,1,0,0,0,1,184,255,255,1,142,197,197,1,92,127, + 127,1,126,175,175,1,51,71,71,1,184,255,255,2,154,214,214,1,162,225, + 225,1,184,255,255,2,51,71,71,1,116,149,158,1,196,214,255,1,188,188, + 238,1,201,201,255,1,199,199,252,1,32,32,40,1,143,143,181,1,201,201, + 255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255, + 255,3,132,183,183,1,51,71,71,1,184,255,255,5,137,176,186,1,21,23, + 27,1,187,187,237,1,201,201,255,2,139,139,176,1,19,19,24,1,66,66, + 84,1,201,201,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,184,255,255,3,132,183,183,1,51,71,71,1,184,255,255,3,188,241, + 255,1,135,148,176,1,20,20,26,1,160,160,203,1,201,201,255,3,188,188, + 238,1,163,163,207,1,50,50,63,1,114,114,144,1,201,201,255,1,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,132,183, + 183,1,51,71,71,1,184,255,255,1,188,241,255,1,196,214,255,1,130,130, + 165,1,26,26,33,1,168,168,213,1,201,201,255,2,188,188,238,1,175,175, + 222,1,201,201,255,2,137,137,174,1,49,49,62,1,201,201,255,1,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,132,183, + 183,1,52,67,71,1,196,214,255,1,201,201,255,1,148,148,188,1,31,31, + 39,1,181,181,229,1,201,201,255,3,169,169,214,1,27,27,34,1,197,197, + 250,1,201,201,255,1,81,81,103,1,107,107,136,1,201,201,255,1,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,2,188,241, + 255,1,141,154,183,1,56,56,71,1,201,201,255,2,48,48,61,1,2,2, + 3,1,6,6,7,3,110,110,139,1,201,201,255,1,107,107,136,1,37,37, + 47,1,41,41,52,1,76,76,96,1,188,188,239,1,201,201,255,1,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,188,241,255,1,196,214, + 255,1,201,201,255,13,198,198,251,1,192,192,244,1,201,201,255,3,224,224, + 224,1,255,255,255,1,128,128,128,1,224,224,224,22,255,255,255,25,208,208, + 208,7,0,0,0,2,208,208,208,6,0,0,0,1,208,208,208,14,0,0, + 0,5,208,208,208,3,0,0,0,2,208,208,208,13,0,0,0,3,208,208, + 208,1,0,0,0,2,208,208,208,2,0,0,0,3,208,208,208,13,0,0, + 0,4,208,208,208,4,0,0,0,3,208,208,208,13,0,0,0,6,208,208, + 208,1,0,0,0,4,208,208,208,13,0,0,0,3,208,208,208,1,0,0, + 0,7,208,208,208,13,0,0,0,2,208,208,208,2,0,0,0,8,208,208, + 208,12,0,0,0,3,208,208,208,1,0,0,0,8,208,208,208,13,0,0, + 0,5,208,208,208,3,0,0,0,2,208,208,208,32,120,1,0,0,255,255, + 255,255,255,255,255,81,0,0,0,7,1,1,1,1,13,13,13,1,0,0, + 0,6,20,20,20,1,0,0,0,14,86,86,86,1,218,218,218,1,205,205, + 205,1,181,181,181,1,7,7,7,1,0,0,0,3,74,74,74,1,239,239, + 239,1,0,0,0,13,18,18,18,1,225,225,225,1,29,29,29,1,0,0, + 0,1,148,148,148,1,95,95,95,1,0,0,0,2,21,21,21,1,210,210, + 210,1,240,240,240,1,0,0,0,13,95,95,95,1,155,155,155,1,11,11, + 11,1,37,37,37,1,0,0,0,4,175,175,175,1,80,80,80,1,240,240, + 240,1,0,0,0,13,124,124,124,1,183,183,183,1,218,218,218,1,199,199, + 199,1,191,191,191,1,19,19,19,1,0,0,0,1,101,101,101,1,142,142, + 142,1,15,15,15,1,240,240,240,1,0,0,0,13,135,135,135,1,225,225, + 225,1,5,5,5,1,0,0,0,1,147,147,147,1,109,109,109,1,36,36, + 36,1,201,201,201,1,8,8,8,1,15,15,15,1,240,240,240,1,0,0, + 0,13,110,110,110,1,161,161,161,1,0,0,0,2,85,85,85,1,174,174, + 174,1,141,141,141,1,234,234,234,1,216,216,216,1,218,218,218,1,253,253, + 253,1,216,216,216,1,0,0,0,12,39,39,39,1,220,220,220,1,15,15, + 15,1,0,0,0,1,163,163,163,1,123,123,123,1,8,8,8,1,16,16, + 16,2,30,30,30,1,241,241,241,1,16,16,16,1,0,0,0,13,108,108, + 108,1,219,219,219,1,210,210,210,1,178,178,178,1,8,8,8,1,0,0, + 0,3,15,15,15,1,240,240,240,1,0,0,0,32,0,0) + ); + +const + objdata_tdbintegerlookup64db: record size: integer; data: array[0..1507] of byte end = + (size: 1508; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,20,116,100,98, + 105,110,116,101,103,101,114,108,111,111,107,117,112,54,52,100,98,23,98,105, + 116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111, + 114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110, + 115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111, + 108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103, + 101,10,100,5,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0, + 0,0,180,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128, + 128,25,0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255, + 255,4,168,233,233,1,184,255,255,4,179,248,248,1,182,252,252,1,184,255, + 255,4,182,252,252,1,168,240,246,1,97,202,255,1,18,153,255,2,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,103,143, + 143,1,51,71,71,1,184,255,255,2,181,251,251,1,69,95,95,1,35,48, + 48,1,31,43,43,1,87,121,121,1,184,255,255,2,99,142,145,1,18,37, + 47,1,3,27,45,1,7,62,103,1,95,199,251,1,174,249,255,1,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,175,242, + 242,1,75,104,104,1,13,18,18,1,51,71,71,1,184,255,255,2,118,164, + 164,1,62,86,86,1,184,255,255,1,180,250,250,1,32,44,44,1,139,199, + 204,1,84,175,221,1,2,19,31,1,17,148,247,1,97,202,255,1,38,54, + 55,1,130,180,180,1,184,255,255,1,224,224,224,1,255,255,255,1,128,128, + 128,1,0,0,0,1,184,255,255,1,142,197,197,1,92,127,127,1,126,175, + 175,1,51,71,71,1,184,255,255,2,154,214,214,1,162,225,225,1,184,255, + 255,1,174,249,255,1,27,56,71,1,11,95,158,1,18,153,255,1,91,189, + 238,1,174,249,255,1,182,252,252,1,29,40,40,1,131,181,181,1,184,255, + 255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255, + 255,3,132,183,183,1,51,71,71,1,184,255,255,3,174,249,255,1,97,202, + 255,1,13,112,186,1,2,16,27,1,90,188,237,1,174,249,255,1,184,255, + 255,1,127,176,176,1,17,24,24,1,61,84,84,1,184,255,255,2,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,132,183, + 183,1,51,71,71,1,184,255,255,1,174,249,255,1,97,202,255,1,18,153, + 255,1,12,106,176,1,10,21,26,1,139,198,203,1,184,255,255,3,172,238, + 238,1,149,207,207,1,45,63,63,1,104,144,144,1,184,255,255,1,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,132,183, + 183,1,48,69,71,1,97,202,255,1,18,153,255,2,63,131,165,1,23,32, + 33,1,154,213,213,1,184,255,255,2,172,238,238,1,160,222,222,1,184,255, + 255,2,126,174,174,1,45,62,62,1,184,255,255,1,224,224,224,1,255,255, + 255,1,128,128,128,1,0,0,0,1,184,255,255,2,174,249,255,1,70,145, + 183,1,5,43,71,1,18,153,255,1,97,202,255,1,128,184,188,1,28,39, + 39,1,165,229,229,1,184,255,255,3,154,214,214,1,25,34,34,1,180,250, + 250,1,184,255,255,1,74,103,103,1,98,136,136,1,184,255,255,1,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,174,249,255,1,97,202, + 255,1,18,153,255,1,13,110,183,1,27,56,71,1,174,249,255,1,184,255, + 255,1,44,61,61,1,2,3,3,1,5,7,7,3,100,139,139,1,184,255, + 255,1,98,136,136,1,34,47,47,1,38,52,52,1,69,96,96,1,172,239, + 239,1,184,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,18,153,255,2,97,202,255,1,174,249,255,1,184,255,255,11,181,251, + 251,1,176,244,244,1,184,255,255,3,224,224,224,1,255,255,255,1,128,128, + 128,1,224,224,224,22,255,255,255,25,208,208,208,7,0,0,0,2,208,208, + 208,6,0,0,0,1,208,208,208,14,0,0,0,5,208,208,208,3,0,0, + 0,2,208,208,208,13,0,0,0,3,208,208,208,1,0,0,0,2,208,208, + 208,2,0,0,0,3,208,208,208,13,0,0,0,4,208,208,208,4,0,0, + 0,3,208,208,208,13,0,0,0,6,208,208,208,1,0,0,0,4,208,208, + 208,13,0,0,0,3,208,208,208,1,0,0,0,7,208,208,208,13,0,0, + 0,2,208,208,208,2,0,0,0,8,208,208,208,12,0,0,0,3,208,208, + 208,1,0,0,0,8,208,208,208,13,0,0,0,5,208,208,208,3,0,0, + 0,2,208,208,208,32,120,1,0,0,255,255,255,255,255,255,255,81,0,0, + 0,7,1,1,1,1,13,13,13,1,0,0,0,6,20,20,20,1,0,0, + 0,14,86,86,86,1,218,218,218,1,205,205,205,1,181,181,181,1,7,7, + 7,1,0,0,0,3,74,74,74,1,239,239,239,1,0,0,0,13,18,18, + 18,1,225,225,225,1,29,29,29,1,0,0,0,1,148,148,148,1,95,95, + 95,1,0,0,0,2,21,21,21,1,210,210,210,1,240,240,240,1,0,0, + 0,13,95,95,95,1,155,155,155,1,11,11,11,1,37,37,37,1,0,0, + 0,4,175,175,175,1,80,80,80,1,240,240,240,1,0,0,0,13,124,124, + 124,1,183,183,183,1,218,218,218,1,199,199,199,1,191,191,191,1,19,19, + 19,1,0,0,0,1,101,101,101,1,142,142,142,1,15,15,15,1,240,240, + 240,1,0,0,0,13,135,135,135,1,225,225,225,1,5,5,5,1,0,0, + 0,1,147,147,147,1,109,109,109,1,36,36,36,1,201,201,201,1,8,8, + 8,1,15,15,15,1,240,240,240,1,0,0,0,13,110,110,110,1,161,161, + 161,1,0,0,0,2,85,85,85,1,174,174,174,1,141,141,141,1,234,234, + 234,1,216,216,216,1,218,218,218,1,253,253,253,1,216,216,216,1,0,0, + 0,12,39,39,39,1,220,220,220,1,15,15,15,1,0,0,0,1,163,163, + 163,1,123,123,123,1,8,8,8,1,16,16,16,2,30,30,30,1,241,241, + 241,1,16,16,16,1,0,0,0,13,108,108,108,1,219,219,219,1,210,210, + 210,1,178,178,178,1,8,8,8,1,0,0,0,3,15,15,15,1,240,240, + 240,1,0,0,0,32,0,0) + ); + +const + objdata_tdbreallookup64lb: record size: integer; data: array[0..1388] of byte end = + (size: 1389; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,100,98, + 114,101,97,108,108,111,111,107,117,112,54,52,108,98,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,240, + 4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,64, + 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,0, + 0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,168, + 233,233,1,184,255,255,7,182,252,252,1,179,248,248,1,184,255,255,5,181, + 232,246,1,186,203,242,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,184,255,255,2,103,143,143,1,51,71,71,1,184,255,255,6,84, + 116,116,1,33,46,46,1,32,45,45,1,72,100,100,1,181,251,251,1,184, + 255,255,1,188,241,255,1,194,211,252,1,54,54,69,1,117,117,149,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,175,242,242,1,75, + 104,104,1,13,18,18,1,51,71,71,1,184,255,255,5,142,197,197,1,40, + 55,55,1,182,252,252,1,183,254,254,1,54,75,75,1,125,161,170,1,196, + 214,255,1,169,169,214,1,45,45,57,1,13,13,17,1,117,117,149,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,142,197,197,1,92, + 127,127,1,126,175,175,1,51,71,71,1,184,255,255,5,162,224,224,1,155, + 215,215,1,184,255,255,1,188,241,255,1,81,88,105,1,98,98,124,1,201, + 201,255,1,114,114,145,1,135,135,171,1,84,84,106,1,117,117,149,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,2,132, + 183,183,1,51,71,71,1,184,255,255,6,188,241,255,1,196,214,255,1,164, + 164,208,1,19,19,24,1,172,172,218,1,201,201,255,3,84,84,106,1,117, + 117,149,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184, + 255,255,2,132,183,183,1,51,71,71,1,184,255,255,4,188,241,255,1,196, + 214,255,1,201,201,255,1,158,158,200,1,20,20,26,1,142,142,180,1,201, + 201,255,4,84,84,106,1,117,117,149,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,184,255,255,2,132,183,183,1,51,71,71,1,184, + 255,255,2,188,241,255,1,196,214,255,1,201,201,255,2,151,151,191,1,22, + 22,28,1,151,151,192,1,201,201,255,5,84,84,106,1,117,117,149,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,2,132, + 183,183,1,51,71,71,1,188,241,255,1,196,214,255,1,197,197,250,1,177, + 177,225,1,201,201,255,1,169,169,215,1,22,22,28,1,168,168,213,1,201, + 201,255,6,84,84,106,1,117,117,149,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,184,255,255,2,135,173,183,1,55,60,71,1,201, + 201,255,2,164,164,208,1,12,12,15,1,201,201,255,1,74,74,94,1,2, + 2,2,1,6,6,7,3,84,84,106,1,201,201,255,3,84,84,106,1,117, + 117,149,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,188, + 241,255,1,196,214,255,1,201,201,255,18,224,224,224,1,255,255,255,1,128, + 128,128,1,224,224,224,22,255,255,255,25,208,208,208,7,0,0,0,2,208, + 208,208,6,0,0,0,1,208,208,208,14,0,0,0,5,208,208,208,3,0, + 0,0,2,208,208,208,13,0,0,0,3,208,208,208,1,0,0,0,2,208, + 208,208,2,0,0,0,3,208,208,208,13,0,0,0,4,208,208,208,4,0, + 0,0,3,208,208,208,13,0,0,0,6,208,208,208,1,0,0,0,4,208, + 208,208,13,0,0,0,3,208,208,208,1,0,0,0,7,208,208,208,13,0, + 0,0,2,208,208,208,2,0,0,0,8,208,208,208,12,0,0,0,3,208, + 208,208,1,0,0,0,8,208,208,208,13,0,0,0,5,208,208,208,3,0, + 0,0,2,208,208,208,32,120,1,0,0,255,255,255,255,255,255,255,81,0, + 0,0,7,1,1,1,1,13,13,13,1,0,0,0,6,20,20,20,1,0, + 0,0,14,86,86,86,1,218,218,218,1,205,205,205,1,181,181,181,1,7, + 7,7,1,0,0,0,3,74,74,74,1,239,239,239,1,0,0,0,13,18, + 18,18,1,225,225,225,1,29,29,29,1,0,0,0,1,148,148,148,1,95, + 95,95,1,0,0,0,2,21,21,21,1,210,210,210,1,240,240,240,1,0, + 0,0,13,95,95,95,1,155,155,155,1,11,11,11,1,37,37,37,1,0, + 0,0,4,175,175,175,1,80,80,80,1,240,240,240,1,0,0,0,13,124, + 124,124,1,183,183,183,1,218,218,218,1,199,199,199,1,191,191,191,1,19, + 19,19,1,0,0,0,1,101,101,101,1,142,142,142,1,15,15,15,1,240, + 240,240,1,0,0,0,13,135,135,135,1,225,225,225,1,5,5,5,1,0, + 0,0,1,147,147,147,1,109,109,109,1,36,36,36,1,201,201,201,1,8, + 8,8,1,15,15,15,1,240,240,240,1,0,0,0,13,110,110,110,1,161, + 161,161,1,0,0,0,2,85,85,85,1,174,174,174,1,141,141,141,1,234, + 234,234,1,216,216,216,1,218,218,218,1,253,253,253,1,216,216,216,1,0, + 0,0,12,39,39,39,1,220,220,220,1,15,15,15,1,0,0,0,1,163, + 163,163,1,123,123,123,1,8,8,8,1,16,16,16,2,30,30,30,1,241, + 241,241,1,16,16,16,1,0,0,0,13,108,108,108,1,219,219,219,1,210, + 210,210,1,178,178,178,1,8,8,8,1,0,0,0,3,15,15,15,1,240, + 240,240,1,0,0,0,32,0,0) + ); + +const + objdata_tdbreallookup64db: record size: integer; data: array[0..1416] of byte end = + (size: 1417; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,100,98, + 114,101,97,108,108,111,111,107,117,112,54,52,100,98,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,12, + 5,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,92, + 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,0, + 0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,168, + 233,233,1,184,255,255,7,182,252,252,1,179,248,248,1,184,255,255,3,174, + 249,255,1,97,202,255,1,17,148,246,1,17,145,242,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,184,255,255,2,103,143,143,1,51, + 71,71,1,184,255,255,6,84,116,116,1,33,46,46,1,32,45,45,1,72, + 100,100,1,171,245,251,1,97,202,255,1,18,153,255,1,18,151,252,1,26, + 55,69,1,102,145,149,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,175,242,242,1,75,104,104,1,13,18,18,1,51,71,71,1,184, + 255,255,5,142,197,197,1,40,55,55,1,182,252,252,1,173,248,254,1,29, + 59,75,1,12,102,170,1,18,153,255,1,81,170,214,1,39,56,57,1,12, + 17,17,1,108,149,149,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,142,197,197,1,92,127,127,1,126,175,175,1,51,71,71,1,184, + 255,255,5,162,224,224,1,147,210,215,1,97,202,255,1,18,153,255,1,7, + 63,105,1,47,98,124,1,174,249,255,1,105,145,145,1,123,171,171,1,76, + 106,106,1,108,149,149,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,184,255,255,2,132,183,183,1,51,71,71,1,184,255,255,4,174, + 249,255,1,97,202,255,1,18,153,255,2,79,165,208,1,16,23,24,1,157, + 218,218,1,184,255,255,3,76,106,106,1,108,149,149,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,184,255,255,2,132,183,183,1,51, + 71,71,1,184,255,255,2,174,249,255,1,97,202,255,1,18,153,255,2,97, + 202,255,1,136,195,200,1,19,26,26,1,130,180,180,1,184,255,255,4,76, + 106,106,1,108,149,149,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,184,255,255,2,132,183,183,1,51,71,71,1,174,249,255,1,97, + 202,255,1,18,153,255,2,97,202,255,1,174,249,255,1,138,191,191,1,20, + 28,28,1,139,192,192,1,184,255,255,5,76,106,106,1,108,149,149,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,2,125, + 179,183,1,27,56,71,1,18,153,255,2,95,198,250,1,154,220,225,1,184, + 255,255,1,155,215,215,1,20,28,28,1,154,213,213,1,184,255,255,6,76, + 106,106,1,108,149,149,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,174,249,255,1,97,202,255,1,13,110,183,1,5,43,71,1,97, + 202,255,1,174,249,255,1,150,208,208,1,11,15,15,1,184,255,255,1,68, + 94,94,1,1,2,2,1,5,7,7,3,76,106,106,1,184,255,255,3,76, + 106,106,1,108,149,149,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,18,153,255,2,97,202,255,1,174,249,255,1,184,255,255,16,224, + 224,224,1,255,255,255,1,128,128,128,1,224,224,224,22,255,255,255,25,208, + 208,208,7,0,0,0,2,208,208,208,6,0,0,0,1,208,208,208,14,0, + 0,0,5,208,208,208,3,0,0,0,2,208,208,208,13,0,0,0,3,208, + 208,208,1,0,0,0,2,208,208,208,2,0,0,0,3,208,208,208,13,0, + 0,0,4,208,208,208,4,0,0,0,3,208,208,208,13,0,0,0,6,208, + 208,208,1,0,0,0,4,208,208,208,13,0,0,0,3,208,208,208,1,0, + 0,0,7,208,208,208,13,0,0,0,2,208,208,208,2,0,0,0,8,208, + 208,208,12,0,0,0,3,208,208,208,1,0,0,0,8,208,208,208,13,0, + 0,0,5,208,208,208,3,0,0,0,2,208,208,208,32,120,1,0,0,255, + 255,255,255,255,255,255,81,0,0,0,7,1,1,1,1,13,13,13,1,0, + 0,0,6,20,20,20,1,0,0,0,14,86,86,86,1,218,218,218,1,205, + 205,205,1,181,181,181,1,7,7,7,1,0,0,0,3,74,74,74,1,239, + 239,239,1,0,0,0,13,18,18,18,1,225,225,225,1,29,29,29,1,0, + 0,0,1,148,148,148,1,95,95,95,1,0,0,0,2,21,21,21,1,210, + 210,210,1,240,240,240,1,0,0,0,13,95,95,95,1,155,155,155,1,11, + 11,11,1,37,37,37,1,0,0,0,4,175,175,175,1,80,80,80,1,240, + 240,240,1,0,0,0,13,124,124,124,1,183,183,183,1,218,218,218,1,199, + 199,199,1,191,191,191,1,19,19,19,1,0,0,0,1,101,101,101,1,142, + 142,142,1,15,15,15,1,240,240,240,1,0,0,0,13,135,135,135,1,225, + 225,225,1,5,5,5,1,0,0,0,1,147,147,147,1,109,109,109,1,36, + 36,36,1,201,201,201,1,8,8,8,1,15,15,15,1,240,240,240,1,0, + 0,0,13,110,110,110,1,161,161,161,1,0,0,0,2,85,85,85,1,174, + 174,174,1,141,141,141,1,234,234,234,1,216,216,216,1,218,218,218,1,253, + 253,253,1,216,216,216,1,0,0,0,12,39,39,39,1,220,220,220,1,15, + 15,15,1,0,0,0,1,163,163,163,1,123,123,123,1,8,8,8,1,16, + 16,16,2,30,30,30,1,241,241,241,1,16,16,16,1,0,0,0,13,108, + 108,108,1,219,219,219,1,210,210,210,1,178,178,178,1,8,8,8,1,0, + 0,0,3,15,15,15,1,240,240,240,1,0,0,0,32,0,0) + ); + +const + objdata_tdbdatetimelookup64lb: record size: integer; data: array[0..1388] of byte end = + (size: 1389; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,21,116,100,98, + 100,97,116,101,116,105,109,101,108,111,111,107,117,112,54,52,108,98,23,98, + 105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108, + 111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111, + 110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99, + 111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97, + 103,101,10,236,4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24, + 0,0,0,60,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128, + 128,128,25,0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184, + 255,255,1,179,248,248,1,167,231,231,2,170,235,235,1,182,252,252,1,184, + 255,255,6,173,240,240,1,167,231,231,5,175,224,237,1,196,214,255,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,127, + 176,176,1,5,7,7,1,22,31,31,1,19,27,27,1,5,7,7,1,60, + 83,83,1,168,233,233,1,184,255,255,4,80,111,111,1,22,31,31,2,1, + 1,1,1,21,26,28,1,24,26,31,1,67,67,85,1,201,201,255,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,127, + 176,176,1,45,63,63,1,184,255,255,2,180,250,250,1,66,92,92,1,56, + 78,78,1,184,255,255,6,188,241,255,1,8,8,10,1,181,181,229,1,201, + 201,255,3,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184, + 255,255,1,127,176,176,1,45,63,63,1,184,255,255,3,175,242,242,1,1, + 2,2,1,162,224,224,1,184,255,255,1,29,40,40,1,165,228,228,1,188, + 241,255,1,196,214,255,1,201,201,255,1,8,8,10,1,181,181,229,1,201, + 201,255,3,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184, + 255,255,1,127,176,176,1,45,63,63,1,184,255,255,4,30,42,42,1,128, + 178,178,1,184,255,255,1,136,174,184,1,189,206,246,1,201,201,255,3,8, + 8,10,1,181,181,229,1,201,201,255,3,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,184,255,255,1,127,176,176,1,45,63,63,1,184, + 255,255,4,31,43,43,1,132,169,179,1,196,214,255,1,201,201,255,5,8, + 8,10,1,181,181,229,1,201,201,255,3,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,184,255,255,1,127,176,176,1,45,63,63,1,184, + 255,255,3,177,227,240,1,7,8,9,1,174,174,221,1,201,201,255,6,8, + 8,10,1,181,181,229,1,201,201,255,3,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,184,255,255,1,127,176,176,1,45,63,63,1,184, + 255,255,1,188,241,255,1,178,195,232,1,69,69,88,1,64,64,81,1,201, + 201,255,2,177,177,224,1,198,198,251,1,201,201,255,3,8,8,10,1,181, + 181,229,1,201,201,255,3,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,184,255,255,1,127,176,176,1,1,1,1,1,5,6,7,1,6, + 6,7,1,17,17,22,1,78,78,99,1,192,192,243,1,201,201,255,2,1, + 1,1,1,175,175,222,1,201,201,255,3,8,8,10,1,181,181,229,1,201, + 201,255,3,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,188, + 241,255,1,196,214,255,1,201,201,255,18,224,224,224,1,255,255,255,1,128, + 128,128,1,224,224,224,22,255,255,255,25,208,208,208,7,0,0,0,2,208, + 208,208,6,0,0,0,1,208,208,208,14,0,0,0,5,208,208,208,3,0, + 0,0,2,208,208,208,13,0,0,0,3,208,208,208,1,0,0,0,2,208, + 208,208,2,0,0,0,3,208,208,208,13,0,0,0,4,208,208,208,4,0, + 0,0,3,208,208,208,13,0,0,0,6,208,208,208,1,0,0,0,4,208, + 208,208,13,0,0,0,3,208,208,208,1,0,0,0,7,208,208,208,13,0, + 0,0,2,208,208,208,2,0,0,0,8,208,208,208,12,0,0,0,3,208, + 208,208,1,0,0,0,8,208,208,208,13,0,0,0,5,208,208,208,3,0, + 0,0,2,208,208,208,32,120,1,0,0,255,255,255,255,255,255,255,81,0, + 0,0,7,1,1,1,1,13,13,13,1,0,0,0,6,20,20,20,1,0, + 0,0,14,86,86,86,1,218,218,218,1,205,205,205,1,181,181,181,1,7, + 7,7,1,0,0,0,3,74,74,74,1,239,239,239,1,0,0,0,13,18, + 18,18,1,225,225,225,1,29,29,29,1,0,0,0,1,148,148,148,1,95, + 95,95,1,0,0,0,2,21,21,21,1,210,210,210,1,240,240,240,1,0, + 0,0,13,95,95,95,1,155,155,155,1,11,11,11,1,37,37,37,1,0, + 0,0,4,175,175,175,1,80,80,80,1,240,240,240,1,0,0,0,13,124, + 124,124,1,183,183,183,1,218,218,218,1,199,199,199,1,191,191,191,1,19, + 19,19,1,0,0,0,1,101,101,101,1,142,142,142,1,15,15,15,1,240, + 240,240,1,0,0,0,13,135,135,135,1,225,225,225,1,5,5,5,1,0, + 0,0,1,147,147,147,1,109,109,109,1,36,36,36,1,201,201,201,1,8, + 8,8,1,15,15,15,1,240,240,240,1,0,0,0,13,110,110,110,1,161, + 161,161,1,0,0,0,2,85,85,85,1,174,174,174,1,141,141,141,1,234, + 234,234,1,216,216,216,1,218,218,218,1,253,253,253,1,216,216,216,1,0, + 0,0,12,39,39,39,1,220,220,220,1,15,15,15,1,0,0,0,1,163, + 163,163,1,123,123,123,1,8,8,8,1,16,16,16,2,30,30,30,1,241, + 241,241,1,16,16,16,1,0,0,0,13,108,108,108,1,219,219,219,1,210, + 210,210,1,178,178,178,1,8,8,8,1,0,0,0,3,15,15,15,1,240, + 240,240,1,0,0,0,32,0,0) + ); + +const + objdata_tdbdatetimelookup64db: record size: integer; data: array[0..1444] of byte end = + (size: 1445; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,21,116,100,98, + 100,97,116,101,116,105,109,101,108,111,111,107,117,112,54,52,100,98,23,98, + 105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108, + 111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111, + 110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99, + 111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97, + 103,101,10,36,5,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24, + 0,0,0,116,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128, + 128,128,25,0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184, + 255,255,1,179,248,248,1,167,231,231,2,170,235,235,1,182,252,252,1,184, + 255,255,6,173,240,240,1,167,231,231,3,158,226,231,1,88,183,231,1,17, + 142,237,1,18,153,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,184,255,255,1,127,176,176,1,5,7,7,1,22,31,31,1,19, + 27,27,1,5,7,7,1,60,83,83,1,168,233,233,1,184,255,255,4,80, + 111,111,1,22,31,31,1,21,30,31,1,0,1,1,1,2,17,28,1,2, + 19,31,1,32,67,85,1,174,249,255,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,184,255,255,1,127,176,176,1,45,63,63,1,184, + 255,255,2,180,250,250,1,66,92,92,1,56,78,78,1,184,255,255,4,174, + 249,255,1,97,202,255,1,18,153,255,1,1,6,10,1,87,181,229,1,174, + 249,255,1,184,255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,184,255,255,1,127,176,176,1,45,63,63,1,184,255,255,3,175, + 242,242,1,1,2,2,1,162,224,224,1,184,255,255,1,27,39,40,1,87, + 181,228,1,18,153,255,2,97,202,255,1,7,10,10,1,165,229,229,1,184, + 255,255,3,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184, + 255,255,1,127,176,176,1,45,63,63,1,184,255,255,4,30,42,42,1,121, + 174,178,1,97,202,255,1,13,110,184,1,17,148,246,1,97,202,255,1,174, + 249,255,1,184,255,255,1,7,10,10,1,165,229,229,1,184,255,255,3,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,127, + 176,176,1,45,63,63,1,184,255,255,3,174,249,255,1,16,34,43,1,13, + 107,179,1,18,153,255,1,97,202,255,1,174,249,255,1,184,255,255,3,7, + 10,10,1,165,229,229,1,184,255,255,3,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,184,255,255,1,127,176,176,1,45,63,63,1,184, + 255,255,1,174,249,255,1,97,202,255,1,17,144,240,1,1,5,9,1,84, + 175,221,1,174,249,255,1,184,255,255,5,7,10,10,1,165,229,229,1,184, + 255,255,3,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184, + 255,255,1,127,176,176,1,43,62,63,1,97,202,255,1,18,153,255,1,16, + 139,232,1,33,70,88,1,55,79,81,1,184,255,255,2,162,224,224,1,181, + 251,251,1,184,255,255,3,7,10,10,1,165,229,229,1,184,255,255,3,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,174,249,255,1,67, + 139,176,1,0,1,1,1,0,4,7,1,3,6,7,1,15,21,22,1,71, + 99,99,1,175,243,243,1,184,255,255,2,1,1,1,1,160,222,222,1,184, + 255,255,3,7,10,10,1,165,229,229,1,184,255,255,3,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,18,153,255,2,97,202,255,1,174, + 249,255,1,184,255,255,16,224,224,224,1,255,255,255,1,128,128,128,1,224, + 224,224,22,255,255,255,25,208,208,208,7,0,0,0,2,208,208,208,6,0, + 0,0,1,208,208,208,14,0,0,0,5,208,208,208,3,0,0,0,2,208, + 208,208,13,0,0,0,3,208,208,208,1,0,0,0,2,208,208,208,2,0, + 0,0,3,208,208,208,13,0,0,0,4,208,208,208,4,0,0,0,3,208, + 208,208,13,0,0,0,6,208,208,208,1,0,0,0,4,208,208,208,13,0, + 0,0,3,208,208,208,1,0,0,0,7,208,208,208,13,0,0,0,2,208, + 208,208,2,0,0,0,8,208,208,208,12,0,0,0,3,208,208,208,1,0, + 0,0,8,208,208,208,13,0,0,0,5,208,208,208,3,0,0,0,2,208, + 208,208,32,120,1,0,0,255,255,255,255,255,255,255,81,0,0,0,7,1, + 1,1,1,13,13,13,1,0,0,0,6,20,20,20,1,0,0,0,14,86, + 86,86,1,218,218,218,1,205,205,205,1,181,181,181,1,7,7,7,1,0, + 0,0,3,74,74,74,1,239,239,239,1,0,0,0,13,18,18,18,1,225, + 225,225,1,29,29,29,1,0,0,0,1,148,148,148,1,95,95,95,1,0, + 0,0,2,21,21,21,1,210,210,210,1,240,240,240,1,0,0,0,13,95, + 95,95,1,155,155,155,1,11,11,11,1,37,37,37,1,0,0,0,4,175, + 175,175,1,80,80,80,1,240,240,240,1,0,0,0,13,124,124,124,1,183, + 183,183,1,218,218,218,1,199,199,199,1,191,191,191,1,19,19,19,1,0, + 0,0,1,101,101,101,1,142,142,142,1,15,15,15,1,240,240,240,1,0, + 0,0,13,135,135,135,1,225,225,225,1,5,5,5,1,0,0,0,1,147, + 147,147,1,109,109,109,1,36,36,36,1,201,201,201,1,8,8,8,1,15, + 15,15,1,240,240,240,1,0,0,0,13,110,110,110,1,161,161,161,1,0, + 0,0,2,85,85,85,1,174,174,174,1,141,141,141,1,234,234,234,1,216, + 216,216,1,218,218,218,1,253,253,253,1,216,216,216,1,0,0,0,12,39, + 39,39,1,220,220,220,1,15,15,15,1,0,0,0,1,163,163,163,1,123, + 123,123,1,8,8,8,1,16,16,16,2,30,30,30,1,241,241,241,1,16, + 16,16,1,0,0,0,13,108,108,108,1,219,219,219,1,210,210,210,1,178, + 178,178,1,8,8,8,1,0,0,0,3,15,15,15,1,240,240,240,1,0, + 0,0,32,0,0) + ); + +const + objdata_tdbstringlookupstrlb: record size: integer; data: array[0..1411] of byte end = + (size: 1412; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,20,116,100,98, + 115,116,114,105,110,103,108,111,111,107,117,112,115,116,114,108,98,23,98,105, + 116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111, + 114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110, + 115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111, + 108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103, + 101,10,4,5,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0, + 0,0,124,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128, + 128,25,0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255, + 255,7,176,244,244,1,175,243,243,1,184,255,255,9,188,241,255,1,196,214, + 255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255, + 255,7,98,136,136,1,92,127,127,1,184,255,255,7,188,241,255,1,196,214, + 255,1,201,201,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,184,255,255,7,98,136,136,1,92,127,127,1,184,255,255,5,188,241, + 255,1,196,214,255,1,201,201,255,4,224,224,224,1,255,255,255,1,128,128, + 128,1,0,0,0,1,184,255,255,1,151,209,209,1,45,62,62,1,26,36, + 36,1,22,31,31,1,113,156,156,1,184,255,255,1,98,136,136,1,63,87, + 87,1,61,85,85,1,22,30,30,1,95,131,131,1,188,241,255,1,196,214, + 255,1,137,137,174,1,37,37,47,1,35,35,45,1,97,97,123,1,201,201, + 255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255, + 255,1,63,88,88,1,126,174,174,1,184,255,255,1,145,201,201,1,12,17, + 17,1,184,255,255,1,98,136,136,1,19,27,27,1,160,222,222,1,170,217, + 230,1,27,29,35,1,149,149,189,1,171,171,217,1,15,15,19,1,169,169, + 214,1,198,198,251,1,56,56,71,1,153,153,194,1,201,201,255,1,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,183,254, + 254,1,141,196,196,1,105,145,145,1,68,94,94,1,0,0,0,1,184,255, + 255,1,98,136,136,1,77,98,104,1,196,214,255,1,201,201,255,1,88,88, + 112,1,97,97,123,1,125,125,158,1,61,61,78,1,201,201,255,5,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,55,76, + 76,2,109,151,151,1,142,197,197,1,0,0,0,1,188,241,255,1,105,114, + 136,1,95,95,121,1,201,201,255,2,94,94,119,1,95,95,121,1,114,114, + 144,1,70,70,89,1,201,201,255,2,191,191,242,1,193,193,245,1,201,201, + 255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,179,248, + 248,1,4,6,6,1,172,239,239,1,184,255,255,1,124,159,168,1,0,0, + 0,1,198,198,251,1,107,107,136,1,42,42,53,1,189,189,240,1,193,193, + 245,1,32,32,40,1,144,144,183,1,157,157,199,1,20,20,25,1,192,192, + 243,1,201,201,255,1,68,68,86,1,135,135,171,1,201,201,255,1,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,89,123, + 123,1,36,46,49,1,51,56,67,1,79,79,100,1,22,22,28,1,176,176, + 223,1,107,107,136,1,65,65,82,1,54,54,68,1,38,38,48,1,110,110, + 139,1,201,201,255,2,117,117,148,1,42,42,53,1,44,44,56,1,76,76, + 96,1,200,200,254,1,201,201,255,1,224,224,224,1,255,255,255,1,128,128, + 128,1,0,0,0,1,188,241,255,1,196,214,255,1,194,194,246,1,195,195, + 247,1,201,201,255,5,199,199,253,1,196,196,249,1,201,201,255,4,200,200, + 254,1,194,194,246,1,201,201,255,3,224,224,224,1,255,255,255,1,128,128, + 128,1,224,224,224,22,255,255,255,25,208,208,208,35,0,0,0,2,208,208, + 208,22,0,0,0,2,208,208,208,16,0,0,0,13,208,208,208,11,0,0, + 0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,4,208,208,208,11,0,0,0,5,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,2,208,208,208,14,0,0,0,7,208,208, + 208,1,0,0,0,2,208,208,208,13,0,0,0,2,208,208,208,1,0,0, + 0,5,208,208,208,1,0,0,0,2,208,208,208,13,0,0,0,5,208,208, + 208,1,0,0,0,5,208,208,208,32,80,1,0,0,255,255,255,255,255,255, + 255,81,0,0,0,35,45,45,45,1,105,105,105,1,0,0,0,22,104,104, + 104,1,143,143,143,1,0,0,0,16,15,15,15,1,182,182,182,1,223,223, + 223,1,213,213,213,1,84,84,84,1,30,30,30,1,218,218,218,1,227,227, + 227,1,107,107,107,1,106,106,106,1,141,141,141,1,231,231,231,1,116,116, + 116,1,0,0,0,11,106,106,106,1,156,156,156,1,0,0,0,1,41,41, + 41,1,165,165,165,1,0,0,0,1,104,104,104,1,143,143,143,1,0,0, + 0,1,126,126,126,1,219,219,219,1,32,32,32,1,20,20,20,1,0,0, + 0,11,50,50,50,1,235,235,235,1,169,169,169,1,91,91,91,1,13,13, + 13,1,0,0,0,1,104,104,104,1,143,143,143,1,0,0,0,1,126,126, + 126,1,147,147,147,1,0,0,0,14,21,21,21,1,103,103,103,1,185,185, + 185,1,223,223,223,1,9,9,9,1,104,104,104,1,143,143,143,1,0,0, + 0,1,126,126,126,1,129,129,129,1,0,0,0,13,93,93,93,1,130,130, + 130,1,0,0,0,1,4,4,4,1,236,236,236,1,33,33,33,1,97,97, + 97,1,151,151,151,1,0,0,0,1,126,126,126,1,129,129,129,1,0,0, + 0,13,14,14,14,1,191,191,191,1,199,199,199,1,218,218,218,1,143,143, + 143,1,0,0,0,1,47,47,47,1,237,237,237,1,140,140,140,1,126,126, + 126,1,129,129,129,1,0,0,0,32,0,0) + ); + +const + objdata_tdbstringlookupstrdb: record size: integer; data: array[0..1431] of byte end = + (size: 1432; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,20,116,100,98, + 115,116,114,105,110,103,108,111,111,107,117,112,115,116,114,100,98,23,98,105, + 116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111, + 114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110, + 115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111, + 108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103, + 101,10,24,5,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0, + 0,0,144,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128, + 128,25,0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255, + 255,7,176,244,244,1,175,243,243,1,184,255,255,7,174,249,255,1,97,202, + 255,1,18,153,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,184,255,255,7,98,136,136,1,92,127,127,1,184,255,255,5,174,249, + 255,1,97,202,255,1,18,153,255,2,97,202,255,1,174,249,255,1,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,7,98,136, + 136,1,92,127,127,1,184,255,255,3,174,249,255,1,97,202,255,1,18,153, + 255,2,97,202,255,1,174,249,255,1,184,255,255,2,224,224,224,1,255,255, + 255,1,128,128,128,1,0,0,0,1,184,255,255,1,151,209,209,1,45,62, + 62,1,26,36,36,1,22,31,31,1,113,156,156,1,184,255,255,1,98,136, + 136,1,63,87,87,1,61,85,85,1,20,29,30,1,50,104,131,1,18,153, + 255,2,66,138,174,1,32,46,47,1,32,45,45,1,89,123,123,1,184,255, + 255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255, + 255,1,63,88,88,1,126,174,174,1,184,255,255,1,145,201,201,1,12,17, + 17,1,184,255,255,1,98,136,136,1,18,26,27,1,84,176,222,1,16,138, + 230,1,2,21,35,1,72,150,189,1,148,212,217,1,14,19,19,1,154,214, + 214,1,181,251,251,1,51,71,71,1,140,194,194,1,184,255,255,1,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,183,254, + 254,1,141,196,196,1,105,145,145,1,68,94,94,1,0,0,0,1,174,249, + 255,1,52,108,136,1,7,62,104,1,18,153,255,1,97,202,255,1,76,109, + 112,1,89,123,123,1,114,158,158,1,56,78,78,1,184,255,255,5,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,55,76, + 76,2,109,151,151,1,134,192,197,1,0,0,0,1,18,153,255,1,10,82, + 136,1,46,96,121,1,174,249,255,1,184,255,255,1,86,119,119,1,87,121, + 121,1,104,144,144,1,64,89,89,1,184,255,255,2,175,242,242,1,177,245, + 245,1,184,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,179,248,248,1,4,6,6,1,163,233,239,1,97,202,255,1,12,101, + 168,1,0,0,0,1,95,199,251,1,93,133,136,1,38,53,53,1,173,240, + 240,1,177,245,245,1,29,40,40,1,132,183,183,1,144,199,199,1,18,25, + 25,1,175,243,243,1,184,255,255,1,62,86,86,1,123,171,171,1,184,255, + 255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,174,249, + 255,1,47,97,123,1,3,29,49,1,5,40,67,1,38,79,100,1,19,27, + 28,1,161,223,223,1,98,136,136,1,59,82,82,1,49,68,68,1,35,48, + 48,1,100,139,139,1,184,255,255,2,107,148,148,1,38,53,53,1,40,56, + 56,1,69,96,96,1,183,254,254,1,184,255,255,1,224,224,224,1,255,255, + 255,1,128,128,128,1,0,0,0,1,18,153,255,2,94,195,246,1,169,241, + 247,1,184,255,255,5,183,253,253,1,180,249,249,1,184,255,255,4,183,254, + 254,1,178,246,246,1,184,255,255,3,224,224,224,1,255,255,255,1,128,128, + 128,1,224,224,224,22,255,255,255,25,208,208,208,35,0,0,0,2,208,208, + 208,22,0,0,0,2,208,208,208,16,0,0,0,13,208,208,208,11,0,0, + 0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,4,208,208,208,11,0,0,0,5,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,2,208,208,208,14,0,0,0,7,208,208, + 208,1,0,0,0,2,208,208,208,13,0,0,0,2,208,208,208,1,0,0, + 0,5,208,208,208,1,0,0,0,2,208,208,208,13,0,0,0,5,208,208, + 208,1,0,0,0,5,208,208,208,32,80,1,0,0,255,255,255,255,255,255, + 255,81,0,0,0,35,45,45,45,1,105,105,105,1,0,0,0,22,104,104, + 104,1,143,143,143,1,0,0,0,16,15,15,15,1,182,182,182,1,223,223, + 223,1,213,213,213,1,84,84,84,1,30,30,30,1,218,218,218,1,227,227, + 227,1,107,107,107,1,106,106,106,1,141,141,141,1,231,231,231,1,116,116, + 116,1,0,0,0,11,106,106,106,1,156,156,156,1,0,0,0,1,41,41, + 41,1,165,165,165,1,0,0,0,1,104,104,104,1,143,143,143,1,0,0, + 0,1,126,126,126,1,219,219,219,1,32,32,32,1,20,20,20,1,0,0, + 0,11,50,50,50,1,235,235,235,1,169,169,169,1,91,91,91,1,13,13, + 13,1,0,0,0,1,104,104,104,1,143,143,143,1,0,0,0,1,126,126, + 126,1,147,147,147,1,0,0,0,14,21,21,21,1,103,103,103,1,185,185, + 185,1,223,223,223,1,9,9,9,1,104,104,104,1,143,143,143,1,0,0, + 0,1,126,126,126,1,129,129,129,1,0,0,0,13,93,93,93,1,130,130, + 130,1,0,0,0,1,4,4,4,1,236,236,236,1,33,33,33,1,97,97, + 97,1,151,151,151,1,0,0,0,1,126,126,126,1,129,129,129,1,0,0, + 0,13,14,14,14,1,191,191,191,1,199,199,199,1,218,218,218,1,143,143, + 143,1,0,0,0,1,47,47,47,1,237,237,237,1,140,140,140,1,126,126, + 126,1,129,129,129,1,0,0,0,32,0,0) + ); + +const + objdata_tdbintegerlookupstrlb: record size: integer; data: array[0..1420] of byte end = + (size: 1421; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,21,116,100,98, + 105,110,116,101,103,101,114,108,111,111,107,117,112,115,116,114,108,98,23,98, + 105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108, + 111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111, + 110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99, + 111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97, + 103,101,10,12,5,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24, + 0,0,0,132,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128, + 128,128,25,0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184, + 255,255,4,168,233,233,1,184,255,255,4,179,248,248,1,182,252,252,1,184, + 255,255,4,182,252,252,1,178,246,246,1,184,255,255,1,188,241,255,1,196, + 214,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184, + 255,255,3,103,143,143,1,51,71,71,1,184,255,255,2,181,251,251,1,69, + 95,95,1,35,48,48,1,31,43,43,1,87,121,121,1,184,255,255,2,105, + 145,145,1,34,47,47,1,33,43,45,1,79,86,103,1,198,198,251,1,201, + 201,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184, + 255,255,1,175,242,242,1,75,104,104,1,13,18,18,1,51,71,71,1,184, + 255,255,2,118,164,164,1,62,86,86,1,184,255,255,1,180,250,250,1,32, + 44,44,1,147,204,204,1,159,221,221,1,23,29,31,1,190,207,247,1,201, + 201,255,1,43,43,55,1,142,142,180,1,201,201,255,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,142,197,197,1,92, + 127,127,1,126,175,175,1,51,71,71,1,184,255,255,2,154,214,214,1,162, + 225,225,1,184,255,255,2,51,71,71,1,116,149,158,1,196,214,255,1,188, + 188,238,1,201,201,255,1,199,199,252,1,32,32,40,1,143,143,181,1,201, + 201,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184, + 255,255,3,132,183,183,1,51,71,71,1,184,255,255,5,137,176,186,1,21, + 23,27,1,187,187,237,1,201,201,255,2,139,139,176,1,19,19,24,1,66, + 66,84,1,201,201,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,184,255,255,3,132,183,183,1,51,71,71,1,184,255,255,3,188, + 241,255,1,135,148,176,1,20,20,26,1,160,160,203,1,201,201,255,3,188, + 188,238,1,163,163,207,1,50,50,63,1,114,114,144,1,201,201,255,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,132, + 183,183,1,51,71,71,1,184,255,255,1,188,241,255,1,196,214,255,1,130, + 130,165,1,26,26,33,1,168,168,213,1,201,201,255,2,188,188,238,1,175, + 175,222,1,201,201,255,2,137,137,174,1,49,49,62,1,201,201,255,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,132, + 183,183,1,52,67,71,1,196,214,255,1,201,201,255,1,148,148,188,1,31, + 31,39,1,181,181,229,1,201,201,255,3,169,169,214,1,27,27,34,1,197, + 197,250,1,201,201,255,1,81,81,103,1,107,107,136,1,201,201,255,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,2,188, + 241,255,1,141,154,183,1,56,56,71,1,201,201,255,2,48,48,61,1,2, + 2,3,1,6,6,7,3,110,110,139,1,201,201,255,1,107,107,136,1,37, + 37,47,1,41,41,52,1,76,76,96,1,188,188,239,1,201,201,255,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,188,241,255,1,196, + 214,255,1,201,201,255,13,198,198,251,1,192,192,244,1,201,201,255,3,224, + 224,224,1,255,255,255,1,128,128,128,1,224,224,224,22,255,255,255,25,208, + 208,208,35,0,0,0,2,208,208,208,22,0,0,0,2,208,208,208,16,0, + 0,0,13,208,208,208,11,0,0,0,2,208,208,208,1,0,0,0,2,208, + 208,208,1,0,0,0,2,208,208,208,1,0,0,0,4,208,208,208,11,0, + 0,0,5,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208, + 208,208,14,0,0,0,7,208,208,208,1,0,0,0,2,208,208,208,13,0, + 0,0,2,208,208,208,1,0,0,0,5,208,208,208,1,0,0,0,2,208, + 208,208,13,0,0,0,5,208,208,208,1,0,0,0,5,208,208,208,32,80, + 1,0,0,255,255,255,255,255,255,255,81,0,0,0,35,45,45,45,1,105, + 105,105,1,0,0,0,22,104,104,104,1,143,143,143,1,0,0,0,16,15, + 15,15,1,182,182,182,1,223,223,223,1,213,213,213,1,84,84,84,1,30, + 30,30,1,218,218,218,1,227,227,227,1,107,107,107,1,106,106,106,1,141, + 141,141,1,231,231,231,1,116,116,116,1,0,0,0,11,106,106,106,1,156, + 156,156,1,0,0,0,1,41,41,41,1,165,165,165,1,0,0,0,1,104, + 104,104,1,143,143,143,1,0,0,0,1,126,126,126,1,219,219,219,1,32, + 32,32,1,20,20,20,1,0,0,0,11,50,50,50,1,235,235,235,1,169, + 169,169,1,91,91,91,1,13,13,13,1,0,0,0,1,104,104,104,1,143, + 143,143,1,0,0,0,1,126,126,126,1,147,147,147,1,0,0,0,14,21, + 21,21,1,103,103,103,1,185,185,185,1,223,223,223,1,9,9,9,1,104, + 104,104,1,143,143,143,1,0,0,0,1,126,126,126,1,129,129,129,1,0, + 0,0,13,93,93,93,1,130,130,130,1,0,0,0,1,4,4,4,1,236, + 236,236,1,33,33,33,1,97,97,97,1,151,151,151,1,0,0,0,1,126, + 126,126,1,129,129,129,1,0,0,0,13,14,14,14,1,191,191,191,1,199, + 199,199,1,218,218,218,1,143,143,143,1,0,0,0,1,47,47,47,1,237, + 237,237,1,140,140,140,1,126,126,126,1,129,129,129,1,0,0,0,32,0, + 0) + ); + +const + objdata_tdbintegerlookupstrdb: record size: integer; data: array[0..1452] of byte end = + (size: 1453; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,21,116,100,98, + 105,110,116,101,103,101,114,108,111,111,107,117,112,115,116,114,100,98,23,98, + 105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108, + 111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111, + 110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99, + 111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97, + 103,101,10,44,5,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24, + 0,0,0,164,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128, + 128,128,25,0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184, + 255,255,4,168,233,233,1,184,255,255,4,179,248,248,1,182,252,252,1,184, + 255,255,4,182,252,252,1,168,240,246,1,97,202,255,1,18,153,255,2,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,103, + 143,143,1,51,71,71,1,184,255,255,2,181,251,251,1,69,95,95,1,35, + 48,48,1,31,43,43,1,87,121,121,1,184,255,255,2,99,142,145,1,18, + 37,47,1,3,27,45,1,7,62,103,1,95,199,251,1,174,249,255,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,175, + 242,242,1,75,104,104,1,13,18,18,1,51,71,71,1,184,255,255,2,118, + 164,164,1,62,86,86,1,184,255,255,1,180,250,250,1,32,44,44,1,139, + 199,204,1,84,175,221,1,2,19,31,1,17,148,247,1,97,202,255,1,38, + 54,55,1,130,180,180,1,184,255,255,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,184,255,255,1,142,197,197,1,92,127,127,1,126, + 175,175,1,51,71,71,1,184,255,255,2,154,214,214,1,162,225,225,1,184, + 255,255,1,174,249,255,1,27,56,71,1,11,95,158,1,18,153,255,1,91, + 189,238,1,174,249,255,1,182,252,252,1,29,40,40,1,131,181,181,1,184, + 255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184, + 255,255,3,132,183,183,1,51,71,71,1,184,255,255,3,174,249,255,1,97, + 202,255,1,13,112,186,1,2,16,27,1,90,188,237,1,174,249,255,1,184, + 255,255,1,127,176,176,1,17,24,24,1,61,84,84,1,184,255,255,2,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,132, + 183,183,1,51,71,71,1,184,255,255,1,174,249,255,1,97,202,255,1,18, + 153,255,1,12,106,176,1,10,21,26,1,139,198,203,1,184,255,255,3,172, + 238,238,1,149,207,207,1,45,63,63,1,104,144,144,1,184,255,255,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3,132, + 183,183,1,48,69,71,1,97,202,255,1,18,153,255,2,63,131,165,1,23, + 32,33,1,154,213,213,1,184,255,255,2,172,238,238,1,160,222,222,1,184, + 255,255,2,126,174,174,1,45,62,62,1,184,255,255,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,184,255,255,2,174,249,255,1,70, + 145,183,1,5,43,71,1,18,153,255,1,97,202,255,1,128,184,188,1,28, + 39,39,1,165,229,229,1,184,255,255,3,154,214,214,1,25,34,34,1,180, + 250,250,1,184,255,255,1,74,103,103,1,98,136,136,1,184,255,255,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,174,249,255,1,97, + 202,255,1,18,153,255,1,13,110,183,1,27,56,71,1,174,249,255,1,184, + 255,255,1,44,61,61,1,2,3,3,1,5,7,7,3,100,139,139,1,184, + 255,255,1,98,136,136,1,34,47,47,1,38,52,52,1,69,96,96,1,172, + 239,239,1,184,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,18,153,255,2,97,202,255,1,174,249,255,1,184,255,255,11,181, + 251,251,1,176,244,244,1,184,255,255,3,224,224,224,1,255,255,255,1,128, + 128,128,1,224,224,224,22,255,255,255,25,208,208,208,35,0,0,0,2,208, + 208,208,22,0,0,0,2,208,208,208,16,0,0,0,13,208,208,208,11,0, + 0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208, + 208,208,1,0,0,0,4,208,208,208,11,0,0,0,5,208,208,208,1,0, + 0,0,2,208,208,208,1,0,0,0,2,208,208,208,14,0,0,0,7,208, + 208,208,1,0,0,0,2,208,208,208,13,0,0,0,2,208,208,208,1,0, + 0,0,5,208,208,208,1,0,0,0,2,208,208,208,13,0,0,0,5,208, + 208,208,1,0,0,0,5,208,208,208,32,80,1,0,0,255,255,255,255,255, + 255,255,81,0,0,0,35,45,45,45,1,105,105,105,1,0,0,0,22,104, + 104,104,1,143,143,143,1,0,0,0,16,15,15,15,1,182,182,182,1,223, + 223,223,1,213,213,213,1,84,84,84,1,30,30,30,1,218,218,218,1,227, + 227,227,1,107,107,107,1,106,106,106,1,141,141,141,1,231,231,231,1,116, + 116,116,1,0,0,0,11,106,106,106,1,156,156,156,1,0,0,0,1,41, + 41,41,1,165,165,165,1,0,0,0,1,104,104,104,1,143,143,143,1,0, + 0,0,1,126,126,126,1,219,219,219,1,32,32,32,1,20,20,20,1,0, + 0,0,11,50,50,50,1,235,235,235,1,169,169,169,1,91,91,91,1,13, + 13,13,1,0,0,0,1,104,104,104,1,143,143,143,1,0,0,0,1,126, + 126,126,1,147,147,147,1,0,0,0,14,21,21,21,1,103,103,103,1,185, + 185,185,1,223,223,223,1,9,9,9,1,104,104,104,1,143,143,143,1,0, + 0,0,1,126,126,126,1,129,129,129,1,0,0,0,13,93,93,93,1,130, + 130,130,1,0,0,0,1,4,4,4,1,236,236,236,1,33,33,33,1,97, + 97,97,1,151,151,151,1,0,0,0,1,126,126,126,1,129,129,129,1,0, + 0,0,13,14,14,14,1,191,191,191,1,199,199,199,1,218,218,218,1,143, + 143,143,1,0,0,0,1,47,47,47,1,237,237,237,1,140,140,140,1,126, + 126,126,1,129,129,129,1,0,0,0,32,0,0) + ); + +const + objdata_tdbreallookupstrlb: record size: integer; data: array[0..1333] of byte end = + (size: 1334; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,18,116,100,98, + 114,101,97,108,108,111,111,107,117,112,115,116,114,108,98,23,98,105,116,109, + 97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4, + 6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11, + 10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111, + 114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10, + 184,4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0, + 48,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25, + 0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3, + 168,233,233,1,184,255,255,7,182,252,252,1,179,248,248,1,184,255,255,5, + 181,232,246,1,186,203,242,1,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,184,255,255,2,103,143,143,1,51,71,71,1,184,255,255,6, + 84,116,116,1,33,46,46,1,32,45,45,1,72,100,100,1,181,251,251,1, + 184,255,255,1,188,241,255,1,194,211,252,1,54,54,69,1,117,117,149,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,175,242,242,1, + 75,104,104,1,13,18,18,1,51,71,71,1,184,255,255,5,142,197,197,1, + 40,55,55,1,182,252,252,1,183,254,254,1,54,75,75,1,125,161,170,1, + 196,214,255,1,169,169,214,1,45,45,57,1,13,13,17,1,117,117,149,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,142,197,197,1, + 92,127,127,1,126,175,175,1,51,71,71,1,184,255,255,5,162,224,224,1, + 155,215,215,1,184,255,255,1,188,241,255,1,81,88,105,1,98,98,124,1, + 201,201,255,1,114,114,145,1,135,135,171,1,84,84,106,1,117,117,149,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,2, + 132,183,183,1,51,71,71,1,184,255,255,6,188,241,255,1,196,214,255,1, + 164,164,208,1,19,19,24,1,172,172,218,1,201,201,255,3,84,84,106,1, + 117,117,149,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 184,255,255,2,132,183,183,1,51,71,71,1,184,255,255,4,188,241,255,1, + 196,214,255,1,201,201,255,1,158,158,200,1,20,20,26,1,142,142,180,1, + 201,201,255,4,84,84,106,1,117,117,149,1,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,184,255,255,2,132,183,183,1,51,71,71,1, + 184,255,255,2,188,241,255,1,196,214,255,1,201,201,255,2,151,151,191,1, + 22,22,28,1,151,151,192,1,201,201,255,5,84,84,106,1,117,117,149,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,2, + 132,183,183,1,51,71,71,1,188,241,255,1,196,214,255,1,197,197,250,1, + 177,177,225,1,201,201,255,1,169,169,215,1,22,22,28,1,168,168,213,1, + 201,201,255,6,84,84,106,1,117,117,149,1,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,184,255,255,2,135,173,183,1,55,60,71,1, + 201,201,255,2,164,164,208,1,12,12,15,1,201,201,255,1,74,74,94,1, + 2,2,2,1,6,6,7,3,84,84,106,1,201,201,255,3,84,84,106,1, + 117,117,149,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 188,241,255,1,196,214,255,1,201,201,255,18,224,224,224,1,255,255,255,1, + 128,128,128,1,224,224,224,22,255,255,255,25,208,208,208,35,0,0,0,2, + 208,208,208,22,0,0,0,2,208,208,208,16,0,0,0,13,208,208,208,11, + 0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2, + 208,208,208,1,0,0,0,4,208,208,208,11,0,0,0,5,208,208,208,1, + 0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,14,0,0,0,7, + 208,208,208,1,0,0,0,2,208,208,208,13,0,0,0,2,208,208,208,1, + 0,0,0,5,208,208,208,1,0,0,0,2,208,208,208,13,0,0,0,5, + 208,208,208,1,0,0,0,5,208,208,208,32,80,1,0,0,255,255,255,255, + 255,255,255,81,0,0,0,35,45,45,45,1,105,105,105,1,0,0,0,22, + 104,104,104,1,143,143,143,1,0,0,0,16,15,15,15,1,182,182,182,1, + 223,223,223,1,213,213,213,1,84,84,84,1,30,30,30,1,218,218,218,1, + 227,227,227,1,107,107,107,1,106,106,106,1,141,141,141,1,231,231,231,1, + 116,116,116,1,0,0,0,11,106,106,106,1,156,156,156,1,0,0,0,1, + 41,41,41,1,165,165,165,1,0,0,0,1,104,104,104,1,143,143,143,1, + 0,0,0,1,126,126,126,1,219,219,219,1,32,32,32,1,20,20,20,1, + 0,0,0,11,50,50,50,1,235,235,235,1,169,169,169,1,91,91,91,1, + 13,13,13,1,0,0,0,1,104,104,104,1,143,143,143,1,0,0,0,1, + 126,126,126,1,147,147,147,1,0,0,0,14,21,21,21,1,103,103,103,1, + 185,185,185,1,223,223,223,1,9,9,9,1,104,104,104,1,143,143,143,1, + 0,0,0,1,126,126,126,1,129,129,129,1,0,0,0,13,93,93,93,1, + 130,130,130,1,0,0,0,1,4,4,4,1,236,236,236,1,33,33,33,1, + 97,97,97,1,151,151,151,1,0,0,0,1,126,126,126,1,129,129,129,1, + 0,0,0,13,14,14,14,1,191,191,191,1,199,199,199,1,218,218,218,1, + 143,143,143,1,0,0,0,1,47,47,47,1,237,237,237,1,140,140,140,1, + 126,126,126,1,129,129,129,1,0,0,0,32,0,0) + ); + +const + objdata_tdbreallookupstrdb: record size: integer; data: array[0..1361] of byte end = + (size: 1362; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,18,116,100,98, + 114,101,97,108,108,111,111,107,117,112,115,116,114,100,98,23,98,105,116,109, + 97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4, + 6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11, + 10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111, + 114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10, + 212,4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0, + 76,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25, + 0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,3, + 168,233,233,1,184,255,255,7,182,252,252,1,179,248,248,1,184,255,255,3, + 174,249,255,1,97,202,255,1,17,148,246,1,17,145,242,1,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,2,103,143,143,1, + 51,71,71,1,184,255,255,6,84,116,116,1,33,46,46,1,32,45,45,1, + 72,100,100,1,171,245,251,1,97,202,255,1,18,153,255,1,18,151,252,1, + 26,55,69,1,102,145,149,1,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,175,242,242,1,75,104,104,1,13,18,18,1,51,71,71,1, + 184,255,255,5,142,197,197,1,40,55,55,1,182,252,252,1,173,248,254,1, + 29,59,75,1,12,102,170,1,18,153,255,1,81,170,214,1,39,56,57,1, + 12,17,17,1,108,149,149,1,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,142,197,197,1,92,127,127,1,126,175,175,1,51,71,71,1, + 184,255,255,5,162,224,224,1,147,210,215,1,97,202,255,1,18,153,255,1, + 7,63,105,1,47,98,124,1,174,249,255,1,105,145,145,1,123,171,171,1, + 76,106,106,1,108,149,149,1,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,184,255,255,2,132,183,183,1,51,71,71,1,184,255,255,4, + 174,249,255,1,97,202,255,1,18,153,255,2,79,165,208,1,16,23,24,1, + 157,218,218,1,184,255,255,3,76,106,106,1,108,149,149,1,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,2,132,183,183,1, + 51,71,71,1,184,255,255,2,174,249,255,1,97,202,255,1,18,153,255,2, + 97,202,255,1,136,195,200,1,19,26,26,1,130,180,180,1,184,255,255,4, + 76,106,106,1,108,149,149,1,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,184,255,255,2,132,183,183,1,51,71,71,1,174,249,255,1, + 97,202,255,1,18,153,255,2,97,202,255,1,174,249,255,1,138,191,191,1, + 20,28,28,1,139,192,192,1,184,255,255,5,76,106,106,1,108,149,149,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,2, + 125,179,183,1,27,56,71,1,18,153,255,2,95,198,250,1,154,220,225,1, + 184,255,255,1,155,215,215,1,20,28,28,1,154,213,213,1,184,255,255,6, + 76,106,106,1,108,149,149,1,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,174,249,255,1,97,202,255,1,13,110,183,1,5,43,71,1, + 97,202,255,1,174,249,255,1,150,208,208,1,11,15,15,1,184,255,255,1, + 68,94,94,1,1,2,2,1,5,7,7,3,76,106,106,1,184,255,255,3, + 76,106,106,1,108,149,149,1,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,18,153,255,2,97,202,255,1,174,249,255,1,184,255,255,16, + 224,224,224,1,255,255,255,1,128,128,128,1,224,224,224,22,255,255,255,25, + 208,208,208,35,0,0,0,2,208,208,208,22,0,0,0,2,208,208,208,16, + 0,0,0,13,208,208,208,11,0,0,0,2,208,208,208,1,0,0,0,2, + 208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,4,208,208,208,11, + 0,0,0,5,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2, + 208,208,208,14,0,0,0,7,208,208,208,1,0,0,0,2,208,208,208,13, + 0,0,0,2,208,208,208,1,0,0,0,5,208,208,208,1,0,0,0,2, + 208,208,208,13,0,0,0,5,208,208,208,1,0,0,0,5,208,208,208,32, + 80,1,0,0,255,255,255,255,255,255,255,81,0,0,0,35,45,45,45,1, + 105,105,105,1,0,0,0,22,104,104,104,1,143,143,143,1,0,0,0,16, + 15,15,15,1,182,182,182,1,223,223,223,1,213,213,213,1,84,84,84,1, + 30,30,30,1,218,218,218,1,227,227,227,1,107,107,107,1,106,106,106,1, + 141,141,141,1,231,231,231,1,116,116,116,1,0,0,0,11,106,106,106,1, + 156,156,156,1,0,0,0,1,41,41,41,1,165,165,165,1,0,0,0,1, + 104,104,104,1,143,143,143,1,0,0,0,1,126,126,126,1,219,219,219,1, + 32,32,32,1,20,20,20,1,0,0,0,11,50,50,50,1,235,235,235,1, + 169,169,169,1,91,91,91,1,13,13,13,1,0,0,0,1,104,104,104,1, + 143,143,143,1,0,0,0,1,126,126,126,1,147,147,147,1,0,0,0,14, + 21,21,21,1,103,103,103,1,185,185,185,1,223,223,223,1,9,9,9,1, + 104,104,104,1,143,143,143,1,0,0,0,1,126,126,126,1,129,129,129,1, + 0,0,0,13,93,93,93,1,130,130,130,1,0,0,0,1,4,4,4,1, + 236,236,236,1,33,33,33,1,97,97,97,1,151,151,151,1,0,0,0,1, + 126,126,126,1,129,129,129,1,0,0,0,13,14,14,14,1,191,191,191,1, + 199,199,199,1,218,218,218,1,143,143,143,1,0,0,0,1,47,47,47,1, + 237,237,237,1,140,140,140,1,126,126,126,1,129,129,129,1,0,0,0,32, + 0,0) + ); + +const + objdata_tdbdatetimelookupstrlb: record size: integer; data: array[0..1349] of byte end = + (size: 1350; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,22,116,100,98, + 100,97,116,101,116,105,109,101,108,111,111,107,117,112,115,116,114,108,98,23, + 98,105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111, + 108,111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105, + 111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95, + 99,111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109, + 97,103,101,10,196,4,0,0,0,0,0,0,6,0,0,0,24,0,0,0, + 24,0,0,0,60,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 128,128,128,25,0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1, + 184,255,255,1,179,248,248,1,167,231,231,2,170,235,235,1,182,252,252,1, + 184,255,255,6,173,240,240,1,167,231,231,5,175,224,237,1,196,214,255,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1, + 127,176,176,1,5,7,7,1,22,31,31,1,19,27,27,1,5,7,7,1, + 60,83,83,1,168,233,233,1,184,255,255,4,80,111,111,1,22,31,31,2, + 1,1,1,1,21,26,28,1,24,26,31,1,67,67,85,1,201,201,255,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1, + 127,176,176,1,45,63,63,1,184,255,255,2,180,250,250,1,66,92,92,1, + 56,78,78,1,184,255,255,6,188,241,255,1,8,8,10,1,181,181,229,1, + 201,201,255,3,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 184,255,255,1,127,176,176,1,45,63,63,1,184,255,255,3,175,242,242,1, + 1,2,2,1,162,224,224,1,184,255,255,1,29,40,40,1,165,228,228,1, + 188,241,255,1,196,214,255,1,201,201,255,1,8,8,10,1,181,181,229,1, + 201,201,255,3,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 184,255,255,1,127,176,176,1,45,63,63,1,184,255,255,4,30,42,42,1, + 128,178,178,1,184,255,255,1,136,174,184,1,189,206,246,1,201,201,255,3, + 8,8,10,1,181,181,229,1,201,201,255,3,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,184,255,255,1,127,176,176,1,45,63,63,1, + 184,255,255,4,31,43,43,1,132,169,179,1,196,214,255,1,201,201,255,5, + 8,8,10,1,181,181,229,1,201,201,255,3,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,184,255,255,1,127,176,176,1,45,63,63,1, + 184,255,255,3,177,227,240,1,7,8,9,1,174,174,221,1,201,201,255,6, + 8,8,10,1,181,181,229,1,201,201,255,3,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,184,255,255,1,127,176,176,1,45,63,63,1, + 184,255,255,1,188,241,255,1,178,195,232,1,69,69,88,1,64,64,81,1, + 201,201,255,2,177,177,224,1,198,198,251,1,201,201,255,3,8,8,10,1, + 181,181,229,1,201,201,255,3,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,184,255,255,1,127,176,176,1,1,1,1,1,5,6,7,1, + 6,6,7,1,17,17,22,1,78,78,99,1,192,192,243,1,201,201,255,2, + 1,1,1,1,175,175,222,1,201,201,255,3,8,8,10,1,181,181,229,1, + 201,201,255,3,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 188,241,255,1,196,214,255,1,201,201,255,18,224,224,224,1,255,255,255,1, + 128,128,128,1,224,224,224,22,255,255,255,25,208,208,208,35,0,0,0,2, + 208,208,208,22,0,0,0,2,208,208,208,16,0,0,0,13,208,208,208,11, + 0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2, + 208,208,208,1,0,0,0,4,208,208,208,11,0,0,0,5,208,208,208,1, + 0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,14,0,0,0,4, + 208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,13, + 0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2, + 208,208,208,1,0,0,0,2,208,208,208,13,0,0,0,5,208,208,208,1, + 0,0,0,5,208,208,208,32,80,1,0,0,255,255,255,255,255,255,255,81, + 0,0,0,35,77,77,77,1,73,73,73,1,0,0,0,22,155,155,155,1, + 92,92,92,1,0,0,0,16,40,40,40,1,203,203,203,1,221,221,221,1, + 201,201,201,1,51,51,51,1,68,68,68,1,230,230,230,1,215,215,215,1, + 69,69,69,1,150,150,150,1,139,139,139,1,234,234,234,1,72,72,72,1, + 0,0,0,11,157,157,157,1,105,105,105,1,0,0,0,1,80,80,80,1, + 125,125,125,1,0,0,0,1,155,155,155,1,92,92,92,1,0,0,0,1, + 178,178,178,1,179,179,179,1,29,29,29,1,11,11,11,1,0,0,0,11, + 91,91,91,1,234,234,234,1,154,154,154,1,74,74,74,1,4,4,4,1, + 0,0,0,1,155,155,155,1,92,92,92,1,0,0,0,1,178,178,178,1, + 96,96,96,1,0,0,0,14,35,35,35,1,119,119,119,1,205,205,205,1, + 181,181,181,1,0,0,0,1,155,155,155,1,92,92,92,1,0,0,0,1, + 178,178,178,1,77,77,77,1,0,0,0,13,138,138,138,1,85,85,85,1, + 0,0,0,1,36,36,36,1,237,237,237,1,0,0,0,1,148,148,148,1, + 99,99,99,1,0,0,0,1,178,178,178,1,77,77,77,1,0,0,0,13, + 45,45,45,1,202,202,202,1,195,195,195,1,225,225,225,1,97,97,97,1, + 0,0,0,1,92,92,92,1,236,236,236,1,97,97,97,1,178,178,178,1, + 77,77,77,1,0,0,0,32,0,0) + ); + +const + objdata_tdbdatetimelookupstrdb: record size: integer; data: array[0..1405] of byte end = + (size: 1406; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,22,116,100,98, + 100,97,116,101,116,105,109,101,108,111,111,107,117,112,115,116,114,100,98,23, + 98,105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111, + 108,111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105, + 111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95, + 99,111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109, + 97,103,101,10,252,4,0,0,0,0,0,0,6,0,0,0,24,0,0,0, + 24,0,0,0,116,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 128,128,128,25,0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1, + 184,255,255,1,179,248,248,1,167,231,231,2,170,235,235,1,182,252,252,1, + 184,255,255,6,173,240,240,1,167,231,231,3,158,226,231,1,88,183,231,1, + 17,142,237,1,18,153,255,1,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,184,255,255,1,127,176,176,1,5,7,7,1,22,31,31,1, + 19,27,27,1,5,7,7,1,60,83,83,1,168,233,233,1,184,255,255,4, + 80,111,111,1,22,31,31,1,21,30,31,1,0,1,1,1,2,17,28,1, + 2,19,31,1,32,67,85,1,174,249,255,1,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,184,255,255,1,127,176,176,1,45,63,63,1, + 184,255,255,2,180,250,250,1,66,92,92,1,56,78,78,1,184,255,255,4, + 174,249,255,1,97,202,255,1,18,153,255,1,1,6,10,1,87,181,229,1, + 174,249,255,1,184,255,255,2,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,184,255,255,1,127,176,176,1,45,63,63,1,184,255,255,3, + 175,242,242,1,1,2,2,1,162,224,224,1,184,255,255,1,27,39,40,1, + 87,181,228,1,18,153,255,2,97,202,255,1,7,10,10,1,165,229,229,1, + 184,255,255,3,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 184,255,255,1,127,176,176,1,45,63,63,1,184,255,255,4,30,42,42,1, + 121,174,178,1,97,202,255,1,13,110,184,1,17,148,246,1,97,202,255,1, + 174,249,255,1,184,255,255,1,7,10,10,1,165,229,229,1,184,255,255,3, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1, + 127,176,176,1,45,63,63,1,184,255,255,3,174,249,255,1,16,34,43,1, + 13,107,179,1,18,153,255,1,97,202,255,1,174,249,255,1,184,255,255,3, + 7,10,10,1,165,229,229,1,184,255,255,3,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,184,255,255,1,127,176,176,1,45,63,63,1, + 184,255,255,1,174,249,255,1,97,202,255,1,17,144,240,1,1,5,9,1, + 84,175,221,1,174,249,255,1,184,255,255,5,7,10,10,1,165,229,229,1, + 184,255,255,3,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 184,255,255,1,127,176,176,1,43,62,63,1,97,202,255,1,18,153,255,1, + 16,139,232,1,33,70,88,1,55,79,81,1,184,255,255,2,162,224,224,1, + 181,251,251,1,184,255,255,3,7,10,10,1,165,229,229,1,184,255,255,3, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,174,249,255,1, + 67,139,176,1,0,1,1,1,0,4,7,1,3,6,7,1,15,21,22,1, + 71,99,99,1,175,243,243,1,184,255,255,2,1,1,1,1,160,222,222,1, + 184,255,255,3,7,10,10,1,165,229,229,1,184,255,255,3,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,18,153,255,2,97,202,255,1, + 174,249,255,1,184,255,255,16,224,224,224,1,255,255,255,1,128,128,128,1, + 224,224,224,22,255,255,255,25,208,208,208,35,0,0,0,2,208,208,208,22, + 0,0,0,2,208,208,208,16,0,0,0,13,208,208,208,11,0,0,0,2, + 208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,1, + 0,0,0,4,208,208,208,11,0,0,0,5,208,208,208,1,0,0,0,2, + 208,208,208,1,0,0,0,2,208,208,208,14,0,0,0,4,208,208,208,1, + 0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,13,0,0,0,2, + 208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,1, + 0,0,0,2,208,208,208,13,0,0,0,5,208,208,208,1,0,0,0,5, + 208,208,208,32,80,1,0,0,255,255,255,255,255,255,255,81,0,0,0,35, + 77,77,77,1,73,73,73,1,0,0,0,22,155,155,155,1,92,92,92,1, + 0,0,0,16,40,40,40,1,203,203,203,1,221,221,221,1,201,201,201,1, + 51,51,51,1,68,68,68,1,230,230,230,1,215,215,215,1,69,69,69,1, + 150,150,150,1,139,139,139,1,234,234,234,1,72,72,72,1,0,0,0,11, + 157,157,157,1,105,105,105,1,0,0,0,1,80,80,80,1,125,125,125,1, + 0,0,0,1,155,155,155,1,92,92,92,1,0,0,0,1,178,178,178,1, + 179,179,179,1,29,29,29,1,11,11,11,1,0,0,0,11,91,91,91,1, + 234,234,234,1,154,154,154,1,74,74,74,1,4,4,4,1,0,0,0,1, + 155,155,155,1,92,92,92,1,0,0,0,1,178,178,178,1,96,96,96,1, + 0,0,0,14,35,35,35,1,119,119,119,1,205,205,205,1,181,181,181,1, + 0,0,0,1,155,155,155,1,92,92,92,1,0,0,0,1,178,178,178,1, + 77,77,77,1,0,0,0,13,138,138,138,1,85,85,85,1,0,0,0,1, + 36,36,36,1,237,237,237,1,0,0,0,1,148,148,148,1,99,99,99,1, + 0,0,0,1,178,178,178,1,77,77,77,1,0,0,0,13,45,45,45,1, + 202,202,202,1,195,195,195,1,225,225,225,1,97,97,97,1,0,0,0,1, + 92,92,92,1,236,236,236,1,97,97,97,1,178,178,178,1,77,77,77,1, + 0,0,0,32,0,0) + ); + +const + objdata_tdbwidgetgrid: record size: integer; data: array[0..1396] of byte end = + (size: 1397; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,100,98, + 119,105,100,103,101,116,103,114,105,100,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,252,4,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,184,4,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,208,208,208,2,128, + 128,128,1,208,208,208,2,112,112,112,1,153,153,153,1,171,171,171,1,165, + 165,165,1,118,118,118,1,184,184,184,1,208,208,208,2,128,128,128,1,208, + 208,208,2,154,154,154,1,148,148,148,1,190,190,190,1,186,186,186,1,148, + 148,148,1,208,208,208,1,255,255,255,1,128,128,128,1,208,208,208,2,128, + 128,128,1,208,208,208,1,179,179,179,1,142,142,142,1,116,116,116,1,148, + 148,148,1,141,141,141,1,121,121,121,1,128,128,128,1,208,208,208,2,128, + 128,128,1,208,208,208,2,144,144,144,2,131,131,131,1,146,146,146,1,165, + 165,165,1,208,208,208,1,255,255,255,1,128,128,128,1,208,208,208,2,128, + 128,128,1,208,208,208,4,175,175,175,1,176,176,176,1,208,208,208,4,128, + 128,128,1,208,208,208,2,186,186,186,1,183,183,183,1,187,187,187,1,191, + 191,191,1,197,197,197,1,208,208,208,1,255,255,255,1,128,128,128,23,255, + 255,255,1,128,128,128,1,208,208,208,2,128,128,128,1,184,255,255,1,122, + 169,169,1,132,183,183,1,146,202,202,1,155,215,215,1,162,225,225,1,184, + 255,255,4,128,128,128,1,184,255,255,2,175,243,243,1,122,169,169,1,147, + 204,204,1,129,179,179,1,100,139,139,1,184,255,255,1,255,255,255,1,128, + 128,128,1,208,208,208,2,128,128,128,1,184,255,255,1,109,151,151,1,115, + 160,160,1,112,155,155,1,145,201,201,1,162,225,225,1,184,255,255,4,128, + 128,128,1,184,255,255,3,138,191,191,1,108,150,150,1,146,202,202,1,114, + 158,158,1,181,251,251,1,255,255,255,1,128,128,128,1,208,208,208,2,128, + 128,128,1,184,255,255,1,171,237,237,1,168,233,233,1,165,228,228,1,154, + 213,213,1,160,222,222,1,184,255,255,4,128,128,128,1,184,255,255,8,255, + 255,255,1,128,128,128,23,255,255,255,1,128,128,128,1,208,208,208,2,128, + 128,128,1,184,255,255,1,149,206,206,1,121,168,168,1,152,211,211,1,172, + 238,238,1,163,226,226,1,175,242,242,1,138,191,191,1,145,201,201,1,181, + 251,251,1,128,128,128,1,184,255,255,4,127,176,176,2,93,129,129,1,184, + 255,255,1,255,255,255,1,128,128,128,1,208,208,208,2,128,128,128,1,184, + 255,255,1,131,181,181,1,170,236,236,1,105,145,145,1,123,170,170,1,131, + 181,181,1,117,162,162,1,137,190,190,1,133,185,185,1,184,255,255,1,128, + 128,128,1,184,255,255,4,134,186,186,1,152,211,211,1,115,159,159,1,184, + 255,255,1,255,255,255,1,128,128,128,1,208,208,208,2,128,128,128,1,184, + 255,255,1,144,199,199,1,152,210,210,1,151,209,209,1,171,237,237,1,172, + 238,238,1,170,235,235,1,159,220,220,1,144,199,199,1,179,248,248,1,128, + 128,128,1,184,255,255,8,255,255,255,1,128,128,128,23,255,255,255,1,128, + 128,128,1,208,208,208,2,128,128,128,1,184,255,255,1,142,197,197,1,128, + 177,177,1,159,221,221,1,184,255,255,6,128,128,128,1,184,255,255,4,122, + 169,169,1,114,158,158,1,113,157,157,1,184,255,255,1,255,255,255,1,128, + 128,128,1,208,208,208,2,128,128,128,1,184,255,255,1,127,176,176,1,137, + 190,190,1,131,181,181,1,184,255,255,6,128,128,128,1,184,255,255,4,128, + 178,178,1,116,161,161,1,114,158,158,1,184,255,255,1,255,255,255,1,128, + 128,128,1,208,208,208,2,128,128,128,1,184,255,255,1,170,235,235,1,157, + 217,217,1,172,239,239,1,184,255,255,6,128,128,128,1,184,255,255,8,255, + 255,255,1,128,128,128,23,255,255,255,1,128,128,128,1,208,208,208,2,128, + 128,128,1,184,255,255,1,126,174,174,1,128,177,177,1,145,201,201,1,167, + 232,232,1,159,221,221,1,131,182,182,1,153,212,212,1,184,255,255,2,128, + 128,128,1,184,255,255,2,165,228,228,1,118,163,163,1,138,191,191,1,133, + 184,184,1,100,139,139,1,184,255,255,1,255,255,255,1,128,128,128,1,208, + 208,208,2,128,128,128,1,184,255,255,1,114,158,158,1,149,207,207,1,87, + 120,120,1,127,176,176,1,126,175,175,1,132,183,183,1,102,142,142,1,184, + 255,255,2,128,128,128,1,184,255,255,2,153,212,212,1,110,152,152,1,147, + 204,204,1,128,178,178,1,114,158,158,1,181,251,251,1,255,255,255,1,128, + 128,128,1,208,208,208,2,128,128,128,1,184,255,255,1,171,237,237,1,184, + 255,255,1,172,239,239,1,146,203,203,1,120,166,166,1,172,239,239,1,130, + 180,180,1,184,255,255,2,128,128,128,1,184,255,255,8,255,255,255,1,128, + 128,128,23,255,255,255,1,128,128,128,1,208,208,208,2,128,128,128,1,184, + 255,255,1,144,199,199,2,163,226,226,1,165,228,228,1,168,233,233,1,184, + 255,255,4,128,128,128,1,184,255,255,4,124,172,172,1,142,197,197,1,99, + 137,137,1,184,255,255,1,255,255,255,1,128,128,128,1,208,208,208,2,128, + 128,128,1,184,255,255,1,132,183,183,1,127,176,176,1,132,183,183,1,125, + 173,173,1,94,130,130,1,184,255,255,4,128,128,128,1,184,255,255,4,150, + 208,208,1,155,215,215,1,121,168,168,1,183,254,254,1,255,255,255,25,12, + 0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tdbstringgrid: record size: integer; data: array[0..1760] of byte end = + (size: 1761; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,100,98, + 115,116,114,105,110,103,103,114,105,100,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,104,6,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,36,6,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,208,208,208,2,128, + 128,128,1,208,208,208,2,112,112,112,1,153,153,153,1,171,171,171,1,165, + 165,165,1,118,118,118,1,184,184,184,1,208,208,208,2,128,128,128,1,208, + 208,208,2,154,154,154,1,148,148,148,1,190,190,190,1,186,186,186,1,148, + 148,148,1,208,208,208,1,255,255,255,1,128,128,128,1,208,208,208,2,128, + 128,128,1,208,208,208,1,179,179,179,1,142,142,142,1,116,116,116,1,148, + 148,148,1,141,141,141,1,121,121,121,1,128,128,128,1,208,208,208,2,128, + 128,128,1,208,208,208,2,144,144,144,2,131,131,131,1,146,146,146,1,165, + 165,165,1,208,208,208,1,255,255,255,1,128,128,128,1,208,208,208,2,128, + 128,128,1,208,208,208,4,175,175,175,1,176,176,176,1,208,208,208,4,128, + 128,128,1,208,208,208,2,186,186,186,1,183,183,183,1,187,187,187,1,191, + 191,191,1,197,197,197,1,208,208,208,1,255,255,255,1,128,128,128,23,255, + 255,255,1,128,128,128,1,208,208,208,2,128,128,128,1,184,255,255,1,122, + 169,169,1,132,183,183,1,146,202,202,1,155,215,215,1,162,225,225,1,184, + 255,255,4,128,128,128,1,184,255,255,2,175,243,243,1,122,169,169,1,147, + 204,204,1,129,179,179,1,100,139,139,1,184,255,255,1,255,255,255,1,128, + 128,128,1,208,208,208,1,209,209,209,1,129,129,129,1,185,255,255,1,111, + 152,152,1,117,161,161,1,114,156,156,1,146,202,202,1,163,225,225,1,185, + 255,255,4,129,129,129,1,185,255,255,3,139,192,192,1,110,151,151,1,147, + 203,203,1,116,159,159,1,182,251,251,1,255,255,255,1,128,128,128,1,213, + 213,213,1,214,214,214,1,145,145,145,1,193,255,255,1,182,239,239,1,180, + 236,236,1,177,232,232,1,167,219,219,1,173,226,226,1,193,255,255,4,145, + 145,145,1,193,255,255,7,192,255,255,1,255,255,255,1,128,128,128,1,170, + 170,170,1,179,179,179,1,180,180,180,1,187,148,135,1,186,154,143,1,180, + 180,180,3,184,160,151,1,188,144,129,2,188,147,133,1,185,158,149,1,180, + 180,180,4,183,166,160,1,189,138,120,1,188,142,126,1,181,173,170,1,170, + 170,170,1,255,255,255,1,128,128,128,1,228,228,228,1,233,233,233,1,197, + 174,166,1,208,53,0,1,208,62,11,1,193,206,203,1,207,234,234,1,216, + 247,247,1,210,133,103,1,208,54,1,1,208,63,13,1,208,61,10,1,208, + 53,0,1,204,96,59,1,222,255,255,2,216,180,160,1,208,59,8,1,207, + 61,10,1,208,55,3,1,205,68,20,1,213,226,218,1,255,255,255,1,128, + 128,128,1,229,229,229,1,233,233,233,1,203,119,91,1,209,72,24,1,208, + 55,3,1,213,168,146,1,186,205,205,1,194,216,216,1,204,124,94,1,207, + 70,22,1,201,225,225,1,199,223,223,1,216,171,149,1,208,53,0,1,220, + 240,236,1,221,233,227,1,209,60,9,1,213,127,93,1,200,215,212,1,208, + 216,210,1,206,67,19,1,212,150,123,1,255,255,255,1,128,128,128,1,229, + 229,229,1,232,230,229,1,207,66,18,1,214,149,121,1,207,106,69,1,208, + 87,44,1,207,234,234,1,216,247,247,1,212,136,106,1,209,65,15,1,210, + 169,149,1,205,159,138,1,211,104,65,1,205,87,47,1,222,255,255,1,217, + 181,161,1,208,53,0,1,219,207,195,1,222,255,255,2,222,252,251,1,215, + 255,255,1,255,255,255,1,128,128,128,1,184,184,184,1,200,151,134,1,208, + 53,0,1,199,174,165,1,201,151,134,1,208,53,0,1,200,166,155,1,197, + 197,197,1,203,114,84,1,208,55,3,1,206,75,30,1,207,71,25,1,207, + 57,5,1,204,101,66,1,198,190,188,1,202,129,104,1,208,53,0,1,198, + 184,179,1,197,197,197,2,196,196,196,1,183,183,183,1,255,255,255,1,128, + 128,128,1,229,229,229,1,216,106,68,1,208,54,1,1,210,78,31,1,207, + 72,25,1,208,53,0,1,209,124,91,1,222,255,255,1,214,139,109,1,210, + 74,26,1,222,255,255,2,220,224,216,1,208,53,0,1,217,177,157,1,217, + 187,169,1,208,53,0,1,218,190,173,1,194,216,216,1,190,210,210,1,198, + 137,112,1,213,198,183,1,255,255,255,1,128,128,128,1,227,210,204,1,209, + 55,3,1,203,114,83,1,217,185,167,1,200,161,143,1,205,110,74,1,208, + 60,9,1,221,243,240,1,214,139,109,1,209,69,20,1,219,211,199,1,219, + 207,195,1,215,161,136,1,208,53,0,1,217,183,164,1,222,245,243,1,210, + 74,26,1,211,93,50,1,200,174,159,1,198,146,124,1,208,53,0,1,213, + 177,156,1,255,255,255,1,128,128,128,1,218,142,116,1,209,57,5,1,195, + 184,180,1,222,255,255,1,215,246,246,1,208,203,193,1,208,53,0,1,216, + 169,146,1,214,139,109,1,208,53,0,2,208,57,5,1,209,67,18,1,203, + 111,80,1,221,253,252,1,222,255,255,1,219,216,206,1,211,90,47,1,208, + 53,0,1,209,70,21,1,214,137,106,1,214,254,254,1,255,255,255,1,128, + 128,128,1,170,170,170,1,179,179,179,1,180,180,180,18,179,179,179,1,170, + 170,170,1,255,255,255,1,128,128,128,1,213,213,213,1,214,214,214,1,145, + 145,145,1,193,255,255,1,143,185,185,1,145,187,187,1,160,208,208,1,179, + 235,235,1,172,226,226,1,148,192,192,1,167,218,218,1,193,255,255,2,145, + 145,145,1,193,255,255,2,177,232,232,1,136,175,175,1,154,200,200,1,149, + 193,193,1,121,154,154,1,192,255,255,1,255,255,255,1,128,128,128,1,208, + 208,208,1,209,209,209,1,129,129,129,1,185,255,255,1,116,159,159,1,150, + 208,208,1,89,122,122,1,129,177,177,1,128,176,176,1,133,184,184,1,104, + 143,143,1,185,255,255,2,129,129,129,1,185,255,255,2,154,213,213,1,112, + 153,153,1,148,205,205,1,129,179,179,1,116,159,159,1,182,251,251,1,255, + 255,255,1,128,128,128,1,208,208,208,2,128,128,128,1,184,255,255,1,171, + 237,237,1,184,255,255,1,172,239,239,1,146,203,203,1,120,166,166,1,172, + 239,239,1,130,180,180,1,184,255,255,2,128,128,128,1,184,255,255,8,255, + 255,255,1,128,128,128,23,255,255,255,1,128,128,128,1,208,208,208,2,128, + 128,128,1,184,255,255,1,144,199,199,2,163,226,226,1,165,228,228,1,168, + 233,233,1,184,255,255,4,128,128,128,1,184,255,255,4,124,172,172,1,142, + 197,197,1,99,137,137,1,184,255,255,1,255,255,255,1,128,128,128,1,208, + 208,208,2,128,128,128,1,184,255,255,1,132,183,183,1,127,176,176,1,132, + 183,183,1,125,173,173,1,94,130,130,1,184,255,255,4,128,128,128,1,184, + 255,255,4,150,208,208,1,155,215,215,1,121,168,168,1,183,254,254,1,255, + 255,255,25,12,0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0, + 0) + ); + +const + objdata_tlookupbuffer: record size: integer; data: array[0..1072] of byte end = + (size: 1073; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,108,111, + 111,107,117,112,98,117,102,102,101,114,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,184,3,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,152,2,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,255,0,2,0, + 0,0,2,0,255,0,2,0,0,0,2,0,255,0,2,0,0,0,2,0, + 255,0,2,0,0,0,2,0,255,0,2,0,0,0,2,0,255,0,2,0, + 0,0,2,190,190,255,11,255,255,255,11,0,0,0,1,0,255,0,1,190, + 190,255,11,255,255,255,1,0,0,0,3,255,255,255,1,0,0,0,5,255, + 255,255,1,0,255,0,2,190,190,255,11,255,255,255,11,0,255,0,1,0, + 0,0,1,190,190,255,9,0,0,255,1,190,190,255,1,255,255,255,1,0, + 0,0,3,255,255,255,1,0,0,0,2,255,255,255,4,0,0,0,2,190, + 190,255,9,0,0,255,2,255,255,255,11,0,0,0,1,0,255,0,1,190, + 190,255,8,0,0,255,4,0,0,0,3,255,255,255,1,0,0,0,3,255, + 255,255,3,0,255,0,2,190,190,255,7,0,0,255,1,190,190,255,1,0, + 0,255,2,255,255,255,11,0,255,0,1,0,0,0,1,190,190,255,7,0, + 0,255,1,190,190,255,1,0,0,255,1,190,190,255,1,255,255,255,1,0, + 0,0,3,255,255,255,1,0,0,0,4,255,255,255,2,0,0,0,2,190, + 190,255,7,0,0,255,1,190,190,255,3,255,255,255,11,0,0,0,1,0, + 255,0,1,190,190,255,7,0,0,255,1,190,190,255,3,255,255,255,1,0, + 0,0,3,255,255,255,1,0,0,0,2,255,255,255,4,0,255,0,2,190, + 190,255,7,0,0,255,1,190,190,255,3,255,255,255,11,0,255,0,1,0, + 0,0,1,190,190,255,7,0,0,255,1,190,190,255,3,255,255,255,1,0, + 0,0,3,255,255,255,1,0,0,0,5,255,255,255,1,0,0,0,2,190, + 190,255,1,0,0,0,3,190,190,255,3,0,0,255,1,190,190,255,3,255, + 255,255,11,0,0,0,1,0,255,0,1,190,190,255,7,0,0,255,1,190, + 190,255,3,255,255,255,1,0,0,0,3,255,255,255,1,0,0,0,2,255, + 255,255,4,0,255,0,2,190,190,255,1,0,0,0,3,190,190,255,3,0, + 0,255,1,190,190,255,3,255,255,255,11,0,255,0,1,0,0,0,1,190, + 190,255,7,0,0,255,1,190,190,255,3,255,255,255,11,0,0,0,2,190, + 190,255,1,0,0,0,3,190,190,255,1,0,0,255,2,190,190,255,4,255, + 255,255,11,0,0,0,1,0,255,0,1,190,190,255,11,255,255,255,11,0, + 255,0,2,190,190,255,1,0,0,0,3,190,190,255,7,255,255,255,11,0, + 255,0,1,0,0,0,1,190,190,255,11,255,255,255,11,0,0,0,2,190, + 190,255,11,255,255,255,11,0,0,0,1,0,255,0,1,190,190,255,11,255, + 255,255,11,0,255,0,2,0,0,0,2,0,255,0,2,0,0,0,2,0, + 255,0,2,0,0,0,2,0,255,0,2,0,0,0,2,0,255,0,2,0, + 0,0,2,0,255,0,2,0,0,0,2,0,255,0,1,232,0,0,0,0, + 0,0,1,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0,2,255, + 255,255,2,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,2,0, + 0,0,2,255,255,255,2,0,0,0,2,255,255,255,22,0,0,0,1,255, + 255,255,48,0,0,0,1,255,255,255,22,0,0,0,2,255,255,255,22,0, + 0,0,1,255,255,255,48,0,0,0,1,255,255,255,22,0,0,0,2,255, + 255,255,22,0,0,0,1,255,255,255,48,0,0,0,1,255,255,255,22,0, + 0,0,2,255,255,255,22,0,0,0,1,255,255,255,48,0,0,0,1,255, + 255,255,22,0,0,0,2,255,255,255,22,0,0,0,1,255,255,255,48,0, + 0,0,1,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,1,255, + 255,255,25,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,2,0, + 0,0,2,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0,2,255, + 255,255,2,0,0,0,2,255,255,255,1,0,0) + ); + +const + objdata_tdblookupbuffer: record size: integer; data: array[0..1074] of byte end = + (size: 1075; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,100,98, + 108,111,111,107,117,112,98,117,102,102,101,114,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,184,3,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,152,2,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,255,0, + 2,0,0,0,2,0,255,0,2,0,0,0,2,0,255,0,2,0,0,0, + 2,0,255,0,2,0,0,0,2,0,255,0,2,0,0,0,2,0,255,0, + 2,0,0,0,2,190,190,255,11,190,255,255,11,0,0,0,1,0,255,0, + 1,190,190,255,11,190,255,255,1,0,0,0,3,190,255,255,1,0,0,0, + 5,190,255,255,1,0,255,0,2,190,190,255,11,190,255,255,11,0,255,0, + 1,0,0,0,1,190,190,255,9,0,0,255,1,190,190,255,1,190,255,255, + 1,0,0,0,3,190,255,255,1,0,0,0,2,190,255,255,4,0,0,0, + 2,190,190,255,9,0,0,255,2,190,255,255,11,0,0,0,1,0,255,0, + 1,190,190,255,8,0,0,255,4,0,0,0,3,190,255,255,1,0,0,0, + 3,190,255,255,3,0,255,0,2,190,190,255,7,0,0,255,1,190,190,255, + 1,0,0,255,2,190,255,255,11,0,255,0,1,0,0,0,1,190,190,255, + 7,0,0,255,1,190,190,255,1,0,0,255,1,190,190,255,1,190,255,255, + 1,0,0,0,3,190,255,255,1,0,0,0,4,190,255,255,2,0,0,0, + 2,190,190,255,7,0,0,255,1,190,190,255,3,190,255,255,11,0,0,0, + 1,0,255,0,1,190,190,255,7,0,0,255,1,190,190,255,3,190,255,255, + 1,0,0,0,3,190,255,255,1,0,0,0,2,190,255,255,4,0,255,0, + 2,190,190,255,7,0,0,255,1,190,190,255,3,190,255,255,11,0,255,0, + 1,0,0,0,1,190,190,255,7,0,0,255,1,190,190,255,3,190,255,255, + 1,0,0,0,3,190,255,255,1,0,0,0,5,190,255,255,1,0,0,0, + 2,190,190,255,1,0,0,0,3,190,190,255,3,0,0,255,1,190,190,255, + 3,190,255,255,11,0,0,0,1,0,255,0,1,190,190,255,7,0,0,255, + 1,190,190,255,3,190,255,255,1,0,0,0,3,190,255,255,1,0,0,0, + 2,190,255,255,4,0,255,0,2,190,190,255,1,0,0,0,3,190,190,255, + 3,0,0,255,1,190,190,255,3,190,255,255,11,0,255,0,1,0,0,0, + 1,190,190,255,7,0,0,255,1,190,190,255,3,190,255,255,11,0,0,0, + 2,190,190,255,1,0,0,0,3,190,190,255,1,0,0,255,2,190,190,255, + 4,190,255,255,11,0,0,0,1,0,255,0,1,190,190,255,11,190,255,255, + 11,0,255,0,2,190,190,255,1,0,0,0,3,190,190,255,7,190,255,255, + 11,0,255,0,1,0,0,0,1,190,190,255,11,190,255,255,11,0,0,0, + 2,190,190,255,11,190,255,255,11,0,0,0,1,0,255,0,1,190,190,255, + 11,190,255,255,11,0,255,0,2,0,0,0,2,0,255,0,2,0,0,0, + 2,0,255,0,2,0,0,0,2,0,255,0,2,0,0,0,2,0,255,0, + 2,0,0,0,2,0,255,0,2,0,0,0,2,0,255,0,1,232,0,0, + 0,0,0,0,1,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0, + 2,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255, + 2,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,22,0,0,0, + 1,255,255,255,48,0,0,0,1,255,255,255,22,0,0,0,2,255,255,255, + 22,0,0,0,1,255,255,255,48,0,0,0,1,255,255,255,22,0,0,0, + 2,255,255,255,22,0,0,0,1,255,255,255,48,0,0,0,1,255,255,255, + 22,0,0,0,2,255,255,255,22,0,0,0,1,255,255,255,48,0,0,0, + 1,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,1,255,255,255, + 48,0,0,0,1,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0, + 1,255,255,255,25,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255, + 2,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0, + 2,255,255,255,2,0,0,0,2,255,255,255,1,0,0) + ); + +const + objdata_tdbmemolookupbuffer: record size: integer; data: array[0..1262] of byte end = + (size: 1263; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,100,98, + 109,101,109,111,108,111,111,107,117,112,98,117,102,102,101,114,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,112,4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,80,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,0,255,0,2,0,0,0,2,0,255,0,2,0,0,0,2,0,255,0, + 2,0,0,0,2,0,255,0,2,0,0,0,2,0,255,0,2,0,0,0, + 2,0,255,0,2,0,0,0,2,190,190,255,11,190,255,255,11,0,0,0, + 1,0,255,0,1,190,190,255,11,190,255,255,1,0,0,0,3,190,255,255, + 1,0,0,0,5,190,255,255,1,0,255,0,2,190,190,255,11,190,255,255, + 11,0,255,0,1,0,0,0,1,190,190,255,9,0,0,255,1,190,190,255, + 1,190,255,255,1,0,0,0,3,190,255,255,1,0,0,0,2,190,255,255, + 4,0,0,0,2,190,190,255,9,0,0,255,2,190,255,255,11,0,0,0, + 1,0,255,0,1,190,190,255,8,0,0,255,4,0,0,0,3,190,255,255, + 1,0,0,0,3,190,255,255,3,0,255,0,2,190,190,255,7,0,0,255, + 1,190,190,255,1,0,0,255,2,190,255,255,11,0,255,0,1,0,0,0, + 1,190,190,255,7,0,0,255,1,190,190,255,1,0,0,255,1,190,190,255, + 1,190,255,255,1,0,0,0,3,190,255,255,1,0,0,0,4,190,255,255, + 2,0,0,0,2,190,190,255,7,0,0,255,1,190,190,255,3,190,255,255, + 11,0,0,0,1,0,255,0,1,190,190,255,7,0,0,255,1,190,190,255, + 3,190,255,255,1,0,0,0,3,190,255,255,1,0,0,0,2,190,255,255, + 4,0,255,0,2,190,190,255,7,0,0,255,1,190,190,255,3,190,255,255, + 11,0,255,0,1,0,0,0,1,190,190,255,7,0,0,255,1,190,190,255, + 3,190,255,255,2,0,0,0,1,60,81,81,1,190,255,255,3,71,95,95, + 1,0,0,0,1,190,255,255,2,0,0,0,2,190,190,255,1,0,0,0, + 3,190,190,255,3,0,0,255,1,190,190,255,3,190,255,255,2,0,0,0, + 1,33,44,44,1,162,218,218,1,190,255,255,1,172,231,231,1,37,49,49, + 1,0,0,0,1,190,255,255,2,0,0,0,1,0,255,0,1,190,190,255, + 7,0,0,255,1,190,190,255,3,190,255,255,2,0,0,0,1,115,154,154, + 1,77,103,103,1,190,255,255,1,93,125,125,1,117,157,157,1,0,0,0, + 1,190,255,255,2,0,255,0,2,190,190,255,1,0,0,0,3,190,190,255, + 3,0,0,255,1,190,190,255,3,190,255,255,2,0,0,0,1,184,247,247, + 1,22,30,30,1,168,225,225,1,33,44,44,1,185,248,248,1,0,0,0, + 1,190,255,255,2,0,255,0,1,0,0,0,1,190,190,255,7,0,0,255, + 1,190,190,255,3,190,255,255,2,0,0,0,1,190,255,255,1,95,127,127, + 1,31,42,42,1,98,131,131,1,190,255,255,1,0,0,0,1,190,255,255, + 2,0,0,0,2,190,190,255,1,0,0,0,3,190,190,255,1,0,0,255, + 2,190,190,255,4,190,255,255,2,0,0,0,1,190,255,255,1,174,233,233, + 1,13,18,18,1,176,236,236,1,190,255,255,1,0,0,0,1,190,255,255, + 2,0,0,0,1,0,255,0,1,190,190,255,11,190,255,255,2,0,0,0, + 1,190,255,255,5,0,0,0,1,190,255,255,2,0,255,0,2,190,190,255, + 1,0,0,0,3,190,190,255,7,190,255,255,2,0,0,0,1,190,255,255, + 5,0,0,0,1,190,255,255,2,0,255,0,1,0,0,0,1,190,190,255, + 11,190,255,255,11,0,0,0,2,190,190,255,11,190,255,255,11,0,0,0, + 1,0,255,0,1,190,190,255,11,190,255,255,11,0,255,0,2,0,0,0, + 2,0,255,0,2,0,0,0,2,0,255,0,2,0,0,0,2,0,255,0, + 2,0,0,0,2,0,255,0,2,0,0,0,2,0,255,0,2,0,0,0, + 2,0,255,0,1,232,0,0,0,0,0,0,1,255,255,255,2,0,0,0, + 2,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255, + 2,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0, + 2,255,255,255,22,0,0,0,1,255,255,255,48,0,0,0,1,255,255,255, + 22,0,0,0,2,255,255,255,22,0,0,0,1,255,255,255,48,0,0,0, + 1,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,1,255,255,255, + 48,0,0,0,1,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0, + 1,255,255,255,48,0,0,0,1,255,255,255,22,0,0,0,2,255,255,255, + 22,0,0,0,1,255,255,255,48,0,0,0,1,255,255,255,22,0,0,0, + 2,255,255,255,22,0,0,0,1,255,255,255,25,0,0,0,2,255,255,255, + 2,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0, + 2,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255, + 1,0,0) + ); + +const + objdata_tmsedbf: record size: integer; data: array[0..1930] of byte end = + (size: 1931; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,7,116,109,115, + 101,100,98,102,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114, + 101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112, + 46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100, + 13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109, + 97,112,46,105,109,97,103,101,10,24,7,0,0,0,0,0,0,6,0,0, + 0,24,0,0,0,24,0,0,0,212,6,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,132,255,255,1,135,255,255,1,138,255,255,1,140,255,255, + 1,143,255,255,1,146,255,255,1,149,255,255,1,152,255,255,1,155,255,255, + 1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255, + 1,172,255,255,1,174,255,255,1,177,255,255,1,180,255,255,1,183,255,255, + 1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255, + 1,132,255,255,1,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255, + 1,146,255,255,1,149,255,255,1,152,255,255,1,155,255,255,1,157,255,255, + 1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255, + 1,174,255,255,1,177,255,255,1,180,255,255,1,183,255,255,1,186,255,255, + 1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255,255, + 1,135,255,255,1,138,255,255,1,0,0,0,2,3,5,5,1,102,174,174, + 1,152,255,255,1,155,255,255,1,157,255,255,1,0,0,0,2,1,1,1, + 1,16,24,24,1,105,155,155,1,174,255,255,1,177,255,255,1,0,0,0, + 4,191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255,255, + 1,138,255,255,1,0,0,0,1,143,255,255,1,100,174,174,1,6,10,10, + 1,104,174,174,1,155,255,255,1,157,255,255,1,0,0,0,1,163,255,255, + 1,165,253,253,1,129,194,194,1,9,13,13,1,174,255,255,1,177,255,255, + 1,0,0,0,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255, + 1,194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255,255, + 1,0,0,0,1,143,255,255,1,146,255,255,1,102,174,174,1,3,5,5, + 1,155,255,255,1,157,255,255,1,0,0,0,1,163,255,255,1,165,254,254, + 1,131,197,197,1,71,106,106,1,174,255,255,1,177,255,255,1,0,0,0, + 1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255, + 1,197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1,0,0,0, + 1,143,255,255,1,146,255,255,1,149,255,255,1,0,0,0,1,155,255,255, + 1,157,255,255,1,0,0,0,4,82,122,122,1,174,255,255,1,177,255,255, + 1,0,0,0,3,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255, + 1,132,255,255,1,135,255,255,1,138,255,255,1,0,0,0,1,143,255,255, + 1,146,255,255,1,102,174,174,1,3,5,5,1,155,255,255,1,157,255,255, + 1,0,0,0,1,163,255,255,1,165,254,254,1,144,217,217,1,8,12,12, + 1,174,255,255,1,177,255,255,1,0,0,0,1,183,255,255,1,186,255,255, + 1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255,255, + 1,135,255,255,1,138,255,255,1,0,0,0,1,143,255,255,1,100,174,174, + 1,6,10,10,1,104,174,174,1,155,255,255,1,157,255,255,1,0,0,0, + 1,163,255,255,1,166,255,255,1,129,195,195,1,21,31,31,1,174,255,255, + 1,177,255,255,1,0,0,0,1,183,255,255,1,186,255,255,1,189,255,255, + 1,191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255,255, + 1,138,255,255,1,0,0,0,2,3,5,5,1,102,174,174,1,152,255,255, + 1,155,255,255,1,157,255,255,1,0,0,0,2,1,1,1,1,21,31,31, + 1,121,180,180,1,174,255,255,1,177,255,255,1,0,0,0,1,183,255,255, + 1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255, + 1,132,255,255,1,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255, + 1,146,255,255,1,149,255,255,1,152,255,255,1,155,255,255,1,157,255,255, + 1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255, + 1,174,255,255,1,177,255,255,1,180,255,255,1,183,255,255,1,186,255,255, + 1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255,255, + 1,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255, + 1,149,255,255,1,152,255,255,1,155,255,255,1,157,255,255,1,160,255,255, + 1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255,255, + 1,177,255,255,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255, + 1,191,255,255,1,194,255,255,1,197,255,255,1,128,128,128,25,135,255,255, + 1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255, + 1,128,128,128,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255, + 1,166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,128,128,128, + 1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255, + 1,194,255,255,1,128,128,128,2,135,255,255,1,138,255,255,1,140,255,255, + 1,143,255,255,1,146,255,255,1,149,255,255,1,128,128,128,1,155,255,255, + 1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255, + 1,172,255,255,1,174,255,255,1,128,128,128,1,180,255,255,1,183,255,255, + 1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,128,128,128, + 26,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255, + 1,149,255,255,1,128,128,128,1,155,255,255,1,157,255,255,1,160,255,255, + 1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255,255, + 1,128,128,128,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255, + 1,191,255,255,1,194,255,255,1,128,128,128,2,135,255,255,1,138,255,255, + 1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,128,128,128, + 1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255, + 1,169,255,255,1,172,255,255,1,174,255,255,1,128,128,128,1,180,255,255, + 1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255, + 1,128,128,128,26,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255, + 1,146,255,255,1,149,255,255,1,128,128,128,1,155,255,255,1,157,255,255, + 1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255, + 1,174,255,255,1,128,128,128,1,180,255,255,1,183,255,255,1,186,255,255, + 1,189,255,255,1,191,255,255,1,194,255,255,1,128,128,128,2,135,255,255, + 1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255, + 1,128,128,128,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255, + 1,166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,128,128,128, + 1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255, + 1,194,255,255,1,128,128,128,26,135,255,255,1,138,255,255,1,140,255,255, + 1,143,255,255,1,146,255,255,1,149,255,255,1,128,128,128,1,155,255,255, + 1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255, + 1,172,255,255,1,174,255,255,1,128,128,128,1,180,255,255,1,183,255,255, + 1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,128,128,128, + 2,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255, + 1,149,255,255,1,128,128,128,1,155,255,255,1,157,255,255,1,160,255,255, + 1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255,255, + 1,128,128,128,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255, + 1,191,255,255,1,194,255,255,1,128,128,128,25,12,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tmsefixedformatdataset: record size: integer; data: array[0..1973] of byte end = + (size: 1974; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,22,116,109,115, + 101,102,105,120,101,100,102,111,114,109,97,116,100,97,116,97,115,101,116,23, + 98,105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111, + 108,111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105, + 111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95, + 99,111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109, + 97,103,101,10,52,7,0,0,0,0,0,0,6,0,0,0,24,0,0,0, + 24,0,0,0,240,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 132,255,255,1,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1, + 146,255,255,1,149,255,255,1,152,255,255,1,155,255,255,1,157,255,255,1, + 160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1, + 174,255,255,1,177,255,255,1,180,255,255,1,183,255,255,1,186,255,255,1, + 189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1, + 135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1, + 149,255,255,1,152,255,255,1,155,255,255,1,157,255,255,1,160,255,255,1, + 163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1, + 177,255,255,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1, + 191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1, + 138,255,255,1,140,255,255,1,143,255,255,1,0,0,0,4,157,255,255,1, + 160,255,255,1,0,0,0,1,166,255,255,1,169,255,255,1,69,103,103,1, + 115,168,168,1,177,255,255,1,119,168,168,1,74,103,103,1,186,255,255,1, + 189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1, + 135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,0,0,0,1, + 149,255,255,1,152,255,255,1,155,255,255,1,157,255,255,1,160,255,255,1, + 0,0,0,1,166,255,255,1,169,255,255,1,169,250,250,1,52,76,76,1, + 135,195,195,1,52,74,74,1,179,249,249,1,186,255,255,1,189,255,255,1, + 191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1, + 138,255,255,1,140,255,255,1,143,255,255,1,0,0,0,1,149,255,255,1, + 152,255,255,1,155,255,255,1,157,255,255,1,160,255,255,1,0,0,0,1, + 166,255,255,1,169,255,255,1,172,255,255,1,158,232,232,1,31,45,45,1, + 163,231,231,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1, + 194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1, + 140,255,255,1,143,255,255,1,0,0,0,3,155,255,255,1,157,255,255,1, + 160,255,255,1,0,0,0,1,166,255,255,1,169,255,255,1,172,255,255,1, + 124,181,181,1,35,51,51,1,126,179,179,1,183,255,255,1,186,255,255,1, + 189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1, + 135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,0,0,0,1, + 149,255,255,1,152,255,255,1,155,255,255,1,157,255,255,1,160,255,255,1, + 0,0,0,1,166,255,255,1,169,255,255,1,150,222,222,1,53,78,78,1, + 173,249,249,1,56,80,80,1,159,222,222,1,186,255,255,1,189,255,255,1, + 191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1, + 138,255,255,1,140,255,255,1,143,255,255,1,0,0,0,1,149,255,255,1, + 152,255,255,1,155,255,255,1,157,255,255,1,160,255,255,1,0,0,0,1, + 166,255,255,1,164,247,247,1,45,66,66,1,153,224,224,1,177,255,255,1, + 159,225,225,1,47,66,66,1,180,247,247,1,189,255,255,1,191,255,255,1, + 194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1, + 140,255,255,1,143,255,255,1,0,0,0,1,149,255,255,1,152,255,255,1, + 155,255,255,1,157,255,255,1,160,255,255,1,0,0,0,1,166,255,255,1, + 66,99,99,1,113,168,168,1,174,255,255,1,177,255,255,1,180,255,255,1, + 121,168,168,1,72,99,99,1,189,255,255,1,191,255,255,1,194,255,255,1, + 197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1,140,255,255,1, + 143,255,255,1,146,255,255,1,149,255,255,1,152,255,255,1,155,255,255,1, + 157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1, + 172,255,255,1,174,255,255,1,177,255,255,1,180,255,255,1,183,255,255,1, + 186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1, + 132,255,255,1,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1, + 146,255,255,1,149,255,255,1,152,255,255,1,155,255,255,1,157,255,255,1, + 160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1, + 174,255,255,1,177,255,255,1,180,255,255,1,183,255,255,1,186,255,255,1, + 189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,128,128,128,25, + 135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1, + 149,255,255,1,128,128,128,1,155,255,255,1,157,255,255,1,160,255,255,1, + 163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1, + 128,128,128,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1, + 191,255,255,1,194,255,255,1,128,128,128,2,135,255,255,1,138,255,255,1, + 140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,128,128,128,1, + 155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1, + 169,255,255,1,172,255,255,1,174,255,255,1,128,128,128,1,180,255,255,1, + 183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1, + 128,128,128,26,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1, + 146,255,255,1,149,255,255,1,128,128,128,1,155,255,255,1,157,255,255,1, + 160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1, + 174,255,255,1,128,128,128,1,180,255,255,1,183,255,255,1,186,255,255,1, + 189,255,255,1,191,255,255,1,194,255,255,1,128,128,128,2,135,255,255,1, + 138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1, + 128,128,128,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1, + 166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,128,128,128,1, + 180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1, + 194,255,255,1,128,128,128,26,135,255,255,1,138,255,255,1,140,255,255,1, + 143,255,255,1,146,255,255,1,149,255,255,1,128,128,128,1,155,255,255,1, + 157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1, + 172,255,255,1,174,255,255,1,128,128,128,1,180,255,255,1,183,255,255,1, + 186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,128,128,128,2, + 135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1, + 149,255,255,1,128,128,128,1,155,255,255,1,157,255,255,1,160,255,255,1, + 163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1, + 128,128,128,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1, + 191,255,255,1,194,255,255,1,128,128,128,26,135,255,255,1,138,255,255,1, + 140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,128,128,128,1, + 155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1, + 169,255,255,1,172,255,255,1,174,255,255,1,128,128,128,1,180,255,255,1, + 183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1, + 128,128,128,2,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1, + 146,255,255,1,149,255,255,1,128,128,128,1,155,255,255,1,157,255,255,1, + 160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1, + 174,255,255,1,128,128,128,1,180,255,255,1,183,255,255,1,186,255,255,1, + 189,255,255,1,191,255,255,1,194,255,255,1,128,128,128,25,12,0,0,0, + 255,255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tmsesdfdataset: record size: integer; data: array[0..1957] of byte end = + (size: 1958; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,109,115, + 101,115,100,102,100,97,116,97,115,101,116,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,44,7,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,232,6,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,132,255,255,1,135,255,255,1, + 138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1, + 152,255,255,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1, + 166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1, + 180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1, + 194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1, + 140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,152,255,255,1, + 155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1, + 169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1,180,255,255,1, + 183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1, + 197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1,98,179,179,1, + 20,36,36,1,3,5,5,1,27,46,46,1,115,193,193,1,155,255,255,1, + 157,255,255,1,0,0,0,2,3,5,5,1,115,174,174,1,172,255,255,1, + 174,255,255,1,177,255,255,1,0,0,0,4,191,255,255,1,194,255,255,1, + 197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1,12,21,21,1, + 105,187,187,1,143,249,249,1,103,176,176,1,18,30,30,1,155,255,255,1, + 157,255,255,1,0,0,0,1,163,255,255,1,113,174,174,1,7,10,10,1, + 117,174,174,1,174,255,255,1,177,255,255,1,0,0,0,1,183,255,255,1, + 186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1, + 132,255,255,1,135,255,255,1,138,255,255,1,25,46,46,1,85,152,152,1, + 137,240,240,1,149,255,255,1,152,255,255,1,155,255,255,1,157,255,255,1, + 0,0,0,1,163,255,255,1,166,255,255,1,115,174,174,1,3,5,5,1, + 174,255,255,1,177,255,255,1,0,0,0,1,183,255,255,1,186,255,255,1, + 189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1, + 135,255,255,1,138,255,255,1,128,234,234,1,70,124,124,1,31,54,54,1, + 34,58,58,1,117,196,196,1,155,255,255,1,157,255,255,1,0,0,0,1, + 163,255,255,1,166,255,255,1,169,255,255,1,0,0,0,1,174,255,255,1, + 177,255,255,1,0,0,0,3,189,255,255,1,191,255,255,1,194,255,255,1, + 197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1,140,255,255,1, + 143,255,255,1,146,255,255,1,125,214,214,1,15,26,26,1,155,255,255,1, + 157,255,255,1,0,0,0,1,163,255,255,1,166,255,255,1,115,174,174,1, + 3,5,5,1,174,255,255,1,177,255,255,1,0,0,0,1,183,255,255,1, + 186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1, + 132,255,255,1,135,255,255,1,138,255,255,1,16,29,29,1,98,174,174,1, + 143,250,250,1,119,203,203,1,16,27,27,1,155,255,255,1,157,255,255,1, + 0,0,0,1,163,255,255,1,113,174,174,1,7,10,10,1,117,174,174,1, + 174,255,255,1,177,255,255,1,0,0,0,1,183,255,255,1,186,255,255,1, + 189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1, + 135,255,255,1,138,255,255,1,105,191,191,1,25,45,45,1,3,5,5,1, + 22,37,37,1,112,188,188,1,155,255,255,1,157,255,255,1,0,0,0,2, + 3,5,5,1,115,174,174,1,172,255,255,1,174,255,255,1,177,255,255,1, + 0,0,0,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1, + 194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1, + 140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,152,255,255,1, + 155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1, + 169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1,180,255,255,1, + 183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1, + 197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1,140,255,255,1, + 143,255,255,1,146,255,255,1,149,255,255,1,152,255,255,1,155,255,255,1, + 157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1, + 172,255,255,1,174,255,255,1,177,255,255,1,180,255,255,1,183,255,255,1, + 186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1, + 128,128,128,25,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1, + 146,255,255,1,149,255,255,1,128,128,128,1,155,255,255,1,157,255,255,1, + 160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1, + 174,255,255,1,128,128,128,1,180,255,255,1,183,255,255,1,186,255,255,1, + 189,255,255,1,191,255,255,1,194,255,255,1,128,128,128,2,135,255,255,1, + 138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1, + 128,128,128,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1, + 166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,128,128,128,1, + 180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1, + 194,255,255,1,128,128,128,26,135,255,255,1,138,255,255,1,140,255,255,1, + 143,255,255,1,146,255,255,1,149,255,255,1,128,128,128,1,155,255,255,1, + 157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1, + 172,255,255,1,174,255,255,1,128,128,128,1,180,255,255,1,183,255,255,1, + 186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,128,128,128,2, + 135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1, + 149,255,255,1,128,128,128,1,155,255,255,1,157,255,255,1,160,255,255,1, + 163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1, + 128,128,128,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1, + 191,255,255,1,194,255,255,1,128,128,128,26,135,255,255,1,138,255,255,1, + 140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,128,128,128,1, + 155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1, + 169,255,255,1,172,255,255,1,174,255,255,1,128,128,128,1,180,255,255,1, + 183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1, + 128,128,128,2,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1, + 146,255,255,1,149,255,255,1,128,128,128,1,155,255,255,1,157,255,255,1, + 160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1, + 174,255,255,1,128,128,128,1,180,255,255,1,183,255,255,1,186,255,255,1, + 189,255,255,1,191,255,255,1,194,255,255,1,128,128,128,26,135,255,255,1, + 138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1, + 128,128,128,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1, + 166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,128,128,128,1, + 180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1, + 194,255,255,1,128,128,128,2,135,255,255,1,138,255,255,1,140,255,255,1, + 143,255,255,1,146,255,255,1,149,255,255,1,128,128,128,1,155,255,255,1, + 157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1, + 172,255,255,1,174,255,255,1,128,128,128,1,180,255,255,1,183,255,255,1, + 186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,128,128,128,25, + 12,0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tmsememdataset: record size: integer; data: array[0..1957] of byte end = + (size: 1958; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,109,115, + 101,109,101,109,100,97,116,97,115,101,116,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,44,7,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,232,6,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,132,255,255,1,135,255,255,1, + 138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1, + 152,255,255,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1, + 166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1, + 180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1, + 194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1, + 140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,152,255,255,1, + 155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1, + 169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1,180,255,255,1, + 183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1, + 197,255,255,1,132,255,255,1,0,0,0,1,58,107,107,1,140,255,255,1, + 143,255,255,1,146,255,255,1,63,107,107,1,0,0,0,1,155,255,255,1, + 0,0,0,1,35,55,55,2,36,55,55,2,167,248,248,1,174,255,255,1, + 0,0,0,1,76,107,107,1,183,255,255,1,186,255,255,1,189,255,255,1, + 80,107,107,1,0,0,0,1,197,255,255,1,132,255,255,1,0,0,0,1, + 29,54,54,1,138,251,251,1,143,255,255,1,144,251,251,1,32,55,55,1, + 0,0,0,1,155,255,255,1,0,0,0,1,160,255,255,1,163,255,255,1, + 166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,0,0,0,1, + 38,54,54,1,180,251,251,1,186,255,255,1,186,251,251,1,41,55,55,1, + 0,0,0,1,197,255,255,1,132,255,255,1,0,0,0,1,64,119,119,1, + 102,186,186,1,143,255,255,1,108,188,188,1,70,119,119,1,0,0,0,1, + 155,255,255,1,0,0,0,1,160,255,255,1,163,255,255,1,166,255,255,1, + 169,255,255,1,172,255,255,1,174,255,255,1,0,0,0,1,84,119,119,1, + 133,186,186,1,186,255,255,1,139,188,188,1,89,119,119,1,0,0,0,1, + 197,255,255,1,132,255,255,1,0,0,0,1,113,208,208,1,53,97,97,1, + 143,255,255,1,58,101,101,1,121,207,207,1,0,0,0,1,155,255,255,1, + 0,0,0,4,18,27,27,1,172,255,255,1,174,255,255,1,0,0,0,1, + 147,208,208,1,70,97,97,1,186,255,255,1,75,101,101,1,155,207,207,1, + 0,0,0,1,197,255,255,1,132,255,255,1,0,0,0,1,137,254,254,1, + 31,56,56,1,136,243,243,1,33,58,58,1,148,254,254,1,0,0,0,1, + 155,255,255,1,0,0,0,1,160,255,255,1,163,255,255,1,166,255,255,1, + 169,255,255,1,172,255,255,1,174,255,255,1,0,0,0,1,179,254,254,1, + 40,56,56,1,177,243,243,1,43,58,58,1,190,254,254,1,0,0,0,1, + 197,255,255,1,132,255,255,1,0,0,0,1,138,255,255,1,71,129,129,1, + 58,103,103,1,73,127,127,1,149,255,255,1,0,0,0,1,155,255,255,1, + 0,0,0,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1, + 172,255,255,1,174,255,255,1,0,0,0,1,180,255,255,1,93,129,129,1, + 75,103,103,1,94,127,127,1,191,255,255,1,0,0,0,1,197,255,255,1, + 132,255,255,1,0,0,0,1,138,255,255,1,120,218,218,1,0,0,0,1, + 123,214,214,1,149,255,255,1,0,0,0,1,155,255,255,1,0,0,0,1, + 35,55,55,2,36,55,55,2,142,211,211,1,174,255,255,1,0,0,0,1, + 180,255,255,1,156,218,218,1,0,0,0,1,159,214,214,1,191,255,255,1, + 0,0,0,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1, + 140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,152,255,255,1, + 155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1, + 169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1,180,255,255,1, + 183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1, + 197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1,140,255,255,1, + 143,255,255,1,146,255,255,1,149,255,255,1,152,255,255,1,155,255,255,1, + 157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1, + 172,255,255,1,174,255,255,1,177,255,255,1,180,255,255,1,183,255,255,1, + 186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1, + 128,128,128,25,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1, + 146,255,255,1,149,255,255,1,128,128,128,1,155,255,255,1,157,255,255,1, + 160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1, + 174,255,255,1,128,128,128,1,180,255,255,1,183,255,255,1,186,255,255,1, + 189,255,255,1,191,255,255,1,194,255,255,1,128,128,128,2,135,255,255,1, + 138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1, + 128,128,128,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1, + 166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,128,128,128,1, + 180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1, + 194,255,255,1,128,128,128,26,135,255,255,1,138,255,255,1,140,255,255,1, + 143,255,255,1,146,255,255,1,149,255,255,1,128,128,128,1,155,255,255,1, + 157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1, + 172,255,255,1,174,255,255,1,128,128,128,1,180,255,255,1,183,255,255,1, + 186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,128,128,128,2, + 135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1, + 149,255,255,1,128,128,128,1,155,255,255,1,157,255,255,1,160,255,255,1, + 163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1, + 128,128,128,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1, + 191,255,255,1,194,255,255,1,128,128,128,26,135,255,255,1,138,255,255,1, + 140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,128,128,128,1, + 155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1, + 169,255,255,1,172,255,255,1,174,255,255,1,128,128,128,1,180,255,255,1, + 183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1, + 128,128,128,2,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1, + 146,255,255,1,149,255,255,1,128,128,128,1,155,255,255,1,157,255,255,1, + 160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1, + 174,255,255,1,128,128,128,1,180,255,255,1,183,255,255,1,186,255,255,1, + 189,255,255,1,191,255,255,1,194,255,255,1,128,128,128,26,135,255,255,1, + 138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1, + 128,128,128,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1, + 166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,128,128,128,1, + 180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1, + 194,255,255,1,128,128,128,2,135,255,255,1,138,255,255,1,140,255,255,1, + 143,255,255,1,146,255,255,1,149,255,255,1,128,128,128,1,155,255,255,1, + 157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1, + 172,255,255,1,174,255,255,1,128,128,128,1,180,255,255,1,183,255,255,1, + 186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,128,128,128,25, + 12,0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tmsepqconnection: record size: integer; data: array[0..1360] of byte end = + (size: 1361; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,109,115, + 101,112,113,99,111,110,110,101,99,116,105,111,110,12,98,105,116,109,97,112, + 46,105,109,97,103,101,10,28,5,0,0,0,0,0,0,0,0,0,0,24, + 0,0,0,24,0,0,0,232,4,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,255,40,0,0,0,1,3,3,3,1,5,5,5,1,18, + 16,9,1,19,17,9,1,0,0,255,6,23,23,23,1,42,42,42,1,101, + 101,101,1,127,125,122,1,79,75,64,1,24,24,24,1,6,6,6,1,17, + 17,17,1,61,61,61,1,116,116,116,1,129,129,129,1,70,70,70,1,29, + 29,29,1,14,14,14,1,77,77,77,1,126,126,126,1,134,134,134,1,67, + 67,67,1,26,26,26,1,4,4,4,1,0,0,255,3,26,26,26,1,140, + 140,140,1,178,178,178,3,176,176,176,1,126,126,126,1,47,47,47,1,105, + 105,105,1,173,173,173,1,178,178,178,3,167,167,167,1,117,117,117,1,59, + 59,59,1,114,114,114,1,167,167,167,1,178,178,178,1,140,140,140,1,31, + 31,31,1,32,26,11,1,0,0,255,1,4,4,4,1,67,67,67,1,178, + 178,178,4,156,156,156,1,91,91,91,1,105,105,105,1,172,172,172,1,178, + 178,178,6,141,141,141,1,70,70,70,1,118,118,118,1,168,168,168,1,178, + 178,178,1,121,121,121,1,11,10,7,1,0,0,255,1,5,5,5,1,135, + 135,135,1,178,178,178,3,177,177,177,1,132,132,132,1,70,70,70,1,153, + 153,153,1,174,174,174,1,177,177,177,1,178,178,178,5,175,175,175,1,133, + 133,133,1,45,45,45,1,127,127,126,1,174,174,174,1,135,135,135,1,5, + 5,5,1,0,0,255,1,5,5,5,1,135,135,135,1,178,178,178,3,176, + 176,176,1,120,120,120,1,39,39,39,1,117,117,117,1,128,128,128,1,152, + 152,152,1,172,172,172,1,178,178,178,3,177,177,177,1,144,144,144,1,97, + 97,97,1,18,18,18,1,79,78,74,1,168,168,167,1,135,135,135,1,6, + 6,6,1,0,0,255,1,11,11,7,1,135,135,135,1,178,178,178,3,176, + 176,176,1,122,122,122,1,24,24,24,1,44,44,44,1,32,32,32,1,60, + 60,60,1,134,134,134,1,178,178,178,3,156,156,156,1,64,64,64,1,9, + 9,9,1,10,10,10,1,42,41,39,1,162,162,161,1,122,122,122,1,14, + 12,8,1,0,0,255,1,29,26,15,1,129,129,129,1,178,178,178,3,176, + 176,176,1,133,133,133,1,67,67,67,1,97,97,97,1,64,64,64,1,33, + 33,33,1,98,98,98,1,178,178,178,3,109,109,109,1,32,32,32,1,41, + 41,41,1,56,56,56,1,90,90,90,1,168,168,168,1,72,72,72,1,0, + 0,255,3,86,86,86,1,178,178,178,3,176,176,176,1,142,142,142,1,109, + 109,109,1,173,173,173,1,161,161,161,1,110,110,110,1,107,107,107,1,168, + 168,168,1,178,178,178,2,109,109,109,1,56,56,56,1,127,127,127,1,91, + 91,91,1,130,130,130,1,157,157,157,1,28,28,28,1,0,0,255,3,33, + 33,33,1,178,178,178,3,173,173,173,1,133,133,133,1,109,109,109,1,178, + 178,178,2,127,127,127,1,93,92,90,1,152,151,149,1,178,178,178,2,135, + 135,135,1,60,60,60,1,126,126,126,1,91,91,91,1,130,130,130,1,114, + 114,114,1,18,18,18,1,0,0,255,3,29,29,29,1,154,154,154,1,178, + 178,178,2,163,163,161,1,105,103,98,1,109,109,109,1,178,178,178,1,172, + 172,172,1,110,110,110,1,98,96,93,1,165,164,161,1,178,178,178,2,174, + 174,174,1,82,82,82,1,81,81,81,1,101,101,101,1,128,128,128,1,69, + 69,69,1,0,0,255,5,111,111,111,1,178,178,178,2,167,166,164,1,103, + 101,96,1,78,78,78,1,166,166,166,1,162,162,162,1,90,90,90,1,105, + 105,105,1,178,178,178,4,131,131,131,1,55,55,55,1,48,48,48,1,60, + 60,60,1,28,28,28,1,0,0,255,5,65,65,65,1,169,169,169,1,178, + 178,178,1,177,177,177,1,134,134,134,1,59,59,59,1,122,122,122,1,133, + 133,133,1,80,80,80,1,126,126,126,1,178,178,178,4,98,98,98,1,23, + 23,23,1,2,2,2,1,0,0,0,1,0,0,255,6,19,19,19,1,84, + 84,84,1,178,178,178,1,177,177,177,1,142,142,142,1,63,63,63,1,72, + 72,72,1,60,60,60,1,30,30,30,1,95,95,95,1,164,164,164,1,178, + 178,178,3,52,52,52,1,0,0,0,3,0,0,255,7,11,11,11,1,67, + 67,67,1,76,76,76,1,80,80,80,1,41,41,41,1,61,61,61,1,80, + 80,80,1,255,255,255,1,134,134,134,1,146,146,146,1,178,178,178,3,52, + 52,52,1,0,0,0,4,0,0,255,8,31,31,31,1,15,15,15,1,12, + 11,11,1,28,27,23,1,255,255,255,2,105,105,105,1,142,142,142,1,178, + 178,178,3,52,52,52,1,255,255,255,3,22,22,22,1,0,0,255,11,5, + 4,1,1,45,44,42,1,54,54,54,1,58,58,58,1,142,142,142,1,178, + 178,178,3,118,118,118,1,79,79,79,1,74,74,74,2,17,17,17,1,0, + 0,255,14,58,58,58,1,142,142,142,1,178,178,178,3,145,145,145,1,33, + 33,33,1,0,0,255,17,61,61,61,1,142,142,142,1,178,178,178,3,145, + 145,145,1,33,33,33,1,0,0,255,17,90,90,90,1,142,142,142,1,178, + 178,178,3,145,145,145,1,33,33,33,1,0,0,255,17,40,40,40,1,103, + 103,103,1,169,169,169,1,178,178,178,2,64,64,64,1,4,4,4,1,0, + 0,255,18,40,38,29,1,109,107,100,1,135,135,135,1,220,220,220,1,6, + 6,6,1,0,0,255,20,14,12,7,1,6,6,6,1,0,0,255,8,0, + 0) + ); + +const + objdata_tmseodbcconnection: record size: integer; data: array[0..1561] of byte end = + (size: 1562; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,18,116,109,115, + 101,111,100,98,99,99,111,110,110,101,99,116,105,111,110,23,98,105,116,109, + 97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4, + 6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11, + 10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111, + 114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10, + 156,5,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0, + 36,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,208,208,208,31, + 255,28,28,1,255,34,23,1,255,34,21,1,255,34,22,3,255,34,23,1, + 255,34,21,1,255,33,23,1,255,28,28,1,208,208,208,13,255,36,24,1, + 255,34,22,9,255,33,22,1,254,28,41,1,249,0,162,1,208,208,208,9, + 255,23,23,1,255,35,23,1,255,34,22,11,251,9,122,1,249,0,162,2, + 208,208,208,7,255,28,28,1,255,34,22,12,253,24,66,1,249,0,162,4, + 208,208,208,6,255,34,21,1,255,34,22,11,255,32,29,1,249,1,159,1, + 249,0,162,5,208,208,208,4,255,35,24,1,255,34,22,8,255,35,22,1, + 255,34,22,3,250,6,136,1,249,0,162,6,208,208,208,3,255,32,32,1, + 255,34,22,7,255,35,22,1,255,64,0,1,208,208,208,2,255,43,43,1, + 252,15,95,1,249,0,162,8,208,208,208,2,255,36,22,1,255,34,22,6, + 255,36,22,1,208,208,208,6,249,0,162,8,208,208,208,2,255,33,21,1, + 255,34,22,5,255,35,22,1,208,208,208,8,249,0,162,7,208,208,208,2, + 255,34,23,1,255,34,22,5,208,208,208,10,249,0,162,6,208,208,208,2, + 255,34,22,5,255,35,22,1,208,208,208,10,249,0,162,7,208,208,208,1, + 255,34,22,4,241,44,35,1,223,57,51,1,208,208,208,10,249,0,162,7, + 208,208,208,1,48,182,211,1,21,202,236,1,11,208,245,1,3,214,252,1, + 0,216,255,1,13,206,243,1,208,208,208,10,249,0,162,6,208,208,208,2, + 0,216,255,6,0,223,255,1,208,208,208,8,249,0,162,7,208,208,208,2, + 0,216,255,6,0,217,255,1,208,208,208,7,249,0,162,8,208,208,208,2, + 0,216,255,7,0,217,255,1,0,221,255,1,208,208,208,4,0,216,255,1, + 180,60,188,1,249,0,162,7,208,208,208,2,0,213,255,1,0,216,255,13, + 1,215,255,1,204,39,179,1,249,0,162,5,208,208,208,4,0,214,255,1, + 0,216,255,13,3,213,254,1,218,28,174,1,249,0,162,4,208,208,208,5, + 0,215,255,1,0,216,255,13,8,209,252,1,227,20,170,1,249,0,162,2, + 208,208,208,7,0,217,255,1,0,216,255,13,65,160,231,1,249,0,162,1, + 208,208,208,9,0,215,255,1,0,216,255,12,208,208,208,13,0,214,255,1, + 0,216,255,1,0,215,255,1,0,216,255,4,0,215,255,1,0,213,255,1, + 208,208,208,32,64,3,0,0,0,0,0,31,9,9,9,1,67,67,67,1, + 120,120,120,1,172,172,172,1,224,224,224,1,240,240,240,1,204,204,204,1, + 167,167,167,1,101,101,101,1,9,9,9,1,0,0,0,13,64,64,64,1, + 222,222,222,1,255,255,255,8,236,236,236,1,125,125,125,1,10,10,10,1, + 0,0,0,9,11,11,11,1,147,147,147,1,254,254,254,1,255,255,255,9, + 253,253,253,1,215,215,215,1,210,210,210,1,36,36,36,1,0,0,0,7, + 9,9,9,1,211,211,211,1,255,255,255,11,195,195,195,1,255,255,255,2, + 240,240,240,1,45,45,45,1,0,0,0,6,144,144,144,1,255,255,255,11, + 216,216,216,1,251,251,251,1,255,255,255,3,217,217,217,1,13,13,13,1, + 0,0,0,4,65,65,65,1,254,254,254,1,255,255,255,6,247,247,247,1, + 199,199,199,1,193,193,193,1,247,247,247,1,246,246,246,1,223,223,223,1, + 255,255,255,5,157,157,157,1,0,0,0,3,8,8,8,1,224,224,224,1, + 255,255,255,5,242,242,242,1,103,103,103,1,4,4,4,1,0,0,0,2, + 6,6,6,1,66,66,66,1,234,234,234,1,255,255,255,5,250,250,250,1, + 25,25,25,1,0,0,0,2,57,57,57,1,255,255,255,5,240,240,240,1, + 35,35,35,1,0,0,0,6,37,37,37,1,222,222,222,1,255,255,255,5, + 127,127,127,1,0,0,0,2,108,108,108,1,255,255,255,5,94,94,94,1, + 0,0,0,8,40,40,40,1,255,255,255,5,205,205,205,1,0,0,0,2, + 158,158,158,1,255,255,255,4,237,237,237,1,0,0,0,10,216,216,216,1, + 255,255,255,4,239,239,239,1,0,0,0,2,209,209,209,1,255,255,255,4, + 184,184,184,1,0,0,0,10,142,142,142,1,255,255,255,5,17,17,17,1, + 0,0,0,1,244,244,244,1,255,255,255,4,160,160,160,1,0,0,0,10, + 121,121,121,1,255,255,255,5,14,14,14,1,0,0,0,1,165,165,165,1, + 217,217,217,1,232,232,232,1,249,249,249,1,255,255,255,1,207,207,207,1, + 0,0,0,10,184,184,184,1,255,255,255,4,238,238,238,1,0,0,0,2, + 155,155,155,1,255,255,255,4,250,250,250,1,16,16,16,1,0,0,0,8, + 16,16,16,1,243,243,243,1,255,255,255,4,197,197,197,1,0,0,0,2, + 110,110,110,1,255,255,255,5,166,166,166,1,0,0,0,7,8,8,8,1, + 193,193,193,1,255,255,255,5,105,105,105,1,0,0,0,2,65,65,65,1, + 255,255,255,6,153,153,153,1,15,15,15,1,0,0,0,4,26,26,26,1, + 141,141,141,1,255,255,255,5,245,245,245,1,16,16,16,1,0,0,0,2, + 12,12,12,1,222,222,222,1,255,255,255,6,234,234,234,1,163,163,163,1, + 110,110,110,1,125,125,125,1,170,170,170,1,249,249,249,1,234,234,234,1, + 212,212,212,1,255,255,255,4,116,116,116,1,0,0,0,4,50,50,50,1, + 248,248,248,1,255,255,255,12,229,229,229,1,230,230,230,1,255,255,255,2, + 200,200,200,1,3,3,3,1,0,0,0,5,103,103,103,1,255,255,255,13, + 224,224,224,1,245,245,245,1,211,211,211,1,23,23,23,1,0,0,0,7, + 114,114,114,1,240,240,240,1,255,255,255,11,252,252,252,1,145,145,145,1, + 19,19,19,1,0,0,0,9,19,19,19,1,144,144,144,1,249,249,249,1, + 255,255,255,7,254,254,254,1,190,190,190,1,46,46,46,1,0,0,0,13, + 31,31,31,1,91,91,91,1,128,128,128,1,165,165,165,1,202,202,202,1, + 198,198,198,1,138,138,138,1,77,77,77,1,18,18,18,1,0,0,0,32, + 0,0) + ); + +const + objdata_tmsemysqlconnection: record size: integer; data: array[0..1746] of byte end = + (size: 1747; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,109,115, + 101,109,121,115,113,108,99,111,110,110,101,99,116,105,111,110,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,84,6,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,84,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255, + 24,143,104,0,1,160,116,0,1,169,123,0,1,164,119,0,1,157,114,0, + 1,143,104,0,1,255,255,255,18,143,104,0,1,188,137,0,1,204,149,1, + 1,205,150,2,1,214,156,0,1,184,134,0,1,166,121,0,1,158,115,0, + 1,149,108,0,1,255,255,255,16,164,119,0,1,209,152,1,1,183,155,80, + 1,191,161,81,1,184,144,39,1,204,150,6,1,224,163,0,1,197,144,0, + 1,161,117,0,1,143,104,0,1,255,255,255,14,153,111,0,1,198,144,0, + 1,183,146,49,1,255,255,255,1,255,254,254,1,218,203,163,1,185,150,58, + 1,197,146,11,1,224,163,0,1,170,124,0,1,147,107,0,1,255,255,255, + 14,164,120,0,1,198,147,9,1,227,217,189,1,231,222,197,1,177,138,34, + 1,212,194,143,1,225,213,180,1,182,142,37,1,220,160,0,1,168,123,2, + 1,143,104,0,1,255,255,255,13,152,111,0,1,203,148,3,1,187,156,71, + 1,235,227,206,1,181,141,32,1,178,143,51,1,255,255,255,1,247,244,236, + 1,184,151,63,1,214,156,2,1,166,121,1,1,143,104,0,1,255,255,255, + 12,143,104,0,1,171,126,3,1,187,144,30,1,247,244,237,1,244,240,230, + 1,236,229,211,1,255,255,255,2,252,251,248,1,183,148,55,1,217,158,0, + 1,162,118,0,1,255,255,255,13,159,116,0,1,205,149,1,1,205,183,125, + 1,255,255,255,5,246,243,234,1,181,143,39,1,198,145,1,1,155,113,0, + 1,255,255,255,12,143,104,0,1,187,139,12,1,190,157,72,1,255,255,255, + 6,221,208,170,1,200,149,9,1,166,120,0,1,143,104,0,1,255,255,255, + 12,179,133,10,1,190,157,68,1,255,255,255,7,184,150,60,1,207,151,2, + 1,157,114,0,1,255,255,255,12,178,133,12,1,189,155,63,1,255,255,255, + 7,234,226,205,1,192,145,19,1,172,125,1,1,143,104,0,1,255,255,255, + 11,178,133,13,1,189,153,59,1,255,255,255,1,255,254,254,1,255,255,255, + 6,190,161,83,1,214,156,0,1,161,117,0,1,255,255,255,11,177,132,12, + 1,189,153,56,1,239,233,218,1,166,129,31,1,244,240,230,1,255,255,255, + 5,245,242,233,1,185,143,32,1,204,150,1,1,158,115,0,1,255,255,255, + 10,169,124,3,1,185,146,44,1,200,176,111,1,215,156,0,1,175,138,39, + 1,255,255,255,6,207,185,127,1,202,151,14,1,182,135,6,1,153,111,0, + 1,255,255,255,9,157,114,0,1,187,138,6,1,166,128,24,1,198,144,1, + 1,199,145,1,1,210,190,138,1,255,255,255,6,215,198,152,1,188,145,29, + 1,192,142,10,1,160,116,0,1,143,104,0,1,255,255,255,7,143,104,0, + 1,163,121,8,1,178,130,1,1,154,112,0,1,165,120,0,1,174,130,14, + 1,245,241,232,1,255,255,255,6,239,232,215,1,187,153,63,1,189,140,9, + 1,164,120,2,1,143,104,0,1,255,255,255,7,143,104,0,1,147,107,0, + 1,255,255,255,1,143,104,0,1,159,116,1,1,176,142,51,1,255,255,255, + 7,225,212,180,1,171,136,43,1,189,138,3,1,162,118,0,1,143,104,0, + 1,255,255,255,10,143,104,0,1,161,123,21,1,223,211,180,1,255,255,255, + 5,201,178,114,1,194,144,12,1,188,139,10,1,183,134,3,1,164,119,0, + 1,147,107,0,1,255,255,255,12,225,214,186,1,255,255,255,5,222,207,168, + 1,190,145,25,1,193,141,2,1,155,113,0,1,255,255,255,21,219,203,162, + 1,185,140,21,1,196,143,1,1,157,115,0,1,255,255,255,21,216,201,158, + 1,173,133,26,1,157,114,0,1,151,110,0,1,255,255,255,22,173,140,50, + 1,153,111,0,1,255,255,255,25,200,2,0,0,0,0,0,24,5,5,5, + 1,175,175,175,1,194,194,194,1,181,181,181,1,128,128,128,1,26,26,26, + 1,0,0,0,18,34,34,34,1,234,234,234,1,252,252,252,2,255,255,255, + 1,230,230,230,1,199,199,199,1,157,157,157,1,68,68,68,1,0,0,0, + 16,198,198,198,1,252,252,252,1,255,255,255,2,249,249,249,1,251,251,251, + 1,255,255,255,1,241,241,241,1,185,185,185,1,29,29,29,1,0,0,0, + 14,72,72,72,1,241,241,241,1,251,251,251,1,255,255,255,4,249,249,249, + 1,255,255,255,1,214,214,214,1,34,34,34,1,0,0,0,14,196,196,196, + 1,250,250,250,1,255,255,255,5,253,253,253,1,255,255,255,1,215,215,215, + 1,26,26,26,1,0,0,0,13,82,82,82,1,249,249,249,1,255,255,255, + 8,213,213,213,1,22,22,22,1,0,0,0,12,1,1,1,1,211,211,211, + 1,255,255,255,9,195,195,195,1,0,0,0,13,137,137,137,1,255,255,255, + 8,253,253,253,1,244,244,244,1,83,83,83,1,0,0,0,12,17,17,17, + 1,241,241,241,1,255,255,255,8,250,250,250,1,209,209,209,1,3,3,3, + 1,0,0,0,12,231,231,231,1,255,255,255,9,251,251,251,1,122,122,122, + 1,0,0,0,12,228,228,228,1,255,255,255,9,252,252,252,1,219,219,219, + 1,15,15,15,1,0,0,0,11,226,226,226,1,255,255,255,11,182,182,182, + 1,0,0,0,11,227,227,227,1,255,255,255,10,254,254,254,1,245,245,245, + 1,117,117,117,1,0,0,0,10,216,216,216,1,253,253,253,1,255,255,255, + 2,223,223,223,1,255,255,255,7,253,253,253,1,232,232,232,1,62,62,62, + 1,0,0,0,9,137,137,137,1,251,251,251,1,248,248,248,1,244,244,244, + 1,246,246,246,1,243,243,243,1,255,255,255,8,243,243,243,1,153,153,153, + 1,7,7,7,1,0,0,0,7,8,8,8,1,206,206,206,1,238,238,238, + 1,131,131,131,1,212,212,212,1,238,238,238,1,255,255,255,9,251,251,251, + 1,206,206,206,1,19,19,19,1,0,0,0,7,10,10,10,1,65,65,65, + 1,0,0,0,1,19,19,19,1,211,211,211,1,247,247,247,1,255,255,255, + 9,253,253,253,1,197,197,197,1,6,6,6,1,0,0,0,10,10,10,10, + 1,210,210,210,1,237,237,237,1,251,251,251,1,255,255,255,6,249,249,249, + 1,232,232,232,1,209,209,209,1,62,62,62,1,0,0,0,12,126,126,126, + 1,155,155,155,1,176,176,176,1,197,197,197,1,220,220,220,1,241,241,241, + 1,255,255,255,1,252,252,252,1,238,238,238,1,136,136,136,1,0,0,0, + 14,7,7,7,1,35,35,35,1,67,67,67,1,101,101,101,1,122,122,122, + 1,143,143,143,1,166,166,166,1,207,207,207,1,246,246,246,1,240,240,240, + 1,112,112,112,1,0,0,0,17,8,8,8,1,28,28,28,1,59,59,59, + 1,90,90,90,1,142,142,142,1,221,221,221,1,239,239,239,1,50,50,50, + 1,0,0,0,20,5,5,5,1,21,21,21,1,103,103,103,1,147,147,147, + 1,0,0,0,25,0,0) + ); + +const + objdata_tenumeditdb: record size: integer; data: array[0..1426] of byte end = + (size: 1427; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,101,110, + 117,109,101,100,105,116,100,98,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,28,5,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,216,4,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,128,128,128,25,255,255,255,1,238,238,238, + 1,29,29,29,1,255,255,255,1,172,172,172,1,21,21,21,1,18,18,18, + 1,148,148,148,1,115,115,115,1,15,15,15,2,128,128,128,1,255,255,255, + 2,0,0,0,1,234,234,234,1,23,23,23,1,255,255,255,6,128,128,128, + 1,255,255,255,1,98,98,98,1,0,0,0,1,255,255,255,1,29,29,29, + 1,201,201,201,1,209,209,209,1,10,10,10,1,255,255,255,2,194,194,194, + 1,17,17,17,1,255,255,255,3,0,0,0,1,255,255,255,2,208,208,208, + 3,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1,247,247,247, + 1,0,0,0,1,255,255,255,3,205,205,205,1,68,68,68,1,255,255,255, + 1,164,164,164,1,4,4,4,1,103,103,103,1,255,255,255,3,0,0,0, + 1,255,255,255,2,0,0,0,3,128,128,128,1,255,255,255,1,128,128,128, + 1,255,255,255,2,0,0,0,1,255,255,255,2,224,224,224,1,70,70,70, + 1,232,232,232,1,255,255,255,2,214,214,214,1,10,10,10,1,255,255,255, + 3,0,0,0,1,255,255,255,2,208,208,208,1,0,0,0,1,208,208,208, + 1,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,2,0,0,0, + 1,255,255,255,1,165,165,165,1,77,77,77,1,235,235,235,1,255,255,255, + 1,32,32,32,1,227,227,227,1,234,234,234,1,24,24,24,1,255,255,255, + 1,252,252,252,1,231,231,231,1,0,0,0,1,247,247,247,1,255,255,255, + 1,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255, + 2,0,0,0,1,255,255,255,1,19,19,19,1,0,0,0,3,177,177,177, + 1,19,19,19,1,24,24,24,1,179,179,179,1,255,255,255,1,223,223,223, + 1,0,0,0,1,223,223,223,1,0,0,0,1,128,128,128,5,255,255,255, + 25,0,0,0,25,184,255,255,17,255,255,255,5,0,0,0,2,184,255,255, + 2,119,165,165,1,0,0,0,1,119,165,165,1,184,255,255,2,0,0,0, + 1,1,1,1,1,54,75,75,1,184,255,255,1,167,232,232,1,56,77,77, + 1,6,9,9,1,27,38,38,1,146,203,203,1,184,255,255,1,255,255,255, + 1,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,0,0,0, + 2,184,255,255,2,63,88,88,1,54,75,75,1,64,89,89,1,184,255,255, + 2,0,0,0,1,169,234,234,1,51,70,70,1,184,255,255,1,59,82,82, + 1,85,118,118,1,177,245,245,1,120,166,166,1,38,53,53,1,184,255,255, + 1,255,255,255,1,0,0,0,3,128,128,128,1,0,0,0,2,184,255,255, + 1,181,251,251,1,15,21,21,1,159,221,221,1,14,20,20,1,181,251,251, + 1,184,255,255,1,0,0,0,2,84,117,117,1,184,255,255,1,9,12,12, + 1,174,241,241,1,184,255,255,4,255,255,255,1,208,208,208,3,128,128,128, + 1,0,0,0,2,184,255,255,1,138,191,191,1,0,0,0,3,138,191,191, + 1,184,255,255,1,0,0,0,1,175,243,243,1,8,11,11,1,184,255,255, + 1,10,14,14,1,174,241,241,1,184,255,255,1,182,252,252,1,152,210,210, + 1,184,255,255,1,128,128,128,5,0,0,0,2,184,255,255,1,82,114,114, + 1,102,141,141,1,184,255,255,1,102,141,141,1,83,115,115,1,184,255,255, + 1,0,0,0,1,170,235,235,1,14,19,19,1,184,255,255,1,60,83,83, + 1,89,124,124,1,177,245,245,1,105,145,145,1,41,57,57,1,184,255,255, + 1,255,255,255,1,212,212,212,1,252,252,252,1,208,208,208,1,255,255,255, + 1,0,0,0,2,184,255,255,1,27,37,37,1,157,217,217,1,184,255,255, + 1,157,217,217,1,27,38,38,1,184,255,255,1,0,0,0,1,2,3,3, + 1,89,124,124,1,184,255,255,1,164,227,227,1,45,63,63,1,5,7,7, + 1,31,43,43,1,154,213,213,1,184,255,255,1,255,255,255,4,128,128,128, + 1,0,0,0,2,184,255,255,17,255,255,255,1,128,128,128,4,0,0,0, + 2,184,255,255,2,0,0,0,2,4,5,5,1,126,174,174,1,184,255,255, + 11,208,208,208,1,255,255,255,1,211,211,211,1,255,255,255,1,208,208,208, + 1,0,0,0,2,184,255,255,2,0,0,0,1,184,255,255,1,126,174,174, + 1,4,5,5,1,184,255,255,1,110,152,152,1,8,11,11,1,115,159,159, + 1,184,255,255,7,255,255,255,2,252,252,252,1,255,255,255,2,0,0,0, + 2,184,255,255,2,0,0,0,1,184,255,255,2,0,0,0,1,184,255,255, + 1,21,29,29,1,142,197,197,1,27,37,37,1,184,255,255,7,255,255,255, + 1,208,208,208,3,128,128,128,1,0,0,0,2,184,255,255,2,0,0,0, + 1,184,255,255,2,0,0,0,1,184,255,255,1,1,2,2,1,0,0,0, + 1,2,3,3,1,184,255,255,7,255,255,255,1,0,0,0,3,128,128,128, + 1,0,0,0,2,184,255,255,2,0,0,0,1,184,255,255,1,126,174,174, + 1,4,5,5,1,184,255,255,1,18,25,25,1,163,226,226,1,184,255,255, + 8,255,255,255,1,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128, + 1,0,0,0,2,184,255,255,2,0,0,0,2,4,5,5,1,126,174,174, + 1,184,255,255,1,105,146,146,1,6,9,9,1,71,98,98,1,184,255,255, + 7,128,128,128,5,0,0,0,25,12,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,66,0,0) + ); + +const + objdata_tenum64editdb: record size: integer; data: array[0..1372] of byte end = + (size: 1373; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,101,110, + 117,109,54,52,101,100,105,116,100,98,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,228,4,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,160,4,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,255,255,255,1,238, + 238,238,1,29,29,29,1,255,255,255,1,172,172,172,1,21,21,21,1,18, + 18,18,1,148,148,148,1,115,115,115,1,15,15,15,2,128,128,128,1,255, + 255,255,2,0,0,0,1,234,234,234,1,23,23,23,1,255,255,255,6,128, + 128,128,1,255,255,255,1,98,98,98,1,0,0,0,1,255,255,255,1,29, + 29,29,1,201,201,201,1,209,209,209,1,10,10,10,1,255,255,255,2,194, + 194,194,1,17,17,17,1,255,255,255,3,0,0,0,1,255,255,255,2,208, + 208,208,3,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1,247, + 247,247,1,0,0,0,1,255,255,255,3,205,205,205,1,68,68,68,1,255, + 255,255,1,164,164,164,1,4,4,4,1,103,103,103,1,255,255,255,3,0, + 0,0,1,255,255,255,2,0,0,0,3,128,128,128,1,255,255,255,1,128, + 128,128,1,255,255,255,2,0,0,0,1,255,255,255,2,224,224,224,1,70, + 70,70,1,232,232,232,1,255,255,255,2,214,214,214,1,10,10,10,1,255, + 255,255,3,0,0,0,1,255,255,255,2,208,208,208,1,0,0,0,1,208, + 208,208,1,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,2,0, + 0,0,1,255,255,255,1,165,165,165,1,77,77,77,1,235,235,235,1,255, + 255,255,1,32,32,32,1,227,227,227,1,234,234,234,1,24,24,24,1,255, + 255,255,1,252,252,252,1,231,231,231,1,0,0,0,1,247,247,247,1,255, + 255,255,1,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128,1,255, + 255,255,2,0,0,0,1,255,255,255,1,19,19,19,1,0,0,0,3,177, + 177,177,1,19,19,19,1,24,24,24,1,179,179,179,1,255,255,255,1,223, + 223,223,1,0,0,0,1,223,223,223,1,0,0,0,1,128,128,128,5,255, + 255,255,25,0,0,0,25,184,255,255,17,255,255,255,5,0,0,0,2,184, + 255,255,17,255,255,255,1,208,208,208,1,0,0,0,1,208,208,208,1,128, + 128,128,1,0,0,0,2,184,255,255,2,183,253,253,1,96,133,133,1,17, + 24,24,1,4,5,5,1,53,73,73,1,166,230,230,1,184,255,255,5,131, + 182,182,1,1,2,2,1,184,255,255,2,255,255,255,1,0,0,0,3,128, + 128,128,1,0,0,0,2,184,255,255,2,102,142,142,1,22,30,30,1,126, + 174,174,1,139,193,193,1,47,65,65,1,56,77,77,1,184,255,255,4,155, + 215,215,1,10,14,14,1,0,0,0,1,184,255,255,2,255,255,255,1,208, + 208,208,3,128,128,128,1,0,0,0,2,184,255,255,1,183,254,254,1,22, + 30,30,1,130,180,180,1,184,255,255,2,168,233,233,1,127,176,176,1,184, + 255,255,3,172,238,238,1,26,36,36,1,82,114,114,1,0,0,0,1,184, + 255,255,2,128,128,128,5,0,0,0,2,184,255,255,1,169,234,234,1,0, + 0,0,1,108,149,149,1,19,27,27,1,6,8,8,1,61,84,84,1,171, + 237,237,1,184,255,255,2,181,251,251,1,50,69,69,1,79,109,109,1,155, + 215,215,1,0,0,0,1,184,255,255,2,255,255,255,1,212,212,212,1,252, + 252,252,1,208,208,208,1,255,255,255,1,0,0,0,2,184,255,255,1,156, + 216,216,1,0,0,0,1,35,49,49,1,136,188,188,1,141,195,195,1,40, + 55,55,1,58,81,81,1,184,255,255,2,80,111,111,1,48,67,67,1,180, + 250,250,1,155,215,215,1,0,0,0,1,184,255,255,2,255,255,255,4,128, + 128,128,1,0,0,0,2,184,255,255,1,159,221,221,1,0,0,0,1,152, + 210,210,1,184,255,255,2,153,212,212,1,1,1,1,1,173,240,240,1,115, + 160,160,1,25,35,35,1,171,237,237,1,184,255,255,1,155,215,215,1,0, + 0,0,1,184,255,255,2,255,255,255,1,128,128,128,4,0,0,0,2,184, + 255,255,1,175,242,242,1,0,0,0,1,180,249,249,1,184,255,255,2,180, + 249,249,1,0,0,0,1,159,220,220,1,66,91,91,1,0,0,0,6,77, + 107,107,1,208,208,208,1,255,255,255,1,211,211,211,1,255,255,255,1,208, + 208,208,1,0,0,0,2,184,255,255,2,29,40,40,1,141,195,195,1,184, + 255,255,2,144,200,200,1,5,7,7,1,178,246,246,1,165,229,229,1,155, + 215,215,3,131,181,181,1,0,0,0,1,155,215,215,1,167,231,231,1,255, + 255,255,2,252,252,252,1,255,255,255,2,0,0,0,2,184,255,255,2,104, + 144,144,1,25,35,35,1,130,180,180,1,131,182,182,1,29,40,40,1,76, + 106,106,1,184,255,255,5,155,215,215,1,0,0,0,1,184,255,255,2,255, + 255,255,1,208,208,208,3,128,128,128,1,0,0,0,2,184,255,255,2,182, + 252,252,1,81,112,112,1,9,12,12,1,11,15,15,1,76,106,106,1,178, + 247,247,1,184,255,255,5,155,215,215,1,0,0,0,1,184,255,255,2,255, + 255,255,1,0,0,0,3,128,128,128,1,0,0,0,2,184,255,255,17,255, + 255,255,1,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,0, + 0,0,2,184,255,255,17,128,128,128,5,0,0,0,25,12,0,0,0,255, + 255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tenumeditlb: record size: integer; data: array[0..1426] of byte end = + (size: 1427; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,101,110, + 117,109,101,100,105,116,108,98,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,28,5,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,216,4,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,128,128,128,25,255,255,255,1,238,238,238, + 1,29,29,29,1,255,255,255,1,172,172,172,1,21,21,21,1,18,18,18, + 1,148,148,148,1,115,115,115,1,15,15,15,2,128,128,128,1,255,255,255, + 2,0,0,0,1,234,234,234,1,23,23,23,1,255,255,255,6,128,128,128, + 1,255,255,255,1,98,98,98,1,0,0,0,1,255,255,255,1,29,29,29, + 1,201,201,201,1,209,209,209,1,10,10,10,1,255,255,255,2,194,194,194, + 1,17,17,17,1,255,255,255,3,0,0,0,1,255,255,255,2,208,208,208, + 3,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1,247,247,247, + 1,0,0,0,1,255,255,255,3,205,205,205,1,68,68,68,1,255,255,255, + 1,164,164,164,1,4,4,4,1,103,103,103,1,255,255,255,3,0,0,0, + 1,255,255,255,2,0,0,0,3,128,128,128,1,255,255,255,1,128,128,128, + 1,255,255,255,2,0,0,0,1,255,255,255,2,224,224,224,1,70,70,70, + 1,232,232,232,1,255,255,255,2,214,214,214,1,10,10,10,1,255,255,255, + 3,0,0,0,1,255,255,255,2,208,208,208,1,0,0,0,1,208,208,208, + 1,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,2,0,0,0, + 1,255,255,255,1,165,165,165,1,77,77,77,1,235,235,235,1,255,255,255, + 1,32,32,32,1,227,227,227,1,234,234,234,1,24,24,24,1,255,255,255, + 1,252,252,252,1,231,231,231,1,0,0,0,1,247,247,247,1,255,255,255, + 1,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255, + 2,0,0,0,1,255,255,255,1,19,19,19,1,0,0,0,3,177,177,177, + 1,19,19,19,1,24,24,24,1,179,179,179,1,255,255,255,1,223,223,223, + 1,0,0,0,1,223,223,223,1,0,0,0,1,128,128,128,5,255,255,255, + 25,0,0,0,25,201,201,255,17,255,255,255,5,0,0,0,2,201,201,255, + 2,130,130,165,1,0,0,0,1,130,130,165,1,201,201,255,2,0,0,0, + 1,1,1,1,1,59,59,75,1,201,201,255,1,183,183,232,1,61,61,77, + 1,7,7,9,1,30,30,38,1,160,160,203,1,201,201,255,1,255,255,255, + 1,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,0,0,0, + 2,201,201,255,2,69,69,88,1,59,59,75,1,70,70,89,1,201,201,255, + 2,0,0,0,1,184,184,234,1,55,55,70,1,201,201,255,1,65,65,82, + 1,93,93,118,1,193,193,245,1,131,131,166,1,42,42,53,1,201,201,255, + 1,255,255,255,1,0,0,0,3,128,128,128,1,0,0,0,2,201,201,255, + 1,198,198,251,1,17,17,21,1,174,174,221,1,16,16,20,1,198,198,251, + 1,201,201,255,1,0,0,0,2,92,92,117,1,201,201,255,1,9,9,12, + 1,190,190,241,1,201,201,255,4,255,255,255,1,208,208,208,3,128,128,128, + 1,0,0,0,2,201,201,255,1,151,151,191,1,0,0,0,3,151,151,191, + 1,201,201,255,1,0,0,0,1,192,192,243,1,9,9,11,1,201,201,255, + 1,11,11,14,1,190,190,241,1,201,201,255,1,199,199,252,1,166,166,210, + 1,201,201,255,1,128,128,128,5,0,0,0,2,201,201,255,1,90,90,114, + 1,111,111,141,1,201,201,255,1,111,111,141,1,91,91,115,1,201,201,255, + 1,0,0,0,1,185,185,235,1,15,15,19,1,201,201,255,1,65,65,83, + 1,98,98,124,1,193,193,245,1,114,114,145,1,45,45,57,1,201,201,255, + 1,255,255,255,1,212,212,212,1,252,252,252,1,208,208,208,1,255,255,255, + 1,0,0,0,2,201,201,255,1,29,29,37,1,171,171,217,1,201,201,255, + 1,171,171,217,1,30,30,38,1,201,201,255,1,0,0,0,1,2,2,3, + 1,98,98,124,1,201,201,255,1,179,179,227,1,50,50,63,1,6,6,7, + 1,34,34,43,1,168,168,213,1,201,201,255,1,255,255,255,4,128,128,128, + 1,0,0,0,2,201,201,255,17,255,255,255,1,128,128,128,4,0,0,0, + 2,201,201,255,2,0,0,0,2,4,4,5,1,137,137,174,1,201,201,255, + 11,208,208,208,1,255,255,255,1,211,211,211,1,255,255,255,1,208,208,208, + 1,0,0,0,2,201,201,255,2,0,0,0,1,201,201,255,1,137,137,174, + 1,4,4,5,1,201,201,255,1,120,120,152,1,9,9,11,1,125,125,159, + 1,201,201,255,7,255,255,255,2,252,252,252,1,255,255,255,2,0,0,0, + 2,201,201,255,2,0,0,0,1,201,201,255,2,0,0,0,1,201,201,255, + 1,23,23,29,1,155,155,197,1,29,29,37,1,201,201,255,7,255,255,255, + 1,208,208,208,3,128,128,128,1,0,0,0,2,201,201,255,2,0,0,0, + 1,201,201,255,2,0,0,0,1,201,201,255,1,2,2,2,1,0,0,0, + 1,2,2,3,1,201,201,255,7,255,255,255,1,0,0,0,3,128,128,128, + 1,0,0,0,2,201,201,255,2,0,0,0,1,201,201,255,1,137,137,174, + 1,4,4,5,1,201,201,255,1,20,20,25,1,178,178,226,1,201,201,255, + 8,255,255,255,1,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128, + 1,0,0,0,2,201,201,255,2,0,0,0,2,4,4,5,1,137,137,174, + 1,201,201,255,1,115,115,146,1,7,7,9,1,77,77,98,1,201,201,255, + 7,128,128,128,5,0,0,0,25,12,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,66,0,0) + ); + +const + objdata_tenum64editlb: record size: integer; data: array[0..1372] of byte end = + (size: 1373; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,101,110, + 117,109,54,52,101,100,105,116,108,98,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,228,4,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,160,4,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,255,255,255,1,238, + 238,238,1,29,29,29,1,255,255,255,1,172,172,172,1,21,21,21,1,18, + 18,18,1,148,148,148,1,115,115,115,1,15,15,15,2,128,128,128,1,255, + 255,255,2,0,0,0,1,234,234,234,1,23,23,23,1,255,255,255,6,128, + 128,128,1,255,255,255,1,98,98,98,1,0,0,0,1,255,255,255,1,29, + 29,29,1,201,201,201,1,209,209,209,1,10,10,10,1,255,255,255,2,194, + 194,194,1,17,17,17,1,255,255,255,3,0,0,0,1,255,255,255,2,208, + 208,208,3,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1,247, + 247,247,1,0,0,0,1,255,255,255,3,205,205,205,1,68,68,68,1,255, + 255,255,1,164,164,164,1,4,4,4,1,103,103,103,1,255,255,255,3,0, + 0,0,1,255,255,255,2,0,0,0,3,128,128,128,1,255,255,255,1,128, + 128,128,1,255,255,255,2,0,0,0,1,255,255,255,2,224,224,224,1,70, + 70,70,1,232,232,232,1,255,255,255,2,214,214,214,1,10,10,10,1,255, + 255,255,3,0,0,0,1,255,255,255,2,208,208,208,1,0,0,0,1,208, + 208,208,1,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,2,0, + 0,0,1,255,255,255,1,165,165,165,1,77,77,77,1,235,235,235,1,255, + 255,255,1,32,32,32,1,227,227,227,1,234,234,234,1,24,24,24,1,255, + 255,255,1,252,252,252,1,231,231,231,1,0,0,0,1,247,247,247,1,255, + 255,255,1,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128,1,255, + 255,255,2,0,0,0,1,255,255,255,1,19,19,19,1,0,0,0,3,177, + 177,177,1,19,19,19,1,24,24,24,1,179,179,179,1,255,255,255,1,223, + 223,223,1,0,0,0,1,223,223,223,1,0,0,0,1,128,128,128,5,255, + 255,255,25,0,0,0,25,201,201,255,17,255,255,255,5,0,0,0,2,201, + 201,255,17,255,255,255,1,208,208,208,1,0,0,0,1,208,208,208,1,128, + 128,128,1,0,0,0,2,201,201,255,2,199,199,253,1,105,105,133,1,19, + 19,24,1,4,4,5,1,58,58,73,1,181,181,230,1,201,201,255,5,143, + 143,182,1,2,2,2,1,201,201,255,2,255,255,255,1,0,0,0,3,128, + 128,128,1,0,0,0,2,201,201,255,2,112,112,142,1,24,24,30,1,137, + 137,174,1,152,152,193,1,51,51,65,1,61,61,77,1,201,201,255,4,169, + 169,215,1,11,11,14,1,0,0,0,1,201,201,255,2,255,255,255,1,208, + 208,208,3,128,128,128,1,0,0,0,2,201,201,255,1,200,200,254,1,24, + 24,30,1,142,142,180,1,201,201,255,2,184,184,233,1,139,139,176,1,201, + 201,255,3,188,188,238,1,28,28,36,1,90,90,114,1,0,0,0,1,201, + 201,255,2,128,128,128,5,0,0,0,2,201,201,255,1,184,184,234,1,0, + 0,0,1,117,117,149,1,21,21,27,1,6,6,8,1,66,66,84,1,187, + 187,237,1,201,201,255,2,198,198,251,1,54,54,69,1,86,86,109,1,169, + 169,215,1,0,0,0,1,201,201,255,2,255,255,255,1,212,212,212,1,252, + 252,252,1,208,208,208,1,255,255,255,1,0,0,0,2,201,201,255,1,170, + 170,216,1,0,0,0,1,39,39,49,1,148,148,188,1,154,154,195,1,43, + 43,55,1,64,64,81,1,201,201,255,2,87,87,111,1,53,53,67,1,197, + 197,250,1,169,169,215,1,0,0,0,1,201,201,255,2,255,255,255,4,128, + 128,128,1,0,0,0,2,201,201,255,1,174,174,221,1,0,0,0,1,166, + 166,210,1,201,201,255,2,167,167,212,1,1,1,1,1,189,189,240,1,126, + 126,160,1,28,28,35,1,187,187,237,1,201,201,255,1,169,169,215,1,0, + 0,0,1,201,201,255,2,255,255,255,1,128,128,128,4,0,0,0,2,201, + 201,255,1,191,191,242,1,0,0,0,1,196,196,249,1,201,201,255,2,196, + 196,249,1,0,0,0,1,173,173,220,1,72,72,91,1,0,0,0,6,84, + 84,107,1,208,208,208,1,255,255,255,1,211,211,211,1,255,255,255,1,208, + 208,208,1,0,0,0,2,201,201,255,2,32,32,40,1,154,154,195,1,201, + 201,255,2,158,158,200,1,6,6,7,1,194,194,246,1,181,181,229,1,169, + 169,215,3,143,143,181,1,0,0,0,1,169,169,215,1,182,182,231,1,255, + 255,255,2,252,252,252,1,255,255,255,2,0,0,0,2,201,201,255,2,114, + 114,144,1,28,28,35,1,142,142,180,1,143,143,182,1,32,32,40,1,84, + 84,106,1,201,201,255,5,169,169,215,1,0,0,0,1,201,201,255,2,255, + 255,255,1,208,208,208,3,128,128,128,1,0,0,0,2,201,201,255,2,199, + 199,252,1,88,88,112,1,9,9,12,1,12,12,15,1,84,84,106,1,195, + 195,247,1,201,201,255,5,169,169,215,1,0,0,0,1,201,201,255,2,255, + 255,255,1,0,0,0,3,128,128,128,1,0,0,0,2,201,201,255,17,255, + 255,255,1,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,0, + 0,0,2,201,201,255,17,128,128,128,5,0,0,0,25,12,0,0,0,255, + 255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tkeystringeditdb: record size: integer; data: array[0..1223] of byte end = + (size: 1224; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,107,101, + 121,115,116,114,105,110,103,101,100,105,116,100,98,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,76,4, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,8,4, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,255,255, + 255,2,165,165,165,1,0,0,0,1,165,165,165,1,255,255,255,2,0,0, + 0,1,1,1,1,1,75,75,75,1,255,255,255,4,0,0,0,1,234,234, + 234,1,23,23,23,1,255,255,255,6,128,128,128,1,255,255,255,2,88,88, + 88,1,75,75,75,1,89,89,89,1,255,255,255,2,0,0,0,1,234,234, + 234,1,70,70,70,1,255,255,255,5,0,0,0,1,255,255,255,2,208,208, + 208,3,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1,251,251, + 251,1,21,21,21,1,221,221,221,1,20,20,20,1,251,251,251,1,255,255, + 255,1,0,0,0,2,117,117,117,1,255,255,255,5,0,0,0,1,255,255, + 255,2,0,0,0,3,128,128,128,1,255,255,255,1,128,128,128,1,255,255, + 255,1,191,191,191,1,0,0,0,3,191,191,191,1,255,255,255,1,0,0, + 0,1,243,243,243,1,11,11,11,1,255,255,255,5,0,0,0,1,255,255, + 255,2,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,255,255, + 255,1,128,128,128,1,255,255,255,1,114,114,114,1,141,141,141,1,255,255, + 255,1,141,141,141,1,115,115,115,1,255,255,255,1,0,0,0,1,235,235, + 235,1,19,19,19,1,255,255,255,3,252,252,252,1,231,231,231,1,0,0, + 0,1,247,247,247,1,255,255,255,1,208,208,208,3,128,128,128,1,255,255, + 255,1,128,128,128,1,255,255,255,1,37,37,37,1,217,217,217,1,255,255, + 255,1,217,217,217,1,38,38,38,1,255,255,255,1,0,0,0,1,3,3, + 3,1,124,124,124,1,255,255,255,3,223,223,223,1,0,0,0,1,223,223, + 223,1,0,0,0,1,128,128,128,5,255,255,255,25,0,0,0,25,184,255, + 255,17,255,255,255,5,0,0,0,2,184,255,255,17,255,255,255,1,208,208, + 208,1,0,0,0,1,208,208,208,1,128,128,128,1,0,0,0,2,184,255, + 255,17,255,255,255,1,0,0,0,3,128,128,128,1,0,0,0,2,184,255, + 255,1,0,0,0,1,184,255,255,2,113,157,157,1,74,102,102,1,184,255, + 255,11,255,255,255,1,208,208,208,3,128,128,128,1,0,0,0,2,184,255, + 255,1,0,0,0,1,184,255,255,1,145,201,201,1,47,65,65,1,180,249, + 249,1,184,255,255,11,128,128,128,5,0,0,0,2,184,255,255,1,0,0, + 0,1,168,233,233,1,38,53,53,1,166,230,230,1,184,255,255,1,134,186, + 186,1,18,25,25,2,141,195,195,1,184,255,255,1,38,52,52,1,146,203, + 203,1,184,255,255,1,147,204,204,1,36,50,50,1,184,255,255,1,255,255, + 255,1,212,212,212,1,252,252,252,1,208,208,208,1,255,255,255,1,0,0, + 0,2,184,255,255,1,0,0,0,1,45,62,62,1,89,124,124,1,184,255, + 255,2,28,39,39,1,140,194,194,1,142,197,197,1,36,50,50,1,184,255, + 255,1,113,157,157,1,70,97,97,1,184,255,255,1,74,102,102,1,110,152, + 152,1,184,255,255,1,255,255,255,4,128,128,128,1,0,0,0,2,184,255, + 255,1,0,0,0,1,105,146,146,1,41,57,57,1,150,208,208,1,184,255, + 255,1,2,3,3,1,0,0,0,2,3,4,4,1,184,255,255,1,178,246, + 246,1,19,27,27,1,163,226,226,1,18,25,25,1,175,242,242,1,184,255, + 255,1,255,255,255,1,128,128,128,4,0,0,0,2,184,255,255,1,0,0, + 0,1,184,255,255,1,157,217,217,1,37,51,51,1,176,244,244,1,25,34, + 34,1,141,195,195,1,184,255,255,4,82,113,113,1,40,55,55,1,71,99, + 99,1,184,255,255,2,208,208,208,1,255,255,255,1,211,211,211,1,255,255, + 255,1,208,208,208,1,0,0,0,2,184,255,255,1,0,0,0,1,184,255, + 255,2,116,161,161,1,68,94,94,1,129,179,179,1,17,23,23,1,9,13, + 13,1,87,120,120,1,184,255,255,2,157,217,217,1,0,0,0,1,145,201, + 201,1,184,255,255,2,255,255,255,2,252,252,252,1,255,255,255,2,0,0, + 0,2,184,255,255,12,146,202,202,1,30,41,41,1,184,255,255,3,255,255, + 255,1,208,208,208,3,128,128,128,1,0,0,0,2,184,255,255,12,9,12, + 12,1,121,168,168,1,184,255,255,3,255,255,255,1,0,0,0,3,128,128, + 128,1,0,0,0,2,184,255,255,17,255,255,255,1,208,208,208,1,0,0, + 0,1,208,208,208,1,128,128,128,1,0,0,0,2,184,255,255,17,128,128, + 128,5,0,0,0,25,12,0,0,0,255,255,255,255,255,255,255,255,255,255, + 255,66,0,0) + ); + +const + objdata_tkeystringeditlb: record size: integer; data: array[0..1223] of byte end = + (size: 1224; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,107,101, + 121,115,116,114,105,110,103,101,100,105,116,108,98,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,76,4, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,8,4, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,255,255, + 255,2,165,165,165,1,0,0,0,1,165,165,165,1,255,255,255,2,0,0, + 0,1,1,1,1,1,75,75,75,1,255,255,255,4,0,0,0,1,234,234, + 234,1,23,23,23,1,255,255,255,6,128,128,128,1,255,255,255,2,88,88, + 88,1,75,75,75,1,89,89,89,1,255,255,255,2,0,0,0,1,234,234, + 234,1,70,70,70,1,255,255,255,5,0,0,0,1,255,255,255,2,208,208, + 208,3,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1,251,251, + 251,1,21,21,21,1,221,221,221,1,20,20,20,1,251,251,251,1,255,255, + 255,1,0,0,0,2,117,117,117,1,255,255,255,5,0,0,0,1,255,255, + 255,2,0,0,0,3,128,128,128,1,255,255,255,1,128,128,128,1,255,255, + 255,1,191,191,191,1,0,0,0,3,191,191,191,1,255,255,255,1,0,0, + 0,1,243,243,243,1,11,11,11,1,255,255,255,5,0,0,0,1,255,255, + 255,2,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,255,255, + 255,1,128,128,128,1,255,255,255,1,114,114,114,1,141,141,141,1,255,255, + 255,1,141,141,141,1,115,115,115,1,255,255,255,1,0,0,0,1,235,235, + 235,1,19,19,19,1,255,255,255,3,252,252,252,1,231,231,231,1,0,0, + 0,1,247,247,247,1,255,255,255,1,208,208,208,3,128,128,128,1,255,255, + 255,1,128,128,128,1,255,255,255,1,37,37,37,1,217,217,217,1,255,255, + 255,1,217,217,217,1,38,38,38,1,255,255,255,1,0,0,0,1,3,3, + 3,1,124,124,124,1,255,255,255,3,223,223,223,1,0,0,0,1,223,223, + 223,1,0,0,0,1,128,128,128,5,255,255,255,25,0,0,0,25,201,201, + 255,17,255,255,255,5,0,0,0,2,201,201,255,17,255,255,255,1,208,208, + 208,1,0,0,0,1,208,208,208,1,128,128,128,1,0,0,0,2,201,201, + 255,17,255,255,255,1,0,0,0,3,128,128,128,1,0,0,0,2,201,201, + 255,1,0,0,0,1,201,201,255,2,124,124,157,1,80,80,102,1,201,201, + 255,11,255,255,255,1,208,208,208,3,128,128,128,1,0,0,0,2,201,201, + 255,1,0,0,0,1,201,201,255,1,158,158,201,1,51,51,65,1,196,196, + 249,1,201,201,255,11,128,128,128,5,0,0,0,2,201,201,255,1,0,0, + 0,1,184,184,233,1,42,42,53,1,181,181,230,1,201,201,255,1,147,147, + 186,1,20,20,25,2,154,154,195,1,201,201,255,1,41,41,52,1,160,160, + 203,1,201,201,255,1,161,161,204,1,39,39,50,1,201,201,255,1,255,255, + 255,1,212,212,212,1,252,252,252,1,208,208,208,1,255,255,255,1,0,0, + 0,2,201,201,255,1,0,0,0,1,49,49,62,1,98,98,124,1,201,201, + 255,2,31,31,39,1,153,153,194,1,155,155,197,1,39,39,50,1,201,201, + 255,1,124,124,157,1,76,76,97,1,201,201,255,1,80,80,102,1,120,120, + 152,1,201,201,255,1,255,255,255,4,128,128,128,1,0,0,0,2,201,201, + 255,1,0,0,0,1,115,115,146,1,45,45,57,1,164,164,208,1,201,201, + 255,1,2,2,3,1,0,0,0,2,3,3,4,1,201,201,255,1,194,194, + 246,1,21,21,27,1,178,178,226,1,20,20,25,1,191,191,242,1,201,201, + 255,1,255,255,255,1,128,128,128,4,0,0,0,2,201,201,255,1,0,0, + 0,1,201,201,255,1,171,171,217,1,40,40,51,1,192,192,244,1,27,27, + 34,1,154,154,195,1,201,201,255,4,89,89,113,1,43,43,55,1,78,78, + 99,1,201,201,255,2,208,208,208,1,255,255,255,1,211,211,211,1,255,255, + 255,1,208,208,208,1,0,0,0,2,201,201,255,1,0,0,0,1,201,201, + 255,2,127,127,161,1,74,74,94,1,141,141,179,1,18,18,23,1,10,10, + 13,1,95,95,120,1,201,201,255,2,171,171,217,1,0,0,0,1,158,158, + 201,1,201,201,255,2,255,255,255,2,252,252,252,1,255,255,255,2,0,0, + 0,2,201,201,255,12,159,159,202,1,32,32,41,1,201,201,255,3,255,255, + 255,1,208,208,208,3,128,128,128,1,0,0,0,2,201,201,255,12,9,9, + 12,1,132,132,168,1,201,201,255,3,255,255,255,1,0,0,0,3,128,128, + 128,1,0,0,0,2,201,201,255,17,255,255,255,1,208,208,208,1,0,0, + 0,1,208,208,208,1,128,128,128,1,0,0,0,2,201,201,255,17,128,128, + 128,5,0,0,0,25,12,0,0,0,255,255,255,255,255,255,255,255,255,255, + 255,66,0,0) + ); + +const + objdata_tmsestringfield: record size: integer; data: array[0..1206] of byte end = + (size: 1207; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,109,115, + 101,115,116,114,105,110,103,102,105,101,108,100,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,60,4,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,100,1,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,184,255,255,25,208,208,208, + 22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255, + 2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208, + 22,184,255,255,2,208,208,208,8,0,0,0,2,208,208,208,12,184,255,255, + 2,208,208,208,8,0,0,0,2,208,208,208,12,184,255,255,2,208,208,208, + 8,0,0,0,2,208,208,208,12,184,255,255,2,208,208,208,2,0,0,0, + 5,208,208,208,1,0,0,0,6,208,208,208,1,0,0,0,5,208,208,208, + 2,184,255,255,2,208,208,208,2,0,0,0,2,208,208,208,1,0,0,0, + 12,208,208,208,1,0,0,0,2,208,208,208,2,184,255,255,2,208,208,208, + 3,0,0,0,7,208,208,208,2,0,0,0,5,208,208,208,5,184,255,255, + 2,208,208,208,2,0,0,0,8,208,208,208,2,0,0,0,4,208,208,208, + 2,0,0,0,2,208,208,208,2,184,255,255,2,208,208,208,2,0,0,0, + 2,208,208,208,1,0,0,0,12,208,208,208,1,0,0,0,2,208,208,208, + 2,184,255,255,2,208,208,208,2,0,0,0,12,208,208,208,1,0,0,0, + 5,208,208,208,2,184,255,255,2,208,208,208,3,0,0,0,2,208,208,208, + 6,0,0,0,1,208,208,208,5,0,0,0,1,208,208,208,4,184,255,255, + 2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208, + 22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255, + 2,208,208,208,22,184,255,255,25,160,2,0,0,255,255,255,25,0,0,0, + 22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255, + 2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0, + 22,255,255,255,2,0,0,0,8,5,5,5,1,18,18,18,1,0,0,0, + 12,255,255,255,2,0,0,0,8,55,55,55,1,192,192,192,1,0,0,0, + 12,255,255,255,2,0,0,0,8,55,55,55,1,192,192,192,1,0,0,0, + 12,255,255,255,2,0,0,0,2,19,19,19,1,166,166,166,1,216,216,216, + 1,229,229,229,1,151,151,151,1,0,0,0,1,55,55,55,1,208,208,208, + 1,143,143,143,1,223,223,223,1,165,165,165,1,12,12,12,1,0,0,0, + 1,40,40,40,1,192,192,192,1,219,219,219,1,166,166,166,1,14,14,14, + 1,0,0,0,2,255,255,255,2,0,0,0,2,109,109,109,1,138,138,138, + 1,0,0,0,1,13,13,13,1,233,233,233,1,45,45,45,1,55,55,55, + 1,255,255,255,1,69,69,69,1,9,9,9,1,173,173,173,1,129,129,129, + 1,1,1,1,1,223,223,223,1,91,91,91,1,0,0,0,1,127,127,127, + 1,122,122,122,1,0,0,0,2,255,255,255,2,0,0,0,3,40,40,40, + 1,98,98,98,1,147,147,147,1,238,238,238,1,62,62,62,1,55,55,55, + 1,215,215,215,1,0,0,0,2,79,79,79,1,196,196,196,1,34,34,34, + 1,237,237,237,1,2,2,2,1,0,0,0,5,255,255,255,2,0,0,0, + 2,116,116,116,1,208,208,208,1,118,118,118,1,59,59,59,1,212,212,212, + 1,63,63,63,1,55,55,55,1,198,198,198,1,0,0,0,2,73,73,73, + 1,197,197,197,1,48,48,48,1,229,229,229,1,0,0,0,2,6,6,6, + 1,18,18,18,1,0,0,0,2,255,255,255,2,0,0,0,2,193,193,193, + 1,79,79,79,1,0,0,0,1,34,34,34,1,245,245,245,1,67,67,67, + 1,55,55,55,1,244,244,244,1,37,37,37,1,1,1,1,1,161,161,161, + 1,135,135,135,1,10,10,10,1,238,238,238,1,50,50,50,1,0,0,0, + 1,106,106,106,1,147,147,147,1,0,0,0,2,255,255,255,2,0,0,0, + 2,81,81,81,1,210,210,210,1,184,184,184,1,180,180,180,1,189,189,189, + 1,95,95,95,1,55,55,55,1,205,205,205,1,172,172,172,1,206,206,206, + 1,149,149,149,1,15,15,15,1,0,0,0,1,69,69,69,1,189,189,189, + 1,198,198,198,1,187,187,187,1,25,25,25,1,0,0,0,2,255,255,255, + 2,0,0,0,3,2,2,2,1,15,15,15,1,0,0,0,6,8,8,8, + 1,0,0,0,5,10,10,10,1,0,0,0,4,255,255,255,2,0,0,0, + 22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255, + 2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0, + 22,255,255,255,25,0,0) + ); + +const + objdata_tmselongintfield: record size: integer; data: array[0..1259] of byte end = + (size: 1260; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,109,115, + 101,108,111,110,103,105,110,116,102,105,101,108,100,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,112,4, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,164,1, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,184,255,255,25,208,208, + 208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255, + 255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208, + 208,22,184,255,255,2,208,208,208,4,0,0,0,2,208,208,208,2,0,0, + 0,2,208,208,208,5,0,0,0,1,208,208,208,6,184,255,255,2,208,208, + 208,4,0,0,0,2,208,208,208,1,0,0,0,5,208,208,208,1,0,0, + 0,5,208,208,208,4,184,255,255,2,208,208,208,4,0,0,0,5,208,208, + 208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0, + 0,2,208,208,208,4,184,255,255,2,208,208,208,4,0,0,0,2,208,208, + 208,1,0,0,0,1,208,208,208,2,0,0,0,2,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,3,208,208,208,3,184,255,255,2,208,208, + 208,4,0,0,0,2,208,208,208,2,0,0,0,4,208,208,208,3,0,0, + 0,3,208,208,208,4,184,255,255,2,208,208,208,4,0,0,0,2,208,208, + 208,2,0,0,0,4,208,208,208,2,0,0,0,4,208,208,208,4,184,255, + 255,2,208,208,208,4,0,0,0,4,208,208,208,2,0,0,0,2,208,208, + 208,1,0,0,0,4,208,208,208,5,184,255,255,2,208,208,208,4,0,0, + 0,5,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,3,208,208, + 208,6,184,255,255,2,208,208,208,4,0,0,0,2,208,208,208,1,0,0, + 0,12,208,208,208,3,184,255,255,2,208,208,208,8,0,0,0,2,208,208, + 208,12,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255, + 255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208, + 208,22,184,255,255,2,208,208,208,22,184,255,255,25,148,2,0,0,255,255, + 255,25,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0, + 0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255, + 255,2,0,0,0,22,255,255,255,2,0,0,0,4,22,22,22,1,3,3, + 3,1,0,0,0,2,2,2,2,1,11,11,11,1,0,0,0,5,11,11, + 11,1,0,0,0,6,255,255,255,2,0,0,0,4,238,238,238,1,33,33, + 33,1,0,0,0,1,97,97,97,1,208,208,208,2,164,164,164,1,7,7, + 7,1,0,0,0,1,52,52,52,1,192,192,192,1,205,205,205,1,199,199, + 199,1,70,70,70,1,0,0,0,4,255,255,255,2,0,0,0,4,238,238, + 238,1,33,33,33,1,22,22,22,1,228,228,228,1,15,15,15,1,0,0, + 0,1,184,184,184,1,92,92,92,1,0,0,0,1,185,185,185,1,76,76, + 76,1,0,0,0,1,54,54,54,1,213,213,213,1,0,0,0,4,255,255, + 255,2,0,0,0,4,238,238,238,1,33,33,33,1,0,0,0,1,17,17, + 17,1,0,0,0,2,201,201,201,1,91,91,91,1,0,0,0,1,67,67, + 67,1,3,3,3,1,0,0,0,1,24,24,24,1,248,248,248,1,8,8, + 8,1,0,0,0,3,255,255,255,2,0,0,0,4,238,238,238,1,33,33, + 33,1,0,0,0,2,66,66,66,1,226,226,226,1,187,187,187,1,2,2, + 2,1,0,0,0,3,1,1,1,1,158,158,158,1,156,156,156,1,0,0, + 0,4,255,255,255,2,0,0,0,4,238,238,238,1,33,33,33,1,0,0, + 0,2,15,15,15,1,44,44,44,1,181,181,181,1,128,128,128,1,0,0, + 0,2,3,3,3,1,161,161,161,1,185,185,185,1,10,10,10,1,0,0, + 0,4,255,255,255,2,0,0,0,4,238,238,238,1,33,33,33,1,14,14, + 14,1,36,36,36,1,0,0,0,2,64,64,64,1,211,211,211,1,0,0, + 0,1,6,6,6,1,172,172,172,1,169,169,169,1,6,6,6,1,0,0, + 0,5,255,255,255,2,0,0,0,4,238,238,238,1,33,33,33,1,28,28, + 28,1,228,228,228,1,11,11,11,1,0,0,0,1,135,135,135,1,136,136, + 136,1,0,0,0,1,158,158,158,1,150,150,150,1,1,1,1,1,0,0, + 0,6,255,255,255,2,0,0,0,4,238,238,238,1,33,33,33,1,0,0, + 0,1,107,107,107,1,208,208,208,1,202,202,202,1,165,165,165,1,24,24, + 24,1,33,33,33,1,254,254,254,1,249,249,249,1,248,248,248,3,26,26, + 26,1,0,0,0,3,255,255,255,2,0,0,0,8,3,3,3,1,13,13, + 13,1,0,0,0,12,255,255,255,2,0,0,0,22,255,255,255,2,0,0, + 0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255, + 255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,25,0,0) + ); + +const + objdata_tmselargeintfield: record size: integer; data: array[0..1220] of byte end = + (size: 1221; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,109,115, + 101,108,97,114,103,101,105,110,116,102,105,101,108,100,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,72, + 4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,124, + 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,184,255,255,25,208, + 208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208, + 208,208,22,184,255,255,2,208,208,208,4,0,0,0,2,208,208,208,3,0, + 0,0,1,208,208,208,6,0,0,0,2,208,208,208,4,184,255,255,2,208, + 208,208,4,0,0,0,2,208,208,208,1,0,0,0,5,208,208,208,3,0, + 0,0,3,208,208,208,4,184,255,255,2,208,208,208,4,0,0,0,5,208, + 208,208,1,0,0,0,2,208,208,208,2,0,0,0,4,208,208,208,4,184, + 255,255,2,208,208,208,4,0,0,0,6,208,208,208,4,0,0,0,4,208, + 208,208,4,184,255,255,2,208,208,208,4,0,0,0,8,208,208,208,1,0, + 0,0,2,208,208,208,1,0,0,0,2,208,208,208,4,184,255,255,2,208, + 208,208,4,0,0,0,5,208,208,208,1,0,0,0,5,208,208,208,1,0, + 0,0,2,208,208,208,4,184,255,255,2,208,208,208,4,0,0,0,4,208, + 208,208,2,0,0,0,9,208,208,208,3,184,255,255,2,208,208,208,4,0, + 0,0,5,208,208,208,1,0,0,0,9,208,208,208,3,184,255,255,2,208, + 208,208,4,0,0,0,2,208,208,208,1,0,0,0,5,208,208,208,4,0, + 0,0,2,208,208,208,4,184,255,255,2,208,208,208,8,0,0,0,2,208, + 208,208,12,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208, + 208,208,22,184,255,255,2,208,208,208,22,184,255,255,25,148,2,0,0,255, + 255,255,25,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,2,0,0,0,4,22,22,22,1,3, + 3,3,1,0,0,0,3,14,14,14,1,0,0,0,6,18,18,18,1,1, + 1,1,1,0,0,0,4,255,255,255,2,0,0,0,4,238,238,238,1,33, + 33,33,1,0,0,0,1,63,63,63,1,214,214,214,1,202,202,202,1,195, + 195,195,1,24,24,24,1,0,0,0,3,46,46,46,1,248,248,248,1,19, + 19,19,1,0,0,0,4,255,255,255,2,0,0,0,4,238,238,238,1,33, + 33,33,1,4,4,4,1,218,218,218,1,51,51,51,1,0,0,0,1,116, + 116,116,1,128,128,128,1,0,0,0,2,7,7,7,1,197,197,197,1,247, + 247,247,1,19,19,19,1,0,0,0,4,255,255,255,2,0,0,0,4,238, + 238,238,1,33,33,33,1,60,60,60,1,190,190,190,1,7,7,7,1,41, + 41,41,1,0,0,0,4,143,143,143,1,98,98,98,1,236,236,236,1,19, + 19,19,1,0,0,0,4,255,255,255,2,0,0,0,4,238,238,238,1,33, + 33,33,1,89,89,89,1,195,195,195,1,215,215,215,1,191,191,191,1,205, + 205,205,1,39,39,39,1,0,0,0,1,68,68,68,1,175,175,175,1,0, + 0,0,1,236,236,236,1,19,19,19,1,0,0,0,4,255,255,255,2,0, + 0,0,4,238,238,238,1,33,33,33,1,100,100,100,1,247,247,247,1,19, + 19,19,1,0,0,0,1,113,113,113,1,144,144,144,1,18,18,18,1,206, + 206,206,1,21,21,21,1,0,0,0,1,236,236,236,1,19,19,19,1,0, + 0,0,4,255,255,255,2,0,0,0,4,238,238,238,1,33,33,33,1,75, + 75,75,1,196,196,196,1,0,0,0,2,51,51,51,1,208,208,208,1,106, + 106,106,1,239,239,239,1,216,216,216,2,252,252,252,1,219,219,219,1,29, + 29,29,1,0,0,0,3,255,255,255,2,0,0,0,4,238,238,238,1,33, + 33,33,1,16,16,16,1,227,227,227,1,31,31,31,1,0,0,0,1,130, + 130,130,1,158,158,158,1,6,6,6,1,16,16,16,3,237,237,237,1,34, + 34,34,1,2,2,2,1,0,0,0,3,255,255,255,2,0,0,0,4,238, + 238,238,1,33,33,33,1,0,0,0,1,81,81,81,1,220,220,220,1,204, + 204,204,1,199,199,199,1,19,19,19,1,0,0,0,4,236,236,236,1,19, + 19,19,1,0,0,0,4,255,255,255,2,0,0,0,8,2,2,2,1,15, + 15,15,1,0,0,0,12,255,255,255,2,0,0,0,22,255,255,255,2,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,25,0, + 0) + ); + +const + objdata_tmsesmallintfield: record size: integer; data: array[0..1244] of byte end = + (size: 1245; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,109,115, + 101,115,109,97,108,108,105,110,116,102,105,101,108,100,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,96, + 4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,180, + 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,184,255,255,25,208, + 208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208, + 208,208,22,184,255,255,2,208,208,208,4,0,0,0,2,208,208,208,3,0, + 0,0,2,208,208,208,4,0,0,0,1,208,208,208,6,184,255,255,2,208, + 208,208,4,0,0,0,2,208,208,208,2,0,0,0,3,208,208,208,2,0, + 0,0,5,208,208,208,4,184,255,255,2,208,208,208,4,0,0,0,2,208, + 208,208,1,0,0,0,4,208,208,208,2,0,0,0,2,208,208,208,1,0, + 0,0,2,208,208,208,4,184,255,255,2,208,208,208,4,0,0,0,2,208, + 208,208,1,0,0,0,4,208,208,208,2,0,0,0,4,208,208,208,5,184, + 255,255,2,208,208,208,4,0,0,0,2,208,208,208,3,0,0,0,2,208, + 208,208,1,0,0,0,6,208,208,208,4,184,255,255,2,208,208,208,4,0, + 0,0,2,208,208,208,3,0,0,0,2,208,208,208,1,0,0,0,3,208, + 208,208,1,0,0,0,2,208,208,208,4,184,255,255,2,208,208,208,4,0, + 0,0,2,208,208,208,3,0,0,0,2,208,208,208,1,0,0,0,3,208, + 208,208,2,0,0,0,2,208,208,208,3,184,255,255,2,208,208,208,4,0, + 0,0,2,208,208,208,3,0,0,0,2,208,208,208,2,0,0,0,2,208, + 208,208,1,0,0,0,2,208,208,208,4,184,255,255,2,208,208,208,4,0, + 0,0,2,208,208,208,3,0,0,0,2,208,208,208,2,0,0,0,5,208, + 208,208,4,184,255,255,2,208,208,208,15,0,0,0,1,208,208,208,6,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208, + 208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,25,116,2,0,0,255,255,255,25,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0, + 0,0,22,255,255,255,2,0,0,0,4,22,22,22,1,3,3,3,1,0, + 0,0,3,11,11,11,2,0,0,0,4,14,14,14,1,0,0,0,6,255, + 255,255,2,0,0,0,4,238,238,238,1,33,33,33,1,0,0,0,2,6, + 6,6,1,198,198,198,1,90,90,90,1,0,0,0,2,25,25,25,1,190, + 190,190,1,201,201,201,1,212,212,212,1,71,71,71,1,0,0,0,4,255, + 255,255,2,0,0,0,4,238,238,238,1,33,33,33,1,0,0,0,1,49, + 49,49,1,206,206,206,1,239,239,239,1,90,90,90,1,0,0,0,2,156, + 156,156,1,117,117,117,1,0,0,0,1,46,46,46,1,197,197,197,1,0, + 0,0,4,255,255,255,2,0,0,0,4,238,238,238,1,33,33,33,1,0, + 0,0,1,119,119,119,1,74,74,74,1,165,165,165,1,90,90,90,1,0, + 0,0,2,241,241,241,1,9,9,9,1,40,40,40,1,7,7,7,1,0, + 0,0,5,255,255,255,2,0,0,0,4,238,238,238,1,33,33,33,1,0, + 0,0,3,165,165,165,1,90,90,90,1,0,0,0,1,16,16,16,1,235, + 235,235,1,187,187,187,1,189,189,189,1,220,220,220,1,86,86,86,1,0, + 0,0,4,255,255,255,2,0,0,0,4,238,238,238,1,33,33,33,1,0, + 0,0,3,165,165,165,1,90,90,90,1,0,0,0,1,27,27,27,1,255, + 255,255,1,83,83,83,1,0,0,0,1,40,40,40,1,216,216,216,1,0, + 0,0,4,255,255,255,2,0,0,0,4,238,238,238,1,33,33,33,1,0, + 0,0,3,165,165,165,1,90,90,90,1,0,0,0,1,4,4,4,1,253, + 253,253,1,13,13,13,1,0,0,0,2,234,234,234,1,25,25,25,1,0, + 0,0,3,255,255,255,2,0,0,0,4,238,238,238,1,33,33,33,1,0, + 0,0,3,165,165,165,1,90,90,90,1,0,0,0,2,184,184,184,1,90, + 90,90,1,0,0,0,1,57,57,57,1,230,230,230,1,0,0,0,4,255, + 255,255,2,0,0,0,4,238,238,238,1,33,33,33,1,0,0,0,3,165, + 165,165,1,90,90,90,1,0,0,0,2,36,36,36,1,205,205,205,1,197, + 197,197,1,223,223,223,1,61,61,61,1,0,0,0,4,255,255,255,2,0, + 0,0,15,17,17,17,1,0,0,0,6,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,25,0,0) + ); + +const + objdata_tmsewordfield: record size: integer; data: array[0..1436] of byte end = + (size: 1437; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,109,115, + 101,119,111,114,100,102,105,101,108,100,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,36,5,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,244,1,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,184,255,255,25,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208, + 208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,1,0,0,0,2,208,208,208,3,0,0,0,2,208, + 208,208,4,0,0,0,1,208,208,208,4,0,0,0,2,208,208,208,3,184, + 255,255,2,208,208,208,1,0,0,0,2,208,208,208,3,0,0,0,2,208, + 208,208,3,0,0,0,2,208,208,208,3,0,0,0,5,208,208,208,1,184, + 255,255,2,208,208,208,1,0,0,0,2,208,208,208,3,0,0,0,2,208, + 208,208,1,0,0,0,4,208,208,208,2,0,0,0,3,208,208,208,1,0, + 0,0,2,208,208,208,1,184,255,255,2,208,208,208,1,0,0,0,2,208, + 208,208,3,0,0,0,2,208,208,208,1,0,0,0,4,208,208,208,2,0, + 0,0,4,208,208,208,3,184,255,255,2,208,208,208,1,0,0,0,2,208, + 208,208,3,0,0,0,2,208,208,208,3,0,0,0,2,208,208,208,2,0, + 0,0,6,208,208,208,1,184,255,255,2,208,208,208,1,0,0,0,2,208, + 208,208,3,0,0,0,2,208,208,208,3,0,0,0,2,208,208,208,2,0, + 0,0,3,208,208,208,1,0,0,0,2,208,208,208,1,184,255,255,2,208, + 208,208,1,0,0,0,2,208,208,208,3,0,0,0,2,208,208,208,3,0, + 0,0,2,208,208,208,2,0,0,0,2,208,208,208,2,0,0,0,2,208, + 208,208,1,184,255,255,2,208,208,208,1,0,0,0,3,208,208,208,1,0, + 0,0,3,208,208,208,3,0,0,0,2,208,208,208,2,0,0,0,6,208, + 208,208,1,184,255,255,2,208,208,208,2,0,0,0,5,208,208,208,4,0, + 0,0,2,208,208,208,3,0,0,0,5,208,208,208,1,184,255,255,2,208, + 208,208,4,0,0,0,1,208,208,208,12,0,0,0,2,208,208,208,3,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208, + 208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,25,248,2,0,0,255,255,255,25,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0, + 0,0,22,255,255,255,2,0,0,0,1,15,15,15,1,11,11,11,1,0, + 0,0,3,7,7,7,1,17,17,17,1,0,0,0,4,22,22,22,1,0, + 0,0,4,2,2,2,1,12,12,12,1,0,0,0,3,255,255,255,2,0, + 0,0,1,162,162,162,1,117,117,117,1,0,0,0,3,82,82,82,1,189, + 189,189,1,0,0,0,3,75,75,75,1,220,220,220,1,0,0,0,3,99, + 99,99,1,219,219,219,1,207,207,207,1,170,170,170,1,2,2,2,1,0, + 0,0,1,255,255,255,2,0,0,0,1,162,162,162,1,117,117,117,1,0, + 0,0,3,82,82,82,1,189,189,189,1,0,0,0,1,4,4,4,1,127, + 127,127,1,232,232,232,1,222,222,222,1,0,0,0,2,29,29,29,1,223, + 223,223,1,20,20,20,1,0,0,0,1,164,164,164,1,79,79,79,1,0, + 0,0,1,255,255,255,2,0,0,0,1,162,162,162,1,117,117,117,1,0, + 0,0,3,82,82,82,1,189,189,189,1,0,0,0,1,28,28,28,1,147, + 147,147,1,52,52,52,1,222,222,222,1,0,0,0,2,112,112,112,1,138, + 138,138,1,14,14,14,1,34,34,34,1,0,0,0,3,255,255,255,2,0, + 0,0,1,162,162,162,1,117,117,117,1,0,0,0,3,82,82,82,1,189, + 189,189,1,0,0,0,3,33,33,33,1,222,222,222,1,0,0,0,2,141, + 141,141,1,178,178,178,1,217,217,217,1,203,203,203,1,184,184,184,1,11, + 11,11,1,0,0,0,1,255,255,255,2,0,0,0,1,159,159,159,1,120, + 120,120,1,0,0,0,3,87,87,87,1,186,186,186,1,0,0,0,3,33, + 33,33,1,222,222,222,1,0,0,0,2,152,152,152,1,211,211,211,1,3, + 3,3,1,0,0,0,1,165,165,165,1,92,92,92,1,0,0,0,1,255, + 255,255,2,0,0,0,1,126,126,126,1,146,146,146,1,0,0,0,3,139, + 139,139,1,155,155,155,1,0,0,0,3,33,33,33,1,222,222,222,1,0, + 0,0,2,127,127,127,1,144,144,144,1,0,0,0,2,103,103,103,1,157, + 157,157,1,0,0,0,1,255,255,255,2,0,0,0,1,73,73,73,1,225, + 225,225,1,26,26,26,1,0,0,0,1,38,38,38,1,213,213,213,1,98, + 98,98,1,0,0,0,3,33,33,33,1,222,222,222,1,0,0,0,2,53, + 53,53,1,212,212,212,1,9,9,9,1,2,2,2,1,179,179,179,1,106, + 106,106,1,0,0,0,1,255,255,255,2,0,0,0,2,123,123,123,1,229, + 229,229,1,226,226,226,1,232,232,232,1,139,139,139,1,0,0,0,4,33, + 33,33,1,222,222,222,1,0,0,0,3,123,123,123,1,217,217,217,1,213, + 213,213,1,166,166,166,1,4,4,4,1,0,0,0,1,255,255,255,2,0, + 0,0,4,18,18,18,1,0,0,0,12,6,6,6,1,11,11,11,1,0, + 0,0,3,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,25,0,0) + ); + +const + objdata_tmseautoincfield: record size: integer; data: array[0..1447] of byte end = + (size: 1448; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,109,115, + 101,97,117,116,111,105,110,99,102,105,101,108,100,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,44,5, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,244,1, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,184,255,255,25,208,208, + 208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255, + 255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208, + 208,22,184,255,255,2,208,208,208,2,0,0,0,2,208,208,208,1,0,0, + 0,2,208,208,208,3,0,0,0,2,208,208,208,4,0,0,0,2,208,208, + 208,4,184,255,255,2,208,208,208,2,0,0,0,2,208,208,208,1,0,0, + 0,2,208,208,208,3,0,0,0,2,208,208,208,2,0,0,0,6,208,208, + 208,2,184,255,255,2,208,208,208,2,0,0,0,2,208,208,208,1,0,0, + 0,3,208,208,208,2,0,0,0,2,208,208,208,1,0,0,0,3,208,208, + 208,1,0,0,0,3,208,208,208,2,184,255,255,2,208,208,208,2,0,0, + 0,2,208,208,208,1,0,0,0,4,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,2,208,208,208,3,0,0,0,2,208,208,208,2,184,255, + 255,2,208,208,208,2,0,0,0,2,208,208,208,1,0,0,0,4,208,208, + 208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,7,184,255, + 255,2,208,208,208,2,0,0,0,2,208,208,208,1,0,0,0,7,208,208, + 208,1,0,0,0,2,208,208,208,7,184,255,255,2,208,208,208,2,0,0, + 0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,4,208,208, + 208,1,0,0,0,2,208,208,208,3,0,0,0,3,208,208,208,1,184,255, + 255,2,208,208,208,2,0,0,0,2,208,208,208,1,0,0,0,2,208,208, + 208,2,0,0,0,3,208,208,208,1,0,0,0,3,208,208,208,1,0,0, + 0,3,208,208,208,2,184,255,255,2,208,208,208,2,0,0,0,2,208,208, + 208,1,0,0,0,2,208,208,208,2,0,0,0,3,208,208,208,2,0,0, + 0,6,208,208,208,2,184,255,255,2,208,208,208,16,0,0,0,2,208,208, + 208,4,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255, + 255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208, + 208,22,184,255,255,2,208,208,208,22,184,255,255,25,0,3,0,0,255,255, + 255,25,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0, + 0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255, + 255,2,0,0,0,22,255,255,255,2,0,0,0,2,19,19,19,1,6,6, + 6,1,0,0,0,1,20,20,20,1,6,6,6,1,0,0,0,3,13,13, + 13,1,11,11,11,1,0,0,0,4,33,33,33,1,10,10,10,1,0,0, + 0,4,255,255,255,2,0,0,0,2,206,206,206,1,65,65,65,1,0,0, + 0,1,221,221,221,1,159,159,159,1,0,0,0,3,141,141,141,1,122,122, + 122,1,0,0,0,2,97,97,97,1,224,224,224,1,200,200,200,1,221,221, + 221,1,173,173,173,1,9,9,9,1,0,0,0,2,255,255,255,2,0,0, + 0,2,206,206,206,1,65,65,65,1,0,0,0,1,221,221,221,1,245,245, + 245,1,74,74,74,1,0,0,0,2,141,141,141,1,122,122,122,1,0,0, + 0,1,86,86,86,1,223,223,223,1,25,25,25,1,0,0,0,1,1,1, + 1,1,164,164,164,1,143,143,143,1,0,0,0,2,255,255,255,2,0,0, + 0,2,206,206,206,1,65,65,65,1,0,0,0,1,221,221,221,1,111,111, + 111,1,228,228,228,1,15,15,15,1,0,0,0,1,141,141,141,1,122,122, + 122,1,0,0,0,1,184,184,184,1,85,85,85,1,0,0,0,3,18,18, + 18,1,59,59,59,1,0,0,0,2,255,255,255,2,0,0,0,2,206,206, + 206,1,65,65,65,1,0,0,0,1,221,221,221,1,34,34,34,1,160,160, + 160,1,158,158,158,1,0,0,0,1,141,141,141,1,122,122,122,1,0,0, + 0,1,237,237,237,1,36,36,36,1,0,0,0,7,255,255,255,2,0,0, + 0,2,206,206,206,1,65,65,65,1,0,0,0,1,221,221,221,1,34,34, + 34,1,16,16,16,1,228,228,228,1,73,73,73,1,141,141,141,1,122,122, + 122,1,0,0,0,1,229,229,229,1,45,45,45,1,0,0,0,7,255,255, + 255,2,0,0,0,2,206,206,206,1,65,65,65,1,0,0,0,1,221,221, + 221,1,34,34,34,1,0,0,0,1,74,74,74,1,227,227,227,1,156,156, + 156,1,122,122,122,1,0,0,0,1,177,177,177,1,98,98,98,1,0,0, + 0,3,40,40,40,1,176,176,176,1,4,4,4,1,0,0,0,1,255,255, + 255,2,0,0,0,2,206,206,206,1,65,65,65,1,0,0,0,1,221,221, + 221,1,34,34,34,1,0,0,0,2,158,158,158,1,250,250,250,1,122,122, + 122,1,0,0,0,1,63,63,63,1,231,231,231,1,41,41,41,1,0,0, + 0,1,17,17,17,1,181,181,181,1,125,125,125,1,0,0,0,2,255,255, + 255,2,0,0,0,2,206,206,206,1,65,65,65,1,0,0,0,1,221,221, + 221,1,34,34,34,1,0,0,0,2,15,15,15,1,227,227,227,1,122,122, + 122,1,0,0,0,2,95,95,95,1,206,206,206,1,218,218,218,1,222,222, + 222,1,145,145,145,1,7,7,7,1,0,0,0,2,255,255,255,2,0,0, + 0,16,12,12,12,1,1,1,1,1,0,0,0,4,255,255,255,2,0,0, + 0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255, + 255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0, + 0,22,255,255,255,25,0,0) + ); + +const + objdata_tmsefloatfield: record size: integer; data: array[0..1033] of byte end = + (size: 1034; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,109,115, + 101,102,108,111,97,116,102,105,101,108,100,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,144,3,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,92,1,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,184,255,255,25,208,208,208,22, + 184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2, + 208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22, + 184,255,255,2,208,208,208,6,0,0,0,2,208,208,208,7,0,0,0,1, + 208,208,208,6,184,255,255,2,208,208,208,5,0,0,0,3,208,208,208,5, + 0,0,0,5,208,208,208,4,184,255,255,2,208,208,208,4,0,0,0,4, + 208,208,208,5,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,4, + 184,255,255,2,208,208,208,4,0,0,0,4,208,208,208,5,0,0,0,2, + 208,208,208,1,0,0,0,3,208,208,208,3,184,255,255,2,208,208,208,6, + 0,0,0,2,208,208,208,7,0,0,0,3,208,208,208,4,184,255,255,2, + 208,208,208,6,0,0,0,2,208,208,208,6,0,0,0,4,208,208,208,4, + 184,255,255,2,208,208,208,6,0,0,0,2,208,208,208,5,0,0,0,4, + 208,208,208,5,184,255,255,2,208,208,208,6,0,0,0,2,208,208,208,2, + 0,0,0,2,208,208,208,1,0,0,0,3,208,208,208,6,184,255,255,2, + 208,208,208,6,0,0,0,2,208,208,208,2,0,0,0,9,208,208,208,3, + 184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2, + 208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22, + 184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,25, + 252,1,0,0,255,255,255,25,0,0,0,22,255,255,255,2,0,0,0,22, + 255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2, + 0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,6, + 15,15,15,1,7,7,7,1,0,0,0,7,11,11,11,1,0,0,0,6, + 255,255,255,2,0,0,0,5,17,17,17,1,221,221,221,1,57,57,57,1, + 0,0,0,5,52,52,52,1,192,192,192,1,205,205,205,1,199,199,199,1, + 70,70,70,1,0,0,0,4,255,255,255,2,0,0,0,4,67,67,67,1, + 218,218,218,1,242,242,242,1,57,57,57,1,0,0,0,5,185,185,185,1, + 76,76,76,1,0,0,0,1,54,54,54,1,213,213,213,1,0,0,0,4, + 255,255,255,2,0,0,0,4,137,137,137,1,56,56,56,1,198,198,198,1, + 57,57,57,1,0,0,0,5,67,67,67,1,3,3,3,1,0,0,0,1, + 24,24,24,1,248,248,248,1,8,8,8,1,0,0,0,3,255,255,255,2, + 0,0,0,6,198,198,198,1,57,57,57,1,0,0,0,7,1,1,1,1, + 158,158,158,1,156,156,156,1,0,0,0,4,255,255,255,2,0,0,0,6, + 198,198,198,1,57,57,57,1,0,0,0,6,3,3,3,1,161,161,161,1, + 185,185,185,1,10,10,10,1,0,0,0,4,255,255,255,2,0,0,0,6, + 198,198,198,1,57,57,57,1,0,0,0,5,6,6,6,1,172,172,172,1, + 169,169,169,1,6,6,6,1,0,0,0,5,255,255,255,2,0,0,0,6, + 198,198,198,1,57,57,57,1,0,0,0,2,21,21,21,1,14,14,14,1, + 0,0,0,1,158,158,158,1,150,150,150,1,1,1,1,1,0,0,0,6, + 255,255,255,2,0,0,0,6,198,198,198,1,57,57,57,1,0,0,0,2, + 174,174,174,1,113,113,113,1,33,33,33,1,254,254,254,1,249,249,249,1, + 248,248,248,3,26,26,26,1,0,0,0,3,255,255,255,2,0,0,0,22, + 255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2, + 0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22, + 255,255,255,2,0,0,0,22,255,255,255,25,0,0) + ); + +const + objdata_tmsecurrencyfield: record size: integer; data: array[0..1232] of byte end = + (size: 1233; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,109,115, + 101,99,117,114,114,101,110,99,121,102,105,101,108,100,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,84, + 4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,116, + 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,184,255,255,25,208, + 208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208, + 208,208,22,184,255,255,2,208,208,208,4,0,0,0,4,208,208,208,6,0, + 0,0,3,208,208,208,5,184,255,255,2,208,208,208,4,0,0,0,5,208, + 208,208,4,0,0,0,5,208,208,208,4,184,255,255,2,208,208,208,3,0, + 0,0,6,208,208,208,4,0,0,0,5,208,208,208,4,184,255,255,2,208, + 208,208,3,0,0,0,4,208,208,208,6,0,0,0,3,208,208,208,6,184, + 255,255,2,208,208,208,3,0,0,0,5,208,208,208,5,0,0,0,5,208, + 208,208,4,184,255,255,2,208,208,208,5,0,0,0,4,208,208,208,5,0, + 0,0,5,208,208,208,3,184,255,255,2,208,208,208,3,0,0,0,6,208, + 208,208,3,0,0,0,2,208,208,208,1,0,0,0,4,208,208,208,3,184, + 255,255,2,208,208,208,3,0,0,0,6,208,208,208,1,0,0,0,8,208, + 208,208,4,184,255,255,2,208,208,208,3,0,0,0,6,208,208,208,1,0, + 0,0,2,208,208,208,1,0,0,0,5,208,208,208,4,184,255,255,2,208, + 208,208,5,0,0,0,2,208,208,208,7,0,0,0,3,208,208,208,5,184, + 255,255,2,208,208,208,5,0,0,0,2,208,208,208,8,0,0,0,1,208, + 208,208,6,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208, + 208,208,22,184,255,255,25,168,2,0,0,255,255,255,25,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,4,1,1,1,1,79,79,79,1,121,121,121,1,5, + 5,5,1,0,0,0,6,24,24,24,1,155,155,155,1,27,27,27,1,0, + 0,0,5,255,255,255,2,0,0,0,4,196,196,196,1,189,189,189,1,204, + 204,204,1,221,221,221,1,13,13,13,1,0,0,0,4,95,95,95,1,211, + 211,211,1,207,207,207,1,216,216,216,1,93,93,93,1,0,0,0,4,255, + 255,255,2,0,0,0,3,64,64,64,1,179,179,179,1,46,46,46,1,105, + 105,105,1,122,122,122,1,70,70,70,1,0,0,0,4,214,214,214,1,30, + 30,30,1,152,152,152,1,43,43,43,1,149,149,149,1,0,0,0,4,255, + 255,255,2,0,0,0,3,75,75,75,1,208,208,208,1,59,59,59,1,105, + 105,105,1,0,0,0,6,224,224,224,1,70,70,70,1,152,152,152,1,0, + 0,0,6,255,255,255,2,0,0,0,3,2,2,2,1,146,146,146,1,238, + 238,238,1,191,191,191,1,69,69,69,1,0,0,0,5,66,66,66,1,224, + 224,224,1,230,230,230,1,115,115,115,1,11,11,11,1,0,0,0,4,255, + 255,255,2,0,0,0,5,58,58,58,1,177,177,177,1,228,228,228,1,96, + 96,96,1,0,0,0,5,2,2,2,1,176,176,176,1,177,177,177,1,201, + 201,201,1,1,1,1,1,0,0,0,3,255,255,255,2,0,0,0,3,43, + 43,43,1,50,50,50,1,46,46,46,1,105,105,105,1,95,95,95,1,177, + 177,177,1,0,0,0,3,9,9,9,1,84,84,84,1,0,0,0,1,152, + 152,152,1,3,3,3,1,241,241,241,1,27,27,27,1,0,0,0,3,255, + 255,255,2,0,0,0,3,96,96,96,1,193,193,193,1,51,51,51,1,105, + 105,105,1,140,140,140,1,113,113,113,1,0,0,0,1,21,21,21,1,14, + 14,14,1,4,4,4,1,240,240,240,1,48,48,48,1,152,152,152,1,35, + 35,35,1,217,217,217,1,0,0,0,4,255,255,255,2,0,0,0,3,9, + 9,9,1,177,177,177,1,229,229,229,1,224,224,224,1,171,171,171,1,18, + 18,18,1,0,0,0,1,174,174,174,1,113,113,113,1,0,0,0,1,91, + 91,91,1,234,234,234,1,226,226,226,1,202,202,202,1,76,76,76,1,0, + 0,0,4,255,255,255,2,0,0,0,5,59,59,59,1,112,112,112,1,0, + 0,0,7,4,4,4,1,164,164,164,1,1,1,1,1,0,0,0,5,255, + 255,255,2,0,0,0,5,7,7,7,1,16,16,16,1,0,0,0,8,23, + 23,23,1,0,0,0,6,255,255,255,2,0,0,0,22,255,255,255,2,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,25,0,0) + ); + +const + objdata_tmsebooleanfield: record size: integer; data: array[0..1107] of byte end = + (size: 1108; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,109,115, + 101,98,111,111,108,101,97,110,102,105,101,108,100,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,216,3, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,124,1, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,184,255,255,25,208,208, + 208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255, + 255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208, + 208,22,184,255,255,2,208,208,208,2,0,0,0,7,208,208,208,2,0,0, + 0,8,208,208,208,3,184,255,255,2,208,208,208,2,0,0,0,8,208,208, + 208,1,0,0,0,8,208,208,208,3,184,255,255,2,208,208,208,5,0,0, + 0,2,208,208,208,4,0,0,0,4,208,208,208,7,184,255,255,2,208,208, + 208,5,0,0,0,2,208,208,208,3,0,0,0,2,208,208,208,1,0,0, + 0,2,208,208,208,7,184,255,255,2,208,208,208,5,0,0,0,2,208,208, + 208,3,0,0,0,2,208,208,208,1,0,0,0,6,208,208,208,3,184,255, + 255,2,208,208,208,5,0,0,0,2,208,208,208,3,0,0,0,2,208,208, + 208,1,0,0,0,6,208,208,208,3,184,255,255,2,208,208,208,5,0,0, + 0,2,208,208,208,2,0,0,0,2,208,208,208,2,0,0,0,2,208,208, + 208,7,184,255,255,2,208,208,208,5,0,0,0,2,208,208,208,2,0,0, + 0,2,208,208,208,2,0,0,0,2,208,208,208,7,184,255,255,2,208,208, + 208,5,0,0,0,2,208,208,208,2,0,0,0,2,208,208,208,2,0,0, + 0,2,208,208,208,7,184,255,255,2,208,208,208,9,0,0,0,2,208,208, + 208,11,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255, + 255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208, + 208,22,184,255,255,2,208,208,208,22,184,255,255,25,36,2,0,0,255,255, + 255,25,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0, + 0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255, + 255,2,0,0,0,22,255,255,255,2,0,0,0,2,9,9,9,1,24,24, + 24,6,0,0,0,2,21,21,21,1,22,22,22,1,14,14,14,1,24,24, + 24,4,19,19,19,1,0,0,0,3,255,255,255,2,0,0,0,2,86,86, + 86,1,224,224,224,2,246,246,246,1,235,235,235,1,224,224,224,2,4,4, + 4,1,0,0,0,1,140,140,140,1,60,60,60,1,159,159,159,1,238,238, + 238,1,224,224,224,3,182,182,182,1,0,0,0,3,255,255,255,2,0,0, + 0,5,178,178,178,1,93,93,93,1,0,0,0,4,197,197,197,1,4,4, + 4,1,159,159,159,1,112,112,112,1,0,0,0,7,255,255,255,2,0,0, + 0,5,178,178,178,1,93,93,93,1,0,0,0,3,28,28,28,1,174,174, + 174,1,0,0,0,1,159,159,159,1,112,112,112,1,0,0,0,7,255,255, + 255,2,0,0,0,5,178,178,178,1,93,93,93,1,0,0,0,3,99,99, + 99,1,103,103,103,1,0,0,0,1,159,159,159,1,202,202,202,1,160,160, + 160,3,35,35,35,1,0,0,0,3,255,255,255,2,0,0,0,5,178,178, + 178,1,93,93,93,1,0,0,0,3,171,171,171,1,32,32,32,1,0,0, + 0,1,159,159,159,1,162,162,162,1,88,88,88,3,19,19,19,1,0,0, + 0,3,255,255,255,2,0,0,0,5,178,178,178,1,93,93,93,1,0,0, + 0,2,3,3,3,1,201,201,201,1,0,0,0,2,159,159,159,1,112,112, + 112,1,0,0,0,7,255,255,255,2,0,0,0,5,178,178,178,1,93,93, + 93,1,0,0,0,2,59,59,59,1,146,146,146,1,0,0,0,2,159,159, + 159,1,112,112,112,1,0,0,0,7,255,255,255,2,0,0,0,5,178,178, + 178,1,93,93,93,1,0,0,0,2,131,131,131,1,75,75,75,1,0,0, + 0,2,159,159,159,1,112,112,112,1,0,0,0,7,255,255,255,2,0,0, + 0,9,21,21,21,1,4,4,4,1,0,0,0,11,255,255,255,2,0,0, + 0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255, + 255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0, + 0,22,255,255,255,25,0,0) + ); + +const + objdata_tmsedatetimefield: record size: integer; data: array[0..1204] of byte end = + (size: 1205; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,109,115, + 101,100,97,116,101,116,105,109,101,102,105,101,108,100,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,56, + 4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,132, + 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,184,255,255,25,208, + 208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208, + 208,208,22,184,255,255,2,208,208,208,2,0,0,0,5,208,208,208,6,0, + 0,0,7,208,208,208,2,184,255,255,2,208,208,208,2,0,0,0,7,208, + 208,208,4,0,0,0,7,208,208,208,2,184,255,255,2,208,208,208,2,0, + 0,0,2,208,208,208,2,0,0,0,3,208,208,208,6,0,0,0,3,208, + 208,208,4,184,255,255,2,208,208,208,2,0,0,0,2,208,208,208,3,0, + 0,0,6,208,208,208,2,0,0,0,3,208,208,208,4,184,255,255,2,208, + 208,208,2,0,0,0,2,208,208,208,4,0,0,0,5,208,208,208,2,0, + 0,0,3,208,208,208,4,184,255,255,2,208,208,208,2,0,0,0,2,208, + 208,208,4,0,0,0,2,208,208,208,5,0,0,0,3,208,208,208,4,184, + 255,255,2,208,208,208,2,0,0,0,2,208,208,208,3,0,0,0,3,208, + 208,208,5,0,0,0,3,208,208,208,4,184,255,255,2,208,208,208,2,0, + 0,0,2,208,208,208,1,0,0,0,4,208,208,208,1,0,0,0,3,208, + 208,208,2,0,0,0,3,208,208,208,4,184,255,255,2,208,208,208,2,0, + 0,0,7,208,208,208,1,0,0,0,3,208,208,208,2,0,0,0,3,208, + 208,208,4,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208, + 208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,25,124,2,0,0,255,255,255,25,0,0,0,22,255,255,255,2,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0, + 0,0,2,9,9,9,1,24,24,24,2,19,19,19,1,2,2,2,1,0, + 0,0,6,17,17,17,1,24,24,24,5,16,16,16,1,0,0,0,2,255, + 255,255,2,0,0,0,2,99,99,99,1,245,245,245,1,224,224,224,1,229, + 229,229,1,247,247,247,1,162,162,162,1,14,14,14,1,0,0,0,4,162, + 162,162,1,224,224,224,1,225,225,225,1,255,255,255,1,224,224,224,2,152, + 152,152,1,0,0,0,2,255,255,255,2,0,0,0,2,99,99,99,1,172, + 172,172,1,0,0,0,2,9,9,9,1,179,179,179,1,157,157,157,1,0, + 0,0,6,9,9,9,1,255,255,255,1,6,6,6,1,0,0,0,4,255, + 255,255,2,0,0,0,2,99,99,99,1,172,172,172,1,0,0,0,3,30, + 30,30,1,254,254,254,1,13,13,13,1,16,16,16,1,216,216,216,1,10, + 10,10,1,0,0,0,2,9,9,9,1,255,255,255,1,6,6,6,1,0, + 0,0,4,255,255,255,2,0,0,0,2,99,99,99,1,172,172,172,1,0, + 0,0,4,233,233,233,1,57,57,57,1,5,5,5,1,72,72,72,1,3, + 3,3,1,0,0,0,2,9,9,9,1,255,255,255,1,6,6,6,1,0, + 0,0,4,255,255,255,2,0,0,0,2,99,99,99,1,172,172,172,1,0, + 0,0,4,232,232,232,1,56,56,56,1,0,0,0,5,9,9,9,1,255, + 255,255,1,6,6,6,1,0,0,0,4,255,255,255,2,0,0,0,2,99, + 99,99,1,172,172,172,1,0,0,0,3,28,28,28,1,250,250,250,1,18, + 18,18,1,0,0,0,5,9,9,9,1,255,255,255,1,6,6,6,1,0, + 0,0,4,255,255,255,2,0,0,0,2,99,99,99,1,172,172,172,1,0, + 0,0,1,1,1,1,1,28,28,28,1,181,181,181,1,154,154,154,1,0, + 0,0,1,2,2,2,1,32,32,32,1,1,1,1,1,0,0,0,2,9, + 9,9,1,255,255,255,1,6,6,6,1,0,0,0,4,255,255,255,2,0, + 0,0,2,99,99,99,1,253,253,253,1,248,248,248,2,230,230,230,1,145, + 145,145,1,7,7,7,1,0,0,0,1,18,18,18,1,255,255,255,1,13, + 13,13,1,0,0,0,2,9,9,9,1,255,255,255,1,6,6,6,1,0, + 0,0,4,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,25,0,0) + ); + +const + objdata_tmsedatefield: record size: integer; data: array[0..896] of byte end = + (size: 897; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,109,115, + 101,100,97,116,101,102,105,101,108,100,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,8,3,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,44,1,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,184,255,255,25,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208, + 208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,7,0,0,0,5,208,208,208,10,184,255,255,2,208, + 208,208,7,0,0,0,7,208,208,208,8,184,255,255,2,208,208,208,7,0, + 0,0,2,208,208,208,2,0,0,0,3,208,208,208,8,184,255,255,2,208, + 208,208,7,0,0,0,2,208,208,208,3,0,0,0,3,208,208,208,7,184, + 255,255,2,208,208,208,7,0,0,0,2,208,208,208,4,0,0,0,2,208, + 208,208,7,184,255,255,2,208,208,208,7,0,0,0,2,208,208,208,4,0, + 0,0,2,208,208,208,7,184,255,255,2,208,208,208,7,0,0,0,2,208, + 208,208,3,0,0,0,3,208,208,208,7,184,255,255,2,208,208,208,7,0, + 0,0,2,208,208,208,2,0,0,0,3,208,208,208,8,184,255,255,2,208, + 208,208,7,0,0,0,7,208,208,208,8,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208, + 208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,25,164,1,0,0,255,255,255,25,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0, + 0,0,22,255,255,255,2,0,0,0,7,8,8,8,1,24,24,24,2,20, + 20,20,1,2,2,2,1,0,0,0,10,255,255,255,2,0,0,0,7,89, + 89,89,1,246,246,246,1,224,224,224,1,229,229,229,1,248,248,248,1,167, + 167,167,1,17,17,17,1,0,0,0,8,255,255,255,2,0,0,0,7,89, + 89,89,1,182,182,182,1,0,0,0,2,7,7,7,1,171,171,171,1,167, + 167,167,1,0,0,0,8,255,255,255,2,0,0,0,7,89,89,89,1,182, + 182,182,1,0,0,0,3,21,21,21,1,255,255,255,1,21,21,21,1,0, + 0,0,7,255,255,255,2,0,0,0,7,89,89,89,1,182,182,182,1,0, + 0,0,4,223,223,223,1,67,67,67,1,0,0,0,7,255,255,255,2,0, + 0,0,7,89,89,89,1,182,182,182,1,0,0,0,4,222,222,222,1,66, + 66,66,1,0,0,0,7,255,255,255,2,0,0,0,7,89,89,89,1,182, + 182,182,1,0,0,0,3,21,21,21,1,250,250,250,1,26,26,26,1,0, + 0,0,7,255,255,255,2,0,0,0,7,89,89,89,1,182,182,182,1,0, + 0,0,2,25,25,25,1,174,174,174,1,164,164,164,1,0,0,0,8,255, + 255,255,2,0,0,0,7,89,89,89,1,253,253,253,1,248,248,248,2,232, + 232,232,1,151,151,151,1,9,9,9,1,0,0,0,8,255,255,255,2,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,25,0,0) + ); + +const + objdata_tmsetimefield: record size: integer; data: array[0..732] of byte end = + (size: 733; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,109,115, + 101,116,105,109,101,102,105,101,108,100,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,100,2,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,252,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,184,255,255,25,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208, + 208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,7,0,0,0,7,208,208,208,8,184,255,255,2,208, + 208,208,7,0,0,0,8,208,208,208,7,184,255,255,2,208,208,208,10,0, + 0,0,2,208,208,208,10,184,255,255,2,208,208,208,10,0,0,0,2,208, + 208,208,10,184,255,255,2,208,208,208,10,0,0,0,2,208,208,208,10,184, + 255,255,2,208,208,208,10,0,0,0,2,208,208,208,10,184,255,255,2,208, + 208,208,10,0,0,0,2,208,208,208,10,184,255,255,2,208,208,208,10,0, + 0,0,2,208,208,208,10,184,255,255,2,208,208,208,10,0,0,0,2,208, + 208,208,10,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208, + 208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,25,48,1,0,0,255,255,255,25,0,0,0,22,255,255,255,2,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0, + 0,0,7,8,8,8,1,24,24,24,6,0,0,0,8,255,255,255,2,0, + 0,0,7,82,82,82,1,224,224,224,2,245,245,245,1,236,236,236,1,224, + 224,224,2,8,8,8,1,0,0,0,7,255,255,255,2,0,0,0,10,174, + 174,174,1,97,97,97,1,0,0,0,10,255,255,255,2,0,0,0,10,174, + 174,174,1,97,97,97,1,0,0,0,10,255,255,255,2,0,0,0,10,174, + 174,174,1,97,97,97,1,0,0,0,10,255,255,255,2,0,0,0,10,174, + 174,174,1,97,97,97,1,0,0,0,10,255,255,255,2,0,0,0,10,174, + 174,174,1,97,97,97,1,0,0,0,10,255,255,255,2,0,0,0,10,174, + 174,174,1,97,97,97,1,0,0,0,10,255,255,255,2,0,0,0,10,174, + 174,174,1,97,97,97,1,0,0,0,10,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,25,0,0) + ); + +const + objdata_tmsebinaryfield: record size: integer; data: array[0..1386] of byte end = + (size: 1387; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,109,115, + 101,98,105,110,97,114,121,102,105,101,108,100,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,240,4,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,180,1,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,184,255,255,25,208,208,208, + 22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255, + 2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208, + 22,184,255,255,2,208,208,208,2,0,0,0,4,208,208,208,4,0,0,0, + 2,208,208,208,1,0,0,0,2,208,208,208,3,0,0,0,2,208,208,208, + 2,184,255,255,2,208,208,208,2,0,0,0,6,208,208,208,2,0,0,0, + 5,208,208,208,3,0,0,0,2,208,208,208,2,184,255,255,2,208,208,208, + 2,0,0,0,2,208,208,208,2,0,0,0,2,208,208,208,2,0,0,0, + 6,208,208,208,2,0,0,0,2,208,208,208,2,184,255,255,2,208,208,208, + 2,0,0,0,2,208,208,208,2,0,0,0,2,208,208,208,2,0,0,0, + 7,208,208,208,1,0,0,0,2,208,208,208,2,184,255,255,2,208,208,208, + 2,0,0,0,6,208,208,208,2,0,0,0,7,208,208,208,1,0,0,0, + 2,208,208,208,2,184,255,255,2,208,208,208,2,0,0,0,7,208,208,208, + 1,0,0,0,4,208,208,208,1,0,0,0,5,208,208,208,2,184,255,255, + 2,208,208,208,2,0,0,0,2,208,208,208,3,0,0,0,2,208,208,208, + 1,0,0,0,4,208,208,208,2,0,0,0,4,208,208,208,2,184,255,255, + 2,208,208,208,2,0,0,0,2,208,208,208,2,0,0,0,3,208,208,208, + 1,0,0,0,4,208,208,208,2,0,0,0,4,208,208,208,2,184,255,255, + 2,208,208,208,2,0,0,0,6,208,208,208,2,0,0,0,4,208,208,208, + 3,0,0,0,3,208,208,208,2,184,255,255,2,208,208,208,22,184,255,255, + 2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208, + 22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255, + 2,208,208,208,22,184,255,255,25,4,3,0,0,255,255,255,25,0,0,0, + 22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255, + 2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0, + 22,255,255,255,2,0,0,0,2,17,17,17,1,24,24,24,2,13,13,13, + 1,0,0,0,4,22,22,22,1,2,2,2,1,0,0,0,1,24,24,24, + 1,2,2,2,1,0,0,0,3,16,16,16,1,7,7,7,1,0,0,0, + 2,255,255,255,2,0,0,0,2,191,191,191,1,235,235,235,1,224,224,224, + 1,237,237,237,1,223,223,223,1,60,60,60,1,0,0,0,2,245,245,245, + 1,26,26,26,1,3,3,3,1,255,255,255,1,121,121,121,1,0,0,0, + 3,179,179,179,1,84,84,84,1,0,0,0,2,255,255,255,2,0,0,0, + 2,191,191,191,1,88,88,88,1,0,0,0,2,85,85,85,1,210,210,210, + 1,0,0,0,2,245,245,245,1,26,26,26,1,3,3,3,1,254,254,254, + 1,239,239,239,1,42,42,42,1,0,0,0,2,179,179,179,1,84,84,84, + 1,0,0,0,2,255,255,255,2,0,0,0,2,191,191,191,1,88,88,88, + 1,0,0,0,2,52,52,52,1,211,211,211,1,0,0,0,2,245,245,245, + 1,26,26,26,1,3,3,3,1,252,252,252,1,115,115,115,1,202,202,202, + 1,3,3,3,1,0,0,0,1,179,179,179,1,84,84,84,1,0,0,0, + 2,255,255,255,2,0,0,0,2,191,191,191,1,203,203,203,1,176,176,176, + 1,185,185,185,1,236,236,236,1,54,54,54,1,0,0,0,2,245,245,245, + 1,26,26,26,1,3,3,3,1,252,252,252,1,2,2,2,1,197,197,197, + 1,120,120,120,1,0,0,0,1,179,179,179,1,84,84,84,1,0,0,0, + 2,255,255,255,2,0,0,0,2,191,191,191,1,135,135,135,1,72,72,72, + 1,80,80,80,1,137,137,137,1,213,213,213,1,9,9,9,1,0,0,0, + 1,245,245,245,1,26,26,26,1,3,3,3,1,252,252,252,1,0,0,0, + 1,37,37,37,1,238,238,238,1,41,41,41,1,179,179,179,1,84,84,84, + 1,0,0,0,2,255,255,255,2,0,0,0,2,191,191,191,1,88,88,88, + 1,0,0,0,3,210,210,210,1,74,74,74,1,0,0,0,1,245,245,245, + 1,26,26,26,1,3,3,3,1,252,252,252,1,0,0,0,2,112,112,112, + 1,201,201,201,1,183,183,183,1,84,84,84,1,0,0,0,2,255,255,255, + 2,0,0,0,2,191,191,191,1,88,88,88,1,0,0,0,2,48,48,48, + 1,241,241,241,1,41,41,41,1,0,0,0,1,245,245,245,1,26,26,26, + 1,3,3,3,1,252,252,252,1,0,0,0,2,2,2,2,1,194,194,194, + 1,250,250,250,1,84,84,84,1,0,0,0,2,255,255,255,2,0,0,0, + 2,191,191,191,1,250,250,250,1,248,248,248,1,245,245,245,1,222,222,222, + 1,103,103,103,1,0,0,0,2,245,245,245,1,26,26,26,1,3,3,3, + 1,252,252,252,1,0,0,0,3,36,36,36,1,245,245,245,1,84,84,84, + 1,0,0,0,2,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0, + 22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255, + 2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0, + 22,255,255,255,25,0,0) + ); + +const + objdata_tmsebytesfield: record size: integer; data: array[0..1385] of byte end = + (size: 1386; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,109,115, + 101,98,121,116,101,115,102,105,101,108,100,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,240,4,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,164,1,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,184,255,255,25,208,208,208,22, + 184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2, + 208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22, + 184,255,255,2,0,0,0,4,208,208,208,18,184,255,255,2,0,0,0,6, + 208,208,208,7,0,0,0,2,208,208,208,7,184,255,255,2,0,0,0,2, + 208,208,208,2,0,0,0,3,208,208,208,6,0,0,0,2,208,208,208,7, + 184,255,255,2,0,0,0,2,208,208,208,2,0,0,0,5,208,208,208,2, + 0,0,0,5,208,208,208,1,0,0,0,4,208,208,208,1,184,255,255,2, + 0,0,0,6,208,208,208,1,0,0,0,2,208,208,208,2,0,0,0,4, + 208,208,208,1,0,0,0,6,184,255,255,2,0,0,0,7,208,208,208,1, + 0,0,0,4,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,6, + 184,255,255,2,0,0,0,2,208,208,208,3,0,0,0,2,208,208,208,1, + 0,0,0,4,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,6, + 184,255,255,2,0,0,0,2,208,208,208,2,0,0,0,3,208,208,208,1, + 0,0,0,4,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,3, + 208,208,208,1,0,0,0,2,184,255,255,2,0,0,0,6,208,208,208,3, + 0,0,0,2,208,208,208,2,0,0,0,9,184,255,255,2,208,208,208,9, + 0,0,0,2,208,208,208,3,0,0,0,2,208,208,208,2,0,0,0,2, + 208,208,208,2,184,255,255,2,208,208,208,7,0,0,0,3,208,208,208,12, + 184,255,255,2,208,208,208,7,0,0,0,3,208,208,208,12,184,255,255,2, + 208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22, + 184,255,255,2,208,208,208,22,184,255,255,25,20,3,0,0,255,255,255,25, + 0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22, + 255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2, + 0,0,0,22,255,255,255,2,15,15,15,1,24,24,24,2,16,16,16,1, + 0,0,0,18,255,255,255,2,162,162,162,1,238,238,238,1,224,224,224,1, + 235,235,235,1,230,230,230,1,80,80,80,1,0,0,0,7,34,34,34,1, + 117,117,117,1,0,0,0,7,255,255,255,2,162,162,162,1,117,117,117,1, + 0,0,0,2,56,56,56,1,236,236,236,1,3,3,3,1,0,0,0,6, + 82,82,82,1,165,165,165,1,0,0,0,7,255,255,255,2,162,162,162,1, + 117,117,117,1,0,0,0,2,25,25,25,1,235,235,235,1,3,3,3,1, + 120,120,120,1,107,107,107,1,0,0,0,2,107,107,107,1,109,109,109,1, + 212,212,212,1,233,233,233,1,123,123,123,1,0,0,0,1,88,88,88,1, + 191,191,191,1,196,196,196,1,94,94,94,1,0,0,0,1,255,255,255,2, + 162,162,162,1,212,212,212,1,176,176,176,1,183,183,183,1,233,233,233,1, + 79,79,79,1,0,0,0,1,53,53,53,1,212,212,212,1,0,0,0,2, + 212,212,212,1,32,32,32,1,82,82,82,1,165,165,165,1,0,0,0,1, + 86,86,86,1,204,204,204,1,18,18,18,1,23,23,23,1,199,199,199,1, + 82,82,82,1,255,255,255,2,162,162,162,1,156,156,156,1,72,72,72,1, + 78,78,78,1,124,124,124,1,220,220,220,1,26,26,26,1,0,0,0,1, + 211,211,211,1,48,48,48,1,52,52,52,1,191,191,191,1,0,0,0,1, + 82,82,82,1,165,165,165,1,0,0,0,1,162,162,162,1,188,188,188,1, + 128,128,128,2,187,187,187,1,153,153,153,1,255,255,255,2,162,162,162,1, + 117,117,117,1,0,0,0,3,181,181,181,1,103,103,103,1,0,0,0,1, + 114,114,114,1,140,140,140,1,144,144,144,1,96,96,96,1,0,0,0,1, + 82,82,82,1,165,165,165,1,0,0,0,1,170,170,170,1,156,156,156,1, + 80,80,80,3,54,54,54,1,255,255,255,2,162,162,162,1,117,117,117,1, + 0,0,0,2,33,33,33,1,228,228,228,1,69,69,69,1,0,0,0,1, + 22,22,22,1,217,217,217,1,212,212,212,1,12,12,12,1,0,0,0,1, + 75,75,75,1,172,172,172,1,0,0,0,1,113,113,113,1,196,196,196,1, + 5,5,5,1,0,0,0,1,150,150,150,1,84,84,84,1,255,255,255,2, + 162,162,162,1,251,251,251,1,248,248,248,1,246,246,246,1,228,228,228,1, + 124,124,124,1,0,0,0,3,176,176,176,1,160,160,160,1,0,0,0,2, + 32,32,32,1,234,234,234,1,159,159,159,1,6,6,6,1,167,167,167,1, + 230,230,230,1,199,199,199,1,168,168,168,1,4,4,4,1,255,255,255,2, + 0,0,0,9,178,178,178,1,60,60,60,1,0,0,0,3,1,1,1,1, + 6,6,6,1,0,0,0,2,10,10,10,1,8,8,8,1,0,0,0,2, + 255,255,255,2,0,0,0,7,46,46,46,1,171,171,171,1,191,191,191,1, + 0,0,0,12,255,255,255,2,0,0,0,7,15,15,15,1,80,80,80,1, + 14,14,14,1,0,0,0,12,255,255,255,2,0,0,0,22,255,255,255,2, + 0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22, + 255,255,255,25,0,0) + ); + +const + objdata_tmseguidfield: record size: integer; data: array[0..1424] of byte end = + (size: 1425; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,109,115, + 101,103,117,105,100,102,105,101,108,100,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,24,5,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,196,1,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,184,255,255,25,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208, + 208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,4,0,0,0,2,208,208,208,8,0,0,0,2,208, + 208,208,4,0,0,0,1,208,208,208,1,184,255,255,2,208,208,208,2,0, + 0,0,6,208,208,208,6,0,0,0,2,208,208,208,4,0,0,0,1,208, + 208,208,1,184,255,255,2,208,208,208,1,0,0,0,3,208,208,208,1,0, + 0,0,3,208,208,208,6,0,0,0,2,208,208,208,4,0,0,0,1,208, + 208,208,1,184,255,255,2,208,208,208,1,0,0,0,2,208,208,208,3,0, + 0,0,4,208,208,208,2,0,0,0,4,208,208,208,1,0,0,0,4,208, + 208,208,1,184,255,255,2,208,208,208,1,0,0,0,2,208,208,208,1,0, + 0,0,6,208,208,208,2,0,0,0,9,208,208,208,1,184,255,255,2,208, + 208,208,1,0,0,0,2,208,208,208,1,0,0,0,6,208,208,208,2,0, + 0,0,6,208,208,208,1,0,0,0,2,208,208,208,1,184,255,255,2,208, + 208,208,1,0,0,0,2,208,208,208,3,0,0,0,4,208,208,208,2,0, + 0,0,6,208,208,208,2,0,0,0,1,208,208,208,1,184,255,255,2,208, + 208,208,1,0,0,0,3,208,208,208,1,0,0,0,3,208,208,208,1,0, + 0,0,12,208,208,208,1,184,255,255,2,208,208,208,2,0,0,0,6,208, + 208,208,1,0,0,0,7,208,208,208,1,0,0,0,4,208,208,208,1,184, + 255,255,2,208,208,208,4,0,0,0,2,208,208,208,4,0,0,0,2,208, + 208,208,6,0,0,0,1,208,208,208,3,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208, + 208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,25,28,3,0,0,255,255,255,25,0,0,0,22,255,255,255,2,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0, + 0,0,4,37,37,37,1,15,15,15,1,0,0,0,8,10,10,10,2,0, + 0,0,4,21,21,21,1,0,0,0,1,255,255,255,2,0,0,0,2,97, + 97,97,1,218,218,218,1,191,191,191,1,224,224,224,1,153,153,153,1,3, + 3,3,1,0,0,0,6,109,109,109,1,114,114,114,1,0,0,0,4,224, + 224,224,1,0,0,0,1,255,255,255,2,0,0,0,1,59,59,59,1,203, + 203,203,1,21,21,21,1,0,0,0,1,4,4,4,1,178,178,178,1,83, + 83,83,1,0,0,0,6,6,6,6,1,7,7,7,1,0,0,0,4,224, + 224,224,1,0,0,0,1,255,255,255,2,0,0,0,1,157,157,157,1,82, + 82,82,1,0,0,0,3,36,36,36,1,41,41,41,1,1,1,1,1,187, + 187,187,1,0,0,0,2,149,149,149,1,39,39,39,1,92,92,92,1,96, + 96,96,1,0,0,0,1,115,115,115,1,220,220,220,1,174,174,174,1,231, + 231,231,1,0,0,0,1,255,255,255,2,0,0,0,1,209,209,209,1,32, + 32,32,1,0,0,0,1,10,10,10,1,32,32,32,2,22,22,22,1,1, + 1,1,1,222,222,222,1,0,0,0,2,177,177,177,1,46,46,46,1,109, + 109,109,1,114,114,114,1,50,50,50,1,203,203,203,1,15,15,15,1,85, + 85,85,1,253,253,253,1,0,0,0,1,255,255,255,2,0,0,0,1,208, + 208,208,1,40,40,40,1,0,0,0,1,69,69,69,1,216,216,216,1,223, + 223,223,1,181,181,181,1,1,1,1,1,222,222,222,1,0,0,0,2,177, + 177,177,1,46,46,46,1,109,109,109,1,114,114,114,1,106,106,106,1,134, + 134,134,1,0,0,0,1,4,4,4,1,242,242,242,1,0,0,0,1,255, + 255,255,2,0,0,0,1,156,156,156,1,94,94,94,1,0,0,0,3,50, + 50,50,1,181,181,181,1,1,1,1,1,224,224,224,1,0,0,0,2,186, + 186,186,1,46,46,46,1,109,109,109,1,114,114,114,1,111,111,111,1,127, + 127,127,1,0,0,0,2,230,230,230,1,0,0,0,1,255,255,255,2,0, + 0,0,1,52,52,52,1,225,225,225,1,52,52,52,1,0,0,0,1,8, + 8,8,1,134,134,134,1,178,178,178,1,0,0,0,1,232,232,232,1,12, + 12,12,2,231,231,231,1,46,46,46,1,109,109,109,1,114,114,114,1,57, + 57,57,1,197,197,197,1,4,4,4,1,50,50,50,1,253,253,253,1,0, + 0,0,1,255,255,255,2,0,0,0,2,72,72,72,1,204,204,204,1,226, + 226,226,1,237,237,237,1,165,165,165,1,22,22,22,1,0,0,0,1,137, + 137,137,1,221,221,221,1,196,196,196,1,187,187,187,1,46,46,46,1,109, + 109,109,1,114,114,114,1,0,0,0,1,140,140,140,1,215,215,215,1,157, + 157,157,1,221,221,221,1,0,0,0,1,255,255,255,2,0,0,0,4,14, + 14,14,1,3,3,3,1,0,0,0,4,14,14,14,1,1,1,1,1,0, + 0,0,6,9,9,9,1,0,0,0,3,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,25,0,0) + ); + +const + objdata_tmsevarbytesfield: record size: integer; data: array[0..1400] of byte end = + (size: 1401; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,109,115, + 101,118,97,114,98,121,116,101,115,102,105,101,108,100,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,252, + 4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,184, + 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,184,255,255,25,208, + 208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208, + 208,208,22,184,255,255,2,0,0,0,2,208,208,208,4,0,0,0,7,208, + 208,208,9,184,255,255,2,0,0,0,3,208,208,208,3,0,0,0,9,208, + 208,208,7,184,255,255,2,208,208,208,1,0,0,0,2,208,208,208,3,0, + 0,0,4,208,208,208,2,0,0,0,3,208,208,208,7,184,255,255,2,208, + 208,208,1,0,0,0,2,208,208,208,2,0,0,0,5,208,208,208,3,0, + 0,0,5,208,208,208,1,0,0,0,3,184,255,255,2,208,208,208,1,0, + 0,0,3,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,7,208, + 208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,184, + 255,255,2,208,208,208,2,0,0,0,5,208,208,208,1,0,0,0,7,208, + 208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,184, + 255,255,2,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,2,208, + 208,208,3,0,0,0,2,208,208,208,1,0,0,0,4,208,208,208,2,184, + 255,255,2,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,2,208, + 208,208,2,0,0,0,3,208,208,208,2,0,0,0,3,208,208,208,2,184, + 255,255,2,208,208,208,3,0,0,0,3,208,208,208,2,0,0,0,7,208, + 208,208,2,0,0,0,3,208,208,208,2,184,255,255,2,208,208,208,17,0, + 0,0,2,208,208,208,3,184,255,255,2,208,208,208,16,0,0,0,3,208, + 208,208,3,184,255,255,2,208,208,208,16,0,0,0,2,208,208,208,4,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208, + 208,208,22,184,255,255,2,208,208,208,22,184,255,255,25,12,3,0,0,255, + 255,255,25,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,2,10,10,10,1,17,17,17,1,0, + 0,0,4,4,4,4,1,21,21,21,1,3,3,3,1,24,24,24,2,23, + 23,23,1,4,4,4,1,0,0,0,9,255,255,255,2,55,55,55,1,232, + 232,232,1,3,3,3,1,0,0,0,3,98,98,98,1,178,178,178,1,39, + 39,39,1,254,254,254,1,224,224,224,1,226,226,226,1,241,241,241,1,174, + 174,174,1,11,11,11,1,0,0,0,7,255,255,255,2,0,0,0,1,212, + 212,212,1,71,71,71,1,0,0,0,3,194,194,194,1,78,78,78,1,39, + 39,39,1,240,240,240,1,0,0,0,2,4,4,4,1,185,185,185,1,106, + 106,106,1,0,0,0,7,255,255,255,2,0,0,0,1,113,113,113,1,162, + 162,162,1,0,0,0,2,34,34,34,1,229,229,229,1,4,4,4,1,39, + 39,39,1,240,240,240,1,0,0,0,3,157,157,157,1,106,106,106,1,19, + 19,19,1,202,202,202,1,5,5,5,1,0,0,0,1,10,10,10,1,194, + 194,194,1,3,3,3,1,255,255,255,2,0,0,0,1,21,21,21,1,237, + 237,237,1,10,10,10,1,0,0,0,1,128,128,128,1,134,134,134,1,0, + 0,0,1,39,39,39,1,251,251,251,1,176,176,176,1,177,177,177,1,202, + 202,202,1,195,195,195,1,6,6,6,1,0,0,0,1,186,186,186,1,78, + 78,78,1,0,0,0,1,91,91,91,1,153,153,153,1,0,0,0,1,255, + 255,255,2,0,0,0,2,172,172,172,1,88,88,88,1,1,1,1,1,221, + 221,221,1,36,36,36,1,0,0,0,1,39,39,39,1,244,244,244,1,72, + 72,72,2,91,91,91,1,198,198,198,1,121,121,121,1,0,0,0,1,89, + 89,89,1,171,171,171,1,0,0,0,1,185,185,185,1,58,58,58,1,0, + 0,0,1,255,255,255,2,0,0,0,2,73,73,73,1,179,179,179,1,63, + 63,63,1,191,191,191,1,0,0,0,2,39,39,39,1,240,240,240,1,0, + 0,0,3,58,58,58,1,226,226,226,1,0,0,0,1,8,8,8,1,231, + 231,231,1,39,39,39,1,215,215,215,1,0,0,0,2,255,255,255,2,0, + 0,0,2,2,2,2,1,220,220,220,1,162,162,162,1,91,91,91,1,0, + 0,0,2,39,39,39,1,240,240,240,1,0,0,0,2,5,5,5,1,134, + 134,134,1,191,191,191,1,0,0,0,2,151,151,151,1,190,190,190,1,122, + 122,122,1,0,0,0,2,255,255,255,2,0,0,0,3,131,131,131,1,237, + 237,237,1,8,8,8,1,0,0,0,2,39,39,39,1,255,255,255,1,248, + 248,248,1,247,247,247,1,239,239,239,1,191,191,191,1,38,38,38,1,0, + 0,0,2,54,54,54,1,253,253,253,1,29,29,29,1,0,0,0,2,255, + 255,255,2,0,0,0,17,56,56,56,1,182,182,182,1,0,0,0,3,255, + 255,255,2,0,0,0,16,129,129,129,1,218,218,218,1,62,62,62,1,0, + 0,0,3,255,255,255,2,0,0,0,16,61,61,61,1,49,49,49,1,0, + 0,0,4,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,25,0, + 0) + ); + +const + objdata_tmsebcdfield: record size: integer; data: array[0..1439] of byte end = + (size: 1440; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,109,115, + 101,98,99,100,102,105,101,108,100,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,40,5,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,200,1,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,184,255,255,25,208,208,208,22,184,255, + 255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208, + 208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255, + 255,2,208,208,208,1,0,0,0,4,208,208,208,5,0,0,0,2,208,208, + 208,3,0,0,0,4,208,208,208,3,184,255,255,2,208,208,208,1,0,0, + 0,5,208,208,208,2,0,0,0,6,208,208,208,1,0,0,0,6,208,208, + 208,1,184,255,255,2,208,208,208,1,0,0,0,1,208,208,208,2,0,0, + 0,3,208,208,208,1,0,0,0,2,208,208,208,2,0,0,0,2,208,208, + 208,1,0,0,0,2,208,208,208,2,0,0,0,3,184,255,255,2,208,208, + 208,1,0,0,0,1,208,208,208,2,0,0,0,6,208,208,208,2,0,0, + 0,2,208,208,208,1,0,0,0,2,208,208,208,3,0,0,0,2,184,255, + 255,2,208,208,208,1,0,0,0,5,208,208,208,1,0,0,0,2,208,208, + 208,6,0,0,0,2,208,208,208,3,0,0,0,2,184,255,255,2,208,208, + 208,1,0,0,0,8,208,208,208,6,0,0,0,2,208,208,208,3,0,0, + 0,2,184,255,255,2,208,208,208,1,0,0,0,1,208,208,208,3,0,0, + 0,5,208,208,208,2,0,0,0,5,208,208,208,2,0,0,0,3,184,255, + 255,2,208,208,208,1,0,0,0,1,208,208,208,2,0,0,0,3,208,208, + 208,1,0,0,0,6,208,208,208,1,0,0,0,2,208,208,208,1,0,0, + 0,3,208,208,208,1,184,255,255,2,208,208,208,1,0,0,0,6,208,208, + 208,1,0,0,0,6,208,208,208,1,0,0,0,6,208,208,208,1,184,255, + 255,2,208,208,208,10,0,0,0,2,208,208,208,10,184,255,255,2,208,208, + 208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255, + 255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208, + 208,22,184,255,255,25,40,3,0,0,255,255,255,25,0,0,0,22,255,255, + 255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0, + 0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255, + 255,2,0,0,0,1,23,23,23,1,24,24,24,1,22,22,22,1,1,1, + 1,1,0,0,0,5,17,17,17,1,22,22,22,1,0,0,0,3,16,16, + 16,1,24,24,24,1,23,23,23,1,8,8,8,1,0,0,0,3,255,255, + 255,2,0,0,0,1,247,247,247,1,224,224,224,1,227,227,227,1,238,238, + 238,1,118,118,118,1,0,0,0,2,15,15,15,1,187,187,187,1,219,219, + 219,1,211,211,211,1,188,188,188,1,18,18,18,1,0,0,0,1,180,180, + 180,1,232,232,232,1,224,224,224,1,244,244,244,1,195,195,195,1,33,33, + 33,1,0,0,0,1,255,255,255,2,0,0,0,1,247,247,247,1,0,0, + 0,2,17,17,17,1,228,228,228,1,21,21,21,1,0,0,0,1,190,190, + 190,1,115,115,115,1,0,0,0,2,127,127,127,1,155,155,155,1,0,0, + 0,1,180,180,180,1,67,67,67,1,0,0,0,2,121,121,121,1,192,192, + 192,1,1,1,1,1,255,255,255,2,0,0,0,1,247,247,247,1,0,0, + 0,2,3,3,3,1,217,217,217,1,21,21,21,1,26,26,26,1,221,221, + 221,1,1,1,1,1,0,0,0,2,8,8,8,1,62,62,62,1,0,0, + 0,1,180,180,180,1,67,67,67,1,0,0,0,3,234,234,234,1,38,38, + 38,1,255,255,255,2,0,0,0,1,247,247,247,1,176,176,176,1,178,178, + 178,1,216,216,216,1,128,128,128,1,0,0,0,1,76,76,76,1,175,175, + 175,1,0,0,0,6,180,180,180,1,67,67,67,1,0,0,0,3,185,185, + 185,1,75,75,75,1,255,255,255,2,0,0,0,1,247,247,247,1,72,72, + 72,1,73,73,73,1,101,101,101,1,217,217,217,1,43,43,43,1,69,69, + 69,1,182,182,182,1,0,0,0,6,180,180,180,1,67,67,67,1,0,0, + 0,3,182,182,182,1,74,74,74,1,255,255,255,2,0,0,0,1,247,247, + 247,1,0,0,0,3,130,130,130,1,124,124,124,1,20,20,20,1,226,226, + 226,1,2,2,2,1,0,0,0,2,18,18,18,1,174,174,174,1,3,3, + 3,1,180,180,180,1,67,67,67,1,0,0,0,2,3,3,3,1,225,225, + 225,1,37,37,37,1,255,255,255,2,0,0,0,1,247,247,247,1,0,0, + 0,2,13,13,13,1,191,191,191,1,94,94,94,1,0,0,0,1,167,167, + 167,1,131,131,131,1,2,2,2,1,7,7,7,1,148,148,148,1,133,133, + 133,1,0,0,0,1,180,180,180,1,67,67,67,1,0,0,0,1,10,10, + 10,1,129,129,129,1,190,190,190,1,0,0,0,1,255,255,255,2,0,0, + 0,1,247,247,247,1,248,248,248,1,247,247,247,1,236,236,236,1,156,156, + 156,1,3,3,3,1,0,0,0,1,14,14,14,1,173,173,173,1,222,222, + 222,1,223,223,223,1,156,156,156,1,13,13,13,1,0,0,0,1,180,180, + 180,1,250,250,250,1,248,248,248,1,240,240,240,1,176,176,176,1,23,23, + 23,1,0,0,0,1,255,255,255,2,0,0,0,10,5,5,5,1,7,7, + 7,1,0,0,0,10,255,255,255,2,0,0,0,22,255,255,255,2,0,0, + 0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255, + 255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,25,0,0) + ); + +const + objdata_tmseblobfield: record size: integer; data: array[0..1444] of byte end = + (size: 1445; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,109,115, + 101,98,108,111,98,102,105,101,108,100,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,44,5,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,188,1,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,184,255,255,25,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208, + 208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,1,0,0,0,4,208,208,208,3,0,0,0,2,208, + 208,208,6,0,0,0,2,208,208,208,4,184,255,255,2,208,208,208,1,0, + 0,0,6,208,208,208,1,0,0,0,2,208,208,208,6,0,0,0,2,208, + 208,208,4,184,255,255,2,208,208,208,1,0,0,0,2,208,208,208,2,0, + 0,0,2,208,208,208,1,0,0,0,2,208,208,208,6,0,0,0,2,208, + 208,208,4,184,255,255,2,208,208,208,1,0,0,0,2,208,208,208,2,0, + 0,0,2,208,208,208,1,0,0,0,7,208,208,208,1,0,0,0,5,208, + 208,208,1,184,255,255,2,208,208,208,1,0,0,0,6,208,208,208,1,0, + 0,0,7,208,208,208,1,0,0,0,5,208,208,208,1,184,255,255,2,208, + 208,208,1,0,0,0,6,208,208,208,1,0,0,0,4,208,208,208,2,0, + 0,0,4,208,208,208,1,0,0,0,2,208,208,208,1,184,255,255,2,208, + 208,208,1,0,0,0,2,208,208,208,2,0,0,0,7,208,208,208,2,0, + 0,0,4,208,208,208,1,0,0,0,2,208,208,208,1,184,255,255,2,208, + 208,208,1,0,0,0,2,208,208,208,2,0,0,0,13,208,208,208,1,0, + 0,0,2,208,208,208,1,184,255,255,2,208,208,208,1,0,0,0,6,208, + 208,208,1,0,0,0,7,208,208,208,1,0,0,0,5,208,208,208,1,184, + 255,255,2,208,208,208,12,0,0,0,2,208,208,208,4,0,0,0,1,208, + 208,208,3,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208, + 208,208,22,184,255,255,2,208,208,208,22,184,255,255,25,56,3,0,0,255, + 255,255,25,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,2,0,0,0,1,9,9,9,1,24, + 24,24,2,14,14,14,1,0,0,0,3,15,15,15,1,5,5,5,1,0, + 0,0,6,16,16,16,1,5,5,5,1,0,0,0,4,255,255,255,2,0, + 0,0,1,104,104,104,1,241,241,241,1,224,224,224,1,236,236,236,1,214, + 214,214,1,35,35,35,1,0,0,0,1,170,170,170,1,61,61,61,1,0, + 0,0,6,176,176,176,1,55,55,55,1,0,0,0,4,255,255,255,2,0, + 0,0,1,104,104,104,1,143,143,143,1,0,0,0,2,104,104,104,1,161, + 161,161,1,0,0,0,1,170,170,170,1,61,61,61,1,0,0,0,6,176, + 176,176,1,55,55,55,1,0,0,0,4,255,255,255,2,0,0,0,1,104, + 104,104,1,143,143,143,1,0,0,0,2,80,80,80,1,162,162,162,1,0, + 0,0,1,170,170,170,1,61,61,61,1,2,2,2,1,124,124,124,1,210, + 210,210,1,173,173,173,1,49,49,49,1,0,0,0,1,176,176,176,1,136, + 136,136,1,208,208,208,1,192,192,192,1,24,24,24,1,0,0,0,1,255, + 255,255,2,0,0,0,1,104,104,104,1,220,220,220,1,176,176,176,1,185, + 185,185,1,230,230,230,1,29,29,29,1,0,0,0,1,170,170,170,1,61, + 61,61,1,98,98,98,1,187,187,187,1,15,15,15,1,57,57,57,1,202, + 202,202,1,0,0,0,1,176,176,176,1,169,169,169,1,7,7,7,1,125, + 125,125,1,160,160,160,1,0,0,0,1,255,255,255,2,0,0,0,1,104, + 104,104,1,175,175,175,1,72,72,72,1,80,80,80,1,152,152,152,1,171, + 171,171,1,0,0,0,1,170,170,170,1,61,61,61,1,159,159,159,1,93, + 93,93,1,0,0,0,2,206,206,206,1,29,29,29,1,176,176,176,1,75, + 75,75,1,0,0,0,1,35,35,35,1,222,222,222,1,0,0,0,1,255, + 255,255,2,0,0,0,1,104,104,104,1,143,143,143,1,0,0,0,2,1, + 1,1,1,239,239,239,1,14,14,14,1,170,170,170,1,61,61,61,1,165, + 165,165,1,84,84,84,1,0,0,0,2,201,201,201,1,46,46,46,1,176, + 176,176,1,58,58,58,1,0,0,0,1,28,28,28,1,220,220,220,1,0, + 0,0,1,255,255,255,2,0,0,0,1,104,104,104,1,143,143,143,1,0, + 0,0,2,63,63,63,1,235,235,235,1,1,1,1,1,170,170,170,1,61, + 61,61,1,113,113,113,1,166,166,166,1,1,1,1,1,28,28,28,1,243, + 243,243,1,6,6,6,1,176,176,176,1,133,133,133,1,0,0,0,1,102, + 102,102,1,162,162,162,1,0,0,0,1,255,255,255,2,0,0,0,1,104, + 104,104,1,252,252,252,1,248,248,248,1,245,245,245,1,215,215,215,1,73, + 73,73,1,0,0,0,1,170,170,170,1,61,61,61,1,9,9,9,1,144, + 144,144,1,203,203,203,1,225,225,225,1,80,80,80,1,0,0,0,1,176, + 176,176,1,152,152,152,1,201,201,201,1,174,174,174,1,29,29,29,1,0, + 0,0,1,255,255,255,2,0,0,0,12,9,9,9,1,2,2,2,1,0, + 0,0,4,7,7,7,1,0,0,0,3,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255, + 255,255,25,0,0) + ); + +const + objdata_tmsememofield: record size: integer; data: array[0..1800] of byte end = + (size: 1801; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,109,115, + 101,109,101,109,111,102,105,101,108,100,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,144,6,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,60,2,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,184,255,255,25,208,208,208,22,184, + 255,255,2,208,208,208,5,0,0,0,2,208,208,208,3,0,0,0,3,208, + 208,208,9,184,255,255,2,208,208,208,5,0,0,0,2,208,208,208,3,0, + 0,0,3,208,208,208,9,184,255,255,2,208,208,208,5,0,0,0,3,208, + 208,208,1,0,0,0,4,208,208,208,1,0,0,0,3,208,208,208,5,184, + 255,255,2,208,208,208,5,0,0,0,3,208,208,208,1,0,0,0,9,208, + 208,208,4,184,255,255,2,208,208,208,5,0,0,0,3,208,208,208,1,0, + 0,0,6,208,208,208,1,0,0,0,2,208,208,208,4,184,255,255,2,208, + 208,208,5,0,0,0,1,208,208,208,1,0,0,0,12,208,208,208,3,184, + 255,255,2,208,208,208,5,0,0,0,1,208,208,208,1,0,0,0,3,208, + 208,208,1,0,0,0,4,208,208,208,1,0,0,0,3,208,208,208,3,184, + 255,255,2,208,208,208,5,0,0,0,1,208,208,208,1,0,0,0,3,208, + 208,208,1,0,0,0,7,208,208,208,4,184,255,255,2,208,208,208,5,0, + 0,0,1,208,208,208,2,0,0,0,2,208,208,208,1,0,0,0,2,208, + 208,208,1,0,0,0,4,208,208,208,4,184,255,255,2,208,208,208,22,184, + 255,255,2,208,208,208,22,184,255,255,2,208,208,208,5,0,0,0,2,208, + 208,208,3,0,0,0,3,208,208,208,9,184,255,255,2,208,208,208,5,0, + 0,0,2,208,208,208,3,0,0,0,3,208,208,208,9,184,255,255,2,208, + 208,208,5,0,0,0,3,208,208,208,2,0,0,0,3,208,208,208,9,184, + 255,255,2,208,208,208,5,0,0,0,3,208,208,208,1,0,0,0,9,208, + 208,208,4,184,255,255,2,208,208,208,5,0,0,0,3,208,208,208,1,0, + 0,0,9,208,208,208,4,184,255,255,2,208,208,208,5,0,0,0,3,208, + 208,208,1,0,0,0,6,208,208,208,1,0,0,0,3,208,208,208,3,184, + 255,255,2,208,208,208,5,0,0,0,1,208,208,208,1,0,0,0,3,208, + 208,208,1,0,0,0,4,208,208,208,2,0,0,0,2,208,208,208,3,184, + 255,255,2,208,208,208,5,0,0,0,1,208,208,208,1,0,0,0,3,208, + 208,208,1,0,0,0,4,208,208,208,1,0,0,0,2,208,208,208,4,184, + 255,255,2,208,208,208,5,0,0,0,1,208,208,208,1,0,0,0,3,208, + 208,208,1,0,0,0,7,208,208,208,4,184,255,255,2,208,208,208,22,184, + 255,255,25,28,4,0,0,255,255,255,25,0,0,0,22,255,255,255,2,0, + 0,0,5,143,143,143,1,92,92,92,1,0,0,0,3,53,53,53,1,152, + 152,152,1,8,8,8,1,0,0,0,9,255,255,255,2,0,0,0,5,241, + 241,241,1,212,212,212,1,0,0,0,3,153,153,153,1,253,253,253,1,13, + 13,13,1,0,0,0,9,255,255,255,2,0,0,0,5,240,240,240,1,189, + 189,189,1,37,37,37,1,0,0,0,1,1,1,1,1,199,199,199,1,227, + 227,227,1,13,13,13,1,0,0,0,1,8,8,8,1,93,93,93,1,34, + 34,34,1,0,0,0,5,255,255,255,2,0,0,0,5,240,240,240,1,110, + 110,110,1,114,114,114,1,0,0,0,1,56,56,56,1,144,144,144,1,226, + 226,226,1,13,13,13,1,45,45,45,1,203,203,203,1,120,120,120,1,190, + 190,190,1,105,105,105,1,0,0,0,4,255,255,255,2,0,0,0,5,240, + 240,240,1,31,31,31,1,190,190,190,1,0,0,0,1,136,136,136,1,63, + 63,63,1,226,226,226,1,13,13,13,1,155,155,155,1,95,95,95,1,0, + 0,0,1,11,11,11,1,194,194,194,1,0,0,0,4,255,255,255,2,0, + 0,0,5,240,240,240,1,0,0,0,1,203,203,203,1,16,16,16,1,196, + 196,196,1,3,3,3,1,226,226,226,1,13,13,13,1,188,188,188,1,216, + 216,216,1,208,208,208,2,206,206,206,1,12,12,12,1,0,0,0,3,255, + 255,255,2,0,0,0,5,240,240,240,1,0,0,0,1,128,128,128,1,126, + 126,126,1,158,158,158,1,0,0,0,1,226,226,226,1,13,13,13,1,132, + 132,132,1,97,97,97,1,0,0,0,1,1,1,1,1,78,78,78,1,1, + 1,1,1,0,0,0,3,255,255,255,2,0,0,0,5,240,240,240,1,0, + 0,0,1,49,49,49,1,246,246,246,1,78,78,78,1,0,0,0,1,226, + 226,226,1,13,13,13,1,50,50,50,1,212,212,212,1,83,83,83,1,138, + 138,138,1,164,164,164,1,0,0,0,4,255,255,255,2,0,0,0,5,120, + 120,120,1,0,0,0,2,122,122,122,1,8,8,8,1,0,0,0,1,113, + 113,113,1,6,6,6,1,0,0,0,1,29,29,29,1,127,127,127,1,96, + 96,96,1,13,13,13,1,0,0,0,4,255,255,255,2,0,0,0,22,255, + 255,255,2,0,0,0,22,255,255,255,2,0,0,0,5,22,22,22,1,12, + 12,12,1,0,0,0,3,6,6,6,1,24,24,24,1,1,1,1,1,0, + 0,0,9,255,255,255,2,0,0,0,5,242,242,242,1,178,178,178,1,0, + 0,0,3,113,113,113,1,255,255,255,1,13,13,13,1,0,0,0,9,255, + 255,255,2,0,0,0,5,240,240,240,1,218,218,218,1,9,9,9,1,0, + 0,0,2,187,187,187,1,239,239,239,1,13,13,13,1,0,0,0,9,255, + 255,255,2,0,0,0,5,240,240,240,1,149,149,149,1,76,76,76,1,0, + 0,0,1,20,20,20,1,181,181,181,1,226,226,226,1,13,13,13,1,10, + 10,10,1,138,138,138,1,214,214,214,1,160,160,160,1,36,36,36,1,0, + 0,0,4,255,255,255,2,0,0,0,5,240,240,240,1,70,70,70,1,152, + 152,152,1,0,0,0,1,96,96,96,1,104,104,104,1,226,226,226,1,13, + 13,13,1,129,129,129,1,163,163,163,1,8,8,8,1,86,86,86,1,173, + 173,173,1,0,0,0,4,255,255,255,2,0,0,0,5,240,240,240,1,6, + 6,6,1,213,213,213,1,0,0,0,1,174,174,174,1,25,25,25,1,226, + 226,226,1,13,13,13,1,190,190,190,1,63,63,63,1,0,0,0,1,2, + 2,2,1,225,225,225,1,9,9,9,1,0,0,0,3,255,255,255,2,0, + 0,0,5,240,240,240,1,0,0,0,1,168,168,168,1,59,59,59,1,189, + 189,189,1,0,0,0,1,226,226,226,1,13,13,13,1,196,196,196,1,53, + 53,53,1,0,0,0,2,231,231,231,1,16,16,16,1,0,0,0,3,255, + 255,255,2,0,0,0,5,240,240,240,1,0,0,0,1,89,89,89,1,201, + 201,201,1,118,118,118,1,0,0,0,1,226,226,226,1,13,13,13,1,144, + 144,144,1,138,138,138,1,0,0,0,1,54,54,54,1,222,222,222,1,0, + 0,0,4,255,255,255,2,0,0,0,5,240,240,240,1,0,0,0,1,15, + 15,15,1,250,250,250,1,37,37,37,1,0,0,0,1,226,226,226,1,13, + 13,13,1,20,20,20,1,157,157,157,1,203,203,203,1,223,223,223,1,57, + 57,57,1,0,0,0,4,255,255,255,2,0,0,0,22,255,255,255,25,0, + 0) + ); + +const + objdata_tmsegraphicfield: record size: integer; data: array[0..1451] of byte end = + (size: 1452; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,109,115, + 101,103,114,97,112,104,105,99,102,105,101,108,100,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,48,5, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,104,4, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,184,255,255,25,255,191, + 141,22,184,255,255,2,255,191,141,22,184,255,255,2,255,194,147,13,255,194, + 146,9,184,255,255,2,255,197,153,3,238,200,160,1,123,218,205,1,21,235, + 247,1,54,230,234,1,167,211,187,1,255,197,153,10,255,197,152,4,184,255, + 255,2,255,201,159,3,123,220,208,1,32,239,250,1,123,249,254,1,98,247, + 254,1,3,237,252,1,218,206,173,1,255,201,159,13,184,255,255,2,255,204, + 165,3,21,236,247,1,123,249,254,1,183,255,255,2,56,241,252,1,118,221, + 212,1,255,204,165,13,184,255,255,2,255,208,171,3,54,232,237,1,98,247, + 254,1,183,255,255,2,32,238,250,1,153,220,204,1,255,208,171,13,184,255, + 255,2,255,211,177,3,167,220,203,1,3,237,252,1,56,241,252,1,32,238, + 250,1,18,235,248,1,244,212,180,1,255,211,177,13,184,255,255,2,255,215, + 183,4,218,218,193,1,118,226,221,1,153,224,211,1,244,216,186,1,255,215, + 183,8,255,214,183,5,248,211,178,1,184,255,255,2,255,218,189,19,197,199, + 145,1,91,174,66,1,12,151,6,1,184,255,255,2,255,222,195,6,255,221, + 195,11,188,200,144,1,77,177,57,1,6,180,3,1,4,181,0,1,4,164, + 0,1,184,255,255,2,255,225,201,15,201,208,159,1,79,184,62,1,7,192, + 4,1,2,194,0,1,3,186,0,1,4,178,0,1,5,162,0,1,184,255, + 255,2,255,228,208,5,255,228,207,8,248,225,201,1,96,189,77,1,11,200, + 8,1,1,207,1,1,2,199,0,1,3,191,0,1,3,183,0,1,4,174, + 0,1,5,162,0,1,184,255,255,2,255,232,214,9,255,232,213,3,251,230, + 210,1,63,184,52,1,0,218,1,1,1,212,1,1,2,204,1,1,2,196, + 0,1,3,187,0,1,4,179,0,1,4,171,0,1,5,162,0,1,184,255, + 255,2,253,101,47,1,254,125,59,1,254,131,70,1,254,137,82,1,254,143, + 93,1,254,150,104,1,254,156,116,1,253,159,121,1,250,148,104,1,248,137, + 85,1,245,126,67,1,243,116,49,1,235,101,30,1,29,162,3,1,1,216, + 1,1,1,208,1,1,2,200,1,1,3,192,0,1,3,184,0,1,4,176, + 0,1,5,171,0,1,5,162,0,1,184,255,255,2,254,120,50,1,255,146, + 61,1,255,154,74,1,255,161,88,1,255,169,101,1,255,176,115,1,255,184, + 129,1,255,191,142,1,252,179,122,1,249,166,100,1,246,153,79,1,243,140, + 57,1,240,126,36,1,176,109,12,1,6,192,1,1,2,205,1,1,2,197, + 0,1,3,189,0,1,4,181,0,1,4,173,0,1,5,171,0,1,5,162, + 0,1,184,255,255,2,254,120,50,1,255,144,58,1,255,152,71,1,255,160, + 85,1,255,167,98,1,255,175,112,1,255,182,126,1,255,190,139,1,252,182, + 126,1,249,169,105,1,246,155,83,1,243,142,62,1,240,129,40,1,237,116, + 19,1,94,125,3,1,2,201,1,1,2,194,0,1,3,186,0,1,4,178, + 0,1,5,171,0,2,5,162,0,1,184,255,255,2,254,120,50,1,255,143, + 55,1,255,150,68,1,255,158,82,1,255,165,95,1,255,173,109,1,255,180, + 123,1,255,188,136,1,253,185,131,1,250,171,110,1,247,158,88,1,244,145, + 67,1,241,132,45,1,238,119,24,1,228,106,2,1,41,150,2,1,3,191, + 0,1,3,183,0,1,4,175,0,1,5,171,0,2,5,162,0,1,184,255, + 255,2,254,120,50,1,255,142,53,1,255,149,65,1,255,156,79,1,255,164, + 92,1,255,171,106,1,255,179,120,1,255,186,133,1,254,187,136,1,251,174, + 114,1,248,161,93,1,245,148,71,1,242,135,50,1,239,122,28,1,236,109, + 7,1,189,111,0,1,28,157,2,1,4,180,0,1,4,171,0,1,5,171, + 0,2,5,162,0,1,184,255,255,2,254,120,50,1,255,142,53,1,255,147, + 62,1,255,155,76,1,255,162,89,1,255,170,103,1,255,177,117,1,255,185, + 130,1,254,190,141,1,251,177,119,1,248,164,98,1,245,151,76,1,242,138, + 55,1,239,125,33,1,236,112,12,1,235,105,0,1,183,111,1,1,23,151, + 2,1,5,171,0,3,5,162,0,1,184,255,255,2,254,120,50,1,255,142, + 53,1,255,145,59,1,255,153,73,1,255,160,86,1,255,168,100,1,255,175, + 114,1,255,183,127,1,255,191,141,1,252,180,124,1,249,167,102,1,246,154, + 81,1,243,141,59,1,240,128,38,1,237,115,16,1,235,105,0,2,178,107, + 2,1,19,151,1,1,5,171,0,2,5,162,0,1,184,255,255,2,253,101, + 47,1,254,120,50,1,254,121,52,1,254,127,64,1,254,134,75,1,254,140, + 87,1,254,147,98,1,254,153,109,1,254,159,121,1,252,154,114,1,250,143, + 95,1,247,132,77,1,244,121,59,1,242,110,41,1,239,99,23,1,237,89, + 5,3,173,89,7,1,13,151,1,1,5,162,0,1,4,155,0,1,184,255, + 255,25,144,0,0,0,255,255,255,255,255,255,255,6,237,237,237,1,235,235, + 235,1,255,255,255,20,247,247,247,1,249,249,249,1,255,255,255,20,252,252, + 252,1,251,251,251,1,255,255,255,20,254,254,254,1,249,249,249,1,255,255, + 255,21,233,233,233,1,255,255,255,22,251,251,251,1,226,226,226,1,255,255, + 255,23,244,244,244,1,245,245,245,1,255,255,255,23,242,242,242,1,255,255, + 255,24,245,245,245,1,255,255,255,24,245,245,245,1,255,255,255,24,242,242, + 242,1,255,255,255,23,252,252,252,1,239,239,239,1,255,255,255,23,246,246, + 246,1,239,239,239,1,255,255,255,27,0,0) + ); + +const + objdata_tmsevariantfield: record size: integer; data: array[0..1399] of byte end = + (size: 1400; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,109,115, + 101,118,97,114,105,97,110,116,102,105,101,108,100,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,252,4, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,192,1, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,184,255,255,25,208,208, + 208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255, + 255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208, + 208,22,184,255,255,1,180,249,249,1,0,0,0,1,208,208,208,5,0,0, + 0,2,208,208,208,1,0,0,0,2,208,208,208,3,0,0,0,5,208,208, + 208,3,184,255,255,1,170,235,235,1,0,0,0,2,208,208,208,3,0,0, + 0,2,208,208,208,2,0,0,0,2,208,208,208,3,0,0,0,7,208,208, + 208,1,184,255,255,2,0,0,0,2,208,208,208,3,0,0,0,2,208,208, + 208,1,0,0,0,4,208,208,208,2,0,0,0,2,208,208,208,3,0,0, + 0,3,184,255,255,2,0,0,0,2,208,208,208,2,0,0,0,3,208,208, + 208,1,0,0,0,4,208,208,208,2,0,0,0,2,208,208,208,3,0,0, + 0,3,184,255,255,2,0,0,0,3,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,6,208,208,208,1,0,0,0,7,208,208,208,1,184,255, + 255,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,6,208,208,208,1,0,0,0,6,208,208,208,2,184,255, + 255,2,208,208,208,1,0,0,0,5,208,208,208,1,0,0,0,9,208,208, + 208,2,0,0,0,3,208,208,208,1,184,255,255,2,208,208,208,2,0,0, + 0,3,208,208,208,1,0,0,0,3,208,208,208,2,0,0,0,5,208,208, + 208,3,0,0,0,3,184,255,255,2,208,208,208,2,0,0,0,3,208,208, + 208,1,0,0,0,2,208,208,208,4,0,0,0,4,208,208,208,3,0,0, + 0,3,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255, + 255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208, + 208,22,184,255,255,2,208,208,208,22,184,255,255,2,208,208,208,22,184,255, + 255,25,4,3,0,0,255,255,255,25,0,0,0,22,255,255,255,2,0,0, + 0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255, + 255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,21,21, + 21,1,0,0,0,5,24,24,24,1,1,1,1,1,0,0,0,1,13,13, + 13,1,14,14,14,1,0,0,0,3,5,5,5,1,24,24,24,3,17,17, + 17,1,0,0,0,3,255,255,255,2,246,246,246,1,24,24,24,1,0,0, + 0,3,57,57,57,1,218,218,218,1,0,0,0,2,196,196,196,1,214,214, + 214,1,0,0,0,3,58,58,58,1,249,249,249,1,208,208,208,2,221,221, + 221,1,241,241,241,1,113,113,113,1,0,0,0,1,255,255,255,2,171,171, + 171,1,112,112,112,1,0,0,0,3,152,152,152,1,120,120,120,1,0,0, + 0,1,42,42,42,1,198,198,198,1,194,194,194,1,64,64,64,1,0,0, + 0,2,58,58,58,1,221,221,221,1,0,0,0,3,52,52,52,1,251,251, + 251,1,19,19,19,1,255,255,255,2,72,72,72,1,203,203,203,1,0,0, + 0,2,8,8,8,1,235,235,235,1,24,24,24,1,0,0,0,1,141,141, + 141,1,120,120,120,1,102,102,102,1,168,168,168,1,0,0,0,2,58,58, + 58,1,221,221,221,1,0,0,0,3,9,9,9,1,239,239,239,1,25,25, + 25,1,255,255,255,2,2,2,2,1,226,226,226,1,39,39,39,1,0,0, + 0,1,87,87,87,1,176,176,176,1,0,0,0,1,5,5,5,1,232,232, + 232,1,29,29,29,1,15,15,15,1,241,241,241,1,22,22,22,1,0,0, + 0,1,58,58,58,1,238,238,238,1,128,128,128,2,140,140,140,1,202,202, + 202,1,139,139,139,1,0,0,0,1,255,255,255,2,0,0,0,1,130,130, + 130,2,0,0,0,1,182,182,182,1,76,76,76,1,0,0,0,1,82,82, + 82,1,219,219,219,1,80,80,80,2,205,205,205,1,119,119,119,1,0,0, + 0,1,58,58,58,1,235,235,235,1,104,104,104,1,114,114,114,1,224,224, + 224,1,107,107,107,1,0,0,0,2,255,255,255,2,0,0,0,1,33,33, + 33,1,219,219,219,1,25,25,25,1,225,225,225,1,3,3,3,1,0,0, + 0,1,181,181,181,1,175,175,175,1,144,144,144,2,164,164,164,1,221,221, + 221,1,1,1,1,1,58,58,58,1,221,221,221,1,0,0,0,2,37,37, + 37,1,239,239,239,1,64,64,64,1,0,0,0,1,255,255,255,2,0,0, + 0,2,189,189,189,1,155,155,155,1,132,132,132,1,0,0,0,1,27,27, + 27,1,243,243,243,1,14,14,14,1,0,0,0,2,3,3,3,1,229,229, + 229,1,71,71,71,1,58,58,58,1,221,221,221,1,0,0,0,3,101,101, + 101,1,225,225,225,1,12,12,12,1,255,255,255,2,0,0,0,2,90,90, + 90,1,253,253,253,1,34,34,34,1,0,0,0,1,123,123,123,1,169,169, + 169,1,0,0,0,4,134,134,134,1,175,175,175,1,58,58,58,1,221,221, + 221,1,0,0,0,3,1,1,1,1,193,193,193,1,147,147,147,1,255,255, + 255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0, + 0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255, + 255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,25,0,0) + ); + +const + objdata_tparamconnector: record size: integer; data: array[0..1390] of byte end = + (size: 1391; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,112,97, + 114,97,109,99,111,110,110,101,99,116,111,114,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,244,4,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,176,1,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,156,156,156,25,208,208,208, + 22,156,156,156,2,208,208,208,22,156,156,156,2,208,208,208,22,156,156,156, + 2,208,208,208,22,156,156,156,2,208,208,208,22,156,156,156,2,208,208,208, + 22,156,156,156,2,208,208,208,1,0,0,0,5,208,208,208,3,0,0,0, + 2,208,208,208,3,0,0,0,5,208,208,208,3,156,156,156,2,208,208,208, + 1,0,0,0,6,208,208,208,2,0,0,0,3,208,208,208,2,0,0,0, + 7,208,208,208,1,156,156,156,2,208,208,208,1,0,0,0,2,208,208,208, + 2,0,0,0,3,208,208,208,1,0,0,0,3,208,208,208,2,0,0,0, + 2,208,208,208,2,0,0,0,3,208,208,208,1,156,156,156,2,208,208,208, + 1,0,0,0,2,208,208,208,3,0,0,0,6,208,208,208,2,0,0,0, + 2,208,208,208,3,0,0,0,2,208,208,208,1,156,156,156,2,208,208,208, + 1,0,0,0,9,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0, + 7,208,208,208,1,156,156,156,2,208,208,208,1,0,0,0,6,208,208,208, + 1,0,0,0,5,208,208,208,1,0,0,0,6,208,208,208,2,156,156,156, + 2,208,208,208,1,0,0,0,2,208,208,208,4,0,0,0,9,208,208,208, + 2,0,0,0,2,208,208,208,2,156,156,156,2,208,208,208,1,0,0,0, + 2,208,208,208,4,0,0,0,2,208,208,208,3,0,0,0,4,208,208,208, + 2,0,0,0,3,208,208,208,1,156,156,156,2,208,208,208,1,0,0,0, + 2,208,208,208,4,0,0,0,2,208,208,208,3,0,0,0,4,208,208,208, + 3,0,0,0,3,156,156,156,2,208,208,208,22,156,156,156,2,208,208,208, + 22,156,156,156,2,208,208,208,22,156,156,156,2,208,208,208,22,156,156,156, + 2,208,208,208,22,156,156,156,2,208,208,208,22,156,156,156,2,208,208,208, + 22,156,156,156,25,12,3,0,0,255,255,255,25,0,0,0,22,255,255,255, + 2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0, + 22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255, + 2,0,0,0,1,6,6,6,1,24,24,24,2,21,21,21,1,3,3,3, + 1,0,0,0,3,4,4,4,1,21,21,21,1,0,0,0,3,8,8,8, + 1,24,24,24,2,23,23,23,1,5,5,5,1,0,0,0,3,255,255,255, + 2,0,0,0,1,70,70,70,1,246,246,246,1,224,224,224,1,225,225,225, + 1,237,237,237,1,132,132,132,1,0,0,0,2,96,96,96,1,248,248,248, + 1,24,24,24,1,0,0,0,2,85,85,85,1,238,238,238,1,208,208,208, + 2,240,240,240,1,180,180,180,1,9,9,9,1,0,0,0,1,255,255,255, + 2,0,0,0,1,70,70,70,1,177,177,177,1,0,0,0,2,20,20,20, + 1,230,230,230,1,41,41,41,1,0,0,0,1,185,185,185,1,151,151,151, + 1,115,115,115,1,0,0,0,2,85,85,85,1,162,162,162,1,0,0,0, + 2,8,8,8,1,193,193,193,1,89,89,89,1,0,0,0,1,255,255,255, + 2,0,0,0,1,70,70,70,1,177,177,177,1,0,0,0,3,200,200,200, + 1,55,55,55,1,21,21,21,1,215,215,215,1,36,36,36,1,210,210,210, + 1,0,0,0,2,85,85,85,1,162,162,162,1,0,0,0,3,154,154,154, + 1,96,96,96,1,0,0,0,1,255,255,255,2,0,0,0,1,70,70,70, + 1,196,196,196,1,64,64,64,1,69,69,69,1,129,129,129,1,225,225,225, + 1,1,1,1,1,106,106,106,1,132,132,132,1,0,0,0,1,204,204,204, + 1,49,49,49,1,0,0,0,1,85,85,85,1,209,209,209,1,128,128,128, + 1,129,129,129,1,163,163,163,1,203,203,203,1,15,15,15,1,0,0,0, + 1,255,255,255,2,0,0,0,1,70,70,70,1,233,233,233,1,184,184,184, + 1,180,180,180,1,148,148,148,1,42,42,42,1,0,0,0,1,195,195,195, + 1,120,120,120,1,80,80,80,1,169,169,169,1,144,144,144,1,0,0,0, + 1,85,85,85,1,200,200,200,1,104,104,104,1,149,149,149,1,210,210,210, + 1,11,11,11,1,0,0,0,2,255,255,255,2,0,0,0,1,70,70,70, + 1,177,177,177,1,0,0,0,4,30,30,30,1,227,227,227,1,144,144,144, + 2,148,148,148,1,233,233,233,1,5,5,5,1,85,85,85,1,162,162,162, + 1,0,0,0,2,153,153,153,1,158,158,158,1,0,0,0,2,255,255,255, + 2,0,0,0,1,70,70,70,1,177,177,177,1,0,0,0,4,117,117,117, + 1,132,132,132,1,0,0,0,3,197,197,197,1,78,78,78,1,85,85,85, + 1,162,162,162,1,0,0,0,2,16,16,16,1,234,234,234,1,63,63,63, + 1,0,0,0,1,255,255,255,2,0,0,0,1,70,70,70,1,177,177,177, + 1,0,0,0,4,206,206,206,1,47,47,47,1,0,0,0,3,105,105,105, + 1,173,173,173,1,85,85,85,1,162,162,162,1,0,0,0,3,102,102,102, + 1,207,207,207,1,2,2,2,1,255,255,255,2,0,0,0,22,255,255,255, + 2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0, + 22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255, + 2,0,0,0,22,255,255,255,25,0,0) + ); + +const + objdata_tsqlresultconnector: record size: integer; data: array[0..1290] of byte end = + (size: 1291; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,115,113, + 108,114,101,115,117,108,116,99,111,110,110,101,99,116,111,114,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,140,4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,144,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,113,200,255, + 25,208,208,208,22,113,200,255,2,208,208,208,22,113,200,255,2,208,208,208, + 22,113,200,255,2,208,208,208,22,113,200,255,2,208,208,208,22,113,200,255, + 2,208,208,208,22,113,200,255,2,208,208,208,3,0,0,0,3,208,208,208, + 5,0,0,0,2,208,208,208,3,0,0,0,2,208,208,208,4,113,200,255, + 2,208,208,208,2,0,0,0,5,208,208,208,2,0,0,0,6,208,208,208, + 1,0,0,0,2,208,208,208,4,113,200,255,2,208,208,208,1,0,0,0, + 3,208,208,208,1,0,0,0,7,208,208,208,1,0,0,0,5,208,208,208, + 4,113,200,255,2,208,208,208,1,0,0,0,2,208,208,208,3,0,0,0, + 4,208,208,208,4,0,0,0,4,208,208,208,4,113,200,255,2,208,208,208, + 1,0,0,0,2,208,208,208,5,0,0,0,2,208,208,208,4,0,0,0, + 4,208,208,208,4,113,200,255,2,208,208,208,1,0,0,0,2,208,208,208, + 5,0,0,0,2,208,208,208,4,0,0,0,4,208,208,208,4,113,200,255, + 2,208,208,208,1,0,0,0,2,208,208,208,3,0,0,0,4,208,208,208, + 4,0,0,0,4,208,208,208,4,113,200,255,2,208,208,208,1,0,0,0, + 3,208,208,208,1,0,0,0,13,208,208,208,4,113,200,255,2,208,208,208, + 2,0,0,0,5,208,208,208,2,0,0,0,6,208,208,208,1,0,0,0, + 6,113,200,255,2,208,208,208,4,0,0,0,1,208,208,208,6,0,0,0, + 2,208,208,208,9,113,200,255,2,208,208,208,22,113,200,255,2,208,208,208, + 22,113,200,255,2,208,208,208,22,113,200,255,2,208,208,208,22,113,200,255, + 2,208,208,208,22,113,200,255,2,208,208,208,22,113,200,255,25,196,2,0, + 0,255,255,255,25,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255, + 2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0, + 22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,3,2,2,2, + 1,36,36,36,1,1,1,1,1,0,0,0,5,31,31,31,1,19,19,19, + 1,0,0,0,3,7,7,7,1,15,15,15,1,0,0,0,4,255,255,255, + 2,0,0,0,2,105,105,105,1,227,227,227,1,197,197,197,1,218,218,218, + 1,92,92,92,1,0,0,0,2,44,44,44,1,214,214,214,1,224,224,224, + 1,215,215,215,1,194,194,194,1,21,21,21,1,0,0,0,1,83,83,83, + 1,164,164,164,1,0,0,0,4,255,255,255,2,0,0,0,1,76,76,76, + 1,214,214,214,1,15,15,15,1,0,0,0,1,25,25,25,1,228,228,228, + 1,28,28,28,1,4,4,4,1,217,217,217,1,91,91,91,1,3,3,3, + 1,0,0,0,1,108,108,108,1,193,193,193,1,2,2,2,1,83,83,83, + 1,164,164,164,1,0,0,0,4,255,255,255,2,0,0,0,1,166,166,166, + 1,83,83,83,1,0,0,0,3,51,51,51,1,19,19,19,1,76,76,76, + 1,182,182,182,1,0,0,0,4,209,209,209,1,43,43,43,1,83,83,83, + 1,164,164,164,1,0,0,0,4,255,255,255,2,0,0,0,1,216,216,216, + 1,35,35,35,1,0,0,0,5,116,116,116,1,137,137,137,1,0,0,0, + 4,158,158,158,1,95,95,95,1,83,83,83,1,164,164,164,1,0,0,0, + 4,255,255,255,2,0,0,0,1,208,208,208,1,42,42,42,1,0,0,0, + 5,113,113,113,1,132,132,132,1,0,0,0,4,154,154,154,1,92,92,92, + 1,83,83,83,1,164,164,164,1,0,0,0,4,255,255,255,2,0,0,0, + 1,160,160,160,1,90,90,90,1,0,0,0,3,125,125,125,1,71,71,71, + 1,62,62,62,1,185,185,185,1,0,0,0,4,209,209,209,1,41,41,41, + 1,83,83,83,1,164,164,164,1,0,0,0,4,255,255,255,2,0,0,0, + 1,55,55,55,1,220,220,220,1,25,25,25,1,0,0,0,1,48,48,48, + 1,226,226,226,1,14,14,14,1,5,5,5,1,195,195,195,1,127,127,127, + 1,15,15,15,1,19,19,19,1,140,140,140,1,184,184,184,1,1,1,1, + 1,83,83,83,1,164,164,164,1,0,0,0,4,255,255,255,2,0,0,0, + 2,98,98,98,1,212,212,212,1,220,220,220,1,197,197,197,1,72,72,72, + 1,0,0,0,2,21,21,21,1,177,177,177,1,230,230,230,1,234,234,234, + 1,177,177,177,1,14,14,14,1,0,0,0,1,83,83,83,1,253,253,253, + 1,248,248,248,3,58,58,58,1,255,255,255,2,0,0,0,4,12,12,12, + 1,0,0,0,6,7,7,7,1,6,6,6,1,0,0,0,9,255,255,255, + 2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0, + 22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255, + 2,0,0,0,22,255,255,255,25,0,0) + ); + +const + objdata_tdblabel: record size: integer; data: array[0..571] of byte end = + (size: 572; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,8,116,100,98, + 108,97,98,101,108,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97, + 114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97, + 112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101, + 100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116, + 109,97,112,46,105,109,97,103,101,10,200,1,0,0,0,0,0,0,6,0, + 0,0,24,0,0,0,24,0,0,0,44,1,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,208,208,208,145,184,255,255,22,208,208,208,2,184,255, + 255,10,177,245,245,1,171,237,237,1,184,255,255,10,208,208,208,2,184,255, + 255,10,67,93,93,1,13,18,18,1,176,244,244,1,184,255,255,9,208,208, + 208,2,184,255,255,9,173,240,240,1,23,32,32,1,69,96,96,1,111,154, + 154,1,184,255,255,9,208,208,208,2,184,255,255,9,109,151,151,1,71,98, + 98,1,137,190,190,1,36,50,50,1,184,255,255,9,208,208,208,2,184,255, + 255,9,38,52,52,1,138,191,191,1,183,254,254,1,22,31,31,1,146,203, + 203,1,184,255,255,8,208,208,208,2,184,255,255,8,151,209,209,1,9,12, + 12,1,126,174,174,1,126,175,175,1,55,76,76,1,71,99,99,1,184,255, + 255,8,208,208,208,2,184,255,255,8,80,111,111,1,46,64,64,1,80,111, + 111,2,76,106,106,1,8,11,11,1,173,240,240,1,184,255,255,7,208,208, + 208,2,184,255,255,7,180,249,249,1,14,19,19,1,154,214,214,1,184,255, + 255,3,43,60,60,1,106,147,147,1,184,255,255,7,208,208,208,2,184,255, + 255,7,122,169,169,1,36,50,50,1,184,255,255,4,114,158,158,1,32,44, + 44,1,184,255,255,7,208,208,208,2,184,255,255,22,208,208,208,2,184,255, + 255,22,208,208,208,145,100,0,0,0,0,0,0,145,255,255,255,22,0,0, + 0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255,255, + 255,22,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0, + 0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255,255, + 255,22,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0, + 0,2,255,255,255,22,0,0,0,145,0,0) + ); + +const + objdata_tdbbarcode: record size: integer; data: array[0..1585] of byte end = + (size: 1586; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,100,98, + 98,97,114,99,111,100,101,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,188,5,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,120,5,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,184,255,255,72,0,0,0,1,184,255,255,1, + 0,0,0,1,184,255,255,2,0,0,0,2,184,255,255,1,0,0,0,1, + 184,255,255,2,0,0,0,1,184,255,255,1,0,0,0,1,184,255,255,1, + 0,0,0,2,184,255,255,1,0,0,0,2,184,255,255,1,0,0,0,1, + 184,255,255,1,0,0,0,2,184,255,255,1,0,0,0,1,184,255,255,2, + 0,0,0,2,184,255,255,1,0,0,0,1,184,255,255,2,0,0,0,1, + 184,255,255,1,0,0,0,1,184,255,255,1,0,0,0,2,184,255,255,1, + 0,0,0,2,184,255,255,1,0,0,0,1,184,255,255,1,0,0,0,2, + 184,255,255,1,0,0,0,1,184,255,255,2,0,0,0,2,184,255,255,1, + 0,0,0,1,184,255,255,2,0,0,0,1,184,255,255,1,0,0,0,1, + 184,255,255,1,0,0,0,2,184,255,255,1,0,0,0,2,184,255,255,1, + 0,0,0,1,184,255,255,1,0,0,0,2,184,255,255,1,0,0,0,1, + 184,255,255,2,0,0,0,2,184,255,255,1,0,0,0,1,184,255,255,2, + 0,0,0,1,184,255,255,1,0,0,0,1,184,255,255,1,0,0,0,2, + 184,255,255,1,0,0,0,2,184,255,255,1,0,0,0,1,184,255,255,1, + 0,0,0,2,184,255,255,1,0,0,0,1,184,255,255,2,0,0,0,2, + 184,255,255,1,0,0,0,1,184,255,255,2,0,0,0,1,184,255,255,1, + 0,0,0,1,184,255,255,1,0,0,0,2,184,255,255,1,0,0,0,2, + 184,255,255,1,0,0,0,1,184,255,255,1,0,0,0,2,184,255,255,1, + 0,0,0,1,184,255,255,2,0,0,0,2,184,255,255,1,0,0,0,1, + 184,255,255,2,0,0,0,1,184,255,255,1,0,0,0,1,184,255,255,1, + 0,0,0,2,184,255,255,1,0,0,0,2,184,255,255,1,0,0,0,1, + 184,255,255,1,0,0,0,2,184,255,255,1,0,0,0,1,184,255,255,2, + 0,0,0,2,184,255,255,1,0,0,0,1,184,255,255,2,0,0,0,1, + 184,255,255,1,0,0,0,1,184,255,255,1,0,0,0,2,184,255,255,1, + 0,0,0,2,184,255,255,1,0,0,0,1,184,255,255,1,0,0,0,2, + 184,255,255,1,0,0,0,1,184,255,255,2,0,0,0,2,184,255,255,1, + 0,0,0,1,184,255,255,2,0,0,0,1,184,255,255,1,0,0,0,1, + 184,255,255,1,0,0,0,2,184,255,255,1,0,0,0,2,184,255,255,1, + 0,0,0,1,184,255,255,1,0,0,0,2,184,255,255,1,0,0,0,1, + 184,255,255,2,0,0,0,2,184,255,255,1,0,0,0,1,184,255,255,2, + 0,0,0,1,184,255,255,1,0,0,0,1,184,255,255,1,0,0,0,2, + 184,255,255,1,0,0,0,2,184,255,255,1,0,0,0,1,184,255,255,1, + 0,0,0,2,184,255,255,1,0,0,0,1,184,255,255,2,0,0,0,2, + 184,255,255,1,0,0,0,1,184,255,255,2,0,0,0,1,184,255,255,1, + 0,0,0,1,184,255,255,1,0,0,0,2,184,255,255,1,0,0,0,2, + 184,255,255,1,0,0,0,1,184,255,255,1,0,0,0,2,184,255,255,1, + 0,0,0,1,184,255,255,2,0,0,0,2,184,255,255,1,0,0,0,1, + 184,255,255,2,0,0,0,1,184,255,255,1,0,0,0,1,184,255,255,1, + 0,0,0,2,184,255,255,1,0,0,0,2,184,255,255,1,0,0,0,1, + 184,255,255,1,0,0,0,2,184,255,255,1,0,0,0,1,184,255,255,2, + 0,0,0,2,184,255,255,1,0,0,0,1,184,255,255,2,0,0,0,1, + 184,255,255,1,0,0,0,1,184,255,255,1,0,0,0,2,184,255,255,1, + 0,0,0,2,184,255,255,1,0,0,0,1,184,255,255,1,0,0,0,2, + 184,255,255,1,0,0,0,1,184,255,255,2,0,0,0,2,184,255,255,1, + 0,0,0,1,184,255,255,2,0,0,0,1,184,255,255,1,0,0,0,1, + 184,255,255,1,0,0,0,2,184,255,255,1,0,0,0,2,184,255,255,1, + 0,0,0,1,184,255,255,1,0,0,0,2,184,255,255,1,0,0,0,1, + 184,255,255,2,180,250,250,1,184,255,255,2,182,252,252,1,184,255,255,2, + 0,0,0,1,184,255,255,1,0,0,0,1,184,255,255,1,182,252,252,1, + 183,254,254,1,184,255,255,1,182,252,252,1,184,255,255,2,0,0,0,1, + 184,255,255,1,0,0,0,2,184,255,255,1,0,0,0,1,184,255,255,1, + 163,226,226,1,50,69,69,1,184,255,255,1,116,161,161,1,98,136,136,1, + 105,146,146,1,184,255,255,1,0,0,0,1,184,255,255,1,0,0,0,1, + 173,240,240,1,57,79,79,1,167,231,231,1,138,191,191,1,93,129,129,1, + 89,124,124,1,184,255,255,1,0,0,0,1,184,255,255,1,0,0,0,2, + 184,255,255,1,0,0,0,1,184,255,255,1,154,214,214,1,89,123,123,1, + 184,255,255,1,82,113,113,1,184,255,255,1,80,111,111,1,184,255,255,1, + 0,0,0,1,184,255,255,1,0,0,0,1,161,223,223,1,100,138,138,1, + 167,231,231,1,84,117,117,1,181,251,251,1,80,111,111,1,184,255,255,1, + 0,0,0,1,184,255,255,1,0,0,0,2,184,255,255,1,0,0,0,1, + 184,255,255,2,92,127,127,1,184,255,255,1,94,130,130,1,184,255,255,1, + 84,116,116,1,184,255,255,1,0,0,0,1,184,255,255,1,0,0,0,1, + 184,255,255,1,110,152,152,1,167,231,231,1,95,132,132,1,183,253,253,1, + 84,116,116,1,184,255,255,1,0,0,0,1,184,255,255,1,0,0,0,2, + 184,255,255,1,0,0,0,1,184,255,255,2,92,127,127,1,184,255,255,1, + 126,175,175,1,104,144,144,1,110,152,152,1,184,255,255,1,0,0,0,1, + 184,255,255,1,0,0,0,1,184,255,255,1,110,152,152,1,167,231,231,1, + 144,200,200,1,100,139,139,1,95,132,132,1,184,255,255,1,0,0,0,1, + 184,255,255,1,0,0,0,1,184,255,255,8,183,253,253,1,184,255,255,9, + 183,253,253,1,184,255,255,53,12,0,0,0,255,255,255,255,255,255,255,255, + 255,255,255,66,0,0) + ); + +const + objdata_tdbstringdisp: record size: integer; data: array[0..828] of byte end = + (size: 829; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,100,98, + 115,116,114,105,110,103,100,105,115,112,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,196,2,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,124,2,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,208,208,208,120,128,128,128,25,184, + 255,255,22,255,255,255,1,128,128,128,1,184,255,255,8,167,232,232,1,184, + 255,255,13,255,255,255,1,128,128,128,1,184,255,255,8,6,8,8,1,184, + 255,255,13,255,255,255,1,128,128,128,1,184,255,255,8,6,8,8,1,184, + 255,255,13,255,255,255,1,128,128,128,1,184,255,255,1,183,254,254,1,89, + 124,124,1,30,41,41,1,19,26,26,1,51,70,70,1,169,234,234,1,184, + 255,255,1,6,8,8,1,103,143,143,1,30,41,41,1,42,58,58,1,157, + 217,217,1,184,255,255,1,176,244,244,1,64,89,89,1,25,34,34,1,51, + 70,70,1,149,207,207,1,184,255,255,3,255,255,255,1,128,128,128,1,184, + 255,255,1,146,203,203,1,47,65,65,1,180,250,250,1,181,251,251,1,56, + 78,78,1,105,145,145,1,184,255,255,1,6,8,8,1,90,125,125,1,181, + 251,251,1,100,138,138,1,44,61,61,1,184,255,255,1,69,96,96,1,76, + 106,106,1,179,248,248,1,138,191,191,1,51,70,70,1,184,255,255,3,255, + 255,255,1,128,128,128,1,184,255,255,2,167,232,232,1,122,169,169,1,87, + 120,120,1,29,40,40,1,92,128,128,1,184,255,255,1,6,9,9,1,166, + 230,230,1,184,255,255,1,171,237,237,1,4,5,5,1,179,248,248,1,22, + 30,30,1,149,206,206,1,184,255,255,6,255,255,255,1,128,128,128,1,184, + 255,255,1,141,196,196,1,20,28,28,1,89,123,123,1,131,181,181,1,71, + 99,99,1,92,127,127,1,184,255,255,1,8,11,11,1,178,246,246,1,184, + 255,255,1,174,241,241,1,5,7,7,1,178,247,247,1,12,16,16,1,157, + 217,217,1,184,255,255,2,167,232,232,1,184,255,255,3,255,255,255,1,128, + 128,128,1,184,255,255,1,91,126,126,1,81,112,112,1,184,255,255,1,178, + 247,247,1,35,49,49,1,89,123,123,1,184,255,255,1,6,8,8,1,119, + 165,165,1,184,255,255,1,114,158,158,1,40,55,55,1,184,255,255,1,51, + 71,71,1,101,140,140,1,184,255,255,1,154,213,213,1,33,46,46,1,183, + 254,254,1,184,255,255,2,255,255,255,1,128,128,128,1,184,255,255,1,159, + 220,220,1,36,50,50,1,50,69,69,1,44,61,61,1,69,95,95,2,184, + 255,255,1,14,19,19,1,79,109,109,1,38,53,53,1,56,77,77,1,154, + 214,214,1,184,255,255,1,158,219,219,1,63,87,87,1,40,56,56,1,40, + 55,55,1,137,190,190,1,184,255,255,3,255,255,255,1,128,128,128,1,184, + 255,255,3,172,238,238,1,184,255,255,6,178,247,247,1,184,255,255,5,177, + 245,245,1,184,255,255,5,255,255,255,1,128,128,128,1,184,255,255,22,255, + 255,255,25,208,208,208,120,16,0,0,0,0,0,0,120,255,255,255,255,255, + 255,255,81,0,0,0,120,0,0) + ); + +const + objdata_tdbintegerdisp: record size: integer; data: array[0..841] of byte end = + (size: 842; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,100,98, + 105,110,116,101,103,101,114,100,105,115,112,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,208,2,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,136,2,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,208,208,208,120,128,128,128,25, + 184,255,255,22,255,255,255,1,128,128,128,1,184,255,255,4,173,240,240,1, + 179,248,248,1,184,255,255,4,176,244,244,1,184,255,255,5,175,242,242,1, + 184,255,255,5,255,255,255,1,128,128,128,1,184,255,255,3,171,237,237,1, + 25,34,34,1,144,199,199,1,184,255,255,2,131,182,182,1,40,55,55,1, + 35,49,49,1,47,65,65,1,149,206,206,1,184,255,255,1,165,229,229,1, + 48,66,66,1,40,56,56,1,29,40,40,1,144,200,200,1,184,255,255,3, + 255,255,255,1,128,128,128,1,184,255,255,2,135,187,187,1,27,37,37,1, + 9,13,13,1,144,199,199,1,184,255,255,1,183,253,253,1,27,38,38,1, + 154,213,213,1,184,255,255,1,121,167,167,1,55,76,76,1,184,255,255,1, + 72,100,100,1,104,144,144,1,184,255,255,1,131,182,182,1,38,52,52,1, + 184,255,255,3,255,255,255,1,128,128,128,1,184,255,255,2,84,117,117,1, + 144,199,199,1,40,55,55,1,144,199,199,1,184,255,255,1,179,248,248,1, + 139,192,192,1,184,255,255,2,144,199,199,1,22,30,30,1,184,255,255,1, + 176,244,244,1,180,249,249,1,184,255,255,1,118,164,164,1,38,53,53,1, + 184,255,255,3,255,255,255,1,128,128,128,1,184,255,255,4,40,55,55,1, + 144,199,199,1,184,255,255,4,179,248,248,1,50,69,69,1,97,134,134,1, + 184,255,255,3,50,69,69,1,6,9,9,1,148,205,205,1,184,255,255,3, + 255,255,255,1,128,128,128,1,184,255,255,4,40,55,55,1,144,199,199,1, + 184,255,255,3,176,244,244,1,48,67,67,1,70,97,97,1,183,253,253,1, + 184,255,255,3,162,224,224,1,112,155,155,1,19,27,27,1,177,245,245,1, + 184,255,255,2,255,255,255,1,128,128,128,1,184,255,255,4,40,55,55,1, + 144,199,199,1,184,255,255,2,173,240,240,1,42,58,58,1,83,115,115,1, + 183,254,254,1,184,255,255,2,152,211,211,1,180,249,249,1,184,255,255,2, + 33,46,46,1,137,190,190,1,184,255,255,2,255,255,255,1,128,128,128,1, + 184,255,255,4,40,55,55,1,144,199,199,1,184,255,255,2,45,63,63,1, + 100,138,138,1,184,255,255,4,64,89,89,1,111,154,154,1,184,255,255,1, + 162,225,225,1,17,24,24,1,178,246,246,1,184,255,255,2,255,255,255,1, + 128,128,128,1,184,255,255,4,40,55,55,1,144,199,199,1,184,255,255,1, + 136,189,189,1,0,0,0,1,5,7,7,3,11,15,15,1,184,255,255,1, + 158,219,219,1,48,67,67,1,40,56,56,2,123,171,171,1,184,255,255,3, + 255,255,255,1,128,128,128,1,184,255,255,16,172,239,239,1,184,255,255,5, + 255,255,255,1,128,128,128,1,184,255,255,22,255,255,255,25,208,208,208,120, + 16,0,0,0,0,0,0,120,255,255,255,255,255,255,255,81,0,0,0,120, + 0,0) + ); + +const + objdata_tdbbooleandisp: record size: integer; data: array[0..725] of byte end = + (size: 726; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,100,98, + 98,111,111,108,101,97,110,100,105,115,112,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,92,2,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,20,2,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,208,208,208,120,128,128,128,25, + 184,255,255,22,255,255,255,1,128,128,128,1,184,255,255,1,171,237,237,1, + 167,231,231,5,173,240,240,1,184,255,255,2,154,214,214,1,183,253,253,1, + 167,232,232,1,167,231,231,4,177,245,245,1,184,255,255,4,255,255,255,1, + 128,128,128,1,184,255,255,1,63,87,87,1,22,31,31,1,21,29,29,1, + 0,0,0,1,22,31,31,2,78,108,108,1,184,255,255,1,183,254,254,1, + 40,56,56,1,184,255,255,1,2,3,3,1,21,29,29,1,22,31,31,3, + 111,154,154,1,184,255,255,4,255,255,255,1,128,128,128,1,184,255,255,3, + 172,239,239,1,0,0,0,1,184,255,255,4,149,206,206,1,74,103,103,1, + 184,255,255,1,2,3,3,1,170,236,236,1,184,255,255,8,255,255,255,1, + 128,128,128,1,184,255,255,3,172,239,239,1,0,0,0,1,184,255,255,4, + 97,134,134,1,126,174,174,1,184,255,255,1,2,3,3,1,170,236,236,1, + 184,255,255,8,255,255,255,1,128,128,128,1,184,255,255,3,172,239,239,1, + 0,0,0,1,184,255,255,4,48,67,67,1,174,241,241,1,184,255,255,1, + 2,3,3,1,63,88,88,1,69,95,95,2,85,118,118,1,184,255,255,5, + 255,255,255,1,128,128,128,1,184,255,255,3,172,239,239,1,0,0,0,1, + 184,255,255,3,174,241,241,1,47,65,65,1,184,255,255,2,2,3,3,1, + 112,155,155,1,121,167,167,2,130,180,180,1,184,255,255,5,255,255,255,1, + 128,128,128,1,184,255,255,3,172,239,239,1,0,0,0,1,184,255,255,3, + 126,174,174,1,95,131,131,1,184,255,255,2,2,3,3,1,170,236,236,1, + 184,255,255,8,255,255,255,1,128,128,128,1,184,255,255,3,172,239,239,1, + 0,0,0,1,184,255,255,3,74,102,102,1,146,202,202,1,184,255,255,2, + 2,3,3,1,170,236,236,1,184,255,255,8,255,255,255,1,128,128,128,1, + 184,255,255,3,172,239,239,1,0,0,0,1,184,255,255,3,37,51,51,1, + 183,253,253,1,184,255,255,2,2,3,3,1,170,236,236,1,184,255,255,8, + 255,255,255,1,128,128,128,1,184,255,255,7,183,254,254,1,167,231,231,1, + 184,255,255,13,255,255,255,1,128,128,128,1,184,255,255,22,255,255,255,25, + 208,208,208,120,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255,81, + 0,0,0,120,0,0) + ); + +const + objdata_tdbrealdisp: record size: integer; data: array[0..786] of byte end = + (size: 787; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,100,98, + 114,101,97,108,100,105,115,112,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,156,2,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,84,2,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,208,208,208,120,128,128,128,25,184,255,255, + 22,255,255,255,1,128,128,128,1,184,255,255,4,173,240,240,1,179,248,248, + 1,184,255,255,7,176,244,244,1,184,255,255,6,168,233,233,1,184,255,255, + 1,255,255,255,1,128,128,128,1,184,255,255,3,171,237,237,1,25,34,34, + 1,144,199,199,1,184,255,255,5,146,203,203,1,45,63,63,1,36,50,50, + 1,40,56,56,1,134,186,186,1,184,255,255,3,137,190,190,1,18,25,25, + 1,184,255,255,1,255,255,255,1,128,128,128,1,184,255,255,2,135,187,187, + 1,27,37,37,1,9,13,13,1,144,199,199,1,184,255,255,5,50,69,69, + 1,130,180,180,1,184,255,255,1,144,200,200,1,31,43,43,1,184,255,255, + 1,183,253,253,1,98,136,136,1,19,26,26,1,15,21,21,1,184,255,255, + 1,255,255,255,1,128,128,128,1,184,255,255,2,84,117,117,1,144,199,199, + 1,40,55,55,1,144,199,199,1,184,255,255,5,135,187,187,1,183,253,253, + 1,184,255,255,1,166,230,230,1,6,8,8,1,178,247,247,1,171,237,237, + 1,74,102,102,1,153,212,212,1,15,21,21,1,184,255,255,1,255,255,255, + 1,128,128,128,1,184,255,255,4,40,55,55,1,144,199,199,1,184,255,255, + 7,183,254,254,1,69,96,96,1,72,100,100,1,184,255,255,3,169,234,234, + 1,15,21,21,1,184,255,255,1,255,255,255,1,128,128,128,1,184,255,255, + 4,40,55,55,1,144,199,199,1,184,255,255,6,182,252,252,1,67,93,93, + 1,51,71,71,1,177,245,245,1,184,255,255,3,169,234,234,1,15,21,21, + 1,184,255,255,1,255,255,255,1,128,128,128,1,184,255,255,4,40,55,55, + 1,144,199,199,1,184,255,255,5,180,249,249,1,59,82,82,1,63,87,87, + 1,180,249,249,1,184,255,255,4,169,234,234,1,15,21,21,1,184,255,255, + 1,255,255,255,1,128,128,128,1,184,255,255,4,40,55,55,1,144,199,199, + 1,184,255,255,2,169,234,234,1,174,241,241,1,184,255,255,1,69,96,96, + 1,76,106,106,1,183,254,254,1,184,255,255,5,169,234,234,1,15,21,21, + 1,184,255,255,1,255,255,255,1,128,128,128,1,184,255,255,4,40,55,55, + 1,144,199,199,1,184,255,255,2,58,80,80,1,103,143,143,1,159,221,221, + 1,0,0,0,1,4,6,6,1,5,7,7,3,166,230,230,1,184,255,255, + 2,169,234,234,1,15,21,21,1,184,255,255,1,255,255,255,1,128,128,128, + 1,184,255,255,22,255,255,255,1,128,128,128,1,184,255,255,22,255,255,255, + 25,208,208,208,120,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255, + 81,0,0,0,120,0,0) + ); + +const + objdata_tdbdatetimedisp: record size: integer; data: array[0..762] of byte end = + (size: 763; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,100,98, + 100,97,116,101,116,105,109,101,100,105,115,112,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,128,2,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,56,2,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,208,208,208,120,128,128,128, + 25,184,255,255,22,255,255,255,1,128,128,128,1,184,255,255,1,182,252,252, + 1,167,231,231,2,168,233,233,1,180,249,249,1,184,255,255,6,176,244,244, + 1,167,231,231,5,168,233,233,1,184,255,255,3,255,255,255,1,128,128,128, + 1,184,255,255,1,161,223,223,1,1,1,1,1,22,31,31,1,21,29,29, + 1,6,8,8,1,43,60,60,1,152,211,211,1,184,255,255,4,110,152,152, + 1,22,31,31,2,5,7,7,1,16,22,22,1,22,31,31,1,32,44,44, + 1,184,255,255,3,255,255,255,1,128,128,128,1,184,255,255,1,161,223,223, + 1,11,15,15,1,184,255,255,3,97,135,135,1,29,40,40,1,178,247,247, + 1,184,255,255,6,41,57,57,1,131,182,182,1,184,255,255,5,255,255,255, + 1,128,128,128,1,184,255,255,1,161,223,223,1,11,15,15,1,184,255,255, + 4,26,36,36,1,127,176,176,1,184,255,255,1,58,80,80,1,136,188,188, + 1,184,255,255,3,41,57,57,1,131,182,182,1,184,255,255,5,255,255,255, + 1,128,128,128,1,184,255,255,1,161,223,223,1,11,15,15,1,184,255,255, + 4,64,89,89,1,95,131,131,1,184,255,255,1,142,197,197,1,168,233,233, + 1,184,255,255,3,41,57,57,1,131,182,182,1,184,255,255,5,255,255,255, + 1,128,128,128,1,184,255,255,1,161,223,223,1,11,15,15,1,184,255,255, + 4,65,90,90,1,95,132,132,1,184,255,255,6,41,57,57,1,131,182,182, + 1,184,255,255,5,255,255,255,1,128,128,128,1,184,255,255,1,161,223,223, + 1,11,15,15,1,184,255,255,3,183,254,254,1,30,41,41,1,126,174,174, + 1,184,255,255,6,41,57,57,1,131,182,182,1,184,255,255,5,255,255,255, + 1,128,128,128,1,184,255,255,1,161,223,223,1,11,15,15,1,184,255,255, + 2,174,241,241,1,91,126,126,1,27,38,38,1,181,251,251,1,184,255,255, + 1,166,230,230,1,177,245,245,1,184,255,255,3,41,57,57,1,131,182,182, + 1,184,255,255,5,255,255,255,1,128,128,128,1,184,255,255,1,161,223,223, + 1,0,0,0,1,5,7,7,2,12,17,17,1,56,77,77,1,162,224,224, + 1,184,255,255,2,35,48,48,1,126,175,175,1,184,255,255,3,41,57,57, + 1,131,182,182,1,184,255,255,5,255,255,255,1,128,128,128,1,184,255,255, + 22,255,255,255,1,128,128,128,1,184,255,255,22,255,255,255,25,208,208,208, + 120,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255,81,0,0,0, + 120,0,0) + ); + +const + objdata_tdbstringdisplb: record size: integer; data: array[0..898] of byte end = + (size: 899; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,100,98, + 115,116,114,105,110,103,100,105,115,112,108,98,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,8,3,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,192,2,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,208,208,208,120,128,128,128, + 25,184,255,255,20,187,245,255,1,197,216,255,1,255,255,255,1,128,128,128, + 1,184,255,255,8,167,232,232,1,184,255,255,9,186,248,255,1,195,221,255, + 1,201,201,255,2,255,255,255,1,128,128,128,1,184,255,255,8,6,8,8, + 1,184,255,255,7,185,251,255,1,194,226,255,1,200,202,255,1,201,201,255, + 3,255,255,255,1,128,128,128,1,184,255,255,8,6,8,8,1,184,255,255, + 5,185,254,255,1,191,230,255,1,200,205,255,1,201,201,255,5,255,255,255, + 1,128,128,128,1,184,255,255,1,183,254,254,1,89,124,124,1,30,41,41, + 1,19,26,26,1,51,70,70,1,169,234,234,1,184,255,255,1,6,8,8, + 1,103,143,143,1,30,41,41,1,42,58,58,1,157,217,217,1,190,235,255, + 1,190,199,244,1,70,70,89,1,27,27,34,1,55,55,70,1,163,163,207, + 1,201,201,255,3,255,255,255,1,128,128,128,1,184,255,255,1,146,203,203, + 1,47,65,65,1,180,250,250,1,181,251,251,1,56,78,78,1,105,145,145, + 1,184,255,255,1,6,8,8,1,90,125,125,1,181,251,251,1,102,130,138, + 1,47,50,61,1,201,201,255,1,76,76,96,1,84,84,106,1,195,195,248, + 1,151,151,191,1,55,55,70,1,201,201,255,3,255,255,255,1,128,128,128, + 1,184,255,255,2,167,232,232,1,122,169,169,1,87,120,120,1,29,40,40, + 1,92,128,128,1,184,255,255,1,6,9,9,1,169,221,230,1,197,216,255, + 1,187,187,237,1,4,4,5,1,195,195,248,1,24,24,30,1,162,162,206, + 1,201,201,255,6,255,255,255,1,128,128,128,1,184,255,255,1,141,196,196, + 1,20,28,28,1,89,123,123,1,131,181,181,1,71,99,99,1,92,127,127, + 1,186,248,255,1,8,10,11,1,194,194,246,1,201,201,255,1,190,190,241, + 1,6,6,7,1,195,195,247,1,13,13,16,1,171,171,217,1,201,201,255, + 2,183,183,232,1,201,201,255,3,255,255,255,1,128,128,128,1,184,255,255, + 1,91,126,126,1,81,112,112,1,184,255,255,1,178,247,247,1,36,48,49, + 1,94,109,123,1,200,202,255,1,6,6,8,1,130,130,165,1,201,201,255, + 1,125,125,158,1,43,43,55,1,201,201,255,1,56,56,71,1,110,110,140, + 1,201,201,255,1,168,168,213,1,36,36,46,1,200,200,254,1,201,201,255, + 2,255,255,255,1,128,128,128,1,184,255,255,1,159,220,220,1,36,50,50, + 1,50,69,69,1,46,55,61,1,75,76,95,1,75,75,95,1,201,201,255, + 1,15,15,19,1,86,86,109,1,42,42,53,1,61,61,77,1,169,169,214, + 1,201,201,255,1,173,173,219,1,69,69,87,1,44,44,56,1,43,43,55, + 1,150,150,190,1,201,201,255,3,255,255,255,1,128,128,128,1,184,255,255, + 2,190,235,255,1,186,194,238,1,201,201,255,6,195,195,247,1,201,201,255, + 5,193,193,245,1,201,201,255,5,255,255,255,1,128,128,128,1,188,240,255, + 1,198,211,255,1,201,201,255,20,255,255,255,25,208,208,208,120,16,0,0, + 0,0,0,0,120,255,255,255,255,255,255,255,81,0,0,0,120,0,0) + ); + +const + objdata_tdbintegerdisplb: record size: integer; data: array[0..895] of byte end = + (size: 896; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,100,98, + 105,110,116,101,103,101,114,100,105,115,112,108,98,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,4,3, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,188,2, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,208,208,208,120,128,128, + 128,25,184,255,255,20,187,245,255,1,197,216,255,1,255,255,255,1,128,128, + 128,1,184,255,255,4,173,240,240,1,179,248,248,1,184,255,255,4,176,244, + 244,1,184,255,255,5,175,242,242,1,184,255,255,1,186,248,255,1,195,221, + 255,1,201,201,255,2,255,255,255,1,128,128,128,1,184,255,255,3,171,237, + 237,1,25,34,34,1,144,199,199,1,184,255,255,2,131,182,182,1,40,55, + 55,1,35,49,49,1,47,65,65,1,149,206,206,1,184,255,255,1,165,229, + 229,1,48,66,66,1,41,55,56,1,30,35,40,1,157,158,200,1,201,201, + 255,3,255,255,255,1,128,128,128,1,184,255,255,2,135,187,187,1,27,37, + 37,1,9,13,13,1,144,199,199,1,184,255,255,1,183,253,253,1,27,38, + 38,1,154,213,213,1,184,255,255,1,121,167,167,1,55,76,76,1,184,255, + 255,1,73,100,100,1,108,130,144,1,200,205,255,1,143,143,182,1,41,41, + 52,1,201,201,255,3,255,255,255,1,128,128,128,1,184,255,255,2,84,117, + 117,1,144,199,199,1,40,55,55,1,144,199,199,1,184,255,255,1,179,248, + 248,1,139,192,192,1,184,255,255,2,144,199,199,1,22,30,30,1,190,235, + 255,1,190,199,244,1,196,196,249,1,201,201,255,1,129,129,164,1,42,42, + 53,1,201,201,255,3,255,255,255,1,128,128,128,1,184,255,255,4,40,55, + 55,1,144,199,199,1,184,255,255,4,179,248,248,1,51,65,69,1,104,111, + 134,1,201,201,255,3,54,54,69,1,7,7,9,1,162,162,205,1,201,201, + 255,3,255,255,255,1,128,128,128,1,184,255,255,4,40,55,55,1,144,199, + 199,1,184,255,255,3,179,234,244,1,52,57,67,1,76,76,97,1,199,199, + 253,1,201,201,255,3,177,177,224,1,122,122,155,1,21,21,27,1,193,193, + 245,1,201,201,255,2,255,255,255,1,128,128,128,1,184,255,255,4,40,55, + 55,1,144,199,199,1,184,255,255,1,186,248,255,1,184,208,240,1,46,46, + 58,1,91,91,115,1,200,200,254,1,201,201,255,2,166,166,211,1,196,196, + 249,1,201,201,255,2,36,36,46,1,150,150,190,1,201,201,255,2,255,255, + 255,1,128,128,128,1,184,255,255,4,40,55,55,1,144,196,199,1,194,226, + 255,1,200,202,255,1,50,50,63,1,109,109,138,1,201,201,255,4,70,70, + 89,1,121,121,154,1,201,201,255,1,177,177,225,1,19,19,24,1,194,194, + 246,1,201,201,255,2,255,255,255,1,128,128,128,1,184,255,255,3,185,254, + 255,1,41,50,55,1,156,160,199,1,201,201,255,1,149,149,189,1,0,0, + 0,1,6,6,7,3,12,12,15,1,201,201,255,1,173,173,219,1,53,53, + 67,1,44,44,56,2,135,135,171,1,201,201,255,3,255,255,255,1,128,128, + 128,1,184,255,255,2,190,235,255,1,199,208,255,1,201,201,255,12,188,188, + 239,1,201,201,255,5,255,255,255,1,128,128,128,1,188,240,255,1,198,211, + 255,1,201,201,255,20,255,255,255,25,208,208,208,120,16,0,0,0,0,0, + 0,120,255,255,255,255,255,255,255,81,0,0,0,120,0,0) + ); + +const + objdata_tdbrealdisplb: record size: integer; data: array[0..872] of byte end = + (size: 873; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,100,98, + 114,101,97,108,100,105,115,112,108,98,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,240,2,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,168,2,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,208,208,208,120,128,128,128,25,184, + 255,255,20,187,245,255,1,197,216,255,1,255,255,255,1,128,128,128,1,184, + 255,255,4,173,240,240,1,179,248,248,1,184,255,255,7,176,244,244,1,184, + 255,255,4,186,248,255,1,195,221,255,1,184,184,233,1,201,201,255,1,255, + 255,255,1,128,128,128,1,184,255,255,3,171,237,237,1,25,34,34,1,144, + 199,199,1,184,255,255,5,146,203,203,1,45,63,63,1,36,50,50,1,40, + 56,56,1,134,186,186,1,185,251,255,1,194,226,255,1,200,202,255,1,150, + 150,190,1,20,20,25,1,201,201,255,1,255,255,255,1,128,128,128,1,184, + 255,255,2,135,187,187,1,27,37,37,1,9,13,13,1,144,199,199,1,184, + 255,255,5,50,69,69,1,130,180,180,1,184,255,255,1,145,199,200,1,32, + 39,43,1,200,205,255,1,199,199,253,1,107,107,136,1,20,20,26,1,17, + 17,21,1,201,201,255,1,255,255,255,1,128,128,128,1,184,255,255,2,84, + 117,117,1,144,199,199,1,40,55,55,1,144,199,199,1,184,255,255,5,135, + 187,187,1,183,253,253,1,190,235,255,1,179,188,230,1,6,6,8,1,195, + 195,247,1,187,187,237,1,80,80,102,1,167,167,212,1,17,17,21,1,201, + 201,255,1,255,255,255,1,128,128,128,1,184,255,255,4,40,55,55,1,144, + 199,199,1,184,255,255,5,188,240,255,1,198,211,255,1,200,200,254,1,76, + 76,96,1,79,79,100,1,201,201,255,3,184,184,234,1,17,17,21,1,201, + 201,255,1,255,255,255,1,128,128,128,1,184,255,255,4,40,55,55,1,144, + 199,199,1,184,255,255,3,187,245,255,1,197,216,255,1,201,201,255,1,199, + 199,252,1,73,73,93,1,56,56,71,1,193,193,245,1,201,201,255,3,184, + 184,234,1,17,17,21,1,201,201,255,1,255,255,255,1,128,128,128,1,184, + 255,255,4,40,55,55,1,144,199,199,1,184,255,255,1,186,248,255,1,195, + 221,255,1,201,201,255,2,196,196,249,1,65,65,82,1,69,69,87,1,196, + 196,249,1,201,201,255,4,184,184,234,1,17,17,21,1,201,201,255,1,255, + 255,255,1,128,128,128,1,184,255,255,4,40,55,55,1,144,196,199,1,194, + 226,255,1,200,202,255,1,184,184,234,1,190,190,241,1,201,201,255,1,76, + 76,96,1,84,84,106,1,200,200,254,1,201,201,255,5,184,184,234,1,17, + 17,21,1,201,201,255,1,255,255,255,1,128,128,128,1,184,255,255,3,185, + 254,255,1,41,50,55,1,156,160,199,1,201,201,255,2,63,63,80,1,113, + 113,143,1,174,174,221,1,0,0,0,1,5,5,6,1,6,6,7,3,181, + 181,230,1,201,201,255,2,184,184,234,1,17,17,21,1,201,201,255,1,255, + 255,255,1,128,128,128,1,184,255,255,2,190,235,255,1,199,208,255,1,201, + 201,255,18,255,255,255,1,128,128,128,1,188,240,255,1,198,211,255,1,201, + 201,255,20,255,255,255,25,208,208,208,120,16,0,0,0,0,0,0,120,255, + 255,255,255,255,255,255,81,0,0,0,120,0,0) + ); + +const + objdata_tdbdatetimedisplb: record size: integer; data: array[0..824] of byte end = + (size: 825; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,100,98, + 100,97,116,101,116,105,109,101,100,105,115,112,108,98,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,188, + 2,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,116, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,208,208,208,120,128, + 128,128,25,184,255,255,20,187,245,255,1,197,216,255,1,255,255,255,1,128, + 128,128,1,184,255,255,1,182,252,252,1,167,231,231,2,168,233,233,1,180, + 249,249,1,184,255,255,6,176,244,244,1,167,231,231,5,170,227,233,1,195, + 221,255,1,201,201,255,2,255,255,255,1,128,128,128,1,184,255,255,1,161, + 223,223,1,1,1,1,1,22,31,31,1,21,29,29,1,6,8,8,1,43, + 60,60,1,152,211,211,1,184,255,255,4,110,152,152,1,22,31,31,2,5, + 7,7,1,16,22,22,1,24,27,31,1,35,35,44,1,201,201,255,3,255, + 255,255,1,128,128,128,1,184,255,255,1,161,223,223,1,11,15,15,1,184, + 255,255,3,97,135,135,1,29,40,40,1,178,247,247,1,184,255,255,5,185, + 254,255,1,43,51,57,1,143,146,182,1,201,201,255,5,255,255,255,1,128, + 128,128,1,184,255,255,1,161,223,223,1,11,15,15,1,184,255,255,4,26, + 36,36,1,127,176,176,1,184,255,255,1,58,80,80,1,136,188,188,1,184, + 255,255,1,190,235,255,1,199,208,255,1,45,45,57,1,143,143,182,1,201, + 201,255,5,255,255,255,1,128,128,128,1,184,255,255,1,161,223,223,1,11, + 15,15,1,184,255,255,4,64,89,89,1,95,131,131,1,184,255,255,1,142, + 197,197,1,172,219,233,1,198,211,255,1,201,201,255,2,45,45,57,1,143, + 143,182,1,201,201,255,5,255,255,255,1,128,128,128,1,184,255,255,1,161, + 223,223,1,11,15,15,1,184,255,255,4,65,90,90,1,95,132,132,1,187, + 245,255,1,197,216,255,1,201,201,255,4,45,45,57,1,143,143,182,1,201, + 201,255,5,255,255,255,1,128,128,128,1,184,255,255,1,161,223,223,1,11, + 15,15,1,184,255,255,3,183,254,254,1,30,40,41,1,133,151,174,1,201, + 201,255,6,45,45,57,1,143,143,182,1,201,201,255,5,255,255,255,1,128, + 128,128,1,184,255,255,1,161,223,223,1,11,15,15,1,184,255,255,2,175, + 237,241,1,96,112,126,1,30,30,38,1,198,198,251,1,201,201,255,1,181, + 181,230,1,193,193,245,1,201,201,255,3,45,45,57,1,143,143,182,1,201, + 201,255,5,255,255,255,1,128,128,128,1,184,255,255,1,161,223,223,1,0, + 0,0,1,5,7,7,1,5,6,7,1,13,14,17,1,61,61,77,1,177, + 177,224,1,201,201,255,2,38,38,48,1,138,138,175,1,201,201,255,3,45, + 45,57,1,143,143,182,1,201,201,255,5,255,255,255,1,128,128,128,1,184, + 255,255,2,190,235,255,1,199,208,255,1,201,201,255,18,255,255,255,1,128, + 128,128,1,188,240,255,1,198,211,255,1,201,201,255,20,255,255,255,25,208, + 208,208,120,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255,81,0, + 0,0,120,0,0) + ); + +const + objdata_tfieldparamlink: record size: integer; data: array[0..1546] of byte end = + (size: 1547; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,102,105, + 101,108,100,112,97,114,97,109,108,105,110,107,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,144,5,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,8,2,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,184,255,255,12,255,255,255, + 12,184,255,255,1,255,255,255,10,184,255,255,1,255,255,255,12,184,255,255, + 1,0,0,0,7,255,255,255,3,184,255,255,1,255,255,255,12,184,255,255, + 1,0,0,0,7,255,255,255,3,184,255,255,1,255,255,255,12,184,255,255, + 1,0,0,0,2,255,255,255,4,0,0,0,1,255,255,255,3,184,255,255, + 1,255,255,255,12,184,255,255,1,0,0,0,5,255,255,255,1,0,0,0, + 1,255,255,255,3,184,255,255,1,255,255,255,12,184,255,255,1,0,0,0, + 2,255,255,255,4,0,0,0,1,255,255,255,3,184,255,255,1,255,255,255, + 12,184,255,255,1,0,0,0,2,255,255,255,4,0,0,0,1,255,255,255, + 3,184,255,255,1,255,255,255,4,2,2,255,4,0,0,255,1,255,255,255, + 3,184,255,255,1,0,0,0,2,255,255,255,4,0,0,0,1,255,255,255, + 3,184,255,255,1,255,255,255,4,0,0,255,3,3,3,255,1,2,2,255, + 1,3,3,255,1,255,255,255,2,184,255,255,1,255,255,255,10,184,255,255, + 1,255,255,255,8,4,4,255,1,2,2,255,1,255,255,255,2,184,255,255, + 12,255,255,255,8,0,0,255,1,2,2,255,1,0,0,255,1,255,255,255, + 22,2,2,255,1,0,0,255,1,255,255,255,22,2,2,255,1,0,0,255, + 1,255,255,255,2,0,0,0,5,255,255,255,2,0,0,0,2,255,255,255, + 3,0,0,0,5,255,255,255,1,0,0,255,5,255,255,255,1,0,0,0, + 6,255,255,255,1,0,0,0,3,255,255,255,2,0,0,0,6,255,255,255, + 1,0,0,255,3,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0, + 6,255,255,255,2,0,0,0,1,255,255,255,3,0,0,0,2,255,255,255, + 2,0,0,255,1,255,255,255,3,0,0,0,11,255,255,255,1,0,0,0, + 5,255,255,255,7,0,0,0,5,255,255,255,1,0,0,0,5,255,255,255, + 1,0,0,0,5,255,255,255,7,0,0,0,2,255,255,255,3,0,0,0, + 6,255,255,255,1,0,0,0,1,255,255,255,2,0,0,0,3,255,255,255, + 6,0,0,0,2,255,255,255,3,0,0,0,2,255,255,255,3,0,0,0, + 3,255,255,255,3,0,0,0,2,255,255,255,101,80,3,0,0,255,255,255, + 12,0,0,0,12,255,255,255,1,0,0,0,10,255,255,255,1,0,0,0, + 12,255,255,255,1,46,46,46,1,184,184,184,4,17,17,17,1,149,149,149, + 1,0,0,0,3,255,255,255,1,0,0,0,12,255,255,255,1,64,64,64, + 1,158,158,158,1,16,16,16,3,1,1,1,1,39,39,39,1,0,0,0, + 3,255,255,255,1,0,0,0,12,255,255,255,1,64,64,64,1,152,152,152, + 1,0,0,0,4,195,195,195,1,0,0,0,3,255,255,255,1,0,0,0, + 12,255,255,255,1,64,64,64,1,230,230,230,1,192,192,192,2,120,120,120, + 1,0,0,0,1,208,208,208,1,0,0,0,3,255,255,255,1,0,0,0, + 12,255,255,255,1,64,64,64,1,152,152,152,1,0,0,0,4,208,208,208, + 1,0,0,0,3,255,255,255,1,0,0,0,12,255,255,255,1,64,64,64, + 1,152,152,152,1,0,0,0,4,208,208,208,1,0,0,0,3,255,255,255, + 1,0,0,0,4,126,126,126,1,242,242,242,1,221,221,221,1,170,170,170, + 1,60,60,60,1,0,0,0,3,255,255,255,1,48,48,48,1,114,114,114, + 1,0,0,0,4,156,156,156,1,0,0,0,3,255,255,255,1,0,0,0, + 4,1,1,1,1,14,14,14,1,40,40,40,1,102,102,102,1,225,225,225, + 1,87,87,87,1,0,0,0,2,255,255,255,1,0,0,0,10,255,255,255, + 1,0,0,0,8,68,68,68,1,205,205,205,1,0,0,0,2,255,255,255, + 12,0,0,0,8,8,8,8,1,248,248,248,1,2,2,2,1,0,0,0, + 22,243,243,243,1,12,12,12,1,0,0,0,22,249,249,249,1,4,4,4, + 1,0,0,0,2,37,37,37,1,120,120,120,2,113,113,113,1,64,64,64, + 1,0,0,0,2,31,31,31,1,103,103,103,1,0,0,0,3,106,106,106, + 1,120,120,120,1,119,119,119,1,100,100,100,1,33,33,33,1,0,0,0, + 1,255,255,255,5,0,0,0,1,80,80,80,1,179,179,179,1,80,80,80, + 1,83,83,83,1,191,191,191,1,87,87,87,1,0,0,0,1,137,137,137, + 1,206,206,206,1,41,41,41,1,0,0,0,2,218,218,218,1,64,64,64, + 2,97,97,97,1,221,221,221,1,15,15,15,1,0,0,0,1,255,255,255, + 3,0,0,0,2,80,80,80,1,144,144,144,1,0,0,0,2,87,87,87, + 1,138,138,138,1,4,4,4,1,202,202,202,1,73,73,73,1,145,145,145, + 1,0,0,0,2,216,216,216,1,0,0,0,3,182,182,182,1,42,42,42, + 1,0,0,0,2,255,255,255,1,0,0,0,3,80,80,80,1,189,189,189, + 1,104,104,104,1,122,122,122,1,202,202,202,1,51,51,51,1,77,77,77, + 1,134,134,134,1,3,3,3,1,214,214,214,1,9,9,9,1,0,0,0, + 1,222,222,222,1,160,160,160,2,177,177,177,1,148,148,148,1,0,0,0, + 7,80,80,80,1,186,186,186,1,96,96,96,1,72,72,72,1,8,8,8, + 1,0,0,0,1,175,175,175,1,191,191,191,1,168,168,168,1,226,226,226, + 1,97,97,97,1,0,0,0,1,217,217,217,1,32,32,32,1,59,59,59, + 1,196,196,196,1,34,34,34,1,0,0,0,7,80,80,80,1,144,144,144, + 1,0,0,0,3,22,22,22,1,197,197,197,1,8,8,8,2,43,43,43, + 1,200,200,200,1,0,0,0,1,216,216,216,1,0,0,0,2,64,64,64, + 1,206,206,206,1,4,4,4,1,0,0,0,6,80,80,80,1,144,144,144, + 1,0,0,0,3,114,114,114,1,113,113,113,1,0,0,0,3,195,195,195, + 1,48,48,48,1,216,216,216,1,0,0,0,3,150,150,150,1,122,122,122, + 1,0,0,0,101,0,0) + ); + +const + objdata_tmsesqlite3dataset: record size: integer; data: array[0..1006] of byte end = + (size: 1007; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,18,116,109,115, + 101,115,113,108,105,116,101,51,100,97,116,97,115,101,116,12,98,105,116,109, + 97,112,46,105,109,97,103,101,10,184,3,0,0,0,0,0,0,0,0,0, + 0,24,0,0,0,24,0,0,0,132,3,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,255,255,255,17,152,164,126,3,199,201,193,1,220,220,220, + 1,223,223,223,1,255,255,255,15,152,164,126,3,193,200,178,1,200,206,186, + 1,212,217,201,1,219,223,210,1,238,240,234,1,253,253,252,1,217,218,215, + 1,255,255,255,13,252,252,252,1,228,231,222,1,207,212,195,1,221,224,212, + 1,251,252,251,1,254,254,254,2,152,164,126,2,245,246,242,1,255,255,255, + 13,243,244,240,1,215,220,205,1,201,207,188,1,168,178,146,1,210,215,199, + 1,152,164,126,3,249,250,248,1,254,254,254,1,221,225,213,1,255,255,255, + 11,243,245,241,1,152,164,126,1,239,241,236,1,237,239,233,1,205,211,193, + 1,152,164,126,2,231,234,225,1,233,235,227,1,248,249,246,1,252,252,251, + 1,152,164,126,2,255,255,255,9,254,254,254,1,152,164,126,3,253,253,253, + 1,214,219,204,1,203,208,189,1,235,238,231,1,152,164,126,1,233,236,228, + 1,254,254,254,1,230,233,224,1,152,164,126,2,255,255,255,10,152,164,126, + 1,176,185,156,1,152,164,126,1,249,250,248,1,253,253,253,1,222,226,214, + 1,224,228,217,1,249,249,247,1,250,250,248,1,250,251,249,1,152,164,126, + 2,255,255,255,10,252,252,251,1,240,242,237,1,226,229,219,1,194,201,178, + 1,152,164,126,1,254,254,254,1,224,228,216,1,152,164,126,1,221,225,212, + 1,254,254,254,1,246,247,244,1,152,164,126,1,219,223,210,1,255,255,255, + 10,249,250,248,1,201,207,188,1,212,217,202,1,230,233,224,1,204,210,191, + 1,246,247,244,1,207,212,195,1,152,164,126,1,226,229,219,1,254,254,254, + 1,248,249,247,1,218,222,208,1,222,226,214,1,255,255,255,9,254,254,254, + 1,236,238,231,1,208,213,196,1,152,164,126,1,223,226,215,1,239,241,235, + 1,214,219,204,1,200,206,186,1,152,164,126,1,219,223,210,1,234,236,229, + 1,252,252,251,1,234,236,229,1,152,164,126,3,255,255,255,7,238,240,234, + 1,210,215,199,1,152,164,126,3,245,246,243,1,224,228,217,1,197,203,182, + 1,152,164,126,1,224,227,216,1,245,246,242,1,227,230,220,1,152,164,126, + 3,255,255,255,8,254,254,254,1,152,164,126,2,252,252,251,1,152,164,126, + 1,224,228,217,1,219,223,209,1,192,199,176,1,152,164,126,1,224,228,217, + 1,254,254,254,1,246,247,244,1,205,210,192,1,152,164,126,1,200,206,187, + 1,253,253,252,1,255,255,255,9,219,223,210,1,209,214,197,1,252,252,251, + 1,152,164,126,1,216,220,206,1,189,197,173,1,152,164,126,1,225,228,217, + 1,255,255,255,1,238,240,234,1,205,211,193,1,207,212,195,1,249,249,247, + 1,255,255,255,11,253,253,252,1,227,230,220,1,152,164,126,1,205,210,192, + 1,191,199,175,1,152,164,126,1,224,227,216,1,255,255,255,1,251,251,250, + 1,229,232,223,1,212,217,202,1,152,164,126,2,255,255,255,12,251,251,250, + 1,200,206,186,1,152,164,126,2,219,223,210,1,254,254,254,1,247,247,245, + 1,216,220,206,1,152,164,126,3,255,255,255,13,234,236,229,1,152,164,126, + 1,184,192,166,1,209,214,197,1,254,254,254,1,226,229,219,1,152,164,126, + 2,255,255,255,15,246,247,243,1,210,215,199,1,152,164,126,1,198,204,184, + 1,224,227,216,1,152,164,126,2,227,230,220,1,152,164,126,1,255,255,255, + 14,254,254,254,1,213,218,203,1,152,164,126,1,199,205,185,1,234,236,228, + 1,225,228,218,1,222,226,214,1,152,164,126,3,255,255,255,14,221,225,213, + 1,152,164,126,2,218,222,208,1,255,255,255,19,206,207,203,1,216,221,207, + 1,152,164,126,1,201,207,187,1,255,255,255,20,187,192,178,1,152,164,126, + 2,232,235,227,1,255,255,255,20,182,186,171,1,152,164,126,1,216,220,206, + 1,255,255,255,21,176,182,164,1,211,216,200,1,255,255,255,22,191,191,191, + 1,255,255,255,23,0,0) + ); + +const + objdata_tdbcalendardatetimeedit: record size: integer; data: array[0..1106] of byte end = + (size: 1107; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,23,116,100,98, + 99,97,108,101,110,100,97,114,100,97,116,101,116,105,109,101,101,100,105,116, + 23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99, + 111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116, + 105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111, + 95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105, + 109,97,103,101,10,208,3,0,0,0,0,0,0,6,0,0,0,24,0,0, + 0,24,0,0,0,140,3,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,128,128,128,25,184,255,255,1,0,0,0,2,4,5,5,1,126,174,174, + 1,184,255,255,3,0,0,0,5,184,255,255,1,0,0,0,1,169,234,234, + 1,17,23,23,1,255,255,255,6,128,128,128,1,184,255,255,1,0,0,0, + 1,184,255,255,1,126,174,174,1,4,5,5,1,184,255,255,2,0,0,0, + 1,184,255,255,2,0,0,0,1,184,255,255,4,0,0,0,1,184,255,255, + 1,255,255,255,1,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128, + 1,184,255,255,1,0,0,0,1,184,255,255,2,0,0,0,1,184,255,255, + 5,0,0,0,1,184,255,255,4,0,0,0,1,184,255,255,1,255,255,255, + 1,0,0,0,3,128,128,128,1,255,255,255,1,128,128,128,1,184,255,255, + 1,0,0,0,1,184,255,255,2,0,0,0,1,184,255,255,5,0,0,0, + 1,184,255,255,4,0,0,0,1,184,255,255,1,255,255,255,1,208,208,208, + 1,0,0,0,1,208,208,208,1,128,128,128,1,255,255,255,1,128,128,128, + 1,184,255,255,1,0,0,0,1,184,255,255,1,126,174,174,1,4,5,5, + 1,184,255,255,5,0,0,0,1,184,255,255,2,182,252,252,1,167,231,231, + 1,0,0,0,1,178,247,247,1,255,255,255,1,208,208,208,3,128,128,128, + 1,255,255,255,1,128,128,128,1,184,255,255,1,0,0,0,2,4,5,5, + 1,126,174,174,1,184,255,255,2,0,0,0,1,184,255,255,2,0,0,0, + 1,184,255,255,2,161,223,223,1,0,0,0,1,161,223,223,1,0,0,0, + 1,128,128,128,5,255,255,255,25,0,0,0,25,255,255,255,22,0,0,0, + 2,255,255,255,1,179,179,179,2,255,255,255,1,179,179,179,2,255,255,255, + 1,179,179,179,2,255,255,255,1,179,179,179,2,255,255,255,1,0,0,0, + 2,255,255,255,1,0,0,0,2,255,255,255,1,0,0,255,2,255,255,255, + 1,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0, + 2,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,2,255,255,255, + 1,0,0,0,2,240,240,240,1,7,7,7,1,23,23,23,1,255,255,255, + 1,7,7,7,2,255,255,255,1,7,7,7,2,255,255,255,1,0,0,255, + 2,255,255,255,1,0,0,0,2,255,255,255,10,247,247,247,1,248,248,248, + 1,255,255,255,1,247,247,247,2,255,255,255,1,247,247,247,2,255,255,255, + 4,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255,1,0,0,0, + 2,248,248,248,1,7,7,7,1,15,15,15,1,255,255,255,1,0,0,0, + 2,255,255,255,1,15,15,15,1,7,7,7,1,233,233,233,1,7,7,7, + 1,23,23,23,1,255,255,255,1,0,0,0,2,255,255,255,1,0,0,255, + 2,255,255,255,1,0,0,0,2,255,255,255,4,247,247,247,1,248,248,248, + 1,255,255,255,4,248,248,248,1,247,247,247,1,255,255,255,1,247,247,247, + 1,248,248,248,1,255,255,255,7,0,0,0,2,255,255,255,22,0,0,0, + 2,255,255,255,1,7,7,7,2,255,255,255,1,0,0,0,2,255,255,255, + 1,0,0,0,2,255,255,255,1,15,15,15,1,7,7,7,1,248,248,248, + 1,0,0,0,2,255,255,255,1,0,0,0,2,255,255,255,1,0,0,255, + 2,255,255,255,1,0,0,0,2,255,255,255,1,247,247,247,2,255,255,255, + 7,248,248,248,1,247,247,247,1,255,255,255,10,0,0,0,2,255,255,255, + 22,0,0,0,2,255,255,255,1,0,0,0,2,247,247,247,1,0,0,0, + 1,7,7,7,1,240,240,240,1,15,15,15,1,30,30,30,1,255,255,255, + 1,7,7,7,1,0,0,0,1,247,247,247,1,159,159,159,2,255,255,255, + 1,179,179,179,2,255,255,255,1,197,197,197,1,183,183,183,1,242,242,242, + 1,0,0,0,15,10,10,10,2,0,0,0,4,9,9,9,1,11,11,11, + 1,2,2,2,1,0,0,0,1,12,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,66,0,0) + ); + +const + objdata_tsequencelink: record size: integer; data: array[0..1332] of byte end = + (size: 1333; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,115,101, + 113,117,101,110,99,101,108,105,110,107,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,188,4,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,228,1,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,255,255,255,1,184,255,255,22,255, + 255,255,2,184,255,255,1,255,255,255,14,0,0,0,1,255,255,255,5,184, + 255,255,1,255,255,255,2,184,255,255,1,255,255,255,3,0,0,0,1,255, + 255,255,1,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,1,0, + 0,0,5,255,255,255,3,184,255,255,1,255,255,255,2,184,255,255,1,255, + 255,255,3,0,0,0,1,255,255,255,1,0,0,0,3,255,255,255,1,0, + 0,0,2,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,3,255, + 255,255,2,184,255,255,1,255,255,255,2,184,255,255,1,255,255,255,3,0, + 0,0,1,255,255,255,1,0,0,0,8,255,255,255,7,184,255,255,1,255, + 255,255,2,184,255,255,1,255,255,255,3,0,0,0,1,255,255,255,1,0, + 0,0,8,255,255,255,7,184,255,255,1,255,255,255,2,184,255,255,1,255, + 255,255,3,0,0,0,1,255,255,255,1,0,0,0,2,255,255,255,1,0, + 0,0,6,255,255,255,2,0,0,0,2,255,255,255,2,184,255,255,1,255, + 255,255,2,184,255,255,1,255,255,255,3,0,0,0,1,255,255,255,1,0, + 0,0,2,255,255,255,1,0,0,0,3,255,255,255,1,0,0,0,6,255, + 255,255,2,184,255,255,1,255,255,255,2,184,255,255,1,255,255,255,3,0, + 0,0,1,255,255,255,1,0,0,0,2,255,255,255,2,0,0,0,2,255, + 255,255,1,0,0,0,5,255,255,255,3,184,255,255,1,255,255,255,2,184, + 255,255,1,255,255,255,20,184,255,255,1,255,255,255,2,184,255,255,22,255, + 255,255,7,0,0,255,1,255,255,255,10,0,0,255,1,255,255,255,12,0, + 0,255,1,255,255,255,9,0,0,255,3,255,255,255,11,0,0,255,1,255, + 255,255,8,0,0,255,5,255,255,255,10,0,0,255,1,255,255,255,10,0, + 0,255,1,255,255,255,10,0,0,255,5,255,255,255,8,0,0,255,1,255, + 255,255,11,0,0,255,3,255,255,255,9,0,0,255,1,255,255,255,12,0, + 0,255,1,255,255,255,10,0,0,255,1,255,255,255,150,160,2,0,0,0, + 0,0,1,255,255,255,22,0,0,0,2,255,255,255,1,0,0,0,14,3, + 3,3,1,0,0,0,5,255,255,255,1,0,0,0,2,255,255,255,1,0, + 0,0,3,209,209,209,1,0,0,0,1,136,136,136,1,160,160,160,1,0, + 0,0,2,67,67,67,1,134,134,134,1,0,0,0,1,24,24,24,1,179, + 179,179,1,182,182,182,1,186,186,186,1,98,98,98,1,0,0,0,3,255, + 255,255,1,0,0,0,2,255,255,255,1,0,0,0,3,216,216,216,1,0, + 0,0,1,141,141,141,1,225,225,225,1,78,78,78,1,0,0,0,1,69, + 69,69,1,138,138,138,1,0,0,0,1,197,197,197,1,49,49,49,1,0, + 0,0,1,3,3,3,1,190,190,190,1,26,26,26,1,0,0,0,2,255, + 255,255,1,0,0,0,2,255,255,255,1,0,0,0,3,216,216,216,1,0, + 0,0,1,141,141,141,1,89,89,89,1,210,210,210,1,18,18,18,1,69, + 69,69,1,138,138,138,1,27,27,27,1,189,189,189,1,0,0,0,7,255, + 255,255,1,0,0,0,2,255,255,255,1,0,0,0,3,216,216,216,1,0, + 0,0,1,141,141,141,1,66,66,66,1,86,86,86,1,164,164,164,1,69, + 69,69,1,138,138,138,1,53,53,53,1,174,174,174,1,0,0,0,7,255, + 255,255,1,0,0,0,2,255,255,255,1,0,0,0,3,216,216,216,1,0, + 0,0,1,141,141,141,1,66,66,66,1,0,0,0,1,171,171,171,1,149, + 149,149,1,138,138,138,1,9,9,9,1,214,214,214,1,2,2,2,1,0, + 0,0,2,117,117,117,1,46,46,46,1,0,0,0,2,255,255,255,1,0, + 0,0,2,255,255,255,1,0,0,0,3,216,216,216,1,0,0,0,1,141, + 141,141,1,66,66,66,1,0,0,0,1,21,21,21,1,233,233,233,1,138, + 138,138,1,0,0,0,1,123,123,123,1,158,158,158,1,53,53,53,1,102, + 102,102,1,198,198,198,1,2,2,2,1,0,0,0,2,255,255,255,1,0, + 0,0,2,255,255,255,1,0,0,0,3,108,108,108,1,0,0,0,1,70, + 70,70,1,33,33,33,1,0,0,0,2,64,64,64,1,69,69,69,1,0, + 0,0,1,1,1,1,1,75,75,75,1,137,137,137,1,99,99,99,1,17, + 17,17,1,0,0,0,3,255,255,255,1,0,0,0,2,255,255,255,1,0, + 0,0,20,255,255,255,1,0,0,0,2,255,255,255,22,0,0,0,7,255, + 255,255,1,0,0,0,10,255,255,255,1,0,0,0,12,255,255,255,1,0, + 0,0,9,255,255,255,3,0,0,0,11,255,255,255,1,0,0,0,8,255, + 255,255,5,0,0,0,10,255,255,255,1,0,0,0,10,255,255,255,1,0, + 0,0,10,255,255,255,5,0,0,0,8,255,255,255,1,0,0,0,11,255, + 255,255,3,0,0,0,9,255,255,255,1,0,0,0,12,255,255,255,1,0, + 0,0,10,255,255,255,1,0,0,0,150,0,0) + ); + +const + objdata_tdbdatabutton: record size: integer; data: array[0..668] of byte end = + (size: 669; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,100,98, + 100,97,116,97,98,117,116,116,111,110,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,36,2,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,220,1,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,255,255,255,120,224,224,224,25,255, + 255,255,22,0,0,0,1,224,224,224,1,255,255,255,1,208,249,255,20,128, + 128,128,1,0,0,0,1,224,224,224,1,255,255,255,1,208,245,255,20,128, + 128,128,1,0,0,0,1,224,224,224,1,255,255,255,1,201,244,255,4,188, + 228,238,1,23,28,29,1,201,244,255,1,136,165,172,1,17,20,21,1,14, + 17,18,1,117,142,148,1,91,110,115,1,12,14,15,2,101,122,128,1,201, + 244,255,5,128,128,128,1,0,0,0,1,224,224,224,1,255,255,255,1,192, + 246,255,4,74,95,98,1,0,0,0,1,192,246,255,1,22,28,29,1,151, + 194,201,1,157,202,209,1,8,10,10,1,192,246,255,2,146,187,194,1,13, + 16,17,1,192,246,255,5,128,128,128,1,0,0,0,1,224,224,224,1,255, + 255,255,1,182,247,255,4,176,239,247,1,0,0,0,1,182,247,255,3,146, + 199,205,1,49,66,68,1,182,247,255,1,117,159,164,1,3,4,4,1,74, + 100,103,1,182,247,255,5,128,128,128,1,0,0,0,1,224,224,224,1,255, + 255,255,1,173,248,255,5,0,0,0,1,173,248,255,2,152,218,224,1,47, + 68,70,1,157,226,232,1,173,248,255,2,145,208,214,1,7,10,10,1,173, + 248,255,5,128,128,128,1,0,0,0,1,224,224,224,1,255,255,255,1,164, + 250,255,5,0,0,0,1,164,250,255,1,106,162,165,1,50,75,77,1,151, + 230,235,1,164,250,255,1,21,31,32,1,146,223,227,1,150,229,234,1,15, + 24,24,1,164,250,255,5,128,128,128,1,0,0,0,1,224,224,224,1,255, + 255,255,1,154,251,255,5,0,0,0,1,154,251,255,1,11,19,19,1,0, + 0,0,3,107,174,177,1,11,19,19,1,14,24,24,1,108,176,179,1,154, + 251,255,5,128,128,128,1,0,0,0,1,224,224,224,1,255,255,255,1,145, + 252,255,20,128,128,128,1,0,0,0,1,224,224,224,1,255,255,255,1,135, + 254,255,20,128,128,128,1,0,0,0,1,224,224,224,1,128,128,128,22,0, + 0,0,25,255,255,255,120,16,0,0,0,0,0,0,120,255,255,255,255,255, + 255,255,81,0,0,0,120,0,0) + ); + +const + objdata_tdbdialogstringedit: record size: integer; data: array[0..878] of byte end = + (size: 879; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,100,98, + 100,105,97,108,111,103,115,116,114,105,110,103,101,100,105,116,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,240,2,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,168,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255, + 120,128,128,128,25,0,0,0,22,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,13,243,243,243,7,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,184,255,255,1,183,254,254,1,22,31,31,1,125,173,173, + 1,184,255,255,1,0,0,0,1,37,51,51,1,35,49,49,1,22,31,31, + 1,108,149,149,1,0,0,0,1,184,255,255,1,0,0,0,1,243,243,243, + 1,232,232,232,5,128,128,128,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,184,255,255,1,149,207,207,1,56,78,78,1,70,97,97, + 1,184,255,255,1,0,0,0,1,184,255,255,2,165,228,228,1,8,11,11, + 1,184,255,255,1,0,0,0,1,184,255,255,1,243,243,243,1,226,226,226, + 5,128,128,128,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,1,92,128,128,1,144,199,199,1,38,53,53,1,183,253,253, + 1,0,0,0,1,184,255,255,1,183,254,254,1,136,189,189,1,31,43,43, + 1,184,255,255,1,0,0,0,1,184,255,255,1,243,243,243,1,215,215,215, + 5,128,128,128,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,184,255,255,1,53,74,74,1,183,253,253,1,74,102,102,1,145,201,201, + 1,0,0,0,4,109,151,151,1,184,255,255,1,0,0,0,1,184,255,255, + 1,243,243,243,1,0,0,0,1,204,204,204,1,0,0,0,1,204,204,204, + 1,0,0,0,1,128,128,128,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,162,224,224,1,0,0,0,3,90,125,125,1,0,0,0, + 1,184,255,255,1,183,254,254,1,141,195,195,1,13,18,18,1,184,255,255, + 1,0,0,0,1,184,255,255,1,243,243,243,1,0,0,0,1,194,194,194, + 1,0,0,0,1,194,194,194,1,0,0,0,1,128,128,128,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,105,145,145,1,117,162,162, + 1,184,255,255,1,174,241,241,1,40,55,55,1,0,0,0,1,184,255,255, + 2,164,227,227,1,12,16,16,1,184,255,255,1,0,0,0,1,184,255,255, + 1,243,243,243,1,183,183,183,5,128,128,128,1,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,51,70,70,1,170,236,236,1,184,255,255, + 2,48,66,66,1,0,0,0,1,37,51,51,1,36,50,50,1,28,39,39, + 1,115,160,160,1,184,255,255,1,0,0,0,1,184,255,255,1,243,243,243, + 1,172,172,172,5,128,128,128,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,184,255,255,10,0,0,0,1,184,255,255,1,0,0,0, + 1,243,243,243,1,167,167,167,5,128,128,128,1,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,184,255,255,13,128,128,128,7,224,224,224, + 1,255,255,255,1,128,128,128,1,224,224,224,22,255,255,255,145,16,0,0, + 0,0,0,0,120,255,255,255,255,255,255,255,81,0,0,0,120,0,0) + ); + +const + objdata_tdbdataimage: record size: integer; data: array[0..1731] of byte end = + (size: 1732; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,100,98, + 100,97,116,97,105,109,97,103,101,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,76,6,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,160,4,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,171,171,171,1,128,128,128,1,171,171, + 171,20,128,128,128,1,171,171,171,1,128,128,128,24,171,171,171,1,128,128, + 128,1,144,255,247,20,128,128,128,1,171,171,171,2,128,128,128,1,150,255, + 247,3,129,253,248,1,85,247,249,1,131,253,248,1,149,255,247,14,128,128, + 128,1,171,171,171,2,128,128,128,1,155,255,248,2,62,244,251,1,1,237, + 253,1,25,240,253,1,2,237,253,1,67,245,251,1,155,255,248,13,128,128, + 128,1,171,171,171,2,128,128,128,1,161,255,249,1,140,253,250,1,1,237, + 253,1,139,251,255,1,183,255,255,1,134,250,254,1,2,237,253,1,143,253, + 250,1,161,255,249,12,128,128,128,1,171,171,171,2,128,128,128,1,167,255, + 249,1,95,247,251,1,26,240,253,1,183,255,255,3,20,239,253,1,100,248, + 250,1,167,255,249,12,128,128,128,1,171,171,171,2,128,128,128,1,173,255, + 250,1,151,253,251,1,1,237,253,1,139,251,255,1,183,255,255,1,133,250, + 254,1,3,237,253,1,155,253,251,1,173,255,250,3,172,255,250,9,128,128, + 128,1,171,171,171,2,128,128,128,1,178,255,250,2,74,244,252,1,2,237, + 253,1,21,239,253,1,3,237,253,1,80,245,252,1,178,255,250,13,128,128, + 128,1,171,171,171,2,128,128,128,1,184,255,251,3,163,253,251,1,110,248, + 252,1,166,253,251,1,184,255,251,13,164,241,222,1,128,128,128,1,171,171, + 171,2,128,128,128,1,190,255,252,17,188,253,249,1,85,193,111,1,6,158, + 4,1,128,128,128,1,171,171,171,2,128,128,128,1,196,255,252,13,195,255, + 252,3,156,232,201,1,30,175,36,1,3,190,0,1,3,173,0,1,128,128, + 128,1,171,171,171,2,128,128,128,1,201,255,253,14,185,245,232,1,76,194, + 94,1,6,185,5,1,2,194,0,1,3,188,0,1,3,171,0,1,128,128, + 128,1,171,171,171,2,128,128,128,1,207,255,254,13,108,208,132,1,16,189, + 17,1,2,204,1,1,2,198,0,1,3,192,0,1,3,186,0,1,3,169, + 0,1,128,128,128,1,171,171,171,2,128,128,128,1,213,255,254,12,87,197, + 104,1,1,209,2,1,1,208,1,1,2,202,1,1,2,196,0,1,3,189, + 0,1,3,183,0,1,3,167,0,1,128,128,128,1,171,171,171,2,128,128, + 128,1,246,116,83,1,247,129,93,1,247,134,100,1,247,137,109,1,247,143, + 117,1,247,146,123,1,245,145,122,1,244,137,109,1,243,130,97,1,241,122, + 85,1,240,115,73,1,234,106,60,1,35,154,6,1,1,212,1,1,1,206, + 1,1,2,199,0,1,3,193,0,1,3,187,0,1,4,181,0,1,3,165, + 0,1,128,128,128,1,171,171,171,2,128,128,128,1,254,137,66,1,255,158, + 82,1,255,165,94,1,255,172,107,1,255,179,120,1,255,186,133,1,254,188, + 137,1,251,176,117,1,248,163,96,1,245,151,76,1,242,139,56,1,240,126, + 36,1,201,109,14,1,20,172,2,1,2,203,1,1,2,197,0,1,3,191, + 0,1,3,184,0,1,4,178,0,1,3,163,0,1,128,128,128,1,171,171, + 171,2,128,128,128,1,254,135,63,1,255,156,79,1,255,163,92,1,255,170, + 104,1,255,178,117,1,255,185,130,1,254,191,142,1,252,179,121,1,249,166, + 101,1,246,154,81,1,243,142,60,1,240,129,40,1,237,117,20,1,155,113, + 2,1,9,184,2,1,2,194,0,1,3,188,0,1,4,182,0,1,4,176, + 0,1,3,162,0,1,128,128,128,1,171,171,171,2,128,128,128,1,254,133, + 60,1,255,155,76,1,255,162,89,1,255,169,102,1,255,176,114,1,255,183, + 127,1,255,190,140,1,252,181,126,1,249,169,106,1,246,157,85,1,244,144, + 65,1,241,132,44,1,238,119,24,1,235,107,4,1,115,122,1,1,6,181, + 0,1,3,186,0,1,4,180,0,1,4,173,0,1,3,162,0,1,128,128, + 128,1,171,171,171,2,128,128,128,1,254,132,57,1,255,153,73,1,255,160, + 86,1,255,167,99,1,255,174,112,1,255,182,125,1,255,189,137,1,253,184, + 130,1,250,172,110,1,247,159,90,1,244,147,69,1,241,135,49,1,239,122, + 29,1,236,110,8,1,235,105,0,1,133,117,1,1,13,166,1,1,4,177, + 0,1,4,171,0,1,3,162,0,1,128,128,128,1,171,171,171,2,128,128, + 128,1,254,130,55,1,255,151,70,1,255,159,83,1,255,166,96,1,255,173, + 109,1,255,180,122,1,255,187,134,1,253,187,135,1,251,175,115,1,248,162, + 94,1,245,150,74,1,242,137,53,1,239,125,33,1,236,112,13,1,235,105, + 0,2,161,111,2,1,22,150,2,1,4,171,0,1,3,162,0,1,128,128, + 128,1,171,171,171,2,128,128,128,1,253,109,49,1,254,126,61,1,254,132, + 72,1,254,138,83,1,254,144,94,1,254,150,105,1,254,156,116,1,253,160, + 122,1,251,149,105,1,248,139,88,1,246,128,71,1,244,118,54,1,241,108, + 36,1,239,97,19,1,237,89,5,3,188,94,5,1,33,135,3,1,4,155, + 0,1,128,128,128,1,171,171,171,1,128,128,128,24,171,171,171,1,128,128, + 128,1,171,171,171,20,128,128,128,1,171,171,171,1,116,1,0,0,0,0, + 0,1,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0,1,255,255, + 255,24,0,0,0,1,255,255,255,22,0,0,0,2,255,255,255,22,0,0, + 0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255,255, + 255,22,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0, + 0,2,255,255,255,20,251,251,251,1,255,255,255,1,0,0,0,2,255,255, + 255,19,233,233,233,1,236,236,236,1,255,255,255,1,0,0,0,2,255,255, + 255,17,252,252,252,1,224,224,224,1,255,255,255,3,0,0,0,2,255,255, + 255,16,235,235,235,1,239,239,239,1,255,255,255,4,0,0,0,2,255,255, + 255,14,252,252,252,1,240,240,240,1,255,255,255,6,0,0,0,2,255,255, + 255,13,234,234,234,1,253,253,253,1,255,255,255,7,0,0,0,2,255,255, + 255,1,238,238,238,1,236,236,236,10,235,235,235,1,225,225,225,1,255,255, + 255,8,0,0,0,2,255,255,255,13,251,251,251,1,239,239,239,1,255,255, + 255,7,0,0,0,2,255,255,255,14,253,253,253,1,249,249,249,1,255,255, + 255,6,0,0,0,2,255,255,255,15,254,254,254,1,252,252,252,1,255,255, + 255,5,0,0,0,2,255,255,255,16,254,254,254,1,248,248,248,1,255,255, + 255,4,0,0,0,2,255,255,255,17,254,254,254,1,244,244,244,1,255,255, + 255,3,0,0,0,2,255,255,255,18,254,254,254,1,243,243,243,1,255,255, + 255,2,0,0,0,1,255,255,255,24,0,0,0,1,255,255,255,1,0,0, + 0,20,255,255,255,1,0,0,0,1,0,0) + ); + +const + objdata_tfieldfieldlink: record size: integer; data: array[0..1470] of byte end = + (size: 1471; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,102,105, + 101,108,100,102,105,101,108,100,108,105,110,107,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,68,5,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,0,2,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,184,255,255,12,255,255,255, + 12,184,255,255,1,255,255,255,10,184,255,255,1,255,255,255,12,184,255,255, + 1,0,0,0,7,255,255,255,3,184,255,255,1,255,255,255,12,184,255,255, + 1,0,0,0,7,255,255,255,3,184,255,255,1,255,255,255,12,184,255,255, + 1,0,0,0,2,255,255,255,4,0,0,0,1,255,255,255,3,184,255,255, + 1,255,255,255,12,184,255,255,1,0,0,0,5,255,255,255,1,0,0,0, + 1,255,255,255,3,184,255,255,1,255,255,255,12,184,255,255,1,0,0,0, + 2,255,255,255,4,0,0,0,1,255,255,255,3,184,255,255,1,255,255,255, + 12,184,255,255,1,0,0,0,2,255,255,255,4,0,0,0,1,255,255,255, + 3,184,255,255,1,255,255,255,4,2,2,255,4,0,0,255,1,255,255,255, + 3,184,255,255,1,0,0,0,2,255,255,255,4,0,0,0,1,255,255,255, + 3,184,255,255,1,255,255,255,4,0,0,255,3,3,3,255,1,2,2,255, + 1,3,3,255,1,255,255,255,2,184,255,255,1,255,255,255,10,184,255,255, + 1,255,255,255,8,4,4,255,1,2,2,255,1,255,255,255,2,184,255,255, + 12,255,255,255,8,0,0,255,1,2,2,255,1,0,0,255,1,255,255,255, + 22,2,2,255,1,0,0,255,1,255,255,255,22,2,2,255,1,0,0,255, + 1,255,255,255,2,0,0,0,8,255,255,255,3,0,0,0,5,255,255,255, + 2,0,0,255,5,255,255,255,1,0,0,0,8,255,255,255,3,0,0,0, + 6,255,255,255,2,0,0,255,3,255,255,255,2,0,0,0,2,255,255,255, + 4,0,0,0,2,255,255,255,3,0,0,0,2,255,255,255,2,0,0,0, + 2,255,255,255,3,0,0,255,1,255,255,255,3,0,0,0,5,255,255,255, + 1,0,0,0,2,255,255,255,3,0,0,0,2,255,255,255,2,0,0,0, + 2,255,255,255,7,0,0,0,5,255,255,255,1,0,0,0,2,255,255,255, + 3,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,7,0,0,0, + 2,255,255,255,4,0,0,0,2,255,255,255,3,0,0,0,2,255,255,255, + 1,0,0,0,3,255,255,255,7,0,0,0,2,255,255,255,4,0,0,0, + 10,255,255,255,103,12,3,0,0,255,255,255,12,0,0,0,12,255,255,255, + 1,0,0,0,10,255,255,255,1,0,0,0,12,255,255,255,1,46,46,46, + 1,184,184,184,4,17,17,17,1,149,149,149,1,0,0,0,3,255,255,255, + 1,0,0,0,12,255,255,255,1,64,64,64,1,158,158,158,1,16,16,16, + 3,1,1,1,1,39,39,39,1,0,0,0,3,255,255,255,1,0,0,0, + 12,255,255,255,1,64,64,64,1,152,152,152,1,0,0,0,4,195,195,195, + 1,0,0,0,3,255,255,255,1,0,0,0,12,255,255,255,1,64,64,64, + 1,230,230,230,1,192,192,192,2,120,120,120,1,0,0,0,1,208,208,208, + 1,0,0,0,3,255,255,255,1,0,0,0,12,255,255,255,1,64,64,64, + 1,152,152,152,1,0,0,0,4,208,208,208,1,0,0,0,3,255,255,255, + 1,0,0,0,12,255,255,255,1,64,64,64,1,152,152,152,1,0,0,0, + 4,208,208,208,1,0,0,0,3,255,255,255,1,0,0,0,4,126,126,126, + 1,242,242,242,1,221,221,221,1,170,170,170,1,60,60,60,1,0,0,0, + 3,255,255,255,1,48,48,48,1,114,114,114,1,0,0,0,4,156,156,156, + 1,0,0,0,3,255,255,255,1,0,0,0,4,1,1,1,1,14,14,14, + 1,40,40,40,1,102,102,102,1,225,225,225,1,87,87,87,1,0,0,0, + 2,255,255,255,1,0,0,0,10,255,255,255,1,0,0,0,8,68,68,68, + 1,205,205,205,1,0,0,0,2,255,255,255,12,0,0,0,8,8,8,8, + 1,248,248,248,1,2,2,2,1,0,0,0,22,243,243,243,1,12,12,12, + 1,0,0,0,22,249,249,249,1,4,4,4,1,0,0,0,2,30,30,30, + 1,120,120,120,4,11,11,11,1,98,98,98,1,6,6,6,1,0,0,0, + 3,91,91,91,1,120,120,120,1,117,117,117,1,90,90,90,1,9,9,9, + 1,0,0,0,2,255,255,255,5,0,0,0,1,64,64,64,1,184,184,184, + 1,80,80,80,3,7,7,7,1,210,210,210,1,13,13,13,1,0,0,0, + 3,195,195,195,1,99,99,99,1,84,84,84,1,128,128,128,1,206,206,206, + 1,7,7,7,1,0,0,0,2,255,255,255,3,0,0,0,2,64,64,64, + 1,152,152,152,1,0,0,0,4,210,210,210,1,13,13,13,1,0,0,0, + 3,195,195,195,1,28,28,28,1,0,0,0,2,147,147,147,1,95,95,95, + 1,0,0,0,3,255,255,255,1,0,0,0,3,64,64,64,1,223,223,223, + 1,176,176,176,2,110,110,110,1,0,0,0,1,210,210,210,1,13,13,13, + 1,0,0,0,3,195,195,195,1,28,28,28,1,0,0,0,2,91,91,91, + 1,136,136,136,1,0,0,0,7,64,64,64,1,158,158,158,1,16,16,16, + 2,10,10,10,1,0,0,0,1,210,210,210,1,13,13,13,1,0,0,0, + 3,195,195,195,1,28,28,28,1,0,0,0,2,100,100,100,1,124,124,124, + 1,0,0,0,7,64,64,64,1,152,152,152,1,0,0,0,4,210,210,210, + 1,13,13,13,1,0,0,0,3,195,195,195,1,28,28,28,1,0,0,0, + 1,7,7,7,1,197,197,197,1,52,52,52,1,0,0,0,7,64,64,64, + 1,152,152,152,1,0,0,0,4,210,210,210,1,195,195,195,1,192,192,192, + 2,40,40,40,1,195,195,195,1,199,199,199,1,193,193,193,1,199,199,199, + 1,104,104,104,1,0,0,0,103,0,0) + ); + +const + objdata_tdbfilenameedit: record size: integer; data: array[0..742] of byte end = + (size: 743; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,100,98, + 102,105,108,101,110,97,109,101,101,100,105,116,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,108,2,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,36,2,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,120,128,128,128, + 25,0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 20,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 1,0,0,0,4,184,255,255,2,0,0,0,1,184,255,255,2,0,0,0, + 1,184,255,255,6,0,0,0,1,184,255,255,1,0,0,0,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,0,0,0, + 1,184,255,255,8,0,0,0,1,184,255,255,7,0,0,0,1,184,255,255, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 1,0,0,0,1,184,255,255,5,0,0,0,1,184,255,255,2,0,0,0, + 1,184,255,255,2,134,186,186,1,18,25,25,2,141,195,195,1,184,255,255, + 1,0,0,0,1,184,255,255,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,184,255,255,1,0,0,0,3,184,255,255,3,0,0,0, + 1,184,255,255,2,0,0,0,1,184,255,255,2,28,39,39,1,140,194,194, + 1,142,197,197,1,36,50,50,1,184,255,255,1,0,0,0,1,184,255,255, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 1,0,0,0,1,184,255,255,5,0,0,0,1,184,255,255,2,0,0,0, + 1,184,255,255,2,2,3,3,1,0,0,0,2,3,4,4,1,184,255,255, + 1,0,0,0,1,184,255,255,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,184,255,255,1,0,0,0,1,184,255,255,5,0,0,0, + 1,184,255,255,2,0,0,0,1,184,255,255,2,25,34,34,1,141,195,195, + 1,159,220,220,1,184,255,255,2,0,0,0,1,184,255,255,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,1,0,0,0, + 1,184,255,255,5,0,0,0,1,184,255,255,2,0,0,0,1,184,255,255, + 2,129,179,179,1,17,23,23,1,0,0,0,1,42,58,58,1,184,255,255, + 1,0,0,0,1,184,255,255,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,184,255,255,17,0,0,0,1,184,255,255,1,0,0,0, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255, + 20,224,224,224,1,255,255,255,1,128,128,128,1,224,224,224,22,255,255,255, + 145,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255,81,0,0,0, + 120,0,0) + ); + +const + objdata_tfieldlink: record size: integer; data: array[0..1529] of byte end = + (size: 1530; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,102,105, + 101,108,100,108,105,110,107,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,132,5,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,224,1,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,255,255,255,97,0,0,0,2,255,255,255,2, + 0,0,0,2,255,255,255,1,0,0,0,2,255,255,255,3,0,0,0,1, + 255,255,255,11,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,1, + 0,0,0,3,255,255,255,2,0,0,0,1,255,255,255,11,0,0,0,2, + 255,255,255,2,0,0,0,6,255,255,255,2,0,0,0,1,255,255,255,12, + 0,0,0,4,255,255,255,1,0,0,0,5,255,255,255,1,0,0,0,1, + 255,255,255,2,2,2,255,4,0,0,255,1,255,255,255,5,0,0,0,4, + 255,255,255,1,0,0,0,5,255,255,255,1,0,0,0,1,255,255,255,2, + 0,0,255,3,3,3,255,1,2,2,255,1,3,3,255,1,255,255,255,4, + 0,0,0,10,255,255,255,1,0,0,0,1,255,255,255,6,4,4,255,1, + 2,2,255,1,255,255,255,5,0,0,0,2,255,255,255,1,0,0,0,2, + 255,255,255,3,0,0,0,7,255,255,255,2,0,0,255,1,2,2,255,1, + 0,0,255,1,255,255,255,22,2,2,255,1,0,0,255,1,255,255,255,22, + 2,2,255,1,0,0,255,1,255,255,255,2,0,0,0,8,255,255,255,3, + 0,0,0,4,255,255,255,3,0,0,255,5,255,255,255,1,0,0,0,8, + 255,255,255,3,0,0,0,5,255,255,255,3,0,0,255,3,255,255,255,2, + 0,0,0,2,255,255,255,4,0,0,0,2,255,255,255,3,0,0,0,2, + 255,255,255,2,0,0,0,2,255,255,255,3,0,0,255,1,255,255,255,3, + 0,0,0,5,255,255,255,1,0,0,0,2,255,255,255,3,0,0,0,2, + 255,255,255,2,0,0,0,2,255,255,255,7,0,0,0,5,255,255,255,1, + 0,0,0,2,255,255,255,3,0,0,0,2,255,255,255,2,0,0,0,2, + 255,255,255,7,0,0,0,2,255,255,255,4,0,0,0,2,255,255,255,3, + 0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,7,0,0,0,2, + 255,255,255,4,0,0,0,11,255,255,255,7,0,0,0,2,255,255,255,4, + 0,0,0,9,255,255,255,80,108,3,0,0,0,0,0,97,105,105,105,1, + 6,6,6,1,0,0,0,2,2,2,2,1,102,102,102,1,0,0,0,1, + 31,31,31,1,103,103,103,1,0,0,0,3,105,105,105,1,0,0,0,11, + 152,152,152,1,81,81,81,1,0,0,0,2,68,68,68,1,150,150,150,1, + 0,0,0,1,137,137,137,1,206,206,206,1,41,41,41,1,0,0,0,2, + 224,224,224,1,0,0,0,11,53,53,53,1,173,173,173,1,0,0,0,2, + 164,164,164,1,50,50,50,1,4,4,4,1,202,202,202,1,73,73,73,1, + 145,145,145,1,0,0,0,2,224,224,224,1,0,0,0,12,202,202,202,1, + 16,16,16,1,13,13,13,1,196,196,196,1,0,0,0,1,77,77,77,1, + 134,134,134,1,3,3,3,1,214,214,214,1,9,9,9,1,0,0,0,1, + 224,224,224,1,0,0,0,2,126,126,126,1,242,242,242,1,221,221,221,1, + 170,170,170,1,60,60,60,1,0,0,0,5,111,111,111,1,101,101,101,1, + 99,99,99,1,106,106,106,1,0,0,0,1,175,175,175,1,191,191,191,1, + 168,168,168,1,226,226,226,1,97,97,97,1,0,0,0,1,224,224,224,1, + 0,0,0,2,1,1,1,1,14,14,14,1,40,40,40,1,102,102,102,1, + 225,225,225,1,87,87,87,1,0,0,0,4,19,19,19,1,184,184,184,1, + 181,181,181,1,15,15,15,1,22,22,22,1,197,197,197,1,8,8,8,2, + 43,43,43,1,200,200,200,1,0,0,0,1,224,224,224,1,0,0,0,6, + 68,68,68,1,205,205,205,1,0,0,0,5,166,166,166,1,158,158,158,1, + 0,0,0,1,114,114,114,1,113,113,113,1,0,0,0,3,195,195,195,1, + 48,48,48,1,238,238,238,1,192,192,192,3,15,15,15,1,0,0,0,2, + 8,8,8,1,248,248,248,1,2,2,2,1,0,0,0,22,243,243,243,1, + 12,12,12,1,0,0,0,22,249,249,249,1,4,4,4,1,0,0,0,2, + 14,14,14,1,56,56,56,4,5,5,5,1,46,46,46,1,2,2,2,1, + 0,0,0,3,42,42,42,1,56,56,56,1,53,53,53,1,27,27,27,1, + 0,0,0,3,255,255,255,5,0,0,0,1,64,64,64,1,210,210,210,1, + 144,144,144,3,13,13,13,1,210,210,210,1,13,13,13,1,0,0,0,3, + 195,195,195,1,156,156,156,1,148,148,148,1,190,190,190,1,155,155,155,1, + 0,0,0,3,255,255,255,3,0,0,0,2,64,64,64,1,152,152,152,1, + 0,0,0,4,210,210,210,1,13,13,13,1,0,0,0,3,195,195,195,1, + 28,28,28,1,0,0,0,2,175,175,175,1,74,74,74,1,0,0,0,3, + 255,255,255,1,0,0,0,3,64,64,64,1,197,197,197,1,112,112,112,2, + 70,70,70,1,0,0,0,1,210,210,210,1,13,13,13,1,0,0,0,3, + 195,195,195,1,28,28,28,1,0,0,0,2,102,102,102,1,128,128,128,1, + 0,0,0,7,64,64,64,1,184,184,184,1,80,80,80,2,50,50,50,1, + 0,0,0,1,210,210,210,1,13,13,13,1,0,0,0,3,195,195,195,1, + 28,28,28,1,0,0,0,2,92,92,92,1,132,132,132,1,0,0,0,7, + 64,64,64,1,152,152,152,1,0,0,0,4,210,210,210,1,13,13,13,1, + 0,0,0,3,195,195,195,1,28,28,28,1,0,0,0,2,163,163,163,1, + 78,78,78,1,0,0,0,7,64,64,64,1,152,152,152,1,0,0,0,4, + 210,210,210,1,134,134,134,1,128,128,128,2,26,26,26,1,195,195,195,1, + 142,142,142,1,132,132,132,1,176,176,176,1,167,167,167,1,2,2,2,1, + 0,0,0,7,16,16,16,1,38,38,38,1,0,0,0,4,52,52,52,1, + 64,64,64,3,13,13,13,1,48,48,48,1,64,64,64,1,61,61,61,1, + 30,30,30,1,0,0,0,80,0,0) + ); + +const + objdata_ttimestampfieldlink: record size: integer; data: array[0..1490] of byte end = + (size: 1491; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,116,105, + 109,101,115,116,97,109,112,102,105,101,108,100,108,105,110,107,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,84,5,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,208,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255, + 97,0,0,0,5,255,255,255,4,0,0,0,6,255,255,255,9,0,0,0, + 6,255,255,255,3,0,0,0,6,255,255,255,9,0,0,0,2,255,255,255, + 2,0,0,0,2,255,255,255,1,0,0,0,2,255,255,255,2,0,0,0, + 2,255,255,255,11,0,0,0,2,255,255,255,3,0,0,0,4,255,255,255, + 2,0,0,0,2,255,255,255,2,2,2,255,4,0,0,255,1,255,255,255, + 4,0,0,0,2,255,255,255,3,0,0,0,1,255,255,255,5,0,0,0, + 2,255,255,255,2,0,0,255,3,3,3,255,1,2,2,255,1,3,3,255, + 1,255,255,255,3,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255, + 5,0,0,0,2,255,255,255,6,4,4,255,1,2,2,255,1,255,255,255, + 3,0,0,0,6,255,255,255,1,0,0,0,2,255,255,255,2,0,0,0, + 2,255,255,255,6,0,0,255,1,2,2,255,1,0,0,255,1,255,255,255, + 22,2,2,255,1,0,0,255,1,255,255,255,22,2,2,255,1,0,0,255, + 1,255,255,255,2,0,0,0,8,255,255,255,3,0,0,0,4,255,255,255, + 3,0,0,255,5,255,255,255,1,0,0,0,8,255,255,255,3,0,0,0, + 5,255,255,255,3,0,0,255,3,255,255,255,2,0,0,0,2,255,255,255, + 4,0,0,0,2,255,255,255,3,0,0,0,2,255,255,255,2,0,0,0, + 2,255,255,255,3,0,0,255,1,255,255,255,3,0,0,0,5,255,255,255, + 1,0,0,0,2,255,255,255,3,0,0,0,2,255,255,255,2,0,0,0, + 2,255,255,255,7,0,0,0,5,255,255,255,1,0,0,0,2,255,255,255, + 3,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,7,0,0,0, + 2,255,255,255,4,0,0,0,2,255,255,255,3,0,0,0,2,255,255,255, + 2,0,0,0,2,255,255,255,7,0,0,0,2,255,255,255,4,0,0,0, + 11,255,255,255,7,0,0,0,2,255,255,255,4,0,0,0,9,255,255,255, + 80,76,3,0,0,0,0,0,97,37,37,37,1,120,120,120,1,119,119,119, + 1,108,108,108,1,43,43,43,1,0,0,0,4,90,90,90,1,120,120,120, + 4,44,44,44,1,0,0,0,9,80,80,80,1,179,179,179,1,80,80,80, + 1,96,96,96,1,205,205,205,1,79,79,79,1,0,0,0,3,60,60,60, + 1,80,80,80,1,190,190,190,1,118,118,118,1,80,80,80,1,29,29,29, + 1,0,0,0,9,80,80,80,1,144,144,144,1,0,0,0,2,31,31,31, + 1,210,210,210,1,0,0,0,1,116,116,116,1,43,43,43,1,0,0,0, + 2,160,160,160,1,55,55,55,1,0,0,0,11,80,80,80,1,144,144,144, + 1,0,0,0,3,225,225,225,1,1,1,1,1,37,37,37,1,13,13,13, + 1,0,0,0,2,160,160,160,1,55,55,55,1,0,0,0,2,126,126,126, + 1,242,242,242,1,221,221,221,1,170,170,170,1,60,60,60,1,0,0,0, + 4,80,80,80,1,144,144,144,1,0,0,0,3,225,225,225,1,0,0,0, + 5,160,160,160,1,55,55,55,1,0,0,0,2,1,1,1,1,14,14,14, + 1,40,40,40,1,102,102,102,1,225,225,225,1,87,87,87,1,0,0,0, + 3,80,80,80,1,144,144,144,1,0,0,0,2,89,89,89,1,167,167,167, + 1,0,0,0,5,160,160,160,1,55,55,55,1,0,0,0,6,68,68,68, + 1,205,205,205,1,0,0,0,3,80,80,80,1,228,228,228,1,192,192,192, + 1,195,195,195,1,175,175,175,1,21,21,21,1,0,0,0,1,153,153,153, + 1,56,56,56,1,0,0,0,2,160,160,160,1,55,55,55,1,0,0,0, + 6,8,8,8,1,248,248,248,1,2,2,2,1,0,0,0,22,243,243,243, + 1,12,12,12,1,0,0,0,22,249,249,249,1,4,4,4,1,0,0,0, + 2,14,14,14,1,56,56,56,4,5,5,5,1,46,46,46,1,2,2,2, + 1,0,0,0,3,42,42,42,1,56,56,56,1,53,53,53,1,27,27,27, + 1,0,0,0,3,255,255,255,5,0,0,0,1,64,64,64,1,210,210,210, + 1,144,144,144,3,13,13,13,1,210,210,210,1,13,13,13,1,0,0,0, + 3,195,195,195,1,156,156,156,1,148,148,148,1,190,190,190,1,155,155,155, + 1,0,0,0,3,255,255,255,3,0,0,0,2,64,64,64,1,152,152,152, + 1,0,0,0,4,210,210,210,1,13,13,13,1,0,0,0,3,195,195,195, + 1,28,28,28,1,0,0,0,2,175,175,175,1,74,74,74,1,0,0,0, + 3,255,255,255,1,0,0,0,3,64,64,64,1,197,197,197,1,112,112,112, + 2,70,70,70,1,0,0,0,1,210,210,210,1,13,13,13,1,0,0,0, + 3,195,195,195,1,28,28,28,1,0,0,0,2,102,102,102,1,128,128,128, + 1,0,0,0,7,64,64,64,1,184,184,184,1,80,80,80,2,50,50,50, + 1,0,0,0,1,210,210,210,1,13,13,13,1,0,0,0,3,195,195,195, + 1,28,28,28,1,0,0,0,2,92,92,92,1,132,132,132,1,0,0,0, + 7,64,64,64,1,152,152,152,1,0,0,0,4,210,210,210,1,13,13,13, + 1,0,0,0,3,195,195,195,1,28,28,28,1,0,0,0,2,163,163,163, + 1,78,78,78,1,0,0,0,7,64,64,64,1,152,152,152,1,0,0,0, + 4,210,210,210,1,134,134,134,1,128,128,128,2,26,26,26,1,195,195,195, + 1,142,142,142,1,132,132,132,1,176,176,176,1,167,167,167,1,2,2,2, + 1,0,0,0,7,16,16,16,1,38,38,38,1,0,0,0,4,52,52,52, + 1,64,64,64,3,13,13,13,1,48,48,48,1,64,64,64,1,61,61,61, + 1,30,30,30,1,0,0,0,80,0,0) + ); + +const + objdata_tdbevent: record size: integer; data: array[0..2487] of byte end = + (size: 2488; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,8,116,100,98, + 101,118,101,110,116,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97, + 114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97, + 112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101, + 100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116, + 109,97,112,46,105,109,97,103,101,10,68,9,0,0,0,0,0,0,6,0, + 0,0,24,0,0,0,24,0,0,0,0,9,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,132,255,255,1,135,255,255,1,138,255,255,1,140,255, + 255,1,143,255,255,1,146,255,255,1,149,255,255,1,152,255,255,1,155,255, + 255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255, + 255,1,172,255,255,1,174,255,255,1,177,255,255,1,180,255,255,1,183,255, + 255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255, + 255,1,132,255,255,1,135,255,255,1,138,255,255,1,140,255,255,1,143,255, + 255,1,146,255,255,1,149,255,255,1,152,255,255,1,155,255,255,1,157,255, + 255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255, + 255,1,164,240,255,1,165,238,255,1,180,255,255,1,183,255,255,1,186,255, + 255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255, + 255,1,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255, + 255,1,149,255,255,1,152,255,255,1,155,255,255,1,157,255,255,1,160,255, + 255,1,163,255,255,1,166,255,255,1,169,255,255,1,140,208,255,1,55,78, + 255,1,87,124,255,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255, + 255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255, + 255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255, + 255,1,152,255,255,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255, + 255,1,166,255,255,1,105,159,255,1,68,88,255,1,136,137,255,1,99,120, + 255,1,166,235,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255, + 255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255, + 255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,152,255, + 255,1,155,255,255,1,157,255,255,1,160,255,255,1,159,248,255,1,72,110, + 255,1,92,108,255,1,175,175,255,1,102,119,255,1,76,108,255,1,169,240, + 255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255, + 255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1,140,255, + 255,1,143,255,255,1,146,255,255,1,149,255,255,1,152,255,255,1,155,255, + 255,1,157,255,255,1,140,223,255,1,60,89,255,1,123,132,255,1,145,153, + 255,1,69,92,255,1,126,184,255,1,177,255,255,1,180,255,255,1,183,255, + 255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255, + 255,1,132,255,255,1,135,255,255,1,138,255,255,1,140,255,255,1,143,255, + 255,1,146,255,255,1,149,255,255,1,152,255,255,1,155,255,255,1,111,181, + 255,1,73,98,255,1,160,163,255,1,99,119,255,1,77,115,255,1,164,243, + 255,1,174,255,255,1,177,255,255,1,180,255,255,1,183,255,255,1,186,255, + 255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255, + 255,1,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255, + 255,1,149,255,255,1,151,253,255,1,80,130,255,1,101,122,255,1,144,154, + 255,1,65,91,255,1,127,195,255,1,169,255,255,1,172,255,255,1,174,255, + 255,1,177,255,255,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255, + 255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255, + 255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,137,235, + 255,1,64,100,255,1,135,149,255,1,98,120,255,1,79,125,255,1,158,247, + 255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,177,255, + 255,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255, + 255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255, + 255,1,140,255,255,1,143,255,255,1,115,200,255,1,74,104,255,1,133,149, + 255,1,64,94,255,1,127,206,255,1,160,255,255,1,163,255,255,1,166,255, + 255,1,169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1,180,255, + 255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255, + 255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1,140,255, + 255,1,124,222,255,1,51,72,255,1,103,115,255,1,35,56,255,1,149,245, + 255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255, + 255,1,172,255,255,1,174,255,255,1,177,255,255,1,180,255,255,1,183,255, + 255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255, + 255,1,132,255,255,1,135,255,255,1,138,255,255,1,140,255,255,1,143,255, + 255,1,129,225,255,1,58,98,255,1,29,49,255,1,40,66,255,1,118,191, + 255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255, + 255,1,174,255,255,1,177,255,255,1,180,255,255,1,183,255,255,1,186,255, + 255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255, + 255,1,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255, + 255,1,149,255,255,1,116,194,255,1,46,75,255,1,30,48,255,1,63,101, + 255,1,150,234,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255, + 255,1,177,255,255,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255, + 255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255, + 255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255, + 255,1,152,255,255,1,154,253,255,1,95,154,255,1,37,59,255,1,35,55, + 255,1,100,154,255,1,168,254,255,1,172,255,255,1,174,255,255,1,177,255, + 255,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255, + 255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255, + 255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,152,255, + 255,1,155,255,255,1,157,255,255,1,151,240,255,1,75,118,255,1,32,49, + 255,1,50,76,255,1,141,209,255,1,174,255,255,1,177,255,255,1,180,255, + 255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255, + 255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1,140,255, + 255,1,143,255,255,1,146,255,255,1,149,255,255,1,152,255,255,1,155,255, + 255,1,148,241,255,1,154,246,255,1,163,255,255,1,141,217,255,1,57,86, + 255,1,30,45,255,1,89,131,255,1,177,255,255,1,180,255,255,1,183,255, + 255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255, + 255,1,132,255,255,1,135,255,255,1,138,255,255,1,140,255,255,1,143,255, + 255,1,146,255,255,1,149,255,255,1,152,255,255,1,155,255,255,1,87,137, + 255,1,127,200,255,1,163,255,255,1,163,250,255,1,76,114,255,1,53,78, + 255,1,156,228,255,1,177,255,255,1,180,255,255,1,183,255,255,1,186,255, + 255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255, + 255,1,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255, + 255,1,149,255,255,1,152,255,255,1,136,224,255,1,83,95,255,1,124,183, + 255,1,142,222,255,1,49,75,255,1,111,167,255,1,172,255,255,1,174,255, + 255,1,177,255,255,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255, + 255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255, + 255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255, + 255,1,152,255,255,1,95,137,255,1,140,140,255,1,92,125,255,1,68,107, + 255,1,154,236,255,1,169,255,255,1,172,255,255,1,174,255,255,1,177,255, + 255,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255, + 255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255, + 255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,125,205, + 255,1,131,137,255,1,169,169,255,1,98,104,255,1,70,96,255,1,77,119, + 255,1,112,169,255,1,161,239,255,1,174,255,255,1,177,255,255,1,180,255, + 255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255, + 255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1,140,255, + 255,1,143,255,255,1,146,255,255,1,149,255,255,1,115,148,255,1,171,171, + 255,1,108,108,255,1,49,55,255,1,41,64,255,1,75,115,255,1,111,167, + 255,1,162,240,255,1,174,255,255,1,177,255,255,1,180,255,255,1,183,255, + 255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255, + 255,1,132,255,255,1,135,255,255,1,138,255,255,1,140,255,255,1,143,255, + 255,1,146,255,255,1,109,180,255,1,133,158,255,1,109,153,255,1,107,169, + 255,1,146,233,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255, + 255,1,174,255,255,1,177,255,255,1,180,255,255,1,183,255,255,1,186,255, + 255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255, + 255,1,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255, + 255,1,147,252,255,1,152,255,255,1,155,255,255,1,157,255,255,1,160,255, + 255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255, + 255,1,177,255,255,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255, + 255,1,191,255,255,1,194,255,255,1,197,255,255,1,132,255,255,1,135,255, + 255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255, + 255,1,152,255,255,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255, + 255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,177,255, + 255,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255, + 255,1,194,255,255,1,197,255,255,1,12,0,0,0,255,255,255,255,255,255, + 255,255,255,255,255,66,0,0) + ); + +const + objdata_tsqlite3connection: record size: integer; data: array[0..1006] of byte end = + (size: 1007; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,18,116,115,113, + 108,105,116,101,51,99,111,110,110,101,99,116,105,111,110,12,98,105,116,109, + 97,112,46,105,109,97,103,101,10,184,3,0,0,0,0,0,0,0,0,0, + 0,24,0,0,0,24,0,0,0,132,3,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,255,255,255,17,152,164,126,3,199,201,193,1,220,220,220, + 1,223,223,223,1,255,255,255,15,152,164,126,3,193,200,178,1,200,206,186, + 1,212,217,201,1,219,223,210,1,238,240,234,1,253,253,252,1,217,218,215, + 1,255,255,255,13,252,252,252,1,228,231,222,1,207,212,195,1,221,224,212, + 1,251,252,251,1,254,254,254,2,152,164,126,2,245,246,242,1,255,255,255, + 13,243,244,240,1,215,220,205,1,201,207,188,1,168,178,146,1,210,215,199, + 1,152,164,126,3,249,250,248,1,254,254,254,1,221,225,213,1,255,255,255, + 11,243,245,241,1,152,164,126,1,239,241,236,1,237,239,233,1,205,211,193, + 1,152,164,126,2,231,234,225,1,233,235,227,1,248,249,246,1,252,252,251, + 1,152,164,126,2,255,255,255,9,254,254,254,1,152,164,126,3,253,253,253, + 1,214,219,204,1,203,208,189,1,235,238,231,1,152,164,126,1,233,236,228, + 1,254,254,254,1,230,233,224,1,152,164,126,2,255,255,255,10,152,164,126, + 1,176,185,156,1,152,164,126,1,249,250,248,1,253,253,253,1,222,226,214, + 1,224,228,217,1,249,249,247,1,250,250,248,1,250,251,249,1,152,164,126, + 2,255,255,255,10,252,252,251,1,240,242,237,1,226,229,219,1,194,201,178, + 1,152,164,126,1,254,254,254,1,224,228,216,1,152,164,126,1,221,225,212, + 1,254,254,254,1,246,247,244,1,152,164,126,1,219,223,210,1,255,255,255, + 10,249,250,248,1,201,207,188,1,212,217,202,1,230,233,224,1,204,210,191, + 1,246,247,244,1,207,212,195,1,152,164,126,1,226,229,219,1,254,254,254, + 1,248,249,247,1,218,222,208,1,222,226,214,1,255,255,255,9,254,254,254, + 1,236,238,231,1,208,213,196,1,152,164,126,1,223,226,215,1,239,241,235, + 1,214,219,204,1,200,206,186,1,152,164,126,1,219,223,210,1,234,236,229, + 1,252,252,251,1,234,236,229,1,152,164,126,3,255,255,255,7,238,240,234, + 1,210,215,199,1,152,164,126,3,245,246,243,1,224,228,217,1,197,203,182, + 1,152,164,126,1,224,227,216,1,245,246,242,1,227,230,220,1,152,164,126, + 3,255,255,255,8,254,254,254,1,152,164,126,2,252,252,251,1,152,164,126, + 1,224,228,217,1,219,223,209,1,192,199,176,1,152,164,126,1,224,228,217, + 1,254,254,254,1,246,247,244,1,205,210,192,1,152,164,126,1,200,206,187, + 1,253,253,252,1,255,255,255,9,219,223,210,1,209,214,197,1,252,252,251, + 1,152,164,126,1,216,220,206,1,189,197,173,1,152,164,126,1,225,228,217, + 1,255,255,255,1,238,240,234,1,205,211,193,1,207,212,195,1,249,249,247, + 1,255,255,255,11,253,253,252,1,227,230,220,1,152,164,126,1,205,210,192, + 1,191,199,175,1,152,164,126,1,224,227,216,1,255,255,255,1,251,251,250, + 1,229,232,223,1,212,217,202,1,152,164,126,2,255,255,255,12,251,251,250, + 1,200,206,186,1,152,164,126,2,219,223,210,1,254,254,254,1,247,247,245, + 1,216,220,206,1,152,164,126,3,255,255,255,13,234,236,229,1,152,164,126, + 1,184,192,166,1,209,214,197,1,254,254,254,1,226,229,219,1,152,164,126, + 2,255,255,255,15,246,247,243,1,210,215,199,1,152,164,126,1,198,204,184, + 1,224,227,216,1,152,164,126,2,227,230,220,1,152,164,126,1,255,255,255, + 14,254,254,254,1,213,218,203,1,152,164,126,1,199,205,185,1,234,236,228, + 1,225,228,218,1,222,226,214,1,152,164,126,3,255,255,255,14,221,225,213, + 1,152,164,126,2,218,222,208,1,255,255,255,19,206,207,203,1,216,221,207, + 1,152,164,126,1,201,207,187,1,255,255,255,20,187,192,178,1,152,164,126, + 2,232,235,227,1,255,255,255,20,182,186,171,1,152,164,126,1,216,220,206, + 1,255,255,255,21,176,182,164,1,211,216,200,1,255,255,255,22,191,191,191, + 1,255,255,255,23,0,0) + ); + +const + objdata_tdbslider: record size: integer; data: array[0..1108] of byte end = + (size: 1109; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,100,98, + 115,108,105,100,101,114,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,224,3,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,152,3,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,255,255,255,120,128,128,128,25,0,0,0,22,255, + 255,255,1,128,128,128,1,0,0,0,1,131,255,255,1,255,255,255,1,131, + 255,255,1,240,255,255,1,131,255,255,1,255,255,255,1,131,255,255,1,237, + 255,255,1,134,255,255,1,255,255,255,5,131,255,255,1,248,255,255,1,142, + 255,255,1,244,255,255,1,131,255,255,1,244,255,255,1,225,225,225,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,134,255,255,1,240, + 255,255,1,147,255,255,1,255,255,255,1,131,255,255,1,233,255,255,1,155, + 255,255,1,244,255,255,1,255,255,255,1,227,227,227,3,138,138,138,1,233, + 255,255,1,131,255,255,1,233,255,255,1,148,255,255,1,255,255,255,1,138, + 255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,131, + 255,255,1,255,255,255,1,142,255,255,1,237,255,255,1,142,255,255,1,237, + 255,255,1,151,255,255,1,241,255,255,1,141,255,255,1,255,255,255,1,218, + 218,218,3,129,129,129,1,144,255,255,1,248,255,255,1,141,255,255,1,255, + 255,255,1,131,255,255,1,255,255,255,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,1,131,255,255,1,237,255,255,1,148, + 255,255,1,255,255,255,1,138,255,255,1,255,255,255,1,138,255,255,1,255, + 255,255,2,208,208,208,3,128,128,128,1,255,255,255,1,134,255,255,1,255, + 255,255,1,131,255,255,1,248,255,255,1,139,255,255,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,131,255,255,1,255,255,255,1,138, + 255,255,1,252,255,255,1,135,255,255,1,244,255,255,1,143,255,255,1,240, + 255,255,1,138,255,255,1,255,255,255,1,199,199,199,3,128,128,128,1,131, + 255,255,1,255,255,255,1,131,255,255,1,255,255,255,1,131,255,255,1,240, + 255,255,1,228,228,228,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,1,135,255,255,1,252,255,255,1,131,255,255,1,255,255,255,1,131, + 255,255,1,255,255,255,1,138,255,255,1,233,255,255,1,255,255,255,1,190, + 190,190,3,128,128,128,1,237,255,255,1,142,255,255,1,244,255,255,1,143, + 255,255,1,255,255,255,1,131,255,255,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,131,255,255,1,255,255,255,1,131,255,255,1,244, + 255,255,1,143,255,255,1,255,255,255,1,131,255,255,1,255,255,255,1,138, + 255,255,1,255,255,255,1,180,180,180,3,128,128,128,1,138,255,255,1,244, + 255,255,1,134,255,255,1,236,255,255,1,150,255,255,1,240,255,255,1,228, + 228,228,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,131, + 255,255,1,255,255,255,1,131,255,255,1,255,255,255,1,131,255,255,1,255, + 255,255,1,131,255,255,1,255,255,255,2,171,171,171,3,128,128,128,1,252, + 255,255,1,142,255,255,1,255,255,255,1,131,255,255,1,255,255,255,1,134, + 255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,131, + 255,255,1,255,255,255,1,131,255,255,1,255,255,255,1,134,255,255,1,255, + 255,255,1,134,255,255,1,255,255,255,1,131,255,255,1,255,255,255,1,167, + 167,167,3,128,128,128,1,131,255,255,1,255,255,255,1,131,255,255,1,255, + 255,255,1,131,255,255,1,244,255,255,1,226,226,226,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,1,138,255,255,1,237,255,255,1,131, + 255,255,1,240,255,255,1,142,255,255,1,240,255,255,1,142,255,255,1,240, + 255,255,1,131,131,131,1,128,128,128,4,248,255,255,1,134,255,255,1,248, + 255,255,1,134,255,255,1,255,255,255,1,131,255,255,1,224,224,224,1,255, + 255,255,1,128,128,128,1,224,224,224,3,227,227,227,1,224,224,224,5,227, + 227,227,1,224,224,224,5,225,225,225,1,224,224,224,1,225,225,225,1,224, + 224,224,4,255,255,255,145,16,0,0,0,0,0,0,120,255,255,255,255,255, + 255,255,81,0,0,0,120,0,0) + ); + +const + objdata_tdbprogressbar: record size: integer; data: array[0..453] of byte end = + (size: 454; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,100,98, + 112,114,111,103,114,101,115,115,98,97,114,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,76,1,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,4,1,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,120,128,128,128,25, + 0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,20, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,222,209,14, + 184,255,255,6,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 255,203,183,14,184,255,255,6,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,255,185,157,14,184,255,255,6,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,255,166,131,14,184,255,255,6,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,255,147,105,14,184,255,255,6, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,128,79,14, + 184,255,255,6,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 255,110,53,14,184,255,255,6,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,255,91,26,14,184,255,255,6,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,184,255,255,20,224,224,224,1,255,255,255,1, + 128,128,128,1,224,224,224,22,255,255,255,145,16,0,0,0,0,0,0,120, + 255,255,255,255,255,255,255,81,0,0,0,120,0,0) + ); + +const + objdata_tdbcoloredit: record size: integer; data: array[0..899] of byte end = + (size: 900; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,100,98, + 99,111,108,111,114,101,100,105,116,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,12,3,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,196,2,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,255,255,255,120,128,128,128,25,0,0, + 0,22,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,20,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,17,0,0, + 0,1,184,255,255,1,0,0,0,1,224,224,224,1,255,255,255,1,128,128, + 128,1,0,0,0,1,0,36,255,1,0,111,255,1,0,187,255,1,0,255, + 247,1,0,255,167,1,0,255,87,1,0,255,7,1,68,255,0,1,143,255, + 0,1,218,255,0,1,255,217,0,1,255,142,0,1,255,67,0,1,255,0, + 7,1,255,0,82,1,255,0,156,1,255,0,231,1,198,0,255,1,0,0, + 0,1,39,0,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,0,36,255,1,0,111,255,1,0,187,255,1,0,255,247,1,0,255, + 167,1,0,255,87,1,0,255,7,1,68,255,0,1,143,255,0,1,218,255, + 0,1,255,217,0,1,255,142,0,1,255,67,0,1,255,0,7,1,255,0, + 82,1,255,0,156,1,255,0,231,1,198,0,255,1,0,0,0,1,39,0, + 255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,0,36, + 255,1,0,111,255,1,0,187,255,1,0,255,247,1,0,255,167,1,0,255, + 87,1,0,255,7,1,68,255,0,1,143,255,0,1,218,255,0,1,255,217, + 0,1,255,142,0,1,255,67,0,1,255,0,7,1,255,0,82,1,255,0, + 156,1,255,0,231,1,198,0,255,1,0,0,0,1,39,0,255,1,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,0,36,255,1,0,111, + 255,1,0,187,255,1,0,255,247,1,0,255,167,1,0,255,87,1,0,255, + 7,1,68,255,0,1,143,255,0,1,218,255,0,1,255,217,0,1,255,142, + 0,1,255,67,0,1,255,0,7,1,255,0,82,1,255,0,156,1,255,0, + 231,1,198,0,255,1,0,0,0,1,39,0,255,1,224,224,224,1,255,255, + 255,1,128,128,128,1,0,0,0,1,0,36,255,1,0,111,255,1,0,187, + 255,1,0,255,247,1,0,255,167,1,0,255,87,1,0,255,7,1,68,255, + 0,1,143,255,0,1,218,255,0,1,255,217,0,1,255,142,0,1,255,67, + 0,1,255,0,7,1,255,0,82,1,255,0,156,1,255,0,231,1,198,0, + 255,1,0,0,0,1,39,0,255,1,224,224,224,1,255,255,255,1,128,128, + 128,1,0,0,0,1,0,36,255,1,0,111,255,1,0,187,255,1,0,255, + 247,1,0,255,167,1,0,255,87,1,0,255,7,1,68,255,0,1,143,255, + 0,1,218,255,0,1,255,217,0,1,255,142,0,1,255,67,0,1,255,0, + 7,1,255,0,82,1,255,0,156,1,255,0,231,1,198,0,255,1,0,0, + 0,1,39,0,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,184,255,255,17,0,0,0,1,184,255,255,1,0,0,0,1,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,184,255,255,20,224,224, + 224,1,255,255,255,1,128,128,128,1,224,224,224,22,255,255,255,145,16,0, + 0,0,0,0,0,120,255,255,255,255,255,255,255,81,0,0,0,120,0,0) + ); + +const + objdata_tsqlstatement: record size: integer; data: array[0..2472] of byte end = + (size: 2473; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,115,113, + 108,115,116,97,116,101,109,101,110,116,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,48,9,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,236,8,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,132,219,255,1,135,220,255,1,138, + 221,255,1,141,222,255,1,144,223,255,1,147,224,255,1,149,224,255,1,152, + 225,255,1,155,226,255,1,158,227,255,1,161,228,255,1,164,229,255,1,166, + 229,255,1,169,230,255,1,172,231,255,1,175,232,255,1,178,233,255,1,181, + 234,255,1,183,234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195, + 238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,138,221,255,1,141, + 222,255,1,144,223,255,1,147,224,255,1,149,224,255,1,152,225,255,1,155, + 226,255,1,158,227,255,1,161,228,255,1,164,229,255,1,166,229,255,1,169, + 230,255,1,172,231,255,1,175,232,255,1,178,233,255,1,181,234,255,1,183, + 234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198, + 239,255,1,132,219,255,1,135,220,255,1,138,221,255,1,141,222,255,1,144, + 223,255,1,147,224,255,1,149,224,255,1,152,225,255,1,155,226,255,1,158, + 227,255,1,161,228,255,1,164,229,255,1,166,229,255,1,169,230,255,1,172, + 231,255,1,175,232,255,1,178,233,255,1,181,234,255,1,183,234,255,1,186, + 235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132, + 219,255,1,135,220,255,1,97,155,179,1,20,31,36,1,3,4,5,1,27, + 40,46,1,113,170,193,1,152,225,255,1,155,226,255,1,155,223,250,1,73, + 103,115,1,12,16,18,2,76,103,114,1,169,226,250,1,175,232,255,1,178, + 233,255,1,0,0,0,1,183,234,255,1,186,235,255,1,189,236,255,1,192, + 237,255,1,195,238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,11, + 18,21,1,103,163,187,1,141,218,249,1,101,155,176,1,18,26,30,1,152, + 225,255,1,155,226,255,1,80,115,129,1,80,114,127,1,157,219,244,1,154, + 212,236,1,89,121,134,1,84,112,124,1,175,232,255,1,178,233,255,1,0, + 0,0,1,183,234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195, + 238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,25,40,46,1,84, + 132,152,1,136,210,240,1,147,224,255,1,149,224,255,1,152,225,255,1,155, + 226,255,1,20,29,33,1,149,211,236,1,164,229,255,1,166,229,255,1,169, + 230,255,1,20,26,29,1,175,232,255,1,178,233,255,1,0,0,0,1,183, + 234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198, + 239,255,1,132,219,255,1,135,220,255,1,127,203,234,1,69,108,124,1,30, + 47,54,1,33,51,58,1,115,172,196,1,152,225,255,1,155,226,255,1,3, + 4,5,1,160,226,253,1,164,229,255,1,166,229,255,1,168,228,253,1,4, + 5,6,1,175,232,255,1,178,233,255,1,0,0,0,1,183,234,255,1,186, + 235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132, + 219,255,1,135,220,255,1,138,221,255,1,141,222,255,1,144,223,255,1,123, + 188,214,1,15,23,26,1,152,225,255,1,155,226,255,1,19,28,31,1,148, + 210,235,1,164,229,255,1,130,180,200,1,143,195,216,1,30,41,45,1,175, + 232,255,1,178,233,255,1,0,0,0,1,183,234,255,1,186,235,255,1,189, + 236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132,219,255,1,135, + 220,255,1,16,25,29,1,96,151,174,1,141,219,250,1,117,178,203,1,16, + 24,27,1,152,225,255,1,155,226,255,1,78,112,126,1,79,112,125,1,157, + 219,244,1,48,66,73,1,30,41,46,1,119,160,177,1,175,232,255,1,178, + 233,255,1,0,0,0,1,183,234,255,1,186,235,255,1,189,236,255,1,192, + 237,255,1,195,238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,103, + 166,191,1,25,39,45,1,3,4,5,1,21,33,37,1,110,165,188,1,152, + 225,255,1,155,226,255,1,155,223,250,1,69,98,110,1,10,13,15,1,13, + 18,20,1,38,52,58,1,42,57,63,1,175,232,255,1,178,233,255,1,0, + 0,0,5,195,238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,138, + 221,255,1,141,222,255,1,144,223,255,1,147,224,255,1,149,224,255,1,152, + 225,255,1,155,226,255,1,158,227,255,1,161,228,255,1,164,229,255,1,166, + 229,255,1,169,230,255,1,135,181,200,1,175,232,255,1,178,233,255,1,181, + 234,255,1,183,234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195, + 238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,138,221,255,1,141, + 222,255,1,144,223,255,1,147,224,255,1,149,224,255,1,152,225,255,1,155, + 226,255,1,158,227,255,1,161,228,255,1,164,229,255,1,166,229,255,1,169, + 230,255,1,172,231,255,1,175,232,255,1,178,233,255,1,181,234,255,1,183, + 234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198, + 239,255,1,132,219,255,1,135,220,255,1,138,221,255,1,141,222,255,1,144, + 223,255,1,147,224,255,1,149,224,255,1,152,225,255,1,155,226,255,1,158, + 227,255,1,161,228,255,1,164,229,255,1,166,229,255,1,169,230,255,1,172, + 231,255,1,175,232,255,1,178,233,255,1,181,234,255,1,183,234,255,1,186, + 235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132, + 219,255,1,135,220,255,1,138,221,255,1,141,222,255,1,144,223,255,1,147, + 224,255,1,149,224,255,1,152,225,255,1,155,226,255,1,158,227,255,1,161, + 228,255,1,0,0,0,1,166,229,255,1,169,230,255,1,172,231,255,1,175, + 232,255,1,178,233,255,1,181,234,255,1,183,234,255,1,186,235,255,1,189, + 236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132,219,255,1,135, + 220,255,1,138,221,255,1,141,222,255,1,144,223,255,1,147,224,255,1,149, + 224,255,1,152,225,255,1,155,226,255,1,158,227,255,1,161,228,255,1,0, + 0,0,1,166,229,255,1,169,230,255,1,172,231,255,1,175,232,255,1,178, + 233,255,1,181,234,255,1,183,234,255,1,186,235,255,1,189,236,255,1,192, + 237,255,1,195,238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,138, + 221,255,1,141,222,255,1,144,223,255,1,147,224,255,1,149,224,255,1,152, + 225,255,1,155,226,255,1,158,227,255,1,161,228,255,1,0,0,0,1,166, + 229,255,1,169,230,255,1,172,231,255,1,175,232,255,1,178,233,255,1,181, + 234,255,1,183,234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195, + 238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,138,221,255,1,141, + 222,255,1,144,223,255,1,147,224,255,1,149,224,255,1,152,225,255,1,155, + 226,255,1,158,227,255,1,161,228,255,1,0,0,0,1,166,229,255,1,169, + 230,255,1,172,231,255,1,175,232,255,1,178,233,255,1,181,234,255,1,183, + 234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198, + 239,255,1,132,219,255,1,135,220,255,1,138,221,255,1,141,222,255,1,144, + 223,255,1,147,224,255,1,149,224,255,1,152,225,255,1,155,226,255,1,158, + 227,255,1,161,228,255,1,0,0,0,1,166,229,255,1,169,230,255,1,172, + 231,255,1,175,232,255,1,178,233,255,1,181,234,255,1,183,234,255,1,186, + 235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132, + 219,255,1,135,220,255,1,138,221,255,1,141,222,255,1,144,223,255,1,147, + 224,255,1,149,224,255,1,152,225,255,1,155,226,255,1,158,227,255,1,161, + 228,255,1,164,229,255,1,166,229,255,1,169,230,255,1,172,231,255,1,175, + 232,255,1,178,233,255,1,181,234,255,1,183,234,255,1,186,235,255,1,189, + 236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132,219,255,1,135, + 220,255,1,138,221,255,1,141,222,255,1,144,223,255,1,147,224,255,1,149, + 224,255,1,152,225,255,1,155,226,255,1,158,227,255,1,161,228,255,1,0, + 0,0,1,166,229,255,1,169,230,255,1,172,231,255,1,175,232,255,1,178, + 233,255,1,181,234,255,1,183,234,255,1,186,235,255,1,189,236,255,1,192, + 237,255,1,195,238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,138, + 221,255,1,141,222,255,1,144,223,255,1,147,224,255,1,149,224,255,1,152, + 225,255,1,155,226,255,1,158,227,255,1,161,228,255,1,164,229,255,1,166, + 229,255,1,169,230,255,1,172,231,255,1,175,232,255,1,178,233,255,1,181, + 234,255,1,183,234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195, + 238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,138,221,255,1,141, + 222,255,1,144,223,255,1,147,224,255,1,149,224,255,1,152,225,255,1,155, + 226,255,1,158,227,255,1,161,228,255,1,164,229,255,1,166,229,255,1,169, + 230,255,1,172,231,255,1,175,232,255,1,178,233,255,1,181,234,255,1,183, + 234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198, + 239,255,1,132,219,255,1,135,220,255,1,138,221,255,1,141,222,255,1,144, + 223,255,1,147,224,255,1,149,224,255,1,152,225,255,1,155,226,255,1,158, + 227,255,1,161,228,255,1,164,229,255,1,166,229,255,1,169,230,255,1,172, + 231,255,1,175,232,255,1,178,233,255,1,181,234,255,1,183,234,255,1,186, + 235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132, + 219,255,1,135,220,255,1,138,221,255,1,141,222,255,1,144,223,255,1,147, + 224,255,1,149,224,255,1,152,225,255,1,155,226,255,1,158,227,255,1,161, + 228,255,1,164,229,255,1,166,229,255,1,169,230,255,1,172,231,255,1,175, + 232,255,1,178,233,255,1,181,234,255,1,183,234,255,1,186,235,255,1,189, + 236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,12,0,0,0,255, + 255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tmsesqlscript: record size: integer; data: array[0..2472] of byte end = + (size: 2473; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,109,115, + 101,115,113,108,115,99,114,105,112,116,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,48,9,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,236,8,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,132,219,255,1,135,220,255,1,138, + 221,255,1,141,222,255,1,144,223,255,1,147,224,255,1,149,224,255,1,152, + 225,255,1,155,226,255,1,158,227,255,1,161,228,255,1,164,229,255,1,166, + 229,255,1,169,230,255,1,172,231,255,1,175,232,255,1,178,233,255,1,181, + 234,255,1,183,234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195, + 238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,138,221,255,1,141, + 222,255,1,144,223,255,1,147,224,255,1,149,224,255,1,152,225,255,1,155, + 226,255,1,158,227,255,1,161,228,255,1,164,229,255,1,166,229,255,1,169, + 230,255,1,172,231,255,1,175,232,255,1,178,233,255,1,181,234,255,1,183, + 234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198, + 239,255,1,132,219,255,1,135,220,255,1,138,221,255,1,141,222,255,1,144, + 223,255,1,147,224,255,1,149,224,255,1,152,225,255,1,155,226,255,1,158, + 227,255,1,161,228,255,1,164,229,255,1,166,229,255,1,169,230,255,1,172, + 231,255,1,175,232,255,1,178,233,255,1,181,234,255,1,183,234,255,1,186, + 235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132, + 219,255,1,135,220,255,1,97,155,179,1,20,31,36,1,3,4,5,1,27, + 40,46,1,113,170,193,1,152,225,255,1,155,226,255,1,155,223,250,1,73, + 103,115,1,12,16,18,2,76,103,114,1,169,226,250,1,175,232,255,1,178, + 233,255,1,0,0,0,1,183,234,255,1,186,235,255,1,189,236,255,1,192, + 237,255,1,195,238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,11, + 18,21,1,103,163,187,1,141,218,249,1,101,155,176,1,18,26,30,1,152, + 225,255,1,155,226,255,1,80,115,129,1,80,114,127,1,157,219,244,1,154, + 212,236,1,89,121,134,1,84,112,124,1,175,232,255,1,178,233,255,1,0, + 0,0,1,183,234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195, + 238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,25,40,46,1,84, + 132,152,1,136,210,240,1,147,224,255,1,149,224,255,1,152,225,255,1,155, + 226,255,1,20,29,33,1,149,211,236,1,164,229,255,1,166,229,255,1,169, + 230,255,1,20,26,29,1,175,232,255,1,178,233,255,1,0,0,0,1,183, + 234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198, + 239,255,1,132,219,255,1,135,220,255,1,127,203,234,1,69,108,124,1,30, + 47,54,1,33,51,58,1,115,172,196,1,152,225,255,1,155,226,255,1,3, + 4,5,1,160,226,253,1,164,229,255,1,166,229,255,1,168,228,253,1,4, + 5,6,1,175,232,255,1,178,233,255,1,0,0,0,1,183,234,255,1,186, + 235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132, + 219,255,1,135,220,255,1,138,221,255,1,141,222,255,1,144,223,255,1,123, + 188,214,1,15,23,26,1,152,225,255,1,155,226,255,1,19,28,31,1,148, + 210,235,1,164,229,255,1,130,180,200,1,143,195,216,1,30,41,45,1,175, + 232,255,1,178,233,255,1,0,0,0,1,183,234,255,1,186,235,255,1,189, + 236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132,219,255,1,135, + 220,255,1,16,25,29,1,96,151,174,1,141,219,250,1,117,178,203,1,16, + 24,27,1,152,225,255,1,155,226,255,1,78,112,126,1,79,112,125,1,157, + 219,244,1,48,66,73,1,30,41,46,1,119,160,177,1,175,232,255,1,178, + 233,255,1,0,0,0,1,183,234,255,1,186,235,255,1,189,236,255,1,192, + 237,255,1,195,238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,103, + 166,191,1,25,39,45,1,3,4,5,1,21,33,37,1,110,165,188,1,152, + 225,255,1,155,226,255,1,155,223,250,1,69,98,110,1,10,13,15,1,13, + 18,20,1,38,52,58,1,42,57,63,1,175,232,255,1,178,233,255,1,0, + 0,0,5,195,238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,138, + 221,255,1,141,222,255,1,144,223,255,1,147,224,255,1,149,224,255,1,152, + 225,255,1,155,226,255,1,158,227,255,1,161,228,255,1,164,229,255,1,166, + 229,255,1,169,230,255,1,135,181,200,1,175,232,255,1,178,233,255,1,181, + 234,255,1,183,234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195, + 238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,138,221,255,1,141, + 222,255,1,144,223,255,1,147,224,255,1,149,224,255,1,152,225,255,1,155, + 226,255,1,158,227,255,1,161,228,255,1,164,229,255,1,166,229,255,1,169, + 230,255,1,172,231,255,1,175,232,255,1,178,233,255,1,181,234,255,1,183, + 234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198, + 239,255,1,132,219,255,1,135,220,255,1,138,221,255,1,141,222,255,1,144, + 223,255,1,147,224,255,1,149,224,255,1,152,225,255,1,155,226,255,1,158, + 227,255,1,161,228,255,1,164,229,255,1,166,229,255,1,169,230,255,1,172, + 231,255,1,175,232,255,1,178,233,255,1,181,234,255,1,183,234,255,1,186, + 235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132, + 219,255,1,135,220,255,1,138,221,255,1,141,222,255,1,144,223,255,1,147, + 224,255,1,149,224,255,1,152,225,255,1,0,0,0,1,158,227,255,1,161, + 228,255,1,0,0,0,1,166,229,255,1,169,230,255,1,0,0,0,1,175, + 232,255,1,178,233,255,1,181,234,255,1,183,234,255,1,186,235,255,1,189, + 236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132,219,255,1,135, + 220,255,1,138,221,255,1,141,222,255,1,144,223,255,1,147,224,255,1,149, + 224,255,1,152,225,255,1,0,0,0,1,158,227,255,1,161,228,255,1,0, + 0,0,1,166,229,255,1,169,230,255,1,0,0,0,1,175,232,255,1,178, + 233,255,1,181,234,255,1,183,234,255,1,186,235,255,1,189,236,255,1,192, + 237,255,1,195,238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,138, + 221,255,1,141,222,255,1,144,223,255,1,147,224,255,1,149,224,255,1,152, + 225,255,1,0,0,0,1,158,227,255,1,161,228,255,1,0,0,0,1,166, + 229,255,1,169,230,255,1,0,0,0,1,175,232,255,1,178,233,255,1,181, + 234,255,1,183,234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195, + 238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,138,221,255,1,141, + 222,255,1,144,223,255,1,147,224,255,1,149,224,255,1,152,225,255,1,0, + 0,0,1,158,227,255,1,161,228,255,1,0,0,0,1,166,229,255,1,169, + 230,255,1,0,0,0,1,175,232,255,1,178,233,255,1,181,234,255,1,183, + 234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198, + 239,255,1,132,219,255,1,135,220,255,1,138,221,255,1,141,222,255,1,144, + 223,255,1,147,224,255,1,149,224,255,1,152,225,255,1,0,0,0,1,158, + 227,255,1,161,228,255,1,0,0,0,1,166,229,255,1,169,230,255,1,0, + 0,0,1,175,232,255,1,178,233,255,1,181,234,255,1,183,234,255,1,186, + 235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132, + 219,255,1,135,220,255,1,138,221,255,1,141,222,255,1,144,223,255,1,147, + 224,255,1,149,224,255,1,152,225,255,1,155,226,255,1,158,227,255,1,161, + 228,255,1,164,229,255,1,166,229,255,1,169,230,255,1,172,231,255,1,175, + 232,255,1,178,233,255,1,181,234,255,1,183,234,255,1,186,235,255,1,189, + 236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132,219,255,1,135, + 220,255,1,138,221,255,1,141,222,255,1,144,223,255,1,147,224,255,1,149, + 224,255,1,152,225,255,1,0,0,0,1,158,227,255,1,161,228,255,1,0, + 0,0,1,166,229,255,1,169,230,255,1,0,0,0,1,175,232,255,1,178, + 233,255,1,181,234,255,1,183,234,255,1,186,235,255,1,189,236,255,1,192, + 237,255,1,195,238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,138, + 221,255,1,141,222,255,1,144,223,255,1,147,224,255,1,149,224,255,1,152, + 225,255,1,155,226,255,1,158,227,255,1,161,228,255,1,164,229,255,1,166, + 229,255,1,169,230,255,1,172,231,255,1,175,232,255,1,178,233,255,1,181, + 234,255,1,183,234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195, + 238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,138,221,255,1,141, + 222,255,1,144,223,255,1,147,224,255,1,149,224,255,1,152,225,255,1,155, + 226,255,1,158,227,255,1,161,228,255,1,164,229,255,1,166,229,255,1,169, + 230,255,1,172,231,255,1,175,232,255,1,178,233,255,1,181,234,255,1,183, + 234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198, + 239,255,1,132,219,255,1,135,220,255,1,138,221,255,1,141,222,255,1,144, + 223,255,1,147,224,255,1,149,224,255,1,152,225,255,1,155,226,255,1,158, + 227,255,1,161,228,255,1,164,229,255,1,166,229,255,1,169,230,255,1,172, + 231,255,1,175,232,255,1,178,233,255,1,181,234,255,1,183,234,255,1,186, + 235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132, + 219,255,1,135,220,255,1,138,221,255,1,141,222,255,1,144,223,255,1,147, + 224,255,1,149,224,255,1,152,225,255,1,155,226,255,1,158,227,255,1,161, + 228,255,1,164,229,255,1,166,229,255,1,169,230,255,1,172,231,255,1,175, + 232,255,1,178,233,255,1,181,234,255,1,183,234,255,1,186,235,255,1,189, + 236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,12,0,0,0,255, + 255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tsqlresult: record size: integer; data: array[0..2469] of byte end = + (size: 2470; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,115,113, + 108,114,101,115,117,108,116,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,48,9,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,236,8,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,132,219,255,1,135,220,255,1,138,221,255,1, + 141,222,255,1,144,223,255,1,147,224,255,1,149,224,255,1,152,225,255,1, + 155,226,255,1,158,227,255,1,161,228,255,1,164,229,255,1,166,229,255,1, + 169,230,255,1,172,231,255,1,175,232,255,1,178,233,255,1,181,234,255,1, + 183,234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195,238,255,1, + 198,239,255,1,132,219,255,1,135,220,255,1,138,221,255,1,141,222,255,1, + 144,223,255,1,147,224,255,1,149,224,255,1,152,225,255,1,155,226,255,1, + 158,227,255,1,161,228,255,1,164,229,255,1,166,229,255,1,169,230,255,1, + 172,231,255,1,175,232,255,1,178,233,255,1,181,234,255,1,183,234,255,1, + 186,235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198,239,255,1, + 132,219,255,1,135,220,255,1,138,221,255,1,141,222,255,1,144,223,255,1, + 147,224,255,1,149,224,255,1,152,225,255,1,155,226,255,1,158,227,255,1, + 161,228,255,1,164,229,255,1,166,229,255,1,169,230,255,1,172,231,255,1, + 175,232,255,1,178,233,255,1,181,234,255,1,183,234,255,1,186,235,255,1, + 189,236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132,219,255,1, + 135,220,255,1,97,155,179,1,20,31,36,1,3,4,5,1,27,40,46,1, + 113,170,193,1,152,225,255,1,155,226,255,1,155,223,250,1,73,103,115,1, + 12,16,18,2,76,103,114,1,169,226,250,1,175,232,255,1,178,233,255,1, + 0,0,0,1,183,234,255,1,186,235,255,1,189,236,255,1,192,237,255,1, + 195,238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,11,18,21,1, + 103,163,187,1,141,218,249,1,101,155,176,1,18,26,30,1,152,225,255,1, + 155,226,255,1,80,115,129,1,80,114,127,1,157,219,244,1,154,212,236,1, + 89,121,134,1,84,112,124,1,175,232,255,1,178,233,255,1,0,0,0,1, + 183,234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195,238,255,1, + 198,239,255,1,132,219,255,1,135,220,255,1,25,40,46,1,84,132,152,1, + 136,210,240,1,147,224,255,1,149,224,255,1,152,225,255,1,155,226,255,1, + 20,29,33,1,149,211,236,1,164,229,255,1,166,229,255,1,169,230,255,1, + 20,26,29,1,175,232,255,1,178,233,255,1,0,0,0,1,183,234,255,1, + 186,235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198,239,255,1, + 132,219,255,1,135,220,255,1,127,203,234,1,69,108,124,1,30,47,54,1, + 33,51,58,1,115,172,196,1,152,225,255,1,155,226,255,1,3,4,5,1, + 160,226,253,1,164,229,255,1,166,229,255,1,168,228,253,1,4,5,6,1, + 175,232,255,1,178,233,255,1,0,0,0,1,183,234,255,1,186,235,255,1, + 189,236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132,219,255,1, + 135,220,255,1,138,221,255,1,141,222,255,1,144,223,255,1,123,188,214,1, + 15,23,26,1,152,225,255,1,155,226,255,1,19,28,31,1,148,210,235,1, + 164,229,255,1,130,180,200,1,143,195,216,1,30,41,45,1,175,232,255,1, + 178,233,255,1,0,0,0,1,183,234,255,1,186,235,255,1,189,236,255,1, + 192,237,255,1,195,238,255,1,198,239,255,1,132,219,255,1,135,220,255,1, + 16,25,29,1,96,151,174,1,141,219,250,1,117,178,203,1,16,24,27,1, + 152,225,255,1,155,226,255,1,78,112,126,1,79,112,125,1,157,219,244,1, + 48,66,73,1,30,41,46,1,119,160,177,1,175,232,255,1,178,233,255,1, + 0,0,0,1,183,234,255,1,186,235,255,1,189,236,255,1,192,237,255,1, + 195,238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,103,166,191,1, + 25,39,45,1,3,4,5,1,21,33,37,1,110,165,188,1,152,225,255,1, + 155,226,255,1,155,223,250,1,69,98,110,1,10,13,15,1,13,18,20,1, + 38,52,58,1,42,57,63,1,175,232,255,1,178,233,255,1,0,0,0,5, + 195,238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,138,221,255,1, + 141,222,255,1,144,223,255,1,147,224,255,1,149,224,255,1,152,225,255,1, + 155,226,255,1,158,227,255,1,161,228,255,1,164,229,255,1,166,229,255,1, + 169,230,255,1,135,181,200,1,175,232,255,1,178,233,255,1,181,234,255,1, + 183,234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195,238,255,1, + 198,239,255,1,132,219,255,1,135,220,255,1,138,221,255,1,141,222,255,1, + 144,223,255,1,147,224,255,1,149,224,255,1,152,225,255,1,155,226,255,1, + 158,227,255,1,161,228,255,1,164,229,255,1,166,229,255,1,169,230,255,1, + 172,231,255,1,175,232,255,1,178,233,255,1,181,234,255,1,183,234,255,1, + 186,235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198,239,255,1, + 132,219,255,1,135,220,255,1,138,221,255,1,141,222,255,1,144,223,255,1, + 147,224,255,1,149,224,255,1,152,225,255,1,155,226,255,1,158,227,255,1, + 161,228,255,1,164,229,255,1,166,229,255,1,169,230,255,1,172,231,255,1, + 175,232,255,1,178,233,255,1,181,234,255,1,183,234,255,1,186,235,255,1, + 189,236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132,219,255,1, + 135,220,255,1,138,221,255,1,138,217,249,1,142,220,251,1,143,218,248,1, + 147,221,252,1,151,223,253,1,153,223,252,1,132,190,213,1,42,59,66,1, + 6,9,10,1,5,7,8,1,38,52,58,1,134,180,199,1,163,217,238,1, + 175,228,250,1,180,233,254,1,182,233,254,1,185,233,253,1,189,236,255,1, + 192,237,255,1,195,238,255,1,198,239,255,1,132,219,255,1,135,220,255,1, + 138,221,255,1,139,219,251,1,139,216,247,1,140,213,242,1,145,219,249,1, + 152,225,255,1,149,217,245,1,26,37,42,1,90,127,142,1,155,216,241,1, + 158,217,242,1,103,141,156,1,13,18,20,1,167,221,243,1,176,230,252,1, + 177,229,250,1,177,226,246,1,175,221,240,1,188,234,253,1,192,237,255,1, + 195,238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,138,221,255,1, + 141,222,255,1,144,223,255,1,147,224,255,1,149,224,255,1,151,223,253,1, + 148,215,243,1,158,227,255,1,161,228,255,1,164,229,255,1,166,229,255,1, + 109,148,164,1,41,55,61,1,175,232,255,1,178,233,255,1,181,234,255,1, + 183,234,255,1,177,224,243,1,185,231,250,1,192,237,255,1,195,238,255,1, + 198,239,255,1,132,219,255,1,135,220,255,1,138,221,255,1,141,222,255,1, + 144,223,255,1,147,224,255,1,148,223,254,1,151,224,254,1,154,224,253,1, + 158,227,255,1,161,228,255,1,164,229,255,1,89,122,136,1,45,61,68,1, + 161,216,238,1,175,232,255,1,178,233,255,1,181,234,255,1,182,233,254,1, + 179,226,245,1,182,227,245,1,192,237,255,1,195,238,255,1,198,239,255,1, + 132,219,255,1,135,220,255,1,138,221,255,1,141,222,255,1,144,223,255,1, + 147,224,255,1,148,223,254,1,147,218,247,1,155,226,255,1,158,227,255,1, + 161,228,255,1,164,229,255,1,5,7,8,1,159,216,240,1,172,231,255,1, + 175,232,255,1,178,233,255,1,181,234,255,1,177,226,246,1,177,224,243,1, + 189,236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132,219,255,1, + 135,220,255,1,138,221,255,1,141,222,255,1,144,223,255,1,147,224,255,1, + 149,224,255,1,152,225,255,1,155,226,255,1,158,227,255,1,161,228,255,1, + 164,229,255,1,166,229,255,1,169,230,255,1,172,231,255,1,175,232,255,1, + 178,233,255,1,181,234,255,1,183,234,255,1,186,235,255,1,189,236,255,1, + 192,237,255,1,195,238,255,1,198,239,255,1,132,219,255,1,135,220,255,1, + 138,221,255,1,141,222,255,1,144,223,255,1,147,224,255,1,147,220,251,1, + 152,225,255,1,155,226,255,1,158,227,255,1,161,228,255,1,164,229,255,1, + 0,0,0,1,169,230,255,1,172,231,255,1,175,232,255,1,178,233,255,1, + 181,234,255,1,182,232,253,1,186,235,255,1,189,236,255,1,192,237,255,1, + 195,238,255,1,198,239,255,1,132,219,255,1,135,220,255,1,138,221,255,1, + 141,222,255,1,144,223,255,1,147,224,255,1,149,224,255,1,152,225,255,1, + 155,226,255,1,158,227,255,1,161,228,255,1,164,229,255,1,166,229,255,1, + 169,230,255,1,172,231,255,1,175,232,255,1,178,233,255,1,181,234,255,1, + 183,234,255,1,186,235,255,1,189,236,255,1,192,237,255,1,195,238,255,1, + 198,239,255,1,132,219,255,1,135,220,255,1,138,221,255,1,141,222,255,1, + 144,223,255,1,147,224,255,1,149,224,255,1,152,225,255,1,155,226,255,1, + 158,227,255,1,161,228,255,1,164,229,255,1,166,229,255,1,169,230,255,1, + 172,231,255,1,175,232,255,1,178,233,255,1,181,234,255,1,183,234,255,1, + 186,235,255,1,189,236,255,1,192,237,255,1,195,238,255,1,198,239,255,1, + 132,219,255,1,135,220,255,1,138,221,255,1,141,222,255,1,144,223,255,1, + 147,224,255,1,149,224,255,1,152,225,255,1,155,226,255,1,158,227,255,1, + 161,228,255,1,164,229,255,1,166,229,255,1,169,230,255,1,172,231,255,1, + 175,232,255,1,178,233,255,1,181,234,255,1,183,234,255,1,186,235,255,1, + 189,236,255,1,192,237,255,1,195,238,255,1,198,239,255,1,132,219,255,1, + 135,220,255,1,138,221,255,1,141,222,255,1,144,223,255,1,147,224,255,1, + 149,224,255,1,152,225,255,1,155,226,255,1,158,227,255,1,161,228,255,1, + 164,229,255,1,166,229,255,1,169,230,255,1,172,231,255,1,175,232,255,1, + 178,233,255,1,181,234,255,1,183,234,255,1,186,235,255,1,189,236,255,1, + 192,237,255,1,195,238,255,1,198,239,255,1,12,0,0,0,255,255,255,255, + 255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tsqllookupbuffer: record size: integer; data: array[0..1215] of byte end = + (size: 1216; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,115,113, + 108,108,111,111,107,117,112,98,117,102,102,101,114,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,68,4, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,36,3, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,255, + 0,2,0,0,0,2,0,255,0,2,0,0,0,2,0,255,0,2,0,0, + 0,2,0,255,0,2,0,0,0,2,0,255,0,2,0,0,0,2,0,255, + 0,2,0,0,0,2,190,190,255,11,190,223,255,11,0,0,0,1,0,255, + 0,1,190,190,255,11,190,223,255,1,0,0,0,3,190,223,255,1,0,0, + 0,5,190,223,255,1,0,255,0,2,190,190,255,11,190,223,255,11,0,255, + 0,1,0,0,0,1,190,190,255,9,0,0,255,1,190,190,255,1,190,223, + 255,1,0,0,0,3,190,223,255,1,0,0,0,2,190,223,255,4,0,0, + 0,2,190,190,255,9,0,0,255,2,190,223,255,11,0,0,0,1,0,255, + 0,1,190,190,255,8,0,0,255,4,0,0,0,3,190,223,255,1,0,0, + 0,3,190,223,255,3,0,255,0,2,190,190,255,7,0,0,255,1,190,190, + 255,1,0,0,255,2,190,223,255,11,0,255,0,1,0,0,0,1,190,190, + 255,7,0,0,255,1,190,190,255,1,0,0,255,1,190,190,255,1,190,223, + 255,1,0,0,0,3,190,223,255,1,0,0,0,4,190,223,255,2,0,0, + 0,2,190,190,255,7,0,0,255,1,190,190,255,3,190,223,255,11,0,0, + 0,1,0,255,0,1,190,190,255,7,0,0,255,1,190,190,255,3,190,223, + 255,1,0,0,0,3,190,223,255,1,0,0,0,2,190,223,255,4,0,255, + 0,2,190,190,255,7,0,0,255,1,190,190,255,3,190,223,255,11,0,255, + 0,1,0,0,0,1,190,190,255,7,0,0,255,1,190,190,255,3,190,223, + 255,11,0,0,0,2,190,190,255,1,0,0,0,3,190,190,255,3,0,0, + 255,1,190,190,255,3,110,148,148,1,46,62,62,1,32,43,43,1,124,167, + 167,1,190,223,255,2,110,148,148,1,46,62,62,1,32,43,43,1,124,167, + 167,1,190,223,255,1,0,0,0,1,0,255,0,1,190,190,255,7,0,0, + 255,1,190,190,255,3,190,223,255,2,177,232,238,1,29,39,39,1,190,223, + 255,4,177,232,238,1,29,39,39,1,190,223,255,1,0,255,0,2,190,190, + 255,1,0,0,0,3,190,190,255,3,0,0,255,1,190,190,255,3,190,223, + 255,2,165,222,222,1,46,62,62,1,190,223,255,4,165,222,222,1,46,62, + 62,1,190,223,255,1,0,255,0,1,0,0,0,1,190,190,255,7,0,0, + 255,1,190,190,255,3,190,223,255,1,163,219,219,1,35,47,47,1,158,212, + 212,1,190,223,255,3,163,219,219,1,35,47,47,1,158,212,212,1,190,223, + 255,1,0,0,0,2,190,190,255,1,0,0,0,3,190,190,255,1,0,0, + 255,2,190,190,255,4,190,223,255,1,57,76,76,1,171,229,229,1,190,223, + 255,4,57,76,76,1,171,229,229,1,190,223,255,2,0,0,0,1,0,255, + 0,1,190,190,255,11,190,223,255,1,71,95,95,1,190,223,255,5,71,95, + 95,1,190,223,255,3,0,255,0,2,190,190,255,1,0,0,0,3,190,190, + 255,7,190,223,255,11,0,255,0,1,0,0,0,1,190,190,255,11,190,223, + 255,1,59,79,79,1,190,223,255,5,59,79,79,1,190,223,255,3,0,0, + 0,2,190,190,255,11,190,223,255,11,0,0,0,1,0,255,0,1,190,190, + 255,11,190,223,255,11,0,255,0,2,0,0,0,2,0,255,0,2,0,0, + 0,2,0,255,0,2,0,0,0,2,0,255,0,2,0,0,0,2,0,255, + 0,2,0,0,0,2,0,255,0,2,0,0,0,2,0,255,0,1,232,0, + 0,0,0,0,0,1,255,255,255,2,0,0,0,2,255,255,255,2,0,0, + 0,2,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0,2,255,255, + 255,2,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,22,0,0, + 0,1,255,255,255,48,0,0,0,1,255,255,255,22,0,0,0,2,255,255, + 255,22,0,0,0,1,255,255,255,48,0,0,0,1,255,255,255,22,0,0, + 0,2,255,255,255,22,0,0,0,1,255,255,255,48,0,0,0,1,255,255, + 255,22,0,0,0,2,255,255,255,22,0,0,0,1,255,255,255,48,0,0, + 0,1,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,1,255,255, + 255,48,0,0,0,1,255,255,255,22,0,0,0,2,255,255,255,22,0,0, + 0,1,255,255,255,25,0,0,0,2,255,255,255,2,0,0,0,2,255,255, + 255,2,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,2,0,0, + 0,2,255,255,255,2,0,0,0,2,255,255,255,1,0,0) + ); + +const + objdata_tmsedatasource: record size: integer; data: array[0..1841] of byte end = + (size: 1842; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,109,115, + 101,100,97,116,97,115,111,117,114,99,101,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,184,6,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,116,6,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,135,255,255,1, + 138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1, + 128,128,128,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1, + 166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,128,128,128,1, + 180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1, + 194,255,255,1,128,128,128,2,135,255,255,1,138,255,255,1,140,255,255,1, + 143,255,255,1,146,255,255,1,149,255,255,1,128,128,128,1,155,255,255,1, + 157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1, + 172,255,255,1,174,255,255,1,128,128,128,1,180,255,255,1,183,255,255,1, + 186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,128,128,128,26, + 135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1, + 149,255,255,1,128,128,128,1,155,255,255,1,157,255,255,1,160,255,255,1, + 163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1, + 128,128,128,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1, + 191,255,255,1,194,255,255,1,128,128,128,2,135,255,255,1,138,255,255,1, + 140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1,128,128,128,1, + 155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1, + 169,255,255,1,172,255,255,1,174,255,255,1,128,128,128,1,180,255,255,1, + 183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1, + 128,128,128,26,135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1, + 146,255,255,1,149,255,255,1,128,128,128,1,155,255,255,1,157,255,255,1, + 160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1, + 174,255,255,1,128,128,128,1,180,255,255,1,183,255,255,1,186,255,255,1, + 189,255,255,1,191,255,255,1,194,255,255,1,128,128,128,2,135,255,255,1, + 138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1,149,255,255,1, + 128,128,128,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1, + 166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,128,128,128,1, + 180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1, + 194,255,255,1,128,128,128,26,135,255,255,1,138,255,255,1,140,255,255,1, + 143,255,255,1,146,255,255,1,149,255,255,1,128,128,128,1,155,255,255,1, + 157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1,169,255,255,1, + 172,255,255,1,174,255,255,1,128,128,128,1,180,255,255,1,183,255,255,1, + 186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,128,128,128,2, + 135,255,255,1,138,255,255,1,140,255,255,1,143,255,255,1,146,255,255,1, + 149,255,255,1,128,128,128,1,155,255,255,1,157,255,255,1,160,255,255,1, + 163,255,255,1,166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1, + 128,128,128,1,180,255,255,1,183,255,255,1,186,255,255,1,189,255,255,1, + 191,255,255,1,194,255,255,1,128,128,128,25,132,255,255,1,135,255,255,1, + 138,255,255,1,140,255,255,1,0,0,255,1,146,255,255,1,149,255,255,1, + 152,255,255,1,155,255,255,1,157,255,255,1,160,255,255,1,0,0,255,1, + 166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1, + 180,255,255,1,0,0,255,1,186,255,255,1,189,255,255,1,191,255,255,1, + 194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1, + 0,0,255,3,149,255,255,1,152,255,255,1,155,255,255,1,157,255,255,1, + 0,0,255,3,169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1, + 0,0,255,3,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1, + 132,255,255,1,135,255,255,1,0,0,255,5,152,255,255,1,155,255,255,1, + 0,0,255,5,172,255,255,1,174,255,255,1,0,0,255,5,191,255,255,1, + 194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1, + 140,255,255,1,0,0,255,1,146,255,255,1,149,255,255,1,152,255,255,1, + 155,255,255,1,157,255,255,1,160,255,255,1,0,0,255,1,166,255,255,1, + 169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1,180,255,255,1, + 0,0,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1, + 197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1,140,255,255,1, + 0,0,255,1,146,255,255,1,149,255,255,1,152,255,255,1,155,255,255,1, + 157,255,255,1,160,255,255,1,0,0,255,1,166,255,255,1,169,255,255,1, + 172,255,255,1,174,255,255,1,177,255,255,1,180,255,255,1,0,0,255,1, + 186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1, + 132,255,255,1,135,255,255,1,138,255,255,1,140,255,255,1,0,0,255,1, + 146,255,255,1,149,255,255,1,152,255,255,1,155,255,255,1,0,0,255,5, + 172,255,255,1,174,255,255,1,177,255,255,1,180,255,255,1,0,0,255,1, + 186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1, + 132,255,255,1,135,255,255,1,138,255,255,1,140,255,255,1,0,0,255,1, + 146,255,255,1,149,255,255,1,152,255,255,1,155,255,255,1,157,255,255,1, + 0,0,255,3,169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1, + 180,255,255,1,0,0,255,1,186,255,255,1,189,255,255,1,191,255,255,1, + 194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1, + 140,255,255,1,0,0,255,1,146,255,255,1,149,255,255,1,152,255,255,1, + 155,255,255,1,157,255,255,1,160,255,255,1,0,0,255,1,166,255,255,1, + 169,255,255,1,172,255,255,1,174,255,255,1,0,0,255,5,191,255,255,1, + 194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,0,0,255,5, + 152,255,255,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1, + 166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1, + 0,0,255,3,189,255,255,1,191,255,255,1,194,255,255,1,197,255,255,1, + 132,255,255,1,135,255,255,1,138,255,255,1,0,0,255,3,149,255,255,1, + 152,255,255,1,155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1, + 166,255,255,1,169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1, + 180,255,255,1,0,0,255,1,186,255,255,1,189,255,255,1,191,255,255,1, + 194,255,255,1,197,255,255,1,132,255,255,1,135,255,255,1,138,255,255,1, + 140,255,255,1,0,0,255,1,146,255,255,1,149,255,255,1,152,255,255,1, + 155,255,255,1,157,255,255,1,160,255,255,1,163,255,255,1,166,255,255,1, + 169,255,255,1,172,255,255,1,174,255,255,1,177,255,255,1,180,255,255,1, + 183,255,255,1,186,255,255,1,189,255,255,1,191,255,255,1,194,255,255,1, + 197,255,255,1,12,0,0,0,255,255,255,255,255,255,255,255,255,255,255,66, + 0,0) + ); + +initialization + registerobjectdata(@objdata_tlocaldataset,tbitmapcomp,'tlocaldataset'); + registerobjectdata(@objdata_tmsesqlquery,tbitmapcomp,'tmsesqlquery'); + registerobjectdata(@objdata_tmsesqltransaction,tbitmapcomp,'tmsesqltransaction'); + registerobjectdata(@objdata_tmseibconnection,tbitmapcomp,'tmseibconnection'); + registerobjectdata(@objdata_tfb3connection,tbitmapcomp,'tfb3connection'); + registerobjectdata(@objdata_tfbservice,tbitmapcomp,'tfbservice'); + registerobjectdata(@objdata_tfb3service,tbitmapcomp,'tfb3service'); + registerobjectdata(@objdata_tdatasource,tbitmapcomp,'tdatasource'); + registerobjectdata(@objdata_tdbnavigator,tbitmapcomp,'tdbnavigator'); + registerobjectdata(@objdata_tdbstringedit,tbitmapcomp,'tdbstringedit'); + registerobjectdata(@objdata_tdropdownlisteditdb,tbitmapcomp,'tdropdownlisteditdb'); + registerobjectdata(@objdata_tdropdownlisteditlb,tbitmapcomp,'tdropdownlisteditlb'); + registerobjectdata(@objdata_tdbdropdownlistedit,tbitmapcomp,'tdbdropdownlistedit'); + registerobjectdata(@objdata_tdbdropdownlisteditdb,tbitmapcomp,'tdbdropdownlisteditdb'); + registerobjectdata(@objdata_tdbdropdownlisteditlb,tbitmapcomp,'tdbdropdownlisteditlb'); + registerobjectdata(@objdata_tdbbooleantextedit,tbitmapcomp,'tdbbooleantextedit'); + registerobjectdata(@objdata_tdbmemoedit,tbitmapcomp,'tdbmemoedit'); + registerobjectdata(@objdata_tdbintegeredit,tbitmapcomp,'tdbintegeredit'); + registerobjectdata(@objdata_tdbbooleanedit,tbitmapcomp,'tdbbooleanedit'); + registerobjectdata(@objdata_tdbdataicon,tbitmapcomp,'tdbdataicon'); + registerobjectdata(@objdata_tdbbooleaneditradio,tbitmapcomp,'tdbbooleaneditradio'); + registerobjectdata(@objdata_tdbrealedit,tbitmapcomp,'tdbrealedit'); + registerobjectdata(@objdata_tdbrealspinedit,tbitmapcomp,'tdbrealspinedit'); + registerobjectdata(@objdata_tdbdatetimeedit,tbitmapcomp,'tdbdatetimeedit'); + registerobjectdata(@objdata_tdbenumedit,tbitmapcomp,'tdbenumedit'); + registerobjectdata(@objdata_tdbenumeditdb,tbitmapcomp,'tdbenumeditdb'); + registerobjectdata(@objdata_tdbenum64editdb,tbitmapcomp,'tdbenum64editdb'); + registerobjectdata(@objdata_tdbenumeditlb,tbitmapcomp,'tdbenumeditlb'); + registerobjectdata(@objdata_tdbenum64editlb,tbitmapcomp,'tdbenum64editlb'); + registerobjectdata(@objdata_tdbkeystringedit,tbitmapcomp,'tdbkeystringedit'); + registerobjectdata(@objdata_tdbkeystringeditdb,tbitmapcomp,'tdbkeystringeditdb'); + registerobjectdata(@objdata_tdbkeystringeditlb,tbitmapcomp,'tdbkeystringeditlb'); + registerobjectdata(@objdata_tdbstringlookuplb,tbitmapcomp,'tdbstringlookuplb'); + registerobjectdata(@objdata_tdbstringlookupdb,tbitmapcomp,'tdbstringlookupdb'); + registerobjectdata(@objdata_tdbintegerlookuplb,tbitmapcomp,'tdbintegerlookuplb'); + registerobjectdata(@objdata_tdbintegerlookupdb,tbitmapcomp,'tdbintegerlookupdb'); + registerobjectdata(@objdata_tdbreallookuplb,tbitmapcomp,'tdbreallookuplb'); + registerobjectdata(@objdata_tdbreallookupdb,tbitmapcomp,'tdbreallookupdb'); + registerobjectdata(@objdata_tdbdatetimelookuplb,tbitmapcomp,'tdbdatetimelookuplb'); + registerobjectdata(@objdata_tdbdatetimelookupdb,tbitmapcomp,'tdbdatetimelookupdb'); + registerobjectdata(@objdata_tdbstringlookup64lb,tbitmapcomp,'tdbstringlookup64lb'); + registerobjectdata(@objdata_tdbstringlookup64db,tbitmapcomp,'tdbstringlookup64db'); + registerobjectdata(@objdata_tdbintegerlookup64lb,tbitmapcomp,'tdbintegerlookup64lb'); + registerobjectdata(@objdata_tdbintegerlookup64db,tbitmapcomp,'tdbintegerlookup64db'); + registerobjectdata(@objdata_tdbreallookup64lb,tbitmapcomp,'tdbreallookup64lb'); + registerobjectdata(@objdata_tdbreallookup64db,tbitmapcomp,'tdbreallookup64db'); + registerobjectdata(@objdata_tdbdatetimelookup64lb,tbitmapcomp,'tdbdatetimelookup64lb'); + registerobjectdata(@objdata_tdbdatetimelookup64db,tbitmapcomp,'tdbdatetimelookup64db'); + registerobjectdata(@objdata_tdbstringlookupstrlb,tbitmapcomp,'tdbstringlookupstrlb'); + registerobjectdata(@objdata_tdbstringlookupstrdb,tbitmapcomp,'tdbstringlookupstrdb'); + registerobjectdata(@objdata_tdbintegerlookupstrlb,tbitmapcomp,'tdbintegerlookupstrlb'); + registerobjectdata(@objdata_tdbintegerlookupstrdb,tbitmapcomp,'tdbintegerlookupstrdb'); + registerobjectdata(@objdata_tdbreallookupstrlb,tbitmapcomp,'tdbreallookupstrlb'); + registerobjectdata(@objdata_tdbreallookupstrdb,tbitmapcomp,'tdbreallookupstrdb'); + registerobjectdata(@objdata_tdbdatetimelookupstrlb,tbitmapcomp,'tdbdatetimelookupstrlb'); + registerobjectdata(@objdata_tdbdatetimelookupstrdb,tbitmapcomp,'tdbdatetimelookupstrdb'); + registerobjectdata(@objdata_tdbwidgetgrid,tbitmapcomp,'tdbwidgetgrid'); + registerobjectdata(@objdata_tdbstringgrid,tbitmapcomp,'tdbstringgrid'); + registerobjectdata(@objdata_tlookupbuffer,tbitmapcomp,'tlookupbuffer'); + registerobjectdata(@objdata_tdblookupbuffer,tbitmapcomp,'tdblookupbuffer'); + registerobjectdata(@objdata_tdbmemolookupbuffer,tbitmapcomp,'tdbmemolookupbuffer'); + registerobjectdata(@objdata_tmsedbf,tbitmapcomp,'tmsedbf'); + registerobjectdata(@objdata_tmsefixedformatdataset,tbitmapcomp,'tmsefixedformatdataset'); + registerobjectdata(@objdata_tmsesdfdataset,tbitmapcomp,'tmsesdfdataset'); + registerobjectdata(@objdata_tmsememdataset,tbitmapcomp,'tmsememdataset'); + registerobjectdata(@objdata_tmsepqconnection,tbitmapcomp,'tmsepqconnection'); + registerobjectdata(@objdata_tmseodbcconnection,tbitmapcomp,'tmseodbcconnection'); + registerobjectdata(@objdata_tmsemysqlconnection,tbitmapcomp,'tmsemysqlconnection'); + registerobjectdata(@objdata_tenumeditdb,tbitmapcomp,'tenumeditdb'); + registerobjectdata(@objdata_tenum64editdb,tbitmapcomp,'tenum64editdb'); + registerobjectdata(@objdata_tenumeditlb,tbitmapcomp,'tenumeditlb'); + registerobjectdata(@objdata_tenum64editlb,tbitmapcomp,'tenum64editlb'); + registerobjectdata(@objdata_tkeystringeditdb,tbitmapcomp,'tkeystringeditdb'); + registerobjectdata(@objdata_tkeystringeditlb,tbitmapcomp,'tkeystringeditlb'); + registerobjectdata(@objdata_tmsestringfield,tbitmapcomp,'tmsestringfield'); + registerobjectdata(@objdata_tmselongintfield,tbitmapcomp,'tmselongintfield'); + registerobjectdata(@objdata_tmselargeintfield,tbitmapcomp,'tmselargeintfield'); + registerobjectdata(@objdata_tmsesmallintfield,tbitmapcomp,'tmsesmallintfield'); + registerobjectdata(@objdata_tmsewordfield,tbitmapcomp,'tmsewordfield'); + registerobjectdata(@objdata_tmseautoincfield,tbitmapcomp,'tmseautoincfield'); + registerobjectdata(@objdata_tmsefloatfield,tbitmapcomp,'tmsefloatfield'); + registerobjectdata(@objdata_tmsecurrencyfield,tbitmapcomp,'tmsecurrencyfield'); + registerobjectdata(@objdata_tmsebooleanfield,tbitmapcomp,'tmsebooleanfield'); + registerobjectdata(@objdata_tmsedatetimefield,tbitmapcomp,'tmsedatetimefield'); + registerobjectdata(@objdata_tmsedatefield,tbitmapcomp,'tmsedatefield'); + registerobjectdata(@objdata_tmsetimefield,tbitmapcomp,'tmsetimefield'); + registerobjectdata(@objdata_tmsebinaryfield,tbitmapcomp,'tmsebinaryfield'); + registerobjectdata(@objdata_tmsebytesfield,tbitmapcomp,'tmsebytesfield'); + registerobjectdata(@objdata_tmseguidfield,tbitmapcomp,'tmseguidfield'); + registerobjectdata(@objdata_tmsevarbytesfield,tbitmapcomp,'tmsevarbytesfield'); + registerobjectdata(@objdata_tmsebcdfield,tbitmapcomp,'tmsebcdfield'); + registerobjectdata(@objdata_tmseblobfield,tbitmapcomp,'tmseblobfield'); + registerobjectdata(@objdata_tmsememofield,tbitmapcomp,'tmsememofield'); + registerobjectdata(@objdata_tmsegraphicfield,tbitmapcomp,'tmsegraphicfield'); + registerobjectdata(@objdata_tmsevariantfield,tbitmapcomp,'tmsevariantfield'); + registerobjectdata(@objdata_tparamconnector,tbitmapcomp,'tparamconnector'); + registerobjectdata(@objdata_tsqlresultconnector,tbitmapcomp,'tsqlresultconnector'); + registerobjectdata(@objdata_tdblabel,tbitmapcomp,'tdblabel'); + registerobjectdata(@objdata_tdbbarcode,tbitmapcomp,'tdbbarcode'); + registerobjectdata(@objdata_tdbstringdisp,tbitmapcomp,'tdbstringdisp'); + registerobjectdata(@objdata_tdbintegerdisp,tbitmapcomp,'tdbintegerdisp'); + registerobjectdata(@objdata_tdbbooleandisp,tbitmapcomp,'tdbbooleandisp'); + registerobjectdata(@objdata_tdbrealdisp,tbitmapcomp,'tdbrealdisp'); + registerobjectdata(@objdata_tdbdatetimedisp,tbitmapcomp,'tdbdatetimedisp'); + registerobjectdata(@objdata_tdbstringdisplb,tbitmapcomp,'tdbstringdisplb'); + registerobjectdata(@objdata_tdbintegerdisplb,tbitmapcomp,'tdbintegerdisplb'); + registerobjectdata(@objdata_tdbrealdisplb,tbitmapcomp,'tdbrealdisplb'); + registerobjectdata(@objdata_tdbdatetimedisplb,tbitmapcomp,'tdbdatetimedisplb'); + registerobjectdata(@objdata_tfieldparamlink,tbitmapcomp,'tfieldparamlink'); + registerobjectdata(@objdata_tmsesqlite3dataset,tbitmapcomp,'tmsesqlite3dataset'); + registerobjectdata(@objdata_tdbcalendardatetimeedit,tbitmapcomp,'tdbcalendardatetimeedit'); + registerobjectdata(@objdata_tsequencelink,tbitmapcomp,'tsequencelink'); + registerobjectdata(@objdata_tdbdatabutton,tbitmapcomp,'tdbdatabutton'); + registerobjectdata(@objdata_tdbdialogstringedit,tbitmapcomp,'tdbdialogstringedit'); + registerobjectdata(@objdata_tdbdataimage,tbitmapcomp,'tdbdataimage'); + registerobjectdata(@objdata_tfieldfieldlink,tbitmapcomp,'tfieldfieldlink'); + registerobjectdata(@objdata_tdbfilenameedit,tbitmapcomp,'tdbfilenameedit'); + registerobjectdata(@objdata_tfieldlink,tbitmapcomp,'tfieldlink'); + registerobjectdata(@objdata_ttimestampfieldlink,tbitmapcomp,'ttimestampfieldlink'); + registerobjectdata(@objdata_tdbevent,tbitmapcomp,'tdbevent'); + registerobjectdata(@objdata_tsqlite3connection,tbitmapcomp,'tsqlite3connection'); + registerobjectdata(@objdata_tdbslider,tbitmapcomp,'tdbslider'); + registerobjectdata(@objdata_tdbprogressbar,tbitmapcomp,'tdbprogressbar'); + registerobjectdata(@objdata_tdbcoloredit,tbitmapcomp,'tdbcoloredit'); + registerobjectdata(@objdata_tsqlstatement,tbitmapcomp,'tsqlstatement'); + registerobjectdata(@objdata_tmsesqlscript,tbitmapcomp,'tmsesqlscript'); + registerobjectdata(@objdata_tsqlresult,tbitmapcomp,'tsqlresult'); + registerobjectdata(@objdata_tsqllookupbuffer,tbitmapcomp,'tsqllookupbuffer'); + registerobjectdata(@objdata_tmsedatasource,tbitmapcomp,'tmsedatasource'); +end. diff --git a/mseide-msegui/lib/common/regcomponents/regdeprecated.pas b/mseide-msegui/lib/common/regcomponents/regdeprecated.pas new file mode 100644 index 0000000..c7937d4 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regdeprecated.pas @@ -0,0 +1,43 @@ +{ MSEide Copyright (c) 1999-2010 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regdeprecated; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface + +implementation +{$ifndef mse_no_db}{$ifdef FPC}{$define hasdb}{$endif}{$endif} +uses + regdeprecated_bmp,msedesignintf,mselistbrowser + {$ifdef hasdb} + ,msemysql40conn,msemysql41conn,msemysql50conn, + msedbf,msesdfdata,msememds + {$endif}; + +procedure Register; +begin + registercomponents('Depr',[tmbdropdownitemedit, //redundant + {$ifdef hasdb} + tmsemysql40connection,tmsemysql41connection,tmsemysql50connection, + tmsedbf,tmsefixedformatdataset,tmsesdfdataset,tmsememdataset + {$endif} + ]); + registercomponenttabhints(['Depr'],['Deprecated components']); +end; + +initialization + register; +end. diff --git a/mseide-msegui/lib/common/regcomponents/regdeprecated_bmp.pas b/mseide-msegui/lib/common/regcomponents/regdeprecated_bmp.pas new file mode 100644 index 0000000..f132c1f --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regdeprecated_bmp.pas @@ -0,0 +1,233 @@ +unit regdeprecated_bmp; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msebitmap; + +const + objdata_tmsemysql40connection: record size: integer; data: array[0..1373] of byte end = + (size: 1374; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,21,116,109,115, + 101,109,121,115,113,108,52,48,99,111,110,110,101,99,116,105,111,110,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,36,5,0,0,0,0,0,0, + 0,0,0,0,24,0,0,0,24,0,0,0,240,4,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,255,35,0,0,0,1,6,5,5,1, + 11,10,9,1,4,4,3,1,7,7,6,1,11,10,9,1,0,0,255,11, + 4,4,3,1,21,18,13,2,21,18,14,1,20,17,13,1,0,0,255,1, + 10,9,7,1,21,19,16,1,147,135,117,1,253,235,207,1,95,88,79,1, + 169,160,147,1,254,242,224,1,79,76,70,1,21,20,19,1,0,0,255,9, + 51,43,31,1,228,194,139,1,251,216,159,1,252,218,165,1,169,148,113,1, + 31,27,21,1,133,118,97,1,253,227,188,1,253,230,193,1,253,232,199,1, + 115,105,91,1,180,168,150,1,253,239,217,1,254,241,223,1,254,244,228,1, + 69,66,62,1,0,0,255,9,60,50,36,1,222,188,134,1,251,215,156,1, + 251,217,162,1,252,219,168,1,252,222,174,1,252,224,180,1,253,227,186,1, + 252,229,192,1,253,231,198,1,254,234,203,1,254,237,209,1,253,239,215,1, + 254,240,220,1,254,243,226,1,69,66,61,1,42,41,39,1,0,0,255,8, + 110,92,63,1,251,212,149,1,252,214,155,1,252,217,161,1,252,219,167,1, + 252,221,172,1,252,223,178,1,252,226,184,1,253,229,190,1,253,231,196,1, + 253,234,201,1,253,236,207,1,254,238,213,1,254,240,219,1,254,243,225,1, + 254,245,230,1,11,10,10,1,0,0,255,6,63,51,34,1,251,206,136,1, + 251,209,142,1,251,211,147,1,251,213,153,1,252,216,159,1,252,218,165,1, + 252,221,170,1,252,223,176,1,213,190,154,1,190,171,143,1,190,173,147,1, + 190,175,151,1,190,177,156,1,190,178,160,1,190,180,164,1,191,182,168,1, + 10,10,9,1,0,0,255,6,63,51,32,1,250,203,128,1,251,206,134,1, + 251,208,140,1,251,210,145,1,251,213,151,1,252,215,157,1,252,217,163,1, + 252,219,169,1,95,83,64,1,0,0,0,7,0,0,255,7,125,98,57,1, + 250,200,120,1,250,203,127,1,251,205,133,1,251,207,138,1,251,209,144,1, + 252,212,150,1,252,214,156,1,252,217,161,1,95,82,61,1,0,0,255,13, + 52,40,22,1,250,194,107,1,250,197,113,1,250,200,119,1,250,202,125,1, + 211,172,111,1,157,130,87,1,204,170,117,1,251,211,148,1,197,167,120,1, + 77,66,48,1,0,0,255,12,34,25,12,1,134,101,50,1,250,191,100,1, + 250,194,106,1,250,196,111,1,211,168,99,1,103,83,51,1,0,0,0,1, + 92,77,52,1,146,122,84,1,61,51,35,1,0,0,255,13,42,31,14,1, + 249,186,86,1,249,188,92,1,249,190,98,1,212,164,88,1,102,80,45,1, + 0,0,255,3,0,0,0,2,0,0,255,12,20,17,12,1,117,95,56,1, + 249,183,79,1,249,185,85,1,213,160,77,1,100,76,39,1,0,0,255,5, + 0,0,168,1,0,0,16,1,0,0,255,3,0,0,224,1,0,0,59,1, + 0,0,43,1,0,0,79,1,0,0,244,1,0,0,255,3,27,21,10,1, + 222,168,79,1,249,180,71,1,249,182,77,1,176,130,58,1,0,0,0,1, + 0,0,255,4,0,0,210,1,0,0,31,1,0,0,15,1,0,0,255,3, + 0,0,74,1,0,0,159,1,0,0,255,1,0,0,106,1,0,0,126,1, + 0,0,255,3,158,112,41,1,248,176,64,1,248,178,66,1,212,153,59,1, + 89,65,28,1,0,0,255,4,0,0,238,1,0,0,46,1,0,0,180,1, + 0,0,15,1,0,0,255,2,0,0,249,1,0,0,4,1,0,0,243,1, + 0,0,255,1,0,0,195,1,0,0,49,1,0,0,255,2,23,16,6,1, + 248,177,65,2,248,177,64,1,186,131,45,1,0,0,0,1,0,0,255,3, + 0,0,253,1,0,0,72,1,0,0,170,1,0,0,223,1,0,0,15,1, + 0,0,255,2,0,0,228,1,0,0,11,1,0,0,255,2,0,0,219,1, + 0,0,21,1,0,0,255,2,21,15,5,1,248,177,65,2,248,176,63,1, + 186,129,40,1,0,0,0,1,0,0,255,3,0,0,120,1,0,0,116,1, + 0,0,255,1,0,0,223,1,0,0,15,1,0,0,255,2,0,0,229,1, + 0,0,12,1,0,0,255,2,0,0,219,1,0,0,20,1,0,0,255,2, + 21,15,5,1,248,177,65,1,248,175,61,1,247,167,41,1,186,127,34,1, + 0,0,0,1,0,0,255,3,0,0,24,1,0,0,45,1,0,0,47,1, + 0,0,41,1,0,0,2,1,0,0,47,1,0,0,255,1,0,0,250,1, + 0,0,6,1,0,0,245,1,0,0,255,1,0,0,196,1,0,0,46,1, + 0,0,255,2,21,14,3,1,247,166,38,1,247,165,37,1,247,162,30,1, + 232,154,32,1,132,89,22,1,0,0,0,2,0,0,255,4,0,0,223,1, + 0,0,15,1,0,0,255,3,0,0,74,1,0,0,160,1,0,0,255,1, + 0,0,109,1,0,0,121,1,0,0,255,2,21,13,2,1,247,162,29,3, + 247,163,31,1,232,156,35,1,179,129,48,1,147,126,87,1,96,84,62,1, + 0,0,255,3,0,0,223,1,0,0,15,1,0,0,255,3,0,0,221,1, + 0,0,54,1,0,0,43,1,0,0,77,1,0,0,243,1,0,0,255,2, + 21,13,2,1,247,162,29,3,196,128,23,1,41,28,6,1,38,27,10,1, + 31,27,18,1,28,25,18,1,0,0,255,14,10,7,1,1,219,143,26,1, + 220,144,26,1,31,20,4,2,30,19,3,1,0,0,255,18,10,7,1,1, + 228,150,27,1,18,12,2,1,0,0,0,1,0,0,255,20,10,7,1,1, + 226,148,27,1,0,0,0,1,0,0,255,21,0,0) + ); + +const + objdata_tmsemysql41connection: record size: integer; data: array[0..1285] of byte end = + (size: 1286; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,21,116,109,115, + 101,109,121,115,113,108,52,49,99,111,110,110,101,99,116,105,111,110,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,204,4,0,0,0,0,0,0, + 0,0,0,0,24,0,0,0,24,0,0,0,152,4,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,255,35,0,0,0,1,6,5,5,1, + 11,10,9,1,4,4,3,1,7,7,6,1,11,10,9,1,0,0,255,11, + 4,4,3,1,21,18,13,2,21,18,14,1,20,17,13,1,0,0,255,1, + 10,9,7,1,21,19,16,1,147,135,117,1,253,235,207,1,95,88,79,1, + 169,160,147,1,254,242,224,1,79,76,70,1,21,20,19,1,0,0,255,9, + 51,43,31,1,228,194,139,1,251,216,159,1,252,218,165,1,169,148,113,1, + 31,27,21,1,133,118,97,1,253,227,188,1,253,230,193,1,253,232,199,1, + 115,105,91,1,180,168,150,1,253,239,217,1,254,241,223,1,254,244,228,1, + 69,66,62,1,0,0,255,9,60,50,36,1,222,188,134,1,251,215,156,1, + 251,217,162,1,252,219,168,1,252,222,174,1,252,224,180,1,253,227,186,1, + 252,229,192,1,253,231,198,1,254,234,203,1,254,237,209,1,253,239,215,1, + 254,240,220,1,254,243,226,1,69,66,61,1,42,41,39,1,0,0,255,8, + 110,92,63,1,251,212,149,1,252,214,155,1,252,217,161,1,252,219,167,1, + 252,221,172,1,252,223,178,1,252,226,184,1,253,229,190,1,253,231,196,1, + 253,234,201,1,253,236,207,1,254,238,213,1,254,240,219,1,254,243,225,1, + 254,245,230,1,11,10,10,1,0,0,255,6,63,51,34,1,251,206,136,1, + 251,209,142,1,251,211,147,1,251,213,153,1,252,216,159,1,252,218,165,1, + 252,221,170,1,252,223,176,1,213,190,154,1,190,171,143,1,190,173,147,1, + 190,175,151,1,190,177,156,1,190,178,160,1,190,180,164,1,191,182,168,1, + 10,10,9,1,0,0,255,6,63,51,32,1,250,203,128,1,251,206,134,1, + 251,208,140,1,251,210,145,1,251,213,151,1,252,215,157,1,252,217,163,1, + 252,219,169,1,95,83,64,1,0,0,0,7,0,0,255,7,125,98,57,1, + 250,200,120,1,250,203,127,1,251,205,133,1,251,207,138,1,251,209,144,1, + 252,212,150,1,252,214,156,1,252,217,161,1,95,82,61,1,0,0,255,13, + 52,40,22,1,250,194,107,1,250,197,113,1,250,200,119,1,250,202,125,1, + 211,172,111,1,157,130,87,1,204,170,117,1,251,211,148,1,197,167,120,1, + 77,66,48,1,0,0,255,12,34,25,12,1,134,101,50,1,250,191,100,1, + 250,194,106,1,250,196,111,1,211,168,99,1,103,83,51,1,0,0,0,1, + 92,77,52,1,146,122,84,1,61,51,35,1,0,0,255,13,42,31,14,1, + 249,186,86,1,249,188,92,1,249,190,98,1,212,164,88,1,102,80,45,1, + 0,0,255,3,0,0,0,2,0,0,255,12,20,17,12,1,117,95,56,1, + 249,183,79,1,249,185,85,1,213,160,77,1,100,76,39,1,0,0,255,5, + 0,0,168,1,0,0,16,1,0,0,255,4,0,0,207,1,0,0,27,1, + 0,0,255,5,27,21,10,1,222,168,79,1,249,180,71,1,249,182,77,1, + 176,130,58,1,0,0,0,1,0,0,255,4,0,0,210,1,0,0,31,1, + 0,0,15,1,0,0,255,2,0,0,253,1,0,0,158,1,0,0,23,1, + 0,0,15,1,0,0,255,5,158,112,41,1,248,176,64,1,248,178,66,1, + 212,153,59,1,89,65,28,1,0,0,255,4,0,0,238,1,0,0,46,1, + 0,0,180,1,0,0,15,1,0,0,255,2,0,0,212,1,0,0,90,1, + 0,0,194,1,0,0,15,1,0,0,255,4,23,16,6,1,248,177,65,2, + 248,177,64,1,186,131,45,1,0,0,0,1,0,0,255,3,0,0,253,1, + 0,0,72,1,0,0,170,1,0,0,223,1,0,0,15,1,0,0,255,4, + 0,0,223,1,0,0,15,1,0,0,255,4,21,15,5,1,248,177,65,2, + 248,176,63,1,186,129,40,1,0,0,0,1,0,0,255,3,0,0,120,1, + 0,0,116,1,0,0,255,1,0,0,223,1,0,0,15,1,0,0,255,4, + 0,0,223,1,0,0,15,1,0,0,255,4,21,15,5,1,248,177,65,1, + 248,175,61,1,247,167,41,1,186,127,34,1,0,0,0,1,0,0,255,3, + 0,0,24,1,0,0,45,1,0,0,47,1,0,0,41,1,0,0,2,1, + 0,0,47,1,0,0,255,3,0,0,223,1,0,0,15,1,0,0,255,4, + 21,14,3,1,247,166,38,1,247,165,37,1,247,162,30,1,232,154,32,1, + 132,89,22,1,0,0,0,2,0,0,255,4,0,0,223,1,0,0,15,1, + 0,0,255,4,0,0,223,1,0,0,15,1,0,0,255,4,21,13,2,1, + 247,162,29,3,247,163,31,1,232,156,35,1,179,129,48,1,147,126,87,1, + 96,84,62,1,0,0,255,3,0,0,223,1,0,0,15,1,0,0,255,4, + 0,0,223,1,0,0,15,1,0,0,255,4,21,13,2,1,247,162,29,3, + 196,128,23,1,41,28,6,1,38,27,10,1,31,27,18,1,28,25,18,1, + 0,0,255,14,10,7,1,1,219,143,26,1,220,144,26,1,31,20,4,2, + 30,19,3,1,0,0,255,18,10,7,1,1,228,150,27,1,18,12,2,1, + 0,0,0,1,0,0,255,20,10,7,1,1,226,148,27,1,0,0,0,1, + 0,0,255,21,0,0) + ); + +const + objdata_tmsemysql50connection: record size: integer; data: array[0..1389] of byte end = + (size: 1390; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,21,116,109,115, + 101,109,121,115,113,108,53,48,99,111,110,110,101,99,116,105,111,110,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,52,5,0,0,0,0,0,0, + 0,0,0,0,24,0,0,0,24,0,0,0,0,5,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,255,35,0,0,0,1,6,5,5,1, + 11,10,9,1,4,4,3,1,7,7,6,1,11,10,9,1,0,0,255,11, + 4,4,3,1,21,18,13,2,21,18,14,1,20,17,13,1,0,0,255,1, + 10,9,7,1,21,19,16,1,147,135,117,1,253,235,207,1,95,88,79,1, + 169,160,147,1,254,242,224,1,79,76,70,1,21,20,19,1,0,0,255,9, + 51,43,31,1,228,194,139,1,251,216,159,1,252,218,165,1,169,148,113,1, + 31,27,21,1,133,118,97,1,253,227,188,1,253,230,193,1,253,232,199,1, + 115,105,91,1,180,168,150,1,253,239,217,1,254,241,223,1,254,244,228,1, + 69,66,62,1,0,0,255,9,60,50,36,1,222,188,134,1,251,215,156,1, + 251,217,162,1,252,219,168,1,252,222,174,1,252,224,180,1,253,227,186,1, + 252,229,192,1,253,231,198,1,254,234,203,1,254,237,209,1,253,239,215,1, + 254,240,220,1,254,243,226,1,69,66,61,1,42,41,39,1,0,0,255,8, + 110,92,63,1,251,212,149,1,252,214,155,1,252,217,161,1,252,219,167,1, + 252,221,172,1,252,223,178,1,252,226,184,1,253,229,190,1,253,231,196,1, + 253,234,201,1,253,236,207,1,254,238,213,1,254,240,219,1,254,243,225,1, + 254,245,230,1,11,10,10,1,0,0,255,6,63,51,34,1,251,206,136,1, + 251,209,142,1,251,211,147,1,251,213,153,1,252,216,159,1,252,218,165,1, + 252,221,170,1,252,223,176,1,213,190,154,1,190,171,143,1,190,173,147,1, + 190,175,151,1,190,177,156,1,190,178,160,1,190,180,164,1,191,182,168,1, + 10,10,9,1,0,0,255,6,63,51,32,1,250,203,128,1,251,206,134,1, + 251,208,140,1,251,210,145,1,251,213,151,1,252,215,157,1,252,217,163,1, + 252,219,169,1,95,83,64,1,0,0,0,7,0,0,255,7,125,98,57,1, + 250,200,120,1,250,203,127,1,251,205,133,1,251,207,138,1,251,209,144,1, + 252,212,150,1,252,214,156,1,252,217,161,1,95,82,61,1,0,0,255,13, + 52,40,22,1,250,194,107,1,250,197,113,1,250,200,119,1,250,202,125,1, + 211,172,111,1,157,130,87,1,204,170,117,1,251,211,148,1,197,167,120,1, + 77,66,48,1,0,0,255,12,34,25,12,1,134,101,50,1,250,191,100,1, + 250,194,106,1,250,196,111,1,211,168,99,1,103,83,51,1,0,0,0,1, + 92,77,52,1,146,122,84,1,61,51,35,1,0,0,255,13,42,31,14,1, + 249,186,86,1,249,188,92,1,249,190,98,1,212,164,88,1,102,80,45,1, + 0,0,255,3,0,0,0,2,0,0,255,12,20,17,12,1,117,95,56,1, + 249,183,79,1,249,185,85,1,213,160,77,1,100,76,39,1,0,0,255,3, + 0,0,71,1,0,0,38,1,0,0,47,2,0,0,73,1,0,0,255,1, + 0,0,224,1,0,0,59,1,0,0,43,1,0,0,79,1,0,0,244,1, + 0,0,255,4,27,21,10,1,222,168,79,1,249,180,71,1,249,182,77,1, + 176,130,58,1,0,0,0,1,0,0,255,2,0,0,254,1,0,0,20,1, + 0,0,241,1,0,0,255,4,0,0,74,1,0,0,159,1,0,0,255,1, + 0,0,106,1,0,0,126,1,0,0,255,4,158,112,41,1,248,176,64,1, + 248,178,66,1,212,153,59,1,89,65,28,1,0,0,255,3,0,0,213,1, + 0,0,20,1,0,0,73,1,0,0,42,1,0,0,102,1,0,0,245,1, + 0,0,249,1,0,0,4,1,0,0,243,1,0,0,255,1,0,0,195,1, + 0,0,49,1,0,0,255,3,23,16,6,1,248,177,65,2,248,177,64,1, + 186,131,45,1,0,0,0,1,0,0,255,3,0,0,194,1,0,0,92,1, + 0,0,239,1,0,0,249,1,0,0,91,1,0,0,105,1,0,0,228,1, + 0,0,11,1,0,0,255,2,0,0,219,1,0,0,21,1,0,0,255,3, + 21,15,5,1,248,177,65,2,248,176,63,1,186,129,40,1,0,0,0,1, + 0,0,255,7,0,0,209,1,0,0,27,1,0,0,229,1,0,0,12,1, + 0,0,255,2,0,0,219,1,0,0,20,1,0,0,255,3,21,15,5,1, + 248,177,65,1,248,175,61,1,247,167,41,1,186,127,34,1,0,0,0,1, + 0,0,255,3,0,0,187,1,0,0,183,1,0,0,255,2,0,0,208,1, + 0,0,31,1,0,0,250,1,0,0,6,1,0,0,245,1,0,0,255,1, + 0,0,196,1,0,0,46,1,0,0,255,3,21,14,3,1,247,166,38,1, + 247,165,37,1,247,162,30,1,232,154,32,1,132,89,22,1,0,0,0,2, + 0,0,255,1,0,0,166,1,0,0,40,1,0,0,243,1,0,0,254,1, + 0,0,98,1,0,0,86,1,0,0,255,1,0,0,74,1,0,0,160,1, + 0,0,255,1,0,0,109,1,0,0,121,1,0,0,255,3,21,13,2,1, + 247,162,29,3,247,163,31,1,232,156,35,1,179,129,48,1,147,126,87,1, + 96,84,62,1,0,0,254,1,0,0,122,1,0,0,34,1,0,0,39,1, + 0,0,83,1,0,0,230,1,0,0,255,1,0,0,221,1,0,0,54,1, + 0,0,43,1,0,0,77,1,0,0,243,1,0,0,255,3,21,13,2,1, + 247,162,29,3,196,128,23,1,41,28,6,1,38,27,10,1,31,27,18,1, + 28,25,18,1,0,0,255,14,10,7,1,1,219,143,26,1,220,144,26,1, + 31,20,4,2,30,19,3,1,0,0,255,18,10,7,1,1,228,150,27,1, + 18,12,2,1,0,0,0,1,0,0,255,20,10,7,1,1,226,148,27,1, + 0,0,0,1,0,0,255,21,0,0) + ); + +initialization + registerobjectdata(@objdata_tmsemysql40connection,tbitmapcomp,'tmsemysql40connection'); + registerobjectdata(@objdata_tmsemysql41connection,tbitmapcomp,'tmsemysql41connection'); + registerobjectdata(@objdata_tmsemysql50connection,tbitmapcomp,'tmsemysql50connection'); +end. diff --git a/mseide-msegui/lib/common/regcomponents/regdesignutils.pas b/mseide-msegui/lib/common/regcomponents/regdesignutils.pas new file mode 100644 index 0000000..8d07222 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regdesignutils.pas @@ -0,0 +1,35 @@ +{ MSEide Copyright (c) 1999-2010 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regdesignutils; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + msegdbutils,classes,msedesignintf,msesyntaxedit,msesyntaxpainter,regdesignutils_bmp; + +procedure Register; +begin + registercomponents('Design',[tgdbmi,tsyntaxedit,tsyntaxpainter]); + registercomponenttabhints(['Design'],['Design utils']); +end; + +initialization + register; +end. diff --git a/mseide-msegui/lib/common/regcomponents/regdesignutils_bmp.pas b/mseide-msegui/lib/common/regcomponents/regdesignutils_bmp.pas new file mode 100644 index 0000000..09c5f75 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regdesignutils_bmp.pas @@ -0,0 +1,150 @@ +unit regdesignutils_bmp; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msebitmap; + +const + objdata_tgdbmi: record size: integer; data: array[0..418] of byte end = + (size: 419; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,6,116,103,100, + 98,109,105,12,98,105,116,109,97,112,46,105,109,97,103,101,10,120,1,0, + 0,0,0,0,0,0,0,0,0,24,0,0,0,24,0,0,0,68,1,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,255,171,0,0,0, + 3,255,0,255,3,0,0,0,4,255,0,255,3,0,0,0,5,255,0,255, + 5,0,0,0,1,255,0,255,3,0,0,0,1,255,0,255,2,0,0,0, + 1,255,0,255,3,0,0,0,1,255,0,255,2,0,0,0,1,255,0,255, + 4,0,0,0,1,255,0,255,3,0,0,0,1,255,0,255,5,0,0,0, + 1,255,0,255,1,0,0,0,1,255,0,255,4,0,0,0,1,255,0,255, + 1,0,0,0,1,255,0,255,4,0,0,0,1,255,0,255,3,0,0,0, + 1,255,0,255,7,0,0,0,1,255,0,255,4,0,0,0,1,255,0,255, + 1,0,0,0,6,255,0,255,3,0,0,0,1,255,0,255,3,0,0,0, + 3,255,0,255,1,0,0,0,1,255,0,255,4,0,0,0,1,255,0,255, + 1,0,0,0,1,255,0,255,4,0,0,0,1,255,0,255,3,0,0,0, + 1,255,0,255,5,0,0,0,1,255,0,255,1,0,0,0,1,255,0,255, + 4,0,0,0,1,255,0,255,1,0,0,0,1,255,0,255,4,0,0,0, + 1,255,0,255,4,0,0,0,1,255,0,255,3,0,0,0,1,255,0,255, + 2,0,0,0,1,255,0,255,3,0,0,0,1,255,0,255,2,0,0,0, + 1,255,0,255,4,0,0,0,1,255,0,255,5,0,0,0,3,255,0,255, + 3,0,0,0,4,255,0,255,3,0,0,0,5,255,0,255,219,0,0) + ); + +const + objdata_tsyntaxedit: record size: integer; data: array[0..1614] of byte end = + (size: 1615; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,115,121, + 110,116,97,120,101,100,105,116,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,216,5,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,140,5,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,128,128,128,25,0,0,0,22,255,255,255, + 1,128,128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,255,255,255,1,140,140,140,1,148,148,148, + 1,226,226,226,1,209,209,209,1,222,222,222,2,175,175,175,1,242,242,242, + 1,132,132,132,1,210,210,210,1,215,215,215,1,226,226,226,1,190,190,190, + 1,209,209,209,1,165,165,165,1,210,210,210,1,208,208,208,1,255,255,255, + 2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255, + 1,138,138,138,1,183,183,183,1,190,190,190,1,133,133,133,1,179,179,179, + 1,177,177,177,1,180,180,183,1,232,232,252,1,153,153,155,1,192,192,192, + 1,140,140,140,1,180,180,180,1,195,195,195,1,213,213,213,1,156,156,156, + 1,169,169,169,1,155,155,155,1,255,255,255,2,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,255,255,255,1,211,211,211,1,255,255,255, + 1,208,208,208,1,161,161,182,1,73,73,214,1,33,33,217,1,4,4,219, + 1,0,0,219,1,3,3,219,1,30,30,221,1,96,96,205,1,205,205,219, + 1,203,203,203,1,234,234,234,1,220,220,220,1,183,183,183,1,167,167,167, + 1,255,255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,255,255,255,3,193,193,246,1,22,22,222,1,0,0,219,7,32,32,224, + 1,236,236,252,1,255,255,255,1,224,224,224,1,255,255,255,1,232,232,232, + 1,255,255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,255,255,255,1,175,175,175,2,39,39,208,1,0,0,219,2,66,66,220, + 1,99,99,191,1,112,112,176,1,89,89,207,1,12,12,213,1,0,0,219, + 2,68,68,209,1,202,202,202,1,145,145,145,1,255,255,255,4,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,164,164,164, + 1,139,139,156,1,1,1,218,1,0,0,219,1,29,29,220,1,161,161,162, + 1,149,149,149,1,159,159,159,1,171,171,171,1,108,108,191,1,0,0,219, + 2,14,14,216,1,134,134,134,1,176,176,176,1,255,255,255,4,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,197,197,197, + 1,191,191,200,1,4,4,220,1,0,0,219,1,1,1,219,1,142,142,238, + 1,233,233,252,1,255,255,255,2,253,253,255,1,189,189,246,1,199,199,247, + 1,209,209,249,1,253,253,255,1,255,255,255,5,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,255,255,255,1,124,124,124,1,216,216,216, + 1,71,71,222,1,0,0,219,3,3,3,219,1,57,57,217,1,108,108,196, + 1,160,160,182,1,236,236,236,1,217,217,217,1,137,137,137,1,213,213,213, + 1,207,207,207,1,186,186,186,1,255,255,255,3,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,255,255,255,1,175,175,175,1,169,169,169, + 1,152,152,167,1,32,32,209,1,0,0,219,5,1,1,219,1,36,36,210, + 1,117,117,191,1,156,156,156,1,192,192,192,1,188,188,188,1,173,173,173, + 1,255,255,255,3,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,255,255,255,1,215,215,215,1,167,167,167,1,157,157,157,1,182,182,185, + 1,124,124,208,1,42,42,201,1,6,6,220,1,0,0,219,5,105,105,211, + 1,236,236,236,1,184,184,184,1,214,214,214,1,255,255,255,3,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,197,197,197, + 1,160,160,160,1,214,214,214,1,218,218,218,1,255,255,255,2,242,242,251, + 1,183,183,245,1,99,99,218,1,16,16,210,1,0,0,219,2,1,1,219, + 1,233,233,252,1,255,255,255,1,0,0,0,1,255,255,255,1,0,0,0, + 1,255,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,255,255,255,1,176,176,176,1,107,107,165,1,81,81,182,1,78,78,200, + 1,127,127,180,1,175,175,175,1,110,110,110,1,216,216,216,1,255,255,255, + 1,170,170,177,1,51,51,222,1,0,0,219,2,167,167,243,1,255,255,255, + 2,0,0,0,1,255,255,255,2,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,255,255,255,1,185,185,185,1,121,121,227,1,0,0,219, + 2,33,33,212,1,187,187,189,1,177,177,177,1,203,203,203,1,255,255,255, + 1,195,195,195,1,55,55,214,1,0,0,219,2,156,156,241,1,255,255,255, + 2,0,0,0,1,255,255,255,2,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,255,255,255,1,242,242,242,1,210,210,249,1,1,1,219, + 1,0,0,219,2,100,100,228,1,202,202,248,1,253,253,255,1,212,212,249, + 1,129,129,237,1,0,0,219,2,2,2,219,1,233,233,252,1,255,255,255, + 2,0,0,0,1,255,255,255,2,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,255,255,255,1,175,175,175,1,226,226,226,1,107,107,220, + 1,0,0,219,4,6,6,219,1,0,0,219,4,88,88,231,1,255,255,255, + 3,0,0,0,1,255,255,255,2,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,255,255,255,1,183,183,183,1,126,126,126,1,236,236,238, + 1,86,86,189,1,12,12,214,1,0,0,219,5,3,3,219,1,107,107,234, + 1,248,248,254,1,255,255,255,3,0,0,0,1,255,255,255,2,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,234,234,234, + 1,162,162,162,1,255,255,255,1,234,234,234,1,244,244,253,1,162,162,218, + 1,133,133,216,1,129,129,233,1,123,123,217,1,150,150,219,1,216,216,231, + 1,255,255,255,5,0,0,0,1,255,255,255,2,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,255,255,255,16,0,0,0,1,255,255,255, + 1,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,255,255,255,20,224,224,224,1,255,255,255,1,128,128,128, + 1,224,224,224,22,255,255,255,25,20,0,0,0,255,255,255,255,255,255,255, + 255,255,255,255,42,128,128,128,1,255,255,255,23,0,0) + ); + +const + objdata_tsyntaxpainter: record size: integer; data: array[0..370] of byte end = + (size: 371; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,115,121, + 110,116,97,120,112,97,105,110,116,101,114,12,98,105,116,109,97,112,46,105, + 109,97,103,101,10,64,1,0,0,0,0,0,0,0,0,0,0,24,0,0, + 0,24,0,0,0,12,1,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,255,0,255,25,0,0,0,3,255,0,255,21,0,0,0,4,255,0,255, + 1,0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,2,0,0,0, + 1,255,0,255,3,255,0,0,4,255,0,255,1,128,0,0,1,255,0,255, + 53,0,0,0,1,255,0,255,1,0,0,0,2,255,0,255,3,0,0,0, + 1,255,0,255,1,0,0,0,1,255,0,255,1,0,0,0,1,255,0,255, + 16,0,0,0,1,255,0,255,43,0,0,0,1,255,0,255,1,0,0,0, + 1,255,0,255,2,0,0,0,1,255,0,255,1,0,0,0,2,255,0,255, + 63,0,0,0,4,255,0,255,2,0,0,0,1,255,0,255,1,0,0,0, + 1,255,0,255,15,0,0,0,1,255,0,255,45,0,0,0,2,255,0,255, + 22,0,0,0,2,255,0,255,70,0,0,0,5,255,0,255,19,0,0,0, + 5,255,0,255,1,0,0,0,3,255,0,255,2,0,0,0,1,255,0,255, + 2,0,0,0,1,255,0,255,1,0,0,0,1,255,0,255,58,0,0,0, + 1,255,0,255,1,0,0,0,3,255,0,255,3,0,0,0,1,255,0,255, + 1,0,0,0,1,255,0,255,33,0,0) + ); + +initialization + registerobjectdata(@objdata_tgdbmi,tbitmapcomp,'tgdbmi'); + registerobjectdata(@objdata_tsyntaxedit,tbitmapcomp,'tsyntaxedit'); + registerobjectdata(@objdata_tsyntaxpainter,tbitmapcomp,'tsyntaxpainter'); +end. diff --git a/mseide-msegui/lib/common/regcomponents/regdialogs.pas b/mseide-msegui/lib/common/regcomponents/regdialogs.pas new file mode 100644 index 0000000..3fe5891 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regdialogs.pas @@ -0,0 +1,43 @@ +{ MSEide Copyright (c) 1999-2012 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regdialogs; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + Classes,msefiledialog,msedesignintf,regdialogs_bmp,msecolordialog, + msememodialog,msedialog,mseguirttistat; + +procedure Register; +begin + registercomponents('Dialog',[tfilelistview,tdirtreeview, + tfiledialog, + tfilenameedit,tremotefilenameedit, + tdirdropdownedit,tcoloredit, + tdialogstringedit,tdialogintegeredit, + tdialogrealedit,tdialogdatetimeedit, + tmemodialogedit, + tmemodialoghistoryedit,tguirttistat]); + registercomponenttabhints(['Dialog'],['User dialogs']); +end; + +initialization + register; +end. diff --git a/mseide-msegui/lib/common/regcomponents/regdialogs_bmp.pas b/mseide-msegui/lib/common/regcomponents/regdialogs_bmp.pas new file mode 100644 index 0000000..4755caf --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regdialogs_bmp.pas @@ -0,0 +1,649 @@ +unit regdialogs_bmp; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msebitmap; + +const + objdata_tfilelistview: record size: integer; data: array[0..868] of byte end = + (size: 869; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,102,105, + 108,101,108,105,115,116,118,105,101,119,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,236,2,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,160,2,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,0,0,0,22,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,2,0,0,0,4,255, + 255,255,2,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,8,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,2,0, + 0,0,1,255,255,255,8,0,0,0,1,255,255,255,8,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,2,0,0,0,1,255, + 255,255,5,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,2,186, + 186,186,1,25,25,25,2,195,195,195,1,255,255,255,2,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,2,0,0,0,3,255, + 255,255,3,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,2,39, + 39,39,1,194,194,194,1,197,197,197,1,50,50,50,1,255,255,255,2,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,2,0, + 0,0,1,255,255,255,5,0,0,0,1,255,255,255,2,0,0,0,1,255, + 255,255,2,3,3,3,1,0,0,0,2,4,4,4,1,255,255,255,2,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,2,0, + 0,0,1,255,255,255,5,0,0,0,1,255,255,255,2,0,0,0,1,255, + 255,255,2,34,34,34,1,195,195,195,1,220,220,220,1,255,255,255,3,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,2,0, + 0,0,1,255,255,255,5,0,0,0,1,255,255,255,2,0,0,0,1,255, + 255,255,2,179,179,179,1,23,23,23,1,0,0,0,1,58,58,58,1,255, + 255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,20,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,20,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,20,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,20,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,20,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,20,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,20,224,224,224,1,255,255,255,1,128,128,128,1,224,224,224,22,255, + 255,255,25,20,0,0,0,255,255,255,255,255,255,255,255,255,255,255,42,128, + 128,128,1,255,255,255,23,0,0) + ); + +const + objdata_tdirtreeview: record size: integer; data: array[0..1027] of byte end = + (size: 1028; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,100,105, + 114,116,114,101,101,118,105,101,119,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,140,3,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,64,3,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,128,128,128,25,0,0,0,22,255,255, + 255,1,128,128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255,255, + 255,1,128,128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255,255, + 255,1,128,128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255,255, + 255,1,128,128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255,255, + 255,1,128,128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255,255, + 255,1,128,128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255,255, + 255,1,128,128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255,255, + 255,1,128,128,128,1,0,0,0,1,255,255,255,3,57,57,57,1,68,68, + 68,2,112,112,112,1,233,233,233,1,255,255,255,2,59,59,59,1,249,249, + 249,1,225,225,225,1,54,54,54,1,68,68,68,1,71,71,71,1,95,95, + 95,1,219,219,219,1,255,255,255,2,224,224,224,1,255,255,255,1,128,128, + 128,1,0,0,0,1,255,255,255,3,8,8,8,1,249,249,249,1,254,254, + 254,1,176,176,176,1,42,42,42,1,245,245,245,1,255,255,255,1,10,10, + 10,1,247,247,247,1,217,217,217,1,39,39,39,1,255,255,255,2,175,175, + 175,1,50,50,50,1,255,255,255,2,224,224,224,1,255,255,255,1,128,128, + 128,1,0,0,0,1,255,255,255,3,8,8,8,1,249,249,249,1,255,255, + 255,2,88,88,88,1,168,168,168,1,255,255,255,1,10,10,10,1,247,247, + 247,1,217,217,217,1,39,39,39,1,255,255,255,2,222,222,222,1,25,25, + 25,1,255,255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,255,255,255,3,8,8,8,1,249,249,249,1,255,255,255,2,120,120, + 120,1,139,139,139,1,255,255,255,1,10,10,10,1,247,247,247,1,217,217, + 217,1,16,16,16,1,102,102,102,1,98,98,98,1,49,49,49,1,173,173, + 173,1,255,255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,255,255,255,3,8,8,8,1,249,249,249,1,255,255,255,2,85,85, + 85,1,168,168,168,1,255,255,255,1,10,10,10,1,247,247,247,1,217,217, + 217,1,34,34,34,1,221,221,221,1,190,190,190,1,41,41,41,1,247,247, + 247,1,255,255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,255,255,255,3,8,8,8,1,249,249,249,1,252,252,252,1,168,168, + 168,1,40,40,40,1,244,244,244,1,255,255,255,1,10,10,10,1,247,247, + 247,1,217,217,217,1,39,39,39,1,255,255,255,2,114,114,114,1,123,123, + 123,1,255,255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,255,255,255,3,57,57,57,1,68,68,68,2,116,116,116,1,234,234, + 234,1,255,255,255,2,59,59,59,1,249,249,249,1,225,225,225,1,82,82, + 82,1,255,255,255,2,242,242,242,1,69,69,69,1,232,232,232,1,255,255, + 255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255, + 255,20,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255, + 255,20,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255, + 255,20,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255, + 255,20,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255, + 255,20,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255, + 255,20,224,224,224,1,255,255,255,1,128,128,128,1,224,224,224,22,255,255, + 255,25,20,0,0,0,255,255,255,255,255,255,255,255,255,255,255,42,128,128, + 128,1,255,255,255,23,0,0) + ); + +const + objdata_tfiledialog: record size: integer; data: array[0..2114] of byte end = + (size: 2115; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,102,105, + 108,101,100,105,97,108,111,103,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,204,7,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,136,7,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,255,255,255,25,242,166,149,1,221,216,211, + 1,242,166,149,1,255,134,109,2,121,64,52,1,157,83,67,1,187,98,80, + 1,208,109,89,2,247,130,106,1,212,111,91,1,255,134,109,4,160,160,160, + 6,128,128,128,1,255,255,255,1,221,216,211,1,7,239,255,1,221,216,211, + 1,255,134,109,2,120,63,51,1,201,106,86,1,181,95,77,1,135,71,58, + 1,214,112,91,1,139,73,59,1,163,86,70,1,242,127,103,1,255,134,109, + 3,160,160,160,1,212,212,212,1,128,128,128,1,160,160,160,1,209,209,209, + 1,128,128,128,2,255,255,255,1,242,166,149,1,221,216,211,1,242,166,149, + 1,255,134,109,2,212,111,91,1,255,134,109,1,218,115,93,1,204,107,87, + 1,180,95,77,1,222,117,95,1,184,97,79,1,253,133,108,1,255,134,109, + 3,160,160,160,1,212,212,212,1,128,128,128,1,160,160,160,1,209,209,209, + 1,128,128,128,2,255,255,255,1,151,24,0,16,128,128,128,7,255,255,255, + 1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226, + 1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221, + 1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215, + 1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210, + 1,209,209,209,1,208,208,208,1,128,128,128,1,255,255,255,1,230,230,230, + 1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225, + 1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220, + 1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214, + 1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209, + 1,208,208,208,1,128,128,128,1,255,255,255,1,230,230,230,1,229,229,229, + 1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224, + 1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219, + 1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213, + 1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208, + 1,128,128,128,1,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228, + 1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223, + 1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218, + 1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212, + 1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,128,128,128, + 1,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227, + 1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222, + 1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217, + 1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211, + 1,210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1,255,255,255, + 1,230,230,230,1,229,229,229,1,228,228,228,1,0,0,0,4,223,223,223, + 1,222,222,222,1,0,0,0,1,220,220,220,1,219,219,219,1,0,0,0, + 1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212, + 1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,128,128,128, + 1,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1,0,0,0, + 1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222, + 1,221,221,221,1,220,220,220,1,219,219,219,1,0,0,0,1,217,217,217, + 1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211, + 1,210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1,255,255,255, + 1,230,230,230,1,229,229,229,1,228,228,228,1,0,0,0,1,226,226,226, + 1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,0,0,0, + 1,220,220,220,1,219,219,219,1,0,0,0,1,217,217,217,1,215,215,215, + 1,156,156,156,1,21,21,21,2,161,161,161,1,210,210,210,1,209,209,209, + 1,208,208,208,1,128,128,128,1,255,255,255,1,230,230,230,1,229,229,229, + 1,228,228,228,1,0,0,0,3,224,224,224,1,223,223,223,1,222,222,222, + 1,0,0,0,1,220,220,220,1,219,219,219,1,0,0,0,1,217,217,217, + 1,215,215,215,1,33,33,33,1,162,162,162,1,164,164,164,1,41,41,41, + 1,210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1,255,255,255, + 1,230,230,230,1,229,229,229,1,228,228,228,1,0,0,0,1,226,226,226, + 1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,0,0,0, + 1,220,220,220,1,219,219,219,1,0,0,0,1,217,217,217,1,215,215,215, + 1,3,3,3,1,0,0,0,2,3,3,3,1,210,210,210,1,209,209,209, + 1,208,208,208,1,128,128,128,1,255,255,255,1,230,230,230,1,229,229,229, + 1,228,228,228,1,0,0,0,1,226,226,226,1,225,225,225,1,224,224,224, + 1,223,223,223,1,222,222,222,1,0,0,0,1,220,220,220,1,219,219,219, + 1,0,0,0,1,217,217,217,1,215,215,215,1,29,29,29,1,163,163,163, + 1,183,183,183,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208, + 1,128,128,128,1,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228, + 1,0,0,0,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223, + 1,222,222,222,1,0,0,0,1,220,220,220,1,219,219,219,1,0,0,0, + 1,217,217,217,1,215,215,215,1,150,150,150,1,19,19,19,1,0,0,0, + 1,48,48,48,1,210,210,210,1,209,209,209,1,208,208,208,1,128,128,128, + 1,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227, + 1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222, + 1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217, + 1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211, + 1,210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1,255,255,255, + 1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226, + 1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221, + 1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215, + 1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210, + 1,209,209,209,1,208,208,208,1,128,128,128,1,255,255,255,1,230,230,230, + 1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225, + 1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220, + 1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214, + 1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209, + 1,208,208,208,1,128,128,128,1,255,255,255,1,230,230,230,1,229,229,229, + 1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224, + 1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219, + 1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213, + 1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208, + 1,128,128,128,1,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228, + 1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223, + 1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218, + 1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212, + 1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,128,128,128, + 1,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227, + 1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222, + 1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217, + 1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211, + 1,210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,25,12,0,0, + 0,255,255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tfilenameedit: record size: integer; data: array[0..740] of byte end = + (size: 741; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,102,105, + 108,101,110,97,109,101,101,100,105,116,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,108,2,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,36,2,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,255,255,255,120,128,128,128,25,0, + 0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,20,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,0, + 0,0,4,255,255,255,2,0,0,0,1,255,255,255,2,0,0,0,1,255, + 255,255,6,0,0,0,1,255,255,255,1,0,0,0,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,0,0,0,1,255, + 255,255,8,0,0,0,1,255,255,255,7,0,0,0,1,255,255,255,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,0, + 0,0,1,255,255,255,5,0,0,0,1,255,255,255,2,0,0,0,1,255, + 255,255,2,186,186,186,1,25,25,25,2,195,195,195,1,255,255,255,1,0, + 0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,1,0,0,0,3,255,255,255,3,0,0,0,1,255, + 255,255,2,0,0,0,1,255,255,255,2,39,39,39,1,194,194,194,1,197, + 197,197,1,50,50,50,1,255,255,255,1,0,0,0,1,255,255,255,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,0, + 0,0,1,255,255,255,5,0,0,0,1,255,255,255,2,0,0,0,1,255, + 255,255,2,3,3,3,1,0,0,0,2,4,4,4,1,255,255,255,1,0, + 0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,1,0,0,0,1,255,255,255,5,0,0,0,1,255, + 255,255,2,0,0,0,1,255,255,255,2,34,34,34,1,195,195,195,1,220, + 220,220,1,255,255,255,2,0,0,0,1,255,255,255,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,0,0,0,1,255, + 255,255,5,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,2,179, + 179,179,1,23,23,23,1,0,0,0,1,58,58,58,1,255,255,255,1,0, + 0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,17,0,0,0,1,255,255,255,1,0,0,0,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,20,224, + 224,224,1,255,255,255,1,128,128,128,1,224,224,224,22,255,255,255,145,16, + 0,0,0,0,0,0,120,255,255,255,255,255,255,255,81,0,0,0,120,0, + 0) + ); + +const + objdata_tdirdropdownedit: record size: integer; data: array[0..1243] of byte end = + (size: 1244; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,100,105, + 114,100,114,111,112,100,111,119,110,101,100,105,116,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,96,4, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,28,4, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,255,255, + 255,1,0,0,0,2,5,5,5,1,174,174,174,1,255,255,255,2,0,0, + 0,1,255,255,255,6,0,0,0,1,255,255,255,1,0,0,0,1,255,255, + 255,6,128,128,128,1,255,255,255,1,0,0,0,1,255,255,255,1,174,174, + 174,1,5,5,5,1,255,255,255,2,0,0,0,1,255,255,255,1,0,0, + 0,1,71,71,71,1,255,255,255,4,0,0,0,1,255,255,255,2,208,208, + 208,3,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1,0,0, + 0,1,255,255,255,2,0,0,0,1,255,255,255,2,0,0,0,1,255,255, + 255,1,0,0,0,1,213,213,213,1,255,255,255,4,0,0,0,1,255,255, + 255,2,0,0,0,3,128,128,128,1,255,255,255,1,128,128,128,1,255,255, + 255,1,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,2,0,0, + 0,1,255,255,255,1,0,0,0,1,254,254,254,1,255,255,255,4,0,0, + 0,1,255,255,255,2,208,208,208,1,0,0,0,1,208,208,208,1,128,128, + 128,1,255,255,255,1,128,128,128,1,255,255,255,1,0,0,0,1,255,255, + 255,1,174,174,174,1,5,5,5,1,255,255,255,2,0,0,0,1,255,255, + 255,1,0,0,0,1,255,255,255,3,252,252,252,1,231,231,231,1,0,0, + 0,1,247,247,247,1,255,255,255,1,208,208,208,3,128,128,128,1,255,255, + 255,1,128,128,128,1,255,255,255,1,0,0,0,2,5,5,5,1,174,174, + 174,1,255,255,255,2,0,0,0,1,255,255,255,1,0,0,0,1,255,255, + 255,3,223,223,223,1,0,0,0,1,223,223,223,1,0,0,0,1,128,128, + 128,5,255,255,255,25,0,0,0,25,255,255,255,22,0,0,0,2,255,255, + 255,1,0,0,0,3,255,255,255,1,238,238,238,1,167,167,167,1,171,171, + 171,1,220,220,220,1,203,203,203,1,175,175,175,1,204,204,204,1,219,219, + 219,1,241,241,241,1,200,200,200,1,243,243,243,1,255,255,255,6,0,0, + 0,2,255,255,255,1,0,0,0,1,255,255,255,1,0,0,0,1,255,255, + 255,1,226,226,226,1,147,147,147,1,164,164,164,1,173,173,173,1,175,175, + 175,1,178,178,178,1,172,172,172,1,182,182,182,1,172,172,172,1,166,166, + 166,1,173,173,173,1,255,255,255,6,0,0,0,2,255,255,255,1,0,0, + 0,3,255,255,255,1,241,241,241,1,198,198,198,1,197,197,197,1,202,202, + 202,1,215,215,215,1,198,198,198,1,219,219,219,1,195,195,195,1,211,211, + 211,1,128,128,128,1,223,223,223,1,255,255,255,6,0,0,0,2,255,255, + 255,2,0,0,0,1,255,255,255,19,0,0,0,2,255,255,255,6,0,0, + 0,3,255,255,255,2,249,249,249,1,181,181,181,1,254,254,254,2,243,243, + 243,1,213,213,213,1,248,248,248,1,255,255,255,4,0,0,0,2,255,255, + 255,2,0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,1,0,0, + 0,1,255,255,255,1,0,0,0,1,255,255,255,1,160,160,160,1,168,168, + 168,1,140,140,140,1,170,170,170,1,140,140,140,1,157,157,157,1,149,149, + 149,1,234,234,234,1,255,255,255,4,0,0,0,2,255,255,255,6,0,0, + 0,3,255,255,255,1,144,144,144,1,209,209,209,1,179,179,179,1,219,219, + 219,1,132,132,132,1,193,193,193,1,164,164,164,1,239,239,239,1,255,255, + 255,4,0,0,0,2,255,255,255,2,0,0,0,1,255,255,255,10,250,250, + 250,1,226,226,226,1,255,255,255,7,0,0,0,2,255,255,255,6,0,0, + 0,3,255,255,255,3,175,175,175,1,200,200,200,1,255,255,255,3,206,206, + 206,1,175,175,175,1,255,255,255,3,0,0,0,2,255,255,255,2,0,0, + 0,1,255,255,255,1,0,0,0,1,255,255,255,1,0,0,0,1,255,255, + 255,1,0,0,0,1,255,255,255,1,141,141,141,1,152,152,152,1,146,146, + 146,1,98,98,98,1,170,170,170,1,137,137,137,1,173,173,173,1,174,174, + 174,1,137,137,137,1,166,166,166,1,175,175,175,1,255,255,255,1,0,0, + 0,2,255,255,255,6,0,0,0,3,255,255,255,1,186,186,186,1,203,203, + 203,1,195,195,195,1,173,173,173,1,202,202,202,1,171,171,171,1,169,169, + 169,1,201,201,201,1,184,184,184,1,172,172,172,1,176,176,176,1,255,255, + 255,1,0,0,0,2,255,255,255,2,0,0,0,1,255,255,255,15,252,252, + 252,1,183,183,183,1,241,241,241,1,255,255,255,1,0,0,0,2,255,255, + 255,22,0,0,0,25,12,0,0,0,255,255,255,255,255,255,255,255,255,255, + 255,66,0,0) + ); + +const + objdata_tcoloredit: record size: integer; data: array[0..1177] of byte end = + (size: 1178; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,99,111, + 108,111,114,101,100,105,116,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,36,4,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,220,3,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,255,255,255,120,128,128,128,25,0,0,0,22, + 255,255,255,1,128,128,128,1,0,0,0,1,0,36,255,1,0,111,255,1, + 0,187,255,1,0,255,247,1,0,255,167,1,0,255,87,1,0,255,7,1, + 68,255,0,1,143,255,0,1,218,255,0,1,255,217,0,1,255,142,0,1, + 255,67,0,1,255,0,7,1,255,0,82,1,255,0,156,1,255,0,231,1, + 198,0,255,1,118,0,255,1,39,0,255,1,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,0,36,255,1,0,111,255,1,0,187,255,1, + 0,255,247,1,0,255,167,1,0,255,87,1,0,255,7,1,68,255,0,1, + 143,255,0,1,218,255,0,1,255,217,0,1,255,142,0,1,255,67,0,1, + 255,0,7,1,255,0,82,1,255,0,156,1,255,0,231,1,0,0,0,1, + 118,0,255,1,0,0,0,1,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,0,36,255,1,0,111,255,1,0,187,255,1,0,255,247,1, + 0,255,167,1,0,255,87,1,0,255,7,1,68,255,0,1,143,255,0,1, + 218,255,0,1,255,217,0,1,255,142,0,1,255,67,0,1,255,0,7,1, + 255,0,82,1,255,0,156,1,255,0,231,1,198,0,255,1,0,0,0,1, + 39,0,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 0,36,255,1,0,111,255,1,0,187,255,1,0,255,247,1,0,255,167,1, + 0,255,87,1,0,255,7,1,68,255,0,1,143,255,0,1,218,255,0,1, + 255,217,0,1,255,142,0,1,255,67,0,1,255,0,7,1,255,0,82,1, + 255,0,156,1,255,0,231,1,198,0,255,1,0,0,0,1,39,0,255,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,0,36,255,1, + 0,111,255,1,0,187,255,1,0,255,247,1,0,255,167,1,0,255,87,1, + 0,255,7,1,68,255,0,1,143,255,0,1,218,255,0,1,255,217,0,1, + 255,142,0,1,255,67,0,1,255,0,7,1,255,0,82,1,255,0,156,1, + 255,0,231,1,198,0,255,1,0,0,0,1,39,0,255,1,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,0,36,255,1,0,111,255,1, + 0,187,255,1,0,255,247,1,0,255,167,1,0,255,87,1,0,255,7,1, + 68,255,0,1,143,255,0,1,218,255,0,1,255,217,0,1,255,142,0,1, + 255,67,0,1,255,0,7,1,255,0,82,1,255,0,156,1,255,0,231,1, + 198,0,255,1,0,0,0,1,39,0,255,1,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,0,36,255,1,0,111,255,1,0,187,255,1, + 0,255,247,1,0,255,167,1,0,255,87,1,0,255,7,1,68,255,0,1, + 143,255,0,1,218,255,0,1,255,217,0,1,255,142,0,1,255,67,0,1, + 255,0,7,1,255,0,82,1,255,0,156,1,255,0,231,1,198,0,255,1, + 0,0,0,1,39,0,255,1,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,0,36,255,1,0,111,255,1,0,187,255,1,0,255,247,1, + 0,255,167,1,0,255,87,1,0,255,7,1,68,255,0,1,143,255,0,1, + 218,255,0,1,255,217,0,1,255,142,0,1,255,67,0,1,255,0,7,1, + 255,0,82,1,255,0,156,1,255,0,231,1,198,0,255,1,0,0,0,1, + 39,0,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 0,36,255,1,0,111,255,1,0,187,255,1,0,255,247,1,0,255,167,1, + 0,255,87,1,0,255,7,1,68,255,0,1,143,255,0,1,218,255,0,1, + 255,217,0,1,255,142,0,1,255,67,0,1,255,0,7,1,255,0,82,1, + 255,0,156,1,255,0,231,1,0,0,0,1,118,0,255,1,0,0,0,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,0,36,255,1, + 0,111,255,1,0,187,255,1,0,255,247,1,0,255,167,1,0,255,87,1, + 0,255,7,1,68,255,0,1,143,255,0,1,218,255,0,1,255,217,0,1, + 255,142,0,1,255,67,0,1,255,0,7,1,255,0,82,1,255,0,156,1, + 255,0,231,1,198,0,255,1,118,0,255,1,39,0,255,1,224,224,224,1, + 255,255,255,1,128,128,128,1,224,224,224,22,255,255,255,145,16,0,0,0, + 0,0,0,120,255,255,255,255,255,255,255,81,0,0,0,120,0,0) + ); + +const + objdata_tdialogstringedit: record size: integer; data: array[0..876] of byte end = + (size: 877; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,100,105, + 97,108,111,103,115,116,114,105,110,103,101,100,105,116,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,240, + 2,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,168, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,120,128, + 128,128,25,0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,13,243,243,243,7,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,1,254,254,254,1,31,31,31,1,173,173,173,1,255, + 255,255,1,0,0,0,1,51,51,51,1,49,49,49,1,31,31,31,1,149, + 149,149,1,0,0,0,1,255,255,255,1,0,0,0,1,243,243,243,1,232, + 232,232,5,128,128,128,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,1,207,207,207,1,78,78,78,1,97,97,97,1,255, + 255,255,1,0,0,0,1,255,255,255,2,228,228,228,1,11,11,11,1,255, + 255,255,1,0,0,0,1,255,255,255,1,243,243,243,1,226,226,226,5,128, + 128,128,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,1,128,128,128,1,199,199,199,1,53,53,53,1,253,253,253,1,0, + 0,0,1,255,255,255,1,254,254,254,1,189,189,189,1,43,43,43,1,255, + 255,255,1,0,0,0,1,255,255,255,1,243,243,243,1,215,215,215,5,128, + 128,128,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,1,74,74,74,1,253,253,253,1,102,102,102,1,201,201,201,1,0, + 0,0,4,151,151,151,1,255,255,255,1,0,0,0,1,255,255,255,1,243, + 243,243,1,0,0,0,1,204,204,204,1,0,0,0,1,204,204,204,1,0, + 0,0,1,128,128,128,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,224,224,224,1,0,0,0,3,125,125,125,1,0,0,0,1,255, + 255,255,1,254,254,254,1,195,195,195,1,18,18,18,1,255,255,255,1,0, + 0,0,1,255,255,255,1,243,243,243,1,0,0,0,1,194,194,194,1,0, + 0,0,1,194,194,194,1,0,0,0,1,128,128,128,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,145,145,145,1,162,162,162,1,255, + 255,255,1,241,241,241,1,55,55,55,1,0,0,0,1,255,255,255,2,227, + 227,227,1,16,16,16,1,255,255,255,1,0,0,0,1,255,255,255,1,243, + 243,243,1,183,183,183,5,128,128,128,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,70,70,70,1,236,236,236,1,255,255,255,2,66, + 66,66,1,0,0,0,1,51,51,51,1,50,50,50,1,39,39,39,1,160, + 160,160,1,255,255,255,1,0,0,0,1,255,255,255,1,243,243,243,1,172, + 172,172,5,128,128,128,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,10,0,0,0,1,255,255,255,1,0,0,0,1,243, + 243,243,1,167,167,167,5,128,128,128,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,13,128,128,128,7,224,224,224,1,255, + 255,255,1,128,128,128,1,224,224,224,22,255,255,255,145,16,0,0,0,0, + 0,0,120,255,255,255,255,255,255,255,81,0,0,0,120,0,0) + ); + +const + objdata_tmemodialogedit: record size: integer; data: array[0..826] of byte end = + (size: 827; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,109,101, + 109,111,100,105,97,108,111,103,101,100,105,116,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,192,2,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,120,2,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,120,128,128,128, + 25,0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255, + 13,243,243,243,7,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 2,127,127,127,1,255,255,255,2,131,131,131,1,0,0,0,1,255,255,255, + 4,0,0,0,1,255,255,255,1,0,0,0,1,243,243,243,1,232,232,232, + 5,128,128,128,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 2,86,86,86,1,255,255,255,2,91,91,91,1,0,0,0,1,255,255,255, + 5,0,0,0,1,255,255,255,1,243,243,243,1,226,226,226,5,128,128,128, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,2,101,101,101, + 1,238,238,238,1,241,241,241,1,104,104,104,1,0,0,0,1,255,255,255, + 1,238,238,238,1,73,73,73,1,57,57,57,1,150,150,150,1,0,0,0, + 1,255,255,255,1,243,243,243,1,215,215,215,5,128,128,128,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,2,169,169,169,1,170,170,170, + 1,175,175,175,1,170,170,170,1,0,0,0,1,255,255,255,1,131,131,131, + 1,196,196,196,1,255,255,255,1,86,86,86,1,0,0,0,1,255,255,255, + 1,243,243,243,1,0,0,0,1,204,204,204,1,0,0,0,1,204,204,204, + 1,0,0,0,1,128,128,128,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,2,236,236,236,1,101,101,101,1,107,107,107,1,237,237,237, + 1,0,0,0,1,255,255,255,1,87,87,87,1,0,0,0,4,255,255,255, + 1,243,243,243,1,0,0,0,1,194,194,194,1,0,0,0,1,194,194,194, + 1,0,0,0,1,128,128,128,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,2,255,255,255,1,81,81,81,1,89,89,89,1,255,255,255, + 1,0,0,0,1,255,255,255,1,109,109,109,1,208,208,208,1,255,255,255, + 1,165,165,165,1,0,0,0,1,255,255,255,1,243,243,243,1,183,183,183, + 5,128,128,128,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 2,255,255,255,1,123,123,123,1,124,124,124,1,255,255,255,1,0,0,0, + 1,255,255,255,1,222,222,222,1,63,63,63,2,124,124,124,1,0,0,0, + 1,255,255,255,1,243,243,243,1,172,172,172,5,128,128,128,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,10,0,0,0, + 1,255,255,255,1,0,0,0,1,243,243,243,1,167,167,167,5,128,128,128, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255, + 13,128,128,128,7,224,224,224,1,255,255,255,1,128,128,128,1,224,224,224, + 22,255,255,255,145,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255, + 81,0,0,0,120,0,0) + ); + +const + objdata_tguirttistat: record size: integer; data: array[0..2711] of byte end = + (size: 2712; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,103,117, + 105,114,116,116,105,115,116,97,116,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,32,10,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,84,8,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,2,2,2,1,9,9,12,1,22,22, + 29,1,178,178,230,1,180,180,231,1,120,120,152,1,10,10,12,2,57,57, + 70,1,193,193,234,1,195,195,235,1,80,80,95,1,11,11,13,2,114,114, + 133,1,207,207,238,1,210,210,239,1,40,40,45,1,11,11,13,1,12,12, + 13,1,190,190,209,1,222,222,243,1,213,213,231,1,2,2,2,1,135,135, + 180,1,173,173,229,1,175,175,229,1,178,178,230,1,180,180,231,1,183,183, + 231,1,185,185,232,1,188,188,233,1,190,190,233,1,193,193,234,1,195,195, + 235,1,197,197,236,1,200,200,236,1,202,202,237,1,205,205,238,1,207,207, + 238,1,210,210,239,1,212,212,240,1,215,215,240,1,217,217,241,1,220,220, + 242,1,222,222,243,1,224,224,243,1,7,7,7,1,171,171,228,1,173,173, + 229,1,175,175,229,1,178,178,230,1,180,180,231,1,183,183,231,1,185,185, + 232,1,188,188,233,1,190,190,233,1,193,193,234,1,195,195,235,1,197,197, + 236,1,200,200,236,1,202,202,237,1,205,205,238,1,207,207,238,1,210,210, + 239,1,212,212,240,1,215,215,240,1,217,217,241,1,220,220,242,1,222,222, + 243,1,224,224,243,1,39,39,42,1,171,171,228,1,173,173,229,1,175,175, + 229,1,178,178,230,1,178,181,231,1,131,210,242,1,95,229,250,1,65,237, + 254,1,64,229,251,1,107,214,244,1,192,196,235,1,197,197,236,1,200,200, + 236,1,202,202,237,1,205,205,238,1,207,207,238,1,210,210,239,1,212,212, + 240,1,215,215,240,1,217,217,241,1,220,220,242,1,222,222,243,1,224,224, + 243,1,227,227,244,1,5,5,7,1,173,173,229,1,175,175,229,1,176,179, + 230,1,123,226,249,1,123,241,255,2,104,241,255,1,73,240,255,1,34,239, + 255,1,57,227,250,1,194,198,236,1,200,200,236,1,202,202,237,1,205,205, + 238,1,207,207,238,1,210,210,239,1,212,212,240,1,215,215,240,1,217,217, + 241,1,220,220,242,1,222,222,243,1,224,224,243,1,227,227,244,1,5,5, + 7,1,173,173,229,1,175,175,229,1,143,208,242,1,145,242,255,1,172,243, + 255,2,144,242,255,1,104,241,255,1,59,239,255,1,13,238,255,1,110,217, + 245,1,200,200,236,1,202,202,237,1,205,205,238,1,207,207,238,1,210,210, + 239,1,212,212,240,1,215,215,240,1,217,217,241,1,220,220,242,1,222,222, + 243,1,224,224,243,1,109,109,117,1,17,17,22,1,173,173,229,1,175,175, + 229,1,134,229,250,1,172,243,255,1,208,245,255,2,172,243,255,1,123,241, + 255,1,73,240,255,1,22,238,255,1,49,230,251,1,200,200,236,1,202,202, + 237,1,205,205,238,1,207,207,238,1,210,210,239,1,212,212,240,1,215,215, + 240,1,217,217,241,1,220,220,242,1,222,222,243,1,224,224,243,1,7,7, + 7,1,171,171,228,1,173,173,229,1,175,175,229,1,125,238,254,1,172,243, + 255,1,208,245,255,2,172,243,255,1,123,241,255,1,73,240,255,1,22,238, + 255,1,21,236,254,1,200,200,236,1,202,202,237,1,205,205,238,1,207,207, + 238,1,210,210,239,1,212,212,240,1,215,215,240,1,217,217,241,1,220,220, + 242,1,222,222,243,1,224,224,243,1,7,7,7,1,171,171,228,1,173,173, + 229,1,170,170,222,1,56,107,117,1,137,229,241,1,169,238,250,1,172,243, + 255,1,144,242,255,1,104,241,255,1,59,239,255,1,13,238,255,1,49,230, + 251,1,200,200,236,1,202,202,237,1,182,182,211,1,136,136,201,1,119,119, + 246,1,212,212,240,1,215,215,240,1,217,217,241,1,220,220,242,1,222,222, + 243,1,224,224,243,1,82,82,88,1,106,106,141,1,173,173,229,1,82,82, + 107,1,21,33,39,1,35,80,85,1,101,198,209,1,123,241,255,1,104,241, + 255,1,73,240,255,1,34,239,255,1,13,238,255,1,110,217,245,1,200,200, + 236,1,202,202,237,1,96,96,113,1,27,27,164,1,12,12,254,1,191,191, + 241,1,215,215,240,1,217,217,241,1,220,220,242,1,222,222,243,1,224,224, + 243,1,227,227,244,1,5,5,7,1,173,173,229,1,137,137,180,1,77,79, + 101,1,33,83,92,1,73,240,255,2,59,239,255,1,34,239,255,1,8,152, + 163,1,13,53,58,1,49,50,59,1,126,126,149,1,176,176,206,1,16,16, + 33,1,0,0,46,1,0,0,208,1,57,57,188,1,61,61,68,1,50,50, + 56,1,80,80,88,1,212,212,232,1,224,224,243,1,227,227,244,1,5,5, + 7,1,173,173,229,1,173,173,226,1,175,175,225,1,171,175,223,1,106,209, + 242,1,54,227,250,1,21,236,254,1,47,228,251,1,13,26,30,1,182,186, + 223,1,189,189,226,1,80,80,94,1,184,184,239,1,6,6,121,1,0,0, + 166,1,0,0,255,1,0,0,80,1,145,145,219,1,215,215,239,1,69,69, + 76,1,145,145,159,1,224,224,243,1,59,59,63,1,44,44,59,1,173,173, + 229,1,175,175,229,1,178,178,230,1,180,180,231,1,183,183,231,1,185,185, + 232,1,188,188,233,1,190,190,233,1,86,86,105,1,24,24,29,1,85,85, + 102,1,161,161,190,1,73,73,249,1,0,0,121,1,0,0,166,1,0,0, + 255,1,0,0,219,1,20,20,134,1,76,76,85,1,32,32,35,1,137,137, + 150,1,224,224,243,1,7,7,7,1,171,171,228,1,173,173,229,1,175,175, + 229,1,207,111,143,1,208,112,144,1,210,114,144,1,211,115,145,1,213,117, + 145,1,212,117,144,1,190,105,128,1,185,153,185,1,120,120,143,1,15,15, + 24,1,0,0,227,1,0,0,121,1,0,0,166,1,0,0,243,1,0,0, + 32,1,0,0,172,1,112,112,229,1,92,92,102,1,134,134,147,1,224,224, + 243,1,7,7,7,1,171,171,228,1,173,173,229,1,175,175,229,1,255,0, + 0,3,211,0,0,1,164,0,0,1,253,0,0,1,52,0,0,1,148,83, + 100,1,148,148,180,1,5,5,37,1,0,0,235,1,0,0,133,1,0,0, + 107,1,0,0,221,1,0,0,33,1,0,0,206,1,9,9,184,1,19,19, + 24,1,125,125,137,1,224,224,243,1,150,150,162,1,57,57,77,1,173,173, + 229,1,175,175,229,1,255,0,0,3,213,0,0,1,170,0,0,1,255,0, + 0,1,224,0,0,1,119,67,80,1,47,47,111,1,0,0,204,1,0,0, + 255,1,0,0,230,1,0,0,125,1,0,0,210,1,0,0,198,1,0,0, + 115,1,0,0,147,1,64,64,201,1,158,158,172,1,224,224,243,1,227,227, + 244,1,5,5,7,1,173,173,229,1,175,175,229,1,255,0,0,7,218,122, + 147,1,188,188,237,1,187,187,237,1,189,189,238,1,191,191,239,1,192,192, + 239,1,194,194,240,1,195,195,241,1,197,197,241,1,198,198,242,1,201,201, + 243,1,222,222,243,1,224,224,243,1,227,227,244,1,5,5,7,1,173,173, + 229,1,175,175,229,1,255,0,0,7,218,122,147,1,197,197,236,1,200,200, + 236,1,202,202,237,1,205,205,238,1,207,207,238,1,210,210,239,1,212,212, + 240,1,215,215,240,1,217,217,241,1,220,220,242,1,222,222,243,1,224,224, + 243,1,18,18,20,1,88,88,117,1,173,173,229,1,175,175,229,1,255,0, + 0,7,218,122,147,1,197,197,236,1,200,200,236,1,202,202,237,1,205,205, + 238,1,207,207,238,1,210,210,239,1,212,212,240,1,215,215,240,1,217,217, + 241,1,220,220,242,1,222,222,243,1,224,224,243,1,7,7,7,1,171,171, + 228,1,173,173,229,1,175,175,229,1,255,0,0,7,218,122,147,1,197,197, + 236,1,200,200,236,1,202,202,237,1,205,205,238,1,207,207,238,1,210,210, + 239,1,212,212,240,1,215,215,240,1,217,217,241,1,220,220,242,1,222,222, + 243,1,224,224,243,1,11,11,12,1,171,171,228,1,173,173,229,1,175,175, + 229,1,255,0,0,7,218,122,147,1,197,197,236,1,200,200,236,1,202,202, + 237,1,205,205,238,1,207,207,238,1,210,210,239,1,212,212,240,1,215,215, + 240,1,217,217,241,1,220,220,242,1,222,222,243,1,224,224,243,1,227,227, + 244,1,26,26,35,1,173,173,229,1,175,175,229,1,178,178,230,1,180,180, + 231,1,183,183,231,1,185,185,232,1,188,188,233,1,190,190,233,1,193,193, + 234,1,195,195,235,1,197,197,236,1,200,200,236,1,202,202,237,1,205,205, + 238,1,207,207,238,1,210,210,239,1,212,212,240,1,215,215,240,1,217,217, + 241,1,220,220,242,1,222,222,243,1,224,224,243,1,227,227,244,1,5,5, + 7,1,172,172,227,1,175,175,229,1,178,178,230,1,169,169,217,1,172,172, + 217,1,175,175,219,1,188,188,233,1,190,190,233,1,190,190,230,1,183,183, + 220,1,185,185,221,1,192,192,227,1,202,202,237,1,205,205,238,1,201,201, + 231,1,197,197,224,1,199,199,225,1,211,211,235,1,217,217,241,1,220,220, + 242,1,212,212,232,1,210,210,228,1,168,168,181,1,5,5,7,1,126,126, + 167,1,175,175,229,1,178,178,230,1,10,10,13,1,8,8,10,1,19,19, + 23,1,188,188,233,1,190,190,233,1,116,116,140,1,8,8,10,2,50,50, + 59,1,202,202,237,1,205,205,238,1,71,71,82,1,9,9,10,2,106,106, + 119,1,217,217,241,1,220,220,242,1,34,34,37,1,9,9,10,1,7,7, + 7,1,148,1,0,0,249,249,249,1,245,245,245,1,232,232,232,1,144,144, + 144,2,169,169,169,1,245,245,245,2,207,207,207,1,144,144,144,2,194,194, + 194,1,245,245,245,2,178,178,178,1,144,144,144,2,223,223,223,1,245,245, + 245,2,153,153,153,1,144,144,144,1,147,147,147,1,249,249,249,1,143,143, + 143,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,218,218, + 218,1,128,128,128,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255, + 255,22,128,128,128,1,248,248,248,1,255,255,255,22,173,173,173,1,233,233, + 233,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248, + 248,1,128,128,128,1,255,255,255,22,188,188,188,1,158,158,158,1,255,255, + 255,22,128,128,128,1,248,248,248,1,255,255,255,22,128,128,128,1,248,248, + 248,1,255,255,255,22,203,203,203,2,255,255,255,22,248,248,248,1,128,128, + 128,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,154,154, + 154,1,191,191,191,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255, + 255,22,128,128,128,1,248,248,248,1,255,255,255,22,236,236,236,1,169,169, + 169,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,244,244, + 244,1,128,128,128,1,255,255,255,22,128,128,128,1,221,221,221,1,255,255, + 255,22,128,128,128,1,248,248,248,1,255,255,255,22,147,147,147,1,231,231, + 231,1,132,132,132,1,112,112,112,2,238,238,238,1,242,242,242,1,226,226, + 226,1,112,112,112,2,145,145,145,1,242,242,242,2,193,193,193,1,112,112, + 112,2,177,177,177,1,242,242,242,2,156,156,156,1,112,112,112,2,214,214, + 214,1,242,242,242,1,231,231,231,1,0,0) + ); + +initialization + registerobjectdata(@objdata_tfilelistview,tbitmapcomp,'tfilelistview'); + registerobjectdata(@objdata_tdirtreeview,tbitmapcomp,'tdirtreeview'); + registerobjectdata(@objdata_tfiledialog,tbitmapcomp,'tfiledialog'); + registerobjectdata(@objdata_tfilenameedit,tbitmapcomp,'tfilenameedit'); + registerobjectdata(@objdata_tdirdropdownedit,tbitmapcomp,'tdirdropdownedit'); + registerobjectdata(@objdata_tcoloredit,tbitmapcomp,'tcoloredit'); + registerobjectdata(@objdata_tdialogstringedit,tbitmapcomp,'tdialogstringedit'); + registerobjectdata(@objdata_tmemodialogedit,tbitmapcomp,'tmemodialogedit'); + registerobjectdata(@objdata_tguirttistat,tbitmapcomp,'tguirttistat'); +end. diff --git a/mseide-msegui/lib/common/regcomponents/regeditwidgets.pas b/mseide-msegui/lib/common/regcomponents/regeditwidgets.pas new file mode 100644 index 0000000..615b2da --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regeditwidgets.pas @@ -0,0 +1,403 @@ +{ MSEide Copyright (c) 1999-2011 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regeditwidgets; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + classes,mclasses,mseedit,msedataedits,msegraphedits, + msedataimage,mselistbrowser,msecalendardatetimeedit, + msewidgetgrid,msetextedit,msedesignintf,regeditwidgets_bmp,msepropertyeditors, + msedropdownlist,mseterminal,msedrawtext,msedatanodes,{msedialog,} + msetypes,msestrings, + regwidgets,msearrayprops,typinfo,msestockobjects,msefoldedit,msebitmap,mseglob, + msestream,mserealsumedit,msedatalist,msegui,msegrids,msesumlist,mseclasses, + sysutils,regglob,msearrayutils,mseeditglob; + +type + tpropertyeditor1 = class(tpropertyeditor); + tdropdowndatacolpropertyeditor = class(tarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + titemlistpropertyeditor = class(tdatalistpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + end; + + twidgetcolelementeditor = class(tdatacoleditor) + public + function getvalue: msestring; override; + end; + + twidgetcolspropertyeditor = class(tdatacolseditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + tdataimagepropertyeditor = class(tstringpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + procedure edit; override; + function getvalue: msestring; override; + end; + + tdatalistsourcepropertyeditor = class(tstringpropertyeditor) + protected + function gettag: integer; virtual; + function getdefaultstate: propertystatesty; override; + public + function getvalues: msestringarty; override; + end; + + tsumlistsourcelevelpropertyeditor = + class(tdatalistsourcepropertyeditor) + protected + function gettag: integer; override; + public + function getvalues: msestringarty; override; + end; + + tsumlistsourceissumpropertyeditor = + class(tdatalistsourcepropertyeditor) + protected + function gettag: integer; override; + end; + + trowstatelistsourcefoldlevelpropertyeditor = + class(tdatalistsourcepropertyeditor) + protected + function gettag: integer; override; + end; + + trowstatelistsourcefoldhiddenpropertyeditor = + class(tdatalistsourcepropertyeditor) + protected + function gettag: integer; override; + end; + + trowstatelistsourceissumpropertyeditor = + class(tdatalistsourcepropertyeditor) + protected + function gettag: integer; override; + end; + + toptionswidgetpropertyeditor = class(tsetpropertyeditor) + protected + function getinvisibleitems: tintegerset; override; + end; + + toptionseditpropertyeditor = class(tsetpropertyeditor) + protected + function getinvisibleitems: tintegerset; override; + end; + + tvalueeditpropertyeditor = class(tclasselementeditor) + public + procedure navigevent(); override; + end; + + tvalueeditspropertyeditor = class(tpersistentarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + function itemgetvalue(const sender: tarrayelementeditor): msestring; + override; +// function geteditorclass: propertyeditorclassty; override; + end; + + titemvalueeditpropertyeditor = class(tcomponentpropertyeditor) + protected + function filtercomponent(const acomponent: tcomponent): boolean; override; + end; + +procedure Register; +begin + registercomponents('Edit',[twidgetgrid, + tstringedit,tmemoedit,trichmemoedit, + tintegeredit,tint64edit,trealedit,trealspinedit,trealsumedit, + tdatetimeedit, + tcalendardatetimeedit, + tbooleanedit,tbooleaneditradio, + tdatabutton,tstockglyphdatabutton, + tdataicon,tdataimage, + tslider,tprogressbar, + tfoldedit, + titemedit,tdropdownitemedit,{tmbdropdownitemedit,}ttreeitemedit, + trecordfieldedit, + thexstringedit,tpointeredit, + tdropdownlistedit,thistoryedit, + tenumedit,tenumtypeedit,tselector, + tkeystringedit, + {tstringlistedit,} + ttextedit,tundotextedit,tterminal +]); + registercomponenttabhints(['Edit'], + ['Edit widgets, twidgetgrid and widgets'+c_linefeed+ + 'which can be placed into twidgetgrid']); + registerpropertyeditor(tdropdowndatacols.classinfo,nil,'', + tdropdowndatacolpropertyeditor); + registerpropertyeditor(ttabulators.classinfo,tcustomtextedit,'tabulators', + toptionalpersistentarraypropertyeditor); + registerpropertyeditor(tcustomitemlist.classinfo,nil,'', + titemlistpropertyeditor); + registerpropertyeditor(typeinfo(twidgetcols),nil,'',twidgetcolspropertyeditor); + registerpropertyeditor(typeinfo(tintegerarrayprop),tstockglyphdatabutton,'', + tstockglypharraypropertyeditor); + registerpropertyeditor(typeinfo(string),tdataimage,'value', + tdataimagepropertyeditor); + registerpropertyeditor(typeinfo(tmaskedbitmap),tdataimage,'bitmap', + tclasspropertyeditor); + registerpropertyeditor(typeinfo(string),tdatalist,'sourcevalue', + tdatalistsourcepropertyeditor); + registerpropertyeditor(typeinfo(string),trealsumlist,'sourcelevel', + tsumlistsourcelevelpropertyeditor); + registerpropertyeditor(typeinfo(string),trealsumlist,'sourceissum', + tsumlistsourceissumpropertyeditor); + registerpropertyeditor(typeinfo(optionswidgetty),nil,'', + toptionswidgetpropertyeditor); + registerpropertyeditor(typeinfo(optionseditty),nil,'', + toptionseditpropertyeditor); + registerpropertyeditor(typeinfo(string),trowstatelist,'sourcefoldlevel', + trowstatelistsourcefoldlevelpropertyeditor); + registerpropertyeditor(typeinfo(string),trowstatelist,'sourcefoldhidden', + trowstatelistsourcefoldhiddenpropertyeditor); + registerpropertyeditor(typeinfo(string),trowstatelist,'sourceissum', + trowstatelistsourceissumpropertyeditor); + registerpropertyeditor(typeinfo(boolean),tcustomdatabutton,'visible', + trefreshbooleanpropertyeditor); + registerpropertyeditor(typeinfo(boolean),tcustomdatabutton,'enabled', + trefreshbooleanpropertyeditor); + registerpropertyeditor(typeinfo(tvalueedits),nil,'',tvalueeditspropertyeditor); + registerpropertyeditor(typeinfo(twidget),tvalueedititem,'', + titemvalueeditpropertyeditor); + registerpropertyeditor(typeinfo(msestring),tcustomrichmemoedit,'value', + trichstringpropertyeditor); +end; + +{ tdropdowndatacolpropertyeditor } + +function tdropdowndatacolpropertyeditor.geteditorclass: propertyeditorclassty; +var + obj1: tobject; +begin + pointer(obj1):= getpointervalue(); + if (obj1 is tdropdowncols) and tdropdowncols(obj1).nostreaming then begin + result:= tclasselementeditor; + end + else begin + result:= tmsestringdatalistpropertyeditor; + end; +end; + +{ titemlistpropertyeditor } + +function titemlistpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate - [ps_dialog]; +end; + +{ twidgetcolelementeditor } + +function twidgetcolelementeditor.getvalue: msestring; +var + col1: twidgetcol; +begin + col1:= twidgetcol(getpointervalue); + result:= inherited getvalue; + if col1.editwidget <> nil then begin + result:= result + msestring('<'+col1.editwidget.name+'>'); + end + else begin + result:= result + '<>'; + end; +end; + +{ twidgetcolspropertyeditor } + +function twidgetcolspropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= twidgetcolelementeditor; +end; + +{ tdataimagepropertyeditor } + +function tdataimagepropertyeditor.getvalue: msestring; +begin + if tcustomdataimage(fcomponent).bitmap.isempty then begin + result:= ''; + end + else begin + result:= ''; + end; +end; + +function tdataimagepropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_dialog]; +end; + +procedure tdataimagepropertyeditor.edit; +var + mstr1: filenamety; + format1: string; + int1: integer; +begin + if imagefilepropedit(mstr1,format1) = mr_ok then begin + for int1:= 0 to high(fprops) do begin + tdataimage(fprops[int1].instance).value:= readfiledatastring(mstr1); + end; + modified; + end; +end; + +{ tdatalistsourcepropertyeditor } + +function tdatalistsourcepropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_valuelist,ps_sortlist]; +end; + +function tdatalistsourcepropertyeditor.getvalues: msestringarty; +var + int1: integer; +begin + result:= nil; + if fcomponent is tcustomgrid then begin + with tcustomgrid(fcomponent).datacols do begin + for int1:= 0 to count -1 do begin + with cols[int1] do begin + if (name <> '') and + (tdatalist(fprops[0].instance).canlink(datalist,gettag)) then begin + additem(result,msestring(name)); + end; + end; + end; + end; + end; +end; + +function tdatalistsourcepropertyeditor.gettag: integer; +begin + result:= 0; +end; + +{ tsumlistsourcelevelpropertyeditor } + +function tsumlistsourcelevelpropertyeditor.getvalues: msestringarty; +begin + result:= inherited getvalues; +// additem(result,foldlevelsumname); +end; + +function tsumlistsourcelevelpropertyeditor.gettag: integer; +begin + result:= sumleveltag; +end; + +{ tsumlistsourceissumpropertyeditor } + +function tsumlistsourceissumpropertyeditor.gettag: integer; +begin + result:= sumissumtag; +end; + +{ toptionswidgetpropertyeditor } + +function toptionswidgetpropertyeditor.getinvisibleitems: tintegerset; +begin + result:= invisibleoptionswidget; +end; + +{ toptionseditpropertyeditor } + +function toptionseditpropertyeditor.getinvisibleitems: tintegerset; +begin + result:= invisibleoptionsedit; +end; + +{ trowstatelistsourcefoldlevelpropertyeditor } + +function trowstatelistsourcefoldlevelpropertyeditor.gettag: integer; +begin + result:= rowstatefoldleveltag; +end; + +{ trowstatelistsourceissumpropertyeditor } + +function trowstatelistsourceissumpropertyeditor.gettag: integer; +begin + result:= rowstateissumtag; +end; + +{ trowstatelistsourcefoldhiddenpropertyeditor } + +function trowstatelistsourcefoldhiddenpropertyeditor.gettag: integer; +begin + result:= rowstatefoldhiddentag; +end; + +{ titemvalueeditpropertyeditor } + +function titemvalueeditpropertyeditor.filtercomponent( + const acomponent: tcomponent): boolean; +var + intf1: igridwidget; +begin + result:= (acomponent is twidget) and + ((twidget(acomponent).parentwidget) = + tvalueedititem(tpropertyeditor1(parenteditor).getpointervalue()).owner) and + getcorbainterface(acomponent,typeinfo(igridwidget),intf1); +end; + +function tvalueeditspropertyeditor.itemgetvalue( + const sender: tarrayelementeditor): msestring; +begin + with tvalueedititem( + tpropertyeditor1(sender.valueeditor).getpointervalue()) do begin + if editwidget <> nil then begin + result:= msestring('<'+inttostr(valueindex)+'>'+'<'+editwidget.name+'>'); + end + else begin + result:= '<>'; + end; + end; +end; + +function tvalueeditspropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tvalueeditpropertyeditor; +end; + +{ tvalueeditpropertyeditor } + +procedure tvalueeditpropertyeditor.navigevent; +begin + with tvalueedititem(getpointervalue()) do begin + if editwidget <> nil then begin + editwidget.bringtofront(); + end; + end; +end; + +initialization + register; +end. diff --git a/mseide-msegui/lib/common/regcomponents/regeditwidgets_bmp.pas b/mseide-msegui/lib/common/regcomponents/regeditwidgets_bmp.pas new file mode 100644 index 0000000..418388d --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regeditwidgets_bmp.pas @@ -0,0 +1,1974 @@ +unit regeditwidgets_bmp; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msebitmap; + +const + objdata_twidgetgrid: record size: integer; data: array[0..1350] of byte end = + (size: 1351; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,119,105, + 100,103,101,116,103,114,105,100,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,208,4,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,140,4,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,128,128,128,25,208,208,208,2,128,128,128, + 1,208,208,208,2,112,112,112,1,153,153,153,1,171,171,171,1,165,165,165, + 1,118,118,118,1,184,184,184,1,208,208,208,2,128,128,128,1,208,208,208, + 2,154,154,154,1,148,148,148,1,190,190,190,1,186,186,186,1,148,148,148, + 1,208,208,208,1,255,255,255,1,128,128,128,1,208,208,208,2,128,128,128, + 1,208,208,208,1,179,179,179,1,142,142,142,1,116,116,116,1,148,148,148, + 1,141,141,141,1,121,121,121,1,128,128,128,1,208,208,208,2,128,128,128, + 1,208,208,208,2,144,144,144,2,131,131,131,1,146,146,146,1,165,165,165, + 1,208,208,208,1,255,255,255,1,128,128,128,1,208,208,208,2,128,128,128, + 1,208,208,208,4,175,175,175,1,176,176,176,1,208,208,208,4,128,128,128, + 1,208,208,208,2,186,186,186,1,183,183,183,1,187,187,187,1,191,191,191, + 1,197,197,197,1,208,208,208,1,255,255,255,1,128,128,128,23,255,255,255, + 1,128,128,128,1,208,208,208,2,128,128,128,1,255,255,255,1,169,169,169, + 1,183,183,183,1,202,202,202,1,215,215,215,1,225,225,225,1,255,255,255, + 4,128,128,128,1,255,255,255,2,243,243,243,1,169,169,169,1,204,204,204, + 1,179,179,179,1,139,139,139,1,255,255,255,2,128,128,128,1,208,208,208, + 2,128,128,128,1,255,255,255,1,151,151,151,1,160,160,160,1,155,155,155, + 1,201,201,201,1,225,225,225,1,255,255,255,4,128,128,128,1,255,255,255, + 3,191,191,191,1,150,150,150,1,202,202,202,1,158,158,158,1,251,251,251, + 1,255,255,255,1,128,128,128,1,208,208,208,2,128,128,128,1,255,255,255, + 1,237,237,237,1,233,233,233,1,228,228,228,1,213,213,213,1,222,222,222, + 1,255,255,255,4,128,128,128,1,255,255,255,9,128,128,128,23,255,255,255, + 1,128,128,128,1,208,208,208,2,128,128,128,1,255,255,255,1,206,206,206, + 1,168,168,168,1,211,211,211,1,238,238,238,1,226,226,226,1,242,242,242, + 1,191,191,191,1,201,201,201,1,251,251,251,1,128,128,128,1,255,255,255, + 4,176,176,176,2,129,129,129,1,255,255,255,2,128,128,128,1,208,208,208, + 2,128,128,128,1,255,255,255,1,181,181,181,1,236,236,236,1,145,145,145, + 1,170,170,170,1,181,181,181,1,162,162,162,1,190,190,190,1,185,185,185, + 1,255,255,255,1,128,128,128,1,255,255,255,4,186,186,186,1,211,211,211, + 1,159,159,159,1,255,255,255,2,128,128,128,1,208,208,208,2,128,128,128, + 1,255,255,255,1,199,199,199,1,210,210,210,1,209,209,209,1,237,237,237, + 1,238,238,238,1,235,235,235,1,220,220,220,1,199,199,199,1,248,248,248, + 1,128,128,128,1,255,255,255,9,128,128,128,23,255,255,255,1,128,128,128, + 1,208,208,208,2,128,128,128,1,255,255,255,1,197,197,197,1,177,177,177, + 1,221,221,221,1,255,255,255,6,128,128,128,1,255,255,255,4,169,169,169, + 1,158,158,158,1,157,157,157,1,255,255,255,2,128,128,128,1,208,208,208, + 2,128,128,128,1,255,255,255,1,176,176,176,1,190,190,190,1,181,181,181, + 1,255,255,255,6,128,128,128,1,255,255,255,4,178,178,178,1,161,161,161, + 1,158,158,158,1,255,255,255,2,128,128,128,1,208,208,208,2,128,128,128, + 1,255,255,255,1,235,235,235,1,217,217,217,1,239,239,239,1,255,255,255, + 6,128,128,128,1,255,255,255,9,128,128,128,23,255,255,255,1,128,128,128, + 1,208,208,208,2,128,128,128,1,255,255,255,1,174,174,174,1,177,177,177, + 1,201,201,201,1,232,232,232,1,221,221,221,1,182,182,182,1,212,212,212, + 1,255,255,255,2,128,128,128,1,255,255,255,2,228,228,228,1,163,163,163, + 1,191,191,191,1,184,184,184,1,139,139,139,1,255,255,255,2,128,128,128, + 1,208,208,208,2,128,128,128,1,255,255,255,1,158,158,158,1,207,207,207, + 1,120,120,120,1,176,176,176,1,175,175,175,1,183,183,183,1,142,142,142, + 1,255,255,255,2,128,128,128,1,255,255,255,2,212,212,212,1,152,152,152, + 1,204,204,204,1,178,178,178,1,158,158,158,1,251,251,251,1,255,255,255, + 1,128,128,128,1,208,208,208,2,128,128,128,1,255,255,255,1,237,237,237, + 1,255,255,255,1,239,239,239,1,203,203,203,1,166,166,166,1,239,239,239, + 1,180,180,180,1,255,255,255,2,128,128,128,1,255,255,255,9,128,128,128, + 23,255,255,255,1,128,128,128,1,208,208,208,2,128,128,128,1,255,255,255, + 1,199,199,199,2,226,226,226,1,228,228,228,1,233,233,233,1,255,255,255, + 4,128,128,128,1,255,255,255,4,172,172,172,1,197,197,197,1,137,137,137, + 1,255,255,255,2,128,128,128,1,208,208,208,2,128,128,128,1,255,255,255, + 1,183,183,183,1,176,176,176,1,183,183,183,1,173,173,173,1,130,130,130, + 1,255,255,255,4,128,128,128,1,255,255,255,4,208,208,208,1,215,215,215, + 1,168,168,168,1,254,254,254,1,255,255,255,25,12,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tdataedit: record size: integer; data: array[0..429] of byte end = + (size: 430; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,100,97, + 116,97,101,100,105,116,12,98,105,116,109,97,112,46,105,109,97,103,101,10, + 128,1,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0,0,0, + 76,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,255,146, + 128,128,128,20,255,0,255,4,128,128,128,1,0,0,0,18,255,255,255,1, + 255,0,255,4,128,128,128,1,0,0,0,1,255,255,255,16,192,192,192,1, + 255,255,255,1,255,0,255,4,128,128,128,1,0,0,0,1,255,255,255,13, + 0,0,0,1,255,255,255,1,0,0,0,1,192,192,192,1,255,255,255,1, + 255,0,255,4,128,128,128,1,0,0,0,1,255,255,255,14,0,0,0,1, + 255,255,255,1,192,192,192,1,255,255,255,1,255,0,255,4,128,128,128,1, + 0,0,0,1,255,255,255,14,0,0,0,1,255,255,255,1,192,192,192,1, + 255,255,255,1,255,0,255,4,128,128,128,1,0,0,0,1,255,255,255,14, + 0,0,0,1,255,255,255,1,192,192,192,1,255,255,255,1,255,0,255,4, + 128,128,128,1,0,0,0,1,255,255,255,14,0,0,0,1,255,255,255,1, + 192,192,192,1,255,255,255,1,255,0,255,4,128,128,128,1,0,0,0,1, + 255,255,255,14,0,0,0,1,255,255,255,1,192,192,192,1,255,255,255,1, + 255,0,255,4,128,128,128,1,0,0,0,1,255,255,255,13,0,0,0,1, + 255,255,255,1,0,0,0,1,192,192,192,1,255,255,255,1,255,0,255,4, + 128,128,128,1,0,0,0,1,255,255,255,16,192,192,192,1,255,255,255,1, + 255,0,255,4,128,128,128,1,192,192,192,18,255,255,255,1,255,0,255,4, + 255,255,255,20,255,0,255,122,0,0) + ); + +const + objdata_ttextedit: record size: integer; data: array[0..1624] of byte end = + (size: 1625; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,116,101, + 120,116,101,100,105,116,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,228,5,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,152,5,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,128,128,128,25,0,0,0,22,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,1,140,140,140,1,148,148,148,1,226, + 226,226,1,209,209,209,1,222,222,222,2,175,175,175,1,242,242,242,1,132, + 132,132,1,210,210,210,1,215,215,215,1,226,226,226,1,190,190,190,1,209, + 209,209,1,165,165,165,1,210,210,210,1,208,208,208,1,255,255,255,2,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,138, + 138,138,1,183,183,183,1,190,190,190,1,133,133,133,1,179,179,179,1,177, + 177,177,1,183,183,183,1,255,255,255,1,154,154,154,1,192,192,192,1,140, + 140,140,1,180,180,180,1,195,195,195,1,213,213,213,1,156,156,156,1,169, + 169,169,1,155,155,155,1,255,255,255,2,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,1,211,211,211,1,255,255,255,1,208, + 208,208,1,178,178,178,1,204,204,204,1,205,205,205,1,200,200,200,1,255, + 255,255,1,202,202,202,1,231,231,231,1,191,191,191,1,219,219,219,1,203, + 203,203,1,234,234,234,1,220,220,220,1,183,183,183,1,167,167,167,1,255, + 255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,6,193,193,193,1,209,209,209,1,220,220,220,1,255,255,255,1,195, + 195,195,1,255,255,255,4,224,224,224,1,255,255,255,1,232,232,232,1,255, + 255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,1,175,175,175,2,170,170,170,1,204,204,204,2,222,222,222,1,170, + 170,170,1,159,159,159,1,193,193,193,1,149,149,149,1,151,151,151,1,178, + 178,178,1,191,191,191,1,202,202,202,1,145,145,145,1,255,255,255,4,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,164, + 164,164,1,151,151,151,1,118,118,118,1,223,223,223,1,226,226,226,1,162, + 162,162,1,149,149,149,1,159,159,159,1,171,171,171,1,175,175,175,2,131, + 131,131,1,178,178,178,1,134,134,134,1,176,176,176,1,255,255,255,4,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,197, + 197,197,1,199,199,199,1,255,255,255,3,254,254,254,1,255,255,255,13,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,124, + 124,124,1,216,216,216,1,229,229,229,1,209,209,209,1,226,226,226,1,247, + 247,247,1,238,238,238,1,212,212,212,1,182,182,182,1,178,178,178,1,236, + 236,236,1,217,217,217,1,137,137,137,1,213,213,213,1,207,207,207,1,186, + 186,186,1,255,255,255,3,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,1,175,175,175,1,169,169,169,1,163,163,163,1,164, + 164,164,1,156,156,156,1,137,137,137,1,229,229,229,1,166,166,166,1,254, + 254,254,1,166,166,166,1,176,176,176,1,177,177,177,1,156,156,156,1,192, + 192,192,1,188,188,188,1,173,173,173,1,255,255,255,3,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,215,215,215,1,167, + 167,167,1,157,157,157,1,184,184,184,1,202,202,202,1,152,152,152,1,255, + 255,255,1,244,244,244,1,177,177,177,1,212,212,212,1,206,206,206,1,242, + 242,242,1,203,203,203,1,236,236,236,1,184,184,184,1,214,214,214,1,255, + 255,255,3,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,1,197,197,197,1,160,160,160,1,214,214,214,1,218,218,218,1,255, + 255,255,2,253,253,253,1,255,255,255,1,216,216,216,1,145,145,145,1,222, + 222,222,1,255,255,255,1,228,228,228,1,255,255,255,2,0,0,0,1,255, + 255,255,1,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,1,176,176,176,1,145,145,145,1,150, + 150,150,1,175,175,175,1,168,168,168,1,175,175,175,1,110,110,110,1,216, + 216,216,1,255,255,255,1,175,175,175,1,231,231,231,1,122,122,122,1,173, + 173,173,1,255,255,255,3,0,0,0,1,255,255,255,2,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,185,185,185,1,235, + 235,235,1,166,166,166,1,195,195,195,1,182,182,182,1,188,188,188,1,177, + 177,177,1,203,203,203,1,255,255,255,1,195,195,195,1,200,200,200,1,169, + 169,169,1,171,171,171,1,255,255,255,3,0,0,0,1,255,255,255,2,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,242, + 242,242,1,255,255,255,3,235,235,235,1,240,240,240,1,255,255,255,6,208, + 208,208,1,255,255,255,3,0,0,0,1,255,255,255,2,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,175,175,175,1,226, + 226,226,1,221,221,221,1,222,222,222,1,132,132,132,1,175,175,175,1,183, + 183,183,1,216,216,216,1,189,189,189,1,196,196,196,1,213,213,213,1,255, + 255,255,5,0,0,0,1,255,255,255,2,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,1,183,183,183,1,126,126,126,1,238, + 238,238,1,163,163,163,1,154,154,154,1,149,149,149,1,195,195,195,1,152, + 152,152,1,221,221,221,1,169,169,169,1,184,184,184,1,255,255,255,5,0, + 0,0,1,255,255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,1,234,234,234,1,162,162,162,1,255,255,255,1,234, + 234,234,1,255,255,255,1,217,217,217,1,215,215,215,1,246,246,246,1,214, + 214,214,1,219,219,219,1,232,232,232,1,255,255,255,5,0,0,0,1,255, + 255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,16,0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,20,224, + 224,224,1,255,255,255,1,128,128,128,1,224,224,224,22,255,255,255,25,20, + 0,0,0,255,255,255,255,255,255,255,255,255,255,255,42,128,128,128,1,255, + 255,255,23,0,0) + ); + +const + objdata_tundotextedit: record size: integer; data: array[0..1608] of byte end = + (size: 1609; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,117,110, + 100,111,116,101,120,116,101,100,105,116,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,208,5,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,132,5,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,0,0,0,22,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,140,140,140,1,148, + 148,148,1,226,226,226,1,209,209,209,1,222,222,222,2,175,175,175,1,242, + 242,242,1,132,132,132,1,210,210,210,1,215,215,215,1,226,226,226,1,190, + 190,190,1,209,209,209,1,165,165,165,1,210,210,210,1,208,208,208,1,255, + 255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,1,138,138,138,1,183,183,183,1,190,190,190,1,133,133,133,1,179, + 179,179,1,177,177,177,1,183,183,183,1,255,255,255,1,154,154,154,1,192, + 192,192,1,140,140,140,1,180,180,180,1,195,195,195,1,213,213,213,1,156, + 156,156,1,169,169,169,1,155,155,155,1,255,255,255,2,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,211,211,211,1,255, + 255,255,1,21,21,218,1,16,16,215,1,18,18,217,1,191,191,206,1,200, + 200,200,1,255,255,255,1,202,202,202,1,231,231,231,1,188,188,191,1,20, + 20,219,1,18,18,217,1,21,21,220,1,212,212,220,1,183,183,183,1,167, + 167,167,1,255,255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,3,2,2,219,1,0,0,219,2,179,179,194,1,209, + 209,209,1,220,220,220,1,255,255,255,1,195,195,195,1,250,250,254,1,0, + 0,219,3,215,215,224,1,255,255,255,1,232,232,232,1,255,255,255,2,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,175, + 175,175,2,1,1,218,1,0,0,219,2,206,206,221,1,170,170,170,1,159, + 159,159,1,193,193,193,1,149,149,149,1,148,148,152,1,0,0,219,3,139, + 139,148,1,255,255,255,4,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,1,164,164,164,1,151,151,151,1,1,1,218,1,0, + 0,219,2,151,151,166,1,149,149,149,1,159,159,159,1,171,171,171,1,175, + 175,175,1,172,172,176,1,0,0,219,3,169,169,178,1,255,255,255,4,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,197, + 197,197,1,199,199,199,1,2,2,219,1,0,0,219,2,236,236,251,1,255, + 255,255,4,250,250,254,1,0,0,219,3,245,245,254,1,255,255,255,4,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,124, + 124,124,1,216,216,216,1,2,2,219,1,0,0,219,2,230,230,245,1,238, + 238,238,1,212,212,212,1,182,182,182,1,178,178,178,1,231,231,235,1,0, + 0,219,3,199,199,208,1,186,186,186,1,255,255,255,3,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,175,175,175,1,169, + 169,169,1,1,1,218,1,0,0,219,2,127,127,142,1,229,229,229,1,166, + 166,166,1,254,254,254,1,166,166,166,1,173,173,177,1,0,0,219,3,181, + 181,190,1,173,173,173,1,255,255,255,3,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,1,215,215,215,1,167,167,167,1,2, + 2,218,1,0,0,219,2,141,141,157,1,255,255,255,1,244,244,244,1,177, + 177,177,1,212,212,212,1,202,202,206,1,0,0,219,3,178,178,185,1,214, + 214,214,1,255,255,255,3,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,1,197,197,197,1,160,160,160,1,18,18,219,1,0, + 0,219,2,229,229,251,1,253,253,253,1,255,255,255,1,216,216,216,1,145, + 145,145,1,212,212,222,1,0,0,219,2,6,6,220,1,255,255,255,1,0, + 0,0,1,255,255,255,1,0,0,0,1,255,255,255,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,176,176,176,1,145, + 145,145,1,25,25,207,1,0,0,219,2,150,150,181,1,110,110,110,1,216, + 216,216,1,255,255,255,1,175,175,175,1,208,208,229,1,0,0,219,2,24, + 24,222,1,255,255,255,2,0,0,0,1,255,255,255,2,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,185,185,185,1,235, + 235,235,1,43,43,205,1,0,0,219,2,108,108,201,1,177,177,177,1,203, + 203,203,1,255,255,255,1,195,195,195,1,144,144,205,1,0,0,219,2,41, + 41,225,1,255,255,255,2,0,0,0,1,255,255,255,2,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,242,242,242,1,255, + 255,255,1,121,121,236,1,0,0,219,2,10,10,220,1,161,161,242,1,230, + 230,251,1,242,242,253,1,181,181,245,1,36,36,224,1,0,0,219,2,102, + 102,233,1,255,255,255,2,0,0,0,1,255,255,255,2,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,175,175,175,1,226, + 226,226,1,206,206,221,1,18,18,219,1,0,0,219,4,2,2,218,1,0, + 0,219,3,7,7,220,1,225,225,251,1,255,255,255,2,0,0,0,1,255, + 255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,1,183,183,183,1,126,126,126,1,238,238,238,1,145,145,169,1,40, + 40,201,1,0,0,219,6,52,52,226,1,210,210,249,1,255,255,255,3,0, + 0,0,1,255,255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,1,234,234,234,1,162,162,162,1,255,255,255,1,234, + 234,234,1,255,255,255,1,192,192,217,1,160,160,216,1,148,148,236,1,118, + 118,216,1,153,153,219,1,197,197,230,1,253,253,255,1,255,255,255,4,0, + 0,0,1,255,255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,16,0,0,0,1,255,255,255,1,0,0,0,1,255, + 255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,20,224,224,224,1,255,255,255,1,128,128,128,1,224,224,224,22,255, + 255,255,25,20,0,0,0,255,255,255,255,255,255,255,255,255,255,255,42,128, + 128,128,1,255,255,255,23,0,0) + ); + +const + objdata_tslider: record size: integer; data: array[0..1106] of byte end = + (size: 1107; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,7,116,115,108, + 105,100,101,114,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114, + 101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112, + 46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100, + 13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109, + 97,112,46,105,109,97,103,101,10,224,3,0,0,0,0,0,0,6,0,0, + 0,24,0,0,0,24,0,0,0,152,3,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,255,255,255,120,128,128,128,25,0,0,0,22,255,255,255, + 1,128,128,128,1,0,0,0,1,208,208,208,1,255,255,255,1,208,208,208, + 1,249,249,249,1,208,208,208,1,255,255,255,1,208,208,208,1,248,248,248, + 1,209,209,209,1,255,255,255,5,208,208,208,1,252,252,252,1,212,212,212, + 1,251,251,251,1,208,208,208,1,251,251,251,1,225,225,225,1,255,255,255, + 1,128,128,128,1,0,0,0,1,255,255,255,1,209,209,209,1,249,249,249, + 1,214,214,214,1,255,255,255,1,208,208,208,1,247,247,247,1,217,217,217, + 1,251,251,251,1,255,255,255,1,227,227,227,3,138,138,138,1,247,247,247, + 1,208,208,208,1,247,247,247,1,215,215,215,1,255,255,255,1,211,211,211, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,208,208,208, + 1,255,255,255,1,212,212,212,1,248,248,248,1,212,212,212,1,248,248,248, + 1,216,216,216,1,249,249,249,1,212,212,212,1,255,255,255,1,218,218,218, + 3,129,129,129,1,213,213,213,1,252,252,252,1,212,212,212,1,255,255,255, + 1,208,208,208,1,255,255,255,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,255,255,255,1,208,208,208,1,248,248,248,1,215,215,215, + 1,255,255,255,1,211,211,211,1,255,255,255,1,211,211,211,1,255,255,255, + 2,208,208,208,3,128,128,128,1,255,255,255,1,209,209,209,1,255,255,255, + 1,208,208,208,1,252,252,252,1,211,211,211,1,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,208,208,208,1,255,255,255,1,211,211,211, + 1,254,254,254,1,209,209,209,1,251,251,251,1,212,212,212,1,249,249,249, + 1,211,211,211,1,255,255,255,1,199,199,199,3,128,128,128,1,208,208,208, + 1,255,255,255,1,208,208,208,1,255,255,255,1,208,208,208,1,249,249,249, + 1,228,228,228,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255, + 1,209,209,209,1,254,254,254,1,208,208,208,1,255,255,255,1,208,208,208, + 1,255,255,255,1,211,211,211,1,247,247,247,1,255,255,255,1,190,190,190, + 3,128,128,128,1,248,248,248,1,212,212,212,1,251,251,251,1,212,212,212, + 1,255,255,255,1,208,208,208,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,208,208,208,1,255,255,255,1,208,208,208,1,251,251,251, + 1,212,212,212,1,255,255,255,1,208,208,208,1,255,255,255,1,211,211,211, + 1,255,255,255,1,180,180,180,3,128,128,128,1,211,211,211,1,251,251,251, + 1,209,209,209,1,248,248,248,1,215,215,215,1,249,249,249,1,228,228,228, + 1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,208,208,208, + 1,255,255,255,1,208,208,208,1,255,255,255,1,208,208,208,1,255,255,255, + 1,208,208,208,1,255,255,255,2,171,171,171,3,128,128,128,1,254,254,254, + 1,212,212,212,1,255,255,255,1,208,208,208,1,255,255,255,1,209,209,209, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,208,208,208, + 1,255,255,255,1,208,208,208,1,255,255,255,1,209,209,209,1,255,255,255, + 1,209,209,209,1,255,255,255,1,208,208,208,1,255,255,255,1,167,167,167, + 3,128,128,128,1,208,208,208,1,255,255,255,1,208,208,208,1,255,255,255, + 1,208,208,208,1,251,251,251,1,226,226,226,1,255,255,255,1,128,128,128, + 1,0,0,0,1,255,255,255,1,211,211,211,1,248,248,248,1,208,208,208, + 1,249,249,249,1,212,212,212,1,249,249,249,1,212,212,212,1,249,249,249, + 1,131,131,131,1,128,128,128,4,252,252,252,1,209,209,209,1,252,252,252, + 1,209,209,209,1,255,255,255,1,208,208,208,1,224,224,224,1,255,255,255, + 1,128,128,128,1,224,224,224,3,227,227,227,1,224,224,224,5,227,227,227, + 1,224,224,224,5,225,225,225,1,224,224,224,1,225,225,225,1,224,224,224, + 4,255,255,255,145,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255, + 81,0,0,0,120,0,0) + ); + +const + objdata_tbooleanedit: record size: integer; data: array[0..488] of byte end = + (size: 489; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,98,111, + 111,108,101,97,110,101,100,105,116,12,98,105,116,109,97,112,46,105,109,97, + 103,101,10,184,1,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24, + 0,0,0,132,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255, + 0,255,125,128,128,128,14,255,0,255,10,128,128,128,1,0,0,0,12,255, + 255,255,1,255,0,255,10,128,128,128,1,0,0,0,1,255,255,255,10,192, + 192,192,1,255,255,255,1,255,0,255,10,128,128,128,1,0,0,0,1,255, + 255,255,1,0,0,0,2,255,255,255,4,0,0,0,2,255,255,255,1,192, + 192,192,1,255,255,255,1,255,0,255,10,128,128,128,1,0,0,0,1,255, + 255,255,1,0,0,0,3,255,255,255,2,0,0,0,3,255,255,255,1,192, + 192,192,1,255,255,255,1,255,0,255,10,128,128,128,1,0,0,0,1,255, + 255,255,2,0,0,0,6,255,255,255,2,192,192,192,1,255,255,255,1,255, + 0,255,10,128,128,128,1,0,0,0,1,255,255,255,3,0,0,0,4,255, + 255,255,3,192,192,192,1,255,255,255,1,255,0,255,10,128,128,128,1,0, + 0,0,1,255,255,255,3,0,0,0,4,255,255,255,3,192,192,192,1,255, + 255,255,1,255,0,255,10,128,128,128,1,0,0,0,1,255,255,255,2,0, + 0,0,6,255,255,255,2,192,192,192,1,255,255,255,1,255,0,255,10,128, + 128,128,1,0,0,0,1,255,255,255,1,0,0,0,3,255,255,255,2,0, + 0,0,3,255,255,255,1,192,192,192,1,255,255,255,1,255,0,255,10,128, + 128,128,1,0,0,0,1,255,255,255,1,0,0,0,2,255,255,255,4,0, + 0,0,2,255,255,255,1,192,192,192,1,255,255,255,1,255,0,255,10,128, + 128,128,1,0,0,0,1,255,255,255,10,192,192,192,1,255,255,255,1,255, + 0,255,10,128,128,128,1,192,192,192,12,255,255,255,1,255,0,255,10,255, + 255,255,14,255,0,255,125,0,0) + ); + +const + objdata_tbooleaneditradio: record size: integer; data: array[0..445] of byte end = + (size: 446; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,98,111, + 111,108,101,97,110,101,100,105,116,114,97,100,105,111,12,98,105,116,109,97, + 112,46,105,109,97,103,101,10,136,1,0,0,0,0,0,0,0,0,0,0, + 24,0,0,0,24,0,0,0,84,1,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,255,0,255,125,128,128,128,14,255,0,255,10,128,128,128,1, + 0,0,0,12,255,255,255,1,255,0,255,10,128,128,128,1,0,0,0,1, + 255,255,255,10,192,192,192,1,255,255,255,1,255,0,255,10,128,128,128,1, + 0,0,0,1,255,255,255,10,192,192,192,1,255,255,255,1,255,0,255,10, + 128,128,128,1,0,0,0,1,255,255,255,4,0,0,0,2,255,255,255,4, + 192,192,192,1,255,255,255,1,255,0,255,10,128,128,128,1,0,0,0,1, + 255,255,255,3,0,0,0,4,255,255,255,3,192,192,192,1,255,255,255,1, + 255,0,255,10,128,128,128,1,0,0,0,1,255,255,255,2,0,0,0,6, + 255,255,255,2,192,192,192,1,255,255,255,1,255,0,255,10,128,128,128,1, + 0,0,0,1,255,255,255,2,0,0,0,6,255,255,255,2,192,192,192,1, + 255,255,255,1,255,0,255,10,128,128,128,1,0,0,0,1,255,255,255,3, + 0,0,0,4,255,255,255,3,192,192,192,1,255,255,255,1,255,0,255,10, + 128,128,128,1,0,0,0,1,255,255,255,4,0,0,0,2,255,255,255,4, + 192,192,192,1,255,255,255,1,255,0,255,10,128,128,128,1,0,0,0,1, + 255,255,255,10,192,192,192,1,255,255,255,1,255,0,255,10,128,128,128,1, + 0,0,0,1,255,255,255,10,192,192,192,1,255,255,255,1,255,0,255,10, + 128,128,128,1,192,192,192,12,255,255,255,1,255,0,255,10,255,255,255,14, + 255,0,255,125,0,0) + ); + +const + objdata_tdataicon: record size: integer; data: array[0..1320] of byte end = + (size: 1321; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,100,97, + 116,97,105,99,111,110,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,180,4,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,88,3,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,171,171,171,1,128,128,128,1,171,171,171,20,128, + 128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171, + 171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128, + 128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171, + 171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128, + 128,128,1,171,171,171,1,128,128,128,24,171,171,171,1,128,128,128,1,255, + 255,255,20,128,128,128,1,171,171,171,2,128,128,128,1,255,255,255,5,255, + 244,240,1,254,228,218,1,251,213,198,1,247,201,182,1,243,186,164,1,239, + 180,153,1,238,181,155,1,237,183,159,1,239,197,178,1,248,230,222,1,255, + 255,254,1,255,255,255,4,128,128,128,1,171,171,171,2,128,128,128,1,255, + 255,255,3,255,243,239,1,254,214,198,1,250,200,179,1,246,192,169,1,243, + 184,159,1,239,176,149,1,235,168,139,1,231,160,129,1,227,152,119,1,223, + 144,109,1,219,136,98,1,215,128,88,1,218,137,101,1,243,219,208,1,255, + 255,255,3,128,128,128,1,171,171,171,2,128,128,128,1,255,255,255,2,255, + 238,231,1,250,200,181,1,247,192,170,1,243,184,160,1,239,177,150,1,235, + 168,140,1,231,161,129,1,227,153,119,1,223,145,109,1,220,137,99,1,216, + 129,89,1,212,121,79,1,208,113,69,1,204,105,58,1,200,98,50,1,233, + 194,176,1,255,255,255,2,128,128,128,1,171,171,171,2,128,128,128,1,255, + 255,255,2,248,203,185,1,243,185,160,1,239,177,150,1,235,169,140,1,231, + 161,130,1,228,153,120,1,224,145,110,1,220,137,100,1,216,129,89,1,212, + 121,79,1,208,113,69,1,204,105,59,1,200,97,49,1,197,89,39,1,193, + 82,29,1,200,104,59,1,255,255,255,2,128,128,128,1,171,171,171,2,128, + 128,128,1,255,255,255,2,243,196,176,1,236,169,141,1,232,162,131,1,228, + 154,120,1,224,146,110,1,220,138,100,1,216,130,90,1,212,122,80,1,208, + 114,70,1,205,106,60,1,201,98,50,1,197,90,39,1,193,82,29,1,189, + 74,19,1,185,66,9,1,200,107,62,1,255,255,255,2,128,128,128,1,171, + 171,171,2,128,128,128,1,255,255,255,2,249,231,223,1,229,160,128,1,224, + 146,111,1,220,138,101,1,216,130,91,1,213,122,81,1,209,114,70,1,205, + 106,60,1,201,98,50,1,197,90,40,1,193,82,30,1,189,74,20,1,185, + 67,10,1,182,59,0,1,186,70,14,1,236,205,190,1,255,255,255,2,128, + 128,128,1,171,171,171,2,128,128,128,1,255,255,255,3,250,240,235,1,228, + 166,138,1,214,125,84,1,209,115,71,1,205,107,61,1,201,99,51,1,197, + 91,41,1,193,83,31,1,189,75,20,1,186,67,10,1,182,59,0,1,183, + 62,4,1,203,115,73,1,246,230,222,1,255,255,255,3,128,128,128,1,171, + 171,171,2,128,128,128,1,255,255,255,5,251,244,241,1,235,196,179,1,222, + 162,134,1,215,141,107,1,205,118,76,1,202,111,68,1,207,126,87,1,214, + 144,111,1,228,181,159,1,250,240,236,1,255,255,255,5,128,128,128,1,171, + 171,171,2,128,128,128,1,255,255,255,20,128,128,128,1,171,171,171,1,128, + 128,128,24,171,171,171,1,128,128,128,1,171,171,171,20,128,128,128,1,171, + 171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128, + 128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171, + 171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128, + 128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171, + 171,171,1,36,1,0,0,0,0,0,1,255,255,255,1,0,0,0,20,255, + 255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0, + 0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255, + 255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0, + 0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255, + 255,255,1,0,0,0,1,255,255,255,24,0,0,0,1,255,255,255,22,0, + 0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255, + 255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0, + 0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255, + 255,255,22,0,0,0,2,255,255,255,22,0,0,0,1,255,255,255,24,0, + 0,0,1,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255, + 255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0, + 0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255, + 255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0, + 0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0,1,0, + 0) + ); + +const + objdata_tdataimage: record size: integer; data: array[0..1737] of byte end = + (size: 1738; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,100,97, + 116,97,105,109,97,103,101,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,84,6,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,168,4,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,171,171,171,1,128,128,128,1,171,171,171,20, + 128,128,128,1,171,171,171,1,128,128,128,24,171,171,171,1,128,128,128,1, + 255,192,144,20,128,128,128,1,171,171,171,2,128,128,128,1,255,196,150,3, + 220,202,164,1,145,213,194,1,224,201,162,1,255,196,149,12,255,195,149,2, + 128,128,128,1,171,171,171,2,128,128,128,1,255,199,155,2,100,223,216,1, + 2,237,253,1,28,238,250,1,3,237,252,1,109,222,213,1,255,199,155,13, + 128,128,128,1,171,171,171,2,128,128,128,1,255,202,161,1,221,207,174,1, + 2,237,253,1,139,251,255,1,183,255,255,1,134,250,254,1,3,237,252,1, + 227,206,171,1,255,202,161,12,128,128,128,1,171,171,171,2,128,128,128,1, + 255,205,167,1,145,219,204,1,29,239,250,1,183,255,255,3,23,238,250,1, + 153,218,201,1,255,205,167,12,128,128,128,1,171,171,171,2,128,128,128,1, + 255,209,173,1,223,213,183,1,2,237,253,1,139,251,255,1,183,255,255,1, + 133,250,254,1,4,237,252,1,229,212,181,1,255,209,173,3,255,209,172,9, + 128,128,128,1,171,171,171,2,128,128,128,1,255,212,178,2,105,227,223,1, + 3,237,253,1,24,238,251,1,4,237,252,1,114,226,220,1,255,212,178,13, + 128,128,128,1,171,171,171,2,128,128,128,1,255,215,184,3,226,218,192,1, + 153,224,211,1,230,217,191,1,255,215,184,13,227,206,163,1,128,128,128,1, + 171,171,171,2,128,128,128,1,255,218,190,17,252,216,188,1,113,176,83,1, + 8,157,4,1,128,128,128,1,171,171,171,2,128,128,128,1,255,222,196,13, + 255,222,195,3,203,205,156,1,39,171,28,1,3,190,0,1,3,173,0,1, + 128,128,128,1,171,171,171,2,128,128,128,1,255,225,201,14,234,217,185,1, + 97,182,75,1,7,185,4,1,2,194,0,1,3,188,0,1,3,171,0,1, + 128,128,128,1,171,171,171,2,128,128,128,1,255,228,207,13,134,194,107,1, + 18,187,15,1,2,204,1,1,2,198,0,1,3,192,0,1,3,186,0,1, + 3,169,0,1,128,128,128,1,171,171,171,2,128,128,128,1,255,232,213,3, + 255,231,213,9,105,187,86,1,2,209,1,1,1,208,1,1,2,202,1,1, + 2,196,0,1,3,189,0,1,3,183,0,1,3,167,0,1,128,128,128,1, + 171,171,171,2,128,128,128,1,252,113,78,1,253,126,88,1,253,131,95,1, + 253,135,104,1,253,139,111,1,253,143,118,1,251,143,117,1,250,135,104,1, + 249,128,93,1,246,120,80,1,245,112,68,1,239,104,55,1,35,153,5,1, + 1,212,1,1,1,206,1,1,2,199,0,1,3,193,0,1,3,187,0,1, + 4,181,0,1,3,165,0,1,128,128,128,1,171,171,171,2,128,128,128,1, + 254,137,66,1,255,158,82,1,255,165,94,1,255,172,107,1,255,179,120,1, + 255,186,133,1,254,188,137,1,251,176,117,1,248,163,96,1,245,151,76,1, + 242,139,56,1,240,126,36,1,201,109,14,1,20,172,2,1,2,203,1,1, + 2,197,0,1,3,191,0,1,3,184,0,1,4,178,0,1,3,163,0,1, + 128,128,128,1,171,171,171,2,128,128,128,1,254,135,63,1,255,156,79,1, + 255,163,92,1,255,170,104,1,255,178,117,1,255,185,130,1,254,191,142,1, + 252,179,121,1,249,166,101,1,246,154,81,1,243,142,60,1,240,129,40,1, + 237,117,20,1,155,113,2,1,9,184,2,1,2,194,0,1,3,188,0,1, + 4,182,0,1,4,176,0,1,3,162,0,1,128,128,128,1,171,171,171,2, + 128,128,128,1,254,133,60,1,255,155,76,1,255,162,89,1,255,169,102,1, + 255,176,114,1,255,183,127,1,255,190,140,1,252,181,126,1,249,169,106,1, + 246,157,85,1,244,144,65,1,241,132,44,1,238,119,24,1,235,107,4,1, + 115,122,1,1,6,181,0,1,3,186,0,1,4,180,0,1,4,173,0,1, + 3,162,0,1,128,128,128,1,171,171,171,2,128,128,128,1,254,132,57,1, + 255,153,73,1,255,160,86,1,255,167,99,1,255,174,112,1,255,182,125,1, + 255,189,137,1,253,184,130,1,250,172,110,1,247,159,90,1,244,147,69,1, + 241,135,49,1,239,122,29,1,236,110,8,1,235,105,0,1,133,117,1,1, + 13,166,1,1,4,177,0,1,4,171,0,1,3,162,0,1,128,128,128,1, + 171,171,171,2,128,128,128,1,254,130,55,1,255,151,70,1,255,159,83,1, + 255,166,96,1,255,173,109,1,255,180,122,1,255,187,134,1,253,187,135,1, + 251,175,115,1,248,162,94,1,245,150,74,1,242,137,53,1,239,125,33,1, + 236,112,13,1,235,105,0,2,161,111,2,1,22,150,2,1,4,171,0,1, + 3,162,0,1,128,128,128,1,171,171,171,2,128,128,128,1,253,109,49,1, + 254,126,61,1,254,132,72,1,254,138,83,1,254,144,94,1,254,150,105,1, + 254,156,116,1,253,160,122,1,251,149,105,1,248,139,88,1,246,128,71,1, + 244,118,54,1,241,108,36,1,239,97,19,1,237,89,5,3,188,94,5,1, + 33,135,3,1,4,155,0,1,128,128,128,1,171,171,171,1,128,128,128,24, + 171,171,171,1,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171,1, + 116,1,0,0,0,0,0,1,255,255,255,1,0,0,0,20,255,255,255,1, + 0,0,0,1,255,255,255,24,0,0,0,1,255,255,255,22,0,0,0,2, + 255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255,22, + 0,0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,2, + 255,255,255,22,0,0,0,2,255,255,255,20,251,251,251,1,255,255,255,1, + 0,0,0,2,255,255,255,19,233,233,233,1,236,236,236,1,255,255,255,1, + 0,0,0,2,255,255,255,17,252,252,252,1,224,224,224,1,255,255,255,3, + 0,0,0,2,255,255,255,16,235,235,235,1,239,239,239,1,255,255,255,4, + 0,0,0,2,255,255,255,14,252,252,252,1,240,240,240,1,255,255,255,6, + 0,0,0,2,255,255,255,13,234,234,234,1,253,253,253,1,255,255,255,7, + 0,0,0,2,255,255,255,1,238,238,238,1,236,236,236,10,235,235,235,1, + 225,225,225,1,255,255,255,8,0,0,0,2,255,255,255,13,251,251,251,1, + 239,239,239,1,255,255,255,7,0,0,0,2,255,255,255,14,253,253,253,1, + 249,249,249,1,255,255,255,6,0,0,0,2,255,255,255,15,254,254,254,1, + 252,252,252,1,255,255,255,5,0,0,0,2,255,255,255,16,254,254,254,1, + 248,248,248,1,255,255,255,4,0,0,0,2,255,255,255,17,254,254,254,1, + 244,244,244,1,255,255,255,3,0,0,0,2,255,255,255,18,254,254,254,1, + 243,243,243,1,255,255,255,2,0,0,0,1,255,255,255,24,0,0,0,1, + 255,255,255,1,0,0,0,20,255,255,255,1,0,0,0,1,0,0) + ); + +const + objdata_tstringedit: record size: integer; data: array[0..822] of byte end = + (size: 823; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,115,116, + 114,105,110,103,101,100,105,116,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,192,2,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,120,2,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,255,255,255,120,128,128,128,25,0,0,0, + 22,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,20,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,7,23,23,23, + 1,255,255,255,9,0,0,0,1,255,255,255,1,0,0,0,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,7,23,23,23, + 1,255,255,255,10,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,255,255,255,1,184,184,184,1,58,58,58, + 1,60,60,60,1,47,47,47,1,213,213,213,1,255,255,255,1,20,20,20, + 1,84,84,84,1,58,58,58,1,61,61,61,1,213,213,213,1,208,208,208, + 1,58,58,58,1,61,61,61,1,76,76,76,1,242,242,242,1,255,255,255, + 1,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,255,255,255,1,145,145,145,1,229,229,229,1,255,255,255, + 1,134,134,134,1,132,132,132,1,255,255,255,1,11,11,11,1,189,189,189, + 1,255,255,255,1,196,196,196,1,58,58,58,2,203,203,203,1,255,255,255, + 1,164,164,164,1,198,198,198,1,255,255,255,1,0,0,0,1,255,255,255, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255, + 1,171,171,171,1,83,83,83,1,96,96,96,1,69,69,69,1,127,127,127, + 1,255,255,255,1,16,16,16,1,255,255,255,2,254,254,254,1,21,21,21, + 1,23,23,23,1,255,255,255,5,0,0,0,1,255,255,255,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,18,18,18, + 1,244,244,244,1,255,255,255,1,104,104,104,1,127,127,127,1,255,255,255, + 1,11,11,11,1,201,201,201,1,255,255,255,1,190,190,190,1,65,65,65, + 1,53,53,53,1,211,211,211,1,255,255,255,1,147,147,147,1,164,164,164, + 1,255,255,255,1,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,255,255,255,1,113,113,113,1,47,47,47, + 1,74,74,74,1,111,111,111,1,103,103,103,1,255,255,255,1,32,32,32, + 1,81,81,81,1,60,60,60,1,66,66,66,1,220,220,220,1,204,204,204, + 1,55,55,55,1,60,60,60,1,80,80,80,1,244,244,244,1,255,255,255, + 1,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,255,255,255,17,0,0,0,1,255,255,255,1,0,0,0, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255, + 20,224,224,224,1,255,255,255,1,128,128,128,1,224,224,224,22,255,255,255, + 145,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255,81,0,0,0, + 120,0,0) + ); + +const + objdata_tdropdownlistedit: record size: integer; data: array[0..1356] of byte end = + (size: 1357; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,100,114, + 111,112,100,111,119,110,108,105,115,116,101,100,105,116,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,208, + 4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,140, + 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,255, + 255,255,2,165,165,165,1,0,0,0,1,165,165,165,1,255,255,255,2,0, + 0,0,1,1,1,1,1,75,75,75,1,255,255,255,4,0,0,0,1,231, + 231,231,1,0,0,0,1,255,255,255,6,128,128,128,1,255,255,255,2,88, + 88,88,1,75,75,75,1,89,89,89,1,255,255,255,2,0,0,0,1,234, + 234,234,1,70,70,70,1,255,255,255,5,0,0,0,1,255,255,255,2,208, + 208,208,3,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1,251, + 251,251,1,21,21,21,1,221,221,221,1,20,20,20,1,251,251,251,1,255, + 255,255,1,0,0,0,2,117,117,117,1,255,255,255,5,0,0,0,1,255, + 255,255,2,0,0,0,3,128,128,128,1,255,255,255,1,128,128,128,1,255, + 255,255,1,191,191,191,1,0,0,0,3,191,191,191,1,255,255,255,1,0, + 0,0,1,243,243,243,1,11,11,11,1,255,255,255,5,0,0,0,1,255, + 255,255,2,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,255, + 255,255,1,128,128,128,1,255,255,255,1,114,114,114,1,141,141,141,1,255, + 255,255,1,141,141,141,1,115,115,115,1,255,255,255,1,0,0,0,1,235, + 235,235,1,19,19,19,1,255,255,255,3,252,252,252,1,231,231,231,1,0, + 0,0,1,247,247,247,1,255,255,255,1,208,208,208,3,128,128,128,1,255, + 255,255,1,128,128,128,1,255,255,255,1,37,37,37,1,217,217,217,1,255, + 255,255,1,217,217,217,1,38,38,38,1,255,255,255,1,0,0,0,1,3, + 3,3,1,124,124,124,1,255,255,255,3,223,223,223,1,0,0,0,1,223, + 223,223,1,0,0,0,1,128,128,128,5,255,255,255,25,0,0,0,25,255, + 255,255,22,0,0,0,2,255,255,255,2,165,165,165,1,0,0,0,1,165, + 165,165,1,255,255,255,2,0,0,0,1,1,1,1,1,75,75,75,1,255, + 255,255,1,232,232,232,1,77,77,77,1,9,9,9,1,38,38,38,1,203, + 203,203,1,255,255,255,2,208,208,208,1,0,0,0,1,208,208,208,1,128, + 128,128,1,0,0,0,2,255,255,255,2,88,88,88,1,75,75,75,1,89, + 89,89,1,255,255,255,2,0,0,0,1,234,234,234,1,70,70,70,1,255, + 255,255,1,82,82,82,1,118,118,118,1,245,245,245,1,166,166,166,1,53, + 53,53,1,255,255,255,2,0,0,0,3,128,128,128,1,0,0,0,2,255, + 255,255,1,251,251,251,1,21,21,21,1,221,221,221,1,20,20,20,1,251, + 251,251,1,255,255,255,1,0,0,0,2,117,117,117,1,255,255,255,1,12, + 12,12,1,241,241,241,1,255,255,255,5,208,208,208,3,128,128,128,1,0, + 0,0,2,255,255,255,1,191,191,191,1,0,0,0,3,191,191,191,1,255, + 255,255,1,0,0,0,1,243,243,243,1,11,11,11,1,255,255,255,1,14, + 14,14,1,241,241,241,1,255,255,255,1,252,252,252,1,210,210,210,1,255, + 255,255,1,128,128,128,5,0,0,0,2,255,255,255,1,114,114,114,1,141, + 141,141,1,255,255,255,1,141,141,141,1,115,115,115,1,255,255,255,1,0, + 0,0,1,235,235,235,1,19,19,19,1,255,255,255,1,83,83,83,1,124, + 124,124,1,245,245,245,1,145,145,145,1,57,57,57,1,255,255,255,2,212, + 212,212,1,252,252,252,1,208,208,208,1,255,255,255,1,0,0,0,2,255, + 255,255,1,37,37,37,1,217,217,217,1,255,255,255,1,217,217,217,1,38, + 38,38,1,255,255,255,1,0,0,0,1,3,3,3,1,124,124,124,1,255, + 255,255,1,227,227,227,1,63,63,63,1,7,7,7,1,43,43,43,1,213, + 213,213,1,255,255,255,5,128,128,128,1,0,0,0,2,255,255,255,18,128, + 128,128,4,0,0,0,2,255,255,255,2,0,0,0,2,5,5,5,1,174, + 174,174,1,255,255,255,11,208,208,208,1,255,255,255,1,211,211,211,1,255, + 255,255,1,208,208,208,1,0,0,0,2,255,255,255,2,0,0,0,1,255, + 255,255,1,174,174,174,1,5,5,5,1,255,255,255,1,152,152,152,1,11, + 11,11,1,159,159,159,1,255,255,255,9,252,252,252,1,255,255,255,2,0, + 0,0,2,255,255,255,2,0,0,0,1,255,255,255,2,0,0,0,1,255, + 255,255,1,29,29,29,1,197,197,197,1,37,37,37,1,255,255,255,8,208, + 208,208,3,128,128,128,1,0,0,0,2,255,255,255,2,0,0,0,1,255, + 255,255,2,0,0,0,1,255,255,255,1,2,2,2,1,0,0,0,1,3, + 3,3,1,255,255,255,8,0,0,0,3,128,128,128,1,0,0,0,2,255, + 255,255,2,0,0,0,1,255,255,255,1,174,174,174,1,5,5,5,1,255, + 255,255,1,25,25,25,1,226,226,226,1,255,255,255,9,208,208,208,1,0, + 0,0,1,208,208,208,1,128,128,128,1,0,0,0,2,255,255,255,2,0, + 0,0,2,5,5,5,1,174,174,174,1,255,255,255,1,146,146,146,1,9, + 9,9,1,98,98,98,1,255,255,255,7,128,128,128,5,0,0,0,25,12, + 0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tintegeredit: record size: integer; data: array[0..827] of byte end = + (size: 828; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,105,110, + 116,101,103,101,114,101,100,105,116,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,196,2,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,124,2,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,255,255,255,120,128,128,128,25,0,0, + 0,22,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,20,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,2,249,249, + 249,1,28,28,28,1,255,255,255,2,177,177,177,1,56,56,56,1,45,45, + 45,1,172,172,172,1,255,255,255,1,187,187,187,1,54,54,54,1,46,46, + 46,1,155,155,155,1,255,255,255,2,0,0,0,1,255,255,255,1,0,0, + 0,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255, + 255,1,200,200,200,1,39,39,39,1,0,0,0,1,255,255,255,2,62,62, + 62,1,249,249,249,1,221,221,221,1,24,24,24,1,255,255,255,1,75,75, + 75,1,242,242,242,1,231,231,231,1,13,13,13,1,255,255,255,3,0,0, + 0,1,255,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,255,255,255,1,252,252,252,1,247,247,247,1,0,0,0,1,255,255, + 255,2,163,163,163,1,255,255,255,1,234,234,234,1,12,12,12,1,255,255, + 255,1,207,207,207,1,254,254,254,1,197,197,197,1,37,37,37,1,255,255, + 255,3,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128,128, + 128,1,0,0,0,1,255,255,255,3,0,0,0,1,255,255,255,3,232,232, + 232,1,65,65,65,1,126,126,126,1,255,255,255,2,143,143,143,1,0,0, + 0,1,150,150,150,1,255,255,255,3,0,0,0,1,255,255,255,1,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,3,0,0, + 0,1,255,255,255,2,206,206,206,1,44,44,44,1,165,165,165,1,254,254, + 254,1,255,255,255,1,240,240,240,1,254,254,254,1,199,199,199,1,16,16, + 16,1,255,255,255,3,0,0,0,1,255,255,255,1,224,224,224,1,255,255, + 255,1,128,128,128,1,0,0,0,1,255,255,255,3,0,0,0,1,255,255, + 255,2,70,70,70,1,226,226,226,1,255,255,255,3,63,63,63,1,251,251, + 251,1,228,228,228,1,19,19,19,1,255,255,255,3,0,0,0,1,255,255, + 255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255, + 255,3,0,0,0,1,255,255,255,1,238,238,238,1,15,15,15,1,51,51, + 51,3,255,255,255,1,159,159,159,1,54,54,54,1,45,45,45,1,164,164, + 164,1,255,255,255,3,0,0,0,1,255,255,255,1,224,224,224,1,255,255, + 255,1,128,128,128,1,0,0,0,1,255,255,255,17,0,0,0,1,255,255, + 255,1,0,0,0,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,255,255,255,20,224,224,224,1,255,255,255,1,128,128,128,1,224,224, + 224,22,255,255,255,145,16,0,0,0,0,0,0,120,255,255,255,255,255,255, + 255,81,0,0,0,120,0,0) + ); + +const + objdata_tint64edit: record size: integer; data: array[0..873] of byte end = + (size: 874; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,105,110, + 116,54,52,101,100,105,116,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,244,2,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,172,2,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,255,255,255,120,128,128,128,25,0,0,0,22, + 255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,5,241,241,241,1, + 255,255,255,6,237,237,237,1,253,253,253,1,255,255,255,6,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,3,194,194,194,1, + 41,41,41,1,53,53,53,1,59,59,59,1,230,230,230,1,255,255,255,3, + 211,211,211,1,7,7,7,1,233,233,233,1,255,255,255,3,0,0,0,1, + 255,255,255,1,0,0,0,1,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,255,255,255,2,252,252,252,1,39,39,39,1,202,202,202,1, + 255,255,255,1,142,142,142,1,124,124,124,1,255,255,255,2,249,249,249,1, + 59,59,59,1,9,9,9,1,233,233,233,1,255,255,255,4,0,0,0,1, + 255,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 255,255,255,2,198,198,198,1,62,62,62,1,249,249,249,1,213,213,213,1, + 255,255,255,4,115,115,115,1,154,154,154,1,22,22,22,1,233,233,233,1, + 255,255,255,4,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,255,255,255,2,169,169,169,1,59,59,59,1, + 41,41,41,1,64,64,64,1,49,49,49,1,214,214,214,1,255,255,255,1, + 190,190,190,1,78,78,78,1,255,255,255,1,22,22,22,1,233,233,233,1, + 255,255,255,4,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,255,255,255,2,158,158,158,1,7,7,7,1, + 234,234,234,1,255,255,255,1,145,145,145,1,108,108,108,1,239,239,239,1, + 49,49,49,1,232,232,232,1,255,255,255,1,22,22,22,1,233,233,233,1, + 255,255,255,4,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,255,255,255,2,183,183,183,1,56,56,56,1, + 255,255,255,2,207,207,207,1,44,44,44,1,152,152,152,1,15,15,15,1, + 39,39,39,2,3,3,3,1,36,36,36,1,223,223,223,1,255,255,255,3, + 0,0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,255,255,255,2,240,240,240,1,28,28,28,1,223,223,223,1, + 255,255,255,1,128,128,128,1,94,94,94,1,249,249,249,1,239,239,239,3, + 20,20,20,1,219,219,219,1,253,253,253,1,255,255,255,3,0,0,0,1, + 255,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 255,255,255,3,177,177,177,1,35,35,35,1,51,51,51,1,55,55,55,1, + 234,234,234,1,255,255,255,4,22,22,22,1,233,233,233,1,255,255,255,3, + 0,0,0,1,255,255,255,1,0,0,0,1,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255,255,255,1, + 128,128,128,1,224,224,224,22,255,255,255,145,16,0,0,0,0,0,0,120, + 255,255,255,255,255,255,255,81,0,0,0,120,0,0) + ); + +const + objdata_trealedit: record size: integer; data: array[0..704] of byte end = + (size: 705; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,114,101, + 97,108,101,100,105,116,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,76,2,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,4,2,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,255,255,255,120,128,128,128,25,0,0,0,22,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,2,249,249,249,1,28, + 28,28,1,255,255,255,6,177,177,177,1,56,56,56,1,45,45,45,1,172, + 172,172,1,255,255,255,3,0,0,0,1,255,255,255,1,0,0,0,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,200, + 200,200,1,39,39,39,1,0,0,0,1,255,255,255,6,62,62,62,1,249, + 249,249,1,221,221,221,1,24,24,24,1,255,255,255,4,0,0,0,1,255, + 255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,1,252,252,252,1,247,247,247,1,0,0,0,1,255,255,255,6,163, + 163,163,1,255,255,255,1,234,234,234,1,12,12,12,1,255,255,255,4,0, + 0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,3,0,0,0,1,255,255,255,7,232,232,232,1,65, + 65,65,1,126,126,126,1,255,255,255,4,0,0,0,1,255,255,255,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,3,0, + 0,0,1,255,255,255,6,206,206,206,1,44,44,44,1,165,165,165,1,254, + 254,254,1,255,255,255,4,0,0,0,1,255,255,255,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,3,0,0,0,1,255, + 255,255,3,251,251,251,1,255,255,255,2,70,70,70,1,226,226,226,1,255, + 255,255,6,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,3,0,0,0,1,255,255,255,3,0, + 0,0,1,255,255,255,1,238,238,238,1,15,15,15,1,51,51,51,3,255, + 255,255,4,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,17,0,0,0,1,255,255,255,1,0, + 0,0,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,20,224,224,224,1,255,255,255,1,128,128,128,1,224,224,224,22,255, + 255,255,145,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255,81,0, + 0,0,120,0,0) + ); + +const + objdata_trealspinedit: record size: integer; data: array[0..708] of byte end = + (size: 709; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,114,101, + 97,108,115,112,105,110,101,100,105,116,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,76,2,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,4,2,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,255,255,255,120,128,128,128,25,0, + 0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,15,208, + 208,208,5,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,2,249,249,249,1,28,28,28,1,255,255,255,6,177,177,177,1,56, + 56,56,1,45,45,45,1,172,172,172,1,255,255,255,1,208,208,208,2,0, + 0,0,1,208,208,208,2,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,1,200,200,200,1,39,39,39,1,0,0,0,1,255, + 255,255,6,62,62,62,1,249,249,249,1,221,221,221,1,24,24,24,1,255, + 255,255,1,208,208,208,1,0,0,0,3,208,208,208,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,252,252,252,1,247, + 247,247,1,0,0,0,1,255,255,255,6,163,163,163,1,255,255,255,1,234, + 234,234,1,12,12,12,1,255,255,255,1,0,0,0,5,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,3,0,0,0,1,255, + 255,255,7,232,232,232,1,65,65,65,1,126,126,126,1,255,255,255,1,208, + 208,208,5,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,3,0,0,0,1,255,255,255,6,206,206,206,1,44,44,44,1,165, + 165,165,1,254,254,254,1,255,255,255,1,208,208,208,5,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,3,0,0,0,1,255, + 255,255,3,251,251,251,1,255,255,255,2,70,70,70,1,226,226,226,1,255, + 255,255,3,0,0,0,5,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,3,0,0,0,1,255,255,255,3,0,0,0,1,255, + 255,255,1,238,238,238,1,15,15,15,1,51,51,51,3,255,255,255,1,208, + 208,208,1,0,0,0,3,208,208,208,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,15,208,208,208,2,0,0,0,1,208, + 208,208,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,15,208,208,208,5,224,224,224,1,255,255,255,1,128,128,128,1,224, + 224,224,22,255,255,255,145,16,0,0,0,0,0,0,120,255,255,255,255,255, + 255,255,81,0,0,0,120,0,0) + ); + +const + objdata_tdatetimeedit: record size: integer; data: array[0..684] of byte end = + (size: 685; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,100,97, + 116,101,116,105,109,101,101,100,105,116,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,52,2,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,236,1,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,255,255,255,120,128,128,128,25,0, + 0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,20,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,0, + 0,0,3,5,5,5,1,174,174,174,1,255,255,255,4,0,0,0,5,255, + 255,255,2,0,0,0,1,255,255,255,1,0,0,0,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,0,0,0,1,255, + 255,255,2,174,174,174,1,5,5,5,1,255,255,255,6,0,0,0,1,255, + 255,255,5,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,3,0, + 0,0,1,255,255,255,2,0,0,0,1,255,255,255,3,0,0,0,1,255, + 255,255,5,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,3,0, + 0,0,1,255,255,255,6,0,0,0,1,255,255,255,5,0,0,0,1,255, + 255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,1,0,0,0,1,255,255,255,3,0,0,0,1,255,255,255,6,0, + 0,0,1,255,255,255,5,0,0,0,1,255,255,255,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,0,0,0,1,255, + 255,255,2,174,174,174,1,5,5,5,1,255,255,255,6,0,0,0,1,255, + 255,255,5,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,1,0,0,0,3,5,5,5,1,174, + 174,174,1,255,255,255,2,0,0,0,1,255,255,255,3,0,0,0,1,255, + 255,255,5,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,17,0,0,0,1,255,255,255,1,0, + 0,0,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,20,224,224,224,1,255,255,255,1,128,128,128,1,224,224,224,22,255, + 255,255,145,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255,81,0, + 0,0,120,0,0) + ); + +const + objdata_tenumedit: record size: integer; data: array[0..1380] of byte end = + (size: 1381; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,101,110, + 117,109,101,100,105,116,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,240,4,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,172,4,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,128,128,128,25,255,255,255,1,238,238,238,1,29, + 29,29,1,255,255,255,1,172,172,172,1,21,21,21,1,18,18,18,1,148, + 148,148,1,115,115,115,1,15,15,15,2,128,128,128,1,255,255,255,2,0, + 0,0,1,234,234,234,1,23,23,23,1,255,255,255,6,128,128,128,1,255, + 255,255,1,98,98,98,1,0,0,0,1,255,255,255,1,29,29,29,1,201, + 201,201,1,209,209,209,1,10,10,10,1,255,255,255,2,194,194,194,1,17, + 17,17,1,255,255,255,3,0,0,0,1,255,255,255,2,208,208,208,3,128, + 128,128,1,255,255,255,1,128,128,128,1,255,255,255,1,247,247,247,1,0, + 0,0,1,255,255,255,3,205,205,205,1,68,68,68,1,255,255,255,1,164, + 164,164,1,4,4,4,1,103,103,103,1,255,255,255,3,0,0,0,1,255, + 255,255,2,0,0,0,3,128,128,128,1,255,255,255,1,128,128,128,1,255, + 255,255,2,0,0,0,1,255,255,255,2,224,224,224,1,70,70,70,1,232, + 232,232,1,255,255,255,2,214,214,214,1,10,10,10,1,255,255,255,3,0, + 0,0,1,255,255,255,2,208,208,208,1,0,0,0,1,208,208,208,1,128, + 128,128,1,255,255,255,1,128,128,128,1,255,255,255,2,0,0,0,1,255, + 255,255,1,165,165,165,1,77,77,77,1,235,235,235,1,255,255,255,1,32, + 32,32,1,227,227,227,1,234,234,234,1,24,24,24,1,255,255,255,1,252, + 252,252,1,231,231,231,1,0,0,0,1,247,247,247,1,255,255,255,1,208, + 208,208,3,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,2,0, + 0,0,1,255,255,255,1,19,19,19,1,0,0,0,3,177,177,177,1,19, + 19,19,1,24,24,24,1,179,179,179,1,255,255,255,1,223,223,223,1,0, + 0,0,1,223,223,223,1,0,0,0,1,128,128,128,5,255,255,255,25,0, + 0,0,25,255,255,255,22,0,0,0,2,255,255,255,2,165,165,165,1,0, + 0,0,1,165,165,165,1,255,255,255,2,0,0,0,1,1,1,1,1,75, + 75,75,1,255,255,255,1,232,232,232,1,77,77,77,1,9,9,9,1,38, + 38,38,1,203,203,203,1,255,255,255,2,208,208,208,1,0,0,0,1,208, + 208,208,1,128,128,128,1,0,0,0,2,255,255,255,2,88,88,88,1,75, + 75,75,1,89,89,89,1,255,255,255,2,0,0,0,1,234,234,234,1,70, + 70,70,1,255,255,255,1,82,82,82,1,118,118,118,1,245,245,245,1,166, + 166,166,1,53,53,53,1,255,255,255,2,0,0,0,3,128,128,128,1,0, + 0,0,2,255,255,255,1,251,251,251,1,21,21,21,1,221,221,221,1,20, + 20,20,1,251,251,251,1,255,255,255,1,0,0,0,2,117,117,117,1,255, + 255,255,1,12,12,12,1,241,241,241,1,255,255,255,5,208,208,208,3,128, + 128,128,1,0,0,0,2,255,255,255,1,191,191,191,1,0,0,0,3,191, + 191,191,1,255,255,255,1,0,0,0,1,243,243,243,1,11,11,11,1,255, + 255,255,1,14,14,14,1,241,241,241,1,255,255,255,1,252,252,252,1,210, + 210,210,1,255,255,255,1,128,128,128,5,0,0,0,2,255,255,255,1,114, + 114,114,1,141,141,141,1,255,255,255,1,141,141,141,1,115,115,115,1,255, + 255,255,1,0,0,0,1,235,235,235,1,19,19,19,1,255,255,255,1,83, + 83,83,1,124,124,124,1,245,245,245,1,145,145,145,1,57,57,57,1,255, + 255,255,2,212,212,212,1,252,252,252,1,208,208,208,1,255,255,255,1,0, + 0,0,2,255,255,255,1,37,37,37,1,217,217,217,1,255,255,255,1,217, + 217,217,1,38,38,38,1,255,255,255,1,0,0,0,1,3,3,3,1,124, + 124,124,1,255,255,255,1,227,227,227,1,63,63,63,1,7,7,7,1,43, + 43,43,1,213,213,213,1,255,255,255,5,128,128,128,1,0,0,0,2,255, + 255,255,18,128,128,128,4,0,0,0,2,255,255,255,2,0,0,0,2,5, + 5,5,1,174,174,174,1,255,255,255,11,208,208,208,1,255,255,255,1,211, + 211,211,1,255,255,255,1,208,208,208,1,0,0,0,2,255,255,255,2,0, + 0,0,1,255,255,255,1,174,174,174,1,5,5,5,1,255,255,255,1,152, + 152,152,1,11,11,11,1,159,159,159,1,255,255,255,9,252,252,252,1,255, + 255,255,2,0,0,0,2,255,255,255,2,0,0,0,1,255,255,255,2,0, + 0,0,1,255,255,255,1,29,29,29,1,197,197,197,1,37,37,37,1,255, + 255,255,8,208,208,208,3,128,128,128,1,0,0,0,2,255,255,255,2,0, + 0,0,1,255,255,255,2,0,0,0,1,255,255,255,1,2,2,2,1,0, + 0,0,1,3,3,3,1,255,255,255,8,0,0,0,3,128,128,128,1,0, + 0,0,2,255,255,255,2,0,0,0,1,255,255,255,1,174,174,174,1,5, + 5,5,1,255,255,255,1,25,25,25,1,226,226,226,1,255,255,255,9,208, + 208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,0,0,0,2,255, + 255,255,2,0,0,0,2,5,5,5,1,174,174,174,1,255,255,255,1,146, + 146,146,1,9,9,9,1,98,98,98,1,255,255,255,7,128,128,128,5,0, + 0,0,25,12,0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0, + 0) + ); + +const + objdata_thistoryedit: record size: integer; data: array[0..1187] of byte end = + (size: 1188; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,104,105, + 115,116,111,114,121,101,100,105,116,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,44,4,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,232,3,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,128,128,128,25,255,255,255,2,165,165, + 165,1,0,0,0,1,165,165,165,1,255,255,255,2,0,0,0,1,1,1, + 1,1,75,75,75,1,255,255,255,4,0,0,0,1,234,234,234,1,23,23, + 23,1,255,255,255,6,128,128,128,1,255,255,255,2,88,88,88,1,75,75, + 75,1,89,89,89,1,255,255,255,2,0,0,0,1,234,234,234,1,70,70, + 70,1,255,255,255,5,0,0,0,1,255,255,255,2,208,208,208,3,128,128, + 128,1,255,255,255,1,128,128,128,1,255,255,255,1,251,251,251,1,21,21, + 21,1,221,221,221,1,20,20,20,1,251,251,251,1,255,255,255,1,0,0, + 0,2,117,117,117,1,255,255,255,5,0,0,0,1,255,255,255,2,0,0, + 0,3,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1,191,191, + 191,1,0,0,0,3,191,191,191,1,255,255,255,1,0,0,0,1,243,243, + 243,1,11,11,11,1,255,255,255,5,0,0,0,1,255,255,255,2,208,208, + 208,1,0,0,0,1,208,208,208,1,128,128,128,1,255,255,255,1,128,128, + 128,1,255,255,255,1,114,114,114,1,141,141,141,1,255,255,255,1,141,141, + 141,1,115,115,115,1,255,255,255,1,0,0,0,1,235,235,235,1,19,19, + 19,1,255,255,255,3,252,252,252,1,231,231,231,1,0,0,0,1,247,247, + 247,1,255,255,255,1,208,208,208,3,128,128,128,1,255,255,255,1,128,128, + 128,1,255,255,255,1,37,37,37,1,217,217,217,1,255,255,255,1,217,217, + 217,1,38,38,38,1,255,255,255,1,0,0,0,1,3,3,3,1,124,124, + 124,1,255,255,255,3,223,223,223,1,0,0,0,1,223,223,223,1,0,0, + 0,1,128,128,128,5,255,255,255,25,0,0,0,25,255,255,255,22,0,0, + 0,2,255,255,255,18,208,208,208,1,0,0,0,1,208,208,208,1,128,128, + 128,1,0,0,0,2,255,255,255,18,0,0,0,3,128,128,128,1,0,0, + 0,2,255,255,255,1,0,0,0,1,255,255,255,3,0,0,0,1,255,255, + 255,2,0,0,0,1,255,255,255,6,83,83,83,1,255,255,255,2,208,208, + 208,3,128,128,128,1,0,0,0,2,255,255,255,1,0,0,0,1,255,255, + 255,3,0,0,0,1,255,255,255,2,247,247,247,1,255,255,255,6,0,0, + 0,1,255,255,255,1,128,128,128,5,0,0,0,2,255,255,255,1,0,0, + 0,1,255,255,255,3,0,0,0,1,255,255,255,2,0,0,0,1,154,154, + 154,1,29,29,29,1,24,24,24,1,144,144,144,1,255,255,255,1,116,116, + 116,1,0,0,0,1,89,89,89,1,255,255,255,1,212,212,212,1,252,252, + 252,1,208,208,208,1,255,255,255,1,0,0,0,2,255,255,255,1,0,0, + 0,5,255,255,255,2,0,0,0,1,12,12,12,1,233,233,233,1,230,230, + 230,1,58,58,58,1,255,255,255,2,0,0,0,1,255,255,255,5,128,128, + 128,1,0,0,0,2,255,255,255,1,0,0,0,1,255,255,255,3,0,0, + 0,1,255,255,255,2,0,0,0,1,50,50,50,1,66,66,66,1,151,151, + 151,1,238,238,238,1,255,255,255,2,0,0,0,1,255,255,255,2,128,128, + 128,4,0,0,0,2,255,255,255,1,0,0,0,1,255,255,255,3,0,0, + 0,1,255,255,255,2,0,0,0,1,243,243,243,1,178,178,178,1,88,88, + 88,1,40,40,40,1,255,255,255,2,0,0,0,1,255,255,255,1,208,208, + 208,1,255,255,255,1,211,211,211,1,255,255,255,1,208,208,208,1,0,0, + 0,2,255,255,255,1,0,0,0,1,255,255,255,3,0,0,0,1,255,255, + 255,2,0,0,0,1,10,10,10,1,225,225,225,1,230,230,230,1,14,14, + 14,1,255,255,255,2,0,0,0,1,253,253,253,1,255,255,255,2,252,252, + 252,1,255,255,255,2,0,0,0,2,255,255,255,1,0,0,0,1,255,255, + 255,3,0,0,0,1,255,255,255,2,0,0,0,1,147,147,147,1,24,24, + 24,1,27,27,27,1,154,154,154,1,255,255,255,2,61,61,61,1,86,86, + 86,1,255,255,255,1,208,208,208,3,128,128,128,1,0,0,0,2,255,255, + 255,18,0,0,0,3,128,128,128,1,0,0,0,2,255,255,255,18,208,208, + 208,1,0,0,0,1,208,208,208,1,128,128,128,1,0,0,0,2,255,255, + 255,17,128,128,128,5,0,0,0,25,12,0,0,0,255,255,255,255,255,255, + 255,255,255,255,255,66,0,0) + ); + +const + objdata_tenumtypeedit: record size: integer; data: array[0..1092] of byte end = + (size: 1093; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,101,110, + 117,109,116,121,112,101,101,100,105,116,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,204,3,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,136,3,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,255,255,255,23,128, + 128,128,1,0,0,0,1,83,83,83,2,128,128,128,1,255,255,255,14,208, + 208,208,3,128,128,128,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,3,0,0,0,1,94,94,94,1,85,85,85,1,255,255,255,1,0, + 0,0,1,255,255,255,1,0,0,0,1,255,255,255,1,0,0,0,1,97, + 97,97,1,70,70,70,1,82,82,82,1,84,84,84,1,255,255,255,1,0, + 0,0,3,128,128,128,1,255,255,255,1,128,128,128,1,0,0,0,3,123, + 123,123,1,0,0,0,1,243,243,243,1,0,0,0,1,255,255,255,1,0, + 0,0,1,255,255,255,1,0,0,0,1,255,255,255,1,0,0,0,1,243, + 243,243,1,0,0,0,1,246,246,246,1,0,0,0,1,255,255,255,1,208, + 208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,3,0,0,0,1,255,255,255,1,0, + 0,0,1,255,255,255,1,0,0,0,1,243,243,243,1,0,0,0,1,255, + 255,255,1,0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,1,0, + 0,0,1,255,255,255,1,208,208,208,3,128,128,128,1,255,255,255,1,128, + 128,128,1,0,0,0,1,83,83,83,2,120,120,120,1,0,0,0,1,255, + 255,255,1,0,0,0,1,255,255,255,1,74,74,74,1,95,95,95,1,0, + 0,0,1,255,255,255,1,0,0,0,1,255,255,255,1,0,0,0,1,255, + 255,255,1,0,0,0,1,128,128,128,5,255,255,255,25,0,0,0,25,255, + 255,255,22,0,0,0,2,255,255,255,18,208,208,208,1,0,0,0,1,208, + 208,208,1,128,128,128,1,0,0,0,2,255,255,255,18,0,0,0,3,128, + 128,128,1,0,0,0,2,255,255,255,1,0,0,0,5,255,255,255,12,208, + 208,208,3,128,128,128,1,0,0,0,2,255,255,255,3,0,0,0,1,255, + 255,255,13,128,128,128,5,0,0,0,2,255,255,255,3,0,0,0,1,255, + 255,255,2,52,52,52,1,203,203,203,1,255,255,255,1,204,204,204,1,50, + 50,50,1,255,255,255,1,0,0,0,1,100,100,100,1,17,17,17,1,174, + 174,174,1,255,255,255,2,212,212,212,1,252,252,252,1,208,208,208,1,255, + 255,255,1,0,0,0,2,255,255,255,3,0,0,0,1,255,255,255,2,157, + 157,157,1,97,97,97,1,255,255,255,1,102,102,102,1,152,152,152,1,255, + 255,255,1,0,0,0,1,175,175,175,1,179,179,179,1,37,37,37,1,255, + 255,255,5,128,128,128,1,0,0,0,2,255,255,255,3,0,0,0,1,255, + 255,255,2,246,246,246,1,27,27,27,1,226,226,226,1,25,25,25,1,242, + 242,242,1,255,255,255,1,0,0,0,1,249,249,249,1,248,248,248,1,5, + 5,5,1,255,255,255,2,128,128,128,4,0,0,0,2,255,255,255,3,0, + 0,0,1,255,255,255,3,113,113,113,1,55,55,55,1,99,99,99,1,255, + 255,255,2,0,0,0,1,183,183,183,1,180,180,180,1,41,41,41,1,255, + 255,255,1,208,208,208,1,255,255,255,1,211,211,211,1,255,255,255,1,208, + 208,208,1,0,0,0,2,255,255,255,3,0,0,0,1,255,255,255,3,217, + 217,217,1,0,0,0,1,201,201,201,1,255,255,255,2,0,0,0,1,80, + 80,80,1,22,22,22,1,184,184,184,1,255,255,255,3,252,252,252,1,255, + 255,255,2,0,0,0,2,255,255,255,7,202,202,202,1,41,41,41,1,255, + 255,255,3,0,0,0,1,255,255,255,5,208,208,208,3,128,128,128,1,0, + 0,0,2,255,255,255,7,12,12,12,1,168,168,168,1,255,255,255,3,0, + 0,0,1,255,255,255,5,0,0,0,3,128,128,128,1,0,0,0,2,255, + 255,255,18,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,0, + 0,0,2,255,255,255,17,128,128,128,5,0,0,0,25,12,0,0,0,255, + 255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tselector: record size: integer; data: array[0..1088] of byte end = + (size: 1089; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,115,101, + 108,101,99,116,111,114,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,204,3,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,136,3,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,128,128,128,25,255,255,255,2,165,165,165,1,0, + 0,0,1,165,165,165,1,255,255,255,2,0,0,0,1,1,1,1,1,75, + 75,75,1,255,255,255,4,0,0,0,1,234,234,234,1,23,23,23,1,255, + 255,255,6,128,128,128,1,255,255,255,2,88,88,88,1,75,75,75,1,89, + 89,89,1,255,255,255,2,0,0,0,1,234,234,234,1,70,70,70,1,255, + 255,255,5,0,0,0,1,255,255,255,2,208,208,208,3,128,128,128,1,255, + 255,255,1,128,128,128,1,255,255,255,1,251,251,251,1,21,21,21,1,221, + 221,221,1,20,20,20,1,251,251,251,1,255,255,255,1,0,0,0,2,117, + 117,117,1,255,255,255,5,0,0,0,1,255,255,255,2,0,0,0,3,128, + 128,128,1,255,255,255,1,128,128,128,1,255,255,255,1,191,191,191,1,0, + 0,0,3,191,191,191,1,255,255,255,1,0,0,0,1,243,243,243,1,11, + 11,11,1,255,255,255,5,0,0,0,1,255,255,255,2,208,208,208,1,0, + 0,0,1,208,208,208,1,128,128,128,1,255,255,255,1,128,128,128,1,255, + 255,255,1,114,114,114,1,141,141,141,1,255,255,255,1,141,141,141,1,115, + 115,115,1,255,255,255,1,0,0,0,1,235,235,235,1,19,19,19,1,255, + 255,255,3,252,252,252,1,231,231,231,1,0,0,0,1,247,247,247,1,255, + 255,255,1,208,208,208,3,128,128,128,1,255,255,255,1,128,128,128,1,255, + 255,255,1,37,37,37,1,217,217,217,1,255,255,255,1,217,217,217,1,38, + 38,38,1,255,255,255,1,0,0,0,1,3,3,3,1,124,124,124,1,255, + 255,255,3,223,223,223,1,0,0,0,1,223,223,223,1,0,0,0,1,128, + 128,128,5,255,255,255,25,0,0,0,25,255,255,255,22,0,0,0,2,255, + 255,255,18,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,0, + 0,0,2,255,255,255,18,0,0,0,3,128,128,128,1,0,0,0,2,255, + 255,255,2,156,156,156,1,17,17,17,1,23,23,23,1,169,169,169,1,255, + 255,255,6,0,0,0,1,255,255,255,5,208,208,208,3,128,128,128,1,0, + 0,0,2,255,255,255,2,16,16,16,1,207,207,207,1,199,199,199,1,23, + 23,23,1,255,255,255,6,0,0,0,1,255,255,255,4,128,128,128,5,0, + 0,0,2,255,255,255,2,43,43,43,1,176,176,176,1,255,255,255,3,186, + 186,186,1,25,25,25,2,195,195,195,1,255,255,255,1,0,0,0,1,255, + 255,255,5,212,212,212,1,252,252,252,1,208,208,208,1,255,255,255,1,0, + 0,0,2,255,255,255,2,228,228,228,1,102,102,102,1,49,49,49,1,185, + 185,185,1,255,255,255,1,39,39,39,1,194,194,194,1,197,197,197,1,50, + 50,50,1,255,255,255,1,0,0,0,1,255,255,255,8,128,128,128,1,0, + 0,0,2,255,255,255,4,227,227,227,1,23,23,23,1,255,255,255,1,3, + 3,3,1,0,0,0,2,4,4,4,1,255,255,255,1,0,0,0,1,255, + 255,255,5,128,128,128,4,0,0,0,2,255,255,255,2,22,22,22,1,199, + 199,199,1,220,220,220,1,22,22,22,1,255,255,255,1,34,34,34,1,195, + 195,195,1,255,255,255,3,0,0,0,1,255,255,255,4,208,208,208,1,255, + 255,255,1,211,211,211,1,255,255,255,1,208,208,208,1,0,0,0,2,255, + 255,255,2,166,166,166,1,22,22,22,1,16,16,16,1,163,163,163,1,255, + 255,255,1,179,179,179,1,23,23,23,1,13,13,13,1,120,120,120,1,255, + 255,255,1,0,0,0,1,255,255,255,6,252,252,252,1,255,255,255,2,0, + 0,0,2,255,255,255,18,208,208,208,3,128,128,128,1,0,0,0,2,255, + 255,255,18,0,0,0,3,128,128,128,1,0,0,0,2,255,255,255,18,208, + 208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,0,0,0,2,255, + 255,255,17,128,128,128,5,0,0,0,25,12,0,0,0,255,255,255,255,255, + 255,255,255,255,255,255,66,0,0) + ); + +const + objdata_titemedit: record size: integer; data: array[0..916] of byte end = + (size: 917; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,105,116, + 101,109,101,100,105,116,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,32,3,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,196,1,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,171,171,171,1,128,128,128,1,171,171,171,20,128, + 128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171, + 171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128, + 128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171, + 171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128, + 128,128,1,171,171,171,1,128,128,128,24,171,171,171,1,128,128,128,1,255, + 255,255,20,128,128,128,1,171,171,171,2,128,128,128,1,255,255,255,16,0, + 0,0,1,255,255,255,1,0,0,0,1,255,255,255,1,128,128,128,1,171, + 171,171,2,128,128,128,1,255,255,255,17,0,0,0,1,255,255,255,2,128, + 128,128,1,171,171,171,2,128,128,128,1,255,255,255,17,0,0,0,1,255, + 255,255,2,128,128,128,1,171,171,171,2,128,128,128,1,255,255,255,17,0, + 0,0,1,255,255,255,2,128,128,128,1,171,171,171,2,128,128,128,1,255, + 255,255,17,0,0,0,1,255,255,255,2,128,128,128,1,171,171,171,2,128, + 128,128,1,255,255,255,17,0,0,0,1,255,255,255,2,128,128,128,1,171, + 171,171,2,128,128,128,1,255,255,255,17,0,0,0,1,255,255,255,2,128, + 128,128,1,171,171,171,2,128,128,128,1,255,255,255,16,0,0,0,1,255, + 255,255,1,0,0,0,1,255,255,255,1,128,128,128,1,171,171,171,2,128, + 128,128,1,255,255,255,20,128,128,128,1,171,171,171,1,128,128,128,24,171, + 171,171,1,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128, + 128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171, + 171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128, + 128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171, + 171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171,1,36, + 1,0,0,0,0,0,1,255,255,255,1,0,0,0,20,255,255,255,1,0, + 0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255, + 255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0, + 0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255, + 255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0, + 0,0,1,255,255,255,24,0,0,0,1,255,255,255,22,0,0,0,2,255, + 255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0, + 0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255, + 255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0, + 0,0,2,255,255,255,22,0,0,0,1,255,255,255,24,0,0,0,1,255, + 255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0, + 0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255, + 255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0, + 0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255, + 255,255,1,0,0,0,20,255,255,255,1,0,0,0,1,0,0) + ); + +const + objdata_trecordfieldedit: record size: integer; data: array[0..1207] of byte end = + (size: 1208; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,114,101, + 99,111,114,100,102,105,101,108,100,101,100,105,116,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,60,4, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,224,2, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,171,171,171,1,128,128, + 128,1,171,171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171,171, + 171,20,128,128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128,128, + 128,1,171,171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171,171, + 171,2,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128,128, + 128,1,171,171,171,20,128,128,128,1,171,171,171,1,128,128,128,24,171,171, + 171,1,128,128,128,1,255,255,255,20,128,128,128,1,171,171,171,2,128,128, + 128,1,0,0,0,3,17,17,17,1,150,150,150,1,255,255,255,12,0,0, + 0,1,255,255,255,1,0,0,0,1,128,128,128,1,171,171,171,2,128,128, + 128,1,0,0,0,1,255,255,255,2,200,200,200,1,19,19,19,1,255,255, + 255,13,0,0,0,1,255,255,255,1,128,128,128,1,171,171,171,2,128,128, + 128,1,0,0,0,1,255,255,255,2,202,202,202,1,22,22,22,1,255,255, + 255,2,186,186,186,1,25,25,25,2,195,195,195,1,255,255,255,2,189,189, + 189,1,32,32,32,1,42,42,42,1,197,197,197,1,255,255,255,1,0,0, + 0,1,255,255,255,1,128,128,128,1,171,171,171,2,128,128,128,1,0,0, + 0,3,19,19,19,1,164,164,164,1,255,255,255,2,39,39,39,1,194,194, + 194,1,197,197,197,1,50,50,50,1,255,255,255,2,41,41,41,1,175,175, + 175,1,196,196,196,1,34,34,34,1,255,255,255,1,0,0,0,1,255,255, + 255,1,128,128,128,1,171,171,171,2,128,128,128,1,0,0,0,1,255,255, + 255,1,214,214,214,1,60,60,60,1,237,237,237,1,255,255,255,2,3,3, + 3,1,0,0,0,2,4,4,4,1,255,255,255,2,4,4,4,1,249,249, + 249,1,255,255,255,3,0,0,0,1,255,255,255,1,128,128,128,1,171,171, + 171,2,128,128,128,1,0,0,0,1,255,255,255,2,159,159,159,1,96,96, + 96,1,255,255,255,2,34,34,34,1,195,195,195,1,220,220,220,1,255,255, + 255,3,36,36,36,1,182,182,182,1,198,198,198,1,35,35,35,1,255,255, + 255,1,0,0,0,1,255,255,255,1,128,128,128,1,171,171,171,2,128,128, + 128,1,0,0,0,1,255,255,255,2,254,254,254,1,56,56,56,1,203,203, + 203,1,255,255,255,1,179,179,179,1,23,23,23,1,0,0,0,1,58,58, + 58,1,255,255,255,2,182,182,182,1,25,25,25,1,19,19,19,1,180,180, + 180,1,255,255,255,1,0,0,0,1,255,255,255,1,128,128,128,1,171,171, + 171,2,128,128,128,1,255,255,255,17,0,0,0,1,255,255,255,1,0,0, + 0,1,128,128,128,1,171,171,171,2,128,128,128,1,255,255,255,20,128,128, + 128,1,171,171,171,1,128,128,128,24,171,171,171,1,128,128,128,1,171,171, + 171,20,128,128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128,128, + 128,1,171,171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171,171, + 171,2,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128,128, + 128,1,171,171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171,171, + 171,20,128,128,128,1,171,171,171,1,36,1,0,0,0,0,0,1,255,255, + 255,1,0,0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0,0, + 0,20,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255,255, + 255,1,0,0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0,0, + 0,2,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255,255, + 255,1,0,0,0,20,255,255,255,1,0,0,0,1,255,255,255,24,0,0, + 0,1,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255,255, + 255,22,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0, + 0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255,255, + 255,22,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0, + 0,1,255,255,255,24,0,0,0,1,255,255,255,1,0,0,0,20,255,255, + 255,1,0,0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0,0, + 0,2,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255,255, + 255,1,0,0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0,0, + 0,20,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255,255, + 255,1,0,0,0,1,0,0) + ); + +const + objdata_tdropdownitemedit: record size: integer; data: array[0..1004] of byte end = + (size: 1005; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,100,114, + 111,112,100,111,119,110,105,116,101,109,101,100,105,116,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,112, + 3,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,20, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,171,171,171,1,128, + 128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171, + 171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128, + 128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171, + 171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128, + 128,128,1,171,171,171,20,128,128,128,1,171,171,171,1,128,128,128,24,171, + 171,171,1,128,128,128,1,255,255,255,20,128,128,128,1,171,171,171,2,128, + 128,128,1,255,255,255,9,0,0,0,1,255,255,255,1,0,0,0,1,255, + 255,255,1,176,176,176,1,232,232,232,5,128,128,128,2,171,171,171,2,128, + 128,128,1,255,255,255,10,0,0,0,1,255,255,255,2,176,176,176,1,226, + 226,226,5,128,128,128,2,171,171,171,2,128,128,128,1,255,255,255,10,0, + 0,0,1,255,255,255,2,176,176,176,1,215,215,215,5,128,128,128,2,171, + 171,171,2,128,128,128,1,255,255,255,10,0,0,0,1,255,255,255,2,176, + 176,176,1,0,0,0,5,128,128,128,2,171,171,171,2,128,128,128,1,255, + 255,255,10,0,0,0,1,255,255,255,2,176,176,176,1,194,194,194,1,0, + 0,0,3,194,194,194,1,128,128,128,2,171,171,171,2,128,128,128,1,255, + 255,255,10,0,0,0,1,255,255,255,2,176,176,176,1,183,183,183,2,0, + 0,0,1,183,183,183,2,128,128,128,2,171,171,171,2,128,128,128,1,255, + 255,255,10,0,0,0,1,255,255,255,2,176,176,176,1,172,172,172,5,128, + 128,128,2,171,171,171,2,128,128,128,1,255,255,255,9,0,0,0,1,255, + 255,255,1,0,0,0,1,255,255,255,1,176,176,176,1,167,167,167,5,128, + 128,128,2,171,171,171,2,128,128,128,1,255,255,255,13,128,128,128,8,171, + 171,171,1,128,128,128,24,171,171,171,1,128,128,128,1,171,171,171,20,128, + 128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171, + 171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128, + 128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171, + 171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128, + 128,128,1,171,171,171,1,36,1,0,0,0,0,0,1,255,255,255,1,0, + 0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255, + 255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0, + 0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255, + 255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0, + 0,0,20,255,255,255,1,0,0,0,1,255,255,255,24,0,0,0,1,255, + 255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0, + 0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255, + 255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0, + 0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,1,255, + 255,255,24,0,0,0,1,255,255,255,1,0,0,0,20,255,255,255,1,0, + 0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255, + 255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0, + 0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255, + 255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0, + 0,0,1,0,0) + ); + +const + objdata_tmbdropdownitemedit: record size: integer; data: array[0..1134] of byte end = + (size: 1135; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,109,98, + 100,114,111,112,100,111,119,110,105,116,101,109,101,100,105,116,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,240,3,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,148,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,171,171,171, + 1,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128,128,128, + 1,171,171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171,171,171, + 20,128,128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128,128,128, + 1,171,171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171, + 2,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171,1,128,128,128, + 24,171,171,171,1,128,128,128,1,255,255,255,20,128,128,128,1,171,171,171, + 2,128,128,128,1,255,255,255,2,0,0,0,1,255,255,255,1,0,0,0, + 1,255,255,255,1,176,176,176,1,232,232,232,5,128,128,128,1,255,255,255, + 1,232,232,232,5,128,128,128,2,171,171,171,2,128,128,128,1,255,255,255, + 3,0,0,0,1,255,255,255,2,176,176,176,1,226,226,226,5,128,128,128, + 1,255,255,255,1,226,226,226,5,128,128,128,2,171,171,171,2,128,128,128, + 1,255,255,255,3,0,0,0,1,255,255,255,2,176,176,176,1,215,215,215, + 5,128,128,128,1,255,255,255,1,215,215,215,5,128,128,128,2,171,171,171, + 2,128,128,128,1,255,255,255,3,0,0,0,1,255,255,255,2,176,176,176, + 1,0,0,0,5,128,128,128,1,255,255,255,1,0,0,0,1,204,204,204, + 1,0,0,0,1,204,204,204,1,0,0,0,1,128,128,128,2,171,171,171, + 2,128,128,128,1,255,255,255,3,0,0,0,1,255,255,255,2,176,176,176, + 1,194,194,194,1,0,0,0,3,194,194,194,1,128,128,128,1,255,255,255, + 1,0,0,0,1,194,194,194,1,0,0,0,1,194,194,194,1,0,0,0, + 1,128,128,128,2,171,171,171,2,128,128,128,1,255,255,255,3,0,0,0, + 1,255,255,255,2,176,176,176,1,183,183,183,2,0,0,0,1,183,183,183, + 2,128,128,128,1,255,255,255,1,183,183,183,5,128,128,128,2,171,171,171, + 2,128,128,128,1,255,255,255,3,0,0,0,1,255,255,255,2,176,176,176, + 1,172,172,172,5,128,128,128,1,255,255,255,1,172,172,172,5,128,128,128, + 2,171,171,171,2,128,128,128,1,255,255,255,2,0,0,0,1,255,255,255, + 1,0,0,0,1,255,255,255,1,176,176,176,1,167,167,167,5,128,128,128, + 1,255,255,255,1,167,167,167,5,128,128,128,2,171,171,171,2,128,128,128, + 1,255,255,255,6,128,128,128,15,171,171,171,1,128,128,128,24,171,171,171, + 1,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128,128,128, + 1,171,171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171,171,171, + 20,128,128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128,128,128, + 1,171,171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171, + 2,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171,1,36,1,0, + 0,0,0,0,1,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0, + 2,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255,255,255, + 1,0,0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0, + 20,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255,255,255, + 1,0,0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0, + 1,255,255,255,24,0,0,0,1,255,255,255,22,0,0,0,2,255,255,255, + 22,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0, + 2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255, + 22,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0, + 2,255,255,255,22,0,0,0,1,255,255,255,24,0,0,0,1,255,255,255, + 1,0,0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0, + 20,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255,255,255, + 1,0,0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0, + 2,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255,255,255, + 1,0,0,0,20,255,255,255,1,0,0,0,1,0,0) + ); + +const + objdata_ttreeitemedit: record size: integer; data: array[0..1040] of byte end = + (size: 1041; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,116,114, + 101,101,105,116,101,109,101,100,105,116,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,152,3,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,60,2,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,171,171,171,1,128,128,128,1,171, + 171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128, + 128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171, + 171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128, + 128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171, + 171,171,20,128,128,128,1,171,171,171,1,128,128,128,24,171,171,171,1,128, + 128,128,1,255,255,255,20,128,128,128,1,171,171,171,2,128,128,128,1,255, + 255,255,1,0,0,0,7,255,255,255,8,0,0,0,1,255,255,255,1,0, + 0,0,1,255,255,255,1,128,128,128,1,171,171,171,2,128,128,128,1,255, + 255,255,1,0,0,0,1,255,255,255,5,0,0,0,1,255,255,255,9,0, + 0,0,1,255,255,255,2,128,128,128,1,171,171,171,2,128,128,128,1,255, + 255,255,1,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,2,0, + 0,0,1,255,255,255,9,0,0,0,1,255,255,255,2,128,128,128,1,171, + 171,171,2,128,128,128,1,255,255,255,1,0,0,0,1,255,255,255,1,0, + 0,0,3,255,255,255,1,0,0,0,1,255,255,255,9,0,0,0,1,255, + 255,255,2,128,128,128,1,171,171,171,2,128,128,128,1,255,255,255,1,0, + 0,0,1,255,255,255,2,0,0,0,1,255,255,255,2,0,0,0,1,255, + 255,255,9,0,0,0,1,255,255,255,2,128,128,128,1,171,171,171,2,128, + 128,128,1,255,255,255,1,0,0,0,1,255,255,255,5,0,0,0,1,255, + 255,255,9,0,0,0,1,255,255,255,2,128,128,128,1,171,171,171,2,128, + 128,128,1,255,255,255,1,0,0,0,7,255,255,255,9,0,0,0,1,255, + 255,255,2,128,128,128,1,171,171,171,2,128,128,128,1,255,255,255,16,0, + 0,0,1,255,255,255,1,0,0,0,1,255,255,255,1,128,128,128,1,171, + 171,171,2,128,128,128,1,255,255,255,20,128,128,128,1,171,171,171,1,128, + 128,128,24,171,171,171,1,128,128,128,1,171,171,171,20,128,128,128,1,171, + 171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128, + 128,128,1,171,171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171, + 171,171,20,128,128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128, + 128,128,1,171,171,171,2,128,128,128,1,171,171,171,20,128,128,128,1,171, + 171,171,1,36,1,0,0,0,0,0,1,255,255,255,1,0,0,0,20,255, + 255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0, + 0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255, + 255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0, + 0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255, + 255,255,1,0,0,0,1,255,255,255,24,0,0,0,1,255,255,255,22,0, + 0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255, + 255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0, + 0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255, + 255,255,22,0,0,0,2,255,255,255,22,0,0,0,1,255,255,255,24,0, + 0,0,1,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255, + 255,255,1,0,0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0, + 0,0,20,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255, + 255,255,1,0,0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0, + 0,0,2,255,255,255,1,0,0,0,20,255,255,255,1,0,0,0,1,0, + 0) + ); + +const + objdata_tfoldedit: record size: integer; data: array[0..1620] of byte end = + (size: 1621; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,102,111, + 108,100,101,100,105,116,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,224,5,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,76,3,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,171,171,171,1,128,128,128,2,171,171,171,18,128, + 128,128,2,171,171,171,2,128,128,128,2,171,171,171,18,128,128,128,2,171, + 171,171,2,128,128,128,2,171,171,171,18,128,128,128,2,171,171,171,2,128, + 128,128,2,171,171,171,18,128,128,128,2,171,171,171,2,128,128,128,2,171, + 171,171,18,128,128,128,2,171,171,171,2,128,128,128,2,171,171,171,18,128, + 128,128,2,171,171,171,1,128,128,128,26,210,210,210,1,250,250,250,18,210, + 210,210,1,128,128,128,2,171,171,171,1,128,128,128,1,228,228,228,1,120, + 120,120,1,39,39,39,6,235,235,235,1,255,255,255,1,239,239,239,1,185, + 185,185,1,241,241,241,1,255,255,255,3,195,195,195,1,107,107,107,1,174, + 174,174,1,98,98,98,1,128,128,128,1,171,171,171,2,128,128,128,1,228, + 228,228,1,95,95,95,1,153,153,153,1,223,223,223,4,27,27,27,1,231, + 231,231,1,255,255,255,1,70,70,70,1,136,136,136,1,238,238,238,1,255, + 255,255,3,246,246,246,1,169,169,169,1,110,110,110,1,206,206,206,1,128, + 128,128,1,171,171,171,2,128,128,128,1,228,228,228,1,95,95,95,1,175, + 175,175,1,255,255,255,1,81,81,81,1,212,212,212,1,255,255,255,1,31, + 31,31,1,231,231,231,1,187,187,187,1,27,27,27,1,140,140,140,1,254, + 254,254,1,186,186,186,1,126,126,126,1,200,200,200,1,255,255,255,1,175, + 175,175,1,95,95,95,1,228,228,228,1,128,128,128,1,171,171,171,2,128, + 128,128,1,228,228,228,1,95,95,95,1,175,175,175,1,77,77,77,1,1, + 1,1,1,6,6,6,1,217,217,217,1,31,31,31,1,231,231,231,1,243, + 243,243,1,50,50,50,1,234,234,234,1,185,185,185,1,101,101,101,1,219, + 219,219,1,85,85,85,1,188,188,188,1,175,175,175,1,95,95,95,1,228, + 228,228,1,128,128,128,1,171,171,171,2,128,128,128,1,228,228,228,1,95, + 95,95,1,175,175,175,1,255,255,255,1,69,69,69,1,209,209,209,1,255, + 255,255,1,31,31,31,1,231,231,231,1,255,255,255,1,55,55,55,1,255, + 255,255,1,91,91,91,1,218,218,218,1,255,255,255,1,196,196,196,1,100, + 100,100,1,175,175,175,1,95,95,95,1,228,228,228,1,128,128,128,1,171, + 171,171,2,128,128,128,1,228,228,228,1,95,95,95,1,159,159,159,1,231, + 231,231,4,28,28,28,1,231,231,231,1,255,255,255,1,55,55,55,1,255, + 255,255,1,129,129,129,1,184,184,184,1,255,255,255,1,163,163,163,1,118, + 118,118,1,175,175,175,1,95,95,95,1,228,228,228,1,128,128,128,1,171, + 171,171,2,128,128,128,1,228,228,228,1,115,115,115,1,31,31,31,6,234, + 234,234,1,255,255,255,1,55,55,55,1,255,255,255,1,225,225,225,1,92, + 92,92,1,96,96,96,1,71,71,71,1,219,219,219,1,169,169,169,1,110, + 110,110,1,206,206,206,1,128,128,128,1,171,171,171,2,128,128,128,1,228, + 228,228,1,255,255,255,15,195,195,195,1,107,107,107,1,174,174,174,1,98, + 98,98,1,128,128,128,1,171,171,171,1,128,128,128,2,210,210,210,1,250, + 250,250,18,210,210,210,1,128,128,128,26,171,171,171,1,128,128,128,2,171, + 171,171,18,128,128,128,2,171,171,171,2,128,128,128,2,171,171,171,18,128, + 128,128,2,171,171,171,2,128,128,128,2,171,171,171,18,128,128,128,2,171, + 171,171,2,128,128,128,2,171,171,171,18,128,128,128,2,171,171,171,2,128, + 128,128,2,171,171,171,18,128,128,128,2,171,171,171,2,128,128,128,2,171, + 171,171,18,128,128,128,2,171,171,171,1,92,2,0,0,0,0,0,1,76, + 76,76,1,55,55,55,1,0,0,0,18,55,55,55,1,76,76,76,1,0, + 0,0,2,144,144,144,1,104,104,104,1,0,0,0,18,104,104,104,1,144, + 144,144,1,0,0,0,2,144,144,144,1,104,104,104,1,0,0,0,18,104, + 104,104,1,144,144,144,1,0,0,0,2,144,144,144,1,104,104,104,1,0, + 0,0,18,104,104,104,1,144,144,144,1,0,0,0,2,144,144,144,1,104, + 104,104,1,0,0,0,18,104,104,104,1,144,144,144,1,0,0,0,2,144, + 144,144,1,104,104,104,1,0,0,0,18,104,104,104,1,144,144,144,1,0, + 0,0,1,102,102,102,1,228,228,228,1,218,218,218,1,192,192,192,18,218, + 218,218,1,228,228,228,1,102,102,102,1,25,25,25,1,165,165,165,1,191, + 191,191,1,217,217,217,18,191,191,191,1,165,165,165,1,25,25,25,1,0, + 0,0,1,144,144,144,1,194,194,194,1,255,255,255,18,225,225,225,1,144, + 144,144,1,0,0,0,2,144,144,144,1,194,194,194,1,255,255,255,18,199, + 199,199,1,144,144,144,1,0,0,0,2,144,144,144,1,194,194,194,1,255, + 255,255,18,194,194,194,1,144,144,144,1,0,0,0,2,144,144,144,1,194, + 194,194,1,255,255,255,18,194,194,194,1,144,144,144,1,0,0,0,2,144, + 144,144,1,194,194,194,1,255,255,255,18,194,194,194,1,144,144,144,1,0, + 0,0,2,144,144,144,1,194,194,194,1,255,255,255,18,194,194,194,1,144, + 144,144,1,0,0,0,2,144,144,144,1,194,194,194,1,255,255,255,18,199, + 199,199,1,144,144,144,1,0,0,0,2,144,144,144,1,194,194,194,1,255, + 255,255,18,225,225,225,1,144,144,144,1,0,0,0,1,25,25,25,1,165, + 165,165,1,191,191,191,1,217,217,217,18,191,191,191,1,165,165,165,1,25, + 25,25,1,102,102,102,1,228,228,228,1,218,218,218,1,192,192,192,18,218, + 218,218,1,228,228,228,1,102,102,102,1,0,0,0,1,144,144,144,1,104, + 104,104,1,0,0,0,18,104,104,104,1,144,144,144,1,0,0,0,2,144, + 144,144,1,104,104,104,1,0,0,0,18,104,104,104,1,144,144,144,1,0, + 0,0,2,144,144,144,1,104,104,104,1,0,0,0,18,104,104,104,1,144, + 144,144,1,0,0,0,2,144,144,144,1,104,104,104,1,0,0,0,18,104, + 104,104,1,144,144,144,1,0,0,0,2,144,144,144,1,104,104,104,1,0, + 0,0,18,104,104,104,1,144,144,144,1,0,0,0,2,76,76,76,1,55, + 55,55,1,0,0,0,18,55,55,55,1,76,76,76,1,0,0,0,1,0, + 0) + ); + +const + objdata_tmemoedit: record size: integer; data: array[0..1352] of byte end = + (size: 1353; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,109,101, + 109,111,101,100,105,116,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,212,4,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,136,4,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,128,128,128,25,0,0,0,22,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,2,11,11,11,1,91,91,91,1,255, + 255,255,3,125,125,125,1,11,11,11,1,255,255,255,11,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,2,22,22,22,1,43, + 43,43,1,246,246,246,1,255,255,255,2,58,58,58,1,21,21,21,1,255, + 255,255,11,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,2,23,23,23,1,119,119,119,1,170,170,170,1,255,255,255,1,196, + 196,196,1,113,113,113,1,23,23,23,1,255,255,255,1,217,217,217,1,64, + 64,64,1,58,58,58,1,56,56,56,1,204,204,204,1,255,255,255,5,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,2,23, + 23,23,1,209,209,209,1,82,82,82,1,255,255,255,1,104,104,104,1,205, + 205,205,1,23,23,23,1,255,255,255,1,61,61,61,1,195,195,195,1,255, + 255,255,1,212,212,212,1,42,42,42,1,255,255,255,5,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,2,23,23,23,1,255, + 255,255,1,52,52,52,1,235,235,235,1,60,60,60,1,255,255,255,1,23, + 23,23,1,255,255,255,1,18,18,18,1,63,63,63,3,33,33,33,1,249, + 249,249,1,255,255,255,4,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,2,23,23,23,1,255,255,255,1,135,135,135,1,85, + 85,85,1,133,133,133,1,255,255,255,1,23,23,23,1,255,255,255,1,57, + 57,57,1,214,214,214,1,255,255,255,1,231,231,231,1,132,132,132,1,255, + 255,255,5,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,2,23,23,23,1,255,255,255,1,225,225,225,1,2,2,2,1,224, + 224,224,1,255,255,255,1,23,23,23,1,255,255,255,1,212,212,212,1,64, + 64,64,1,61,61,61,1,53,53,53,1,177,177,177,1,255,255,255,5,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,20,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,20,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,2,11, + 11,11,1,91,91,91,1,255,255,255,3,125,125,125,1,11,11,11,1,255, + 255,255,7,0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,2,22, + 22,22,1,43,43,43,1,246,246,246,1,255,255,255,2,58,58,58,1,21, + 21,21,1,255,255,255,8,0,0,0,1,255,255,255,2,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,2,23,23,23,1,119, + 119,119,1,170,170,170,1,255,255,255,1,196,196,196,1,113,113,113,1,23, + 23,23,1,255,255,255,1,210,210,210,1,58,58,58,1,57,57,57,1,58, + 58,58,1,210,210,210,1,255,255,255,2,0,0,0,1,255,255,255,2,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,2,23, + 23,23,1,209,209,209,1,82,82,82,1,255,255,255,1,104,104,104,1,205, + 205,205,1,23,23,23,1,255,255,255,1,56,56,56,1,196,196,196,1,255, + 255,255,1,194,194,194,1,55,55,55,1,255,255,255,2,0,0,0,1,255, + 255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,2,23,23,23,1,255,255,255,1,52,52,52,1,235,235,235,1,60, + 60,60,1,255,255,255,1,23,23,23,1,255,255,255,1,20,20,20,1,255, + 255,255,2,254,254,254,1,21,21,21,1,255,255,255,2,0,0,0,1,255, + 255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,2,23,23,23,1,255,255,255,1,135,135,135,1,85,85,85,1,133, + 133,133,1,255,255,255,1,23,23,23,1,255,255,255,1,55,55,55,1,197, + 197,197,1,255,255,255,1,195,195,195,1,55,55,55,1,255,255,255,2,0, + 0,0,1,255,255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,2,23,23,23,1,255,255,255,1,225,225,225,1,2, + 2,2,1,224,224,224,1,255,255,255,1,23,23,23,1,255,255,255,1,208, + 208,208,1,57,57,57,1,58,58,58,1,59,59,59,1,209,209,209,1,255, + 255,255,2,0,0,0,1,255,255,255,2,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,16,0,0,0,1,255,255,255,1,0, + 0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,20,224,224,224,1,255,255,255,1,128,128,128,1,224, + 224,224,22,255,255,255,25,20,0,0,0,255,255,255,255,255,255,255,255,255, + 255,255,42,128,128,128,1,255,255,255,23,0,0) + ); + +const + objdata_tkeystringedit: record size: integer; data: array[0..1177] of byte end = + (size: 1178; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,107,101, + 121,115,116,114,105,110,103,101,100,105,116,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,32,4,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,220,3,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,255,255,255,2, + 165,165,165,1,0,0,0,1,165,165,165,1,255,255,255,2,0,0,0,1, + 1,1,1,1,75,75,75,1,255,255,255,4,0,0,0,1,234,234,234,1, + 23,23,23,1,255,255,255,6,128,128,128,1,255,255,255,2,88,88,88,1, + 75,75,75,1,89,89,89,1,255,255,255,2,0,0,0,1,234,234,234,1, + 70,70,70,1,255,255,255,5,0,0,0,1,255,255,255,2,208,208,208,3, + 128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1,251,251,251,1, + 21,21,21,1,221,221,221,1,20,20,20,1,251,251,251,1,255,255,255,1, + 0,0,0,2,117,117,117,1,255,255,255,5,0,0,0,1,255,255,255,2, + 0,0,0,3,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1, + 191,191,191,1,0,0,0,3,191,191,191,1,255,255,255,1,0,0,0,1, + 243,243,243,1,11,11,11,1,255,255,255,5,0,0,0,1,255,255,255,2, + 208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,255,255,255,1, + 128,128,128,1,255,255,255,1,114,114,114,1,141,141,141,1,255,255,255,1, + 141,141,141,1,115,115,115,1,255,255,255,1,0,0,0,1,235,235,235,1, + 19,19,19,1,255,255,255,3,252,252,252,1,231,231,231,1,0,0,0,1, + 247,247,247,1,255,255,255,1,208,208,208,3,128,128,128,1,255,255,255,1, + 128,128,128,1,255,255,255,1,37,37,37,1,217,217,217,1,255,255,255,1, + 217,217,217,1,38,38,38,1,255,255,255,1,0,0,0,1,3,3,3,1, + 124,124,124,1,255,255,255,3,223,223,223,1,0,0,0,1,223,223,223,1, + 0,0,0,1,128,128,128,5,255,255,255,25,0,0,0,25,255,255,255,22, + 0,0,0,2,255,255,255,18,208,208,208,1,0,0,0,1,208,208,208,1, + 128,128,128,1,0,0,0,2,255,255,255,18,0,0,0,3,128,128,128,1, + 0,0,0,2,255,255,255,1,0,0,0,1,255,255,255,2,157,157,157,1, + 102,102,102,1,255,255,255,12,208,208,208,3,128,128,128,1,0,0,0,2, + 255,255,255,1,0,0,0,1,255,255,255,1,201,201,201,1,65,65,65,1, + 249,249,249,1,255,255,255,11,128,128,128,5,0,0,0,2,255,255,255,1, + 0,0,0,1,233,233,233,1,53,53,53,1,230,230,230,1,255,255,255,1, + 186,186,186,1,25,25,25,2,195,195,195,1,255,255,255,1,52,52,52,1, + 203,203,203,1,255,255,255,1,204,204,204,1,50,50,50,1,255,255,255,2, + 212,212,212,1,252,252,252,1,208,208,208,1,255,255,255,1,0,0,0,2, + 255,255,255,1,0,0,0,1,62,62,62,1,124,124,124,1,255,255,255,2, + 39,39,39,1,194,194,194,1,197,197,197,1,50,50,50,1,255,255,255,1, + 157,157,157,1,97,97,97,1,255,255,255,1,102,102,102,1,152,152,152,1, + 255,255,255,5,128,128,128,1,0,0,0,2,255,255,255,1,0,0,0,1, + 146,146,146,1,57,57,57,1,208,208,208,1,255,255,255,1,3,3,3,1, + 0,0,0,2,4,4,4,1,255,255,255,1,246,246,246,1,27,27,27,1, + 226,226,226,1,25,25,25,1,242,242,242,1,255,255,255,2,128,128,128,4, + 0,0,0,2,255,255,255,1,0,0,0,1,255,255,255,1,217,217,217,1, + 51,51,51,1,244,244,244,1,34,34,34,1,195,195,195,1,255,255,255,4, + 113,113,113,1,55,55,55,1,99,99,99,1,255,255,255,2,208,208,208,1, + 255,255,255,1,211,211,211,1,255,255,255,1,208,208,208,1,0,0,0,2, + 255,255,255,1,0,0,0,1,255,255,255,2,161,161,161,1,94,94,94,1, + 179,179,179,1,23,23,23,1,13,13,13,1,120,120,120,1,255,255,255,2, + 217,217,217,1,0,0,0,1,201,201,201,1,255,255,255,4,252,252,252,1, + 255,255,255,2,0,0,0,2,255,255,255,12,202,202,202,1,41,41,41,1, + 255,255,255,4,208,208,208,3,128,128,128,1,0,0,0,2,255,255,255,12, + 12,12,12,1,168,168,168,1,255,255,255,4,0,0,0,3,128,128,128,1, + 0,0,0,2,255,255,255,18,208,208,208,1,0,0,0,1,208,208,208,1, + 128,128,128,1,0,0,0,2,255,255,255,17,128,128,128,5,0,0,0,25, + 12,0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tpointeredit: record size: integer; data: array[0..763] of byte end = + (size: 764; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,112,111, + 105,110,116,101,114,101,100,105,116,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,132,2,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,60,2,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,255,255,255,120,128,128,128,25,0,0, + 0,22,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,20,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,0,0, + 0,1,171,171,171,1,255,255,255,2,0,0,0,1,255,255,255,2,0,0, + 0,1,255,255,255,2,0,0,0,1,255,255,255,5,0,0,0,1,255,255, + 255,1,0,0,0,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,255,255,255,1,0,0,0,1,39,39,39,1,249,249,249,1,255,255, + 255,1,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,2,0,0, + 0,1,255,255,255,6,0,0,0,1,255,255,255,1,224,224,224,1,255,255, + 255,1,128,128,128,1,0,0,0,1,255,255,255,1,0,0,0,1,107,107, + 107,1,139,139,139,1,255,255,255,1,0,0,0,1,255,255,255,2,0,0, + 0,1,255,255,255,2,0,0,0,1,255,255,255,6,0,0,0,1,255,255, + 255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255, + 255,1,0,0,0,1,235,235,235,1,31,31,31,1,235,235,235,1,0,0, + 0,1,255,255,255,2,0,0,0,1,255,255,255,2,0,0,0,1,255,255, + 255,6,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128,128, + 128,1,0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,1,139,139, + 139,1,106,106,106,1,0,0,0,1,255,255,255,2,0,0,0,1,255,255, + 255,2,0,0,0,1,255,255,255,6,0,0,0,1,255,255,255,1,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,0,0, + 0,1,255,255,255,1,249,249,249,1,38,38,38,1,0,0,0,1,255,255, + 255,2,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,6,0,0, + 0,1,255,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,255,255,255,1,0,0,0,1,255,255,255,2,171,171,171,1,0,0, + 0,1,255,255,255,2,0,0,0,1,255,255,255,2,0,0,0,5,255,255, + 255,2,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128,128, + 128,1,0,0,0,1,255,255,255,17,0,0,0,1,255,255,255,1,0,0, + 0,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255, + 255,20,224,224,224,1,255,255,255,1,128,128,128,1,224,224,224,22,255,255, + 255,145,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255,81,0,0, + 0,120,0,0) + ); + +const + objdata_tcalendardatetimeedit: record size: integer; data: array[0..1092] of byte end = + (size: 1093; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,21,116,99,97, + 108,101,110,100,97,114,100,97,116,101,116,105,109,101,101,100,105,116,23,98, + 105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108, + 111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111, + 110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99, + 111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97, + 103,101,10,196,3,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24, + 0,0,0,128,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128, + 128,128,25,255,255,255,1,0,0,0,2,5,5,5,1,174,174,174,1,255, + 255,255,3,0,0,0,5,255,255,255,1,0,0,0,1,234,234,234,1,23, + 23,23,1,255,255,255,6,128,128,128,1,255,255,255,1,0,0,0,1,255, + 255,255,1,174,174,174,1,5,5,5,1,255,255,255,2,0,0,0,1,255, + 255,255,2,0,0,0,1,255,255,255,4,0,0,0,1,255,255,255,2,208, + 208,208,3,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1,0, + 0,0,1,255,255,255,2,0,0,0,1,255,255,255,5,0,0,0,1,255, + 255,255,4,0,0,0,1,255,255,255,2,0,0,0,3,128,128,128,1,255, + 255,255,1,128,128,128,1,255,255,255,1,0,0,0,1,255,255,255,2,0, + 0,0,1,255,255,255,5,0,0,0,1,255,255,255,4,0,0,0,1,255, + 255,255,2,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,255, + 255,255,1,128,128,128,1,255,255,255,1,0,0,0,1,255,255,255,1,174, + 174,174,1,5,5,5,1,255,255,255,5,0,0,0,1,255,255,255,2,252, + 252,252,1,231,231,231,1,0,0,0,1,247,247,247,1,255,255,255,1,208, + 208,208,3,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1,0, + 0,0,2,5,5,5,1,174,174,174,1,255,255,255,2,0,0,0,1,255, + 255,255,2,0,0,0,1,255,255,255,2,223,223,223,1,0,0,0,1,223, + 223,223,1,0,0,0,1,128,128,128,5,255,255,255,25,0,0,0,25,255, + 255,255,22,0,0,0,2,255,255,255,1,179,179,179,2,255,255,255,1,179, + 179,179,2,255,255,255,1,179,179,179,2,255,255,255,1,179,179,179,2,255, + 255,255,1,0,0,0,2,255,255,255,1,0,0,0,2,255,255,255,1,0, + 0,255,2,255,255,255,1,0,0,0,2,255,255,255,22,0,0,0,2,255, + 255,255,22,0,0,0,2,255,255,255,1,0,0,0,2,255,255,255,1,0, + 0,0,2,255,255,255,1,0,0,0,2,240,240,240,1,7,7,7,1,23, + 23,23,1,255,255,255,1,7,7,7,2,255,255,255,1,7,7,7,2,255, + 255,255,1,0,0,255,2,255,255,255,1,0,0,0,2,255,255,255,10,247, + 247,247,1,248,248,248,1,255,255,255,1,247,247,247,2,255,255,255,1,247, + 247,247,2,255,255,255,4,0,0,0,2,255,255,255,22,0,0,0,2,255, + 255,255,1,0,0,0,2,248,248,248,1,7,7,7,1,15,15,15,1,255, + 255,255,1,0,0,0,2,255,255,255,1,15,15,15,1,7,7,7,1,233, + 233,233,1,7,7,7,1,23,23,23,1,255,255,255,1,0,0,0,2,255, + 255,255,1,0,0,255,2,255,255,255,1,0,0,0,2,255,255,255,4,247, + 247,247,1,248,248,248,1,255,255,255,4,248,248,248,1,247,247,247,1,255, + 255,255,1,247,247,247,1,248,248,248,1,255,255,255,7,0,0,0,2,255, + 255,255,22,0,0,0,2,255,255,255,1,7,7,7,2,255,255,255,1,0, + 0,0,2,255,255,255,1,0,0,0,2,255,255,255,1,15,15,15,1,7, + 7,7,1,248,248,248,1,0,0,0,2,255,255,255,1,0,0,0,2,255, + 255,255,1,0,0,255,2,255,255,255,1,0,0,0,2,255,255,255,1,247, + 247,247,2,255,255,255,7,248,248,248,1,247,247,247,1,255,255,255,10,0, + 0,0,2,255,255,255,22,0,0,0,2,255,255,255,1,0,0,0,2,247, + 247,247,1,0,0,0,1,7,7,7,1,240,240,240,1,15,15,15,1,30, + 30,30,1,255,255,255,1,7,7,7,1,0,0,0,1,247,247,247,1,159, + 159,159,2,255,255,255,1,179,179,179,2,255,255,255,1,197,197,197,1,183, + 183,183,1,242,242,242,1,0,0,0,15,10,10,10,2,0,0,0,4,9, + 9,9,1,11,11,11,1,2,2,2,1,0,0,0,1,12,0,0,0,255, + 255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tdatabutton: record size: integer; data: array[0..666] of byte end = + (size: 667; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,100,97, + 116,97,98,117,116,116,111,110,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,36,2,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,220,1,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,255,255,255,120,224,224,224,25,255,255,255, + 22,0,0,0,1,224,224,224,1,255,255,255,1,235,235,235,20,128,128,128, + 1,0,0,0,1,224,224,224,1,255,255,255,1,232,232,232,20,128,128,128, + 1,0,0,0,1,224,224,224,1,255,255,255,1,229,229,229,4,214,214,214, + 1,26,26,26,1,229,229,229,1,154,154,154,1,19,19,19,1,16,16,16, + 1,133,133,133,1,103,103,103,1,13,13,13,2,115,115,115,1,229,229,229, + 5,128,128,128,1,0,0,0,1,224,224,224,1,255,255,255,1,226,226,226, + 4,87,87,87,1,0,0,0,1,226,226,226,1,26,26,26,1,178,178,178, + 1,185,185,185,1,9,9,9,1,226,226,226,2,172,172,172,1,15,15,15, + 1,226,226,226,5,128,128,128,1,0,0,0,1,224,224,224,1,255,255,255, + 1,223,223,223,4,216,216,216,1,0,0,0,1,223,223,223,3,179,179,179, + 1,59,59,59,1,223,223,223,1,143,143,143,1,3,3,3,1,90,90,90, + 1,223,223,223,5,128,128,128,1,0,0,0,1,224,224,224,1,255,255,255, + 1,221,221,221,5,0,0,0,1,221,221,221,2,194,194,194,1,61,61,61, + 1,201,201,201,1,221,221,221,2,185,185,185,1,9,9,9,1,221,221,221, + 5,128,128,128,1,0,0,0,1,224,224,224,1,255,255,255,1,218,218,218, + 5,0,0,0,1,218,218,218,1,141,141,141,1,66,66,66,1,201,201,201, + 1,218,218,218,1,27,27,27,1,194,194,194,1,200,200,200,1,21,21,21, + 1,218,218,218,5,128,128,128,1,0,0,0,1,224,224,224,1,255,255,255, + 1,215,215,215,5,0,0,0,1,215,215,215,1,16,16,16,1,0,0,0, + 3,149,149,149,1,16,16,16,1,20,20,20,1,151,151,151,1,215,215,215, + 5,128,128,128,1,0,0,0,1,224,224,224,1,255,255,255,1,212,212,212, + 20,128,128,128,1,0,0,0,1,224,224,224,1,255,255,255,1,209,209,209, + 20,128,128,128,1,0,0,0,1,224,224,224,1,128,128,128,22,0,0,0, + 25,255,255,255,120,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255, + 81,0,0,0,120,0,0) + ); + +const + objdata_tstockglyphdatabutton: record size: integer; data: array[0..704] of byte end = + (size: 705; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,21,116,115,116, + 111,99,107,103,108,121,112,104,100,97,116,97,98,117,116,116,111,110,23,98, + 105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108, + 111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111, + 110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99, + 111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97, + 103,101,10,64,2,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24, + 0,0,0,248,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255, + 255,255,120,224,224,224,25,255,255,255,22,0,0,0,1,224,224,224,1,255, + 255,255,1,235,235,235,20,128,128,128,1,0,0,0,1,224,224,224,1,255, + 255,255,1,232,232,232,20,128,128,128,1,0,0,0,1,224,224,224,1,255, + 255,255,1,214,214,214,1,26,26,26,1,229,229,229,1,154,154,154,1,19, + 19,19,1,16,16,16,1,133,133,133,1,103,103,103,1,13,13,13,2,115, + 115,115,1,229,229,229,9,128,128,128,1,0,0,0,1,224,224,224,1,255, + 255,255,1,87,87,87,1,0,0,0,1,226,226,226,1,26,26,26,1,178, + 178,178,1,185,185,185,1,9,9,9,1,226,226,226,2,172,172,172,1,15, + 15,15,1,226,226,226,9,128,128,128,1,0,0,0,1,224,224,224,1,255, + 255,255,1,216,216,216,1,0,0,0,1,223,223,223,3,179,179,179,1,59, + 59,59,1,223,223,223,1,143,143,143,1,3,3,3,1,90,90,90,1,223, + 223,223,1,62,62,62,2,223,223,223,1,62,62,62,2,223,223,223,1,62, + 62,62,2,128,128,128,1,0,0,0,1,224,224,224,1,255,255,255,1,221, + 221,221,1,0,0,0,1,221,221,221,2,194,194,194,1,61,61,61,1,201, + 201,201,1,221,221,221,2,185,185,185,1,9,9,9,1,221,221,221,1,62, + 62,62,2,221,221,221,1,62,62,62,2,221,221,221,1,62,62,62,2,128, + 128,128,1,0,0,0,1,224,224,224,1,255,255,255,1,218,218,218,1,0, + 0,0,1,218,218,218,1,141,141,141,1,66,66,66,1,201,201,201,1,218, + 218,218,1,27,27,27,1,194,194,194,1,200,200,200,1,21,21,21,1,218, + 218,218,9,128,128,128,1,0,0,0,1,224,224,224,1,255,255,255,1,215, + 215,215,1,0,0,0,1,215,215,215,1,16,16,16,1,0,0,0,3,149, + 149,149,1,16,16,16,1,20,20,20,1,151,151,151,1,215,215,215,9,128, + 128,128,1,0,0,0,1,224,224,224,1,255,255,255,1,212,212,212,20,128, + 128,128,1,0,0,0,1,224,224,224,1,255,255,255,1,209,209,209,20,128, + 128,128,1,0,0,0,1,224,224,224,1,128,128,128,22,0,0,0,25,255, + 255,255,120,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255,81,0, + 0,0,120,0,0) + ); + +const + objdata_tprogressbar: record size: integer; data: array[0..451] of byte end = + (size: 452; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,112,114, + 111,103,114,101,115,115,98,97,114,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,76,1,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,4,1,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,255,255,255,120,128,128,128,25,0,0, + 0,22,255,255,255,1,128,128,128,1,0,0,0,1,208,208,208,20,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,222,209,14,208,208, + 208,6,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,203, + 183,14,208,208,208,6,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,255,185,157,14,208,208,208,6,224,224,224,1,255,255,255,1,128,128, + 128,1,0,0,0,1,255,166,131,14,208,208,208,6,224,224,224,1,255,255, + 255,1,128,128,128,1,0,0,0,1,255,147,105,14,208,208,208,6,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,128,79,14,208,208, + 208,6,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,110, + 53,14,208,208,208,6,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,255,91,26,14,208,208,208,6,224,224,224,1,255,255,255,1,128,128, + 128,1,0,0,0,1,208,208,208,20,224,224,224,1,255,255,255,1,128,128, + 128,1,224,224,224,22,255,255,255,145,16,0,0,0,0,0,0,120,255,255, + 255,255,255,255,255,81,0,0,0,120,0,0) + ); + +const + objdata_thexstringedit: record size: integer; data: array[0..817] of byte end = + (size: 818; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,104,101, + 120,115,116,114,105,110,103,101,100,105,116,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,184,2,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,112,2,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,120,128,128,128,25, + 0,0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,20, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,2, + 254,254,254,1,31,31,31,1,173,173,173,1,255,255,255,1,205,205,205,1, + 49,49,49,1,50,50,50,1,208,208,208,1,255,255,255,2,249,249,249,1, + 28,28,28,1,255,255,255,3,0,0,0,1,255,255,255,1,0,0,0,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,2, + 207,207,207,1,78,78,78,1,97,97,97,1,255,255,255,1,71,71,71,1, + 188,188,188,1,187,187,187,1,75,75,75,1,255,255,255,1,200,200,200,1, + 39,39,39,1,0,0,0,1,255,255,255,4,0,0,0,1,255,255,255,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,2, + 128,128,128,1,199,199,199,1,53,53,53,1,253,253,253,1,15,15,15,1, + 242,242,242,1,240,240,240,1,17,17,17,1,255,255,255,1,252,252,252,1, + 247,247,247,1,0,0,0,1,255,255,255,4,0,0,0,1,255,255,255,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,2, + 74,74,74,1,253,253,253,1,102,102,102,1,201,201,201,1,1,1,1,1, + 254,254,254,1,252,252,252,1,2,2,2,1,255,255,255,3,0,0,0,1, + 255,255,255,4,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,255,255,255,1,224,224,224,1,0,0,0,3, + 125,125,125,1,15,15,15,1,242,242,242,1,240,240,240,1,16,16,16,1, + 255,255,255,3,0,0,0,1,255,255,255,4,0,0,0,1,255,255,255,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1, + 145,145,145,1,162,162,162,1,255,255,255,1,241,241,241,1,55,55,55,1, + 71,71,71,1,188,188,188,1,186,186,186,1,73,73,73,1,255,255,255,3, + 0,0,0,1,255,255,255,4,0,0,0,1,255,255,255,1,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,70,70,70,1, + 236,236,236,1,255,255,255,2,66,66,66,1,179,179,179,1,49,49,49,2, + 206,206,206,1,255,255,255,3,0,0,0,1,255,255,255,4,0,0,0,1, + 255,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 255,255,255,17,0,0,0,1,255,255,255,1,0,0,0,1,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,20,224,224,224,1, + 255,255,255,1,128,128,128,1,224,224,224,22,255,255,255,145,16,0,0,0, + 0,0,0,120,255,255,255,255,255,255,255,81,0,0,0,120,0,0) + ); + +initialization + registerobjectdata(@objdata_twidgetgrid,tbitmapcomp,'twidgetgrid'); + registerobjectdata(@objdata_tdataedit,tbitmapcomp,'tdataedit'); + registerobjectdata(@objdata_ttextedit,tbitmapcomp,'ttextedit'); + registerobjectdata(@objdata_tundotextedit,tbitmapcomp,'tundotextedit'); + registerobjectdata(@objdata_tslider,tbitmapcomp,'tslider'); + registerobjectdata(@objdata_tbooleanedit,tbitmapcomp,'tbooleanedit'); + registerobjectdata(@objdata_tbooleaneditradio,tbitmapcomp,'tbooleaneditradio'); + registerobjectdata(@objdata_tdataicon,tbitmapcomp,'tdataicon'); + registerobjectdata(@objdata_tdataimage,tbitmapcomp,'tdataimage'); + registerobjectdata(@objdata_tstringedit,tbitmapcomp,'tstringedit'); + registerobjectdata(@objdata_tdropdownlistedit,tbitmapcomp,'tdropdownlistedit'); + registerobjectdata(@objdata_tintegeredit,tbitmapcomp,'tintegeredit'); + registerobjectdata(@objdata_tint64edit,tbitmapcomp,'tint64edit'); + registerobjectdata(@objdata_trealedit,tbitmapcomp,'trealedit'); + registerobjectdata(@objdata_trealspinedit,tbitmapcomp,'trealspinedit'); + registerobjectdata(@objdata_tdatetimeedit,tbitmapcomp,'tdatetimeedit'); + registerobjectdata(@objdata_tenumedit,tbitmapcomp,'tenumedit'); + registerobjectdata(@objdata_thistoryedit,tbitmapcomp,'thistoryedit'); + registerobjectdata(@objdata_tenumtypeedit,tbitmapcomp,'tenumtypeedit'); + registerobjectdata(@objdata_tselector,tbitmapcomp,'tselector'); + registerobjectdata(@objdata_titemedit,tbitmapcomp,'titemedit'); + registerobjectdata(@objdata_trecordfieldedit,tbitmapcomp,'trecordfieldedit'); + registerobjectdata(@objdata_tdropdownitemedit,tbitmapcomp,'tdropdownitemedit'); + registerobjectdata(@objdata_tmbdropdownitemedit,tbitmapcomp,'tmbdropdownitemedit'); + registerobjectdata(@objdata_ttreeitemedit,tbitmapcomp,'ttreeitemedit'); + registerobjectdata(@objdata_tfoldedit,tbitmapcomp,'tfoldedit'); + registerobjectdata(@objdata_tmemoedit,tbitmapcomp,'tmemoedit'); + registerobjectdata(@objdata_tkeystringedit,tbitmapcomp,'tkeystringedit'); + registerobjectdata(@objdata_tpointeredit,tbitmapcomp,'tpointeredit'); + registerobjectdata(@objdata_tcalendardatetimeedit,tbitmapcomp,'tcalendardatetimeedit'); + registerobjectdata(@objdata_tdatabutton,tbitmapcomp,'tdatabutton'); + registerobjectdata(@objdata_tstockglyphdatabutton,tbitmapcomp,'tstockglyphdatabutton'); + registerobjectdata(@objdata_tprogressbar,tbitmapcomp,'tprogressbar'); + registerobjectdata(@objdata_thexstringedit,tbitmapcomp,'thexstringedit'); +end. diff --git a/mseide-msegui/lib/common/regcomponents/regexperimental.pas b/mseide-msegui/lib/common/regcomponents/regexperimental.pas new file mode 100644 index 0000000..b7d10d5 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regexperimental.pas @@ -0,0 +1,31 @@ +{ MSEide Copyright (c) 1999-2010 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regexperimental; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +implementation +uses + msedesignintf,msetraywidget; + +procedure Register; +begin +// registercomponents('Exp',[]); + registercomponenttabhints(['Exp'],['Experimental components']); +end; +initialization + register; +end. diff --git a/mseide-msegui/lib/common/regcomponents/regglob.pas b/mseide-msegui/lib/common/regcomponents/regglob.pas new file mode 100644 index 0000000..52ce861 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regglob.pas @@ -0,0 +1,144 @@ +{ MSEide Copyright (c) 1999-2017 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regglob; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msepropertyeditors,typinfo,msebitmap,msetypes{msestrings}; + +type + tstockglypheditor = class(tenumpropertyeditor) + protected + function hasimagelist(): boolean; + function gettypeinfo: ptypeinfo; override; + function getdefaultstate: propertystatesty; override; + public + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + procedure edit; override; + end; + + tstockglypharraypropertyeditor = class(tintegerarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + timagenrpropertyeditor = class(tordinalpropertyeditor) + private + fintf: iimagelistinfo; + protected + function getdefaultstate: propertystatesty; override; + public + procedure edit; override; + end; + +implementation +uses + msestockobjects,mseimageselectorform,mseclasses,mseformatstr; + +{ tstockglypharraypropertyeditor } + +function tstockglypharraypropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tstockglypheditor; +end; + +{ tstockglypheditor } + +function tstockglypheditor.gettypeinfo: ptypeinfo; +begin + result:= typeinfo(stockglyphty); +end; + +function tstockglypheditor.hasimagelist(): boolean; +var + intf1: iimagelistinfo; +begin + result:= getcorbainterface(fprops[0].instance, + typeinfo(iimagelistinfo),intf1) and (intf1.getimagelist() <> nil); +end; + +function tstockglypheditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_dialog]; + if hasimagelist then begin + result:= result - [ps_valuelist]; + end; +end; + +procedure tstockglypheditor.setvalue(const value: msestring); +begin + if hasimagelist then begin + setordvalue(strtointvalue(ansistring(value))); + end + else begin + inherited; + end; +end; + +function tstockglypheditor.getvalue: msestring; +begin + if hasimagelist then begin + result:= inttostrmse(getordvalue); + end + else begin + result:= inherited getvalue(); + end; +end; + +procedure tstockglypheditor.edit; +var + int1: integer; + intf1: iimagelistinfo; + list1: timagelist; +begin + int1:= getordvalue; + intf1:= nil; + if getcorbainterface(fprops[0].instance, + typeinfo(iimagelistinfo),intf1) then begin + list1:= intf1.getimagelist; + end; + if list1 = nil then begin + list1:= stockobjects.glyphs; + end; + timageselectorfo.create(nil,list1,int1); + setordvalue(int1); +end; + +{ timagenrpropertyeditor } + +function timagenrpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate; + if getcorbainterface(fprops[0].instance,typeinfo(iimagelistinfo),fintf) and + (fintf.getimagelist <> nil) then begin + result:= result + [ps_dialog]; + end; +end; + +procedure timagenrpropertyeditor.edit; +var + int1: integer; +begin + if fintf <> nil then begin + int1:= getordvalue; + timageselectorfo.create(nil,fintf.getimagelist,int1); + setordvalue(int1); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/regcomponents/regifi.pas b/mseide-msegui/lib/common/regcomponents/regifi.pas new file mode 100644 index 0000000..90055b9 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regifi.pas @@ -0,0 +1,259 @@ +{ MSEide Copyright (c) 1999-2014 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regifi; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +implementation +uses + mseglob,classes,mseificomp,msedesignintf,regifi_bmp,msepropertyeditors, + mseclasses,mselistbrowser, + msecomponenteditors,mseificomponenteditors,msetypes{msestrings},msedatalist, + {$ifndef mse_no_db}{$ifdef FPC}mseifidbcomp,{$endif}{$endif} + mseifidialogcomp,mseifigui,mseifiendpoint, + typinfo,mseififieldeditor; + +type + tificonnectedfields1 = class(tificonnectedfields); +{ + tifiwidgeteditor = class(tcomponentpropertyeditor) + protected + function filtercomponent(const acomponent: tcomponent): boolean; override; + end; +} + tifidropdowncolpropertyeditor = class(tarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + tificolitempropertyeditor = class(tclasselementeditor) + public + function getvalue: msestring; override; + end; + + tifilinkcomparraypropertyeditor = class(tpersistentarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + tififieldnamepropertyeditor = class(tstringpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + function getvalues: msestringarty; override; + end; + + tifisourcefieldnamepropertyeditor = class(tstringpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + procedure setvalue(const value: msestring); override; + function getvalues: msestringarty; override; + end; + + tifidataconnectionpropertyeditor = class(tcomponentinterfacepropertyeditor) + protected + function getintfinfo: ptypeinfo; override; + end; + + tificonnectedfieldselementeditor = class(tclasselementeditor) + public + function getvalue: msestring; override; + end; + + tificonnectedfieldspropertyeditor = class(tpersistentarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + function getdefaultstate: propertystatesty; override; + public + procedure edit; override; + end; + +procedure register; +begin + registercomponents('ifi',[tifiintegerendpoint,tifiint64endpoint, + tifipointerendpoint, + tifibooleanendpoint,tifirealendpoint,tifidatetimeendpoint, + tifistringendpoint,tifiactionendpoint, + tifiintegerlinkcomp,tifiint64linkcomp,tifipointerlinkcomp, + tifibooleanlinkcomp, + tifireallinkcomp,tifidatetimelinkcomp,tifistringlinkcomp, + tifienumlinkcomp,tifidropdownlistlinkcomp, + tifiactionlinkcomp,tififormlinkcomp, + tifidialoglinkcomp,tifidialog, + tifigridlinkcomp,tifiitemlinkcomp,tifitreeitemlinkcomp, + tconnectedifidatasource{,tifisqldatasource,} + {$ifndef mse_no_db}{$ifdef FPC},tifisqlresult{$endif}{$endif}]); + registercomponenttabhints(['ifi'], + ['MSEifi and socket components.'+lineend+ + 'Please compile with -dmse_with_pascalscript for PascalScript components.']); +// registerpropertyeditor(typeinfo(tcomponent),tcustomificlientcontroller, +// 'widget',tifiwidgeteditor); + registercomponenteditor(tifilinkcomp,tifilinkcompeditor); + registerpropertyeditor(typeinfo(tifidropdowncols),nil,'', + tifidropdowncolpropertyeditor); + registerpropertyeditor(typeinfo(tifilinkcomparrayprop),nil,'', + tifilinkcomparraypropertyeditor); + registerpropertyeditor(typeinfo(ififieldnamety),nil,'', + tififieldnamepropertyeditor); + registerpropertyeditor(typeinfo(ifisourcefieldnamety),nil,'', + tifisourcefieldnamepropertyeditor); + registerpropertyeditor(typeinfo(tificonnectedfields),nil,'', + tificonnectedfieldspropertyeditor); + registerpropertyeditor(typeinfo(tmsecomponent),tifidatasource,'connection', + tifidataconnectionpropertyeditor); +end; + +{ tifiwidgeteditor } +{ +function tifiwidgeteditor.filtercomponent( + const acomponent: tcomponent): boolean; +var + intf1: pointer; +begin +// result:= tcustomifivaluewidgetcontroller( +// fprops[0].instance).canconnect(acomponent); +end; +} +{ tifidropdowncolpropertyeditor } + +function tifidropdowncolpropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tmsestringdatalistpropertyeditor; +end; + +{ tificolitempropertyeditor } + +function tificolitempropertyeditor.getvalue: msestring; +var + obj1: tificolitem; +begin + result:= ''; + obj1:= tificolitem(getpointervalue); + if (obj1 <> nil) and (obj1.link <> nil) then begin + result:= msestring('<'+obj1.link.name+'>'); + end; +end; + +{ tifilinkcomparraypropertyeditor } + +function tifilinkcomparraypropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tificolitempropertyeditor; +end; + +{ tififieldnamepropertyeditor } + +function tififieldnamepropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_valuelist,ps_sortlist]; +end; + +function tififieldnamepropertyeditor.getvalues: msestringarty; +var + intf1: iififieldinfo; + intf2: iififieldsource; + dataso: tifidatasource; + types: listdatatypesty; +begin + result:= nil; + if getcorbainterface(fprops[0].instance,typeinfo(iififieldinfo), + intf1) then begin + dataso:= nil; + types:= []; + intf1.getfieldinfo(ansistring(fname),dataso,types); + if (dataso <> nil) and getcorbainterface(dataso,typeinfo(iififieldsource), + intf2) then begin + result:= intf2.getfieldnames(types); + end; + end; +end; + +{ tifisourcefieldnamepropertyeditor } + +function tifisourcefieldnamepropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_valuelist,ps_sortlist,ps_volatile]; +end; + +function tifisourcefieldnamepropertyeditor.getvalues: msestringarty; +var + intf1: iififieldlinksource; +begin + result:= nil; + if getcorbainterface(fprops[0].instance, + typeinfo(iififieldlinksource),intf1) then begin + result:= intf1.getfieldnames(ansistring(fname)); + end; +end; + +procedure tifisourcefieldnamepropertyeditor.setvalue(const value: msestring); +var + intf1: iififieldlinksource; +begin + inherited; + if getcorbainterface(fprops[0].instance, + typeinfo(iififieldlinksource),intf1) then begin + intf1.setdesignsourcefieldname(ansistring(value)); + end; +end; + +{ tifidataconnectionpropertyeditor } + +function tifidataconnectionpropertyeditor.getintfinfo: ptypeinfo; +begin + result:= typeinfo(iifidataconnection); +end; + +{ tificonnectedfieldselementeditor } + +function tificonnectedfieldselementeditor.getvalue: msestring; +begin + with tififieldlink(getpointervalue) do begin + result:= msestring('<'+sourcefieldname+'><'+fieldname+'>'); + end; +end; + +{ tificonnectedfieldspropertyeditor } + +function tificonnectedfieldspropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tificonnectedfieldselementeditor; +end; + +function tificonnectedfieldspropertyeditor.getdefaultstate: propertystatesty; +var + po1: pointer; +begin + result:= inherited getdefaultstate(); + if mseclasses.getcorbainterface( + tificonnectedfields1(getpointervalue).fowner.connection, + typeinfo(iifidbdataconnection),po1) then begin + + result:= result + [ps_dialog]; + end; +end; + +procedure tificonnectedfieldspropertyeditor.edit; +begin + if editififields(tificonnectedfields(getpointervalue)) then begin + modified; + end; +end; + +initialization + register; +end. diff --git a/mseide-msegui/lib/common/regcomponents/regifi_bmp.pas b/mseide-msegui/lib/common/regcomponents/regifi_bmp.pas new file mode 100644 index 0000000..429e142 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regifi_bmp.pas @@ -0,0 +1,2317 @@ +unit regifi_bmp; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msebitmap; + +const + objdata_tifiintegerendpoint: record size: integer; data: array[0..1282] of byte end = + (size: 1283; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,105,102, + 105,105,110,116,101,103,101,114,101,110,100,112,111,105,110,116,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,132,4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,164,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,151,255,143, + 25,208,208,208,15,0,0,0,2,208,208,208,5,151,255,143,2,208,208,208, + 7,0,0,0,11,208,208,208,4,151,255,143,2,208,208,208,7,0,0,0, + 12,208,208,208,3,151,255,143,2,208,208,208,15,0,0,0,3,208,208,208, + 4,151,255,143,2,208,208,208,15,0,0,0,2,208,208,208,5,151,255,143, + 2,208,208,208,22,151,255,143,2,208,208,208,5,0,0,0,2,208,208,208, + 3,0,0,0,2,208,208,208,3,0,0,0,3,208,208,208,4,151,255,143, + 2,208,208,208,4,0,0,0,3,208,208,208,2,0,0,0,10,208,208,208, + 3,151,255,143,2,208,208,208,3,0,0,0,4,208,208,208,1,0,0,0, + 3,208,208,208,1,0,0,0,4,208,208,208,1,0,0,0,2,208,208,208, + 3,151,255,143,2,208,208,208,3,0,0,0,4,208,208,208,5,0,0,0, + 2,208,208,208,2,0,0,0,3,208,208,208,3,151,255,143,2,208,208,208, + 5,0,0,0,2,208,208,208,3,0,0,0,3,208,208,208,3,0,0,0, + 3,208,208,208,3,151,255,143,2,208,208,208,5,0,0,0,2,208,208,208, + 2,0,0,0,4,208,208,208,4,0,0,0,3,208,208,208,2,151,255,143, + 2,208,208,208,5,0,0,0,2,208,208,208,2,0,0,0,2,208,208,208, + 3,0,0,0,2,208,208,208,1,0,0,0,3,208,208,208,2,151,255,143, + 2,208,208,208,5,0,0,0,2,208,208,208,1,0,0,0,11,208,208,208, + 3,151,255,143,2,208,208,208,16,0,0,0,1,208,208,208,5,151,255,143, + 2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208, + 22,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143, + 2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143,25,168,2,0, + 0,240,240,240,25,0,0,0,15,135,135,135,1,52,52,52,1,0,0,0, + 5,240,240,240,2,0,0,0,7,8,8,8,8,80,80,80,1,233,233,233, + 1,58,58,58,1,0,0,0,4,240,240,240,2,0,0,0,7,248,248,248, + 9,252,252,252,1,229,229,229,1,10,10,10,1,0,0,0,3,240,240,240, + 2,0,0,0,15,87,87,87,1,233,233,233,1,52,52,52,1,0,0,0, + 4,240,240,240,2,0,0,0,15,127,127,127,1,47,47,47,1,0,0,0, + 5,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,5,16,16,16, + 1,38,38,38,1,0,0,0,3,22,22,22,1,49,49,49,1,0,0,0, + 3,1,1,1,1,54,54,54,1,29,29,29,1,0,0,0,4,240,240,240, + 2,0,0,0,4,13,13,13,1,189,189,189,1,124,124,124,1,0,0,0, + 2,128,128,128,1,175,175,175,1,146,146,146,1,200,200,200,1,7,7,7, + 1,5,5,5,1,198,198,198,1,139,139,139,1,194,194,194,1,94,94,94, + 1,0,0,0,3,240,240,240,2,0,0,0,3,27,27,27,1,214,214,214, + 1,182,182,182,1,124,124,124,1,0,0,0,1,8,8,8,1,192,192,192, + 1,2,2,2,1,0,0,0,1,146,146,146,1,87,87,87,1,50,50,50, + 1,108,108,108,1,0,0,0,1,46,46,46,1,200,200,200,1,0,0,0, + 3,240,240,240,2,0,0,0,3,16,16,16,1,21,21,21,1,99,99,99, + 1,124,124,124,1,0,0,0,5,196,196,196,1,67,67,67,1,0,0,0, + 2,50,50,50,1,170,170,170,1,115,115,115,1,0,0,0,3,240,240,240, + 2,0,0,0,5,99,99,99,1,124,124,124,1,0,0,0,3,2,2,2, + 1,156,156,156,1,160,160,160,1,0,0,0,3,99,99,99,1,187,187,187, + 1,131,131,131,1,0,0,0,3,240,240,240,2,0,0,0,5,99,99,99, + 1,124,124,124,1,0,0,0,2,5,5,5,1,168,168,168,1,150,150,150, + 1,2,2,2,1,0,0,0,4,2,2,2,1,224,224,224,1,24,24,24, + 1,0,0,0,2,240,240,240,2,0,0,0,5,99,99,99,1,124,124,124, + 1,0,0,0,2,168,168,168,1,127,127,127,1,0,0,0,3,80,80,80, + 1,150,150,150,1,0,0,0,1,11,11,11,1,216,216,216,1,5,5,5, + 1,0,0,0,2,240,240,240,2,0,0,0,5,99,99,99,1,124,124,124, + 1,0,0,0,1,55,55,55,1,255,255,255,1,216,216,216,3,105,105,105, + 1,2,2,2,1,163,163,163,1,180,180,180,1,189,189,189,1,86,86,86, + 1,0,0,0,3,240,240,240,2,0,0,0,16,10,10,10,1,0,0,0, + 5,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240,240, + 2,0,0,0,22,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0, + 22,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240,240, + 25,0,0) + ); + +const + objdata_tifiint64endpoint: record size: integer; data: array[0..1140] of byte end = + (size: 1141; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,105,102, + 105,105,110,116,54,52,101,110,100,112,111,105,110,116,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,248, + 3,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,100, + 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,151,255,143,25,208, + 208,208,14,0,0,0,2,208,208,208,6,151,255,143,2,208,208,208,6,0, + 0,0,11,208,208,208,5,151,255,143,2,208,208,208,6,0,0,0,12,208, + 208,208,4,151,255,143,2,208,208,208,14,0,0,0,3,208,208,208,5,151, + 255,143,2,208,208,208,14,0,0,0,2,208,208,208,6,151,255,143,2,208, + 208,208,22,151,255,143,2,208,208,208,7,0,0,0,3,208,208,208,4,0, + 0,0,2,208,208,208,6,151,255,143,2,208,208,208,6,0,0,0,5,208, + 208,208,2,0,0,0,3,208,208,208,6,151,255,143,2,208,208,208,6,0, + 0,0,2,208,208,208,1,0,0,0,2,208,208,208,2,0,0,0,3,208, + 208,208,6,151,255,143,2,208,208,208,5,0,0,0,6,208,208,208,1,0, + 0,0,4,208,208,208,6,151,255,143,2,208,208,208,5,0,0,0,11,208, + 208,208,6,151,255,143,2,208,208,208,5,0,0,0,3,208,208,208,1,0, + 0,0,8,208,208,208,5,151,255,143,2,208,208,208,6,0,0,0,2,208, + 208,208,1,0,0,0,8,208,208,208,5,151,255,143,2,208,208,208,6,0, + 0,0,5,208,208,208,3,0,0,0,2,208,208,208,6,151,255,143,2,208, + 208,208,8,0,0,0,1,208,208,208,13,151,255,143,2,208,208,208,22,151, + 255,143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143,2,208, + 208,208,22,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,22,151, + 255,143,2,208,208,208,22,151,255,143,25,92,2,0,0,240,240,240,25,0, + 0,0,14,125,125,125,1,64,64,64,1,0,0,0,6,240,240,240,2,0, + 0,0,6,8,8,8,8,66,66,66,1,233,233,233,1,73,73,73,1,0, + 0,0,5,240,240,240,2,0,0,0,6,248,248,248,9,251,251,251,1,241, + 241,241,1,19,19,19,1,0,0,0,4,240,240,240,2,0,0,0,14,72, + 72,72,1,235,235,235,1,67,67,67,1,0,0,0,5,240,240,240,2,0, + 0,0,14,117,117,117,1,59,59,59,1,0,0,0,6,240,240,240,2,0, + 0,0,22,240,240,240,2,0,0,0,7,1,1,1,1,53,53,53,1,7, + 7,7,1,0,0,0,4,33,33,33,1,27,27,27,1,0,0,0,6,240, + 240,240,2,0,0,0,6,56,56,56,1,175,175,175,1,135,135,135,1,212, + 212,212,1,30,30,30,1,0,0,0,2,13,13,13,1,222,222,222,1,96, + 96,96,1,0,0,0,6,240,240,240,2,0,0,0,6,194,194,194,1,42, + 42,42,1,0,0,0,1,60,60,60,1,63,63,63,1,0,0,0,2,157, + 157,157,1,195,195,195,1,96,96,96,1,0,0,0,6,240,240,240,2,0, + 0,0,5,1,1,1,1,230,230,230,1,84,84,84,1,163,163,163,1,81, + 81,81,1,2,2,2,1,0,0,0,1,83,83,83,1,137,137,137,1,135, + 135,135,1,96,96,96,1,0,0,0,6,240,240,240,2,0,0,0,5,16, + 16,16,1,249,249,249,1,141,141,141,1,45,45,45,1,183,183,183,1,77, + 77,77,1,26,26,26,1,189,189,189,1,6,6,6,1,135,135,135,1,96, + 96,96,1,0,0,0,6,240,240,240,2,0,0,0,5,2,2,2,1,247, + 247,247,1,12,12,12,1,0,0,0,1,72,72,72,1,161,161,161,1,158, + 158,158,1,182,182,182,1,144,144,144,1,203,203,203,1,186,186,186,1,49, + 49,49,1,0,0,0,5,240,240,240,2,0,0,0,6,194,194,194,1,50, + 50,50,1,0,0,0,1,115,115,115,1,129,129,129,1,43,43,43,1,64, + 64,64,2,165,165,165,1,136,136,136,1,22,22,22,1,0,0,0,5,240, + 240,240,2,0,0,0,6,43,43,43,1,161,161,161,1,183,183,183,1,192, + 192,192,1,15,15,15,1,0,0,0,3,135,135,135,1,96,96,96,1,0, + 0,0,6,240,240,240,2,0,0,0,8,11,11,11,1,0,0,0,13,240, + 240,240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240,240,2,0, + 0,0,22,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,22,240, + 240,240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240,240,25,0, + 0) + ); + +const + objdata_tifipointerendpoint: record size: integer; data: array[0..938] of byte end = + (size: 939; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,105,102, + 105,112,111,105,110,116,101,114,101,110,100,112,111,105,110,116,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,44,3,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,180,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,150,255,143, + 25,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0, + 22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143, + 2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0, + 22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143, + 2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0, + 22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143, + 2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0, + 22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143, + 2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,25,64,2,0, + 0,244,244,244,25,0,0,0,13,113,113,113,1,79,79,79,1,0,0,0, + 7,244,244,244,2,0,0,0,6,6,6,6,7,54,54,54,1,232,232,232, + 1,98,98,98,1,0,0,0,6,244,244,244,2,0,0,0,6,250,250,250, + 8,252,252,252,1,255,255,255,1,30,30,30,1,0,0,0,5,244,244,244, + 2,0,0,0,13,53,53,53,1,231,231,231,1,82,82,82,1,0,0,0, + 6,244,244,244,2,0,0,0,13,105,105,105,1,70,70,70,1,0,0,0, + 7,244,244,244,2,0,0,0,22,244,244,244,2,0,0,0,5,2,2,2, + 1,51,51,51,3,21,21,21,1,0,0,0,12,244,244,244,2,0,0,0, + 5,11,11,11,1,244,244,244,1,136,136,136,1,141,141,141,1,202,202,202, + 1,126,126,126,1,0,0,0,11,244,244,244,2,0,0,0,5,11,11,11, + 1,231,231,231,1,0,0,0,2,6,6,6,1,230,230,230,1,15,15,15, + 1,0,0,0,1,73,73,73,1,108,108,108,1,41,41,41,1,0,0,0, + 6,244,244,244,2,0,0,0,5,11,11,11,1,231,231,231,1,0,0,0, + 2,6,6,6,1,230,230,230,1,15,15,15,1,132,132,132,1,166,166,166, + 1,87,87,87,1,203,203,203,1,61,61,61,1,0,0,0,5,244,244,244, + 2,0,0,0,5,11,11,11,1,245,245,245,1,153,153,153,1,156,156,156, + 1,204,204,204,1,125,125,125,1,4,4,4,1,232,232,232,1,8,8,8, + 1,0,0,0,1,65,65,65,1,172,172,172,1,0,0,0,5,244,244,244, + 2,0,0,0,5,11,11,11,1,236,236,236,1,51,51,51,1,45,45,45, + 1,13,13,13,1,0,0,0,1,12,12,12,1,222,222,222,1,0,0,0, + 2,38,38,38,1,198,198,198,1,0,0,0,5,244,244,244,2,0,0,0, + 5,11,11,11,1,231,231,231,1,0,0,0,5,211,211,211,1,34,34,34, + 1,0,0,0,1,102,102,102,1,150,150,150,1,0,0,0,5,244,244,244, + 2,0,0,0,5,11,11,11,1,231,231,231,1,0,0,0,5,59,59,59, + 1,205,205,205,1,181,181,181,1,194,194,194,1,23,23,23,1,0,0,0, + 5,244,244,244,2,0,0,0,14,14,14,14,1,0,0,0,7,244,244,244, + 2,0,0,0,22,244,244,244,2,0,0,0,22,244,244,244,2,0,0,0, + 22,244,244,244,2,0,0,0,22,244,244,244,2,0,0,0,22,244,244,244, + 2,0,0,0,22,244,244,244,2,0,0,0,22,244,244,244,25,0,0) + ); + +const + objdata_tifibooleanendpoint: record size: integer; data: array[0..1226] of byte end = + (size: 1227; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,105,102, + 105,98,111,111,108,101,97,110,101,110,100,112,111,105,110,116,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,76,4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,156,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,151,255,143, + 25,208,208,208,14,0,0,0,2,208,208,208,6,151,255,143,2,208,208,208, + 14,0,0,0,3,208,208,208,5,151,255,143,2,208,208,208,6,0,0,0, + 12,208,208,208,4,151,255,143,2,208,208,208,6,0,0,0,11,208,208,208, + 5,151,255,143,2,208,208,208,14,0,0,0,2,208,208,208,6,151,255,143, + 2,208,208,208,22,151,255,143,2,208,208,208,3,0,0,0,7,208,208,208, + 1,0,0,0,8,208,208,208,3,151,255,143,2,208,208,208,3,0,0,0, + 7,208,208,208,1,0,0,0,8,208,208,208,3,151,255,143,2,208,208,208, + 6,0,0,0,2,208,208,208,3,0,0,0,4,208,208,208,7,151,255,143, + 2,208,208,208,6,0,0,0,2,208,208,208,3,0,0,0,1,208,208,208, + 1,0,0,0,2,208,208,208,7,151,255,143,2,208,208,208,6,0,0,0, + 2,208,208,208,2,0,0,0,2,208,208,208,1,0,0,0,5,208,208,208, + 4,151,255,143,2,208,208,208,6,0,0,0,2,208,208,208,2,0,0,0, + 2,208,208,208,1,0,0,0,2,208,208,208,7,151,255,143,2,208,208,208, + 6,0,0,0,2,208,208,208,2,0,0,0,2,208,208,208,1,0,0,0, + 2,208,208,208,7,151,255,143,2,208,208,208,6,0,0,0,2,208,208,208, + 1,0,0,0,2,208,208,208,2,0,0,0,2,208,208,208,7,151,255,143, + 2,208,208,208,6,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208, + 2,0,0,0,2,208,208,208,7,151,255,143,2,208,208,208,22,151,255,143, + 2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208, + 22,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143, + 2,208,208,208,22,151,255,143,25,120,2,0,0,255,255,255,1,248,248,248, + 22,255,255,255,1,248,248,248,1,0,0,0,14,129,129,129,1,70,70,70, + 1,0,0,0,6,248,248,248,2,0,0,0,14,62,62,62,1,235,235,235, + 1,79,79,79,1,0,0,0,5,248,248,248,2,0,0,0,6,248,248,248, + 9,251,251,251,1,243,243,243,1,20,20,20,1,0,0,0,4,248,248,248, + 2,0,0,0,6,8,8,8,8,80,80,80,1,236,236,236,1,65,65,65, + 1,0,0,0,5,248,248,248,2,0,0,0,14,113,113,113,1,55,55,55, + 1,0,0,0,6,248,248,248,2,0,0,0,22,248,248,248,2,0,0,0, + 3,1,1,1,1,8,8,8,5,4,4,4,1,0,0,0,1,3,3,3, + 1,23,23,23,1,4,4,4,1,8,8,8,4,2,2,2,1,0,0,0, + 3,248,248,248,2,0,0,0,3,43,43,43,1,208,208,208,2,248,248,248, + 1,214,214,214,1,208,208,208,1,112,112,112,1,0,0,0,1,66,66,66, + 1,109,109,109,1,136,136,136,1,228,228,228,1,208,208,208,3,77,77,77, + 1,0,0,0,3,248,248,248,2,0,0,0,6,214,214,214,1,33,33,33, + 1,0,0,0,3,139,139,139,1,38,38,38,1,136,136,136,1,111,111,111, + 1,0,0,0,7,248,248,248,2,0,0,0,6,214,214,214,1,33,33,33, + 1,0,0,0,3,178,178,178,1,0,0,0,1,136,136,136,1,111,111,111, + 1,0,0,0,7,248,248,248,2,0,0,0,6,214,214,214,1,33,33,33, + 1,0,0,0,2,27,27,27,1,151,151,151,1,0,0,0,1,136,136,136, + 1,233,233,233,1,216,216,216,2,181,181,181,1,0,0,0,4,248,248,248, + 2,0,0,0,6,214,214,214,1,33,33,33,1,0,0,0,2,99,99,99, + 1,81,81,81,1,0,0,0,1,136,136,136,1,111,111,111,1,0,0,0, + 7,248,248,248,2,0,0,0,6,214,214,214,1,33,33,33,1,0,0,0, + 2,167,167,167,1,14,14,14,1,0,0,0,1,136,136,136,1,111,111,111, + 1,0,0,0,7,248,248,248,2,0,0,0,6,214,214,214,1,33,33,33, + 1,0,0,0,1,4,4,4,1,178,178,178,1,0,0,0,2,136,136,136, + 1,111,111,111,1,0,0,0,7,248,248,248,2,0,0,0,6,53,53,53, + 1,8,8,8,1,0,0,0,1,14,14,14,1,54,54,54,1,0,0,0, + 2,34,34,34,1,27,27,27,1,0,0,0,7,248,248,248,2,0,0,0, + 22,248,248,248,2,0,0,0,22,248,248,248,2,0,0,0,22,248,248,248, + 2,0,0,0,22,248,248,248,2,0,0,0,22,248,248,248,2,0,0,0, + 22,248,248,248,2,0,0,0,22,248,248,248,1,255,255,255,1,248,248,248, + 22,255,255,255,1,0,0) + ); + +const + objdata_tifirealendpoint: record size: integer; data: array[0..1443] of byte end = + (size: 1444; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,105,102, + 105,114,101,97,108,101,110,100,112,111,105,110,116,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,40,5, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,236,1, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,151,255,143,25,208,208, + 208,14,0,0,0,2,208,208,208,6,151,255,143,2,208,208,208,14,0,0, + 0,3,208,208,208,5,151,255,143,2,208,208,208,6,0,0,0,12,208,208, + 208,4,151,255,143,2,208,208,208,6,0,0,0,11,208,208,208,5,151,255, + 143,2,208,208,208,14,0,0,0,2,208,208,208,6,151,255,143,2,208,208, + 208,22,151,255,143,2,208,208,208,4,0,0,0,2,208,208,208,5,0,0, + 0,3,208,208,208,3,0,0,0,3,208,208,208,2,151,255,143,2,208,208, + 208,3,0,0,0,3,208,208,208,4,0,0,0,5,208,208,208,1,0,0, + 0,5,208,208,208,1,151,255,143,2,208,208,208,2,0,0,0,4,208,208, + 208,4,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,2,208,208,208,1,151,255,143,2,208,208, + 208,2,0,0,0,4,208,208,208,4,0,0,0,2,208,208,208,1,0,0, + 0,5,208,208,208,1,0,0,0,2,208,208,208,1,151,255,143,2,208,208, + 208,4,0,0,0,2,208,208,208,4,0,0,0,2,208,208,208,1,0,0, + 0,4,208,208,208,2,0,0,0,2,208,208,208,1,151,255,143,2,208,208, + 208,4,0,0,0,2,208,208,208,4,0,0,0,2,208,208,208,1,0,0, + 0,5,208,208,208,1,0,0,0,2,208,208,208,1,151,255,143,2,208,208, + 208,4,0,0,0,2,208,208,208,2,0,0,0,1,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,5,208,208, + 208,1,151,255,143,2,208,208,208,4,0,0,0,2,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,5,208,208,208,1,0,0,0,4,208,208, + 208,2,151,255,143,2,208,208,208,12,0,0,0,1,208,208,208,5,0,0, + 0,1,208,208,208,3,151,255,143,2,208,208,208,22,151,255,143,2,208,208, + 208,22,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255, + 143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143,2,208,208, + 208,22,151,255,143,25,4,3,0,0,240,240,240,25,0,0,0,14,119,119, + 119,1,59,59,59,1,0,0,0,6,240,240,240,2,0,0,0,14,66,66, + 66,1,232,232,232,1,67,67,67,1,0,0,0,5,240,240,240,2,0,0, + 0,6,232,232,232,9,242,242,242,1,241,241,241,1,19,19,19,1,0,0, + 0,4,240,240,240,2,0,0,0,6,24,24,24,8,80,80,80,1,235,235, + 235,1,73,73,73,1,0,0,0,5,240,240,240,2,0,0,0,14,125,125, + 125,1,64,64,64,1,0,0,0,6,240,240,240,2,0,0,0,22,240,240, + 240,2,0,0,0,4,49,49,49,1,6,6,6,1,0,0,0,5,6,6, + 6,1,60,60,60,1,20,20,20,1,0,0,0,3,22,22,22,1,58,58, + 58,1,6,6,6,1,0,0,0,2,240,240,240,2,0,0,0,3,62,62, + 62,1,246,246,246,1,20,20,20,1,0,0,0,4,20,20,20,1,215,215, + 215,1,148,148,148,1,221,221,221,1,52,52,52,1,0,0,0,1,86,86, + 86,1,206,206,206,1,161,161,161,1,197,197,197,1,6,6,6,1,0,0, + 0,1,240,240,240,2,0,0,0,2,104,104,104,1,199,199,199,1,224,224, + 224,1,20,20,20,1,0,0,0,4,136,136,136,1,123,123,123,1,0,0, + 0,1,84,84,84,1,173,173,173,1,0,0,0,1,224,224,224,1,34,34, + 34,1,0,0,0,1,173,173,173,1,85,85,85,1,0,0,0,1,240,240, + 240,2,0,0,0,2,36,36,36,1,2,2,2,1,203,203,203,1,20,20, + 20,1,0,0,0,4,179,179,179,1,73,73,73,1,0,0,0,1,37,37, + 37,1,216,216,216,1,11,11,11,1,240,240,240,1,1,1,1,1,0,0, + 0,1,125,125,125,1,127,127,127,1,0,0,0,1,240,240,240,2,0,0, + 0,4,203,203,203,1,20,20,20,1,0,0,0,4,203,203,203,1,40,40, + 40,1,0,0,0,1,7,7,7,1,229,229,229,1,35,35,35,1,208,208, + 208,1,0,0,0,2,95,95,95,1,141,141,141,1,0,0,0,1,240,240, + 240,2,0,0,0,4,203,203,203,1,20,20,20,1,0,0,0,4,181,181, + 181,1,76,76,76,1,0,0,0,1,46,46,46,1,203,203,203,1,13,13, + 13,1,243,243,243,1,1,1,1,1,0,0,0,1,134,134,134,1,115,115, + 115,1,0,0,0,1,240,240,240,2,0,0,0,4,203,203,203,1,20,20, + 20,1,0,0,0,2,7,7,7,1,0,0,0,1,123,123,123,1,127,127, + 127,1,0,0,0,1,103,103,103,1,153,153,153,1,0,0,0,1,211,211, + 211,1,38,38,38,1,1,1,1,1,189,189,189,1,65,65,65,1,0,0, + 0,1,240,240,240,2,0,0,0,4,203,203,203,1,20,20,20,1,0,0, + 0,1,28,28,28,1,227,227,227,1,0,0,0,1,15,15,15,1,162,162, + 162,1,191,191,191,1,204,204,204,1,22,22,22,1,0,0,0,1,58,58, + 58,1,188,188,188,1,200,200,200,1,148,148,148,1,0,0,0,2,240,240, + 240,2,0,0,0,12,10,10,10,1,0,0,0,5,10,10,10,1,0,0, + 0,3,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240, + 240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240,240,2,0,0, + 0,22,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240, + 240,25,0,0) + ); + +const + objdata_tifidatetimeendpoint: record size: integer; data: array[0..979] of byte end = + (size: 980; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,20,116,105,102, + 105,100,97,116,101,116,105,109,101,101,110,100,112,111,105,110,116,23,98,105, + 116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111, + 114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110, + 115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111, + 108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103, + 101,10,84,3,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0, + 0,0,180,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,150,255, + 143,25,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0, + 0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255, + 143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0, + 0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255, + 143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0, + 0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255, + 143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0, + 0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255, + 143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,25,104,2, + 0,0,244,244,244,25,0,0,0,13,113,113,113,1,79,79,79,1,0,0, + 0,7,244,244,244,2,0,0,0,6,6,6,6,7,54,54,54,1,232,232, + 232,1,98,98,98,1,0,0,0,6,244,244,244,2,0,0,0,6,250,250, + 250,8,252,252,252,1,255,255,255,1,30,30,30,1,0,0,0,5,244,244, + 244,2,0,0,0,13,53,53,53,1,231,231,231,1,82,82,82,1,0,0, + 0,6,244,244,244,2,0,0,0,13,105,105,105,1,70,70,70,1,0,0, + 0,7,244,244,244,2,0,0,0,22,244,244,244,2,0,0,0,4,29,29, + 29,1,51,51,51,1,50,50,50,1,16,16,16,1,0,0,0,4,2,2, + 2,1,51,51,51,5,28,28,28,1,0,0,0,3,244,244,244,2,0,0, + 0,4,146,146,146,1,181,181,181,1,146,146,146,1,203,203,203,1,127,127, + 127,1,0,0,0,3,5,5,5,1,136,136,136,2,222,222,222,1,162,162, + 162,1,136,136,136,1,74,74,74,1,0,0,0,3,244,244,244,2,0,0, + 0,4,146,146,146,1,97,97,97,1,0,0,0,1,4,4,4,1,192,192, + 192,1,69,69,69,1,0,0,0,1,79,79,79,1,0,0,0,3,184,184, + 184,1,57,57,57,1,0,0,0,5,244,244,244,2,0,0,0,4,146,146, + 146,1,97,97,97,1,0,0,0,2,98,98,98,1,147,147,147,1,4,4, + 4,1,146,146,146,1,3,3,3,1,0,0,0,2,184,184,184,1,57,57, + 57,1,0,0,0,5,244,244,244,2,0,0,0,4,146,146,146,1,97,97, + 97,1,0,0,0,2,78,78,78,1,164,164,164,1,0,0,0,5,184,184, + 184,1,57,57,57,1,0,0,0,5,244,244,244,2,0,0,0,4,146,146, + 146,1,97,97,97,1,0,0,0,2,112,112,112,1,136,136,136,1,0,0, + 0,5,184,184,184,1,57,57,57,1,0,0,0,5,244,244,244,2,0,0, + 0,4,146,146,146,1,97,97,97,1,0,0,0,1,29,29,29,1,216,216, + 216,1,44,44,44,1,0,0,0,5,184,184,184,1,57,57,57,1,0,0, + 0,5,244,244,244,2,0,0,0,4,146,146,146,1,223,223,223,1,204,204, + 204,1,199,199,199,1,74,74,74,1,0,0,0,1,4,4,4,1,223,223, + 223,1,3,3,3,1,0,0,0,2,184,184,184,1,57,57,57,1,0,0, + 0,5,244,244,244,2,0,0,0,11,2,2,2,1,0,0,0,10,244,244, + 244,2,0,0,0,22,244,244,244,2,0,0,0,22,244,244,244,2,0,0, + 0,22,244,244,244,2,0,0,0,22,244,244,244,2,0,0,0,22,244,244, + 244,2,0,0,0,22,244,244,244,2,0,0,0,22,244,244,244,25,0,0) + ); + +const + objdata_tifistringendpoint: record size: integer; data: array[0..1417] of byte end = + (size: 1418; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,18,116,105,102, + 105,115,116,114,105,110,103,101,110,100,112,111,105,110,116,23,98,105,116,109, + 97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4, + 6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11, + 10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111, + 114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10, + 12,5,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0, + 176,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,151,255,143,25, + 208,208,208,14,0,0,0,2,208,208,208,6,151,255,143,2,208,208,208,6, + 0,0,0,11,208,208,208,5,151,255,143,2,208,208,208,6,0,0,0,12, + 208,208,208,4,151,255,143,2,208,208,208,14,0,0,0,3,208,208,208,5, + 151,255,143,2,208,208,208,14,0,0,0,2,208,208,208,6,151,255,143,2, + 208,208,208,22,151,255,143,2,208,208,208,3,0,0,0,2,208,208,208,3, + 0,0,0,5,208,208,208,3,0,0,0,4,208,208,208,2,151,255,143,2, + 208,208,208,3,0,0,0,3,208,208,208,2,0,0,0,6,208,208,208,1, + 0,0,0,6,208,208,208,1,151,255,143,2,208,208,208,2,0,0,0,4, + 208,208,208,2,0,0,0,2,208,208,208,2,0,0,0,2,208,208,208,1, + 0,0,0,2,208,208,208,2,0,0,0,3,151,255,143,2,208,208,208,2, + 0,0,0,4,208,208,208,2,0,0,0,8,208,208,208,6,151,255,143,2, + 208,208,208,1,0,0,0,6,208,208,208,1,0,0,0,8,208,208,208,6, + 151,255,143,2,208,208,208,1,0,0,0,6,208,208,208,1,0,0,0,2, + 208,208,208,2,0,0,0,5,208,208,208,3,0,0,0,2,151,255,143,2, + 208,208,208,1,0,0,0,2,208,208,208,2,0,0,0,5,208,208,208,2, + 0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,2,0,0,0,2, + 208,208,208,1,151,255,143,2,0,0,0,3,208,208,208,3,0,0,0,8, + 208,208,208,1,0,0,0,6,208,208,208,1,151,255,143,2,208,208,208,17, + 0,0,0,2,208,208,208,3,151,255,143,2,208,208,208,22,151,255,143,2, + 208,208,208,22,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,22, + 151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143,2, + 208,208,208,22,151,255,143,25,36,3,0,0,240,240,240,25,0,0,0,14, + 125,125,125,1,64,64,64,1,0,0,0,6,240,240,240,2,0,0,0,6, + 8,8,8,8,68,68,68,1,234,234,234,1,73,73,73,1,0,0,0,5, + 240,240,240,2,0,0,0,6,248,248,248,9,251,251,251,1,241,241,241,1, + 19,19,19,1,0,0,0,4,240,240,240,2,0,0,0,14,66,66,66,1, + 232,232,232,1,67,67,67,1,0,0,0,5,240,240,240,2,0,0,0,14, + 119,119,119,1,59,59,59,1,0,0,0,6,240,240,240,2,0,0,0,22, + 240,240,240,2,0,0,0,3,38,38,38,1,43,43,43,1,0,0,0,3, + 52,52,52,1,72,72,72,1,71,71,71,1,50,50,50,1,8,8,8,1, + 0,0,0,3,4,4,4,1,56,56,56,1,79,79,79,1,12,12,12,1, + 0,0,0,2,240,240,240,2,0,0,0,3,193,193,193,1,207,207,207,1, + 1,1,1,1,0,0,0,2,187,187,187,1,176,176,176,1,153,153,153,1, + 173,173,173,1,211,211,211,1,17,17,17,1,0,0,0,1,24,24,24,1, + 207,207,207,1,164,164,164,1,136,136,136,1,214,214,214,1,78,78,78,1, + 0,0,0,1,240,240,240,2,0,0,0,2,43,43,43,1,183,183,183,1, + 167,167,167,1,69,69,69,1,0,0,0,2,187,187,187,1,60,60,60,1, + 0,0,0,2,161,161,161,1,81,81,81,1,0,0,0,1,191,191,191,1, + 83,83,83,1,0,0,0,2,36,36,36,1,188,188,188,1,3,3,3,1, + 240,240,240,2,0,0,0,2,140,140,140,1,96,96,96,1,74,74,74,1, + 173,173,173,1,0,0,0,2,187,187,187,1,103,103,103,1,56,56,56,1, + 80,80,80,1,198,198,198,1,27,27,27,1,9,9,9,1,232,232,232,1, + 0,0,0,6,240,240,240,2,0,0,0,1,5,5,5,1,222,222,222,1, + 12,12,12,1,3,3,3,1,223,223,223,1,26,26,26,1,0,0,0,1, + 187,187,187,1,188,188,188,1,168,168,168,1,181,181,181,1,199,199,199,1, + 37,37,37,1,35,35,35,1,218,218,218,1,0,0,0,6,240,240,240,2, + 0,0,0,1,80,80,80,1,232,232,232,1,208,208,208,2,226,226,226,1, + 126,126,126,1,0,0,0,1,187,187,187,1,60,60,60,1,0,0,0,2, + 96,96,96,1,161,161,161,1,2,2,2,1,240,240,240,1,7,7,7,1, + 0,0,0,3,108,108,108,1,13,13,13,1,240,240,240,2,0,0,0,1, + 178,178,178,1,73,73,73,1,0,0,0,2,41,41,41,1,226,226,226,1, + 3,3,3,1,187,187,187,1,60,60,60,1,0,0,0,2,122,122,122,1, + 159,159,159,1,0,0,0,1,153,153,153,1,140,140,140,1,0,0,0,2, + 82,82,82,1,191,191,191,1,0,0,0,1,240,240,240,2,24,24,24,1, + 226,226,226,1,3,3,3,1,0,0,0,3,198,198,198,1,79,79,79,1, + 187,187,187,1,225,225,225,1,216,216,216,1,217,217,217,1,190,190,190,1, + 30,30,30,1,0,0,0,1,7,7,7,1,168,168,168,1,206,206,206,1, + 202,202,202,1,182,182,182,1,39,39,39,1,0,0,0,1,240,240,240,2, + 0,0,0,17,2,2,2,1,12,12,12,1,0,0,0,3,240,240,240,2, + 0,0,0,22,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,22, + 240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240,240,2, + 0,0,0,22,240,240,240,2,0,0,0,22,240,240,240,25,0,0) + ); + +const + objdata_tifiactionendpoint: record size: integer; data: array[0..1937] of byte end = + (size: 1938; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,18,116,105,102, + 105,97,99,116,105,111,110,101,110,100,112,111,105,110,116,23,98,105,116,109, + 97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4, + 6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11, + 10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111, + 114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10, + 20,7,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0, + 52,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,151,255,143,25, + 208,208,208,13,0,0,0,1,0,0,106,1,0,0,255,1,208,208,208,6, + 151,255,143,2,208,208,208,13,0,0,149,1,2,2,17,1,2,2,135,1, + 0,0,0,1,208,208,208,5,151,255,143,2,208,208,208,6,0,0,0,5, + 0,0,1,1,0,0,10,1,3,3,12,1,6,6,10,1,0,0,0,1, + 0,0,39,1,0,0,0,1,208,208,208,4,151,255,143,2,208,208,208,6, + 0,0,0,4,0,0,185,1,13,13,233,1,108,108,238,1,114,114,193,1, + 3,3,19,1,0,0,71,1,0,0,0,2,208,208,208,4,151,255,143,2, + 208,208,208,9,0,0,255,1,41,41,255,1,159,159,255,1,86,86,243,1, + 3,3,95,1,0,0,22,1,0,0,0,3,208,208,208,4,151,255,143,2, + 208,208,208,7,0,0,255,1,3,3,255,1,86,86,254,1,149,149,254,1, + 32,32,233,1,0,0,145,1,0,0,0,4,208,208,208,5,151,255,143,2, + 208,208,208,6,0,0,255,1,17,17,255,1,135,135,254,1,85,85,247,1, + 6,6,210,1,0,0,37,1,0,0,0,3,208,208,208,7,151,255,143,2, + 208,208,208,5,0,0,255,1,47,47,255,1,140,140,254,1,29,29,238,1, + 0,0,132,1,0,0,0,4,208,208,208,8,151,255,143,2,208,208,208,3, + 0,0,255,1,4,4,255,1,90,90,254,1,85,85,251,1,5,5,210,1, + 0,0,23,1,0,0,0,3,208,208,208,10,151,255,143,2,208,208,208,3, + 0,0,255,1,53,53,255,1,64,64,251,1,3,3,228,1,0,0,43,1, + 0,0,0,3,208,208,208,11,151,255,143,2,208,208,208,4,0,0,197,1, + 0,0,217,1,0,0,237,1,0,0,247,2,0,0,0,1,208,208,208,12, + 151,255,143,2,208,208,208,5,0,0,0,1,0,0,158,1,0,0,226,1, + 0,0,245,1,0,0,250,1,0,0,241,1,208,208,208,11,151,255,143,2, + 208,208,208,6,0,0,0,2,0,0,189,1,0,0,235,1,0,0,247,1, + 0,0,250,1,0,0,205,1,208,208,208,9,151,255,143,2,208,208,208,8, + 0,0,0,1,0,0,72,1,0,0,208,1,0,0,241,1,0,0,249,1, + 0,0,245,1,208,208,208,8,151,255,143,2,208,208,208,8,0,0,255,1, + 0,0,0,2,0,0,136,1,0,0,223,1,0,0,248,1,0,0,245,1, + 208,208,208,7,151,255,143,2,208,208,208,8,24,24,255,1,0,0,128,1, + 208,208,208,1,0,0,249,1,0,0,253,1,0,0,217,1,0,0,5,1, + 0,0,0,1,208,208,208,6,151,255,143,2,208,208,208,7,21,21,255,1, + 95,95,255,1,33,33,147,1,0,0,251,1,0,0,255,1,0,0,233,1, + 0,0,0,3,208,208,208,6,151,255,143,2,208,208,208,7,80,80,255,1, + 161,161,255,1,28,28,218,1,0,0,246,1,0,0,0,4,208,208,208,7, + 151,255,143,2,208,208,208,6,60,60,255,1,158,158,255,1,149,149,255,1, + 81,81,253,1,20,20,249,1,0,0,250,2,0,0,0,1,208,208,208,8, + 151,255,143,2,208,208,208,5,28,28,255,1,133,133,255,1,151,151,255,1, + 80,80,251,1,21,21,230,1,0,0,203,1,0,0,169,1,0,0,69,1, + 0,0,0,2,208,208,208,7,151,255,143,2,208,208,208,5,76,76,255,1, + 117,117,250,1,36,36,161,1,0,0,36,1,0,0,0,5,208,208,208,8, + 151,255,143,2,208,208,208,5,0,0,0,8,208,208,208,9,151,255,143,8, + 150,254,142,1,150,253,142,1,150,254,142,1,151,255,143,14,168,3,0,0, + 240,240,240,25,0,0,0,13,102,102,102,1,110,110,110,1,10,10,10,1, + 0,0,0,6,240,240,240,2,0,0,0,13,151,151,151,1,250,250,250,1, + 157,157,157,1,1,1,1,1,0,0,0,5,240,240,240,2,0,0,0,6, + 240,240,240,5,241,241,241,1,250,250,250,1,252,252,252,1,255,255,255,2, + 48,48,48,1,1,1,1,1,0,0,0,4,240,240,240,2,0,0,0,6, + 16,16,16,4,58,58,58,1,188,188,188,1,233,233,233,1,244,244,244,1, + 250,250,250,1,183,183,183,1,41,41,41,1,3,3,3,1,0,0,0,4, + 240,240,240,2,0,0,0,9,93,93,93,1,193,193,193,1,250,250,250,1, + 213,213,213,1,215,215,215,1,142,142,142,1,52,52,52,1,12,12,12,1, + 1,1,1,1,0,0,0,4,240,240,240,2,0,0,0,7,7,7,7,1, + 147,147,147,1,205,205,205,1,236,236,236,1,200,200,200,1,125,125,125,1, + 67,67,67,1,29,29,29,1,4,4,4,1,1,1,1,1,0,0,0,5, + 240,240,240,2,0,0,0,6,31,31,31,1,178,178,178,1,224,224,224,1, + 205,205,205,1,173,173,173,1,83,83,83,1,49,49,49,1,11,11,11,1, + 2,2,2,1,0,0,0,7,240,240,240,2,0,0,0,5,72,72,72,1, + 190,190,190,1,224,224,224,1,192,192,192,1,114,114,114,1,64,64,64,1, + 26,26,26,1,4,4,4,1,1,1,1,1,0,0,0,8,240,240,240,2, + 0,0,0,3,2,2,2,1,127,127,127,1,200,200,200,1,198,198,198,1, + 157,157,157,1,76,76,76,1,44,44,44,1,10,10,10,1,2,2,2,1, + 0,0,0,10,240,240,240,2,0,0,0,3,59,59,59,1,193,193,193,1, + 216,216,216,1,195,195,195,1,71,71,71,1,22,22,22,1,3,3,3,1, + 1,1,1,1,0,0,0,11,240,240,240,2,0,0,0,4,21,21,21,1, + 161,161,161,1,216,216,216,1,200,200,200,1,85,85,85,1,1,1,1,1, + 0,0,0,12,240,240,240,2,0,0,0,5,4,4,4,1,64,64,64,1, + 186,186,186,1,214,214,214,1,169,169,169,1,33,33,33,1,0,0,0,11, + 240,240,240,2,0,0,0,6,2,2,2,1,8,8,8,1,103,103,103,1, + 202,202,202,1,205,205,205,1,118,118,118,1,5,5,5,1,0,0,0,9, + 240,240,240,2,0,0,0,8,3,3,3,1,18,18,18,1,140,140,140,1, + 209,209,209,1,187,187,187,1,60,60,60,1,0,0,0,8,240,240,240,2, + 0,0,0,8,16,16,16,1,1,1,1,1,3,3,3,1,41,41,41,1, + 173,173,173,1,217,217,217,1,104,104,104,1,0,0,0,7,240,240,240,2, + 0,0,0,8,157,157,157,1,4,4,4,1,0,0,0,1,38,38,38,1, + 195,195,195,1,122,122,122,1,52,52,52,1,6,6,6,1,0,0,0,6, + 240,240,240,2,0,0,0,7,62,62,62,1,251,251,251,1,70,70,70,1, + 88,88,88,1,166,166,166,1,31,31,31,1,22,22,22,1,13,13,13,1, + 1,1,1,1,0,0,0,6,240,240,240,2,0,0,0,7,190,190,190,1, + 255,255,255,1,185,185,185,1,92,92,92,1,6,6,6,1,12,12,12,1, + 2,2,2,1,1,1,1,1,0,0,0,7,240,240,240,2,0,0,0,6, + 94,94,94,1,255,255,255,2,249,249,249,1,203,203,203,1,147,147,147,1, + 91,91,91,1,1,1,1,1,0,0,0,8,240,240,240,2,0,0,0,5, + 9,9,9,1,214,214,214,1,255,255,255,1,246,246,246,1,210,210,210,1, + 169,169,169,1,116,116,116,1,48,48,48,1,14,14,14,1,1,1,1,1, + 0,0,0,7,240,240,240,2,0,0,0,5,74,74,74,1,135,135,135,1, + 122,122,122,1,85,85,85,1,73,73,73,1,56,56,56,1,36,36,36,1, + 16,16,16,1,2,2,2,1,0,0,0,8,240,240,240,2,0,0,0,5, + 1,1,1,1,16,16,16,1,36,36,36,1,19,19,19,1,4,4,4,1, + 2,2,2,2,1,1,1,1,0,0,0,9,240,240,240,25,0,0) + ); + +const + objdata_tifilinkcomp: record size: integer; data: array[0..2863] of byte end = + (size: 2864; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,105,102, + 105,108,105,110,107,99,111,109,112,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,184,10,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,236,8,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,4,2,1,13,22, + 13,1,159,255,151,1,162,255,155,1,103,159,99,1,2,4,2,1,3,4, + 2,1,45,65,43,1,177,255,171,1,180,255,174,1,66,92,64,1,3,4, + 3,2,92,123,90,1,195,255,190,1,197,255,193,1,33,42,32,1,3,4, + 3,2,166,202,164,1,212,255,209,1,204,242,201,1,0,0,0,1,107,181, + 101,1,153,255,145,1,156,255,148,1,159,255,151,1,162,255,155,1,165,255, + 158,1,168,255,161,1,171,255,164,1,174,255,167,1,177,255,171,1,180,255, + 174,1,183,255,177,1,186,255,180,1,189,255,183,1,192,255,187,1,195,255, + 190,1,197,255,193,1,200,255,196,1,203,255,199,1,206,255,203,1,209,255, + 206,1,212,255,209,1,215,255,212,1,3,4,3,1,151,255,143,1,153,255, + 145,1,156,255,148,1,159,255,151,1,162,255,155,1,165,255,158,1,168,255, + 161,1,171,255,164,1,174,255,167,1,177,255,171,1,180,255,174,1,183,255, + 177,1,186,255,180,1,189,255,183,1,192,255,187,1,195,255,190,1,197,255, + 193,1,200,255,196,1,203,255,199,1,206,255,203,1,209,255,206,1,212,255, + 209,1,215,255,212,1,27,32,27,1,151,255,143,1,153,255,145,1,156,255, + 148,1,159,255,151,1,162,255,155,1,165,255,158,1,168,255,161,1,171,255, + 164,1,174,255,167,1,177,255,171,1,180,255,174,1,183,255,177,1,186,255, + 180,1,189,255,183,1,192,255,187,1,195,255,190,1,197,255,193,1,200,255, + 196,1,203,255,199,1,206,255,203,1,209,255,206,1,212,255,209,1,215,255, + 212,1,218,255,215,1,8,13,7,1,153,255,145,1,156,255,148,1,159,255, + 151,1,162,255,155,1,165,255,158,1,168,255,161,1,171,255,164,1,174,255, + 167,1,177,255,171,1,180,255,174,1,183,255,177,1,186,255,180,1,189,255, + 183,1,192,255,187,1,195,255,190,1,197,255,193,1,200,255,196,1,203,255, + 199,1,206,255,203,1,209,255,206,1,212,255,209,1,215,255,212,1,218,255, + 215,1,2,4,2,1,153,255,145,1,156,255,148,1,159,255,151,1,162,255, + 155,1,165,255,158,1,168,255,161,1,171,255,164,1,174,255,167,1,177,255, + 171,1,180,255,174,1,183,255,177,1,186,255,180,1,189,255,183,1,192,255, + 187,1,195,255,190,1,197,255,193,1,200,255,196,1,203,255,199,1,206,255, + 203,1,209,255,206,1,212,255,209,1,215,255,212,1,120,141,119,1,8,13, + 7,1,153,255,145,1,156,255,148,1,159,255,151,1,162,255,155,1,165,255, + 158,1,168,255,161,1,171,255,164,1,174,255,167,1,177,255,171,1,180,255, + 174,1,183,255,177,1,186,255,180,1,189,255,183,1,192,255,187,1,195,255, + 190,1,197,255,193,1,200,255,196,1,203,255,199,1,206,255,203,1,209,255, + 206,1,212,255,209,1,215,255,212,1,3,4,3,1,151,255,143,1,153,255, + 145,1,153,250,145,1,158,253,150,1,162,255,155,1,165,255,158,1,150,228, + 144,1,165,246,158,1,169,248,162,1,177,255,171,1,178,252,172,1,181,252, + 175,1,186,255,180,1,189,255,183,1,192,255,187,1,195,255,190,1,197,255, + 193,1,200,255,196,1,200,251,196,1,204,253,201,1,209,255,206,1,212,255, + 209,1,215,255,212,1,3,4,3,1,151,255,143,1,153,255,145,1,54,88, + 51,1,109,175,104,1,162,255,155,1,60,92,57,1,38,58,37,1,129,193, + 124,1,7,10,7,1,177,255,171,1,96,136,93,1,108,151,105,1,186,255, + 180,1,189,255,183,1,192,255,187,1,195,255,190,1,197,255,193,1,200,255, + 196,1,101,127,99,1,129,160,127,1,209,255,206,1,212,255,209,1,215,255, + 212,1,67,79,66,1,107,181,101,1,153,255,145,1,54,88,51,1,109,175, + 104,1,159,250,152,1,18,28,17,1,156,237,150,1,170,253,163,1,7,10, + 7,1,177,255,171,1,96,136,93,1,108,151,105,1,185,254,179,1,186,251, + 180,1,192,255,187,1,180,235,175,1,197,255,193,1,200,255,196,1,101,127, + 99,1,129,160,127,1,209,255,206,1,209,251,206,1,211,250,208,1,218,255, + 215,1,2,4,2,1,153,255,145,1,54,88,51,1,109,175,104,1,90,142, + 86,1,6,9,6,1,57,86,54,1,165,246,158,1,7,10,7,1,177,255, + 171,1,96,136,93,1,108,151,105,1,149,204,144,1,45,61,44,1,78,103, + 76,1,47,62,46,1,63,82,62,1,200,255,196,1,101,127,99,1,129,160, + 127,1,180,220,178,1,41,49,40,1,175,208,173,1,218,255,215,1,2,4, + 2,1,153,255,145,1,54,88,51,1,109,175,104,1,162,255,155,1,17,27, + 17,1,166,252,159,1,170,253,163,1,7,10,7,1,177,255,171,1,96,136, + 93,1,108,151,105,1,149,204,144,1,10,14,10,1,188,250,183,1,195,255, + 190,1,25,33,25,1,186,237,182,1,101,127,99,1,103,127,101,1,43,53, + 43,1,176,212,174,1,215,255,212,1,67,79,66,1,32,54,30,1,153,255, + 145,1,54,88,51,1,109,175,104,1,162,255,155,1,17,27,17,1,166,252, + 159,1,170,253,163,1,7,10,7,1,177,255,171,1,96,136,93,1,108,151, + 105,1,149,204,144,1,51,69,50,1,192,255,187,1,195,255,190,1,40,52, + 39,1,178,227,174,1,101,127,99,1,23,28,22,1,30,36,29,1,194,233, + 191,1,215,255,212,1,3,4,3,1,151,255,143,1,153,255,145,1,54,88, + 51,1,109,175,104,1,162,255,155,1,17,27,17,1,166,252,159,1,170,253, + 163,1,7,10,7,1,177,255,171,1,96,136,93,1,108,151,105,1,149,204, + 144,1,56,75,54,1,192,255,187,1,195,255,190,1,40,52,39,1,178,227, + 174,1,101,127,99,1,127,157,125,1,127,155,125,1,67,81,66,1,215,255, + 212,1,3,4,3,1,151,255,143,1,153,255,145,1,54,88,51,1,109,175, + 104,1,162,255,155,1,17,27,17,1,166,252,159,1,170,253,163,1,7,10, + 7,1,177,255,171,1,96,136,93,1,108,151,105,1,149,204,144,1,56,75, + 54,1,192,255,187,1,195,255,190,1,40,52,39,1,178,227,174,1,101,127, + 99,1,129,160,127,1,209,255,206,1,56,67,55,1,137,163,136,1,120,141, + 119,1,64,107,60,1,153,255,145,1,131,214,124,1,147,235,139,1,162,255, + 155,1,128,198,123,1,168,255,161,1,171,255,164,1,132,194,127,1,177,255, + 171,1,160,226,154,1,164,229,159,1,177,243,172,1,156,210,151,1,192,255, + 187,1,195,255,190,1,158,205,155,1,195,248,191,1,178,223,174,1,187,232, + 185,1,209,255,206,1,195,234,192,1,173,205,170,1,218,255,215,1,2,4, + 2,1,153,255,145,1,156,255,148,1,159,255,151,1,162,255,155,1,165,255, + 158,1,168,255,161,1,171,255,164,1,174,255,167,1,177,255,171,1,180,255, + 174,1,183,255,177,1,186,255,180,1,189,255,183,1,192,255,187,1,195,255, + 190,1,197,255,193,1,200,255,196,1,203,255,199,1,206,255,203,1,209,255, + 206,1,212,255,209,1,215,255,212,1,218,255,215,1,2,4,2,1,153,255, + 145,1,156,255,148,1,159,255,151,1,162,255,155,1,165,255,158,1,168,255, + 161,1,171,255,164,1,174,255,167,1,177,255,171,1,180,255,174,1,183,255, + 177,1,186,255,180,1,189,255,183,1,192,255,187,1,195,255,190,1,197,255, + 193,1,200,255,196,1,203,255,199,1,206,255,203,1,209,255,206,1,212,255, + 209,1,215,255,212,1,27,32,27,1,64,107,60,1,153,255,145,1,156,255, + 148,1,159,255,151,1,162,255,155,1,165,255,158,1,168,255,161,1,171,255, + 164,1,174,255,167,1,177,255,171,1,180,255,174,1,183,255,177,1,186,255, + 180,1,189,255,183,1,192,255,187,1,195,255,190,1,197,255,193,1,200,255, + 196,1,203,255,199,1,206,255,203,1,209,255,206,1,212,255,209,1,215,255, + 212,1,3,4,3,1,151,255,143,1,153,255,145,1,156,255,148,1,159,255, + 151,1,162,255,155,1,165,255,158,1,168,255,161,1,171,255,164,1,174,255, + 167,1,177,255,171,1,180,255,174,1,183,255,177,1,186,255,180,1,189,255, + 183,1,192,255,187,1,195,255,190,1,197,255,193,1,200,255,196,1,203,255, + 199,1,206,255,203,1,209,255,206,1,212,255,209,1,215,255,212,1,3,4, + 3,1,151,255,143,1,153,255,145,1,156,255,148,1,159,255,151,1,162,255, + 155,1,165,255,158,1,168,255,161,1,171,255,164,1,174,255,167,1,177,255, + 171,1,180,255,174,1,183,255,177,1,186,255,180,1,189,255,183,1,192,255, + 187,1,195,255,190,1,197,255,193,1,200,255,196,1,203,255,199,1,206,255, + 203,1,209,255,206,1,212,255,209,1,215,255,212,1,195,228,192,1,32,54, + 30,1,153,255,145,1,156,255,148,1,159,255,151,1,162,255,155,1,165,255, + 158,1,168,255,161,1,171,255,164,1,174,255,167,1,177,255,171,1,180,255, + 174,1,183,255,177,1,186,255,180,1,189,255,183,1,192,255,187,1,195,255, + 190,1,197,255,193,1,200,255,196,1,203,255,199,1,206,255,203,1,209,255, + 206,1,212,255,209,1,215,255,212,1,218,255,215,1,2,4,2,1,153,255, + 145,1,156,255,148,1,159,255,151,1,162,255,155,1,165,255,158,1,168,255, + 161,1,171,255,164,1,174,255,167,1,177,255,171,1,180,255,174,1,183,255, + 177,1,186,255,180,1,189,255,183,1,192,255,187,1,195,255,190,1,197,255, + 193,1,200,255,196,1,203,255,199,1,206,255,203,1,209,255,206,1,212,255, + 209,1,215,255,212,1,195,228,192,1,0,0,0,1,121,202,115,1,156,255, + 148,1,159,255,151,1,2,4,2,2,14,22,14,1,171,255,164,1,174,255, + 167,1,110,159,107,1,3,4,3,2,48,65,46,1,189,255,183,1,192,255, + 187,1,70,92,68,1,3,4,3,2,98,123,96,1,206,255,203,1,209,255, + 206,1,35,42,35,1,3,4,3,1,0,0,0,1,148,1,0,0,255,255, + 255,1,252,252,252,1,237,237,237,1,136,136,136,2,165,165,165,1,252,252, + 252,2,208,208,208,1,136,136,136,2,194,194,194,1,252,252,252,2,179,179, + 179,1,136,136,136,2,223,223,223,1,252,252,252,2,150,150,150,1,136,136, + 136,1,139,139,139,1,255,255,255,1,157,157,157,1,255,255,255,22,252,252, + 252,1,136,136,136,1,255,255,255,22,230,230,230,1,136,136,136,1,255,255, + 255,22,136,136,136,1,244,244,244,1,255,255,255,22,136,136,136,1,252,252, + 252,1,255,255,255,22,172,172,172,1,244,244,244,1,255,255,255,22,252,252, + 252,1,136,136,136,1,255,255,255,22,252,252,252,1,136,136,136,1,255,255, + 255,22,201,201,201,1,157,157,157,1,255,255,255,22,136,136,136,1,252,252, + 252,1,255,255,255,22,136,136,136,1,252,252,252,1,255,255,255,22,201,201, + 201,1,215,215,215,1,255,255,255,22,252,252,252,1,136,136,136,1,255,255, + 255,22,252,252,252,1,136,136,136,1,255,255,255,22,172,172,172,1,186,186, + 186,1,255,255,255,22,136,136,136,1,252,252,252,1,255,255,255,22,136,136, + 136,1,252,252,252,1,255,255,255,22,230,230,230,1,186,186,186,1,255,255, + 255,22,252,252,252,1,136,136,136,1,255,255,255,22,252,252,252,1,136,136, + 136,1,255,255,255,22,143,143,143,1,215,215,215,1,255,255,255,22,136,136, + 136,1,252,252,252,1,255,255,255,22,143,143,143,1,255,255,255,1,150,150, + 150,1,136,136,136,2,252,252,252,2,237,237,237,1,136,136,136,2,165,165, + 165,1,252,252,252,2,208,208,208,1,136,136,136,2,194,194,194,1,252,252, + 252,2,179,179,179,1,136,136,136,2,223,223,223,1,252,252,252,1,255,255, + 255,1,0,0) + ); + +const + objdata_tifiintegerlinkcomp: record size: integer; data: array[0..1370] of byte end = + (size: 1371; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,105,102, + 105,105,110,116,101,103,101,114,108,105,110,107,99,111,109,112,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,220,4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,188,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,151,255,143, + 25,208,208,208,6,0,0,0,2,208,208,208,6,0,0,0,2,208,208,208, + 6,151,255,143,2,208,208,208,5,0,0,0,12,208,208,208,5,151,255,143, + 2,208,208,208,4,0,0,0,14,208,208,208,4,151,255,143,2,208,208,208, + 5,0,0,0,3,208,208,208,6,0,0,0,3,208,208,208,5,151,255,143, + 2,208,208,208,6,0,0,0,2,208,208,208,6,0,0,0,2,208,208,208, + 6,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,5,0,0,0, + 2,208,208,208,3,0,0,0,2,208,208,208,3,0,0,0,3,208,208,208, + 4,151,255,143,2,208,208,208,4,0,0,0,3,208,208,208,2,0,0,0, + 10,208,208,208,3,151,255,143,2,208,208,208,3,0,0,0,4,208,208,208, + 1,0,0,0,3,208,208,208,1,0,0,0,4,208,208,208,1,0,0,0, + 2,208,208,208,3,151,255,143,2,208,208,208,3,0,0,0,4,208,208,208, + 5,0,0,0,2,208,208,208,2,0,0,0,3,208,208,208,3,151,255,143, + 2,208,208,208,5,0,0,0,2,208,208,208,3,0,0,0,3,208,208,208, + 3,0,0,0,3,208,208,208,3,151,255,143,2,208,208,208,5,0,0,0, + 2,208,208,208,2,0,0,0,4,208,208,208,4,0,0,0,3,208,208,208, + 2,151,255,143,2,208,208,208,5,0,0,0,2,208,208,208,2,0,0,0, + 2,208,208,208,3,0,0,0,2,208,208,208,1,0,0,0,3,208,208,208, + 2,151,255,143,2,208,208,208,5,0,0,0,2,208,208,208,1,0,0,0, + 11,208,208,208,3,151,255,143,2,208,208,208,16,0,0,0,1,208,208,208, + 5,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143, + 2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208, + 22,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143, + 25,232,2,0,0,240,240,240,25,0,0,0,6,59,59,59,1,130,130,130, + 1,0,0,0,6,125,125,125,1,64,64,64,1,0,0,0,6,240,240,240, + 2,0,0,0,5,67,67,67,1,236,236,236,1,76,76,76,1,8,8,8, + 6,68,68,68,1,234,234,234,1,73,73,73,1,0,0,0,5,240,240,240, + 2,0,0,0,4,15,15,15,1,237,237,237,1,251,251,251,1,248,248,248, + 8,251,251,251,1,241,241,241,1,19,19,19,1,0,0,0,4,240,240,240, + 2,0,0,0,5,61,61,61,1,233,233,233,1,74,74,74,1,0,0,0, + 6,66,66,66,1,232,232,232,1,67,67,67,1,0,0,0,5,240,240,240, + 2,0,0,0,6,53,53,53,1,124,124,124,1,0,0,0,6,119,119,119, + 1,59,59,59,1,0,0,0,6,240,240,240,2,0,0,0,22,240,240,240, + 2,0,0,0,5,16,16,16,1,38,38,38,1,0,0,0,3,22,22,22, + 1,49,49,49,1,0,0,0,3,1,1,1,1,54,54,54,1,29,29,29, + 1,0,0,0,4,240,240,240,2,0,0,0,4,13,13,13,1,189,189,189, + 1,124,124,124,1,0,0,0,2,128,128,128,1,175,175,175,1,146,146,146, + 1,200,200,200,1,7,7,7,1,5,5,5,1,198,198,198,1,139,139,139, + 1,194,194,194,1,94,94,94,1,0,0,0,3,240,240,240,2,0,0,0, + 3,27,27,27,1,214,214,214,1,182,182,182,1,124,124,124,1,0,0,0, + 1,8,8,8,1,192,192,192,1,2,2,2,1,0,0,0,1,146,146,146, + 1,87,87,87,1,50,50,50,1,108,108,108,1,0,0,0,1,46,46,46, + 1,200,200,200,1,0,0,0,3,240,240,240,2,0,0,0,3,16,16,16, + 1,21,21,21,1,99,99,99,1,124,124,124,1,0,0,0,5,196,196,196, + 1,67,67,67,1,0,0,0,2,50,50,50,1,170,170,170,1,115,115,115, + 1,0,0,0,3,240,240,240,2,0,0,0,5,99,99,99,1,124,124,124, + 1,0,0,0,3,2,2,2,1,156,156,156,1,160,160,160,1,0,0,0, + 3,99,99,99,1,187,187,187,1,131,131,131,1,0,0,0,3,240,240,240, + 2,0,0,0,5,99,99,99,1,124,124,124,1,0,0,0,2,5,5,5, + 1,168,168,168,1,150,150,150,1,2,2,2,1,0,0,0,4,2,2,2, + 1,224,224,224,1,24,24,24,1,0,0,0,2,240,240,240,2,0,0,0, + 5,99,99,99,1,124,124,124,1,0,0,0,2,168,168,168,1,127,127,127, + 1,0,0,0,3,80,80,80,1,150,150,150,1,0,0,0,1,11,11,11, + 1,216,216,216,1,5,5,5,1,0,0,0,2,240,240,240,2,0,0,0, + 5,99,99,99,1,124,124,124,1,0,0,0,1,55,55,55,1,255,255,255, + 1,216,216,216,3,105,105,105,1,2,2,2,1,163,163,163,1,180,180,180, + 1,189,189,189,1,86,86,86,1,0,0,0,3,240,240,240,2,0,0,0, + 16,10,10,10,1,0,0,0,5,240,240,240,2,0,0,0,22,240,240,240, + 2,0,0,0,22,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0, + 22,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240,240, + 2,0,0,0,22,240,240,240,25,0,0) + ); + +const + objdata_tifiint64linkcomp: record size: integer; data: array[0..1228] of byte end = + (size: 1229; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,105,102, + 105,105,110,116,54,52,108,105,110,107,99,111,109,112,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,80, + 4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,124, + 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,151,255,143,25,208, + 208,208,6,0,0,0,2,208,208,208,6,0,0,0,2,208,208,208,6,151, + 255,143,2,208,208,208,5,0,0,0,12,208,208,208,5,151,255,143,2,208, + 208,208,4,0,0,0,14,208,208,208,4,151,255,143,2,208,208,208,5,0, + 0,0,3,208,208,208,6,0,0,0,3,208,208,208,5,151,255,143,2,208, + 208,208,6,0,0,0,2,208,208,208,6,0,0,0,2,208,208,208,6,151, + 255,143,2,208,208,208,22,151,255,143,2,208,208,208,7,0,0,0,3,208, + 208,208,4,0,0,0,2,208,208,208,6,151,255,143,2,208,208,208,6,0, + 0,0,5,208,208,208,2,0,0,0,3,208,208,208,6,151,255,143,2,208, + 208,208,6,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,2,0, + 0,0,3,208,208,208,6,151,255,143,2,208,208,208,5,0,0,0,6,208, + 208,208,1,0,0,0,4,208,208,208,6,151,255,143,2,208,208,208,5,0, + 0,0,11,208,208,208,6,151,255,143,2,208,208,208,5,0,0,0,3,208, + 208,208,1,0,0,0,8,208,208,208,5,151,255,143,2,208,208,208,6,0, + 0,0,2,208,208,208,1,0,0,0,8,208,208,208,5,151,255,143,2,208, + 208,208,6,0,0,0,5,208,208,208,3,0,0,0,2,208,208,208,6,151, + 255,143,2,208,208,208,8,0,0,0,1,208,208,208,13,151,255,143,2,208, + 208,208,22,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,22,151, + 255,143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143,2,208, + 208,208,22,151,255,143,2,208,208,208,22,151,255,143,25,156,2,0,0,240, + 240,240,25,0,0,0,6,59,59,59,1,130,130,130,1,0,0,0,6,125, + 125,125,1,64,64,64,1,0,0,0,6,240,240,240,2,0,0,0,5,67, + 67,67,1,236,236,236,1,76,76,76,1,8,8,8,6,68,68,68,1,234, + 234,234,1,73,73,73,1,0,0,0,5,240,240,240,2,0,0,0,4,15, + 15,15,1,237,237,237,1,251,251,251,1,248,248,248,8,251,251,251,1,241, + 241,241,1,19,19,19,1,0,0,0,4,240,240,240,2,0,0,0,5,61, + 61,61,1,233,233,233,1,74,74,74,1,0,0,0,6,66,66,66,1,232, + 232,232,1,67,67,67,1,0,0,0,5,240,240,240,2,0,0,0,6,53, + 53,53,1,124,124,124,1,0,0,0,6,119,119,119,1,59,59,59,1,0, + 0,0,6,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,7,1, + 1,1,1,53,53,53,1,7,7,7,1,0,0,0,4,33,33,33,1,27, + 27,27,1,0,0,0,6,240,240,240,2,0,0,0,6,56,56,56,1,175, + 175,175,1,135,135,135,1,212,212,212,1,30,30,30,1,0,0,0,2,13, + 13,13,1,222,222,222,1,96,96,96,1,0,0,0,6,240,240,240,2,0, + 0,0,6,194,194,194,1,42,42,42,1,0,0,0,1,60,60,60,1,63, + 63,63,1,0,0,0,2,157,157,157,1,195,195,195,1,96,96,96,1,0, + 0,0,6,240,240,240,2,0,0,0,5,1,1,1,1,230,230,230,1,84, + 84,84,1,163,163,163,1,81,81,81,1,2,2,2,1,0,0,0,1,83, + 83,83,1,137,137,137,1,135,135,135,1,96,96,96,1,0,0,0,6,240, + 240,240,2,0,0,0,5,16,16,16,1,249,249,249,1,141,141,141,1,45, + 45,45,1,183,183,183,1,77,77,77,1,26,26,26,1,189,189,189,1,6, + 6,6,1,135,135,135,1,96,96,96,1,0,0,0,6,240,240,240,2,0, + 0,0,5,2,2,2,1,247,247,247,1,12,12,12,1,0,0,0,1,72, + 72,72,1,161,161,161,1,158,158,158,1,182,182,182,1,144,144,144,1,203, + 203,203,1,186,186,186,1,49,49,49,1,0,0,0,5,240,240,240,2,0, + 0,0,6,194,194,194,1,50,50,50,1,0,0,0,1,115,115,115,1,129, + 129,129,1,43,43,43,1,64,64,64,2,165,165,165,1,136,136,136,1,22, + 22,22,1,0,0,0,5,240,240,240,2,0,0,0,6,43,43,43,1,161, + 161,161,1,183,183,183,1,192,192,192,1,15,15,15,1,0,0,0,3,135, + 135,135,1,96,96,96,1,0,0,0,6,240,240,240,2,0,0,0,8,11, + 11,11,1,0,0,0,13,240,240,240,2,0,0,0,22,240,240,240,2,0, + 0,0,22,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,22,240, + 240,240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240,240,2,0, + 0,0,22,240,240,240,25,0,0) + ); + +const + objdata_tifipointerlinkcomp: record size: integer; data: array[0..1002] of byte end = + (size: 1003; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,105,102, + 105,112,111,105,110,116,101,114,108,105,110,107,99,111,109,112,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,108,3,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,180,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,150,255,143, + 25,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0, + 22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143, + 2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0, + 22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143, + 2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0, + 22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143, + 2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0, + 22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143, + 2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,25,128,2,0, + 0,244,244,244,25,0,0,0,6,47,47,47,1,119,119,119,1,0,0,0, + 6,126,126,126,1,65,65,65,1,0,0,0,6,244,244,244,2,0,0,0, + 5,51,51,51,1,230,230,230,1,84,84,84,1,0,0,0,6,60,60,60, + 1,234,234,234,1,79,79,79,1,0,0,0,5,244,244,244,2,0,0,0, + 4,14,14,14,1,235,235,235,1,249,249,249,1,244,244,244,8,249,249,249, + 1,240,240,240,1,19,19,19,1,0,0,0,4,244,244,244,2,0,0,0, + 5,65,65,65,1,233,233,233,1,77,77,77,1,12,12,12,6,74,74,74, + 1,233,233,233,1,68,68,68,1,0,0,0,5,244,244,244,2,0,0,0, + 6,63,63,63,1,138,138,138,1,0,0,0,6,116,116,116,1,57,57,57, + 1,0,0,0,6,244,244,244,2,0,0,0,22,244,244,244,2,0,0,0, + 5,2,2,2,1,51,51,51,3,21,21,21,1,0,0,0,12,244,244,244, + 2,0,0,0,5,11,11,11,1,244,244,244,1,136,136,136,1,141,141,141, + 1,202,202,202,1,126,126,126,1,0,0,0,11,244,244,244,2,0,0,0, + 5,11,11,11,1,231,231,231,1,0,0,0,2,6,6,6,1,230,230,230, + 1,15,15,15,1,0,0,0,1,73,73,73,1,108,108,108,1,41,41,41, + 1,0,0,0,6,244,244,244,2,0,0,0,5,11,11,11,1,231,231,231, + 1,0,0,0,2,6,6,6,1,230,230,230,1,15,15,15,1,132,132,132, + 1,166,166,166,1,87,87,87,1,203,203,203,1,61,61,61,1,0,0,0, + 5,244,244,244,2,0,0,0,5,11,11,11,1,245,245,245,1,153,153,153, + 1,156,156,156,1,204,204,204,1,125,125,125,1,4,4,4,1,232,232,232, + 1,8,8,8,1,0,0,0,1,65,65,65,1,172,172,172,1,0,0,0, + 5,244,244,244,2,0,0,0,5,11,11,11,1,236,236,236,1,51,51,51, + 1,45,45,45,1,13,13,13,1,0,0,0,1,12,12,12,1,222,222,222, + 1,0,0,0,2,38,38,38,1,198,198,198,1,0,0,0,5,244,244,244, + 2,0,0,0,5,11,11,11,1,231,231,231,1,0,0,0,5,211,211,211, + 1,34,34,34,1,0,0,0,1,102,102,102,1,150,150,150,1,0,0,0, + 5,244,244,244,2,0,0,0,5,11,11,11,1,231,231,231,1,0,0,0, + 5,59,59,59,1,205,205,205,1,181,181,181,1,194,194,194,1,23,23,23, + 1,0,0,0,5,244,244,244,2,0,0,0,14,14,14,14,1,0,0,0, + 7,244,244,244,2,0,0,0,22,244,244,244,2,0,0,0,22,244,244,244, + 2,0,0,0,22,244,244,244,2,0,0,0,22,244,244,244,2,0,0,0, + 22,244,244,244,2,0,0,0,22,244,244,244,2,0,0,0,22,244,244,244, + 25,0,0) + ); + +const + objdata_tifibooleanlinkcomp: record size: integer; data: array[0..1262] of byte end = + (size: 1263; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,105,102, + 105,98,111,111,108,101,97,110,108,105,110,107,99,111,109,112,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,112,4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,164,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,151,255,143, + 25,208,208,208,6,0,0,0,2,208,208,208,6,0,0,0,2,208,208,208, + 6,151,255,143,2,208,208,208,5,0,0,0,3,208,208,208,6,0,0,0, + 3,208,208,208,5,151,255,143,2,208,208,208,4,0,0,0,14,208,208,208, + 4,151,255,143,2,208,208,208,5,0,0,0,12,208,208,208,5,151,255,143, + 2,208,208,208,6,0,0,0,2,208,208,208,6,0,0,0,2,208,208,208, + 6,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,3,0,0,0, + 7,208,208,208,1,0,0,0,8,208,208,208,3,151,255,143,2,208,208,208, + 3,0,0,0,7,208,208,208,1,0,0,0,8,208,208,208,3,151,255,143, + 2,208,208,208,6,0,0,0,2,208,208,208,3,0,0,0,4,208,208,208, + 7,151,255,143,2,208,208,208,6,0,0,0,2,208,208,208,2,0,0,0, + 2,208,208,208,1,0,0,0,5,208,208,208,4,151,255,143,2,208,208,208, + 6,0,0,0,2,208,208,208,2,0,0,0,2,208,208,208,1,0,0,0, + 5,208,208,208,4,151,255,143,2,208,208,208,6,0,0,0,2,208,208,208, + 2,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,7,151,255,143, + 2,208,208,208,6,0,0,0,2,208,208,208,2,0,0,0,2,208,208,208, + 1,0,0,0,2,208,208,208,7,151,255,143,2,208,208,208,6,0,0,0, + 2,208,208,208,1,0,0,0,2,208,208,208,2,0,0,0,2,208,208,208, + 7,151,255,143,2,208,208,208,9,0,0,0,2,208,208,208,11,151,255,143, + 2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208, + 22,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143, + 2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143,25,148,2,0, + 0,240,240,240,25,0,0,0,6,48,48,48,1,118,118,118,1,0,0,0, + 6,125,125,125,1,64,64,64,1,0,0,0,6,240,240,240,2,0,0,0, + 5,56,56,56,1,233,233,233,1,82,82,82,1,0,0,0,6,62,62,62, + 1,233,233,233,1,73,73,73,1,0,0,0,5,240,240,240,2,0,0,0, + 4,15,15,15,1,237,237,237,1,247,247,247,1,240,240,240,8,246,246,246, + 1,241,241,241,1,19,19,19,1,0,0,0,4,240,240,240,2,0,0,0, + 5,73,73,73,1,234,234,234,1,74,74,74,1,16,16,16,6,78,78,78, + 1,233,233,233,1,67,67,67,1,0,0,0,5,240,240,240,2,0,0,0, + 6,65,65,65,1,136,136,136,1,0,0,0,6,119,119,119,1,59,59,59, + 1,0,0,0,6,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0, + 3,14,14,14,1,72,72,72,5,39,39,39,1,0,0,0,1,16,16,16, + 1,57,57,57,1,38,38,38,1,72,72,72,4,26,26,26,1,0,0,0, + 3,240,240,240,2,0,0,0,3,30,30,30,1,152,152,152,2,237,237,237, + 1,166,166,166,1,152,152,152,1,83,83,83,1,0,0,0,1,91,91,91, + 1,92,92,92,1,137,137,137,1,193,193,193,1,152,152,152,3,55,55,55, + 1,0,0,0,3,240,240,240,2,0,0,0,6,211,211,211,1,36,36,36, + 1,0,0,0,3,161,161,161,1,22,22,22,1,137,137,137,1,102,102,102, + 1,0,0,0,7,240,240,240,2,0,0,0,6,211,211,211,1,36,36,36, + 1,0,0,0,2,1,1,1,1,182,182,182,1,0,0,0,1,137,137,137, + 1,126,126,126,1,40,40,40,2,33,33,33,1,0,0,0,4,240,240,240, + 2,0,0,0,6,211,211,211,1,36,36,36,1,0,0,0,2,49,49,49, + 1,134,134,134,1,0,0,0,1,137,137,137,1,207,207,207,1,176,176,176, + 2,147,147,147,1,0,0,0,4,240,240,240,2,0,0,0,6,211,211,211, + 1,36,36,36,1,0,0,0,2,120,120,120,1,63,63,63,1,0,0,0, + 1,137,137,137,1,102,102,102,1,0,0,0,7,240,240,240,2,0,0,0, + 6,211,211,211,1,36,36,36,1,0,0,0,2,178,178,178,1,5,5,5, + 1,0,0,0,1,137,137,137,1,102,102,102,1,0,0,0,7,240,240,240, + 2,0,0,0,6,211,211,211,1,36,36,36,1,0,0,0,1,12,12,12, + 1,171,171,171,1,0,0,0,2,137,137,137,1,102,102,102,1,0,0,0, + 7,240,240,240,2,0,0,0,9,5,5,5,1,17,17,17,1,0,0,0, + 11,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240,240, + 2,0,0,0,22,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0, + 22,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240,240, + 25,0,0) + ); + +const + objdata_tifistringlinkcomp: record size: integer; data: array[0..1505] of byte end = + (size: 1506; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,18,116,105,102, + 105,115,116,114,105,110,103,108,105,110,107,99,111,109,112,23,98,105,116,109, + 97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4, + 6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11, + 10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111, + 114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10, + 100,5,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0, + 200,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,151,255,143,25, + 208,208,208,7,0,0,0,2,208,208,208,6,0,0,0,2,208,208,208,5, + 151,255,143,2,208,208,208,6,0,0,0,12,208,208,208,4,151,255,143,2, + 208,208,208,5,0,0,0,14,208,208,208,3,151,255,143,2,208,208,208,6, + 0,0,0,3,208,208,208,6,0,0,0,3,208,208,208,4,151,255,143,2, + 208,208,208,7,0,0,0,2,208,208,208,6,0,0,0,2,208,208,208,5, + 151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,3,0,0,0,2, + 208,208,208,3,0,0,0,5,208,208,208,3,0,0,0,4,208,208,208,2, + 151,255,143,2,208,208,208,3,0,0,0,3,208,208,208,2,0,0,0,6, + 208,208,208,1,0,0,0,6,208,208,208,1,151,255,143,2,208,208,208,2, + 0,0,0,4,208,208,208,2,0,0,0,2,208,208,208,2,0,0,0,2, + 208,208,208,1,0,0,0,2,208,208,208,2,0,0,0,3,151,255,143,2, + 208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,8,208,208,208,6, + 151,255,143,2,208,208,208,1,0,0,0,6,208,208,208,1,0,0,0,8, + 208,208,208,6,151,255,143,2,208,208,208,1,0,0,0,6,208,208,208,1, + 0,0,0,2,208,208,208,2,0,0,0,5,208,208,208,3,0,0,0,2, + 151,255,143,2,208,208,208,1,0,0,0,2,208,208,208,2,0,0,0,5, + 208,208,208,2,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,2, + 0,0,0,2,208,208,208,1,151,255,143,2,0,0,0,3,208,208,208,3, + 0,0,0,8,208,208,208,1,0,0,0,6,208,208,208,1,151,255,143,2, + 208,208,208,17,0,0,0,2,208,208,208,3,151,255,143,2,208,208,208,22, + 151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143,2, + 208,208,208,22,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,22, + 151,255,143,2,208,208,208,22,151,255,143,25,100,3,0,0,240,240,240,25, + 0,0,0,7,59,59,59,1,130,130,130,1,0,0,0,6,125,125,125,1, + 64,64,64,1,0,0,0,5,240,240,240,2,0,0,0,6,67,67,67,1, + 235,235,235,1,74,74,74,1,8,8,8,6,66,66,66,1,233,233,233,1, + 73,73,73,1,0,0,0,4,240,240,240,2,0,0,0,5,15,15,15,1, + 237,237,237,1,251,251,251,1,248,248,248,8,251,251,251,1,241,241,241,1, + 19,19,19,1,0,0,0,3,240,240,240,2,0,0,0,6,61,61,61,1, + 235,235,235,1,80,80,80,1,0,0,0,6,72,72,72,1,235,235,235,1, + 67,67,67,1,0,0,0,4,240,240,240,2,0,0,0,7,53,53,53,1, + 122,122,122,1,0,0,0,6,117,117,117,1,59,59,59,1,0,0,0,5, + 240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,3,38,38,38,1, + 43,43,43,1,0,0,0,3,52,52,52,1,72,72,72,1,71,71,71,1, + 50,50,50,1,8,8,8,1,0,0,0,3,4,4,4,1,56,56,56,1, + 79,79,79,1,12,12,12,1,0,0,0,2,240,240,240,2,0,0,0,3, + 193,193,193,1,207,207,207,1,1,1,1,1,0,0,0,2,187,187,187,1, + 176,176,176,1,153,153,153,1,173,173,173,1,211,211,211,1,17,17,17,1, + 0,0,0,1,24,24,24,1,207,207,207,1,164,164,164,1,136,136,136,1, + 214,214,214,1,78,78,78,1,0,0,0,1,240,240,240,2,0,0,0,2, + 43,43,43,1,183,183,183,1,167,167,167,1,69,69,69,1,0,0,0,2, + 187,187,187,1,60,60,60,1,0,0,0,2,161,161,161,1,81,81,81,1, + 0,0,0,1,191,191,191,1,83,83,83,1,0,0,0,2,36,36,36,1, + 188,188,188,1,3,3,3,1,240,240,240,2,0,0,0,2,140,140,140,1, + 96,96,96,1,74,74,74,1,173,173,173,1,0,0,0,2,187,187,187,1, + 103,103,103,1,56,56,56,1,80,80,80,1,198,198,198,1,27,27,27,1, + 9,9,9,1,232,232,232,1,0,0,0,6,240,240,240,2,0,0,0,1, + 5,5,5,1,222,222,222,1,12,12,12,1,3,3,3,1,223,223,223,1, + 26,26,26,1,0,0,0,1,187,187,187,1,188,188,188,1,168,168,168,1, + 181,181,181,1,199,199,199,1,37,37,37,1,35,35,35,1,218,218,218,1, + 0,0,0,6,240,240,240,2,0,0,0,1,80,80,80,1,232,232,232,1, + 208,208,208,2,226,226,226,1,126,126,126,1,0,0,0,1,187,187,187,1, + 60,60,60,1,0,0,0,2,96,96,96,1,161,161,161,1,2,2,2,1, + 240,240,240,1,7,7,7,1,0,0,0,3,108,108,108,1,13,13,13,1, + 240,240,240,2,0,0,0,1,178,178,178,1,73,73,73,1,0,0,0,2, + 41,41,41,1,226,226,226,1,3,3,3,1,187,187,187,1,60,60,60,1, + 0,0,0,2,122,122,122,1,159,159,159,1,0,0,0,1,153,153,153,1, + 140,140,140,1,0,0,0,2,82,82,82,1,191,191,191,1,0,0,0,1, + 240,240,240,2,24,24,24,1,226,226,226,1,3,3,3,1,0,0,0,3, + 198,198,198,1,79,79,79,1,187,187,187,1,225,225,225,1,216,216,216,1, + 217,217,217,1,190,190,190,1,30,30,30,1,0,0,0,1,7,7,7,1, + 168,168,168,1,206,206,206,1,202,202,202,1,182,182,182,1,39,39,39,1, + 0,0,0,1,240,240,240,2,0,0,0,17,2,2,2,1,12,12,12,1, + 0,0,0,3,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,22, + 240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240,240,2, + 0,0,0,22,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,22, + 240,240,240,25,0,0) + ); + +const + objdata_tifidropdownlistlinkcomp: record size: integer; data: array[0..1611] of byte end = + (size: 1612; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,24,116,105,102, + 105,100,114,111,112,100,111,119,110,108,105,115,116,108,105,110,107,99,111,109, + 112,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116, + 99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112, + 116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109, + 111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46, + 105,109,97,103,101,10,200,5,0,0,0,0,0,0,6,0,0,0,24,0, + 0,0,24,0,0,0,36,2,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,151,255,143,25,208,208,208,6,0,0,0,2,208,208,208,6,0,0, + 0,2,208,208,208,6,151,255,143,2,208,208,208,5,0,0,0,3,208,208, + 208,6,0,0,0,3,208,208,208,5,151,255,143,2,208,208,208,4,0,0, + 0,14,208,208,208,4,151,255,143,2,208,208,208,5,0,0,0,3,208,208, + 208,6,0,0,0,3,208,208,208,5,151,255,143,2,208,208,208,6,0,0, + 0,2,208,208,208,6,0,0,0,2,208,208,208,6,151,255,143,2,208,208, + 208,22,151,255,143,2,208,208,208,1,0,0,0,5,208,208,208,5,0,0, + 0,2,208,208,208,1,0,0,0,2,208,208,208,3,0,0,0,2,208,208, + 208,1,151,255,143,2,208,208,208,1,0,0,0,6,208,208,208,4,0,0, + 0,2,208,208,208,1,0,0,0,2,208,208,208,3,0,0,0,2,208,208, + 208,1,151,255,143,2,208,208,208,1,0,0,0,2,208,208,208,2,0,0, + 0,3,208,208,208,1,0,0,0,4,208,208,208,1,0,0,0,2,208,208, + 208,3,0,0,0,2,208,208,208,1,151,255,143,2,208,208,208,1,0,0, + 0,2,208,208,208,3,0,0,0,7,208,208,208,1,0,0,0,2,208,208, + 208,3,0,0,0,2,208,208,208,1,151,255,143,2,208,208,208,1,0,0, + 0,2,208,208,208,3,0,0,0,4,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,2,208,208,208,3,0,0,0,2,208,208,208,1,151,255, + 143,2,208,208,208,1,0,0,0,2,208,208,208,3,0,0,0,4,208,208, + 208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,3,0,0, + 0,2,208,208,208,1,151,255,143,2,208,208,208,1,0,0,0,2,208,208, + 208,2,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,2,208,208,208,3,0,0,0,2,208,208, + 208,1,151,255,143,2,208,208,208,1,0,0,0,6,208,208,208,1,0,0, + 0,5,208,208,208,1,0,0,0,7,208,208,208,1,151,255,143,2,208,208, + 208,10,0,0,0,1,208,208,208,11,151,255,143,2,208,208,208,22,151,255, + 143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143,2,208,208, + 208,22,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255, + 143,2,208,208,208,22,151,255,143,25,108,3,0,0,240,240,240,25,0,0, + 0,6,59,59,59,1,130,130,130,1,0,0,0,6,125,125,125,1,64,64, + 64,1,0,0,0,6,240,240,240,2,0,0,0,5,67,67,67,1,235,235, + 235,1,70,70,70,1,0,0,0,6,62,62,62,1,233,233,233,1,73,73, + 73,1,0,0,0,5,240,240,240,2,0,0,0,4,15,15,15,1,237,237, + 237,1,255,255,255,10,241,241,241,1,19,19,19,1,0,0,0,4,240,240, + 240,2,0,0,0,5,61,61,61,1,233,233,233,1,74,74,74,1,0,0, + 0,6,66,66,66,1,232,232,232,1,67,67,67,1,0,0,0,5,240,240, + 240,2,0,0,0,6,53,53,53,1,124,124,124,1,0,0,0,6,119,119, + 119,1,59,59,59,1,0,0,0,6,240,240,240,2,0,0,0,22,240,240, + 240,2,0,0,0,1,48,48,48,1,72,72,72,1,71,71,71,1,55,55, + 55,1,12,12,12,1,0,0,0,5,6,6,6,1,56,56,56,1,0,0, + 0,1,51,51,51,1,18,18,18,1,0,0,0,3,8,8,8,1,54,54, + 54,1,0,0,0,1,240,240,240,2,0,0,0,1,173,173,173,1,182,182, + 182,1,152,152,152,1,169,169,169,1,222,222,222,1,72,72,72,1,0,0, + 0,4,21,21,21,1,202,202,202,1,0,0,0,1,181,181,181,1,66,66, + 66,1,0,0,0,3,22,22,22,1,145,145,145,1,0,0,0,1,240,240, + 240,2,0,0,0,1,173,173,173,1,74,74,74,1,0,0,0,2,46,46, + 46,1,228,228,228,1,8,8,8,1,0,0,0,1,24,24,24,1,80,80, + 80,1,44,44,44,1,202,202,202,1,0,0,0,1,181,181,181,1,66,66, + 66,1,0,0,0,3,8,8,8,1,54,54,54,1,0,0,0,1,240,240, + 240,2,0,0,0,1,173,173,173,1,74,74,74,1,0,0,0,3,209,209, + 209,1,48,48,48,1,46,46,46,1,212,212,212,1,119,119,119,1,195,195, + 195,1,202,202,202,1,0,0,0,1,181,181,181,1,66,66,66,1,0,0, + 0,3,29,29,29,1,194,194,194,1,0,0,0,1,240,240,240,2,0,0, + 0,1,173,173,173,1,74,74,74,1,0,0,0,3,175,175,175,1,73,73, + 73,1,153,153,153,1,93,93,93,1,0,0,0,1,66,66,66,1,202,202, + 202,1,0,0,0,1,181,181,181,1,66,66,66,1,0,0,0,3,29,29, + 29,1,194,194,194,1,0,0,0,1,240,240,240,2,0,0,0,1,173,173, + 173,1,74,74,74,1,0,0,0,3,210,210,210,1,41,41,41,1,184,184, + 184,1,53,53,53,1,0,0,0,1,23,23,23,1,202,202,202,1,0,0, + 0,1,181,181,181,1,66,66,66,1,0,0,0,3,29,29,29,1,194,194, + 194,1,0,0,0,1,240,240,240,2,0,0,0,1,173,173,173,1,74,74, + 74,1,0,0,0,2,95,95,95,1,202,202,202,1,0,0,0,1,138,138, + 138,1,121,121,121,1,0,0,0,1,82,82,82,1,202,202,202,1,0,0, + 0,1,181,181,181,1,66,66,66,1,0,0,0,3,29,29,29,1,194,194, + 194,1,0,0,0,1,240,240,240,2,0,0,0,1,173,173,173,1,227,227, + 227,1,216,216,216,1,223,223,223,1,180,180,180,1,29,29,29,1,0,0, + 0,1,15,15,15,1,195,195,195,1,187,187,187,1,148,148,148,1,202,202, + 202,1,0,0,0,1,181,181,181,1,226,226,226,1,216,216,216,2,177,177, + 177,1,29,29,29,1,194,194,194,1,0,0,0,1,240,240,240,2,0,0, + 0,10,10,10,10,1,0,0,0,11,240,240,240,2,0,0,0,22,240,240, + 240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240,240,2,0,0, + 0,22,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240, + 240,2,0,0,0,22,240,240,240,25,0,0) + ); + +const + objdata_tifienumlinkcomp: record size: integer; data: array[0..1399] of byte end = + (size: 1400; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,105,102, + 105,101,110,117,109,108,105,110,107,99,111,109,112,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,252,4, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,228,1, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,151,255,143,25,208,208, + 208,6,0,0,0,2,208,208,208,6,0,0,0,2,208,208,208,6,151,255, + 143,2,208,208,208,5,0,0,0,3,208,208,208,6,0,0,0,3,208,208, + 208,5,151,255,143,2,208,208,208,4,0,0,0,14,208,208,208,4,151,255, + 143,2,208,208,208,5,0,0,0,3,208,208,208,6,0,0,0,3,208,208, + 208,5,151,255,143,2,208,208,208,6,0,0,0,2,208,208,208,6,0,0, + 0,2,208,208,208,6,151,255,143,2,208,208,208,22,151,255,143,2,208,208, + 208,2,0,0,0,7,208,208,208,13,151,255,143,2,208,208,208,2,0,0, + 0,7,208,208,208,13,151,255,143,2,208,208,208,2,0,0,0,2,208,208, + 208,5,0,0,0,5,208,208,208,1,0,0,0,2,208,208,208,1,0,0, + 0,2,208,208,208,2,151,255,143,2,208,208,208,2,0,0,0,6,208,208, + 208,1,0,0,0,5,208,208,208,1,0,0,0,2,208,208,208,1,0,0, + 0,2,208,208,208,2,151,255,143,2,208,208,208,2,0,0,0,6,208,208, + 208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,2,208,208,208,2,151,255,143,2,208,208, + 208,2,0,0,0,2,208,208,208,5,0,0,0,2,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208, + 208,2,151,255,143,2,208,208,208,2,0,0,0,2,208,208,208,5,0,0, + 0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,2,208,208,208,2,151,255,143,2,208,208,208,2,0,0, + 0,9,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,5,208,208, + 208,2,151,255,143,2,208,208,208,16,0,0,0,2,208,208,208,4,151,255, + 143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143,2,208,208, + 208,22,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255, + 143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143,25,224,2, + 0,0,240,240,240,25,0,0,0,6,59,59,59,1,130,130,130,1,0,0, + 0,6,125,125,125,1,64,64,64,1,0,0,0,6,240,240,240,2,0,0, + 0,5,67,67,67,1,235,235,235,1,70,70,70,1,0,0,0,6,62,62, + 62,1,233,233,233,1,73,73,73,1,0,0,0,5,240,240,240,2,0,0, + 0,4,15,15,15,1,237,237,237,1,255,255,255,10,241,241,241,1,19,19, + 19,1,0,0,0,4,240,240,240,2,0,0,0,5,61,61,61,1,233,233, + 233,1,74,74,74,1,0,0,0,6,66,66,66,1,232,232,232,1,67,67, + 67,1,0,0,0,5,240,240,240,2,0,0,0,6,53,53,53,1,124,124, + 124,1,0,0,0,6,119,119,119,1,59,59,59,1,0,0,0,6,240,240, + 240,2,0,0,0,22,240,240,240,2,0,0,0,2,3,3,3,1,72,72, + 72,5,14,14,14,1,0,0,0,13,240,240,240,2,0,0,0,2,12,12, + 12,1,247,247,247,1,152,152,152,4,30,30,30,1,0,0,0,13,240,240, + 240,2,0,0,0,2,12,12,12,1,235,235,235,1,0,0,0,5,30,30, + 30,1,28,28,28,2,76,76,76,1,6,6,6,1,0,0,0,1,54,54, + 54,1,8,8,8,1,0,0,0,1,27,27,27,1,35,35,35,1,0,0, + 0,2,240,240,240,2,0,0,0,2,12,12,12,1,239,239,239,1,48,48, + 48,3,44,44,44,1,0,0,0,1,106,106,106,1,197,197,197,1,127,127, + 127,1,164,164,164,2,0,0,0,1,194,194,194,1,29,29,29,1,0,0, + 0,1,98,98,98,1,125,125,125,1,0,0,0,2,240,240,240,2,0,0, + 0,2,12,12,12,1,249,249,249,1,168,168,168,3,154,154,154,1,0,0, + 0,1,106,106,106,1,172,172,172,1,0,0,0,1,11,11,11,1,218,218, + 218,1,0,0,0,1,194,194,194,1,29,29,29,1,0,0,0,1,98,98, + 98,1,125,125,125,1,0,0,0,2,240,240,240,2,0,0,0,2,12,12, + 12,1,235,235,235,1,0,0,0,5,106,106,106,1,125,125,125,1,0,0, + 0,1,2,2,2,1,221,221,221,1,0,0,0,1,194,194,194,1,30,30, + 30,1,0,0,0,1,102,102,102,1,125,125,125,1,0,0,0,2,240,240, + 240,2,0,0,0,2,12,12,12,1,235,235,235,1,0,0,0,5,106,106, + 106,1,125,125,125,1,0,0,0,1,2,2,2,1,221,221,221,1,0,0, + 0,1,184,184,184,1,56,56,56,1,0,0,0,1,150,150,150,1,125,125, + 125,1,0,0,0,2,240,240,240,2,0,0,0,2,12,12,12,1,252,252, + 252,1,216,216,216,4,77,77,77,1,106,106,106,1,125,125,125,1,0,0, + 0,1,2,2,2,1,221,221,221,1,0,0,0,1,88,88,88,1,221,221, + 221,1,151,151,151,1,147,147,147,1,125,125,125,1,0,0,0,2,240,240, + 240,2,0,0,0,16,8,8,8,1,4,4,4,1,0,0,0,4,240,240, + 240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240,240,2,0,0, + 0,22,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240, + 240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240,240,25,0,0) + ); + +const + objdata_tifireallinkcomp: record size: integer; data: array[0..1531] of byte end = + (size: 1532; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,105,102, + 105,114,101,97,108,108,105,110,107,99,111,109,112,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,128,5, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,4,2, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,151,255,143,25,208,208, + 208,7,0,0,0,2,208,208,208,6,0,0,0,2,208,208,208,5,151,255, + 143,2,208,208,208,6,0,0,0,12,208,208,208,4,151,255,143,2,208,208, + 208,5,0,0,0,14,208,208,208,3,151,255,143,2,208,208,208,6,0,0, + 0,3,208,208,208,6,0,0,0,3,208,208,208,4,151,255,143,2,208,208, + 208,7,0,0,0,2,208,208,208,6,0,0,0,2,208,208,208,5,151,255, + 143,2,208,208,208,22,151,255,143,2,208,208,208,4,0,0,0,2,208,208, + 208,5,0,0,0,3,208,208,208,3,0,0,0,3,208,208,208,2,151,255, + 143,2,208,208,208,3,0,0,0,3,208,208,208,4,0,0,0,5,208,208, + 208,1,0,0,0,5,208,208,208,1,151,255,143,2,208,208,208,2,0,0, + 0,4,208,208,208,4,0,0,0,2,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,151,255, + 143,2,208,208,208,2,0,0,0,4,208,208,208,4,0,0,0,2,208,208, + 208,1,0,0,0,5,208,208,208,1,0,0,0,2,208,208,208,1,151,255, + 143,2,208,208,208,4,0,0,0,2,208,208,208,4,0,0,0,2,208,208, + 208,1,0,0,0,4,208,208,208,2,0,0,0,2,208,208,208,1,151,255, + 143,2,208,208,208,4,0,0,0,2,208,208,208,4,0,0,0,2,208,208, + 208,1,0,0,0,5,208,208,208,1,0,0,0,2,208,208,208,1,151,255, + 143,2,208,208,208,4,0,0,0,2,208,208,208,2,0,0,0,1,208,208, + 208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0, + 0,5,208,208,208,1,151,255,143,2,208,208,208,4,0,0,0,2,208,208, + 208,1,0,0,0,2,208,208,208,1,0,0,0,5,208,208,208,1,0,0, + 0,4,208,208,208,2,151,255,143,2,208,208,208,12,0,0,0,1,208,208, + 208,5,0,0,0,1,208,208,208,3,151,255,143,2,208,208,208,22,151,255, + 143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143,2,208,208, + 208,22,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255, + 143,2,208,208,208,22,151,255,143,25,68,3,0,0,240,240,240,25,0,0, + 0,7,59,59,59,1,130,130,130,1,0,0,0,6,125,125,125,1,64,64, + 64,1,0,0,0,5,240,240,240,2,0,0,0,6,67,67,67,1,235,235, + 235,1,74,74,74,1,8,8,8,6,66,66,66,1,233,233,233,1,73,73, + 73,1,0,0,0,4,240,240,240,2,0,0,0,5,15,15,15,1,237,237, + 237,1,251,251,251,1,248,248,248,8,251,251,251,1,241,241,241,1,19,19, + 19,1,0,0,0,3,240,240,240,2,0,0,0,6,61,61,61,1,235,235, + 235,1,80,80,80,1,0,0,0,6,72,72,72,1,235,235,235,1,67,67, + 67,1,0,0,0,4,240,240,240,2,0,0,0,7,53,53,53,1,122,122, + 122,1,0,0,0,6,117,117,117,1,59,59,59,1,0,0,0,5,240,240, + 240,2,0,0,0,22,240,240,240,2,0,0,0,4,49,49,49,1,6,6, + 6,1,0,0,0,5,6,6,6,1,60,60,60,1,20,20,20,1,0,0, + 0,3,22,22,22,1,58,58,58,1,6,6,6,1,0,0,0,2,240,240, + 240,2,0,0,0,3,62,62,62,1,246,246,246,1,20,20,20,1,0,0, + 0,4,20,20,20,1,215,215,215,1,148,148,148,1,221,221,221,1,52,52, + 52,1,0,0,0,1,86,86,86,1,206,206,206,1,161,161,161,1,197,197, + 197,1,6,6,6,1,0,0,0,1,240,240,240,2,0,0,0,2,104,104, + 104,1,199,199,199,1,224,224,224,1,20,20,20,1,0,0,0,4,136,136, + 136,1,123,123,123,1,0,0,0,1,84,84,84,1,173,173,173,1,0,0, + 0,1,224,224,224,1,34,34,34,1,0,0,0,1,173,173,173,1,85,85, + 85,1,0,0,0,1,240,240,240,2,0,0,0,2,36,36,36,1,2,2, + 2,1,203,203,203,1,20,20,20,1,0,0,0,4,179,179,179,1,73,73, + 73,1,0,0,0,1,37,37,37,1,216,216,216,1,11,11,11,1,240,240, + 240,1,1,1,1,1,0,0,0,1,125,125,125,1,127,127,127,1,0,0, + 0,1,240,240,240,2,0,0,0,4,203,203,203,1,20,20,20,1,0,0, + 0,4,203,203,203,1,40,40,40,1,0,0,0,1,7,7,7,1,229,229, + 229,1,35,35,35,1,208,208,208,1,0,0,0,2,95,95,95,1,141,141, + 141,1,0,0,0,1,240,240,240,2,0,0,0,4,203,203,203,1,20,20, + 20,1,0,0,0,4,181,181,181,1,76,76,76,1,0,0,0,1,46,46, + 46,1,203,203,203,1,13,13,13,1,243,243,243,1,1,1,1,1,0,0, + 0,1,134,134,134,1,115,115,115,1,0,0,0,1,240,240,240,2,0,0, + 0,4,203,203,203,1,20,20,20,1,0,0,0,2,7,7,7,1,0,0, + 0,1,123,123,123,1,127,127,127,1,0,0,0,1,103,103,103,1,153,153, + 153,1,0,0,0,1,211,211,211,1,38,38,38,1,1,1,1,1,189,189, + 189,1,65,65,65,1,0,0,0,1,240,240,240,2,0,0,0,4,203,203, + 203,1,20,20,20,1,0,0,0,1,28,28,28,1,227,227,227,1,0,0, + 0,1,15,15,15,1,162,162,162,1,191,191,191,1,204,204,204,1,22,22, + 22,1,0,0,0,1,58,58,58,1,188,188,188,1,200,200,200,1,148,148, + 148,1,0,0,0,2,240,240,240,2,0,0,0,12,10,10,10,1,0,0, + 0,5,10,10,10,1,0,0,0,3,240,240,240,2,0,0,0,22,240,240, + 240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240,240,2,0,0, + 0,22,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240, + 240,2,0,0,0,22,240,240,240,25,0,0) + ); + +const + objdata_tifidatetimelinkcomp: record size: integer; data: array[0..1043] of byte end = + (size: 1044; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,20,116,105,102, + 105,100,97,116,101,116,105,109,101,108,105,110,107,99,111,109,112,23,98,105, + 116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111, + 114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110, + 115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111, + 108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103, + 101,10,148,3,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0, + 0,0,180,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,150,255, + 143,25,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0, + 0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255, + 143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0, + 0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255, + 143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0, + 0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255, + 143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0, + 0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255, + 143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,25,168,2, + 0,0,244,244,244,25,0,0,0,6,47,47,47,1,119,119,119,1,0,0, + 0,6,126,126,126,1,65,65,65,1,0,0,0,6,244,244,244,2,0,0, + 0,5,51,51,51,1,230,230,230,1,84,84,84,1,0,0,0,6,60,60, + 60,1,234,234,234,1,79,79,79,1,0,0,0,5,244,244,244,2,0,0, + 0,4,14,14,14,1,235,235,235,1,249,249,249,1,244,244,244,8,249,249, + 249,1,240,240,240,1,19,19,19,1,0,0,0,4,244,244,244,2,0,0, + 0,5,65,65,65,1,233,233,233,1,77,77,77,1,12,12,12,6,74,74, + 74,1,233,233,233,1,68,68,68,1,0,0,0,5,244,244,244,2,0,0, + 0,6,63,63,63,1,138,138,138,1,0,0,0,6,116,116,116,1,57,57, + 57,1,0,0,0,6,244,244,244,2,0,0,0,22,244,244,244,2,0,0, + 0,4,29,29,29,1,51,51,51,1,50,50,50,1,16,16,16,1,0,0, + 0,4,2,2,2,1,51,51,51,5,28,28,28,1,0,0,0,3,244,244, + 244,2,0,0,0,4,146,146,146,1,181,181,181,1,146,146,146,1,203,203, + 203,1,127,127,127,1,0,0,0,3,5,5,5,1,136,136,136,2,222,222, + 222,1,162,162,162,1,136,136,136,1,74,74,74,1,0,0,0,3,244,244, + 244,2,0,0,0,4,146,146,146,1,97,97,97,1,0,0,0,1,4,4, + 4,1,192,192,192,1,69,69,69,1,0,0,0,1,79,79,79,1,0,0, + 0,3,184,184,184,1,57,57,57,1,0,0,0,5,244,244,244,2,0,0, + 0,4,146,146,146,1,97,97,97,1,0,0,0,2,98,98,98,1,147,147, + 147,1,4,4,4,1,146,146,146,1,3,3,3,1,0,0,0,2,184,184, + 184,1,57,57,57,1,0,0,0,5,244,244,244,2,0,0,0,4,146,146, + 146,1,97,97,97,1,0,0,0,2,78,78,78,1,164,164,164,1,0,0, + 0,5,184,184,184,1,57,57,57,1,0,0,0,5,244,244,244,2,0,0, + 0,4,146,146,146,1,97,97,97,1,0,0,0,2,112,112,112,1,136,136, + 136,1,0,0,0,5,184,184,184,1,57,57,57,1,0,0,0,5,244,244, + 244,2,0,0,0,4,146,146,146,1,97,97,97,1,0,0,0,1,29,29, + 29,1,216,216,216,1,44,44,44,1,0,0,0,5,184,184,184,1,57,57, + 57,1,0,0,0,5,244,244,244,2,0,0,0,4,146,146,146,1,223,223, + 223,1,204,204,204,1,199,199,199,1,74,74,74,1,0,0,0,1,4,4, + 4,1,223,223,223,1,3,3,3,1,0,0,0,2,184,184,184,1,57,57, + 57,1,0,0,0,5,244,244,244,2,0,0,0,11,2,2,2,1,0,0, + 0,10,244,244,244,2,0,0,0,22,244,244,244,2,0,0,0,22,244,244, + 244,2,0,0,0,22,244,244,244,2,0,0,0,22,244,244,244,2,0,0, + 0,22,244,244,244,2,0,0,0,22,244,244,244,2,0,0,0,22,244,244, + 244,25,0,0) + ); + +const + objdata_tifiactionlinkcomp: record size: integer; data: array[0..1993] of byte end = + (size: 1994; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,18,116,105,102, + 105,97,99,116,105,111,110,108,105,110,107,99,111,109,112,23,98,105,116,109, + 97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4, + 6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11, + 10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111, + 114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10, + 76,7,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0, + 48,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,151,255,143,25, + 208,208,208,6,0,0,0,2,208,208,208,6,0,0,59,1,0,0,33,1, + 208,208,208,6,151,255,143,2,208,208,208,5,0,0,0,3,208,208,208,5, + 0,0,255,1,17,17,166,1,0,0,11,1,0,0,0,1,208,208,208,5, + 151,255,143,2,208,208,208,4,0,0,0,8,0,0,5,1,2,2,6,1, + 5,5,7,1,0,0,3,1,0,0,0,2,208,208,208,4,151,255,143,2, + 208,208,208,5,0,0,0,5,0,0,215,1,13,13,244,1,112,112,246,1, + 145,145,245,1,24,24,165,1,0,0,8,1,0,0,0,2,208,208,208,4, + 151,255,143,2,208,208,208,6,0,0,0,2,208,208,208,1,0,0,255,1, + 41,41,255,1,159,159,255,1,86,86,243,1,6,6,211,1,0,0,13,1, + 0,0,0,3,208,208,208,4,151,255,143,2,208,208,208,7,0,0,255,1, + 3,3,255,1,86,86,254,1,149,149,254,1,32,32,233,1,0,0,145,1, + 0,0,0,4,208,208,208,5,151,255,143,2,208,208,208,6,0,0,255,1, + 17,17,255,1,135,135,254,1,85,85,247,1,6,6,210,1,0,0,37,1, + 0,0,0,3,208,208,208,7,151,255,143,2,208,208,208,5,0,0,255,1, + 47,47,255,1,140,140,254,1,29,29,238,1,0,0,132,1,0,0,0,4, + 208,208,208,8,151,255,143,2,208,208,208,3,0,0,255,1,4,4,255,1, + 90,90,254,1,85,85,251,1,5,5,210,1,0,0,23,1,0,0,0,3, + 208,208,208,10,151,255,143,2,208,208,208,3,0,0,255,1,53,53,255,1, + 64,64,251,1,3,3,228,1,0,0,43,1,0,0,0,3,208,208,208,11, + 151,255,143,2,208,208,208,4,0,0,197,1,0,0,217,1,0,0,237,1, + 0,0,247,2,0,0,0,1,208,208,208,12,151,255,143,2,208,208,208,5, + 0,0,0,1,0,0,158,1,0,0,226,1,0,0,245,1,0,0,250,1, + 0,0,241,1,208,208,208,11,151,255,143,2,208,208,208,6,0,0,0,2, + 0,0,189,1,0,0,235,1,0,0,247,1,0,0,250,1,0,0,205,1, + 208,208,208,9,151,255,143,2,208,208,208,8,0,0,0,1,0,0,72,1, + 0,0,208,1,0,0,241,1,0,0,249,1,0,0,245,1,208,208,208,8, + 151,255,143,2,208,208,208,8,0,0,255,1,0,0,0,2,0,0,136,1, + 0,0,223,1,0,0,248,1,0,0,245,1,208,208,208,7,151,255,143,2, + 208,208,208,8,24,24,255,1,0,0,128,1,208,208,208,1,0,0,249,1, + 0,0,253,1,0,0,217,1,0,0,5,1,0,0,0,1,208,208,208,6, + 151,255,143,2,208,208,208,7,21,21,255,1,95,95,255,1,33,33,147,1, + 0,0,251,1,0,0,255,1,0,0,233,1,0,0,0,3,208,208,208,6, + 151,255,143,2,208,208,208,7,80,80,255,1,161,161,255,1,28,28,218,1, + 0,0,246,1,0,0,0,4,208,208,208,7,151,255,143,2,208,208,208,6, + 60,60,255,1,158,158,255,1,149,149,255,1,81,81,253,1,20,20,249,1, + 0,0,250,2,0,0,0,1,208,208,208,8,151,255,143,2,208,208,208,5, + 28,28,255,1,133,133,255,1,151,151,255,1,80,80,251,1,21,21,230,1, + 0,0,203,1,0,0,169,1,0,0,69,1,0,0,0,2,208,208,208,7, + 151,255,143,2,208,208,208,5,76,76,255,1,117,117,250,1,36,36,161,1, + 0,0,36,1,0,0,0,5,208,208,208,8,151,255,143,2,208,208,208,5, + 0,0,0,8,208,208,208,9,151,255,143,25,228,3,0,0,240,240,240,25, + 0,0,0,6,48,48,48,1,118,118,118,1,0,0,0,6,147,147,147,1, + 61,61,61,1,0,0,0,6,240,240,240,2,0,0,0,5,56,56,56,1, + 233,233,233,1,82,82,82,1,0,0,0,5,117,117,117,1,213,213,213,1, + 243,243,243,1,62,62,62,1,0,0,0,5,240,240,240,2,0,0,0,4, + 15,15,15,1,237,237,237,1,251,251,251,1,248,248,248,5,252,252,252,1, + 254,254,254,1,255,255,255,1,254,254,254,1,242,242,242,1,20,20,20,1, + 0,0,0,4,240,240,240,2,0,0,0,5,73,73,73,1,234,234,234,1, + 68,68,68,1,8,8,8,2,52,52,52,1,186,186,186,1,233,233,233,1, + 241,241,241,1,216,216,216,1,244,244,244,1,107,107,107,1,3,3,3,1, + 0,0,0,4,240,240,240,2,0,0,0,6,65,65,65,1,136,136,136,1, + 0,0,0,1,93,93,93,1,193,193,193,1,250,250,250,1,213,213,213,1, + 181,181,181,1,173,173,173,1,108,108,108,1,12,12,12,1,1,1,1,1, + 0,0,0,4,240,240,240,2,0,0,0,7,7,7,7,1,147,147,147,1, + 205,205,205,1,236,236,236,1,200,200,200,1,125,125,125,1,67,67,67,1, + 29,29,29,1,4,4,4,1,1,1,1,1,0,0,0,5,240,240,240,2, + 0,0,0,6,31,31,31,1,178,178,178,1,224,224,224,1,205,205,205,1, + 173,173,173,1,83,83,83,1,49,49,49,1,11,11,11,1,2,2,2,1, + 0,0,0,7,240,240,240,2,0,0,0,5,72,72,72,1,190,190,190,1, + 224,224,224,1,192,192,192,1,114,114,114,1,64,64,64,1,26,26,26,1, + 4,4,4,1,1,1,1,1,0,0,0,8,240,240,240,2,0,0,0,3, + 2,2,2,1,127,127,127,1,200,200,200,1,198,198,198,1,157,157,157,1, + 76,76,76,1,44,44,44,1,10,10,10,1,2,2,2,1,0,0,0,10, + 240,240,240,2,0,0,0,3,59,59,59,1,193,193,193,1,216,216,216,1, + 195,195,195,1,71,71,71,1,22,22,22,1,3,3,3,1,1,1,1,1, + 0,0,0,11,240,240,240,2,0,0,0,4,21,21,21,1,161,161,161,1, + 216,216,216,1,200,200,200,1,85,85,85,1,1,1,1,1,0,0,0,12, + 240,240,240,2,0,0,0,5,4,4,4,1,64,64,64,1,186,186,186,1, + 214,214,214,1,169,169,169,1,33,33,33,1,0,0,0,11,240,240,240,2, + 0,0,0,6,2,2,2,1,8,8,8,1,103,103,103,1,202,202,202,1, + 205,205,205,1,118,118,118,1,5,5,5,1,0,0,0,9,240,240,240,2, + 0,0,0,8,3,3,3,1,18,18,18,1,140,140,140,1,209,209,209,1, + 187,187,187,1,60,60,60,1,0,0,0,8,240,240,240,2,0,0,0,8, + 16,16,16,1,1,1,1,1,3,3,3,1,41,41,41,1,173,173,173,1, + 217,217,217,1,104,104,104,1,0,0,0,7,240,240,240,2,0,0,0,8, + 157,157,157,1,4,4,4,1,0,0,0,1,38,38,38,1,195,195,195,1, + 122,122,122,1,52,52,52,1,6,6,6,1,0,0,0,6,240,240,240,2, + 0,0,0,7,62,62,62,1,251,251,251,1,70,70,70,1,88,88,88,1, + 166,166,166,1,31,31,31,1,22,22,22,1,13,13,13,1,1,1,1,1, + 0,0,0,6,240,240,240,2,0,0,0,7,190,190,190,1,255,255,255,1, + 185,185,185,1,92,92,92,1,6,6,6,1,12,12,12,1,2,2,2,1, + 1,1,1,1,0,0,0,7,240,240,240,2,0,0,0,6,94,94,94,1, + 255,255,255,2,249,249,249,1,203,203,203,1,147,147,147,1,91,91,91,1, + 1,1,1,1,0,0,0,8,240,240,240,2,0,0,0,5,9,9,9,1, + 214,214,214,1,255,255,255,1,246,246,246,1,210,210,210,1,169,169,169,1, + 116,116,116,1,48,48,48,1,14,14,14,1,1,1,1,1,0,0,0,7, + 240,240,240,2,0,0,0,5,74,74,74,1,135,135,135,1,122,122,122,1, + 85,85,85,1,73,73,73,1,56,56,56,1,36,36,36,1,16,16,16,1, + 2,2,2,1,0,0,0,8,240,240,240,2,0,0,0,5,1,1,1,1, + 16,16,16,1,36,36,36,1,19,19,19,1,4,4,4,1,2,2,2,2, + 1,1,1,1,0,0,0,9,240,240,240,25,0,0) + ); + +const + objdata_tifigridlinkcomp: record size: integer; data: array[0..2615] of byte end = + (size: 2616; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,105,102, + 105,103,114,105,100,108,105,110,107,99,111,109,112,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,188,9, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,236,7, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,4,2,1,5,8, + 4,1,15,25,14,1,159,255,152,1,162,255,155,1,102,158,98,1,5,8, + 5,2,45,66,44,1,177,255,171,1,180,255,174,1,66,92,64,1,6,8, + 6,2,92,122,90,1,195,255,190,1,198,255,194,1,31,39,30,1,6,8, + 6,2,177,215,173,1,213,255,210,1,205,241,202,1,3,4,3,1,100,169, + 95,1,153,252,146,1,153,243,147,1,156,243,150,1,159,243,152,1,161,243, + 155,1,164,243,159,1,167,243,161,1,170,243,164,1,172,243,167,1,175,243, + 170,1,178,243,173,1,180,243,176,1,183,243,179,1,186,243,181,1,189,243, + 184,1,191,243,188,1,194,243,190,1,197,243,193,1,200,243,196,1,202,243, + 199,1,210,251,208,1,216,255,213,1,7,8,7,1,151,255,143,1,144,210, + 139,1,132,143,131,1,139,160,137,1,139,158,137,1,139,157,137,1,141,160, + 140,1,142,160,140,2,143,160,141,1,144,160,142,1,144,160,143,1,145,160, + 144,2,146,160,145,1,146,158,145,1,146,157,146,1,148,160,147,1,149,160, + 147,1,150,160,149,2,186,215,184,1,216,255,213,1,25,30,25,1,151,255, + 143,1,139,185,136,1,139,153,138,1,208,208,208,1,180,180,180,1,165,165, + 165,1,208,208,208,1,176,176,176,1,139,139,139,1,154,154,154,1,151,151, + 151,1,129,129,129,1,173,173,173,1,184,184,184,1,208,208,208,1,180,180, + 180,1,165,165,165,1,143,143,143,1,135,135,135,1,177,177,177,1,175,175, + 175,1,136,163,134,1,216,255,213,1,219,255,216,1,12,21,12,1,139,185, + 136,1,139,153,138,1,208,208,208,1,180,180,180,1,165,165,165,1,208,208, + 208,1,144,144,144,1,129,129,129,1,144,144,144,1,123,123,123,1,134,134, + 134,1,143,143,143,1,146,146,146,1,208,208,208,1,180,180,180,1,165,165, + 165,1,139,139,139,1,132,132,132,1,128,128,128,1,144,144,144,1,160,191, + 157,1,216,255,213,1,219,255,216,1,5,8,4,1,139,185,136,1,138,152, + 137,1,188,203,187,1,168,177,167,1,156,163,156,1,189,203,189,1,190,203, + 189,2,189,201,189,1,146,154,145,1,187,197,186,1,192,203,191,1,193,203, + 192,2,171,177,170,1,159,163,159,1,195,203,194,1,195,203,195,2,196,203, + 195,1,213,255,210,1,216,255,213,1,120,139,118,1,9,16,9,1,139,185, + 136,1,132,147,131,1,138,157,136,1,134,147,133,1,132,142,132,1,141,159, + 140,1,141,158,140,1,142,159,141,1,143,159,142,1,144,159,143,1,145,159, + 143,1,145,159,144,1,146,159,145,2,140,148,140,1,137,142,137,1,148,159, + 147,1,149,159,148,1,149,159,149,1,150,159,149,1,213,255,210,1,216,255, + 213,1,7,8,7,1,151,255,143,1,139,185,136,1,139,153,138,1,208,208, + 208,1,168,193,166,1,162,187,160,1,196,196,196,1,160,160,160,1,162,162, + 162,1,205,205,205,1,184,184,184,1,246,246,246,1,255,255,255,3,211,211, + 211,1,185,185,185,1,162,162,162,1,210,210,210,1,179,179,179,1,137,137, + 137,1,208,249,205,1,216,255,213,1,7,8,7,1,151,255,143,1,140,185, + 136,1,140,154,139,1,210,210,210,1,171,195,169,1,165,189,163,1,198,198, + 198,1,195,195,195,1,161,161,161,1,186,186,186,1,149,149,149,1,245,245, + 245,1,255,255,255,3,213,213,213,1,189,189,189,1,193,193,193,1,167,167, + 167,1,198,198,198,1,164,164,164,1,195,234,193,1,216,255,213,1,68,79, + 67,1,107,180,101,1,142,186,139,1,145,157,145,1,206,206,206,1,179,196, + 178,1,175,192,173,1,239,239,239,9,209,209,209,1,192,192,192,1,239,239, + 239,1,238,238,238,1,237,237,237,1,235,235,235,1,213,255,210,1,216,255, + 213,1,219,255,216,1,7,10,6,1,147,187,144,1,154,160,154,1,194,194, + 194,1,188,192,188,1,187,191,187,1,200,200,200,1,199,199,199,1,200,200, + 200,7,194,194,194,1,191,191,191,1,200,200,200,1,197,197,197,1,180,180, + 180,1,163,163,163,1,213,255,210,1,216,255,213,1,219,255,216,1,8,11, + 7,1,149,188,146,1,160,168,160,1,233,233,233,1,214,226,213,1,212,223, + 211,1,251,251,251,1,204,204,204,1,227,227,227,1,236,236,236,1,226,226, + 226,1,239,239,239,1,221,221,221,1,232,232,232,1,229,229,229,1,234,234, + 234,1,223,223,223,1,218,218,218,1,214,214,214,1,164,164,164,1,255,255, + 255,1,213,255,210,1,216,255,213,1,68,79,67,1,35,58,34,1,149,188, + 146,1,161,168,160,1,233,233,233,1,215,227,214,1,212,224,211,1,241,241, + 241,1,203,203,203,1,222,222,222,1,214,214,214,1,201,201,201,1,221,221, + 221,2,216,216,216,1,226,226,226,1,235,235,235,1,224,224,224,1,223,223, + 223,1,233,233,233,1,186,186,186,1,255,255,255,1,213,255,210,1,216,255, + 213,1,7,8,7,1,153,255,146,1,149,188,146,1,160,168,160,1,227,227, + 227,1,212,222,211,1,210,220,209,1,246,246,246,9,229,229,229,1,220,220, + 220,1,246,246,246,1,245,245,245,1,241,241,241,1,236,236,236,1,213,255, + 210,1,216,255,213,1,7,8,7,1,153,255,146,1,149,188,146,1,159,164, + 159,1,205,205,205,1,201,204,201,1,200,203,200,1,211,211,211,1,210,210, + 210,1,211,211,211,7,206,206,206,1,203,203,203,1,211,211,211,1,206,206, + 206,1,186,186,186,1,164,164,164,1,213,255,210,1,216,255,213,1,120,139, + 118,1,66,108,63,1,149,188,146,1,161,168,160,1,233,233,233,1,215,227, + 214,1,212,224,211,1,248,248,248,1,217,217,217,1,222,222,222,1,234,234, + 234,1,255,255,255,5,235,235,235,1,224,224,224,1,216,216,216,1,206,206, + 206,1,185,185,185,1,255,255,255,1,213,255,210,1,216,255,213,1,219,255, + 216,1,8,11,7,1,149,188,146,1,161,168,160,1,233,233,233,1,215,226, + 214,1,212,224,211,1,244,244,244,1,217,217,217,1,220,220,220,1,225,225, + 225,1,255,255,255,5,235,235,235,1,224,224,224,1,219,219,219,1,207,207, + 207,1,185,185,185,1,255,255,255,1,213,255,210,1,216,255,213,1,219,255, + 216,1,8,11,7,1,148,188,146,1,159,166,159,1,226,226,226,1,209,220, + 208,1,207,217,206,1,245,245,245,9,227,227,227,1,217,217,217,1,245,245, + 245,1,244,244,244,1,240,240,240,1,236,236,236,1,210,250,207,1,216,255, + 213,1,25,30,25,1,70,117,66,1,146,187,142,1,151,157,150,1,186,186, + 186,1,180,184,179,1,178,182,178,1,193,193,193,9,186,186,186,1,182,182, + 182,1,193,193,193,1,190,190,190,1,177,177,177,1,162,162,162,1,197,231, + 194,1,216,255,213,1,7,8,7,1,152,255,144,1,141,185,138,1,144,156, + 143,1,213,213,213,1,178,200,176,1,172,194,170,1,237,237,237,1,154,154, + 154,2,217,217,217,1,206,206,206,1,176,176,176,1,202,202,202,1,212,212, + 212,1,255,255,255,1,216,216,216,1,194,194,194,1,204,204,204,1,187,187, + 187,1,153,153,153,1,200,200,200,1,154,184,152,1,216,255,213,1,7,8, + 7,1,151,255,143,1,150,239,144,1,151,229,146,1,160,255,153,1,163,255, + 156,1,166,255,159,1,156,235,150,1,114,170,110,1,134,195,129,1,117,168, + 113,1,122,173,118,1,101,140,98,1,140,191,136,1,143,192,139,1,192,255, + 188,1,195,255,191,1,198,255,194,1,112,142,110,1,165,205,162,1,131,161, + 128,1,172,209,169,1,154,184,152,1,216,255,213,1,207,241,205,1,29,50, + 28,1,153,255,146,1,156,255,149,1,159,255,152,1,162,255,155,1,165,255, + 158,1,168,255,162,1,171,255,165,1,174,255,168,1,177,255,171,1,145,205, + 140,1,163,227,158,1,186,255,181,1,154,208,150,1,192,255,187,1,195,255, + 190,1,198,255,194,1,201,255,197,1,204,255,200,1,207,255,203,1,210,255, + 206,1,213,255,210,1,216,255,213,1,219,255,216,1,5,8,4,1,153,255, + 146,1,156,255,149,1,159,255,152,1,162,255,155,1,165,255,158,1,168,255, + 162,1,171,255,165,1,174,255,168,1,177,255,171,1,180,255,174,1,183,255, + 178,1,186,255,181,1,189,255,184,1,192,255,187,1,195,255,190,1,198,255, + 194,1,201,255,197,1,204,255,200,1,207,255,203,1,210,255,206,1,213,255, + 210,1,216,255,213,1,184,215,182,1,2,4,2,1,114,191,109,1,156,255, + 149,1,159,255,152,1,8,12,7,1,5,8,5,1,16,25,16,1,171,255, + 165,1,174,255,168,1,110,158,106,1,5,8,5,1,6,8,5,1,48,66, + 47,1,189,255,184,1,192,255,187,1,70,92,69,1,6,8,6,2,98,122, + 96,1,207,255,203,1,210,255,206,1,33,39,32,1,7,8,6,1,3,4, + 3,1,152,1,0,0,244,244,244,1,248,248,248,1,233,233,233,1,128,128, + 128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2,188,188, + 188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221,1,248,248, + 248,2,139,139,139,1,128,128,128,1,131,131,131,1,244,244,244,1,154,154, + 154,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,229,229, + 229,1,128,128,128,1,255,255,255,22,128,128,128,1,236,236,236,1,255,255, + 255,22,128,128,128,1,248,248,248,1,255,255,255,22,165,165,165,1,240,240, + 240,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248, + 248,1,128,128,128,1,255,255,255,22,195,195,195,1,150,150,150,1,255,255, + 255,22,128,128,128,1,248,248,248,1,255,255,255,22,128,128,128,1,248,248, + 248,1,255,255,255,22,195,195,195,1,211,211,211,1,255,255,255,22,248,248, + 248,1,129,129,129,1,255,255,255,22,248,248,248,1,129,129,129,1,255,255, + 255,22,165,165,165,1,181,181,181,1,255,255,255,22,128,128,128,1,248,248, + 248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,229,229, + 229,1,177,177,177,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255, + 255,22,248,248,248,1,128,128,128,1,255,255,255,22,131,131,131,1,214,214, + 214,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,139,139, + 139,1,244,244,244,1,146,146,146,1,128,128,128,2,244,244,244,1,248,248, + 248,1,233,233,233,1,128,128,128,2,158,158,158,1,248,248,248,2,203,203, + 203,1,128,128,128,2,188,188,188,1,248,248,248,2,173,173,173,1,128,128, + 128,2,221,221,221,1,248,248,248,1,244,244,244,1,0,0) + ); + +const + objdata_tconnectedifidatasource: record size: integer; data: array[0..2590] of byte end = + (size: 2591; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,23,116,99,111, + 110,110,101,99,116,101,100,105,102,105,100,97,116,97,115,111,117,114,99,101, + 23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99, + 111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116, + 105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111, + 95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105, + 109,97,103,101,10,156,9,0,0,0,0,0,0,6,0,0,0,24,0,0, + 0,24,0,0,0,204,7,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,2,4,2,1,5,8,4,1,15,25,14,1,159,255,152,1,162,255,155, + 1,102,158,98,1,5,8,5,2,45,66,44,1,177,255,171,1,180,255,174, + 1,66,92,64,1,6,8,6,2,92,122,90,1,195,255,190,1,198,255,194, + 1,31,39,30,1,6,8,6,2,177,215,173,1,213,255,210,1,205,241,202, + 1,3,4,3,1,100,169,95,1,129,135,129,3,130,135,129,2,130,135,130, + 4,131,135,130,2,131,135,131,4,132,135,131,1,132,135,132,4,133,135,132, + 1,133,135,133,1,7,8,7,1,151,255,143,1,128,128,128,1,156,255,149, + 1,159,255,152,1,162,255,155,1,165,255,158,1,168,255,162,1,171,255,165, + 1,128,128,128,1,177,255,171,1,180,255,174,1,183,255,178,1,186,255,181, + 1,189,255,184,1,192,255,187,1,195,255,190,1,198,255,194,1,128,128,128, + 1,204,255,200,1,207,255,203,1,210,255,206,1,213,255,210,1,216,255,213, + 1,25,30,25,1,151,255,143,1,128,128,128,1,156,255,149,1,159,255,152, + 1,162,255,155,1,165,255,158,1,168,255,162,1,171,255,165,1,128,128,128, + 1,177,255,171,1,180,255,174,1,183,255,178,1,186,255,181,1,189,255,184, + 1,192,255,187,1,195,255,190,1,198,255,194,1,128,128,128,1,204,255,200, + 1,207,255,203,1,210,255,206,1,213,255,210,1,216,255,213,1,219,255,216, + 1,12,21,12,1,128,128,128,1,129,135,129,2,130,135,129,2,130,135,130, + 2,128,128,128,1,130,135,130,1,131,135,130,2,131,135,131,4,132,135,131, + 1,128,128,128,1,132,135,132,3,133,135,132,1,133,135,133,1,219,255,216, + 1,5,8,4,1,128,128,128,1,156,255,149,1,159,255,152,1,162,255,155, + 1,165,255,158,1,168,255,162,1,171,255,165,1,128,128,128,1,177,255,171, + 1,180,255,174,1,183,255,178,1,186,255,181,1,189,255,184,1,192,255,187, + 1,195,255,190,1,198,255,194,1,128,128,128,1,204,255,200,1,207,255,203, + 1,210,255,206,1,213,255,210,1,216,255,213,1,120,139,118,1,9,16,9, + 1,128,128,128,1,156,255,149,1,159,255,152,1,162,255,155,1,165,255,158, + 1,168,255,162,1,171,255,165,1,128,128,128,1,177,255,171,1,180,255,174, + 1,183,255,178,1,186,255,181,1,189,255,184,1,192,255,187,1,195,255,190, + 1,198,255,194,1,128,128,128,1,204,255,200,1,207,255,203,1,210,255,206, + 1,213,255,210,1,216,255,213,1,7,8,7,1,151,255,143,1,128,128,128, + 1,129,135,129,2,130,135,129,2,130,135,130,2,128,128,128,1,130,135,130, + 1,131,135,130,2,131,135,131,4,132,135,131,1,128,128,128,1,132,135,132, + 3,133,135,132,1,133,135,133,1,7,8,7,1,151,255,143,1,128,128,128, + 1,156,255,149,1,159,255,152,1,162,255,155,1,165,255,158,1,168,255,162, + 1,171,255,165,1,128,128,128,1,177,255,171,1,180,255,174,1,183,255,178, + 1,186,255,181,1,189,255,184,1,192,255,187,1,195,255,190,1,198,255,194, + 1,128,128,128,1,204,255,200,1,207,255,203,1,210,255,206,1,213,255,210, + 1,216,255,213,1,68,79,67,1,106,179,100,1,128,128,128,1,156,255,149, + 1,159,255,152,1,162,255,155,1,165,255,158,1,168,255,162,1,171,255,165, + 1,128,128,128,1,177,255,171,1,180,255,174,1,183,255,178,1,186,255,181, + 1,189,255,184,1,192,255,187,1,195,255,190,1,198,255,194,1,128,128,128, + 1,204,255,200,1,207,255,203,1,210,255,206,1,213,255,210,1,216,255,213, + 1,219,255,216,1,5,8,4,1,128,128,128,1,129,135,129,2,130,135,129, + 2,130,135,130,2,128,128,128,1,130,135,130,1,131,135,130,2,131,135,131, + 4,132,135,131,1,128,128,128,1,132,135,132,3,133,135,132,1,133,135,133, + 1,219,255,216,1,5,8,4,1,128,128,128,1,156,255,149,1,159,255,152, + 1,162,255,155,1,165,255,158,1,168,255,162,1,171,255,165,1,128,128,128, + 1,177,255,171,1,180,255,174,1,183,255,178,1,186,255,181,1,189,255,184, + 1,192,255,187,1,195,255,190,1,198,255,194,1,128,128,128,1,204,255,200, + 1,207,255,203,1,210,255,206,1,213,255,210,1,216,255,213,1,68,79,67, + 1,32,55,31,1,128,128,128,1,156,255,149,1,159,255,152,1,162,255,155, + 1,165,255,158,1,168,255,162,1,171,255,165,1,128,128,128,1,177,255,171, + 1,180,255,174,1,183,255,178,1,186,255,181,1,189,255,184,1,192,255,187, + 1,195,255,190,1,198,255,194,1,128,128,128,1,204,255,200,1,207,255,203, + 1,210,255,206,1,213,255,210,1,216,255,213,1,7,8,7,1,151,255,143, + 1,129,135,129,3,130,135,129,2,130,135,130,4,131,135,130,2,131,135,131, + 4,132,135,131,1,132,135,132,4,133,135,132,1,133,135,133,1,7,8,7, + 1,151,255,143,1,153,255,146,1,156,255,149,1,159,255,152,1,132,207,174, + 1,0,0,255,1,136,207,180,1,171,255,165,1,174,255,168,1,177,255,171, + 1,180,255,174,1,183,255,178,1,0,0,255,1,189,255,184,1,192,255,187, + 1,195,255,190,1,198,255,194,1,201,255,197,1,185,231,205,1,0,0,255, + 1,190,231,211,1,213,255,210,1,216,255,213,1,120,139,118,1,63,106,60, + 1,153,255,146,1,156,255,149,1,99,159,191,1,0,0,255,3,107,159,199, + 1,174,255,168,1,177,255,171,1,180,255,174,1,0,0,255,3,192,255,187, + 1,195,255,190,1,198,255,194,1,163,207,208,1,0,0,255,3,173,207,218, + 1,216,255,213,1,219,255,216,1,5,8,4,1,153,255,146,1,156,255,149, + 1,84,135,200,1,86,135,202,1,41,63,231,1,89,135,206,1,91,135,207, + 1,174,255,168,1,177,255,171,1,0,0,255,5,195,255,190,1,198,255,194, + 1,62,79,237,1,63,79,238,1,44,54,244,1,65,79,240,1,66,79,241, + 1,216,255,213,1,219,255,216,1,5,8,4,1,153,255,146,1,156,255,149, + 1,159,255,152,1,162,255,155,1,0,0,255,1,168,255,162,1,171,255,165, + 1,174,255,168,1,177,255,171,1,180,255,174,1,183,255,178,1,0,0,255, + 1,189,255,184,1,192,255,187,1,195,255,190,1,198,255,194,1,201,255,197, + 1,204,255,200,1,0,0,255,1,210,255,206,1,213,255,210,1,216,255,213, + 1,25,30,25,1,68,115,64,1,153,255,146,1,156,255,149,1,159,255,152, + 1,162,255,155,1,0,0,255,1,168,255,162,1,171,255,165,1,174,255,168, + 1,177,255,171,1,180,255,174,1,183,255,178,1,0,0,255,1,189,255,184, + 1,192,255,187,1,195,255,190,1,198,255,194,1,201,255,197,1,204,255,200, + 1,0,0,255,1,210,255,206,1,213,255,210,1,216,255,213,1,7,8,7, + 1,151,255,143,1,153,255,146,1,156,255,149,1,159,255,152,1,162,255,155, + 1,0,0,255,1,168,255,162,1,171,255,165,1,174,255,168,1,177,255,171, + 1,0,0,255,5,195,255,190,1,198,255,194,1,201,255,197,1,204,255,200, + 1,0,0,255,1,210,255,206,1,213,255,210,1,216,255,213,1,7,8,7, + 1,151,255,143,1,153,255,146,1,156,255,149,1,84,135,200,1,86,135,202, + 1,0,0,255,1,89,135,206,1,91,135,207,1,174,255,168,1,177,255,171, + 1,180,255,174,1,0,0,255,3,192,255,187,1,195,255,190,1,198,255,194, + 1,62,79,237,1,63,79,238,1,0,0,255,1,65,79,240,1,66,79,241, + 1,216,255,213,1,207,241,205,1,29,50,28,1,153,255,146,1,156,255,149, + 1,99,159,191,1,0,0,255,3,107,159,199,1,174,255,168,1,177,255,171, + 1,180,255,174,1,183,255,178,1,0,0,255,1,189,255,184,1,192,255,187, + 1,195,255,190,1,198,255,194,1,163,207,208,1,0,0,255,3,173,207,218, + 1,216,255,213,1,219,255,216,1,5,8,4,1,153,255,146,1,156,255,149, + 1,159,255,152,1,132,207,174,1,0,0,255,1,136,207,180,1,171,255,165, + 1,174,255,168,1,177,255,171,1,180,255,174,1,183,255,178,1,186,255,181, + 1,189,255,184,1,192,255,187,1,195,255,190,1,198,255,194,1,201,255,197, + 1,185,231,205,1,0,0,255,1,190,231,211,1,213,255,210,1,216,255,213, + 1,184,215,182,1,2,4,2,1,114,191,109,1,156,255,149,1,159,255,152, + 1,8,12,7,1,5,8,5,1,16,25,16,1,171,255,165,1,174,255,168, + 1,110,158,106,1,5,8,5,1,6,8,5,1,48,66,47,1,189,255,184, + 1,192,255,187,1,70,92,69,1,6,8,6,2,98,122,96,1,207,255,203, + 1,210,255,206,1,33,39,32,1,7,8,6,1,3,4,3,1,152,1,0, + 0,244,244,244,1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158, + 1,248,248,248,2,203,203,203,1,128,128,128,2,188,188,188,1,248,248,248, + 2,173,173,173,1,128,128,128,2,221,221,221,1,248,248,248,2,139,139,139, + 1,128,128,128,1,131,131,131,1,244,244,244,1,154,154,154,1,255,255,255, + 22,248,248,248,1,128,128,128,1,255,255,255,22,229,229,229,1,128,128,128, + 1,255,255,255,22,128,128,128,1,236,236,236,1,255,255,255,22,128,128,128, + 1,248,248,248,1,255,255,255,22,165,165,165,1,240,240,240,1,255,255,255, + 22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128, + 1,255,255,255,22,195,195,195,1,150,150,150,1,255,255,255,22,128,128,128, + 1,248,248,248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255, + 22,195,195,195,1,210,210,210,1,255,255,255,22,248,248,248,1,128,128,128, + 1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,165,165,165, + 1,180,180,180,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255, + 22,128,128,128,1,248,248,248,1,255,255,255,22,229,229,229,1,176,176,176, + 1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248, + 1,128,128,128,1,255,255,255,22,131,131,131,1,214,214,214,1,255,255,255, + 22,128,128,128,1,248,248,248,1,255,255,255,22,139,139,139,1,244,244,244, + 1,146,146,146,1,128,128,128,2,244,244,244,1,248,248,248,1,233,233,233, + 1,128,128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128, + 2,188,188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221, + 1,248,248,248,1,244,244,244,1,0,0) + ); + +const + objdata_tifisqlresult: record size: integer; data: array[0..2472] of byte end = + (size: 2473; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,105,102, + 105,115,113,108,114,101,115,117,108,116,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,48,9,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,236,8,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,152,255,144,1,155,255,148,1,158, + 255,151,1,161,255,154,1,164,255,157,1,167,255,160,1,169,255,163,1,172, + 255,166,1,175,255,169,1,178,255,172,1,181,255,175,1,184,255,178,1,186, + 255,181,1,189,255,184,1,192,255,187,1,195,255,190,1,198,255,193,1,201, + 255,196,1,203,255,199,1,206,255,202,1,209,255,205,1,212,255,208,1,215, + 255,211,1,218,255,215,1,152,255,144,1,155,255,148,1,158,255,151,1,161, + 255,154,1,164,255,157,1,167,255,160,1,169,255,163,1,172,255,166,1,175, + 255,169,1,178,255,172,1,181,255,175,1,184,255,178,1,186,255,181,1,189, + 255,184,1,192,255,187,1,195,255,190,1,198,255,193,1,201,255,196,1,203, + 255,199,1,206,255,202,1,209,255,205,1,212,255,208,1,215,255,211,1,218, + 255,215,1,152,255,144,1,155,255,148,1,158,255,151,1,161,255,154,1,164, + 255,157,1,167,255,160,1,169,255,163,1,172,255,166,1,175,255,169,1,178, + 255,172,1,181,255,175,1,184,255,178,1,186,255,181,1,189,255,184,1,192, + 255,187,1,195,255,190,1,198,255,193,1,201,255,196,1,203,255,199,1,206, + 255,202,1,209,255,205,1,212,255,208,1,215,255,211,1,218,255,215,1,152, + 255,144,1,155,255,148,1,111,179,106,1,23,36,22,1,3,5,3,1,30, + 46,29,1,128,193,123,1,172,255,166,1,175,255,169,1,175,250,169,1,82, + 115,79,1,13,18,13,2,84,114,82,1,188,250,183,1,195,255,190,1,198, + 255,193,1,0,0,0,1,203,255,199,1,206,255,202,1,209,255,205,1,212, + 255,208,1,215,255,211,1,218,255,215,1,152,255,144,1,155,255,148,1,13, + 21,12,1,118,187,113,1,160,249,153,1,115,176,110,1,20,30,19,1,172, + 255,166,1,175,255,169,1,90,129,87,1,90,127,87,1,176,244,170,1,172, + 236,168,1,99,134,97,1,93,124,91,1,195,255,190,1,198,255,193,1,0, + 0,0,1,203,255,199,1,206,255,202,1,209,255,205,1,212,255,208,1,215, + 255,211,1,218,255,215,1,152,255,144,1,155,255,148,1,29,46,27,1,96, + 152,92,1,154,240,148,1,167,255,160,1,169,255,163,1,172,255,166,1,175, + 255,169,1,23,33,22,1,168,236,162,1,184,255,178,1,186,255,181,1,189, + 255,184,1,22,29,21,1,195,255,190,1,198,255,193,1,0,0,0,1,203, + 255,199,1,206,255,202,1,209,255,205,1,212,255,208,1,215,255,211,1,218, + 255,215,1,152,255,144,1,155,255,148,1,145,234,139,1,78,124,75,1,35, + 54,33,1,38,58,36,1,130,196,125,1,172,255,166,1,175,255,169,1,3, + 5,3,1,180,253,174,1,184,255,178,1,186,255,181,1,188,253,183,1,5, + 6,4,1,195,255,190,1,198,255,193,1,0,0,0,1,203,255,199,1,206, + 255,202,1,209,255,205,1,212,255,208,1,215,255,211,1,218,255,215,1,152, + 255,144,1,155,255,148,1,158,255,151,1,161,255,154,1,164,255,157,1,140, + 214,134,1,17,26,17,1,172,255,166,1,175,255,169,1,22,31,21,1,167, + 235,161,1,184,255,178,1,146,200,142,1,160,216,156,1,34,45,33,1,195, + 255,190,1,198,255,193,1,0,0,0,1,203,255,199,1,206,255,202,1,209, + 255,205,1,212,255,208,1,215,255,211,1,218,255,215,1,152,255,144,1,155, + 255,148,1,18,29,17,1,110,174,105,1,161,250,154,1,133,203,127,1,18, + 27,17,1,172,255,166,1,175,255,169,1,88,126,85,1,89,125,86,1,176, + 244,170,1,53,73,52,1,34,46,33,1,133,177,130,1,195,255,190,1,198, + 255,193,1,0,0,0,1,203,255,199,1,206,255,202,1,209,255,205,1,212, + 255,208,1,215,255,211,1,218,255,215,1,152,255,144,1,155,255,148,1,118, + 191,113,1,28,45,27,1,3,5,3,1,24,37,23,1,125,188,120,1,172, + 255,166,1,175,255,169,1,175,250,169,1,78,110,75,1,11,15,10,1,15, + 20,14,1,43,58,42,1,47,63,46,1,195,255,190,1,198,255,193,1,0, + 0,0,5,215,255,211,1,218,255,215,1,152,255,144,1,155,255,148,1,158, + 255,151,1,161,255,154,1,164,255,157,1,167,255,160,1,169,255,163,1,172, + 255,166,1,175,255,169,1,178,255,172,1,181,255,175,1,184,255,178,1,186, + 255,181,1,189,255,184,1,151,200,147,1,195,255,190,1,198,255,193,1,201, + 255,196,1,203,255,199,1,206,255,202,1,209,255,205,1,212,255,208,1,215, + 255,211,1,218,255,215,1,152,255,144,1,155,255,148,1,158,255,151,1,161, + 255,154,1,164,255,157,1,167,255,160,1,169,255,163,1,172,255,166,1,175, + 255,169,1,178,255,172,1,181,255,175,1,184,255,178,1,186,255,181,1,189, + 255,184,1,192,255,187,1,195,255,190,1,198,255,193,1,201,255,196,1,203, + 255,199,1,206,255,202,1,209,255,205,1,212,255,208,1,215,255,211,1,218, + 255,215,1,152,255,144,1,155,255,148,1,158,255,151,1,161,255,154,1,164, + 255,157,1,167,255,160,1,169,255,163,1,172,255,166,1,175,255,169,1,178, + 255,172,1,181,255,175,1,184,255,178,1,186,255,181,1,189,255,184,1,192, + 255,187,1,195,255,190,1,198,255,193,1,201,255,196,1,203,255,199,1,206, + 255,202,1,209,255,205,1,212,255,208,1,215,255,211,1,218,255,215,1,152, + 255,144,1,155,255,148,1,158,255,151,1,134,213,129,1,42,66,41,1,7, + 10,6,1,5,8,5,1,39,58,38,1,135,196,130,1,149,213,144,1,47, + 66,45,1,7,10,7,1,6,8,6,1,43,58,42,1,148,196,144,1,163, + 213,159,1,51,66,50,1,8,10,8,1,6,8,6,1,47,58,46,1,161, + 196,158,1,212,255,208,1,215,255,211,1,218,255,215,1,152,255,144,1,155, + 255,148,1,158,255,151,1,27,42,25,1,91,142,87,1,158,241,151,1,160, + 242,155,1,105,156,102,1,14,20,13,1,29,42,28,1,101,142,97,1,174, + 241,168,1,177,242,172,1,116,156,113,1,15,20,15,1,32,42,31,1,110, + 142,107,1,190,241,185,1,193,242,189,1,126,156,124,1,16,20,16,1,212, + 255,208,1,215,255,211,1,218,255,215,1,152,255,144,1,155,255,148,1,158, + 255,151,1,161,255,154,1,164,255,157,1,167,255,160,1,169,255,163,1,111, + 164,107,1,42,61,40,1,178,255,172,1,181,255,175,1,184,255,178,1,186, + 255,181,1,122,164,118,1,46,61,45,1,195,255,190,1,198,255,193,1,201, + 255,196,1,203,255,199,1,132,164,130,1,50,61,49,1,212,255,208,1,215, + 255,211,1,218,255,215,1,152,255,144,1,155,255,148,1,158,255,151,1,161, + 255,154,1,164,255,157,1,167,255,160,1,90,136,87,1,46,68,44,1,163, + 238,158,1,178,255,172,1,181,255,175,1,184,255,178,1,99,136,97,1,50, + 68,49,1,179,238,175,1,195,255,190,1,198,255,193,1,201,255,196,1,108, + 136,106,1,55,68,54,1,195,238,191,1,212,255,208,1,215,255,211,1,218, + 255,215,1,152,255,144,1,155,255,148,1,158,255,151,1,161,255,154,1,164, + 255,157,1,167,255,160,1,5,8,5,1,162,240,156,1,175,255,169,1,178, + 255,172,1,181,255,175,1,184,255,178,1,6,8,6,1,178,240,173,1,192, + 255,187,1,195,255,190,1,198,255,193,1,201,255,196,1,6,8,6,1,194, + 240,190,1,209,255,205,1,212,255,208,1,215,255,211,1,218,255,215,1,152, + 255,144,1,155,255,148,1,158,255,151,1,161,255,154,1,164,255,157,1,167, + 255,160,1,169,255,163,1,172,255,166,1,175,255,169,1,178,255,172,1,181, + 255,175,1,184,255,178,1,186,255,181,1,189,255,184,1,192,255,187,1,195, + 255,190,1,198,255,193,1,201,255,196,1,203,255,199,1,206,255,202,1,209, + 255,205,1,212,255,208,1,215,255,211,1,218,255,215,1,152,255,144,1,155, + 255,148,1,158,255,151,1,161,255,154,1,164,255,157,1,167,255,160,1,0, + 0,0,1,172,255,166,1,175,255,169,1,178,255,172,1,181,255,175,1,184, + 255,178,1,0,0,0,1,189,255,184,1,192,255,187,1,195,255,190,1,198, + 255,193,1,201,255,196,1,0,0,0,1,206,255,202,1,209,255,205,1,212, + 255,208,1,215,255,211,1,218,255,215,1,152,255,144,1,155,255,148,1,158, + 255,151,1,161,255,154,1,164,255,157,1,167,255,160,1,169,255,163,1,172, + 255,166,1,175,255,169,1,178,255,172,1,181,255,175,1,184,255,178,1,186, + 255,181,1,189,255,184,1,192,255,187,1,195,255,190,1,198,255,193,1,201, + 255,196,1,203,255,199,1,206,255,202,1,209,255,205,1,212,255,208,1,215, + 255,211,1,218,255,215,1,152,255,144,1,155,255,148,1,158,255,151,1,161, + 255,154,1,164,255,157,1,167,255,160,1,169,255,163,1,172,255,166,1,175, + 255,169,1,178,255,172,1,181,255,175,1,184,255,178,1,186,255,181,1,189, + 255,184,1,192,255,187,1,195,255,190,1,198,255,193,1,201,255,196,1,203, + 255,199,1,206,255,202,1,209,255,205,1,212,255,208,1,215,255,211,1,218, + 255,215,1,152,255,144,1,155,255,148,1,158,255,151,1,161,255,154,1,164, + 255,157,1,167,255,160,1,169,255,163,1,172,255,166,1,175,255,169,1,178, + 255,172,1,181,255,175,1,184,255,178,1,186,255,181,1,189,255,184,1,192, + 255,187,1,195,255,190,1,198,255,193,1,201,255,196,1,203,255,199,1,206, + 255,202,1,209,255,205,1,212,255,208,1,215,255,211,1,218,255,215,1,152, + 255,144,1,155,255,148,1,158,255,151,1,161,255,154,1,164,255,157,1,167, + 255,160,1,169,255,163,1,172,255,166,1,175,255,169,1,178,255,172,1,181, + 255,175,1,184,255,178,1,186,255,181,1,189,255,184,1,192,255,187,1,195, + 255,190,1,198,255,193,1,201,255,196,1,203,255,199,1,206,255,202,1,209, + 255,205,1,212,255,208,1,215,255,211,1,218,255,215,1,12,0,0,0,255, + 255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tififormlinkcomp: record size: integer; data: array[0..1475] of byte end = + (size: 1476; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,105,102, + 105,102,111,114,109,108,105,110,107,99,111,109,112,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,72,5, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,212,1, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,151,255,143,25,208,208, + 208,6,0,0,0,2,208,208,208,6,0,0,0,2,208,208,208,6,151,255, + 143,2,208,208,208,5,0,0,0,3,208,208,208,6,0,0,0,3,208,208, + 208,5,151,255,143,2,208,208,208,4,0,0,0,14,208,208,208,4,151,255, + 143,2,208,208,208,5,0,0,0,3,208,208,208,6,0,0,0,3,208,208, + 208,5,151,255,143,2,208,208,208,6,0,0,0,2,208,208,208,6,0,0, + 0,2,208,208,208,6,151,255,143,2,208,208,208,22,151,255,143,2,0,0, + 0,6,208,208,208,16,151,255,143,2,0,0,0,6,208,208,208,16,151,255, + 143,2,0,0,0,2,208,208,208,5,0,0,0,3,208,208,208,1,0,0, + 0,7,208,208,208,1,0,0,0,2,208,208,208,1,151,255,143,2,0,0, + 0,5,208,208,208,1,0,0,0,16,151,255,143,2,0,0,0,5,208,208, + 208,1,0,0,0,2,208,208,208,1,0,0,0,4,208,208,208,1,0,0, + 0,5,208,208,208,1,0,0,0,2,151,255,143,2,0,0,0,2,208,208, + 208,3,0,0,0,2,208,208,208,2,0,0,0,4,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,151,255, + 143,2,0,0,0,2,208,208,208,4,0,0,0,2,208,208,208,1,0,0, + 0,4,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,2,151,255,143,2,0,0,0,2,208,208,208,4,0,0, + 0,7,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,2,151,255,143,2,208,208,208,8,0,0,0,1,208,208, + 208,5,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0, + 0,2,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255, + 143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143,2,208,208, + 208,22,151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255, + 143,25,60,3,0,0,240,240,240,25,0,0,0,6,59,59,59,1,130,130, + 130,1,0,0,0,6,125,125,125,1,64,64,64,1,0,0,0,6,240,240, + 240,2,0,0,0,5,67,67,67,1,235,235,235,1,70,70,70,1,0,0, + 0,6,62,62,62,1,233,233,233,1,73,73,73,1,0,0,0,5,240,240, + 240,2,0,0,0,4,15,15,15,1,237,237,237,1,255,255,255,10,241,241, + 241,1,19,19,19,1,0,0,0,4,240,240,240,2,0,0,0,5,61,61, + 61,1,233,233,233,1,74,74,74,1,0,0,0,6,66,66,66,1,232,232, + 232,1,67,67,67,1,0,0,0,5,240,240,240,2,0,0,0,6,53,53, + 53,1,124,124,124,1,0,0,0,6,119,119,119,1,59,59,59,1,0,0, + 0,6,240,240,240,2,0,0,0,22,240,240,240,2,37,37,37,1,72,72, + 72,4,11,11,11,1,0,0,0,16,240,240,240,2,134,134,134,1,194,194, + 194,1,152,152,152,3,24,24,24,1,0,0,0,16,240,240,240,2,134,134, + 134,1,105,105,105,1,0,0,0,5,26,26,26,1,66,66,66,1,2,2, + 2,1,0,0,0,1,27,27,27,1,37,37,37,1,76,76,76,1,13,13, + 13,1,5,5,5,1,4,4,4,1,12,12,12,1,0,0,0,1,1,1, + 1,1,7,7,7,1,0,0,0,1,240,240,240,2,134,134,134,1,129,129, + 129,1,40,40,40,2,26,26,26,1,0,0,0,1,121,121,121,1,186,186, + 186,1,124,124,124,1,203,203,203,1,17,17,17,1,98,98,98,1,218,218, + 218,1,157,157,157,1,66,66,66,1,205,205,205,1,184,184,184,1,219,219, + 219,1,125,125,125,1,146,146,146,1,203,203,203,1,66,66,66,1,240,240, + 240,2,134,134,134,1,209,209,209,1,176,176,176,2,116,116,116,1,0,0, + 0,1,238,238,238,1,15,15,15,1,0,0,0,1,123,123,123,1,96,96, + 96,1,98,98,98,1,148,148,148,1,0,0,0,1,39,39,39,1,223,223, + 223,1,4,4,4,1,60,60,60,1,226,226,226,1,0,0,0,1,62,62, + 62,1,153,153,153,1,240,240,240,2,134,134,134,1,105,105,105,1,0,0, + 0,3,7,7,7,1,217,217,217,1,0,0,0,2,80,80,80,1,147,147, + 147,1,98,98,98,1,118,118,118,1,0,0,0,1,39,39,39,1,188,188, + 188,1,0,0,0,1,39,39,39,1,177,177,177,1,0,0,0,1,47,47, + 47,1,168,168,168,1,240,240,240,2,134,134,134,1,105,105,105,1,0,0, + 0,4,183,183,183,1,35,35,35,1,0,0,0,1,148,148,148,1,102,102, + 102,1,98,98,98,1,117,117,117,1,0,0,0,1,39,39,39,1,184,184, + 184,1,0,0,0,1,39,39,39,1,176,176,176,1,0,0,0,1,47,47, + 47,1,168,168,168,1,240,240,240,2,134,134,134,1,105,105,105,1,0,0, + 0,4,60,60,60,1,187,187,187,1,193,193,193,1,172,172,172,1,7,7, + 7,1,98,98,98,1,117,117,117,1,0,0,0,1,39,39,39,1,184,184, + 184,1,0,0,0,1,39,39,39,1,176,176,176,1,0,0,0,1,47,47, + 47,1,168,168,168,1,240,240,240,2,0,0,0,8,11,11,11,1,0,0, + 0,5,9,9,9,1,46,46,46,1,0,0,0,1,9,9,9,1,44,44, + 44,1,0,0,0,1,11,11,11,1,42,42,42,1,240,240,240,2,0,0, + 0,22,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240, + 240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240,240,2,0,0, + 0,22,240,240,240,2,0,0,0,22,240,240,240,25,0,0) + ); + +const + objdata_tifidialoglinkcomp: record size: integer; data: array[0..1589] of byte end = + (size: 1590; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,18,116,105,102, + 105,100,105,97,108,111,103,108,105,110,107,99,111,109,112,23,98,105,116,109, + 97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4, + 6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11, + 10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111, + 114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10, + 184,5,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0, + 204,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,151,255,143,25, + 208,208,208,7,0,0,0,2,208,208,208,6,0,0,0,2,208,208,208,5, + 151,255,143,2,208,208,208,6,0,0,0,12,208,208,208,4,151,255,143,2, + 208,208,208,5,0,0,0,14,208,208,208,3,151,255,143,2,208,208,208,6, + 0,0,0,3,208,208,208,6,0,0,0,3,208,208,208,4,151,255,143,2, + 208,208,208,7,0,0,0,2,208,208,208,6,0,0,0,2,208,208,208,5, + 151,255,143,2,208,208,208,22,151,255,143,2,0,0,0,4,208,208,208,2, + 0,0,0,1,208,208,208,5,0,0,0,1,208,208,208,9,151,255,143,2, + 0,0,0,7,208,208,208,5,0,0,0,1,208,208,208,9,151,255,143,2, + 0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,1, + 208,208,208,1,0,0,0,3,208,208,208,1,0,0,0,1,208,208,208,2, + 0,0,0,1,208,208,208,3,0,0,0,1,208,208,208,1,0,0,0,1, + 151,255,143,2,0,0,0,2,208,208,208,2,0,0,0,9,208,208,208,1, + 0,0,0,8,151,255,143,2,0,0,0,2,208,208,208,2,0,0,0,11, + 208,208,208,1,0,0,0,6,151,255,143,2,0,0,0,2,208,208,208,2, + 0,0,0,11,208,208,208,1,0,0,0,3,208,208,208,2,0,0,0,1, + 151,255,143,2,0,0,0,2,208,208,208,1,0,0,0,6,208,208,208,1, + 0,0,0,5,208,208,208,1,0,0,0,6,151,255,143,2,0,0,0,13, + 208,208,208,1,0,0,0,8,151,255,143,2,208,208,208,8,0,0,0,2, + 208,208,208,2,0,0,0,1,208,208,208,2,0,0,0,2,208,208,208,1, + 0,0,0,4,151,255,143,2,208,208,208,18,0,0,0,4,151,255,143,2, + 208,208,208,18,0,0,0,3,208,208,208,1,151,255,143,2,208,208,208,22, + 151,255,143,2,208,208,208,22,151,255,143,2,208,208,208,22,151,255,143,2, + 208,208,208,22,151,255,143,2,208,208,208,22,151,255,143,25,180,3,0,0, + 240,240,240,25,0,0,0,7,59,59,59,1,130,130,130,1,0,0,0,6, + 125,125,125,1,64,64,64,1,0,0,0,5,240,240,240,2,0,0,0,6, + 67,67,67,1,235,235,235,1,74,74,74,1,8,8,8,6,66,66,66,1, + 233,233,233,1,73,73,73,1,0,0,0,4,240,240,240,2,0,0,0,5, + 15,15,15,1,237,237,237,1,251,251,251,1,248,248,248,8,251,251,251,1, + 241,241,241,1,19,19,19,1,0,0,0,3,240,240,240,2,0,0,0,6, + 61,61,61,1,235,235,235,1,80,80,80,1,0,0,0,6,72,72,72,1, + 235,235,235,1,67,67,67,1,0,0,0,4,240,240,240,2,0,0,0,7, + 53,53,53,1,122,122,122,1,0,0,0,6,117,117,117,1,59,59,59,1, + 0,0,0,5,240,240,240,2,0,0,0,22,240,240,240,2,47,47,47,1, + 72,72,72,1,63,63,63,1,19,19,19,1,0,0,0,2,49,49,49,1, + 0,0,0,5,5,5,5,1,0,0,0,9,240,240,240,2,168,168,168,1, + 161,161,161,1,160,160,160,1,214,214,214,1,56,56,56,1,1,1,1,1, + 130,130,130,1,0,0,0,5,184,184,184,1,0,0,0,9,240,240,240,2, + 168,168,168,1,23,23,23,1,0,0,0,1,40,40,40,1,185,185,185,1, + 0,0,0,1,49,49,49,1,0,0,0,1,30,30,30,1,83,83,83,1, + 30,30,30,1,0,0,0,1,184,184,184,1,0,0,0,2,8,8,8,1, + 0,0,0,3,8,8,8,1,0,0,0,1,5,5,5,1,240,240,240,2, + 168,168,168,1,23,23,23,1,0,0,0,2,206,206,206,1,1,1,1,1, + 174,174,174,1,27,27,27,1,190,190,190,1,112,112,112,1,213,213,213,1, + 6,6,6,1,184,184,184,1,0,0,0,1,131,131,131,1,183,183,183,1, + 169,169,169,1,9,9,9,1,60,60,60,1,203,203,203,1,161,161,161,1, + 171,171,171,1,240,240,240,2,168,168,168,1,23,23,23,1,0,0,0,2, + 197,197,197,1,2,2,2,1,174,174,174,1,22,22,22,1,33,33,33,1, + 31,31,31,1,191,191,191,1,26,26,26,1,184,184,184,1,7,7,7,1, + 156,156,156,1,0,0,0,1,107,107,107,1,70,70,70,1,181,181,181,1, + 21,21,21,1,37,37,37,1,187,187,187,1,240,240,240,2,168,168,168,1, + 23,23,23,1,0,0,0,2,197,197,197,1,1,1,1,1,174,174,174,1, + 29,29,29,1,200,200,200,1,155,155,155,1,198,198,198,1,27,27,27,1, + 184,184,184,1,62,62,62,1,117,117,117,1,0,0,0,1,56,56,56,1, + 128,128,128,1,186,186,186,1,0,0,0,2,174,174,174,1,240,240,240,2, + 168,168,168,1,23,23,23,1,0,0,0,1,80,80,80,1,157,157,157,1, + 1,1,1,1,174,174,174,1,106,106,106,1,87,87,87,1,0,0,0,1, + 199,199,199,1,31,31,31,1,184,184,184,1,23,23,23,1,152,152,152,1, + 0,0,0,1,93,93,93,1,104,104,104,1,167,167,167,1,10,10,10,1, + 28,28,28,1,187,187,187,1,240,240,240,2,168,168,168,1,219,219,219,1, + 220,220,220,1,190,190,190,1,21,21,21,1,1,1,1,1,174,174,174,1, + 41,41,41,1,196,196,196,1,171,171,171,1,190,190,190,1,50,50,50,1, + 184,184,184,1,0,0,0,1,173,173,173,1,134,134,134,1,201,201,201,1, + 27,27,27,1,71,71,71,1,177,177,177,1,170,170,170,1,180,180,180,1, + 240,240,240,2,0,0,0,8,7,7,7,1,6,6,6,1,0,0,0,2, + 46,46,46,1,0,0,0,2,64,64,64,1,21,21,21,1,0,0,0,1, + 39,39,39,1,19,19,19,1,14,14,14,1,159,159,159,1,240,240,240,2, + 0,0,0,18,117,117,117,1,131,131,131,1,161,161,161,1,89,89,89,1, + 240,240,240,2,0,0,0,18,1,1,1,1,61,61,61,1,52,52,52,1, + 0,0,0,1,240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,22, + 240,240,240,2,0,0,0,22,240,240,240,2,0,0,0,22,240,240,240,2, + 0,0,0,22,240,240,240,25,0,0) + ); + +const + objdata_tifidialog: record size: integer; data: array[0..2489] of byte end = + (size: 2490; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,105,102, + 105,100,105,97,108,111,103,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,68,9,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,0,9,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,152,255,144,1,155,255,148,1,158,255,151,1, + 161,255,154,1,164,255,157,1,167,255,160,1,169,255,163,1,172,255,166,1, + 175,255,169,1,178,255,172,1,181,255,175,1,184,255,178,1,186,255,181,1, + 189,255,184,1,192,255,187,1,195,255,190,1,198,255,193,1,201,255,196,1, + 203,255,199,1,206,255,202,1,209,255,205,1,212,255,208,1,215,255,211,1, + 218,255,215,1,152,255,144,1,155,255,148,1,158,255,151,1,161,255,154,1, + 164,255,157,1,167,255,160,1,169,255,163,1,172,255,166,1,175,255,169,1, + 178,255,172,1,181,255,175,1,184,255,178,1,186,255,181,1,189,255,184,1, + 192,255,187,1,195,255,190,1,198,255,193,1,201,255,196,1,203,255,199,1, + 206,255,202,1,209,255,205,1,212,255,208,1,215,255,211,1,218,255,215,1, + 152,255,144,1,155,255,148,1,158,255,151,1,161,255,154,1,164,255,157,1, + 167,255,160,1,169,255,163,1,172,255,166,1,175,255,169,1,178,255,172,1, + 181,255,175,1,184,255,178,1,186,255,181,1,189,255,184,1,192,255,187,1, + 195,255,190,1,198,255,193,1,201,255,196,1,203,255,199,1,206,255,202,1, + 209,255,205,1,212,255,208,1,215,255,211,1,218,255,215,1,152,255,144,1, + 155,255,148,1,158,255,151,1,161,255,154,1,164,255,157,1,167,255,160,1, + 169,255,163,1,172,255,166,1,175,255,169,1,178,255,172,1,181,255,175,1, + 184,255,178,1,186,255,181,1,189,255,184,1,192,255,187,1,195,255,190,1, + 198,255,193,1,201,255,196,1,203,255,199,1,206,255,202,1,209,255,205,1, + 212,255,208,1,215,255,211,1,218,255,215,1,152,255,144,1,155,255,148,1, + 158,255,151,1,161,255,154,1,164,255,157,1,167,255,160,1,169,255,163,1, + 172,255,166,1,175,255,169,1,178,255,172,1,181,255,175,1,184,255,178,1, + 186,255,181,1,189,255,184,1,192,255,187,1,195,255,190,1,198,255,193,1, + 201,255,196,1,203,255,199,1,206,255,202,1,209,255,205,1,212,255,208,1, + 215,255,211,1,218,255,215,1,152,255,144,1,155,255,148,1,158,255,151,1, + 161,255,154,1,164,255,157,1,167,255,160,1,169,255,163,1,172,255,166,1, + 175,255,169,1,178,255,172,1,181,255,175,1,184,255,178,1,186,255,181,1, + 189,255,184,1,192,255,187,1,195,255,190,1,198,255,193,1,201,255,196,1, + 203,255,199,1,206,255,202,1,209,255,205,1,212,255,208,1,215,255,211,1, + 218,255,215,1,152,255,144,1,155,255,148,1,158,255,151,1,161,255,154,1, + 164,255,157,1,167,255,160,1,169,255,163,1,172,255,166,1,175,255,169,1, + 178,255,172,1,181,255,175,1,184,255,178,1,186,255,181,1,189,255,184,1, + 192,255,187,1,195,255,190,1,198,255,193,1,201,255,196,1,203,255,199,1, + 206,255,202,1,209,255,205,1,212,255,208,1,215,255,211,1,218,255,215,1, + 152,255,144,1,126,208,121,1,113,183,108,1,121,192,116,1,152,236,145,1, + 167,255,160,1,169,255,163,1,139,206,134,1,175,255,169,1,178,255,172,1, + 181,255,175,1,184,255,178,1,186,255,181,1,185,250,180,1,192,255,187,1, + 195,255,190,1,198,255,193,1,201,255,196,1,203,255,199,1,206,255,202,1, + 209,255,205,1,212,255,208,1,215,255,211,1,218,255,215,1,152,255,144,1, + 53,87,50,1,58,94,56,1,60,95,57,1,26,41,25,1,130,199,125,1, + 168,254,162,1,84,125,81,1,175,255,169,1,178,255,172,1,181,255,175,1, + 184,255,178,1,186,255,181,1,53,71,51,1,192,255,187,1,195,255,190,1, + 198,255,193,1,201,255,196,1,203,255,199,1,206,255,202,1,209,255,205,1, + 212,255,208,1,215,255,211,1,218,255,215,1,152,255,144,1,53,87,50,1, + 144,232,137,1,161,255,154,1,138,215,132,1,46,70,44,1,169,255,163,1, + 139,206,134,1,175,255,169,1,157,225,152,1,122,172,118,1,162,225,157,1, + 186,255,181,1,53,71,51,1,192,255,187,1,195,255,190,1,192,247,187,1, + 201,255,196,1,203,255,199,1,206,255,202,1,202,247,199,1,212,255,208,1, + 211,250,207,1,218,255,215,1,152,255,144,1,53,87,50,1,144,232,137,1, + 161,255,154,1,164,255,157,1,32,49,31,1,168,254,162,1,55,81,53,1, + 156,228,151,1,45,65,44,1,102,143,98,1,30,42,29,1,182,249,177,1, + 53,71,51,1,192,255,187,1,95,124,92,1,56,72,54,1,68,86,66,1, + 196,246,192,1,158,195,154,1,43,52,42,1,78,94,77,1,71,84,70,1, + 218,255,215,1,152,255,144,1,53,87,50,1,144,232,137,1,161,255,154,1, + 164,255,157,1,38,58,36,1,168,253,162,1,55,81,53,1,160,233,154,1, + 155,222,150,1,159,224,154,1,46,64,45,1,167,229,163,1,53,71,51,1, + 187,248,182,1,76,99,74,1,198,255,193,1,117,148,114,1,147,185,144,1, + 60,74,59,1,192,234,188,1,181,218,178,1,57,68,56,1,218,255,215,1, + 152,255,144,1,53,87,50,1,144,232,137,1,161,255,154,1,164,255,157,1, + 38,58,36,1,168,254,162,1,55,81,53,1,155,226,150,1,38,55,37,1, + 71,100,69,1,41,57,40,1,166,228,162,1,53,71,51,1,145,193,142,1, + 106,138,103,1,198,255,193,1,157,199,153,1,101,127,99,1,56,69,55,1, + 209,255,205,1,212,255,208,1,68,81,67,1,218,255,215,1,152,255,144,1, + 53,87,50,1,144,232,137,1,161,255,154,1,113,175,108,1,64,98,61,1, + 168,254,162,1,55,81,53,1,102,149,99,1,117,168,113,1,181,255,175,1, + 40,56,39,1,163,224,159,1,53,71,51,1,175,232,170,1,79,103,77,1, + 198,255,193,1,128,162,125,1,120,151,118,1,71,88,70,1,201,245,197,1, + 189,227,185,1,57,68,56,1,218,255,215,1,152,255,144,1,53,87,50,1, + 22,36,21,1,22,35,21,1,42,65,40,1,153,234,147,1,168,254,162,1, + 55,81,53,1,147,214,142,1,41,59,40,1,60,84,58,1,47,65,45,1, + 150,205,146,1,53,71,51,1,192,255,187,1,63,82,61,1,94,121,92,1, + 43,54,42,1,182,228,178,1,149,184,146,1,64,78,63,1,71,85,69,1, + 63,75,62,1,218,255,215,1,152,255,144,1,155,255,148,1,158,255,151,1, + 161,255,154,1,164,255,157,1,167,255,160,1,169,255,163,1,172,255,166,1, + 175,255,169,1,173,248,167,1,177,249,171,1,184,255,178,1,186,255,181,1, + 155,209,151,1,192,255,187,1,195,255,190,1,148,191,145,1,184,234,180,1, + 203,255,199,1,174,216,171,1,193,236,190,1,200,241,197,1,81,96,79,1, + 218,255,215,1,152,255,144,1,155,255,148,1,158,255,151,1,161,255,154,1, + 164,255,157,1,167,255,160,1,169,255,163,1,172,255,166,1,175,255,169,1, + 178,255,172,1,181,255,175,1,184,255,178,1,186,255,181,1,189,255,184,1, + 192,255,187,1,195,255,190,1,198,255,193,1,201,255,196,1,203,255,199,1, + 111,138,109,1,102,124,100,1,78,94,77,1,140,166,137,1,218,255,215,1, + 152,255,144,1,155,255,148,1,158,255,151,1,161,255,154,1,164,255,157,1, + 167,255,160,1,169,255,163,1,172,255,166,1,175,255,169,1,178,255,172,1, + 181,255,175,1,184,255,178,1,186,255,181,1,189,255,184,1,192,255,187,1, + 195,255,190,1,198,255,193,1,201,255,196,1,203,255,199,1,205,254,201,1, + 159,194,156,1,169,203,166,1,215,255,211,1,218,255,215,1,152,255,144,1, + 155,255,148,1,158,255,151,1,161,255,154,1,164,255,157,1,167,255,160,1, + 169,255,163,1,172,255,166,1,175,255,169,1,178,255,172,1,181,255,175,1, + 184,255,178,1,186,255,181,1,189,255,184,1,192,255,187,1,195,255,190,1, + 198,255,193,1,201,255,196,1,203,255,199,1,206,255,202,1,209,255,205,1, + 212,255,208,1,215,255,211,1,218,255,215,1,152,255,144,1,155,255,148,1, + 158,255,151,1,161,255,154,1,164,255,157,1,167,255,160,1,169,255,163,1, + 172,255,166,1,175,255,169,1,178,255,172,1,181,255,175,1,184,255,178,1, + 186,255,181,1,189,255,184,1,192,255,187,1,195,255,190,1,198,255,193,1, + 201,255,196,1,203,255,199,1,206,255,202,1,209,255,205,1,212,255,208,1, + 215,255,211,1,218,255,215,1,152,255,144,1,155,255,148,1,158,255,151,1, + 161,255,154,1,164,255,157,1,167,255,160,1,169,255,163,1,172,255,166,1, + 175,255,169,1,178,255,172,1,181,255,175,1,184,255,178,1,186,255,181,1, + 189,255,184,1,192,255,187,1,195,255,190,1,198,255,193,1,201,255,196,1, + 203,255,199,1,206,255,202,1,209,255,205,1,212,255,208,1,215,255,211,1, + 218,255,215,1,152,255,144,1,155,255,148,1,158,255,151,1,161,255,154,1, + 164,255,157,1,167,255,160,1,169,255,163,1,172,255,166,1,175,255,169,1, + 178,255,172,1,181,255,175,1,184,255,178,1,186,255,181,1,189,255,184,1, + 192,255,187,1,195,255,190,1,198,255,193,1,201,255,196,1,203,255,199,1, + 206,255,202,1,209,255,205,1,212,255,208,1,215,255,211,1,218,255,215,1, + 152,255,144,1,155,255,148,1,158,255,151,1,161,255,154,1,164,255,157,1, + 167,255,160,1,169,255,163,1,172,255,166,1,175,255,169,1,178,255,172,1, + 181,255,175,1,184,255,178,1,186,255,181,1,189,255,184,1,192,255,187,1, + 195,255,190,1,198,255,193,1,201,255,196,1,203,255,199,1,206,255,202,1, + 209,255,205,1,212,255,208,1,215,255,211,1,218,255,215,1,152,255,144,1, + 155,255,148,1,158,255,151,1,161,255,154,1,164,255,157,1,167,255,160,1, + 169,255,163,1,172,255,166,1,175,255,169,1,178,255,172,1,181,255,175,1, + 184,255,178,1,186,255,181,1,189,255,184,1,192,255,187,1,195,255,190,1, + 198,255,193,1,201,255,196,1,203,255,199,1,206,255,202,1,209,255,205,1, + 212,255,208,1,215,255,211,1,218,255,215,1,12,0,0,0,255,255,255,255, + 255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tifiitemlinkcomp: record size: integer; data: array[0..1135] of byte end = + (size: 1136; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,105,102, + 105,105,116,101,109,108,105,110,107,99,111,109,112,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,244,3, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,180,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,150,255,143,25,0,0, + 0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255, + 143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0, + 0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255, + 143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0, + 0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255, + 143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0, + 0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255, + 143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0, + 0,22,150,255,143,2,0,0,0,22,150,255,143,25,8,3,0,0,244,244, + 244,25,0,0,0,7,59,59,59,1,133,133,133,1,0,0,0,6,126,126, + 126,1,65,65,65,1,0,0,0,5,244,244,244,2,0,0,0,6,63,63, + 63,1,233,233,233,1,74,74,74,1,6,6,6,6,65,65,65,1,234,234, + 234,1,79,79,79,1,0,0,0,4,244,244,244,2,0,0,0,5,14,14, + 14,1,235,235,235,1,252,252,252,1,250,250,250,8,252,252,252,1,240,240, + 240,1,19,19,19,1,0,0,0,3,244,244,244,2,0,0,0,6,53,53, + 53,1,230,230,230,1,82,82,82,1,0,0,0,6,65,65,65,1,232,232, + 232,1,68,68,68,1,0,0,0,4,244,244,244,2,0,0,0,7,50,50, + 50,1,123,123,123,1,0,0,0,6,116,116,116,1,57,57,57,1,0,0, + 0,5,244,244,244,2,0,0,0,22,244,244,244,2,0,0,0,3,14,14, + 14,1,24,24,24,1,0,0,0,17,244,244,244,2,0,0,0,3,70,70, + 70,1,121,121,121,1,1,1,1,1,121,121,121,1,0,0,0,15,244,244, + 244,2,0,0,0,3,70,70,70,1,121,121,121,1,80,80,80,1,211,211, + 211,1,50,50,50,1,0,0,0,1,84,84,84,1,82,82,82,1,0,0, + 0,1,47,47,47,1,53,53,53,1,103,103,103,1,22,22,22,1,75,75, + 75,1,85,85,85,1,0,0,0,4,244,244,244,2,0,0,0,3,70,70, + 70,1,121,121,121,1,67,67,67,1,206,206,206,1,42,42,42,1,104,104, + 104,1,139,139,139,1,147,147,147,1,90,90,90,1,119,119,119,1,173,173, + 173,1,113,113,113,1,224,224,224,1,117,117,117,1,178,178,178,1,65,65, + 65,1,0,0,0,3,244,244,244,2,0,0,0,3,70,70,70,1,121,121, + 121,1,2,2,2,1,181,181,181,1,0,0,0,1,176,176,176,1,53,53, + 53,1,64,64,64,1,163,163,163,1,119,119,119,1,64,64,64,1,0,0, + 0,1,200,200,200,1,0,0,0,1,81,81,81,1,105,105,105,1,0,0, + 0,3,244,244,244,2,0,0,0,3,70,70,70,1,121,121,121,1,2,2, + 2,1,181,181,181,1,0,0,0,1,201,201,201,1,153,153,153,2,108,108, + 108,1,119,119,119,1,64,64,64,1,0,0,0,1,183,183,183,1,0,0, + 0,1,75,75,75,1,108,108,108,1,0,0,0,3,244,244,244,2,0,0, + 0,3,70,70,70,1,121,121,121,1,1,1,1,1,184,184,184,1,0,0, + 0,1,171,171,171,1,24,24,24,1,2,2,2,1,32,32,32,1,119,119, + 119,1,64,64,64,1,0,0,0,1,183,183,183,1,0,0,0,1,75,75, + 75,1,108,108,108,1,0,0,0,3,244,244,244,2,0,0,0,3,70,70, + 70,1,121,121,121,1,0,0,0,1,199,199,199,1,94,94,94,1,51,51, + 51,1,201,201,201,1,190,190,190,1,74,74,74,1,119,119,119,1,64,64, + 64,1,0,0,0,1,183,183,183,1,0,0,0,1,75,75,75,1,108,108, + 108,1,0,0,0,3,244,244,244,2,0,0,0,6,6,6,6,2,0,0, + 0,1,3,3,3,1,5,5,5,1,0,0,0,11,244,244,244,2,0,0, + 0,22,244,244,244,2,0,0,0,22,244,244,244,2,0,0,0,22,244,244, + 244,2,0,0,0,22,244,244,244,2,0,0,0,22,244,244,244,2,0,0, + 0,22,244,244,244,2,0,0,0,22,244,244,244,25,0,0) + ); + +const + objdata_tifitreeitemlinkcomp: record size: integer; data: array[0..1067] of byte end = + (size: 1068; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,20,116,105,102, + 105,116,114,101,101,105,116,101,109,108,105,110,107,99,111,109,112,23,98,105, + 116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111, + 114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110, + 115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111, + 108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103, + 101,10,172,3,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0, + 0,0,180,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,150,255, + 143,25,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0, + 0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255, + 143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0, + 0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255, + 143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0, + 0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255, + 143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0, + 0,22,150,255,143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255, + 143,2,0,0,0,22,150,255,143,2,0,0,0,22,150,255,143,25,192,2, + 0,0,244,244,244,25,0,0,0,7,59,59,59,1,133,133,133,1,0,0, + 0,6,126,126,126,1,65,65,65,1,0,0,0,5,244,244,244,2,0,0, + 0,6,63,63,63,1,233,233,233,1,74,74,74,1,6,6,6,6,65,65, + 65,1,234,234,234,1,79,79,79,1,0,0,0,4,244,244,244,2,0,0, + 0,5,14,14,14,1,235,235,235,1,252,252,252,1,250,250,250,8,252,252, + 252,1,240,240,240,1,19,19,19,1,0,0,0,3,244,244,244,2,0,0, + 0,6,53,53,53,1,230,230,230,1,82,82,82,1,0,0,0,6,65,65, + 65,1,232,232,232,1,68,68,68,1,0,0,0,4,244,244,244,2,0,0, + 0,7,50,50,50,1,123,123,123,1,0,0,0,6,116,116,116,1,57,57, + 57,1,0,0,0,5,244,244,244,2,0,0,0,22,244,244,244,2,0,0, + 0,3,30,30,30,1,51,51,51,3,39,39,39,1,0,0,0,14,244,244, + 244,2,0,0,0,3,81,81,81,1,136,136,136,1,224,224,224,1,136,136, + 136,1,105,105,105,1,0,0,0,14,244,244,244,2,0,0,0,5,189,189, + 189,1,0,0,0,2,72,72,72,1,73,73,73,1,26,26,26,1,22,22, + 22,1,107,107,107,1,37,37,37,1,0,0,0,1,8,8,8,1,100,100, + 100,1,59,59,59,1,0,0,0,4,244,244,244,2,0,0,0,5,189,189, + 189,1,0,0,0,2,197,197,197,1,150,150,150,1,30,30,30,1,187,187, + 187,1,92,92,92,1,193,193,193,1,8,8,8,1,154,154,154,1,107,107, + 107,1,179,179,179,1,42,42,42,1,0,0,0,3,244,244,244,2,0,0, + 0,5,189,189,189,1,0,0,0,2,186,186,186,1,0,0,0,1,35,35, + 35,1,165,165,165,1,51,51,51,1,149,149,149,1,57,57,57,1,189,189, + 189,1,51,51,51,1,106,106,106,1,111,111,111,1,0,0,0,3,244,244, + 244,2,0,0,0,5,189,189,189,1,0,0,0,2,183,183,183,1,0,0, + 0,1,62,62,62,1,202,202,202,1,153,153,153,2,54,54,54,1,223,223, + 223,1,153,153,153,2,77,77,77,1,0,0,0,3,244,244,244,2,0,0, + 0,5,189,189,189,1,0,0,0,2,183,183,183,1,0,0,0,1,28,28, + 28,1,167,167,167,1,0,0,0,1,29,29,29,1,4,4,4,1,192,192, + 192,1,3,3,3,1,15,15,15,1,19,19,19,1,0,0,0,3,244,244, + 244,2,0,0,0,5,189,189,189,1,0,0,0,2,183,183,183,1,0,0, + 0,2,139,139,139,1,186,186,186,1,179,179,179,1,12,12,12,1,91,91, + 91,1,197,197,197,1,191,191,191,1,37,37,37,1,0,0,0,3,244,244, + 244,2,0,0,0,12,9,9,9,1,0,0,0,3,7,7,7,1,2,2, + 2,1,0,0,0,4,244,244,244,2,0,0,0,22,244,244,244,2,0,0, + 0,22,244,244,244,2,0,0,0,22,244,244,244,2,0,0,0,22,244,244, + 244,2,0,0,0,22,244,244,244,2,0,0,0,22,244,244,244,2,0,0, + 0,22,244,244,244,25,0,0) + ); + +initialization + registerobjectdata(@objdata_tifiintegerendpoint,tbitmapcomp,'tifiintegerendpoint'); + registerobjectdata(@objdata_tifiint64endpoint,tbitmapcomp,'tifiint64endpoint'); + registerobjectdata(@objdata_tifipointerendpoint,tbitmapcomp,'tifipointerendpoint'); + registerobjectdata(@objdata_tifibooleanendpoint,tbitmapcomp,'tifibooleanendpoint'); + registerobjectdata(@objdata_tifirealendpoint,tbitmapcomp,'tifirealendpoint'); + registerobjectdata(@objdata_tifidatetimeendpoint,tbitmapcomp,'tifidatetimeendpoint'); + registerobjectdata(@objdata_tifistringendpoint,tbitmapcomp,'tifistringendpoint'); + registerobjectdata(@objdata_tifiactionendpoint,tbitmapcomp,'tifiactionendpoint'); + registerobjectdata(@objdata_tifilinkcomp,tbitmapcomp,'tifilinkcomp'); + registerobjectdata(@objdata_tifiintegerlinkcomp,tbitmapcomp,'tifiintegerlinkcomp'); + registerobjectdata(@objdata_tifiint64linkcomp,tbitmapcomp,'tifiint64linkcomp'); + registerobjectdata(@objdata_tifipointerlinkcomp,tbitmapcomp,'tifipointerlinkcomp'); + registerobjectdata(@objdata_tifibooleanlinkcomp,tbitmapcomp,'tifibooleanlinkcomp'); + registerobjectdata(@objdata_tifistringlinkcomp,tbitmapcomp,'tifistringlinkcomp'); + registerobjectdata(@objdata_tifidropdownlistlinkcomp,tbitmapcomp,'tifidropdownlistlinkcomp'); + registerobjectdata(@objdata_tifienumlinkcomp,tbitmapcomp,'tifienumlinkcomp'); + registerobjectdata(@objdata_tifireallinkcomp,tbitmapcomp,'tifireallinkcomp'); + registerobjectdata(@objdata_tifidatetimelinkcomp,tbitmapcomp,'tifidatetimelinkcomp'); + registerobjectdata(@objdata_tifiactionlinkcomp,tbitmapcomp,'tifiactionlinkcomp'); + registerobjectdata(@objdata_tifigridlinkcomp,tbitmapcomp,'tifigridlinkcomp'); + registerobjectdata(@objdata_tconnectedifidatasource,tbitmapcomp,'tconnectedifidatasource'); + registerobjectdata(@objdata_tifisqlresult,tbitmapcomp,'tifisqlresult'); + registerobjectdata(@objdata_tififormlinkcomp,tbitmapcomp,'tififormlinkcomp'); + registerobjectdata(@objdata_tifidialoglinkcomp,tbitmapcomp,'tifidialoglinkcomp'); + registerobjectdata(@objdata_tifidialog,tbitmapcomp,'tifidialog'); + registerobjectdata(@objdata_tifiitemlinkcomp,tbitmapcomp,'tifiitemlinkcomp'); + registerobjectdata(@objdata_tifitreeitemlinkcomp,tbitmapcomp,'tifitreeitemlinkcomp'); +end. diff --git a/mseide-msegui/lib/common/regcomponents/regifirem.pas b/mseide-msegui/lib/common/regcomponents/regifirem.pas new file mode 100644 index 0000000..c0f77d7 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regifirem.pas @@ -0,0 +1,287 @@ +{ MSEide Copyright (c) 1999-2014 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regifirem; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +implementation +uses + classes,mclasses,mseifi,msedesignintf,msepropertyeditors, + msetypes{msestrings},msedesigner, + mseclasses,mseifids,mseifiglob,msegui,typinfo,msesockets,mseifigui, + mseifilink,msessl,mdb,regifirem_bmp,mseifidbgui,msecryptohandler; + +type + tmodulelinkitemeditor = class(tclasselementeditor) + protected + function getdefaultstate: propertystatesty; override; + public + function getvalue: msestring; override; + end; + + tmodulelinkeditor = class(tpersistentarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + tmodulelinkactionitemeditor = class(tmodulelinkitemeditor) + public + function getvalue: msestring; override; + end; + + tmodulelinkactionseditor = class(tpersistentarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + tifidatawidgeteditor = class(tcomponentpropertyeditor) + protected + function filtercomponent(const acomponent: tcomponent): boolean; override; + procedure checkcomponent(const avalue: tcomponent); override; + public + end; + + tvaluewidgetlinkitemeditor = class(tmodulelinkitemeditor) + public + function getvalue: msestring; override; + end; + + tvaluewidgetlinkseditor = class(tpersistentarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + tififieldoptoinselementeditor = class(tsetarrayelementeditor) + public + function name: msestring; override; + end; + + tififieldoptionseditor = class(tsetarraypropertyeditor) + protected + function getelementeditorclass: elementeditorclassty; override; + public + procedure setvalue(const value: msestring); override; + end; + + tifitxactioncompeditor = class(tcomponentpropertyeditor) + protected + function filtercomponent(const acomponent: tcomponent): boolean; override; + end; + + tlocalconncompeditor = class(tcomponentpropertyeditor) + protected + function filtercomponent(const acomponent: tcomponent): boolean; override; + end; + + tifidatacolsitemeditor = class(tmodulelinkitemeditor) + public + function getvalue: msestring; override; + end; + + tifidatacolseditor = class(tpersistentarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + +procedure register; +begin + registercomponents('ifi',[tmodulelink,tformlink, + trxwidgetgrid,tdbrxwidgetgrid,ttxdatagrid, + {tpipeifichannel,tsocketpipeifichannel, + tsocketclientifichannel,tsocketserverifichannel,} + ttxdataset,trxdataset,ttxsqlquery, + tpipeiochannel,tsocketstdiochannel, + tsocketclientiochannel,tsocketserveriochannel, + tsocketstdio,tsocketclient, + tsocketserver,tsocketserverstdio, + tssl]); + registerpropertyeditor(typeinfo(tmodulelinkarrayprop),nil,'',tmodulelinkeditor); + registerpropertyeditor(typeinfo(tlinkactions),nil,'',tmodulelinkactionseditor); + registerpropertyeditor(typeinfo(tvaluewidgetlinks),nil,'',tvaluewidgetlinkseditor); + registerpropertyeditor(typeinfo(twidget),tvaluewidgetlink,'widget',tifidatawidgeteditor); + registerpropertyeditor(typeinfo(tcomponent),ttxlinkaction,'ificomp', + tifitxactioncompeditor); + registerpropertyeditor(typeinfo(tcustomiochannel),tcustomiochannel,'localconn', + tlocalconncompeditor); + registerpropertyeditor(typeinfo(tifidatacols),nil,'',tifidatacolseditor); +// registerpropertyeditor(typeinfo(tififieldoptions),tifidscontroller,'', +// tififieldoptionseditor); +end; + +{ tmodulelinkitemeditor } + +function tmodulelinkitemeditor.getvalue: msestring; +//var +// mstr1: msestring; +begin + with tmodulelinkprop(getpointervalue) do begin + result:= msestring('<'+name+'>'); + end; +end; + +{ tmodulelinkactionitemeditor } + +function tmodulelinkactionitemeditor.getvalue: msestring; +var + mstr1: msestring; +begin + result:= inherited getvalue; + with tlinkaction(getpointervalue) do begin + if action = nil then begin + result:= result+'<>'; + end + else begin + mstr1:= msestring(fdesigner.getcomponentname(action)); + if mstr1 = '' then begin + ownernamepath(action); + end; + result:= result+'<'+mstr1+'>'; + end; + end; +end; + +function tmodulelinkitemeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_refresh]; +end; + +{ tmodulelinkeditor } + +function tmodulelinkeditor.geteditorclass: propertyeditorclassty; +begin + result:= tmodulelinkitemeditor; +end; + +{ tmodulelinkactionseditor } + +function tmodulelinkactionseditor.geteditorclass: propertyeditorclassty; +begin + result:= tmodulelinkactionitemeditor; +end; + +{ tifidatawidgeteditor } + +function tifidatawidgeteditor.filtercomponent(const acomponent: tcomponent): boolean; +var + intf1: iificlient; +begin + result:= getcorbainterface(acomponent,typeinfo(iificlient),intf1); +end; + +{ tvaluewidgetlinkitemeditor } + +function tvaluewidgetlinkitemeditor.getvalue: msestring; +var + mstr1: msestring; +begin + result:= inherited getvalue; + with tvaluewidgetlink(getpointervalue) do begin + if widget = nil then begin + result:= result+'<>'; + end + else begin + mstr1:= msestring(fdesigner.getcomponentname(widget)); + if mstr1 = '' then begin + ownernamepath(widget); + end; + result:= result+'<'+mstr1+'>'; + end; + end; +end; + +{ tvaluewidgetlinkseditor } + +function tvaluewidgetlinkseditor.geteditorclass: propertyeditorclassty; +begin + result:= tvaluewidgetlinkitemeditor; +end; + +{ tifidatawidgeteditor } + +procedure tifidatawidgeteditor.checkcomponent(const avalue: tcomponent); +begin + inherited; + with tvaluewidgetlink(fprops[0].instance) do begin + if name = '' then begin + name:= avalue.name; + end; + end; +end; + +{ tififieldoptionseditor } + +function tififieldoptionseditor.getelementeditorclass: elementeditorclassty; +begin + result:= tififieldoptoinselementeditor; +end; + +procedure tififieldoptionseditor.setvalue(const value: msestring); +begin + //readonly +end; + +{ tififieldoptoinselementeditor } + +function tififieldoptoinselementeditor.name: msestring; +var + field1: tfield; +begin + field1:= tifidscontroller(fprops[0].instance).getfield(findex); + if field1 <> nil then begin + result:= msestring(field1.fieldname); + end + else begin + result:= inherited name; + end; +end; + +{ tifitxactioncompeditor } + +function tifitxactioncompeditor.filtercomponent( + const acomponent: tcomponent): boolean; +var + intf1: iifitxaction; +begin + result:= mseclasses.getcorbainterface(acomponent,typeinfo(iifitxaction),intf1); +end; + +{ tlocalconncompeditor } + +function tlocalconncompeditor.filtercomponent( + const acomponent: tcomponent): boolean; +begin + result:= acomponent <> fcomponent; +end; + +{ tifidatacolsitemeditor } + +function tifidatacolsitemeditor.getvalue: msestring; +begin + with tifidatacol(getpointervalue) do begin + result:= msestring('<'+name+'>'); + end; +end; + +{ tifidatacolseditor } + +function tifidatacolseditor.geteditorclass: propertyeditorclassty; +begin + result:= tifidatacolsitemeditor; +end; + +initialization + register; +end. diff --git a/mseide-msegui/lib/common/regcomponents/regifirem_bmp.pas b/mseide-msegui/lib/common/regcomponents/regifirem_bmp.pas new file mode 100644 index 0000000..c21aae2 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regifirem_bmp.pas @@ -0,0 +1,691 @@ +unit regifirem_bmp; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msebitmap; + +const + objdata_tsocketclient: record size: integer; data: array[0..221] of byte end = + (size: 222; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,115,111, + 99,107,101,116,99,108,105,101,110,116,12,98,105,116,109,97,112,46,105,109, + 97,103,101,10,172,0,0,0,0,0,0,0,0,0,0,0,24,0,0,0, + 24,0,0,0,120,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 192,192,192,38,99,99,99,3,192,192,192,20,99,99,99,1,192,192,192,2, + 99,99,99,1,192,192,192,19,99,99,99,1,192,192,192,3,0,0,0,4, + 192,192,192,13,99,99,99,4,192,192,192,3,99,99,99,1,192,192,192,16, + 99,99,99,4,192,192,192,3,99,99,99,1,192,192,192,19,99,99,99,1, + 192,192,192,3,0,0,0,4,192,192,192,17,99,99,99,1,192,192,192,2, + 99,99,99,1,192,192,192,21,99,99,99,3,192,192,192,255,192,192,192,112, + 0,0) + ); + +const + objdata_tsocketserver: record size: integer; data: array[0..237] of byte end = + (size: 238; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,115,111, + 99,107,101,116,115,101,114,118,101,114,12,98,105,116,109,97,112,46,105,109, + 97,103,101,10,188,0,0,0,0,0,0,0,0,0,0,0,24,0,0,0, + 24,0,0,0,136,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 192,192,192,42,99,99,99,3,192,192,192,20,99,99,99,1,192,192,192,3, + 99,99,99,1,192,192,192,18,99,99,99,1,192,192,192,2,0,0,0,1, + 192,192,192,2,99,99,99,1,192,192,192,17,99,99,99,1,192,192,192,5, + 99,99,99,1,192,192,192,17,99,99,99,1,192,192,192,5,99,99,99,1, + 192,192,192,17,99,99,99,1,192,192,192,2,0,0,0,1,192,192,192,2, + 99,99,99,1,192,192,192,18,99,99,99,1,192,192,192,3,99,99,99,1, + 192,192,192,20,99,99,99,3,192,192,192,255,192,192,192,108,0,0) + ); + +const + objdata_tsocketstdio: record size: integer; data: array[0..656] of byte end = + (size: 657; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,115,111, + 99,107,101,116,115,116,100,105,111,12,98,105,116,109,97,112,46,105,109,97, + 103,101,10,96,2,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24, + 0,0,0,44,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192, + 192,192,33,99,99,99,3,192,192,192,6,99,99,99,3,192,192,192,11,99, + 99,99,1,192,192,192,2,99,99,99,1,192,192,192,5,99,99,99,1,192, + 192,192,3,99,99,99,1,192,192,192,9,99,99,99,1,192,192,192,3,0, + 0,0,3,192,192,192,2,99,99,99,1,192,192,192,2,0,0,0,1,192, + 192,192,2,99,99,99,1,192,192,192,5,99,99,99,4,192,192,192,3,99, + 99,99,1,192,192,192,4,99,99,99,1,192,192,192,5,99,99,99,1,192, + 192,192,5,99,99,99,4,192,192,192,3,99,99,99,1,192,192,192,4,99, + 99,99,1,192,192,192,5,99,99,99,1,192,192,192,8,99,99,99,1,192, + 192,192,3,0,0,0,3,192,192,192,2,99,99,99,1,192,192,192,2,0, + 0,0,1,192,192,192,2,99,99,99,1,192,192,192,9,99,99,99,1,192, + 192,192,2,99,99,99,1,192,192,192,5,99,99,99,1,192,192,192,3,99, + 99,99,1,192,192,192,11,99,99,99,3,192,192,192,6,99,99,99,3,192, + 192,192,83,0,0,0,1,192,192,192,4,0,0,0,1,192,192,192,13,0, + 0,0,3,192,192,192,2,0,0,0,1,192,192,192,4,0,0,0,1,192, + 192,192,1,0,0,0,1,192,192,192,2,0,0,0,3,192,192,192,5,0, + 0,0,1,192,192,192,4,0,0,0,3,192,192,192,1,0,0,0,3,192, + 192,192,1,0,0,0,1,192,192,192,1,0,0,0,1,192,192,192,3,0, + 0,0,1,192,192,192,4,0,0,0,3,192,192,192,3,0,0,0,1,192, + 192,192,1,0,0,0,1,192,192,192,2,0,0,0,1,192,192,192,1,0, + 0,0,1,192,192,192,1,0,0,0,1,192,192,192,3,0,0,0,1,192, + 192,192,7,0,0,0,1,192,192,192,2,0,0,0,1,192,192,192,1,0, + 0,0,1,192,192,192,2,0,0,0,1,192,192,192,1,0,0,0,1,192, + 192,192,1,0,0,0,1,192,192,192,3,0,0,0,1,192,192,192,7,0, + 0,0,1,192,192,192,2,0,0,0,1,192,192,192,1,0,0,0,1,192, + 192,192,2,0,0,0,1,192,192,192,1,0,0,0,1,192,192,192,1,0, + 0,0,1,192,192,192,3,0,0,0,1,192,192,192,4,0,0,0,3,192, + 192,192,3,0,0,0,1,192,192,192,2,0,0,0,3,192,192,192,1,0, + 0,0,1,192,192,192,2,0,0,0,3,192,192,192,123,0,0) + ); + +const + objdata_tsocketserverstdio: record size: integer; data: array[0..550] of byte end = + (size: 551; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,18,116,115,111, + 99,107,101,116,115,101,114,118,101,114,115,116,100,105,111,12,98,105,116,109, + 97,112,46,105,109,97,103,101,10,240,1,0,0,0,0,0,0,0,0,0, + 0,24,0,0,0,24,0,0,0,188,1,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,192,192,192,42,99,99,99,3,192,192,192,20,99,99,99, + 1,192,192,192,3,99,99,99,1,192,192,192,18,99,99,99,1,192,192,192, + 2,0,0,0,1,192,192,192,2,99,99,99,1,192,192,192,17,99,99,99, + 1,192,192,192,5,99,99,99,1,192,192,192,17,99,99,99,1,192,192,192, + 5,99,99,99,1,192,192,192,17,99,99,99,1,192,192,192,2,0,0,0, + 1,192,192,192,2,99,99,99,1,192,192,192,18,99,99,99,1,192,192,192, + 3,99,99,99,1,192,192,192,20,99,99,99,3,192,192,192,83,0,0,0, + 1,192,192,192,4,0,0,0,1,192,192,192,13,0,0,0,3,192,192,192, + 2,0,0,0,1,192,192,192,4,0,0,0,1,192,192,192,1,0,0,0, + 1,192,192,192,2,0,0,0,3,192,192,192,5,0,0,0,1,192,192,192, + 4,0,0,0,3,192,192,192,1,0,0,0,3,192,192,192,1,0,0,0, + 1,192,192,192,1,0,0,0,1,192,192,192,3,0,0,0,1,192,192,192, + 4,0,0,0,3,192,192,192,3,0,0,0,1,192,192,192,1,0,0,0, + 1,192,192,192,2,0,0,0,1,192,192,192,1,0,0,0,1,192,192,192, + 1,0,0,0,1,192,192,192,3,0,0,0,1,192,192,192,7,0,0,0, + 1,192,192,192,2,0,0,0,1,192,192,192,1,0,0,0,1,192,192,192, + 2,0,0,0,1,192,192,192,1,0,0,0,1,192,192,192,1,0,0,0, + 1,192,192,192,3,0,0,0,1,192,192,192,7,0,0,0,1,192,192,192, + 2,0,0,0,1,192,192,192,1,0,0,0,1,192,192,192,2,0,0,0, + 1,192,192,192,1,0,0,0,1,192,192,192,1,0,0,0,1,192,192,192, + 3,0,0,0,1,192,192,192,4,0,0,0,3,192,192,192,3,0,0,0, + 1,192,192,192,2,0,0,0,3,192,192,192,1,0,0,0,1,192,192,192, + 2,0,0,0,3,192,192,192,123,0,0) + ); + +const + objdata_tpipeiochannel: record size: integer; data: array[0..886] of byte end = + (size: 887; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,112,105, + 112,101,105,111,99,104,97,110,110,101,108,12,98,105,116,109,97,112,46,105, + 109,97,103,101,10,68,3,0,0,0,0,0,0,0,0,0,0,24,0,0, + 0,24,0,0,0,16,3,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,192,192,192,25,153,227,172,22,192,192,192,2,153,227,172,3,0,0,0, + 2,147,147,147,16,153,227,172,1,192,192,192,2,153,227,172,2,0,0,0, + 1,118,119,118,2,0,0,0,1,252,252,252,13,252,253,252,2,153,227,172, + 1,192,192,192,2,153,227,172,1,0,0,0,1,166,165,166,4,0,0,0, + 1,210,214,210,1,201,216,205,1,210,214,211,1,209,215,211,1,210,215,210, + 2,210,215,211,2,209,215,211,1,210,215,211,5,153,227,172,1,192,192,192, + 2,153,227,172,1,0,0,0,1,214,214,214,4,0,0,0,1,166,165,166, + 1,166,166,166,1,166,166,165,1,166,165,165,1,165,165,165,1,166,165,165, + 1,165,165,166,1,165,166,166,1,166,166,166,1,166,165,165,5,153,227,172, + 1,192,192,192,2,153,227,172,2,0,0,0,1,252,252,252,1,255,255,255, + 1,0,0,0,1,118,119,118,1,118,118,118,1,119,118,118,1,118,118,118, + 2,118,119,118,1,118,118,118,1,118,119,118,1,119,118,119,1,118,118,118, + 1,119,118,118,5,153,227,172,1,192,192,192,2,153,227,172,3,0,0,0, + 2,90,89,90,2,89,89,89,1,90,90,90,1,90,89,90,2,89,89,90, + 2,90,90,89,1,90,89,90,7,153,227,172,1,192,192,192,2,153,227,172, + 22,192,192,192,2,153,227,172,1,147,147,146,1,147,147,147,1,146,146,147, + 1,147,147,147,1,147,146,147,2,147,147,147,1,146,147,147,1,147,147,147, + 2,147,147,146,2,146,147,146,2,147,147,147,2,0,0,0,2,153,227,172, + 3,192,192,192,2,153,227,172,1,252,252,252,8,253,252,252,1,252,252,252, + 1,252,252,253,1,252,252,252,1,252,253,252,2,252,252,252,1,0,0,0, + 1,118,119,118,2,0,0,0,1,153,227,172,2,192,192,192,2,153,227,172, + 1,210,215,210,1,210,214,211,1,210,215,210,1,210,215,211,1,209,215,211, + 1,210,214,210,2,201,216,205,1,210,214,211,1,209,215,211,1,210,215,210, + 2,210,215,211,2,0,0,0,1,166,165,166,4,0,0,0,1,153,227,172, + 1,192,192,192,2,153,227,172,1,166,166,166,1,165,166,166,1,165,166,165, + 1,166,165,166,1,165,165,165,1,166,165,165,1,166,165,166,1,166,166,166, + 1,166,166,165,1,166,165,165,1,165,165,165,1,166,165,165,1,165,165,166, + 1,165,166,166,1,0,0,0,1,214,214,214,4,0,0,0,1,153,227,172, + 1,192,192,192,2,153,227,172,1,118,118,118,2,119,118,119,1,118,119,118, + 1,118,118,118,1,118,118,119,1,118,118,118,1,119,118,118,1,118,118,118, + 2,118,119,118,1,118,118,118,1,118,119,118,1,119,118,119,1,118,118,119, + 1,0,0,0,1,252,252,252,1,255,255,255,1,0,0,0,1,153,227,172, + 2,192,192,192,2,153,227,172,1,90,89,89,1,89,90,90,1,90,89,90, + 1,90,90,89,1,90,89,90,1,90,89,89,1,90,90,90,1,89,89,89, + 1,90,90,90,1,90,89,90,2,89,89,90,2,90,90,89,1,90,89,90, + 1,90,90,90,1,90,89,89,1,0,0,0,1,153,227,172,3,192,192,192, + 2,153,227,172,22,192,192,192,2,153,227,172,22,192,192,192,2,153,227,172, + 22,192,192,192,2,153,227,172,22,192,192,192,2,153,227,172,22,192,192,192, + 2,153,227,172,22,192,192,192,2,153,227,172,22,192,192,192,2,153,227,172, + 22,192,192,192,25,0,0) + ); + +const + objdata_tsocketstdiochannel: record size: integer; data: array[0..823] of byte end = + (size: 824; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,115,111, + 99,107,101,116,115,116,100,105,111,99,104,97,110,110,101,108,12,98,105,116, + 109,97,112,46,105,109,97,103,101,10,0,3,0,0,0,0,0,0,0,0, + 0,0,24,0,0,0,24,0,0,0,204,2,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,192,192,192,25,153,227,172,8,99,99,99,3,153,227, + 172,6,99,99,99,3,153,227,172,2,192,192,192,2,153,227,172,7,99,99, + 99,1,192,192,192,2,99,99,99,1,153,227,172,5,99,99,99,1,192,192, + 192,3,99,99,99,1,153,227,172,1,192,192,192,2,153,227,172,6,99,99, + 99,1,192,192,192,3,0,0,0,3,153,227,172,2,99,99,99,1,192,192, + 192,2,0,0,0,1,192,192,192,2,99,99,99,1,192,192,192,2,153,227, + 172,3,99,99,99,4,192,192,192,3,99,99,99,1,153,227,172,4,99,99, + 99,1,192,192,192,5,99,99,99,1,192,192,192,2,153,227,172,3,99,99, + 99,4,192,192,192,3,99,99,99,1,153,227,172,4,99,99,99,1,192,192, + 192,5,99,99,99,1,192,192,192,2,153,227,172,6,99,99,99,1,192,192, + 192,3,0,0,0,3,153,227,172,2,99,99,99,1,192,192,192,2,0,0, + 0,1,192,192,192,2,99,99,99,1,192,192,192,2,153,227,172,7,99,99, + 99,1,192,192,192,2,99,99,99,1,153,227,172,5,99,99,99,1,192,192, + 192,3,99,99,99,1,153,227,172,1,192,192,192,2,153,227,172,8,99,99, + 99,3,153,227,172,6,99,99,99,3,153,227,172,2,192,192,192,2,153,227, + 172,22,192,192,192,2,153,227,172,22,192,192,192,2,153,227,172,22,192,192, + 192,2,153,227,172,7,0,0,0,1,153,227,172,4,0,0,0,1,153,227, + 172,9,192,192,192,2,153,227,172,2,0,0,0,3,153,227,172,2,0,0, + 0,1,153,227,172,4,0,0,0,1,153,227,172,1,0,0,0,1,153,227, + 172,2,0,0,0,3,153,227,172,2,192,192,192,2,153,227,172,1,0,0, + 0,1,153,227,172,4,0,0,0,3,153,227,172,1,0,0,0,3,153,227, + 172,1,0,0,0,1,153,227,172,1,0,0,0,1,153,227,172,3,0,0, + 0,1,153,227,172,1,192,192,192,2,153,227,172,1,0,0,0,3,153,227, + 172,3,0,0,0,1,153,227,172,1,0,0,0,1,153,227,172,2,0,0, + 0,1,153,227,172,1,0,0,0,1,153,227,172,1,0,0,0,1,153,227, + 172,3,0,0,0,1,153,227,172,1,192,192,192,2,153,227,172,4,0,0, + 0,1,153,227,172,2,0,0,0,1,153,227,172,1,0,0,0,1,153,227, + 172,2,0,0,0,1,153,227,172,1,0,0,0,1,153,227,172,1,0,0, + 0,1,153,227,172,3,0,0,0,1,153,227,172,1,192,192,192,2,153,227, + 172,4,0,0,0,1,153,227,172,2,0,0,0,1,153,227,172,1,0,0, + 0,1,153,227,172,2,0,0,0,1,153,227,172,1,0,0,0,1,153,227, + 172,1,0,0,0,1,153,227,172,3,0,0,0,1,153,227,172,1,192,192, + 192,2,153,227,172,1,0,0,0,3,153,227,172,3,0,0,0,1,153,227, + 172,2,0,0,0,3,153,227,172,1,0,0,0,1,153,227,172,2,0,0, + 0,3,153,227,172,2,192,192,192,2,153,227,172,22,192,192,192,2,153,227, + 172,22,192,192,192,2,153,227,172,22,192,192,192,2,153,227,172,22,192,192, + 192,25,0,0) + ); + +const + objdata_tsocketserveriochannel: record size: integer; data: array[0..402] of byte end = + (size: 403; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,22,116,115,111, + 99,107,101,116,115,101,114,118,101,114,105,111,99,104,97,110,110,101,108,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,88,1,0,0,0,0,0, + 0,0,0,0,0,24,0,0,0,24,0,0,0,36,1,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,192,192,192,25,153,227,172,17,99,99,99, + 3,153,227,172,2,192,192,192,2,153,227,172,16,99,99,99,1,192,192,192, + 3,99,99,99,1,153,227,172,1,192,192,192,2,153,227,172,15,99,99,99, + 1,192,192,192,2,0,0,0,1,192,192,192,2,99,99,99,1,192,192,192, + 2,153,227,172,15,99,99,99,1,192,192,192,5,99,99,99,1,192,192,192, + 2,153,227,172,15,99,99,99,1,192,192,192,5,99,99,99,1,192,192,192, + 2,153,227,172,15,99,99,99,1,192,192,192,2,0,0,0,1,192,192,192, + 2,99,99,99,1,192,192,192,2,153,227,172,16,99,99,99,1,192,192,192, + 3,99,99,99,1,153,227,172,1,192,192,192,2,153,227,172,17,99,99,99, + 3,153,227,172,2,192,192,192,2,153,227,172,22,192,192,192,2,153,227,172, + 22,192,192,192,2,153,227,172,22,192,192,192,2,153,227,172,22,192,192,192, + 2,153,227,172,22,192,192,192,2,153,227,172,22,192,192,192,2,153,227,172, + 22,192,192,192,2,153,227,172,22,192,192,192,2,153,227,172,22,192,192,192, + 2,153,227,172,22,192,192,192,2,153,227,172,22,192,192,192,2,153,227,172, + 22,192,192,192,2,153,227,172,22,192,192,192,2,153,227,172,22,192,192,192, + 25,0,0) + ); + +const + objdata_tsocketclientiochannel: record size: integer; data: array[0..402] of byte end = + (size: 403; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,22,116,115,111, + 99,107,101,116,99,108,105,101,110,116,105,111,99,104,97,110,110,101,108,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,88,1,0,0,0,0,0, + 0,0,0,0,0,24,0,0,0,24,0,0,0,36,1,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,192,192,192,25,153,227,172,13,99,99,99, + 3,153,227,172,6,192,192,192,2,153,227,172,12,99,99,99,1,192,192,192, + 2,99,99,99,1,153,227,172,6,192,192,192,2,153,227,172,11,99,99,99, + 1,192,192,192,3,0,0,0,4,153,227,172,3,192,192,192,2,153,227,172, + 8,99,99,99,4,192,192,192,3,99,99,99,1,153,227,172,6,192,192,192, + 2,153,227,172,8,99,99,99,4,192,192,192,3,99,99,99,1,153,227,172, + 6,192,192,192,2,153,227,172,11,99,99,99,1,192,192,192,3,0,0,0, + 4,153,227,172,3,192,192,192,2,153,227,172,12,99,99,99,1,192,192,192, + 2,99,99,99,1,153,227,172,6,192,192,192,2,153,227,172,13,99,99,99, + 3,153,227,172,6,192,192,192,2,153,227,172,22,192,192,192,2,153,227,172, + 22,192,192,192,2,153,227,172,22,192,192,192,2,153,227,172,22,192,192,192, + 2,153,227,172,22,192,192,192,2,153,227,172,22,192,192,192,2,153,227,172, + 22,192,192,192,2,153,227,172,22,192,192,192,2,153,227,172,22,192,192,192, + 2,153,227,172,22,192,192,192,2,153,227,172,22,192,192,192,2,153,227,172, + 22,192,192,192,2,153,227,172,22,192,192,192,2,153,227,172,22,192,192,192, + 25,0,0) + ); + +const + objdata_tformlink: record size: integer; data: array[0..733] of byte end = + (size: 734; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,102,111, + 114,109,108,105,110,107,12,98,105,116,109,97,112,46,105,109,97,103,101,10, + 176,2,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0,0,0, + 124,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,192,192,25, + 0,0,0,1,153,227,172,2,0,0,0,2,153,227,172,2,0,0,0,2, + 153,227,172,2,0,0,0,2,153,227,172,2,0,0,0,2,153,227,172,2, + 0,0,0,2,153,227,172,1,192,192,192,2,153,227,172,22,192,192,192,2, + 153,227,172,2,255,255,255,18,153,227,172,1,0,0,0,1,192,192,192,2, + 0,0,0,1,153,227,172,1,255,255,255,1,255,0,0,13,255,255,255,1, + 0,0,0,1,192,192,192,1,128,128,128,1,153,227,172,1,0,0,0,1, + 192,192,192,2,0,0,0,1,153,227,172,1,255,255,255,1,255,0,0,13, + 255,255,255,1,192,192,192,1,0,0,0,1,128,128,128,1,153,227,172,2, + 192,192,192,2,153,227,172,2,255,255,255,1,128,128,128,17,153,227,172,2, + 192,192,192,2,153,227,172,2,255,255,255,1,192,192,192,16,128,128,128,1, + 153,227,172,1,0,0,0,1,192,192,192,2,153,227,172,2,255,255,255,1, + 192,192,192,16,128,128,128,1,153,227,172,1,0,0,0,1,192,192,192,2, + 0,0,0,1,153,227,172,1,255,255,255,1,192,192,192,16,128,128,128,1, + 153,227,172,2,192,192,192,2,0,0,0,1,153,227,172,1,255,255,255,1, + 192,192,192,16,128,128,128,1,153,227,172,2,192,192,192,2,153,227,172,2, + 255,255,255,1,192,192,192,16,128,128,128,1,153,227,172,1,0,0,0,1, + 192,192,192,2,153,227,172,2,255,255,255,1,192,192,192,16,128,128,128,1, + 153,227,172,1,0,0,0,1,192,192,192,2,0,0,0,1,153,227,172,1, + 255,255,255,1,192,192,192,16,128,128,128,1,153,227,172,2,192,192,192,2, + 0,0,0,1,153,227,172,1,255,255,255,1,192,192,192,16,128,128,128,1, + 153,227,172,2,192,192,192,2,153,227,172,2,255,255,255,1,192,192,192,16, + 128,128,128,1,153,227,172,1,0,0,0,1,192,192,192,2,153,227,172,2, + 255,255,255,1,192,192,192,16,128,128,128,1,153,227,172,1,0,0,0,1, + 192,192,192,2,0,0,0,1,153,227,172,1,255,255,255,1,192,192,192,16, + 128,128,128,1,153,227,172,2,192,192,192,2,0,0,0,1,153,227,172,1, + 255,255,255,1,192,192,192,16,128,128,128,1,153,227,172,2,192,192,192,2, + 153,227,172,2,255,255,255,1,192,192,192,16,128,128,128,1,153,227,172,1, + 0,0,0,1,192,192,192,2,153,227,172,2,128,128,128,18,153,227,172,1, + 0,0,0,1,192,192,192,2,0,0,0,1,153,227,172,21,192,192,192,2, + 0,0,0,1,153,227,172,2,0,0,0,2,153,227,172,2,0,0,0,2, + 153,227,172,2,0,0,0,2,153,227,172,2,0,0,0,2,153,227,172,2, + 0,0,0,2,153,227,172,1,192,192,192,25,0,0) + ); + +const + objdata_tmodulelink: record size: integer; data: array[0..619] of byte end = + (size: 620; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,109,111, + 100,117,108,101,108,105,110,107,12,98,105,116,109,97,112,46,105,109,97,103, + 101,10,60,2,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0, + 0,0,8,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,192, + 192,25,0,0,0,1,153,227,172,2,0,0,0,2,153,227,172,2,0,0, + 0,2,153,227,172,2,0,0,0,2,153,227,172,2,0,0,0,2,153,227, + 172,2,0,0,0,2,153,227,172,1,192,192,192,2,153,227,172,22,192,192, + 192,2,153,227,172,21,0,0,0,1,192,192,192,2,0,0,0,1,153,227, + 172,2,0,0,0,2,153,227,172,2,0,0,0,2,153,227,172,2,0,0, + 0,2,153,227,172,2,0,0,0,2,153,227,172,4,0,0,0,1,192,192, + 192,2,0,0,0,1,153,227,172,17,0,0,0,1,153,227,172,3,192,192, + 192,2,153,227,172,18,0,0,0,1,153,227,172,3,192,192,192,2,153,227, + 172,3,0,0,0,1,153,227,172,17,0,0,0,1,192,192,192,2,153,227, + 172,3,0,0,0,1,153,227,172,17,0,0,0,1,192,192,192,2,0,0, + 0,1,153,227,172,17,0,0,0,1,153,227,172,3,192,192,192,2,0,0, + 0,1,153,227,172,17,0,0,0,1,153,227,172,3,192,192,192,2,153,227, + 172,3,0,0,0,1,153,227,172,17,0,0,0,1,192,192,192,2,153,227, + 172,3,0,0,0,1,153,227,172,17,0,0,0,1,192,192,192,2,0,0, + 0,1,153,227,172,17,0,0,0,1,153,227,172,3,192,192,192,2,0,0, + 0,1,153,227,172,17,0,0,0,1,153,227,172,3,192,192,192,2,153,227, + 172,3,0,0,0,1,153,227,172,17,0,0,0,1,192,192,192,2,153,227, + 172,3,0,0,0,1,153,227,172,17,0,0,0,1,192,192,192,2,0,0, + 0,1,153,227,172,17,0,0,0,1,153,227,172,3,192,192,192,2,0,0, + 0,1,153,227,172,17,0,0,0,1,153,227,172,3,192,192,192,2,153,227, + 172,3,0,0,0,2,153,227,172,2,0,0,0,2,153,227,172,2,0,0, + 0,2,153,227,172,2,0,0,0,2,153,227,172,4,0,0,0,1,192,192, + 192,2,153,227,172,21,0,0,0,1,192,192,192,2,0,0,0,1,153,227, + 172,21,192,192,192,2,0,0,0,1,153,227,172,2,0,0,0,2,153,227, + 172,2,0,0,0,2,153,227,172,2,0,0,0,2,153,227,172,2,0,0, + 0,2,153,227,172,2,0,0,0,2,153,227,172,1,192,192,192,25,0,0) + ); + +const + objdata_trxwidgetgrid: record size: integer; data: array[0..869] of byte end = + (size: 870; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,114,120, + 119,105,100,103,101,116,103,114,105,100,12,98,105,116,109,97,112,46,105,109, + 97,103,101,10,52,3,0,0,0,0,0,0,0,0,0,0,24,0,0,0, + 24,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 255,0,255,50,128,128,128,20,255,0,255,4,128,128,128,1,192,192,192,1, + 128,128,128,1,192,192,192,7,255,255,255,1,192,192,192,8,128,128,128,1, + 255,0,255,4,128,128,128,20,255,0,255,4,128,128,128,1,192,192,192,1, + 128,128,128,1,153,227,172,6,192,192,192,1,153,227,172,9,128,128,128,1, + 255,0,255,4,128,128,128,1,192,192,192,1,128,128,128,1,153,227,172,1, + 167,167,167,4,153,227,172,1,192,192,192,1,153,227,172,1,167,167,167,3, + 153,227,172,5,128,128,128,1,255,0,255,4,128,128,128,1,192,192,192,1, + 128,128,128,1,0,0,255,5,153,227,172,1,192,192,192,1,153,227,172,1, + 0,0,255,1,153,227,172,5,0,0,255,1,153,227,172,1,128,128,128,1, + 255,0,255,4,128,128,128,1,192,192,192,1,128,128,128,1,0,0,255,1, + 167,167,167,4,0,0,255,1,192,192,192,1,153,227,172,1,167,167,167,1, + 0,0,255,1,167,167,167,3,0,0,255,1,153,227,172,2,128,128,128,1, + 255,0,255,4,128,128,128,1,192,192,192,1,128,128,128,1,0,0,255,1, + 153,227,172,4,0,0,255,1,192,192,192,1,153,227,172,2,0,0,255,1, + 153,227,172,3,0,0,255,1,153,227,172,2,128,128,128,1,255,0,255,4, + 128,128,128,1,192,192,192,1,128,128,128,1,0,0,255,1,167,167,167,3, + 153,227,172,1,0,0,255,1,192,192,192,1,153,227,172,1,167,167,167,2, + 0,0,255,1,167,167,167,1,0,0,255,1,167,167,167,2,153,227,172,1, + 128,128,128,1,255,0,255,4,128,128,128,1,192,192,192,1,128,128,128,1, + 0,0,255,5,153,227,172,1,192,192,192,1,153,227,172,4,0,0,255,1, + 153,227,172,4,128,128,128,1,255,0,255,4,128,128,128,1,192,192,192,1, + 128,128,128,1,0,0,255,1,167,167,167,3,0,0,255,1,153,227,172,1, + 192,192,192,1,153,227,172,1,167,167,167,2,0,0,255,1,167,167,167,1, + 0,0,255,1,153,227,172,3,128,128,128,1,255,0,255,4,128,128,128,1, + 192,192,192,1,128,128,128,1,0,0,255,1,153,227,172,4,0,0,255,1, + 192,192,192,1,153,227,172,2,0,0,255,1,153,227,172,3,0,0,255,1, + 153,227,172,2,128,128,128,1,255,0,255,4,128,128,128,1,192,192,192,1, + 128,128,128,1,0,0,255,1,167,167,167,3,153,227,172,1,0,0,255,1, + 192,192,192,1,153,227,172,1,167,167,167,1,0,0,255,1,167,167,167,1, + 153,227,172,2,0,0,255,1,153,227,172,2,128,128,128,1,255,0,255,4, + 128,128,128,1,192,192,192,1,128,128,128,1,0,0,255,1,153,227,172,4, + 0,0,255,1,192,192,192,1,153,227,172,1,0,0,255,1,153,227,172,5, + 0,0,255,1,153,227,172,1,128,128,128,1,255,0,255,4,128,128,128,1, + 192,192,192,1,128,128,128,1,153,227,172,1,167,167,167,3,153,227,172,2, + 192,192,192,1,153,227,172,9,128,128,128,1,255,0,255,4,128,128,128,1, + 192,192,192,1,128,128,128,1,153,227,172,6,192,192,192,1,153,227,172,9, + 128,128,128,1,255,0,255,4,128,128,128,1,192,192,192,1,128,128,128,1, + 153,227,172,6,192,192,192,1,153,227,172,9,128,128,128,1,255,0,255,4, + 128,128,128,20,255,0,255,98,0,0) + ); + +const + objdata_ttxdatagrid: record size: integer; data: array[0..871] of byte end = + (size: 872; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,116,120, + 100,97,116,97,103,114,105,100,12,98,105,116,109,97,112,46,105,109,97,103, + 101,10,56,3,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0, + 0,0,4,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0, + 255,50,128,128,128,20,255,0,255,4,128,128,128,1,192,192,192,1,128,128, + 128,1,192,192,192,7,255,255,255,1,192,192,192,8,128,128,128,1,255,0, + 255,4,128,128,128,20,255,0,255,4,128,128,128,1,192,192,192,1,128,128, + 128,1,153,227,172,6,192,192,192,1,153,227,172,9,128,128,128,1,255,0, + 255,4,128,128,128,1,192,192,192,1,128,128,128,1,153,227,172,1,167,167, + 167,4,153,227,172,1,192,192,192,1,153,227,172,1,167,167,167,3,153,227, + 172,5,128,128,128,1,255,0,255,4,128,128,128,1,192,192,192,1,0,0, + 255,7,192,192,192,1,0,0,255,1,153,227,172,5,0,0,255,1,153,227, + 172,2,128,128,128,1,255,0,255,4,128,128,128,1,192,192,192,1,128,128, + 128,1,153,227,172,1,167,167,167,1,0,0,255,1,167,167,167,2,153,227, + 172,1,192,192,192,1,153,227,172,1,0,0,255,1,167,167,167,3,0,0, + 255,1,167,167,167,1,153,227,172,2,128,128,128,1,255,0,255,4,128,128, + 128,1,192,192,192,1,128,128,128,1,153,227,172,2,0,0,255,1,153,227, + 172,3,192,192,192,1,153,227,172,1,0,0,255,1,153,227,172,3,0,0, + 255,1,153,227,172,3,128,128,128,1,255,0,255,4,128,128,128,1,192,192, + 192,1,128,128,128,1,153,227,172,1,167,167,167,1,0,0,255,1,167,167, + 167,1,153,227,172,2,192,192,192,1,153,227,172,1,167,167,167,1,0,0, + 255,1,167,167,167,1,0,0,255,1,167,167,167,3,153,227,172,1,128,128, + 128,1,255,0,255,4,128,128,128,1,192,192,192,1,128,128,128,1,153,227, + 172,2,0,0,255,1,153,227,172,3,192,192,192,1,153,227,172,3,0,0, + 255,1,153,227,172,5,128,128,128,1,255,0,255,4,128,128,128,1,192,192, + 192,1,128,128,128,1,153,227,172,1,167,167,167,1,0,0,255,1,167,167, + 167,2,153,227,172,1,192,192,192,1,153,227,172,1,167,167,167,1,0,0, + 255,1,167,167,167,1,0,0,255,1,153,227,172,4,128,128,128,1,255,0, + 255,4,128,128,128,1,192,192,192,1,128,128,128,1,153,227,172,2,0,0, + 255,1,153,227,172,3,192,192,192,1,153,227,172,1,0,0,255,1,153,227, + 172,3,0,0,255,1,153,227,172,3,128,128,128,1,255,0,255,4,128,128, + 128,1,192,192,192,1,128,128,128,1,153,227,172,1,167,167,167,1,0,0, + 255,1,167,167,167,1,153,227,172,2,192,192,192,1,153,227,172,1,0,0, + 255,1,167,167,167,2,153,227,172,1,0,0,255,1,153,227,172,3,128,128, + 128,1,255,0,255,4,128,128,128,1,192,192,192,1,128,128,128,1,153,227, + 172,2,0,0,255,1,153,227,172,3,192,192,192,1,0,0,255,1,153,227, + 172,5,0,0,255,1,153,227,172,2,128,128,128,1,255,0,255,4,128,128, + 128,1,192,192,192,1,128,128,128,1,153,227,172,1,167,167,167,3,153,227, + 172,2,192,192,192,1,153,227,172,9,128,128,128,1,255,0,255,4,128,128, + 128,1,192,192,192,1,128,128,128,1,153,227,172,6,192,192,192,1,153,227, + 172,9,128,128,128,1,255,0,255,4,128,128,128,1,192,192,192,1,128,128, + 128,1,153,227,172,6,192,192,192,1,153,227,172,9,128,128,128,1,255,0, + 255,4,128,128,128,20,255,0,255,98,0,0) + ); + +const + objdata_trxdataset: record size: integer; data: array[0..1290] of byte end = + (size: 1291; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,114,120, + 100,97,116,97,115,101,116,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,220,4,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0,0, + 0,168,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,255, + 25,153,227,172,1,8,4,8,1,0,0,0,7,0,4,0,1,0,0,0, + 3,0,4,0,1,0,0,0,1,8,4,0,1,0,0,0,2,0,4,0, + 1,0,0,0,2,153,227,172,1,255,0,255,2,153,227,172,1,0,0,0, + 1,197,198,197,1,0,4,0,1,205,206,205,1,197,194,197,1,213,202,205, + 1,205,198,197,2,189,190,189,1,205,206,205,1,205,198,205,1,205,202,205, + 1,180,206,205,1,180,206,197,1,197,190,189,1,205,194,197,1,189,202,197, + 1,180,206,205,1,189,194,197,1,0,0,0,1,153,227,172,1,255,0,255, + 2,153,227,172,1,0,4,0,1,0,12,8,1,0,0,0,2,16,0,0, + 3,8,0,0,1,0,0,0,1,0,4,0,1,0,0,0,3,0,4,0, + 1,16,4,0,1,16,8,0,1,8,0,0,1,0,0,0,1,0,4,0, + 2,153,227,172,1,255,0,255,2,153,227,172,1,0,0,0,1,197,206,197, + 1,0,0,0,1,153,227,172,6,205,202,205,1,153,227,172,9,0,0,0, + 1,153,227,172,1,255,0,255,2,153,227,172,1,0,0,0,1,238,246,246, + 1,0,4,0,1,153,227,172,6,197,198,197,1,153,227,172,2,0,0,0, + 5,153,227,172,2,0,4,0,1,153,227,172,1,255,0,255,2,153,227,172, + 1,0,0,0,1,197,206,205,1,0,4,0,1,153,227,172,1,41,105,41, + 1,0,0,0,1,41,105,41,1,0,0,0,1,153,227,172,1,197,194,189, + 1,153,227,172,1,0,0,0,1,16,28,222,5,0,0,0,1,153,227,172, + 1,0,0,0,1,153,227,172,1,255,0,255,2,153,227,172,1,0,8,0, + 1,238,246,246,1,0,12,0,1,153,227,172,6,205,194,189,1,153,227,172, + 1,0,0,0,1,16,28,222,1,153,227,172,3,16,28,222,1,0,0,0, + 1,153,227,172,1,0,0,0,1,153,227,172,1,255,0,255,2,153,227,172, + 1,0,0,0,1,197,206,197,1,0,0,0,1,153,227,172,1,41,105,41, + 1,0,0,0,2,41,105,41,1,153,227,172,1,205,190,189,1,153,227,172, + 5,16,28,222,2,0,0,0,1,153,227,172,1,0,8,0,1,153,227,172, + 1,255,0,255,2,153,227,172,1,0,0,0,1,255,255,255,1,8,4,0, + 1,153,227,172,4,180,230,190,1,153,227,172,1,213,198,197,1,153,227,172, + 4,16,28,222,2,0,0,0,1,153,227,172,2,0,0,0,1,153,227,172, + 1,255,0,255,2,153,227,172,1,8,8,8,1,197,198,197,1,0,0,0, + 1,153,227,172,1,41,105,41,1,0,0,0,3,153,227,172,1,213,202,197, + 1,153,227,172,3,16,28,222,2,0,0,0,1,153,227,172,3,0,0,0, + 1,153,227,172,1,255,0,255,2,153,227,172,1,0,0,0,1,255,255,255, + 1,8,4,0,1,153,227,172,3,180,230,190,1,153,227,172,2,205,194,197, + 1,153,227,172,3,16,28,222,1,0,0,0,1,153,227,172,4,0,0,0, + 1,153,227,172,1,255,0,255,2,153,227,172,1,0,8,8,1,197,198,197, + 1,0,0,0,1,153,227,172,1,41,105,41,1,0,0,0,2,41,105,41, + 1,153,227,172,1,205,198,197,1,153,227,172,3,16,28,222,1,0,0,0, + 1,153,227,172,4,0,0,0,1,153,227,172,1,255,0,255,2,153,227,172, + 1,0,0,0,1,255,250,246,1,8,4,0,1,153,227,172,6,197,190,189, + 1,153,227,172,9,0,0,0,1,153,227,172,1,255,0,255,2,153,227,172, + 1,0,0,0,1,205,206,205,1,0,0,0,1,153,227,172,6,205,202,205, + 1,153,227,172,3,16,28,222,1,0,0,0,1,153,227,172,4,8,4,0, + 1,153,227,172,1,255,0,255,2,153,227,172,1,0,0,255,4,153,227,172, + 1,0,0,0,1,153,227,172,1,0,0,255,1,153,227,172,1,0,0,0, + 1,153,227,172,1,0,0,255,1,153,227,172,1,16,28,222,1,0,0,0, + 1,153,227,172,1,8,4,0,1,0,0,0,2,8,4,0,1,153,227,172, + 1,255,0,255,2,153,227,172,1,0,0,255,1,153,227,172,3,0,0,255, + 1,153,227,172,2,0,0,255,1,153,227,172,3,0,0,255,1,153,227,172, + 9,255,0,255,2,153,227,172,1,0,0,255,1,153,227,172,3,0,0,255, + 1,153,227,172,3,0,0,255,1,153,227,172,1,0,0,255,1,153,227,172, + 10,255,0,255,2,153,227,172,1,0,0,255,4,153,227,172,5,0,0,255, + 1,153,227,172,11,255,0,255,2,153,227,172,1,0,0,255,1,153,227,172, + 3,0,0,255,1,153,227,172,3,0,0,255,1,153,227,172,1,0,0,255, + 1,153,227,172,10,255,0,255,2,153,227,172,1,0,0,255,1,153,227,172, + 3,0,0,255,1,153,227,172,3,0,0,255,1,153,227,172,1,0,0,255, + 1,153,227,172,10,255,0,255,2,153,227,172,1,0,0,255,1,153,227,172, + 3,0,0,255,1,153,227,172,2,0,0,255,1,153,227,172,3,0,0,255, + 1,153,227,172,9,255,0,255,2,153,227,172,1,0,0,255,1,153,227,172, + 3,0,0,255,1,153,227,172,2,0,0,255,1,153,227,172,3,0,0,255, + 1,153,227,172,9,255,0,255,25,0,0) + ); + +const + objdata_ttxdataset: record size: integer; data: array[0..1234] of byte end = + (size: 1235; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,116,120, + 100,97,116,97,115,101,116,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,164,4,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0,0, + 0,112,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,255, + 25,153,227,172,1,8,4,8,1,0,0,0,7,0,4,0,1,0,0,0, + 3,0,4,0,1,0,0,0,1,8,4,0,1,0,0,0,2,0,4,0, + 1,0,0,0,2,153,227,172,1,255,0,255,2,153,227,172,1,0,0,0, + 1,197,198,197,1,0,4,0,1,205,206,205,1,197,194,197,1,213,202,205, + 1,205,198,197,2,189,190,189,1,205,206,205,1,205,198,205,1,205,202,205, + 1,180,206,205,1,180,206,197,1,197,190,189,1,205,194,197,1,189,202,197, + 1,180,206,205,1,189,194,197,1,0,0,0,1,153,227,172,1,255,0,255, + 2,153,227,172,1,0,4,0,1,0,12,8,1,0,0,0,2,16,0,0, + 3,8,0,0,1,0,0,0,1,0,4,0,1,0,0,0,3,0,4,0, + 1,16,4,0,1,16,8,0,1,8,0,0,1,0,0,0,1,0,4,0, + 2,153,227,172,1,255,0,255,2,153,227,172,1,0,0,0,1,197,206,197, + 1,0,0,0,1,153,227,172,6,205,202,205,1,153,227,172,9,0,0,0, + 1,153,227,172,1,255,0,255,2,153,227,172,1,0,0,0,1,238,246,246, + 1,0,4,0,1,153,227,172,6,197,198,197,1,153,227,172,2,0,0,0, + 5,153,227,172,2,0,4,0,1,153,227,172,1,255,0,255,2,153,227,172, + 1,0,0,0,1,197,206,205,1,0,4,0,1,153,227,172,1,41,105,41, + 1,0,0,0,1,41,105,41,1,0,0,0,1,153,227,172,1,197,194,189, + 1,153,227,172,1,0,0,0,1,16,28,222,5,0,0,0,1,153,227,172, + 1,0,0,0,1,153,227,172,1,255,0,255,2,153,227,172,1,0,8,0, + 1,238,246,246,1,0,12,0,1,153,227,172,6,205,194,189,1,153,227,172, + 1,0,0,0,1,16,28,222,1,153,227,172,3,16,28,222,1,0,0,0, + 1,153,227,172,1,0,0,0,1,153,227,172,1,255,0,255,2,153,227,172, + 1,0,0,0,1,197,206,197,1,0,0,0,1,153,227,172,1,41,105,41, + 1,0,0,0,2,41,105,41,1,153,227,172,1,205,190,189,1,153,227,172, + 5,16,28,222,2,0,0,0,1,153,227,172,1,0,8,0,1,153,227,172, + 1,255,0,255,2,153,227,172,1,0,0,0,1,255,255,255,1,8,4,0, + 1,153,227,172,4,180,230,190,1,153,227,172,1,213,198,197,1,153,227,172, + 4,16,28,222,2,0,0,0,1,153,227,172,2,0,0,0,1,153,227,172, + 1,255,0,255,2,153,227,172,1,8,8,8,1,197,198,197,1,0,0,0, + 1,153,227,172,1,41,105,41,1,0,0,0,3,153,227,172,1,213,202,197, + 1,153,227,172,3,16,28,222,2,0,0,0,1,153,227,172,3,0,0,0, + 1,153,227,172,1,255,0,255,2,153,227,172,1,0,0,0,1,255,255,255, + 1,8,4,0,1,153,227,172,3,180,230,190,1,153,227,172,2,205,194,197, + 1,153,227,172,3,16,28,222,1,0,0,0,1,153,227,172,4,0,0,0, + 1,153,227,172,1,255,0,255,2,153,227,172,1,0,8,8,1,197,198,197, + 1,0,0,0,1,153,227,172,1,41,105,41,1,0,0,0,2,41,105,41, + 1,153,227,172,1,205,198,197,1,153,227,172,3,16,28,222,1,0,0,0, + 1,153,227,172,4,0,0,0,1,153,227,172,1,255,0,255,2,153,227,172, + 1,0,0,0,1,255,250,246,1,8,4,0,1,153,227,172,6,197,190,189, + 1,153,227,172,9,0,0,0,1,153,227,172,1,255,0,255,2,153,227,172, + 1,0,0,0,1,205,206,205,1,0,0,0,1,153,227,172,6,205,202,205, + 1,153,227,172,3,16,28,222,1,0,0,0,1,153,227,172,4,8,4,0, + 1,153,227,172,1,255,0,255,2,153,227,172,1,0,0,255,5,153,227,172, + 1,0,0,255,1,153,227,172,1,0,0,0,1,153,227,172,1,0,0,255, + 1,153,227,172,2,16,28,222,1,0,0,0,1,153,227,172,1,8,4,0, + 1,0,0,0,2,8,4,0,1,153,227,172,1,255,0,255,2,153,227,172, + 3,0,0,255,1,153,227,172,3,0,0,255,1,153,227,172,3,0,0,255, + 1,153,227,172,10,255,0,255,2,153,227,172,3,0,0,255,1,153,227,172, + 4,0,0,255,1,153,227,172,1,0,0,255,1,153,227,172,11,255,0,255, + 2,153,227,172,3,0,0,255,1,153,227,172,5,0,0,255,1,153,227,172, + 12,255,0,255,2,153,227,172,3,0,0,255,1,153,227,172,4,0,0,255, + 1,153,227,172,1,0,0,255,1,153,227,172,11,255,0,255,2,153,227,172, + 3,0,0,255,1,153,227,172,4,0,0,255,1,153,227,172,1,0,0,255, + 1,153,227,172,11,255,0,255,2,153,227,172,3,0,0,255,1,153,227,172, + 3,0,0,255,1,153,227,172,3,0,0,255,1,153,227,172,10,255,0,255, + 2,153,227,172,3,0,0,255,1,153,227,172,3,0,0,255,1,153,227,172, + 3,0,0,255,1,153,227,172,10,255,0,255,25,0,0) + ); + +const + objdata_tssl: record size: integer; data: array[0..584] of byte end = + (size: 585; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,4,116,115,115, + 108,12,98,105,116,109,97,112,46,105,109,97,103,101,10,32,2,0,0,0, + 0,0,0,0,0,0,0,24,0,0,0,24,0,0,0,236,1,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,192,192,192,25,0,0,0,1,192, + 192,192,2,0,0,0,2,192,192,192,2,0,0,0,2,192,192,192,2,0, + 0,0,2,192,192,192,2,0,0,0,2,192,192,192,2,0,0,0,2,192, + 192,192,48,0,0,0,1,192,192,192,2,0,0,0,1,192,192,192,20,0, + 0,0,1,192,192,192,2,0,0,0,1,192,192,192,68,0,0,0,1,192, + 192,192,5,0,0,0,3,192,192,192,4,0,0,0,3,192,192,192,3,0, + 0,0,1,192,192,192,4,0,0,0,1,192,192,192,2,0,0,0,1,192, + 192,192,1,0,0,0,1,192,192,192,3,0,0,0,1,192,192,192,2,0, + 0,0,1,192,192,192,3,0,0,0,1,192,192,192,2,0,0,0,1,192, + 192,192,7,0,0,0,1,192,192,192,1,0,0,0,1,192,192,192,6,0, + 0,0,1,192,192,192,6,0,0,0,1,192,192,192,10,0,0,0,3,192, + 192,192,4,0,0,0,3,192,192,192,3,0,0,0,1,192,192,192,4,0, + 0,0,1,192,192,192,8,0,0,0,1,192,192,192,6,0,0,0,1,192, + 192,192,2,0,0,0,1,192,192,192,4,0,0,0,1,192,192,192,2,0, + 0,0,1,192,192,192,1,0,0,0,1,192,192,192,3,0,0,0,1,192, + 192,192,2,0,0,0,1,192,192,192,3,0,0,0,1,192,192,192,2,0, + 0,0,1,192,192,192,7,0,0,0,1,192,192,192,1,0,0,0,1,192, + 192,192,3,0,0,0,1,192,192,192,2,0,0,0,1,192,192,192,3,0, + 0,0,1,192,192,192,2,0,0,0,1,192,192,192,10,0,0,0,3,192, + 192,192,4,0,0,0,3,192,192,192,3,0,0,0,4,192,192,192,1,0, + 0,0,1,192,192,192,23,0,0,0,1,192,192,192,2,0,0,0,1,192, + 192,192,23,0,0,0,1,192,192,192,44,0,0,0,1,192,192,192,23,0, + 0,0,1,192,192,192,2,0,0,0,1,192,192,192,23,0,0,0,1,192, + 192,192,2,0,0,0,2,192,192,192,2,0,0,0,2,192,192,192,2,0, + 0,0,2,192,192,192,2,0,0,0,2,192,192,192,2,0,0,0,2,192, + 192,192,26,0,0) + ); + +const + objdata_ttxsqlquery: record size: integer; data: array[0..1135] of byte end = + (size: 1136; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,116,120, + 115,113,108,113,117,101,114,121,12,98,105,116,109,97,112,46,105,109,97,103, + 101,10,64,4,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0, + 0,0,12,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,220,220, + 220,25,153,227,172,2,0,0,0,3,153,227,172,2,0,0,0,3,153,227, + 172,2,0,0,0,1,153,227,172,4,0,0,0,1,153,227,172,4,220,220, + 220,2,153,227,172,1,0,0,0,1,255,214,0,3,0,0,0,2,255,214, + 0,3,0,0,0,2,255,214,0,1,0,0,0,1,153,227,172,2,0,0, + 0,1,255,214,0,1,0,0,0,1,153,227,172,3,220,220,220,2,0,0, + 0,1,255,214,0,1,0,0,0,4,255,214,0,1,0,0,0,3,255,214, + 0,1,0,0,0,1,255,214,0,1,0,0,0,1,153,227,172,3,0,0, + 0,1,255,214,0,1,0,0,0,1,153,227,172,2,220,220,220,2,0,0, + 0,1,255,214,0,1,0,0,0,1,153,227,172,2,0,0,0,1,255,214, + 0,1,0,0,0,1,153,227,172,1,0,0,0,1,255,214,0,1,0,0, + 0,1,255,214,0,1,0,0,0,1,153,227,172,4,0,0,0,1,255,214, + 0,1,0,0,0,1,153,227,172,1,220,220,220,2,0,0,0,1,255,214, + 0,1,0,0,0,2,153,227,172,1,0,0,0,1,255,214,0,1,0,0, + 0,1,153,227,172,1,0,0,0,1,255,214,0,1,0,0,0,1,255,214, + 0,1,0,0,0,1,153,227,172,5,0,0,0,1,255,214,0,1,0,0, + 0,1,220,220,220,2,153,227,172,1,0,0,0,1,255,214,0,2,0,0, + 0,2,255,214,0,1,0,0,0,1,153,227,172,1,0,0,0,1,255,214, + 0,1,0,0,0,1,255,214,0,1,0,0,0,1,153,227,172,6,0,0, + 0,1,255,214,0,1,0,0,0,1,220,220,220,1,153,227,172,2,0,0, + 0,2,255,214,0,1,0,0,0,1,255,214,0,1,0,0,0,3,255,214, + 0,1,0,0,0,1,255,214,0,1,0,0,0,1,153,227,172,5,0,0, + 0,1,255,214,0,1,0,0,0,1,220,220,220,2,153,227,172,3,0,0, + 0,1,255,214,0,1,0,0,0,1,255,214,0,1,0,0,0,1,255,214, + 0,1,0,0,0,1,255,214,0,1,0,0,0,1,255,214,0,1,0,0, + 0,1,153,227,172,4,0,0,0,1,255,214,0,1,0,0,0,1,153,227, + 172,1,220,220,220,2,153,227,172,1,0,0,0,3,255,214,0,1,0,0, + 0,1,255,214,0,1,0,0,0,2,255,214,0,1,0,0,0,2,255,214, + 0,1,0,0,0,3,153,227,172,1,0,0,0,1,255,214,0,1,0,0, + 0,1,153,227,172,2,220,220,220,2,0,0,0,1,255,214,0,3,0,0, + 0,1,153,227,172,1,0,0,0,8,255,214,0,2,0,0,0,1,255,214, + 0,1,0,0,0,1,153,227,172,3,220,220,220,2,153,227,172,1,0,0, + 0,3,153,227,172,2,0,0,0,1,99,218,94,7,0,0,0,2,153,227, + 172,1,0,0,0,1,153,227,172,4,220,220,220,2,153,227,172,6,0,0, + 0,1,99,218,94,7,0,0,0,1,153,227,172,7,220,220,220,2,153,227, + 172,7,0,0,0,4,99,218,94,3,0,0,0,1,153,227,172,7,220,220, + 220,2,153,227,172,11,99,218,94,3,0,0,0,1,153,227,172,7,220,220, + 220,2,0,0,255,5,153,227,172,1,0,0,255,1,153,227,172,3,0,0, + 255,1,99,218,94,3,0,0,0,1,153,227,172,7,220,220,220,2,153,227, + 172,2,0,0,255,1,153,227,172,3,0,0,255,1,153,227,172,2,99,218, + 94,1,0,0,255,1,99,218,94,2,0,0,0,1,153,227,172,8,220,220, + 220,2,153,227,172,2,0,0,255,1,153,227,172,4,0,0,255,1,153,227, + 172,1,0,0,255,1,99,218,94,2,0,0,0,1,153,227,172,9,220,220, + 220,2,153,227,172,2,0,0,255,1,153,227,172,5,0,0,255,1,99,218, + 94,3,0,0,0,1,153,227,172,9,220,220,220,2,153,227,172,2,0,0, + 255,1,153,227,172,4,0,0,255,1,153,227,172,1,0,0,255,1,99,218, + 94,1,0,0,0,1,153,227,172,10,220,220,220,2,153,227,172,2,0,0, + 255,1,153,227,172,4,0,0,255,1,153,227,172,1,0,0,255,1,153,227, + 172,12,220,220,220,2,153,227,172,2,0,0,255,1,153,227,172,3,0,0, + 255,1,153,227,172,2,99,218,94,1,0,0,255,1,153,227,172,11,220,220, + 220,2,153,227,172,2,0,0,255,1,153,227,172,3,0,0,255,1,153,227, + 172,1,0,0,0,1,99,218,94,1,0,0,255,1,153,227,172,11,220,220, + 220,11,0,0,0,1,153,227,172,1,220,220,220,12,0,0) + ); + +initialization + registerobjectdata(@objdata_tsocketclient,tbitmapcomp,'tsocketclient'); + registerobjectdata(@objdata_tsocketserver,tbitmapcomp,'tsocketserver'); + registerobjectdata(@objdata_tsocketstdio,tbitmapcomp,'tsocketstdio'); + registerobjectdata(@objdata_tsocketserverstdio,tbitmapcomp,'tsocketserverstdio'); + registerobjectdata(@objdata_tpipeiochannel,tbitmapcomp,'tpipeiochannel'); + registerobjectdata(@objdata_tsocketstdiochannel,tbitmapcomp,'tsocketstdiochannel'); + registerobjectdata(@objdata_tsocketserveriochannel,tbitmapcomp,'tsocketserveriochannel'); + registerobjectdata(@objdata_tsocketclientiochannel,tbitmapcomp,'tsocketclientiochannel'); + registerobjectdata(@objdata_tformlink,tbitmapcomp,'tformlink'); + registerobjectdata(@objdata_tmodulelink,tbitmapcomp,'tmodulelink'); + registerobjectdata(@objdata_trxwidgetgrid,tbitmapcomp,'trxwidgetgrid'); + registerobjectdata(@objdata_ttxdatagrid,tbitmapcomp,'ttxdatagrid'); + registerobjectdata(@objdata_trxdataset,tbitmapcomp,'trxdataset'); + registerobjectdata(@objdata_ttxdataset,tbitmapcomp,'ttxdataset'); + registerobjectdata(@objdata_tssl,tbitmapcomp,'tssl'); + registerobjectdata(@objdata_ttxsqlquery,tbitmapcomp,'ttxsqlquery'); +end. diff --git a/mseide-msegui/lib/common/regcomponents/regkernel.pas b/mseide-msegui/lib/common/regcomponents/regkernel.pas new file mode 100644 index 0000000..6a49790 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regkernel.pas @@ -0,0 +1,908 @@ +{ MSEide Copyright (c) 1999-2018 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regkernel; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + typinfo,msepropertyeditors; + +implementation +uses + classes,mclasses,msethreadcomp,msebitmap,msetimer,msestatfile,mseact, + mseactions,mseshapes,msewidgets,mseindexlookupeditor,msecornermaskeditor, + msedesignintf,msemenus,msegui,msepipestream,sysutils,mseassistivehandler, + msegraphutils,regkernel_bmp,msegraphics,msestrings,msepostscriptprinter, + mseprinter,msetypes,msedatalist,msedatamodules,mseclasses,formdesigner, + mseapplication,mseglob,mseguiglob,mseskin,msedesigner,msemacros, + mseguithreadcomp,mseprocmonitorcomp,msefadepropedit,mseguiprocess, + msearrayprops,msesumlist,mserttistat,msestockobjects,regglob,msearrayutils, + msecryptohandler,msestringcontainer,mseformatstr; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + twidget1 = class(twidget); + tactivator1 = class(tactivator); + tskincontroller1 = class(tskincontroller); + tarrayelementeditor1 = class(tarrayelementeditor); + + temptysetpropertyeditor = class(tsetpropertyeditor) + public + procedure updatedefaultvalue; override; //implicit [] default + end; + + tactionpropertyeditor = class(tcomponentpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + end; + + tshortcutactionpropertyeditor = class(tclasselementeditor) + public + function getvalue: msestring; override; + end; + + tshortcutactionspropertyeditor = class(tpersistentarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + tskincolorarraypropertyeditor = class(tpersistentarraypropertyeditor) + protected + function itemgetvalue(const sender: tarrayelementeditor): msestring; + override; + end; + + tlevelarrayelementeditor = class(tarrayelementeditor) + public + function name: msestring; override; + end; + + tlevelarraypropertyeditor = class(tpersistentarraypropertyeditor) + protected + function getelementeditorclass: elementeditorclassty; override; + end; + + tneglevelarrayelementeditor = class(tarrayelementeditor) + public + function name: msestring; override; + end; + + tneglevelarraypropertyeditor = class(tpersistentarraypropertyeditor) + protected + function getelementeditorclass: elementeditorclassty; override; + end; + + tactionstatespropertyeditor = class(tsetpropertyeditor) + protected + function getdefaultstate: propertystatesty override; + function getinvisibleitems: tintegerset override; + end; + + tbounds_xeditor = class(tordinalpropertyeditor) + public + function getvalue: msestring; override; + procedure setvalue(const value: msestring); override; + end; + + tbounds_yeditor = class(tordinalpropertyeditor) + public + function getvalue: msestring; override; + procedure setvalue(const value: msestring); override; + end; + + tbounds_sizeeditor = class(tordinalpropertyeditor) + public + procedure setvalue(const value: msestring); override; + end; + + tframepropertyeditor = class(toptionalclasspropertyeditor) + protected + function dispname: msestring; override; + public + procedure edit; override; + end; + + tactivatorclientspropertyeditor = class(tconstarraypropertyeditor) + protected + procedure itemmoved(const source,dest: integer); override; + public + function subproperties: propertyeditorarty; override; + end; + + tskincontrollerextenderspropertyeditor = class(tconstarraypropertyeditor) + protected + procedure itemmoved(const source,dest: integer); override; + public + function subproperties: propertyeditorarty; override; + end; + + tsysshortcutelementeditor = class(tarrayelementeditor) + public + function name: msestring; override; + end; + + tsysshortcutspropertyeditor = class(tconstarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + function getelementeditorclass: elementeditorclassty; override; + public + end; + + tassistiveshortcutelementeditor = class(tarrayelementeditor) + public + function name: msestring; override; + end; + + tassistiveshortcutspropertyeditor = class(tconstarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + function getelementeditorclass: elementeditorclassty; override; + public + end; + + tfacelocalpropseditor = class(temptysetpropertyeditor) + protected + function getinvisibleitems: tintegerset; override; + end; + + tfacepropertyeditor = class(toptionalclasspropertyeditor) + protected + function dispname: msestring; override; + end; + + tfaceelementeditor = class(tclasselementeditor) + protected + function dispname: msestring; override; + end; + + tfacelistpropertyeditor = class(tpersistentarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + tindexlookupeditor = class(tmsestringpropertyeditor) + public + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + procedure edit(); override; + end; + + tcornermaskeditor = class(tmsestringpropertyeditor) + public + procedure setvalue(const value: msestring); override; + function getvalue: msestring; override; + procedure edit(); override; + end; + + tmacroseditor = class(tpersistentarraypropertyeditor) + protected + function itemgetvalue(const sender: tarrayelementeditor): msestring + override; + end; + + timagelistversioncounteditor = class(tordinalpropertyeditor) + public + procedure setvalue(const value: msestring); override; +end; + +const + datamoduleintf: designmoduleintfty = + (createfunc: {$ifdef FPC}@{$endif}createmsedatamodule; + initnewcomponent: nil; getscale: nil; sourcetoform: nil; + ); + +procedure Register; +begin + registerclass(tmsedatamodule); + registercomponents('Gui',[tmainmenu,tpopupmenu, + tfacecomp,tfacelist,tframecomp,tfontcomp,tskincontroller, +// tskinextender, + tbitmapcomp,timagelist,tshortcutcontroller,thelpcontroller, + tguiprocess, + taction,tguithreadcomp,tassistivehandler, + tassistivewidgetitem]); + registercomponenttabhints(['Gui'],['Non visual components with GUI dependence']); + + registercomponents('NoGui',[tstatfile,trttistat,tnoguiaction,tactivator, + ttimer,tanimtimer,tanimitemcomp,tthreadcomp,tpipereadercomp, + tprocessmonitor, + tstringcontainer,tkeystringcontainer]); + registercomponenttabhints(['NoGui'],['Components without GUI dependence']); + + registerpropertyeditor(typeinfo(fontlocalpropsty),nil,'', + temptysetpropertyeditor); + registerpropertyeditor(typeinfo(framelocalpropsty),nil,'', + temptysetpropertyeditor); + registerpropertyeditor(typeinfo(framelocalprops1ty),nil,'', + temptysetpropertyeditor); + registerpropertyeditor(typeinfo(facelocalpropsty),nil,'', + tfacelocalpropseditor); + + registerpropertyeditor(typeinfo(tskincolors),nil,'', + tskincolorarraypropertyeditor); + registerpropertyeditor(typeinfo(tstatfile),tstatfile,'', + tlinkcomponentpropertyeditor); + + registerpropertyeditor(typeinfo(tcustomframe),nil,'',tframepropertyeditor); + registerpropertyeditor(typeinfo(tcustomface),nil,'',tfacepropertyeditor); + + registerpropertyeditor(typeinfo(tfacearrayprop),nil,'',tfacelistpropertyeditor); + registerpropertyeditor(typeinfo(tcustomaction),nil,'',tactionpropertyeditor); + registerpropertyeditor(typeinfo(tshortcutactions),nil,'', + tshortcutactionspropertyeditor); + registerpropertyeditor(typeinfo(tcolorarrayprop),tcustomface,'fade_color', + tfacefadecoloreditor); + registerpropertyeditor(typeinfo(trealarrayprop),tcustomface,'fade_pos', + tfacefadeposeditor); + registerpropertyeditor(typeinfo(tcolorarrayprop),tfacetemplate,'fade_color', + tfacetemplatefadecoloreditor); + registerpropertyeditor(typeinfo(trealarrayprop),tfacetemplate,'fade_pos', + tfacetemplatefadeposeditor); + + registerpropertyeditor(typeinfo(tcolorarrayprop),tcustomface,'fade_opacolor', + tfacefadeopacoloreditor); + registerpropertyeditor(typeinfo(trealarrayprop),tcustomface,'fade_opapos', + tfacefadeopaposeditor); + registerpropertyeditor(typeinfo(tcolorarrayprop),tfacetemplate,'fade_opacolor', + tfacetemplatefadeopacoloreditor); + registerpropertyeditor(typeinfo(trealarrayprop),tfacetemplate,'fade_opapos', + tfacetemplatefadeopaposeditor); + + registerpropertyeditor(typeinfo(int32),timagelist,'versioncount', + timagelistversioncounteditor); + registerpropertyeditor(typeinfo(msestring),timagelist,'cornermask_topleft', + tcornermaskeditor); + registerpropertyeditor(typeinfo(msestring),timagelist,'cornermask_bottomleft', + tcornermaskeditor); + registerpropertyeditor(typeinfo(msestring),timagelist,'cornermask_bottomright', + tcornermaskeditor); + registerpropertyeditor(typeinfo(msestring),timagelist,'cornermask_topright', + tcornermaskeditor); + registerpropertyeditor(typeinfo(msestring),timagelist,'indexlookup', + tindexlookupeditor); + registerpropertyeditor(typeinfo(msestring),tfacelist,'indexlookup', + tindexlookupeditor); + + registerpropertyeditor(typeinfo(tsumdownarrayprop),nil,'', + tlevelarraypropertyeditor); + registerpropertyeditor(typeinfo(tsumuparrayprop),nil,'', + tneglevelarraypropertyeditor); + registerpropertyeditor(typeinfo(tsysshortcuts),nil,'', + tsysshortcutspropertyeditor); + registerpropertyeditor(typeinfo(tassistiveshortcuts),nil,'', + tassistiveshortcutspropertyeditor); + registerpropertyeditor(typeinfo(string),tfont,'name',tfontnamepropertyeditor); + registerpropertyeditor(typeinfo(actionstatesty),nil,'', + tactionstatespropertyeditor); + registerpropertyeditor(typeinfo(shortcutty),nil,'',tshortcutpropertyeditor); + registerpropertyeditor(typeinfo(imagenrty),nil,'',timagenrpropertyeditor); + registerpropertyeditor(typeinfo(facenrty),nil,'',tordinalpropertyeditor); + registerpropertyeditor(typeinfo(tcollection),nil,'',tcollectionpropertyeditor); + registerpropertyeditor(typeinfo(tmenuitems),nil,'',tmenuarraypropertyeditor); + registerpropertyeditor(typeinfo(tcustomframe),nil,'',tframepropertyeditor); + registerpropertyeditor(typeinfo(tcustomface),nil,'', + toptionalclasspropertyeditor); + registerpropertyeditor(typeinfo(toptionalfont),nil,'', + toptionalclasspropertyeditor); + registerpropertyeditor(typeinfo(tparentfont),nil,'', + tparentfontpropertyeditor); + registerpropertyeditor(typeinfo(integer),twidget,'bounds_x',tbounds_xeditor); + registerpropertyeditor(typeinfo(integer),twidget,'bounds_y',tbounds_yeditor); + registerpropertyeditor(typeinfo(integer),twidget,'bounds_cy', + tbounds_sizeeditor); + registerpropertyeditor(typeinfo(integer),twidget,'bounds_cx', + tbounds_sizeeditor); + registerpropertyeditor(typeinfo(integer),twidget,'bounds_cymin', + tbounds_sizeeditor); + registerpropertyeditor(typeinfo(integer),twidget,'bounds_cxmin', + tbounds_sizeeditor); + registerpropertyeditor(typeinfo(integer),twidget,'bounds_cymax', + tbounds_sizeeditor); + registerpropertyeditor(typeinfo(integer),twidget,'bounds_cxmax', + tbounds_sizeeditor); + registerpropertyeditor(typeinfo(tfacetemplate),tcustommenu,'facetemplate', + toptionalclasspropertyeditor); + registerpropertyeditor(typeinfo(tfacetemplate),tmainmenu,'popupfacetemplate', + toptionalclasspropertyeditor); + registerpropertyeditor(typeinfo(integer),tactivator,'clients', + tactivatorclientspropertyeditor); + registerpropertyeditor(typeinfo(integer),tskincontroller,'extenders', + tskincontrollerextenderspropertyeditor); + registerpropertyeditor(typeinfo(stockglyphty),nil,'', + tstockglypheditor); + registerpropertyeditor(typeinfo(tmacroproperty),nil,'', + tmacroseditor); + + registerunitgroup(['msestatfile'],['msestat']); + + registerdesignmoduleclass(tmsedatamodule,@datamoduleintf); +end; + +{ tactionpropertyeditor } + +function tactionpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_volatile]; +end; + +{ tactionstatespropertyeditor } + +function tactionstatespropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_volatile,ps_refresh]; +end; + +function tactionstatespropertyeditor.getinvisibleitems: tintegerset; +begin + result:= invisibleactionstates; +end; + +{ tbounds_xeditor } + +function tbounds_xeditor.getvalue: msestring; +begin + if fprops[0].instance = fmodule then begin + result:= inttostrmse(fdesigner.getmodulex(fmodule)); +// result:= inttostr(twidget(fprops[0].instance).screenpos.x); + end + else begin + result:= inherited getvalue; + end; +end; + +procedure tbounds_xeditor.setvalue(const value: msestring); +begin + if fprops[0].instance = fmodule then begin + fdesigner.setmodulex(fmodule,strtoint(value)); + end + else begin + inherited; + end; +end; + +{ tbounds_yeditor } + +function tbounds_yeditor.getvalue: msestring; +begin + if fprops[0].instance = fmodule then begin + result:= inttostrmse(fdesigner.getmoduley(fmodule)); +// result:= inttostr(twidget(fprops[0].instance).screenpos.y); + end + else begin + result:= inherited getvalue; + end; +end; + +procedure tbounds_yeditor.setvalue(const value: msestring); +begin + if fprops[0].instance = fmodule then begin + fdesigner.setmoduley(fmodule,strtoint(value)); + end + else begin + inherited; + end; +end; + +{ tbounds_sizeeditor } + +procedure tbounds_sizeeditor.setvalue(const value: msestring); +begin + inherited; + fdesigner.modulesizechanged(fmodule); +end; + +{ tframepropertyeditor } + +function tframepropertyeditor.dispname: msestring; +begin + with tcustomframe(getpointervalue) do begin + if template <> nil then begin + result:= msestring(template.name); + end + else begin + result:= inherited dispname; + end; + end; +end; + +procedure tframepropertyeditor.edit; +begin + inherited; + if fprops[0].instance is twidget then begin + twidget1(fprops[0].instance).clientrectchanged; + end; +end; + +{ tactivatorclientspropertyeditor } + +function tactivatorclientspropertyeditor.subproperties: propertyeditorarty; +var + int1: integer; + ar1: stringarty; +begin + with tactivator1(fprops[0].instance) do begin + updateorder; + fclientnames:= nil; + ar1:= getclientnames; + setlength(result,length(fclients)); + for int1:= 0 to high(result) do begin + result[int1]:= tconstelementeditor.create(msestring(ar1[int1]), + int1,self,geteditorclass,fdesigner,fobjectinspector,fprops,ftypeinfo); + end; + end; +end; + +procedure tactivatorclientspropertyeditor.itemmoved(const source: integer; + const dest: integer); +begin + moveitem(tactivator1(fprops[0].instance).fclients,source,dest); + modified; +end; + +{ tskincontrollerextenderspropertyeditor } + +function tskincontrollerextenderspropertyeditor.subproperties: propertyeditorarty; +var + int1: integer; + ar1: stringarty; +begin + with tskincontroller1(fprops[0].instance) do begin + updateorder; + fextendernames:= nil; + ar1:= getextendernames; + setlength(result,length(fextenders)); + for int1:= 0 to high(result) do begin + result[int1]:= tconstelementeditor.create(msestring(ar1[int1]), + int1,self,geteditorclass,fdesigner,fobjectinspector,fprops,ftypeinfo); + end; + end; +end; + +procedure tskincontrollerextenderspropertyeditor.itemmoved(const source: integer; + const dest: integer); +begin + moveitem(pointerarty(tskincontroller1(fprops[0].instance).fextenders), + source,dest); + modified; +end; + +{ tsysshortcutelementeditor } + +function tsysshortcutelementeditor.name: msestring; +begin + result:= msestring(getenumname(typeinfo(sysshortcutty),findex)); +end; + +{ tsysshortcutspropertyeditor } + +function tsysshortcutspropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tshortcutpropertyeditor; +end; + +function tsysshortcutspropertyeditor.getelementeditorclass: elementeditorclassty; +begin + result:= tsysshortcutelementeditor; +end; + +{ tassistiveshortcutelementeditor } + +function tassistiveshortcutelementeditor.name: msestring; +begin + result:= msestring(getenumname(typeinfo(assistiveshortcutty),findex)); +end; + +{ tassistiveshortcutspropertyeditor } + +function tassistiveshortcutspropertyeditor.geteditorclass(): + propertyeditorclassty; +begin + result:= tshortcutarpropertyeditor; +end; + +function tassistiveshortcutspropertyeditor.getelementeditorclass(): + elementeditorclassty; +begin + result:= tassistiveshortcutelementeditor; +end; + +{ tshortcutactionpropertyeditor } + +function tshortcutactionpropertyeditor.getvalue: msestring; +var + item1: tshortcutaction; +begin + item1:= tshortcutaction(getpointervalue); + if item1.action = nil then begin + result:= '<--->'; + end + else begin + result:= '<'+getcomponentpropname(item1.action)+'>'; + { + result:= '<'; + if item1.action.owner <> module then begin + result:= result+module.name+'.'; + end; + result:= result+designer.getcomponentdispname(item1.action)+'>'; + } + end; + result:= result + '<' + item1.dispname + '>'; +end; + +{ tshortcutactionspropertyeditor } + +function tshortcutactionspropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tshortcutactionpropertyeditor; +end; + +{ tlevelarraypropertyeditor } + +function tlevelarraypropertyeditor.getelementeditorclass: elementeditorclassty; +begin + result:= tlevelarrayelementeditor; +end; + +{ tlevelarrayelementeditor } + +function tlevelarrayelementeditor.name: msestring; +begin + result:= 'Level ' + inttostrmse(findex+1); +end; + +{ tneglevelarraypropertyeditor } + +function tneglevelarraypropertyeditor.getelementeditorclass: elementeditorclassty; +begin + result:= tneglevelarrayelementeditor; +end; + +{ tneglevelarrayelementeditor } + +function tneglevelarrayelementeditor.name: msestring; +begin + result:= 'Level ' + inttostrmse(-(findex+1)); +end; + +(* +{ tactionshortcutspropertyeditor } + +constructor tactionshortcutspropertyeditor.create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypeinfo: ptypeinfo); +begin + fsc1:= aprops[0].propinfo^.name = 'shortcut1'; + inherited; +end; + +procedure tactionshortcutspropertyeditor.setvalue(const value: msestring); +var + ar1: msestringarty; + ar2: shortcutarty; + int1: integer; +begin + ar1:= splitstring(value,widechar(' ')); + if high(ar1) > 0 then begin + setlength(ar2,length(ar1)); + for int1:= 0 to high(ar1) do begin + ar2[int1]:= texttovalue(ar1[int1]); + end; + for int1:= 0 to high(fprops) do begin + if fprops[int1].instance is taction then begin + with taction(fprops[int1].instance) do begin + if fsc1 then begin + shortcuts1:= ar2; + end + else begin + shortcuts:= ar2; + end; + end; + end + else begin + setordvalue(int1,0); + end; + end; + end + else begin + inherited; + end; +end; + +function tactionshortcutspropertyeditor.getvalue: msestring; +var + ar1: shortcutarty; + int1: integer; +begin + result:= ''; + with taction(fprops[0].instance) do begin + if self.fsc1 then begin + ar1:= shortcuts1; + end + else begin + ar1:= shortcuts; + end; + end; + result:= ''; + for int1:= 0 to high(ar1) do begin + result:= result + getvaluetext(ar1[int1]) + ' '; + end; + if result <> '' then begin + setlength(result,length(result)-1); + end; +end; + +{ tshortcutactionitempropertyeditor } + +constructor tshortcutactionitempropertyeditor.create(const adesigner: idesigner; + const amodule: tmsecomponent; const acomponent: tcomponent; + const aobjectinspector: iobjectinspector; + const aprops: propinstancearty; atypeinfo: ptypeinfo); +begin + fsc1:= aprops[0].propinfo^.name = 'shortcut1default'; + inherited; +end; + +procedure tshortcutactionitempropertyeditor.setvalue(const value: msestring); +var + ar1: msestringarty; + ar2: shortcutarty; + int1: integer; +begin + ar1:= splitstring(value,widechar(' ')); + if high(ar1) > 0 then begin + setlength(ar2,length(ar1)); + for int1:= 0 to high(ar1) do begin + ar2[int1]:= texttovalue(ar1[int1]); + end; + for int1:= 0 to high(fprops) do begin + if fprops[int1].instance is tshortcutaction then begin + with tshortcutaction(fprops[int1].instance) do begin + if fsc1 then begin + shortcuts1default:= ar2; + end + else begin + shortcutsdefault:= ar2; + end; + end; + end + else begin + setordvalue(int1,0); + end; + end; + end + else begin + inherited; + end; +end; + +function tshortcutactionitempropertyeditor.getvalue: msestring; +var + ar1: shortcutarty; + int1: integer; +begin + result:= ''; + with tshortcutaction(fprops[0].instance) do begin + if self.fsc1 then begin + ar1:= shortcuts1default; + end + else begin + ar1:= shortcutsdefault; + end; + end; + result:= ''; + for int1:= 0 to high(ar1) do begin + result:= result + getvaluetext(ar1[int1]) + ' '; + end; + if result <> '' then begin + setlength(result,length(result)-1); + end; +end; +*) +{ tfacelocalpropseditor } + +function tfacelocalpropseditor.getinvisibleitems: tintegerset; +begin + result:= invisiblefacelocalprops; +end; + +{ tfaceeditor } + +function tfacepropertyeditor.dispname: msestring; +begin + with tcustomface(getpointervalue) do begin + if template <> nil then begin + result:= msestring(template.name); + end + else begin + result:= inherited dispname; + end; + end; +end; + +{ tfaceelementeditor } + +function tfaceelementeditor.dispname: msestring; +begin + with tcustomface(getpointervalue) do begin + if template <> nil then begin + result:= msestring(template.name); + end + else begin + result:= inherited dispname; + end; + end; +end; + +{ tfacelistpropertyeditor } + +function tfacelistpropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tfaceelementeditor; +end; + +{ temptysetpropertyeditor } + +procedure temptysetpropertyeditor.updatedefaultvalue; +begin + if getordvalue <> 0 then begin + include(fstate,ps_modified); + end + else begin + exclude(fstate,ps_modified); + end; +end; + +{ tskincolorarraypropertyeditor } + +function tskincolorarraypropertyeditor.itemgetvalue( + const sender: tarrayelementeditor): msestring; +begin + result:= msestring('<'+colortostring(tskincolor( + tarrayelementeditor1(sender).getpointervalue(0)).color) + '>'); +end; + +{ tindexlookupeditor } + +procedure tindexlookupeditor.setvalue(const value: msestring); +begin + if (value = '') and + askyesno('Do you want to delete the lookup list?') then begin + inherited setvalue(''); + end + else begin + inherited setvalue(getmsestringvalue(0)); + end; +end; + +function tindexlookupeditor.getvalue: msestring; +var + mstr1: msestring; +begin + mstr1:= getmsestringvalue(0,true); + if mstr1 = '' then begin + result:= ''; + end + else begin + result:= '<'+inttostrmse(length(mstr1))+'>'; + end; +end; + +procedure tindexlookupeditor.edit(); +var + mstr1: msestring; + imagelist: timagelist; + facelist: tfacelist; +begin + mstr1:= getmsestringvalue(0,true); + imagelist:= nil; + facelist:= nil; + if fcomponent is timagelist then begin + pointer(imagelist):= fcomponent; + end; + if fcomponent is tfacelist then begin + pointer(facelist):= fcomponent; + end; + if editlookupindex(mstr1,imagelist,facelist) then begin + setmsestringvalue(mstr1,true); + end; +end; + +{ tcornermaskeditor } + +procedure tcornermaskeditor.setvalue(const value: msestring); +begin + if (value = '') and + askyesno('Do you want to delete the corner mask?') then begin + inherited setvalue(''); + end + else begin + inherited setvalue(getmsestringvalue(0)); + end; +end; + +function tcornermaskeditor.getvalue: msestring; +var + mstr1: msestring; +begin + mstr1:= getmsestringvalue(0,true); + if mstr1 = '' then begin + result:= ''; + end + else begin + result:= '<'+inttostrmse(length(mstr1))+'>'; + end; +end; + +procedure tcornermaskeditor.edit(); +var + mstr1: msestring; +begin + mstr1:= getmsestringvalue(0,true); + if editcornermask(mstr1) then begin + setmsestringvalue(mstr1,true); + end; +end; + +{ tmacroseditor } + +function tmacroseditor.itemgetvalue( + const sender: tarrayelementeditor): msestring; +begin + with tstringlistmacroitem( + tarrayelementeditor1(sender).getpointervalue) do begin + result:= '<'+name+'>'; + end; +end; + +{ timagelistversioncounteditor } + +procedure timagelistversioncounteditor.setvalue(const value: msestring); +var + int1: integer; + va: integer; +begin + va:= strtoint(value); + if va < 0 then begin + va:= 0; + end; + int1:= timagelist(fcomponent).versioncount; + if not wantpropertydelete(va,int1-1) then begin + exit; + end; + inherited; +end; + +initialization + register; +end. diff --git a/mseide-msegui/lib/common/regcomponents/regkernel_bmp.pas b/mseide-msegui/lib/common/regcomponents/regkernel_bmp.pas new file mode 100644 index 0000000..c19a1cd --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regkernel_bmp.pas @@ -0,0 +1,3769 @@ +unit regkernel_bmp; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msebitmap; + +const + objdata_taction: record size: integer; data: array[0..467] of byte end = + (size: 468; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,7,116,97,99, + 116,105,111,110,12,98,105,116,109,97,112,46,105,109,97,103,101,10,168,1, + 0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0,0,0,116,1, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,255,87,0,0, + 255,2,255,0,255,20,0,0,255,2,255,0,255,19,0,0,255,3,255,0, + 255,19,0,0,255,2,255,0,255,20,0,0,255,2,255,0,255,23,0,0, + 255,2,255,0,255,24,0,0,255,2,255,0,255,24,0,0,255,2,255,0, + 255,24,0,0,255,2,255,0,255,21,0,0,255,2,255,0,255,21,0,0, + 255,1,255,0,255,17,0,0,255,1,255,0,255,3,0,0,255,2,255,0, + 255,1,0,0,0,2,255,0,255,2,0,0,0,1,255,0,255,2,0,0, + 0,1,255,0,255,1,0,0,0,1,255,0,255,7,0,0,255,1,255,0, + 255,2,0,0,255,1,255,0,255,2,0,0,0,1,255,0,255,2,0,0, + 0,1,255,0,255,1,0,0,0,1,255,0,255,2,0,0,0,1,255,0, + 255,1,0,0,0,1,255,0,255,6,0,0,255,1,255,0,255,1,0,0, + 255,2,255,0,255,3,0,0,0,1,255,0,255,4,0,0,0,1,255,0, + 255,2,0,0,0,1,255,0,255,1,0,0,0,1,255,0,255,6,0,0, + 255,2,255,0,255,1,0,0,255,3,255,0,255,1,0,0,0,1,255,0, + 255,1,0,0,0,2,255,0,255,1,0,0,0,1,255,0,255,2,0,0, + 0,1,255,0,255,1,0,0,0,1,255,0,255,6,0,0,255,3,255,0, + 255,4,0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,1,0,0, + 0,1,255,0,255,2,0,0,0,1,255,0,255,1,0,0,0,1,255,0, + 255,14,0,0,0,2,255,0,255,3,0,0,0,2,255,0,255,2,0,0, + 0,1,255,0,255,98,0,0) + ); + +const + objdata_timagelist: record size: integer; data: array[0..1821] of byte end = + (size: 1822; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,105,109, + 97,103,101,108,105,115,116,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,168,6,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,32,5,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,208,208,208,4,124,123,123,1,123,123,123,19, + 208,208,208,4,125,124,123,1,251,192,146,1,255,194,147,10,255,194,146,7, + 125,124,123,1,208,208,208,2,124,124,123,1,123,123,123,19,251,195,151,1, + 125,124,123,1,208,208,208,2,125,124,124,1,251,192,146,1,255,194,147,10, + 255,194,146,7,127,125,124,1,251,199,158,1,125,124,124,1,124,123,123,1, + 123,123,123,19,251,195,151,1,127,125,124,1,251,202,164,1,125,124,124,1, + 125,124,123,1,251,192,146,1,255,194,147,10,255,194,146,7,127,125,124,1, + 251,199,158,1,127,126,125,1,251,205,170,1,125,124,124,1,125,124,123,1, + 251,195,152,1,242,199,158,1,132,216,202,1,25,235,245,1,54,230,234,1, + 168,211,187,1,255,197,153,9,255,197,152,3,127,125,124,1,251,201,164,1, + 127,126,125,1,251,208,175,1,125,124,124,1,125,124,123,1,251,199,158,1, + 136,218,203,1,29,239,250,1,121,249,254,1,100,247,254,1,5,236,252,1, + 210,208,176,1,255,201,159,11,127,125,124,1,251,205,169,1,127,126,125,1, + 251,211,181,1,125,124,124,2,251,201,164,1,30,234,245,1,117,249,254,1, + 183,255,255,2,61,242,252,1,109,224,216,1,255,204,165,11,127,125,124,1, + 251,208,175,1,127,126,125,1,82,169,60,1,121,123,121,1,125,124,124,1, + 251,205,169,1,64,231,235,1,92,246,254,1,183,255,255,2,37,238,250,1, + 145,220,206,1,255,208,171,11,127,125,124,1,251,211,181,1,124,125,123,1, + 7,187,4,1,121,124,121,1,125,124,124,1,251,208,175,1,180,219,199,1, + 3,237,252,1,54,241,252,1,34,238,250,1,16,236,249,1,240,213,182,1, + 255,211,177,11,126,125,124,1,73,172,54,1,120,124,120,1,7,184,4,1, + 121,124,121,1,125,124,124,1,251,212,181,1,255,215,183,1,220,218,193,1, + 118,226,221,1,150,224,212,1,242,216,187,1,255,215,183,7,255,214,183,5, + 123,125,122,1,7,187,4,1,120,125,120,1,7,181,4,1,121,123,121,1, + 125,124,124,1,251,215,187,1,255,218,189,15,235,211,175,1,70,173,51,1, + 120,124,120,1,7,184,4,1,120,124,120,1,8,178,4,1,121,123,121,1, + 125,124,124,1,251,219,193,1,255,222,195,2,255,221,195,12,158,194,120,1, + 16,176,11,1,3,189,0,1,120,124,120,1,7,181,4,1,120,124,120,1, + 8,174,4,1,121,123,121,1,125,124,124,1,251,222,199,1,255,225,201,12, + 207,209,162,1,58,184,45,1,3,192,2,1,2,194,0,1,3,186,0,1, + 120,124,120,1,8,178,4,1,120,124,120,1,8,172,4,1,121,123,121,1, + 125,124,124,1,251,225,205,1,255,228,208,2,255,228,207,8,250,226,203,1, + 100,186,77,1,10,194,6,1,1,207,1,1,2,199,0,1,3,191,0,1, + 3,183,0,1,120,124,120,1,8,174,4,1,120,124,120,1,9,170,4,1, + 121,123,121,1,125,124,124,1,251,229,211,1,255,232,214,6,255,232,213,3, + 252,231,210,1,84,180,55,1,0,218,1,1,1,212,1,1,2,204,1,1, + 2,196,0,1,3,188,0,1,4,180,0,1,120,124,120,1,8,171,4,1, + 120,124,120,1,9,170,4,1,121,123,121,1,125,122,122,1,250,131,72,1, + 254,137,81,1,254,143,93,1,254,150,104,1,254,156,115,1,253,159,122,1, + 250,148,104,1,248,137,86,1,245,126,68,1,243,116,50,1,237,103,33,1, + 68,150,11,1,1,217,1,1,1,209,1,1,2,201,1,1,3,193,0,1, + 3,185,0,1,4,176,0,1,120,124,120,1,9,169,4,1,120,124,120,1, + 9,170,4,1,121,123,121,1,125,122,122,1,251,152,76,1,255,161,87,1, + 255,168,101,1,255,176,114,1,255,183,128,1,255,191,142,1,252,179,122,1, + 249,166,101,1,246,153,79,1,243,140,58,1,240,127,36,1,212,113,15,1, + 40,166,5,1,1,206,1,1,2,197,0,1,3,189,0,1,4,181,0,1, + 4,173,0,1,120,124,120,1,9,169,4,1,120,124,120,1,9,170,4,1, + 121,123,121,1,125,122,122,1,251,151,73,1,255,159,84,1,255,167,98,1, + 255,174,111,1,255,182,125,1,255,189,139,1,252,182,127,1,249,169,106,1, + 246,156,84,1,243,143,63,1,240,130,41,1,237,117,20,1,171,114,1,1, + 19,179,2,1,2,194,0,1,3,186,0,1,4,178,0,1,5,171,0,1, + 120,124,120,1,9,169,4,1,121,124,121,1,123,123,123,2,125,122,122,1, + 251,149,70,1,255,158,81,1,255,165,95,1,255,173,109,1,255,180,122,1, + 255,188,136,1,253,185,132,1,250,172,110,1,247,159,89,1,244,146,67,1, + 241,133,46,1,238,120,24,1,235,107,3,1,140,121,1,1,20,170,1,1, + 3,183,0,1,4,175,0,1,5,171,0,1,120,124,120,1,9,169,4,1, + 121,124,121,1,128,128,128,1,208,208,208,1,125,122,122,1,251,147,67,1, + 255,156,78,1,255,163,92,1,255,171,106,1,255,178,119,1,255,186,133,1, + 254,188,137,1,251,175,115,1,248,162,94,1,245,149,72,1,242,136,51,1, + 239,123,29,1,236,109,8,1,235,105,0,1,165,114,1,1,27,153,6,1, + 4,172,0,1,5,171,0,1,121,123,121,1,123,123,123,2,128,128,128,1, + 208,208,208,1,125,122,122,1,251,146,64,1,255,154,75,1,255,162,89,1, + 255,169,103,1,255,177,116,1,255,184,130,1,254,191,141,1,251,178,120,1, + 248,165,98,1,245,152,77,1,242,138,55,1,239,125,34,1,236,112,12,1, + 235,105,0,2,192,109,0,1,35,139,2,1,5,171,0,1,121,123,121,1, + 123,123,123,1,208,208,208,3,125,122,122,1,123,123,123,20,208,208,208,3, + 80,1,0,0,0,0,0,4,250,250,250,1,255,255,255,19,0,0,0,4, + 251,251,251,1,255,255,255,18,252,252,252,1,0,0,0,2,250,250,250,1, + 255,255,255,20,252,252,252,1,0,0,0,2,251,251,251,1,255,255,255,20, + 252,252,252,1,250,250,250,1,255,255,255,22,252,252,252,1,251,251,251,1, + 255,255,255,22,252,252,252,1,251,251,251,1,255,255,255,22,252,252,252,1, + 251,251,251,1,255,255,255,22,252,252,252,1,251,251,251,1,255,255,255,21, + 225,225,225,1,253,253,253,1,251,251,251,1,255,255,255,22,253,253,253,1, + 251,251,251,1,255,255,255,19,254,254,254,1,255,255,255,2,253,253,253,1, + 251,251,251,1,255,255,255,22,253,253,253,1,251,251,251,1,255,255,255,22, + 253,253,253,1,251,251,251,1,255,255,255,22,253,253,253,1,251,251,251,1, + 255,255,255,22,253,253,253,1,251,251,251,1,255,255,255,22,253,253,253,1, + 252,252,252,1,255,255,255,22,253,253,253,2,255,255,255,22,253,253,253,1, + 252,252,252,1,255,255,255,22,253,253,253,1,252,252,252,1,255,255,255,23, + 252,252,252,1,255,255,255,20,253,253,253,1,8,8,8,1,0,0,0,1, + 252,252,252,1,255,255,255,21,8,8,8,1,0,0,0,1,252,252,252,1, + 255,255,255,16,240,240,240,1,255,255,255,1,253,253,253,1,8,8,8,1, + 0,0,0,3,251,251,251,1,255,255,255,19,8,8,8,1,0,0,0,3, + 0,0) + ); + +const + objdata_tstatfile: record size: integer; data: array[0..2860] of byte end = + (size: 2861; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,115,116, + 97,116,102,105,108,101,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,184,10,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,232,8,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,3,4,3,1,5,7,5,1,17,22,17,1,177, + 229,178,1,180,230,180,1,113,143,113,1,6,7,6,2,49,61,50,1,192, + 234,194,1,195,234,196,1,71,85,72,1,6,7,6,2,98,114,99,1,207, + 238,209,1,209,239,212,1,33,37,33,1,7,7,7,2,184,203,188,1,222, + 242,225,1,212,230,216,1,3,4,4,1,113,151,113,1,172,228,173,1,175, + 229,175,1,177,229,178,1,180,230,180,1,182,231,183,1,185,232,186,1,187, + 232,188,1,190,233,191,1,192,234,194,1,195,234,196,1,197,235,199,1,199, + 236,201,1,202,236,204,1,204,237,207,1,207,238,209,1,209,239,212,1,212, + 239,215,1,214,240,217,1,217,241,220,1,219,241,223,1,222,242,225,1,224, + 243,228,1,7,7,7,1,171,228,171,1,172,228,173,1,175,229,175,1,177, + 229,178,1,180,230,180,1,182,231,183,1,185,232,186,1,187,232,188,1,190, + 233,191,1,192,234,194,1,195,234,196,1,197,235,199,1,199,236,201,1,202, + 236,204,1,204,237,207,1,207,238,209,1,209,239,212,1,212,239,215,1,214, + 240,217,1,217,241,220,1,219,241,223,1,222,242,225,1,224,243,228,1,26, + 28,27,1,171,228,171,1,172,228,173,1,175,229,175,1,177,229,178,1,180, + 230,180,1,182,231,183,1,185,232,186,1,187,232,188,1,190,233,191,1,192, + 234,194,1,195,234,196,1,197,235,199,1,199,236,201,1,202,236,204,1,204, + 237,207,1,207,238,209,1,209,239,212,1,212,239,215,1,214,240,217,1,217, + 241,220,1,219,241,223,1,222,242,225,1,224,243,228,1,226,243,230,1,14, + 18,14,1,172,228,173,1,175,229,175,1,177,229,178,1,180,230,180,1,182, + 231,183,1,185,232,186,1,187,232,188,1,190,233,191,1,192,234,194,1,195, + 234,196,1,197,235,199,1,199,236,201,1,202,236,204,1,204,237,207,1,207, + 238,209,1,209,239,212,1,212,239,215,1,214,240,217,1,217,241,220,1,219, + 241,223,1,222,242,225,1,224,243,228,1,226,243,230,1,5,7,5,1,172, + 228,173,1,175,229,175,1,177,229,178,1,180,230,180,1,182,231,183,1,185, + 232,186,1,187,232,188,1,190,233,191,1,192,234,194,1,195,234,196,1,197, + 235,199,1,199,236,201,1,202,236,204,1,204,237,207,1,207,238,209,1,209, + 239,212,1,212,239,215,1,214,240,217,1,217,241,220,1,219,241,223,1,222, + 242,225,1,224,243,228,1,123,133,126,1,11,14,11,1,172,228,173,1,175, + 229,175,1,177,229,178,1,180,230,180,1,182,231,183,1,185,232,186,1,187, + 232,188,1,190,233,191,1,192,234,194,1,195,234,196,1,197,235,199,1,199, + 236,201,1,202,236,204,1,204,237,207,1,207,238,209,1,209,239,212,1,212, + 239,215,1,214,240,217,1,217,241,220,1,219,241,223,1,222,242,225,1,224, + 243,228,1,7,7,7,1,171,228,171,1,172,228,173,1,175,229,175,1,177, + 229,178,1,180,230,180,1,182,231,183,1,185,232,186,1,187,232,188,1,190, + 233,191,1,192,234,194,1,195,234,196,1,197,235,199,1,199,236,201,1,202, + 236,204,1,204,237,207,1,207,238,209,1,209,239,212,1,212,239,215,1,214, + 240,217,1,217,241,220,1,219,241,223,1,222,242,225,1,224,243,228,1,7, + 7,7,1,171,228,171,1,172,228,173,1,77,101,77,1,17,22,17,1,79, + 101,79,1,182,231,183,1,185,232,186,1,187,232,188,1,190,233,191,1,192, + 234,194,1,195,234,196,1,197,235,199,1,199,236,201,1,202,236,204,1,92, + 107,93,1,207,238,209,1,209,239,212,1,212,239,215,1,214,240,217,1,217, + 241,220,1,219,241,223,1,222,242,225,1,224,243,228,1,70,75,71,1,120, + 160,120,1,172,228,173,1,113,147,113,1,9,12,9,1,113,144,113,1,182, + 231,183,1,185,232,186,1,187,232,188,1,190,233,191,1,192,234,194,1,195, + 234,196,1,197,235,199,1,199,236,201,1,202,236,204,1,0,0,0,1,207, + 238,209,1,209,239,212,1,212,239,215,1,214,240,217,1,217,241,220,1,219, + 241,223,1,222,242,225,1,224,243,228,1,226,243,230,1,5,7,5,1,172, + 228,173,1,95,125,95,1,146,189,147,1,96,123,96,1,182,231,183,1,185, + 232,186,1,187,232,188,1,190,233,191,1,131,160,132,1,3,4,3,1,9, + 11,9,1,77,92,78,1,0,0,0,3,209,239,212,1,148,167,150,1,23, + 25,23,1,9,10,9,1,117,129,119,1,222,242,225,1,224,243,228,1,226, + 243,230,1,5,7,5,1,172,228,173,1,175,229,175,1,177,229,178,1,180, + 230,180,1,182,231,183,1,185,232,186,1,187,232,188,1,190,233,191,1,29, + 36,30,1,59,71,59,1,186,222,188,1,199,236,201,1,202,236,204,1,0, + 0,0,1,207,238,209,1,209,239,212,1,206,232,209,1,187,210,190,1,187, + 208,190,1,12,13,12,1,222,242,225,1,224,243,228,1,70,75,71,1,37, + 49,37,1,172,228,173,1,175,229,175,1,177,229,178,1,180,230,180,1,182, + 231,183,1,185,232,186,1,187,232,188,1,190,233,191,1,164,200,166,1,29, + 35,29,1,8,9,8,1,152,180,154,1,202,236,204,1,0,0,0,1,207, + 238,209,1,209,239,212,1,147,166,149,1,64,72,65,1,26,29,27,1,0, + 0,0,1,222,242,225,1,224,243,228,1,7,7,7,1,171,228,171,1,172, + 228,173,1,175,229,175,1,177,229,178,1,180,230,180,1,182,231,183,1,185, + 232,186,1,187,232,188,1,190,233,191,1,192,234,194,1,195,234,196,1,53, + 64,54,1,15,18,15,1,202,236,204,1,0,0,0,1,196,225,198,1,209, + 239,212,1,11,12,11,1,148,166,150,1,151,167,153,1,0,0,0,1,222, + 242,225,1,224,243,228,1,7,7,7,1,171,228,171,1,172,228,173,1,175, + 229,175,1,177,229,178,1,180,230,180,1,182,231,183,1,185,232,186,1,0, + 0,0,1,190,233,191,1,79,96,80,1,9,11,9,1,4,5,4,1,136, + 161,137,1,202,236,204,1,45,52,45,1,6,7,6,1,209,239,212,1,78, + 88,79,1,7,8,7,1,95,106,97,1,0,0,0,1,222,242,225,1,224, + 243,228,1,123,133,126,1,71,95,71,1,172,228,173,1,175,229,175,1,177, + 229,178,1,180,230,180,1,182,231,183,1,185,232,186,1,187,232,188,1,190, + 233,191,1,192,234,194,1,195,234,196,1,197,235,199,1,199,236,201,1,202, + 236,204,1,204,237,207,1,207,238,209,1,209,239,212,1,212,239,215,1,214, + 240,217,1,217,241,220,1,219,241,223,1,222,242,225,1,224,243,228,1,226, + 243,230,1,5,7,5,1,172,228,173,1,175,229,175,1,177,229,178,1,180, + 230,180,1,182,231,183,1,185,232,186,1,187,232,188,1,190,233,191,1,192, + 234,194,1,195,234,196,1,197,235,199,1,199,236,201,1,202,236,204,1,204, + 237,207,1,207,238,209,1,209,239,212,1,212,239,215,1,214,240,217,1,217, + 241,220,1,219,241,223,1,222,242,225,1,224,243,228,1,226,243,230,1,5, + 7,5,1,172,228,173,1,175,229,175,1,177,229,178,1,180,230,180,1,182, + 231,183,1,185,232,186,1,187,232,188,1,190,233,191,1,192,234,194,1,195, + 234,196,1,197,235,199,1,199,236,201,1,202,236,204,1,204,237,207,1,207, + 238,209,1,209,239,212,1,212,239,215,1,214,240,217,1,217,241,220,1,219, + 241,223,1,222,242,225,1,224,243,228,1,26,28,27,1,77,103,77,1,172, + 228,173,1,175,229,175,1,177,229,178,1,180,230,180,1,182,231,183,1,185, + 232,186,1,187,232,188,1,190,233,191,1,192,234,194,1,195,234,196,1,197, + 235,199,1,199,236,201,1,202,236,204,1,204,237,207,1,207,238,209,1,209, + 239,212,1,212,239,215,1,214,240,217,1,217,241,220,1,219,241,223,1,222, + 242,225,1,224,243,228,1,7,7,7,1,171,228,171,1,172,228,173,1,175, + 229,175,1,177,229,178,1,180,230,180,1,182,231,183,1,185,232,186,1,187, + 232,188,1,190,233,191,1,192,234,194,1,195,234,196,1,197,235,199,1,199, + 236,201,1,202,236,204,1,204,237,207,1,207,238,209,1,209,239,212,1,212, + 239,215,1,214,240,217,1,217,241,220,1,219,241,223,1,222,242,225,1,224, + 243,228,1,7,7,7,1,171,228,171,1,172,228,173,1,175,229,175,1,177, + 229,178,1,180,230,180,1,182,231,183,1,185,232,186,1,187,232,188,1,190, + 233,191,1,192,234,194,1,195,234,196,1,197,235,199,1,199,236,201,1,202, + 236,204,1,204,237,207,1,207,238,209,1,209,239,212,1,212,239,215,1,214, + 240,217,1,217,241,220,1,219,241,223,1,222,242,225,1,224,243,228,1,214, + 230,218,1,33,44,33,1,172,228,173,1,175,229,175,1,177,229,178,1,180, + 230,180,1,182,231,183,1,185,232,186,1,187,232,188,1,190,233,191,1,192, + 234,194,1,195,234,196,1,197,235,199,1,199,236,201,1,202,236,204,1,204, + 237,207,1,207,238,209,1,209,239,212,1,212,239,215,1,214,240,217,1,217, + 241,220,1,219,241,223,1,222,242,225,1,224,243,228,1,226,243,230,1,5, + 7,5,1,172,228,173,1,175,229,175,1,177,229,178,1,180,230,180,1,182, + 231,183,1,185,232,186,1,187,232,188,1,190,233,191,1,192,234,194,1,195, + 234,196,1,197,235,199,1,199,236,201,1,202,236,204,1,204,237,207,1,207, + 238,209,1,209,239,212,1,212,239,215,1,214,240,217,1,217,241,220,1,219, + 241,223,1,222,242,225,1,224,243,228,1,190,205,194,1,3,4,3,1,129, + 170,129,1,175,229,175,1,177,229,178,1,9,11,9,1,6,7,6,1,18, + 23,18,1,187,232,188,1,190,233,191,1,119,145,120,1,6,7,6,2,52, + 61,52,1,202,236,204,1,204,237,207,1,75,86,75,1,6,7,6,1,6, + 7,7,1,103,115,104,1,217,241,220,1,219,241,223,1,34,37,35,1,7, + 7,7,1,3,4,4,1,152,1,0,0,244,244,244,1,248,248,248,1,233, + 233,233,1,128,128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128, + 128,128,2,188,188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,221, + 221,221,1,248,248,248,2,139,139,139,1,128,128,128,1,131,131,131,1,244, + 244,244,1,154,154,154,1,255,255,255,22,248,248,248,1,128,128,128,1,255, + 255,255,22,229,229,229,1,128,128,128,1,255,255,255,22,128,128,128,1,236, + 236,236,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,165, + 165,165,1,240,240,240,1,255,255,255,22,248,248,248,1,128,128,128,1,255, + 255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,195,195,195,1,150, + 150,150,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,128, + 128,128,1,248,248,248,1,255,255,255,22,195,195,195,1,210,210,210,1,255, + 255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128, + 128,128,1,255,255,255,22,165,165,165,1,180,180,180,1,255,255,255,22,128, + 128,128,1,248,248,248,1,255,255,255,22,128,128,128,1,248,248,248,1,255, + 255,255,22,229,229,229,1,176,176,176,1,255,255,255,22,248,248,248,1,128, + 128,128,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,131, + 131,131,1,214,214,214,1,255,255,255,22,128,128,128,1,248,248,248,1,255, + 255,255,22,139,139,139,1,244,244,244,1,146,146,146,1,128,128,128,2,244, + 244,244,1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1,248, + 248,248,2,203,203,203,1,128,128,128,2,188,188,188,1,248,248,248,2,173, + 173,173,1,128,128,128,2,221,221,221,1,248,248,248,1,244,244,244,1,0, + 0) + ); + +const + objdata_tstringcontainer: record size: integer; data: array[0..2875] of byte end = + (size: 2876; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,115,116, + 114,105,110,103,99,111,110,116,97,105,110,101,114,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,192,10, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,240,8, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,1,5,7, + 5,1,18,22,18,1,177,229,177,1,179,231,181,1,113,144,113,1,5,7, + 5,1,6,7,6,1,49,60,50,1,193,233,193,1,195,235,197,1,71,84, + 72,1,6,7,6,2,99,113,99,1,207,237,209,1,209,239,213,1,32,37, + 33,1,6,7,6,2,185,204,187,1,221,243,225,1,212,232,216,1,3,4, + 3,1,113,151,113,1,173,229,173,1,175,229,176,1,178,230,178,1,180,231, + 181,1,183,231,184,1,185,232,186,1,188,233,189,1,190,233,191,1,193,234, + 194,1,195,235,197,1,197,236,199,1,200,236,202,1,202,237,205,1,205,238, + 207,1,207,238,210,1,210,239,213,1,212,240,215,1,215,240,218,1,217,241, + 220,1,220,242,223,1,222,243,226,1,224,243,228,1,7,7,7,1,171,227, + 171,1,173,229,173,1,175,229,176,1,175,225,175,1,134,172,135,1,119,150, + 120,1,157,197,158,1,188,233,189,1,190,233,191,1,193,234,194,1,194,234, + 196,1,197,236,199,1,200,236,202,1,202,237,205,1,205,238,207,1,207,238, + 210,1,210,239,213,1,212,240,215,1,169,188,171,1,217,241,220,1,220,242, + 223,1,222,243,226,1,224,243,228,1,27,28,27,1,171,227,171,1,173,229, + 173,1,173,226,174,1,43,56,43,1,60,77,60,1,88,111,89,1,33,41, + 33,1,105,131,106,1,190,233,191,1,145,176,146,1,104,125,105,1,197,236, + 199,1,200,236,202,1,202,237,205,1,205,238,207,1,207,238,210,1,209,238, + 212,1,106,120,108,1,47,53,48,1,217,241,220,1,220,242,223,1,222,243, + 226,1,224,243,228,1,227,243,231,1,14,18,14,1,173,229,173,1,140,183, + 141,1,39,51,39,1,180,231,181,1,183,231,184,1,166,208,167,1,50,62, + 50,1,189,232,190,1,87,106,87,1,70,84,70,1,175,209,176,1,158,187, + 160,1,175,205,178,1,150,174,151,1,205,235,208,1,64,73,65,1,70,79, + 71,1,47,53,48,1,217,241,220,1,220,242,223,1,222,243,226,1,224,243, + 228,1,227,243,231,1,5,7,5,1,173,229,173,1,169,221,170,1,29,37, + 29,1,71,91,71,1,135,170,136,1,181,227,182,1,188,233,189,1,189,231, + 190,1,68,83,68,1,54,65,55,1,161,193,163,1,52,61,52,1,52,61, + 53,1,84,97,84,1,205,235,208,1,179,203,181,1,192,217,195,1,47,53, + 48,1,217,241,220,1,220,242,223,1,222,243,226,1,224,243,228,1,124,133, + 127,1,11,14,11,1,173,229,173,1,175,229,176,1,166,215,166,1,102,131, + 103,1,47,59,47,1,13,16,13,1,105,131,106,1,190,233,191,1,122,148, + 122,1,96,116,97,1,197,236,199,1,52,61,52,1,148,174,150,1,205,238, + 207,1,207,238,210,1,210,239,213,1,192,217,195,1,47,53,48,1,217,241, + 220,1,220,242,223,1,222,243,226,1,224,243,228,1,7,7,7,1,171,227, + 171,1,173,229,173,1,145,189,146,1,147,190,147,1,180,231,181,1,183,231, + 184,1,168,210,168,1,24,29,24,1,168,206,169,1,122,148,122,1,96,116, + 97,1,197,236,199,1,52,61,52,1,168,197,170,1,205,238,207,1,207,238, + 210,1,210,239,213,1,192,217,195,1,47,53,48,1,217,241,220,1,220,242, + 223,1,222,243,226,1,224,243,228,1,7,7,7,1,171,227,171,1,173,229, + 173,1,124,163,125,1,43,56,43,1,173,222,174,1,183,231,184,1,176,221, + 177,1,30,37,30,1,174,214,175,1,124,150,125,1,93,112,94,1,197,236, + 199,1,52,61,52,1,169,198,171,1,205,238,207,1,207,238,210,1,210,239, + 213,1,192,217,195,1,47,53,48,1,217,241,220,1,220,242,223,1,222,243, + 226,1,224,243,228,1,71,75,72,1,121,160,121,1,173,229,173,1,174,228, + 175,1,88,114,88,1,23,29,23,1,38,48,38,1,25,32,26,1,116,143, + 116,1,190,233,191,1,157,190,157,1,21,25,21,1,124,148,125,1,52,61, + 52,1,169,198,171,1,205,238,207,1,207,238,210,1,210,239,213,1,192,217, + 195,1,47,53,48,1,217,241,220,1,220,242,223,1,222,243,226,1,224,243, + 228,1,227,243,231,1,5,7,5,1,173,229,173,1,175,229,176,1,178,230, + 178,1,180,231,181,1,169,213,170,1,185,232,186,1,188,233,189,1,190,233, + 191,1,193,234,194,1,192,231,194,1,195,233,197,1,200,236,202,1,202,237, + 205,1,205,238,207,1,207,238,210,1,210,239,213,1,212,240,215,1,215,240, + 218,1,217,241,220,1,220,242,223,1,222,243,226,1,224,243,228,1,227,243, + 231,1,5,7,5,1,173,229,173,1,175,229,176,1,178,230,178,1,180,231, + 181,1,183,231,184,1,185,232,186,1,188,233,189,1,190,233,191,1,193,234, + 194,1,195,235,197,1,197,236,199,1,200,236,202,1,202,237,205,1,205,238, + 207,1,207,238,210,1,210,239,213,1,212,240,215,1,215,240,218,1,217,241, + 220,1,220,242,223,1,222,243,226,1,224,243,228,1,71,75,72,1,36,49, + 36,1,173,229,173,1,175,229,176,1,178,230,178,1,175,225,176,1,165,208, + 166,1,185,232,186,1,188,233,189,1,190,233,191,1,193,234,194,1,195,235, + 197,1,197,236,199,1,200,236,202,1,202,237,205,1,205,238,207,1,207,238, + 210,1,210,239,213,1,210,238,213,1,215,240,218,1,217,241,220,1,220,242, + 223,1,222,243,226,1,224,243,228,1,7,7,7,1,171,227,171,1,173,229, + 173,1,175,229,176,1,84,108,84,1,20,25,20,1,42,53,43,1,24,30, + 24,1,140,174,141,1,190,233,191,1,163,197,164,1,127,153,128,1,197,236, + 199,1,200,236,202,1,202,237,205,1,205,238,207,1,207,238,210,1,89,101, + 90,1,55,62,56,1,54,60,55,1,147,164,149,1,220,242,223,1,222,243, + 226,1,224,243,228,1,7,7,7,1,171,227,171,1,173,229,173,1,146,191, + 147,1,31,40,31,1,179,230,180,1,183,231,184,1,148,186,149,1,27,33, + 27,1,190,233,191,1,118,143,119,1,93,112,94,1,195,233,197,1,196,231, + 198,1,200,235,203,1,196,228,198,1,150,173,152,1,77,87,78,1,212,240, + 215,1,202,226,205,1,36,40,36,1,217,239,220,1,222,243,226,1,224,243, + 228,1,124,133,127,1,72,95,72,1,173,229,173,1,160,209,161,1,18,23, + 18,1,116,149,116,1,175,221,176,1,185,232,186,1,177,219,178,1,187,229, + 188,1,38,46,38,1,30,36,30,1,141,169,143,1,52,61,52,1,53,62, + 54,1,37,43,37,1,193,222,196,1,198,225,200,1,212,240,215,1,202,226, + 205,1,15,17,16,1,216,237,219,1,222,243,226,1,224,243,228,1,227,243, + 231,1,5,7,5,1,173,229,173,1,175,229,176,1,140,181,140,1,57,73, + 57,1,12,15,12,1,49,62,50,1,147,182,147,1,190,233,191,1,122,148, + 122,1,96,116,97,1,197,236,199,1,52,61,52,1,133,156,135,1,205,238, + 207,1,207,238,210,1,210,239,213,1,206,233,209,1,67,74,68,1,116,129, + 117,1,220,242,223,1,222,243,226,1,224,243,228,1,227,243,231,1,5,7, + 5,1,173,229,173,1,165,216,166,1,168,217,168,1,180,231,181,1,178,225, + 179,1,127,159,128,1,17,21,17,1,179,219,180,1,122,148,122,1,96,116, + 97,1,197,236,199,1,52,61,52,1,166,194,168,1,205,238,207,1,207,238, + 210,1,201,229,204,1,57,64,57,1,107,120,109,1,217,241,220,1,220,242, + 223,1,222,243,226,1,224,243,228,1,27,28,27,1,77,103,77,1,173,229, + 173,1,112,146,113,1,67,87,67,1,180,231,181,1,183,231,184,1,185,232, + 186,1,41,50,41,1,163,200,164,1,123,149,123,1,96,115,97,1,197,236, + 199,1,52,61,52,1,169,198,171,1,205,238,207,1,200,230,203,1,49,56, + 50,1,125,141,126,1,215,240,218,1,217,241,220,1,220,242,223,1,222,243, + 226,1,224,243,228,1,7,7,7,1,171,227,171,1,173,229,173,1,166,217, + 167,1,46,60,46,1,50,64,50,1,84,106,84,1,51,64,51,1,72,89, + 72,1,190,233,191,1,141,171,142,1,36,43,36,1,149,179,151,1,52,61, + 52,1,169,198,171,1,205,238,207,1,106,122,108,1,24,27,24,1,86,97, + 87,1,87,97,88,1,88,97,89,1,204,225,207,1,222,243,226,1,224,243, + 228,1,7,7,7,1,171,227,171,1,173,229,173,1,175,229,176,1,176,227, + 176,1,145,187,146,1,123,155,123,1,151,189,152,1,188,233,189,1,190,233, + 191,1,193,234,194,1,150,181,151,1,169,203,171,1,163,193,165,1,194,228, + 197,1,205,238,207,1,173,199,175,1,157,179,160,1,159,180,161,1,161,180, + 163,1,163,181,165,1,214,235,217,1,222,243,226,1,224,243,228,1,216,232, + 220,1,33,44,33,1,173,229,173,1,175,229,176,1,178,230,178,1,180,231, + 181,1,183,231,184,1,185,232,186,1,188,233,189,1,190,233,191,1,193,234, + 194,1,195,235,197,1,197,236,199,1,200,236,202,1,202,237,205,1,205,238, + 207,1,207,238,210,1,210,239,213,1,212,240,215,1,215,240,218,1,217,241, + 220,1,220,242,223,1,222,243,226,1,224,243,228,1,227,243,231,1,5,7, + 5,1,173,229,173,1,175,229,176,1,178,230,178,1,180,231,181,1,183,231, + 184,1,185,232,186,1,188,233,189,1,190,233,191,1,193,234,194,1,195,235, + 197,1,197,236,199,1,200,236,202,1,202,237,205,1,205,238,207,1,207,238, + 210,1,210,239,213,1,212,240,215,1,215,240,218,1,217,241,220,1,220,242, + 223,1,222,243,226,1,224,243,228,1,191,204,194,1,3,3,3,1,129,171, + 129,1,175,229,175,1,177,229,177,1,8,10,8,1,5,7,5,1,18,22, + 18,1,187,233,189,1,189,233,191,1,119,144,119,1,6,7,6,2,52,62, + 53,1,201,237,205,1,205,237,207,1,75,85,76,1,6,7,6,2,103,115, + 105,1,217,241,219,1,219,241,223,1,35,38,35,1,7,7,7,1,3,4, + 3,1,152,1,0,0,244,244,244,1,248,248,248,1,233,233,233,1,128,128, + 128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2,188,188, + 188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221,1,248,248, + 248,2,139,139,139,1,128,128,128,1,131,131,131,1,244,244,244,1,154,154, + 154,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,229,229, + 229,1,128,128,128,1,255,255,255,22,128,128,128,1,236,236,236,1,255,255, + 255,22,128,128,128,1,248,248,248,1,255,255,255,22,165,165,165,1,240,240, + 240,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248, + 248,1,128,128,128,1,255,255,255,22,195,195,195,1,150,150,150,1,255,255, + 255,22,128,128,128,1,248,248,248,1,255,255,255,22,128,128,128,1,248,248, + 248,1,255,255,255,22,195,195,195,1,210,210,210,1,255,255,255,22,248,248, + 248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255, + 255,22,165,165,165,1,180,180,180,1,255,255,255,22,128,128,128,1,248,248, + 248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,229,229, + 229,1,176,176,176,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255, + 255,22,248,248,248,1,128,128,128,1,255,255,255,22,131,131,131,1,214,214, + 214,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,139,139, + 139,1,244,244,244,1,146,146,146,1,128,128,128,2,244,244,244,1,248,248, + 248,1,233,233,233,1,128,128,128,2,158,158,158,1,248,248,248,2,203,203, + 203,1,128,128,128,2,188,188,188,1,248,248,248,2,173,173,173,1,128,128, + 128,2,221,221,221,1,248,248,248,1,244,244,244,1,0,0) + ); + +const + objdata_tkeystringcontainer: record size: integer; data: array[0..2878] of byte end = + (size: 2879; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,107,101, + 121,115,116,114,105,110,103,99,111,110,116,97,105,110,101,114,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,192,10,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,240,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3, + 1,5,7,5,1,18,22,18,1,177,229,177,1,179,231,181,1,113,144,113, + 1,5,7,5,1,6,7,6,1,49,60,50,1,193,233,193,1,195,235,197, + 1,71,84,72,1,6,7,6,2,99,113,99,1,207,237,209,1,209,239,213, + 1,32,37,33,1,6,7,6,2,185,204,187,1,221,243,225,1,212,232,216, + 1,3,4,3,1,113,151,113,1,173,229,173,1,175,229,176,1,178,230,178, + 1,180,231,181,1,183,231,184,1,185,232,186,1,188,233,189,1,190,233,191, + 1,193,234,194,1,195,235,197,1,197,236,199,1,200,236,202,1,202,237,205, + 1,205,238,207,1,207,238,210,1,210,239,213,1,212,240,215,1,215,240,218, + 1,217,241,220,1,220,242,223,1,222,243,226,1,224,243,228,1,7,7,7, + 1,171,227,171,1,173,229,173,1,132,172,133,1,178,230,178,1,180,231,181, + 1,183,231,184,1,137,172,138,1,177,219,178,1,190,233,191,1,193,234,194, + 1,195,235,197,1,197,236,199,1,200,236,202,1,201,236,204,1,205,238,207, + 1,207,238,210,1,210,239,213,1,212,240,215,1,215,240,218,1,217,241,220, + 1,178,195,180,1,222,243,226,1,224,243,228,1,27,28,27,1,171,227,171, + 1,173,229,173,1,21,28,21,1,178,230,178,1,180,231,181,1,90,114,91, + 1,70,87,70,1,187,232,188,1,190,233,191,1,193,234,194,1,195,235,197, + 1,197,236,199,1,173,205,175,1,100,117,101,1,205,238,207,1,207,238,210, + 1,210,239,213,1,212,240,215,1,215,240,218,1,171,190,173,1,16,18,17, + 1,222,243,226,1,224,243,228,1,227,243,231,1,14,18,14,1,173,229,173, + 1,21,28,21,1,178,230,178,1,109,140,109,1,55,70,56,1,182,228,183, + 1,188,233,189,1,173,212,174,1,128,155,129,1,157,189,158,1,197,236,199, + 1,124,146,125,1,63,73,64,1,183,213,185,1,166,190,168,1,166,188,168, + 1,180,204,183,1,159,178,162,1,47,52,47,1,33,36,33,1,222,243,226, + 1,224,243,228,1,227,243,231,1,5,7,5,1,173,229,173,1,21,28,21, + 1,126,162,126,1,32,41,32,1,177,223,178,1,185,232,186,1,187,231,188, + 1,39,48,39,1,111,135,112,1,49,59,49,1,141,169,143,1,106,125,107, + 1,49,58,50,1,171,199,173,1,42,49,43,1,65,74,66,1,134,152,136, + 1,192,215,195,1,213,236,216,1,47,52,48,1,222,243,226,1,224,243,228, + 1,124,133,127,1,11,14,11,1,173,229,173,1,18,23,18,1,43,55,43, + 1,34,43,34,1,150,189,151,1,185,232,186,1,184,228,185,1,29,36,29, + 1,137,166,138,1,179,216,181,1,185,221,187,1,158,186,159,1,87,102,88, + 1,205,238,207,1,31,35,31,1,199,227,202,1,212,240,215,1,215,240,218, + 1,217,241,220,1,47,52,48,1,222,243,226,1,224,243,228,1,7,7,7, + 1,171,227,171,1,173,229,173,1,19,25,19,1,163,210,163,1,139,178,140, + 1,37,46,37,1,182,228,183,1,188,233,189,1,147,180,148,1,64,77,64, + 1,21,26,22,1,142,170,144,1,158,186,159,1,87,102,88,1,205,238,207, + 1,44,50,44,1,210,239,213,1,212,240,215,1,215,240,218,1,217,241,220, + 1,47,52,48,1,222,243,226,1,224,243,228,1,7,7,7,1,171,227,171, + 1,173,229,173,1,21,28,21,1,178,230,178,1,180,231,181,1,74,93,74, + 1,96,121,97,1,178,221,179,1,98,120,98,1,193,234,194,1,145,175,147, + 1,76,91,76,1,160,189,162,1,86,100,87,1,205,238,207,1,45,51,45, + 1,210,239,213,1,212,240,215,1,215,240,218,1,217,241,220,1,47,52,48, + 1,222,243,226,1,224,243,228,1,71,75,72,1,121,160,121,1,173,229,173, + 1,21,28,21,1,178,230,178,1,180,231,181,1,172,217,172,1,22,28,23, + 1,157,195,158,1,81,100,82,1,56,68,56,1,38,46,39,1,153,183,155, + 1,184,217,186,1,26,31,27,1,134,156,136,1,45,51,45,1,210,239,213, + 1,212,240,215,1,215,240,218,1,217,241,220,1,47,52,48,1,222,243,226, + 1,224,243,228,1,227,243,231,1,5,7,5,1,173,229,173,1,175,229,176, + 1,178,230,178,1,180,231,181,1,183,231,184,1,185,232,186,1,188,233,189, + 1,190,233,191,1,185,224,186,1,193,232,195,1,197,236,199,1,200,236,202, + 1,200,234,203,1,203,235,205,1,207,238,210,1,210,239,213,1,212,240,215, + 1,215,240,218,1,217,241,220,1,220,242,223,1,222,243,226,1,224,243,228, + 1,227,243,231,1,5,7,5,1,173,229,173,1,175,229,176,1,178,230,178, + 1,180,231,181,1,183,231,184,1,185,232,186,1,188,233,189,1,190,233,191, + 1,193,234,194,1,195,235,197,1,197,236,199,1,200,236,202,1,202,237,205, + 1,205,238,207,1,207,238,210,1,210,239,213,1,212,240,215,1,215,240,218, + 1,217,241,220,1,220,242,223,1,222,243,226,1,224,243,228,1,71,75,72, + 1,36,49,36,1,173,229,173,1,170,223,171,1,178,230,178,1,180,231,181, + 1,183,231,184,1,181,227,182,1,187,231,188,1,190,233,191,1,193,234,194, + 1,195,235,197,1,197,236,199,1,200,236,202,1,202,237,205,1,205,238,207, + 1,207,238,210,1,210,239,213,1,212,240,215,1,215,240,218,1,217,241,220, + 1,218,240,221,1,222,243,226,1,224,243,228,1,7,7,7,1,171,227,171, + 1,173,229,173,1,21,28,21,1,178,230,178,1,180,231,181,1,128,162,129, + 1,39,49,39,1,178,221,179,1,190,233,191,1,193,234,194,1,195,235,197, + 1,197,236,199,1,184,217,186,1,128,150,129,1,205,238,207,1,207,238,210, + 1,210,239,213,1,212,240,215,1,161,180,163,1,57,63,58,1,56,62,57, + 1,137,150,139,1,224,243,228,1,7,7,7,1,171,227,171,1,173,229,173, + 1,21,28,21,1,178,230,178,1,142,182,143,1,34,43,34,1,169,212,170, + 1,188,233,189,1,190,233,191,1,176,214,177,1,193,232,195,1,197,236,199, + 1,154,181,155,1,85,99,86,1,203,235,205,1,203,233,206,1,203,231,205, + 1,210,238,213,1,57,64,58,1,203,225,205,1,219,241,222,1,51,56,52, + 1,217,235,221,1,124,133,127,1,72,95,72,1,173,229,173,1,21,28,21, + 1,153,198,153,1,32,42,33,1,160,202,161,1,185,232,186,1,188,233,189, + 1,58,71,58,1,63,76,63,1,35,42,36,1,162,194,164,1,76,90,77, + 1,27,32,27,1,151,175,153,1,50,57,50,1,43,49,43,1,104,118,105, + 1,196,218,198,1,217,241,220,1,220,242,223,1,34,37,35,1,213,231,216, + 1,227,243,231,1,5,7,5,1,173,229,173,1,19,25,19,1,38,49,38, + 1,28,36,28,1,169,213,170,1,185,232,186,1,181,225,182,1,34,41,34, + 1,180,218,181,1,161,194,162,1,163,195,165,1,158,186,159,1,87,102,88, + 1,205,238,207,1,30,35,30,1,185,211,188,1,212,240,215,1,215,240,218, + 1,217,241,220,1,114,125,115,1,95,104,97,1,224,243,228,1,227,243,231, + 1,5,7,5,1,173,229,173,1,18,23,18,1,140,180,140,1,112,143,112, + 1,63,80,63,1,185,232,186,1,188,233,189,1,106,130,106,1,23,28,24, + 1,60,73,61,1,169,203,171,1,158,186,159,1,87,102,88,1,205,238,207, + 1,41,48,42,1,210,239,213,1,212,240,215,1,215,240,218,1,126,140,128, + 1,66,73,67,1,219,239,222,1,224,243,228,1,27,28,27,1,77,103,77, + 1,173,229,173,1,21,28,21,1,178,230,178,1,180,231,181,1,46,58,46, + 1,127,159,128,1,179,222,180,1,136,167,137,1,191,231,192,1,117,141,118, + 1,76,91,76,1,158,187,160,1,86,101,88,1,205,238,207,1,45,51,45, + 1,210,239,213,1,212,240,215,1,141,157,143,1,67,75,68,1,214,235,217, + 1,222,243,226,1,224,243,228,1,7,7,7,1,171,227,171,1,173,229,173, + 1,21,28,21,1,178,230,178,1,180,231,181,1,155,196,156,1,22,28,23, + 1,175,217,176,1,46,57,46,1,100,121,100,1,60,73,61,1,125,150,126, + 1,176,207,177,1,33,39,34,1,159,185,161,1,45,51,45,1,210,239,213, + 1,207,234,210,1,18,20,18,1,79,88,80,1,89,98,90,1,90,98,91, + 1,205,222,208,1,7,7,7,1,171,227,171,1,173,229,173,1,137,179,137, + 1,178,230,178,1,180,231,181,1,183,231,184,1,152,190,152,1,170,211,171, + 1,186,228,187,1,141,171,142,1,156,188,158,1,197,236,199,1,200,236,202, + 1,162,190,164,1,178,206,179,1,166,191,169,1,210,239,213,1,206,233,209, + 1,161,180,163,1,163,181,165,1,165,181,167,1,166,182,169,1,216,234,220, + 1,216,232,220,1,33,44,33,1,173,229,173,1,175,229,176,1,178,230,178, + 1,180,231,181,1,183,231,184,1,185,232,186,1,188,233,189,1,190,233,191, + 1,193,234,194,1,195,235,197,1,197,236,199,1,200,236,202,1,202,237,205, + 1,205,238,207,1,207,238,210,1,210,239,213,1,212,240,215,1,215,240,218, + 1,217,241,220,1,220,242,223,1,222,243,226,1,224,243,228,1,227,243,231, + 1,5,7,5,1,173,229,173,1,175,229,176,1,178,230,178,1,180,231,181, + 1,183,231,184,1,185,232,186,1,188,233,189,1,190,233,191,1,193,234,194, + 1,195,235,197,1,197,236,199,1,200,236,202,1,202,237,205,1,205,238,207, + 1,207,238,210,1,210,239,213,1,212,240,215,1,215,240,218,1,217,241,220, + 1,220,242,223,1,222,243,226,1,224,243,228,1,191,204,194,1,3,3,3, + 1,129,171,129,1,175,229,175,1,177,229,177,1,8,10,8,1,5,7,5, + 1,18,22,18,1,187,233,189,1,189,233,191,1,119,144,119,1,6,7,6, + 2,52,62,53,1,201,237,205,1,205,237,207,1,75,85,76,1,6,7,6, + 2,103,115,105,1,217,241,219,1,219,241,223,1,35,38,35,1,7,7,7, + 1,3,4,3,1,152,1,0,0,244,244,244,1,248,248,248,1,233,233,233, + 1,128,128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128, + 2,188,188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221, + 1,248,248,248,2,139,139,139,1,128,128,128,1,131,131,131,1,244,244,244, + 1,154,154,154,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255, + 22,229,229,229,1,128,128,128,1,255,255,255,22,128,128,128,1,236,236,236, + 1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,165,165,165, + 1,240,240,240,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255, + 22,248,248,248,1,128,128,128,1,255,255,255,22,195,195,195,1,150,150,150, + 1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,128,128,128, + 1,248,248,248,1,255,255,255,22,195,195,195,1,210,210,210,1,255,255,255, + 22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128, + 1,255,255,255,22,165,165,165,1,180,180,180,1,255,255,255,22,128,128,128, + 1,248,248,248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255, + 22,229,229,229,1,176,176,176,1,255,255,255,22,248,248,248,1,128,128,128, + 1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,131,131,131, + 1,214,214,214,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255, + 22,139,139,139,1,244,244,244,1,146,146,146,1,128,128,128,2,244,244,244, + 1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1,248,248,248, + 2,203,203,203,1,128,128,128,2,188,188,188,1,248,248,248,2,173,173,173, + 1,128,128,128,2,221,221,221,1,248,248,248,1,244,244,244,1,0,0) + ); + +const + objdata_trttistat: record size: integer; data: array[0..2716] of byte end = + (size: 2717; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,114,116, + 116,105,115,116,97,116,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,40,10,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,92,8,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,1,3,3,3,1,15,20,15,1,178, + 230,178,1,180,231,181,1,114,144,115,1,3,3,3,2,49,60,49,1,193, + 234,194,1,195,235,197,1,71,85,72,1,3,4,3,2,99,115,100,1,207, + 238,210,1,210,239,212,1,35,40,36,1,3,4,3,2,175,192,177,1,222, + 243,226,1,213,231,217,1,0,0,0,1,121,161,121,1,173,229,173,1,175, + 229,176,1,178,230,178,1,180,231,181,1,183,231,184,1,185,232,186,1,188, + 233,189,1,190,233,191,1,193,234,194,1,195,235,197,1,197,236,199,1,200, + 236,202,1,202,237,205,1,205,238,207,1,207,238,210,1,210,239,212,1,212, + 240,215,1,215,240,218,1,217,241,220,1,220,242,223,1,222,243,226,1,224, + 243,228,1,3,4,3,1,171,228,171,1,173,229,173,1,175,229,176,1,178, + 230,178,1,180,231,181,1,183,231,184,1,185,232,186,1,187,233,189,1,190, + 233,191,1,193,234,194,1,195,235,197,1,197,236,199,1,200,236,202,1,202, + 237,205,1,205,238,207,1,207,238,210,1,210,239,212,1,212,240,215,1,215, + 240,218,1,217,241,220,1,220,242,223,1,222,243,226,1,224,243,228,1,28, + 31,29,1,171,228,171,1,173,229,173,1,175,229,176,1,178,230,178,1,177, + 231,182,1,129,236,219,1,93,239,243,1,62,238,253,1,62,238,243,1,107, + 236,223,1,192,235,198,1,197,236,199,1,200,236,202,1,202,237,205,1,205, + 238,207,1,207,238,210,1,210,239,212,1,212,240,215,1,215,240,218,1,217, + 241,220,1,220,242,223,1,222,243,226,1,224,243,228,1,227,244,231,1,9, + 11,9,1,173,229,173,1,175,229,176,1,176,231,180,1,122,239,239,1,124, + 241,255,1,123,241,255,1,104,241,255,1,73,240,255,1,34,239,255,1,57, + 237,241,1,194,236,200,1,200,236,202,1,202,237,205,1,205,238,207,1,207, + 238,210,1,210,239,212,1,212,240,215,1,215,240,218,1,217,241,220,1,220, + 242,223,1,222,243,226,1,224,243,228,1,227,244,231,1,3,3,3,1,173, + 229,173,1,175,229,176,1,141,236,217,1,146,242,255,1,173,243,255,1,172, + 243,255,1,145,242,255,1,104,241,255,1,59,239,255,1,13,238,255,1,110, + 237,226,1,200,236,202,1,202,237,205,1,205,238,207,1,207,238,210,1,210, + 239,212,1,212,240,215,1,215,240,218,1,217,241,220,1,220,242,223,1,222, + 243,226,1,224,243,228,1,125,135,128,1,9,11,9,1,173,229,173,1,175, + 229,176,1,133,239,242,1,173,243,255,1,208,245,255,2,171,243,255,1,122, + 241,255,1,72,240,255,1,22,238,255,1,49,237,244,1,200,236,202,1,202, + 237,205,1,205,238,207,1,207,238,210,1,210,239,212,1,212,240,215,1,215, + 240,218,1,217,241,220,1,220,242,223,1,222,243,226,1,224,243,228,1,3, + 4,3,1,171,228,171,1,173,229,173,1,174,229,176,1,125,241,253,1,173, + 243,255,1,208,245,255,2,171,243,255,1,122,241,255,1,72,240,255,1,22, + 238,255,1,21,238,252,1,200,236,202,1,202,237,205,1,205,238,207,1,207, + 238,210,1,210,239,212,1,212,240,215,1,215,240,218,1,217,241,220,1,220, + 242,223,1,222,243,226,1,224,243,228,1,3,4,3,1,171,228,171,1,173, + 229,173,1,170,222,170,1,53,108,109,1,139,233,245,1,169,238,250,1,171, + 243,255,1,144,242,255,1,104,241,255,1,58,239,255,1,13,238,255,1,49, + 237,244,1,200,236,202,1,202,237,205,1,178,207,180,1,132,152,180,1,114, + 129,232,1,212,240,215,1,215,240,218,1,217,241,220,1,220,242,223,1,222, + 243,226,1,224,243,228,1,70,75,71,1,121,161,121,1,173,229,173,1,79, + 103,79,1,19,35,32,1,33,77,81,1,102,200,212,1,122,241,255,1,104, + 241,255,1,72,240,255,1,33,239,255,1,13,238,255,1,110,237,226,1,200, + 236,202,1,202,237,205,1,97,112,100,1,25,29,160,1,9,10,253,1,189, + 214,219,1,215,240,218,1,217,241,220,1,220,242,223,1,222,243,226,1,224, + 243,228,1,227,244,231,1,3,3,3,1,173,229,173,1,135,176,135,1,75, + 100,78,1,33,91,91,1,73,240,255,1,72,240,255,1,58,239,255,1,33, + 239,255,1,8,151,162,1,13,53,54,1,46,56,47,1,127,150,128,1,177, + 208,180,1,17,20,34,1,0,0,51,1,0,0,210,1,53,59,179,1,56, + 62,56,1,43,48,44,1,72,80,73,1,210,230,214,1,224,243,228,1,227, + 244,231,1,3,3,3,1,173,229,173,1,173,226,174,1,175,225,175,1,170, + 223,176,1,104,235,219,1,54,237,242,1,21,238,252,1,47,237,242,1,13, + 29,27,1,184,226,190,1,189,226,190,1,84,99,85,1,183,215,210,1,5, + 6,121,1,0,0,165,1,0,0,255,1,0,0,83,1,141,157,204,1,215, + 239,218,1,72,79,73,1,144,157,146,1,224,243,228,1,70,75,71,1,36, + 48,36,1,173,229,173,1,175,229,176,1,178,230,178,1,180,231,181,1,183, + 231,184,1,185,232,186,1,188,233,189,1,190,233,191,1,86,104,86,1,25, + 30,25,1,85,102,86,1,159,188,161,1,71,84,237,1,0,0,122,1,0, + 0,165,1,0,0,255,1,0,0,220,1,18,20,133,1,75,83,78,1,32, + 35,32,1,135,148,137,1,224,243,228,1,3,4,3,1,171,228,171,1,173, + 229,173,1,175,229,176,1,207,143,111,1,208,144,113,1,210,144,115,1,211, + 145,116,1,213,145,118,1,212,144,118,1,189,128,106,1,189,188,157,1,123, + 147,124,1,14,17,20,1,0,0,228,1,0,0,122,1,0,0,165,1,0, + 0,243,1,0,0,32,1,0,0,169,1,106,117,217,1,97,106,98,1,132, + 145,135,1,224,243,228,1,3,4,3,1,171,228,171,1,173,229,173,1,175, + 229,176,1,255,0,0,3,209,0,0,1,166,0,0,1,253,0,0,1,50, + 0,0,1,146,99,82,1,148,177,153,1,4,5,35,1,0,0,236,1,0, + 0,134,1,0,0,105,1,0,0,223,1,0,0,34,1,0,0,205,1,7, + 7,185,1,22,24,26,1,124,135,126,1,224,243,228,1,125,135,128,1,72, + 96,72,1,173,229,173,1,175,229,176,1,255,0,0,3,212,0,0,1,171, + 0,0,1,255,0,0,1,224,0,0,1,119,80,67,1,47,57,102,1,0, + 0,205,1,0,0,255,1,0,0,230,1,0,0,125,1,0,0,210,1,0, + 0,200,1,0,0,116,1,0,0,146,1,58,64,198,1,157,172,160,1,224, + 243,228,1,227,244,231,1,3,3,3,1,173,229,173,1,175,229,176,1,255, + 0,0,7,218,147,123,1,188,225,202,1,187,220,206,1,189,221,208,1,191, + 221,210,1,192,220,213,1,194,220,215,1,195,220,218,1,197,220,221,1,198, + 220,223,1,200,220,226,1,222,243,226,1,224,243,228,1,227,244,231,1,3, + 3,3,1,173,229,173,1,175,229,176,1,255,0,0,7,218,147,123,1,197, + 236,199,1,200,236,202,1,202,237,205,1,205,238,207,1,207,238,210,1,210, + 239,212,1,212,240,215,1,215,240,218,1,217,241,220,1,220,242,223,1,222, + 243,226,1,224,243,228,1,28,31,29,1,72,96,72,1,173,229,173,1,175, + 229,176,1,255,0,0,7,218,147,123,1,197,236,199,1,200,236,202,1,202, + 237,205,1,205,238,207,1,207,238,210,1,210,239,212,1,212,240,215,1,215, + 240,218,1,217,241,220,1,220,242,223,1,222,243,226,1,224,243,228,1,3, + 4,3,1,171,228,171,1,173,229,173,1,175,229,176,1,255,0,0,7,218, + 147,123,1,197,236,199,1,200,236,202,1,202,237,205,1,205,238,207,1,207, + 238,210,1,210,239,212,1,212,240,215,1,215,240,218,1,217,241,220,1,220, + 242,223,1,222,243,226,1,224,243,228,1,3,4,3,1,171,228,171,1,173, + 229,173,1,175,229,176,1,255,0,0,7,218,147,123,1,197,236,199,1,200, + 236,202,1,202,237,205,1,205,238,207,1,207,238,210,1,210,239,212,1,212, + 240,215,1,215,240,218,1,217,241,220,1,220,242,223,1,222,243,226,1,224, + 243,228,1,203,218,207,1,36,48,36,1,173,229,173,1,175,229,176,1,180, + 223,172,1,182,224,175,1,185,224,178,1,187,225,180,1,190,226,183,1,192, + 226,185,1,195,227,188,1,196,232,195,1,197,236,199,1,200,236,202,1,202, + 237,205,1,205,238,207,1,207,238,210,1,210,239,212,1,212,240,215,1,215, + 240,218,1,217,241,220,1,220,242,223,1,222,243,226,1,224,243,228,1,227, + 244,231,1,3,3,3,1,173,229,173,1,175,229,176,1,178,230,178,1,180, + 231,181,1,183,231,184,1,185,232,186,1,188,233,189,1,190,233,191,1,193, + 234,194,1,195,235,197,1,197,236,199,1,200,236,202,1,202,237,205,1,205, + 238,207,1,207,238,210,1,210,239,212,1,212,240,215,1,215,240,218,1,217, + 241,220,1,220,242,223,1,222,243,226,1,224,243,228,1,203,218,207,1,0, + 0,0,1,137,182,137,1,175,229,176,1,178,230,178,1,3,3,3,2,16, + 20,16,1,188,233,189,1,190,233,191,1,120,146,121,1,3,3,3,1,3, + 4,3,1,51,60,52,1,202,237,205,1,205,238,207,1,75,86,76,1,3, + 4,3,2,104,116,105,1,217,241,220,1,220,242,223,1,37,40,37,1,3, + 4,3,1,0,0,0,1,148,1,0,0,255,255,255,1,252,252,252,1,237, + 237,237,1,136,136,136,2,165,165,165,1,252,252,252,2,208,208,208,1,136, + 136,136,2,194,194,194,1,252,252,252,2,179,179,179,1,136,136,136,2,223, + 223,223,1,252,252,252,2,150,150,150,1,136,136,136,1,139,139,139,1,255, + 255,255,1,157,157,157,1,255,255,255,22,252,252,252,1,136,136,136,1,255, + 255,255,22,230,230,230,1,136,136,136,1,255,255,255,22,136,136,136,1,244, + 244,244,1,255,255,255,22,136,136,136,1,252,252,252,1,255,255,255,22,172, + 172,172,1,244,244,244,1,255,255,255,22,252,252,252,1,136,136,136,1,255, + 255,255,22,252,252,252,1,136,136,136,1,255,255,255,22,201,201,201,1,157, + 157,157,1,255,255,255,22,136,136,136,1,252,252,252,1,255,255,255,22,136, + 136,136,1,252,252,252,1,255,255,255,22,201,201,201,1,215,215,215,1,255, + 255,255,22,252,252,252,1,136,136,136,1,255,255,255,22,252,252,252,1,136, + 136,136,1,255,255,255,22,172,172,172,1,186,186,186,1,255,255,255,22,136, + 136,136,1,252,252,252,1,255,255,255,22,136,136,136,1,252,252,252,1,255, + 255,255,22,230,230,230,1,186,186,186,1,255,255,255,22,252,252,252,1,136, + 136,136,1,255,255,255,22,252,252,252,1,136,136,136,1,255,255,255,22,143, + 143,143,1,215,215,215,1,255,255,255,22,136,136,136,1,252,252,252,1,255, + 255,255,22,143,143,143,1,255,255,255,1,150,150,150,1,136,136,136,2,252, + 252,252,2,237,237,237,1,136,136,136,2,165,165,165,1,252,252,252,2,208, + 208,208,1,136,136,136,2,194,194,194,1,252,252,252,2,179,179,179,1,136, + 136,136,2,223,223,223,1,252,252,252,1,255,255,255,1,0,0) + ); + +const + objdata_tbitmapcomp: record size: integer; data: array[0..2014] of byte end = + (size: 2015; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,98,105, + 116,109,97,112,99,111,109,112,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,104,7,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,200,4,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,3,208,208,208,2,0,0,0, + 4,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,4,208,208,208, + 1,0,0,0,3,208,208,208,22,0,0,0,1,208,208,208,2,123,123,123, + 20,208,208,208,1,0,0,0,1,208,208,208,2,123,123,123,1,255,194,147, + 11,255,194,146,7,123,123,123,1,208,208,208,2,0,0,0,1,208,208,208, + 1,123,123,123,1,255,197,153,1,238,200,160,1,123,218,205,1,21,235,247, + 1,54,230,234,1,167,211,187,1,255,197,153,10,255,197,152,2,123,123,123, + 1,208,208,208,2,0,0,0,1,208,208,208,1,123,123,123,1,255,201,159, + 1,123,220,208,1,32,239,250,1,123,249,254,1,98,247,254,1,3,237,252, + 1,218,206,173,1,255,201,159,11,123,123,123,1,208,208,208,1,0,0,0, + 2,208,208,208,1,123,123,123,1,255,204,165,1,21,236,247,1,123,249,254, + 1,183,255,255,2,56,241,252,1,118,221,212,1,255,204,165,11,123,123,123, + 1,208,208,208,1,0,0,0,1,208,208,208,2,123,123,123,1,255,208,171, + 1,54,232,237,1,98,247,254,1,183,255,255,2,32,238,250,1,153,220,204, + 1,255,208,171,11,123,123,123,1,208,208,208,1,0,0,0,1,208,208,208, + 2,123,123,123,1,255,211,177,1,167,220,203,1,3,237,252,1,56,241,252, + 1,32,238,250,1,18,235,248,1,244,212,180,1,255,211,177,11,123,123,123, + 1,208,208,208,1,0,0,0,2,208,208,208,1,123,123,123,1,255,215,183, + 2,218,218,193,1,118,226,221,1,153,224,211,1,244,216,186,1,255,215,183, + 8,255,214,183,4,123,123,123,1,208,208,208,2,0,0,0,1,208,208,208, + 1,123,123,123,1,255,218,189,16,232,209,172,1,75,169,54,1,123,123,123, + 1,208,208,208,2,0,0,0,1,208,208,208,1,123,123,123,1,255,222,195, + 4,255,221,195,11,154,190,117,1,15,173,10,1,3,189,0,1,123,123,123, + 1,208,208,208,1,0,0,0,2,208,208,208,1,123,123,123,1,255,225,201, + 13,202,208,159,1,63,182,49,1,2,193,1,1,2,194,0,1,3,186,0, + 1,123,123,123,1,208,208,208,1,0,0,0,1,208,208,208,2,123,123,123, + 1,255,228,208,3,255,228,207,8,248,225,201,1,91,188,73,1,6,199,5, + 1,1,207,1,1,2,199,0,1,3,191,0,1,3,183,0,1,123,123,123, + 1,208,208,208,1,0,0,0,1,208,208,208,2,123,123,123,1,255,232,214, + 7,255,232,213,3,251,230,210,1,59,184,49,1,0,219,1,1,1,212,1, + 1,2,204,1,1,2,196,0,1,3,187,0,1,4,179,0,1,123,123,123, + 1,208,208,208,1,0,0,0,2,208,208,208,1,123,123,123,1,254,131,70, + 1,254,137,82,1,254,143,93,1,254,150,104,1,254,156,116,1,253,159,121, + 1,251,148,104,1,248,137,85,1,246,126,67,1,243,116,49,1,234,103,30, + 1,38,155,4,1,1,216,1,1,1,208,1,1,2,200,1,1,3,192,0, + 1,3,184,0,1,4,176,0,1,123,123,123,1,208,208,208,2,0,0,0, + 1,208,208,208,1,123,123,123,1,255,154,74,1,255,161,88,1,255,169,101, + 1,255,176,115,1,255,184,129,1,255,191,142,1,252,179,122,1,249,166,100, + 1,246,153,79,1,243,140,57,1,240,126,36,1,206,112,12,1,23,170,2, + 1,2,205,1,1,2,197,0,1,3,189,0,1,4,181,0,1,4,173,0, + 1,123,123,123,1,208,208,208,2,0,0,0,1,208,208,208,1,123,123,123, + 1,255,152,71,1,255,160,85,1,255,167,98,1,255,175,112,1,255,182,126, + 1,255,190,139,1,252,182,126,1,249,169,105,1,246,155,83,1,243,142,62, + 1,240,129,40,1,237,116,19,1,165,115,1,1,10,183,2,1,2,194,0, + 1,3,186,0,1,4,178,0,1,5,171,0,1,123,123,123,1,208,208,208, + 1,0,0,0,2,208,208,208,1,123,123,123,1,255,150,68,1,255,158,82, + 1,255,165,95,1,255,173,109,1,255,180,123,1,255,188,136,1,253,185,131, + 1,250,171,110,1,247,158,88,1,244,145,67,1,241,132,45,1,238,119,24, + 1,235,106,2,1,135,122,1,1,12,174,1,1,3,183,0,1,4,175,0, + 1,5,171,0,1,123,123,123,1,208,208,208,1,0,0,0,1,208,208,208, + 2,123,123,123,1,255,149,65,1,255,156,79,1,255,164,92,1,255,171,106, + 1,255,179,120,1,255,186,133,1,254,187,136,1,251,174,114,1,248,161,93, + 1,245,148,71,1,242,135,50,1,239,122,28,1,236,109,7,1,235,105,0, + 1,159,114,1,1,20,157,1,1,4,171,0,1,5,171,0,1,123,123,123, + 1,208,208,208,1,0,0,0,1,208,208,208,2,123,123,123,1,255,147,62, + 1,255,155,76,1,255,162,89,1,255,170,103,1,255,177,117,1,255,185,130, + 1,254,190,141,1,251,177,119,1,248,164,98,1,245,151,76,1,242,138,55, + 1,239,125,33,1,236,112,12,1,235,105,0,2,184,110,1,1,33,142,2, + 1,5,171,0,1,123,123,123,1,208,208,208,1,0,0,0,2,208,208,208, + 1,123,123,123,20,208,208,208,2,0,0,0,1,208,208,208,22,0,0,0, + 3,208,208,208,2,0,0,0,3,208,208,208,2,0,0,0,4,208,208,208, + 2,0,0,0,4,208,208,208,2,0,0,0,3,104,2,0,0,240,240,240, + 2,210,210,210,1,0,0,0,2,60,60,60,1,240,240,240,2,150,150,150, + 1,0,0,0,2,120,120,120,1,240,240,240,2,90,90,90,1,0,0,0, + 2,187,187,187,1,240,240,240,2,22,22,22,1,0,0,0,1,7,7,7, + 1,240,240,240,1,52,52,52,1,0,0,0,22,240,240,240,1,0,0,0, + 2,255,255,255,20,0,0,0,1,202,202,202,1,0,0,0,2,255,255,255, + 20,0,0,0,2,217,217,217,1,0,0,0,1,255,255,255,20,0,0,0, + 2,240,240,240,1,0,0,0,1,255,255,255,20,0,0,0,1,75,75,75, + 1,225,225,225,1,0,0,0,1,255,255,255,20,0,0,0,1,240,240,240, + 1,0,0,0,2,255,255,255,20,0,0,0,1,240,240,240,1,0,0,0, + 2,255,255,255,20,0,0,0,1,135,135,135,1,45,45,45,1,0,0,0, + 1,255,255,255,20,0,0,0,2,240,240,240,1,0,0,0,1,255,255,255, + 18,223,223,223,1,255,255,255,1,0,0,0,2,240,240,240,1,0,0,0, + 1,255,255,255,16,242,242,242,1,231,231,231,1,255,255,255,2,0,0,0, + 1,135,135,135,1,165,165,165,1,0,0,0,1,255,255,255,15,228,228,228, + 1,250,250,250,1,255,255,255,3,0,0,0,1,240,240,240,1,0,0,0, + 2,255,255,255,13,247,247,247,1,246,246,246,1,255,255,255,5,0,0,0, + 1,240,240,240,1,0,0,0,2,255,255,255,12,229,229,229,1,255,255,255, + 7,0,0,0,1,75,75,75,1,105,105,105,1,0,0,0,1,255,255,255, + 11,252,252,252,1,225,225,225,1,255,255,255,7,0,0,0,2,240,240,240, + 1,0,0,0,1,255,255,255,12,252,252,252,1,238,238,238,1,255,255,255, + 6,0,0,0,2,240,240,240,1,0,0,0,1,255,255,255,13,254,254,254, + 1,249,249,249,1,255,255,255,5,0,0,0,1,202,202,202,1,97,97,97, + 1,0,0,0,1,255,255,255,14,254,254,254,1,249,249,249,1,255,255,255, + 4,0,0,0,1,240,240,240,1,0,0,0,2,255,255,255,16,244,244,244, + 1,255,255,255,3,0,0,0,1,240,240,240,1,0,0,0,2,255,255,255, + 17,239,239,239,1,255,255,255,2,0,0,0,1,7,7,7,1,172,172,172, + 1,0,0,0,1,255,255,255,20,0,0,0,2,240,240,240,1,0,0,0, + 22,22,22,22,1,240,240,240,1,37,37,37,1,0,0,0,2,232,232,232, + 1,240,240,240,1,210,210,210,1,0,0,0,2,60,60,60,1,240,240,240, + 2,150,150,150,1,0,0,0,2,120,120,120,1,240,240,240,2,90,90,90, + 1,0,0,0,2,187,187,187,1,240,240,240,2,0,0) + ); + +const + objdata_ttimer: record size: integer; data: array[0..3217] of byte end = + (size: 3218; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,6,116,116,105, + 109,101,114,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114,101, + 110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112,46, + 111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,13, + 98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109,97, + 112,46,105,109,97,103,101,10,32,12,0,0,0,0,0,0,6,0,0,0, + 24,0,0,0,24,0,0,0,164,6,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,208,208,208,10,158,158,255,1,118,118,255,1,79,79,255,1, + 208,208,208,14,26,128,139,1,46,146,156,1,55,153,163,1,53,152,161,1, + 33,135,145,1,0,96,106,1,112,112,253,1,180,180,255,1,140,140,255,1, + 101,101,255,1,61,61,255,1,208,208,208,1,0,111,122,1,24,130,140,1, + 46,146,156,1,49,149,159,1,42,143,153,1,17,120,131,1,0,0,0,1, + 208,208,208,3,0,111,122,1,57,144,153,1,155,209,215,1,186,248,255,1, + 177,248,255,2,160,235,242,1,59,153,163,1,51,68,209,1,148,148,255,1, + 163,163,255,1,123,123,255,1,84,84,255,1,5,115,126,1,54,153,162,1, + 148,225,233,1,177,248,255,1,190,249,255,1,202,248,253,1,120,187,194,1, + 50,137,146,1,0,0,0,2,208,208,208,1,24,134,146,1,166,222,228,1, + 240,253,255,1,204,250,255,1,177,248,255,3,84,171,179,1,15,69,89,1, + 90,91,153,1,138,139,64,1,132,132,84,1,208,208,208,1,27,132,142,1, + 93,179,188,1,201,250,255,1,214,251,255,1,228,252,255,1,241,253,255,1, + 254,254,255,1,128,188,194,1,7,59,64,1,0,0,0,1,0,111,122,1, + 38,162,174,1,173,247,255,1,248,254,255,1,221,252,255,1,185,248,255,1, + 175,246,253,1,67,153,162,1,11,52,56,1,0,0,6,1,8,8,60,1, + 85,85,41,1,47,47,86,1,0,0,129,1,0,0,60,1,29,113,122,1, + 92,161,167,1,249,252,253,1,231,252,255,1,203,250,255,1,175,247,255,1, + 144,243,253,1,26,121,131,1,0,0,0,1,0,111,122,1,62,199,213,1, + 136,244,255,1,211,251,255,1,239,253,255,1,193,243,249,1,51,139,148,1, + 4,30,38,1,4,4,99,1,4,4,140,1,23,23,127,1,63,64,107,1, + 66,66,108,1,27,27,129,1,5,5,141,1,7,7,127,1,10,63,80,1, + 54,144,153,1,146,239,249,1,124,243,255,1,96,240,255,1,91,240,255,1, + 34,151,163,1,0,0,0,1,8,123,134,1,74,215,229,1,99,240,255,1, + 175,247,255,1,225,239,241,1,50,127,135,1,0,12,47,1,6,6,130,1, + 45,45,107,1,152,153,37,1,175,176,33,1,184,185,38,1,192,193,44,1, + 201,202,49,1,193,194,62,1,62,62,118,1,10,10,133,1,0,19,74,1, + 22,132,143,1,82,227,241,1,91,240,255,2,42,164,176,1,0,11,12,1, + 11,127,138,1,74,216,230,1,91,240,255,1,112,218,229,1,39,115,122,1, + 0,6,13,1,6,6,130,1,88,89,68,1,157,158,22,1,166,167,27,1, + 175,176,33,1,184,185,38,1,192,193,44,1,201,202,49,1,210,211,55,1, + 219,220,60,1,134,135,97,1,10,11,132,1,0,8,20,1,18,124,135,1, + 74,215,228,1,91,240,255,1,46,170,183,1,0,17,19,1,0,111,122,1, + 53,186,200,1,64,200,214,1,16,101,109,1,0,1,1,1,4,4,104,1, + 42,42,101,1,149,150,16,1,157,158,22,1,166,167,27,1,175,176,33,1, + 184,185,38,1,192,193,44,1,201,202,49,1,210,211,55,1,219,220,60,1, + 227,228,66,1,70,70,118,1,7,7,102,1,0,2,2,1,17,119,129,1, + 64,199,213,1,32,144,155,1,0,0,0,1,208,208,208,1,19,136,148,1, + 13,98,107,1,0,0,0,1,0,0,10,1,3,3,140,1,128,129,22,1, + 149,150,16,1,157,158,22,1,166,167,27,1,175,176,33,1,184,185,38,1, + 192,193,44,1,201,202,49,1,210,211,55,1,219,220,60,1,227,228,66,1, + 211,219,87,1,12,20,148,1,0,0,9,1,0,0,0,1,15,113,123,1, + 12,93,101,1,0,0,0,1,208,208,208,1,0,0,0,3,0,0,98,1, + 18,18,125,1,140,141,11,1,149,150,16,1,156,163,33,1,129,234,198,1, + 157,201,102,1,184,185,38,1,192,193,44,1,188,210,81,1,166,232,149,1, + 144,246,200,1,131,252,229,1,170,247,172,1,33,36,133,1,0,0,49,1, + 0,0,0,4,208,208,208,1,0,0,0,3,0,0,142,1,46,46,95,1, + 140,141,11,1,149,150,16,1,156,160,27,1,140,214,147,1,117,254,250,1, + 129,242,212,1,130,245,217,1,117,255,252,1,120,253,244,1,159,241,173,1, + 213,232,91,1,236,237,71,1,83,83,118,1,0,0,83,1,0,0,0,4, + 208,208,208,4,0,0,144,1,46,46,94,1,140,141,11,1,149,150,16,1, + 157,158,22,1,166,167,27,1,154,205,112,1,118,254,249,1,125,248,229,1, + 162,227,144,1,203,214,69,1,219,220,60,1,227,228,66,1,236,237,71,1, + 83,83,118,1,0,0,82,1,0,0,0,2,208,208,208,6,0,0,144,1, + 18,18,125,1,140,141,11,1,149,150,16,1,157,158,22,1,166,167,27,1, + 175,176,33,1,179,191,56,1,191,194,47,1,201,202,49,1,210,211,55,1, + 219,220,60,1,227,228,66,1,236,237,71,1,32,32,130,1,0,0,47,1, + 0,0,0,2,208,208,208,6,0,0,128,1,3,3,140,1,128,129,22,1, + 149,150,16,1,157,158,22,1,166,167,27,1,175,176,33,1,184,185,38,1, + 192,193,44,1,201,202,49,1,210,211,55,1,219,220,60,1,227,228,66,1, + 217,217,77,1,5,5,140,1,0,0,6,1,0,0,0,2,208,208,208,7, + 5,5,134,1,41,41,103,1,149,150,16,1,157,158,22,1,166,167,27,1, + 175,176,33,1,184,185,38,1,192,193,44,1,201,202,49,1,210,211,55,1, + 219,220,60,1,227,228,66,1,69,69,119,1,6,6,98,1,0,0,0,3, + 208,208,208,7,0,0,103,1,7,7,137,1,87,88,68,1,157,158,22,1, + 166,167,27,1,175,176,33,1,184,185,38,1,192,193,44,1,201,202,49,1, + 210,211,55,1,219,220,60,1,132,133,97,1,10,11,131,1,0,0,7,1, + 0,0,0,3,208,208,208,7,24,199,223,1,59,194,215,1,7,24,139,1, + 43,43,107,1,150,151,38,1,175,176,33,1,184,185,38,1,192,193,44,1, + 201,202,49,1,189,190,64,1,60,60,117,1,10,20,132,1,22,152,177,1, + 0,144,166,1,0,7,10,1,0,0,0,2,208,208,208,6,9,196,219,1, + 75,208,240,1,116,195,218,1,0,129,150,1,4,4,100,1,4,4,140,1, + 21,21,127,1,60,60,105,1,63,63,107,1,24,24,129,1,5,5,140,1, + 5,5,94,1,2,78,89,1,172,230,238,1,11,143,189,1,0,119,136,1, + 0,0,0,2,208,208,208,6,31,201,225,1,240,248,251,1,4,154,190,1, + 0,34,38,1,0,0,0,1,0,0,8,1,0,0,51,1,0,0,82,1, + 0,0,81,1,0,0,43,1,0,0,4,1,0,0,0,1,0,12,15,1, + 49,194,220,1,134,193,219,1,0,149,176,1,0,0,0,3,208,208,208,4, + 0,195,218,1,75,207,237,1,115,184,214,1,0,145,168,1,0,0,0,10, + 24,188,211,1,233,249,251,1,22,152,192,1,0,85,97,1,0,0,0,2, + 208,208,208,4,7,197,219,1,142,222,233,1,0,153,189,1,0,53,60,1, + 0,0,0,10,0,176,208,1,45,198,225,1,110,199,219,1,0,110,125,1, + 0,0,0,2,208,208,208,4,0,0,0,1,12,172,190,1,0,107,122,1, + 0,0,0,3,208,208,208,9,11,164,180,1,23,141,154,1,0,2,2,1, + 0,0,0,2,208,208,208,5,0,0,0,5,208,208,208,9,0,0,0,5, + 208,208,208,1,68,5,0,0,0,0,0,10,1,1,1,1,43,43,43,1, + 32,32,32,1,0,0,0,14,72,72,72,1,175,175,175,1,184,184,184,1, + 186,186,186,1,134,134,134,1,28,28,28,1,129,129,129,1,239,239,239,1, + 255,255,255,1,206,206,206,1,3,3,3,1,0,0,0,1,12,12,12,1, + 107,107,107,1,177,177,177,1,178,178,178,1,174,174,174,1,53,53,53,1, + 1,1,1,1,0,0,0,3,2,2,2,1,186,186,186,1,242,242,242,1, + 255,255,255,4,220,220,220,1,124,124,124,1,255,255,255,3,39,39,39,1, + 32,32,32,1,213,213,213,1,252,252,252,1,255,255,255,3,235,235,235,1, + 153,153,153,1,8,8,8,1,1,1,1,1,0,0,0,1,127,127,127,1, + 249,249,249,1,255,255,255,5,241,241,241,1,160,160,160,1,176,176,176,1, + 255,255,255,1,64,64,64,1,0,0,0,1,85,85,85,1,230,230,230,1, + 255,255,255,5,242,242,242,1,93,93,93,1,14,14,14,1,13,13,13,1, + 221,221,221,1,255,255,255,5,239,239,239,1,168,168,168,1,129,129,129,1, + 123,123,123,1,185,185,185,1,140,140,140,1,59,59,59,1,13,13,13,1, + 77,77,77,1,231,231,231,1,255,255,255,5,214,214,214,1,64,64,64,1, + 48,48,48,1,244,244,244,1,255,255,255,4,235,235,235,1,158,158,158,1, + 198,198,198,1,251,251,251,1,242,242,242,1,246,246,246,1,247,247,247,1, + 244,244,244,1,250,250,250,1,156,156,156,1,76,76,76,1,226,226,226,1, + 255,255,255,4,238,238,238,1,109,109,109,1,84,84,84,1,255,255,255,4, + 228,228,228,1,162,162,162,1,238,238,238,1,248,248,248,1,255,255,255,6, + 249,249,249,1,235,235,235,1,103,103,103,1,215,215,215,1,254,254,254,1, + 255,255,255,2,242,242,242,1,136,136,136,1,91,91,91,1,255,255,255,2, + 252,252,252,1,219,219,219,1,141,141,141,1,236,236,236,1,254,254,254,1, + 255,255,255,9,237,237,237,1,92,92,92,1,199,199,199,1,252,252,252,1, + 255,255,255,1,243,243,243,1,144,144,144,1,28,28,28,1,236,236,236,1, + 246,246,246,1,206,206,206,1,133,133,133,1,189,189,189,1,247,247,247,1, + 255,255,255,10,250,250,250,1,195,195,195,1,67,67,67,1,174,174,174,1, + 247,247,247,1,232,232,232,1,133,133,133,1,0,0,0,1,181,181,181,1, + 161,161,161,1,125,125,125,1,104,104,104,1,250,250,250,1,255,255,255,12, + 252,252,252,1,115,115,115,1,39,39,39,1,141,141,141,1,171,171,171,1, + 121,121,121,1,0,0,0,1,5,5,5,1,45,45,45,1,79,79,79,1, + 78,78,78,1,241,241,241,1,255,255,255,12,248,248,248,1,155,155,155,1, + 69,69,69,1,14,14,14,1,31,31,31,1,71,71,71,1,0,0,0,1, + 1,1,1,1,6,6,6,1,11,11,11,1,108,108,108,1,246,246,246,1, + 255,255,255,12,250,250,250,1,185,185,185,1,97,97,97,1,14,14,14,1, + 3,3,3,1,10,10,10,1,0,0,0,4,106,106,106,1,246,246,246,1, + 255,255,255,12,250,250,250,1,187,187,187,1,114,114,114,1,17,17,17,1, + 0,0,0,6,53,53,53,1,241,241,241,1,255,255,255,12,248,248,248,1, + 162,162,162,1,113,113,113,1,17,17,17,1,0,0,0,6,6,6,6,1, + 249,249,249,1,255,255,255,12,252,252,252,1,138,138,138,1,96,96,96,1, + 14,14,14,1,0,0,0,7,146,146,146,1,247,247,247,1,255,255,255,10, + 250,250,250,1,204,204,204,1,128,128,128,1,68,68,68,1,9,9,9,1, + 0,0,0,7,10,10,10,1,226,226,226,1,254,254,254,1,255,255,255,9, + 240,240,240,1,140,140,140,1,111,111,111,1,31,31,31,1,3,3,3,1, + 0,0,0,7,146,146,146,1,196,196,196,1,230,230,230,1,249,249,249,1, + 255,255,255,6,250,250,250,1,239,239,239,1,225,225,225,1,211,211,211,1, + 75,75,75,1,17,17,17,1,2,2,2,1,0,0,0,6,56,56,56,1, + 239,239,239,1,255,255,255,1,166,166,166,1,186,186,186,1,251,251,251,1, + 248,248,248,1,250,250,250,2,249,249,249,1,252,252,252,1,200,200,200,1, + 168,168,168,1,254,254,254,1,252,252,252,1,154,154,154,1,47,47,47,1, + 8,8,8,1,0,0,0,6,181,181,181,1,255,255,255,1,235,235,235,1, + 140,140,140,1,100,100,100,1,61,61,61,1,126,126,126,1,171,171,171,1, + 172,172,172,1,148,148,148,1,123,123,123,1,118,118,118,1,102,102,102,1, + 222,222,222,1,255,255,255,1,225,225,225,1,94,94,94,1,20,20,20,1, + 2,2,2,1,0,0,0,4,34,34,34,1,233,233,233,1,255,255,255,1, + 209,209,209,1,131,131,131,1,77,77,77,1,23,23,23,1,16,16,16,1, + 27,27,27,1,46,46,46,1,59,59,59,1,46,46,46,1,27,27,27,1, + 16,16,16,1,148,148,148,1,255,255,255,1,249,249,249,1,160,160,160,1, + 55,55,55,1,9,9,9,1,0,0,0,4,70,70,70,1,246,246,246,1, + 240,240,240,1,154,154,154,1,113,113,113,1,40,40,40,1,6,6,6,1, + 1,1,1,1,2,2,2,1,5,5,5,1,8,8,8,1,5,5,5,1, + 2,2,2,1,1,1,1,1,16,16,16,1,225,225,225,1,251,251,251,1, + 186,186,186,1,91,91,91,1,18,18,18,1,0,0,0,4,1,1,1,1, + 110,110,110,1,136,136,136,1,117,117,117,1,79,79,79,1,21,21,21,1, + 0,0,0,9,67,67,67,1,143,143,143,1,112,112,112,1,87,87,87,1, + 20,20,20,1,0,0,0,5,4,4,4,1,32,32,32,1,57,57,57,1, + 21,21,21,1,4,4,4,1,0,0,0,9,2,2,2,1,24,24,24,1, + 49,49,49,1,36,36,36,1,7,7,7,1,0,0,0,1,0,0) + ); + +const + objdata_tanimtimer: record size: integer; data: array[0..3109] of byte end = + (size: 3110; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,97,110, + 105,109,116,105,109,101,114,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,176,11,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,52,6,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,10,128,128,255,1,121,121,255,1, + 82,82,255,1,0,0,0,13,0,85,85,1,33,133,143,1,48,149,159,1, + 59,157,167,1,57,155,165,1,39,139,149,1,0,99,107,1,113,113,253,1, + 181,181,255,1,141,141,255,1,103,103,255,1,64,64,255,1,0,0,0,1, + 0,112,128,1,31,136,146,1,51,150,160,1,58,157,165,1,49,148,158,1, + 27,129,140,1,0,0,0,4,0,113,113,1,61,147,155,1,179,224,228,1, + 187,249,255,1,177,248,255,2,167,240,247,1,69,162,171,1,50,73,203,1, + 148,148,255,1,164,164,255,1,124,124,255,1,83,83,255,1,25,130,140,1, + 66,162,172,1,158,234,241,1,177,248,255,1,191,249,255,1,204,250,255,1, + 159,214,219,1,49,137,144,1,0,0,0,3,31,141,153,1,190,237,242,1, + 240,254,255,1,204,250,255,1,177,248,255,3,84,169,178,1,17,66,90,1, + 90,90,150,1,139,139,65,1,118,118,95,1,4,4,253,1,8,26,234,1, + 37,69,229,1,82,102,254,1,88,102,254,1,93,103,254,1,99,104,254,1, + 159,160,254,1,150,202,207,1,22,91,97,1,0,0,0,1,0,109,128,1, + 45,171,183,1,173,248,255,1,249,254,255,1,222,252,255,1,186,249,255,1, + 174,246,253,1,64,152,161,1,9,50,55,1,0,0,17,1,7,7,80,1, + 87,87,40,1,48,48,84,1,2,2,183,1,3,3,252,1,3,3,253,5, + 67,94,254,1,147,245,255,1,30,129,139,1,0,0,0,1,4,120,131,1, + 68,207,221,1,136,244,255,1,212,251,255,1,240,254,255,1,193,243,248,1, + 49,138,146,1,5,28,48,1,7,7,108,1,5,5,140,1,45,46,113,1, + 80,80,99,1,83,83,101,1,52,52,117,1,6,6,162,1,4,4,245,1, + 3,3,253,2,3,3,249,1,3,3,253,1,38,92,254,1,91,240,255,1, + 37,155,167,1,0,7,7,1,16,133,144,1,79,223,237,1,100,241,255,1, + 175,248,255,1,225,239,240,1,51,129,137,1,0,14,51,1,6,6,133,1, + 70,70,89,1,157,157,35,1,175,176,33,1,184,185,39,1,193,194,44,1, + 202,203,50,1,197,198,61,1,63,63,156,1,3,3,253,4,36,91,254,1, + 91,240,255,1,51,177,191,1,0,23,26,1,15,134,143,1,77,220,235,1, + 91,240,255,1,110,215,226,1,37,115,122,1,0,5,27,1,6,6,133,1, + 96,97,61,1,158,159,22,1,167,168,28,1,175,176,33,1,184,185,39,1, + 193,194,44,1,202,203,50,1,174,175,90,1,21,21,237,1,3,3,253,4, + 29,80,243,1,91,240,255,1,47,172,184,1,0,18,19,1,5,118,128,1, + 61,196,210,1,63,197,211,1,15,102,109,1,0,0,0,1,6,6,111,1, + 62,62,84,1,149,150,17,1,158,159,22,1,167,168,28,1,175,176,33,1, + 184,185,39,1,193,194,44,1,167,168,86,1,20,20,237,1,3,3,253,1, + 22,22,237,1,67,68,160,1,4,4,243,1,3,3,253,1,7,36,216,1, + 62,196,209,1,31,143,154,1,0,0,0,2,22,141,151,1,12,98,106,1, + 0,0,0,1,0,0,23,1,4,4,139,1,132,133,18,1,149,150,17,1, + 158,159,22,1,167,168,28,1,175,176,33,1,184,185,39,1,162,163,78,1, + 22,22,234,1,3,3,253,1,21,21,237,1,185,190,105,1,203,228,107,1, + 13,21,166,1,3,3,241,1,3,3,230,1,14,114,123,1,14,99,107,1, + 0,0,0,5,0,0,115,1,35,35,107,1,140,141,11,1,149,150,17,1, + 157,164,33,1,129,234,197,1,156,201,103,1,154,155,74,1,21,21,233,1, + 3,3,253,1,17,22,245,1,116,204,218,1,121,254,245,1,166,248,178,1, + 63,69,129,1,0,0,110,1,3,3,201,1,0,0,0,7,0,0,143,1, + 58,59,83,1,140,141,11,1,149,150,17,1,157,162,28,1,140,215,148,1, + 98,210,251,1,14,23,250,1,3,3,253,1,13,24,253,1,101,209,244,1, + 159,240,172,1,214,232,91,1,237,238,72,1,106,106,113,1,0,0,86,1, + 0,0,14,1,0,0,0,7,0,0,144,1,57,58,84,1,140,141,11,1, + 149,150,17,1,158,159,22,1,140,141,64,1,17,22,240,1,3,3,253,1, + 13,23,250,1,139,185,154,1,206,213,64,1,219,220,61,1,228,229,66,1, + 237,238,72,1,104,104,113,1,0,0,86,1,0,0,0,8,0,0,143,1, + 34,34,108,1,140,141,11,1,149,150,17,1,133,133,59,1,19,19,232,1, + 3,3,253,1,18,19,237,1,159,162,83,1,202,203,50,1,210,211,55,1, + 219,220,61,1,228,229,66,1,237,238,72,1,59,59,123,1,0,0,66,1, + 0,0,0,8,0,0,136,1,4,4,140,1,131,132,20,1,125,126,55,1, + 18,18,231,1,3,3,253,1,17,17,235,1,153,153,77,1,193,194,44,1, + 202,203,50,1,210,211,55,1,219,220,61,1,228,229,66,1,219,220,78,1, + 7,7,140,1,0,0,14,1,0,0,0,9,6,6,134,1,50,50,114,1, + 17,17,231,1,3,3,253,1,17,17,234,1,145,146,72,1,184,185,39,1, + 193,194,44,1,202,203,50,1,210,211,55,1,219,220,61,1,228,229,66,1, + 95,95,112,1,10,10,106,1,0,0,0,10,0,0,213,1,4,4,243,1, + 3,3,253,1,16,16,234,1,139,139,68,1,175,176,33,1,184,185,39,1, + 193,194,44,1,202,203,50,1,210,211,55,1,219,220,61,1,141,142,95,1, + 10,10,134,1,0,0,19,1,0,0,0,9,0,0,255,1,4,14,251,1, + 3,3,253,1,3,4,244,1,53,53,122,1,155,155,37,1,175,176,33,1, + 184,185,39,1,193,194,44,1,202,203,50,1,194,194,62,1,87,87,109,1, + 10,19,136,1,24,150,175,1,0,139,161,1,0,9,9,1,0,0,0,7, + 0,0,255,1,3,8,252,1,3,3,253,1,13,19,250,1,1,97,181,1, + 6,6,109,1,5,5,139,1,39,39,114,1,74,75,100,1,78,79,102,1, + 44,44,119,1,6,6,140,1,7,9,102,1,3,73,93,1,176,232,240,1, + 12,145,188,1,0,128,146,1,0,0,0,6,0,0,255,1,3,3,253,2, + 23,23,253,1,4,129,204,1,0,43,48,1,0,0,0,1,0,0,23,1, + 0,0,74,1,0,0,89,1,0,0,87,1,0,0,66,1,0,0,14,1, + 0,0,0,1,0,12,14,1,49,195,220,1,134,193,220,1,0,156,183,1, + 0,3,3,1,0,0,0,6,2,28,248,1,9,19,252,1,95,153,221,1, + 0,152,176,1,0,0,0,10,23,189,209,1,229,248,251,1,23,155,194,1, + 0,92,106,1,0,0,0,6,11,191,210,1,135,202,235,1,0,155,191,1, + 0,61,68,1,0,0,0,10,0,138,149,1,45,197,223,1,113,199,220,1, + 0,110,125,1,0,0,0,7,16,166,184,1,0,113,130,1,0,0,0,12, + 12,157,177,1,26,139,152,1,0,3,3,1,0,0,0,27,68,5,0,0, + 0,0,0,10,2,2,2,1,42,42,42,1,31,31,31,1,0,0,0,13, + 3,3,3,1,107,107,107,1,180,180,180,1,195,195,195,1,187,187,187,1, + 152,152,152,1,31,31,31,1,133,133,133,1,240,240,240,1,255,255,255,1, + 204,204,204,1,4,4,4,1,0,0,0,1,16,16,16,1,131,131,131,1, + 180,180,180,1,189,189,189,1,178,178,178,1,93,93,93,1,1,1,1,1, + 0,0,0,3,9,9,9,1,193,193,193,1,250,250,250,1,255,255,255,4, + 227,227,227,1,137,137,137,1,255,255,255,3,40,40,40,1,51,51,51,1, + 219,219,219,1,255,255,255,4,246,246,246,1,166,166,166,1,9,9,9,1, + 1,1,1,1,0,0,0,1,165,165,165,1,254,254,254,1,255,255,255,5, + 241,241,241,1,162,162,162,1,178,178,178,1,255,255,255,1,67,67,67,1, + 132,132,132,1,185,185,185,1,245,245,245,1,255,255,255,5,246,246,246,1, + 129,129,129,1,18,18,18,1,14,14,14,1,222,222,222,1,255,255,255,5, + 239,239,239,1,168,168,168,1,134,134,134,1,143,143,143,1,193,193,193,1, + 148,148,148,1,117,117,117,1,236,236,236,1,255,255,255,7,222,222,222,1, + 76,76,76,1,72,72,72,1,251,251,251,1,255,255,255,4,235,235,235,1, + 164,164,164,1,208,208,208,1,250,250,250,1,243,243,243,1,251,251,251,2, + 244,244,244,1,250,250,250,1,249,249,249,1,255,255,255,6,240,240,240,1, + 117,117,117,1,113,113,113,1,255,255,255,4,231,231,231,1,165,165,165,1, + 244,244,244,1,251,251,251,1,255,255,255,6,253,253,253,1,255,255,255,6, + 246,246,246,1,146,146,146,1,105,105,105,1,255,255,255,2,252,252,252,1, + 220,220,220,1,149,149,149,1,244,244,244,1,254,254,254,1,255,255,255,12, + 254,254,254,1,255,255,255,1,244,244,244,1,145,145,145,1,52,52,52,1, + 243,243,243,1,246,246,246,1,206,206,206,1,133,133,133,1,202,202,202,1, + 251,251,251,1,255,255,255,10,253,253,253,1,251,251,251,1,255,255,255,1, + 225,225,225,1,246,246,246,1,233,233,233,1,134,134,134,1,1,1,1,1, + 176,176,176,1,164,164,164,1,125,125,125,1,110,110,110,1,249,249,249,1, + 255,255,255,12,252,252,252,1,243,243,243,1,176,176,176,1,141,141,141,1, + 176,176,176,1,122,122,122,1,0,0,0,1,6,6,6,1,44,44,44,1, + 78,78,78,1,104,104,104,1,242,242,242,1,255,255,255,12,248,248,248,1, + 183,183,183,1,171,171,171,1,16,16,16,1,31,31,31,1,73,73,73,1, + 0,0,0,1,1,1,1,1,6,6,6,1,11,11,11,1,118,118,118,1, + 250,250,250,1,255,255,255,12,252,252,252,1,190,190,190,1,109,109,109,1, + 16,16,16,1,3,3,3,1,10,10,10,1,0,0,0,4,115,115,115,1, + 250,250,250,1,255,255,255,12,252,252,252,1,190,190,190,1,117,117,117,1, + 18,18,18,1,0,0,0,6,82,82,82,1,241,241,241,1,255,255,255,12, + 248,248,248,1,175,175,175,1,117,117,117,1,18,18,18,1,0,0,0,6, + 15,15,15,1,248,248,248,1,255,255,255,12,252,252,252,1,143,143,143,1, + 104,104,104,1,16,16,16,1,0,0,0,7,162,162,162,1,251,251,251,1, + 255,255,255,10,252,252,252,1,210,210,210,1,129,129,129,1,73,73,73,1, + 10,10,10,1,0,0,0,7,60,60,60,1,253,253,253,1,255,255,255,9, + 254,254,254,1,244,244,244,1,146,146,146,1,115,115,115,1,34,34,34,1, + 3,3,3,1,0,0,0,6,41,41,41,1,244,244,244,1,255,255,255,1, + 254,254,254,1,253,253,253,1,255,255,255,6,252,252,252,1,244,244,244,1, + 224,224,224,1,208,208,208,1,81,81,81,1,22,22,22,1,4,4,4,1, + 0,0,0,5,41,41,41,1,237,237,237,1,255,255,255,2,178,178,178,1, + 197,197,197,1,251,251,251,1,248,248,248,1,251,251,251,2,248,248,248,1, + 251,251,251,1,209,209,209,1,172,172,172,1,253,253,253,1,252,252,252,1, + 150,150,150,1,47,47,47,1,12,12,12,1,1,1,1,1,0,0,0,3, + 23,23,23,1,234,234,234,1,255,255,255,2,240,240,240,1,132,132,132,1, + 91,91,91,1,76,76,76,1,148,148,148,1,178,178,178,1,181,181,181,1, + 165,165,165,1,130,130,130,1,119,119,119,1,107,107,107,1,224,224,224,1, + 255,255,255,1,226,226,226,1,83,83,83,1,29,29,29,1,5,5,5,1, + 1,1,1,1,0,0,0,3,138,138,138,1,253,253,253,1,255,255,255,1, + 206,206,206,1,113,113,113,1,73,73,73,1,26,26,26,1,19,19,19,1, + 36,36,36,1,54,54,54,1,63,63,63,1,54,54,54,1,35,35,35,1, + 19,19,19,1,154,154,154,1,255,255,255,1,249,249,249,1,149,149,149,1, + 60,60,60,1,13,13,13,1,1,1,1,1,0,0,0,3,68,68,68,1, + 247,247,247,1,239,239,239,1,142,142,142,1,105,105,105,1,44,44,44,1, + 12,12,12,1,2,2,2,1,3,3,3,1,7,7,7,1,8,8,8,1, + 7,7,7,1,3,3,3,1,2,2,2,1,24,24,24,1,226,226,226,1, + 250,250,250,1,176,176,176,1,82,82,82,1,21,21,21,1,2,2,2,1, + 0,0,0,3,2,2,2,1,112,112,112,1,122,122,122,1,95,95,95,1, + 77,77,77,1,22,22,22,1,2,2,2,1,0,0,0,7,1,1,1,1, + 65,65,65,1,138,138,138,1,93,93,93,1,69,69,69,1,25,25,25,1, + 2,2,2,1,0,0,0,3,1,1,1,1,6,6,6,1,35,35,35,1, + 50,50,50,1,30,30,30,1,10,10,10,1,1,1,1,1,0,0,0,7, + 1,1,1,1,8,8,8,1,25,25,25,1,45,45,45,1,36,36,36,1, + 7,7,7,1,1,1,1,1,0,0) + ); + +const + objdata_tanimitemcomp: record size: integer; data: array[0..1280] of byte end = + (size: 1281; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,97,110, + 105,109,105,116,101,109,99,111,109,112,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,136,4,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,224,1,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,156,156,156,25,0,0,0,22,156, + 156,156,2,0,0,0,22,156,156,156,2,0,0,0,12,3,3,252,1,3, + 3,253,7,0,0,0,2,156,156,156,2,0,0,0,13,2,2,253,1,3, + 3,253,6,0,0,0,2,156,156,156,2,0,0,0,14,2,2,253,1,3, + 3,253,2,3,3,249,1,3,3,253,2,0,0,0,2,156,156,156,2,0, + 0,0,14,6,6,255,1,3,3,253,5,0,0,0,2,156,156,156,2,0, + 0,0,13,6,6,255,1,3,3,253,6,0,0,0,2,156,156,156,2,0, + 0,0,12,6,6,255,1,3,3,253,3,6,6,255,1,2,2,253,1,3, + 3,253,2,0,0,0,2,156,156,156,2,0,0,0,11,0,0,255,1,3, + 3,253,3,6,6,255,1,0,0,0,2,3,3,253,2,0,0,0,2,156, + 156,156,2,0,0,0,10,6,6,255,1,3,3,253,3,6,6,255,1,0, + 0,0,4,3,3,252,1,0,0,0,2,156,156,156,2,0,0,0,9,0, + 0,255,1,3,3,253,3,6,6,255,1,0,0,0,8,156,156,156,2,0, + 0,0,8,0,0,255,1,3,3,253,3,6,6,255,1,0,0,0,9,156, + 156,156,2,0,0,0,7,0,0,255,1,3,3,253,3,6,6,255,1,0, + 0,0,10,156,156,156,2,0,0,0,6,0,0,255,1,3,3,253,3,6, + 6,255,1,0,0,0,11,156,156,156,2,0,0,0,5,0,0,255,1,3, + 3,253,3,6,6,255,1,0,0,0,12,156,156,156,2,0,0,0,4,0, + 0,255,1,3,3,253,3,6,6,255,1,0,0,0,13,156,156,156,2,0, + 0,0,3,0,0,255,1,3,3,253,3,6,6,255,1,0,0,0,14,156, + 156,156,2,0,0,0,2,0,0,255,1,3,3,253,3,6,6,255,1,0, + 0,0,15,156,156,156,2,0,0,0,2,3,3,254,1,3,3,253,2,6, + 6,255,1,0,0,0,16,156,156,156,2,0,0,0,2,0,0,255,1,3, + 3,254,1,6,6,255,1,0,0,0,17,156,156,156,2,0,0,0,22,156, + 156,156,2,0,0,0,22,156,156,156,25,112,2,0,0,255,255,255,25,0, + 0,0,22,255,255,255,2,0,0,0,22,255,255,255,2,0,0,0,12,93, + 93,93,1,237,237,237,1,238,238,238,5,230,230,230,1,0,0,0,2,255, + 255,255,2,0,0,0,13,108,108,108,1,254,254,254,1,255,255,255,4,246, + 246,246,1,0,0,0,2,255,255,255,2,0,0,0,14,108,108,108,1,254, + 254,254,1,255,255,255,3,246,246,246,1,0,0,0,2,255,255,255,2,0, + 0,0,14,45,45,45,1,241,241,241,1,255,255,255,3,246,246,246,1,0, + 0,0,2,255,255,255,2,0,0,0,13,45,45,45,1,234,234,234,1,255, + 255,255,1,241,241,241,1,254,254,254,1,255,255,255,1,246,246,246,1,0, + 0,0,2,255,255,255,2,0,0,0,12,45,45,45,1,234,234,234,1,255, + 255,255,1,234,234,234,1,45,45,45,1,108,108,108,1,254,254,254,1,246, + 246,246,1,0,0,0,2,255,255,255,2,0,0,0,11,41,41,41,1,231, + 231,231,1,255,255,255,1,234,234,234,1,45,45,45,1,0,0,0,2,102, + 102,102,1,245,245,245,1,0,0,0,2,255,255,255,2,0,0,0,10,45, + 45,45,1,234,234,234,1,255,255,255,1,234,234,234,1,45,45,45,1,0, + 0,0,4,100,100,100,1,0,0,0,2,255,255,255,2,0,0,0,9,41, + 41,41,1,231,231,231,1,255,255,255,1,234,234,234,1,45,45,45,1,0, + 0,0,8,255,255,255,2,0,0,0,8,41,41,41,1,231,231,231,1,255, + 255,255,1,234,234,234,1,45,45,45,1,0,0,0,9,255,255,255,2,0, + 0,0,7,41,41,41,1,231,231,231,1,255,255,255,1,234,234,234,1,45, + 45,45,1,0,0,0,10,255,255,255,2,0,0,0,6,41,41,41,1,231, + 231,231,1,255,255,255,1,234,234,234,1,45,45,45,1,0,0,0,11,255, + 255,255,2,0,0,0,5,41,41,41,1,231,231,231,1,255,255,255,1,234, + 234,234,1,45,45,45,1,0,0,0,12,255,255,255,2,0,0,0,4,41, + 41,41,1,231,231,231,1,255,255,255,1,234,234,234,1,45,45,45,1,0, + 0,0,13,255,255,255,2,0,0,0,3,41,41,41,1,231,231,231,1,255, + 255,255,1,234,234,234,1,45,45,45,1,0,0,0,14,255,255,255,2,0, + 0,0,2,41,41,41,1,231,231,231,1,255,255,255,1,234,234,234,1,45, + 45,45,1,0,0,0,15,255,255,255,2,0,0,0,2,177,177,177,1,255, + 255,255,1,234,234,234,1,45,45,45,1,0,0,0,16,255,255,255,2,0, + 0,0,2,14,14,14,1,177,177,177,1,45,45,45,1,0,0,0,17,255, + 255,255,2,0,0,0,22,255,255,255,2,0,0,0,22,255,255,255,25,0, + 0) + ); + +const + objdata_tpipereadercomp: record size: integer; data: array[0..2074] of byte end = + (size: 2075; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,112,105, + 112,101,114,101,97,100,101,114,99,111,109,112,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,160,7,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,108,4,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,208,208,208,26,153,102,102, + 1,142,85,85,1,208,208,208,21,128,96,96,1,188,161,162,1,210,184,185, + 1,196,165,165,1,182,149,150,1,161,124,126,1,143,98,98,1,208,208,208, + 17,173,142,142,1,245,233,234,1,249,241,242,1,245,233,235,1,241,226,227, + 1,237,217,219,1,215,189,191,1,195,162,165,1,184,149,150,1,169,133,133, + 1,152,111,111,1,128,85,85,1,208,208,208,12,187,149,151,1,235,209,211, + 1,239,218,219,1,243,227,228,1,247,236,237,1,248,240,242,1,245,233,234, + 1,241,225,227,1,237,217,219,1,233,210,212,1,222,194,197,1,196,162,164, + 1,187,150,152,1,176,137,137,1,146,104,106,1,255,0,0,1,208,208,208, + 8,186,142,143,1,224,183,185,1,228,192,194,1,232,201,203,1,235,210,212, + 1,239,219,220,1,243,228,229,1,247,237,238,1,248,240,241,1,244,232,233, + 1,240,224,226,1,237,217,219,1,215,187,189,1,163,112,114,1,167,97,99, + 1,146,88,88,1,130,87,87,1,208,208,208,7,184,129,131,1,213,157,160, + 1,217,166,168,1,220,175,177,1,224,184,186,1,228,193,195,1,232,202,204, + 1,236,211,212,1,240,220,221,1,244,229,230,1,247,238,239,1,243,233,234, + 1,171,128,129,1,200,127,129,1,196,118,121,1,192,109,112,1,149,90,93, + 1,139,93,93,1,208,208,208,6,176,111,113,1,201,131,134,1,205,140,143, + 1,209,149,152,1,213,158,161,1,217,167,169,1,221,176,178,1,225,185,187, + 1,228,194,196,1,232,203,204,1,236,212,213,1,198,168,168,1,200,147,149, + 1,208,146,149,1,204,137,140,1,200,128,131,1,185,114,117,1,140,90,92, + 1,208,208,208,6,166,92,96,1,190,105,109,1,194,114,117,1,198,123,126, + 1,202,132,135,1,206,141,144,1,210,150,153,1,213,159,161,1,217,168,170, + 1,221,177,179,1,225,186,188,1,175,135,136,1,220,175,177,1,216,166,168, + 1,212,156,159,1,208,147,150,1,204,138,141,1,150,98,100,1,208,208,208, + 3,0,0,157,1,208,208,208,2,159,87,88,1,181,83,87,1,183,88,92, + 1,187,97,101,1,191,106,109,1,194,115,118,1,198,124,127,1,202,133,136, + 1,206,142,145,1,210,151,153,1,214,160,162,1,179,139,141,1,229,194,196, + 1,225,185,187,1,221,175,178,1,217,166,168,1,212,157,159,1,161,111,112, + 1,208,208,208,2,0,0,157,1,7,7,167,1,208,208,208,2,148,86,88, + 1,180,83,87,1,181,83,87,3,183,89,93,1,187,98,102,1,191,107,110, + 1,195,116,119,1,199,125,128,1,201,132,135,1,184,149,151,1,237,213,215, + 1,233,204,205,1,229,194,196,1,222,183,187,1,80,66,176,1,104,77,145, + 1,92,46,104,1,208,208,208,1,15,15,177,1,19,19,183,1,208,208,208, + 2,128,64,64,1,156,85,86,1,180,83,87,1,181,83,87,5,184,90,94, + 1,187,99,102,1,185,106,109,1,197,168,169,1,245,232,233,1,241,223,224, + 1,237,214,215,1,109,96,188,1,61,60,235,1,60,60,234,1,30,29,193, + 1,15,15,177,1,32,32,200,1,43,43,215,1,0,0,157,1,208,208,208, + 2,128,64,64,1,150,85,85,1,161,84,85,1,180,83,87,1,181,83,87, + 5,180,83,87,1,179,141,142,1,246,235,236,1,249,242,243,1,245,233,234, + 1,180,166,209,1,101,92,192,1,56,48,178,1,33,33,200,1,50,50,224, + 1,69,69,249,1,67,67,247,1,14,14,176,1,208,208,208,2,0,0,0, + 2,11,7,7,1,96,55,57,1,145,74,76,1,180,83,87,1,181,83,87, + 4,171,125,126,1,237,218,220,1,242,227,228,1,246,235,236,1,250,243,244, + 1,245,233,234,1,171,138,140,1,0,0,157,1,32,32,200,1,73,73,255, + 1,51,51,226,1,13,13,175,1,208,208,208,2,0,0,0,4,4,2,2, + 1,88,49,51,1,142,74,76,1,180,83,87,1,181,83,87,2,162,106,107, + 1,229,202,205,1,233,210,212,1,237,218,220,1,241,226,228,1,245,234,235, + 1,159,126,126,1,17,17,179,1,47,47,220,1,20,20,184,1,10,10,170, + 1,208,208,208,4,0,0,0,5,4,2,2,1,84,50,50,1,141,73,76, + 1,179,83,87,1,167,89,91,1,202,166,169,1,225,193,196,1,229,202,204, + 1,233,210,212,1,212,186,187,1,84,60,110,1,8,8,167,1,10,10,170, + 1,208,208,208,7,0,0,0,6,2,2,2,1,80,47,47,1,139,73,75, + 1,160,107,108,1,221,188,191,1,225,193,196,1,221,188,191,1,134,101,102, + 1,5,2,32,1,0,0,0,2,208,208,208,9,0,0,0,6,2,0,0, + 1,83,49,49,1,151,103,105,1,159,121,122,1,130,94,96,1,20,13,13, + 1,0,0,0,3,208,208,208,11,0,0,0,6,2,0,0,1,16,11,11, + 1,0,0,0,5,208,208,208,13,0,0,0,10,208,208,208,16,0,0,0, + 7,208,208,208,77,252,2,0,0,0,0,0,26,5,5,5,1,9,9,9, + 1,0,0,0,21,8,8,8,1,195,195,195,1,233,233,233,1,193,193,193, + 1,151,151,151,1,109,109,109,1,34,34,34,1,0,0,0,17,124,124,124, + 1,255,255,255,5,247,247,247,1,209,209,209,1,168,168,168,1,127,127,127, + 1,69,69,69,1,6,6,6,1,0,0,0,12,164,164,164,1,255,255,255, + 9,254,254,254,1,225,225,225,1,185,185,185,1,144,144,144,1,102,102,102, + 1,1,1,1,1,0,0,0,8,196,196,196,1,255,255,255,13,249,249,249, + 1,211,211,211,1,47,47,47,1,0,0,0,7,224,224,224,1,255,255,255, + 15,206,206,206,1,11,11,11,1,0,0,0,6,214,214,214,1,255,255,255, + 15,253,253,253,1,111,111,111,1,0,0,0,6,191,191,191,1,255,255,255, + 16,189,189,189,1,0,0,0,3,2,2,2,1,0,0,0,2,168,168,168, + 1,255,255,255,16,212,212,212,1,0,0,0,2,16,16,16,1,137,137,137, + 1,0,0,0,2,110,110,110,1,255,255,255,16,236,236,236,1,11,11,11, + 1,0,0,0,1,152,152,152,1,215,215,215,1,0,0,0,2,4,4,4, + 1,180,180,180,1,255,255,255,15,254,254,254,1,215,215,215,1,146,146,146, + 1,222,222,222,1,238,238,238,1,40,40,40,1,0,0,0,2,4,4,4, + 1,117,117,117,1,211,211,211,1,255,255,255,13,247,247,247,1,223,223,223, + 1,250,250,250,1,255,255,255,2,143,143,143,1,0,0,0,2,1,1,1, + 1,13,13,13,1,69,69,69,1,176,176,176,1,231,231,231,1,255,255,255, + 11,210,210,210,1,34,34,34,1,226,226,226,1,255,255,255,1,244,244,244, + 1,172,172,172,1,0,0,0,2,1,1,1,1,11,11,11,1,57,57,57, + 1,99,99,99,1,128,128,128,1,186,186,186,1,231,231,231,1,255,255,255, + 9,183,183,183,1,171,171,171,1,245,245,245,1,200,200,200,1,83,83,83, + 1,0,0,0,4,2,2,2,1,11,11,11,1,29,29,29,1,70,70,70, + 1,105,105,105,1,129,129,129,1,185,185,185,1,230,230,230,1,255,255,255, + 6,250,250,250,1,130,130,130,1,214,214,214,1,83,83,83,1,0,0,0, + 7,1,1,1,1,3,3,3,1,13,13,13,1,31,31,31,1,72,72,72, + 1,108,108,108,1,129,129,129,1,184,184,184,1,229,229,229,1,255,255,255, + 4,222,222,222,1,101,101,101,1,20,20,20,1,1,1,1,1,0,0,0, + 9,1,1,1,1,3,3,3,1,14,14,14,1,35,35,35,1,76,76,76, + 1,110,110,110,1,129,129,129,1,187,187,187,1,248,248,248,1,246,246,246, + 1,224,224,224,1,141,141,141,1,96,96,96,1,24,24,24,1,2,2,2, + 1,0,0,0,11,1,1,1,1,4,4,4,1,15,15,15,1,38,38,38, + 1,79,79,79,1,113,113,113,1,128,128,128,1,138,138,138,1,124,124,124, + 1,97,97,97,1,44,44,44,1,8,8,8,1,1,1,1,1,0,0,0, + 13,1,1,1,1,4,4,4,1,16,16,16,1,41,41,41,1,71,71,71, + 1,74,74,74,1,63,63,63,1,31,31,31,1,8,8,8,1,1,1,1, + 1,0,0,0,16,1,1,1,1,5,5,5,1,12,12,12,2,10,10,10, + 1,4,4,4,1,1,1,1,1,0,0,0,77,0,0) + ); + +const + objdata_tthreadcomp: record size: integer; data: array[0..1306] of byte end = + (size: 1307; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,116,104, + 114,101,97,100,99,111,109,112,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,164,4,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,208,2,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,208,208,208,101,36,169,33,1,35,169,33, + 1,36,182,36,1,208,208,208,21,32,167,32,1,35,170,33,1,35,169,33, + 1,35,168,31,1,208,208,208,22,35,168,31,1,35,169,33,1,35,170,33, + 1,32,167,32,1,208,208,208,21,36,182,36,1,35,169,33,3,36,182,36, + 1,208,208,208,21,32,167,32,1,35,169,34,1,35,169,33,1,35,168,31, + 1,208,208,208,14,138,220,255,1,141,222,255,1,208,208,208,6,35,168,31, + 1,35,169,33,1,35,170,33,1,32,167,32,1,208,208,208,2,117,216,255, + 1,138,220,255,1,208,208,208,8,180,233,255,1,144,222,255,1,146,219,255, + 1,208,208,208,6,36,182,36,1,35,169,33,1,36,169,33,1,208,208,208, + 1,134,219,255,1,155,224,255,1,180,233,255,1,208,208,208,8,221,245,255, + 1,146,223,255,1,146,222,255,1,35,169,33,1,208,208,208,1,35,169,33, + 1,208,208,208,1,35,169,33,1,208,208,208,1,35,169,33,1,208,208,208, + 1,35,169,33,1,208,208,208,1,182,233,255,1,198,238,255,1,221,245,255, + 1,208,208,208,8,248,251,253,1,149,223,255,1,148,223,255,1,35,169,33, + 1,163,228,255,1,35,169,33,1,163,228,255,1,35,169,33,1,163,228,255, + 1,35,169,33,1,163,228,255,1,35,169,33,1,163,228,255,1,225,246,255, + 1,241,250,255,1,248,251,253,1,208,208,208,8,215,234,243,1,136,214,247, + 1,143,219,251,1,35,169,33,1,255,255,255,1,35,169,33,1,255,255,255, + 1,35,169,33,1,255,255,255,1,35,169,33,1,255,255,255,1,35,169,33, + 1,255,255,255,1,244,249,251,1,231,243,248,1,215,234,243,1,208,208,208, + 8,181,217,233,1,115,199,235,1,123,205,239,1,35,169,33,1,181,217,233, + 1,35,169,33,1,181,217,233,1,35,169,33,1,181,217,233,1,35,169,33, + 1,181,217,233,1,35,169,33,1,181,217,233,1,210,232,241,1,197,225,238, + 1,181,217,233,1,208,208,208,8,148,200,223,1,94,185,223,1,102,190,227, + 1,35,169,33,1,109,180,212,1,35,169,33,1,109,180,212,1,35,169,33, + 1,109,180,212,1,35,169,33,1,109,180,212,1,35,169,33,1,109,180,212, + 1,175,214,231,1,163,208,227,1,148,200,223,1,208,208,208,8,115,184,214, + 1,74,171,211,1,81,176,215,1,35,169,33,1,36,143,190,1,35,169,33, + 1,36,143,190,1,35,169,33,1,36,143,190,1,35,169,33,1,36,143,190, + 1,35,169,33,1,36,143,190,1,141,197,221,1,128,190,217,1,115,184,214, + 1,208,208,208,8,82,167,204,1,53,156,199,1,62,161,204,1,35,169,33, + 1,208,208,208,1,35,169,33,1,208,208,208,1,35,169,33,1,208,208,208, + 1,35,169,33,1,208,208,208,1,35,169,33,1,208,208,208,1,107,179,212, + 1,94,173,207,1,82,167,204,1,208,208,208,8,49,150,194,1,33,142,187, + 1,36,146,194,1,208,208,208,10,73,158,206,1,60,155,197,1,49,150,194, + 1,208,208,208,8,16,133,184,1,12,126,177,1,208,208,208,12,24,138,186, + 1,16,133,184,1,208,208,208,100,156,1,0,0,0,0,0,101,208,208,208, + 1,124,124,124,1,7,7,7,1,0,0,0,21,32,32,32,1,176,176,176, + 1,219,219,219,1,73,73,73,1,0,0,0,22,73,73,73,1,219,219,219, + 1,176,176,176,1,32,32,32,1,0,0,0,21,7,7,7,1,124,124,124, + 1,236,236,236,1,124,124,124,1,7,7,7,1,0,0,0,21,32,32,32, + 1,175,175,175,1,219,219,219,1,73,73,73,1,0,0,0,14,255,255,255, + 1,85,85,85,1,0,0,0,6,73,73,73,1,219,219,219,1,176,176,176, + 1,32,32,32,1,0,0,0,2,85,85,85,1,255,255,255,1,0,0,0, + 8,255,255,255,1,234,234,234,1,21,21,21,1,0,0,0,6,7,7,7, + 1,124,124,124,1,208,208,208,1,0,0,0,1,21,21,21,1,234,234,234, + 1,255,255,255,1,0,0,0,8,255,255,255,2,170,170,170,1,255,255,255, + 1,0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,1,0,0,0, + 1,255,255,255,1,0,0,0,1,255,255,255,1,0,0,0,1,170,170,170, + 1,255,255,255,2,0,0,0,8,255,255,255,16,0,0,0,8,255,255,255, + 16,0,0,0,8,255,255,255,16,0,0,0,8,255,255,255,16,0,0,0, + 8,255,255,255,16,0,0,0,8,255,255,255,2,170,170,170,1,255,255,255, + 1,0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,1,0,0,0, + 1,255,255,255,1,0,0,0,1,255,255,255,1,0,0,0,1,170,170,170, + 1,255,255,255,2,0,0,0,8,255,255,255,1,234,234,234,1,21,21,21, + 1,0,0,0,10,21,21,21,1,234,234,234,1,255,255,255,1,0,0,0, + 8,255,255,255,1,85,85,85,1,0,0,0,12,85,85,85,1,255,255,255, + 1,0,0,0,100,0,0) + ); + +const + objdata_tframecomp: record size: integer; data: array[0..1469] of byte end = + (size: 1470; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,102,114, + 97,109,101,99,111,109,112,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,72,5,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,156,2,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,3,208,208,208,2,0,0,0,4, + 208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,4,208,208,208,1, + 0,0,0,3,208,208,208,22,0,0,0,1,208,208,208,2,255,255,255,20, + 208,208,208,1,0,0,0,1,208,208,208,2,255,255,255,1,102,102,102,19, + 208,208,208,2,0,0,0,1,208,208,208,1,255,255,255,1,102,102,102,1, + 208,208,208,16,255,255,255,1,102,102,102,1,208,208,208,2,0,0,0,1, + 208,208,208,1,255,255,255,1,102,102,102,1,208,208,208,16,255,255,255,1, + 102,102,102,1,208,208,208,1,0,0,0,2,208,208,208,1,255,255,255,1, + 102,102,102,1,208,208,208,16,255,255,255,1,102,102,102,1,208,208,208,1, + 0,0,0,1,208,208,208,2,255,255,255,1,102,102,102,1,208,208,208,16, + 255,255,255,1,102,102,102,1,208,208,208,1,0,0,0,1,208,208,208,2, + 255,255,255,1,102,102,102,1,208,208,208,16,255,255,255,1,102,102,102,1, + 208,208,208,1,0,0,0,2,208,208,208,1,255,255,255,1,102,102,102,1, + 208,208,208,16,255,255,255,1,102,102,102,1,208,208,208,2,0,0,0,1, + 208,208,208,1,255,255,255,1,102,102,102,1,208,208,208,16,255,255,255,1, + 102,102,102,1,208,208,208,2,0,0,0,1,208,208,208,1,255,255,255,1, + 102,102,102,1,208,208,208,16,255,255,255,1,102,102,102,1,208,208,208,1, + 0,0,0,2,208,208,208,1,255,255,255,1,102,102,102,1,208,208,208,16, + 255,255,255,1,102,102,102,1,208,208,208,1,0,0,0,1,208,208,208,2, + 255,255,255,1,102,102,102,1,208,208,208,16,255,255,255,1,102,102,102,1, + 208,208,208,1,0,0,0,1,208,208,208,2,255,255,255,1,102,102,102,1, + 208,208,208,16,255,255,255,1,102,102,102,1,208,208,208,1,0,0,0,2, + 208,208,208,1,255,255,255,1,102,102,102,1,208,208,208,16,255,255,255,1, + 102,102,102,1,208,208,208,2,0,0,0,1,208,208,208,1,255,255,255,1, + 102,102,102,1,208,208,208,16,255,255,255,1,102,102,102,1,208,208,208,2, + 0,0,0,1,208,208,208,1,255,255,255,1,102,102,102,1,208,208,208,16, + 255,255,255,1,102,102,102,1,208,208,208,1,0,0,0,2,208,208,208,1, + 255,255,255,1,102,102,102,1,208,208,208,16,255,255,255,1,102,102,102,1, + 208,208,208,1,0,0,0,1,208,208,208,2,255,255,255,1,102,102,102,1, + 208,208,208,16,255,255,255,1,102,102,102,1,208,208,208,1,0,0,0,1, + 208,208,208,2,255,255,255,19,102,102,102,1,208,208,208,1,0,0,0,2, + 208,208,208,1,102,102,102,20,208,208,208,2,0,0,0,1,208,208,208,22, + 0,0,0,3,208,208,208,2,0,0,0,3,208,208,208,2,0,0,0,4, + 208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,3,116,2,0,0, + 240,240,240,2,210,210,210,1,0,0,0,2,60,60,60,1,240,240,240,2, + 150,150,150,1,0,0,0,2,120,120,120,1,240,240,240,2,90,90,90,1, + 0,0,0,2,187,187,187,1,240,240,240,2,22,22,22,1,0,0,0,1, + 7,7,7,1,240,240,240,1,52,52,52,1,0,0,0,22,240,240,240,1, + 0,0,0,2,255,255,255,20,0,0,0,1,202,202,202,1,0,0,0,2, + 255,255,255,20,0,0,0,2,217,217,217,1,0,0,0,1,255,255,255,2, + 0,0,0,16,255,255,255,2,0,0,0,2,240,240,240,1,0,0,0,1, + 255,255,255,2,0,0,0,16,255,255,255,2,0,0,0,1,75,75,75,1, + 225,225,225,1,0,0,0,1,255,255,255,2,0,0,0,16,255,255,255,2, + 0,0,0,1,240,240,240,1,0,0,0,2,255,255,255,2,0,0,0,16, + 255,255,255,2,0,0,0,1,240,240,240,1,0,0,0,2,255,255,255,2, + 0,0,0,16,255,255,255,2,0,0,0,1,135,135,135,1,45,45,45,1, + 0,0,0,1,255,255,255,2,0,0,0,16,255,255,255,2,0,0,0,2, + 240,240,240,1,0,0,0,1,255,255,255,2,0,0,0,16,255,255,255,2, + 0,0,0,2,240,240,240,1,0,0,0,1,255,255,255,2,0,0,0,16, + 255,255,255,2,0,0,0,1,135,135,135,1,165,165,165,1,0,0,0,1, + 255,255,255,2,0,0,0,16,255,255,255,2,0,0,0,1,240,240,240,1, + 0,0,0,2,255,255,255,2,0,0,0,16,255,255,255,2,0,0,0,1, + 240,240,240,1,0,0,0,2,255,255,255,2,0,0,0,16,255,255,255,2, + 0,0,0,1,75,75,75,1,105,105,105,1,0,0,0,1,255,255,255,2, + 0,0,0,16,255,255,255,2,0,0,0,2,240,240,240,1,0,0,0,1, + 255,255,255,2,0,0,0,16,255,255,255,2,0,0,0,2,240,240,240,1, + 0,0,0,1,255,255,255,2,0,0,0,16,255,255,255,2,0,0,0,1, + 202,202,202,1,97,97,97,1,0,0,0,1,255,255,255,2,0,0,0,16, + 255,255,255,2,0,0,0,1,240,240,240,1,0,0,0,2,255,255,255,2, + 0,0,0,16,255,255,255,2,0,0,0,1,240,240,240,1,0,0,0,2, + 255,255,255,20,0,0,0,1,7,7,7,1,172,172,172,1,0,0,0,1, + 255,255,255,20,0,0,0,2,240,240,240,1,0,0,0,22,22,22,22,1, + 240,240,240,1,37,37,37,1,0,0,0,2,232,232,232,1,240,240,240,1, + 210,210,210,1,0,0,0,2,60,60,60,1,240,240,240,2,150,150,150,1, + 0,0,0,2,120,120,120,1,240,240,240,2,90,90,90,1,0,0,0,2, + 187,187,187,1,240,240,240,2,0,0) + ); + +const + objdata_tfacecomp: record size: integer; data: array[0..2460] of byte end = + (size: 2461; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,102,97, + 99,101,99,111,109,112,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,40,9,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,96,7,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,3,208,208,208,2,0,0,0,4,208, + 208,208,2,0,0,0,4,208,208,208,2,0,0,0,4,208,208,208,1,0, + 0,0,3,22,240,255,3,21,237,255,1,21,231,255,1,20,225,255,1,20, + 220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17, + 191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14, + 155,255,1,14,147,255,1,13,140,255,1,13,132,255,1,13,129,255,2,0, + 0,0,1,208,208,208,1,22,240,255,3,21,237,255,1,21,231,255,1,20, + 225,255,1,20,220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18, + 197,255,1,17,191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15, + 163,255,1,14,155,255,1,14,147,255,1,13,140,255,1,13,132,255,1,13, + 129,255,2,0,0,0,1,208,208,208,1,22,240,255,3,21,237,255,1,21, + 231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19,208,255,1,18, + 202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16,178,255,1,16, + 170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13,140,255,1,13, + 132,255,1,13,129,255,2,208,208,208,1,0,0,0,1,22,240,255,3,21, + 237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19, + 208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16, + 178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13, + 140,255,1,13,132,255,1,13,129,255,2,208,208,208,1,0,0,0,1,22, + 240,255,3,21,237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19, + 214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17, + 185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14, + 147,255,1,13,140,255,1,13,132,255,1,13,129,255,2,0,0,0,2,22, + 240,255,3,21,237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19, + 214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17, + 185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14, + 147,255,1,13,140,255,1,13,132,255,1,13,129,255,2,0,0,0,1,208, + 208,208,1,22,240,255,3,21,237,255,1,21,231,255,1,20,225,255,1,20, + 220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17, + 191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14, + 155,255,1,14,147,255,1,13,140,255,1,13,132,255,1,13,129,255,2,0, + 0,0,1,208,208,208,1,22,240,255,3,21,237,255,1,21,231,255,1,20, + 225,255,1,20,220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18, + 197,255,1,17,191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15, + 163,255,1,14,155,255,1,14,147,255,1,13,140,255,1,13,132,255,1,13, + 129,255,2,0,0,0,2,22,240,255,3,21,237,255,1,21,231,255,1,20, + 225,255,1,20,220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18, + 197,255,1,17,191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15, + 163,255,1,14,155,255,1,14,147,255,1,13,140,255,1,13,132,255,1,13, + 129,255,2,208,208,208,1,0,0,0,1,22,240,255,3,21,237,255,1,21, + 231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19,208,255,1,18, + 202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16,178,255,1,16, + 170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13,140,255,1,13, + 132,255,1,13,129,255,2,208,208,208,1,0,0,0,1,22,240,255,3,21, + 237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19, + 208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16, + 178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13, + 140,255,1,13,132,255,1,13,129,255,2,0,0,0,2,22,240,255,3,21, + 237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19, + 208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16, + 178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13, + 140,255,1,13,132,255,1,13,129,255,2,0,0,0,1,208,208,208,1,22, + 240,255,3,21,237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19, + 214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17, + 185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14, + 147,255,1,13,140,255,1,13,132,255,1,13,129,255,2,0,0,0,1,208, + 208,208,1,22,240,255,3,21,237,255,1,21,231,255,1,20,225,255,1,20, + 220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17, + 191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14, + 155,255,1,14,147,255,1,13,140,255,1,13,132,255,1,13,129,255,2,0, + 0,0,2,22,240,255,3,21,237,255,1,21,231,255,1,20,225,255,1,20, + 220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17, + 191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14, + 155,255,1,14,147,255,1,13,140,255,1,13,132,255,1,13,129,255,2,208, + 208,208,1,0,0,0,1,22,240,255,3,21,237,255,1,21,231,255,1,20, + 225,255,1,20,220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18, + 197,255,1,17,191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15, + 163,255,1,14,155,255,1,14,147,255,1,13,140,255,1,13,132,255,1,13, + 129,255,2,208,208,208,1,0,0,0,1,22,240,255,3,21,237,255,1,21, + 231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19,208,255,1,18, + 202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16,178,255,1,16, + 170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13,140,255,1,13, + 132,255,1,13,129,255,2,0,0,0,2,22,240,255,3,21,237,255,1,21, + 231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19,208,255,1,18, + 202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16,178,255,1,16, + 170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13,140,255,1,13, + 132,255,1,13,129,255,2,0,0,0,1,208,208,208,1,22,240,255,3,21, + 237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19, + 208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16, + 178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13, + 140,255,1,13,132,255,1,13,129,255,2,0,0,0,1,208,208,208,1,22, + 240,255,3,21,237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19, + 214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17, + 185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14, + 147,255,1,13,140,255,1,13,132,255,1,13,129,255,2,0,0,0,2,22, + 240,255,3,21,237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19, + 214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17, + 185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14, + 147,255,1,13,140,255,1,13,132,255,1,13,129,255,2,208,208,208,1,0, + 0,0,1,22,240,255,3,21,237,255,1,21,231,255,1,20,225,255,1,20, + 220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17, + 191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14, + 155,255,1,14,147,255,1,13,140,255,1,13,132,255,1,13,129,255,2,0, + 0,0,3,208,208,208,2,0,0,0,3,208,208,208,2,0,0,0,4,208, + 208,208,2,0,0,0,4,208,208,208,2,0,0,0,3,144,1,0,0,240, + 240,240,2,210,210,210,1,0,0,0,2,60,60,60,1,240,240,240,2,150, + 150,150,1,0,0,0,2,120,120,120,1,240,240,240,2,90,90,90,1,0, + 0,0,2,187,187,187,1,240,240,240,2,22,22,22,1,0,0,0,1,7, + 7,7,1,240,240,240,1,52,52,52,1,255,255,255,22,240,240,240,1,0, + 0,0,1,255,255,255,22,202,202,202,1,0,0,0,1,255,255,255,22,0, + 0,0,1,217,217,217,1,255,255,255,22,0,0,0,1,240,240,240,1,255, + 255,255,22,75,75,75,1,225,225,225,1,255,255,255,22,240,240,240,1,0, + 0,0,1,255,255,255,22,240,240,240,1,0,0,0,1,255,255,255,22,135, + 135,135,1,45,45,45,1,255,255,255,22,0,0,0,1,240,240,240,1,255, + 255,255,22,0,0,0,1,240,240,240,1,255,255,255,22,135,135,135,1,165, + 165,165,1,255,255,255,22,240,240,240,1,0,0,0,1,255,255,255,22,240, + 240,240,1,0,0,0,1,255,255,255,22,75,75,75,1,105,105,105,1,255, + 255,255,22,0,0,0,1,240,240,240,1,255,255,255,22,0,0,0,1,240, + 240,240,1,255,255,255,22,202,202,202,1,97,97,97,1,255,255,255,22,240, + 240,240,1,0,0,0,1,255,255,255,22,240,240,240,1,0,0,0,1,255, + 255,255,22,7,7,7,1,172,172,172,1,255,255,255,22,0,0,0,1,240, + 240,240,1,255,255,255,22,22,22,22,1,240,240,240,1,37,37,37,1,0, + 0,0,2,232,232,232,1,240,240,240,1,210,210,210,1,0,0,0,2,60, + 60,60,1,240,240,240,2,150,150,150,1,0,0,0,2,120,120,120,1,240, + 240,240,2,90,90,90,1,0,0,0,2,187,187,187,1,240,240,240,2,0, + 0) + ); + +const + objdata_tfontcomp: record size: integer; data: array[0..2316] of byte end = + (size: 2317; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,102,111, + 110,116,99,111,109,112,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,152,8,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,220,2,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,3,208,208,208,2,0,0,0,4,208, + 208,208,2,0,0,0,4,208,208,208,2,0,0,0,4,208,208,208,1,0, + 0,0,3,208,208,208,22,0,0,0,1,208,208,208,2,0,0,0,6,208, + 208,208,15,0,0,0,1,208,208,208,2,0,0,0,6,208,208,208,12,0, + 0,0,2,208,208,208,2,0,0,0,1,208,208,208,1,0,0,0,2,208, + 208,208,6,0,0,0,1,208,208,208,3,0,0,0,1,208,208,208,1,0, + 0,0,2,208,208,208,1,0,0,0,3,208,208,208,2,0,0,0,1,208, + 208,208,1,0,0,0,2,208,208,208,4,0,0,0,5,208,208,208,1,0, + 0,0,8,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,8,208, + 208,208,1,0,0,0,5,208,208,208,1,0,0,0,2,208,208,208,1,0, + 0,0,2,208,208,208,1,0,0,0,1,208,208,208,2,0,0,0,2,208, + 208,208,4,0,0,0,2,208,208,208,2,0,0,0,4,208,208,208,1,0, + 0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,1,208, + 208,208,2,0,0,0,2,208,208,208,4,0,0,0,2,208,208,208,1,0, + 0,0,5,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208, + 208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,4,0, + 0,0,5,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208, + 208,208,1,0,0,0,2,208,208,208,2,0,0,0,1,208,208,208,1,0, + 0,0,2,208,208,208,6,0,0,0,2,208,208,208,2,0,0,0,2,208, + 208,208,1,0,0,0,2,208,208,208,1,0,0,0,3,208,208,208,1,0, + 0,0,1,208,208,208,22,0,0,0,2,208,208,208,22,0,0,0,1,208, + 208,208,2,0,0,0,2,208,208,208,15,0,0,0,2,208,208,208,2,0, + 0,0,1,208,208,208,2,0,0,0,2,208,208,208,15,0,0,0,2,208, + 208,208,2,0,0,0,19,208,208,208,1,0,0,0,2,208,208,208,3,0, + 0,0,1,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,16,208, + 208,208,3,0,0,0,1,208,208,208,1,0,0,0,2,208,208,208,1,0, + 0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,4,208, + 208,208,2,0,0,0,4,208,208,208,2,0,0,0,2,208,208,208,1,0, + 0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208, + 208,208,1,0,0,0,4,208,208,208,2,0,0,0,4,208,208,208,2,0, + 0,0,1,208,208,208,2,0,0,0,5,208,208,208,1,0,0,0,2,208, + 208,208,1,0,0,0,10,208,208,208,2,0,0,0,1,208,208,208,2,0, + 0,0,5,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,7,208, + 208,208,1,0,0,0,2,208,208,208,2,0,0,0,2,208,208,208,12,0, + 0,0,2,208,208,208,9,0,0,0,1,208,208,208,12,0,0,0,2,208, + 208,208,8,0,0,0,3,208,208,208,2,0,0,0,3,208,208,208,2,0, + 0,0,4,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,3,132, + 5,0,0,240,240,240,2,210,210,210,1,0,0,0,2,60,60,60,1,240, + 240,240,2,150,150,150,1,0,0,0,2,120,120,120,1,240,240,240,2,90, + 90,90,1,0,0,0,2,187,187,187,1,240,240,240,2,22,22,22,1,0, + 0,0,1,7,7,7,1,240,240,240,1,52,52,52,1,0,0,0,22,240, + 240,240,1,0,0,0,2,2,2,2,1,8,8,8,4,4,4,4,1,0, + 0,0,15,202,202,202,1,0,0,0,2,94,94,94,1,238,238,238,1,216, + 216,216,3,115,115,115,1,0,0,0,12,123,123,123,1,5,5,5,1,0, + 0,0,2,217,217,217,1,0,0,0,1,94,94,94,1,145,145,145,1,0, + 0,0,6,10,10,10,1,0,0,0,3,5,5,5,1,0,0,0,1,9, + 9,9,1,5,5,5,1,0,0,0,1,4,4,4,1,218,218,218,1,14, + 14,14,1,0,0,0,2,240,240,240,1,0,0,0,1,94,94,94,1,145, + 145,145,1,0,0,0,4,10,10,10,1,170,170,170,1,182,182,182,1,190, + 190,190,1,92,92,92,1,0,0,0,1,176,176,176,1,136,136,136,1,164, + 164,164,1,225,225,225,1,59,59,59,1,88,88,88,1,243,243,243,1,166, + 166,166,1,0,0,0,1,75,75,75,1,225,225,225,1,0,0,0,1,94, + 94,94,1,238,238,238,1,216,216,216,3,1,1,1,1,118,118,118,1,147, + 147,147,1,0,0,0,1,8,8,8,1,219,219,219,1,3,3,3,1,176, + 176,176,1,121,121,121,1,0,0,0,1,93,93,93,1,145,145,145,1,0, + 0,0,1,217,217,217,1,6,6,6,1,0,0,0,1,240,240,240,1,0, + 0,0,2,94,94,94,1,145,145,145,1,0,0,0,4,155,155,155,1,82, + 82,82,1,0,0,0,2,187,187,187,1,53,53,53,1,176,176,176,1,60, + 60,60,1,0,0,0,1,72,72,72,1,151,151,151,1,0,0,0,1,217, + 217,217,1,6,6,6,1,0,0,0,1,240,240,240,1,0,0,0,2,94, + 94,94,1,145,145,145,1,0,0,0,4,92,92,92,1,128,128,128,1,0, + 0,0,1,1,1,1,1,233,233,233,1,23,23,23,1,176,176,176,1,55, + 55,55,1,0,0,0,1,72,72,72,1,151,151,151,1,0,0,0,1,216, + 216,216,1,7,7,7,1,0,0,0,1,135,135,135,1,45,45,45,1,0, + 0,0,1,94,94,94,1,145,145,145,1,0,0,0,4,14,14,14,1,199, + 199,199,1,135,135,135,1,178,178,178,1,153,153,153,1,0,0,0,1,176, + 176,176,1,55,55,55,1,0,0,0,1,72,72,72,1,151,151,151,1,0, + 0,0,1,192,192,192,1,148,148,148,1,0,0,0,2,240,240,240,1,0, + 0,0,1,23,23,23,1,36,36,36,1,0,0,0,6,60,60,60,1,47, + 47,47,1,0,0,0,2,44,44,44,1,13,13,13,1,0,0,0,1,18, + 18,18,1,37,37,37,1,0,0,0,1,21,21,21,1,71,71,71,1,2, + 2,2,1,0,0,0,1,240,240,240,1,0,0,0,22,135,135,135,1,165, + 165,165,1,0,0,0,22,240,240,240,1,0,0,0,2,16,16,16,1,56, + 56,56,1,0,0,0,15,118,118,118,1,56,56,56,1,0,0,0,2,240, + 240,240,1,0,0,0,2,94,94,94,1,129,129,129,1,0,0,0,15,151, + 151,151,1,72,72,72,1,0,0,0,2,75,75,75,1,105,105,105,1,4, + 4,4,1,210,210,210,1,220,220,220,1,75,75,75,1,147,147,147,1,120, + 120,120,1,196,196,196,1,157,157,157,1,46,46,46,1,165,165,165,1,157, + 157,157,1,5,5,5,1,49,49,49,1,145,145,145,1,179,179,179,1,183, + 183,183,1,70,70,70,1,0,0,0,1,151,151,151,1,72,72,72,1,0, + 0,0,3,240,240,240,1,0,0,0,1,94,94,94,1,129,129,129,1,0, + 0,0,1,189,189,189,1,126,126,126,1,3,3,3,1,191,191,191,1,163, + 163,163,1,3,3,3,1,155,155,155,1,73,73,73,1,63,63,63,1,241, + 241,241,1,29,29,29,1,23,23,23,1,224,224,224,1,18,18,18,1,151, + 151,151,1,72,72,72,1,0,0,0,3,240,240,240,1,0,0,0,1,94, + 94,94,1,129,129,129,1,0,0,0,1,189,189,189,1,53,53,53,1,0, + 0,0,1,149,149,149,1,82,82,82,1,0,0,0,1,125,125,125,1,106, + 106,106,1,63,63,63,1,174,174,174,1,0,0,0,2,169,169,169,1,70, + 70,70,1,151,151,151,1,72,72,72,1,0,0,0,2,202,202,202,1,97, + 97,97,1,0,0,0,1,94,94,94,1,129,129,129,1,0,0,0,1,189, + 189,189,1,42,42,42,1,0,0,0,1,149,149,149,1,74,74,74,1,0, + 0,0,1,125,125,125,1,106,106,106,1,63,63,63,1,186,186,186,1,0, + 0,0,2,192,192,192,1,51,51,51,1,151,151,151,1,72,72,72,1,0, + 0,0,2,240,240,240,1,0,0,0,2,82,82,82,1,178,178,178,1,31, + 31,31,1,189,189,189,1,42,42,42,1,0,0,0,1,149,149,149,1,74, + 74,74,1,0,0,0,1,125,125,125,1,106,106,106,1,63,63,63,1,247, + 247,247,1,88,88,88,1,97,97,97,1,201,201,201,1,4,4,4,1,151, + 151,151,1,72,72,72,1,0,0,0,2,240,240,240,1,0,0,0,2,10, + 10,10,1,123,123,123,1,67,67,67,1,94,94,94,1,21,21,21,1,0, + 0,0,1,74,74,74,1,37,37,37,1,0,0,0,1,62,62,62,1,53, + 53,53,1,63,63,63,1,178,178,178,1,122,122,122,1,124,124,124,1,23, + 23,23,1,0,0,0,1,75,75,75,1,36,36,36,1,0,0,0,2,7, + 7,7,1,172,172,172,1,0,0,0,12,63,63,63,1,168,168,168,1,0, + 0,0,9,240,240,240,1,0,0,0,12,33,33,33,1,89,89,89,1,0, + 0,0,8,22,22,22,1,240,240,240,1,37,37,37,1,0,0,0,2,232, + 232,232,1,240,240,240,1,210,210,210,1,0,0,0,2,60,60,60,1,240, + 240,240,2,150,150,150,1,0,0,0,2,120,120,120,1,240,240,240,2,90, + 90,90,1,0,0,0,2,187,187,187,1,240,240,240,2,0,0) + ); + +const + objdata_tactivator: record size: integer; data: array[0..1465] of byte end = + (size: 1466; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,97,99, + 116,105,118,97,116,111,114,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,68,5,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,56,3,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,208,208,208,128,70,209,70,1,82,220,80,1, + 88,222,85,1,94,222,90,1,98,223,96,1,102,223,101,1,107,223,105,1, + 106,213,106,1,208,208,208,15,71,217,71,1,77,219,75,1,82,220,80,1, + 88,221,85,1,93,222,90,1,98,223,96,1,103,224,101,1,109,225,106,1, + 110,217,106,1,105,203,105,1,0,0,0,1,208,208,208,12,67,217,63,1, + 72,218,69,1,77,219,75,1,82,220,80,1,88,221,85,1,93,222,90,1, + 98,223,96,1,103,224,101,1,109,225,106,1,114,226,111,1,118,226,116,1, + 87,159,84,1,0,0,0,1,208,208,208,10,70,209,70,1,67,217,63,1, + 72,218,69,1,77,219,75,1,82,220,80,1,88,221,85,1,93,222,90,1, + 98,223,96,1,103,224,101,1,109,225,106,1,114,226,111,1,119,227,117,1, + 114,211,113,1,34,57,28,1,0,0,0,1,208,208,208,9,63,216,58,1, + 67,217,64,1,72,218,69,1,77,219,75,1,82,220,80,1,88,221,85,1, + 93,222,90,1,98,223,96,1,103,224,101,1,109,225,106,1,114,226,111,1, + 119,227,117,1,124,228,122,1,84,149,83,1,0,0,0,1,208,208,208,9, + 62,216,59,1,67,217,64,1,72,218,69,1,77,219,75,1,82,220,80,1, + 88,221,85,1,93,222,90,1,98,223,96,1,103,224,101,1,109,225,106,1, + 114,226,111,1,119,227,117,1,124,228,122,1,104,184,102,1,0,0,0,2, + 208,208,208,8,62,216,59,1,67,217,64,1,72,218,69,1,77,219,75,1, + 82,220,80,1,88,221,85,1,93,222,90,1,98,223,96,1,103,224,101,1, + 109,225,106,1,114,226,111,1,119,227,117,1,124,228,122,1,122,216,120,1, + 0,0,0,2,208,208,208,8,62,216,59,1,67,217,64,1,72,218,69,1, + 77,219,75,1,82,220,80,1,88,221,85,1,93,222,90,1,98,223,96,1, + 103,224,101,1,109,225,106,1,114,226,111,1,119,227,117,1,124,228,122,1, + 122,216,120,1,0,0,0,2,208,208,208,8,62,215,59,1,67,217,64,1, + 72,218,69,1,77,219,75,1,82,220,80,1,88,221,85,1,93,222,90,1, + 98,223,96,1,103,224,101,1,109,225,106,1,114,226,111,1,119,227,117,1, + 124,228,122,1,104,184,102,1,0,0,0,2,208,208,208,8,62,214,58,1, + 67,217,64,1,72,218,69,1,77,219,75,1,82,220,80,1,88,221,85,1, + 93,222,90,1,98,223,96,1,103,224,101,1,109,225,106,1,114,226,111,1, + 119,227,117,1,124,228,122,1,79,140,78,1,0,0,0,2,208,208,208,8, + 64,191,64,1,64,208,61,1,72,218,69,1,77,219,75,1,82,220,80,1, + 88,221,85,1,93,222,90,1,98,223,96,1,103,224,101,1,109,225,106,1, + 114,226,111,1,119,227,117,1,114,210,113,1,11,18,9,1,0,0,0,2, + 208,208,208,9,61,198,57,1,71,217,68,1,77,219,75,1,82,220,80,1, + 88,221,85,1,93,222,90,1,98,223,96,1,103,224,101,1,109,225,106,1, + 114,226,111,1,118,226,116,1,46,84,44,1,0,0,0,2,208,208,208,10, + 0,0,0,1,49,151,49,1,71,203,69,1,82,220,80,1,88,221,85,1, + 93,222,90,1,98,223,96,1,103,224,101,1,109,225,106,1,105,208,102,1, + 43,82,43,1,0,0,0,3,208,208,208,11,0,0,0,1,17,51,17,1, + 53,143,52,1,71,178,69,1,88,209,85,1,92,210,90,1,83,180,82,1, + 66,137,65,1,9,18,9,1,0,0,0,3,208,208,208,13,0,0,0,10, + 208,208,208,16,0,0,0,6,208,208,208,80,212,1,0,0,0,0,0,128, + 11,11,11,1,118,118,118,1,176,176,176,1,229,229,229,2,177,177,177,1, + 119,119,119,1,12,12,12,1,0,0,0,15,61,61,61,1,221,221,221,1, + 255,255,255,6,230,230,230,1,68,68,68,1,1,1,1,1,0,0,0,12, + 61,61,61,1,253,253,253,1,255,255,255,8,254,254,254,1,88,88,88,1, + 1,1,1,1,0,0,0,10,11,11,11,1,221,221,221,1,255,255,255,10, + 239,239,239,1,45,45,45,1,1,1,1,1,0,0,0,9,118,118,118,1, + 255,255,255,12,182,182,182,1,8,8,8,1,0,0,0,9,176,176,176,1, + 255,255,255,12,219,219,219,1,64,64,64,1,1,1,1,1,0,0,0,8, + 229,229,229,1,255,255,255,12,243,243,243,1,96,96,96,1,2,2,2,1, + 0,0,0,8,229,229,229,1,255,255,255,12,243,243,243,1,124,124,124,1, + 2,2,2,1,0,0,0,8,177,177,177,1,255,255,255,12,219,219,219,1, + 124,124,124,1,2,2,2,1,0,0,0,8,119,119,119,1,255,255,255,12, + 193,193,193,1,96,96,96,1,2,2,2,1,0,0,0,8,12,12,12,1, + 230,230,230,1,255,255,255,10,240,240,240,1,143,143,143,1,64,64,64,1, + 1,1,1,1,0,0,0,9,67,67,67,1,254,254,254,1,255,255,255,8, + 254,254,254,1,167,167,167,1,119,119,119,1,8,8,8,1,0,0,0,10, + 1,1,1,1,88,88,88,1,239,239,239,1,255,255,255,6,240,240,240,1, + 167,167,167,1,136,136,136,1,36,36,36,1,1,1,1,1,0,0,0,11, + 1,1,1,1,45,45,45,1,182,182,182,1,219,219,219,1,243,243,243,2, + 219,219,219,1,193,193,193,1,143,143,143,1,119,119,119,1,36,36,36,1, + 1,1,1,1,0,0,0,13,1,1,1,1,9,9,9,1,64,64,64,1, + 96,96,96,1,124,124,124,2,96,96,96,1,64,64,64,1,9,9,9,1, + 1,1,1,1,0,0,0,16,1,1,1,1,2,2,2,4,1,1,1,1, + 0,0,0,80,0,0) + ); + +const + objdata_tpostscriptprinter: record size: integer; data: array[0..2129] of byte end = + (size: 2130; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,18,116,112,111, + 115,116,115,99,114,105,112,116,112,114,105,110,116,101,114,23,98,105,116,109, + 97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4, + 6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11, + 10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111, + 114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10, + 212,7,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0, + 236,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2, + 1,1,1,1,18,18,18,1,131,131,131,1,208,208,208,2,146,146,146,1, + 29,29,29,1,4,4,4,1,38,38,38,1,157,157,157,1,208,208,208,12, + 0,0,0,1,208,208,208,2,163,163,163,1,15,15,15,1,208,208,208,2, + 17,17,17,1,153,153,153,1,203,203,203,1,144,144,144,1,24,24,24,1, + 208,208,208,12,0,0,0,1,208,208,208,1,206,206,206,1,155,155,155,1, + 18,18,18,1,208,208,208,2,38,38,38,1,124,124,124,1,196,196,196,1, + 208,208,208,14,0,0,0,3,21,21,21,1,136,136,136,1,208,208,208,2, + 191,191,191,1,101,101,101,1,44,44,44,1,47,47,47,1,160,160,160,1, + 208,208,208,12,0,0,0,1,208,208,208,9,175,175,175,1,21,21,21,1, + 208,208,208,12,0,0,0,1,208,208,208,6,24,24,24,1,142,142,142,1, + 204,204,204,1,166,166,166,1,22,22,22,1,208,208,208,12,0,0,0,1, + 208,208,208,6,156,156,156,1,37,37,37,1,4,4,4,1,26,66,69,1, + 63,162,172,1,74,172,182,5,62,145,153,1,43,147,157,1,0,122,133,1, + 208,208,208,14,33,144,155,1,146,210,217,1,162,227,233,1,177,248,255,1, + 169,236,243,1,177,248,255,2,120,168,173,1,169,242,250,1,55,159,169,1, + 18,134,140,1,208,208,208,13,48,152,164,1,113,159,163,1,140,196,202,1, + 130,182,187,1,118,165,170,1,177,248,255,1,168,235,242,1,103,144,148,1, + 121,170,175,1,119,169,174,1,40,126,134,1,0,128,128,1,208,208,208,12, + 72,164,173,1,191,232,237,1,205,250,255,1,177,216,220,1,187,227,232,1, + 205,250,255,5,76,167,176,1,208,208,208,12,0,128,128,1,71,125,129,1, + 154,166,167,1,183,197,199,1,192,206,208,1,193,207,209,1,235,253,255,1, + 197,212,214,1,189,203,205,1,194,208,210,1,235,253,255,1,71,159,167,1, + 208,208,208,12,37,139,148,1,166,194,197,1,244,253,255,1,216,224,226,1, + 199,206,208,1,213,221,223,1,244,253,255,1,208,215,217,1,203,210,212,1, + 190,197,199,1,173,210,215,1,39,140,150,1,208,208,208,11,0,128,128,1, + 67,160,168,1,147,175,179,1,162,193,197,1,185,221,225,1,175,208,212,1, + 210,250,255,1,193,229,234,1,195,232,237,1,184,219,223,1,204,246,252,1, + 53,148,157,1,115,115,115,2,119,119,119,1,208,208,208,8,0,0,0,1, + 77,145,153,1,140,220,230,1,146,204,211,1,175,245,253,1,145,203,210,1, + 137,193,199,1,176,247,255,1,165,232,239,1,146,205,212,1,152,213,220,1, + 97,183,192,1,191,207,208,1,220,220,220,1,171,171,171,1,144,144,144,1, + 208,208,208,7,158,158,158,1,188,188,189,1,56,153,162,1,93,192,203,1, + 92,191,201,1,92,190,200,1,91,189,199,1,90,188,198,1,89,187,197,1, + 89,186,197,1,88,186,196,1,84,182,192,1,123,186,192,1,235,235,235,1, + 170,170,170,1,178,178,178,1,155,155,155,1,208,208,208,5,151,151,151,1, + 185,185,185,1,230,230,230,1,238,239,239,1,218,229,230,1,220,230,231,1, + 221,230,231,1,223,231,232,1,224,232,233,1,226,233,234,1,228,234,235,1, + 229,235,235,1,231,236,236,1,232,236,236,1,221,221,222,1,160,160,160,1, + 187,187,187,1,188,188,188,1,155,155,155,1,208,208,208,4,139,139,139,1, + 160,160,160,1,177,177,177,1,179,179,179,1,181,181,181,1,182,182,182,9, + 181,181,181,1,158,158,158,1,188,188,188,3,155,155,155,1,208,208,208,4, + 146,146,146,1,187,187,187,1,203,203,203,1,219,219,219,1,235,235,235,1, + 241,241,241,1,243,243,243,1,244,244,244,1,246,246,246,1,247,247,247,1, + 248,248,248,1,125,253,136,2,189,253,194,1,232,232,232,1,167,167,167,1, + 188,188,188,2,187,187,187,1,149,149,149,1,208,208,208,4,146,146,146,1, + 187,187,187,1,203,203,203,1,219,219,219,1,235,235,235,1,241,241,241,1, + 243,243,243,1,244,244,244,1,246,246,246,1,247,247,247,1,248,248,248,1, + 0,255,21,2,126,254,137,1,232,232,232,1,167,167,167,1,188,188,188,2, + 158,158,158,1,109,109,109,1,208,208,208,4,146,146,146,1,187,187,187,1, + 203,203,203,1,219,219,219,1,235,235,235,1,241,241,241,1,243,243,243,1, + 244,244,244,1,246,246,246,1,247,247,247,1,248,248,248,1,0,0,255,2, + 126,126,254,1,232,232,232,1,167,167,167,1,188,188,188,1,141,141,141,1, + 14,14,14,1,0,0,0,1,208,208,208,4,146,146,146,1,187,187,187,1, + 203,203,203,1,219,219,219,1,235,235,235,1,241,241,241,1,243,243,243,1, + 244,244,244,1,246,246,246,1,247,247,247,1,248,248,248,1,125,125,253,2, + 189,189,253,1,232,232,232,1,167,167,167,1,149,149,149,1,27,27,27,1, + 0,0,0,2,208,208,208,4,128,128,128,1,156,156,156,1,169,169,169,1, + 183,183,183,1,196,196,196,1,201,201,201,1,203,203,203,2,205,205,205,1, + 206,206,206,1,207,207,207,1,208,208,208,1,209,209,209,1,210,210,210,1, + 193,193,193,1,144,144,144,1,41,41,41,1,0,0,0,2,208,208,208,5, + 115,115,115,1,118,118,118,1,108,108,108,1,107,107,107,1,112,112,112,1, + 115,115,115,1,116,116,116,3,117,117,117,5,119,119,119,1,67,67,67,1, + 0,0,0,2,208,208,208,7,0,0,0,16,208,208,208,4,176,2,0,0, + 255,255,255,2,254,254,254,1,233,233,233,1,95,95,95,1,0,0,0,2, + 76,76,76,1,219,219,219,1,250,250,250,1,209,209,209,1,62,62,62,1, + 0,0,0,12,255,255,255,1,0,0,0,2,55,55,55,1,236,236,236,1, + 0,0,0,2,234,234,234,1,68,68,68,1,6,6,6,1,79,79,79,1, + 225,225,225,1,0,0,0,12,255,255,255,1,0,0,0,1,2,2,2,1, + 65,65,65,1,233,233,233,1,0,0,0,2,209,209,209,1,103,103,103,1, + 15,15,15,1,0,0,0,14,255,255,255,3,229,229,229,1,88,88,88,1, + 0,0,0,2,21,21,21,1,131,131,131,1,201,201,201,1,197,197,197,1, + 59,59,59,1,0,0,0,12,255,255,255,1,0,0,0,9,41,41,41,1, + 229,229,229,1,0,0,0,12,255,255,255,1,0,0,0,6,226,226,226,1, + 81,81,81,1,5,5,5,1,52,52,52,1,228,228,228,1,0,0,0,12, + 255,255,255,1,0,0,0,6,64,64,64,1,210,210,210,1,250,250,250,1, + 230,230,230,1,233,233,233,1,220,220,220,5,225,225,225,1,203,203,203,1, + 23,23,23,1,0,0,0,14,145,145,145,1,255,255,255,8,216,216,216,1, + 42,42,42,1,0,0,0,13,176,176,176,1,255,255,255,9,225,225,225,1, + 2,2,2,1,0,0,0,12,197,197,197,1,255,255,255,9,206,206,206,1, + 0,0,0,12,4,4,4,1,227,227,227,1,255,255,255,9,183,183,183,1, + 0,0,0,12,110,110,110,1,250,250,250,1,255,255,255,8,245,245,245,1, + 104,104,104,1,0,0,0,11,2,2,2,1,206,206,206,1,255,255,255,9, + 203,203,203,1,40,40,40,2,45,45,45,1,0,0,0,8,1,1,1,1, + 165,165,165,1,253,253,253,1,255,255,255,11,238,238,238,1,195,195,195,1, + 0,0,0,7,84,84,84,1,194,194,194,1,255,255,255,12,231,231,231,1, + 251,251,251,1,168,168,168,1,0,0,0,5,64,64,64,1,181,181,181,1, + 250,250,250,1,255,255,255,11,246,246,246,1,231,231,231,1,255,255,255,2, + 168,168,168,1,0,0,0,4,161,161,161,1,228,228,228,1,225,225,225,12, + 230,230,230,1,239,239,239,1,255,255,255,3,168,168,168,1,0,0,0,4, + 168,168,168,1,255,255,255,18,149,149,149,1,0,0,0,4,168,168,168,1, + 255,255,255,17,184,184,184,1,7,7,7,1,0,0,0,4,168,168,168,1, + 255,255,255,16,229,229,229,1,147,147,147,1,77,77,77,1,0,0,0,4, + 168,168,168,1,255,255,255,15,235,235,235,1,154,154,154,1,92,92,92,1, + 1,1,1,1,0,0,0,4,175,175,175,1,255,255,255,14,245,245,245,1, + 161,161,161,1,105,105,105,1,4,4,4,1,0,0,0,5,135,135,135,1, + 183,183,183,1,211,211,211,1,223,223,223,11,228,228,228,1,181,181,181,1, + 116,116,116,1,9,9,9,1,0,0,0,7,21,21,21,1,70,70,70,14, + 15,15,15,1,0,0,0,4,0,0) + ); + +const + objdata_tgdiprinter: record size: integer; data: array[0..2314] of byte end = + (size: 2315; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,103,100, + 105,112,114,105,110,116,101,114,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,148,8,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,76,5,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,208,208,208,1,142,142,142,1,4,4,4, + 1,6,6,6,1,151,151,151,1,208,208,208,3,0,0,0,2,4,4,4, + 1,142,142,142,1,208,208,208,3,0,0,0,1,208,208,208,8,142,142,142, + 1,8,8,8,1,142,142,142,1,157,157,157,1,31,31,31,1,158,158,158, + 1,208,208,208,2,0,0,0,1,208,208,208,1,142,142,142,1,8,8,8, + 1,142,142,142,1,208,208,208,2,0,0,0,1,208,208,208,8,4,4,4, + 1,142,142,142,1,208,208,208,2,194,194,194,1,201,201,201,1,208,208,208, + 2,0,0,0,1,208,208,208,2,142,142,142,1,4,4,4,1,208,208,208, + 2,0,0,0,1,208,208,208,8,0,0,0,1,208,208,208,2,0,0,0, + 3,208,208,208,2,0,0,0,1,208,208,208,3,0,0,0,1,208,208,208, + 2,0,0,0,1,208,208,208,8,4,4,4,1,142,142,142,1,208,208,208, + 2,142,142,142,1,4,4,4,1,208,208,208,2,0,0,0,1,208,208,208, + 2,142,142,142,1,4,4,4,1,208,208,208,2,0,0,0,1,208,208,208, + 8,142,142,142,1,8,8,8,1,142,142,142,2,8,8,8,1,142,142,142, + 1,208,208,208,2,0,0,0,1,208,208,208,1,142,142,142,1,8,8,8, + 1,142,142,142,1,208,208,208,2,0,0,0,1,208,208,208,9,142,142,142, + 1,4,4,4,2,142,142,142,1,208,208,208,3,0,0,0,2,9,45,48, + 1,63,161,171,1,74,172,182,3,64,148,157,1,74,172,182,1,62,145,153, + 1,43,147,157,1,0,122,133,1,208,208,208,14,33,144,155,1,146,210,217, + 1,162,227,233,1,177,248,255,1,169,236,243,1,177,248,255,2,120,168,173, + 1,169,242,250,1,55,159,169,1,18,134,140,1,208,208,208,13,48,152,164, + 1,113,159,163,1,140,196,202,1,130,182,187,1,118,165,170,1,177,248,255, + 1,168,235,242,1,103,144,148,1,121,170,175,1,119,169,174,1,40,126,134, + 1,0,128,128,1,208,208,208,12,72,164,173,1,191,232,237,1,205,250,255, + 1,177,216,220,1,187,227,232,1,205,250,255,5,76,167,176,1,208,208,208, + 12,0,128,128,1,71,125,129,1,154,166,167,1,183,197,199,1,192,206,208, + 1,193,207,209,1,235,253,255,1,197,212,214,1,189,203,205,1,194,208,210, + 1,235,253,255,1,71,159,167,1,208,208,208,12,37,139,148,1,166,194,197, + 1,244,253,255,1,216,224,226,1,199,206,208,1,213,221,223,1,244,253,255, + 1,208,215,217,1,203,210,212,1,190,197,199,1,173,210,215,1,39,140,150, + 1,208,208,208,11,0,128,128,1,67,160,168,1,147,175,179,1,162,193,197, + 1,185,221,225,1,175,208,212,1,210,250,255,1,193,229,234,1,195,232,237, + 1,184,219,223,1,204,246,252,1,53,148,157,1,115,115,115,2,119,119,119, + 1,208,208,208,8,0,0,0,1,77,145,153,1,140,220,230,1,146,204,211, + 1,175,245,253,1,145,203,210,1,137,193,199,1,176,247,255,1,165,232,239, + 1,146,205,212,1,152,213,220,1,97,183,192,1,191,207,208,1,220,220,220, + 1,171,171,171,1,144,144,144,1,208,208,208,7,158,158,158,1,188,188,189, + 1,56,153,162,1,93,192,203,1,92,191,201,1,92,190,200,1,91,189,199, + 1,90,188,198,1,89,187,197,1,89,186,197,1,88,186,196,1,84,182,192, + 1,123,186,192,1,235,235,235,1,170,170,170,1,178,178,178,1,155,155,155, + 1,208,208,208,5,151,151,151,1,185,185,185,1,230,230,230,1,238,239,239, + 1,218,229,230,1,220,230,231,1,221,230,231,1,223,231,232,1,224,232,233, + 1,226,233,234,1,228,234,235,1,229,235,235,1,231,236,236,1,232,236,236, + 1,221,221,222,1,160,160,160,1,187,187,187,1,188,188,188,1,155,155,155, + 1,208,208,208,4,139,139,139,1,160,160,160,1,177,177,177,1,179,179,179, + 1,181,181,181,1,182,182,182,9,181,181,181,1,158,158,158,1,188,188,188, + 3,155,155,155,1,208,208,208,4,146,146,146,1,187,187,187,1,203,203,203, + 1,219,219,219,1,235,235,235,1,241,241,241,1,243,243,243,1,244,244,244, + 1,246,246,246,1,247,247,247,1,248,248,248,1,125,253,136,2,189,253,194, + 1,232,232,232,1,167,167,167,1,188,188,188,2,187,187,187,1,149,149,149, + 1,208,208,208,4,146,146,146,1,187,187,187,1,203,203,203,1,219,219,219, + 1,235,235,235,1,241,241,241,1,243,243,243,1,244,244,244,1,246,246,246, + 1,247,247,247,1,248,248,248,1,0,255,21,2,126,254,137,1,232,232,232, + 1,167,167,167,1,188,188,188,2,158,158,158,1,109,109,109,1,208,208,208, + 4,146,146,146,1,187,187,187,1,203,203,203,1,219,219,219,1,235,235,235, + 1,241,241,241,1,243,243,243,1,244,244,244,1,246,246,246,1,247,247,247, + 1,248,248,248,1,0,0,255,2,126,126,254,1,232,232,232,1,167,167,167, + 1,188,188,188,1,141,141,141,1,14,14,14,1,0,0,0,1,208,208,208, + 4,146,146,146,1,187,187,187,1,203,203,203,1,219,219,219,1,235,235,235, + 1,241,241,241,1,243,243,243,1,244,244,244,1,246,246,246,1,247,247,247, + 1,248,248,248,1,125,125,253,2,189,189,253,1,232,232,232,1,167,167,167, + 1,149,149,149,1,27,27,27,1,0,0,0,2,208,208,208,4,128,128,128, + 1,156,156,156,1,169,169,169,1,183,183,183,1,196,196,196,1,201,201,201, + 1,203,203,203,2,205,205,205,1,206,206,206,1,207,207,207,1,208,208,208, + 1,209,209,209,1,210,210,210,1,193,193,193,1,144,144,144,1,41,41,41, + 1,0,0,0,2,208,208,208,5,115,115,115,1,118,118,118,1,108,108,108, + 1,107,107,107,1,112,112,112,1,115,115,115,1,116,116,116,3,117,117,117, + 5,119,119,119,1,67,67,67,1,0,0,0,2,208,208,208,7,0,0,0, + 16,208,208,208,4,16,3,0,0,0,0,0,1,81,81,81,1,250,250,250, + 1,248,248,248,1,70,70,70,1,0,0,0,3,255,255,255,2,250,250,250, + 1,81,81,81,1,0,0,0,3,255,255,255,1,0,0,0,8,81,81,81, + 1,245,245,245,1,81,81,81,1,63,63,63,1,217,217,217,1,61,61,61, + 1,0,0,0,2,255,255,255,1,0,0,0,1,81,81,81,1,245,245,245, + 1,81,81,81,1,0,0,0,2,255,255,255,1,0,0,0,8,250,250,250, + 1,81,81,81,1,0,0,0,2,17,17,17,1,8,8,8,1,0,0,0, + 2,255,255,255,1,0,0,0,2,81,81,81,1,250,250,250,1,0,0,0, + 2,255,255,255,1,0,0,0,8,255,255,255,1,0,0,0,2,255,255,255, + 3,0,0,0,2,255,255,255,1,0,0,0,3,255,255,255,1,0,0,0, + 2,255,255,255,1,0,0,0,8,250,250,250,1,81,81,81,1,0,0,0, + 2,81,81,81,1,250,250,250,1,0,0,0,2,255,255,255,1,0,0,0, + 2,81,81,81,1,250,250,250,1,0,0,0,2,255,255,255,1,0,0,0, + 8,81,81,81,1,245,245,245,1,81,81,81,2,245,245,245,1,81,81,81, + 1,0,0,0,2,255,255,255,1,0,0,0,1,81,81,81,1,245,245,245, + 1,81,81,81,1,0,0,0,2,255,255,255,1,0,0,0,9,81,81,81, + 1,250,250,250,2,81,81,81,1,0,0,0,3,255,255,255,2,252,252,252, + 1,235,235,235,1,220,220,220,3,255,255,255,1,220,220,220,1,225,225,225, + 1,203,203,203,1,23,23,23,1,0,0,0,14,145,145,145,1,255,255,255, + 8,216,216,216,1,42,42,42,1,0,0,0,13,176,176,176,1,255,255,255, + 9,225,225,225,1,2,2,2,1,0,0,0,12,197,197,197,1,255,255,255, + 9,206,206,206,1,0,0,0,12,4,4,4,1,227,227,227,1,255,255,255, + 9,183,183,183,1,0,0,0,12,110,110,110,1,250,250,250,1,255,255,255, + 8,245,245,245,1,104,104,104,1,0,0,0,11,2,2,2,1,206,206,206, + 1,255,255,255,9,203,203,203,1,40,40,40,2,45,45,45,1,0,0,0, + 8,1,1,1,1,165,165,165,1,253,253,253,1,255,255,255,11,238,238,238, + 1,195,195,195,1,0,0,0,7,84,84,84,1,194,194,194,1,255,255,255, + 12,231,231,231,1,251,251,251,1,168,168,168,1,0,0,0,5,64,64,64, + 1,181,181,181,1,250,250,250,1,255,255,255,11,246,246,246,1,231,231,231, + 1,255,255,255,2,168,168,168,1,0,0,0,4,161,161,161,1,228,228,228, + 1,225,225,225,12,230,230,230,1,239,239,239,1,255,255,255,3,168,168,168, + 1,0,0,0,4,168,168,168,1,255,255,255,18,149,149,149,1,0,0,0, + 4,168,168,168,1,255,255,255,17,184,184,184,1,7,7,7,1,0,0,0, + 4,168,168,168,1,255,255,255,16,229,229,229,1,147,147,147,1,77,77,77, + 1,0,0,0,4,168,168,168,1,255,255,255,15,235,235,235,1,154,154,154, + 1,92,92,92,1,1,1,1,1,0,0,0,4,175,175,175,1,255,255,255, + 14,245,245,245,1,161,161,161,1,105,105,105,1,4,4,4,1,0,0,0, + 5,135,135,135,1,183,183,183,1,211,211,211,1,223,223,223,11,228,228,228, + 1,181,181,181,1,116,116,116,1,9,9,9,1,0,0,0,7,21,21,21, + 1,70,70,70,14,15,15,15,1,0,0,0,4,0,0) + ); + +const + objdata_twmfprinter: record size: integer; data: array[0..2634] of byte end = + (size: 2635; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,119,109, + 102,112,114,105,110,116,101,114,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,212,9,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,236,5,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,25,25,25,1,183,183,183,1,208,208,208, + 1,125,125,125,1,1,1,1,1,132,132,132,1,208,208,208,1,185,185,185, + 1,26,26,26,1,208,208,208,1,0,0,0,1,119,119,119,1,208,208,208, + 3,118,118,118,1,0,0,0,1,208,208,208,2,0,0,0,4,208,208,208, + 1,77,77,77,1,131,131,131,1,208,208,208,1,82,82,82,1,55,55,55, + 1,90,90,90,1,208,208,208,1,132,132,132,1,79,79,79,1,208,208,208, + 1,0,0,0,1,69,69,69,1,208,208,208,3,69,69,69,1,0,0,0, + 1,208,208,208,2,0,0,0,1,208,208,208,4,128,128,128,1,79,79,79, + 1,208,208,208,1,41,41,41,1,140,140,140,1,47,47,47,1,208,208,208, + 1,80,80,80,1,131,131,131,1,208,208,208,1,0,0,0,1,91,91,91, + 1,166,166,166,1,208,208,208,1,165,165,165,1,92,92,92,1,0,0,0, + 1,208,208,208,2,0,0,0,1,208,208,208,4,180,180,180,1,28,28,28, + 1,203,203,203,1,15,15,15,1,205,205,205,1,19,19,19,1,206,206,206, + 1,29,29,29,1,184,184,184,1,208,208,208,1,0,0,0,1,153,153,153, + 1,84,84,84,1,208,208,208,1,83,83,83,1,153,153,153,1,0,0,0, + 1,208,208,208,2,0,0,0,3,208,208,208,3,24,24,24,1,142,142,142, + 1,49,49,49,1,208,208,208,1,51,51,51,1,145,145,145,1,29,29,29, + 1,208,208,208,2,0,0,0,1,203,203,203,1,23,23,23,1,192,192,192, + 1,23,23,23,1,204,204,204,1,0,0,0,1,208,208,208,2,0,0,0, + 1,208,208,208,5,75,75,75,1,48,48,48,1,91,91,91,1,208,208,208, + 1,95,95,95,1,49,49,49,1,81,81,81,1,208,208,208,2,0,0,0, + 1,208,208,208,1,67,67,67,1,73,73,73,1,68,68,68,1,208,208,208, + 1,0,0,0,1,208,208,208,2,0,0,0,1,208,208,208,5,126,126,126, + 1,0,0,0,1,132,132,132,1,208,208,208,1,138,138,138,1,0,0,0, + 1,133,133,133,1,208,208,208,2,6,42,45,1,60,162,172,1,77,169,179, + 1,64,148,157,1,77,169,179,1,74,172,182,1,64,148,157,1,62,145,153, + 1,43,147,157,1,0,11,12,1,208,208,208,14,33,144,155,1,146,210,217, + 1,162,227,233,1,177,248,255,1,169,236,243,1,177,248,255,2,120,168,173, + 1,169,242,250,1,55,159,169,1,18,134,140,1,208,208,208,13,48,152,164, + 1,113,159,163,1,140,196,202,1,130,182,187,1,118,165,170,1,177,248,255, + 1,168,235,242,1,103,144,148,1,121,170,175,1,119,169,174,1,40,126,134, + 1,0,128,128,1,208,208,208,12,72,164,173,1,191,232,237,1,205,250,255, + 1,177,216,220,1,187,227,232,1,205,250,255,5,76,167,176,1,208,208,208, + 12,0,128,128,1,71,125,129,1,154,166,167,1,183,197,199,1,192,206,208, + 1,193,207,209,1,235,253,255,1,197,212,214,1,189,203,205,1,194,208,210, + 1,235,253,255,1,71,159,167,1,208,208,208,12,37,139,148,1,166,194,197, + 1,244,253,255,1,216,224,226,1,199,206,208,1,213,221,223,1,244,253,255, + 1,208,215,217,1,203,210,212,1,190,197,199,1,173,210,215,1,39,140,150, + 1,208,208,208,11,0,128,128,1,67,160,168,1,147,175,179,1,162,193,197, + 1,185,221,225,1,175,208,212,1,210,250,255,1,193,229,234,1,195,232,237, + 1,184,219,223,1,204,246,252,1,53,148,157,1,115,115,115,2,119,119,119, + 1,208,208,208,8,0,0,0,1,77,145,153,1,140,220,230,1,146,204,211, + 1,175,245,253,1,145,203,210,1,137,193,199,1,176,247,255,1,165,232,239, + 1,146,205,212,1,152,213,220,1,97,183,192,1,191,207,208,1,220,220,220, + 1,171,171,171,1,144,144,144,1,208,208,208,7,158,158,158,1,188,188,189, + 1,56,153,162,1,93,192,203,1,92,191,201,1,92,190,200,1,91,189,199, + 1,90,188,198,1,89,187,197,1,89,186,197,1,88,186,196,1,84,182,192, + 1,123,186,192,1,235,235,235,1,170,170,170,1,178,178,178,1,155,155,155, + 1,208,208,208,5,151,151,151,1,185,185,185,1,230,230,230,1,238,239,239, + 1,218,229,230,1,220,230,231,1,221,230,231,1,223,231,232,1,224,232,233, + 1,226,233,234,1,228,234,235,1,229,235,235,1,231,236,236,1,232,236,236, + 1,221,221,222,1,160,160,160,1,187,187,187,1,188,188,188,1,155,155,155, + 1,208,208,208,4,139,139,139,1,160,160,160,1,177,177,177,1,179,179,179, + 1,181,181,181,1,182,182,182,9,181,181,181,1,158,158,158,1,188,188,188, + 3,155,155,155,1,208,208,208,4,146,146,146,1,187,187,187,1,203,203,203, + 1,219,219,219,1,235,235,235,1,241,241,241,1,243,243,243,1,244,244,244, + 1,246,246,246,1,247,247,247,1,248,248,248,1,125,253,136,2,189,253,194, + 1,232,232,232,1,167,167,167,1,188,188,188,2,187,187,187,1,149,149,149, + 1,208,208,208,4,146,146,146,1,187,187,187,1,203,203,203,1,219,219,219, + 1,235,235,235,1,241,241,241,1,243,243,243,1,244,244,244,1,246,246,246, + 1,247,247,247,1,248,248,248,1,0,255,21,2,126,254,137,1,232,232,232, + 1,167,167,167,1,188,188,188,2,158,158,158,1,109,109,109,1,208,208,208, + 4,146,146,146,1,187,187,187,1,203,203,203,1,219,219,219,1,235,235,235, + 1,241,241,241,1,243,243,243,1,244,244,244,1,246,246,246,1,247,247,247, + 1,248,248,248,1,0,0,255,2,126,126,254,1,232,232,232,1,167,167,167, + 1,188,188,188,1,141,141,141,1,14,14,14,1,0,0,0,1,208,208,208, + 4,146,146,146,1,187,187,187,1,203,203,203,1,219,219,219,1,235,235,235, + 1,241,241,241,1,243,243,243,1,244,244,244,1,246,246,246,1,247,247,247, + 1,248,248,248,1,125,125,253,2,189,189,253,1,232,232,232,1,167,167,167, + 1,149,149,149,1,27,27,27,1,0,0,0,2,208,208,208,4,128,128,128, + 1,156,156,156,1,169,169,169,1,183,183,183,1,196,196,196,1,201,201,201, + 1,203,203,203,2,205,205,205,1,206,206,206,1,207,207,207,1,208,208,208, + 1,209,209,209,1,210,210,210,1,193,193,193,1,144,144,144,1,41,41,41, + 1,0,0,0,2,208,208,208,5,115,115,115,1,118,118,118,1,108,108,108, + 1,107,107,107,1,112,112,112,1,115,115,115,1,116,116,116,3,117,117,117, + 5,119,119,119,1,67,67,67,1,0,0,0,2,208,208,208,7,0,0,0, + 16,208,208,208,4,176,3,0,0,224,224,224,1,31,31,31,1,0,0,0, + 1,102,102,102,1,254,254,254,1,93,93,93,1,0,0,0,1,28,28,28, + 1,223,223,223,1,0,0,0,1,255,255,255,1,109,109,109,1,0,0,0, + 3,110,110,110,1,255,255,255,1,0,0,0,2,255,255,255,4,0,0,0, + 1,161,161,161,1,94,94,94,1,0,0,0,1,154,154,154,1,187,187,187, + 1,145,145,145,1,0,0,0,1,93,93,93,1,158,158,158,1,0,0,0, + 1,255,255,255,1,171,171,171,1,0,0,0,3,171,171,171,1,255,255,255, + 1,0,0,0,2,255,255,255,1,0,0,0,4,98,98,98,1,158,158,158, + 1,0,0,0,1,205,205,205,1,83,83,83,1,197,197,197,1,0,0,0, + 1,157,157,157,1,94,94,94,1,0,0,0,1,255,255,255,1,143,143,143, + 1,52,52,52,1,0,0,0,1,53,53,53,1,142,142,142,1,255,255,255, + 1,0,0,0,2,255,255,255,1,0,0,0,4,34,34,34,1,221,221,221, + 1,6,6,6,1,237,237,237,1,4,4,4,1,232,232,232,1,3,3,3, + 1,220,220,220,1,29,29,29,1,0,0,0,1,255,255,255,1,68,68,68, + 1,152,152,152,1,0,0,0,1,153,153,153,1,67,67,67,1,255,255,255, + 1,0,0,0,2,255,255,255,3,0,0,0,3,226,226,226,1,81,81,81, + 1,195,195,195,1,0,0,0,1,192,192,192,1,77,77,77,1,220,220,220, + 1,0,0,0,2,255,255,255,1,6,6,6,1,227,227,227,1,20,20,20, + 1,227,227,227,1,5,5,5,1,255,255,255,1,0,0,0,2,255,255,255, + 1,0,0,0,5,163,163,163,1,196,196,196,1,144,144,144,1,0,0,0, + 1,139,139,139,1,195,195,195,1,156,156,156,1,0,0,0,2,255,255,255, + 1,0,0,0,1,173,173,173,1,165,165,165,1,172,172,172,1,0,0,0, + 1,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,5,100,100,100, + 1,255,255,255,1,93,93,93,1,0,0,0,1,86,86,86,1,255,255,255, + 1,92,92,92,1,0,0,0,2,255,255,255,1,225,225,225,1,233,233,233, + 1,255,255,255,1,233,233,233,1,220,220,220,1,255,255,255,1,225,225,225, + 1,203,203,203,1,255,255,255,1,0,0,0,14,145,145,145,1,255,255,255, + 8,216,216,216,1,42,42,42,1,0,0,0,13,176,176,176,1,255,255,255, + 9,225,225,225,1,2,2,2,1,0,0,0,12,197,197,197,1,255,255,255, + 9,206,206,206,1,0,0,0,12,4,4,4,1,227,227,227,1,255,255,255, + 9,183,183,183,1,0,0,0,12,110,110,110,1,250,250,250,1,255,255,255, + 8,245,245,245,1,104,104,104,1,0,0,0,11,2,2,2,1,206,206,206, + 1,255,255,255,9,203,203,203,1,40,40,40,2,45,45,45,1,0,0,0, + 8,1,1,1,1,165,165,165,1,253,253,253,1,255,255,255,11,238,238,238, + 1,195,195,195,1,0,0,0,7,84,84,84,1,194,194,194,1,255,255,255, + 12,231,231,231,1,251,251,251,1,168,168,168,1,0,0,0,5,64,64,64, + 1,181,181,181,1,250,250,250,1,255,255,255,11,246,246,246,1,231,231,231, + 1,255,255,255,2,168,168,168,1,0,0,0,4,161,161,161,1,228,228,228, + 1,225,225,225,12,230,230,230,1,239,239,239,1,255,255,255,3,168,168,168, + 1,0,0,0,4,168,168,168,1,255,255,255,18,149,149,149,1,0,0,0, + 4,168,168,168,1,255,255,255,17,184,184,184,1,7,7,7,1,0,0,0, + 4,168,168,168,1,255,255,255,16,229,229,229,1,147,147,147,1,77,77,77, + 1,0,0,0,4,168,168,168,1,255,255,255,15,235,235,235,1,154,154,154, + 1,92,92,92,1,1,1,1,1,0,0,0,4,175,175,175,1,255,255,255, + 14,245,245,245,1,161,161,161,1,105,105,105,1,4,4,4,1,0,0,0, + 5,135,135,135,1,183,183,183,1,211,211,211,1,223,223,223,11,228,228,228, + 1,181,181,181,1,116,116,116,1,9,9,9,1,0,0,0,7,21,21,21, + 1,70,70,70,14,15,15,15,1,0,0,0,4,0,0) + ); + +const + objdata_tmainmenu: record size: integer; data: array[0..1936] of byte end = + (size: 1937; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,109,97, + 105,110,109,101,110,117,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,28,7,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,128,4,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,3,208,208,208,2,0,0,0,4,208, + 208,208,2,0,0,0,4,208,208,208,2,0,0,0,4,208,208,208,1,0, + 0,0,3,208,208,208,5,209,209,209,1,255,255,255,7,209,209,209,1,208, + 208,208,8,0,0,0,1,208,208,208,1,175,175,175,1,156,156,156,1,190, + 190,190,1,180,180,180,1,208,208,208,1,209,209,209,1,254,254,254,1,208, + 208,208,1,206,206,206,2,208,208,208,2,206,206,206,1,130,130,130,1,208, + 208,208,1,175,175,175,1,178,178,178,1,194,194,194,1,208,208,208,4,0, + 0,0,1,208,208,208,1,148,148,148,1,161,161,161,1,157,157,157,1,117, + 117,117,1,125,125,125,1,209,209,209,1,254,254,254,1,205,205,205,1,110, + 110,110,1,170,170,170,1,143,143,143,1,152,152,152,1,207,207,207,1,129, + 129,129,1,208,208,208,1,153,153,153,2,118,118,118,1,126,126,126,1,124, + 124,124,1,114,114,114,1,208,208,208,2,0,0,0,1,179,179,179,1,208, + 208,208,1,182,182,182,1,162,162,162,1,167,167,167,1,209,209,209,1,254, + 254,254,1,158,158,158,1,144,144,144,1,131,131,131,1,147,147,147,2,207, + 207,207,1,128,128,128,1,208,208,208,1,178,178,178,1,195,195,195,1,162, + 162,162,1,168,168,168,1,170,170,170,1,168,168,168,1,208,208,208,2,0, + 0,0,1,153,153,153,1,107,107,107,1,208,208,208,4,255,255,255,1,208, + 208,208,3,207,207,207,2,208,208,208,1,128,128,128,1,208,208,208,1,130, + 130,130,2,208,208,208,5,0,0,0,2,208,208,208,6,211,211,211,1,128, + 128,128,7,208,208,208,8,0,0,0,1,128,128,128,7,255,255,255,12,192, + 192,192,1,128,128,128,3,4,4,4,1,208,208,208,7,255,255,255,1,208, + 208,208,9,197,197,197,1,208,208,208,1,128,128,128,1,0,0,0,2,208, + 208,208,1,0,0,0,2,208,208,208,6,255,255,255,1,190,190,190,1,116, + 116,116,1,148,148,148,1,200,200,200,1,162,162,162,1,194,194,194,1,181, + 181,181,1,208,208,208,2,103,103,103,1,165,165,165,1,128,128,128,1,0, + 0,0,2,208,208,208,2,0,0,0,1,208,208,208,6,255,255,255,1,198, + 198,198,1,135,135,135,1,165,165,165,1,173,173,173,1,115,115,115,1,148, + 148,148,1,142,142,142,1,208,208,208,2,103,103,103,1,165,165,165,1,128, + 128,128,1,0,0,0,2,208,208,208,2,0,0,0,1,208,208,208,6,255, + 255,255,1,166,166,166,1,148,148,148,1,168,168,168,1,150,150,150,1,158, + 158,158,1,177,177,177,1,157,157,157,1,208,208,208,2,197,197,197,1,208, + 208,208,1,128,128,128,1,0,0,0,2,208,208,208,1,0,0,0,2,208, + 208,208,6,255,255,255,11,212,212,212,1,128,128,128,1,0,0,0,2,208, + 208,208,1,0,0,0,1,208,208,208,7,255,255,255,2,200,200,200,1,153, + 153,153,1,192,192,192,1,224,224,224,2,209,209,209,1,215,215,215,1,224, + 224,224,2,128,128,128,2,0,0,0,2,208,208,208,1,0,0,0,1,208, + 208,208,7,255,255,255,2,169,169,169,1,147,147,147,1,152,152,152,1,136, + 136,136,1,151,151,151,1,153,153,153,1,168,168,168,1,153,153,153,1,223, + 223,223,1,128,128,128,2,0,0,0,2,208,208,208,1,0,0,0,2,208, + 208,208,6,255,255,255,2,169,169,169,1,203,203,203,1,220,220,220,1,156, + 156,156,1,104,104,104,1,157,157,157,1,148,148,148,1,134,134,134,1,218, + 218,218,1,128,128,128,2,0,0,0,2,208,208,208,2,0,0,0,1,208, + 208,208,6,255,255,255,2,224,224,224,9,128,128,128,2,0,0,0,2,208, + 208,208,2,0,0,0,1,208,208,208,6,255,255,255,1,218,218,218,1,128, + 128,128,11,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,6,255, + 255,255,1,191,191,191,1,170,170,170,1,208,208,208,1,183,183,183,1,208, + 208,208,1,207,207,207,1,181,181,181,1,208,208,208,4,128,128,128,1,0, + 0,0,2,208,208,208,1,0,0,0,1,208,208,208,7,255,255,255,1,169, + 169,169,1,125,125,125,1,149,149,149,2,153,153,153,1,148,148,148,1,108, + 108,108,1,159,159,159,1,138,138,138,1,170,170,170,1,208,208,208,1,128, + 128,128,1,0,0,0,2,208,208,208,1,0,0,0,1,208,208,208,7,255, + 255,255,1,169,169,169,1,123,123,123,1,131,131,131,1,148,148,148,1,102, + 102,102,1,121,121,121,1,108,108,108,1,139,139,139,1,103,103,103,1,144, + 144,144,1,208,208,208,1,128,128,128,1,0,0,0,2,208,208,208,1,0, + 0,0,2,208,208,208,6,255,255,255,1,208,208,208,4,207,207,207,1,208, + 208,208,3,207,207,207,1,208,208,208,2,128,128,128,1,0,0,0,2,208, + 208,208,2,0,0,0,1,208,208,208,6,252,252,252,1,128,128,128,12,0, + 0,0,2,208,208,208,1,0,0,0,3,208,208,208,2,0,0,0,20,100, + 2,0,0,240,240,240,2,210,210,210,1,0,0,0,2,60,60,60,1,240, + 240,240,2,150,150,150,1,0,0,0,2,120,120,120,1,240,240,240,2,90, + 90,90,1,0,0,0,2,187,187,187,1,240,240,240,2,22,22,22,1,0, + 0,0,1,7,7,7,1,240,240,240,1,52,52,52,1,255,255,255,22,240, + 240,240,1,0,0,0,1,255,255,255,22,202,202,202,1,0,0,0,1,255, + 255,255,22,0,0,0,1,217,217,217,1,255,255,255,22,0,0,0,1,240, + 240,240,1,255,255,255,22,75,75,75,1,225,225,225,1,255,255,255,22,240, + 240,240,1,176,176,176,1,255,255,255,22,248,248,248,1,0,0,0,7,255, + 255,255,13,135,135,135,1,3,3,3,1,0,0,0,1,135,135,135,1,45, + 45,45,1,0,0,0,6,255,255,255,13,137,137,137,1,3,3,3,1,0, + 0,0,2,240,240,240,1,0,0,0,6,255,255,255,13,137,137,137,1,3, + 3,3,1,0,0,0,2,240,240,240,1,0,0,0,6,255,255,255,13,137, + 137,137,1,3,3,3,1,0,0,0,1,135,135,135,1,165,165,165,1,0, + 0,0,6,255,255,255,13,137,137,137,1,3,3,3,1,0,0,0,1,240, + 240,240,1,0,0,0,7,255,255,255,13,137,137,137,1,3,3,3,1,0, + 0,0,1,240,240,240,1,0,0,0,7,255,255,255,13,137,137,137,1,3, + 3,3,1,0,0,0,1,75,75,75,1,105,105,105,1,0,0,0,6,255, + 255,255,13,137,137,137,1,3,3,3,1,0,0,0,2,240,240,240,1,0, + 0,0,6,255,255,255,13,137,137,137,1,3,3,3,1,0,0,0,2,240, + 240,240,1,0,0,0,6,255,255,255,13,137,137,137,1,3,3,3,1,0, + 0,0,1,202,202,202,1,97,97,97,1,0,0,0,6,255,255,255,13,137, + 137,137,1,3,3,3,1,0,0,0,1,240,240,240,1,0,0,0,7,255, + 255,255,13,137,137,137,1,3,3,3,1,0,0,0,1,240,240,240,1,0, + 0,0,7,255,255,255,13,137,137,137,1,3,3,3,1,0,0,0,1,7, + 7,7,1,172,172,172,1,0,0,0,6,255,255,255,13,137,137,137,1,3, + 3,3,1,0,0,0,2,240,240,240,1,0,0,0,6,129,129,129,1,255, + 255,255,12,137,137,137,1,3,3,3,1,0,0,0,1,22,22,22,1,240, + 240,240,1,37,37,37,1,0,0,0,2,232,232,232,1,240,240,240,1,210, + 210,210,1,3,3,3,1,135,135,135,1,165,165,165,1,248,248,248,2,206, + 206,206,1,137,137,137,2,193,193,193,1,248,248,248,2,179,179,179,1,137, + 137,137,1,135,135,135,1,188,188,188,1,240,240,240,2,0,0) + ); + +const + objdata_tpopupmenu: record size: integer; data: array[0..2273] of byte end = + (size: 2274; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,112,111, + 112,117,112,109,101,110,117,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,108,8,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,104,3,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,3,208,208,208,2,0,0,0,4, + 208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,4,208,208,208,1, + 0,0,0,3,208,208,208,22,0,0,0,1,208,208,208,1,255,255,255,17, + 213,213,213,1,208,208,208,4,0,0,0,1,208,208,208,1,255,255,255,2, + 208,208,208,12,0,0,0,2,208,208,208,1,128,128,128,1,208,208,208,5, + 0,0,0,1,255,255,255,2,0,0,0,11,208,208,208,1,0,0,0,3, + 128,128,128,1,208,208,208,5,0,0,0,1,255,255,255,2,0,0,0,11, + 208,208,208,1,0,0,0,3,128,128,128,1,208,208,208,4,0,0,0,2, + 255,255,255,2,0,0,0,11,208,208,208,1,0,0,0,2,208,208,208,1, + 128,128,128,1,208,208,208,4,0,0,0,1,208,208,208,1,255,255,255,2, + 191,191,191,1,127,127,127,1,191,191,191,1,255,255,255,11,213,213,213,1, + 128,128,128,1,208,208,208,4,0,0,0,1,208,208,208,1,255,255,255,3, + 0,0,0,3,208,208,208,2,0,0,0,2,208,208,208,6,128,128,128,2, + 208,208,208,4,0,0,0,2,255,255,255,3,0,0,0,8,208,208,208,2, + 0,0,0,1,208,208,208,2,128,128,128,2,208,208,208,5,0,0,0,1, + 255,255,255,3,0,0,0,9,208,208,208,1,11,11,11,1,20,20,20,1, + 0,0,0,1,128,128,128,2,208,208,208,5,0,0,0,1,255,255,255,3, + 208,208,208,9,0,0,0,1,35,35,35,1,74,74,74,1,27,27,27,1, + 111,111,111,1,128,128,128,1,208,208,208,4,0,0,0,2,255,255,255,2, + 219,219,219,1,128,128,128,9,126,126,126,1,38,38,38,1,255,255,255,1, + 144,144,144,1,34,34,34,1,78,78,78,1,208,208,208,4,0,0,0,1, + 208,208,208,1,255,255,255,2,0,0,0,2,208,208,208,1,0,0,0,1, + 208,208,208,1,0,0,0,2,208,208,208,3,0,0,0,1,37,37,37,1, + 255,255,255,2,210,210,210,1,50,50,50,1,24,24,24,1,0,0,0,1, + 208,208,208,2,0,0,0,1,208,208,208,1,255,255,255,2,0,0,0,11, + 37,37,37,1,255,255,255,3,247,247,247,1,53,53,53,1,13,13,13,1, + 0,0,0,1,208,208,208,1,0,0,0,2,255,255,255,2,0,0,0,11, + 38,38,38,1,255,255,255,2,206,206,206,1,55,55,55,1,30,30,30,1, + 15,15,15,1,0,0,0,1,208,208,208,2,0,0,0,1,255,255,255,2, + 208,208,208,4,0,0,0,1,208,208,208,3,0,0,0,1,208,208,208,1, + 0,0,0,1,38,38,38,1,170,170,170,1,45,45,45,1,147,147,147,1, + 39,39,39,1,9,9,9,1,208,208,208,4,0,0,0,1,255,255,255,1, + 211,211,211,1,128,128,128,10,121,121,121,1,20,20,20,1,36,36,36,1, + 47,47,47,1,76,76,76,1,176,176,176,1,33,33,33,1,0,0,0,1, + 208,208,208,2,0,0,0,2,208,208,208,12,0,0,0,2,208,208,208,1, + 0,0,0,1,36,36,36,1,243,243,243,1,100,100,100,1,27,27,27,1, + 208,208,208,2,0,0,0,1,208,208,208,17,26,26,26,1,165,165,165,1, + 245,245,245,1,48,48,48,1,21,21,21,1,208,208,208,1,0,0,0,1, + 208,208,208,17,9,9,9,1,71,71,71,1,255,255,255,1,185,185,185,1, + 31,31,31,1,0,0,0,3,208,208,208,16,0,0,0,1,37,37,37,1, + 136,136,136,1,42,42,42,1,24,24,24,1,0,0,0,1,208,208,208,1, + 0,0,0,1,208,208,208,17,22,22,22,1,27,27,27,1,3,3,3,1, + 208,208,208,2,0,0,0,3,208,208,208,2,0,0,0,3,208,208,208,2, + 0,0,0,4,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,3, + 204,4,0,0,240,240,240,2,210,210,210,1,0,0,0,2,60,60,60,1, + 240,240,240,2,150,150,150,1,0,0,0,2,120,120,120,1,240,240,240,2, + 90,90,90,1,0,0,0,2,187,187,187,1,240,240,240,2,22,22,22,1, + 0,0,0,1,7,7,7,1,240,240,240,1,52,52,52,1,0,0,0,22, + 240,240,240,1,0,0,0,1,8,8,8,1,255,255,255,16,192,192,192,1, + 0,0,0,4,202,202,202,1,0,0,0,1,8,8,8,1,248,248,248,1, + 0,0,0,12,10,10,10,1,4,4,4,1,0,0,0,1,255,255,255,1, + 0,0,0,5,217,217,217,1,8,8,8,1,248,248,248,1,25,25,25,1, + 117,117,117,1,69,69,69,1,10,10,10,1,55,55,55,1,19,19,19,1, + 31,31,31,1,47,47,47,1,68,68,68,1,47,47,47,1,2,2,2,1, + 0,0,0,1,40,40,40,1,160,160,160,1,4,4,4,1,255,255,255,1, + 0,0,0,5,240,240,240,1,8,8,8,1,248,248,248,1,15,15,15,1, + 86,86,86,1,62,62,62,1,43,43,43,1,108,108,108,1,73,73,73,1, + 81,81,81,1,80,80,80,1,111,111,111,1,37,37,37,1,62,62,62,1, + 0,0,0,1,40,40,40,1,162,162,162,1,4,4,4,1,255,255,255,1, + 0,0,0,4,75,75,75,1,225,225,225,1,8,8,8,1,248,248,248,1, + 55,55,55,1,73,73,73,1,49,49,49,1,72,72,72,1,57,57,57,1, + 40,40,40,1,60,60,60,1,40,40,40,1,45,45,45,1,75,75,75,1, + 14,14,14,1,0,0,0,1,10,10,10,1,4,4,4,1,0,0,0,1, + 255,255,255,1,0,0,0,4,240,240,240,1,0,0,0,1,8,8,8,1, + 248,248,248,1,255,255,255,14,192,192,192,1,255,255,255,1,0,0,0,4, + 240,240,240,1,0,0,0,1,8,8,8,1,248,248,248,2,31,31,31,1, + 80,80,80,1,33,33,33,1,0,0,0,2,20,20,20,1,7,7,7,1, + 0,0,0,6,255,255,255,2,0,0,0,4,135,135,135,1,45,45,45,1, + 8,8,8,1,248,248,248,2,72,72,72,1,82,82,82,1,85,85,85,1, + 94,94,94,1,88,88,88,1,82,82,82,1,62,62,62,1,80,80,80,1, + 0,0,0,2,62,62,62,1,0,0,0,2,255,255,255,2,0,0,0,5, + 240,240,240,1,8,8,8,1,248,248,248,2,72,72,72,1,15,15,15,1, + 13,13,13,1,70,70,70,1,137,137,137,1,82,82,82,2,105,105,105,1, + 3,3,3,1,0,0,0,1,253,253,253,1,167,167,167,1,4,4,4,1, + 255,255,255,2,0,0,0,5,240,240,240,1,8,8,8,1,248,248,248,2, + 0,0,0,9,2,2,2,1,251,251,251,1,254,254,254,1,233,233,233,1, + 255,255,255,2,0,0,0,4,135,135,135,1,165,165,165,1,8,8,8,1, + 248,248,248,1,173,173,173,1,255,255,255,15,0,0,0,4,240,240,240,1, + 0,0,0,1,8,8,8,1,248,248,248,1,24,24,24,1,44,44,44,1, + 0,0,0,1,31,31,31,1,0,0,0,1,4,4,4,1,30,30,30,1, + 0,0,0,3,6,6,6,1,251,251,251,1,255,255,255,4,205,205,205,1, + 14,14,14,1,0,0,0,2,240,240,240,1,0,0,0,1,8,8,8,1, + 248,248,248,1,56,56,56,1,97,97,97,1,72,72,72,2,70,70,70,1, + 78,78,78,1,117,117,117,1,59,59,59,1,89,89,89,1,40,40,40,1, + 8,8,8,1,251,251,251,1,255,255,255,5,244,244,244,1,45,45,45,1, + 0,0,0,1,75,75,75,1,105,105,105,1,8,8,8,1,248,248,248,1, + 56,56,56,1,99,99,99,1,95,95,95,1,73,73,73,1,133,133,133,1, + 110,110,110,1,115,115,115,1,88,88,88,1,129,129,129,1,72,72,72,1, + 10,10,10,1,250,250,250,1,255,255,255,4,239,239,239,1,103,103,103,1, + 3,3,3,1,0,0,0,2,240,240,240,1,8,8,8,1,248,248,248,1, + 0,0,0,4,1,1,1,1,0,0,0,3,1,1,1,1,0,0,0,1, + 12,12,12,1,250,250,250,1,255,255,255,1,254,254,254,1,255,255,255,2, + 67,67,67,1,0,0,0,4,240,240,240,1,4,4,4,1,190,190,190,1, + 255,255,255,16,244,244,244,1,14,14,14,1,0,0,0,2,202,202,202,1, + 97,97,97,1,0,0,0,12,8,8,8,1,75,75,75,1,0,0,0,1, + 13,13,13,1,250,250,250,1,255,255,255,2,205,205,205,1,0,0,0,2, + 240,240,240,1,0,0,0,17,221,221,221,1,255,255,255,2,253,253,253,1, + 114,114,114,1,0,0,0,1,240,240,240,1,0,0,0,17,103,103,103,1, + 254,254,254,1,255,255,255,2,249,249,249,1,33,33,33,1,7,7,7,1, + 172,172,172,1,0,0,0,16,10,10,10,1,249,249,249,1,255,255,255,1, + 252,252,252,1,220,220,220,1,51,51,51,1,0,0,0,1,240,240,240,1, + 0,0,0,17,205,205,205,1,223,223,223,1,64,64,64,1,0,0,0,2, + 22,22,22,1,240,240,240,1,37,37,37,1,0,0,0,2,232,232,232,1, + 240,240,240,1,210,210,210,1,0,0,0,2,60,60,60,1,240,240,240,2, + 150,150,150,1,0,0,0,2,120,120,120,1,240,240,240,2,96,96,96,1, + 0,0,0,2,187,187,187,1,240,240,240,2,0,0) + ); + +const + objdata_tnoguiaction: record size: integer; data: array[0..1603] of byte end = + (size: 1604; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,110,111, + 103,117,105,97,99,116,105,111,110,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,204,5,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,152,2,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,208,208,208,39,15,147,0,2,208,208, + 208,21,20,144,0,1,27,145,7,1,23,144,5,1,0,0,0,1,208,208, + 208,18,0,128,0,1,19,144,0,1,54,160,38,1,146,224,139,1,85,179, + 73,1,13,88,0,1,0,0,0,1,208,208,208,16,24,146,0,1,21,145, + 1,1,96,188,85,1,179,249,176,1,97,184,86,1,20,129,4,1,6,52, + 0,1,0,0,0,1,208,208,208,15,18,143,0,1,32,150,14,1,137,217, + 131,1,157,232,152,1,42,149,27,1,12,96,0,1,0,0,0,3,208,208, + 208,14,19,145,0,1,61,167,45,1,174,244,170,1,98,187,86,1,20,127, + 3,1,6,40,0,1,0,0,0,3,208,208,208,13,23,139,0,1,22,144, + 3,1,111,199,100,1,161,235,155,1,43,149,26,1,12,90,0,1,0,0, + 0,3,208,208,208,14,19,147,0,1,33,151,15,1,158,235,154,1,98,190, + 87,1,19,125,3,1,3,31,0,1,0,0,0,3,208,208,208,14,18,145, + 0,1,62,170,47,1,157,234,152,1,41,151,24,1,10,84,0,1,0,0, + 0,3,208,208,208,15,18,146,0,1,45,161,29,1,130,213,120,1,22,144, + 4,1,6,51,0,1,0,0,0,3,208,208,208,17,18,138,0,1,21,138, + 2,1,21,135,0,1,21,138,0,1,18,138,0,1,0,128,0,1,208,208, + 208,19,0,64,0,1,17,127,0,1,19,137,0,1,21,137,0,1,20,141, + 0,1,18,135,0,1,208,208,208,19,0,0,0,1,15,91,0,1,17,129, + 0,1,20,138,0,1,21,139,0,1,19,141,0,1,28,142,0,1,208,208, + 208,19,0,0,0,1,12,119,0,1,19,133,0,1,20,139,0,1,20,141, + 0,1,18,140,0,1,0,0,0,1,208,208,208,17,18,237,0,1,0,230, + 0,1,0,0,0,1,17,124,0,1,19,138,0,1,20,143,0,1,18,139, + 0,1,0,102,0,1,208,208,208,16,33,165,12,1,29,194,17,1,0,0, + 0,1,14,142,0,1,18,144,0,1,18,141,0,1,11,77,0,1,0,0, + 0,2,208,208,208,14,25,206,0,1,88,185,72,1,62,173,53,1,18,132, + 0,1,19,144,0,1,19,143,0,1,0,22,0,1,0,0,0,2,208,208, + 208,15,67,184,52,1,148,226,140,1,56,161,43,1,19,139,0,1,20,133, + 0,1,0,0,0,3,208,208,208,15,36,200,27,1,136,220,130,1,173,244, + 169,1,100,189,88,1,48,153,32,1,20,144,0,1,17,165,0,1,15,226, + 0,1,208,208,208,16,110,209,97,1,174,245,171,1,118,203,108,1,56,155, + 41,1,18,124,0,1,17,122,0,1,13,127,0,1,8,106,0,1,0,0, + 0,1,208,208,208,14,43,206,27,1,132,221,127,1,74,168,65,1,21,114, + 14,1,6,51,0,1,0,0,0,4,208,208,208,15,0,255,0,1,0,0, + 0,7,208,208,208,17,0,0,0,3,208,208,208,14,252,2,0,0,0,0, + 0,39,33,33,33,2,0,0,0,21,76,76,76,1,208,208,208,1,164,164, + 164,1,2,2,2,1,0,0,0,18,2,2,2,1,133,133,133,1,202,202, + 202,1,253,253,253,1,211,211,211,1,61,61,61,1,2,2,2,1,0,0, + 0,16,21,21,21,1,183,183,183,1,211,211,211,1,255,255,255,1,216,216, + 216,1,202,202,202,1,79,79,79,1,3,3,3,1,0,0,0,15,57,57, + 57,1,204,204,204,1,230,230,230,1,235,235,235,1,217,217,217,1,143,143, + 143,1,60,60,60,1,19,19,19,1,1,1,1,1,0,0,0,14,109,109, + 109,1,203,203,203,1,248,248,248,1,214,214,214,1,195,195,195,1,89,89, + 89,1,38,38,38,1,7,7,7,1,1,1,1,1,0,0,0,13,11,11, + 11,1,166,166,166,1,205,205,205,1,230,230,230,1,215,215,215,1,133,133, + 133,1,57,57,57,1,17,17,17,1,3,3,3,1,0,0,0,14,40,40, + 40,1,199,199,199,1,221,221,221,1,208,208,208,1,185,185,185,1,82,82, + 82,1,35,35,35,1,6,6,6,1,1,1,1,1,0,0,0,14,86,86, + 86,1,205,205,205,1,218,218,218,1,210,210,210,1,122,122,122,1,54,54, + 54,1,15,15,15,1,3,3,3,1,0,0,0,15,70,70,70,1,237,237, + 237,1,229,229,229,1,240,240,240,1,91,91,91,1,31,31,31,1,5,5, + 5,1,1,1,1,1,0,0,0,17,57,57,57,1,205,205,205,1,231,231, + 231,1,224,224,224,1,102,102,102,1,2,2,2,1,0,0,0,19,4,4, + 4,1,106,106,106,1,224,224,224,1,233,233,233,1,194,194,194,1,44,44, + 44,1,0,0,0,19,1,1,1,1,17,17,17,1,148,148,148,1,234,234, + 234,1,235,235,235,1,135,135,135,1,9,9,9,1,0,0,0,19,2,2, + 2,1,41,41,41,1,186,186,186,1,243,243,243,1,220,220,220,1,71,71, + 71,1,1,1,1,1,0,0,0,17,14,14,14,1,10,10,10,1,3,3, + 3,1,76,76,76,1,218,218,218,1,253,253,253,1,166,166,166,1,5,5, + 5,1,0,0,0,16,124,124,124,1,61,61,61,1,1,1,1,1,18,18, + 18,1,181,181,181,1,210,210,210,1,93,93,93,1,13,13,13,1,1,1, + 1,1,0,0,0,14,31,31,31,1,223,223,223,1,115,115,115,1,58,58, + 58,1,214,214,214,1,119,119,119,1,23,23,23,1,18,18,18,1,2,2, + 2,1,0,0,0,15,148,148,148,1,255,255,255,1,196,196,196,1,188,188, + 188,1,38,38,38,1,12,12,12,1,4,4,4,1,1,1,1,1,0,0, + 0,15,56,56,56,1,240,240,240,1,255,255,255,1,244,244,244,1,193,193, + 193,1,140,140,140,1,88,88,88,1,17,17,17,1,0,0,0,16,173,173, + 173,1,255,255,255,2,244,244,244,1,210,210,210,1,167,167,167,1,114,114, + 114,1,34,34,34,1,1,1,1,1,0,0,0,14,84,84,84,1,193,193, + 193,1,166,166,166,1,143,143,143,1,91,91,91,1,60,60,60,1,40,40, + 40,1,20,20,20,1,3,3,3,1,0,0,0,15,3,3,3,1,7,7, + 7,1,37,37,37,1,22,22,22,1,7,7,7,1,2,2,2,2,1,1, + 1,1,0,0,0,17,1,1,1,1,2,2,2,1,1,1,1,1,0,0, + 0,14,0,0) + ); + +const + objdata_tskincontroller: record size: integer; data: array[0..2306] of byte end = + (size: 2307; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,115,107, + 105,110,99,111,110,116,114,111,108,108,101,114,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,136,8,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,92,6,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,208,208,208, + 2,0,0,0,4,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0, + 4,208,208,208,1,0,0,0,3,208,208,208,22,0,0,0,1,208,208,208, + 2,255,255,255,20,208,208,208,1,0,0,0,1,208,208,208,2,255,255,255, + 1,102,102,102,19,208,208,208,2,0,0,0,1,208,208,208,1,255,255,255, + 1,102,102,102,1,21,237,255,1,21,231,255,1,20,225,255,1,20,220,255, + 1,19,214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17,191,255, + 1,17,185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14,155,255, + 1,14,147,255,1,13,140,255,1,255,255,255,1,102,102,102,1,208,208,208, + 2,0,0,0,1,208,208,208,1,255,255,255,1,102,102,102,1,21,237,255, + 1,21,231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19,208,255, + 1,18,202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16,178,255, + 1,16,170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13,140,255, + 1,255,255,255,1,102,102,102,1,208,208,208,1,0,0,0,2,208,208,208, + 1,255,255,255,1,102,102,102,1,21,237,255,1,21,231,255,1,20,225,255, + 1,20,220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18,197,255, + 1,17,191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15,163,255, + 1,14,155,255,1,14,147,255,1,13,140,255,1,255,255,255,1,102,102,102, + 1,208,208,208,1,0,0,0,1,208,208,208,2,255,255,255,1,102,102,102, + 1,21,237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19,214,255, + 1,19,208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17,185,255, + 1,16,178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14,147,255, + 1,13,140,255,1,255,255,255,1,102,102,102,1,208,208,208,1,0,0,0, + 1,208,208,208,2,255,255,255,1,102,102,102,1,21,237,255,1,21,231,255, + 1,20,225,255,1,20,220,255,1,19,214,255,1,19,208,255,1,18,202,255, + 1,18,197,255,1,17,191,255,1,17,185,255,1,16,178,255,1,16,170,255, + 1,15,163,255,1,14,155,255,1,14,147,255,1,13,140,255,1,255,255,255, + 1,102,102,102,1,208,208,208,1,0,0,0,2,208,208,208,1,255,255,255, + 1,102,102,102,1,21,237,255,1,21,231,255,1,20,225,255,1,20,220,255, + 1,19,214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17,191,255, + 1,17,185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14,155,255, + 1,14,147,255,1,13,140,255,1,255,255,255,1,102,102,102,1,208,208,208, + 2,0,0,0,1,208,208,208,1,255,255,255,1,102,102,102,1,21,237,255, + 1,21,231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19,208,255, + 1,18,202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16,178,255, + 1,16,170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13,140,255, + 1,255,255,255,1,102,102,102,1,208,208,208,2,0,0,0,1,208,208,208, + 1,255,255,255,1,102,102,102,1,21,237,255,1,21,231,255,1,20,225,255, + 1,20,220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18,197,255, + 1,17,191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15,163,255, + 1,14,155,255,1,14,147,255,1,13,140,255,1,255,255,255,1,102,102,102, + 1,208,208,208,1,0,0,0,2,208,208,208,1,255,255,255,1,102,102,102, + 1,21,237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19,214,255, + 1,19,208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17,185,255, + 1,16,178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14,147,255, + 1,13,140,255,1,255,255,255,1,102,102,102,1,208,208,208,1,0,0,0, + 1,208,208,208,2,255,255,255,1,102,102,102,1,21,237,255,1,21,231,255, + 1,20,225,255,1,20,220,255,1,19,214,255,1,19,208,255,1,18,202,255, + 1,18,197,255,1,17,191,255,1,17,185,255,1,16,178,255,1,16,170,255, + 1,15,163,255,1,14,155,255,1,14,147,255,1,13,140,255,1,255,255,255, + 1,102,102,102,1,208,208,208,1,0,0,0,1,208,208,208,2,255,255,255, + 1,102,102,102,1,21,237,255,1,21,231,255,1,20,225,255,1,20,220,255, + 1,19,214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17,191,255, + 1,17,185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14,155,255, + 1,14,147,255,1,13,140,255,1,255,255,255,1,102,102,102,1,208,208,208, + 1,0,0,0,2,208,208,208,1,255,255,255,1,102,102,102,1,21,237,255, + 1,21,231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19,208,255, + 1,18,202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16,178,255, + 1,16,170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13,140,255, + 1,255,255,255,1,102,102,102,1,208,208,208,2,0,0,0,1,208,208,208, + 1,255,255,255,1,102,102,102,1,21,237,255,1,21,231,255,1,20,225,255, + 1,20,220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18,197,255, + 1,17,191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15,163,255, + 1,14,155,255,1,14,147,255,1,13,140,255,1,255,255,255,1,102,102,102, + 1,208,208,208,2,0,0,0,1,208,208,208,1,255,255,255,1,102,102,102, + 1,21,237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19,214,255, + 1,19,208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17,185,255, + 1,16,178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14,147,255, + 1,13,140,255,1,255,255,255,1,102,102,102,1,208,208,208,1,0,0,0, + 2,208,208,208,1,255,255,255,1,102,102,102,1,21,237,255,1,21,231,255, + 1,20,225,255,1,20,220,255,1,19,214,255,1,19,208,255,1,18,202,255, + 1,18,197,255,1,17,191,255,1,17,185,255,1,16,178,255,1,16,170,255, + 1,15,163,255,1,14,155,255,1,14,147,255,1,13,140,255,1,255,255,255, + 1,102,102,102,1,208,208,208,1,0,0,0,1,208,208,208,2,255,255,255, + 1,102,102,102,1,21,237,255,1,21,231,255,1,20,225,255,1,20,220,255, + 1,19,214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17,191,255, + 1,17,185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14,155,255, + 1,14,147,255,1,13,140,255,1,255,255,255,1,102,102,102,1,208,208,208, + 1,0,0,0,1,208,208,208,2,255,255,255,19,102,102,102,1,208,208,208, + 1,0,0,0,2,208,208,208,1,102,102,102,20,208,208,208,2,0,0,0, + 1,208,208,208,22,0,0,0,3,208,208,208,2,0,0,0,3,208,208,208, + 2,0,0,0,4,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0, + 3,244,1,0,0,240,240,240,2,210,210,210,1,0,0,0,2,60,60,60, + 1,240,240,240,2,150,150,150,1,0,0,0,2,120,120,120,1,240,240,240, + 2,90,90,90,1,0,0,0,2,187,187,187,1,240,240,240,2,22,22,22, + 1,0,0,0,1,7,7,7,1,240,240,240,1,52,52,52,1,0,0,0, + 22,240,240,240,1,0,0,0,2,255,255,255,20,0,0,0,1,202,202,202, + 1,0,0,0,2,255,255,255,20,0,0,0,2,217,217,217,1,0,0,0, + 1,255,255,255,20,0,0,0,2,240,240,240,1,0,0,0,1,255,255,255, + 20,0,0,0,1,75,75,75,1,225,225,225,1,0,0,0,1,255,255,255, + 20,0,0,0,1,240,240,240,1,0,0,0,2,255,255,255,20,0,0,0, + 1,240,240,240,1,0,0,0,2,255,255,255,20,0,0,0,1,135,135,135, + 1,45,45,45,1,0,0,0,1,255,255,255,20,0,0,0,2,240,240,240, + 1,0,0,0,1,255,255,255,20,0,0,0,2,240,240,240,1,0,0,0, + 1,255,255,255,20,0,0,0,1,135,135,135,1,165,165,165,1,0,0,0, + 1,255,255,255,20,0,0,0,1,240,240,240,1,0,0,0,2,255,255,255, + 20,0,0,0,1,240,240,240,1,0,0,0,2,255,255,255,20,0,0,0, + 1,75,75,75,1,105,105,105,1,0,0,0,1,255,255,255,20,0,0,0, + 2,240,240,240,1,0,0,0,1,255,255,255,20,0,0,0,2,240,240,240, + 1,0,0,0,1,255,255,255,20,0,0,0,1,202,202,202,1,97,97,97, + 1,0,0,0,1,255,255,255,20,0,0,0,1,240,240,240,1,0,0,0, + 2,255,255,255,20,0,0,0,1,240,240,240,1,0,0,0,2,255,255,255, + 20,0,0,0,1,7,7,7,1,172,172,172,1,0,0,0,1,255,255,255, + 20,0,0,0,2,240,240,240,1,0,0,0,22,22,22,22,1,240,240,240, + 1,37,37,37,1,0,0,0,2,232,232,232,1,240,240,240,1,210,210,210, + 1,0,0,0,2,60,60,60,1,240,240,240,2,150,150,150,1,0,0,0, + 2,120,120,120,1,240,240,240,2,90,90,90,1,0,0,0,2,187,187,187, + 1,240,240,240,2,0,0) + ); + +const + objdata_tskinextender: record size: integer; data: array[0..1536] of byte end = + (size: 1537; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,115,107, + 105,110,101,120,116,101,110,100,101,114,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,136,5,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,92,3,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,208,208,208,2,0, + 0,0,4,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,4,208, + 208,208,1,0,0,0,3,208,208,208,22,0,0,0,1,208,208,208,2,255, + 255,255,20,208,208,208,1,0,0,0,1,208,208,208,2,255,255,255,1,102, + 102,102,19,208,208,208,2,0,0,0,1,208,208,208,1,255,255,255,1,102, + 102,102,1,21,237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19, + 214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17, + 185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14, + 147,255,1,13,140,255,1,255,255,255,1,102,102,102,1,208,208,208,2,0, + 0,0,1,208,208,208,1,255,255,255,1,102,102,102,1,21,237,255,1,21, + 231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19,208,255,1,18, + 202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16,178,255,1,16, + 170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13,140,255,1,255, + 255,255,1,102,102,102,1,208,208,208,1,0,0,0,2,208,208,208,1,255, + 255,255,1,102,102,102,1,21,237,255,1,21,231,255,1,20,225,255,1,20, + 220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17, + 191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14, + 155,255,1,14,147,255,1,13,140,255,1,255,255,255,1,102,102,102,1,208, + 208,208,1,0,0,0,1,208,208,208,2,255,255,255,1,102,102,102,1,21, + 237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19, + 208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16, + 178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13, + 140,255,1,255,255,255,1,102,102,102,1,208,208,208,1,0,0,0,1,208, + 208,208,2,255,255,255,1,102,102,102,1,21,237,255,1,21,231,255,1,20, + 225,255,1,20,220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18, + 197,255,1,17,191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15, + 163,255,1,14,155,255,1,14,147,255,1,13,140,255,1,255,255,255,1,102, + 102,102,1,208,208,208,1,0,0,0,2,208,208,208,1,255,255,255,1,102, + 102,102,1,21,237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19, + 214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17, + 185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14, + 147,255,1,13,140,255,1,255,255,255,1,102,102,102,1,208,208,208,2,0, + 0,0,1,208,208,208,1,255,255,255,19,102,102,102,1,208,208,208,2,0, + 0,0,1,208,208,208,1,102,102,102,20,208,208,208,1,0,0,0,2,208, + 208,208,1,255,255,255,1,208,208,208,20,0,0,0,1,208,208,208,2,255, + 255,255,1,208,208,208,20,0,0,0,1,208,208,208,2,255,255,255,1,208, + 208,208,20,0,0,0,2,208,208,208,1,255,255,255,1,208,208,208,21,0, + 0,0,1,208,208,208,1,255,255,255,1,208,208,208,21,0,0,0,1,208, + 208,208,1,255,255,255,1,208,208,208,20,0,0,0,2,208,208,208,1,255, + 255,255,1,208,208,208,20,0,0,0,1,208,208,208,2,255,255,255,1,208, + 208,208,20,0,0,0,1,208,208,208,2,255,255,255,1,208,208,208,20,0, + 0,0,2,208,208,208,23,0,0,0,1,208,208,208,22,0,0,0,3,208, + 208,208,2,0,0,0,3,208,208,208,2,0,0,0,4,208,208,208,2,0, + 0,0,4,208,208,208,2,0,0,0,3,244,1,0,0,240,240,240,2,210, + 210,210,1,0,0,0,2,60,60,60,1,240,240,240,2,150,150,150,1,0, + 0,0,2,120,120,120,1,240,240,240,2,90,90,90,1,0,0,0,2,187, + 187,187,1,240,240,240,2,22,22,22,1,0,0,0,1,7,7,7,1,240, + 240,240,1,52,52,52,1,0,0,0,22,240,240,240,1,0,0,0,2,255, + 255,255,20,0,0,0,1,202,202,202,1,0,0,0,2,255,255,255,20,0, + 0,0,2,217,217,217,1,0,0,0,1,255,255,255,20,0,0,0,2,240, + 240,240,1,0,0,0,1,255,255,255,20,0,0,0,1,75,75,75,1,225, + 225,225,1,0,0,0,1,255,255,255,20,0,0,0,1,240,240,240,1,0, + 0,0,2,255,255,255,20,0,0,0,1,240,240,240,1,0,0,0,2,255, + 255,255,20,0,0,0,1,135,135,135,1,45,45,45,1,0,0,0,1,255, + 255,255,20,0,0,0,2,240,240,240,1,0,0,0,1,255,255,255,1,128, + 128,128,1,255,255,255,18,0,0,0,2,240,240,240,1,0,0,0,1,255, + 255,255,20,0,0,0,1,135,135,135,1,165,165,165,1,0,0,0,1,255, + 255,255,1,0,0,0,20,240,240,240,1,0,0,0,2,255,255,255,1,0, + 0,0,20,240,240,240,1,0,0,0,2,255,255,255,1,0,0,0,20,75, + 75,75,1,105,105,105,1,0,0,0,1,255,255,255,1,0,0,0,21,240, + 240,240,1,0,0,0,1,255,255,255,1,0,0,0,21,240,240,240,1,0, + 0,0,1,255,255,255,1,0,0,0,20,202,202,202,1,97,97,97,1,0, + 0,0,1,255,255,255,1,0,0,0,20,240,240,240,1,0,0,0,2,255, + 255,255,1,0,0,0,20,240,240,240,1,0,0,0,2,255,255,255,1,0, + 0,0,20,7,7,7,1,172,172,172,1,0,0,0,23,240,240,240,1,0, + 0,0,22,22,22,22,1,240,240,240,1,37,37,37,1,0,0,0,2,232, + 232,232,1,240,240,240,1,210,210,210,1,0,0,0,2,60,60,60,1,240, + 240,240,2,150,150,150,1,0,0,0,2,120,120,120,1,240,240,240,2,90, + 90,90,1,0,0,0,2,187,187,187,1,240,240,240,2,0,0) + ); + +const + objdata_tshortcutcontroller: record size: integer; data: array[0..2850] of byte end = + (size: 2851; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,115,104, + 111,114,116,99,117,116,99,111,110,116,114,111,108,108,101,114,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,164,10,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,212,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,4, + 1,5,5,7,1,17,17,22,1,177,177,229,1,180,180,230,1,113,113,143, + 1,6,6,7,2,49,49,61,1,192,192,234,1,195,195,234,1,71,71,85, + 1,6,6,7,2,98,98,114,1,207,207,238,1,209,209,239,1,33,33,37, + 1,7,7,7,2,184,184,203,1,222,222,242,1,212,212,230,1,3,3,4, + 1,113,113,151,1,172,172,228,1,175,175,229,1,177,177,229,1,180,180,230, + 1,182,182,231,1,185,185,232,1,187,187,232,1,190,190,233,1,192,192,234, + 1,195,195,234,1,197,197,235,1,199,199,236,1,202,202,236,1,204,204,237, + 1,207,207,238,1,209,209,239,1,212,212,239,1,214,214,240,1,217,217,241, + 1,219,219,241,1,222,222,242,1,224,224,243,1,7,7,7,1,171,171,228, + 1,172,172,228,1,175,175,229,1,177,177,229,1,180,180,230,1,182,182,231, + 1,185,185,232,1,187,187,232,1,190,190,233,1,192,192,234,1,195,195,234, + 1,197,197,235,1,199,199,236,1,202,202,236,1,204,204,237,1,207,207,238, + 1,209,209,239,1,212,212,239,1,214,214,240,1,217,217,241,1,219,219,241, + 1,222,222,242,1,224,224,243,1,26,26,28,1,171,171,228,1,172,172,228, + 1,175,175,229,1,177,177,229,1,180,180,230,1,182,182,231,1,185,185,232, + 1,187,187,232,1,190,190,233,1,192,192,234,1,195,195,234,1,197,197,235, + 1,199,199,236,1,202,202,236,1,204,204,237,1,207,207,238,1,209,209,239, + 1,212,212,239,1,214,214,240,1,217,217,241,1,219,219,241,1,222,222,242, + 1,224,224,243,1,226,226,243,1,14,14,18,1,172,172,228,1,175,175,229, + 1,177,177,229,1,180,180,230,1,182,182,231,1,185,185,232,1,187,187,232, + 1,190,190,233,1,192,192,234,1,195,195,234,1,197,197,235,1,199,199,236, + 1,202,202,236,1,204,204,237,1,207,207,238,1,209,209,239,1,212,212,239, + 1,214,214,240,1,217,217,241,1,219,219,241,1,222,222,242,1,224,224,243, + 1,226,226,243,1,5,5,7,1,172,172,228,1,175,175,229,1,177,177,229, + 1,180,180,230,1,173,173,220,1,63,63,79,1,7,7,9,1,31,31,38, + 1,162,162,197,1,195,195,234,1,197,197,235,1,90,90,106,1,202,202,236, + 1,204,204,237,1,207,207,238,1,209,209,239,1,212,212,239,1,0,0,0, + 1,217,217,241,1,219,219,241,1,222,222,242,1,224,224,243,1,123,123,133, + 1,11,11,14,1,172,172,228,1,175,175,229,1,177,177,229,1,180,180,230, + 1,78,78,99,1,131,131,165,1,184,184,228,1,109,109,133,1,44,44,54, + 1,195,195,234,1,197,197,235,1,0,0,0,1,202,202,236,1,204,204,237, + 1,207,207,238,1,209,209,239,1,212,212,239,1,0,0,0,1,217,217,241, + 1,219,219,241,1,222,222,242,1,224,224,243,1,7,7,7,1,171,171,228, + 1,172,172,228,1,175,175,229,1,177,177,229,1,180,180,230,1,19,19,24, + 1,165,165,207,1,187,187,232,1,187,187,229,1,154,154,187,1,195,195,234, + 1,0,0,0,3,204,204,237,1,0,0,0,1,58,58,67,1,212,212,239, + 1,0,0,0,1,217,217,241,1,219,219,241,1,222,222,242,1,224,224,243, + 1,7,7,7,1,171,171,228,1,172,172,228,1,175,175,229,1,177,177,229, + 1,180,180,230,1,4,4,5,1,183,183,229,1,187,187,232,1,190,190,233, + 1,192,192,234,1,195,195,234,1,197,197,235,1,0,0,0,1,202,202,236, + 1,204,204,237,1,0,0,0,1,175,175,200,1,212,212,239,1,0,0,0, + 1,217,217,241,1,219,219,241,1,222,222,242,1,224,224,243,1,70,70,75, + 1,120,120,160,1,172,172,228,1,175,175,229,1,177,177,229,1,180,180,230, + 1,21,21,26,1,165,165,207,1,187,187,232,1,181,181,222,1,104,104,127, + 1,195,195,234,1,197,197,235,1,0,0,0,1,202,202,236,1,204,204,237, + 1,0,0,0,1,208,208,238,1,212,212,239,1,0,0,0,1,217,217,241, + 1,219,219,241,1,222,222,242,1,224,224,243,1,226,226,243,1,5,5,7, + 1,172,172,228,1,175,175,229,1,177,177,229,1,180,180,230,1,76,76,97, + 1,129,129,162,1,183,183,227,1,94,94,115,1,54,54,66,1,195,195,234, + 1,197,197,235,1,0,0,0,1,191,191,223,1,204,204,237,1,0,0,0, + 1,209,209,239,1,212,212,239,1,0,0,0,1,217,217,241,1,219,219,241, + 1,222,222,242,1,224,224,243,1,226,226,243,1,5,5,7,1,172,172,228, + 1,175,175,229,1,177,177,229,1,180,180,230,1,171,171,217,1,53,53,66, + 1,6,6,7,1,37,37,46,1,166,166,203,1,195,195,234,1,197,197,235, + 1,44,44,52,1,6,6,6,1,204,204,237,1,0,0,0,1,209,209,239, + 1,212,212,239,1,0,0,0,1,217,217,241,1,219,219,241,1,222,222,242, + 1,224,224,243,1,70,70,75,1,37,37,49,1,172,172,228,1,175,175,229, + 1,177,177,229,1,180,180,230,1,182,182,231,1,185,185,232,1,187,187,232, + 1,190,190,233,1,192,192,234,1,195,195,234,1,197,197,235,1,199,199,236, + 1,202,202,236,1,204,204,237,1,207,207,238,1,209,209,239,1,212,212,239, + 1,214,214,240,1,217,217,241,1,219,219,241,1,222,222,242,1,224,224,243, + 1,7,7,7,1,171,171,228,1,172,172,228,1,175,175,229,1,177,177,229, + 1,180,180,230,1,182,182,231,1,185,185,232,1,187,187,232,1,190,190,233, + 1,192,192,234,1,195,195,234,1,197,197,235,1,199,199,236,1,202,202,236, + 1,204,204,237,1,207,207,238,1,209,209,239,1,212,212,239,1,214,214,240, + 1,217,217,241,1,219,219,241,1,222,222,242,1,224,224,243,1,7,7,7, + 1,171,171,228,1,172,172,228,1,175,175,229,1,177,177,229,1,180,180,230, + 1,182,182,231,1,185,185,232,1,187,187,232,1,190,190,233,1,192,192,234, + 1,195,195,234,1,197,197,235,1,199,199,236,1,202,202,236,1,204,204,237, + 1,207,207,238,1,209,209,239,1,212,212,239,1,214,214,240,1,217,217,241, + 1,219,219,241,1,222,222,242,1,224,224,243,1,123,123,133,1,71,71,95, + 1,172,172,228,1,175,175,229,1,177,177,229,1,180,180,230,1,182,182,231, + 1,185,185,232,1,187,187,232,1,190,190,233,1,192,192,234,1,195,195,234, + 1,197,197,235,1,199,199,236,1,202,202,236,1,204,204,237,1,207,207,238, + 1,209,209,239,1,212,212,239,1,214,214,240,1,217,217,241,1,219,219,241, + 1,222,222,242,1,224,224,243,1,226,226,243,1,5,5,7,1,172,172,228, + 1,175,175,229,1,177,177,229,1,180,180,230,1,182,182,231,1,185,185,232, + 1,187,187,232,1,190,190,233,1,192,192,234,1,195,195,234,1,0,0,0, + 1,199,199,236,1,202,202,236,1,204,204,237,1,207,207,238,1,209,209,239, + 1,212,212,239,1,214,214,240,1,217,217,241,1,219,219,241,1,222,222,242, + 1,224,224,243,1,226,226,243,1,5,5,7,1,172,172,228,1,175,175,229, + 1,177,177,229,1,180,180,230,1,182,182,231,1,185,185,232,1,187,187,232, + 1,190,190,233,1,192,192,234,1,195,195,234,1,0,0,0,1,199,199,236, + 1,202,202,236,1,204,204,237,1,207,207,238,1,209,209,239,1,212,212,239, + 1,214,214,240,1,217,217,241,1,219,219,241,1,222,222,242,1,224,224,243, + 1,26,26,28,1,77,77,103,1,172,172,228,1,175,175,229,1,177,177,229, + 1,180,180,230,1,182,182,231,1,185,185,232,1,187,187,232,1,190,190,233, + 1,0,0,0,5,204,204,237,1,207,207,238,1,209,209,239,1,212,212,239, + 1,214,214,240,1,217,217,241,1,219,219,241,1,222,222,242,1,224,224,243, + 1,7,7,7,1,171,171,228,1,172,172,228,1,175,175,229,1,177,177,229, + 1,180,180,230,1,182,182,231,1,185,185,232,1,187,187,232,1,190,190,233, + 1,192,192,234,1,195,195,234,1,0,0,0,1,199,199,236,1,202,202,236, + 1,204,204,237,1,207,207,238,1,209,209,239,1,212,212,239,1,214,214,240, + 1,217,217,241,1,219,219,241,1,222,222,242,1,224,224,243,1,7,7,7, + 1,171,171,228,1,172,172,228,1,175,175,229,1,177,177,229,1,180,180,230, + 1,182,182,231,1,185,185,232,1,187,187,232,1,190,190,233,1,192,192,234, + 1,195,195,234,1,0,0,0,1,199,199,236,1,202,202,236,1,204,204,237, + 1,207,207,238,1,209,209,239,1,212,212,239,1,214,214,240,1,217,217,241, + 1,219,219,241,1,222,222,242,1,224,224,243,1,214,214,230,1,33,33,44, + 1,172,172,228,1,175,175,229,1,177,177,229,1,180,180,230,1,182,182,231, + 1,185,185,232,1,187,187,232,1,190,190,233,1,192,192,234,1,195,195,234, + 1,197,197,235,1,199,199,236,1,202,202,236,1,204,204,237,1,207,207,238, + 1,209,209,239,1,212,212,239,1,214,214,240,1,217,217,241,1,219,219,241, + 1,222,222,242,1,224,224,243,1,226,226,243,1,5,5,7,1,172,172,228, + 1,175,175,229,1,177,177,229,1,180,180,230,1,182,182,231,1,185,185,232, + 1,187,187,232,1,190,190,233,1,192,192,234,1,195,195,234,1,197,197,235, + 1,199,199,236,1,202,202,236,1,204,204,237,1,207,207,238,1,209,209,239, + 1,212,212,239,1,214,214,240,1,217,217,241,1,219,219,241,1,222,222,242, + 1,224,224,243,1,190,190,205,1,3,3,4,1,129,129,170,1,175,175,229, + 1,177,177,229,1,9,9,11,1,6,6,7,1,18,18,23,1,187,187,232, + 1,190,190,233,1,119,119,145,1,6,6,7,2,52,52,61,1,202,202,236, + 1,204,204,237,1,75,75,86,1,6,6,7,2,103,103,115,1,217,217,241, + 1,219,219,241,1,34,34,37,1,7,7,7,1,3,3,4,1,152,1,0, + 0,244,244,244,1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158, + 1,248,248,248,2,203,203,203,1,128,128,128,2,188,188,188,1,248,248,248, + 2,173,173,173,1,128,128,128,2,221,221,221,1,248,248,248,2,139,139,139, + 1,128,128,128,1,131,131,131,1,244,244,244,1,154,154,154,1,255,255,255, + 22,248,248,248,1,128,128,128,1,255,255,255,22,229,229,229,1,128,128,128, + 1,255,255,255,22,128,128,128,1,236,236,236,1,255,255,255,22,128,128,128, + 1,248,248,248,1,255,255,255,22,165,165,165,1,240,240,240,1,255,255,255, + 22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128, + 1,255,255,255,22,195,195,195,1,150,150,150,1,255,255,255,22,128,128,128, + 1,248,248,248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255, + 22,195,195,195,1,210,210,210,1,255,255,255,22,248,248,248,1,128,128,128, + 1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,165,165,165, + 1,180,180,180,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255, + 22,128,128,128,1,248,248,248,1,255,255,255,22,229,229,229,1,176,176,176, + 1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248, + 1,128,128,128,1,255,255,255,22,131,131,131,1,214,214,214,1,255,255,255, + 22,128,128,128,1,248,248,248,1,255,255,255,22,139,139,139,1,244,244,244, + 1,146,146,146,1,128,128,128,2,244,244,244,1,248,248,248,1,233,233,233, + 1,128,128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128, + 2,188,188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221, + 1,248,248,248,1,244,244,244,1,0,0) + ); + +const + objdata_thelpcontroller: record size: integer; data: array[0..2858] of byte end = + (size: 2859; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,104,101, + 108,112,99,111,110,116,114,111,108,108,101,114,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,176,10,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,228,8,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,3,3, + 1,15,15,20,1,177,177,229,1,180,180,230,1,114,114,144,1,3,3,3, + 2,49,49,60,1,192,192,234,1,195,195,234,1,71,71,85,1,3,3,4, + 2,98,98,114,1,207,207,238,1,209,209,239,1,35,35,39,1,3,3,4, + 2,174,174,191,1,221,221,242,1,213,213,231,1,0,0,0,1,121,121,161, + 1,172,172,228,1,175,175,229,1,177,177,229,1,180,180,230,1,182,182,231, + 1,185,185,232,1,187,187,232,1,190,190,233,1,192,192,234,1,195,195,234, + 1,197,197,235,1,199,199,236,1,202,202,236,1,204,204,237,1,207,207,238, + 1,209,209,239,1,212,212,239,1,214,214,240,1,217,217,241,1,219,219,241, + 1,221,221,242,1,224,224,243,1,3,3,4,1,171,171,228,1,172,172,228, + 1,175,175,229,1,177,177,229,1,180,180,230,1,182,182,231,1,185,185,232, + 1,187,187,232,1,190,190,233,1,192,192,234,1,195,195,234,1,197,197,235, + 1,199,199,236,1,202,202,236,1,204,204,237,1,207,207,238,1,209,209,239, + 1,212,212,239,1,214,214,240,1,217,217,241,1,219,219,241,1,221,221,242, + 1,224,224,243,1,28,28,30,1,171,171,228,1,172,172,228,1,175,175,229, + 1,177,177,229,1,180,180,230,1,182,182,231,1,185,185,232,1,187,187,232, + 1,190,190,233,1,192,192,234,1,195,195,234,1,197,197,235,1,199,199,236, + 1,202,202,236,1,204,204,237,1,207,207,238,1,209,209,239,1,212,212,239, + 1,214,214,240,1,217,217,241,1,219,219,241,1,221,221,242,1,224,224,243, + 1,226,226,243,1,9,9,11,1,172,172,228,1,175,175,229,1,177,177,229, + 1,180,180,230,1,182,182,231,1,185,185,232,1,187,187,232,1,190,190,233, + 1,192,192,234,1,195,195,234,1,197,197,235,1,199,199,236,1,202,202,236, + 1,204,204,237,1,207,207,238,1,209,209,239,1,212,212,239,1,214,214,240, + 1,217,217,241,1,219,219,241,1,221,221,242,1,224,224,243,1,226,226,243, + 1,3,3,3,1,172,172,228,1,175,175,229,1,177,177,229,1,180,180,230, + 1,182,182,231,1,185,185,232,1,187,187,232,1,190,190,233,1,192,192,234, + 1,195,195,234,1,197,197,235,1,199,199,236,1,202,202,236,1,204,204,237, + 1,207,207,238,1,209,209,239,1,212,212,239,1,214,214,240,1,217,217,241, + 1,219,219,241,1,221,221,242,1,224,224,243,1,125,125,134,1,9,9,11, + 1,172,172,228,1,175,175,229,1,177,177,229,1,180,180,230,1,182,182,231, + 1,185,185,232,1,187,187,232,1,190,190,233,1,192,192,234,1,195,195,234, + 1,197,197,235,1,199,199,236,1,202,202,236,1,204,204,237,1,207,207,238, + 1,209,209,239,1,212,212,239,1,214,214,240,1,217,217,241,1,219,219,241, + 1,221,221,242,1,224,224,243,1,3,3,4,1,171,171,228,1,172,172,228, + 1,171,171,224,1,177,177,229,1,180,180,230,1,182,182,231,1,185,185,232, + 1,183,183,227,1,190,190,233,1,192,192,234,1,195,195,234,1,197,197,235, + 1,199,199,236,1,202,202,236,1,204,204,237,1,201,201,231,1,209,209,239, + 1,212,212,239,1,214,214,240,1,217,217,241,1,219,219,241,1,221,221,242, + 1,224,224,243,1,3,3,4,1,171,171,228,1,172,172,228,1,27,27,35, + 1,155,155,201,1,180,180,230,1,182,182,231,1,168,168,210,1,23,23,29, + 1,190,190,233,1,192,192,234,1,195,195,234,1,197,197,235,1,199,199,236, + 1,202,202,236,1,204,204,237,1,25,25,29,1,209,209,239,1,212,212,239, + 1,214,214,240,1,217,217,241,1,219,219,241,1,221,221,242,1,224,224,243, + 1,70,70,75,1,121,121,161,1,172,172,228,1,27,27,35,1,155,155,201, + 1,180,180,230,1,182,182,231,1,168,168,210,1,23,23,29,1,190,190,233, + 1,192,192,234,1,195,195,234,1,186,186,222,1,199,199,236,1,202,202,236, + 1,204,204,237,1,25,25,29,1,209,209,239,1,208,208,234,1,213,213,239, + 1,198,198,220,1,218,218,240,1,221,221,242,1,224,224,243,1,226,226,243, + 1,3,3,3,1,172,172,228,1,27,27,35,1,151,151,195,1,174,174,223, + 1,176,176,224,1,163,163,204,1,23,23,29,1,190,190,233,1,166,166,203, + 1,64,64,77,1,61,61,73,1,58,58,68,1,170,170,198,1,204,204,237, + 1,25,25,29,1,209,209,239,1,61,61,68,1,54,54,60,1,66,66,74, + 1,32,32,35,1,188,188,206,1,224,224,243,1,226,226,243,1,3,3,3, + 1,172,172,228,1,27,27,35,1,29,29,38,1,33,33,42,1,34,34,43, + 1,31,31,39,1,23,23,29,1,190,190,233,1,88,88,107,1,137,137,164, + 1,197,197,235,1,157,157,186,1,85,85,99,1,204,204,237,1,25,25,29, + 1,209,209,239,1,61,61,68,1,122,122,136,1,217,217,241,1,145,145,160, + 1,71,71,78,1,224,224,243,1,70,70,75,1,36,36,48,1,172,172,228, + 1,27,27,35,1,155,155,201,1,180,180,230,1,182,182,231,1,168,168,210, + 1,23,23,29,1,190,190,233,1,32,32,39,1,46,46,55,1,49,49,58, + 2,53,53,62,1,204,204,237,1,25,25,29,1,209,209,239,1,61,61,68, + 1,176,176,198,1,217,217,241,1,198,198,217,1,36,36,40,1,224,224,243, + 1,3,3,4,1,171,171,228,1,172,172,228,1,27,27,35,1,155,155,201, + 1,180,180,230,1,182,182,231,1,168,168,210,1,23,23,29,1,190,190,233, + 1,70,70,85,1,148,148,177,1,197,197,235,1,184,184,218,1,138,138,161, + 1,204,204,237,1,25,25,29,1,209,209,239,1,61,61,68,1,140,140,157, + 1,217,217,241,1,156,156,172,1,66,66,72,1,224,224,243,1,3,3,4, + 1,171,171,228,1,172,172,228,1,27,27,35,1,155,155,201,1,180,180,230, + 1,182,182,231,1,168,168,210,1,23,23,29,1,190,190,233,1,146,146,178, + 1,43,43,51,1,104,104,123,1,46,46,55,1,125,125,146,1,204,204,237, + 1,25,25,29,1,209,209,239,1,61,61,68,1,38,38,42,1,109,109,121, + 1,37,37,41,1,170,170,186,1,224,224,243,1,125,125,134,1,72,72,96, + 1,172,172,228,1,138,138,181,1,172,172,223,1,180,180,230,1,182,182,231, + 1,181,181,227,1,147,147,182,1,190,190,233,1,192,192,234,1,190,190,228, + 1,141,141,169,1,177,177,210,1,202,202,236,1,204,204,237,1,162,162,186, + 1,209,209,239,1,61,61,68,1,159,159,178,1,150,150,166,1,196,196,215, + 1,221,221,242,1,224,224,243,1,226,226,243,1,3,3,3,1,172,172,228, + 1,175,175,229,1,177,177,229,1,180,180,230,1,182,182,231,1,185,185,232, + 1,187,187,232,1,190,190,233,1,192,192,234,1,195,195,234,1,197,197,235, + 1,199,199,236,1,202,202,236,1,204,204,237,1,207,207,238,1,209,209,239, + 1,61,61,68,1,173,173,194,1,217,217,241,1,219,219,241,1,221,221,242, + 1,224,224,243,1,226,226,243,1,3,3,3,1,172,172,228,1,175,175,229, + 1,177,177,229,1,180,180,230,1,182,182,231,1,185,185,232,1,187,187,232, + 1,190,190,233,1,192,192,234,1,195,195,234,1,197,197,235,1,199,199,236, + 1,202,202,236,1,204,204,237,1,207,207,238,1,209,209,239,1,170,170,191, + 1,203,203,228,1,217,217,241,1,219,219,241,1,221,221,242,1,224,224,243, + 1,28,28,30,1,72,72,96,1,172,172,228,1,175,175,229,1,177,177,229, + 1,180,180,230,1,182,182,231,1,185,185,232,1,187,187,232,1,190,190,233, + 1,192,192,234,1,195,195,234,1,197,197,235,1,199,199,236,1,202,202,236, + 1,204,204,237,1,207,207,238,1,209,209,239,1,212,212,239,1,214,214,240, + 1,217,217,241,1,219,219,241,1,221,221,242,1,224,224,243,1,3,3,4, + 1,171,171,228,1,172,172,228,1,175,175,229,1,177,177,229,1,180,180,230, + 1,182,182,231,1,185,185,232,1,187,187,232,1,190,190,233,1,192,192,234, + 1,195,195,234,1,197,197,235,1,199,199,236,1,202,202,236,1,204,204,237, + 1,207,207,238,1,209,209,239,1,212,212,239,1,214,214,240,1,217,217,241, + 1,219,219,241,1,221,221,242,1,224,224,243,1,3,3,4,1,171,171,228, + 1,172,172,228,1,175,175,229,1,177,177,229,1,180,180,230,1,182,182,231, + 1,185,185,232,1,187,187,232,1,190,190,233,1,192,192,234,1,195,195,234, + 1,197,197,235,1,199,199,236,1,202,202,236,1,204,204,237,1,207,207,238, + 1,209,209,239,1,212,212,239,1,214,214,240,1,217,217,241,1,219,219,241, + 1,221,221,242,1,224,224,243,1,202,202,218,1,36,36,48,1,172,172,228, + 1,175,175,229,1,177,177,229,1,180,180,230,1,182,182,231,1,185,185,232, + 1,187,187,232,1,190,190,233,1,192,192,234,1,195,195,234,1,197,197,235, + 1,199,199,236,1,202,202,236,1,204,204,237,1,207,207,238,1,209,209,239, + 1,212,212,239,1,214,214,240,1,217,217,241,1,219,219,241,1,221,221,242, + 1,224,224,243,1,226,226,243,1,3,3,3,1,172,172,228,1,175,175,229, + 1,177,177,229,1,180,180,230,1,182,182,231,1,185,185,232,1,187,187,232, + 1,190,190,233,1,192,192,234,1,195,195,234,1,197,197,235,1,199,199,236, + 1,202,202,236,1,204,204,237,1,207,207,238,1,209,209,239,1,212,212,239, + 1,214,214,240,1,217,217,241,1,219,219,241,1,221,221,242,1,224,224,243, + 1,202,202,218,1,0,0,0,1,137,137,181,1,175,175,229,1,177,177,229, + 1,3,3,3,2,16,16,20,1,187,187,232,1,190,190,233,1,120,120,146, + 1,3,3,3,2,51,51,60,1,202,202,236,1,204,204,237,1,75,75,86, + 1,3,3,4,2,103,103,116,1,217,217,241,1,219,219,241,1,37,37,40, + 1,3,3,4,1,0,0,0,1,148,1,0,0,255,255,255,1,252,252,252, + 1,237,237,237,1,136,136,136,2,165,165,165,1,252,252,252,2,208,208,208, + 1,136,136,136,2,194,194,194,1,252,252,252,2,179,179,179,1,136,136,136, + 2,223,223,223,1,252,252,252,2,150,150,150,1,136,136,136,1,139,139,139, + 1,255,255,255,1,157,157,157,1,255,255,255,22,252,252,252,1,136,136,136, + 1,255,255,255,22,230,230,230,1,136,136,136,1,255,255,255,22,136,136,136, + 1,244,244,244,1,255,255,255,22,136,136,136,1,252,252,252,1,255,255,255, + 22,172,172,172,1,244,244,244,1,255,255,255,22,252,252,252,1,136,136,136, + 1,255,255,255,22,252,252,252,1,136,136,136,1,255,255,255,22,201,201,201, + 1,157,157,157,1,255,255,255,22,136,136,136,1,252,252,252,1,255,255,255, + 22,136,136,136,1,252,252,252,1,255,255,255,22,201,201,201,1,215,215,215, + 1,255,255,255,22,252,252,252,1,136,136,136,1,255,255,255,22,252,252,252, + 1,136,136,136,1,255,255,255,22,172,172,172,1,186,186,186,1,255,255,255, + 22,136,136,136,1,252,252,252,1,255,255,255,22,136,136,136,1,252,252,252, + 1,255,255,255,22,230,230,230,1,186,186,186,1,255,255,255,22,252,252,252, + 1,136,136,136,1,255,255,255,22,252,252,252,1,136,136,136,1,255,255,255, + 22,143,143,143,1,215,215,215,1,255,255,255,22,136,136,136,1,252,252,252, + 1,255,255,255,22,143,143,143,1,255,255,255,1,150,150,150,1,136,136,136, + 2,252,252,252,2,237,237,237,1,136,136,136,2,165,165,165,1,252,252,252, + 2,208,208,208,1,136,136,136,2,194,194,194,1,252,252,252,2,179,179,179, + 1,136,136,136,2,223,223,223,1,252,252,252,1,255,255,255,1,0,0) + ); + +const + objdata_tguiprocess: record size: integer; data: array[0..2866] of byte end = + (size: 2867; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,103,117, + 105,112,114,111,99,101,115,115,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,188,10,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,236,8,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,2,2,2,1,4,4,5,1,15,15,18, + 1,183,183,225,1,185,185,227,1,117,117,143,1,4,4,5,2,49,49,58, + 1,195,195,231,1,197,197,231,1,70,70,82,1,4,4,5,2,101,101,116, + 1,209,209,237,1,211,211,237,1,33,33,37,1,5,5,5,2,185,185,204, + 1,221,221,241,1,209,209,228,1,2,2,3,1,117,117,150,1,178,178,224, + 1,180,180,225,1,183,183,226,1,185,185,227,1,187,187,228,1,189,189,229, + 1,191,191,230,1,193,193,230,1,196,196,231,1,198,198,232,1,200,200,233, + 1,202,202,234,1,204,204,235,1,206,206,236,1,209,209,237,1,211,211,237, + 1,213,213,238,1,215,215,239,1,217,217,240,1,219,219,241,1,222,222,242, + 1,224,224,243,1,5,5,5,1,175,175,223,1,178,178,224,1,180,180,225, + 1,183,183,226,1,185,185,227,1,187,187,228,1,189,189,229,1,191,191,230, + 1,193,193,230,1,196,196,231,1,198,198,232,1,200,200,233,1,202,202,234, + 1,204,204,235,1,206,206,236,1,209,209,237,1,211,211,237,1,213,213,238, + 1,215,215,239,1,217,217,240,1,219,219,241,1,222,222,242,1,224,224,243, + 1,26,26,28,1,175,175,223,1,178,178,224,1,180,180,225,1,183,183,226, + 1,185,185,227,1,187,187,228,1,189,189,229,1,191,191,230,1,193,193,230, + 1,196,196,231,1,198,198,232,1,200,200,233,1,202,202,234,1,204,204,235, + 1,206,206,236,1,209,209,237,1,211,211,237,1,213,213,238,1,215,215,239, + 1,217,217,240,1,219,219,241,1,222,222,242,1,224,224,243,1,225,225,243, + 1,12,12,15,1,178,178,224,1,180,180,225,1,183,183,226,1,185,185,227, + 1,187,187,228,1,189,189,229,1,191,191,230,1,193,193,230,1,196,196,231, + 1,198,198,232,1,200,200,233,1,202,202,234,1,204,204,235,1,206,206,236, + 1,209,209,237,1,211,211,237,1,213,213,238,1,215,215,239,1,217,217,240, + 1,219,219,241,1,222,222,242,1,224,224,243,1,225,225,243,1,4,4,5, + 1,178,178,224,1,180,180,225,1,183,183,226,1,185,185,227,1,187,187,228, + 1,189,189,229,1,191,191,230,1,193,193,230,1,196,196,231,1,198,198,232, + 1,200,200,233,1,202,202,234,1,204,204,235,1,206,206,236,1,209,209,237, + 1,211,211,237,1,213,213,238,1,215,215,239,1,217,217,240,1,219,219,241, + 1,222,222,242,1,224,224,243,1,126,126,135,1,9,9,12,1,178,178,224, + 1,180,180,225,1,183,183,226,1,185,185,227,1,187,187,228,1,189,189,229, + 1,191,191,230,1,193,193,230,1,196,196,231,1,198,198,232,1,200,200,233, + 1,202,202,234,1,204,204,235,1,206,206,236,1,209,209,237,1,211,211,237, + 1,213,213,238,1,215,215,239,1,217,217,240,1,219,219,241,1,222,222,242, + 1,224,224,243,1,5,5,5,1,175,175,223,1,178,178,224,1,154,154,192, + 1,146,146,181,1,148,148,182,1,161,161,196,1,188,188,228,1,191,191,230, + 1,193,193,230,1,196,196,231,1,198,198,232,1,200,200,233,1,202,202,234, + 1,204,204,235,1,206,206,236,1,209,209,237,1,211,211,237,1,213,213,238, + 1,215,215,239,1,217,217,240,1,219,219,241,1,222,222,242,1,224,224,243, + 1,5,5,5,1,175,175,223,1,178,178,224,1,48,48,60,1,67,67,82, + 1,86,86,106,1,59,59,72,1,47,47,57,1,184,184,222,1,193,193,230, + 1,196,196,231,1,198,198,232,1,200,200,233,1,202,202,234,1,204,204,235, + 1,206,206,236,1,209,209,237,1,211,211,237,1,213,213,238,1,215,215,239, + 1,217,217,240,1,219,219,241,1,222,222,242,1,224,224,243,1,67,67,72, + 1,124,124,158,1,178,178,224,1,48,48,60,1,143,143,176,1,185,185,227, + 1,187,187,228,1,71,71,86,1,121,121,145,1,157,157,187,1,153,153,180, + 1,119,119,139,1,190,190,221,1,194,194,225,1,129,129,148,1,126,126,144, + 1,194,194,220,1,211,211,237,1,213,213,238,1,191,191,213,1,125,125,138, + 1,147,147,162,1,219,219,239,1,224,224,243,1,225,225,243,1,4,4,5, + 1,178,178,224,1,48,48,60,1,143,143,176,1,185,185,227,1,187,187,228, + 1,71,71,86,1,121,121,146,1,102,102,122,1,25,25,30,1,102,102,120, + 1,186,186,217,1,46,46,53,1,106,106,123,1,123,123,141,1,37,37,42, + 1,199,199,224,1,189,189,211,1,35,35,38,1,137,137,152,1,100,100,110, + 1,86,86,94,1,224,224,243,1,225,225,243,1,4,4,5,1,178,178,224, + 1,48,48,60,1,57,57,71,1,74,74,91,1,54,54,65,1,50,50,60, + 1,184,184,221,1,102,102,122,1,105,105,124,1,198,198,232,1,150,150,175, + 1,59,59,69,1,204,204,235,1,206,206,236,1,98,98,111,1,127,127,142, + 1,114,114,127,1,113,113,126,1,217,217,240,1,219,219,241,1,132,132,144, + 1,224,224,243,1,67,67,72,1,37,37,47,1,178,178,224,1,48,48,60, + 1,114,114,141,1,149,149,182,1,169,169,207,1,189,189,229,1,191,191,230, + 1,102,102,122,1,108,108,127,1,198,198,232,1,136,136,158,1,82,82,95, + 1,204,204,235,1,206,206,236,1,120,120,136,1,106,106,119,1,100,100,112, + 1,133,133,148,1,217,217,240,1,219,219,241,1,222,222,242,1,224,224,243, + 1,5,5,5,1,175,175,223,1,178,178,224,1,48,48,60,1,143,143,176, + 1,185,185,227,1,187,187,228,1,189,189,229,1,191,191,230,1,102,102,122, + 1,108,108,127,1,198,198,232,1,173,173,202,1,38,38,44,1,201,201,231, + 1,206,206,236,1,67,67,76,1,145,145,163,1,139,139,155,1,87,87,97, + 1,217,217,240,1,210,210,231,1,101,101,110,1,224,224,243,1,5,5,5, + 1,175,175,223,1,178,178,224,1,48,48,60,1,143,143,176,1,185,185,227, + 1,187,187,228,1,189,189,229,1,191,191,230,1,102,102,122,1,108,108,127, + 1,198,198,232,1,200,200,233,1,114,114,132,1,42,42,49,1,49,49,56, + 1,83,83,94,1,210,210,236,1,210,210,235,1,74,74,82,1,60,60,66, + 1,50,50,55,1,154,154,168,1,224,224,243,1,126,126,135,1,70,70,90, + 1,178,178,224,1,180,180,225,1,183,183,226,1,185,185,227,1,187,187,228, + 1,189,189,229,1,191,191,230,1,193,193,230,1,196,196,231,1,198,198,232, + 1,200,200,233,1,202,202,234,1,201,201,231,1,198,198,227,1,209,209,237, + 1,211,211,237,1,213,213,238,1,215,215,239,1,209,209,232,1,217,217,239, + 1,222,222,242,1,224,224,243,1,225,225,243,1,4,4,5,1,178,178,224, + 1,180,180,225,1,183,183,226,1,185,185,227,1,187,187,228,1,189,189,229, + 1,191,191,230,1,193,193,230,1,196,196,231,1,198,198,232,1,200,200,233, + 1,202,202,234,1,204,204,235,1,206,206,236,1,209,209,237,1,211,211,237, + 1,213,213,238,1,215,215,239,1,217,217,240,1,219,219,241,1,222,222,242, + 1,224,224,243,1,225,225,243,1,4,4,5,1,178,178,224,1,180,180,225, + 1,183,183,226,1,185,185,227,1,187,187,228,1,189,189,229,1,191,191,230, + 1,193,193,230,1,196,196,231,1,198,198,232,1,200,200,233,1,202,202,234, + 1,204,204,235,1,206,206,236,1,209,209,237,1,211,211,237,1,213,213,238, + 1,215,215,239,1,217,217,240,1,219,219,241,1,222,222,242,1,224,224,243, + 1,26,26,28,1,76,76,97,1,178,178,224,1,180,180,225,1,183,183,226, + 1,185,185,227,1,187,187,228,1,189,189,229,1,191,191,230,1,193,193,230, + 1,196,196,231,1,198,198,232,1,200,200,233,1,202,202,234,1,204,204,235, + 1,206,206,236,1,209,209,237,1,211,211,237,1,213,213,238,1,215,215,239, + 1,217,217,240,1,219,219,241,1,222,222,242,1,224,224,243,1,5,5,5, + 1,175,175,223,1,178,178,224,1,180,180,225,1,183,183,226,1,185,185,227, + 1,187,187,228,1,189,189,229,1,191,191,230,1,193,193,230,1,196,196,231, + 1,198,198,232,1,200,200,233,1,202,202,234,1,204,204,235,1,206,206,236, + 1,209,209,237,1,211,211,237,1,213,213,238,1,215,215,239,1,217,217,240, + 1,219,219,241,1,222,222,242,1,224,224,243,1,5,5,5,1,175,175,223, + 1,178,178,224,1,180,180,225,1,183,183,226,1,185,185,227,1,187,187,228, + 1,189,189,229,1,191,191,230,1,193,193,230,1,196,196,231,1,198,198,232, + 1,200,200,233,1,202,202,234,1,204,204,235,1,206,206,236,1,209,209,237, + 1,211,211,237,1,213,213,238,1,215,215,239,1,217,217,240,1,219,219,241, + 1,222,222,242,1,224,224,243,1,211,211,228,1,33,33,43,1,178,178,224, + 1,180,180,225,1,183,183,226,1,185,185,227,1,187,187,228,1,189,189,229, + 1,191,191,230,1,193,193,230,1,196,196,231,1,198,198,232,1,200,200,233, + 1,202,202,234,1,204,204,235,1,206,206,236,1,209,209,237,1,211,211,237, + 1,213,213,238,1,215,215,239,1,217,217,240,1,219,219,241,1,222,222,242, + 1,224,224,243,1,225,225,243,1,4,4,5,1,178,178,224,1,180,180,225, + 1,183,183,226,1,185,185,227,1,187,187,228,1,189,189,229,1,191,191,230, + 1,193,193,230,1,196,196,231,1,198,198,232,1,200,200,233,1,202,202,234, + 1,204,204,235,1,206,206,236,1,209,209,237,1,211,211,237,1,213,213,238, + 1,215,215,239,1,217,217,240,1,219,219,241,1,222,222,242,1,224,224,243, + 1,189,189,204,1,2,2,2,1,133,133,168,1,179,179,225,1,183,183,225, + 1,6,6,8,1,4,4,5,1,16,16,19,1,191,191,229,1,193,193,229, + 1,122,122,145,1,4,4,5,2,51,51,59,1,203,203,235,1,205,205,235, + 1,73,73,84,1,5,5,5,2,106,106,118,1,217,217,239,1,219,219,241, + 1,35,35,37,1,5,5,5,1,2,2,3,1,152,1,0,0,247,247,247, + 1,250,250,250,1,236,236,236,1,128,128,128,2,157,157,157,1,250,250,250, + 2,204,204,204,1,128,128,128,2,189,189,189,1,250,250,250,2,171,171,171, + 1,128,128,128,2,221,221,221,1,250,250,250,2,139,139,139,1,128,128,128, + 1,132,132,132,1,247,247,247,1,153,153,153,1,255,255,255,22,250,250,250, + 1,128,128,128,1,255,255,255,22,229,229,229,1,128,128,128,1,255,255,255, + 22,128,128,128,1,239,239,239,1,255,255,255,22,128,128,128,1,250,250,250, + 1,255,255,255,22,164,164,164,1,243,243,243,1,255,255,255,22,250,250,250, + 1,128,128,128,1,255,255,255,22,250,250,250,1,128,128,128,1,255,255,255, + 22,197,197,197,1,150,150,150,1,255,255,255,22,128,128,128,1,250,250,250, + 1,255,255,255,22,128,128,128,1,250,250,250,1,255,255,255,22,197,197,197, + 1,211,211,211,1,255,255,255,22,250,250,250,1,128,128,128,1,255,255,255, + 22,250,250,250,1,128,128,128,1,255,255,255,22,164,164,164,1,182,182,182, + 1,255,255,255,22,128,128,128,1,250,250,250,1,255,255,255,22,128,128,128, + 1,250,250,250,1,255,255,255,22,229,229,229,1,178,178,178,1,255,255,255, + 22,250,250,250,1,128,128,128,1,255,255,255,22,250,250,250,1,128,128,128, + 1,255,255,255,22,132,132,132,1,214,214,214,1,255,255,255,22,128,128,128, + 1,250,250,250,1,255,255,255,22,139,139,139,1,247,247,247,1,146,146,146, + 1,128,128,128,2,247,247,247,1,250,250,250,1,236,236,236,1,128,128,128, + 2,157,157,157,1,250,250,250,2,204,204,204,1,128,128,128,2,189,189,189, + 1,250,250,250,2,171,171,171,1,128,128,128,2,221,221,221,1,250,250,250, + 1,247,247,247,1,0,0) + ); + +const + objdata_tguithreadcomp: record size: integer; data: array[0..1313] of byte end = + (size: 1314; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,103,117, + 105,116,104,114,101,97,100,99,111,109,112,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,168,4,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,212,2,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,208,208,208,101,15,15,255,1, + 14,14,255,1,0,0,255,1,208,208,208,21,16,16,255,1,14,14,255,1, + 15,15,255,1,14,14,255,1,208,208,208,22,14,14,255,1,15,15,255,1, + 14,14,255,1,16,16,255,1,208,208,208,21,0,0,255,1,14,14,255,1, + 15,15,255,1,14,14,255,1,0,0,255,1,208,208,208,21,16,16,255,1, + 15,15,255,2,14,14,255,1,208,208,208,14,138,220,255,1,141,222,255,1, + 208,208,208,6,14,14,255,1,15,15,255,1,14,14,255,1,16,16,255,1, + 208,208,208,2,117,216,255,1,138,220,255,1,208,208,208,8,180,233,255,1, + 144,222,255,1,146,219,255,1,208,208,208,6,0,0,255,1,14,14,255,1, + 15,15,255,1,208,208,208,1,134,219,255,1,155,224,255,1,180,233,255,1, + 208,208,208,8,221,245,255,1,146,223,255,1,146,222,255,1,15,15,255,1, + 208,208,208,1,15,15,255,1,208,208,208,1,15,15,255,1,208,208,208,1, + 15,15,255,1,208,208,208,1,15,15,255,1,208,208,208,1,182,233,255,1, + 198,238,255,1,221,245,255,1,208,208,208,8,248,251,253,1,149,223,255,1, + 148,223,255,1,15,15,255,1,163,228,255,1,15,15,255,1,163,228,255,1, + 15,15,255,1,163,228,255,1,15,15,255,1,163,228,255,1,15,15,255,1, + 163,228,255,1,225,246,255,1,241,250,255,1,248,251,253,1,208,208,208,8, + 215,234,243,1,136,214,247,1,143,219,251,1,15,15,255,1,255,255,255,1, + 15,15,255,1,255,255,255,1,15,15,255,1,255,255,255,1,15,15,255,1, + 255,255,255,1,15,15,255,1,255,255,255,1,244,249,251,1,231,243,248,1, + 215,234,243,1,208,208,208,8,181,217,233,1,115,199,235,1,123,205,239,1, + 15,15,255,1,181,217,233,1,15,15,255,1,181,217,233,1,15,15,255,1, + 181,217,233,1,15,15,255,1,181,217,233,1,15,15,255,1,181,217,233,1, + 210,232,241,1,197,225,238,1,181,217,233,1,208,208,208,8,148,200,223,1, + 94,185,223,1,102,190,227,1,15,15,255,1,109,180,212,1,15,15,255,1, + 109,180,212,1,15,15,255,1,109,180,212,1,15,15,255,1,109,180,212,1, + 15,15,255,1,109,180,212,1,175,214,231,1,163,208,227,1,148,200,223,1, + 208,208,208,8,115,184,214,1,74,171,211,1,81,176,215,1,15,15,255,1, + 36,143,190,1,15,15,255,1,36,143,190,1,15,15,255,1,36,143,190,1, + 15,15,255,1,36,143,190,1,15,15,255,1,36,143,190,1,141,197,221,1, + 128,190,217,1,115,184,214,1,208,208,208,8,82,167,204,1,53,156,199,1, + 62,161,204,1,15,15,255,1,208,208,208,1,15,15,255,1,208,208,208,1, + 15,15,255,1,208,208,208,1,15,15,255,1,208,208,208,1,15,15,255,1, + 208,208,208,1,107,179,212,1,94,173,207,1,82,167,204,1,208,208,208,8, + 49,150,194,1,33,142,187,1,36,146,194,1,208,208,208,10,73,158,206,1, + 60,155,197,1,49,150,194,1,208,208,208,8,16,133,184,1,12,126,177,1, + 208,208,208,12,24,138,186,1,16,133,184,1,208,208,208,100,156,1,0,0, + 0,0,0,101,208,208,208,1,124,124,124,1,7,7,7,1,0,0,0,21, + 32,32,32,1,176,176,176,1,219,219,219,1,73,73,73,1,0,0,0,22, + 73,73,73,1,219,219,219,1,176,176,176,1,32,32,32,1,0,0,0,21, + 7,7,7,1,124,124,124,1,236,236,236,1,124,124,124,1,7,7,7,1, + 0,0,0,21,32,32,32,1,175,175,175,1,219,219,219,1,73,73,73,1, + 0,0,0,14,255,255,255,1,85,85,85,1,0,0,0,6,73,73,73,1, + 219,219,219,1,176,176,176,1,32,32,32,1,0,0,0,2,85,85,85,1, + 255,255,255,1,0,0,0,8,255,255,255,1,234,234,234,1,21,21,21,1, + 0,0,0,6,7,7,7,1,124,124,124,1,208,208,208,1,0,0,0,1, + 21,21,21,1,234,234,234,1,255,255,255,1,0,0,0,8,255,255,255,2, + 170,170,170,1,255,255,255,1,0,0,0,1,255,255,255,1,0,0,0,1, + 255,255,255,1,0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,1, + 0,0,0,1,170,170,170,1,255,255,255,2,0,0,0,8,255,255,255,16, + 0,0,0,8,255,255,255,16,0,0,0,8,255,255,255,16,0,0,0,8, + 255,255,255,16,0,0,0,8,255,255,255,16,0,0,0,8,255,255,255,2, + 170,170,170,1,255,255,255,1,0,0,0,1,255,255,255,1,0,0,0,1, + 255,255,255,1,0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,1, + 0,0,0,1,170,170,170,1,255,255,255,2,0,0,0,8,255,255,255,1, + 234,234,234,1,21,21,21,1,0,0,0,10,21,21,21,1,234,234,234,1, + 255,255,255,1,0,0,0,8,255,255,255,1,85,85,85,1,0,0,0,12, + 85,85,85,1,255,255,255,1,0,0,0,100,0,0) + ); + +const + objdata_tprocessmonitor: record size: integer; data: array[0..2246] of byte end = + (size: 2247; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,112,114, + 111,99,101,115,115,109,111,110,105,116,111,114,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,76,8,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,12,4,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,208,208,208,39,15,147,0, + 2,208,208,208,21,20,144,0,1,27,145,7,1,23,145,5,1,208,208,208, + 19,0,128,0,1,19,144,0,1,54,160,38,1,146,224,139,1,90,190,77, + 1,20,141,0,1,208,208,208,8,0,0,0,1,82,82,82,1,14,14,14, + 1,142,142,142,1,208,208,208,2,0,0,0,1,58,58,58,1,208,208,208, + 1,17,103,0,1,2,13,0,1,9,18,8,1,129,180,127,1,104,197,92, + 1,23,145,4,1,13,108,0,1,26,26,26,1,34,34,34,1,161,161,161, + 1,208,208,208,5,0,0,0,1,143,143,143,1,146,146,146,1,30,30,30, + 1,208,208,208,2,0,0,0,1,174,174,174,1,18,143,0,1,5,21,2, + 1,97,154,93,1,112,165,108,1,6,23,4,1,19,143,0,1,208,208,208, + 1,33,33,33,1,143,143,143,1,160,160,160,1,28,28,28,1,208,208,208, + 5,0,0,0,1,203,203,203,1,202,202,202,1,4,4,4,1,208,208,208, + 2,0,0,0,1,19,144,0,1,62,167,45,1,2,3,2,1,101,192,88, + 1,22,142,3,1,0,2,0,1,208,208,208,2,3,3,3,1,203,203,203, + 1,208,208,208,7,0,0,0,1,149,149,149,1,147,147,147,1,33,33,33, + 1,208,208,208,1,23,139,0,1,0,0,0,1,111,200,100,1,162,237,157, + 1,6,22,4,1,13,102,0,1,148,148,148,1,29,29,29,1,208,208,208, + 2,29,29,29,1,148,148,148,1,162,162,162,1,29,29,29,1,208,208,208, + 5,0,0,0,1,65,65,65,1,18,18,18,1,150,150,150,1,19,147,0, + 1,33,151,15,1,0,0,0,1,101,196,90,1,22,146,3,1,11,105,0, + 1,18,18,18,1,20,20,20,1,148,148,148,1,208,208,208,2,148,148,148, + 1,20,20,20,1,15,15,15,1,147,147,147,1,208,208,208,5,0,0,0, + 1,208,208,208,2,18,145,0,1,62,170,47,1,157,235,153,1,43,158,26, + 1,18,146,0,1,208,208,208,16,0,0,0,1,208,208,208,1,18,146,0, + 1,45,161,29,1,131,215,121,1,23,146,4,1,16,143,0,1,208,208,208, + 20,19,144,0,1,22,144,3,1,22,140,0,1,21,142,0,1,18,143,0, + 1,0,255,0,1,208,208,208,19,0,255,0,1,19,145,0,1,20,142,0, + 1,21,140,0,1,20,144,0,1,19,143,0,1,208,208,208,20,23,139,0, + 1,19,143,0,1,20,142,0,1,21,141,0,1,19,145,0,1,32,159,0, + 1,208,208,208,12,0,0,0,1,96,96,96,1,8,8,8,1,110,110,110, + 1,78,78,78,1,7,7,7,1,142,142,142,1,208,208,208,1,15,147,0, + 1,15,101,0,1,2,13,0,2,13,104,0,1,208,208,208,2,0,0,0, + 1,64,64,64,1,7,7,7,1,142,142,142,1,208,208,208,5,0,0,0, + 1,145,145,145,1,175,175,175,1,2,2,2,1,145,145,145,1,142,142,142, + 1,4,4,4,1,18,237,0,1,0,255,0,1,29,29,29,1,14,103,0, + 1,14,101,0,1,3,20,0,1,19,143,0,1,0,170,0,1,0,0,0, + 1,148,148,148,1,142,142,142,1,4,4,4,1,208,208,208,5,0,0,0, + 1,206,206,206,1,208,208,208,1,0,0,0,1,207,207,207,1,208,208,208, + 1,0,0,0,1,33,165,12,1,30,199,17,1,2,2,2,1,15,146,0, + 1,18,141,0,1,0,2,0,1,20,143,0,1,208,208,208,1,0,0,0, + 1,207,207,207,1,208,208,208,1,0,0,0,1,208,208,208,5,0,0,0, + 1,208,208,208,2,0,0,0,1,208,208,208,2,0,0,0,1,88,185,72, + 1,74,207,64,1,3,20,0,1,13,102,0,1,13,103,0,1,0,18,0, + 1,208,208,208,2,0,0,0,1,208,208,208,2,0,0,0,1,208,208,208, + 5,0,0,0,1,208,208,208,2,0,0,0,1,208,208,208,2,0,0,0, + 1,148,226,140,1,63,180,47,1,14,101,0,1,2,13,0,1,20,20,20, + 1,148,148,148,1,208,208,208,2,0,0,0,1,208,208,208,2,0,0,0, + 1,208,208,208,10,36,200,27,1,136,220,130,1,173,244,169,1,102,193,90, + 1,50,162,33,1,21,148,0,1,18,169,0,1,16,239,0,1,208,208,208, + 16,111,209,97,1,174,245,171,1,118,203,108,1,58,158,42,1,20,136,0, + 1,20,146,0,1,17,165,0,1,17,238,0,1,208,208,208,15,43,206,27, + 1,132,222,127,1,85,193,74,1,33,174,22,1,23,209,0,1,208,208,208, + 19,0,255,0,1,208,208,208,41,8,4,0,0,0,0,0,39,33,33,33, + 2,0,0,0,21,76,76,76,1,208,208,208,1,163,163,163,1,0,0,0, + 19,2,2,2,1,133,133,133,1,202,202,202,1,253,253,253,1,199,199,199, + 1,38,38,38,1,0,0,0,8,255,255,255,1,155,155,155,1,238,238,238, + 1,81,81,81,1,0,0,0,2,255,255,255,1,184,184,184,1,0,0,0, + 1,90,90,90,1,249,249,249,1,251,251,251,1,255,255,255,1,202,202,202, + 1,180,180,180,1,87,87,87,1,223,223,223,1,213,213,213,1,58,58,58, + 1,0,0,0,5,255,255,255,1,80,80,80,1,76,76,76,1,218,218,218, + 1,0,0,0,2,255,255,255,1,42,42,42,1,57,57,57,1,248,248,248, + 1,237,237,237,1,239,239,239,1,248,248,248,1,96,96,96,1,0,0,0, + 1,214,214,214,1,80,80,80,1,59,59,59,1,221,221,221,1,0,0,0, + 5,255,255,255,1,6,6,6,1,7,7,7,1,250,250,250,1,0,0,0, + 2,255,255,255,1,110,110,110,1,203,203,203,1,255,255,255,1,204,204,204, + 1,172,172,172,1,251,251,251,1,0,0,0,2,251,251,251,1,6,6,6, + 1,0,0,0,7,255,255,255,1,72,72,72,1,75,75,75,1,214,214,214, + 1,0,0,0,1,11,11,11,1,255,255,255,1,204,204,204,1,228,228,228, + 1,248,248,248,1,133,133,133,1,74,74,74,1,219,219,219,1,0,0,0, + 2,219,219,219,1,73,73,73,1,57,57,57,1,220,220,220,1,0,0,0, + 5,255,255,255,1,175,175,175,1,233,233,233,1,71,71,71,1,40,40,40, + 1,199,199,199,1,255,255,255,1,202,202,202,1,159,159,159,1,88,88,88, + 1,233,233,233,1,231,231,231,1,73,73,73,1,0,0,0,2,73,73,73, + 1,230,230,230,1,236,236,236,1,75,75,75,1,0,0,0,5,255,255,255, + 1,0,0,0,2,86,86,86,1,205,205,205,1,217,217,217,1,200,200,200, + 1,70,70,70,1,0,0,0,16,255,255,255,1,0,0,0,1,70,70,70, + 1,237,237,237,1,228,228,228,1,235,235,235,1,32,32,32,1,0,0,0, + 20,55,55,55,1,196,196,196,1,222,222,222,1,218,218,218,1,98,98,98, + 1,1,1,1,1,0,0,0,19,1,1,1,1,93,93,93,1,215,215,215, + 1,228,228,228,1,190,190,190,1,41,41,41,1,0,0,0,20,11,11,11, + 1,134,134,134,1,228,228,228,1,231,231,231,1,132,132,132,1,8,8,8, + 1,0,0,0,12,255,255,255,1,137,137,137,1,245,245,245,1,120,120,120, + 1,159,159,159,1,247,247,247,1,81,81,81,1,0,0,0,1,33,33,33, + 1,197,197,197,1,254,254,254,1,251,251,251,1,121,121,121,1,0,0,0, + 2,255,255,255,1,177,177,177,1,247,247,247,1,81,81,81,1,0,0,0, + 5,255,255,255,1,77,77,77,1,41,41,41,1,253,253,253,1,77,77,77, + 1,81,81,81,1,250,250,250,1,14,14,14,1,9,9,9,1,219,219,219, + 1,120,120,120,1,223,223,223,1,255,255,255,1,162,162,162,1,3,3,3, + 1,255,255,255,1,73,73,73,1,81,81,81,1,250,250,250,1,0,0,0, + 5,255,255,255,1,2,2,2,1,0,0,0,1,255,255,255,1,1,1,1, + 1,0,0,0,1,255,255,255,1,124,124,124,1,59,59,59,1,252,252,252, + 1,23,23,23,1,182,182,182,1,254,254,254,1,50,50,50,1,0,0,0, + 1,255,255,255,1,1,1,1,1,0,0,0,1,255,255,255,1,0,0,0, + 5,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,2,255,255,255, + 1,223,223,223,1,96,96,96,1,227,227,227,1,226,226,226,1,158,158,158, + 1,220,220,220,1,0,0,0,2,255,255,255,1,0,0,0,2,255,255,255, + 1,0,0,0,5,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0, + 2,255,255,255,2,174,174,174,1,204,204,204,1,236,236,236,1,231,231,231, + 1,73,73,73,1,0,0,0,2,255,255,255,1,0,0,0,2,255,255,255, + 1,0,0,0,10,56,56,56,1,240,240,240,1,255,255,255,1,239,239,239, + 1,183,183,183,1,136,136,136,1,86,86,86,1,16,16,16,1,0,0,0, + 16,173,173,173,1,255,255,255,2,239,239,239,1,191,191,191,1,140,140,140, + 1,88,88,88,1,15,15,15,1,0,0,0,15,84,84,84,1,193,193,193, + 1,144,144,144,1,94,94,94,1,22,22,22,1,0,0,0,19,3,3,3, + 1,0,0,0,41,0,0) + ); + +const + objdata_tfacelist: record size: integer; data: array[0..2156] of byte end = + (size: 2157; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,102,97, + 99,101,108,105,115,116,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,248,7,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,128,7,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,208,208,208,4,159,159,159,20,208,208,208,4,159, + 159,159,1,22,240,255,1,21,237,255,1,21,231,255,1,20,225,255,1,20, + 220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17, + 191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14, + 155,255,1,14,147,255,1,13,140,255,1,13,132,255,1,102,102,102,1,208, + 208,208,2,159,159,159,20,13,132,255,1,102,102,102,1,208,208,208,2,159, + 159,159,1,22,240,255,1,21,237,255,1,21,231,255,1,20,225,255,1,20, + 220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17, + 191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14, + 155,255,1,14,147,255,1,13,140,255,1,13,132,255,1,102,102,102,1,13, + 132,255,1,102,102,102,1,159,159,159,20,13,132,255,1,102,102,102,1,13, + 132,255,1,102,102,102,1,159,159,159,1,22,240,255,1,21,237,255,1,21, + 231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19,208,255,1,18, + 202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16,178,255,1,16, + 170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13,140,255,1,13, + 132,255,1,102,102,102,1,13,132,255,1,102,102,102,1,13,132,255,1,102, + 102,102,1,159,159,159,1,22,240,255,1,21,237,255,1,21,231,255,1,20, + 225,255,1,20,220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18, + 197,255,1,17,191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15, + 163,255,1,14,155,255,1,14,147,255,1,13,140,255,1,13,132,255,1,102, + 102,102,1,13,132,255,1,102,102,102,1,13,132,255,1,102,102,102,1,159, + 159,159,1,22,240,255,1,21,237,255,1,21,231,255,1,20,225,255,1,20, + 220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17, + 191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14, + 155,255,1,14,147,255,1,13,140,255,1,13,132,255,1,102,102,102,1,13, + 132,255,1,102,102,102,1,13,132,255,1,102,102,102,1,159,159,159,1,22, + 240,255,1,21,237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19, + 214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17, + 185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14, + 147,255,1,13,140,255,1,13,132,255,1,102,102,102,1,13,132,255,1,102, + 102,102,1,13,132,255,1,102,102,102,1,159,159,159,1,22,240,255,1,21, + 237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19, + 208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16, + 178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13, + 140,255,1,13,132,255,1,102,102,102,1,13,132,255,1,102,102,102,1,13, + 132,255,1,102,102,102,1,159,159,159,1,22,240,255,1,21,237,255,1,21, + 231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19,208,255,1,18, + 202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16,178,255,1,16, + 170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13,140,255,1,13, + 132,255,1,102,102,102,1,13,132,255,1,102,102,102,1,13,132,255,1,102, + 102,102,1,159,159,159,1,22,240,255,1,21,237,255,1,21,231,255,1,20, + 225,255,1,20,220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18, + 197,255,1,17,191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15, + 163,255,1,14,155,255,1,14,147,255,1,13,140,255,1,13,132,255,1,102, + 102,102,1,13,132,255,1,102,102,102,1,13,132,255,1,102,102,102,1,159, + 159,159,1,22,240,255,1,21,237,255,1,21,231,255,1,20,225,255,1,20, + 220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17, + 191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14, + 155,255,1,14,147,255,1,13,140,255,1,13,132,255,1,102,102,102,1,13, + 132,255,1,102,102,102,1,13,132,255,1,102,102,102,1,159,159,159,1,22, + 240,255,1,21,237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19, + 214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17, + 185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14, + 147,255,1,13,140,255,1,13,132,255,1,102,102,102,1,13,132,255,1,102, + 102,102,1,13,132,255,1,102,102,102,1,159,159,159,1,22,240,255,1,21, + 237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19, + 208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16, + 178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13, + 140,255,1,13,132,255,1,102,102,102,1,13,132,255,1,102,102,102,1,13, + 132,255,1,102,102,102,1,159,159,159,1,22,240,255,1,21,237,255,1,21, + 231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19,208,255,1,18, + 202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16,178,255,1,16, + 170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13,140,255,1,13, + 132,255,1,102,102,102,1,13,132,255,1,102,102,102,1,13,132,255,1,102, + 102,102,1,159,159,159,1,22,240,255,1,21,237,255,1,21,231,255,1,20, + 225,255,1,20,220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18, + 197,255,1,17,191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15, + 163,255,1,14,155,255,1,14,147,255,1,13,140,255,1,13,132,255,1,102, + 102,102,1,13,132,255,1,102,102,102,1,13,132,255,1,102,102,102,1,159, + 159,159,1,22,240,255,1,21,237,255,1,21,231,255,1,20,225,255,1,20, + 220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17, + 191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14, + 155,255,1,14,147,255,1,13,140,255,1,13,132,255,1,102,102,102,1,13, + 132,255,1,102,102,102,1,13,132,255,1,102,102,102,1,159,159,159,1,22, + 240,255,1,21,237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19, + 214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17, + 185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14, + 147,255,1,13,140,255,1,13,132,255,1,102,102,102,1,13,132,255,1,102, + 102,102,1,13,132,255,1,102,102,102,1,159,159,159,1,22,240,255,1,21, + 237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19, + 208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16, + 178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13, + 140,255,1,13,132,255,1,102,102,102,1,13,132,255,1,102,102,102,3,159, + 159,159,1,22,240,255,1,21,237,255,1,21,231,255,1,20,225,255,1,20, + 220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17, + 191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14, + 155,255,1,14,147,255,1,13,140,255,1,13,132,255,1,102,102,102,1,13, + 132,255,1,102,102,102,1,208,208,208,2,159,159,159,1,22,240,255,1,21, + 237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19, + 208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16, + 178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13, + 140,255,1,13,132,255,1,102,102,102,3,208,208,208,2,159,159,159,1,22, + 240,255,1,21,237,255,1,21,231,255,1,20,225,255,1,20,220,255,1,19, + 214,255,1,19,208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17, + 185,255,1,16,178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,14, + 147,255,1,13,140,255,1,13,132,255,1,102,102,102,1,208,208,208,4,102, + 102,102,20,208,208,208,4,64,0,0,0,0,0,0,4,255,255,255,20,0, + 0,0,4,255,255,255,20,0,0,0,2,255,255,255,22,0,0,0,2,255, + 255,255,255,255,255,255,173,0,0,0,2,255,255,255,22,0,0,0,2,255, + 255,255,20,0,0,0,4,255,255,255,20,0,0,0,4,0,0) + ); + +const + objdata_tpagesizeselector: record size: integer; data: array[0..1196] of byte end = + (size: 1197; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,112,97, + 103,101,115,105,122,101,115,101,108,101,99,116,111,114,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,48, + 4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,236, + 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,255, + 255,255,2,165,165,165,1,0,0,0,1,165,165,165,1,255,255,255,2,223, + 223,223,1,0,0,0,1,255,255,255,5,0,0,0,1,234,234,234,1,23, + 23,23,1,255,255,255,6,128,128,128,1,255,255,255,2,88,88,88,1,75, + 75,75,1,89,89,89,1,255,255,255,2,159,159,159,1,0,0,0,1,255, + 255,255,6,0,0,0,1,255,255,255,2,208,208,208,3,128,128,128,1,255, + 255,255,1,128,128,128,1,255,255,255,1,251,251,251,1,21,21,21,1,221, + 221,221,1,20,20,20,1,251,251,251,1,255,255,255,1,95,95,95,1,0, + 0,0,1,255,255,255,6,0,0,0,1,255,255,255,2,0,0,0,3,128, + 128,128,1,255,255,255,1,128,128,128,1,255,255,255,1,191,191,191,1,0, + 0,0,3,191,191,191,1,255,255,255,1,31,31,31,1,0,0,0,1,255, + 255,255,6,0,0,0,1,255,255,255,2,208,208,208,1,0,0,0,1,208, + 208,208,1,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1,114, + 114,114,1,141,141,141,1,255,255,255,1,141,141,141,1,115,115,115,1,255, + 255,255,1,0,0,0,3,255,255,255,3,252,252,252,1,231,231,231,1,0, + 0,0,1,247,247,247,1,255,255,255,1,208,208,208,3,128,128,128,1,255, + 255,255,1,128,128,128,1,255,255,255,1,37,37,37,1,217,217,217,1,255, + 255,255,1,217,217,217,1,38,38,38,1,255,255,255,2,0,0,0,1,255, + 255,255,4,223,223,223,1,0,0,0,1,223,223,223,1,0,0,0,1,128, + 128,128,5,255,255,255,25,0,0,0,25,255,255,255,22,0,0,0,2,255, + 255,255,2,165,165,165,1,0,0,0,1,165,165,165,1,255,255,255,2,223, + 223,223,1,0,0,0,1,255,255,255,9,208,208,208,1,0,0,0,1,208, + 208,208,1,128,128,128,1,0,0,0,2,255,255,255,2,88,88,88,1,75, + 75,75,1,89,89,89,1,255,255,255,2,159,159,159,1,0,0,0,1,255, + 255,255,9,0,0,0,3,128,128,128,1,0,0,0,2,255,255,255,1,251, + 251,251,1,21,21,21,1,221,221,221,1,20,20,20,1,251,251,251,1,255, + 255,255,1,95,95,95,1,0,0,0,1,255,255,255,9,208,208,208,3,128, + 128,128,1,0,0,0,2,255,255,255,1,191,191,191,1,0,0,0,3,191, + 191,191,1,255,255,255,1,31,31,31,1,0,0,0,1,255,255,255,8,128, + 128,128,5,0,0,0,2,255,255,255,1,114,114,114,1,141,141,141,1,255, + 255,255,1,141,141,141,1,115,115,115,1,255,255,255,1,0,0,0,3,255, + 255,255,8,212,212,212,1,252,252,252,1,208,208,208,1,255,255,255,1,0, + 0,0,2,255,255,255,1,37,37,37,1,217,217,217,1,255,255,255,1,217, + 217,217,1,38,38,38,1,255,255,255,2,0,0,0,1,255,255,255,9,254, + 254,254,1,209,209,209,1,254,254,254,1,128,128,128,1,0,0,0,2,255, + 255,255,18,128,128,128,4,0,0,0,2,255,255,255,2,165,165,165,1,0, + 0,0,1,165,165,165,1,255,255,255,1,212,212,212,1,0,0,0,3,255, + 255,255,9,211,211,211,1,255,255,255,1,208,208,208,1,0,0,0,2,255, + 255,255,2,88,88,88,1,75,75,75,1,89,89,89,1,255,255,255,1,127, + 127,127,1,133,133,133,1,255,255,255,11,252,252,252,1,255,255,255,2,0, + 0,0,2,255,255,255,1,251,251,251,1,21,21,21,1,221,221,221,1,20, + 20,20,1,251,251,251,1,42,42,42,1,38,38,38,1,14,14,14,1,156, + 156,156,1,255,255,255,8,208,208,208,3,128,128,128,1,0,0,0,2,255, + 255,255,1,191,191,191,1,0,0,0,3,191,191,191,1,255,255,255,2,245, + 245,245,1,22,22,22,1,255,255,255,8,0,0,0,3,128,128,128,1,0, + 0,0,2,255,255,255,1,114,114,114,1,141,141,141,1,255,255,255,1,141, + 141,141,1,115,115,115,1,31,31,31,1,231,231,231,1,246,246,246,1,36, + 36,36,1,255,255,255,8,208,208,208,1,0,0,0,1,208,208,208,1,128, + 128,128,1,0,0,0,2,255,255,255,1,37,37,37,1,217,217,217,1,255, + 255,255,1,217,217,217,1,38,38,38,1,174,174,174,1,18,18,18,1,24, + 24,24,1,181,181,181,1,255,255,255,7,128,128,128,5,0,0,0,25,12, + 0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tpageorientationselector: record size: integer; data: array[0..1451] of byte end = + (size: 1452; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,24,116,112,97, + 103,101,111,114,105,101,110,116,97,116,105,111,110,115,101,108,101,99,116,111, + 114,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116, + 99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112, + 116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109, + 111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46, + 105,109,97,103,101,10,40,5,0,0,0,0,0,0,6,0,0,0,24,0, + 0,0,24,0,0,0,228,4,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,128,128,128,14,99,99,99,1,128,128,128,10,255,255,255,1,0,0, + 0,1,2,2,2,1,109,109,109,1,255,255,255,9,0,0,0,2,234,234, + 234,1,23,23,23,1,255,255,255,6,128,128,128,1,255,255,255,1,0,0, + 0,1,237,237,237,1,11,11,11,1,255,255,255,1,180,180,180,1,23,23, + 23,1,24,24,24,1,184,184,184,1,255,255,255,1,0,0,0,1,71,71, + 71,1,0,0,0,4,255,255,255,2,208,208,208,3,128,128,128,1,255,255, + 255,1,128,128,128,1,255,255,255,1,0,0,0,1,233,233,233,1,13,13, + 13,1,255,255,255,1,36,36,36,1,181,181,181,1,179,179,179,1,36,36, + 36,1,255,255,255,1,0,0,0,1,213,213,213,1,255,255,255,1,0,0, + 0,1,255,255,255,1,0,0,0,1,255,255,255,2,0,0,0,3,128,128, + 128,1,255,255,255,1,128,128,128,1,255,255,255,1,0,0,0,2,99,99, + 99,1,255,255,255,1,3,3,3,1,249,249,249,1,248,248,248,1,4,4, + 4,1,255,255,255,1,0,0,0,1,254,254,254,1,255,255,255,1,0,0, + 0,1,255,255,255,1,0,0,0,1,255,255,255,2,208,208,208,1,0,0, + 0,1,208,208,208,1,128,128,128,1,255,255,255,1,128,128,128,1,255,255, + 255,1,0,0,0,1,255,255,255,3,35,35,35,1,181,181,181,2,36,36, + 36,1,255,255,255,1,0,0,0,1,255,255,255,2,0,0,0,1,218,218, + 218,1,0,0,0,1,247,247,247,1,255,255,255,1,208,208,208,3,128,128, + 128,1,255,255,255,1,128,128,128,1,255,255,255,1,0,0,0,1,255,255, + 255,3,179,179,179,1,22,22,22,1,24,24,24,1,182,182,182,1,255,255, + 255,1,0,0,0,1,255,255,255,2,49,49,49,1,0,0,0,1,223,223, + 223,1,0,0,0,1,128,128,128,5,255,255,255,25,0,0,0,25,255,255, + 255,13,197,197,197,1,255,255,255,8,0,0,0,2,255,255,255,1,0,0, + 0,1,2,2,2,1,109,109,109,1,255,255,255,9,0,0,0,1,255,255, + 255,4,208,208,208,1,0,0,0,1,208,208,208,1,128,128,128,1,0,0, + 0,2,255,255,255,1,0,0,0,1,237,237,237,1,11,11,11,1,255,255, + 255,1,180,180,180,1,23,23,23,1,24,24,24,1,184,184,184,1,255,255, + 255,1,0,0,0,1,71,71,71,1,0,0,0,3,255,255,255,3,0,0, + 0,3,128,128,128,1,0,0,0,2,255,255,255,1,0,0,0,1,233,233, + 233,1,13,13,13,1,255,255,255,1,36,36,36,1,181,181,181,1,179,179, + 179,1,36,36,36,1,255,255,255,1,0,0,0,1,213,213,213,1,255,255, + 255,1,0,0,0,1,255,255,255,4,208,208,208,3,128,128,128,1,0,0, + 0,2,255,255,255,1,0,0,0,2,99,99,99,1,255,255,255,1,3,3, + 3,1,249,249,249,1,248,248,248,1,4,4,4,1,255,255,255,1,0,0, + 0,1,254,254,254,1,255,255,255,1,0,0,0,1,255,255,255,3,128,128, + 128,5,0,0,0,2,255,255,255,1,0,0,0,1,255,255,255,3,35,35, + 35,1,181,181,181,2,36,36,36,1,255,255,255,1,0,0,0,1,255,255, + 255,2,0,0,0,1,241,241,241,1,255,255,255,3,212,212,212,1,252,252, + 252,1,208,208,208,1,255,255,255,1,0,0,0,2,255,255,255,1,0,0, + 0,1,255,255,255,3,179,179,179,1,22,22,22,1,24,24,24,1,182,182, + 182,1,255,255,255,1,0,0,0,1,255,255,255,2,56,56,56,1,7,7, + 7,1,255,255,255,3,254,254,254,1,209,209,209,1,254,254,254,1,128,128, + 128,1,0,0,0,2,255,255,255,18,128,128,128,4,0,0,0,2,255,255, + 255,1,0,0,0,1,255,255,255,13,0,0,0,1,255,255,255,3,211,211, + 211,1,255,255,255,1,208,208,208,1,0,0,0,2,255,255,255,1,0,0, + 0,1,255,255,255,2,108,108,108,1,14,14,14,1,7,7,7,1,88,88, + 88,1,255,255,255,1,5,5,5,1,196,196,196,1,255,255,255,1,173,173, + 173,1,18,18,18,1,92,92,92,1,0,0,0,1,255,255,255,3,252,252, + 252,1,255,255,255,2,0,0,0,2,255,255,255,1,0,0,0,1,255,255, + 255,4,220,220,220,1,1,1,1,1,255,255,255,1,0,0,0,1,5,5, + 5,1,255,255,255,1,35,35,35,1,183,183,183,1,177,177,177,1,0,0, + 0,1,255,255,255,2,208,208,208,3,128,128,128,1,0,0,0,2,255,255, + 255,1,0,0,0,1,255,255,255,2,177,177,177,1,76,76,76,1,31,31, + 31,1,0,0,0,1,255,255,255,1,0,0,0,2,255,255,255,1,4,4, + 4,1,249,249,249,1,248,248,248,1,0,0,0,1,255,255,255,2,0,0, + 0,3,128,128,128,1,0,0,0,2,255,255,255,1,0,0,0,1,255,255, + 255,2,13,13,13,1,175,175,175,1,158,158,158,1,0,0,0,1,255,255, + 255,1,0,0,0,2,255,255,255,1,39,39,39,1,178,178,178,1,182,182, + 182,1,0,0,0,1,255,255,255,2,208,208,208,1,0,0,0,1,208,208, + 208,1,128,128,128,1,0,0,0,2,255,255,255,1,0,0,0,3,94,94, + 94,1,8,8,8,1,112,112,112,1,0,0,0,1,255,255,255,1,0,0, + 0,2,255,255,255,1,180,180,180,1,19,19,19,1,94,94,94,1,0,0, + 0,1,255,255,255,1,128,128,128,5,0,0,0,25,12,0,0,0,255,255, + 255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tassistivehandler: record size: integer; data: array[0..1548] of byte end = + (size: 1549; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,97,115, + 115,105,115,116,105,118,101,104,97,110,100,108,101,114,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,144, + 5,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,24, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,104,109, + 11,179,1,133,12,224,1,130,12,221,1,97,12,170,1,85,0,149,1,129, + 13,219,1,135,14,228,1,121,13,199,1,0,0,0,15,104,8,175,1,127, + 12,216,1,132,12,225,2,114,11,192,1,112,10,187,1,133,12,226,2,129, + 12,218,1,90,8,158,1,0,0,0,13,85,6,146,1,112,9,189,1,116, + 9,198,3,111,9,187,1,110,9,188,1,117,9,199,3,105,9,181,1,0, + 0,0,12,58,0,104,1,92,7,159,1,99,7,171,2,100,7,171,2,100, + 7,172,4,100,7,173,1,101,7,172,1,80,6,138,1,0,0,0,10,39, + 0,78,1,76,4,131,1,83,4,144,3,83,4,145,2,84,4,145,3,84, + 4,146,3,80,4,140,1,61,6,105,1,0,0,0,8,44,0,78,1,61, + 1,107,1,66,1,117,2,67,1,117,1,67,1,118,4,67,1,119,2,68, + 1,119,2,68,1,120,2,65,1,116,1,54,3,94,1,0,0,0,6,28, + 0,52,1,49,0,86,1,50,0,91,1,50,0,89,2,47,0,84,1,43, + 0,77,1,46,0,84,1,54,0,89,1,43,0,78,4,43,0,79,1,51, + 0,88,1,50,0,89,1,51,0,90,2,41,0,73,1,0,0,0,6,61, + 2,107,1,70,2,124,4,63,1,110,1,51,0,77,1,0,0,0,4,56, + 3,101,1,68,2,121,1,70,2,124,3,61,2,109,1,43,0,43,1,0, + 0,0,6,51,0,51,1,73,4,126,1,81,4,141,4,77,3,133,1,68, + 5,118,1,59,4,102,1,67,3,114,1,74,5,128,1,80,4,140,1,81, + 4,141,3,72,4,126,1,0,0,85,1,0,0,0,8,62,0,106,1,87, + 5,149,1,91,5,157,11,88,5,151,1,66,0,113,1,0,0,0,10,73, + 5,130,1,101,7,173,1,101,7,174,10,83,7,144,1,0,0,0,12,99, + 9,172,1,112,9,191,9,102,9,175,1,0,0,85,1,0,0,0,12,88, + 9,132,1,116,10,198,1,122,10,208,7,119,10,203,1,90,9,151,1,0, + 0,0,14,108,12,185,1,130,12,222,1,132,12,225,6,110,10,190,1,0, + 0,0,16,116,11,196,1,136,13,228,1,143,14,241,3,138,14,233,1,119, + 13,200,1,0,0,0,18,77,0,128,1,112,12,193,1,123,13,207,1,117, + 14,196,1,89,13,140,1,0,0,0,106,64,3,0,0,255,255,255,1,242, + 242,242,1,211,211,211,1,0,0,0,2,61,61,61,1,242,242,242,2,151, + 151,151,1,0,0,0,2,122,122,122,1,242,242,242,2,89,89,89,1,0, + 0,0,2,183,183,183,1,242,242,242,2,28,28,28,1,0,0,0,1,2, + 2,2,1,252,252,252,1,43,43,43,1,0,0,0,22,246,246,246,1,0, + 0,0,23,201,201,201,1,0,0,0,24,234,234,234,1,0,0,0,7,47, + 47,47,1,148,148,148,1,149,149,149,1,21,21,21,1,12,12,12,1,142, + 142,142,1,151,151,151,1,59,59,59,1,0,0,0,8,246,246,246,1,0, + 0,0,6,64,64,64,1,239,239,239,1,255,255,255,2,121,121,121,1,105, + 105,105,1,255,255,255,2,240,240,240,1,34,34,34,1,0,0,0,6,75, + 75,75,1,226,226,226,1,0,0,0,5,42,42,42,1,233,233,233,1,255, + 255,255,3,219,219,219,1,206,206,206,1,255,255,255,3,175,175,175,1,0, + 0,0,6,246,246,246,1,0,0,0,5,22,22,22,1,213,213,213,1,255, + 255,255,10,89,89,89,1,0,0,0,5,246,246,246,1,0,0,0,4,13, + 13,13,1,189,189,189,1,255,255,255,11,236,236,236,1,46,46,46,1,0, + 0,0,4,139,139,139,1,50,50,50,1,0,0,0,2,46,46,46,1,193, + 193,193,1,255,255,255,13,234,234,234,1,90,90,90,1,4,4,4,1,0, + 0,0,3,246,246,246,1,0,0,0,1,64,64,64,1,184,184,184,1,182, + 182,182,1,184,184,184,2,142,142,142,1,66,66,66,1,61,61,61,1,57, + 57,57,1,65,65,65,4,106,106,106,1,171,171,171,1,178,178,178,1,190, + 190,190,2,130,130,130,1,0,0,0,3,246,246,246,1,0,0,0,2,143, + 143,143,1,255,255,255,4,174,174,174,1,20,20,20,1,0,0,0,4,96, + 96,96,1,243,243,243,1,255,255,255,3,154,154,154,1,6,6,6,1,0, + 0,0,2,138,138,138,1,165,165,165,1,0,0,0,2,5,5,5,1,188, + 188,188,1,255,255,255,4,220,220,220,1,112,112,112,1,65,65,65,1,76, + 76,76,1,170,170,170,1,254,254,254,1,255,255,255,3,180,180,180,1,3, + 3,3,1,0,0,0,3,246,246,246,1,0,0,0,4,29,29,29,1,232, + 232,232,1,255,255,255,11,236,236,236,1,27,27,27,1,0,0,0,4,246, + 246,246,1,0,0,0,5,94,94,94,1,255,255,255,11,108,108,108,1,0, + 0,0,5,76,76,76,1,113,113,113,1,0,0,0,5,175,175,175,1,255, + 255,255,9,197,197,197,1,3,3,3,1,0,0,0,6,246,246,246,1,0, + 0,0,5,29,29,29,1,233,233,233,1,255,255,255,7,249,249,249,1,54, + 54,54,1,0,0,0,7,246,246,246,1,0,0,0,6,87,87,87,1,252, + 252,252,1,255,255,255,6,125,125,125,1,0,0,0,7,200,200,200,1,102, + 102,102,1,0,0,0,7,90,90,90,1,229,229,229,1,255,255,255,3,241, + 241,241,1,120,120,120,1,0,0,0,8,246,246,246,1,0,0,0,9,10, + 10,10,1,66,66,66,1,79,79,79,1,74,74,74,1,20,20,20,1,0, + 0,0,9,246,246,246,1,0,0,0,23,15,15,15,1,174,174,174,1,0, + 0,0,23,246,246,246,1,0,0,0,22,17,17,17,1,255,255,255,1,28, + 28,28,1,0,0,0,1,2,2,2,1,244,244,244,2,210,210,210,1,0, + 0,0,2,64,64,64,1,244,244,244,2,148,148,148,1,0,0,0,2,126, + 126,126,1,244,244,244,2,86,86,86,1,0,0,0,2,188,188,188,1,244, + 244,244,1,252,252,252,1,0,0) + ); + +const + objdata_tassistivewidgetitem: record size: integer; data: array[0..1207] of byte end = + (size: 1208; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,20,116,97,115, + 115,105,115,116,105,118,101,119,105,100,103,101,116,105,116,101,109,23,98,105, + 116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111, + 114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110, + 115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111, + 108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103, + 101,10,56,4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0, + 0,0,184,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,156,156, + 156,25,170,170,170,22,156,156,156,2,0,0,0,22,156,156,156,2,0,0, + 0,22,156,156,156,2,0,0,0,22,156,156,156,2,0,0,0,22,156,156, + 156,2,0,0,0,22,156,156,156,2,0,0,0,22,156,156,156,2,0,0, + 0,22,156,156,156,2,0,0,0,7,141,14,238,1,143,13,241,1,142,14, + 240,1,143,14,241,1,128,0,255,1,143,14,241,1,142,14,241,1,142,13, + 242,2,0,0,0,6,156,156,156,2,0,0,0,5,107,7,181,1,106,8, + 182,4,107,8,183,1,106,8,182,1,107,8,183,2,107,8,184,2,106,8, + 184,1,96,0,191,1,0,0,0,4,156,156,156,2,0,0,0,2,64,0, + 128,1,71,4,124,1,70,1,124,1,71,2,124,3,71,2,125,4,72,2, + 126,4,72,2,128,1,72,3,128,1,71,3,126,1,70,0,128,1,64,0, + 128,1,0,0,0,1,156,156,156,2,0,0,0,2,70,0,119,1,68,1, + 120,4,67,2,120,1,67,0,122,1,128,0,128,1,0,0,0,3,72,0, + 120,1,69,0,119,1,68,1,119,1,68,1,120,2,68,1,119,1,69,0, + 120,1,73,0,109,1,0,0,0,1,156,156,156,2,0,0,0,3,89,0, + 153,1,88,4,153,1,89,5,154,4,89,5,155,2,89,5,154,7,98,0, + 157,1,0,0,0,3,156,156,156,2,0,0,0,5,110,8,189,1,110,8, + 188,10,111,8,188,1,0,0,0,5,156,156,156,2,0,0,0,6,131,13, + 222,2,131,12,222,7,130,10,224,1,0,0,0,6,156,156,156,2,0,0, + 0,8,150,15,255,1,152,16,255,2,150,15,255,1,150,14,255,1,149,12, + 255,1,0,0,0,8,156,156,156,2,0,0,0,22,156,156,156,2,0,0, + 0,22,156,156,156,2,0,0,0,22,156,156,156,2,0,0,0,22,156,156, + 156,2,0,0,0,22,156,156,156,2,0,0,0,22,156,156,156,25,72,2, + 0,0,253,253,253,24,245,245,245,1,3,3,3,22,234,234,234,1,245,245, + 245,1,0,0,0,22,234,234,234,1,245,245,245,1,0,0,0,22,234,234, + 234,1,245,245,245,1,0,0,0,22,234,234,234,1,245,245,245,1,0,0, + 0,22,234,234,234,1,245,245,245,1,0,0,0,22,234,234,234,1,245,245, + 245,1,0,0,0,22,234,234,234,1,245,245,245,1,0,0,0,22,234,234, + 234,1,245,245,245,1,0,0,0,7,74,74,74,1,161,161,161,1,187,187, + 187,1,141,141,141,1,2,2,2,1,141,141,141,1,187,187,187,1,171,171, + 171,1,61,61,61,1,0,0,0,6,234,234,234,1,245,245,245,1,0,0, + 0,5,76,76,76,1,203,203,203,1,255,255,255,4,218,218,218,1,255,255, + 255,3,252,252,252,1,132,132,132,1,8,8,8,1,0,0,0,4,234,234, + 234,1,245,245,245,1,0,0,0,2,16,16,16,1,72,72,72,1,185,185, + 185,1,238,238,238,12,202,202,202,1,93,93,93,1,40,40,40,1,4,4, + 4,1,0,0,0,1,234,234,234,1,245,245,245,1,0,0,0,2,77,77, + 77,1,214,214,214,1,238,238,238,2,224,224,224,1,159,159,159,1,65,65, + 65,1,2,2,2,1,0,0,0,3,32,32,32,1,126,126,126,1,207,207, + 207,1,221,221,221,1,234,234,234,1,205,205,205,1,96,96,96,1,7,7, + 7,1,0,0,0,1,234,234,234,1,245,245,245,1,0,0,0,3,20,20, + 20,1,173,173,173,1,255,255,255,4,236,236,236,1,193,193,193,1,187,187, + 187,1,224,224,224,1,255,255,255,4,164,164,164,1,13,13,13,1,0,0, + 0,3,234,234,234,1,245,245,245,1,0,0,0,5,97,97,97,1,243,243, + 243,1,255,255,255,8,246,246,246,1,99,99,99,1,0,0,0,5,234,234, + 234,1,245,245,245,1,0,0,0,6,39,39,39,1,183,183,183,1,254,254, + 254,1,255,255,255,5,194,194,194,1,49,49,49,1,0,0,0,6,234,234, + 234,1,245,245,245,1,0,0,0,8,34,34,34,1,82,82,82,1,114,114, + 114,1,119,119,119,1,90,90,90,1,41,41,41,1,0,0,0,8,234,234, + 234,1,245,245,245,1,0,0,0,22,234,234,234,1,245,245,245,1,0,0, + 0,22,234,234,234,1,245,245,245,1,0,0,0,22,234,234,234,1,245,245, + 245,1,0,0,0,22,234,234,234,1,245,245,245,1,0,0,0,22,234,234, + 234,1,245,245,245,1,0,0,0,22,234,234,234,1,255,255,255,1,248,248, + 248,22,255,255,255,1,0,0) + ); + +initialization + registerobjectdata(@objdata_taction,tbitmapcomp,'taction'); + registerobjectdata(@objdata_timagelist,tbitmapcomp,'timagelist'); + registerobjectdata(@objdata_tstatfile,tbitmapcomp,'tstatfile'); + registerobjectdata(@objdata_tstringcontainer,tbitmapcomp,'tstringcontainer'); + registerobjectdata(@objdata_tkeystringcontainer,tbitmapcomp,'tkeystringcontainer'); + registerobjectdata(@objdata_trttistat,tbitmapcomp,'trttistat'); + registerobjectdata(@objdata_tbitmapcomp,tbitmapcomp,'tbitmapcomp'); + registerobjectdata(@objdata_ttimer,tbitmapcomp,'ttimer'); + registerobjectdata(@objdata_tanimtimer,tbitmapcomp,'tanimtimer'); + registerobjectdata(@objdata_tanimitemcomp,tbitmapcomp,'tanimitemcomp'); + registerobjectdata(@objdata_tpipereadercomp,tbitmapcomp,'tpipereadercomp'); + registerobjectdata(@objdata_tthreadcomp,tbitmapcomp,'tthreadcomp'); + registerobjectdata(@objdata_tframecomp,tbitmapcomp,'tframecomp'); + registerobjectdata(@objdata_tfacecomp,tbitmapcomp,'tfacecomp'); + registerobjectdata(@objdata_tfontcomp,tbitmapcomp,'tfontcomp'); + registerobjectdata(@objdata_tactivator,tbitmapcomp,'tactivator'); + registerobjectdata(@objdata_tpostscriptprinter,tbitmapcomp,'tpostscriptprinter'); + registerobjectdata(@objdata_tgdiprinter,tbitmapcomp,'tgdiprinter'); + registerobjectdata(@objdata_twmfprinter,tbitmapcomp,'twmfprinter'); + registerobjectdata(@objdata_tmainmenu,tbitmapcomp,'tmainmenu'); + registerobjectdata(@objdata_tpopupmenu,tbitmapcomp,'tpopupmenu'); + registerobjectdata(@objdata_tnoguiaction,tbitmapcomp,'tnoguiaction'); + registerobjectdata(@objdata_tskincontroller,tbitmapcomp,'tskincontroller'); + registerobjectdata(@objdata_tskinextender,tbitmapcomp,'tskinextender'); + registerobjectdata(@objdata_tshortcutcontroller,tbitmapcomp,'tshortcutcontroller'); + registerobjectdata(@objdata_thelpcontroller,tbitmapcomp,'thelpcontroller'); + registerobjectdata(@objdata_tguiprocess,tbitmapcomp,'tguiprocess'); + registerobjectdata(@objdata_tguithreadcomp,tbitmapcomp,'tguithreadcomp'); + registerobjectdata(@objdata_tprocessmonitor,tbitmapcomp,'tprocessmonitor'); + registerobjectdata(@objdata_tfacelist,tbitmapcomp,'tfacelist'); + registerobjectdata(@objdata_tpagesizeselector,tbitmapcomp,'tpagesizeselector'); + registerobjectdata(@objdata_tpageorientationselector,tbitmapcomp,'tpageorientationselector'); + registerobjectdata(@objdata_tassistivehandler,tbitmapcomp,'tassistivehandler'); + registerobjectdata(@objdata_tassistivewidgetitem,tbitmapcomp,'tassistivewidgetitem'); +end. diff --git a/mseide-msegui/lib/common/regcomponents/regmath.pas b/mseide-msegui/lib/common/regcomponents/regmath.pas new file mode 100644 index 0000000..8286378 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regmath.pas @@ -0,0 +1,199 @@ +{ MSEide Copyright (c) 1999-2013 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regmath; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + msetypes,classes,mclasses,msefft,msedesignintf,msesignal,msefilter, + mseformatstr, + msepropertyeditors,msestrings,msedesigner,msesigfft,regmath_bmp, + msesiggui,msesigfftgui,msesignoise,msesigmidi,msedatalist, + mseiircoeffeditor,msefircoeffeditor,msegui,sysutils,mseglob; + +type + tinputconnpropertyeditor = class(tsubcomponentpropertyeditor) + protected + function getlinksource: tcomponent; override; + public + function getvalue: msestring; override; + end; + + tinputconnarraypropertyeditor = class(tpersistentarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + toutputconnpropertyeditor = class(tcomponentpropertyeditor) + protected + function filtercomponent(const acomponent: tcomponent): boolean; override; + end; + + tiircoeffpropertyeditor = class(tdatalistpropertyeditor) + public + procedure edit; override; + end; + + tfircoeffpropertyeditor = class(tdatalistpropertyeditor) + public + procedure edit; override; + end; + +procedure register; +begin + registercomponents('Math',[tsigcontroller,tsigout,tsigin, + tsigconnector,ttrigconnector, + tsigadd,tsigmult, + tsigdelay,tsigdelayn,tsigdelayvar,tsigfir,tsigiir, + tsigfilter,tsigfilterbank, + tsigwavetable,tsignoise,tsigfuncttable,tsigenvelope, + tsigsampler,tsigscope,tsigscopefft, + tsigfft,tfft,tsigsamplerfft, + tsigrealedit,tsigslider,tsigkeyboard, + tsigmidiconnector,tsigmidimulticonnector, + twavetableedit,tfuncttableedit,tffttableedit,tenvelopeedit + ]); + registercomponenttabhints(['Math'], + ['Experimental mathematical and signal processing components.']); + registerpropertyeditor(typeinfo(tdoubleconn),tdoublezcomp,'', + tsubcomponentpropertyeditor); +// registerpropertyeditor(typeinfo(tdoubleconn),tdoubleinpconnitem,'', +// tsubcomponentpropertyeditor); + registerpropertyeditor(typeinfo(tdoubleinputconn),nil,'', + tinputconnpropertyeditor); + registerpropertyeditor(typeinfo(tdoubleoutputconn),tdoubleinputconn,'', + toutputconnpropertyeditor); + registerpropertyeditor(typeinfo(tdoubleinpconnarrayprop),nil,'', + tinputconnarraypropertyeditor); + registerpropertyeditor(typeinfo(tcomplexdatalist),tsigiir,'coeff', + tiircoeffpropertyeditor); + registerpropertyeditor(typeinfo(trealdatalist),tsigfir,'coeff', + tfircoeffpropertyeditor); +end; + +{ tinputconnpropertyeditor } + +function tinputconnpropertyeditor.getvalue: msestring; +var + inst: tdoubleinputconn; +begin + inst:= tdoubleinputconn(getpointervalue); + if inst.source = nil then begin + result:= '<->'; + end + else begin + result:= msestring('<'+designer.getcomponentdispname(inst.source)+'>'); + end; +end; + +function tinputconnpropertyeditor.getlinksource: tcomponent; +begin + result:= tdoubleinputconn(getpointervalue).source; +end; + +{ tinputconnarraypropertyeditor } + +function tinputconnarraypropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tinputconnpropertyeditor; +end; + +{ toutputconnpropertyeditor } + +function toutputconnpropertyeditor.filtercomponent( + const acomponent: tcomponent): boolean; +var + cont1: tsigcontroller; +begin + cont1:= tdoubleinputconn(instance).controller; + result:= (cont1 <> nil) and (tdoubleoutputconn(acomponent).controller = cont1); +end; + +{ tiircoeffpropertyeditor } + +procedure tiircoeffpropertyeditor.edit; +var + inst: tsigiir; + int1,int2,int3: integer; +begin + with tiircoeffeditorfo.create(nil) do begin + inst:= tsigiir(component); + numed.gridvalues:= inst.origcoeff.asarrayim; + dened.gridvalues:= inst.origcoeff.asarrayre; + numdi.gridvalues:= inst.coeff.asarrayim; + dendi.gridvalues:= inst.coeff.asarrayre; + int3:= 0; + with grid.fixcols[-1] do begin + captions.count:= grid.rowcount; + for int1:= 0 to inst.sections.count - 1 do begin + if int1 <> 0 then begin + grid.rowlinewidth[int3-1]:= 3; + end; + for int2:= 0 to inst.sections[int1] - 1 do begin + captions[int3]:= 's'+inttostrmse(int1)+':'+inttostrmse(-int2); + inc(int3); + end; + end; + end; + if show(ml_application) = mr_ok then begin + inst.coeff.asarrayre:= dendi.gridvalues; + inst.coeff.asarrayim:= numdi.gridvalues; + inst.origcoeff.asarrayre:= dened.gridvalues; + inst.origcoeff.asarrayim:= numed.gridvalues; + self.modified(); + end; + free; + end; +end; + +{ tfircoeffpropertyeditor } + +procedure tfircoeffpropertyeditor.edit; +var + inst: tsigfir; + int1,int2,int3: integer; +begin + with tfircoeffeditorfo.create(nil) do begin + inst:= tsigfir(component); + coeffed.gridvalues:= inst.coeff.asarray; + int3:= 0; + with grid.fixcols[-1] do begin + captions.count:= grid.rowcount; + for int1:= 0 to inst.sections.count - 1 do begin + if int1 <> 0 then begin + grid.rowlinewidth[int3-1]:= 3; + end; + for int2:= 0 to inst.sections[int1] - 1 do begin + captions[int3]:= 's'+inttostrmse(int1)+':'+inttostrmse(-int2); + inc(int3); + end; + end; + end; + if show(ml_application) = mr_ok then begin + inst.coeff.asarray:= coeffed.gridvalues; + self.modified(); + end; + free; + end; +end; + +initialization + register; +end. diff --git a/mseide-msegui/lib/common/regcomponents/regmath_bmp.pas b/mseide-msegui/lib/common/regcomponents/regmath_bmp.pas new file mode 100644 index 0000000..b4eb168 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regmath_bmp.pas @@ -0,0 +1,4887 @@ +unit regmath_bmp; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msebitmap; + +const + objdata_tfft: record size: integer; data: array[0..1259] of byte end = + (size: 1260; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,4,116,102,102, + 116,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116, + 99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112, + 116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109, + 111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46, + 105,109,97,103,101,10,124,4,0,0,0,0,0,0,6,0,0,0,24,0, + 0,0,24,0,0,0,148,1,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,3,208,208,208,2,0,0,0,4,208,208,208,2,0,0, + 0,4,208,208,208,2,0,0,0,4,208,208,208,1,0,0,0,3,208,208, + 208,22,0,0,0,1,208,208,208,23,0,0,0,1,208,208,208,24,0,0, + 0,1,208,208,208,23,0,0,0,1,208,208,208,22,0,0,0,2,208,208, + 208,22,0,0,0,1,208,208,208,23,0,0,0,1,208,208,208,3,0,0, + 0,18,208,208,208,2,0,0,0,2,208,208,208,2,0,0,0,18,208,208, + 208,3,0,0,0,1,208,208,208,2,0,0,0,2,208,208,208,4,0,0, + 0,2,208,208,208,6,0,0,0,2,208,208,208,5,0,0,0,1,208,208, + 208,2,0,0,0,5,208,208,208,1,0,0,0,5,208,208,208,3,0,0, + 0,2,208,208,208,4,0,0,0,2,208,208,208,2,0,0,0,5,208,208, + 208,1,0,0,0,5,208,208,208,3,0,0,0,2,208,208,208,4,0,0, + 0,1,208,208,208,3,0,0,0,2,208,208,208,4,0,0,0,2,208,208, + 208,6,0,0,0,2,208,208,208,4,0,0,0,1,208,208,208,3,0,0, + 0,2,208,208,208,4,0,0,0,2,208,208,208,6,0,0,0,2,208,208, + 208,4,0,0,0,2,208,208,208,2,0,0,0,2,208,208,208,4,0,0, + 0,2,208,208,208,6,0,0,0,2,208,208,208,5,0,0,0,1,208,208, + 208,23,0,0,0,1,208,208,208,22,0,0,0,2,208,208,208,22,0,0, + 0,1,208,208,208,23,0,0,0,1,208,208,208,23,0,0,0,2,208,208, + 208,23,0,0,0,1,208,208,208,22,0,0,0,3,208,208,208,2,0,0, + 0,3,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,4,208,208, + 208,2,0,0,0,3,176,2,0,0,240,240,240,2,210,210,210,1,0,0, + 0,2,60,60,60,1,240,240,240,2,150,150,150,1,0,0,0,2,120,120, + 120,1,240,240,240,2,90,90,90,1,0,0,0,2,187,187,187,1,240,240, + 240,2,22,22,22,1,0,0,0,1,7,7,7,1,240,240,240,1,52,52, + 52,1,0,0,0,22,240,240,240,1,0,0,0,23,202,202,202,1,0,0, + 0,24,217,217,217,1,0,0,0,23,240,240,240,1,0,0,0,22,75,75, + 75,1,225,225,225,1,0,0,0,22,240,240,240,1,0,0,0,23,240,240, + 240,1,0,0,0,3,58,58,58,1,72,72,72,4,7,7,7,1,42,42, + 42,1,72,72,72,4,22,22,22,1,70,70,70,1,72,72,72,4,55,55, + 55,1,0,0,0,2,135,135,135,1,45,45,45,1,0,0,0,2,206,206, + 206,1,165,165,165,1,152,152,152,3,15,15,15,1,152,152,152,1,187,187, + 187,1,152,152,152,3,47,47,47,1,148,148,148,1,152,152,152,1,214,214, + 214,1,189,189,189,1,152,152,152,1,117,117,117,1,0,0,0,3,240,240, + 240,1,0,0,0,2,206,206,206,1,33,33,33,1,0,0,0,4,152,152, + 152,1,87,87,87,1,0,0,0,6,154,154,154,1,93,93,93,1,0,0, + 0,5,240,240,240,1,0,0,0,2,206,206,206,1,68,68,68,1,40,40, + 40,2,22,22,22,1,0,0,0,1,152,152,152,1,113,113,113,1,40,40, + 40,2,31,31,31,1,0,0,0,3,154,154,154,1,93,93,93,1,0,0, + 0,4,135,135,135,1,165,165,165,1,0,0,0,2,206,206,206,1,186,186, + 186,1,176,176,176,2,99,99,99,1,0,0,0,1,152,152,152,1,203,203, + 203,1,176,176,176,2,137,137,137,1,0,0,0,3,154,154,154,1,93,93, + 93,1,0,0,0,4,240,240,240,1,0,0,0,3,206,206,206,1,33,33, + 33,1,0,0,0,4,152,152,152,1,87,87,87,1,0,0,0,6,154,154, + 154,1,93,93,93,1,0,0,0,4,240,240,240,1,0,0,0,3,206,206, + 206,1,33,33,33,1,0,0,0,4,152,152,152,1,87,87,87,1,0,0, + 0,6,154,154,154,1,93,93,93,1,0,0,0,4,75,75,75,1,105,105, + 105,1,0,0,0,2,206,206,206,1,33,33,33,1,0,0,0,4,152,152, + 152,1,87,87,87,1,0,0,0,6,154,154,154,1,93,93,93,1,0,0, + 0,5,240,240,240,1,0,0,0,23,240,240,240,1,0,0,0,22,202,202, + 202,1,97,97,97,1,0,0,0,22,240,240,240,1,0,0,0,23,240,240, + 240,1,0,0,0,23,7,7,7,1,172,172,172,1,0,0,0,23,240,240, + 240,1,0,0,0,22,22,22,22,1,240,240,240,1,37,37,37,1,0,0, + 0,2,232,232,232,1,240,240,240,1,210,210,210,1,0,0,0,2,60,60, + 60,1,240,240,240,2,150,150,150,1,0,0,0,2,120,120,120,1,240,240, + 240,2,90,90,90,1,0,0,0,2,187,187,187,1,240,240,240,2,0,0) + ); + +const + objdata_tsigcontroller: record size: integer; data: array[0..2729] of byte end = + (size: 2730; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,115,105, + 103,99,111,110,116,114,111,108,108,101,114,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,48,10,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,96,8,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,4,3,3,1,7,7,5,1, + 22,22,17,1,230,224,178,1,231,225,180,1,143,140,113,1,7,7,6,2, + 61,60,49,1,234,230,193,1,235,231,195,1,85,83,71,1,7,7,6,2, + 114,112,98,1,238,235,207,1,239,236,210,1,37,37,33,1,7,7,7,2, + 204,201,185,1,243,240,222,1,230,228,212,1,4,4,4,1,151,147,113,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,28,28,26,1,228,222,171,1,229,223,173,1,229,224,175,1, + 255,230,16,18,243,240,222,1,243,241,224,1,244,242,227,1,18,18,14,1, + 229,223,173,1,229,224,175,1,255,230,16,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,255,230,16,1, + 243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1, + 229,224,175,1,255,230,16,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,255,230,16,1,243,240,222,1, + 243,241,224,1,133,132,124,1,14,14,11,1,229,223,173,1,229,224,175,1, + 255,230,16,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,225,220,188,1,181,178,154,1, + 204,200,173,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 240,238,215,1,241,238,217,1,255,230,16,1,243,240,222,1,243,241,224,1, + 7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,255,230,16,1, + 231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 190,187,157,1,53,52,44,1,4,4,3,1,12,12,10,1,0,0,0,1, + 54,53,47,1,207,205,180,1,239,236,210,1,240,237,212,1,240,238,215,1, + 241,238,217,1,255,230,16,1,243,240,222,1,243,241,224,1,7,7,7,1, + 228,222,171,1,229,223,173,1,229,224,175,1,255,230,16,1,231,225,180,1, + 231,226,183,1,232,227,185,1,233,228,188,1,195,191,159,1,19,19,16,1, + 101,100,84,1,202,197,168,1,236,232,200,1,192,189,164,1,49,48,42,1, + 33,32,28,1,232,230,204,1,240,237,212,1,240,238,215,1,241,238,217,1, + 255,230,16,1,243,240,222,1,243,241,224,1,75,75,70,1,160,156,120,1, + 229,223,173,1,229,224,175,1,255,230,16,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,54,53,44,1,65,64,54,1,234,230,194,1, + 236,231,197,1,236,232,200,1,237,233,202,1,198,195,170,1,32,31,28,1, + 183,180,161,1,240,237,212,1,240,238,215,1,241,238,217,1,255,230,16,1, + 243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1, + 229,224,175,1,255,230,16,1,231,225,180,1,231,226,183,1,232,227,185,1, + 227,222,183,1,6,6,5,1,161,158,132,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,255,230,16,1,243,240,222,1, + 243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1, + 255,230,16,1,231,225,180,1,231,226,183,1,232,227,185,1,181,177,146,1, + 0,0,0,1,197,194,163,1,235,231,195,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 240,238,215,1,241,238,217,1,255,230,16,1,243,240,222,1,243,241,224,1, + 75,75,70,1,49,48,37,1,229,223,173,1,229,224,175,1,255,230,16,1, + 231,225,180,1,231,226,183,1,232,227,185,1,189,185,153,1,0,0,0,1, + 190,187,157,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1, + 241,238,217,1,255,230,16,1,243,240,222,1,243,241,224,1,7,7,7,1, + 228,222,171,1,229,223,173,1,229,224,175,1,255,230,16,1,231,225,180,1, + 231,226,183,1,232,227,185,1,228,224,184,1,5,5,4,1,154,152,127,1, + 235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 144,142,125,1,198,195,174,1,240,237,212,1,240,238,215,1,241,238,217,1, + 255,230,16,1,243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1, + 229,223,173,1,229,224,175,1,255,230,16,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,58,57,48,1,61,60,51,1,232,228,193,1, + 236,231,197,1,236,232,200,1,237,233,202,1,173,170,149,1,0,0,0,1, + 159,157,140,1,240,237,212,1,240,238,215,1,241,238,217,1,255,230,16,1, + 243,240,222,1,243,241,224,1,133,132,124,1,95,93,71,1,229,223,173,1, + 229,224,175,1,255,230,16,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,205,201,167,1,19,19,16,1,85,83,70,1,190,186,158,1, + 222,218,188,1,151,148,128,1,34,33,29,1,51,51,45,1,234,231,206,1, + 240,237,212,1,240,238,215,1,241,238,217,1,255,230,16,1,243,240,222,1, + 243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1, + 255,230,16,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,183,179,151,1,46,45,38,1,0,0,0,2,2,2,2,1, + 83,82,72,1,218,216,190,1,239,236,210,1,240,237,212,1,240,238,215,1, + 241,238,217,1,255,230,16,1,243,240,222,1,243,241,224,1,244,242,227,1, + 7,7,5,1,229,223,173,1,229,224,175,1,255,230,16,1,231,225,180,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1, + 235,231,195,1,220,216,184,1,201,197,170,1,229,225,195,1,238,234,205,1, + 238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1, + 255,230,16,1,243,240,222,1,243,241,224,1,28,28,26,1,103,100,77,1, + 229,223,173,1,229,224,175,1,255,230,16,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,255,230,16,1, + 243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1, + 229,224,175,1,255,230,16,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,255,230,16,1,243,240,222,1, + 243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1, + 255,230,16,18,243,240,222,1,243,241,224,1,231,229,215,1,44,43,33,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,205,204,191,1,4,3,3,1,171,167,129,1,229,224,175,1, + 230,224,178,1,11,11,9,1,7,7,6,1,23,22,18,1,233,228,188,1, + 233,229,190,1,145,143,120,1,7,7,6,2,61,60,52,1,237,233,202,1, + 238,234,205,1,86,85,75,1,7,7,6,2,115,114,103,1,241,238,217,1, + 242,239,220,1,38,37,34,1,7,7,7,1,4,4,4,1,152,1,0,0, + 244,244,244,1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1, + 248,248,248,2,203,203,203,1,128,128,128,2,188,188,188,1,248,248,248,2, + 173,173,173,1,128,128,128,2,221,221,221,1,248,248,248,2,139,139,139,1, + 128,128,128,1,131,131,131,1,244,244,244,1,154,154,154,1,255,255,255,22, + 248,248,248,1,128,128,128,1,255,255,255,22,229,229,229,1,128,128,128,1, + 255,255,255,22,128,128,128,1,236,236,236,1,255,255,255,22,128,128,128,1, + 248,248,248,1,255,255,255,22,165,165,165,1,240,240,240,1,255,255,255,22, + 248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1, + 255,255,255,22,195,195,195,1,150,150,150,1,255,255,255,22,128,128,128,1, + 248,248,248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22, + 195,195,195,1,210,210,210,1,255,255,255,22,248,248,248,1,128,128,128,1, + 255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,165,165,165,1, + 180,180,180,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22, + 128,128,128,1,248,248,248,1,255,255,255,22,229,229,229,1,176,176,176,1, + 255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1, + 128,128,128,1,255,255,255,22,131,131,131,1,214,214,214,1,255,255,255,22, + 128,128,128,1,248,248,248,1,255,255,255,22,139,139,139,1,244,244,244,1, + 146,146,146,1,128,128,128,2,244,244,244,1,248,248,248,1,233,233,233,1, + 128,128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2, + 188,188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221,1, + 248,248,248,1,244,244,244,1,0,0) + ); + +const + objdata_tsigadd: record size: integer; data: array[0..2846] of byte end = + (size: 2847; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,7,116,115,105, + 103,97,100,100,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114, + 101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112, + 46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100, + 13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109, + 97,112,46,105,109,97,103,101,10,172,10,0,0,0,0,0,0,6,0,0, + 0,24,0,0,0,24,0,0,0,220,8,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,4,3,3,1,7,7,5,1,22,22,17,1,230,224,178, + 1,231,225,180,1,143,140,113,1,7,7,6,2,61,60,49,1,234,230,193, + 1,235,231,195,1,85,83,71,1,7,7,6,2,114,112,98,1,238,235,207, + 1,239,236,210,1,37,37,33,1,7,7,7,2,204,201,185,1,243,240,222, + 1,230,228,212,1,4,4,4,1,151,147,113,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,28,28,26, + 1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180, + 1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193, + 1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205, + 1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217, + 1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,18,18,14, + 1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183, + 1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195, + 1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207, + 1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220, + 1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173, + 1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185, + 1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197, + 1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210, + 1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,243,241,224,1,133,132,124,1,14,14,11,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7, + 1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180, + 1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193, + 1,235,231,195,1,50,49,42,1,194,191,165,1,237,233,202,1,238,234,205, + 1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217, + 1,242,239,220,1,243,240,222,1,243,241,224,1,75,75,70,1,160,156,120, + 1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183, + 1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195, + 1,6,6,5,1,184,181,156,1,237,233,202,1,238,234,205,1,238,235,207, + 1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220, + 1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173, + 1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185, + 1,233,228,188,1,223,219,182,1,219,216,181,1,220,217,183,1,6,6,5, + 1,173,170,147,1,222,218,189,1,224,220,193,1,238,235,207,1,239,236,210, + 1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,65,64,53,1,0,0,0,5,7,6,6,1,238,235,207,1,239,236,210, + 1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,243,241,224,1,75,75,70,1,49,48,37,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,217,214,177,1,212,208,175,1,213,209,177,1,6,6,5,1,168,165,142, + 1,215,211,183,1,217,213,187,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,6,6,5,1,184,181,156,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7, + 1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180, + 1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193, + 1,235,231,195,1,35,34,29,1,191,187,162,1,237,233,202,1,238,234,205, + 1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217, + 1,242,239,220,1,243,240,222,1,243,241,224,1,133,132,124,1,95,93,71, + 1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183, + 1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195, + 1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207, + 1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220, + 1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173, + 1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185, + 1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197, + 1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210, + 1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,28,28,26,1,103,100,77,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7, + 1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180, + 1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193, + 1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205, + 1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217, + 1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1,228,222,171, + 1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183, + 1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195, + 1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207, + 1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220, + 1,243,240,222,1,243,241,224,1,231,229,215,1,44,43,33,1,229,223,173, + 1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185, + 1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197, + 1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210, + 1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,205,204,191,1,4,3,3,1,171,167,129,1,229,224,175,1,230,224,178, + 1,11,11,9,1,7,7,6,1,23,22,18,1,233,228,188,1,233,229,190, + 1,145,143,120,1,7,7,6,2,61,60,52,1,237,233,202,1,238,234,205, + 1,86,85,75,1,7,7,6,2,115,114,103,1,241,238,217,1,242,239,220, + 1,38,37,34,1,7,7,7,1,4,4,4,1,152,1,0,0,244,244,244, + 1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1,248,248,248, + 2,203,203,203,1,128,128,128,2,188,188,188,1,248,248,248,2,173,173,173, + 1,128,128,128,2,221,221,221,1,248,248,248,2,139,139,139,1,128,128,128, + 1,131,131,131,1,244,244,244,1,154,154,154,1,255,255,255,22,248,248,248, + 1,128,128,128,1,255,255,255,22,229,229,229,1,128,128,128,1,255,255,255, + 22,128,128,128,1,236,236,236,1,255,255,255,22,128,128,128,1,248,248,248, + 1,255,255,255,22,165,165,165,1,240,240,240,1,255,255,255,22,248,248,248, + 1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255, + 22,195,195,195,1,150,150,150,1,255,255,255,22,128,128,128,1,248,248,248, + 1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,195,195,195, + 1,210,210,210,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255, + 22,248,248,248,1,128,128,128,1,255,255,255,22,165,165,165,1,180,180,180, + 1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,128,128,128, + 1,248,248,248,1,255,255,255,22,229,229,229,1,176,176,176,1,255,255,255, + 22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128, + 1,255,255,255,22,131,131,131,1,214,214,214,1,255,255,255,22,128,128,128, + 1,248,248,248,1,255,255,255,22,139,139,139,1,244,244,244,1,146,146,146, + 1,128,128,128,2,244,244,244,1,248,248,248,1,233,233,233,1,128,128,128, + 2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2,188,188,188, + 1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221,1,248,248,248, + 1,244,244,244,1,0,0) + ); + +const + objdata_tsigmult: record size: integer; data: array[0..2863] of byte end = + (size: 2864; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,8,116,115,105, + 103,109,117,108,116,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97, + 114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97, + 112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101, + 100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116, + 109,97,112,46,105,109,97,103,101,10,188,10,0,0,0,0,0,0,6,0, + 0,0,24,0,0,0,24,0,0,0,236,8,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,4,3,3,1,7,7,5,1,22,22,17,1,230,224, + 178,1,231,225,180,1,143,140,113,1,7,7,6,2,61,60,49,1,234,230, + 193,1,235,231,195,1,85,83,71,1,7,7,6,2,114,112,98,1,238,235, + 207,1,239,236,210,1,37,37,33,1,7,7,7,2,204,201,185,1,243,240, + 222,1,230,228,212,1,4,4,4,1,151,147,113,1,229,223,173,1,229,224, + 175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228, + 188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232, + 200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237, + 212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241, + 224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224, + 178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229, + 190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233, + 202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238, + 215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,28,28, + 26,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225, + 180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230, + 193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234, + 205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238, + 217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,18,18, + 14,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226, + 183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231, + 195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235, + 207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239, + 220,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223, + 173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227, + 185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231, + 197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236, + 210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240, + 222,1,243,241,224,1,133,132,124,1,14,14,11,1,229,223,173,1,229,224, + 175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228, + 188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232, + 200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237, + 212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241, + 224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224, + 178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229, + 190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233, + 202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238, + 215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7, + 7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225, + 180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230, + 193,1,235,231,195,1,162,159,135,1,149,146,126,1,237,233,202,1,238,234, + 205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238, + 217,1,242,239,220,1,243,240,222,1,243,241,224,1,75,75,70,1,160,156, + 120,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226, + 183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231, + 195,1,81,79,67,1,53,52,45,1,237,233,202,1,238,234,205,1,238,235, + 207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239, + 220,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223, + 173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227, + 185,1,233,228,188,1,205,201,167,1,112,110,92,1,208,205,173,1,100,98, + 83,1,74,73,63,1,217,213,185,1,129,127,111,1,177,175,154,1,239,236, + 210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240, + 222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224, + 175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228, + 188,1,147,145,120,1,2,2,2,1,3,3,2,1,23,23,19,1,18,17, + 15,1,5,5,4,1,0,0,0,1,106,105,93,1,239,236,210,1,240,237, + 212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241, + 224,1,75,75,70,1,49,48,37,1,229,223,173,1,229,224,175,1,230,224, + 178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229, + 190,1,222,218,183,1,154,151,128,1,3,3,2,1,0,0,0,1,131,129, + 112,1,219,216,189,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238, + 215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7, + 7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225, + 180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,226,222, + 186,1,51,50,42,1,52,51,43,1,76,75,64,1,29,28,25,1,214,210, + 184,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238, + 217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1,228,222, + 171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226, + 183,1,232,227,185,1,233,228,188,1,233,229,190,1,137,134,113,1,3,3, + 2,1,191,187,159,1,212,208,180,1,14,14,12,1,95,94,82,1,238,235, + 207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239, + 220,1,243,240,222,1,243,241,224,1,133,132,124,1,95,93,71,1,229,223, + 173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227, + 185,1,233,228,188,1,233,229,190,1,234,230,193,1,190,187,158,1,236,231, + 197,1,236,232,200,1,193,190,165,1,236,232,203,1,238,235,207,1,239,236, + 210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240, + 222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224, + 175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228, + 188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232, + 200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237, + 212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241, + 224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1,230,224, + 178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229, + 190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233, + 202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238, + 215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,28,28, + 26,1,103,100,77,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225, + 180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230, + 193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234, + 205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238, + 217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1,228,222, + 171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226, + 183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231, + 195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235, + 207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239, + 220,1,243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223, + 173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227, + 185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231, + 197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236, + 210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240, + 222,1,243,241,224,1,231,229,215,1,44,43,33,1,229,223,173,1,229,224, + 175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228, + 188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232, + 200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237, + 212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241, + 224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1,230,224, + 178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229, + 190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233, + 202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238, + 215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,205,204, + 191,1,4,3,3,1,171,167,129,1,229,224,175,1,230,224,178,1,11,11, + 9,1,7,7,6,1,23,22,18,1,233,228,188,1,233,229,190,1,145,143, + 120,1,7,7,6,2,61,60,52,1,237,233,202,1,238,234,205,1,86,85, + 75,1,7,7,6,2,115,114,103,1,241,238,217,1,242,239,220,1,38,37, + 34,1,7,7,7,1,4,4,4,1,152,1,0,0,244,244,244,1,248,248, + 248,1,233,233,233,1,128,128,128,2,158,158,158,1,248,248,248,2,203,203, + 203,1,128,128,128,2,188,188,188,1,248,248,248,2,173,173,173,1,128,128, + 128,2,221,221,221,1,248,248,248,2,139,139,139,1,128,128,128,1,131,131, + 131,1,244,244,244,1,154,154,154,1,255,255,255,22,248,248,248,1,128,128, + 128,1,255,255,255,22,229,229,229,1,128,128,128,1,255,255,255,22,128,128, + 128,1,236,236,236,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255, + 255,22,165,165,165,1,240,240,240,1,255,255,255,22,248,248,248,1,128,128, + 128,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,195,195, + 195,1,150,150,150,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255, + 255,22,128,128,128,1,248,248,248,1,255,255,255,22,195,195,195,1,210,210, + 210,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248, + 248,1,128,128,128,1,255,255,255,22,165,165,165,1,180,180,180,1,255,255, + 255,22,128,128,128,1,248,248,248,1,255,255,255,22,128,128,128,1,248,248, + 248,1,255,255,255,22,229,229,229,1,176,176,176,1,255,255,255,22,248,248, + 248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255, + 255,22,131,131,131,1,214,214,214,1,255,255,255,22,128,128,128,1,248,248, + 248,1,255,255,255,22,139,139,139,1,244,244,244,1,146,146,146,1,128,128, + 128,2,244,244,244,1,248,248,248,1,233,233,233,1,128,128,128,2,158,158, + 158,1,248,248,248,2,203,203,203,1,128,128,128,2,188,188,188,1,248,248, + 248,2,173,173,173,1,128,128,128,2,221,221,221,1,248,248,248,1,244,244, + 244,1,0,0) + ); + +const + objdata_tsigdelay: record size: integer; data: array[0..2856] of byte end = + (size: 2857; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,115,105, + 103,100,101,108,97,121,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,180,10,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,228,8,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,4,3,3,1,7,7,5,1,22,22,17,1,230, + 224,178,1,231,225,180,1,143,140,113,1,7,7,6,2,61,60,49,1,234, + 230,193,1,235,231,195,1,85,83,71,1,7,7,6,2,114,112,98,1,238, + 235,207,1,239,236,210,1,37,37,33,1,7,7,7,2,204,201,185,1,243, + 240,222,1,230,228,212,1,4,4,4,1,151,147,113,1,229,223,173,1,229, + 224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233, + 228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240, + 237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243, + 241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230, + 224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233, + 229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240, + 238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,28, + 28,26,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231, + 225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234, + 230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241, + 238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,18, + 18,14,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231, + 226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235, + 231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242, + 239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229, + 223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232, + 227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236, + 231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239, + 236,210,1,240,237,212,1,180,178,161,1,241,238,217,1,242,239,220,1,243, + 240,222,1,243,241,224,1,133,132,124,1,14,14,11,1,229,223,173,1,229, + 224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233, + 228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,116, + 114,102,1,87,86,78,1,241,238,217,1,242,239,220,1,243,240,222,1,243, + 241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230, + 224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233, + 229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,232,229,205,1,112, + 111,100,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7, + 7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231, + 225,180,1,231,226,183,1,232,227,185,1,192,188,155,1,167,164,136,1,168, + 165,139,1,169,166,140,1,169,166,141,1,198,195,168,1,237,233,202,1,176, + 173,152,1,111,110,97,1,214,211,188,1,240,237,212,1,112,111,100,1,241, + 238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,75,75,70,1,160, + 156,120,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231, + 226,183,1,232,227,185,1,145,142,117,1,94,92,77,1,95,93,78,1,95, + 93,79,1,23,23,19,1,115,113,97,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,112,111,100,1,241,238,217,1,242, + 239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229, + 223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232, + 227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,148,146,123,1,46, + 45,39,1,228,224,193,1,237,233,202,1,238,234,205,1,238,235,207,1,239, + 236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243, + 240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229, + 224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233, + 228,188,1,233,229,190,1,186,183,154,1,28,27,23,1,208,204,174,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240, + 237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243, + 241,224,1,75,75,70,1,49,48,37,1,229,223,173,1,229,224,175,1,230, + 224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,213, + 209,174,1,32,32,26,1,179,176,148,1,236,231,197,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240, + 238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7, + 7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231, + 225,180,1,231,226,183,1,232,227,185,1,229,224,185,1,58,57,47,1,139, + 137,115,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241, + 238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1,228, + 222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231, + 226,183,1,232,227,185,1,101,98,81,1,96,94,78,1,234,230,193,1,235, + 231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242, + 239,220,1,243,240,222,1,243,241,224,1,133,132,124,1,95,93,71,1,229, + 223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,223, + 218,178,1,0,0,0,1,32,31,26,1,36,35,30,3,95,94,81,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240, + 238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244, + 242,227,1,7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231, + 225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234, + 230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241, + 238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,7, + 7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231, + 226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235, + 231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242, + 239,220,1,243,240,222,1,243,241,224,1,28,28,26,1,103,100,77,1,229, + 223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232, + 227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236, + 231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239, + 236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243, + 240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229, + 224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233, + 228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240, + 237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243, + 241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230, + 224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233, + 229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240, + 238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,231, + 229,215,1,44,43,33,1,229,223,173,1,229,224,175,1,230,224,178,1,231, + 225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234, + 230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241, + 238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,7, + 7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231, + 226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235, + 231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242, + 239,220,1,243,240,222,1,243,241,224,1,205,204,191,1,4,3,3,1,171, + 167,129,1,229,224,175,1,230,224,178,1,11,11,9,1,7,7,6,1,23, + 22,18,1,233,228,188,1,233,229,190,1,145,143,120,1,7,7,6,2,61, + 60,52,1,237,233,202,1,238,234,205,1,86,85,75,1,7,7,6,2,115, + 114,103,1,241,238,217,1,242,239,220,1,38,37,34,1,7,7,7,1,4, + 4,4,1,152,1,0,0,244,244,244,1,248,248,248,1,233,233,233,1,128, + 128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2,188, + 188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221,1,248, + 248,248,2,139,139,139,1,128,128,128,1,131,131,131,1,244,244,244,1,154, + 154,154,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,229, + 229,229,1,128,128,128,1,255,255,255,22,128,128,128,1,236,236,236,1,255, + 255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,165,165,165,1,240, + 240,240,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248, + 248,248,1,128,128,128,1,255,255,255,22,195,195,195,1,150,150,150,1,255, + 255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,128,128,128,1,248, + 248,248,1,255,255,255,22,195,195,195,1,210,210,210,1,255,255,255,22,248, + 248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1,255, + 255,255,22,165,165,165,1,180,180,180,1,255,255,255,22,128,128,128,1,248, + 248,248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,229, + 229,229,1,176,176,176,1,255,255,255,22,248,248,248,1,128,128,128,1,255, + 255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,131,131,131,1,214, + 214,214,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,139, + 139,139,1,244,244,244,1,146,146,146,1,128,128,128,2,244,244,244,1,248, + 248,248,1,233,233,233,1,128,128,128,2,158,158,158,1,248,248,248,2,203, + 203,203,1,128,128,128,2,188,188,188,1,248,248,248,2,173,173,173,1,128, + 128,128,2,221,221,221,1,248,248,248,1,244,244,244,1,0,0) + ); + +const + objdata_tsigdelayn: record size: integer; data: array[0..2857] of byte end = + (size: 2858; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,115,105, + 103,100,101,108,97,121,110,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,180,10,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,228,8,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,4,3,3,1,7,7,5,1,22,22,17,1, + 230,224,178,1,231,225,180,1,143,140,113,1,7,7,6,2,61,60,49,1, + 234,230,193,1,235,231,195,1,85,83,71,1,7,7,6,2,114,112,98,1, + 238,235,207,1,239,236,210,1,37,37,33,1,7,7,7,2,204,201,185,1, + 243,240,222,1,230,228,212,1,4,4,4,1,151,147,113,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1, + 28,28,26,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1, + 241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1, + 18,18,14,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1, + 235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1, + 242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 226,223,198,1,176,174,155,1,240,238,215,1,221,218,199,1,203,201,185,1, + 243,240,222,1,243,241,224,1,133,132,124,1,14,14,11,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,208,205,183,1, + 30,30,27,1,207,205,185,1,195,192,175,1,153,151,139,1,243,240,222,1, + 243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,208,205,183,1,127,125,112,1, + 91,91,82,1,192,189,173,1,153,151,139,1,243,240,222,1,243,241,224,1, + 7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,192,188,155,1,167,164,136,1, + 168,165,139,1,169,166,140,1,169,166,141,1,198,195,168,1,237,233,202,1, + 176,173,152,1,111,110,97,1,186,183,163,1,136,135,121,1,183,181,164,1, + 88,87,79,1,153,151,139,1,243,240,222,1,243,241,224,1,75,75,70,1, + 160,156,120,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,232,227,185,1,145,142,117,1,94,92,77,1,95,93,78,1, + 95,93,79,1,23,23,19,1,115,113,97,1,237,233,202,1,238,234,205,1, + 238,235,207,1,208,205,183,1,136,135,121,1,240,238,215,1,106,105,95,1, + 153,151,139,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,148,146,123,1, + 46,45,39,1,228,224,193,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,186,183,154,1,28,27,23,1,208,204,174,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,75,75,70,1,49,48,37,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 213,209,174,1,32,32,26,1,179,176,148,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1, + 7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,229,224,185,1,58,57,47,1, + 139,137,115,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1, + 241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1, + 228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,232,227,185,1,101,98,81,1,96,94,78,1,234,230,193,1, + 235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1, + 242,239,220,1,243,240,222,1,243,241,224,1,133,132,124,1,95,93,71,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 223,218,178,1,0,0,0,1,32,31,26,1,36,35,30,3,95,94,81,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1, + 244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1, + 241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1, + 7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1, + 235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1, + 242,239,220,1,243,240,222,1,243,241,224,1,28,28,26,1,103,100,77,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1, + 231,229,215,1,44,43,33,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1, + 241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1, + 7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1, + 235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1, + 242,239,220,1,243,240,222,1,243,241,224,1,205,204,191,1,4,3,3,1, + 171,167,129,1,229,224,175,1,230,224,178,1,11,11,9,1,7,7,6,1, + 23,22,18,1,233,228,188,1,233,229,190,1,145,143,120,1,7,7,6,2, + 61,60,52,1,237,233,202,1,238,234,205,1,86,85,75,1,7,7,6,2, + 115,114,103,1,241,238,217,1,242,239,220,1,38,37,34,1,7,7,7,1, + 4,4,4,1,152,1,0,0,244,244,244,1,248,248,248,1,233,233,233,1, + 128,128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2, + 188,188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221,1, + 248,248,248,2,139,139,139,1,128,128,128,1,131,131,131,1,244,244,244,1, + 154,154,154,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22, + 229,229,229,1,128,128,128,1,255,255,255,22,128,128,128,1,236,236,236,1, + 255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,165,165,165,1, + 240,240,240,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22, + 248,248,248,1,128,128,128,1,255,255,255,22,195,195,195,1,150,150,150,1, + 255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,128,128,128,1, + 248,248,248,1,255,255,255,22,195,195,195,1,210,210,210,1,255,255,255,22, + 248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1, + 255,255,255,22,165,165,165,1,180,180,180,1,255,255,255,22,128,128,128,1, + 248,248,248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22, + 229,229,229,1,176,176,176,1,255,255,255,22,248,248,248,1,128,128,128,1, + 255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,131,131,131,1, + 214,214,214,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22, + 139,139,139,1,244,244,244,1,146,146,146,1,128,128,128,2,244,244,244,1, + 248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1,248,248,248,2, + 203,203,203,1,128,128,128,2,188,188,188,1,248,248,248,2,173,173,173,1, + 128,128,128,2,221,221,221,1,248,248,248,1,244,244,244,1,0,0) + ); + +const + objdata_tsigdelayvar: record size: integer; data: array[0..2859] of byte end = + (size: 2860; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,115,105, + 103,100,101,108,97,121,118,97,114,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,180,10,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,228,8,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,4,3,3,1,7,7,5,1,22,22, + 17,1,230,224,178,1,231,225,180,1,143,140,113,1,7,7,6,2,61,60, + 49,1,234,230,193,1,235,231,195,1,85,83,71,1,7,7,6,2,114,112, + 98,1,238,235,207,1,239,236,210,1,37,37,33,1,7,7,7,2,204,201, + 185,1,243,240,222,1,230,228,212,1,4,4,4,1,151,147,113,1,229,223, + 173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227, + 185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231, + 197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236, + 210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240, + 222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224, + 175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228, + 188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232, + 200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237, + 212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241, + 224,1,28,28,26,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224, + 178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229, + 190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233, + 202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238, + 215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242, + 227,1,18,18,14,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225, + 180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230, + 193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234, + 205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238, + 217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7, + 5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226, + 183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231, + 195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235, + 207,1,216,213,189,1,188,186,166,1,240,238,215,1,197,194,177,1,221,218, + 201,1,243,240,222,1,243,241,224,1,133,132,124,1,14,14,11,1,229,223, + 173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227, + 185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231, + 197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236, + 210,1,91,90,81,1,200,198,179,1,107,105,96,1,242,239,220,1,243,240, + 222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224, + 175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228, + 188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232, + 200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,219,217, + 194,1,29,29,26,1,227,224,204,1,242,239,220,1,243,240,222,1,243,241, + 224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224, + 178,1,231,225,180,1,231,226,183,1,232,227,185,1,192,188,155,1,167,164, + 136,1,168,165,139,1,169,166,140,1,169,166,141,1,198,195,168,1,237,233, + 202,1,176,173,152,1,111,110,97,1,214,211,188,1,136,134,120,1,122,121, + 110,1,143,141,128,1,242,239,220,1,243,240,222,1,243,241,224,1,75,75, + 70,1,160,156,120,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225, + 180,1,231,226,183,1,232,227,185,1,145,142,117,1,94,92,77,1,95,93, + 78,1,95,93,79,1,23,23,19,1,115,113,97,1,237,233,202,1,238,234, + 205,1,238,235,207,1,187,185,165,1,130,128,115,1,240,238,215,1,110,108, + 99,1,201,199,183,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7, + 5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226, + 183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,148,146, + 123,1,46,45,39,1,228,224,193,1,237,233,202,1,238,234,205,1,238,235, + 207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239, + 220,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223, + 173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227, + 185,1,233,228,188,1,233,229,190,1,186,183,154,1,28,27,23,1,208,204, + 174,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236, + 210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240, + 222,1,243,241,224,1,75,75,70,1,49,48,37,1,229,223,173,1,229,224, + 175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228, + 188,1,213,209,174,1,32,32,26,1,179,176,148,1,236,231,197,1,236,232, + 200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237, + 212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241, + 224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224, + 178,1,231,225,180,1,231,226,183,1,232,227,185,1,229,224,185,1,58,57, + 47,1,139,137,115,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233, + 202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238, + 215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7, + 7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225, + 180,1,231,226,183,1,232,227,185,1,101,98,81,1,96,94,78,1,234,230, + 193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234, + 205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238, + 217,1,242,239,220,1,243,240,222,1,243,241,224,1,133,132,124,1,95,93, + 71,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226, + 183,1,223,218,178,1,0,0,0,1,32,31,26,1,36,35,30,3,95,94, + 81,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237, + 212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241, + 224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1,230,224, + 178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229, + 190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233, + 202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238, + 215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242, + 227,1,7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225, + 180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230, + 193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234, + 205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238, + 217,1,242,239,220,1,243,240,222,1,243,241,224,1,28,28,26,1,103,100, + 77,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226, + 183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231, + 195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235, + 207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239, + 220,1,243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223, + 173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227, + 185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231, + 197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236, + 210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240, + 222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224, + 175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228, + 188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232, + 200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237, + 212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241, + 224,1,231,229,215,1,44,43,33,1,229,223,173,1,229,224,175,1,230,224, + 178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229, + 190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233, + 202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238, + 215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242, + 227,1,7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225, + 180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230, + 193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234, + 205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238, + 217,1,242,239,220,1,243,240,222,1,243,241,224,1,205,204,191,1,4,3, + 3,1,171,167,129,1,229,224,175,1,230,224,178,1,11,11,9,1,7,7, + 6,1,23,22,18,1,233,228,188,1,233,229,190,1,145,143,120,1,7,7, + 6,2,61,60,52,1,237,233,202,1,238,234,205,1,86,85,75,1,7,7, + 6,2,115,114,103,1,241,238,217,1,242,239,220,1,38,37,34,1,7,7, + 7,1,4,4,4,1,152,1,0,0,244,244,244,1,248,248,248,1,233,233, + 233,1,128,128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128, + 128,2,188,188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221, + 221,1,248,248,248,2,139,139,139,1,128,128,128,1,131,131,131,1,244,244, + 244,1,154,154,154,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255, + 255,22,229,229,229,1,128,128,128,1,255,255,255,22,128,128,128,1,236,236, + 236,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,165,165, + 165,1,240,240,240,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255, + 255,22,248,248,248,1,128,128,128,1,255,255,255,22,195,195,195,1,150,150, + 150,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,128,128, + 128,1,248,248,248,1,255,255,255,22,195,195,195,1,210,210,210,1,255,255, + 255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128, + 128,1,255,255,255,22,165,165,165,1,180,180,180,1,255,255,255,22,128,128, + 128,1,248,248,248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255, + 255,22,229,229,229,1,176,176,176,1,255,255,255,22,248,248,248,1,128,128, + 128,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,131,131, + 131,1,214,214,214,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255, + 255,22,139,139,139,1,244,244,244,1,146,146,146,1,128,128,128,2,244,244, + 244,1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1,248,248, + 248,2,203,203,203,1,128,128,128,2,188,188,188,1,248,248,248,2,173,173, + 173,1,128,128,128,2,221,221,221,1,248,248,248,1,244,244,244,1,0,0) + ); + +const + objdata_tsigfir: record size: integer; data: array[0..2862] of byte end = + (size: 2863; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,7,116,115,105, + 103,102,105,114,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114, + 101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112, + 46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100, + 13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109, + 97,112,46,105,109,97,103,101,10,188,10,0,0,0,0,0,0,6,0,0, + 0,24,0,0,0,24,0,0,0,236,8,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,4,3,3,1,7,7,5,1,22,22,17,1,230,224,178, + 1,231,225,180,1,143,140,113,1,7,7,6,2,61,60,49,1,234,230,193, + 1,235,231,195,1,85,83,71,1,7,7,6,2,114,112,98,1,238,235,207, + 1,239,236,210,1,37,37,33,1,7,7,7,2,204,201,185,1,243,240,222, + 1,230,228,212,1,4,4,4,1,151,147,113,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,28,28,26, + 1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180, + 1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193, + 1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205, + 1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217, + 1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,18,18,14, + 1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183, + 1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195, + 1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207, + 1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220, + 1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173, + 1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185, + 1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197, + 1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210, + 1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,243,241,224,1,133,132,124,1,14,14,11,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7, + 1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,188,184,147, + 1,166,162,131,1,166,163,133,1,167,164,135,1,167,164,136,1,217,214,179, + 1,212,208,176,1,195,191,163,1,236,232,200,1,193,190,165,1,171,168,147, + 1,171,169,149,1,175,173,154,1,206,204,182,1,239,237,214,1,241,238,217, + 1,242,239,220,1,243,240,222,1,243,241,224,1,75,75,70,1,160,156,120, + 1,229,223,173,1,229,224,175,1,230,224,178,1,79,77,61,1,67,66,53, + 1,94,92,75,1,94,92,76,1,94,92,77,1,199,196,164,1,153,150,127, + 1,90,88,75,1,236,232,200,1,81,79,69,1,80,79,69,1,111,110,97, + 1,106,105,93,1,45,45,40,1,88,88,79,1,241,238,217,1,242,239,220, + 1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173, + 1,229,224,175,1,230,224,178,1,79,77,61,1,167,163,132,1,232,227,185, + 1,233,228,188,1,233,229,190,1,234,230,193,1,153,150,127,1,90,88,75, + 1,236,232,200,1,81,79,69,1,172,169,148,1,238,235,207,1,239,236,210, + 1,233,230,206,1,15,15,13,1,225,222,203,1,242,239,220,1,243,240,222, + 1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175, + 1,230,224,178,1,79,77,61,1,140,137,111,1,196,191,156,1,196,192,159, + 1,207,204,169,1,234,230,193,1,153,150,127,1,90,88,75,1,236,232,200, + 1,81,79,69,1,161,159,139,1,223,220,194,1,218,216,192,1,164,162,145, + 1,37,36,33,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,75,75,70,1,49,48,37,1,229,223,173,1,229,224,175,1,230,224,178, + 1,79,77,61,1,52,51,41,1,72,70,57,1,72,71,58,1,118,116,96, + 1,234,230,193,1,153,150,127,1,90,88,75,1,236,232,200,1,81,79,69, + 1,37,37,32,1,49,49,43,1,7,6,6,1,91,90,81,1,214,212,191, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7, + 1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,79,77,61, + 1,167,163,132,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193, + 1,153,150,127,1,90,88,75,1,236,232,200,1,81,79,69,1,172,169,148, + 1,238,235,207,1,191,189,168,1,28,28,25,1,212,210,190,1,241,238,217, + 1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1,228,222,171, + 1,229,223,173,1,229,224,175,1,230,224,178,1,79,77,61,1,167,163,132, + 1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,153,150,127, + 1,90,88,75,1,236,232,200,1,81,79,69,1,172,169,148,1,238,235,207, + 1,239,236,210,1,134,132,118,1,56,56,51,1,240,237,216,1,242,239,220, + 1,243,240,222,1,243,241,224,1,133,132,124,1,95,93,71,1,229,223,173, + 1,229,224,175,1,230,224,178,1,79,77,61,1,167,163,132,1,232,227,185, + 1,233,228,188,1,233,229,190,1,234,230,193,1,153,150,127,1,90,88,75, + 1,236,232,200,1,81,79,69,1,172,169,148,1,238,235,207,1,239,236,210, + 1,238,235,210,1,52,51,46,1,139,137,125,1,242,239,220,1,243,240,222, + 1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,28,28,26, + 1,103,100,77,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180, + 1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193, + 1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205, + 1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217, + 1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1,228,222,171, + 1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183, + 1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195, + 1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207, + 1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220, + 1,243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173, + 1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185, + 1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197, + 1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210, + 1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,243,241,224,1,231,229,215,1,44,43,33,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,205,204,191, + 1,4,3,3,1,171,167,129,1,229,224,175,1,230,224,178,1,11,11,9, + 1,7,7,6,1,23,22,18,1,233,228,188,1,233,229,190,1,145,143,120, + 1,7,7,6,2,61,60,52,1,237,233,202,1,238,234,205,1,86,85,75, + 1,7,7,6,2,115,114,103,1,241,238,217,1,242,239,220,1,38,37,34, + 1,7,7,7,1,4,4,4,1,152,1,0,0,244,244,244,1,248,248,248, + 1,233,233,233,1,128,128,128,2,158,158,158,1,248,248,248,2,203,203,203, + 1,128,128,128,2,188,188,188,1,248,248,248,2,173,173,173,1,128,128,128, + 2,221,221,221,1,248,248,248,2,139,139,139,1,128,128,128,1,131,131,131, + 1,244,244,244,1,154,154,154,1,255,255,255,22,248,248,248,1,128,128,128, + 1,255,255,255,22,229,229,229,1,128,128,128,1,255,255,255,22,128,128,128, + 1,236,236,236,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255, + 22,165,165,165,1,240,240,240,1,255,255,255,22,248,248,248,1,128,128,128, + 1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,195,195,195, + 1,150,150,150,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255, + 22,128,128,128,1,248,248,248,1,255,255,255,22,195,195,195,1,210,210,210, + 1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248, + 1,128,128,128,1,255,255,255,22,165,165,165,1,180,180,180,1,255,255,255, + 22,128,128,128,1,248,248,248,1,255,255,255,22,128,128,128,1,248,248,248, + 1,255,255,255,22,229,229,229,1,176,176,176,1,255,255,255,22,248,248,248, + 1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255, + 22,131,131,131,1,214,214,214,1,255,255,255,22,128,128,128,1,248,248,248, + 1,255,255,255,22,139,139,139,1,244,244,244,1,146,146,146,1,128,128,128, + 2,244,244,244,1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158, + 1,248,248,248,2,203,203,203,1,128,128,128,2,188,188,188,1,248,248,248, + 2,173,173,173,1,128,128,128,2,221,221,221,1,248,248,248,1,244,244,244, + 1,0,0) + ); + +const + objdata_tsigiir: record size: integer; data: array[0..2862] of byte end = + (size: 2863; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,7,116,115,105, + 103,105,105,114,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114, + 101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112, + 46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100, + 13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109, + 97,112,46,105,109,97,103,101,10,188,10,0,0,0,0,0,0,6,0,0, + 0,24,0,0,0,24,0,0,0,236,8,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,4,3,3,1,7,7,5,1,22,22,17,1,230,224,178, + 1,231,225,180,1,143,140,113,1,7,7,6,2,61,60,49,1,234,230,193, + 1,235,231,195,1,85,83,71,1,7,7,6,2,114,112,98,1,238,235,207, + 1,239,236,210,1,37,37,33,1,7,7,7,2,204,201,185,1,243,240,222, + 1,230,228,212,1,4,4,4,1,151,147,113,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,28,28,26, + 1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180, + 1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193, + 1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205, + 1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217, + 1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,18,18,14, + 1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183, + 1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195, + 1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207, + 1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220, + 1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173, + 1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185, + 1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197, + 1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210, + 1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,243,241,224,1,133,132,124,1,14,14,11,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7, + 1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180, + 1,231,226,183,1,176,172,140,1,227,222,183,1,230,226,188,1,173,170,143, + 1,235,231,195,1,213,208,178,1,169,166,144,1,170,167,145,1,172,169,148, + 1,194,192,169,1,232,229,203,1,240,237,212,1,240,238,215,1,241,238,217, + 1,242,239,220,1,243,240,222,1,243,241,224,1,75,75,70,1,160,156,120, + 1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183, + 1,31,30,25,1,209,205,169,1,222,218,181,1,18,18,15,1,235,231,195, + 1,153,149,127,1,46,45,39,1,111,109,94,1,111,109,96,1,70,69,61, + 1,38,38,34,1,220,217,195,1,240,238,215,1,241,238,217,1,242,239,220, + 1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173, + 1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,31,30,25, + 1,209,205,169,1,222,218,181,1,18,18,15,1,235,231,195,1,153,149,127, + 1,98,96,83,1,237,233,202,1,238,234,205,1,238,235,207,1,79,78,69, + 1,152,150,134,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,31,30,25,1,209,205,169, + 1,222,218,181,1,18,18,15,1,235,231,195,1,153,149,127,1,93,91,78, + 1,222,218,189,1,222,218,191,1,193,191,168,1,36,35,31,1,201,199,178, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,75,75,70,1,49,48,37,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,31,30,25,1,209,205,169,1,222,218,181, + 1,18,18,15,1,235,231,195,1,153,149,127,1,21,21,18,1,51,50,44, + 1,21,20,18,1,45,44,39,1,187,184,164,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7, + 1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180, + 1,231,226,183,1,31,30,25,1,209,205,169,1,222,218,181,1,18,18,15, + 1,235,231,195,1,153,149,127,1,98,96,83,1,237,233,202,1,226,222,195, + 1,46,45,40,1,157,155,138,1,240,237,212,1,240,238,215,1,241,238,217, + 1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1,228,222,171, + 1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183, + 1,31,30,25,1,209,205,169,1,222,218,181,1,18,18,15,1,235,231,195, + 1,153,149,127,1,98,96,83,1,237,233,202,1,238,234,205,1,198,195,172, + 1,18,18,16,1,211,208,186,1,240,238,215,1,241,238,217,1,242,239,220, + 1,243,240,222,1,243,241,224,1,133,132,124,1,95,93,71,1,229,223,173, + 1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,31,30,25, + 1,209,205,169,1,222,218,181,1,18,18,15,1,235,231,195,1,153,149,127, + 1,98,96,83,1,237,233,202,1,238,234,205,1,238,235,207,1,122,120,107, + 1,66,65,58,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,28,28,26, + 1,103,100,77,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180, + 1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193, + 1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205, + 1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217, + 1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1,228,222,171, + 1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183, + 1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195, + 1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207, + 1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220, + 1,243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173, + 1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185, + 1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197, + 1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210, + 1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,243,241,224,1,231,229,215,1,44,43,33,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,205,204,191, + 1,4,3,3,1,171,167,129,1,229,224,175,1,230,224,178,1,11,11,9, + 1,7,7,6,1,23,22,18,1,233,228,188,1,233,229,190,1,145,143,120, + 1,7,7,6,2,61,60,52,1,237,233,202,1,238,234,205,1,86,85,75, + 1,7,7,6,2,115,114,103,1,241,238,217,1,242,239,220,1,38,37,34, + 1,7,7,7,1,4,4,4,1,152,1,0,0,244,244,244,1,248,248,248, + 1,233,233,233,1,128,128,128,2,158,158,158,1,248,248,248,2,203,203,203, + 1,128,128,128,2,188,188,188,1,248,248,248,2,173,173,173,1,128,128,128, + 2,221,221,221,1,248,248,248,2,139,139,139,1,128,128,128,1,131,131,131, + 1,244,244,244,1,154,154,154,1,255,255,255,22,248,248,248,1,128,128,128, + 1,255,255,255,22,229,229,229,1,128,128,128,1,255,255,255,22,128,128,128, + 1,236,236,236,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255, + 22,165,165,165,1,240,240,240,1,255,255,255,22,248,248,248,1,128,128,128, + 1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,195,195,195, + 1,150,150,150,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255, + 22,128,128,128,1,248,248,248,1,255,255,255,22,195,195,195,1,210,210,210, + 1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248, + 1,128,128,128,1,255,255,255,22,165,165,165,1,180,180,180,1,255,255,255, + 22,128,128,128,1,248,248,248,1,255,255,255,22,128,128,128,1,248,248,248, + 1,255,255,255,22,229,229,229,1,176,176,176,1,255,255,255,22,248,248,248, + 1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255, + 22,131,131,131,1,214,214,214,1,255,255,255,22,128,128,128,1,248,248,248, + 1,255,255,255,22,139,139,139,1,244,244,244,1,146,146,146,1,128,128,128, + 2,244,244,244,1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158, + 1,248,248,248,2,203,203,203,1,128,128,128,2,188,188,188,1,248,248,248, + 2,173,173,173,1,128,128,128,2,221,221,221,1,248,248,248,1,244,244,244, + 1,0,0) + ); + +const + objdata_tsigfft: record size: integer; data: array[0..2858] of byte end = + (size: 2859; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,7,116,115,105, + 103,102,102,116,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114, + 101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112, + 46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100, + 13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109, + 97,112,46,105,109,97,103,101,10,184,10,0,0,0,0,0,0,6,0,0, + 0,24,0,0,0,24,0,0,0,232,8,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,4,3,3,1,7,7,5,1,22,22,17,1,230,224,178, + 1,231,225,180,1,143,140,113,1,7,7,6,2,61,60,49,1,234,230,193, + 1,235,231,195,1,85,83,71,1,7,7,6,2,114,112,98,1,238,235,207, + 1,239,236,210,1,37,37,33,1,7,7,7,2,204,201,185,1,243,240,222, + 1,230,228,212,1,4,4,4,1,151,147,113,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,28,28,26, + 1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180, + 1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193, + 1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205, + 1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217, + 1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,18,18,14, + 1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183, + 1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195, + 1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207, + 1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220, + 1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173, + 1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185, + 1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197, + 1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210, + 1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,243,241,224,1,133,132,124,1,14,14,11,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7, + 1,228,222,171,1,229,223,173,1,229,224,175,1,178,173,138,1,166,161,129, + 1,166,162,131,1,166,163,133,1,167,164,135,1,227,223,185,1,195,192,161, + 1,169,166,140,1,169,166,141,1,169,166,144,1,170,167,145,1,217,214,187, + 1,173,170,150,1,172,169,151,1,172,170,152,1,172,171,154,1,173,171,156, + 1,190,187,173,1,243,240,222,1,243,241,224,1,75,75,70,1,160,156,120, + 1,229,223,173,1,229,224,175,1,44,43,34,1,82,79,64,1,93,91,74, + 1,94,92,75,1,94,92,76,1,219,216,179,1,95,93,78,1,63,62,52, + 1,95,93,80,1,95,94,81,1,96,94,82,1,194,191,167,1,100,99,87, + 1,97,95,85,1,39,38,34,1,62,62,56,1,97,96,88,1,131,129,119, + 1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173, + 1,229,224,175,1,44,43,34,1,201,196,157,1,231,226,183,1,232,227,185, + 1,233,228,188,1,233,229,190,1,95,93,78,1,155,152,128,1,236,231,197, + 1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210, + 1,95,94,84,1,152,151,137,1,241,238,217,1,242,239,220,1,243,240,222, + 1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175, + 1,44,43,34,1,169,165,132,1,195,191,154,1,196,191,156,1,213,208,172, + 1,233,229,190,1,95,93,78,1,131,129,109,1,199,195,166,1,199,196,169, + 1,208,205,177,1,238,234,205,1,238,235,207,1,239,236,210,1,95,94,84, + 1,152,151,137,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,75,75,70,1,49,48,37,1,229,223,173,1,229,224,175,1,44,43,34, + 1,63,61,49,1,72,70,57,2,143,139,115,1,233,229,190,1,95,93,78, + 1,48,47,40,1,73,72,61,1,73,72,62,1,110,108,93,1,238,234,205, + 1,238,235,207,1,239,236,210,1,95,94,84,1,152,151,137,1,241,238,217, + 1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1,228,222,171, + 1,229,223,173,1,229,224,175,1,44,43,34,1,201,196,157,1,231,226,183, + 1,232,227,185,1,233,228,188,1,233,229,190,1,95,93,78,1,155,152,128, + 1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207, + 1,239,236,210,1,95,94,84,1,152,151,137,1,241,238,217,1,242,239,220, + 1,243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173, + 1,229,224,175,1,44,43,34,1,201,196,157,1,231,226,183,1,232,227,185, + 1,233,228,188,1,233,229,190,1,95,93,78,1,155,152,128,1,236,231,197, + 1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210, + 1,95,94,84,1,152,151,137,1,241,238,217,1,242,239,220,1,243,240,222, + 1,243,241,224,1,133,132,124,1,95,93,71,1,229,223,173,1,229,224,175, + 1,44,43,34,1,201,196,157,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,95,93,78,1,155,152,128,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,95,94,84, + 1,152,151,137,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227, + 1,7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180, + 1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193, + 1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205, + 1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217, + 1,242,239,220,1,243,240,222,1,243,241,224,1,28,28,26,1,103,100,77, + 1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183, + 1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195, + 1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207, + 1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220, + 1,243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173, + 1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185, + 1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197, + 1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210, + 1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,231,229,215,1,44,43,33,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227, + 1,7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180, + 1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193, + 1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205, + 1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217, + 1,242,239,220,1,243,240,222,1,243,241,224,1,205,204,191,1,4,3,3, + 1,171,167,129,1,229,224,175,1,230,224,178,1,11,11,9,1,7,7,6, + 1,23,22,18,1,233,228,188,1,233,229,190,1,145,143,120,1,7,7,6, + 2,61,60,52,1,237,233,202,1,238,234,205,1,86,85,75,1,7,7,6, + 2,115,114,103,1,241,238,217,1,242,239,220,1,38,37,34,1,7,7,7, + 1,4,4,4,1,152,1,0,0,244,244,244,1,248,248,248,1,233,233,233, + 1,128,128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128, + 2,188,188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221, + 1,248,248,248,2,139,139,139,1,128,128,128,1,131,131,131,1,244,244,244, + 1,154,154,154,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255, + 22,229,229,229,1,128,128,128,1,255,255,255,22,128,128,128,1,236,236,236, + 1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,165,165,165, + 1,240,240,240,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255, + 22,248,248,248,1,128,128,128,1,255,255,255,22,195,195,195,1,150,150,150, + 1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,128,128,128, + 1,248,248,248,1,255,255,255,22,195,195,195,1,210,210,210,1,255,255,255, + 22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128, + 1,255,255,255,22,165,165,165,1,180,180,180,1,255,255,255,22,128,128,128, + 1,248,248,248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255, + 22,229,229,229,1,176,176,176,1,255,255,255,22,248,248,248,1,128,128,128, + 1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,131,131,131, + 1,214,214,214,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255, + 22,139,139,139,1,244,244,244,1,146,146,146,1,128,128,128,2,244,244,244, + 1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1,248,248,248, + 2,203,203,203,1,128,128,128,2,188,188,188,1,248,248,248,2,173,173,173, + 1,128,128,128,2,221,221,221,1,248,248,248,1,244,244,244,1,0,0) + ); + +const + objdata_tsigin: record size: integer; data: array[0..2845] of byte end = + (size: 2846; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,6,116,115,105, + 103,105,110,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114,101, + 110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112,46, + 111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,13, + 98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109,97, + 112,46,105,109,97,103,101,10,172,10,0,0,0,0,0,0,6,0,0,0, + 24,0,0,0,24,0,0,0,220,8,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,4,3,3,1,7,7,5,1,22,22,17,1,230,224,178,1, + 231,225,180,1,143,140,113,1,7,7,6,2,61,60,49,1,234,230,193,1, + 235,231,195,1,85,83,71,1,7,7,6,2,114,112,98,1,238,235,207,1, + 239,236,210,1,37,37,33,1,7,7,7,2,204,201,185,1,243,240,222,1, + 230,228,212,1,4,4,4,1,151,147,113,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1, + 7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1, + 241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,28,28,26,1, + 228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1, + 235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1, + 242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,18,18,14,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,133,132,124,1,14,14,11,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1, + 7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1, + 241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1, + 228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1, + 231,227,192,1,176,172,147,1,236,232,200,1,211,207,180,1,194,191,167,1, + 238,235,207,1,239,236,210,1,240,237,212,1,200,199,180,1,220,217,198,1, + 242,239,220,1,243,240,222,1,243,241,224,1,75,75,70,1,160,156,120,1, + 229,223,173,1,229,224,175,1,230,224,178,1,127,124,99,1,177,173,140,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,220,217,183,1, + 21,21,18,1,236,232,200,1,142,140,121,1,10,10,9,1,205,203,179,1, + 239,236,210,1,240,237,212,1,99,98,89,1,164,162,148,1,242,239,220,1, + 243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1, + 229,224,175,1,230,224,178,1,177,172,138,1,22,21,17,1,177,174,141,1, + 233,228,188,1,233,229,190,1,234,230,193,1,220,217,183,1,21,21,18,1, + 236,232,200,1,142,140,121,1,41,40,35,1,58,57,50,1,238,235,209,1, + 240,237,212,1,99,98,89,1,164,162,148,1,242,239,220,1,243,240,222,1, + 243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,177,173,140,1,22,21,17,1,178,174,144,1, + 233,229,190,1,234,230,193,1,220,217,183,1,21,21,18,1,236,232,200,1, + 142,140,121,1,118,116,101,1,77,76,67,1,135,133,119,1,240,237,212,1, + 99,98,89,1,164,162,148,1,242,239,220,1,243,240,222,1,243,241,224,1, + 75,75,70,1,49,48,37,1,229,223,173,1,0,0,0,5,51,50,41,1, + 233,229,190,1,234,230,193,1,220,217,183,1,21,21,18,1,236,232,200,1, + 142,140,121,1,118,116,101,1,218,216,190,1,28,28,25,1,205,203,181,1, + 99,98,89,1,164,162,148,1,242,239,220,1,243,240,222,1,243,241,224,1, + 7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,177,173,140,1,22,21,17,1,178,174,144,1,233,229,190,1, + 234,230,193,1,220,217,183,1,21,21,18,1,236,232,200,1,142,140,121,1, + 118,116,101,1,238,235,207,1,160,158,141,1,55,54,48,1,96,95,86,1, + 164,162,148,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1, + 228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,177,172,138,1, + 22,21,17,1,177,174,141,1,233,228,188,1,233,229,190,1,234,230,193,1, + 220,217,183,1,21,21,18,1,236,232,200,1,142,140,121,1,118,116,101,1, + 238,235,207,1,239,236,210,1,82,81,72,1,15,15,13,1,164,162,148,1, + 242,239,220,1,243,240,222,1,243,241,224,1,133,132,124,1,95,93,71,1, + 229,223,173,1,229,224,175,1,230,224,178,1,127,124,99,1,177,173,140,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,220,217,183,1, + 21,21,18,1,236,232,200,1,142,140,121,1,118,116,101,1,238,235,207,1, + 239,236,210,1,222,219,196,1,22,21,19,1,164,162,148,1,242,239,220,1, + 243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1, + 28,28,26,1,103,100,77,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1, + 241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1, + 228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1, + 235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1, + 242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,231,229,215,1,44,43,33,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1, + 205,204,191,1,4,3,3,1,171,167,129,1,229,224,175,1,230,224,178,1, + 11,11,9,1,7,7,6,1,23,22,18,1,233,228,188,1,233,229,190,1, + 145,143,120,1,7,7,6,2,61,60,52,1,237,233,202,1,238,234,205,1, + 86,85,75,1,7,7,6,2,115,114,103,1,241,238,217,1,242,239,220,1, + 38,37,34,1,7,7,7,1,4,4,4,1,152,1,0,0,244,244,244,1, + 248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1,248,248,248,2, + 203,203,203,1,128,128,128,2,188,188,188,1,248,248,248,2,173,173,173,1, + 128,128,128,2,221,221,221,1,248,248,248,2,139,139,139,1,128,128,128,1, + 131,131,131,1,244,244,244,1,154,154,154,1,255,255,255,22,248,248,248,1, + 128,128,128,1,255,255,255,22,229,229,229,1,128,128,128,1,255,255,255,22, + 128,128,128,1,236,236,236,1,255,255,255,22,128,128,128,1,248,248,248,1, + 255,255,255,22,165,165,165,1,240,240,240,1,255,255,255,22,248,248,248,1, + 128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22, + 195,195,195,1,150,150,150,1,255,255,255,22,128,128,128,1,248,248,248,1, + 255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,195,195,195,1, + 210,210,210,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22, + 248,248,248,1,128,128,128,1,255,255,255,22,165,165,165,1,180,180,180,1, + 255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,128,128,128,1, + 248,248,248,1,255,255,255,22,229,229,229,1,176,176,176,1,255,255,255,22, + 248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1, + 255,255,255,22,131,131,131,1,214,214,214,1,255,255,255,22,128,128,128,1, + 248,248,248,1,255,255,255,22,139,139,139,1,244,244,244,1,146,146,146,1, + 128,128,128,2,244,244,244,1,248,248,248,1,233,233,233,1,128,128,128,2, + 158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2,188,188,188,1, + 248,248,248,2,173,173,173,1,128,128,128,2,221,221,221,1,248,248,248,1, + 244,244,244,1,0,0) + ); + +const + objdata_tsigout: record size: integer; data: array[0..2846] of byte end = + (size: 2847; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,7,116,115,105, + 103,111,117,116,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114, + 101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112, + 46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100, + 13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109, + 97,112,46,105,109,97,103,101,10,172,10,0,0,0,0,0,0,6,0,0, + 0,24,0,0,0,24,0,0,0,220,8,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,4,3,3,1,7,7,5,1,22,22,17,1,230,224,178, + 1,231,225,180,1,143,140,113,1,7,7,6,2,61,60,49,1,234,230,193, + 1,235,231,195,1,85,83,71,1,7,7,6,2,114,112,98,1,238,235,207, + 1,239,236,210,1,37,37,33,1,7,7,7,2,204,201,185,1,243,240,222, + 1,230,228,212,1,4,4,4,1,151,147,113,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,28,28,26, + 1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180, + 1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193, + 1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205, + 1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217, + 1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,18,18,14, + 1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183, + 1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195, + 1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207, + 1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220, + 1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173, + 1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185, + 1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197, + 1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210, + 1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,243,241,224,1,133,132,124,1,14,14,11,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7, + 1,228,222,171,1,229,223,173,1,229,224,175,1,220,214,170,1,159,154,124, + 1,192,188,152,1,232,227,185,1,233,228,188,1,193,189,157,1,228,225,188, + 1,235,231,195,1,232,227,194,1,193,189,163,1,201,197,171,1,171,168,147, + 1,171,169,149,1,172,169,151,1,191,189,169,1,240,238,215,1,241,238,217, + 1,242,239,220,1,243,240,222,1,243,241,224,1,75,75,70,1,160,156,120, + 1,229,223,173,1,221,216,169,1,49,47,38,1,84,82,66,1,73,72,58, + 1,121,118,96,1,233,228,188,1,88,86,72,1,212,208,175,1,235,231,195, + 1,222,217,185,1,81,79,68,1,159,156,135,1,96,95,83,1,27,27,24, + 1,97,95,85,1,136,135,121,1,240,238,215,1,132,131,119,1,185,183,168, + 1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173, + 1,139,136,106,1,122,119,94,1,231,225,180,1,231,226,183,1,69,68,55, + 1,206,201,166,1,88,86,72,1,212,208,175,1,235,231,195,1,222,217,185, + 1,81,79,68,1,237,233,202,1,238,234,205,1,66,65,58,1,239,236,210, + 1,240,237,212,1,240,238,215,1,184,182,166,1,23,22,21,1,186,184,170, + 1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,86,84,66, + 1,180,176,140,1,231,225,180,1,231,226,183,1,136,133,108,1,160,156,129, + 1,88,86,72,1,212,208,175,1,235,231,195,1,222,217,185,1,81,79,68, + 1,237,233,202,1,238,234,205,1,66,65,58,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,185,183,168,1,23,23,21,1,186,184,171, + 1,75,75,70,1,49,48,37,1,229,223,173,1,70,69,54,1,219,213,170, + 1,231,225,180,1,231,226,183,1,150,147,120,1,138,135,111,1,88,86,72, + 1,212,208,175,1,235,231,195,1,222,217,185,1,81,79,68,1,237,233,202, + 1,238,234,205,1,66,65,58,1,239,236,210,1,0,0,0,5,53,53,49, + 1,7,7,7,1,228,222,171,1,229,223,173,1,101,99,78,1,172,168,133, + 1,231,225,180,1,231,226,183,1,99,97,79,1,173,169,139,1,103,101,84, + 1,200,197,165,1,235,231,195,1,197,193,165,1,95,94,81,1,237,233,202, + 1,238,234,205,1,66,65,58,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,185,183,168,1,23,23,21,1,186,184,171,1,7,7,7, + 1,228,222,171,1,229,223,173,1,171,167,130,1,84,82,65,1,225,219,175, + 1,206,201,163,1,51,50,41,1,220,215,178,1,136,134,111,1,146,143,120, + 1,235,231,195,1,141,138,117,1,129,126,109,1,237,233,202,1,238,234,205, + 1,66,65,58,1,239,236,210,1,240,237,212,1,240,238,215,1,184,182,166, + 1,23,22,21,1,186,184,170,1,243,241,224,1,133,132,124,1,95,93,71, + 1,229,223,173,1,229,224,175,1,115,112,89,1,39,38,30,1,33,32,26, + 1,166,162,132,1,233,228,188,1,224,220,183,1,52,51,43,1,37,36,31, + 1,52,51,43,1,225,221,191,1,237,233,202,1,238,234,205,1,66,65,58, + 1,239,236,210,1,240,237,212,1,240,238,215,1,132,131,119,1,185,183,168, + 1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173, + 1,229,224,175,1,230,224,178,1,223,217,174,1,229,224,182,1,232,227,185, + 1,233,228,188,1,233,229,190,1,234,230,193,1,223,219,185,1,236,231,197, + 1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210, + 1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,28,28,26,1,103,100,77,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7, + 1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180, + 1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193, + 1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205, + 1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217, + 1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1,228,222,171, + 1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183, + 1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195, + 1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207, + 1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220, + 1,243,240,222,1,243,241,224,1,231,229,215,1,44,43,33,1,229,223,173, + 1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185, + 1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197, + 1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210, + 1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,205,204,191,1,4,3,3,1,171,167,129,1,229,224,175,1,230,224,178, + 1,11,11,9,1,7,7,6,1,23,22,18,1,233,228,188,1,233,229,190, + 1,145,143,120,1,7,7,6,2,61,60,52,1,237,233,202,1,238,234,205, + 1,86,85,75,1,7,7,6,2,115,114,103,1,241,238,217,1,242,239,220, + 1,38,37,34,1,7,7,7,1,4,4,4,1,152,1,0,0,244,244,244, + 1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1,248,248,248, + 2,203,203,203,1,128,128,128,2,188,188,188,1,248,248,248,2,173,173,173, + 1,128,128,128,2,221,221,221,1,248,248,248,2,139,139,139,1,128,128,128, + 1,131,131,131,1,244,244,244,1,154,154,154,1,255,255,255,22,248,248,248, + 1,128,128,128,1,255,255,255,22,229,229,229,1,128,128,128,1,255,255,255, + 22,128,128,128,1,236,236,236,1,255,255,255,22,128,128,128,1,248,248,248, + 1,255,255,255,22,165,165,165,1,240,240,240,1,255,255,255,22,248,248,248, + 1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255, + 22,195,195,195,1,150,150,150,1,255,255,255,22,128,128,128,1,248,248,248, + 1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,195,195,195, + 1,210,210,210,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255, + 22,248,248,248,1,128,128,128,1,255,255,255,22,165,165,165,1,180,180,180, + 1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,128,128,128, + 1,248,248,248,1,255,255,255,22,229,229,229,1,176,176,176,1,255,255,255, + 22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128, + 1,255,255,255,22,131,131,131,1,214,214,214,1,255,255,255,22,128,128,128, + 1,248,248,248,1,255,255,255,22,139,139,139,1,244,244,244,1,146,146,146, + 1,128,128,128,2,244,244,244,1,248,248,248,1,233,233,233,1,128,128,128, + 2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2,188,188,188, + 1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221,1,248,248,248, + 1,244,244,244,1,0,0) + ); + +const + objdata_tsigconnector: record size: integer; data: array[0..2796] of byte end = + (size: 2797; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,115,105, + 103,99,111,110,110,101,99,116,111,114,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,116,10,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,164,8,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,4,3,3,1,7,7,5,1,22, + 22,17,1,230,224,178,1,231,225,180,1,143,140,113,1,7,7,6,2,61, + 60,49,1,234,230,193,1,235,231,195,1,85,83,71,1,7,7,6,2,114, + 112,98,1,238,235,207,1,239,236,210,1,37,37,33,1,7,7,7,2,204, + 201,185,1,243,240,222,1,230,228,212,1,4,4,4,1,151,147,113,1,229, + 223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232, + 227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236, + 231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239, + 236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243, + 240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229, + 224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233, + 228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240, + 237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243, + 241,224,1,28,28,26,1,228,222,171,1,229,223,173,1,229,224,175,1,230, + 224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233, + 229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240, + 238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244, + 242,227,1,18,18,14,1,229,223,173,1,229,224,175,1,230,224,178,1,231, + 225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234, + 230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241, + 238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,7, + 7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231, + 226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235, + 231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242, + 239,220,1,243,240,222,1,243,241,224,1,133,132,124,1,14,14,11,1,229, + 223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232, + 227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236, + 231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239, + 236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243, + 240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229, + 224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233, + 228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240, + 237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243, + 241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230, + 224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233, + 229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240, + 238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,75, + 75,70,1,160,156,120,1,229,223,173,1,229,224,175,1,230,224,178,1,231, + 225,180,1,127,124,100,1,177,174,141,1,233,228,188,1,233,229,190,1,234, + 230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,132, + 131,119,1,185,183,168,1,243,240,222,1,243,241,224,1,244,242,227,1,7, + 7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,177, + 173,140,1,22,21,17,1,178,174,144,1,233,229,190,1,234,230,193,1,235, + 231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,184,182,166,1,23, + 22,21,1,186,184,170,1,243,241,224,1,244,242,227,1,7,7,5,1,229, + 223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,177, + 174,141,1,22,21,18,1,178,175,145,1,234,230,193,1,235,231,195,1,236, + 231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239, + 236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,185,183,168,1,23, + 23,21,1,186,184,171,1,75,75,70,1,49,48,37,1,229,223,173,1,229, + 224,175,1,0,0,0,19,53,53,49,1,7,7,7,1,228,222,171,1,229, + 223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,177, + 174,141,1,22,21,18,1,178,175,145,1,234,230,193,1,235,231,195,1,236, + 231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239, + 236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,185,183,168,1,23, + 23,21,1,186,184,171,1,7,7,7,1,228,222,171,1,229,223,173,1,229, + 224,175,1,230,224,178,1,231,225,180,1,177,173,140,1,22,21,17,1,178, + 174,144,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240, + 237,212,1,240,238,215,1,184,182,166,1,23,22,21,1,186,184,170,1,243, + 241,224,1,133,132,124,1,95,93,71,1,229,223,173,1,229,224,175,1,230, + 224,178,1,231,225,180,1,127,124,100,1,177,174,141,1,233,228,188,1,233, + 229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240, + 238,215,1,132,131,119,1,185,183,168,1,243,240,222,1,243,241,224,1,244, + 242,227,1,7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231, + 225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234, + 230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241, + 238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,7, + 7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231, + 226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235, + 231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242, + 239,220,1,243,240,222,1,243,241,224,1,28,28,26,1,103,100,77,1,229, + 223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232, + 227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236, + 231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239, + 236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243, + 240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229, + 224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233, + 228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240, + 237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243, + 241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230, + 224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233, + 229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240, + 238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,231, + 229,215,1,44,43,33,1,229,223,173,1,229,224,175,1,230,224,178,1,231, + 225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234, + 230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241, + 238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,7, + 7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231, + 226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235, + 231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242, + 239,220,1,243,240,222,1,243,241,224,1,205,204,191,1,4,3,3,1,171, + 167,129,1,229,224,175,1,230,224,178,1,11,11,9,1,7,7,6,1,23, + 22,18,1,233,228,188,1,233,229,190,1,145,143,120,1,7,7,6,2,61, + 60,52,1,237,233,202,1,238,234,205,1,86,85,75,1,7,7,6,2,115, + 114,103,1,241,238,217,1,242,239,220,1,38,37,34,1,7,7,7,1,4, + 4,4,1,152,1,0,0,244,244,244,1,248,248,248,1,233,233,233,1,128, + 128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2,188, + 188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221,1,248, + 248,248,2,139,139,139,1,128,128,128,1,131,131,131,1,244,244,244,1,154, + 154,154,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,229, + 229,229,1,128,128,128,1,255,255,255,22,128,128,128,1,236,236,236,1,255, + 255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,165,165,165,1,240, + 240,240,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248, + 248,248,1,128,128,128,1,255,255,255,22,195,195,195,1,150,150,150,1,255, + 255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,128,128,128,1,248, + 248,248,1,255,255,255,22,195,195,195,1,210,210,210,1,255,255,255,22,248, + 248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1,255, + 255,255,22,165,165,165,1,180,180,180,1,255,255,255,22,128,128,128,1,248, + 248,248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,229, + 229,229,1,176,176,176,1,255,255,255,22,248,248,248,1,128,128,128,1,255, + 255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,131,131,131,1,214, + 214,214,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,139, + 139,139,1,244,244,244,1,146,146,146,1,128,128,128,2,244,244,244,1,248, + 248,248,1,233,233,233,1,128,128,128,2,158,158,158,1,248,248,248,2,203, + 203,203,1,128,128,128,2,188,188,188,1,248,248,248,2,173,173,173,1,128, + 128,128,2,221,221,221,1,248,248,248,1,244,244,244,1,0,0) + ); + +const + objdata_ttrigconnector: record size: integer; data: array[0..2821] of byte end = + (size: 2822; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,116,114, + 105,103,99,111,110,110,101,99,116,111,114,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,140,10,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,188,8,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,4,3,3,1,7,7,5,1, + 22,22,17,1,230,224,178,1,231,225,180,1,143,140,113,1,7,7,6,2, + 61,60,49,1,234,230,193,1,235,231,195,1,85,83,71,1,7,7,6,2, + 114,112,98,1,238,235,207,1,239,236,210,1,37,37,33,1,7,7,7,2, + 204,201,185,1,243,240,222,1,230,228,212,1,4,4,4,1,151,147,113,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,156,155,229,1,90,89,241,1,241,238,219,1,243,240,222,1, + 243,241,224,1,28,28,26,1,228,222,171,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,234,231,211,1,107,106,236,1, + 88,88,246,1,131,130,244,1,177,175,213,1,242,239,221,1,243,241,224,1, + 244,242,227,1,18,18,14,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,212,209,212,1,78,77,241,1,112,112,249,1,176,175,254,1, + 89,88,231,1,116,115,199,1,239,236,218,1,243,241,224,1,244,242,227,1, + 7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1, + 235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,175,173,218,1, + 80,79,243,1,142,142,253,1,133,133,245,1,68,68,222,1,138,136,171,1, + 185,183,168,1,234,231,214,1,242,240,224,1,133,132,124,1,14,14,11,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,235,231,200,1,124,122,228,1,101,101,243,1,176,176,254,1, + 92,91,233,1,94,93,197,1,169,167,154,1,203,200,183,1,235,232,214,1, + 242,239,221,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,220,216,201,1, + 87,86,235,1,132,132,246,1,136,135,245,1,71,70,221,1,145,143,163,1, + 185,182,163,1,223,221,200,1,238,235,214,1,242,239,220,1,243,240,222,1, + 243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,190,187,207,1,85,84,239,1,158,158,249,1, + 96,95,234,1,103,101,191,1,171,169,150,1,205,202,180,1,234,231,207,1, + 239,237,214,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1, + 75,75,70,1,160,156,120,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,127,124,100,1,177,174,141,1,233,228,188,1,233,229,190,1, + 143,140,217,1,108,107,241,1,135,134,244,1,79,78,221,1,152,149,157,1, + 186,183,160,1,223,220,194,1,236,233,208,1,240,237,212,1,240,238,215,1, + 132,131,119,1,185,183,168,1,243,240,222,1,243,241,224,1,244,242,227,1, + 7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 177,173,140,1,22,21,17,1,177,173,144,1,94,92,229,1,136,135,243,1, + 91,90,238,1,117,115,187,1,173,170,147,1,206,202,175,1,233,229,200,1, + 237,234,206,1,239,236,210,1,240,237,212,1,240,238,215,1,184,182,166,1, + 23,22,21,1,186,184,170,1,243,241,224,1,244,242,227,1,7,7,5,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 177,174,141,1,22,21,18,1,142,139,166,1,85,84,228,1,34,33,235,1, + 56,55,223,1,188,185,197,1,234,230,200,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,185,183,168,1, + 23,23,21,1,186,184,171,1,75,75,70,1,49,48,37,1,229,223,173,1, + 229,224,175,1,0,0,0,7,0,0,89,1,0,0,187,1,0,0,203,1, + 0,0,129,1,0,0,8,1,0,0,0,7,53,53,49,1,7,7,7,1, + 228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,177,174,141,1,22,21,18,1,178,175,145,1,234,230,193,1, + 232,228,192,1,212,208,187,1,95,94,208,1,40,40,234,1,59,57,237,1, + 171,169,218,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1, + 185,183,168,1,23,23,21,1,186,184,171,1,7,7,7,1,228,222,171,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,177,173,140,1, + 22,21,17,1,178,174,144,1,233,229,190,1,234,230,193,1,235,231,195,1, + 235,230,196,1,232,228,197,1,189,185,191,1,72,71,218,1,41,40,238,1, + 91,89,234,1,216,213,215,1,240,238,215,1,184,182,166,1,23,22,21,1, + 186,184,170,1,243,241,224,1,133,132,124,1,95,93,71,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,127,124,100,1,177,174,141,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,235,231,201,1,232,228,200,1,157,154,198,1,55,54,228,1, + 49,49,241,1,141,139,228,1,130,129,119,1,185,183,168,1,243,240,222,1, + 243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,230,227,201,1, + 173,170,218,1,237,233,205,1,236,233,205,1,207,206,206,1,27,26,245,1, + 85,84,220,1,219,216,209,1,241,238,219,1,243,240,222,1,243,241,224,1, + 244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 234,230,193,1,235,231,195,1,236,231,197,1,143,141,225,1,150,148,230,1, + 228,224,196,1,181,179,218,1,62,61,243,1,180,177,218,1,208,206,186,1, + 223,220,201,1,241,238,219,1,243,240,222,1,243,241,224,1,28,28,26,1, + 103,100,77,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1, + 235,231,195,1,217,212,202,1,105,104,249,1,155,154,230,1,115,113,213,1, + 116,114,231,1,227,224,207,1,224,221,198,1,234,232,210,1,240,237,216,1, + 242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 145,142,230,1,160,160,255,1,129,129,248,1,108,107,217,1,182,180,214,1, + 230,227,204,1,238,235,211,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,202,199,205,1,152,152,252,1, + 150,150,255,1,88,88,255,1,26,26,255,1,30,30,244,1,93,92,233,1, + 205,203,217,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,231,229,215,1,44,43,33,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,154,153,235,1,144,144,245,1,108,107,213,1, + 104,103,187,1,135,133,162,1,168,166,146,1,182,179,160,1,210,207,185,1, + 237,235,212,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1, + 244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 234,230,193,1,205,201,203,1,191,187,160,1,176,173,149,1,193,190,165,1, + 211,208,182,1,229,226,199,1,236,233,207,1,239,236,211,1,240,238,215,1, + 241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,205,204,191,1, + 4,3,3,1,171,167,129,1,229,224,175,1,230,224,178,1,11,11,9,1, + 7,7,6,1,23,22,18,1,233,228,188,1,233,229,190,1,145,143,120,1, + 7,7,6,2,60,59,51,1,234,230,199,1,236,232,203,1,86,85,75,1, + 7,7,6,2,115,114,103,1,241,238,217,1,242,239,220,1,38,37,34,1, + 7,7,7,1,4,4,4,1,152,1,0,0,244,244,244,1,248,248,248,1, + 233,233,233,1,128,128,128,2,158,158,158,1,248,248,248,2,203,203,203,1, + 128,128,128,2,188,188,188,1,248,248,248,2,173,173,173,1,128,128,128,2, + 221,221,221,1,248,248,248,2,139,139,139,1,128,128,128,1,131,131,131,1, + 244,244,244,1,154,154,154,1,255,255,255,22,248,248,248,1,128,128,128,1, + 255,255,255,22,229,229,229,1,128,128,128,1,255,255,255,22,128,128,128,1, + 236,236,236,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22, + 165,165,165,1,240,240,240,1,255,255,255,22,248,248,248,1,128,128,128,1, + 255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,195,195,195,1, + 150,150,150,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22, + 128,128,128,1,248,248,248,1,255,255,255,22,195,195,195,1,210,210,210,1, + 255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1, + 128,128,128,1,255,255,255,22,165,165,165,1,180,180,180,1,255,255,255,22, + 128,128,128,1,248,248,248,1,255,255,255,22,128,128,128,1,248,248,248,1, + 255,255,255,22,229,229,229,1,176,176,176,1,255,255,255,22,248,248,248,1, + 128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22, + 131,131,131,1,214,214,214,1,255,255,255,22,128,128,128,1,248,248,248,1, + 255,255,255,22,139,139,139,1,244,244,244,1,146,146,146,1,128,128,128,2, + 244,244,244,1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1, + 248,248,248,2,204,204,204,1,129,129,129,2,188,188,188,1,248,248,248,2, + 173,173,173,1,128,128,128,2,221,221,221,1,248,248,248,1,244,244,244,1, + 0,0) + ); + +const + objdata_tsigwavetable: record size: integer; data: array[0..2868] of byte end = + (size: 2869; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,115,105, + 103,119,97,118,101,116,97,98,108,101,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,188,10,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,236,8,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,4,3,3,1,7,7,5,1,22, + 22,17,1,230,224,178,1,231,225,180,1,143,140,113,1,7,7,6,2,61, + 60,49,1,234,230,193,1,235,231,195,1,85,83,71,1,7,7,6,2,114, + 112,98,1,238,235,207,1,239,236,210,1,37,37,33,1,7,7,7,2,204, + 201,185,1,243,240,222,1,230,228,212,1,4,4,4,1,151,147,113,1,229, + 223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232, + 227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236, + 231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239, + 236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243, + 240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229, + 224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,149, + 146,120,1,139,137,113,1,234,230,193,1,235,231,195,1,236,231,197,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240, + 237,212,1,240,238,215,1,241,238,217,1,236,233,215,1,110,108,100,1,242, + 240,223,1,28,28,26,1,228,222,171,1,229,223,173,1,229,224,175,1,230, + 224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,43,42,35,1,17, + 17,14,1,228,224,188,1,235,231,195,1,236,231,197,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240, + 238,215,1,241,238,217,1,173,171,157,1,56,56,51,1,243,241,224,1,244, + 242,227,1,18,18,14,1,229,223,173,1,229,224,175,1,230,224,178,1,231, + 225,180,1,231,226,183,1,207,202,165,1,23,22,18,1,62,61,51,1,151, + 149,125,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241, + 238,217,1,94,93,85,1,134,133,123,1,243,241,224,1,244,242,227,1,7, + 7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231, + 226,183,1,139,136,111,1,90,88,72,1,157,154,128,1,57,56,47,1,235, + 231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,238,235,214,1,20, + 20,18,1,213,210,194,1,243,241,224,1,133,132,124,1,14,14,11,1,229, + 223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,72, + 70,57,1,157,154,127,1,228,225,186,1,22,22,18,1,199,196,165,1,236, + 231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239, + 236,210,1,240,237,212,1,240,238,215,1,181,178,163,1,48,48,44,1,243, + 240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229, + 224,175,1,230,224,178,1,231,225,180,1,225,220,178,1,15,15,12,1,220, + 215,178,1,233,229,190,1,109,107,90,1,105,103,87,1,236,231,197,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240, + 237,212,1,240,238,215,1,103,102,93,1,127,126,116,1,243,240,222,1,243, + 241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230, + 224,178,1,231,225,180,1,168,164,133,1,60,59,48,1,233,228,188,1,233, + 229,190,1,202,198,167,1,19,19,16,1,230,225,192,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,239, + 237,214,1,26,26,24,1,205,202,186,1,243,240,222,1,243,241,224,1,75, + 75,70,1,160,156,120,1,229,223,173,1,229,224,175,1,230,224,178,1,231, + 225,180,1,100,97,79,1,127,125,102,1,233,228,188,1,233,229,190,1,234, + 230,193,1,62,61,51,1,154,150,128,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,188,187,169,1,41, + 40,37,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,7, + 7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,33, + 32,26,1,196,191,156,1,233,228,188,1,233,229,190,1,234,230,193,1,156, + 153,129,1,58,57,49,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,111,110,99,1,119,118,107,1,242, + 239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229, + 223,173,1,229,224,175,1,230,224,178,1,197,191,153,1,31,30,24,1,232, + 227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,229,226,190,1,20, + 20,17,1,200,197,169,1,237,233,202,1,238,234,205,1,238,235,207,1,239, + 236,210,1,240,237,212,1,34,34,30,1,198,195,178,1,242,239,220,1,243, + 240,222,1,243,241,224,1,75,75,70,1,49,48,37,1,229,223,173,1,229, + 224,175,1,230,224,178,1,129,125,100,1,98,96,78,1,232,227,185,1,233, + 228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,108,106,90,1,106, + 105,90,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,197, + 194,174,1,34,34,30,1,241,238,217,1,242,239,220,1,243,240,222,1,243, + 241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230, + 224,178,1,62,60,48,1,166,162,131,1,232,227,185,1,233,228,188,1,233, + 229,190,1,234,230,193,1,235,231,195,1,202,197,168,1,19,19,16,1,230, + 227,196,1,238,234,205,1,238,235,207,1,239,236,210,1,120,118,106,1,111, + 110,99,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7, + 7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,219,213,170,1,14, + 14,11,1,224,219,177,1,232,227,185,1,233,228,188,1,233,229,190,1,234, + 230,193,1,235,231,195,1,236,231,197,1,60,59,51,1,155,153,132,1,238, + 234,205,1,238,235,207,1,239,236,210,1,42,42,37,1,189,188,169,1,241, + 238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,133,132,124,1,95, + 93,71,1,229,223,173,1,229,224,175,1,157,153,121,1,69,67,54,1,231, + 226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235, + 231,195,1,236,231,197,1,155,152,131,1,59,58,51,1,238,234,205,1,238, + 235,207,1,204,202,180,1,27,27,24,1,239,237,214,1,241,238,217,1,242, + 239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229, + 223,173,1,229,224,175,1,89,87,69,1,137,133,107,1,231,226,183,1,232, + 227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236, + 231,197,1,230,227,195,1,20,19,17,1,203,199,174,1,238,235,207,1,127, + 126,112,1,104,103,92,1,240,238,215,1,241,238,217,1,242,239,220,1,243, + 240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229, + 224,175,1,23,23,18,1,204,199,159,1,231,226,183,1,232,227,185,1,233, + 228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236, + 232,200,1,107,105,91,1,108,106,93,1,238,235,207,1,51,50,44,1,183, + 180,161,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243, + 241,224,1,28,28,26,1,103,100,77,1,229,223,173,1,185,181,141,1,40, + 39,31,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233, + 229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,201, + 197,171,1,20,19,17,1,205,203,179,1,22,22,20,1,238,235,210,1,240, + 238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7, + 7,7,1,228,222,171,1,229,223,173,1,118,115,90,1,107,105,83,1,231, + 225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234, + 230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,59, + 58,51,1,56,55,49,1,97,95,85,1,240,237,212,1,240,238,215,1,241, + 238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1,228, + 222,171,1,229,223,173,1,51,50,39,1,175,170,135,1,231,225,180,1,231, + 226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235, + 231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,154,151,133,1,0, + 0,0,1,174,172,153,1,240,237,212,1,240,238,215,1,241,238,217,1,242, + 239,220,1,243,240,222,1,243,241,224,1,231,229,215,1,44,43,33,1,229, + 223,173,1,163,160,125,1,226,220,175,1,231,225,180,1,231,226,183,1,232, + 227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236, + 231,197,1,236,232,200,1,237,233,202,1,231,228,199,1,150,148,131,1,235, + 232,207,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243, + 240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229, + 224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233, + 228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240, + 237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243, + 241,224,1,205,204,191,1,4,3,3,1,171,167,129,1,229,224,175,1,230, + 224,178,1,11,11,9,1,7,7,6,1,23,22,18,1,233,228,188,1,233, + 229,190,1,145,143,120,1,7,7,6,2,61,60,52,1,237,233,202,1,238, + 234,205,1,86,85,75,1,7,7,6,2,115,114,103,1,241,238,217,1,242, + 239,220,1,38,37,34,1,7,7,7,1,4,4,4,1,152,1,0,0,244, + 244,244,1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1,248, + 248,248,2,203,203,203,1,128,128,128,2,188,188,188,1,248,248,248,2,173, + 173,173,1,128,128,128,2,221,221,221,1,248,248,248,2,139,139,139,1,128, + 128,128,1,131,131,131,1,244,244,244,1,154,154,154,1,255,255,255,22,248, + 248,248,1,128,128,128,1,255,255,255,22,229,229,229,1,128,128,128,1,255, + 255,255,22,128,128,128,1,236,236,236,1,255,255,255,22,128,128,128,1,248, + 248,248,1,255,255,255,22,165,165,165,1,240,240,240,1,255,255,255,22,248, + 248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1,255, + 255,255,22,195,195,195,1,150,150,150,1,255,255,255,22,128,128,128,1,248, + 248,248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,195, + 195,195,1,210,210,210,1,255,255,255,22,248,248,248,1,128,128,128,1,255, + 255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,165,165,165,1,180, + 180,180,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,128, + 128,128,1,248,248,248,1,255,255,255,22,229,229,229,1,176,176,176,1,255, + 255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128, + 128,128,1,255,255,255,22,131,131,131,1,214,214,214,1,255,255,255,22,128, + 128,128,1,248,248,248,1,255,255,255,22,139,139,139,1,244,244,244,1,146, + 146,146,1,128,128,128,2,244,244,244,1,248,248,248,1,233,233,233,1,128, + 128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2,188, + 188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221,1,248, + 248,248,1,244,244,244,1,0,0) + ); + +const + objdata_tsigfuncttable: record size: integer; data: array[0..2869] of byte end = + (size: 2870; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,115,105, + 103,102,117,110,99,116,116,97,98,108,101,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,188,10,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,236,8,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,4,3,3,1,7,7,5,1, + 22,22,17,1,230,224,178,1,231,225,180,1,143,140,113,1,7,7,6,2, + 61,60,49,1,234,230,193,1,235,231,195,1,85,83,71,1,7,7,6,2, + 114,112,98,1,238,235,207,1,239,236,210,1,37,37,33,1,7,7,7,2, + 204,201,185,1,243,240,222,1,230,228,212,1,4,4,4,1,151,147,113,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 223,220,197,1,120,119,107,1,120,119,108,1,121,119,110,1,121,120,111,1, + 243,241,224,1,28,28,26,1,228,222,171,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,232,229,203,1,33,33,29,1, + 104,104,94,1,120,119,108,1,121,119,110,1,121,120,111,1,243,241,224,1, + 244,242,227,1,18,18,14,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,118,117,104,1,79,78,70,1,240,238,215,1, + 241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1, + 7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1, + 235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 203,201,177,1,19,19,16,1,215,212,190,1,240,238,215,1,241,238,217,1, + 242,239,220,1,243,240,222,1,243,241,224,1,133,132,124,1,14,14,11,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,64,64,56,1, + 132,130,116,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,158,155,136,1,42,41,37,1,235,232,207,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1, + 225,221,192,1,25,25,22,1,183,181,159,1,239,236,210,1,240,237,212,1, + 240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1, + 75,75,70,1,160,156,120,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,104,102,89,1, + 91,90,79,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1, + 241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1, + 7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1, + 235,231,195,1,236,231,197,1,193,189,163,1,20,20,17,1,219,216,189,1, + 238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1, + 242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 235,230,196,1,53,52,45,1,144,142,123,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,75,75,70,1,49,48,37,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,143,140,120,1, + 53,52,45,1,236,232,201,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,217,213,180,1,20,20,17,1,193,189,163,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1, + 7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 234,230,193,1,90,89,75,1,104,101,87,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1, + 241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,133,132,124,1, + 95,93,71,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,180,177,148,1, + 25,24,21,1,224,219,187,1,236,232,200,1,237,233,202,1,238,234,205,1, + 238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1, + 242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,229,225,187,1,41,41,34,1,156,153,129,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,129,127,105,1,63,62,52,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,28,28,26,1,103,100,77,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,208,204,168,1, + 18,18,15,1,200,197,165,1,235,231,195,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1, + 7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,77,75,62,1,115,113,94,1, + 234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1, + 241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1, + 228,222,171,1,229,223,173,1,114,112,87,1,115,112,89,1,115,112,90,1, + 115,113,91,1,101,99,81,1,32,31,26,1,226,222,184,1,234,230,193,1, + 235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1, + 242,239,220,1,243,240,222,1,243,241,224,1,231,229,215,1,44,43,33,1, + 229,223,173,1,114,112,87,1,115,112,89,1,115,112,90,1,115,113,91,1, + 116,113,92,1,217,212,175,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,205,204,191,1,4,3,3,1,171,167,129,1,229,224,175,1, + 230,224,178,1,11,11,9,1,7,7,6,1,23,22,18,1,233,228,188,1, + 233,229,190,1,145,143,120,1,7,7,6,2,61,60,52,1,237,233,202,1, + 238,234,205,1,86,85,75,1,7,7,6,2,115,114,103,1,241,238,217,1, + 242,239,220,1,38,37,34,1,7,7,7,1,4,4,4,1,152,1,0,0, + 244,244,244,1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1, + 248,248,248,2,203,203,203,1,128,128,128,2,188,188,188,1,248,248,248,2, + 173,173,173,1,128,128,128,2,221,221,221,1,248,248,248,2,139,139,139,1, + 128,128,128,1,131,131,131,1,244,244,244,1,154,154,154,1,255,255,255,22, + 248,248,248,1,128,128,128,1,255,255,255,22,229,229,229,1,128,128,128,1, + 255,255,255,22,128,128,128,1,236,236,236,1,255,255,255,22,128,128,128,1, + 248,248,248,1,255,255,255,22,165,165,165,1,240,240,240,1,255,255,255,22, + 248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1, + 255,255,255,22,195,195,195,1,150,150,150,1,255,255,255,22,128,128,128,1, + 248,248,248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22, + 195,195,195,1,210,210,210,1,255,255,255,22,248,248,248,1,128,128,128,1, + 255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,165,165,165,1, + 180,180,180,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22, + 128,128,128,1,248,248,248,1,255,255,255,22,229,229,229,1,176,176,176,1, + 255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1, + 128,128,128,1,255,255,255,22,131,131,131,1,214,214,214,1,255,255,255,22, + 128,128,128,1,248,248,248,1,255,255,255,22,139,139,139,1,244,244,244,1, + 146,146,146,1,128,128,128,2,244,244,244,1,248,248,248,1,233,233,233,1, + 128,128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2, + 188,188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221,1, + 248,248,248,1,244,244,244,1,0,0) + ); + +const + objdata_tsigenvelope: record size: integer; data: array[0..2867] of byte end = + (size: 2868; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,115,105, + 103,101,110,118,101,108,111,112,101,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,188,10,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,236,8,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,4,3,3,1,7,7,5,1,22,22, + 17,1,230,224,178,1,231,225,180,1,143,140,113,1,7,7,6,2,61,60, + 49,1,234,230,193,1,235,231,195,1,85,83,71,1,7,7,6,2,114,112, + 98,1,238,235,207,1,239,236,210,1,37,37,33,1,7,7,7,2,204,201, + 185,1,243,240,222,1,230,228,212,1,4,4,4,1,151,147,113,1,229,223, + 173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227, + 185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231, + 197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236, + 210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240, + 222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224, + 175,1,226,220,175,1,215,209,167,1,231,226,183,1,232,227,185,1,233,228, + 188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232, + 200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237, + 212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241, + 224,1,28,28,26,1,228,222,171,1,229,223,173,1,229,224,175,1,100,98, + 77,1,35,34,28,1,226,222,179,1,232,227,185,1,233,228,188,1,233,229, + 190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233, + 202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238, + 215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242, + 227,1,18,18,14,1,229,223,173,1,229,224,175,1,75,73,58,1,13,12, + 10,1,130,128,103,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230, + 193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234, + 205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238, + 217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7, + 5,1,229,223,173,1,229,224,175,1,50,48,38,1,139,135,108,1,20,19, + 16,1,216,211,172,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231, + 195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235, + 207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239, + 220,1,243,240,222,1,243,241,224,1,133,132,124,1,14,14,11,1,229,223, + 173,1,229,224,175,1,23,23,18,1,201,196,157,1,99,97,78,1,99,97, + 79,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231, + 197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236, + 210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240, + 222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,225,220, + 172,1,4,4,3,1,226,220,176,1,215,210,170,1,20,20,16,1,196,192, + 159,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232, + 200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237, + 212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241, + 224,1,7,7,7,1,228,222,171,1,229,223,173,1,202,198,154,1,21,20, + 16,1,231,225,180,1,231,226,183,1,132,129,105,1,67,65,54,1,233,229, + 190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233, + 202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238, + 215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,75,75, + 70,1,160,156,120,1,229,223,173,1,177,173,135,1,47,46,36,1,231,225, + 180,1,231,226,183,1,228,223,182,1,36,35,29,1,101,99,82,1,117,115, + 96,1,117,115,97,1,118,115,98,1,118,116,100,1,118,116,101,1,119,117, + 102,1,119,117,103,1,119,118,105,1,120,118,106,1,120,119,107,1,120,119, + 108,1,240,237,218,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7, + 5,1,229,223,173,1,151,148,115,1,73,71,57,1,231,225,180,1,231,226, + 183,1,232,227,185,1,217,212,175,1,116,114,95,1,117,115,96,1,117,115, + 97,1,118,115,98,1,118,116,100,1,118,116,101,1,119,117,102,1,119,117, + 103,1,119,118,105,1,120,118,106,1,120,119,107,1,70,69,63,1,111,110, + 101,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223, + 173,1,126,123,96,1,98,96,76,1,231,225,180,1,231,226,183,1,232,227, + 185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231, + 197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236, + 210,1,240,237,212,1,240,238,215,1,175,173,157,1,65,64,59,1,243,240, + 222,1,243,241,224,1,75,75,70,1,49,48,37,1,229,223,173,1,100,98, + 76,1,124,121,96,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228, + 188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232, + 200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237, + 212,1,240,238,215,1,219,217,197,1,19,19,17,1,243,240,222,1,243,241, + 224,1,7,7,7,1,228,222,171,1,229,223,173,1,75,73,57,1,151,147, + 117,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229, + 190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233, + 202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238, + 215,1,241,238,217,1,23,22,21,1,217,215,198,1,243,241,224,1,7,7, + 7,1,228,222,171,1,229,223,173,1,49,48,38,1,176,171,136,1,231,225, + 180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230, + 193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234, + 205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238, + 217,1,67,67,61,1,172,169,157,1,243,241,224,1,133,132,124,1,95,93, + 71,1,229,223,173,1,23,23,18,1,202,197,156,1,231,225,180,1,231,226, + 183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231, + 195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235, + 207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,112,111, + 102,1,126,124,115,1,243,241,224,1,244,242,227,1,7,7,5,1,225,220, + 170,1,4,4,3,1,225,220,175,1,231,225,180,1,231,226,183,1,232,227, + 185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231, + 197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236, + 210,1,240,237,212,1,240,238,215,1,241,238,217,1,158,156,143,1,80,79, + 73,1,243,241,224,1,244,242,227,1,7,7,5,1,202,197,153,1,22,22, + 17,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228, + 188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232, + 200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237, + 212,1,240,238,215,1,241,238,217,1,202,200,184,1,33,33,30,1,243,241, + 224,1,28,28,26,1,103,100,77,1,177,172,134,1,48,47,37,1,230,224, + 178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229, + 190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233, + 202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238, + 215,1,241,238,217,1,239,236,217,1,10,9,9,1,231,229,213,1,7,7, + 7,1,228,222,171,1,151,147,114,1,75,73,57,1,230,224,178,1,231,225, + 180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230, + 193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234, + 205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238, + 217,1,242,239,220,1,50,49,45,1,186,184,171,1,7,7,7,1,228,222, + 171,1,129,126,98,1,100,98,76,1,230,224,178,1,231,225,180,1,231,226, + 183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231, + 195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235, + 207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239, + 220,1,94,93,86,1,146,145,134,1,231,229,215,1,44,43,33,1,229,223, + 173,1,225,220,172,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227, + 185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231, + 197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236, + 210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,237,234, + 217,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224, + 175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228, + 188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232, + 200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237, + 212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241, + 224,1,205,204,191,1,4,3,3,1,171,167,129,1,229,224,175,1,230,224, + 178,1,11,11,9,1,7,7,6,1,23,22,18,1,233,228,188,1,233,229, + 190,1,145,143,120,1,7,7,6,2,61,60,52,1,237,233,202,1,238,234, + 205,1,86,85,75,1,7,7,6,2,115,114,103,1,241,238,217,1,242,239, + 220,1,38,37,34,1,7,7,7,1,4,4,4,1,152,1,0,0,244,244, + 244,1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1,248,248, + 248,2,203,203,203,1,128,128,128,2,188,188,188,1,248,248,248,2,173,173, + 173,1,128,128,128,2,221,221,221,1,248,248,248,2,139,139,139,1,128,128, + 128,1,131,131,131,1,244,244,244,1,154,154,154,1,255,255,255,22,248,248, + 248,1,128,128,128,1,255,255,255,22,229,229,229,1,128,128,128,1,255,255, + 255,22,128,128,128,1,236,236,236,1,255,255,255,22,128,128,128,1,248,248, + 248,1,255,255,255,22,165,165,165,1,240,240,240,1,255,255,255,22,248,248, + 248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255, + 255,22,195,195,195,1,150,150,150,1,255,255,255,22,128,128,128,1,248,248, + 248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,195,195, + 195,1,210,210,210,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255, + 255,22,248,248,248,1,128,128,128,1,255,255,255,22,165,165,165,1,180,180, + 180,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,128,128, + 128,1,248,248,248,1,255,255,255,22,229,229,229,1,176,176,176,1,255,255, + 255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128, + 128,1,255,255,255,22,131,131,131,1,214,214,214,1,255,255,255,22,128,128, + 128,1,248,248,248,1,255,255,255,22,139,139,139,1,244,244,244,1,146,146, + 146,1,128,128,128,2,244,244,244,1,248,248,248,1,233,233,233,1,128,128, + 128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2,188,188, + 188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221,1,248,248, + 248,1,244,244,244,1,0,0) + ); + +const + objdata_tsigsampler: record size: integer; data: array[0..2858] of byte end = + (size: 2859; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,115,105, + 103,115,97,109,112,108,101,114,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,180,10,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,228,8,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,4,3,3,1,7,7,5,1,22,22,17, + 1,230,224,178,1,231,225,180,1,143,140,113,1,7,7,6,2,61,60,49, + 1,234,230,193,1,235,231,195,1,85,83,71,1,7,7,6,2,114,112,98, + 1,238,235,207,1,239,236,210,1,37,37,33,1,7,7,7,2,204,201,185, + 1,243,240,222,1,230,228,212,1,4,4,4,1,151,147,113,1,229,223,173, + 1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185, + 1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197, + 1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210, + 1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,28,28,26,1,228,222,171,1,229,223,173,1,194,190,148,1,69,67,53, + 1,35,34,28,1,66,65,52,1,183,179,146,1,233,228,188,1,233,229,190, + 1,234,230,193,1,171,168,142,1,59,58,49,1,230,226,195,1,237,233,202, + 1,238,234,205,1,156,154,136,1,52,52,46,1,216,214,191,1,240,238,215, + 1,241,238,217,1,241,238,219,1,69,68,63,1,150,148,138,1,244,242,227, + 1,18,18,14,1,229,223,173,1,34,33,26,1,162,158,126,1,226,221,176, + 1,176,172,139,1,15,15,12,1,223,218,180,1,233,229,190,1,234,230,193, + 1,73,72,60,1,74,72,62,1,153,150,129,1,237,233,202,1,238,234,205, + 1,133,131,115,1,19,19,16,1,137,136,121,1,240,238,215,1,241,238,217, + 1,186,184,169,1,14,14,13,1,123,122,113,1,244,242,227,1,7,7,5, + 1,228,222,172,1,23,23,18,1,179,175,139,1,231,225,180,1,231,226,183, + 1,176,172,140,1,218,214,176,1,233,229,190,1,213,209,176,1,41,41,34, + 1,191,187,159,1,56,55,48,1,237,233,202,1,238,234,205,1,133,131,115, + 1,95,93,83,1,57,57,51,1,240,238,215,1,241,238,217,1,102,101,93, + 1,92,91,84,1,123,122,113,1,133,132,124,1,14,14,11,1,229,223,173, + 1,170,166,130,1,33,33,26,1,37,36,29,1,105,103,83,1,195,191,155, + 1,233,228,188,1,233,229,190,1,128,126,106,1,123,120,102,1,236,231,197, + 1,45,45,38,1,197,194,168,1,238,234,205,1,133,131,115,1,121,119,106, + 1,57,57,51,1,214,212,191,1,238,235,214,1,57,56,52,1,142,140,130, + 1,123,122,113,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175, + 1,230,224,178,1,190,185,148,1,123,121,98,1,25,25,20,1,195,190,157, + 1,233,229,190,1,39,38,32,1,93,91,77,1,118,115,98,1,56,55,48, + 1,100,99,86,1,238,234,205,1,133,131,115,1,121,119,106,1,137,136,121, + 1,133,132,119,1,177,175,159,1,119,117,108,1,143,141,131,1,123,122,113, + 1,7,7,7,1,228,222,171,1,194,189,147,1,75,74,58,1,230,224,178, + 1,231,225,180,1,231,226,183,1,108,106,86,1,139,136,112,1,183,180,149, + 1,48,47,39,1,161,159,134,1,162,159,135,1,156,154,133,1,19,18,16, + 1,228,224,196,1,133,131,115,1,121,119,106,1,216,214,191,1,55,54,49, + 1,95,93,85,1,204,202,185,1,143,141,131,1,123,122,113,1,75,75,70, + 1,160,156,120,1,228,222,172,1,51,50,39,1,95,92,73,1,161,157,126, + 1,141,138,112,1,40,39,32,1,204,199,164,1,93,92,76,1,143,141,118, + 1,235,231,195,1,236,231,197,1,236,232,200,1,76,75,65,1,145,142,125, + 1,133,131,115,1,121,119,106,1,240,237,212,1,61,61,55,1,60,60,54, + 1,242,239,220,1,143,141,131,1,123,122,113,1,244,242,227,1,7,7,5, + 1,229,223,173,1,222,217,170,1,138,134,107,1,100,97,78,1,120,117,95, + 1,199,195,159,1,233,228,188,1,130,128,106,1,221,217,182,1,235,231,195, + 1,236,231,197,1,236,232,200,1,191,188,163,1,155,152,133,1,186,183,162, + 1,180,178,158,1,240,237,212,1,181,179,162,1,175,173,157,1,242,239,220, + 1,193,191,177,1,183,181,169,1,244,242,227,1,7,7,5,1,229,223,173, + 1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185, + 1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197, + 1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210, + 1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,243,241,224,1,75,75,70,1,49,48,37,1,229,223,173,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224, + 1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,160,155,124, + 1,108,105,84,1,108,105,85,1,114,111,91,1,147,144,119,1,226,222,184, + 1,234,230,193,1,133,130,110,1,218,214,182,1,236,232,200,1,237,233,202, + 1,238,234,205,1,225,222,196,1,112,110,98,1,112,111,99,1,112,111,100, + 1,112,111,101,1,113,112,103,1,225,222,205,1,243,241,224,1,7,7,7, + 1,228,222,171,1,229,223,173,1,229,224,175,1,97,95,75,1,92,90,72, + 1,151,148,120,1,147,144,118,1,75,73,60,1,84,83,69,1,234,230,193, + 1,41,41,34,1,202,197,168,1,236,232,200,1,237,233,202,1,238,234,205, + 1,214,211,186,1,21,20,18,1,157,155,139,1,157,156,141,1,158,156,142, + 1,158,157,144,1,232,229,212,1,243,241,224,1,133,132,124,1,95,93,71, + 1,229,223,173,1,229,224,175,1,97,95,75,1,140,137,109,1,231,226,183, + 1,232,227,185,1,210,206,170,1,19,19,16,1,234,230,193,1,41,41,34, + 1,202,197,168,1,236,232,200,1,237,233,202,1,238,234,205,1,214,211,186, + 1,32,31,28,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220, + 1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173, + 1,229,224,175,1,97,95,75,1,132,129,103,1,217,212,172,1,201,197,160, + 1,108,106,87,1,83,82,68,1,234,230,193,1,41,41,34,1,202,197,168, + 1,236,232,200,1,237,233,202,1,238,234,205,1,214,211,186,1,18,18,16, + 1,135,133,119,1,135,133,121,1,135,133,122,1,151,149,137,1,243,240,222, + 1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175, + 1,97,95,75,1,31,30,24,1,50,49,39,1,69,68,55,1,135,132,109, + 1,213,209,174,1,234,230,193,1,41,41,34,1,202,197,168,1,236,232,200, + 1,237,233,202,1,238,234,205,1,214,211,186,1,19,19,16,1,142,140,126, + 1,142,141,127,1,143,141,128,1,158,156,143,1,243,240,222,1,243,241,224, + 1,28,28,26,1,103,100,77,1,229,223,173,1,229,224,175,1,97,95,75, + 1,140,137,109,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,41,41,34,1,202,197,168,1,236,232,200,1,237,233,202, + 1,238,234,205,1,214,211,186,1,32,31,28,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7, + 1,228,222,171,1,229,223,173,1,229,224,175,1,97,95,75,1,140,137,109, + 1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193, + 1,41,41,34,1,182,178,152,1,214,210,181,1,215,211,183,1,222,218,191, + 1,214,211,186,1,29,29,26,1,217,215,192,1,217,216,195,1,218,216,197, + 1,219,217,199,1,236,233,216,1,243,241,224,1,7,7,7,1,228,222,171, + 1,229,223,173,1,229,224,175,1,131,127,101,1,163,159,127,1,231,226,183, + 1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,90,89,75, + 1,58,57,49,2,59,58,50,1,111,109,96,1,220,217,192,1,59,58,52, + 1,59,59,52,1,59,59,53,1,60,59,54,2,188,185,172,1,243,241,224, + 1,231,229,215,1,44,43,33,1,229,223,173,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227, + 1,7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180, + 1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193, + 1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205, + 1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217, + 1,242,239,220,1,243,240,222,1,243,241,224,1,205,204,191,1,4,3,3, + 1,171,167,129,1,229,224,175,1,230,224,178,1,11,11,9,1,7,7,6, + 1,23,22,18,1,233,228,188,1,233,229,190,1,145,143,120,1,7,7,6, + 2,61,60,52,1,237,233,202,1,238,234,205,1,86,85,75,1,7,7,6, + 2,115,114,103,1,241,238,217,1,242,239,220,1,38,37,34,1,7,7,7, + 1,4,4,4,1,152,1,0,0,244,244,244,1,248,248,248,1,233,233,233, + 1,128,128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128, + 2,188,188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221, + 1,248,248,248,2,139,139,139,1,128,128,128,1,131,131,131,1,244,244,244, + 1,154,154,154,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255, + 22,229,229,229,1,128,128,128,1,255,255,255,22,128,128,128,1,236,236,236, + 1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,165,165,165, + 1,240,240,240,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255, + 22,248,248,248,1,128,128,128,1,255,255,255,22,195,195,195,1,150,150,150, + 1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,128,128,128, + 1,248,248,248,1,255,255,255,22,195,195,195,1,210,210,210,1,255,255,255, + 22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128, + 1,255,255,255,22,165,165,165,1,180,180,180,1,255,255,255,22,128,128,128, + 1,248,248,248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255, + 22,229,229,229,1,176,176,176,1,255,255,255,22,248,248,248,1,128,128,128, + 1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,131,131,131, + 1,214,214,214,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255, + 22,139,139,139,1,244,244,244,1,146,146,146,1,128,128,128,2,244,244,244, + 1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1,248,248,248, + 2,203,203,203,1,128,128,128,2,188,188,188,1,248,248,248,2,173,173,173, + 1,128,128,128,2,221,221,221,1,248,248,248,1,244,244,244,1,0,0) + ); + +const + objdata_tsigsamplerfft: record size: integer; data: array[0..2869] of byte end = + (size: 2870; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,115,105, + 103,115,97,109,112,108,101,114,102,102,116,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,188,10,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,236,8,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,4,3,3,1,7,7,5,1, + 22,22,17,1,230,224,178,1,231,225,180,1,143,140,113,1,7,7,6,2, + 61,60,49,1,234,230,193,1,235,231,195,1,85,83,71,1,7,7,6,2, + 114,112,98,1,238,235,207,1,239,236,210,1,37,37,33,1,7,7,7,2, + 204,201,185,1,243,240,222,1,230,228,212,1,4,4,4,1,151,147,113,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,28,28,26,1,228,222,171,1,229,223,173,1,194,190,148,1, + 69,67,53,1,35,34,28,1,66,65,52,1,183,179,146,1,233,228,188,1, + 233,229,190,1,234,230,193,1,171,168,142,1,59,58,49,1,230,226,195,1, + 237,233,202,1,238,234,205,1,156,154,136,1,52,52,46,1,216,214,191,1, + 240,238,215,1,241,238,217,1,241,238,219,1,69,68,63,1,150,148,138,1, + 244,242,227,1,18,18,14,1,229,223,173,1,34,33,26,1,162,158,126,1, + 226,221,176,1,176,172,139,1,15,15,12,1,223,218,180,1,233,229,190,1, + 234,230,193,1,73,72,60,1,74,72,62,1,153,150,129,1,237,233,202,1, + 238,234,205,1,133,131,115,1,19,19,16,1,137,136,121,1,240,238,215,1, + 241,238,217,1,186,184,169,1,14,14,13,1,123,122,113,1,244,242,227,1, + 7,7,5,1,228,222,172,1,23,23,18,1,179,175,139,1,231,225,180,1, + 231,226,183,1,176,172,140,1,218,214,176,1,233,229,190,1,213,209,176,1, + 41,41,34,1,191,187,159,1,56,55,48,1,237,233,202,1,238,234,205,1, + 133,131,115,1,95,93,83,1,57,57,51,1,240,238,215,1,241,238,217,1, + 102,101,93,1,92,91,84,1,123,122,113,1,133,132,124,1,14,14,11,1, + 229,223,173,1,170,166,130,1,33,33,26,1,37,36,29,1,105,103,83,1, + 195,191,155,1,233,228,188,1,233,229,190,1,128,126,106,1,123,120,102,1, + 236,231,197,1,45,45,38,1,197,194,168,1,238,234,205,1,133,131,115,1, + 121,119,106,1,57,57,51,1,214,212,191,1,238,235,214,1,57,56,52,1, + 142,140,130,1,123,122,113,1,7,7,7,1,228,222,171,1,229,223,173,1, + 229,224,175,1,230,224,178,1,190,185,148,1,123,121,98,1,25,25,20,1, + 195,190,157,1,233,229,190,1,39,38,32,1,93,91,77,1,118,115,98,1, + 56,55,48,1,100,99,86,1,238,234,205,1,133,131,115,1,121,119,106,1, + 137,136,121,1,133,132,119,1,177,175,159,1,119,117,108,1,143,141,131,1, + 123,122,113,1,7,7,7,1,228,222,171,1,194,189,147,1,75,74,58,1, + 230,224,178,1,231,225,180,1,231,226,183,1,108,106,86,1,139,136,112,1, + 183,180,149,1,48,47,39,1,161,159,134,1,162,159,135,1,156,154,133,1, + 19,18,16,1,228,224,196,1,133,131,115,1,121,119,106,1,216,214,191,1, + 55,54,49,1,95,93,85,1,204,202,185,1,143,141,131,1,123,122,113,1, + 75,75,70,1,160,156,120,1,228,222,172,1,51,50,39,1,95,92,73,1, + 161,157,126,1,141,138,112,1,40,39,32,1,204,199,164,1,93,92,76,1, + 143,141,118,1,235,231,195,1,236,231,197,1,236,232,200,1,76,75,65,1, + 145,142,125,1,133,131,115,1,121,119,106,1,240,237,212,1,61,61,55,1, + 60,60,54,1,242,239,220,1,143,141,131,1,123,122,113,1,244,242,227,1, + 7,7,5,1,229,223,173,1,222,217,170,1,138,134,107,1,100,97,78,1, + 120,117,95,1,199,195,159,1,233,228,188,1,130,128,106,1,221,217,182,1, + 235,231,195,1,236,231,197,1,236,232,200,1,191,188,163,1,155,152,133,1, + 186,183,162,1,180,178,158,1,240,237,212,1,181,179,162,1,175,173,157,1, + 242,239,220,1,193,191,177,1,183,181,169,1,244,242,227,1,7,7,5,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,75,75,70,1,49,48,37,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1, + 201,196,156,1,108,105,84,1,108,105,85,1,108,106,86,1,109,106,88,1, + 150,147,122,1,231,227,191,1,110,108,91,1,110,108,92,1,110,108,93,1, + 111,109,94,1,127,125,109,1,187,184,162,1,112,110,98,1,112,111,99,1, + 112,111,100,1,112,111,101,1,113,112,103,1,199,197,182,1,243,241,224,1, + 7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,176,171,136,1, + 45,44,35,1,151,148,120,1,152,149,121,1,153,149,123,1,180,177,147,1, + 228,225,188,1,13,13,11,1,155,151,129,1,155,152,131,1,155,153,132,1, + 166,163,143,1,205,203,179,1,157,155,138,1,152,151,135,1,9,9,8,1, + 158,156,142,1,158,157,144,1,214,212,196,1,243,241,224,1,133,132,124,1, + 95,93,71,1,229,223,173,1,229,224,175,1,176,171,136,1,69,67,54,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,228,225,188,1, + 20,20,17,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 238,235,207,1,239,236,210,1,232,230,205,1,15,15,13,1,241,238,217,1, + 242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1, + 229,223,173,1,229,224,175,1,176,171,136,1,41,40,32,1,137,134,108,1, + 137,134,110,1,138,135,111,1,220,216,180,1,228,225,188,1,12,12,10,1, + 140,137,117,1,140,137,118,1,140,138,120,1,204,201,176,1,238,235,207,1, + 239,236,210,1,232,230,205,1,15,15,13,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1, + 229,224,175,1,176,171,136,1,39,38,30,1,130,127,103,1,130,127,104,1, + 131,128,105,1,219,216,179,1,228,225,188,1,11,11,9,1,132,130,110,1, + 132,130,112,1,133,131,113,1,202,198,174,1,238,235,207,1,239,236,210,1, + 232,230,205,1,15,15,13,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,28,28,26,1,103,100,77,1,229,223,173,1,229,224,175,1, + 176,171,136,1,69,67,54,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,228,225,188,1,20,20,17,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,232,230,205,1, + 15,15,13,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1, + 7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,176,171,136,1, + 69,67,54,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 228,225,188,1,20,20,17,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,232,230,205,1,15,15,13,1, + 241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1, + 228,222,171,1,229,223,173,1,229,224,175,1,189,184,147,1,110,107,85,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,230,226,190,1, + 74,72,61,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 238,235,207,1,239,236,210,1,234,231,207,1,72,71,64,1,241,238,217,1, + 242,239,220,1,243,240,222,1,243,241,224,1,231,229,215,1,44,43,33,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,205,204,191,1,4,3,3,1,171,167,129,1,229,224,175,1, + 230,224,178,1,11,11,9,1,7,7,6,1,23,22,18,1,233,228,188,1, + 233,229,190,1,145,143,120,1,7,7,6,2,61,60,52,1,237,233,202,1, + 238,234,205,1,86,85,75,1,7,7,6,2,115,114,103,1,241,238,217,1, + 242,239,220,1,38,37,34,1,7,7,7,1,4,4,4,1,152,1,0,0, + 244,244,244,1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1, + 248,248,248,2,203,203,203,1,128,128,128,2,188,188,188,1,248,248,248,2, + 173,173,173,1,128,128,128,2,221,221,221,1,248,248,248,2,139,139,139,1, + 128,128,128,1,131,131,131,1,244,244,244,1,154,154,154,1,255,255,255,22, + 248,248,248,1,128,128,128,1,255,255,255,22,229,229,229,1,128,128,128,1, + 255,255,255,22,128,128,128,1,236,236,236,1,255,255,255,22,128,128,128,1, + 248,248,248,1,255,255,255,22,165,165,165,1,240,240,240,1,255,255,255,22, + 248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1, + 255,255,255,22,195,195,195,1,150,150,150,1,255,255,255,22,128,128,128,1, + 248,248,248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22, + 195,195,195,1,210,210,210,1,255,255,255,22,248,248,248,1,128,128,128,1, + 255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,165,165,165,1, + 180,180,180,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22, + 128,128,128,1,248,248,248,1,255,255,255,22,229,229,229,1,176,176,176,1, + 255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1, + 128,128,128,1,255,255,255,22,131,131,131,1,214,214,214,1,255,255,255,22, + 128,128,128,1,248,248,248,1,255,255,255,22,139,139,139,1,244,244,244,1, + 146,146,146,1,128,128,128,2,244,244,244,1,248,248,248,1,233,233,233,1, + 128,128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2, + 188,188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221,1, + 248,248,248,1,244,244,244,1,0,0) + ); + +const + objdata_tsigfilter: record size: integer; data: array[0..2865] of byte end = + (size: 2866; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,115,105, + 103,102,105,108,116,101,114,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,188,10,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,236,8,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,4,3,3,1,7,7,5,1,22,22,17,1, + 230,224,178,1,231,225,180,1,143,140,113,1,7,7,6,2,61,60,49,1, + 234,230,193,1,235,231,195,1,85,83,71,1,7,7,6,2,114,112,98,1, + 238,235,207,1,239,236,210,1,37,37,33,1,7,7,7,2,204,201,185,1, + 243,240,222,1,230,228,212,1,4,4,4,1,151,147,113,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,219,217,193,1,161,159,142,1, + 226,224,202,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1, + 28,28,26,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,165,163,144,1,16,16,14,1,59,59,52,1,50,49,45,1, + 241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1, + 18,18,14,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1, + 235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,161,159,139,1, + 21,20,18,1,191,189,168,1,238,235,210,1,36,35,32,1,182,180,164,1, + 242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,124,122,105,1,25,25,22,1,189,187,165,1, + 239,236,210,1,240,237,212,1,147,146,132,1,75,74,67,1,242,239,220,1, + 243,240,222,1,243,241,224,1,133,132,124,1,14,14,11,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,228,224,189,1,159,156,133,1, + 65,64,55,1,52,51,44,1,215,211,185,1,238,235,207,1,239,236,210,1, + 240,237,212,1,228,226,204,1,13,13,12,1,240,237,218,1,243,240,222,1, + 243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,114,112,87,1, + 115,112,89,1,115,112,90,1,115,113,91,1,116,113,92,1,116,114,94,1, + 116,114,95,1,87,86,72,1,17,16,14,1,62,61,52,1,144,142,122,1, + 231,228,197,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 240,238,215,1,40,39,36,1,202,200,184,1,243,240,222,1,243,241,224,1, + 7,7,7,1,228,222,171,1,229,223,173,1,114,112,87,1,115,112,89,1, + 115,112,90,1,115,113,91,1,116,113,92,1,116,114,94,1,116,114,95,1, + 147,144,121,1,214,210,177,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1, + 90,89,81,1,152,150,138,1,243,240,222,1,243,241,224,1,75,75,70,1, + 160,156,120,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1, + 235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,140,138,126,1, + 102,100,92,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,188,186,169,1,52,52,47,1, + 243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,222,219,200,1,13,13,12,1,243,240,222,1, + 243,241,224,1,75,75,70,1,49,48,37,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 240,238,215,1,241,238,217,1,16,16,15,1,221,218,202,1,243,241,224,1, + 7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1, + 241,238,217,1,53,52,48,1,185,183,169,1,243,241,224,1,7,7,7,1, + 228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1, + 235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1, + 89,88,81,1,149,147,136,1,243,241,224,1,133,132,124,1,95,93,71,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,125,124,114,1, + 111,110,102,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,161,159,147,1,75,74,69,1, + 243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 240,238,215,1,241,238,217,1,198,196,180,1,39,39,36,1,243,241,224,1, + 28,28,26,1,103,100,77,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1, + 241,238,217,1,233,231,212,1,8,8,7,1,240,238,221,1,7,7,7,1, + 228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1, + 235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1, + 242,239,220,1,28,27,25,1,211,209,194,1,7,7,7,1,228,222,171,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 65,64,59,1,173,172,160,1,231,229,215,1,44,43,33,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,101,100,92,1, + 141,140,130,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 240,238,215,1,241,238,217,1,242,239,220,1,239,236,219,1,243,241,224,1, + 205,204,191,1,4,3,3,1,171,167,129,1,229,224,175,1,230,224,178,1, + 11,11,9,1,7,7,6,1,23,22,18,1,233,228,188,1,233,229,190,1, + 145,143,120,1,7,7,6,2,61,60,52,1,237,233,202,1,238,234,205,1, + 86,85,75,1,7,7,6,2,115,114,103,1,241,238,217,1,242,239,220,1, + 38,37,34,1,7,7,7,1,4,4,4,1,152,1,0,0,244,244,244,1, + 248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1,248,248,248,2, + 203,203,203,1,128,128,128,2,188,188,188,1,248,248,248,2,173,173,173,1, + 128,128,128,2,221,221,221,1,248,248,248,2,139,139,139,1,128,128,128,1, + 131,131,131,1,244,244,244,1,154,154,154,1,255,255,255,22,248,248,248,1, + 128,128,128,1,255,255,255,22,229,229,229,1,128,128,128,1,255,255,255,22, + 128,128,128,1,236,236,236,1,255,255,255,22,128,128,128,1,248,248,248,1, + 255,255,255,22,165,165,165,1,240,240,240,1,255,255,255,22,248,248,248,1, + 128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22, + 195,195,195,1,150,150,150,1,255,255,255,22,128,128,128,1,248,248,248,1, + 255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,195,195,195,1, + 210,210,210,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22, + 248,248,248,1,128,128,128,1,255,255,255,22,165,165,165,1,180,180,180,1, + 255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,128,128,128,1, + 248,248,248,1,255,255,255,22,229,229,229,1,176,176,176,1,255,255,255,22, + 248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1, + 255,255,255,22,131,131,131,1,214,214,214,1,255,255,255,22,128,128,128,1, + 248,248,248,1,255,255,255,22,139,139,139,1,244,244,244,1,146,146,146,1, + 128,128,128,2,244,244,244,1,248,248,248,1,233,233,233,1,128,128,128,2, + 158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2,188,188,188,1, + 248,248,248,2,173,173,173,1,128,128,128,2,221,221,221,1,248,248,248,1, + 244,244,244,1,0,0) + ); + +const + objdata_tsigfilterbank: record size: integer; data: array[0..2869] of byte end = + (size: 2870; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,115,105, + 103,102,105,108,116,101,114,98,97,110,107,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,188,10,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,236,8,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,4,3,3,1,7,7,5,1, + 22,22,17,1,230,224,178,1,231,225,180,1,143,140,113,1,7,7,6,2, + 61,60,49,1,234,230,193,1,235,231,195,1,85,83,71,1,7,7,6,2, + 114,112,98,1,238,235,207,1,239,236,210,1,37,37,33,1,7,7,7,2, + 204,201,185,1,243,240,222,1,230,228,212,1,4,4,4,1,151,147,113,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1, + 229,224,175,1,230,224,178,1,219,214,171,1,192,188,152,1,232,227,185,1, + 233,228,188,1,221,217,180,1,195,191,160,1,235,231,195,1,236,231,197,1, + 236,232,200,1,194,191,166,1,229,225,197,1,238,235,207,1,239,236,210,1, + 197,194,174,1,231,229,207,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,28,28,26,1,228,222,171,1,229,223,173,1,229,224,175,1, + 230,224,178,1,61,59,47,1,5,4,4,1,187,182,149,1,233,228,188,1, + 61,60,50,1,5,5,4,1,189,186,157,1,236,231,197,1,180,177,152,1, + 6,5,5,1,72,71,62,1,238,235,207,1,182,180,160,1,6,6,5,1, + 72,72,65,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1, + 244,242,227,1,18,18,14,1,229,223,173,1,229,224,175,1,216,210,167,1, + 11,11,8,1,105,103,83,1,105,102,83,1,218,214,176,1,11,11,9,1, + 106,105,88,1,106,104,88,1,236,231,197,1,107,106,91,1,105,103,90,1, + 15,15,13,1,221,218,192,1,109,107,96,1,106,105,94,1,15,15,13,1, + 224,221,202,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1, + 7,7,5,1,229,223,173,1,229,224,175,1,172,168,133,1,57,56,44,1, + 196,191,155,1,25,24,20,1,174,170,140,1,58,57,47,1,198,195,163,1, + 25,24,21,1,234,229,195,1,58,57,49,1,178,175,151,1,82,81,71,1, + 143,141,124,1,59,58,52,1,180,178,159,1,83,82,74,1,145,143,130,1, + 242,239,220,1,243,240,222,1,243,241,224,1,133,132,124,1,14,14,11,1, + 229,223,173,1,229,224,175,1,149,145,115,1,83,81,65,1,231,226,183,1, + 25,24,20,1,133,130,107,1,84,83,69,1,234,230,193,1,25,24,21,1, + 207,203,173,1,34,34,29,1,204,201,174,1,145,142,125,1,90,88,78,1, + 35,34,30,1,207,204,183,1,146,145,131,1,91,90,82,1,242,239,220,1, + 243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1, + 229,224,175,1,124,121,96,1,107,104,83,1,231,226,183,1,54,53,43,1, + 95,93,77,1,108,106,88,1,234,230,193,1,54,53,45,1,178,174,148,1, + 9,9,8,1,229,225,195,1,175,172,150,1,60,59,52,1,9,9,8,1, + 232,229,205,1,176,175,158,1,60,60,54,1,242,239,220,1,243,240,222,1, + 243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1, + 100,98,77,1,130,127,102,1,231,226,183,1,83,81,66,1,63,62,51,1, + 132,129,107,1,234,230,193,1,84,82,70,1,139,136,116,1,15,15,13,1, + 237,233,202,1,204,201,176,1,28,28,24,1,14,14,12,1,240,237,212,1, + 206,204,185,1,30,30,27,1,242,239,220,1,243,240,222,1,243,241,224,1, + 75,75,70,1,160,156,120,1,229,223,173,1,229,224,175,1,77,75,59,1, + 153,149,119,1,231,226,183,1,112,109,89,1,39,38,32,1,154,152,126,1, + 234,230,193,1,113,111,94,1,99,97,83,1,38,37,32,1,237,233,202,1, + 232,228,200,1,5,5,4,1,38,38,34,1,240,237,212,1,234,232,210,1, + 6,6,5,1,239,236,217,1,243,240,222,1,243,241,224,1,244,242,227,1, + 7,7,5,1,229,223,173,1,229,224,175,1,52,51,40,1,177,172,138,1, + 231,226,183,1,141,138,112,1,20,20,16,1,178,175,145,1,234,230,193,1, + 143,140,119,1,65,63,54,1,62,61,53,1,237,233,202,1,238,234,205,1, + 18,18,16,1,55,54,48,1,240,237,212,1,240,238,215,1,26,25,23,1, + 213,210,193,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1, + 229,223,173,1,229,224,175,1,28,27,22,1,200,195,156,1,231,226,183,1, + 170,166,136,1,7,7,6,1,202,198,165,1,234,230,193,1,172,169,143,1, + 36,36,30,1,86,85,73,1,237,233,202,1,238,234,205,1,34,34,30,1, + 65,64,58,1,240,237,212,1,240,238,215,1,56,55,50,1,181,179,165,1, + 243,240,222,1,243,241,224,1,75,75,70,1,49,48,37,1,229,223,173,1, + 228,223,174,1,5,5,4,1,224,218,174,1,231,226,183,1,201,197,160,1, + 1,1,0,1,226,222,184,1,234,230,193,1,205,201,170,1,13,13,11,1, + 111,109,94,1,237,233,202,1,238,234,205,1,45,45,39,1,69,68,61,1, + 240,237,212,1,240,238,215,1,89,88,80,1,148,146,135,1,243,240,222,1, + 243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,208,204,159,1, + 17,17,13,1,231,225,180,1,231,226,183,1,209,205,166,1,0,0,0,1, + 227,223,185,1,234,230,193,1,232,228,193,1,3,3,2,1,132,130,112,1, + 237,233,202,1,238,234,205,1,49,49,42,1,66,65,58,1,240,237,212,1, + 240,238,215,1,122,120,110,1,116,114,105,1,243,240,222,1,243,241,224,1, + 7,7,7,1,228,222,171,1,229,223,173,1,184,180,141,1,41,40,32,1, + 231,225,180,1,231,226,183,1,187,182,149,1,6,6,5,1,196,193,160,1, + 234,230,193,1,235,231,195,1,10,10,8,1,136,133,115,1,237,233,202,1, + 238,234,205,1,46,46,41,1,56,55,49,1,240,237,212,1,240,238,215,1, + 155,153,140,1,83,82,75,1,243,240,222,1,243,241,224,1,133,132,124,1, + 95,93,71,1,229,223,173,1,159,155,121,1,66,64,51,1,231,225,180,1, + 231,226,183,1,161,158,128,1,19,18,15,1,164,162,134,1,234,230,193,1, + 235,231,195,1,13,12,11,1,131,129,112,1,237,233,202,1,238,234,205,1, + 36,35,31,1,38,38,34,1,240,237,212,1,240,238,215,1,188,186,169,1, + 49,49,45,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1, + 229,223,173,1,135,132,103,1,90,88,70,1,231,225,180,1,231,226,183,1, + 136,134,109,1,38,37,31,1,132,129,107,1,234,230,193,1,235,231,195,1, + 8,8,7,1,119,117,101,1,237,233,202,1,238,234,205,1,19,18,17,1, + 14,14,13,1,240,237,212,1,240,238,215,1,221,218,199,1,16,16,15,1, + 243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1, + 106,104,81,1,118,115,91,1,231,225,180,1,231,226,183,1,107,105,86,1, + 79,77,64,1,74,73,60,1,234,230,193,1,225,221,187,1,4,4,3,1, + 74,73,63,1,237,233,202,1,228,224,196,1,7,6,6,1,37,37,33,1, + 197,194,174,1,240,238,215,1,241,238,217,1,38,37,35,1,199,197,182,1, + 243,241,224,1,28,28,26,1,103,100,77,1,229,223,173,1,57,55,43,1, + 167,163,129,1,231,225,180,1,231,226,183,1,57,56,46,1,158,155,127,1, + 15,14,12,1,228,225,188,1,177,174,147,1,50,49,41,1,15,15,13,1, + 231,228,197,1,179,176,154,1,53,53,46,1,108,106,95,1,125,124,111,1, + 240,238,215,1,241,238,217,1,109,108,99,1,127,125,116,1,243,241,224,1, + 7,7,7,1,228,222,171,1,225,220,170,1,13,12,10,1,218,213,169,1, + 231,225,180,1,227,222,180,1,13,12,10,1,221,216,178,1,58,57,47,1, + 170,167,140,1,123,121,102,1,108,106,90,1,58,57,49,1,172,169,147,1, + 125,123,108,1,109,108,95,1,179,177,157,1,54,53,47,1,240,238,215,1, + 241,238,217,1,181,179,165,1,54,54,50,1,243,241,224,1,7,7,7,1, + 228,222,171,1,154,150,116,1,56,54,43,1,230,224,178,1,231,225,180,1, + 155,152,123,1,56,55,45,1,233,228,188,1,126,124,103,1,100,98,82,1, + 41,40,34,1,176,172,147,1,128,126,108,1,101,99,86,1,41,40,35,1, + 177,175,154,1,235,232,207,1,17,17,15,1,221,219,198,1,241,238,217,1, + 238,235,217,1,17,17,16,1,224,222,206,1,231,229,215,1,44,43,33,1, + 58,57,44,1,164,161,126,1,230,224,178,1,231,225,180,1,59,58,47,1, + 166,163,133,1,233,228,188,1,196,192,159,1,31,30,25,1,51,50,42,1, + 236,231,197,1,198,195,168,1,31,30,26,1,51,50,44,1,238,235,207,1, + 239,236,210,1,81,80,71,1,162,161,145,1,241,238,217,1,242,239,220,1, + 82,81,75,1,164,163,151,1,244,242,227,1,7,7,5,1,216,211,164,1, + 229,224,175,1,230,224,178,1,231,225,180,1,218,214,173,1,232,227,185,1, + 233,228,188,1,233,229,190,1,225,221,185,1,221,217,184,1,236,231,197,1, + 236,232,200,1,228,224,194,1,224,220,193,1,238,235,207,1,239,236,210,1, + 231,228,204,1,240,238,215,1,241,238,217,1,242,239,220,1,233,231,213,1, + 243,241,224,1,205,204,191,1,4,3,3,1,171,167,129,1,229,224,175,1, + 230,224,178,1,11,11,9,1,7,7,6,1,23,22,18,1,233,228,188,1, + 233,229,190,1,145,143,120,1,7,7,6,2,61,60,52,1,237,233,202,1, + 238,234,205,1,86,85,75,1,7,7,6,2,115,114,103,1,241,238,217,1, + 242,239,220,1,38,37,34,1,7,7,7,1,4,4,4,1,152,1,0,0, + 244,244,244,1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1, + 248,248,248,2,203,203,203,1,128,128,128,2,188,188,188,1,248,248,248,2, + 173,173,173,1,128,128,128,2,221,221,221,1,248,248,248,2,139,139,139,1, + 128,128,128,1,131,131,131,1,244,244,244,1,154,154,154,1,255,255,255,22, + 248,248,248,1,128,128,128,1,255,255,255,22,229,229,229,1,128,128,128,1, + 255,255,255,22,128,128,128,1,236,236,236,1,255,255,255,22,128,128,128,1, + 248,248,248,1,255,255,255,22,165,165,165,1,240,240,240,1,255,255,255,22, + 248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1, + 255,255,255,22,195,195,195,1,150,150,150,1,255,255,255,22,128,128,128,1, + 248,248,248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22, + 195,195,195,1,210,210,210,1,255,255,255,22,248,248,248,1,128,128,128,1, + 255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,165,165,165,1, + 180,180,180,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22, + 128,128,128,1,248,248,248,1,255,255,255,22,229,229,229,1,176,176,176,1, + 255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1, + 128,128,128,1,255,255,255,22,131,131,131,1,214,214,214,1,255,255,255,22, + 128,128,128,1,248,248,248,1,255,255,255,22,139,139,139,1,244,244,244,1, + 146,146,146,1,128,128,128,2,244,244,244,1,248,248,248,1,233,233,233,1, + 128,128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2, + 188,188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221,1, + 248,248,248,1,244,244,244,1,0,0) + ); + +const + objdata_tsigkeyboard: record size: integer; data: array[0..2651] of byte end = + (size: 2652; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,115,105, + 103,107,101,121,98,111,97,114,100,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,228,9,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,20,8,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,4,3,3,1,7,7,5,1,22,22, + 17,1,230,224,178,1,231,225,180,1,143,140,113,1,7,7,6,2,61,60, + 49,1,234,230,193,1,235,231,195,1,85,83,71,1,7,7,6,2,114,112, + 98,1,238,235,207,1,239,236,210,1,37,37,33,1,7,7,7,2,204,201, + 185,1,243,240,222,1,230,228,212,1,4,4,4,1,151,147,113,1,229,223, + 173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227, + 185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231, + 197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236, + 210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240, + 222,1,243,241,224,1,7,7,7,1,228,222,171,1,172,167,130,1,176,174, + 146,1,242,239,216,1,181,179,162,1,120,119,108,1,118,117,101,1,182,180, + 165,1,243,241,222,1,182,181,167,1,180,178,157,1,245,242,225,1,183,181, + 170,1,122,121,113,1,121,119,108,1,184,183,172,1,246,245,232,1,184,183, + 174,1,183,181,169,1,247,246,235,1,248,246,237,1,186,184,178,1,182,181, + 168,1,28,28,26,1,228,222,171,1,114,111,86,1,120,118,106,1,254,254, + 254,1,127,127,127,1,0,0,0,1,13,13,12,1,127,127,127,1,254,254, + 254,1,63,63,63,1,60,59,55,1,254,254,254,1,127,127,127,1,0,0, + 0,2,127,127,127,1,254,254,254,1,127,127,127,1,122,122,116,1,254,254, + 254,2,127,127,127,1,121,120,112,1,244,242,227,1,18,18,14,1,114,111, + 86,1,120,118,106,1,254,254,254,1,127,127,127,1,0,0,0,1,27,26, + 24,1,127,127,127,1,254,254,254,1,63,63,63,1,60,59,55,1,254,254, + 254,1,127,127,127,1,0,0,0,2,127,127,127,1,254,254,254,1,127,127, + 127,1,122,122,116,1,254,254,254,2,127,127,127,1,121,120,112,1,244,242, + 227,1,7,7,5,1,114,111,86,1,120,118,106,1,254,254,254,1,127,127, + 127,1,0,0,0,1,27,26,24,1,127,127,127,1,254,254,254,1,63,63, + 63,1,60,59,55,1,254,254,254,1,127,127,127,1,0,0,0,2,127,127, + 127,1,254,254,254,1,127,127,127,1,122,122,116,1,254,254,254,2,127,127, + 127,1,121,120,112,1,133,132,124,1,14,14,11,1,114,111,86,1,120,118, + 106,1,254,254,254,1,127,127,127,1,0,0,0,1,27,26,24,1,127,127, + 127,1,254,254,254,1,63,63,63,1,60,59,55,1,254,254,254,1,127,127, + 127,1,0,0,0,2,127,127,127,1,254,254,254,1,127,127,127,1,122,122, + 116,1,254,254,254,2,127,127,127,1,121,120,112,1,7,7,7,1,228,222, + 171,1,114,111,86,1,120,118,106,1,254,254,254,1,127,127,127,1,0,0, + 0,1,27,26,24,1,127,127,127,1,254,254,254,1,63,63,63,1,60,59, + 55,1,254,254,254,1,127,127,127,1,0,0,0,2,127,127,127,1,254,254, + 254,1,127,127,127,1,122,122,116,1,254,254,254,2,127,127,127,1,121,120, + 112,1,7,7,7,1,228,222,171,1,114,111,86,1,120,118,106,1,254,254, + 254,1,127,127,127,1,0,0,0,1,27,26,24,1,127,127,127,1,254,254, + 254,1,63,63,63,1,60,59,55,1,254,254,254,1,127,127,127,1,0,0, + 0,2,127,127,127,1,254,254,254,1,127,127,127,1,122,122,116,1,254,254, + 254,2,127,127,127,1,121,120,112,1,75,75,70,1,160,156,120,1,114,111, + 86,1,120,118,106,1,254,254,254,1,127,127,127,1,0,0,0,1,27,26, + 24,1,127,127,127,1,254,254,254,1,63,63,63,1,60,59,55,1,254,254, + 254,1,127,127,127,1,0,0,0,2,127,127,127,1,254,254,254,1,127,127, + 127,1,122,122,116,1,254,254,254,2,127,127,127,1,121,120,112,1,244,242, + 227,1,7,7,5,1,114,111,86,1,120,118,106,1,254,254,254,1,127,127, + 127,1,0,0,0,1,27,26,24,1,127,127,127,1,254,254,254,1,63,63, + 63,1,60,59,55,1,254,254,254,1,127,127,127,1,0,0,0,2,127,127, + 127,1,254,254,254,1,127,127,127,1,122,122,116,1,254,254,254,2,127,127, + 127,1,121,120,112,1,244,242,227,1,7,7,5,1,114,111,86,1,120,118, + 106,1,254,254,254,1,127,127,127,1,0,0,0,1,27,26,24,1,127,127, + 127,1,254,254,254,1,63,63,63,1,60,59,55,1,254,254,254,1,127,127, + 127,1,0,0,0,2,127,127,127,1,254,254,254,1,127,127,127,1,122,122, + 116,1,254,254,254,2,127,127,127,1,121,120,112,1,75,75,70,1,49,48, + 37,1,114,111,86,1,120,118,106,1,254,254,254,1,127,127,127,1,0,0, + 0,1,13,13,12,1,127,127,127,1,254,254,254,1,63,63,63,1,60,59, + 55,1,254,254,254,1,127,127,127,1,0,0,0,2,127,127,127,1,254,254, + 254,1,127,127,127,1,122,122,116,1,254,254,254,2,127,127,127,1,121,120, + 112,1,7,7,7,1,228,222,171,1,114,111,86,1,120,118,106,1,254,254, + 254,1,190,190,190,1,63,63,63,1,59,59,53,1,190,190,190,1,254,254, + 254,1,63,63,63,1,60,59,55,1,254,254,254,1,190,190,190,1,47,47, + 47,1,44,44,41,1,190,190,190,1,254,254,254,1,127,127,127,1,122,122, + 116,1,254,254,254,2,127,127,127,1,121,120,112,1,7,7,7,1,228,222, + 171,1,114,111,86,1,120,118,106,1,254,254,254,2,127,127,127,1,120,119, + 109,1,254,254,254,2,63,63,63,1,60,59,55,1,254,254,254,2,127,127, + 127,1,122,121,114,1,254,254,254,2,127,127,127,1,122,122,116,1,254,254, + 254,2,127,127,127,1,121,120,112,1,133,132,124,1,95,93,71,1,114,111, + 86,1,120,118,106,1,254,254,254,2,127,127,127,1,120,119,109,1,254,254, + 254,2,63,63,63,1,60,59,55,1,254,254,254,2,127,127,127,1,122,121, + 114,1,254,254,254,2,127,127,127,1,122,122,116,1,254,254,254,2,127,127, + 127,1,121,120,112,1,244,242,227,1,7,7,5,1,114,111,86,1,120,118, + 106,1,254,254,254,2,127,127,127,1,120,119,109,1,254,254,254,2,63,63, + 63,1,60,59,55,1,254,254,254,2,127,127,127,1,122,121,114,1,254,254, + 254,2,127,127,127,1,122,122,116,1,254,254,254,2,127,127,127,1,121,120, + 112,1,244,242,227,1,7,7,5,1,114,111,86,1,120,118,106,1,254,254, + 254,2,127,127,127,1,120,119,109,1,254,254,254,2,63,63,63,1,60,59, + 55,1,254,254,254,2,127,127,127,1,122,121,114,1,254,254,254,2,127,127, + 127,1,122,122,116,1,254,254,254,2,127,127,127,1,121,120,112,1,28,28, + 26,1,103,100,77,1,114,111,86,1,120,118,106,1,254,254,254,2,127,127, + 127,1,120,119,109,1,254,254,254,2,63,63,63,1,60,59,55,1,254,254, + 254,2,127,127,127,1,122,121,114,1,254,254,254,2,127,127,127,1,122,122, + 116,1,254,254,254,2,127,127,127,1,121,120,112,1,7,7,7,1,228,222, + 171,1,114,111,86,1,120,118,106,1,254,254,254,2,127,127,127,1,120,119, + 109,1,254,254,254,2,63,63,63,1,60,59,55,1,254,254,254,2,127,127, + 127,1,122,121,114,1,254,254,254,2,127,127,127,1,122,122,116,1,254,254, + 254,2,127,127,127,1,121,120,112,1,7,7,7,1,228,222,171,1,114,111, + 86,1,58,57,48,1,120,118,107,1,120,119,107,1,59,58,53,1,59,58, + 50,1,121,119,109,1,121,120,110,1,29,29,26,2,121,120,112,2,60,59, + 56,1,60,59,54,1,122,121,114,1,122,121,115,1,60,60,57,1,60,60, + 56,1,123,122,117,2,61,60,58,1,121,120,112,1,231,229,215,1,44,43, + 33,1,172,167,130,1,114,112,87,1,115,112,89,1,115,112,90,1,115,113, + 91,1,86,85,69,1,116,114,94,1,116,114,95,1,87,86,72,1,88,86, + 73,1,118,115,98,1,118,116,100,1,118,116,101,1,89,87,76,1,119,117, + 103,1,119,118,105,1,120,118,106,1,89,89,80,1,120,119,108,1,121,119, + 110,1,121,120,111,1,182,181,168,1,244,242,227,1,7,7,5,1,229,223, + 173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227, + 185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231, + 197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236, + 210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240, + 222,1,243,241,224,1,205,204,191,1,4,3,3,1,171,167,129,1,229,224, + 175,1,230,224,178,1,11,11,9,1,7,7,6,1,23,22,18,1,233,228, + 188,1,233,229,190,1,145,143,120,1,7,7,6,2,61,60,52,1,237,233, + 202,1,238,234,205,1,86,85,75,1,7,7,6,2,115,114,103,1,241,238, + 217,1,242,239,220,1,38,37,34,1,7,7,7,1,4,4,4,1,152,1, + 0,0,244,244,244,1,248,248,248,1,233,233,233,1,128,128,128,2,158,158, + 158,1,248,248,248,2,203,203,203,1,128,128,128,2,188,188,188,1,248,248, + 248,2,173,173,173,1,128,128,128,2,221,221,221,1,248,248,248,2,139,139, + 139,1,128,128,128,1,131,131,131,1,244,244,244,1,154,154,154,1,255,255, + 255,22,248,248,248,1,128,128,128,1,255,255,255,22,229,229,229,1,128,128, + 128,1,255,255,255,22,128,128,128,1,236,236,236,1,255,255,255,22,128,128, + 128,1,248,248,248,1,255,255,255,22,165,165,165,1,240,240,240,1,255,255, + 255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128, + 128,1,255,255,255,22,195,195,195,1,150,150,150,1,255,255,255,22,128,128, + 128,1,248,248,248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255, + 255,22,195,195,195,1,210,210,210,1,255,255,255,22,248,248,248,1,128,128, + 128,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,165,165, + 165,1,180,180,180,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255, + 255,22,128,128,128,1,248,248,248,1,255,255,255,22,229,229,229,1,176,176, + 176,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248, + 248,1,128,128,128,1,255,255,255,22,131,131,131,1,214,214,214,1,255,255, + 255,22,128,128,128,1,248,248,248,1,255,255,255,22,139,139,139,1,244,244, + 244,1,146,146,146,1,128,128,128,2,244,244,244,1,248,248,248,1,233,233, + 233,1,128,128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128, + 128,2,188,188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221, + 221,1,248,248,248,1,244,244,244,1,0,0) + ); + +const + objdata_twavetableedit: record size: integer; data: array[0..2133] of byte end = + (size: 2134; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,119,97, + 118,101,116,97,98,108,101,101,100,105,116,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,220,7,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,152,7,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,0,0,0,22, + 255,255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1, + 241,238,217,1,242,239,220,1,243,240,222,1,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,232,227,185,1,106,104,86,1,90,88,73,1,234,230,193,1, + 235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1, + 227,224,206,1,58,57,53,1,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 230,225,184,1,21,21,17,1,18,18,15,1,211,207,174,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,148,146,135,1, + 90,88,82,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,177,174,141,1, + 45,44,36,1,112,110,92,1,115,113,95,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,64,63,58,1,174,172,159,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,105,102,83,1,118,115,95,1, + 208,205,170,1,25,24,20,1,229,226,190,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 240,238,215,1,218,216,197,1,22,22,20,1,239,236,219,1,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,32,31,25,1,192,188,155,1,233,229,190,1, + 79,78,65,1,149,147,124,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1, + 137,135,123,1,99,97,90,1,243,240,222,1,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,229,224,175,1,230,224,178,1,231,225,180,1, + 190,186,151,1,32,31,25,1,233,228,188,1,233,229,190,1,180,177,148,1, + 48,47,40,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,52,51,47,1, + 183,181,167,1,243,240,222,1,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,229,224,175,1,230,224,178,1,231,225,180,1,118,115,93,1, + 106,103,84,1,233,228,188,1,233,229,190,1,234,230,193,1,45,44,37,1, + 184,180,154,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,208,206,186,1,26,26,24,1,241,238,219,1, + 243,240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 229,224,175,1,230,224,178,1,231,225,180,1,44,43,35,1,178,174,142,1, + 233,228,188,1,233,229,190,1,234,230,193,1,147,144,122,1,82,81,69,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,125,124,112,1,108,106,97,1,242,239,220,1,243,240,222,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175,1, + 230,224,178,1,203,198,158,1,22,21,17,1,230,225,184,1,233,228,188,1, + 233,229,190,1,234,230,193,1,228,224,189,1,24,24,20,1,213,209,180,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 41,41,37,1,192,189,173,1,242,239,220,1,243,240,222,1,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,230,224,178,1, + 130,127,102,1,92,90,73,1,232,227,185,1,233,228,188,1,233,229,190,1, + 234,230,193,1,235,231,195,1,113,111,94,1,117,115,99,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,198,195,175,1,34,34,30,1, + 241,238,217,1,242,239,220,1,243,240,222,1,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,229,224,175,1,230,224,178,1,58,56,45,1, + 166,162,131,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1, + 235,231,195,1,210,206,175,1,25,25,21,1,231,228,197,1,238,234,205,1, + 238,235,207,1,239,236,210,1,114,112,101,1,117,116,105,1,241,238,217,1, + 242,239,220,1,243,240,222,1,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,229,224,175,1,213,207,165,1,15,15,12,1,226,221,179,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,79,77,67,1,151,149,129,1,238,234,205,1,238,235,207,1, + 239,236,210,1,31,31,27,1,200,199,180,1,241,238,217,1,242,239,220,1, + 243,240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 229,224,175,1,143,140,111,1,80,78,62,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 180,177,153,1,49,48,42,1,238,234,205,1,238,235,207,1,187,184,164,1, + 43,43,38,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175,1, + 70,69,54,1,153,149,119,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1, + 45,44,38,1,186,183,160,1,238,235,207,1,102,101,90,1,126,125,111,1, + 240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,224,224,224,1, + 255,255,255,1,128,128,128,1,0,0,0,1,220,215,168,1,14,14,11,1, + 219,214,171,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,147,144,125,1, + 84,83,72,1,235,232,205,1,22,22,20,1,209,206,185,1,240,238,215,1, + 241,238,217,1,242,239,220,1,243,240,222,1,224,224,224,1,255,255,255,1, + 128,128,128,1,0,0,0,1,155,152,119,1,67,65,52,1,231,225,180,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1, + 235,231,195,1,236,231,197,1,236,232,200,1,230,226,196,1,23,23,20,1, + 151,149,132,1,52,52,46,1,240,237,212,1,240,238,215,1,241,238,217,1, + 242,239,220,1,243,240,222,1,224,224,224,1,255,255,255,1,128,128,128,1, + 0,0,0,1,84,82,64,1,140,136,108,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,113,111,97,1,10,10,9,1, + 135,133,119,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1, + 84,82,64,1,210,205,163,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,211,207,182,1,53,53,46,1,216,213,189,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,224,224,224,1, + 255,255,255,1,128,128,128,1,224,224,224,22,255,255,255,25,12,0,0,0, + 255,255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tfuncttableedit: record size: integer; data: array[0..2118] of byte end = + (size: 2119; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,102,117, + 110,99,116,116,97,98,108,101,101,100,105,116,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,204,7,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,136,7,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,0,0,0, + 22,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,229,224,175,1,230,224,178,1,231,225,180, + 1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193, + 1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205, + 1,238,235,207,1,203,201,179,1,45,45,40,1,14,14,13,3,243,240,222, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,69,68,61,1,157,155,139, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202, + 1,238,234,205,1,169,167,147,1,56,56,49,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,229,224,175,1,230,224,178,1,231,225,180, + 1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193, + 1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,233,229,201, + 1,37,37,32,1,193,191,170,1,240,237,212,1,240,238,215,1,241,238,217, + 1,242,239,220,1,243,240,222,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183, + 1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195, + 1,236,231,197,1,236,232,200,1,237,233,202,1,130,128,112,1,95,94,83, + 1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220, + 1,243,240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185, + 1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197, + 1,236,232,200,1,216,212,184,1,28,28,24,1,218,216,190,1,239,236,210, + 1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,90,89,77,1,134,132,116,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,234,230,193,1,235,231,195,1,236,231,197,1,187,184,158,1,40,39,34, + 1,234,230,202,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,229,224,175,1,230,224,178,1,231,225,180, + 1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193, + 1,235,231,195,1,235,230,196,1,52,51,44,1,173,170,147,1,238,234,205, + 1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217, + 1,242,239,220,1,243,240,222,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183, + 1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195, + 1,150,147,125,1,73,72,62,1,237,233,202,1,238,234,205,1,238,235,207, + 1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220, + 1,243,240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185, + 1,233,228,188,1,233,229,190,1,234,230,193,1,224,220,186,1,31,30,25, + 1,204,200,173,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210, + 1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188, + 1,233,229,190,1,234,230,193,1,111,109,92,1,112,110,93,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,230,224,178, + 1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190, + 1,202,198,167,1,30,30,25,1,225,220,188,1,236,232,200,1,237,233,202, + 1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215, + 1,241,238,217,1,242,239,220,1,243,240,222,1,224,224,224,1,255,255,255, + 1,128,128,128,1,0,0,0,1,229,224,175,1,230,224,178,1,231,225,180, + 1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,72,70,59, + 1,150,148,125,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205, + 1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217, + 1,242,239,220,1,243,240,222,1,224,224,224,1,255,255,255,1,128,128,128, + 1,0,0,0,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183, + 1,232,227,185,1,233,228,188,1,169,166,138,1,52,51,43,1,234,230,194, + 1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207, + 1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220, + 1,243,240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185, + 1,229,224,185,1,39,39,32,1,186,183,154,1,235,231,195,1,236,231,197, + 1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210, + 1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175, + 1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,131,128,105, + 1,90,88,73,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200, + 1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212, + 1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,224,224,224, + 1,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,14,13,10, + 1,14,13,11,3,50,49,41,1,212,208,173,1,234,230,193,1,235,231,195, + 1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207, + 1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220, + 1,243,240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0, + 1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185, + 1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197, + 1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210, + 1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222, + 1,224,224,224,1,255,255,255,1,128,128,128,1,224,224,224,22,255,255,255, + 25,12,0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tffttableedit: record size: integer; data: array[0..2132] of byte end = + (size: 2133; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,102,102, + 116,116,97,98,108,101,101,100,105,116,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,220,7,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,152,7,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,0,0,0,22,255, + 255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,230,224,178,1,231, + 225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234, + 230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241, + 238,217,1,242,239,220,1,243,240,222,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,229,224,175,1,230,224,178,1,231,225,180,1,231, + 226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235, + 231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242, + 239,220,1,243,240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,229,224,175,1,0,0,0,1,231,225,180,1,231,226,183,1,232, + 227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236, + 231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239, + 236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243, + 240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229, + 224,175,1,0,0,0,1,231,225,180,1,231,226,183,1,232,227,185,1,233, + 228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240, + 237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,0, + 0,0,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233, + 229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240, + 238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,0,0,0,1,231, + 225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234, + 230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241, + 238,217,1,242,239,220,1,243,240,222,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,229,224,175,1,0,0,0,1,231,225,180,1,231, + 226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235, + 231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242, + 239,220,1,243,240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,229,224,175,1,0,0,0,1,231,225,180,1,231,226,183,1,232, + 227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236, + 231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239, + 236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243, + 240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229, + 224,175,1,0,0,0,1,231,225,180,1,0,0,0,1,232,227,185,1,233, + 228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240, + 237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,0, + 0,0,1,231,225,180,1,0,0,0,1,232,227,185,1,233,228,188,1,233, + 229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240, + 238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,0,0,0,1,231, + 225,180,1,0,0,0,1,232,227,185,1,233,228,188,1,233,229,190,1,117, + 115,96,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241, + 238,217,1,242,239,220,1,243,240,222,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,229,224,175,1,0,0,0,1,231,225,180,1,0, + 0,0,1,232,227,185,1,233,228,188,1,233,229,190,1,0,0,0,1,235, + 231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242, + 239,220,1,243,240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,229,224,175,1,0,0,0,1,231,225,180,1,0,0,0,1,232, + 227,185,1,233,228,188,1,233,229,190,1,0,0,0,1,235,231,195,1,236, + 231,197,1,236,232,200,1,118,116,101,1,238,234,205,1,238,235,207,1,239, + 236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243, + 240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229, + 224,175,1,0,0,0,1,231,225,180,1,0,0,0,1,232,227,185,1,233, + 228,188,1,233,229,190,1,0,0,0,1,235,231,195,1,236,231,197,1,236, + 232,200,1,0,0,0,1,238,234,205,1,238,235,207,1,239,236,210,1,240, + 237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,0, + 0,0,1,231,225,180,1,0,0,0,1,232,227,185,1,233,228,188,1,233, + 229,190,1,0,0,0,1,235,231,195,1,236,231,197,1,236,232,200,1,0, + 0,0,1,238,234,205,1,238,235,207,1,239,236,210,1,120,118,106,1,240, + 238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,0,0,0,1,231, + 225,180,1,0,0,0,1,232,227,185,1,0,0,0,1,233,229,190,1,0, + 0,0,1,235,231,195,1,118,115,98,1,236,232,200,1,0,0,0,1,238, + 234,205,1,238,235,207,1,239,236,210,1,0,0,0,1,240,238,215,1,241, + 238,217,1,242,239,220,1,243,240,222,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,229,224,175,1,0,0,0,1,231,225,180,1,0, + 0,0,1,232,227,185,1,0,0,0,1,233,229,190,1,0,0,0,1,235, + 231,195,1,0,0,0,1,236,232,200,1,0,0,0,1,238,234,205,1,238, + 235,207,1,239,236,210,1,0,0,0,1,240,238,215,1,241,238,217,1,242, + 239,220,1,243,240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,229,224,175,1,0,0,0,1,231,225,180,1,0,0,0,1,232, + 227,185,1,0,0,0,1,233,229,190,1,0,0,0,1,235,231,195,1,0, + 0,0,1,236,232,200,1,0,0,0,1,238,234,205,1,119,117,103,1,239, + 236,210,1,0,0,0,1,240,238,215,1,241,238,217,1,242,239,220,1,243, + 240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229, + 224,175,1,0,0,0,1,231,225,180,1,0,0,0,1,232,227,185,1,0, + 0,0,1,233,229,190,1,0,0,0,1,235,231,195,1,0,0,0,1,236, + 232,200,1,0,0,0,1,238,234,205,1,0,0,0,1,239,236,210,1,0, + 0,0,1,240,238,215,1,120,119,108,1,242,239,220,1,243,240,222,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,0, + 0,0,1,231,225,180,1,0,0,0,1,232,227,185,1,0,0,0,1,233, + 229,190,1,0,0,0,1,235,231,195,1,0,0,0,1,236,232,200,1,0, + 0,0,1,238,234,205,1,0,0,0,1,239,236,210,1,0,0,0,1,240, + 238,215,1,0,0,0,1,242,239,220,1,243,240,222,1,224,224,224,1,255, + 255,255,1,128,128,128,1,224,224,224,22,255,255,255,25,12,0,0,0,255, + 255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tenvelopeedit: record size: integer; data: array[0..2132] of byte end = + (size: 2133; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,101,110, + 118,101,108,111,112,101,101,100,105,116,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,220,7,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,152,7,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,0,0,0,22,255, + 255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,230,224,178,1,230, + 224,179,1,218,214,173,1,232,227,185,1,233,228,188,1,233,229,190,1,234, + 230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241, + 238,217,1,242,239,220,1,243,240,222,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,229,224,175,1,230,224,178,1,162,158,126,1,16, + 16,13,1,220,215,176,1,233,228,188,1,233,229,190,1,234,230,193,1,235, + 231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242, + 239,220,1,243,240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,229,224,175,1,230,224,178,1,140,136,109,1,6,6,5,1,122, + 119,97,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236, + 231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239, + 236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243, + 240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229, + 224,175,1,230,224,178,1,118,115,92,1,103,101,82,1,25,24,20,1,222, + 217,179,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240, + 237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,230, + 224,178,1,95,93,74,1,149,145,118,1,98,96,78,1,124,122,100,1,233, + 229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240, + 238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,230,224,178,1,73, + 71,57,1,170,167,135,1,207,202,165,1,25,24,20,1,223,219,182,1,234, + 230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241, + 238,217,1,242,239,220,1,243,240,222,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,229,224,175,1,230,224,178,1,51,49,40,1,193, + 189,153,1,232,227,185,1,94,92,76,1,126,124,103,1,234,230,193,1,235, + 231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242, + 239,220,1,243,240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,229,224,175,1,230,224,178,1,29,28,23,1,215,210,170,1,232, + 227,185,1,205,200,165,1,25,24,20,1,124,122,102,1,124,122,103,1,125, + 122,104,1,125,123,106,1,125,123,107,1,126,124,109,1,126,124,110,1,127, + 125,111,1,127,125,112,1,127,126,114,1,241,238,217,1,242,239,220,1,243, + 240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229, + 224,175,1,230,224,178,1,14,13,11,1,231,226,183,1,232,227,185,1,233, + 228,188,1,183,180,149,1,124,122,102,1,124,122,103,1,125,122,104,1,125, + 123,106,1,125,123,107,1,126,124,109,1,126,124,110,1,127,125,111,1,127, + 125,112,1,75,75,67,1,123,121,111,1,242,239,220,1,243,240,222,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,216, + 210,167,1,27,26,21,1,231,226,183,1,232,227,185,1,233,228,188,1,233, + 229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,174, + 173,156,1,83,82,75,1,242,239,220,1,243,240,222,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,194,189,150,1,50, + 49,39,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234, + 230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,213,211,191,1,43, + 43,39,1,242,239,220,1,243,240,222,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,229,224,175,1,171,167,133,1,72,70,56,1,231, + 226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235, + 231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,239,237,214,1,19,19,17,1,240, + 237,218,1,243,240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,229,224,175,1,150,146,116,1,94,92,73,1,231,226,183,1,232, + 227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236, + 231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239, + 236,210,1,240,237,212,1,240,238,215,1,48,48,43,1,208,205,189,1,243, + 240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229, + 224,175,1,127,124,98,1,116,113,90,1,231,226,183,1,232,227,185,1,233, + 228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240, + 237,212,1,240,238,215,1,87,86,78,1,169,167,154,1,243,240,222,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,106, + 103,82,1,139,135,108,1,231,226,183,1,232,227,185,1,233,228,188,1,233, + 229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240, + 238,215,1,126,124,113,1,129,127,117,1,243,240,222,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,83,81,64,1,160, + 156,125,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234, + 230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,164, + 162,148,1,89,88,81,1,243,240,222,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,229,224,175,1,61,60,47,1,183,178,143,1,231, + 226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235, + 231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,203,201,183,1,50, + 50,46,1,243,240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,229,224,175,1,39,38,30,1,205,199,160,1,231,226,183,1,232, + 227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236, + 231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239, + 236,210,1,240,237,212,1,240,238,215,1,236,233,213,1,16,16,15,1,243, + 240,222,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229, + 224,175,1,20,19,15,1,226,220,176,1,231,226,183,1,232,227,185,1,233, + 228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240, + 237,212,1,240,238,215,1,241,238,217,1,40,39,36,1,217,215,198,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,229,224,175,1,229, + 223,177,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233, + 229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240, + 238,215,1,241,238,217,1,239,236,217,1,243,240,222,1,224,224,224,1,255, + 255,255,1,128,128,128,1,224,224,224,22,255,255,255,25,12,0,0,0,255, + 255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tsigscope: record size: integer; data: array[0..2980] of byte end = + (size: 2981; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,115,105, + 103,115,99,111,112,101,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,48,11,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,96,5,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,128,128,128,25,254,228,0,2,208,208,208,1,255, + 225,0,1,254,228,0,2,208,208,208,1,255,223,0,1,254,228,0,1,208, + 208,208,2,255,223,0,1,254,228,0,1,208,208,208,2,255,223,0,1,254, + 228,0,1,208,208,208,3,254,228,0,1,208,208,208,1,255,255,255,1,128, + 128,128,1,254,228,0,5,253,227,0,1,24,22,0,1,141,126,0,1,247, + 222,0,1,254,228,0,9,85,76,0,1,216,194,0,1,252,226,0,1,254, + 228,0,1,255,254,247,1,128,128,128,1,254,228,0,1,208,208,208,2,255, + 223,0,1,254,228,0,1,0,0,0,2,3,2,0,1,74,67,0,1,208, + 208,208,2,255,223,0,1,254,228,0,1,208,208,208,2,255,223,0,1,254, + 228,0,1,0,0,0,3,119,106,0,1,208,208,208,1,255,255,255,1,128, + 128,128,1,208,208,208,4,0,0,0,6,208,208,208,6,0,0,0,6,255, + 255,255,1,128,128,128,1,254,228,0,2,208,208,208,1,255,225,0,1,171, + 153,0,1,3,3,0,1,208,208,208,1,255,223,0,1,82,74,0,1,0, + 0,0,1,208,208,208,1,255,223,0,1,254,228,0,1,208,208,208,2,255, + 223,0,1,99,89,0,1,0,0,0,1,208,208,208,2,43,38,0,1,0, + 0,0,1,255,255,255,1,128,128,128,1,254,228,0,4,120,107,0,1,128, + 115,0,1,254,228,0,2,132,119,0,1,117,105,0,1,254,228,0,6,48, + 43,0,1,199,179,0,1,254,228,0,2,98,88,0,1,150,135,0,1,255, + 254,247,1,128,128,128,1,254,228,0,1,208,208,208,2,255,223,0,1,65, + 59,0,1,0,0,0,1,208,208,208,1,255,223,0,1,162,145,0,1,0, + 0,0,1,208,208,208,1,255,223,0,1,254,228,0,1,208,208,208,2,204, + 178,0,1,9,8,0,1,0,0,0,1,208,208,208,2,134,121,0,1,0, + 0,0,1,255,255,255,1,128,128,128,1,208,208,208,3,0,0,0,3,208, + 208,208,2,0,0,0,2,208,208,208,5,0,0,0,2,208,208,208,3,0, + 0,0,2,255,255,255,1,128,128,128,1,254,228,0,1,255,223,0,1,208, + 208,208,1,67,59,0,1,33,30,0,1,255,223,0,1,208,208,208,1,255, + 223,0,1,225,202,0,1,0,0,0,1,208,208,208,1,255,223,0,1,254, + 228,0,1,208,208,208,2,18,16,0,1,67,60,0,1,208,208,208,3,166, + 149,0,1,0,0,0,1,255,255,255,1,128,128,128,1,254,228,0,2,208, + 208,208,1,163,146,0,1,87,78,0,1,254,228,0,1,208,208,208,1,254, + 228,0,1,252,226,0,1,8,7,0,1,0,0,0,1,254,228,0,3,208, + 208,208,1,138,124,0,1,111,99,0,1,254,228,0,1,208,208,208,1,254, + 228,0,1,182,164,0,1,71,63,0,1,255,255,255,1,128,128,128,1,254, + 228,0,1,255,255,0,1,208,208,208,1,6,6,0,1,136,122,0,1,208, + 208,208,2,255,223,0,1,254,228,0,1,0,0,0,2,255,223,0,1,254, + 228,0,1,208,208,208,2,5,5,0,1,147,132,0,1,208,208,208,3,197, + 177,0,1,1,1,0,1,255,255,255,1,128,128,128,1,208,208,208,3,0, + 0,0,2,208,208,208,4,0,0,0,2,208,208,208,4,0,0,0,2,208, + 208,208,3,0,0,0,2,255,255,255,1,128,128,128,1,254,228,0,1,255, + 223,0,1,208,208,208,1,1,1,0,1,236,212,0,1,255,223,0,1,208, + 208,208,2,254,228,0,1,0,0,0,2,208,208,208,1,254,228,0,1,208, + 208,208,2,0,0,0,1,208,187,0,1,208,208,208,3,228,205,0,1,1, + 1,0,1,255,255,255,1,128,128,128,1,254,228,0,2,0,0,0,1,30, + 27,0,1,254,228,0,2,208,208,208,1,254,228,0,2,162,146,0,1,0, + 0,0,1,254,228,0,3,208,208,208,1,13,12,0,1,237,213,0,1,254, + 228,0,1,208,208,208,1,254,228,0,1,253,227,0,1,240,215,0,1,255, + 255,255,1,128,128,128,1,254,228,0,1,255,223,0,1,0,0,0,2,254, + 228,0,1,208,208,208,3,254,228,0,1,0,0,0,2,208,208,208,1,254, + 228,0,1,208,208,208,1,0,0,0,2,254,228,0,1,208,208,208,3,254, + 228,0,1,255,223,0,1,255,255,255,1,128,128,128,1,208,208,208,2,0, + 0,0,2,208,208,208,5,0,0,0,3,208,208,208,2,0,0,0,2,208, + 208,208,6,255,255,255,1,128,128,128,1,254,228,0,1,214,187,0,1,0, + 0,0,1,32,28,0,1,254,228,0,1,255,223,0,1,208,208,208,2,254, + 228,0,1,208,208,208,1,0,0,0,2,254,228,0,1,208,208,208,1,0, + 0,0,2,254,228,0,1,208,208,208,3,254,228,0,1,255,223,0,1,255, + 255,255,1,128,128,128,1,254,228,0,1,169,151,0,1,0,0,0,1,254, + 228,0,3,208,208,208,1,254,228,0,3,0,0,0,1,99,89,0,1,254, + 228,0,2,0,0,0,1,163,147,0,1,254,228,0,2,208,208,208,1,254, + 228,0,3,255,255,255,1,128,128,128,1,193,173,0,1,1,1,0,1,0, + 0,0,1,208,208,208,1,254,228,0,1,208,208,208,3,254,228,0,1,208, + 208,208,1,0,0,0,2,165,148,0,1,0,0,0,3,254,228,0,1,208, + 208,208,3,254,228,0,1,255,223,0,1,255,255,255,1,128,128,128,1,0, + 0,0,2,208,208,208,9,0,0,0,4,208,208,208,7,255,255,255,1,128, + 128,128,1,254,228,0,1,255,223,0,1,208,208,208,1,255,223,0,1,254, + 228,0,1,255,223,0,1,208,208,208,2,254,228,0,1,208,208,208,3,254, + 228,0,1,0,0,0,1,208,208,208,2,254,228,0,1,208,208,208,3,254, + 228,0,1,255,223,0,1,255,255,255,1,128,128,128,1,254,228,0,2,208, + 208,208,1,254,228,0,3,208,208,208,1,254,228,0,3,208,208,208,1,254, + 228,0,3,208,208,208,1,254,228,0,3,208,208,208,1,254,228,0,3,255, + 255,255,25,152,5,0,0,255,255,255,26,8,8,8,1,0,0,0,1,15, + 15,15,1,248,248,248,1,8,8,8,1,0,0,0,1,8,8,8,1,248, + 248,248,1,0,0,0,2,8,8,8,1,248,248,248,1,0,0,0,2,8, + 8,8,1,248,248,248,1,0,0,0,3,255,255,255,1,0,0,0,1,255, + 255,255,3,248,248,248,1,7,7,7,1,240,240,240,1,255,255,255,1,248, + 248,248,1,59,59,59,1,251,251,251,1,255,255,255,2,8,8,8,1,248, + 248,248,1,255,255,255,2,8,8,8,1,248,248,248,1,255,255,255,2,23, + 23,23,1,249,249,249,1,255,255,255,5,0,0,0,2,8,8,8,1,248, + 248,248,1,115,115,115,1,226,226,226,1,194,194,194,1,253,253,253,1,0, + 0,0,2,8,8,8,1,248,248,248,1,0,0,0,2,8,8,8,1,248, + 248,248,1,121,121,121,1,237,237,237,1,221,221,221,1,255,255,255,1,0, + 0,0,1,255,255,255,2,0,0,0,4,16,16,16,1,234,234,234,1,42, + 42,42,1,3,3,3,1,237,237,237,1,22,22,22,1,0,0,0,6,36, + 36,36,1,234,234,234,1,28,28,28,1,22,22,22,1,240,240,240,1,3, + 3,3,1,255,255,255,3,8,8,8,1,0,0,0,1,15,15,15,1,250, + 250,250,1,181,181,181,1,0,0,0,1,8,8,8,1,253,253,253,1,90, + 90,90,1,0,0,0,1,8,8,8,1,248,248,248,1,0,0,0,2,8, + 8,8,1,252,252,252,1,122,122,122,1,0,0,0,2,255,255,255,1,48, + 48,48,1,255,255,255,3,248,248,248,1,7,7,7,1,240,240,240,1,255, + 255,255,1,251,251,251,1,7,7,7,1,248,248,248,1,255,255,255,2,8, + 8,8,1,248,248,248,1,255,255,255,2,8,8,8,1,248,248,248,1,255, + 255,255,2,8,8,8,1,248,248,248,1,255,255,255,5,0,0,0,2,8, + 8,8,1,253,253,253,1,72,72,72,1,0,0,0,1,8,8,8,1,250, + 250,250,1,168,168,168,1,0,0,0,1,8,8,8,1,248,248,248,1,0, + 0,0,2,10,10,10,1,255,255,255,1,14,14,14,1,0,0,0,2,255, + 255,255,1,136,136,136,1,255,255,255,2,0,0,0,3,1,1,1,1,239, + 239,239,1,19,19,19,1,0,0,0,2,59,59,59,1,198,198,198,1,0, + 0,0,5,34,34,34,1,227,227,227,1,0,0,0,3,104,104,104,1,152, + 152,152,1,255,255,255,3,8,8,8,1,0,0,0,1,52,52,52,1,254, + 254,254,1,8,8,8,1,0,0,0,1,8,8,8,1,249,249,249,1,227, + 227,227,1,0,0,0,1,8,8,8,1,248,248,248,1,0,0,0,2,81, + 81,81,1,253,253,253,1,0,0,0,3,255,255,255,1,168,168,168,1,255, + 255,255,3,248,248,248,1,0,0,0,1,250,250,250,1,255,255,255,1,248, + 248,248,1,0,0,0,1,255,255,255,3,4,4,4,1,255,255,255,3,0, + 0,0,1,255,255,255,3,0,0,0,1,255,255,255,5,254,254,254,1,2, + 2,2,1,0,0,0,1,144,144,144,1,251,251,251,1,0,0,0,2,8, + 8,8,1,248,248,248,1,222,222,222,1,31,31,31,1,8,8,8,1,248, + 248,248,1,0,0,0,2,156,156,156,1,251,251,251,1,0,0,0,3,254, + 254,254,1,199,199,199,1,255,255,255,2,0,0,0,3,189,189,189,1,68, + 68,68,1,0,0,0,4,187,187,187,1,67,67,67,1,0,0,0,4,183, + 183,183,1,76,76,76,1,0,0,0,3,41,41,41,1,215,215,215,1,255, + 255,255,2,248,248,248,1,16,16,16,1,0,0,0,1,238,238,238,1,255, + 255,255,1,8,8,8,1,0,0,0,2,255,255,255,1,140,140,140,1,116, + 116,116,1,0,0,0,1,255,255,255,1,0,0,0,2,212,212,212,1,255, + 255,255,1,0,0,0,3,249,249,249,1,232,232,232,1,255,255,255,3,248, + 248,248,1,31,31,31,1,254,254,254,1,255,255,255,1,248,248,248,1,0, + 0,0,1,255,255,255,3,167,167,167,1,255,255,255,3,0,0,0,1,255, + 255,255,3,0,0,0,1,255,255,255,5,248,248,248,1,8,8,8,1,80, + 80,80,1,175,175,175,1,255,255,255,1,0,0,0,3,255,255,255,1,44, + 44,44,1,217,217,217,1,0,0,0,1,255,255,255,1,0,0,0,1,16, + 16,16,1,243,243,243,1,255,255,255,1,0,0,0,3,248,248,248,1,8, + 8,8,1,255,255,255,2,0,0,0,2,133,133,133,1,125,125,125,1,0, + 0,0,5,4,4,4,1,246,246,246,1,13,13,13,1,0,0,0,2,46, + 46,46,1,213,213,213,1,0,0,0,6,255,255,255,2,248,248,248,1,19, + 19,19,1,225,225,225,1,53,53,53,1,255,255,255,1,8,8,8,1,0, + 0,0,2,255,255,255,1,0,0,0,1,205,205,205,1,61,61,61,1,255, + 255,255,1,0,0,0,1,95,95,95,1,168,168,168,1,255,255,255,1,0, + 0,0,3,248,248,248,1,8,8,8,1,255,255,255,3,250,250,250,1,194, + 194,194,1,248,248,248,1,255,255,255,1,248,248,248,1,0,0,0,1,255, + 255,255,3,136,136,136,1,255,255,255,3,172,172,172,1,255,255,255,3,0, + 0,0,1,255,255,255,5,250,250,250,1,235,235,235,1,68,68,68,1,0, + 0,0,1,255,255,255,1,0,0,0,3,255,255,255,1,0,0,0,1,16, + 16,16,1,232,232,232,1,255,255,255,1,79,79,79,1,235,235,235,1,17, + 17,17,1,255,255,255,1,0,0,0,3,248,248,248,1,8,8,8,1,255, + 255,255,2,117,117,117,1,72,72,72,1,0,0,0,9,71,71,71,1,183, + 183,183,1,238,238,238,1,61,61,61,1,0,0,0,7,255,255,255,2,248, + 248,248,1,16,16,16,1,0,0,0,1,8,8,8,1,255,255,255,1,8, + 8,8,1,0,0,0,2,255,255,255,1,0,0,0,3,255,255,255,1,2, + 2,2,1,0,0,0,2,255,255,255,1,0,0,0,3,248,248,248,1,8, + 8,8,1,255,255,255,3,248,248,248,1,0,0,0,1,248,248,248,1,255, + 255,255,1,248,248,248,1,0,0,0,1,255,255,255,3,0,0,0,1,255, + 255,255,3,0,0,0,1,255,255,255,3,0,0,0,1,255,255,255,28,0, + 0) + ); + +const + objdata_tsigscopefft: record size: integer; data: array[0..2803] of byte end = + (size: 2804; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,115,105, + 103,115,99,111,112,101,102,102,116,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,124,10,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,224,4,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,128,128,128,25,254,228,0,2,208,208, + 208,1,255,225,0,1,254,228,0,2,208,208,208,1,255,223,0,1,254,228, + 0,1,208,208,208,2,255,223,0,1,254,228,0,1,208,208,208,2,255,223, + 0,1,254,228,0,1,208,208,208,3,254,228,0,1,208,208,208,1,255,255, + 255,1,128,128,128,1,254,228,0,22,255,254,247,1,128,128,128,1,254,228, + 0,1,208,208,208,1,0,0,0,1,255,223,0,1,254,228,0,1,208,208, + 208,2,255,223,0,1,254,228,0,1,208,208,208,2,255,223,0,1,254,228, + 0,1,208,208,208,2,255,223,0,1,254,228,0,1,208,208,208,3,254,228, + 0,1,208,208,208,1,255,255,255,1,128,128,128,1,208,208,208,2,0,0, + 0,2,208,208,208,18,255,255,255,1,128,128,128,1,254,228,0,2,0,0, + 0,1,164,145,0,1,254,228,0,2,208,208,208,1,255,223,0,1,254,228, + 0,1,208,208,208,2,255,223,0,1,254,228,0,1,208,208,208,2,255,223, + 0,1,254,228,0,1,208,208,208,3,254,228,0,1,208,208,208,1,255,255, + 255,1,128,128,128,1,254,228,0,2,0,0,0,1,246,220,0,1,254,228, + 0,18,255,254,247,1,128,128,128,1,254,228,0,1,208,208,208,1,0,0, + 0,1,125,110,0,1,254,228,0,1,208,208,208,2,255,223,0,1,254,228, + 0,1,208,208,208,2,255,223,0,1,254,228,0,1,208,208,208,2,255,223, + 0,1,254,228,0,1,208,208,208,3,254,228,0,1,208,208,208,1,255,255, + 255,1,128,128,128,1,208,208,208,2,0,0,0,2,208,208,208,18,255,255, + 255,1,128,128,128,1,254,228,0,1,255,223,0,1,0,0,0,1,168,147, + 0,1,247,222,0,1,255,223,0,1,208,208,208,1,255,223,0,1,254,228, + 0,1,208,208,208,2,255,223,0,1,254,228,0,1,208,208,208,2,255,223, + 0,1,254,228,0,1,208,208,208,3,254,228,0,1,208,208,208,1,255,255, + 255,1,128,128,128,1,254,228,0,2,0,0,0,1,246,221,0,1,7,6, + 0,1,246,221,0,1,208,208,208,1,254,228,0,3,208,208,208,1,254,228, + 0,3,208,208,208,1,254,228,0,3,208,208,208,1,254,228,0,3,255,255, + 255,1,128,128,128,1,254,228,0,1,255,255,0,1,0,0,0,1,125,110, + 0,1,7,6,0,1,0,0,0,1,208,208,208,1,255,223,0,1,254,228, + 0,1,208,208,208,2,255,223,0,1,254,228,0,1,208,208,208,2,255,223, + 0,1,254,228,0,1,208,208,208,3,254,228,0,1,255,255,0,1,255,255, + 255,1,128,128,128,1,208,208,208,2,0,0,0,4,208,208,208,2,0,0, + 0,2,208,208,208,12,255,255,255,1,128,128,128,1,254,228,0,1,255,223, + 0,1,0,0,0,1,125,110,0,1,7,6,0,1,125,110,0,1,208,208, + 208,2,7,6,0,1,0,0,0,1,208,208,208,2,254,228,0,1,208,208, + 208,3,254,228,0,1,208,208,208,3,254,228,0,1,255,223,0,1,255,255, + 255,1,128,128,128,1,254,228,0,2,0,0,0,1,246,221,0,1,7,6, + 0,1,246,221,0,1,208,208,208,1,254,228,0,1,7,6,0,1,246,221, + 0,1,208,208,208,1,254,228,0,1,124,111,0,1,250,224,0,1,208,208, + 208,1,254,228,0,3,208,208,208,1,254,228,0,3,255,255,255,1,128,128, + 128,1,254,228,0,1,255,223,0,1,0,0,0,2,7,6,0,1,0,0, + 0,1,208,208,208,2,7,6,0,1,0,0,0,1,208,208,208,2,7,6, + 0,1,0,0,0,1,208,208,208,2,254,228,0,1,208,208,208,3,254,228, + 0,1,255,223,0,1,255,255,255,1,128,128,128,1,208,208,208,2,0,0, + 0,5,208,208,208,1,0,0,0,2,208,208,208,2,0,0,0,2,208,208, + 208,2,0,0,0,2,208,208,208,4,255,255,255,1,128,128,128,1,254,228, + 0,1,255,223,0,1,0,0,0,1,125,110,0,1,7,6,0,1,125,110, + 0,1,0,0,0,2,7,6,0,1,0,0,0,3,7,6,0,1,0,0, + 0,1,208,208,208,2,7,6,0,1,0,0,0,1,208,208,208,2,254,228, + 0,1,255,223,0,1,255,255,255,1,128,128,128,1,254,228,0,2,0,0, + 0,1,246,221,0,1,7,6,0,1,246,221,0,1,0,0,0,1,246,221, + 0,1,7,6,0,1,246,221,0,1,0,0,0,1,246,221,0,1,7,6, + 0,1,246,221,0,1,208,208,208,1,254,228,0,1,7,6,0,1,246,221, + 0,1,208,208,208,1,254,228,0,3,255,255,255,1,128,128,128,1,254,228, + 0,1,255,223,0,1,0,0,0,2,7,6,0,1,0,0,0,3,7,6, + 0,1,0,0,0,3,7,6,0,1,0,0,0,3,7,6,0,1,0,0, + 0,1,208,208,208,2,254,228,0,1,255,223,0,1,255,255,255,1,128,128, + 128,1,208,208,208,2,0,0,0,18,208,208,208,2,255,255,255,1,128,128, + 128,1,254,228,0,1,255,223,0,1,0,0,0,1,134,117,0,1,15,13, + 0,1,134,117,0,1,0,0,0,2,15,13,0,1,0,0,0,3,15,13, + 0,1,0,0,0,3,15,13,0,1,0,0,0,3,254,228,0,1,255,223, + 0,1,255,255,255,1,128,128,128,1,254,228,0,2,208,208,208,1,254,228, + 0,3,208,208,208,1,254,228,0,3,208,208,208,1,254,228,0,3,208,208, + 208,1,254,228,0,3,208,208,208,1,254,228,0,3,255,255,255,25,100,5, + 0,0,255,255,255,26,8,8,8,1,0,0,0,1,15,15,15,1,248,248, + 248,1,8,8,8,1,0,0,0,1,8,8,8,1,248,248,248,1,0,0, + 0,2,8,8,8,1,248,248,248,1,0,0,0,2,8,8,8,1,248,248, + 248,1,0,0,0,3,255,255,255,1,0,0,0,1,255,255,255,3,248,248, + 248,1,7,7,7,1,240,240,240,1,255,255,255,1,248,248,248,1,7,7, + 7,1,248,248,248,1,255,255,255,2,8,8,8,1,248,248,248,1,255,255, + 255,2,8,8,8,1,248,248,248,1,255,255,255,2,8,8,8,1,248,248, + 248,1,255,255,255,5,0,0,0,1,7,7,7,1,8,8,8,1,248,248, + 248,1,0,0,0,2,8,8,8,1,248,248,248,1,0,0,0,2,8,8, + 8,1,248,248,248,1,0,0,0,2,8,8,8,1,248,248,248,1,0,0, + 0,3,255,255,255,1,0,0,0,1,255,255,255,2,0,0,0,2,248,248, + 248,1,8,8,8,1,0,0,0,18,255,255,255,3,8,8,8,1,248,248, + 248,1,23,23,23,1,248,248,248,1,8,8,8,1,0,0,0,1,8,8, + 8,1,248,248,248,1,0,0,0,2,8,8,8,1,248,248,248,1,0,0, + 0,2,8,8,8,1,248,248,248,1,0,0,0,3,255,255,255,1,0,0, + 0,1,255,255,255,3,248,248,248,2,240,240,240,1,255,255,255,1,248,248, + 248,1,7,7,7,1,248,248,248,1,255,255,255,2,8,8,8,1,248,248, + 248,1,255,255,255,2,8,8,8,1,248,248,248,1,255,255,255,2,8,8, + 8,1,248,248,248,1,255,255,255,5,0,0,0,1,248,248,248,1,16,16, + 16,1,248,248,248,1,0,0,0,2,8,8,8,1,248,248,248,1,0,0, + 0,2,8,8,8,1,248,248,248,1,0,0,0,2,8,8,8,1,248,248, + 248,1,0,0,0,3,255,255,255,1,0,0,0,1,255,255,255,2,0,0, + 0,2,248,248,248,1,8,8,8,1,0,0,0,18,255,255,255,3,8,8, + 8,1,248,248,248,1,23,23,23,1,248,248,248,1,8,8,8,1,0,0, + 0,1,8,8,8,1,248,248,248,1,0,0,0,2,8,8,8,1,248,248, + 248,1,0,0,0,2,8,8,8,1,248,248,248,1,0,0,0,3,255,255, + 255,1,0,0,0,1,255,255,255,3,248,248,248,3,255,255,255,1,248,248, + 248,1,0,0,0,1,255,255,255,3,0,0,0,1,255,255,255,3,0,0, + 0,1,255,255,255,3,0,0,0,1,255,255,255,5,254,254,254,1,2,2, + 2,1,248,248,248,1,16,16,16,1,255,255,255,1,8,8,8,1,0,0, + 0,1,8,8,8,1,248,248,248,1,0,0,0,2,8,8,8,1,248,248, + 248,1,0,0,0,2,8,8,8,1,248,248,248,1,0,0,0,3,254,254, + 254,1,2,2,2,1,255,255,255,2,0,0,0,2,248,248,248,1,8,8, + 8,1,248,248,248,1,8,8,8,1,0,0,0,2,131,131,131,1,4,4, + 4,1,0,0,0,12,255,255,255,2,248,248,248,1,16,16,16,1,248,248, + 248,1,16,16,16,1,255,255,255,1,16,16,16,1,0,0,0,2,255,255, + 255,1,8,8,8,1,0,0,0,2,255,255,255,1,0,0,0,3,255,255, + 255,1,0,0,0,3,248,248,248,1,8,8,8,1,255,255,255,3,248,248, + 248,3,255,255,255,1,248,248,248,1,0,0,0,1,255,255,255,3,0,0, + 0,1,255,255,255,3,0,0,0,1,255,255,255,3,0,0,0,1,255,255, + 255,5,248,248,248,1,8,8,8,1,248,248,248,1,8,8,8,1,255,255, + 255,1,8,8,8,1,0,0,0,2,255,255,255,1,8,8,8,1,0,0, + 0,2,255,255,255,1,8,8,8,1,0,0,0,2,255,255,255,1,0,0, + 0,3,248,248,248,1,8,8,8,1,255,255,255,2,0,0,0,2,248,248, + 248,1,8,8,8,1,248,248,248,1,8,8,8,1,7,7,7,1,0,0, + 0,1,248,248,248,1,8,8,8,1,0,0,0,2,248,248,248,1,8,8, + 8,1,0,0,0,2,131,131,131,1,4,4,4,1,0,0,0,4,255,255, + 255,2,248,248,248,1,16,16,16,1,248,248,248,1,16,16,16,1,255,255, + 255,1,16,16,16,1,248,248,248,1,8,8,8,1,255,255,255,1,8,8, + 8,1,131,131,131,1,4,4,4,1,255,255,255,1,8,8,8,1,0,0, + 0,2,255,255,255,1,8,8,8,1,0,0,0,2,248,248,248,1,8,8, + 8,1,255,255,255,3,248,248,248,3,255,255,255,1,248,248,248,2,255,255, + 255,3,248,248,248,1,255,255,255,3,0,0,0,1,255,255,255,3,0,0, + 0,1,255,255,255,5,248,248,248,1,8,8,8,1,248,248,248,1,8,8, + 8,1,255,255,255,1,8,8,8,1,248,248,248,1,8,8,8,1,255,255, + 255,1,8,8,8,1,248,248,248,1,8,8,8,1,255,255,255,1,8,8, + 8,1,131,131,131,1,4,4,4,1,255,255,255,1,8,8,8,1,0,0, + 0,2,248,248,248,1,8,8,8,1,255,255,255,2,0,0,0,2,248,248, + 248,1,8,8,8,1,248,248,248,1,8,8,8,1,248,248,248,1,8,8, + 8,1,248,248,248,1,8,8,8,1,248,248,248,1,8,8,8,1,248,248, + 248,1,8,8,8,1,248,248,248,1,8,8,8,1,248,248,248,1,8,8, + 8,1,131,131,131,1,4,4,4,1,0,0,0,2,255,255,255,2,248,248, + 248,1,16,16,16,1,240,240,240,1,15,15,15,1,255,255,255,1,15,15, + 15,1,240,240,240,1,7,7,7,1,255,255,255,1,7,7,7,1,240,240, + 240,1,7,7,7,1,255,255,255,1,7,7,7,1,240,240,240,1,7,7, + 7,1,255,255,255,1,7,7,7,1,240,240,240,1,7,7,7,1,248,248, + 248,1,8,8,8,1,255,255,255,3,248,248,248,1,0,0,0,1,248,248, + 248,1,255,255,255,1,248,248,248,1,0,0,0,1,255,255,255,3,0,0, + 0,1,255,255,255,3,0,0,0,1,255,255,255,3,0,0,0,1,255,255, + 255,28,0,0) + ); + +const + objdata_tsignoise: record size: integer; data: array[0..2868] of byte end = + (size: 2869; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,115,105, + 103,110,111,105,115,101,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,192,10,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,236,8,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,4,3,3,1,7,7,5,1,22,22,17,1,230, + 224,178,1,231,225,180,1,143,140,113,1,7,7,6,2,61,60,49,1,234, + 230,193,1,231,227,192,1,85,83,71,1,7,7,6,2,114,112,98,1,238, + 235,207,1,239,236,210,1,37,37,33,1,7,7,7,2,204,201,185,1,243, + 240,222,1,230,228,212,1,4,4,4,1,151,147,113,1,229,223,173,1,229, + 224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233, + 228,188,1,233,229,190,1,234,230,193,1,135,132,112,1,235,230,196,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240, + 237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,241, + 239,222,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230, + 224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233, + 229,190,1,227,223,187,1,20,20,17,1,202,197,168,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240, + 238,215,1,241,238,217,1,242,239,220,1,208,205,190,1,188,186,173,1,28, + 28,26,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231, + 225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,139, + 137,115,1,0,0,0,1,158,155,132,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241, + 238,217,1,242,239,220,1,105,104,96,1,158,157,146,1,244,242,227,1,18, + 18,14,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231, + 226,183,1,232,227,185,1,221,216,178,1,231,227,189,1,33,32,27,1,62, + 61,51,1,115,112,96,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,231, + 228,210,1,13,13,12,1,132,130,121,1,244,242,227,1,7,7,5,1,229, + 223,173,1,229,224,175,1,227,221,176,1,231,225,180,1,231,226,183,1,224, + 219,178,1,49,48,40,1,147,145,120,1,56,55,46,1,158,155,131,1,71, + 70,59,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239, + 236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,140,139,128,1,5, + 5,4,1,104,103,96,1,133,132,124,1,14,14,11,1,229,223,173,1,229, + 224,175,1,113,110,87,1,180,176,140,1,231,226,183,1,92,90,73,1,3, + 3,2,1,11,11,9,1,163,161,135,1,202,198,167,1,28,27,23,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240, + 237,212,1,240,238,215,1,241,238,217,1,38,37,35,1,125,123,114,1,184, + 182,170,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,91, + 89,71,1,9,9,7,1,101,98,80,1,33,32,26,1,130,127,105,1,37, + 37,31,1,233,229,192,1,234,230,194,1,12,12,10,1,221,217,187,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240, + 238,215,1,176,174,158,1,44,43,40,1,243,240,222,1,243,241,224,1,7, + 7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,87,85,68,1,95, + 93,74,1,23,22,18,1,188,184,150,1,216,211,174,1,150,147,122,1,234, + 230,193,1,235,231,195,1,55,53,46,1,179,176,151,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,82, + 81,74,1,145,143,132,1,243,240,222,1,243,241,224,1,75,75,70,1,160, + 156,120,1,229,223,173,1,229,224,175,1,84,82,65,1,149,146,116,1,221, + 216,175,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235, + 231,195,1,99,97,83,1,135,133,115,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,237,235,212,1,17,17,15,1,219, + 217,199,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229, + 223,173,1,229,224,175,1,80,78,62,1,153,149,119,1,231,226,183,1,232, + 227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,146, + 143,122,1,87,86,74,1,202,198,172,1,114,112,98,1,238,235,207,1,239, + 236,210,1,231,228,204,1,164,162,147,1,44,44,40,1,242,239,220,1,243, + 240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229, + 224,175,1,76,74,59,1,157,153,122,1,231,226,183,1,232,227,185,1,233, + 228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,203,198,169,1,30, + 29,25,1,151,149,129,1,0,0,0,1,199,196,173,1,239,236,210,1,161, + 159,142,1,0,0,0,1,112,110,100,1,242,239,220,1,243,240,222,1,243, + 241,224,1,75,75,70,1,49,48,37,1,229,223,173,1,229,224,175,1,72, + 70,56,1,160,156,125,1,231,226,183,1,232,227,185,1,233,228,188,1,233, + 229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,24,24,20,1,99, + 97,84,1,7,6,6,1,106,105,93,1,239,236,210,1,154,152,136,1,0, + 0,0,1,179,176,161,1,242,239,220,1,243,240,222,1,243,241,224,1,7, + 7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,69,67,53,1,164, + 160,128,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234, + 230,193,1,235,231,195,1,236,231,197,1,81,80,69,1,20,19,17,1,100, + 98,86,1,21,21,19,1,237,234,208,1,147,145,130,1,37,36,33,1,235, + 232,212,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1,228, + 222,171,1,229,223,173,1,229,224,175,1,65,63,50,1,167,162,130,1,231, + 226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235, + 231,195,1,236,231,197,1,139,136,118,1,0,0,0,1,156,153,134,1,49, + 48,42,1,181,179,159,1,140,138,124,1,104,103,93,1,241,238,217,1,242, + 239,220,1,243,240,222,1,243,241,224,1,133,132,124,1,95,93,71,1,33, + 32,25,1,213,208,163,1,60,59,47,1,170,166,133,1,231,226,183,1,232, + 227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236, + 231,197,1,196,193,166,1,0,0,0,1,180,177,155,1,122,121,106,1,105, + 104,92,1,133,131,117,1,110,109,99,1,241,238,217,1,242,239,220,1,243, + 240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,46,45,35,1,179, + 175,137,1,57,55,44,1,174,169,136,1,231,226,183,1,232,227,185,1,233, + 228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,235, + 231,199,1,80,79,68,1,214,210,184,1,197,194,171,1,30,30,26,1,125, + 124,111,1,118,117,105,1,241,238,217,1,242,239,220,1,243,240,222,1,243, + 241,224,1,244,242,227,1,7,7,5,1,81,79,61,1,144,141,110,1,53, + 52,41,1,178,173,138,1,231,226,183,1,232,227,185,1,233,228,188,1,233, + 229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,32,31,28,1,72,72,64,1,124, + 123,111,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,28, + 28,26,1,103,100,77,1,115,112,87,1,110,107,84,1,47,46,36,1,184, + 179,143,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234, + 230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,107,106,94,1,6,6,5,1,131,130,117,1,241, + 238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1,228, + 222,171,1,150,146,113,1,56,54,43,1,25,25,20,1,204,199,159,1,231, + 226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235, + 231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,181,179,159,1,0,0,0,1,137,136,123,1,241,238,217,1,242, + 239,220,1,243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,215, + 209,162,1,69,68,53,1,0,0,0,1,224,218,174,1,231,226,183,1,232, + 227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236, + 231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,236, + 233,208,1,19,19,17,1,145,144,130,1,241,238,217,1,242,239,220,1,243, + 240,222,1,243,241,224,1,231,229,215,1,44,43,33,1,229,223,173,1,229, + 224,175,1,143,140,111,1,231,225,180,1,231,226,183,1,232,227,185,1,233, + 228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,150, + 148,132,1,198,196,177,1,241,238,217,1,242,239,220,1,243,240,222,1,243, + 241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1,230, + 224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233, + 229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240, + 238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,205, + 204,191,1,4,3,3,1,171,167,129,1,229,224,175,1,230,224,178,1,11, + 11,9,1,7,7,6,1,23,22,18,1,233,228,188,1,233,229,190,1,145, + 143,120,1,7,7,6,2,61,60,52,1,237,233,202,1,238,234,205,1,86, + 85,75,1,7,7,6,2,115,114,103,1,241,238,217,1,242,239,220,1,38, + 37,34,1,7,7,7,1,4,4,4,1,156,1,0,0,244,244,244,1,248, + 248,248,1,233,233,233,1,128,128,128,2,158,158,158,1,248,248,248,2,203, + 203,203,1,128,128,128,1,129,129,129,1,188,188,188,1,248,248,248,2,173, + 173,173,1,128,128,128,2,221,221,221,1,248,248,248,2,139,139,139,1,128, + 128,128,1,131,131,131,1,244,244,244,1,154,154,154,1,255,255,255,22,248, + 248,248,1,128,128,128,1,255,255,255,22,229,229,229,1,128,128,128,1,255, + 255,255,22,128,128,128,1,236,236,236,1,255,255,255,22,128,128,128,1,248, + 248,248,1,255,255,255,22,165,165,165,1,240,240,240,1,255,255,255,22,248, + 248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1,255, + 255,255,22,195,195,195,1,150,150,150,1,255,255,255,22,128,128,128,1,248, + 248,248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,195, + 195,195,1,210,210,210,1,255,255,255,22,248,248,248,1,128,128,128,1,255, + 255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,165,165,165,1,180, + 180,180,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,128, + 128,128,1,248,248,248,1,255,255,255,22,229,229,229,1,176,176,176,1,255, + 255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128, + 128,128,1,255,255,255,22,131,131,131,1,214,214,214,1,255,255,255,22,128, + 128,128,1,248,248,248,1,255,255,255,22,139,139,139,1,244,244,244,1,146, + 146,146,1,128,128,128,2,244,244,244,1,248,248,248,1,233,233,233,1,128, + 128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2,188, + 188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221,1,248, + 248,248,1,244,244,244,1,0,0) + ); + +const + objdata_tsigmidisource: record size: integer; data: array[0..2869] of byte end = + (size: 2870; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,115,105, + 103,109,105,100,105,115,111,117,114,99,101,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,188,10,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,236,8,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,4,3,3,1,7,7,5,1, + 22,22,17,1,230,224,178,1,231,225,180,1,143,140,113,1,7,7,6,2, + 61,60,49,1,234,230,193,1,235,231,195,1,85,83,71,1,7,7,6,2, + 114,112,98,1,238,235,207,1,239,236,210,1,37,37,33,1,7,7,7,2, + 204,201,185,1,243,240,222,1,230,228,212,1,4,4,4,1,151,147,113,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,28,28,26,1,228,222,171,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1, + 244,242,227,1,18,18,14,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1, + 241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1, + 7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1, + 235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1, + 242,239,220,1,243,240,222,1,243,241,224,1,133,132,124,1,14,14,11,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,181,177,138,1, + 183,178,142,1,231,225,180,1,231,226,183,1,232,227,185,1,224,219,181,1, + 167,164,136,1,222,218,183,1,229,226,190,1,178,174,148,1,236,232,200,1, + 209,206,178,1,171,168,147,1,171,169,149,1,182,180,160,1,218,216,193,1, + 240,238,215,1,241,238,217,1,242,239,220,1,180,178,165,1,241,239,222,1, + 75,75,70,1,160,156,120,1,229,223,173,1,57,55,43,1,17,17,13,1, + 226,221,176,1,231,226,183,1,232,227,185,1,148,145,119,1,0,0,0,1, + 190,187,157,1,215,211,178,1,28,27,23,1,236,232,200,1,136,133,116,1, + 44,43,38,1,96,95,84,1,86,85,76,1,38,37,33,1,123,122,110,1, + 241,238,217,1,242,239,220,1,17,17,16,1,233,232,215,1,244,242,227,1, + 7,7,5,1,229,223,173,1,57,55,43,1,53,52,41,1,164,160,128,1, + 231,226,183,1,232,227,185,1,71,70,58,1,45,44,37,1,190,187,157,1, + 215,211,178,1,28,27,23,1,236,232,200,1,136,133,116,1,109,107,94,1, + 238,235,207,1,239,236,210,1,225,222,199,1,37,36,33,1,195,192,175,1, + 242,239,220,1,17,17,16,1,233,232,215,1,244,242,227,1,7,7,5,1, + 229,223,173,1,57,55,43,1,132,128,102,1,85,83,66,1,231,226,183,1, + 215,210,171,1,69,67,55,1,65,64,53,1,190,187,157,1,215,211,178,1, + 28,27,23,1,236,232,200,1,136,133,116,1,109,107,94,1,238,235,207,1, + 239,236,210,1,240,237,212,1,103,102,92,1,135,133,122,1,242,239,220,1, + 17,17,16,1,233,232,215,1,75,75,70,1,49,48,37,1,229,223,173,1, + 57,55,43,1,186,181,144,1,37,36,29,1,225,220,178,1,139,136,111,1, + 145,142,117,1,65,64,53,1,190,187,157,1,215,211,178,1,28,27,23,1, + 236,232,200,1,136,133,116,1,109,107,94,1,238,235,207,1,239,236,210,1, + 240,237,212,1,135,133,121,1,112,111,101,1,242,239,220,1,17,17,16,1, + 233,232,215,1,7,7,7,1,228,222,171,1,229,223,173,1,57,55,43,1, + 187,182,144,1,101,98,78,1,159,156,126,1,66,64,52,1,219,215,177,1, + 65,64,53,1,190,187,157,1,215,211,178,1,28,27,23,1,236,232,200,1, + 136,133,116,1,109,107,94,1,238,235,207,1,239,236,210,1,240,237,212,1, + 103,102,92,1,142,140,128,1,242,239,220,1,17,17,16,1,233,232,215,1, + 7,7,7,1,228,222,171,1,229,223,173,1,57,55,43,1,187,182,144,1, + 179,175,140,1,65,64,52,1,77,76,62,1,233,228,188,1,65,64,53,1, + 190,187,157,1,215,211,178,1,28,27,23,1,236,232,200,1,136,133,116,1, + 109,107,94,1,238,235,207,1,239,236,210,1,198,195,175,1,24,23,21,1, + 221,218,199,1,242,239,220,1,17,17,16,1,233,232,215,1,133,132,124,1, + 95,93,71,1,229,223,173,1,57,55,43,1,187,182,144,1,230,224,179,1, + 26,26,21,1,156,152,124,1,233,228,188,1,65,64,53,1,190,187,157,1, + 215,211,178,1,28,27,23,1,236,232,200,1,136,133,116,1,17,17,14,1, + 36,36,32,1,32,31,28,1,51,50,45,1,180,178,161,1,241,238,217,1, + 242,239,220,1,17,17,16,1,233,232,215,1,244,242,227,1,7,7,5,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,28,28,26,1,103,100,77,1,229,223,173,1,229,224,175,1, + 230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1, + 7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1, + 234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1, + 241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7,7,1, + 228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1, + 235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1, + 242,239,220,1,243,240,222,1,243,241,224,1,231,229,215,1,44,43,33,1, + 229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1, + 243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1, + 229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1, + 243,241,224,1,205,204,191,1,4,3,3,1,171,167,129,1,229,224,175,1, + 230,224,178,1,11,11,9,1,7,7,6,1,23,22,18,1,233,228,188,1, + 233,229,190,1,145,143,120,1,7,7,6,2,61,60,52,1,237,233,202,1, + 238,234,205,1,86,85,75,1,7,7,6,2,115,114,103,1,241,238,217,1, + 242,239,220,1,38,37,34,1,7,7,7,1,4,4,4,1,152,1,0,0, + 244,244,244,1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1, + 248,248,248,2,203,203,203,1,128,128,128,2,188,188,188,1,248,248,248,2, + 173,173,173,1,128,128,128,2,221,221,221,1,248,248,248,2,139,139,139,1, + 128,128,128,1,131,131,131,1,244,244,244,1,154,154,154,1,255,255,255,22, + 248,248,248,1,128,128,128,1,255,255,255,22,229,229,229,1,128,128,128,1, + 255,255,255,22,128,128,128,1,236,236,236,1,255,255,255,22,128,128,128,1, + 248,248,248,1,255,255,255,22,165,165,165,1,240,240,240,1,255,255,255,22, + 248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1, + 255,255,255,22,195,195,195,1,150,150,150,1,255,255,255,22,128,128,128,1, + 248,248,248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22, + 195,195,195,1,210,210,210,1,255,255,255,22,248,248,248,1,128,128,128,1, + 255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,165,165,165,1, + 180,180,180,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22, + 128,128,128,1,248,248,248,1,255,255,255,22,229,229,229,1,176,176,176,1, + 255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1, + 128,128,128,1,255,255,255,22,131,131,131,1,214,214,214,1,255,255,255,22, + 128,128,128,1,248,248,248,1,255,255,255,22,139,139,139,1,244,244,244,1, + 146,146,146,1,128,128,128,2,244,244,244,1,248,248,248,1,233,233,233,1, + 128,128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2, + 188,188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221,1, + 248,248,248,1,244,244,244,1,0,0) + ); + +const + objdata_tsigmidiconnector: record size: integer; data: array[0..2800] of byte end = + (size: 2801; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,115,105, + 103,109,105,100,105,99,111,110,110,101,99,116,111,114,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,116, + 10,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,164, + 8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,3,3,1,7, + 7,5,1,22,22,17,1,230,224,178,1,231,225,180,1,143,140,113,1,7, + 7,6,2,61,60,49,1,234,230,193,1,235,231,195,1,85,83,71,1,7, + 7,6,2,114,112,98,1,238,235,207,1,239,236,210,1,37,37,33,1,7, + 7,7,2,204,201,185,1,243,240,222,1,230,228,212,1,4,4,4,1,151, + 147,113,1,229,223,173,1,224,219,171,1,225,220,175,1,231,225,180,1,231, + 226,183,1,232,227,185,1,233,228,188,1,226,222,184,1,233,229,192,1,235, + 231,195,1,230,225,192,1,236,232,200,1,234,230,200,1,231,227,199,1,231, + 228,201,1,238,235,209,1,240,237,212,1,240,238,215,1,241,238,217,1,242, + 239,220,1,236,233,216,1,243,241,224,1,7,7,7,1,228,222,171,1,229, + 223,173,1,57,55,43,1,31,30,24,1,231,225,180,1,231,226,183,1,232, + 227,185,1,168,165,136,1,0,0,0,1,190,187,157,1,215,211,178,1,28, + 27,23,1,236,232,200,1,136,133,116,1,17,17,14,1,36,36,32,1,31, + 31,27,1,46,46,41,1,172,171,154,1,241,238,217,1,242,239,220,1,17, + 17,16,1,233,232,215,1,28,28,26,1,228,222,171,1,229,223,173,1,57, + 55,43,1,34,33,27,1,183,178,143,1,231,226,183,1,232,227,185,1,88, + 86,71,1,28,28,23,1,190,187,157,1,215,211,178,1,28,27,23,1,236, + 232,200,1,136,133,116,1,109,107,94,1,238,235,207,1,239,236,210,1,194, + 191,171,1,30,30,27,1,215,212,193,1,242,239,220,1,17,17,16,1,233, + 232,215,1,244,242,227,1,18,18,14,1,229,223,173,1,57,55,43,1,112, + 109,87,1,105,102,82,1,231,226,183,1,226,221,180,1,58,56,46,1,65, + 64,53,1,190,187,157,1,215,211,178,1,28,27,23,1,236,232,200,1,136, + 133,116,1,109,107,94,1,238,235,207,1,239,236,210,1,240,237,212,1,90, + 90,81,1,145,143,130,1,242,239,220,1,17,17,16,1,233,232,215,1,244, + 242,227,1,7,7,5,1,229,223,173,1,57,55,43,1,179,174,138,1,38, + 37,30,1,230,225,182,1,159,156,127,1,125,122,101,1,65,64,53,1,190, + 187,157,1,215,211,178,1,28,27,23,1,236,232,200,1,136,133,116,1,109, + 107,94,1,238,235,207,1,239,236,210,1,240,237,212,1,134,133,120,1,112, + 111,101,1,242,239,220,1,17,17,16,1,233,232,215,1,133,132,124,1,14, + 14,11,1,229,223,173,1,57,55,43,1,187,182,144,1,81,79,63,1,179, + 175,142,1,80,78,64,1,206,201,166,1,65,64,53,1,190,187,157,1,215, + 211,178,1,28,27,23,1,236,232,200,1,136,133,116,1,109,107,94,1,238, + 235,207,1,239,236,210,1,240,237,212,1,115,114,103,1,132,131,119,1,242, + 239,220,1,17,17,16,1,233,232,215,1,7,7,7,1,228,222,171,1,229, + 223,173,1,57,55,43,1,187,182,144,1,159,155,124,1,94,92,75,1,64, + 62,51,1,233,228,188,1,65,64,53,1,190,187,157,1,215,211,178,1,28, + 27,23,1,236,232,200,1,136,133,116,1,109,107,94,1,238,235,207,1,239, + 236,210,1,231,228,204,1,33,33,30,1,200,198,180,1,242,239,220,1,17, + 17,16,1,233,232,215,1,7,7,7,1,228,222,171,1,229,223,173,1,57, + 55,43,1,187,182,144,1,225,219,175,1,16,16,13,1,136,133,108,1,233, + 228,188,1,65,64,53,1,190,187,157,1,215,211,178,1,28,27,23,1,236, + 232,200,1,136,133,116,1,44,43,38,1,96,95,84,1,83,82,73,1,34, + 33,30,1,129,128,116,1,241,238,217,1,242,239,220,1,17,17,16,1,233, + 232,215,1,75,75,70,1,160,156,120,1,229,223,173,1,186,182,142,1,219, + 213,170,1,231,225,180,1,188,183,149,1,221,216,176,1,233,228,188,1,191, + 188,156,1,223,219,184,1,230,226,191,1,184,180,154,1,236,232,200,1,212, + 208,181,1,178,175,154,1,178,176,155,1,187,185,165,1,224,221,198,1,240, + 238,215,1,241,238,217,1,242,239,220,1,187,184,171,1,241,239,222,1,244, + 242,227,1,7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231, + 225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234, + 230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241, + 238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,7, + 7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231, + 226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235, + 231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242, + 239,220,1,243,240,222,1,243,241,224,1,75,75,70,1,49,48,37,1,229, + 223,173,1,229,224,175,1,230,224,178,1,127,124,99,1,177,173,140,1,232, + 227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236, + 231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239, + 236,210,1,240,237,212,1,132,131,118,1,184,182,166,1,242,239,220,1,243, + 240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229, + 224,175,1,230,224,178,1,177,172,138,1,22,21,17,1,177,174,141,1,233, + 228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240, + 237,212,1,184,182,164,1,23,22,20,1,185,183,168,1,243,240,222,1,243, + 241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230, + 224,178,1,231,225,180,1,177,173,140,1,22,21,17,1,178,174,144,1,233, + 229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240, + 238,215,1,184,182,166,1,23,22,21,1,186,184,170,1,243,241,224,1,133, + 132,124,1,95,93,71,1,229,223,173,1,0,0,0,19,53,53,49,1,243, + 241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1,230, + 224,178,1,231,225,180,1,177,173,140,1,22,21,17,1,178,174,144,1,233, + 229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240, + 238,215,1,184,182,166,1,23,22,21,1,186,184,170,1,243,241,224,1,244, + 242,227,1,7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,177, + 172,138,1,22,21,17,1,177,174,141,1,233,228,188,1,233,229,190,1,234, + 230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,184,182,164,1,23, + 22,20,1,185,183,168,1,243,240,222,1,243,241,224,1,28,28,26,1,103, + 100,77,1,229,223,173,1,229,224,175,1,230,224,178,1,127,124,99,1,177, + 173,140,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235, + 231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238, + 235,207,1,239,236,210,1,240,237,212,1,132,131,118,1,184,182,166,1,242, + 239,220,1,243,240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229, + 223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232, + 227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236, + 231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239, + 236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243, + 240,222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229, + 224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233, + 228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236, + 232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240, + 237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243, + 241,224,1,231,229,215,1,44,43,33,1,229,223,173,1,229,224,175,1,230, + 224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233, + 229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237, + 233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240, + 238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244, + 242,227,1,7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1,231, + 225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,233,229,190,1,234, + 230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238, + 234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,241, + 238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,205,204,191,1,4, + 3,3,1,171,167,129,1,229,224,175,1,230,224,178,1,11,11,9,1,7, + 7,6,1,23,22,18,1,233,228,188,1,233,229,190,1,145,143,120,1,7, + 7,6,2,61,60,52,1,237,233,202,1,238,234,205,1,86,85,75,1,7, + 7,6,2,115,114,103,1,241,238,217,1,242,239,220,1,38,37,34,1,7, + 7,7,1,4,4,4,1,152,1,0,0,244,244,244,1,248,248,248,1,233, + 233,233,1,128,128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128, + 128,128,2,188,188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,221, + 221,221,1,248,248,248,2,139,139,139,1,128,128,128,1,131,131,131,1,244, + 244,244,1,154,154,154,1,255,255,255,22,248,248,248,1,128,128,128,1,255, + 255,255,22,229,229,229,1,128,128,128,1,255,255,255,22,128,128,128,1,236, + 236,236,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,165, + 165,165,1,240,240,240,1,255,255,255,22,248,248,248,1,128,128,128,1,255, + 255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,195,195,195,1,150, + 150,150,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,128, + 128,128,1,248,248,248,1,255,255,255,22,195,195,195,1,210,210,210,1,255, + 255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128, + 128,128,1,255,255,255,22,165,165,165,1,180,180,180,1,255,255,255,22,128, + 128,128,1,248,248,248,1,255,255,255,22,128,128,128,1,248,248,248,1,255, + 255,255,22,229,229,229,1,176,176,176,1,255,255,255,22,248,248,248,1,128, + 128,128,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,131, + 131,131,1,214,214,214,1,255,255,255,22,128,128,128,1,248,248,248,1,255, + 255,255,22,139,139,139,1,244,244,244,1,146,146,146,1,128,128,128,2,244, + 244,244,1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1,248, + 248,248,2,203,203,203,1,128,128,128,2,188,188,188,1,248,248,248,2,173, + 173,173,1,128,128,128,2,221,221,221,1,248,248,248,1,244,244,244,1,0, + 0) + ); + +const + objdata_tsigmidimulticonnector: record size: integer; data: array[0..2733] of byte end = + (size: 2734; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,22,116,115,105, + 103,109,105,100,105,109,117,108,116,105,99,111,110,110,101,99,116,111,114,23, + 98,105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111, + 108,111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105, + 111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95, + 99,111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109, + 97,103,101,10,44,10,0,0,0,0,0,0,6,0,0,0,24,0,0,0, + 24,0,0,0,92,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 4,3,3,1,7,7,5,1,22,22,17,1,230,224,178,1,231,225,180,1, + 143,140,113,1,7,7,6,2,61,60,49,1,234,230,193,1,235,231,195,1, + 85,83,71,1,7,7,6,2,114,112,98,1,238,235,207,1,239,236,210,1, + 37,37,33,1,7,7,7,2,204,201,185,1,243,240,222,1,230,228,212,1, + 4,4,4,1,151,147,113,1,229,223,173,1,224,219,171,1,225,220,175,1, + 231,225,180,1,231,226,183,1,232,227,185,1,233,228,188,1,226,222,184,1, + 233,229,192,1,235,231,195,1,230,225,192,1,236,232,200,1,234,230,200,1, + 231,227,199,1,231,228,201,1,238,235,209,1,240,237,212,1,240,238,215,1, + 241,238,217,1,242,239,220,1,236,233,216,1,243,241,224,1,7,7,7,1, + 228,222,171,1,229,223,173,1,57,55,43,1,31,30,24,1,231,225,180,1, + 231,226,183,1,232,227,185,1,168,165,136,1,0,0,0,1,190,187,157,1, + 215,211,178,1,28,27,23,1,236,232,200,1,136,133,116,1,17,17,14,1, + 36,36,32,1,31,31,27,1,46,46,41,1,172,171,154,1,241,238,217,1, + 242,239,220,1,17,17,16,1,233,232,215,1,28,28,26,1,228,222,171,1, + 229,223,173,1,57,55,43,1,34,33,27,1,183,178,143,1,231,226,183,1, + 232,227,185,1,88,86,71,1,28,28,23,1,190,187,157,1,215,211,178,1, + 28,27,23,1,236,232,200,1,136,133,116,1,109,107,94,1,238,235,207,1, + 239,236,210,1,194,191,171,1,30,30,27,1,215,212,193,1,242,239,220,1, + 17,17,16,1,233,232,215,1,244,242,227,1,18,18,14,1,229,223,173,1, + 57,55,43,1,112,109,87,1,105,102,82,1,231,226,183,1,226,221,180,1, + 58,56,46,1,65,64,53,1,190,187,157,1,215,211,178,1,28,27,23,1, + 236,232,200,1,136,133,116,1,109,107,94,1,238,235,207,1,239,236,210,1, + 240,237,212,1,90,90,81,1,145,143,130,1,242,239,220,1,17,17,16,1, + 233,232,215,1,244,242,227,1,7,7,5,1,229,223,173,1,57,55,43,1, + 179,174,138,1,38,37,30,1,230,225,182,1,159,156,127,1,125,122,101,1, + 65,64,53,1,190,187,157,1,215,211,178,1,28,27,23,1,236,232,200,1, + 136,133,116,1,109,107,94,1,238,235,207,1,239,236,210,1,240,237,212,1, + 134,133,120,1,112,111,101,1,242,239,220,1,17,17,16,1,233,232,215,1, + 133,132,124,1,14,14,11,1,229,223,173,1,57,55,43,1,187,182,144,1, + 81,79,63,1,179,175,142,1,80,78,64,1,206,201,166,1,65,64,53,1, + 190,187,157,1,215,211,178,1,28,27,23,1,236,232,200,1,136,133,116,1, + 109,107,94,1,238,235,207,1,239,236,210,1,240,237,212,1,115,114,103,1, + 132,131,119,1,242,239,220,1,17,17,16,1,233,232,215,1,7,7,7,1, + 228,222,171,1,229,223,173,1,57,55,43,1,187,182,144,1,159,155,124,1, + 94,92,75,1,64,62,51,1,233,228,188,1,65,64,53,1,190,187,157,1, + 215,211,178,1,28,27,23,1,236,232,200,1,136,133,116,1,109,107,94,1, + 238,235,207,1,239,236,210,1,231,228,204,1,33,33,30,1,200,198,180,1, + 242,239,220,1,17,17,16,1,233,232,215,1,7,7,7,1,228,222,171,1, + 229,223,173,1,57,55,43,1,187,182,144,1,225,219,175,1,16,16,13,1, + 136,133,108,1,233,228,188,1,65,64,53,1,190,187,157,1,215,211,178,1, + 28,27,23,1,236,232,200,1,136,133,116,1,44,43,38,1,96,95,84,1, + 83,82,73,1,34,33,30,1,129,128,116,1,241,238,217,1,242,239,220,1, + 17,17,16,1,233,232,215,1,75,75,70,1,160,156,120,1,229,223,173,1, + 186,182,142,1,219,213,170,1,231,225,180,1,188,183,149,1,221,216,176,1, + 233,228,188,1,191,188,156,1,223,219,184,1,230,226,191,1,184,180,154,1, + 236,232,200,1,212,208,181,1,178,175,154,1,178,176,155,1,187,185,165,1, + 224,221,198,1,240,238,215,1,241,238,217,1,242,239,220,1,187,184,171,1, + 241,239,222,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1, + 230,224,178,1,127,124,99,1,177,173,140,1,232,227,185,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 132,131,118,1,184,182,166,1,242,239,220,1,243,240,222,1,243,241,224,1, + 244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1,230,224,178,1, + 177,172,138,1,22,21,17,1,177,174,141,1,233,228,188,1,233,229,190,1, + 234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,184,182,164,1, + 23,22,20,1,185,183,168,1,243,240,222,1,243,241,224,1,75,75,70,1, + 49,48,37,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 177,173,140,1,22,21,17,1,178,174,144,1,233,229,190,1,234,230,193,1, + 235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,184,182,166,1, + 23,22,21,1,186,184,170,1,243,241,224,1,7,7,7,1,228,222,171,1, + 229,223,173,1,0,0,0,19,53,53,49,1,243,241,224,1,7,7,7,1, + 228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1, + 177,173,140,1,22,21,17,1,178,174,144,1,233,229,190,1,234,230,193,1, + 235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,184,182,166,1, + 23,22,21,1,186,184,170,1,243,241,224,1,133,132,124,1,95,93,71,1, + 229,223,173,1,229,224,175,1,230,224,178,1,177,172,138,1,22,21,17,1, + 177,174,141,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,184,182,164,1,23,22,20,1,185,183,168,1, + 243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1, + 229,224,175,1,230,224,178,1,70,68,54,1,135,132,107,1,232,227,185,1, + 233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1, + 236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1, + 240,237,212,1,72,72,65,1,141,139,127,1,242,239,220,1,243,240,222,1, + 243,241,224,1,244,242,227,1,7,7,5,1,229,223,173,1,229,224,175,1, + 230,224,178,1,177,172,138,1,22,21,17,1,177,174,141,1,233,228,188,1, + 233,229,190,1,234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1, + 237,233,202,1,238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1, + 184,182,164,1,23,22,20,1,185,183,168,1,243,240,222,1,243,241,224,1, + 28,28,26,1,103,100,77,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,177,173,140,1,22,21,17,1,178,174,144,1,233,229,190,1, + 234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1, + 184,182,166,1,23,22,21,1,186,184,170,1,243,241,224,1,7,7,7,1, + 228,222,171,1,229,223,173,1,0,0,0,19,53,53,49,1,243,241,224,1, + 7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1, + 231,225,180,1,177,173,140,1,22,21,17,1,178,174,144,1,233,229,190,1, + 234,230,193,1,235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1, + 238,234,205,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1, + 184,182,166,1,23,22,21,1,186,184,170,1,243,241,224,1,231,229,215,1, + 44,43,33,1,229,223,173,1,229,224,175,1,230,224,178,1,177,172,138,1, + 22,21,17,1,177,174,141,1,233,228,188,1,233,229,190,1,234,230,193,1, + 235,231,195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1, + 238,235,207,1,239,236,210,1,240,237,212,1,184,182,164,1,23,22,20,1, + 185,183,168,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1, + 229,223,173,1,229,224,175,1,230,224,178,1,127,124,99,1,177,173,140,1, + 232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1, + 236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1, + 239,236,210,1,240,237,212,1,132,131,118,1,184,182,166,1,242,239,220,1, + 243,240,222,1,243,241,224,1,205,204,191,1,4,3,3,1,171,167,129,1, + 229,224,175,1,230,224,178,1,11,11,9,1,7,7,6,1,23,22,18,1, + 233,228,188,1,233,229,190,1,145,143,120,1,7,7,6,2,61,60,52,1, + 237,233,202,1,238,234,205,1,86,85,75,1,7,7,6,2,115,114,103,1, + 241,238,217,1,242,239,220,1,38,37,34,1,7,7,7,1,4,4,4,1, + 152,1,0,0,244,244,244,1,248,248,248,1,233,233,233,1,128,128,128,2, + 158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2,188,188,188,1, + 248,248,248,2,173,173,173,1,128,128,128,2,221,221,221,1,248,248,248,2, + 139,139,139,1,128,128,128,1,131,131,131,1,244,244,244,1,154,154,154,1, + 255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,229,229,229,1, + 128,128,128,1,255,255,255,22,128,128,128,1,236,236,236,1,255,255,255,22, + 128,128,128,1,248,248,248,1,255,255,255,22,165,165,165,1,240,240,240,1, + 255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1, + 128,128,128,1,255,255,255,22,195,195,195,1,150,150,150,1,255,255,255,22, + 128,128,128,1,248,248,248,1,255,255,255,22,128,128,128,1,248,248,248,1, + 255,255,255,22,195,195,195,1,210,210,210,1,255,255,255,22,248,248,248,1, + 128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22, + 165,165,165,1,180,180,180,1,255,255,255,22,128,128,128,1,248,248,248,1, + 255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,229,229,229,1, + 176,176,176,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22, + 248,248,248,1,128,128,128,1,255,255,255,22,131,131,131,1,214,214,214,1, + 255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,139,139,139,1, + 244,244,244,1,146,146,146,1,128,128,128,2,244,244,244,1,248,248,248,1, + 233,233,233,1,128,128,128,2,158,158,158,1,248,248,248,2,203,203,203,1, + 128,128,128,2,188,188,188,1,248,248,248,2,173,173,173,1,128,128,128,2, + 221,221,221,1,248,248,248,1,244,244,244,1,0,0) + ); + +const + objdata_tsigoutaudio: record size: integer; data: array[0..2851] of byte end = + (size: 2852; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,115,105, + 103,111,117,116,97,117,100,105,111,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,172,10,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,220,8,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,4,3,3,1,7,7,5,1,22,22, + 17,1,230,224,178,1,231,225,180,1,143,140,113,1,7,7,6,2,61,60, + 49,1,234,230,193,1,235,231,195,1,85,83,71,1,7,7,6,2,114,112, + 98,1,238,235,207,1,239,236,210,1,37,37,33,1,7,7,7,2,204,201, + 185,1,243,240,222,1,230,228,212,1,4,4,4,1,151,147,113,1,229,223, + 173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227, + 185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231, + 197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236, + 210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240, + 222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224, + 175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227,185,1,185,181, + 149,1,226,222,184,1,234,230,193,1,229,225,190,1,195,191,163,1,236,232, + 200,1,237,233,202,1,202,198,174,1,227,224,197,1,239,236,210,1,240,237, + 212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241, + 224,1,28,28,26,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224, + 178,1,231,225,180,1,231,226,183,1,231,226,184,1,33,32,27,1,159,156, + 130,1,234,230,193,1,210,207,174,1,92,90,76,1,236,232,200,1,237,233, + 202,1,108,106,93,1,197,194,171,1,239,236,210,1,240,237,212,1,240,238, + 215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242, + 227,1,18,18,14,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225, + 180,1,231,226,183,1,185,181,147,1,105,103,85,1,89,87,72,1,234,230, + 193,1,210,207,174,1,92,90,76,1,236,232,200,1,237,233,202,1,108,106, + 93,1,197,194,171,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238, + 217,1,242,239,220,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7, + 5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226, + 183,1,119,117,95,1,182,178,147,1,65,64,53,1,232,228,191,1,210,207, + 174,1,92,90,76,1,236,232,200,1,237,233,202,1,108,106,93,1,197,194, + 171,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239, + 220,1,243,240,222,1,243,241,224,1,133,132,124,1,14,14,11,1,229,223, + 173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,69,68, + 55,1,231,226,187,1,115,113,94,1,180,177,148,1,210,207,174,1,92,90, + 76,1,236,232,200,1,237,233,202,1,108,106,93,1,197,194,171,1,239,236, + 210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240, + 222,1,243,241,224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224, + 175,1,230,224,178,1,231,225,180,1,216,211,171,1,22,21,17,1,43,42, + 35,1,38,38,31,1,108,106,89,1,226,222,187,1,80,78,66,1,236,232, + 200,1,237,233,202,1,83,82,72,1,211,208,183,1,239,236,210,1,240,237, + 212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241, + 224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224, + 178,1,231,225,180,1,153,150,121,1,140,137,112,1,233,228,188,1,230,226, + 188,1,53,52,44,1,235,231,195,1,56,54,46,1,230,226,195,1,229,225, + 195,1,45,44,39,1,234,231,204,1,239,236,210,1,240,237,212,1,240,238, + 215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,75,75, + 70,1,160,156,120,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225, + 180,1,88,86,70,1,204,199,163,1,233,228,188,1,233,229,190,1,81,79, + 67,1,201,197,167,1,150,147,125,1,35,35,30,1,29,28,25,1,144,141, + 124,1,238,235,207,1,239,236,210,1,240,237,212,1,240,238,215,1,132,131, + 119,1,185,183,168,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7, + 5,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226, + 183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231, + 195,1,236,231,197,1,231,227,196,1,230,227,196,1,238,234,205,1,238,235, + 207,1,239,236,210,1,240,237,212,1,240,238,215,1,184,182,166,1,23,22, + 21,1,186,184,170,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223, + 173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227, + 185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231, + 197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236, + 210,1,240,237,212,1,240,238,215,1,241,238,217,1,185,183,168,1,23,23, + 21,1,186,184,171,1,75,75,70,1,49,48,37,1,229,223,173,1,229,224, + 175,1,230,224,178,1,226,221,176,1,224,219,177,1,230,225,184,1,233,228, + 188,1,233,229,190,1,234,230,193,1,230,226,191,1,236,231,197,1,236,232, + 200,1,234,230,200,1,221,217,191,1,238,235,207,1,239,236,210,1,0,0, + 0,5,53,53,49,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224, + 175,1,230,224,178,1,84,82,66,1,33,32,26,1,31,30,25,1,71,70, + 58,1,225,221,183,1,227,223,187,1,74,72,61,1,236,231,197,1,185,182, + 157,1,24,24,21,1,51,50,44,1,83,82,72,1,237,234,208,1,240,237, + 212,1,240,238,215,1,241,238,217,1,185,183,168,1,23,23,21,1,186,184, + 171,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224, + 178,1,84,82,66,1,212,207,168,1,232,227,185,1,132,130,107,1,131,128, + 107,1,227,223,187,1,74,72,61,1,236,231,197,1,51,50,43,1,204,201, + 174,1,238,234,205,1,139,137,121,1,133,131,117,1,240,237,212,1,240,238, + 215,1,184,182,166,1,23,22,21,1,186,184,170,1,243,241,224,1,133,132, + 124,1,95,93,71,1,229,223,173,1,229,224,175,1,230,224,178,1,84,82, + 66,1,212,207,168,1,232,227,185,1,220,215,178,1,70,69,57,1,227,223, + 187,1,74,72,61,1,205,201,172,1,62,61,53,1,237,233,202,1,238,234, + 205,1,234,231,204,1,68,68,60,1,240,237,212,1,240,238,215,1,132,131, + 119,1,185,183,168,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7, + 5,1,229,223,173,1,229,224,175,1,230,224,178,1,84,82,66,1,212,207, + 168,1,232,227,185,1,233,228,188,1,64,63,52,1,227,223,187,1,74,72, + 61,1,180,177,151,1,114,112,96,1,237,233,202,1,238,234,205,1,238,235, + 207,1,59,58,52,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239, + 220,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223, + 173,1,229,224,175,1,230,224,178,1,84,82,66,1,212,207,168,1,232,227, + 185,1,231,226,187,1,61,60,50,1,227,223,187,1,74,72,61,1,204,199, + 170,1,83,82,71,1,237,233,202,1,238,234,205,1,223,220,194,1,59,58, + 52,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240, + 222,1,243,241,224,1,28,28,26,1,103,100,77,1,229,223,173,1,229,224, + 175,1,230,224,178,1,84,82,66,1,212,207,168,1,232,227,185,1,167,164, + 135,1,106,104,86,1,227,223,187,1,74,72,61,1,234,229,195,1,45,45, + 38,1,229,225,195,1,238,234,205,1,159,157,138,1,110,108,96,1,240,237, + 212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241, + 224,1,7,7,7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224, + 178,1,84,82,66,1,86,84,68,1,82,80,65,1,40,39,32,1,208,205, + 170,1,227,223,187,1,74,72,61,1,236,231,197,1,164,161,139,1,33,32, + 28,1,94,93,81,1,35,34,30,1,225,222,198,1,240,237,212,1,240,238, + 215,1,241,238,217,1,242,239,220,1,243,240,222,1,243,241,224,1,7,7, + 7,1,228,222,171,1,229,223,173,1,229,224,175,1,230,224,178,1,195,190, + 152,1,173,169,137,1,182,178,145,1,225,220,181,1,233,229,190,1,232,228, + 191,1,195,192,162,1,236,231,197,1,236,232,200,1,216,212,184,1,172,169, + 148,1,231,228,201,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238, + 217,1,242,239,220,1,243,240,222,1,243,241,224,1,231,229,215,1,44,43, + 33,1,229,223,173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226, + 183,1,232,227,185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231, + 195,1,236,231,197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235, + 207,1,239,236,210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239, + 220,1,243,240,222,1,243,241,224,1,244,242,227,1,7,7,5,1,229,223, + 173,1,229,224,175,1,230,224,178,1,231,225,180,1,231,226,183,1,232,227, + 185,1,233,228,188,1,233,229,190,1,234,230,193,1,235,231,195,1,236,231, + 197,1,236,232,200,1,237,233,202,1,238,234,205,1,238,235,207,1,239,236, + 210,1,240,237,212,1,240,238,215,1,241,238,217,1,242,239,220,1,243,240, + 222,1,243,241,224,1,205,204,191,1,4,3,3,1,171,167,129,1,229,224, + 175,1,230,224,178,1,11,11,9,1,7,7,6,1,23,22,18,1,233,228, + 188,1,233,229,190,1,145,143,120,1,7,7,6,2,61,60,52,1,237,233, + 202,1,238,234,205,1,86,85,75,1,7,7,6,2,115,114,103,1,241,238, + 217,1,242,239,220,1,38,37,34,1,7,7,7,1,4,4,4,1,152,1, + 0,0,244,244,244,1,248,248,248,1,233,233,233,1,128,128,128,2,158,158, + 158,1,248,248,248,2,203,203,203,1,128,128,128,2,188,188,188,1,248,248, + 248,2,173,173,173,1,128,128,128,2,221,221,221,1,248,248,248,2,139,139, + 139,1,128,128,128,1,131,131,131,1,244,244,244,1,154,154,154,1,255,255, + 255,22,248,248,248,1,128,128,128,1,255,255,255,22,229,229,229,1,128,128, + 128,1,255,255,255,22,128,128,128,1,236,236,236,1,255,255,255,22,128,128, + 128,1,248,248,248,1,255,255,255,22,165,165,165,1,240,240,240,1,255,255, + 255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128, + 128,1,255,255,255,22,195,195,195,1,150,150,150,1,255,255,255,22,128,128, + 128,1,248,248,248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255, + 255,22,195,195,195,1,210,210,210,1,255,255,255,22,248,248,248,1,128,128, + 128,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,165,165, + 165,1,180,180,180,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255, + 255,22,128,128,128,1,248,248,248,1,255,255,255,22,229,229,229,1,176,176, + 176,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248, + 248,1,128,128,128,1,255,255,255,22,131,131,131,1,214,214,214,1,255,255, + 255,22,128,128,128,1,248,248,248,1,255,255,255,22,139,139,139,1,244,244, + 244,1,146,146,146,1,128,128,128,2,244,244,244,1,248,248,248,1,233,233, + 233,1,128,128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128, + 128,2,188,188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221, + 221,1,248,248,248,1,244,244,244,1,0,0) + ); + +const + objdata_tmidisource: record size: integer; data: array[0..1614] of byte end = + (size: 1615; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,109,105, + 100,105,115,111,117,114,99,101,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,216,5,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,228,1,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,3,208,208,208,2,0,0,0, + 4,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,4,208,208,208, + 1,0,0,0,3,208,208,208,22,0,0,0,1,208,208,208,23,0,0,0, + 1,208,208,208,24,0,0,0,1,208,208,208,23,0,0,0,1,208,208,208, + 22,0,0,0,2,208,208,208,22,0,0,0,1,208,208,208,23,0,0,0, + 1,208,208,208,2,0,0,0,2,208,208,208,3,0,0,0,5,208,208,208, + 1,0,0,0,5,208,208,208,3,0,0,0,4,208,208,208,1,0,0,0, + 3,208,208,208,2,0,0,0,5,208,208,208,1,0,0,0,6,208,208,208, + 2,0,0,0,2,208,208,208,1,0,0,0,1,208,208,208,1,0,0,0, + 3,208,208,208,2,0,0,0,5,208,208,208,1,0,0,0,2,208,208,208, + 2,0,0,0,3,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0, + 1,208,208,208,1,0,0,0,3,208,208,208,1,0,0,0,6,208,208,208, + 1,0,0,0,2,208,208,208,3,0,0,0,2,208,208,208,1,0,0,0, + 4,208,208,208,1,0,0,0,10,208,208,208,1,0,0,0,2,208,208,208, + 3,0,0,0,2,208,208,208,1,0,0,0,3,208,208,208,2,0,0,0, + 10,208,208,208,1,0,0,0,2,208,208,208,3,0,0,0,2,208,208,208, + 1,0,0,0,3,208,208,208,2,0,0,0,5,208,208,208,1,0,0,0, + 4,208,208,208,1,0,0,0,2,208,208,208,2,0,0,0,3,208,208,208, + 1,0,0,0,4,208,208,208,1,0,0,0,5,208,208,208,1,0,0,0, + 4,208,208,208,1,0,0,0,6,208,208,208,2,0,0,0,2,208,208,208, + 1,0,0,0,1,208,208,208,23,0,0,0,1,208,208,208,22,0,0,0, + 2,208,208,208,22,0,0,0,1,208,208,208,23,0,0,0,1,208,208,208, + 23,0,0,0,2,208,208,208,23,0,0,0,1,208,208,208,22,0,0,0, + 3,208,208,208,2,0,0,0,3,208,208,208,2,0,0,0,4,208,208,208, + 2,0,0,0,4,208,208,208,2,0,0,0,3,188,3,0,0,240,240,240, + 2,210,210,210,1,0,0,0,2,60,60,60,1,240,240,240,2,150,150,150, + 1,0,0,0,2,120,120,120,1,240,240,240,2,90,90,90,1,0,0,0, + 2,187,187,187,1,240,240,240,2,22,22,22,1,0,0,0,1,7,7,7, + 1,240,240,240,1,52,52,52,1,0,0,0,22,240,240,240,1,0,0,0, + 23,202,202,202,1,0,0,0,24,217,217,217,1,0,0,0,23,240,240,240, + 1,0,0,0,22,75,75,75,1,225,225,225,1,0,0,0,22,240,240,240, + 1,0,0,0,23,240,240,240,1,0,0,0,2,54,54,54,1,52,52,52, + 1,0,0,0,3,10,10,10,1,72,72,72,1,13,13,13,1,6,6,6, + 1,63,63,63,1,0,0,0,1,30,30,30,1,72,72,72,2,61,61,61, + 1,23,23,23,1,0,0,0,3,66,66,66,1,2,2,2,1,135,135,135, + 1,45,45,45,1,0,0,0,1,192,192,192,1,236,236,236,1,5,5,5, + 1,0,0,0,2,93,93,93,1,255,255,255,1,48,48,48,1,22,22,22, + 1,225,225,225,1,0,0,0,1,109,109,109,1,208,208,208,1,152,152,152, + 1,163,163,163,1,215,215,215,1,124,124,124,1,0,0,0,2,237,237,237, + 1,10,10,10,1,0,0,0,1,240,240,240,1,0,0,0,1,192,192,192, + 1,196,196,196,1,74,74,74,1,0,0,0,2,177,177,177,1,206,206,206, + 1,48,48,48,1,22,22,22,1,225,225,225,1,0,0,0,1,109,109,109, + 1,138,138,138,1,0,0,0,2,16,16,16,1,216,216,216,1,49,49,49, + 1,0,0,0,1,237,237,237,1,10,10,10,1,0,0,0,1,240,240,240, + 1,0,0,0,1,192,192,192,1,109,109,109,1,161,161,161,1,0,0,0, + 1,19,19,19,1,180,180,180,1,184,184,184,1,48,48,48,1,22,22,22, + 1,225,225,225,1,0,0,0,1,109,109,109,1,138,138,138,1,0,0,0, + 3,146,146,146,1,112,112,112,1,0,0,0,1,237,237,237,1,10,10,10, + 1,135,135,135,1,165,165,165,1,0,0,0,1,192,192,192,1,49,49,49, + 1,214,214,214,1,7,7,7,1,102,102,102,1,96,96,96,1,184,184,184, + 1,48,48,48,1,22,22,22,1,225,225,225,1,0,0,0,1,109,109,109, + 1,138,138,138,1,0,0,0,3,112,112,112,1,136,136,136,1,0,0,0, + 1,237,237,237,1,10,10,10,1,240,240,240,1,0,0,0,2,192,192,192, + 1,48,48,48,1,144,144,144,1,79,79,79,1,183,183,183,1,15,15,15, + 1,184,184,184,1,48,48,48,1,22,22,22,1,225,225,225,1,0,0,0, + 1,109,109,109,1,138,138,138,1,0,0,0,3,146,146,146,1,105,105,105, + 1,0,0,0,1,237,237,237,1,10,10,10,1,240,240,240,1,0,0,0, + 2,192,192,192,1,48,48,48,1,57,57,57,1,183,183,183,1,170,170,170, + 1,0,0,0,1,184,184,184,1,48,48,48,1,22,22,22,1,225,225,225, + 1,0,0,0,1,109,109,109,1,138,138,138,1,0,0,0,2,45,45,45, + 1,230,230,230,1,21,21,21,1,0,0,0,1,237,237,237,1,10,10,10, + 1,75,75,75,1,105,105,105,1,0,0,0,1,192,192,192,1,48,48,48, + 1,1,1,1,1,226,226,226,1,84,84,84,1,0,0,0,1,184,184,184, + 1,48,48,48,1,22,22,22,1,225,225,225,1,0,0,0,1,109,109,109, + 1,237,237,237,1,216,216,216,1,221,221,221,1,201,201,201,1,64,64,64, + 1,0,0,0,2,237,237,237,1,10,10,10,1,0,0,0,1,240,240,240, + 1,0,0,0,23,240,240,240,1,0,0,0,22,202,202,202,1,97,97,97, + 1,0,0,0,22,240,240,240,1,0,0,0,23,240,240,240,1,0,0,0, + 23,7,7,7,1,172,172,172,1,0,0,0,23,240,240,240,1,0,0,0, + 22,22,22,22,1,240,240,240,1,37,37,37,1,0,0,0,2,232,232,232, + 1,240,240,240,1,210,210,210,1,0,0,0,2,60,60,60,1,240,240,240, + 2,150,150,150,1,0,0,0,2,120,120,120,1,240,240,240,2,90,90,90, + 1,0,0,0,2,187,187,187,1,240,240,240,2,0,0) + ); + +const + objdata_taudioout: record size: integer; data: array[0..2048] of byte end = + (size: 2049; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,97,117, + 100,105,111,111,117,116,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,140,7,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,140,2,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,3,208,208,208,2,0,0,0,4,208, + 208,208,2,0,0,0,4,208,208,208,2,0,0,0,4,208,208,208,1,0, + 0,0,3,208,208,208,22,0,0,0,1,208,208,208,7,0,0,0,2,208, + 208,208,1,0,0,0,2,208,208,208,2,0,0,0,2,208,208,208,7,0, + 0,0,1,208,208,208,6,0,0,0,3,208,208,208,1,0,0,0,2,208, + 208,208,2,0,0,0,2,208,208,208,8,0,0,0,1,208,208,208,5,0, + 0,0,3,208,208,208,1,0,0,0,2,208,208,208,2,0,0,0,2,208, + 208,208,8,0,0,0,1,208,208,208,5,0,0,0,6,208,208,208,2,0, + 0,0,2,208,208,208,7,0,0,0,2,208,208,208,5,0,0,0,6,208, + 208,208,2,0,0,0,2,208,208,208,7,0,0,0,1,208,208,208,5,0, + 0,0,7,208,208,208,2,0,0,0,2,208,208,208,7,0,0,0,1,208, + 208,208,5,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,0, + 0,0,5,208,208,208,7,0,0,0,2,208,208,208,4,0,0,0,2,208, + 208,208,2,0,0,0,6,208,208,208,4,0,0,0,2,208,208,208,3,0, + 0,0,1,208,208,208,11,0,0,0,2,208,208,208,5,0,0,0,3,208, + 208,208,2,0,0,0,1,208,208,208,19,0,0,0,5,208,208,208,3,0, + 0,0,3,208,208,208,3,0,0,0,1,208,208,208,2,0,0,0,2,208, + 208,208,2,0,0,0,7,208,208,208,4,0,0,0,7,208,208,208,1,0, + 0,0,5,208,208,208,3,0,0,0,4,208,208,208,4,0,0,0,2,208, + 208,208,1,0,0,0,4,208,208,208,1,0,0,0,2,208,208,208,1,0, + 0,0,2,208,208,208,2,0,0,0,3,208,208,208,1,0,0,0,2,208, + 208,208,3,0,0,0,2,208,208,208,1,0,0,0,6,208,208,208,2,0, + 0,0,2,208,208,208,2,0,0,0,2,208,208,208,3,0,0,0,1,208, + 208,208,3,0,0,0,2,208,208,208,2,0,0,0,5,208,208,208,3,0, + 0,0,1,208,208,208,7,0,0,0,1,208,208,208,3,0,0,0,2,208, + 208,208,1,0,0,0,6,208,208,208,2,0,0,0,2,208,208,208,6,0, + 0,0,2,208,208,208,3,0,0,0,2,208,208,208,1,0,0,0,7,208, + 208,208,1,0,0,0,2,208,208,208,6,0,0,0,1,208,208,208,4,0, + 0,0,7,208,208,208,1,0,0,0,5,208,208,208,6,0,0,0,1,208, + 208,208,4,0,0,0,4,208,208,208,1,0,0,0,2,208,208,208,2,0, + 0,0,3,208,208,208,7,0,0,0,2,208,208,208,23,0,0,0,1,208, + 208,208,22,0,0,0,3,208,208,208,2,0,0,0,3,208,208,208,2,0, + 0,0,4,208,208,208,2,0,0,0,4,208,208,208,2,0,0,0,3,200, + 4,0,0,240,240,240,2,210,210,210,1,0,0,0,2,60,60,60,1,240, + 240,240,2,150,150,150,1,0,0,0,2,120,120,120,1,240,240,240,2,90, + 90,90,1,0,0,0,2,187,187,187,1,240,240,240,2,22,22,22,1,0, + 0,0,1,7,7,7,1,240,240,240,1,52,52,52,1,0,0,0,22,240, + 240,240,1,0,0,0,7,53,53,53,1,8,8,8,1,0,0,0,1,7, + 7,7,1,44,44,44,1,0,0,0,2,39,39,39,1,12,12,12,1,0, + 0,0,7,202,202,202,1,0,0,0,6,1,1,1,1,219,219,219,1,81, + 81,81,1,0,0,0,1,27,27,27,1,156,156,156,1,0,0,0,2,139, + 139,139,1,44,44,44,1,0,0,0,8,217,217,217,1,0,0,0,5,52, + 52,52,1,140,140,140,1,158,158,158,1,0,0,0,1,27,27,27,1,156, + 156,156,1,0,0,0,2,139,139,139,1,44,44,44,1,0,0,0,8,240, + 240,240,1,0,0,0,5,124,124,124,1,56,56,56,1,184,184,184,1,2, + 2,2,1,27,27,27,1,156,156,156,1,0,0,0,2,139,139,139,1,44, + 44,44,1,0,0,0,7,75,75,75,1,225,225,225,1,0,0,0,5,179, + 179,179,1,2,2,2,1,129,129,129,1,59,59,59,1,27,27,27,1,156, + 156,156,1,0,0,0,2,139,139,139,1,44,44,44,1,0,0,0,7,240, + 240,240,1,0,0,0,5,17,17,17,1,231,231,231,1,208,208,208,1,213, + 213,213,1,137,137,137,1,10,10,10,1,169,169,169,1,0,0,0,2,166, + 166,166,1,29,29,29,1,0,0,0,7,240,240,240,1,0,0,0,5,86, + 86,86,1,101,101,101,1,0,0,0,1,3,3,3,1,197,197,197,1,0, + 0,0,1,195,195,195,1,7,7,7,1,9,9,9,1,207,207,207,1,4, + 4,4,1,0,0,0,7,135,135,135,1,45,45,45,1,0,0,0,4,158, + 158,158,1,31,31,31,1,0,0,0,2,167,167,167,1,37,37,37,1,93, + 93,93,1,217,217,217,1,224,224,224,1,101,101,101,1,0,0,0,4,115, + 115,115,1,60,60,60,1,0,0,0,3,240,240,240,1,0,0,0,11,5, + 5,5,1,7,7,7,1,0,0,0,5,60,60,60,1,231,231,231,1,60, + 60,60,1,0,0,0,2,240,240,240,1,0,0,0,19,60,60,60,1,231, + 231,231,1,60,60,60,1,135,135,135,1,165,165,165,1,0,0,0,3,5, + 5,5,1,8,8,8,1,2,2,2,1,0,0,0,3,5,5,5,1,0, + 0,0,2,3,3,3,1,18,18,18,1,0,0,0,2,255,255,255,5,199, + 199,199,1,240,240,240,1,0,0,0,4,162,162,162,1,219,219,219,1,221, + 221,221,1,177,177,177,1,9,9,9,1,8,8,8,1,175,175,175,1,0, + 0,0,1,55,55,55,1,229,229,229,1,200,200,200,1,166,166,166,1,2, + 2,2,1,0,0,0,3,60,60,60,1,231,231,231,1,60,60,60,1,240, + 240,240,1,0,0,0,4,162,162,162,1,21,21,21,1,0,0,0,1,110, + 110,110,1,112,112,112,1,8,8,8,1,175,175,175,1,0,0,0,1,200, + 200,200,1,35,35,35,1,0,0,0,1,106,106,106,1,113,113,113,1,0, + 0,0,2,60,60,60,1,231,231,231,1,60,60,60,1,0,0,0,1,75, + 75,75,1,105,105,105,1,0,0,0,3,162,162,162,1,21,21,21,1,0, + 0,0,1,14,14,14,1,178,178,178,1,8,8,8,1,175,175,175,1,33, + 33,33,1,188,188,188,1,0,0,0,2,4,4,4,1,182,182,182,1,0, + 0,0,2,115,115,115,1,60,60,60,1,0,0,0,3,240,240,240,1,0, + 0,0,3,162,162,162,1,21,21,21,1,0,0,0,2,185,185,185,1,8, + 8,8,1,175,175,175,1,60,60,60,1,132,132,132,1,0,0,0,3,192, + 192,192,1,0,0,0,7,240,240,240,1,0,0,0,3,162,162,162,1,21, + 21,21,1,0,0,0,1,2,2,2,1,188,188,188,1,8,8,8,1,175, + 175,175,1,35,35,35,1,165,165,165,1,0,0,0,2,16,16,16,1,192, + 192,192,1,0,0,0,6,202,202,202,1,97,97,97,1,0,0,0,3,162, + 162,162,1,21,21,21,1,0,0,0,1,72,72,72,1,139,139,139,1,8, + 8,8,1,175,175,175,1,2,2,2,1,206,206,206,1,9,9,9,1,0, + 0,0,1,85,85,85,1,138,138,138,1,0,0,0,6,240,240,240,1,0, + 0,0,4,162,162,162,1,160,160,160,1,165,165,165,1,211,211,211,1,27, + 27,27,1,8,8,8,1,175,175,175,1,0,0,0,1,78,78,78,1,220, + 220,220,1,154,154,154,1,218,218,218,1,15,15,15,1,0,0,0,6,240, + 240,240,1,0,0,0,4,40,40,40,1,64,64,64,1,55,55,55,1,9, + 9,9,1,0,0,0,1,2,2,2,1,43,43,43,1,0,0,0,2,23, + 23,23,1,71,71,71,1,8,8,8,1,0,0,0,7,7,7,7,1,172, + 172,172,1,0,0,0,23,240,240,240,1,0,0,0,22,22,22,22,1,240, + 240,240,1,37,37,37,1,0,0,0,2,232,232,232,1,240,240,240,1,210, + 210,210,1,0,0,0,2,60,60,60,1,240,240,240,2,150,150,150,1,0, + 0,0,2,120,120,120,1,240,240,240,2,90,90,90,1,0,0,0,2,187, + 187,187,1,240,240,240,2,0,0) + ); + +initialization + registerobjectdata(@objdata_tfft,tbitmapcomp,'tfft'); + registerobjectdata(@objdata_tsigcontroller,tbitmapcomp,'tsigcontroller'); + registerobjectdata(@objdata_tsigadd,tbitmapcomp,'tsigadd'); + registerobjectdata(@objdata_tsigmult,tbitmapcomp,'tsigmult'); + registerobjectdata(@objdata_tsigdelay,tbitmapcomp,'tsigdelay'); + registerobjectdata(@objdata_tsigdelayn,tbitmapcomp,'tsigdelayn'); + registerobjectdata(@objdata_tsigdelayvar,tbitmapcomp,'tsigdelayvar'); + registerobjectdata(@objdata_tsigfir,tbitmapcomp,'tsigfir'); + registerobjectdata(@objdata_tsigiir,tbitmapcomp,'tsigiir'); + registerobjectdata(@objdata_tsigfft,tbitmapcomp,'tsigfft'); + registerobjectdata(@objdata_tsigin,tbitmapcomp,'tsigin'); + registerobjectdata(@objdata_tsigout,tbitmapcomp,'tsigout'); + registerobjectdata(@objdata_tsigconnector,tbitmapcomp,'tsigconnector'); + registerobjectdata(@objdata_ttrigconnector,tbitmapcomp,'ttrigconnector'); + registerobjectdata(@objdata_tsigwavetable,tbitmapcomp,'tsigwavetable'); + registerobjectdata(@objdata_tsigfuncttable,tbitmapcomp,'tsigfuncttable'); + registerobjectdata(@objdata_tsigenvelope,tbitmapcomp,'tsigenvelope'); + registerobjectdata(@objdata_tsigsampler,tbitmapcomp,'tsigsampler'); + registerobjectdata(@objdata_tsigsamplerfft,tbitmapcomp,'tsigsamplerfft'); + registerobjectdata(@objdata_tsigfilter,tbitmapcomp,'tsigfilter'); + registerobjectdata(@objdata_tsigfilterbank,tbitmapcomp,'tsigfilterbank'); + registerobjectdata(@objdata_tsigkeyboard,tbitmapcomp,'tsigkeyboard'); + registerobjectdata(@objdata_twavetableedit,tbitmapcomp,'twavetableedit'); + registerobjectdata(@objdata_tfuncttableedit,tbitmapcomp,'tfuncttableedit'); + registerobjectdata(@objdata_tffttableedit,tbitmapcomp,'tffttableedit'); + registerobjectdata(@objdata_tenvelopeedit,tbitmapcomp,'tenvelopeedit'); + registerobjectdata(@objdata_tsigscope,tbitmapcomp,'tsigscope'); + registerobjectdata(@objdata_tsigscopefft,tbitmapcomp,'tsigscopefft'); + registerobjectdata(@objdata_tsignoise,tbitmapcomp,'tsignoise'); + registerobjectdata(@objdata_tsigmidisource,tbitmapcomp,'tsigmidisource'); + registerobjectdata(@objdata_tsigmidiconnector,tbitmapcomp,'tsigmidiconnector'); + registerobjectdata(@objdata_tsigmidimulticonnector,tbitmapcomp,'tsigmidimulticonnector'); + registerobjectdata(@objdata_tsigoutaudio,tbitmapcomp,'tsigoutaudio'); + registerobjectdata(@objdata_tmidisource,tbitmapcomp,'tmidisource'); + registerobjectdata(@objdata_taudioout,tbitmapcomp,'taudioout'); +end. diff --git a/mseide-msegui/lib/common/regcomponents/regmm.pas b/mseide-msegui/lib/common/regcomponents/regmm.pas new file mode 100644 index 0000000..22e1622 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regmm.pas @@ -0,0 +1,33 @@ +{ MSEide Copyright (c) 2010 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regmm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +implementation +uses + mseaudio,msedesignintf,msesigaudio,msemidi,msesigmidi,msespeak; + +procedure register; +begin + registercomponents('MM',[taudioout,tmidisource,tespeakng]); + registercomponenttabhints(['MM'],['Multimedia components (experimental).']); + registercomponents('Math',[tsigoutaudio,tsigmidiconnector,tsigmidisource]); +end; + +initialization + register; +end. diff --git a/mseide-msegui/lib/common/regcomponents/regpascalscript.pas b/mseide-msegui/lib/common/regcomponents/regpascalscript.pas new file mode 100644 index 0000000..d32d339 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regpascalscript.pas @@ -0,0 +1,277 @@ +{ MSEide Copyright (c) 1999-2013 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regpascalscript; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +implementation +uses + classes,mclasses,msedesignintf,msepascalscript,msepascimport, + msepropertyeditors,msetypes,msestrings, + msetexteditor,mseglob,mseguiglob,msegui,msewidgets,uPSComponent, + uPSComponent_Default, + msepascimportmsegui,formdesigner,sourceupdate,mseparser,pascaldesignparser, + msedesigner,mserichstring,mseclasses,msedesignparser; +type + tpascaleditor = class(ttextstringspropertyeditor) + protected + function getscript: tpasc; virtual; + function getsyntaxindex: integer; override; + procedure doafterclosequery(var amodalresult: modalresultty); override; + function gettestbutton: boolean; override; + function getcaption: msestring; override; + end; + + tpascformeditor = class(tpascaleditor) + private + fmoduleprefix: ansistring; + protected + function getscript: tpasc; override; + procedure doafterclosequery(var amodalresult: modalresultty); override; + procedure updateline(var aline: ansistring); override; + public + procedure edit; override; + end; + +function sourcetoformscript(const amodule: tmsecomponent; + const asource: trichstringdatalist): boolean; forward; +const + pascformintf: designmoduleintfty = + (createfunc: {$ifdef FPC}@{$endif}createpascform; + initnewcomponent: nil; getscale: nil; sourcetoform: @sourcetoformscript); + +procedure Register; +begin + registerclass(tpascform); + registercomponents('PaSc',[tpasc,tpascdllplugin,tpascimport_classes, + tpascimport_dateutils,tpascimportmsegui]); + registerpropertyeditor(typeinfo(tstrings),tpasc,'Script',tpascaleditor); + registerpropertyeditor(typeinfo(tstrings),tpascform,'pasc_script', + tpascformeditor); + registerdesignmoduleclass(tpascform,@pascformintf); + registercomponenttabhints(['PaSc'], + ['Experimental PascalScript Components']); +end; + +procedure doupdateline(aline: pchar; const moduleprefix: ansistring); +var //todo: patch PascalScript to accept classname + int1: integer; + po1,po2,po3: pchar; +begin //remove module prefix + if (moduleprefix <> '') and (aline <> nil) then begin + po1:= pchar(aline); + while po1^ <> #0 do begin + po2:= pchar(moduleprefix); + po3:= po1; + while (upperchars[po1^] = po2^) and (po1^ <> #0) do begin + inc(po1); + inc(po2); + end; + if po2^ = #0 then begin //found + for int1:= 0 to (po2 - pchar(moduleprefix)) - 1 do begin + po3[int1]:= ' '; + end; + end + else begin + po1:= po3+1; //next char + end; + end; + end; +end; + +function sourcetoformscript(const amodule: tmsecomponent; + const asource: trichstringdatalist): boolean; +var + bo1: boolean; + po1: punitinfoty; + po2: pmoduleinfoty; + mstr1: msestring; + start,stop: sourceposty; + prefix: ansistring; + int1: integer; +begin + bo1:= getimplementationtext(amodule,po1,start,stop,mstr1); + if bo1 then begin + po2:= designer.modules.findmodule(amodule); + prefix:= struppercase(po2^.moduleclassname)+'.'; + with tpascform(amodule).script.script do begin + text:= mstr1; + for int1:= 0 to count - 1 do begin + doupdateline(pchar(strings[int1]),prefix); + end; + end; + designer.componentmodified(amodule); + end; + result:= true; +end; + +var + pascalindex: integer = -1; +const + pascalsyntax = +'caseinsensitive'+lineend+ +'styles'+lineend+ +' default '''''+lineend+ +' words ''b'''+lineend+ +' comment ''i'' cl_dkblue'+lineend+ +' option ''b'' cl_dkblue'+lineend+ +' string '''' cl_dkblue'+lineend+ + +'keyworddefs pascal'+lineend+ +' ''ABSOLUTE'' ''ABSTRACT'' ''AND'' ''ARRAY'' ''AS'' ''ASM'' ''ASSEMBLER'' ''BEGIN'''+lineend+ +' ''BREAK'' ''CASE'' ''CDECL'' ''CLASS'' ''CONST'' ''CONSTRUCTOR'''+lineend+ +' ''CONTINUE'' ''DEFAULT'' ''DESTRUCTOR'' ''DISPOSE'' ''DIV'' ''DO'' ''DOWNTO'''+lineend+ +' ''ELSE'' ''END'' ''EXCEPT'' ''EXIT'' ''EXPORT'' ''EXPORTS'' ''EXTERNAL'' ''FAIL'''+lineend+ +' ''FALSE'' ''FAR'' ''FILE'' ''FINALIZATION'' ''FINALLY'' ''FOR'' ''FORWARD'' ''FUNCTION'' ''GOTO'' ''IF'''+lineend+ +' ''IMPLEMENTATION'' ''IN'' ''INDEX'' ''INHERITED'''+lineend+ +' ''INITIALIZATION'' ''INLINE'' ''INTERFACE'' ''INTERRUPT'' ''IS'' ''LABEL'' ''LIBRARY'''+lineend+ +' ''MOD'' ''NEW'' ''NIL'' ''NODEFAULT'' ''NOT'' ''OBJECT'''+lineend+ +' ''OF'' ''ON'' ''OPERATOR'' ''OR'' ''OUT'' ''OTHERWISE'' ''PACKED'' ''POPSTACK'' ''PRIVATE'' '+lineend+ +' ''PROCEDURE'' ''PROGRAM'' ''PROPERTY'' ''PROTECTED'''+lineend+ +' ''PUBLIC'' ''PUBLISHED'' ''RAISE'' ''READ'' ''RECORD'' ''REINTRODUCE'' ''REPEAT'' '+lineend+ +' ''RESOURCESTRING'''+lineend+ +' ''SELF'' ''SET'' ''SHL'' ''SHR'''+lineend+ +' ''STDCALL'' ''STORED'' ''THEN'' ''THREADVAR'' ''TO'' ''TRUE'' ''TRY'' ''TYPE'' ''UNIT'' ''UNTIL'''+lineend+ +' ''USES'' ''VAR'' ''VIRTUAL'' ''WHILE'' ''WITH'' ''WRITE'' ''XOR'''+lineend+ +' ''OVERLOAD'' ''OVERRIDE'''+lineend+ + +'scope option option'+lineend+ +' endtokens'+lineend+ +' ''}'''+lineend+ + +'scope comment1 comment'+lineend+ +' endtokens'+lineend+ +' ''}'''+lineend+ + +'scope comment2 comment'+lineend+ +' endtokens'+lineend+ +' '''''+lineend+ + +'scope comment3 comment'+lineend+ +' endtokens'+lineend+ +' ''*)'''+lineend+ + +'scope string string'+lineend+ +' endtokens'+lineend+ +' '''''''' '''''+lineend+ + +'scope string1 string'+lineend+ +' calltokens'+lineend+ +' '''''''' string'+lineend+ +' endtokens'+lineend+ +' '' '' '''''+lineend+ + +'scope main'+lineend+ + +' keywords words'+lineend+ +' pascal'+lineend+ + +' calltokens'+lineend+ +' ''{$'' option'+lineend+ +' ''{'' comment1'+lineend+ +' ''//'' comment2'+lineend+ +' ''(*'' comment3'+lineend+ +' '''''''' string'+lineend+ +' ''#'' string1'; + + +{ tpascaleditor } + +function tpascaleditor.getscript: tpasc; +begin + result:= tpasc(getordvalue(0)); +end; + +procedure tpascaleditor.doafterclosequery(var amodalresult: modalresultty); +begin + if amodalresult = mr_canclose then begin + with getscript do begin + if compile then begin +// showmessage('Compile OK'); + end + else begin + showmessage(compilermessagetext,'Compile Error'); + amodalresult:= mr_none; + end; + end; + end; +end; + +function tpascaleditor.gettestbutton: boolean; +begin + result:= true; +end; + +function tpascaleditor.getcaption: msestring; +begin + result:= 'PascalScript Editor'; +end; + +function tpascaleditor.getsyntaxindex: integer; +begin + if pascalindex < 0 then begin + pascalindex:= msetexteditor.syntaxpainter.readdeffile(pascalsyntax); + end; + result:= pascalindex; +end; + +{ tpascformeditor } + +function tpascformeditor.getscript: tpasc; +begin + result:= tpascform(component).script; +end; + +procedure tpascformeditor.edit; +var + bo1: boolean; + po1: punitinfoty; + po2: pmoduleinfoty; + mstr1: msestring; + start,stop: sourceposty; +begin + bo1:= getimplementationtext(fmodule,po1,start,stop,mstr1); + if bo1 then begin + po2:= designer.modules.findmodule(fmodule); + fmoduleprefix:= struppercase(po2^.moduleclassname)+'.'; + getscript.script.text:= mstr1; + end + else begin + fmoduleprefix:= ''; + end; + inherited; + if bo1 and (fmodalresult = mr_ok) then begin + sourceupdater.replacetext(po1,start,stop, + concatstrings(forigtext,msestring(lineend))+lineend); + end; +end; + +procedure tpascformeditor.doafterclosequery(var amodalresult: modalresultty); +begin + if amodalresult in [mr_canclose,mr_ok] then begin + end; + inherited; +end; + +procedure tpascformeditor.updateline(var aline: ansistring); + //todo: patch PascalScript to accept classname +begin + doupdateline(pchar(aline),fmoduleprefix); +end; + +initialization + register; +end. diff --git a/mseide-msegui/lib/common/regcomponents/regprinter.pas b/mseide-msegui/lib/common/regcomponents/regprinter.pas new file mode 100644 index 0000000..501d441 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regprinter.pas @@ -0,0 +1,32 @@ +{ MSEide Copyright (c) 1999-2010 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regprinter; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +implementation +uses + mseprinter,msepostscriptprinter,msegdiprint,msedesignintf; + +procedure Register; +begin + registercomponents('Gui',[tpostscriptprinter,tgdiprinter,twmfprinter]); + registercomponents('Dialog',[tpagesizeselector,tpageorientationselector]); +end; + +initialization + register; +end. diff --git a/mseide-msegui/lib/common/regcomponents/regreport.pas b/mseide-msegui/lib/common/regcomponents/regreport.pas new file mode 100644 index 0000000..9c816b5 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regreport.pas @@ -0,0 +1,182 @@ +{ MSEide Copyright (c) 1999-2016 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regreport; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface + +implementation +uses + classes,mclasses,msereport,msedesignintf,formdesigner,reportdesigner, + msepropertyeditors,mseformatstr,mserepps,msedrawtext, + sysutils,msetypes{msestrings},regreport_bmp,regdb,mselookupbuffer; +const + reportintf: designmoduleintfty = + (createfunc: {$ifdef FPC}@{$endif}createreport; + initnewcomponent: {$ifdef FPC}@{$endif}initreportcomponent; + getscale: {$ifdef FPC}@{$endif}getreportscale; + sourcetoform: nil); + reppageformintf: designmoduleintfty = + (createfunc: @createreppageform; + initnewcomponent: nil; + getscale: @getreppageformscale; + sourcetoform: nil); + +type + treptabulators1 = class(treptabulators); + treptabulatoritem1 = class(treptabulatoritem); + + treptabulatoreditor = class(tclasselementeditor) + public + function getvalue: msestring; override; + end; + + treptabulatorseditor = class(tpersistentarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + procedure itemfocused(const sender: tarrayelementeditor) override; + procedure resetactivetab(); + public + destructor destroy(); override; + end; + +procedure Register; +begin + registerclass(treport); + registerclass(treportpage); + registerclass(treppageform); + registercomponents('Rep',[treportpage,tbandarea,ttilearea,tbandgroup, + trecordband, + trepvaluedisp,treppagenumdisp,trepprintdatedisp, + {trepstringdisplb,trepintegerdisplb,treprealdisplb, + trepdatetimedisplb,} + trepspacer,treppsdisp]); + registercomponenttabhints(['Rep'],['Report components']); + + registerdesignmoduleclass(treport,@reportintf,treportdesignerfo); + registerdesignmoduleclass(treppageform,@reppageformintf,treportdesignerfo); + registerpropertyeditor(typeinfo(treptabulators),nil,'',treptabulatorseditor); + registerpropertyeditor(typeinfo(tcustomrecordband),treptabulators,'linksource', + tlocallinkcomponentpropertyeditor); +// registerpropertyeditor(typeinfo(string),tcustomreplookupdisp,'keydatafield', +// tdbfieldnamepropertyeditor); + registerpropertyeditor(typeinfo(string),tcustomrecordband,'visidatafield', + tdbfieldnamepropertyeditor); + registerpropertyeditor(typeinfo(string),tcustomrecordband,'visigroupfield', + tdbfieldnamepropertyeditor); + registerpropertyeditor(typeinfo(tcustomrecordband),tcustomrecordband,'nextband', + tsisterwidgetpropertyeditor); + registerpropertyeditor(typeinfo(tcustomrecordband),tcustomrecordband,'nextbandifempty', + tsisterwidgetpropertyeditor); +end; + +{ treptabulatoreditor } + +function treptabulatoreditor.getvalue: msestring; +var + mstr1: msestring; +begin + with treptabulatoritem(getpointervalue) do begin + if datafield = '' then begin + if ifilink <> nil then begin + mstr1:= msestring(ifilink.name); + end + else begin + mstr1:= value; + end; + end + else begin + mstr1:= ''; + if datasource <> nil then begin + mstr1:= msestring(datasource.name+'.'); + end; + mstr1:= mstr1+msestring(datafield); + if (lookupbuffer <> nil) and (lookupbuffer is tdblookupbuffer) and + (lookupvaluefieldno >= 0) then begin + with tdblookupbuffer(lookupbuffer) do begin + case lookupkind of + lk_text: begin + if lookupvaluefieldno < lookupbuffer.fieldcounttext then begin + mstr1:= mstr1+'><'+msestring(textfields[lookupvaluefieldno]); + end; + end; + lk_integer: begin + if lookupvaluefieldno < lookupbuffer.fieldcountinteger then begin + mstr1:= mstr1+'><'+msestring(integerfields[lookupvaluefieldno]); + end; + end; + lk_float,lk_date,lk_time,lk_datetime: begin + if lookupvaluefieldno < lookupbuffer.fieldcountfloat then begin + mstr1:= mstr1+'><'+msestring(floatfields[lookupvaluefieldno]); + end; + end; + end; + end; + end; + end; + result:= '<'+formatfloatmse(pos,'0.0')+'><'+mstr1+'>'; + end; +end; + +{ treptabulatorseditor } + +destructor treptabulatorseditor.destroy(); +begin + resetactivetab(); + inherited; +end; + +procedure treptabulatorseditor.resetactivetab(); +var + i1,i2: int32; + p1: treptabulators1; +begin + for i1:= 0 to high(fprops) do begin + p1:= treptabulators1(getpointervalue(i1)); + for i2:= 0 to p1.count - 1 do begin + with treptabulatoritem1(p1.fitems[i2]) do begin + exclude(fstate,tas_editactive); + end; + end; + p1.fband.invalidate(); + end; +end; + +function treptabulatorseditor.geteditorclass: propertyeditorclassty; +begin + result:= treptabulatoreditor; +end; + +procedure treptabulatorseditor.itemfocused(const sender: tarrayelementeditor); +var + i1: int32; + p1: treptabulators1; +begin + resetactivetab(); + for i1:= 0 to high(fprops) do begin + p1:= treptabulators1(getpointervalue(i1)); + if p1.count > sender.index then begin + with treptabulatoritem1(p1.fitems[sender.index]) do begin + include(fstate,tas_editactive); + end; + end; + end; + inherited; +end; + +initialization + register; +end. diff --git a/mseide-msegui/lib/common/regcomponents/regreport_bmp.pas b/mseide-msegui/lib/common/regcomponents/regreport_bmp.pas new file mode 100644 index 0000000..139eeb8 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regreport_bmp.pas @@ -0,0 +1,387 @@ +unit regreport_bmp; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msebitmap; + +const + objdata_treportpage: record size: integer; data: array[0..1730] of byte end = + (size: 1731; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,114,101, + 112,111,114,116,112,97,103,101,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,76,6,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,24,5,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,14,14,14,1,15,15,15,1,45,45,45, + 1,255,255,255,2,195,195,195,1,15,15,15,2,105,105,105,1,255,255,255, + 2,135,135,135,1,15,15,15,2,165,165,165,1,255,255,255,2,68,68,68, + 1,15,15,15,2,233,233,233,1,255,255,255,1,248,248,248,1,15,15,15, + 1,200,200,200,1,255,255,255,22,15,15,15,1,255,255,255,23,53,53,53, + 1,255,255,255,3,245,245,245,1,135,135,135,2,137,137,137,1,163,163,163, + 1,238,238,238,1,255,255,255,1,189,189,189,1,135,135,135,4,244,244,244, + 1,189,189,189,1,135,135,135,1,136,136,136,1,146,146,146,1,216,216,216, + 1,255,255,255,3,36,36,36,1,255,255,255,2,234,234,234,1,46,46,46, + 1,191,191,191,1,190,190,190,1,139,139,139,1,52,52,52,1,255,255,255, + 1,113,113,113,1,125,125,125,1,175,175,175,3,248,248,248,1,113,113,113, + 1,119,119,119,1,175,175,175,1,165,165,165,1,39,39,39,1,221,221,221, + 1,255,255,255,2,14,14,14,1,255,255,255,2,234,234,234,1,61,61,61, + 1,255,255,255,2,253,253,253,1,37,37,37,1,251,251,251,1,113,113,113, + 1,182,182,182,1,255,255,255,4,113,113,113,1,174,174,174,1,255,255,255, + 2,105,105,105,1,180,180,180,1,255,255,255,1,180,180,180,1,28,28,28, + 1,255,255,255,2,234,234,234,1,23,23,23,1,95,95,95,1,93,93,93, + 1,72,72,72,1,146,146,146,1,255,255,255,1,113,113,113,1,51,51,51, + 1,71,71,71,2,94,94,94,1,255,255,255,1,113,113,113,1,103,103,103, + 1,151,151,151,1,120,120,120,1,48,48,48,1,247,247,247,1,255,255,255, + 1,15,15,15,1,255,255,255,3,234,234,234,1,53,53,53,1,223,223,223, + 1,172,172,172,1,67,67,67,1,244,244,244,1,255,255,255,1,113,113,113, + 1,177,177,177,1,247,247,247,2,248,248,248,1,255,255,255,1,113,113,113, + 1,109,109,109,1,160,160,160,1,200,200,200,1,254,254,254,1,255,255,255, + 2,15,15,15,1,255,255,255,3,234,234,234,1,61,61,61,1,255,255,255, + 2,142,142,142,1,93,93,93,1,255,255,255,1,113,113,113,1,182,182,182, + 1,255,255,255,4,113,113,113,1,174,174,174,1,255,255,255,5,120,120,120, + 1,208,208,208,1,255,255,255,2,234,234,234,1,61,61,61,1,255,255,255, + 2,253,253,253,1,57,57,57,1,183,183,183,1,113,113,113,1,45,45,45, + 1,63,63,63,3,207,207,207,1,113,113,113,1,174,174,174,1,255,255,255, + 6,14,14,14,1,255,255,255,23,14,14,14,1,255,255,255,22,120,120,120, + 1,87,87,87,1,255,255,255,2,249,249,249,1,199,199,199,2,203,203,203, + 1,234,234,234,1,255,255,255,2,254,254,254,1,200,200,200,1,255,255,255, + 5,221,221,221,1,189,189,189,1,233,233,233,1,255,255,255,3,15,15,15, + 1,255,255,255,3,226,226,226,1,26,26,26,1,111,111,111,1,110,110,110, + 1,52,52,52,1,159,159,159,1,255,255,255,1,192,192,192,1,22,22,22, + 1,190,190,190,1,255,255,255,2,245,245,245,1,68,68,68,1,107,107,107, + 1,137,137,137,1,60,60,60,1,167,167,167,1,255,255,255,2,15,15,15, + 1,255,255,255,3,226,226,226,1,61,61,61,1,255,255,255,2,218,218,218, + 1,63,63,63,1,255,255,255,1,95,95,95,1,167,167,167,1,86,86,86, + 1,255,255,255,2,113,113,113,1,166,166,166,1,255,255,255,2,244,244,244, + 1,107,107,107,1,255,255,255,2,180,180,180,1,146,146,146,1,255,255,255, + 2,226,226,226,1,51,51,51,1,215,215,215,1,205,205,205,1,113,113,113, + 1,127,127,127,1,242,242,242,1,58,58,58,1,255,255,255,1,53,53,53, + 1,232,232,232,1,255,255,255,1,49,49,49,1,239,239,239,1,255,255,255, + 1,249,249,249,1,244,244,244,1,241,241,241,1,255,255,255,3,14,14,14, + 1,255,255,255,2,226,226,226,1,23,23,23,1,95,95,95,1,109,109,109, + 1,179,179,179,1,247,247,247,1,155,155,155,1,73,73,73,1,151,151,151, + 1,73,73,73,1,134,134,134,1,255,255,255,1,42,42,42,1,238,238,238, + 1,255,255,255,1,129,129,129,1,71,71,71,1,15,15,15,1,240,240,240, + 1,255,255,255,2,14,14,14,1,255,255,255,2,226,226,226,1,61,61,61, + 1,255,255,255,4,61,61,61,1,175,175,175,1,183,183,183,1,178,178,178, + 1,39,39,39,1,253,253,253,1,107,107,107,1,156,156,156,1,255,255,255, + 3,53,53,53,1,240,240,240,1,255,255,255,1,53,53,53,1,154,154,154, + 1,255,255,255,2,226,226,226,1,61,61,61,1,255,255,255,3,215,215,215, + 1,70,70,70,1,255,255,255,3,85,85,85,1,182,182,182,1,243,243,243, + 1,65,65,65,1,100,100,100,1,137,137,137,1,74,74,74,1,86,86,86, + 1,250,250,250,1,255,255,255,1,15,15,15,1,255,255,255,3,248,248,248, + 1,207,207,207,1,255,255,255,3,230,230,230,1,223,223,223,1,255,255,255, + 3,228,228,228,1,221,221,221,1,255,255,255,1,254,254,254,1,212,212,212, + 1,174,174,174,1,221,221,221,1,255,255,255,3,15,15,15,1,255,255,255, + 23,248,248,248,1,80,80,80,1,255,255,255,23,14,14,14,1,255,255,255, + 22,233,233,233,1,14,14,14,1,217,217,217,1,255,255,255,2,22,22,22, + 1,15,15,15,1,44,44,44,1,255,255,255,2,194,194,194,1,15,15,15, + 2,103,103,103,1,255,255,255,2,133,133,133,1,15,15,15,2,163,163,163, + 1,255,255,255,2,67,67,67,1,15,15,15,2,252,0,0,0,254,254,254, + 1,255,255,255,23,243,243,243,1,255,255,255,23,240,240,240,1,255,255,255, + 23,240,240,240,1,255,255,255,23,253,253,253,1,255,255,255,23,254,254,254, + 1,255,255,255,23,253,253,253,1,255,255,255,23,240,240,240,1,255,255,255, + 23,240,240,240,1,255,255,255,23,243,243,243,1,255,255,255,23,254,254,254, + 1,255,255,255,23,254,254,254,1,255,255,255,23,250,250,250,1,255,255,255, + 23,240,240,240,1,255,255,255,23,240,240,240,1,255,255,255,23,246,246,246, + 1,255,255,255,23,254,254,254,1,255,255,255,23,254,254,254,1,255,255,255, + 23,246,246,246,1,255,255,255,23,240,240,240,1,255,255,255,23,240,240,240, + 1,255,255,255,23,250,250,250,1,255,255,255,23,254,254,254,1,255,255,255, + 23,254,254,254,1,249,249,249,1,248,248,248,2,254,254,254,1,255,255,255, + 1,254,254,254,1,248,248,248,2,250,250,250,1,255,255,255,2,252,252,252, + 1,248,248,248,2,251,251,251,1,255,255,255,2,250,250,250,1,248,248,248, + 2,253,253,253,1,255,255,255,2,0,0) + ); + +const + objdata_tbandarea: record size: integer; data: array[0..445] of byte end = + (size: 446; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,98,97, + 110,100,97,114,101,97,12,98,105,116,109,97,112,46,105,109,97,103,101,10, + 144,1,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0,0,0, + 92,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,255,50, + 0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0,2, + 255,255,255,2,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,1, + 0,0,0,1,255,0,255,4,0,0,0,1,255,255,255,18,0,0,0,1, + 255,0,255,4,255,255,255,20,255,0,255,4,255,255,255,1,143,143,143,18, + 255,255,255,1,255,0,255,4,0,0,0,1,255,255,255,18,0,0,0,1, + 255,0,255,4,0,0,0,1,255,255,255,18,0,0,0,1,255,0,255,4, + 255,255,255,1,143,143,143,18,255,255,255,1,255,0,255,4,255,255,255,20, + 255,0,255,4,0,0,0,1,255,255,255,18,0,0,0,1,255,0,255,4, + 0,0,0,1,143,143,143,18,0,0,0,1,255,0,255,4,255,255,255,20, + 255,0,255,4,255,255,255,20,255,0,255,4,0,0,0,1,143,143,143,18, + 0,0,0,1,255,0,255,4,0,0,0,1,255,255,255,18,0,0,0,1, + 255,0,255,4,255,255,255,20,255,0,255,4,255,255,255,1,143,143,143,18, + 255,255,255,1,255,0,255,4,0,0,0,1,255,255,255,18,0,0,0,1, + 255,0,255,4,0,0,0,1,255,255,255,18,0,0,0,1,255,0,255,4, + 255,255,255,1,143,143,143,18,255,255,255,1,255,0,255,4,255,255,255,1, + 0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0,2, + 255,255,255,2,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,1, + 255,0,255,50,0,0) + ); + +const + objdata_ttilearea: record size: integer; data: array[0..561] of byte end = + (size: 562; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,116,105, + 108,101,97,114,101,97,12,98,105,116,109,97,112,46,105,109,97,103,101,10, + 4,2,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0,0,0, + 208,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,255,50, + 0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0,1, + 30,30,30,1,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0,2, + 255,255,255,1,0,0,0,1,255,0,255,4,0,0,0,1,255,255,255,9, + 143,143,143,1,255,255,255,8,0,0,0,1,255,0,255,4,255,255,255,10, + 143,143,143,1,255,255,255,9,255,0,255,4,255,255,255,10,143,143,143,1, + 255,255,255,9,255,0,255,4,0,0,0,1,255,255,255,9,143,143,143,1, + 255,255,255,8,0,0,0,1,255,0,255,4,0,0,0,1,255,255,255,9, + 143,143,143,1,255,255,255,8,0,0,0,1,255,0,255,4,255,255,255,10, + 143,143,143,1,255,255,255,9,255,0,255,4,255,255,255,1,143,143,143,18, + 255,255,255,1,255,0,255,4,0,0,0,1,255,255,255,9,143,143,143,1, + 255,255,255,8,0,0,0,1,255,0,255,4,0,0,0,1,255,255,255,9, + 143,143,143,1,255,255,255,8,0,0,0,1,255,0,255,4,255,255,255,10, + 143,143,143,1,255,255,255,9,255,0,255,4,255,255,255,10,143,143,143,1, + 255,255,255,9,255,0,255,4,0,0,0,1,255,255,255,9,143,143,143,1, + 255,255,255,8,0,0,0,1,255,0,255,4,0,0,0,1,255,255,255,9, + 143,143,143,1,255,255,255,8,0,0,0,1,255,0,255,4,255,255,255,1, + 143,143,143,18,255,255,255,1,255,0,255,4,255,255,255,10,143,143,143,1, + 255,255,255,9,255,0,255,4,0,0,0,1,255,255,255,9,143,143,143,1, + 255,255,255,8,0,0,0,1,255,0,255,4,0,0,0,1,255,255,255,9, + 143,143,143,1,255,255,255,8,0,0,0,1,255,0,255,4,255,255,255,10, + 143,143,143,1,255,255,255,9,255,0,255,4,255,255,255,1,0,0,0,2, + 255,255,255,2,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,2, + 0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,1,255,0,255,50, + 0,0) + ); + +const + objdata_tbandgroup: record size: integer; data: array[0..338] of byte end = + (size: 339; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,98,97, + 110,100,103,114,111,117,112,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,36,1,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0,0, + 0,240,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,255, + 50,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0, + 2,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255, + 1,0,0,0,1,255,0,255,4,0,0,0,1,255,255,255,18,0,0,0, + 1,255,0,255,4,255,255,255,20,255,0,255,4,255,255,255,20,255,0,255, + 4,0,0,0,1,255,255,255,18,0,0,0,1,255,0,255,4,0,0,0, + 3,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255, + 2,0,0,0,2,255,255,255,2,0,0,0,3,255,0,255,4,255,255,255, + 20,255,0,255,4,255,255,255,20,255,0,255,4,0,0,0,1,255,255,255, + 18,0,0,0,1,255,0,255,4,0,0,0,1,255,255,255,18,0,0,0, + 1,255,0,255,4,255,255,255,1,0,0,0,2,255,255,255,2,0,0,0, + 2,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255, + 2,0,0,0,2,255,255,255,1,255,0,255,255,255,0,255,11,0,0) + ); + +const + objdata_trecordband: record size: integer; data: array[0..243] of byte end = + (size: 244; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,114,101, + 99,111,114,100,98,97,110,100,12,98,105,116,109,97,112,46,105,109,97,103, + 101,10,196,0,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0, + 0,0,144,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0, + 255,50,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,2,0,0, + 0,2,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0,2,255,255, + 255,1,0,0,0,1,255,0,255,4,0,0,0,1,255,255,255,18,0,0, + 0,1,255,0,255,4,255,255,255,20,255,0,255,4,255,255,255,20,255,0, + 255,4,0,0,0,1,255,255,255,18,0,0,0,1,255,0,255,4,0,0, + 0,3,255,255,255,2,0,0,0,2,255,255,255,2,0,0,0,2,255,255, + 255,2,0,0,0,2,255,255,255,2,0,0,0,3,255,0,255,255,255,0, + 255,131,0,0) + ); + +const + objdata_trepvaluedisp: record size: integer; data: array[0..193] of byte end = + (size: 194; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,114,101, + 112,118,97,108,117,101,100,105,115,112,12,98,105,116,109,97,112,46,105,109, + 97,103,101,10,144,0,0,0,0,0,0,0,0,0,0,0,24,0,0,0, + 24,0,0,0,92,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 255,0,255,146,255,255,255,20,255,0,255,4,255,255,255,20,255,0,255,4, + 255,255,255,20,255,0,255,4,255,255,255,20,255,0,255,4,255,255,255,20, + 255,0,255,4,255,255,255,20,255,0,255,4,255,255,255,20,255,0,255,4, + 255,255,255,20,255,0,255,4,255,255,255,20,255,0,255,4,255,255,255,20, + 255,0,255,4,255,255,255,20,255,0,255,170,0,0) + ); + +const + objdata_treppagenumdisp: record size: integer; data: array[0..595] of byte end = + (size: 596; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,114,101, + 112,112,97,103,101,110,117,109,100,105,115,112,12,98,105,116,109,97,112,46, + 105,109,97,103,101,10,32,2,0,0,0,0,0,0,0,0,0,0,24,0, + 0,0,24,0,0,0,236,1,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,255,0,255,146,255,255,255,20,255,0,255,4,255,255,255,2,215,215, + 215,1,0,0,0,1,3,3,3,1,4,4,4,1,24,24,24,1,106,106, + 106,1,244,244,244,1,255,255,255,4,105,105,105,1,218,218,218,1,173,173, + 173,1,149,149,149,1,255,255,255,3,255,0,255,4,255,255,255,2,215,215, + 215,1,3,3,3,1,255,255,255,2,222,222,222,1,68,68,68,1,94,94, + 94,1,255,255,255,4,68,68,68,1,255,255,255,1,98,98,98,1,225,225, + 225,1,255,255,255,3,255,0,255,4,255,255,255,2,215,215,215,1,3,3, + 3,1,255,255,255,3,199,199,199,1,18,18,18,1,255,255,255,2,3,3, + 3,1,2,2,2,2,3,3,3,1,1,1,1,1,3,3,3,2,255,255, + 255,2,255,0,255,4,255,255,255,2,215,215,215,1,3,3,3,1,255,255, + 255,3,190,190,190,1,28,28,28,1,255,255,255,3,168,168,168,1,155,155, + 155,1,243,243,243,1,84,84,84,1,255,255,255,4,255,0,255,4,255,255, + 255,2,215,215,215,1,3,3,3,1,255,255,255,1,253,253,253,1,210,210, + 210,1,50,50,50,1,127,127,127,1,255,255,255,3,125,125,125,1,200,200, + 200,1,199,199,199,1,126,126,126,1,255,255,255,4,255,0,255,4,255,255, + 255,2,215,215,215,1,0,0,0,1,7,7,7,1,8,8,8,1,35,35, + 35,1,132,132,132,1,253,253,253,1,255,255,255,3,83,83,83,1,243,243, + 243,1,154,154,154,1,169,169,169,1,255,255,255,4,255,0,255,4,255,255, + 255,2,215,215,215,1,3,3,3,1,255,255,255,6,7,7,7,2,2,2, + 2,1,7,7,7,1,3,3,3,1,6,6,6,1,7,7,7,1,255,255, + 255,3,255,0,255,4,255,255,255,2,215,215,215,1,3,3,3,1,255,255, + 255,7,224,224,224,1,99,99,99,1,255,255,255,1,68,68,68,1,255,255, + 255,5,255,0,255,4,255,255,255,2,215,215,215,1,3,3,3,1,255,255, + 255,7,149,149,149,1,174,174,174,1,221,221,221,1,102,102,102,1,255,255, + 255,5,255,0,255,4,255,255,255,20,255,0,255,170,0,0) + ); + +const + objdata_trepprintdatedisp: record size: integer; data: array[0..565] of byte end = + (size: 566; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,114,101, + 112,112,114,105,110,116,100,97,116,101,100,105,115,112,12,98,105,116,109,97, + 112,46,105,109,97,103,101,10,0,2,0,0,0,0,0,0,0,0,0,0, + 24,0,0,0,24,0,0,0,204,1,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,255,0,255,146,255,255,255,20,255,0,255,4,255,255,255,2, + 215,215,215,1,0,0,0,1,4,4,4,1,5,5,5,1,27,27,27,1, + 96,96,96,1,224,224,224,1,255,255,255,2,3,3,3,3,0,0,0,1, + 3,3,3,3,255,255,255,2,255,0,255,4,255,255,255,2,215,215,215,1, + 3,3,3,1,255,255,255,1,253,253,253,1,217,217,217,1,103,103,103,1, + 25,25,25,1,231,231,231,1,255,255,255,3,215,215,215,1,7,7,7,1, + 255,255,255,5,255,0,255,4,255,255,255,2,215,215,215,1,3,3,3,1, + 255,255,255,4,89,89,89,1,105,105,105,1,255,255,255,3,215,215,215,1, + 7,7,7,1,255,255,255,5,255,0,255,4,255,255,255,2,215,215,215,1, + 3,3,3,1,255,255,255,4,184,184,184,1,34,34,34,1,255,255,255,3, + 215,215,215,1,7,7,7,1,255,255,255,5,255,0,255,4,255,255,255,2, + 215,215,215,1,3,3,3,1,255,255,255,4,210,210,210,1,12,12,12,1, + 255,255,255,3,215,215,215,1,7,7,7,1,255,255,255,5,255,0,255,4, + 255,255,255,2,215,215,215,1,3,3,3,1,255,255,255,4,187,187,187,1, + 36,36,36,1,255,255,255,3,215,215,215,1,7,7,7,1,255,255,255,5, + 255,0,255,4,255,255,255,2,215,215,215,1,3,3,3,1,255,255,255,4, + 95,95,95,1,117,117,117,1,255,255,255,3,215,215,215,1,7,7,7,1, + 255,255,255,5,255,0,255,4,255,255,255,2,215,215,215,1,3,3,3,1, + 255,255,255,1,253,253,253,1,220,220,220,1,107,107,107,1,37,37,37,1, + 241,241,241,1,255,255,255,3,215,215,215,1,7,7,7,1,255,255,255,5, + 255,0,255,4,255,255,255,2,215,215,215,1,0,0,0,1,3,3,3,1, + 5,5,5,1,30,30,30,1,105,105,105,1,234,234,234,1,255,255,255,4, + 215,215,215,1,7,7,7,1,255,255,255,5,255,0,255,4,255,255,255,20, + 255,0,255,170,0,0) + ); + +const + objdata_trepspacer: record size: integer; data: array[0..526] of byte end = + (size: 527; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,114,101, + 112,115,112,97,99,101,114,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,224,1,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0,0, + 0,172,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,255, + 50,255,255,255,20,255,0,255,4,255,255,255,20,255,0,255,4,255,255,255, + 20,255,0,255,4,255,255,255,20,255,0,255,4,255,255,255,3,0,0,0, + 1,255,255,255,11,0,0,0,1,255,255,255,4,255,0,255,4,255,255,255, + 3,0,0,0,1,255,255,255,11,0,0,0,1,255,255,255,4,255,0,255, + 4,255,255,255,3,0,0,0,1,255,255,255,11,0,0,0,1,255,255,255, + 4,255,0,255,4,255,255,255,3,0,0,0,1,255,255,255,11,0,0,0, + 1,255,255,255,4,255,0,255,4,255,255,255,3,0,0,0,1,255,255,255, + 3,0,0,0,1,255,255,255,3,0,0,0,1,255,255,255,3,0,0,0, + 1,255,255,255,4,255,0,255,4,255,255,255,3,0,0,0,1,255,255,255, + 1,0,0,0,3,255,255,255,3,0,0,0,3,255,255,255,1,0,0,0, + 1,255,255,255,4,255,0,255,4,255,255,255,3,0,0,0,13,255,255,255, + 4,255,0,255,4,255,255,255,3,0,0,0,1,255,255,255,1,0,0,0, + 3,255,255,255,3,0,0,0,3,255,255,255,1,0,0,0,1,255,255,255, + 4,255,0,255,4,255,255,255,3,0,0,0,1,255,255,255,3,0,0,0, + 1,255,255,255,3,0,0,0,1,255,255,255,3,0,0,0,1,255,255,255, + 4,255,0,255,4,255,255,255,3,0,0,0,1,255,255,255,11,0,0,0, + 1,255,255,255,4,255,0,255,4,255,255,255,3,0,0,0,1,255,255,255, + 11,0,0,0,1,255,255,255,4,255,0,255,4,255,255,255,3,0,0,0, + 1,255,255,255,11,0,0,0,1,255,255,255,4,255,0,255,4,255,255,255, + 3,0,0,0,1,255,255,255,11,0,0,0,1,255,255,255,4,255,0,255, + 4,255,255,255,20,255,0,255,4,255,255,255,20,255,0,255,4,255,255,255, + 20,255,0,255,50,0,0) + ); + +const + objdata_treppsdisp: record size: integer; data: array[0..1017] of byte end = + (size: 1018; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,114,101, + 112,112,115,100,105,115,112,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,132,3,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,168,2,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,50,255,255,255,20,0,0,0,4, + 255,255,255,20,0,0,0,4,255,255,255,20,0,0,0,4,255,255,255,20, + 0,0,0,4,255,255,255,20,0,0,0,4,255,255,255,2,252,252,252,1, + 85,85,85,3,88,88,88,1,123,123,123,1,230,230,230,1,255,255,255,2, + 238,238,238,1,121,121,121,1,61,61,61,1,60,60,60,1,132,132,132,1, + 246,246,246,1,255,255,255,3,0,0,0,4,255,255,255,2,250,250,250,1, + 0,0,0,1,152,152,152,1,187,187,187,1,176,176,176,1,98,98,98,1, + 21,21,21,1,230,230,230,1,255,255,255,1,57,57,57,1,83,83,83,1, + 196,196,196,1,190,190,190,1,64,64,64,1,79,79,79,1,255,255,255,3, + 0,0,0,4,255,255,255,2,250,250,250,1,0,0,0,1,207,207,207,1, + 255,255,255,3,55,55,55,1,141,141,141,1,227,227,227,1,0,0,0,1, + 228,228,228,1,255,255,255,2,222,222,222,1,17,17,17,1,231,231,231,1, + 255,255,255,2,0,0,0,4,255,255,255,2,250,250,250,1,0,0,0,1, + 207,207,207,1,255,255,255,3,72,72,72,1,130,130,130,1,248,248,248,1, + 20,20,20,1,125,125,125,1,251,251,251,1,255,255,255,6,0,0,0,4, + 255,255,255,2,250,250,250,1,0,0,0,1,180,180,180,1,221,221,221,1, + 216,216,216,1,151,151,151,1,8,8,8,1,207,207,207,1,255,255,255,1, + 197,197,197,1,37,37,37,1,24,24,24,1,114,114,114,1,215,215,215,1, + 255,255,255,4,0,0,0,4,255,255,255,2,250,250,250,1,0,0,0,1, + 28,28,28,1,34,34,34,1,40,40,40,1,77,77,77,1,189,189,189,1, + 255,255,255,3,253,253,253,1,188,188,188,1,97,97,97,1,8,8,8,1, + 128,128,128,1,255,255,255,3,0,0,0,4,255,255,255,2,250,250,250,1, + 0,0,0,1,207,207,207,1,255,255,255,5,232,232,232,1,215,215,215,1, + 255,255,255,3,194,194,194,1,2,2,2,1,231,231,231,1,255,255,255,2, + 0,0,0,4,255,255,255,2,250,250,250,1,0,0,0,1,207,207,207,1, + 255,255,255,5,173,173,173,1,21,21,21,1,243,243,243,1,255,255,255,2, + 224,224,224,1,0,0,0,1,227,227,227,1,255,255,255,2,0,0,0,4, + 255,255,255,2,250,250,250,1,0,0,0,1,207,207,207,1,255,255,255,5, + 251,251,251,1,74,74,74,1,45,45,45,1,134,134,134,1,136,136,136,1, + 42,42,42,1,87,87,87,1,255,255,255,3,0,0,0,4,255,255,255,2, + 253,253,253,1,136,136,136,1,233,233,233,1,255,255,255,6,254,254,254,1, + 181,181,181,1,121,121,121,1,124,124,124,1,179,179,179,1,254,254,254,1, + 255,255,255,3,0,0,0,4,255,255,255,20,0,0,0,4,255,255,255,20, + 0,0,0,4,255,255,255,20,0,0,0,4,255,255,255,20,0,0,0,4, + 255,255,255,20,0,0,0,50,164,0,0,0,0,0,0,50,255,255,255,20, + 0,0,0,4,255,255,255,20,0,0,0,4,255,255,255,20,0,0,0,4, + 255,255,255,20,0,0,0,4,255,255,255,20,0,0,0,4,255,255,255,20, + 0,0,0,4,255,255,255,20,0,0,0,4,255,255,255,20,0,0,0,4, + 255,255,255,20,0,0,0,4,255,255,255,20,0,0,0,4,255,255,255,20, + 0,0,0,4,255,255,255,20,0,0,0,4,255,255,255,20,0,0,0,4, + 255,255,255,20,0,0,0,4,255,255,255,20,0,0,0,4,255,255,255,20, + 0,0,0,4,255,255,255,20,0,0,0,4,255,255,255,20,0,0,0,4, + 255,255,255,20,0,0,0,4,255,255,255,20,0,0,0,50,0,0) + ); + +initialization + registerobjectdata(@objdata_treportpage,tbitmapcomp,'treportpage'); + registerobjectdata(@objdata_tbandarea,tbitmapcomp,'tbandarea'); + registerobjectdata(@objdata_ttilearea,tbitmapcomp,'ttilearea'); + registerobjectdata(@objdata_tbandgroup,tbitmapcomp,'tbandgroup'); + registerobjectdata(@objdata_trecordband,tbitmapcomp,'trecordband'); + registerobjectdata(@objdata_trepvaluedisp,tbitmapcomp,'trepvaluedisp'); + registerobjectdata(@objdata_treppagenumdisp,tbitmapcomp,'treppagenumdisp'); + registerobjectdata(@objdata_trepprintdatedisp,tbitmapcomp,'trepprintdatedisp'); + registerobjectdata(@objdata_trepspacer,tbitmapcomp,'trepspacer'); + registerobjectdata(@objdata_treppsdisp,tbitmapcomp,'treppsdisp'); +end. diff --git a/mseide-msegui/lib/common/regcomponents/regserialcomm.pas b/mseide-msegui/lib/common/regcomponents/regserialcomm.pas new file mode 100644 index 0000000..6a46bb7 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regserialcomm.pas @@ -0,0 +1,37 @@ +{ MSEide Copyright (c) 1999-2013 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regserialcomm; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + Classes,msecommport,msecommutils,msesercomm,msedesignintf,regserialcomm_bmp; + +procedure Register; +begin + registercomponents('Comm',[tcommport,tasciicommport,tasciiprotport, + tsercommcomp,tsercommchannel,tasynsercommchannel, + tcommselector]); + registercomponenttabhints(['Comm'],['Components for serial port (RS232)']); +end; + +initialization + register; +end. diff --git a/mseide-msegui/lib/common/regcomponents/regserialcomm_bmp.pas b/mseide-msegui/lib/common/regcomponents/regserialcomm_bmp.pas new file mode 100644 index 0000000..4c8cdc5 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regserialcomm_bmp.pas @@ -0,0 +1,721 @@ +unit regserialcomm_bmp; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msebitmap; + +const + objdata_tcommport: record size: integer; data: array[0..1952] of byte end = + (size: 1953; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,99,111, + 109,109,112,111,114,116,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,44,7,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,244,1,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,208,208,208,73,0,0,0,4,208,208,208,1,0, + 0,0,4,208,208,208,1,0,0,0,2,208,208,208,2,0,0,0,5,208, + 208,208,1,0,0,0,2,208,208,208,2,0,0,0,13,208,208,208,1,0, + 0,0,5,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208, + 208,208,2,0,0,0,4,208,208,208,1,0,0,0,5,208,208,208,1,0, + 0,0,5,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208, + 208,208,4,0,0,0,1,208,208,208,3,0,0,0,10,208,208,208,1,0, + 0,0,2,208,208,208,1,0,0,0,2,208,208,208,2,0,0,0,1,208, + 208,208,1,0,0,0,1,208,208,208,3,0,0,0,13,208,208,208,1,0, + 0,0,2,208,208,208,2,0,0,0,4,208,208,208,1,0,0,0,14,208, + 208,208,2,0,0,0,4,208,208,208,1,0,0,0,9,208,208,208,1,0, + 0,0,5,208,208,208,1,0,0,0,1,208,208,208,2,0,0,0,4,208, + 208,208,2,0,0,0,3,208,208,208,1,0,0,0,4,208,208,208,1,0, + 0,0,5,208,208,208,1,0,0,0,1,208,208,208,51,0,0,0,4,208, + 208,208,2,0,0,0,3,208,208,208,1,0,0,0,10,208,208,208,4,0, + 0,0,20,208,208,208,4,0,0,0,2,208,208,208,1,0,0,0,4,208, + 208,208,1,0,0,0,4,208,208,208,2,0,0,0,2,208,208,208,1,0, + 0,0,2,208,208,208,5,0,0,0,7,208,208,208,2,0,0,0,6,208, + 208,208,2,0,0,0,2,208,208,208,5,0,0,0,4,208,208,208,1,0, + 0,0,1,208,208,208,3,0,0,0,6,208,208,208,2,0,0,0,2,208, + 208,208,5,0,0,0,2,208,208,208,3,0,0,0,2,208,208,208,1,0, + 0,0,4,208,208,208,1,0,0,0,2,208,208,208,2,0,0,0,2,208, + 208,208,5,0,0,0,2,208,208,208,3,0,0,0,7,208,208,208,1,0, + 0,0,3,208,208,208,1,0,0,0,2,208,208,208,5,0,0,0,2,208, + 208,208,4,0,0,0,6,208,208,208,2,0,0,0,2,208,208,208,1,0, + 0,0,2,208,208,208,75,0,5,0,0,0,0,0,73,24,24,24,1,168, + 168,168,1,193,193,193,1,68,68,68,1,0,0,0,1,4,4,4,1,147, + 147,147,1,209,209,209,1,122,122,122,1,0,0,0,1,37,37,37,1,186, + 186,186,1,0,0,0,2,50,50,50,1,156,156,156,1,27,27,27,1,193, + 193,193,1,3,3,3,1,0,0,0,1,40,40,40,1,166,166,166,1,0, + 0,0,2,172,172,172,1,61,61,61,1,21,21,21,1,189,189,189,1,7, + 7,7,1,121,121,121,1,137,137,137,1,15,15,15,1,134,134,134,1,91, + 91,91,1,48,48,48,1,241,241,241,1,39,39,39,1,0,0,0,1,120, + 120,120,1,188,188,188,1,35,35,35,1,241,241,241,1,52,52,52,1,0, + 0,0,1,108,108,108,1,201,201,201,1,0,0,0,1,10,10,10,1,163, + 163,163,1,0,0,0,2,50,50,50,1,15,15,15,1,208,208,208,1,12, + 12,12,1,0,0,0,1,4,4,4,1,171,171,171,1,48,48,48,1,182, + 182,182,1,101,101,101,1,0,0,0,1,145,145,145,1,168,168,168,1,35, + 35,35,1,182,182,182,1,114,114,114,1,0,0,0,1,145,145,145,1,168, + 168,168,1,0,0,0,1,45,45,45,1,128,128,128,1,0,0,0,4,197, + 197,197,1,0,0,0,3,180,180,180,1,48,48,48,1,127,127,127,1,155, + 155,155,1,4,4,4,1,140,140,140,1,168,168,168,1,35,35,35,1,135, + 135,135,1,161,161,161,1,0,0,0,1,143,143,143,1,168,168,168,1,0, + 0,0,1,35,35,35,1,138,138,138,1,0,0,0,2,1,1,1,1,0, + 0,0,1,193,193,193,1,0,0,0,3,195,195,195,1,48,48,48,1,119, + 119,119,1,163,163,163,1,54,54,54,1,88,88,88,1,168,168,168,1,35, + 35,35,1,132,132,132,1,162,162,162,1,43,43,43,1,101,101,101,1,168, + 168,168,1,0,0,0,1,5,5,5,1,181,181,181,1,0,0,0,2,142, + 142,142,1,40,40,40,1,188,188,188,1,20,20,20,1,0,0,0,1,36, + 36,36,1,176,176,176,1,48,48,48,1,119,119,119,1,132,132,132,1,146, + 146,146,1,24,24,24,1,168,168,168,1,35,35,35,1,132,132,132,1,119, + 119,119,1,146,146,146,1,37,37,37,1,168,168,168,1,0,0,0,2,138, + 138,138,1,125,125,125,1,93,93,93,1,186,186,186,1,0,0,0,1,61, + 61,61,1,198,198,198,1,87,87,87,1,203,203,203,1,54,54,54,1,48, + 48,48,1,119,119,119,1,70,70,70,1,203,203,203,1,0,0,0,1,168, + 168,168,1,35,35,35,1,132,132,132,1,57,57,57,1,216,216,216,1,0, + 0,0,1,168,168,168,1,0,0,0,2,9,9,9,1,97,97,97,1,121, + 121,121,1,20,20,20,1,0,0,0,2,61,61,61,1,136,136,136,1,62, + 62,62,1,0,0,0,1,24,24,24,1,59,59,59,1,11,11,11,1,83, + 83,83,1,0,0,0,1,84,84,84,1,17,17,17,1,66,66,66,1,5, + 5,5,1,90,90,90,1,0,0,0,1,84,84,84,1,0,0,0,51,78, + 78,78,1,136,136,136,1,132,132,132,1,69,69,69,1,0,0,0,2,75, + 75,75,1,148,148,148,1,69,69,69,1,0,0,0,1,12,12,12,1,136, + 136,136,2,119,119,119,1,34,34,34,1,52,52,52,1,136,136,136,3,100, + 100,100,1,0,0,0,4,148,148,148,1,106,106,106,1,92,92,92,1,198, + 198,198,1,39,39,39,1,71,71,71,1,196,196,196,1,79,79,79,1,172, + 172,172,1,66,66,66,1,24,24,24,1,181,181,181,1,72,72,72,1,101, + 101,101,1,196,196,196,1,33,33,33,1,88,88,88,1,200,200,200,1,91, + 91,91,1,65,65,65,1,0,0,0,4,148,148,148,1,27,27,27,1,0, + 0,0,1,99,99,99,1,86,86,86,1,179,179,179,1,39,39,39,1,0, + 0,0,1,12,12,12,1,173,173,173,1,24,24,24,1,151,151,151,1,0, + 0,0,2,179,179,179,1,4,4,4,1,0,0,0,1,170,170,170,1,5, + 5,5,1,0,0,0,5,148,148,148,1,41,41,41,1,30,30,30,1,176, + 176,176,1,34,34,34,1,203,203,203,1,1,1,1,1,0,0,0,2,177, + 177,177,1,24,24,24,1,184,184,184,1,80,80,80,1,102,102,102,1,179, + 179,179,1,0,0,0,2,170,170,170,1,5,5,5,1,0,0,0,5,148, + 148,148,1,206,206,206,1,183,183,183,1,87,87,87,1,0,0,0,1,190, + 190,190,1,0,0,0,3,190,190,190,1,24,24,24,1,207,207,207,1,142, + 142,142,1,213,213,213,1,12,12,12,1,0,0,0,2,170,170,170,1,5, + 5,5,1,0,0,0,5,148,148,148,1,27,27,27,1,0,0,0,3,186, + 186,186,1,20,20,20,1,0,0,0,1,10,10,10,1,199,199,199,1,24, + 24,24,1,151,151,151,1,0,0,0,1,113,113,113,1,109,109,109,1,0, + 0,0,2,170,170,170,1,5,5,5,1,0,0,0,5,148,148,148,1,27, + 27,27,1,0,0,0,3,85,85,85,1,158,158,158,1,25,25,25,1,145, + 145,145,1,109,109,109,1,24,24,24,1,151,151,151,1,0,0,0,1,9, + 9,9,1,207,207,207,1,6,6,6,1,0,0,0,1,170,170,170,1,5, + 5,5,1,0,0,0,5,111,111,111,1,20,20,20,1,0,0,0,4,113, + 113,113,1,198,198,198,1,132,132,132,1,1,1,1,1,18,18,18,1,113, + 113,113,1,0,0,0,2,105,105,105,1,62,62,62,1,0,0,0,1,128, + 128,128,1,3,3,3,1,0,0,0,75,0,0) + ); + +const + objdata_tasciicommport: record size: integer; data: array[0..1857] of byte end = + (size: 1858; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,97,115, + 99,105,105,99,111,109,109,112,111,114,116,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,200,6,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,20,2,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,208,208,208,76,0,0,0,2, + 208,208,208,2,0,0,0,4,208,208,208,1,0,0,0,4,208,208,208,1, + 0,0,0,1,208,208,208,1,0,0,0,1,208,208,208,6,0,0,0,3, + 208,208,208,1,0,0,0,10,208,208,208,1,0,0,0,1,208,208,208,1, + 0,0,0,1,208,208,208,6,0,0,0,3,208,208,208,1,0,0,0,7, + 208,208,208,2,0,0,0,1,208,208,208,1,0,0,0,1,208,208,208,1, + 0,0,0,1,208,208,208,6,0,0,0,4,208,208,208,1,0,0,0,6, + 208,208,208,4,0,0,0,1,208,208,208,1,0,0,0,1,208,208,208,6, + 0,0,0,4,208,208,208,2,0,0,0,5,208,208,208,2,0,0,0,1, + 208,208,208,1,0,0,0,1,208,208,208,1,0,0,0,1,208,208,208,5, + 0,0,0,7,208,208,208,1,0,0,0,4,208,208,208,2,0,0,0,1, + 208,208,208,1,0,0,0,1,208,208,208,1,0,0,0,1,208,208,208,5, + 0,0,0,2,208,208,208,2,0,0,0,11,208,208,208,1,0,0,0,1, + 208,208,208,1,0,0,0,1,208,208,208,5,0,0,0,2,208,208,208,2, + 0,0,0,5,208,208,208,2,0,0,0,4,208,208,208,1,0,0,0,1, + 208,208,208,1,0,0,0,1,208,208,208,53,0,0,0,4,208,208,208,2, + 0,0,0,3,208,208,208,1,0,0,0,10,208,208,208,4,0,0,0,20, + 208,208,208,4,0,0,0,2,208,208,208,1,0,0,0,4,208,208,208,1, + 0,0,0,4,208,208,208,2,0,0,0,2,208,208,208,1,0,0,0,2, + 208,208,208,5,0,0,0,7,208,208,208,2,0,0,0,6,208,208,208,2, + 0,0,0,2,208,208,208,5,0,0,0,4,208,208,208,1,0,0,0,1, + 208,208,208,3,0,0,0,6,208,208,208,2,0,0,0,2,208,208,208,5, + 0,0,0,2,208,208,208,3,0,0,0,2,208,208,208,1,0,0,0,4, + 208,208,208,1,0,0,0,2,208,208,208,2,0,0,0,2,208,208,208,5, + 0,0,0,2,208,208,208,3,0,0,0,7,208,208,208,1,0,0,0,3, + 208,208,208,1,0,0,0,2,208,208,208,5,0,0,0,2,208,208,208,4, + 0,0,0,6,208,208,208,2,0,0,0,2,208,208,208,1,0,0,0,2, + 208,208,208,75,124,4,0,0,0,0,0,76,145,145,145,1,48,48,48,1, + 0,0,0,2,108,108,108,1,211,211,211,1,154,154,154,1,5,5,5,1, + 0,0,0,1,64,64,64,1,191,191,191,1,167,167,167,1,30,30,30,1, + 0,0,0,1,137,137,137,1,0,0,0,1,137,137,137,1,0,0,0,6, + 4,4,4,1,184,184,184,1,128,128,128,1,0,0,0,1,21,21,21,1, + 175,175,175,1,13,13,13,1,124,124,124,1,101,101,101,1,20,20,20,1, + 184,184,184,1,28,28,28,1,58,58,58,1,159,159,159,1,0,0,0,1, + 176,176,176,1,0,0,0,1,176,176,176,1,0,0,0,6,60,60,60,1, + 111,111,111,1,169,169,169,1,0,0,0,1,32,32,32,1,165,165,165,1, + 4,4,4,1,13,13,13,1,42,42,42,1,85,85,85,1,88,88,88,1, + 0,0,0,2,66,66,66,1,0,0,0,1,176,176,176,1,0,0,0,1, + 176,176,176,1,0,0,0,6,129,129,129,1,44,44,44,1,153,153,153,1, + 23,23,23,1,0,0,0,1,148,148,148,1,220,220,220,1,116,116,116,1, + 2,2,2,1,121,121,121,1,52,52,52,1,0,0,0,4,176,176,176,1, + 0,0,0,1,176,176,176,1,0,0,0,6,195,195,195,1,128,128,128,1, + 179,179,179,1,97,97,97,1,0,0,0,2,37,37,37,1,156,156,156,1, + 119,119,119,1,111,111,111,1,62,62,62,1,0,0,0,2,1,1,1,1, + 0,0,0,1,176,176,176,1,0,0,0,1,176,176,176,1,0,0,0,5, + 15,15,15,1,182,182,182,1,80,80,80,1,86,86,86,1,169,169,169,1, + 75,75,75,1,78,78,78,1,0,0,0,1,3,3,3,1,166,166,166,1, + 74,74,74,1,111,111,111,1,0,0,0,2,181,181,181,1,0,0,0,1, + 176,176,176,1,0,0,0,1,176,176,176,1,0,0,0,5,81,81,81,1, + 99,99,99,1,0,0,0,2,189,189,189,1,31,31,31,1,202,202,202,1, + 83,83,83,1,136,136,136,1,106,106,106,1,3,3,3,1,191,191,191,1, + 85,85,85,1,136,136,136,1,127,127,127,1,0,0,0,1,176,176,176,1, + 0,0,0,1,176,176,176,1,0,0,0,5,66,66,66,1,24,24,24,1, + 0,0,0,2,76,76,76,1,23,23,23,1,52,52,52,1,139,139,139,1, + 103,103,103,1,0,0,0,2,29,29,29,1,123,123,123,1,91,91,91,1, + 4,4,4,1,0,0,0,1,88,88,88,1,0,0,0,1,88,88,88,1, + 0,0,0,53,78,78,78,1,136,136,136,1,132,132,132,1,69,69,69,1, + 0,0,0,2,75,75,75,1,148,148,148,1,69,69,69,1,0,0,0,1, + 12,12,12,1,136,136,136,2,119,119,119,1,34,34,34,1,52,52,52,1, + 136,136,136,3,100,100,100,1,0,0,0,4,148,148,148,1,106,106,106,1, + 92,92,92,1,198,198,198,1,39,39,39,1,71,71,71,1,196,196,196,1, + 79,79,79,1,172,172,172,1,66,66,66,1,24,24,24,1,181,181,181,1, + 72,72,72,1,101,101,101,1,196,196,196,1,33,33,33,1,88,88,88,1, + 200,200,200,1,91,91,91,1,65,65,65,1,0,0,0,4,148,148,148,1, + 27,27,27,1,0,0,0,1,99,99,99,1,86,86,86,1,179,179,179,1, + 39,39,39,1,0,0,0,1,12,12,12,1,173,173,173,1,24,24,24,1, + 151,151,151,1,0,0,0,2,179,179,179,1,4,4,4,1,0,0,0,1, + 170,170,170,1,5,5,5,1,0,0,0,5,148,148,148,1,41,41,41,1, + 30,30,30,1,176,176,176,1,34,34,34,1,203,203,203,1,1,1,1,1, + 0,0,0,2,177,177,177,1,24,24,24,1,184,184,184,1,80,80,80,1, + 102,102,102,1,179,179,179,1,0,0,0,2,170,170,170,1,5,5,5,1, + 0,0,0,5,148,148,148,1,206,206,206,1,183,183,183,1,87,87,87,1, + 0,0,0,1,190,190,190,1,0,0,0,3,190,190,190,1,24,24,24,1, + 207,207,207,1,142,142,142,1,213,213,213,1,12,12,12,1,0,0,0,2, + 170,170,170,1,5,5,5,1,0,0,0,5,148,148,148,1,27,27,27,1, + 0,0,0,3,186,186,186,1,20,20,20,1,0,0,0,1,10,10,10,1, + 199,199,199,1,24,24,24,1,151,151,151,1,0,0,0,1,113,113,113,1, + 109,109,109,1,0,0,0,2,170,170,170,1,5,5,5,1,0,0,0,5, + 148,148,148,1,27,27,27,1,0,0,0,3,85,85,85,1,158,158,158,1, + 25,25,25,1,145,145,145,1,109,109,109,1,24,24,24,1,151,151,151,1, + 0,0,0,1,9,9,9,1,207,207,207,1,6,6,6,1,0,0,0,1, + 170,170,170,1,5,5,5,1,0,0,0,5,111,111,111,1,20,20,20,1, + 0,0,0,4,113,113,113,1,198,198,198,1,132,132,132,1,1,1,1,1, + 18,18,18,1,113,113,113,1,0,0,0,2,105,105,105,1,62,62,62,1, + 0,0,0,1,128,128,128,1,3,3,3,1,0,0,0,75,0,0) + ); + +const + objdata_tasciiprotport: record size: integer; data: array[0..1661] of byte end = + (size: 1662; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,97,115, + 99,105,105,112,114,111,116,112,111,114,116,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,4,6,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,156,1,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,208,208,208,77,0,0,0,2, + 208,208,208,12,0,0,0,1,208,208,208,8,0,0,0,3,208,208,208,12, + 0,0,0,1,208,208,208,8,0,0,0,3,208,208,208,1,0,0,0,13, + 208,208,208,7,0,0,0,3,208,208,208,1,0,0,0,12,208,208,208,7, + 0,0,0,7,208,208,208,1,0,0,0,5,208,208,208,1,0,0,0,3, + 208,208,208,7,0,0,0,13,208,208,208,1,0,0,0,3,208,208,208,7, + 0,0,0,2,208,208,208,1,0,0,0,8,208,208,208,1,0,0,0,6, + 208,208,208,6,0,0,0,2,208,208,208,2,0,0,0,7,208,208,208,1, + 0,0,0,3,208,208,208,1,0,0,0,2,208,208,208,11,0,0,0,2, + 208,208,208,22,0,0,0,2,208,208,208,16,0,0,0,4,208,208,208,2, + 0,0,0,3,208,208,208,1,0,0,0,10,208,208,208,4,0,0,0,20, + 208,208,208,4,0,0,0,2,208,208,208,1,0,0,0,4,208,208,208,1, + 0,0,0,4,208,208,208,2,0,0,0,2,208,208,208,1,0,0,0,2, + 208,208,208,5,0,0,0,7,208,208,208,2,0,0,0,6,208,208,208,2, + 0,0,0,2,208,208,208,5,0,0,0,4,208,208,208,1,0,0,0,1, + 208,208,208,3,0,0,0,6,208,208,208,2,0,0,0,2,208,208,208,5, + 0,0,0,2,208,208,208,3,0,0,0,2,208,208,208,1,0,0,0,4, + 208,208,208,1,0,0,0,2,208,208,208,2,0,0,0,2,208,208,208,5, + 0,0,0,2,208,208,208,3,0,0,0,7,208,208,208,1,0,0,0,3, + 208,208,208,1,0,0,0,2,208,208,208,5,0,0,0,2,208,208,208,4, + 0,0,0,6,208,208,208,2,0,0,0,2,208,208,208,1,0,0,0,2, + 208,208,208,75,48,4,0,0,0,0,0,77,182,182,182,1,10,10,10,1, + 0,0,0,12,52,52,52,1,0,0,0,8,42,42,42,1,197,197,197,1, + 77,77,77,1,0,0,0,12,160,160,160,1,0,0,0,8,111,111,111,1, + 79,79,79,1,150,150,150,1,0,0,0,1,94,94,94,1,148,148,148,1, + 178,178,178,1,28,28,28,1,87,87,87,1,156,156,156,1,98,98,98,1, + 83,83,83,1,182,182,182,1,83,83,83,1,58,58,58,1,229,229,229,1, + 79,79,79,1,0,0,0,7,169,169,169,1,5,5,5,1,176,176,176,1, + 0,0,0,1,121,121,121,1,120,120,120,1,45,45,45,1,149,149,149,1, + 111,111,111,1,117,117,117,1,15,15,15,1,163,163,163,1,10,10,10,1, + 172,172,172,1,3,3,3,1,160,160,160,1,0,0,0,7,6,6,6,1, + 215,215,215,1,128,128,128,1,205,205,205,1,45,45,45,1,121,121,121,1, + 51,51,51,1,0,0,0,1,174,174,174,1,111,111,111,1,56,56,56,1, + 33,33,33,1,129,129,129,1,0,0,0,1,112,112,112,1,49,49,49,1, + 160,160,160,1,0,0,0,7,63,63,63,1,151,151,151,1,80,80,80,1, + 119,119,119,1,120,120,120,1,121,121,121,1,59,59,59,1,4,4,4,1, + 172,172,172,1,111,111,111,1,48,48,48,1,22,22,22,1,141,141,141,1, + 0,0,0,1,129,129,129,1,43,43,43,1,159,159,159,1,0,0,0,7, + 132,132,132,1,47,47,47,1,0,0,0,1,8,8,8,1,186,186,186,1, + 121,121,121,1,159,159,159,1,111,111,111,1,112,112,112,1,111,111,111,1, + 48,48,48,1,0,0,0,1,182,182,182,1,73,73,73,1,190,190,190,1, + 8,8,8,1,172,172,172,1,32,32,32,1,0,0,0,6,89,89,89,1, + 1,1,1,1,0,0,0,2,98,98,98,1,122,122,122,1,121,121,121,2, + 5,5,5,1,55,55,55,1,24,24,24,1,0,0,0,1,25,25,25,1, + 129,129,129,1,46,46,46,1,0,0,0,1,75,75,75,1,67,67,67,1, + 0,0,0,11,121,121,121,1,46,46,46,1,0,0,0,22,64,64,64,1, + 24,24,24,1,0,0,0,16,78,78,78,1,136,136,136,1,132,132,132,1, + 69,69,69,1,0,0,0,2,75,75,75,1,148,148,148,1,69,69,69,1, + 0,0,0,1,12,12,12,1,136,136,136,2,119,119,119,1,34,34,34,1, + 52,52,52,1,136,136,136,3,100,100,100,1,0,0,0,4,148,148,148,1, + 106,106,106,1,92,92,92,1,198,198,198,1,39,39,39,1,71,71,71,1, + 196,196,196,1,79,79,79,1,172,172,172,1,66,66,66,1,24,24,24,1, + 181,181,181,1,72,72,72,1,101,101,101,1,196,196,196,1,33,33,33,1, + 88,88,88,1,200,200,200,1,91,91,91,1,65,65,65,1,0,0,0,4, + 148,148,148,1,27,27,27,1,0,0,0,1,99,99,99,1,86,86,86,1, + 179,179,179,1,39,39,39,1,0,0,0,1,12,12,12,1,173,173,173,1, + 24,24,24,1,151,151,151,1,0,0,0,2,179,179,179,1,4,4,4,1, + 0,0,0,1,170,170,170,1,5,5,5,1,0,0,0,5,148,148,148,1, + 41,41,41,1,30,30,30,1,176,176,176,1,34,34,34,1,203,203,203,1, + 1,1,1,1,0,0,0,2,177,177,177,1,24,24,24,1,184,184,184,1, + 80,80,80,1,102,102,102,1,179,179,179,1,0,0,0,2,170,170,170,1, + 5,5,5,1,0,0,0,5,148,148,148,1,206,206,206,1,183,183,183,1, + 87,87,87,1,0,0,0,1,190,190,190,1,0,0,0,3,190,190,190,1, + 24,24,24,1,207,207,207,1,142,142,142,1,213,213,213,1,12,12,12,1, + 0,0,0,2,170,170,170,1,5,5,5,1,0,0,0,5,148,148,148,1, + 27,27,27,1,0,0,0,3,186,186,186,1,20,20,20,1,0,0,0,1, + 10,10,10,1,199,199,199,1,24,24,24,1,151,151,151,1,0,0,0,1, + 113,113,113,1,109,109,109,1,0,0,0,2,170,170,170,1,5,5,5,1, + 0,0,0,5,148,148,148,1,27,27,27,1,0,0,0,3,85,85,85,1, + 158,158,158,1,25,25,25,1,145,145,145,1,109,109,109,1,24,24,24,1, + 151,151,151,1,0,0,0,1,9,9,9,1,207,207,207,1,6,6,6,1, + 0,0,0,1,170,170,170,1,5,5,5,1,0,0,0,5,111,111,111,1, + 20,20,20,1,0,0,0,4,113,113,113,1,198,198,198,1,132,132,132,1, + 1,1,1,1,18,18,18,1,113,113,113,1,0,0,0,2,105,105,105,1, + 62,62,62,1,0,0,0,1,128,128,128,1,3,3,3,1,0,0,0,75, + 0,0) + ); + +const + objdata_tcommselector: record size: integer; data: array[0..597] of byte end = + (size: 598; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,99,111, + 109,109,115,101,108,101,99,116,111,114,12,98,105,116,109,97,112,46,105,109, + 97,103,101,10,36,2,0,0,0,0,0,0,0,0,0,0,24,0,0,0, + 24,0,0,0,240,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 255,0,255,146,128,128,128,20,255,0,255,4,128,128,128,1,0,0,0,18, + 255,255,255,1,255,0,255,4,128,128,128,1,0,0,0,1,255,255,255,10, + 255,0,255,5,128,128,128,1,192,192,192,1,255,255,255,1,255,0,255,4, + 128,128,128,1,0,0,0,1,255,255,255,10,255,0,255,5,128,128,128,1, + 192,192,192,1,255,255,255,1,255,0,255,4,128,128,128,1,0,0,0,1, + 255,255,255,2,0,0,0,1,255,255,255,3,0,0,0,1,255,255,255,3, + 255,0,255,5,128,128,128,1,192,192,192,1,255,255,255,1,255,0,255,4, + 128,128,128,1,0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,1, + 0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,1,0,0,0,1, + 255,255,255,2,0,0,0,5,128,128,128,1,192,192,192,1,255,255,255,1, + 255,0,255,4,128,128,128,1,0,0,0,1,255,255,255,1,0,0,0,1, + 255,255,255,3,0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,2, + 255,0,255,1,0,0,0,3,255,0,255,1,128,128,128,1,192,192,192,1, + 255,255,255,1,255,0,255,4,128,128,128,1,0,0,0,1,255,255,255,1, + 0,0,0,1,255,255,255,3,0,0,0,1,255,255,255,1,0,0,0,1, + 255,255,255,2,255,0,255,2,0,0,0,1,255,0,255,2,128,128,128,1, + 192,192,192,1,255,255,255,1,255,0,255,4,128,128,128,1,0,0,0,1, + 255,255,255,1,0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,1, + 0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,2,255,0,255,5, + 128,128,128,1,192,192,192,1,255,255,255,1,255,0,255,4,128,128,128,1, + 0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,3,0,0,0,1, + 255,255,255,3,255,0,255,5,128,128,128,1,192,192,192,1,255,255,255,1, + 255,0,255,4,128,128,128,1,0,0,0,1,255,255,255,10,128,128,128,6, + 192,192,192,1,255,255,255,1,255,0,255,4,128,128,128,1,192,192,192,18, + 255,255,255,1,255,0,255,4,255,255,255,20,255,0,255,122,0,0) + ); + +const + objdata_tsercommcomp: record size: integer; data: array[0..2915] of byte end = + (size: 2916; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,115,101, + 114,99,111,109,109,99,111,109,112,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,236,10,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,32,5,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,26,255,187,75,23,223,163,1,8,77, + 57,1,26,255,187,2,24,237,174,1,7,67,49,1,4,42,31,1,16,161, + 118,1,24,231,169,1,10,101,74,1,26,255,187,2,14,138,101,1,19,189, + 139,1,8,75,55,1,25,246,181,1,26,255,187,1,15,150,110,1,21,210, + 154,1,26,255,187,5,15,146,107,1,5,50,37,1,23,226,166,1,26,255, + 187,1,12,117,86,1,16,161,118,1,23,230,168,1,5,46,33,1,25,249, + 183,1,8,76,56,1,21,210,154,1,25,246,181,1,6,57,42,1,26,253, + 185,1,2,23,17,1,14,139,102,1,26,255,187,1,13,124,91,1,20,197, + 145,1,26,255,187,5,8,83,61,1,16,160,117,1,15,144,106,1,26,255, + 187,1,11,105,77,1,18,180,132,1,26,255,187,1,20,201,147,1,25,244, + 179,1,20,198,145,1,9,90,66,1,14,142,104,1,16,154,113,1,26,255, + 187,1,7,71,52,1,6,55,40,1,25,250,183,1,13,124,91,1,20,197, + 145,1,26,255,187,4,26,254,186,1,7,71,52,1,25,243,178,1,8,77, + 57,1,26,255,187,1,22,218,160,1,3,31,23,1,7,65,48,1,19,187, + 137,1,26,255,187,2,7,73,53,1,7,66,49,1,26,253,185,1,26,255, + 187,1,8,75,55,1,14,133,97,1,15,149,110,1,13,124,91,1,20,197, + 145,1,26,255,187,4,20,198,145,1,5,47,34,1,12,114,83,1,3,31, + 23,1,25,249,183,1,26,255,187,1,26,251,184,1,17,166,122,1,4,40, + 30,1,23,225,165,1,26,255,187,1,17,162,119,1,13,127,93,1,26,255, + 187,2,8,75,55,1,25,244,179,1,5,54,39,1,12,122,89,1,20,197, + 145,1,26,255,187,4,13,125,91,1,13,129,94,1,17,163,120,1,9,86, + 63,1,18,178,131,1,9,90,66,1,26,255,187,2,14,138,101,1,18,178, + 131,1,26,255,187,1,18,174,128,1,14,137,100,1,26,255,187,2,8,75, + 55,1,26,255,187,1,12,121,89,1,5,46,33,1,20,197,145,1,26,255, + 187,4,7,69,51,1,25,249,183,1,26,255,187,1,20,193,141,1,10,101, + 74,1,13,124,91,1,9,91,67,1,17,163,120,1,6,57,42,1,24,234, + 172,1,26,255,187,1,18,174,128,1,14,137,100,1,26,255,187,2,8,75, + 55,1,26,255,187,1,24,237,174,1,1,12,9,1,20,197,145,1,26,255, + 187,4,15,151,111,1,26,255,187,2,26,253,185,1,15,146,107,1,26,254, + 186,1,14,140,103,1,10,101,74,1,20,195,143,1,26,255,187,2,22,213, + 156,1,20,194,142,1,26,255,187,2,16,159,117,1,26,255,187,2,16,161, + 118,1,23,226,166,1,26,255,187,51,25,248,182,1,14,138,101,1,11,111, + 81,1,23,221,162,1,26,255,187,2,16,160,117,1,10,95,70,1,19,183, + 134,1,26,255,187,1,23,225,165,1,12,119,87,1,26,255,187,2,22,219, + 161,1,14,136,100,1,24,233,171,1,11,113,83,1,26,255,187,2,23,227, + 167,1,13,130,95,1,26,255,187,2,11,106,78,1,12,117,86,1,16,161, + 118,1,6,59,43,1,26,255,187,1,16,157,115,1,6,56,41,1,17,166, + 122,1,7,64,47,1,20,193,141,1,20,198,145,1,0,5,4,1,23,226, + 166,1,26,255,187,1,14,137,100,1,5,50,37,1,22,213,156,1,0,4, + 3,1,22,212,156,1,26,255,187,1,15,150,110,1,4,40,29,1,26,255, + 187,1,25,250,183,1,7,64,47,1,26,255,187,2,15,149,110,1,23,228, + 168,1,5,51,37,1,23,226,166,1,26,255,187,1,24,232,170,1,8,77, + 57,1,20,198,145,1,5,49,36,1,16,158,116,1,26,255,187,1,10,97, + 71,1,8,75,55,1,22,213,156,1,5,49,36,1,15,144,106,1,26,255, + 187,1,10,100,73,1,7,73,53,1,26,255,187,1,22,211,155,1,11,108, + 79,1,26,255,187,4,4,43,32,1,26,255,187,3,7,67,49,1,20,198, + 145,1,11,105,77,1,10,96,71,1,26,255,187,1,10,98,72,1,8,75, + 55,1,22,213,156,1,10,100,73,1,9,89,65,1,26,255,187,1,10,98, + 72,1,8,75,55,1,26,255,187,1,21,204,150,1,11,111,81,1,26,255, + 187,4,6,56,41,1,26,255,187,3,6,55,40,1,20,198,145,1,13,123, + 90,1,8,80,59,1,21,210,154,1,14,138,101,1,8,75,55,1,22,213, + 156,1,11,110,81,1,8,80,59,1,23,224,164,1,13,125,91,1,8,75, + 55,1,26,255,187,1,25,243,178,1,8,77,57,1,26,255,187,2,15,143, + 105,1,22,212,156,1,5,49,36,1,25,244,179,1,26,255,187,1,23,228, + 168,1,6,58,43,1,20,198,145,1,13,123,90,1,10,96,71,1,13,124, + 91,1,21,207,152,1,8,75,55,1,22,213,156,1,11,110,81,1,11,108, + 79,1,13,125,91,1,20,193,141,1,8,75,55,1,26,255,187,2,8,74, + 54,1,19,184,135,1,22,217,159,1,6,55,41,1,26,251,184,1,14,141, + 103,1,10,96,71,1,23,225,165,1,9,86,63,1,15,149,110,1,20,198, + 145,1,13,123,90,1,16,158,116,1,5,45,33,1,26,255,187,1,8,75, + 55,1,22,213,156,1,11,110,81,1,18,172,126,1,4,36,26,1,26,251, + 184,1,8,75,55,1,26,255,187,2,22,219,161,1,8,82,60,1,6,62, + 45,1,19,185,136,1,26,255,187,1,26,254,186,1,12,119,87,1,5,47, + 35,1,12,120,88,1,26,255,187,1,22,212,156,1,16,154,113,1,23,227, + 167,1,11,111,81,1,26,255,187,1,12,116,85,1,23,224,164,1,15,143, + 105,1,24,238,175,1,10,101,74,1,26,255,187,1,12,116,85,1,26,255, + 187,73,148,5,0,0,207,207,207,23,201,201,201,1,207,207,207,23,201,201, + 201,1,207,207,207,23,201,201,201,1,207,207,207,3,212,212,212,1,238,238, + 238,1,207,207,207,2,210,210,210,1,240,240,240,1,246,246,246,1,222,222, + 222,1,211,211,211,1,234,234,234,1,207,207,207,2,227,227,227,1,218,218, + 218,1,239,239,239,1,208,208,208,1,207,207,207,1,224,224,224,1,214,214, + 214,1,207,207,207,1,201,201,201,1,207,207,207,3,225,225,225,1,244,244, + 244,1,212,212,212,1,207,207,207,1,231,231,231,1,222,222,222,1,211,211, + 211,1,245,245,245,1,208,208,208,1,238,238,238,1,214,214,214,1,208,208, + 208,1,242,242,242,1,207,207,207,1,250,250,250,1,226,226,226,1,207,207, + 207,1,229,229,229,1,216,216,216,1,207,207,207,1,201,201,201,1,207,207, + 207,3,237,237,237,1,223,223,223,1,225,225,225,1,207,207,207,1,233,233, + 233,1,219,219,219,1,207,207,207,1,216,216,216,1,209,209,209,1,216,216, + 216,1,236,236,236,1,226,226,226,1,224,224,224,1,207,207,207,1,240,240, + 240,1,243,243,243,1,208,208,208,1,229,229,229,1,216,216,216,1,207,207, + 207,1,201,201,201,1,207,207,207,3,240,240,240,1,209,209,209,1,238,238, + 238,1,207,207,207,1,213,213,213,1,248,248,248,1,241,241,241,1,218,218, + 218,1,207,207,207,2,239,239,239,1,241,241,241,1,207,207,207,2,239,239, + 239,1,228,228,228,1,225,225,225,1,229,229,229,1,216,216,216,1,207,207, + 207,1,201,201,201,1,207,207,207,2,216,216,216,1,245,245,245,1,231,231, + 231,1,248,248,248,1,208,208,208,1,207,207,207,1,208,208,208,1,221,221, + 221,1,246,246,246,1,212,212,212,1,207,207,207,1,222,222,222,1,229,229, + 229,1,207,207,207,2,239,239,239,1,209,209,209,1,243,243,243,1,230,230, + 230,1,216,216,216,1,207,207,207,1,201,201,201,1,207,207,207,2,229,229, + 229,1,228,228,228,1,222,222,222,1,237,237,237,1,219,219,219,1,236,236, + 236,1,207,207,207,2,227,227,227,1,219,219,219,1,207,207,207,1,220,220, + 220,1,227,227,227,1,207,207,207,2,239,239,239,1,207,207,207,1,230,230, + 230,1,245,245,245,1,216,216,216,1,207,207,207,1,201,201,201,1,207,207, + 207,2,240,240,240,1,208,208,208,1,207,207,207,1,217,217,217,1,234,234, + 234,1,229,229,229,1,235,235,235,1,222,222,222,1,242,242,242,1,210,210, + 210,1,207,207,207,1,220,220,220,1,227,227,227,1,207,207,207,2,239,239, + 239,1,207,207,207,1,210,210,210,1,252,252,252,1,216,216,216,1,207,207, + 207,1,201,201,201,1,207,207,207,2,224,224,224,1,207,207,207,3,225,225, + 225,1,207,207,207,1,226,226,226,1,234,234,234,1,217,217,217,1,207,207, + 207,2,214,214,214,1,217,217,217,1,207,207,207,2,223,223,223,1,207,207, + 207,2,222,222,222,1,212,212,212,1,207,207,207,1,201,201,201,1,207,207, + 207,23,201,201,201,1,207,207,207,23,201,201,201,1,207,207,207,1,208,208, + 208,1,227,227,227,1,232,232,232,1,212,212,212,1,207,207,207,2,223,223, + 223,1,235,235,235,1,219,219,219,1,207,207,207,1,212,212,212,1,230,230, + 230,1,207,207,207,2,213,213,213,1,227,227,227,1,210,210,210,1,231,231, + 231,1,207,207,207,2,211,211,211,1,228,228,228,1,201,201,201,1,207,207, + 207,1,233,233,233,1,231,231,231,1,222,222,222,1,242,242,242,1,207,207, + 207,1,223,223,223,1,243,243,243,1,221,221,221,1,241,241,241,1,217,217, + 217,1,216,216,216,1,254,254,254,1,212,212,212,1,207,207,207,1,227,227, + 227,1,244,244,244,1,214,214,214,1,254,254,254,1,214,214,214,1,207,207, + 207,1,224,224,224,1,246,246,246,1,201,201,201,1,208,208,208,1,241,241, + 241,1,207,207,207,2,225,225,225,1,211,211,211,1,244,244,244,1,212,212, + 212,1,207,207,207,1,211,211,211,1,238,238,238,1,216,216,216,1,244,244, + 244,1,223,223,223,1,207,207,207,1,234,234,234,1,239,239,239,1,214,214, + 214,1,244,244,244,1,225,225,225,1,207,207,207,1,234,234,234,1,239,239, + 239,1,201,201,201,1,214,214,214,1,232,232,232,1,207,207,207,4,245,245, + 245,1,207,207,207,3,240,240,240,1,216,216,216,1,233,233,233,1,234,234, + 234,1,207,207,207,1,234,234,234,1,239,239,239,1,214,214,214,1,234,234, + 234,1,236,236,236,1,207,207,207,1,234,234,234,1,239,239,239,1,201,201, + 201,1,215,215,215,1,232,232,232,1,207,207,207,4,243,243,243,1,207,207, + 207,3,243,243,243,1,216,216,216,1,229,229,229,1,238,238,238,1,214,214, + 214,1,227,227,227,1,239,239,239,1,214,214,214,1,232,232,232,1,238,238, + 238,1,212,212,212,1,229,229,229,1,239,239,239,1,201,201,201,1,209,209, + 209,1,238,238,238,1,207,207,207,2,226,226,226,1,214,214,214,1,244,244, + 244,1,209,209,209,1,207,207,207,1,211,211,211,1,242,242,242,1,216,216, + 216,1,229,229,229,1,234,234,234,1,229,229,229,1,215,215,215,1,239,239, + 239,1,214,214,214,1,232,232,232,2,229,229,229,1,217,217,217,1,239,239, + 239,1,201,201,201,1,207,207,207,1,239,239,239,1,218,218,218,1,213,213, + 213,1,243,243,243,1,208,208,208,1,226,226,226,1,234,234,234,1,212,212, + 212,1,237,237,237,1,225,225,225,1,216,216,216,1,229,229,229,1,223,223, + 223,1,245,245,245,1,207,207,207,1,239,239,239,1,214,214,214,1,232,232, + 232,1,221,221,221,1,247,247,247,1,208,208,208,1,239,239,239,1,201,201, + 201,1,207,207,207,1,213,213,213,1,237,237,237,1,241,241,241,1,218,218, + 218,1,207,207,207,2,230,230,230,1,244,244,244,1,230,230,230,1,207,207, + 207,1,214,214,214,1,224,224,224,1,211,211,211,1,232,232,232,1,207,207, + 207,1,231,231,231,1,212,212,212,1,226,226,226,1,210,210,210,1,234,234, + 234,1,207,207,207,1,231,231,231,1,201,201,201,1,207,207,207,23,201,201, + 201,1,207,207,207,23,201,201,201,24,195,195,195,1,0,0) + ); + +const + objdata_tsercommchannel: record size: integer; data: array[0..2066] of byte end = + (size: 2067; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,115,101, + 114,99,111,109,109,99,104,97,110,110,101,108,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,152,7,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,92,3,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,26,255,187,77,17,166,122, + 1,4,40,30,1,7,68,50,1,24,232,170,1,22,216,158,1,5,47,34, + 3,12,120,88,1,18,180,132,1,5,47,34,1,5,47,35,1,7,71,52, + 1,21,207,152,1,26,255,187,10,6,57,42,1,24,232,170,1,16,160,117, + 1,10,99,73,1,21,204,150,1,10,98,72,1,23,226,166,2,24,238,175, + 1,16,161,118,1,15,144,106,1,25,245,180,1,18,179,132,1,7,70,51, + 1,26,255,187,9,26,253,185,1,6,57,42,1,25,242,177,1,26,255,187, + 1,19,190,140,1,21,204,150,1,11,110,81,1,26,255,187,3,16,161,118, + 1,15,149,110,1,26,255,187,1,26,253,185,1,7,66,49,1,26,255,187, + 10,13,132,97,1,2,22,16,1,11,106,78,1,25,240,176,1,21,204,150, + 1,3,32,23,1,7,68,50,2,18,175,128,1,16,161,118,1,6,61,45, + 1,10,98,72,1,6,63,46,1,15,149,110,1,26,255,187,11,23,226,166, + 1,12,114,83,1,8,83,61,1,21,204,150,1,9,90,66,1,21,207,152, + 2,24,237,174,1,16,161,118,1,11,103,76,1,15,148,109,1,7,68,50, + 1,26,255,187,10,21,210,154,1,13,127,93,1,26,255,187,2,8,74,54, + 1,21,204,150,1,11,110,81,1,26,255,187,3,16,161,118,1,15,149,110, + 1,26,255,187,1,11,104,76,1,16,158,116,1,26,255,187,9,25,250,183, + 1,4,44,32,1,15,150,110,1,13,131,96,1,10,98,72,1,21,204,150, + 1,7,69,51,1,16,155,113,2,19,183,134,1,16,161,118,1,15,149,110, + 1,26,255,187,1,23,227,167,1,5,47,35,1,26,255,187,10,22,213,156, + 1,11,110,81,1,12,122,89,1,25,244,179,1,23,230,168,1,12,114,83, + 3,16,153,112,1,21,206,151,1,20,201,147,1,26,255,187,2,15,150,110, + 1,24,232,170,1,26,255,187,57,24,233,171,1,13,123,90,1,13,125,91, + 1,24,237,174,1,26,255,187,1,15,149,110,1,26,255,187,2,17,167,123, + 1,24,236,173,1,26,255,187,1,20,193,141,1,18,176,129,1,26,255,187, + 11,8,74,54,1,14,140,103,1,15,143,105,1,9,84,62,1,26,255,187, + 1,7,68,50,1,26,255,187,2,10,98,72,1,22,218,160,1,26,255,187, + 1,10,95,70,1,8,83,61,1,26,255,187,10,21,203,149,1,10,102,75, + 1,26,255,187,2,13,129,94,1,26,251,184,1,7,68,50,1,26,255,187, + 2,10,98,72,1,22,218,160,1,26,255,187,1,8,74,54,1,9,88,64, + 1,25,240,176,1,26,255,187,9,17,162,119,1,16,154,113,1,26,255,187, + 4,4,38,28,1,11,106,78,2,4,44,32,1,22,218,160,1,22,212,156, + 1,11,104,76,1,15,147,108,1,17,163,120,1,26,255,187,9,16,156,114, + 1,16,157,115,1,26,255,187,4,5,50,37,1,17,163,120,2,7,65,48, + 1,22,218,160,1,14,137,100,1,12,119,87,1,16,153,112,1,9,89,65, + 1,26,255,187,9,19,190,140,1,12,120,88,1,26,255,187,2,12,116,85, + 1,25,244,179,1,7,68,50,1,26,255,187,2,10,98,72,1,22,218,160, + 1,8,76,56,1,10,98,72,2,5,45,33,1,26,255,187,9,25,249,183, + 1,6,55,40,1,22,213,156,1,20,196,144,1,7,69,51,1,26,255,187, + 1,7,68,50,1,26,255,187,2,10,98,72,1,22,214,157,1,7,68,50, + 1,26,255,187,2,10,97,71,1,20,198,145,1,26,255,187,9,20,194,142, + 1,7,69,51,1,8,75,55,1,21,209,153,1,26,255,187,1,11,110,81, + 1,26,255,187,2,14,134,98,1,19,189,139,1,14,142,104,1,26,255,187, + 2,19,182,133,1,16,158,116,1,26,255,187,76,4,4,0,0,195,195,195, + 1,207,207,207,23,195,195,195,1,207,207,207,23,195,195,195,1,207,207,207, + 23,195,195,195,1,207,207,207,4,221,221,221,1,246,246,246,1,240,240,240, + 1,211,211,211,1,213,213,213,1,245,245,245,3,230,230,230,1,219,219,219, + 1,245,245,245,1,244,244,244,1,240,240,240,1,215,215,215,1,207,207,207, + 5,195,195,195,1,207,207,207,4,242,242,242,1,211,211,211,1,223,223,223, + 1,234,234,234,1,215,215,215,1,234,234,234,1,212,212,212,2,210,210,210, + 1,222,222,222,1,225,225,225,1,209,209,209,1,219,219,219,1,240,240,240, + 1,207,207,207,5,195,195,195,1,207,207,207,4,242,242,242,1,209,209,209, + 1,207,207,207,1,217,217,217,1,215,215,215,1,232,232,232,1,207,207,207, + 3,222,222,222,1,225,225,225,1,207,207,207,2,241,241,241,1,207,207,207, + 5,195,195,195,1,207,207,207,4,228,228,228,1,250,250,250,1,233,233,233, + 1,209,209,209,1,215,215,215,1,248,248,248,1,240,240,240,2,220,220,220, + 1,222,222,222,1,242,242,242,1,234,234,234,1,241,241,241,1,225,225,225, + 1,207,207,207,5,195,195,195,1,207,207,207,5,212,212,212,1,231,231,231, + 1,237,237,237,1,215,215,215,1,236,236,236,1,215,215,215,2,210,210,210, + 1,222,222,222,1,233,233,233,1,225,225,225,1,240,240,240,1,207,207,207, + 6,195,195,195,1,207,207,207,3,214,214,214,1,229,229,229,1,207,207,207, + 2,239,239,239,1,215,215,215,1,232,232,232,1,207,207,207,3,222,222,222, + 1,225,225,225,1,207,207,207,1,233,233,233,1,223,223,223,1,207,207,207, + 5,195,195,195,1,207,207,207,3,208,208,208,1,245,245,245,1,224,224,224, + 1,228,228,228,1,234,234,234,1,215,215,215,1,240,240,240,1,224,224,224, + 2,219,219,219,1,222,222,222,1,225,225,225,1,207,207,207,1,211,211,211, + 1,244,244,244,1,207,207,207,5,195,195,195,1,207,207,207,4,214,214,214, + 1,232,232,232,1,230,230,230,1,209,209,209,1,211,211,211,1,231,231,231, + 3,224,224,224,1,215,215,215,1,216,216,216,1,207,207,207,2,224,224,224, + 1,211,211,211,1,207,207,207,4,195,195,195,1,207,207,207,23,195,195,195, + 1,207,207,207,23,195,195,195,1,207,207,207,4,210,210,210,1,229,229,229, + 2,210,210,210,1,207,207,207,1,225,225,225,1,207,207,207,2,221,221,221, + 1,210,210,210,1,207,207,207,1,217,217,217,1,220,220,220,1,207,207,207, + 6,195,195,195,1,207,207,207,4,239,239,239,1,226,226,226,2,237,237,237, + 1,207,207,207,1,240,240,240,1,207,207,207,2,234,234,234,1,213,213,213, + 1,207,207,207,1,235,235,235,1,237,237,237,1,207,207,207,6,195,195,195, + 1,207,207,207,3,215,215,215,1,233,233,233,1,207,207,207,2,228,228,228, + 1,208,208,208,1,240,240,240,1,207,207,207,2,234,234,234,1,213,213,213, + 1,207,207,207,1,239,239,239,1,236,236,236,1,209,209,209,1,207,207,207, + 5,195,195,195,1,207,207,207,3,222,222,222,1,224,224,224,1,207,207,207, + 4,247,247,247,1,233,233,233,2,245,245,245,1,213,213,213,1,214,214,214, + 1,233,233,233,1,225,225,225,1,222,222,222,1,207,207,207,5,195,195,195, + 1,207,207,207,3,223,223,223,2,207,207,207,4,244,244,244,1,222,222,222, + 2,241,241,241,1,213,213,213,1,227,227,227,1,230,230,230,1,224,224,224, + 1,236,236,236,1,207,207,207,5,195,195,195,1,207,207,207,3,217,217,217, + 1,230,230,230,1,207,207,207,2,231,231,231,1,209,209,209,1,240,240,240, + 1,207,207,207,2,234,234,234,1,213,213,213,1,238,238,238,1,234,234,234, + 2,245,245,245,1,207,207,207,5,195,195,195,1,207,207,207,3,208,208,208, + 1,243,243,243,1,214,214,214,1,216,216,216,1,240,240,240,1,207,207,207, + 1,240,240,240,1,207,207,207,2,234,234,234,1,213,213,213,1,240,240,240, + 1,207,207,207,2,234,234,234,1,216,216,216,1,207,207,207,4,195,195,195, + 1,207,207,207,4,217,217,217,1,240,240,240,1,239,239,239,1,214,214,214, + 1,207,207,207,1,232,232,232,1,207,207,207,2,227,227,227,1,218,218,218, + 1,226,226,226,1,207,207,207,2,219,219,219,1,223,223,223,1,207,207,207, + 4,195,195,195,1,207,207,207,23,195,195,195,1,207,207,207,23,183,183,183, + 1,195,195,195,23,0,0) + ); + +const + objdata_tasynsercommchannel: record size: integer; data: array[0..2246] of byte end = + (size: 2247; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,97,115, + 121,110,115,101,114,99,111,109,109,99,104,97,110,110,101,108,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,72,8,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,20,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,255,187, + 75,23,223,164,1,8,77,57,1,26,255,187,2,24,237,174,1,6,67,49, + 1,4,43,31,1,16,161,118,1,23,231,169,1,10,101,74,1,26,255,187, + 2,13,138,101,1,19,189,139,1,7,76,55,1,25,246,181,1,26,255,187, + 1,15,150,110,1,21,210,154,1,26,255,187,5,15,146,108,1,5,50,37, + 1,23,226,166,1,26,255,187,1,12,117,85,1,16,161,118,1,23,230,168, + 1,4,46,33,1,26,249,183,1,8,76,56,1,21,210,154,1,25,246,181, + 1,6,57,42,1,26,253,186,1,2,23,17,1,15,139,103,1,26,255,187, + 1,12,124,91,1,20,197,145,1,26,255,187,5,9,83,61,1,16,160,118, + 1,15,144,107,1,26,255,187,1,11,105,77,1,19,180,133,1,26,255,187, + 1,20,201,148,1,24,244,179,1,20,198,145,1,9,90,66,1,15,142,104, + 1,16,154,113,1,26,255,187,1,7,71,52,1,5,55,40,1,26,250,184, + 1,12,124,91,1,20,197,145,1,26,255,187,4,26,254,186,1,7,71,52, + 1,24,243,178,1,8,77,57,1,26,255,187,1,22,218,160,1,3,31,23, + 1,6,66,48,1,19,187,137,1,26,255,187,2,7,73,53,1,6,67,49, + 1,26,253,186,1,26,255,187,1,7,76,55,1,13,133,97,1,15,150,110, + 1,12,124,91,1,20,197,145,1,26,255,187,4,20,198,145,1,5,47,34, + 1,11,114,84,1,3,31,23,1,26,249,183,1,26,255,187,1,26,251,184, + 1,17,166,122,1,4,40,30,1,23,225,165,1,26,255,187,1,16,162,119, + 1,13,127,92,1,26,255,187,2,7,76,55,1,24,244,179,1,5,54,40, + 1,12,122,89,1,20,197,145,1,26,255,187,4,12,125,91,1,13,129,95, + 1,16,163,119,1,9,86,62,1,19,178,132,1,9,91,66,1,26,255,187, + 2,13,138,101,1,19,178,132,1,26,255,187,1,17,174,128,1,13,137,100, + 1,26,255,187,2,7,76,55,1,26,255,187,1,12,121,89,1,4,46,33, + 1,20,197,145,1,26,255,187,4,7,69,51,1,26,249,183,1,26,255,187, + 1,20,193,141,1,10,101,74,1,12,124,91,1,10,91,67,1,16,163,119, + 1,6,57,42,1,24,234,172,1,26,255,187,1,17,174,128,1,13,137,100, + 1,26,255,187,2,7,76,55,1,26,255,187,1,24,237,174,1,1,12,9, + 1,20,197,145,1,26,255,187,4,16,151,112,1,26,255,187,2,26,253,186, + 1,15,146,108,1,26,254,186,1,15,140,103,1,10,101,74,1,20,195,143, + 1,26,255,187,2,21,213,156,1,20,194,142,1,26,255,187,2,16,159,117, + 1,26,255,187,2,16,161,118,1,23,226,166,1,26,255,187,55,24,233,171, + 1,12,122,90,1,12,125,91,1,24,237,174,1,26,255,187,1,15,150,110, + 1,26,255,187,2,17,167,123,1,24,236,172,1,26,255,187,1,20,193,141, + 1,17,176,129,1,26,255,187,11,7,74,54,1,15,140,103,1,15,143,105, + 1,9,84,61,1,26,255,187,1,7,68,50,1,26,255,187,2,10,98,72, + 1,22,218,160,1,26,255,187,1,10,95,69,1,9,83,61,1,26,255,187, + 10,20,203,149,1,10,102,76,1,26,255,187,2,13,129,95,1,26,251,184, + 1,7,68,50,1,26,255,187,2,10,98,72,1,22,218,160,1,26,255,187, + 1,7,74,54,1,9,88,65,1,24,240,177,1,26,255,187,9,16,162,119, + 1,16,154,113,1,26,255,187,4,4,38,28,1,11,106,78,2,4,44,32, + 1,22,218,160,1,21,212,156,1,11,104,77,1,15,147,108,1,16,163,119, + 1,26,255,187,9,16,156,114,1,16,157,115,1,26,255,187,4,5,50,37, + 1,16,163,119,2,6,66,48,1,22,218,160,1,13,137,100,1,12,119,88, + 1,16,153,112,1,9,89,65,1,26,255,187,9,19,190,140,1,12,120,88, + 1,26,255,187,2,12,116,85,1,24,244,179,1,7,68,50,1,26,255,187, + 2,10,98,72,1,22,218,160,1,8,76,56,1,10,98,72,2,4,45,33, + 1,26,255,187,9,26,249,183,1,5,55,40,1,21,213,156,1,20,196,144, + 1,7,69,51,1,26,255,187,1,7,68,50,1,26,255,187,2,10,98,72, + 1,22,214,158,1,7,68,50,1,26,255,187,2,10,97,72,1,20,198,145, + 1,26,255,187,9,20,194,142,1,7,69,51,1,7,75,54,1,21,209,154, + 1,26,255,187,1,11,110,80,1,26,255,187,2,13,134,99,1,19,189,139, + 1,15,142,104,1,26,255,187,2,19,182,133,1,16,158,115,1,26,255,187, + 76,252,3,0,0,207,207,207,75,212,212,212,1,238,238,238,1,207,207,207, + 2,210,210,210,1,240,240,240,1,246,246,246,1,222,222,222,1,211,211,211, + 1,234,234,234,1,207,207,207,2,227,227,227,1,218,218,218,1,239,239,239, + 1,208,208,208,1,207,207,207,1,224,224,224,1,214,214,214,1,207,207,207, + 5,225,225,225,1,244,244,244,1,212,212,212,1,207,207,207,1,231,231,231, + 1,222,222,222,1,211,211,211,1,245,245,245,1,208,208,208,1,238,238,238, + 1,214,214,214,1,208,208,208,1,242,242,242,1,207,207,207,1,250,250,250, + 1,226,226,226,1,207,207,207,1,229,229,229,1,216,216,216,1,207,207,207, + 5,237,237,237,1,223,223,223,1,225,225,225,1,207,207,207,1,233,233,233, + 1,219,219,219,1,207,207,207,1,216,216,216,1,209,209,209,1,216,216,216, + 1,236,236,236,1,226,226,226,1,224,224,224,1,207,207,207,1,240,240,240, + 1,243,243,243,1,208,208,208,1,229,229,229,1,216,216,216,1,207,207,207, + 5,240,240,240,1,209,209,209,1,238,238,238,1,207,207,207,1,213,213,213, + 1,248,248,248,1,241,241,241,1,218,218,218,1,207,207,207,2,239,239,239, + 1,241,241,241,1,207,207,207,2,239,239,239,1,228,228,228,1,225,225,225, + 1,229,229,229,1,216,216,216,1,207,207,207,4,216,216,216,1,245,245,245, + 1,231,231,231,1,248,248,248,1,208,208,208,1,207,207,207,1,208,208,208, + 1,221,221,221,1,246,246,246,1,212,212,212,1,207,207,207,1,222,222,222, + 1,229,229,229,1,207,207,207,2,239,239,239,1,209,209,209,1,243,243,243, + 1,230,230,230,1,216,216,216,1,207,207,207,4,229,229,229,1,228,228,228, + 1,222,222,222,1,237,237,237,1,219,219,219,1,236,236,236,1,207,207,207, + 2,227,227,227,1,219,219,219,1,207,207,207,1,220,220,220,1,227,227,227, + 1,207,207,207,2,239,239,239,1,207,207,207,1,230,230,230,1,245,245,245, + 1,216,216,216,1,207,207,207,4,240,240,240,1,208,208,208,1,207,207,207, + 1,217,217,217,1,234,234,234,1,229,229,229,1,235,235,235,1,222,222,222, + 1,242,242,242,1,210,210,210,1,207,207,207,1,220,220,220,1,227,227,227, + 1,207,207,207,2,239,239,239,1,207,207,207,1,210,210,210,1,252,252,252, + 1,216,216,216,1,207,207,207,4,224,224,224,1,207,207,207,3,225,225,225, + 1,207,207,207,1,226,226,226,1,234,234,234,1,217,217,217,1,207,207,207, + 2,214,214,214,1,217,217,217,1,207,207,207,2,223,223,223,1,207,207,207, + 2,222,222,222,1,212,212,212,1,207,207,207,55,210,210,210,1,229,229,229, + 2,210,210,210,1,207,207,207,1,225,225,225,1,207,207,207,2,221,221,221, + 1,210,210,210,1,207,207,207,1,217,217,217,1,220,220,220,1,207,207,207, + 11,239,239,239,1,226,226,226,2,237,237,237,1,207,207,207,1,240,240,240, + 1,207,207,207,2,234,234,234,1,213,213,213,1,207,207,207,1,235,235,235, + 1,237,237,237,1,207,207,207,10,215,215,215,1,233,233,233,1,207,207,207, + 2,228,228,228,1,208,208,208,1,240,240,240,1,207,207,207,2,234,234,234, + 1,213,213,213,1,207,207,207,1,239,239,239,1,236,236,236,1,209,209,209, + 1,207,207,207,9,222,222,222,1,224,224,224,1,207,207,207,4,247,247,247, + 1,233,233,233,2,245,245,245,1,213,213,213,1,214,214,214,1,233,233,233, + 1,225,225,225,1,222,222,222,1,207,207,207,9,223,223,223,2,207,207,207, + 4,244,244,244,1,222,222,222,2,241,241,241,1,213,213,213,1,227,227,227, + 1,230,230,230,1,224,224,224,1,236,236,236,1,207,207,207,9,217,217,217, + 1,230,230,230,1,207,207,207,2,231,231,231,1,209,209,209,1,240,240,240, + 1,207,207,207,2,234,234,234,1,213,213,213,1,238,238,238,1,234,234,234, + 2,245,245,245,1,207,207,207,9,208,208,208,1,243,243,243,1,214,214,214, + 1,216,216,216,1,240,240,240,1,207,207,207,1,240,240,240,1,207,207,207, + 2,234,234,234,1,213,213,213,1,240,240,240,1,207,207,207,2,234,234,234, + 1,216,216,216,1,207,207,207,9,217,217,217,1,240,240,240,1,239,239,239, + 1,214,214,214,1,207,207,207,1,232,232,232,1,207,207,207,2,227,227,227, + 1,218,218,218,1,226,226,226,1,207,207,207,2,219,219,219,1,223,223,223, + 1,207,207,207,76,0,0) + ); + +initialization + registerobjectdata(@objdata_tcommport,tbitmapcomp,'tcommport'); + registerobjectdata(@objdata_tasciicommport,tbitmapcomp,'tasciicommport'); + registerobjectdata(@objdata_tasciiprotport,tbitmapcomp,'tasciiprotport'); + registerobjectdata(@objdata_tcommselector,tbitmapcomp,'tcommselector'); + registerobjectdata(@objdata_tsercommcomp,tbitmapcomp,'tsercommcomp'); + registerobjectdata(@objdata_tsercommchannel,tbitmapcomp,'tsercommchannel'); + registerobjectdata(@objdata_tasynsercommchannel,tbitmapcomp,'tasynsercommchannel'); +end. diff --git a/mseide-msegui/lib/common/regcomponents/regsysutils.pas b/mseide-msegui/lib/common/regcomponents/regsysutils.pas new file mode 100644 index 0000000..ec23168 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regsysutils.pas @@ -0,0 +1,185 @@ +{ MSEide Copyright (c) 1999-2010 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regsysutils; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + msedesignintf,msesysenv,msefilechange,regsysutils_bmp,mseprocess, + msecomponenteditors,msepython, + msetypes{msestrings},msetexteditor, + sysutils,mclasses,msesysenvmanagereditor,mseglob,msepropertyeditors; +type + tarrayelementeditor1 = class(tarrayelementeditor); + + tsysenvmanagereditor = class(tcomponenteditor) + public + constructor create(const adesigner: idesigner; + acomponent: tcomponent); override; + procedure edit; override; + end; + + tprocessoptionseditor = class(tsetpropertyeditor) + protected + function getinvisibleitems: tintegerset; override; + end; + + tpythonscriptseditor = class(tpersistentarraypropertyeditor) + protected + function itemgetvalue(const sender: tarrayelementeditor): msestring + override; + end; + + tpythonpropertyeditor = class(ttextstringspropertyeditor) + private +// factivebefore: boolean; +// fdbactivebefore: boolean; +// fintf: isqlpropertyeditor; + protected +// function nocheck: boolean; virtual; + function getsyntaxindex: integer; override; +// procedure doafterclosequery(var amodalresult: modalresultty); override; +// function gettestbutton: boolean; override; +// function getutf8: boolean; override; + function getcaption: msestring; override; + function ismsestring: boolean; override; + public +// procedure edit; override; + end; + +procedure Register; +begin + registercomponents('NoGui',[tsysenvmanager,tfilechangenotifyer,tmseprocess, + tpythonscript]); + registercomponenteditor(tsysenvmanager,tsysenvmanagereditor); + registerpropertyeditor(typeinfo(processoptionsty),nil,'', + tprocessoptionseditor); + registerpropertyeditor(typeinfo(tpythonscripts),nil,'', + tpythonscriptseditor); + registerpropertyeditor(typeinfo(tpythonstringlist),nil,'', + tpythonpropertyeditor); +end; + +{ tsysenvmanagereditor } + +constructor tsysenvmanagereditor.create(const adesigner: idesigner; + acomponent: tcomponent); +begin + inherited; + fstate:= fstate + [cs_canedit]; +end; + +procedure tsysenvmanagereditor.edit; +begin + if editsysenvmanager(tsysenvmanager(fcomponent)) = mr_ok then begin + fdesigner.componentmodified(fcomponent); + end; +end; + +{ tprocessoptionseditor } + +function tprocessoptionseditor.getinvisibleitems: tintegerset; +begin + result:= [ord(pro_nopipeterminate)]; +end; + +{ tpythonscriptseditor } + +function tpythonscriptseditor.itemgetvalue( + const sender: tarrayelementeditor): msestring; +begin + with tpythonstringlistitem( + tarrayelementeditor1(sender).getpointervalue) do begin + result:= '<'+name+'>'; + end; +end; + +{ tpythonpropertyeditor } + +const + pythonsyntax = +'styles'+lineend+ +' default '''''+lineend+ +' words ''b'''+lineend+ +' comment ''i'' cl_dkblue'+lineend+ +' option ''b'' cl_dkblue'+lineend+ +' string '''' cl_dkblue'+lineend+ +' '+lineend+ +'keyworddefs python'+lineend+ +' ''False'' ''class'' ''finally'' ''is'' ''return'''+lineend+ +' ''None'' ''continue'' ''for'' ''lambda'' ''try'''+lineend+ +' ''True'' ''def'' ''from'' ''nonlocal'' ''while'''+lineend+ +' ''and'' ''del'' ''global'' ''not'' ''with'''+lineend+ +' ''as'' ''elif'' ''if'' ''or'' ''yield'''+lineend+ +' ''assert'' ''else'' ''import'' ''pass'''+lineend+ +' ''break'' ''except'' ''in'' ''raise'''+lineend+ +''+lineend+ +'scope comment1 comment'+lineend+ +' endtokens'+lineend+ +' '''''+lineend+ +'scope string1 string'+lineend+ +' endtokens'+lineend+ +' '''''''' '''''+lineend+ +'scope string2 string'+lineend+ +' endtokens'+lineend+ +' ''"'' '''''+lineend+ +'scope string3 string'+lineend+ +' endtokens'+lineend+ +' '''''''''''''''''+lineend+ +'scope string4 string'+lineend+ +' endtokens'+lineend+ +' ''"""'''+lineend+ +' '+lineend+ +'scope main'+lineend+ +''+lineend+ +' keywords words'+lineend+ +' python'+lineend+ +' calltokens'+lineend+ +' ''#'' comment1'+lineend+ +' '''''''''''''''' string3'+lineend+ +' '''''''' string1'+lineend+ +' ''"""'' string4'+lineend+ +' ''"'' string2'+lineend+ +''; + +var + pythonindex: integer = -1; + +function tpythonpropertyeditor.getsyntaxindex: integer; +begin + if pythonindex < 0 then begin + pythonindex:= msetexteditor.syntaxpainter.readdeffile(pythonsyntax); + end; + result:= pythonindex; +end; + +function tpythonpropertyeditor.getcaption: msestring; +begin + result:= 'Python Editor'; +end; + +function tpythonpropertyeditor.ismsestring: boolean; +begin + result:= true; +end; + +initialization + register; +end. diff --git a/mseide-msegui/lib/common/regcomponents/regsysutils_bmp.pas b/mseide-msegui/lib/common/regcomponents/regsysutils_bmp.pas new file mode 100644 index 0000000..aa2ee7c --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regsysutils_bmp.pas @@ -0,0 +1,558 @@ +unit regsysutils_bmp; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msebitmap; + +const + objdata_tsysenvmanager: record size: integer; data: array[0..2865] of byte end = + (size: 2866; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,115,121, + 115,101,110,118,109,97,110,97,103,101,114,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,184,10,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,232,8,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,1,7,6,5,1, + 22,18,17,1,225,185,181,1,226,188,183,1,141,118,115,1,7,6,6,2, + 60,51,50,1,231,198,195,1,232,201,197,1,84,73,72,1,7,6,6,2, + 113,100,99,1,236,211,208,1,237,213,210,1,37,33,33,1,7,7,7,2, + 203,187,185,1,242,224,222,1,230,214,212,1,4,4,3,1,148,119,116,1, + 223,181,176,1,224,183,179,1,225,185,181,1,226,188,183,1,227,190,185,1, + 228,192,188,1,229,194,190,1,230,196,192,1,231,198,195,1,232,201,197,1, + 232,203,199,1,233,205,201,1,234,207,204,1,235,209,206,1,236,211,208,1, + 237,213,210,1,238,216,213,1,239,218,215,1,240,220,217,1,241,222,220,1, + 242,224,222,1,243,226,224,1,7,7,7,1,223,180,175,1,223,181,176,1, + 224,183,179,1,225,185,181,1,226,188,183,1,227,190,185,1,228,192,188,1, + 229,194,190,1,230,196,192,1,231,198,195,1,232,201,197,1,232,203,199,1, + 233,205,201,1,234,207,204,1,235,209,206,1,236,211,208,1,237,213,210,1, + 238,216,213,1,239,218,215,1,240,220,217,1,241,222,220,1,242,224,222,1, + 243,226,224,1,28,27,26,1,223,180,175,1,223,181,176,1,224,183,179,1, + 225,185,181,1,226,188,183,1,227,190,185,1,228,192,188,1,229,194,190,1, + 230,196,192,1,231,198,195,1,232,201,197,1,232,203,199,1,233,205,201,1, + 234,207,204,1,235,209,206,1,236,211,208,1,237,213,210,1,238,216,213,1, + 239,218,215,1,240,220,217,1,241,222,220,1,242,224,222,1,243,226,224,1, + 243,228,226,1,18,15,14,1,223,181,176,1,224,183,179,1,225,185,181,1, + 226,188,183,1,0,0,0,1,89,75,74,1,15,13,13,1,157,134,131,1, + 231,198,195,1,232,201,197,1,162,142,139,1,25,22,21,1,10,9,9,1, + 125,111,110,1,236,211,208,1,237,213,210,1,0,0,0,1,67,61,60,1, + 240,220,217,1,241,222,220,1,242,224,222,1,243,226,224,1,243,228,226,1, + 7,5,5,1,223,181,176,1,224,183,179,1,225,185,181,1,226,188,183,1, + 0,0,0,1,156,132,129,1,161,136,133,1,33,28,28,1,231,198,195,1, + 232,201,197,1,226,197,194,1,204,179,176,1,202,179,176,1,13,11,11,1, + 236,211,208,1,237,213,210,1,0,0,0,1,200,182,180,1,240,220,217,1, + 241,222,220,1,242,224,222,1,243,226,224,1,133,125,123,1,14,11,11,1, + 0,0,0,2,225,185,181,1,226,188,183,1,0,0,0,1,223,187,184,1, + 223,189,185,1,5,4,4,1,231,198,195,1,232,201,197,1,161,141,138,1, + 69,61,60,1,28,25,25,1,0,0,0,1,236,211,208,1,237,213,210,1, + 0,0,0,1,238,217,214,1,240,220,217,1,241,222,220,1,242,224,222,1, + 243,226,224,1,7,7,7,1,223,180,175,1,223,181,176,1,224,183,179,1, + 225,185,181,1,226,188,183,1,0,0,0,1,164,138,135,1,162,137,134,1, + 37,32,31,1,231,198,195,1,232,201,197,1,12,10,10,1,161,141,139,1, + 162,144,142,1,0,0,0,1,236,211,208,1,237,213,210,1,0,0,0,1, + 239,218,215,1,240,220,217,1,241,222,220,1,242,224,222,1,243,226,224,1, + 7,7,7,1,223,180,175,1,223,181,176,1,224,183,179,1,225,185,181,1, + 226,188,183,1,0,0,0,1,72,60,59,1,20,17,16,1,166,141,139,1, + 231,198,195,1,232,201,197,1,86,75,73,1,7,6,6,1,103,91,90,1, + 0,0,0,1,236,211,208,1,237,213,210,1,0,0,0,1,239,218,215,1, + 240,220,217,1,241,222,220,1,242,224,222,1,243,226,224,1,75,70,70,1, + 156,126,123,1,223,181,176,1,224,183,179,1,225,185,181,1,226,188,183,1, + 0,0,0,1,228,192,188,1,229,194,190,1,230,196,192,1,231,198,195,1, + 232,201,197,1,232,203,199,1,233,205,201,1,234,207,204,1,235,209,206,1, + 236,211,208,1,237,213,210,1,238,216,213,1,239,218,215,1,240,220,217,1, + 241,222,220,1,242,224,222,1,243,226,224,1,243,228,226,1,7,5,5,1, + 223,181,176,1,224,183,179,1,225,185,181,1,226,188,183,1,0,0,0,1, + 228,192,188,1,229,194,190,1,230,196,192,1,231,198,195,1,232,201,197,1, + 232,203,199,1,233,205,201,1,234,207,204,1,235,209,206,1,236,211,208,1, + 237,213,210,1,238,216,213,1,239,218,215,1,240,220,217,1,241,222,220,1, + 242,224,222,1,243,226,224,1,243,228,226,1,7,5,5,1,223,181,176,1, + 224,183,179,1,225,185,181,1,226,188,183,1,227,190,185,1,228,192,188,1, + 229,194,190,1,230,196,192,1,231,198,195,1,232,201,197,1,232,203,199,1, + 233,205,201,1,234,207,204,1,235,209,206,1,236,211,208,1,237,213,210,1, + 238,216,213,1,239,218,215,1,240,220,217,1,241,222,220,1,242,224,222,1, + 243,226,224,1,75,70,70,1,48,39,38,1,152,124,120,1,4,4,4,1, + 0,0,0,1,29,24,24,1,171,143,139,1,228,192,188,1,229,194,190,1, + 230,196,192,1,231,198,195,1,232,201,197,1,232,203,199,1,233,205,201,1, + 234,207,204,1,235,209,206,1,236,211,208,1,237,213,210,1,238,216,213,1, + 239,218,215,1,240,220,217,1,241,222,220,1,242,224,222,1,243,226,224,1, + 7,7,7,1,223,180,175,1,4,4,3,1,140,114,112,1,0,0,0,1, + 164,136,133,1,34,28,28,1,228,192,188,1,229,194,190,1,230,196,192,1, + 231,198,195,1,232,201,197,1,232,203,199,1,233,205,201,1,234,207,204,1, + 235,209,206,1,236,211,208,1,237,213,210,1,238,216,213,1,239,218,215,1, + 240,220,217,1,241,222,220,1,242,224,222,1,243,226,224,1,7,7,7,1, + 223,180,175,1,62,50,49,1,43,35,34,1,0,0,0,1,185,154,150,1, + 227,190,185,1,228,192,188,1,229,194,190,1,168,143,140,1,23,19,19,1, + 23,20,19,1,177,155,152,1,233,205,201,1,234,207,204,1,0,0,0,1, + 72,65,64,1,7,7,7,1,162,147,145,1,239,218,215,1,47,43,43,1, + 195,179,178,1,242,224,222,1,196,183,181,1,26,24,24,1,93,75,73,1, + 216,175,170,1,127,104,102,1,0,0,0,1,13,11,11,1,113,95,92,1, + 228,192,188,1,229,194,190,1,35,30,29,1,176,151,148,1,179,155,152,1, + 45,40,39,1,233,205,201,1,234,207,204,1,0,0,0,1,168,151,148,1, + 162,145,143,1,5,4,4,1,239,218,215,1,142,130,128,1,102,94,93,1, + 242,224,222,1,104,97,96,1,142,133,132,1,7,5,5,1,223,181,176,1, + 224,183,179,1,0,0,0,1,186,155,151,1,0,0,0,1,228,192,188,1, + 229,194,190,1,3,2,2,1,0,0,0,2,4,3,3,1,233,205,201,1, + 234,207,204,1,0,0,0,1,235,210,207,1,237,213,210,1,0,0,0,1, + 239,218,215,1,228,209,206,1,26,24,24,1,229,212,210,1,27,25,25,1, + 228,214,212,1,7,5,5,1,24,20,19,1,165,135,132,1,0,0,0,1, + 154,128,125,1,4,4,4,1,228,192,188,1,229,194,190,1,31,26,26,1, + 177,151,149,1,200,173,170,1,232,203,199,1,233,205,201,1,234,207,204,1, + 0,0,0,1,236,211,208,1,237,213,210,1,0,0,0,1,239,218,215,1, + 240,220,217,1,93,85,85,1,83,76,76,1,87,81,80,1,28,27,26,1, + 100,81,79,1,154,125,121,1,24,19,19,1,0,0,0,1,11,9,9,1, + 159,133,130,1,228,192,188,1,229,194,190,1,161,138,135,1,21,18,18,1, + 0,0,0,1,53,46,45,1,233,205,201,1,234,207,204,1,0,0,0,1, + 236,211,208,1,237,213,210,1,0,0,0,1,239,218,215,1,240,220,217,1, + 189,174,173,1,0,0,0,1,181,168,167,1,7,7,7,1,223,180,175,1, + 223,181,176,1,224,183,179,1,0,0,0,1,226,188,183,1,227,190,185,1, + 228,192,188,1,229,194,190,1,230,196,192,1,231,198,195,1,232,201,197,1, + 232,203,199,1,233,205,201,1,234,207,204,1,235,209,206,1,236,211,208,1, + 237,213,210,1,238,216,213,1,239,218,215,1,240,220,217,1,241,222,220,1, + 242,224,222,1,243,226,224,1,7,7,7,1,223,180,175,1,223,181,176,1, + 224,183,179,1,225,185,181,1,226,188,183,1,227,190,185,1,228,192,188,1, + 229,194,190,1,230,196,192,1,231,198,195,1,232,201,197,1,232,203,199,1, + 233,205,201,1,234,207,204,1,235,209,206,1,236,211,208,1,237,213,210,1, + 238,216,213,1,239,218,215,1,240,220,217,1,241,222,220,1,242,224,222,1, + 243,226,224,1,230,216,214,1,43,35,34,1,223,181,176,1,224,183,179,1, + 225,185,181,1,226,188,183,1,227,190,185,1,228,192,188,1,229,194,190,1, + 230,196,192,1,231,198,195,1,232,201,197,1,232,203,199,1,233,205,201,1, + 234,207,204,1,235,209,206,1,236,211,208,1,237,213,210,1,238,216,213,1, + 239,218,215,1,240,220,217,1,241,222,220,1,242,224,222,1,243,226,224,1, + 243,228,226,1,7,5,5,1,223,181,176,1,224,183,179,1,225,185,181,1, + 226,188,183,1,227,190,185,1,228,192,188,1,229,194,190,1,230,196,192,1, + 231,198,195,1,232,201,197,1,232,203,199,1,233,205,201,1,234,207,204,1, + 235,209,206,1,236,211,208,1,237,213,210,1,238,216,213,1,239,218,215,1, + 240,220,217,1,241,222,220,1,242,224,222,1,243,226,224,1,205,192,190,1, + 3,3,3,1,167,135,132,1,224,183,179,1,225,185,181,1,11,9,9,1, + 7,6,6,1,22,19,18,1,229,194,190,1,230,196,192,1,143,123,121,1, + 7,6,6,2,61,53,52,1,234,207,204,1,235,209,206,1,85,76,75,1, + 7,6,6,1,7,7,6,1,115,104,103,1,240,220,217,1,241,222,220,1, + 37,35,34,1,7,7,7,1,4,4,3,1,152,1,0,0,244,244,244,1, + 248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1,248,248,248,2, + 203,203,203,1,128,128,128,2,188,188,188,1,248,248,248,2,173,173,173,1, + 128,128,128,2,221,221,221,1,248,248,248,2,139,139,139,1,128,128,128,1, + 131,131,131,1,244,244,244,1,154,154,154,1,255,255,255,22,248,248,248,1, + 128,128,128,1,255,255,255,22,229,229,229,1,128,128,128,1,255,255,255,22, + 128,128,128,1,236,236,236,1,255,255,255,22,128,128,128,1,248,248,248,1, + 255,255,255,22,165,165,165,1,240,240,240,1,255,255,255,22,248,248,248,1, + 128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22, + 195,195,195,1,150,150,150,1,255,255,255,22,128,128,128,1,248,248,248,1, + 255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,195,195,195,1, + 210,210,210,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255,255,22, + 248,248,248,1,128,128,128,1,255,255,255,22,238,238,238,1,180,180,180,1, + 255,255,255,22,181,181,181,1,248,248,248,1,255,255,255,22,136,136,136,1, + 248,248,248,1,255,255,255,22,229,229,229,1,176,176,176,1,255,255,255,22, + 248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1, + 255,255,255,22,131,131,131,1,214,214,214,1,255,255,255,22,128,128,128,1, + 248,248,248,1,255,255,255,22,139,139,139,1,244,244,244,1,146,146,146,1, + 128,128,128,2,244,244,244,1,248,248,248,1,233,233,233,1,128,128,128,2, + 158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2,188,188,188,1, + 248,248,248,2,173,173,173,1,128,128,128,2,221,221,221,1,248,248,248,1, + 244,244,244,1,0,0) + ); + +const + objdata_tmseprocess: record size: integer; data: array[0..2858] of byte end = + (size: 2859; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,109,115, + 101,112,114,111,99,101,115,115,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,180,10,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,232,8,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,1,3,3,3,1,19,16,15, + 1,225,185,181,1,226,188,183,1,142,119,115,1,3,3,3,2,59,50,49, + 1,231,198,195,1,232,201,197,1,84,73,72,1,3,3,3,2,113,101,99, + 1,236,211,208,1,237,213,210,1,39,36,35,1,4,3,3,2,191,176,175, + 1,242,224,222,1,231,215,213,1,0,0,0,1,158,127,124,1,223,181,176, + 1,224,183,179,1,225,185,181,1,226,188,183,1,227,190,185,1,228,192,188, + 1,229,194,190,1,230,196,192,1,231,198,195,1,232,201,197,1,232,203,199, + 1,233,205,201,1,234,207,204,1,235,209,206,1,236,211,208,1,237,213,210, + 1,238,216,213,1,239,218,215,1,240,220,217,1,241,222,220,1,242,224,222, + 1,243,226,224,1,4,3,3,1,223,180,175,1,223,181,176,1,224,183,179, + 1,225,185,181,1,226,188,183,1,227,190,185,1,228,192,188,1,229,194,190, + 1,230,196,192,1,231,198,195,1,232,201,197,1,232,203,199,1,233,205,201, + 1,234,207,204,1,235,209,206,1,236,211,208,1,237,213,210,1,238,216,213, + 1,239,218,215,1,240,220,217,1,241,222,220,1,242,224,222,1,243,226,224, + 1,30,29,28,1,223,180,175,1,223,181,176,1,224,183,179,1,225,185,181, + 1,226,188,183,1,227,190,185,1,228,192,188,1,229,194,190,1,230,196,192, + 1,231,198,195,1,232,201,197,1,232,203,199,1,233,205,201,1,234,207,204, + 1,235,209,206,1,236,211,208,1,237,213,210,1,238,216,213,1,239,218,215, + 1,240,220,217,1,241,222,220,1,242,224,222,1,243,226,224,1,243,228,226, + 1,11,9,9,1,223,181,176,1,224,183,179,1,225,185,181,1,226,188,183, + 1,227,190,185,1,228,192,188,1,229,194,190,1,230,196,192,1,231,198,195, + 1,232,201,197,1,232,203,199,1,233,205,201,1,234,207,204,1,235,209,206, + 1,236,211,208,1,237,213,210,1,238,216,213,1,239,218,215,1,240,220,217, + 1,241,222,220,1,242,224,222,1,243,226,224,1,243,228,226,1,3,3,3, + 1,223,181,176,1,224,183,179,1,225,185,181,1,226,188,183,1,227,190,185, + 1,228,192,188,1,229,194,190,1,230,196,192,1,231,198,195,1,232,201,197, + 1,232,203,199,1,233,205,201,1,234,207,204,1,235,209,206,1,236,211,208, + 1,237,213,210,1,238,216,213,1,239,218,215,1,240,220,217,1,241,222,220, + 1,242,224,222,1,243,226,224,1,134,126,125,1,11,9,9,1,223,181,176, + 1,224,183,179,1,225,185,181,1,226,188,183,1,227,190,185,1,228,192,188, + 1,229,194,190,1,230,196,192,1,231,198,195,1,232,201,197,1,232,203,199, + 1,233,205,201,1,234,207,204,1,235,209,206,1,236,211,208,1,237,213,210, + 1,238,216,213,1,239,218,215,1,240,220,217,1,241,222,220,1,242,224,222, + 1,243,226,224,1,4,3,3,1,223,180,175,1,223,181,176,1,219,179,175, + 1,218,179,175,1,220,183,178,1,226,189,184,1,228,192,188,1,229,194,190, + 1,230,196,192,1,231,198,195,1,232,201,197,1,232,203,199,1,233,205,201, + 1,234,207,204,1,235,209,206,1,236,211,208,1,237,213,210,1,238,216,213, + 1,239,218,215,1,240,220,217,1,241,222,220,1,242,224,222,1,243,226,224, + 1,4,3,3,1,223,180,175,1,223,181,176,1,42,34,34,1,35,29,28, + 1,42,35,34,1,36,30,29,1,47,40,39,1,198,168,165,1,230,196,192, + 1,231,198,195,1,232,201,197,1,232,203,199,1,233,205,201,1,234,207,204, + 1,235,209,206,1,236,211,208,1,237,213,210,1,238,216,213,1,239,218,215, + 1,240,220,217,1,241,222,220,1,242,224,222,1,243,226,224,1,75,70,70, + 1,158,127,124,1,223,181,176,1,42,34,34,1,190,156,153,1,226,188,183, + 1,227,190,185,1,121,102,100,1,85,72,71,1,229,195,191,1,226,194,191, + 1,218,189,185,1,229,201,197,1,233,205,201,1,234,207,204,1,220,196,193, + 1,236,211,208,1,237,213,210,1,238,216,213,1,239,218,215,1,232,213,210, + 1,229,211,209,1,242,224,222,1,243,226,224,1,243,228,226,1,3,3,3, + 1,223,181,176,1,42,34,34,1,190,156,153,1,226,188,183,1,227,190,185, + 1,136,114,112,1,94,80,78,1,199,170,166,1,42,36,35,1,36,32,31, + 1,110,96,94,1,175,154,151,1,53,47,46,1,70,62,61,1,71,64,63, + 1,206,185,183,1,238,216,213,1,128,117,116,1,43,40,39,1,69,64,63, + 1,113,105,104,1,243,226,224,1,243,228,226,1,3,3,3,1,223,181,176, + 1,42,34,34,1,83,68,67,1,98,82,80,1,72,60,59,1,46,39,38, + 1,186,157,154,1,199,170,166,1,15,13,13,1,224,194,190,1,232,203,199, + 1,34,30,29,1,191,169,166,1,235,209,206,1,149,133,131,1,112,100,99, + 1,213,193,190,1,25,23,23,1,239,219,216,1,241,222,220,1,115,106,105, + 1,235,219,217,1,75,70,70,1,47,38,37,1,223,181,176,1,42,34,34, + 1,136,112,109,1,162,135,131,1,195,163,159,1,228,192,188,1,229,194,190, + 1,199,170,166,1,49,42,41,1,232,201,197,1,229,201,197,1,19,17,17, + 1,234,207,204,1,235,209,206,1,213,190,188,1,43,38,38,1,175,159,157, + 1,82,74,73,1,240,220,217,1,241,222,220,1,242,224,222,1,243,226,224, + 1,4,3,3,1,223,180,175,1,223,181,176,1,42,34,34,1,190,156,153, + 1,226,188,183,1,227,190,185,1,228,192,188,1,229,194,190,1,199,170,166, + 1,53,45,44,1,232,201,197,1,232,203,199,1,58,51,50,1,207,183,181, + 1,235,209,206,1,167,149,147,1,71,63,63,1,224,203,200,1,48,44,43, + 1,240,220,217,1,241,222,220,1,121,112,111,1,225,209,207,1,4,3,3, + 1,223,180,175,1,223,181,176,1,42,34,34,1,190,156,153,1,226,188,183, + 1,227,190,185,1,228,192,188,1,229,194,190,1,199,170,166,1,53,45,44, + 1,232,201,197,1,232,203,199,1,154,136,133,1,58,51,50,1,120,107,105, + 1,38,34,33,1,176,158,156,1,238,216,213,1,97,89,88,1,93,85,84, + 1,111,102,101,1,79,73,72,1,243,226,224,1,134,126,125,1,94,76,74, + 1,223,181,176,1,179,146,143,1,216,178,174,1,226,188,183,1,227,190,185, + 1,228,192,188,1,229,194,190,1,223,190,186,1,187,160,158,1,232,201,197, + 1,232,203,199,1,233,205,201,1,222,196,194,1,166,148,145,1,216,193,190, + 1,237,213,210,1,238,216,213,1,239,218,215,1,206,189,186,1,188,173,172, + 1,242,224,222,1,243,226,224,1,243,228,226,1,3,3,3,1,223,181,176, + 1,224,183,179,1,225,185,181,1,226,188,183,1,227,190,185,1,228,192,188, + 1,229,194,190,1,230,196,192,1,231,198,195,1,232,201,197,1,232,203,199, + 1,233,205,201,1,234,207,204,1,235,209,206,1,236,211,208,1,237,213,210, + 1,238,216,213,1,239,218,215,1,240,220,217,1,241,222,220,1,242,224,222, + 1,243,226,224,1,243,228,226,1,3,3,3,1,223,181,176,1,224,183,179, + 1,225,185,181,1,226,188,183,1,227,190,185,1,228,192,188,1,229,194,190, + 1,230,196,192,1,231,198,195,1,232,201,197,1,232,203,199,1,233,205,201, + 1,234,207,204,1,235,209,206,1,236,211,208,1,237,213,210,1,238,216,213, + 1,239,218,215,1,240,220,217,1,241,222,220,1,242,224,222,1,243,226,224, + 1,30,29,28,1,94,76,74,1,223,181,176,1,224,183,179,1,225,185,181, + 1,226,188,183,1,227,190,185,1,228,192,188,1,229,194,190,1,230,196,192, + 1,231,198,195,1,232,201,197,1,232,203,199,1,233,205,201,1,234,207,204, + 1,235,209,206,1,236,211,208,1,237,213,210,1,238,216,213,1,239,218,215, + 1,240,220,217,1,241,222,220,1,242,224,222,1,243,226,224,1,4,3,3, + 1,223,180,175,1,223,181,176,1,224,183,179,1,225,185,181,1,226,188,183, + 1,227,190,185,1,228,192,188,1,229,194,190,1,230,196,192,1,231,198,195, + 1,232,201,197,1,232,203,199,1,233,205,201,1,234,207,204,1,235,209,206, + 1,236,211,208,1,237,213,210,1,238,216,213,1,239,218,215,1,240,220,217, + 1,241,222,220,1,242,224,222,1,243,226,224,1,4,3,3,1,223,180,175, + 1,223,181,176,1,224,183,179,1,225,185,181,1,226,188,183,1,227,190,185, + 1,228,192,188,1,229,194,190,1,230,196,192,1,231,198,195,1,232,201,197, + 1,232,203,199,1,233,205,201,1,234,207,204,1,235,209,206,1,236,211,208, + 1,237,213,210,1,238,216,213,1,239,218,215,1,240,220,217,1,241,222,220, + 1,242,224,222,1,243,226,224,1,218,204,202,1,47,38,37,1,223,181,176, + 1,224,183,179,1,225,185,181,1,226,188,183,1,227,190,185,1,228,192,188, + 1,229,194,190,1,230,196,192,1,231,198,195,1,232,201,197,1,232,203,199, + 1,233,205,201,1,234,207,204,1,235,209,206,1,236,211,208,1,237,213,210, + 1,238,216,213,1,239,218,215,1,240,220,217,1,241,222,220,1,242,224,222, + 1,243,226,224,1,243,228,226,1,3,3,3,1,223,181,176,1,224,183,179, + 1,225,185,181,1,226,188,183,1,227,190,185,1,228,192,188,1,229,194,190, + 1,230,196,192,1,231,198,195,1,232,201,197,1,232,203,199,1,233,205,201, + 1,234,207,204,1,235,209,206,1,236,211,208,1,237,213,210,1,238,216,213, + 1,239,218,215,1,240,220,217,1,241,222,220,1,242,224,222,1,243,226,224, + 1,218,204,202,1,0,0,0,1,177,144,140,1,224,183,179,1,225,185,181, + 1,3,3,3,2,19,16,16,1,229,194,190,1,230,196,192,1,144,124,122, + 1,3,3,3,2,60,52,51,1,234,207,204,1,235,209,206,1,85,76,75, + 1,4,3,3,2,115,105,104,1,240,220,217,1,241,222,220,1,40,37,37, + 1,4,3,3,1,0,0,0,1,148,1,0,0,255,255,255,1,252,252,252, + 1,237,237,237,1,136,136,136,2,165,165,165,1,252,252,252,2,208,208,208, + 1,136,136,136,2,194,194,194,1,252,252,252,2,179,179,179,1,136,136,136, + 2,223,223,223,1,252,252,252,2,150,150,150,1,136,136,136,1,139,139,139, + 1,255,255,255,1,157,157,157,1,255,255,255,22,252,252,252,1,136,136,136, + 1,255,255,255,22,230,230,230,1,136,136,136,1,255,255,255,22,136,136,136, + 1,244,244,244,1,255,255,255,22,136,136,136,1,252,252,252,1,255,255,255, + 22,172,172,172,1,244,244,244,1,255,255,255,22,252,252,252,1,136,136,136, + 1,255,255,255,22,252,252,252,1,136,136,136,1,255,255,255,22,201,201,201, + 1,157,157,157,1,255,255,255,22,136,136,136,1,252,252,252,1,255,255,255, + 22,136,136,136,1,252,252,252,1,255,255,255,22,201,201,201,1,215,215,215, + 1,255,255,255,22,252,252,252,1,136,136,136,1,255,255,255,22,252,252,252, + 1,136,136,136,1,255,255,255,22,172,172,172,1,186,186,186,1,255,255,255, + 22,136,136,136,1,252,252,252,1,255,255,255,22,136,136,136,1,252,252,252, + 1,255,255,255,22,230,230,230,1,186,186,186,1,255,255,255,22,252,252,252, + 1,136,136,136,1,255,255,255,22,252,252,252,1,136,136,136,1,255,255,255, + 22,143,143,143,1,215,215,215,1,255,255,255,22,136,136,136,1,252,252,252, + 1,255,255,255,22,143,143,143,1,255,255,255,1,150,150,150,1,136,136,136, + 2,252,252,252,2,237,237,237,1,136,136,136,2,165,165,165,1,252,252,252, + 2,208,208,208,1,136,136,136,2,194,194,194,1,252,252,252,2,179,179,179, + 1,136,136,136,2,223,223,223,1,252,252,252,1,255,255,255,1,0,0) + ); + +const + objdata_tpythonscript: record size: integer; data: array[0..2868] of byte end = + (size: 2869; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,112,121, + 116,104,111,110,115,99,114,105,112,116,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,188,10,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,236,8,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,2,2,2,1,5,4,4,1,18, + 15,15,1,225,185,181,1,225,187,183,1,143,119,115,1,5,4,4,2,58, + 50,49,1,231,199,195,1,231,201,197,1,82,72,70,1,5,4,4,2,116, + 103,101,1,237,211,209,1,237,213,211,1,37,33,33,1,5,5,5,2,204, + 185,185,1,241,225,221,1,228,213,211,1,3,2,2,1,150,120,117,1,224, + 182,177,1,225,184,179,1,226,186,181,1,226,188,184,1,227,190,186,1,228, + 192,188,1,229,195,190,1,230,197,193,1,231,199,195,1,232,201,197,1,233, + 203,200,1,234,205,202,1,235,207,204,1,236,210,206,1,237,212,209,1,238, + 214,211,1,238,216,213,1,239,218,216,1,240,220,218,1,241,222,220,1,242, + 225,222,1,243,227,225,1,5,5,5,1,223,179,175,1,224,182,177,1,225, + 184,179,1,226,186,181,1,226,188,184,1,227,190,186,1,228,192,188,1,229, + 195,190,1,230,197,193,1,231,199,195,1,232,201,197,1,233,203,200,1,234, + 205,202,1,235,207,204,1,236,210,206,1,237,212,209,1,238,214,211,1,238, + 216,213,1,239,218,216,1,240,220,218,1,241,222,220,1,242,225,222,1,243, + 227,225,1,28,27,27,1,223,179,175,1,224,182,177,1,225,184,179,1,226, + 186,181,1,226,188,184,1,227,190,186,1,228,192,188,1,229,195,190,1,230, + 197,193,1,231,199,195,1,232,201,197,1,233,203,200,1,234,205,202,1,235, + 207,204,1,236,210,206,1,237,212,209,1,238,214,211,1,238,216,213,1,239, + 218,216,1,240,220,218,1,241,222,220,1,242,225,222,1,243,227,225,1,243, + 229,227,1,15,12,12,1,224,182,177,1,225,184,179,1,226,186,181,1,226, + 188,184,1,227,190,186,1,228,192,188,1,229,195,190,1,230,197,193,1,231, + 199,195,1,232,201,197,1,233,203,200,1,234,205,202,1,235,207,204,1,236, + 210,206,1,237,212,209,1,238,214,211,1,238,216,213,1,239,218,216,1,240, + 220,218,1,241,222,220,1,242,225,222,1,243,227,225,1,243,229,227,1,5, + 4,4,1,224,182,177,1,225,184,179,1,226,186,181,1,226,188,184,1,227, + 190,186,1,228,192,188,1,229,195,190,1,230,197,193,1,231,199,195,1,232, + 201,197,1,233,203,200,1,234,205,202,1,235,207,204,1,236,210,206,1,237, + 212,209,1,238,214,211,1,238,216,213,1,239,218,216,1,240,220,218,1,241, + 222,220,1,242,225,222,1,243,227,225,1,135,128,126,1,12,9,9,1,224, + 182,177,1,225,184,179,1,226,186,181,1,226,188,184,1,227,190,186,1,228, + 192,188,1,229,195,190,1,230,197,193,1,231,199,195,1,232,201,197,1,233, + 203,200,1,234,205,202,1,235,207,204,1,236,210,206,1,237,212,209,1,238, + 214,211,1,238,216,213,1,239,218,216,1,240,220,218,1,241,222,220,1,242, + 225,222,1,243,227,225,1,5,5,5,1,223,179,175,1,224,182,177,1,225, + 184,179,1,226,186,181,1,226,188,184,1,227,190,186,1,228,192,188,1,191, + 163,159,1,184,158,154,1,185,159,156,1,202,175,172,1,233,203,200,1,234, + 205,202,1,235,207,204,1,236,210,206,1,237,212,209,1,238,214,211,1,238, + 216,213,1,239,218,216,1,240,220,218,1,241,222,220,1,242,225,222,1,243, + 227,225,1,5,5,5,1,223,179,175,1,224,182,177,1,225,184,179,1,226, + 186,181,1,226,188,184,1,227,190,186,1,228,192,188,1,42,36,35,1,93, + 80,78,1,107,92,90,1,67,58,57,1,71,62,61,1,230,202,199,1,235, + 207,204,1,236,210,206,1,237,212,209,1,238,214,211,1,238,216,213,1,239, + 218,216,1,240,220,218,1,241,222,220,1,242,225,222,1,243,227,225,1,72, + 69,67,1,158,126,124,1,224,182,177,1,225,184,179,1,226,186,181,1,226, + 188,184,1,227,190,186,1,228,192,188,1,42,36,35,1,198,170,167,1,231, + 199,195,1,232,201,197,1,69,60,59,1,161,141,139,1,148,131,129,1,236, + 210,206,1,237,212,209,1,181,163,161,1,202,183,180,1,239,218,216,1,240, + 220,218,1,241,222,220,1,242,225,222,1,243,227,225,1,243,229,227,1,5, + 4,4,1,224,182,177,1,225,184,179,1,226,186,181,1,226,188,184,1,227, + 190,186,1,228,192,188,1,42,36,35,1,198,170,167,1,231,199,195,1,232, + 201,197,1,69,60,59,1,168,147,145,1,41,37,36,1,199,177,174,1,237, + 212,209,1,45,40,40,1,205,186,184,1,239,218,216,1,240,220,218,1,241, + 222,220,1,242,225,222,1,243,227,225,1,243,229,227,1,5,4,4,1,224, + 182,177,1,225,184,179,1,226,186,181,1,226,188,184,1,227,190,186,1,228, + 192,188,1,42,36,35,1,79,68,67,1,92,80,78,1,60,52,51,1,73, + 64,63,1,230,202,199,1,126,111,110,1,120,107,105,1,207,185,183,1,51, + 46,46,1,238,216,213,1,239,218,216,1,240,220,218,1,241,222,220,1,242, + 225,222,1,243,227,225,1,72,69,67,1,47,37,37,1,224,182,177,1,225, + 184,179,1,226,186,181,1,226,188,184,1,227,190,186,1,228,192,188,1,42, + 36,35,1,159,136,133,1,187,161,158,1,213,184,181,1,233,203,200,1,234, + 205,202,1,209,184,182,1,44,40,39,1,134,120,118,1,133,120,118,1,238, + 216,213,1,239,218,216,1,240,220,218,1,241,222,220,1,242,225,222,1,243, + 227,225,1,5,5,5,1,223,179,175,1,224,182,177,1,225,184,179,1,226, + 186,181,1,226,188,184,1,227,190,186,1,228,192,188,1,42,36,35,1,198, + 170,167,1,231,199,195,1,232,201,197,1,233,203,200,1,234,205,202,1,235, + 207,204,1,61,54,53,1,35,32,31,1,214,192,189,1,238,216,213,1,239, + 218,216,1,240,220,218,1,241,222,220,1,242,225,222,1,243,227,225,1,5, + 5,5,1,223,179,175,1,224,182,177,1,225,184,179,1,226,186,181,1,226, + 188,184,1,227,190,186,1,228,192,188,1,42,36,35,1,198,170,167,1,231, + 199,195,1,232,201,197,1,233,203,200,1,234,205,202,1,235,207,204,1,145, + 129,127,1,60,54,53,1,238,214,211,1,238,216,213,1,239,218,216,1,240, + 220,218,1,241,222,220,1,242,225,222,1,243,227,225,1,135,128,126,1,90, + 73,70,1,224,182,177,1,225,184,179,1,226,186,181,1,226,188,184,1,227, + 190,186,1,228,192,188,1,229,195,190,1,230,197,193,1,231,199,195,1,232, + 201,197,1,233,203,200,1,234,205,202,1,235,207,204,1,127,113,111,1,144, + 129,127,1,238,214,211,1,238,216,213,1,239,218,216,1,240,220,218,1,241, + 222,220,1,242,225,222,1,243,227,225,1,243,229,227,1,5,4,4,1,224, + 182,177,1,225,184,179,1,226,186,181,1,226,188,184,1,227,190,186,1,228, + 192,188,1,229,195,190,1,230,197,193,1,231,199,195,1,232,201,197,1,233, + 203,200,1,234,205,202,1,99,87,86,1,49,44,43,1,228,204,201,1,238, + 214,211,1,238,216,213,1,239,218,216,1,240,220,218,1,241,222,220,1,242, + 225,222,1,243,227,225,1,243,229,227,1,5,4,4,1,224,182,177,1,225, + 184,179,1,226,186,181,1,226,188,184,1,227,190,186,1,228,192,188,1,229, + 195,190,1,230,197,193,1,231,199,195,1,232,201,197,1,233,203,200,1,234, + 205,202,1,209,184,182,1,230,205,201,1,237,212,209,1,238,214,211,1,238, + 216,213,1,239,218,216,1,240,220,218,1,241,222,220,1,242,225,222,1,243, + 227,225,1,28,27,27,1,97,77,76,1,224,182,177,1,225,184,179,1,226, + 186,181,1,226,188,184,1,227,190,186,1,228,192,188,1,229,195,190,1,230, + 197,193,1,231,199,195,1,232,201,197,1,233,203,200,1,234,205,202,1,235, + 207,204,1,236,210,206,1,237,212,209,1,238,214,211,1,238,216,213,1,239, + 218,216,1,240,220,218,1,241,222,220,1,242,225,222,1,243,227,225,1,5, + 5,5,1,223,179,175,1,224,182,177,1,225,184,179,1,226,186,181,1,226, + 188,184,1,227,190,186,1,228,192,188,1,229,195,190,1,230,197,193,1,231, + 199,195,1,232,201,197,1,233,203,200,1,234,205,202,1,235,207,204,1,236, + 210,206,1,237,212,209,1,238,214,211,1,238,216,213,1,239,218,216,1,240, + 220,218,1,241,222,220,1,242,225,222,1,243,227,225,1,5,5,5,1,223, + 179,175,1,224,182,177,1,225,184,179,1,226,186,181,1,226,188,184,1,227, + 190,186,1,228,192,188,1,229,195,190,1,230,197,193,1,231,199,195,1,232, + 201,197,1,233,203,200,1,234,205,202,1,235,207,204,1,236,210,206,1,237, + 212,209,1,238,214,211,1,238,216,213,1,239,218,216,1,240,220,218,1,241, + 222,220,1,242,225,222,1,243,227,225,1,228,214,213,1,43,35,33,1,224, + 182,177,1,225,184,179,1,226,186,181,1,226,188,184,1,227,190,186,1,228, + 192,188,1,229,195,190,1,230,197,193,1,231,199,195,1,232,201,197,1,233, + 203,200,1,234,205,202,1,235,207,204,1,236,210,206,1,237,212,209,1,238, + 214,211,1,238,216,213,1,239,218,216,1,240,220,218,1,241,222,220,1,242, + 225,222,1,243,227,225,1,243,229,227,1,5,4,4,1,224,182,177,1,225, + 184,179,1,226,186,181,1,226,188,184,1,227,190,186,1,228,192,188,1,229, + 195,190,1,230,197,193,1,231,199,195,1,232,201,197,1,233,203,200,1,234, + 205,202,1,235,207,204,1,236,210,206,1,237,212,209,1,238,214,211,1,238, + 216,213,1,239,218,216,1,240,220,218,1,241,222,220,1,242,225,222,1,243, + 227,225,1,204,193,191,1,2,2,2,1,168,136,133,1,225,183,179,1,225, + 185,181,1,8,6,6,1,5,4,4,1,18,16,15,1,229,195,189,1,229, + 197,193,1,145,125,122,1,5,4,4,2,59,53,51,1,235,207,203,1,235, + 209,205,1,84,74,73,1,5,5,5,2,118,107,106,1,239,219,217,1,241, + 221,219,1,37,35,35,1,5,5,5,1,3,2,2,1,152,1,0,0,247, + 247,247,1,250,250,250,1,236,236,236,1,128,128,128,2,157,157,157,1,250, + 250,250,2,204,204,204,1,128,128,128,2,189,189,189,1,250,250,250,2,171, + 171,171,1,128,128,128,2,221,221,221,1,250,250,250,2,139,139,139,1,128, + 128,128,1,132,132,132,1,247,247,247,1,153,153,153,1,255,255,255,22,250, + 250,250,1,128,128,128,1,255,255,255,22,229,229,229,1,128,128,128,1,255, + 255,255,22,128,128,128,1,239,239,239,1,255,255,255,22,128,128,128,1,250, + 250,250,1,255,255,255,22,164,164,164,1,243,243,243,1,255,255,255,22,250, + 250,250,1,128,128,128,1,255,255,255,22,250,250,250,1,128,128,128,1,255, + 255,255,22,197,197,197,1,150,150,150,1,255,255,255,22,128,128,128,1,250, + 250,250,1,255,255,255,22,128,128,128,1,250,250,250,1,255,255,255,22,197, + 197,197,1,211,211,211,1,255,255,255,22,250,250,250,1,128,128,128,1,255, + 255,255,22,250,250,250,1,128,128,128,1,255,255,255,22,164,164,164,1,182, + 182,182,1,255,255,255,22,128,128,128,1,250,250,250,1,255,255,255,22,128, + 128,128,1,250,250,250,1,255,255,255,22,229,229,229,1,178,178,178,1,255, + 255,255,22,250,250,250,1,128,128,128,1,255,255,255,22,250,250,250,1,128, + 128,128,1,255,255,255,22,132,132,132,1,214,214,214,1,255,255,255,22,128, + 128,128,1,250,250,250,1,255,255,255,22,139,139,139,1,247,247,247,1,146, + 146,146,1,128,128,128,2,247,247,247,1,250,250,250,1,236,236,236,1,128, + 128,128,2,157,157,157,1,250,250,250,2,204,204,204,1,128,128,128,2,189, + 189,189,1,250,250,250,2,171,171,171,1,128,128,128,2,221,221,221,1,250, + 250,250,1,247,247,247,1,0,0) + ); + +const + objdata_tfilechangenotifyer: record size: integer; data: array[0..1834] of byte end = + (size: 1835; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,102,105, + 108,101,99,104,97,110,103,101,110,111,116,105,102,121,101,114,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,172,6,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,192,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,208,208,208, + 39,15,147,0,2,208,208,208,21,20,144,0,1,27,145,7,1,23,145,5, + 1,0,0,0,1,208,208,208,18,0,128,0,1,19,144,0,1,54,160,38, + 1,146,224,139,1,85,180,73,1,16,109,0,1,0,0,0,1,208,208,208, + 9,0,0,0,2,208,208,208,5,24,146,0,1,21,145,1,1,96,188,85, + 1,179,249,176,1,97,184,86,1,15,95,3,1,1,10,0,1,0,0,0, + 1,208,208,208,7,0,0,0,4,208,208,208,1,0,0,0,1,208,208,208, + 2,18,143,0,1,32,150,14,1,137,217,131,1,157,232,152,1,38,136,25, + 1,11,87,0,1,0,0,0,4,208,208,208,6,0,0,0,7,19,145,0, + 1,61,167,45,1,174,244,171,1,98,188,86,1,20,127,3,1,2,11,0, + 1,0,0,0,6,208,208,208,5,0,0,0,5,7,42,0,1,22,144,3, + 1,111,199,100,1,161,235,155,1,43,150,26,1,12,90,0,1,0,0,0, + 7,208,208,208,7,0,0,0,3,0,4,0,1,29,135,13,1,158,235,154, + 1,98,190,87,1,19,125,3,1,3,31,0,1,0,0,0,8,208,208,208, + 7,0,0,0,2,17,140,0,1,22,61,17,1,134,200,130,1,41,151,24, + 1,10,83,0,1,0,0,0,3,208,208,208,2,0,0,0,5,208,208,208, + 8,18,146,0,1,45,161,29,1,130,214,120,1,22,144,4,1,6,50,0, + 1,0,0,0,3,208,208,208,17,18,136,0,1,21,136,2,1,21,135,0, + 1,21,139,0,1,18,139,0,1,0,128,0,1,208,208,208,19,0,32,0, + 1,15,116,0,1,19,136,0,1,21,138,0,1,20,142,0,1,18,140,0, + 1,208,208,208,19,0,0,0,1,11,68,0,1,16,123,0,1,20,138,0, + 1,21,140,0,1,19,143,0,1,28,142,0,1,208,208,208,18,0,0,0, + 2,10,96,0,1,19,130,0,1,20,140,0,1,20,142,0,1,18,141,0, + 1,208,208,208,18,18,237,0,1,0,35,0,1,0,0,0,1,12,90,0, + 1,19,137,0,1,20,143,0,1,19,142,0,1,0,128,0,1,208,208,208, + 16,29,179,10,1,4,28,2,1,0,0,0,1,3,28,0,1,18,143,0, + 1,18,139,0,1,11,80,0,1,0,0,0,1,208,208,208,15,25,206,0, + 1,83,190,67,1,30,93,24,1,3,25,0,1,17,126,0,1,19,143,0, + 1,0,22,0,1,0,0,0,2,208,208,208,15,60,191,44,1,148,226,140, + 1,68,181,56,1,19,142,0,1,20,136,0,1,0,0,0,3,208,208,208, + 15,31,201,22,1,132,221,124,1,173,244,169,1,101,196,91,1,45,169,28, + 1,18,159,0,1,17,176,0,1,15,226,0,1,208,208,208,16,96,215,82, + 1,174,245,171,1,118,203,108,1,54,160,39,1,18,138,0,2,15,151,0, + 1,11,158,0,1,0,0,0,1,208,208,208,14,36,216,21,1,117,225,111, + 1,65,172,56,1,21,120,13,1,6,52,0,1,0,0,0,5,208,208,208, + 14,0,192,0,1,0,0,0,8,208,208,208,16,0,0,0,4,208,208,208, + 13,180,3,0,0,0,0,0,39,33,33,33,2,0,0,0,21,76,76,76, + 1,208,208,208,1,164,164,164,1,1,1,1,1,0,0,0,18,2,2,2, + 1,133,133,133,1,202,202,202,1,253,253,253,1,210,210,210,1,49,49,49, + 1,1,1,1,1,0,0,0,9,61,61,61,1,144,144,144,1,0,0,0, + 5,21,21,21,1,183,183,183,1,211,211,211,1,255,255,255,1,216,216,216, + 1,214,214,214,1,176,176,176,1,3,3,3,1,0,0,0,7,21,21,21, + 1,12,12,12,1,78,78,78,1,199,199,199,1,0,0,0,1,35,35,35, + 1,0,0,0,2,57,57,57,1,204,204,204,1,230,230,230,1,235,235,235, + 1,220,220,220,1,150,150,150,1,116,116,116,1,210,210,210,1,1,1,1, + 1,35,35,35,1,0,0,0,6,132,132,132,1,242,242,242,1,185,185,185, + 1,220,220,220,1,205,205,205,1,249,249,249,1,12,12,12,1,109,109,109, + 1,203,203,203,1,248,248,248,1,213,213,213,1,195,195,195,1,170,170,170, + 1,245,245,245,1,185,185,185,1,223,223,223,1,202,202,202,1,251,251,251, + 1,17,17,17,1,0,0,0,5,4,4,4,1,53,53,53,1,214,214,214, + 1,255,255,255,1,112,112,112,1,33,33,33,1,166,166,166,1,205,205,205, + 1,230,230,230,1,215,215,215,1,133,133,133,1,61,61,61,1,24,24,24, + 1,53,53,53,1,209,209,209,1,255,255,255,1,117,117,117,1,24,24,24, + 1,0,0,0,7,116,116,116,1,219,219,219,1,122,122,122,1,224,224,224, + 1,204,204,204,1,221,221,221,1,208,208,208,1,185,185,185,1,83,83,83, + 1,38,38,38,1,7,7,7,1,1,1,1,1,108,108,108,1,224,224,224, + 1,117,117,117,1,222,222,222,1,25,25,25,1,0,0,0,7,109,109,109, + 1,71,71,71,1,88,88,88,1,234,234,234,1,223,223,223,1,209,209,209, + 1,122,122,122,1,57,57,57,1,17,17,17,1,3,3,3,1,0,0,0, + 2,103,103,103,1,77,77,77,1,1,1,1,1,148,148,148,1,35,35,35, + 1,0,0,0,8,70,70,70,1,237,237,237,1,229,229,229,1,239,239,239, + 1,91,91,91,1,35,35,35,1,6,6,6,1,1,1,1,1,0,0,0, + 17,58,58,58,1,208,208,208,1,231,231,231,1,222,222,222,1,101,101,101, + 1,2,2,2,1,0,0,0,19,8,8,8,1,117,117,117,1,225,225,225, + 1,232,232,232,1,192,192,192,1,42,42,42,1,0,0,0,19,2,2,2, + 1,22,22,22,1,155,155,155,1,234,234,234,1,233,233,233,1,133,133,133, + 1,9,9,9,1,0,0,0,18,1,1,1,1,3,3,3,1,50,50,50, + 1,190,190,190,1,243,243,243,1,219,219,219,1,70,70,70,1,0,0,0, + 18,14,14,14,1,54,54,54,1,83,83,83,1,97,97,97,1,219,219,219, + 1,253,253,253,1,164,164,164,1,4,4,4,1,0,0,0,16,124,124,124, + 1,175,175,175,1,255,255,255,1,72,72,72,1,182,182,182,1,213,213,213, + 1,89,89,89,1,8,8,8,1,0,0,0,15,31,31,31,1,223,223,223, + 1,155,155,155,2,219,219,219,1,119,119,119,1,24,24,24,1,20,20,20, + 1,1,1,1,1,0,0,0,15,149,149,149,1,255,255,255,1,196,196,196, + 1,185,185,185,1,38,38,38,1,14,14,14,1,6,6,6,1,1,1,1, + 1,0,0,0,15,57,57,57,1,240,240,240,1,255,255,255,1,244,244,244, + 1,189,189,189,1,139,139,139,1,88,88,88,1,17,17,17,1,0,0,0, + 16,173,173,173,1,255,255,255,2,244,244,244,1,208,208,208,1,159,159,159, + 1,105,105,105,1,23,23,23,1,1,1,1,1,0,0,0,14,84,84,84, + 1,194,194,194,1,168,168,168,1,143,143,143,1,92,92,92,1,68,68,68, + 1,48,48,48,1,29,29,29,1,9,9,9,1,1,1,1,1,0,0,0, + 14,4,4,4,1,14,14,14,1,48,48,48,1,32,32,32,1,14,14,14, + 1,3,3,3,1,2,2,2,1,1,1,1,2,0,0,0,16,1,1,1, + 1,2,2,2,1,1,1,1,2,0,0,0,13,0,0) + ); + +initialization + registerobjectdata(@objdata_tsysenvmanager,tbitmapcomp,'tsysenvmanager'); + registerobjectdata(@objdata_tmseprocess,tbitmapcomp,'tmseprocess'); + registerobjectdata(@objdata_tpythonscript,tbitmapcomp,'tpythonscript'); + registerobjectdata(@objdata_tfilechangenotifyer,tbitmapcomp,'tfilechangenotifyer'); +end. diff --git a/mseide-msegui/lib/common/regcomponents/regunitgroups.pas b/mseide-msegui/lib/common/regcomponents/regunitgroups.pas new file mode 100644 index 0000000..79796e0 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regunitgroups.pas @@ -0,0 +1,126 @@ +{ MSEide Copyright (c) 2007-2018 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regunitgroups; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +implementation +uses + msedesignintf; + +procedure reggroups; +begin + registerunitgroup(['msegui'],['msegraphics','msegraphutils']); + registerunitgroup(['mseskin'],['mseclasses']); + registerunitgroup(['mseedit'],['msegui','msemenus','mseguiglob','msegraphics','mseapplication','sysutils','msestat','msestatfile','msetypes','msestream']); + registerunitgroup(['msetabs'],['msegui','msemenus','mseguiglob','msegraphics','msewidgets','msegraphutils','msedragglob','msescrollbar']); + registerunitgroup(['msetoolbar'],['msegui','msemenus','mseguiglob','msegraphics','msewidgets']); + registerunitgroup(['msedataedits'],['msegui','msemenus','mseguiglob','msegraphics','msetypes','mseedit','mseificomp','mseifiglob','mseglob','mseificompglob','mseact','msedropdownlist']); + registerunitgroup(['msegraphedits'],['msegui','msemenus','mseguiglob','msegraphics','msescrollbar','msetypes','mseificomp','mseifiglob','mseglob','mseificompglob']); + registerunitgroup(['msesimplewidgets'],['msegui','msemenus','mseguiglob','msegraphics','mseclasses','msegraphutils','msewidgets']); + registerunitgroup(['msegrids'],['msegui','msemenus','mseguiglob','msegraphics','msedragglob','msetypes']); + registerunitgroup(['msewidgets'],['msegui','msemenus','mseguiglob','msegraphics']); + registerunitgroup(['mseificomp'],['mseifiglob','mseglob','mseificompglob']); + registerunitgroup(['mseactions'],['mseclasses']); + registerunitgroup(['mseprocess'],['msepipestream']); + registerunitgroup(['msemenuwidgets'],['msegui','msemenus','mseguiglob','msegraphics']); + registerunitgroup(['msewidgetgrid'],['msegui','msemenus','mseguiglob','msegraphics','msegrids','msetypes']); + registerunitgroup(['msedispwidgets'],['msegui','msemenus','mseguiglob','msegraphics','msetypes','mserichstring']); + registerunitgroup(['msesplitter'],['msegui','msemenus','mseguiglob','msegraphics']); + registerunitgroup(['mseforms'],['msegui','msemenus','mseguiglob','msegraphics','msegraphutils','msewidgets','mseglob','mseevent','mseclasses','msestat','mseguiintf','mseapplication','msedragglob','msedock']); + registerunitgroup(['msedock'],['msegui','msemenus','mseguiglob','msegraphics','msegraphutils','msedragglob']); + registerunitgroup(['mselistbrowser'],['msegui','msemenus','mseguiglob','msegraphics','msedataedits','msetypes','mseedit','msedatanodes','msestat','msegrids','mseificomp','mseifiglob','mseglob']); + registerunitgroup(['mseifigui'],['mseifi','mseifilink','mseifiglob','mseglob','msegui','msemenus','mseguiglob','msegraphics','msegrids','msetypes','mseapplication','mseforms']); + registerunitgroup(['mseifi'],['msesercomm']); + registerunitgroup(['mseifilink'],['mseifiglob','mseglob']); + registerunitgroup(['msesockets'],['msesercomm','msesys']); + registerunitgroup(['mserttistat'],['msestat']); + registerunitgroup(['msefiledialog'],['msegui','msemenus','mseguiglob','msegraphics','mselistbrowser','msegrids','msetypes','msesys','msebitmap','mseglob','msedataedits','mseedit','msedatanodes']); + registerunitgroup(['msedialog'],['msegui','msemenus','mseguiglob','msegraphics','msedataedits','msetypes','mseedit','mseglob']); + registerunitgroup(['msestringcontainer'],['msetypes']); + registerunitgroup(['msecolordialog'],['msegui','msemenus','mseguiglob','msegraphics','msedataedits','msetypes','mseedit','msegraphutils']); + registerunitgroup(['msememodialog'],['msegui','msemenus','mseguiglob','msegraphics','msedataedits','msetypes','mseedit']); + registerunitgroup(['msetextedit'],['msegui','msemenus','mseguiglob','msegraphics','mseedit','msetypes','mseeditglob','msegrids','mserichstring']); + registerunitgroup(['msesyntaxedit'],['msegui','msemenus','mseguiglob','msegraphics','mseedit','msetypes','msetextedit','mseeditglob','msegrids','mserichstring']); + registerunitgroup(['msereport'],['msegui','msemenus','mseguiglob','msegraphics','msesplitter','mdb','mseifiglob','mserichstring','msetypes']); + registerunitgroup(['msesysenv'],['msetypes']); + registerunitgroup(['msepostscriptprinter'],['mseprinter','sysutils','msetypes']); + registerunitgroup(['mseprocmonitorcomp'],['msesystypes']); + registerunitgroup(['mseprinter'],['msegui','msemenus','mseguiglob','msegraphics','msedataedits','msetypes','mseedit']); + registerunitgroup(['mseimage'],['msegui','msemenus','mseguiglob','msegraphics']); + registerunitgroup(['msedial'],['msegui','msemenus','mseguiglob','msegraphics']); + registerunitgroup(['msewindowwidget'],['msegui','msemenus','mseguiglob','msegraphics','mseclasses','msetypes','msegraphutils']); + registerunitgroup(['msechart'],['msegui','msemenus','mseguiglob','msegraphics','msegraphutils']); + registerunitgroup(['msepolygon'],['msegui','msemenus','mseguiglob','msegraphics','msegraphutils']); + registerunitgroup(['msepickwidget'],['msegui','msemenus','mseguiglob','msegraphics','mseclasses','mseobjectpicker','msepointer','msetypes']); + registerunitgroup(['msetraywidget'],['msegui','msemenus','mseguiglob','msegraphics','mseclasses']); + registerunitgroup(['msedockpanelform'],['msetypes','msemenus','mseclasses']); + registerunitgroup(['msechartedit'],['msegui','msemenus','mseguiglob','msegraphics','msegraphutils','msetypes']); + registerunitgroup(['msebarcode'],['msegui','msemenus','mseguiglob','msegraphics']); + registerunitgroup(['mseopenglwidget'],['msegui','msemenus','mseguiglob','msegraphics','mseclasses','msegraphutils','msewindowwidget','msetypes']); + registerunitgroup(['mseopenglcanvaswidget'],['msegui','msemenus','mseguiglob','msegraphics','mseclasses','msegraphutils','msewindowwidget','msetypes']); + registerunitgroup(['msedb'],['mdb','msetypes','mseifiglob']); + registerunitgroup(['msegdiprint'],['mseprinter']); + registerunitgroup(['mseterminal'],['msegui','msemenus','mseguiglob','msegraphics','mseedit','msetypes','msetextedit','mseeditglob','msegrids','mserichstring']); + registerunitgroup(['msedataimage'],['msegui','msemenus','mseguiglob','msegraphics']); + registerunitgroup(['msecalendardatetimeedit'],['msegui','msemenus','mseguiglob','msegraphics','msedataedits','msetypes','mseedit']); + registerunitgroup(['msefoldedit'],['msegui','msemenus','mseguiglob','msegraphics','msedataedits','msetypes','mseedit','msegrids']); + registerunitgroup(['mserealsumedit'],['msegui','msemenus','mseguiglob','msegraphics','msedataedits','msetypes','mseedit']); + registerunitgroup(['mseguirttistat'],['mserttistat','msestat','msegui']); + registerunitgroup(['mseassistivehandler'],['msespeak','mseassistiveclient','mseguiglob','msegrids','msegraphutils','msetypes','mseassistiveserver','mseact','mseshapes','msemenuwidgets','mdb']); + registerunitgroup(['mseguithreadcomp'],['msethreadcomp']); + registerunitgroup(['msesignal'],['msetypes']); + registerunitgroup(['msesigfft'],['msetypes','msesignal']); + registerunitgroup(['msesiggui'],['msegui','msemenus','mseguiglob','msegraphics','msetypes','msegraphedits','msedataedits','mseedit','msegraphutils','msechartedit','msesignal']); + registerunitgroup(['msesigfftgui'],['msegui','msemenus','mseguiglob','msegraphics','msegraphutils','msesignal','msesigfft']); + registerunitgroup(['msesigmidi'],['msemidi','msedatamodules']); + registerunitgroup(['mseaudio'],['msetypes']); + registerunitgroup(['msesqldb'],['msedatabase','sysutils','msqldb','msebufdataset','mdb','msedb','msetypes']); + registerunitgroup(['msedbedit'],['msegui','msemenus','mseguiglob','msegraphics','msedataedits','msetypes','mseedit','mselookupbuffer','msegraphedits','msegrids','mdb']); + registerunitgroup(['msesqlresult'],['msqldb','sysutils','mselookupbuffer']); + registerunitgroup(['msqldb'],['sysutils']); + registerunitgroup(['msedbdispwidgets'],['msegui','msemenus','mseguiglob','msegraphics','msetypes']); + registerunitgroup(['mseibconnection'],['msedatabase','sysutils','msqldb','msetypes']); + registerunitgroup(['msefb3connection'],['msedatabase','sysutils','msqldb','msetypes']); + registerunitgroup(['msefbservice'],['msetypes','sysutils']); + registerunitgroup(['msefb3service'],['msetypes','sysutils']); + registerunitgroup(['msepqconnection'],['msedatabase','sysutils','msqldb','msetypes']); + registerunitgroup(['mseodbcconn'],['msedatabase','sysutils','msqldb','msetypes']); + registerunitgroup(['mselocaldataset'],['msebufdataset','mdb','msedb']); + registerunitgroup(['msedbgraphics'],['mdb','msegui','msemenus','mseguiglob','msegraphics']); + registerunitgroup(['msedbdialog'],['msegui','msemenus','mseguiglob','msegraphics','msedataedits','msetypes','mseedit','msegraphutils','mseglob']); + registerunitgroup(['msedbcalendardatetimeedit'],['msegui','msemenus','mseguiglob','msegraphics','msedataedits','msetypes','mseedit']); + registerunitgroup(['msedbevents'],['msedatabase','sysutils']); + registerunitgroup(['msesqlite3conn'],['msedatabase','sysutils']); + registerunitgroup(['msemysqlconn'],['msedatabase','sysutils','msqldb','msetypes']); + registerunitgroup(['msedblookup'],['msegui','msemenus','mseguiglob','msegraphics','msedataedits','msetypes']); + registerunitgroup(['mserepps'],['msegui','msemenus','mseguiglob','msegraphics','msereport']); + registerunitgroup(['mseifidbcomp'],['msesqlresult','msqldb','sysutils']); + registerunitgroup(['mseifiendpoint'],['msetypes']); + registerunitgroup(['mseifids'],['mdb','msebufdataset','msedb','msesqldb','msetypes']); + registerunitgroup(['mseifidbgui'],['msegui','msemenus','mseguiglob','msegraphics','msegrids','msetypes']); + registerunitgroup(['msecommutils'],['msegui','msemenus','mseguiglob','msegraphics','msedataedits','msetypes','mseedit','msecommport']); + registerunitgroup(['msemysql40conn'],['msedatabase','sysutils','msqldb','msetypes']); + registerunitgroup(['msemysql41conn'],['msedatabase','sysutils','msqldb','msetypes']); + registerunitgroup(['msemysql50conn'],['msedatabase','sysutils','msqldb','msetypes']); + registerunitgroup(['msedbf'],['mdbf','dbf_idxfile','mdb']); + registerunitgroup(['msesdfdata'],['mdb']); + registerunitgroup(['msememds'],['mdb']); +end; + +initialization + reggroups; +end. diff --git a/mseide-msegui/lib/common/regcomponents/regwidgets.pas b/mseide-msegui/lib/common/regcomponents/regwidgets.pas new file mode 100644 index 0000000..db722f1 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regwidgets.pas @@ -0,0 +1,570 @@ +{ MSEide Copyright (c) 1999-2017 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regwidgets; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msetypes,msepropertyeditors,msestrings,sysutils; + +type + tgridpropseditor = class(tpersistentarraypropertyeditor) + protected + procedure itemmoved(const source,dest: integer); override; + end; + + tdatacoleditor = class(tclasselementeditor) + public + function getvalue: msestring; override; + end; + + tdatacolseditor = class(tgridpropseditor) + protected + function geteditorclass: propertyeditorclassty; override; + public + function itemprefix: msestring; override; + end; + +implementation +uses + classes,mclasses,msesimplewidgets,msegrids,msemenus,mseimage,msedispwidgets, + msetoolbar,msetabs,msedesignintf,regwidgets_bmp,mselistbrowser,mserichstring, + msesplitter,msedock,mseforms,mseclasses,typinfo,msearrayprops,msewidgets, + msegui,formdesigner,msedial,msemenuwidgets,msewindowwidget,msechart, + msepolygon,msepickwidget,msetraywidget,msedockpanelform,msechartedit,mseedit, + msebarcode,msedatalist,mseact,mseformatstr,msesizingform, + msetaborderoverrideeditor,msedesigner,mseglob + {$ifndef mse_no_opengl} +// {$ifdef FPC} + ,mseopenglwidget + {$ifdef mse_with_openglcanvas} + ,mseopenglcanvaswidget +// {$endif} + {$endif} + {$endif}; + +type + tpropertyeditor1 = class(tpropertyeditor); + tdatacols1 = class(tdatacols); + tfixcols1 = class(tfixcols); + tfixrows1 = class(tfixrows); + ttaborderoverride1 = class(ttaborderoverride); + + +type + tfixgridpropeditor = class(tarrayelementeditor) + public + function name: msestring; override; + end; + + tfixgridpropseditor = class(tgridpropseditor) + protected + function getelementeditorclass: elementeditorclassty; override; + end; + + tfixrowseditor = class(tfixgridpropseditor) + public + function itemprefix: msestring; override; + end; + + tfixcolseditor = class(tfixgridpropseditor) + public + function itemprefix: msestring; override; + end; + + tcolheaderelementeditor = class(tclasselementeditor) + public + function getvalue: msestring; override; + end; + + tcolheaderspropertyeditor = class(tpersistentarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + end; + + tfixcolheaderspropertyeditor = class(tpersistentarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + function getelementeditorclass: elementeditorclassty; override; + end; + + ttraceeditor = class(tclasselementeditor) + public + function getvalue: msestring; override; + end; + + ttraceseditor = class(tpersistentarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + public + end; + + ttoolbuttoneditor = class(tclasselementeditor) + public + function getvalue: msestring; override; + end; + + ttoolbuttonseditor = class(tpersistentarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + public + end; + + tcoloptionseditor = class(tsetpropertyeditor) + protected + function getinvisibleitems: tintegerset; override; + end; + + tgridoptionseditor = class(tsetpropertyeditor) + protected + function getinvisibleitems: tintegerset; override; + end; + + tframebuttoneditor = class(tclasspropertyeditor) + protected + function dispname: msestring; override; + end; + + tframebuttonitemeditor = class(tclasselementeditor) + public + function dispname: msestring; override; + end; + + tframebuttonseditor = class(tpersistentarraypropertyeditor) + protected + function geteditorclass: propertyeditorclassty; override; + public + end; + + toptionsplaceeditor = class(tsetpropertyeditor) + protected + function getinvisibleitems: tintegerset; override; + end; + + ttaborderoverridepropertyeditor = class(tclasspropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + procedure edit override; + end; + + toptionsdockeditor = class(tsetpropertyeditor) + protected + function getinvisibleitems: tintegerset; override; + end; + +const + mseformintf: designmoduleintfty = + (createfunc: {$ifdef FPC}@{$endif}createmseform; + initnewcomponent: nil; getscale: nil; sourcetoform: nil); + sizingformintf: designmoduleintfty = + (createfunc: {$ifdef FPC}@{$endif}createsizingform; + initnewcomponent: nil; getscale: nil; sourcetoform: nil); + mainformintf: designmoduleintfty = + (createfunc: {$ifdef FPC}@{$endif}createmainform; + initnewcomponent: nil; getscale: nil; sourcetoform: nil); + dockpanelformintf: designmoduleintfty = + (createfunc: {$ifdef FPC}@{$endif}createdockpanelform; + initnewcomponent: nil; getscale: nil; sourcetoform: nil); + subformintf: designmoduleintfty = + (createfunc: {$ifdef FPC}@{$endif}createsubform; + initnewcomponent: nil; getscale: nil; sourcetoform: nil); + scrollboxformintf: designmoduleintfty = + (createfunc: {$ifdef FPC}@{$endif}createscrollboxform; + initnewcomponent: nil; getscale: nil; sourcetoform: nil); + tabformintf: designmoduleintfty = + (createfunc: {$ifdef FPC}@{$endif}createtabform; + initnewcomponent: nil; getscale: nil; sourcetoform: nil); + +procedure Register; +begin + registerclass(tmseform); + registerclass(tdockform); + registerclass(tsubform); + registerclass(tdockpanelform); + registerclass(tscrollboxform); + registerclass(tsizingform); + + registercomponents('Widget',[ + tlabel,ticon, + tstringdisp,trichstringdisp,tintegerdisp,tint64disp,trealdisp,tdatetimedisp, + tbytestringdisp,tbooleandisp, + tedit, + tbutton,trichbutton,tstockglyphbutton,trichstockglyphbutton, + tsimplewidget,teventwidget, + tgroupbox,tscrollbox,tstepbox,tdockpanel,tdockhandle,tmseformwidget, + tdockformwidget, + texpandingwidget,tsplitter,tspacer,tlayouter, + tmainmenuwidget, + ttoolbar, + ttabbar,ttabwidget,ttabpage, + tdrawgrid,tstringgrid,tlistview, + tpaintbox,tpolygon,tpickwidget,timage,tbarcode, + tdial,tchart,txychartedit,txserieschartedit,tchartrecorder, + twindowwidget + {$ifndef mse_no_opengl} + {$ifdef FPC} + ,topenglwidget + {$ifdef mse_with_openglcanvas} + ,topenglcanvaswidget + {$endif} + {$endif} + {$endif} + ,ttraywidget,tdockpanelformcontroller + ]); + registercomponenttabhints(['Widget'], + ['Display widgets, edit widgets which can''t be placed into twidgetgrid']); + registerpropertyeditor(typeinfo(tcellframe),nil,'', + toptionalclasspropertyeditor); + registerpropertyeditor(typeinfo(tdatacols),nil,'',tdatacolseditor); + registerpropertyeditor(typeinfo(tfixcols),nil,'',tfixcolseditor); + registerpropertyeditor(typeinfo(tfixrows),nil,'',tfixrowseditor); + registerpropertyeditor(typeinfo(tfixcolheaders),nil,'', + tfixcolheaderspropertyeditor); + registerpropertyeditor(typeinfo(integer),tcolheader,'mergecols', + tvolatileordinalpropertyeditor); + registerpropertyeditor(typeinfo(tcolheaders),nil,'',tcolheaderspropertyeditor); + registerpropertyeditor(typeinfo(twidget),tsplitter,'linkleft', + tsisterwidgetpropertyeditor); + registerpropertyeditor(typeinfo(twidget),tsplitter,'linktop', + tsisterwidgetpropertyeditor); + registerpropertyeditor(typeinfo(twidget),tsplitter,'linkright', + tsisterwidgetpropertyeditor); + registerpropertyeditor(typeinfo(twidget),tsplitter,'linkbottom', + tsisterwidgetpropertyeditor); + registerpropertyeditor(typeinfo(twidget),tspacer,'linkleft', + tsisterwidgetpropertyeditor); + registerpropertyeditor(typeinfo(twidget),tspacer,'linktop', + tsisterwidgetpropertyeditor); + registerpropertyeditor(typeinfo(twidget),tspacer,'linkright', + tsisterwidgetpropertyeditor); + registerpropertyeditor(typeinfo(twidget),tspacer,'linkbottom', + tsisterwidgetpropertyeditor); + + registerpropertyeditor(typeinfo(twidget),tlayouter,'linkleft', + tsisterwidgetpropertyeditor); + registerpropertyeditor(typeinfo(twidget),tlayouter,'linktop', + tsisterwidgetpropertyeditor); + registerpropertyeditor(typeinfo(twidget),tlayouter,'linkright', + tsisterwidgetpropertyeditor); + registerpropertyeditor(typeinfo(twidget),tlayouter,'linkbottom', + tsisterwidgetpropertyeditor); + registerpropertyeditor(typeinfo(twidget),tlayouter,'align_leader', + tchildwidgetpropertyeditor); + registerpropertyeditor(typeinfo(placeoptionsty),tlayouter,'place_options', + toptionsplaceeditor); + +// registerpropertyeditor(typeinfo(tface),tdial,'',toptionalclasspropertyeditor); + registerpropertyeditor(typeinfo(ttraces),nil,'',ttraceseditor); + registerpropertyeditor(typeinfo(ttoolbuttons),nil,'',ttoolbuttonseditor); + registerpropertyeditor(typeinfo(trealdatalist),ttrace,'', + toptionaldatalistpropertyeditor); + + registerpropertyeditor(typeinfo(boolean),tcustombutton,'visible', + trefreshbooleanpropertyeditor); + registerpropertyeditor(typeinfo(boolean),tcustombutton,'enabled', + trefreshbooleanpropertyeditor); + registerpropertyeditor(typeinfo(coloptionsty),nil,'', + tcoloptionseditor); + registerpropertyeditor(typeinfo(optionsgridty),nil,'', + tgridoptionseditor); + registerpropertyeditor(typeinfo(tframebutton),nil,'', + tframebuttoneditor); + registerpropertyeditor(typeinfo(tframebuttons),nil,'', + tframebuttonseditor); + registerpropertyeditor(typeinfo(msestring),tcustomrichstringdisp,'value', + trichstringpropertyeditor); + registerpropertyeditor(typeinfo(msestring),tcustomrichbutton,'captionrich', + trichstringpropertyeditor); + + registerpropertyeditor(typeinfo(labeloptionsty),tcustomlabel,'', + tvolatilesetpropertyeditor); + + registerpropertyeditor(typeinfo(ttaborderoverride),nil,'', + ttaborderoverridepropertyeditor); + registerpropertyeditor(typeinfo(optionsdockty),nil,'', + toptionsdockeditor); + + registerunitgroup(['msegrids'],['msegui','msegraphutils','mseclasses', + 'msegridsglob']); + registerunitgroup(['msewidgetgrid'],['msedataedits', + 'msegui','msegraphutils','mseclasses']); + + registerdesignmoduleclass(tmseform,@mseformintf); + registerdesignmoduleclass(tsizingform,@sizingformintf); + registerdesignmoduleclass(tmainform,@mainformintf); + registerdesignmoduleclass(tdockform,@mseformintf); + registerdesignmoduleclass(tdockpanelform,@dockpanelformintf); + registerdesignmoduleclass(tsubform,@subformintf); + registerdesignmoduleclass(tscrollboxform,@scrollboxformintf); + registerdesignmoduleclass(ttabform,@tabformintf); +end; + +{ tgridpropseditor } + +procedure tgridpropseditor.itemmoved(const source,dest: integer); +var + int1: integer; +begin + inherited; + for int1:= 0 to high(fprops) do begin + with fprops[int1] do begin + if instance is tcustomgrid then begin + tcustomgrid(instance).layoutchanged; + end; + end; + end; +end; + +{ tfixgridpropeditor } + +function tfixgridpropeditor.name: msestring; +begin +// result:= 'Item '+inttostr(findex - tarrayprop(tpropertyeditor1(fparenteditor).getordvalue).count); + result:= tpersistentarraypropertyeditor(fparenteditor).itemprefix+ + inttostrmse(-findex - 1); +end; + +{ tfixgridpropseditor } + +function tfixgridpropseditor.getelementeditorclass: elementeditorclassty; +begin + result:= tfixgridpropeditor; +end; + +{ tdatacoleditor } + +function tdatacoleditor.getvalue: msestring; +begin + result:= msestring('<'+tdatacol(getpointervalue).name+'>'); +end; + +{ tdatacolseditor } + +function tdatacolseditor.geteditorclass: propertyeditorclassty; +begin + result:= tdatacoleditor; +end; +(* +procedure tdatacolseditor.move(const curindex: integer; + const newindex: integer); +var + int1: integer; +begin + inherited; + { + for int1:= 0 to high(fprops) do begin + with tdatacols1(getordvalue(int1)) do begin + move(curindex,newindex); +// tfixrows1(fgrid.fixrows).movecol(curindex,newindex); + end; + end; + } +end; + +*) + +function tdatacolseditor.itemprefix: msestring; +begin + result:= 'Col '; +end; + +{ tfixcolseditor } + +function tfixcolseditor.itemprefix: msestring; +begin + result:= 'Col '; +end; + +{ tcolheaderelementeditor } + +function tcolheaderelementeditor.getvalue: msestring; +begin + result:= '<'+tcolheader(getpointervalue).caption+'>'; +end; + +{ tcolheaderspropertyeditor } + +function tcolheaderspropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tcolheaderelementeditor; +end; + +{ tfixcolheaderspropertyeditor } + +function tfixcolheaderspropertyeditor.geteditorclass: propertyeditorclassty; +begin + result:= tcolheaderelementeditor; +end; + +function tfixcolheaderspropertyeditor.getelementeditorclass: elementeditorclassty; +begin + result:= tfixgridpropeditor; +end; + +{ tfixrowseditor } + +function tfixrowseditor.itemprefix: msestring; +begin + result:= 'Row '; +end; + +{ ttraceeditor } + +function ttraceeditor.getvalue: msestring; +begin + result:= msestring('<'+ttrace(getpointervalue).name+'>'); +end; + +{ ttraceseditor } + +function ttraceseditor.geteditorclass: propertyeditorclassty; +begin + result:= ttraceeditor; +end; + +{ ttoolbuttoneditor } + +function ttoolbuttoneditor.getvalue: msestring; +begin + with ttoolbutton(getpointervalue) do begin + if mao_separator in options then begin + result:= '<---->'; + end + else begin + if action <> nil then begin + result:= msestring('<'+action.name+'>'); + end + else begin + result:= '<>'; + end; + end; + end; +end; + +{ ttoolbuttonseditor } + +function ttoolbuttonseditor.geteditorclass: propertyeditorclassty; +begin + result:= ttoolbuttoneditor; +end; + +{ tcoloptionseditor } + +function tcoloptionseditor.getinvisibleitems: tintegerset; +begin + result:= invisiblecoloptions; +end; + +{ tgridoptionseditor } + +function tgridoptionseditor.getinvisibleitems: tintegerset; +begin + result:= invisibleoptionsgrid; +end; + +{ tframebuttoneditor } + +function tframebuttoneditor.dispname(): msestring; +begin + with tframebutton(getpointervalue()) do begin + if action <> nil then begin + result:= msestring(action.name); + end + else begin + result:= inherited dispname(); + end; + end; +end; + +{ tframebuttonitemeditor } + +function tframebuttonitemeditor.dispname: msestring; +begin + with tframebutton(getpointervalue()) do begin + if action <> nil then begin + result:= msestring(action.name); + end + else begin + result:= inherited dispname(); + end; + end; +end; + +{ tframebuttonseditor } + +function tframebuttonseditor.geteditorclass: propertyeditorclassty; +begin + result:= tframebuttonitemeditor; +end; + +{ toptionsplaceeditor } + +function toptionsplaceeditor.getinvisibleitems: tintegerset; +begin + result:= invisibleplaceoptions; +end; + +{ ttaborderoverridepropertyeditor } + +function ttaborderoverridepropertyeditor.getdefaultstate: propertystatesty; +begin + if fmodule is twidget then begin + result:= inherited getdefaultstate + [ps_dialog]; + end; +end; + +procedure ttaborderoverridepropertyeditor.edit; +var + prop: ttaborderoverride1; + i1: int32; +begin + prop:= ttaborderoverride1(getpointervalue()); +// rcomp:= rootcomponent(prop.fowner); + with tmsetaborderoverrideeditorfo.create(prop.fowner) do begin + grid.beginupdate(); + grid.rowcount:= length(prop.fitems); + for i1:= 0 to grid.rowhigh do begin + with prop.fitems[i1] do begin + aed[i1]:= msestring(compnamepath(a)); + bed[i1]:= msestring(compnamepath(b)); + end; + end; + grid.endupdate(); + if show(ml_application) = mr_ok then begin + prop.clear(); + for i1:= 0 to grid.rowhigh do begin + prop.add(findcomp(aed[i1]),findcomp(bed[i1])); + end; + modified(); + end; + end; +end; + +{ toptionsdockeditor } + +function toptionsdockeditor.getinvisibleitems: tintegerset; +begin + result:= tintegerset(card32(deprecatedoptionsdock)); +end; + +initialization + register; +end. + + diff --git a/mseide-msegui/lib/common/regcomponents/regwidgets_bmp.pas b/mseide-msegui/lib/common/regcomponents/regwidgets_bmp.pas new file mode 100644 index 0000000..62de783 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regwidgets_bmp.pas @@ -0,0 +1,4366 @@ +unit regwidgets_bmp; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msebitmap; + +const + objdata_tsimplewidget: record size: integer; data: array[0..1388] of byte end = + (size: 1389; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,115,105, + 109,112,108,101,119,105,100,103,101,116,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,244,4,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,88,2,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,255,255,255,25,5,5,5,1,6, + 6,6,1,21,21,21,1,224,224,224,2,135,135,135,1,6,6,6,2,56, + 56,56,1,224,224,224,2,78,78,78,1,6,6,6,2,112,112,112,1,224, + 224,224,2,33,33,33,1,6,6,6,2,187,187,187,1,224,224,224,1,255, + 255,255,2,198,198,198,1,217,217,217,1,218,218,218,1,224,224,224,2,222, + 222,222,1,217,217,217,2,220,220,220,1,224,224,224,2,220,220,220,1,217, + 217,217,2,222,222,222,1,224,224,224,2,219,219,219,1,217,217,217,2,224, + 224,224,1,202,202,202,1,0,0,0,1,255,255,255,1,7,7,7,1,224, + 224,224,20,8,8,8,1,0,0,0,1,255,255,255,1,7,7,7,1,224, + 224,224,20,8,8,8,1,0,0,0,1,255,255,255,1,26,26,26,1,224, + 224,224,20,31,31,31,1,0,0,0,1,255,255,255,1,209,209,209,1,224, + 224,224,20,157,157,157,1,0,0,0,1,255,255,255,1,209,209,209,1,224, + 224,224,20,157,157,157,1,0,0,0,1,255,255,255,1,126,126,126,1,224, + 224,224,20,103,103,103,1,0,0,0,1,255,255,255,1,7,7,7,1,224, + 224,224,20,8,8,8,1,0,0,0,1,255,255,255,1,7,7,7,1,224, + 224,224,20,8,8,8,1,0,0,0,1,255,255,255,1,63,63,63,1,224, + 224,224,20,65,65,65,1,0,0,0,1,255,255,255,1,209,209,209,1,224, + 224,224,20,157,157,157,1,0,0,0,1,255,255,255,1,209,209,209,1,224, + 224,224,20,157,157,157,1,0,0,0,1,255,255,255,1,68,68,68,1,224, + 224,224,20,65,65,65,1,0,0,0,1,255,255,255,1,7,7,7,1,224, + 224,224,20,8,8,8,1,0,0,0,1,255,255,255,1,7,7,7,1,224, + 224,224,20,8,8,8,1,0,0,0,1,255,255,255,1,118,118,118,1,224, + 224,224,20,109,109,109,1,0,0,0,1,255,255,255,1,209,209,209,1,224, + 224,224,20,157,157,157,1,0,0,0,1,255,255,255,1,209,209,209,1,224, + 224,224,20,157,157,157,1,0,0,0,1,255,255,255,1,30,30,30,1,224, + 224,224,20,27,27,27,1,0,0,0,1,255,255,255,1,7,7,7,1,224, + 224,224,20,8,8,8,1,0,0,0,1,255,255,255,1,2,2,2,1,164, + 164,164,1,157,157,157,1,135,135,135,1,8,8,8,2,44,44,44,1,157, + 157,157,2,89,89,89,1,8,8,8,2,80,80,80,1,157,157,157,2,52, + 52,52,1,8,8,8,2,119,119,119,1,157,157,157,2,4,4,4,1,0, + 0,0,1,255,255,255,1,0,0,0,23,100,2,0,0,0,0,0,25,237, + 237,237,1,247,247,247,1,231,231,231,1,120,120,120,2,152,152,152,1,247, + 247,247,2,199,199,199,1,120,120,120,2,184,184,184,1,247,247,247,2,163, + 163,163,1,120,120,120,2,219,219,219,1,247,247,247,2,132,132,132,1,67, + 67,67,1,0,0,0,2,136,136,136,1,255,255,255,20,155,155,155,1,16, + 16,16,1,0,0,0,1,248,248,248,1,255,255,255,20,252,252,252,1,111, + 111,111,1,0,0,0,1,248,248,248,1,255,255,255,20,252,252,252,1,126, + 126,126,1,0,0,0,1,230,230,230,1,255,255,255,20,243,243,243,1,125, + 125,125,1,0,0,0,1,137,137,137,1,255,255,255,20,205,205,205,1,122, + 122,122,1,0,0,0,1,137,137,137,1,255,255,255,20,205,205,205,1,122, + 122,122,1,0,0,0,1,168,168,168,1,255,255,255,20,220,220,220,1,123, + 123,123,1,0,0,0,1,248,248,248,1,255,255,255,20,252,252,252,1,126, + 126,126,1,0,0,0,1,248,248,248,1,255,255,255,20,252,252,252,1,126, + 126,126,1,0,0,0,1,203,203,203,1,255,255,255,20,231,231,231,1,124, + 124,124,1,0,0,0,1,137,137,137,1,255,255,255,20,205,205,205,1,122, + 122,122,1,0,0,0,1,137,137,137,1,255,255,255,20,205,205,205,1,122, + 122,122,1,0,0,0,1,199,199,199,1,255,255,255,20,231,231,231,1,124, + 124,124,1,0,0,0,1,248,248,248,1,255,255,255,20,252,252,252,1,126, + 126,126,1,0,0,0,1,248,248,248,1,255,255,255,20,252,252,252,1,126, + 126,126,1,0,0,0,1,172,172,172,1,255,255,255,20,218,218,218,1,123, + 123,123,1,0,0,0,1,137,137,137,1,255,255,255,20,205,205,205,1,122, + 122,122,1,0,0,0,1,137,137,137,1,255,255,255,20,205,205,205,1,122, + 122,122,1,0,0,0,1,227,227,227,1,255,255,255,20,245,245,245,1,125, + 125,125,1,0,0,0,1,248,248,248,1,255,255,255,20,252,252,252,1,126, + 126,126,1,0,0,0,1,250,250,250,1,197,197,197,1,205,205,205,1,211, + 211,211,1,252,252,252,2,239,239,239,1,205,205,205,2,224,224,224,1,252, + 252,252,2,227,227,227,1,205,205,205,2,236,236,236,1,252,252,252,2,215, + 215,215,1,205,205,205,2,250,250,250,1,126,126,126,1,0,0,0,1,23, + 23,23,1,106,106,106,1,122,122,122,1,123,123,123,1,126,126,126,2,125, + 125,125,1,122,122,122,2,124,124,124,1,126,126,126,2,124,124,124,1,122, + 122,122,2,125,125,125,1,126,126,126,2,123,123,123,1,122,122,122,2,126, + 126,126,1,106,106,106,1,0,0) + ); + +const + objdata_tbutton: record size: integer; data: array[0..786] of byte end = + (size: 787; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,7,116,98,117, + 116,116,111,110,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114, + 101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112, + 46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100, + 13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109, + 97,112,46,105,109,97,103,101,10,160,2,0,0,0,0,0,0,6,0,0, + 0,24,0,0,0,24,0,0,0,88,2,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,255,255,255,120,224,224,224,25,255,255,255,22,0,0,0, + 1,224,224,224,1,255,255,255,1,235,235,235,20,128,128,128,1,0,0,0, + 1,224,224,224,1,255,255,255,1,232,232,232,16,179,179,179,1,232,232,232, + 3,128,128,128,1,0,0,0,1,224,224,224,1,255,255,255,1,229,229,229, + 1,208,208,208,1,69,69,69,1,8,8,8,1,34,34,34,1,182,182,182, + 1,229,229,229,10,0,0,0,1,229,229,229,3,128,128,128,1,0,0,0, + 1,224,224,224,1,255,255,255,1,226,226,226,1,73,73,73,1,105,105,105, + 1,217,217,217,1,147,147,147,1,47,47,47,1,226,226,226,1,96,96,96, + 1,12,12,12,1,6,6,6,1,78,78,78,1,0,0,0,1,89,89,89, + 1,15,15,15,1,154,154,154,1,0,0,0,3,226,226,226,2,128,128,128, + 1,0,0,0,1,224,224,224,1,255,255,255,1,223,223,223,1,10,10,10, + 1,211,211,211,1,223,223,223,6,192,192,192,1,1,1,1,1,0,0,0, + 1,153,153,153,1,157,157,157,1,32,32,32,1,223,223,223,1,0,0,0, + 1,223,223,223,3,128,128,128,1,0,0,0,1,224,224,224,1,255,255,255, + 1,221,221,221,1,12,12,12,1,209,209,209,1,221,221,221,1,218,218,218, + 1,182,182,182,1,221,221,221,1,153,153,153,1,66,66,66,1,27,27,27, + 1,0,0,0,2,216,216,216,1,215,215,215,1,4,4,4,1,221,221,221, + 1,0,0,0,1,221,221,221,3,128,128,128,1,0,0,0,1,224,224,224, + 1,255,255,255,1,218,218,218,1,71,71,71,1,106,106,106,1,209,209,209, + 1,124,124,124,1,49,49,49,1,218,218,218,1,11,11,11,1,150,150,150, + 1,135,135,135,1,0,0,0,2,156,156,156,1,154,154,154,1,35,35,35, + 1,218,218,218,1,0,0,0,1,206,206,206,1,218,218,218,2,128,128,128, + 1,0,0,0,1,224,224,224,1,255,255,255,1,215,215,215,1,191,191,191, + 1,53,53,53,1,6,6,6,1,36,36,36,1,180,180,180,1,215,215,215, + 1,79,79,79,1,7,7,7,1,94,94,94,1,0,0,0,2,67,67,67, + 1,19,19,19,1,155,155,155,1,215,215,215,1,47,47,47,1,6,6,6, + 1,215,215,215,2,128,128,128,1,0,0,0,1,224,224,224,1,255,255,255, + 1,212,212,212,11,0,0,0,1,212,212,212,8,128,128,128,1,0,0,0, + 1,224,224,224,1,255,255,255,1,209,209,209,11,0,0,0,1,209,209,209, + 8,128,128,128,1,0,0,0,1,224,224,224,1,128,128,128,22,0,0,0, + 25,255,255,255,120,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255, + 81,0,0,0,120,0,0) + ); + +const + objdata_tdrawgrid: record size: integer; data: array[0..1528] of byte end = + (size: 1529; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,100,114, + 97,119,103,114,105,100,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,132,5,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,64,5,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,128,128,128,25,208,208,208,2,128,128,128,1,208, + 208,208,2,112,112,112,1,153,153,153,1,171,171,171,1,165,165,165,1,118, + 118,118,1,184,184,184,1,208,208,208,2,128,128,128,1,208,208,208,2,154, + 154,154,1,148,148,148,1,190,190,190,1,186,186,186,1,148,148,148,1,208, + 208,208,1,255,255,255,1,128,128,128,1,208,208,208,2,128,128,128,1,208, + 208,208,1,179,179,179,1,142,142,142,1,116,116,116,1,148,148,148,1,141, + 141,141,1,121,121,121,1,128,128,128,1,208,208,208,2,128,128,128,1,208, + 208,208,2,144,144,144,2,131,131,131,1,146,146,146,1,165,165,165,1,208, + 208,208,1,255,255,255,1,128,128,128,1,208,208,208,2,128,128,128,1,208, + 208,208,4,175,175,175,1,176,176,176,1,208,208,208,4,128,128,128,1,208, + 208,208,2,186,186,186,1,183,183,183,1,187,187,187,1,191,191,191,1,197, + 197,197,1,208,208,208,1,255,255,255,1,128,128,128,23,255,255,255,1,128, + 128,128,1,208,208,208,2,128,128,128,1,255,255,255,1,169,169,169,1,183, + 183,183,1,151,215,220,1,96,235,248,1,72,239,254,1,77,241,255,1,173, + 249,255,1,255,255,255,2,128,128,128,1,255,255,255,2,243,243,243,1,169, + 169,169,1,204,204,204,1,179,179,179,1,139,139,139,1,255,255,255,2,128, + 128,128,1,208,208,208,2,128,128,128,1,255,255,255,1,151,151,151,1,125, + 187,193,1,109,240,255,1,140,241,255,1,133,241,255,1,94,240,255,1,39, + 238,255,1,140,218,224,1,255,255,255,1,128,128,128,1,255,255,255,3,191, + 191,191,1,150,150,150,1,202,202,202,1,158,158,158,1,251,251,251,1,255, + 255,255,1,128,128,128,1,208,208,208,2,128,128,128,1,255,255,255,1,237, + 237,237,1,114,239,251,1,153,242,255,1,208,244,255,1,192,243,255,1,131, + 241,255,1,65,239,255,1,32,216,230,1,207,207,207,1,128,128,128,1,255, + 255,255,9,128,128,128,6,92,234,248,1,154,242,255,1,208,244,255,1,194, + 243,255,1,132,241,255,1,66,239,255,1,15,227,243,1,70,70,70,1,128, + 128,128,2,113,113,143,1,128,128,128,6,255,255,255,1,128,128,128,1,208, + 208,208,2,128,128,128,1,255,255,255,1,206,206,206,1,91,219,230,1,112, + 241,255,1,143,242,255,1,136,241,255,1,96,240,255,1,41,238,255,1,35, + 196,208,1,121,121,121,1,128,128,128,1,235,235,255,1,33,33,255,1,220, + 220,240,1,255,255,255,1,176,176,176,2,129,129,129,1,255,255,255,2,128, + 128,128,1,208,208,208,2,128,128,128,1,255,255,255,1,181,181,181,1,204, + 237,239,1,55,226,241,1,73,239,255,1,68,239,255,1,40,238,255,1,19, + 225,241,1,73,106,108,1,155,155,155,1,128,128,128,1,114,114,255,1,4, + 4,255,1,60,60,201,1,244,244,244,1,186,186,186,1,211,211,211,1,159, + 159,159,1,255,255,255,2,128,128,128,1,208,208,208,2,128,128,128,1,255, + 255,255,1,199,199,199,1,210,210,210,1,179,197,198,1,68,174,182,1,50, + 188,198,1,62,168,176,1,92,110,111,1,99,99,99,1,229,229,229,1,113, + 113,144,1,10,10,255,1,4,4,255,1,7,7,252,1,155,155,186,1,255, + 255,255,5,128,128,128,8,122,122,122,1,95,95,95,1,85,85,85,1,95, + 95,95,1,122,122,122,1,128,128,128,1,49,49,209,1,4,4,255,3,24, + 24,184,1,119,119,119,1,128,128,128,3,255,255,255,1,128,128,128,1,208, + 208,208,2,128,128,128,1,255,255,255,1,197,197,197,1,253,5,36,1,254, + 6,37,1,255,7,38,4,255,255,255,1,209,209,255,1,5,5,254,1,4, + 4,255,3,5,5,254,1,91,91,137,1,158,158,158,1,157,157,157,1,255, + 255,255,2,128,128,128,1,208,208,208,2,128,128,128,1,255,255,255,1,176, + 176,176,1,255,0,32,6,119,119,119,1,76,76,255,1,4,4,255,5,26, + 26,205,1,145,145,145,1,158,158,158,1,255,255,255,2,128,128,128,1,208, + 208,208,2,128,128,128,1,255,255,255,1,235,235,235,1,255,0,32,6,115, + 115,115,1,248,248,255,1,76,76,84,1,111,111,119,4,112,112,119,1,155, + 155,155,1,255,255,255,3,128,128,128,6,255,0,32,6,58,58,58,1,128, + 128,128,1,126,126,126,7,128,128,128,2,255,255,255,1,128,128,128,1,208, + 208,208,2,128,128,128,1,255,255,255,1,174,174,174,1,255,0,32,6,115, + 115,115,1,255,255,255,1,128,128,128,1,255,255,255,2,228,228,228,1,163, + 163,163,1,191,191,191,1,184,184,184,1,139,139,139,1,255,255,255,2,128, + 128,128,1,208,208,208,2,128,128,128,1,255,255,255,1,158,158,158,1,255, + 0,32,6,115,115,115,1,255,255,255,1,128,128,128,1,255,255,255,2,212, + 212,212,1,152,152,152,1,204,204,204,1,178,178,178,1,158,158,158,1,251, + 251,251,1,255,255,255,1,128,128,128,1,208,208,208,2,128,128,128,1,255, + 255,255,1,237,237,237,1,255,247,248,1,113,105,106,1,97,89,90,1,81, + 73,74,1,113,105,106,1,86,78,79,1,115,115,115,1,255,255,255,1,128, + 128,128,1,255,255,255,9,128,128,128,7,126,126,126,6,128,128,128,10,255, + 255,255,1,128,128,128,1,208,208,208,2,128,128,128,1,255,255,255,1,199, + 199,199,2,226,226,226,1,228,228,228,1,233,233,233,1,255,255,255,4,128, + 128,128,1,255,255,255,4,172,172,172,1,197,197,197,1,137,137,137,1,255, + 255,255,2,128,128,128,1,208,208,208,2,128,128,128,1,255,255,255,1,183, + 183,183,1,176,176,176,1,183,183,183,1,173,173,173,1,130,130,130,1,255, + 255,255,4,128,128,128,1,255,255,255,4,208,208,208,1,215,215,215,1,168, + 168,168,1,254,254,254,1,255,255,255,25,12,0,0,0,255,255,255,255,255, + 255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tstringgrid: record size: integer; data: array[0..1730] of byte end = + (size: 1731; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,115,116, + 114,105,110,103,103,114,105,100,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,76,6,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,8,6,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,128,128,128,25,208,208,208,2,128,128,128, + 1,208,208,208,2,112,112,112,1,153,153,153,1,171,171,171,1,165,165,165, + 1,118,118,118,1,184,184,184,1,208,208,208,2,128,128,128,1,208,208,208, + 2,154,154,154,1,148,148,148,1,190,190,190,1,186,186,186,1,148,148,148, + 1,208,208,208,1,255,255,255,1,128,128,128,1,208,208,208,2,128,128,128, + 1,208,208,208,1,179,179,179,1,142,142,142,1,116,116,116,1,148,148,148, + 1,141,141,141,1,121,121,121,1,128,128,128,1,208,208,208,2,128,128,128, + 1,208,208,208,2,144,144,144,2,131,131,131,1,146,146,146,1,165,165,165, + 1,208,208,208,1,255,255,255,1,128,128,128,1,208,208,208,2,128,128,128, + 1,208,208,208,4,175,175,175,1,176,176,176,1,208,208,208,4,128,128,128, + 1,208,208,208,2,186,186,186,1,183,183,183,1,187,187,187,1,191,191,191, + 1,197,197,197,1,208,208,208,1,255,255,255,1,128,128,128,23,255,255,255, + 1,128,128,128,1,208,208,208,2,128,128,128,1,255,255,255,1,169,169,169, + 1,183,183,183,1,202,202,202,1,215,215,215,1,225,225,225,1,255,255,255, + 4,128,128,128,1,255,255,255,2,243,243,243,1,169,169,169,1,204,204,204, + 1,179,179,179,1,139,139,139,1,255,255,255,2,128,128,128,1,208,208,208, + 1,209,209,209,1,129,129,129,1,255,255,255,1,152,152,152,1,161,161,161, + 1,156,156,156,1,202,202,202,1,225,225,225,1,255,255,255,4,129,129,129, + 1,255,255,255,3,192,192,192,1,151,151,151,1,203,203,203,1,159,159,159, + 1,251,251,251,1,255,255,255,1,128,128,128,1,213,213,213,1,214,214,214, + 1,145,145,145,1,255,255,255,1,239,239,239,1,236,236,236,1,232,232,232, + 1,219,219,219,1,226,226,226,1,255,255,255,4,145,145,145,1,255,255,255, + 9,128,128,128,1,170,170,170,1,179,179,179,1,180,180,180,1,187,148,135, + 1,186,154,143,1,180,180,180,3,184,160,151,1,188,144,129,2,188,147,133, + 1,185,158,149,1,180,180,180,4,183,166,160,1,189,138,120,1,188,142,126, + 1,181,173,170,1,170,170,170,1,255,255,255,1,128,128,128,1,228,228,228, + 1,233,233,233,1,197,174,166,1,208,53,0,1,209,62,11,1,214,206,203, + 1,234,234,234,1,247,247,247,1,222,133,103,1,208,54,1,1,209,63,13, + 1,209,61,10,1,208,53,0,1,204,96,59,1,255,255,255,2,237,180,160, + 1,209,59,8,1,208,61,10,1,209,55,3,1,207,68,20,1,248,226,218, + 1,255,255,255,1,128,128,128,1,229,229,229,1,233,233,233,1,203,119,91, + 1,212,72,24,1,208,55,3,1,231,168,146,1,205,205,205,1,216,216,216, + 1,213,124,94,1,209,70,22,1,225,225,225,1,223,223,223,1,235,171,149, + 1,208,53,0,1,251,240,236,1,250,233,227,1,210,60,9,1,225,127,93, + 1,223,215,212,1,232,216,210,1,208,67,19,1,231,150,123,1,255,255,255, + 1,128,128,128,1,229,229,229,1,232,230,229,1,207,66,18,1,230,149,121, + 1,214,106,69,1,213,87,44,1,234,234,234,1,247,247,247,1,225,136,106, + 1,210,65,15,1,227,169,149,1,220,159,138,1,219,104,65,1,205,87,47, + 1,255,255,255,1,238,181,161,1,208,53,0,1,244,207,195,1,255,255,255, + 2,254,252,251,1,255,255,255,2,128,128,128,1,184,184,184,1,200,151,134, + 1,208,53,0,1,199,174,165,1,201,151,134,1,208,53,0,1,200,166,155, + 1,197,197,197,1,203,114,84,1,208,55,3,1,206,75,30,1,207,71,25, + 1,207,57,5,1,204,101,66,1,198,190,188,1,202,129,104,1,208,53,0, + 1,198,184,179,1,197,197,197,2,196,196,196,1,183,183,183,1,255,255,255, + 1,128,128,128,1,229,229,229,1,216,106,68,1,208,54,1,1,214,78,31, + 1,210,72,25,1,208,53,0,1,220,124,91,1,255,255,255,1,228,139,109, + 1,213,74,26,1,255,255,255,2,248,224,216,1,208,53,0,1,237,177,157, + 1,239,187,169,1,208,53,0,1,240,190,173,1,216,216,216,1,210,210,210, + 1,208,137,112,1,242,198,183,1,255,255,255,1,128,128,128,1,227,210,204, + 1,209,55,3,1,203,114,83,1,239,185,167,1,215,161,143,1,213,110,74, + 1,209,60,9,1,252,243,240,1,228,139,109,1,212,69,20,1,245,211,199, + 1,244,207,195,1,233,161,136,1,208,53,0,1,238,183,164,1,253,245,243, + 1,213,74,26,1,217,93,50,1,217,174,159,1,210,146,124,1,208,53,0, + 1,237,177,156,1,255,255,255,1,128,128,128,1,218,142,116,1,209,57,5, + 1,195,184,180,1,255,255,255,1,246,246,246,1,231,203,193,1,208,53,0, + 1,235,169,146,1,228,139,109,1,208,53,0,2,209,57,5,1,211,67,18, + 1,203,111,80,1,254,253,252,1,255,255,255,1,246,216,206,1,217,90,47, + 1,208,53,0,1,212,70,21,1,228,137,106,1,255,254,254,1,255,255,255, + 1,128,128,128,1,170,170,170,1,179,179,179,1,180,180,180,18,179,179,179, + 1,170,170,170,1,255,255,255,1,128,128,128,1,213,213,213,1,214,214,214, + 1,145,145,145,1,255,255,255,1,185,185,185,1,187,187,187,1,208,208,208, + 1,235,235,235,1,226,226,226,1,192,192,192,1,218,218,218,1,255,255,255, + 2,145,145,145,1,255,255,255,2,232,232,232,1,175,175,175,1,200,200,200, + 1,193,193,193,1,154,154,154,1,255,255,255,2,128,128,128,1,208,208,208, + 1,209,209,209,1,129,129,129,1,255,255,255,1,159,159,159,1,208,208,208, + 1,122,122,122,1,177,177,177,1,176,176,176,1,184,184,184,1,143,143,143, + 1,255,255,255,2,129,129,129,1,255,255,255,2,213,213,213,1,153,153,153, + 1,205,205,205,1,179,179,179,1,159,159,159,1,251,251,251,1,255,255,255, + 1,128,128,128,1,208,208,208,2,128,128,128,1,255,255,255,1,237,237,237, + 1,255,255,255,1,239,239,239,1,203,203,203,1,166,166,166,1,239,239,239, + 1,180,180,180,1,255,255,255,2,128,128,128,1,255,255,255,9,128,128,128, + 23,255,255,255,1,128,128,128,1,208,208,208,2,128,128,128,1,255,255,255, + 1,199,199,199,2,226,226,226,1,228,228,228,1,233,233,233,1,255,255,255, + 4,128,128,128,1,255,255,255,4,172,172,172,1,197,197,197,1,137,137,137, + 1,255,255,255,2,128,128,128,1,208,208,208,2,128,128,128,1,255,255,255, + 1,183,183,183,1,176,176,176,1,183,183,183,1,173,173,173,1,130,130,130, + 1,255,255,255,4,128,128,128,1,255,255,255,4,208,208,208,1,215,215,215, + 1,168,168,168,1,254,254,254,1,255,255,255,25,12,0,0,0,255,255,255, + 255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tmainmenuwidget: record size: integer; data: array[0..1474] of byte end = + (size: 1475; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,109,97, + 105,110,109,101,110,117,119,105,100,103,101,116,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,72,5,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,192,3,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,208,208,208,30,209,209,209, + 1,255,255,255,7,209,209,209,1,208,208,208,10,175,175,175,1,156,156,156, + 1,190,190,190,1,180,180,180,1,208,208,208,1,209,209,209,1,254,254,254, + 1,208,208,208,1,206,206,206,2,208,208,208,2,206,206,206,1,130,130,130, + 1,208,208,208,1,175,175,175,1,178,178,178,1,194,194,194,1,208,208,208, + 6,148,148,148,1,161,161,161,1,157,157,157,1,117,117,117,1,125,125,125, + 1,209,209,209,1,254,254,254,1,205,205,205,1,110,110,110,1,170,170,170, + 1,143,143,143,1,152,152,152,1,207,207,207,1,129,129,129,1,208,208,208, + 1,153,153,153,2,118,118,118,1,126,126,126,1,124,124,124,1,114,114,114, + 1,208,208,208,3,179,179,179,1,208,208,208,1,182,182,182,1,162,162,162, + 1,167,167,167,1,209,209,209,1,254,254,254,1,158,158,158,1,144,144,144, + 1,131,131,131,1,147,147,147,2,207,207,207,1,128,128,128,1,208,208,208, + 1,178,178,178,1,195,195,195,1,162,162,162,1,168,168,168,1,170,170,170, + 1,168,168,168,1,208,208,208,3,153,153,153,1,107,107,107,1,208,208,208, + 4,255,255,255,1,208,208,208,3,207,207,207,2,208,208,208,1,128,128,128, + 1,208,208,208,1,130,130,130,2,208,208,208,13,211,211,211,1,128,128,128, + 7,208,208,208,9,128,128,128,7,255,255,255,12,192,192,192,1,128,128,128, + 4,208,208,208,7,255,255,255,1,208,208,208,9,197,197,197,1,208,208,208, + 1,128,128,128,1,0,0,0,2,208,208,208,9,255,255,255,1,190,190,190, + 1,116,116,116,1,148,148,148,1,200,200,200,1,162,162,162,1,194,194,194, + 1,181,181,181,1,208,208,208,2,103,103,103,1,165,165,165,1,128,128,128, + 1,0,0,0,2,208,208,208,9,255,255,255,1,198,198,198,1,135,135,135, + 1,165,165,165,1,173,173,173,1,115,115,115,1,148,148,148,1,142,142,142, + 1,208,208,208,2,103,103,103,1,165,165,165,1,128,128,128,1,0,0,0, + 2,208,208,208,9,255,255,255,1,166,166,166,1,148,148,148,1,168,168,168, + 1,150,150,150,1,158,158,158,1,177,177,177,1,157,157,157,1,208,208,208, + 2,197,197,197,1,208,208,208,1,128,128,128,1,0,0,0,2,208,208,208, + 9,255,255,255,11,212,212,212,1,128,128,128,1,0,0,0,2,208,208,208, + 9,255,255,255,2,200,200,200,1,153,153,153,1,192,192,192,1,224,224,224, + 2,209,209,209,1,215,215,215,1,224,224,224,2,128,128,128,2,0,0,0, + 2,208,208,208,9,255,255,255,2,169,169,169,1,147,147,147,1,152,152,152, + 1,136,136,136,1,151,151,151,1,153,153,153,1,168,168,168,1,153,153,153, + 1,223,223,223,1,128,128,128,2,0,0,0,2,208,208,208,9,255,255,255, + 2,169,169,169,1,203,203,203,1,220,220,220,1,156,156,156,1,104,104,104, + 1,157,157,157,1,148,148,148,1,134,134,134,1,218,218,218,1,128,128,128, + 2,0,0,0,2,208,208,208,9,255,255,255,2,224,224,224,9,128,128,128, + 2,0,0,0,2,208,208,208,9,255,255,255,1,218,218,218,1,128,128,128, + 11,0,0,0,2,208,208,208,9,255,255,255,1,191,191,191,1,170,170,170, + 1,208,208,208,1,183,183,183,1,208,208,208,1,207,207,207,1,181,181,181, + 1,208,208,208,4,128,128,128,1,0,0,0,2,208,208,208,9,255,255,255, + 1,169,169,169,1,125,125,125,1,149,149,149,2,153,153,153,1,148,148,148, + 1,108,108,108,1,159,159,159,1,138,138,138,1,170,170,170,1,208,208,208, + 1,128,128,128,1,0,0,0,2,208,208,208,9,255,255,255,1,169,169,169, + 1,123,123,123,1,131,131,131,1,148,148,148,1,102,102,102,1,121,121,121, + 1,108,108,108,1,139,139,139,1,103,103,103,1,144,144,144,1,208,208,208, + 1,128,128,128,1,0,0,0,2,208,208,208,9,255,255,255,1,208,208,208, + 4,207,207,207,1,208,208,208,3,207,207,207,1,208,208,208,2,128,128,128, + 1,0,0,0,2,208,208,208,9,252,252,252,1,128,128,128,12,0,0,0, + 2,208,208,208,9,0,0,0,15,208,208,208,2,80,1,0,0,0,0,0, + 25,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255, + 22,0,0,0,2,255,255,255,22,0,0,0,2,255,255,255,22,0,0,0, + 2,255,255,255,22,0,0,0,1,176,176,176,1,255,255,255,22,128,128,128, + 1,0,0,0,7,255,255,255,13,135,135,135,1,3,3,3,1,0,0,0, + 9,255,255,255,13,137,137,137,1,3,3,3,1,0,0,0,9,255,255,255, + 13,137,137,137,1,3,3,3,1,0,0,0,9,255,255,255,13,137,137,137, + 1,3,3,3,1,0,0,0,9,255,255,255,13,137,137,137,1,3,3,3, + 1,0,0,0,9,255,255,255,13,137,137,137,1,3,3,3,1,0,0,0, + 9,255,255,255,13,137,137,137,1,3,3,3,1,0,0,0,9,255,255,255, + 13,137,137,137,1,3,3,3,1,0,0,0,9,255,255,255,13,137,137,137, + 1,3,3,3,1,0,0,0,9,255,255,255,13,137,137,137,1,3,3,3, + 1,0,0,0,9,255,255,255,13,137,137,137,1,3,3,3,1,0,0,0, + 9,255,255,255,13,137,137,137,1,3,3,3,1,0,0,0,9,255,255,255, + 13,137,137,137,1,3,3,3,1,0,0,0,9,255,255,255,13,137,137,137, + 1,3,3,3,1,0,0,0,9,129,129,129,1,255,255,255,12,137,137,137, + 1,3,3,3,1,0,0,0,9,3,3,3,1,135,135,135,1,137,137,137, + 11,135,135,135,1,3,3,3,1,0,0,0,2,0,0) + ); + +const + objdata_taction: record size: integer; data: array[0..1598] of byte end = + (size: 1599; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,7,116,97,99, + 116,105,111,110,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114, + 101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112, + 46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100, + 13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109, + 97,112,46,105,109,97,103,101,10,204,5,0,0,0,0,0,0,6,0,0, + 0,24,0,0,0,24,0,0,0,140,2,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,208,208,208,39,0,0,255,2,208,208,208,21,0,0,255, + 1,7,7,255,1,6,6,252,1,0,0,0,1,208,208,208,19,0,0,255, + 1,34,34,255,1,136,136,255,1,66,66,239,1,0,0,143,1,0,0,0, + 1,208,208,208,16,0,0,255,1,2,2,255,1,75,75,254,1,175,175,255, + 1,76,76,239,1,4,4,211,1,0,0,62,1,0,0,0,1,208,208,208, + 15,0,0,255,1,14,14,255,1,118,118,255,1,141,141,252,1,25,25,230, + 1,0,0,143,1,0,0,0,3,208,208,208,14,0,0,255,1,42,42,255, + 1,160,160,255,1,77,77,243,1,3,3,207,1,0,0,37,1,0,0,0, + 3,208,208,208,13,0,0,255,1,4,4,255,1,86,86,254,1,141,141,253, + 1,24,24,234,1,0,0,131,1,0,0,0,4,208,208,208,13,0,0,255, + 1,17,17,255,1,132,132,255,1,78,78,248,1,3,3,205,1,0,0,26, + 1,0,0,0,3,208,208,208,14,0,0,255,1,46,46,255,1,129,129,254, + 1,24,24,240,1,0,0,117,1,0,0,0,3,208,208,208,15,0,0,255, + 1,28,28,255,1,97,97,254,1,5,5,242,1,0,0,33,1,0,0,0, + 3,208,208,208,17,0,0,234,1,3,3,229,1,0,0,239,1,0,0,244, + 1,0,0,238,1,0,0,0,1,208,208,208,19,0,0,0,1,0,0,179, + 1,0,0,232,1,0,0,246,1,0,0,250,1,0,0,235,1,208,208,208, + 19,0,0,0,1,0,0,43,1,0,0,204,1,0,0,239,1,0,0,248, + 1,0,0,249,1,0,0,128,1,208,208,208,18,0,0,0,2,0,0,123, + 1,0,0,218,1,0,0,244,1,0,0,250,1,0,0,242,1,208,208,208, + 18,0,0,255,1,0,0,230,1,0,0,0,1,0,0,163,1,0,0,230, + 1,0,0,248,1,0,0,250,1,0,0,0,1,208,208,208,16,12,12,255, + 1,17,17,252,1,208,208,208,1,0,0,183,1,0,0,249,1,0,0,240, + 1,0,0,97,1,0,0,0,2,208,208,208,14,0,0,255,1,72,72,255, + 1,55,55,218,1,0,0,242,1,0,0,255,1,0,0,251,1,0,0,0, + 3,208,208,208,15,52,52,255,1,140,140,255,1,48,48,224,1,0,0,247, + 1,0,0,222,1,0,0,0,3,208,208,208,15,27,27,255,1,130,130,255, + 1,169,169,255,1,92,92,250,1,32,32,245,1,0,0,248,1,0,0,251, + 1,0,0,241,1,208,208,208,16,97,97,255,1,171,171,255,1,108,108,255, + 1,41,41,250,1,0,0,234,1,0,0,223,1,0,0,214,1,0,0,170, + 1,0,0,0,1,208,208,208,14,27,27,255,1,127,127,254,1,65,65,223, + 1,14,14,168,1,0,0,61,1,0,0,0,5,208,208,208,14,0,0,192, + 1,0,0,0,8,208,208,208,16,0,0,0,4,208,208,208,13,8,3,0, + 0,0,0,0,39,15,15,15,1,17,17,17,1,0,0,0,21,47,47,47, + 1,182,182,182,1,135,135,135,1,1,1,1,1,0,0,0,19,96,96,96, + 1,193,193,193,1,253,253,253,1,200,200,200,1,36,36,36,1,1,1,1, + 1,0,0,0,16,7,7,7,1,146,146,146,1,209,209,209,1,255,255,255, + 1,213,213,213,1,181,181,181,1,62,62,62,1,3,3,3,1,0,0,0, + 15,32,32,32,1,176,176,176,1,230,230,230,1,235,235,235,1,203,203,203, + 1,127,127,127,1,65,65,65,1,25,25,25,1,2,2,2,1,0,0,0, + 14,74,74,74,1,188,188,188,1,248,248,248,1,209,209,209,1,175,175,175, + 1,83,83,83,1,45,45,45,1,10,10,10,1,2,2,2,1,0,0,0, + 13,2,2,2,1,127,127,127,1,201,201,201,1,230,230,230,1,199,199,199, + 1,117,117,117,1,63,63,63,1,23,23,23,1,3,3,3,1,1,1,1, + 1,0,0,0,13,20,20,20,1,166,166,166,1,220,220,220,1,203,203,203, + 1,164,164,164,1,78,78,78,1,43,43,43,1,8,8,8,1,1,1,1, + 1,0,0,0,14,55,55,55,1,184,184,184,1,217,217,217,1,190,190,190, + 1,106,106,106,1,60,60,60,1,20,20,20,1,3,3,3,1,0,0,0, + 15,33,33,33,1,206,206,206,1,227,227,227,1,214,214,214,1,77,77,77, + 1,39,39,39,1,7,7,7,1,1,1,1,1,0,0,0,17,33,33,33, + 1,177,177,177,1,220,220,220,1,198,198,198,1,68,68,68,1,1,1,1, + 1,0,0,0,19,5,5,5,1,87,87,87,1,198,198,198,1,214,214,214, + 1,157,157,157,1,23,23,23,1,0,0,0,19,2,2,2,1,12,12,12, + 1,126,126,126,1,209,209,209,1,205,205,205,1,103,103,103,1,2,2,2, + 1,0,0,0,18,1,1,1,1,3,3,3,1,31,31,31,1,160,160,160, + 1,215,215,215,1,183,183,183,1,48,48,48,1,0,0,0,18,14,14,14, + 1,10,10,10,1,4,4,4,1,59,59,59,1,187,187,187,1,216,216,216, + 1,127,127,127,1,1,1,1,1,0,0,0,16,124,124,124,1,60,60,60, + 1,0,0,0,1,7,7,7,1,144,144,144,1,188,188,188,1,71,71,71, + 1,11,11,11,1,1,1,1,1,0,0,0,14,31,31,31,1,223,223,223, + 1,112,112,112,1,35,35,35,1,180,180,180,1,89,89,89,1,18,18,18, + 1,24,24,24,1,3,3,3,1,0,0,0,15,148,148,148,1,255,255,255, + 1,189,189,189,1,153,153,153,1,22,22,22,1,14,14,14,1,7,7,7, + 1,2,2,2,1,0,0,0,15,56,56,56,1,240,240,240,1,255,255,255, + 1,244,244,244,1,191,191,191,1,140,140,140,1,87,87,87,1,17,17,17, + 1,0,0,0,16,173,173,173,1,255,255,255,2,244,244,244,1,209,209,209, + 1,160,160,160,1,105,105,105,1,23,23,23,1,1,1,1,1,0,0,0, + 14,84,84,84,1,193,193,193,1,165,165,165,1,143,143,143,1,92,92,92, + 1,70,70,70,1,51,51,51,1,31,31,31,1,13,13,13,1,1,1,1, + 1,0,0,0,14,4,4,4,1,10,10,10,1,49,49,49,1,34,34,34, + 1,16,16,16,1,3,3,3,1,2,2,2,1,1,1,1,2,0,0,0, + 16,1,1,1,1,2,2,2,1,1,1,1,2,0,0,0,13,0,0) + ); + +const + objdata_tlabel: record size: integer; data: array[0..837] of byte end = + (size: 838; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,6,116,108,97, + 98,101,108,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114,101, + 110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112,46, + 111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,13, + 98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109,97, + 112,46,105,109,97,103,101,10,212,2,0,0,0,0,0,0,6,0,0,0, + 24,0,0,0,24,0,0,0,196,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,208,208,208,82,0,0,0,3,208,208,208,21,0,0,0,4, + 208,208,208,20,0,0,0,4,208,208,208,19,0,0,0,6,208,208,208,18, + 0,0,0,6,208,208,208,17,0,0,0,3,208,208,208,1,0,0,0,3, + 208,208,208,17,0,0,0,3,208,208,208,2,0,0,0,3,208,208,208,16, + 0,0,0,3,208,208,208,2,0,0,0,3,208,208,208,15,0,0,0,3, + 208,208,208,3,0,0,0,4,208,208,208,14,0,0,0,10,208,208,208,13, + 0,0,0,11,208,208,208,13,0,0,0,12,208,208,208,12,0,0,0,3, + 208,208,208,6,0,0,0,3,208,208,208,11,0,0,0,4,208,208,208,6, + 0,0,0,4,208,208,208,10,0,0,0,3,208,208,208,8,0,0,0,3, + 208,208,208,10,0,0,0,3,208,208,208,8,0,0,0,3,208,208,208,125, + 216,1,0,0,0,0,0,82,1,1,1,1,8,8,8,1,6,6,6,1, + 0,0,0,21,110,110,110,1,255,255,255,1,248,248,248,1,20,20,20,1, + 0,0,0,20,209,209,209,1,233,233,233,1,255,255,255,1,118,118,118,1, + 0,0,0,19,51,51,51,1,255,255,255,1,121,121,121,1,223,223,223,1, + 221,221,221,1,1,1,1,1,0,0,0,18,150,150,150,1,255,255,255,1, + 45,45,45,1,137,137,137,1,255,255,255,1,73,73,73,1,0,0,0,17, + 8,8,8,1,239,239,239,1,220,220,220,1,0,0,0,1,49,49,49,1, + 255,255,255,1,178,178,178,1,0,0,0,17,91,91,91,1,255,255,255,1, + 126,126,126,1,0,0,0,2,210,210,210,1,252,252,252,1,30,30,30,1, + 0,0,0,16,189,189,189,1,254,254,254,1,32,32,32,1,0,0,0,2, + 115,115,115,1,255,255,255,1,132,132,132,1,0,0,0,15,33,33,33,1, + 254,254,254,1,192,192,192,1,0,0,0,3,24,24,24,1,252,252,252,1, + 232,232,232,1,5,5,5,1,0,0,0,14,130,130,130,1,255,255,255,1, + 183,183,183,1,120,120,120,4,228,228,228,1,255,255,255,1,86,86,86,1, + 0,0,0,13,2,2,2,1,226,226,226,1,255,255,255,8,191,191,191,1, + 0,0,0,13,72,72,72,1,255,255,255,1,178,178,178,1,24,24,24,5, + 27,27,27,1,236,236,236,1,255,255,255,1,41,41,41,1,0,0,0,12, + 170,170,170,1,255,255,255,1,80,80,80,1,0,0,0,6,144,144,144,1, + 255,255,255,1,146,146,146,1,0,0,0,11,19,19,19,1,249,249,249,1, + 236,236,236,1,6,6,6,1,0,0,0,6,46,46,46,1,255,255,255,1, + 240,240,240,1,10,10,10,1,0,0,0,10,111,111,111,1,255,255,255,1, + 148,148,148,1,0,0,0,8,204,204,204,1,255,255,255,1,100,100,100,1, + 0,0,0,10,92,92,92,1,128,128,128,1,38,38,38,1,0,0,0,8, + 65,65,65,1,128,128,128,1,89,89,89,1,0,0,0,125,0,0) + ); + +const + objdata_timage: record size: integer; data: array[0..1525] of byte end = + (size: 1526; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,6,116,105,109, + 97,103,101,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114,101, + 110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112,46, + 111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,13, + 98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109,97, + 112,46,105,109,97,103,101,10,132,5,0,0,0,0,0,0,6,0,0,0, + 24,0,0,0,24,0,0,0,188,4,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,128,128,128,25,255,191,141,22,255,255,255,1,128,128,128,1, + 255,191,141,22,255,255,255,1,128,128,128,1,255,194,147,13,255,194,146,9, + 255,255,255,1,128,128,128,1,255,197,153,3,238,200,160,1,123,218,205,1, + 21,235,247,1,54,230,234,1,167,211,187,1,255,197,153,10,255,197,152,4, + 255,255,255,1,128,128,128,1,255,201,159,3,123,220,208,1,32,239,250,1, + 123,249,254,1,98,247,254,1,3,237,252,1,218,206,173,1,255,201,159,13, + 255,255,255,1,128,128,128,1,255,204,165,3,21,236,247,1,123,249,254,1, + 183,255,255,2,56,241,252,1,118,221,212,1,255,204,165,13,255,255,255,1, + 128,128,128,1,255,208,171,3,54,232,237,1,98,247,254,1,183,255,255,2, + 32,238,250,1,153,220,204,1,255,208,171,13,255,255,255,1,128,128,128,1, + 255,211,177,3,167,220,203,1,3,237,252,1,56,241,252,1,32,238,250,1, + 18,235,248,1,244,212,180,1,255,211,177,13,255,255,255,1,128,128,128,1, + 255,215,183,4,218,218,193,1,118,226,221,1,153,224,211,1,244,216,186,1, + 255,215,183,8,255,214,183,5,248,211,178,1,255,255,255,1,128,128,128,1, + 255,218,189,19,197,199,145,1,91,174,66,1,12,151,6,1,255,255,255,1, + 128,128,128,1,255,222,195,6,255,221,195,11,188,200,144,1,77,177,57,1, + 6,180,3,1,4,181,0,1,4,164,0,1,255,255,255,1,128,128,128,1, + 255,225,201,15,201,208,159,1,79,184,62,1,7,192,4,1,2,194,0,1, + 3,186,0,1,4,178,0,1,5,162,0,1,255,255,255,1,128,128,128,1, + 255,228,208,5,255,228,207,8,248,225,201,1,96,189,77,1,11,200,8,1, + 1,207,1,1,2,199,0,1,3,191,0,1,3,183,0,1,4,174,0,1, + 5,162,0,1,255,255,255,1,128,128,128,1,255,232,214,9,255,232,213,3, + 251,230,210,1,63,184,52,1,0,218,1,1,1,212,1,1,2,204,1,1, + 2,196,0,1,3,187,0,1,4,179,0,1,4,171,0,1,5,162,0,1, + 255,255,255,1,128,128,128,1,253,101,47,1,254,125,59,1,254,131,70,1, + 254,137,82,1,254,143,93,1,254,150,104,1,254,156,116,1,253,159,121,1, + 250,148,104,1,248,137,85,1,245,126,67,1,243,116,49,1,235,101,30,1, + 29,162,3,1,1,216,1,1,1,208,1,1,2,200,1,1,3,192,0,1, + 3,184,0,1,4,176,0,1,5,171,0,1,5,162,0,1,255,255,255,1, + 128,128,128,1,254,120,50,1,255,146,61,1,255,154,74,1,255,161,88,1, + 255,169,101,1,255,176,115,1,255,184,129,1,255,191,142,1,252,179,122,1, + 249,166,100,1,246,153,79,1,243,140,57,1,240,126,36,1,176,109,12,1, + 6,192,1,1,2,205,1,1,2,197,0,1,3,189,0,1,4,181,0,1, + 4,173,0,1,5,171,0,1,5,162,0,1,255,255,255,1,128,128,128,1, + 254,120,50,1,255,144,58,1,255,152,71,1,255,160,85,1,255,167,98,1, + 255,175,112,1,255,182,126,1,255,190,139,1,252,182,126,1,249,169,105,1, + 246,155,83,1,243,142,62,1,240,129,40,1,237,116,19,1,94,125,3,1, + 2,201,1,1,2,194,0,1,3,186,0,1,4,178,0,1,5,171,0,2, + 5,162,0,1,255,255,255,1,128,128,128,1,254,120,50,1,255,143,55,1, + 255,150,68,1,255,158,82,1,255,165,95,1,255,173,109,1,255,180,123,1, + 255,188,136,1,253,185,131,1,250,171,110,1,247,158,88,1,244,145,67,1, + 241,132,45,1,238,119,24,1,228,106,2,1,41,150,2,1,3,191,0,1, + 3,183,0,1,4,175,0,1,5,171,0,2,5,162,0,1,255,255,255,1, + 128,128,128,1,254,120,50,1,255,142,53,1,255,149,65,1,255,156,79,1, + 255,164,92,1,255,171,106,1,255,179,120,1,255,186,133,1,254,187,136,1, + 251,174,114,1,248,161,93,1,245,148,71,1,242,135,50,1,239,122,28,1, + 236,109,7,1,189,111,0,1,28,157,2,1,4,180,0,1,4,171,0,1, + 5,171,0,2,5,162,0,1,255,255,255,1,128,128,128,1,254,120,50,1, + 255,142,53,1,255,147,62,1,255,155,76,1,255,162,89,1,255,170,103,1, + 255,177,117,1,255,185,130,1,254,190,141,1,251,177,119,1,248,164,98,1, + 245,151,76,1,242,138,55,1,239,125,33,1,236,112,12,1,235,105,0,1, + 183,111,1,1,23,151,2,1,5,171,0,3,5,162,0,1,255,255,255,1, + 128,128,128,1,254,120,50,1,255,142,53,1,255,145,59,1,255,153,73,1, + 255,160,86,1,255,168,100,1,255,175,114,1,255,183,127,1,255,191,141,1, + 252,180,124,1,249,167,102,1,246,154,81,1,243,141,59,1,240,128,38,1, + 237,115,16,1,235,105,0,2,178,107,2,1,19,151,1,1,5,171,0,2, + 5,162,0,1,255,255,255,1,128,128,128,1,253,101,47,1,254,120,50,1, + 254,121,52,1,254,127,64,1,254,134,75,1,254,140,87,1,254,147,98,1, + 254,153,109,1,254,159,121,1,252,154,114,1,250,143,95,1,247,132,77,1, + 244,121,59,1,242,110,41,1,239,99,23,1,237,89,5,3,173,89,7,1, + 13,151,1,1,5,162,0,1,4,155,0,1,255,255,255,25,144,0,0,0, + 255,255,255,255,255,255,255,6,237,237,237,1,235,235,235,1,255,255,255,20, + 247,247,247,1,249,249,249,1,255,255,255,20,252,252,252,1,251,251,251,1, + 255,255,255,20,254,254,254,1,249,249,249,1,255,255,255,21,233,233,233,1, + 255,255,255,22,251,251,251,1,226,226,226,1,255,255,255,23,244,244,244,1, + 245,245,245,1,255,255,255,23,242,242,242,1,255,255,255,24,245,245,245,1, + 255,255,255,24,245,245,245,1,255,255,255,24,242,242,242,1,255,255,255,23, + 252,252,252,1,239,239,239,1,255,255,255,23,246,246,246,1,239,239,239,1, + 255,255,255,27,0,0) + ); + +const + objdata_tdispwidget: record size: integer; data: array[0..295] of byte end = + (size: 296; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,100,105, + 115,112,119,105,100,103,101,116,12,98,105,116,109,97,112,46,105,109,97,103, + 101,10,248,0,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0, + 0,0,196,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0, + 255,146,128,128,128,20,255,0,255,4,128,128,128,1,192,192,192,18,255,255, + 255,1,255,0,255,4,128,128,128,1,192,192,192,18,255,255,255,1,255,0, + 255,4,128,128,128,1,192,192,192,18,255,255,255,1,255,0,255,4,128,128, + 128,1,192,192,192,18,255,255,255,1,255,0,255,4,128,128,128,1,192,192, + 192,18,255,255,255,1,255,0,255,4,128,128,128,1,192,192,192,18,255,255, + 255,1,255,0,255,4,128,128,128,1,192,192,192,18,255,255,255,1,255,0, + 255,4,128,128,128,1,192,192,192,18,255,255,255,1,255,0,255,4,128,128, + 128,1,192,192,192,18,255,255,255,1,255,0,255,4,128,128,128,1,192,192, + 192,18,255,255,255,1,255,0,255,4,128,128,128,1,192,192,192,18,255,255, + 255,1,255,0,255,4,255,255,255,20,255,0,255,122,0,0) + ); + +const + objdata_tintegerdisp: record size: integer; data: array[0..839] of byte end = + (size: 840; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,105,110, + 116,101,103,101,114,100,105,115,112,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,208,2,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,136,2,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,208,208,208,120,128,128,128,25,209,209, + 209,22,255,255,255,1,128,128,128,1,211,211,211,4,199,199,199,1,205,205, + 205,1,211,211,211,4,202,202,202,1,211,211,211,5,200,200,200,1,211,211, + 211,5,255,255,255,1,128,128,128,1,214,214,214,3,199,199,199,1,29,29, + 29,1,167,167,167,1,214,214,214,2,153,153,153,1,46,46,46,1,41,41, + 41,1,55,55,55,1,173,173,173,1,214,214,214,1,192,192,192,1,55,55, + 55,1,47,47,47,1,34,34,34,1,168,168,168,1,214,214,214,3,255,255, + 255,1,128,128,128,1,217,217,217,2,159,159,159,1,31,31,31,1,11,11, + 11,1,169,169,169,1,217,217,217,1,215,215,215,1,32,32,32,1,181,181, + 181,1,217,217,217,1,142,142,142,1,65,65,65,1,217,217,217,1,85,85, + 85,1,123,123,123,1,217,217,217,1,155,155,155,1,44,44,44,1,217,217, + 217,3,255,255,255,1,128,128,128,1,219,219,219,2,100,100,100,1,171,171, + 171,1,47,47,47,1,171,171,171,1,219,219,219,1,213,213,213,1,165,165, + 165,1,219,219,219,2,171,171,171,1,26,26,26,1,219,219,219,1,210,210, + 210,1,214,214,214,1,219,219,219,1,141,141,141,1,46,46,46,1,219,219, + 219,3,255,255,255,1,128,128,128,1,222,222,222,4,48,48,48,1,173,173, + 173,1,222,222,222,4,216,216,216,1,60,60,60,1,117,117,117,1,222,222, + 222,3,60,60,60,1,8,8,8,1,178,178,178,1,222,222,222,3,255,255, + 255,1,128,128,128,1,224,224,224,4,48,48,48,1,175,175,175,1,224,224, + 224,3,214,214,214,1,59,59,59,1,85,85,85,1,222,222,222,1,224,224, + 224,3,197,197,197,1,136,136,136,1,24,24,24,1,215,215,215,1,224,224, + 224,2,255,255,255,1,128,128,128,1,227,227,227,4,49,49,49,1,177,177, + 177,1,227,227,227,2,214,214,214,1,52,52,52,1,102,102,102,1,226,226, + 226,1,227,227,227,2,188,188,188,1,222,222,222,1,227,227,227,2,41,41, + 41,1,169,169,169,1,227,227,227,2,255,255,255,1,128,128,128,1,229,229, + 229,4,49,49,49,1,179,179,179,1,229,229,229,2,57,57,57,1,124,124, + 124,1,229,229,229,4,80,80,80,1,138,138,138,1,229,229,229,1,202,202, + 202,1,22,22,22,1,221,221,221,1,229,229,229,2,255,255,255,1,128,128, + 128,1,232,232,232,4,50,50,50,1,181,181,181,1,232,232,232,1,172,172, + 172,1,0,0,0,1,6,6,6,3,14,14,14,1,232,232,232,1,199,199, + 199,1,61,61,61,1,51,51,51,2,156,156,156,1,232,232,232,3,255,255, + 255,1,128,128,128,1,235,235,235,16,220,220,220,1,235,235,235,5,255,255, + 255,1,128,128,128,1,237,237,237,22,255,255,255,25,208,208,208,120,16,0, + 0,0,0,0,0,120,255,255,255,255,255,255,255,81,0,0,0,120,0,0) + ); + +const + objdata_tint64disp: record size: integer; data: array[0..733] of byte end = + (size: 734; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,105,110, + 116,54,52,100,105,115,112,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,104,2,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,32,2,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,208,208,208,120,128,128,128,25,209,209,209,22, + 255,255,255,1,128,128,128,1,212,212,212,7,200,200,200,1,212,212,212,6, + 199,199,199,1,210,210,210,1,212,212,212,6,255,255,255,1,128,128,128,1, + 214,214,214,5,172,172,172,1,38,38,38,1,45,45,45,2,184,184,184,1, + 214,214,214,3,187,187,187,1,12,12,12,1,180,180,180,1,214,214,214,6, + 255,255,255,1,128,128,128,1,217,217,217,5,43,43,43,1,160,160,160,1, + 217,217,217,1,135,135,135,1,91,91,91,1,217,217,217,2,215,215,215,1, + 57,57,57,1,13,13,13,1,183,183,183,1,217,217,217,6,255,255,255,1, + 128,128,128,1,220,220,220,4,186,186,186,1,39,39,39,1,217,217,217,1, + 184,184,184,1,219,219,219,1,220,220,220,3,115,115,115,1,118,118,118,1, + 34,34,34,1,185,185,185,1,220,220,220,6,255,255,255,1,128,128,128,1, + 222,222,222,4,163,163,163,1,44,44,44,1,39,39,39,1,57,57,57,1, + 38,38,38,1,178,178,178,1,222,222,222,1,178,178,178,1,57,57,57,1, + 220,220,220,1,34,34,34,1,187,187,187,1,222,222,222,6,255,255,255,1, + 128,128,128,1,225,225,225,4,155,155,155,1,2,2,2,1,196,196,196,1, + 225,225,225,1,144,144,144,1,79,79,79,1,217,217,217,1,47,47,47,1, + 196,196,196,1,225,225,225,1,34,34,34,1,190,190,190,1,225,225,225,6, + 255,255,255,1,128,128,128,1,227,227,227,4,179,179,179,1,34,34,34,1, + 227,227,227,2,200,200,200,1,23,23,23,1,151,151,151,1,11,11,11,1, + 35,35,35,2,5,5,5,1,29,29,29,1,185,185,185,1,227,227,227,5, + 255,255,255,1,128,128,128,1,230,230,230,4,224,224,224,1,28,28,28,1, + 191,191,191,1,230,230,230,1,132,132,132,1,69,69,69,1,225,225,225,1, + 216,216,216,3,33,33,33,1,182,182,182,1,227,227,227,1,230,230,230,5, + 255,255,255,1,128,128,128,1,233,233,233,5,173,173,173,1,34,34,34,1, + 49,49,49,1,42,42,42,1,207,207,207,1,233,233,233,4,36,36,36,1, + 196,196,196,1,233,233,233,6,255,255,255,1,128,128,128,1,235,235,235,6, + 234,234,234,1,220,220,220,1,235,235,235,14,255,255,255,1,128,128,128,1, + 238,238,238,22,255,255,255,25,208,208,208,120,16,0,0,0,0,0,0,120, + 255,255,255,255,255,255,255,81,0,0,0,120,0,0) + ); + +const + objdata_trealdisp: record size: integer; data: array[0..784] of byte end = + (size: 785; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,114,101, + 97,108,100,105,115,112,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,156,2,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,84,2,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,208,208,208,120,128,128,128,25,209,209,209,22,255, + 255,255,1,128,128,128,1,211,211,211,4,199,199,199,1,205,205,205,1,211, + 211,211,7,202,202,202,1,211,211,211,6,193,193,193,1,211,211,211,1,255, + 255,255,1,128,128,128,1,214,214,214,3,199,199,199,1,29,29,29,1,167, + 167,167,1,214,214,214,5,170,170,170,1,53,53,53,1,42,42,42,1,47, + 47,47,1,156,156,156,1,214,214,214,3,159,159,159,1,21,21,21,1,214, + 214,214,1,255,255,255,1,128,128,128,1,217,217,217,2,159,159,159,1,31, + 31,31,1,11,11,11,1,169,169,169,1,217,217,217,5,59,59,59,1,153, + 153,153,1,217,217,217,1,170,170,170,1,37,37,37,1,217,217,217,1,215, + 215,215,1,116,116,116,1,22,22,22,1,18,18,18,1,217,217,217,1,255, + 255,255,1,128,128,128,1,219,219,219,2,100,100,100,1,171,171,171,1,47, + 47,47,1,171,171,171,1,219,219,219,5,161,161,161,1,217,217,217,1,219, + 219,219,1,198,198,198,1,7,7,7,1,212,212,212,1,204,204,204,1,88, + 88,88,1,182,182,182,1,18,18,18,1,219,219,219,1,255,255,255,1,128, + 128,128,1,222,222,222,4,48,48,48,1,173,173,173,1,222,222,222,7,221, + 221,221,1,84,84,84,1,87,87,87,1,222,222,222,3,204,204,204,1,18, + 18,18,1,222,222,222,1,255,255,255,1,128,128,128,1,224,224,224,4,48, + 48,48,1,175,175,175,1,224,224,224,6,221,221,221,1,82,82,82,1,62, + 62,62,1,215,215,215,1,224,224,224,3,206,206,206,1,18,18,18,1,224, + 224,224,1,255,255,255,1,128,128,128,1,227,227,227,4,49,49,49,1,177, + 177,177,1,227,227,227,5,222,222,222,1,73,73,73,1,77,77,77,1,222, + 222,222,1,227,227,227,4,208,208,208,1,19,19,19,1,227,227,227,1,255, + 255,255,1,128,128,128,1,229,229,229,4,49,49,49,1,179,179,179,1,229, + 229,229,2,210,210,210,1,216,216,216,1,229,229,229,1,86,86,86,1,95, + 95,95,1,228,228,228,1,229,229,229,5,210,210,210,1,19,19,19,1,229, + 229,229,1,255,255,255,1,128,128,128,1,232,232,232,4,50,50,50,1,181, + 181,181,1,232,232,232,2,73,73,73,1,130,130,130,1,201,201,201,1,0, + 0,0,1,5,5,5,1,6,6,6,3,209,209,209,1,232,232,232,2,213, + 213,213,1,19,19,19,1,232,232,232,1,255,255,255,1,128,128,128,1,235, + 235,235,22,255,255,255,1,128,128,128,1,237,237,237,22,255,255,255,25,208, + 208,208,120,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255,81,0, + 0,0,120,0,0) + ); + +const + objdata_tstringdisp: record size: integer; data: array[0..826] of byte end = + (size: 827; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,115,116, + 114,105,110,103,100,105,115,112,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,196,2,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,124,2,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,208,208,208,120,128,128,128,25,209,209,209, + 22,255,255,255,1,128,128,128,1,211,211,211,8,192,192,192,1,211,211,211, + 13,255,255,255,1,128,128,128,1,214,214,214,8,7,7,7,1,214,214,214, + 13,255,255,255,1,128,128,128,1,217,217,217,8,7,7,7,1,217,217,217, + 13,255,255,255,1,128,128,128,1,219,219,219,1,218,218,218,1,106,106,106, + 1,35,35,35,1,22,22,22,1,60,60,60,1,201,201,201,1,219,219,219, + 1,7,7,7,1,123,123,123,1,35,35,35,1,50,50,50,1,186,186,186, + 1,219,219,219,1,210,210,210,1,76,76,76,1,29,29,29,1,60,60,60, + 1,178,178,178,1,219,219,219,3,255,255,255,1,128,128,128,1,222,222,222, + 1,177,177,177,1,57,57,57,1,218,218,218,1,219,219,219,1,68,68,68, + 1,126,126,126,1,222,222,222,1,7,7,7,1,109,109,109,1,219,219,219, + 1,120,120,120,1,53,53,53,1,222,222,222,1,84,84,84,1,92,92,92, + 1,216,216,216,1,166,166,166,1,61,61,61,1,222,222,222,3,255,255,255, + 1,128,128,128,1,224,224,224,2,204,204,204,1,148,148,148,1,105,105,105, + 1,35,35,35,1,112,112,112,1,224,224,224,1,8,8,8,1,202,202,202, + 1,224,224,224,1,208,208,208,1,4,4,4,1,218,218,218,1,26,26,26, + 1,181,181,181,1,224,224,224,6,255,255,255,1,128,128,128,1,227,227,227, + 1,174,174,174,1,25,25,25,1,109,109,109,1,161,161,161,1,88,88,88, + 1,113,113,113,1,227,227,227,1,10,10,10,1,219,219,219,1,227,227,227, + 1,215,215,215,1,6,6,6,1,220,220,220,1,14,14,14,1,193,193,193, + 1,227,227,227,2,207,207,207,1,227,227,227,3,255,255,255,1,128,128,128, + 1,229,229,229,1,113,113,113,1,101,101,101,1,229,229,229,1,222,222,222, + 1,44,44,44,1,110,110,110,1,229,229,229,1,7,7,7,1,148,148,148, + 1,229,229,229,1,142,142,142,1,49,49,49,1,229,229,229,1,64,64,64, + 1,126,126,126,1,229,229,229,1,191,191,191,1,41,41,41,1,228,228,228, + 1,229,229,229,2,255,255,255,1,128,128,128,1,232,232,232,1,200,200,200, + 1,45,45,45,1,63,63,63,1,55,55,55,1,86,86,86,2,232,232,232, + 1,17,17,17,1,99,99,99,1,48,48,48,1,70,70,70,1,195,195,195, + 1,232,232,232,1,199,199,199,1,79,79,79,1,51,51,51,1,50,50,50, + 1,173,173,173,1,232,232,232,3,255,255,255,1,128,128,128,1,235,235,235, + 3,219,219,219,1,235,235,235,6,228,228,228,1,235,235,235,5,226,226,226, + 1,235,235,235,5,255,255,255,1,128,128,128,1,237,237,237,22,255,255,255, + 25,208,208,208,120,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255, + 81,0,0,0,120,0,0) + ); + +const + objdata_trichstringdisp: record size: integer; data: array[0..842] of byte end = + (size: 843; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,114,105, + 99,104,115,116,114,105,110,103,100,105,115,112,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,208,2,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,14,0,0,0,144,2,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,209,209,209, + 22,255,255,255,1,128,128,128,1,212,212,212,22,255,255,255,1,128,128,128, + 1,214,214,214,8,33,33,246,1,108,108,233,1,214,214,214,12,255,255,255, + 1,128,128,128,1,217,217,217,8,7,7,251,1,94,94,237,1,217,217,217, + 12,255,255,255,1,128,128,128,1,220,220,220,2,139,139,139,1,60,60,60, + 1,46,46,46,1,94,94,94,1,211,211,211,1,220,220,220,1,7,7,251, + 1,83,83,240,1,116,116,235,1,62,62,243,1,149,149,230,1,219,219,220, + 1,220,220,220,2,132,132,132,1,61,61,61,1,80,80,80,1,182,182,182, + 1,220,220,220,2,255,255,255,1,128,128,128,1,222,222,222,1,176,176,176, + 1,34,34,34,1,203,203,203,1,202,202,202,1,55,55,55,1,132,132,132, + 1,222,222,222,1,7,7,251,1,5,5,251,1,113,113,237,1,77,77,242, + 1,0,0,252,1,172,172,229,1,222,222,222,1,130,130,130,1,63,63,63, + 1,200,200,200,1,144,144,144,1,58,58,58,1,222,222,222,2,255,255,255, + 1,128,128,128,1,225,225,225,2,210,210,210,1,169,169,169,1,127,127,127, + 1,45,45,45,1,113,113,113,1,225,225,225,1,7,7,251,1,63,63,244, + 1,225,225,225,1,216,216,226,1,5,5,251,1,100,100,240,1,225,225,225, + 1,19,19,19,1,195,195,195,1,225,225,225,1,224,224,224,1,206,206,206, + 1,225,225,225,2,255,255,255,1,128,128,128,1,227,227,227,1,179,179,179, + 1,27,27,27,1,95,95,95,1,147,147,147,1,83,83,83,1,113,113,113, + 1,227,227,227,1,7,7,251,1,76,76,244,1,227,227,227,1,225,225,227, + 1,15,15,250,1,69,69,244,1,202,202,202,1,19,19,19,1,227,227,227, + 2,221,221,221,1,226,226,226,1,227,227,227,2,255,255,255,1,128,128,128, + 1,230,230,230,1,114,114,114,1,101,101,101,1,230,230,230,1,225,225,225, + 1,49,49,49,1,111,111,111,1,230,230,230,1,7,7,251,1,16,16,250, + 1,162,162,236,1,133,133,239,1,0,0,252,1,122,122,240,1,225,225,225, + 1,22,22,22,1,221,221,221,1,229,229,229,1,54,54,54,1,166,166,166, + 1,230,230,230,2,255,255,255,1,128,128,128,1,233,233,233,1,198,198,198, + 1,44,44,44,1,70,70,70,1,61,61,61,1,87,87,87,2,233,233,233, + 1,7,7,251,1,76,76,246,1,26,26,250,1,9,9,251,1,97,97,244, + 1,223,223,234,1,233,233,233,1,132,132,132,1,56,56,56,1,57,57,57, + 1,115,115,115,1,233,233,233,3,255,255,255,1,128,128,128,1,235,235,235, + 3,219,219,219,1,235,235,235,6,234,234,235,1,226,226,236,1,235,235,235, + 4,229,229,229,1,230,230,230,1,235,235,235,4,255,255,255,1,128,128,128, + 1,238,238,238,22,255,255,255,25,8,0,0,0,255,255,255,255,255,255,255, + 81,0,0) + ); + +const + objdata_tbooleandisp: record size: integer; data: array[0..723] of byte end = + (size: 724; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,98,111, + 111,108,101,97,110,100,105,115,112,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,92,2,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,20,2,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,208,208,208,120,128,128,128,25,209,209, + 209,22,255,255,255,1,128,128,128,1,211,211,211,1,196,196,196,1,191,191, + 191,5,199,199,199,1,211,211,211,2,177,177,177,1,209,209,209,1,192,192, + 192,1,191,191,191,4,203,203,203,1,211,211,211,4,255,255,255,1,128,128, + 128,1,214,214,214,1,73,73,73,1,26,26,26,1,24,24,24,1,0,0, + 0,1,26,26,26,2,91,91,91,1,214,214,214,1,213,213,213,1,47,47, + 47,1,214,214,214,1,3,3,3,1,24,24,24,1,26,26,26,3,129,129, + 129,1,214,214,214,4,255,255,255,1,128,128,128,1,217,217,217,3,203,203, + 203,1,0,0,0,1,217,217,217,4,175,175,175,1,88,88,88,1,217,217, + 217,1,3,3,3,1,201,201,201,1,217,217,217,8,255,255,255,1,128,128, + 128,1,219,219,219,3,205,205,205,1,0,0,0,1,219,219,219,4,115,115, + 115,1,149,149,149,1,219,219,219,1,3,3,3,1,203,203,203,1,219,219, + 219,8,255,255,255,1,128,128,128,1,222,222,222,3,208,208,208,1,0,0, + 0,1,222,222,222,4,58,58,58,1,210,210,210,1,222,222,222,1,3,3, + 3,1,77,77,77,1,83,83,83,2,103,103,103,1,222,222,222,5,255,255, + 255,1,128,128,128,1,224,224,224,3,210,210,210,1,0,0,0,1,224,224, + 224,3,212,212,212,1,57,57,57,1,224,224,224,2,3,3,3,1,136,136, + 136,1,147,147,147,2,158,158,158,1,224,224,224,5,255,255,255,1,128,128, + 128,1,227,227,227,3,213,213,213,1,0,0,0,1,227,227,227,3,155,155, + 155,1,117,117,117,1,227,227,227,2,3,3,3,1,210,210,210,1,227,227, + 227,8,255,255,255,1,128,128,128,1,229,229,229,3,215,215,215,1,0,0, + 0,1,229,229,229,3,92,92,92,1,181,181,181,1,229,229,229,2,3,3, + 3,1,212,212,212,1,229,229,229,8,255,255,255,1,128,128,128,1,232,232, + 232,3,217,217,217,1,0,0,0,1,232,232,232,3,46,46,46,1,230,230, + 230,1,232,232,232,2,3,3,3,1,215,215,215,1,232,232,232,8,255,255, + 255,1,128,128,128,1,235,235,235,7,234,234,234,1,213,213,213,1,235,235, + 235,13,255,255,255,1,128,128,128,1,237,237,237,22,255,255,255,25,208,208, + 208,120,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255,81,0,0, + 0,120,0,0) + ); + +const + objdata_tedit: record size: integer; data: array[0..484] of byte end = + (size: 485; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,5,116,101,100, + 105,116,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110, + 116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111, + 112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98, + 109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112, + 46,105,109,97,103,101,10,116,1,0,0,0,0,0,0,6,0,0,0,24, + 0,0,0,24,0,0,0,44,1,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,255,255,255,120,128,128,128,25,0,0,0,22,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,17,0,0,0,1,255,255,255,1,0, + 0,0,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,18,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,18,0,0,0,1,255,255,255,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,18,0, + 0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,18,0,0,0,1,255,255,255,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,18,0,0,0,1,255, + 255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,18,0,0,0,1,255,255,255,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,17,0,0,0,1,255,255,255,1,0, + 0,0,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,20,224,224,224,1,255,255,255,1,128,128,128,1,224,224,224,22,255, + 255,255,145,16,0,0,0,0,0,0,120,255,255,255,255,255,255,255,81,0, + 0,0,120,0,0) + ); + +const + objdata_ttoolbar: record size: integer; data: array[0..727] of byte end = + (size: 728; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,8,116,116,111, + 111,108,98,97,114,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97, + 114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97, + 112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101, + 100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116, + 109,97,112,46,105,109,97,103,101,10,100,2,0,0,0,0,0,0,6,0, + 0,0,24,0,0,0,24,0,0,0,32,2,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,208,208,208,168,255,255,255,23,128,128,128,1,255,255, + 255,1,208,208,208,16,204,204,204,1,208,208,208,5,128,128,128,1,255,255, + 255,1,208,208,208,2,108,108,151,2,208,208,208,3,191,202,188,1,86,161, + 69,1,39,143,15,1,111,171,97,1,207,208,207,1,208,208,208,1,115,115, + 115,1,255,255,255,1,208,208,208,1,159,159,159,1,141,141,141,1,202,202, + 202,1,208,208,208,3,128,128,128,1,255,255,255,1,208,208,208,2,73,73, + 159,2,208,208,208,3,113,171,100,1,88,162,71,1,175,195,170,1,52,148, + 30,1,163,191,156,1,208,208,208,1,115,115,115,1,255,255,255,1,208,208, + 208,1,158,158,158,1,104,104,104,1,109,109,109,1,178,178,178,1,208,208, + 208,2,128,128,128,1,255,255,255,1,108,108,151,1,73,73,159,1,38,38, + 167,2,73,73,159,1,108,108,151,1,208,208,208,1,66,153,46,1,163,191, + 157,1,208,208,208,1,113,172,99,1,118,173,105,1,208,208,208,1,115,115, + 115,1,255,255,255,1,208,208,208,1,158,158,158,1,144,144,144,1,176,176, + 176,1,107,107,107,1,141,141,141,1,202,202,202,1,128,128,128,1,255,255, + 255,1,108,108,151,1,73,73,159,1,38,38,167,2,73,73,159,1,108,108, + 151,1,208,208,208,1,66,154,46,1,166,192,160,1,208,208,208,1,115,172, + 102,1,117,173,104,1,208,208,208,1,115,115,115,1,255,255,255,1,208,208, + 208,1,158,158,158,1,144,144,144,1,176,176,176,1,108,108,108,1,141,141, + 141,1,202,202,202,1,128,128,128,1,255,255,255,1,208,208,208,2,73,73, + 159,2,208,208,208,3,103,168,88,1,104,168,89,1,199,204,198,1,63,152, + 42,1,153,187,145,1,208,208,208,1,115,115,115,1,255,255,255,1,208,208, + 208,1,158,158,158,1,104,104,104,1,110,110,110,1,180,180,180,1,208,208, + 208,2,128,128,128,1,255,255,255,1,208,208,208,2,108,108,151,2,208,208, + 208,3,182,198,178,1,64,152,43,1,32,141,7,1,87,161,70,1,205,207, + 205,1,208,208,208,1,115,115,115,1,255,255,255,1,208,208,208,1,159,159, + 159,1,144,144,144,1,204,204,204,1,208,208,208,3,128,128,128,1,255,255, + 255,1,208,208,208,9,195,203,193,1,208,208,208,6,205,205,205,1,208,208, + 208,5,128,128,128,25,208,208,208,168,12,0,0,0,0,0,0,168,255,255, + 255,240,0,0,0,168,0,0) + ); + +const + objdata_tsplitter: record size: integer; data: array[0..1428] of byte end = + (size: 1429; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,115,112, + 108,105,116,116,101,114,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,32,5,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,244,2,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,3,3,3,1,7,7,7,1,18,18,18,1,224, + 224,224,2,139,139,139,1,7,7,7,2,58,58,58,1,224,224,224,2,81, + 81,81,1,7,7,7,2,107,107,107,1,224,224,224,2,39,39,39,1,7, + 7,7,2,177,177,177,1,224,224,224,2,255,255,255,1,7,7,7,1,224, + 224,224,21,7,7,7,1,255,255,255,1,26,26,26,1,224,224,224,21,7, + 7,7,1,0,0,0,1,224,224,224,22,25,25,25,1,0,0,0,1,224, + 224,224,22,145,145,145,1,0,0,0,1,131,131,131,1,224,224,224,21,145, + 145,145,1,0,0,0,1,7,7,7,1,224,224,224,9,112,112,112,1,224, + 224,224,1,112,112,112,1,224,224,224,9,99,99,99,1,0,0,0,1,7, + 7,7,1,224,224,224,9,0,0,0,1,224,224,224,1,0,0,0,1,224, + 224,224,9,7,7,7,1,0,0,0,1,64,64,64,1,224,224,224,9,0, + 0,0,1,224,224,224,1,0,0,0,1,224,224,224,9,7,7,7,1,0, + 0,0,1,224,224,224,5,55,55,55,1,168,168,168,1,224,224,224,3,0, + 0,0,1,224,224,224,1,0,0,0,1,224,224,224,3,168,168,168,1,55, + 55,55,1,224,224,224,4,55,55,55,1,0,0,0,1,224,224,224,5,0, + 0,0,2,55,55,55,1,168,168,168,1,224,224,224,1,0,0,0,1,224, + 224,224,1,0,0,0,1,224,224,224,1,168,168,168,1,55,55,55,1,0, + 0,0,2,224,224,224,4,145,145,145,1,0,0,0,1,75,75,75,1,112, + 112,112,1,0,0,0,7,112,112,112,1,0,0,0,1,224,224,224,1,0, + 0,0,1,112,112,112,1,0,0,0,7,112,112,112,1,145,145,145,1,0, + 0,0,1,7,7,7,1,224,224,224,4,0,0,0,2,55,55,55,1,168, + 168,168,1,224,224,224,1,0,0,0,1,224,224,224,1,0,0,0,1,224, + 224,224,1,168,168,168,1,55,55,55,1,0,0,0,2,224,224,224,4,64, + 64,64,1,0,0,0,1,7,7,7,1,224,224,224,4,55,55,55,1,168, + 168,168,1,224,224,224,3,0,0,0,1,224,224,224,1,0,0,0,1,224, + 224,224,3,168,168,168,1,55,55,55,1,224,224,224,4,7,7,7,1,0, + 0,0,1,115,115,115,1,224,224,224,9,0,0,0,1,224,224,224,1,0, + 0,0,1,224,224,224,9,7,7,7,1,0,0,0,1,224,224,224,10,0, + 0,0,1,224,224,224,1,0,0,0,1,224,224,224,9,90,90,90,1,0, + 0,0,1,224,224,224,10,112,112,112,1,224,224,224,1,112,112,112,1,224, + 224,224,9,145,145,145,1,0,0,0,1,35,35,35,1,224,224,224,21,145, + 145,145,1,0,0,0,1,7,7,7,1,224,224,224,21,32,32,32,1,0, + 0,0,1,7,7,7,1,224,224,224,21,7,7,7,1,0,0,0,1,189, + 189,189,1,224,224,224,21,7,7,7,1,0,0,0,1,224,224,224,22,129, + 129,129,1,0,0,0,1,179,179,179,1,7,7,7,2,28,28,28,1,145, + 145,145,2,94,94,94,1,7,7,7,2,59,59,59,1,145,145,145,2,59, + 59,59,1,7,7,7,2,94,94,94,1,145,145,145,2,28,28,28,1,7, + 7,7,2,134,134,134,1,85,85,85,1,0,0,0,1,255,255,255,1,0, + 0,0,23,244,1,0,0,244,244,244,1,248,248,248,1,236,236,236,1,128, + 128,128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2,188, + 188,188,1,248,248,248,2,173,173,173,1,128,128,128,2,218,218,218,1,248, + 248,248,2,143,143,143,1,128,128,128,1,64,64,64,1,0,0,0,1,248, + 248,248,1,255,255,255,21,248,248,248,1,0,0,0,1,229,229,229,1,255, + 255,255,21,248,248,248,1,16,16,16,1,128,128,128,1,255,255,255,21,241, + 241,241,1,106,106,106,1,128,128,128,1,255,255,255,21,198,198,198,1,122, + 122,122,1,161,161,161,1,255,255,255,21,198,198,198,1,122,122,122,1,248, + 248,248,1,255,255,255,21,213,213,213,1,122,122,122,1,248,248,248,1,255, + 255,255,21,252,252,252,1,122,122,122,1,199,199,199,1,255,255,255,21,252, + 252,252,1,122,122,122,1,128,128,128,1,255,255,255,21,230,230,230,1,122, + 122,122,1,128,128,128,1,255,255,255,21,198,198,198,1,122,122,122,1,191, + 191,191,1,255,255,255,21,198,198,198,1,122,122,122,1,248,248,248,1,255, + 255,255,21,226,226,226,1,122,122,122,1,248,248,248,1,255,255,255,21,252, + 252,252,1,122,122,122,1,169,169,169,1,255,255,255,21,252,252,252,1,122, + 122,122,1,128,128,128,1,255,255,255,21,216,216,216,1,122,122,122,1,128, + 128,128,1,255,255,255,21,198,198,198,1,122,122,122,1,221,221,221,1,255, + 255,255,21,198,198,198,1,122,122,122,1,248,248,248,1,255,255,255,21,240, + 240,240,1,122,122,122,1,248,248,248,1,255,255,255,21,252,252,252,1,122, + 122,122,1,139,139,139,1,255,255,255,21,252,252,252,1,122,122,122,1,128, + 128,128,1,255,255,255,21,203,203,203,1,122,122,122,1,75,75,75,1,248, + 248,248,1,251,251,251,1,242,242,242,1,198,198,198,2,215,215,215,1,252, + 252,252,2,228,228,228,1,198,198,198,2,228,228,228,1,252,252,252,2,215, + 215,215,1,198,198,198,2,242,242,242,1,252,252,252,2,201,201,201,1,169, + 169,169,1,122,122,122,1,0,0,0,1,16,16,16,1,106,106,106,1,122, + 122,122,20,106,106,106,1,0,0) + ); + +const + objdata_tdockhandle: record size: integer; data: array[0..459] of byte end = + (size: 460; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,100,111, + 99,107,104,97,110,100,108,101,12,98,105,116,109,97,112,46,105,109,97,103, + 101,10,156,1,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0, + 0,0,104,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0, + 255,237,255,255,255,1,255,0,255,22,255,255,255,1,128,128,128,1,255,0, + 255,21,255,255,255,1,128,128,128,1,192,192,192,1,255,0,255,20,255,255, + 255,1,128,128,128,1,192,192,192,1,255,255,255,1,255,0,255,19,255,255, + 255,1,128,128,128,1,192,192,192,1,255,255,255,1,128,128,128,1,255,0, + 255,18,255,255,255,1,128,128,128,1,192,192,192,1,255,255,255,1,128,128, + 128,1,192,192,192,1,255,0,255,17,255,255,255,1,128,128,128,1,192,192, + 192,1,255,255,255,1,128,128,128,1,192,192,192,1,255,255,255,1,255,0, + 255,16,255,255,255,1,128,128,128,1,192,192,192,1,255,255,255,1,128,128, + 128,1,192,192,192,1,255,255,255,1,128,128,128,1,255,0,255,15,255,255, + 255,1,128,128,128,1,192,192,192,1,255,255,255,1,128,128,128,1,192,192, + 192,1,255,255,255,1,128,128,128,1,255,0,255,15,255,255,255,1,128,128, + 128,1,192,192,192,1,255,255,255,1,128,128,128,1,192,192,192,1,255,255, + 255,1,128,128,128,1,255,0,255,15,255,255,255,1,128,128,128,1,192,192, + 192,1,255,255,255,1,128,128,128,1,192,192,192,1,255,255,255,1,128,128, + 128,1,255,0,255,15,255,255,255,1,128,128,128,1,192,192,192,1,255,255, + 255,1,128,128,128,1,192,192,192,1,255,255,255,1,128,128,128,1,255,0, + 255,15,255,255,255,1,128,128,128,1,192,192,192,1,255,255,255,1,128,128, + 128,1,192,192,192,1,255,255,255,1,128,128,128,1,255,0,255,55,0,0) + ); + +const + objdata_teventwidget: record size: integer; data: array[0..1619] of byte end = + (size: 1620; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,101,118, + 101,110,116,119,105,100,103,101,116,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,220,5,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,192,2,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,128,128,128,25,208,208,208,14,0,0, + 255,2,208,208,208,6,255,255,255,1,128,128,128,1,208,208,208,13,0,0, + 255,1,7,7,255,1,6,6,255,1,208,208,208,6,255,255,255,1,128,128, + 128,1,208,208,208,12,0,0,255,1,34,34,255,1,136,136,255,1,71,71, + 255,1,0,0,255,1,208,208,208,5,255,255,255,1,128,128,128,1,208,208, + 208,10,0,0,255,1,2,2,255,1,75,75,255,1,175,175,255,1,82,82, + 255,1,5,5,255,1,0,0,255,1,208,208,208,5,255,255,255,1,128,128, + 128,1,208,208,208,9,0,0,255,1,14,14,255,1,119,119,255,1,143,143, + 255,1,28,28,255,1,0,0,255,1,208,208,208,7,255,255,255,1,128,128, + 128,1,208,208,208,8,0,0,255,1,42,42,255,1,160,160,255,1,81,81, + 255,1,4,4,255,1,0,0,255,1,208,208,208,8,255,255,255,1,128,128, + 128,1,208,208,208,6,0,0,255,1,4,4,255,1,86,86,255,1,142,142, + 255,1,26,26,255,1,0,0,255,1,208,208,208,10,255,255,255,1,128,128, + 128,1,208,208,208,5,0,0,255,1,17,17,255,1,132,132,255,1,80,80, + 255,1,4,4,255,1,0,0,255,1,208,208,208,11,255,255,255,1,128,128, + 128,1,208,208,208,4,0,0,255,1,46,46,255,1,130,130,255,1,26,26, + 255,1,0,0,255,1,208,208,208,13,255,255,255,1,128,128,128,1,208,208, + 208,3,0,0,255,1,28,28,255,1,97,97,255,1,5,5,255,1,0,0, + 255,1,208,208,208,14,255,255,255,1,128,128,128,1,208,208,208,4,0,0, + 255,1,3,3,255,1,0,0,255,3,208,208,208,13,255,255,255,1,128,128, + 128,1,208,208,208,6,0,0,255,5,208,208,208,11,255,255,255,1,128,128, + 128,1,208,208,208,7,0,0,255,6,208,208,208,9,255,255,255,1,128,128, + 128,1,208,208,208,9,0,0,255,5,208,208,208,8,255,255,255,1,128,128, + 128,1,208,208,208,8,0,0,255,2,208,208,208,1,0,0,255,4,208,208, + 208,7,255,255,255,1,128,128,128,1,208,208,208,8,12,12,255,1,17,17, + 255,1,208,208,208,1,0,0,255,4,208,208,208,7,255,255,255,1,128,128, + 128,1,208,208,208,7,0,0,255,1,72,72,255,1,64,64,255,1,0,0, + 255,3,208,208,208,9,255,255,255,1,128,128,128,1,208,208,208,7,52,52, + 255,1,140,140,255,1,55,55,255,1,0,0,255,2,208,208,208,10,255,255, + 255,1,128,128,128,1,208,208,208,6,27,27,255,1,130,130,255,1,169,169, + 255,1,94,94,255,1,34,34,255,1,0,0,255,3,208,208,208,8,255,255, + 255,1,128,128,128,1,208,208,208,6,97,97,255,1,171,171,255,1,108,108, + 255,1,42,42,255,1,0,0,255,4,208,208,208,8,255,255,255,1,128,128, + 128,1,208,208,208,5,27,27,255,1,127,127,255,1,75,75,255,1,22,22, + 255,1,0,0,255,1,208,208,208,12,255,255,255,1,128,128,128,1,208,208, + 208,5,0,0,255,1,208,208,208,16,255,255,255,25,228,2,0,0,255,255, + 255,25,0,0,0,14,15,15,15,1,17,17,17,1,0,0,0,6,255,255, + 255,2,0,0,0,13,47,47,47,1,182,182,182,1,134,134,134,1,0,0, + 0,6,255,255,255,2,0,0,0,12,96,96,96,1,193,193,193,1,253,253, + 253,1,187,187,187,1,20,20,20,1,0,0,0,5,255,255,255,2,0,0, + 0,10,7,7,7,1,146,146,146,1,208,208,208,1,255,255,255,1,200,200, + 200,1,150,150,150,1,15,15,15,1,0,0,0,5,255,255,255,2,0,0, + 0,9,32,32,32,1,176,176,176,1,230,230,230,1,232,232,232,1,183,183, + 183,1,71,71,71,1,0,0,0,7,255,255,255,2,0,0,0,8,74,74, + 74,1,188,188,188,1,248,248,248,1,199,199,199,1,142,142,142,1,12,12, + 12,1,0,0,0,8,255,255,255,2,0,0,0,6,2,2,2,1,127,127, + 127,1,201,201,201,1,228,228,228,1,183,183,183,1,60,60,60,1,0,0, + 0,10,255,255,255,2,0,0,0,5,20,20,20,1,166,166,166,1,220,220, + 220,1,197,197,197,1,132,132,132,1,8,8,8,1,0,0,0,11,255,255, + 255,2,0,0,0,4,55,55,55,1,184,184,184,1,216,216,216,1,179,179, + 179,1,49,49,49,1,0,0,0,13,255,255,255,2,0,0,0,3,33,33, + 33,1,206,206,206,1,226,226,226,1,203,203,203,1,10,10,10,1,0,0, + 0,14,255,255,255,2,0,0,0,4,30,30,30,1,159,159,159,1,206,206, + 206,1,189,189,189,1,64,64,64,1,0,0,0,13,255,255,255,2,0,0, + 0,6,61,61,61,1,180,180,180,1,207,207,207,1,154,154,154,1,21,21, + 21,1,0,0,0,11,255,255,255,2,0,0,0,7,2,2,2,1,101,101, + 101,1,196,196,196,1,200,200,200,1,101,101,101,1,1,1,1,1,0,0, + 0,9,255,255,255,2,0,0,0,9,15,15,15,1,137,137,137,1,206,206, + 206,1,179,179,179,1,46,46,46,1,0,0,0,8,255,255,255,2,0,0, + 0,8,14,14,14,1,9,9,9,1,0,0,0,1,38,38,38,1,169,169, + 169,1,210,210,210,1,124,124,124,1,0,0,0,7,255,255,255,2,0,0, + 0,8,124,124,124,1,59,59,59,1,0,0,0,1,5,5,5,1,141,141, + 141,1,177,177,177,1,27,27,27,1,0,0,0,7,255,255,255,2,0,0, + 0,7,31,31,31,1,223,223,223,1,96,96,96,1,33,33,33,1,180,180, + 180,1,88,88,88,1,0,0,0,9,255,255,255,2,0,0,0,7,149,149, + 149,1,255,255,255,1,165,165,165,1,148,148,148,1,19,19,19,1,0,0, + 0,10,255,255,255,2,0,0,0,6,57,57,57,1,240,240,240,1,255,255, + 255,1,239,239,239,1,183,183,183,1,136,136,136,1,87,87,87,1,16,16, + 16,1,0,0,0,8,255,255,255,2,0,0,0,6,173,173,173,1,255,255, + 255,2,239,239,239,1,191,191,191,1,139,139,139,1,88,88,88,1,15,15, + 15,1,0,0,0,8,255,255,255,2,0,0,0,5,84,84,84,1,193,193, + 193,1,144,144,144,1,94,94,94,1,22,22,22,1,0,0,0,12,255,255, + 255,2,0,0,0,5,3,3,3,1,0,0,0,16,255,255,255,25,0,0) + ); + +const + objdata_tdockpanel: record size: integer; data: array[0..2297] of byte end = + (size: 2298; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,100,111, + 99,107,112,97,110,101,108,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,132,8,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,64,8,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,128,128,128,25,230,230,230,1,229,229,229,1, + 228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1, + 223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1, + 218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1, + 212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1, + 255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1, + 227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1, + 222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1, + 217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1, + 255,255,255,1,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1, + 128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1, + 226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1, + 221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1, + 215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,255,255,255,1, + 128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1,128,128,128,1, + 230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1, + 225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1, + 220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1, + 214,214,214,1,213,213,213,1,212,212,212,1,255,255,255,1,128,128,128,1, + 255,255,255,1,128,128,128,1,255,255,255,1,128,128,128,1,230,230,230,1, + 229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1, + 224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1, + 219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1, + 213,213,213,1,212,212,212,1,255,255,255,1,128,128,128,1,255,255,255,1, + 128,128,128,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1, + 228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1, + 223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1, + 218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1, + 212,212,212,1,255,255,255,1,128,128,128,1,255,255,255,1,128,128,128,1, + 255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1, + 227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1, + 222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1, + 217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1, + 255,255,255,1,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1, + 128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1, + 226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1, + 221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1, + 215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,255,255,255,1, + 128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1,128,128,128,1, + 230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1, + 225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1, + 220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1, + 214,214,214,1,213,213,213,1,212,212,212,1,255,255,255,1,128,128,128,1, + 255,255,255,1,128,128,128,1,255,255,255,1,128,128,128,1,230,230,230,1, + 229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1, + 224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1, + 219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1, + 213,213,213,1,212,212,212,1,255,255,255,1,128,128,128,1,255,255,255,1, + 128,128,128,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1, + 228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1, + 223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1, + 218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1, + 212,212,212,1,255,255,255,1,128,128,128,1,255,255,255,1,128,128,128,1, + 255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1, + 227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1, + 222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1, + 217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1, + 255,255,255,1,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1, + 128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1, + 226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1, + 221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1, + 215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,255,255,255,1, + 128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1,128,128,128,1, + 230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1, + 225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1, + 220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1, + 214,214,214,1,213,213,213,1,212,212,212,1,255,255,255,1,128,128,128,1, + 255,255,255,1,128,128,128,1,255,255,255,1,128,128,128,1,230,230,230,1, + 229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1, + 224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1, + 219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1, + 213,213,213,1,212,212,212,1,255,255,255,1,128,128,128,1,255,255,255,1, + 128,128,128,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1, + 228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1, + 223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1, + 218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1, + 212,212,212,1,255,255,255,1,128,128,128,1,255,255,255,1,128,128,128,1, + 255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1, + 227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1, + 222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1, + 217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1, + 255,255,255,1,128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1, + 128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1, + 226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1, + 221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1, + 215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,255,255,255,1, + 128,128,128,1,255,255,255,1,128,128,128,1,255,255,255,1,128,128,128,1, + 230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1, + 225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1, + 220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1, + 214,214,214,1,213,213,213,1,212,212,212,1,255,255,255,1,128,128,128,1, + 255,255,255,1,128,128,128,1,255,255,255,1,128,128,128,1,230,230,230,1, + 229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1, + 224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1, + 219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1, + 213,213,213,1,212,212,212,1,255,255,255,1,128,128,128,1,255,255,255,1, + 128,128,128,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1, + 228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1, + 223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1, + 218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1, + 212,212,212,1,255,255,255,1,128,128,128,1,255,255,255,1,128,128,128,1, + 255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1, + 227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1, + 222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1, + 217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1, + 211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,255,255,255,25, + 12,0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tstockglyphbutton: record size: integer; data: array[0..772] of byte end = + (size: 773; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,115,116, + 111,99,107,103,108,121,112,104,98,117,116,116,111,110,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,136, + 2,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,212, + 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,125,224, + 224,224,14,255,255,255,10,224,224,224,1,255,255,255,12,0,0,0,1,255, + 255,255,10,224,224,224,1,255,255,255,1,235,235,235,10,128,128,128,1,0, + 0,0,1,255,255,255,10,224,224,224,1,255,255,255,1,232,232,232,2,205, + 205,205,1,232,232,232,4,205,205,205,1,232,232,232,2,128,128,128,1,0, + 0,0,1,255,255,255,10,224,224,224,1,255,255,255,1,229,229,229,1,202, + 202,202,1,22,22,22,1,175,175,175,1,229,229,229,2,175,175,175,1,22, + 22,22,1,202,202,202,1,229,229,229,1,128,128,128,1,0,0,0,1,255, + 255,255,10,224,224,224,1,255,255,255,1,226,226,226,2,173,173,173,1,21, + 21,21,1,173,173,173,2,21,21,21,1,173,173,173,1,226,226,226,2,128, + 128,128,1,0,0,0,1,255,255,255,10,224,224,224,1,255,255,255,1,223, + 223,223,3,171,171,171,1,16,16,16,2,171,171,171,1,223,223,223,3,128, + 128,128,1,0,0,0,1,255,255,255,10,224,224,224,1,255,255,255,1,221, + 221,221,3,169,169,169,1,16,16,16,2,169,169,169,1,221,221,221,3,128, + 128,128,1,0,0,0,1,255,255,255,10,224,224,224,1,255,255,255,1,218, + 218,218,2,167,167,167,1,21,21,21,1,167,167,167,2,21,21,21,1,167, + 167,167,1,218,218,218,2,128,128,128,1,0,0,0,1,255,255,255,10,224, + 224,224,1,255,255,255,1,215,215,215,1,190,190,190,1,20,20,20,1,164, + 164,164,1,215,215,215,2,164,164,164,1,20,20,20,1,190,190,190,1,215, + 215,215,1,128,128,128,1,0,0,0,1,255,255,255,10,224,224,224,1,255, + 255,255,1,212,212,212,2,187,187,187,1,212,212,212,4,187,187,187,1,212, + 212,212,2,128,128,128,1,0,0,0,1,255,255,255,10,224,224,224,1,255, + 255,255,1,209,209,209,10,128,128,128,1,0,0,0,1,255,255,255,10,224, + 224,224,1,128,128,128,12,0,0,0,1,255,255,255,10,0,0,0,14,255, + 255,255,125,124,0,0,0,0,0,0,125,255,255,255,14,0,0,0,10,255, + 255,255,14,0,0,0,10,255,255,255,14,0,0,0,10,255,255,255,14,0, + 0,0,10,255,255,255,14,0,0,0,10,255,255,255,14,0,0,0,10,255, + 255,255,14,0,0,0,10,255,255,255,14,0,0,0,10,255,255,255,14,0, + 0,0,10,255,255,255,14,0,0,0,10,255,255,255,14,0,0,0,10,255, + 255,255,1,208,208,208,1,255,255,255,12,0,0,0,10,255,255,255,14,0, + 0,0,10,255,255,255,14,0,0,0,125,0,0) + ); + +const + objdata_tgroupbox: record size: integer; data: array[0..2256] of byte end = + (size: 2257; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,103,114, + 111,117,112,98,111,120,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,92,8,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,164,7,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,208,208,208,3,0,0,0,3,208,208,208,3,0, + 0,0,1,208,208,208,17,0,0,0,9,208,208,208,12,128,128,128,3,0, + 0,0,10,128,128,128,12,230,230,230,1,229,229,229,1,204,204,204,1,184, + 184,184,1,169,169,169,1,183,183,183,1,135,135,135,1,170,170,170,1,163, + 163,163,1,157,157,157,1,147,147,147,1,219,219,219,1,218,218,218,1,217, + 217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211, + 211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,255,255,255,1,128, + 128,128,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226, + 226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221, + 221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215, + 215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210, + 210,210,1,209,209,209,1,208,208,208,1,255,255,255,1,128,128,128,1,230, + 230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225, + 225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220, + 220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214, + 214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209, + 209,209,1,208,208,208,1,255,255,255,1,128,128,128,1,230,230,230,1,229, + 229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224, + 224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219, + 219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213, + 213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208, + 208,208,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228, + 228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223, + 223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218, + 218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212, + 212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,255, + 255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1,227, + 227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222, + 222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217, + 217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211, + 211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,255,255,255,1,128, + 128,128,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226, + 226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221, + 221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215, + 215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210, + 210,210,1,209,209,209,1,208,208,208,1,255,255,255,1,128,128,128,1,230, + 230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225, + 225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220, + 220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214, + 214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209, + 209,209,1,208,208,208,1,255,255,255,1,128,128,128,1,230,230,230,1,229, + 229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224, + 224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219, + 219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213, + 213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208, + 208,208,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228, + 228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223, + 223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218, + 218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212, + 212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,255, + 255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1,227, + 227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222, + 222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217, + 217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211, + 211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,255,255,255,1,128, + 128,128,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226, + 226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221, + 221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215, + 215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210, + 210,210,1,209,209,209,1,208,208,208,1,255,255,255,1,128,128,128,1,230, + 230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225, + 225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220, + 220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214, + 214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209, + 209,209,1,208,208,208,1,255,255,255,1,128,128,128,1,230,230,230,1,229, + 229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224, + 224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219, + 219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213, + 213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208, + 208,208,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228, + 228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223, + 223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218, + 218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212, + 212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,255, + 255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1,227, + 227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222, + 222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217, + 217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211, + 211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,255,255,255,1,128, + 128,128,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226, + 226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221, + 221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215, + 215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210, + 210,210,1,209,209,209,1,208,208,208,1,255,255,255,1,128,128,128,1,230, + 230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225, + 225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220, + 220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214, + 214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209, + 209,209,1,208,208,208,1,255,255,255,1,128,128,128,1,230,230,230,1,229, + 229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224, + 224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219, + 219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213, + 213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208, + 208,208,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228, + 228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223, + 223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218, + 218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212, + 212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,255, + 255,255,25,128,0,0,0,0,0,0,3,19,19,19,1,88,88,88,1,58, + 58,58,1,0,0,0,3,46,46,46,1,0,0,0,17,55,55,55,1,141, + 141,141,1,175,175,175,1,58,58,58,1,31,31,31,1,69,69,69,1,102, + 102,102,1,84,84,84,1,91,91,91,1,0,0,0,12,255,255,255,2,128, + 128,128,1,55,55,55,1,154,154,154,1,161,161,161,1,91,91,91,1,63, + 63,63,1,122,122,122,1,136,136,136,1,147,147,147,1,126,126,126,1,13, + 13,13,1,255,255,255,255,255,255,255,255,255,255,255,5,0,0) + ); + +const + objdata_tscrollbox: record size: integer; data: array[0..2205] of byte end = + (size: 2206; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,115,99, + 114,111,108,108,98,111,120,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,40,8,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,228,7,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,128,128,128,25,230,230,230,1,229,229,229,1, + 228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1, + 223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1, + 218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1, + 212,212,212,1,255,255,255,5,128,128,128,1,230,230,230,1,229,229,229,1, + 228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1, + 223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1, + 218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1, + 212,212,212,1,255,255,255,1,210,210,210,1,209,209,209,1,128,128,128,1, + 255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1, + 227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1, + 222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1, + 217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1, + 255,255,255,1,210,210,210,1,209,209,209,1,128,128,128,1,255,255,255,1, + 128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1, + 226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1, + 221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1, + 215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,128,128,128,4, + 255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1, + 227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1, + 222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1, + 217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1, + 250,250,250,1,211,211,211,1,252,252,252,1,211,211,211,1,255,255,255,1, + 128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1, + 226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1, + 221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1, + 215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,215,215,215,1, + 255,255,255,1,209,209,209,1,255,255,255,2,128,128,128,1,230,230,230,1, + 229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1, + 224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1, + 219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1, + 213,213,213,1,212,212,212,1,255,255,255,5,128,128,128,1,230,230,230,1, + 229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1, + 224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1, + 219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1, + 213,213,213,1,212,212,212,1,255,255,255,1,210,210,210,1,209,209,209,1, + 128,128,128,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1, + 228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1, + 223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1, + 218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1, + 212,212,212,1,255,255,255,1,210,210,210,1,209,209,209,1,128,128,128,1, + 255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1, + 227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1, + 222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1, + 217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1, + 255,255,255,1,210,210,210,1,209,209,209,1,128,128,128,1,255,255,255,1, + 128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1, + 226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1, + 221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1, + 215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,255,255,255,1, + 210,210,210,1,209,209,209,1,128,128,128,1,255,255,255,1,128,128,128,1, + 230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1, + 225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1, + 220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1, + 214,214,214,1,213,213,213,1,212,212,212,1,255,255,255,1,210,210,210,1, + 209,209,209,1,128,128,128,1,255,255,255,1,128,128,128,1,230,230,230,1, + 229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1, + 224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1, + 219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1, + 213,213,213,1,212,212,212,1,255,255,255,1,210,210,210,1,209,209,209,1, + 128,128,128,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1, + 228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1, + 223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1, + 218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1, + 212,212,212,1,128,128,128,4,255,255,255,1,128,128,128,1,230,230,230,1, + 229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1, + 224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1, + 219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1, + 213,213,213,1,212,212,212,1,255,255,255,1,210,210,210,1,250,250,250,1, + 211,211,211,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1, + 228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1, + 223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1, + 218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1, + 212,212,212,1,211,211,211,1,248,248,248,1,215,215,215,1,247,247,247,1, + 255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1, + 227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1, + 222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1, + 217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1, + 250,250,250,1,215,215,215,1,255,255,255,1,211,211,211,1,255,255,255,1, + 128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1, + 226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1, + 221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1, + 215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,214,214,214,1, + 254,254,254,1,210,210,210,1,255,255,255,2,128,128,128,1,230,230,230,1, + 229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1, + 224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1, + 219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1, + 213,213,213,1,212,212,212,1,255,255,255,5,128,128,128,1,230,230,230,1, + 229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1, + 224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1, + 219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1, + 213,213,213,1,212,212,212,1,255,255,255,1,210,210,210,1,209,209,209,1, + 128,128,128,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1, + 228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1, + 223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1, + 218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1, + 212,212,212,1,255,255,255,1,210,210,210,1,209,209,209,1,128,128,128,1, + 255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1, + 227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1, + 222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1, + 217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1, + 128,128,128,4,255,255,255,25,12,0,0,0,255,255,255,255,255,255,255,255, + 255,255,255,66,0,0) + ); + +const + objdata_tstepbox: record size: integer; data: array[0..2239] of byte end = + (size: 2240; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,8,116,115,116, + 101,112,98,111,120,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97, + 114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97, + 112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101, + 100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116, + 109,97,112,46,105,109,97,103,101,10,76,8,0,0,0,0,0,0,6,0, + 0,0,24,0,0,0,24,0,0,0,8,8,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,128,128,128,17,0,0,0,1,128,128,128,2,0,0, + 0,1,128,128,128,4,230,230,230,1,229,229,229,1,228,228,228,1,227,227, + 227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222, + 222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217, + 217,1,215,215,215,1,0,0,0,2,212,212,212,1,211,211,211,1,0,0, + 0,2,208,208,208,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229, + 229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224, + 224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219, + 219,1,218,218,218,1,217,217,217,1,0,0,0,3,212,212,212,1,211,211, + 211,1,0,0,0,3,255,255,255,1,128,128,128,1,230,230,230,1,229,229, + 229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224, + 224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219, + 219,1,218,218,218,1,0,0,0,4,212,212,212,1,211,211,211,1,0,0, + 0,4,128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227, + 227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222, + 222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217, + 217,1,0,0,0,3,212,212,212,1,211,211,211,1,0,0,0,3,255,255, + 255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227, + 227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222, + 222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217, + 217,1,215,215,215,1,0,0,0,2,212,212,212,1,211,211,211,1,0,0, + 0,2,208,208,208,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229, + 229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224, + 224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219, + 219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,0,0, + 0,1,212,212,212,1,211,211,211,1,0,0,0,1,209,209,209,1,208,208, + 208,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228, + 228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223, + 223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218, + 218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212, + 212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,255,255, + 255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227, + 227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222, + 222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217, + 217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211, + 211,1,210,210,210,1,209,209,209,1,208,208,208,1,255,255,255,1,128,128, + 128,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226, + 226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221, + 221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215, + 215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210, + 210,1,209,209,209,1,208,208,208,1,255,255,255,1,128,128,128,1,230,230, + 230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225, + 225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220, + 220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214, + 214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209, + 209,1,208,208,208,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229, + 229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224, + 224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219, + 219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213, + 213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208, + 208,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228, + 228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223, + 223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218, + 218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212, + 212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,255,255, + 255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227, + 227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222, + 222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217, + 217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211, + 211,1,210,210,210,1,209,209,209,1,208,208,208,1,255,255,255,1,128,128, + 128,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226, + 226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221, + 221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215, + 215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210, + 210,1,209,209,209,1,208,208,208,1,255,255,255,1,128,128,128,1,230,230, + 230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225, + 225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220, + 220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214, + 214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209, + 209,1,208,208,208,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229, + 229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224, + 224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219, + 219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213, + 213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208, + 208,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228, + 228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223, + 223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218, + 218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212, + 212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,255,255, + 255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227, + 227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222, + 222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217, + 217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211, + 211,1,210,210,210,1,209,209,209,1,208,208,208,1,255,255,255,1,128,128, + 128,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226, + 226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221, + 221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215, + 215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210, + 210,1,209,209,209,1,208,208,208,1,255,255,255,1,128,128,128,1,230,230, + 230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225, + 225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220, + 220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214, + 214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209, + 209,1,208,208,208,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229, + 229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224, + 224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219, + 219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213, + 213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208, + 208,1,255,255,255,1,128,128,128,1,230,230,230,1,229,229,229,1,228,228, + 228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223, + 223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218, + 218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212, + 212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,255,255, + 255,25,12,0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_ttabbar: record size: integer; data: array[0..690] of byte end = + (size: 691; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,7,116,116,97, + 98,98,97,114,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114, + 101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112, + 46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100, + 13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109, + 97,112,46,105,109,97,103,101,10,64,2,0,0,0,0,0,0,6,0,0, + 0,24,0,0,0,24,0,0,0,156,1,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,208,208,208,192,255,255,255,10,208,208,208,14,255,255,255, + 1,208,208,208,7,128,128,128,1,255,255,255,11,208,208,208,4,255,255,255, + 1,208,208,208,1,187,187,187,1,199,199,199,1,208,208,208,1,197,197,197, + 1,208,208,208,2,128,128,128,1,255,255,255,1,224,224,224,9,128,128,128, + 1,208,208,208,4,255,255,255,1,170,170,170,1,162,162,162,1,131,131,131, + 1,166,166,166,1,123,123,123,1,166,166,166,1,175,175,175,1,128,128,128, + 1,255,255,255,1,199,199,199,1,153,153,153,1,192,192,192,1,224,224,224, + 1,200,200,200,1,224,224,224,4,128,128,128,1,208,208,208,4,255,255,255, + 1,157,157,157,1,176,176,176,1,126,126,126,1,142,142,142,1,136,136,136, + 1,118,118,118,1,144,144,144,1,128,128,128,1,255,255,255,1,168,168,168, + 1,147,147,147,1,149,149,149,1,139,139,139,1,150,150,150,1,177,177,177, + 2,170,170,170,1,165,165,165,1,128,128,128,1,208,208,208,4,255,255,255, + 1,208,208,208,1,169,169,169,1,192,192,192,1,184,184,184,1,182,182,182, + 1,183,183,183,1,188,188,188,1,128,128,128,1,255,255,255,1,168,168,168, + 1,203,203,203,1,211,211,211,1,107,107,107,1,140,140,140,1,151,151,151, + 1,134,134,134,1,153,153,153,1,141,141,141,1,128,128,128,1,208,208,208, + 4,255,255,255,1,208,208,208,1,0,0,0,1,104,104,104,1,208,208,208, + 4,128,128,128,1,255,255,255,1,224,224,224,9,128,128,128,1,208,208,208, + 4,255,255,255,1,208,208,208,7,128,128,128,1,255,255,255,1,154,154,154, + 1,0,0,0,1,182,182,182,1,224,224,224,6,128,128,128,1,208,208,208, + 4,255,255,255,10,224,224,224,9,255,255,255,5,208,208,208,168,108,0,0, + 0,0,0,0,192,255,255,255,9,128,128,128,1,0,0,0,14,255,255,255, + 19,128,128,128,1,0,0,0,4,255,255,255,19,240,240,240,1,0,0,0, + 4,255,255,255,19,240,240,240,1,0,0,0,4,255,255,255,19,240,240,240, + 1,0,0,0,4,255,255,255,19,240,240,240,1,0,0,0,4,255,255,255, + 19,240,240,240,1,0,0,0,4,255,255,255,19,240,240,240,1,0,0,0, + 4,255,255,255,24,0,0,0,168,0,0) + ); + +const + objdata_ttabpage: record size: integer; data: array[0..2503] of byte end = + (size: 2504; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,8,116,116,97, + 98,112,97,103,101,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97, + 114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97, + 112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101, + 100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116, + 109,97,112,46,105,109,97,103,101,10,84,9,0,0,0,0,0,0,6,0, + 0,0,24,0,0,0,24,0,0,0,80,7,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,255,255,255,8,251,251,251,1,254,254,254,1,230,230, + 230,1,229,229,229,7,240,240,240,1,255,255,255,1,208,208,208,4,255,255, + 255,1,211,211,211,1,208,208,208,6,133,133,133,1,252,252,252,1,254,254, + 254,9,248,248,248,1,208,208,208,4,255,255,255,1,211,211,211,1,157,157, + 157,1,171,171,171,1,208,208,208,1,183,183,183,1,208,208,208,2,133,133, + 133,1,252,252,252,1,225,225,225,1,224,224,224,8,128,128,128,2,208,208, + 208,3,255,255,255,1,163,163,163,1,185,185,185,1,139,139,139,1,152,152, + 152,1,118,118,118,1,151,151,151,1,156,156,156,1,133,133,133,1,252,252, + 252,1,206,206,206,1,151,151,151,1,189,189,189,1,224,224,224,1,204,204, + 204,1,221,221,221,1,224,224,224,3,128,128,128,2,208,208,208,3,255,255, + 255,1,184,184,184,1,134,134,134,1,122,122,122,1,138,138,138,1,124,124, + 124,1,116,116,116,1,136,136,136,1,133,133,133,1,252,252,252,1,181,181, + 181,1,138,138,138,1,148,148,148,1,143,143,143,1,150,150,150,1,171,171, + 171,1,177,177,177,1,172,172,172,1,162,162,162,1,128,128,128,2,208,208, + 208,3,255,255,255,1,211,211,211,1,201,201,201,1,205,205,205,1,208,208, + 208,4,133,133,133,1,252,252,252,1,181,181,181,1,191,191,191,1,216,216, + 216,1,105,105,105,1,146,146,146,1,148,148,148,1,132,132,132,1,155,155, + 155,1,138,138,138,1,128,128,128,2,208,208,208,3,255,255,255,1,211,211, + 211,1,19,19,19,1,95,95,95,1,208,208,208,4,133,133,133,1,252,252, + 252,1,223,223,223,1,217,217,217,1,222,222,222,1,224,224,224,6,128,128, + 128,2,208,208,208,3,255,255,255,1,214,214,214,1,211,211,211,6,143,143, + 143,1,252,252,252,1,174,174,174,1,6,6,6,1,170,170,170,1,224,224, + 224,6,132,132,132,1,193,193,193,1,255,255,255,13,228,228,228,1,224,224, + 224,8,253,253,253,1,255,255,255,4,18,18,18,1,0,0,0,2,76,76, + 76,1,228,228,228,1,227,227,227,1,75,75,75,1,0,0,0,2,74,74, + 74,1,221,221,221,1,220,220,220,1,73,73,73,1,0,0,0,2,72,72, + 72,1,215,215,215,1,214,214,214,1,71,71,71,1,0,0,0,2,70,70, + 70,1,209,209,209,1,208,208,208,1,0,0,0,1,231,231,231,1,230,230, + 230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225, + 225,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219, + 219,1,218,218,218,1,217,217,217,1,216,216,216,1,215,215,215,1,214,214, + 214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209, + 209,1,69,69,69,1,77,77,77,1,231,231,231,1,230,230,230,1,229,229, + 229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,223,223, + 223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218, + 218,1,217,217,217,1,216,216,216,1,215,215,215,1,214,214,214,1,213,213, + 213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,0,0, + 0,1,232,232,232,1,231,231,231,1,230,230,230,1,229,229,229,1,228,228, + 228,1,227,227,227,1,226,226,226,1,225,225,225,1,223,223,223,1,222,222, + 222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217, + 217,1,216,216,216,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212, + 212,1,211,211,211,1,210,210,210,1,209,209,209,1,0,0,0,1,232,232, + 232,1,231,231,231,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227, + 227,1,226,226,226,1,225,225,225,1,223,223,223,1,222,222,222,1,221,221, + 221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,216,216, + 216,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211, + 211,1,210,210,210,1,209,209,209,1,69,69,69,1,77,77,77,1,231,231, + 231,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226, + 226,1,225,225,225,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220, + 220,1,219,219,219,1,218,218,218,1,217,217,217,1,216,216,216,1,215,215, + 215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210, + 210,1,209,209,209,1,208,208,208,1,0,0,0,1,231,231,231,1,230,230, + 230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225, + 225,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219, + 219,1,218,218,218,1,217,217,217,1,216,216,216,1,215,215,215,1,214,214, + 214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209, + 209,1,208,208,208,1,0,0,0,1,231,231,231,1,230,230,230,1,229,229, + 229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,223,223, + 223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218, + 218,1,217,217,217,1,216,216,216,1,215,215,215,1,214,214,214,1,213,213, + 213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,69,69, + 69,1,77,77,77,1,231,231,231,1,230,230,230,1,229,229,229,1,228,228, + 228,1,227,227,227,1,226,226,226,1,225,225,225,1,223,223,223,1,222,222, + 222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217, + 217,1,216,216,216,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212, + 212,1,211,211,211,1,210,210,210,1,209,209,209,1,0,0,0,1,232,232, + 232,1,231,231,231,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227, + 227,1,226,226,226,1,225,225,225,1,223,223,223,1,222,222,222,1,221,221, + 221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,216,216, + 216,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211, + 211,1,210,210,210,1,209,209,209,1,0,0,0,1,232,232,232,1,231,231, + 231,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226, + 226,1,225,225,225,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220, + 220,1,219,219,219,1,218,218,218,1,217,217,217,1,216,216,216,1,215,215, + 215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210, + 210,1,209,209,209,1,69,69,69,1,77,77,77,1,231,231,231,1,230,230, + 230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225, + 225,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219, + 219,1,218,218,218,1,217,217,217,1,216,216,216,1,215,215,215,1,214,214, + 214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209, + 209,1,208,208,208,1,0,0,0,1,231,231,231,1,230,230,230,1,229,229, + 229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,223,223, + 223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218, + 218,1,217,217,217,1,216,216,216,1,215,215,215,1,214,214,214,1,213,213, + 213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208, + 208,1,0,0,0,1,231,231,231,1,230,230,230,1,229,229,229,1,228,228, + 228,1,227,227,227,1,226,226,226,1,225,225,225,1,223,223,223,1,222,222, + 222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217, + 217,1,216,216,216,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212, + 212,1,211,211,211,1,210,210,210,1,209,209,209,1,69,69,69,1,46,46, + 46,1,231,231,231,1,230,230,230,1,76,76,76,1,0,0,0,2,75,75, + 75,1,225,225,225,1,223,223,223,1,74,74,74,1,0,0,0,2,73,73, + 73,1,218,218,218,1,217,217,217,1,72,72,72,1,0,0,0,2,71,71, + 71,1,212,212,212,1,211,211,211,1,70,70,70,1,0,0,0,2,204,1, + 0,0,240,240,240,1,248,248,248,8,146,146,146,1,23,23,23,8,16,16, + 16,1,4,4,4,1,0,0,0,4,240,240,240,1,241,241,241,1,255,255, + 255,17,149,149,149,1,0,0,0,4,240,240,240,1,241,241,241,1,255,255, + 255,17,233,233,233,1,8,8,8,1,0,0,0,3,240,240,240,1,244,244, + 244,1,255,255,255,17,233,233,233,1,8,8,8,1,0,0,0,3,240,240, + 240,1,243,243,243,1,255,255,255,17,233,233,233,1,8,8,8,1,0,0, + 0,3,240,240,240,1,241,241,241,1,255,255,255,17,233,233,233,1,8,8, + 8,1,0,0,0,3,240,240,240,1,241,241,241,1,255,255,255,17,233,233, + 233,1,8,8,8,1,0,0,0,3,234,234,234,1,235,235,235,1,248,248, + 248,6,254,254,254,1,255,255,255,10,234,234,234,1,16,16,16,1,8,8, + 8,3,253,253,253,1,255,255,255,9,234,234,234,1,248,248,248,8,236,236, + 236,1,248,248,248,4,208,208,208,1,255,255,255,2,192,192,192,1,128,128, + 128,2,192,192,192,1,255,255,255,2,192,192,192,1,128,128,128,2,192,192, + 192,1,255,255,255,2,192,192,192,1,128,128,128,2,192,192,192,1,255,255, + 255,2,192,192,192,1,128,128,128,1,64,64,64,1,255,255,255,23,192,192, + 192,2,255,255,255,23,128,128,128,1,255,255,255,23,128,128,128,1,255,255, + 255,22,192,192,192,2,255,255,255,22,128,128,128,1,255,255,255,23,128,128, + 128,1,255,255,255,23,192,192,192,2,255,255,255,23,128,128,128,1,255,255, + 255,23,128,128,128,1,255,255,255,22,192,192,192,2,255,255,255,22,128,128, + 128,1,255,255,255,23,128,128,128,1,255,255,255,23,192,192,192,1,160,160, + 160,1,128,128,128,2,192,192,192,1,255,255,255,2,192,192,192,1,128,128, + 128,2,192,192,192,1,255,255,255,2,192,192,192,1,128,128,128,2,192,192, + 192,1,255,255,255,2,192,192,192,1,128,128,128,2,192,192,192,1,255,255, + 255,2,0,0) + ); + +const + objdata_ttabwidget: record size: integer; data: array[0..2217] of byte end = + (size: 2218; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,116,97, + 98,119,105,100,103,101,116,23,98,105,116,109,97,112,46,116,114,97,110,115, + 112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116, + 109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115, + 107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98, + 105,116,109,97,112,46,105,109,97,103,101,10,52,8,0,0,0,0,0,0, + 6,0,0,0,24,0,0,0,24,0,0,0,20,7,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,255,255,255,8,251,251,251,1,254,254,254,1, + 230,230,230,1,229,229,229,7,240,240,240,1,255,255,255,1,208,208,208,4, + 255,255,255,1,211,211,211,1,208,208,208,6,133,133,133,1,252,252,252,1, + 254,254,254,9,248,248,248,1,208,208,208,4,255,255,255,1,211,211,211,1, + 157,157,157,1,171,171,171,1,208,208,208,1,183,183,183,1,208,208,208,2, + 133,133,133,1,252,252,252,1,225,225,225,1,224,224,224,8,128,128,128,2, + 208,208,208,3,255,255,255,1,163,163,163,1,185,185,185,1,139,139,139,1, + 152,152,152,1,118,118,118,1,151,151,151,1,156,156,156,1,133,133,133,1, + 252,252,252,1,206,206,206,1,151,151,151,1,189,189,189,1,224,224,224,1, + 204,204,204,1,221,221,221,1,224,224,224,3,128,128,128,2,208,208,208,3, + 255,255,255,1,184,184,184,1,134,134,134,1,122,122,122,1,138,138,138,1, + 124,124,124,1,116,116,116,1,136,136,136,1,133,133,133,1,252,252,252,1, + 181,181,181,1,138,138,138,1,148,148,148,1,143,143,143,1,150,150,150,1, + 171,171,171,1,177,177,177,1,172,172,172,1,162,162,162,1,128,128,128,2, + 208,208,208,3,255,255,255,1,211,211,211,1,201,201,201,1,205,205,205,1, + 208,208,208,4,133,133,133,1,252,252,252,1,181,181,181,1,191,191,191,1, + 216,216,216,1,105,105,105,1,146,146,146,1,148,148,148,1,132,132,132,1, + 155,155,155,1,138,138,138,1,128,128,128,2,208,208,208,3,255,255,255,1, + 211,211,211,1,19,19,19,1,95,95,95,1,208,208,208,4,133,133,133,1, + 252,252,252,1,223,223,223,1,217,217,217,1,222,222,222,1,224,224,224,6, + 128,128,128,2,208,208,208,3,255,255,255,1,214,214,214,1,211,211,211,6, + 143,143,143,1,252,252,252,1,174,174,174,1,6,6,6,1,170,170,170,1, + 224,224,224,6,132,132,132,1,193,193,193,1,255,255,255,13,228,228,228,1, + 224,224,224,8,253,253,253,1,255,255,255,5,230,230,230,1,229,229,229,1, + 228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1, + 223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1, + 218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1, + 212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1, + 128,128,128,1,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1, + 227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1, + 222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1, + 217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1, + 211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1, + 255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1, + 226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1, + 221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1, + 215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1, + 210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1,255,255,255,1, + 230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1, + 225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1, + 220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1, + 214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1, + 209,209,209,1,208,208,208,1,128,128,128,1,255,255,255,1,230,230,230,1, + 229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1, + 224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1, + 219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1, + 213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1, + 208,208,208,1,128,128,128,1,255,255,255,1,230,230,230,1,229,229,229,1, + 228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1, + 223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1, + 218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1, + 212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1, + 128,128,128,1,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1, + 227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1, + 222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1, + 217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1, + 211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1, + 255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1, + 226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1, + 221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1, + 215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1, + 210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1,255,255,255,1, + 230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1, + 225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1, + 220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1, + 214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1, + 209,209,209,1,208,208,208,1,128,128,128,1,255,255,255,1,230,230,230,1, + 229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1, + 224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1, + 219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1, + 213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1, + 208,208,208,1,128,128,128,1,255,255,255,1,230,230,230,1,229,229,229,1, + 228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1, + 223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1, + 218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1, + 212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1, + 128,128,128,1,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1, + 227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1, + 222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1, + 217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1, + 211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1, + 255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1, + 226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1, + 221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1, + 215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1, + 210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1,255,255,255,1, + 230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1, + 225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1, + 220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1, + 214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1, + 209,209,209,1,208,208,208,1,128,128,128,1,255,255,255,1,128,128,128,23, + 232,0,0,0,240,240,240,1,248,248,248,8,146,146,146,1,23,23,23,8, + 16,16,16,1,4,4,4,1,0,0,0,4,240,240,240,1,241,241,241,1, + 255,255,255,17,149,149,149,1,0,0,0,4,240,240,240,1,241,241,241,1, + 255,255,255,17,233,233,233,1,8,8,8,1,0,0,0,3,240,240,240,1, + 244,244,244,1,255,255,255,17,233,233,233,1,8,8,8,1,0,0,0,3, + 240,240,240,1,243,243,243,1,255,255,255,17,233,233,233,1,8,8,8,1, + 0,0,0,3,240,240,240,1,241,241,241,1,255,255,255,17,233,233,233,1, + 8,8,8,1,0,0,0,3,240,240,240,1,241,241,241,1,255,255,255,17, + 233,233,233,1,8,8,8,1,0,0,0,3,234,234,234,1,235,235,235,1, + 248,248,248,6,254,254,254,1,255,255,255,10,234,234,234,1,16,16,16,1, + 8,8,8,3,253,253,253,1,255,255,255,9,234,234,234,1,248,248,248,8, + 236,236,236,1,248,248,248,4,255,255,255,255,255,255,255,105,0,0) + ); + +const + objdata_tterminal: record size: integer; data: array[0..928] of byte end = + (size: 929; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,116,101, + 114,109,105,110,97,108,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,44,3,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,224,2,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,128,128,128,25,0,0,0,22,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,20,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,8,240,240,240,1,255,255,255,11,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,8,144, + 144,144,1,38,38,38,1,136,136,136,1,231,231,231,1,255,255,255,8,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,1,253, + 253,253,1,247,247,247,1,255,255,255,4,254,254,254,2,188,188,188,1,92, + 92,92,1,14,14,14,1,78,78,78,1,176,176,176,1,251,251,251,1,255, + 255,255,5,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,141, + 141,141,1,32,32,32,1,2,2,2,1,59,59,59,1,147,147,147,1,184, + 184,184,1,96,96,96,1,208,208,208,1,255,255,255,3,241,241,241,1,155, + 155,155,1,53,53,53,1,24,24,24,1,208,208,208,1,255,255,255,4,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,105,105,105,1,204, + 204,204,1,189,189,189,1,121,121,121,1,38,38,38,1,22,22,22,1,92, + 92,92,1,241,241,241,1,255,255,255,3,207,207,207,1,109,109,109,1,20, + 20,20,1,66,66,66,1,221,221,221,1,255,255,255,4,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,8,239,239,239,1,147, + 147,147,1,49,49,49,1,26,26,26,1,122,122,122,1,221,221,221,1,255, + 255,255,2,0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,8,145, + 145,145,1,78,78,78,1,178,178,178,1,252,252,252,1,255,255,255,5,0, + 0,0,1,255,255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,17,0,0,0,1,255,255,255,2,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,255,255,255,17,0,0,0,1,255, + 255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,17,0,0,0,1,255,255,255,2,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,255,255,255,17,0,0,0,1,255,255,255,2,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255,255,255,17,0, + 0,0,1,255,255,255,2,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,255,255,255,16,0,0,0,1,255,255,255,1,0,0,0,1,255, + 255,255,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,255, + 255,255,20,224,224,224,1,255,255,255,1,128,128,128,1,224,224,224,22,255, + 255,255,25,20,0,0,0,255,255,255,255,255,255,255,255,255,255,255,42,128, + 128,128,1,255,255,255,23,0,0) + ); + +const + objdata_tmseformwidget: record size: integer; data: array[0..2145] of byte end = + (size: 2146; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,109,115, + 101,102,111,114,109,119,105,100,103,101,116,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,232,7,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,164,7,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,25,242,166,149,1, + 221,216,211,1,242,166,149,1,255,134,109,2,121,64,52,1,157,83,67,1, + 187,98,80,1,208,109,89,2,247,130,106,1,212,111,91,1,255,134,109,4, + 160,160,160,6,128,128,128,1,255,255,255,1,221,216,211,1,7,239,255,1, + 221,216,211,1,255,134,109,2,120,63,51,1,201,106,86,1,181,95,77,1, + 135,71,58,1,214,112,91,1,139,73,59,1,163,86,70,1,242,127,103,1, + 255,134,109,3,160,160,160,1,212,212,212,1,128,128,128,1,160,160,160,1, + 209,209,209,1,128,128,128,2,255,255,255,1,242,166,149,1,221,216,211,1, + 242,166,149,1,255,134,109,2,212,111,91,1,255,134,109,1,218,115,93,1, + 204,107,87,1,180,95,77,1,222,117,95,1,184,97,79,1,253,133,108,1, + 255,134,109,3,160,160,160,1,212,212,212,1,128,128,128,1,160,160,160,1, + 209,209,209,1,128,128,128,2,255,255,255,1,151,24,0,16,128,128,128,7, + 255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1, + 226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1, + 221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1, + 215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1, + 210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1,255,255,255,1, + 230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1, + 225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1, + 220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1, + 214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1, + 209,209,209,1,208,208,208,1,128,128,128,1,255,255,255,1,230,230,230,1, + 229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1, + 224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1, + 219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1, + 213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1, + 208,208,208,1,128,128,128,1,255,255,255,1,230,230,230,1,229,229,229,1, + 228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1, + 223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1, + 218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1, + 212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1, + 128,128,128,1,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1, + 227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1, + 222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1, + 217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1, + 211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1, + 255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1, + 226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1, + 221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1, + 215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1, + 210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1,255,255,255,1, + 230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1, + 225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1, + 220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1, + 214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1, + 209,209,209,1,208,208,208,1,128,128,128,1,255,255,255,1,230,230,230,1, + 229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1, + 224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1, + 219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1, + 213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1, + 208,208,208,1,128,128,128,1,255,255,255,1,230,230,230,1,229,229,229,1, + 228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1, + 223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1, + 218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1, + 212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1, + 128,128,128,1,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1, + 227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1, + 222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1, + 217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1, + 211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1, + 255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1, + 226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1, + 221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1, + 215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1, + 210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1,255,255,255,1, + 230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1, + 225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1, + 220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1, + 214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1, + 209,209,209,1,208,208,208,1,128,128,128,1,255,255,255,1,230,230,230,1, + 229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1, + 224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1, + 219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1, + 213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1, + 208,208,208,1,128,128,128,1,255,255,255,1,230,230,230,1,229,229,229,1, + 228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1, + 223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1, + 218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1, + 212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1, + 128,128,128,1,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1, + 227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1, + 222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1, + 217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1, + 211,211,211,1,210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1, + 255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1, + 226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1, + 221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1, + 215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1, + 210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1,255,255,255,1, + 230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1, + 225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1, + 220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1, + 214,214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1, + 209,209,209,1,208,208,208,1,128,128,128,1,255,255,255,1,230,230,230,1, + 229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1, + 224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1, + 219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1, + 213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1, + 208,208,208,1,128,128,128,25,12,0,0,0,255,255,255,255,255,255,255,255, + 255,255,255,66,0,0) + ); + +const + objdata_tdockformwidget: record size: integer; data: array[0..2082] of byte end = + (size: 2083; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,100,111, + 99,107,102,111,114,109,119,105,100,103,101,116,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,168,7,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,100,7,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,25,242,166,149, + 1,221,216,211,1,242,166,149,1,255,134,109,2,121,64,52,1,157,83,67, + 1,187,98,80,1,208,109,89,2,247,130,106,1,212,111,91,1,255,134,109, + 4,160,160,160,6,128,128,128,1,255,255,255,1,221,216,211,1,7,239,255, + 1,221,216,211,1,255,134,109,2,120,63,51,1,201,106,86,1,181,95,77, + 1,135,71,58,1,214,112,91,1,139,73,59,1,163,86,70,1,242,127,103, + 1,255,134,109,3,160,160,160,1,212,212,212,1,128,128,128,1,160,160,160, + 1,209,209,209,1,128,128,128,2,255,255,255,1,242,166,149,1,221,216,211, + 1,242,166,149,1,255,134,109,2,212,111,91,1,255,134,109,1,218,115,93, + 1,204,107,87,1,180,95,77,1,222,117,95,1,184,97,79,1,253,133,108, + 1,255,134,109,3,160,160,160,1,212,212,212,1,128,128,128,1,160,160,160, + 1,209,209,209,1,128,128,128,2,255,255,255,1,151,24,0,16,128,128,128, + 7,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227, + 1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222, + 1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217, + 1,215,215,215,1,214,214,214,1,213,213,213,1,212,212,212,1,211,211,211, + 1,210,210,210,1,209,209,209,1,208,208,208,1,128,128,128,1,255,255,255, + 1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226, + 1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221, + 1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215, + 1,214,214,214,1,213,213,213,1,215,215,215,1,252,252,252,1,128,128,128, + 1,252,252,252,1,128,128,128,2,255,255,255,1,230,230,230,1,229,229,229, + 1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224, + 1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219, + 1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213, + 1,215,215,215,1,252,252,252,1,128,128,128,1,252,252,252,1,128,128,128, + 2,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227, + 1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222, + 1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217, + 1,215,215,215,1,214,214,214,1,213,213,213,1,215,215,215,1,252,252,252, + 1,128,128,128,1,253,253,253,1,128,128,128,2,255,255,255,1,230,230,230, + 1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225, + 1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220, + 1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214, + 1,213,213,213,1,215,215,215,1,252,252,252,1,128,128,128,1,253,253,253, + 1,128,128,128,2,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228, + 1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223, + 1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218, + 1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,215,215,215, + 1,252,252,252,1,128,128,128,1,253,253,253,1,128,128,128,2,255,255,255, + 1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226, + 1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221, + 1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215, + 1,214,214,214,1,213,213,213,1,215,215,215,1,252,252,252,1,128,128,128, + 1,253,253,253,1,128,128,128,2,255,255,255,1,230,230,230,1,229,229,229, + 1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224, + 1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219, + 1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213, + 1,215,215,215,1,252,252,252,1,128,128,128,1,253,253,253,1,128,128,128, + 2,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227, + 1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222, + 1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217, + 1,215,215,215,1,214,214,214,1,213,213,213,1,215,215,215,1,252,252,252, + 1,128,128,128,1,254,254,254,1,128,128,128,2,255,255,255,1,230,230,230, + 1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225, + 1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220, + 1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214, + 1,213,213,213,1,215,215,215,1,252,252,252,1,128,128,128,1,254,254,254, + 1,128,128,128,2,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228, + 1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223, + 1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218, + 1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,215,215,215, + 1,252,252,252,1,128,128,128,1,254,254,254,1,128,128,128,2,255,255,255, + 1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226, + 1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221, + 1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215, + 1,214,214,214,1,213,213,213,1,215,215,215,1,252,252,252,1,128,128,128, + 1,254,254,254,1,128,128,128,2,255,255,255,1,230,230,230,1,229,229,229, + 1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224, + 1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219, + 1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213, + 1,215,215,215,1,252,252,252,1,128,128,128,1,254,254,254,1,128,128,128, + 2,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227, + 1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222, + 1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217, + 1,215,215,215,1,214,214,214,1,213,213,213,1,215,215,215,1,252,252,252, + 1,128,128,128,1,254,254,254,1,128,128,128,2,255,255,255,1,230,230,230, + 1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225, + 1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220, + 1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214, + 1,213,213,213,1,215,215,215,1,252,252,252,1,128,128,128,1,255,255,255, + 1,128,128,128,2,255,255,255,1,230,230,230,1,229,229,229,1,228,228,228, + 1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224,1,223,223,223, + 1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218, + 1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213,1,215,215,215, + 1,252,252,252,1,128,128,128,1,255,255,255,1,128,128,128,2,255,255,255, + 1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226, + 1,225,225,225,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221, + 1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,215,215,215, + 1,214,214,214,1,213,213,213,1,215,215,215,1,252,252,252,1,128,128,128, + 1,255,255,255,1,128,128,128,2,255,255,255,1,230,230,230,1,229,229,229, + 1,228,228,228,1,227,227,227,1,226,226,226,1,225,225,225,1,224,224,224, + 1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219, + 1,218,218,218,1,217,217,217,1,215,215,215,1,214,214,214,1,213,213,213, + 1,215,215,215,1,252,252,252,1,210,210,210,1,209,209,209,1,208,208,208, + 1,128,128,128,25,12,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 66,0,0) + ); + +const + objdata_tpaintbox: record size: integer; data: array[0..1664] of byte end = + (size: 1665; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,112,97, + 105,110,116,98,111,120,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,12,6,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,112,3,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,128,128,128,25,208,208,208,17,0,255,255,1,208, + 208,208,4,255,255,255,1,128,128,128,1,208,208,208,16,49,167,255,1,97, + 188,255,1,147,210,255,1,208,208,208,3,255,255,255,1,128,128,128,1,208, + 208,208,16,51,168,255,1,170,219,255,1,88,184,255,1,0,146,255,1,208, + 208,208,2,255,255,255,1,128,128,128,1,208,208,208,15,52,168,255,1,112, + 194,255,1,136,205,255,1,29,158,255,1,0,145,255,1,208,208,208,2,255, + 255,255,1,128,128,128,1,208,208,208,14,57,170,255,1,53,168,255,1,185, + 226,255,1,77,179,255,1,0,146,255,1,0,128,255,1,208,208,208,2,255, + 255,255,1,128,128,128,1,208,208,208,14,51,168,255,1,126,200,255,1,125, + 200,255,1,17,153,255,1,0,147,255,1,208,208,208,3,255,255,255,1,128, + 128,128,1,208,208,208,13,55,164,255,1,67,175,255,1,173,220,255,1,65, + 174,255,1,0,146,255,1,208,208,208,4,255,255,255,1,128,128,128,1,208, + 208,208,13,51,168,255,1,140,206,255,1,113,195,255,1,5,148,255,1,0, + 143,255,1,208,208,208,4,255,255,255,1,128,128,128,1,208,208,208,12,50, + 168,255,1,82,181,255,1,161,215,255,1,53,169,255,1,0,147,255,1,208, + 208,208,5,255,255,255,1,128,128,128,1,208,208,208,11,0,255,255,1,51, + 168,255,1,155,213,255,1,101,190,255,1,0,146,255,1,0,142,255,1,208, + 208,208,5,255,255,255,1,128,128,128,1,208,208,208,8,68,222,239,1,98, + 195,228,1,51,157,241,1,52,167,255,1,96,187,255,1,149,210,255,1,42, + 164,255,1,0,146,255,1,208,208,208,6,255,255,255,1,128,128,128,1,208, + 208,208,7,0,242,255,1,60,203,240,1,143,192,218,1,139,176,218,1,87, + 135,233,1,152,199,254,1,90,184,255,1,0,146,255,1,0,128,255,1,208, + 208,208,6,255,255,255,1,128,128,128,1,208,208,208,7,0,218,255,1,0, + 176,255,1,16,138,251,1,91,140,232,1,146,159,217,1,131,132,220,1,72, + 123,238,1,3,140,255,1,208,208,208,7,255,255,255,1,128,128,128,1,208, + 208,208,7,0,193,255,1,0,149,255,1,1,106,255,1,1,62,255,1,25, + 40,249,1,102,116,228,1,147,168,216,1,123,170,223,1,105,186,227,1,208, + 208,208,6,255,255,255,1,128,128,128,1,208,208,208,7,0,167,255,1,0, + 123,255,1,1,79,255,1,1,35,255,1,1,12,255,1,1,56,255,1,34, + 117,246,1,112,178,226,1,89,196,232,1,208,208,208,6,255,255,255,1,128, + 128,128,1,208,208,208,7,0,140,255,1,1,96,255,1,1,52,255,1,1, + 9,255,1,1,39,255,1,1,83,255,1,0,127,255,1,0,171,255,1,1, + 214,255,1,208,208,208,6,255,255,255,1,128,128,128,1,208,208,208,7,0, + 111,255,1,1,69,255,1,1,26,255,1,1,21,255,1,1,66,255,1,1, + 110,255,1,0,154,255,1,0,198,255,1,0,230,255,1,208,208,208,6,255, + 255,255,1,128,128,128,1,208,208,208,7,0,85,255,1,1,43,255,1,1, + 4,255,1,1,48,255,1,1,92,255,1,0,137,255,1,0,181,255,1,0, + 226,255,1,208,208,208,7,255,255,255,1,128,128,128,1,208,208,208,7,0, + 61,255,1,1,16,255,1,1,31,255,1,1,75,255,1,0,119,255,1,0, + 162,255,1,0,209,255,1,208,208,208,8,255,255,255,1,128,128,128,1,208, + 208,208,6,0,77,255,1,1,34,255,1,1,14,255,1,1,58,255,1,1, + 102,255,1,0,146,255,1,0,186,255,1,208,208,208,9,255,255,255,1,128, + 128,128,1,208,208,208,6,2,51,255,1,1,7,255,1,2,40,255,1,0, + 86,255,1,0,139,255,1,208,208,208,11,255,255,255,1,128,128,128,1,208, + 208,208,22,255,255,255,25,100,2,0,0,255,255,255,25,0,0,0,17,1, + 1,1,1,0,0,0,4,255,255,255,2,0,0,0,16,52,52,52,1,214, + 214,214,1,80,80,80,1,0,0,0,3,255,255,255,2,0,0,0,16,196, + 196,196,1,255,255,255,2,178,178,178,1,0,0,0,2,255,255,255,2,0, + 0,0,15,88,88,88,1,255,255,255,3,109,109,109,1,0,0,0,2,255, + 255,255,2,0,0,0,14,9,9,9,1,225,225,225,1,255,255,255,2,215, + 215,215,1,4,4,4,1,0,0,0,2,255,255,255,2,0,0,0,14,126, + 126,126,1,255,255,255,3,73,73,73,1,0,0,0,3,255,255,255,2,0, + 0,0,13,28,28,28,1,245,245,245,1,255,255,255,2,183,183,183,1,0, + 0,0,4,255,255,255,2,0,0,0,13,164,164,164,1,255,255,255,2,251, + 251,251,1,41,41,41,1,0,0,0,4,255,255,255,2,0,0,0,12,56, + 56,56,1,254,254,254,1,255,255,255,2,146,146,146,1,0,0,0,5,255, + 255,255,2,0,0,0,11,1,1,1,1,200,200,200,1,255,255,255,2,238, + 238,238,1,18,18,18,1,0,0,0,5,255,255,255,2,0,0,0,8,127, + 127,127,1,210,210,210,1,55,55,55,1,93,93,93,1,255,255,255,3,110, + 110,110,1,0,0,0,6,255,255,255,2,0,0,0,7,60,60,60,1,255, + 255,255,2,254,254,254,1,213,213,213,1,239,239,239,1,255,255,255,1,215, + 215,215,1,4,4,4,1,0,0,0,6,255,255,255,2,0,0,0,7,82, + 82,82,1,255,255,255,4,251,251,251,1,211,211,211,1,80,80,80,1,0, + 0,0,7,255,255,255,2,0,0,0,7,91,91,91,1,255,255,255,6,245, + 245,245,1,93,93,93,1,0,0,0,6,255,255,255,2,0,0,0,7,87, + 87,87,1,255,255,255,7,197,197,197,1,0,0,0,6,255,255,255,2,0, + 0,0,7,71,71,71,1,255,255,255,7,201,201,201,1,0,0,0,6,255, + 255,255,2,0,0,0,7,55,55,55,1,255,255,255,6,232,232,232,1,31, + 31,31,1,0,0,0,6,255,255,255,2,0,0,0,7,39,39,39,1,255, + 255,255,5,240,240,240,1,53,53,53,1,0,0,0,7,255,255,255,2,0, + 0,0,7,100,100,100,1,255,255,255,4,226,226,226,1,44,44,44,1,0, + 0,0,8,255,255,255,2,0,0,0,6,10,10,10,1,223,223,223,1,255, + 255,255,2,245,245,245,1,168,168,168,1,26,26,26,1,0,0,0,9,255, + 255,255,2,0,0,0,6,130,130,130,1,192,192,192,1,148,148,148,1,89, + 89,89,1,11,11,11,1,0,0,0,11,255,255,255,2,0,0,0,22,255, + 255,255,25,0,0) + ); + +const + objdata_texpandingwidget: record size: integer; data: array[0..1843] of byte end = + (size: 1844; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,16,116,101,120, + 112,97,110,100,105,110,103,119,105,100,103,101,116,23,98,105,116,109,97,112, + 46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0, + 0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98, + 109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109, + 97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,184,6, + 0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,140,4, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,1,7,7, + 7,1,18,18,18,1,223,223,223,2,139,139,139,1,7,7,7,2,58,58, + 58,1,223,223,223,2,80,80,80,1,7,7,7,2,106,106,106,1,223,223, + 223,2,39,39,39,1,7,7,7,2,177,177,177,1,223,223,223,2,255,255, + 255,1,7,7,7,1,223,223,223,1,210,210,210,19,223,223,223,1,7,7, + 7,1,255,255,255,1,26,26,26,1,210,210,210,1,0,0,0,19,210,210, + 210,1,7,7,7,1,0,0,0,1,223,223,223,1,210,210,210,1,0,0, + 0,1,197,197,197,1,210,210,210,7,105,105,105,1,210,210,210,7,197,197, + 197,1,0,0,0,1,210,210,210,1,24,24,24,1,0,0,0,1,223,223, + 223,1,210,210,210,1,0,0,0,1,210,210,210,1,224,224,224,6,168,168, + 168,1,0,0,0,1,168,168,168,1,224,224,224,6,210,210,210,1,0,0, + 0,1,210,210,210,1,144,144,144,1,0,0,0,1,131,131,131,1,210,210, + 210,1,0,0,0,1,210,210,210,1,224,224,224,6,55,55,55,1,0,0, + 0,1,55,55,55,1,224,224,224,6,210,210,210,1,0,0,0,1,210,210, + 210,1,144,144,144,1,0,0,0,1,7,7,7,1,210,210,210,1,0,0, + 0,1,210,210,210,1,224,224,224,5,168,168,168,1,0,0,0,3,168,168, + 168,1,224,224,224,5,210,210,210,1,0,0,0,1,210,210,210,1,100,100, + 100,1,0,0,0,1,7,7,7,1,210,210,210,1,0,0,0,1,210,210, + 210,1,224,224,224,5,55,55,55,1,0,0,0,3,55,55,55,1,224,224, + 224,5,210,210,210,1,0,0,0,1,210,210,210,1,7,7,7,1,0,0, + 0,1,64,64,64,1,210,210,210,1,0,0,0,1,210,210,210,1,224,224, + 224,15,210,210,210,1,0,0,0,1,210,210,210,1,7,7,7,1,0,0, + 0,1,223,223,223,1,210,210,210,1,0,0,0,1,210,210,210,1,224,224, + 224,2,168,168,168,1,55,55,55,1,224,224,224,7,55,55,55,1,168,168, + 168,1,224,224,224,2,210,210,210,1,0,0,0,1,210,210,210,1,55,55, + 55,1,0,0,0,1,223,223,223,1,210,210,210,1,0,0,0,1,210,210, + 210,1,168,168,168,1,55,55,55,1,0,0,0,2,224,224,224,7,0,0, + 0,2,55,55,55,1,168,168,168,1,210,210,210,1,0,0,0,1,210,210, + 210,1,144,144,144,1,0,0,0,1,75,75,75,1,210,210,210,1,0,0, + 0,1,105,105,105,1,0,0,0,4,224,224,224,7,0,0,0,4,105,105, + 105,1,0,0,0,1,210,210,210,1,144,144,144,1,0,0,0,1,7,7, + 7,1,210,210,210,1,0,0,0,1,210,210,210,1,168,168,168,1,55,55, + 55,1,0,0,0,2,224,224,224,7,0,0,0,2,55,55,55,1,168,168, + 168,1,210,210,210,1,0,0,0,1,210,210,210,1,63,63,63,1,0,0, + 0,1,7,7,7,1,210,210,210,1,0,0,0,1,210,210,210,1,224,224, + 224,2,168,168,168,1,55,55,55,1,224,224,224,7,55,55,55,1,168,168, + 168,1,224,224,224,2,210,210,210,1,0,0,0,1,210,210,210,1,7,7, + 7,1,0,0,0,1,115,115,115,1,210,210,210,1,0,0,0,1,210,210, + 210,1,224,224,224,15,210,210,210,1,0,0,0,1,210,210,210,1,7,7, + 7,1,0,0,0,1,223,223,223,1,210,210,210,1,0,0,0,1,210,210, + 210,1,224,224,224,5,55,55,55,1,0,0,0,3,55,55,55,1,224,224, + 224,5,210,210,210,1,0,0,0,1,210,210,210,1,90,90,90,1,0,0, + 0,1,223,223,223,1,210,210,210,1,0,0,0,1,210,210,210,1,224,224, + 224,5,168,168,168,1,0,0,0,3,168,168,168,1,224,224,224,5,210,210, + 210,1,0,0,0,1,210,210,210,1,144,144,144,1,0,0,0,1,35,35, + 35,1,210,210,210,1,0,0,0,1,210,210,210,1,224,224,224,6,55,55, + 55,1,0,0,0,1,55,55,55,1,224,224,224,6,210,210,210,1,0,0, + 0,1,210,210,210,1,144,144,144,1,0,0,0,1,7,7,7,1,210,210, + 210,1,0,0,0,1,210,210,210,1,224,224,224,6,168,168,168,1,0,0, + 0,1,168,168,168,1,224,224,224,6,210,210,210,1,0,0,0,1,210,210, + 210,1,32,32,32,1,0,0,0,1,7,7,7,1,210,210,210,1,0,0, + 0,1,197,197,197,1,210,210,210,7,105,105,105,1,210,210,210,7,197,197, + 197,1,0,0,0,1,210,210,210,1,7,7,7,1,0,0,0,1,187,187, + 187,1,210,210,210,1,0,0,0,19,210,210,210,1,7,7,7,1,0,0, + 0,1,223,223,223,2,210,210,210,19,223,223,223,1,128,128,128,1,0,0, + 0,1,180,180,180,1,7,7,7,2,27,27,27,1,144,144,144,2,94,94, + 94,1,7,7,7,2,59,59,59,1,144,144,144,2,59,59,59,1,7,7, + 7,2,94,94,94,1,144,144,144,2,27,27,27,1,7,7,7,2,133,133, + 133,1,85,85,85,1,0,0,0,1,255,255,255,1,0,0,0,23,244,1, + 0,0,244,244,244,1,248,248,248,1,236,236,236,1,128,128,128,2,158,158, + 158,1,248,248,248,2,203,203,203,1,128,128,128,2,188,188,188,1,248,248, + 248,2,173,173,173,1,128,128,128,2,218,218,218,1,248,248,248,2,143,143, + 143,1,128,128,128,1,64,64,64,1,0,0,0,1,248,248,248,1,255,255, + 255,21,248,248,248,1,0,0,0,1,229,229,229,1,255,255,255,21,248,248, + 248,1,16,16,16,1,128,128,128,1,255,255,255,21,241,241,241,1,106,106, + 106,1,128,128,128,1,255,255,255,21,198,198,198,1,122,122,122,1,161,161, + 161,1,255,255,255,21,198,198,198,1,122,122,122,1,248,248,248,1,255,255, + 255,21,213,213,213,1,122,122,122,1,248,248,248,1,255,255,255,21,252,252, + 252,1,122,122,122,1,199,199,199,1,255,255,255,21,252,252,252,1,122,122, + 122,1,128,128,128,1,255,255,255,21,230,230,230,1,122,122,122,1,128,128, + 128,1,255,255,255,21,198,198,198,1,122,122,122,1,191,191,191,1,255,255, + 255,21,198,198,198,1,122,122,122,1,248,248,248,1,255,255,255,21,226,226, + 226,1,122,122,122,1,248,248,248,1,255,255,255,21,252,252,252,1,122,122, + 122,1,169,169,169,1,255,255,255,21,252,252,252,1,122,122,122,1,128,128, + 128,1,255,255,255,21,216,216,216,1,122,122,122,1,128,128,128,1,255,255, + 255,21,198,198,198,1,122,122,122,1,221,221,221,1,255,255,255,21,198,198, + 198,1,122,122,122,1,248,248,248,1,255,255,255,21,240,240,240,1,122,122, + 122,1,248,248,248,1,255,255,255,21,252,252,252,1,122,122,122,1,139,139, + 139,1,255,255,255,21,252,252,252,1,122,122,122,1,128,128,128,1,255,255, + 255,21,203,203,203,1,122,122,122,1,75,75,75,1,248,248,248,1,251,251, + 251,1,241,241,241,1,198,198,198,2,214,214,214,1,252,252,252,2,228,228, + 228,1,198,198,198,2,228,228,228,1,252,252,252,2,214,214,214,1,198,198, + 198,2,241,241,241,1,252,252,252,2,201,201,201,1,169,169,169,1,122,122, + 122,1,0,0,0,1,16,16,16,1,106,106,106,1,122,122,122,20,106,106, + 106,1,0,0) + ); + +const + objdata_tspacer: record size: integer; data: array[0..1446] of byte end = + (size: 1447; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,7,116,115,112, + 97,99,101,114,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114, + 101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112, + 46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100, + 13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109, + 97,112,46,105,109,97,103,101,10,52,5,0,0,0,0,0,0,6,0,0, + 0,24,0,0,0,24,0,0,0,8,3,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,3,3,3,1,7,7,7,1,18,18,18,1,224,224,224, + 2,139,139,139,1,7,7,7,2,58,58,58,1,224,224,224,2,81,81,81, + 1,7,7,7,2,107,107,107,1,224,224,224,2,39,39,39,1,7,7,7, + 2,177,177,177,1,224,224,224,2,255,255,255,1,7,7,7,1,224,224,224, + 21,7,7,7,1,255,255,255,1,26,26,26,1,224,224,224,21,7,7,7, + 1,0,0,0,1,224,224,224,22,25,25,25,1,0,0,0,1,224,224,224, + 22,145,145,145,1,0,0,0,1,131,131,131,1,224,224,224,21,145,145,145, + 1,0,0,0,1,7,7,7,1,224,224,224,2,112,112,112,1,224,224,224, + 14,112,112,112,1,224,224,224,3,99,99,99,1,0,0,0,1,7,7,7, + 1,224,224,224,2,0,0,0,1,224,224,224,14,0,0,0,1,224,224,224, + 3,7,7,7,1,0,0,0,1,64,64,64,1,224,224,224,2,0,0,0, + 1,224,224,224,14,0,0,0,1,224,224,224,3,7,7,7,1,0,0,0, + 1,224,224,224,3,0,0,0,1,224,224,224,3,210,210,210,1,112,112,112, + 1,126,126,126,1,224,224,224,3,55,55,55,1,168,168,168,1,224,224,224, + 3,0,0,0,1,224,224,224,3,55,55,55,1,0,0,0,1,224,224,224, + 3,0,0,0,1,224,224,224,1,210,210,210,1,112,112,112,1,13,13,13, + 1,0,0,0,1,112,112,112,1,224,224,224,3,0,0,0,2,55,55,55, + 1,168,168,168,1,224,224,224,1,0,0,0,1,224,224,224,3,145,145,145, + 1,0,0,0,1,75,75,75,1,224,224,224,2,0,0,0,1,196,196,196, + 1,27,27,27,1,0,0,0,11,112,112,112,1,0,0,0,1,224,224,224, + 3,145,145,145,1,0,0,0,1,7,7,7,1,224,224,224,2,0,0,0, + 1,224,224,224,1,210,210,210,1,112,112,112,1,13,13,13,1,0,0,0, + 1,112,112,112,1,224,224,224,3,0,0,0,2,55,55,55,1,168,168,168, + 1,224,224,224,1,0,0,0,1,224,224,224,3,64,64,64,1,0,0,0, + 1,7,7,7,1,224,224,224,2,0,0,0,1,224,224,224,3,210,210,210, + 1,112,112,112,1,126,126,126,1,224,224,224,3,55,55,55,1,168,168,168, + 1,224,224,224,3,0,0,0,1,224,224,224,3,7,7,7,1,0,0,0, + 1,115,115,115,1,224,224,224,2,0,0,0,1,224,224,224,14,0,0,0, + 1,224,224,224,3,7,7,7,1,0,0,0,1,224,224,224,3,0,0,0, + 1,224,224,224,14,0,0,0,1,224,224,224,3,90,90,90,1,0,0,0, + 1,224,224,224,3,112,112,112,1,224,224,224,14,112,112,112,1,224,224,224, + 3,145,145,145,1,0,0,0,1,35,35,35,1,224,224,224,21,145,145,145, + 1,0,0,0,1,7,7,7,1,224,224,224,21,32,32,32,1,0,0,0, + 1,7,7,7,1,224,224,224,21,7,7,7,1,0,0,0,1,189,189,189, + 1,224,224,224,21,7,7,7,1,0,0,0,1,224,224,224,22,129,129,129, + 1,0,0,0,1,179,179,179,1,7,7,7,2,28,28,28,1,145,145,145, + 2,94,94,94,1,7,7,7,2,59,59,59,1,145,145,145,2,59,59,59, + 1,7,7,7,2,94,94,94,1,145,145,145,2,28,28,28,1,7,7,7, + 2,134,134,134,1,85,85,85,1,0,0,0,1,255,255,255,1,0,0,0, + 23,244,1,0,0,244,244,244,1,248,248,248,1,236,236,236,1,128,128,128, + 2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2,188,188,188, + 1,248,248,248,2,173,173,173,1,128,128,128,2,218,218,218,1,248,248,248, + 2,143,143,143,1,128,128,128,1,64,64,64,1,0,0,0,1,248,248,248, + 1,255,255,255,21,248,248,248,1,0,0,0,1,229,229,229,1,255,255,255, + 21,248,248,248,1,16,16,16,1,128,128,128,1,255,255,255,21,241,241,241, + 1,106,106,106,1,128,128,128,1,255,255,255,21,198,198,198,1,122,122,122, + 1,161,161,161,1,255,255,255,21,198,198,198,1,122,122,122,1,248,248,248, + 1,255,255,255,21,213,213,213,1,122,122,122,1,248,248,248,1,255,255,255, + 21,252,252,252,1,122,122,122,1,199,199,199,1,255,255,255,21,252,252,252, + 1,122,122,122,1,128,128,128,1,255,255,255,21,230,230,230,1,122,122,122, + 1,128,128,128,1,255,255,255,21,198,198,198,1,122,122,122,1,191,191,191, + 1,255,255,255,21,198,198,198,1,122,122,122,1,248,248,248,1,255,255,255, + 21,226,226,226,1,122,122,122,1,248,248,248,1,255,255,255,21,252,252,252, + 1,122,122,122,1,169,169,169,1,255,255,255,21,252,252,252,1,122,122,122, + 1,128,128,128,1,255,255,255,21,216,216,216,1,122,122,122,1,128,128,128, + 1,255,255,255,21,198,198,198,1,122,122,122,1,221,221,221,1,255,255,255, + 21,198,198,198,1,122,122,122,1,248,248,248,1,255,255,255,21,240,240,240, + 1,122,122,122,1,248,248,248,1,255,255,255,21,252,252,252,1,122,122,122, + 1,139,139,139,1,255,255,255,21,252,252,252,1,122,122,122,1,128,128,128, + 1,255,255,255,21,203,203,203,1,122,122,122,1,75,75,75,1,248,248,248, + 1,251,251,251,1,242,242,242,1,198,198,198,2,215,215,215,1,252,252,252, + 2,228,228,228,1,198,198,198,2,228,228,228,1,252,252,252,2,215,215,215, + 1,198,198,198,2,242,242,242,1,252,252,252,2,201,201,201,1,169,169,169, + 1,122,122,122,1,0,0,0,1,16,16,16,1,106,106,106,1,122,122,122, + 20,106,106,106,1,0,0) + ); + +const + objdata_tlayouter: record size: integer; data: array[0..1564] of byte end = + (size: 1565; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,108,97, + 121,111,117,116,101,114,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,168,5,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,124,3,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,3,3,3,1,7,7,7,1,18,18,18,1,224, + 224,224,2,139,139,139,1,7,7,7,2,58,58,58,1,224,224,224,2,81, + 81,81,1,7,7,7,2,107,107,107,1,224,224,224,2,39,39,39,1,7, + 7,7,2,177,177,177,1,224,224,224,2,255,255,255,1,7,7,7,1,224, + 224,224,10,196,196,196,1,224,224,224,10,7,7,7,1,255,255,255,1,26, + 26,26,1,224,224,224,9,210,210,210,1,27,27,27,1,210,210,210,1,224, + 224,224,9,7,7,7,1,0,0,0,1,224,224,224,10,112,112,112,1,0, + 0,0,1,112,112,112,1,224,224,224,9,25,25,25,1,0,0,0,1,224, + 224,224,9,210,210,210,1,13,13,13,1,0,0,0,1,13,13,13,1,210, + 210,210,1,224,224,224,8,145,145,145,1,0,0,0,1,131,131,131,1,224, + 224,224,8,112,112,112,1,0,0,0,3,112,112,112,1,224,224,224,8,145, + 145,145,1,0,0,0,1,7,7,7,1,224,224,224,8,126,126,126,1,112, + 112,112,1,0,0,0,1,112,112,112,1,126,126,126,1,224,224,224,8,99, + 99,99,1,0,0,0,1,7,7,7,1,224,224,224,10,0,0,0,1,224, + 224,224,10,7,7,7,1,0,0,0,1,64,64,64,1,224,224,224,10,0, + 0,0,1,224,224,224,10,7,7,7,1,0,0,0,1,224,224,224,4,210, + 210,210,1,112,112,112,1,126,126,126,1,224,224,224,4,0,0,0,1,224, + 224,224,4,126,126,126,1,112,112,112,1,210,210,210,1,224,224,224,3,55, + 55,55,1,0,0,0,1,224,224,224,2,210,210,210,1,112,112,112,1,13, + 13,13,1,0,0,0,1,112,112,112,1,224,224,224,9,112,112,112,1,0, + 0,0,1,13,13,13,1,112,112,112,1,210,210,210,1,224,224,224,1,145, + 145,145,1,0,0,0,1,75,75,75,1,196,196,196,1,27,27,27,1,0, + 0,0,7,224,224,224,3,0,0,0,7,27,27,27,1,196,196,196,1,145, + 145,145,1,0,0,0,1,7,7,7,1,224,224,224,1,210,210,210,1,112, + 112,112,1,13,13,13,1,0,0,0,1,112,112,112,1,224,224,224,9,112, + 112,112,1,0,0,0,1,13,13,13,1,112,112,112,1,210,210,210,1,224, + 224,224,1,64,64,64,1,0,0,0,1,7,7,7,1,224,224,224,3,210, + 210,210,1,112,112,112,1,126,126,126,1,224,224,224,4,0,0,0,1,224, + 224,224,4,126,126,126,1,112,112,112,1,210,210,210,1,224,224,224,3,7, + 7,7,1,0,0,0,1,115,115,115,1,224,224,224,10,0,0,0,1,224, + 224,224,10,7,7,7,1,0,0,0,1,224,224,224,11,0,0,0,1,224, + 224,224,10,90,90,90,1,0,0,0,1,224,224,224,9,126,126,126,1,112, + 112,112,1,0,0,0,1,112,112,112,1,126,126,126,1,224,224,224,8,145, + 145,145,1,0,0,0,1,35,35,35,1,224,224,224,8,112,112,112,1,0, + 0,0,3,112,112,112,1,224,224,224,8,145,145,145,1,0,0,0,1,7, + 7,7,1,224,224,224,8,210,210,210,1,13,13,13,1,0,0,0,1,13, + 13,13,1,210,210,210,1,224,224,224,8,32,32,32,1,0,0,0,1,7, + 7,7,1,224,224,224,9,112,112,112,1,0,0,0,1,112,112,112,1,224, + 224,224,9,7,7,7,1,0,0,0,1,189,189,189,1,224,224,224,9,210, + 210,210,1,27,27,27,1,210,210,210,1,224,224,224,9,7,7,7,1,0, + 0,0,1,224,224,224,11,196,196,196,1,224,224,224,10,129,129,129,1,0, + 0,0,1,179,179,179,1,7,7,7,2,28,28,28,1,145,145,145,2,94, + 94,94,1,7,7,7,2,59,59,59,1,145,145,145,2,59,59,59,1,7, + 7,7,2,94,94,94,1,145,145,145,2,28,28,28,1,7,7,7,2,134, + 134,134,1,85,85,85,1,0,0,0,1,255,255,255,1,0,0,0,23,244, + 1,0,0,244,244,244,1,248,248,248,1,236,236,236,1,128,128,128,2,158, + 158,158,1,248,248,248,2,203,203,203,1,128,128,128,2,188,188,188,1,248, + 248,248,2,173,173,173,1,128,128,128,2,218,218,218,1,248,248,248,2,143, + 143,143,1,128,128,128,1,64,64,64,1,0,0,0,1,248,248,248,1,255, + 255,255,21,248,248,248,1,0,0,0,1,229,229,229,1,255,255,255,21,248, + 248,248,1,16,16,16,1,128,128,128,1,255,255,255,21,241,241,241,1,106, + 106,106,1,128,128,128,1,255,255,255,21,198,198,198,1,122,122,122,1,161, + 161,161,1,255,255,255,21,198,198,198,1,122,122,122,1,248,248,248,1,255, + 255,255,21,213,213,213,1,122,122,122,1,248,248,248,1,255,255,255,21,252, + 252,252,1,122,122,122,1,199,199,199,1,255,255,255,21,252,252,252,1,122, + 122,122,1,128,128,128,1,255,255,255,21,230,230,230,1,122,122,122,1,128, + 128,128,1,255,255,255,21,198,198,198,1,122,122,122,1,191,191,191,1,255, + 255,255,21,198,198,198,1,122,122,122,1,248,248,248,1,255,255,255,21,226, + 226,226,1,122,122,122,1,248,248,248,1,255,255,255,21,252,252,252,1,122, + 122,122,1,169,169,169,1,255,255,255,21,252,252,252,1,122,122,122,1,128, + 128,128,1,255,255,255,21,216,216,216,1,122,122,122,1,128,128,128,1,255, + 255,255,21,198,198,198,1,122,122,122,1,221,221,221,1,255,255,255,21,198, + 198,198,1,122,122,122,1,248,248,248,1,255,255,255,21,240,240,240,1,122, + 122,122,1,248,248,248,1,255,255,255,21,252,252,252,1,122,122,122,1,139, + 139,139,1,255,255,255,21,252,252,252,1,122,122,122,1,128,128,128,1,255, + 255,255,21,203,203,203,1,122,122,122,1,75,75,75,1,248,248,248,1,251, + 251,251,1,242,242,242,1,198,198,198,2,215,215,215,1,252,252,252,2,228, + 228,228,1,198,198,198,2,228,228,228,1,252,252,252,2,215,215,215,1,198, + 198,198,2,242,242,242,1,252,252,252,2,201,201,201,1,169,169,169,1,122, + 122,122,1,0,0,0,1,16,16,16,1,106,106,106,1,122,122,122,20,106, + 106,106,1,0,0) + ); + +const + objdata_tdatetimedisp: record size: integer; data: array[0..760] of byte end = + (size: 761; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,100,97, + 116,101,116,105,109,101,100,105,115,112,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,128,2,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,56,2,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,208,208,208,120,128,128,128,25,209, + 209,209,22,255,255,255,1,128,128,128,1,211,211,211,1,209,209,209,1,191, + 191,191,2,193,193,193,1,206,206,206,1,211,211,211,6,202,202,202,1,191, + 191,191,5,193,193,193,1,211,211,211,3,255,255,255,1,128,128,128,1,214, + 214,214,1,187,187,187,1,1,1,1,1,26,26,26,1,24,24,24,1,7, + 7,7,1,50,50,50,1,177,177,177,1,214,214,214,4,128,128,128,1,26, + 26,26,2,6,6,6,1,18,18,18,1,26,26,26,1,37,37,37,1,214, + 214,214,3,255,255,255,1,128,128,128,1,217,217,217,1,190,190,190,1,13, + 13,13,1,217,217,217,3,115,115,115,1,34,34,34,1,210,210,210,1,217, + 217,217,6,49,49,49,1,155,155,155,1,217,217,217,5,255,255,255,1,128, + 128,128,1,219,219,219,1,192,192,192,1,13,13,13,1,219,219,219,4,31, + 31,31,1,151,151,151,1,219,219,219,1,69,69,69,1,161,161,161,1,219, + 219,219,3,49,49,49,1,156,156,156,1,219,219,219,5,255,255,255,1,128, + 128,128,1,222,222,222,1,194,194,194,1,13,13,13,1,222,222,222,4,77, + 77,77,1,114,114,114,1,222,222,222,1,172,172,172,1,203,203,203,1,222, + 222,222,3,50,50,50,1,158,158,158,1,222,222,222,5,255,255,255,1,128, + 128,128,1,224,224,224,1,196,196,196,1,13,13,13,1,224,224,224,4,79, + 79,79,1,116,116,116,1,224,224,224,6,50,50,50,1,160,160,160,1,224, + 224,224,5,255,255,255,1,128,128,128,1,227,227,227,1,199,199,199,1,13, + 13,13,1,227,227,227,3,226,226,226,1,36,36,36,1,155,155,155,1,227, + 227,227,6,51,51,51,1,162,162,162,1,227,227,227,5,255,255,255,1,128, + 128,128,1,229,229,229,1,200,200,200,1,13,13,13,1,229,229,229,2,216, + 216,216,1,113,113,113,1,34,34,34,1,225,225,225,1,229,229,229,1,207, + 207,207,1,220,220,220,1,229,229,229,3,51,51,51,1,163,163,163,1,229, + 229,229,5,255,255,255,1,128,128,128,1,232,232,232,1,203,203,203,1,0, + 0,0,1,6,6,6,2,15,15,15,1,70,70,70,1,204,204,204,1,232, + 232,232,2,44,44,44,1,159,159,159,1,232,232,232,3,52,52,52,1,166, + 166,166,1,232,232,232,5,255,255,255,1,128,128,128,1,235,235,235,22,255, + 255,255,1,128,128,128,1,237,237,237,22,255,255,255,25,208,208,208,120,16, + 0,0,0,0,0,0,120,255,255,255,255,255,255,255,81,0,0,0,120,0, + 0) + ); + +const + objdata_tbytestringdisp: record size: integer; data: array[0..890] of byte end = + (size: 891; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,15,116,98,121, + 116,101,115,116,114,105,110,103,100,105,115,112,23,98,105,116,109,97,112,46, + 116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0, + 128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109, + 111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97, + 115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,0,3,0, + 0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,184,2,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,208,208,208,120,128,128,128, + 25,209,209,209,22,255,255,255,1,128,128,128,1,211,211,211,4,193,193,193, + 1,206,206,206,1,211,211,211,5,200,200,200,1,211,211,211,6,194,194,194, + 1,210,210,210,1,211,211,211,2,255,255,255,1,128,128,128,1,214,214,214, + 3,185,185,185,1,4,4,4,1,109,109,109,1,214,214,214,3,205,205,205, + 1,60,60,60,1,33,33,33,1,23,23,23,1,166,166,166,1,214,214,214, + 3,179,179,179,1,11,11,11,1,205,205,205,1,214,214,214,2,255,255,255, + 1,128,128,128,1,217,217,217,3,104,104,104,1,100,100,100,1,26,26,26, + 1,214,214,214,1,217,217,217,2,99,99,99,1,103,103,103,1,217,217,217, + 1,152,152,152,1,32,32,32,1,216,216,216,1,217,217,217,1,134,134,134, + 1,26,26,26,1,3,3,3,1,208,208,208,1,217,217,217,2,255,255,255, + 1,128,128,128,1,219,219,219,2,216,216,216,1,24,24,24,1,193,193,193, + 1,53,53,53,1,153,153,153,1,219,219,219,2,42,42,42,1,182,182,182, + 1,219,219,219,1,214,214,214,1,3,3,3,1,188,188,188,1,219,219,219, + 1,82,82,82,1,189,189,189,1,9,9,9,1,210,210,210,1,219,219,219, + 2,255,255,255,1,128,128,128,1,222,222,222,2,157,157,157,1,55,55,55, + 1,222,222,222,1,137,137,137,1,65,65,65,1,222,222,222,2,16,16,16, + 1,205,205,205,1,222,222,222,2,37,37,37,1,169,169,169,1,222,222,222, + 3,10,10,10,1,212,212,212,1,222,222,222,2,255,255,255,1,128,128,128, + 1,224,224,224,2,71,71,71,1,86,86,86,1,154,154,154,1,142,142,142, + 1,3,3,3,1,197,197,197,1,224,224,224,1,12,12,12,1,197,197,197, + 1,224,224,224,2,38,38,38,1,174,174,174,1,224,224,224,3,10,10,10, + 1,214,214,214,1,224,224,224,2,255,255,255,1,128,128,128,1,227,227,227, + 1,207,207,207,1,12,12,12,1,99,99,99,3,45,45,45,1,109,109,109, + 1,227,227,227,1,35,35,35,1,162,162,162,1,227,227,227,1,222,222,222, + 1,4,4,4,1,207,207,207,1,227,227,227,3,10,10,10,1,217,217,217, + 1,227,227,227,2,255,255,255,1,128,128,128,1,229,229,229,1,126,126,126, + 1,77,77,77,1,229,229,229,3,169,169,169,1,22,22,22,1,225,225,225, + 1,101,101,101,1,104,104,104,1,229,229,229,1,166,166,166,1,39,39,39, + 1,229,229,229,4,10,10,10,1,219,219,219,1,229,229,229,2,255,255,255, + 1,128,128,128,1,232,232,232,1,37,37,37,1,162,162,162,1,232,232,232, + 3,231,231,231,1,29,29,29,1,156,156,156,1,213,213,213,1,89,89,89, + 1,44,44,44,1,37,37,37,1,184,184,184,1,232,232,232,4,10,10,10, + 1,222,222,222,1,232,232,232,2,255,255,255,1,128,128,128,1,235,235,235, + 11,226,226,226,1,235,235,235,10,255,255,255,1,128,128,128,1,237,237,237, + 22,255,255,255,25,208,208,208,120,16,0,0,0,0,0,0,120,255,255,255, + 255,255,255,255,81,0,0,0,120,0,0) + ); + +const + objdata_tlistview: record size: integer; data: array[0..2260] of byte end = + (size: 2261; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,9,116,108,105, + 115,116,118,105,101,119,23,98,105,116,109,97,112,46,116,114,97,110,115,112, + 97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109, + 97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107, + 101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105, + 116,109,97,112,46,105,109,97,103,101,10,96,8,0,0,0,0,0,0,6, + 0,0,0,24,0,0,0,24,0,0,0,28,8,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,128,128,128,25,135,207,233,1,145,214,237,1,143, + 212,237,1,140,210,237,1,138,208,237,1,137,207,237,1,134,205,237,1,132, + 203,236,1,130,201,236,1,128,199,236,1,126,198,236,1,124,196,235,1,122, + 194,235,1,119,192,235,1,118,190,235,1,116,189,234,1,113,187,234,1,111, + 185,234,1,109,183,233,1,107,181,233,1,105,180,233,1,95,172,228,1,255, + 255,255,1,128,128,128,1,147,216,237,1,158,224,243,1,155,221,242,1,124, + 200,228,1,120,191,220,1,122,196,224,1,139,210,238,1,144,212,241,1,142, + 210,241,1,139,208,241,1,137,206,241,1,135,204,240,1,133,202,240,1,130, + 200,240,1,128,198,240,1,126,196,239,1,122,194,237,1,99,184,157,1,105, + 186,177,1,116,188,238,1,114,186,238,1,103,178,233,1,255,255,255,1,128, + 128,128,1,147,216,237,1,158,224,243,1,89,174,206,1,101,144,172,1,76, + 151,183,1,95,147,177,1,77,155,187,1,123,199,230,1,142,210,241,1,139, + 208,241,1,137,206,241,1,135,204,240,1,133,202,240,1,130,200,240,1,128, + 198,240,1,114,189,210,1,88,180,128,1,150,229,199,1,147,222,196,1,98, + 178,175,1,114,186,238,1,103,178,233,1,255,255,255,1,128,128,128,1,147, + 216,237,1,154,222,241,1,172,194,208,1,240,170,150,1,201,205,214,1,232, + 170,161,1,222,179,177,1,135,202,228,1,142,210,241,1,139,208,241,1,137, + 206,241,1,135,204,240,1,133,202,240,1,130,200,240,1,94,179,163,1,74, + 174,103,1,121,209,163,1,156,233,206,1,156,227,206,1,106,182,144,1,92, + 172,176,1,103,178,233,1,255,255,255,1,128,128,128,1,147,216,237,1,158, + 224,243,1,146,206,226,1,171,175,220,1,145,165,239,1,165,175,227,1,186, + 213,231,1,127,201,229,1,142,210,241,1,139,208,241,1,137,206,241,1,135, + 204,240,1,132,201,238,1,77,168,122,1,60,160,86,1,67,167,88,1,121, + 209,160,1,162,238,214,1,76,169,99,1,88,172,151,1,71,158,120,1,99, + 176,220,1,255,255,255,1,128,128,128,1,147,216,237,1,158,224,243,1,136, + 207,230,1,181,213,230,1,121,133,242,1,116,128,242,1,156,205,225,1,135, + 207,237,1,142,210,241,1,139,208,241,1,137,206,241,1,135,204,240,1,133, + 202,240,1,126,197,230,1,74,169,117,1,90,187,122,1,134,218,179,1,172, + 245,229,1,142,213,189,1,83,167,132,1,114,186,238,1,103,178,233,1,255, + 255,255,1,128,128,128,1,147,216,237,1,158,224,243,1,155,222,243,1,125, + 192,221,1,121,186,214,1,122,186,214,1,129,199,230,1,144,212,241,1,142, + 210,241,1,139,208,241,1,137,206,241,1,135,204,240,1,125,197,223,1,63, + 160,93,1,77,171,121,1,69,167,88,1,132,216,175,1,148,226,194,1,80, + 170,106,1,82,165,123,1,67,157,113,1,103,178,233,1,255,255,255,1,128, + 128,128,1,147,216,237,1,152,223,223,1,136,218,175,1,142,212,158,1,130, + 210,137,1,119,211,118,1,121,211,126,1,125,212,185,1,142,210,241,1,139, + 208,241,1,137,206,241,1,135,204,240,1,133,202,240,1,128,198,234,1,75, + 169,115,1,101,195,135,1,146,227,195,1,174,244,231,1,127,201,170,1,80, + 163,123,1,98,176,195,1,103,178,233,1,255,255,255,1,128,128,128,1,147, + 216,237,1,133,217,154,1,123,216,136,1,121,215,137,1,119,215,138,1,109, + 215,120,1,95,213,92,1,79,213,62,1,116,211,171,1,139,208,241,1,137, + 206,241,1,135,204,240,1,127,198,227,1,53,155,69,1,67,170,88,1,102, + 195,134,1,140,221,191,1,161,232,218,1,118,191,155,1,77,154,102,1,46, + 132,59,1,57,148,103,1,250,253,250,1,128,128,128,1,147,216,237,1,157, + 222,241,1,101,144,157,1,121,174,192,1,151,218,242,1,149,216,242,1,122, + 179,202,1,136,200,228,1,142,210,241,1,139,208,241,1,122,184,215,1,135, + 204,240,1,133,202,240,1,130,200,240,1,114,182,212,1,102,172,187,1,67, + 155,187,1,44,132,186,1,101,180,192,1,106,182,211,1,111,184,230,1,98, + 169,221,1,255,255,255,1,128,128,128,1,147,216,237,1,156,220,239,1,76, + 108,118,1,95,137,152,1,111,160,177,1,113,163,183,1,93,137,155,1,124, + 183,208,1,113,167,192,1,123,184,213,1,93,141,164,1,135,204,240,1,133, + 202,240,1,130,200,240,1,87,134,163,1,58,90,110,1,52,112,153,1,42, + 115,167,1,89,147,186,1,98,159,201,1,114,186,238,1,74,128,167,1,255, + 255,255,1,128,128,128,1,147,216,237,1,156,220,239,1,105,150,164,1,153, + 220,243,1,99,144,159,1,97,141,158,1,89,131,148,1,103,151,172,1,99, + 146,167,1,87,131,151,1,81,121,142,1,135,204,240,1,133,202,240,1,130, + 200,240,1,84,130,157,1,95,148,180,1,63,100,123,1,83,132,164,1,84, + 134,168,1,76,124,157,1,83,136,174,1,74,128,167,1,255,255,255,1,128, + 128,128,1,147,216,237,1,158,224,243,1,156,222,243,1,153,220,243,1,149, + 217,241,1,147,215,241,1,146,214,242,1,144,212,241,1,142,210,241,1,139, + 208,241,1,137,206,241,1,135,204,240,1,133,202,240,1,130,200,240,1,117, + 181,219,1,131,189,226,1,161,171,188,1,165,185,206,1,126,169,202,1,106, + 173,218,1,114,186,238,1,96,165,217,1,255,255,255,1,128,128,128,1,147, + 216,237,1,158,224,243,1,137,207,236,1,87,173,225,1,63,159,224,1,67, + 160,224,1,84,170,225,1,127,199,234,1,142,210,241,1,139,208,241,1,137, + 206,241,1,135,204,240,1,133,202,240,1,130,200,240,1,162,157,170,1,221, + 191,192,1,227,197,197,3,211,150,155,1,114,186,238,1,103,178,233,1,255, + 255,255,1,128,128,128,1,147,216,237,1,158,224,243,1,81,170,223,1,81, + 168,233,1,114,185,237,1,127,191,239,1,114,185,237,1,87,171,224,1,142, + 210,241,1,139,208,241,1,137,206,241,1,135,204,240,1,133,202,240,1,130, + 200,240,1,191,134,134,1,184,131,132,1,189,150,155,1,213,179,182,1,212, + 120,123,1,207,82,83,1,114,186,238,1,103,178,233,1,255,255,255,1,128, + 128,128,1,147,216,237,1,154,222,241,1,63,156,224,1,110,183,237,1,158, + 207,243,1,191,223,247,1,158,207,243,1,95,172,226,1,139,208,239,1,139, + 208,241,1,137,206,241,1,135,204,240,1,133,202,240,1,130,200,240,1,191, + 134,134,4,206,73,73,1,207,82,83,1,114,186,238,1,103,178,233,1,255, + 255,255,1,128,128,128,1,147,216,237,1,158,224,243,1,95,177,225,1,101, + 178,235,1,146,201,241,1,169,212,244,1,144,200,240,1,101,180,226,1,142, + 210,241,1,139,208,241,1,137,206,241,1,135,204,240,1,133,202,240,1,130, + 200,240,1,191,134,134,4,206,73,73,1,201,95,100,1,114,186,238,1,103, + 178,233,1,255,255,255,1,128,128,128,1,147,216,237,1,158,224,243,1,154, + 221,242,1,115,192,230,1,102,180,228,1,106,182,229,1,114,190,229,1,142, + 211,240,1,142,210,241,1,139,208,241,1,137,206,241,1,135,204,240,1,133, + 202,240,1,130,200,240,1,178,151,161,1,190,136,137,1,191,134,134,2,205, + 77,78,1,144,168,204,1,114,186,238,1,103,178,233,1,255,255,255,1,128, + 128,128,1,147,216,237,1,141,199,216,1,111,158,172,1,149,215,237,1,151, + 218,242,1,149,216,242,1,146,214,242,1,144,212,241,1,142,210,241,1,139, + 208,241,1,137,206,241,1,135,204,240,1,133,202,240,1,122,188,226,1,128, + 198,240,1,133,193,232,1,168,166,185,1,178,135,138,1,170,143,164,1,109, + 177,224,1,114,186,238,1,103,178,233,1,255,255,255,1,128,128,128,1,147, + 216,237,1,106,150,163,1,153,218,238,1,99,142,157,1,102,148,164,1,103, + 149,167,1,96,141,159,1,101,148,168,1,101,150,172,1,136,203,235,1,136, + 205,240,1,135,204,240,1,133,202,240,1,89,137,165,1,128,198,240,1,108, + 168,205,1,106,167,205,1,83,132,164,1,97,154,193,1,86,139,176,1,79, + 129,165,1,95,163,214,1,255,255,255,1,128,128,128,1,147,216,237,1,103, + 146,158,1,105,150,164,1,105,151,167,1,76,109,121,1,91,132,148,1,90, + 132,149,1,99,145,165,1,66,97,112,1,107,161,186,1,132,199,232,1,135, + 204,240,1,133,202,240,1,89,137,165,1,124,192,232,1,88,137,167,1,83, + 131,161,1,71,112,140,1,84,134,168,1,68,111,140,1,86,141,180,1,72, + 124,163,1,255,255,255,1,128,128,128,1,135,207,233,1,145,214,237,1,142, + 211,236,1,140,210,237,1,138,208,237,1,112,170,194,1,129,198,229,1,132, + 203,236,1,129,200,235,1,128,199,236,1,126,198,236,1,124,196,235,1,122, + 194,235,1,109,176,216,1,88,142,176,1,103,168,208,1,94,155,195,1,102, + 170,216,1,99,166,212,1,85,144,185,1,70,120,155,1,94,169,224,1,255, + 255,255,25,12,0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0, + 0) + ); + +const + objdata_tbarcode: record size: integer; data: array[0..2863] of byte end = + (size: 2864; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,8,116,98,97, + 114,99,111,100,101,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97, + 114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97, + 112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101, + 100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116, + 109,97,112,46,105,109,97,103,101,10,188,10,0,0,0,0,0,0,6,0, + 0,0,24,0,0,0,24,0,0,0,12,5,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,208,208,208,72,0,0,0,1,208,208,208,1,0,0, + 0,1,208,208,208,2,0,0,0,2,208,208,208,1,0,0,0,1,208,208, + 208,2,0,0,0,1,208,208,208,1,0,0,0,1,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,1,208,208, + 208,1,0,0,0,2,208,208,208,1,0,0,0,1,208,208,208,2,0,0, + 0,2,208,208,208,1,0,0,0,1,208,208,208,2,0,0,0,1,208,208, + 208,1,0,0,0,1,208,208,208,1,0,0,0,2,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,1,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,1,208,208,208,2,0,0,0,2,208,208,208,1,0,0, + 0,1,208,208,208,2,0,0,0,1,208,208,208,1,0,0,0,1,208,208, + 208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0, + 0,1,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,1,208,208, + 208,2,0,0,0,2,208,208,208,1,0,0,0,1,208,208,208,2,0,0, + 0,1,208,208,208,1,0,0,0,1,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,2,208,208,208,1,0,0,0,1,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,1,208,208,208,2,0,0,0,2,208,208, + 208,1,0,0,0,1,208,208,208,2,0,0,0,1,208,208,208,1,0,0, + 0,1,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,1,208,208,208,1,0,0,0,2,208,208,208,1,0,0, + 0,1,208,208,208,2,0,0,0,2,208,208,208,1,0,0,0,1,208,208, + 208,2,0,0,0,1,208,208,208,1,0,0,0,1,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,1,208,208, + 208,1,0,0,0,2,208,208,208,1,0,0,0,1,208,208,208,2,0,0, + 0,2,208,208,208,1,0,0,0,1,208,208,208,2,0,0,0,1,208,208, + 208,1,0,0,0,1,208,208,208,1,0,0,0,2,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,1,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,1,208,208,208,2,0,0,0,2,208,208,208,1,0,0, + 0,1,208,208,208,2,0,0,0,1,208,208,208,1,0,0,0,1,208,208, + 208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0, + 0,1,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,1,208,208, + 208,2,0,0,0,2,208,208,208,1,0,0,0,1,208,208,208,2,0,0, + 0,1,208,208,208,1,0,0,0,1,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,2,208,208,208,1,0,0,0,1,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,1,208,208,208,2,0,0,0,2,208,208, + 208,1,0,0,0,1,208,208,208,2,0,0,0,1,208,208,208,1,0,0, + 0,1,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,1,208,208,208,1,0,0,0,2,208,208,208,1,0,0, + 0,1,208,208,208,2,0,0,0,2,208,208,208,1,0,0,0,1,208,208, + 208,2,0,0,0,1,208,208,208,1,0,0,0,1,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,1,208,208, + 208,1,0,0,0,2,208,208,208,1,0,0,0,1,208,208,208,2,0,0, + 0,2,208,208,208,1,0,0,0,1,208,208,208,2,0,0,0,1,208,208, + 208,1,0,0,0,1,208,208,208,1,0,0,0,2,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,1,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,1,208,208,208,2,0,0,0,2,208,208,208,1,0,0, + 0,1,208,208,208,2,0,0,0,1,208,208,208,1,0,0,0,1,208,208, + 208,1,0,0,0,2,208,208,208,1,0,0,0,2,208,208,208,1,0,0, + 0,1,208,208,208,1,0,0,0,2,208,208,208,1,0,0,0,1,208,208, + 208,2,0,0,0,1,208,208,208,2,0,0,0,1,208,208,208,2,0,0, + 0,1,208,208,208,1,0,0,0,1,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,1,208,208,208,2,0,0,0,1,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,1,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,3,208,208,208,1,0,0,0,1,208,208,208,1,0,0, + 0,7,208,208,208,1,0,0,0,1,208,208,208,1,0,0,0,2,208,208, + 208,1,0,0,0,1,208,208,208,1,0,0,0,2,208,208,208,1,0,0, + 0,1,208,208,208,1,0,0,0,1,208,208,208,1,0,0,0,1,208,208, + 208,1,0,0,0,7,208,208,208,1,0,0,0,1,208,208,208,1,0,0, + 0,2,208,208,208,1,0,0,0,1,208,208,208,2,0,0,0,1,208,208, + 208,1,0,0,0,1,208,208,208,1,0,0,0,1,208,208,208,1,0,0, + 0,1,208,208,208,1,0,0,0,1,208,208,208,1,0,0,0,5,208,208, + 208,1,0,0,0,1,208,208,208,1,0,0,0,2,208,208,208,1,0,0, + 0,1,208,208,208,2,0,0,0,1,208,208,208,1,0,0,0,3,208,208, + 208,1,0,0,0,1,208,208,208,1,0,0,0,1,208,208,208,1,0,0, + 0,5,208,208,208,1,0,0,0,1,208,208,208,1,0,0,0,1,208,208, + 208,8,0,0,0,1,208,208,208,9,0,0,0,1,208,208,208,53,120,5, + 0,0,0,0,0,72,255,255,255,1,0,0,0,1,255,255,255,1,0,0, + 0,2,255,255,255,2,0,0,0,1,255,255,255,1,0,0,0,2,255,255, + 255,1,0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,2,0,0, + 0,1,255,255,255,2,0,0,0,1,255,255,255,1,0,0,0,1,255,255, + 255,2,0,0,0,1,255,255,255,1,0,0,0,2,255,255,255,2,0,0, + 0,1,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,1,255,255, + 255,1,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,2,0,0, + 0,1,255,255,255,1,0,0,0,1,255,255,255,2,0,0,0,1,255,255, + 255,1,0,0,0,2,255,255,255,2,0,0,0,1,255,255,255,1,0,0, + 0,2,255,255,255,1,0,0,0,1,255,255,255,1,0,0,0,1,255,255, + 255,2,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,1,0,0, + 0,1,255,255,255,2,0,0,0,1,255,255,255,1,0,0,0,2,255,255, + 255,2,0,0,0,1,255,255,255,1,0,0,0,2,255,255,255,1,0,0, + 0,1,255,255,255,1,0,0,0,1,255,255,255,2,0,0,0,1,255,255, + 255,2,0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,2,0,0, + 0,1,255,255,255,1,0,0,0,2,255,255,255,2,0,0,0,1,255,255, + 255,1,0,0,0,2,255,255,255,1,0,0,0,1,255,255,255,1,0,0, + 0,1,255,255,255,2,0,0,0,1,255,255,255,2,0,0,0,1,255,255, + 255,1,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,1,0,0, + 0,2,255,255,255,2,0,0,0,1,255,255,255,1,0,0,0,2,255,255, + 255,1,0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,2,0,0, + 0,1,255,255,255,2,0,0,0,1,255,255,255,1,0,0,0,1,255,255, + 255,2,0,0,0,1,255,255,255,1,0,0,0,2,255,255,255,2,0,0, + 0,1,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,1,255,255, + 255,1,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,2,0,0, + 0,1,255,255,255,1,0,0,0,1,255,255,255,2,0,0,0,1,255,255, + 255,1,0,0,0,2,255,255,255,2,0,0,0,1,255,255,255,1,0,0, + 0,2,255,255,255,1,0,0,0,1,255,255,255,1,0,0,0,1,255,255, + 255,2,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,1,0,0, + 0,1,255,255,255,2,0,0,0,1,255,255,255,1,0,0,0,2,255,255, + 255,2,0,0,0,1,255,255,255,1,0,0,0,2,255,255,255,1,0,0, + 0,1,255,255,255,1,0,0,0,1,255,255,255,2,0,0,0,1,255,255, + 255,2,0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,2,0,0, + 0,1,255,255,255,1,0,0,0,2,255,255,255,2,0,0,0,1,255,255, + 255,1,0,0,0,2,255,255,255,1,0,0,0,1,255,255,255,1,0,0, + 0,1,255,255,255,2,0,0,0,1,255,255,255,2,0,0,0,1,255,255, + 255,1,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,1,0,0, + 0,2,255,255,255,2,0,0,0,1,255,255,255,1,0,0,0,2,255,255, + 255,1,0,0,0,1,255,255,255,1,0,0,0,1,255,255,255,2,0,0, + 0,1,255,255,255,2,0,0,0,1,255,255,255,1,0,0,0,1,255,255, + 255,2,0,0,0,1,255,255,255,1,0,0,0,2,255,255,255,2,0,0, + 0,1,255,255,255,1,0,0,0,2,255,255,255,1,0,0,0,1,255,255, + 255,1,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,2,0,0, + 0,1,255,255,255,1,0,0,0,1,255,255,255,2,0,0,0,1,255,255, + 255,1,0,0,0,2,255,255,255,2,0,0,0,1,255,255,255,1,0,0, + 0,2,255,255,255,1,0,0,0,1,255,255,255,1,0,0,0,1,255,255, + 255,2,0,0,0,1,255,255,255,2,0,0,0,1,255,255,255,1,0,0, + 0,1,255,255,255,2,0,0,0,1,255,255,255,1,0,0,0,2,5,5, + 5,1,0,0,0,2,3,3,3,1,0,0,0,2,255,255,255,1,0,0, + 0,1,255,255,255,1,0,0,0,1,3,3,3,1,1,1,1,1,0,0, + 0,1,3,3,3,1,0,0,0,2,255,255,255,1,0,0,0,1,255,255, + 255,2,0,0,0,1,255,255,255,1,0,0,0,1,29,29,29,1,186,186, + 186,1,0,0,0,1,94,94,94,1,119,119,119,1,109,109,109,1,0,0, + 0,1,255,255,255,1,0,0,0,1,255,255,255,1,15,15,15,1,176,176, + 176,1,24,24,24,1,64,64,64,1,126,126,126,1,131,131,131,1,0,0, + 0,1,255,255,255,1,0,0,0,1,255,255,255,2,0,0,0,1,255,255, + 255,1,0,0,0,1,41,41,41,1,132,132,132,1,0,0,0,1,142,142, + 142,1,0,0,0,1,144,144,144,1,0,0,0,1,255,255,255,1,0,0, + 0,1,255,255,255,1,32,32,32,1,117,117,117,1,24,24,24,1,138,138, + 138,1,4,4,4,1,144,144,144,1,0,0,0,1,255,255,255,1,0,0, + 0,1,255,255,255,2,0,0,0,1,255,255,255,1,0,0,0,2,128,128, + 128,1,0,0,0,1,125,125,125,1,0,0,0,1,139,139,139,1,0,0, + 0,1,255,255,255,1,0,0,0,1,255,255,255,1,0,0,0,1,103,103, + 103,1,24,24,24,1,123,123,123,1,2,2,2,1,139,139,139,1,0,0, + 0,1,255,255,255,1,0,0,0,1,255,255,255,2,0,0,0,1,255,255, + 255,1,0,0,0,2,128,128,128,1,0,0,0,1,80,80,80,1,111,111, + 111,1,103,103,103,1,0,0,0,1,255,255,255,1,0,0,0,1,255,255, + 255,1,0,0,0,1,103,103,103,1,24,24,24,1,55,55,55,1,116,116, + 116,1,123,123,123,1,0,0,0,1,255,255,255,1,0,0,0,1,255,255, + 255,1,0,0,0,8,2,2,2,1,0,0,0,9,2,2,2,1,0,0, + 0,53,0,0) + ); + +const + objdata_tdial: record size: integer; data: array[0..641] of byte end = + (size: 642; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,5,116,100,105, + 97,108,12,98,105,116,109,97,112,46,105,109,97,103,101,10,88,2,0,0, + 0,0,0,0,0,0,0,0,24,0,0,0,24,0,0,0,36,2,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,255,0,255,169,0,0,0,1, + 255,0,255,5,0,0,0,1,255,0,255,5,0,0,0,1,255,0,255,5, + 0,0,0,1,255,0,255,5,0,0,0,1,255,0,255,5,0,0,0,1, + 255,0,255,5,0,0,0,1,255,0,255,5,0,0,0,1,255,0,255,5, + 0,0,0,1,255,0,255,5,0,0,0,1,255,0,255,5,0,0,0,1, + 255,0,255,5,0,0,0,1,255,0,255,5,0,0,0,1,255,0,255,5, + 0,0,0,1,255,0,255,5,0,0,0,1,255,0,255,5,0,0,0,1, + 255,0,255,5,0,0,0,1,255,0,255,5,0,0,0,1,255,0,255,5, + 0,0,0,1,255,0,255,5,0,0,0,1,255,0,255,5,0,0,0,1, + 255,0,255,2,0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,2, + 0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,2,0,0,0,1, + 255,0,255,2,0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,2, + 0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,2,0,0,0,1, + 255,0,255,2,0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,2, + 0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,2,0,0,0,1, + 255,0,255,2,0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,2, + 0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,2,0,0,0,1, + 255,0,255,2,0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,2, + 0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,2,0,0,0,1, + 255,0,255,2,0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,2, + 0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,2,0,0,0,1, + 255,0,255,2,0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,2, + 0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,2,0,0,0,1, + 255,0,255,2,0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,2, + 0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,2,0,0,0,1, + 255,0,255,2,0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,2, + 0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,2,0,0,0,1, + 255,0,255,2,0,0,0,1,255,0,255,2,0,0,0,1,255,0,255,145, + 0,0) + ); + +const + objdata_tchart: record size: integer; data: array[0..2621] of byte end = + (size: 2622; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,6,116,99,104, + 97,114,116,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114,101, + 110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112,46, + 111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,13, + 98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109,97, + 112,46,105,109,97,103,101,10,204,9,0,0,0,0,0,0,6,0,0,0, + 24,0,0,0,24,0,0,0,188,4,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,128,128,128,25,250,144,144,2,208,208,208,1,253,152,152,1, + 250,144,144,2,208,208,208,1,255,159,159,1,250,144,144,1,208,208,208,2, + 255,159,159,1,250,144,144,1,208,208,208,2,255,159,159,1,250,144,144,1, + 208,208,208,2,0,0,0,1,113,65,65,1,0,0,0,1,255,255,255,1, + 128,128,128,1,250,144,144,3,250,145,145,1,250,144,144,13,228,132,132,1, + 6,4,4,1,19,11,11,1,112,64,64,1,228,132,132,1,255,252,252,1, + 128,128,128,1,250,144,144,1,208,208,208,2,255,159,159,1,250,144,144,1, + 208,208,208,2,255,159,159,1,250,144,144,1,208,208,208,2,255,159,159,1, + 250,144,144,1,208,208,208,2,255,159,159,1,228,131,131,1,0,0,0,3, + 250,144,144,1,208,208,208,1,255,255,255,1,128,128,128,1,208,208,208,16, + 0,0,0,2,208,208,208,4,255,255,255,1,128,128,128,1,250,144,144,2, + 208,208,208,1,253,152,152,1,250,144,144,2,208,208,208,1,255,159,159,1, + 250,144,144,1,208,208,208,2,255,159,159,1,250,144,144,1,208,208,208,2, + 66,41,41,1,19,11,11,1,0,0,0,1,208,208,208,2,250,144,144,1, + 208,208,208,1,255,255,255,1,128,128,128,1,250,144,144,3,250,145,145,1, + 250,144,144,8,229,132,132,1,250,144,144,2,114,66,66,1,111,64,64,1, + 250,144,144,5,255,252,252,1,128,128,128,1,250,144,144,1,208,208,208,2, + 255,159,159,1,250,144,144,1,208,208,208,2,255,159,159,1,250,144,144,1, + 208,208,208,2,64,40,40,1,21,12,12,1,0,0,0,2,1,0,0,1, + 227,131,131,1,208,208,208,3,250,144,144,1,208,208,208,1,255,255,255,1, + 128,128,128,1,208,208,208,11,0,0,0,5,208,208,208,6,255,255,255,1, + 128,128,128,1,250,144,144,1,255,159,159,1,208,208,208,1,255,159,159,1, + 250,144,144,1,255,159,159,1,208,208,208,1,255,159,159,1,250,144,144,1, + 208,208,208,1,0,0,0,1,1,0,0,1,230,132,132,1,0,0,0,2, + 64,40,40,1,250,144,144,1,208,208,208,3,250,144,144,1,208,208,208,1, + 255,255,255,1,128,128,128,1,250,144,144,2,208,208,208,1,250,144,144,3, + 208,208,208,1,250,144,144,3,0,0,0,1,116,67,67,1,250,144,144,2, + 0,0,0,1,250,144,144,3,208,208,208,1,250,144,144,3,255,255,255,1, + 128,128,128,1,250,144,144,1,255,128,128,1,208,208,208,1,255,159,159,1, + 250,144,144,1,208,208,208,2,255,159,159,1,250,144,144,1,0,0,0,2, + 66,41,41,1,250,144,144,1,208,208,208,2,255,159,159,1,250,144,144,1, + 208,208,208,3,250,144,144,1,255,128,128,1,255,255,255,1,128,128,128,1, + 208,208,208,9,0,0,0,2,208,208,208,11,255,255,255,1,128,128,128,1, + 250,144,144,1,255,159,159,1,0,0,0,1,255,159,159,1,250,144,144,1, + 255,159,159,1,208,208,208,1,0,0,0,1,89,51,51,1,0,0,0,2, + 208,208,208,1,250,144,144,1,208,208,208,3,250,144,144,1,208,208,208,3, + 250,144,144,1,255,159,159,1,255,255,255,1,128,128,128,1,250,144,144,1, + 237,136,136,1,0,0,0,1,113,65,65,1,214,123,123,1,139,80,80,1, + 0,0,0,1,39,23,23,1,139,80,80,1,231,133,133,1,208,208,208,1, + 250,144,144,3,208,208,208,1,250,144,144,3,208,208,208,1,250,144,144,3, + 255,255,255,1,128,128,128,1,250,144,144,1,14,9,9,1,0,0,0,2, + 18,10,10,1,0,0,0,2,208,208,208,1,250,144,144,1,208,208,208,3, + 250,144,144,1,208,208,208,3,250,144,144,1,208,208,208,3,250,144,144,1, + 255,159,159,1,255,255,255,1,128,128,128,1,208,208,208,1,0,0,0,2, + 208,208,208,1,0,0,0,1,208,208,208,17,255,255,255,1,128,128,128,1, + 237,136,136,1,1,1,1,1,0,0,0,1,255,159,159,1,250,144,144,1, + 255,159,159,1,208,208,208,2,250,144,144,1,208,208,208,3,250,144,144,1, + 208,208,208,3,250,144,144,1,208,208,208,3,250,144,144,1,255,159,159,1, + 255,255,255,1,128,128,128,1,162,93,93,1,78,45,45,1,208,208,208,1, + 250,144,144,3,208,208,208,1,250,144,144,3,208,208,208,1,250,144,144,3, + 208,208,208,1,250,144,144,3,208,208,208,1,250,144,144,3,255,255,255,1, + 128,128,128,1,77,44,44,1,14,9,9,1,208,208,208,2,250,144,144,1, + 208,208,208,3,250,144,144,1,208,208,208,3,250,144,144,1,208,208,208,3, + 250,144,144,1,208,208,208,3,250,144,144,1,255,159,159,1,255,255,255,1, + 128,128,128,1,0,0,0,2,208,208,208,20,255,255,255,1,128,128,128,1, + 250,144,144,1,255,159,159,1,208,208,208,1,255,159,159,1,250,144,144,1, + 255,159,159,1,208,208,208,2,250,144,144,1,208,208,208,3,250,144,144,1, + 208,208,208,3,250,144,144,1,208,208,208,3,250,144,144,1,255,159,159,1, + 255,255,255,1,128,128,128,1,250,144,144,2,208,208,208,1,250,144,144,3, + 208,208,208,1,250,144,144,3,208,208,208,1,250,144,144,3,208,208,208,1, + 250,144,144,3,208,208,208,1,250,144,144,3,255,255,255,25,216,4,0,0, + 255,255,255,26,8,8,8,1,0,0,0,1,15,15,15,1,248,248,248,1, + 8,8,8,1,0,0,0,1,8,8,8,1,248,248,248,1,0,0,0,2, + 8,8,8,1,248,248,248,1,0,0,0,2,8,8,8,1,248,248,248,1, + 0,0,0,2,22,22,22,1,255,255,255,1,117,117,117,1,255,255,255,3, + 248,248,248,1,7,7,7,1,240,240,240,1,255,255,255,1,248,248,248,1, + 7,7,7,1,248,248,248,1,255,255,255,2,8,8,8,1,248,248,248,1, + 255,255,255,2,8,8,8,1,248,248,248,1,255,255,255,2,144,144,144,1, + 254,254,254,1,255,255,255,5,0,0,0,2,8,8,8,1,248,248,248,1, + 0,0,0,2,8,8,8,1,248,248,248,1,0,0,0,2,8,8,8,1, + 248,248,248,1,0,0,0,2,8,8,8,1,249,249,249,1,236,236,236,1, + 143,143,143,1,24,24,24,1,255,255,255,1,0,0,0,1,255,255,255,2, + 0,0,0,16,139,139,139,1,143,143,143,1,0,0,0,4,255,255,255,3, + 8,8,8,1,0,0,0,1,15,15,15,1,248,248,248,1,8,8,8,1, + 0,0,0,1,8,8,8,1,248,248,248,1,0,0,0,2,8,8,8,1, + 248,248,248,1,0,0,0,2,28,28,28,1,254,254,254,1,24,24,24,1, + 0,0,0,2,255,255,255,1,0,0,0,1,255,255,255,3,248,248,248,1, + 7,7,7,1,240,240,240,1,255,255,255,1,248,248,248,1,7,7,7,1, + 248,248,248,1,255,255,255,2,8,8,8,1,248,248,248,1,255,255,255,2, + 8,8,8,1,252,252,252,1,255,255,255,2,8,8,8,1,248,248,248,1, + 255,255,255,5,0,0,0,2,8,8,8,1,248,248,248,1,0,0,0,2, + 8,8,8,1,248,248,248,1,0,0,0,2,29,29,29,1,254,254,254,1, + 60,60,60,1,20,20,20,1,235,235,235,1,249,249,249,1,0,0,0,3, + 255,255,255,1,0,0,0,1,255,255,255,2,0,0,0,11,140,140,140,1, + 177,177,177,1,231,231,231,1,177,177,177,1,140,140,140,1,0,0,0,6, + 255,255,255,3,8,8,8,1,0,0,0,1,16,16,16,1,248,248,248,1, + 8,8,8,1,0,0,0,1,8,8,8,1,248,248,248,1,0,0,0,1, + 22,22,22,1,234,234,234,1,249,249,249,1,60,60,60,1,233,233,233,1, + 29,29,29,1,248,248,248,1,0,0,0,3,255,255,255,1,0,0,0,1, + 255,255,255,3,248,248,248,1,0,0,0,1,248,248,248,1,255,255,255,1, + 248,248,248,1,0,0,0,1,255,255,255,3,140,140,140,1,255,255,255,3, + 21,21,21,1,255,255,255,3,0,0,0,1,255,255,255,5,254,254,254,1, + 2,2,2,1,0,0,0,1,8,8,8,1,248,248,248,1,0,0,0,2, + 8,8,8,1,248,248,248,1,22,22,22,1,234,234,234,1,28,28,28,1, + 248,248,248,1,0,0,0,2,8,8,8,1,248,248,248,1,0,0,0,3, + 254,254,254,1,2,2,2,1,255,255,255,2,0,0,0,9,140,140,140,1, + 139,139,139,1,0,0,0,11,255,255,255,2,248,248,248,1,16,16,16,1, + 12,12,12,1,8,8,8,1,255,255,255,1,8,8,8,1,0,0,0,1, + 61,61,61,1,255,255,255,1,238,238,238,1,22,22,22,1,0,0,0,1, + 255,255,255,1,0,0,0,3,255,255,255,1,0,0,0,3,248,248,248,1, + 8,8,8,1,255,255,255,3,248,248,248,1,237,237,237,1,252,252,252,1, + 255,255,255,1,251,251,251,1,213,213,213,1,255,255,255,3,0,0,0,1, + 255,255,255,3,0,0,0,1,255,255,255,3,0,0,0,1,255,255,255,5, + 248,248,248,1,95,95,95,1,185,185,185,1,140,140,140,1,255,255,255,1, + 164,164,164,1,62,62,62,1,0,0,0,1,255,255,255,1,0,0,0,3, + 255,255,255,1,0,0,0,3,255,255,255,1,0,0,0,3,248,248,248,1, + 8,8,8,1,255,255,255,2,0,0,0,1,176,176,176,1,88,88,88,1, + 0,0,0,1,1,1,1,1,0,0,0,17,255,255,255,2,248,248,248,1, + 240,240,240,1,12,12,12,1,8,8,8,1,255,255,255,1,8,8,8,1, + 0,0,0,2,255,255,255,1,0,0,0,3,255,255,255,1,0,0,0,3, + 255,255,255,1,0,0,0,3,248,248,248,1,8,8,8,1,255,255,255,3, + 253,253,253,1,0,0,0,1,248,248,248,1,255,255,255,1,248,248,248,1, + 0,0,0,1,255,255,255,3,0,0,0,1,255,255,255,3,0,0,0,1, + 255,255,255,3,0,0,0,1,255,255,255,5,253,253,253,1,95,95,95,1, + 0,0,0,2,255,255,255,1,0,0,0,3,255,255,255,1,0,0,0,3, + 255,255,255,1,0,0,0,3,255,255,255,1,0,0,0,3,248,248,248,1, + 8,8,8,1,255,255,255,2,119,119,119,1,13,13,13,1,0,0,0,20, + 255,255,255,2,248,248,248,1,16,16,16,1,0,0,0,1,8,8,8,1, + 255,255,255,1,8,8,8,1,0,0,0,2,255,255,255,1,0,0,0,3, + 255,255,255,1,0,0,0,3,255,255,255,1,0,0,0,3,248,248,248,1, + 8,8,8,1,255,255,255,3,248,248,248,1,0,0,0,1,248,248,248,1, + 255,255,255,1,248,248,248,1,0,0,0,1,255,255,255,3,0,0,0,1, + 255,255,255,3,0,0,0,1,255,255,255,3,0,0,0,1,255,255,255,28, + 0,0) + ); + +const + objdata_tchartrecorder: record size: integer; data: array[0..2833] of byte end = + (size: 2834; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,116,99,104, + 97,114,116,114,101,99,111,114,100,101,114,23,98,105,116,109,97,112,46,116, + 114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128, + 14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111, + 95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115, + 107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,152,10,0,0, + 0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,136,4,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,250,144,144,1, + 253,152,152,1,0,0,0,1,250,144,144,3,208,208,208,1,250,144,144,3, + 208,208,208,2,250,144,144,1,208,208,208,1,0,0,0,1,208,208,208,1, + 250,144,144,1,208,208,208,3,250,144,144,1,255,159,159,1,255,255,255,1, + 128,128,128,1,250,144,144,1,190,109,109,1,1,1,1,1,188,108,108,1, + 250,144,144,9,191,110,110,1,1,1,1,1,189,109,109,1,250,144,144,6, + 255,250,250,1,128,128,128,1,190,109,109,1,1,1,1,1,0,0,0,2, + 191,110,110,1,208,208,208,3,250,144,144,1,208,208,208,3,191,110,110,1, + 0,0,0,3,191,110,110,1,208,208,208,3,250,144,144,1,255,159,159,1, + 255,255,255,1,128,128,128,1,0,0,0,2,208,208,208,1,0,0,0,3, + 208,208,208,5,0,0,0,3,208,208,208,1,0,0,0,3,208,208,208,4, + 255,255,255,1,128,128,128,1,250,144,144,1,253,152,152,1,208,208,208,1, + 250,144,144,1,191,110,110,1,1,0,0,1,0,0,0,1,250,144,144,3, + 0,0,0,2,191,110,110,1,208,208,208,3,191,110,110,1,0,0,0,2, + 208,208,208,1,250,144,144,1,255,159,159,1,255,255,255,1,128,128,128,1, + 250,144,144,5,190,109,109,1,1,0,0,1,188,109,109,1,250,144,144,1, + 190,109,109,1,1,0,0,1,190,109,109,1,250,144,144,5,191,110,110,1, + 1,0,0,1,190,109,109,1,250,144,144,2,255,252,252,1,128,128,128,1, + 250,144,144,1,255,159,159,1,208,208,208,2,250,144,144,1,208,208,208,1, + 0,0,0,2,140,81,81,1,0,0,0,2,208,208,208,1,250,144,144,1, + 208,208,208,3,250,144,144,1,208,208,208,1,0,0,0,2,138,80,80,1, + 9,6,6,1,255,255,255,1,128,128,128,1,208,208,208,7,0,0,0,3, + 208,208,208,9,0,0,0,3,255,255,255,1,128,128,128,1,250,144,144,1, + 253,152,152,1,208,208,208,1,250,144,144,3,208,208,208,1,250,144,144,1, + 239,138,138,1,250,144,144,1,208,208,208,2,250,144,144,1,208,208,208,3, + 250,144,144,1,208,208,208,3,239,138,138,1,255,159,159,1,255,255,255,1, + 128,128,128,1,250,144,144,22,255,252,252,1,128,128,128,1,250,144,144,1, + 255,159,159,1,208,208,208,2,250,144,144,1,208,208,208,3,250,144,144,1, + 208,208,208,3,250,144,144,1,208,208,208,3,250,144,144,1,208,208,208,3, + 250,144,144,1,255,159,159,1,255,255,255,1,128,128,128,1,208,208,208,22, + 255,255,255,1,128,128,128,1,250,144,144,1,253,152,152,1,208,208,208,1, + 250,144,144,2,40,23,23,1,0,0,0,2,72,41,41,1,39,22,22,1, + 208,208,208,2,250,144,144,1,208,208,208,3,250,144,144,1,208,208,208,2, + 0,0,0,1,68,39,39,1,9,6,6,1,255,255,255,1,128,128,128,1, + 250,144,144,4,219,126,126,1,25,14,14,1,9,5,5,1,230,133,133,1, + 136,78,78,1,30,17,17,1,73,42,42,1,250,144,144,7,80,46,46,1, + 29,17,17,1,133,77,77,1,240,138,138,1,255,252,252,1,128,128,128,1, + 250,144,144,1,255,159,159,1,208,208,208,1,0,0,0,1,57,33,33,1, + 0,0,0,1,208,208,208,2,250,144,144,1,0,0,0,2,208,208,208,1, + 250,144,144,1,208,208,208,3,250,144,144,1,208,208,208,1,0,0,0,2, + 250,144,144,1,255,159,159,1,255,255,255,1,128,128,128,1,208,208,208,3, + 0,0,0,2,208,208,208,4,0,0,0,3,208,208,208,5,0,0,0,3, + 208,208,208,2,255,255,255,1,128,128,128,1,250,144,144,1,253,152,152,1, + 0,0,0,1,1,0,0,1,227,131,131,1,250,144,144,1,208,208,208,1, + 250,144,144,3,0,0,0,2,238,137,137,1,208,208,208,3,239,138,138,1, + 0,0,0,2,208,208,208,1,250,144,144,1,255,159,159,1,255,255,255,1, + 128,128,128,1,250,144,144,1,246,142,142,1,2,1,1,1,159,92,92,1, + 250,144,144,7,94,54,54,1,105,60,60,1,250,144,144,3,110,63,63,1, + 96,55,55,1,250,144,144,4,255,252,252,1,128,128,128,1,216,125,125,1, + 5,3,3,1,0,0,0,1,208,208,208,1,250,144,144,1,255,146,146,1, + 208,208,208,2,250,144,144,1,255,146,146,1,208,208,208,1,0,0,0,1, + 30,17,17,1,8,5,5,1,0,0,0,2,29,17,17,1,74,42,42,1, + 208,208,208,2,250,145,145,1,255,136,136,1,255,255,255,1,128,128,128,1, + 0,0,0,3,208,208,208,9,0,0,0,5,208,208,208,5,255,255,255,1, + 128,128,128,1,250,144,144,1,253,144,144,1,208,208,208,1,250,144,144,2, + 253,152,152,1,208,208,208,1,250,144,144,2,253,153,153,1,208,208,208,2, + 250,144,144,1,255,159,159,1,208,208,208,2,250,144,144,1,255,159,159,1, + 208,208,208,2,250,145,145,1,255,143,143,1,255,255,255,1,128,128,128,1, + 250,144,144,22,255,252,252,1,255,255,255,24,216,5,0,0,255,255,255,25, + 248,248,248,1,16,16,16,1,11,11,11,1,7,7,7,1,255,255,255,1, + 8,8,8,1,0,0,0,1,7,7,7,1,255,255,255,1,6,6,6,1, + 0,0,0,2,255,255,255,1,0,0,0,1,11,11,11,1,0,0,0,1, + 255,255,255,1,0,0,0,3,248,248,248,1,8,8,8,1,255,255,255,2, + 254,254,254,1,250,250,250,1,232,232,232,1,240,240,240,1,255,255,255,1, + 248,248,248,1,11,11,11,1,236,236,236,1,255,255,255,1,249,249,249,1, + 11,11,11,1,244,244,244,1,255,255,255,2,232,232,232,1,247,247,247,1, + 255,255,255,2,12,12,12,1,244,244,244,1,255,255,255,4,250,250,250,1, + 232,232,232,1,112,112,112,1,231,231,231,1,255,255,255,1,0,0,0,3, + 255,255,255,1,0,0,0,3,255,255,255,1,231,231,231,1,112,112,112,1, + 231,231,231,1,255,255,255,1,0,0,0,3,248,248,248,1,8,8,8,1, + 255,255,255,2,115,115,115,1,60,60,60,1,0,0,0,1,60,60,60,1, + 231,231,231,1,60,60,60,1,0,0,0,5,60,60,60,1,231,231,231,1, + 60,60,60,1,0,0,0,1,60,60,60,1,231,231,231,1,60,60,60,1, + 0,0,0,4,255,255,255,2,248,248,248,1,16,16,16,1,0,0,0,1, + 7,7,7,1,255,255,255,1,232,232,232,1,60,60,60,1,7,7,7,1, + 255,255,255,1,6,6,6,1,60,60,60,1,231,231,231,1,255,255,255,1, + 0,0,0,3,255,255,255,1,231,231,231,1,60,60,60,1,0,0,0,1, + 248,248,248,1,8,8,8,1,255,255,255,3,248,248,248,1,7,7,7,1, + 240,240,240,1,255,255,255,1,250,250,250,1,232,232,232,1,244,244,244,1, + 255,255,255,1,250,250,250,1,232,232,232,1,250,250,250,1,255,255,255,2, + 8,8,8,1,248,248,248,1,255,255,255,2,232,232,232,1,250,250,250,1, + 255,255,255,4,248,248,248,1,8,8,8,1,0,0,0,2,255,255,255,1, + 0,0,0,1,60,60,60,1,231,231,231,1,255,255,255,1,231,231,231,1, + 60,60,60,1,0,0,0,1,255,255,255,1,0,0,0,3,255,255,255,1, + 0,0,0,1,60,60,60,1,231,231,231,1,251,251,251,1,119,119,119,1, + 255,255,255,2,0,0,0,7,60,60,60,1,231,231,231,1,60,60,60,1, + 0,0,0,9,60,60,60,1,231,231,231,1,60,60,60,1,255,255,255,2, + 248,248,248,1,16,16,16,1,0,0,0,1,7,7,7,1,255,255,255,1, + 8,8,8,1,0,0,0,1,7,7,7,1,255,255,255,1,6,6,6,1, + 0,0,0,2,255,255,255,1,0,0,0,3,255,255,255,1,0,0,0,3, + 248,248,248,1,8,8,8,1,255,255,255,3,248,248,248,1,7,7,7,1, + 240,240,240,1,255,255,255,1,248,248,248,1,7,7,7,1,240,240,240,1, + 255,255,255,1,249,249,249,1,7,7,7,1,248,248,248,1,255,255,255,2, + 8,8,8,1,248,248,248,1,255,255,255,2,8,8,8,1,248,248,248,1, + 255,255,255,4,248,248,248,1,8,8,8,1,0,0,0,2,255,255,255,1, + 0,0,0,3,255,255,255,1,0,0,0,3,255,255,255,1,0,0,0,3, + 255,255,255,1,0,0,0,3,248,248,248,1,8,8,8,1,255,255,255,2, + 0,0,0,22,255,255,255,2,248,248,248,1,16,16,16,1,0,0,0,1, + 7,7,7,1,255,255,255,1,43,43,43,1,185,185,185,1,239,239,239,1, + 255,255,255,1,34,34,34,1,0,0,0,2,255,255,255,1,0,0,0,3, + 255,255,255,1,0,0,0,2,30,30,30,1,253,253,253,1,123,123,123,1, + 255,255,255,3,248,248,248,1,7,7,7,1,240,240,240,1,255,255,255,1, + 254,254,254,1,110,110,110,1,241,241,241,1,255,255,255,1,254,254,254,1, + 23,23,23,1,248,248,248,1,255,255,255,2,8,8,8,1,248,248,248,1, + 255,255,255,2,23,23,23,1,254,254,254,1,255,255,255,4,248,248,248,1, + 8,8,8,1,0,0,0,1,3,3,3,1,255,255,255,1,104,104,104,1, + 0,0,0,2,255,255,255,1,147,147,147,1,157,157,157,1,0,0,0,1, + 255,255,255,1,0,0,0,3,255,255,255,1,0,0,0,1,157,157,157,1, + 143,143,143,1,248,248,248,1,8,8,8,1,255,255,255,2,0,0,0,3, + 127,127,127,1,179,179,179,1,0,0,0,4,12,12,12,1,222,222,222,1, + 68,68,68,1,0,0,0,5,68,68,68,1,221,221,221,1,11,11,11,1, + 0,0,0,2,255,255,255,2,247,247,247,1,16,16,16,1,47,47,47,1, + 232,232,232,1,255,255,255,1,8,8,8,1,0,0,0,1,7,7,7,1, + 255,255,255,1,6,6,6,1,68,68,68,1,222,222,222,1,255,255,255,1, + 0,0,0,3,255,255,255,1,221,221,221,1,68,68,68,1,0,0,0,1, + 247,247,247,1,8,8,8,1,255,255,255,2,254,254,254,1,248,248,248,1, + 206,206,206,1,245,245,245,1,255,255,255,1,248,248,248,1,7,7,7,1, + 240,240,240,1,255,255,255,1,249,249,249,1,7,7,7,1,252,252,252,1, + 255,255,255,2,8,8,8,1,248,248,248,1,255,255,255,2,8,8,8,1, + 248,248,248,1,255,255,255,4,242,242,242,1,191,191,191,1,170,170,170,1, + 0,0,0,1,248,248,248,1,7,7,7,1,0,0,0,2,248,248,248,1, + 7,7,7,1,0,0,0,1,16,16,16,1,254,254,254,1,120,120,120,1, + 19,19,19,1,119,119,119,1,254,254,254,1,23,23,23,1,0,0,0,2, + 240,240,240,1,15,15,15,1,255,255,255,2,116,116,116,1,110,110,110,1, + 1,1,1,1,0,0,0,9,29,29,29,1,182,182,182,1,239,239,239,1, + 184,184,184,1,30,30,30,1,0,0,0,5,255,255,255,2,240,240,240,1, + 23,23,23,1,0,0,0,1,7,7,7,1,248,248,248,1,16,16,16,1, + 0,0,0,1,7,7,7,1,248,248,248,1,14,14,14,1,0,0,0,2, + 248,248,248,1,8,8,8,1,0,0,0,2,248,248,248,1,8,8,8,1, + 0,0,0,2,240,240,240,1,16,16,16,1,255,255,255,2,254,254,254,1, + 248,248,248,1,7,7,7,1,240,240,240,1,255,255,255,1,248,248,248,1, + 7,7,7,1,240,240,240,1,255,255,255,1,249,249,249,1,7,7,7,1, + 248,248,248,1,255,255,255,2,8,8,8,1,248,248,248,1,255,255,255,2, + 8,8,8,1,248,248,248,1,255,255,255,27,0,0) + ); + +const + objdata_twindowwidget: record size: integer; data: array[0..1000] of byte end = + (size: 1001; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,119,105, + 110,100,111,119,119,105,100,103,101,116,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,112,3,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,44,3,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,255,164,139,22,255, + 255,255,1,128,128,128,1,255,164,139,22,255,255,255,1,128,128,128,1,255, + 164,139,22,255,255,255,1,128,128,128,1,255,164,139,22,255,255,255,1,128, + 128,128,1,255,164,139,22,255,255,255,1,128,128,128,1,255,164,139,22,255, + 255,255,1,128,128,128,1,255,164,139,2,235,151,128,1,249,160,136,1,255, + 164,139,2,248,159,135,1,231,149,126,1,255,164,139,3,242,156,132,1,243, + 156,132,1,245,158,134,1,240,154,131,1,255,164,139,3,252,162,137,1,233, + 150,127,1,255,164,139,2,255,255,255,1,128,128,128,1,255,164,139,2,72, + 46,39,1,157,101,86,1,255,164,139,2,140,90,76,1,0,0,0,1,213, + 137,116,1,255,164,139,2,82,53,45,1,161,104,88,1,147,95,80,1,92, + 59,50,1,255,164,139,3,219,141,119,1,20,13,11,1,255,164,139,2,255, + 255,255,1,128,128,128,1,255,164,139,2,140,90,76,1,98,63,53,1,255, + 164,139,2,67,43,37,1,81,52,44,1,140,90,76,1,255,164,139,1,254, + 163,138,1,21,14,11,1,230,148,125,1,147,95,80,1,92,59,50,1,255, + 164,139,3,219,141,119,1,20,13,11,1,255,164,139,2,255,255,255,1,128, + 128,128,1,255,164,139,2,208,134,113,1,39,25,21,1,255,164,139,1,243, + 156,132,1,30,19,16,1,196,126,107,1,68,44,37,1,255,164,139,1,212, + 136,116,1,46,30,25,1,255,164,139,1,147,95,80,1,92,59,50,1,255, + 164,139,3,219,141,119,1,20,13,11,1,255,164,139,2,255,255,255,1,128, + 128,128,1,255,164,139,2,254,163,138,1,23,15,13,1,236,152,129,1,177, + 114,96,1,94,60,51,1,252,162,137,1,23,15,13,1,244,157,133,1,150, + 96,82,1,116,75,63,1,255,164,139,1,147,95,80,1,23,15,13,1,63, + 41,34,3,54,35,29,1,20,13,11,1,255,164,139,2,255,255,255,1,128, + 128,128,1,255,164,139,3,89,57,49,1,178,114,97,1,104,67,57,1,165, + 106,90,1,255,164,139,1,82,53,45,1,188,121,102,1,87,56,47,1,186, + 120,101,1,255,164,139,1,147,95,80,1,74,48,40,1,207,133,113,3,178, + 114,97,1,20,13,11,1,255,164,139,2,255,255,255,1,128,128,128,1,255, + 164,139,3,157,101,86,1,121,78,66,1,35,23,19,1,235,151,128,1,255, + 164,139,1,152,98,83,1,132,85,72,1,34,22,19,1,247,159,135,1,255, + 164,139,1,147,95,80,1,92,59,50,1,255,164,139,3,219,141,119,1,20, + 13,11,1,255,164,139,2,255,255,255,1,128,128,128,1,255,164,139,3,225, + 145,123,1,42,27,23,1,52,33,28,1,255,164,139,2,222,143,121,1,44, + 28,24,1,70,45,38,1,255,164,139,2,147,95,80,1,92,59,50,1,255, + 164,139,3,219,141,119,1,20,13,11,1,255,164,139,2,255,255,255,1,128, + 128,128,1,255,164,139,4,37,24,20,1,124,80,68,1,255,164,139,3,36, + 23,20,1,140,90,76,1,255,164,139,2,147,95,80,1,92,59,50,1,255, + 164,139,3,219,141,119,1,20,13,11,1,255,164,139,2,255,255,255,1,128, + 128,128,1,255,164,139,22,255,255,255,1,128,128,128,1,255,164,139,22,255, + 255,255,1,128,128,128,1,255,164,139,22,255,255,255,1,128,128,128,1,255, + 164,139,22,255,255,255,1,128,128,128,1,255,164,139,22,255,255,255,1,128, + 128,128,1,255,164,139,22,255,255,255,1,128,128,128,1,255,164,139,22,255, + 255,255,25,12,0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0, + 0) + ); + +const + objdata_topenglwidget: record size: integer; data: array[0..832] of byte end = + (size: 833; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,116,111,112, + 101,110,103,108,119,105,100,103,101,116,23,98,105,116,109,97,112,46,116,114, + 97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14, + 98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95, + 109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107, + 0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,200,2,0,0,0, + 0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,132,2,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,255,164,139,22,255, + 255,255,1,128,128,128,1,255,164,139,22,255,255,255,1,128,128,128,1,255, + 164,139,22,255,255,255,1,128,128,128,1,255,164,139,22,255,255,255,1,128, + 128,128,1,255,164,139,22,255,255,255,1,128,128,128,1,255,164,139,22,255, + 255,255,1,128,128,128,1,255,164,139,7,237,152,129,1,217,140,118,1,252, + 162,137,1,255,164,139,3,234,150,128,1,251,161,137,1,255,164,139,7,255, + 255,255,1,128,128,128,1,255,164,139,5,195,125,106,1,45,29,25,1,48, + 31,26,1,61,39,33,1,24,15,13,1,157,101,86,1,255,164,139,2,22, + 14,12,1,209,134,114,1,255,164,139,7,255,255,255,1,128,128,128,1,255, + 164,139,4,212,136,116,1,33,21,18,1,203,131,111,1,255,164,139,2,222, + 143,121,1,23,15,13,1,215,138,117,1,255,164,139,1,22,14,12,1,209, + 134,114,1,255,164,139,7,255,255,255,1,128,128,128,1,255,164,139,4,111, + 71,61,1,130,84,71,1,255,164,139,4,196,126,107,1,228,147,124,1,255, + 164,139,1,22,14,12,1,209,134,114,1,255,164,139,7,255,255,255,1,128, + 128,128,1,255,164,139,4,53,34,29,1,180,116,98,1,255,164,139,2,228, + 147,124,1,223,143,122,2,237,152,129,1,255,164,139,1,22,14,12,1,209, + 134,114,1,255,164,139,7,255,255,255,1,128,128,128,1,255,164,139,4,53, + 34,29,1,172,111,94,1,255,164,139,2,73,47,40,1,39,25,21,1,21, + 14,11,1,111,71,61,1,255,164,139,1,22,14,12,1,209,134,114,1,255, + 164,139,7,255,255,255,1,128,128,128,1,255,164,139,4,113,73,62,1,117, + 75,64,1,255,164,139,4,135,87,74,1,111,71,61,1,255,164,139,1,22, + 14,12,1,209,134,114,1,255,164,139,7,255,255,255,1,128,128,128,1,255, + 164,139,4,217,140,118,1,28,18,15,1,158,102,86,1,250,161,136,1,255, + 164,139,1,223,143,122,1,67,43,37,1,115,74,63,1,255,164,139,1,22, + 14,12,1,209,134,114,1,255,164,139,7,255,255,255,1,128,128,128,1,255, + 164,139,5,215,138,117,1,70,45,38,1,24,15,13,1,28,18,15,1,27, + 17,15,1,131,84,71,1,247,159,135,1,255,164,139,1,22,14,12,1,6, + 4,3,1,7,5,4,3,218,140,119,1,255,164,139,3,255,255,255,1,128, + 128,128,1,255,164,139,7,252,162,137,1,239,154,130,1,255,164,139,13,255, + 255,255,1,128,128,128,1,255,164,139,22,255,255,255,1,128,128,128,1,255, + 164,139,22,255,255,255,1,128,128,128,1,255,164,139,22,255,255,255,1,128, + 128,128,1,255,164,139,22,255,255,255,1,128,128,128,1,255,164,139,22,255, + 255,255,1,128,128,128,1,255,164,139,22,255,255,255,25,12,0,0,0,255, + 255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_topenglcanvaswidget: record size: integer; data: array[0..1242] of byte end = + (size: 1243; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,19,116,111,112, + 101,110,103,108,99,97,110,118,97,115,119,105,100,103,101,116,23,98,105,116, + 109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114, + 4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115, + 11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108, + 111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,92,4,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0, + 0,24,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128, + 25,255,164,139,22,255,255,255,1,128,128,128,1,255,164,139,7,236,152,129, + 1,218,140,119,1,253,163,138,1,255,164,139,3,233,150,127,1,252,162,137, + 1,255,164,139,7,255,255,255,1,128,128,128,1,255,164,139,5,189,122,103, + 1,44,28,24,1,49,32,27,1,60,39,33,1,25,16,14,1,163,105,89, + 1,255,164,139,2,14,9,8,1,217,140,118,1,255,164,139,7,255,255,255, + 1,128,128,128,1,255,164,139,4,207,133,113,1,34,22,19,1,207,133,113, + 1,255,164,139,2,218,140,119,1,21,14,11,1,221,142,120,1,255,164,139, + 1,14,9,8,1,217,140,118,1,255,164,139,7,255,255,255,1,128,128,128, + 1,255,164,139,4,104,67,57,1,137,88,75,1,255,164,139,4,194,125,106, + 1,230,148,125,1,255,164,139,1,14,9,8,1,217,140,118,1,255,164,139, + 7,255,255,255,1,128,128,128,1,255,164,139,4,45,29,25,1,188,121,102, + 1,255,164,139,2,228,147,124,1,223,143,122,2,238,153,130,1,255,164,139, + 1,14,9,8,1,217,140,118,1,255,164,139,7,255,255,255,1,128,128,128, + 1,255,164,139,4,46,30,25,1,180,116,98,1,255,164,139,2,67,43,37, + 1,39,25,21,1,20,13,11,1,119,77,65,1,255,164,139,1,14,9,8, + 1,217,140,118,1,255,164,139,7,255,255,255,1,128,128,128,1,255,164,139, + 4,105,68,57,1,124,80,68,1,255,164,139,4,128,82,70,1,119,77,65, + 1,255,164,139,1,14,9,8,1,217,140,118,1,255,164,139,7,255,255,255, + 1,128,128,128,1,255,164,139,4,213,137,116,1,26,17,14,1,163,105,89, + 1,251,161,137,1,255,164,139,1,220,141,120,1,62,40,34,1,123,79,67, + 1,255,164,139,1,14,9,8,1,217,140,118,1,255,164,139,7,255,255,255, + 1,128,128,128,1,255,164,139,5,211,136,115,1,68,44,37,1,24,15,13, + 1,27,17,15,1,29,19,16,1,135,87,74,1,248,159,135,1,255,164,139, + 1,14,9,8,1,6,4,3,1,7,5,4,3,226,145,123,1,255,164,139, + 3,255,255,255,1,128,128,128,1,255,164,139,7,252,162,137,1,240,154,131, + 1,255,164,139,13,255,255,255,1,128,128,128,1,255,164,139,5,218,140,119, + 1,138,89,75,1,89,57,49,1,148,95,81,1,229,147,125,1,255,164,139, + 4,147,95,80,1,152,98,83,1,255,164,139,6,255,255,255,1,128,128,128, + 1,255,164,139,4,203,131,111,1,32,21,17,1,131,84,71,1,188,121,102, + 1,125,80,68,1,29,19,16,1,239,154,130,1,255,164,139,2,240,154,131, + 1,39,25,21,1,25,16,14,1,242,156,132,1,255,164,139,5,255,255,255, + 1,128,128,128,1,255,164,139,4,33,21,18,1,174,112,95,1,255,164,139, + 3,119,77,65,1,160,103,87,1,255,164,139,2,152,98,83,1,106,68,58, + 1,94,60,51,1,151,97,82,1,255,164,139,5,255,255,255,1,128,128,128, + 1,255,164,139,3,231,149,126,1,13,8,7,1,255,164,139,8,53,34,29, + 1,193,124,105,1,189,122,103,1,47,30,26,1,255,164,139,5,255,255,255, + 1,128,128,128,1,255,164,139,3,196,126,107,1,38,24,21,1,255,164,139, + 7,210,135,114,1,33,21,18,1,254,163,138,2,30,19,16,1,200,129,109, + 1,255,164,139,4,255,255,255,1,128,128,128,1,255,164,139,3,238,153,130, + 1,6,4,3,1,250,161,136,1,255,164,139,3,229,147,125,1,217,140,118, + 1,255,164,139,1,111,71,61,1,16,10,9,1,47,30,26,2,16,10,9, + 1,96,62,52,1,255,164,139,4,255,255,255,1,128,128,128,1,255,164,139, + 4,49,32,27,1,157,101,86,1,255,164,139,3,81,52,44,1,121,78,66, + 1,249,160,136,1,19,12,10,1,206,132,112,1,239,154,130,2,206,132,112, + 1,10,6,5,1,239,154,130,1,255,164,139,3,255,255,255,1,128,128,128, + 1,255,164,139,4,215,138,117,1,21,14,11,1,118,76,64,1,163,105,89, + 1,91,59,50,1,33,21,18,1,245,158,134,1,169,109,92,1,53,34,29, + 1,255,164,139,4,60,39,33,1,144,93,78,1,255,164,139,3,255,255,255, + 1,128,128,128,1,255,164,139,5,227,146,124,1,160,103,87,1,114,73,62, + 1,176,113,96,1,247,159,135,1,255,164,139,1,175,113,95,1,189,122,103, + 1,255,164,139,4,195,125,106,1,161,104,88,1,255,164,139,3,255,255,255, + 1,128,128,128,1,255,164,139,22,255,255,255,1,128,128,128,1,255,164,139, + 22,255,255,255,25,12,0,0,0,255,255,255,255,255,255,255,255,255,255,255, + 66,0,0) + ); + +const + objdata_tpolygon: record size: integer; data: array[0..2067] of byte end = + (size: 2068; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,8,116,112,111, + 108,121,103,111,110,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97, + 114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97, + 112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101, + 100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116, + 109,97,112,46,105,109,97,103,101,10,160,7,0,0,0,0,0,0,6,0, + 0,0,24,0,0,0,24,0,0,0,56,4,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,128,128,128,25,208,208,208,17,0,255,255,1,208,208, + 208,4,255,255,255,1,128,128,128,1,208,208,208,16,49,167,255,1,97,188, + 255,1,147,210,255,1,208,208,208,3,255,255,255,1,128,128,128,1,208,208, + 208,2,0,0,0,18,208,208,208,2,255,255,255,1,128,128,128,1,208,208, + 208,2,0,0,0,1,208,208,208,12,52,168,255,1,112,194,255,1,136,205, + 255,1,29,158,255,1,0,0,0,1,208,208,208,2,255,255,255,1,128,128, + 128,1,208,208,208,2,0,0,0,1,208,208,208,11,57,170,255,1,53,168, + 255,1,185,226,255,1,77,179,255,1,0,146,255,1,0,0,0,1,208,208, + 208,2,255,255,255,1,128,128,128,1,208,208,208,2,0,0,0,1,208,208, + 208,11,51,168,255,1,126,200,255,1,125,200,255,1,17,153,255,1,0,147, + 255,1,0,0,0,1,208,208,208,2,255,255,255,1,128,128,128,1,208,208, + 208,2,0,0,0,1,208,208,208,10,55,164,255,1,67,175,255,1,173,220, + 255,1,65,174,255,1,0,146,255,1,208,208,208,1,0,0,0,1,208,208, + 208,2,255,255,255,1,128,128,128,1,208,208,208,2,0,0,0,1,208,208, + 208,10,51,168,255,1,140,206,255,1,113,195,255,1,5,148,255,1,0,143, + 255,1,208,208,208,1,0,0,0,1,208,208,208,2,255,255,255,1,128,128, + 128,1,208,208,208,2,0,0,0,1,208,208,208,9,50,168,255,1,82,181, + 255,1,161,215,255,1,53,169,255,1,0,147,255,1,208,208,208,2,0,0, + 0,1,208,208,208,2,255,255,255,1,128,128,128,1,208,208,208,2,0,0, + 0,1,208,208,208,8,0,255,255,1,51,168,255,1,155,213,255,1,101,190, + 255,1,0,146,255,1,0,142,255,1,208,208,208,2,0,0,0,1,208,208, + 208,2,255,255,255,1,128,128,128,1,208,208,208,2,0,0,0,1,208,208, + 208,5,68,222,239,1,98,195,228,1,51,157,241,1,52,167,255,1,96,187, + 255,1,149,210,255,1,42,164,255,1,0,146,255,1,208,208,208,3,0,0, + 0,1,208,208,208,2,255,255,255,1,128,128,128,1,208,208,208,2,0,0, + 0,1,208,208,208,4,0,242,255,1,60,203,240,1,143,192,218,1,139,176, + 218,1,87,135,233,1,152,199,254,1,90,184,255,1,0,146,255,1,0,128, + 255,1,208,208,208,3,0,0,0,1,208,208,208,2,255,255,255,1,128,128, + 128,1,208,208,208,2,0,0,0,1,208,208,208,4,0,218,255,1,0,176, + 255,1,16,138,251,1,91,140,232,1,146,159,217,1,131,132,220,1,72,123, + 238,1,3,140,255,1,208,208,208,4,0,0,0,1,208,208,208,2,255,255, + 255,1,128,128,128,1,208,208,208,2,0,0,0,1,208,208,208,4,0,193, + 255,1,0,149,255,1,1,106,255,1,1,62,255,1,25,40,249,1,102,116, + 228,1,147,168,216,1,123,170,223,1,105,186,227,1,208,208,208,3,0,0, + 0,1,208,208,208,2,255,255,255,1,128,128,128,1,208,208,208,2,0,0, + 0,1,208,208,208,4,0,167,255,1,0,123,255,1,1,79,255,1,1,35, + 255,1,1,12,255,1,1,56,255,1,34,117,246,1,112,178,226,1,89,196, + 232,1,208,208,208,3,0,0,0,1,208,208,208,2,255,255,255,1,128,128, + 128,1,208,208,208,2,0,0,0,1,208,208,208,4,0,140,255,1,1,96, + 255,1,1,52,255,1,1,9,255,1,1,39,255,1,1,83,255,1,0,127, + 255,1,0,171,255,1,1,214,255,1,208,208,208,3,0,0,0,1,208,208, + 208,2,255,255,255,1,128,128,128,1,208,208,208,2,0,0,0,1,208,208, + 208,4,0,111,255,1,1,69,255,1,1,26,255,1,1,21,255,1,1,66, + 255,1,1,110,255,1,0,154,255,1,0,198,255,1,0,230,255,1,208,208, + 208,3,0,0,0,1,208,208,208,2,255,255,255,1,128,128,128,1,208,208, + 208,2,0,0,0,1,208,208,208,4,0,85,255,1,1,43,255,1,1,4, + 255,1,1,48,255,1,1,92,255,1,0,137,255,1,0,181,255,1,0,226, + 255,1,208,208,208,4,0,0,0,1,208,208,208,2,255,255,255,1,128,128, + 128,1,208,208,208,2,0,0,0,1,208,208,208,4,0,61,255,1,1,16, + 255,1,1,31,255,1,1,75,255,1,0,119,255,1,0,162,255,1,0,209, + 255,1,208,208,208,5,0,0,0,1,208,208,208,2,255,255,255,1,128,128, + 128,1,208,208,208,2,0,0,0,18,208,208,208,2,255,255,255,1,128,128, + 128,1,208,208,208,6,2,51,255,1,1,7,255,1,2,40,255,1,0,86, + 255,1,0,139,255,1,208,208,208,11,255,255,255,1,128,128,128,1,208,208, + 208,22,255,255,255,25,48,3,0,0,255,255,255,25,0,0,0,17,1,1, + 1,1,0,0,0,4,255,255,255,2,0,0,0,16,52,52,52,1,214,214, + 214,1,80,80,80,1,0,0,0,3,255,255,255,2,0,0,0,2,255,255, + 255,18,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,1,0,0, + 0,12,88,88,88,1,255,255,255,4,0,0,0,2,255,255,255,2,0,0, + 0,2,255,255,255,1,0,0,0,11,9,9,9,1,225,225,225,1,255,255, + 255,2,215,215,215,1,255,255,255,1,0,0,0,2,255,255,255,2,0,0, + 0,2,255,255,255,1,0,0,0,11,126,126,126,1,255,255,255,3,73,73, + 73,1,255,255,255,1,0,0,0,2,255,255,255,2,0,0,0,2,255,255, + 255,1,0,0,0,10,28,28,28,1,245,245,245,1,255,255,255,2,183,183, + 183,1,0,0,0,1,255,255,255,1,0,0,0,2,255,255,255,2,0,0, + 0,2,255,255,255,1,0,0,0,10,164,164,164,1,255,255,255,2,251,251, + 251,1,41,41,41,1,0,0,0,1,255,255,255,1,0,0,0,2,255,255, + 255,2,0,0,0,2,255,255,255,1,0,0,0,9,56,56,56,1,254,254, + 254,1,255,255,255,2,146,146,146,1,0,0,0,2,255,255,255,1,0,0, + 0,2,255,255,255,2,0,0,0,2,255,255,255,1,0,0,0,8,1,1, + 1,1,200,200,200,1,255,255,255,2,238,238,238,1,18,18,18,1,0,0, + 0,2,255,255,255,1,0,0,0,2,255,255,255,2,0,0,0,2,255,255, + 255,1,0,0,0,5,127,127,127,1,210,210,210,1,55,55,55,1,93,93, + 93,1,255,255,255,3,110,110,110,1,0,0,0,3,255,255,255,1,0,0, + 0,2,255,255,255,2,0,0,0,2,255,255,255,1,0,0,0,4,60,60, + 60,1,255,255,255,2,254,254,254,1,213,213,213,1,239,239,239,1,255,255, + 255,1,215,215,215,1,4,4,4,1,0,0,0,3,255,255,255,1,0,0, + 0,2,255,255,255,2,0,0,0,2,255,255,255,1,0,0,0,4,82,82, + 82,1,255,255,255,4,251,251,251,1,211,211,211,1,80,80,80,1,0,0, + 0,4,255,255,255,1,0,0,0,2,255,255,255,2,0,0,0,2,255,255, + 255,1,0,0,0,4,91,91,91,1,255,255,255,6,245,245,245,1,93,93, + 93,1,0,0,0,3,255,255,255,1,0,0,0,2,255,255,255,2,0,0, + 0,2,255,255,255,1,0,0,0,4,87,87,87,1,255,255,255,7,197,197, + 197,1,0,0,0,3,255,255,255,1,0,0,0,2,255,255,255,2,0,0, + 0,2,255,255,255,1,0,0,0,4,71,71,71,1,255,255,255,7,201,201, + 201,1,0,0,0,3,255,255,255,1,0,0,0,2,255,255,255,2,0,0, + 0,2,255,255,255,1,0,0,0,4,55,55,55,1,255,255,255,6,232,232, + 232,1,31,31,31,1,0,0,0,3,255,255,255,1,0,0,0,2,255,255, + 255,2,0,0,0,2,255,255,255,1,0,0,0,4,39,39,39,1,255,255, + 255,5,240,240,240,1,53,53,53,1,0,0,0,4,255,255,255,1,0,0, + 0,2,255,255,255,2,0,0,0,2,255,255,255,1,0,0,0,4,100,100, + 100,1,255,255,255,4,226,226,226,1,44,44,44,1,0,0,0,5,255,255, + 255,1,0,0,0,2,255,255,255,2,0,0,0,2,255,255,255,18,0,0, + 0,2,255,255,255,2,0,0,0,6,130,130,130,1,192,192,192,1,148,148, + 148,1,89,89,89,1,11,11,11,1,0,0,0,11,255,255,255,2,0,0, + 0,22,255,255,255,25,0,0) + ); + +const + objdata_trichbutton: record size: integer; data: array[0..1150] of byte end = + (size: 1151; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,114,105, + 99,104,98,117,116,116,111,110,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,8,4,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,192,3,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,255,255,255,120,224,224,224,25,255,255,255, + 22,0,0,0,1,224,224,224,1,255,255,255,1,22,240,255,2,21,237,255, + 1,21,231,255,1,20,225,255,1,20,220,255,1,19,214,255,1,19,208,255, + 1,18,202,255,1,18,197,255,1,17,191,255,1,17,185,255,1,16,178,255, + 1,16,170,255,1,15,163,255,1,14,155,255,1,14,147,255,1,13,140,255, + 1,13,132,255,1,13,129,255,1,128,128,128,1,0,0,0,1,224,224,224, + 1,255,255,255,1,22,240,255,2,21,237,255,1,21,231,255,1,20,225,255, + 1,20,220,255,1,19,214,255,1,19,208,255,1,18,202,255,1,18,197,255, + 1,17,191,255,1,17,185,255,1,16,178,255,1,16,170,255,1,15,163,255, + 1,14,155,255,1,14,147,255,1,13,140,255,1,13,132,255,1,13,129,255, + 1,128,128,128,1,0,0,0,1,224,224,224,1,255,255,255,1,22,240,255, + 2,21,232,250,1,11,122,135,1,7,84,95,1,11,118,137,1,18,207,247, + 1,19,208,255,1,18,202,255,1,18,197,255,1,17,191,255,1,17,185,255, + 1,16,178,255,1,16,170,255,1,15,163,255,1,14,155,255,1,13,136,236, + 1,11,119,217,1,13,132,255,1,13,129,255,1,128,128,128,1,0,0,0, + 1,224,224,224,1,255,255,255,1,22,240,255,2,8,91,98,1,15,163,180, + 1,20,225,255,1,14,150,174,1,9,103,123,1,19,208,255,1,17,196,247, + 1,15,168,218,1,17,186,248,1,17,185,255,1,15,168,240,1,15,156,234, + 1,14,155,243,1,14,155,255,1,9,91,157,1,8,82,150,1,13,132,255, + 1,13,129,255,1,128,128,128,1,0,0,0,1,224,224,224,1,255,255,255, + 1,22,240,255,1,22,238,253,1,6,67,72,1,21,231,255,1,20,225,255, + 1,20,220,255,1,19,212,253,1,16,180,221,1,5,61,77,1,10,107,139, + 1,4,43,57,1,17,184,253,1,3,38,55,1,7,75,113,1,5,51,80, + 1,11,120,198,1,6,63,110,1,5,51,93,1,13,130,251,1,13,129,255, + 1,128,128,128,1,0,0,0,1,224,224,224,1,255,255,255,1,22,240,255, + 1,21,232,247,1,6,68,73,1,21,231,255,1,20,225,255,1,20,220,255, + 1,19,214,255,1,18,201,247,1,13,147,186,1,10,110,142,1,3,29,39, + 1,16,176,242,1,4,43,62,1,16,170,255,1,13,141,220,1,5,59,97, + 1,9,98,170,1,8,91,165,1,13,132,255,1,13,129,255,1,128,128,128, + 1,0,0,0,1,224,224,224,1,255,255,255,1,22,240,255,2,6,62,67, + 1,19,211,233,1,20,225,255,1,17,192,222,1,8,86,103,1,12,133,163, + 1,8,90,113,1,15,168,218,1,5,55,73,1,16,174,240,1,4,42,60, + 1,16,170,255,1,12,134,209,1,6,66,108,1,9,98,170,1,8,91,165, + 1,13,132,255,1,13,129,255,1,128,128,128,1,0,0,0,1,224,224,224, + 1,255,255,255,1,22,240,255,2,17,197,212,1,6,71,78,1,8,89,101, + 1,6,70,81,1,16,184,219,1,15,161,197,1,6,70,88,1,9,94,122, + 1,3,38,51,1,15,161,222,1,3,36,51,1,6,67,101,1,5,50,78, + 1,12,133,218,1,11,114,198,1,3,33,61,1,12,125,242,1,13,129,255, + 1,128,128,128,1,0,0,0,1,224,224,224,1,255,255,255,1,22,240,255, + 2,21,237,255,1,21,231,255,1,19,218,247,1,20,220,255,1,19,214,255, + 1,19,208,255,1,18,198,250,1,18,194,251,1,17,191,255,1,17,185,255, + 1,5,55,79,1,16,166,249,1,15,162,254,1,14,155,255,1,14,147,255, + 1,13,137,249,1,13,132,255,1,13,129,255,1,128,128,128,1,0,0,0, + 1,224,224,224,1,255,255,255,1,22,240,255,2,21,237,255,1,21,231,255, + 1,20,225,255,1,20,220,255,1,19,214,255,1,19,208,255,1,18,202,255, + 1,18,197,255,1,17,191,255,1,17,185,255,1,10,109,156,1,16,170,255, + 1,15,163,255,1,14,155,255,1,14,147,255,1,13,140,255,1,13,132,255, + 1,13,129,255,1,128,128,128,1,0,0,0,1,224,224,224,1,128,128,128, + 22,0,0,0,25,255,255,255,120,16,0,0,0,0,0,0,120,255,255,255, + 255,255,255,255,81,0,0,0,120,0,0) + ); + +const + objdata_trichstockglyphbutton: record size: integer; data: array[0..960] of byte end = + (size: 961; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,21,116,114,105, + 99,104,115,116,111,99,107,103,108,121,112,104,98,117,116,116,111,110,23,98, + 105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108, + 111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111, + 110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99, + 111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97, + 103,101,10,64,3,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24, + 0,0,0,140,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255, + 255,255,125,224,224,224,14,255,255,255,10,224,224,224,1,255,255,255,12,0, + 0,0,1,255,255,255,10,224,224,224,1,255,255,255,1,21,237,255,1,20, + 227,255,1,20,218,255,1,19,208,255,1,18,198,255,1,17,189,255,1,16, + 178,255,1,15,165,255,1,14,153,255,1,13,140,255,1,128,128,128,1,0, + 0,0,1,255,255,255,10,224,224,224,1,255,255,255,1,21,237,255,1,20, + 227,255,1,18,192,225,1,19,208,255,1,18,198,255,1,17,189,255,1,16, + 178,255,1,13,146,225,1,14,153,255,1,13,140,255,1,128,128,128,1,0, + 0,0,1,255,255,255,10,224,224,224,1,255,255,255,1,21,237,255,1,18, + 200,225,1,2,21,24,1,15,159,195,1,18,198,255,1,17,189,255,1,12, + 136,195,1,1,16,24,1,12,135,225,1,13,140,255,1,128,128,128,1,0, + 0,0,1,255,255,255,10,224,224,224,1,255,255,255,1,21,237,255,1,20, + 227,255,1,15,167,195,1,2,20,24,1,14,151,195,1,13,145,195,1,2, + 17,24,1,11,126,195,1,14,153,255,1,13,140,255,1,128,128,128,1,0, + 0,0,1,255,255,255,10,224,224,224,1,255,255,255,1,21,237,255,1,20, + 227,255,1,20,218,255,1,15,159,195,1,2,15,18,1,1,14,18,1,12, + 136,195,1,15,165,255,1,14,153,255,1,13,140,255,1,128,128,128,1,0, + 0,0,1,255,255,255,10,224,224,224,1,255,255,255,1,21,237,255,1,20, + 227,255,1,20,218,255,1,15,159,195,1,1,14,18,1,2,14,18,1,12, + 136,195,1,15,165,255,1,14,153,255,1,13,140,255,1,128,128,128,1,0, + 0,0,1,255,255,255,10,224,224,224,1,255,255,255,1,21,237,255,1,20, + 227,255,1,15,167,195,1,2,20,24,1,14,151,195,1,13,145,195,1,2, + 17,24,1,11,126,195,1,14,153,255,1,13,140,255,1,128,128,128,1,0, + 0,0,1,255,255,255,10,224,224,224,1,255,255,255,1,21,237,255,1,18, + 200,225,1,2,21,24,1,15,159,195,1,18,198,255,1,17,189,255,1,12, + 136,195,1,1,16,24,1,12,135,225,1,13,140,255,1,128,128,128,1,0, + 0,0,1,255,255,255,10,224,224,224,1,255,255,255,1,21,237,255,1,20, + 227,255,1,18,192,225,1,19,208,255,1,18,198,255,1,17,189,255,1,16, + 178,255,1,13,146,225,1,14,153,255,1,13,140,255,1,128,128,128,1,0, + 0,0,1,255,255,255,10,224,224,224,1,255,255,255,1,21,237,255,1,20, + 227,255,1,20,218,255,1,19,208,255,1,18,198,255,1,17,189,255,1,16, + 178,255,1,15,165,255,1,14,153,255,1,13,140,255,1,128,128,128,1,0, + 0,0,1,255,255,255,10,224,224,224,1,128,128,128,12,0,0,0,1,255, + 255,255,10,0,0,0,14,255,255,255,125,124,0,0,0,0,0,0,125,255, + 255,255,14,0,0,0,10,255,255,255,14,0,0,0,10,255,255,255,14,0, + 0,0,10,255,255,255,14,0,0,0,10,255,255,255,14,0,0,0,10,255, + 255,255,14,0,0,0,10,255,255,255,14,0,0,0,10,255,255,255,14,0, + 0,0,10,255,255,255,14,0,0,0,10,255,255,255,14,0,0,0,10,255, + 255,255,14,0,0,0,10,255,255,255,1,208,208,208,1,255,255,255,12,0, + 0,0,10,255,255,255,14,0,0,0,10,255,255,255,14,0,0,0,125,0, + 0) + ); + +const + objdata_txychartedit: record size: integer; data: array[0..2131] of byte end = + (size: 2132; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,116,120,121, + 99,104,97,114,116,101,100,105,116,23,98,105,116,109,97,112,46,116,114,97, + 110,115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98, + 105,116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109, + 97,115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0, + 12,98,105,116,109,97,112,46,105,109,97,103,101,10,220,7,0,0,0,0, + 0,0,6,0,0,0,24,0,0,0,24,0,0,0,152,7,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,128,128,128,25,0,0,0,22,255,255, + 255,1,128,128,128,1,0,0,0,1,231,231,231,1,230,230,230,1,229,229, + 229,1,228,228,228,1,227,227,227,1,226,226,226,1,224,224,224,1,223,223, + 223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218, + 218,1,217,217,217,1,216,216,216,1,215,215,215,1,214,214,214,1,212,212, + 212,1,211,211,211,1,210,210,210,1,224,224,224,1,255,255,255,1,128,128, + 128,1,0,0,0,1,231,231,231,1,230,230,230,1,229,229,229,1,228,228, + 228,1,227,227,227,1,226,226,226,1,224,224,224,1,223,223,223,1,222,222, + 222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217, + 217,1,216,216,216,1,215,215,215,1,214,214,214,1,212,212,212,1,121,121, + 121,1,182,182,182,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,231,231,231,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227, + 227,1,226,226,226,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221, + 221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,216,216, + 216,1,215,215,215,1,214,214,214,1,171,171,171,1,25,25,25,1,199,199, + 199,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,231,231, + 231,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226, + 226,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220, + 220,1,219,219,219,1,218,218,218,1,217,217,217,1,216,216,216,1,215,215, + 215,1,212,212,212,1,45,45,45,1,141,141,141,1,210,210,210,1,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,231,231,231,1,230,230, + 230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,224,224, + 224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219, + 219,1,218,218,218,1,217,217,217,1,216,216,216,1,215,215,215,1,126,126, + 126,1,61,61,61,1,211,211,211,1,210,210,210,1,224,224,224,1,255,255, + 255,1,128,128,128,1,0,0,0,1,231,231,231,1,230,230,230,1,229,229, + 229,1,228,228,228,1,227,227,227,1,226,226,226,1,224,224,224,1,223,223, + 223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218, + 218,1,217,217,217,1,216,216,216,1,196,196,196,1,21,21,21,1,184,184, + 184,1,211,211,211,1,210,210,210,1,224,224,224,1,255,255,255,1,128,128, + 128,1,0,0,0,1,231,231,231,1,230,230,230,1,229,229,229,1,228,228, + 228,1,227,227,227,1,226,226,226,1,224,224,224,1,223,223,223,1,222,222, + 222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217, + 217,1,216,216,216,1,75,75,75,1,111,111,111,1,212,212,212,1,211,211, + 211,1,210,210,210,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,231,231,231,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227, + 227,1,226,226,226,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221, + 221,1,220,220,220,1,219,219,219,1,218,218,218,1,214,214,214,1,133,133, + 133,1,34,34,34,1,209,209,209,1,212,212,212,1,211,211,211,1,210,210, + 210,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,231,231, + 231,1,230,230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226, + 226,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220, + 220,1,193,193,193,1,107,107,107,1,25,25,25,1,64,64,64,1,192,192, + 192,1,214,214,214,1,212,212,212,1,211,211,211,1,210,210,210,1,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,231,231,231,1,230,230, + 230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,224,224, + 224,1,223,223,223,1,219,219,219,1,153,153,153,1,64,64,64,1,26,26, + 26,1,109,109,109,1,192,192,192,1,216,216,216,1,215,215,215,1,214,214, + 214,1,212,212,212,1,211,211,211,1,210,210,210,1,224,224,224,1,255,255, + 255,1,128,128,128,1,0,0,0,1,231,231,231,1,230,230,230,1,229,229, + 229,1,228,228,228,1,227,227,227,1,226,226,226,1,199,199,199,1,111,111, + 111,1,26,26,26,1,64,64,64,1,153,153,153,1,216,216,216,1,218,218, + 218,1,217,217,217,1,216,216,216,1,215,215,215,1,214,214,214,1,212,212, + 212,1,211,211,211,1,210,210,210,1,224,224,224,1,255,255,255,1,128,128, + 128,1,0,0,0,1,231,231,231,1,230,230,230,1,229,229,229,1,228,228, + 228,1,203,203,203,1,67,67,67,1,25,25,25,1,109,109,109,1,196,196, + 196,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217, + 217,1,216,216,216,1,215,215,215,1,214,214,214,1,212,212,212,1,211,211, + 211,1,210,210,210,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,231,231,231,1,230,230,230,1,229,229,229,1,223,223,223,1,36,36, + 36,1,139,139,139,1,221,221,221,1,223,223,223,1,222,222,222,1,221,221, + 221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,216,216, + 216,1,215,215,215,1,214,214,214,1,212,212,212,1,211,211,211,1,210,210, + 210,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,231,231, + 231,1,230,230,230,1,229,229,229,1,118,118,118,1,79,79,79,1,226,226, + 226,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220, + 220,1,219,219,219,1,218,218,218,1,217,217,217,1,216,216,216,1,215,215, + 215,1,214,214,214,1,212,212,212,1,211,211,211,1,210,210,210,1,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,231,231,231,1,230,230, + 230,1,198,198,198,1,22,22,22,1,207,207,207,1,226,226,226,1,224,224, + 224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219, + 219,1,218,218,218,1,217,217,217,1,216,216,216,1,215,215,215,1,214,214, + 214,1,212,212,212,1,211,211,211,1,210,210,210,1,224,224,224,1,255,255, + 255,1,128,128,128,1,0,0,0,1,231,231,231,1,230,230,230,1,66,66, + 66,1,134,134,134,1,227,227,227,1,226,226,226,1,224,224,224,1,223,223, + 223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218, + 218,1,217,217,217,1,216,216,216,1,215,215,215,1,214,214,214,1,212,212, + 212,1,211,211,211,1,210,210,210,1,224,224,224,1,255,255,255,1,128,128, + 128,1,0,0,0,1,231,231,231,1,154,154,154,1,48,48,48,1,226,226, + 226,1,227,227,227,1,226,226,226,1,224,224,224,1,223,223,223,1,222,222, + 222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217, + 217,1,216,216,216,1,215,215,215,1,214,214,214,1,212,212,212,1,211,211, + 211,1,210,210,210,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0, + 0,1,219,219,219,1,27,27,27,1,185,185,185,1,228,228,228,1,227,227, + 227,1,226,226,226,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221, + 221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,216,216, + 216,1,215,215,215,1,214,214,214,1,212,212,212,1,211,211,211,1,210,210, + 210,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,200,200, + 200,1,132,132,132,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226, + 226,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220, + 220,1,219,219,219,1,218,218,218,1,217,217,217,1,216,216,216,1,215,215, + 215,1,214,214,214,1,212,212,212,1,211,211,211,1,210,210,210,1,224,224, + 224,1,255,255,255,1,128,128,128,1,0,0,0,1,231,231,231,1,230,230, + 230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,224,224, + 224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219, + 219,1,218,218,218,1,217,217,217,1,216,216,216,1,215,215,215,1,214,214, + 214,1,212,212,212,1,211,211,211,1,210,210,210,1,224,224,224,1,255,255, + 255,1,128,128,128,1,224,224,224,22,255,255,255,25,12,0,0,0,255,255, + 255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_txserieschartedit: record size: integer; data: array[0..2136] of byte end = + (size: 2137; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,17,116,120,115, + 101,114,105,101,115,99,104,97,114,116,101,100,105,116,23,98,105,116,109,97, + 112,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111,114,4,6, + 0,0,128,14,98,105,116,109,97,112,46,111,112,116,105,111,110,115,11,10, + 98,109,111,95,109,97,115,107,101,100,13,98,109,111,95,99,111,108,111,114, + 109,97,115,107,0,12,98,105,116,109,97,112,46,105,109,97,103,101,10,220, + 7,0,0,0,0,0,0,6,0,0,0,24,0,0,0,24,0,0,0,152, + 7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,25,0, + 0,0,22,255,255,255,1,128,128,128,1,0,0,0,1,231,231,231,1,230, + 230,230,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,224, + 224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219, + 219,219,1,218,218,218,1,217,217,217,1,216,216,216,1,215,215,215,1,214, + 214,214,1,212,212,212,1,211,211,211,1,210,210,210,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,231,231,231,1,230,230,230,1,229, + 229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,224,224,224,1,223, + 223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218, + 218,218,1,217,217,217,1,216,216,216,1,215,215,215,1,214,214,214,1,212, + 212,212,1,211,211,211,1,210,210,210,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,231,231,231,1,0,0,0,1,229,229,229,1,228, + 228,228,1,227,227,227,1,226,226,226,1,224,224,224,1,223,223,223,1,222, + 222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217, + 217,217,1,216,216,216,1,215,215,215,1,214,214,214,1,212,212,212,1,211, + 211,211,1,210,210,210,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,231,231,231,1,0,0,0,1,229,229,229,1,228,228,228,1,227, + 227,227,1,226,226,226,1,224,224,224,1,223,223,223,1,222,222,222,1,221, + 221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,216, + 216,216,1,215,215,215,1,214,214,214,1,212,212,212,1,211,211,211,1,210, + 210,210,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,231, + 231,231,1,0,0,0,1,229,229,229,1,228,228,228,1,227,227,227,1,226, + 226,226,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220, + 220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,216,216,216,1,215, + 215,215,1,214,214,214,1,212,212,212,1,211,211,211,1,210,210,210,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,231,231,231,1,0, + 0,0,1,229,229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,224, + 224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219, + 219,219,1,218,218,218,1,217,217,217,1,216,216,216,1,215,215,215,1,214, + 214,214,1,212,212,212,1,211,211,211,1,210,210,210,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,231,231,231,1,0,0,0,1,229, + 229,229,1,228,228,228,1,227,227,227,1,226,226,226,1,224,224,224,1,223, + 223,223,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218, + 218,218,1,217,217,217,1,216,216,216,1,215,215,215,1,214,214,214,1,212, + 212,212,1,211,211,211,1,210,210,210,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,231,231,231,1,0,0,0,1,229,229,229,1,228, + 228,228,1,227,227,227,1,226,226,226,1,224,224,224,1,223,223,223,1,222, + 222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217, + 217,217,1,216,216,216,1,215,215,215,1,214,214,214,1,212,212,212,1,211, + 211,211,1,210,210,210,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,231,231,231,1,0,0,0,1,229,229,229,1,0,0,0,1,227, + 227,227,1,226,226,226,1,224,224,224,1,223,223,223,1,222,222,222,1,221, + 221,221,1,220,220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,216, + 216,216,1,215,215,215,1,214,214,214,1,212,212,212,1,211,211,211,1,210, + 210,210,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,231, + 231,231,1,0,0,0,1,229,229,229,1,0,0,0,1,227,227,227,1,226, + 226,226,1,224,224,224,1,223,223,223,1,222,222,222,1,221,221,221,1,220, + 220,220,1,219,219,219,1,218,218,218,1,217,217,217,1,216,216,216,1,215, + 215,215,1,214,214,214,1,212,212,212,1,211,211,211,1,210,210,210,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,231,231,231,1,0, + 0,0,1,229,229,229,1,0,0,0,1,227,227,227,1,226,226,226,1,224, + 224,224,1,111,111,111,1,222,222,222,1,221,221,221,1,220,220,220,1,219, + 219,219,1,218,218,218,1,217,217,217,1,216,216,216,1,215,215,215,1,214, + 214,214,1,212,212,212,1,211,211,211,1,210,210,210,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,231,231,231,1,0,0,0,1,229, + 229,229,1,0,0,0,1,227,227,227,1,226,226,226,1,224,224,224,1,0, + 0,0,1,222,222,222,1,221,221,221,1,220,220,220,1,219,219,219,1,218, + 218,218,1,217,217,217,1,216,216,216,1,215,215,215,1,214,214,214,1,212, + 212,212,1,211,211,211,1,210,210,210,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,231,231,231,1,0,0,0,1,229,229,229,1,0, + 0,0,1,227,227,227,1,226,226,226,1,224,224,224,1,0,0,0,1,222, + 222,222,1,221,221,221,1,220,220,220,1,109,109,109,1,218,218,218,1,217, + 217,217,1,216,216,216,1,215,215,215,1,214,214,214,1,212,212,212,1,211, + 211,211,1,210,210,210,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,231,231,231,1,0,0,0,1,229,229,229,1,0,0,0,1,227, + 227,227,1,226,226,226,1,224,224,224,1,0,0,0,1,222,222,222,1,221, + 221,221,1,220,220,220,1,0,0,0,1,218,218,218,1,217,217,217,1,216, + 216,216,1,215,215,215,1,214,214,214,1,212,212,212,1,211,211,211,1,210, + 210,210,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,231, + 231,231,1,0,0,0,1,229,229,229,1,0,0,0,1,227,227,227,1,226, + 226,226,1,224,224,224,1,0,0,0,1,222,222,222,1,221,221,221,1,220, + 220,220,1,0,0,0,1,218,218,218,1,217,217,217,1,216,216,216,1,107, + 107,107,1,214,214,214,1,212,212,212,1,211,211,211,1,210,210,210,1,224, + 224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,231,231,231,1,0, + 0,0,1,229,229,229,1,0,0,0,1,227,227,227,1,0,0,0,1,224, + 224,224,1,0,0,0,1,222,222,222,1,110,110,110,1,220,220,220,1,0, + 0,0,1,218,218,218,1,217,217,217,1,216,216,216,1,0,0,0,1,214, + 214,214,1,212,212,212,1,211,211,211,1,210,210,210,1,224,224,224,1,255, + 255,255,1,128,128,128,1,0,0,0,1,231,231,231,1,0,0,0,1,229, + 229,229,1,0,0,0,1,227,227,227,1,0,0,0,1,224,224,224,1,0, + 0,0,1,222,222,222,1,0,0,0,1,220,220,220,1,0,0,0,1,218, + 218,218,1,217,217,217,1,216,216,216,1,0,0,0,1,214,214,214,1,212, + 212,212,1,211,211,211,1,210,210,210,1,224,224,224,1,255,255,255,1,128, + 128,128,1,0,0,0,1,231,231,231,1,0,0,0,1,229,229,229,1,0, + 0,0,1,227,227,227,1,0,0,0,1,224,224,224,1,0,0,0,1,222, + 222,222,1,0,0,0,1,220,220,220,1,0,0,0,1,218,218,218,1,108, + 108,108,1,216,216,216,1,0,0,0,1,214,214,214,1,212,212,212,1,211, + 211,211,1,210,210,210,1,224,224,224,1,255,255,255,1,128,128,128,1,0, + 0,0,1,231,231,231,1,0,0,0,1,229,229,229,1,0,0,0,1,227, + 227,227,1,0,0,0,1,224,224,224,1,0,0,0,1,222,222,222,1,0, + 0,0,1,220,220,220,1,0,0,0,1,218,218,218,1,0,0,0,1,216, + 216,216,1,0,0,0,1,214,214,214,1,106,106,106,1,211,211,211,1,210, + 210,210,1,224,224,224,1,255,255,255,1,128,128,128,1,0,0,0,1,231, + 231,231,1,0,0,0,1,229,229,229,1,0,0,0,1,227,227,227,1,0, + 0,0,1,224,224,224,1,0,0,0,1,222,222,222,1,0,0,0,1,220, + 220,220,1,0,0,0,1,218,218,218,1,0,0,0,1,216,216,216,1,0, + 0,0,1,214,214,214,1,0,0,0,1,211,211,211,1,210,210,210,1,224, + 224,224,1,255,255,255,1,128,128,128,1,224,224,224,22,255,255,255,25,12, + 0,0,0,255,255,255,255,255,255,255,255,255,255,255,66,0,0) + ); + +const + objdata_tpickwidget: record size: integer; data: array[0..2530] of byte end = + (size: 2531; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,112,105, + 99,107,119,105,100,103,101,116,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,108,9,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,156,4,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,128,128,128,25,208,208,208,14,0,0,255, + 2,208,208,208,6,255,255,255,1,128,128,128,1,208,208,208,4,0,0,0, + 3,208,208,208,1,0,0,0,3,208,208,208,1,0,0,0,1,0,0,17, + 1,4,4,123,1,6,6,255,1,0,0,0,2,208,208,208,4,255,255,255, + 1,128,128,128,1,208,208,208,4,0,0,0,1,208,208,208,7,0,0,255, + 1,34,34,255,1,136,136,255,1,71,71,255,1,0,0,213,1,0,0,0, + 1,208,208,208,4,255,255,255,1,128,128,128,1,208,208,208,4,0,0,0, + 1,208,208,208,5,0,0,255,1,2,2,255,1,75,75,255,1,175,175,255, + 1,82,82,255,1,5,5,255,1,0,0,255,1,208,208,208,5,255,255,255, + 1,128,128,128,1,208,208,208,9,0,0,255,1,14,14,255,1,119,119,255, + 1,143,143,255,1,28,28,255,1,0,0,255,1,208,208,208,1,0,0,0, + 2,208,208,208,4,255,255,255,1,128,128,128,1,208,208,208,4,0,0,0, + 1,208,208,208,3,0,0,255,1,42,42,255,1,160,160,255,1,81,81,255, + 1,4,4,255,1,0,0,255,1,208,208,208,2,0,0,0,2,208,208,208, + 4,255,255,255,1,128,128,128,1,208,208,208,4,0,0,0,1,208,208,208, + 1,0,0,255,1,4,4,255,1,86,86,255,1,142,142,255,1,26,26,255, + 1,0,0,255,1,208,208,208,4,0,0,0,2,208,208,208,4,255,255,255, + 1,128,128,128,1,208,208,208,4,0,0,0,1,0,0,255,1,17,17,255, + 1,132,132,255,1,80,80,255,1,4,4,255,1,0,0,255,1,208,208,208, + 11,255,255,255,1,128,128,128,1,208,208,208,4,0,0,255,1,46,46,255, + 1,130,130,255,1,26,26,255,1,0,0,255,1,208,208,208,4,9,9,9, + 1,0,0,0,1,208,208,208,1,0,0,0,2,208,208,208,4,255,255,255, + 1,128,128,128,1,208,208,208,3,0,0,255,1,9,9,74,1,97,97,255, + 1,5,5,255,1,0,0,255,1,208,208,208,5,29,29,29,1,32,32,32, + 1,17,17,17,1,0,0,0,2,208,208,208,4,255,255,255,1,128,128,128, + 1,208,208,208,4,0,0,11,1,3,3,255,1,0,0,255,3,208,208,208, + 4,37,37,37,1,185,185,185,1,49,49,49,1,24,24,24,1,0,0,0, + 1,208,208,208,4,255,255,255,1,128,128,128,1,208,208,208,4,0,0,0, + 1,208,208,208,1,0,0,255,5,208,208,208,2,37,37,37,1,236,236,236, + 1,246,246,246,1,101,101,101,1,29,29,29,1,8,8,8,1,208,208,208, + 3,255,255,255,1,128,128,128,1,208,208,208,7,0,0,255,6,36,36,36, + 1,239,239,239,1,255,255,255,2,174,174,174,1,34,34,34,1,19,19,19, + 1,0,0,0,1,208,208,208,1,255,255,255,1,128,128,128,1,208,208,208, + 4,0,0,0,3,208,208,208,1,0,0,0,1,0,0,6,1,0,0,207, + 1,0,0,255,1,0,0,87,1,36,36,36,1,239,239,239,1,255,255,255, + 2,195,195,195,1,52,52,52,1,18,18,18,1,0,0,0,1,208,208,208, + 1,255,255,255,1,128,128,128,1,208,208,208,4,0,0,0,3,208,208,208, + 1,0,0,146,1,0,0,106,1,0,0,0,1,0,0,255,1,0,0,242, + 1,37,37,42,1,239,239,239,1,192,192,192,1,163,163,163,1,19,19,19, + 1,15,15,15,1,0,0,0,1,208,208,208,2,255,255,255,1,128,128,128, + 1,208,208,208,8,12,12,255,1,17,17,255,1,208,208,208,1,0,0,255, + 2,34,34,38,1,51,51,51,1,24,24,24,1,100,100,100,1,105,105,105, + 1,23,23,23,1,208,208,208,3,255,255,255,1,128,128,128,1,208,208,208, + 7,0,0,255,1,72,72,255,1,64,64,255,1,0,0,255,3,9,9,9, + 1,18,18,18,1,0,0,0,1,38,38,38,1,243,243,243,1,48,48,48, + 1,17,17,17,1,208,208,208,2,255,255,255,1,128,128,128,1,208,208,208, + 7,52,52,255,1,140,140,255,1,55,55,255,1,0,0,255,2,208,208,208, + 1,0,0,0,1,208,208,208,2,32,32,32,1,182,182,182,1,206,206,206, + 1,32,32,32,1,0,0,0,1,208,208,208,1,255,255,255,1,128,128,128, + 1,208,208,208,6,27,27,255,1,130,130,255,1,169,169,255,1,94,94,255, + 1,34,34,255,1,0,0,255,3,208,208,208,2,17,17,17,1,86,86,86, + 1,255,255,255,1,134,134,134,1,27,27,27,1,0,0,0,1,255,255,255, + 1,128,128,128,1,208,208,208,6,97,97,255,1,171,171,255,1,108,108,255, + 1,42,42,255,1,0,0,255,4,208,208,208,2,0,0,0,1,39,39,39, + 1,243,243,243,1,148,148,148,1,28,28,28,1,7,7,7,1,255,255,255, + 1,128,128,128,1,208,208,208,5,27,27,255,1,127,127,255,1,75,75,255, + 1,22,22,255,1,0,0,255,1,208,208,208,7,29,29,29,1,34,34,34, + 1,30,30,30,1,12,12,12,1,208,208,208,1,255,255,255,1,128,128,128, + 1,208,208,208,5,0,0,255,1,208,208,208,11,12,12,12,1,9,9,9, + 1,208,208,208,3,255,255,255,25,152,4,0,0,255,255,255,25,0,0,0, + 14,15,15,15,1,17,17,17,1,0,0,0,6,255,255,255,2,0,0,0, + 4,140,140,140,1,186,186,186,1,99,99,99,1,0,0,0,1,88,88,88, + 1,186,186,186,1,105,105,105,1,0,0,0,1,76,76,76,1,199,199,199, + 1,214,214,214,1,134,134,134,1,70,70,70,1,181,181,181,1,0,0,0, + 4,255,255,255,2,0,0,0,4,186,186,186,1,0,0,0,7,96,96,96, + 1,193,193,193,1,253,253,253,1,187,187,187,1,24,24,24,1,124,124,124, + 1,0,0,0,4,255,255,255,2,0,0,0,4,6,6,6,1,0,0,0, + 5,7,7,7,1,146,146,146,1,208,208,208,1,255,255,255,1,200,200,200, + 1,150,150,150,1,15,15,15,1,0,0,0,5,255,255,255,2,0,0,0, + 9,32,32,32,1,176,176,176,1,230,230,230,1,232,232,232,1,183,183,183, + 1,71,71,71,1,0,0,0,1,1,1,1,1,56,56,56,1,0,0,0, + 4,255,255,255,2,0,0,0,4,175,175,175,1,0,0,0,3,74,74,74, + 1,188,188,188,1,248,248,248,1,199,199,199,1,142,142,142,1,12,12,12, + 1,0,0,0,2,6,6,6,1,181,181,181,1,0,0,0,4,255,255,255, + 2,0,0,0,4,186,186,186,1,0,0,0,1,2,2,2,1,127,127,127, + 1,201,201,201,1,228,228,228,1,183,183,183,1,60,60,60,1,0,0,0, + 4,4,4,4,1,130,130,130,1,0,0,0,4,255,255,255,2,0,0,0, + 4,18,18,18,1,20,20,20,1,166,166,166,1,220,220,220,1,197,197,197, + 1,132,132,132,1,8,8,8,1,0,0,0,11,255,255,255,2,0,0,0, + 4,55,55,55,1,184,184,184,1,216,216,216,1,179,179,179,1,49,49,49, + 1,0,0,0,4,191,191,191,1,30,30,30,1,0,0,0,1,1,1,1, + 1,45,45,45,1,0,0,0,4,255,255,255,2,0,0,0,3,33,33,33, + 1,238,238,238,1,226,226,226,1,203,203,203,1,10,10,10,1,0,0,0, + 5,248,248,248,1,249,249,249,1,108,108,108,1,6,6,6,1,181,181,181, + 1,0,0,0,4,255,255,255,2,0,0,0,4,194,194,194,1,159,159,159, + 1,206,206,206,1,189,189,189,1,64,64,64,1,0,0,0,4,247,247,247, + 1,255,255,255,1,253,253,253,1,202,202,202,1,142,142,142,1,0,0,0, + 4,255,255,255,2,0,0,0,4,23,23,23,1,0,0,0,1,61,61,61, + 1,180,180,180,1,207,207,207,1,154,154,154,1,21,21,21,1,0,0,0, + 2,247,247,247,1,255,255,255,3,243,243,243,1,63,63,63,1,0,0,0, + 3,255,255,255,2,0,0,0,7,2,2,2,1,101,101,101,1,196,196,196, + 1,200,200,200,1,101,101,101,1,1,1,1,1,248,248,248,1,255,255,255, + 4,252,252,252,1,159,159,159,1,3,3,3,1,0,0,0,1,255,255,255, + 2,0,0,0,4,172,172,172,1,181,181,181,1,23,23,23,1,0,0,0, + 1,158,158,158,1,185,185,185,1,150,150,150,1,206,206,206,1,223,223,223, + 1,253,253,253,1,255,255,255,4,254,254,254,1,245,245,245,1,66,66,66, + 1,0,0,0,1,255,255,255,2,0,0,0,4,12,12,12,2,1,1,1, + 1,0,0,0,1,23,23,23,1,21,21,21,1,1,1,1,1,38,38,38, + 1,172,172,172,1,254,254,254,1,255,255,255,3,254,254,254,1,138,138,138, + 1,7,7,7,1,0,0,0,2,255,255,255,2,0,0,0,8,124,124,124, + 1,59,59,59,1,0,0,0,1,5,5,5,1,141,141,141,1,253,253,253, + 1,254,254,254,1,248,248,248,1,255,255,255,2,208,208,208,1,0,0,0, + 3,255,255,255,2,0,0,0,7,31,31,31,1,223,223,223,1,96,96,96, + 1,33,33,33,1,180,180,180,1,88,88,88,1,223,223,223,1,102,102,102, + 1,30,30,30,1,252,252,252,1,255,255,255,1,253,253,253,1,120,120,120, + 1,0,0,0,2,255,255,255,2,0,0,0,7,149,149,149,1,255,255,255, + 1,165,165,165,1,148,148,148,1,19,19,19,1,0,0,0,1,2,2,2, + 1,0,0,0,2,234,234,234,1,255,255,255,2,250,250,250,1,37,37,37, + 1,0,0,0,1,255,255,255,2,0,0,0,6,57,57,57,1,240,240,240, + 1,255,255,255,1,239,239,239,1,183,183,183,1,136,136,136,1,87,87,87, + 1,16,16,16,1,0,0,0,2,138,138,138,1,255,255,255,3,233,233,233, + 1,5,5,5,1,255,255,255,2,0,0,0,6,173,173,173,1,255,255,255, + 2,239,239,239,1,191,191,191,1,139,139,139,1,88,88,88,1,15,15,15, + 1,0,0,0,2,24,24,24,1,251,251,251,1,255,255,255,2,253,253,253, + 1,111,111,111,1,255,255,255,2,0,0,0,5,84,84,84,1,193,193,193, + 1,144,144,144,1,94,94,94,1,22,22,22,1,0,0,0,7,230,230,230, + 1,254,254,254,1,233,233,233,1,84,84,84,1,0,0,0,1,255,255,255, + 2,0,0,0,5,3,3,3,1,0,0,0,11,86,86,86,1,83,83,83, + 1,0,0,0,3,255,255,255,25,0,0) + ); + +const + objdata_ttraywidget: record size: integer; data: array[0..2186] of byte end = + (size: 2187; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,116,116,114, + 97,121,119,105,100,103,101,116,23,98,105,116,109,97,112,46,116,114,97,110, + 115,112,97,114,101,110,116,99,111,108,111,114,4,6,0,0,128,14,98,105, + 116,109,97,112,46,111,112,116,105,111,110,115,11,10,98,109,111,95,109,97, + 115,107,101,100,13,98,109,111,95,99,111,108,111,114,109,97,115,107,0,12, + 98,105,116,109,97,112,46,105,109,97,103,101,10,20,8,0,0,0,0,0, + 0,6,0,0,0,24,0,0,0,24,0,0,0,152,3,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,128,128,128,25,208,208,208,14,0,0,255, + 2,208,208,208,6,255,255,255,1,128,128,128,1,208,208,208,13,0,0,255, + 1,7,7,255,1,6,6,255,1,208,208,208,6,255,255,255,1,128,128,128, + 1,208,208,208,12,0,0,255,1,34,34,255,1,136,136,255,1,71,71,255, + 1,0,0,255,1,208,208,208,5,255,255,255,1,128,128,128,1,208,208,208, + 10,0,0,255,1,2,2,255,1,75,75,255,1,175,175,255,1,82,82,255, + 1,5,5,255,1,0,0,255,1,208,208,208,5,255,255,255,1,128,128,128, + 1,208,208,208,9,0,0,255,1,14,14,255,1,119,119,255,1,143,143,255, + 1,28,28,255,1,0,0,255,1,208,208,208,7,255,255,255,1,128,128,128, + 1,208,208,208,8,0,0,255,1,42,42,255,1,160,160,255,1,81,81,255, + 1,4,4,255,1,0,0,255,1,208,208,208,8,255,255,255,1,128,128,128, + 1,0,0,0,6,0,0,32,1,4,4,255,1,86,86,255,1,142,142,255, + 1,26,26,255,1,0,0,255,1,208,208,208,10,255,255,255,1,128,128,128, + 1,0,0,0,5,0,0,3,1,7,7,104,1,132,132,255,1,80,80,255, + 1,4,4,255,1,0,0,255,1,208,208,208,11,255,255,255,1,128,128,128, + 1,208,208,208,2,0,0,0,2,0,0,255,1,46,46,255,1,130,130,255, + 1,26,26,255,1,0,0,255,1,208,208,208,13,255,255,255,1,128,128,128, + 1,208,208,208,2,0,0,0,1,0,0,4,1,28,28,255,1,97,97,255, + 1,5,5,255,1,0,0,4,1,0,0,0,10,208,208,208,2,0,0,0, + 2,255,255,255,1,128,128,128,1,208,208,208,2,0,0,0,2,0,0,255, + 1,3,3,255,1,0,0,255,1,0,0,28,1,0,0,44,1,0,0,0, + 10,208,208,208,1,0,0,0,2,255,255,255,1,128,128,128,1,208,208,208, + 2,0,0,0,2,208,208,208,2,0,0,255,1,0,0,27,1,0,0,195, + 1,0,0,255,2,0,0,0,5,208,208,208,1,0,0,0,5,255,255,255, + 1,128,128,128,1,208,208,208,2,0,0,0,2,208,208,208,3,0,0,0, + 1,0,0,180,1,0,0,255,1,0,0,219,1,0,0,11,1,0,0,1, + 1,0,0,0,3,208,208,208,1,0,0,0,4,208,208,208,1,255,255,255, + 1,128,128,128,1,208,208,208,2,0,0,0,2,208,208,208,3,0,0,0, + 2,0,0,255,1,0,0,132,1,0,0,57,1,0,0,255,2,0,0,0, + 2,208,208,208,2,0,0,0,3,208,208,208,1,255,255,255,1,128,128,128, + 1,208,208,208,2,0,0,0,2,208,208,208,3,0,0,0,1,0,0,64, + 1,0,0,255,1,0,0,0,1,0,0,11,1,0,0,46,1,0,0,52, + 1,0,0,69,1,0,0,0,1,208,208,208,2,0,0,0,3,208,208,208, + 1,255,255,255,1,128,128,128,1,208,208,208,8,12,12,255,1,17,17,255, + 1,208,208,208,1,0,0,255,1,0,0,229,1,0,0,254,1,0,0,255, + 1,208,208,208,3,0,0,0,2,208,208,208,2,255,255,255,1,128,128,128, + 1,208,208,208,7,0,0,255,1,72,72,255,1,64,64,255,1,0,0,255, + 3,208,208,208,4,0,0,0,3,208,208,208,2,255,255,255,1,128,128,128, + 1,208,208,208,7,52,52,255,1,140,140,255,1,55,55,255,1,0,0,255, + 2,208,208,208,5,0,0,0,2,208,208,208,3,255,255,255,1,128,128,128, + 1,208,208,208,6,27,27,255,1,130,130,255,1,169,169,255,1,94,94,255, + 1,34,34,255,1,0,0,255,3,208,208,208,8,255,255,255,1,128,128,128, + 1,208,208,208,6,97,97,255,1,171,171,255,1,108,108,255,1,42,42,255, + 1,0,0,255,4,208,208,208,8,255,255,255,1,128,128,128,1,208,208,208, + 5,27,27,255,1,127,127,255,1,75,75,255,1,22,22,255,1,0,0,255, + 1,208,208,208,12,255,255,255,1,128,128,128,1,208,208,208,5,0,0,255, + 1,208,208,208,16,255,255,255,25,68,4,0,0,255,255,255,25,0,0,0, + 14,15,15,15,1,17,17,17,1,0,0,0,6,255,255,255,2,0,0,0, + 13,47,47,47,1,182,182,182,1,134,134,134,1,0,0,0,6,255,255,255, + 2,0,0,0,12,96,96,96,1,193,193,193,1,253,253,253,1,187,187,187, + 1,20,20,20,1,0,0,0,5,255,255,255,2,0,0,0,10,7,7,7, + 1,146,146,146,1,208,208,208,1,255,255,255,1,200,200,200,1,150,150,150, + 1,15,15,15,1,0,0,0,5,255,255,255,2,0,0,0,9,32,32,32, + 1,176,176,176,1,230,230,230,1,232,232,232,1,183,183,183,1,71,71,71, + 1,0,0,0,7,255,255,255,2,0,0,0,8,74,74,74,1,188,188,188, + 1,248,248,248,1,199,199,199,1,142,142,142,1,12,12,12,1,0,0,0, + 8,255,255,255,2,19,19,19,1,24,24,24,5,15,15,15,1,127,127,127, + 1,201,201,201,1,228,228,228,1,183,183,183,1,60,60,60,1,0,0,0, + 10,255,255,255,2,183,183,183,1,224,224,224,1,229,229,229,1,252,252,252, + 1,224,224,224,1,226,226,226,1,209,209,209,1,220,220,220,1,197,197,197, + 1,132,132,132,1,8,8,8,1,0,0,0,11,255,255,255,2,0,0,0, + 2,41,41,41,1,230,230,230,1,55,55,55,1,184,184,184,1,216,216,216, + 1,179,179,179,1,49,49,49,1,0,0,0,13,255,255,255,2,0,0,0, + 2,41,41,41,1,233,233,233,1,206,206,206,1,226,226,226,1,203,203,203, + 1,188,188,188,1,140,140,140,1,230,230,230,1,39,39,39,1,101,101,101, + 1,213,213,213,1,226,226,226,1,200,200,200,1,39,39,39,1,50,50,50, + 1,178,178,178,1,0,0,0,2,43,43,43,1,165,165,165,1,255,255,255, + 2,0,0,0,2,41,41,41,1,230,230,230,1,30,30,30,1,159,159,159, + 1,206,206,206,1,246,246,246,1,169,169,169,1,32,32,32,1,23,23,23, + 1,210,210,210,1,18,18,18,1,1,1,1,1,144,144,144,1,146,146,146, + 1,1,1,1,1,225,225,225,1,40,40,40,1,0,0,0,1,138,138,138, + 1,109,109,109,1,255,255,255,2,0,0,0,2,41,41,41,1,230,230,230, + 1,0,0,0,2,61,61,61,1,244,244,244,1,217,217,217,1,154,154,154, + 1,21,21,21,1,14,14,14,1,79,79,79,1,127,127,127,1,199,199,199, + 1,163,163,163,1,0,0,0,1,131,131,131,1,132,132,132,1,2,2,2, + 1,223,223,223,1,20,20,20,1,255,255,255,2,0,0,0,2,41,41,41, + 1,230,230,230,1,0,0,0,3,219,219,219,1,123,123,123,1,196,196,196, + 1,206,206,206,1,239,239,239,1,143,143,143,1,83,83,83,1,120,120,120, + 1,164,164,164,1,0,0,0,1,36,36,36,1,222,222,222,1,68,68,68, + 1,176,176,176,1,0,0,0,1,255,255,255,2,0,0,0,2,41,41,41, + 1,230,230,230,1,0,0,0,3,219,219,219,1,36,36,36,1,15,15,15, + 1,176,176,176,1,242,242,242,1,179,179,179,1,46,46,46,1,170,170,170, + 1,168,168,168,1,0,0,0,2,195,195,195,1,193,193,193,1,82,82,82, + 1,0,0,0,1,255,255,255,2,0,0,0,2,41,41,41,1,230,230,230, + 1,0,0,0,3,219,219,219,1,48,48,48,1,9,9,9,1,11,11,11, + 1,206,206,206,1,233,233,233,1,244,244,244,1,198,198,198,1,196,196,196, + 1,0,0,0,2,99,99,99,1,237,237,237,1,6,6,6,1,0,0,0, + 1,255,255,255,2,0,0,0,8,124,124,124,1,59,59,59,1,0,0,0, + 1,5,5,5,1,148,148,148,1,177,177,177,1,27,27,27,1,0,0,0, + 3,95,95,95,1,144,144,144,1,0,0,0,2,255,255,255,2,0,0,0, + 7,31,31,31,1,223,223,223,1,96,96,96,1,33,33,33,1,180,180,180, + 1,88,88,88,1,0,0,0,4,154,154,154,1,221,221,221,1,34,34,34, + 1,0,0,0,2,255,255,255,2,0,0,0,7,149,149,149,1,255,255,255, + 1,165,165,165,1,148,148,148,1,19,19,19,1,0,0,0,5,73,73,73, + 1,37,37,37,1,0,0,0,3,255,255,255,2,0,0,0,6,57,57,57, + 1,240,240,240,1,255,255,255,1,239,239,239,1,183,183,183,1,136,136,136, + 1,87,87,87,1,16,16,16,1,0,0,0,8,255,255,255,2,0,0,0, + 6,173,173,173,1,255,255,255,2,239,239,239,1,191,191,191,1,139,139,139, + 1,88,88,88,1,15,15,15,1,0,0,0,8,255,255,255,2,0,0,0, + 5,84,84,84,1,193,193,193,1,144,144,144,1,94,94,94,1,22,22,22, + 1,0,0,0,12,255,255,255,2,0,0,0,5,3,3,3,1,0,0,0, + 16,255,255,255,25,0,0) + ); + +const + objdata_tdockpanelformcontroller: record size: integer; data: array[0..2527] of byte end = + (size: 2528; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,24,116,100,111, + 99,107,112,97,110,101,108,102,111,114,109,99,111,110,116,114,111,108,108,101, + 114,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110,116, + 99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111,112, + 116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98,109, + 111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112,46, + 105,109,97,103,101,10,92,9,0,0,0,0,0,0,6,0,0,0,24,0, + 0,0,24,0,0,0,140,7,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,3,3,4,1,5,5,7,1,17,17,22,1,178,178,230,1,180,180, + 231,1,113,113,143,1,6,6,7,2,49,49,61,1,193,193,234,1,195,195, + 235,1,71,71,85,1,6,6,7,2,98,98,114,1,207,207,238,1,210,210, + 239,1,33,33,37,1,7,7,7,2,185,185,204,1,222,222,243,1,212,212, + 230,1,4,4,4,1,113,113,151,1,255,255,255,22,7,7,7,1,171,171, + 228,1,255,255,255,1,242,166,149,1,221,216,211,1,242,166,149,1,140,74, + 60,1,148,78,63,1,180,95,77,1,208,109,89,1,213,112,91,1,246,129, + 105,1,210,110,90,1,251,132,107,1,255,134,109,3,160,160,160,6,128,128, + 128,1,26,26,28,1,171,171,228,1,255,255,255,1,221,216,211,1,7,239, + 255,1,221,216,211,1,138,73,59,1,183,96,78,2,170,89,73,1,189,99, + 81,1,153,80,65,1,158,83,68,1,199,105,85,1,255,134,109,3,160,160, + 160,1,212,212,240,1,128,128,128,1,160,160,160,1,220,220,242,1,128,128, + 128,2,227,227,244,1,14,14,18,1,255,255,255,1,242,166,149,1,221,216, + 211,1,242,166,149,1,211,111,90,1,255,134,109,1,219,115,94,1,215,113, + 92,1,187,98,80,1,220,116,94,1,185,97,79,1,231,121,99,1,255,134, + 109,3,160,160,160,1,212,212,240,1,128,128,128,1,160,160,160,1,220,220, + 242,1,128,128,128,2,227,227,244,1,5,5,7,1,255,255,255,1,151,24, + 0,14,128,128,128,7,124,124,133,1,11,11,14,1,255,255,255,1,175,175, + 229,1,178,178,230,1,180,180,231,1,183,183,231,1,185,185,232,1,188,188, + 233,1,190,190,233,1,193,193,234,1,195,195,235,1,197,197,236,1,200,200, + 236,1,202,202,237,1,205,205,238,1,207,207,238,1,210,210,239,1,212,212, + 240,1,215,215,240,1,217,217,241,1,220,220,242,1,222,222,243,1,128,128, + 128,1,7,7,7,1,171,171,228,1,255,255,255,1,175,175,229,1,178,178, + 230,1,180,180,231,1,183,183,231,1,185,185,232,1,188,188,233,1,190,190, + 233,1,193,193,234,1,195,195,235,1,197,197,236,1,200,200,236,1,202,202, + 237,1,205,205,238,1,207,207,238,1,210,210,239,1,212,212,240,1,255,255, + 255,1,128,128,128,1,255,255,255,1,128,128,128,2,7,7,7,1,171,171, + 228,1,255,255,255,1,175,175,229,1,178,178,230,1,180,180,231,1,183,183, + 231,1,185,185,232,1,188,188,233,1,190,190,233,1,193,193,234,1,195,195, + 235,1,197,197,236,1,200,200,236,1,202,202,237,1,205,205,238,1,207,207, + 238,1,210,210,239,1,212,212,240,1,255,255,255,1,128,128,128,1,255,255, + 255,1,128,128,128,2,70,70,75,1,120,120,160,1,255,255,255,1,175,175, + 229,1,178,178,230,1,180,180,231,1,183,183,231,1,185,185,232,1,188,188, + 233,1,190,190,233,1,193,193,234,1,195,195,235,1,197,197,236,1,200,200, + 236,1,202,202,237,1,205,205,238,1,207,207,238,1,210,210,239,1,212,212, + 240,1,255,255,255,1,128,128,128,1,255,255,255,1,128,128,128,2,227,227, + 244,1,5,5,7,1,255,255,255,1,175,175,229,1,178,178,230,1,180,180, + 231,1,183,183,231,1,185,185,232,1,188,188,233,1,190,190,233,1,193,193, + 234,1,195,195,235,1,197,197,236,1,200,200,236,1,202,202,237,1,205,205, + 238,1,207,207,238,1,210,210,239,1,213,213,240,1,255,255,255,1,128,128, + 128,1,255,255,255,1,128,128,128,2,227,227,244,1,5,5,7,1,255,255, + 255,1,175,175,229,1,178,178,230,1,180,180,231,1,183,183,231,1,185,185, + 232,1,188,188,233,1,190,190,233,1,193,193,234,1,195,195,235,1,197,197, + 236,1,200,200,236,1,202,202,237,1,205,205,238,1,207,207,238,1,210,210, + 239,1,213,213,240,1,254,254,255,1,128,128,128,1,255,255,255,1,128,128, + 128,2,70,70,75,1,37,37,49,1,255,255,255,1,175,175,229,1,178,178, + 230,1,180,180,231,1,183,183,231,1,185,185,232,1,188,188,233,1,190,190, + 233,1,193,193,234,1,195,195,235,1,197,197,236,1,200,200,236,1,202,202, + 237,1,205,205,238,1,207,207,238,1,210,210,239,1,213,213,240,1,254,254, + 255,1,128,128,128,1,255,255,255,1,128,128,128,2,7,7,7,1,171,171, + 228,1,255,255,255,1,175,175,229,1,178,178,230,1,180,180,231,1,183,183, + 231,1,185,185,232,1,188,188,233,1,190,190,233,1,193,193,234,1,195,195, + 235,1,197,197,236,1,200,200,236,1,202,202,237,1,205,205,238,1,207,207, + 238,1,210,210,239,1,213,213,240,1,254,254,255,1,128,128,128,1,255,255, + 255,1,128,128,128,2,7,7,7,1,171,171,228,1,255,255,255,1,175,175, + 229,1,178,178,230,1,180,180,231,1,183,183,231,1,185,185,232,1,188,188, + 233,1,190,190,233,1,193,193,234,1,195,195,235,1,197,197,236,1,200,200, + 236,1,202,202,237,1,205,205,238,1,207,207,238,1,210,210,239,1,213,213, + 240,1,254,254,255,1,128,128,128,1,255,255,255,1,128,128,128,2,124,124, + 133,1,71,71,95,1,255,255,255,1,175,175,229,1,178,178,230,1,180,180, + 231,1,183,183,231,1,185,185,232,1,188,188,233,1,190,190,233,1,193,193, + 234,1,195,195,235,1,197,197,236,1,200,200,236,1,202,202,237,1,205,205, + 238,1,207,207,238,1,210,210,239,1,214,214,241,1,254,254,254,1,128,128, + 128,1,255,255,255,1,128,128,128,2,227,227,244,1,5,5,7,1,255,255, + 255,1,175,175,229,1,178,178,230,1,180,180,231,1,183,183,231,1,185,185, + 232,1,188,188,233,1,190,190,233,1,193,193,234,1,195,195,235,1,197,197, + 236,1,200,200,236,1,202,202,237,1,205,205,238,1,207,207,238,1,210,210, + 239,1,214,214,241,1,253,253,254,1,128,128,128,1,255,255,255,1,128,128, + 128,2,227,227,244,1,5,5,7,1,255,255,255,1,175,175,229,1,178,178, + 230,1,180,180,231,1,183,183,231,1,185,185,232,1,188,188,233,1,190,190, + 233,1,193,193,234,1,195,195,235,1,197,197,236,1,200,200,236,1,202,202, + 237,1,205,205,238,1,207,207,238,1,210,210,239,1,214,214,241,1,253,253, + 254,1,128,128,128,1,255,255,255,1,128,128,128,2,26,26,28,1,77,77, + 103,1,255,255,255,1,175,175,229,1,178,178,230,1,180,180,231,1,183,183, + 231,1,185,185,232,1,188,188,233,1,190,190,233,1,193,193,234,1,195,195, + 235,1,197,197,236,1,200,200,236,1,202,202,237,1,205,205,238,1,207,207, + 238,1,210,210,239,1,214,214,241,1,253,253,254,1,128,128,128,1,255,255, + 255,1,128,128,128,2,7,7,7,1,171,171,228,1,255,255,255,1,175,175, + 229,1,178,178,230,1,180,180,231,1,183,183,231,1,185,185,232,1,188,188, + 233,1,190,190,233,1,193,193,234,1,195,195,235,1,197,197,236,1,200,200, + 236,1,202,202,237,1,205,205,238,1,207,207,238,1,210,210,239,1,214,214, + 241,1,253,253,254,1,128,128,128,1,255,255,255,1,128,128,128,2,7,7, + 7,1,171,171,228,1,255,255,255,1,175,175,229,1,178,178,230,1,180,180, + 231,1,183,183,231,1,185,185,232,1,188,188,233,1,190,190,233,1,193,193, + 234,1,195,195,235,1,197,197,236,1,200,200,236,1,202,202,237,1,205,205, + 238,1,207,207,238,1,210,210,239,1,214,214,241,1,253,253,254,1,128,128, + 128,1,255,255,255,1,128,128,128,2,215,215,231,1,33,33,44,1,255,255, + 255,1,175,175,229,1,178,178,230,1,180,180,231,1,183,183,231,1,185,185, + 232,1,188,188,233,1,190,190,233,1,193,193,234,1,195,195,235,1,197,197, + 236,1,200,200,236,1,202,202,237,1,205,205,238,1,207,207,238,1,210,210, + 239,1,215,215,241,1,253,253,254,1,217,217,241,1,220,220,242,1,222,222, + 243,1,128,128,128,1,227,227,244,1,5,5,7,1,173,173,229,1,128,128, + 128,21,191,191,205,1,3,3,4,1,129,129,171,1,175,175,229,1,178,178, + 230,1,9,9,11,1,6,6,7,1,18,18,23,1,188,188,233,1,190,190, + 233,1,120,120,145,1,6,6,7,2,52,52,61,1,202,202,237,1,205,205, + 238,1,75,75,86,1,6,6,7,2,103,103,115,1,217,217,241,1,220,220, + 242,1,34,34,38,1,7,7,7,1,4,4,4,1,152,1,0,0,244,244, + 244,1,248,248,248,1,233,233,233,1,128,128,128,2,158,158,158,1,248,248, + 248,2,203,203,203,1,128,128,128,2,188,188,188,1,248,248,248,2,173,173, + 173,1,128,128,128,2,221,221,221,1,248,248,248,2,139,139,139,1,128,128, + 128,1,131,131,131,1,244,244,244,1,154,154,154,1,255,255,255,22,248,248, + 248,1,128,128,128,1,255,255,255,22,229,229,229,1,128,128,128,1,255,255, + 255,22,128,128,128,1,236,236,236,1,255,255,255,22,128,128,128,1,248,248, + 248,1,255,255,255,22,165,165,165,1,240,240,240,1,255,255,255,22,248,248, + 248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255, + 255,22,195,195,195,1,150,150,150,1,255,255,255,22,128,128,128,1,248,248, + 248,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,195,195, + 195,1,210,210,210,1,255,255,255,22,248,248,248,1,128,128,128,1,255,255, + 255,22,248,248,248,1,128,128,128,1,255,255,255,22,165,165,165,1,180,180, + 180,1,255,255,255,22,128,128,128,1,248,248,248,1,255,255,255,22,128,128, + 128,1,248,248,248,1,255,255,255,22,229,229,229,1,176,176,176,1,255,255, + 255,22,248,248,248,1,128,128,128,1,255,255,255,22,248,248,248,1,128,128, + 128,1,255,255,255,22,131,131,131,1,214,214,214,1,255,255,255,22,128,128, + 128,1,248,248,248,1,255,255,255,22,139,139,139,1,244,244,244,1,146,146, + 146,1,128,128,128,2,244,244,244,1,248,248,248,1,233,233,233,1,128,128, + 128,2,158,158,158,1,248,248,248,2,203,203,203,1,128,128,128,2,188,188, + 188,1,248,248,248,2,173,173,173,1,128,128,128,2,221,221,221,1,248,248, + 248,1,244,244,244,1,0,0) + ); + +const + objdata_ticon: record size: integer; data: array[0..880] of byte end = + (size: 881; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,5,116,105,99, + 111,110,23,98,105,116,109,97,112,46,116,114,97,110,115,112,97,114,101,110, + 116,99,111,108,111,114,4,6,0,0,128,14,98,105,116,109,97,112,46,111, + 112,116,105,111,110,115,11,10,98,109,111,95,109,97,115,107,101,100,13,98, + 109,111,95,99,111,108,111,114,109,97,115,107,0,12,98,105,116,109,97,112, + 46,105,109,97,103,101,10,0,3,0,0,0,0,0,0,6,0,0,0,24, + 0,0,0,24,0,0,0,228,1,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,171,171,171,198,255,255,255,1,255,211,189,1,253,209,189,1,251, + 201,179,1,247,192,169,1,243,184,160,1,239,176,149,1,235,168,139,1,231, + 159,129,1,226,152,119,1,224,145,110,1,255,255,0,1,171,171,171,11,255, + 207,191,1,255,208,190,1,251,200,180,1,247,192,170,1,243,184,160,1,239, + 176,150,1,235,169,139,1,231,161,129,1,228,153,119,1,224,145,109,1,220, + 137,99,1,216,129,89,1,213,121,79,1,207,112,68,1,171,171,171,9,255, + 208,192,1,251,201,181,1,247,193,170,1,243,185,160,1,239,177,150,1,236, + 169,140,1,232,161,130,1,228,153,120,1,224,145,110,1,220,137,100,1,216, + 129,89,1,212,121,79,1,208,113,69,1,205,105,59,1,201,97,49,1,197, + 88,38,1,171,171,171,8,247,192,171,1,244,185,161,1,240,177,151,1,236, + 169,141,1,232,161,131,1,228,154,120,1,224,146,110,1,220,138,100,1,216, + 130,90,1,213,122,80,1,209,114,70,1,205,106,60,1,201,98,50,1,197, + 90,39,1,193,82,29,1,189,75,19,1,171,171,171,8,240,178,151,1,236, + 170,141,1,232,162,131,1,228,154,121,1,224,146,111,1,221,138,101,1,217, + 130,91,1,213,122,80,1,209,114,70,1,205,106,60,1,201,98,50,1,197, + 91,40,1,193,82,30,1,190,75,20,1,186,67,10,1,182,59,0,1,171, + 171,171,8,231,165,133,1,229,154,122,1,225,147,111,1,221,139,101,1,217, + 131,91,1,213,123,81,1,209,115,71,1,205,107,61,1,201,99,51,1,198, + 91,41,1,194,83,31,1,190,75,21,1,186,67,10,1,182,59,0,2,180, + 59,0,1,171,171,171,9,224,139,100,1,217,130,92,1,213,123,82,1,209, + 115,72,1,206,107,62,1,202,99,51,1,198,91,41,1,194,83,31,1,190, + 76,21,1,186,68,11,1,182,60,1,1,182,59,0,2,185,62,0,1,171, + 171,171,12,201,107,67,1,202,101,53,1,198,92,43,1,195,84,32,1,190, + 76,22,1,186,68,12,1,183,60,2,1,182,58,0,1,183,58,0,1,188, + 54,0,1,171,171,171,199,228,0,0,0,0,0,0,198,1,1,1,1,58, + 58,58,1,143,143,143,1,192,192,192,1,217,217,217,1,243,243,243,2,217, + 217,217,1,192,192,192,1,143,143,143,1,58,58,58,1,1,1,1,1,0, + 0,0,11,64,64,64,1,222,222,222,1,255,255,255,10,222,222,222,1,64, + 64,64,1,0,0,0,9,93,93,93,1,253,253,253,1,255,255,255,12,253, + 253,253,1,93,93,93,1,0,0,0,8,212,212,212,1,255,255,255,14,212, + 212,212,1,0,0,0,8,193,193,193,1,255,255,255,14,193,193,193,1,0, + 0,0,8,65,65,65,1,241,241,241,1,255,255,255,12,241,241,241,1,65, + 65,65,1,0,0,0,9,33,33,33,1,182,182,182,1,251,251,251,1,255, + 255,255,8,251,251,251,1,182,182,182,1,33,33,33,1,0,0,0,12,19, + 19,19,1,96,96,96,1,144,144,144,1,169,169,169,1,195,195,195,2,169, + 169,169,1,144,144,144,1,96,96,96,1,19,19,19,1,0,0,0,199,0, + 0) + ); + +initialization + registerobjectdata(@objdata_tsimplewidget,tbitmapcomp,'tsimplewidget'); + registerobjectdata(@objdata_tbutton,tbitmapcomp,'tbutton'); + registerobjectdata(@objdata_tdrawgrid,tbitmapcomp,'tdrawgrid'); + registerobjectdata(@objdata_tstringgrid,tbitmapcomp,'tstringgrid'); + registerobjectdata(@objdata_tmainmenuwidget,tbitmapcomp,'tmainmenuwidget'); + registerobjectdata(@objdata_taction,tbitmapcomp,'taction'); + registerobjectdata(@objdata_tlabel,tbitmapcomp,'tlabel'); + registerobjectdata(@objdata_timage,tbitmapcomp,'timage'); + registerobjectdata(@objdata_tdispwidget,tbitmapcomp,'tdispwidget'); + registerobjectdata(@objdata_tintegerdisp,tbitmapcomp,'tintegerdisp'); + registerobjectdata(@objdata_tint64disp,tbitmapcomp,'tint64disp'); + registerobjectdata(@objdata_trealdisp,tbitmapcomp,'trealdisp'); + registerobjectdata(@objdata_tstringdisp,tbitmapcomp,'tstringdisp'); + registerobjectdata(@objdata_trichstringdisp,tbitmapcomp,'trichstringdisp'); + registerobjectdata(@objdata_tbooleandisp,tbitmapcomp,'tbooleandisp'); + registerobjectdata(@objdata_tedit,tbitmapcomp,'tedit'); + registerobjectdata(@objdata_ttoolbar,tbitmapcomp,'ttoolbar'); + registerobjectdata(@objdata_tsplitter,tbitmapcomp,'tsplitter'); + registerobjectdata(@objdata_tdockhandle,tbitmapcomp,'tdockhandle'); + registerobjectdata(@objdata_teventwidget,tbitmapcomp,'teventwidget'); + registerobjectdata(@objdata_tdockpanel,tbitmapcomp,'tdockpanel'); + registerobjectdata(@objdata_tstockglyphbutton,tbitmapcomp,'tstockglyphbutton'); + registerobjectdata(@objdata_tgroupbox,tbitmapcomp,'tgroupbox'); + registerobjectdata(@objdata_tscrollbox,tbitmapcomp,'tscrollbox'); + registerobjectdata(@objdata_tstepbox,tbitmapcomp,'tstepbox'); + registerobjectdata(@objdata_ttabbar,tbitmapcomp,'ttabbar'); + registerobjectdata(@objdata_ttabpage,tbitmapcomp,'ttabpage'); + registerobjectdata(@objdata_ttabwidget,tbitmapcomp,'ttabwidget'); + registerobjectdata(@objdata_tterminal,tbitmapcomp,'tterminal'); + registerobjectdata(@objdata_tmseformwidget,tbitmapcomp,'tmseformwidget'); + registerobjectdata(@objdata_tdockformwidget,tbitmapcomp,'tdockformwidget'); + registerobjectdata(@objdata_tpaintbox,tbitmapcomp,'tpaintbox'); + registerobjectdata(@objdata_texpandingwidget,tbitmapcomp,'texpandingwidget'); + registerobjectdata(@objdata_tspacer,tbitmapcomp,'tspacer'); + registerobjectdata(@objdata_tlayouter,tbitmapcomp,'tlayouter'); + registerobjectdata(@objdata_tdatetimedisp,tbitmapcomp,'tdatetimedisp'); + registerobjectdata(@objdata_tbytestringdisp,tbitmapcomp,'tbytestringdisp'); + registerobjectdata(@objdata_tlistview,tbitmapcomp,'tlistview'); + registerobjectdata(@objdata_tbarcode,tbitmapcomp,'tbarcode'); + registerobjectdata(@objdata_tdial,tbitmapcomp,'tdial'); + registerobjectdata(@objdata_tchart,tbitmapcomp,'tchart'); + registerobjectdata(@objdata_tchartrecorder,tbitmapcomp,'tchartrecorder'); + registerobjectdata(@objdata_twindowwidget,tbitmapcomp,'twindowwidget'); + registerobjectdata(@objdata_topenglwidget,tbitmapcomp,'topenglwidget'); + registerobjectdata(@objdata_topenglcanvaswidget,tbitmapcomp,'topenglcanvaswidget'); + registerobjectdata(@objdata_tpolygon,tbitmapcomp,'tpolygon'); + registerobjectdata(@objdata_trichbutton,tbitmapcomp,'trichbutton'); + registerobjectdata(@objdata_trichstockglyphbutton,tbitmapcomp,'trichstockglyphbutton'); + registerobjectdata(@objdata_txychartedit,tbitmapcomp,'txychartedit'); + registerobjectdata(@objdata_txserieschartedit,tbitmapcomp,'txserieschartedit'); + registerobjectdata(@objdata_tpickwidget,tbitmapcomp,'tpickwidget'); + registerobjectdata(@objdata_ttraywidget,tbitmapcomp,'ttraywidget'); + registerobjectdata(@objdata_tdockpanelformcontroller,tbitmapcomp,'tdockpanelformcontroller'); + registerobjectdata(@objdata_ticon,tbitmapcomp,'ticon'); +end. diff --git a/mseide-msegui/lib/common/regcomponents/regzeoslib.pas b/mseide-msegui/lib/common/regcomponents/regzeoslib.pas new file mode 100644 index 0000000..32c3697 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regzeoslib.pas @@ -0,0 +1,207 @@ +{ MSEide Copyright (c) 1999-2010 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit regzeoslib; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +implementation +uses + Classes,mclasses,msedesignintf,ZDataset,ZConnection,ZSqlUpdate, + ZStoredProcedure,ZSqlMetadata, + ZSqlProcessor,ZSqlMonitor,ZSequence,msezeos,regzeoslib_bmp,regdb, + msepropertyeditors,ZSqlStrings,ZAbstractRODataset,mseglob,msegui,mdb,msedb, + msetypes{msestrings}; + +type + tzprotocolpropertyeditor = class(tstringpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + function getvalues: msestringarty; override; + end; + + tzquerysqlpropertyeditor = class(tsqlpropertyeditor) + private + factivebefore: boolean; + protected + procedure doafterclosequery(var amodalresult: modalresultty); override; + function gettestbutton: boolean; override; + function getutf8: boolean; override; + public + procedure edit; override; + end; + + tzreadonlyquerysqlpropertyeditor = class(tsqlpropertyeditor) + private + factivebefore: boolean; + protected + procedure doafterclosequery(var amodalresult: modalresultty); override; + function gettestbutton: boolean; override; + function getutf8: boolean; override; + public + procedure edit; override; + end; + + tzcatalogpropertyeditor = class(tstringpropertyeditor) + protected + function getdefaultstate: propertystatesty; override; + public + function getvalues: msestringarty; override; + end; + +procedure Register; +begin + registercomponents('Zeos',[TZConnection, tmsezreadonlyquery, tmsezquery, + tmseztable, + TZUpdateSQL, tmsezstoredproc, TZSQLMetadata, TZSQLProcessor, + TZSQLMonitor, TZSequence, tmsezgraphicfield]); + registercomponenttabhints(['Zeos'],['ZeosLib database components']); + registerpropertyeditor(typeinfo(string),TZConnection,'Protocol', + tzprotocolpropertyeditor); + { + registerpropertyeditor(typeinfo(tstrings),TmseZreadonlyQuery,'SQL', + tzreadonlyquerysqlpropertyeditor); + registerpropertyeditor(typeinfo(tstrings),TmseZQuery,'SQL', + tzquerysqlpropertyeditor); + } + registerpropertyeditor(typeinfo(tstrings),TZUpdateSQL,'DeleteSQL', + tsqlpropertyeditor); + registerpropertyeditor(typeinfo(tstrings),TZUpdateSQL,'InsertSQL', + tsqlpropertyeditor); + registerpropertyeditor(typeinfo(tstrings),TZUpdateSQL,'ModifySQL', + tsqlpropertyeditor); + registerpropertyeditor(typeinfo(tstrings),TZUpdateSQL,'RefreshSQL', + tsqlpropertyeditor); + registerpropertyeditor(typeinfo(tstrings),TZSqlProcessor,'RefreshSQL', + tsqlpropertyeditor); + registerpropertyeditor(typeinfo(string),TZConnection,'Catalog', + tzcatalogpropertyeditor); + registerpropertyeditor(typeinfo(boolean),TZConnection,'Connected', + tvolatilebooleanpropertyeditor); +end; + +{ tzquerysqlpropertyeditor } + +procedure tzquerysqlpropertyeditor.doafterclosequery( + var amodalresult: modalresultty); +begin + if amodalresult = mr_canclose then begin + tmsezquery(fprops[0].instance).active:= true; + end; +end; + +function tzquerysqlpropertyeditor.gettestbutton: boolean; +begin + result:= true; +end; + +function tzquerysqlpropertyeditor.getutf8: boolean; +begin + result:= dso_utf8 in tmsezquery(fprops[0].instance).controller.options; +end; + +procedure tzquerysqlpropertyeditor.edit; +begin + factivebefore:= tmsezquery(fprops[0].instance).active; + inherited; + if not factivebefore then begin + tmsezquery(fprops[0].instance).active:= false; + end; +end; + +{ tzreadonlyquerysqlpropertyeditor } + +procedure tzreadonlyquerysqlpropertyeditor.doafterclosequery( + var amodalresult: modalresultty); +begin + if amodalresult = mr_canclose then begin + tmsezreadonlyquery(fprops[0].instance).active:= true; + end; +end; + +function tzreadonlyquerysqlpropertyeditor.gettestbutton: boolean; +begin + result:= true; +end; + +function tzreadonlyquerysqlpropertyeditor.getutf8: boolean; +begin + result:= dso_utf8 in tmsezreadonlyquery(fprops[0].instance).controller.options; +end; + +procedure tzreadonlyquerysqlpropertyeditor.edit; +begin + factivebefore:= tmsezreadonlyquery(fprops[0].instance).active; + inherited; + if not factivebefore then begin + tmsezreadonlyquery(fprops[0].instance).active:= false; + end; +end; + +{ tzprotocolpropertyeditor } + +function tzprotocolpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate + [ps_valuelist,ps_sortlist]; +end; + +function tzprotocolpropertyeditor.getvalues: msestringarty; +var + list1: tstringlist; + int1: integer; +begin + list1:= tstringlist.create; + try + tzconnection(fprops[0].instance).getprotocolnames(list1); + setlength(result,list1.count); + for int1:= 0 to high(result) do begin + result[int1]:= msestring(list1[int1]); + end; + finally + list1.free; + end; +end; + +{ tzcatalogpropertyeditor } + +function tzcatalogpropertyeditor.getdefaultstate: propertystatesty; +begin + result:= inherited getdefaultstate; + if tzconnection(fprops[0].instance).connected then begin + result:= result + [ps_valuelist,ps_sortlist]; + end; +end; + +function tzcatalogpropertyeditor.getvalues: msestringarty; +var + list1: tstringlist; + int1: integer; +begin + list1:= tstringlist.create; + try + tzconnection(fprops[0].instance).getcatalognames(list1); + setlength(result,list1.count); + for int1:= 0 to high(result) do begin + result[int1]:= msestring(list1[int1]); + end; + finally + list1.free; + end; +end; + +initialization + Register; +end. diff --git a/mseide-msegui/lib/common/regcomponents/regzeoslib_bmp.pas b/mseide-msegui/lib/common/regcomponents/regzeoslib_bmp.pas new file mode 100644 index 0000000..8f5e851 --- /dev/null +++ b/mseide-msegui/lib/common/regcomponents/regzeoslib_bmp.pas @@ -0,0 +1,696 @@ +unit regzeoslib_bmp; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,msebitmap; + +const + objdata_tmsezreadonlyquery: record size: integer; data: array[0..1238] of byte end = + (size: 1239; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,18,116,109,115, + 101,122,114,101,97,100,111,110,108,121,113,117,101,114,121,12,98,105,116,109, + 97,112,46,105,109,97,103,101,10,160,4,0,0,0,0,0,0,0,0,0, + 0,24,0,0,0,24,0,0,0,108,4,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,4,2,132,98,4,2,4,20,4,2,132,4,4,2,4, + 1,140,174,76,2,132,170,76,1,116,154,60,1,108,142,52,1,100,138,44, + 1,92,126,36,1,84,118,28,1,76,110,28,1,68,102,20,1,60,90,12, + 1,52,82,12,1,36,70,4,1,28,62,4,1,20,50,4,1,12,42,4, + 1,4,22,4,2,4,2,4,1,164,162,164,1,4,2,132,3,4,2,4, + 1,140,174,76,2,132,170,76,1,108,142,52,2,100,138,44,1,92,126,36, + 1,84,118,28,1,68,102,20,2,60,90,12,1,36,66,44,1,12,22,132, + 1,4,10,164,1,4,18,132,1,4,34,36,1,4,22,4,2,4,2,4, + 1,156,154,148,1,4,2,132,3,4,2,4,1,220,222,220,1,188,190,188, + 6,124,126,124,1,188,190,188,3,28,34,164,1,4,10,164,1,148,146,180, + 1,4,10,164,1,28,34,164,1,188,190,188,2,4,2,4,1,156,154,156, + 1,4,2,132,3,4,2,4,1,252,254,252,1,188,190,188,3,196,194,196, + 1,196,198,196,1,196,194,196,1,188,190,188,1,204,206,204,1,204,202,204, + 1,212,210,204,1,212,214,212,1,212,210,212,1,156,158,204,1,4,10,164, + 1,28,34,172,1,220,222,220,1,228,226,228,1,4,2,4,1,156,154,156, + 1,4,2,132,3,4,2,4,1,252,254,252,1,188,190,188,2,196,194,196, + 3,204,202,204,1,188,190,188,1,204,202,204,2,212,210,212,2,116,122,188, + 1,12,14,164,1,28,34,164,1,188,186,212,1,228,226,228,2,4,2,4, + 1,156,154,156,1,4,2,132,3,4,2,4,1,228,226,228,1,188,190,188, + 6,124,126,124,1,188,190,188,4,4,10,164,2,172,174,188,1,188,190,188, + 3,4,2,4,1,156,154,148,1,4,2,132,3,4,2,4,1,252,254,252, + 1,196,194,196,2,196,198,196,2,204,202,204,2,188,190,188,1,204,206,204, + 1,212,210,212,2,212,214,212,1,220,218,220,2,220,222,220,1,228,226,228, + 2,228,230,228,1,4,2,4,1,156,154,156,1,4,2,132,3,4,2,4, + 1,252,254,252,1,188,190,188,1,196,194,196,1,196,198,196,1,196,194,196, + 1,204,202,204,2,188,190,188,1,212,210,212,1,212,210,204,1,220,218,220, + 1,212,214,212,1,4,10,164,2,228,226,228,2,236,234,236,1,228,230,228, + 1,4,2,4,1,156,154,156,1,4,2,132,3,4,2,4,1,228,226,228, + 1,188,190,188,6,124,126,124,1,188,190,188,4,4,10,164,2,188,190,188, + 4,4,2,4,1,156,154,156,1,4,2,132,3,4,2,4,1,252,254,252, + 1,196,198,196,2,204,202,204,2,132,138,92,1,68,102,20,2,132,138,92, + 1,212,210,204,1,124,134,92,1,68,102,20,3,132,142,100,1,196,198,180, + 1,68,102,20,2,20,22,12,1,156,154,148,1,4,2,132,3,4,2,4, + 1,252,254,252,1,196,202,188,1,196,198,196,1,204,202,204,1,204,206,204, + 1,68,102,20,2,132,138,100,1,68,102,20,1,196,198,188,1,68,102,20, + 2,196,194,180,1,68,102,20,2,196,198,180,1,68,102,20,2,20,22,12, + 1,156,154,156,1,4,2,132,3,4,2,4,1,220,222,220,1,172,174,188, + 1,188,190,188,3,68,102,20,2,116,118,100,1,172,170,156,1,172,174,164, + 1,68,102,20,2,164,162,148,1,68,102,20,2,140,142,108,1,68,102,20, + 2,36,42,12,1,148,146,148,1,4,2,132,2,132,130,4,5,204,206,204, + 2,124,134,92,1,68,102,20,2,124,130,92,1,204,206,196,1,68,102,20, + 2,196,194,180,1,68,102,20,2,196,198,180,1,68,102,20,2,20,22,12, + 1,148,146,124,1,4,2,132,1,132,130,4,2,252,254,252,3,132,130,4, + 2,204,206,204,1,212,210,204,1,124,134,92,1,68,102,20,2,196,202,188, + 1,60,90,12,1,68,102,20,1,196,194,180,1,68,102,20,2,196,198,180, + 1,68,102,20,2,20,22,12,1,148,146,148,1,4,2,132,1,132,130,4, + 4,236,234,236,1,132,130,4,2,4,2,4,3,68,102,20,2,20,22,12, + 1,68,102,20,2,20,26,12,1,68,102,20,2,20,22,12,1,68,102,20, + 2,20,22,12,1,148,146,148,1,4,2,132,1,132,130,4,3,252,254,252, + 1,132,130,4,3,156,154,148,1,68,102,20,1,124,130,92,1,68,102,20, + 2,140,138,124,1,68,102,20,5,140,142,108,1,68,102,20,2,140,142,108, + 1,156,154,148,1,4,2,132,1,132,130,4,2,252,254,252,1,132,130,4, + 4,4,2,132,1,116,126,84,1,68,102,20,2,108,118,76,1,4,2,132, + 1,116,122,76,1,68,102,20,1,60,90,12,1,68,102,20,1,108,118,76, + 1,4,2,132,1,60,90,12,1,68,102,20,2,60,90,12,1,4,2,132, + 1,132,130,4,2,252,254,252,3,132,130,4,2,4,2,132,9,108,118,76, + 1,68,102,20,1,4,2,132,7,132,130,4,5,4,2,132,18,0,0) + ); + +const + objdata_tmsezquery: record size: integer; data: array[0..1270] of byte end = + (size: 1271; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,109,115, + 101,122,113,117,101,114,121,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,200,4,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0,0, + 0,148,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128, + 98,0,0,0,20,0,0,128,4,0,0,0,1,141,175,79,2,134,168,72, + 1,118,152,58,1,109,143,51,1,102,136,44,1,93,127,37,1,85,119,31, + 1,75,109,25,1,67,101,19,1,56,90,14,1,48,82,8,1,37,71,3, + 1,28,62,0,1,17,51,0,1,8,42,0,1,0,23,0,2,0,0,0, + 1,164,161,164,1,0,0,128,3,0,0,0,1,141,175,79,2,134,168,72, + 1,118,152,58,1,109,143,51,1,102,136,44,1,93,127,37,1,85,119,31, + 1,75,109,25,1,67,101,19,1,56,90,14,1,39,67,41,1,10,20,134, + 1,4,10,160,1,6,17,134,1,7,35,34,1,0,23,0,2,0,0,0, + 1,157,154,157,1,0,0,128,3,0,0,0,1,225,225,225,1,188,188,188, + 6,125,125,125,1,188,188,188,3,29,33,166,1,4,9,163,1,144,145,182, + 1,4,9,163,1,29,33,166,1,188,188,188,2,0,0,0,1,157,154,157, + 1,0,0,128,3,0,0,0,1,255,255,255,1,188,188,188,2,192,192,192, + 2,197,197,197,1,199,199,199,1,188,188,188,1,204,204,204,2,208,208,208, + 1,211,211,211,1,213,213,213,1,157,158,201,1,4,9,163,1,29,34,170, + 1,225,225,225,1,227,227,227,1,0,0,0,1,157,154,157,1,0,0,128, + 3,0,0,0,1,255,255,255,1,188,188,188,1,189,189,189,1,194,194,194, + 2,199,199,199,1,201,201,201,1,188,188,188,1,206,206,206,2,210,210,210, + 1,212,212,212,1,119,121,191,1,6,11,163,1,34,38,171,1,184,185,212, + 1,226,226,226,1,229,229,229,1,0,0,0,1,157,154,157,1,0,0,128, + 3,0,0,0,1,225,225,225,1,188,188,188,6,125,125,125,1,188,188,188, + 4,8,13,164,1,4,9,163,1,171,172,186,1,188,188,188,3,0,0,0, + 1,157,154,157,1,0,0,128,3,0,0,0,1,255,255,255,1,191,191,191, + 1,193,193,193,1,198,198,198,2,202,202,202,1,205,205,205,1,188,188,188, + 1,209,209,209,2,214,214,214,1,216,216,216,1,218,218,218,1,221,221,221, + 1,225,225,225,2,230,230,230,1,232,232,232,1,0,0,0,1,157,154,157, + 1,0,0,128,3,0,0,0,1,255,255,255,1,192,192,192,1,195,195,195, + 1,199,199,199,2,204,204,204,1,206,206,206,1,188,188,188,1,211,211,211, + 2,216,216,216,1,218,218,218,1,4,9,163,2,227,227,227,2,232,232,232, + 1,234,234,234,1,0,0,0,1,157,154,157,1,0,0,128,3,0,0,0, + 1,225,225,225,1,188,188,188,5,188,188,187,1,125,125,125,1,188,188,187, + 2,188,188,188,1,188,188,187,1,4,9,163,2,188,188,187,1,188,188,188, + 3,0,0,0,1,157,154,157,1,0,0,128,3,0,0,0,1,255,255,255, + 1,196,196,196,1,198,198,198,1,203,203,203,2,171,160,148,1,112,82,53, + 2,173,161,150,1,213,212,211,1,174,163,151,1,112,82,53,3,182,170,158, + 1,216,212,209,1,112,82,53,2,14,11,7,1,157,154,157,1,0,0,128, + 3,0,0,0,1,255,255,255,1,198,198,198,1,200,200,200,1,205,205,205, + 1,205,205,204,1,112,82,53,2,165,156,148,1,112,82,53,1,209,207,205, + 1,112,82,53,2,208,205,202,1,112,82,53,2,216,212,208,1,112,82,53, + 2,15,11,7,1,157,154,157,1,0,0,128,3,0,0,0,1,225,225,225, + 1,188,188,188,3,188,188,187,1,112,82,53,2,123,119,115,1,180,176,173, + 1,182,180,177,1,112,82,53,2,178,173,169,1,112,82,53,2,169,162,155, + 1,112,82,53,2,28,20,13,1,155,150,152,1,0,0,128,2,128,128,0, + 5,208,208,207,2,172,160,148,1,112,82,53,2,172,159,146,1,213,211,210, + 1,112,82,53,2,212,208,204,1,112,82,53,2,219,215,211,1,112,82,53, + 2,15,11,7,1,155,150,151,1,0,0,128,1,128,128,0,2,255,255,255, + 3,128,128,0,2,210,210,209,1,212,211,211,1,172,159,146,1,112,82,53, + 2,212,209,207,1,112,82,53,2,214,210,206,1,112,82,53,2,220,216,212, + 1,112,82,53,2,15,11,7,1,155,150,151,1,0,0,128,1,128,128,0, + 4,255,255,255,1,128,128,0,2,0,0,0,1,1,1,1,1,5,4,2, + 1,112,82,53,2,14,10,7,1,112,82,53,2,16,12,7,1,112,82,53, + 2,16,12,7,1,112,82,53,2,15,11,7,1,155,150,151,1,0,0,128, + 1,128,128,0,3,255,255,255,1,128,128,0,3,157,154,157,1,112,82,53, + 1,146,136,132,1,112,82,53,2,151,144,143,1,112,82,53,5,151,144,142, + 1,112,82,53,2,151,144,143,1,161,156,157,1,0,0,128,1,128,128,0, + 2,255,255,255,1,128,128,0,4,0,0,128,1,159,145,135,1,112,82,53, + 2,153,137,126,1,0,0,128,1,155,141,130,1,112,82,53,3,152,136,123, + 1,0,0,128,1,112,82,53,4,0,0,128,1,128,128,0,2,255,255,255, + 3,128,128,0,2,0,0,128,9,157,142,130,1,112,82,53,1,0,0,128, + 7,128,128,0,5,0,0,128,18,0,0) + ); + +const + objdata_tmseztable: record size: integer; data: array[0..1070] of byte end = + (size: 1071; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,116,109,115, + 101,122,116,97,98,108,101,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,0,4,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0,0, + 0,204,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128, + 98,0,0,0,20,0,0,128,4,0,0,0,1,141,175,79,2,134,168,72, + 1,118,152,58,1,109,143,51,1,102,136,44,1,93,127,37,1,85,119,31, + 1,75,109,25,1,67,101,19,1,56,90,14,1,48,82,8,1,37,71,3, + 1,28,62,0,1,17,51,0,1,8,42,0,1,0,23,0,2,0,0,0, + 1,164,161,164,1,0,0,128,3,0,0,0,1,141,175,79,2,134,168,72, + 1,118,152,58,1,109,143,51,1,102,136,44,1,93,127,37,1,85,119,31, + 1,75,109,25,1,67,101,19,1,56,90,14,1,48,82,8,1,37,71,3, + 1,28,62,0,1,17,51,0,1,8,42,0,1,0,23,0,2,0,0,0, + 1,157,154,157,1,0,0,128,3,0,0,0,1,225,225,225,1,188,188,188, + 6,125,125,125,1,188,188,188,10,0,0,0,1,157,154,157,1,0,0,128, + 3,0,0,0,1,255,255,255,1,188,188,188,2,192,192,192,2,197,197,197, + 1,199,199,199,1,188,188,188,1,204,204,204,2,208,208,208,1,211,211,211, + 1,213,213,213,1,215,215,215,1,220,220,220,2,225,225,225,1,227,227,227, + 1,0,0,0,1,157,154,157,1,0,0,128,3,0,0,0,1,255,255,255, + 1,188,188,188,1,189,189,189,1,194,194,194,2,199,199,199,1,201,201,201, + 1,188,188,188,1,206,206,206,2,210,210,210,1,212,212,212,1,215,215,215, + 1,217,217,217,1,222,222,222,2,226,226,226,1,229,229,229,1,0,0,0, + 1,157,154,157,1,0,0,128,3,0,0,0,1,225,225,225,1,188,188,188, + 6,125,125,125,1,188,188,188,10,0,0,0,1,157,154,157,1,0,0,128, + 3,0,0,0,1,255,255,255,1,191,191,191,1,193,193,193,1,198,198,198, + 2,202,202,202,1,205,205,205,1,188,188,188,1,209,209,209,2,214,214,214, + 1,216,216,216,1,218,218,218,1,221,221,221,1,225,225,225,2,230,230,230, + 1,232,232,232,1,0,0,0,1,157,154,157,1,0,0,128,3,0,0,0, + 1,255,255,255,1,192,192,192,1,195,195,195,1,199,199,199,2,204,204,204, + 1,206,206,206,1,188,188,188,1,211,211,211,2,216,216,216,1,218,218,218, + 1,220,220,220,1,223,223,223,1,227,227,227,2,232,232,232,1,234,234,234, + 1,0,0,0,1,157,154,157,1,0,0,128,3,0,0,0,1,225,225,225, + 1,188,188,188,6,125,125,125,1,188,188,188,10,0,0,0,1,157,154,157, + 1,0,0,128,3,0,0,0,1,255,255,255,1,196,196,196,1,198,198,198, + 1,203,203,203,2,208,208,208,1,210,210,210,1,188,188,188,1,215,215,215, + 2,214,214,214,1,216,216,216,1,218,218,218,1,221,221,221,1,231,231,231, + 2,235,235,235,1,238,238,238,1,0,0,0,1,157,154,157,1,0,0,128, + 3,0,0,0,1,255,255,255,1,198,198,198,1,200,200,200,1,205,205,205, + 2,209,209,209,1,212,212,212,1,188,188,188,1,216,216,216,3,218,218,218, + 1,220,220,220,1,223,223,223,1,233,233,233,2,237,237,237,1,240,240,240, + 1,0,0,0,1,157,154,157,1,0,0,128,3,0,0,0,1,225,225,225, + 1,188,188,188,6,125,125,125,1,188,188,188,10,0,0,0,1,157,154,157, + 1,0,0,128,2,128,128,0,5,208,208,208,2,213,213,213,1,215,215,215, + 1,188,188,188,1,220,220,220,2,225,225,225,1,227,227,227,1,229,229,229, + 1,232,232,232,1,236,236,236,2,241,241,241,1,243,243,243,1,0,0,0, + 1,157,154,157,1,0,0,128,1,128,128,0,2,255,255,255,3,128,128,0, + 2,210,210,210,1,215,215,215,1,217,217,217,1,188,188,188,1,222,222,222, + 2,226,226,226,1,229,229,229,1,231,231,231,1,233,233,233,1,238,238,238, + 2,243,243,243,1,245,245,245,1,0,0,0,1,157,154,157,1,0,0,128, + 1,128,128,0,4,255,255,255,1,128,128,0,2,0,0,0,15,157,154,157, + 1,0,0,128,1,128,128,0,3,255,255,255,1,128,128,0,3,157,154,157, + 15,164,161,164,1,0,0,128,1,128,128,0,2,255,255,255,1,128,128,0, + 4,0,0,128,17,128,128,0,2,255,255,255,3,128,128,0,2,0,0,128, + 18,128,128,0,5,0,0,128,18,0,0) + ); + +const + objdata_TZConnection: record size: integer; data: array[0..1008] of byte end = + (size: 1009; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,84,90,67, + 111,110,110,101,99,116,105,111,110,12,98,105,116,109,97,112,46,105,109,97, + 103,101,10,192,3,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24, + 0,0,0,140,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,128,51,142,140,142,1,97,95,97,1,0,0,0,6,97,95,97,1,146, + 144,146,1,0,0,128,13,141,140,141,1,0,0,0,1,55,142,55,1,66, + 170,66,1,81,205,81,4,63,161,63,1,49,126,49,1,0,0,0,1,136, + 134,136,1,0,0,128,12,0,0,0,1,105,210,105,1,81,205,81,8,83, + 177,83,1,0,0,0,1,0,0,128,12,0,0,0,1,125,192,125,1,132, + 218,132,1,99,209,99,1,81,205,81,4,127,207,127,1,126,195,126,1,87, + 152,87,1,0,0,0,1,0,0,128,12,0,0,0,1,70,159,70,1,93, + 171,93,1,145,197,145,1,177,213,177,1,182,213,182,1,177,210,177,1,175, + 207,175,1,130,180,130,1,93,155,93,1,34,112,34,1,0,0,0,1,0, + 0,128,12,0,0,0,1,70,159,70,2,141,190,141,1,130,184,130,1,59, + 146,59,1,54,140,54,1,50,134,50,1,45,129,45,1,41,123,41,1,34, + 112,34,1,0,0,0,1,63,107,118,1,0,0,0,1,0,0,128,10,0, + 0,0,1,70,159,70,2,133,186,133,1,139,188,139,1,59,146,59,1,54, + 140,54,1,50,134,50,1,45,129,45,1,41,123,41,1,34,112,34,1,50, + 83,93,1,186,229,239,1,0,0,0,1,0,0,128,10,0,0,0,1,70, + 159,70,2,122,181,122,1,130,184,130,1,59,146,59,1,54,140,54,1,50, + 134,50,1,45,129,45,1,41,123,41,1,48,82,90,1,187,229,238,1,128, + 214,238,1,0,0,0,1,19,31,35,1,22,37,42,1,10,16,18,1,0, + 0,128,7,0,0,0,1,70,159,70,2,108,175,108,1,119,178,119,1,59, + 146,59,1,54,140,54,1,50,134,50,1,45,129,45,1,46,79,87,1,182, + 228,239,1,128,214,238,4,109,183,204,1,79,134,150,1,0,0,0,1,0, + 0,128,6,0,0,0,1,70,159,70,2,108,175,108,1,119,178,119,1,59, + 146,59,1,54,140,54,1,50,134,50,1,40,68,75,1,178,226,238,1,128, + 214,238,7,93,157,175,1,0,0,0,1,0,0,128,5,0,0,0,1,65, + 150,65,1,70,159,70,1,108,175,108,1,104,171,104,1,59,146,59,1,54, + 140,54,1,50,134,50,1,39,66,73,1,6,100,143,1,12,148,209,5,40, + 163,215,1,70,180,222,1,128,214,238,1,87,147,164,1,0,0,0,1,0, + 0,128,4,74,81,74,1,0,0,0,1,37,85,37,1,74,133,74,1,85, + 159,85,1,59,145,59,1,56,140,56,1,53,136,53,1,34,96,34,1,25, + 44,48,1,6,100,143,1,12,148,209,2,0,0,0,2,4,82,118,1,9, + 112,158,1,53,170,217,1,109,183,204,1,0,0,0,1,0,0,128,5,115, + 121,115,1,58,75,58,1,0,0,0,6,57,69,57,1,21,35,39,1,7, + 107,152,1,12,148,209,1,0,0,0,1,0,0,128,1,0,0,0,1,3, + 64,92,1,10,125,176,1,128,214,238,1,0,0,0,1,0,0,128,15,15, + 26,30,1,17,102,137,1,0,0,0,1,0,0,128,2,0,0,0,1,8, + 107,152,1,128,214,238,1,0,0,0,1,0,0,128,16,17,30,34,1,6, + 11,11,1,0,0,128,2,0,0,0,1,65,145,174,1,69,118,132,1,0, + 0,0,1,0,0,128,3,128,128,0,5,0,0,128,12,0,0,0,1,120, + 201,224,1,0,0,0,1,0,0,128,3,128,128,0,2,255,255,255,3,128, + 128,0,2,0,0,128,10,0,0,0,1,107,180,201,1,68,116,129,1,0, + 0,0,1,0,0,128,3,128,128,0,4,255,255,255,1,128,128,0,2,0, + 0,128,9,0,0,0,1,92,156,174,1,79,134,150,1,0,0,0,1,0, + 0,128,4,128,128,0,3,255,255,255,1,128,128,0,3,0,0,128,10,0, + 0,0,2,0,0,128,5,128,128,0,2,255,255,255,1,128,128,0,4,0, + 0,128,17,128,128,0,2,255,255,255,3,128,128,0,2,0,0,128,18,128, + 128,0,5,0,0,128,18,0,0) + ); + +const + objdata_TZSequence: record size: integer; data: array[0..1406] of byte end = + (size: 1407; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,10,84,90,83, + 101,113,117,101,110,99,101,12,98,105,116,109,97,112,46,105,109,97,103,101, + 10,80,5,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0,0, + 0,28,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128, + 17,150,133,119,1,119,92,67,1,108,78,49,1,119,92,67,1,150,133,119, + 1,0,0,128,18,47,47,47,1,108,78,49,1,167,121,76,1,172,125,79, + 1,167,121,76,1,108,78,49,1,47,47,47,1,0,0,128,4,142,140,142, + 1,97,95,97,1,0,0,0,6,97,95,97,1,146,144,146,1,0,0,128, + 2,92,91,92,1,108,78,49,1,172,125,79,2,255,255,255,1,172,125,79, + 2,108,78,49,1,93,92,93,1,0,0,128,2,141,140,141,1,0,0,0, + 1,55,142,55,1,66,170,66,1,81,205,81,4,63,161,63,1,49,126,49, + 1,0,0,0,1,136,134,136,1,0,0,128,1,0,0,0,1,167,121,76, + 1,172,125,79,1,108,78,49,1,255,255,255,1,108,78,49,1,172,125,79, + 1,167,121,76,1,24,24,24,1,0,0,128,2,0,0,0,1,105,210,105, + 1,81,205,81,8,83,177,83,1,0,0,0,1,0,0,128,1,0,0,0, + 1,172,125,79,1,255,255,255,5,172,125,79,1,0,0,0,1,0,0,128, + 2,0,0,0,1,125,192,125,1,132,218,132,1,99,209,99,1,81,205,81, + 4,127,207,127,1,126,195,126,1,87,152,87,1,0,0,0,1,0,0,128, + 1,27,20,14,1,167,121,76,1,172,125,79,1,108,78,49,1,255,255,255, + 1,108,78,49,1,172,125,79,1,167,121,76,1,24,24,24,1,0,0,128, + 2,0,0,0,1,70,159,70,1,93,171,93,1,145,197,145,1,177,213,177, + 1,182,213,182,1,177,210,177,1,175,207,175,1,130,180,130,1,93,155,93, + 1,34,112,34,1,0,0,0,1,0,0,128,1,93,92,93,1,108,78,49, + 1,172,125,79,2,255,255,255,1,172,125,79,2,108,78,49,1,93,92,93, + 1,0,0,128,2,0,0,0,1,70,159,70,2,141,190,141,1,130,184,130, + 1,59,146,59,1,54,140,54,1,50,134,50,1,45,129,45,1,41,123,41, + 1,34,112,34,1,0,0,0,1,0,0,128,2,47,47,47,1,108,78,49, + 1,167,121,76,1,172,125,79,1,167,121,76,1,108,78,49,1,47,47,47, + 1,0,0,128,3,0,0,0,1,70,159,70,2,133,186,133,1,139,188,139, + 1,59,146,59,1,54,140,54,1,50,134,50,1,45,129,45,1,40,122,40, + 1,33,110,33,1,0,0,0,1,0,0,128,3,93,92,93,1,18,13,8, + 1,0,0,0,1,17,17,17,1,84,82,84,1,0,0,128,4,0,0,0, + 1,70,159,70,2,122,181,122,1,130,184,130,1,59,146,59,1,54,140,54, + 1,42,114,42,1,29,85,29,1,0,0,0,3,137,135,137,1,0,0,128, + 11,0,0,0,1,70,159,70,2,108,175,108,1,119,178,119,1,59,146,59, + 1,53,139,53,1,0,0,0,3,137,135,137,1,0,0,0,3,0,0,128, + 10,0,0,0,1,70,159,70,2,108,175,108,1,119,178,119,1,59,146,59, + 1,53,137,53,1,0,0,0,1,137,135,137,1,143,149,151,1,129,135,137, + 1,133,140,142,1,120,128,131,1,0,0,0,1,112,111,112,1,0,0,128, + 9,0,0,0,1,65,150,65,1,70,159,70,1,108,175,108,1,104,171,104, + 1,58,145,58,1,0,0,0,2,115,121,123,1,95,101,103,1,59,63,64, + 1,97,102,104,1,114,122,124,1,0,0,0,2,0,0,128,9,74,81,74, + 1,0,0,0,1,37,85,37,1,74,133,74,1,85,159,85,1,58,143,58, + 1,0,0,0,1,137,135,137,1,146,153,154,1,78,82,83,1,20,22,23, + 1,115,117,118,1,147,153,155,1,74,80,82,1,0,0,0,1,146,144,146, + 1,0,0,128,9,115,121,115,1,58,75,58,1,0,0,0,5,115,120,121, + 1,125,132,134,1,150,153,154,1,179,182,183,1,117,123,125,1,0,0,0, + 2,140,138,140,1,0,0,128,15,0,0,0,1,131,136,138,1,100,105,107, + 1,108,117,120,1,86,93,95,1,77,83,84,1,0,0,0,1,83,82,83, + 1,0,0,128,16,0,0,0,3,60,65,66,1,0,0,0,3,112,110,112, + 1,0,0,128,1,1,1,1,3,0,0,128,4,128,128,0,5,0,0,128, + 5,0,0,0,3,105,104,105,1,6,6,6,2,125,123,125,1,4,4,4, + 1,225,227,228,1,3,3,3,1,122,120,122,1,8,8,8,1,9,9,9, + 1,128,128,0,2,255,255,255,3,128,128,0,2,0,0,128,7,6,6,6, + 1,225,225,225,1,177,179,179,1,6,6,6,1,65,70,72,1,150,157,159, + 1,65,70,72,1,6,6,6,1,129,135,136,1,33,33,33,1,128,128,0, + 4,255,255,255,1,128,128,0,2,0,0,128,7,8,8,8,1,173,175,176, + 1,161,167,168,1,150,157,159,3,134,142,144,1,142,149,151,1,116,125,128, + 1,65,70,72,1,128,128,0,3,255,255,255,1,128,128,0,3,0,0,128, + 8,7,7,7,1,150,157,159,2,84,88,89,1,87,94,96,1,131,136,137, + 1,116,125,128,1,107,116,118,1,6,6,6,1,128,128,0,2,255,255,255, + 1,128,128,0,4,0,0,128,6,1,1,1,2,65,70,72,1,150,157,159, + 1,87,94,96,1,63,66,67,1,36,39,40,1,48,52,54,1,150,157,159, + 1,99,107,109,1,65,70,72,1,128,128,0,2,255,255,255,3,128,128,0, + 2,0,0,128,6,1,1,1,1,225,226,226,1,175,181,182,1,150,157,159, + 1,84,88,89,1,30,32,33,1,8,9,10,1,22,24,24,1,228,230,230, + 1,116,125,128,1,92,99,101,1,0,0,128,1,128,128,0,5,0,0,128, + 7,1,1,1,1,3,3,3,1,65,70,72,1,150,157,159,1,131,136,137, + 1,48,52,54,1,20,22,22,1,137,139,140,1,220,222,223,1,92,99,101, + 1,0,0,128,1,0,0) + ); + +const + objdata_TZSqlMetadata: record size: integer; data: array[0..1253] of byte end = + (size: 1254; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,13,84,90,83, + 113,108,77,101,116,97,100,97,116,97,12,98,105,116,109,97,112,46,105,109, + 97,103,101,10,180,4,0,0,0,0,0,0,0,0,0,0,24,0,0,0, + 24,0,0,0,128,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,128,51,102,101,102,1,48,47,48,1,0,0,0,6,48,47,48,1, + 108,107,108,1,0,0,128,13,101,102,101,1,0,0,0,1,55,142,55,1, + 66,170,66,1,81,205,81,4,63,161,63,1,49,126,49,1,0,0,0,1, + 94,93,94,1,0,0,128,12,0,0,0,1,105,210,105,1,81,205,81,8, + 83,177,83,1,0,0,0,1,0,0,128,12,0,0,0,1,125,192,125,1, + 132,218,132,1,99,209,99,1,81,205,81,4,127,207,127,1,126,195,126,1, + 87,152,87,1,0,0,0,1,0,0,128,12,0,0,0,1,70,159,70,1, + 93,171,93,1,145,197,145,1,177,213,177,1,182,213,182,1,177,210,177,1, + 175,207,175,1,130,180,130,1,93,155,93,1,34,112,34,1,0,0,0,1, + 0,0,128,12,0,0,0,1,70,159,70,2,141,190,141,1,130,184,130,1, + 59,146,59,1,54,140,54,1,50,134,50,1,45,129,45,1,41,123,41,1, + 34,112,34,1,0,0,0,1,0,0,128,12,0,0,0,1,70,159,70,2, + 133,186,133,1,139,188,139,1,59,146,59,1,54,140,54,1,50,134,50,1, + 45,129,45,1,41,123,41,1,34,112,34,1,0,0,0,1,0,0,128,12, + 0,0,0,1,70,159,70,2,122,181,122,1,130,184,130,1,59,146,59,1, + 54,140,54,1,0,0,0,7,0,0,128,3,120,118,120,1,0,0,0,1, + 120,118,120,1,0,0,128,4,0,0,0,1,70,159,70,2,108,175,108,1, + 119,178,119,1,59,146,59,1,54,140,54,1,0,0,0,1,97,123,232,1, + 67,97,228,4,0,0,0,1,0,0,128,3,37,37,37,1,208,200,194,1, + 0,0,0,1,0,0,128,4,0,0,0,1,70,159,70,2,108,175,108,1, + 119,178,119,1,59,146,59,1,54,140,54,1,0,0,0,1,67,97,228,1, + 30,66,223,4,0,0,0,1,0,0,128,2,120,118,120,1,26,26,26,1, + 187,162,139,1,0,0,0,1,120,118,120,1,0,0,128,3,0,0,0,1, + 65,150,65,1,70,159,70,1,108,175,108,1,104,171,104,1,59,146,59,1, + 54,140,54,1,0,0,0,1,67,97,228,1,30,66,223,4,0,0,0,1, + 0,0,128,2,56,56,56,1,216,208,199,1,174,144,117,1,145,120,97,1, + 56,56,56,1,0,0,128,3,31,42,31,1,0,0,0,1,37,85,37,1, + 74,133,74,1,85,159,85,1,59,145,59,1,55,140,55,1,0,0,0,1, + 67,97,228,1,30,66,223,4,0,0,0,1,0,0,128,1,120,118,120,1, + 0,0,0,1,198,177,158,1,174,144,117,2,0,0,0,1,120,118,120,1, + 0,0,128,3,68,80,68,1,24,45,24,1,0,0,0,5,67,97,228,1, + 30,66,223,4,0,0,0,1,0,0,128,1,22,22,22,1,216,208,199,1, + 174,144,117,3,145,120,97,1,0,0,0,1,0,0,128,5,166,163,166,1, + 150,149,150,1,150,147,150,1,148,146,148,1,0,0,0,7,0,0,128,1, + 0,0,0,7,0,0,128,25,128,128,0,5,0,0,128,4,120,118,120,1, + 32,32,32,1,0,0,0,1,32,32,32,1,120,118,120,1,0,0,128,4, + 120,118,120,1,0,0,0,1,120,118,120,1,0,0,128,2,128,128,0,2, + 255,255,255,3,128,128,0,2,0,0,128,2,120,118,120,1,18,53,71,1, + 118,192,230,1,121,197,239,1,96,177,226,1,18,49,71,1,120,118,120,1, + 0,0,128,2,120,118,120,1,0,0,0,1,120,169,120,1,0,0,0,1, + 120,118,120,1,0,0,128,1,128,128,0,4,255,255,255,1,128,128,0,2, + 0,0,128,2,32,32,32,1,137,200,232,1,75,180,235,1,61,170,234,1, + 61,167,234,1,51,143,204,1,32,32,32,1,0,0,128,1,120,118,120,1, + 0,0,0,1,120,169,120,1,58,131,58,1,76,142,76,1,24,24,24,1, + 120,118,120,1,128,128,0,3,255,255,255,1,128,128,0,3,0,0,128,2, + 0,0,0,1,139,205,241,1,61,171,234,1,61,168,234,1,61,164,233,1, + 54,147,213,1,0,0,0,1,0,0,128,1,0,0,0,1,130,170,130,1, + 58,131,58,1,38,119,38,2,70,123,70,1,0,0,0,1,128,128,0,2, + 255,255,255,1,128,128,0,4,0,0,128,2,32,32,32,1,118,189,230,1, + 61,168,234,1,61,165,233,1,60,157,228,1,48,128,192,1,32,32,32,1, + 0,0,128,1,120,118,120,1,0,0,0,1,34,107,34,1,38,119,38,1, + 30,96,30,1,0,0,0,1,120,118,120,1,128,128,0,2,255,255,255,3, + 128,128,0,2,0,0,128,2,120,118,120,1,18,50,71,1,50,141,200,1, + 52,141,205,1,48,129,192,1,16,43,66,1,120,118,120,1,0,0,128,2, + 120,118,120,1,0,0,0,1,27,86,27,1,0,0,0,1,120,118,120,1, + 0,0,128,2,128,128,0,5,0,0,128,4,120,118,120,1,32,32,32,1, + 0,0,0,1,32,32,32,1,120,118,120,1,0,0,128,4,120,118,120,1, + 0,0,0,1,120,118,120,1,0,0,128,2,0,0) + ); + +const + objdata_TZSqlMonitor: record size: integer; data: array[0..1524] of byte end = + (size: 1525; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,84,90,83, + 113,108,77,111,110,105,116,111,114,12,98,105,116,109,97,112,46,105,109,97, + 103,101,10,196,5,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24, + 0,0,0,144,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,128,1,142,140,142,1,97,95,97,1,0,0,0,6,97,95,97,1,146, + 144,146,1,0,0,128,13,141,140,141,1,0,0,0,1,55,142,55,1,66, + 170,66,1,81,205,81,4,63,161,63,1,49,126,49,1,0,0,0,1,136, + 134,136,1,0,0,128,12,0,0,0,1,105,210,105,1,81,205,81,8,83, + 177,83,1,0,0,0,1,0,0,128,12,0,0,0,1,125,192,125,1,132, + 218,132,1,99,209,99,1,81,205,81,4,127,207,127,1,126,195,126,1,76, + 132,76,1,0,0,0,1,73,72,73,1,0,0,0,1,2,2,2,1,57, + 56,57,1,118,116,118,1,0,0,128,7,0,0,0,1,70,159,70,1,93, + 171,93,1,145,197,145,1,177,213,177,1,182,213,182,1,177,210,177,1,175, + 207,175,1,130,180,130,1,62,103,62,1,3,8,3,1,93,79,67,1,146, + 125,105,1,156,135,113,1,161,138,115,1,152,129,107,1,88,75,61,1,12, + 11,12,1,129,127,129,1,0,0,128,5,0,0,0,1,70,159,70,2,141, + 190,141,1,130,184,130,1,59,146,59,1,54,140,54,1,50,134,50,1,39, + 112,39,1,3,8,3,1,130,112,94,1,176,159,142,1,203,194,185,1,225, + 220,214,1,230,222,215,1,201,182,162,1,178,150,124,1,134,113,93,1,11, + 11,11,1,0,0,128,5,0,0,0,1,70,159,70,2,133,186,133,1,139, + 188,139,1,59,146,59,1,54,140,54,1,50,134,50,1,22,62,22,1,91, + 78,65,1,179,162,145,1,222,217,211,1,247,246,246,1,249,247,245,1,244, + 238,233,1,234,224,215,1,197,172,148,1,184,155,128,1,100,83,68,1,98, + 97,98,1,0,0,128,4,0,0,0,1,70,159,70,2,122,181,122,1,130, + 184,130,1,59,146,59,1,54,140,54,1,50,133,50,1,13,37,13,1,148, + 127,106,1,207,196,185,1,248,246,245,1,249,246,242,1,244,238,233,1,232, + 221,211,1,214,195,177,1,189,161,134,1,190,164,140,1,168,141,115,1,47, + 46,47,1,0,0,128,4,0,0,0,1,70,159,70,2,108,175,108,1,119, + 178,119,1,59,146,59,1,54,140,54,1,50,133,50,1,0,0,0,1,156, + 134,112,1,233,230,227,1,252,250,249,1,243,237,231,1,233,223,212,1,217, + 199,182,1,193,166,139,1,189,160,133,1,196,172,149,1,184,156,132,1,1, + 1,1,1,0,0,128,4,0,0,0,1,70,159,70,2,108,175,108,1,119, + 178,119,1,59,146,59,1,54,140,54,1,49,132,49,1,0,0,0,1,149, + 127,106,1,225,220,213,1,242,235,229,1,232,221,211,1,217,199,182,1,195, + 168,141,1,191,163,136,1,187,158,131,1,202,181,162,1,183,157,133,1,0, + 0,0,1,0,0,128,4,0,0,0,1,65,150,65,1,70,159,70,1,108, + 175,108,1,104,171,104,1,59,146,59,1,54,140,54,1,49,132,49,1,8, + 24,8,1,137,116,96,1,187,169,151,1,226,215,204,1,215,198,181,1,193, + 166,139,1,191,163,136,1,190,162,136,1,195,171,148,1,209,192,175,1,164, + 137,111,1,48,47,48,1,0,0,128,4,74,81,74,1,0,0,0,1,37, + 85,37,1,74,133,74,1,85,159,85,1,59,145,59,1,56,140,56,1,53, + 135,53,1,14,40,14,1,81,67,56,1,154,130,107,1,177,155,135,1,185, + 157,132,1,187,158,131,1,190,162,137,1,197,173,151,1,215,200,185,1,189, + 164,141,1,99,82,66,1,93,91,93,1,0,0,128,5,115,121,115,1,58, + 75,58,1,0,0,0,6,1,2,1,1,115,96,79,1,147,124,102,1,170, + 150,132,1,180,159,139,1,196,177,159,1,205,188,171,1,195,173,152,1,138, + 114,93,1,5,5,5,1,127,126,127,1,0,0,128,11,115,113,115,1,62, + 61,62,1,0,0,0,1,11,11,11,1,85,71,57,1,136,116,97,1,153, + 131,111,1,155,130,106,1,156,129,105,1,98,81,65,1,5,5,5,1,89, + 87,89,1,0,0,128,10,171,168,171,1,0,0,0,1,5,5,5,1,7, + 7,7,1,18,13,8,1,46,34,22,1,56,51,47,1,37,37,37,1,1, + 1,1,1,0,0,0,1,21,15,10,1,50,36,23,1,102,93,87,1,0, + 0,128,1,98,72,47,1,108,79,51,1,0,0,128,7,156,154,156,1,38, + 38,38,1,185,185,185,1,144,144,144,1,22,22,22,1,47,35,22,1,129, + 121,115,1,93,68,44,1,161,158,158,1,91,67,43,1,86,63,41,1,142, + 137,136,1,88,65,42,1,94,69,45,1,0,0,128,1,108,79,51,1,111, + 81,53,1,0,0,128,6,167,164,167,1,13,13,13,1,177,177,177,1,110, + 110,110,1,0,0,0,2,77,56,36,1,151,145,144,1,0,0,128,2,105, + 77,50,1,103,76,49,1,0,0,128,1,104,76,49,1,107,78,51,1,0, + 0,128,1,112,82,53,2,0,0,128,4,128,128,0,5,0,0,0,2,74, + 68,63,1,84,62,40,1,100,73,47,1,155,141,130,1,0,0,128,1,111, + 81,53,2,0,0,128,1,111,81,53,1,112,82,53,1,0,0,128,1,112, + 82,53,2,0,0,128,3,128,128,0,2,255,255,255,3,128,128,0,2,86, + 84,85,1,144,141,142,1,139,127,117,1,108,79,51,1,112,82,53,1,0, + 0,128,1,112,82,53,2,0,0,128,1,112,82,53,2,0,0,128,1,112, + 82,53,2,0,0,128,3,128,128,0,4,255,255,255,1,128,128,0,2,145, + 143,145,1,0,0,128,2,111,81,53,1,112,82,53,1,0,0,128,1,112, + 82,53,2,0,0,128,1,112,82,53,2,0,0,128,1,112,82,53,2,0, + 0,128,3,128,128,0,3,255,255,255,1,128,128,0,3,0,0,128,1,107, + 78,51,1,175,166,161,1,112,82,53,2,0,0,128,1,112,82,53,5,0, + 0,128,1,112,82,53,2,0,0,128,3,128,128,0,2,255,255,255,1,128, + 128,0,4,0,0,128,1,162,149,139,1,112,82,53,2,157,142,130,1,0, + 0,128,1,160,145,134,1,112,82,53,3,156,140,128,1,0,0,128,1,112, + 82,53,4,0,0,128,1,128,128,0,2,255,255,255,3,128,128,0,2,0, + 0,128,9,157,142,130,1,112,82,53,1,0,0,128,7,128,128,0,5,0, + 0,128,18,0,0) + ); + +const + objdata_TZSqlProcessor: record size: integer; data: array[0..1202] of byte end = + (size: 1203; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,14,84,90,83, + 113,108,80,114,111,99,101,115,115,111,114,12,98,105,116,109,97,112,46,105, + 109,97,103,101,10,128,4,0,0,0,0,0,0,0,0,0,0,24,0,0, + 0,24,0,0,0,76,4,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,128,53,121,119,121,1,0,0,0,15,119,117,119,1,0,0,128, + 6,121,119,121,1,156,156,156,1,251,251,251,1,241,241,241,1,233,233,233, + 9,241,241,241,1,207,207,207,1,214,214,214,1,155,155,155,1,64,64,64, + 1,119,117,119,1,0,0,128,5,0,0,0,1,255,255,255,12,233,233,233, + 1,119,119,119,1,143,143,143,1,179,179,179,1,212,212,212,1,0,0,0, + 1,0,0,128,5,0,0,0,1,247,247,247,1,233,233,233,1,220,220,220, + 10,210,210,210,1,133,133,133,1,0,0,0,4,0,0,128,5,0,0,0, + 1,244,244,244,1,220,220,220,11,210,210,210,1,0,0,0,1,80,79,80, + 1,142,140,142,1,0,0,128,7,0,0,0,4,173,173,173,1,222,223,223, + 1,223,222,223,1,219,219,220,1,223,223,223,3,223,222,223,1,222,223,223, + 1,212,211,212,1,0,0,0,1,137,135,137,1,0,0,128,7,0,0,0, + 3,202,206,207,1,0,0,0,3,226,225,225,1,226,225,226,1,225,226,226, + 1,226,226,225,1,225,225,225,1,225,226,225,1,226,225,225,1,214,213,213, + 1,0,0,0,1,149,147,149,1,0,0,128,6,151,148,151,1,0,0,0, + 1,223,224,224,1,143,149,151,1,129,135,137,1,133,140,142,1,120,128,131, + 1,0,0,0,1,130,130,130,1,228,229,228,1,228,228,228,2,229,228,228, + 1,228,228,228,2,216,216,216,1,0,0,0,1,157,154,157,1,0,0,128, + 6,0,0,0,2,114,120,122,1,95,101,103,1,59,63,64,1,97,102,104, + 1,114,122,124,1,0,0,0,2,231,231,230,1,231,231,231,1,231,231,230, + 1,231,230,231,1,231,231,231,1,230,231,231,1,218,218,218,1,0,0,0, + 1,159,157,159,1,0,0,128,6,0,0,0,1,219,220,221,1,146,153,154, + 1,78,82,83,1,20,22,23,1,115,117,118,1,147,153,155,1,74,80,82, + 1,0,0,0,1,233,233,233,1,234,233,233,1,234,234,233,1,233,234,233, + 1,233,233,234,1,233,233,233,1,220,220,219,1,0,0,0,1,161,159,161, + 1,0,0,128,6,0,0,0,2,115,120,121,1,125,132,134,1,150,153,154, + 1,179,182,183,1,117,123,125,1,0,0,0,2,236,235,235,2,236,236,236, + 1,236,235,235,2,235,236,235,1,222,220,221,1,0,0,0,1,160,157,160, + 1,0,0,128,6,141,138,141,1,0,0,0,1,128,133,135,1,100,105,107, + 1,108,117,120,1,86,93,95,1,90,83,72,1,112,82,53,2,188,175,164, + 1,236,235,235,1,190,178,166,1,112,82,53,3,178,166,154,1,14,10,7, + 1,112,82,53,2,0,0,128,6,0,0,0,3,60,65,66,1,0,0,0, + 1,112,82,53,2,203,194,186,1,112,82,53,1,232,230,228,1,112,82,53, + 2,227,224,221,1,112,82,53,2,15,11,7,1,112,82,53,2,0,0,128, + 7,0,0,0,4,112,82,53,2,225,222,218,1,230,226,224,1,235,231,229, + 1,112,82,53,2,227,222,218,1,112,82,53,2,28,20,13,1,112,82,53, + 2,0,0,128,7,0,0,0,1,251,251,251,1,247,247,247,1,246,246,245, + 1,192,180,168,1,112,82,53,2,187,174,161,1,239,237,235,1,112,82,53, + 2,228,224,220,1,112,82,53,2,15,11,7,1,112,82,53,2,0,0,128, + 4,128,128,0,5,249,248,248,2,246,245,244,1,190,178,164,1,112,82,53, + 2,237,234,231,1,112,82,53,2,231,226,221,1,112,82,53,2,16,12,7, + 1,112,82,53,2,0,0,128,3,128,128,0,2,255,255,255,3,128,128,0, + 2,126,126,126,1,126,125,125,1,125,124,123,1,112,82,53,2,124,120,117, + 1,112,82,53,2,235,231,226,1,112,82,53,2,16,12,7,1,112,82,53, + 2,0,0,128,3,128,128,0,4,255,255,255,1,128,128,0,2,253,253,253, + 1,112,82,53,1,217,210,203,1,112,82,53,2,232,228,224,1,112,82,53, + 5,16,12,7,1,112,82,53,2,0,0,128,3,128,128,0,3,255,255,255, + 1,128,128,0,3,220,219,219,1,177,165,154,1,112,82,53,2,170,156,142, + 1,206,203,199,1,173,160,147,1,112,82,53,3,143,129,115,1,68,63,60, + 1,112,82,53,4,0,0,128,1,128,128,0,2,255,255,255,1,128,128,0, + 4,0,0,0,1,3,2,1,1,7,5,3,1,11,8,5,1,12,9,6, + 1,9,6,4,1,6,4,3,1,9,7,4,1,14,10,6,1,52,38,25, + 1,112,82,53,1,147,141,140,1,0,0,128,5,128,128,0,2,255,255,255, + 3,128,128,0,2,182,179,182,1,180,177,180,1,179,176,178,1,178,174,176, + 1,177,173,175,1,179,175,177,1,179,176,178,1,177,174,176,1,175,171,172, + 1,171,166,167,1,170,165,165,1,0,0,128,7,128,128,0,5,0,0,128, + 18,0,0) + ); + +const + objdata_TZStoredProc: record size: integer; data: array[0..976] of byte end = + (size: 977; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,12,84,90,83, + 116,111,114,101,100,80,114,111,99,12,98,105,116,109,97,112,46,105,109,97, + 103,101,10,160,3,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24, + 0,0,0,108,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,128,52,118,116,118,1,0,0,0,1,118,116,118,1,0,0,128,7,118, + 116,118,1,30,30,30,1,0,0,0,1,30,29,30,1,112,110,112,1,0, + 0,128,8,118,116,118,1,0,0,0,1,120,169,120,1,0,0,0,1,118, + 116,118,1,0,0,128,5,118,116,118,1,18,53,71,1,118,192,230,1,121, + 197,239,1,96,177,226,1,18,49,71,1,103,101,103,1,0,0,128,6,118, + 116,118,1,0,0,0,1,120,169,120,1,58,131,58,1,76,142,76,1,24, + 24,24,1,118,116,118,1,0,0,128,4,30,30,30,1,137,200,232,1,75, + 180,235,1,61,170,234,1,61,167,234,1,51,143,204,1,24,24,24,1,0, + 0,128,6,0,0,0,1,130,170,130,1,58,131,58,1,38,119,38,2,70, + 123,70,1,0,0,0,6,139,205,241,1,61,171,234,1,61,168,234,1,61, + 164,233,1,54,147,213,1,0,0,0,1,0,0,128,6,118,116,118,1,0, + 0,0,1,34,107,34,1,38,119,38,1,30,96,30,1,0,0,0,1,118, + 116,118,1,0,0,128,4,30,29,30,1,118,189,230,1,61,168,234,1,61, + 165,233,1,60,157,228,1,48,128,192,1,22,22,22,1,0,0,128,7,118, + 116,118,1,0,0,0,1,27,86,27,1,0,0,0,1,118,116,118,1,0, + 0,128,5,112,110,112,1,18,50,71,1,50,141,200,1,52,141,205,1,48, + 129,192,1,16,43,66,1,85,84,85,1,0,0,128,8,118,116,118,1,0, + 0,0,1,118,116,118,1,0,0,128,7,103,101,103,1,24,24,24,1,0, + 0,0,1,22,22,22,1,85,84,85,1,0,0,128,10,0,0,0,1,0, + 0,128,23,0,0,0,1,0,0,128,23,0,0,0,1,0,0,128,23,0, + 0,0,1,0,0,128,20,0,0,0,7,0,0,128,17,0,0,0,1,97, + 123,232,1,67,97,228,4,43,31,20,1,112,82,53,2,162,148,138,1,0, + 0,128,1,164,150,141,1,112,82,53,3,162,148,138,1,0,0,128,1,112, + 82,53,2,0,0,128,5,0,0,0,1,67,97,228,1,30,66,223,3,30, + 66,222,1,112,82,53,2,159,148,142,1,112,82,53,1,0,0,128,1,112, + 82,53,2,0,0,128,1,112,82,53,2,0,0,128,1,112,82,53,2,0, + 0,128,5,0,0,0,1,67,97,228,1,30,66,223,3,30,66,222,1,112, + 82,53,2,169,162,161,1,0,0,128,2,112,82,53,2,0,0,128,1,112, + 82,53,2,0,0,128,1,112,82,53,2,0,0,128,4,128,128,0,5,30, + 66,222,2,45,33,21,1,112,82,53,2,159,144,133,1,0,0,128,1,112, + 82,53,2,0,0,128,1,112,82,53,2,0,0,128,1,112,82,53,2,0, + 0,128,3,128,128,0,2,255,255,255,3,128,128,0,2,30,66,222,1,3, + 2,1,1,134,120,108,1,112,82,53,2,0,0,128,1,112,82,53,2,0, + 0,128,1,112,82,53,2,0,0,128,1,112,82,53,2,0,0,128,3,128, + 128,0,4,255,255,255,1,128,128,0,2,0,0,0,1,1,0,0,1,150, + 147,147,1,112,82,53,2,0,0,128,1,112,82,53,2,0,0,128,1,112, + 82,53,2,0,0,128,1,112,82,53,2,0,0,128,3,128,128,0,3,255, + 255,255,1,128,128,0,3,118,116,118,1,112,82,53,1,150,141,136,1,112, + 82,53,2,0,0,128,1,112,82,53,5,0,0,128,1,112,82,53,2,0, + 0,128,3,128,128,0,2,255,255,255,1,128,128,0,4,0,0,128,1,153, + 139,129,1,112,82,53,2,157,141,129,1,0,0,128,1,160,145,134,1,112, + 82,53,3,156,139,127,1,0,0,128,1,112,82,53,4,0,0,128,1,128, + 128,0,2,255,255,255,3,128,128,0,2,0,0,128,9,157,141,129,1,112, + 82,53,1,0,0,128,7,128,128,0,5,0,0,128,18,0,0) + ); + +const + objdata_TZUpdateSql: record size: integer; data: array[0..1459] of byte end = + (size: 1460; data: ( + 84,80,70,48,11,116,98,105,116,109,97,112,99,111,109,112,11,84,90,85, + 112,100,97,116,101,83,113,108,12,98,105,116,109,97,112,46,105,109,97,103, + 101,10,132,5,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24,0, + 0,0,80,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 128,38,64,63,64,1,17,17,17,1,0,0,0,1,17,17,17,1,64,63, + 64,1,0,0,128,17,80,78,80,1,29,52,29,1,90,145,91,1,127,180, + 127,1,123,180,123,1,112,173,112,1,90,147,91,1,19,46,19,1,80,78, + 80,1,0,0,128,14,80,78,80,1,59,100,59,1,144,189,145,1,109,170, + 110,1,79,154,81,1,114,176,114,1,64,149,64,1,91,164,93,1,94,167, + 94,1,66,109,67,1,80,78,80,1,0,0,128,4,0,0,0,9,32,55, + 33,1,149,193,148,1,101,166,101,1,62,145,64,1,113,177,114,1,255,255, + 255,1,65,152,67,2,67,154,69,1,94,169,96,1,19,47,20,1,0,0, + 128,4,0,0,0,1,141,175,79,2,134,168,72,1,118,152,58,1,109,143, + 51,1,102,136,44,1,93,127,37,1,28,39,10,1,99,152,99,1,118,175, + 119,1,62,145,62,1,113,174,113,1,255,255,255,4,117,181,118,1,69,158, + 71,1,58,135,58,1,53,52,53,1,0,0,128,3,0,0,0,1,141,175, + 79,2,134,168,72,1,118,152,58,1,109,143,51,1,102,136,44,1,93,127, + 37,1,7,10,3,1,145,190,145,1,86,159,86,1,64,147,65,1,65,148, + 65,1,116,180,117,1,255,255,255,1,67,154,69,1,94,170,94,1,255,255, + 255,1,69,160,72,2,14,13,14,1,0,0,128,3,0,0,0,1,225,225, + 225,1,188,188,188,6,0,0,0,1,147,193,146,1,69,150,70,1,255,255, + 255,1,66,151,66,1,66,153,68,1,136,192,137,1,68,159,70,2,255,255, + 255,1,71,162,73,1,71,164,73,1,0,0,0,1,0,0,128,3,0,0, + 0,1,255,255,255,1,188,188,188,2,192,192,192,2,197,197,197,1,199,199, + 199,1,16,16,16,1,136,187,137,1,65,150,65,1,255,255,255,1,92,167, + 94,1,68,155,68,1,255,255,255,1,118,185,120,1,70,161,72,1,71,162, + 73,1,71,164,73,2,14,13,14,1,0,0,128,3,0,0,0,1,255,255, + 255,1,188,188,188,1,189,189,189,1,194,194,194,2,199,199,199,1,201,201, + 201,1,61,61,61,1,114,163,115,1,69,154,69,1,116,180,116,1,255,255, + 255,4,119,186,120,1,72,165,72,1,73,166,75,1,63,142,63,1,51,50, + 51,1,0,0,128,3,0,0,0,1,225,225,225,1,188,188,188,6,89,89, + 89,1,30,55,30,1,102,173,102,1,68,155,70,1,69,156,71,1,70,159, + 72,1,255,255,255,1,120,188,121,1,72,167,75,2,74,167,76,1,22,51, + 22,1,111,109,111,1,0,0,128,3,0,0,0,1,255,255,255,1,191,191, + 191,1,193,193,193,1,198,198,198,2,202,202,202,1,205,205,205,1,188,188, + 188,1,84,84,84,1,78,119,78,1,94,171,94,1,69,160,72,1,70,161, + 73,1,97,175,97,1,72,165,74,1,74,167,74,1,75,168,77,1,41,96, + 41,1,0,0,0,1,157,154,157,1,0,0,128,3,0,0,0,1,255,255, + 255,1,192,192,192,1,195,195,195,1,199,199,199,2,204,204,204,1,206,206, + 206,1,188,188,188,1,211,211,211,1,85,85,85,1,24,53,25,1,59,138, + 59,1,70,161,73,1,72,165,74,2,63,144,63,1,21,52,21,1,95,95, + 95,1,0,0,0,1,157,154,157,1,0,0,128,3,0,0,0,1,225,225, + 225,1,188,188,188,5,188,188,187,1,125,125,125,1,188,188,187,2,133,133, + 133,1,61,61,61,1,16,16,16,1,0,0,0,1,16,16,16,1,61,61, + 61,1,133,133,133,1,188,188,188,1,0,0,0,1,157,154,157,1,0,0, + 128,3,0,0,0,1,255,255,255,1,196,196,196,1,198,198,198,1,203,203, + 203,2,171,160,148,1,112,82,53,2,173,161,150,1,213,212,211,1,174,163, + 151,1,112,82,53,3,182,170,158,1,216,212,209,1,112,82,53,2,14,11, + 7,1,157,154,157,1,0,0,128,3,0,0,0,1,255,255,255,1,198,198, + 198,1,200,200,200,1,205,205,205,1,205,205,204,1,112,82,53,2,165,156, + 148,1,112,82,53,1,209,207,205,1,112,82,53,2,208,205,202,1,112,82, + 53,2,216,212,208,1,112,82,53,2,15,11,7,1,157,154,157,1,0,0, + 128,3,0,0,0,1,225,225,225,1,188,188,188,3,188,188,187,1,112,82, + 53,2,123,119,115,1,180,176,173,1,182,180,177,1,112,82,53,2,178,173, + 169,1,112,82,53,2,169,162,155,1,112,82,53,2,28,20,13,1,155,150, + 152,1,0,0,128,2,128,128,0,5,208,208,207,2,172,160,148,1,112,82, + 53,2,172,159,146,1,213,211,210,1,112,82,53,2,212,208,204,1,112,82, + 53,2,219,215,211,1,112,82,53,2,15,11,7,1,155,150,151,1,0,0, + 128,1,128,128,0,2,255,255,255,3,128,128,0,2,210,210,209,1,212,211, + 211,1,172,159,146,1,112,82,53,2,212,209,207,1,112,82,53,2,214,210, + 206,1,112,82,53,2,220,216,212,1,112,82,53,2,15,11,7,1,155,150, + 151,1,0,0,128,1,128,128,0,4,255,255,255,1,128,128,0,2,0,0, + 0,1,1,1,1,1,5,4,2,1,112,82,53,2,14,10,7,1,112,82, + 53,2,16,12,7,1,112,82,53,2,16,12,7,1,112,82,53,2,15,11, + 7,1,155,150,151,1,0,0,128,1,128,128,0,3,255,255,255,1,128,128, + 0,3,157,154,157,1,112,82,53,1,146,136,132,1,112,82,53,2,151,144, + 143,1,112,82,53,5,151,144,142,1,112,82,53,2,151,144,143,1,161,156, + 157,1,0,0,128,1,128,128,0,2,255,255,255,1,128,128,0,4,0,0, + 128,1,159,145,135,1,112,82,53,2,153,137,126,1,0,0,128,1,155,141, + 130,1,112,82,53,3,152,136,123,1,0,0,128,1,112,82,53,4,0,0, + 128,1,128,128,0,2,255,255,255,3,128,128,0,2,0,0,128,9,157,142, + 130,1,112,82,53,1,0,0,128,7,128,128,0,5,0,0,128,18,0,0) + ); + +initialization + registerobjectdata(@objdata_tmsezreadonlyquery,tbitmapcomp,'tmsezreadonlyquery'); + registerobjectdata(@objdata_tmsezquery,tbitmapcomp,'tmsezquery'); + registerobjectdata(@objdata_tmseztable,tbitmapcomp,'tmseztable'); + registerobjectdata(@objdata_TZConnection,tbitmapcomp,'TZConnection'); + registerobjectdata(@objdata_TZSequence,tbitmapcomp,'TZSequence'); + registerobjectdata(@objdata_TZSqlMetadata,tbitmapcomp,'TZSqlMetadata'); + registerobjectdata(@objdata_TZSqlMonitor,tbitmapcomp,'TZSqlMonitor'); + registerobjectdata(@objdata_TZSqlProcessor,tbitmapcomp,'TZSqlProcessor'); + registerobjectdata(@objdata_TZStoredProc,tbitmapcomp,'TZStoredProc'); + registerobjectdata(@objdata_TZUpdateSql,tbitmapcomp,'TZUpdateSql'); +end. diff --git a/mseide-msegui/lib/common/report/mselatex.pas b/mseide-msegui/lib/common/report/mselatex.pas new file mode 100644 index 0000000..be77e1d --- /dev/null +++ b/mseide-msegui/lib/common/report/mselatex.pas @@ -0,0 +1,174 @@ +{ MSEgui Copyright (c) 2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mselatex; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msestrings,mserichstring,msetypes; + +function richstringtolatex(const source: richstringty): msestring; + +implementation +uses + msegraphutils,msearrayutils,msegraphics,sysutils,mseformatstr; + +const + escchars = ['#','$','%','&','{','}','_']; + +function richstringtolatex(const source: richstringty): msestring; + +var + d: pmsechar; + + procedure add(const astr: msestring); + var + i1: integer; + begin + i1:= length(astr); + move(pointer(astr)^,d^,i1*sizeof(msechar)); + inc(d,i1); + end; + +const + maxitemlen = 200; //maxlen of escape code + format code +var + s,e,dend: pmsechar; + mch1: msechar; + formatindex: integer; + styles1: fontstylesty; + rgb1: rgbtriplety; + defcolors: rgbtriplearty; + i1,i2: integer; +begin + if source.text = '' then begin + result:= ''; + end + else begin + defcolors:= nil; //compiler warning + setlength(result,2*length(source.text)+maxitemlen); + d:= pointer(result); + dend:= d + length(result) - maxitemlen; + s:= pointer(source.text); + formatindex:= 0; + add('{\noindent\fontseries{l}\fontshape{n}\selectfont{}'); +//prichstringty(@source)^.format:= nil; + repeat + if formatindex > high(source.format) then begin + e:= pmsechar(pointer(source.text)) + length(source.text); + end + else begin + e:= pmsechar(pointer(source.text)) + source.format[formatindex].index; + end; + while s < e do begin + mch1:= s^; + if (ord(mch1) < $80) then begin + if (char(byte(mch1)) in escchars) then begin + d^:= '\'; + inc(d); + d^:= mch1; + inc(d); + end + else begin + case mch1 of + '\': begin + add('\textbackslash{}'); + end; + '^': begin + add('\textasciicircum{}'); + end; + '~': begin + add('\textasciitilde{}'); + end; + ' ': begin + add('\hphantom{n}'); + end; + c_return: begin + inc(d); //ignore + end; + c_linefeed: begin + add('\newline'+c_return); + // d^:= c_return; //paragraph + // inc(d); + end; + else begin + d^:= mch1; + inc(d); + end; + end; + end; + end + else begin + d^:= mch1; + inc(d); + end; + if d >= dend then begin + dend:= pmsechar(result); //backup + setlength(result,length(result)*2); + inc(d,(pmsechar(pointer(result))-dend)); //relocate + dend:= pmsechar(pointer(result)) + length(result) - maxitemlen; + end; + inc(s); + end; + if formatindex <= high(source.format) then begin + with source.format[formatindex] do begin + styles1:= fontstylesty(newinfos) * style.fontstyle; + if ni_fontcolor in newinfos then begin + if style.fontcolor = 0 then begin + add('\color{black}'); + end + else begin + rgb1:= colortorgb(not style.fontcolor); + i2:= -1; + for i1:= 0 to high(defcolors) do begin + if colorty(defcolors[i1]) = colorty(rgb1) then begin + i2:= i1; + break; + end; + end; + if i2 < 0 then begin + additem(longwordarty(defcolors),colorty(rgb1)); + i2:= high(defcolors); + add('\definecolor{c'+inttostrmse(i2)+'}{RGB}{'+ + inttostrmse(rgb1.red)+','+ + inttostrmse(rgb1.green)+','+ + inttostrmse(rgb1.blue)+'}'); + end; + add('\color{c'+inttostrmse(i2)+'}'); + end; + end; + if fs_bold in styles1 then begin + add('\fontseries{b}'); + end + else begin + if ni_bold in newinfos then begin + add('\fontseries{l}'); + end; + end; + if fs_italic in styles1 then begin + add('\fontshape{it}'); + end + else begin + if ni_italic in newinfos then begin + add('\fontshape{n}'); + end; + end; + if newinfos*[ni_bold,ni_italic] <> [] then begin + add('\selectfont{}'); + end; + end; + end; + inc(formatindex); + until formatindex > length(source.format); + add('}'); + setlength(result,d-pmsechar(pointer(result))); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/report/msereport.pas b/mseide-msegui/lib/common/report/msereport.pas new file mode 100644 index 0000000..f56960a --- /dev/null +++ b/mseide-msegui/lib/common/report/msereport.pas @@ -0,0 +1,8733 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msereport; +{$ifdef FPC}{$mode objfpc}{$h+}{$GOTO ON}{$interfaces corba}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses,mseapplication,msegui,msegraphics,msetypes,msewidgets, + msegraphutils,mseclasses,mseinterfaces,mseificomp, + msetabs,mseprinter,msestream,msearrayprops,mseguiglob,msesimplewidgets, + msedrawtext,msestrings,mserichstring,msedb,mdb,msethread,mseobjectpicker, + msepointer,mseevent,msesplitter,msestatfile,mselookupbuffer,mseformatstr, + msegdiprint,msemenus,mseglob; + +const + defaultrepppmm = 3; + defaultreppagewidth = 190; + defaultreppageheight = 270; + defaultrepfontheight = 14; + defaultrepfontname = 'stf_report'; + tabpickthreshold = 3; + endrendertag = 49125363; + + defaultreptabtextflags = [tf_ycentered]; + defaultbandanchors = [an_top]; + defaultbandoptionswidget = defaultoptionswidget; + {(defaultoptionswidget + [ow_fontlineheight]) - + [ow_fontglyphheight];} + + defaultrepvaluedisptextflags = [tf_ycentered]; + defaultrepvaluedispoptionsscale = + [osc_expandx,osc_shrinkx,osc_expandy,osc_shrinky]; + defaultrepfontcolor = cl_black; + +type + lookupkindty = (lk_text,lk_integer,lk_int64,lk_float,lk_date,lk_time,lk_datetime); + linevisiblety = (lv_topofpage,lv_nottopofpage, + lv_firstofpage,lv_normal,lv_lastofpage, + lv_firstofgroup,lv_lastofgroup, + lv_firstrecord,lv_lastrecord); + linevisiblesty = set of linevisiblety; + + tablineinfoty = record + widthmm: real; + color: colorty; + colorgap: colorty; + capstyle: capstylety; + dashes: string; + dist: integer; + visible: linevisiblesty; + end; + tablinekindty = (tlk_top,tlk_vert,tlk_bottom); + tablineinfoarty = array[tablinekindty] of tablineinfoty; +const + defaulttablinewidth = 0; + defaulttablinecolor = cl_black; + defaulttablinecolorgap = cl_transparent; + defaulttablinecapstyle = cs_projecting; + defaulttablinedashes = ''; + defaulttablinedist = 0; + defaulttablinevisible = [lv_topofpage,lv_nottopofpage, + lv_firstofpage,lv_normal,lv_lastofpage, + lv_firstofgroup,lv_lastofgroup, + lv_firstrecord,lv_lastrecord]; + defaulttablineinfo: tablineinfoty = (widthmm: defaulttablinewidth; + color: defaulttablinecolor; colorgap: defaulttablinecolorgap; + capstyle: defaulttablinecapstyle; + dashes: defaulttablinedashes; dist: defaulttablinedist; + visible: defaulttablinevisible); +type + bandoptionshowty = ( + //show only on first/last record of group + bos_showfirstpage,bos_hidefirstpage, + bos_shownormalpage,bos_hidenormalpage, + //checks current treportpage + bos_showevenpage,bos_hideevenpage, + bos_showoddpage,bos_hideoddpage, + //checks the printed page number + bos_showtopofpage,bos_hidetopofpage, + bos_shownottopofpage,bos_hidenottopofpage, + bos_showfirstofpage,bos_hidefirstofpage, + bos_shownormalofpage,bos_hidenormalofpage, + bos_showlastofpage,bos_hidelastofpage, + //checks the position in the bandarea + bos_showfirstrecord,bos_hidefirstrecord, + bos_shownormalrecord,bos_hidenormalrecord, + bos_showlastrecord,bos_hidelastrecord + //checks the connected dataset + ); + bandoptionshowsty = set of bandoptionshowty; + + bandoptionty = (bo_once,bo_evenpage,bo_oddpage, + //defines hasdata, page nums are null based + bo_visigroupfirst,bo_visigroupnotfirst, + bo_visigrouplast,bo_visigroupnotlast, + bo_delayednextrecord, + bo_localvalue, + //used in treppagenumdisp to show the number of the current + //treportpage instead the number of the printed pages + //and in trepprinttimedisp to show now instead of + //print start time + bo_topofarea //sets areafull if not first of page before render + ); + bandoptionsty = set of bandoptionty; + +const + visibilitymask = [bos_showfirstpage,bos_hidefirstpage, + bos_shownormalpage,bos_hidenormalpage, + bos_showevenpage,bos_hideevenpage, + bos_showoddpage,bos_hideoddpage, + bos_showtopofpage,bos_hidetopofpage, + bos_shownottopofpage,bos_hidenottopofpage, + bos_showfirstofpage,bos_hidefirstofpage, + bos_shownormalofpage,bos_hidenormalofpage, + bos_showlastofpage,bos_hidelastofpage, + bos_showfirstrecord,bos_hidefirstrecord, + bos_shownormalrecord,bos_hidenormalrecord, + bos_showlastrecord,bos_hidelastrecord + ]; + defaultrepvaluedispoptions = [bo_evenpage,bo_oddpage]; + +type + reportoptionty = (reo_autorelease,reo_prepass,reo_nodisablecontrols, + reo_nothread,reo_waitdialog, + reo_autoreadstat,reo_autowritestat,reo_delayedreadstat); + reportoptionsty = set of reportoptionty; + +const + defaultreportoptions = []; + +type + tbasebandarea = class; + tcustomrecordband = class; + tcustomreportpage = class; + rendereventty = procedure(const sender: tobject; + const acanvas: tcanvas) of object; + beforerenderrecordeventty = procedure(const sender: tcustomrecordband; + var empty: boolean) of object; + synceventty = procedure() of object; + + treptabfont = class(tparentfont) + protected + procedure setname(const avalue: string); override; + public + constructor create; override; + class function getinstancepo(owner: tobject): pfont; override; + published + property color default defaultrepfontcolor; + end; + + trepwidgetfont = class(twidgetfont) + protected + procedure setname(const avalue: string); override; + public + constructor create; override; + published + property color default defaultrepfontcolor; + end; + + trepfont = class(tfont) + protected + procedure setname(const avalue: string); override; + public + constructor create; override; + published + property color default defaultrepfontcolor; + end; + + treptabulatoritem = class; + + treptabitemdatalink = class(tfielddatalink) + private + fowner: treptabulatoritem; + protected + procedure recordchanged(afield: tfield); override; + public + constructor create(const aowner: treptabulatoritem); + end; + + getrichstringeventty = procedure(const sender: tobject; + var avalue: richstringty) of object; + reptabulatoritemoptionty = (rto_disabled,rto_count,rto_sum,rto_average, + rto_shownull, + rto_nocurrentvalue,rto_noreset); + reptabulatoritemoptionsty = set of reptabulatoritemoptionty; + + itemsumty = record + count: integer; + resetpending: boolean; + reset: boolean; + case tfieldtype of + ftinteger,ftword,ftsmallint,ftboolean: (integervalue: integer); + ftlargeint: (largeintvalue: int64); + ftfloat: (floatvalue: double); + ftbcd: (bcdvalue: currency); + end; + + treptabulatoritem = class(ttabulatoritem,idbeditinfo) + private + fvalue: richstringty; + ffont: treptabfont; + ftextflags: textflagsty; + fdatalink: treptabitemdatalink; + fongetvalue: getrichstringeventty; + flineinfos: tablineinfoarty; + flookupbuffer: tcustomlookupbuffer; + flookupkeyfieldno: integer; + flookupvaluefieldno: integer; + flookupkind: lookupkindty; + fformat: msestring; + fcolor: colorty; + ftag: integer; + foptions: reptabulatoritemoptionsty; + fsum: itemsumty; + fifilink: tifilinkcomp; + procedure setvalue(const avalue: msestring); + procedure setrichvalue(const avalue: richstringty); + function getdisptext: richstringty; + function getfont: treptabfont; + procedure setfont(const avalue: treptabfont); + function isfontstored: boolean; + procedure createfont; + procedure changed; + procedure fontchanged(const asender: tobject); + procedure settextflags(const avalue: textflagsty); + function getdatasource1: tdatasource; + procedure setdatasource(const avalue: tdatasource); + function getdatafield: string; + procedure setdatafield(const avalue: string); + + procedure setlitop_widthmm(const avalue: real); + procedure setlitop_color(const avalue: colorty); + procedure setlitop_colorgap(const avalue: colorty); + procedure setlitop_capstyle(const avalue: capstylety); + procedure setlitop_dashes(const avalue: string); + procedure setlitop_dist(const avalue: integer); + procedure setlitop_visible(const avalue: linevisiblesty); + + procedure setlivert_widthmm(const avalue: real); + procedure setlivert_color(const avalue: colorty); + procedure setlivert_colorgap(const avalue: colorty); + procedure setlivert_capstyle(const avalue: capstylety); + procedure setlivert_dashes(const avalue: string); + procedure setlivert_dist(const avalue: integer); + procedure setlivert_visible(const avalue: linevisiblesty); + + procedure setlibottom_widthmm(const avalue: real); + procedure setlibottom_color(const avalue: colorty); + procedure setlibottom_colorgap(const avalue: colorty); + procedure setlibottom_capstyle(const avalue: capstylety); + procedure setlibottom_dashes(const avalue: string); + procedure setlibottom_dist(const avalue: integer); + procedure setlibottom_visible(const avalue: linevisiblesty); + procedure recchanged; + + //idbeditinfo + function getdataset(const aindex: integer): tdataset; + procedure getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); + procedure setlookupbuffer(const avalue: tcustomlookupbuffer); + procedure setlookupkeyfieldno(const avalue: integer); + procedure setlookupvaluefieldno(const avalue: integer); + procedure setlookupkind(const avalue: lookupkindty); + procedure setformat(const avalue: msestring); + procedure setcolor(avalue: colorty); + + function getsumasinteger: integer; + function getsumaslargeint: int64; + function getsumasfloat: double; + function getsumascurrency: currency; + procedure initsum; + procedure setoptions(const avalue: reptabulatoritemoptionsty); + function getsumcount: integer; + procedure setenabled(const avalue: boolean); + procedure setifilink(const avalue: tifilinkcomp); + protected + function getenabled: boolean override; + procedure setpos(const avalue: real); override; + function xlineoffset: integer; + procedure dobeforenextrecord(const adatasource: tdatasource); + procedure scale(const ascale: real); + public + constructor create(aowner: tobject); override; + destructor destroy; override; + procedure resetsum(const skipcurrent: boolean); + + procedure setintvalue(const avalue: int32); + procedure setint64value(const avalue: int64); + procedure setfloatvalue(const avalue: flo64); + procedure setdatetimevalue(const avalue: tdatetime); + procedure setcurrencyvalue(const avalue: currency); + + property sumcount: integer read getsumcount; + property sumasinteger: integer read getsumasinteger; + property sumaslargeint: int64 read getsumaslargeint; + property sumasfloat: double read getsumasfloat; + property sumascurrency: currency read getsumascurrency; + property richvalue: richstringty read fvalue write setrichvalue; + property enabled: boolean read getenabled write setenabled; + published + property tag: integer read ftag write ftag default 0; + property options: reptabulatoritemoptionsty read foptions + write setoptions default []; + property value: msestring read fvalue.text write setvalue; + property font: treptabfont read getfont write setfont stored isfontstored; + property color: colorty read fcolor write setcolor default cl_none; + property textflags: textflagsty read ftextflags write settextflags + default defaultreptabtextflags; + property ifilink: tifilinkcomp read fifilink write setifilink; + property datafield: string read getdatafield write setdatafield; + property datasource: tdatasource read getdatasource1 write setdatasource; + property lookupbuffer: tcustomlookupbuffer read flookupbuffer + write setlookupbuffer; + property lookupkeyfieldno: integer read flookupkeyfieldno + write setlookupkeyfieldno default 0; + property lookupvaluefieldno: integer read flookupvaluefieldno + write setlookupvaluefieldno default 0; + property lookupkind: lookupkindty read flookupkind + write setlookupkind default lk_text; + property format: msestring read fformat write setformat; + + property litop_widthmm: real read flineinfos[tlk_top].widthmm write + setlitop_widthmm; + property litop_color: colorty read flineinfos[tlk_top].color write + setlitop_color default defaulttablinecolor; + property litop_colorgap: colorty read flineinfos[tlk_top].colorgap write + setlitop_colorgap default defaulttablinecolorgap; + property litop_capstyle: capstylety read flineinfos[tlk_top].capstyle write + setlitop_capstyle default defaulttablinecapstyle; + property litop_dashes: string read flineinfos[tlk_top].dashes write + setlitop_dashes; + property litop_dist: integer read flineinfos[tlk_top].dist write + setlitop_dist default defaulttablinedist; + property litop_visible: linevisiblesty read flineinfos[tlk_top].visible write + setlitop_visible default defaulttablinevisible; + + property livert_widthmm: real read flineinfos[tlk_vert].widthmm write + setlivert_widthmm; + property livert_color: colorty read flineinfos[tlk_vert].color write + setlivert_color default defaulttablinecolor; + property livert_colorgap: colorty read flineinfos[tlk_vert].colorgap write + setlivert_colorgap default defaulttablinecolorgap; + property livert_capstyle: capstylety read flineinfos[tlk_vert].capstyle write + setlivert_capstyle default defaulttablinecapstyle; + property livert_dashes: string read flineinfos[tlk_vert].dashes write + setlivert_dashes; + property livert_dist: integer read flineinfos[tlk_vert].dist write + setlivert_dist default defaulttablinedist; + property livert_visible: linevisiblesty read flineinfos[tlk_vert].visible write + setlivert_visible default defaulttablinevisible; + + property libottom_widthmm: real read flineinfos[tlk_bottom].widthmm write + setlibottom_widthmm; + property libottom_color: colorty read flineinfos[tlk_bottom].color write + setlibottom_color default defaulttablinecolor; + property libottom_colorgap: colorty read flineinfos[tlk_bottom].colorgap write + setlibottom_colorgap default defaulttablinecolorgap; + property libottom_capstyle: capstylety read flineinfos[tlk_bottom].capstyle write + setlibottom_capstyle default defaulttablinecapstyle; + property libottom_dashes: string read flineinfos[tlk_bottom].dashes write + setlibottom_dashes; + property libottom_dist: integer read flineinfos[tlk_bottom].dist write + setlibottom_dist default defaulttablinedist; + property libottom_visible: linevisiblesty read flineinfos[tlk_bottom].visible write + setlibottom_visible default defaulttablinevisible; + + property ongetvalue: getrichstringeventty read fongetvalue write fongetvalue; + property distleft; //mm + property distright; //mm + end; + + treptabulators = class(tcustomtabulators) + private + finfo: drawtextinfoty; + fminsize: sizety; + fsizevalid: boolean; + flineinfos: tablineinfoarty; + flileft: tablineinfoty; + fliright: tablineinfoty; + fdistright: real; + fdistleft: real; + + flinksource: tcustomrecordband; + procedure setlitop_widthmm(const avalue: real); + procedure setlitop_color(const avalue: colorty); + procedure setlitop_colorgap(const avalue: colorty); + procedure setlitop_capstyle(const avalue: capstylety); + procedure setlitop_dashes(const avalue: string); + procedure setlitop_dist(const avalue: integer); + procedure setlitop_visible(const avalue: linevisiblesty); + + procedure setlileft_widthmm(const avalue: real); + procedure setlileft_color(const avalue: colorty); + procedure setlileft_colorgap(const avalue: colorty); + procedure setlileft_capstyle(const avalue: capstylety); + procedure setlileft_dashes(const avalue: string); + procedure setlileft_dist(const avalue: integer); + procedure setlileft_visible(const avalue: linevisiblesty); + + procedure setlivert_widthmm(const avalue: real); + procedure setlivert_color(const avalue: colorty); + procedure setlivert_colorgap(const avalue: colorty); + procedure setlivert_capstyle(const avalue: capstylety); + procedure setlivert_dashes(const avalue: string); + procedure setlivert_dist(const avalue: integer); + procedure setlivert_visible(const avalue: linevisiblesty); + + procedure setliright_widthmm(const avalue: real); + procedure setliright_color(const avalue: colorty); + procedure setliright_colorgap(const avalue: colorty); + procedure setliright_capstyle(const avalue: capstylety); + procedure setliright_dashes(const avalue: string); + procedure setliright_dist(const avalue: integer); + procedure setliright_visible(const avalue: linevisiblesty); + + procedure setlibottom_widthmm(const avalue: real); + procedure setlibottom_color(const avalue: colorty); + procedure setlibottom_colorgap(const avalue: colorty); + procedure setlibottom_capstyle(const avalue: capstylety); + procedure setlibottom_dashes(const avalue: string); + procedure setlibottom_dist(const avalue: integer); + procedure setlibottom_visible(const avalue: linevisiblesty); + + function getitems(const index: integer): treptabulatoritem; + procedure setitems(const index: integer; const avalue: treptabulatoritem); + procedure processvalues(const acanvas: tcanvas; const adest: rectty; + const apaint: boolean); + procedure setdistleft(const avalue: real); + procedure setdistright(const avalue: real); + procedure setlinksource(const avalue: tcustomrecordband); + protected + fband: tcustomrecordband; + class function getitemclass: tabulatoritemclassty; override; + procedure paint(const acanvas: tcanvas; const adest: rectty); + procedure checksize; + procedure recchanged; + procedure sourcechanged; + procedure dochange(const aindex: integer); override; + procedure setcount1(acount: integer; doinit: boolean); override; + procedure dobeforenextrecord(const adatasource: tdatasource); + procedure initsums; + procedure scale(const ascale: real); + public + constructor create(const aowner: tcustomrecordband); + procedure resetsums(const skipcurrent: boolean); + property items[const index: integer]: treptabulatoritem read getitems + write setitems; default; + published + + property litop_widthmm: real read flineinfos[tlk_top].widthmm write + setlitop_widthmm; + property litop_color: colorty read flineinfos[tlk_top].color write + setlitop_color default defaulttablinecolor; + property litop_colorgap: colorty read flineinfos[tlk_top].colorgap write + setlitop_colorgap default defaulttablinecolorgap; + property litop_capstyle: capstylety read flineinfos[tlk_top].capstyle write + setlitop_capstyle default defaulttablinecapstyle; + property litop_dashes: string read flineinfos[tlk_top].dashes write + setlitop_dashes; + property litop_dist: integer read flineinfos[tlk_top].dist write + setlitop_dist default defaulttablinedist; + property litop_visible: linevisiblesty read flineinfos[tlk_top].visible write + setlitop_visible default defaulttablinevisible; + + property lileft_widthmm: real read flileft.widthmm write + setlileft_widthmm; + property lileft_color: colorty read flileft.color write + setlileft_color default defaulttablinecolor; + property lileft_colorgap: colorty read flileft.colorgap write + setlileft_colorgap default defaulttablinecolorgap; + property lileft_capstyle: capstylety read flileft.capstyle write + setlileft_capstyle default defaulttablinecapstyle; + property lileft_dashes: string read flileft.dashes write + setlileft_dashes; + property lileft_dist: integer read flileft.dist write + setlileft_dist default defaulttablinedist; + property lileft_visible: linevisiblesty read flileft.visible write + setlileft_visible default defaulttablinevisible; + + property livert_widthmm: real read flineinfos[tlk_vert].widthmm write + setlivert_widthmm; + property livert_color: colorty read flineinfos[tlk_vert].color write + setlivert_color default defaulttablinecolor; + property livert_colorgap: colorty read flineinfos[tlk_vert].colorgap write + setlivert_colorgap default defaulttablinecolorgap; + property livert_capstyle: capstylety read flineinfos[tlk_vert].capstyle write + setlivert_capstyle default defaulttablinecapstyle; + property livert_dashes: string read flineinfos[tlk_vert].dashes write + setlivert_dashes; + property livert_dist: integer read flineinfos[tlk_vert].dist write + setlivert_dist default defaulttablinedist; + property livert_visible: linevisiblesty read flineinfos[tlk_vert].visible write + setlivert_visible default defaulttablinevisible; + + property liright_widthmm: real read fliright.widthmm write + setliright_widthmm; + property liright_color: colorty read fliright.color write + setliright_color default defaulttablinecolor; + property liright_colorgap: colorty read fliright.colorgap write + setliright_colorgap default defaulttablinecolorgap; + property liright_capstyle: capstylety read fliright.capstyle write + setliright_capstyle default defaulttablinecapstyle; + property liright_dashes: string read fliright.dashes write + setliright_dashes; + property liright_dist: integer read fliright.dist write + setliright_dist default defaulttablinedist; + property liright_visible: linevisiblesty read fliright.visible write + setliright_visible default defaulttablinevisible; + + property libottom_widthmm: real read flineinfos[tlk_bottom].widthmm write + setlibottom_widthmm; + property libottom_color: colorty read flineinfos[tlk_bottom].color write + setlibottom_color default defaulttablinecolor; + property libottom_colorgap: colorty read flineinfos[tlk_bottom].colorgap write + setlibottom_colorgap default defaulttablinecolorgap; + property libottom_capstyle: capstylety read flineinfos[tlk_bottom].capstyle + write setlibottom_capstyle default defaulttablinecapstyle; + property libottom_dashes: string read flineinfos[tlk_bottom].dashes write + setlibottom_dashes; + property libottom_dist: integer read flineinfos[tlk_bottom].dist write + setlibottom_dist default defaulttablinedist; + property libottom_visible: linevisiblesty read flineinfos[tlk_bottom].visible + write setlibottom_visible default defaulttablinevisible; + property distleft: real read fdistleft write setdistleft; //mm + property distright: real read fdistright write setdistright; //mm + property linksource: tcustomrecordband read flinksource write setlinksource; + property defaultdist; + end; + + recordbandstatety = (rbs_prepass,rbs_rendering,rbs_showed,rbs_pageshowed, + rbs_finish, + rbs_notfirstrecord,rbs_lastrecord,rbs_visibilitychecked, + rbs_nextrecordpending); + recordbandstatesty = set of recordbandstatety; + + ireportclient = interface(inullinterface) + function getwidget: twidget; + procedure updatevisibility; + procedure beginrender(const arestart: boolean); + procedure endrender; + procedure adddatasets(var adatasets: datasetarty); + procedure init; + procedure resetzebra; + procedure setppmm(const avalue: real); + end; + ireportclientarty = array of ireportclient; + + ibandparent = interface(inullinterface)[miid_ibandparent] + procedure registerclient(const aclient: ireportclient); + procedure unregisterclient(const aclient: ireportclient); + function beginband(const acanvas: tcanvas; + const sender: tcustomrecordband): boolean; + //true if area full + procedure endband(const acanvas: tcanvas; const sender: tcustomrecordband); + function istopband: boolean; + function isfirstband: boolean; + function islastband(const addheight: integer = 0): boolean; + function isfirstrecord: boolean; + function islastrecord: boolean; +// function isfirstofgroup: boolean; +// function islastofgroup: boolean; + procedure updatevisible; + function getwidget: twidget; + function remainingheight: integer; + procedure setareafull(const avalue: boolean); + function pagepagenum: integer; //null based + function reppagenum: integer; //null based + function getlastpagepagecount: integer; + function getlastreppagecount: integer; + function pageprintstarttime: tdatetime; + function repprintstarttime: tdatetime; + function getreppage: tcustomreportpage; + procedure resetzebra; + function getppmm: real; + end; + + trecordbanddatalink = class(tmsedatalink) + end; + + trepspacer = class(tlayouter,ireportclient) + private + foptionsrep: bandoptionshowsty; + fparentintf: ibandparent; + procedure setoptionsrep(const avalue: bandoptionshowsty); + protected + procedure parentchanged; override; //update fparentintf + procedure updatevisibility; + procedure beginrender(const arestart: boolean); + procedure endrender; + procedure adddatasets(var adatasets: datasetarty); + procedure init; + procedure resetzebra; + procedure setppmm(const avalue: real); + published + property optionsrep: bandoptionshowsty read foptionsrep + write setoptionsrep default []; + end; + + bandareaarty = array of tbasebandarea; + + recordbandarty = array of tcustomrecordband; + recordbandeventty = procedure(const sender: tcustomrecordband) of object; + + zebraoptionty = (zo_resetonpagestart,zo_resetparent); + zebraoptionsty = set of zebraoptionty; + + trepwidgetframe = class(tcaptionframe) + public + constructor create(const aintf: icaptionframe); + published + property framei_left default 1; + property framei_top default 1; + property framei_right default 1; + property framei_bottom default 1; + end; + + tcustomrecordband = class(tcustomscalingwidget,idbeditinfo,ireccontrol, + iobjectpicker,ireportclient,icaptionframe) + private + frecbands: recordbandarty; + fparentintf: ibandparent; + fonbeforerender: beforerenderrecordeventty; + fonafterrender: recordbandeventty; + fonpaint: painteventty; + fonafterpaint: painteventty; + ftextframe: int32; + ftabs: treptabulators; + fupdating: integer; + fdatalink: trecordbanddatalink; + fvisidatalink: tfielddatalink; + fvisigrouplink: tfielddatalink; + foptions: bandoptionsty; + foptionsshow: bandoptionshowsty; + fgroupnum: int64; + fgroupstring: msestring; + fnextgroupnum: integer; + fnextgroupstring: msestring; + fobjectpicker: tobjectpicker; + fnextband: tcustomrecordband; + fnextbandiflastofarea: tcustomrecordband; + fnextbandifempty: tcustomrecordband; + fnextbandiflast: tcustomrecordband; + fareas: bandareaarty; +// fonbeforepaint: painteventty; + fonbeforenextrecord: notifyeventty; + fonafternextrecord: notifyeventty; + fzebra_color: colorty; + fzebra_start: integer; + fzebra_height: integer; + fzebra_step: integer; + fzebra_counter: integer; + fzebra_options: zebraoptionsty; + procedure settextframe(const avalue: int32); + procedure settabs(const avalue: treptabulators); + procedure setoptionsshow(const avalue: bandoptionshowsty); + function getvisidatasource: tdatasource; + procedure setvisidatasource(const avalue: tdatasource); + function getvisidatafield: string; + procedure setvisidatafield(const avalue: string); + function getdatasource: tdatasource; overload; + procedure setdatasource(const avalue: tdatasource); virtual; + function getvisigroupfield: string; + procedure setvisigroupfield(const avalue: string); + //idbeditinfo + function getdataset(const aindex: integer): tdataset; overload; + procedure getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); + //ireccontrol + procedure recchanged; + procedure setnextband(const avalue: tcustomrecordband); + procedure setnextbandiflastofarea(const avalue: tcustomrecordband); + procedure setnextbandifempty(const avalue: tcustomrecordband); + procedure setnextbandiflast(const avalue: tcustomrecordband); + protected + fstate: recordbandstatesty; + procedure setfont(const avalue: trepwidgetfont); + function getfont: trepwidgetfont; + function getfontclass: widgetfontclassty; override; + + procedure internalcreateframe() override; + procedure registerchildwidget(const child: twidget); override; + procedure unregisterchildwidget(const child: twidget); override; + procedure minclientsizechanged; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + procedure fontchanged; override; + procedure clientrectchanged() override; + procedure inheritedpaint(const acanvas: tcanvas); + procedure parentchanged; override; //update fparentintf + function getminbandsize: sizety; virtual; + function calcminscrollsize: sizety; override; + function textarea(): rectty; + procedure render(const acanvas: tcanvas; var empty: boolean); virtual; + procedure init; virtual; + procedure initpage; virtual; + procedure beginrender(const arestart: boolean); virtual; + procedure endrender; virtual; + procedure adddatasets(var adatasets: datasetarty); virtual; + procedure dopaintforeground(const acanvas: tcanvas); override; + procedure doonpaint(const acanvas: tcanvas); override; + procedure doafterpaint(const acanvas: tcanvas); override; + procedure dobeforenextrecord(const adatasource: tdatasource); virtual; + procedure dosyncnextrecord; virtual; + + procedure nextrecord(const setflag: boolean = true); + function rendering: boolean; + function bandheight: integer; + procedure dobeforerender(var empty: boolean); virtual; + function bandisvisible(const checklast: boolean): boolean; + function getvisibility: boolean; + procedure updatevisibility; virtual; + function lastbandheight: integer; virtual; + procedure loaded; override; + + procedure setppmm(const avalue: real); + procedure clientmouseevent(var info: mouseeventinfoty); override; + //iobjectpicker + function getcursorshape(const sender: tobjectpicker; + var ashape: cursorshapety): boolean; + //true if found + procedure getpickobjects(const sender: tobjectpicker; + var aobjects: integerarty); + procedure beginpickmove(const sender: tobjectpicker); + procedure pickthumbtrack(const sender: tobjectpicker); + procedure endpickmove(const sender: tobjectpicker); + procedure cancelpickmove(const sender: tobjectpicker); + procedure paintxorpic(const sender: tobjectpicker; const acanvas: tcanvas); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure paint(const canvas: tcanvas); override; + function actualcolor: colorty; override; + procedure scale(const ascale: real); override; + procedure synctofontheight; override; + procedure beginupdate; + procedure endupdate; + function remainingbands: integer; + function reppage: tcustomreportpage; + procedure finish; + function isfirstrecord: boolean; + function islastrecord: boolean; + function isfirstofgroup: boolean; + function islastofgroup: boolean; + procedure restart; + procedure resetzebra; virtual; + + property textframe: int32 read ftextframe write settextframe default 1; + property tabs: treptabulators read ftabs write settabs; + property font: trepwidgetfont read getfont write setfont stored isfontstored; + property datasource: tdatasource read getdatasource write setdatasource; + property visidatasource: tdatasource read getvisidatasource + write setvisidatasource; + property visidatafield: string read getvisidatafield write setvisidatafield; + //controls visibility not null -> visible + property visigroupfield: string read getvisigroupfield write setvisigroupfield; + property options: bandoptionsty read foptions write foptions default []; + property optionsshow: bandoptionshowsty read foptionsshow write setoptionsshow default []; + property nextband: tcustomrecordband read fnextband write setnextband; + //used by tcustombandarea + property nextbandiflastofarea: tcustomrecordband read fnextbandiflastofarea + write setnextbandiflastofarea; + //used by tcustombandarea + property nextbandifempty: tcustomrecordband read fnextbandifempty + write setnextbandifempty; + //used by tcustombandarea + property nextbandiflast: tcustomrecordband read fnextbandiflast + write setnextbandiflast; + //used by tcustombandarea + property zebra_counter: integer read fzebra_counter write fzebra_counter; + property zebra_color: colorty read fzebra_color write fzebra_color default cl_infobackground; + property zebra_start: integer read fzebra_start write fzebra_start default 0; + property zebra_height: integer read fzebra_height write fzebra_height default 0; + property zebra_step: integer read fzebra_step write fzebra_step default 2; + property zebra_options: zebraoptionsty read fzebra_options + write fzebra_options default []; + + property onbeforerender: beforerenderrecordeventty read fonbeforerender + write fonbeforerender; +// property onbeforepaint: painteventty read fonbeforepaint write fonbeforepaint; + property onpaint: painteventty read fonpaint write fonpaint; + property onafterpaint: painteventty read fonafterpaint write fonafterpaint; + property onafterrender: recordbandeventty read fonafterrender + write fonafterrender; + property onbeforenextrecord: notifyeventty read fonbeforenextrecord + write fonbeforenextrecord; + property onafternextrecord: notifyeventty read fonafternextrecord + write fonafternextrecord; + published + property anchors default defaultbandanchors; + property optionswidget default defaultbandoptionswidget; + end; + + trecordband = class(tcustomrecordband) + published + property font; +// property fontempty; + property textframe; + property tabs; + property datasource; + property options; + property optionsshow; + property optionsscale; + property visidatasource; + property visidatafield; + property visigroupfield; + property nextband; + property nextbandiflastofarea; + property nextbandifempty; + property nextbandiflast; + + property zebra_color; + property zebra_start; + property zebra_height; + property zebra_step; + property zebra_options; + property onfontheightdelta; + property onlayout; + + property onbeforerender; + property onbeforepaint; + property onpaint; + property onafterpaint; + property onafterrender; + property onbeforenextrecord; + property onafternextrecord; + end; + + tcustomrepvaluedisp = class; + getrepvaluetexteventty = procedure(const sender: tcustomrepvaluedisp; + var atext: msestring) of object; + + tcustomrepvaluedisp = class(tcustomrecordband) + private + ftextflags: textflagsty; + fformat: msestring; + fongettext: getrepvaluetexteventty; + procedure setformat(const avalue: msestring); + procedure settextflags(const avalue: textflagsty); + protected + function calcminscrollsize: sizety; override; + procedure dopaintforeground(const acanvas: tcanvas); override; + procedure dogettext(var atext: msestring); + function getdisptext: msestring; virtual; + procedure render(const acanvas: tcanvas; var empty: boolean); override; + public + constructor create(aowner: tcomponent); override; + property textflags: textflagsty read ftextflags write settextflags default + defaultrepvaluedisptextflags; + property format: msestring read fformat write setformat; + property optionsscale default defaultrepvaluedispoptionsscale; + property ongettext: getrepvaluetexteventty read fongettext write fongettext; + property options default defaultrepvaluedispoptions; + published + property anchors default [an_left,an_top]; + end; + + trepvaluedisp = class(tcustomrepvaluedisp) + private + fvalue: msestring; + procedure setvalue(const avalue: msestring); + protected + function getdisptext: msestring; override; + procedure dobeforerender(var empty: boolean); override; + published + property value: msestring read fvalue write setvalue; + property font; +// property tabs; +// property datasource; + property textflags; + property textframe; + property options; + property optionsshow; + property optionsscale; + property visidatasource; + property visidatafield; + property visigroupfield; + property zebra_color; + property zebra_start; + property zebra_height; + property zebra_step; + property zebra_options; + property onfontheightdelta; + property onlayout; + + property onbeforerender; + property onbeforepaint; + property onpaint; + property onafterpaint; + property onafterrender; + property ongettext; + end; + + treppagenumdisp = class(trepvaluedisp) + private + foffset: integer; + procedure setoffset(const avalue: integer); + protected + function getdisptext: msestring; override; + procedure initpage; override; + procedure parentchanged; override; + public + constructor create(aowner: tcomponent); override; + published + property offset: integer read foffset write setoffset default 1; + property format; //'1' returns lastpagecount + end; + + trepprintdatedisp = class(trepvaluedisp) + protected + procedure initpage; override; + procedure parentchanged; override; + function getdisptext: msestring; override; + published + property format; + end; + + tcustombandgroup = class(tcustomrecordband,ibandparent) + private + procedure setdatasource(const avalue: tdatasource); override; + //ibandparent; + procedure registerclient(const aclient: ireportclient); + procedure unregisterclient(const aclient: ireportclient); + function beginband(const acanvas: tcanvas; + const sender: tcustomrecordband): boolean; + //true if area full + procedure endband(const acanvas: tcanvas; const sender: tcustomrecordband); + function istopband: boolean; + function isfirstband: boolean; + function islastband(const addheight: integer = 0): boolean; + procedure updatevisible; + function getwidget: twidget; + function remainingheight: integer; + function pagepagenum: integer; //null based + function reppagenum: integer; //null based + function getlastpagepagecount: integer; + function getlastreppagecount: integer; + function pageprintstarttime: tdatetime; + function repprintstarttime: tdatetime; + function getreppage: tcustomreportpage; + protected + procedure dobeforenextrecord(const adatasource: tdatasource); override; + procedure dosyncnextrecord; override; + function getppmm: real; + procedure setparentwidget(const avalue: twidget); override; + procedure registerchildwidget(const child: twidget); override; + procedure unregisterchildwidget(const child: twidget); override; + procedure dobeforerender(var empty: boolean); override; + procedure dopaint(const acanvas: tcanvas); override; +// procedure updatevisibility; override; + function getminbandsize: sizety; override; + procedure initpage; override; + procedure init; override; + procedure beginrender(const arestart: boolean); override; + procedure endrender; override; + procedure adddatasets(var adatasets: datasetarty); override; + function lastbandheight: integer; override; + procedure setareafull(const avalue: boolean); + public + procedure resetzebra; override; + property font: trepwidgetfont read getfont write setfont stored isfontstored; + end; + + tbandgroup = class(tcustombandgroup) + published + property font; +// property fontempty; + property tabs; + property datasource; + property nextband; + property nextbandiflastofarea; + property nextbandifempty; + property nextbandiflast; + property options; + property optionsshow; + property optionsscale; + property visidatasource; + property visidatafield; + property visigroupfield; + property zebra_color; + property zebra_start; + property zebra_height; + property zebra_step; + property zebra_options; + + property onfontheightdelta; + property onlayout; + + property onbeforerender; + property onpaint; + property onafterpaint; + property onafterrender; + end; + + bandareastatety = (bas_inited,bas_backgroundrendered,bas_areafull, + bas_rendering, + bas_top,bas_notfirstband,bas_lastband,bas_bandstarted, + bas_activebandchanged,bas_finished); + bandareastatesty = set of bandareastatety; + + bandareaeventty = procedure(const sender: tbasebandarea) of object; + bandareapainteventty = procedure(const sender: tbasebandarea; + const acanvas: tcanvas) of object; + + tbasebandarea = class(tpublishedwidget,ibandparent) + private + fareabands: recordbandarty; + fstate: bandareastatesty; + freportpage: tcustomreportpage; + frecordband: tcustomrecordband; + fonbeforerender: bandareaeventty; + fonafterrender: bandareaeventty; + fonpaint: bandareapainteventty; + fonafterpaint: bandareapainteventty; + fonfirstarea: bandareaeventty; + fonlastarea: bandareaeventty; + forigin: pointty; + fsaveindex: integer; + function getareafull: boolean; + procedure setareafull(const avalue: boolean); + protected + procedure registerchildwidget(const child: twidget); override; + procedure unregisterchildwidget(const child: twidget); override; + procedure setparentwidget(const avalue: twidget); override; + procedure renderbackground(const acanvas: tcanvas); + function render(const acanvas: tcanvas): boolean; virtual; + //true if finished + function rendering: boolean; + procedure beginrender(const arestart: boolean); + procedure endrender; + procedure adddatasets(var adatasets: datasetarty); + procedure dofirstarea; virtual; + procedure dobeforerender; virtual; + procedure doonpaint(const acanvas: tcanvas); override; + procedure doafterpaint1(const acanvas: tcanvas); virtual; + procedure init; virtual; + procedure initareapage; virtual; + procedure initband; virtual; + procedure initpage; + procedure dobeforenextrecord(const adatasource: tdatasource); + procedure dosyncnextrecord; + function checkareafull(ay: integer): boolean; + procedure setppmm(const avalue: real); + //ibandparent + function getppmm: real; + procedure registerclient(const aclient: ireportclient); + procedure unregisterclient(const aclient: ireportclient); + function beginband(const acanvas: tcanvas; + const sender: tcustomrecordband): boolean; virtual; + //true if area full + procedure endband(const acanvas: tcanvas; + const sender: tcustomrecordband); virtual; + procedure updatevisible; + function getlastpagepagecount: integer; + function getlastreppagecount: integer; + procedure setfont(const avalue: trepwidgetfont); + function getfont: trepwidgetfont; + function getfontclass: widgetfontclassty; override; + public + procedure paint(const canvas: tcanvas); override; + function isfirstrecord: boolean; + function islastrecord: boolean; + function istopband: boolean; virtual; + function isfirstband: boolean; virtual; + function islastband(const addheight: integer = 0): boolean; virtual; + function remainingheight: integer; virtual; + + function pagepagenum: integer; //null based + function reppagenum: integer; //null based + function pageprintstarttime: tdatetime; + function repprintstarttime: tdatetime; + function getreppage: tcustomreportpage; + + procedure restart; virtual; + procedure resetzebra; + + property font: trepwidgetfont read getfont write setfont stored isfontstored; + property onfirstarea: bandareaeventty read fonfirstarea write fonfirstarea; + property onlastarea: bandareaeventty read fonlastarea write fonlastarea; + property onbeforerender: bandareaeventty read fonbeforerender + write fonbeforerender; + property onafterrender: bandareaeventty read fonafterrender + write fonafterrender; + property onpaint: bandareapainteventty read fonpaint write fonpaint; + property onafterpaint: bandareapainteventty read fonafterpaint write fonafterpaint; + end; + + bandareaoptionty = (bao_nopagerestart); + bandareaoptionsty = set of bandareaoptionty; + + tcustombandarea = class(tbasebandarea) + private + factiveband: integer; + facty: integer; + factybefore: integer; + fbandnum: integer; + function getacty: integer; + protected + foptions: bandareaoptionsty; + procedure init; override; + procedure initband; override; + procedure initareapage; override; + function render(const acanvas: tcanvas): boolean; override; + //true if finished + function beginband(const acanvas: tcanvas; + const sender: tcustomrecordband): boolean; override; + //true if area full + procedure endband(const acanvas: tcanvas; + const sender: tcustomrecordband); override; + public + function isfirstband: boolean; override; + function islastband(const addheight: integer = 0): boolean; override; + function remainingheight: integer; override; + procedure restart; override; + + property acty: integer read getacty; + property areafull: boolean read getareafull write setareafull; + property options: bandareaoptionsty read foptions write foptions default []; + end; + + tbandarea = class(tcustombandarea) + published + property font; +// property fontempty; + property options; + property onfirstarea; + property onlastarea; + property onbeforerender; + property onafterrender; + property onpaint; + property onafterpaint; + end; + + tileareaoptionty = (tao_vertical); + tileareaoptionsty = set of tileareaoptionty; + + tcustomtilearea = class(tbasebandarea) + private + fcolcount: integer; + frowcount: integer; + fcellorigin: pointty; + flihorz: tablineinfoty; + flivert: tablineinfoty; + flileft: tablineinfoty; + flitop: tablineinfoty; + fliright: tablineinfoty; + flibottom: tablineinfoty; + foptions: tileareaoptionsty; + procedure setcolcount(const avalue: integer); + procedure setrowcount(const avalue: integer); + + procedure setlivert_widthmm(const avalue: real); + procedure setlivert_color(const avalue: colorty); + procedure setlivert_colorgap(const avalue: colorty); + procedure setlivert_capstyle(const avalue: capstylety); + procedure setlivert_dashes(const avalue: string); + + procedure setlihorz_widthmm(const avalue: real); + procedure setlihorz_color(const avalue: colorty); + procedure setlihorz_colorgap(const avalue: colorty); + procedure setlihorz_capstyle(const avalue: capstylety); + procedure setlihorz_dashes(const avalue: string); + + procedure setlileft_widthmm(const avalue: real); + procedure setlileft_color(const avalue: colorty); + procedure setlileft_colorgap(const avalue: colorty); + procedure setlileft_capstyle(const avalue: capstylety); + procedure setlileft_dashes(const avalue: string); + procedure setlileft_dist(const avalue: integer); + + procedure setlitop_widthmm(const avalue: real); + procedure setlitop_color(const avalue: colorty); + procedure setlitop_colorgap(const avalue: colorty); + procedure setlitop_capstyle(const avalue: capstylety); + procedure setlitop_dashes(const avalue: string); + procedure setlitop_dist(const avalue: integer); + + procedure setliright_widthmm(const avalue: real); + procedure setliright_color(const avalue: colorty); + procedure setliright_colorgap(const avalue: colorty); + procedure setliright_capstyle(const avalue: capstylety); + procedure setliright_dashes(const avalue: string); + procedure setliright_dist(const avalue: integer); + + procedure setlibottom_widthmm(const avalue: real); + procedure setlibottom_color(const avalue: colorty); + procedure setlibottom_colorgap(const avalue: colorty); + procedure setlibottom_capstyle(const avalue: capstylety); + procedure setlibottom_dashes(const avalue: string); + procedure setlibottom_dist(const avalue: integer); + + protected + procedure drawline(const acanvas: tcanvas; const ainfo: tablineinfoty; + const start,stop: pointty); + procedure drawlines(const acanvas: tcanvas); + procedure dopaintoverlay(const canvas: tcanvas); override; + function render(const acanvas: tcanvas): boolean; override; + //true if finished + function beginband(const acanvas: tcanvas; + const sender: tcustomrecordband): boolean; override; + procedure endband(const acanvas: tcanvas; const sender: tcustomrecordband); override; + public + constructor create(aowner: tcomponent); override; + function cellwidthmm: real; + function cellheightmm: real; + function cellsize: sizety; + function cellrect: rectty; + + property colcount: integer read fcolcount write setcolcount default 2; + property rowcount: integer read frowcount write setrowcount default 2; + + property livert_widthmm: real read flivert.widthmm write + setlivert_widthmm; + property livert_color: colorty read flivert.color write + setlivert_color default defaulttablinecolor; + property livert_colorgap: colorty read flivert.colorgap write + setlivert_colorgap default defaulttablinecolorgap; + property livert_capstyle: capstylety read flivert.capstyle write + setlivert_capstyle default defaulttablinecapstyle; + property livert_dashes: string read flivert.dashes write + setlivert_dashes; + + property lihorz_widthmm: real read flihorz.widthmm write + setlihorz_widthmm; + property lihorz_color: colorty read flihorz.color write + setlihorz_color default defaulttablinecolor; + property lihorz_colorgap: colorty read flihorz.colorgap write + setlihorz_colorgap default defaulttablinecolorgap; + property lihorz_capstyle: capstylety read flihorz.capstyle write + setlihorz_capstyle default defaulttablinecapstyle; + property lihorz_dashes: string read flihorz.dashes write + setlihorz_dashes; + + property lileft_widthmm: real read flileft.widthmm write + setlileft_widthmm; + property lileft_color: colorty read flileft.color write + setlileft_color default defaulttablinecolor; + property lileft_colorgap: colorty read flileft.colorgap write + setlileft_colorgap default defaulttablinecolorgap; + property lileft_capstyle: capstylety read flileft.capstyle write + setlileft_capstyle default defaulttablinecapstyle; + property lileft_dashes: string read flileft.dashes write + setlileft_dashes; + property lileft_dist: integer read flileft.dist write + setlileft_dist default defaulttablinedist; + + property litop_widthmm: real read flitop.widthmm write + setlitop_widthmm; + property litop_color: colorty read flitop.color write + setlitop_color default defaulttablinecolor; + property litop_colorgap: colorty read flitop.colorgap write + setlitop_colorgap default defaulttablinecolorgap; + property litop_capstyle: capstylety read flitop.capstyle write + setlitop_capstyle default defaulttablinecapstyle; + property litop_dashes: string read flitop.dashes write + setlitop_dashes; + property litop_dist: integer read flitop.dist write + setlitop_dist default defaulttablinedist; + + property liright_widthmm: real read fliright.widthmm write + setliright_widthmm; + property liright_color: colorty read fliright.color write + setliright_color default defaulttablinecolor; + property liright_colorgap: colorty read fliright.colorgap write + setliright_colorgap default defaulttablinecolorgap; + property liright_capstyle: capstylety read fliright.capstyle write + setliright_capstyle default defaulttablinecapstyle; + property liright_dashes: string read fliright.dashes write + setliright_dashes; + property liright_dist: integer read fliright.dist write + setliright_dist default defaulttablinedist; + + property libottom_widthmm: real read flibottom.widthmm write + setlibottom_widthmm; + property libottom_color: colorty read flibottom.color write + setlibottom_color default defaulttablinecolor; + property libottom_colorgap: colorty read flibottom.colorgap write + setlibottom_colorgap default defaulttablinecolorgap; + property libottom_capstyle: capstylety read flibottom.capstyle write + setlibottom_capstyle default defaulttablinecapstyle; + property libottom_dashes: string read flibottom.dashes write + setlibottom_dashes; + property libottom_dist: integer read flibottom.dist write + setlibottom_dist default defaulttablinedist; + + property options: tileareaoptionsty read foptions write foptions default []; + end; + + ttilearea = class(tcustomtilearea) + published + property colcount; + property rowcount; + + property livert_widthmm; + property livert_color; + property livert_colorgap; + property livert_capstyle; + property livert_dashes; + + property lihorz_widthmm; + property lihorz_color; + property lihorz_colorgap; + property lihorz_capstyle; + property lihorz_dashes; + + property lileft_widthmm; + property lileft_color; + property lileft_colorgap; + property lileft_capstyle; + property lileft_dashes; + property lileft_dist; + + property litop_widthmm; + property litop_color; + property litop_colorgap; + property litop_capstyle; + property litop_dashes; + property litop_dist; + + property liright_widthmm; + property liright_color; + property liright_colorgap; + property liright_capstyle; + property liright_dashes; + property liright_dist; + + property libottom_widthmm; + property libottom_color; + property libottom_colorgap; + property libottom_capstyle; + property libottom_dashes; + property libottom_dist; + + property options; + + property font; +// property fontempty; + property onfirstarea; + property onlastarea; + property onbeforerender; + property onafterrender; + property onpaint; + property onafterpaint; + end; + + reportpagestatety = (rpps_inited,rpps_sizesetting,rpps_rendering, + rpps_backgroundrendered, + rpps_restart, + rpps_showed,rpps_finish,rpps_notfirstrecord,rpps_lastrecord, + rpps_nextrecordpending); + reportpagestatesty = set of reportpagestatety; + + tcustomreport = class; + + treportpagedatalink = class(tmsedatalink) + end; + + reportpageoptionty = (rpo_once,rpo_firsteven,rpo_firstodd, + rpo_delayednextrecord,rpo_datasourceonly, + rpo_reportpagewidth,rpo_reportpageheight); + reportpageoptionsty = set of reportpageoptionty; + + reportpageeventty = procedure(const sender: tcustomreportpage) of object; + reportpagepainteventty = procedure(const sender: tcustomreportpage; + const acanvas: tcanvas) of object; + beforerenderpageeventty = procedure(const sender: tcustomreportpage; + var empty: boolean) of object; + reppageorientationty = (rpo_default,rpo_portrait,rpo_landscape); + + tcustomreportpage = class(twidget,ibandparent) + private + fbands: recordbandarty; + fclients: ireportclientarty; + fareas: bandareaarty; + fstate: reportpagestatesty; + fonbeforerender: beforerenderpageeventty; + fonafterrender: reportpageeventty; + fonpaint: reportpagepainteventty; + fonafterpaint: reportpagepainteventty; + fpagedim: sizety; + fpagewidth: real; + fpageheight: real; + fppmm: real; + fvisiblepage: boolean; + fpagenum: integer; + fonfirstpage: reportpageeventty; + fonafterlastpage: reportpageeventty; + fnextpage: tcustomreportpage; + fnextpageifempty: tcustomreportpage; + fnextpageiflast: tcustomreportpage; + fsaveindex: integer; + fdatalink: treportpagedatalink; + foptions: reportpageoptionsty; + fprintstarttime: tdatetime; + freccontrols: pointerarty; + fprintorientation: reppageorientationty; + flastpagecount: integer; + fonbeforenextrecord: notifyeventty; + fonafternextrecord: notifyeventty; + procedure setpagewidth(const avalue: real); + procedure setpageheight(const avalue: real); + procedure updatepagesize; + procedure setppmm(const avalue: real); + procedure setnextpage(const avalue: tcustomreportpage); + procedure setnextpageifempty(const avalue: tcustomreportpage); + procedure setnextpageiflast(const avalue: tcustomreportpage); + function getdatasource: tdatasource; + procedure setdatasource(const avalue: tdatasource); + procedure setoptions(const avalue: reportpageoptionsty); + protected + freport: tcustomreport; + procedure registerchildwidget(const child: twidget); override; + procedure unregisterchildwidget(const child: twidget); override; + procedure setparentwidget(const avalue: twidget); override; + procedure sizechanged; override; + + procedure setfont(const avalue: trepwidgetfont); + function getfont: trepwidgetfont; + function getfontclass: widgetfontclassty; override; + + procedure renderbackground(const acanvas: tcanvas); + procedure beginrender(const arestart: boolean); + procedure endrender; + procedure adddatasets(var adatasets: datasetarty); + function rendering: boolean; + procedure beginarea(const acanvas: tcanvas; const sender: tbasebandarea); + procedure dofirstpage; virtual; + procedure dobeforerender(var empty: boolean); virtual; + procedure doonpaint(const acanvas: tcanvas); override; + procedure doafterpaint1(const acanvas: tcanvas); virtual; + procedure doafterlastpage; virtual; + procedure dobeforenextrecord(const adatasource: tdatasource); + procedure dosyncnextrecord; + property ppmm: real read fppmm write setppmm; //pixel per mm + + procedure init; virtual; + procedure nextrecord; + function render(const acanvas: tcanvas): boolean; + //true if empty + + //ibandparent + function getppmm: real; + procedure registerclient(const aclient: ireportclient); + procedure unregisterclient(const aclient: ireportclient); + function beginband(const acanvas: tcanvas; + const sender: tcustomrecordband): boolean; + procedure endband(const acanvas: tcanvas; const sender: tcustomrecordband); + function istopband: boolean; + function isfirstband: boolean; + function islastband(const addheight: integer = 0): boolean; + procedure setareafull(const avalue: boolean); + + procedure updatevisible; + function remainingheight: integer; + function pagepagenum: integer; //null based + function reppagenum: integer; //null based + function pageprintstarttime: tdatetime; + function repprintstarttime: tdatetime; + function getreppage: tcustomreportpage; + function getlastpagepagecount: integer; + function getlastreppagecount: integer; + + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + + function isfirstrecord: boolean; + function islastrecord: boolean; + procedure insertwidget(const awidget: twidget; const apos: pointty); override; + + procedure recordchanged; + property report: tcustomreport read freport; + property pagenum: integer read fpagenum write fpagenum; + //null-based, local to this page + property lastpagecount: integer read getlastpagepagecount write flastpagecount; + //local to this page + property printstarttime: tdatetime read fprintstarttime write fprintstarttime; + property visiblepage: boolean read fvisiblepage write fvisiblepage default true; + procedure activatepage; + procedure finish; + procedure restart; + procedure resetzebra; + + property pagewidth: real read fpagewidth write setpagewidth; + //mm, 0 -> use report value + property pageheight: real read fpageheight write setpageheight; + //mm, 0 -> use report value + function getpagewidth: real; //actual value + function getpageheight: real; //actual value + + property font: trepwidgetfont read getfont write setfont stored isfontstored; + property nextpage: tcustomreportpage read fnextpage write setnextpage; + property nextpageifempty: tcustomreportpage read fnextpageifempty write + setnextpageifempty; + property nextpageiflast: tcustomreportpage read fnextpageiflast write + setnextpageiflast; + property datasource: tdatasource read getdatasource write setdatasource; + property options: reportpageoptionsty read foptions write setoptions + default []; + property printorientation: reppageorientationty read fprintorientation + write fprintorientation default rpo_default; + //default --> printer.canvas value + + property onfirstpage: reportpageeventty read fonfirstpage + write fonfirstpage; + property onbeforerender: beforerenderpageeventty read fonbeforerender + write fonbeforerender; + property onafterrender: reportpageeventty read fonafterrender + write fonafterrender; + property onpaint: reportpagepainteventty read fonpaint write fonpaint; + property onafterpaint: reportpagepainteventty read fonafterpaint + write fonafterpaint; + property onbeforenextrecord: notifyeventty read fonbeforenextrecord + write fonbeforenextrecord; + property onafternextrecord: notifyeventty read fonafternextrecord + write fonafternextrecord; + property onafterlastpage: reportpageeventty read fonafterlastpage + write fonafterlastpage; + end; + + reportpagearty = array of tcustomreportpage; + + treportpage = class(tcustomreportpage) + published + property pagewidth; + property pageheight; + property color; + property frame; + property face; + property visible; + property font; +// property fontempty; + property nextpage; + property nextpageifempty; + property nextpageiflast; + property visiblepage; + property datasource; + property options; + property printorientation; + + property onfirstpage; + property onbeforerender; + property onafterrender; + property onpaint; + property onafterpaint; + property onbeforenextrecord; + property onafternextrecord; + property onafterlastpage; + end; + + repdesigninfoty = record + widgetrect: rectty; + gridsize: real; + showgrid: boolean; + snaptogrid: boolean; + end; + prepdesigninfoty = ^repdesigninfoty; + + treppageform = class(treportpage) + private + function getgrid_show: boolean; + procedure setgrid_show(const avalue: boolean); + function getgrid_snap: boolean; + procedure setgrid_snap(const avalue: boolean); + function getgrid_size: real; + procedure setgrid_size(avalue: real); + procedure writerepdesigninfo(writer: twriter); + procedure readrepdesigninfo(reader: treader); + protected + frepdesigninfo: repdesigninfoty; + class function hasresource(): boolean override; + class function getmoduleclassname(): string override; + procedure defineproperties(filer: tfiler) override; + public + constructor create(aowner: tcomponent); overload; override; + constructor create(aowner: tcomponent; load: boolean); + overload; virtual; + published + property grid_show: boolean read frepdesigninfo.showgrid + write setgrid_show default true; + property grid_snap: boolean read frepdesigninfo.snaptogrid + write setgrid_snap default true; + property grid_size: real read frepdesigninfo.gridsize write setgrid_size; + property ppmm; + property color default cl_transparent; + end; + + reppageformclassty = class of treppageform; + + repstatety = (rs_activepageset,rs_finish,rs_restart,rs_running,rs_endpass, + rs_dummypage); + repstatesty = set of repstatety; + + reporteventty = procedure(const sender: tcustomreport) of object; + preambleeventty = procedure(const sender: tcustomreport; var apreamble: string) of object; + + tcustomreport = class(twidget) + private + fppmm: real; + fonreportstart: reporteventty; + fonbeforerender: reporteventty; + fonafterrender: reporteventty; + fonreportfinished: notifyeventty; + fprinter: tcustomprinter; //preliminary + fstream: ttextstream; + fstreamset: boolean; + fcommand: msestring; + fcanvas: tcanvas; + fpagenum: integer; + fthread: tmsethread; + fcanceled: boolean; + fppmmbefore: real; + fstate: repstatesty; + factivepage: integer; + fprintstarttime: tdatetime; + fonprogress: notifyeventty; + fonrenderfinish: reporteventty; + fnilstream: boolean; + foptions: reportoptionsty; + flastpagecount: integer; +// fonloaded: notifyeventty; + fonpreamble: preambleeventty; + fdialogtext: msestring; + fdialogcaption: msestring; + fdatasets: datasetarty; + fonpagebeforerender: beforerenderpageeventty; + fonpageafterpaint: reportpagepainteventty; + fonpagepaint: reportpagepainteventty; + fpagewidth: real; + fpageheight: real; + procedure setppmm(const avalue: real); + function getreppages(index: integer): tcustomreportpage; + procedure setreppages(index: integer; const avalue: tcustomreportpage); + function getgrid_show: boolean; + procedure setgrid_show(const avalue: boolean); + function getgrid_snap: boolean; + procedure setgrid_snap(const avalue: boolean); + function getgrid_size: real; + procedure setgrid_size(avalue: real); + procedure writerepdesigninfo(writer: twriter); + procedure readrepdesigninfo(reader: treader); + function exec(thread: tmsethread): integer; + function getcanceled: boolean; + procedure setcanceled(const avalue: boolean); + function getrunning: boolean; + procedure setactivepage(const avalue: integer); + procedure doexec(const sender: tobject); + procedure docancel(const sender: tobject); + procedure setpagewidth(const avalue: real); + procedure setpageheight(const avalue: real); + protected + frepdesigninfo: repdesigninfoty; + freppages: reportpagearty; + fdefaultprintorientation: pageorientationty; + class function hasresource: boolean override; + procedure updatepagesize; + procedure dopagebeforerender(const sender: tcustomreportpage; + var empty: boolean); + procedure dopagepaint(const sender: tcustomreportpage; + const acanvas: tcanvas); + procedure dopageafterpaint(const sender: tcustomreportpage; + const acanvas: tcanvas); + + procedure internalrender(const acanvas: tcanvas; const aprinter: tcustomprinter; + const acommand: msestring; const astream: ttextstream; + const anilstream: boolean; const onafterrender: reporteventty); + procedure initpage(const apage: tcustomreportpage); + procedure unregisterchildwidget(const child: twidget); override; + procedure getchildren(proc: tgetchildproc; root: tcomponent); override; + procedure defineproperties(filer: tfiler); override; + procedure nextpage(const acanvas: tcanvas); + procedure doprogress; + procedure doasyncevent(var atag: integer); override; + procedure notification(acomponent: tcomponent; + operation: toperation); override; + procedure setfont(const avalue: trepfont); + function getfont: trepfont; + function getfontclass: widgetfontclassty; override; + function getdialogcaption: msestring virtual; + function getdialogtext: msestring virtual; +// procedure doloaded; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + + procedure insertwidget(const awidget: twidget; const apos: pointty) override; + function add(const apage: tcustomreportpage; + aindex: int32 = bigint): tcustomreportpage; + //report owns page + procedure delete(const aindex: int32); + procedure clear(); + procedure movepage(const curindex,newindex: int32); + + procedure render(const acanvas: tcanvas; + const onafterrender: reporteventty = nil); overload; + procedure render(const aprinter: tstreamprinter; + const command: msestring = ''; + const onafterrender: reporteventty = nil); overload; + procedure render(const aprinter: tstreamprinter; + const astream: ttextstream; //owns the stream + const onafterrender: reporteventty = nil); overload; + procedure render(const aprinter: tcustomgdiprinter; + const onafterrender: reporteventty = nil); overload; + procedure waitfor; //returns before calling of onafterrender + function prepass: boolean; //true if in prepass render state + procedure restart; + procedure recordchanged; + //calls recordchanged of active page + + property ppmm: real read fppmm write setppmm; //pixel per mm + property pagewidth: real read fpagewidth write setpagewidth; + //mm, default 190 + property pageheight: real read fpageheight write setpageheight; + //mm, default 270 + + function reppagecount: integer; + property reppages[index: integer]: tcustomreportpage read getreppages + write setreppages; default; + property pagenum: integer read fpagenum {write fpagenum}; + //null-based + property lastpagecount: integer read flastpagecount write flastpagecount; + property activepage: integer read factivepage write setactivepage; + procedure finish; + property printstarttime: tdatetime read fprintstarttime + write fprintstarttime; + property nilstream: boolean read fnilstream; + //true if reder called with nil stream + + property font: trepfont read getfont write setfont; + property color default cl_transparent; + property grid_show: boolean read frepdesigninfo.showgrid + write setgrid_show default true; + property grid_snap: boolean read frepdesigninfo.snaptogrid + write setgrid_snap default true; + property grid_size: real read frepdesigninfo.gridsize write setgrid_size; + property canceled: boolean read getcanceled write setcanceled; + property running: boolean read getrunning; + property options: reportoptionsty read foptions write foptions + default defaultreportoptions; + property dialogtext: msestring read fdialogtext write fdialogtext; + property dialogcaption: msestring read fdialogcaption write fdialogcaption; + + property onpreamble: preambleeventty read fonpreamble write fonpreamble; + property onreportstart: reporteventty read fonreportstart + write fonreportstart; + property onbeforerender: reporteventty read fonbeforerender + write fonbeforerender; + property onafterrender: reporteventty read fonafterrender + write fonafterrender; + property onreportfinished: notifyeventty read fonreportfinished + write fonreportfinished; + //executed in main thread context + property onpagebeforerender: beforerenderpageeventty + read fonpagebeforerender write fonpagebeforerender; + property onpagepaint: reportpagepainteventty read fonpagepaint + write fonpagepaint; + property onpageafterpaint: reportpagepainteventty read fonpageafterpaint + write fonpageafterpaint; + property onprogress: notifyeventty read fonprogress write fonprogress; +// property onloaded: notifyeventty read fonloaded write fonloaded; + end; + + treport = class(tcustomreport) + private + fstatfile: tstatfile; + foncreate: notifyeventty; + foncreated: notifyeventty; + fonloaded: notifyeventty; + fondestroy: notifyeventty; + fondestroyed: notifyeventty; + procedure setstatfile(const avalue: tstatfile); + protected + class function getmoduleclassname: string; override; + class function hasresource: boolean; override; + procedure doafterload; override; + procedure dooncreate; virtual; + procedure readstate(reader: treader); override; + procedure autoreadstat; + public + constructor create(aowner: tcomponent); overload; override; + constructor create(aowner: tcomponent; load: boolean); + overload; virtual; + destructor destroy; override; + procedure beforedestruction; override; + procedure reload; + procedure afterconstruction; override; + published + property statfile: tstatfile read fstatfile write setstatfile; + property color; + property ppmm; + property pagewidth; + property pageheight; + property font; +// property fontempty; + property grid_show; + property grid_snap; + property grid_size; + property options; + property dialogtext; + property dialogcaption; + property onpreamble; + property onreportstart; + property onbeforerender; + property onafterrender; + property onreportfinished; + property onpagebeforerender; + property onpagepaint; + property onpageafterpaint; + property onprogress; + property oncreate: notifyeventty read foncreate write foncreate; + property oncreated: notifyeventty read foncreated write foncreated; + property onloaded: notifyeventty read fonloaded write fonloaded; + property ondestroy: notifyeventty read fondestroy write fondestroy; + property ondestroyed: notifyeventty read fondestroyed write fondestroyed; + end; + + reportclassty = class of treport; + +function createreport(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; +procedure initreportcomponent(const amodule: tcomponent; + const acomponent: tcomponent); +function getreportscale(const amodule: tcomponent): real; +function createreppageform(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; +function getreppageformscale(const amodule: tcomponent): real; + +implementation +uses + msearrayutils,sysutils,msestreaming,msebits,msereal,math,msesysintf,msesys, + msedate; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tcustomframe1 = class(tcustomframe); + twidget1 = class(twidget); + twindow1 = class(twindow); + tmsecomponent1 = class(tmsecomponent); + tdataset1 = class(tdataset); + tcanvas1 = class(tcanvas); + tifilink1 = class(tifilinkcomp); + +function checkdashes(const avalue: string): string; +var + int1: integer; +begin + result:= avalue; + for int1:= 1 to length(avalue) do begin + if avalue[int1] = #0 then begin + setlength(result,int1-1); //remove nulls + break; + end; + end; +end; + +procedure renderingerror; +begin + raise exception.create('Operation not possible while rendering'); +end; +{ +function checkisfirstrecord(const adatalink: tmsedatalink; + out avalue: boolean): boolean; //true if adatalink active +begin + result:= adatalink.active; + if result then begin + avalue:= adatalink.dataset.recno = 1; + end + else begin + avalue:= false; + end; +end; + +function checkislastrecord(const adatalink: tmsedatalink; + out avalue: boolean): boolean; //true if adatalink active +begin + result:= adatalink.active; + if result then begin + avalue:= adatalink.dataset.recno = adatalink.dataset.recordcount; + end + else begin + avalue:= false; + end; +end; +} +function checkislastrecord(const adatalink: tmsedatalink; + const syncproc: synceventty): boolean; +var +// bm: string; + int1: integer; +begin + result:= false; + with adatalink do begin //todo: optimize + if active then begin + if dataset.eof then begin + result:= true; + end + else begin + if (dscontroller <> nil) and not assigned(syncproc) then begin + result:= dscontroller.islastrecord; + end + else begin + int1:= dataset.recno; + tdataset1(dataset).settempstate(dataset.state); //disable controls + try + dataset.next; + result:= dataset.eof; + if assigned(syncproc) and not result then begin + syncproc; + end; + dataset.recno:= int1; + finally + tdataset1(dataset).restorestate(dataset.state); + end; + end; + end; + end; + end; +end; + +function createreport(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; +begin + result:= reportclassty(aclass).create(nil,false); + tmsecomponent1(result).factualclassname:= aclassname; +end; + +function getreportscale(const amodule: tcomponent): real; +begin + result:= tcustomreport(amodule).fppmm/defaultppmm; +end; + +procedure initreportcomponent(const amodule: tcomponent; + const acomponent: tcomponent); +begin +// if acomponent is twidget then begin +// twidget(acomponent).scale(getreportscale(amodule)); +// end; +end; + +function createreppageform(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; +begin + result:= reppageformclassty(aclass).create(nil,false); + tmsecomponent1(result).factualclassname:= aclassname; +end; + +function getreppageformscale(const amodule: tcomponent): real; +begin + result:= tcustomreportpage(amodule).fppmm/defaultppmm; +end; + +{ treptabfont } + +class function treptabfont.getinstancepo(owner: tobject): pfont; +begin + result:= @treptabulatoritem(owner).ffont; +end; + +constructor treptabfont.create; +begin + inherited; + finfo.baseinfo.color:= defaultrepfontcolor; + finfo.baseinfo.name:= defaultrepfontname; +end; + +procedure treptabfont.setname(const avalue: string); +begin + if avalue = '' then begin + inherited setname(defaultrepfontname); + end + else begin + inherited; + end; +end; + +{ treptabitemdatalink } + +constructor treptabitemdatalink.create(const aowner: treptabulatoritem); +begin + fowner:= aowner; + inherited create; +end; + +procedure treptabitemdatalink.recordchanged(afield: tfield); +begin + if (afield = nil) or (afield = field) then begin + fowner.changed; + { + with treptabulators(fowner.fowner).fband do begin + invalidate; + end; + } + end; +end; + +{ treptabulatoritem } + +constructor treptabulatoritem.create(aowner: tobject); +var + kind1: tablinekindty; +begin + fcolor:= cl_none; + ftextflags:= defaultreptabtextflags; + fdatalink:= treptabitemdatalink.create(self); + for kind1:= low(tablinekindty) to high(tablinekindty) do begin + flineinfos[kind1]:= defaulttablineinfo; + end; + inherited; + with treptabulators(aowner),fband do begin + self.flineinfos[tlk_vert]:= flineinfos[tlk_vert]; + if not (csloading in componentstate) then begin + self.fdatalink.datasource:= datasource; + self.fdistleft:= distleft; + self.fdistright:= distright; + end; + end; +end; + +destructor treptabulatoritem.destroy; +begin + lookupbuffer:= nil; + ifilink:= nil; + inherited; + ffont.free; + fdatalink.free; +end; + +procedure treptabulatoritem.setvalue(const avalue: msestring); +begin + fvalue.text:= avalue; + fvalue.format:= nil; + changed; +end; + +procedure treptabulatoritem.setrichvalue(const avalue: richstringty); +begin + fvalue:= avalue; + changed; +end; + +function treptabulatoritem.getfont: treptabfont; +begin + getoptionalobject(treptabulators(fowner).fband.componentstate,ffont, + {$ifdef FPC}@{$endif}createfont); + if ffont <> nil then begin + result:= ffont; + end + else begin +{$warnings off} + result:= treptabfont(treptabulators(fowner).fband.getfont); +{$warnings on} + end; +end; + +procedure treptabulatoritem.createfont; +begin + if ffont = nil then begin + ffont:= treptabfont.create; + ffont.onchange:= {$ifdef FPC}@{$endif}fontchanged; + end; +end; + +procedure treptabulatoritem.setfont(const avalue: treptabfont); +begin + if avalue <> ffont then begin + setoptionalobject(treptabulators(fowner).fband.componentstate,avalue, + ffont,{$ifdef fpc}@{$endif}createfont); + changed; + end; +end; + +function treptabulatoritem.isfontstored: boolean; +begin + result:= ffont <> nil; +end; + +procedure treptabulatoritem.changed; +begin + with treptabulators(fowner),fband do begin + fsizevalid:= false; + if rendering or ([csdesigning,csdestroying] * componentstate = + [csdesigning]) then begin + minclientsizechanged; +// change(-1); + end; + end; +end; + +procedure treptabulatoritem.setpos(const avalue: real); +begin + inherited; + treptabulators(fowner).fband.sendchangeevent(oe_designchanged); + //syncronize linked tabs +end; + +procedure treptabulatoritem.fontchanged(const asender: tobject); +begin + changed; +end; + +procedure treptabulatoritem.settextflags(const avalue: textflagsty); +begin + if ftextflags <> avalue then begin + ftextflags:= checktextflags(ftextflags,avalue); + changed; + end; +end; + +function treptabulatoritem.getdatasource1: tdatasource; +begin + result:= fdatalink.datasource; +end; + +procedure treptabulatoritem.setdatasource(const avalue: tdatasource); +begin + fdatalink.datasource:= avalue; + changed; +end; + +function treptabulatoritem.getdatafield: string; +begin + result:= fdatalink.fieldname; +end; + +procedure treptabulatoritem.setdatafield(const avalue: string); +begin + fdatalink.fieldname:= avalue; +end; + +function treptabulatoritem.getdataset(const aindex: integer): tdataset; +begin + result:= fdatalink.dataset; +end; + +procedure treptabulatoritem.getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); +begin + apropertynames:= nil; + afieldtypes:= nil; +end; + +function treptabulatoritem.getdisptext: richstringty; + + procedure dofloat(const avalue: realty); + begin + case flookupkind of + lk_float: begin + result.text:= realtytostring(avalue,fformat); + end; + lk_time: begin + result.text:= mseformatstr.timetostring(avalue,fformat); + end; + lk_date: begin + result.text:= mseformatstr.datetostring(avalue,fformat); + end; + lk_datetime: begin + result.text:= mseformatstr.datetimetostring(avalue,fformat); + end; + end; + end; + +var + ikey: integer; + i64key: integer; + skey: msestring; + int1: integer; + int641: int64; + cl1: customificlientcontrollerclassty; + +begin + if fdatalink.fieldactive then begin + result.format:= nil; + if flookupbuffer <> nil then begin + try + result.text:= ''; + if fdatalink.islargeint then begin + i64key:= fdatalink.field.aslargeint; + case flookupkind of + lk_text: begin + result.text:= fformat + flookupbuffer.lookuptext(flookupkeyfieldno, + flookupvaluefieldno,i64key); + end; + lk_integer: begin + int1:= flookupbuffer.lookupinteger(flookupkeyfieldno, + flookupvaluefieldno,i64key); + result.text:= realtytostring(int1,fformat); + end; + lk_int64: begin + int641:= flookupbuffer.lookupint64(flookupkeyfieldno, + flookupvaluefieldno,i64key); + result.text:= realtytostring(int641,fformat); + end; + lk_float,lk_time,lk_date,lk_datetime: begin + dofloat(flookupbuffer.lookupfloat(flookupkeyfieldno, + flookupvaluefieldno,i64key)); + end; + end; + end + else begin + if fdatalink.ismsestring then begin + skey:= tmsestringfield(fdatalink.field).asmsestring; + case flookupkind of + lk_text: begin + result.text:= fformat + flookupbuffer.lookuptext(flookupkeyfieldno, + flookupvaluefieldno,skey); + end; + lk_integer: begin + int1:= flookupbuffer.lookupinteger(flookupkeyfieldno, + flookupvaluefieldno,skey); + result.text:= realtytostring(int1,fformat); + end; + lk_int64: begin + int641:= flookupbuffer.lookupint64(flookupkeyfieldno, + flookupvaluefieldno,skey); + result.text:= realtytostring(int641,fformat); + end; + lk_float,lk_time,lk_date,lk_datetime: begin + dofloat(flookupbuffer.lookupfloat(flookupkeyfieldno, + flookupvaluefieldno,skey)); + end; + end; + end + else begin + ikey:= fdatalink.field.asinteger; + case flookupkind of + lk_text: begin + result.text:= fformat + flookupbuffer.lookuptext(flookupkeyfieldno, + flookupvaluefieldno,ikey); + end; + lk_integer: begin + int1:= flookupbuffer.lookupinteger(flookupkeyfieldno, + flookupvaluefieldno,ikey); + result.text:= realtytostring(int1,fformat); + end; + lk_int64: begin + int641:= flookupbuffer.lookupint64(flookupkeyfieldno, + flookupvaluefieldno,ikey); + result.text:= realtytostring(int641,fformat); + end; + lk_float,lk_time,lk_date,lk_datetime: begin + dofloat(flookupbuffer.lookupfloat(flookupkeyfieldno, + flookupvaluefieldno,ikey)); + end; + end; + end; + end; + except + end; + end + else begin + if foptions * [rto_sum,rto_count,rto_average] <> [] then begin + with fdatalink.field do begin + if not (rto_shownull in foptions) and + ((rto_nocurrentvalue in foptions) or fsum.resetpending or + isnull and not (rto_count in foptions)) and + (fsum.count = 0) then begin + result.text:= ''; + end + else begin + if rto_count in foptions then begin + result.text:= realtytostring(sumcount,fformat); + end + else begin + if rto_average in foptions then begin + int1:= sumcount; + if int1 = 0 then begin + result.text:= realtytostring(0,fformat); + end + else begin + case datatype of + ftinteger,ftword,ftsmallint,ftboolean: begin + result.text:= realtytostring(sumasinteger/int1,fformat); + end; + ftlargeint: begin + result.text:= realtytostring(sumaslargeint/int1,fformat); + end; + ftfloat,ftcurrency: begin + result.text:= realtytostring(sumasfloat/int1,fformat); + end; + ftbcd: begin + result.text:= realtytostring(sumascurrency/int1,fformat); + end; + end; + end; + end + else begin + case datatype of + ftinteger,ftword,ftsmallint,ftboolean: begin + result.text:= realtytostring(sumasinteger,fformat); + end; + ftlargeint: begin + result.text:= realtytostring(sumaslargeint,fformat); + end; + ftfloat,ftcurrency: begin + result.text:= realtytostring(sumasfloat,fformat); + end; + ftbcd: begin + result.text:= realtytostring(sumascurrency,fformat); + end; + end; + end; + end; + end; + end; + end + else begin + result.text:= fdatalink.msedisplaytext(fformat); + end; + end; + end + else begin + if rto_count in foptions then begin + if not (rto_shownull in foptions) and + ((rto_nocurrentvalue in foptions) or fsum.resetpending) and + (fsum.count = 0) then begin + result.text:= ''; + end + else begin + result.text:= realtytostring(sumcount,fformat); + end + end + else begin + if fifilink <> nil then begin + cl1:= tifilink1(fifilink).getcontrollerclass(); + if cl1 = tstringclientcontroller then begin + result.text:= tstringclientcontroller(fifilink.c).value; + end + else begin + if cl1 = tintegerclientcontroller then begin + result.text:= realtytostring( + tintegerclientcontroller(fifilink.c).value,fformat); + end + else begin + if cl1 = tint64clientcontroller then begin + result.text:= realtytostring( + tint64clientcontroller(fifilink.c).value,fformat); + end + else begin + if cl1 = trealclientcontroller then begin + result.text:= realtytostring( + trealclientcontroller(fifilink.c).value,fformat); + end + else begin + if cl1 = tdatetimeclientcontroller then begin + result.text:= mseformatstr.datetimetostring( + tdatetimeclientcontroller(fifilink.c).value,fformat); + end; + end; + end; + end; + end; + end + else begin + result:= fvalue; + end; + end; + end; + if treptabulators(fowner).fband.canevent(tmethod(fongetvalue)) then begin + fongetvalue(self,result); + end; +end; + +procedure treptabulatoritem.setlitop_widthmm(const avalue: real); +begin + flineinfos[tlk_top].widthmm:= avalue; + changed; +end; + +procedure treptabulatoritem.setlitop_color(const avalue: colorty); +begin + flineinfos[tlk_top].color:= avalue; + changed; +end; + +procedure treptabulatoritem.setlitop_colorgap(const avalue: colorty); +begin + flineinfos[tlk_top].colorgap:= avalue; + changed; +end; + +procedure treptabulatoritem.setlitop_capstyle(const avalue: capstylety); +begin + flineinfos[tlk_top].capstyle:= avalue; + changed; +end; + +procedure treptabulatoritem.setlitop_dashes(const avalue: string); +begin + flineinfos[tlk_top].dashes:= checkdashes(avalue); + changed; +end; + +procedure treptabulatoritem.setlitop_dist(const avalue: integer); +begin + flineinfos[tlk_top].dist:= avalue; + changed; +end; + +procedure treptabulatoritem.setlitop_visible(const avalue: linevisiblesty); +begin + flineinfos[tlk_top].visible:= avalue; + changed; +end; + +procedure treptabulatoritem.setlivert_widthmm(const avalue: real); +begin + flineinfos[tlk_vert].widthmm:= avalue; + changed; +end; + +procedure treptabulatoritem.setlivert_color(const avalue: colorty); +begin + flineinfos[tlk_vert].color:= avalue; + changed; +end; + +procedure treptabulatoritem.setlivert_colorgap(const avalue: colorty); +begin + flineinfos[tlk_vert].colorgap:= avalue; + changed; +end; + +procedure treptabulatoritem.setlivert_capstyle(const avalue: capstylety); +begin + flineinfos[tlk_vert].capstyle:= avalue; + changed; +end; + +procedure treptabulatoritem.setlivert_dashes(const avalue: string); +begin + flineinfos[tlk_vert].dashes:= checkdashes(avalue); + changed; +end; + +procedure treptabulatoritem.setlivert_dist(const avalue: integer); +begin + flineinfos[tlk_vert].dist:= avalue; + changed; +end; + +procedure treptabulatoritem.setlivert_visible(const avalue: linevisiblesty); +begin + flineinfos[tlk_vert].visible:= avalue; + changed; +end; + +procedure treptabulatoritem.setlibottom_widthmm(const avalue: real); +begin + flineinfos[tlk_bottom].widthmm:= avalue; + changed; +end; + +procedure treptabulatoritem.setlibottom_color(const avalue: colorty); +begin + flineinfos[tlk_bottom].color:= avalue; + changed; +end; + +procedure treptabulatoritem.setlibottom_colorgap(const avalue: colorty); +begin + flineinfos[tlk_bottom].colorgap:= avalue; + changed; +end; + +procedure treptabulatoritem.setlibottom_capstyle(const avalue: capstylety); +begin + flineinfos[tlk_bottom].capstyle:= avalue; + changed; +end; + +procedure treptabulatoritem.setlibottom_dashes(const avalue: string); +begin + flineinfos[tlk_bottom].dashes:= checkdashes(avalue); + changed; +end; + +procedure treptabulatoritem.setlibottom_dist(const avalue: integer); +begin + flineinfos[tlk_bottom].dist:= avalue; + changed; +end; + +procedure treptabulatoritem.setlibottom_visible(const avalue: linevisiblesty); +begin + flineinfos[tlk_bottom].visible:= avalue; + changed; +end; + +function treptabulatoritem.xlineoffset: integer; +begin + with flineinfos[tlk_vert] do begin + if kind = tak_left then begin + result:= -dist; + end + else begin + result:= dist; + end; + end; +end; + +procedure treptabulatoritem.recchanged; +begin + fdatalink.recordchanged(nil); +end; + +procedure treptabulatoritem.setlookupbuffer(const avalue: tcustomlookupbuffer); +begin + treptabulators(fowner).fband.setlinkedvar(avalue,tmsecomponent(flookupbuffer)); + changed; +end; + +procedure treptabulatoritem.setifilink(const avalue: tifilinkcomp); +begin + treptabulators(fowner).fband.setlinkedvar(avalue,tmsecomponent(fifilink)); + changed(); +end; + +procedure treptabulatoritem.setlookupkeyfieldno(const avalue: integer); +begin + flookupkeyfieldno:= avalue; + changed; +end; + +procedure treptabulatoritem.setlookupvaluefieldno(const avalue: integer); +begin + flookupvaluefieldno:= avalue; + changed; +end; + +procedure treptabulatoritem.setlookupkind(const avalue: lookupkindty); +begin + flookupkind:= avalue; + changed; +end; + +procedure treptabulatoritem.setformat(const avalue: msestring); +begin + fformat:= avalue; + changed; +end; + +procedure treptabulatoritem.setcolor(avalue: colorty); +begin + if avalue = cl_invalid then begin + avalue:= cl_none; + end; + if fcolor <> avalue then begin + fcolor:= avalue; + treptabulators(fowner).fband.invalidate; + end +end; + +procedure treptabulatoritem.resetsum(const skipcurrent: boolean); +begin + fillchar(fsum,sizeof(fsum),0); + fsum.resetpending:= skipcurrent; + fsum.reset:= true; +end; + +procedure treptabulatoritem.setintvalue(const avalue: int32); +begin + value:= formatfloatmse(avalue,format); +end; + +procedure treptabulatoritem.setint64value(const avalue: int64); +begin + value:= formatfloatmse(avalue,format); +end; + +procedure treptabulatoritem.setfloatvalue(const avalue: flo64); +begin + value:= formatfloatmse(avalue,format); +end; + +procedure treptabulatoritem.setdatetimevalue(const avalue: tdatetime); +begin + value:= formatdatetimemse(avalue,format); +end; + +procedure treptabulatoritem.setcurrencyvalue(const avalue: currency); +begin + value:= formatfloatmse(avalue,format); +end; + +procedure treptabulatoritem.initsum; +begin + fillchar(fsum,sizeof(fsum),0); +end; + +procedure treptabulatoritem.dobeforenextrecord(const adatasource: tdatasource); +begin + if (foptions * [rto_count,rto_sum,rto_average] <> []) and + (fdatalink.datasource = adatasource) then begin + if fdatalink.active then begin + if fdatalink.field = nil then begin + inc(fsum.count); + end + else begin + with fdatalink.field,fsum do begin + if not isnull then begin + inc(count); + case datatype of + ftinteger,ftword,ftsmallint,ftboolean: begin + integervalue:= integervalue + asinteger; + end; + ftlargeint: begin + largeintvalue:= largeintvalue + aslargeint; + end; + ftfloat,ftcurrency: begin + floatvalue:= floatvalue + asfloat; + end; + ftbcd: begin + bcdvalue:= bcdvalue + ascurrency; + end; + end; + end; + end; + end; + end; + if fsum.resetpending then begin + initsum; + end; + end; +end; + +function treptabulatoritem.getsumasinteger: integer; +begin + if fsum.resetpending and fsum.reset or not fdatalink.fieldactive then begin + result:= 0; + end + else begin + result:= fsum.integervalue; + if not (rto_nocurrentvalue in foptions) then begin + result:= result + fdatalink.field.asinteger; + end; + end; +end; + +function treptabulatoritem.getsumaslargeint: int64; +begin + if fsum.resetpending and fsum.reset or not fdatalink.fieldactive then begin + result:= 0; + end + else begin + result:= fsum.largeintvalue; + if not (rto_nocurrentvalue in foptions) then begin + result:= result + fdatalink.field.aslargeint; + end; + end; +end; + +function treptabulatoritem.getsumasfloat: double; +begin + if fsum.resetpending and fsum.reset or not fdatalink.fieldactive then begin + result:= 0; + end + else begin + result:= fsum.floatvalue; + if not (rto_nocurrentvalue in foptions) then begin + result:= result + fdatalink.field.asfloat; + end; + end; +end; + +function treptabulatoritem.getsumascurrency: currency; +begin + if fsum.resetpending and fsum.reset or not fdatalink.fieldactive then begin + result:= 0; + end + else begin + result:= fsum.bcdvalue; + if not (rto_nocurrentvalue in foptions) then begin + result:= result + fdatalink.field.ascurrency; + end; + end; +end; + +function treptabulatoritem.getsumcount: integer; +begin + if fsum.resetpending and fsum.reset or not fdatalink.active then begin + result:= 0; + end + else begin + result:= fsum.count; + if not (rto_nocurrentvalue in foptions) then begin + result:= result + 1; + end; + end; +end; + +function treptabulatoritem.getenabled: boolean; +begin + result:= not (rto_disabled in foptions); +end; + +procedure treptabulatoritem.setenabled(const avalue: boolean); +begin + if avalue then begin + options:= options - [rto_disabled]; + end + else begin + options:= options + [rto_disabled]; + end; +end; + +procedure treptabulatoritem.setoptions(const avalue: reptabulatoritemoptionsty); +const + mask: reptabulatoritemoptionsty = [rto_count,rto_sum,rto_average]; +begin + if avalue <> foptions then begin + foptions:= reptabulatoritemoptionsty(setsinglebit( + {$ifdef FPC}longword{$else}byte{$endif}(avalue), + {$ifdef FPC}longword{$else}byte{$endif}(foptions), + {$ifdef FPC}longword{$else}byte{$endif}(mask))); + changed; + end; +end; + +procedure treptabulatoritem.scale(const ascale: real); +begin + if ffont <> nil then begin + ffont.scale(ascale); + end; +end; + +{ treptabulators } + +constructor treptabulators.create(const aowner: tcustomrecordband); +var + kind1: tablinekindty; +begin + fband:= aowner; + flileft:= defaulttablineinfo; + fliright:= defaulttablineinfo; + for kind1:= low(tablinekindty) to high(tablinekindty) do begin + flineinfos[kind1]:= defaulttablineinfo; + end; + inherited create; +end; + +class function treptabulators.getitemclass: tabulatoritemclassty; +begin + result:= treptabulatoritem; +end; + +function treptabulators.getitems(const index: integer): treptabulatoritem; +begin + result:= treptabulatoritem(inherited items[index]); +end; + +procedure treptabulators.setitems(const index: integer; + const avalue: treptabulatoritem); +begin + inherited items[index]:= avalue; +end; + +procedure treptabulators.processvalues(const acanvas: tcanvas; + const adest: rectty; const apaint: boolean); +var + saved: boolean; + bandcx: integer; + visiblemask: linevisiblesty; + + procedure checkinit(const ainfo: tablineinfoty); + var + rect1: rectty; + reppage1: tcustomreportpage; + begin + if not saved then begin + saved:= true; + acanvas.save; + acanvas.move(makepoint(adest.x,0)); + acanvas.addcliprect(inflaterect(makerect(nullpoint,fband.size),1000)); + //allow line drawing everywhere + if not fband.rendering then begin + reppage1:= fband.reppage; + if reppage1 <> nil then begin + rect1:= reppage1.clippedpaintrect; + translateclientpoint1(rect1.pos,reppage1,fband); + end + else begin + rect1:= fband.paintsizerect; + end; + rect1.x:= rect1.x - adest.x; + acanvas.intersectcliprect(rect1); //limit line drawing area + end; + end; + with ainfo do begin + acanvas.linewidthmm:= widthmm; + acanvas.capstyle:= capstyle; + if (dashes <> '') and (colorgap <> cl_transparent) then begin + acanvas.dashes:= copy(dashes+#0,1,high(dashesstringty)); + acanvas.colorbackground:= colorgap; + end + else begin + acanvas.dashes:= copy(dashes,1,high(dashesstringty)); + end; + end; + end; + + procedure drawhorzline(const aindex: integer; const akind: tablinekindty); + function nextx: integer; + begin + if aindex < high(ftabs) then begin + with ftabs[aindex+1] do begin + result:= linepos + treptabulatoritem(fitems[index]).xlineoffset; + end; + end + else begin + result:= bandcx; + end; + end; + + var + startx,endx,y: integer; + begin + with treptabulatoritem(fitems[ftabs[aindex].index]) do begin + with flineinfos[akind] do begin + if widthmm > 0 then begin + if visible * visiblemask <> [] then begin + checkinit(flineinfos[akind]); + with ftabs[aindex] do begin + case kind of + tak_left: begin + startx:=linepos + xlineoffset; + endx:= nextx; + end; + else begin + if aindex > 0 then begin + with ftabs[aindex-1] do begin + startx:= linepos + treptabulatoritem(fitems[index]).xlineoffset; + end; + end + else begin + startx:= 0; + end; + if kind = tak_centered then begin + endx:= nextx; + end + else begin + endx:= linepos + xlineoffset; + end; + end; + end; + end; + if akind = tlk_top then begin + y:= - flineinfos[tlk_top].dist; + end + else begin + y:= treptabulators(fowner).fband.clientheight + + flineinfos[tlk_bottom].dist; + end; + acanvas.drawline(makepoint(startx,y),makepoint(endx,y),color); + end; + end; + end; + end; + end; + +var + int1,int2,int3,int4: integer; + moved: boolean; + rstr1: richstringty; +// rect1: rectty; + isdecimal: boolean; + cellrect: rectty; + tab1: treptabulatoritem; +begin + fminsize:= nullsize; + bandcx:= adest.cx; + saved:= false; + moved:= false; + visiblemask:= []; + if apaint then begin + with fband do begin + cellrect:= adest; + if not rendering or (fparentintf = nil) then begin + visiblemask:= [lv_topofpage,lv_nottopofpage, + lv_firstofpage,lv_normal,lv_lastofpage, + lv_firstofgroup,lv_lastofgroup, + lv_firstrecord,lv_lastrecord]; + end + else begin + visiblemask:= [lv_normal]; + with fparentintf do begin + if istopband then begin + include(visiblemask,lv_topofpage); + exclude(visiblemask,lv_nottopofpage); + end + else begin + include(visiblemask,lv_nottopofpage); + exclude(visiblemask,lv_topofpage); + end; + if isfirstband then begin + include(visiblemask,lv_firstofpage); + exclude(visiblemask,lv_normal); + end; + if islastband then begin + include(visiblemask,lv_lastofpage); + exclude(visiblemask,lv_normal); + end; + if fband.isfirstofgroup then begin + include(visiblemask,lv_firstofgroup); + end; + if fband.islastofgroup then begin + include(visiblemask,lv_lastofgroup); + end; + end; + if isfirstrecord then begin + include(visiblemask,lv_firstrecord); + exclude(visiblemask,lv_normal); + end; + if islastrecord then begin + include(visiblemask,lv_lastrecord); + exclude(visiblemask,lv_normal); + end; + end; + end; + end; + if count > 0 then begin + checkuptodate; + with finfo do begin + for int1:= 0 to count - 1 do begin + tab1:= treptabulatoritem(fitems[ftabs[int1].index]); + if tab1.enabled then begin + with ftabs[int1],tab1 do begin + text:= getdisptext; + if apaint and (foptions*[rto_count,rto_sum,rto_average] <> []) and + not (rto_noreset in foptions) then begin + fsum.resetpending:= true; + end; + finfo.font:= font; + flags:= ftextflags; + dest:= adest; + if width <= 0 then begin + case kind of + tak_left: begin + dest.cx:= adest.cx - textpos + width; + end; + else begin + dest.cx:= adest.cx + width; + end; + end; + end + else begin + dest.cx:= width; + end; + dest.x:= adest.x + textpos; + if apaint and (fcolor <> cl_none) then begin + cellrect.x:= adest.x + linepos; + if int1 < high(ftabs) then begin + cellrect.cx:= cellwidth; + end + else begin + cellrect.cx:= adest.cx - linepos; + end; + acanvas.fillrect(cellrect,fcolor); + end; + isdecimal:= tabkind = tak_decimal; + case tabkind of + tak_centered: begin + flags:= (flags - [tf_right]) + [tf_xcentered]; + dec(dest.x,dest.cx div 2); + end; + tak_right,tak_decimal: begin + flags:= (flags - [tf_xcentered]) + [tf_right]; + dec(dest.x,dest.cx); + end; + end; + end; + if isdecimal then begin + int2:= findlastchar(text.text,defaultformatsettingsmse.decimalseparator); + if int2 > 0 then begin + rstr1:= text; + text:= richcopy(rstr1,1,int2-1); + if apaint then begin + drawtext(acanvas,finfo); + end + else begin + textrect(acanvas,finfo); + end; + int3:= res.x; + int4:= res.cx; + text:= richcopy(rstr1,int2,bigint); + inc(dest.x,dest.cx); + exclude(flags,tf_right); + if apaint then begin + drawtext(acanvas,finfo); + end + else begin + textrect(acanvas,finfo); + end; + res.x:= int3; + res.cx:= res.cx + int4; + text:= rstr1; + end + else begin + if apaint then begin + drawtext(acanvas,finfo); + end + else begin + textrect(acanvas,finfo); + end; + end; + end + else begin //not decimal + if apaint then begin + drawtext(acanvas,finfo); + end + else begin + textrect(acanvas,finfo); + end; + end; + int2:= res.x + res.cx; + if int2 > fminsize.cx then begin + fminsize.cx:= int2; + end; + if res.cy = 0 then begin + res.cy:= font.lineheight; + end; + int2:= dest.y + res.cy; + if int2 > fminsize.cy then begin + fminsize.cy:= int2; + end; + end; + end; + end; + if apaint then begin + for int1:= 0 to count - 1 do begin + with treptabulatoritem(fitems[ftabs[int1].index]) do begin + if enabled then begin + with flineinfos[tlk_vert] do begin + if widthmm > 0 then begin + if visible * visiblemask <> [] then begin + checkinit(flineinfos[tlk_vert]); + with ftabs[int1] do begin + case kind of + tak_left: begin + int2:= linepos - dist + end + else begin + int2:= linepos + dist; + end; + end; + end; + acanvas.drawline(makepoint(int2,fband.clientheight+libottom_dist), + makepoint(int2,-litop_dist),color); + end; + end; + end; + drawhorzline(int1,tlk_top); + drawhorzline(int1,tlk_bottom); + end; + end; + end; + end; + end; + if apaint then begin + moved:= not saved; + acanvas.remove(makepoint(adest.x,0)); + bandcx:= fband.clientwidth; + with flileft do begin + if widthmm > 0 then begin + if visible * visiblemask <> [] then begin + checkinit(flileft); + acanvas.drawline(makepoint(-dist, + fband.clientheight+flineinfos[tlk_bottom].dist), + makepoint(-dist,-flineinfos[tlk_top].dist),color); + end; + end; + end; + with fliright do begin + if widthmm > 0 then begin + if visible * visiblemask <> [] then begin + checkinit(fliright); + acanvas.drawline(makepoint(bandcx+dist,fband.clientheight+ + flineinfos[tlk_bottom].dist), + makepoint(bandcx+dist,-flineinfos[tlk_top].dist),color); + end; + end; + end; + with flineinfos[tlk_top] do begin + if widthmm > 0 then begin + if visible * visiblemask <> [] then begin + checkinit(flineinfos[tlk_top]); + acanvas.drawline(makepoint(-flileft.dist,-dist), + makepoint(bandcx+fliright.dist,-dist),color); + end; + end; + end; + with flineinfos[tlk_bottom] do begin + if widthmm > 0 then begin + if visible * visiblemask <> [] then begin + checkinit(flineinfos[tlk_bottom]); + int2:= fband.clientheight+dist; + acanvas.drawline(makepoint(-flileft.dist,int2), + makepoint(bandcx+fliright.dist,int2),color); + end; + end; + end; + end; + if saved then begin + acanvas.restore; + end; + if moved then begin + acanvas.move(makepoint(adest.x,0)); + end; + fsizevalid:= true; +end; + +procedure treptabulators.paint(const acanvas: tcanvas; const adest: rectty); +begin + processvalues(acanvas,adest,true); +end; + +procedure treptabulators.checksize; +begin + if not fsizevalid then begin + processvalues(fband.getcanvas,fband.textarea(),false); + end; +end; + +procedure treptabulators.setlitop_widthmm(const avalue: real); +begin + if avalue <> flineinfos[tlk_top].widthmm then begin + flineinfos[tlk_top].widthmm:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setlitop_color(const avalue: colorty); +begin + if avalue <> flineinfos[tlk_top].color then begin + flineinfos[tlk_top].color:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setlitop_colorgap(const avalue: colorty); +begin + if avalue <> flineinfos[tlk_top].colorgap then begin + flineinfos[tlk_top].colorgap:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setlitop_capstyle(const avalue: capstylety); +begin + if avalue <> flineinfos[tlk_top].capstyle then begin + flineinfos[tlk_top].capstyle:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setlitop_dashes(const avalue: string); +begin + if avalue <> flineinfos[tlk_top].dashes then begin + flineinfos[tlk_top].dashes:= checkdashes(avalue); + fband.invalidate; + end; +end; + +procedure treptabulators.setlitop_dist(const avalue: integer); +begin + if avalue <> flineinfos[tlk_top].dist then begin + flineinfos[tlk_top].dist:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setlitop_visible(const avalue: linevisiblesty); +begin + if avalue <> flineinfos[tlk_top].visible then begin + flineinfos[tlk_top].visible:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setlileft_widthmm(const avalue: real); +begin + if avalue <> flileft.widthmm then begin + flileft.widthmm:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setlileft_color(const avalue: colorty); +begin + if avalue <> flileft.color then begin + flileft.color:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setlileft_colorgap(const avalue: colorty); +begin + if avalue <> flileft.colorgap then begin + flileft.colorgap:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setlileft_capstyle(const avalue: capstylety); +begin + if avalue <> flileft.capstyle then begin + flileft.capstyle:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setlileft_dashes(const avalue: string); +begin + if avalue <> flileft.dashes then begin + flileft.dashes:= checkdashes(avalue); + fband.invalidate; + end; +end; + +procedure treptabulators.setlileft_dist(const avalue: integer); +begin + if avalue <> flileft.dist then begin + flileft.dist:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setlileft_visible(const avalue: linevisiblesty); +begin + if avalue <> flileft.visible then begin + flileft.visible:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setlivert_widthmm(const avalue: real); +var + int1: integer; +begin +// if (avalue <> flineinfos[tlk_vert].widthmm) then begin + flineinfos[tlk_vert].widthmm:= avalue; + if not (csloading in fband.componentstate) then begin + for int1:= 0 to high(fitems) do begin + treptabulatoritem(fitems[int1]).livert_widthmm:= avalue; + end; + end; +// end; +end; + +procedure treptabulators.setlivert_color(const avalue: colorty); +var + int1: integer; +begin +// if (avalue <> flineinfos[tlk_vert].color) then begin + flineinfos[tlk_vert].color:= avalue; + if not (csloading in fband.componentstate) then begin + for int1:= 0 to high(fitems) do begin + treptabulatoritem(fitems[int1]).livert_color:= avalue; + end; + end; +// end; +end; + +procedure treptabulators.setlivert_colorgap(const avalue: colorty); +var + int1: integer; +begin +// if (avalue <> flineinfos[tlk_vert].colorgap) then begin + flineinfos[tlk_vert].colorgap:= avalue; + if not (csloading in fband.componentstate) then begin + for int1:= 0 to high(fitems) do begin + treptabulatoritem(fitems[int1]).livert_colorgap:= avalue; + end; + end; +// end; +end; + +procedure treptabulators.setlivert_capstyle(const avalue: capstylety); +var + int1: integer; +begin +// if (avalue <> flineinfos[tlk_vert].capstyle) then begin + flineinfos[tlk_vert].capstyle:= avalue; + if not (csloading in fband.componentstate) then begin + for int1:= 0 to high(fitems) do begin + treptabulatoritem(fitems[int1]).livert_capstyle:= avalue; + end; + end; +// end; +end; + +procedure treptabulators.setlivert_dashes(const avalue: string); +var + int1: integer; +begin +// if (avalue <> flineinfos[tlk_vert].dashes) then begin + flineinfos[tlk_vert].dashes:= checkdashes(avalue); + if not (csloading in fband.componentstate) then begin + for int1:= 0 to high(fitems) do begin + treptabulatoritem(fitems[int1]).livert_dashes:= checkdashes(avalue); + end; + end; +// end; +end; + +procedure treptabulators.setlivert_dist(const avalue: integer); +var + int1: integer; +begin +// if (avalue <> flineinfos[tlk_vert].dist) then begin + flineinfos[tlk_vert].dist:= avalue; + if not (csloading in fband.componentstate) then begin + for int1:= 0 to high(fitems) do begin + treptabulatoritem(fitems[int1]).livert_dist:= avalue; + end; + end; +// end; +end; + +procedure treptabulators.setlivert_visible(const avalue: linevisiblesty); +var + int1: integer; +begin +// if (avalue <> flineinfos[tlk_vert].visible) and +// not (csloading in fband.componentstate) then begin + flineinfos[tlk_vert].visible:= avalue; + if not (csloading in fband.componentstate) then begin + for int1:= 0 to high(fitems) do begin + treptabulatoritem(fitems[int1]).livert_visible:= avalue; + end; + end; +// end; +end; + +procedure treptabulators.setdistleft(const avalue: real); +var + int1: integer; +begin +// if avalue <> fdistleft then begin + fdistleft:= avalue; + if not (csloading in fband.componentstate) then begin + for int1:= 0 to high(fitems) do begin + treptabulatoritem(fitems[int1]).distleft:= fdistleft; + end; + end; +// end; +end; + +procedure treptabulators.setdistright(const avalue: real); +var + int1: integer; +begin +// if avalue <> fdistright then begin + fdistright:= avalue; + if not (csloading in fband.componentstate) then begin + for int1:= 0 to high(fitems) do begin + treptabulatoritem(fitems[int1]).distright:= fdistright; + end; + end; +// end; +end; + +procedure treptabulators.setliright_widthmm(const avalue: real); +begin + if avalue <> fliright.widthmm then begin + fliright.widthmm:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setliright_color(const avalue: colorty); +begin + if avalue <> fliright.color then begin + fliright.color:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setliright_colorgap(const avalue: colorty); +begin + if avalue <> fliright.colorgap then begin + fliright.colorgap:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setliright_capstyle(const avalue: capstylety); +begin + if avalue <> fliright.capstyle then begin + fliright.capstyle:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setliright_dashes(const avalue: string); +begin + if avalue <> fliright.dashes then begin + fliright.dashes:= checkdashes(avalue); + fband.invalidate; + end; +end; + +procedure treptabulators.setliright_dist(const avalue: integer); +begin + if avalue <> fliright.dist then begin + fliright.dist:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setliright_visible(const avalue: linevisiblesty); +begin + if avalue <> fliright.visible then begin + fliright.visible:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setlibottom_widthmm(const avalue: real); +begin + if avalue <> flineinfos[tlk_bottom].widthmm then begin + flineinfos[tlk_bottom].widthmm:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setlibottom_color(const avalue: colorty); +begin + if avalue <> flineinfos[tlk_bottom].color then begin + flineinfos[tlk_bottom].color:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setlibottom_colorgap(const avalue: colorty); +begin + if avalue <> flineinfos[tlk_bottom].colorgap then begin + flineinfos[tlk_bottom].colorgap:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setlibottom_capstyle(const avalue: capstylety); +begin + if avalue <> flineinfos[tlk_bottom].capstyle then begin + flineinfos[tlk_bottom].capstyle:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setlibottom_dashes(const avalue: string); +begin + if avalue <> flineinfos[tlk_bottom].dashes then begin + flineinfos[tlk_bottom].dashes:= checkdashes(avalue); + fband.invalidate; + end; +end; + +procedure treptabulators.setlibottom_dist(const avalue: integer); +begin + if avalue <> flineinfos[tlk_bottom].dist then begin + flineinfos[tlk_bottom].dist:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.setlibottom_visible(const avalue: linevisiblesty); +begin + if avalue <> flineinfos[tlk_bottom].visible then begin + flineinfos[tlk_bottom].visible:= avalue; + fband.invalidate; + end; +end; + +procedure treptabulators.recchanged; +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + treptabulatoritem(fitems[int1]).recchanged; + end; +end; + +procedure treptabulators.setlinksource(const avalue: tcustomrecordband); +var + band1: tcustomrecordband; +begin + if avalue <> flinksource then begin + band1:= avalue; + while band1 <> nil do begin + if band1 = fband then begin + raise exception.create('Recursive linksource.'); + end; + band1:= band1.ftabs.flinksource; + end; + fband.setlinkedvar(avalue,tmsecomponent(flinksource)); + sourcechanged; + end; +end; + +procedure treptabulators.sourcechanged; +var + int1: integer; +begin + if (flinksource <> nil) and + not (csloading in flinksource.componentstate) then begin + beginupdate; + try + count:= flinksource.ftabs.count; + for int1:= 0 to high(fitems) do begin + with treptabulatoritem(fitems[int1]) do begin + pos:= treptabulatoritem(flinksource.ftabs.fitems[int1]).pos; + end; + end; + finally + endupdate; + end; + end; +end; + +procedure treptabulators.dochange(const aindex: integer); +begin + fsizevalid:= false; + inherited; +// fband.sendchangeevent(oe_designchanged); +end; + +procedure treptabulators.setcount1(acount: integer; doinit: boolean); +const + step = 10; +var + countbefore: integer; + int1,int2: integer; +begin + with fband do begin + if (componentstate * [csdesigning,csloading] = [csdesigning]) and + (acount > count) then begin + countbefore:= count; + checkuptodate; + if countbefore > 0 then begin + int2:= self.pos[countbefore-1] + step; + end + else begin + int2:= 0; + end; + inherited; + for int1:= countbefore to count - 1 do begin + items[int1].pos:= int2 / ppmm; + inc(int2,step); //offset + end; + end + else begin + inherited; + end; + end; +end; + +procedure treptabulators.resetsums(const skipcurrent: boolean); +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + treptabulatoritem(fitems[int1]).resetsum(skipcurrent); + end; +end; + +procedure treptabulators.dobeforenextrecord(const adatasource: tdatasource); +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + treptabulatoritem(fitems[int1]).dobeforenextrecord(adatasource); + end; +end; + +procedure treptabulators.initsums; +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + treptabulatoritem(fitems[int1]).initsum; + end; +end; + +procedure treptabulators.scale(const ascale: real); +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + treptabulatoritem(fitems[int1]).scale(ascale); + end; +end; + +procedure setbandoptionsshow(const avalue: bandoptionshowsty; + var foptions: bandoptionshowsty); +const + topmask: bandoptionshowsty = [bos_showtopofpage,bos_hidetopofpage]; + nottopmask: bandoptionshowsty = [bos_shownottopofpage,bos_hidenottopofpage]; + firstmask: bandoptionshowsty = [bos_showfirstpage,bos_hidefirstpage]; + normalmask: bandoptionshowsty = [bos_shownormalpage,bos_hidenormalpage]; + evenmask: bandoptionshowsty = [bos_showevenpage,bos_hideevenpage]; + oddmask: bandoptionshowsty = [bos_showoddpage,bos_hideoddpage]; + firstofpagemask: bandoptionshowsty = [bos_showfirstofpage,bos_hidefirstofpage]; + normalofpagemask: bandoptionshowsty = [bos_shownormalofpage,bos_hidenormalofpage]; + lastofpagemask: bandoptionshowsty = [bos_showlastofpage,bos_hidelastofpage]; + firstrecmask: bandoptionshowsty = [bos_showfirstrecord,bos_hidefirstrecord]; + normalrecmask: bandoptionshowsty = [bos_shownormalrecord,bos_hidenormalrecord]; + lastrecmask: bandoptionshowsty = [bos_showlastrecord,bos_hidelastrecord]; +var + vis1: bandoptionshowsty; +begin + vis1:= bandoptionshowsty(setsinglebit(longword(avalue),longword(foptions), + longword(topmask))); + vis1:= bandoptionshowsty(setsinglebit(longword(avalue),longword(foptions), + longword(nottopmask))); + vis1:= bandoptionshowsty(setsinglebit(longword(avalue),longword(foptions), + longword(firstmask))); + vis1:= bandoptionshowsty(setsinglebit(longword(vis1),longword(foptions), + longword(normalmask))); + vis1:= bandoptionshowsty(setsinglebit(longword(vis1),longword(foptions), + longword(evenmask))); + vis1:= bandoptionshowsty(setsinglebit(longword(vis1),longword(foptions), + longword(oddmask))); + vis1:= bandoptionshowsty(setsinglebit(longword(vis1),longword(foptions), + longword(firstofpagemask))); + vis1:= bandoptionshowsty(setsinglebit(longword(vis1),longword(foptions), + longword(normalofpagemask))); + vis1:= bandoptionshowsty(setsinglebit(longword(vis1), + longword(foptions),longword(lastofpagemask))); + vis1:= bandoptionshowsty(setsinglebit(longword(vis1),longword(foptions), + longword(firstrecmask))); + vis1:= bandoptionshowsty(setsinglebit(longword(vis1),longword(foptions), + longword(normalrecmask))); + foptions:= bandoptionshowsty(setsinglebit(longword(vis1),longword(foptions), + longword(lastrecmask))); +end; + +function checkvisibility(const fparentintf: ibandparent; + const foptions: bandoptionshowsty; checklast: boolean; + var aresult: boolean; out show: boolean): boolean; + //true if more checks possible +label + endlab; +var + topofpage,firstofpage,lastofpage: boolean; + even1,first1: boolean; +begin + result:= false; + show:= false; + if foptions * visibilitymask <> [] then begin + if fparentintf <> nil then begin + first1:= fparentintf.pagepagenum = 0; + if first1 and (bos_hidefirstpage in foptions) then begin + aresult:= false; + goto endlab; + end; + if first1 and (bos_showfirstpage in foptions) then begin + aresult:= true; + goto endlab; + end; + if not first1 and (bos_hidenormalpage in foptions) then begin + aresult:= false; + goto endlab; + end; + if not first1 and (bos_shownormalpage in foptions) then begin + aresult:= true; + goto endlab; + end; + + even1:= not odd(fparentintf.reppagenum); + if even1 and (bos_hideevenpage in foptions) then begin + aresult:= false; + goto endlab; + end; + if not even1 and (bos_hideoddpage in foptions) then begin + aresult:= false; + goto endlab; + end; + show:= even1 and (bos_showevenpage in foptions); + show:= show or not even1 and (bos_showoddpage in foptions); + + topofpage:= fparentintf.istopband; + firstofpage:= fparentintf.isfirstband; + lastofpage:= checklast and fparentintf.islastband; + if topofpage then begin + if bos_showtopofpage in foptions then begin + aresult:= true; + goto endlab; + end + else begin + if bos_hidetopofpage in foptions then begin + aresult:= false; + end; + end; + end + else begin + if bos_shownottopofpage in foptions then begin + aresult:= true; + goto endlab; + end + else begin + if bos_hidenottopofpage in foptions then begin + aresult:= false; + end; + end; + end; + if firstofpage then begin + if bos_showfirstofpage in foptions then begin + aresult:= true; + goto endlab; + end + else begin + if bos_hidefirstofpage in foptions then begin + aresult:= false; + end; + end; + end; + if lastofpage then begin + if bos_showlastofpage in foptions then begin + aresult:= true; + goto endlab; + end + else begin + if bos_hidelastofpage in foptions then begin + aresult:= false; + show:= false; + end; + end; + end; + if not firstofpage and not lastofpage then begin + if bos_shownormalofpage in foptions then begin + aresult:= true; + goto endlab; + end + else begin + if bos_hidenormalofpage in foptions then begin + aresult:= false; + show:= false; + end; + end; + end; + end; + end; + result:= true; +endlab: +end; + +procedure updateparentintf(const sender: ireportclient; + var fparentintf: ibandparent); +var + widget1: twidget; +begin + with twidget1(sender.getwidget) do begin + if fparentwidget <> nil then begin + if fparentintf <> nil then begin + fparentintf.unregisterclient(sender); + end; + widget1:= fparentwidget; + while (widget1 <> nil) and + not widget1.getcorbainterface(typeinfo(ibandparent),fparentintf) do begin + widget1:= widget1.parentwidget; + end; + if fparentintf <> nil then begin + fparentintf.registerclient(sender); + sender.setppmm(fparentintf.getppmm); + end; + end + else begin + if fparentintf <> nil then begin + fparentintf.unregisterclient(sender); + end; + fparentintf:= nil; + end; + end; +end; + +{ trepspacer } + +procedure trepspacer.updatevisibility; +var + bo1,bo2: boolean; +begin + bo1:= visible; + checkvisibility(fparentintf,foptionsrep,true,bo1,bo2); + visible:= bo1 or bo2; +end; + +procedure trepspacer.setoptionsrep(const avalue: bandoptionshowsty); +const + spacerbandoptions = [ + bos_showtopofpage,bos_hidetopofpage, + bos_shownottopofpage,bos_hidenottopofpage, + bos_showfirstpage,bos_hidefirstpage, + bos_shownormalpage,bos_hidenormalpage, + bos_showevenpage,bos_hideevenpage, + bos_showoddpage,bos_hideoddpage, + bos_showfirstofpage,bos_hidefirstofpage, + bos_shownormalofpage,bos_hidenormalofpage, + bos_showlastofpage,bos_hidelastofpage + // bo_showfirstrecord,bo_hidefirstrecord, + // bo_shownormalrecord,bo_hidenormalrecord, + // bo_showlastrecord,bo_hidelastrecord, + //todo: check first-last record + // bo_localvalue + ]; + + +begin + setbandoptionsshow(avalue * spacerbandoptions,foptionsrep); +end; + +procedure trepspacer.parentchanged; +begin + updateparentintf(ireportclient(self),fparentintf); + inherited; +end; + +procedure trepspacer.beginrender(const arestart: boolean); +begin + include(fwidgetstate1,ws1_noclipchildren); +end; + +procedure trepspacer.endrender; +begin + exclude(fwidgetstate1,ws1_noclipchildren); +end; + +procedure trepspacer.adddatasets(var adatasets: datasetarty); +begin + //dummy +end; + +procedure trepspacer.init; +begin + //dummy +end; + +procedure trepspacer.resetzebra; +begin + //dummy +end; + +procedure trepspacer.setppmm(const avalue: real); +begin + //dummy +end; + +{ tcustomrecordband } + +constructor tcustomrecordband.create(aowner: tcomponent); +begin + ftextframe:= 1; + ftabs:= treptabulators.create(self); + fdatalink:= trecordbanddatalink.create; + fvisidatalink:= tfielddatalink.create; + fvisigrouplink:= tfielddatalink.create; + fzebra_step:= 2; + fzebra_color:= cl_infobackground; + inherited; + include(fwidgetstate1,ws1_designactive); + fanchors:= defaultbandanchors; + foptionswidget:= defaultbandoptionswidget; +end; + +destructor tcustomrecordband.destroy; +begin + fobjectpicker.free; + ftabs.free; + fdatalink.free; + fvisidatalink.free; + fvisigrouplink.free; + inherited; +end; + +procedure tcustomrecordband.loaded; +begin + inherited; + if (csdesigning in componentstate) and (fobjectpicker = nil) then begin + fobjectpicker:= tobjectpicker.create(iobjectpicker(self)); + end; +end; + +procedure tcustomrecordband.parentchanged; +begin + updateparentintf(ireportclient(self),fparentintf); + inherited; +end; + +procedure tcustomrecordband.dobeforerender(var empty: boolean); +begin + if not (not(rbs_showed in fstate) and (bo_once in foptions)) and + not(bo_once in foptions) and fdatalink.active then begin + empty:= (rbs_finish in fstate) or fdatalink.dataset.eof; + end; + if canevent(tmethod(fonbeforerender)) then begin + application.lock; + try + fonbeforerender(self,empty); + finally + application.unlock; + end; + end; + if not empty and visible and (bo_topofarea in foptions) and + (fparentintf <> nil) and not fparentintf.istopband + {fparentintf.isfirstband} then begin + fparentintf.setareafull(true); + end; +end; + +procedure tcustomrecordband.doonpaint(const acanvas: tcanvas); +begin + if canevent(tmethod(fonpaint)) then begin + application.lock; + try + fonpaint(self,acanvas); + finally + application.unlock; + end; + end; +end; + +function tcustomrecordband.actualcolor: colorty; +var + bo1: boolean; + int1: integer; +begin + bo1:= false; + if (rbs_rendering in fstate) and (fzebra_height > 0) and (fzebra_step > 0) then begin + int1:= (fzebra_counter - fzebra_start) mod fzebra_step; + if int1 < 0 then begin + if int1 < fzebra_height - fzebra_step then begin + bo1:= true; + end; + end + else begin + if int1 < fzebra_height then begin + bo1:= true; + end; + end; + end; + if bo1 then begin + result:= fzebra_color; + end + else begin + result:= inherited actualcolor; + end; +end; + +procedure tcustomrecordband.render(const acanvas: tcanvas; var empty: boolean); +var + widget1: twidget; + int1: integer; +begin + exclude(fstate,rbs_prepass); + widget1:= rootwidget; + if (widget1 is tcustomreport) then begin + with tcustomreport(widget1) do begin + if canceled then begin + abort; + end; + if prepass then begin + include(self.fstate,rbs_prepass); + end; + end; + end; + application.checkoverload; + if rbs_nextrecordpending in fstate then begin + nextrecord; + end; + fparentintf.updatevisible; //?? + include(fstate,rbs_visibilitychecked); + empty:= empty or (rbs_finish in fstate); + dobeforerender(empty); + if not empty then begin + if not (rbs_visibilitychecked in fstate) then begin + fparentintf.updatevisible; + end; + if visible then begin + if fparentintf.beginband(acanvas,self) then begin + exit; //area full + end; + try + for int1:= 0 to high(fareas) do begin + fareas[int1].initband; + end; + inheritedpaint(acanvas); + finally + fparentintf.endband(acanvas,self); + end; + if canevent(tmethod(fonafterrender)) then begin + application.lock; + try + fonafterrender(self); + finally + application.unlock; + end; + end; + end; + if bo_delayednextrecord in foptions then begin + include(fstate,rbs_nextrecordpending); + end + else begin + nextrecord; + end; + end; +end; + +procedure tcustomrecordband.init; +var + int1: integer; +begin + exclude(fstate,rbs_finish); + if fvisigrouplink.fieldactive then begin + if fvisigrouplink.isstringfield then begin + fgroupstring:= fvisigrouplink.asmsestring; + end + else begin + fgroupnum:= fvisigrouplink.aslargeint; + end; +// fnextgroupnum:= fgroupnum; set by beginrender + end; + for int1:= 0 to high(fareas) do begin + fareas[int1].init; + end; +end; + +procedure tcustomrecordband.initpage; +var + int1: integer; +begin + if (zo_resetonpagestart in fzebra_options) then begin + fzebra_counter:= 0; + end; + exclude(fstate,rbs_pageshowed); + for int1:= 0 to high(fareas) do begin + fareas[int1].initpage; + end; +end; + +function tcustomrecordband.rendering: boolean; +begin + result:= rbs_rendering in fstate; +end; + +function tcustomrecordband.bandheight: integer; +begin + result:= bounds_cy; +end; + +procedure tcustomrecordband.inheritedpaint(const acanvas: tcanvas); +begin + inherited paint(acanvas); + inc(fzebra_counter); + if (zo_resetparent in fzebra_options) and (fparentintf <> nil) then begin + fparentintf.resetzebra; + end; +end; + +procedure tcustomrecordband.paint(const canvas: tcanvas); +begin + if not rendering then begin + inherited; + end; +end; + +procedure tcustomrecordband.beginrender(const arestart: boolean); +var + int1: integer; +begin + ftabs.initsums; + fzebra_counter:= 0; + if arestart then begin + fstate:= (fstate * [rbs_pageshowed]) + [rbs_rendering] + end + else begin + fstate:= [rbs_rendering]; + end; + include(fwidgetstate1,ws1_noclipchildren); + if fdatalink.active then begin + application.lock; + try + if not (bo_once in foptions) then begin + fdatalink.dataset.first(); + if checkislastrecord(fdatalink,@dosyncnextrecord) then begin + include(fstate,rbs_lastrecord); + end; + end + else begin + include(fstate,rbs_lastrecord); + end; + recchanged; + finally + application.unlock; + end; + end; + for int1:= 0 to high(fareas) do begin + fareas[int1].beginrender(arestart); + end; +end; + +procedure tcustomrecordband.restart; +begin + beginrender(true); +end; + +procedure tcustomrecordband.resetzebra; +var + int1: integer; +begin + fzebra_counter:= 0; + for int1:= 0 to high(fareas) do begin + fareas[int1].resetzebra; + end; +end; + +procedure tcustomrecordband.endrender; +var + int1: integer; +begin + for int1:= 0 to high(fareas) do begin + fareas[int1].endrender; + end; + exclude(fstate,rbs_rendering); + exclude(fwidgetstate1,ws1_noclipchildren); +end; + +procedure tcustomrecordband.adddatasets(var adatasets: datasetarty); +var + int1: integer; +begin + for int1:= 0 to high(fareas) do begin + fareas[int1].adddatasets(adatasets); + end; + if fdatalink.dataset <> nil then begin + adduniqueitem(pointerarty(adatasets),fdatalink.dataset); + end; +end; + +procedure tcustomrecordband.settextframe(const avalue: int32); +begin + if ftextframe <> avalue then begin + ftextframe:= avalue; + if fframe = nil then begin +// minclientsizechanged(); + clientrectchanged(); + end; + end; +end; + +procedure tcustomrecordband.settabs(const avalue: treptabulators); +begin + ftabs.assign(avalue); +end; + +procedure tcustomrecordband.dobeforenextrecord(const adatasource: tdatasource); +begin + ftabs.dobeforenextrecord(adatasource); + if fvisigrouplink.fieldactive then begin + if fvisigrouplink.isstringfield then begin + fgroupstring:= fvisigrouplink.asmsestring; + end + else begin + fgroupnum:= fvisigrouplink.field.aslargeint; + end; + end; +end; + +procedure tcustomrecordband.dosyncnextrecord; +begin + if fvisigrouplink.fieldactive then begin + if fvisigrouplink.isstringfield then begin + fnextgroupstring:= fvisigrouplink.asmsestring; + end + else begin + fnextgroupnum:= fvisigrouplink.field.aslargeint; + end; + end; +end; + +procedure tcustomrecordband.nextrecord(const setflag: boolean = true); +begin + application.lock; + try + exclude(fstate,rbs_nextrecordpending); + if canevent(tmethod(fonbeforenextrecord)) then begin + fonbeforenextrecord(self); + end; + if setflag then begin + include(fstate,rbs_notfirstrecord); + dobeforenextrecord(fdatalink.datasource); + end; + if fdatalink.active and not (bo_once in foptions) then begin + fdatalink.dataset.next; + if setflag then begin + if checkislastrecord(fdatalink, + {$ifdef FPC}@{$endif}dosyncnextrecord) then begin + include(fstate,rbs_lastrecord); + end; + fparentintf.getreppage.recordchanged; + end; + end; + if canevent(tmethod(fonafternextrecord)) then begin + fonafternextrecord(self); + end; + finally + application.unlock; + end; +end; + +procedure tcustomrecordband.doafterpaint(const acanvas: tcanvas); +var +// ar1: segmentarty; + ar2: tabulatorarty; + int1,int2: integer; + a,b: pointty; + col1: colorty; +begin + inherited; + if (rbs_rendering in fstate) then begin + if canevent(tmethod(fonafterpaint)) then begin + application.lock; + try + fonafterpaint(self,acanvas); + finally + application.unlock; + end; + end; + end; + if csdesigning in componentstate then begin + ar2:= ftabs.tabs; +// setlength(ar1,length(ar2)); + int2:= innerclientwidgetpos.x; + if fframe = nil then begin + int2:= int2 + ftextframe; + end; + for int1:= 0 to high(ar2) do begin +// with ar1[int1] do begin + with ar2[int1] do begin + with treptabulatoritem(ftabs.fitems[index]) do begin + if enabled then begin + col1:= cl_red; + end + else begin + col1:= cl_blue; + end; + if tas_editactive in fstate then begin + acanvas.dashes:= ''; + end + else begin + acanvas.dashes:= #2#2; + end + end; + a.x:= linepos+int2; + end; + a.y:= 0; + b.x:= a.x; + b.y:= fwidgetrect.cy; + acanvas.drawline(a,b,col1); +// end; + end; +// acanvas.drawlinesegments(ar1,cl_red); + acanvas.dashes:= ''; + end; +end; + +procedure tcustomrecordband.dopaintforeground(const acanvas: tcanvas); +begin +{ + if canevent(tmethod(fonbeforepaint)) then begin + fonbeforepaint(self,acanvas); + end; +} + inherited; + ftabs.paint(acanvas,textarea()); +end; + +function tcustomrecordband.getminbandsize: sizety; +begin + ftabs.checksize; + result:= ftabs.fminsize; +end; + +function tcustomrecordband.calcminscrollsize: sizety; +var + size1: sizety; +begin + result:= inherited calcminscrollsize; + size1:= getminbandsize; + if fframe <> nil then begin + with tcustomframe1(fframe) do begin + size1.cx:= size1.cx + fi.innerframe.right; + size1.cy:= size1.cy + fi.innerframe.bottom; + end; + end + else begin + size1.cx:= size1.cx + ftextframe; + size1.cy:= size1.cy + ftextframe; + end; + with size1 do begin + if cx > result.cx then begin + result.cx:= cx; + end; + if cy > result.cy then begin + result.cy:= cy + end; + end; +end; + +function tcustomrecordband.textarea(): rectty; +begin + result:= innerclientrect; + if fframe = nil then begin + inflaterect1(result,-ftextframe); + end; +end; + +procedure tcustomrecordband.minclientsizechanged; +begin + if (fupdating <= 0) and not (csloading in componentstate) then begin + clientrectchanged; + end; +end; + +procedure tcustomrecordband.fontchanged; +begin + ftabs.fsizevalid:= false; + inherited; + minclientsizechanged; +end; + +procedure tcustomrecordband.clientrectchanged(); +begin + ftabs.fsizevalid:= false; + inherited; +end; + +procedure tcustomrecordband.beginupdate; +begin + inc(fupdating); +end; + +procedure tcustomrecordband.endupdate; +begin + dec(fupdating); + if fupdating = 0 then begin + clientrectchanged; + end; +end; + +procedure tcustomrecordband.setdatasource(const avalue: tdatasource); +var + int1: integer; +begin + fdatalink.datasource:= avalue; + if (componentstate*[csdesigning,csloading] = [csdesigning]) and + (avalue <> nil) then begin + for int1:= 0 to ftabs.count - 1 do begin + ftabs[int1].datasource:= avalue; + end; + end; +end; + +function tcustomrecordband.getdatasource: tdatasource; +begin + result:= fdatalink.datasource; +end; + +procedure tcustomrecordband.setoptionsshow(const avalue: bandoptionshowsty); +begin + setbandoptionsshow(avalue,foptionsshow); +end; + +procedure tcustomrecordband.synctofontheight; +var + i1: int32; +begin +// inherited; + i1:= calcminscrollsize().cy; + if ftabs.count = 0 then begin + i1:= i1 + font.glyphheight; + if fframe <> nil then begin + with tcustomframe1(fframe) do begin + i1:= i1 + fi.innerframe.top; + end; + end + else begin + i1:= i1 + ftextframe; + end; + end; + if fframe <> nil then begin + i1:= i1 + fframe.paintframedim.cy + end; + height:= i1; +// syncsinglelinefontheight(true); +end; + +function tcustomrecordband.isfirstrecord: boolean; +begin + if fdatalink.active then begin + result:= not (rbs_notfirstrecord in fstate); + end + else begin + if fparentintf <> nil then begin + result:= fparentintf.isfirstrecord; + end + else begin + result:= false; + end; + end; +end; + +function tcustomrecordband.islastrecord: boolean; +begin + if fdatalink.active then begin + result:= rbs_lastrecord in fstate; + end + else begin + if fparentintf <> nil then begin + result:= fparentintf.islastrecord; + end + else begin + result:= false; + end; + end; +end; + +function tcustomrecordband.isfirstofgroup: boolean; +begin + if fvisigrouplink.isstringfield then begin + result:= fvisigrouplink.fieldactive and (isfirstrecord or + (fvisigrouplink.asmsestring <> fgroupstring)); + end + else begin + result:= fvisigrouplink.fieldactive and (isfirstrecord or + (fvisigrouplink.field.aslargeint <> fgroupnum)); + end; +end; + +function tcustomrecordband.islastofgroup: boolean; +begin + if fvisigrouplink.isstringfield then begin + result:= fvisigrouplink.fieldactive and (islastrecord or + (fvisigrouplink.asmsestring <> fnextgroupstring)); + end + else begin + result:= fvisigrouplink.fieldactive and (islastrecord or + (fvisigrouplink.field.aslargeint <> fnextgroupnum)); + end; +end; + +function tcustomrecordband.bandisvisible(const checklast: boolean): boolean; +label + endlab; +var + firstrecord,lastrecord: boolean; + bo1: boolean; +begin + result:= visible; + firstrecord:= isfirstrecord; + lastrecord:= islastrecord; + if fvisigrouplink.fieldactive then begin + if fvisigrouplink.isstringfield then begin + if (bo_visigroupfirst in foptions) and (firstrecord or + (fvisigrouplink.asmsestring <> fgroupstring)) or + (bo_visigrouplast in foptions) and (lastrecord or + (fvisigrouplink.asmsestring <> fnextgroupstring)) or + (bo_visigroupnotfirst in foptions) and not (firstrecord or + (fvisigrouplink.asmsestring <> fgroupstring)) or + (bo_visigroupnotlast in foptions) and not(lastrecord or + (fvisigrouplink.asmsestring <> fnextgroupstring)) then begin + result:= true; + end + else begin + result:= false; + end; + end + else begin + if (bo_visigroupfirst in foptions) and (firstrecord or + (fvisigrouplink.field.aslargeint <> fgroupnum)) or + (bo_visigrouplast in foptions) and (lastrecord or + (fvisigrouplink.field.aslargeint <> fnextgroupnum)) or + (bo_visigroupnotfirst in foptions) and not (firstrecord or + (fvisigrouplink.field.aslargeint <> fgroupnum)) or + (bo_visigroupnotlast in foptions) and not(lastrecord or + (fvisigrouplink.field.aslargeint <> fnextgroupnum)) then begin + result:= true; + end + else begin + result:= false; + end; + end; + end; + if fvisidatalink.fieldactive then begin + if fvisidatalink.field.isnull then begin + result:= false; + end + else begin + result:= true; + end; + end; + if checkvisibility(fparentintf,foptionsshow,checklast,result,bo1) then begin + if firstrecord then begin + if bos_showfirstrecord in foptionsshow then begin + result:= true; + goto endlab; + end + else begin + if bos_hidefirstrecord in foptionsshow then begin + result:= false; + bo1:= false; + end; + end; + end; + if lastrecord then begin + if bos_showlastrecord in foptionsshow then begin + result:= true; + goto endlab; + end + else begin + if bos_hidelastrecord in foptionsshow then begin + result:= false; + bo1:= false; + end; + end; + end; + if not firstrecord and not lastrecord then begin + if bos_shownormalrecord in foptionsshow then begin + result:= true; + goto endlab; + end + else begin + if bos_hidenormalrecord in foptionsshow then begin + result:= false; + bo1:= false; + end; + end; + end; + if bo1 then begin + result:= true; + end; + end; + endlab: +end; + +function tcustomrecordband.getvisibility: boolean; +begin + result:= bandisvisible(true); +end; + +procedure tcustomrecordband.updatevisibility; +var + int1: integer; +begin + visible:= getvisibility; + beginscaling; + for int1:= 0 to high(frecbands) do begin + with frecbands[int1] do begin + updatevisibility; + end; + end; + endscaling; +end; + +function tcustomrecordband.lastbandheight: integer; +begin + result:= bounds_cy; +end; + +function tcustomrecordband.remainingbands: integer; +var + widget1,widget2,widget3: twidget; + {int1,}int2: integer; +begin + result:= 0; + if fparentintf <> nil then begin + widget3:= fparentintf.getwidget; + widget1:= self; + repeat + widget2:= widget1; + widget1:= widget1.parentwidget; + until (widget1 = widget3); + if widget2 is tcustomrecordband then begin + with tcustomrecordband(widget2) do begin + int2:= fparentintf.remainingheight - lastbandheight; + if int2 >= 0 then begin + if bounds_cy <= 0 then begin + result:= bigint; + end + else begin + result:= 1 + int2 div bounds_cy; + end; + end; + end; + end; + end; +end; + +function tcustomrecordband.reppage: tcustomreportpage; +begin + if fparentintf <> nil then begin + result:= fparentintf.getreppage; + end + else begin + result:= nil; + end; +end; + +procedure tcustomrecordband.finish; +begin + include(fstate,rbs_finish); +end; + +function tcustomrecordband.getvisidatasource: tdatasource; +begin + result:= fvisidatalink.datasource; +end; + +procedure tcustomrecordband.setvisidatasource(const avalue: tdatasource); +begin + fvisidatalink.datasource:= avalue; + fvisigrouplink.datasource:= avalue; +end; + +function tcustomrecordband.getvisidatafield: string; +begin + result:= fvisidatalink.fieldname; +end; + +procedure tcustomrecordband.setvisidatafield(const avalue: string); +begin + fvisidatalink.fieldname:= avalue; +end; + +function tcustomrecordband.getdataset(const aindex: integer): tdataset; +begin + result:= fvisidatalink.dataset; +end; + +procedure tcustomrecordband.getfieldtypes(out apropertynames: stringarty; + out afieldtypes: fieldtypesarty); +begin + setlength(apropertynames,2); + apropertynames[0]:= 'visidatafield'; + apropertynames[1]:= 'visigroupfield'; + setlength(afieldtypes,2); + afieldtypes[0]:= []; + afieldtypes[1]:= [ftinteger,ftlargeint,ftsmallint, + ftword,ftboolean] + textfields; +end; + +function tcustomrecordband.getvisigroupfield: string; +begin + result:= fvisigrouplink.fieldname; +end; + +procedure tcustomrecordband.setvisigroupfield(const avalue: string); +begin + fvisigrouplink.fieldname:= avalue; +end; + +procedure tcustomrecordband.recchanged; +begin + fdatalink.recordchanged(nil); + ftabs.recchanged; +end; + +function tcustomrecordband.getcursorshape(const sender: tobjectpicker; + var ashape: cursorshapety): boolean; +var + ar1: integerarty; +begin + getpickobjects(sender,ar1); + result:= ar1 <> nil; + if result then begin + ashape:= cr_sizehor; + end; +end; + +procedure tcustomrecordband.getpickobjects(const sender: tobjectpicker; + var aobjects: integerarty); +var + int1,int2,int3: integer; + arect: rectty; +begin + arect:= sender.pickrect; + if fframe <> nil then begin + int3:= arect.x - frame.framei_left; + end + else begin + int3:= arect.x - ftextframe; + end; + for int1:= 0 to ftabs.count - 1 do begin + int2:= abs(int3 - ftabs.linepos[int1]); + if int2 < tabpickthreshold then begin + setlength(aobjects,1); + aobjects[0]:= int1; + break; + end; + end; +end; + +procedure tcustomrecordband.beginpickmove(const sender: tobjectpicker); +begin + //dummy +end; + +procedure tcustomrecordband.pickthumbtrack(const sender: tobjectpicker); +begin + //dummy +end; + +procedure tcustomrecordband.endpickmove(const sender: tobjectpicker); +begin + ftabs.linepos[sender.currentobjects[0]]:= + ftabs.linepos[sender.currentobjects[0]] + sender.pickoffset.x; +//fitems[ftabs[index].index] + designchanged('tabs',ftabs.ftabs[sender.currentobjects[0]].index); +end; + +procedure tcustomrecordband.paintxorpic(const sender: tobjectpicker; + const acanvas: tcanvas); +var + i1: int32; +begin + i1:= innerclientpos.x; + if fframe = nil then begin + i1:= i1 + ftextframe; + end; + acanvas.fillxorrect(makerect(i1+sender.pickoffset.x + + ftabs.linepos[sender.currentobjects[0]],0,1,clientheight)); +end; + +procedure tcustomrecordband.clientmouseevent(var info: mouseeventinfoty); +begin + inherited; + if not (es_processed in info.eventstate) and (fobjectpicker <> nil) then begin + fobjectpicker.mouseevent(info); + end; +end; + +procedure tcustomrecordband.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (event = oe_designchanged) and (sender = ftabs.flinksource) then begin + ftabs.sourcechanged; +// designchanged; + end; +end; + +procedure tcustomrecordband.setfont(const avalue: trepwidgetfont); +begin + inherited setfont(avalue); +end; + +function tcustomrecordband.getfont: trepwidgetfont; +begin + result:= trepwidgetfont(inherited getfont); +end; + +function tcustomrecordband.getfontclass: widgetfontclassty; +begin + result:= trepwidgetfont; +end; + +procedure tcustomrecordband.internalcreateframe(); +begin + trepwidgetframe.create(icaptionframe(self)); +end; + +procedure tcustomrecordband.setnextband(const avalue: tcustomrecordband); +begin + setlinkedvar(avalue,tmsecomponent(fnextband)); +end; + +procedure tcustomrecordband.setnextbandiflastofarea( + const avalue: tcustomrecordband); +begin + setlinkedvar(avalue,tmsecomponent(fnextbandiflastofarea)); +end; + +procedure tcustomrecordband.setnextbandifempty(const avalue: tcustomrecordband); +begin + setlinkedvar(avalue,tmsecomponent(fnextbandifempty)); +end; + +procedure tcustomrecordband.setnextbandiflast(const avalue: tcustomrecordband); +begin + setlinkedvar(avalue,tmsecomponent(fnextbandiflast)); +end; + +procedure tcustomrecordband.registerchildwidget(const child: twidget); +begin + inherited; + if child is tbasebandarea then begin + additem(pointerarty(fareas),child); + end; + if child is tcustomrecordband then begin + additem(pointerarty(frecbands),child); + end; +end; + +procedure tcustomrecordband.unregisterchildwidget(const child: twidget); +begin + removeitem(pointerarty(fareas),child); + removeitem(pointerarty(frecbands),child); + inherited; +end; + +procedure tcustomrecordband.setppmm(const avalue: real); +var + int1: integer; +begin + ftabs.ppmm:= avalue; + for int1:= 0 to high(fareas) do begin + fareas[int1].setppmm(avalue); + end; + for int1:= 0 to high(frecbands) do begin + frecbands[int1].setppmm(avalue); + end; +end; + +procedure tcustomrecordband.scale(const ascale: real); +begin + inherited; + ftabs.scale(ascale); +end; + +procedure tcustomrecordband.cancelpickmove(const sender: tobjectpicker); +begin + //dummy +end; + +{ tcustombandgroup } + +procedure tcustombandgroup.registerchildwidget(const child: twidget); +begin + if child is tcustomrecordband then begin + inherited; +// additem(pointerarty(fbands),child); + with tcustomrecordband(child) do begin + fparentintf:= ibandparent(self); + include(fwidgetstate1,ws1_nominsize); + end; + end + else begin + raise exception.create('Widget must be tcustomrecordband.'); + end; +end; + +procedure tcustombandgroup.unregisterchildwidget(const child: twidget); +begin +// removeitem(pointerarty(fbands),child); + tcustomrecordband(child).fparentintf:= nil; + inherited; + exclude(tcustomrecordband(child).fwidgetstate1,ws1_nominsize); +end; + +procedure tcustombandgroup.registerclient(const aclient: ireportclient); +begin + //dummy, register children only +end; + +procedure tcustombandgroup.unregisterclient(const aclient: ireportclient); +begin + //dummy, register children only +end; + +procedure tcustombandgroup.dobeforerender(var empty: boolean); +var + int1: integer; + bo1: boolean; +begin + inherited; + for int1:= 0 to high(frecbands) do begin + bo1:= empty; + frecbands[int1].dobeforerender(bo1); + end; +end; + +procedure tcustombandgroup.dopaint(const acanvas: tcanvas); +var + int1,int2,int3: integer; + pt1: pointty; +begin + inherited; + if rendering then begin + pt1:= acanvas.origin; + int2:= pt1.x - paintpos.x; + int3:= pt1.y + innerclientpos.y; + for int1:= 0 to high(frecbands) do begin + with frecbands[int1] do begin + if visible then begin + acanvas.origin:= makepoint(int2 + bounds_x,int3); + inheritedpaint(acanvas); + inc(int3,bounds_cy); +// acanvas.move(makepoint(0,bounds_cy)); + nextrecord; + end; + end; + end; + acanvas.origin:= pt1; + end; +end; + +procedure tcustombandgroup.setdatasource(const avalue: tdatasource); +var + int1,int2: integer; +begin + inherited; + if (componentstate*[csdesigning,csloading] = [csdesigning]) and + (avalue <> nil) then begin + for int1:= 0 to high(frecbands) do begin + with frecbands[int1] do begin + if datasource = nil then begin + for int2:= 0 to ftabs.count - 1 do begin + ftabs[int2].datasource:= avalue; + end; + end; + end; + end; + end; +end; + +procedure tcustombandgroup.setparentwidget(const avalue: twidget); +var + int1: integer; +begin + inherited; + for int1:= 0 to high(frecbands) do begin + frecbands[int1].fparentintf:= fparentintf; + end; +end; +{ +procedure tcustombandgroup.updatevisibility; +var + int1: integer; +begin + inherited; + beginscaling; + for int1:= 0 to high(fbands) do begin + with fbands[int1] do begin + updatevisibility; + end; + end; + endscaling; +end; +} +function tcustombandgroup.getminbandsize: sizety; +var + int1,int2,int3: integer; +begin + result:= inherited getminbandsize; + int2:= 0; + for int1:= 0 to high(frecbands) do begin + with frecbands[int1] do begin + if visible then begin + int3:= bounds_x + bounds_cx; + if int3 > result.cx then begin + result.cx:= int3; + end; + inc(int2,bounds_cy); + end; + end; + end; + if int2 > result.cy then begin + result.cy:= int2; + end; +end; + +function tcustombandgroup.lastbandheight: integer; +var + int1,int2: integer; +begin + result:= inherited lastbandheight; + if osc_expandy in optionsscale then begin + int2:= innerclientframewidth.cy; + for int1:= 0 to high(frecbands) do begin + with frecbands[int1] do begin + if bandisvisible(false) and not (bos_hidelastofpage in foptionsshow) or + (bos_showlastofpage in foptionsshow) then begin + int2:= int2 + bounds_cy; + end; + end; + end; + if int2 > result then begin + result:= int2; + end; + end; +end; + +procedure tcustombandgroup.setareafull(const avalue: boolean); +begin + if fparentintf <> nil then begin + fparentintf.setareafull(avalue); + end; +end; + +procedure tcustombandgroup.init; +var + int1: integer; +begin + sortwidgetsyorder(widgetarty(frecbands)); + inherited; + for int1:= 0 to high(frecbands) do begin + frecbands[int1].init; + end; +end; + +procedure tcustombandgroup.beginrender(const arestart: boolean); +var + int1: integer; +begin + inherited; + for int1:= 0 to high(frecbands) do begin + frecbands[int1].beginrender(arestart); + end; +end; + +procedure tcustombandgroup.resetzebra; +var + int1: integer; +begin + inherited; + for int1:= 0 to high(frecbands) do begin + frecbands[int1].resetzebra; + end; +end; + +procedure tcustombandgroup.endrender; +var + int1: integer; +begin + inherited; + for int1:= 0 to high(frecbands) do begin + frecbands[int1].endrender; + end; +end; + +procedure tcustombandgroup.adddatasets(var adatasets: datasetarty); +var + int1: integer; +begin + inherited; + for int1:= 0 to high(frecbands) do begin + frecbands[int1].adddatasets(adatasets); + end; +end; + +function tcustombandgroup.beginband(const acanvas: tcanvas; + const sender: tcustomrecordband): boolean; +begin + result:= fparentintf.beginband(acanvas,sender); +end; + +procedure tcustombandgroup.endband(const acanvas: tcanvas; + const sender: tcustomrecordband); +begin + fparentintf.endband(acanvas,sender); +end; + +function tcustombandgroup.istopband: boolean; +begin + result:= fparentintf.istopband; +end; + +function tcustombandgroup.isfirstband: boolean; +begin + result:= fparentintf.isfirstband; +end; + +function tcustombandgroup.islastband(const addheight: integer = 0): boolean; +begin + result:= fparentintf.islastband; +end; + +procedure tcustombandgroup.updatevisible; +begin + fparentintf.updatevisible; +end; + +function tcustombandgroup.getwidget: twidget; +begin + result:= fparentintf.getwidget; +end; + +function tcustombandgroup.remainingheight: integer; +begin + result:= fparentintf.remainingheight; +end; + +function tcustombandgroup.pagepagenum: integer; +begin + result:= fparentintf.pagepagenum; +end; + +function tcustombandgroup.reppagenum: integer; +begin + result:= fparentintf.reppagenum; +end; + +function tcustombandgroup.getlastpagepagecount: integer; +begin + result:= fparentintf.getlastpagepagecount; +end; + +function tcustombandgroup.getlastreppagecount: integer; +begin + result:= fparentintf.getlastreppagecount; +end; + +function tcustombandgroup.pageprintstarttime: tdatetime; +begin + result:= fparentintf.pageprintstarttime; +end; + +function tcustombandgroup.repprintstarttime: tdatetime; +begin + result:= fparentintf.repprintstarttime; +end; + +function tcustombandgroup.getreppage: tcustomreportpage; +begin + result:= fparentintf.getreppage; +end; + +procedure tcustombandgroup.dobeforenextrecord(const adatasource: tdatasource); +var + int1: integer; +begin + inherited; + for int1:= 0 to high(frecbands) do begin + frecbands[int1].dobeforenextrecord(adatasource); + end; +end; + +procedure tcustombandgroup.dosyncnextrecord; +var + int1: integer; +begin + inherited; + for int1:= 0 to high(frecbands) do begin + frecbands[int1].dosyncnextrecord; + end; +end; + +procedure tcustombandgroup.initpage; +var + int1: integer; +begin + inherited; + for int1:= 0 to high(frecbands) do begin + frecbands[int1].initpage; + end; +end; + +function tcustombandgroup.getppmm: real; +begin + result:= ftabs.ppmm; +end; + +{ tbasebandarea } + +function tbasebandarea.getareafull: boolean; +begin + result:= bas_areafull in fstate; +end; + +procedure tbasebandarea.setareafull(const avalue: boolean); +begin + if avalue then begin + include(fstate,bas_areafull); + end + else begin + exclude(fstate,bas_areafull); + end; +end; + +procedure tbasebandarea.registerchildwidget(const child: twidget); +begin + inherited; + if child is tcustomrecordband then begin + additem(pointerarty(fareabands),child); + end; +end; + +procedure tbasebandarea.unregisterchildwidget(const child: twidget); +begin + removeitem(pointerarty(fareabands),child); + inherited; +end; + +procedure tbasebandarea.registerclient(const aclient: ireportclient); +begin + //dummy, register children only +end; + +procedure tbasebandarea.unregisterclient(const aclient: ireportclient); +begin + //dummy, register children only +end; + +procedure tbasebandarea.setparentwidget(const avalue: twidget); +var + widget1: twidget; +begin + if avalue is tcustomrecordband then begin + frecordband:= tcustomrecordband(avalue); + end + else begin + frecordband:= nil; + end; + if avalue is tcustomreportpage then begin + freportpage:= tcustomreportpage(avalue); + end + else begin + freportpage:= nil; + widget1:= avalue.parentwidget; + while widget1 <> nil do begin + if widget1 is tcustomreportpage then begin + freportpage:= tcustomreportpage(widget1); + break; + end; + widget1:= widget1.parentwidget; + end; + end; + inherited; +end; + +procedure tbasebandarea.init; +var + int1: integer; +begin + include(fstate,bas_inited); + sortwidgetsyorder(widgetarty(fareabands)); + for int1:= 0 to high(fareabands) do begin + fareabands[int1].init; + end; + initareapage; +end; + +procedure tbasebandarea.initband; +begin + sortwidgetsyorder(widgetarty(fareabands)); + fstate:= fstate - [bas_areafull,bas_backgroundrendered,bas_notfirstband, + bas_lastband]; +end; + +procedure tbasebandarea.initpage; +var + int1: integer; +begin + include(fstate,bas_top); + for int1:= 0 to high(fareabands) do begin + fareabands[int1].initpage; + end; + initband; +end; + +function tbasebandarea.render(const acanvas: tcanvas): boolean; +begin + result:= false; + //dummy +end; + +procedure tbasebandarea.initareapage; +begin + exclude(fstate,bas_notfirstband); + include(fstate,bas_top); +end; + +procedure tbasebandarea.dofirstarea; +begin + if canevent(tmethod(fonfirstarea)) then begin + application.lock; + try + fonfirstarea(self); + finally + application.unlock; + end; + end; +end; + +procedure tbasebandarea.dobeforerender; +begin + if canevent(tmethod(fonbeforerender)) then begin + application.lock; + try + fonbeforerender(self); + finally + application.unlock; + end; + end; +end; + +procedure tbasebandarea.doonpaint(const acanvas: tcanvas); +begin + if canevent(tmethod(fonpaint)) then begin + application.lock; + try + fonpaint(self,acanvas); + finally + application.unlock; + end; + end; +end; + +procedure tbasebandarea.doafterpaint1(const acanvas: tcanvas); +begin + if canevent(tmethod(fonafterpaint)) then begin + application.lock; + try + fonafterpaint(self,acanvas); + finally + application.unlock; + end; + end; +end; + +procedure tbasebandarea.renderbackground(const acanvas: tcanvas); +begin + if frecordband = nil then begin + freportpage.beginarea(acanvas,self); + acanvas.origin:= pos; + end + else begin + acanvas.origin:= forigin; + end; + inherited paint(acanvas); +end; + +function tbasebandarea.checkareafull(ay: integer): boolean; +begin + if frame <> nil then begin + ay:= ay + fframe.innerframe.bottom; + end; + result:= ay > bounds_y + bounds_cy; +end; + +function tbasebandarea.beginband(const acanvas: tcanvas; + const sender: tcustomrecordband): boolean; +begin + result:= false; //dummy +end; + +procedure tbasebandarea.endband(const acanvas: tcanvas; + const sender: tcustomrecordband); +begin + //dummy +end; + +procedure tbasebandarea.paint(const canvas: tcanvas); +begin + if not rendering then begin + inherited; + end + else begin + if (frecordband <> nil) then begin + forigin:= canvas.origin; + render(canvas); + end; + end; +end; + +function tbasebandarea.rendering: boolean; +begin + result:= bas_rendering in fstate; +end; + +procedure tbasebandarea.beginrender(const arestart: boolean); +var + int1: integer; +begin + if arestart then begin + fstate:= fstate - [bas_notfirstband,bas_finished]; + end + else begin + fstate:= [bas_rendering]; + end; + include(fwidgetstate1,ws1_noclipchildren); + for int1:= 0 to high(fareabands) do begin + with fareabands[int1] do begin + beginrender(false); + end; + end; +end; + +procedure tbasebandarea.resetzebra; +var + int1: integer; +begin + for int1:= 0 to high(fareabands) do begin + fareabands[int1].resetzebra; + end; +end; + +procedure tbasebandarea.endrender; +var + int1: integer; +begin + exclude(fstate,bas_rendering); + exclude(fwidgetstate1,ws1_noclipchildren); + for int1:= 0 to high(fareabands) do begin + fareabands[int1].endrender; + end; +end; + +procedure tbasebandarea.adddatasets(var adatasets: datasetarty); +var + int1: integer; +begin + for int1:= 0 to high(fareabands) do begin + fareabands[int1].adddatasets(adatasets); + end; +end; + +function tbasebandarea.istopband: boolean; +begin + result:= bas_top in fstate; +end; + +function tbasebandarea.isfirstband: boolean; +begin + result:= false; //dummy +end; + +function tbasebandarea.islastband(const addheight: integer = 0): boolean; +begin + result:= false; //dummy +end; + +function tbasebandarea.remainingheight: integer; +begin + result:= 0; //dummy +end; + +procedure tbasebandarea.updatevisible; +var + int1: integer; +begin + for int1:= 0 to high(fareabands) do begin + fareabands[int1].updatevisibility; + end; +end; + +function tbasebandarea.pagepagenum: integer; +begin + result:= freportpage.pagenum; +end; + +function tbasebandarea.reppagenum: integer; +begin + if freportpage.freport <> nil then begin + result:= freportpage.freport.pagenum; + end + else begin + result:= 0; + end; +end; + +function tbasebandarea.pageprintstarttime: tdatetime; +begin + result:= freportpage.fprintstarttime; +end; + +function tbasebandarea.getlastpagepagecount: integer; +begin + result:= freportpage.flastpagecount; +end; + +function tbasebandarea.getlastreppagecount: integer; +begin + if freportpage.freport <> nil then begin + result:= freportpage.freport.flastpagecount; + end + else begin + result:= 0; + end; +end; + +function tbasebandarea.repprintstarttime: tdatetime; +begin + if freportpage.freport <> nil then begin + result:= freportpage.freport.fprintstarttime; + end + else begin + result:= nowlocal; + end; +end; + +function tbasebandarea.getreppage: tcustomreportpage; +begin + result:= freportpage; +end; + +function tbasebandarea.isfirstrecord: boolean; +begin + if frecordband <> nil then begin + result:= frecordband.isfirstrecord; + end + else begin + result:= freportpage.isfirstrecord; + end; +end; + +function tbasebandarea.islastrecord: boolean; +begin + if frecordband <> nil then begin + result:= frecordband.islastrecord; + end + else begin + result:= freportpage.islastrecord; + end; +end; + +procedure tbasebandarea.dobeforenextrecord(const adatasource: tdatasource); +var + int1: integer; +begin + for int1:= 0 to high(fareabands) do begin + fareabands[int1].dobeforenextrecord(adatasource); + end; +end; + +procedure tbasebandarea.setppmm(const avalue: real); +var + int1: integer; +begin + for int1:= 0 to high(fareabands) do begin + fareabands[int1].setppmm(avalue); + end; +end; + +procedure tbasebandarea.dosyncnextrecord; +var + int1: integer; +begin + for int1:= 0 to high(fareabands) do begin + fareabands[int1].dosyncnextrecord; + end; +end; + +procedure tbasebandarea.setfont(const avalue: trepwidgetfont); +begin + inherited setfont(avalue); +end; + +function tbasebandarea.getfont: trepwidgetfont; +begin + result:= trepwidgetfont(inherited getfont); +end; + +function tbasebandarea.getfontclass: widgetfontclassty; +begin + result:= trepwidgetfont; +end; + +procedure tbasebandarea.restart; +begin + beginrender(true); + if freportpage <> nil then begin + freportpage.recordchanged; + end; +end; + +function tbasebandarea.getppmm: real; +begin + if freportpage <> nil then begin + result:= freportpage.ppmm; + end + else begin + result:= defaultppmm; + end; +end; + +{ tcustomreportpage } + +constructor tcustomreportpage.create(aowner: tcomponent); +begin + fprintstarttime:= nowlocal; + fvisiblepage:= true; + fdatalink:= treportpagedatalink.create; + inherited; + fwidgetstate1:= fwidgetstate1 + [{ws1_nodesignvisible,}ws1_nodesignmove + {,ws1_nodesignhandles,ws1_nodesigndelete}]; +// fpagewidth:= defaultreppagewidth; +// fpageheight:= defaultreppageheight; + fppmm:= defaultrepppmm; + with fwidgetrect do begin + cx:= round(defaultreppagewidth*defaultrepppmm); + cy:= round(defaultreppageheight*defaultrepppmm); + end; +end; + +destructor tcustomreportpage.destroy; +begin + inherited; + fdatalink.free; +end; + +procedure tcustomreportpage.registerchildwidget(const child: twidget); +begin + inherited; + if child is tbasebandarea then begin + additem(pointerarty(fareas),child); + end; +end; + +procedure tcustomreportpage.unregisterchildwidget(const child: twidget); +begin + removeitem(pointerarty(fareas),child); + inherited; +end; + +procedure tcustomreportpage.registerclient(const aclient: ireportclient); +var + widget1: twidget; +begin + if finditem(pointerarty(fclients),pointer(aclient)) < 0 then begin + additem(pointerarty(fclients),pointer(aclient)); + end; + widget1:= aclient.getwidget; + if widget1 is tcustomrecordband then begin + if finditem(pointerarty(fbands),widget1) < 0 then begin + additem(pointerarty(fbands),widget1); + end; + end; +end; + +procedure tcustomreportpage.unregisterclient(const aclient: ireportclient); +begin + removeitem(pointerarty(fclients),pointer(aclient)); + removeitem(pointerarty(fbands),aclient.getwidget); +end; + +procedure tcustomreportpage.setparentwidget(const avalue: twidget); +begin + if avalue is tcustomreport then begin + freport:= tcustomreport(avalue); + updatepagesize; + end + else begin + freport:= nil; + end; + inherited; +end; + +procedure tcustomreportpage.init; +var + int1: integer; +begin + include(fstate,rpps_inited); + exclude(fstate,rpps_showed); + for int1:= 0 to high(fclients) do begin + fclients[int1].init; + end; +// for int1:= 0 to high(fareas) do begin +// fareas[int1].init; +// end; +end; + +procedure tcustomreportpage.dosyncnextrecord; +var + int1: integer; +begin + for int1:= 0 to high(fareas) do begin + fareas[int1].dosyncnextrecord; + end; + for int1:= 0 to high(fbands) do begin + fbands[int1].dosyncnextrecord; + end; +end; + +procedure tcustomreportpage.dobeforenextrecord(const adatasource: tdatasource); +var + int1: integer; +begin + for int1:= 0 to high(fareas) do begin + fareas[int1].dobeforenextrecord(adatasource); + end; + for int1:= 0 to high(fbands) do begin + fbands[int1].dobeforenextrecord(adatasource); + end; +end; + +procedure tcustomreportpage.nextrecord; +begin + application.lock; + try + exclude(fstate,rpps_nextrecordpending); + if canevent(tmethod(fonbeforenextrecord)) then begin + fonbeforenextrecord(self); + end; + dobeforenextrecord(fdatalink.datasource); + fdatalink.dataset.next; + if checkislastrecord(fdatalink,{$ifdef FPC}@{$endif}dosyncnextrecord) then begin + include(fstate,rpps_lastrecord); + end; + if canevent(tmethod(fonafternextrecord)) then begin + fonafternextrecord(self); + end; + finally + application.unlock; + end; + recordchanged; +end; + +function tcustomreportpage.render(const acanvas: tcanvas): boolean; +var + int1: integer; + bo1,bo2,bo4: boolean; + customdataempty: boolean; + backgroundrendered: boolean; +// hascustomdata: boolean; + + procedure renderband(const aband: tcustomrecordband); + begin + with aband do begin + bo4:= (not customdataempty or backgroundrendered) and + (bo2 and (bo_oddpage in foptions) or + not bo2 and (bo_evenpage in foptions)); //has data + bo4:= not(bo4 or ((bo_once in foptions) and not (rbs_showed in fstate))); + //empty + render(acanvas,bo4); + bo1:= bo1 and bo4; + end; + end; + +var + orient1: pageorientationty; + +begin + if not (rpps_inited in fstate) then begin + init; + end; + fprintstarttime:= nowlocal; + bo1:= odd(reppagenum); + if bo1 and (rpo_firsteven in foptions) or not bo1 and + (rpo_firstodd in foptions) then begin + freport.nextpage(acanvas); + with freport do begin + if fpagenum = 0 then begin + include(fstate,rs_dummypage); + end; + inc(fpagenum); + end; + end; + fpagenum:= 0; + exclude(fstate,rpps_finish); + recordchanged; + dofirstpage; + result:= true; + repeat + if rpps_finish in fstate then begin + break; + end; + if rpps_nextrecordpending in fstate then begin + nextrecord; + end; + exclude(fstate,rpps_backgroundrendered); + acanvas.reset; + if acanvas is tcustomprintercanvas then begin + if fprintorientation = rpo_default then begin + orient1:= freport.fdefaultprintorientation; + end + else begin + orient1:= pageorientationty(pred(fprintorientation)); + end; + tcustomprintercanvas(acanvas).printorientation:= orient1; + end; + acanvas.intersectcliprect(makerect(nullpoint,fwidgetrect.size)); + updatevisible; + bo1:= (not fdatalink.active or fdatalink.dataset.eof) and + not ((rpo_once in foptions) and not (rpps_showed in fstate)); + dobeforerender(bo1); + customdataempty:= bo1; + if not bo1 or not (rpo_datasourceonly in foptions) then begin + for int1:= 0 to high(fareas) do begin + fareas[int1].initpage; + end; + for int1:= 0 to high(fbands) do begin + fbands[int1].initpage; + end; + updatevisible; + for int1:= 0 to high(fareas) do begin + with fareas[int1] do begin + if visible then begin + bo1:= render(acanvas) and bo1; + end; + end; + end; + sortwidgetsyorder(widgetarty(fbands),self); + bo2:= odd(reppagenum); + // bo5:= true; + backgroundrendered:= rpps_backgroundrendered in fstate; + for int1:= 0 to high(fbands) do begin + if not (fbands[int1] is tcustomrepvaluedisp) then begin + renderband(fbands[int1]); + end; + end; + backgroundrendered:= rpps_backgroundrendered in fstate; + for int1:= 0 to high(fbands) do begin + if fbands[int1] is tcustomrepvaluedisp then begin + renderband(fbands[int1]); + end; + end; + if not (rpps_backgroundrendered in fstate) and not customdataempty then begin + renderbackground(acanvas); + end; + + if rpps_backgroundrendered in fstate then begin + doafterpaint1(acanvas); + if canevent(tmethod(fonafterrender)) then begin + fonafterrender(self); + end; + if not (rpps_finish in fstate) and fdatalink.active then begin + bo1:= false; + if rpo_delayednextrecord in foptions then begin + include(fstate,rpps_nextrecordpending); + end + else begin + nextrecord; + end; + end; + inc(fpagenum); + inc(freport.fpagenum); + include(fstate,rpps_showed); + end; + freport.doprogress; + end; + result:= result and bo1; + if bo1 or (fnextpage <> nil) or (rpps_finish in fstate) then begin + //next page + exclude(fstate,rpps_restart); + doafterlastpage; + if rpps_restart in fstate then begin + bo1:= false; + end; + end; + until bo1 or (fnextpage <> nil); +end; + +function tcustomreportpage.rendering: boolean; +begin + result:= rpps_rendering in fstate; +end; + +procedure tcustomreportpage.dobeforerender(var empty: boolean); +begin + if canevent(tmethod(fonbeforerender)) then begin + application.lock; + try + fonbeforerender(self,empty); + finally + application.unlock; + end; + end; + freport.dopagebeforerender(self,empty); +end; + +procedure tcustomreportpage.doonpaint(const acanvas: tcanvas); +begin + if freport <> nil then begin + freport.dopagepaint(self,acanvas); + if canevent(tmethod(fonpaint)) then begin + application.lock; + try + fonpaint(self,acanvas); + finally + application.unlock; + end; + end; + end; +end; + +procedure tcustomreportpage.doafterpaint1(const acanvas: tcanvas); +begin + if canevent(tmethod(fonafterpaint)) then begin + application.lock; + try + fonafterpaint(self,acanvas); + finally + application.unlock; + end; + end; + if freport <> nil then begin + freport.dopageafterpaint(self,acanvas); + end; +end; + +procedure tcustomreportpage.renderbackground(const acanvas: tcanvas); +//var +// orient1: pageorientationty; +begin + if (freport.fpagenum <> 0) and not (rs_dummypage in freport.fstate) then begin + freport.nextpage(acanvas); + end; + exclude(freport.fstate,rs_dummypage); +{ moved to render + if acanvas is tprintercanvas then begin + if fprintorientation = rpo_default then begin + orient1:= freport.fdefaultprintorientation; + end + else begin + orient1:= pageorientationty(pred(fprintorientation)); + end; + tprintercanvas(acanvas).printorientation:= orient1; + end; +} + acanvas.origin:= pos; + inherited paint(acanvas); + include(fstate,rpps_backgroundrendered); +end; + +procedure tcustomreportpage.beginarea(const acanvas: tcanvas; + const sender: tbasebandarea); +begin + if not (rpps_backgroundrendered in fstate) then begin + include(fstate,rpps_backgroundrendered); + renderbackground(acanvas); + end; +end; + +procedure tcustomreportpage.beginrender(const arestart: boolean); + procedure addreccontrols(const awidget: twidget); + var + int1: integer; + po1: pointer; + begin + for int1:= 0 to awidget.widgetcount -1 do begin + addreccontrols(awidget.widgets[int1]); + if awidget.widgets[int1].getcorbainterface(typeinfo(ireccontrol),po1) then begin + additem(freccontrols,po1); + end; + end; + end; +var + int1: integer; +begin + freccontrols:= nil; + addreccontrols(self); + if arestart then begin + fstate:= fstate * [rpps_inited,rpps_rendering]; + end + else begin + fstate:= [rpps_rendering]; + end; + include(fwidgetstate1,ws1_noclipchildren); + with fdatalink do begin + if active then begin + application.lock; + try + dataset.first; + if checkislastrecord(fdatalink,{$ifdef FPC}@{$endif}dosyncnextrecord) then begin + include(fstate,rpps_lastrecord); + end; + finally + application.unlock; + end; + self.recordchanged; + end; + end; + for int1:= 0 to high(fclients) do begin + fclients[int1].beginrender(false); + end; + for int1:= 0 to high(fareas) do begin + fareas[int1].beginrender(false); + end; +end; + +procedure tcustomreportpage.resetzebra; +var + int1: integer; +begin + for int1:= 0 to high(fclients) do begin + fclients[int1].resetzebra; + end; + for int1:= 0 to high(fareas) do begin + fareas[int1].resetzebra; + end; +end; + +procedure tcustomreportpage.endrender; +var + int1: integer; +begin + flastpagecount:= fpagenum; + freccontrols:= nil; + exclude(fstate,rpps_rendering); + exclude(fwidgetstate1,ws1_noclipchildren); + for int1:= 0 to high(fclients) do begin + fclients[int1].endrender; + end; + for int1:= 0 to high(fareas) do begin + fareas[int1].endrender; + end; +end; + +procedure tcustomreportpage.adddatasets(var adatasets: datasetarty); +var + int1: integer; +begin + if fdatalink.dataset <> nil then begin + adduniqueitem(pointerarty(adatasets),fdatalink.dataset); + end; + for int1:= 0 to high(fclients) do begin + fclients[int1].adddatasets(adatasets); + end; + for int1:= 0 to high(fareas) do begin + fareas[int1].adddatasets(adatasets); + end; +end; + +procedure tcustomreportpage.setpagewidth(const avalue: real); +begin + if fpagewidth <> avalue then begin + fpagewidth:= avalue; + updatepagesize; + end; +end; + +procedure tcustomreportpage.setpageheight(const avalue: real); +begin + if fpageheight <> avalue then begin + fpageheight:= avalue; + updatepagesize; + end; +end; + +procedure tcustomreportpage.updatepagesize; +begin + if not (rpps_sizesetting in fstate) then begin + include(fstate,rpps_sizesetting); + size:= makesize(round(getpagewidth*fppmm),round(getpageheight*fppmm)); + fpagedim:= size; + exclude(fstate,rpps_sizesetting); + end; +end; + +procedure tcustomreportpage.sizechanged; +begin + if (freport <> nil) and visible then begin + freport.size:= size; + end; + inherited; + if (csdesigning in componentstate) and + not (rpps_sizesetting in fstate) then begin + if width <> fpagedim.cx then begin + fpagedim.cx:= width; + fpagewidth:= fpagedim.cx / fppmm; + end; + if height <> fpagedim.cy then begin + fpagedim.cy:= height; + fpageheight:= fpagedim.cy / fppmm; + end; + end; +end; + +procedure tcustomreportpage.setppmm(const avalue: real); +var + rea1: real; + int1: integer; +begin + if avalue <> fppmm then begin + rea1:= avalue/fppmm; + fppmm:= avalue; + for int1:= 0 to high(fclients) do begin + fclients[int1].setppmm(avalue); + end; + for int1:= 0 to high(fareas) do begin + fareas[int1].setppmm(avalue); + end; + if not (csloading in componentstate) then begin + scale(rea1); + end; + updatepagesize; + end; +end; + +procedure tcustomreportpage.insertwidget(const awidget: twidget; + const apos: pointty); +begin + if (awidget is tcustomreportpage) and (fparentwidget <> nil) then begin + fparentwidget.insertwidget(awidget,addpoint(apos,pos)); + end + else begin + inherited; + end; +end; + +procedure tcustomreportpage.dofirstpage; +begin + if canevent(tmethod(fonfirstpage)) then begin + application.lock; + try + fonfirstpage(self); + finally + application.unlock; + end; + end; +end; + +procedure tcustomreportpage.doafterlastpage; +begin + if canevent(tmethod(fonafterlastpage)) then begin + application.lock; + try + fonafterlastpage(self); + finally + application.unlock; + end; + end; +end; + +procedure tcustomreportpage.setnextpage(const avalue: tcustomreportpage); +begin + setlinkedvar(avalue,tmsecomponent(fnextpage)); +end; + +procedure tcustomreportpage.setnextpageifempty(const avalue: tcustomreportpage); +begin + setlinkedvar(avalue,tmsecomponent(fnextpageifempty)); +end; + +procedure tcustomreportpage.setnextpageiflast(const avalue: tcustomreportpage); +begin + setlinkedvar(avalue,tmsecomponent(fnextpageiflast)); +end; + +function tcustomreportpage.beginband(const acanvas: tcanvas; + const sender: tcustomrecordband): boolean; +begin + fsaveindex:= acanvas.save; + if not (rpps_backgroundrendered in fstate) then begin + renderbackground(acanvas); + end; + acanvas.origin:= translatewidgetpoint(sender.pos,sender.parentwidget,self); + result:= false; +end; + +procedure tcustomreportpage.endband(const acanvas: tcanvas; + const sender: tcustomrecordband); +begin + acanvas.restore(fsaveindex); + include(sender.fstate,rbs_showed); +end; + +function tcustomreportpage.istopband: boolean; +begin + result:= false; +end; + +function tcustomreportpage.isfirstband: boolean; +begin + result:= false; +end; + +function tcustomreportpage.islastband(const addheight: integer = 0): boolean; +begin + result:= false; +end; + +procedure tcustomreportpage.setareafull(const avalue: boolean); +begin + //dummy +end; + +procedure tcustomreportpage.updatevisible; +var + int1: integer; +begin + for int1:= 0 to high(fclients) do begin + fclients[int1].updatevisibility; + end; + for int1:= 0 to high(fareas) do begin + fareas[int1].updatevisible; + end; +end; + +function tcustomreportpage.remainingheight: integer; +begin + result:= 0; +end; + +function tcustomreportpage.pagepagenum: integer; +begin + result:= fpagenum; +end; + +function tcustomreportpage.reppagenum: integer; +begin + if freport <> nil then begin + result:= freport.fpagenum; + end + else begin + result:= 0; + end; +end; + +function tcustomreportpage.getdatasource: tdatasource; +begin + result:= fdatalink.datasource; +end; + +function tcustomreportpage.pageprintstarttime: tdatetime; +begin + result:= fprintstarttime; +end; + +function tcustomreportpage.repprintstarttime: tdatetime; +begin + if freport <> nil then begin + result:= freport.fprintstarttime; + end + else begin + result:= nowlocal(); + end; +end; + +procedure tcustomreportpage.setdatasource(const avalue: tdatasource); +begin + fdatalink.datasource:= avalue; +end; + +procedure tcustomreportpage.activatepage; +begin + if freport <> nil then begin + freport.activepage:= finditem(pointerarty(freport.freppages),self); + end; +end; + +procedure tcustomreportpage.finish; +begin + include(fstate,rpps_finish); +end; + +procedure tcustomreportpage.restart; +begin + beginrender(true); + include(fstate,rpps_restart); + recordchanged; +end; + +procedure tcustomreportpage.setoptions(const avalue: reportpageoptionsty); +const + mask: reportpageoptionsty = [rpo_firsteven,rpo_firstodd]; +begin + foptions:= reportpageoptionsty(setsinglebit( + {$ifdef FPC}longword{$else}byte{$endif}(avalue), + {$ifdef FPC}longword{$else}byte{$endif}(foptions), + {$ifdef FPC}longword{$else}byte{$endif}(mask))); +end; + +function tcustomreportpage.getreppage: tcustomreportpage; +begin + result:= self; +end; + +function tcustomreportpage.isfirstrecord: boolean; +begin + if fdatalink.active then begin + result:= not (rpps_notfirstrecord in fstate); + end + else begin + result:= false; + end; +end; + +function tcustomreportpage.islastrecord: boolean; +begin + if fdatalink.active then begin + result:= rpps_lastrecord in fstate; + end + else begin + result:= false; + end; +end; + +procedure tcustomreportpage.recordchanged; +var + int1: integer; +begin + application.lock; + try + for int1:= 0 to high(freccontrols) do begin + ireccontrol(freccontrols[int1]).recchanged; + end; + finally + application.unlock; + end; +end; + +function tcustomreportpage.getlastpagepagecount: integer; +begin + result:= flastpagecount; +end; + +function tcustomreportpage.getlastreppagecount: integer; +begin + if freport <> nil then begin + result:= freport.flastpagecount; + end + else begin + result:= 0; + end; +end; + +procedure tcustomreportpage.setfont(const avalue: trepwidgetfont); +begin + inherited setfont(avalue); +end; + +function tcustomreportpage.getfont: trepwidgetfont; +begin + result:= trepwidgetfont(inherited getfont); +end; + +function tcustomreportpage.getfontclass: widgetfontclassty; +begin + result:= trepwidgetfont; +end; + +function tcustomreportpage.getppmm: real; +begin + result:= fppmm; +end; + +function tcustomreportpage.getpagewidth: real; +begin + result:= fpagewidth; + if result = 0 then begin + if freport = nil then begin + result:= defaultpagewidth; + end + else begin + result:= freport.fpagewidth; + end; + end + else begin + if (rpo_reportpagewidth in foptions) and (freport <> nil) then begin + result:= freport.fpagewidth; + end; + end; +end; + +function tcustomreportpage.getpageheight: real; +begin + result:= fpageheight; + if result = 0 then begin + if freport = nil then begin + result:= defaultpageheight; + end + else begin + result:= freport.fpageheight; + end; + end + else begin + if (rpo_reportpageheight in foptions) and (freport <> nil) then begin + result:= freport.fpageheight; + end; + end; +end; + +procedure initrepdesigninfo(var ainfo: repdesigninfoty); +begin + with ainfo do begin + widgetrect:= makerect(50,50,50,50); + gridsize:= 2; //mm + showgrid:= true; + snaptogrid:= true; + end; +end; + +{ tcustomreport } + +constructor tcustomreport.create(aowner: tcomponent); +begin + fprintstarttime:= nowlocal; + fppmm:= defaultrepppmm; + fpagewidth:= defaultreppagewidth; + fpageheight:= defaultreppageheight; + foptions:= defaultreportoptions; + initrepdesigninfo(frepdesigninfo); + inherited; + visible:= false; + color:= cl_transparent; +{$warnings off} + ffont:= twidgetfont(trepfont.create); +{$warnings on} + ffont.height:= round(defaultrepfontheight * (fppmm/defaultrepppmm)); + ffont.onchange:= {$ifdef FPC}@{$endif}dofontchanged; + //createfont; +end; + +destructor tcustomreport.destroy; +begin + if fthread <> nil then begin + fthread.terminate; + application.waitforthread(fthread); + end; + fthread.free; + inherited; +end; + +class function tcustomreport.hasresource: boolean; +begin + result:= true; +end; + +procedure tcustomreport.unregisterchildwidget(const child: twidget); +begin + removeitem(pointerarty(freppages),child); + inherited; +end; + +procedure tcustomreport.setppmm(const avalue: real); +var + int1: integer; +begin + if avalue <> fppmm then begin + if avalue <= 0 then begin + raise exception.create('Invalid value'); + end; + if (ffont <> nil) and (fppmm > 0) then begin + include(fwidgetstate1,ws1_scaling); + ffont.scale(avalue/fppmm); + exclude(fwidgetstate1,ws1_scaling); + end; + fppmm:= avalue; + for int1:= 0 to high(freppages) do begin + freppages[int1].ppmm:= avalue; + end; + if not (csloading in componentstate) then begin + postchildscaled; + end; + end; +end; + +procedure tcustomreport.initpage(const apage: tcustomreportpage); +begin + apage.ppmm:= fppmm; +end; + +procedure tcustomreport.insertwidget(const awidget: twidget; + const apos: pointty); +begin + if not (awidget is tcustomreportpage) then begin + raise exception.create('Invalid widget'); + end; + additem(pointerarty(freppages),awidget); + initpage(tcustomreportpage(awidget)); + inherited insertwidget(awidget,nullpoint); +end; + +function tcustomreport.add(const apage: tcustomreportpage; + aindex: int32 = bigint): tcustomreportpage; +var + i1: int32; +begin + result:= apage; + i1:= length(freppages); + if aindex >= i1 then begin + aindex:= i1; + end; + insertitem(pointerarty(freppages),aindex,apage); + initpage(apage); + apage.parentwidget:= self; +end; + +procedure tcustomreport.delete(const aindex: int32); +begin + reppages[aindex].destroy(); +end; + +procedure tcustomreport.clear(); +begin + while freppages <> nil do begin + delete(high(freppages)); + end; +end; + +procedure tcustomreport.movepage(const curindex: int32; const newindex: int32); +begin + moveitem(pointerarty(freppages),curindex,newindex); +end; + +function tcustomreport.exec(thread: tmsethread): integer; + + function checkterminated: boolean; + begin + result:= (thread <> nil) and thread.terminated or fcanceled; + end; + + procedure fakevisible(const awidget: twidget; const aset: boolean); + var + int1: integer; + begin + with twidget1(awidget) do begin + if aset then begin + include(fwidgetstate1,ws1_fakevisible); + end + else begin + exclude(fwidgetstate1,ws1_fakevisible); + end; +// updateopaque(false); + for int1:= 0 to high(fwidgets) do begin + fakevisible(fwidgets[int1],aset); + end; + end; + end; + +var + terminated1: boolean; + recnos: integerarty; + renderbegin: boolean; + + procedure dofinish(const islast: boolean); + var + int1: integer; + begin + application.lock; + try + fakevisible(self,false); + flastpagecount:= fpagenum; + if renderbegin then begin + for int1:= 0 to high(freppages) do begin + freppages[int1].endrender; + end; + end; + terminated1:= checkterminated; + if islast or (rs_endpass in fstate) or terminated1 then begin + exclude(fstate,rs_running); + fstream.free; + if fprinter <> nil then begin + fprinter.endprint; + fprinter.canvas.printorientation:= fdefaultprintorientation; + end; + fcanvas.ppmm:= fppmmbefore; + asyncevent(endrendertag); + for int1:= 0 to high(fdatasets) do begin + with fdatasets[int1] do begin + if active then begin + if (recnos[int1] > 0) and (recnos[int1] <= recordcount) then begin + try + if recno <> recnos[int1] then begin + //no checkbrowsemode if there was no scroll + recno:= recnos[int1]; + end; + except; + end; + end; + end; + if not (reo_nodisablecontrols in foptions) then begin + try + enablecontrols; + except + end; + end; + end; + end; + fdatasets:= nil; + end; + finally + application.unlock; + end; + end; + +var + int1: integer; + bo1: boolean; + page1: tcustomreportpage; + stream1: ttextstream; + str1: string; + restarted: boolean; + +begin + fstate:= [rs_running]; + result:= 0; + fdefaultprintorientation:= pao_portrait; + if fprinter <> nil then begin + fdefaultprintorientation:= fprinter.canvas.printorientation; + end; + fppmmbefore:= fcanvas.ppmm; + fcanvas.ppmm:= fppmm; + if not (reo_prepass in foptions) then begin + include(fstate,rs_endpass); + end; + application.lock; + try + twindow1(window).setasynccanvas(fcanvas); + finally + application.unlock; + end; + for int1:= 0 to high(freppages) do begin + freppages[int1].adddatasets(fdatasets); + end; + setlength(recnos,length(fdatasets)); + for int1:= 0 to high(fdatasets) do begin + with fdatasets[int1] do begin + if not (reo_nodisablecontrols in foptions) then begin + disablecontrols; + end; + recnos[int1]:= recno; + end; + end; + try + repeat //until terminated1 + fpagenum:= 0; + factivepage:= 0; + renderbegin:= false; + fakevisible(self,true); + try + if fprinter <> nil then begin + str1:= ''; + if canevent(tmethod(fonpreamble)) then begin + application.lock; + try + fonpreamble(self,str1); + finally + application.unlock; + end; + end; + if rs_endpass in fstate then begin + if fprinter is tstreamprinter then begin + with tstreamprinter(fprinter) do begin + if fstreamset then begin + stream1:= fstream; + fstream:= nil; + beginprint(stream1,str1); + end + else begin + beginprint(fcommand,str1); + end; + end; + end + else begin + with fprinter do begin + beginprint(false); + end; + end; + end + else begin + if fprinter is tstreamprinter then begin + with tstreamprinter(fprinter) do begin + beginprint(nil,str1); + end; + end + else begin + fprinter.beginprint(true); + end; + end; + end; + if canevent(tmethod(fonreportstart)) then begin + application.lock; + try + fonreportstart(self); + finally + application.unlock; + end; + end; + except + dofinish(true); + raise; + end; + restarted:= false; + repeat //until not restarted + try + if canevent(tmethod(fonbeforerender)) then begin + application.lock; + try + fonbeforerender(self); + finally + application.unlock; + end; + end; + renderbegin:= true; + for int1:= 0 to high(freppages) do begin + freppages[int1].beginrender(false); + end; + if high(freppages) >= factivepage then begin + page1:= freppages[factivepage]; + while true do begin + for int1:= finditem(pointerarty(freppages),page1) to high(freppages) do begin + if freppages[int1].visiblepage then begin + page1:= freppages[int1]; + break; + end; + end; + if page1.visiblepage and not checkterminated then begin + exclude(fstate,rs_activepageset); + factivepage:= finditem(pointerarty(freppages),page1); + bo1:= page1.render(fcanvas); + if rs_finish in fstate then begin + break; + end; + if rs_activepageset in fstate then begin + page1:= freppages[factivepage]; + end + else begin + if not bo1 and (page1.fnextpage <> nil) then begin + page1:= page1.fnextpage; + end + else begin + if bo1 and (page1.fnextpageifempty <> nil) then begin + page1:= page1.fnextpageifempty; + end + else begin + if page1.fnextpageiflast <> nil then begin + page1:= page1.fnextpageiflast; + end + else begin + int1:= finditem(pointerarty(freppages),page1); + if (int1 >= 0) and (int1 < high(freppages)) then begin + page1:= freppages[int1+1]; + end + else begin + page1:= nil; + end; + end; + end; + end; + end; + if finditem(pointerarty(freppages),page1) < 0 then begin + break; + end; + end + else begin + break; + end; + end; + end; + except + dofinish(true); + raise; + end; + restarted:= false; + if canevent(tmethod(fonafterrender)) then begin + application.lock; + try + exclude(fstate,rs_restart); + fonafterrender(self); + restarted:= rs_restart in fstate; + finally + application.unlock; + end; + end; + until not restarted; + dofinish(false); + if (rs_endpass in fstate) then begin + break; + end; + fstate:= [rs_endpass]; + until terminated1; + finally + application.lock; + try + twindow1(window).releaseasynccanvas; + finally + application.unlock; + end; + if {(fthread <> nil) and }(reo_waitdialog in foptions) then begin + application.terminatewait; + end; + end; +end; + +procedure tcustomreport.doexec(const sender: tobject); +begin + exec(nil); +end; + +procedure tcustomreport.docancel(const sender: tobject); +begin + canceled:= true; +end; + +procedure tcustomreport.internalrender(const acanvas: tcanvas; + const aprinter: tcustomprinter; const acommand: msestring; + const astream: ttextstream; const anilstream: boolean; + const onafterrender: reporteventty); +begin + if running then begin + raise exception.create('Already rendering.'); + end; + include(fstate,rs_running); + fnilstream:= anilstream; + fonrenderfinish:= onafterrender; + if assigned(fonrenderfinish) and + (tobject(tmethod(fonrenderfinish).data) is tcomponent) then begin + tcomponent(tmethod(fonrenderfinish).data).freenotification(self); + end; + fprintstarttime:= nowlocal; + fprinter:= aprinter; + fcanvas:= acanvas; + fstream:= astream; + fstreamset:= (astream <> nil) or nilstream; + fcommand:= acommand; + freeandnil(fthread); + fcanceled:= false; + if reo_nothread in foptions then begin + application.beginwait; + try + if reo_waitdialog in foptions then begin + application.waitdialog(nil,getdialogtext,getdialogcaption, + {$ifdef FPC}@{$endif}docancel,{$ifdef FPC}@{$endif}doexec); +// if not canceled then begin +// application.terminatewait; +// end; + end + else begin + exec(nil); + end; + finally + application.endwait; + end; + end + else begin + if reo_waitdialog in foptions then begin + application.resetwaitdialog; + end; + fthread:= tmsethread.create({$ifdef FPC}@{$endif}exec); + if reo_waitdialog in foptions then begin + application.waitdialog(nil,getdialogtext,getdialogcaption); + waitfor; + end; + end; +end; + +procedure tcustomreport.render(const acanvas: tcanvas; + const onafterrender: reporteventty = nil); +begin + internalrender(acanvas,nil,'',nil,false,onafterrender); +end; + +procedure tcustomreport.render(const aprinter: tstreamprinter; + const command: msestring = ''; + const onafterrender: reporteventty = nil); +begin + internalrender(aprinter.canvas,aprinter,command,nil,false,onafterrender); +end; + +procedure tcustomreport.render(const aprinter: tstreamprinter; + const astream: ttextstream; + const onafterrender: reporteventty = nil); +begin + internalrender(aprinter.canvas,aprinter,'',astream,astream = nil,onafterrender); +end; + +procedure tcustomreport.render(const aprinter: tcustomgdiprinter; + const onafterrender: reporteventty = nil); +begin + internalrender(aprinter.canvas,aprinter,'',nil,true,onafterrender); +end; + +procedure tcustomreport.getchildren(proc: tgetchildproc; root: tcomponent); +var + int1: integer; + comp1: tcomponent; +begin + for int1:= 0 to high(freppages) do begin + comp1:= freppages[int1]; + if (comp1.owner = root) and + not (cssubcomponent in comp1.componentstyle) then begin + proc(comp1); + end; + end; + getcompchildren(proc,root); + { + for int1:= 0 to high(freppages) do begin + comp1:= freppages[int1]; + if ((comp1.owner = root) or (csinline in root.componentstate) and + not (csancestor in comp1.componentstate) and + issubcomponent(comp1.owner,root)) then begin + proc(comp1); + end; + end; + if root = self then begin + for int1 := 0 to componentcount - 1 do begin + comp1 := components[int1]; + if not comp1.hasparent then begin + proc(comp1); + end; + end; + end; + } +end; + +function tcustomreport.getreppages(index: integer): tcustomreportpage; +begin + checkarrayindex(freppages,index); + result:= freppages[index]; +end; + +procedure tcustomreport.setreppages(index: integer; + const avalue: tcustomreportpage); +begin + checkarrayindex(freppages,index); + freppages[index].assign(avalue); +end; + +function tcustomreport.reppagecount: integer; +begin + result:= length(freppages); +end; +{ +procedure tcustomreport.internalcreatefont; +var + font1: twidgetfont; +begin + font1:= trepwidgetfont.create; + font1.height:= round(defaultrepfontheight * (fppmm/defaultrepppmm)); +// font1.name:= defaultrepfontname; + ffont:= font1; + inherited; +end; +} +function tcustomreport.getgrid_show: boolean; +begin + result:= frepdesigninfo.showgrid; +end; + +procedure tcustomreport.setgrid_show(const avalue: boolean); +begin + frepdesigninfo.showgrid:= avalue; + designchanged; +end; + +function tcustomreport.getgrid_snap: boolean; +begin + result:= frepdesigninfo.snaptogrid; +end; + +procedure tcustomreport.setgrid_snap(const avalue: boolean); +begin + frepdesigninfo.snaptogrid:= avalue; + designchanged; +end; + +function tcustomreport.getgrid_size: real; +begin + result:= frepdesigninfo.gridsize; +end; + +procedure tcustomreport.setgrid_size(avalue: real); +begin + if avalue < 2/ppmm then begin + avalue:= 2/ppmm; + end; + frepdesigninfo.gridsize:= avalue; + designchanged; +end; + +procedure tcustomreport.writerepdesigninfo(writer: twriter); +begin + writerectty(writer,frepdesigninfo.widgetrect); +end; + +procedure tcustomreport.readrepdesigninfo(reader: treader); +begin + frepdesigninfo.widgetrect:= readrectty(reader); +end; + +procedure tcustomreport.defineproperties(filer: tfiler); +begin + filer.defineproperty('repdesigninfo',{$ifdef FPC}@{$endif}readrepdesigninfo, + {$ifdef FPC}@{$endif}writerepdesigninfo,true); + inherited; +end; + +procedure tcustomreport.nextpage(const acanvas: tcanvas); +begin + tcanvas1(acanvas).nextpage; +{ + if acanvas is tcustomprintercanvas then begin + tcustomprintercanvas(acanvas).nextpage; + end; +} +end; + +function tcustomreport.getcanceled: boolean; +begin + result:= (fthread <> nil) and + (fthread.terminated or ((reo_waitdialog in foptions) and + application.waitcanceled)) or fcanceled; +end; + +procedure tcustomreport.setcanceled(const avalue: boolean); +begin + fcanceled:= fcanceled or avalue; + if avalue and (fthread <> nil) then begin + fthread.terminate; + end; +end; + +function tcustomreport.getrunning: boolean; +begin + result:= rs_running in fstate; + { + result:= (fthread <> nil) and fthread.running; + } +end; + +procedure tcustomreport.waitfor; +var + int1: integer; +begin + if running and (fthread <> nil) then begin + int1:= application.unlockall; + fthread.waitfor; + application.relockall(int1); +// exclude(fstate,rs_running); + end; +end; + +procedure tcustomreport.setactivepage(const avalue: integer); +begin + checkarrayindex(freppages,avalue); + include(fstate,rs_activepageset); + factivepage:= avalue; +end; + +procedure tcustomreport.finish; +begin + include(fstate,rs_finish); +end; + +procedure tcustomreport.doprogress; +begin + if canevent(tmethod(fonprogress)) then begin + application.lock; + try + fonprogress(self); + finally + application.unlock; + end; + end; + if (fthread = nil) and (reo_waitdialog in foptions) and not canceled then begin + application.processmessages; + end; +end; + +procedure tcustomreport.doasyncevent(var atag: integer); +begin + inherited; + if (atag = endrendertag) then begin + try + if canevent(tmethod(fonreportfinished)) then begin + fonreportfinished(self); + end; + if canevent(tmethod(fonrenderfinish)) then begin + fonrenderfinish(self); + end; +// exclude(fstate,rs_running); + finally + if reo_autorelease in foptions then begin + release; + end; + end; + end; +end; + +procedure tcustomreport.notification(acomponent: tcomponent; + operation: toperation); +begin + inherited; + if assigned(fonrenderfinish) and + (tmethod(fonrenderfinish).data = pointer(acomponent)) then begin + fonrenderfinish:= nil; + end; +end; + +procedure tcustomreport.setfont(const avalue: trepfont); +begin + ffont.assign(avalue); +end; + +function tcustomreport.getfont: trepfont; +begin +{$warnings off} + result:= trepfont(ffont); //has no parent font +{$warnings on} +end; + +function tcustomreport.getfontclass: widgetfontclassty; +begin + result:= nil; //static font +end; + +function tcustomreport.getdialogcaption: msestring; +begin + result:= fdialogcaption; + if result = '' then begin + result:= 'Report' + end; +end; + +function tcustomreport.getdialogtext: msestring; +begin + result:= fdialogtext; + if result = '' then begin + result:= 'Rendering...' + end; +end; + +function tcustomreport.prepass: boolean; +begin + result:= not (rs_endpass in fstate); +end; + +procedure tcustomreport.restart; +var + int1: integer; +begin + include(fstate,rs_restart); + for int1:= 0 to high(freppages) do begin + freppages[int1].restart; + end; + activepage:= 0; +end; + +procedure tcustomreport.recordchanged; +begin + freppages[factivepage].recordchanged; +end; + +procedure tcustomreport.dopagebeforerender(const sender: tcustomreportpage; + var empty: boolean); +begin + if canevent(tmethod(fonpagebeforerender)) then begin + application.lock; + try + fonpagebeforerender(sender,empty); + finally + application.unlock; + end; + end; +end; + +procedure tcustomreport.dopageafterpaint(const sender: tcustomreportpage; + const acanvas: tcanvas); +begin + if canevent(tmethod(fonpageafterpaint)) then begin + application.lock; + try + fonpageafterpaint(sender,acanvas); + finally + application.unlock; + end; + end; +end; + +procedure tcustomreport.dopagepaint(const sender: tcustomreportpage; + const acanvas: tcanvas); +begin + if canevent(tmethod(fonpagepaint)) then begin + application.lock; + try + fonpagepaint(sender,acanvas); + finally + application.unlock; + end; + end; +end; + +procedure tcustomreport.setpagewidth(const avalue: real); +begin + if fpagewidth <> avalue then begin + fpagewidth:= avalue; + updatepagesize; + end; +end; + +procedure tcustomreport.setpageheight(const avalue: real); +begin + if fpageheight <> avalue then begin + fpageheight:= avalue; + updatepagesize; + end; +end; + +procedure tcustomreport.updatepagesize; +var + int1: integer; +begin + if not (csloading in componentstate) then begin + for int1:= 0 to high(freppages) do begin + with freppages[int1] do begin + if (fpagewidth = 0) or (fpageheight = 0) then begin + updatepagesize(); + end; + end; + end; + end; +end; + +{ +procedure tcustomreport.notifycontrols; +var + int1: integer; +begin + if running then begin + application.lock; + try + for int1:= 0 to high(fdatasets) do begin + try + fdatasets[int1].enablecontrols; + finally + fdatasets[int1].disablecontrols; + end; + end; + finally + application.unlock; + end; + end; +end; +} + {treport} + +constructor treport.create(aowner: tcomponent); +begin + create(aowner,true); +end; + +constructor treport.create(aowner: tcomponent; load: boolean); +begin + include(fmsecomponentstate,cs_ismodule); + inherited create(aowner); + if load and not (csdesigning in componentstate) and + (cs_ismodule in fmsecomponentstate) then begin + loadmsemodule(self,treport); + end; + + if not (acs_dooncreatecalled in factstate) then begin + dooncreate; + end; + if not load then begin + doafterload; + end; +end; + +destructor treport.destroy; +var + bo1: boolean; +begin + bo1:= csdesigning in componentstate; + inherited; //csdesigningflag is removed + if not bo1 and candestroyevent(tmethod(fondestroyed)) then begin + fondestroyed(self); + end; +end; + +procedure treport.setstatfile(const avalue: tstatfile); +begin + setlinkedvar(avalue,tmsecomponent(fstatfile)); +end; + +procedure treport.beforedestruction; +begin + if (fstatfile <> nil) and (reo_autowritestat in foptions) and + not (csdesigning in componentstate) then begin + fstatfile.writestat; + end; + inherited; + if candestroyevent(tmethod(fondestroy)) then begin + fondestroy(self); + end; +end; + +procedure treport.afterconstruction; +begin + inherited; + if assigned(foncreated) then begin + foncreated(self); + end; +end; + +procedure treport.doafterload; +begin + inherited; + autoreadstat; + if canevent(tmethod(fonloaded)) then begin + fonloaded(self); + end; +end; + +procedure treport.dooncreate; +begin + if not (cs_inheritedloading in msecomponentstate) then begin + include(factstate,acs_dooncreatecalled); + if assigned(foncreate) then begin //csloading possibly set + foncreate(self); + end; + end; +end; + +class function treport.getmoduleclassname: string; +begin + result:= 'treport'; +end; + +class function treport.hasresource: boolean; +begin + result:= self <> treport; +end; + +procedure treport.readstate(reader: treader); +begin + inherited; + if not (acs_dooncreatecalled in factstate) then begin + dooncreate; + end; +end; + +procedure treport.reload; +begin + name:= ''; + reloadmsecomponent(self); +end; + +procedure treport.autoreadstat; +begin + if (fstatfile <> nil) and not (csdesigning in componentstate) and + (foptions*[reo_autoreadstat,reo_delayedreadstat] = + [reo_autoreadstat]) then begin + fstatfile.readstat; + end; +end; + +{ treppageform } + +constructor treppageform.create(aowner: tcomponent); +begin + create(aowner,true); +end; + +constructor treppageform.create(aowner: tcomponent; load: boolean); +begin + initrepdesigninfo(frepdesigninfo); + include(fmsecomponentstate,cs_ismodule); + inherited create(aowner); + color:= cl_transparent; + createfont(); + if load and not (csdesigning in componentstate) and + (cs_ismodule in fmsecomponentstate) then begin + loadmsemodule(self,treport); + end; +end; + +class function treppageform.getmoduleclassname(): string; +begin + result:= 'treppageform'; +end; + +class function treppageform.hasresource(): boolean; +begin + result:= self <> treppageform; +end; + +function treppageform.getgrid_show: boolean; +begin + result:= frepdesigninfo.showgrid; +end; + +procedure treppageform.setgrid_show(const avalue: boolean); +begin + frepdesigninfo.showgrid:= avalue; + designchanged; +end; + +function treppageform.getgrid_snap: boolean; +begin + result:= frepdesigninfo.snaptogrid; +end; + +procedure treppageform.setgrid_snap(const avalue: boolean); +begin + frepdesigninfo.snaptogrid:= avalue; + designchanged; +end; + +function treppageform.getgrid_size: real; +begin + result:= frepdesigninfo.gridsize; +end; + +procedure treppageform.setgrid_size(avalue: real); +begin + if avalue < 2/ppmm then begin + avalue:= 2/ppmm; + end; + frepdesigninfo.gridsize:= avalue; + designchanged; +end; + +procedure treppageform.writerepdesigninfo(writer: twriter); +begin + writerectty(writer,frepdesigninfo.widgetrect); +end; + +procedure treppageform.readrepdesigninfo(reader: treader); +begin + frepdesigninfo.widgetrect:= readrectty(reader); +end; + +procedure treppageform.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('repdesigninfo',@readrepdesigninfo, + @writerepdesigninfo,true); +end; + +{ tcustomrepvaluedisp } + +constructor tcustomrepvaluedisp.create(aowner: tcomponent); +begin + ftextflags:= defaultrepvaluedisptextflags; + foptionsscale:= defaultrepvaluedispoptionsscale; + inherited; + foptions:= defaultrepvaluedispoptions; + foptionsscale:= defaultrepvaluedispoptionsscale; + fanchors:= [an_left,an_top]; +end; + +procedure tcustomrepvaluedisp.dopaintforeground(const acanvas: tcanvas); +begin + inherited; + drawtext(acanvas,getdisptext,textarea,ftextflags,font); +end; + +procedure tcustomrepvaluedisp.dogettext(var atext: msestring); +begin + if canevent(tmethod(fongettext)) then begin + fongettext(self,atext); + end; +end; + +function tcustomrepvaluedisp.getdisptext: msestring; +begin + result:= msestring(name); + dogettext(result); +end; + +procedure tcustomrepvaluedisp.setformat(const avalue: msestring); +begin + if fformat <> avalue then begin + fformat:= avalue; + minclientsizechanged; + end; +// invalidate; +end; + +procedure tcustomrepvaluedisp.settextflags(const avalue: textflagsty); +begin + if ftextflags <> avalue then begin + ftextflags:= avalue; + minclientsizechanged; + end; +end; + +function tcustomrepvaluedisp.calcminscrollsize: sizety; +var + size1: sizety; +begin + result:= inherited calcminscrollsize; + size1:= textrect(getcanvas,getdisptext,innerclientrect,ftextflags,font).size; + if fframe <> nil then begin + with fframe do begin + size1.cx:= size1.cx + framei_left + framei_right; + size1.cy:= size1.cy + framei_top + framei_bottom; + end; + end + else begin + size1.cx:= size1.cx + 2*ftextframe; + size1.cy:= size1.cy + 2*ftextframe; + end; + if size1.cx > result.cx then begin + result.cx:= size1.cx; + end; + if size1.cy > result.cy then begin + result.cy:= size1.cy; + end; +end; + +procedure tcustomrepvaluedisp.render(const acanvas: tcanvas; + var empty: boolean); +begin + inherited; +// empty:= true; +end; + +{ trepvaluedisp } + +procedure trepvaluedisp.setvalue(const avalue: msestring); +begin +// if fvalue <> avalue then begin + fvalue:= avalue; + minclientsizechanged; +// end; +end; + +function trepvaluedisp.getdisptext: msestring; +begin + result:= fvalue; + if (csdesigning in componentstate) and (result = '') then begin + result:= msestring(name); + end; + if rendering then begin + dogettext(result); + end; +end; + +procedure trepvaluedisp.dobeforerender(var empty: boolean); +begin + inherited; + minclientsizechanged; +end; + +{ treppagenumdisp } + +constructor treppagenumdisp.create(aowner: tcomponent); +begin + foffset:= 1; + inherited; +end; + +function treppagenumdisp.getdisptext: msestring; +var + int1,int2: integer; + mstr1: msestring; + squote,dquote: boolean; +begin + if fparentintf <> nil then begin + squote:= false; + dquote:= false; + mstr1:= fformat; + for int1:= 1 to length(fformat) do begin + case fformat[int1] of + '''': begin + if not dquote then begin + squote:= not squote; + end; + end; + '"': begin + if not squote then begin + dquote:= not dquote; + end; + end; + '1': begin + if not (squote or dquote) then begin + + if bo_localvalue in foptions then begin + int2:= fparentintf.getlastpagepagecount; + end + else begin + int2:= fparentintf.getlastreppagecount; + end; + mstr1:= copy(fformat,1,int1-1) + '"' +inttostrmse(int2) +'"' + + copy(fformat,int1+1,bigint); + end; + end; + end; + end; + if bo_localvalue in foptions then begin + int1:= fparentintf.pagepagenum; + end + else begin + int1:= fparentintf.reppagenum + end; + result:= formatfloatmse(int1+foffset,mstr1); + dogettext(result); + end + else begin + result:= inherited getdisptext; + end; +end; + +procedure treppagenumdisp.setoffset(const avalue: integer); +begin + if foffset <> avalue then begin + foffset:= avalue; + minclientsizechanged; + end; +end; + +procedure treppagenumdisp.initpage; +begin + inherited; + minclientsizechanged; +end; + +procedure treppagenumdisp.parentchanged; +begin + inherited; + minclientsizechanged; +end; + +{ trepprintdatedisp } + +function trepprintdatedisp.getdisptext: msestring; +var + ti1: tdatetime; + str1: msestring; +begin + if fparentintf <> nil then begin + if bo_localvalue in foptions then begin + ti1:= fparentintf.pageprintstarttime; + end + else begin + ti1:= fparentintf.repprintstarttime; + end; + if fformat = '' then begin + str1:= 'c'; + end + else begin + str1:= fformat; + end; + result:= mseformatstr.datetimetostring(ti1,str1); +// result:= formatdatetime(str1,ti1); + dogettext(result); + end + else begin + result:= inherited getdisptext; + end; +end; + +procedure trepprintdatedisp.initpage; +begin + inherited; + minclientsizechanged; +end; + +procedure trepprintdatedisp.parentchanged; +begin + inherited; + minclientsizechanged; +end; + +{ trepwidgetfont } + +constructor trepwidgetfont.create; +begin + inherited; + finfo.baseinfo.color:= defaultrepfontcolor; + finfo.baseinfo.name:= defaultrepfontname; +end; + +procedure trepwidgetfont.setname(const avalue: string); +begin + if avalue = '' then begin + inherited setname(defaultrepfontname); + end + else begin + inherited; + end; +end; + +{ trepfont } + +constructor trepfont.create; +begin + inherited; + finfo.baseinfo.color:= defaultrepfontcolor; + finfo.baseinfo.name:= defaultrepfontname; +end; + +procedure trepfont.setname(const avalue: string); +begin + if avalue = '' then begin + inherited setname(defaultrepfontname); + end + else begin + inherited; + end; +end; +(* +{ tcustomreplookupdisp } + +constructor tcustomreplookupdisp.create(aowner: tcomponent); +begin + fkeydatalink:= treplookupdatalink.create(self); + inherited; +end; + +destructor tcustomreplookupdisp.destroy; +begin + fkeydatalink.free; + inherited; +end; + +procedure tcustomreplookupdisp.setlookupbuffer(const avalue: tcustomlookupbuffer); +begin + setlinkedvar(avalue,tmsecomponent(flookupbuffer)); + change; +end; + +function tcustomreplookupdisp.getdatasource(const aindex: integer): tdatasource; +begin + result:= keydatasource; +end; + +procedure tcustomreplookupdisp.getfieldtypes(out propertynames: stringarty; + out fieldtypes: fieldtypesarty); +begin + propertynames:= nil; + setlength(fieldtypes,1); + fieldtypes[0]:= integerfields; +end; + +function tcustomreplookupdisp.getkeydatasource: tdatasource; +begin + result:= fkeydatalink.datasource; +end; + +procedure tcustomreplookupdisp.setkeydatasource(const avalue: tdatasource); +begin + fkeydatalink.datasource:= avalue; +end; + +function tcustomreplookupdisp.getkeydatafield: string; +begin + result:= fkeydatalink.fieldname; +end; + +procedure tcustomreplookupdisp.setkeydatafield(const avalue: string); +begin + fkeydatalink.fieldname:= avalue; +end; + +procedure tcustomreplookupdisp.setlookupkeyfieldno(const avalue: integer); +begin + if avalue <> flookupkeyfieldno then begin + flookupkeyfieldno:= avalue; + change; + end; +end; + +procedure tcustomreplookupdisp.setlookupvaluefieldno(const avalue: integer); +begin + if avalue <> flookupvaluefieldno then begin + flookupvaluefieldno:= avalue; + change; + end; +end; + +procedure tcustomreplookupdisp.change; +begin + minclientsizechanged; +end; + +procedure tcustomreplookupdisp.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (event in [oe_changed,oe_connect]) and (sender = flookupbuffer) then begin + change; + end; +end; + +procedure tcustomreplookupdisp.settextdefault(const avalue: msestring); +begin + ftextdefault:= avalue; + change; +end; + +function tcustomreplookupdisp.getdisptext: msestring; +begin + result:= ''; + if fkeydatalink.fieldactive then begin + keyvalue:= fkeydatalink.field.asinteger; + result:= flookuptext; + end; + if (result = '') and (csdesigning in componentstate) then begin + result:= ftextdefault; + if result = '' then begin + result:= inherited getdisptext; + end; + end + else begin + dogettext(result); + end; +end; + +procedure tcustomreplookupdisp.setkeyvalue(const avalue: integer); +begin + fkeyvalue:= avalue; + if flookupbuffer <> nil then begin + flookuptext:= getlookuptext; + end + else begin + flookuptext:= ''; + end; +end; + +function tcustomreplookupdisp.getlookuptext: msestring; +begin + result:= name; +end; + +{ treplookupdatalink } + +constructor treplookupdatalink.create(const aowner: tcustomreplookupdisp); +begin + fowner:= aowner; + inherited create; +end; + +procedure treplookupdatalink.recordchanged(afield: tfield); +begin + if (afield = nil) or (afield = field) then begin + fowner.change; + end; +end; + +{ trepstringdisplb } + +function trepstringdisplb.getlookuptext: msestring; +begin + result:= flookupbuffer.lookuptext(flookupkeyfieldno,flookupvaluefieldno, + fkeyvalue); +end; + +{ trepintegerdisplb } + +constructor trepintegerdisplb.create(aowner: tcomponent); +begin + fbase:= nb_dec; + fbitcount:= 32; + inherited; +end; + +function trepintegerdisplb.getlookuptext: msestring; +var + int1: integer; +begin + int1:= flookupbuffer.lookupinteger(flookupkeyfieldno,flookupvaluefieldno, + fkeyvalue); + result:= intvaluetostr(int1,fbase,fbitcount) +end; + +procedure trepintegerdisplb.setbase(const avalue: numbasety); +begin + fbase:= avalue; + change; +end; + +procedure trepintegerdisplb.setbitcount(const avalue: integer); +begin + fbitcount:= avalue; + change; +end; + +{ treprealdisplb } + +function treprealdisplb.getlookuptext: msestring; +var + rea1: realty; +begin + rea1:= flookupbuffer.lookupfloat(flookupkeyfieldno,flookupvaluefieldno, + fkeyvalue); + result:= realtytostring(rea1,fformat) +end; + +{ trepdatetimedisplb } + +constructor trepdatetimedisplb.create(aowner: tcomponent); +begin + fkind:= dtk_date; + inherited; +end; + +function trepdatetimedisplb.getlookuptext: msestring; +var + dat1: tdatetime; +begin + dat1:= flookupbuffer.lookupfloat(flookupkeyfieldno,flookupvaluefieldno, + fkeyvalue); + if fkind = dtk_time then begin + result:= mseformatstr.timetostring(dat1,fformat); + end + else begin + result:= mseformatstr.datetimetostring(dat1,fformat); + end; +end; + +procedure trepdatetimedisplb.setkind(const avalue: datetimekindty); +begin + fkind:= avalue; + change; +end; +*) + +{ tcustombandarea } + +procedure tcustombandarea.init; +begin + factiveband:= 0; + inherited; +end; + +procedure tcustombandarea.initband; +begin + if not (bao_nopagerestart in foptions) then begin + factiveband:= 0; + end; + inherited; +end; + +procedure tcustombandarea.initareapage; +begin + facty:= innerclientwidgetpos.y + bounds_y; + fbandnum:= 0; + inherited; +end; + +function tcustombandarea.render(const acanvas: tcanvas): boolean; +var //true if finished + bo1,bo2: boolean; + int1,int2: integer; + isfinished: boolean; + band1: tcustomrecordband; + activebandhaddata: boolean; +begin + result:= true; + if not (bas_inited in fstate) then begin + init; + dofirstarea; + end; + try + if factiveband <= high(fareabands) then begin + updatevisible; + dobeforerender; + isfinished:= true; + activebandhaddata:= false; + while (factiveband <= high(fareabands)) and not areafull do begin + exclude(fstate,bas_bandstarted); + while (factiveband <= high(fareabands)) and + not fareabands[factiveband].visible do begin + inc(factiveband); + end; + if factiveband <= high(fareabands) then begin + exclude(fstate,bas_activebandchanged); + with fareabands[factiveband] do begin + if not (bas_finished in self.fstate) then begin + bo2:= odd(fparentintf.reppagenum); + bo2:= bo2 and (bo_oddpage in foptions) or + not bo2 and (bo_evenpage in foptions); //has data + end + else begin + bo2:= false; + end; + bo1:= ((rbs_showed in fstate) or not(bo_once in foptions)) and + ((rbs_pageshowed in fstate) or not bo2); //empty + render(acanvas,bo1); + activebandhaddata:= activebandhaddata or not bo1; + if bas_activebandchanged in self.fstate then begin + updatevisible; + activebandhaddata:= false; + continue; + end; + if not bo2 then begin + isfinished:= bo1; + end; + bo1:= bo1 or bo2; + result:= result and bo1; + if bo1 then begin //empty + band1:= nil; + if not activebandhaddata and (fnextbandifempty <> nil) then begin + band1:= fnextbandifempty; + end + else begin + if fnextbandiflast <> nil then begin + band1:= fnextbandiflast; + end; + end; + if band1 <> nil then begin + for int1:= 0 to high(fareabands) do begin + if fareabands[int1] = band1 then begin + for int2:= int1 to factiveband do begin + exclude(fareabands[int2].fstate,rbs_showed); + end; + factiveband:= int1-1; + break; + end; + end; + end; + repeat + inc(factiveband); + until (factiveband > high(fareabands)) or fareabands[factiveband].visible; + activebandhaddata:= false; + end + else begin + band1:= nil; + if bas_areafull in self.fstate then begin + if fnextbandiflastofarea <> nil then begin + band1:= fnextbandiflastofarea; + end; + end + else begin + if (fnextband <> nil) and + not (fdatalink.active and fdatalink.dataset.eof) then begin + band1:= fnextband; + end; + end; + if band1 <> nil then begin + for int1:= 0 to high(fareabands) do begin + if fareabands[int1] = band1 then begin + for int2:= int1 to factiveband do begin + exclude(fareabands[int2].fstate,rbs_showed); + end; + factiveband:= int1; + while (factiveband <= high(fareabands)) and + not fareabands[factiveband].visible do begin + inc(factiveband); + end; + activebandhaddata:= false; + break; + end; + end; + end; + end; + end; + end; + end; + if isfinished then begin + include(fstate,bas_finished); + end; + end; + finally + if result then begin + exclude(fstate,bas_inited); + end; + end; + if bas_backgroundrendered in fstate then begin + doafterpaint1(acanvas); + if canevent(tmethod(fonafterrender)) then begin + application.lock; + try + fonafterrender(self); + finally + application.unlock; + end; + end; + end; + if result and canevent(tmethod(fonlastarea)) then begin + application.lock; + try + fonlastarea(self); + finally + application.unlock; + end; + end; +end; + +function tcustombandarea.beginband(const acanvas: tcanvas; + const sender: tcustomrecordband): boolean; + //true if area full +var + bo1: boolean; + pt1: pointty; +begin + result:= bas_areafull in fstate; + if not result then begin + fsaveindex:= acanvas.save; + bo1:= (bas_backgroundrendered in fstate); + if not bo1 then begin + include(fstate,bas_backgroundrendered); + renderbackground(acanvas); + initareapage; + end; + if frecordband <> nil then begin + pt1.x:= sender.bounds_x + forigin.x; + pt1.y:= forigin.y + facty - sender.bounds_y; + end + else begin + pt1:= makepoint(sender.bounds_x+bounds_x,facty); + end; + acanvas.origin:= pt1; + factybefore:= facty; + inc(facty,sender.bandheight); + include(fstate,bas_bandstarted); + result:= bo1 and checkareafull(facty); + //print minimum one band + end; + if result then begin + include(fstate,bas_areafull); + initareapage; + end; +end; + +procedure tcustombandarea.endband(const acanvas: tcanvas; + const sender: tcustomrecordband); +begin + acanvas.restore(fsaveindex); + include(fstate,bas_notfirstband); + exclude(fstate,bas_top); + sender.fstate:= sender.fstate + [rbs_showed,rbs_pageshowed]; + inc(fbandnum); +end; + +function tcustombandarea.getacty: integer; +begin + if (bas_bandstarted in fstate) then begin + result:= factybefore; + end + else begin + result:= facty; + end; + result:= result - (innerclientwidgetpos.y + bounds_y); +end; + +function tcustombandarea.remainingheight: integer; +begin + result:= facty - (bounds_y + bounds_cy); + if fframe <> nil then begin + result:= result - fframe.innerframe.bottom; + end; +end; + +procedure tcustombandarea.restart; +begin + factiveband:= 0; + include(fstate,bas_activebandchanged); + inherited; +end; + +function tcustombandarea.isfirstband: boolean; +begin + result:= (factiveband <= high(fareabands)) and + not (rbs_pageshowed in fareabands[factiveband].fstate); +// result:= not (bas_notfirstband in fstate); +end; + +function tcustombandarea.islastband(const addheight: integer = 0): boolean; +var + int1: integer; +begin + result:= fstate * [bas_lastband{,bas_lastchecking}] <> []; + if not result and (factiveband <= high(fareabands)) then begin + with fareabands[factiveband] do begin + int1:= facty + addheight + lastbandheight; + if not (bas_bandstarted in self.fstate) then begin + int1:= int1 + bounds_cy; + end; + end; + result:= checkareafull(int1); + end; +end; + +{ tcustomtilearea } + +constructor tcustomtilearea.create(aowner: tcomponent); +begin + fcolcount:= 2; + frowcount:= 2; + flivert:= defaulttablineinfo; + flihorz:= defaulttablineinfo; + flileft:= defaulttablineinfo; + flitop:= defaulttablineinfo; + fliright:= defaulttablineinfo; + flibottom:= defaulttablineinfo; + inherited; +end; + +function tcustomtilearea.cellwidthmm: real; +begin + result:= innerclientsize.cx / (getppmm * fcolcount); +end; + +function tcustomtilearea.cellheightmm: real; +begin + result:= innerclientsize.cy / (getppmm * frowcount); +end; + +function tcustomtilearea.cellsize: sizety; +begin + result:= innerclientsize; + result.cx:= (result.cx + fcolcount div 2) div fcolcount; + result.cy:= (result.cy + frowcount div 2) div frowcount; +end; + +function tcustomtilearea.cellrect: rectty; +begin + result.pos:= innerclientpos; + result.size:= cellsize; +end; + +function tcustomtilearea.render(const acanvas: tcanvas): boolean; +var //true if finished + bo1,bo2: boolean; + int1{,int2}: integer; + isfinished: boolean; + col,row: integer; + cellwidthmm1,cellheightmm1: real; +// y: real; +begin + result:= true; + if not (bas_inited in fstate) then begin + init; + dofirstarea; + end; + col:= 0; + row:= 0; + cellwidthmm1:= cellwidthmm; + cellheightmm1:= cellheightmm; + try + updatevisible; + dobeforerender; + isfinished:= true; + repeat + fcellorigin.x:= round(col*cellwidthmm1*getppmm); + fcellorigin.y:= round(row*cellheightmm1*getppmm); + isfinished:= true; + for int1:= 0 to high(fareabands) do begin + with fareabands[int1] do begin + if visible then begin + if not (bas_finished in self.fstate) then begin + bo2:= odd(fparentintf.reppagenum); + bo2:= bo2 and (bo_oddpage in foptions) or + not bo2 and (bo_evenpage in foptions); //has data + end + else begin + bo2:= false; //has no autodata + end; + bo1:= ((rbs_showed in fstate) or not(bo_once in foptions)) and + ((rbs_pageshowed in fstate) or not bo2); //empty + render(acanvas,bo1); + if not bo2 then begin + isfinished:= isfinished and bo1; + end; + bo1:= bo1 or bo2; + result:= result and bo1; + end; + end; + end; + if isfinished then begin + include(fstate,bas_finished); + end; + if tao_vertical in foptions then begin + inc(row); + if row >= frowcount then begin + row:= 0; + inc(col); + if col >= fcolcount then begin + break; + end; + end; + end + else begin + inc(col); + if col >= fcolcount then begin + col:= 0; + inc(row); + if row >= frowcount then begin + break; + end; + end; + end; + until isfinished; + finally + if result then begin + exclude(fstate,bas_inited); + end; + end; + if bas_backgroundrendered in fstate then begin + acanvas.save; + try + if frecordband <> nil then begin + acanvas.move(forigin); + end + else begin + acanvas.move(pos); + end; + drawlines(acanvas); + doafterpaint1(acanvas); + finally + acanvas.restore; + end; + if canevent(tmethod(fonafterrender)) then begin + application.lock; + try + fonafterrender(self); + finally + application.unlock; + end; + end; + end; + if result and canevent(tmethod(fonlastarea)) then begin + application.lock; + try + fonlastarea(self); + finally + application.unlock; + end; + end; +end; + +procedure tcustomtilearea.setcolcount(const avalue: integer); +begin + fcolcount:= avalue; + if avalue <= 0 then begin + fcolcount:= 1; + end; + invalidate; +end; + +procedure tcustomtilearea.setrowcount(const avalue: integer); +begin + frowcount:= avalue; + if avalue <= 0 then begin + frowcount:= 1; + end; + invalidate; +end; + +function tcustomtilearea.beginband(const acanvas: tcanvas; + const sender: tcustomrecordband): boolean; +var + bo1: boolean; + pt1: pointty; +begin + fsaveindex:= acanvas.save; + bo1:= (bas_backgroundrendered in fstate); + if not bo1 then begin + include(fstate,bas_backgroundrendered); + renderbackground(acanvas); + initareapage; + end; + pt1:= sender.pos; + if frecordband <> nil then begin + addpoint1(pt1,forigin); + end + else begin + addpoint1(pt1,pos); + end; + addpoint1(pt1,fcellorigin); + acanvas.origin:= pt1; + include(fstate,bas_bandstarted); + result:= false; +end; + +procedure tcustomtilearea.endband(const acanvas: tcanvas; + const sender: tcustomrecordband); +begin + acanvas.restore(fsaveindex); + include(fstate,bas_notfirstband); + exclude(fstate,bas_top); + sender.fstate:= sender.fstate + [rbs_showed,rbs_pageshowed]; +// inc(fbandnum); +end; + +procedure tcustomtilearea.setlivert_widthmm(const avalue: real); +begin + if avalue <> flivert.widthmm then begin + flivert.widthmm:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlivert_color(const avalue: colorty); +begin + if avalue <> flivert.color then begin + flivert.color:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlivert_colorgap(const avalue: colorty); +begin + if avalue <> flivert.colorgap then begin + flivert.colorgap:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlivert_capstyle(const avalue: capstylety); +begin + if avalue <> flivert.capstyle then begin + flivert.capstyle:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlivert_dashes(const avalue: string); +begin + if avalue <> flivert.dashes then begin + flivert.dashes:= checkdashes(avalue); + invalidate; + end; +end; + +procedure tcustomtilearea.setlihorz_widthmm(const avalue: real); +begin + if avalue <> flihorz.widthmm then begin + flihorz.widthmm:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlihorz_color(const avalue: colorty); +begin + if avalue <> flihorz.color then begin + flihorz.color:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlihorz_colorgap(const avalue: colorty); +begin + if avalue <> flihorz.colorgap then begin + flihorz.colorgap:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlihorz_capstyle(const avalue: capstylety); +begin + if avalue <> flihorz.capstyle then begin + flihorz.capstyle:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlihorz_dashes(const avalue: string); +begin + if avalue <> flihorz.dashes then begin + flihorz.dashes:= checkdashes(avalue); + invalidate; + end; +end; + +procedure tcustomtilearea.setlileft_widthmm(const avalue: real); +begin + if avalue <> flileft.widthmm then begin + flileft.widthmm:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlileft_color(const avalue: colorty); +begin + if avalue <> flileft.color then begin + flileft.color:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlileft_colorgap(const avalue: colorty); +begin + if avalue <> flileft.colorgap then begin + flileft.colorgap:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlileft_capstyle(const avalue: capstylety); +begin + if avalue <> flileft.capstyle then begin + flileft.capstyle:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlileft_dashes(const avalue: string); +begin + if avalue <> flileft.dashes then begin + flileft.dashes:= checkdashes(avalue); + invalidate; + end; +end; + +procedure tcustomtilearea.setlileft_dist(const avalue: integer); +begin + if avalue <> flileft.dist then begin + flileft.dist:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlitop_widthmm(const avalue: real); +begin + if avalue <> flitop.widthmm then begin + flitop.widthmm:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlitop_color(const avalue: colorty); +begin + if avalue <> flitop.color then begin + flitop.color:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlitop_colorgap(const avalue: colorty); +begin + if avalue <> flitop.colorgap then begin + flitop.colorgap:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlitop_capstyle(const avalue: capstylety); +begin + if avalue <> flitop.capstyle then begin + flitop.capstyle:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlitop_dashes(const avalue: string); +begin + if avalue <> flitop.dashes then begin + flitop.dashes:= checkdashes(avalue); + invalidate; + end; +end; + +procedure tcustomtilearea.setlitop_dist(const avalue: integer); +begin + if avalue <> flitop.dist then begin + flitop.dist:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setliright_widthmm(const avalue: real); +begin + if avalue <> fliright.widthmm then begin + fliright.widthmm:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setliright_color(const avalue: colorty); +begin + if avalue <> fliright.color then begin + fliright.color:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setliright_colorgap(const avalue: colorty); +begin + if avalue <> fliright.colorgap then begin + fliright.colorgap:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setliright_capstyle(const avalue: capstylety); +begin + if avalue <> fliright.capstyle then begin + fliright.capstyle:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setliright_dashes(const avalue: string); +begin + if avalue <> fliright.dashes then begin + fliright.dashes:= checkdashes(avalue); + invalidate; + end; +end; + +procedure tcustomtilearea.setliright_dist(const avalue: integer); +begin + if avalue <> fliright.dist then begin + fliright.dist:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlibottom_widthmm(const avalue: real); +begin + if avalue <> flibottom.widthmm then begin + flibottom.widthmm:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlibottom_color(const avalue: colorty); +begin + if avalue <> flibottom.color then begin + flibottom.color:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlibottom_colorgap(const avalue: colorty); +begin + if avalue <> flibottom.colorgap then begin + flibottom.colorgap:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlibottom_capstyle(const avalue: capstylety); +begin + if avalue <> flibottom.capstyle then begin + flibottom.capstyle:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.setlibottom_dashes(const avalue: string); +begin + if avalue <> flibottom.dashes then begin + flibottom.dashes:= checkdashes(avalue); + invalidate; + end; +end; + +procedure tcustomtilearea.setlibottom_dist(const avalue: integer); +begin + if avalue <> flibottom.dist then begin + flibottom.dist:= avalue; + invalidate; + end; +end; + +procedure tcustomtilearea.drawline(const acanvas: tcanvas; const ainfo: tablineinfoty; + const start,stop: pointty); +begin + if ainfo.widthmm > 0 then begin + with acanvas do begin + linewidthmm:= ainfo.widthmm; + colorbackground:= ainfo.colorgap; + capstyle:= ainfo.capstyle; + dashes:= ainfo.dashes; + acanvas.drawline(start,stop,ainfo.color); + end; + end + else begin + if csdesigning in componentstate then begin + with acanvas do begin + linewidth:= 0; + dashes:= #2#3; + capstyle:= cs_butt; + acanvas.drawline(start,stop,cl_black); + end; + end; + end; +end; + +procedure tcustomtilearea.drawlines(const acanvas: tcanvas); +var + rect1: rectty; + pt1,pt2: pointty; + int1: integer; + cellh,cellv: real; +begin + acanvas.save; + acanvas.addcliprect(inflaterect(widgetsizerect,1000)); + rect1:= innerwidgetrect; + with rect1 do begin + cellh:= cellwidthmm * getppmm; + cellv:= cellheightmm * getppmm; + + pt1.y:= y - flitop.dist; + pt2.y:= y + cy + flibottom.dist; + for int1:= 1 to fcolcount - 1 do begin + pt1.x:= x + round(int1 * cellh); + pt2.x:= pt1.x; + drawline(acanvas,flivert,pt1,pt2); + end; + + pt1.x:= x - flileft.dist; + pt2.x:= x + cx + fliright.dist; + for int1:= 1 to frowcount - 1 do begin + pt1.y:= y + round(int1 * cellv); + pt2.y:= pt1.y; + drawline(acanvas,flihorz,pt1,pt2); + end; + + pt1.y:= y - flitop.dist; + pt2.y:= pt1.y; + drawline(acanvas,flitop,pt1,pt2); + pt1.y:= y + cy + flibottom.dist; + pt2.y:= pt1.y; + drawline(acanvas,flibottom,pt1,pt2); + + pt1.y:= y - flitop.dist; + pt2.y:= y + cy + flibottom.dist; + pt1.x:= x - flileft.dist; + pt2.x:= pt1.x; + drawline(acanvas,flileft,pt1,pt2); + pt1.x:= x + cx + fliright.dist; + pt2.x:= pt1.x; + drawline(acanvas,fliright,pt1,pt2); + end; + + acanvas.restore; +end; + +procedure tcustomtilearea.dopaintoverlay(const canvas: tcanvas); +begin + if not rendering then begin + drawlines(canvas); + end; + inherited; +end; + +{ trepwidgetframe } + +constructor trepwidgetframe.create(const aintf: icaptionframe); +begin + inherited; + inflateframe1(fi.innerframe,1); + internalupdatestate; +end; + +end. diff --git a/mseide-msegui/lib/common/report/mserepps.pas b/mseide-msegui/lib/common/report/mserepps.pas new file mode 100644 index 0000000..11725da --- /dev/null +++ b/mseide-msegui/lib/common/report/mserepps.pas @@ -0,0 +1,322 @@ +{ MSEgui Copyright (c) 2016-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mserepps; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,msereport,msestrings,msepostscriptprinter,msegraphics,mclasses, + msegraphutils,msegui,msemenus,mseguiglob; +type + optionpsty = (ops_noheadercomments,ops_noshowpage); + optionspsty = set of optionpsty; + layoutflagty = (la_right,la_bottom,la_xcentered,la_ycentered, + la_stretchx,la_stretchy,la_fit, + la_mirrorx,la_mirrory,la_rotate90,la_rotate180); + layoutflagsty = set of layoutflagty; + +const + defaultoptionsps = [ops_noheadercomments,ops_noshowpage]; + +type +// +//todo: use ps text from datafield +// + treppsdisp = class(tcustomrecordband) + private + fpsfile: filenamety; + foptionsps: optionspsty; + flayout: layoutflagsty; + fscale: flo64; + fshifthorz: flo64; + fshiftvert: flo64; + procedure setlayout(const avalue: layoutflagsty); + protected + procedure render(const acanvas: tcanvas; var empty: boolean) override; + public + constructor create(aowner: tcomponent); override; + published + property anchors default [an_left,an_top]; + property psfile: filenamety read fpsfile write fpsfile; + property optionsps: optionspsty read foptionsps write foptionsps + default defaultoptionsps; + property layout: layoutflagsty read flayout + write setlayout default []; + property scale: flo64 read fscale write fscale; + property shifthorz: flo64 read fshifthorz write fshifthorz; //mm + property shiftvert: flo64 read fshiftvert write fshiftvert; //mm +// property value: msestring read fvalue write setvalue; + property font; +// property tabs; +// property datasource; +// property textflags; + property options; + property optionsshow; + property optionsscale; + property visidatasource; + property visidatafield; + property visigroupfield; + property zebra_color; + property zebra_start; + property zebra_height; + property zebra_step; + property zebra_options; + property onfontheightdelta; + property onlayout; + + property onbeforerender; + property onbeforepaint; + property onpaint; + property onafterpaint; + property onafterrender; +// property ongettext; + end; + +implementation +uses + msestream,msesys,mseformatstr,msebits,mseprinter; + +{ treppsdisp } + +constructor treppsdisp.create(aowner: tcomponent); +begin + foptionsps:= defaultoptionsps; + fscale:= 1; + inherited; + fanchors:= [an_left,an_top]; +end; + +procedure treppsdisp.setlayout(const avalue: layoutflagsty); +begin + flayout:= layoutflagsty( + setsinglebit(card32(avalue),card32(flayout), + [card32([la_xcentered,la_right]),card32([la_ycentered,la_bottom]), + card32([la_fit,la_stretchx]),card32([la_fit,la_stretchy])] + ) + ); +end; + +procedure treppsdisp.render(const acanvas: tcanvas; var empty: boolean); +const + nl = lineend; +var + stream1: ttextstream; + as1: ansistring; + b1,b2,inheader,hasbb: boolean; + ar1: stringarty; + bbll,bbur: pspointty; + destll,destur: pspointty; + pt1,pt2: pspointty; + destpos: pointty; + destsize: sizety; + mat1,mat2: psmatrixty; + f1,f2: flo64; +begin + b1:= rbs_showed in fstate; + inherited; + if visible and (fpsfile <> '') and not (rbs_prepass in fstate) and not b1 and + (acanvas is tpostscriptcanvas) then begin + stream1:= ttextstream.create(fpsfile,fm_read); + try + with tpostscriptcanvas(acanvas) do begin + pscommandbegin(); + inheader:= true; + hasbb:= false; + repeat + b1:= stream1.readstrln(as1); + b2:= (length(as1) >= 2) and (as1[1] = '%') and + ((as1[2] = '%') or (as1[2] = '!')); + if inheader then begin + if b2 then begin + if startsstr(pchar('BoundingBox:'),pchar(pointer(as1))+2) then begin + ar1:= splitstring(as1,' ',true); + if high(ar1) >= 4 then begin + if trystrtodouble(ar1[1],bbll.x,'.') and + trystrtodouble(ar1[2],bbll.y,'.') and + trystrtodouble(ar1[3],bbur.x,'.') and + trystrtodouble(ar1[4],bbur.y,'.') then begin + hasbb:= true; + end; + end; + end; + if (ops_noheadercomments in foptionsps) then begin + continue; //skip headercomment + end; + end + else begin + inheader:= false; + pscommandwrite('save'+nl); + if ops_noshowpage in foptionsps then begin +// pscommandwrite('/showpage_orig /showpage load def'+nl); + pscommandwrite('/showpage {} bind def'+nl); + //disable showpage command + mat1:= psunitymatrix; + if hasbb then begin + destpos:= addpoint(rootpos,innerclientwidgetpos); + destsize:= innerclientsize; + destll:= devpos(mp(destpos.x,destpos.y+destsize.cy)); + destur:= devpos(mp(destpos.x+destsize.cx,destpos.y)); + if la_mirrorx in flayout then begin + mat1[0,0]:= -1.0; + bbll.x:= -bbll.x; + bbur.x:= -bbur.x; + end; + if la_mirrory in flayout then begin + mat1[1,1]:= -1.0; + bbll.y:= -bbll.y; + bbur.y:= -bbur.y; + end; + f1:= 0; + if la_rotate90 in flayout then begin + f1:= f1 + pi/2; + end; + if la_rotate180 in flayout then begin + f1:= f1 + pi; + end; + if f1 <> 0.0 then begin + psrotate(mat1,f1); + mat2:= psunitymatrix; + psrotate(mat2,f1); + bbll:= pstransform(mat2,bbll); + bbur:= pstransform(mat2,bbur); + end; + psnormalizerect(bbll,bbur); + if la_fit in flayout then begin + f1:= bbur.x - bbll.x; + if f1 <> 0 then begin + f1:= (destur.x-destll.x) / f1; + f2:= bbur.y - bbll.y; + if f2 <> 0 then begin + f2:= (destur.y-destll.y) / f2; + if f2 < f1 then begin + f1:= f2; + end; + psscale(mat1,f1); + bbll.x:= bbll.x * f1; + bbll.y:= bbll.y * f1; + bbur.x:= bbur.x * f1; + bbur.y:= bbur.y * f1; + end; + end; + end + else begin + if la_stretchx in flayout then begin + f1:= bbur.x - bbll.x; + if f1 <> 0 then begin + f2:= destur.x - destll.x; + f1:= f2/f1; + psscalex(mat1,f1); + bbll.x:= bbll.x * f1; + bbur.x:= bbur.x * f1; + end; + end; + if la_stretchy in flayout then begin + f1:= bbur.y - bbll.y; + if f1 <> 0 then begin + f2:= destur.y - destll.y; + f1:= f2/f1; + psscaley(mat1,f1); + bbll.y:= bbll.y * f1; + bbur.y:= bbur.y * f1; + end; + end; + end; + if la_right in flayout then begin + pt1.x:= bbur.x; + pt2.x:= destur.x; + end + else begin + if la_xcentered in flayout then begin + pt1.x:= (bbll.x + bbur.x) / 2; + pt2.x:= (destll.x + destur.x) / 2; + end + else begin + pt1.x:= bbll.x; + pt2.x:= destll.x; + end; + end; + if la_bottom in flayout then begin + pt1.y:= bbll.y; + pt2.y:= destll.y; + end + else begin + if la_ycentered in flayout then begin + pt1.y:= (bbll.y + bbur.y) / 2; + pt2.y:= (destll.y + destur.y) / 2; + end + else begin + pt1.y:= bbur.y; + pt2.y:= destur.y; + end; + end; + pstranslate(mat1,psdist(pt1,pt2)); + psscale(mat1,fscale); + if la_right in flayout then begin + pt1.x:= destur.x * (1-fscale); //right + end + else begin + if flayout * [la_stretchx,la_xcentered,la_fit] <> [] then begin + pt1.x:= ((destll.x + destur.x) * (1-fscale)) / 2; + end + else begin //left + pt1.x:= destll.x * (1-fscale); + end; + end; + if flayout * [la_stretchy,la_ycentered, + la_fit,la_bottom] = [] then begin + pt1.y:= destur.y * (1-fscale); //top + end + else begin + if not (la_bottom in flayout) then begin + pt1.y:= ((destll.y + destur.y) * (1-fscale)) / 2; + end + else begin //bottom + pt1.y:= destll.y * (fscale - 1); + end; + end; + pt1.x:= pt1.x + mmtoprintscale* fshifthorz; + pt1.y:= pt1.y + mmtoprintscale* fshiftvert; + end + else begin + psscale(mat1,fscale); + pt1.x:= mmtoprintscale* fshifthorz; + pt1.y:= mmtoprintscale* fshiftvert; + end; + pstranslate(mat1,pt1); + pscommandwrite(psrealtostr(destll.x)+' '+psrealtostr(destll.y) + ' '+ + psrealtostr(destur.x-destll.x)+' '+ + psrealtostr(destur.y-destll.y)+' rectclip'+nl); + pscommandwrite(matrixstring(mat1)+' concat'+nl); + end; + end; + end + else begin + if b2 and (ops_noheadercomments in foptionsps) then begin + continue; + end; + end; + pscommandwrite(as1+c_return+c_linefeed); + until not b1; +// if (ops_noshowpage in foptionsps) and not inheader then begin +// pscommandwrite('/showpage /showpage_orig load def'+nl); +// //restore showpage command +// end; + pscommandwrite('restore'+nl); + pscommandend(); + end; + finally + stream1.destroy(); + end; + end + else begin + empty:= true; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/serialcomm/msecommport.pas b/mseide-msegui/lib/common/serialcomm/msecommport.pas new file mode 100644 index 0000000..845440f --- /dev/null +++ b/mseide-msegui/lib/common/serialcomm/msecommport.pas @@ -0,0 +1,2263 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msecommport; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifndef FPC}{$ifdef linux} {$define UNIX} {$endif}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses {$ifdef mswindows} windows,{$ifndef FPC} mmsystem,{$endif} + {$else} mselibc, + {$endif} + classes,mclasses,msethread,mseguiglob,msecommtimer,mseevent,mseclasses, + msesystypes,msestrings,msestat,msestatfile,msetypes,mseglob; + +type + commstatety = ( + coms_none, //0 + coms_ok, //1 + coms_working, //2 + coms_notopen, //3 + coms_abort, //4 + coms_timeout, //5 + coms_exception, //6 + coms_error, //7 + coms_bufferoverflow, //8 + coms_canceled, //9 + coms_unknown, //10 + coms_command, //11 + coms_parameter, //12 + coms_busy //13 + ); + + errorrecty = record + error: integer; + text: msestring; + end; + perrorrecty = ^errorrecty; + +const + defaulteorchar = c_linefeed; + + cpf_none = 0; + cpf_ok = 1; + cpf_working = 2; + cpf_notopen = 3; + cpf_abort = 4; + cpf_timeout = 5; + cpf_exception = 6; + cpf_error = 7; + cpf_bufferoverflow = 8; + cpf_canceled = 9; + + cpf_unknown = 10; //asciiprot errors + cpf_command = 11; + cpf_parameter = 12; + cpf_busy = 13; + cpf_user = 100; + + errortexte: array[commstatety] of errorrecty = + ( + (error: cpf_none; text: ''), + (error: cpf_ok; text: 'OK'), + (error: cpf_working; text: 'busy'), + (error: cpf_notopen; text: 'not open'), + (error: cpf_abort; text: 'abort'), + (error: cpf_timeout; text: 'timeout'), + (error: cpf_exception; text: 'exception'), + (error: cpf_error; text: 'error'), + (error: cpf_bufferoverflow; text: 'bufferoverflow'), + (error: cpf_canceled; text: 'canceled'), + (error: cpf_unknown; text: 'unknown'), + (error: cpf_command; text: 'command error'), + (error: cpf_parameter; text: 'paramter error'), + (error: cpf_busy; text: 'busy') + ); + + commerrors = ' 1 ok' + c_linefeed + + ' 2 working' + c_linefeed + + ' 3 port not open' + c_linefeed + + ' 4 abort' + c_linefeed + + ' 5 timeout' + c_linefeed + + ' 6 exception' + c_linefeed + + ' 7 error' + c_linefeed + + ' 8 bufferoverflow' + c_linefeed + + ' 9 canceled'; + +type + commnrty = (cnr_invalid=-1, + cnr_1,cnr_2,cnr_3,cnr_4,cnr_5,cnr_6,cnr_7,cnr_8,cnr_9); + commbaudratety = (cbr_50,cbr_75,cbr_110,cbr_134,cbr_150,cbr_200,cbr_300,cbr_600, + cbr_1200,cbr_1800,cbr_2400,cbr_4800,cbr_9600,cbr_19200, + cbr_38400,cbr_57600,cbr_115200); + commdatabitsty = (cdb_5,cdb_6,cdb_7,cdb_8); + commstopbitty = (csb_1,csb_2); + commparityty = (cpa_none,cpa_odd,cpa_even); + +const + {$ifdef UNIX} + + commname: array[commnrty] of string = + ('','ttyS0','ttyS1','ttyS2','ttyS3','ttyS4','ttyS5', + 'ttyS6','ttyS7','ttyS8'{,'ttyS9'}); + { + commname: array[commnrty] of string = + ('ttys0','ttys1','ttys2','ttys3','ttys4','ttys5', + 'ttys6','ttys7','ttys8'); + } + invalidfilehandle = ptruint(-1); + infinitemse = cardinal(-1); + B57600 = $1001; //0010001 + B115200 = $1002; //0010002 + commbaudflags: array[commbaudratety] of integer = + (B50,B75,B110,B134,B150,B200,B300,B600, + B1200,B1800,B2400,B4800,B9600,B19200, + B38400,B57600,B115200); + commdatabitflags: array[commdatabitsty] of integer = (cs5,cs6,cs7,cs8); + {$else} + commname: array[commnrty] of string = ('','COM1','COM2','COM3','COM4','COM5', + 'COM6','COM7','COM8','COM9'); + invalidfilehandle = INVALID_HANDLE_VALUE; + infinitemse = INFINITE; + {$endif} + commbittime: array[commbaudratety] of real = + (1/50,1/75,1/110,1/134,1/150,1/200,1/300,1/600, + 1/1200,1/1800,1/2400,1/4800,1/9600,1/19200, + 1/38400,1/57600,1/115200); + commbaudrates: array[commbaudratety] of integer = ( + 50,75,110,134,150,200,300,600, + 1200,1800,2400,4800,9600,19200, + 38400,57600,115200); + +type + + tcustomrs232 = class(tpersistent) + private + fowner: tmsecomponent; //can be nil + fhandle: ptruint; + fcommnr: commnrty; + frtstimevor: integer; //in us fuer halbduplex + frtstimenach: integer; + fhalfduplex: boolean; + fbaud: commbaudratety; + fstopbit: commstopbitty; + faparity: commparityty; + fbyteus: integer; + foncheckabort: checkeventty; + {$ifdef mswindows} + overlappedrx: toverlapped; + overlappedtx: toverlapped; + timer: tmmtimermse; + commtimeouts: tcommtimeouts; + {$endif} + fdatabits: commdatabitsty; + fcommname: filenamety; + fopenerror: int32; + procedure updatebyteinfo; + procedure Setbaud(const Value: commbaudratety); + procedure Setcommnr(const Value: commnrty); + procedure Setparity(const Value: commparityty); + procedure Setstopbit(const Value: commstopbitty); + function waitfortx(timeout: integer): boolean; //timeout in us + function defaulttimeout(us: longword; anzahl: integer; out timeout: longword): boolean; + // timeout in us 0 -> 2*uebertragungszeit, + // infinitemse -> kein timeout + {$ifdef mswindows} + procedure eotevent(sender: tobject); + function setreadnonblocked(const anonblocked: boolean): boolean; + {$endif} + procedure setdatabits(const avalue: commdatabitsty); + procedure setactive(const avalue: boolean); + procedure setcommname(const avalue: filenamety); + protected + fvmin: char; + fnoclosehandle: boolean; + fonopen: proceventty; + fonclose: proceventty; + function canevent(const aevent: tmethod): boolean; + function piperead(var buf; const acount: integer; out readcount: integer; + const nonblocked: boolean): boolean; + function pipewrite(const buffer; count: longint): longint; + public + constructor create(const aowner: tmsecomponent; //aowner can be nil + const aoncheckabort: checkeventty = nil); + destructor destroy; override; + function open: boolean; + procedure close; + function opened: boolean; + procedure reset; + procedure resetinput; + procedure resetoutput; + procedure setrts(active: boolean); + procedure setdtr(active: boolean); + function writestring(const dat: string; timeout: longword = 0; + waitforeot: boolean = false): boolean; + //timeout in us, wenn = 0 -> warten auf uebertragungsende, bei halbduplex sowiso + function readbuffer(anzahl: integer; out dat; + timeout: longword = 0): integer; + //list daten, true wenn gelungen, timeout in us 0 -> 2*uebertragungszeit + function readstring(anzahl: integer; out dat: string; + timeout: longword = infinitemse): boolean; + //list daten, true wenn gelungen, timeout in us 0 -> 2*uebertragungszeit + function readavailbuffer(const maxcount: integer; out dat): integer; + function readavailstring(const maxcount: integer): string; + + function transmissiontime(const acount: integer): longword; //bringt uebertragungszeit in us + property active: boolean read opened write setactive; + property openerror: int32 read fopenerror; + property handle: ptruint read fhandle; + property commnr: commnrty read Fcommnr write Setcommnr default cnr_1; + property commname: filenamety read fcommname write setcommname; + //overrides commnr + function commpath(): filenamety; + property baud: commbaudratety read Fbaud write Setbaud default cbr_9600; + property databits: commdatabitsty read fdatabits write setdatabits default cdb_8; + property stopbit: commstopbitty read Fstopbit write Setstopbit default csb_1; + property parity: commparityty read Faparity write Setparity default cpa_none; + property halfduplex: boolean read fhalfduplex write fhalfduplex default false; + property oncheckabort: checkeventty read foncheckabort; + property rtstimevor: integer read frtstimevor write frtstimevor; //in us + property rtstimenach: integer read frtstimenach write frtstimenach; //in us + property byteus: integer read fbyteus; + end; + + trs232 = class(tcustomrs232) + end; + + tcommevent = class; + commeventty = procedure(const sender: tcommevent) of object; + tcommthread = class; + + tcommevent = class(tmseevent) + private + fstate: commstatety; + fpersistent: boolean; + fsem: semty; + protected + procedure process(const thread: tcommthread; var ok: boolean); virtual; + procedure processed(const thread: tcommthread; var ok: boolean); virtual; + public + onerror: commeventty; //synchronized with maineventloop + onsuccess: commeventty; //synchronized with maineventloop + timeout: integer; //us + constructor create(persistent: boolean; atimeout: integer = 200000); virtual; + destructor destroy; override; + function state: commstatety; + function waitfordata: boolean; //true if no error + end; + + tcommthread = class(teventthread) + private + protected + fowner: tmsecomponent; + fport: trs232; + fabort: boolean; + fsendretries: integer; + function checkabort(const sender: tobject): boolean; virtual; + function execute(thread: tmsethread): integer; override; + public + constructor create(const aowner: tmsecomponent); //owner can be nil + destructor destroy; override; + function writestring(const dat: string; timeout: integer = 0): boolean; + //timeout in us, wenn = 0 -> warten auf uebertragungsende, bei halbduplex sowiso + function readstring(anzahl: integer; out dat: string; + timeout: integer = 0): boolean; + //list daten, true wenn gelungen, timeout in us, 0 -> doppelte uebertragungszeit + procedure abort; //alle laufende auftraege werden mit timeout abgebrochen + //ruecksetzung bei leerer messagequeue, bei aufruf aus fremdem thread, + // rueckkehr nach ruecksetzung + procedure postevent(event: tcommevent); + procedure reset; virtual; + property port: trs232 read fport; + property sendretries: integer read fsendretries write fsendretries default 0; + end; + + tcommport = class(tmsecomponent,istatfile) + private + Fonconnectedchange: booleanchangedeventty; + flastresult: integer; + Fonportchange: notifyeventty; + fopened: boolean; + factive: boolean; + fstatfile: tstatfile; + fstatvarname: msestring; + fstatpriority: integer; + function getport: commnrty; + procedure setport(const Value: commnrty); + function getopened: boolean; + function getbusy: boolean; + function getbaudrate: commbaudratety; + function getparity: commparityty; + function getstopbit: commstopbitty; + procedure Setbaudrate(const Value: commbaudratety); + procedure Setparity(const Value: commparityty); + procedure Setstopbit(const Value: commstopbitty); + function gethalfduplex: boolean; + procedure sethalfduplex(const Value: boolean); + function getsendretries: integer; + procedure setsendretries(const Value: integer); + function getrtstimenach: integer; + function getrtstimevor: integer; + procedure setrtstimenach(const Value: integer); + procedure setrtstimevor(const Value: integer); + procedure setactive(const Value: boolean); + procedure setstatfile(const Value: tstatfile); +// function waitfordata(const event: tcomevent): comstatety; +// function getpriority: tthreadprioritymse; +// procedure setpriority(const Value: tthreadprioritymse); + function getdatabits: commdatabitsty; + procedure setdatabits(const avalue: commdatabitsty); + function getportname: filenamety; + procedure setportname(const avalue: filenamety); + protected + ftimeout: integer; + fthread: tcommthread; + procedure portchanged; virtual; +// function createdatascanner(slavenr,adresse,anzahl,zykluszeit: integer; +// empfaengerproc: empfaengerprocty): tdatascanner; virtual; +// function waitresult(const data: portdataty): boolean; + function postandwait(const event: tcommevent): boolean; //true if ok + procedure postevent(const event: tcommevent); + procedure loaded; override; + function extracterrortext(error: integer; errors: array of errorrecty; + var text: msestring): boolean; //true if found + //istatfile + procedure dostatread(const reader: tstatreader); virtual; + procedure dostatwrite(const writer: tstatwriter); virtual; + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + procedure doafteropen; virtual; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function openport(raiseexception: boolean = false): boolean; + // true wenn gelungen + procedure closeport; + procedure abort; + //bricht laufende auftraege mit timeout ab, wird automatisch rueckgesetzt + function geterrortext(error: integer): msestring; virtual; + function getlastresulttext: msestring; + property thread: tcommthread read fthread; + property opened: boolean read getopened; + property busy: boolean read getbusy; + property halfduplex: boolean read gethalfduplex write sethalfduplex default false; + + property objectlinker: tobjectlinker read getobjectlinker + {$ifdef msehasimplements}implements istatfile{$endif}; + published + property onportchange: notifyeventty read Fonportchange + write fonportchange; + property onconnectchanged: booleanchangedeventty read Fonconnectedchange + write fonconnectedchange; + property sendretries: integer read getsendretries write setsendretries default 0; + property port: commnrty read getport write setport default cnr_1; + property portname: filenamety read getportname write setportname; + //overrides port + property baudrate: commbaudratety read getbaudrate write Setbaudrate default cbr_9600; + property stopbit: commstopbitty read getstopbit write Setstopbit default csb_1; + property parity: commparityty read getparity write Setparity default cpa_none; + property databits: commdatabitsty read getdatabits write setdatabits default cdb_8; + property rtstimevor: integer read getrtstimevor write setrtstimevor default 0; + property rtstimenach: integer read getrtstimenach write setrtstimenach default 0; + property timeout: integer read ftimeout write ftimeout default 200000; +// property priority: tthreadprioritymse read getpriority write setpriority default tpnormal; + property active: boolean read factive write setactive default false; + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read getstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + end; + + tasciicommevent = class(tcommevent) + protected + procedure process(const thread: tcommthread; var ok: boolean); override; + public + commandstring: string; + resultstring: string; + resultcode: integer; //cpf_... + end; + + asciicommeventclassty = class of tasciicommevent; + + tasciicommthread = class(tcommthread) + private + puffer: string; + zeitstempel: longword; //in us + timeoutstarted: boolean; + feorchar: char; + procedure starttimeout(step: longword); + procedure closetimeout; + protected + function checkabort(const sender: tobject): boolean; override; + public + constructor create(const aowner: tmsecomponent); + procedure reset; override; //setzt commport zurueck + function readln(timeout: integer; out dat: string): integer; + //cpf_io wenn gelungen + function sendstring(const data: string; out antwort: string; + timeout: integer): integer; overload; + function sendstring(const data: string): integer; overload; + //no answer reading + property eorchar: char read feorchar write feorchar default defaulteorchar; + end; + + tasciicommport = class(tcommport) + private + function geteorchar: char; + procedure seteorchar(const avalue: char); + function getthread: tasciicommthread; + protected + function geteventclass: asciicommeventclassty; virtual; + public + constructor create(aowner: tcomponent); override; + function send(const commandstring: string; out answer: string; + atimeout: integer = 0): integer; overload; + function send(const commandstrings: array of string): integer; overload; + //reads no answer + property thread: tasciicommthread read getthread; + published + property halfduplex; + property eorchar: char read geteorchar write seteorchar default defaulteorchar; + end; + + asciiproterrorty = (ape_unknown,ape_command,ape_parameter,ape_busy); + +const + errorchar = '*'; + errorcodes: array[asciiproterrorty] of integer = + (cpf_unknown,cpf_command,cpf_parameter,cpf_busy); + +type + tasciiprotevent = class(tasciicommevent) + private + protected + procedure processed(const thread: tcommthread; var ok: boolean); override; + public + constructor create(persistent: boolean; atimeout: integer = 200000); override; + end; + + tasciiprotport = class(tasciicommport) + protected + function geteventclass: asciicommeventclassty; override; + public + function send(const commandstring: string; out answer: string; + atimeout: integer = 0; aadress: integer = -1): integer; + //-1: no address + end; + +function checkcommport(commnr: commnrty): boolean; //true wenn comport zur verfuegung +function crc16(const data; len: integer): word; +function bintoascii(const bytes: string): string; overload; + // $0..$f->'A'..'P', lsb first +function bintoascii(const bytes: pchar; const len: integer): string; overload; +function asciitobin(const chars: string): string; + +implementation +uses +// {$ifdef UNIX} {kernelioctl,}msesysbindings, {$endif} + sysutils,mseapplication,msesysintf1,msesysintf,msesys,msesysutils, + msepipestream,msefileutils,mseformatstr; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + asciipufferlaenge = 255; + + t_nichtoffen = 'not open'; + databitcounts: array[commdatabitsty] of integer = (5,6,7,8); + + {$ifdef mswindows} +const // fuer tdcb.flags + fBinary = $0001; // binary mode, no EOF check + fParity = $0002; // enable parity checking + fOutxCtsFlow = $0004; // CTS output flow control + fOutxDsrFlow = $0008; // DSR output flow control + fDtrControldisable = $0000; // DTR flow control type + fDtrControlenable = $0010; + fDsrSensitivity = $0040; // DSR sensitivity + TXContinueOnXoff = $0080; // XOFF continues Tx + + fOutX = $0100; // XON/XOFF out flow control + fInX = $0200; // XON/XOFF in flow control + fErrorChar = $0400; // enable error replacement + fNull = $0800; // enable null stripping + fRtsControldisable = $0000; // RTS flow control + fRtsControlenable = $1000; + fRtsControlhandshake = $2000; + fRtsControltoggle = $3000; + fAbortOnError = $4000; // abort reads/writes on error +// DWORD fDummy2:17; // reserved +{ + defaultdcb: tdcb = ( + DCBlength: sizeof(tdcb); + BaudRate: 9600; + Flags: fbinary+fdtrcontrolenable+frtscontrolenable; + wReserved: 0; + XonLim: 256; + XoffLim: 128; + ByteSize: 8; + Parity: NOPARITY; + StopBits: ONESTOPBIT; + XonChar: #17; + XoffChar: #19; + ErrorChar: #0; + EofChar: #0; + EvtChar: #0; + wReserved1: 0; + ); + } + {$endif} + +{/* Table of CRC values for high-order byte */} +const //crcpolynom = $a001; + auchCRCHi: array[0..255] of byte = ( +$00, $C1, $81, $40, $01, $C0, $80, $41, $01, $C0, +$80, $41, $00, $C1, $81, $40, $01, $C0, $80, $41, +$00, $C1, $81, $40, $00, $C1, $81, $40, $01, $C0, +$80, $41, $01, $C0, $80, $41, $00, $C1, $81, $40, +$00, $C1, $81, $40, $01, $C0, $80, $41, $00, $C1, +$81, $40, $01, $C0, $80, $41, $01, $C0, $80, $41, +$00, $C1, $81, $40, $01, $C0, $80, $41, $00, $C1, +$81, $40, $00, $C1, $81, $40, $01, $C0, $80, $41, +$00, $C1, $81, $40, $01, $C0, $80, $41, $01, $C0, +$80, $41, $00, $C1, $81, $40, $00, $C1, $81, $40, +$01, $C0, $80, $41, $01, $C0, $80, $41, $00, $C1, +$81, $40, $01, $C0, $80, $41, $00, $C1, $81, $40, +$00, $C1, $81, $40, $01, $C0, $80, $41, $01, $C0, +$80, $41, $00, $C1, $81, $40, $00, $C1, $81, $40, +$01, $C0, $80, $41, $00, $C1, $81, $40, $01, $C0, +$80, $41, $01, $C0, $80, $41, $00, $C1, $81, $40, +$00, $C1, $81, $40, $01, $C0, $80, $41, $01, $C0, +$80, $41, $00, $C1, $81, $40, $01, $C0, $80, $41, +$00, $C1, $81, $40, $00, $C1, $81, $40, $01, $C0, +$80, $41, $00, $C1, $81, $40, $01, $C0, $80, $41, +$01, $C0, $80, $41, $00, $C1, $81, $40, $01, $C0, +$80, $41, $00, $C1, $81, $40, $00, $C1, $81, $40, +$01, $C0, $80, $41, $01, $C0, $80, $41, $00, $C1, +$81, $40, $00, $C1, $81, $40, $01, $C0, $80, $41, +$00, $C1, $81, $40, $01, $C0, $80, $41, $01, $C0, +$80, $41, $00, $C1, $81, $40 +) ; + auchCRCLo: array[0..255] of byte = ( +$00, $C0, $C1, $01, $C3, $03, $02, $C2, $C6, $06, +$07, $C7, $05, $C5, $C4, $04, $CC, $0C, $0D, $CD, +$0F, $CF, $CE, $0E, $0A, $CA, $CB, $0B, $C9, $09, +$08, $C8, $D8, $18, $19, $D9, $1B, $DB, $DA, $1A, +$1E, $DE, $DF, $1F, $DD, $1D, $1C, $DC, $14, $D4, +$D5, $15, $D7, $17, $16, $D6, $D2, $12, $13, $D3, +$11, $D1, $D0, $10, $F0, $30, $31, $F1, $33, $F3, +$F2, $32, $36, $F6, $F7, $37, $F5, $35, $34, $F4, +$3C, $FC, $FD, $3D, $FF, $3F, $3E, $FE, $FA, $3A, +$3B, $FB, $39, $F9, $F8, $38, $28, $E8, $E9, $29, +$EB, $2B, $2A, $EA, $EE, $2E, $2F, $EF, $2D, $ED, +$EC, $2C, $E4, $24, $25, $E5, $27, $E7, $E6, $26, +$22, $E2, $E3, $23, $E1, $21, $20, $E0, $A0, $60, +$61, $A1, $63, $A3, $A2, $62, $66, $A6, $A7, $67, +$A5, $65, $64, $A4, $6C, $AC, $AD, $6D, $AF, $6F, +$6E, $AE, $AA, $6A, $6B, $AB, $69, $A9, $A8, $68, +$78, $B8, $B9, $79, $BB, $7B, $7A, $BA, $BE, $7E, +$7F, $BF, $7D, $BD, $BC, $7C, $B4, $74, $75, $B5, +$77, $B7, $B6, $76, $72, $B2, $B3, $73, $B1, $71, +$70, $B0, $50, $90, $91, $51, $93, $53, $52, $92, +$96, $56, $57, $97, $55, $95, $94, $54, $9C, $5C, +$5D, $9D, $5F, $9F, $9E, $5E, $5A, $9A, $9B, $5B, +$99, $59, $58, $98, $88, $48, $49, $89, $4B, $8B, +$8A, $4A, $4E, $8E, $8F, $4F, $8D, $4D, $4C, $8C, +$44, $84, $85, $45, $87, $47, $46, $86, $82, $42, +$43, $83, $41, $81, $80, $40 +) ; + +function crc16(const data; len: integer): word; +var + uchcrchi,uchcrclo: byte; + int1: integer; + po: pbyte; + by1: byte; +begin + uchcrchi:= $ff; + uchcrclo:= $ff; + po:= @data; + for int1:= len-1 downto 0 do begin + by1:= po^ xor uchCRCHi; + inc(po); + uchCRCHi:= uchCRCLo xor auchCRCHi[by1]; + uchCRCLo:= auchCRCLo[by1] ; + end; +// result:= (uchCRCHi shl 8) or uchCRCLo; + result:= (uchCRCLo shl 8) or uchCRCHi; //gedreht! +end; + +function gettickus: longword; //laufzeit in us + {$ifdef UNIX} +var + t1: timeval; +begin +// gettimeofday(t1,ptimezone(nil){$ifdef FPC}^{$endif}); + gettimeofday(@t1,ptimezone(nil)); + result:= t1.tv_sec * 1000000 + t1.tv_usec; +end; + {$else} +begin + result:= windows.gettickcount*1000; +end; + {$endif} + +function commnrtocommname(commnr: commnrty): string; +begin + if (commnr < low(commnrty)) or (commnr > high(commnrty)) then begin + raise exception.Create('Invalid comnr: '+inttostr(integer(commnr))+'.'); + end; + result:= commname[commnr]; +end; + +function checkcommport(commnr: commnrty): boolean; //true wenn comport zur verfuegung //clx +var + hcomm: thandle; +{$ifndef mswindows} + info: termios; +{$endif} +begin + {$ifdef mswindows} + hcomm:= createfile(pchar(commname[commnr]), GENERIC_READ or GENERIC_WRITE, 0, nil, + OPEN_EXISTING,0,0); + if hcomm = invalidfilehandle then begin + result:= false; + end + else begin + result:= true; + closehandle(hcomm); + end; + {$else} + hcomm:= mselibc.open(PChar('/dev/'+commname[commnr]), o_rdwr or o_nonblock + {,FileAccessRights}); + if hcomm = thandle(invalidfilehandle) then begin + result:= false; + end + else begin + result:= msetcgetattr(hcomm,info) = 0; + __close(hcomm); + end; + {$endif} +end; + +function getbyte(char: pchar): byte; +begin + result:= ord(char^)-ord('A') + ((ord((char+1)^)-ord('A')) shl 4); +end; + +function getword(char: pchar): word; +begin + result:= getbyte(char) + (getbyte(char+2) shl 8); +end; + +function bintoascii(const bytes: pchar; const len: integer): string; +var + int1: integer; + po: pchar; +begin + if len > 0 then begin + setlength(result,2*len); + po:= @result[1]; + for int1:= 0 to len-1 do begin + po^:= char((pbyteaty(bytes)^[int1] and $0f) + ord('A')); + inc(po); + po^:= char((pbyteaty(bytes)^[int1] shr 4) + ord('A')); + inc(po); + end; + end + else begin + result:= ''; + end; +end; + +function bintoascii(const bytes: string): string; +begin + result:= bintoascii(pointer(bytes),length(bytes)); +end; + +function asciitobin(const chars: string): string; +var + po: pchar; + int1: integer; +begin + setlength(result,(length(chars)+1) div 2); + po:= pointer(chars); + for int1:= 1 to length(result) do begin + result[int1]:= char(getbyte(po)); + inc(po,2); + end; +end; + +{ tcustomrs232 } + +constructor tcustomrs232.create(const aowner: tmsecomponent; const + aoncheckabort: checkeventty = nil); +begin + fcommnr:= cnr_1; + fowner:= aowner; + fhandle:= invalidfilehandle; + fbaud:= cbr_9600; + fdatabits:= cdb_8; + fstopbit:= csb_1; + faparity:= cpa_none; + foncheckabort:= aoncheckabort; + updatebyteinfo; +end; + +destructor tcustomrs232.destroy; +begin + close; + inherited; +end; + +procedure tcustomrs232.updatebyteinfo; +var + openedvorher: boolean; + int1: integer; +begin + openedvorher:= opened; + if openedvorher then begin + close; + end; + int1:= 1 + databitcounts[fdatabits] + 1; //start + N daten + stop + if fstopbit = csb_2 then begin + inc(int1); + end; + if faparity <> cpa_none then begin + inc(int1); + end; + fbyteus:= round(int1*1000000*commbittime[fbaud]); + if openedvorher then begin + open; + end; +end; + +function tcustomrs232.transmissiontime(const acount: integer): longword; +begin + result:= fbyteus * acount; +end; + +procedure tcustomrs232.Setbaud(const Value: commbaudratety); +begin + if fbaud <> value then begin + Fbaud := Value; + updatebyteinfo; + end; +end; + +procedure tcustomrs232.Setcommnr(const Value: commnrty); +begin + if (value < cnr_1) or (value > high(commnrty)) then begin + raise exception.Create('Invalid commnr: '+inttostr(integer(value))+'.'); + end; + if fcommnr <> value then begin + Fcommnr := Value; + updatebyteinfo; + end; +end; + +procedure tcustomrs232.setcommname(const avalue: filenamety); +begin + if fcommname <> avalue then begin + fcommname:= avalue; + updatebyteinfo; + end; +end; + +procedure tcustomrs232.Setparity(const Value: commparityty); +begin + if faparity <> value then begin + Faparity := Value; + updatebyteinfo; + end; +end; + +procedure tcustomrs232.setdatabits(const avalue: commdatabitsty); +begin + if fdatabits <> avalue then begin + fdatabits:= avalue; + updatebyteinfo; + end; +end; + +function tcustomrs232.canevent(const aevent: tmethod): boolean; +begin + result:= (fowner = nil) or (fowner.canevent(aevent)); +end; + +procedure tcustomrs232.Setstopbit(const Value: commstopbitty); +begin + if fstopbit <> value then begin + Fstopbit := Value; + updatebyteinfo; + end; +end; + +procedure tcustomrs232.reset; +begin + if opened then begin + {$ifdef UNIX} + ioctl(fhandle,TCFLSH,[2]); //input und output flushen + {$else} + purgecomm(fhandle,PURGE_TXABORT+PURGE_RXABORT+PURGE_TXCLEAR+PURGE_RXCLEAR); + {$endif} + end; +end; + +procedure tcustomrs232.resetinput; +begin + if opened then begin + {$ifdef UNIX} + ioctl(fhandle,TCFLSH,[0]); //input flushen + {$else} + purgecomm(fhandle,PURGE_RXABORT+PURGE_RXCLEAR); + {$endif} + end; +end; + +procedure tcustomrs232.resetoutput; +begin + if opened then begin + {$ifdef UNIX} + ioctl(fhandle,TCFLSH,[1]); //output flushen + {$else} + purgecomm(fhandle,PURGE_TXABORT+PURGE_TXCLEAR); + {$endif} + end; +end; + +procedure tcustomrs232.close; +begin + if opened then begin + if assigned(fonclose) then begin + fonclose; + end; + {$ifdef UNIX} + if not fnoclosehandle then begin + __close(fhandle); + end; + {$else} + if not fnoclosehandle then begin + closehandle(fhandle); + end; + if overlappedrx.hevent <> 0 then begin + closehandle(overlappedrx.hevent); + overlappedrx.hEvent:= 0; + end; + if overlappedtx.hevent <> 0 then begin + closehandle(overlappedtx.hevent); + overlappedtx.hEvent:= 0; + end; + freeandnil(timer); + {$endif} + end; + fhandle:= invalidfilehandle; + fopenerror:= 0; +end; + +function tcustomrs232.opened: boolean; +begin + result:= fhandle <> invalidfilehandle; +end; + +function tcustomrs232.commpath(): filenamety; +begin + if fcommname <> '' then begin + result:= tosysfilepath(fcommname); + end + else begin + {$ifdef MSWINDOWS} + result:= msestring(msecommport.commname[fcommnr]); + {$else} + result:= msestring('/dev/'+msecommport.commname[fcommnr]); + {$endif} + end; +end; + +function tcustomrs232.open: boolean; +{$ifdef UNIX} +const + iflagoff = BRKINT or INPCK or ISTRIP or IGNCR or INLCR or ICRNL or IUCLC or + IXON or IXANY or IXOFF or IMAXBEL; + iflagon = IGNBRK or IGNPAR; + oflagoff = OPOST or OLCUC or ONLCR or OCRNL or ONOCR or ONLRET or OFILL or + OFDEL or NLDLY or TABDLY or BSDLY or VTDLY or FFDLY; + oflagon = 0; + cflagoff = CBAUD or CSIZE or CSTOPB or PARENB or PARODD or HUPCL or CBAUDEX or + CIBAUD or CRTSCTS ; + cflagon = CREAD or CLOCAL; + lflagoff = ISIG or ICANON or XCASE or ECHO or ECHOE or ECHOK or ECHONL or + NOFLSH or TOSTOP or ECHOCTL or ECHOPRT or ECHOKE or IEXTEN; + lflagon = 0; +var + info: termios{ty}; + {$else} +var + int1: integer; + dcb: tdcb; +// bitzeit: real; +const // fuer tdcb.flags + fBinary = $0001; // binary mode, no EOF check + fParity = $0002; // enable parity checking + fOutxCtsFlow = $0004; // CTS output flow control + fOutxDsrFlow = $0008; // DSR output flow control + fDtrControldisable = $0000; // DTR flow control type + fDtrControlenable = $0010; + fDsrSensitivity = $0040; // DSR sensitivity + TXContinueOnXoff = $0080; // XOFF continues Tx + + fOutX = $0100; // XON/XOFF out flow control + fInX = $0200; // XON/XOFF in flow control + fErrorChar = $0400; // enable error replacement + fNull = $0800; // enable null stripping + fRtsControldisable = $0000; // RTS flow control + fRtsControlenable = $1000; + fRtsControlhandshake = $2000; + fRtsControltoggle = $3000; + fAbortOnError = $4000; // abort reads/writes on error +// DWORD fDummy2:17; // reserved + + defaultdcb: tdcb = ( + DCBlength: sizeof(tdcb); + BaudRate: 9600; + Flags: fbinary{+fdtrcontrolenable+frtscontrolenable}; + wReserved: 0; + XonLim: 256; + XoffLim: 128; + ByteSize: 8; + Parity: NOPARITY; + StopBits: ONESTOPBIT; + XonChar: #17; + XoffChar: #19; + ErrorChar: #0; + EofChar: #0; + EvtChar: #0; + wReserved1: 0; + + ); + +{$endif} + + procedure raiseerror; + begin + close; + syserror(syelasterror,'trs232: Can not set port mode.'); + end; +var + str1: string; + +begin //open + close; + str1:= ansistring(commpath()); + {$ifdef UNIX} + fhandle:= mselibc.open(PChar(str1),o_rdwr or o_nonblock{,FileAccessRights}); + if integer(fhandle) >= 0 then begin + msetcgetattr(fhandle,info); + info.c_iflag:= info.c_iflag and not(iflagoff) or iflagon; + info.c_oflag:= info.c_oflag and not(oflagoff) or oflagon; + info.c_cflag:= info.c_cflag and not(cflagoff) or cflagon; + info.c_lflag:= info.c_lflag and not(lflagoff) or lflagon; + if fstopbit = csb_2 then begin + info.c_cflag:= info.c_cflag or cstopb; + end; + if faparity <> cpa_none then begin + info.c_cflag:= info.c_cflag or parenb; + end; + if faparity = cpa_odd then begin + info.c_cflag:= info.c_cflag or parodd; + end; + info.c_line:= char(N_TTY); + info.c_cc[VMIN]:= fvmin; + info.c_cc[VTIME]:= #0; + + info.c_cflag:= info.c_cflag or commdatabitflags[fdatabits]; + cfsetispeed(info,commbaudflags[fbaud]); + cfsetospeed(info,commbaudflags[fbaud]); + if msetcsetattr(fhandle,TCSANOW,info) <> 0 then begin + raiseerror; + end; + reset; + end; + {$else} + int1:= 0; + fillchar(overlappedrx,sizeof(overlappedrx),0); + fillchar(overlappedtx,sizeof(overlappedtx),0); + overlappedrx.hevent:= createevent(nil,true,false,nil); + overlappedtx.hevent:= createevent(nil,true,false,nil); + + repeat + fhandle:= createfile(pchar(str1),GENERIC_READ or GENERIC_WRITE, 0, + nil,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0); + if (fhandle = invalidfilehandle) and (pos('//./',str1) = 0) then begin + str1:= '//./'+str1; + fhandle:= createfile(pchar(str1),GENERIC_READ or GENERIC_WRITE, 0, + nil,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0); + end; + if fhandle = invalidfilehandle then begin + sleep(100); + end; + inc(int1); + until (fhandle <> invalidfilehandle) or (int1 > 2); + if fhandle <> invalidfilehandle then begin + fillchar(commtimeouts,sizeof(commtimeouts),#0); //keine timeouts +// commtimeouts.readintervaltimeout:= maxdword; //bei read sofortige rueckkehr + setcommtimeouts(fhandle,commtimeouts); + dcb:= defaultdcb; + if fhalfduplex then begin +// dcb.flags:= fbinary+fdtrcontrolenable+frtscontroltoggle; //geht nicht bei win95! +// dcb.flags:= fbinary+fdtrcontrolenable+frtscontroldisable; + timer:= tmmtimermse.create; + end; + dcb.baudrate:= commbaudrates[fbaud]; + dcb.bytesize:= databitcounts[fdatabits]; + case fstopbit of + csb_1: dcb.stopbits:= onestopbit; + csb_2: begin + dcb.stopbits:= twostopbits; + end; + end; + case self.faparity of + cpa_none: dcb.parity:= noparity; + cpa_odd: dcb.parity:= oddparity; + cpa_even: dcb.parity:= evenparity; + end; + if not setcommstate(fhandle,dcb) then begin + raiseerror; + end; + reset; + end; + {$endif} + result:= opened; + if not result then begin + fopenerror:= getlasterror(); + end; + if result and assigned(fonopen) then begin + fonopen; + end; +end; + +procedure tcustomrs232.setrts(active: boolean); +{$ifndef mswindows} +var + flags: integer; +{$endif} +begin + if opened then begin + {$ifdef UNIX} + flags:= TIOCM_RTS; + if active then begin + ioctl(fhandle,TIOCMBIS,@flags); + end + else begin + ioctl(fhandle,TIOCMBIC,@flags); + end; + {$else} + if active then begin + escapecommfunction(fhandle,windows.setrts); + end + else begin + escapecommfunction(fhandle,windows.clrrts); + end; + {$endif} + end; +end; + +procedure tcustomrs232.setdtr(active: boolean); +{$ifndef mswindows} +var + flags: integer; +{$endif} +begin + if opened then begin + {$ifdef UNIX} + flags:= TIOCM_DTR; + if active then begin + ioctl(fhandle,TIOCMBIS,@flags); + end + else begin + ioctl(fhandle,TIOCMBIC,@flags); + end; + {$else} + if active then begin + escapecommfunction(fhandle,windows.setdtr); + end + else begin + escapecommfunction(fhandle,windows.clrdtr); + end; + {$endif} + end; +end; + +function tcustomrs232.waitfortx(timeout: integer): boolean; + //fuer LINUX: um max ein tick verzoegert! + //funktioniert nicht in win2k, vermutlich bug + + {$ifdef mswindows} +var + ca1: longword; + {$endif} +begin + {$ifdef UNIX} + ioctl(fhandle,tcsbrk,[-1]); + result:= true; + {$else} + getcommmask(fhandle,ca1); + if ca1 <> ev_txempty then begin + raise exception.Create('trs232.waitfortx falsche commmask'); + end; + waitcommevent(fhandle,ca1,@overlappedtx); + result:= waitforsingleobject(overlappedtx.hevent,timeout div 1000) = + wait_object_0; + if not result then begin + setcommmask(fhandle,0); //overlapped puffer freigeben + end; + {$endif} +end; + +{$ifdef mswindows} +procedure tcustomrs232.eotevent(sender: tobject); +begin + setrts(false); +end; + +{$endif} +function tcustomrs232.defaulttimeout(us: longword; anzahl: integer; + out timeout: longword): boolean; + // timeout in us 0 -> 2*uebertragungszeit, +begin + timeout:= us; + result:= us <> infinitemse; + if result then begin + if us = 0 then begin + timeout:= transmissiontime(anzahl)*2+30000; + end; + end; +end; + +function tcustomrs232.writestring(const dat: string; timeout: longword = 0; + waitforeot: boolean = false): boolean; + // timeout in us 0 -> 2*uebertragungszeit, + // waitforeot -> warten auf uebertragungsende, bei halbduplex sowiso +var + len: longword; + {$ifdef UNIX} + timed: boolean; + int1: integer; + ca1: longword; + po: ^byte; + time: longword; + {$else} + ca1: longword; +// time: longword; +// bo1: boolean; + {$endif} +begin + result:= false; + if integer(fhandle) >= 0 then begin + len:= length(dat); + if len = 0 then begin + result:= true; + exit; + end; + if fhalfduplex then begin + setrts(true); + {$ifdef mswindows} +// waitus(frtstimevor); + timer.wait(frtstimevor+1000); + timer.start(integer(len)*fbyteus+frtstimenach+1000,{$ifdef FPC}@{$endif}eotevent); + {$else} + waitus(frtstimevor); +// usleep(frtstimevor); + {$endif} + end; + {$ifdef UNIX} + timed:= defaulttimeout(timeout,len,timeout); + time:= timestep(timeout); + po:= @dat[1]; + repeat + int1:= __write(fhandle,po^,len); + inc(po,int1); + dec(len,int1); + until (len = 0) or (timed and msesysutils.timeout(time)); + result:= len = 0; + {$else} + defaulttimeout(timeout,len,timeout); + setcommmask(fhandle,0); + setcommmask(fhandle,ev_txempty); //funktioniert nicht fuer w2k, waitcommevent kehrt sofort zurueck! + if not writefile(fhandle,dat[1],len,ca1,@overlappedtx) then begin + if getlasterror = ERROR_IO_PENDING then begin + result:= waitforsingleobject(overlappedtx.hevent,timeout div 1000+1) = + WAIT_OBJECT_0; + end; + end + else begin + result:= true; + end; + if not result then begin + purgecomm(fhandle,PURGE_TXABORT); //overlapped puffer freigeben + end; + {$endif} + if fhalfduplex then begin + if result then begin + {$ifdef mswindows} + timer.wait; + {$else} +// result:= false; + time:= timestep(transmissiontime(length(dat)*2)); + repeat + ioctl(fhandle,tiocsergetlsr,@ca1); + result:= ca1 and TIOCSER_TEMT <> 0; + until result or msesysutils.timeout(time); + if result and (frtstimenach <> 0) then begin + waitus(frtstimenach); + end; +// usleep(frtstimenach); + {$endif} + end; + setrts(false); + end + else begin + if waitforeot then begin + result:= waitfortx(timeout); + end; + end; + end; + {$ifdef mswindows} + purgecomm(fhandle,PURGE_TXABORT); //overlapped puffer freigeben + {$endif} +end; + +function tcustomrs232.readbuffer(anzahl: integer; out dat; + timeout: longword = 0): integer; + //list daten, bringt anzahl gelesene zeichen timeout in us 0 -> 2*uebertragungszeit +var + po: ^byte; + int1: integer; + {$ifdef UNIX} + time: longword; + pollinfo: array[0..0] of pollfd; + {$else} + time: longword; + bo1: boolean; + {$endif} + timed: boolean; +begin + result:= 0; + po:= @dat; + if opened then begin + if anzahl > 0 then begin + timed:= defaulttimeout(timeout,anzahl,timeout); + time:= timestep(timeout); + {$ifdef mswindows} + bo1:= windows.readfile(fhandle,po^,anzahl,longword(int1),@overlappedrx); + {$else} + if timed then begin + fillchar(pollinfo,sizeof(pollinfo),0); + with pollinfo[0] do begin + fd:= fhandle; + events:= pollin; + end; + end; + {$endif} + while true do begin + {$ifdef UNIX} + if timed then begin + repeat + int1:= poll(@pollinfo,1,timeout div 1000 + 1); + if (int1 < 0) and (sys_getlasterror <> eintr) then begin + break; + end; + until int1 >= 0; + if int1 > 0 then begin + int1:= __read(fhandle,po^,anzahl); + end; + end + else begin + int1:= __read(fhandle,po^,anzahl); + end; + {$else} + if not bo1 then begin + if not getoverlappedresult(fhandle, + overlappedrx,longword(int1),false) then begin + bo1:= windows.getlasterror = error_io_incomplete; + if bo1 then begin + bo1:= waitforsingleobject( + overlappedrx.hevent,timeout div 1000 + 1) = WAIT_OBJECT_0; + if bo1 then begin + bo1:= getoverlappedresult(fhandle, + overlappedrx,longword(int1),false); + end; + end; + if not bo1 then begin + int1:= -1; + purgecomm(fhandle,PURGE_RXABORT); //puffer freigeben + end; + end; + end; + {$endif} + if int1 < 0 then begin + break; + end; + if int1 <> 0 then begin + inc(po,int1); + end; + anzahl:= anzahl - int1; + result:= result + int1; + if (anzahl <= 0) or timed and msesysutils.timeout(time) or + (canevent(tmethod(foncheckabort)) and foncheckabort(self)) then begin + break; +// end +// else begin +// sleepus(fbyteus); + end; + end; + end; + end; +end; + +(* +{$ifdef UNIX} +function tcustomrs232.readbuffer(anzahl: integer; out dat; + timeout: longword = 0): integer; + //list daten, bringt anzahl gelesene zeichen timeout in us 0 -> 2*uebertragungszeit +var + po: ^byte; + int1: integer; + time: timeval; + timed: boolean; +begin + result:= 0; + po:= @dat; + if opened then begin + if anzahl > 0 then begin + timed:= defaulttimeout(timeout,anzahl,timeout); + time:= timestep(timeout); + while true do begin + int1:= __read(fhandle,po^,anzahl); + if int1 < 0 then begin + break; + end; + if int1 <> 0 then begin + inc(po,int1); + end; + anzahl:= anzahl - int1; + result:= result + int1; + if (anzahl <= 0) or timed and zeitabgelaufen(time) or + (canevent(foncheckabort) and foncheckabort(self)) then begin + break; + end + else begin + usleep(fbyteus); + end; + end; + end; + end; +end; + +{$else} + +function tcustomrs232.readbuffer(anzahl: integer; out dat; + timeout: longword = 0): integer; + //liest daten, bringt anzahl gelesene zeichen timeout in us 0 -> 2*uebertragungszeit +var + po: ^byte; + int1: integer; + bo1: boolean; +begin + result:= 0; + po:= @dat; + if opened then begin + if anzahl > 0 then begin + if defaulttimeout(timeout,anzahl,timeout) then begin + timeout:= timeout div 1000; + end; + bo1:= windows.readfile(fhandle,po^,anzahl,longword(result),@overlapped); + if not bo1 and (getlasterror = ERROR_IO_PENDING) then begin + bo1:= waitforsingleobject(overlapped.hevent,timeout) = WAIT_OBJECT_0; + end; + if not bo1 then begin + purgecomm(fhandle,PURGE_RXABORT); //puffer freigeben + end + else begin + if not getoverlappedresult(fhandle,overlapped,longword(result),false) then begin + result:= 0; + end; + end; + end; + end; +end; +{$endif} //not unix +{$ifend} +*) + +function tcustomrs232.readstring(anzahl: integer; out dat: string; + timeout: longword = infinitemse): boolean; + //timeout = 0 -> timeout = 2*uebertragungszeit +var + int1: integer; +begin + result:= false; + if opened then begin + setlength(dat,anzahl); + int1:= readbuffer(anzahl,dat[1],timeout); + setlength(dat,int1); + result:= int1 = anzahl; + end; +end; + +function tcustomrs232.readavailbuffer(const maxcount: integer; out dat): integer; +begin + result:= 0; + if maxcount > 0 then begin + piperead(dat,maxcount,result,true); + end; +end; + +function tcustomrs232.readavailstring(const maxcount: integer): string; +begin + setlength(result,maxcount); + setlength(result,readavailbuffer(maxcount,pointer(result)^)); +end; + +{$ifdef mswindows} +function tcustomrs232.setreadnonblocked(const anonblocked: boolean): boolean; +begin + result:= true; + if anonblocked then begin + if commtimeouts.readintervaltimeout <> maxdword then begin + commtimeouts.readintervaltimeout:= maxdword; + result:= setcommtimeouts(fhandle,commtimeouts); + end; + end + else begin + if commtimeouts.readintervaltimeout <> 0 then begin + commtimeouts.readintervaltimeout:= 0; + result:= setcommtimeouts(fhandle,commtimeouts); + end; + end; + if not result then begin + commtimeouts.readintervaltimeout:= maxdword div 2; //setting invalid + end; +end; +{$endif} + +function tcustomrs232.piperead(var buf; const acount: integer; + out readcount: integer; + const nonblocked: boolean): boolean; +{$ifdef mswindows} +var + w1: dword; + bo1: boolean; +{$endif} +begin +{$ifdef mswindows} + bo1:= true; + w1:= 0; + bo1:= setreadnonblocked(nonblocked); + if bo1 then begin + if nonblocked then begin + bo1:= windows.readfile(fhandle,buf,acount,w1,@overlappedrx); + end + else begin + if acount > 0 then begin + bo1:= windows.readfile(fhandle,buf,1,w1,@overlappedrx); + end + else begin + bo1:= windows.readfile(fhandle,buf,0,w1,@overlappedrx); + end; + if not bo1 and (getlasterror = ERROR_IO_PENDING) then begin + bo1:= getoverlappedresult(fhandle,overlappedrx,w1,true); + end; + if bo1 and (acount > 1) then begin + bo1:= setreadnonblocked(true) and + windows.readfile(fhandle,(pchar(@buf)+1)^,acount-1,w1,@overlappedrx); + if not bo1 and (getlasterror = ERROR_IO_PENDING) then begin + bo1:= getoverlappedresult(fhandle,overlappedrx,w1,true); + end; + if bo1 then begin + w1:= w1 + 1; + end; + end; + end; + end; + if not bo1 then begin + readcount:= 0; + end + else begin + readcount:= w1; + end; + result:= bo1; +{$else} + readcount:= readfilenonblock(handle,buf,acount,nonblocked); + result:= readcount >= 0; +{$endif} +end; + +function tcustomrs232.pipewrite(const buffer; count: longint): longint; +{$ifdef mswindows} +var + w1: dword; + bo1: boolean; +{$endif} +begin +{$ifdef mswindows} + bo1:= windows.writefile(fhandle,buffer,count,w1,@overlappedtx); + if not bo1 and (getlasterror = ERROR_IO_PENDING) then begin + bo1:= getoverlappedresult(fhandle,overlappedtx,w1,true); + end; + if bo1 then begin + result:= w1; + end + else begin + result:= -1; + end; +{$else} + result:= sys_write(fhandle,@buffer,count); +{$endif} +end; + +procedure tcustomrs232.setactive(const avalue: boolean); +begin + if avalue then begin + open; + end + else begin + close; + end; +end; + +{ tcommthread } + +constructor tcommthread.create(const aowner: tmsecomponent); +begin + fowner:= aowner; + fport:= trs232.create(fowner,{$ifdef FPC}@{$endif}checkabort); + inherited create({$ifdef FPC}@{$endif}execute); +end; + +destructor tcommthread.destroy; +begin + inherited; + fport.Free; +end; + +function tcommthread.readstring(anzahl: integer; out dat: string; + timeout: integer): boolean; +begin + result:= fport.readstring(anzahl,dat,timeout); + if not result then begin + fport.reset; //puffer freigeben + end; +end; + +function tcommthread.writestring(const dat: string; + timeout: integer): boolean; +begin + result:= fport.writestring(dat,timeout,timeout=0); +end; + +procedure tcommthread.abort; +begin + if running then begin + fabort := true; + inherited postevent(tmseevent.create(ek_abort)); + if sys_getcurrentthread <> id then begin + while fabort do begin + sys_threadschedyield; + end; + end; + end; +end; + +function tcommthread.checkabort(const sender: tobject): boolean; +begin + result:= application.terminated or terminated or fabort; +end; + +function tcommthread.execute(thread: tmsethread): integer; +var + event: tmseevent; + abort1: boolean; + + procedure freeevent; + begin + if event is tcommevent then begin + with tcommevent(event) do begin + if not fpersistent then begin + free1; + end + else begin + if abort1 then begin + fstate:= coms_abort; + sys_sempost(fsem); + end; + end; + end; + end + else begin + event.Free1; + end; + end; + +var + bo1,bo2: boolean; + +begin + repeat + event:= waitevent; + abort1:= fabort; + if abort1 then begin + freeevent; + while eventcount > 0 do begin + event:= waitevent; + freeevent; + end; + fabort:= false; + end + else begin + if event is tcommevent then begin + with tcommevent(event) do begin + bo2:= not fpersistent; //event can be destroyed later + try + bo1:= false; + process(self,bo1); + finally + if bo2 then begin + event.free1; + end; + end; + end; + end + else begin + event.Free1; + end; + end; + until terminated; + result:= 0; +end; + +procedure tcommthread.reset; +begin + fport.reset; +end; + +procedure tcommthread.postevent(event: tcommevent); +begin + with event do begin + if fstate = coms_working then begin + raise exception.Create('Comevent working!'); + end; + fstate:= coms_working; +// if fpersistent then begin +// semreset{(fsem)}; +// end; + end; + inherited postevent(event); +end; + +{ tcomevent } + +constructor tcommevent.create(persistent: boolean; atimeout: integer = 200000); +begin + fpersistent:= persistent; + timeout:= atimeout; + if fpersistent then begin + sys_semcreate(fsem,0); + end; + inherited create(ek_user); +end; + +destructor tcommevent.destroy; +begin + if fpersistent then begin + sys_semdestroy(fsem); + end; + inherited; +end; + +procedure tcommevent.process(const thread: tcommthread; var ok: boolean); +begin + processed(thread,ok); +end; + +procedure tcommevent.processed(const thread: tcommthread; var ok: boolean); +begin + if ok then begin + fstate:= coms_ok; + if assigned(onsuccess) then begin + application.lock; + try + onsuccess(self); + finally + application.unlock; + end; + end; + end + else begin + fstate:= coms_error; + if assigned(onerror) then begin + application.lock; + try + onerror(self); + finally + application.unlock; + end; + end; + end; + if fpersistent then begin + sys_sempost(fsem); + end; +end; + +function tcommevent.state: commstatety; +begin + result:= fstate; +end; + +function tcommevent.waitfordata: boolean; +begin + if not fpersistent then begin + raise exception.Create('Comevent not persistent!'); + end; + sys_semwait(fsem,0); + result:= fstate = coms_ok; +end; + +{ tasciicommthread } + +constructor tasciicommthread.create(const aowner: tmsecomponent); +begin + feorchar:= defaulteorchar; + inherited; +end; + +function tasciicommthread.checkabort(const sender: tobject): boolean; +begin + result:= inherited checkabort(sender) or + timeoutstarted and later(zeitstempel,gettickus); +end; + +procedure tasciicommthread.closetimeout; +begin + timeoutstarted:= false; +end; + +procedure tasciicommthread.starttimeout(step: longword); +begin + zeitstempel:= gettickus + step; + timeoutstarted:= true; +end; + +function tasciicommthread.readln(timeout: integer; + out dat: string): integer; //todo: optimize +var + po,po1: pchar; + laenge: integer; //longword; + lwo1: longword; + bo1,bo2: boolean; +// ca1: longword; +begin + result:= cpf_timeout; + dat:= ''; + laenge:= length(puffer); + setlength(puffer,asciipufferlaenge); + po:= pchar(puffer); //start + po1:= po; + bo1:= false; + bo2:= false; + starttimeout(timeout); + while not bo1 do begin + po1:= strlscan(po1,feorchar,laenge-(po1-po)); + if po1 <> nil then begin + dat:= dat + copy(puffer,1,po1-po); + move(po1[1],po^,laenge-(po1-po)); + laenge:= laenge-(po1-po)-1; + result:= cpf_ok; + break; + end; + if laenge >= asciipufferlaenge then begin + dat:= dat + puffer; + uniquestring(puffer); + laenge:= 0; + { + laenge:= 0; //platz fuer naechstes telegramm + result:= cpf_bufferoverflow; + break; //puffer voll + } + end; + po1:= po+laenge; + lwo1:= fport.readbuffer(asciipufferlaenge-laenge,po1[0],fport.transmissiontime(2)); + laenge:= laenge + integer(lwo1); + bo1:= bo2; + bo2:= checkabort(nil); + end; + setlength(puffer,laenge); + closetimeout; +end; + +procedure tasciicommthread.reset; +begin + puffer:= ''; + inherited; +end; + +function tasciicommthread.sendstring(const data: string): integer; +begin + if not fport.opened then begin + result:= cpf_notopen; + exit; + end; + result:= cpf_timeout; + if fport.writestring(data+feorchar,0) then begin + result:= cpf_ok; + end; +end; + +function tasciicommthread.sendstring(const data: string; + out antwort: string; timeout: integer): integer; +var + int1: integer; + bo1: boolean; +// str1: string; +begin + if not fport.opened then begin + result:= cpf_notopen; + exit; + end; + int1:= fsendretries; + repeat +// while (result <> cpf_ok) and (int1 >= 0) do begin + reset; // puffer loeschen + result:= sendstring(data); + if result = cpf_ok then begin + result:= cpf_timeout; +// if fport.writestring(data+feorchar,0) then begin + if fport.fhalfduplex then begin +// sleep(20); + bo1:= fport.readstring(length(data)+1,antwort,0); //eigene zeichen + end + else begin + bo1:= true; + end; + if bo1 then begin + result:= readln(timeout,antwort); + end; + end; + dec(int1); + until (result = cpf_ok) or (int1 < 0); +end; + +{ tcommport } + +constructor tcommport.create(aowner: tcomponent); +begin + ftimeout:= 200000; + if fthread = nil then begin + fthread:= tcommthread.create(self); + end; + inherited; +end; + +destructor tcommport.destroy; +begin + freeandnil(fthread); + inherited; +end; + +procedure tcommport.abort; +begin + fthread.abort; +end; + +procedure tcommport.closeport; +begin + fthread.fport.close; + fopened:= false; + portchanged; +end; + +function tcommport.getbusy: boolean; +begin + result:= fthread.eventcount > 0; +end; + +function tcommport.getbaudrate: commbaudratety; +begin + result:= fthread.fport.baud; +end; + +procedure tcommport.Setbaudrate(const Value: commbaudratety); +begin + fthread.fport.baud:= value; +end; + +function tcommport.getdatabits: commdatabitsty; +begin + result:= fthread.fport.databits; +end; + +procedure tcommport.setdatabits(const avalue: commdatabitsty); +begin + fthread.fport.databits:= avalue; +end; + +function tcommport.extracterrortext(error: integer; + errors: array of errorrecty; var text: msestring): boolean; +var + int1: integer; +begin + result:= false; + for int1:= 0 to high(errors) do begin + if errors[int1].error = error then begin + text:= errors[int1].text; + result:= true; + break; + end; + end; +end; + +function tcommport.geterrortext(error: integer): msestring; +begin + if not extracterrortext(error,errortexte,result) then begin + result:= 'Error Nr.: '+inttostrmse(error); + end; +end; + +function tcommport.gethalfduplex: boolean; +begin + result:= fthread.fport.halfduplex; +end; + +procedure tcommport.sethalfduplex(const Value: boolean); +begin + fthread.fport.halfduplex:= value; +end; + +function tcommport.getlastresulttext: msestring; +begin + result:= geterrortext(flastresult); +end; + +function tcommport.getopened: boolean; +begin + result:= (fthread <> nil ) and fopened and (fthread.fport.opened); +end; + +function tcommport.getparity: commparityty; +begin + result:= fthread.fport.parity; +end; + +procedure tcommport.Setparity(const Value: commparityty); +begin + fthread.fport.parity:= value; +end; + +function tcommport.getport: commnrty; +begin + result:= fthread.fport.commnr; +end; + +procedure tcommport.setport(const Value: commnrty); +begin + fthread.fport.commnr:= value; + portchanged; +end; + +function tcommport.getportname: filenamety; +begin + result:= fthread.fport.commname; +end; + +procedure tcommport.setportname(const avalue: filenamety); +begin + fthread.fport.commname:= avalue; + portchanged; +end; + + +function tcommport.getrtstimenach: integer; +begin + result:= fthread.fport.frtstimenach; +end; + +procedure tcommport.setrtstimenach(const Value: integer); +begin + fthread.fport.rtstimenach:= value; +end; + +function tcommport.getrtstimevor: integer; +begin + result:= fthread.fport.frtstimevor; +end; + +procedure tcommport.setrtstimevor(const Value: integer); +begin + fthread.fport.rtstimevor:= value; +end; + +function tcommport.getsendretries: integer; +begin + result:= fthread.sendretries; +end; + +procedure tcommport.setsendretries(const Value: integer); +begin + fthread.sendretries:= value; +end; + +function tcommport.getstopbit: commstopbitty; +begin + result:= fthread.fport.stopbit; +end; + +procedure tcommport.Setstopbit(const Value: commstopbitty); +begin + fthread.fport.stopbit:= value; +end; + +function tcommport.openport(raiseexception: boolean): boolean; +begin + result:= fthread.fport.open; + fopened:= true; + if raiseexception and not result then begin +// raise EFCreateError.Create(commname[fport.fcommnr]+' '+t_nichtoffen+'.'); + raise exception.Create(commname[fthread.fport.fcommnr]+' '+t_nichtoffen+'.'); + end; + doafteropen; + portchanged; +end; + +procedure tcommport.portchanged; +begin + if canevent(tmethod(fonportchange)) then begin + fonportchange(self); + end; +end; + +function tcommport.postandwait(const event: tcommevent): boolean; +begin + fthread.postevent(event); + result:= event.waitfordata; +end; + +procedure tcommport.postevent(const event: tcommevent); +begin + fthread.postevent(event); +end; + +procedure tcommport.setactive(const Value: boolean); +begin + factive := Value; + if componentstate * [csloading,csdesigning] = [] then begin + if value then begin + openport; + end + else begin + closeport; + end; + end; +end; + +procedure tcommport.loaded; +begin + inherited; + setactive(factive); +end; + +procedure tcommport.setstatfile(const Value: tstatfile); +begin + setstatfilevar(istatfile(self),value,fstatfile); +end; + +function tcommport.getstatvarname: msestring; +begin + Result := fstatvarname; +end; + +procedure tcommport.dostatread(const reader: tstatreader); +begin + port:= commnrty(reader.readinteger('port',integer(port), + ord(low(commnrty)),ord(high(commnrty)))); +end; + +procedure tcommport.dostatwrite(const writer: tstatwriter); +begin + writer.writeinteger('port',integer(port)); +end; + +procedure tcommport.statreading; +begin + //dummy +end; + +procedure tcommport.statread; +begin + //dummy +end; + +procedure tcommport.doafteropen; +begin + //dummy; +end; + +function tcommport.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +{ tasciicommport } + +constructor tasciicommport.create(aowner: tcomponent); +begin + fthread:= tasciicommthread.create(self); + inherited; +end; + +function tasciicommport.geteorchar: char; +begin + result:= tasciicommthread(fthread).eorchar; +end; + +procedure tasciicommport.seteorchar(const avalue: char); +begin + tasciicommthread(fthread).eorchar:= avalue; +end; + +function tasciicommport.send(const commandstring: string; + out answer: string; atimeout: integer = 0): integer; +var + ev: tasciicommevent; +begin + if atimeout = 0 then begin + atimeout:= ftimeout; + end; + ev:= geteventclass.create(true,atimeout); + try + ev.commandstring:= commandstring; + tasciicommthread(fthread).postevent(ev); + ev.waitfordata; + if (ev.state = coms_ok) or (ev.state = coms_error) then begin + result:= ev.resultcode; + answer:= ev.resultstring; + end + else begin + result:= integer(ev.state); + answer:= ''; + end; + finally + ev.Free1; + end; +end; + +function tasciicommport.geteventclass: asciicommeventclassty; +begin + result:= tasciicommevent; +end; + +function tasciicommport.send(const commandstrings: array of string): integer; +var + int1: integer; +// str1: string; +begin + result:= cpf_none; + for int1:= 0 to high(commandstrings) do begin + result:= tasciicommthread(fthread).sendstring(commandstrings[int1]); + if result <> cpf_ok then begin + break; + end; + end; +end; + +function tasciicommport.getthread: tasciicommthread; +begin + result:= tasciicommthread(fthread); +end; + +{ tasciicomevent } + +procedure tasciicommevent.process(const thread: tcommthread; var ok: boolean); +begin + if commandstring <> '' then begin + with tasciicommthread(thread) do begin + resultcode:= sendstring(commandstring,resultstring,timeout); + end; + ok:= resultcode = cpf_ok; + end; + inherited; +end; + +{ tasciiprotevent } + +constructor tasciiprotevent.create(persistent: boolean; + atimeout: integer = 200000); +begin + inherited; +end; + +procedure tasciiprotevent.processed(const thread: tcommthread; var ok: boolean); +var + int1: integer; +begin + if ok and (length(resultstring) > 0) then begin + if resultstring[1] = errorchar then begin + ok:= false; + if length(resultstring) = 1 then begin + int1:= ord(ape_command); + end + else begin + int1:= ord(resultstring[2]) - ord('A')+1; + if (int1 < ord(ape_command)) or + (int1 > ord(high(asciiproterrorty))) then begin + int1:= ord(ape_unknown); + end; + end; + resultcode:= errorcodes[asciiproterrorty(int1)]; + end; + end; + inherited; +end; + +{ asciiprotport } + +function tasciiprotport.geteventclass: asciicommeventclassty; +begin + result:= tasciiprotevent; +end; + +function tasciiprotport.send(const commandstring: string; out answer: string; + atimeout: integer = 0; aadress: integer = -1): integer; +begin + if aadress = -1 then begin + result:= inherited send(commandstring,answer,atimeout); + end + else begin + result:= inherited send(char(byte(aadress) or $80) + + commandstring,answer,atimeout); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/serialcomm/msecommtimer.pas b/mseide-msegui/lib/common/serialcomm/msecommtimer.pas new file mode 100644 index 0000000..d75dc43 --- /dev/null +++ b/mseide-msegui/lib/common/serialcomm/msecommtimer.pas @@ -0,0 +1,196 @@ +{ MSEgui Copyright (c) 1999-2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msecommtimer; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifndef FPC}{$ifdef linux} {$define UNIX} {$endif}{$endif} + +interface +uses + {$ifdef mswindows} + windows,{$ifndef FPC}mmsystem,{$endif} + {$endif} + {$ifdef UNIX} + mselibc, + {$endif} + Classes; +{$ifdef mswindows} +type + {$ifdef FPC} + PTimeCaps = ^TTimeCaps; + timecaps_tag = record + wPeriodMin: UINT; { minimum period supported } + wPeriodMax: UINT; { maximum period supported } + end; + TTimeCaps = timecaps_tag; + TIMECAPS = timecaps_tag; + TFNTimeCallBack = procedure(uTimerID, uMessage: UINT; + dwUser, dw1, dw2: DWORD) stdcall; + {$endif} + + tmmtimermse = class //mindeszeit bei nt ca 10ms, + // ungestoerte zeit meistens 10ms zu klein + private + fevent: thandle; + fontimer: tnotifyevent; + ftimecaps: timecaps; + fresolution: integer; + ftimehandle: integer; + protected + fid: int32; //index in instance array + public + constructor create; + destructor destroy; override; + procedure wait(us: longword; aontimer: tnotifyevent = nil); overload; + procedure wait; overload; + procedure start(us: longword; aontimer: tnotifyevent = nil); + procedure abort; + end; + + {$ifdef FPC} +const + TIME_ONESHOT = 0; { program timer for single event } + TIME_PERIODIC = 1; { program for continuous periodic event } + TIME_CALLBACK_FUNCTION = $0000; { callback is function } + TIME_CALLBACK_EVENT_SET = $0010; { callback is event - use SetEvent } + TIME_CALLBACK_EVENT_PULSE = $0020; { callback is event - use PulseEvent } + mmsyst = 'winmm.dll'; +function timeKillEvent(uTimerID: UINT): MMRESULT; stdcall; + external mmsyst name 'timeKillEvent'; +function timeGetDevCaps(lpTimeCaps: PTimeCaps; uSize: UINT): MMRESULT; stdcall; + external mmsyst name 'timeGetDevCaps'; +function timeBeginPeriod(uPeriod: UINT): MMRESULT; stdcall; + external mmsyst name 'timeBeginPeriod'; +function timeEndPeriod(uPeriod: UINT): MMRESULT; stdcall; + external mmsyst name 'timeEndPeriod'; +function timeSetEvent(uDelay, uResolution: UINT; + lpFunction: TFNTimeCallBack; dwUser: DWORD; uFlags: UINT): MMRESULT; stdcall; + external mmsyst name 'timeSetEvent'; + {$endif} +{$endif mswindows} + +implementation +uses + {$ifdef mswindows}msesystypes,msesysintf1,{$endif}sysutils; + +{$ifdef mswindows} +var + timerinstances: array of tmmtimermse; + timerlock: mutexty; + +procedure locktimer(); +begin + sys_mutexlock(timerlock); +end; + +procedure unlocktimer(); +begin + sys_mutexunlock(timerlock); +end; + +procedure mmtimerevent(uTimerID, uMessage: UINT; + dwUser, dw1, dw2: DWORD); stdcall; +var + ti1: tmmtimermse; +begin + locktimer(); + ti1:= timerinstances[dwuser]; + unlocktimer(); + with ti1 do begin + if assigned(fontimer) then begin + fontimer(ti1); + end; + setevent(fevent); + end; +end; + +procedure tmmtimermse.abort; +begin + if ftimehandle <> 0 then begin + timekillevent(ftimehandle); + ftimehandle:= 0; + end; +end; + +constructor tmmtimermse.create; +var + i1: int32; +begin + fevent:= createevent(nil,false,false,nil); + timegetdevcaps(@ftimecaps,sizeof(timecaps)); + fresolution:= ftimecaps.wPeriodMin; + if fresolution < 1 then begin + fresolution:= 1; + end; + timebeginperiod(fresolution); + inherited; + fid:= -1; + locktimer(); + for i1:= 0 to high(timerinstances) do begin + if timerinstances[i1] = nil then begin + fid:= i1; + end; + end; + if fid < 0 then begin + fid:= length(timerinstances); + setlength(timerinstances,fid+1); + end; + timerinstances[fid]:= self; + unlocktimer(); +end; + +destructor tmmtimermse.destroy; +begin + abort; + closehandle(fevent); + timeendperiod(fresolution); + locktimer(); + timerinstances[fid]:= nil; + unlocktimer(); + inherited; +end; + +procedure tmmtimermse.start(us: longword; aontimer: tnotifyevent = nil); +var + ms: longword; +begin + abort; + fontimer:= aontimer; + ms:= us div 1000; + if ms >= ftimecaps.wPeriodMin then begin + ftimehandle:= timesetevent(ms,1,@mmtimerevent,fid,time_oneshot); + if ftimehandle = 0 then begin + raise exception.Create('timererror'); + end; + end + else begin + mmtimerevent(0,0,fid,0,0); + end; +end; + +procedure tmmtimermse.wait; +begin + waitforsingleobject(fevent,infinite{ms+20}); + abort; +end; + +procedure tmmtimermse.wait(us: longword; aontimer: tnotifyevent = nil); +begin + start(us,aontimer); + wait; +end; + +initialization + sys_mutexcreate(timerlock); +finalization + sys_mutexdestroy(timerlock); +{$endif} + +end. diff --git a/mseide-msegui/lib/common/serialcomm/msecommutils.pas b/mseide-msegui/lib/common/serialcomm/msecommutils.pas new file mode 100644 index 0000000..bcf39b4 --- /dev/null +++ b/mseide-msegui/lib/common/serialcomm/msecommutils.pas @@ -0,0 +1,211 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msecommutils; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msedataedits,msecommport,msetypes,msedatalist, + classes,mclasses,mseclasses,msedropdownlist,msestat, + msemenus,mseevent,msestrings,msegui,mseguiglob,mseedit,msegraphics; +type + setcommnreventty = procedure(const sender: tobject; var avalue: commnrty; + var accept: boolean) of object; + getcommnreventty = procedure(const sender: tobject; + var avalue: commnrty) of object; + + tcommselector = class(tcustomselector) + private + fongetactivecommnr: getcommnreventty; + fvaluename: filenamety; + function getvalue: commnrty; + procedure setvalue(const aValue: commnrty); + function readonsetvalue: setcommnreventty; + procedure writeonsetvalue(const aValue: setcommnreventty); + procedure setvaluename(const avalue: filenamety); + protected + procedure getdropdowninfo(var aenums: integerarty; + const names: tdropdowndatacols); override; +// function createdropdowncontroller: tcustomdropdowncontroller; override; + procedure texttovalue(var accept: boolean; const quiet: boolean); override; + function internaldatatotext(const data): msestring; override; + procedure readstatvalue(const reader: tstatreader); override; + procedure writestatvalue(const writer: tstatwriter); override; + public + constructor create(aowner: tcomponent); override; + published + property value: commnrty read getvalue write setvalue default cnr_1; + property valuename: filenamety read fvaluename write setvaluename; +{$ifdef mse_with_ifi} + property ifilink; +{$endif} + property dropdown; + property onsetvalue: setcommnreventty read readonsetvalue write writeonsetvalue; + property onbeforedropdown; + property onafterclosedropdown; + property ongetactivecommnr: getcommnreventty read fongetactivecommnr + write fongetactivecommnr; + end; + +implementation +uses + mseeditglob; + +type + comminforecty = record anzeigetext, dropdowntext: string; commnr: commnrty end; + comminfoty = array[cnr_1..cnr_9] of comminforecty; +const + + {$ifdef mswindows} + comminfo: comminfoty = ((anzeigetext:'COM1'; dropdowntext:'1 COM1'; commnr: cnr_1), + (anzeigetext:'COM2'; dropdowntext:'2 COM2'; commnr: cnr_2), + (anzeigetext:'COM3'; dropdowntext:'3 COM3'; commnr: cnr_3), + (anzeigetext:'COM4'; dropdowntext:'4 COM4'; commnr: cnr_4), + (anzeigetext:'COM5'; dropdowntext:'5 COM5'; commnr: cnr_5), + (anzeigetext:'COM6'; dropdowntext:'6 COM6'; commnr: cnr_6), + (anzeigetext:'COM7'; dropdowntext:'7 COM7'; commnr: cnr_7), + (anzeigetext:'COM8'; dropdowntext:'8 COM8'; commnr: cnr_8), + (anzeigetext:'COM9'; dropdowntext:'9 COM9'; commnr: cnr_9) + ); + {$else} + + comminfo: comminfoty = ((anzeigetext:'ttyS0'; dropdowntext:'0 ttyS0'; commnr: cnr_1), + (anzeigetext:'ttyS1'; dropdowntext:'1 ttyS1'; commnr: cnr_2), + (anzeigetext:'ttyS2'; dropdowntext:'2 ttyS2'; commnr: cnr_3), + (anzeigetext:'ttyS3'; dropdowntext:'3 ttyS3'; commnr: cnr_4), + (anzeigetext:'ttyS4'; dropdowntext:'4 ttyS4'; commnr: cnr_5), + (anzeigetext:'ttyS5'; dropdowntext:'5 ttyS5'; commnr: cnr_6), + (anzeigetext:'ttyS6'; dropdowntext:'6 ttyS6'; commnr: cnr_7), + (anzeigetext:'ttyS7'; dropdowntext:'7 ttyS7'; commnr: cnr_8), + (anzeigetext:'ttyS8'; dropdowntext:'8 ttyS8'; commnr: cnr_9) + ); + { + comminfo: comminfoty = ((anzeigetext:'ttys0'; dropdowntext:'0 ttys0'; commnr: cnr_1), + (anzeigetext:'ttys1'; dropdowntext:'1 ttys1'; commnr: cnr_2), + (anzeigetext:'ttys2'; dropdowntext:'2 ttys2'; commnr: cnr_3), + (anzeigetext:'ttys3'; dropdowntext:'3 ttys3'; commnr: cnr_4), + (anzeigetext:'ttys4'; dropdowntext:'4 ttys4'; commnr: cnr_5), + (anzeigetext:'ttys5'; dropdowntext:'5 ttys5'; commnr: cnr_6), + (anzeigetext:'ttys6'; dropdowntext:'6 ttys6'; commnr: cnr_7), + (anzeigetext:'ttys7'; dropdowntext:'7 ttys7'; commnr: cnr_8), + (anzeigetext:'ttys8'; dropdowntext:'8 ttys8'; commnr: cnr_9) + ); + } + {$endif} + + +{ tcommselector } + +constructor tcommselector.create(aowner: tcomponent); +var + comm: commnrty; +begin + inherited; + dropdown.cols.nostreaming:= true; + inherited value:= integer(cnr_1); + for comm:= low(comminfo) to high(comminfo) do begin + tdropdownlistcontroller(fdropdown).cols[0].add( + msestring(comminfo[comm].anzeigetext)); + end; +end; + +procedure tcommselector.getdropdowninfo(var aenums: integerarty; + const names: tdropdowndatacols); +var + comm: commnrty; + int1: integer; + activecomm: commnrty; +begin + setlength(aenums,integer(high(commnrty))); + names[0].clear; + activecomm:= commnrty(-1); + if canevent(tmethod(fongetactivecommnr)) then begin + fongetactivecommnr(self,activecomm); + end; + int1:= 0; + for comm:= low(comminfo) to high(comminfo) do begin + if (comm = activecomm) or checkcommport(comm) then begin + aenums[int1]:= integer(comm); + names[0].add(msestring(comminfo[comm].dropdowntext)); + inc(int1); + end; + end; + setlength(aenums,int1); +end; + +function tcommselector.getvalue: commnrty; +begin + result:= commnrty(fvalue1); +end; + +function tcommselector.readonsetvalue: setcommnreventty; +begin + result:= setcommnreventty(fonsetvalue1); +end; + +procedure tcommselector.writeonsetvalue(const aValue: setcommnreventty); +begin + fonsetvalue1:= setintegereventty(avalue); +end; + +procedure tcommselector.setvalue(const aValue: commnrty); +begin + inherited setvalue(integer(avalue)); +end; +{ +function tcommselector.createdropdowncontroller: tcustomdropdowncontroller; +begin + result:= tnocolsenumdropdowncontroller.create(idropdownlist(self)); +end; +} +procedure tcommselector.setvaluename(const avalue: filenamety); +begin + if avalue <> fvaluename then begin + fvaluename:= avalue; + changed; + end; +end; + +procedure tcommselector.texttovalue(var accept: boolean; const quiet: boolean); +var + mstr1: msestring; +begin + mstr1:= fvaluename; + if not (des_statreading in fstate) then begin + fvaluename:= text; + end; + inherited; + if not accept then begin + fvaluename:= mstr1; + end; +end; + +function tcommselector.internaldatatotext(const data): msestring; +begin + result:= inherited internaldatatotext(data); + if (@data = nil) and (value = cnr_invalid) then begin + result:= fvaluename; + end; +end; + +procedure tcommselector.readstatvalue(const reader: tstatreader); +begin + inherited; + valuename:= reader.readmsestring(valuevarname+'_name',fvaluename); +end; + +procedure tcommselector.writestatvalue(const writer: tstatwriter); +begin + inherited; + writer.writemsestring(valuevarname+'_name',fvaluename); +end; + +end. diff --git a/mseide-msegui/lib/common/serialcomm/msesercomm.pas b/mseide-msegui/lib/common/serialcomm/msesercomm.pas new file mode 100644 index 0000000..6759563 --- /dev/null +++ b/mseide-msegui/lib/common/serialcomm/msesercomm.pas @@ -0,0 +1,1328 @@ +{ MSEgui Copyright (c) 2011-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msesercomm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + classes,mclasses,msecommport,mseclasses,mseglob,msepipestream,msetypes, + msecryptio,msethread,mseevent,mseapplication,msesystypes,msetimer; + +const + closepipestag = 836915; + closeconnectiontag = closepipestag + 1; + +type + tcustomcommpipes = class; + tcommreader = class; + commpipeseventty = procedure(const sender: tcustomcommpipes) of object; + + icommserver = interface(inullinterface) + end; + icommclient = interface(iobjectlink) + procedure setcommserverintf(const aintf: icommserver); + function getobjectlinker: tobjectlinker; + procedure dorxchange(const areader: tcommreader); + end; + icommclientarty = array of icommclient; + + tcommreader = class(tpipereader) + private + ftimeoutms: integer; + fonthreadterminate: proceventty; + protected + fpipes: tcustomcommpipes; + fcrypto: pcryptoioinfoty; + fonafterconnect: proceventty; + procedure settimeoutms(const avalue: integer); virtual; + function execthread(thread: tmsethread): integer; override; + function internalread(var buf; const acount: integer; out readcount: integer; + const nonblocked: boolean = false): boolean; virtual; + function doread(var buf; const acount: integer; out readcount: integer; + const nonblocked: boolean = false): boolean; override; + procedure dochange; override; + public + constructor create(const apipes: tcustomcommpipes); + property timeoutms: integer read ftimeoutms write settimeoutms; + end; + + + tcommwriter = class(tpipewriter) + private + ftimeoutms: integer; + protected + fowner: tcustomcommpipes; + fcrypto: pcryptoioinfoty; + procedure settimeoutms(const avalue: integer); virtual; + function internalwrite(const buffer; count: longint): longint; virtual; + function dowrite(const buffer; count: longint): longint; override; + public + constructor create(const aowner: tcustomcommpipes); + property timeoutms: integer read ftimeoutms write settimeoutms; + end; + + tsercommwriter = class(tcommwriter) + protected + function internalwrite(const buffer; count: longint): longint; override; + end; + + tsercommreader = class(tcommreader) + protected + function internalread(var buf; const acount: integer; out readcount: integer; + const nonblocked: boolean = false): boolean; override; + end; + + tcustomcommcomp = class; + + commpipesstatety = (cps_open,cps_closing,cps_detached,cps_releasing); + commpipesstatesty = set of commpipesstatety; + + tcustomcommpipes = class(tlinkedpersistent,ievent) + private + foninputavailable: commpipeseventty; + foncommbroken: commpipeseventty; + fowner: tcustomcommcomp; + fonbeforeconnect: commpipeseventty; + fonafterconnect: commpipeseventty; + fonbeforedisconnect: commpipeseventty; + fonafterdisconnect: commpipeseventty; + function gethandle: integer; + procedure sethandle(const avalue: integer); + function getoverloadsleepus: integer; + procedure setoverloadsleepus(const avalue: integer); + procedure setoninputavailable(const avalue: commpipeseventty); + procedure doinputavailable(const sender: tpipereader); + procedure dopipebroken(const sender: tpipereader); + procedure internalclose; + function getoptionsreader: pipereaderoptionsty; + procedure setoptionsreader(const avalue: pipereaderoptionsty); + function getrxtimeoutms: integer; + procedure setrxtimeoutms(const avalue: integer); + function gettxtimeoutms: integer; + procedure settxtimeoutms(const avalue: integer); + procedure dorxchange(const areader: tcommreader); virtual; + protected + fstate: commpipesstatesty; + frx: tcommreader; + ftx: tcommwriter; + fcryptoio: tcryptoio; + fcryptoioinfo: cryptoioinfoty; + procedure createpipes; virtual; abstract; + procedure doafterconnect; virtual; + procedure dothreadterminate; + procedure setcryptoio(const acryptoio: tcryptoio); + procedure receiveevent(const event: tobjectevent); + property oncommbroken: commpipeseventty read foncommbroken + write foncommbroken; + public + constructor create(const aowner: tcustomcommcomp; + const acryptkind: cryptoiokindty); reintroduce; + destructor destroy; override; + procedure close; + procedure release; + { + procedure runhandlerapp(const commandline: filenamety); + //connects to input/output + } + property handle: integer read gethandle write sethandle; + property rx: tcommreader read frx; + property tx: tcommwriter read ftx; + property rxtimeoutms: integer read getrxtimeoutms write setrxtimeoutms; + property txtimeoutms: integer read gettxtimeoutms write settxtimeoutms; + + property overloadsleepus: integer read getoverloadsleepus + write setoverloadsleepus default -1; + //checks application.checkoverload before calling oninputavaliable + //if >= 0 + property optionsreader: pipereaderoptionsty read getoptionsreader + write setoptionsreader default []; + property onbeforeconnect: commpipeseventty read fonbeforeconnect + write fonbeforeconnect; + property onafterconnect: commpipeseventty read fonafterconnect + write fonafterconnect; + property onbeforedisconnect: commpipeseventty read fonbeforedisconnect + write fonbeforedisconnect; + property onafterdisconnect: commpipeseventty read fonafterdisconnect + write fonafterdisconnect; + property oninputavailable: commpipeseventty read foninputavailable + write setoninputavailable; + end; + + tsercommpipes = class(tcustomcommpipes) + protected + procedure createpipes; override; + published + property optionsreader; + property overloadsleepus; + property oninputavailable; + property oncommbroken; + end; + + commcompeventty = procedure(sender: tcustomcommcomp) of object; + + tcustomcommcomp = class(tactcomponent,icommserver) + private + fclients: icommclientarty; + fonbeforeconnect: commcompeventty; + fonafterconnect: commcompeventty; + fonbeforedisconnect: commcompeventty; + fonafterdisconnect: commcompeventty; + procedure setcryptoio(const avalue: tcryptoio); + protected + fhandle: integer; + factive: boolean; + factiveafterload: boolean; + fcryptoio: tcryptoio; + procedure setactive(const avalue: boolean); override; + procedure doactivated; override; + procedure dodeactivated; override; + procedure internalconnect; virtual; abstract; + procedure internaldisconnect; virtual; + procedure closepipes(const sender: tcustomcommpipes); virtual; abstract; + procedure writedata(const adata: string); + function trywritedata(const adata: string): syserrorty; virtual; abstract; + procedure connect; + procedure disconnect; + procedure checkinactive; + procedure doafterconnect(const sender: tcustomcommpipes); + procedure loaded; override; + function gethalfduplex: boolean; virtual; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function calctransmissiontime(const alength: integer): integer; virtual; + //us, 0 if not supported + property active: boolean read factive write setactive default false; + property cryptoio: tcryptoio read fcryptoio write setcryptoio; + + property onbeforeconnect: commcompeventty read fonbeforeconnect + write fonbeforeconnect; + property onafterconnect: commcompeventty read fonafterconnect + write fonafterconnect; + property onbeforedisconnect: commcompeventty read fonbeforedisconnect + write fonbeforedisconnect; + property onafterdisconnect: commcompeventty read fonafterdisconnect + write fonafterdisconnect; + end; + + tasyncserport = class(tcustomrs232) + protected + + public + constructor create(const aowner: tmsecomponent; //aowner can be nil + const aoncheckabort: checkeventty = nil); + published + property commnr; + property commname; + property baud; + property databits; + property stopbit; + property parity; + end; + + sercommoptionty = (sco_halfduplex,sco_nopipe); + sercommoptionsty = set of sercommoptionty; + + tcustomsercommcomp = class(tcustomcommcomp) + private + foptions: sercommoptionsty; + procedure setpipes(const avalue: tsercommpipes); + procedure setport(const avalue: tasyncserport); + procedure setoptions(const avalue: sercommoptionsty); + protected + fpipes: tsercommpipes; + fport: tasyncserport; +// procedure writedata(const adata: string); override; + function trywritedata(const adata: string): syserrorty; override; + procedure internalconnect; override; + procedure internaldisconnect; override; + procedure closepipes(const sender: tcustomcommpipes); override; + procedure doasyncevent(var atag: integer); override; + function gethalfduplex: boolean; override; + protected + procedure doportopen; + procedure doportclose; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function calctransmissiontime(const alength: integer): integer; override; + property pipes: tsercommpipes read fpipes write setpipes; + property port: tasyncserport read fport write setport; + property options: sercommoptionsty read foptions + write setoptions default []; + end; + + tsercommcomp = class(tcustomsercommcomp) + published + property pipes; + property port; + property active; + property activator; + property cryptoio; + property options; + property onbeforeconnect; + property onafterconnect; + property onbeforedisconnect; + property onafterdisconnect; + end; + + commresponseflagty = (crf_error,crf_timeout,crf_eof,crf_trunc,crf_writeerror); + commresponseflagsty = set of commresponseflagty; + tcustomsercommchannel = class; + commresponseeventty = procedure(const sender: tcustomsercommchannel; + var adata: string; var aflags: commresponseflagsty) of object; + sercommchannelstatety = (sccs_pending,sccs_sync,sccs_eor); + sercommchannelstatesty = set of sercommchannelstatety; + + tcustomsercommchannel = class(tmsecomponent,icommclient) + private + fsercomm: tcustomcommcomp; + fserverintf: icommserver; + fonresponse: commresponseeventty; + ftimer: tsimpletimer; + ftimeoutus: integer; + fsem: semty; + feor: string; + procedure setsercomm(const avalue: tcustomcommcomp); + procedure dotimer(const sender: tobject); + protected + fstate: sercommchannelstatesty; + fexpected: integer; + fsent: integer; + fdata: string; + fflags: commresponseflagsty; + function internaltransmit(const adata: string; + const aresponselength: integer; const atimeoutus: integer; + const sync: boolean; const aeor: boolean): syserrorty; + procedure checksercomm; + procedure doresponse; virtual; + //icommclient + procedure setcommserverintf(const aintf: icommserver); + procedure dorxchange(const areader: tcommreader); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure clear; + function transmit(const adata: string; const aresponselength: integer; + const atimeoutus: integer = -1): syserrorty; virtual; overload; + //threadsafe + //async, answer by onresponse + //0 -> timeoutus property, + //-1 -> timeoutus + guessed transmission time, + //-2 unlimited + function transmiteor(const adata: string; const aresponselength: integer = 0; + const atimeoutus: integer = -1): syserrorty; virtual; overload; + //use EOR, async + function transmit(const adata: string; const aresponselength: integer; + out aresult: string; + const atimeoutus: integer = -1): commresponseflagsty; virtual; overload; + //synchronous, threadsafe + function transmiteor(const adata: string; out aresult: string; + const aresponselength: integer = 0; + const atimeoutus: integer = -1): commresponseflagsty; virtual; overload; + //use EOR, synchronous, threadsafe + property sercomm: tcustomcommcomp read fsercomm write setsercomm; + property timeoutus: integer read ftimeoutus write ftimeoutus default 0; + //0 -> unlimited, + property onresponse: commresponseeventty read fonresponse write fonresponse; + property eor: string read feor write feor; //end of record, default $0a + end; + + tsercommchannel = class(tcustomsercommchannel) + published + property sercomm; + property timeoutus; + property eor; + property onresponse; + end; + + setupcommeventty = procedure(const sender: tobject; + const acomm: tcustomsercommcomp) of object; + + tasynsercommchannel = class(tcustomsercommchannel) + private + fonconnect: notifyeventty; + fondisconnect: notifyeventty; + fonsetupcomm: setupcommeventty; + fconnected: boolean; + fconnectafterload: boolean; + function getsercomm: tcustomsercommcomp; + procedure setsercomm(const avalue: tcustomsercommcomp); + procedure setconnected(const avalue: boolean); + protected + procedure loaded; override; + procedure setupcomm(const acomm: tcustomsercommcomp); virtual; + procedure doconnect; virtual; + procedure dodisconnect; virtual; + property onconnect: notifyeventty read fonconnect write fonconnect; + property ondisconnect: notifyeventty read fondisconnect write fondisconnect; + public + procedure connect; virtual; + procedure disconnect; virtual; + published + property sercomm: tcustomsercommcomp read getsercomm write setsercomm; + property onsetupcomm: setupcommeventty read fonsetupcomm write fonsetupcomm; + property timeoutus; + property eor; + property onresponse; + property connected: boolean read fconnected write setconnected + default false; + end; + +procedure setcomcomp(const alink: icommclient; const acommcomp: tcustomcommcomp; + var dest: tcustomcommcomp); +procedure connectcryptoio(const acryptoio: tcryptoio; const tx: tcommwriter; + const rx: tcommreader; + var cryptoioinfo: cryptoioinfoty; + txfd: integer = invalidfilehandle; + rxfd: integer = invalidfilehandle); + +implementation +uses + msesys,msestream,msearrayutils,sysutils,msebits,msesysintf1,msestrings, + msesysutils; + +procedure setcomcomp(const alink: icommclient; + const acommcomp: tcustomcommcomp; var dest: tcustomcommcomp); +begin + alink.setcommserverintf(nil); + if dest <> nil then begin + removeitem(pointerarty(dest.fclients),pointer(alink)); + end; + alink.getobjectlinker.setlinkedvar(alink,acommcomp,tmsecomponent(dest)); + if dest <> nil then begin + additem(pointerarty(dest.fclients),pointer(alink)); + alink.setcommserverintf(icommserver(dest)); + end; +end; + +procedure connectcryptoio(const acryptoio: tcryptoio; const tx: tcommwriter; + const rx: tcommreader; + var cryptoioinfo: cryptoioinfoty; + txfd: integer = invalidfilehandle; + rxfd: integer = invalidfilehandle); +begin + if (acryptoio <> nil) and (cryptoioinfo.kind <> cyk_none) then begin + if txfd = invalidfilehandle then begin + txfd:= tx.handle; + end; + if rxfd = invalidfilehandle then begin + rxfd:= rx.handle; + end; + tx.fcrypto:= @cryptoioinfo; + rx.fcrypto:= @cryptoioinfo; + acryptoio.link(txfd,rxfd,cryptoioinfo); + if cryptoioinfo.kind = cyk_server then begin + cryptoaccept(cryptoioinfo,rx.timeoutms); + end + else begin + cryptoconnect(cryptoioinfo,rx.timeoutms); + end; + end + else begin + tx.fcrypto:= nil; + rx.fcrypto:= nil; + end; +end; + +{ tcustomsercommcomp } + +constructor tcustomsercommcomp.create(aowner: tcomponent); +begin + if fpipes = nil then begin + fpipes:= tsercommpipes.create(self,cyk_none); //todo: cyk_sercomm + end; + fport:= tasyncserport.create(self); + fport.fnoclosehandle:= true; + fport.fonopen:= @doportopen; + fport.fonclose:= @doportclose; + inherited; +end; + +destructor tcustomsercommcomp.destroy; +begin + fport.free; + fpipes.free; + inherited; +end; + +procedure tcustomsercommcomp.setpipes(const avalue: tsercommpipes); +begin + fpipes.assign(avalue); +end; + +procedure tcustomsercommcomp.doportopen; +begin + if (fpipes.handle = invalidfilehandle) and + not (sco_nopipe in foptions) then begin + fpipes.handle:= fport.handle; + end; + factive:= true; +end; + +procedure tcustomsercommcomp.doportclose; +begin + fpipes.handle:= msesystypes.invalidfilehandle; + factive:= false; +end; + +procedure tcustomsercommcomp.internalconnect; +begin + if not (csdesigning in componentstate) then begin + if not fport.open then begin + componentexception(self, + 'Can not open comm port "'+fport.commpath+'":'+lineend+ + msestring(syserrortext(sye_lasterror))); + end; + {$ifdef unix} + setfilenonblock(fport.handle,sco_nopipe in foptions); + {$endif}; +// if not (sco_nopipe in foptions) then begin +// fpipes.handle:= fport.handle; +// end; + end; + factive:= true; + doafterconnect(fpipes); +end; + +procedure tcustomsercommcomp.internaldisconnect; +begin + fpipes.handle:= msesystypes.invalidfilehandle; + inherited; + fport.close; +end; + +procedure tcustomsercommcomp.closepipes(const sender: tcustomcommpipes); +begin +// if (csdestroying in componentstate) and application.ismainthread then begin + disconnect; +// end +// else begin +// asyncevent(closepipestag); +// end; +end; + +procedure tcustomsercommcomp.doasyncevent(var atag: integer); +begin + if atag = closepipestag then begin + disconnect; + end; +end; + +procedure tcustomsercommcomp.setport(const avalue: tasyncserport); +begin + fport.assign(avalue); +end; + +function tcustomsercommcomp.trywritedata(const adata: string): syserrorty; +begin + result:= fpipes.tx.trywritebuffer(pointer(adata)^,length(adata)); +end; + +function tcustomsercommcomp.gethalfduplex: boolean; +begin + result:= sco_halfduplex in foptions; +end; + +function tcustomsercommcomp.calctransmissiontime( + const alength: integer): integer; +begin + result:= fport.transmissiontime(alength); +end; + +procedure tcustomsercommcomp.setoptions(const avalue: sercommoptionsty); +begin + foptions:= avalue; + fport.fnoclosehandle:= not (sco_nopipe in foptions); +end; + +{ tsercommpipes } + +procedure tsercommpipes.createpipes; +begin + ftx:= tsercommwriter.create(self); + frx:= tsercommreader.create(self); +end; + +{ tasyncserport } + +constructor tasyncserport.create(const aowner: tmsecomponent; + const aoncheckabort: checkeventty = nil); +begin + inherited create(aowner,aoncheckabort); + fvmin:= #1; //blocking until first byte +end; + +{ tcustomcommpipes } + +constructor tcustomcommpipes.create(const aowner: tcustomcommcomp; + const acryptkind: cryptoiokindty); +begin + fowner:= aowner; + createpipes; +// frx:= tsocketreader.create; + frx.fonafterconnect:= {$ifdef FPC}@{$endif}doafterconnect; + frx.onpipebroken:= {$ifdef FPC}@{$endif}dopipebroken; + frx.fonthreadterminate:= {$ifdef FPC}@{$endif}dothreadterminate; +// ftx:= tsocketwriter.create; + setlinkedvar(aowner.fcryptoio,tmsecomponent(fcryptoio)); + fcryptoioinfo.kind:= acryptkind; +end; + +destructor tcustomcommpipes.destroy; +begin + inherited; + close; + frx.free; + ftx.free; +end; + +procedure tcustomcommpipes.release; +begin + if not (cps_releasing in fstate) then begin + application.postevent(tobjectevent.create(ek_release,ievent(self))); + include(fstate,cps_releasing); + end; +end; + +function tcustomcommpipes.gethandle: integer; +begin + result:= ftx.handle; +end; + +procedure tcustomcommpipes.doafterconnect; +begin + connectcryptoio(fcryptoio,ftx,frx,fcryptoioinfo); + if assigned(fonafterconnect) then begin + fonafterconnect(self); + end; +end; + +procedure tcustomcommpipes.dothreadterminate; +begin + cryptothreadterminate(fcryptoioinfo); + //dummy +end; + +procedure tcustomcommpipes.sethandle(const avalue: integer); +//var +// int1: integer; +begin + ftx.releasehandle; + ftx.handle:= avalue; + frx.handle:= avalue; + { + int1:= avalue; + if avalue <> invalidfilehandle then begin + syserror(sys_dup(avalue,int1)); + end; + frx.handle:= int1; + } + if avalue <> invalidfilehandle then begin + include(fstate,cps_open); + end + else begin + setcryptoio(nil); + exclude(fstate,cps_open); + end; +end; + +procedure tcustomcommpipes.setcryptoio(const acryptoio: tcryptoio); +begin + fcryptoio:= acryptoio; + with fcryptoioinfo do begin + cryptounlink(fcryptoioinfo); + ftx.fcrypto:= nil; + frx.fcrypto:= nil; + end; +end; + +function tcustomcommpipes.getoverloadsleepus: integer; +begin + result:= frx.overloadsleepus; +end; + +procedure tcustomcommpipes.setoverloadsleepus(const avalue: integer); +begin + frx.overloadsleepus:= avalue; +end; + +procedure tcustomcommpipes.setoninputavailable(const avalue: commpipeseventty); +begin + foninputavailable:= avalue; + if assigned(avalue) then begin + frx.oninputavailable:= {$ifdef FPC}@{$endif}doinputavailable; + end + else begin + frx.oninputavailable:= nil; + end; +end; + +procedure tcustomcommpipes.doinputavailable(const sender: tpipereader); +begin + if fowner.canevent(tmethod(foninputavailable)) then begin + foninputavailable(self); + end; +end; + +procedure tcustomcommpipes.receiveevent(const event: tobjectevent); +begin + if (event is tuserevent) and (tuserevent(event).tag = closepipestag) then begin + if assigned(foncommbroken) then begin + foncommbroken(self); + end + else begin + close; + end; + end + else begin + if event.kind = ek_release then begin + free; + end; + end; +end; + +procedure tcustomcommpipes.dopipebroken(const sender: tpipereader); +begin + application.postevent(tuserevent.create(ievent(self),closepipestag)); +end; + +procedure tcustomcommpipes.internalclose; +begin + fowner.closepipes(self); +end; + +procedure tcustomcommpipes.close; +begin + if fstate * [cps_open,cps_closing] = [cps_open] then begin + include(fstate,cps_closing); + try + if fowner.canevent(tmethod(fonbeforedisconnect)) then begin + fonbeforedisconnect(self); + end; + internalclose; + if fowner.canevent(tmethod(fonafterdisconnect)) then begin + fonafterdisconnect(self); + end; + finally + fstate:= fstate - [cps_closing,cps_open]; + end; + end; +end; + +function tcustomcommpipes.getoptionsreader: pipereaderoptionsty; +begin + result:= frx.options; +end; + +procedure tcustomcommpipes.setoptionsreader(const avalue: pipereaderoptionsty); +begin + frx.options:= avalue; +end; + +function tcustomcommpipes.getrxtimeoutms: integer; +begin + result:= frx.timeoutms; +end; + +procedure tcustomcommpipes.setrxtimeoutms(const avalue: integer); +begin + frx.timeoutms:= avalue; +end; + +function tcustomcommpipes.gettxtimeoutms: integer; +begin + result:= ftx.timeoutms; +end; + +procedure tcustomcommpipes.settxtimeoutms(const avalue: integer); +begin + ftx.timeoutms:= avalue; +end; + +procedure tcustomcommpipes.dorxchange(const areader: tcommreader); +var + int1: integer; +begin + for int1:= 0 to high(fowner.fclients) do begin + fowner.fclients[int1].dorxchange(areader); + end; +end; + +{ +procedure tcustomcommpipes.runhandlerapp(const commandline: filenamety); +var + rxha,txha: integer; + str1: string; +begin + rxha:= frx.handle; + txha:= ftx.handle; + frx.releasehandle; + ftx.releasehandle; + include(fstate,sops_detached); + internalclose; + execmse1(commandline,@rxha,@txha); +end; +} +{ tcustomcommcomp } + +constructor tcustomcommcomp.create(aowner: tcomponent); +begin + fhandle:= invalidfilehandle; + inherited; +end; + +destructor tcustomcommcomp.destroy; +var + int1: integer; +begin + for int1:= 0 to high(fclients) do begin + fclients[int1].setcommserverintf(nil); + end; + fclients:= nil; + inherited; +end; + +procedure tcustomcommcomp.doactivated; +begin + active:= true; +// if factive then begin +// connect; +// end; +end; + +procedure tcustomcommcomp.dodeactivated; +begin + active:= false; +end; + +procedure tcustomcommcomp.internaldisconnect; +begin + fhandle:= invalidfilehandle; + factive:= false; +end; + +procedure tcustomcommcomp.checkinactive; +begin + if not (csloading in componentstate) and active then begin + raise exception.create('Socket must be inactive.'); + end; +end; + +procedure tcustomcommcomp.setactive(const avalue: boolean); +begin + if factive <> avalue then begin + if not (csreading in componentstate) then begin + if avalue then begin + connect; + end + else begin + disconnect; + end; + end + else begin + factiveafterload:= avalue; + end; + end; +end; + +procedure tcustomcommcomp.doafterconnect(const sender: tcustomcommpipes); +begin + if canevent(tmethod(fonafterconnect)) then begin + application.lock; + try + fonafterconnect(self); + finally + application.unlock; + end; + end; +end; + +procedure tcustomcommcomp.connect; +begin + if canevent(tmethod(fonbeforeconnect)) then begin + fonbeforeconnect(self); + end; + internalconnect; +end; + +procedure tcustomcommcomp.disconnect; +begin + if canevent(tmethod(fonbeforedisconnect)) then begin + fonbeforedisconnect(self); + end; + internaldisconnect; + if canevent(tmethod(fonafterdisconnect)) then begin + fonafterdisconnect(self); + end; +end; + +procedure tcustomcommcomp.setcryptoio(const avalue: tcryptoio); +begin + setlinkedvar(avalue,tmsecomponent(fcryptoio)); +end; + +procedure tcustomcommcomp.loaded; +begin + inherited; + if factiveafterload then begin + active:= true; + end; +end; + +function tcustomcommcomp.gethalfduplex: boolean; +begin + result:= false; +end; + +function tcustomcommcomp.calctransmissiontime(const alength: integer): integer; +begin + result:= 0; +end; + +procedure tcustomcommcomp.writedata(const adata: string); +begin + syserror(trywritedata(adata)); +end; + +{ tcommreader } + +constructor tcommreader.create(const apipes: tcustomcommpipes); +begin + fpipes:= apipes; + inherited create; + fstate:= fstate + [tss_haslink]; +end; + +procedure tcommreader.settimeoutms(const avalue: integer); +begin + ftimeoutms:= avalue; +end; + +function tcommreader.execthread(thread: tmsethread): integer; +var + bo1: boolean; +begin +{$ifdef mse_debugsockets} + debugout(self,'socketreader execthread'); +{$endif} + fthread:= tsemthread(thread); + try + if assigned(fonafterconnect) then begin + try + fonafterconnect; + except + include(fstate,tss_error); + include(fstate,tss_eof); + doinputavailable; + raise; + end; + end; + with fthread do begin + while not terminated and not (tss_error in fstate) do begin + bo1:= doread(fmsbuf,sizeof(fmsbuf),fmsbufcount); + if not terminated then begin + if not bo1 then begin + include(fstate,tss_error); //broken socket + end; + if (fmsbufcount > 0) or (tss_error in fstate) then begin + include(fstate,tss_pipeactive); + doinputavailable; + if not terminated and not (tss_error in fstate) then begin + semwait; + end; + end; + end; + end; + include(fstate,tss_eof); + end; + result:= 0; + finally + if assigned(fonthreadterminate) then begin + fonthreadterminate; + end; + end; +{$ifdef mse_debugsockets} + debugout(self,'socketreader exitthread'); +{$endif} +end; + +function tcommreader.internalread(var buf; const acount: integer; + out readcount: integer; + const nonblocked: boolean = false): boolean; +begin + result:= inherited doread(buf,acount,readcount,nonblocked); +end; + +function tcommreader.doread(var buf; const acount: integer; + out readcount: integer; + const nonblocked: boolean = false): boolean; +var + int1: integer; +begin + if fcrypto <> nil then begin + if nonblocked then begin + int1:= -1; + end + else begin + int1:= 0; + end; + readcount:= cryptoread(fcrypto^,@buf,acount,int1); + result:= readcount >= 0; + if not result then begin + readcount:= 0; + end; + end + else begin + result:= internalread(buf,acount,readcount,nonblocked); + end; +end; + +procedure tcommreader.dochange; +begin + fpipes.dorxchange(self); +end; + +{ tcommwriter } + +constructor tcommwriter.create(const aowner: tcustomcommpipes); +begin + fowner:= aowner; + inherited create; +end; + +procedure tcommwriter.settimeoutms(const avalue: integer); +begin + ftimeoutms:= avalue; +end; + +function tcommwriter.internalwrite(const buffer; count: longint): longint; +begin + result:= inherited dowrite(buffer,count); +end; + +function tcommwriter.dowrite(const buffer; count: longint): longint; +begin + if fcrypto <> nil then begin + result:= cryptowrite(fcrypto^,@buffer,count,ftimeoutms); + end + else begin + result:= internalwrite(buffer,count); + end; +end; + +{ tcustomsercommchannel } + +constructor tcustomsercommchannel.create(aowner: tcomponent); +begin + feor:= c_linefeed; + sys_semcreate(fsem,0); + ftimer:= tsimpletimer.create(0,{$ifdef FPC}@{$endif}dotimer,false,[to_single]); + inherited; +end; + +destructor tcustomsercommchannel.destroy; +begin + clear; + ftimer.free; + sercomm:= nil; + sys_semdestroy(fsem); + inherited; +end; + +procedure tcustomsercommchannel.setsercomm(const avalue: tcustomcommcomp); +begin + if fsercomm <> avalue then begin + setcomcomp(icommclient(self),avalue,fsercomm); + end; +end; + +procedure tcustomsercommchannel.setcommserverintf(const aintf: icommserver); +begin + fserverintf:= aintf; +end; + +procedure tcustomsercommchannel.doresponse; +begin + if canevent(tmethod(fonresponse)) then begin + fonresponse(self,fdata,fflags); + end; +end; + +procedure tcustomsercommchannel.dorxchange(const areader: tcommreader); +var + bo1: boolean; + int1: integer; +begin + if sccs_pending in fstate then begin + fdata:= fdata + areader.readdatastring; + fflags:= []; + if areader.eof then begin + include(fflags,crf_eof); + end; + if sccs_eor in fstate then begin + int1:= pos(feor,fdata); + bo1:= int1 > 0; + if bo1 then begin + setlength(fdata,int1-1); + end; + end + else begin + bo1:= length(fdata) >= fexpected; + end; + if (fflags <> []) or bo1 then begin + exclude(fstate,sccs_pending); + if fsercomm.gethalfduplex then begin + fdata:= copy(fdata,fsent+1,bigint); + fexpected:= fexpected - fsent; + end; + if length(fdata) < fexpected then begin + include(fflags,crf_trunc); + end; + ftimer.enabled:= false; + if sccs_sync in fstate then begin + sys_sempost(fsem); + end + else begin + doresponse; + end; + end; + end + else begin + areader.readdatastring; //drop the data + end; +end; + +procedure tcustomsercommchannel.dotimer(const sender: tobject); +begin + fflags:= [crf_timeout]; + doresponse; +end; + +function tcustomsercommchannel.internaltransmit(const adata: string; + const aresponselength: integer; const atimeoutus: integer; + const sync: boolean; const aeor: boolean): syserrorty; +var + int1: integer; +begin + result:= sye_ok; + application.lock; + try + clear; + checksercomm; + if aeor and (feor = '') then begin + componentexception(self,'No end of record marker'); + end; + fsent:= length(adata); + fexpected:= aresponselength; + if fsercomm.gethalfduplex then begin + fexpected:= fexpected+fsent; + end; + int1:= ftimeoutus; + if atimeoutus <> 0 then begin + int1:= atimeoutus; + end; + if atimeoutus = -2 then begin + int1:= 0; + end; + if int1 = -1 then begin + int1:= 2*fsercomm.calctransmissiontime(fexpected+fsent)+ftimeoutus; + end; + updatebit({$ifdef FPC}longword{$else}byte{$endif}(fstate), + ord(sccs_sync),sync); + updatebit({$ifdef FPC}longword{$else}byte{$endif}(fstate),ord(sccs_eor),aeor); + include(fstate, sccs_pending); + result:= fsercomm.trywritedata(adata); + if result = sye_ok then begin + if sync then begin + sys_semtrywait(fsem); //clear + result:= application.semwait(fsem,int1); + exclude(fstate, sccs_pending); + end + else begin + if int1 > 0 then begin + ftimer.interval:= int1; + ftimer.enabled:= true; + end; + end; + end; + finally + application.unlock; + end; +end; + +function tcustomsercommchannel.transmit(const adata: string; + const aresponselength: integer; + const atimeoutus: integer = -1): syserrorty; +begin + result:= internaltransmit(adata,aresponselength,atimeoutus,false,false); +end; + +function tcustomsercommchannel.transmit(const adata: string; + const aresponselength: integer; + out aresult: string; + const atimeoutus: integer = -1): commresponseflagsty; + //synchronous +begin + case internaltransmit(adata,aresponselength,atimeoutus,true,false) of + sye_ok: begin + result:= fflags; + end; + sye_write: begin + result:= [crf_writeerror]; + end; + else begin + result:= [crf_timeout]; + end; + end; + aresult:= fdata; +end; + +procedure tcustomsercommchannel.checksercomm; +begin + if fsercomm = nil then begin + componentexception(self,'No sercomm.'); + end; + if not fsercomm.active then begin + componentexception(self,'sercomm inactive.'); + end; +end; + +procedure tcustomsercommchannel.clear; +begin + ftimer.enabled:= false; + fdata:= ''; + fstate:= fstate-[sccs_pending]; +end; + +function tcustomsercommchannel.transmiteor(const adata: string; + const aresponselength: integer = 0; + const atimeoutus: integer = -1): syserrorty; +begin + result:= internaltransmit(adata+feor,aresponselength,atimeoutus,false,true); +end; + +function tcustomsercommchannel.transmiteor(const adata: string; + out aresult: string; const aresponselength: integer = 0; + const atimeoutus: integer = -1): commresponseflagsty; +begin + case internaltransmit(adata+feor,aresponselength,atimeoutus,true,true) of + sye_ok: begin + result:= fflags; + end; + sye_write: begin + result:= [crf_writeerror]; + end; + else begin + result:= [crf_timeout]; + end; + end; + aresult:= fdata; +end; + +{ tsercommreader } + +function tsercommreader.internalread(var buf; const acount: integer; + out readcount: integer; + const nonblocked: boolean = false): boolean; +begin + result:= tcustomsercommcomp(fpipes.fowner).port.piperead(buf,acount,readcount, + nonblocked); +// result:= inherited internalread(buf,acount,readcount,nonblocked); +end; + +{ tsercommwriter } + +function tsercommwriter.internalwrite(const buffer; count: longint): longint; +begin + result:= tcustomsercommcomp(fowner.fowner).port.pipewrite(buffer,count); +end; + +{ tasynsercommchannel } + +function tasynsercommchannel.getsercomm: tcustomsercommcomp; +begin + result:= tcustomsercommcomp(inherited sercomm); +end; + +procedure tasynsercommchannel.setsercomm(const avalue: tcustomsercommcomp); +begin + if avalue = nil then begin + connected:= false; + end; + inherited setsercomm(avalue); + if (avalue <> nil) and not (csloading in componentstate) then begin + setupcomm(avalue); + end; +end; + +procedure tasynsercommchannel.doconnect; +begin + if canevent(tmethod(fonconnect)) then begin + fonconnect(self); + end; +end; + +procedure tasynsercommchannel.dodisconnect; +begin + if canevent(tmethod(fondisconnect)) then begin + fondisconnect(self); + end; +end; + +procedure tasynsercommchannel.setconnected(const avalue: boolean); +begin + if csloading in componentstate then begin + fconnectafterload:= avalue; + end + else begin + if fconnected <> avalue then begin + if avalue then begin + connect; + end + else begin + disconnect; + end; + end; + end; +end; + +procedure tasynsercommchannel.loaded; +begin + inherited; + if fsercomm <> nil then begin + setupcomm(tcustomsercommcomp(fsercomm)); + end; + if fconnectafterload then begin + connect; + end; +end; + +procedure tasynsercommchannel.setupcomm(const acomm: tcustomsercommcomp); +begin + if canevent(tmethod(fonsetupcomm)) then begin + fonsetupcomm(self,acomm); + end; +end; + +procedure tasynsercommchannel.connect; +begin + if fsercomm <> nil then begin + fsercomm.active:= true; + end; + fconnected:= true; +end; + +procedure tasynsercommchannel.disconnect; +begin + fconnected:= false; +end; + +end. diff --git a/mseide-msegui/lib/common/sysutils/msedbus.pas b/mseide-msegui/lib/common/sysutils/msedbus.pas new file mode 100644 index 0000000..a9ad2ec --- /dev/null +++ b/mseide-msegui/lib/common/sysutils/msedbus.pas @@ -0,0 +1,750 @@ +{ MSEgui Copyright (c) 2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msedbus; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msectypes,msetypes,msestrings; + +{$packrecords c} + +const +{$ifdef mswindows} + {$define wincall} //depends on compiler? + dbuslib: array[0..0] of filenamety = ('libdbus.dll'); +{$else} + dbuslib: array[0..1] of filenamety = ('libdbus-1.so','libdbus-1.so.3'); +{$endif} + +type + dbus_int64_t = int64; + dbus_uint64_t = uint64; + dbus_int32_t = int32; + pdbus_uint32_t = ^dbus_uint32_t; + dbus_uint32_t = uint32; + dbus_int16_t = int16; + dbus_uint16_t = uint16; + size_t = uint32; + dbus_unichar_t = dbus_uint32_t; + dbus_bool_t = dbus_uint32_t; + pdbus_bool_t = ^dbus_bool_t; + va_list = record end; + pva_list = ^va_list; + +//** +// * Indicates the status of incoming data on a #DBusConnection. This determines whether +// * dbus_connection_dispatch() needs to be called. +// */ + DBusDispatchStatus = ( + DBUS_DISPATCH_DATA_REMAINS, //**< There is more data to potentially convert to messages. */ + DBUS_DISPATCH_COMPLETE, //**< All currently available data has been processed. */ + DBUS_DISPATCH_NEED_MEMORY //**< More memory is needed to continue. */ + ); + +const + +//* Types of message */ + +//** This value is never a valid message type, see dbus_message_get_type() */ + DBUS_MESSAGE_TYPE_INVALID = 0; +//** Message type of a method call message, see dbus_message_get_type() */ + DBUS_MESSAGE_TYPE_METHOD_CALL = 1; +//** Message type of a method return message, see dbus_message_get_type() */ + DBUS_MESSAGE_TYPE_METHOD_RETURN = 2; +//** Message type of an error reply message, see dbus_message_get_type() */ + DBUS_MESSAGE_TYPE_ERROR = 3; +//** Message type of a signal message, see dbus_message_get_type() */ + DBUS_MESSAGE_TYPE_SIGNAL = 4; + + DBUS_NUM_MESSAGE_TYPES = 5; + +//** Type code that is never equal to a legitimate type code */ + DBUS_TYPE_INVALID = cint(0); +///** #DBUS_TYPE_INVALID as a string literal instead of a int literal */ + DBUS_TYPE_INVALID_AS_STRING = cchar(#0); + +//* Primitive types */ +//** Type code marking an 8-bit unsigned integer */ + DBUS_TYPE_BYTE = cint('y'); +//** #DBUS_TYPE_BYTE as a string literal instead of a int literal */ + DBUS_TYPE_BYTE_AS_STRING = 'y'; +//** Type code marking a boolean */ + DBUS_TYPE_BOOLEAN = cint('b'); +//** #DBUS_TYPE_BOOLEAN as a string literal instead of a int literal */ + DBUS_TYPE_BOOLEAN_AS_STRING = 'b'; +//** Type code marking a 16-bit signed integer */ + DBUS_TYPE_INT16 = cint('n'); +//** #DBUS_TYPE_INT16 as a string literal instead of a int literal */ + DBUS_TYPE_INT16_AS_STRING = 'n'; +//** Type code marking a 16-bit unsigned integer */ + DBUS_TYPE_UINT16 = cint('q'); +//** #DBUS_TYPE_UINT16 as a string literal instead of a int literal */ + DBUS_TYPE_UINT16_AS_STRING = 'q'; +//** Type code marking a 32-bit signed integer */ + DBUS_TYPE_INT32 = cint('i'); +//** #DBUS_TYPE_INT32 as a string literal instead of a int literal */ + DBUS_TYPE_INT32_AS_STRING = 'i'; +//** Type code marking a 32-bit unsigned integer */ + DBUS_TYPE_UINT32 = cint('u'); +//** #DBUS_TYPE_UINT32 as a string literal instead of a int literal */ + DBUS_TYPE_UINT32_AS_STRING = 'u'; +//** Type code marking a 64-bit signed integer */ + DBUS_TYPE_INT64 = cint('x'); +//** #DBUS_TYPE_INT64 as a string literal instead of a int literal */ + DBUS_TYPE_INT64_AS_STRING = 'x'; +//** Type code marking a 64-bit unsigned integer */ + DBUS_TYPE_UINT64 = cint('t'); +//** #DBUS_TYPE_UINT64 as a string literal instead of a int literal */ + DBUS_TYPE_UINT64_AS_STRING = 't'; +//** Type code marking an 8-byte double in IEEE 754 format */ + DBUS_TYPE_DOUBLE = cint('d'); +//** #DBUS_TYPE_DOUBLE as a string literal instead of a int literal */ + DBUS_TYPE_DOUBLE_AS_STRING = 'd'; +//** Type code marking a UTF-8 encoded, nul-terminated Unicode string */ + DBUS_TYPE_STRING = cint('s'); +//** #DBUS_TYPE_STRING as a string literal instead of a int literal */ + DBUS_TYPE_STRING_AS_STRING = 's'; +//** Type code marking a D-Bus object path */ + DBUS_TYPE_OBJECT_PATH = cint('o'); +//** #DBUS_TYPE_OBJECT_PATH as a string literal instead of a int literal */ + DBUS_TYPE_OBJECT_PATH_AS_STRING = 'o'; +//** Type code marking a D-Bus type signature */ + DBUS_TYPE_SIGNATURE = cint('g'); +//** #DBUS_TYPE_SIGNATURE as a string literal instead of a int literal */ + DBUS_TYPE_SIGNATURE_AS_STRING = 'g'; +//** Type code marking a unix file descriptor */ + DBUS_TYPE_UNIX_FD = cint('h'); +//** #DBUS_TYPE_UNIX_FD as a string literal instead of a int literal */ + DBUS_TYPE_UNIX_FD_AS_STRING = 'h'; + +//* Compound types */ +//** Type code marking a D-Bus array type */ + DBUS_TYPE_ARRAY = cint('a'); +//** #DBUS_TYPE_ARRAY as a string literal instead of a int literal */ + DBUS_TYPE_ARRAY_AS_STRING = 'a'; +//** Type code marking a D-Bus variant type */ + DBUS_TYPE_VARIANT = cint('v'); +//** #DBUS_TYPE_VARIANT as a string literal instead of a int literal */ + DBUS_TYPE_VARIANT_AS_STRING = 'v'; + +//** STRUCT and DICT_ENTRY are sort of special since their codes can't +// * appear in a type string, instead +// * DBUS_STRUCT_BEGIN_CHAR/DBUS_DICT_ENTRY_BEGIN_CHAR have to appear +// */ +//** Type code used to represent a struct; however, this type code does not appear +// * in type signatures, instead #DBUS_STRUCT_BEGIN_CHAR and #DBUS_STRUCT_END_CHAR will +// * appear in a signature. +// */ + DBUS_TYPE_STRUCT = cint('r'); +//** #DBUS_TYPE_STRUCT as a string literal instead of a int literal */ + DBUS_TYPE_STRUCT_AS_STRING = 'r'; +//** Type code used to represent a dict entry; however, this type code does not appear +// * in type signatures, instead #DBUS_DICT_ENTRY_BEGIN_CHAR and #DBUS_DICT_ENTRY_END_CHAR will +// * appear in a signature. +// */ + DBUS_TYPE_DICT_ENTRY = cint('e'); +//** #DBUS_TYPE_DICT_ENTRY as a string literal instead of a int literal */ + DBUS_TYPE_DICT_ENTRY_AS_STRING = 'e'; + +//* Owner flags */ + DBUS_NAME_FLAG_ALLOW_REPLACEMENT = $1; + //**< Allow another service to become the primary owner if requested */ + DBUS_NAME_FLAG_REPLACE_EXISTING = $2; + //**< Request to replace the current primary owner */ + DBUS_NAME_FLAG_DO_NOT_QUEUE = $4; + //**< If we can not become the primary owner do not place us in the queue */ + +//* Replies to request for a name */ + DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER = 1; + //**< Service has become the primary owner of the requested name */ + DBUS_REQUEST_NAME_REPLY_IN_QUEUE = 2; + //**< Service could not become the primary owner and has been placed in the queue */ + DBUS_REQUEST_NAME_REPLY_EXISTS = 3; + //**< Service is already in the queue */ + DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER = 4; + //**< Service is already the primary owner */ + + DBUS_TIMEOUT_INFINITE = cint($7fffffff); + DBUS_TIMEOUT_USE_DEFAULT = cint(-1); + + DBUS_WATCH_READABLE = 1 shl 0; //**< As in POLLIN */ + DBUS_WATCH_WRITABLE = 1 shl 1; //**< As in POLLOUT */ + DBUS_WATCH_ERROR = 1 shl 2; //**< As in POLLERR (can't watch for + // * this, but can be present in + // * current state passed to + // * dbus_watch_handle()). + // */ + DBUS_WATCH_HANGUP = 1 shl 3; //**< As in POLLHUP (can't watch for + //* it, but can be present in current + //* state passed to + //* dbus_watch_handle()). + //*/ + //* Internal to libdbus, there is also _DBUS_WATCH_NVAL in dbus-watch.h */ + +type + DBusError = record + name: pcchar; //**< public error name field */ + message: pcchar; //**< public error message field */ + dummy: cuint; +// unsigned int dummy1 : 1; /**< placeholder */ +// unsigned int dummy2 : 1; /**< placeholder */ +// unsigned int dummy3 : 1; /**< placeholder */ +// unsigned int dummy4 : 1; /**< placeholder */ +// unsigned int dummy5 : 1; /**< placeholder */ + padding1: pointer; {< placeholder } + end; + pDBusError = ^DBusError; + + DBusMessageIter = record + dummy1: pointer; //**< Don't use this */ + dummy2: pointer; //**< Don't use this */ + dummy3: dbus_uint32_t; //**< Don't use this */ + dummy4: cint; //**< Don't use this */ + dummy5: cint; //**< Don't use this */ + dummy6: cint; //**< Don't use this */ + dummy7: cint; //**< Don't use this */ + dummy8: cint; //**< Don't use this */ + dummy9: cint; //**< Don't use this */ + dummy10: cint; //**< Don't use this */ + dummy11: cint; //**< Don't use this */ + pad1: cint; //**< Don't use this */ + pad2: cint; //**< Don't use this */ + pad3: pointer; //**< Don't use this */ + end; + pDBusMessageIter = ^DBusMessageIter; + + DBusConnection = record end; + pDBusConnection = ^DBusConnection; + DBusMessage = record end; + pDBusMessage = ^DBusMessage; + DBusWatch = record end; + pDBusWatch = ^DBusWatch; + DBusTimeout = record end; + pDBusTimeout = ^DBusTimeout; + DBusPendingCall = record end; + pDBusPendingCall = ^DBusPendingCall; + ppDBusPendingCall = ^pDBusPendingCall; + +//** +//* Results that a message handler can return. +//*/ +DBusHandlerResult = ( + DBUS_HANDLER_RESULT_HANDLED, + //**< Message has had its effect - no need to run more handlers. */ + DBUS_HANDLER_RESULT_NOT_YET_HANDLED, + //**< Message has not had any effect - see if other handlers want it. */ + DBUS_HANDLER_RESULT_NEED_MEMORY + //**< Need more memory in order to return #DBUS_HANDLER_RESULT_HANDLED or + //#DBUS_HANDLER_RESULT_NOT_YET_HANDLED. + // Please try again later with more memory. */ +); + +///** +// * Called when a message needs to be handled. The result indicates whether or +// * not more handlers should be run. Set with dbus_connection_add_filter(). +// */ + DBusHandleMessageFunction = + function(connection: pDBusConnection; message: pDBusMessage; + user_data: pointer): DBusHandlerResult + {$ifdef wincall}stdcall{$else}cdecl{$endif}; +//** +//* Called when a message is sent to a registered object path. Found in +//* #DBusObjectPathVTable which is registered with dbus_connection_register_object_path() +//* or dbus_connection_register_fallback(). +//*/ + DBusObjectPathMessageFunction = + function(connection: pDBusConnection; message: pDBusMessage; + user_data: pointer): DBusHandlerResult + {$ifdef wincall}stdcall{$else}cdecl{$endif}; +//** +//* Called when a #DBusObjectPathVTable is unregistered (or its connection is freed). +//* Found in #DBusObjectPathVTable. +//*/ + DBusObjectPathUnregisterFunction = procedure(connection: pDBusConnection; + user_data: pointer) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + DBusObjectPathVTable = record + unregister_function: DBusObjectPathUnregisterFunction; + //**< Function to unregister this handler */ + message_function: DBusObjectPathMessageFunction; + //**< Function to handle messages */ + + dbus_internal_pad1: pointer; //**< Reserved for future expansion */ + dbus_internal_pad2: pointer; //**< Reserved for future expansion */ + dbus_internal_pad3: pointer; //**< Reserved for future expansion */ + dbus_internal_pad4: pointer; //**< Reserved for future expansion */ + end; + pDBusObjectPathVTable = ^DBusObjectPathVTable; + + DBusBusType = ( + DBUS_BUS_SESSION, //**< The login session bus */ + DBUS_BUS_SYSTEM, //**< The systemwide bus */ + DBUS_BUS_STARTER //**< The bus that started us, if any */ + ); + + DBusFreeFunction = procedure(memory: pointer) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +//** Called when libdbus needs a new watch to be monitored by the main +//* loop. Returns #FALSE if it lacks enough memory to add the +//* watch. Set by dbus_connection_set_watch_functions() or +//* dbus_server_set_watch_functions(). +//*/ + DBusAddWatchFunction = function(watch: pDBusWatch; + data: pointer): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +//** Called when dbus_watch_get_enabled() may return a different value +//* than it did before. Set by dbus_connection_set_watch_functions() +//* or dbus_server_set_watch_functions(). +//*/ + DBusWatchToggledFunction = procedure(watch: pDBusWatch; data: pointer) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +//** Called when libdbus no longer needs a watch to be monitored by the +//* main loop. Set by dbus_connection_set_watch_functions() or +//* dbus_server_set_watch_functions(). +//*/ + DBusRemoveWatchFunction = procedure(watch: pDBusWatch; data: pointer) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +//** Called when libdbus needs a new timeout to be monitored by the main +//* loop. Returns #FALSE if it lacks enough memory to add the +//* watch. Set by dbus_connection_set_timeout_functions() or +//* dbus_server_set_timeout_functions(). +//*/ + DBusAddTimeoutFunction = function(timeout: pDBusTimeout; + data: pointer): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +//** Called when dbus_timeout_get_enabled() may return a different +//* value than it did before. +//* Set by dbus_connection_set_timeout_functions() or +//* dbus_server_set_timeout_functions(). +//*/ + DBusTimeoutToggledFunction = procedure(timeout: pDBusTimeout; data: pointer) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; +//** Called when libdbus no longer needs a timeout to be monitored by the +//* main loop. Set by dbus_connection_set_timeout_functions() or +//* dbus_server_set_timeout_functions(). +//*/ + DBusRemoveTimeoutFunction = procedure(timeout: pDBusTimeout; data: pointer) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +//** +//* Called when a pending call now has a reply available. Set with +//* dbus_pending_call_set_notify(). +//*/ + DBusPendingCallNotifyFunction = procedure(pending: pDBusPendingCall; + user_data: pointer) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +var + dbus_bus_get: + function(type_: DBusBusType; error: PDBusError): PDBusConnection + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_bus_get_private: + function(type_: DBusBusType; error: PDBusError): PDBusConnection + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_connection_close: procedure(connection: pDBusConnection) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_shutdown: procedure() + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + dbus_connection_set_watch_functions: + function(connection: pDBusConnection; add_function: DBusAddWatchFunction; + remove_function: DBusRemoveWatchFunction; + toggled_function: DBusWatchToggledFunction; + data: pointer; + free_data_function: DBusFreeFunction): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_connection_set_timeout_functions: + function(connection: pDBusConnection; add_function: DBusAddTimeoutFunction; + remove_function: DBusRemoveTimeoutFunction; + toggled_function: DBusTimeoutToggledFunction; + data: pointer; + free_data_function: DBusFreeFunction): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + dbus_connection_add_filter: + function(connection: pDBusConnection; function_: DBusHandleMessageFunction; + user_data: pointer; free_data_function: DBusFreeFunction): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_connection_remove_filter: + procedure(connection: pDBusConnection; + function_: DBusHandleMessageFunction; user_data: pointer); + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_connection_try_register_object_path: + function(cionnection: pDBusConnection; path: pchar; + vtable: pDBusObjectPathVTable; + user_data: pointer; error: pDBusError): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_connection_unregister_object_path: + function(connection: pDBusConnection; path: pcchar): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_connection_try_register_fallback: + function(connection: pDBusConnection; path: pcchar; + vtable: pDBusObjectPathVTable; user_data: pointer; + error: pDBusError): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + dbus_watch_get_unix_fd: function(watch: pDBusWatch): cint + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_watch_get_socket: function(watch: pDBusWatch): cint + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_watch_get_flags: function(watch: pDBusWatch): cuint + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_watch_get_data: function(watch: pDBusWatch): pointer + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_watch_set_data: procedure(watch: pDBusWatch; data: pointer; + free_data_function: DBusFreeFunction) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_watch_handle: function(watch: pDBusWatch; flags: cuint): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_watch_get_enabled: function(watch: pDBusWatch): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + dbus_timeout_get_interval: function(timeout: pDBusTimeout): cint + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_timeout_get_data: function(timeout: pDBusTimeout): pointer + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_timeout_set_data: procedure(timeout: pDBusTimeout; data: pointer; + free_data_function: DBusFreeFunction) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_timeout_handle: function(timeout: pDBusTimeout): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_timeout_get_enabled: function(timeout: pDBusTimeout): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_timeout_needs_restart: function(timeout: pDBusTimeout): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_timeout_restarted: procedure(timeout: pDBusTimeout) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + dbus_error_init: procedure(error: pDBusError) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_error_free: procedure(error: pDBusError) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_error_is_set: function(error: pDBusError): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_connection_set_exit_on_disconnect: + procedure(connection: pDBusConnection; exit_on_disconnect: dbus_bool_t) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_bus_get_unique_name: function(connection: pDBusConnection): pcchar + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_bus_request_name: + function(connection: PDBusConnection; name: pcchar; flags: cuint; + error: pDBusError): cint + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_new_method_call: + function(bus_name: pcchar; path: pcchar; iface: pcchar; + method: pcchar): pDBusMessage + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_new_method_return: + function(method_call: pDBusMessage): pDBusMessage + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_new_signal: + function(path: pchar; iface: pchar; name: pcchar): pDBusMessage + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_new_error: + function(reply_to: pDBusMessage; error_name: pcchar; + error_message: pcchar): pDBusMessage + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + dbus_message_unref: procedure(message: pDBusMessage) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_get_type: function(message: pDBusMessage): cint + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_set_path: function(message:pDBusMessage; + object_path: pcchar): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_get_path: function(message: pDBusMessage): pcchar + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_set_interface: + function(message: pDBusMessage; iface: pcchar): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_get_interface: function(message: pDBusMessage): pcchar + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_set_member: + function(message: pDBusMessage; member: pcchar): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_get_member: function(message: pDBusMessage): pcchar; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_set_error_name: + function(message: pDBusMessage; name: pcchar): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_get_error_name: + function(message: pDBusMessage): pcchar; + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_set_destination: + function(message: pDBusMessage; destination: pchar): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_get_destination: function(message: pDBusMessage): pchar + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_set_sender: + function(msessage: pDBusMessage; sender: pcchar): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_get_sender: function (message: pDBusMessage): pcchar + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_get_signature: function(message: pDBusMessage): pchar + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_set_no_reply: + procedure(message: pDBusMessage; no_reply: dbus_bool_t) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_get_no_reply: function(message: pDBusMessage): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + dbus_message_iter_init_append: + procedure(message: pDBusMessage; iter: pDBusMessageIter) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_iter_init: + function(message: pDBusMessage; iter: pDBusMessageIter): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_append_args_valist: + function (message: pDBusMessage; first_arg_type: cint; + var_args: pva_list): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_iter_append_basic: + function(iter: pDBusMessageIter; type_: cint; value: pointer): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_iter_append_fixed_array: + function(iter: pDBusMessageIter; element_type: cint; value: pointer; + n_elements: cint): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + dbus_message_iter_next: function (iter: pDBusMessageIter): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_iter_get_arg_type: function (iter: pDBusMessageIter): cint + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_iter_get_basic: procedure (iter: pDBusMessageIter; value: pointer) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_iter_open_container: + function(iter: pDBusMessageIter; type_: cint; + const contained_signature: pcchar; + sub: pDBusMessageIter): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_iter_close_container: + function(iter: pDBusMessageIter; sub: pDBusMessageIter): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_iter_abandon_container: + procedure(iter: pDBusMessageIter; sub: pDBusMessageIter); + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + dbus_message_iter_recurse: + procedure (iter: pDBusMessageIter; sub: pDBusMessageIter) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_iter_get_element_type: function (iter: pDBusMessageIter): cint + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_message_iter_get_fixed_array: + procedure (iter: pDBusMessageIter; value: pointer; n_elements: pcint) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + dbus_connection_send_with_reply_and_block: + function(connection: pDBusConnection; message: pDBusMessage; + timeout_milliseconds: cint; error: pDBusError): pDBusMessage + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_connection_send_with_reply: + function(connection: pDBusConnection; message: pDBusMessage; + pending_return: ppDBusPendingCall; + timeout_milliseconds: cint): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_connection_send: + function(connection: pDBusConnection; message: pDBusMessage; + client_serial: pdbus_uint32_t): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_connection_flush: procedure(connection: pDBusConnection) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_connection_dispatch: + function(connection: pDBusConnection): DBusDispatchStatus + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + dbus_pending_call_unref: procedure(pending: pDBusPendingCall) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_pending_call_set_notify: + function(pending: pDBusPendingCall; + function_: DBusPendingCallNotifyFunction; + user_data: pointer; free_user_data: DBusFreeFunction): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_pending_call_steal_reply: + function(pending: pDBusPendingCall): pDBusMessage + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + + dbus_bus_add_match: + procedure(connection: pDBusConnection; rule: pcchar; error: pDBusError) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + dbus_bus_remove_match: + procedure(connection: pDBusConnection; rule: pcchar; error: pDBusError) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; + +function initializedbus(const sonames: array of filenamety; //[] = default + const onlyonce: boolean = false): boolean; + //true if ok +procedure releasedbus(); + +implementation +uses + msedynload,sysutils; +var + libinfo: dynlibinfoty; + +procedure inidbus(const data: pointer); +begin +end; + +procedure finidbus(const data: pointer); +begin +end; + +function initializedbus(const sonames: array of filenamety; //[] = default + const onlyonce: boolean = false): boolean; +const + funcs: array[0..76] of funcinfoty = ( + (n: 'dbus_bus_get'; d: @dbus_bus_get), // 0 + (n: 'dbus_bus_get_private'; d: @dbus_bus_get_private), // 1 + (n: 'dbus_connection_close'; d: @dbus_connection_close), // 2 + (n: 'dbus_shutdown'; d: @dbus_shutdown), // 3 + (n: 'dbus_connection_set_watch_functions'; + d: @dbus_connection_set_watch_functions), // 4 + (n: 'dbus_connection_set_timeout_functions'; + d: @dbus_connection_set_timeout_functions), // 5 + (n: 'dbus_connection_add_filter'; + d: @dbus_connection_add_filter), // 6 + (n: 'dbus_connection_remove_filter'; + d: @dbus_connection_remove_filter), // 7 + (n: 'dbus_connection_try_register_object_path'; + d: @dbus_connection_try_register_object_path), // 8 + (n: 'dbus_connection_try_register_fallback'; + d: @dbus_connection_try_register_fallback), // 9 + (n: 'dbus_connection_unregister_object_path'; + d: @dbus_connection_unregister_object_path), //10 + (n: 'dbus_watch_get_unix_fd'; d: @dbus_watch_get_unix_fd), //11 + (n: 'dbus_watch_get_socket'; d: @dbus_watch_get_socket), //12 + (n: 'dbus_watch_get_flags'; d: @dbus_watch_get_flags), //13 + (n: 'dbus_watch_get_data'; d: @dbus_watch_get_data), //14 + (n: 'dbus_watch_set_data'; d: @dbus_watch_set_data), //15 + (n: 'dbus_watch_handle'; d: @dbus_watch_handle), //16 + (n: 'dbus_watch_get_enabled'; d: @dbus_watch_get_enabled), //17 + + (n: 'dbus_timeout_get_interval'; + d: @dbus_timeout_get_interval), //18 + (n: 'dbus_timeout_get_data'; d: @dbus_timeout_get_data), //19 + (n: 'dbus_timeout_set_data'; d: @dbus_timeout_set_data), //20 + (n: 'dbus_timeout_handle'; d: @dbus_timeout_handle), //21 + (n: 'dbus_timeout_get_enabled'; d: @dbus_timeout_get_enabled), //22 + (n: 'dbus_timeout_needs_restart'; + d: @dbus_timeout_needs_restart), //23 + (n: 'dbus_timeout_restarted'; d: @dbus_timeout_restarted), //24 + + (n: 'dbus_error_init'; d: @dbus_error_init), //25 + (n: 'dbus_error_free'; d: @dbus_error_free), //26 + (n: 'dbus_error_is_set'; d: @dbus_error_is_set), //27 + (n: 'dbus_connection_set_exit_on_disconnect'; + d: @dbus_connection_set_exit_on_disconnect), //28 + (n: 'dbus_bus_get_unique_name'; d: @dbus_bus_get_unique_name), //29 + (n: 'dbus_bus_request_name'; d: @dbus_bus_request_name), //30 + (n: 'dbus_message_new_method_call'; + d: @dbus_message_new_method_call), //31 + (n: 'dbus_message_new_method_return'; + d: @dbus_message_new_method_return), //32 + (n: 'dbus_message_new_signal'; d: @dbus_message_new_signal), //33 + (n: 'dbus_message_new_error'; d: @dbus_message_new_error), //34 + (n: 'dbus_message_get_type'; d: @dbus_message_get_type), //35 + (n: 'dbus_message_set_path'; d: @dbus_message_set_path), //36 + (n: 'dbus_message_get_path'; d: @dbus_message_get_path), //37 + (n: 'dbus_message_set_interface'; + d: @dbus_message_set_interface), //38 + (n: 'dbus_message_get_interface'; + d: @dbus_message_get_interface), //39 + (n: 'dbus_message_set_member'; d: @dbus_message_set_member), //40 + (n: 'dbus_message_get_member'; d: @dbus_message_get_member), //41 + (n: 'dbus_message_set_error_name'; + d: @dbus_message_set_error_name), //42 + (n: 'dbus_message_get_error_name'; + d: @dbus_message_get_error_name), //43 + (n: 'dbus_message_set_destination'; + d: @dbus_message_set_destination), //44 + (n: 'dbus_message_get_destination'; + d: @dbus_message_get_destination), //45 + (n: 'dbus_message_set_sender'; d: @dbus_message_set_sender), //46 + (n: 'dbus_message_set_sender'; d: @dbus_message_set_sender), //47 + (n: 'dbus_message_get_sender'; d: @dbus_message_get_sender), //48 + (n: 'dbus_message_get_signature'; + d: @dbus_message_get_signature), //49 + (n: 'dbus_message_set_no_reply'; + d: @dbus_message_set_no_reply), //50 + (n: 'dbus_message_get_no_reply'; + d: @dbus_message_get_no_reply), //51 + + (n: 'dbus_message_unref'; d: @dbus_message_unref), //52 + (n: 'dbus_message_iter_init_append'; + d: @dbus_message_iter_init_append), //53 + (n: 'dbus_message_iter_init'; d: @dbus_message_iter_init), //54 + (n: 'dbus_message_append_args_valist'; + d: @dbus_message_append_args_valist), //55 + (n: 'dbus_message_iter_append_basic'; + d: @dbus_message_iter_append_basic), //56 + (n: 'dbus_message_iter_append_fixed_array'; + d: @dbus_message_iter_append_fixed_array), //57 + (n: 'dbus_message_iter_next'; d: @dbus_message_iter_next), //58 + (n: 'dbus_message_iter_get_arg_type'; + d: @dbus_message_iter_get_arg_type), //59 + (n: 'dbus_message_iter_get_basic'; + d: @dbus_message_iter_get_basic), //60 + (n: 'dbus_message_iter_open_container'; + d: @dbus_message_iter_open_container), //61 + (n: 'dbus_message_iter_close_container'; + d: @dbus_message_iter_close_container), //62 + (n: 'dbus_message_iter_abandon_container'; + d: @dbus_message_iter_abandon_container), //63 + (n: 'dbus_message_iter_recurse'; + d: @dbus_message_iter_recurse), //64 + (n: 'dbus_message_iter_get_element_type'; + d: @dbus_message_iter_get_element_type), //65 + (n: 'dbus_message_iter_get_fixed_array'; + d: @dbus_message_iter_get_fixed_array), //66 + (n: 'dbus_connection_send_with_reply_and_block'; + d: @dbus_connection_send_with_reply_and_block), //67 + (n: 'dbus_connection_send_with_reply'; + d: @dbus_connection_send_with_reply), //68 + (n: 'dbus_connection_send'; d: @dbus_connection_send), //69 + (n: 'dbus_connection_flush'; d: @dbus_connection_flush), //70 + (n: 'dbus_connection_dispatch'; d: @dbus_connection_dispatch), //71 + (n: 'dbus_pending_call_unref'; d: @dbus_pending_call_unref), //72 + (n: 'dbus_pending_call_set_notify'; + d: @dbus_pending_call_set_notify), //73 + (n: 'dbus_pending_call_steal_reply'; + d: @dbus_pending_call_steal_reply), //74 + (n: 'dbus_bus_add_match'; d: @dbus_bus_add_match), //75 + (n: 'dbus_bus_remove_match'; d: @dbus_bus_remove_match) //76 + ); + +{ + (n: ''; d: @),// +} + + errormessage = 'Can not load D-Bus library. '; + +begin + if not onlyonce or (libinfo.refcount = 0) then begin + result:= initializedynlib(libinfo,sonames,dbuslib,funcs,[], + errormessage,@inidbus,true); + end; +end; + +procedure releasedbus(); +begin + releasedynlib(libinfo,@finidbus); +end; + +initialization + initializelibinfo(libinfo); +finalization + finalizelibinfo(libinfo); +end. diff --git a/mseide-msegui/lib/common/sysutils/msedbusinterface.pas b/mseide-msegui/lib/common/sysutils/msedbusinterface.pas new file mode 100644 index 0000000..77e8575 --- /dev/null +++ b/mseide-msegui/lib/common/sysutils/msedbusinterface.pas @@ -0,0 +1,3916 @@ +{ MSEgui Copyright (c) 2016-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msedbusinterface; +{$ifdef FPC}{$mode objfpc}{$h+}{$goto on} + {$if FPC_FULLVERSION >= 030000} {$define mse_fpc_3_0} {$endif} + {$if FPC_FULLVERSION >= 030100} {$define mse_fpc_3_2} {$endif} +{$endif} + +{$ifdef mswindows} + {$define wincall} //depends on compiler? +{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + mseglob,msectypes,msedbus,msetypes,mseclasses,mseevent,msehash,sysutils, + msesys,msetimer,msehashstore,msestringident,mselinklist,typinfo; + +const + msebusname = 'mse.msegui.app'; + +type + dbusdataty = ( + dbt_INVALID, + dbt_BYTE, + dbt_BOOLEAN, + dbt_INT16, + dbt_UINT16, + dbt_INT32, + dbt_UINT32, + dbt_INT64, + dbt_UINT64, + dbt_DOUBLE, + dbt_STRING, + dbt_OBJECT_PATH, + dbt_SIGNATURE, + dbt_UNIX_FD, + dbt_ARRAY, + dbt_VARIANT, + dbt_STRUCT, + dbt_DICT_ENTRY, + dbt_msevariant, + dbt_structend + ); + pdbusdataty = ^dbusdataty; + dbusdatatyarty = array of dbusdataty; + + variantvaluekindty = (vvk_none,vvk_string,vvk_int32,vvk_card32,vvk_dynar, + vvk_record,vvk_variantar); + dynarinfoty = record + data: pointer; + typinfo: ptypeinfo; + end; + pdynarinfoty = ^dynarinfoty; + variantarinfoty = record + data: pointer; //variantvaluearty + typinfo: ptypeinfo; + end; +// pvariantarinfoty = ^variantarinfoty; + + variantflagty = (vf_var,vf_dict); + variantflagsty = set of variantflagty; + variantvaluety = record +// types: dbusdatatyarty; + flags: variantflagsty; + case kind: variantvaluekindty of + vvk_string: (vstring: pointer;); + vvk_int32: (vint32: int32;); + vvk_card32: (vcard32: card32;); + vvk_dynar: (vdynar: dynarinfoty); + vvk_record,vvk_variantar: (vvariantar: variantarinfoty); + end; + pvariantvaluety = ^variantvaluety; + variantvaluearty = array of variantvaluety; + + dictentryty = record + name: string; + value: variantvaluety; + end; + pdictentryty = ^dictentryty; + dictentryarty = array of dictentryty; + + edbus = class(exception) + end; + + idbusclient = interface(iobjectlink) + end; + idbusresponse = interface(idbusclient) + procedure replied(const serial: card32; const amessage: pdbusmessage{; + const auser_data: pointer}); + end; + +const + dbusdatasizes: array[dbusdataty] of int32 = ( + 0, //dbt_INVALID, + sizeof(byte), //dbt_BYTE, + sizeof(boolean), //dbt_BOOLEAN, + sizeof(int16), //dbt_INT16, + sizeof(card16), //dbt_UINT16, + sizeof(int32), //dbt_INT32, + sizeof(card32), //dbt_UINT32, + sizeof(int64), //dbt_INT64, + sizeof(card64), //dbt_UINT64, + sizeof(flo64), //dbt_DOUBLE, + sizeof(ansistring), //dbt_STRING, + sizeof(ansistring), //dbt_OBJECT_PATH, + sizeof(ansistring), //dbt_SIGNATURE, + 0, //dbt_UNIX_FD, + sizeof(dynarinfoty), //dbt_ARRAY, + 0, //dbt_VARIANT, + 0, //dbt_STRUCT, + sizeof(dictentryty), //dbt_DICT_ENTRY + sizeof(variantvaluety), //dbt_msevariant + 0 //dbt_structend + ); + + methodhandlerid = strid0; + signalmatchid = strid1; + signalhandlerid = strid1; + separatorid = strid3; + +var + arraytypes: array[dbusdataty] of pdynarraytypeinfo; +const + dbusdatacodes: array[dbusdataty] of cint = ( + DBUS_TYPE_INVALID, + DBUS_TYPE_BYTE, + DBUS_TYPE_BOOLEAN, + DBUS_TYPE_INT16, + DBUS_TYPE_UINT16, + DBUS_TYPE_INT32, + DBUS_TYPE_UINT32, + DBUS_TYPE_INT64, + DBUS_TYPE_UINT64, + DBUS_TYPE_DOUBLE, + DBUS_TYPE_STRING, + DBUS_TYPE_OBJECT_PATH, + DBUS_TYPE_SIGNATURE, + DBUS_TYPE_UNIX_FD, + DBUS_TYPE_ARRAY, + DBUS_TYPE_VARIANT, + DBUS_TYPE_STRUCT, + DBUS_TYPE_DICT_ENTRY, + -1, //dbt_msevariant + -1 //dbt_structend + ); + + dbusdatatycodes: array[variantvaluekindty] of cint = ( + DBUS_TYPE_INVALID, //vvk_none + DBUS_TYPE_STRING, //vvk_string, + DBUS_TYPE_INT32, //vvk_int32, + DBUS_TYPE_UINT32, //vvk_card32, + DBUS_TYPE_INVALID, //vvk_dynar, + DBUS_TYPE_INVALID, //vvk_record + DBUS_TYPE_INVALID //vvk_variantar + ); + + dbusdatastrings: array[dbusdataty] of string = ( + DBUS_TYPE_INVALID_AS_STRING, + DBUS_TYPE_BYTE_AS_STRING, + DBUS_TYPE_BOOLEAN_AS_STRING, + DBUS_TYPE_INT16_AS_STRING, + DBUS_TYPE_UINT16_AS_STRING, + DBUS_TYPE_INT32_AS_STRING, + DBUS_TYPE_UINT32_AS_STRING, + DBUS_TYPE_INT64_AS_STRING, + DBUS_TYPE_UINT64_AS_STRING, + DBUS_TYPE_DOUBLE_AS_STRING, + DBUS_TYPE_STRING_AS_STRING, + DBUS_TYPE_OBJECT_PATH_AS_STRING, + DBUS_TYPE_SIGNATURE_AS_STRING, + DBUS_TYPE_UNIX_FD_AS_STRING, + '',//DBUS_TYPE_ARRAY_AS_STRING, + '',//DBUS_TYPE_VARIANT_AS_STRING, + '',//DBUS_TYPE_STRUCT_AS_STRING, + '{sv}', //DBUS_TYPE_DICT_ENTRY_AS_STRING + '', //dbt_msevariant + '' //dbt_structend + ); + +type + messageeventty = procedure(const amessage: pdbusmessage; + var handled: boolean) of object; + messagedataeventty = procedure(const amessage: pdbusmessage; + const data: pointer; var handled: boolean) of object; + //default false + + idbusservice = interface; + + idbusobject = interface(inullinterface) + function getinstance: tobject; + procedure registeritems(const sender: idbusservice); + function getpath(): string; + function getintrospecttext(const aindent: int32): string; + procedure busconnected(); + end; + + idbusservice = interface(inullinterface) + procedure registerobject(const sender: idbusobject); + procedure unregisterobject(const sender: idbusobject); + procedure registermethodhandler(const ainterface: string; + const amember: string; const asignature: array of dbusdataty; + const ahandler: messagedataeventty; const adata: pointer); + + procedure registersignalhandler(const asender: string; const apath: string; + const ainterface: string; + const amember: string; const asignature: array of dbusdataty; + const ahandler: messagedataeventty; const adata: pointer); + end; + +type + watchinfoty = record + flags: pollflagsty; + id: int32; + watch: pdbuswatch; + end; + pwatchinfoty = ^watchinfoty; + + timeoutinfoty = record + timeout: pdbustimeout; + timer: tsimpletimer; + end; + ptimeoutinfoty = ^timeoutinfoty; + + pendinginfoty = record + pendingpo: pdbuspendingcall; + serial: card32; + link: hashoffsetty; + prev: hashoffsetty; + next: hashoffsetty; + end; + ppendinginfoty = ^pendinginfoty; + + linkinfoty = record + link: idbusclient; + pendingoffs: hashoffsetty; //chain + end; + plinkinfoty = ^linkinfoty; + + objinfoty = record + prev: hashoffsetty; + next: hashoffsetty; + obj: idbusobject; +// path: pointer; //string +// items: pointer; //stringarty + handlers: pointer; //hashoffsetarty + end; + pobjinfoty = ^objinfoty; + + itemkindty = (dbk_watch,dbk_timeout,dbk_pending,dbk_link,dbk_obj); + + dbusinfoty = record + case kind: itemkindty of + dbk_watch: (watch: watchinfoty); + dbk_timeout: (timeout: timeoutinfoty); + dbk_pending: (pending: pendinginfoty); + dbk_link: (link: linkinfoty); + dbk_obj: (obj: objinfoty); + end; + pdbusinfoty = ^dbusinfoty; + dbusitemty = record + key: pointer; + data: dbusinfoty; + end; + pdbusitemty = ^dbusitemty; + dbusitemhashdataty = record + header: hashheaderty; + data: dbusitemty; + end; + pdbusitemhashdataty = ^dbusitemhashdataty; + + tdbusservice = class; + + tdbusitemhashdatalist = class(tpointerhashdatalist,iobjectlink) + private + fwatches: card32arty; + funlinking: boolean; + fserial: card32; + protected + fowner: tdbusservice; + fobjects: hashoffsetty; //chain + flastobject: hashoffsetty; + procedure finalizeitem(const aitem: phashdataty) override; + procedure dopollcallback(const aflags: pollflagsty; const adata: pointer); + function findwatch(const key: pdbuswatch): pwatchinfoty; + function findtimeout(const key: pdbustimeout): ptimeoutinfoty; + function findpending(const key: pdbuspendingcall): ppendinginfoty; + + //iobjectlink + procedure link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); + procedure unlink(const source,dest: iobjectlink; valuepo: pointer = nil); + //source = 1 -> dest destroyed + procedure objevent(const sender: iobjectlink; const event: objecteventty); + function getinstance: tobject; + function getrecordsize(): int32 override; + public + constructor create(const aowner: tdbusservice); + function addwatch(const key: pdbuswatch): pwatchinfoty; + function addlink(const alink: idbusclient; + const apending: hashoffsetty): plinkinfoty; + function addpending(const apending: pdbuspendingcall; + const alink: idbusresponse; + var aserial: card32): ppendinginfoty; + function addobject(const aobj: idbusobject): pobjinfoty; +// function addpending(const aitem: pdbuspendingcall): ppendinginfoty; +// procedure freeitems(); + procedure handlewatches(); + end; + + handlerkindty = (hk_none,hk_match,hk_method,hk_signal); + + signaldataty = record + match: hashoffsetty; + prev: hashoffsetty; + next: hashoffsetty; + end; + handlerhandlerdataty = record + handler: messagedataeventty; + datapo: pointer; + case handlerkindty of + hk_signal: (signal: signaldataty); + end; + handlermatchdataty = record + match: identty; + refcount: int32; + end; + + handlerdataty = record + case kind: handlerkindty of + hk_match: + (match: handlermatchdataty); + hk_method,hk_signal: + (handler: handlerhandlerdataty); + end; + handlerhashdataty = record + header: treeelementhashdataty; + data: handlerdataty; + end; + phandlerhashdataty = ^handlerhashdataty; + + thandlerhashdatalist = class(thashtree) + private + fstringidents: tstringidents; + femptystringid: identty; + protected + fowner: tdbusservice; + function getrecordsize(): int32 override; + procedure finalizeitem(const aitem: phashdataty) override; + + public + constructor create(const aowner: tdbusservice); + destructor destroy(); override; + function scanpath(var avec: identvecty; + const apath: pchar; const aseparator: char): boolean; + //true if ok, too many levels otherwise + function addmethod(const aobject,ainterface,amember,asignature: string; + out adata: phandlerhashdataty): hashoffsetty; + function findmethod(const aobject,ainterface,amember, + asignature: pchar): phandlerhashdataty; + function addsignal( + const asender,apath,ainterface,amember,asignature: string; + out adata: phandlerhashdataty): hashoffsetty; + function findsignal(const asender,apath,ainterface,amember, + asignature: pchar): phandlerhashdataty; + end; + + tdbusservice = class(tlinkedobject,idbusservice,idbusobject) + private + fconn: pdbusconnection; + ferr: dbuserror; + fbusid: string; + fbusname: string; + fitems: tdbusitemhashdatalist; + fregisteringobj: pobjinfoty; + fregisteringpath: string; + fhandlers: thandlerhashdatalist; +// fwatches: array of pwatchinfoty; +// ftimeouts: array of ptimeoutinfoty; +// fpendings: array of ppendinfoty; + protected + procedure disconnect(); + function doaddwatch(const awatch: pdbuswatch): int32; + procedure dowatchtoggled(const awatch: pdbuswatch); + procedure doremovewatch(const awatch: pdbuswatch); + function doaddtimeout(const atimeout: pdbustimeout): int32; + procedure dotimeouttoggled(const atimeout: pdbustimeout); + procedure doremovetimeout(const atimeout: pdbustimeout); + procedure updatewatch(const awatch: pdbuswatch); + procedure updatetimeout(const atimeout: pdbustimeout); + procedure dotimer(const sender: tobject); + function err(): pdbuserror; + function checkok(): boolean; + procedure raisedbuserror(); + procedure doidle(var again: boolean); + procedure dopendingcallback(pending: pDBusPendingCall{; user_data: pointer}); + procedure setupmessage(const amessage: pdbusmessage; + const params: array of variantvaluety); + function methodcall(const bus_name,path,iface,method: string; + const params: array of variantvaluety): pdbusmessage; + procedure dounregisterobj(const aobj: pobjinfoty); + procedure doregisteritems(const aobj: pobjinfoty); + procedure dounregisteritems(const aobj: pobjinfoty); + procedure unregisteritem(const apath: string); + procedure mainfilter(const amessage: pdbusmessage; var handled: boolean); + procedure registerobjects(); + procedure unregisterobjects(); + function checkconnect(): boolean; + procedure introspect(const amessage: pdbusmessage; const adata: pointer; + var ahandled: boolean); + + //idbusobject for rootobject + procedure registeritems(const sender: idbusservice); + function getpath(): string; + function getintrospecttext(const aindent: int32): string; + procedure busconnected(); + + public + constructor create(); + destructor destroy(); override; + function connected: boolean; + function connect: boolean; + //idbusservice + procedure registerobject(const sender: idbusobject); + procedure unregisterobject(const sender: idbusobject); + procedure registermethodhandler(const ainterface: string; + const amember: string; const asignature: array of dbusdataty; + const ahandler: messagedataeventty; const adata: pointer); + procedure registersignalhandler(const asender: string; const apath: string; + const ainterface: string; + const amember: string; const asignature: array of dbusdataty; + const ahandler: messagedataeventty; const adata: pointer); + function dbuscallmethod(const returnedto: idbusresponse; var aserial: card32; + const bus_name,path,iface,method: string; + const params: array of variantvaluety; + const timeout: int32 = -1): boolean; //true if ok + function dbuscallmethod(const bus_name,path,iface,method: string; + const params: array of variantvaluety; + const resulttypes: array of dbusdataty; + const results: array of pointer; + const timeout: int32 = -1): boolean; //blocking, true if ok + function dbusreadmessage(const amessage: pdbusmessage; + const resulttypes: array of dbusdataty; + const results: array of pointer; + const apartial: boolean = false): boolean; + //true if ok + function dbusgetproperty(const bus_name,path,iface,property_name: string; + const resulttypes: array of dbusdataty; + const results: array of pointer; + const timeout: int32 = -1): boolean; //blocking, true if ok + function dbusreply(const amessage: pdbusmessage; + const params: array of variantvaluety): boolean; + function dbuserror(const amessage: pdbusmessage; + const aname: string; const atext: string): boolean; + function dbussignal(const path,iface,name: string; + const params: array of variantvaluety): boolean; + property dbusid: string read fbusid; + property dbusname: string read fbusname; + end; + +{$typeinfo on} + tdbusobject = class(teventobject,idbusobject) + protected + fservice: tdbusservice; + function getpropvalue(const aprop: ppropinfo; + out avalue: variantvaluety): boolean; + procedure introspect(const amessage: pdbusmessage; const adata: pointer; + var ahandled: boolean); + procedure propget(const amessage: pdbusmessage; const adata: pointer; + var ahandled: boolean); + procedure propset(const amessage: pdbusmessage; const adata: pointer; + var ahandled: boolean); + procedure propgetall(const amessage: pdbusmessage; const adata: pointer; + var ahandled: boolean); + function getintrospectitems(): string virtual; + function getpropintf: string virtual; + function rootpath: string; + procedure propchangesignal(const amember: string); + + procedure propertyget(const amessage: pdbusmessage; + const aname: string; var avalue: variantvaluety) virtual; + procedure propertiesget(var props: dictentryarty) virtual; + procedure propertyset(const amessage: pdbusmessage; + const aname: string; var ahandled: boolean) virtual; + //idbusobject + procedure registeritems(const sender: idbusservice) virtual; + function getpath(): string virtual; + function getintrospecttext(const aindent: int32): string virtual; + procedure busconnected() virtual; + public + constructor create(const aservice: tdbusservice); + destructor destroy(); override; + end; +{$typeinfo off} + +var + dbuslasterror: string; +{ +function dbusconnect(): boolean; //true if ok +procedure dbusdisconnect(); +function dbusid(): string; +function dbusname(): string; + +function dbuscallmethod(const returnedto: idbusresponse; var serial: card32; + const bus_name,path,iface,method: string; + const paramtypes: array of dbusdataty; + const params: array of pointer; + const timeout: int32 = -1): boolean; //true if ok +function dbusreadmessage(const amessage: pdbusmessage; + const resulttypes: array of dbusdataty; + const results: array of pointer): boolean; //true if ok +function dbuscallmethod(const bus_name,path,iface,method: string; + const paramtypes: array of dbusdataty; + const params: array of pointer; + const resulttypes: array of dbusdataty; + const results: array of pointer; + const timeout: int32 = -1): boolean; //blocking, true if ok +procedure dbusreply(const amessage: pdbusmessage; + const paramtypes: array of dbusdataty; + const params: array of pointer); +} +{$ifdef mse_dumpdbus} +function dbusdumpmessage(const amessage: pdbusmessage): string; +{$endif} + +procedure additem(var dest: dbusdatatyarty; const value: dbusdataty); +procedure additem(var dest: variantvaluearty; const value: variantvaluety); + +procedure setvariantvalue(const avalue: string; var avariant: variantvaluety; + const aflags: variantflagsty = []); +function variantvalue(const avalue: string; + const aflags: variantflagsty = []): variantvaluety; +procedure setvariantvalue(const avalue: int32; var avariant: variantvaluety; + const aflags: variantflagsty = []); +function variantvalue(const avalue: int32; + const aflags: variantflagsty = []): variantvaluety; +procedure setvariantvalue(const avalue: card32; var avariant: variantvaluety; + const aflags: variantflagsty = []); +function variantvalue(const avalue: card32; + const aflags: variantflagsty = []): variantvaluety; +procedure setvariantvalue(const avaluead: pointer; const atypeinfo: ptypeinfo; + var avariant: variantvaluety; const aflags: variantflagsty = []); +function variantvalue(const avaluead: pointer; const atypeinfo: ptypeinfo; + const aflags: variantflagsty = []): variantvaluety; + +function itemtypeinfo(const dynartypeinfo: ptypeinfo): ptypeinfo; +function dbusdatastring(const atypeinfo: ptypeinfo): string; + +implementation +uses + msestrings,msesysintf,mseguiintf, + msefloattostr,mseapplication,msearrayutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + lineend = c_linefeed; + + peerintf = +''+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend; + + introspectintf = +''+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend; + + propertiesintf = +''+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend; + +{ +type + userdatarecty = record + service: tdbusservice; + data: pointer; + end; + puserdatarecty = ^userdatarecty; +} +var +// conn: pdbusconnection; +// ferr: dbuserror; +// busid: string; +// busname: string; +// fdbc: tdbusservice; + dbuslibinited: boolean; + nextidnumber: card16; +// userdatacache: linklistty; + dbusalignments: array[dbusdataty] of int32; + +function initdbuslib(): boolean; +begin + result:= true; + if not dbuslibinited then begin + result:= initializedbus([]); + if result then begin + dbuslibinited:= true; + end; + end; +end; + +procedure raiseerror(const message: string); +begin + raise edbus.create(message); +end; + +procedure error(const message: string); +begin + dbuslasterror:= message; +end; + +procedure outofmemory(); +begin + error('Out of memory'); +end; + +function itemtypeinfo(const dynartypeinfo: ptypeinfo): ptypeinfo; +begin + result:= ptypeinfo(gettypedata(dynartypeinfo)^.eltype2); +end; + +procedure additem(var dest: dbusdatatyarty; const value: dbusdataty); +begin + setlength(dest,high(dest)+2); + dest[high(dest)]:= value; +end; + +procedure additem(var dest: variantvaluearty; const value: variantvaluety); +begin + setlength(dest,high(dest)+2); + dest[high(dest)]:= value; +end; + +function getsignature(const asignature: array of dbusdataty): string; +var + i1: int32; +begin + result:= ''; + for i1:= 0 to high(asignature) do begin + result:= result + dbusdatastrings[asignature[i1]]; + end; +end; + +function indent(const atext: string; const aindent: int32): string; +var + p1,p2: pchar; + s1: string; +begin + result:= ''; + if atext <> '' then begin + s1:= charstring(' ',2*aindent); + p1:= pchar(atext); + while p1^ <> #0 do begin + p2:= p1; + while (p1^ <> #0) and (p1^ <> c_linefeed) do begin + inc(p1); + end; + if p1^ <> #0 then begin + inc(p1); + end; + result:= result+s1+psubstr(p2,p1); + end; + end; +end; + +function dbuspath(const apath: string): string; +var + i1: int32; +begin + result:= apath; + i1:= length(result); + if (i1 > 1) and (result[i1] = '/') then begin + setlength(result,i1-1); //remove trailing '/' + end; +end; + +(* +function checkconnect(): boolean; +begin + result:= (fdbc <> nil) and fdbc.connected; +end; + +function dbuscontroller(): tdbusservice; +begin + if fdbc = nil then begin + fdbc:= tdbusservice.create; + end; + result:= fdbc; +end; + +function dbusconnect(): boolean; //true if ok +begin + result:= dbuscontroller.connect(); +end; + +procedure dbusdisconnect(); +begin + if fdbc <> nil then begin + fdbc.disconnect(); + end; +end; + +function dbusid(): string; +begin + result:= ''; + if checkconnect() then begin + result:= fdbc.fbusid; + end; +end; + +function dbusname(): string; +begin + result:= ''; + if checkconnect() then begin + result:= fdbc.fbusname; + end; +end; + +function dbuscallmethod(const returnedto: idbusresponse; var serial: card32; + const bus_name,path,iface,method: string; + const paramtypes: array of dbusdataty; + const params: array of pointer; + const timeout: int32 = -1): boolean; //true if ok +begin + result:= false; + if checkconnect() then begin + result:= fdbc.dbuscallmethod(returnedto,serial,bus_name,path,iface,method, + paramtypes,params,timeout); + end; +end; +*) +{$ifdef mse_dumpdbus} +function dbusdumpmessage(const amessage: pdbusmessage): string; +var + level: int32; + + function nilstr(const astr: pcchar): string; + begin + if astr = nil then begin + result:= 'NIL'; + end + else begin + result:= string(astr); + end; + end; //nilstr + + function dumptype(const t: int32): string; + begin + case t of + DBUS_TYPE_INVALID: result:= ''; + DBUS_TYPE_BYTE: result:= 'BYTE'; + DBUS_TYPE_BOOLEAN: result:= 'BOOLEAN'; + DBUS_TYPE_INT16: result:= 'INT16'; + DBUS_TYPE_UINT16: result:= 'UINT16'; + DBUS_TYPE_INT32: result:= 'INT32'; + DBUS_TYPE_UINT32: result:= 'UINT32'; + DBUS_TYPE_INT64: result:= 'INT64'; + DBUS_TYPE_UINT64: result:= 'UINT64'; + DBUS_TYPE_DOUBLE: result:= 'DOUBLE'; + DBUS_TYPE_STRING: result:= 'STRING'; + DBUS_TYPE_OBJECT_PATH: result:= 'OBJECT_PATH'; + DBUS_TYPE_SIGNATURE: result:= 'SIGNATURE'; + DBUS_TYPE_UNIX_FD: result:= 'UNIX_FD'; + DBUS_TYPE_ARRAY: result:= 'ARRAY'; + DBUS_TYPE_VARIANT: result:= 'VARIANT'; + DBUS_TYPE_STRUCT: result:= 'STRUCT'; + DBUS_TYPE_DICT_ENTRY: result:= 'DICT_ENTRY'; + end; + end; + + function dumpdata(const t: int32; iterpo: pdbusmessageiter): string; + var + b1: byte; + bool1: dbus_bool_t; + i16: int16; + c16: card16; + i32: int32; + c32: card32; + i64: int64; + c64: card64; + f64: flo64; + pc1: pcchar; + + begin + result:= ''; + case t of + DBUS_TYPE_INVALID: begin end; + DBUS_TYPE_BYTE: begin + dbus_message_iter_get_basic(iterpo,@b1); + result:= inttostr(b1); + end; + DBUS_TYPE_BOOLEAN: begin + dbus_message_iter_get_basic(iterpo,@bool1); + result:= inttostr(bool1); + end; + DBUS_TYPE_INT16: begin; + dbus_message_iter_get_basic(iterpo,@i16); + result:= inttostr(i16); + end; + DBUS_TYPE_UINT16: begin + dbus_message_iter_get_basic(iterpo,@c16); + result:= inttostr(c16); + end; + DBUS_TYPE_INT32: begin + dbus_message_iter_get_basic(iterpo,@i32); + result:= inttostr(i32); + end; + DBUS_TYPE_UINT32: begin + dbus_message_iter_get_basic(iterpo,@c32); + result:= inttostr(c32); + end; + DBUS_TYPE_INT64: begin + dbus_message_iter_get_basic(iterpo,@i64); + result:= inttostr(i64); + end; + DBUS_TYPE_UINT64: begin + dbus_message_iter_get_basic(iterpo,@c64); + result:= inttostr(c64); + end; + DBUS_TYPE_DOUBLE: begin + dbus_message_iter_get_basic(iterpo,@f64); + result:= string(doubletostring(f64,-1)); + end; + DBUS_TYPE_STRING, + DBUS_TYPE_OBJECT_PATH, + DBUS_TYPE_SIGNATURE: begin + dbus_message_iter_get_basic(iterpo,@pc1); + result:= '"'+string(pc1)+'"'; + end; + DBUS_TYPE_UNIX_FD: begin end; + DBUS_TYPE_ARRAY: begin end; + DBUS_TYPE_VARIANT: begin end; + DBUS_TYPE_STRUCT: begin end; + DBUS_TYPE_DICT_ENTRY: begin end; + end; + end; + + function readvalue(var aiter: dbusmessageiter): string; + var + i1,i2: int32; + iter2,iter3: dbusmessageiter; + iterpo: pdbusmessageiter; + first: boolean; + s1,s2: string; + label + endlab; + begin + inc(level); + s2:= charstring(' ',level); + result:= s2; + iterpo:= @aiter; + i1:= dbus_message_iter_get_arg_type(iterpo); + if i1 = DBUS_TYPE_INVALID then begin + goto endlab; + end; + if i1 = DBUS_TYPE_VARIANT then begin + dbus_message_iter_recurse(@aiter,@iter3); + iterpo:= @iter3; + i1:= dbus_message_iter_get_arg_type(iterpo); //nested variants? + end; + case i1 of + DBUS_TYPE_ARRAY: begin + i2:= dbus_message_iter_get_element_type(iterpo); + dbus_message_iter_recurse(iterpo,@iter2); + result:= dumptype(i2)+'['; + first:= true; + while dbus_message_iter_get_arg_type(@iter2) <> DBUS_TYPE_INVALID do begin + s1:= readvalue(iter2); + if s1 = '' then begin + if not first then begin + setlength(result,length(result)-1); //remove last comma + end; + result:= result+']'; + break; + end + else begin + result:= result+s1+','; + end; + first:= false; + end; + end; //array +// DBUS_TYPE_VARIANT, //todo +// DBUS_TYPE_STRUCT, +// DBUS_TYPE_DICT_ENTRY + else begin + result:= result+dumptype(i1)+' '+dumpdata(i1,iterpo); + end; + end; + dbus_message_iter_next(@aiter); + +endlab: + if result <> s2 then begin + result:= result+lineend; + end + else begin + result:= ''; + end; + end;//readvalue + +var + iter1: dbusmessageiter; + s1: string; + +begin + level:= 0; + result:= '*'; + if amessage = nil then begin + result:= result+'NIL'; + end + else begin + dbus_message_iter_init(amessage,@iter1); + case dbus_message_get_type(amessage) of + DBUS_MESSAGE_TYPE_INVALID: begin + result:= result+'INVALID'; + end; + DBUS_MESSAGE_TYPE_METHOD_CALL: begin + result:= result+'METHODCALL'; + end; + DBUS_MESSAGE_TYPE_METHOD_RETURN: begin + result:= result+'METHOD_RETURN'; + end; + DBUS_MESSAGE_TYPE_ERROR: begin + result:= result+'ERROR'; + end; + DBUS_MESSAGE_TYPE_SIGNAL: begin + result:= result+'SIGNAL'; + end; + end; + result:= result+' '+nilstr(dbus_message_get_destination(amessage))+' '+ + nilstr(dbus_message_get_path(amessage))+' '+ + nilstr(dbus_message_get_interface(amessage))+' '+ + nilstr(dbus_message_get_member(amessage))+' '+lineend; + repeat + s1:= readvalue(iter1); + result:= result+s1; + until s1 = ''; + end; +end; +{$endif} +(* +function dbusreadmessage(const amessage: pdbusmessage; + const resulttypes: array of dbusdataty; + const results: array of pointer): boolean; //true if ok +begin + result:= false; + if checkconnect() then begin + result:= fdbc.readmessage(amessage,resulttypes,results); + end; +end; + +function dbuscallmethod(const bus_name,path,iface,method: string; + const paramtypes: array of dbusdataty; + const params: array of pointer; + const resulttypes: array of dbusdataty; + const results: array of pointer; + const timeout: int32 = -1): boolean; //blocking, true if ok +begin + result:= false; + if checkconnect() then begin + result:= fdbc.dbuscallmethod(bus_name,path,iface,method,paramtypes,params, + resulttypes,results,timeout); + end; +end; + +procedure dbusreply(const amessage: pdbusmessage; + const paramtypes: array of dbusdataty; + const params: array of pointer); +begin + if checkconnect() then begin + fdbc.reply(amessage,paramtypes,params); + end; +end; +*) +function addwatch(watch: pDBusWatch; data: pointer): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; +begin + result:= tdbusservice(data).doaddwatch(watch); +end; + +procedure watchtoggled(watch: pDBusWatch; data: pointer) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; +begin + tdbusservice(data).dowatchtoggled(watch); +end; + +procedure removewatch(watch: pDBusWatch; data: pointer) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; +begin + tdbusservice(data).doremovewatch(watch); +end; + +function addtimeout(timeout: pDBusTimeout; data: pointer): dbus_bool_t + {$ifdef wincall}stdcall{$else}cdecl{$endif}; +begin + result:= tdbusservice(data).doaddtimeout(timeout); +end; + +procedure timeouttoggled(timeout: pDBusTimeout; data: pointer) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; +begin + tdbusservice(data).dotimeouttoggled(timeout); +end; + +procedure removetimeout(timeout: pDBusTimeout; data: pointer) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; +begin + tdbusservice(data).doremovetimeout(timeout); +end; + +procedure pendingcallback(pending: pDBusPendingCall; user_data: pointer) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; +begin +// if fdbc <> nil then begin +{$ifdef mse_debugdbus} + writeln('**pendingcallback'); +{$endif} + tdbusservice(user_data).dopendingcallback(pending); +{ + with puserdatarecty(getlistitem(userdatacache,ptruint(user_data)))^ do begin + service.dopendingcallback(pending,data); + end; +} +end; +{ +procedure pollcallback(const aflags: pollflagsty; const adata: pointer); +begin +// if fdbc <> nil then begin + with puserdatarecty(getlistitem(userdatacache,ptruint(adata)))^ do begin + service.fitems.dopollcallback(aflags,data); + end; +end; +} + +function aligntoptr(const p: pointer): pointer; inline; +begin +{$ifdef FPC_REQUIRES_PROPER_ALIGNMENT} + result:=align(p,sizeof(p)); +{$else FPC_REQUIRES_PROPER_ALIGNMENT} + result:=p; +{$endif FPC_REQUIRES_PROPER_ALIGNMENT} +end; + +procedure alignandstep(const atype: dbusdataty; var adataad: pointer); +var + pu1: ptruint; +begin + pu1:= dbusalignments[atype]-1; + adataad:= pointer((ptruint(adataad)+pu1) and not pu1) + //align + dbusdatasizes[atype]; +end; + +procedure align(const atype: dbusdataty; var adataad: pointer); +var + pu1: ptruint; +begin + pu1:= dbusalignments[atype]-1; + adataad:= pointer((ptruint(adataad)+pu1) and not pu1); +end; + +const + inttypestrings: array[tordtype] of string = ( + //otSByte, otUByte, + DBUS_TYPE_BYTE_AS_STRING,DBUS_TYPE_BYTE_AS_STRING, + //otSWord, otUWord, + DBUS_TYPE_INT16_AS_STRING,DBUS_TYPE_UINT16_AS_STRING, + //otSLong, otULong + DBUS_TYPE_INT32_AS_STRING,DBUS_TYPE_UINT32_AS_STRING +{$ifdef mse_fpc_3_2} + //otSQWord, otUQWord + ,DBUS_TYPE_INT64_AS_STRING,DBUS_TYPE_UINT64_AS_STRING +{$endif} + ); +type +{$ifdef mse_fpc_3_0} + precordtypedata = ptypedata; +{$else} + recordtypedata = + {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT} + packed + {$endif} + record + case TTypeKind of + tkrecord: ( + RecSize: Integer; + ManagedFldCount: Integer; + {ManagedFields: array[1..ManagedFldCount] of TManagedField} + ); + end; + precordtypedata = ^recordtypedata; + PManagedField = ^TManagedField; + TManagedField = + {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT} + packed + {$endif} + record + TypeRef: PTypeInfo; + {$ifdef mse_fpc_3_0} + FldOffset: SizeInt; + {$else} + FldOffset: longint; + {$endif} + end; +{$endif} + +function dbusdatastring(const atypeinfo: ptypeinfo): string; +var + p1: ptypedata; + p2,pe: pmanagedfield; +begin + result:= ''; + p1:= gettypedata(atypeinfo); + case atypeinfo^.kind of + tkdynarray: begin + result:= 'a'+dbusdatastring(ptypeinfo(p1^.eltype2)); + end; + tkrecord: begin + result:= '('; + p2:= aligntoptr(pointer(@precordtypedata(p1)^. + {$ifdef mse_fpc_3_2}totalfieldcount{$else}managedfldcount{$endif})+ + sizeof(precordtypedata(p1)^. + {$ifdef mse_fpc_3_2}totalfieldcount{$else}managedfldcount{$endif})); + pe:= p2+precordtypedata(p1)^. + {$ifdef mse_fpc_3_2}totalfieldcount{$else}managedfldcount{$endif}; + while p2 < pe do begin + result:= result+dbusdatastring(p2^.typeref); + inc(p2); + end; + result:= result+')'; + end; + tkinteger: begin + result:= inttypestrings[p1^.ordtype]; + end; + tkastring: begin + result:= 's'; + end; + else begin + raiseerror('type not supported'); + end; + end; +end; + +{$ifdef mse_debugvariant} +var + variantlevel: int32; +{$endif} + +function dbusdatastring(const avalue: variantvaluety): string; +var + p1,pe: pvariantvaluety; +begin +{$ifdef mse_debugvariant} + inc(variantlevel); + writeln('**dbusdatastring:',variantlevel,':',avalue.kind); +{$endif} + case avalue.kind of + vvk_string: begin + result:= dbusdatastrings[dbt_string]; + end; + vvk_int32: begin + result:= dbusdatastrings[dbt_int32]; + end; + vvk_dynar: begin + result:= dbusdatastring(avalue.vdynar.typinfo); + end; + vvk_variantar: begin + result:= dbusdatastring(avalue.vvariantar.typinfo); + end; + vvk_record: begin + result:= '('; + p1:= avalue.vvariantar.data; + pe:= p1 + length(variantvaluearty(avalue.vvariantar.data)); + {$ifdef mse_debugvariant} + writeln('*recordcount:',variantlevel,':',pe-p1); + {$endif} + while p1 < pe do begin + result:= result+dbusdatastring(p1^); + inc(p1); + end; + result:= result+')'; + end; + else begin + raiseerror('type not supported'); + end; + end; +{$ifdef mse_debugvariant} + writeln('*dbusdatastring:',variantlevel,':',result); + dec(variantlevel); +{$endif} +end; + +const + inttypes: array[tordtype] of dbusdataty = ( + //otSByte, otUByte, + dbt_byte,dbt_byte, + //otSWord, otUWord, + dbt_int16,dbt_uint16, + //otSLong, otULong + dbt_int32,dbt_uint32 +{$ifdef mse_fpc_3_2} + //otSQWord, otUQWord + ,dbt_int64,dbt_uint64 +{$endif} + ); + +procedure stackarray(const source: dbusdatatyarty; var dest: dbusdatatyarty); +var + i1: int32; +begin + i1:= length(dest); + setlength(dest,i1+length(source)); + move(source[0],dest[i1],length(source)*sizeof(source[0])); +end; + +function dbusdatatypes(const atypeinfo: ptypeinfo): dbusdatatyarty; +var + p1: ptypedata; + p2,pe: pmanagedfield; +begin + setlength(result,1); + p1:= gettypedata(atypeinfo); + case atypeinfo^.kind of + tkdynarray: begin + result[0]:= dbt_array; + stackarray(dbusdatatypes(ptypeinfo(p1^.eltype2)),result); + end; + tkrecord: begin + result[0]:= dbt_struct; + p2:= aligntoptr(pointer(@precordtypedata(p1)^. + {$ifdef mse_fpc_3_2}totalfieldcount{$else}managedfldcount{$endif})+ + sizeof(precordtypedata(p1)^. + {$ifdef mse_fpc_3_2}totalfieldcount{$else}managedfldcount{$endif})); + pe:= p2+precordtypedata(p1)^. + {$ifdef mse_fpc_3_2}totalfieldcount{$else}managedfldcount{$endif}; + while p2 < pe do begin + stackarray(dbusdatatypes(p2^.typeref),result); + inc(p2); + end; + setlength(result,high(result)+2); + result[high(result)]:= dbt_structend; + end; + tkinteger: begin + result[0]:= inttypes[p1^.ordtype]; + end; + tkastring: begin + result[0]:= dbt_string; + end; + else begin + raiseerror('type not supported'); + end; + end; +end; +{ +function dbusdatastring(const atype: dbusdataty; var adataad: pointer): string; +var + i1: int32; + p1: pointer; +begin + align(atype,adataad); + case atype of + dbt_msevariant: begin + result:= ''; + with pvariantvaluety(adataad)^ do begin + case kind of + vvk_dynar: begin + result:= dbusdatastring(vdynar.typinfo); + end; + vvk_record: begin + result:= dbusdatastring(vrecord.typinfo); + end; + else begin + p1:= nil; + result:= dbusdatastring(types[0],p1); //simple type + end; + end; + end; + end; + else begin //structs, dictentries? + result:= dbusdatastrings[atype]; + end; + end; + adataad:= adataad + dbusdatasizes[atype]; +end; +} +procedure finalizevariantvalue(var avariant: variantvaluety); +var + p1: pvariantvaluety; + pe: pointer; +begin + with avariant do begin + case kind of + vvk_variantar,vvk_record: begin + p1:= vvariantar.data; + pe:= p1 + length(variantvaluearty(vvariantar.data)); + while p1 < pe do begin + finalizevariantvalue(p1^); + inc(p1); + end; + variantvaluearty(vvariantar.data):= nil; + end; +// vvk_string: begin +// string(vstring):= ''; +// end; + end; + end; +end; + +procedure finalizedictentryar(var adict: dictentryarty); +var + p1,pe: pdictentryty; +begin + p1:= pointer(adict); + pe:= p1 + length(adict); + while p1 < pe do begin + finalizevariantvalue(p1^.value); + inc(p1); + end; +end; + +procedure setvariantvalue(const avalue: string; var avariant: variantvaluety; + const aflags: variantflagsty = []); +begin + with avariant do begin + kind:= vvk_string; + flags:= aflags; +// setlength(types,1); +// types[0]:= dbt_string; + vstring:= pchar(avalue); +// vstring:= nil; +// string(vstring):= avalue; + end; +end; + +function variantvalue(const avalue: string; + const aflags: variantflagsty = []): variantvaluety; +begin + setvariantvalue(avalue,result,aflags); +end; + +procedure setvariantvalue(const avalue: int32; var avariant: variantvaluety; + const aflags: variantflagsty = []); +begin + with avariant do begin + kind:= vvk_int32; + flags:= aflags; + vint32:= avalue; + end; +end; + +function variantvalue(const avalue: int32; + const aflags: variantflagsty = []): variantvaluety; +begin + setvariantvalue(avalue,result,aflags); +end; + +procedure setvariantvalue(const avalue: card32; var avariant: variantvaluety; + const aflags: variantflagsty = []); +begin + with avariant do begin + kind:= vvk_card32; + flags:= aflags; + vcard32:= avalue; + end; +end; + +function variantvalue(const avalue: card32; + const aflags: variantflagsty = []): variantvaluety; +begin + setvariantvalue(avalue,result,aflags); +end; + +{ +procedure setvariantdynarvalue(const avalue: pointer; + const atypeinfo: ptypeinfo; var avariant: variantvaluety; + const aflags: variantflagsty = []); +begin + with avariant do begin + kind:= vvk_dynar; + flags:= aflags; +// types:= dbusdatatypes(atypeinfo); + vdynar.data:= avalue; + vdynar.typinfo:= atypeinfo; + end; +end; + +function variantdynarvalue(const avalue: pointer; const atypeinfo: ptypeinfo; + const aflags: variantflagsty = []): variantvaluety; +begin + setvariantdynarvalue(avalue,atypeinfo,result,aflags); +end; +} + +procedure setvariantvalue(const avaluead: pointer; const atypeinfo: ptypeinfo; + var avariant: variantvaluety; const aflags: variantflagsty = []); +var + pt: ptypedata; + p1: pmanagedfield; + pe: pointer; + pvalue: pvariantvaluety; + pvar: pvariantvaluety; + p2: pointer; +begin +{$ifdef mse_debugvariant} +inc(variantlevel); +writeln('**setvariantvalue:',variantlevel,':',atypeinfo^.name, + ' ',atypeinfo^.kind); +{$endif} + + pt:= gettypedata(atypeinfo); + with avariant do begin + flags:= aflags; + case atypeinfo^.kind of + tkastring: begin + setvariantvalue(pstring(avaluead)^,avariant,aflags); + end; + tkinteger: begin + if pt^.ordtype <> otslong then begin + raiseerror('Invalid ord type'); + end; + setvariantvalue(pint32(avaluead)^,avariant,aflags); + end; + tkdynarray: begin + kind:= vvk_dynar; + case ptypeinfo(pt^.eltype2)^.kind of + tkrecord: begin + if vf_dict in aflags then begin + vdynar.data:= ppointer(avaluead)^; + vdynar.typinfo:= atypeinfo; + end + else begin + kind:= vvk_variantar; //needs finalize + vvariantar.typinfo:= atypeinfo; + vvariantar.data:= nil; + p2:= ppointer(avaluead)^; + setlength(variantvaluearty(vvariantar.data), + dynarraylength(p2)); + pvar:= vvariantar.data; + pe:= pvar + dynarraylength(p2); + while pvar < pe do begin + setvariantvalue(p2,ptypeinfo(pt^.eltype2),pvar^); + inc(pvar); + inc(p2,pt^.elsize); + end; + end; + end + else begin + vdynar.data:= ppointer(avaluead)^; + vdynar.typinfo:= atypeinfo; + end; + end; + end; + tkrecord: begin + kind:= vvk_record; + vvariantar.data:= nil; + setlength(variantvaluearty(vvariantar.data),precordtypedata(pt)^. + {$ifdef mse_fpc_3_2}totalfieldcount{$else}managedfldcount{$endif}); + p1:= aligntoptr(pointer(@precordtypedata(pt)^. + {$ifdef mse_fpc_3_2}totalfieldcount{$else}managedfldcount{$endif}) + + sizeof(precordtypedata(pt)^. + {$ifdef mse_fpc_3_2}totalfieldcount{$else}managedfldcount{$endif})); + pe:= p1+precordtypedata(pt)^. + {$ifdef mse_fpc_3_2}totalfieldcount{$else}managedfldcount{$endif}; + pvalue:= vvariantar.data; +{$ifdef mse_debugvariant} +writeln('*recordfieldcount:',variantlevel,':',pe-p1); +{$endif} + while p1 < pe do begin + setvariantvalue(avaluead+p1^.fldoffset,p1^.typeref,pvalue^); + inc(p1); + inc(pvalue); + end; +{$ifdef mse_debugvariant} +writeln('*endfields:',variantlevel); +{$endif} + end; + else begin + raiseerror('Invalid type'); + end; + end; + end; +{$ifdef mse_debugvariant} + dec(variantlevel); +{$endif} +end; + +function variantvalue(const avaluead: pointer; const atypeinfo: ptypeinfo; + const aflags: variantflagsty = []): variantvaluety; +begin + setvariantvalue(avaluead,atypeinfo,result,aflags); +end; +(* +procedure setvariantrecordvalue(const avalue: pointer; + atypeinfo: ptypeinfo; var avariant: variantvaluety); +var + pt: ptypedata; + p1,pe: pmanagedfield; + pvalue: pvariantvaluety; +begin + with avariant do begin + kind:= vvk_record; +// types:= dbusdatatypes(atypeinfo); + vrecord.data:= nil; +// vrecord.typinfo:= atypeinfo; + pt:= gettypedata(atypeinfo); + setlength(variantvaluearty(vrecord.data),pt^. + {$ifdef mse_fpc_3_2}totalfieldcount{$else}managedfldcount{$endif}); + p1:= aligntoptr(pointer(@pt^. + {$ifdef mse_fpc_3_2}totalfieldcount{$else}managedfldcount{$endif})+ + sizeof(pt^. + {$ifdef mse_fpc_3_2}totalfieldcount{$else}managedfldcount{$endif})); + pe:= p1+pt^.{$ifdef mse_fpc_3_2}totalfieldcount{$else}managedfldcount{$endif}; + pvalue:= vrecord.data; + while p1 < pe do begin + setvariantvalue(avalue+p1^.fldoffset,p1^.typeref,pvalue^); + inc(p1); + inc(pvalue); + end; + end; +end; + +function variantrecordvalue(const avaluead: pointer; + const atypeinfo: ptypeinfo): variantvaluety; +begin + setvariantrecordvalue(avaluead,atypeinfo,result); +end; +*) +{ tdbusitemhashdatalist } + +constructor tdbusitemhashdatalist.create(const aowner: tdbusservice); +begin + fowner:= aowner; + inherited create(); + include(fstate,hls_needsfinalize); +end; + +function tdbusitemhashdatalist.getrecordsize(): int32; +begin + result:= sizeof(dbusitemhashdataty); +end; + +function tdbusitemhashdatalist.addwatch(const key: pdbuswatch): pwatchinfoty; +var + p1: pdbusitemhashdataty; +begin + p1:= pdbusitemhashdataty(add(key)); + p1^.data.data.kind:= dbk_watch; + result:= @p1^.data.data.watch; + msearrayutils.additem(longwordarty(fwatches),getdataoffs(result)); + with result^ do begin + flags:= []; + watch:= key; + end; +end; + +function tdbusitemhashdatalist.addlink(const alink: idbusclient; + const apending: hashoffsetty): plinkinfoty; +var + p1,p2: pdbusitemhashdataty; +begin + p1:= pdbusitemhashdataty(find(alink)); + if p1 = nil then begin + p1:= pdbusitemhashdataty(add(alink)); + p1^.data.data.kind:= dbk_link; + alink.link(iobjectlink(pchar(alink)+1),iobjectlink(self)); + //create backlink + p1^.data.data.link.pendingoffs:= 0; + end; + result:= @p1^.data.data.link; + with result^ do begin + link:= alink; + if pendingoffs <> 0 then begin + p2:= getdatapo(pendingoffs); + p2^.data.data.pending.prev:= apending; + end; + p2:= getdatapo(apending); + p2^.data.data.pending.next:= pendingoffs; + p2^.data.data.pending.prev:= 0; + p2^.data.data.pending.link:= getdataoffs(p1); + pendingoffs:= apending; + end; +end; + +function tdbusitemhashdatalist.addpending(const apending: pdbuspendingcall; + const alink: idbusresponse; var aserial: card32): ppendinginfoty; +var + p1: pdbusitemhashdataty; +begin + p1:= pdbusitemhashdataty(add(apending)); + p1^.data.data.kind:= dbk_pending; + result:= @p1^.data.data.pending; + with result^ do begin + pendingpo:= apending; + inc(fserial); + if fserial = 0 then begin + inc(fserial); + end; + serial:= fserial; + aserial:= serial; + end; + addlink(alink,getdataoffs(p1)); +end; + +function tdbusitemhashdatalist.addobject( + const aobj: idbusobject): pobjinfoty; +var + p1: pdbusitemhashdataty; + o1: hashoffsetty; +begin + p1:= pdbusitemhashdataty(add(aobj)); + o1:= getdataoffs(p1); + if flastobject = 0 then begin + flastobject:= o1; + end; + p1^.data.data.kind:= dbk_obj; + result:= @p1^.data.data.obj; + with result^ do begin + obj:= aobj; +// path:= nil; +// items:= nil; + handlers:= nil; + prev:= 0; + next:= fobjects; + if fobjects <> 0 then begin + with pdbusitemhashdataty(getdatapo(fobjects))^.data.data.obj do begin + prev:= o1; + end; + end; + fobjects:= o1; + end; +end; + +procedure tdbusitemhashdatalist.finalizeitem(const aitem: phashdataty); +var + p1: pdbusitemhashdataty; + o1: hashoffsetty; +begin + with pdbusitemhashdataty(aitem)^.data do begin + case data.kind of + dbk_watch: begin + gui_removepollfd(data.watch.id); + removeitem(integerarty(fwatches),getdataoffs(@data.watch)); + end; + dbk_timeout: begin + data.timeout.timer.free; + end; + dbk_link: begin + if not funlinking then begin + data.link.link.unlink(iobjectlink(pchar(iobjectlink(self))+1), + data.link.link); + //remove backlink + end; + o1:= data.link.pendingoffs; + while o1 <> 0 do begin + p1:= getdatapo(o1); + with p1^.data.data.pending do begin + o1:= next; + link:= 0; + end; + end; + end; + dbk_pending: begin + with data.pending do begin + if prev <> 0 then begin + p1:= getdatapo(prev); + p1^.data.data.pending.next:= next; + end + else begin //first in pending chain + if link <> 0 then begin + p1:= getdatapo(link); + if next <> 0 then begin + p1^.data.data.link.pendingoffs:= next; + end + else begin + internaldelete(link); //empty pending chain + end; + end; + end; + dbus_pending_call_unref(pendingpo); + end; + end; + dbk_obj: begin + fowner.dounregisterobj(@data.obj); + with data.obj do begin + if next <> 0 then begin + with pdbusitemhashdataty(getdatapo(next))^.data.data do begin + obj.prev:= prev; + end; + end + else begin + flastobject:= prev; + end; + if prev <> 0 then begin + with pdbusitemhashdataty(getdatapo(prev))^.data.data do begin + obj.next:= next; + end; + end + else begin + fobjects:= next; + end; +// string(path):= ''; +// stringarty(items):= nil; + hashoffsetarty(handlers):= nil; + end; + end; + end; + end; +end; + +procedure tdbusitemhashdatalist.dopollcallback(const aflags: pollflagsty; + const adata: pointer); +var + p1: pdbusitemhashdataty; +begin + p1:= pdbusitemhashdataty(find(adata)); + if (p1 <> nil) and (p1^.data.data.kind = dbk_watch) then begin + //throw no exception +{$ifdef mse_debugdbus} + if p1^.data.data.watch.flags <> aflags then begin + writeln('**dopollcallback:',int32(aflags)); + end; +{$endif} + p1^.data.data.watch.flags:= p1^.data.data.watch.flags + aflags; + end; +end; + +function tdbusitemhashdatalist.findwatch(const key: pdbuswatch): pwatchinfoty; +begin + result:= pointer(find(key)); + if result = nil then begin + raiseerror('Watch not found'); + end; + if pdbusitemhashdataty(result)^.data.data.kind <> dbk_watch then begin + raiseerror('Invalid watch'); + end; + result:= @pdbusitemhashdataty(result)^.data.data.watch; +end; + +function tdbusitemhashdatalist.findtimeout( + const key: pdbustimeout): ptimeoutinfoty; +begin + result:= pointer(find(key)); + if result = nil then begin + raiseerror('Timeout not found'); + end; + if pdbusitemhashdataty(result)^.data.data.kind <> dbk_timeout then begin + raiseerror('Invalid timeout'); + end; + result:= @pdbusitemhashdataty(result)^.data.data.timeout; +end; + +function tdbusitemhashdatalist.findpending( + const key: pdbuspendingcall): ppendinginfoty; +begin + result:= pointer(find(key)); + if result = nil then begin + raiseerror('Pendingcall not found'); + end; + if pdbusitemhashdataty(result)^.data.data.kind <> dbk_pending then begin + raiseerror('Invalid pendingcall'); + end; + result:= @pdbusitemhashdataty(result)^.data.data.pending; +end; + +procedure tdbusitemhashdatalist.link(const source: iobjectlink; + const dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); +begin + //dummy +end; + +procedure tdbusitemhashdatalist.unlink(const source: iobjectlink; + const dest: iobjectlink; valuepo: pointer = nil); +begin + if not odd(ptruint(source)) then begin //full link + delete(source); + end; +end; + +procedure tdbusitemhashdatalist.objevent(const sender: iobjectlink; + const event: objecteventty); +begin + if event = oe_destroyed then begin + funlinking:= true; + delete(sender); + funlinking:= false; + end; +end; + +function tdbusitemhashdatalist.getinstance: tobject; +begin + result:= self; +end; + +const + watchflags: array[pollflagty] of card32 = ( + DBUS_WATCH_READABLE, //pf_in, //POLLIN = $001; + 0, //pf_pri, //POLLPRI = $002; + DBUS_WATCH_WRITABLE, //pf_out, //POLLOUT = $004; + DBUS_WATCH_ERROR, //pf_err, //POLLERR = $008; + DBUS_WATCH_HANGUP, //pf_hup, //POLLHUP = $010; + 0 //pf_nval //POLLNVAL = $020; + ); + +procedure tdbusitemhashdatalist.handlewatches(); +var + i1: int32; + c1: card32; + f1: pollflagty; +begin + for i1:= 0 to high(fwatches) do begin + with pwatchinfoty(getdatapo(fwatches[i1]))^ do begin + if flags <> [] then begin + c1:= 0; + for f1:= low(f1) to high(f1) do begin + if f1 in flags then begin + c1:= c1 or watchflags[f1]; + end; + end; + dbus_watch_handle(watch,c1); + end; + end; + end; +end; + +{ tdbusservice } + +constructor tdbusservice.create(); +begin + fitems:= tdbusitemhashdatalist.create(self); + fhandlers:= thandlerhashdatalist.create(self); + inherited; + registerobject(idbusobject(self)); +end; + +destructor tdbusservice.destroy(); +begin + unregisterobject(idbusobject(self)); + disconnect(); + inherited; + fitems.free(); + fhandlers.free(); +end; + +function tdbusservice.connected: boolean; +begin + result:= fconn <> nil; +end; +(* +procedure tdbusservice.setupmessage(const amessage: pdbusmessage; + const paramtypes: array of dbusdataty; + const params: array of pointer); + + function writevalue(var iter: dbusmessageiter; + var pt: pdbusdataty; var pd: ppointer; var datapo: pointer): boolean; + var + p1,pe: pointer; + p2: ppointer; + p3: pdbusdataty; + pdict: pdictentryty; + precord: precordinfoty; + record1: recordinfoty; + pvariant: pvariantvaluety; + pdynar: pdynarinfoty; + ptypda: ptypedata; + pd1: pointer; + p5: pointer; + bool1: dbus_bool_t; + pc1: pcchar; + iter2: dbusmessageiter; + i1,i2: int32; + d1: dbusdataty; + d2: array[0..1] of dbusdataty; + s1: string; + label + oklab,oklab1; + begin + result:= false; +{ + if pt >= pte then begin + error('dbuscallmethod() paramtypes and params count do not match'); + exit; + end; +} + p1:= pd^; + case pt^ of +// dbt_INVALID, + dbt_BYTE: begin + p1:= @bool1; + bool1:= 0; + if pboolean(pd)^ then begin + bool1:= 1; + end; + end; + dbt_BOOLEAN: begin + end; + dbt_INT16: begin + end; + dbt_UINT16: begin + end; + dbt_INT32: begin + end; + dbt_UINT32: begin + end; + dbt_INT64: begin + end; + dbt_UINT64: begin + end; + dbt_DOUBLE: begin + end; + dbt_STRING,dbt_OBJECT_PATH,dbt_SIGNATURE: begin + p1:= @pc1; + pc1:= pchar(pansistring(pd^)^); + end; + +// dbt_UNIX_FD, + dbt_ARRAY: begin + inc(pt); +{ + if pt >= pte then begin + error('dbuscallmethod() paramtypes and params count do not match'); + exit; + end; +} + pdynar:= pd^; //pointer to dynarinfoty + ptypda:= gettypedata(pdynar^.typinfo); + i1:= ptypda^.elsize; + s1:= dbusdatastrings[pt^]; + if s1 = '' then begin + s1:= dbusdatastring(ptypda^.eltype2); + end; + if dbus_message_iter_open_container(@iter,dbusdatacodes[dbt_array], + pchar(s1),@iter2) = 0 then begin + outofmemory(); + exit; + end; + p1:= ppointer(p1)^; //dynamic array + i2:= dynarraylength(p1); + if p1 <> nil then begin + pe:= p1 + i1 * i2; + while p1 < pe do begin + p2:= @p1; //restore + p3:= pt; //restore + if not writevalue(iter2,p3,p2,pd1) then begin //pd1 is dummy + dbus_message_iter_abandon_container(@iter,@iter2); + exit; + end; + inc(p1,i1); + end; + end; + if dbus_message_iter_close_container(@iter,@iter2) = 0 then begin + outofmemory(); + exit; + end; + goto oklab; + end; + dbt_VARIANT: begin + inc(pt); + p1:= pd^; + if dbus_message_iter_open_container(@iter,dbusdatacodes[dbt_variant], + pchar(dbusdatastring(pt^,p1)),@iter2) = 0 then begin + outofmemory(); + exit; + end; + if not writevalue(iter2,pt,pd,pd1) then begin //pd1 is dummy + dbus_message_iter_abandon_container(@iter,@iter2); + exit; + end; + if dbus_message_iter_close_container(@iter,@iter2) = 0 then begin + outofmemory(); + exit; + end; + goto oklab1; + end; + dbt_STRUCT: begin + precord:= pd^; + inc(pt); + pd1:= precord^.dataad; //record start + if dbus_message_iter_open_container(@iter,dbusdatacodes[dbt_struct], + nil,@iter2) = 0 then begin + outofmemory(); + exit; + end; + while pt^ <> dbt_structend do begin + if pt^ = dbt_struct then begin + record1.dataad:= pd1; //typinfo not used + p1:= @record1; + p2:= @p1; + end + else begin + p2:= @pd1; //restore + end; + if not writevalue(iter2,pt,p2,pd1) then begin + dbus_message_iter_abandon_container(@iter,@iter2); + exit; + end; + end; + if dbus_message_iter_close_container(@iter,@iter2) = 0 then begin + outofmemory(); + exit; + end; + goto oklab1; + end; + dbt_DICT_ENTRY: begin + pdict:= pd^; +{ + d2[0]:= dbt_variant; + p4:= pd^; + case p4^.value.kind of + vvk_string: begin + d2[1]:= dbt_string; + p1:= @p4^.value.vstring; + end; + vvk_int32: begin + d2[1]:= dbt_int32; + p1:= @p4^.value.vint32; + end; + else begin + result:= false; + error('dbuscallmethod() paramtype not yet supported'); + exit; + end; + end; + } + if dbus_message_iter_open_container(@iter,dbusdatacodes[dbt_dict_entry], + nil,@iter2) = 0 then begin + outofmemory(); + exit; + end; + d1:= dbt_string; + p3:= @d1; + p5:= @pdict^.name; + p2:= @p5; + if not writevalue(iter2,p3,p2,pd1) then begin //name, pd1 is dummy + dbus_message_iter_abandon_container(@iter,@iter2); + exit; + end; + d2[0]:= dbt_variant; + d2[1]:= dbt_msevariant; + p3:= @d2; + p1:= @pdict^.value; + p2:= @p1; + if not writevalue(iter2,p3,p2,pd1) then begin //value, pd1 is dummy + dbus_message_iter_abandon_container(@iter,@iter2); + exit; + end; + if dbus_message_iter_close_container(@iter,@iter2) = 0 then begin + outofmemory(); + exit; + end; + goto oklab1; + end; + dbt_msevariant: begin + pvariant:= pd^; + case pvariant^.kind of + vvk_string: begin + p1:= @pvariant^.vstring; + end; + vvk_int32: begin + p1:= @pvariant^.vint32; + end; + vvk_dynar: begin + p1:= @pvariant^.vdynar.data; + end; + vvk_record: begin + p1:= @pvariant^.vrecord.dataad; + end; + else begin + error('dbuscallmethod() variant data type not yet supported'); + exit; + end; + end; + p2:= @p1; + p3:= pointer(pvariant^.types); + if not writevalue(iter,p3,p2,pd1) then begin //pd1 is dummy + exit; + end; + goto oklab; + end; + else begin + result:= false; + error('dbuscallmethod() paramtype not yet supported'); + exit; + end; + end; + + if dbus_message_iter_append_basic(@iter, + dbusdatacodes[pt^],p1) = 0 then begin + outofmemory(); + exit; + end; + alignandstep(pt^,datapo); + oklab: + inc(pt); + inc(pd); + oklab1: + result:= true; + end;//writevalue + +var + pde: ppointer; + iter1: dbusmessageiter; + pt: pdbusdataty; + pte: pdbusdataty; + + pd: ppointer; + pd1: pointer; + +label + errorlab,oklab; + +begin + dbus_message_iter_init_append(amessage,@iter1); + pt:= @paramtypes[0]; + pte:= pt + length(paramtypes); + pd:= @params[0]; + pde:= pd + length(params); + while pd < pde do begin + if not writevalue(iter1,pt,pd,pd1) then begin //pd1 is dummy + goto errorlab; + end; + end; + goto oklab; + if pt <> pte then begin + error('dbuscallmethod() paramtypes and params count do not match'); + goto errorlab; + end; +errorlab: + dbus_message_unref(amessage); + raiseerror(dbuslasterror); +oklab: +end; +*) + +procedure tdbusservice.setupmessage(const amessage: pdbusmessage; + const params: array of variantvaluety); + + function writevalue(const aiter: dbusmessageiter; + const param: variantvaluety): boolean; + var + p1: pointer; + pe: pointer; + pc: pchar; + ps: pstring; + pv: pvariantvaluety; + pt: ptypeinfo; + v1: variantvaluety; + i1: int32; + iter1,iter2,iter3: dbusmessageiter; + s1: string; + pdict: pdictentryty; + piter: pdbusmessageiter; + label + oklab, + errorlab,error1lab,error2lab; + begin + if vf_var in param.flags then begin + if dbus_message_iter_open_container(@aiter,dbusdatacodes[dbt_variant], + pchar(dbusdatastring(param)),@iter3) = 0 then begin + outofmemory; + exit; + end; + piter:= @iter3; + end + else begin + piter:= @aiter; + end; + case param.kind of + vvk_string: begin + pc:= pchar(string(param.vstring)); + p1:= @pc; + end; + vvk_int32: begin + p1:= @param.vint32; + end; + vvk_card32: begin + p1:= @param.vcard32; + end; + vvk_variantar: begin + pt:= ptypeinfo(gettypedata(param.vvariantar.typinfo)^.eltype2); + s1:= dbusdatastring(pt); + if dbus_message_iter_open_container(piter,dbusdatacodes[dbt_array], + pchar(s1),@iter1) = 0 then begin + outofmemory(); + goto errorlab; + end; + pv:= param.vvariantar.data; + pe:= pv+length(variantvaluearty(param.vvariantar.data)); + while pv < pe do begin + if not writevalue(iter1,pv^) then begin + goto error1lab; + end; + inc(pv); + end; + if dbus_message_iter_close_container(piter,@iter1) = 0 then begin + outofmemory(); + goto errorlab; + end; + goto oklab; + end; + vvk_dynar: begin + if vf_dict in param.flags then begin + s1:= dbusdatastrings[dbt_dict_entry]; + end + else begin + pt:= ptypeinfo(gettypedata(param.vdynar.typinfo)^.eltype2); + s1:= dbusdatastring(pt); + end; + if dbus_message_iter_open_container(piter,dbusdatacodes[dbt_array], + pchar(s1),@iter1) = 0 then begin + outofmemory(); + goto errorlab; + end; + if vf_dict in param.flags then begin + pdict:= param.vdynar.data; + pe:= pointer(pdict+length(dictentryarty(param.vdynar.data))); + while pointer(pdict) < pe do begin + if dbus_message_iter_open_container(@iter1,dbusdatacodes[dbt_dict_entry], + nil,@iter2) = 0 then begin + outofmemory(); + goto error1lab; + end; + v1.flags:= []; + v1.kind:= vvk_string; + v1.vstring:= pointer(pdict^.name); + if not writevalue(iter2,v1) then begin + goto error2lab; + end; + if not writevalue(iter2,pdict^.value) then begin + goto error2lab; + end; + if dbus_message_iter_close_container(@iter1,@iter2) = 0 then begin + outofmemory(); + goto error1lab; + end; + inc(pdict); + end; + end + else begin + case pt^.kind of + tkinteger: begin + i1:= dynarraylength(param.vdynar.data); + if i1 > 0 then begin + if dbus_message_iter_append_fixed_array(@iter1, + dbusdatacodes[inttypes[gettypedata(pt)^.ordtype]],@param.vdynar.data, + i1) = 0 then begin + outofmemory(); + goto error1lab; + end; + end; + end; + tkastring: begin + i1:= dynarraylength(param.vdynar.data); + if i1 > 0 then begin + ps:= param.vdynar.data; + pe:= ps+i1; + while ps < pe do begin + pc:= pchar(ps^); + if dbus_message_iter_append_basic( + @iter1,dbusdatacodes[dbt_string],@pc) = 0 then begin + outofmemory(); + goto error1lab; + end; + inc(ps); + end; + end; + end; +{ + tkrecord: begin + pv:= param.vdynar.data; + pe:= pv+length(variantvaluearty(param.vdynar.data)); + while pv < pe do begin + if not writevalue(iter1,pv^) then begin + goto error1lab; + end; + inc(pv); + end; + end; +} + else begin + raiseerror('dbuscallmethod() data type not yet supported'); + end; + end; + end; + if dbus_message_iter_close_container(piter,@iter1) = 0 then begin + outofmemory(); + goto errorlab; + end; + goto oklab; + end; + vvk_record: begin + if dbus_message_iter_open_container(piter,dbusdatacodes[dbt_struct], + nil,@iter1) = 0 then begin + outofmemory(); + goto errorlab; + end; + pv:= param.vvariantar.data; + pe:= pv+length(variantvaluearty(param.vvariantar.data)); + while pv < pe do begin + if not writevalue(iter1,pv^) then begin + goto error1lab; + end; + inc(pv); + end; + if dbus_message_iter_close_container(piter,@iter1) = 0 then begin + outofmemory(); + goto errorlab; + end; + goto oklab; + end; + else begin + raiseerror('dbuscallmethod() variant data type not yet supported'); + end; + end; + if dbus_message_iter_append_basic(piter, + dbusdatatycodes[param.kind],p1) = 0 then begin + outofmemory(); + goto errorlab; + end; + oklab: + if piter <> @aiter then begin + if dbus_message_iter_close_container(@aiter,piter) = 0 then begin + outofmemory(); + exit; + end; + end; + result:= true; + exit; + + error2lab: + dbus_message_iter_abandon_container(@iter1,@iter2); + error1lab: + dbus_message_iter_abandon_container(piter,@iter1); + errorlab: + if piter <> @aiter then begin + dbus_message_iter_abandon_container(piter,piter); + end; + end;//writevalue + +var + pd,pe: pvariantvaluety; + iter1: dbusmessageiter; +begin + dbus_message_iter_init_append(amessage,@iter1); + pd:= @params[0]; + pe:= pd + length(params); + while pd < pe do begin + if not writevalue(iter1,pd^) then begin //pd1 is dummy + dbus_message_unref(amessage); + raiseerror(dbuslasterror); + end; + inc(pd); + end; +end; + +function tdbusservice.dbusreply(const amessage: pdbusmessage; + const params: array of variantvaluety): boolean; +var + m1: pdbusmessage; +begin + m1:= dbus_message_new_method_return(amessage); + setupmessage(m1,params); + result:= dbus_connection_send(fconn,m1,nil) <> 0; + dbus_message_unref(m1); +end; + +function tdbusservice.dbuserror(const amessage: pdbusmessage; + const aname: string; const atext: string): boolean; +var + m1: pdbusmessage; +begin + m1:= dbus_message_new_error(amessage,pchar(aname),pointer(atext)); + result:= dbus_connection_send(fconn,m1,nil) <> 0; + dbus_message_unref(m1); +end; + +function tdbusservice.dbussignal(const path: string; const iface: string; + const name: string; + const params: array of variantvaluety): boolean; +var + m1: pdbusmessage; +begin + result:= false; + m1:= dbus_message_new_signal(pchar(path),pchar(iface),pchar(name)); + setupmessage(m1,params); + result:= dbus_connection_send(fconn,m1,nil) <> 0; + dbus_message_unref(m1); +end; + + +function tdbusservice.methodcall(const bus_name,path,iface,method: string; + const params: array of variantvaluety): pdbusmessage; +begin + result:= dbus_message_new_method_call(pointer(bus_name),pchar(path), + pointer(iface),pchar(method)); + if result = nil then begin + outofmemory(); + end + else begin + setupmessage(result,params); + end; +end; + +type + callbackinfoty = record + handler: messageeventty; + end; + pcallbackinfoty = ^callbackinfoty; + +function filtertrampoline(connection: pDBusConnection; message: pDBusMessage; + user_data: pointer): DBusHandlerResult + {$ifdef wincall}stdcall{$else}cdecl{$endif}; +var + handler: messageeventty; + b1: boolean; +begin + tmethod(handler).data:= user_data; + tmethod(handler).code:= @tdbusservice.mainfilter; + b1:= false; + handler(message,b1); + if b1 then begin + result:= DBUS_HANDLER_RESULT_HANDLED; +// dbus_message_unref(message); + end + else begin + result:= DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + end; +end; + +function objectpathhandlertrampoline(connection: pDBusConnection; + message: pDBusMessage; user_data: pointer): DBusHandlerResult + {$ifdef wincall}stdcall{$else}cdecl{$endif}; +var + b1: boolean; +begin + with pcallbackinfoty(user_data)^ do begin + b1:= false; + handler(message,b1); + if b1 then begin + result:= DBUS_HANDLER_RESULT_HANDLED; + dbus_message_unref(message); + end + else begin + result:= DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + end; + end; +end; + +procedure unregisterobjectpath(connection: pDBusConnection; + user_data: pointer) + {$ifdef wincall}stdcall{$else}cdecl{$endif}; +begin + freemem(user_data); +end; +{ +const + dbuscallbackvtable: DBusObjectPathVTable = ( + unregister_function: @unregisterobjectpath; + message_function: @objectpathhandlertrampoline; + dbus_internal_pad1: nil; + dbus_internal_pad2: nil; + dbus_internal_pad3: nil; + dbus_internal_pad4: nil; + ); +} +{ +procedure tdbusservice.registerfallback(const apath: string; + const ahandler: messageeventty); +var + p1: pcallbackinfoty; +begin + p1:= getmem(sizeof(callbackinfoty)); + if dbus_connection_try_register_fallback(fconn, + pchar(apath), + @dbuscallbackvtable,p1,err) <> 0 then begin + with p1^ do begin + handler:= ahandler; + end; + end + else begin + freemem(p1); + raisedbuserror(); + end; +end; +} +{ +procedure tdbusservice.registeritem(const ainterface: string; + const apath: string; const asignature: string; + const ahandler: messageeventty); +var + p1: pcallbackinfoty; + s1: string; +begin + p1:= getmem(sizeof(callbackinfoty)); + with fregisteringobj^ do begin + s1:= pchar(fregisteringpath+'/'+apath); + if dbus_connection_try_register_object_path(fconn, + pchar(s1), + @dbuscallbackvtable,p1,err) <> 0 then begin + with p1^ do begin + handler:= ahandler; + end; + msearrayutils.additem(stringarty(items),apath); + end + else begin + freemem(p1); + raisedbuserror(); + end; + end; +end; +} +function tdbusservice.checkconnect(): boolean; +begin + result:= connected(); + if not result then begin + result:= connect(); + end; +end; + +const + introspectheader = +''+lineend; + +procedure tdbusservice.introspect(const amessage: pdbusmessage; + const adata: pointer; var ahandled: boolean); +var + s1: string; + o1: hashoffsetty; +begin + s1:= introspectheader+''+lineend; + o1:= fitems.flastobject; + while o1 <> 0 do begin + with pdbusitemhashdataty(fitems.getdatapo(o1))^.data.data.obj do begin + s1:= s1+obj.getintrospecttext(1); + o1:= prev; + end; + end; + s1:= s1+''+lineend; + if dbusreply(amessage,variantvalue(s1)) then begin + ahandled:= true; + end; +end; + +procedure tdbusservice.registeritems(const sender: idbusservice); +begin + sender.registermethodhandler( + 'org.freedesktop.DBus.Introspectable','Introspect',[],@introspect,nil); +end; + +function tdbusservice.getpath(): string; +begin + result:= ''; +end; + +function tdbusservice.getintrospecttext(const aindent: int32): string; +begin + result:= indent(peerintf+introspectintf,aindent); +end; + +procedure tdbusservice.busconnected(); +begin + //dummy +end; + +procedure tdbusservice.registermethodhandler(const ainterface: string; + const amember: string; const asignature: array of dbusdataty; + const ahandler: messagedataeventty; const adata: pointer); +var + offs1: hashoffsetty; + p1: phandlerhashdataty; + s1: string; +begin + s1:= getsignature(asignature); + offs1:= fhandlers.addmethod(fregisteringpath,ainterface,amember,s1,p1); + addoffs(hashoffsetarty(fregisteringobj^.handlers),offs1); + with p1^.data.handler do begin + datapo:= adata; + handler:= ahandler; + end; +end; + +procedure tdbusservice.registersignalhandler(const asender: string; + const apath: string; const ainterface: string; + const amember: string; const asignature: array of dbusdataty; + const ahandler: messagedataeventty; const adata: pointer); +var + offs1: hashoffsetty; + p1: phandlerhashdataty; + s1: string; +begin + s1:= getsignature(asignature); + offs1:= fhandlers.addsignal(asender,apath,ainterface,amember,s1,p1); + addoffs(hashoffsetarty(fregisteringobj^.handlers),offs1); + with p1^.data.handler do begin + datapo:= adata; + handler:= ahandler; + end; +end; + +procedure tdbusservice.doregisteritems(const aobj: pobjinfoty); +begin + fregisteringobj:= aobj; + fregisteringpath:= '/'+dbuspath(aobj^.obj.getpath()); + try + aobj^.obj.registeritems(idbusservice(self)); + finally + fregisteringobj:= nil; + fregisteringpath:= ''; + end; +end; + +procedure tdbusservice.dounregisteritems(const aobj: pobjinfoty); +var + po1,poe: phashoffsetty; +begin + po1:= aobj^.handlers; + poe:= po1 + length(hashoffsetarty(aobj^.handlers)); + while po1 < poe do begin + fhandlers.delete(po1^); + inc(po1); + end; +end; + +procedure tdbusservice.unregisteritem(const apath: string); +begin + dbus_connection_unregister_object_path(fconn,pchar(apath)); +end; + +procedure tdbusservice.mainfilter(const amessage: pdbusmessage; + var handled: boolean); +var + p1: phandlerhashdataty; + + procedure handlesignal(); + begin + while not handled and (p1 <> nil) do begin + try + with p1^.data.handler do begin + handler(amessage,datapo,handled); + end; + except + //application.handleexception(); does not work because of idle recursion + on e: exception do begin + error(e.message); + end; + end; + p1:= fhandlers.getdatapoornil(p1^.data.handler.signal.next); + end; + end; + +begin +{$ifdef mse_dumpdbus} + write(dbusdumpmessage(amessage)); +{$endif} + handled:= false; + case dbus_message_get_type(amessage) of + DBUS_MESSAGE_TYPE_METHOD_CALL: begin + p1:= fhandlers.findmethod(dbus_message_get_path(amessage), + dbus_message_get_interface(amessage), + dbus_message_get_member(amessage), + dbus_message_get_signature(amessage)); + if p1 <> nil then begin + try + with p1^.data.handler do begin + handler(amessage,datapo,handled); + end; + except + //application.handleexception(); does not work because of idle recursion + on e: exception do begin + error(e.message); + end; + end; + end; + end; + DBUS_MESSAGE_TYPE_SIGNAL: begin + p1:= fhandlers.findsignal(dbus_message_get_sender(amessage), + dbus_message_get_path(amessage), + dbus_message_get_interface(amessage), + dbus_message_get_member(amessage), + dbus_message_get_signature(amessage)); + handlesignal(); + if not handled then begin + p1:= fhandlers.findsignal('', //try any sender + dbus_message_get_path(amessage), + dbus_message_get_interface(amessage), + dbus_message_get_member(amessage), + dbus_message_get_signature(amessage)); + handlesignal(); + end; + end; + end; +end; + +procedure tdbusservice.registerobjects(); +var + i1: int32; + p1: pdbusitemhashdataty; +begin + for i1:= 0 to fitems.count - 1 do begin + p1:= pointer(fitems.next()); + if p1^.data.data.kind = dbk_obj then begin + doregisteritems(@p1^.data.data.obj); + end; + end; + for i1:= 0 to fitems.count - 1 do begin + p1:= pointer(fitems.next()); + if p1^.data.data.kind = dbk_obj then begin + p1^.data.data.obj.obj.busconnected(); + end; + end; +end; + +procedure tdbusservice.unregisterobjects(); +begin +// unregisteritem('/'); +end; + +procedure tdbusservice.dounregisterobj(const aobj: pobjinfoty); +begin + if fconn <> nil then begin + dounregisteritems(aobj); + end; +end; + +procedure tdbusservice.registerobject(const sender: idbusobject); +var + p1: pobjinfoty; +begin + + p1:= fitems.addobject(sender); + if connected then begin + doregisteritems(p1); + sender.busconnected(); + end; +end; + +procedure tdbusservice.unregisterobject(const sender: idbusobject); +begin + fitems.delete(sender); +end; + +function tdbusservice.dbuscallmethod(const returnedto: idbusresponse; + var aserial: card32; + const bus_name: string; const path: string; const iface: string; + const method: string; + const params: array of variantvaluety; + const timeout: int32 = -1): boolean; + +var + pend1: pdbuspendingcall; + m1: pdbusmessage; + +label + errorlab; +begin + result:= false; + if checkconnect() then begin + m1:= methodcall(bus_name,path,iface,method,params); + if m1 <> nil then begin + result:= dbus_connection_send_with_reply(fconn,m1,@pend1,timeout) <> 0; + if not result then begin + outofmemory(); + goto errorlab; + end; + fitems.addpending(pend1,returnedto,aserial); + dbus_pending_call_set_notify(pend1,@pendingcallback,self,nil); +errorlab: + dbus_message_unref(m1); + end; + end; +end; + +function tdbusservice.dbuscallmethod(const bus_name: string; + const path: string; const iface: string; const method: string; + const params: array of variantvaluety; + const resulttypes: array of dbusdataty; + const results: array of pointer; + const timeout: int32 = -1): boolean; +var + m1,m2: pdbusmessage; + +label + errorlab; +begin + result:= false; + if checkconnect() then begin + m1:= methodcall(bus_name,path,iface,method,params); + if m1 <> nil then begin + m2:= dbus_connection_send_with_reply_and_block(fconn,m1,timeout,err()); + if m2 = nil then begin + checkok(); + end + else begin + result:= dbusreadmessage(m2,resulttypes,results); + dbus_message_unref(m2); + end; +errorlab: + dbus_message_unref(m1); + end; + end; +end; + +function tdbusservice.dbusgetproperty( + const bus_name,path,iface,property_name: string; + const resulttypes: array of dbusdataty; + const results: array of pointer; + const timeout: int32 = -1): boolean; //blocking, true if ok +begin + result:= dbuscallmethod(bus_name,path,'org.freedesktop.DBus.Properties','Get', + [variantvalue(iface),variantvalue(property_name)], + resulttypes,results,timeout) +end; + +function tdbusservice.dbusreadmessage(const amessage: pdbusmessage; + const resulttypes: array of dbusdataty; + const results: array of pointer; + const apartial: boolean = false): boolean; + //true if ok +var + pte: pdbusdataty; + + function readvalue(var aiter: dbusmessageiter; + var pt: pdbusdataty; var pd: ppointer): boolean; + var + i1,i2,i3: int32; + si1: sizeint; + p1,p2: pointer; + p3: pdbusdataty; + p4: ppointer; + bool1: dbus_bool_t; + pc1: pcchar; + isstring: boolean; + typ1: pdynarraytypeinfo; + t1: dbusdataty; + iter2,iter3: dbusmessageiter; + iterpo: pdbusmessageiter; + + label + oklab; + begin + result:= false; + if pt >= pte then begin + error('dbuscallmethod() resulttypes and results count do not match'); + exit; + end; + iterpo:= @aiter; + i1:= dbus_message_iter_get_arg_type(iterpo); + if i1 = DBUS_TYPE_INVALID then begin + error('dbuscallmethod() returned param count:'+ + inttostr(pd - ppointer(@results[0]))+ + ' expected:'+inttostr(length(results))); + exit; + end; + if i1 = DBUS_TYPE_VARIANT then begin + dbus_message_iter_recurse(@aiter,@iter3); + iterpo:= @iter3; + i1:= dbus_message_iter_get_arg_type(iterpo); //nested variants? + end; + if i1 <> dbusdatacodes[pt^] then begin + error('dbuscallmethod() returned param does not match:'+inttostr(i1)+ + ' expected:'+inttostr(dbusdatacodes[pt^])); + exit; + end; + isstring:= false; + p1:= pd^; + case i1 of +// DBUS_TYPE_INVALID, + DBUS_TYPE_BYTE: begin + end; + DBUS_TYPE_BOOLEAN: begin + p1:= @bool1; + end; + DBUS_TYPE_INT16: begin + end; + DBUS_TYPE_UINT16: begin + end; + DBUS_TYPE_INT32: begin + end; + DBUS_TYPE_UINT32: begin + end; + DBUS_TYPE_INT64: begin + end; + DBUS_TYPE_UINT64: begin + end; + DBUS_TYPE_DOUBLE: begin + end; + DBUS_TYPE_STRING,DBUS_TYPE_OBJECT_PATH,DBUS_TYPE_SIGNATURE: begin + isstring:= true; + p1:= @pc1; + end; + +// DBUS_TYPE_UNIX_FD, + DBUS_TYPE_ARRAY: begin + inc(pt); + if pt >= pte then begin + error('dbuscallmethod() returntypes and returns count do not match'); + exit; + end; + i1:= dbusdatasizes[pt^]; + if i1 = 0 then begin + error('dbuscallmethod() array item type not yet supported'); + exit; + end; + i2:= dbus_message_iter_get_element_type(iterpo); + if i2 <> dbusdatacodes[pt^] then begin + error('dbuscallmethod() returned array item type does not match'); + exit; + end; + p1:= pd^; //pointer to var + t1:= pt^; + typ1:= arraytypes[t1]; + i3:= 0; + dbus_message_iter_recurse(iterpo,@iter2); + while dbus_message_iter_get_arg_type(@iter2) <> DBUS_TYPE_INVALID do begin + msearrayutils.additem(p1^,typ1,i3); + p2:= ppointer(p1)^ + i1*(i3-1); //data pointer in array + p4:= @p2; + p3:= @t1; + if not readvalue(iter2,p3,p4) then begin + exit; + end; + end; + si1:= i3; + dynarraysetlength(ppointer(p1)^,typ1,1,@si1); + goto oklab; + end; //array +// DBUS_TYPE_VARIANT, +// DBUS_TYPE_STRUCT, +// DBUS_TYPE_DICT_ENTRY + else begin + error('dbuscallmethod() invalid returned value'); + exit; + end; + end; + dbus_message_iter_get_basic(iterpo,p1); + p1:= pd^; + if isstring then begin + if pc1 = nil then begin + pansistring(p1)^:= ''; + end + else begin + pansistring(p1)^:= ansistring(pc1); + end; + end + else begin + if i1 = DBUS_TYPE_BOOLEAN then begin + pboolean(p1)^:= bool1 <> 0; + end; + end; + oklab: + dbus_message_iter_next(@aiter); + inc(pt); + inc(pd); + result:= true; + end;//readvalue + +var + iter1: dbusmessageiter; + pde: ppointer; + pt: pdbusdataty; + pd: ppointer; + s1: string; + p1: pointer; + t1: dbusdataty; + +label + errorlab; +begin + result:= false; + if checkconnect() then begin + if amessage = nil then begin + error('NIL message'); + goto errorlab; + end + else begin + dbus_message_iter_init(amessage,@iter1); + + if dbus_message_get_type(amessage) = DBUS_MESSAGE_TYPE_ERROR then begin + p1:= @s1; + pd:= @p1; + t1:= dbt_string; + pt:= @t1; + pte:= pt+1; + if readvalue(iter1,pt,pd) then begin + error(s1); + end; + goto errorlab; + end; + + pt:= @resulttypes[0]; + pte:= pt + length(resulttypes); + pd:= @results[0]; + pde:= pd + length(results); + while pd < pde do begin + if not readvalue(iter1,pt,pd) then begin + goto errorlab; + end; + end; + if not apartial and (dbus_message_iter_get_arg_type(@iter1) <> + DBUS_TYPE_INVALID) then begin + error('dbuscallmethod() wrong returned param count'); + goto errorlab; + end; + if pt <> pte then begin + error('dbuscallmethod() resulttypes and results count do not match'); + goto errorlab; + end; + result:= true; + end; +errorlab: + end; +end; + +function tdbusservice.connect: boolean; +var + i1,i2: int32; + s1,s2: string; +begin + if fconn <> nil then begin + result:= true; + exit; + end; + result:= false; + try + if not initdbuslib() then begin + exit; + end; + dbus_error_init(@ferr); + fconn:= dbus_bus_get_private(dbus_bus_session,err); + if fconn = nil then begin + checkok(); + end + else begin + dbus_connection_set_exit_on_disconnect(fconn,0); + fbusid:= dbus_bus_get_unique_name(fconn); + s1:= msebusname+'-'+inttostr(sys_getpid())+'-'; + i1:= nextidnumber; + repeat + s2:= s1+inttostr(i1); + i2:= dbus_bus_request_name(fconn,pchar(s2), + DBUS_NAME_FLAG_DO_NOT_QUEUE,err()); + inc(i1); + if (i1 > nextidnumber+200) or (i2 < 0) then begin + disconnect(); + exit; + end; + until (i2 = DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER){ or + (i2 = DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER)}; + nextidnumber:= i1; + fbusname:= s2; + dbus_connection_add_filter(fconn,@filtertrampoline,self,nil); + //start asynchronous message handling + dbus_connection_set_watch_functions(fconn,@addwatch,@removewatch, + @watchtoggled,self,nil); + dbus_connection_set_timeout_functions(fconn,@addtimeout,@removetimeout, + @timeouttoggled,self,nil); + application.registeronidle(@doidle); + registerobjects(); + result:= true; + end; + except + on e: exception do begin + dbuslasterror:= e.message; + end; + end; +end; + +procedure tdbusservice.disconnect(); +begin + if fconn <> nil then begin + unregisterobjects(); + dbus_connection_close(fconn); + dbus_connection_remove_filter(fconn,@filtertrampoline,self); + fitems.clear(); + if not applicationdestroyed() then begin + application.unregisteronidle(@doidle); + end; + err(); //free ferr + dbus_shutdown(); + fconn:= nil; + fbusid:= ''; + fbusname:= ''; +// releasedbus(); + end; +end; + +function tdbusservice.doaddwatch(const awatch: pdbuswatch): int32; +var + i1,i2: int32; + fla1: pollflagsty; + p1: pwatchinfoty; +begin + result:= 0; + i2:= dbus_watch_get_unix_fd(awatch); + if i2 > 0 then begin + fla1:= []; + i1:= dbus_watch_get_flags(awatch); + if i1 and DBUS_WATCH_READABLE <> 0 then begin + include(fla1,pf_in); + end; + if i1 and DBUS_WATCH_WRITABLE <> 0 then begin + include(fla1,pf_out); + end; + p1:= fitems.addwatch(awatch); + gui_addpollfd(p1^.id,i2,fla1,@fitems.dopollcallback,awatch); + updatewatch(awatch); + result:= 1; + end; +end; + +procedure tdbusservice.updatewatch(const awatch: pdbuswatch); +begin + with fitems.findwatch(awatch)^ do begin + gui_setpollfdactive(id,dbus_watch_get_enabled(awatch) <> 0); + end; +end; + +procedure tdbusservice.dowatchtoggled(const awatch: pdbuswatch); +begin + updatewatch(awatch); +end; + +procedure tdbusservice.doremovewatch(const awatch: pdbuswatch); +//var +// p1: pwatchinfoty; +begin + fitems.delete(awatch); +{ + p1:= dbus_watch_get_data(awatch); + gui_removepollfd(p1^.id); + removeitem(pointerarty(fwatches),p1); +} +end; + +procedure tdbusservice.updatetimeout(const atimeout: pdbustimeout); +var + i1: int32; + b1: boolean; +begin + with fitems.findtimeout(atimeout)^.timer do begin + b1:= dbus_timeout_get_enabled(atimeout) <> 0; + i1:= dbus_timeout_get_interval(atimeout)*1000; + if b1 then begin + if i1 <> interval then begin + interval:= i1; + enabled:= true; + end; + end + else begin + enabled:= false; + interval:= i1; + end; + end; +end; + +function tdbusservice.doaddtimeout(const atimeout: pdbustimeout): int32; +var + meth1: notifyeventty; +begin + meth1:= @dotimer; + tmethod(meth1).data:= atimeout; + with pdbusitemhashdataty(fitems.add(atimeout))^.data.data do begin + kind:= dbk_timeout; + with timeout do begin + timer:= tsimpletimer.create(0,meth1); + end; + end; +// dbus_timeout_set_data(atimeout,ti1,@freetimeout); + updatetimeout(atimeout); + result:= 1; +end; + +procedure tdbusservice.dotimeouttoggled(const atimeout: pdbustimeout); +begin + updatetimeout(atimeout); +end; + +procedure tdbusservice.doremovetimeout(const atimeout: pdbustimeout); +begin + fitems.delete(atimeout); +end; + +procedure tdbusservice.dotimer(const sender: tobject); +var + timeout1: pdbustimeout; +begin +{$ifdef mse_debugdbus} + writeln('**dotimer'); +{$endif} + timeout1:= pdbustimeout(pointer(self)); + dbus_timeout_handle(timeout1); +end; + +function tdbusservice.err(): pdbuserror; +begin + if dbus_error_is_set(@ferr) <> 0 then begin + dbus_error_free(@ferr); + end; + result:= @ferr; +end; + +function tdbusservice.checkok(): boolean; +begin + result:= dbus_error_is_set(@ferr) = 0; + if not result then begin + dbuslasterror:= string(ferr.message); + end; +end; + +procedure tdbusservice.raisedbuserror(); +begin + if not checkok() then begin + raiseerror(dbuslasterror); + end; +end; + +procedure tdbusservice.doidle(var again: boolean); +begin + if fconn <> nil then begin +{$ifdef mse_debugdbus} + writeln('**doidle'); +{$endif} + fitems.handlewatches(); + repeat + until dbus_connection_dispatch(fconn) <> DBUS_DISPATCH_DATA_REMAINS; + dbus_connection_flush(fconn); + end; +end; + +procedure tdbusservice.dopendingcallback(pending: pDBusPendingCall{; + user_data: pointer}); +var + m1: pdbusmessage; + p1: pdbusitemhashdataty; +begin + m1:= dbus_pending_call_steal_reply(pending); + with fitems.findpending(pending)^ do begin + if link <> 0 then begin + p1:= fitems.getdatapo(link); + idbusresponse(p1^.data.data.link.link).replied(serial,m1{,user_data}); +// fitems.delete(link); + end; + fitems.delete(pending); + end; + if m1 <> nil then begin + dbus_message_unref(m1); + end; +end; + +{ +procedure tdbusservice.dofreependingcallback(memory: pointer); +begin + removeitem(pointerarty(fpendings),memory); + freemem(memory); +end; +} +{ tdbusobject } + +constructor tdbusobject.create(const aservice: tdbusservice); +begin + setlinkedvar(aservice,tlinkedobject(fservice)); + inherited create; + if fservice <> nil then begin + fservice.registerobject(idbusobject(self)); + end; +end; + +destructor tdbusobject.destroy(); +begin + if fservice <> nil then begin + fservice.unregisterobject(idbusobject(self)); + end; + inherited; +end; +{ +function tdbusobject.getinstance(): tobject; +begin + result:= self; +end; +} +procedure tdbusobject.registeritems(const sender: idbusservice); +begin + sender.registermethodhandler( + 'org.freedesktop.DBus.Introspectable','Introspect',[],@introspect,nil); + sender.registermethodhandler( + 'org.freedesktop.DBus.Properties','Get', + [dbt_string,dbt_string],@propget,nil); + sender.registermethodhandler( + 'org.freedesktop.DBus.Properties','Set', + [dbt_string,dbt_string,dbt_variant],@propset,nil); + sender.registermethodhandler( + 'org.freedesktop.DBus.Properties','GetAll', + [dbt_string],@propgetall,nil); +end; + +function tdbusobject.getpath(): string; +begin + result:= ''; +end; + +function tdbusobject.getintrospecttext(const aindent: int32): string; +var + s1: string; +begin + s1:= charstring(' ',2*aindent); + result:= s1+''+lineend; + result:= result + indent(getintrospectitems(),aindent+1); + result:= result+s1+''+lineend; +end; + +procedure tdbusobject.busconnected(); +begin + //dummy +end; + +procedure tdbusobject.introspect(const amessage: pdbusmessage; + const adata: pointer; var ahandled: boolean); +var + s1: string; +begin + s1:= introspectheader+getintrospecttext(0); + fservice.dbusreply(amessage,variantvalue(s1)); + ahandled:= true; +end; + +function tdbusobject.getpropvalue(const aprop: ppropinfo; + out avalue: variantvaluety): boolean; +var + p3: pointer; +begin + result:= true; + with aprop^ do begin + if getproc <> nil then begin + case proptype^.kind of + tkastring: begin + setvariantvalue(getstrprop(self,aprop),avalue,[vf_var]); + end; + tkinteger: begin + setvariantvalue(int32(getordprop(self,aprop)),avalue,[vf_var]); + end; + tkdynarray: begin + p3:= pointer(ptruint(getordprop(self,aprop))); + setvariantvalue(@p3,proptype,avalue,[vf_var]); + end; + else begin + result:= false; + end; + end; + end + else begin + result:= false; + end; + end; +end; + +procedure tdbusobject.propget(const amessage: pdbusmessage; const adata: pointer; + var ahandled: boolean); +var + s1,s2: string; + p1: ppropinfo; + v1: variantvaluety; +begin + if fservice.dbusreadmessage(amessage, + [dbt_string,dbt_string],[@s1,@s2]) then begin + if (s1 = '') or (s1 = getpropintf()) then begin + v1.kind:= vvk_none; + propertyget(amessage,s2,v1); + if v1.kind = vvk_none then begin + p1:= getpropinfo(self,s2); + if p1 = nil then begin + fservice.dbuserror(amessage, + 'org.freedesktop.DBus.Error.InvalidArgs', + 'Property '+s2+' was not found in object '+rootpath()); + end + else begin + if not getpropvalue(p1,v1) then begin + fservice.dbuserror(amessage, + 'org.freedesktop.DBus.Error.PropertyWriteOnly', //unofficional + 'Property '+s2+' is write only'); + end; + end; + end; + if v1.kind <> vvk_none then begin + fservice.dbusreply(amessage,[v1]); + end; + end + else begin + fservice.dbuserror(amessage, + 'org.freedesktop.DBus.Error.UnknownInterface', + 'Interface '+s1+' was not found in object '+rootpath()); + end; + end; + ahandled:= true; +end; + +procedure tdbusobject.propset(const amessage: pdbusmessage; + const adata: pointer; var ahandled: boolean); +var + s1,s2,s3: string; + p1: ppropinfo; + b1: boolean; +label + oklab; +begin + if fservice.dbusreadmessage(amessage,[dbt_string,dbt_string], + [@s1,@s2],true) then begin + if (s1 = '') or (s1 = getpropintf()) then begin + b1:= false; + propertyset(amessage,s2,b1); + if not b1 then begin + p1:= getpropinfo(self,s2); + if p1 = nil then begin + fservice.dbuserror(amessage, + 'org.freedesktop.DBus.Error.InvalidArgs', + 'Property '+s2+' was not found in object '+rootpath()); + end + else begin + if p1^.setproc = nil then begin + fservice.dbuserror(amessage, + 'org.freedesktop.DBus.Error.PropertyReadOnly', + 'Property '+s2+' is read only'); + end + else begin + case p1^.proptype^.kind of + tkastring: begin + if fservice.dbusreadmessage(amessage, + [dbt_string,dbt_string,dbt_string],[@s1,@s2,@s3]) then begin + setstrprop(self,p1,s3); + goto oklab; + end; + end; + end; + fservice.dbuserror(amessage, + 'org.freedesktop.DBus.Error.InvalidArgs', + 'Property '+s2+' wrong type'); + end; + end; + end; + end + else begin + fservice.dbuserror(amessage, + 'org.freedesktop.DBus.Error.UnknownInterface', + 'Interface '+s1+' was not found in object '+rootpath()); + end; + end; +oklab: + ahandled:= true; +end; + +type + pppropinfo = ^ppropinfo; + +procedure tdbusobject.propgetall(const amessage: pdbusmessage; + const adata: pointer; var ahandled: boolean); +var + ar1: dictentryarty; + ar2: propinfopoarty; + i1,i2: int32; + p1: pdictentryty; + p2: pppropinfo; +// dynar1: dynarinfoty; +begin + propertiesget(ar1); + + i1:= length(ar1); + ar2:= getpropinfoar(self); + setlength(ar1,i1+length(ar2)); //max + + try + p1:= @ar1[i1]; + p2:= pointer(ar2); + for i2:= i1 to high(ar1) do begin + if getpropvalue(p2^,p1^.value) then begin + p1^.name:= p2^^.name; + inc(p1); + end; + inc(p2); + end; + setlength(ar1,p1-pdictentryty(pointer(ar1))); +// dynar1.data:= pointer(ar1); +// dynar1.typinfo:= typeinfo(ar1); + if fservice.dbusreply(amessage, + variantvalue(@ar1,typeinfo(ar1),[vf_dict])) then begin + ahandled:= true; + end; + finally + finalizedictentryar(ar1); + end; +end; + +function tdbusobject.getintrospectitems(): string; +begin + result:= introspectintf+propertiesintf; +end; + +function tdbusobject.getpropintf: string; +begin + result:= ''; +end; + +function tdbusobject.rootpath: string; +begin + result:= '/'+dbuspath(getpath()); +end; + +procedure tdbusobject.propchangesignal(const amember: string); +begin + if (fservice <> nil) and fservice.connected then begin + fservice.dbussignal(rootpath(),getpropintf(),amember,[]); + end; +end; +{ +procedure tdbusobject.setrecordprop(const adataad: pointer; + atype: ptypeinfo; var avalue: variantvaluety; + const aflags: variantflagsty = []); +begin + if atype^.kind = tkdynarray then begin + atype:= gettypedata(atype)^.eltype2; + end; + setvariantvalue(adataad,atype,avalue,aflags); +end; +} +procedure tdbusobject.propertyget(const amessage: pdbusmessage; + const aname: string; var avalue: variantvaluety); +begin + //dummy +end; + +procedure tdbusobject.propertiesget(var props: dictentryarty); +begin + //dummy +end; + +procedure tdbusobject.propertyset(const amessage: pdbusmessage; + const aname: string; var ahandled: boolean); +begin + //dummy +end; + +{ +procedure tdbusobject.unregisteritems(const sender: idbusservice); +begin + //dummy +end; +} +{ thandlerhashdatalist } + +constructor thandlerhashdatalist.create(const aowner: tdbusservice); +begin + fowner:= aowner; + fstringidents:= tstringidents.create(); + femptystringid:= fstringidents.getident(''); + fstate:= fstate+[hls_needsnull,hls_needsfinalize]; + inherited create(); +end; + +destructor thandlerhashdatalist.destroy(); +begin + inherited; + fstringidents.free(); +end; + +function thandlerhashdatalist.scanpath(var avec: identvecty; + const apath: pchar; const aseparator: char): boolean; +var + p1,p2: pchar; +begin + result:= true; + with avec do begin + if high >= system.high(d) then begin + result:= false; + exit; + end; + inc(high); + d[high]:= separatorid; + if apath <> nil then begin + p1:= apath; + while p1^ <> #0 do begin + if high >= system.high(d) then begin + result:= false; + exit; + end; + p2:= p1; + while (p2^ <> aseparator) and (p2^ <> #0) do begin + inc(p2); + end; + inc(high); + d[high]:= fstringidents.getident(p1,p2); + if p2^ = #0 then begin + break; + end; + p1:= p2+1; + end; + end; + end; +end; + +function thandlerhashdatalist.addmethod( + const aobject,ainterface,amember,asignature: string; + out adata: phandlerhashdataty): hashoffsetty; + procedure pathlenerror(); + begin + raiseerror('Too many path elements'); + end;//pathlenerror + +var + vec1: identvecty; +begin + vec1.high:= 0; + vec1.d[0]:= methodhandlerid; + if not scanpath(vec1,pchar(aobject),'/') then begin + pathlenerror(); + end; + if not scanpath(vec1,pchar(ainterface),'.') then begin + pathlenerror(); + end; + if not scanpath(vec1,pchar(amember),'.') then begin + pathlenerror(); + end; + if not scanpath(vec1,pchar(asignature),#0) then begin + pathlenerror(); + end; + result:= inherited add(vec1,pointer(adata)); + adata^.data.kind:= hk_method; +end; + +function constructmatch(const asender,apath,ainterface,amember: string): string; +begin + result:= ''; + if asender <> '' then begin + result:= result+'sender='+''''+asender+''','; + end; + if apath <> '' then begin + result:= result+'path='+''''+apath+''','; + end; + if ainterface <> '' then begin + result:= result+'interface='+''''+ainterface+''','; + end; + if amember <> '' then begin + result:= result+'member='+''''+amember+''','; + end; + if result <> '' then begin + setlength(result,length(result)-1); + end; +end; + +function thandlerhashdatalist.addsignal( + const asender,apath,ainterface,amember,asignature: string; + out adata: phandlerhashdataty): hashoffsetty; + procedure pathlenerror(); + begin + raiseerror('Too many path elements'); + end;//pathlenerror + +var + vec1: identvecty; + p1: phandlerhashdataty; + s1: string; + o1,o2: hashoffsetty; +begin + s1:= 'type=signal,'+constructmatch(asender,apath,ainterface,amember); + vec1.high:= 1; + vec1.d[0]:= signalmatchid; + vec1.d[1]:= fstringidents.getident(s1); + p1:= phandlerhashdataty(find(vec1)); + if p1 = nil then begin + add(vec1,pointer(p1)); + dbus_bus_add_match(fowner.fconn,pchar(s1),nil); + p1^.data.kind:= hk_match; + with p1^.data.match do begin + match:= vec1.d[1]; + refcount:= 0; + end; + end; + o1:= getdataoffs(p1); + inc(p1^.data.match.refcount); + + vec1.high:= 5; + vec1.d[0]:= signalhandlerid; + vec1.d[1]:= fstringidents.getident(asender); + vec1.d[2]:= fstringidents.getident(apath); + vec1.d[3]:= fstringidents.getident(ainterface); + vec1.d[4]:= fstringidents.getident(amember); + vec1.d[5]:= fstringidents.getident(asignature); + find(vec1,o2); //always the last entered? + result:= inherited add(vec1,pointer(adata)); + adata^.data.kind:= hk_signal; + with adata^.data.handler do begin + signal.match:= o1; + signal.prev:= 0; + if o2 <> 0 then begin + phandlerhashdataty(getdatapo(o2))^.data.handler.signal.prev:= result; + + signal.next:= o2; + end + else begin + signal.next:= 0; + end; + end; +end; + +function thandlerhashdatalist.findmethod(const aobject: pchar; + const ainterface: pchar; const amember: pchar; + const asignature: pchar): phandlerhashdataty; +var + vec1: identvecty; +begin + result:= nil; + vec1.high:= 0; + vec1.d[0]:= methodhandlerid; + if scanpath(vec1,aobject,'/') and + scanpath(vec1,ainterface,'.') and + scanpath(vec1,amember,'.') and + scanpath(vec1,asignature,#0) then begin + result:= phandlerhashdataty(inherited find(vec1)); + if (result <> nil) and (result^.data.kind <> hk_method) then begin + result:= nil; + end; + end; +end; + +function thandlerhashdatalist.findsignal(const asender: pchar; + const apath: pchar; const ainterface: pchar; + const amember: pchar; const asignature: pchar): phandlerhashdataty; +var + vec1: identvecty; +begin + vec1.high:= 5; + vec1.d[0]:= signalhandlerid; + vec1.d[1]:= fstringidents.getident(asender); + vec1.d[2]:= fstringidents.getident(apath); + vec1.d[3]:= fstringidents.getident(ainterface); + vec1.d[4]:= fstringidents.getident(amember); + vec1.d[5]:= fstringidents.getident(asignature); + result:= phandlerhashdataty(inherited find(vec1)); + if (result <> nil) and (result^.data.kind <> hk_signal) then begin + result:= nil; + end; +end; + +function thandlerhashdatalist.getrecordsize(): int32; +begin + result:= sizeof(handlerhashdataty); +end; + +procedure thandlerhashdatalist.finalizeitem(const aitem: phashdataty); +var + p1: phandlerhashdataty; +begin + with phandlerhashdataty(aitem)^ do begin + case data.kind of + hk_match: begin + if fowner.fconn <> nil then begin + dbus_bus_remove_match(fowner.fconn, + fstringidents.getidentnamep(data.match.match),nil); + end; + end; + hk_signal: begin + if data.handler.signal.next <> 0 then begin + phandlerhashdataty(getdatapo(data.handler.signal.next))^. + data.handler.signal.prev:= data.handler.signal.prev; + end; + if data.handler.signal.prev <> 0 then begin + phandlerhashdataty(getdatapo(data.handler.signal.prev))^. + data.handler.signal.next:= data.handler.signal.next; + end; + p1:= getdatapo(data.handler.signal.match); + dec(p1^.data.match.refcount); + if p1^.data.match.refcount = 0 then begin + internaldelete(data.handler.signal.match); + end; + end; + end; + end; + inherited; +end; + +{ +var + card32rec: record b: byte; v: card32 end; +const + card32align: int32 = (@card32rec.v - @card32rec.b); + + dbusalignments: array[dbusdataty] of int32 = ( + 0, //dbt_INVALID, + sizeof(byte), //dbt_BYTE, + sizeof(boolean), //dbt_BOOLEAN, + sizeof(int16), //dbt_INT16, + sizeof(card16), //dbt_UINT16, + sizeof(int32), //dbt_INT32, + sizeof(card32), //dbt_UINT32, + sizeof(int64), //dbt_INT64, + sizeof(card64), //dbt_UINT64, + sizeof(flo64), //dbt_DOUBLE, + sizeof(ansistring), //dbt_STRING, + sizeof(ansistring), //dbt_OBJECT_PATH, + sizeof(ansistring), //dbt_SIGNATURE, + 0, //dbt_UNIX_FD, + 0, //dbt_ARRAY, + 0, //dbt_VARIANT, + 0, //dbt_STRUCT, + sizeof(dictentryty), //dbt_DICT_ENTRY + sizeof(variantvaluety) //dbt_msevariant + ); +} + +procedure doinit(); +var + card32rec: record b: byte; v: card32 end; + card64rec: record b: byte; v: card64 end; + flo64rec: record b: byte; v: flo64 end; + porec: record b: byte; v: pointer end; + dictrec: record b: byte; v: dictentryty end; + msevarrec: record b: byte; v: variantvaluety end; + offs32: int32; + offs64: int32; + offsflo64: int32; + offspo: int32; + offsdict: int32; + offsmsevar: int32; +begin + offs32:= @card32rec.v - @card32rec.b; + offs64:= @card64rec.v - @card64rec.b; + offsflo64:= @flo64rec.v - @flo64rec.b; + offspo:= @porec.v - @porec.b; + offsdict:= @dictrec.v - @dictrec.b; + offsmsevar:= @msevarrec.v - @msevarrec.b; + + dbusalignments[dbt_INVALID]:= 0; + dbusalignments[dbt_BYTE]:= sizeof(byte); + dbusalignments[dbt_BOOLEAN]:= sizeof(boolean); + dbusalignments[dbt_INT16]:= sizeof(int16); + dbusalignments[dbt_UINT16]:= sizeof(uint16); + dbusalignments[dbt_INT32]:= offs32; + dbusalignments[dbt_UINT32]:= offs32; + dbusalignments[dbt_INT64]:= offs64; + dbusalignments[dbt_UINT64]:= offs64; + dbusalignments[dbt_DOUBLE]:= offsflo64; + dbusalignments[dbt_STRING]:= offspo; + dbusalignments[dbt_OBJECT_PATH]:= offspo; + dbusalignments[dbt_SIGNATURE]:= offspo; + dbusalignments[dbt_UNIX_FD]:= 0; + dbusalignments[dbt_ARRAY]:= 0; + dbusalignments[dbt_VARIANT]:= 0; + dbusalignments[dbt_STRUCT]:= 0; + dbusalignments[dbt_DICT_ENTRY]:= offsdict; + dbusalignments[dbt_msevariant]:= offsmsevar; + + arraytypes[dbt_INVALID]:= nil; + arraytypes[dbt_BYTE]:= typeinfo(bytearty); + arraytypes[dbt_BOOLEAN]:= typeinfo(booleanarty); + arraytypes[dbt_INT16]:= typeinfo(int16arty); + arraytypes[dbt_UINT16]:= typeinfo(card16arty); + arraytypes[dbt_INT32]:= typeinfo(int32arty); + arraytypes[dbt_UINT32]:= typeinfo(card32arty); + arraytypes[dbt_INT64]:= typeinfo(int64arty); + arraytypes[dbt_UINT64]:= typeinfo(card64arty); + arraytypes[dbt_DOUBLE]:= typeinfo(flo64arty); + arraytypes[dbt_STRING]:= typeinfo(ansistringarty); + arraytypes[dbt_OBJECT_PATH]:= typeinfo(ansistringarty); + arraytypes[dbt_SIGNATURE]:= typeinfo(ansistringarty); + arraytypes[dbt_UNIX_FD]:= nil; + arraytypes[dbt_ARRAY]:= nil; + arraytypes[dbt_VARIANT]:= nil; + arraytypes[dbt_STRUCT]:= nil; + arraytypes[dbt_DICT_ENTRY]:= nil; + arraytypes[dbt_msevariant]:= nil; +end; + +initialization + doinit(); +// clearlist(userdatacache,sizeof(userdatarecty),0); +finalization + dbuslasterror:= ''; //memory leak without on FPC 2.6.4 +// freelist(userdatacache); +end. diff --git a/mseide-msegui/lib/common/sysutils/mseenvmacros.pas b/mseide-msegui/lib/common/sysutils/mseenvmacros.pas new file mode 100644 index 0000000..ba6d20f --- /dev/null +++ b/mseide-msegui/lib/common/sysutils/mseenvmacros.pas @@ -0,0 +1,67 @@ +{ MSEgui Copyright (c) 2015 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} + +unit mseenvmacros; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msemacros; + +function envmacros(): macroinfoarty; + +implementation +uses + msetypes{msestrings},msesysintf; + +var + fenvmacros: macroinfoarty; + +function envmacros(): macroinfoarty; +begin + result:= fenvmacros; +end; + +function env_var(const sender: tmacrolist; + const params: msestringarty): msestring; +begin + result:= ''; + if params <> nil then begin + if sys_getenv(params[0],result) then begin + if high(params) > 1 then begin + result:= params[2]; + end; + end + else begin + if high(params) > 0 then begin + result:= params[1]; + end; + end; + end; +end; + +const + envmacroconst: array[0..0] of macroinfoty = ( + (name: 'ENV_VAR'; value: ''; handler: macrohandlerty(@env_var); + expandlevel: 0) + ); + +procedure initenvmacros(); +var + int1: integer; +begin + setlength(fenvmacros,length(envmacroconst)); + for int1:= 0 to high(envmacroconst) do begin + fenvmacros[int1]:= envmacroconst[int1]; + end; +end; + +initialization + initenvmacros(); +end. diff --git a/mseide-msegui/lib/common/sysutils/mseexecmacros.pas b/mseide-msegui/lib/common/sysutils/mseexecmacros.pas new file mode 100644 index 0000000..263841b --- /dev/null +++ b/mseide-msegui/lib/common/sysutils/mseexecmacros.pas @@ -0,0 +1,73 @@ +{ MSEgui Copyright (c) 2015 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} + +unit mseexecmacros; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msemacros; + +function execmacros(): macroinfoarty; + +implementation +uses + mseprocess,mseprocutils,msefileutils,msetypes{msestrings},mseformatstr; + +var + fexecmacros: macroinfoarty; + +function execmacros(): macroinfoarty; +begin + result:= fexecmacros; +end; + +function exec_out(const sender: tmacrolist; + const params: msestringarty): msestring; +const + defaulttimeout = 1000000; //1 second +var + str1: string; + i1: int32; +begin + result:= ''; + if params <> nil then begin + i1:= defaulttimeout; + if high(params) >= 1 then begin + if trystrtoint(params[1],i1) then begin + i1:= i1 * 1000; + end + else begin + i1:= defaulttimeout; + end; + end; + getprocessoutput(syscommandline(params[0]),'',str1,i1); + result:= msestring(str1); + end; +end; + +const + execmacroconst: array[0..0] of macroinfoty = ( + (name: 'EXEC_OUT'; value: ''; handler: macrohandlerty(@exec_out); + expandlevel: 0) //processoutput + ); + +procedure initexecmacros(); +var + int1: integer; +begin + setlength(fexecmacros,length(execmacroconst)); + for int1:= 0 to high(execmacroconst) do begin + fexecmacros[int1]:= execmacroconst[int1]; + end; +end; + +initialization + initexecmacros(); +end. diff --git a/mseide-msegui/lib/common/sysutils/msefilechange.pas b/mseide-msegui/lib/common/sysutils/msefilechange.pas new file mode 100644 index 0000000..7641ced --- /dev/null +++ b/mseide-msegui/lib/common/sysutils/msefilechange.pas @@ -0,0 +1,708 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msefilechange; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifndef FPC}{$ifdef linux} {$define UNIX} {$endif}{$endif} + +interface + +uses + mseclasses,SysUtils,msethread,msefileutils,msesys, + msetypes,msestrings,classes,mseapplication,mseevent; + +{$ifdef UNIX} +const + sigpuffermask = 32-1; //maximale anzahl pending notifications +{$endif} + +type + tfilechangenotifyer = class; + + filechangeinfoty = record + dir: filenamety; + infovorher: fileinfoty; + info: fileinfoty; + tag: integer; + force: boolean; + changed: filechangesty; + end; + + filechangedeventty = procedure(const sender: tfilechangenotifyer; + const info: filechangeinfoty) of object; + + filechangeinfo1ty = record + info: filechangeinfoty; + owner: tfilechangenotifyer; + isroot: boolean; + end; + fileinfosty = array of filechangeinfo1ty; + + tdirinfo = class + private + ffileinfos: fileinfosty; + fpath: filenamety; + fdirhandle: integer; + procedure deleteinfo(index: integer); + public + constructor create(afd: integer; const apath: filenamety); //owns the fd + destructor destroy; override; + procedure addfile(root: boolean; const sender: tfilechangenotifyer; + const tag: integer; const aforce: boolean; + const ainfo: fileinfoty); + procedure changed; + property path: filenamety read fpath; + end; + + dirchangedeventty = procedure(const sender: tdirinfo) of object; + +{$ifdef mswindows} + handlearty = array of thandle; +{$endif} + + tdirchangethread = class(tsemthread) + private +{$ifdef mswindows} + sem: cardinal; + dirdescriptors: handlearty; +{$endif} + fdirs: array of tdirinfo; +{$ifdef UNIX} + fsigqueue: array[0..sigpuffermask] of integer; + fsiginpo,fsigoutpo: integer; + procedure changesignal(const afd: integer); +{$endif} + procedure dochange(const afd: integer); + procedure deletedirinfo(index: integer); + protected + function execute(thread: tmsethread): integer; override; + public + constructor Create; + destructor Destroy; override; + procedure addnotification(const sender: tfilechangenotifyer; + const filename: filenamety; + const tag: integer; const force: boolean); + procedure removenotification(const sender: tfilechangenotifyer; + const filename: filenamety; tag: integer); + procedure clear; + //filename = '' -> filename nicht auswerten, + //onchanged = nil -> onchanged nicht auswerten. tag = 0 -> tag nicht auswerten + end; + + tfilechangenotifyer = class(tactcomponent) + private + fonfilechanged: filechangedeventty; + fpath: filenamety; + feventtag: integer; + procedure dofilechanged(const sender: tfilechangenotifyer; + const info: filechangeinfoty); + procedure setpath(const Value: filenamety); + procedure removepath; + procedure addpath; + procedure seteventtag(const Value: integer); + protected + procedure loaded; override; + procedure receiveevent(const event: tobjectevent); override; + public + destructor destroy; override; + procedure addnotification(const filename: filenamety; const atag: integer = 0; + const force: boolean = false); + procedure removenotification(const filename: filenamety; atag: integer = 0); + procedure clear; + published + property onfilechanged: filechangedeventty read fonfilechanged write fonfilechanged; + property path: filenamety read fpath write setpath; + property eventtag: integer read feventtag write seteventtag default 0; + + end; + +implementation +uses + msedatalist,rtlconsts,msesysintf1,msesysintf,mselist,msearrayutils +{$ifdef mswindows} + ,windows +{$else} + ,mselibc +{$endif} + ; +var + fchangethread: tdirchangethread; + +function changethread: tdirchangethread; +begin + if fchangethread = nil then begin + fchangethread:= tdirchangethread.Create; + end; + result:= fchangethread; +end; + +{$ifdef UNIX} +var + dirinfosig: integer; + +procedure DirChanged(SigNum : Integer; context: psiginfo; p: pointer); cdecl; + //kernel 2.6.25.18 does not return si_fd! +begin + if SigNum = dirinfosig then begin + if fchangethread <> nil then begin + fchangethread.changesignal(context^._sigpoll.si_fd); + end; + end; +end; + +const + notifyflags = DN_MODIFY or DN_CREATE or DN_DELETE or DN_RENAME or DN_ATTRIB; + +function adddir(const sender: tdirchangethread; + const name: filenamety): integer; +var +{$ifdef linux} + flags: longword; + action: tsigactionex; +{$endif} + str1: string; +begin + str1:= ansistring(name); + result:= mselibc.open(PChar(str1),o_rdonly); +// if sys_openfile(name,fm_read,[],[],result) = sye_ok then begin +{$ifdef linux} + if result >= 0 then begin + FillChar(action, SizeOf(action), 0); + with action do begin + sa_sigaction:= @DirChanged; + sa_flags := SA_SIGINFO or SA_RESTART; + end; + Flags:= notifyflags; + if not((sigactionex(dirinfosig,action, nil) = 0) and + (fcntl(result, F_SETSIG,[dirinfosig]) = 0) and + (fcntl(result, F_NOTIFY,[Flags]) = 0)) then begin + sys_closefile(result); //es hat nicht geklappt + result:= -1; + exit; + end; + unblocksignal(dirinfosig); + end; +{$endif} +end; + +{$ENDIF unix} + +{ tdirinfo } + +constructor tdirinfo.create(afd: integer; const apath: filenamety); +begin + fdirhandle:= afd; + fpath:= apath; + inherited create; +end; + +destructor tdirinfo.destroy; +begin + {$ifdef mswindows} + findclosechangenotification(fdirhandle); + {$else} + sys_closefile(fdirhandle); + {$endif} + inherited +end; + +procedure tdirinfo.deleteinfo(index: integer); +var + info1: array[0..sizeof(filechangeinfo1ty)-1] of byte; +begin + move(ffileinfos[index],info1,sizeof(info1)); + move(ffileinfos[index+1],ffileinfos[index], + (length(ffileinfos)-index-1)*sizeof(ffileinfos[0])); + move(info1,ffileinfos[high(ffileinfos)],sizeof(info1)); + setlength(ffileinfos,high(ffileinfos)); +end; + +procedure tdirinfo.addfile(root: boolean; const sender:tfilechangenotifyer; + const tag: integer; const aforce: boolean; const ainfo: fileinfoty); +var + int1: integer; +begin + int1:= length(ffileinfos); + setlength(ffileinfos,int1+1); + with ffileinfos[int1] do begin + info.dir:= fpath; + info.infovorher:= ainfo; + info.tag:= tag; + info.force:= aforce; + isroot:= root; + owner:= sender; + end; +end; + +type + tfilechangeevent = class(tasyncevent) + public + info: filechangeinfoty; + end; + +procedure tdirinfo.changed; +const + notcheckflags = [fc_accesstime,fc_ctime]; //ctime is unreliable in freebsd +var + int1: integer; + bo1: boolean; + str1: string; + aevent: tfilechangeevent; +begin +{$ifdef UNIX} + {$ifdef linux} + fcntl(fdirhandle,F_NOTIFY,[notifyflags]); + {$endif} +{$endif} + for int1:= 0 to length(ffileinfos) - 1 do begin + with ffileinfos[int1] do begin + if isroot then begin + bo1:= getfileinfo(filedir(fpath),info.info); + end + else begin + bo1:= getfileinfo(fpath+info.infovorher.name,info.info); + end; + if bo1 then begin + info.changed:= compfileinfos(info.infovorher,info.info); + end + else begin + bo1:= not (fc_removed in info.changed); //report only once + info.changed:= [fc_removed]; + end; + if isroot and (info.changed = []) then begin + include(info.changed,fc_direntries); + end; + if info.force then begin + include(info.changed,fc_force); + info.force:= false; + end; + if bo1 and (info.changed - notcheckflags <> []) then begin + aevent:= tfilechangeevent.Create(ievent(owner),0); + aevent.info:= info; + application.postevent(aevent); + str1:= ansistring(info.infovorher.name); + info.infovorher:= info.info; + info.infovorher.name:= filenamety(str1); + if not (fc_removed in info.changed) then begin + info.changed:= []; + end; + end; + end; + end; +end; + +constructor tdirchangethread.Create; +begin + {$ifdef mswindows} + setlength(dirdescriptors,1); + sem:= createsemaphore(nil,0,bigint,nil); + dirdescriptors[0]:= sem; + {$endif} + inherited Create({$ifdef FPC}@{$endif}execute); +end; + +destructor tdirchangethread.Destroy; +begin + terminate; + clear; +{$ifdef mswindows} + closehandle(sem); +{$endif} + inherited; +end; + +procedure tdirchangethread.deletedirinfo(index: integer); +begin + lock; + fdirs[index].Free; + + move(fdirs[index+1],fdirs[index],(length(fdirs)-index-1)*sizeof(fdirs[0])); + setlength(fdirs,length(fdirs)-1); +{$ifdef mswindows} + deleteitem(pointerarty(dirdescriptors),index+1); + releasesemaphore(sem,1,nil); +{$endif} + unlock; +end; + +procedure tdirchangethread.clear; +var + int1: integer; +begin + lock; + for int1:= 0 to length(fdirs) - 1 do begin + fdirs[int1].Free; + end; + setlength(fdirs,0); +{$ifdef mswindows} + setlength(dirdescriptors,1); + releasesemaphore(sem,1,nil); +{$endif} + unlock; +end; + +{$ifdef UNIX} +procedure tdirchangethread.changesignal(const afd: integer); +var + int1: integer; +begin + if not terminated then begin + int1:= fsigoutpo; + while int1 <> fsiginpo do begin + if fsigqueue[int1] = afd then begin + exit; //allready seen + end; + int1:= (int1 + 1) and sigpuffermask; + end; + int1:= (fsiginpo + 1) and sigpuffermask; + if int1 <> fsigoutpo then begin + fsigqueue[fsiginpo]:= afd; +// fsiginpo:= int1; + interlockedexchange(fsiginpo,int1); + end; + sempost; + end; +end; +{$endif} + +procedure tdirchangethread.dochange(const afd: integer); +var + int1: integer; +begin + if terminated or application.terminated then begin + exit; + end; + lock; + try + if afd = -1 then begin + for int1:= 0 to high(fdirs) do begin + fdirs[int1].changed; + end; + end + else begin + for int1:= 0 to high(fdirs) do begin + if (fdirs[int1].fdirhandle = afd) then begin + //ev. unzuverlaessig bei wiederverwendetem fd? + fdirs[int1].changed; + break; + end; + end; + end; + finally + unlock; + end; +end; + +function tdirchangethread.execute(thread: tmsethread): integer; +{$ifdef mswindows} +var + Obj: DWORD; + Handles: handlearty; + fafd: thandle; +begin + result:= 0; + handles:= nil; //compilerwarning + while not Terminated and not application.terminated do begin + lock; + handles:= copy(dirdescriptors); + unlock; + Obj := WaitForMultipleObjects(length(handles), @Handles[0], False, INFINITE); + if not terminated and not application.terminated then begin + if obj <> wait_failed then begin //else closed handle + obj:= obj - wait_object_0; + if (obj > 0) and (integer(obj) < length(handles)) then begin + fafd:= handles[obj]; + FindNextChangeNotification(fafd); + dochange(fafd); + end; + end; + end; + end; +end; +{$else} //unix +{$ifdef linux} +var + int1: integer; +{$endif} +begin + while not terminated do begin + {$ifdef linux} + semwait; + while not terminated and not (application.terminated) and + (fsiginpo <> fsigoutpo) do begin + int1:= fsigoutpo; + interlockedexchange(fsigoutpo,(fsigoutpo + 1) and sigpuffermask); + dochange(fsigqueue[int1]); + end; + {$else} + semwait(500000); //freebsd needs polling + if not terminated and not (application.terminated) then begin + dochange(-1); + end; + {$endif} + if not terminated then begin + sleep(500); + end; + end; + result:= 0; +end; +{$endif} + +procedure tdirchangethread.addnotification(const sender: tfilechangenotifyer; + const filename: filenamety; const tag: integer; + const force: boolean); +var + int1: integer; + apath: filenamety; + fname: filenamety; + wstr1: filenamety; + dirinfo: tdirinfo; + info: fileinfoty; +{$ifdef mswindows} + fd: thandle; +{$else} + fd: integer; +{$endif} + +begin + wstr1:= filepath(filename); + if not getfileinfo(wstr1,info) then begin +{$ifdef FPC} + raise EFCreateError.CreateFmt(SFCreateError,[filepath(FileName), + sys_geterrortext(mselasterror)]); +{$else} + + {$if RTLVersion > 14.1} + raise EFOpenError.CreateResFmt(@SFOpenErrorEx, [filepath(FileName), + SysErrorMessage(mselasterror)]); + {$else} + raise EFOpenError.CreateResFmt(@SFOpenError, [filepath(FileName), + SysErrorMessage(mselasterror)]); + {$ifend} +{$endif} + end; + if info.extinfo1.filetype = ft_dir then begin + apath:= filepath(wstr1,fk_dir); + fname:= ''; + end + else begin + splitfilepath(wstr1,apath,fname); +// apath:= extractfilepath(str1); +// fname:= extractfilename(str1); + end; + tosysfilepath1(apath); + dirinfo:= nil; + for int1:= 0 to length(fdirs) - 1 do begin + if fdirs[int1].path = apath then begin + dirinfo:= fdirs[int1]; + break; + end; + end; + lock; + if dirinfo = nil then begin + int1:= length(fdirs); +{$ifdef mswindows} + if iswin95 then begin + fd:= FindFirstChangeNotificationA(PChar(string(apath)), + False, FILE_NOTIFY_CHANGE_FILE_NAME or FILE_NOTIFY_CHANGE_DIR_NAME or + FILE_NOTIFY_CHANGE_ATTRIBUTES or FILE_NOTIFY_CHANGE_SIZE or + file_notify_change_last_write or file_notify_change_security); + end + else begin + fd:= FindFirstChangeNotificationW(PwideChar(apath), + False, FILE_NOTIFY_CHANGE_FILE_NAME or FILE_NOTIFY_CHANGE_DIR_NAME or + FILE_NOTIFY_CHANGE_ATTRIBUTES or FILE_NOTIFY_CHANGE_SIZE or + file_notify_change_last_write or file_notify_change_security); + end; + if fd <> invalid_handle_value then begin + setlength(dirdescriptors,int1+2); + dirdescriptors[int1+1]:= fd; +{$else unix} + fd:= adddir(self,apath); + if fd >= 0 then begin +{$endif} + setlength(fdirs,int1+1); + dirinfo:= tdirinfo.Create(fd,apath); + fdirs[int1]:= dirinfo; + + {$ifdef mswindows} + releasesemaphore(sem,1,nil); + {$endif} + end; + end; + if dirinfo <> nil then begin + dirinfo.addfile(fname = '',sender,tag,force,info); + end; + unlock; +end; + +procedure tdirchangethread.removenotification(const sender: tfilechangenotifyer; + const filename: filenamety; tag: integer); +var + apath,aname: filenamety; + int1,int2: integer; + +begin + if filename = '' then begin + apath:= ''; + end + else begin + apath:= tosysfilepath(filepath(filename,fk_dir)); + end; + lock; + for int1:= 0 to length(fdirs) - 1 do begin + with fdirs[int1] do begin + if (apath = '') or (fpath = apath) then begin + int2:= 0; + while int2 < length(ffileinfos) do begin + with ffileinfos[int2] do begin + if isroot and (owner = sender) and + ((tag = 0) or (info.tag = tag)) then begin + deleteinfo(int2); + end + else begin + inc(int2); + end; + end; + end; + end; + end; + end; + if filename = '' then begin + apath:= ''; + aname:= ''; + end + else begin + splitfilepath(filename,apath,aname); + end; + tosysfilepath1(apath); + for int1:= 0 to length(fdirs) - 1 do begin + with fdirs[int1] do begin + if (apath = '') or (fpath = apath) then begin + int2:= 0; + while int2 < length(ffileinfos) do begin + with ffileinfos[int2] do begin + if ((aname = '') or (info.infovorher.name = aname)) and + (owner = sender) and ((tag = 0) or (info.tag = tag)) then begin + deleteinfo(int2); + end + else begin + inc(int2); + end; + end; + end; + end; + end; + end; + int1:= 0; + while int1 < length(fdirs) do begin + if length(fdirs[int1].ffileinfos) = 0 then begin + deletedirinfo(int1); + end + else begin + inc(int1); + end; + end; + unlock; +end; + +{ tfilechangenotifyer } + +destructor tfilechangenotifyer.destroy; +begin + clear; + inherited; +end; + +procedure tfilechangenotifyer.dofilechanged(const sender: tfilechangenotifyer; + const info: filechangeinfoty); +begin + if assigned(fonfilechanged) then begin + fonfilechanged(self,info); + end; +end; + +procedure tfilechangenotifyer.setpath(const Value: filenamety); +begin + if fpath <> value then begin + removepath; + fpath := Value; + addpath; + end; +end; + +procedure tfilechangenotifyer.seteventtag(const Value: integer); +begin + if feventtag <> value then begin + removepath; + feventtag := Value; + addpath; + end; +end; + +procedure tfilechangenotifyer.loaded; +begin + inherited; + addpath; +end; + +procedure tfilechangenotifyer.receiveevent(const event: tobjectevent); +begin + if event is tfilechangeevent then begin + dofilechanged(self,tfilechangeevent(event).info); + end + else begin + inherited; + end; +end; + +procedure tfilechangenotifyer.addpath; +begin + if (fpath <> '') and (componentstate * [csdesigning,csloading] = []) then begin + addnotification(fpath,feventtag); + end; +end; + +procedure tfilechangenotifyer.removepath; +begin + if (fpath <> '') and (componentstate * [csdesigning,csloading] = []) then begin + removenotification(fpath,feventtag); + end; +end; + +procedure tfilechangenotifyer.addnotification(const filename: filenamety; + const atag: integer = 0; const force: boolean = false); +begin + changethread.addnotification(self,filename,atag,force); +end; + +procedure tfilechangenotifyer.removenotification(const filename: filenamety; + atag: integer = 0); +begin + if fchangethread <> nil then begin + fchangethread.removenotification(self,filename,atag); + end; +end; + +procedure tfilechangenotifyer.clear; +begin + removenotification(''); +end; + +initialization +{$ifdef UNIX} + dirinfosig:= sigrtmin + 10; + if dirinfosig > sigrtmax then begin + dirinfosig:= sigrtmax; + end; +{$endif unix} +finalization + freeandnil(fchangethread); +end. diff --git a/mseide-msegui/lib/common/sysutils/msefilemacros.pas b/mseide-msegui/lib/common/sysutils/msefilemacros.pas new file mode 100644 index 0000000..918d8a7 --- /dev/null +++ b/mseide-msegui/lib/common/sysutils/msefilemacros.pas @@ -0,0 +1,158 @@ +{ MSEgui Copyright (c) 2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} + +unit msefilemacros; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msemacros; + +function filemacros(): macroinfoarty; + +implementation +uses + msefileutils,msetypes{msestrings}; + +var + ffilemacros: macroinfoarty; + +function filemacros(): macroinfoarty; +begin + result:= ffilemacros; +end; + +function file_mse(const sender: tmacrolist; + const params: msestringarty): msestring; +begin + result:= ''; + if params <> nil then begin + result:= tomsefilepath(params[0]); + end; +end; + +function file_sys(const sender: tmacrolist; + const params: msestringarty): msestring; +begin + result:= ''; + if params <> nil then begin + result:= tosysfilepath(params[0]); + end; +end; + +function file_path(const sender: tmacrolist; + const params: msestringarty): msestring; +begin + result:= ''; + if params <> nil then begin + result:= filepath(params[0]); + end; +end; + +function file_file(const sender: tmacrolist; + const params: msestringarty): msestring; + //no trailing path delimiter +begin + result:= ''; + if params <> nil then begin + result:= filepath(params[0],fk_file,true); + end; +end; + +function file_dir(const sender: tmacrolist; + const params: msestringarty): msestring; +begin + result:= ''; + if params <> nil then begin + result:= filepath(params[0],fk_dir,true); + end; +end; + +function file_name(const sender: tmacrolist; + const params: msestringarty): msestring; +begin + result:= ''; + if params <> nil then begin + result:= filename(params[0]); + end; +end; + +function file_namebase(const sender: tmacrolist; + const params: msestringarty): msestring; +begin + result:= ''; + if params <> nil then begin + result:= filenamebase(params[0]); + end; +end; + +function file_ext(const sender: tmacrolist; + const params: msestringarty): msestring; +begin + result:= ''; + if params <> nil then begin + result:= fileext(params[0]); + end; +end; + +function file_noname(const sender: tmacrolist; + const params: msestringarty): msestring; +begin + result:= ''; + if params <> nil then begin + result:= filedir(params[0]); + end; +end; + +function file_noext(const sender: tmacrolist; + const params: msestringarty): msestring; +begin + result:= ''; + if params <> nil then begin + result:= removefileext(params[0]); + end; +end; + +const + filemacroconst: array[0..9] of macroinfoty = ( + (name: 'FILE_MSE'; value: ''; handler: macrohandlerty(@file_mse); + expandlevel: 0), //convert to mse format + (name: 'FILE_SYS'; value: ''; handler: macrohandlerty(@file_sys); + expandlevel: 0), //convert to sys format + (name: 'FILE_PATH'; value: ''; handler: macrohandlerty(@file_path); + expandlevel: 0), //absolute path + (name: 'FILE_FILE'; value: ''; handler: macrohandlerty(@file_FILE); + expandlevel: 0), //no trailing path delimiter + (name: 'FILE_DIR'; value: ''; handler: macrohandlerty(@file_dir); + expandlevel: 0), //trailing path delimiter + (name: 'FILE_NAME'; value: ''; handler: macrohandlerty(@file_name); + expandlevel: 0), //no directory part + (name: 'FILE_NAMEBASE'; value: ''; handler: macrohandlerty(@file_namebase); + expandlevel: 0), //no directory and name extension part + (name: 'FILE_EXT'; value: ''; handler: macrohandlerty(@file_ext); + expandlevel: 0), //file name extension + (name: 'FILE_NONAME'; value: ''; handler: macrohandlerty(@file_noname); + expandlevel: 0), //directory part only + (name: 'FILE_NOEXT'; value: ''; handler: macrohandlerty(@file_noext); + expandlevel: 0) //no file name extension + ); + +procedure initfilemacros(); +var + int1: integer; +begin + setlength(ffilemacros,length(filemacroconst)); + for int1:= 0 to high(filemacroconst) do begin + ffilemacros[int1]:= filemacroconst[int1]; + end; +end; + +initialization + initfilemacros(); +end. diff --git a/mseide-msegui/lib/common/sysutils/mseguiprocess.pas b/mseide-msegui/lib/common/sysutils/mseguiprocess.pas new file mode 100644 index 0000000..226c355 --- /dev/null +++ b/mseide-msegui/lib/common/sysutils/mseguiprocess.pas @@ -0,0 +1,114 @@ +{ MSEgui Copyright (c) 2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseguiprocess; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseprocess,msetypes{msestrings}; + +type + guiprocessoptionty = (prog_waitdialog, + prog_cancontinue); //continue button in wait dialog + guiprocessoptionsty = set of guiprocessoptionty; + + tguiprocess = class(tmseprocess) + private + fdialogcaption: msestring; + fdialoggaption: msestring; + fdialogtext: msestring; + foptionsgui: guiprocessoptionsty; + function getcancontinue: boolean; + procedure setcancontinue(const avalue: boolean); + protected + procedure setactive(const avalue: boolean) override; + function getdialogcaption: msestring virtual; + function getdialogtext: msestring virtual; + procedure cancelev(const sender: tobject); + procedure continueev(const sender: tobject); + procedure doprocfinished() override; + public + property cancontinue: boolean read getcancontinue write setcancontinue; + published + property dialogcaption: msestring read fdialogcaption write fdialoggaption; + property dialogtext: msestring read fdialogtext write fdialogtext; + property optionsgui: guiprocessoptionsty read foptionsgui + write foptionsgui default []; + end; + +implementation +uses + msegui; + +{ tguiprocess } + +function tguiprocess.getcancontinue: boolean; +begin + result:= prog_cancontinue in foptionsgui; +end; + +procedure tguiprocess.setcancontinue(const avalue: boolean); +begin + if avalue then begin + optionsgui:= optionsgui + [prog_cancontinue]; + end + else begin + optionsgui:= optionsgui - [prog_cancontinue]; + end; +end; + +procedure tguiprocess.setactive(const avalue: boolean); +begin + inherited; + if (prog_waitdialog in foptionsgui) and avalue and active then begin + if prog_cancontinue in foptionsgui then begin + application.waitdialog(nil,getdialogtext(),getdialogcaption(),@cancelev,nil, + nil,@continueev); + end + else begin + application.waitdialog(nil,getdialogtext(),getdialogcaption(),@cancelev); + end; + end; +end; + +function tguiprocess.getdialogcaption: msestring; +begin + result:= fdialogcaption; + if result = '' then begin + result:= 'Process' + end; +end; + +function tguiprocess.getdialogtext: msestring; +begin + result:= fdialogtext; + if result = '' then begin + result:= 'Running...' + end; +end; + +procedure tguiprocess.cancelev(const sender: tobject); +begin + kill(); +end; + +procedure tguiprocess.continueev(const sender: tobject); +begin + active:= false; +end; + +procedure tguiprocess.doprocfinished(); +begin + inherited; + if (prog_waitdialog in foptionsgui) and application.waitstarted() then begin + application.terminatewait(); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/sysutils/mseinputcontroller.pas b/mseide-msegui/lib/common/sysutils/mseinputcontroller.pas new file mode 100644 index 0000000..8ee873d --- /dev/null +++ b/mseide-msegui/lib/common/sysutils/mseinputcontroller.pas @@ -0,0 +1,242 @@ +{ MSEgui Copyright (c) 1999-2006 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseinputcontroller; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifndef FPC}{$ifdef linux} {$define UNIX} {$endif}{$endif} + +interface + +uses + Classes,msethread,msetypes,mseclasses; + +type + + tinputcontroller = class; + + fileinputeventty = procedure (sender: tinputcontroller; + const activefiles: integerarty) of object; + + tinputcontroller = class(tmsethread) + private + factive: boolean; + finputfiles: integerarty; + ainputfiles: integerarty; + foninputavailable: fileinputeventty; + fchanged: boolean; + readyfiles: integerarty; + procedure inputavailable; + procedure getfiles; + procedure setactive(const Value: boolean); + procedure psetinputfiles(const Value: integerarty); + protected + function execute(thread: tmsethread): integer; override; + public + constructor create; + procedure setinputfiles(files: array of integer); + property active: boolean read factive write setactive; + property inputfiles: integerarty read finputfiles write psetinputfiles; + property oninputavailable: fileinputeventty read foninputavailable + write foninputavailable; + end; + + tinputcontrollercomp = class(tmsecomponent) + private + fcontroller: tinputcontroller; + function getinputfiles: integerarty; + function getoninputavailable: fileinputeventty; + procedure psetinputfiles(const Value: integerarty); + procedure setactive(const Value: boolean); + procedure setoninputavailable(const Value: fileinputeventty); + function getactive: boolean; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + + procedure setinputfiles(files: array of integer); + published + property active: boolean read getactive write setactive default false; + property inputfiles: integerarty read getinputfiles write psetinputfiles; + property oninputavailable: fileinputeventty read getoninputavailable + write setoninputavailable; + end; + + +implementation +uses + mseapplication, +{$ifdef UNIX} + mselibc; +{$else} + msesysutils; + +type + tfdset = integer; //dummys + tfdsetpoty = ^tfdset; +const + fd_setsize = 1; + +procedure fd_zero(fdset: tfdset); +begin +end; +procedure fd_set(index: integer;fdset: tfdset); +begin +end; +function fd_isset(index: integer; fdset: tfdset): boolean; +begin + result:= false; +end; +function select(size: integer; fdset: tfdsetpoty; po1,po2,po3: pointer): integer; +begin + result:= 0; +end; +{$endif} + +{ tinputcontroller } + +function tinputcontroller.execute(thread: tmsethread): integer; +var + fdset: tfdset; + timeout: timeval; + int1,int2: integer; +begin + fd_zero(fdset); + repeat + if factive then begin + timeout.tv_sec:= 0; + timeout.tv_usec:= 100000; + if fchanged then begin + application.synchronize(getfiles); + fd_zero(fdset); + end; + for int1:= 0 to length(ainputfiles) - 1 do begin + fd_set(ainputfiles[int1],fdset); + end; + int1:= select(fd_setsize,@fdset,nil,nil,@timeout); + if not fchanged then begin + if (int1 > 0) then begin + int2:= 0; + setlength(readyfiles,length(ainputfiles)); + for int1:= 0 to length(ainputfiles) - 1 do begin + if fd_isset(ainputfiles[int1],fdset) then begin + readyfiles[int2]:= ainputfiles[int1]; + inc(int2); + end; + end; + setlength(readyfiles,int2); + application.synchronize(inputavailable); + end; + end; + end; + if not factive then begin + sys_threadschedyield(0); + end; + until terminated; + result:= 0; +end; + +procedure tinputcontroller.getfiles; +begin + ainputfiles:= finputfiles; + fchanged:= false; +end; + +procedure tinputcontroller.setactive(const Value: boolean); +begin + factive := Value; +end; + +procedure tinputcontroller.psetinputfiles(const Value: integerarty); +var + bo1: boolean; +begin + bo1:= factive; + factive:= false; + finputfiles:= Value; + fchanged:= true; + factive:= bo1; +end; + +procedure tinputcontroller.inputavailable; +begin + if factive and not fchanged and assigned(foninputavailable) then begin + foninputavailable(self,readyfiles); + end; +end; + +procedure tinputcontroller.setinputfiles(files: array of integer); +var + intar: integerarty; + int1: integer; +begin + setlength(intar,length(files)); + for int1:= 0 to length(intar)-1 do begin + intar[int1]:= files[int1]; + end; + psetinputfiles(intar); +end; + +constructor tinputcontroller.create; +begin + inherited create(execute); +end; + +{ tinputcontrollercomp } + +constructor tinputcontrollercomp.create(aowner: tcomponent); +begin + inherited; + fcontroller:= tinputcontroller.create; +end; + +destructor tinputcontrollercomp.destroy; +begin + fcontroller.free; + inherited; +end; + +function tinputcontrollercomp.getactive: boolean; +begin + result:= fcontroller.active; +end; + +function tinputcontrollercomp.getinputfiles: integerarty; +begin + result:= fcontroller.inputfiles; +end; + +function tinputcontrollercomp.getoninputavailable: fileinputeventty; +begin + result:= fcontroller.oninputavailable; +end; + +procedure tinputcontrollercomp.psetinputfiles(const Value: integerarty); +begin + fcontroller.inputfiles:= value; +end; + +procedure tinputcontrollercomp.setactive(const Value: boolean); +begin + fcontroller.active:= Value; +end; + +procedure tinputcontrollercomp.setinputfiles(files: array of integer); +begin + fcontroller.setinputfiles(files); +end; + +procedure tinputcontrollercomp.setoninputavailable( + const Value: fileinputeventty); +begin + fcontroller.oninputavailable:= value; +end; + +end. + diff --git a/mseide-msegui/lib/common/sysutils/msemacmacros.pas b/mseide-msegui/lib/common/sysutils/msemacmacros.pas new file mode 100644 index 0000000..27b04c8 --- /dev/null +++ b/mseide-msegui/lib/common/sysutils/msemacmacros.pas @@ -0,0 +1,73 @@ +{ MSEgui Copyright (c) 2015 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} + +unit msemacmacros; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msemacros; + +function macmacros(): macroinfoarty; + +implementation +uses + msetypes{msestrings},msesysintf; + +var + fmacmacros: macroinfoarty; + +function macmacros(): macroinfoarty; +begin + result:= fmacmacros; +end; + +function mac_ifdef(const sender: tmacrolist; + const params: msestringarty): msestring; + //name,[ifndef value[,ifdef value]] +var + po1: pmacroinfoty; +begin + result:= ''; + if params <> nil then begin + if sender.find(params[0],po1) then begin + if high(params) > 1 then begin + result:= params[2]; + end + else begin + result:= po1^.value; + end; + end + else begin + if high(params) > 0 then begin + result:= params[1]; + end; + end; + end; +end; + +const + macmacroconst: array[0..0] of macroinfoty = ( + (name: 'MAC_IFDEF'; value: ''; handler: macrohandlerty(@mac_ifdef); + expandlevel: 0) + ); + +procedure initmacmacros(); +var + int1: integer; +begin + setlength(fmacmacros,length(macmacroconst)); + for int1:= 0 to high(macmacroconst) do begin + fmacmacros[int1]:= macmacroconst[int1]; + end; +end; + +initialization + initmacmacros(); +end. diff --git a/mseide-msegui/lib/common/sysutils/msemime.pas b/mseide-msegui/lib/common/sysutils/msemime.pas new file mode 100644 index 0000000..d19dcfd --- /dev/null +++ b/mseide-msegui/lib/common/sysutils/msemime.pas @@ -0,0 +1,246 @@ +{ MSEgui Copyright (c) 2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msemime; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msegui,msedrag,msestrings,msetypes,msegraphutils,mseglob,mseguiglob,mseclasses, + msedragglob; + +type + + tmimedragobject = class; + + imimesource = interface(iobjectlink) + procedure convertmimedata(const sender: tmimedragobject; + var adata: string; const atypeindex: integer); + procedure convertmimetext(const sender: tmimedragobject; + var adata: msestring; const atypeindex: integer); + end; + + tmimedragobject = class(tdragobject,iobjectlink) + private + fdata: string; + ftext: msestring; + fobjectlinker: tobjectlinker; + procedure setformatindex(const avalue: integer); + protected + fformats: msestringarty; + fformatistext: booleanarty; + fformatindex: integer; + fwantedformatindex: integer; + fintf: imimesource; + function getdata: string; virtual; + function gettext: msestring; virtual; + procedure setdata(const avalue: string); virtual; + procedure settext(const avalue: msestring); virtual; + //iobjectlink + procedure link(const source,dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); + procedure unlink(const source,dest: iobjectlink; valuepo: pointer = nil); + procedure objevent(const asender: iobjectlink; const event: objecteventty); + function getinstance: tobject; + public + constructor create(const asender: tobject; var instance: tdragobject; + const apickpos: pointty; const aformats: array of msestring; + const aformatistext: array of boolean; + const aactions: dndactionsty = []; + const aintf: imimesource = nil); virtual; + constructor createwrite(const asender: tobject; var instance: tdragobject; + const apickpos: pointty; const aformats: array of msestring; + const aformatistext: array of boolean; + const aactions: dndactionsty = []; + const aintf: imimesource = nil); + destructor destroy; override; + function checkformat(const awanted: array of msestring): boolean; + property formats: msestringarty read fformats; //do not modify + property formatistext: booleanarty read fformatistext; //do not modify + property formatindex: integer read fformatindex + write setformatindex default -1; + //-1 -> none selected + property wantedformatindex: integer read fwantedformatindex + write fwantedformatindex default -1; + //-1 -> none selected + property data: string read getdata write setdata; + property text: msestring read gettext write settext; + function convertmimedata(const atypeindex: integer): string; virtual; + function convertmimetext(const atypeindex: integer): msestring; virtual; + end; + +implementation +uses + msearrayutils; + +{ tmimedragobject } + +constructor tmimedragobject.create(const asender: tobject; + var instance: tdragobject; const apickpos: pointty; + const aformats: array of msestring; + const aformatistext: array of boolean; + const aactions: dndactionsty = []; + const aintf: imimesource = nil); +begin + fobjectlinker:= tobjectlinker.create(iobjectlink(self),nil); + fformats:= opentodynarraym(aformats); + fformatistext:= opentodynarraybo(aformatistext); + setlength(fformatistext,length(fformats)); + factions:= aactions; + fformatindex:= -1; + fwantedformatindex:= -1; + fintf:= aintf; + if fintf <> nil then begin + fobjectlinker.link(iobjectlink(self),fintf); + end; + inherited create(asender,instance,apickpos,aactions); +end; + +constructor tmimedragobject.createwrite(const asender: tobject; + var instance: tdragobject; const apickpos: pointty; + const aformats: array of msestring; + const aformatistext: array of boolean; + const aactions: dndactionsty = []; + const aintf: imimesource = nil); +begin + include(fstate,dos_write); + create(asender,instance,apickpos,aformats,aformatistext,aactions,aintf); +end; + +destructor tmimedragobject.destroy; +begin + fobjectlinker.free; + inherited; +end; + +procedure tmimedragobject.setformatindex(const avalue: integer); +begin + if avalue < 0 then begin + fformatindex:= -1; + end + else begin + checkarrayindex(fformats,avalue); + fformatindex:= avalue; + end; +end; + +function tmimedragobject.checkformat( + const awanted: array of msestring): boolean; +var + int1,int2: integer; +begin + result:= false; + fformatindex:= -1; + fwantedformatindex:= -1; + for int1:= 0 to high(awanted) do begin + for int2:= 0 to high(fformats) do begin + if awanted[int1] = fformats[int2] then begin + result:= true; + fformatindex:= int2; + fwantedformatindex:= int1; + exit; + end; + end; + end; +end; + +function tmimedragobject.getdata: string; +begin + if fformatindex >= 0 then begin + result:= convertmimedata(fformatindex); + end + else begin + if fdata = '' then begin + result:= ansistring(ftext); + end + else begin + result:= fdata; + end; + end; +end; + +function tmimedragobject.gettext: msestring; +begin + if fformatindex >= 0 then begin + result:= convertmimetext(fformatindex); + end + else begin + if ftext = '' then begin + result:= msestring(fdata); + end + else begin + result:= ftext; + end; + end; +end; + +procedure tmimedragobject.setdata(const avalue: string); +begin + ftext:= ''; + fdata:= avalue; +end; + +procedure tmimedragobject.settext(const avalue: msestring); +begin + fdata:= ''; + ftext:= avalue; +end; + +function tmimedragobject.convertmimedata(const atypeindex: integer): string; +begin + if fdata = '' then begin + result:= ansistring(ftext); + end + else begin + result:= fdata; + end; + if fintf <> nil then begin + fintf.convertmimedata(self,result,atypeindex); + end; +end; + +function tmimedragobject.convertmimetext(const atypeindex: integer): msestring; +begin + if ftext = '' then begin + result:= msestring(fdata); + end + else begin + result:= ftext; + end; + if fintf <> nil then begin + fintf.convertmimetext(self,result,atypeindex); + end; +end; + +procedure tmimedragobject.link(const source: iobjectlink; + const dest: iobjectlink; valuepo: pointer = nil; + ainterfacetype: pointer = nil; once: boolean = false); +begin + fobjectlinker.link(source,dest,valuepo,ainterfacetype,once); +end; + +procedure tmimedragobject.unlink(const source: iobjectlink; + const dest: iobjectlink; valuepo: pointer = nil); +begin + fobjectlinker.unlink(source,dest,valuepo); +end; + +procedure tmimedragobject.objevent(const asender: iobjectlink; + const event: objecteventty); +begin + if (asender = fintf) and (event = oe_destroyed) then begin + destroy; + end; +end; + +function tmimedragobject.getinstance: tobject; +begin + result:= self; +end; + +end. diff --git a/mseide-msegui/lib/common/sysutils/mseprocess.pas b/mseide-msegui/lib/common/sysutils/mseprocess.pas new file mode 100644 index 0000000..3e911f5 --- /dev/null +++ b/mseide-msegui/lib/common/sysutils/mseprocess.pas @@ -0,0 +1,1044 @@ +{ MSEgui Copyright (c) 2010-2015 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseprocess; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,mseclasses,msepipestream,msestrings,msestatfile,msestat, + msesystypes,mseevent,msetypes,mseprocmonitor,mseapplication,msedatalist; +const + defaultpipewaitus = 0; +type + processstatety = (prs_listening,prs_waitcursor); + processstatesty = set of processstatety; + processoptionty = (pro_output,pro_erroroutput,pro_input,pro_errorouttoout, + pro_shell, //default on linux + pro_noshell, //default on windows, + pro_inactive,pro_nostdhandle, //windows only + pro_newconsole,pro_nowindow,pro_detached, //windows only + pro_allowsetforegroundwindow, //windows only + pro_group, //linux only + pro_sessionleader, //linux only + pro_settty, //linux only + pro_tty,pro_echo,pro_icanon, //linux only + pro_nowaitforpipeeof, + pro_nopipeterminate, //not used + pro_usepipewritehandles,pro_winpipewritehandles, + pro_waitcursor,pro_checkescape,pro_escapekill, + //terminate or kill process if esc pressed + pro_processmessages, + pro_ctrlc //for tterminal + ); + processoptionsty = set of processoptionty; +const + defaultprocessoptions = [pro_winpipewritehandles]; + //there is no other way on win32 to + //terminate read on a hanging process + defaultgetprocessoutputoptions = defaultprocessoptions + [pro_inactive]; + defaultgetprocessoutputoptionserrorouttoout = + defaultprocessoptions + [pro_inactive,pro_errorouttoout]; + defaultstartprocessoptions = defaultprocessoptions + [pro_inactive]; + +type + tcustommseprocess = class; + + tcustommseprocess = class(tactcomponent,istatfile,iprocmonitor) + private + finput: tpipewriterpers; + foutput: tpipereaderpers; + ferroroutput: tpipereaderpers; + ffilename: filenamety; + fparameter: msestring; + fstatfile: tstatfile; + fstatvarname: msestring; + factive: boolean; + fprochandle: prochandlety; + flastprochandle: prochandlety; + fonprocfinished: notifyeventty; + flistenid: ptruint; + fexitcode: integer; + fcommandline: msestring; + fcommandline1: msestring; + fworkingdirectory: filenamety; + fpipewaitus: integer; + fstatpriority: integer; + foncheckabort: updatebooleaneventty; + fparams: tmsestringdatalist; + fenvvars: tmsestringdatalist; + procedure setoutput(const avalue: tpipereaderpers); + procedure seterroroutput(const avalue: tpipereaderpers); + function getactive: boolean; + procedure setstatfile(const avalue: tstatfile); + procedure updatecommandline; + function getcommandline: msestring; + procedure setcommandline(const avalue: msestring); + procedure procend; + procedure setinput(const avalue: tpipewriterpers); + procedure setparams(const avalue: tmsestringdatalist); + procedure setenvvars(const avalue: tmsestringdatalist); + protected + foptions: processoptionsty; + fstate: processstatesty; + procedure setoptions(const avalue: processoptionsty) virtual; + procedure setactive(const avalue: boolean); override; + procedure loaded; override; + procedure listen; + procedure unlisten; + procedure finalizeexec; + procedure receiveevent(const event: tobjectevent); override; + procedure waitforpipeeof; + procedure doprocfinished virtual; + procedure postprocessdied; + + //istatfile + procedure dostatread(const reader: tstatreader); + procedure dostatwrite(const writer: tstatwriter); + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + //iprocmonitor + procedure processdied(const aprochandle: prochandlety; + const aexecresult: integer; const adata: pointer); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function running: boolean; + procedure terminate; + procedure kill; + function waitforprocess: integer; overload; //returns exitcode + function waitforprocess(const atimeoutus: integer): boolean; overload; + //true if process finished + property commandline: msestring read getcommandline write setcommandline; + //overrides filename and parameter + property prochandle: prochandlety read fprochandle; + property lastprochandle: prochandlety read flastprochandle; + property exitcode: integer read fexitcode; + + property filename: filenamety read ffilename write ffilename; + property parameter: msestring read fparameter write fparameter; + property workingdirectory: filenamety read fworkingdirectory + write fworkingdirectory; + property params: tmsestringdatalist read fparams write setparams; + property envvars: tmsestringdatalist read fenvvars write setenvvars; + property active: boolean read getactive write setactive default false; + property options: processoptionsty read foptions write setoptions + default defaultprocessoptions; + property pipewaitus: integer read fpipewaitus write fpipewaitus + default defaultpipewaitus; + //0 -> infinite + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read getstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + property input: tpipewriterpers read finput write setinput; + property output: tpipereaderpers read foutput write setoutput; + property erroroutput: tpipereaderpers read ferroroutput write seterroroutput; + property onprocfinished: notifyeventty read fonprocfinished + write fonprocfinished; + property oncheckabort: updatebooleaneventty + read foncheckabort write foncheckabort; + end; + + tmseprocess = class(tcustommseprocess) + published + property filename; + property parameter; + property workingdirectory; + property params; + property envvars; + property active; + property options; + property pipewaitus; + property statfile; + property statvarname; + property statpriority; + property input; + property output; + property erroroutput; + property onprocfinished; + property oncheckabort; + end; + +function getprocessoutput(const filename: msestring; + const aparams: msestringarty; + const todata: string; + out fromdata: string; out errordata: string; + const atimeoutus: integer = -1; + const aoptions: processoptionsty = + defaultgetprocessoutputoptions; + const acheckabort: updatebooleaneventty = nil; + const amaxdatalen: integer = 0): integer; + //returns program exitcode, -1 in case of error + //-2 in case of maxdatalen reached + +function getprocessoutput(const acommandline: msestring; const todata: string; + out fromdata: string; out errordata: string; + const atimeoutus: integer = -1; + const aoptions: processoptionsty = + defaultgetprocessoutputoptions; + const acheckabort: updatebooleaneventty = nil; + const amaxdatalen: integer = 0): integer; + //returns program exitcode, -1 in case of error + //-2 in case of maxdatalen reached +function getprocessoutput(const acommandline: msestring; const todata: string; + out fromdata: string; + const atimeoutus: integer = -1; + const aoptions: processoptionsty = + defaultgetprocessoutputoptionserrorouttoout; + const acheckabort: updatebooleaneventty = nil; + const amaxdatalen: integer = 0): integer; + //returns program exitcode, -1 in case of error + //-2 in case of maxdatalen reached +function getprocessoutput(out prochandle: prochandlety; + const acommandline: msestring; const todata: string; + out fromdata: string; out errordata: string; + const atimeoutus: integer = -1; + const aoptions: processoptionsty = + defaultgetprocessoutputoptions; + const acheckabort: updatebooleaneventty = nil; + const amaxdatalen: integer = 0): integer; + //returns program exitcode, -1 in case of error + //-2 in case of maxdatalen reached +function getprocessoutput(out prochandle: prochandlety; + const acommandline: msestring; const todata: string; + out fromdata: string; + const atimeoutus: integer = -1; + const aoptions: processoptionsty = + defaultgetprocessoutputoptionserrorouttoout; + const acheckabort: updatebooleaneventty = nil; + const amaxdatalen: integer = 0): integer; + //returns program exitcode, -1 in case of error + //-2 in case of maxdatalen reached + +function startprocessandwait(const acommandline: msestring; + const atimeoutus: integer = -1; + const aoptions: processoptionsty = + defaultgetprocessoutputoptions; + const acheckabort: updatebooleaneventty = nil): integer; + //returns program exitcode, -1 in case of error +implementation +uses + mseprocutils,msefileutils,sysutils,msesysintf,msebits,msesys, + msesysutils; +type + tstringprocess = class(tcustommseprocess) + private + ffromdata: string; + ffromcount: sizeint; + ferrordata: string; + ferrorcount: sizeint; + fmaxdatalen: sizeint; + fmaxdatareached: boolean; + procedure readdata(const sender: tpipereader; + var adata: string; var acount: sizeint); + procedure fromavail(const sender: tpipereader); + procedure erroravail(const sender: tpipereader); + public + constructor create(const amaxdatalen: sizeint = 0); reintroduce; + end; + +function getprocessoutput1(const prochandlepo: pprochandlety; + const acommandline: msestring; const aparams: msestringarty; + const todata: string; + out fromdata: string; out errordata: string; + const atimeout: integer; const aoptions: processoptionsty; + const acheckabort: updatebooleaneventty; + const amaxdatalen: integer): integer; + //returns program exitcode, -1 in case of error, + //-2 in case of maxdatalen reached +var + proc1: tstringprocess; + i1: int32; +begin + result:= -1; + proc1:= tstringprocess.create(amaxdatalen); + try + with proc1 do begin + if aparams <> nil then begin + filename:= acommandline; + params.count:= length(aparams); + for i1:= 0 to high(aparams) do begin + params[i1]:= aparams[i1]; + end; + end + else begin + commandline:= acommandline; + end; + options:= aoptions + [pro_output,pro_erroroutput,pro_input]; + oncheckabort:= acheckabort; + active:= true; + if prochandlepo <> nil then begin + application.lock; + prochandlepo^:= prochandle; + application.unlock; + end; + if todata <> '' then begin + try + input.pipewriter.write(todata); + except + end; + input.pipewriter.close; + end; + if atimeout < 0 then begin + result:= waitforprocess; + end + else begin + if waitforprocess(atimeout) then begin + result:= exitcode; + end; + end; + if fmaxdatareached then begin + result:= -2; + end; + if result <> -1 then begin + setlength(proc1.ffromdata,proc1.ffromcount); + fromdata:= proc1.ffromdata; + setlength(proc1.ferrordata,proc1.ferrorcount); + errordata:= proc1.ferrordata; + end; + end; + finally + application.lock; + if prochandlepo <> nil then begin + prochandlepo^:= invalidprochandle; + end; + proc1.release; +// proc1.free; //calls application.unlockall + application.unlock; + end; +end; + +function startprocessandwait(const acommandline: msestring; + const atimeoutus: integer = -1; + const aoptions: processoptionsty = + defaultstartprocessoptions; + const acheckabort: updatebooleaneventty = nil): integer; + //returns program exitcode, -1 in case of error + //-2 in case of maxdatalen reached +var + proc1: tcustommseprocess; +begin + result:= -1; + proc1:= tcustommseprocess.create(nil); + try + with proc1 do begin + commandline:= acommandline; + options:= aoptions - [pro_output,pro_erroroutput,pro_input]; + oncheckabort:= acheckabort; + active:= true; + if atimeoutus < 0 then begin + result:= waitforprocess; + end + else begin + if waitforprocess(atimeoutus) then begin + result:= exitcode; + end; + end; + end; + finally + proc1.free; + end; +end; + +function getprocessoutput(const filename: msestring; + const aparams: msestringarty; + const todata: string; + out fromdata: string; out errordata: string; + const atimeoutus: integer = -1; + const aoptions: processoptionsty = + defaultgetprocessoutputoptions; + const acheckabort: updatebooleaneventty = nil; + const amaxdatalen: integer = 0): integer; + //returns program exitcode, -1 in case of error + //-2 in case of maxdatalen reached +begin + result:= getprocessoutput1(nil,filename,aparams,todata,fromdata,errordata, + atimeoutus,aoptions,acheckabort,amaxdatalen); +end; + +function getprocessoutput(const acommandline: msestring; const todata: string; + out fromdata: string; out errordata: string; + const atimeoutus: integer = -1; + const aoptions: processoptionsty = + defaultgetprocessoutputoptions; + const acheckabort: updatebooleaneventty = nil; + const amaxdatalen: integer = 0): integer; +begin + result:= getprocessoutput1(nil,acommandline,nil,todata,fromdata,errordata, + atimeoutus,aoptions,acheckabort,amaxdatalen); +end; + +function getprocessoutput(const acommandline: msestring; const todata: string; + out fromdata: string; + const atimeoutus: integer = -1; + const aoptions: processoptionsty = + defaultgetprocessoutputoptionserrorouttoout; + const acheckabort: updatebooleaneventty = nil; + const amaxdatalen: integer = 0): integer; +var + str1: string; +begin + result:= getprocessoutput1(nil,acommandline,nil,todata,fromdata,str1, + atimeoutus,aoptions,acheckabort,amaxdatalen); +end; + +function getprocessoutput(out prochandle: prochandlety; + const acommandline: msestring; const todata: string; + out fromdata: string; out errordata: string; + const atimeoutus: integer = -1; + const aoptions: processoptionsty = + defaultgetprocessoutputoptions; + const acheckabort: updatebooleaneventty = nil; + const amaxdatalen: integer = 0): integer; +begin + result:= getprocessoutput1(@prochandle,acommandline,nil,todata,fromdata,errordata, + atimeoutus,aoptions,acheckabort,amaxdatalen); +end; + +function getprocessoutput(out prochandle: prochandlety; + const acommandline: msestring; const todata: string; + out fromdata: string; + const atimeoutus: integer = -1; + const aoptions: processoptionsty = + defaultgetprocessoutputoptionserrorouttoout; + const acheckabort: updatebooleaneventty = nil; + const amaxdatalen: integer = 0): integer; +var + str1: string; +begin + result:= getprocessoutput1(@prochandle,acommandline,nil,todata,fromdata,str1, + atimeoutus,aoptions,acheckabort,amaxdatalen); +end; + +{ tcustommseprocess } + +constructor tcustommseprocess.create(aowner: tcomponent); +begin + foptions:= defaultprocessoptions; + fprochandle:= invalidprochandle; + finput:= tpipewriterpers.create(self); + foutput:= tpipereaderpers.create(self); + ferroroutput:= tpipereaderpers.create(self); + fpipewaitus:= defaultpipewaitus; + fparams:= tmsestringdatalist.create; + fenvvars:= tmsestringdatalist.create; + inherited; +end; + +destructor tcustommseprocess.destroy; +begin + finalizeexec(); + finput.free(); + foutput.free(); //calls application.unlockall + ferroroutput.free(); //calls application.unlockall + fparams.free(); + fenvvars.free(); + inherited; +// finput.free; +// foutput.free; +// ferroroutput.free; +end; + +procedure tcustommseprocess.setoutput(const avalue: tpipereaderpers); +begin + foutput.assign(avalue); +end; + +procedure tcustommseprocess.seterroroutput(const avalue: tpipereaderpers); +begin + ferroroutput.assign(avalue); +end; + +function tcustommseprocess.getactive: boolean; +begin + if componentstate * [csloading,csdesigning] <> [] then begin + result:= factive; + end + else begin + result:= fprochandle <> invalidprochandle; + end; +end; + +procedure tcustommseprocess.doprocfinished; +begin + if canevent(tmethod(fonprocfinished)) then begin + fonprocfinished(self); + end; + { + if not (pro_nopipeterminate in foptions) then begin + foutput.pipereader.terminate; + ferroroutput.pipereader.terminate; + end; + } +end; + +procedure tcustommseprocess.procend; +begin + fprochandle:= invalidprochandle; + foutput.pipereader.writehandle:= invalidfilehandle; + ferroroutput.pipereader.writehandle:= invalidfilehandle; + waitforpipeeof; + if prs_waitcursor in fstate then begin + exclude(fstate,prs_waitcursor); + application.endwait; + end; + finalizeexec(); + doprocfinished; +end; + +procedure tcustommseprocess.postprocessdied; +begin + exclude(fstate,prs_listening); + application.postevent(tchildprocevent.create(ievent(self),fprochandle, + fexitcode,pointer(flistenid))); + fprochandle:= invalidprochandle; +end; + +procedure tcustommseprocess.setactive(const avalue: boolean); +var + outp: tpipereader; + erroroutp: tpipereader; + inp: tpipewriter; + sessionleader: boolean; + group: integer; + opt1: execoptionsty; +// str1: ansistring; +// mstr1: msestring; +begin + sessionleader:= false; + group:= -1; + if componentstate * [csloading,csdesigning] <> [] then begin + factive:= avalue; + end + else begin + if avalue <> active then begin + outp:= nil; + erroroutp:= nil; + inp:= nil; + finalizeexec(); + if avalue then begin + application.lock; + try + updatecommandline; + if pro_output in foptions then begin + outp:= foutput.pipereader; + end; + if pro_erroroutput in foptions then begin + erroroutp:= ferroroutput.pipereader; + end + else begin + if pro_errorouttoout in foptions then begin + erroroutp:= foutput.pipereader; + end; + end; + if pro_input in foptions then begin + inp:= finput.pipewriter; + end; + if pro_group in foptions then begin + group:= 0; + end; + if pro_sessionleader in foptions then begin + sessionleader:= true; + group:= -1; + end; + opt1:= []; + if sessionleader then begin + include(opt1,exo_sessionleader); + end; + if pro_settty in foptions then begin + include(opt1,exo_settty); + end; + if pro_shell in foptions then begin + include(opt1,exo_shell); + end; + if pro_noshell in foptions then begin + include(opt1,exo_noshell); + end; + if pro_inactive in foptions then begin + include(opt1,exo_inactive); + end; + if pro_tty in foptions then begin + include(opt1,exo_tty); + end; + if pro_echo in foptions then begin + include(opt1,exo_echo); + end; + if pro_icanon in foptions then begin + include(opt1,exo_icanon); + end; + if pro_nostdhandle in foptions then begin + include(opt1,exo_nostdhandle); + end; + if pro_newconsole in foptions then begin + include(opt1,exo_newconsole); + end; + if pro_nowindow in foptions then begin + include(opt1,exo_nowindow); + end; + if pro_detached in foptions then begin + include(opt1,exo_detached); + end; + if pro_allowsetforegroundwindow in foptions then begin + include(opt1,exo_allowsetforegroundwindow); + end; + if pro_usepipewritehandles in foptions then begin + include(opt1,exo_usepipewritehandles); + end; + if pro_winpipewritehandles in foptions then begin + include(opt1,exo_winpipewritehandles); + end; + { + if fworkingdirectory <> '' then begin + mstr1:= filepath(fworkingdirectory); + sys_tosysfilepath(mstr1); + str1:= mstr1; + end; + } + try + fprochandle:= execmse2(syscommandline(fcommandline1), + inp,outp,erroroutp,group,opt1,fworkingdirectory, + fparams.asarray,fenvvars.asarray); +// fprochandle:= execmse2(syscommandline(fcommandline1), +// inp,outp,erroroutp,group,opt1,str1); + except + fprochandle:= invalidprochandle; + flastprochandle:= invalidprochandle; + finalizeexec(); + fexitcode:= -1; + raise; + end; + flastprochandle:= fprochandle; + if fprochandle = invalidprochandle then begin + finalizeexec; + end + else begin + if pro_waitcursor in foptions then begin + include(fstate,prs_waitcursor); + application.beginwait; + end; + listen; + end; + finally + application.unlock; + end; + end; + end; + end; +end; + +procedure tcustommseprocess.receiveevent(const event: tobjectevent); +begin + if (event.kind = ek_childproc) then begin + with tchildprocevent(event) do begin + if data = pointer(flistenid) then begin + procend; + end; + end; + end + else begin + inherited; + end; +end; + +function tcustommseprocess.waitforprocess(const atimeoutus: integer): boolean; + //true if process finished +var + int1: integer; + bo1: boolean; + ts1: longword; + procerr: processexiterrorty; + i2: int32; +begin + result:= false; + procerr:= pee_ok; + bo1:= prs_listening in fstate; + unlisten; + if bo1 then begin + int1:= application.unlockall; + if (foptions*[pro_checkescape,pro_processmessages] <> []) or + assigned(foncheckabort) then begin + ts1:= timestep(atimeoutus); + i2:= 100000; + if (atimeoutus >= 0) and (atimeoutus < i2) then begin + i2:= atimeoutus; + end; + repeat + if pro_processmessages in foptions then begin + application.relockall(int1); + application.processmessages; + int1:= application.unlockall; + end; + procerr:= mseprocutils.getprocessexitcode(fprochandle,fexitcode,i2); + bo1:= (procerr <> pee_timeout) or ((atimeoutus >= 0) and timeout(ts1)); + if not bo1 then begin + if (pro_checkescape in foptions) then begin + bo1:= application.waitescaped; + end; + if assigned(foncheckabort) then begin + foncheckabort(self,bo1); + end; + end; + until bo1; + result:= procerr in [pee_ok,pee_signaled]; + if not result then begin + if pro_escapekill in foptions then begin + killprocess(fprochandle); + end + else begin + terminateprocess(fprochandle); + end; + procend(); + end; + end + else begin + procerr:= mseprocutils.getprocessexitcode(fprochandle,fexitcode,atimeoutus); + result:= procerr in [pee_ok,pee_signaled]; + end; + application.relockall(int1); + end + else begin + result:= true; + end; + if result or (procerr = pee_error) then begin + procend(); + end; +end; + +function tcustommseprocess.waitforprocess: integer; +begin + result:= -1; + if waitforprocess(-1) then begin + result:= fexitcode; + end; +end; + +procedure tcustommseprocess.setstatfile(const avalue: tstatfile); +begin + setstatfilevar(istatfile(self),avalue,fstatfile); +end; + +function tcustommseprocess.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +procedure tcustommseprocess.dostatread(const reader: tstatreader); +begin + ffilename:= reader.readmsestring('file',ffilename); + fparameter:= reader.readmsestring('param',fparameter); +end; + +procedure tcustommseprocess.dostatwrite(const writer: tstatwriter); +begin + writer.writemsestring('file',ffilename); + writer.writemsestring('param',fparameter); +end; + +procedure tcustommseprocess.statreading; +begin + //dummy +end; + +procedure tcustommseprocess.statread; +begin + //dummy +end; + +procedure tcustommseprocess.loaded; +begin + inherited; + active:= factive; +end; + +procedure tcustommseprocess.listen; +begin + application.lock; + if not (prs_listening in fstate) and + (fprochandle <> invalidprochandle) then begin + pro_listentoprocess(fprochandle,iprocmonitor(self),pointer(flistenid)); + include(fstate,prs_listening); + end; + application.unlock; +end; + +procedure tcustommseprocess.unlisten; +begin + application.lock; + try + inc(flistenid); + if prs_listening in fstate then begin + pro_unlistentoprocess(fprochandle,iprocmonitor(self)); + end; + exclude(fstate,prs_listening); + finally + application.unlock; + end; +end; + +procedure tcustommseprocess.finalizeexec; +begin + finput.pipewriter.close(); + foutput.pipereader.terminateandwait(); + ferroroutput.pipereader.terminateandwait(); + application.lock; + unlisten; + if fprochandle <> invalidprochandle then begin + pro_killzombie(fprochandle); + fprochandle:= invalidprochandle; + end; + application.unlock; + foutput.pipereader.close(); + ferroroutput.pipereader.close(); +end; + +procedure tcustommseprocess.waitforpipeeof; +var + int1,int2,int3: integer; + lwo1: longword; +begin + if not (pro_nowaitforpipeeof in foptions) then begin + int1:= application.unlockall; + int2:= foutput.pipereader.overloadsleepus; + int3:= ferroroutput.pipereader.overloadsleepus; + foutput.pipereader.overloadsleepus:= 0; + ferroroutput.pipereader.overloadsleepus:= 0; + lwo1:= timestep(fpipewaitus); +// sleepus(0); //shed_yield + sys_schedyield(); + while not (foutput.pipereader.eof and ferroroutput.pipereader.eof) and + ((fpipewaitus = 0) or not timeout(lwo1)) do begin + sleepus(1000); //wait for last chars + end; + application.relockall(int1); + if (foutput.pipereader.eof and ferroroutput.pipereader.eof) then begin + foutput.pipereader.waitfor; //process data + ferroroutput.pipereader.waitfor; //process data + end; + foutput.pipereader.overloadsleepus:= int2; + ferroroutput.pipereader.overloadsleepus:= int3; + end; +end; + +procedure tcustommseprocess.processdied(const aprochandle: prochandlety; + const aexecresult: integer; const adata: pointer); +begin + if (prs_listening in fstate) and (adata = pointer(flistenid)) then begin + fexitcode:= aexecresult; + postprocessdied; + end +end; + +procedure tcustommseprocess.updatecommandline; +begin + if fcommandline <> '' then begin + fcommandline1:= fcommandline; + end + else begin + fcommandline1:= quotefilename(tosysfilepath(ffilename)); + if fparameter <> '' then begin + fcommandline1:= fcommandline1 + ' ' + fparameter; + end; + end; +end; + +function tcustommseprocess.getcommandline: msestring; +begin + updatecommandline; + result:= fcommandline1; +end; + +procedure tcustommseprocess.setcommandline(const avalue: msestring); +begin + fcommandline:= avalue; +end; + + +{ +function tcustommseprocess.waitforprocess: integer; +var + int1: integer; +begin + int1:= application.unlockall; + try + unlisten; + result:= fexitcode; + if running then begin + result:= mseprocutils.waitforprocess(fprochandle); + fexitcode:= result; + procend; + end; + finally + application.relockall(int1); + end; +end; + +function tcustommseprocess.waitforprocess(const atimeoutus: integer): boolean; + //true if process finished +var + int1: integer; +begin + int1:= application.unlockall; + try + unlisten; + if running then begin + result:= mseprocutils.getprocessexitcode(fprochandle,fexitcode,atimeoutus); + if result then begin + procend; + end + else begin + application.lock; + try + listen; + result:= mseprocutils.getprocessexitcode(fprochandle,fexitcode,0); + if result then begin + unlisten; + end; + finally + application.unlock; + end; + if result then begin + procend; + end; + end; + end + else begin + result:= true; + end; + finally + application.relockall(int1); + end; +end; +} + +function tcustommseprocess.running: boolean; +begin + result:= fprochandle <> invalidprochandle; +end; + +procedure tcustommseprocess.terminate; +begin +{$ifdef mswindows} + kill(); +{$else} + application.lock; + try + if running then begin + syserror(sys_terminateprocess(fprochandle)); + end; + finally + application.unlock; + end; +{$endif} +end; + +procedure tcustommseprocess.kill; +begin + application.lock; + try + if running then begin + finput.pipewriter.close; + syserror(sys_killprocess(fprochandle)); + foutput.pipereader.terminate; + ferroroutput.pipereader.terminate; +// syserror(sys_killprocess(fprochandle)); + end; + finally + application.unlock; + end; +end; + +procedure tcustommseprocess.setoptions(const avalue: processoptionsty); +{$ifndef FPC} +const + mask1: processoptionsty = [pro_erroroutput,pro_errorouttoout]; + mask2: processoptionsty = [pro_shell,pro_noshell]; + mask3: processoptionsty = [pro_sessionleader,pro_group]; +{$endif} +begin + foptions:= processoptionsty( + {$ifdef FPC} + setsinglebit(longword(avalue), + longword(foptions), + [longword([pro_erroroutput,pro_errorouttoout]), + longword([pro_shell,pro_noshell]), + longword([pro_sessionleader,pro_group])])); + {$else} + setsinglebitar32(longword(avalue), + longword(foptions), + [longword(mask1),longword(mask2),longword(mask3)])); + {$endif} + exclude(foptions,pro_nopipeterminate); + if foptions * [pro_nowaitforpipeeof{,pro_nopipeterminate}] = [] then begin + exclude(foptions,pro_usepipewritehandles); + end; +end; + +function tcustommseprocess.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +procedure tcustommseprocess.setinput(const avalue: tpipewriterpers); +begin + finput.assign(avalue); +end; + +procedure tcustommseprocess.setparams(const avalue: tmsestringdatalist); +begin + fparams.assign(avalue); +end; + +procedure tcustommseprocess.setenvvars(const avalue: tmsestringdatalist); +begin + fenvvars.assign(avalue); +end; + +{ tstringprocess } + +constructor tstringprocess.create(const amaxdatalen: sizeint = 0); +begin + fmaxdatalen:= amaxdatalen; + inherited create(nil); + options:= options + [pro_output,pro_erroroutput,pro_input]; + output.pipereader.oninputavailable:= {$ifdef FPC}@{$endif}fromavail; + erroroutput.pipereader.oninputavailable:= {$ifdef FPC}@{$endif}erroravail; +end; + +procedure tstringprocess.readdata(const sender: tpipereader; + var adata: string; var acount: sizeint); +begin + if sender.active then begin + if adata = '' then begin + adata:= sender.readbuffer; //try to get complete small results without + //buffer oversize + acount:= length(adata); + end + else begin + sender.appenddatastring(adata,acount); + end; + if (fmaxdatalen > 0) and (acount > fmaxdatalen) then begin + kill(); + fmaxdatareached:= true; + end; + end; +end; + +procedure tstringprocess.fromavail(const sender: tpipereader); +begin + readdata(sender,ffromdata,ffromcount); +end; + +procedure tstringprocess.erroravail(const sender: tpipereader); +begin + readdata(sender,ferrordata,ferrorcount); +end; + +end. diff --git a/mseide-msegui/lib/common/sysutils/mseprocmonitorcomp.pas b/mseide-msegui/lib/common/sysutils/mseprocmonitorcomp.pas new file mode 100644 index 0000000..7d108c7 --- /dev/null +++ b/mseide-msegui/lib/common/sysutils/mseprocmonitorcomp.pas @@ -0,0 +1,145 @@ +{ MSEgui Copyright (c) 2008-2015 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseprocmonitorcomp; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +interface +uses + msetypes,mseclasses,msesystypes,mseevent,mseprocmonitor,mseprocutils, + msestrings; + +type + proclisteninfoty = record + prochandle: prochandlety; + data: pointer; + end; + proclisteninfoarty = array of proclisteninfoty; + + childdiedeventty = procedure(const sender: tobject; + const prochandle: prochandlety; const execresult: integer; + const data: pointer) of object; + + tprocessmonitor = class(tmsecomponent,iprocmonitor) + private + fonchilddied: childdiedeventty; + finfos: proclisteninfoarty; + protected + procedure receiveevent(const event: tobjectevent); override; + procedure internalunlistentoprocess(const aprochandle: prochandlety; + const internal: boolean); + //iprocmonitor + procedure processdied(const aprochandle: prochandlety; + const aexecresult: integer; const adata: pointer); + public + destructor destroy; override; + function listentoprocess(const aprochandle: prochandlety; + const adata: pointer = nil): boolean; + //does nothing and returns false if aprochandle = invalidprochandle + procedure unlistentoprocess(const aprochandle: prochandlety); + function exec(const acommandline: msestring; + const aoptions: execoptionsty = [] +// const inactive: boolean = true; + //windows only +// const nostdhandle: boolean = false + //windows only + ): prochandlety; + published + property onchilddied: childdiedeventty read fonchilddied write fonchilddied; + end; + +implementation +uses + msedatalist,mseapplication,msearrayutils; + +{ tprocessmonitor } + +destructor tprocessmonitor.destroy; +var + int1: integer; +begin + for int1:= high(finfos) downto 0 do begin + pro_unlistentoprocess(finfos[int1].prochandle,iprocmonitor(self)); + end; + inherited; +end; + +function tprocessmonitor.listentoprocess(const aprochandle: prochandlety; + const adata: pointer): boolean; +begin + result:= aprochandle <> invalidprochandle; + if result then begin + setlength(finfos,high(finfos)+2); + with finfos[high(finfos)] do begin + prochandle:= aprochandle; + data:= adata; + end; + pro_listentoprocess(aprochandle,iprocmonitor(self),adata); + end; +end; + +procedure tprocessmonitor.internalunlistentoprocess( + const aprochandle: prochandlety; const internal: boolean); +var + int1: integer; +begin + for int1:= high(finfos) downto 0 do begin + with finfos[int1] do begin + if prochandle = aprochandle then begin + if not internal then begin + pro_unlistentoprocess(aprochandle,iprocmonitor(self)); + end; + deleteitem(finfos,typeinfo(proclisteninfoarty),int1); + end; + end; + end; +end; + +procedure tprocessmonitor.processdied(const aprochandle: prochandlety; + const aexecresult: integer; const adata: pointer); +begin + application.postevent(tchildprocevent.create(ievent(self),aprochandle, + aexecresult,adata)); +end; + +procedure tprocessmonitor.receiveevent(const event: tobjectevent); +begin + if (event.kind = ek_childproc) then begin + with tchildprocevent(event) do begin + if canevent(tmethod(fonchilddied)) then begin + fonchilddied(self,prochandle,execresult,data); + end; + internalunlistentoprocess(prochandle,true); + end; + end + else begin + inherited; + end; +end; + +procedure tprocessmonitor.unlistentoprocess(const aprochandle: prochandlety); +begin + internalunlistentoprocess(aprochandle, false); +end; + +function tprocessmonitor.exec(const acommandline: msestring; + const aoptions: execoptionsty = [] +// const inactive: boolean = true; +// const nostdhandle: boolean = false + ): prochandlety; +begin + application.lock; + try + result:= execmse4(acommandline,aoptions{inactive,nostdhandle}); + listentoprocess(result); + finally + application.unlock; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/sysutils/mseprocutils.pas b/mseide-msegui/lib/common/sysutils/mseprocutils.pas new file mode 100644 index 0000000..1a8c5c0 --- /dev/null +++ b/mseide-msegui/lib/common/sysutils/mseprocutils.pas @@ -0,0 +1,1510 @@ +{ MSEgui Copyright (c) 1999-2015 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseprocutils; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifndef FPC}{$ifdef linux} {$define UNIX} {$endif}{$endif} +{$if fpc_fullversion >= 30000} + {$define mse_fpc_3} +{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + {$ifdef mswindows}windows{$else}mselibc{$endif}, + msetypes,msestream,msepipestream,sysutils,msesysutils,msesystypes,msesys, + msestrings; + +type + pipedescriptorty = record + {$ifdef mswindows} + readdes: ptrint; + writedes: ptrint; + {$else} + readdes: integer; + writedes: integer; + {$endif} + end; + execoptionty = (exo_shell, //default on Linux + exo_noshell, //default on Windows + exo_inactive, //windows only + exo_nostdhandle, //windows only + exo_newconsole, //windows only + exo_nowindow, //windows only + exo_detached, //windows only + exo_allowsetforegroundwindow, //windows only + exo_sessionleader, //linux only + exo_settty, //linux only + exo_tty,exo_echo,exo_icanon, //linux only + exo_usepipewritehandles,exo_winpipewritehandles + ); + execoptionsty = set of execoptionty; +const + pipewritehandlemask = [exo_usepipewritehandles + {$ifdef mswindows},exo_winpipewritehandles{$endif}]; +type + processexiterrorty = (pee_ok,pee_signaled,pee_timeout,pee_error); + +function getprocessexitcode(prochandle: prochandlety; out exitcode: integer; + const timeoutus: integer = 0): processexiterrorty; + //<0 -> no timeout, closes handle + //exicode = -signum - 256 by pee_signaled (unix only) + +function waitforprocess(prochandle: prochandlety): integer; + +function execmse(const commandline: msestring; //sys format + const options: execoptionsty = []; + const workingdirectory: filenamety = ''; + const params: msestringarty = nil; + const envvars: msestringarty = nil): boolean; +//starts program, true if OK + +function execmse4(const commandline: msestring; //sys format + const options: execoptionsty = []; + const workingdirectory: filenamety = ''; + const params: msestringarty = nil; + const envvars: msestringarty = nil): prochandlety; +//starts program, returns processhandle, execerror on error +//don't forget closehandle on windows! + +function execmse1(const commandline: msestring; //sys format + topipe: pinteger = nil; + frompipe: pinteger = nil; + errorpipe: pinteger = nil; + groupid: integer = -1; //-1 -> keine, 0 = childpid + const options: execoptionsty = []; + frompipewritehandle: pinteger = nil; + errorpipewritehandle: pinteger = nil; + const workingdirectory: filenamety = ''; + const params: msestringarty = nil; + const envvars: msestringarty = nil): prochandlety; +//starts program, returns processhandle, execerror on error +//don't forget closehandle on windows! +//creates pipes + +function execmse2(const commandline: msestring; //sys format + topipe: tpipewriter = nil; + frompipe: tpipereader = nil; + errorpipe: tpipereader = nil; + groupid: integer = -1; //-1 -> keine, 0 = childpid + const options: execoptionsty = []; + const workingdirectory: filenamety = ''; + const params: msestringarty = nil; + const envvars: msestringarty = nil): prochandlety; +//starts program, returns processhandle, execerror on error +//don't forget closehandle on windows! +//creates pipes + +function execmse3(const commandline: msestring; //sys format + topipe: pinteger = nil; + frompipe: pinteger = nil; + errorpipe: pinteger = nil; + groupid: integer = -1; //-1 -> keine, 0 = childpid + const options: execoptionsty = []; + frompipewritehandle: pinteger = nil; + errorpipewritehandle: pinteger = nil; + const workingdirectory: filenamety = ''; + const params: msestringarty = nil; + const envvars: msestringarty = nil): prochandlety; +//starts program, returns processhandle, execerror on error +//don't forget closehandle on windows! +//uses existing file handles + +function execwaitmse(const commandline: msestring; //sys format + const options: execoptionsty = []; + const workingdirectory: filenamety = ''; + const params: msestringarty = nil; + const envvars: msestringarty = nil): integer; overload; +//runs programm, waits for program termination, returns program exitcode +//inactive true -> no console window (win32 only) + +procedure killprocess(handle: prochandlety); +procedure killprocesstree(handle: prochandlety); +function terminateprocess(handle: prochandlety): integer; + //sendet sigterm, bringt exitresult, -1 on error +procedure killprocessid(id: procidty); +procedure killprocesstreeid(id: procidty); + +function getpid: procidty; + +function getprocesstree: procitemarty; +function getprocesschildren(const pid: procidty): procidarty; +function getallprocesschildren(const pid: procidty): procidarty; +{moved to msegui +function activateprocesswindow(const procid: integer; + const araise: boolean = true): boolean; + //true if ok +} +function pipe(out desc: pipedescriptorty; write: boolean): boolean; + //true if ok + + {$ifdef UNIX} +function getpseudoterminal(out name: string): integer; + +type + procinfoty = record + pid: integer; + comm: string; + state: char; + ppid: integer; + pgrp: integer; + session: integer; + tty_nr: integer; + tpgid: integer; + flags: longword; + minflt: longword; + cminflt: longword; + majflt: longword; + cmajflt: longword; + utime: longword; + stime: longword; + cutime: longint; + cstime: longint; + priority: longint; + nice: longint; + null: longint; + itrealvalue: longint; + starttime: longword; + vsize: longword; + rss: longint; + rlim: longword; + startcode: longword; + endcode: longword; + startstack: longword; + kstkesp: longword; + kstkeip: longword; + signal: longword; + blocked: longword; + sigignore: longword; + sigcatch: longword; + wchan: longword; + nswap: longword; + cnswap: longword; + exitsignal: integer; + processor: integer; + end; + +function getprocinfo(pid: procidty): procinfoty; +function getchildpid(pid: procidty): procidarty; +function getinnerstpid(pid: procidty): procidty; +function getppid2(pid: procidty): procidty; + + {$endif} +type + eexecerror = class(msesysutils.eoserror) + end; + +implementation +uses + msesysintf1,msesysintf,mseprocmonitor,msearrayutils,mseformatstr, + mseapplication,msefileutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +procedure killprocesstree1(id: procidty); +var + ar1: procidarty; + int1: integer; +begin + ar1:= getprocesschildren(id); + for int1:= 0 to high(ar1) do begin + killprocesstree1(ar1[int1]); + killprocessid(ar1[int1]); + end; +end; + +procedure killprocesstree(handle: prochandlety); +begin +{$ifdef windows} + killprocesstree1(procidfromprochandle(handle)); +{$else} + killprocesstree1(handle); +{$endif} + killprocess(handle); +end; + +procedure killprocessid(id: procidty); +{$ifdef mswindows} +var + h1: prochandlety; +{$endif} +begin +{$ifdef mswindows} + h1:= windows.openprocess(process_terminate,false,id); + if h1 <> 0 then begin + windows.terminateprocess(h1,0); + windows.closehandle(h1); + end; +{$else} + killprocess(id); +{$endif} +end; + +procedure killprocesstreeid(id: procidty); +{$ifdef mswindows} +var + h1: prochandlety; +{$endif} +begin +{$ifdef mswindows} + h1:= windows.openprocess(process_terminate,false,id); + if h1 <> 0 then begin + killprocesstree(h1); + windows.closehandle(h1); + end; +{$else} + killprocesstree1(id); + killprocessid(id); +{$endif} +end; + +function getpid: procidty; +begin + result:= sys_getpid; +end; + +function compprocitem(const l,r): integer; +begin + result:= procitemty(l).pid - procitemty(r).pid; +end; + +function findprocitem(const l,r): integer; +begin + result:= procidty(l) - procitemty(r).pid; +end; + +function getprocesstree: procitemarty; +var + int1,int2: integer; +begin + result:= sys_getprocesses; + sortarray(result,sizeof(procitemty),{$ifdef FPC}@{$endif}compprocitem); + for int1:= 0 to high(result) do begin + if findarrayitem(result[int1].ppid,result,sizeof(procitemty), + {$ifdef FPC}@{$endif}findprocitem,int2) then begin + additem(winidarty(result[int2].children),result[int1].pid); + end; + end; +end; + +function getprocesschildren(const pid: procidty): procidarty; +var + ar1: procitemarty; + int2: integer; +begin + result:= nil; + if pid <> invalidprocid then begin + ar1:= getprocesstree; + if findarrayitem(pid,ar1,sizeof(procitemty), + {$ifdef FPC}@{$endif}findprocitem,int2) then begin + result:= ar1[int2].children; + end; + end; +end; + +function getallprocesschildren(const pid: procidty): procidarty; +var + ar1: procitemarty; + + procedure addproc(const pid: integer); + var + int1,int2: integer; + begin + if findarrayitem(pid,ar1,sizeof(procitemty), + {$ifdef FPC}@{$endif}findprocitem,int2) then begin + stackarray(winidarty(ar1[int2].children),winidarty(result)); + for int1:= 0 to high(ar1[int2].children) do begin + addproc(ar1[int2].children[int1]); + end; + end; + end; + +begin + ar1:= getprocesstree; + setlength(result,1); + result[0]:= pid; + addproc(pid); +end; + +procedure execerror(const errno: integer; const commandline: msestring); +begin + raise eexecerror.Create(errno, + ansistring('Can not execute "'+commandline+'".'+lineend)); +end; + +{$ifdef mswindows} +function getprocessexitcode(prochandle: prochandlety; out exitcode: integer; + const timeoutus: integer = 0): processexiterrorty; + //true if ok, close handle +var + dwo1: longword; + ca1: longword; +begin + result:= pee_error; + exitcode:= -1; + if prochandle <> invalidprochandle then begin + if timeoutus < 0 then begin + exitcode:= waitforprocess(prochandle); + if exitcode <> -1 then begin + result:= pee_ok; + end; + end + else begin + ca1:= timestep(timeoutus); + while true do begin + if getexitcodeprocess(prochandle,dwo1) then begin + if dwo1 <> still_active then begin + exitcode:= dwo1; + closehandle(prochandle); + result:= pee_ok; + break; + end + else begin + if (timeoutus = 0) or timeout(ca1) then begin + result:= pee_timeout; + break; + end; + sys_schedyield; + end; + end + else begin + exit; + end; + end; + end; + end; +end; + +function waitforprocess(prochandle: prochandlety): integer; +begin + result:= -1; + if waitforsingleobject(prochandle,infinite) = wait_object_0 then begin + getprocessexitcode(prochandle,result); + end; +// else begin +// raise eoserror.create(''); +// end; +end; + +function pipe(out desc: pipedescriptorty; write: boolean): boolean; + //true if ok + + procedure error; + begin + closehandle(desc.writedes); + closehandle(desc.readdes); + end; + +var + sa: security_attributes; + hdup: integer; + po1: pinteger; +begin + result:= false; + fillchar(sa,sizeof(sa),0); + sa.nlength:= sizeof(sa); + sa.bInheritHandle:= true; + if createpipe(ptruint(desc.readdes),ptruint(desc.writedes),@sa,0) then begin + if write then begin + po1:= @desc.writedes; + end + else begin + po1:= @desc.readdes; + end; + if not duplicatehandle(getcurrentprocess,po1^,getcurrentprocess,@hdup,0, + false,duplicate_same_access) then begin //non inheritable + error; + end + else begin + closehandle(po1^); + po1^:= hdup; + end; + result:= true; + end; +end; + +function execmse0(const commandline: msestring; topipe: pinteger = nil; + frompipe: pinteger = nil; + errorpipe: pinteger = nil; + groupid: integer = -1; //-1 -> keine, 0 = childpid + const options: execoptionsty = []; + frompipewritehandle: pinteger = nil; + errorpipewritehandle: pinteger = nil; + const workingdirectory: msestring = ''; + const params: msestringarty = nil; + const envvars: msestringarty = nil + ): prochandlety; +//startet programm, bringt processhandle, execerror wenn misslungen +//closehandle nicht vergessen! + +var + topipehandles,frompipehandles,errorpipehandles: pipedescriptorty; + + procedure execerr; + var + errorbefore: integer; + begin + errorbefore:= sys_getlasterror; + if errorbefore = 0 then begin + errorbefore:= 2; //filenotfound + end; + if topipehandles.writedes <> invalidfilehandle then closehandle(topipehandles.writedes); + if topipehandles.readdes <> invalidfilehandle then closehandle(topipehandles.readdes); + if frompipehandles.writedes <> invalidfilehandle then closehandle(frompipehandles.writedes); + if frompipehandles.readdes <> invalidfilehandle then closehandle(frompipehandles.readdes); + if errorpipehandles.writedes <> invalidfilehandle then closehandle(errorpipehandles.writedes); + if errorpipehandles.readdes <> invalidfilehandle then closehandle(errorpipehandles.readdes); + execerror(errorbefore,commandline); + end; + +var + startupinfo: {$ifdef mse_fpc_3}tstartupinfow{$else}tstartupinfo{$endif}; + creationflags: dword; + processinfo: tprocessinformation; + bo1: boolean; + mstr1: msestring; + wd1,cmd1,env1: msestring; + i1,i2,i3,i4: int32; +begin + creationflags:= 0; + result:= invalidprochandle; + fillchar(startupinfo,sizeof(startupinfo),0); + startupinfo.hStdInput:= stdinputhandle; + startupinfo.hStdoutput:= stdoutputhandle; + startupinfo.hStderror:= stderrorhandle; + + topipehandles.writedes:= invalidfilehandle; + topipehandles.readdes:= invalidfilehandle; + frompipehandles.writedes:= invalidfilehandle; + frompipehandles.readdes:= invalidfilehandle; + errorpipehandles.writedes:= invalidfilehandle; + errorpipehandles.readdes:= invalidfilehandle; + + if topipe <> nil then begin + if topipe^ = invalidfilehandle then begin + if not pipe(topipehandles,true) then execerr; + topipe^:= topipehandles.WriteDes; + startupinfo.hStdInput:= topipehandles.readdes; + end + else begin + startupinfo.hStdInput:= topipe^; + end; + end; + if frompipe <> nil then begin + if frompipe^ = invalidfilehandle then begin + if not pipe(frompipehandles,false) then execerr; + frompipe^:= frompipehandles.readDes; + startupinfo.hStdoutput:= frompipehandles.writedes; + end + else begin + startupinfo.hStdoutput:= frompipe^; + end; + end; + if errorpipe <> nil then begin + if errorpipe <> frompipe then begin + if errorpipe^ = invalidfilehandle then begin + if not pipe(errorpipehandles,false) then execerr; + errorpipe^:= errorpipehandles.readdes; + startupinfo.hStderror:= errorpipehandles.writedes; + end + else begin + startupinfo.hStderror:= errorpipe^; + end; + end + else begin + if frompipe^ <> invalidfilehandle then begin + errorpipe^:= frompipehandles.readdes; + startupinfo.hStderror:= frompipehandles.writedes; + end + else begin + startupinfo.hStderror:= frompipe^; + end; + end; + end; + if not (exo_nostdhandle in options) then begin + startupinfo.dwflags:= startupinfo.dwFlags or startf_usestdhandles; + end; + if exo_nowindow in options then begin + creationflags:= creationflags or create_no_window; + end; + if exo_newconsole in options then begin + creationflags:= creationflags or create_new_console; + end; + if exo_detached in options then begin + creationflags:= creationflags or detached_process; + end; + if (exo_allowsetforegroundwindow in options) and + assigned(allowsetforegroundwindow) then begin + allowsetforegroundwindow(asfw_any); + end; + if exo_inactive in options then begin + startupinfo.wShowWindow:= sw_hide; + startupinfo.dwflags:= startupinfo.dwFlags or startf_useshowwindow; + end; + wd1:= tosysfilepath(workingdirectory); + mstr1:= commandline; + for i1:= 0 to high(params) do begin + if params[i1] = '' then begin + mstr1:= mstr1 + ' ""'; + end + else begin + mstr1:= mstr1 + ' '+quotestring(params[i1],'"',false); + end; + end; + + cmd1:= copy(mstr1,1,bigint); //must be writeable for createprocessw + env1:= ''; + if envvars <> nil then begin + i2:= 0; + for i1:= 0 to high(envvars) do begin + i4:= length(envvars[i1]); + if i4 > 0 then begin + i2:= i2+i4; + end; + end; + setlength(env1,i2+length(envvars)); + i3:= 0; + for i1:= 0 to high(envvars) do begin + i4:= length(envvars[i1]); + if i4 > 0 then begin + move(pointer(envvars[i1])^,(pmsechar(pointer(env1))+i3)^, + (i4+1)*sizeof(msechar)); + i3:= i3 + i4 + 1; + end; + end; + end; //string has terminating #0 + + if exo_shell in options then begin + cmd1:= 'cmd.exe /q /c'+cmd1; + end; + if iswin95 then begin + bo1:= createprocessa(nil,pchar(ansistring(cmd1)),nil,nil,true,creationflags, + pointer(ansistring(env1)), + pointer(ansistring(wd1)), + {$ifdef mse_fpc_3}tstartupinfoa{$endif}(startupinfo),processinfo); + end + else begin + bo1:= createprocessw(nil,pmsechar(cmd1),nil,nil,true, + creationflags or create_unicode_environment, + pointer(env1), + pointer(wd1),startupinfo,processinfo); + end; + + if bo1 then begin + if topipehandles.readdes <> invalidfilehandle then begin + closehandle(topipehandles.readdes); + end; + if frompipehandles.writedes <> invalidfilehandle then begin + if frompipewritehandle <> nil then begin + frompipewritehandle^:= frompipehandles.writedes; + end + else begin + closehandle(frompipehandles.writedes); + end; + end; + if errorpipehandles.writedes <> invalidfilehandle then begin + if errorpipewritehandle <> nil then begin + errorpipewritehandle^:= errorpipehandles.writedes; + end + else begin + closehandle(errorpipehandles.writedes); + end; + end; + result:= processinfo.hProcess; + closehandle(processinfo.hThread); + end + else begin + execerr; + end; +end; + +procedure killprocess(handle: prochandlety); +begin + if handle <> invalidprochandle then begin + windows.terminateprocess(handle,0); + closehandle(handle); + end; +end; + +function terminateprocess(handle: prochandlety): integer; + //bricht process ab, kein exitresult +begin + result:= -1; + if handle <> invalidprochandle then begin + result:= 0; + killprocess(handle); + end; +end; + +{$endif} + +{$ifdef UNIX} +function getprocessexitcode(prochandle: prochandlety; out exitcode: integer; + const timeoutus: integer = 0): processexiterrorty; + //-1 -> no timeout +var + dwo1: longword; + cancel: boolean; + + function check(const apid: integer): boolean; + begin + result:= false; + if apid <> -1 then begin + result:= apid = prochandle; +// if result then begin +// exitcode:= wexitstatus(dwo1); +// end; + end + else begin + if sys_getlasterror <> eintr then begin + cancel:= true; + end; + end; + end; + + procedure setresult(); + begin + if wifsignaled(dwo1) then begin + result:= pee_signaled; + exitcode:= -wtermsig(dwo1)-256; + end + else begin + result:= pee_ok; + exitcode:= wexitstatus(dwo1); + end; + end; + +var + i1: int32; + +begin + result:= pee_error; + cancel:= false; + exitcode:= -1; + if prochandle <> invalidprochandle then begin + if check(waitpid(prochandle,@dwo1,wnohang)) then begin + setresult(); + exit; + end + else begin + if not cancel then begin + result:= pee_timeout; + end; + end; + + if (result = pee_timeout) and (timeoutus <> 0) then begin + if timeoutus < 0 then begin + repeat + until check(waitpid(prochandle,@dwo1,0)) or cancel; + if cancel then begin + result:= pee_error; + end + else begin + setresult(); +// result:= pee_ok; + end + end + else begin + i1:= timedwaitpid(prochandle,@dwo1,timeoutus); + case i1 of + -2: begin + result:= pee_timeout; + end; + else begin + if i1 >= 0 then begin + if i1 > 0 then begin + setresult(); +// exitcode:= wexitstatus(dwo1); +// if wifsignaled(dwo1) then begin +// result:= pee_signaled; +// end +// else begin +// result:= pee_ok; +// end; + end + else begin + result:= pee_timeout; + end; + end + else begin + result:= pee_error; + end; + end; + end; + end; + end; + end; +end; + +function waitforprocess(prochandle: prochandlety): integer; +var + dwo1: longword; + pid: integer; +begin + result:= -1; + while true do begin + pid:= waitpid(prochandle,@dwo1,0); + if pid <> -1 then begin + if wifsignaled(dwo1) then begin + result:= -wtermsig(dwo1)-256; + end + else begin + result:= wexitstatus(dwo1); + end; + break; + end + else begin + if sys_getlasterror <> eintr then begin + exit; +// result:= 0; //compilerwarning +// raise eoserror.create(''); + end; + end; + end; +end; + +function pipe(out desc: pipedescriptorty; write: boolean): boolean; + //returns errorcode, 0 if ok +begin + result:= mselibc.pipe(tpipedescriptors(desc)) = 0; + if result then begin + if write then begin + setcloexec(desc.writedes); + end + else begin + setcloexec(desc.readdes); + end; + end; +end; + +function getpseudoterminal(out name: string): integer; +const + buflen = 256; +var + buffer: array[0..buflen] of char; +begin + result:= getpt; + if result < 0 then begin + syserror(sye_lasterror); + end; + if (grantpt(result) < 0) or (unlockpt(result) < 0) then begin + syserror(sye_lasterror); + end; + if ptsname_r(result,@buffer,buflen) < 0 then begin + syserror(sye_lasterror); + end; + name:= buffer; +end; + +function execmse0(const commandline: msestring; topipe: pinteger = nil; + frompipe: pinteger = nil; + errorpipe: pinteger = nil; + groupid: integer = -1; //-1 -> keine, 0 = childpid + const options: execoptionsty = []; + frompipewritehandle: pinteger = nil; + errorpipewritehandle: pinteger = nil; + const workingdirectory: filenamety = ''; + const params: msestringarty = nil; + const envvars: msestringarty = nil + ): prochandlety; +const + shell = shortstring('/bin/sh'); + buflen = 256; +type + namebufferty = array[0..buflen] of char; +var + procid: integer; + topipehandles,frompipehandles,errorpipehandles: tpipedescriptors; + ptyout: integer;// = -1; + ptyerr: integer;// = -1; + ptynameout: namebufferty; + ptynameerr: namebufferty; + + procedure execerr; + var + errorbefore: integer; + begin + errorbefore:= sys_getlasterror; + if topipehandles.writedes <> invalidfilehandle then __close(topipehandles.writedes); + if topipehandles.readdes <> invalidfilehandle then __close(topipehandles.readdes); + if frompipehandles.writedes <> invalidfilehandle then __close(frompipehandles.writedes); + if frompipehandles.readdes <> invalidfilehandle then __close(frompipehandles.readdes); + if errorpipehandles.writedes <> invalidfilehandle then __close(errorpipehandles.writedes); + if errorpipehandles.readdes <> invalidfilehandle then __close(errorpipehandles.readdes); + execerror(errorbefore,commandline); + end; + + function dogetpt(var pty: integer; var ptyname: namebufferty): integer; + procedure ptyerror; + begin + __close(pty); + pty:= -1; + end; //ptyerror + var + ios: termios; + begin + if pty < 0 then begin + pty:= getpt; + if msetcgetattr(pty,ios) <> 0 then begin + ptyerror; + end + else begin + if exo_icanon in options then begin + ios.c_lflag:= ios.c_lflag or icanon; + end + else begin + ios.c_lflag:= ios.c_lflag and not icanon; + end; + if exo_echo in options then begin + ios.c_lflag:= ios.c_lflag or echo; + end + else begin + ios.c_lflag:= ios.c_lflag and not echo; + end; + ios.c_cc[vmin]:= #1; + ios.c_cc[vtime]:= #0; + if msetcsetattr(pty,tcsanow,ios) <> 0 then begin + ptyerror; + end + else begin + if (grantpt(pty) < 0) or (unlockpt(pty) < 0) then begin + ptyerror; + end; + end; + end; + end + else begin + pty:= dup(pty); + end; + if pty >= 0 then begin + if ptsname_r(pty,@ptyname,buflen) < 0 then begin + ptyerror; + end; + end; + result:= pty; + end; //dogetpt + + procedure openpipe(var pipehandles: tpipedescriptors); + begin + if exo_tty in options then begin + with pipehandles do begin + if @pipehandles = @topipehandles then begin + writedes:= dogetpt(ptyout,ptynameout); + readdes:= open(ptynameout,o_rdonly); + if readdes < 0 then execerr; + end + else begin + if @pipehandles = @frompipehandles then begin + readdes:= dogetpt(ptyout,ptynameout); + if readdes < 0 then execerr; + writedes:= open(ptynameout,o_wronly); + end + else begin + readdes:= dogetpt(ptyerr,ptynameerr); + if readdes < 0 then execerr; + writedes:= open(ptynameerr,o_wronly); + end; + if writedes < 0 then execerr; + end; + end; + end + else begin + if mselibc.pipe(pipehandles) <> 0 then execerr; + end; + end; + +var + bo1: boolean; + i1,i2: int32; + wd1: ansistring; + command1,commandline1: ansistring; + params1,envvars1: pointerarty; + par,env: stringarty; + useshell: boolean; +begin + wd1:= ''; + commandline1:= ansistring(commandline); + if workingdirectory <> '' then begin + wd1:= ansistring(tosysfilepath(workingdirectory)); + end; + setlength(par,length(params)); + for i1:= 0 to high(par) do begin + par[i1]:= ansistring(params[i1]); + end; + setlength(env,length(envvars)); + for i1:= 0 to high(env) do begin + env[i1]:= ansistring(envvars[i1]); + end; + useshell:= not (exo_noshell in options); + if useshell then begin + command1:= shell; + if params <> nil then begin +// i1:= length(parsecommandline(commandline)); +// for i1:= i1 to i1 + high(params) do begin + for i1:= 1 to length(params) do begin + if params[i1-1] = '' then begin + commandline1:= commandline1 + ' ""'; + end + else begin + commandline1:= commandline1 + ' ${'+inttostr(i1)+'}'; + end; + end; + end; + setlength(params1,4); + params1[1]:= pchar('-c'); + params1[2]:= pchar(commandline1); + params1[3]:= pchar(command1); //shell name + end + else begin + command1:= ansistring(tosysfilepath(msestring(commandline))); + setlength(params1,1); + end; + + params1[0]:= pchar(command1); + i2:= length(params1); + setlength(params1,i2+length(params)+1); + for i1:= 0 to high(par) do begin + params1[i2]:= pchar(par[i1]); + inc(i2); + end; + params1[high(params1)]:= nil; + + setlength(envvars1,length(envvars)+1); + for i1:= 0 to high(env) do begin + envvars1[i1]:= pchar(env[i1]); + end; + envvars1[high(envvars1)]:= nil; + + ptyout:= -1; + ptyerr:= -1; + result:= invalidprochandle; //compilerwarnung; + topipehandles.writedes:= invalidfilehandle; + topipehandles.readdes:= invalidfilehandle; + frompipehandles.writedes:= invalidfilehandle; + frompipehandles.readdes:= invalidfilehandle; + errorpipehandles.writedes:= invalidfilehandle; + errorpipehandles.readdes:= invalidfilehandle; + + if topipe <> nil then begin + if topipe^ = invalidfilehandle then begin + openpipe(topipehandles); + setcloexec(topipehandles.writedes); + topipe^:= topipehandles.writedes; + end + else begin + topipehandles.readdes:= topipe^; + end; + end; + if frompipe <> nil then begin + if frompipe^ = invalidfilehandle then begin + openpipe(frompipehandles); + setcloexec(frompipehandles.readdes); + frompipe^:= frompipehandles.readdes; + end + else begin + frompipehandles.writedes:= frompipe^; + end; + end; + if errorpipe <> nil then begin + if errorpipe <> frompipe then begin + if errorpipe^ = invalidfilehandle then begin + openpipe(errorpipehandles); + setcloexec(errorpipehandles.readdes); + errorpipe^:= errorpipehandles.readdes; + end + else begin + errorpipehandles.writedes:= errorpipe^; + end; + end; + end; + + procid:= mselibc.vfork; +// procid:= mselibc.fork; + + if procid = -1 then execerr; + + if procid = 0 then begin //child + if wd1 <> '' then begin + mselibc.__chdir(pointer(wd1)); + end; + if exo_sessionleader in options then begin + setsid; + end + else begin + if groupid <> -1 then begin + if groupid = 0 then begin + setpgid(procid,procid); + end + else begin + setpgid(procid,groupid); + end; + end; + end; + + if topipe <> nil then begin + __close(topipehandles.writedes); + if dup2(topipehandles.ReadDes,0) = -1 then begin + mselibc._exit(exit_failure); + end; + __close(topipehandles.readdes); + end; + if frompipe <> nil then begin + __close(frompipehandles.readdes); + if dup2(frompipehandles.writeDes,1) = -1 then begin + mselibc._exit(exit_failure); + end; + end; + if errorpipe <> nil then begin + if errorpipe <> frompipe then begin + __close(errorpipehandles.readdes); + if dup2(errorpipehandles.writeDes,2) = -1 then begin + mselibc._exit(exit_failure); + end; + __close(errorpipehandles.writedes); + end + else begin + if dup2(frompipehandles.writeDes,2) = -1 then begin + mselibc._exit(exit_failure); + end; + end + end; + if frompipe <> nil then begin + __close(frompipehandles.writedes); + end; + + if (exo_settty in options) then begin + bo1:= false; //search posssible controlling TTY + if (topipehandles.writedes <> invalidfilehandle) and + (isatty(0) <> 0) then begin + bo1:= ioctl(0,TIOCSCTTY,[]) <> -1; + end; + if not bo1 and (frompipehandles.writedes <> invalidfilehandle) and + (isatty(1) <> 0) then begin + bo1:= ioctl(1,TIOCSCTTY,[]) <> -1; + end; + if not bo1 and (errorpipehandles.writedes <> invalidfilehandle) and + (isatty(2) <> 0) then begin + bo1:= ioctl(2,TIOCSCTTY,[]) <> -1; + end; + end; + +// mselibc.execl(shell,shell,['-c',pchar(commandline),nil]); + if envvars <> nil then begin + mselibc.execve(pointer(pchar(command1)),pointer(params1),pointer(envvars1)); + end + else begin + mselibc.execv(pointer(pchar(command1)),pointer(params1)); + end; + mselibc._exit(exit_failure); //execl misslungen + + end + else begin //parent + if topipe <> nil then begin + __close(topipehandles.readDes); + end; + if frompipe <> nil then begin + if frompipewritehandle <> nil then begin + frompipewritehandle^:= frompipehandles.writedes; + end + else begin + __close(frompipehandles.writeDes); + end; + end; + if (errorpipe <> nil) and (errorpipe <> frompipe) then begin + if errorpipewritehandle <> nil then begin + errorpipewritehandle^:= errorpipehandles.writedes; + end + else begin + __close(errorpipehandles.writeDes); + end; + end; + result:= procid; + end; +end; + +procedure killprocess(handle: prochandlety); +var + int1: integer; +begin + if handle <> invalidprochandle then begin + int1:= kill(handle,sigterm); + if (int1 <> 0) and (errno <> esrch) then begin + exit; +// raise eoserror.create(''); //sigterm nicht moeglich + end; + if waitpid(handle,@int1,wnohang) = 0 then begin + sleep(100); + if waitpid(handle,@int1,wnohang) = 0 then begin + sleep(1000); + if waitpid(handle,@int1,wnohang) = 0 then begin + int1:= kill(handle,sigkill); + if (int1 <> 0) and (errno <> esrch) then begin + raise eoserror.create(''); //sigkill nicht moeglich + end; + while waitpid(handle,@int1,0) = -1 do begin + if sys_getlasterror <> eintr then begin + break; +// raise eoserror.create(''); + end; + end; + end; + end; + end; + end; +end; + +function terminateprocess(handle: prochandlety): integer; + //bringt exitresult +var + int1: integer; +begin + result:= -1; + if handle <> invalidprochandle then begin + int1:= kill(handle,sigterm); + if (int1 <> 0) and (errno <> esrch) then begin + exit; //sigterm nicht moeglich +// raise eoserror.create(''); + end; + + while waitpid(handle,@result,0) = -1 do begin + if sys_getlasterror <> eintr then begin + break; +// raise eoserror.create(''); + end; + end; + end; +end; + +function getppid2(pid: procidty): procidty; +var + stream: ttextstream; + str1: string; +begin + stream:= ttextstream.create('/proc/'+inttostrmse(pid)+'/stat',fm_read); + try + fillchar(result,sizeof(result),0); + stream.readln(str1); +// {$ifdef FPC} + sscanf(pchar(str1),'%*d (%*a[^)]) %*c %d',[@result]); +// {$else} +// sscanf(pchar(str1),'%*d (%*a[^)]) %*c %d',@result); +// {$endif} + finally + stream.free; + end; +end; + +function getprocinfo(pid: procidty): procinfoty; +var + stream: ttextstream; + str1: string; + commpo: pchar; +begin + stream:= ttextstream.create('/proc/'+inttostrmse(pid)+'/stat',fm_read); + try + fillchar(result,sizeof(result),0); + stream.readln(str1); + with result do begin + mselibc.sscanf(pchar(str1),'%d (%a[^)]) %c %d %d %d %d %d %lu %lu '+ + '%lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %lu %lu %ld %lu %lu %lu %lu %lu '+ + '%lu %lu %lu %lu %lu %lu %lu %lu %d %d', +// {$ifdef FPC}[{$endif} + [ + @pid, + @commpo, + @state, + @ppid, + @pgrp, + @session, + @tty_nr, + @tpgid, + @flags, + @minflt, + @cminflt, + @majflt, + @cmajflt, + @utime, + @stime, + @cutime, + @cstime, + @priority, + @nice, + @null, + @itrealvalue, + @starttime, + @vsize, + @rss, + @rlim, + @startcode, + @endcode, + @startstack, + @kstkesp, + @kstkeip, + @signal, + @blocked, + @sigignore, + @sigcatch, + @wchan, + @nswap, + @cnswap, + @exitsignal, + @processor + ] +// {$ifdef FPC}]{$endif} + ); + comm:= string(commpo); + mselibc.free(commpo); + end; + finally + stream.Free; + end +end; + +function getchildpid(pid: procidty): procidarty; +var + srec: tsearchrec; + int1: procidty; +begin + result:= nil; + if findfirst('/proc/*',fadirectory,srec) = 0 then begin + repeat + if (length(srec.name) > 0) and (srec.name[1] >= '0') and + (srec.name[1] <= '9') then begin +{$ifdef CPU64} + if trystrtoint64(srec.name,int1) then begin +{$else} + if trystrtoint(srec.name,int1) then begin +{$endif} + if getppid2(int1) = pid then begin + setlength(result,length(result)+1); + result[length(result)-1]:= int1; + end; + end; + end; + until findnext(srec) <> 0; + end; +end; + +function getinnerstpid(pid: procidty): procidty; +var + intar1: procidarty; + int1,int2: integer; +begin + result:= pid; + intar1:= getchildpid(pid); + for int1:= 0 to length(intar1) - 1 do begin + int2:= getinnerstpid(intar1[int1]); + if int2 > result then begin + result:= int2; + end; + end; +end; + +{$endif} + +function execmse(const commandline: msestring; + const options: execoptionsty = []; + const workingdirectory: filenamety = ''; + const params: msestringarty = nil; + const envvars: msestringarty = nil): boolean; +var + procid: prochandlety; +begin + result:= true; +{$ifdef MSWINDOWS} + try + try + procid:= execmse1(commandline,nil,nil,nil,-1,options,nil,nil, + workingdirectory,params,envvars); + finally + if procid <> invalidprochandle then begin + closehandle(procid); + end; + end; + except + result:= false; + end; +{$else} + try + procid:= execmse1(commandline,nil,nil,nil,-1,options,nil,nil, + workingdirectory,params,envvars); + pro_killzombie(procid); + except + result:= false; + end; +{$endif} +end; + +function execwaitmse(const commandline: msestring; + const options: execoptionsty = []; + const workingdirectory: filenamety = ''; + const params: msestringarty = nil; + const envvars: msestringarty = nil): integer; +//startet programm, wartet auf ende, bring exitcode, -1 wenn start nicht moeglich +var + prochandle: prochandlety; +begin + result:= -1; + //programm wurde nicht gestartet oder getexitcodeprozessproblem + prochandle:= execmse1(commandline,nil,nil,nil,-1,options,nil,nil, + workingdirectory,params,envvars); + if prochandle <> invalidprochandle then begin + result:= waitforprocess(prochandle); + end; +end; +{ +function execwaitmse(const commandline: string; + const options: execoptionsty = []; + const workingdirectory: ansistring = '' + //const inactive: boolean = true + ): integer; +begin + result:= mselibc.__system(pchar(commandline)); +end; +} + +function execmse1(const commandline: msestring; topipe: pinteger = nil; + frompipe: pinteger = nil; + errorpipe: pinteger = nil; + groupid: integer = -1; //-1 -> keine, 0 = childpid + const options: execoptionsty = []; + frompipewritehandle: pinteger = nil; + errorpipewritehandle: pinteger = nil; + const workingdirectory: filenamety = ''; + const params: msestringarty = nil; + const envvars: msestringarty = nil): prochandlety; + //creates pipes +begin + if topipe <> nil then begin + topipe^:= invalidfilehandle; + end; + if frompipe <> nil then begin + frompipe^:= invalidfilehandle; + end; + if errorpipe <> nil then begin + errorpipe^:= invalidfilehandle; + end; + result:= execmse0(commandline,topipe,frompipe,errorpipe,groupid,options, + frompipewritehandle,errorpipewritehandle, + workingdirectory,params,envvars); +end; + +function execmse2(const commandline: msestring; topipe: tpipewriter = nil; + frompipe: tpipereader = nil; + errorpipe: tpipereader = nil; + groupid: integer = -1; //-1 -> keine, 0 = childpid + const options: execoptionsty = []; + const workingdirectory: filenamety = ''; + const params: msestringarty = nil; + const envvars: msestringarty = nil): prochandlety; + //bringt procid +var + top,fromp,errp,fromwrite,errwrite: integer; + topp,frompp,errpp,fromwritep,errwritep: pinteger; +begin + if topipe <> nil then begin + topp:= @top; + topipe.close; + end + else begin + topp:= nil; + end; + if frompipe <> nil then begin + frompipe.close; + frompp:= @fromp; + fromwritep:= @fromwrite; + end + else begin + frompp:= nil; + fromwritep:= nil; + end; + if errorpipe <> nil then begin + if errorpipe <> frompipe then begin + errorpipe.close; + errpp:= @errp; + errwritep:= @errwrite; + end + else begin + errpp:= @fromp; + errwritep:= nil; + end; + end + else begin + errpp:= nil; + errwritep:= nil; + end; + if options * pipewritehandlemask = [] then begin + fromwritep:= nil; + errwritep:= nil; + end; + result:= execmse1(commandline,topp,frompp,errpp,groupid, + options, + fromwritep,errwritep,workingdirectory,params,envvars); + if topp <> nil then begin + topipe.Handle:= topp^; + end; + if frompp <> nil then begin + frompipe.Handle:= frompp^; + if fromwritep <> nil then begin + frompipe.writehandle:= fromwritep^; + end; + end; + if errpp <> nil then begin + if errorpipe <> frompipe then begin + errorpipe.Handle:= errpp^; + if errwritep <> nil then begin + errorpipe.writehandle:= errwritep^; + end; + end; + end; +end; + +function execmse3(const commandline: msestring; + topipe: pinteger = nil; + frompipe: pinteger = nil; + errorpipe: pinteger = nil; + groupid: integer = -1; //-1 -> keine, 0 = childpid + const options: execoptionsty = []; + frompipewritehandle: pinteger = nil; + errorpipewritehandle: pinteger = nil; + const workingdirectory: filenamety = ''; + const params: msestringarty = nil; + const envvars: msestringarty = nil): prochandlety; + //uses existing file handles +begin + result:= execmse0(commandline,topipe,frompipe,errorpipe, + groupid,options,frompipewritehandle,errorpipewritehandle, + workingdirectory,params,envvars); +end; + +function execmse4(const commandline: msestring; + const options: execoptionsty = []; + const workingdirectory: filenamety = ''; + const params: msestringarty = nil; + const envvars: msestringarty = nil): prochandlety; +begin + result:= execmse1(commandline,nil,nil,nil,-1,options,nil,nil, + workingdirectory,params,envvars); +end; + +end. diff --git a/mseide-msegui/lib/common/sysutils/msepython.pas b/mseide-msegui/lib/common/sysutils/msepython.pas new file mode 100644 index 0000000..6492397 --- /dev/null +++ b/mseide-msegui/lib/common/sysutils/msepython.pas @@ -0,0 +1,302 @@ +{ MSEgui Copyright (c) 2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msepython; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseprocess,mclasses,msearrayprops,msemacros,mseclasses, + msetypes{msestrings}; + +const + defaultpythonprocoptions = defaultprocessoptions + [pro_input]; + pyboolstrings: array[boolean] of msestring = ('False','True'); + +type + tpythonstringlist = class(tmacrostringlist) + end; + + tpythonstringlistitem = class(townedpersistent) + private + fname: msestring; + fscript: tpythonstringlist; + procedure setscript(const avalue: tpythonstringlist); + protected + public + constructor create(aowner: tobject); override; + destructor destroy; override; + procedure assign(source: tpersistent); override; + function execute(const atimeoutus: integer = -1): int32; //-1 -> infinite + //returns exitcode, -1 for timeout + published + property name: msestring read fname write fname; + property script: tpythonstringlist read fscript write setscript; + end; + + tpythonscript = class; + + tpythonscripts = class(townedpersistentarrayprop) + private + fdummylist: tmacrostringlist; + function getitems(const aindex: integer): tpythonstringlistitem; + procedure setitems(const aindex: integer; + const avalue: tpythonstringlistitem); + procedure setmacros(const avalue: tmacroproperty); + function getmacros: tmacroproperty; + protected + public + constructor create(const aowner: tpythonscript); reintroduce; + destructor destroy(); override; + property items[const aindex: integer]: tpythonstringlistitem read getitems + write setitems; default; + function itembyname(const aname: msestring): tpythonstringlistitem; + class function getitemclasstype: persistentclassty; override; + //used in dumpunitgroups + published + property macros: tmacroproperty read getmacros write setmacros; + end; + + tpythonscript = class(tcustommseprocess) + private + fscripts: tpythonscripts; + procedure setscripts(const avalue: tpythonscripts); + protected + procedure setoptions(const avalue: processoptionsty) override; + public + constructor create(aowner: tcomponent); override; + destructor destroy(); override; + published + property scripts: tpythonscripts read fscripts write setscripts; + property filename; + property parameter; + property workingdirectory; + property params; + property envvars; + property active; + property options default defaultpythonprocoptions; + property pipewaitus; + property statfile; + property statvarname; + property statpriority; + property input; + property output; + property erroroutput; + property onprocfinished; + property oncheckabort; + end; + +function pyboolean(const avalue: boolean): msestring; + +implementation +uses + sysutils,mseapplication; + +function pyboolean(const avalue: boolean): msestring; +begin + if avalue then begin + result:= 'True'; + end + else begin + result:= 'False'; + end; +{ + if avalue then begin + result:= '1'; + end + else begin + result:= '0'; + end; +} +end; + +{ tpythonscript } + +constructor tpythonscript.create(aowner: tcomponent); +begin + fscripts:= tpythonscripts.create(self); + inherited; + filename:= 'python'; + options:= defaultpythonprocoptions; +end; + +destructor tpythonscript.destroy(); +begin + inherited; + fscripts.free(); +end; + +procedure tpythonscript.setscripts(const avalue: tpythonscripts); +begin + fscripts.assign(avalue); +end; + +procedure tpythonscript.setoptions(const avalue: processoptionsty); +begin + inherited; + if not (pro_input in foptions) then begin + inherited setoptions(foptions + [pro_noshell]); + //bash -c only supports a single commandstring -> + //python -c can not be used with bash and paramlist + end; +end; + +{ tpythonstringlistitem } + +constructor tpythonstringlistitem.create(aowner: tobject); +begin + fscript:= tpythonstringlist.create(); + inherited; +end; + +destructor tpythonstringlistitem.destroy; +begin + fscript.free; + inherited; +end; + +procedure tpythonstringlistitem.assign(source: tpersistent); +begin + if source is tpythonstringlistitem then begin + with tpythonstringlistitem(source) do begin + self.name:= name; + self.script:= script; + end; + end; +end; + +function tpythonstringlistitem.execute(const atimeoutus: integer = -1): int32; +var + i1,i2: int32; + ms1: msestring; +begin + with tpythonscript(fowner) do begin + active:= false; + ms1:= fscripts.fdummylist.expandmacros(fscript.text); + if not (pro_input in options) then begin + i2:= -1; + for i1:= 0 to params.count-1 do begin + if params[i1] = '-' then begin + i2:= i1; + break; + end; + end; + i1:= i2; + if i1 < 0 then begin + params.insert(0,'-c'); + params.insert(1,ms1); + i1:= 0; + i2:= 2; + end + else begin + params[i1]:= '-c'; + inc(i1); + params.insert(i1,ms1); + i2:= 1; + end; + try + active:= true; + finally + if i2 = 1 then begin + params[i1-1]:= '-'; + end; + params.deleteitems(i1,i2); + end; + end + else begin + active:= true; + try + input.pipewriter.write(ms1); + except + application.handleexception(); + end; + input.pipewriter.close(); + end; + if atimeoutus < 0 then begin + result:= waitforprocess(); + end + else begin + if atimeoutus > 0 then begin + if not waitforprocess(atimeoutus) then begin + result:= -1; + end + else begin + result:= exitcode; + end; + end + else begin + result:= exitcode; + end; + end; + end; +end; + +procedure tpythonstringlistitem.setscript(const avalue: tpythonstringlist); +begin + fscript.assign(avalue); +end; + +{ tpythonscripts } + +constructor tpythonscripts.create(const aowner: tpythonscript); +begin + fowner:= aowner; + fdummylist:= tmacrostringlist.create(); + inherited create(aowner,tpythonstringlistitem); +end; + +destructor tpythonscripts.destroy(); +begin + inherited; + fdummylist.free(); +end; + +function tpythonscripts.getitems(const aindex: integer): tpythonstringlistitem; +begin + result:= tpythonstringlistitem(inherited getitems(aindex)); +end; + +procedure tpythonscripts.setitems(const aindex: integer; + const avalue: tpythonstringlistitem); +begin + inherited; +end; + +procedure tpythonscripts.setmacros(const avalue: tmacroproperty); +begin + fdummylist.macros:= avalue; +end; + +function tpythonscripts.getmacros: tmacroproperty; +begin + result:= fdummylist.macros; +end; + +function tpythonscripts.itembyname( + const aname: msestring): tpythonstringlistitem; +var + int1: integer; +begin + result:= nil; + for int1:= 0 to high(fitems) do begin + if tpythonstringlistitem(fitems[int1]).name = aname then begin + result:= tpythonstringlistitem(fitems[int1]); + break; + end; + end; + if result = nil then begin + raise exception.create('Script "'+ansistring(aname)+'" not found.'); + end; +end; + +class function tpythonscripts.getitemclasstype: persistentclassty; +begin + result:= tpythonstringlistitem; +end; + +end. diff --git a/mseide-msegui/lib/common/sysutils/msestatusnotifieritem.pas b/mseide-msegui/lib/common/sysutils/msestatusnotifieritem.pas new file mode 100644 index 0000000..8f9178e --- /dev/null +++ b/mseide-msegui/lib/common/sysutils/msestatusnotifieritem.pas @@ -0,0 +1,608 @@ + { MSEgui Copyright (c) 2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +// +// for internal use in MSEgui only +// +unit msestatusnotifieritem; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msedbusinterface,msestrings,msetypes,msebitmap,msedbus,msegraphutils, + mseevent; +type + desktopkindty = (desk_none,desk_freedesktop,desk_kde); + + iconpixmapty = record + cx,cy: int32; + data: bytearty; + end; + iconpixmaparty = array of iconpixmapty; + + tooltipinfoty = record + iconname: string; + iconpixmap: array of iconpixmapty; + title: string; + text: string; + end; + tooltipinfoarty = array of tooltipinfoty; + //workaround in order to get item typeinfo + + statusnotifiercategoryty = (snc_applicationstatus,snc_communications, + snc_systemservices,snc_hardware); + tstatusnotifieritem = class; + statusnotifierposprocty = procedure(const sender: tstatusnotifieritem; + const apos: pointty) of object; + tstatusnotifieritem = class(tdbusobject) + private + fstatuscategory: statusnotifiercategoryty; + fid: string; + fid1: string; //possibly updated from applicationname + ftitle: string; + fstatus: string; + fwindowid: int32; + ficonname: string; + ficonpixmap: iconpixmaparty; + foverlayiconname: string; + foverlayiconpixmap: iconpixmaparty; + fatentioniconname: string; + fatentioniconpixmap: iconpixmaparty; + fatentionmoviename: string; + ftooltip: tooltipinfoty; + factive: boolean; + foncontextmenu: statusnotifierposprocty; + fonactivate: statusnotifierposprocty; + fmessageid: card32; + fonsecondaryactivate: statusnotifierposprocty; + function getcategory: string; + function getid: string; + procedure setactive(const avalue: boolean); + protected + fdesktopkind: desktopkindty; + function getintrospectitems(): string override; + function getpath(): string override; + procedure busconnected() override; + procedure propertiesget(var props: dictentryarty) override; + procedure propertyget(const amessage: pdbusmessage; + const aname: string; var avalue: variantvaluety) override; + function getpropintf: string override; + procedure registeritems(const sender: idbusservice) override; + procedure contextmenu(const amessage: pdbusmessage; const adata: pointer; + var ahandled: boolean); + procedure activate(const amessage: pdbusmessage; const adata: pointer; + var ahandled: boolean); + procedure secondaryactivate(const amessage: pdbusmessage; + const adata: pointer; var ahandled: boolean); + procedure scroll(const amessage: pdbusmessage; const adata: pointer; + var ahandled: boolean); + procedure receiveevent(const event: tobjectevent) override; + public + constructor create(); + destructor destroy(); override; + function checkdesktop(): boolean; + property desktopkind: desktopkindty read fdesktopkind; + function showmessage(const message: msestring; const title: msestring; + out messageid: card32; + const timeoutms: card32 = 0): boolean; + function cancelmessage(const messageid: card32): boolean; + + property active: boolean read factive write setactive; + property statuscategory: statusnotifiercategoryty read fstatuscategory + write fstatuscategory default snc_applicationstatus; + procedure setToolTip(const avalue: tooltipinfoty); + procedure setId(const avalue: string); //'' -> applicationname + procedure setTitle(const avalue: string); + procedure setStatus(const avalue: string); + procedure setWindowId(const avalue: int32); + procedure setIconName(const avalue: string); + procedure setIconPixmap(const avalue: tmaskedbitmap); + procedure setIconPixmap(const avalue: iconpixmaparty); + procedure setOverlayIconName(const avalue: string); + procedure setOverlayIconPixmap(const avalue: iconpixmaparty); + procedure setAtentionIconName(const avalue: string); + procedure setAtentionIconPixmap(const avalue: iconpixmaparty); + procedure setAtentionMovieName(const avalue: string); + property ToolTip: tooltipinfoty read ftooltip; + property oncontextmenu: statusnotifierposprocty read foncontextmenu + write foncontextmenu; + property onactivate: statusnotifierposprocty read fonactivate + write fonactivate; + property onsecondaryactivate: statusnotifierposprocty + read fonsecondaryactivate write fonsecondaryactivate; + published + property Category: string read getcategory; + property Id: string read getid; + property Title: string read ftitle; + property Status: string read fstatus; + property WindowId: int32 read fwindowid; + property IconName: string read ficonname; + property IconPixmap: iconpixmaparty read ficonpixmap; + property OverlayIconName: string read foverlayiconname; + property OverlayIconPixmap: iconpixmaparty read foverlayiconpixmap; + property AtentionIconName: string read fatentioniconname; + property AtentionIconPixmap: iconpixmaparty read fatentioniconpixmap; + property AtentionMovieName: string read fatentionmoviename; + end; + +function bitmaptoiconpixmap(const abitmap: tmaskedbitmap): iconpixmapty; + +implementation +uses + mseapplication,msegraphics,sysutils; +type + dbuspixelty = packed record a,r,g,b: card8 end; //in network byte order + pdbuspixelty = ^dbuspixelty; + +function bitmaptoiconpixmap(const abitmap: tmaskedbitmap): iconpixmapty; +var + p1: pdbuspixelty; + p1a: prgbtriplety; + p2: pcard8; + pe: pointer; + bmp1: tmaskedbitmap; + i1: int32; +begin + bmp1:= tmaskedbitmap.create(abitmap.kind); + bmp1.assign(abitmap); + bmp1.kind:= bmk_rgb; + with result do begin + cx:= abitmap.width; + cy:= abitmap.height; + setlength(data,cx*cy*4); + if (cx <> 0) and (cy <> 0) then begin + p1:= pdbuspixelty(pointer(data)); + p1a:= bmp1.scanline[0]; + if bmp1.masked then begin + bmp1.graymask:= true; + for i1:= 0 to cy-1 do begin + p2:= bmp1.mask.scanline[i1]; + pe:= p2+cx; + while p2 < pe do begin + p1^.r:= p1a^.red; + p1^.g:= p1a^.green; + p1^.b:= p1a^.blue; + p1^.a:= p2^; + inc(p1); + inc(p1a); + inc(p2); + end; + end; + end + else begin + p1:= pdbuspixelty(pointer(data)); + pe:= p1 + cx*cy; + while p1 < pe do begin + p1^.r:= p1a^.red; + p1^.g:= p1a^.green; + p1^.b:= p1a^.blue; + p1^.a:= $ff; + inc(p1); + inc(p1a); + end; + end; + end; + { + p1:= pdbuspixelty(pointer(data)); + pe:= p1 + cx*cy; + while p1 < pe do begin + swapendian(card32(p1^)); + inc(p1); + end; + } + end; + bmp1.free; +end; + +const + datadef1 = +''+lineend+ +''+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +//' '+lineend+ +//' '+lineend+ +//' '+lineend+ +' '+lineend+ +' '+lineend+ +//' '+lineend+ +//' '+lineend+ +' '+lineend+ +' '+lineend+ +//' '+lineend+ +//' '+lineend+ +' '+lineend+ +' '+lineend+ +//' '+lineend+ +//' '+lineend+ +' '+lineend+ +' '+lineend+ +//' '+lineend+ +//' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend+ +''+lineend; + +const + interfacestart: array[desktopkindty] of string = ( + '','org.freedesktop.','org.kde.'); + +constructor tstatusnotifieritem.create(); +begin + inherited create(nil); +// checkdesktop(); +end; + +destructor tstatusnotifieritem.destroy(); +begin + inherited; + active:= false; + freeandnil(fservice); //in case of checkdesktop out of setactive +end; + +function tstatusnotifieritem.showmessage(const message: msestring; + const title: msestring; + out messageid: card32; const timeoutms: card32 = 0): boolean; +var + s1,s2,s3: string; + c1: card32; + p1: pointer; +begin + inc(fmessageid); + s1:= getid; + s2:= stringtoutf8(title); + s3:= stringtoutf8(message); + if fmessageid = 0 then begin + inc(fmessageid); + end; + messageid:= fmessageid; + p1:= nil; + result:= fservice.dbuscallmethod('org.freedesktop.Notifications', + '/org/freedesktop/Notifications','org.freedesktop.Notifications', + 'Notify', + [variantvalue(s1),variantvalue(fmessageid), + variantvalue(''), + variantvalue(s2), + variantvalue(s3), + variantvalue(@p1,typeinfo(stringarty)), + variantvalue(@p1,typeinfo(dictentryarty),[vf_dict]), + variantvalue(int32(timeoutms))],[dbt_uint32],[@c1]); +end; + +function tstatusnotifieritem.cancelmessage( + const messageid: card32): boolean; +begin + result:= fservice.dbuscallmethod('org.freedesktop.Notifications', + '/org/freedesktop/Notifications','org.freedesktop.Notifications', + 'CloseNotification',[variantvalue(messageid)],[],[]); +end; + +const + categorynames: array[statusnotifiercategoryty] of string = ( + //snc_applicationstatus,snc_communications,snc_systemservices,snc_hardware + 'ApplicationStatus', 'Communications', 'SystemServices', 'Hardware'); + +function tstatusnotifieritem.getcategory: string; +begin + result:= categorynames[fstatuscategory]; +end; + +function tstatusnotifieritem.getid: string; +begin + fid1:= fid; + if fid1 = '' then begin + fid1:= stringtoutf8(application.applicationname); + end; + result:= fid1; +end; + +function tstatusnotifieritem.checkdesktop(): boolean; +var + b2: boolean; + desk1: desktopkindty; +begin + if fservice = nil then begin + fservice:= tdbusservice.create(); + try + if fservice.connect() then begin + for desk1:= desktopkindty(1) to high(desk1) do begin + if fservice.dbusgetproperty(interfacestart[desk1]+'StatusNotifierWatcher', + '/StatusNotifierWatcher',interfacestart[desk1]+'StatusNotifierWatcher', + 'IsStatusNotifierHostRegistered',[dbt_boolean],[@b2]) then begin + if b2 then begin + fdesktopkind:= desk1; + break; + end; + end; + end; + end; + if fdesktopkind = desk_none then begin + fservice.destroy(); + fservice:= nil; + end; + except + fservice.destroy; + fservice:= nil; + raise; + end; + end; + result:= fservice <> nil; +end; + +procedure tstatusnotifieritem.setactive(const avalue: boolean); +begin + if avalue <> factive then begin + if factive then begin + fservice.destroy; + fservice:= nil; + factive:= false; + end + else begin + if checkdesktop() then begin + factive:= true; + fservice.registerobject(idbusobject(self)); + end; + end; + end; +end; + +function tstatusnotifieritem.getintrospectitems(): string; +begin + result:= inherited getintrospectitems() + + datadef1+getpropintf()+datadef2; +end; + +function tstatusnotifieritem.getpath(): string; +begin + result:= inherited getpath()+'StatusNotifierItem'; +end; + +procedure tstatusnotifieritem.busconnected(); +var + s1: string; +begin + inherited; +// s1:= fservice.dbusname; + s1:= fservice.dbusid; + if not fservice.dbuscallmethod( + interfacestart[fdesktopkind]+'StatusNotifierWatcher', + '/StatusNotifierWatcher', + interfacestart[fdesktopkind]+'StatusNotifierWatcher', + 'RegisterStatusNotifierItem',variantvalue(s1),[],[]) then begin + end; +end; + +procedure tstatusnotifieritem.propertiesget(var props: dictentryarty); +begin + setlength(props,1); + with props[0] do begin + name:= 'ToolTip'; + setvariantvalue(@ftooltip,itemtypeinfo(typeinfo(tooltipinfoarty)), + value,[vf_var]); + end; +end; + +procedure tstatusnotifieritem.propertyget(const amessage: pdbusmessage; + const aname: string; var avalue: variantvaluety); +begin + if aname = 'ToolTip' then begin + setvariantvalue(@ftooltip,itemtypeinfo(typeinfo(tooltipinfoarty)), + avalue,[vf_var]); + end; +end; + +function tstatusnotifieritem.getpropintf: string; +begin + result:= interfacestart[fdesktopkind]+'StatusNotifierItem'; +end; + +procedure tstatusnotifieritem.registeritems(const sender: idbusservice); +begin + inherited; + sender.registermethodhandler(getpropintf(), + 'ContextMenu',[dbt_int32,dbt_int32],@contextmenu,nil); + sender.registermethodhandler(getpropintf(), + 'Activate',[dbt_int32,dbt_int32],@activate,nil); + sender.registermethodhandler(getpropintf(), + 'SecondaryActivate',[dbt_int32,dbt_int32],@secondaryactivate,nil); + sender.registermethodhandler(getpropintf(), + 'Scroll',[dbt_int32,dbt_string],@scroll,nil); +end; + +procedure tstatusnotifieritem.receiveevent(const event: tobjectevent); +begin + inherited; + if (event.kind = ek_objectdata) and (event is tpointobjectevent) and + assigned(foncontextmenu) then begin + foncontextmenu(self,tpointobjectevent(event).data); + end; +end; + +procedure tstatusnotifieritem.contextmenu(const amessage: pdbusmessage; + const adata: pointer; var ahandled: boolean); +var + x,y: int32; +begin + if fservice.dbusreadmessage(amessage,[dbt_int32,dbt_int32],[@x,@y]) then begin + application.postevent(tpointobjectevent.create(mp(x,y),ievent(self))); + //deadlock in dbus library if called directly because of modal call + fservice.dbusreply(amessage,[]); + ahandled:= true; + end +end; + +procedure tstatusnotifieritem.activate(const amessage: pdbusmessage; + const adata: pointer; var ahandled: boolean); +var + x,y: int32; +begin + if fservice.dbusreadmessage(amessage,[dbt_int32,dbt_int32],[@x,@y]) then begin + fservice.dbusreply(amessage,[]); + if assigned(fonactivate) then begin + fonactivate(self,mp(x,y)); + end; + ahandled:= true; + end +end; + +procedure tstatusnotifieritem.secondaryactivate(const amessage: pdbusmessage; + const adata: pointer; var ahandled: boolean); +var + x,y: int32; +begin + if fservice.dbusreadmessage(amessage,[dbt_int32,dbt_int32],[@x,@y]) then begin + fservice.dbusreply(amessage,[]); + if assigned(fonsecondaryactivate) then begin + fonsecondaryactivate(self,mp(x,y)); + end; + ahandled:= true; + end +end; + +procedure tstatusnotifieritem.scroll(const amessage: pdbusmessage; + const adata: pointer; var ahandled: boolean); +var + delta: int32; + orientation: string; +begin + if fservice.dbusreadmessage(amessage,[dbt_int32,dbt_string], + [@delta,@orientation]) then begin + fservice.dbusreply(amessage,[]); + ahandled:= true; + end +end; + +procedure tstatusnotifieritem.setId(const avalue: string); +begin + fid:= avalue; +end; + +procedure tstatusnotifieritem.setTitle(const avalue: string); +begin + ftitle:= avalue; + propchangesignal('NewTitle'); +end; + +procedure tstatusnotifieritem.setStatus(const avalue: string); +begin + fstatus:= avalue; + if (fservice <> nil) and fservice.connected then begin + fservice.dbussignal(rootpath(),getpropintf(),'NewStatus', + variantvalue(fstatus)); + end; +end; + +procedure tstatusnotifieritem.setWindowId(const avalue: int32); +begin + fwindowid:= avalue; +end; + +procedure tstatusnotifieritem.setIconName(const avalue: string); +begin + ficonname:= avalue; + propchangesignal('NewIcon'); +end; + +procedure tstatusnotifieritem.setIconPixmap(const avalue: tmaskedbitmap); +var + ar1: iconpixmaparty; +begin + ar1:= nil; + if (avalue <> nil) and avalue.hasimage() then begin + setlength(ar1,1); + ar1[0]:= bitmaptoiconpixmap(avalue); + end; + seticonpixmap(ar1); +end; + +procedure tstatusnotifieritem.setIconPixmap(const avalue: iconpixmaparty); +begin + ficonpixmap:= avalue; + propchangesignal('NewIcon'); +end; + +procedure tstatusnotifieritem.setOverlayIconName(const avalue: string); +begin + foverlayiconname:= avalue; + propchangesignal('NewOverlayIcon'); +end; + +procedure tstatusnotifieritem.setOverlayIconPixmap( + const avalue: iconpixmaparty); +begin + foverlayiconpixmap:= avalue; + propchangesignal('NewOverlayIcon'); +end; + +procedure tstatusnotifieritem.setAtentionIconName(const avalue: string); +begin + fatentioniconname:= avalue; + propchangesignal('NewAttentionIcon'); +end; + +procedure tstatusnotifieritem.setAtentionIconPixmap( + const avalue: iconpixmaparty); +begin + fatentioniconpixmap:= avalue; + propchangesignal('NewAttentionIcon'); +end; + +procedure tstatusnotifieritem.setAtentionMovieName(const avalue: string); +begin + fatentionmoviename:= avalue; +end; + +procedure tstatusnotifieritem.setToolTip(const avalue: tooltipinfoty); +begin + ftooltip:= avalue; + propchangesignal('NewToolTip'); +end; + +end. diff --git a/mseide-msegui/lib/common/sysutils/msestatussnotifieritem.pas b/mseide-msegui/lib/common/sysutils/msestatussnotifieritem.pas new file mode 100644 index 0000000..08193b9 --- /dev/null +++ b/mseide-msegui/lib/common/sysutils/msestatussnotifieritem.pas @@ -0,0 +1,99 @@ + { MSEgui Copyright (c) 2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msestatussnotifieritem; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msedbusinterface; +type + tstatusnotifieritem = class(tdbusobject) + protected + function getintrospectitems(): string virtual; + end; + +implementation + +const + datadef = +''+lineend+ +''+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend+ +' '+lineend+ +' '+lineend+ +' '+lineend+ +''+lineend+ +''+lineend; + +{ tstatusnotifieritem } + +function tstatusnotifieritem.getintrospectitems(): string; +begin + result:= datadef; +end; + +end. diff --git a/mseide-msegui/lib/common/sysutils/msestrmacros.pas b/mseide-msegui/lib/common/sysutils/msestrmacros.pas new file mode 100644 index 0000000..c1c8d58 --- /dev/null +++ b/mseide-msegui/lib/common/sysutils/msestrmacros.pas @@ -0,0 +1,98 @@ +{ MSEgui Copyright (c) 2015 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} + +unit msestrmacros; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msemacros; + +function strmacros(): macroinfoarty; + +implementation +uses + mseprocess,mseprocutils,msefileutils,msetypes{msestrings},sysutils; + +var + fstrmacros: macroinfoarty; + +function strmacros(): macroinfoarty; +begin + result:= fstrmacros; +end; + +function str_trim(const sender: tmacrolist; + const params: msestringarty): msestring; +begin + result:= ''; + if params <> nil then begin + result:= trim(sender.expandmacros(params[0])); + end; +end; + +function str_trimleft(const sender: tmacrolist; + const params: msestringarty): msestring; +begin + result:= ''; + if params <> nil then begin + result:= trimleft(sender.expandmacros(params[0])); + end; +end; + +function str_trimright(const sender: tmacrolist; + const params: msestringarty): msestring; +begin + result:= ''; + if params <> nil then begin + result:= trimright(sender.expandmacros(params[0])); + end; +end; + +function str_coalesce(const sender: tmacrolist; + const params: msestringarty): msestring; +var + i1: int32; +begin + result:= ''; + if params <> nil then begin + for i1:= 0 to high(params) do begin + result:= sender.expandmacros(params[i1]); + if result <> '' then begin + break; + end; + end; + end; +end; + +const + strmacroconst: array[0..3] of macroinfoty = ( + (name: 'STR_TRIM'; value: ''; handler: macrohandlerty(@str_trim); + expandlevel: 0), + (name: 'STR_TRIMLEFT'; value: ''; handler: macrohandlerty(@str_trimleft); + expandlevel: 0), + (name: 'STR_TRIMRIGHT'; value: ''; handler: macrohandlerty(@str_trimright); + expandlevel: 0), + (name: 'STR_COALESCE'; value: ''; handler: macrohandlerty(@str_coalesce); + expandlevel: 0) + ); + +procedure initexecmacros(); +var + int1: integer; +begin + setlength(fstrmacros,length(strmacroconst)); + for int1:= 0 to high(strmacroconst) do begin + fstrmacros[int1]:= strmacroconst[int1]; + end; +end; + +initialization + initexecmacros(); +end. diff --git a/mseide-msegui/lib/common/sysutils/msesysdnd.pas b/mseide-msegui/lib/common/sysutils/msesysdnd.pas new file mode 100644 index 0000000..8300dba --- /dev/null +++ b/mseide-msegui/lib/common/sysutils/msesysdnd.pas @@ -0,0 +1,194 @@ +{ MSEgui Copyright (c) 2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msesysdnd; +//under construction + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +interface +uses + mseevent,msetypes,msegraphutils,mseguiglob,msedragglob,msedrag,msestrings, + msemime,mseglob,msegui; + +type + + tsysdndevent = class(twindowevent) + private + public + fformats: msestringarty; + fformatistext: booleanarty; + fpos: pointty; + fshiftstate: shiftstatesty; + fscroll: boolean; + fdndkind: drageventkindty; + factions: dndactionsty; + constructor create(const adndkind: drageventkindty; + const awinid: winidty; const apos: pointty; + const ashiftstate: shiftstatesty; const ascroll: boolean; + const aformats: msestringarty; + const aformatistext: booleanarty; + const aactions: dndactionsty); + end; + + tsysdndstatusevent = class(tobjectevent) + private + faccept: boolean; + public + constructor create(const aintf: ievent; const aaccept: boolean); + property accept: boolean read faccept; + end; + + tsysmimedragobject = class(tmimedragobject,isysdnd) + private + protected + procedure checkwritable; + procedure setdata(const avalue: string); override; + procedure settext(const avalue: msestring); override; + function getdata: string; override; + function gettext: msestring; override; + procedure cancelsysdnd; virtual; + //isysdnd + function getformats: msestringarty; + function getformatistext: booleanarty; + function getactions: dndactionsty; + public + constructor create(const asender: tobject; var instance: tdragobject; + const apickpos: pointty; const aformats: array of msestring; + const aformatistext: array of boolean; + const aactions: dndactionsty = []; + const aintf: imimesource = nil); override; + constructor createwrite(const asender: tobject; var instance: tdragobject; + const apickpos: pointty; const aformats: array of msestring; + const aformatistext: array of boolean; + const aactions: dndactionsty = []; + const aintf: imimesource = nil); + end; + +implementation +uses + msearrayutils,mseguiintf,sysutils; + +{ tsysdndevent } + +constructor tsysdndevent.create(const adndkind: drageventkindty; + const awinid: winidty; const apos: pointty; + const ashiftstate: shiftstatesty; const ascroll: boolean; + const aformats: msestringarty; const aformatistext: booleanarty; + const aactions: dndactionsty); +begin + fdndkind:= adndkind; + fpos:= apos; + fshiftstate:= ashiftstate; + fscroll:= ascroll; + fformats:= aformats; + fformatistext:= aformatistext; + factions:= aactions; + inherited create(ek_sysdnd,awinid); +end; + +{ tsysmimedragobject } + +constructor tsysmimedragobject.create(const asender: tobject; + var instance: tdragobject; const apickpos: pointty; + const aformats: array of msestring; + const aformatistext: array of boolean; + const aactions: dndactionsty = []; + const aintf: imimesource = nil); +begin + fsysdndintf:= isysdnd(self); + include(fstate,dos_sysdnd); + inherited create(asender,instance,apickpos,aformats,aformatistext, + aactions,aintf); +end; + +constructor tsysmimedragobject.createwrite(const asender: tobject; + var instance: tdragobject; const apickpos: pointty; + const aformats: array of msestring; + const aformatistext: array of boolean; + const aactions: dndactionsty = []; + const aintf: imimesource = nil); +begin + include(fstate,dos_sysdnd); + inherited createwrite(asender,instance,apickpos,aformats,aformatistext, + aactions,aintf); +end; + +function tsysmimedragobject.getdata: string; +begin + if dos_write in fstate then begin + result:= inherited getdata; + end + else begin + result:= ''; + gui_sysdndreaddata(result,formatindex); +// guierror(gui_sysdndreaddata(result,typeindex),'Can not read sysdnd data.'); + end; +end; + +function tsysmimedragobject.gettext: msestring; +begin + if dos_write in fstate then begin + result:= inherited gettext; + end + else begin + result:= ''; + gui_sysdndreadtext(result,formatindex); +// guierror(gui_sysdndreadtext(result,typeindex),'Can not read sysdnd text.'); + end; +end; + +procedure tsysmimedragobject.checkwritable; +begin + if not (dos_write in fstate) then begin + raise exception.create('Dragobject is readonly'); + end; +end; + +procedure tsysmimedragobject.setdata(const avalue: string); +begin + checkwritable; + inherited; +end; + +procedure tsysmimedragobject.settext(const avalue: msestring); +begin + checkwritable; + inherited; +end; + +procedure tsysmimedragobject.cancelsysdnd; +begin + destroy; +end; + +function tsysmimedragobject.getformats: msestringarty; +begin + result:= formats; +end; + +function tsysmimedragobject.getformatistext: booleanarty; +begin + result:= fformatistext; +end; + +function tsysmimedragobject.getactions: dndactionsty; +begin + result:= factions; +end; + +{ tsysdndstatusevent } + +constructor tsysdndstatusevent.create(const aintf: ievent; + const aaccept: boolean); +begin + faccept:= aaccept; + inherited create(ek_sysdndstatus,aintf); +end; + +end. diff --git a/mseide-msegui/lib/common/sysutils/msesysenv.pas b/mseide-msegui/lib/common/sysutils/msesysenv.pas new file mode 100644 index 0000000..fa1936d --- /dev/null +++ b/mseide-msegui/lib/common/sysutils/msesysenv.pas @@ -0,0 +1,1349 @@ +{ MSEgui Copyright (c) 1999-2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msesysenv; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifndef FPC}{$ifdef linux} {$define UNIX} {$endif}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,msestat,msestatfile,mseclasses,msetypes, + msestrings,msedatalist,sysutils, + mselist,msearrayutils,msemacros; + +const + commandlineparchar = '-'; + defaulterrorcode = 1; + +type + argumentkindty = (ak_none, + ak_envvar, //environement variable z.b. 'PATH' + ak_par, //commandlineparameter + //z.b. '-v', '--help' + ak_pararg, //commandlineparameter mit argument + //z.b. '-vabc', '-v abc', '-v "abc def" + // '--file=abc' + ak_arg //commandline argument, name muss '' sein, + // z.b. 'abc', '"abc def"' + ); + + argumentkindsty = set of argumentkindty; +const + at_pars = [ak_par,ak_pararg]; + +type + sysenverrornrty = (ern_io,ern_user,ern_invalidparameter,ern_missedargument,ern_invalidargument, + ern_ambiguousparameter,ern_invalidinteger,ern_mandatoryparameter); +const + errtexte: array[sysenverrornrty] of msestring = ('','', + 'Invalid parameter','Missed argument','Invalid argument','Ambiguous parameter', + 'Invalid integer','Parameter mandatory'); +type + argumentflagty = (arf_envdefined, // wert aus env. gesetzt 0 + arf_statdefined, // wert aus statfile. gesetzt 1 + arf_setdefined, // wert aus programm gesetzt 2 + arf_res1, //3 + arf_res2, //4 + arf_res3, //5 + arf_res4, //6 + arf_mandatory, // obligatorisch //7 + arf_argopt, // argument optional //8 + arf_filenames, // argument wird durch pathsep //9 + // gesplitted + arf_statoverride, // wert wird durch statfile //10 + // ueberschrieben + // ev. auch geloescht + arf_stataddval, // wert wird von statfile //11 + // geschrieben falls + // noch nicht gesetzt + arf_unquote, //unquote argument value //12 + arf_integer, //fuer arg und pararg //13 + arf_help //print help and terminate //14 + ); + + argumentflagsty = set of argumentflagty; + + sysenvoptionty = (seo_appterminateonexception,seo_terminateonerror, + seo_haltonerror,seo_exceptiononerror,seo_exitoninfo, + seo_noerrormess, + seo_tooutput, //info -> outputpipe + seo_toerror, //errormeldung -> errorpipe + seo_noautoinit //no call of init in loaded() + ); + sysenvoptionsty = set of sysenvoptionty; + +const + arf_defined = [arf_envdefined,arf_statdefined,arf_setdefined]; + defaultsysenvmanageroptions = [seo_tooutput,seo_toerror]; + +type + ehalt = class(exception); + + argumentdefty = record + kind: argumentkindty; + name: msestring; //case sensitive, single char -> + // short parameter 'a' 'b' -> '-a' '-b' or '-ab' or '-ba', + // '-abcde' -> '--abcde' + anames: pmsestring;//pointer auf array[0..0] of string alias, + //letzter string muss leer sein ('abc','def',''); + flags: argumentflagsty; + initvalue: msestring; + end; + + pargumentdefty = ^argumentdefty; + argumentdefaty = array [0..0] of argumentdefty; + pargumentdefaty = ^argumentdefaty; + argumentdefarty = array of argumentdefty; + + envvarty = record + flags: argumentflagsty; + values: msestringarty; + name: msestring; + end; + penvvarty = ^envvarty; + envvararty = array of envvarty; + + tsysenvmanager = class; + sysenvmanagereventty = procedure(sender: tsysenvmanager) of object; + + sysenvmanagervalueeventty = procedure(sender: tsysenvmanager; + const index: integer; var defined: boolean; + var argument: msestringarty; var error: sysenverrornrty) of object; + + sysenvdefty = record + kind: argumentkindty; + name: msestring; + anames: msestringarty; + flags: argumentflagsty; + initvalue: msestring; + argument: msestring; + before: msestring; + help: msestring; + after: msestring; + end; + psysenvdefty = ^sysenvdefty; + sysenvdefarty = array of sysenvdefty; + + tsysenvmanager = class(tmsecomponent,istatfile) + private + foninit: sysenvmanagereventty; + fenvvars: envvararty; + foptions: sysenvoptionsty; + ferrorcode: integer; + fstatfile: tstatfile; + fstatvarname: msestring; + fonvalueread: sysenvmanagervalueeventty; + fdefs: sysenvdefarty; + fhelpheader: msestring; + fhelpfooter: msestring; + fonafterinit: sysenvmanagereventty; + fstatpriority: integer; + ferrorcount: int32; + procedure setoninit(const Value: sysenvmanagereventty); + procedure doinit; + procedure errorme(nr: sysenverrornrty; value: msestring); + procedure checkindex(index: integer); + function getdefined(index: integer): boolean; + function getvalue(index: integer): msestring; + function getvalues(index: integer): msestringarty; + procedure setstatfile(const Value: tstatfile); + function dovalueread(const index: integer; + var defined: boolean; var value: msestringarty): sysenverrornrty; + procedure setdefined(index: integer; const Value: boolean); + procedure setvalue(index: integer; const Value: msestring); + procedure setvalues(index: integer; const Value: msestringarty); + function setdef(index: integer; avalue: msestringarty; + adefined: argumentflagsty): sysenverrornrty; overload; + function setdef(index: integer; avalue: msestring; + adefined: argumentflagsty): sysenverrornrty; overload; + function getintegervalue1(index: integer): integer; + procedure setintegervalue(index: integer; const Value: integer); + procedure setdefs(const avalue: sysenvdefarty); + procedure readdefs(reader: treader); + procedure writedefs(writer: twriter); +// procedure readinitvalues(reader: treader); +// procedure writeinitvalues(writer: twriter); +// procedure readhelps(reader: treader); +// procedure writehelps(writer: twriter); + procedure setoptions(const avalue: sysenvoptionsty); + function getdefcount: int32; + protected + procedure loaded; override; + procedure defineproperties(filer: tfiler); override; + //istatfiler + procedure dostatread(const reader: tstatreader); virtual; + procedure dostatwrite(const writer: tstatwriter); virtual; + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + public + constructor create(aowner: tcomponent); override; + function init(const arguments: array of argumentdefty; + const values: msestringarty): boolean; + //true if ok + function init(const arguments: array of argumentdefty): boolean; + //use commandline values + function init(const values: msestringarty): boolean; //use defs + function init(): boolean; //use defs and commandline values + + procedure processinfo(index: integer; value: string); + procedure errormessage(const mess: msestring); + procedure printmessage(value: msestring); + procedure printhelp; + function getcommandlinemacros(const macrodef: integer; + const firstenvvarmacro: integer = -1; + const lastenvvarmacro: integer = -1; + prepend: macroinfoarty = nil): macroinfoarty; + property errorcount: int32 read ferrorcount; + property defined[index: integer]: boolean read getdefined + write setdefined; default; + property objectlinker: tobjectlinker read getobjectlinker + {$ifdef msehasimplements}implements istatfile{$endif}; + property values[index: integer]: msestringarty + read getvalues write setvalues; + property value[index: integer]: msestring read getvalue write setvalue; + //bringt letzten string in array + property integervalue[index: integer]: integer read getintegervalue1 + write setintegervalue; + //bringt letzten string in array als integer + function getintegervalue(var avalue: integer; const index: integer; + const min: integer = minint; + const max: integer = maxint): boolean; + //false if not defined or not in range + function findfirstfile(filename: filenamety; + searchinvars: array of integer): filenamety; + //bringt erstes filevorkommen + function findlastfile(filename: filenamety; + searchinvars: array of integer): filenamety; + //bringt letztes filevorkommen + property defs: sysenvdefarty read fdefs write setdefs; + property defcount: int32 read getdefcount; + published + property options: sysenvoptionsty read foptions write setoptions + default defaultsysenvmanageroptions; + property errorcode: integer read ferrorcode write ferrorcode + default defaulterrorcode; + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read getstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + property helpheader: msestring read fhelpheader write fhelpheader; + property helpfooter: msestring read fhelpfooter write fhelpfooter; + + property onvalueread: sysenvmanagervalueeventty read fonvalueread + write fonvalueread; + property oninit: sysenvmanagereventty read foninit write setoninit; + property onafterinit: sysenvmanagereventty read fonafterinit + write fonafterinit; + end; + +procedure defstoarguments(const defs: sysenvdefarty; + out arguments: argumentdefarty; out alias: msestringararty); + +implementation +uses + msesysutils,RTLConsts,msestream,msesys{$ifdef UNIX},mselibc{$endif}, + typinfo,mseapplication,msebits,msesysintf,mseformatstr,msefileutils; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +procedure defstoarguments(const defs: sysenvdefarty; + out arguments: argumentdefarty; out alias: msestringararty); +var + int1,int2: integer; + d: psysenvdefty; +begin + setlength(arguments,length(defs)); + setlength(alias,length(defs)); + for int1:= 0 to high(defs) do begin + d:= @defs[int1]; + with arguments[int1] do begin + kind:= d^.kind; + name:= d^.name; + setlength(alias[int1],length(d^.anames)); + for int2:= 0 to high(d^.anames) do begin + alias[int1][int2]:= d^.anames[int2]; + end; + if alias[int1] <> nil then begin + setlength(alias[int1],high(alias[int1])+2); //end marker + end; + anames:= pointer(alias[int1]); + flags:= d^.flags; + initvalue:= d^.initvalue; +// argument:= d^.argument; +// help:= d^.help; + end; + end; +end; + +{ +procedure defstoarguments(const defs: msestring; + out arguments: argumentdefarty; out alias: stringararty); +var + ar1,ar2: msestringarty; + int1: integer; +begin + ar1:= breaklines(defs); + setlength(arguments,length(ar1)); + setlength(alias,length(ar1)); + for int1:= 0 to high(ar1) do begin + splitstringquoted(ar1[int1],ar2,'"',','); + setlength(ar2,5); //max + with arguments[int1] do begin + kind:= argumentkindty(checkenumvalue(typeinfo(argumentkindty),ar2[0])); + name:= ar2[1]; + splitstringquoted(ar2[2],alias[int1]); + if alias[int1] <> nil then begin + setlength(alias[int1],high(alias[int1])+2); + end; + anames:= pointer(alias[int1]); + flags:= argumentflagsty(stringtoset( + ptypeinfo(typeinfo(argumentflagsty)),ar2[3])); + initvalue:= ar2[4]; + end; + end; +end; +} + +{ tsysenvmanager } + +constructor tsysenvmanager.create(aowner: tcomponent); +begin + ferrorcode:= defaulterrorcode; + foptions:= defaultsysenvmanageroptions; + inherited; +end; + +procedure tsysenvmanager.setstatfile(const Value: tstatfile); +begin + setstatfilevar(istatfile(self),value,fstatfile); +end; + +function tsysenvmanager.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +procedure tsysenvmanager.dostatread(const reader: tstatreader); +var + int1,int2: integer; + strar1: msestringarty; + aflags: argumentflagsty; +begin + strar1:= nil; + with reader do begin + int1:= readinteger('envvars',0,0,maxint); + for int1:= 0 to int1-1 do begin + int2:= readinteger(arrayname('flags',int1)); + strar1:= readarray(arrayname('values',int1),msestringarty(nil)); + aflags:= argumentflagsty({$ifdef FPC}longword{$else}word{$endif}(int2)); + if int1 < length(fenvvars) then begin + with fenvvars[int1] do begin + if aflags * arf_defined <> [] then begin + aflags:= aflags - arf_defined + [arf_statdefined]; + end + else begin + aflags:= aflags - arf_defined; + end; + if arf_statoverride in flags then begin + setdef(int1,strar1,flags); + end + else begin + if (arf_stataddval in flags) and not (arf_envdefined in flags) and + (arf_statdefined in aflags) then begin + setdef(int1,strar1,aflags); + end; + end; + end; + end; + end; + end; +end; + +procedure tsysenvmanager.statreading; +begin + //dummy +end; + +procedure tsysenvmanager.statread; +begin + //dummy +end; + +procedure tsysenvmanager.dostatwrite(const writer: tstatwriter); +var + int1: integer; +begin + with writer do begin + writeinteger('envvars',length(fenvvars)); + for int1:= 0 to high(fenvvars) do begin + with fenvvars[int1] do begin + writeinteger('flags',{$ifdef FPC}longword{$else}word{$endif}(flags)); + writearray(arrayname('values',int1),values); +// writeln(word(flags)); +// writeln(values); + end; + end; + end; +end; + +procedure tsysenvmanager.checkindex(index: integer); +begin + if (index < 0) or (index >= length(fenvvars)) then begin + tlist.Error(SListIndexError, Index); + end; +end; + +procedure tsysenvmanager.doinit; +var + ar1: argumentdefarty; + ar2: msestringararty; +begin + if not (csdesigning in componentstate) then begin + if assigned(foninit) then begin + foninit(self); + end + else begin + if fdefs <> nil then begin + defstoarguments(fdefs,ar1,ar2); + init(ar1); + end; + end; + if assigned(fonafterinit) then begin + fonafterinit(self); + end; + end + else begin + if fdefs <> nil then begin + try + try + defstoarguments(fdefs,ar1,ar2); + except + on e: exception do begin + componentexception(self,msestring(e.message)); + end; + end; + except + application.handleexception + end; + end; + end; +end; + +procedure tsysenvmanager.errorme(nr: sysenverrornrty; value: msestring); +var + str1: string; +begin + if nr <> ern_io then begin + inc(ferrorcount); + if not (seo_noerrormess in foptions) then begin + if nr = ern_user then begin + str1:= ansistring(value); + end + else begin + str1:= ansistring(errtexte[nr] + ': '+value); + end; + if seo_toerror in foptions then begin + writestderr(str1,true); + end + else begin +// dispfehler(str1,'Parameter Error'); //!!!!todo + end; + end; + if seo_terminateonerror in foptions then begin + if ferrorcode <> 0 then begin + exitcode:= ferrorcode; + end; + application.terminated:= true; + end; + if seo_haltonerror in foptions then begin + halt(ferrorcode); + end; + if seo_exceptiononerror in foptions then begin + raise ehalt.Create(''); + end; + end; +end; + +procedure tsysenvmanager.errormessage(const mess: msestring); +begin + errorme(ern_user,mess); +end; + +procedure tsysenvmanager.printhelp; + + procedure printitem(const aitem: sysenvdefty{; const envvars: boolean}); + var + int2: integer; + mstr1: msestring; + ar1: msestringarty; + a0,a1: msestring; + begin + mstr1:= ''; + with aitem do begin + if name <> '' then begin + if (kind = ak_par) then begin +// if envvars then begin +// exit; +// end; + if name[1] <> '-' then begin + mstr1:= ' -'+name; + end + else begin + mstr1:= ' -'+name; + end; + if anames <> nil then begin + mstr1:= mstr1+','; + extendstring(mstr1,6); + for int2:= 0 to high(anames) do begin + mstr1:= mstr1+'-'+anames[int2]; + mstr1:= mstr1+','; + end; + setlength(mstr1,length(mstr1)-1); //remove last comma + end; + end + else begin + if (kind = ak_pararg) then begin +// if envvars then begin +// exit; +// end; + if arf_argopt in flags then begin + a0:= '['; + a1:= ']'; + end + else begin + a0:= ''; + a1:= ''; + end; + if name[1] <> '-' then begin + mstr1:= ' -'+name; + end + else begin + mstr1:= ' -'+name+a0+'='; + end; + mstr1:= mstr1+argument+a1; + if anames <> nil then begin + mstr1:= mstr1+','; + extendstring(mstr1,6); + for int2:= 0 to high(anames) do begin + if anames[int2] <> '' then begin + if anames[int2][1] = '-' then begin + mstr1:= mstr1+'-'+anames[int2]+a0+'='+argument+a1; + end + else begin + mstr1:= mstr1+'-'+anames[int2]+a0+argument+a1; + end; + end; + mstr1:= mstr1+','; + end; + setlength(mstr1,length(mstr1)-1); //remove last comma + end; + end + else begin + if {envvars and }(kind = ak_envvar) and (help <> '') then begin + mstr1:= ' '+name; + for int2:= 0 to high(anames) do begin + mstr1:= mstr1+','+anames[int2]; + end; + end + else begin + exit; + end; + end; + end; + end; + if help <> '' then begin + ar1:= breaklines(help); + if length(mstr1) < 29 then begin + extendstring(mstr1,29); + mstr1:= mstr1 + ar1[0]; + end + else begin + mstr1:= mstr1+lineend+charstring(msechar(' '),29)+ar1[0]; + end; + for int2:= 1 to high(ar1) do begin + mstr1:= mstr1+lineend+charstring(msechar(' '),29)+ar1[int2]; + end; + end; + if mstr1 <> '' then begin + if before <> '' then begin + writestderr(ansistring(before),true); + end; + writestderr(ansistring(mstr1),true); + if after <> '' then begin + writestderr(ansistring(after),true); + end; + end; + end; + end; + +var + int1: integer; + +begin + if fhelpheader <> '' then begin + writestderr(ansistring(fhelpheader),true); + end; + for int1:= 0 to high(fdefs) do begin + printitem(fdefs[int1]{,false}); + end; +{ + for int1:= 0 to high(fdefs) do begin + printitem(fdefs[int1],true); + end; +} + if fhelpfooter <> '' then begin + writestderr(ansistring(fhelpfooter),true); + end; +end; + +procedure tsysenvmanager.printmessage(value: msestring); +begin + if seo_tooutput in foptions then begin + value:= value+lineend; + writestdout(ansistring(value)); + end + else begin +// dispmessage(value); //!!!!todo + end; + if seo_exitoninfo in foptions then begin + halt(0); + end; +end; + +function tsysenvmanager.findfirstfile(filename: filenamety; + searchinvars: array of integer): filenamety; +var + int1,int2: integer; + index: integer; + str1: filenamety; +begin + result:= ''; + for int1:= 0 to high(searchinvars) do begin + index:= searchinvars[int1]; + checkindex(index); + for int2:= 0 to high(fenvvars[index].values) do begin + str1:= fenvvars[index].values[int2]; + if str1 <> '' then begin + str1:= includetrailingpathdelimiter(str1); + end; + str1:= str1 + filename; + if fileexists(str1) then begin + result:= str1; + exit; + end; + end; + end; +end; + +function tsysenvmanager.findlastfile(filename: filenamety; + searchinvars: array of integer): filenamety; +var + int1,int2: integer; + index: integer; + str1: filenamety; +begin + result:= ''; + for int1:= high(searchinvars) downto 0 do begin + index:= searchinvars[int1]; + checkindex(index); + for int2:= high(fenvvars[index].values) downto 0 do begin + str1:= fenvvars[index].values[int2]; + if str1 <> '' then begin + str1:= includetrailingpathdelimiter(str1); + end; + str1:= str1 + filename; + if fileexists(str1) then begin + result:= str1; + exit; + end; + end; + end; +end; + +function tsysenvmanager.getdefined(index: integer): boolean; +begin + checkindex(index); + result:= fenvvars[index].flags * arf_defined <> []; +end; + +procedure tsysenvmanager.setdefined(index: integer; + const Value: boolean); +begin + checkindex(index); + if value then begin + fenvvars[index].flags:= fenvvars[index].flags + [arf_setdefined]; + end + else begin + fenvvars[index].flags:= fenvvars[index].flags - arf_defined; + end; +end; + +function tsysenvmanager.getvalue(index: integer): msestring; +begin + checkindex(index); + if length(fenvvars[index].values) = 0 then begin + result:= ''; + end + else begin + result:= fenvvars[index].values[high(fenvvars[index].values)]; + end; +end; + +procedure tsysenvmanager.setvalue(index: integer; const Value: msestring); +var + strar: msestringarty; +begin + checkindex(index); + setlength(strar,1); + strar[0]:= value; + setvalues(index,strar); +end; + +function tsysenvmanager.getvalues(index: integer): msestringarty; +begin + checkindex(index); + result:= fenvvars[index].values; +end; + +procedure tsysenvmanager.setvalues(index: integer; + const Value: msestringarty); +begin + checkindex(index); + fenvvars[index].values:= value; + setdefined(index,true); +end; + +function tsysenvmanager.dovalueread(const index: integer; + var defined: boolean; var value: msestringarty): sysenverrornrty; +begin + result:= ern_io; + if assigned(fonvalueread) then begin + fonvalueread(self,index,defined,value,result); + end; +end; + +function tsysenvmanager.setdef(index: integer; avalue: msestringarty; + adefined: argumentflagsty): sysenverrornrty; +var + strar1: msestringarty; + int1,int2: integer; + bo1: boolean; + i1: int32; +begin + result:= ern_io; + if index >= 0 then begin + bo1:= adefined <> []; + result:= dovalueread(index,bo1,avalue); + if not bo1 then begin + adefined:= adefined - arf_defined; + end; + adefined:= adefined * arf_defined; + + with fenvvars[index] do begin + if flags * arf_defined = [] then begin + {$ifdef FPC} + setlength(values,0); //values:= nil; -> av! + {$else} + values:= nil; //initvalue entfernen + {$endif} + end; + if adefined = [] then begin + flags:= flags - arf_defined; + end + else begin + flags:= flags + adefined; + end; + if result = ern_io then begin + if arf_filenames in flags then begin + for int1:= 0 to high(avalue) do begin + splitstring(avalue[int1],strar1,pathsep); + stackarray(strar1,values); + end; + end + else begin + if arf_integer in flags then begin + for int1:= 0 to high(avalue) do begin + if not trystrtoint(avalue[int1],int2) then begin + result:= ern_invalidinteger; + break; + end; + end; + end; + if result = ern_io then begin + i1:= length(values); + stackarray(avalue,values); + if arf_unquote in flags then begin + for i1:= i1 to high(values) do begin + values[i1]:= unquotefilename(values[i1]); + end; + end; + end; + end; + end; + end; + end; +end; + +function tsysenvmanager.setdef(index: integer; avalue: msestring; + adefined: argumentflagsty): sysenverrornrty; +var + strar1: msestringarty; +begin + setlength(strar1,1); + strar1[0]:= avalue; + result:= setdef(index,strar1,adefined); +end; + +function tsysenvmanager.init(const arguments: array of argumentdefty; + const values: msestringarty): boolean; + +var + index: integer; + strar1: msestringarty; + + function finddef(typen: argumentkindsty; aname: msestring): integer; + + function checkname(const argumentdef: argumentdefty): boolean; + + function checkanames: boolean; + var + po1: pmsestring; + begin + result:= false; + po1:= argumentdef.anames; + if po1 <> nil then begin + while po1^ <> '' do begin + if msecomparestrlen(aname,po1^) = 0 then begin + result:= true; + exit; + end; + inc(po1); + end; + end; + end; //checkanames + + begin //checkname + with argumentdef do begin + result:= kind in typen; + if result then begin +// result:= (msecomparestrlen(aname,name) = 0) or checkanames; + result:= (aname = '') or (msecomparestrlen(name,aname) = 0) or + checkanames(); + end; + end; + end; + + var + int1,int2: integer; + begin + for int1:= 0 to high(arguments) do begin + if checkname(arguments[int1]) then begin + result:= int1; + for int2:= int1 + 1 to high(arguments) do begin + if checkname(arguments[int2]) then begin + errorme(ern_ambiguousparameter,strar1[index]); + result:= -2; + break; + end; + end; + exit; + end; + end; + result:= -1; + end; + + function isparameter(const str: msestring): boolean; + begin + result:= (length(str) > 0) and (str[1] = commandlineparchar); + end; + + procedure findswitch(str1: msestring); + var + pardefindex1: integer; + + procedure setoptargument; + var + needed: boolean; + begin + needed:= not (arf_argopt in arguments[pardefindex1].flags); + inc(index); + if index < length(strar1) then begin + if isparameter(strar1[index]) then begin + dec(index); + if needed then begin + errorme(ern_missedargument,strar1[index]); + end + else begin + errorme(setdef(pardefindex1,nil,[arf_envdefined]),strar1[index]); + end; + end + else begin + errorme(setdef(pardefindex1,strar1[index],[arf_envdefined]),strar1[index]); + end; + end + else begin + dec(index); + if needed then begin + errorme(ern_missedargument,strar1[index]); + end + else begin + errorme(setdef(pardefindex1,nil,[arf_envdefined]),strar1[index]); + end; + end; + end; + + procedure checkarguments; + begin + case arguments[pardefindex1].kind of + ak_pararg: begin + if length(str1) > 0 then begin + errorme(setdef(pardefindex1,str1,[arf_envdefined]),str1) + end + else begin + setoptargument; + end; + end; + ak_par: begin + errorme(setdef(pardefindex1,nil,[arf_envdefined]),str1); + if length(str1) > 0 then begin + findswitch(str1); + end; + end; + end; + end; + + var + strar2: msestringarty; + + begin //findswitch + if length(str1) > 0 then begin + if isparameter(str1) then begin //langer parameter + setlength(strar2,2); + splitstring(str1,strar2,'='); + pardefindex1:= finddef(at_pars,strar2[0]); + if pardefindex1 >= 0 then begin + with fenvvars[pardefindex1] do begin + case arguments[pardefindex1].kind of + ak_par: begin + if length(strar2) > 1 then begin + errorme(ern_invalidargument,strar1[index]); + end + else begin + include(flags,arf_envdefined); + end; + end; + ak_pararg: begin + if length(strar2) > 1 then begin + errorme(setdef(pardefindex1,strar2[1],[arf_envdefined]),strar1[index]); + end + else begin + setoptargument; + end; + end; + end; + end; + end + else begin + if pardefindex1 = -1 then begin + errorme(ern_invalidparameter,strar1[index]); + end; + end; + end + else begin + pardefindex1:= finddef(at_pars,str1); + if pardefindex1 < 0 then begin + pardefindex1:= finddef(at_pars,str1[1]); + if pardefindex1 >= 0 then begin + str1:= copy(str1,2,maxint); + checkarguments; + end + else begin + if pardefindex1 = -1 then begin + errorme(ern_invalidparameter,strar1[index]); + end; + end; + end + else begin + str1:= copy(str1,length(arguments[pardefindex1].name)+1,maxint); + checkarguments; + end; + end; + end + else begin + errorme(ern_invalidparameter,strar1[index]); + end; + end; + +var + i1: integer; + str1: msestring; +// {$ifdef UNIX} +// po1: pchar; +// {$endif} +begin //init + ferrorcount:= 0; + if high(arguments) = -1 then begin + exit; + end; + setlength(fenvvars,high(arguments)+1); + for i1:= 0 to high(fenvvars) do begin + with fenvvars[i1] do begin + flags:= arguments[i1].flags; + name:= arguments[i1].name; + setlength(values,1); + values[0]:= arguments[i1].initvalue; + end; + end; + strar1:= values; + index:= 0; + while index < length(strar1) do begin + str1:= strar1[index]; + if isparameter(str1) then begin + str1:= copy(str1,2,maxint); + findswitch(str1); + end + else begin + i1:= finddef([ak_arg],''); + if i1 >= 0 then begin + errorme(setdef(i1,str1,[arf_envdefined]),str1); + end + else begin + errorme(ern_invalidargument,str1); + end; + end; + inc(index); + end; + for i1:= 0 to high(arguments) do begin + if (arf_help in arguments[i1].flags) and + (fenvvars[i1].flags * arf_defined <> []) then begin + printhelp; + application.terminated:= true; + exit; + end; + end; + for i1:= 0 to high(arguments) do begin + with arguments[i1] do begin + if kind = ak_envvar then begin + {$ifdef mswindows} + str1:= + {$ifdef FPC}sysutils.{$endif}getenvironmentvariable(name); + //!!!! delphi bug flicken(info in qc)!! + if str1 <> '' then begin +// errorme(setdef(int1,str1,true),name); + errorme(setdef(i1,str1,[arf_envdefined]),name); + end; + {$else} +{ + po1:= getenv(pchar(name)); + if po1 <> nil then begin + errorme(setdef(int1,po1,[arf_envdefined]),name); + end; +} + if sys_getenv(name,str1) then begin + errorme(setdef(i1,str1,[arf_envdefined]),name); + end; + {$endif}; + end; + if (arf_mandatory in flags) and not defined[i1] then begin + str1:= ''; + if not (kind in [ak_arg]) then begin + str1:= '-'; + end; + errorme(ern_mandatoryparameter,str1+name); + end; + end; + end; + result:= ferrorcount = 0; +end; + +function tsysenvmanager.init(const arguments: array of argumentdefty): boolean; +var + ar1: msestringarty; +begin + ar1:= getcommandlinearguments(); + if high(ar1) > 0 then begin + //FPC 2.6.4 throws an exception in copy() if out of range + result:= init(arguments,copy(ar1,1,bigint)); + end + else begin + result:= init(arguments,nil); + end; +end; + +function tsysenvmanager.init(const values: msestringarty): boolean; //use defs +var + ar1: argumentdefarty; + ar2: msestringararty; +begin + defstoarguments(fdefs,ar1,ar2); + result:= init(ar1,values); +end; + +function tsysenvmanager.init(): boolean; //use defs and commandline values +begin + result:= init(copy(getcommandlinearguments(),1,bigint)); +end; + +procedure tsysenvmanager.processinfo(index: integer; value: string); +begin + if defined[index] then begin + printmessage(msestring(value)); + end; +end; + +procedure tsysenvmanager.setoninit(const Value: sysenvmanagereventty); +begin + foninit := Value; + if not (csloading in componentstate) then begin + doinit(); + end; +end; + +procedure tsysenvmanager.loaded; +begin + inherited; + if not (seo_noautoinit in foptions) then begin + doinit(); + end; +end; + +procedure readdefdata(const reader: treader; var data); +begin + with sysenvdefty(data) do begin + ord(kind):= reader.readenum(typeinfo(kind)); + name:= reader.readunicodestring; + readstringar(reader,anames); + longword(flags):= reader.readset(typeinfo(flags)); + initvalue:= reader.readunicodestring; + argument:= reader.readunicodestring; + help:= reader.readunicodestring; + before:= reader.readunicodestring; + after:= reader.readunicodestring; + end; +end; + +procedure tsysenvmanager.readdefs(reader: treader); +var + ar1: sysenvdefarty; +begin + ar1:= nil; //compiler warning + readrecordar(reader,ar1,typeinfo(ar1),@readdefdata); + defs:= ar1; +end; + +procedure writedefdata(const writer: twriter; const data); +begin + with sysenvdefty(data) do begin + writer.writeenum(ord(kind),typeinfo(kind)); + writer.writeunicodestring(name); + writestringar(writer,anames); + writer.writeset(longword(flags),typeinfo(flags)); + writer.writeunicodestring(initvalue); + writer.writeunicodestring(argument); + writer.writeunicodestring(help); + writer.writeunicodestring(before); + writer.writeunicodestring(after); + end; +end; + +procedure tsysenvmanager.writedefs(writer: twriter); +begin + writerecordar(writer,fdefs,typeinfo(fdefs),@writedefdata); +end; +{ +procedure tsysenvmanager.readinitvalues(reader: treader); +begin +end; + +procedure tsysenvmanager.writeinitvalues(writer: twriter); +begin +end; + +procedure tsysenvmanager.readhelps(reader: treader); +begin +end; + +procedure tsysenvmanager.writehelps(writer: twriter); +begin +end; +} +procedure tsysenvmanager.defineproperties(filer: tfiler); + + function needswritedefs: boolean; + var + po1: psysenvdefty; + int1,int2: integer; + begin + with tsysenvmanager(filer.ancestor) do begin + result:= high(fdefs) <> high(self.fdefs); + if not result then begin + for int1:= 0 to high(fdefs) do begin + po1:= @self.fdefs[int1]; + with fdefs[int1] do begin + result:= high(anames) <> high(po1^.anames); + if not result then begin + for int2:= 0 to high(anames) do begin + if anames[int2] <> po1^.anames[int2] then begin + result:= true; + break; + end; + end; + if not result then begin + result:= + (kind <> po1^.kind) or + (name <> po1^.name) or + (flags <> po1^.flags) or + (initvalue <> po1^.initvalue) or + (argument <> po1^.argument) or + (help <> po1^.help); + end; + end; + end; + if result then begin + break; + end; + end; + end; + end; + end; + +begin + inherited; + filer.defineproperty('defs',@readdefs,@writedefs, + (filer.ancestor = nil) and (fdefs <> nil) or + (filer.ancestor <> nil) and needswritedefs); +// filer.defineproperty('default',@readinitvalues,@writeinitvalues,fdefs <> nil); +// filer.defineproperty('help',@readhelps,@writehelps,fdefs <> nil); +end; + +function tsysenvmanager.getintegervalue1(index: integer): integer; +begin + result:= strtoint(getvalue(index)); +end; + +function tsysenvmanager.getintegervalue(var avalue: integer; const index: integer; + const min: integer = minint; const max: integer = maxint): boolean; + //false if not defined or not in range +var + int1: integer; +begin + result:= defined[index]; + if result then begin + int1:= integervalue[index]; + if (int1 < min) or (int1 > max) then begin + result:= false; + end + else begin + avalue:= int1; + end; + end; +end; + +procedure tsysenvmanager.setintegervalue(index: integer; + const Value: integer); +begin + setvalue(index,inttostrmse(value)); +end; + +function tsysenvmanager.getcommandlinemacros( + const macrodef: integer; + const firstenvvarmacro: integer = -1; const lastenvvarmacro: integer = -1; + prepend: macroinfoarty = nil): macroinfoarty; +var + ar1,ar2: msestringarty; + int1,int2,int3,int4: integer; + po1: penvvarty; +begin + result:= prepend; + checkindex(macrodef); + if (firstenvvarmacro >= 0) and (lastenvvarmacro >= 0) then begin + checkindex(firstenvvarmacro); + checkindex(lastenvvarmacro); + for int1:= ord(firstenvvarmacro) to ord(lastenvvarmacro) do begin + //envvar macros can be overridden by --macrodef + if defined[int1] then begin + setlength(result,high(result) + 2); + with result[high(result)] do begin + po1:= @fenvvars[int1]; + name:= po1^.name; + if po1^.values <> nil then begin + value:= po1^.values[high(po1^.values)]; + end; + end; + end; + end; + end; + ar1:= values[macrodef]; + for int1:= 0 to high(ar1) do begin + ar2:= nil; + splitstringquoted(ar1[int1],ar2,msechar('"'),msechar(',')); + if ar2 <> nil then begin + int3:= length(result); + int4:= (high(ar2)+2) div 2; //pair count + setlength(result,int3+int4); + for int2:= 0 to int4-1 do begin + with result[int2+int3] do begin + int4:= int2 * 2; + name:= ar2[int4]; + if int4 < high(ar2) then begin + value:= ar2[int4+1] + end; + end; + end; + end; + end; +end; + +procedure tsysenvmanager.setdefs(const avalue: sysenvdefarty); + +begin + fdefs:= avalue; + if not (csloading in componentstate) then begin + doinit; + end; +end; + +procedure tsysenvmanager.setoptions(const avalue: sysenvoptionsty); +begin + foptions:= sysenvoptionsty(setsinglebit(longword(avalue),longword(foptions), + longword([seo_terminateonerror,seo_haltonerror,seo_exceptiononerror]))); + if not (csdesigning in componentstate) and + (seo_appterminateonexception in avalue) then begin + application.options:= application.options + [apo_terminateonexception]; + end; +end; + +function tsysenvmanager.getdefcount: int32; +begin + result:= length(fdefs); +end; + +function tsysenvmanager.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +end. diff --git a/mseide-msegui/lib/common/unicode/mseunicode.pas b/mseide-msegui/lib/common/unicode/mseunicode.pas new file mode 100644 index 0000000..d833db1 --- /dev/null +++ b/mseide-msegui/lib/common/unicode/mseunicode.pas @@ -0,0 +1,287 @@ +unit mseunicode; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes{msestrings},msegraphics,msegraphutils,mseguiglob; + +type + + tunifont = class(tfont) + public + constructor create; override; + function hasglyph(const achar: unicharty): boolean; + function createfontwithglyph(const achar: unicharty): tunifont; + //nil if none exist + end; + unifontarty = array of tunifont; + + tunisubstfont = class(tunifont) + private + fbase: tunifont; + protected + function getfont(var drawinfo: drawinfoty): boolean; override; + function gethandle: fontnumty; override; + public + constructor create(const base: tunifont; const aglyph: unicharty); reintroduce; + end; + + unitextstatety = (uts_fontmatched); + unitextstatesty = set of unitextstatety; + + segmentinfoty = record + charindex: integer; //null based + fontnum: integer; //index in ffonts + end; + segmentinfoarty = array of segmentinfoty; + + tunitext = class + private + ffont: tunifont; + ftext: msestring; + fstate: unitextstatesty; + ffonts: unifontarty; + fsegments: segmentinfoarty; + procedure setfont(const avalue: tunifont); + procedure settext(const avalue: msestring); + procedure freefonts; + protected + procedure fontchanged(const sender: tobject); + procedure changed; + procedure checkstate; + procedure matchfonts; + public + constructor create(const atext: msestring = ''; const afont: tfont = nil); + //afont = nil -> stf_unicode + destructor destroy; override; + procedure drawstring(const acanvas: tcanvas; const apos: pointty; + const grayed: boolean = false); + property font: tunifont read ffont write setfont; + property text: msestring read ftext write settext; + end; + +procedure unidrawstring(const acanvas: tcanvas; const atext: msestring; + const apos: pointty; + const afont: tfont = nil; const grayed: boolean = false); +implementation +uses + mseuniintf,sysutils,msefont; + +procedure unidrawstring(const acanvas: tcanvas; const atext: msestring; + const apos: pointty; + const afont: tfont = nil; const grayed: boolean = false); +var + unitext1: tunitext; +begin + unitext1:= tunitext.create(atext,afont); + try + unitext1.drawstring(acanvas,apos,grayed); + finally + unitext1.free; + end; +end; + +{ tunifont } + +constructor tunifont.create; +begin + inherited; + name:= 'stf_unicode'; +end; + +function tunifont.hasglyph(const achar: unicharty): boolean; +var + info: drawinfoty; +begin + with info,fonthasglyph do begin + try + font:= getdatapo^.font; + unichar:= achar; + gdi_call(gdf_fonthasglyph,info); + result:= hasglyph; + except + result:= false; + end; + end; +end; + +function tunifont.createfontwithglyph(const achar: unicharty): tunifont; +begin + result:= tunisubstfont.create(self,achar); + if not result.hasglyph(achar) then begin + freeandnil(result); + end; +end; + +{ tunisubstfont } + +constructor tunisubstfont.create(const base: tunifont; const aglyph: unicharty); +begin + finfo.glyph:= aglyph; + fbase:= base; + inherited create; + assignproperties(base,false); +end; + +function tunisubstfont.getfont(var drawinfo: drawinfoty): boolean; +begin + result:= uni_getfontwithglyph(drawinfo); + if result then begin + drawinfo.getfont.basefont:= fbase.getdatapo^.font; + end; +end; + +function tunisubstfont.gethandle: fontnumty; +begin + if fhandlepo^ = 0 then begin + fhandlepo^:= getfontforglyph(fbase.getdatapo^.font,finfo.glyph); + end; + result:= inherited gethandle; +end; + +{ tunitext } + +constructor tunitext.create(const atext: msestring = ''; const afont: tfont = nil); +begin + ftext:= atext; + ffont:= tunifont.create; + setlength(ffonts,1); + ffonts[0]:= ffont; + if afont <> nil then begin + ffont.assign(afont); + end; + ffont.onchange:= {$ifdef FPC}@{$endif}fontchanged; +end; + +destructor tunitext.destroy; +begin + ffont.free; + freefonts; + inherited; +end; + +procedure tunitext.setfont(const avalue: tunifont); +begin + ffont.assign(avalue); +end; + +procedure tunitext.fontchanged(const sender: tobject); +begin + changed; +end; + +procedure tunitext.changed; +begin + exclude(fstate,uts_fontmatched); +end; + +procedure tunitext.drawstring(const acanvas: tcanvas; const apos: pointty; + const grayed: boolean = false); +var + int1,int2,int3: integer; + pt1: pointty; + po1: pmsechar; +begin + checkstate; + pt1:= apos; + po1:= pmsechar(ftext); + for int1:= 0 to high(fsegments) do begin + with fsegments[int1] do begin + if int1 < high(fsegments) then begin + int2:= fsegments[int1+1].charindex - charindex; + int3:= acanvas.getstringwidth(po1,int2,ffonts[fontnum]); + end + else begin + int2:= length(ftext) - charindex; //rest + int3:= 0; //compiler warning + end; + acanvas.drawstring(po1,int2,pt1,ffonts[fontnum]); + inc(pt1.x,int3); + inc(po1,int2); + end; + end; +end; + +procedure tunitext.checkstate; +begin + if not (uts_fontmatched in fstate) then begin + matchfonts; + end; +end; + +procedure tunitext.matchfonts; +var + int1: integer; + fontnum1: integer; + first: boolean; + + procedure addsegment; + begin + if not first then begin + setlength(fsegments,high(fsegments)+2); + end; + with fsegments[high(fsegments)] do begin + charindex:= int1 - 1; + fontnum:= fontnum1; + end; + end; + +var + int2: integer; + fontnum2: integer; + unich1: unicharty; + font1: tunifont; + +begin + fontnum1:= 0; + int1:= 1; + fsegments:= nil; + first:= false; + addsegment; + first:= true; + while int1 <= length(ftext) do begin + unich1:= word(ftext[int1]); + fontnum2:= -1; + for int2:= 0 to high(ffonts) do begin + if ffonts[int2].hasglyph(unich1) then begin + fontnum2:= int2; + break; + end; + end; + if fontnum2 < 0 then begin + font1:= ffont.createfontwithglyph(unich1); + if font1 <> nil then begin + setlength(ffonts,high(ffonts)+2); + fontnum2:= high(ffonts); + ffonts[fontnum2]:= font1; + end + else begin + fontnum2:= 0; //no font with glyph found + end; + end; + if fontnum2 <> fontnum1 then begin + fontnum1:= fontnum2; + addsegment; + end; + first:= false; + inc(int1); + end; + include(fstate,uts_fontmatched); +end; + +procedure tunitext.settext(const avalue: msestring); +begin + ftext:= avalue; + changed; +end; + +procedure tunitext.freefonts; +var + int1: integer; +begin + for int1:= 1 to high(ffonts) do begin + ffonts[int1].free; + end; + setlength(ffonts,1); +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/msebarcode.pas b/mseide-msegui/lib/common/widgets/msebarcode.pas new file mode 100644 index 0000000..21bae43 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msebarcode.pas @@ -0,0 +1,739 @@ +{ MSEgui Copyright (c) 2011-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msebarcode; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + msetypes,classes,mclasses,msewidgets,msebitmap,msegraphics,mseclasses, + msegraphutils, + msestrings,msegui,msemenus,mseguiglob; + +type + barcodestatety = (bcs_bitmapvalid,bcs_layoutvalid,bcs_painting); + barcodestatesty = set of barcodestatety; + bitmapnumty = (bmn_1,bmn_2); + + tcustombarcode = class; + + tbarcodefont = class(tfont) + private + fowner: tcustombarcode; + protected + procedure dochanged(const changed: canvasstatesty; + const nochange: boolean); override; + public + constructor create(const aowner: tcustombarcode); reintroduce; + end; + + barcodeoptionty = (bco_calcchecksum); + barcodeoptionsty = set of barcodeoptionty; + + tcustombarcode = class(tpublishedwidget) + private + fbitmap1: tbitmap; + fbitmap2: tbitmap; + fcellcount: integer; + fcelldata1: pbyte; + fcelldata2: pbyte; + fcolorbar: colorty; + fcolorspace: colorty; + fvalue: msestring; + fcode: msestring; + fcoderect: rectty; + fsubcliprects: rectarty; + ffontbar: tbarcodefont; + fdirection: graphicdirectionty; + foptions: barcodeoptionsty; + procedure setcolorbar(const avalue: colorty); + procedure setcolorspace(const avalue: colorty); + procedure setvalue(const avalue: msestring); + procedure setcell1(const adata: pbyte; const aindex: integer; + const avalue: boolean); + procedure setfontbar(const avalue: tbarcodefont); + procedure setdirection(const avalue: graphicdirectionty); + procedure setoptions(const avalue: barcodeoptionsty); + protected + fbarrect1: rectty; + fbarrect2: rectty; + fstate: barcodestatesty; + procedure adjustrect(var arect: rectty); + procedure checkbitmap; + procedure calcbitmap; virtual; abstract; + procedure updatelayout(const asize: sizety); virtual; + procedure checkvalue; virtual; + procedure dopaint2(const acanvas: tcanvas); virtual; + procedure dopaintforeground(const acanvas: tcanvas); override; + procedure clientrectchanged; override; + procedure change(const alayout: boolean); + procedure setcell(const anum: bitmapnumty; const aindex: integer; + const avalue: boolean = true); overload; + procedure setcell(const anum: bitmapnumty; + const aindex: array of integer); overload; + procedure subcliprect(const arect: rectty); + procedure drawtext(const acanvas: tcanvas; const atext: msestring; + const adest: rectty; const aheight: integer); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property direction: graphicdirectionty read fdirection + write setdirection default gd_right; + property colorbar: colorty read fcolorbar write setcolorbar + default cl_black; + property colorspace: colorty read fcolorspace write setcolorspace + default cl_transparent; + property value: msestring read fvalue write setvalue; + property fontbar: tbarcodefont read ffontbar write setfontbar; + property options: barcodeoptionsty read foptions write setoptions default []; + end; + + barcodekindty = (bk_none,bk_gtin_13,bk_gtin_8); + + tcustombarcode1 = class(tcustombarcode) + private + fkind: barcodekindty; + procedure setkind(const avalue: barcodekindty); + protected + ffontheight: integer; + frect1: rectty; + frect2: rectty; + frect3: rectty; + procedure checkvalue; override; + procedure calcbitmap; override; + procedure updatelayout(const asize: sizety); override; + procedure dopaint2(const acanvas: tcanvas); override; + public + property kind: barcodekindty read fkind write setkind default bk_none; + end; + + tbarcode = class(tcustombarcode1) + published + property options; + property kind; + property direction; + property colorbar; + property colorspace; + property value; + property fontbar; + end; + +function encodegtin13(const avalue: int64): msestring; //'' on error +function decodegtin13(const avalue: msestring): int64; //-1 on error + +implementation +uses + rtlconsts,msebits,msedrawtext,mseformatstr; + +function gtin13checksum(const avalue: int64): int32; +var + i1,i2,i3: int32; + i4: int64; +begin + i2:= 0; + i4:= avalue; + for i1:= 0 to 11 do begin + i3:= i4 mod 10; + if odd(i1) then begin + i2:= i2 + i3; + end + else begin + i2:= i2 + i3*3; + end; + i4:= i4 div 10; + end; + result:= (10 - i2 mod 10) mod 10; +end; + +function encodegtin13(const avalue: int64): msestring; //'' on error +begin + result:= ''; + if (avalue >= 0) and (avalue <= 999999999999) then begin + result:= inttostrmse(avalue*10+int64(gtin13checksum(avalue))); + end; +end; + +function decodegtin13(const avalue: msestring): int64; //-1 on error +var + i1,i2: int64; +begin + result:= -1; + if trystrtoint64(avalue,i1) then begin + i2:= i1 div 10; + if gtin13checksum(i2) = i1 mod 10 then begin + result:= i2; + end; + end; +end; + +type + patterngtin13ty = (pgt13_l0,pgt13_l1,pgt13_r,pgt13_13); + +const + textflags: array[graphicdirectionty] of textflagsty = + //gd_right + ([tf_xcentered,tf_ycentered], + //gd_up + [tf_xcentered,tf_ycentered,tf_rotate90], + //gd_left + [tf_xcentered,tf_ycentered,tf_rotate180], + //gd_down + [tf_xcentered,tf_ycentered,tf_rotate180,tf_rotate90], + //gd_none + [tf_xcentered,tf_ycentered]); + + cellcounts: array[barcodekindty] of integer = + //bk_none,bk_gtin_13, bk_gtin_8 + (0, 3+6*7+5+6*7+3, 3+4*7+5+4*7+3 ); + framesizes: array[barcodekindty] of integer = + //bk_none,bk_gtin_13, bk_gtin_8 + (0, 2*7, 2*7); + charwidths: array[barcodekindty] of integer = + //bk_none,bk_gtin_13, bk_gtin_8 + (0, 7, 7); + { + spacecounts: array[barcodekindty] of integer = + //bk_none,bk_gtin_13 + (0, 3*3+2*7); + charcounts: array[barcodekindty] of integer = + //bk_none,bk_gtin_13 + (1, 13); + } + patterngtin13: array[patterngtin13ty,0..9] of byte = +// 0 1 2 3 4 5 6 7 8 9 +//0001101 0011001 0010011 0111101 0100011 0110001 0101111 0111011 0110111 0001011 _l0 + (($0d, $19, $13, $3d, $23, $31, $2f, $3b, $37, $0b),//_13 0 +//0100111 0110011 0011011 0100001 0011101 0111001 0000101 0010001 0001001 0010111 _l1 + ($27, $33, $1b, $21, $1d, $39, $05, $11, $09, $17),//_13 1 +//1110010 1100110 1101100 1000010 1011100 1001110 1010000 1000100 1001000 1110100 _r + ($72, $66, $6c, $42, $5c, $4e, $50, $44, $48, $74), +// 000000 001011 001101 001110 010011 011001 011100 010101 010110 011010 _13 + ($00, $0b, $0d, $0e, $13, $19, $1c, $15, $16, $1a) + ); + + reversemask7: array[0..6] of byte = + //1000000 0100000 0010000 0001000 0000100 0000010 0000001 + ( $40, $20, $10, $08, $04, $02, $01); + reversemask6: array[0..5] of byte = + //0100000 0010000 0001000 0000100 0000010 0000001 + ( $20, $10, $08, $04, $02, $01); + +{ tcustombarcode } + +constructor tcustombarcode.create(aowner: tcomponent); +begin + fcolorbar:= cl_black; + fcolorspace:= cl_transparent; + ffontbar:= tbarcodefont.create(self); + inherited; + fbitmap1:= tbitmap.create(bmk_mono{true}); + fbitmap2:= tbitmap.create(bmk_mono{true}); +end; + +destructor tcustombarcode.destroy; +begin + fbitmap1.free; + fbitmap2.free; + ffontbar.free; + inherited; +end; + +procedure tcustombarcode.checkbitmap; +var + int1: integer; +begin + if fstate * [bcs_bitmapvalid,bcs_layoutvalid] <> + [bcs_bitmapvalid,bcs_layoutvalid] then begin + checkvalue; + if not (bcs_layoutvalid in fstate) then begin + fsubcliprects:= nil; + fcellcount:= 0; + fbarrect1:= mr(nullpoint,fcoderect.size); + if fdirection in [gd_up,gd_down] then begin + with fbarrect1 do begin + int1:= cx; + cx:= cy; + cy:= int1; + end; + end; + fbarrect2:= fbarrect1; + if fdirection in [gd_up,gd_down] then begin + updatelayout(ms(fcoderect.cy,fcoderect.cx)); + end + else begin + updatelayout(fcoderect.size); + end; + adjustrect(fbarrect1); + adjustrect(fbarrect2); + for int1:= 0 to high(fsubcliprects) do begin + adjustrect(fsubcliprects[int1]); + end; + end; + fcelldata1:= nil; + fcelldata2:= nil; + if (fcode = '') or (fcellcount <= 0) then begin + fbitmap1.clear; + fbitmap2.clear; + end + else begin + if fdirection in [gd_up,gd_down] then begin + fbitmap1.size:= ms(1,fcellcount); + fbitmap2.size:= ms(1,fcellcount); + fcelldata1:= fbitmap1.scanline[0]; + fcelldata2:= fbitmap2.scanline[0]; + fillchar(fcelldata1^,fcellcount*4,0); + fillchar(fcelldata2^,fcellcount*4,0); + end + else begin + fbitmap1.size:= ms(fcellcount,1); + fbitmap2.size:= ms(fcellcount,1); + fcelldata1:= fbitmap1.scanline[0]; + fcelldata2:= fbitmap2.scanline[0]; + fillchar(fcelldata1^,((fcellcount+31) div 32) * 4,0); + fillchar(fcelldata2^,((fcellcount+31) div 32) * 4,0); + end; + calcbitmap; + end; + fstate:= fstate + [bcs_bitmapvalid,bcs_layoutvalid]; + end; +end; + +procedure tcustombarcode.dopaintforeground(const acanvas: tcanvas); +var + reg1: regionty; + int1: integer; +begin + inherited; + checkbitmap; + if fsubcliprects <> nil then begin + reg1:= acanvas.copyclipregion; + for int1:= 0 to high(fsubcliprects) do begin + acanvas.subcliprect(fsubcliprects[int1]); + end; + end; + fbitmap1.paint(acanvas,fbarrect1,[al_stretchx,al_stretchy,al_or], + fcolorbar,fcolorspace); + fbitmap2.paint(acanvas,fbarrect2,[al_stretchx,al_stretchy,al_or], + fcolorbar,cl_transparent); + if fsubcliprects <> nil then begin + acanvas.clipregion:= reg1; + end; + include(fstate,bcs_painting); + try + dopaint2(acanvas); + finally + exclude(fstate,bcs_painting); + end; +end; + +procedure tcustombarcode.change(const alayout: boolean); +begin + exclude(fstate,bcs_bitmapvalid); + if alayout then begin + exclude(fstate,bcs_layoutvalid); + end; + invalidate; +end; + +procedure tcustombarcode.setcell1(const adata: pbyte; const aindex: integer; + const avalue: boolean); +var + po1: pbyte; + int1: integer; +begin + if (aindex < 0) or (aindex >= fcellcount) then begin + tlist.error(slistindexerror,aindex); + end; + int1:= aindex; + if fdirection in [gd_left,gd_up] then begin + int1:= fcellcount-aindex-1; + end; + if fdirection in [gd_right,gd_left] then begin + po1:= pbyte(pchar(adata)+(int1 div 8)); + if avalue then begin + po1^:= po1^ or bits[int1 and $07]; + end + else begin + po1^:= po1^ and not bits[int1 and $07]; + end; + end + else begin + po1:= pbyte(pchar(adata)+(int1 * 4)); + if avalue then begin + plongword(po1)^:= $ffffffff; + end + else begin + po1^:= 0; + end; + end; +end; + +procedure tcustombarcode.setcell(const anum: bitmapnumty; const aindex: integer; + const avalue: boolean = true); +begin + if anum = bmn_1 then begin + setcell1(fcelldata1,aindex,avalue); + end + else begin + setcell1(fcelldata2,aindex,avalue); + end; +end; + +procedure tcustombarcode.setcell(const anum: bitmapnumty; + const aindex: array of integer); +var + int1: integer; + po1: pbyte; +begin + po1:= fcelldata2; + if anum = bmn_1 then begin + po1:= fcelldata1; + end; + for int1:= 0 to high(aindex) do begin + setcell1(po1,aindex[int1],true); + end; +end; + +procedure tcustombarcode.setcolorbar(const avalue: colorty); +begin + if fcolorbar <> avalue then begin + fcolorbar:= avalue; + invalidate; + end; +end; + +procedure tcustombarcode.setcolorspace(const avalue: colorty); +begin + if fcolorspace <> avalue then begin + fcolorspace:= avalue; + invalidate; + end; +end; + +procedure tcustombarcode.setvalue(const avalue: msestring); +begin + if fvalue <> avalue then begin + fvalue:= avalue; +// checkvalue; + change(false); + end; +end; + +procedure tcustombarcode.checkvalue; +begin + fcode:= fvalue; +end; + +procedure tcustombarcode.updatelayout(const asize: sizety); +begin + //dummy +end; + +procedure tcustombarcode.clientrectchanged; +begin + inherited; + fcoderect:= innerclientrect; + change(true); +end; + +procedure tcustombarcode.subcliprect(const arect: rectty); +begin + setlength(fsubcliprects,high(fsubcliprects)+2); + fsubcliprects[high(fsubcliprects)]:= arect; +end; + +procedure tcustombarcode.drawtext(const acanvas: tcanvas; + const atext: msestring; const adest: rectty; + const aheight: integer); +var + int1: integer; +begin + int1:= ffontbar.height; + ffontbar.height:= aheight; + msedrawtext.drawtext(acanvas,atext,adest,textflags[fdirection],ffontbar); + ffontbar.height:= int1; +end; + +procedure tcustombarcode.setfontbar(const avalue: tbarcodefont); +begin + ffontbar.assign(avalue); +end; + +procedure tcustombarcode.dopaint2(const acanvas: tcanvas); +begin + //dummy +end; + +procedure tcustombarcode.setdirection(const avalue: graphicdirectionty); +begin + if fdirection <> avalue then begin + if not (csreading in componentstate) then begin + changedirection(avalue,fdirection); + end + else begin + fdirection:= avalue; + end; + change(true); + end; +end; + +procedure tcustombarcode.adjustrect(var arect: rectty); +var + pt1: pointty; + int1: integer; +begin + pt1:= arect.pos; + with arect do begin + case fdirection of + gd_up: begin + pt1.x:= y + fcoderect.x; + pt1.y:= fcoderect.y + fcoderect.cy - x - cx; + int1:= arect.cx; + arect.cx:= arect.cy; + arect.cy:= int1; + end; + gd_left: begin + pt1.x:= fcoderect.x + fcoderect.cx - x - cx; + pt1.y:= fcoderect.y + fcoderect.cy - y - cy; + end; + gd_down: begin + pt1.x:= fcoderect.x + fcoderect.cx - y - cy; + pt1.y:= fcoderect.y + x; + int1:= arect.cx; + arect.cx:= arect.cy; + arect.cy:= int1; + end; + else begin //gd_right + pt1.x:= fcoderect.x + x; + pt1.y:= fcoderect.y + y; + end; + end; + end; + arect.pos:= pt1; +end; + +procedure tcustombarcode.setoptions(const avalue: barcodeoptionsty); +begin + if foptions <> avalue then begin + foptions:= avalue; + change(false); +// checkvalue; + end; +end; + +{ tcustombarcode1 } + +procedure tcustombarcode1.calcbitmap; +var + cellindex: integer; + + procedure putcells(const apattern: byte); + var + int1: integer; + begin + for int1:= 0 to high(reversemask7) do begin + if apattern and reversemask7[int1] <> 0 then begin + setcell(bmn_2,cellindex); + end; + inc(cellindex); + end; + end; + +var + int1: integer; + digits: array[0..11] of byte; + by2: byte; + pat1: patterngtin13ty; +begin + case fkind of + bk_gtin_8: begin + setcell(bmn_1,[0,2,32,34,64,66]); //start, center, stop + for int1:= 6 to 13 do begin + digits[int1-6]:= ord(fcode[int1])-ord('0'); + end; + cellindex:= 3; + for int1:= 0 to 3 do begin + putcells(patterngtin13[pgt13_l0,digits[int1]]); + end; + cellindex:= 36; + for int1:= 4 to 7 do begin + putcells(patterngtin13[pgt13_r,digits[int1]]); + end; + end; + bk_gtin_13: begin + setcell(bmn_1,[0,2,46,48,92,94]); //start, center, stop + for int1:= 2 to 13 do begin + digits[int1-2]:= ord(fcode[int1])-ord('0'); + end; + by2:= patterngtin13[pgt13_13,ord(fcode[1])-ord('0')]; + cellindex:= 3; + for int1:= 0 to 5 do begin + pat1:= pgt13_l0; + if by2 and reversemask6[int1] <> 0 then begin + pat1:= pgt13_l1; + end; + putcells(patterngtin13[pat1,digits[int1]]); + end; + cellindex:= 50; + for int1:= 6 to 11 do begin + putcells(patterngtin13[pgt13_r,digits[int1]]); + end; + end; + end; +end; + +procedure tcustombarcode1.setkind(const avalue: barcodekindty); +begin + if fkind <> avalue then begin + fkind:= avalue; + change(true); + end; +end; + +procedure tcustombarcode1.checkvalue; +var + int1,int2,int3: integer; + by1: byte; + po1: pmsechar; + mch1: msechar; +begin + inherited; + if fcode <> '' then begin + case fkind of + bk_gtin_13,bk_gtin_8: begin + int2:= length(fcode); + setlength(fcode,13); //unique instance + po1:= pointer(fcode); + for int1:= 0 to int2-1 do begin + mch1:= (po1+int1)^; + if (mch1 < '0') or (mch1 > '9') then begin + (po1+int1)^:= '0'; + end; + end; + if int2 < 13 then begin + move(po1^,(po1+13-int2)^,int2*sizeof(msechar)); + for int1:= 0 to 12-int2 do begin + (po1+int1)^:= '0'; + end; + end; + if bco_calcchecksum in foptions then begin + int2:= 0; + int3:= 0; + for int1:= 12 downto 1 do begin + if odd(int1) then begin + int2:= int2 + ord((po1+int1)^) - ord('0'); //*1 + end + else begin + int3:= int3 + ord((po1+int1)^) - ord('0'); //*3 + end; + end; + by1:= (3*int3+int2) mod 10; + if by1 <> 0 then begin + by1:= (10-by1) mod 10; //controllsum + end; + move((po1+1)^,po1^,12*sizeof(msechar)); + (po1+12)^:= msechar(by1+ord('0')); + end; + end; + end; + end; +end; + +procedure tcustombarcode1.updatelayout(const asize: sizety); +var + cellsize1: real; + charwidth1: real; + framesize1: integer; + int1: integer; +begin + fcellcount:= cellcounts[fkind]; + if fcellcount > 0 then begin + framesize1:= framesizes[fkind]; + cellsize1:= asize.cx / (fcellcount+framesize1); + charwidth1:= charwidths[fkind]*cellsize1; + with fbarrect1 do begin //center barrect + cx:= round(fcellcount*cellsize1); + x:= (asize.cx-cx) div 2; + end; + fbarrect2:= fbarrect1; + if ffontbar.height = 0 then begin + ffontheight:= round(charwidth1*1.5); + end + else begin + ffontheight:= ffontbar.height; + end; + fbarrect2.cy:= fbarrect2.cy - round(ffontheight*1.2); + + case fkind of + bk_gtin_13,bk_gtin_8: begin + with frect1 do begin + int1:= round(charwidth1); + x:= fbarrect1.x - int1; + y:= asize.cy - ffontheight; + cx:= int1; + cy:= ffontheight; + end; + with frect2 do begin + y:= frect1.y; + cy:= frect1.cy; + x:= fbarrect1.x + round(3*cellsize1); + int1:= 6; + if fkind = bk_gtin_8 then begin + int1:= 4; + end; + cx:= round(int1*charwidth1); + end; + frect3:= frect2; + with frect3 do begin + x:= fbarrect1.x + round((3+int1*7+5)*cellsize1); + end; + adjustrect(frect1); + adjustrect(frect2); + adjustrect(frect3); + end; + end; + end; +end; + +procedure tcustombarcode1.dopaint2(const acanvas: tcanvas); +begin + inherited; + if fcode <> '' then begin + case fkind of + bk_gtin_13: begin + drawtext(acanvas,fcode[1],frect1,ffontheight); + drawtext(acanvas,copy(fcode,2,6),frect2,ffontheight); + drawtext(acanvas,copy(fcode,8,6),frect3,ffontheight); + end; + bk_gtin_8: begin + drawtext(acanvas,copy(fcode,6,4),frect2,ffontheight); + drawtext(acanvas,copy(fcode,10,4),frect3,ffontheight); + end; + end; + end; +end; + +{ tbarcodefont } + +constructor tbarcodefont.create(const aowner: tcustombarcode); +begin + fowner:= aowner; + inherited create; +end; + +procedure tbarcodefont.dochanged(const changed: canvasstatesty; + const nochange: boolean); +begin + inherited; + if not nochange and not(bcs_painting in fowner.fstate) then begin + fowner.change(cs_font in changed); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/msechart.pas b/mseide-msegui/lib/common/widgets/msechart.pas new file mode 100644 index 0000000..ee54737 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msechart.pas @@ -0,0 +1,4637 @@ +{ MSEgui Copyright (c) 2007-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msechart; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,msegui,mseguiglob,mseclasses,msearrayprops,msetypes, + msegraphics,msegraphutils,mseglob,msereal, + msewidgets,msesimplewidgets,msedial,msebitmap,msemenus,mseevent, + msedatalist,msestatfile,msestat,msestrings; + +type + optionchartty = (oca_autofitleft,oca_autofittop,oca_autofitright, + oca_autofitbottom); //same layout as rectsidesty + optionschartty = set of optionchartty; +const + allrectsides = [rs_left,rs_top,rs_right,rs_bottom]; + rectsidesmask = [oca_autofitleft,oca_autofittop,oca_autofitright, + oca_autofitbottom]; + defaultoptionschart = [oca_autofitleft,oca_autofittop,oca_autofitright, + oca_autofitbottom]; +type + chartstatety = (chs_nocolorchart,chs_hasdialscroll,chs_hasdialshift, + chs_started,chs_full,chs_chartvalid, //for tchartrecorder + chs_layoutvalid); + chartstatesty = set of chartstatety; + charttraceoptionty = (cto_invisible,cto_smooth,cto_stockglyphs,cto_adddataright, + cto_xordered, //optimize for big data quantity + cto_logx,cto_logy,cto_seriescentered, + cto_savexscale,cto_saveyscale + ); + charttraceoptionsty = set of charttraceoptionty; + tracelegendplacementty = (tlp_none,tlp_xy,tlp_above,tlp_below); + +const + chartrecorderstatesmask = [chs_hasdialscroll,chs_hasdialshift,chs_started, + chs_full,chs_chartvalid]; + defaultxytraceoptions = [cto_xordered]; + defaultlegenddist = 1; + defaultlegendplacement = tlp_xy; + +type + tcustomchart = class; + tracestatety = (trs_datapointsvalid,trs_ownsxdatalist,trs_ownsydatalist); + tracestatesty = set of tracestatety; + tracekindty = (trk_xseries,trk_xy); + tracechartkindty = (tck_line,tck_bar); + tracechartkindsty = set of tracechartkindty; + + xseriesdataty = record + value: real; + index: integer; + end; + + datapointty = record + first,min,max,last: integer; + used: boolean; + end; + datapointarty = array of datapointty; + + barrefty = (br_zero,br_top,br_bottom); + + ttracefont = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + traceinfoty = record + xdata: realarty; + ydata: realarty; + xydata: complexarty; + xdatalist: trealdatalist; + ydatalist: trealdatalist; + state: tracestatesty; + datapoints: pointarty; + barlines: segmentarty; + bottommargin,topmargin: integer; + color: colorty; + colorimage: colorty; + xserrange: real; + xserstart: real; + xrange: real; + xstart: real; + yrange: real; + ystart: real; + kind: tracekindty; + maxcount: integer; + widthmm: real; + dashes: string; + legend: msestring; + legendrect: rectty; + font: ttracefont; + options: charttraceoptionsty; + chartkind: tracechartkindty; + bar_offset: integer; + bar_width: integer; + bar_frame: tframe; + bar_face: tface; + bar_ref: barrefty; + start: integer; + imagenr: imagenrty; + name: string; + end; + + ttraces = class; + + tbarframe = class(tframe) + public + constructor create(const aintf: iframe); + end; + ttrace = class; + + ttracedatalist = class(trealdatalist) + private + fowner: ttrace; + procedure readdummy(reader: treader); + procedure writedummy(writer: twriter); + protected + procedure dochange; override; + procedure defineproperties(filer: tfiler); override; + public + constructor create(const aowner: ttrace); reintroduce; + property defaultzero default true; + end; + + ttrace = class(townedeventpersistent,iimagelistinfo,iframe,iface) + private + finfo: traceinfoty; + fbreaks: integerarty; + fbmp2: tmaskedbitmap; + fco1: colorty; + fimli1: timagelist; + frect1: rectty; + fimagealignment: alignmentsty; + fhint_captionx: msestring; + fhint_captiony: msestring; + procedure setxydata(const avalue: complexarty); + procedure datachange; + procedure legendchange; + procedure setcolor(const avalue: colorty); + procedure setcolorimage(const avalue: colorty); + procedure setxserrange(const avalue: real); + procedure setxserstart(const avalue: real); + procedure setxrange(const avalue: real); + procedure setxstart(const avalue: real); + procedure setyrange(const avalue: real); + procedure setystart(const avalue: real); + procedure scaleerror; + procedure setxdata(const avalue: realarty); + procedure setydata(const avalue: realarty); + procedure setmaxcount(const avalue: integer); + procedure setwidthmm(const avalue: real); + procedure setdashes(const avalue: string); + procedure readxseriescount(reader: treader); + procedure readxscale(reader: treader); + procedure readxoffset(reader: treader); + procedure readyscale(reader: treader); + procedure readyoffset(reader: treader); + procedure setstart(const avalue: integer); + function getxdatalist: trealdatalist; + procedure setxdatalist(const avalue: trealdatalist); + function getydatalist: trealdatalist; + procedure setydatalist(const avalue: trealdatalist); + procedure setimagenr(const avalue: imagenrty); + function getimagelist: timagelist; + function getlogx: boolean; + procedure setlogx(const avalue: boolean); + function getlogy: boolean; + procedure setlogy(const avalue: boolean); + function getvisible: boolean; + procedure setvisible(const avalue: boolean); + function getxdatapo: preal; + function getydatapo: preal; + function getxydatapo: pcomplexty; + function getcount: integer; + function getxvalue(const index: integer): real; + procedure setxvalue(const index: integer; const avalue: real); + function getyvalue(const index: integer): real; + procedure setyvalue(const index: integer; const avalue: real); + function getxyvalue(const index: integer): complexty; + procedure setxyvalue(const index: integer; const avalue: complexty); + procedure setchartkind(const avalue: tracechartkindty); + procedure setbar_offset(const avalue: integer); + procedure setbar_width(const avalue: integer); + function getbar_frame: tframe; + procedure setbar_frame(const avalue: tframe); + function getbar_face: tface; + procedure setbar_face(const avalue: tface); + procedure setbar_ref(const avalue: barrefty); + procedure setbreaks(const avalue: integerarty); + function getlegend_font: ttracefont; + procedure setlegend_font(const avalue: ttracefont); + procedure setlegend_caption(const avalue: msestring); + function isfontstored: boolean; + procedure fontchanged(const sender: tobject); + function getsmooth: boolean; + procedure setsmooth(const avalue: boolean); + protected + fstate: tracestatesty; + ftraces: ttraces; + fcurfont: tfont; + flnxstart: real; + flnxrange: real; + flnystart: real; + flnyrange: real; + procedure setkind(const avalue: tracekindty); virtual; + procedure setoptions(const avalue: charttraceoptionsty); virtual; + function getxitempo(const aindex: integer): preal; + function getyitempo(const aindex: integer): preal; + procedure getdatapo(out xpo,ypo: preal; //xpo nil for xseries + out xcount,ycount,xstep,ystep: integer); + + procedure checkgraphic; + procedure clip2(const acanvas: tcanvas); + procedure paint(const acanvas: tcanvas); + procedure paint1(const acanvas: tcanvas; const imagesize: sizety; + const imagealignment: alignmentsty); + procedure paint2(const acanvas: tcanvas); + procedure defineproperties(filer: tfiler); override; + function hintx: msestring; + function hinty: msestring; + //iframe + procedure setframeinstance(instance: tcustomframe); + procedure setstaticframe(value: boolean); + function getstaticframe: boolean; + procedure scrollwidgets(const dist: pointty); + procedure clientrectchanged; + function getcomponentstate: tcomponentstate; + function getmsecomponentstate: msecomponentstatesty; + procedure invalidate; + procedure invalidatewidget; + procedure invalidaterect(const rect: rectty; + const org: originty = org_client; const noclip: boolean = false); + function getwidget: twidget; + function getwidgetrect: rectty; + function getframestateflags: framestateflagsty; + //iface + function translatecolor(const acolor: colorty): colorty; + function getclientrect: rectty; + procedure setlinkedvar(const source: tmsecomponent; var dest: tmsecomponent; + const linkintf: iobjectlink = nil); + procedure widgetregioninvalid; + procedure forcexyarray; + public + constructor create(aowner: tobject); override; + destructor destroy; override; + procedure createbar_frame; + procedure createbar_face; + procedure createfont; + + procedure clear; + procedure deletedata(const aindex: integer); overload; + procedure deletedata(const aindexar: integerarty); overload; + procedure addxydata(const xy: complexty); overload; + procedure addxydata(const x: real; const y: real); overload; + procedure addxseriesdata(const avalue: real); + procedure insertxseriesdata(const avalue: xseriesdataty); + procedure assign(source: tpersistent); override; + procedure minmaxx(out amin,amax: real); + procedure minmaxx1(var amin,amax: real); //extend + procedure minmaxy(out amin,amax: real); + procedure minmaxy1(var amin,amax: real); //extend + procedure autoscalex(const astartmargin: real = 0; + const aendmargin: real = 0); + procedure autoscaley(const astartmargin: real = 0; + const aendmargin: real = 0); + + property xdata: realarty read finfo.xdata write setxdata; + property ydata: realarty read finfo.ydata write setydata; + property xydata: complexarty read finfo.xydata write setxydata; + property breaks: integerarty read fbreaks write setbreaks; + //for xy without cto_xordered only + + property xvalue[const index: integer]: real read getxvalue write setxvalue; + property yvalue[const index: integer]: real read getyvalue write setyvalue; + property xyvalue[const index: integer]: complexty read getxyvalue + write setxyvalue; + property xdatapo: preal read getxdatapo; + property ydatapo: preal read getydatapo; + property xydatapo: pcomplexty read getxydatapo; + property count: integer read getcount; + + property logx: boolean read getlogx write setlogx; + property logy: boolean read getlogy write setlogy; + property visible: boolean read getvisible write setvisible; + property smooth: boolean read getsmooth write setsmooth; + + published + property xdatalist: trealdatalist read getxdatalist write setxdatalist; + property ydatalist: trealdatalist read getydatalist write setydatalist; + property color: colorty read finfo.color write setcolor default cl_black; + property colorimage: colorty read finfo.colorimage + write setcolorimage default cl_default; + property widthmm: real read finfo.widthmm write setwidthmm; //default 0.3 + property dashes: string read finfo.dashes write setdashes; + property xserrange: real read finfo.xserrange write setxserrange; + //default 1.0 + property xserstart: real read finfo.xserstart write setxserstart; + property xrange: real read finfo.xrange write setxrange; //default 1.0 + property xstart: real read finfo.xstart write setxstart; + property yrange: real read finfo.yrange write setyrange; //default 1.0 + property ystart: real read finfo.ystart write setystart; + property kind: tracekindty read finfo.kind write setkind default trk_xseries; + property start: integer read finfo.start write setstart default 0; + property maxcount: integer read finfo.maxcount write setmaxcount default 0; + //0-> data count + property chartkind: tracechartkindty read finfo.chartkind write setchartkind + default tck_line; + property options: charttraceoptionsty read finfo.options + write setoptions default []; + property bar_offset: integer read finfo.bar_offset + write setbar_offset default 0; + property bar_width: integer read finfo.bar_width + write setbar_width default 0; //0 -> bar line + property bar_frame: tframe read getbar_frame write setbar_frame; + property bar_face: tface read getbar_face write setbar_face; + property bar_ref: barrefty read finfo.bar_ref write setbar_ref default br_zero; + + property imagenr: imagenrty read finfo.imagenr write setimagenr default -1; + property name: string read finfo.name write finfo.name; + property legend_caption: msestring read finfo.legend write setlegend_caption; + property legend_font: ttracefont read getlegend_font + write setlegend_font stored isfontstored; + property hint_captionx: msestring read fhint_captionx + write fhint_captionx; + property hint_captiony: msestring read fhint_captiony + write fhint_captiony; + end; + + traceaty = array[0..0] of ttrace; + ptraceaty = ^traceaty; + + tracesstatety = (trss_graphicvalid); + tracesstatesty = set of tracesstatety; + + ttracesfont = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + ttraces = class(townedeventpersistentarrayprop) + private + ftracestate: tracesstatesty; + fxserstart: real; + fxstart: real; + fystart: real; + fxserrange: real; + fxrange: real; + fyrange: real; + fmaxcount: integer; + fimage_list: timagelist; + fimage_widthmm: real; + fimage_heightmm: real; + foptions: charttraceoptionsty; + fkind: tracekindty; + fchartkind: tracechartkindty; + fbar_width: integer; + fbar_ref: barrefty; + ffont: ttracesfont; + flegend_pos: complexty; + flegend_dist: integer; + flegend_placement: tracelegendplacementty; + flegend_fitdist: integer; + fstart: integer; + procedure setitems(const index: integer; const avalue: ttrace); + function getitems(const index: integer): ttrace; + procedure setxserstart(const avalue: real); + procedure setxstart(const avalue: real); + procedure setystart(const avalue: real); + procedure setxserrange(const avalue: real); + procedure setxrange(const avalue: real); + procedure setyrange(const avalue: real); + procedure setstart(const avalue: integer); + procedure setmaxcount(const avalue: integer); + procedure setimage_list(const avalue: timagelist); + procedure setimage_widthmm(const avalue: real); + procedure setimage_heightmm(const avalue: real); + function getlogx: boolean; + procedure setlogx(const avalue: boolean); + function getlogy: boolean; + procedure setlogy(const avalue: boolean); + procedure setchartkind(const avalue: tracechartkindty); + procedure setbar_width(const avalue: integer); + procedure setbar_ref(const avalue: barrefty); + function getfont: ttracesfont; + procedure setfont(const avalue: ttracesfont); + function isfontstored: boolean; + procedure fontchanged(const sender: tobject); + procedure setlegend_pos(const avalue: complexty); + procedure setlegend_x(const avalue: real); + procedure setlegend_y(const avalue: real); + procedure setlegend_dist(const avalue: integer); + procedure setlegend_placement(const avalue: tracelegendplacementty); + procedure setlegend_fitdist(const avalue: integer); + protected + fsize: sizety; + fscalex: real; + fscaley: real; + flegendsize: sizety; + procedure setkind(const avalue: tracekindty); virtual; + procedure setoptions(const avalue: charttraceoptionsty); virtual; + procedure change; reintroduce; + procedure layoutchanged; + procedure clientrectchanged; + procedure clipoverlay(const acanvas: tcanvas); + procedure paint(const acanvas: tcanvas); + procedure paintoverlay(const acanvas: tcanvas); + procedure calclegendrect; + procedure checkgraphic; + procedure createitem(const index: integer; var item: tpersistent); override; + public + constructor create(const aowner: tcustomchart); reintroduce; + destructor destroy; override; + class function getitemclasstype: persistentclassty; override; + procedure createfont; + function itembyname(const aname: string): ttrace; + function actualimagelist: timagelist; + procedure assign(source: tpersistent); override; + procedure dostatread(const reader: tstatreader); + procedure dostatwrite(const writer: tstatwriter); + procedure setdata(const adata: realararty); overload; + procedure setdata(const adata: complexararty); overload; + property logx: boolean read getlogx write setlogx; + property logy: boolean read getlogy write setlogy; + property items[const index: integer]: ttrace read getitems + write setitems; default; + property legend_pos: complexty read flegend_pos write setlegend_pos; + published + property kind: tracekindty read fkind write setkind default trk_xseries; + property chartkind: tracechartkindty read fchartkind + write setchartkind default tck_line; + property options: charttraceoptionsty read foptions + write setoptions default []; + //item default values + property xserstart: real read fxserstart write setxserstart; + property xstart: real read fxstart write setxstart; + property ystart: real read fystart write setystart; + property xrange: real read fxrange write setxrange; + property xserrange: real read fxserrange write setxserrange; + property yrange: real read fyrange write setyrange; + property start: integer read fstart write setstart default 0; + property maxcount: integer read fmaxcount write setmaxcount default 0; + //properties not used in asssign below + property image_list: timagelist read fimage_list write setimage_list; + property image_widthmm: real read fimage_widthmm write setimage_widthmm; + property image_heighthmm: real read fimage_heightmm write setimage_heightmm; + property bar_width: integer read fbar_width + write setbar_width default 0; //0 -> bar line + property bar_ref: barrefty read fbar_ref write setbar_ref default br_zero; + property font: ttracesfont read getfont write setfont stored isfontstored; + property legend_x: real read flegend_pos.re write setlegend_x; + property legend_y: real read flegend_pos.im write setlegend_y; + property legend_dist: integer read flegend_dist write setlegend_dist default + defaultlegenddist; + property legend_fitdist: integer read flegend_fitdist + write setlegend_fitdist default defaultlegenddist; + property legend_placement: tracelegendplacementty read flegend_placement + write setlegend_placement default tlp_xy; + end; + + txytrace = class(ttrace) + protected + procedure setkind(const avalue: tracekindty); override; + procedure setoptions(const avalue: charttraceoptionsty); override; + public + constructor create(aowner: tobject); override; + published + property kind default trk_xy; + property options default defaultxytraceoptions; + end; + + txytraces = class(ttraces) + protected + fxordered: boolean; + procedure setkind(const avalue: tracekindty); override; + procedure setoptions(const avalue: charttraceoptionsty); override; + public + constructor create(const aowner: tcustomchart; const axordered: boolean); + class function getitemclasstype: persistentclassty; override; + published + property kind default trk_xy; + property options default defaultxytraceoptions; + end; + + ichartdialcontroller = interface(idialcontroller) + function getxstart: real; + function getystart: real; + function getxrange: real; + function getyrange: real; + end; + + tchartdialvert = class(tcustomdialcontroller) + protected + procedure setdirection(const avalue: graphicdirectionty); override; + public + constructor create(const aintf: idialcontroller); override; + published + property options; //first! + property color; + property widthmm; + property direction default gd_up; + property indent1; + property indent2; + property fitdist; + property start; + property range; + property kind; + property markers; + property ticks; + end; + + tchartdialhorz = class(tcustomdialcontroller) + protected + procedure setdirection(const avalue: graphicdirectionty); override; + public + constructor create(const aintf: idialcontroller); override; + published + property options; //first! + property color; + property widthmm; + property direction default gd_right; + property indent1; + property indent2; + property fitdist; + property start; + property range; + property kind; + property markers; + property ticks; + end; + + tchartdials = class(tcustomdialcontrollers) + private + function getitems(const aindex: integer): tcustomdialcontroller; + procedure setitems(const aindex: integer; + const avalue: tcustomdialcontroller); + protected + public + constructor create(const aintf: ichartdialcontroller); + procedure changed; + procedure paint(const acanvas: tcanvas); + procedure afterpaint(const acanvas: tcanvas); + property items[const aindex: integer]: tcustomdialcontroller read getitems + write setitems; default; + end; + + tchartdialshorz = class(tchartdials) + private + function getitems(const aindex: integer): tchartdialhorz; + procedure setitems(const aindex: integer; const avalue: tchartdialhorz); + protected + function getitemclass: dialcontrollerclassty; override; + procedure createitem(const index: integer; var item: tpersistent); override; + public + class function getitemclasstype: persistentclassty; override; + property items[const aindex: integer]: tchartdialhorz read getitems write setitems; default; + end; + + tchartdialsvert = class(tchartdials) + private + function getitems(const aindex: integer): tchartdialvert; + procedure setitems(const aindex: integer; const avalue: tchartdialvert); + protected + function getitemclass: dialcontrollerclassty; override; + procedure createitem(const index: integer; var item: tpersistent); override; + public + class function getitemclasstype: persistentclassty; override; + property items[const aindex: integer]: tchartdialvert read getitems + write setitems; default; + end; + + tchartframe = class(tscrollboxframe) + protected + function actualcolorclient(): colorty override; + public + constructor create(const aintf: iscrollframe; const owner: twidget); + published + property framei_left default 0; + property framei_top default 0; + property framei_right default 1; + property framei_bottom default 1; + property colorclient {default cl_foreground}; + end; + +const + defaultchartoptionswidget = defaultscrollboxoptionswidget - + [ow_mousefocus,ow_tabfocus,ow_arrowfocus]; +type + tcuchart = class(tscrollbox,ichartdialcontroller,istatfile,iframe) + private + fxdials: tchartdialshorz; + fydials: tchartdialsvert; + fxstart: real; + fystart: real; + fxrange: real; + fyrange: real; + fstatfile: tstatfile; + fstatvarname: msestring; + foptionschart: optionschartty; + ffitframe: framety; + fstatpriority: integer; + procedure setxdials(const avalue: tchartdialshorz); + procedure setydials(const avalue: tchartdialsvert); + procedure setcolorchart(const avalue: colorty); + function getxstart: real; + procedure setxstart(const avalue: real); virtual; + function getystart: real; + procedure setystart(const avalue: real); virtual; + function getxrange: real; + procedure setxrange(const avalue: real); virtual; + function getyrange: real; + procedure setyrange(const avalue: real); virtual; + procedure setstatfile(const avalue: tstatfile); + procedure setoptionschart(const avalue: optionschartty); + procedure setfitframe(const avalue: framety); + procedure setfitframe_left(const avalue: integer); + procedure setfitframe_top(const avalue: integer); + procedure setfitframe_right(const avalue: integer); + procedure setfitframe_bottom(const avalue: integer); + function getfacechart: tface; + procedure setfacechart(const avalue: tface); + function getframechart: tframe; + procedure setframechart(const avalue: tframe); + protected + fcolorchart: colorty; + ffacechart: tface; + fframechart: tframe; + fstate: chartstatesty; + fshiftsum: int64; + fscrollsum: integer; + fsampleco: integer; + fchartframerect: rectty; + procedure fontchanged; override; + function checklayout: boolean; virtual; //true if changes made + function actualcolorchart(): colorty; + procedure changed; virtual; + procedure layoutchanged; virtual; + procedure chartchange; + procedure invalidatelayout; + procedure clientrectchanged; override; + procedure dopaintbackground(const canvas: tcanvas); override; + procedure doclipcontent1(const acanvas: tcanvas); virtual; + procedure dopaintcontent(const acanvas: tcanvas); virtual; + procedure dopaintcontent1(const acanvas: tcanvas); virtual; + procedure dopaintforeground(const acanvas: tcanvas); override; + //iscrollframe + function getzoomrefframe: framety; override; + //idialcontroller + procedure directionchanged(const dir,dirbefore: graphicdirectionty); + function getdialrect: rectty; + function getlimitrect: rectty; + procedure internalcreateframe; override; + procedure defineproperties(filer: tfiler); override; + //istatfile + procedure dostatread(const reader: tstatreader); virtual; + procedure dostatwrite(const writer: tstatwriter); virtual; + procedure statreading; virtual; + procedure statread; virtual; + function getstatvarname: msestring; + function getstatpriority: integer; + procedure initscrollstate; + procedure extendfit(const asides: rectsidesty; var aext: rectextty); virtual; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure paint(const acanvas: tcanvas); override; + procedure createfacechart; + procedure createframechart; + function fit(const asides: rectsidesty = allrectsides): boolean; + //adjust fitframe for extents of dials + //returns true if changes made + + property optionschart: optionschartty read foptionschart + write setoptionschart default defaultoptionschart; + property colorchart: colorty read fcolorchart write setcolorchart + default cl_default; + property facechart: tface read getfacechart write setfacechart; + property framechart: tframe read getframechart write setframechart; + property xstart: real read getxstart write setxstart; + property ystart: real read getystart write setystart; + property xrange: real read getxrange write setxrange; //default 1 + property yrange: real read getyrange write setyrange; //default 1 + + property xdials: tchartdialshorz read fxdials write setxdials; + property ydials: tchartdialsvert read fydials write setydials; + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read getstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + property fitframe: framety read ffitframe write setfitframe; + property fitframe_left: integer read ffitframe.left + write setfitframe_left default 0; + property fitframe_top: integer read ffitframe.top + write setfitframe_top default 0; + property fitframe_right: integer read ffitframe.right + write setfitframe_right default 0; + property fitframe_bottom: integer read ffitframe.bottom + write setfitframe_bottom default 0; + published + property optionswidget default defaultchartoptionswidget; + end; + + tcustomchart = class(tcuchart) + private + ftracehint_captionx: msestring; + ftracehint_captiony: msestring; + fmarkerhintcaption: msestring; + procedure settraces(const avalue: ttraces); + procedure setxstart(const avalue: real); override; + procedure setystart(const avalue: real); override; + procedure setxrange(const avalue: real); override; + procedure setyrange(const avalue: real); override; + protected + ftraces: ttraces; + procedure clientrectchanged; override; + procedure doclipcontent1(const acanvas: tcanvas); override; + procedure dopaintcontent(const acanvas: tcanvas); override; + procedure dopaintcontent1(const acanvas: tcanvas); override; + procedure dostatread(const reader: tstatreader); override; + procedure dostatwrite(const writer: tstatwriter); override; + procedure layoutchanged; override; + procedure extendfit(const asides: rectsidesty; var aext: rectextty); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure clear; virtual; + procedure autoscalex(const astartmargin: real = 0; + const aendmargin: real = 0); + procedure autoscaley(const astartmargin: real = 0; + const aendmargin: real = 0); + procedure addsample(const asamples: array of real); virtual; + property traces: ttraces read ftraces write settraces; + property tracehint_captionx: msestring read ftracehint_captionx + write ftracehint_captionx; + property tracehint_captiony: msestring read ftracehint_captiony + write ftracehint_captiony; + property markerhintcaption: msestring read fmarkerhintcaption + write fmarkerhintcaption; + end; + + tchart = class(tcustomchart) + published + property optionschart; + property traces; + property colorchart; + property facechart; + property framechart; + property xstart; + property ystart; + property xrange; + property yrange; + property xdials; + property ydials; + property fitframe_left; + property fitframe_top; + property fitframe_right; + property fitframe_bottom; + property statfile; + property statvarname; + property statpriority; + property onbeforepaint; + property onpaintbackground; + property onpaint; + property onafterpaint; + end; + + trecordertrace = class(tvirtualpersistent) + private + fybefore: integer; + fstart: real; + frange: real; + fcolor: colorty; + fwidth: integer; + procedure setrange(const avalue: real); + public + constructor create; override; + published + property start: real read fstart write fstart; + property range: real read frange write setrange; + property color: colorty read fcolor write fcolor default cl_glyph; + property width: integer read fwidth write fwidth default 0; + end; + + trecordertraces = class(tpersistentarrayprop) + public + constructor create; + class function getitemclasstype: persistentclassty; override; + end; + + chartrecorderoptionty = (cro_adddataright); + chartrecorderoptionsty = set of chartrecorderoptionty; + + tchartrecorder = class(tcuchart) + private + fchart: tmaskedbitmap; + fsamplecount: integer; + fstep: real; + fstepsum: real; + fchartrect: rectty; + fchartclientrect: rectty; + fchartwindowrect: rectty; + fxref: integer; + ftraces: trecordertraces; + foptions: chartrecorderoptionsty; + procedure setsamplecount(const avalue: integer); + procedure settraces(const avalue: trecordertraces); + protected + procedure checkinit; + procedure dopaintcontent(const acanvas: tcanvas); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure addsample(const asamples: array of real); + procedure clear; + published + property options: chartrecorderoptionsty read foptions write foptions + default []; + property samplecount: integer read fsamplecount write setsamplecount + default 100; + property traces: trecordertraces read ftraces write settraces; + + property optionschart; + property colorchart; + property facechart; + property framechart; + property xstart; + property ystart; + property xrange; + property yrange; + property xdials; + property ydials; + property fitframe_left; + property fitframe_top; + property fitframe_right; + property fitframe_bottom; + property statfile; + property statvarname; + property statpriority; + property onbeforepaint; + property onpaintbackground; + property onpaint; + property onafterpaint; + end; + +function autointerval(const arange: real; const aintervalcount: real): real; + //returns apropropriate 1/2/5 value +function calctracerange(var min: real; const max: real; const log: boolean; + const startmargin: real = 0; const endmargin: real = 0): real; +function makexseriesdata(const value: real; const index: integer): xseriesdataty; + +implementation +uses + sysutils,math,msebits,rtlconsts,msestockobjects,msearrayutils,mseformatstr; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tcustomdialcontroller1 = class(tcustomdialcontroller); + tdialticks1 = class(tdialticks); + tdialmarkers1 = class(tdialmarkers); + tcustomframe1 = class(tcustomframe); + +function makexseriesdata(const value: real; const index: integer): xseriesdataty; +begin + result.value:= value; + result.index:= index; +end; + +function autointerval(const arange: real; const aintervalcount: real): real; + //returns apropropriate 1/2/5 value +var + rea1: real; + rea2: real; + int1: integer; + scale: real; +begin + rea1:= abs(arange/aintervalcount); + if rea1 < 1e-99 then begin + rea1:= 1e-99; + end; + int1:= ceil(log10(rea1)); + scale:= intpower(10,int1-1); + rea2:= 0.9*rea1/scale; //1..10, 10% overrange + if rea2 < 1 then begin + rea2:= 1; + end + else begin + if rea2 < 2 then begin + rea2:= 2; + end + else begin + if rea2 < 5 then begin + rea2:= 5; + end + else begin + rea2:= 10; + end; + end; + end; + result:= rea2 * scale; + if arange < 0 then begin + result:= -result; + end; +end; + +{ ttracefont } + +class function ttracefont.getinstancepo(owner: tobject): pfont; +begin + result:= @ttrace(owner).finfo.font; +end; + +{ ttracedatalist } + +constructor ttracedatalist.create(const aowner: ttrace); +begin + fowner:= aowner; + inherited create; + defaultzero:= true; + min:= -bigreal; +end; + +procedure ttracedatalist.dochange; +begin + fowner.datachange; + inherited; +end; + +procedure ttracedatalist.readdummy(reader: treader); +begin + reader.readinteger; +end; + +procedure ttracedatalist.writedummy(writer: twriter); +begin + writer.writeinteger(0); +end; + +procedure ttracedatalist.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('dummy',{$ifdef FPC}@{$endif}readdummy, + {$ifdef FPC}@{$endif}writedummy,(filer.ancestor = nil)and (count = 0)); + //in order to create optional instance +end; + +{ ttrace } + +constructor ttrace.create(aowner: tobject); +begin + ftraces:= tcustomchart(aowner).ftraces; + finfo.color:= cl_black; + finfo.colorimage:= cl_default; + finfo.widthmm:= 0.3; + finfo.xserrange:= 1.0; + finfo.xrange:= 1.0; + finfo.yrange:= 1.0; + finfo.imagenr:= -1; + inherited; +end; + +destructor ttrace.destroy; +begin + xdatalist:= nil; + ydatalist:= nil; + inherited; + finfo.bar_frame.free; + finfo.bar_face.free; + finfo.font.free; + fbmp2.free; +end; + +procedure ttrace.datachange; +begin + exclude(finfo.state,trs_datapointsvalid); + tcustomchart(fowner).traces.change; +end; + +procedure ttrace.legendchange; +begin + with tcustomchart(fowner).traces do begin + if legend_placement in [tlp_above,tlp_below] then begin + layoutchanged; + end + else begin + change; + end; + end; +end; + +procedure ttrace.setxydata(const avalue: complexarty); +begin + xdatalist:= nil; + ydatalist:= nil; + finfo.xdata:= nil; + finfo.ydata:= nil; + finfo.xydata:= avalue; + datachange; +end; + +procedure ttrace.setbreaks(const avalue: integerarty); +begin + fbreaks:= avalue; + tcustomchart(fowner).traces.change; +end; + +procedure ttrace.setxdata(const avalue: realarty); +begin + xdatalist:= nil; + finfo.xydata:= nil; + finfo.xdata:= avalue; + datachange; +end; + +procedure ttrace.setydata(const avalue: realarty); +begin + ydatalist:= nil; + finfo.xydata:= nil; + finfo.ydata:= avalue; + datachange; +end; + +procedure ttrace.setxdatalist(const avalue: trealdatalist); +begin + finfo.xdata:= nil; + finfo.xydata:= nil; + if csdesigning in tcustomchart(fowner).componentstate then begin + if avalue = nil then begin + freeandnil(finfo.xdatalist); + exclude(fstate,trs_ownsxdatalist); + end + else begin + if finfo.xdatalist = nil then begin + finfo.xdatalist:= ttracedatalist.create(self); + include(finfo.state,trs_ownsxdatalist); + end; + if (ptruint(pointer(avalue)) <> 1) then begin + finfo.xdatalist.assign(avalue); + end; + end; + end + else begin + if trs_ownsxdatalist in fstate then begin + finfo.xdatalist.free; + exclude(fstate,trs_ownsxdatalist); + end; + finfo.xdatalist:= avalue; + end; + datachange; +end; + +procedure ttrace.setydatalist(const avalue: trealdatalist); +begin + finfo.ydata:= nil; + finfo.xydata:= nil; + if csdesigning in tcustomchart(fowner).componentstate then begin + if avalue = nil then begin + freeandnil(finfo.ydatalist); + exclude(fstate,trs_ownsydatalist); + end + else begin + if finfo.ydatalist = nil then begin + finfo.ydatalist:= ttracedatalist.create(self); + include(finfo.state,trs_ownsydatalist); + end; + if (ptruint(pointer(avalue)) <> 1) then begin + finfo.ydatalist.assign(avalue); + end; + end; + end + else begin + if trs_ownsydatalist in fstate then begin + finfo.ydatalist.free; + exclude(fstate,trs_ownsydatalist); + end; + finfo.ydatalist:= avalue; + end; + datachange; +end; + +procedure ttrace.forcexyarray; +var + ar1: complexarty; +begin + with finfo do begin + ar1:= xydata; + if ar1 = nil then begin + if xdatalist <> nil then begin + xdatalist.assigntore(ar1); + end; + if ydatalist <> nil then begin + ydatalist.assigntoim(ar1); + end; + if xdata <> nil then begin + copytore(xdata,ar1); + end; + if ydata <> nil then begin + copytoim(ydata,ar1); + end; + end; + if ar1 <> xydata then begin + self.xydata:= ar1; + end; + end; +end; + +function ttrace.getxdatalist: trealdatalist; +begin + if (finfo.xdatalist = nil) and + (csreading in tcustomchart(fowner).componentstate) then begin + finfo.xdatalist:= ttracedatalist.create(self); + include(finfo.state,trs_ownsxdatalist); + end; + result:= finfo.xdatalist; +end; + +function ttrace.getydatalist: trealdatalist; +begin + if (finfo.ydatalist = nil) and + (csreading in tcustomchart(fowner).componentstate) then begin + finfo.ydatalist:= ttracedatalist.create(self); + include(finfo.state,trs_ownsydatalist); + end; + result:= finfo.ydatalist; +end; + +procedure ttrace.checkgraphic; + + function pkround(const avalue: real): integer; + begin + if avalue > $3fff then begin //X11 range is 16bit + result:= $3fff; + end + else begin + if avalue < -$4000 then begin + result:= -$4000; + end + else begin + result:= round(avalue); + end; + end; + end; + +var + pox,poy: pchar; + intx,inty: integer; + + procedure checkrange(var dpcount: integer); + var + int1: integer; + begin + int1:= finfo.maxcount; + if int1 = 0 then begin + int1:= dpcount; + end; + if finfo.start + int1 > dpcount then begin + int1:= dpcount - finfo.start; + end; + if int1 < dpcount then begin + dpcount:= int1; + end; + if dpcount < 0 then begin + dpcount:= 0; + end; + pox:= pox + finfo.start * intx; + poy:= poy + finfo.start * inty; + end; + +var + int1,int2,int3,int4: integer; + xo,xs,yo,ys,lxo,lxs: real; + rea1: real; + ar1: datapointarty; + dpcountx,dpcounty,dpcountxy: integer; + xbottom,xtop: integer; + isxseries: boolean; + dpcounty1: integer; + islogx,islogy: boolean; + +begin + if not (trs_datapointsvalid in finfo.state) and visible then begin + dpcounty1:= 0; + finfo.datapoints:= nil; + include(finfo.state,trs_datapointsvalid); + dpcountx:= 0; + dpcounty:= 0; + with finfo do begin + isxseries:= (kind = trk_xseries); + islogx:= cto_logx in options; + islogy:= cto_logy in options; + bottommargin:= 0; + topmargin:= 0; + if xydata <> nil then begin + pox:= @xydata[0].re; + poy:= @xydata[0].im; + intx:= sizeof(complexty); + inty:= sizeof(complexty); + dpcountx:= length(xydata); + dpcounty:= dpcountx; + end + else begin + if xdatalist <> nil then begin + dpcountx:= xdatalist.count; + pox:= xdatalist.datapo; + intx:= finfo.xdatalist.size; + end + else begin + pox:= pointer(xdata); + intx:= sizeof(real); + dpcountx:= length(xdata); + end; + if ydatalist <> nil then begin + dpcounty:= ydatalist.count; + poy:= ydatalist.datapo; + inty:= ydatalist.size; + end + else begin + poy:= pointer(ydata); + inty:= sizeof(real); + dpcounty:= length(ydata); + end; + end; + end; + dpcountxy:= dpcountx; + if isxseries or (dpcounty < dpcountxy) then begin + dpcountxy:= dpcounty; + end; + if islogy then begin + yo:= -(chartln(finfo.ystart + finfo.yrange)); + ys:= -tcustomchart(fowner).traces.fscaley / (-chartln(finfo.ystart) - yo); + end + else begin + yo:= -finfo.ystart - finfo.yrange; + ys:= -tcustomchart(fowner).traces.fscaley / finfo.yrange; + end; + case finfo.kind of + trk_xy,trk_xseries: begin + lxo:= 0; + lxs:= 1; + if isxseries then begin + dpcounty1:= dpcounty-1; + rea1:= 0; + if maxcount > 1 then begin + int2:= maxcount - 1; + if (int2 > dpcounty1) and + (cto_adddataright in finfo.options) then begin + rea1:= {$ifdef FPC}real({$endif}1.0{$ifdef FPC}){$endif} - + dpcounty1 / int2; + end; + end + else begin + int2:= dpcounty1; + end; + if cto_logx in options then begin + lxo:= int2 * (finfo.xserstart/finfo.xserrange); + lxs:= finfo.xserrange; + xo:= -chartln(-(rea1 - finfo.xstart) * int2); + xs:= tcustomchart(fowner).traces.fscalex; + if int2 > 0 then begin + xs:= xs / (chartln((finfo.xstart+finfo.xrange) * int2)+xo); + end; + if xs <> 0 then begin + xo:= xo + 1/xs; + end; + end + else begin + xo:= (rea1 - finfo.xstart) * int2; + xs:= tcustomchart(fowner).traces.fscalex; + if int2 > 0 then begin + xs:= xs / (finfo.xrange * int2); + end; + if xs <> 0 then begin + xo:= xo + 1/xs; + end; + xo:= (finfo.xserstart*int2+xo)/(finfo.xserrange); + xs:= xs*finfo.xserrange; + end; + end + else begin + if cto_logx in options then begin + xo:= -chartln(finfo.xstart); + xs:= tcustomchart(fowner).traces.fscalex / + (chartln(finfo.xrange+finfo.xstart)+xo); + end + else begin + xo:= -finfo.xstart; + xs:= tcustomchart(fowner).traces.fscalex / finfo.xrange; + end; + end; + checkrange(dpcountxy); + if isxseries and (cto_seriescentered in finfo.options) and + (dpcounty > 0) then begin + xs:= xs*(dpcounty1/dpcounty); + xo:= xo + 0.5; + end; + + if (cto_xordered in finfo.options) or isxseries then begin + int4:= tcustomchart(fowner).traces.fsize.cx+3;//2; //cx + 1 + setlength(ar1,int4); + dec(int4); + xbottom:= minint; + xtop:= maxint; + for int1:= 0 to dpcountxy - 1 do begin + if isxseries then begin + if islogx then begin + int2:= round((chartln((int1+lxo)*lxs) + xo) * xs); + end + else begin + int2:= round((int1 + xo) * xs); + end; + end + else begin + if islogx then begin + int2:= pkround((chartln(preal(pox)^) + xo) * xs) + 1; + end + else begin + int2:= pkround((preal(pox)^ + xo) * xs) + 1; + end; + end; + if islogy then begin + int3:= pkround((chartln(preal(poy)^) + yo) * ys); + end + else begin + int3:= pkround((preal(poy)^ + yo) * ys); + end; + if int2 < 0 then begin + if int2 > xbottom then begin + xbottom:= int2; + end; + int2:= 0; + end; + if int2 > int4 then begin + if int2 < xtop then begin + xtop:= int2; + end; + int2:= int4; + end; + with ar1[int2] do begin + if not used then begin + used:= true; + first:= int3; + min:= int3; + max:= int3; + end + else begin + if int3 < min then begin + min:= int3; + end; + if int3 > max then begin + max:= int3; + end; + end; + last:= int3; + end; + if xtop <> maxint then begin + break; + end; + inc(pox,intx); + inc(poy,inty); + end; + with ar1[0] do begin //endpoints + first:= last; + min:= last; + max:= last; + end; + with ar1[high(ar1)] do begin + first:= last; + min:= last; + max:= last; + end; + setlength(finfo.datapoints,length(ar1)*4); //first->max->min->last + int2:= 0; + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + if used then begin + int3:= int1-1; + finfo.datapoints[int2].x:= int3; + finfo.datapoints[int2].y:= first; + inc(int2); + if max > first then begin + finfo.datapoints[int2].x:= int3; + finfo.datapoints[int2].y:= max; + inc(int2); + end; + if min < max then begin + finfo.datapoints[int2].x:= int3; + finfo.datapoints[int2].y:= min; + inc(int2); + end; + if last > min then begin + finfo.datapoints[int2].x:= int3; + finfo.datapoints[int2].y:= last; + inc(int2); + end; + end; + end; + end; + setlength(finfo.datapoints,int2); + if chartkind = tck_line then begin + with finfo do begin //adjust boundary values + //todo: extend window for image size + barlines:= nil; + if int2 > 1 then begin + if ar1[0].used then begin + bottommargin:= 1; + datapoints[0].y:= pkround(datapoints[0].y + + (datapoints[1].y - datapoints[0].y) * + (-1-xbottom)/ + (datapoints[1].x-xbottom)); + end; + if ar1[high(ar1)].used then begin + topmargin:= 1; + datapoints[int2-1].y:= pkround(datapoints[int2-1].y + + (datapoints[int2-2].y - datapoints[int2-1].y) * + (length(ar1)-xtop)/ + (datapoints[int2-2].x-xtop)); + end; + end; + end; + end + else begin //tck_barline + with finfo do begin + setlength(barlines,length(datapoints)); + case bar_ref of + br_top: begin + int2:= -1; + end; + br_bottom: begin + int2:= tcustomchart(fowner).traces.fsize.cy+1; + end; + else begin //br_zero + int2:= round(yo*ys); //zero position + if int2 < 0 then begin + int2:= -1; + end; + if int2 > tcustomchart(fowner).traces.fsize.cy+1 then begin + int2:= tcustomchart(fowner).traces.fsize.cy+1; + end; + end; + end; + for int1:= 0 to high(barlines) do begin + with barlines[int1] do begin + a.x:= datapoints[int1].x + bar_offset; + a.y:= datapoints[int1].y; + b.x:= a.x; + b.y:= int2; + end; + end; + end; + end; + end //xordered + else begin //xy + setlength(finfo.datapoints,dpcountxy); + for int1:= 0 to high(finfo.datapoints) do begin + if islogx then begin + finfo.datapoints[int1].x:= pkround((chartln(preal(pox)^) + xo)* xs); + end + else begin + finfo.datapoints[int1].x:= pkround((preal(pox)^ + xo)* xs); + end; + if islogy then begin + finfo.datapoints[int1].y:= pkround((chartln(preal(poy)^) + yo)* ys); + end + else begin + finfo.datapoints[int1].y:= pkround((preal(poy)^ + yo)* ys); + end; + inc(pox,intx); + inc(poy,inty); + end; + end; + end; + end; + end; +end; + +procedure ttrace.paint(const acanvas: tcanvas); +var + int1,int2: integer; + rect1,rect2: rectty; + bo1: boolean; + po1,pend: ppointty; + startindex,pointcount: integer; +begin + if (finfo.widthmm > 0) and visible then begin + acanvas.linewidthmm:= finfo.widthmm; + if finfo.dashes <> '' then begin + acanvas.dashes:= finfo.dashes; + end; + if finfo.chartkind = tck_bar then begin + if finfo.bar_width = 0 then begin + acanvas.drawlinesegments(finfo.barlines,finfo.color); + end + else begin + rect1.cx:= finfo.bar_width; + for int1:= 0 to high(finfo.barlines) do begin + with finfo.barlines[int1] do begin + rect1.pos:= a; + rect1.cy:= b.y - a.y; + acanvas.fillrect(rect1,finfo.color); + if finfo.bar_frame <> nil then begin + if rect1.cy < 0 then begin + rect1.y:= rect1.y + rect1.cy; + rect1.y:= -rect1.y; + end; + acanvas.save; + finfo.bar_frame.paintbackground(acanvas,rect1,true,true); + if finfo.bar_face <> nil then begin + rect2:= deflaterect(rect1,finfo.bar_frame.innerframe); + acanvas.remove(pointty(finfo.bar_frame.paintframe.topleft)); + finfo.bar_face.paint(acanvas,rect2); + end; + acanvas.restore; + finfo.bar_frame.paintoverlay(acanvas,rect1); + end + else begin + if finfo.bar_face <> nil then begin + finfo.bar_face.paint(acanvas,rect1); + end; + end; + end; + end; + end; + end + else begin + if finfo.datapoints <> nil then begin + if cto_smooth in finfo.options then begin + acanvas.smooth:= true; + end; + acanvas.capstyle:= cs_round; + acanvas.joinstyle:= js_round; + bo1:= (kind = trk_xseries) or (cto_xordered in finfo.options); + if bo1 then begin + po1:= pointer(finfo.datapoints); + inc(po1); + pend:= po1 + high(finfo.datapoints); + rect1:= acanvas.clipbox; + int2:= (acanvas.linewidth+1) div 2; + int1:= rect1.x - int2; + while po1 < pend do begin + if po1^.x >= int1 then begin + break; + end; + inc(po1); + end; + dec(po1); + startindex:= po1 - ppointty(pointer(finfo.datapoints)); + int1:= rect1.x+rect1.cx+int2; + dec(pend); + while po1 < pend do begin + if po1^.x > int1 then begin + break; + end; + inc(po1); + end; + inc(po1); + pointcount:= po1 - ppointty(pointer(finfo.datapoints)) - startindex; + end + else begin + startindex:= 0; + pointcount:= length(finfo.datapoints); + end; + if (fbreaks = nil) or bo1 then begin + acanvas.drawlines(finfo.datapoints,false,finfo.color,startindex,pointcount); + end + else begin + acanvas.drawlines(finfo.datapoints,fbreaks,false,finfo.color,startindex, + pointcount); + end; + acanvas.capstyle:= cs_butt; + acanvas.joinstyle:= js_miter; + acanvas.smooth:= false; + end; + end; + if finfo.dashes <> '' then begin + acanvas.dashes:= ''; + end; + end; +end; + +procedure ttrace.paint1(const acanvas: tcanvas; const imagesize: sizety; + const imagealignment: alignmentsty); +var + int1: integer; + pt1: pointty; +// rect1: rectty; +// co1: colorty; + bmp1{,bmp2}: tmaskedbitmap; +// margin: integer; +// imli1: timagelist; +begin + if not visible then begin + exit; + end; + fimagealignment:= imagealignment; + with ftraces do begin + fimli1:= actualimagelist; + if (fimli1 <> nil) and (finfo.imagenr >= 0) and + (finfo.imagenr < fimli1.count) then begin + pt1:= pointty(imagesize); + pt1.x:= pt1.x div 2; + pt1.y:= pt1.y div 2; + acanvas.remove(pt1); + frect1.size:= imagesize; + fco1:= finfo.colorimage; + if fco1 = cl_default then begin + fco1:= finfo.color; + end; + if not acanvas.highresdevice and + (imagealignment * [al_stretchx,al_stretchy] <> []) then begin + bmp1:= tmaskedbitmap.create(fimli1.kind{fimli1.monochrome}); + fbmp2.free; //in case of previous exception + fbmp2:= tmaskedbitmap.create(bmk_rgb{false}); + try + bmp1.masked:= fimli1.masked; + fimli1.getimage(finfo.imagenr,bmp1); + bmp1.colorforeground:= fco1; + bmp1.colorbackground:= tcuchart(fowner).actualcolorchart; +// bmp1.monochrome:= false; + bmp1.kind:= bmk_rgb; + bmp1.colormask:= true; + fbmp2.size:= imagesize; + bmp1.stretch(fbmp2); + for int1:= finfo.bottommargin to high(finfo.datapoints) - + finfo.topmargin do begin + fbmp2.paint(acanvas,finfo.datapoints[int1],[],fco1); + end; + finally + bmp1.free; +// bmp2.free; + end; + end + else begin + for int1:= finfo.bottommargin to high(finfo.datapoints) - + finfo.topmargin do begin + frect1.pos:= finfo.datapoints[int1]; + fimli1.paint(acanvas,finfo.imagenr,frect1,imagealignment,fco1); + end; + end; + acanvas.move(pt1); + end + else begin + fimli1:= nil; + end; + end; +end; + +procedure ttrace.paint2(const acanvas: tcanvas); +var + int1: integer; + pt1: pointty; +begin + if not visible then begin + exit; + end; + if finfo.legend <> '' then begin + int1:= finfo.legendrect.x + 2*fcurfont.glyphheight; + acanvas.drawstring(finfo.legend,mp(int1,finfo.legendrect.y+fcurfont.ascent), + fcurfont); + pt1.y:= finfo.legendrect.y + finfo.legendrect.cy div 2; + if finfo.widthmm > 0 then begin + acanvas.dashes:= finfo.dashes; + acanvas.linewidthmm:= finfo.widthmm; + acanvas.drawvect(mp(finfo.legendrect.x+1,pt1.y), + gd_right,2*fcurfont.glyphheight-3,finfo.color); + acanvas.dashes:= ''; + acanvas.linewidthmm:= 0; + end; + pt1.x:= int1 - fcurfont.glyphheight; //image center + if fimli1 <> nil then begin + if fbmp2 <> nil then begin + pt1.x:= pt1.x - fbmp2.width div 2; + pt1.y:= pt1.x - fbmp2.height div 2; + fbmp2.paint(acanvas,pt1,[],fco1); + end + else begin + frect1.x:= pt1.x - frect1.cx div 2; + frect1.y:= pt1.y - frect1.cy div 2; + fimli1.paint(acanvas,finfo.imagenr,frect1,fimagealignment,fco1); + end; + end; + end; + fbmp2.free; + fbmp2:= nil; +end; + +procedure ttrace.clip2(const acanvas: tcanvas); +//const +// padding = 1; +//var +// rect1: rectty; +begin + if not visible then begin + exit; + end; + if finfo.legend <> '' then begin + fcurfont:= legend_font; +{ + rect1.pos:= finfo.legendpos; + rect1.cx:= acanvas.getstringwidth(finfo.legend,fcurfont)+ + 2*fcurfont.glyphheight + 2*padding; + rect1.cy:= fcurfont.glyphheight + 2*padding; + rect1.y:= rect1.y - fcurfont.ascent - padding; + rect1.x:= rect1.x - padding; + acanvas.subcliprect(rect1); +} + acanvas.subcliprect(finfo.legendrect); + end; +end; + +procedure ttrace.setcolor(const avalue: colorty); +begin + if finfo.color <> avalue then begin + finfo.color:= avalue; + tcustomchart(fowner).traces.change; + end; +end; + +procedure ttrace.setcolorimage(const avalue: colorty); +begin + if finfo.colorimage <> avalue then begin + finfo.colorimage:= avalue; + tcustomchart(fowner).traces.change; + end; +end; + +procedure ttrace.setwidthmm(const avalue: real); +begin + finfo.widthmm:= avalue; + tcustomchart(fowner).traces.change; +end; + +procedure ttrace.setdashes(const avalue: string); +begin + finfo.dashes:= avalue; + tcustomchart(fowner).traces.change; +end; + +procedure ttrace.setxserstart(const avalue: real); +begin + finfo.xserstart:= avalue; + datachange; +end; + +procedure ttrace.setxstart(const avalue: real); +begin + finfo.xstart:= avalue; + flnxstart:= chartln(avalue); + flnxrange:= chartln(finfo.xstart+finfo.xrange)-flnxstart; + datachange; +end; + +procedure ttrace.setxrange(const avalue: real); +begin + if avalue = 0 then begin + scaleerror; + end; + finfo.xrange:= avalue; + flnxrange:= chartln(finfo.xstart+finfo.xrange)-flnxstart; + datachange; +end; + +procedure ttrace.setxserrange(const avalue: real); +begin + if avalue = 0 then begin + scaleerror; + end; + finfo.xserrange:= avalue; + datachange; +end; + +procedure ttrace.setystart(const avalue: real); +begin + finfo.ystart:= avalue; + flnystart:= chartln(avalue); + flnyrange:= chartln(finfo.ystart+finfo.yrange)-flnystart; + datachange; +end; + +procedure ttrace.setyrange(const avalue: real); +begin + if avalue = 0 then begin + scaleerror; + end; + finfo.yrange:= avalue; + flnyrange:= chartln(finfo.ystart+finfo.yrange)-flnystart; + datachange; +end; + +procedure ttrace.setoptions(const avalue: charttraceoptionsty); +begin + if avalue <> finfo.options then begin + finfo.options:= avalue {- [cto_stockglyphs]}; + datachange; + end; +end; + +procedure ttrace.setchartkind(const avalue: tracechartkindty); +begin + if finfo.chartkind <> avalue then begin + finfo.chartkind:= avalue; + datachange; + end; +end; + +procedure ttrace.setbar_offset(const avalue: integer); +begin + if finfo.bar_offset <> avalue then begin + finfo.bar_offset:= avalue; + datachange; + end; +end; + +procedure ttrace.setbar_width(const avalue: integer); +begin + if finfo.bar_width <> avalue then begin + finfo.bar_width:= avalue; + datachange; + end; +end; + +procedure ttrace.setbar_ref(const avalue: barrefty); +begin + if finfo.bar_ref <> avalue then begin + finfo.bar_ref:= avalue; + datachange; + end; +end; + +procedure ttrace.scaleerror; +begin + raise exception.create('Range can not be 0.'); +end; + +procedure ttrace.setkind(const avalue: tracekindty); +begin + if finfo.kind <> avalue then begin + finfo.kind:= avalue; + datachange; + end; +end; + +procedure ttrace.setstart(const avalue: integer); +begin + if finfo.start <> avalue then begin + finfo.start:= avalue; + datachange; + end; +end; + +procedure ttrace.setmaxcount(const avalue: integer); +begin + if finfo.maxcount <> avalue then begin + finfo.maxcount:= avalue; + datachange; + end; +end; + +procedure ttrace.addxseriesdata(const avalue: real); +begin + finfo.ydatalist:= nil; + if (finfo.maxcount = 0) or (length(finfo.ydata) < finfo.maxcount) then begin + setlength(finfo.ydata,high(finfo.ydata) + 2); + end + else begin + move(finfo.ydata[1],finfo.ydata[0], + sizeof(finfo.ydata[0])*high(finfo.ydata)); + end; + finfo.ydata[high(finfo.ydata)]:= avalue; + datachange; +end; + +procedure ttrace.insertxseriesdata(const avalue: xseriesdataty); +begin + finfo.ydatalist:= nil; + insertitem(finfo.ydata,avalue.index,avalue.value); + datachange; +end; + +procedure ttrace.readxseriescount(reader: treader); +begin + maxcount:= reader.readinteger; +end; + +procedure ttrace.readxscale(reader: treader); +begin + xrange:= reader.readfloat; +end; + +procedure ttrace.readxoffset(reader: treader); +begin + xstart:= -reader.readfloat; +end; + +procedure ttrace.readyscale(reader: treader); +begin + yrange:= reader.readfloat; +end; + +procedure ttrace.readyoffset(reader: treader); +begin + ystart:= -reader.readfloat; +end; + +procedure ttrace.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('xseriescount',{$ifdef FPC}@{$endif}readxseriescount, + nil,false); + filer.defineproperty('xoffset',{$ifdef FPC}@{$endif}readxoffset, + nil,false); + filer.defineproperty('xscale',{$ifdef FPC}@{$endif}readxscale, + nil,false); + filer.defineproperty('yoffset',{$ifdef FPC}@{$endif}readyoffset, + nil,false); + filer.defineproperty('yscale',{$ifdef FPC}@{$endif}readyscale, + nil,false); +end; + +procedure ttrace.setimagenr(const avalue: imagenrty); +begin + if finfo.imagenr <> avalue then begin + finfo.imagenr:= avalue; + datachange; + end; +end; + +function ttrace.getimagelist: timagelist; +begin + result:= ftraces.actualimagelist; +end; + +procedure ttrace.assign(source: tpersistent); +begin + if source is ttrace then begin + with ttrace(source) do begin + self.finfo:= finfo; + datachange; + end; + end + else begin + inherited; + end; +end; + +procedure ttrace.clear; +begin + xydata:= nil; + fbreaks:= nil; +end; + +procedure ttrace.addxydata(const x: real; const y: real); +var + int1,int2: integer; +begin + with finfo do begin + xdatalist:= nil; + ydatalist:= nil; + if xydata <> nil then begin + if cto_xordered in options then begin + int2:= 0; + for int1:= high(xydata) downto 0 do begin + if xydata[int1].re <= x then begin + int2:= int1+1; + break; + end; + end; + insertitem(xydata,int2,makecomplex(x,y)); + end + else begin + setlength(xydata,high(xydata)+2); + with xydata[high(xydata)] do begin + re:= x; + im:= y; + end; + end; + end + else begin + if (xdata <> nil) then begin + if cto_xordered in options then begin + int2:= 0; + for int1:= high(xdata) downto 0 do begin + if xdata[int1] <= x then begin + int2:= int1+1; + break; + end; + end; + setlength(ydata,length(xdata)); + insertitem(xdata,int2,x); + insertitem(ydata,int2,y); + end + else begin + setlength(xdata,high(xdata)+2); + setlength(ydata,length(xdata)); + xdata[high(xdata)]:= x; + ydata[high(xdata)]:= y; + end; + end + else begin + if (ydata <> nil) then begin + if cto_xordered in options then begin + end + else begin + setlength(ydata,high(ydata)+2); + setlength(xdata,length(ydata)); + xdata[high(xdata)]:= x; + ydata[high(xdata)]:= y; + end; + end + else begin + setlength(xydata,1); + with xydata[0] do begin + re:= x; + im:= y; + end; + end; + end; + end; + end; + datachange; +end; + +function ttrace.getlogx: boolean; +begin + result:= cto_logx in options; +end; + +procedure ttrace.setlogx(const avalue: boolean); +begin + if avalue then begin + options:= options + [cto_logx]; + end + else begin + options:= options - [cto_logx]; + end; +end; + +function ttrace.getlogy: boolean; +begin + result:= cto_logy in options; +end; + +procedure ttrace.setlogy(const avalue: boolean); +begin + if avalue then begin + options:= options + [cto_logy]; + end + else begin + options:= options - [cto_logy]; + end; +end; + +function ttrace.getvisible: boolean; +begin + result:= not (cto_invisible in finfo.options); +end; + +procedure ttrace.setvisible(const avalue: boolean); +begin + if avalue then begin + options:= options - [cto_invisible]; + end + else begin + options:= options + [cto_invisible]; + end; +end; + +function ttrace.getsmooth: boolean; +begin + result:= cto_smooth in options; +end; + +procedure ttrace.setsmooth(const avalue: boolean); +begin + if avalue then begin + options:= options + [cto_smooth]; + end + else begin + options:= options - [cto_smooth]; + end; +end; + +function ttrace.getxdatapo: preal; +begin + result:= pointer(finfo.xdata); + if xdatalist <> nil then begin + result:= xdatalist.datapo; + end; +end; + +function ttrace.getydatapo: preal; +begin + result:= pointer(finfo.ydata); + if ydatalist <> nil then begin + result:= ydatalist.datapo; + end; +end; + +function ttrace.getxydatapo: pcomplexty; +begin + result:= pointer(finfo.xydata); +end; + +function ttrace.getcount: integer; +begin + result:= 0; + with finfo do begin + if ydata <> nil then begin + result:= length(ydata); + exit; + end; + if xdata <> nil then begin + result:= length(xdata); + exit; + end; + if xydata <> nil then begin + result:= length(xydata); + exit; + end; + if ydatalist <> nil then begin + result:= ydatalist.count; + exit; + end; + if xdatalist <> nil then begin + result:= xdatalist.count; + exit; + end; + end; +end; + +function ttrace.getxvalue(const index: integer): real; +begin + result:= getxitempo(index)^; +end; + +procedure ttrace.setxvalue(const index: integer; const avalue: real); +begin + getxitempo(index)^:= avalue; + datachange; +end; + +function ttrace.getyvalue(const index: integer): real; +begin + result:= getyitempo(index)^; +end; + +procedure ttrace.setyvalue(const index: integer; const avalue: real); +begin + getyitempo(index)^:= avalue; + datachange; +end; + +function ttrace.getxyvalue(const index: integer): complexty; +begin + result.re:= getxitempo(index)^; + result.im:= getyitempo(index)^; +end; + +procedure ttrace.setxyvalue(const index: integer; const avalue: complexty); +begin + getxitempo(index)^:= avalue.re; + getyitempo(index)^:= avalue.im; + datachange; +end; + +procedure ttrace.addxydata(const xy: complexty); +begin + addxydata(xy.re,xy.im); +end; + +function ttrace.getxitempo(const aindex: integer): preal; +begin + with finfo do begin + if xdatalist <> nil then begin + result:= xdatalist.getitempo(aindex); + end + else begin + if xdata <> nil then begin + checkarrayindex(xdata,aindex); + result:= @xdata[aindex]; + end + else begin + checkarrayindex(xydata,aindex); + result:= @xydata[aindex].re; + end; + end; + end; +end; + +function ttrace.getyitempo(const aindex: integer): preal; +begin + with finfo do begin + if ydatalist <> nil then begin + result:= ydatalist.getitempo(aindex); + end + else begin + if ydata <> nil then begin + checkarrayindex(ydata,aindex); + result:= @ydata[aindex]; + end + else begin + checkarrayindex(xydata,aindex); + result:= @xydata[aindex].im; + end + end; + end; +end; + +procedure ttrace.getdatapo(out xpo,ypo: preal; //xpo nil for xseries + out xcount,ycount,xstep,ystep: integer); +begin + ystep:= 1; + xstep:= 1; + xpo:= nil; + ypo:= nil; + xcount:= 0; + ycount:= 0; + with finfo do begin + if ydatalist <> nil then begin + ypo:= ydatalist.datapo; + ycount:= ydatalist.count; + end + else begin + if ydata <> nil then begin + ypo:= pointer(ydata); + ycount:= length(ydata); + end + else begin + ypo:= pointer(xydata); + ycount:= length(xydata); + ystep:= 2; + if ypo <> nil then begin + inc(ypo); + end; + end; + end; + if kind <> trk_xseries then begin + if xdatalist <> nil then begin + xpo:= xdatalist.datapo; + xcount:= xdatalist.count; + end + else begin + if xdata <> nil then begin + xpo:= pointer(xdata); + xcount:= length(xdata); + end + else begin + xpo:= pointer(xydata); + xcount:= length(xydata); + ystep:= 2; + end; + end; + end; + end; +end; + +procedure ttrace.deletedata(const aindex: integer); +begin + if (aindex < 0) or (aindex >= count) then begin + tlist.error(slistindexerror, aindex); + end; + datachange; + with finfo do begin + if ydata <> nil then begin + deleteitem(ydata,aindex); + end; + if xdata <> nil then begin + deleteitem(xdata,aindex); + end; + if xydata <> nil then begin + deleteitem(xydata,aindex); + end; + if ydatalist <> nil then begin + ydatalist.deletedata(aindex); + end; + if xdatalist <> nil then begin + xdatalist.deletedata(aindex); + end; + end; +end; + +procedure ttrace.deletedata(const aindexar: integerarty); +var + int1,int2,int3: integer; + ar1: integerarty; +begin + ar1:= copy(aindexar); + for int1:= 0 to high(ar1) do begin + int2:= ar1[int1]; + deletedata(int2); + for int3:= int1+1 to high(ar1) do begin + if ar1[int3] >= int2 then begin + dec(ar1[int3]); + end; + end; + end; +end; + +function ttrace.getbar_frame: tframe; +begin + tcustomchart(fowner).getoptionalobject(finfo.bar_frame, + {$ifdef FPC}@{$endif}createbar_frame); + result:= finfo.bar_frame; +end; + +procedure ttrace.setbar_frame(const avalue: tframe); +begin + tcustomchart(fowner).setoptionalobject(avalue,finfo.bar_frame, + {$ifdef FPC}@{$endif}createbar_frame); + datachange; +end; + +function ttrace.getbar_face: tface; +begin + tcustomchart(fowner).getoptionalobject(finfo.bar_face,{$ifdef FPC}@{$endif}createbar_face); + result:= finfo.bar_face; +end; + +procedure ttrace.setbar_face(const avalue: tface); +begin + tcustomchart(fowner).setoptionalobject(avalue,finfo.bar_face, + {$ifdef FPC}@{$endif}createbar_face); + datachange; +end; + +procedure ttrace.createbar_frame; +begin + if finfo.bar_frame = nil then begin + tbarframe.create(iframe(self)); + end; +end; + +procedure ttrace.createbar_face; +begin + if finfo.bar_face = nil then begin + finfo.bar_face:= tface.create(iface(self)); + end; +end; + +procedure ttrace.setframeinstance(instance: tcustomframe); +begin + finfo.bar_frame:= tframe(instance); +end; + +procedure ttrace.setstaticframe(value: boolean); +begin + //dummy +end; + +function ttrace.getstaticframe: boolean; +begin + result:= false; +end; + +procedure ttrace.scrollwidgets(const dist: pointty); +begin + //dummy +end; + +procedure ttrace.clientrectchanged; +begin + invalidate; +end; + +function ttrace.getcomponentstate: tcomponentstate; +begin + result:= tcustomchart(fowner).componentstate; +end; + +function ttrace.getmsecomponentstate: msecomponentstatesty; +begin + result:= tcustomchart(fowner).msecomponentstate; +end; + +procedure ttrace.invalidate; +begin + tcustomchart(fowner).invalidate; +end; + +procedure ttrace.invalidatewidget; +begin + tcustomchart(fowner).invalidatewidget; +end; + +procedure ttrace.invalidaterect(const rect: rectty; + const org: originty = org_client; const noclip: boolean = false); +begin + tcustomchart(fowner).invalidaterect(rect,org,noclip); +end; + +function ttrace.getwidget: twidget; +begin + result:= tcustomchart(fowner); +end; + +function ttrace.getwidgetrect: rectty; +begin + result:= tcustomchart(fowner).innerclientrect; +end; + +function ttrace.getframestateflags: framestateflagsty; +begin + result:= []; +end; + +function ttrace.translatecolor(const acolor: colorty): colorty; +begin + result:= acolor; + if acolor = cl_default then begin + result:= finfo.color; + end + else begin + result:= acolor; + end; +end; + +function ttrace.getclientrect: rectty; +begin + result:= tcustomchart(fowner).getdialrect; +end; + +procedure ttrace.setlinkedvar(const source: tmsecomponent; + var dest: tmsecomponent; const linkintf: iobjectlink = nil); +begin + tcustomchart(fowner).setlinkedvar(source,dest,linkintf); +end; + +procedure ttrace.widgetregioninvalid; +begin + //dummy +end; + +procedure ttrace.minmaxx1(var amin: real; var amax: real); +var + min,max: real; + int1: integer; + pox,poy: preal; + cx,cy,sx,sy: integer; +begin + if kind = trk_xseries then begin + min:= xserstart; + max:= min + xserrange; + end + else begin + getdatapo(pox,poy,cx,cy,sx,sy); + if cx = 0 then begin + min:= 0; + max:= 1; + end + else begin + min:= amin; + max:= amax; + for int1:= cx-1 downto 0 do begin + if pox^ > max then begin + max:= pox^; + end; + if pox^ < min then begin + min:= pox^; + end; + inc(pox,sx); + end; + end; + end; + if min < amin then begin + amin:= min; + end; + if max > amax then begin + amax:= max; + end; +end; + +procedure ttrace.minmaxy1(var amin: real; var amax: real); +var + min,max: real; + int1: integer; + pox,poy: preal; + cx,cy,sx,sy: integer; +begin + getdatapo(pox,poy,cx,cy,sx,sy); + if cy = 0 then begin + min:= 0; + max:= 1; + end + else begin + min:= amin; + max:= amax; + for int1:= cy-1 downto 0 do begin + if poy^ > max then begin + max:= poy^; + end; + if poy^ < min then begin + min:= poy^; + end; + inc(poy,sy); + end; + end; + if min < amin then begin + amin:= min; + end; + if max > amax then begin + amax:= max; + end; +end; + +procedure ttrace.minmaxx(out amin: real; out amax: real); +begin + amin:= bigreal; + amax:= -bigreal; + minmaxx1(amin,amax); + if amax < amin then begin + amin:= 0; + amax:= 0; + end; +end; + +procedure ttrace.minmaxy(out amin: real; out amax: real); +begin + amin:= bigreal; + amax:= -bigreal; + minmaxy1(amin,amax); + if amax < amin then begin + amin:= 0; + amax:= 0; + end; +end; + +procedure ttrace.autoscalex(const astartmargin: real = 0; + const aendmargin: real = 0); +var + min,max: real; +begin + minmaxx(min,max); + xrange:= calctracerange(min,max,cto_logx in options,astartmargin,aendmargin); + xstart:= min; +end; + +procedure ttrace.autoscaley(const astartmargin: real = 0; + const aendmargin: real = 0); +var + min,max: real; +begin + minmaxy(min,max); + yrange:= calctracerange(min,max,cto_logy in options,astartmargin,aendmargin); + ystart:= min; +end; + +procedure ttrace.fontchanged(const sender: tobject); +begin + legendchange; +end; + +function ttrace.isfontstored: boolean; +begin + result:= finfo.font <> nil; +end; + +procedure ttrace.createfont; +begin + if finfo.font = nil then begin + finfo.font:= ttracefont.create; + finfo.font.onchange:= {$ifdef FPC}@{$endif}fontchanged; + end; +end; + +function ttrace.getlegend_font: ttracefont; +begin + getoptionalobject(tcustomchart(fowner).componentstate, + finfo.font,{$ifdef FPC}@{$endif}createfont); + if finfo.font <> nil then begin + result:= finfo.font; + end + else begin +{$warnings off} + result:= ttracefont(ftraces.getfont); +{$warnings on} + end; +end; + +procedure ttrace.setlegend_font(const avalue: ttracefont); +begin + if avalue <> finfo.font then begin + setoptionalobject(tcustomchart(fowner).componentstate, + avalue,finfo.font,{$ifdef FPC}@{$endif}createfont); + legendchange; + end; +end; + +procedure ttrace.setlegend_caption(const avalue: msestring); +begin + finfo.legend:= avalue; + legendchange; +end; + +function ttrace.hintx: msestring; +begin + result:= fhint_captionx; + if result = '' then begin + result:= tcustomchart(fowner).tracehint_captionx; + end; +end; + +function ttrace.hinty: msestring; +begin + result:= fhint_captiony; + if result = '' then begin + result:= tcustomchart(fowner).tracehint_captiony; + end; +end; + +{ ttracesfont } + +class function ttracesfont.getinstancepo(owner: tobject): pfont; +begin + result:= @ttraces(owner).ffont; +end; + +{ ttraces } + +constructor ttraces.create(const aowner: tcustomchart); +begin + fkind:= trk_xseries; + fxserrange:= 1; + fxrange:= 1; + fyrange:= 1; + flegend_dist:= defaultlegenddist; + flegend_fitdist:= defaultlegenddist; + flegend_placement:= defaultlegendplacement; + inherited create(aowner,ownedeventpersistentclassty(getitemclasstype)); +end; + +destructor ttraces.destroy; +begin + inherited; + ffont.free; +end; + +class function ttraces.getitemclasstype: persistentclassty; +begin + result:= ttrace; +end; + +procedure ttraces.change; +begin + exclude(ftracestate,trss_graphicvalid); + tcuchart(fowner).invalidate; +end; + +procedure ttraces.clientrectchanged; +var + int1: integer; +begin + exclude(ftracestate,trss_graphicvalid); + for int1:= 0 to high(fitems) do begin + exclude(ptraceaty(fitems)^[int1].finfo.state,trs_datapointsvalid); + end; +end; + +procedure ttraces.paint(const acanvas: tcanvas); +var + int1: integer; + size1: sizety; + align1: alignmentsty; + imli1: timagelist; +begin + for int1:= 0 to high(fitems) do begin + ptraceaty(fitems)^[int1].paint(acanvas); + end; + align1:= []; + size1:= nullsize; + imli1:= actualimagelist; + if imli1 <> nil then begin + size1:= imli1.size; + if fimage_widthmm <> 0 then begin + size1.cx:= round(fimage_widthmm*acanvas.ppmm); + align1:= align1 + [al_stretchx,al_intpol]; + end; + if fimage_heightmm <> 0 then begin + size1.cy:= round(fimage_heightmm*acanvas.ppmm); + align1:= align1 + [al_stretchy,al_intpol]; + end; + end; + exclude(align1,al_intpol); + for int1:= 0 to high(fitems) do begin + ptraceaty(fitems)^[int1].paint1(acanvas,size1,align1); + end; + acanvas.linewidth:= 0; +end; + +procedure ttraces.clipoverlay(const acanvas: tcanvas); +var + int1: integer; +begin + checkgraphic; + if flegend_placement <> tlp_none then begin + for int1:= 0 to high(fitems) do begin + ptraceaty(fitems)^[int1].clip2(acanvas); + end; + end; +end; + +procedure ttraces.paintoverlay(const acanvas: tcanvas); +var + int1: integer; +begin + if flegend_placement <> tlp_none then begin + for int1:= 0 to high(fitems) do begin + ptraceaty(fitems)^[int1].paint2(acanvas); + end; + end; +end; + +procedure ttraces.calclegendrect; +type + rowinfoty = record + last: integer; + width: integer; + height: integer; + end; +var + int1,int2,int3: integer; + x1,y1,x2,y2: integer; + canvas1: tcanvas; + rect1: rectty; + ar1: array of rowinfoty; + + procedure pushrow(const aindex: integer); + begin + with ar1[int2] do begin + last:= aindex; + width:= x1; + height:= y1; + end; + y2:= y2 + y1; + inc(int2); + x1:= -1; + y1:= 0; + end; //pushrow + +begin + if not (trss_graphicvalid in ftracestate) then begin + canvas1:= tcustomchart(fowner).getcanvas; + rect1:= tcustomchart(fowner).getdialrect; + fsize:= rect1.size; + if fsize.cx < 0 then begin + fsize.cx:= 0; + end; + if fsize.cy < 0 then begin + fsize.cy:= 0; + end; + fscalex:= fsize.cx; + fscaley:= fsize.cy; + + x1:= 0; + y1:= 0; + for int1:= 0 to high(fitems) do begin + with ptraceaty(fitems)^[int1] do begin + if (finfo.legend <> '') and not (cto_invisible in finfo.options) then begin + with finfo.legendrect do begin + fcurfont:= getlegend_font; + cy:= fcurfont.glyphheight; + cx:= 2*cy + canvas1.getstringwidth(finfo.legend,fcurfont); + if cx > x1 then begin + x1:= cx; + end; + y1:= y1 + cy; + end; + end + else begin + finfo.legendrect:= nullrect; + end; + end; + end; + case flegend_placement of + tlp_xy: begin + x2:= round(flegend_pos.re*fsize.cx) - x1 div 2; + int1:= fsize.cx - x1 - flegend_dist; + if x2 > int1 then begin + x2:= int1; + end; + if x2 < flegend_dist then begin + x2:= flegend_dist; + end; + y2:= fsize.cy - round(flegend_pos.im*fsize.cy) - y1 div 2; + int1:= fsize.cy - y1 - flegend_dist; + if y2 > int1 then begin + y2:= int1; + end; + if y2 < flegend_dist then begin + y2:= flegend_dist; + end; + + x2:= x2 + rect1.x; + y2:= y2 + rect1.y; + for int1:= 0 to high(fitems) do begin + with ptraceaty(fitems)^[int1].finfo.legendrect do begin + x:= x2; + y:= y2; + y2:= y2 + cy; + end; + end; + end; + tlp_above,tlp_below: begin + setlength(ar1,length(fitems)); //max + if ar1 <> nil then begin + x2:= rect1.cx; //max width + y2:= 0; //tot height + with ptraceaty(fitems)^[0].finfo.legendrect do begin + x1:= cx; + y1:= cy; + end; + int2:= 0; + for int1:= 1 to high(fitems) do begin + with ptraceaty(fitems)^[int1].finfo.legendrect do begin + if x1+cx+1 > x2 then begin + pushrow(int1-1); + end; + x1:= x1 + cx + 1; + if cy > y1 then begin + y1:= cy; + end; + end; + end; + if (int2 = 0) or (high(fitems) > 0) then begin + pushrow(high(fitems)); //last or single + end; + setlength(ar1,int2); + if flegend_placement = tlp_above then begin + y1:= rect1.y - y2 - flegend_dist; + end + else begin + y1:= rect1.y + rect1.cy + flegend_dist; + end; + int2:= 0; + x2:= 0; + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + if x2 < width then begin + x2:= width; + end; + end; + end; + flegendsize.cx:= x2; + flegendsize.cy:= y2; + x2:= rect1.x + (rect1.cx - x2) div 2; //center block + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + x1:= x2; + for int3:= int2 to last do begin + with ptraceaty(fitems)^[int3].finfo.legendrect do begin + x:= x1; + y:= y1 + (height - cy) div 2; + x1:= x1 + cx + 1; + end; + end; + int2:= last + 1; + y1:= y1 + height; + end; + end; + end; + end; + end; + end; +end; + +procedure ttraces.checkgraphic; +var + int1: integer; +begin + if not (trss_graphicvalid in ftracestate) then begin + calclegendrect; + for int1:= 0 to high(fitems) do begin + with ptraceaty(fitems)^[int1] do begin + checkgraphic; + end; + end; + include(ftracestate,trss_graphicvalid); + end; +end; + +procedure ttraces.setitems(const index: integer; const avalue: ttrace); +begin + inherited getitems(index).assign(avalue); +end; + +function ttraces.getitems(const index: integer): ttrace; +begin + result:= ttrace(inherited getitems(index)); +end; + +function ttraces.itembyname(const aname: string): ttrace; +var + int1: integer; +begin + result:= nil; + for int1:= 0 to high(fitems) do begin + if ttrace(fitems[int1]).name = aname then begin + result:= ttrace(fitems[int1]); + break; + end; + end; +end; + +procedure ttraces.setxserstart(const avalue: real); +var + int1: integer; +begin + fxserstart:= avalue; + if not (csreading in tcuchart(fowner).componentstate) then begin + for int1:= 0 to high(fitems) do begin + ttrace(fitems[int1]).xserstart:= avalue; + end; + end; +end; + +procedure ttraces.setxstart(const avalue: real); +var + int1: integer; +begin + fxstart:= avalue; + if not (csreading in tcuchart(fowner).componentstate) then begin + for int1:= 0 to high(fitems) do begin + ttrace(fitems[int1]).xstart:= avalue; + end; + end; +end; + +procedure ttraces.setystart(const avalue: real); +var + int1: integer; +begin + fystart:= avalue; + if not (csreading in tcuchart(fowner).componentstate) then begin + for int1:= 0 to high(fitems) do begin + ttrace(fitems[int1]).ystart:= avalue; + end; + end; +end; + +procedure ttraces.setxserrange(const avalue: real); +var + int1: integer; +begin + fxserrange:= avalue; + if not (csreading in tcuchart(fowner).componentstate) then begin + for int1:= 0 to high(fitems) do begin + ttrace(fitems[int1]).xserrange:= avalue; + end; + end; +end; + +procedure ttraces.setxrange(const avalue: real); +var + int1: integer; +begin + fxrange:= avalue; + if not (csreading in tcuchart(fowner).componentstate) then begin + for int1:= 0 to high(fitems) do begin + ttrace(fitems[int1]).xrange:= avalue; + end; + end; +end; + +procedure ttraces.setyrange(const avalue: real); +var + int1: integer; +begin + fyrange:= avalue; + if not (csreading in tcuchart(fowner).componentstate) then begin + for int1:= 0 to high(fitems) do begin + ttrace(fitems[int1]).yrange:= avalue; + end; + end; +end; + +procedure ttraces.setstart(const avalue: integer); +var + int1: integer; +begin + fstart:= avalue; + if not (csreading in tcuchart(fowner).componentstate) then begin + for int1:= 0 to high(fitems) do begin + ttrace(fitems[int1]).start:= avalue; + end; + end; +end; + +procedure ttraces.setmaxcount(const avalue: integer); +var + int1: integer; +begin + fmaxcount:= avalue; + if not (csreading in tcuchart(fowner).componentstate) then begin + for int1:= 0 to high(fitems) do begin + ttrace(fitems[int1]).maxcount:= avalue; + end; + end; +end; + +procedure ttraces.setkind(const avalue: tracekindty); +var + int1: integer; +begin + if fkind <> avalue then begin + fkind:= avalue; + if not (csreading in tcuchart(fowner).componentstate) then begin + for int1:= 0 to count - 1 do begin + ttrace(fitems[int1]).kind:= avalue; + end; + end; + end; +end; + +procedure ttraces.setchartkind(const avalue: tracechartkindty); +var + int1: integer; +begin + if fchartkind <> avalue then begin + fchartkind:= avalue; + if not (csreading in tcuchart(fowner).componentstate) then begin + for int1:= 0 to count - 1 do begin + ttrace(fitems[int1]).chartkind:= avalue; + end; + end; + end; +end; + +procedure ttraces.setbar_width(const avalue: integer); +var + int1: integer; +begin + if fbar_width <> avalue then begin + fbar_width:= avalue; + if not (csreading in tcuchart(fowner).componentstate) then begin + for int1:= 0 to count - 1 do begin + ttrace(fitems[int1]).bar_width:= avalue; + end; + end; + end; +end; + +procedure ttraces.setbar_ref(const avalue: barrefty); +var + int1: integer; +begin + if fbar_ref <> avalue then begin + fbar_ref:= avalue; + if not (csreading in tcuchart(fowner).componentstate) then begin + for int1:= 0 to count - 1 do begin + ttrace(fitems[int1]).bar_ref:= avalue; + end; + end; + end; +end; + +procedure ttraces.setoptions(const avalue: charttraceoptionsty); +var + int1: integer; + mask: {$ifdef FPC}longword{$else}byte{$endif}; +begin + if foptions <> avalue then begin + mask:= {$ifdef FPC}longword{$else}word{$endif}(avalue) xor + {$ifdef FPC}longword{$else}word{$endif}(foptions); + foptions:= avalue; + if not (csreading in tcuchart(fowner).componentstate) then begin + for int1:= 0 to count - 1 do begin + ttrace(fitems[int1]).options:= charttraceoptionsty(replacebits( + {$ifdef FPC}longword{$else}word{$endif}(foptions), + {$ifdef FPC}longword{$else}word{$endif}( + ttrace(fitems[int1]).options),mask)); + end; + end; + end; +end; + +procedure ttraces.createitem(const index: integer; var item: tpersistent); +begin + inherited; + with ttrace(item) do begin + kind:= self.fkind; + chartkind:= self.fchartkind; + bar_width:= self.fbar_width; + bar_ref:= self.fbar_ref; + options:= self.foptions; + xserstart:= self.fxserstart; + xstart:= self.fxstart; + ystart:= self.fystart; + xserrange:= self.fxserrange; + xrange:= self.fxrange; + yrange:= self.fyrange; + start:= self.fstart; + maxcount:= self.fmaxcount; + end; +end; + +procedure ttraces.assign(source: tpersistent); +begin + if source is ttraces then begin + with ttraces(source) do begin + self.fxserstart:= fxserstart; + self.fxstart:= fxstart; + self.fystart:= fystart; + self.fxserrange:= fxserrange; + self.fxrange:= fxrange; + self.fyrange:= fyrange; + self.maxcount:= fmaxcount; + end; + end; + inherited; +end; + +procedure ttraces.setimage_list(const avalue: timagelist); +begin + setlinkedvar(avalue,tmsecomponent(fimage_list)); + change; +end; + +procedure ttraces.setimage_widthmm(const avalue: real); +begin + fimage_widthmm:= avalue; + change; +end; + +procedure ttraces.setimage_heightmm(const avalue: real); +begin + fimage_heightmm:= avalue; + change; +end; + +function ttraces.getfont: ttracesfont; +begin + getoptionalobject(tcustomchart(fowner).componentstate, + ffont,{$ifdef FPC}@{$endif}createfont); + if ffont <> nil then begin + result:= ffont; + end + else begin +{$warnings off} + result:= ttracesfont(tcustomchart(fowner).getfont); +{$warnings on} + end; +end; + +procedure ttraces.setfont(const avalue: ttracesfont); +begin + if avalue <> ffont then begin + setoptionalobject(tcustomchart(fowner).componentstate, + avalue,ffont,{$ifdef FPC}@{$endif}createfont); + layoutchanged; + end; +end; + +procedure ttraces.dostatread(const reader: tstatreader); +var + int1: integer; + mstr1: msestring; +begin + for int1:= 0 to count - 1 do begin + mstr1:= inttostrmse(int1); + with ttrace(fitems[int1]) do begin + if cto_savexscale in foptions then begin + xstart:= reader.readreal('xstart'+mstr1,xstart); + xrange:= reader.readreal('xrange'+mstr1,xrange); + end; + if cto_saveyscale in foptions then begin + ystart:= reader.readreal('ystart'+mstr1,ystart); + yrange:= reader.readreal('yrange'+mstr1,yrange); + end; + end; + end; +end; + +procedure ttraces.dostatwrite(const writer: tstatwriter); +var + int1: integer; + mstr1: msestring; +begin + for int1:= 0 to count - 1 do begin + mstr1:= inttostrmse(int1); + with ttrace(fitems[int1]) do begin + if cto_savexscale in foptions then begin + writer.writereal('xstart'+mstr1,xstart); + writer.writereal('xrange'+mstr1,xrange); + end; + if cto_saveyscale in foptions then begin + writer.writereal('ystart'+mstr1,ystart); + writer.writereal('yrange'+mstr1,yrange); + end; + end; + end; +end; + +function ttraces.getlogx: boolean; +begin + result:= cto_logx in options; +end; + +procedure ttraces.setlogx(const avalue: boolean); +begin + if avalue then begin + options:= options + [cto_logx]; + end + else begin + options:= options - [cto_logx]; + end; +end; + +function ttraces.getlogy: boolean; +begin + result:= cto_logy in options; +end; + +procedure ttraces.setlogy(const avalue: boolean); +begin + if avalue then begin + options:= options + [cto_logy]; + end + else begin + options:= options - [cto_logy]; + end; +end; + +function ttraces.actualimagelist: timagelist; +begin + result:= fimage_list; + if (result = nil) and (cto_stockglyphs in foptions) then begin + result:= stockobjects.glyphs; + end; +end; + +procedure ttraces.setdata(const adata: realararty); +var + int1: integer; +begin + for int1:= 0 to high(adata) do begin + if int1 > high(fitems) then begin + break; + end; + ttrace(fitems[int1]).ydata:= adata[int1]; + end; +end; + +procedure ttraces.setdata(const adata: complexararty); +var + int1: integer; +begin + for int1:= 0 to high(adata) do begin + if int1 > high(fitems) then begin + break; + end; + ttrace(fitems[int1]).xydata:= adata[int1]; + end; +end; + +function ttraces.isfontstored: boolean; +begin + result:= ffont <> nil; +end; + +procedure ttraces.createfont; +begin + if font = nil then begin + ffont:= ttracesfont.create; + ffont.onchange:= {$ifdef FPC}@{$endif}fontchanged; + end; +end; + +procedure ttraces.fontchanged(const sender: tobject); +begin + layoutchanged; +end; + +procedure ttraces.setlegend_pos(const avalue: complexty); +begin + if (flegend_pos.re <> avalue.re) or (flegend_pos.im <> avalue.im) then begin + flegend_pos:= avalue; + change; + end; +end; + +procedure ttraces.setlegend_x(const avalue: real); +begin + legend_pos:= mc(avalue,flegend_pos.im); +end; + +procedure ttraces.setlegend_y(const avalue: real); +begin + legend_pos:= mc(flegend_pos.re,avalue); +end; + +procedure ttraces.setlegend_dist(const avalue: integer); +begin + if flegend_dist <> avalue then begin + flegend_dist:= avalue; + layoutchanged; + end; +end; + +procedure ttraces.setlegend_placement(const avalue: tracelegendplacementty); +begin + if flegend_placement <> avalue then begin + flegend_placement:= avalue; + layoutchanged; + end; +end; + +procedure ttraces.setlegend_fitdist(const avalue: integer); +begin + if flegend_fitdist <> avalue then begin + flegend_fitdist:= avalue; + layoutchanged; + end; +end; + +procedure ttraces.layoutchanged; +begin + exclude(ftracestate,trss_graphicvalid); + change; + tcustomchart(fowner).layoutchanged; +end; + +{ tchartdialvert } + +constructor tchartdialvert.create(const aintf: idialcontroller); +begin + inherited create(aintf); + direction:= gd_up; +end; + +procedure tchartdialvert.setdirection(const avalue: graphicdirectionty); +begin + if avalue in [gd_up,gd_down] then begin + inherited; + end; +end; + +{ tchartdialhorz } + +constructor tchartdialhorz.create(const aintf: idialcontroller); +begin + inherited; + direction:= gd_right; +end; + +procedure tchartdialhorz.setdirection(const avalue: graphicdirectionty); +begin + if avalue in [gd_right,gd_left] then begin + inherited; + end; +end; + +{ tchartframe } + +constructor tchartframe.create(const aintf: iscrollframe; const owner: twidget); +begin + inherited; + fi.innerframe.left:= 0; + fi.innerframe.top:= 0; + fi.innerframe.right:= 1; + fi.innerframe.bottom:= 1; +end; + +function tchartframe.actualcolorclient(): colorty; +begin + result:= fi.colorclient; + if result = cl_default then begin + result:= cl_foreground; + end; +end; + +{ tcuchart } + +constructor tcuchart.create(aowner: tcomponent); +begin + fcolorchart:= cl_default; + foptionschart:= defaultoptionschart; + fxrange:= 1; + fyrange:= 1; + fydials:= tchartdialsvert.create(ichartdialcontroller(self)); + fxdials:= tchartdialshorz.create(ichartdialcontroller(self)); +{ + with fdialvert do begin + direction:= gd_up; + ticks.count:= 1; + with ticks[0] do begin + intervalcount:= 10; + color:= cl_dkgray; + end; + end; + with fdialhorz do begin + direction:= gd_right; + ticks.count:= 1; + with ticks[0] do begin + intervalcount:= 10; + color:= cl_dkgray; + end; + end; +} + inherited; + optionswidget:= defaultchartoptionswidget; +end; + +destructor tcuchart.destroy; +begin + fydials.free; + fxdials.free; + inherited; + ffacechart.free; + fframechart.free; +end; + +procedure tcuchart.invalidatelayout; +begin + if componentstate * [csloading,csdestroying] = [] then begin + exclude(fstate,chs_layoutvalid); + fxdials.changed; + fydials.changed; + chartchange; + end; +end; + +procedure tcuchart.clientrectchanged; +begin + invalidatelayout; + inherited; +end; +{ +procedure tcuchart.dobeforepaint(const canvas: tcanvas); +var + pt1: pointty; +begin + inherited; + if canevent(tmethod(fonbeforepaint)) then begin + pt1:= clientwidgetpos; + canvas.move(pt1); + fonbeforepaint(self,canvas); + canvas.remove(pt1); + end; +end; +} + +procedure tcuchart.doclipcontent1(const acanvas: tcanvas); +begin + //dummy +end; + +procedure tcuchart.dopaintcontent(const acanvas: tcanvas); +begin + //dummy +end; + +procedure tcuchart.dopaintcontent1(const acanvas: tcanvas); +begin + //dummy +end; + +procedure tcuchart.dopaintbackground(const canvas: tcanvas); +begin + inherited; + if not (chs_nocolorchart in fstate) and not canvas.clipregionisempty then begin + if fcolorchart <> cl_default then begin + canvas.fillrect(getdialrect,fcolorchart); + end; + if ffacechart <> nil then begin + ffacechart.paint(canvas,getdialrect); + end; + end; +// if canevent(tmethod(fonpaintbackground)) then begin +// fonpaintbackground(self,canvas); +// end; +end; +{ +procedure tcuchart.doonpaint(const canvas: tcanvas); +begin + inherited; + if canevent(tmethod(fonpaint)) then begin + fonpaint(self,canvas); + end; +end; + +procedure tcuchart.doafterpaint(const canvas: tcanvas); +var + pt1: pointty; +begin + inherited; + if canevent(tmethod(fonafterpaint)) then begin + pt1:= clientwidgetpos; + canvas.move(pt1); + fonafterpaint(self,canvas); + canvas.remove(pt1); + end; +end; +} +procedure tcuchart.dopaintforeground(const acanvas: tcanvas); +begin + inherited; + acanvas.save; + doclipcontent1(acanvas); + fxdials.paint(acanvas); + fydials.paint(acanvas); + dopaintcontent(acanvas); + fxdials.afterpaint(acanvas); + fydials.afterpaint(acanvas); + acanvas.restore; + dopaintcontent1(acanvas); + if fframechart <> nil then begin + fframechart.paintoverlay(acanvas,fchartframerect); + end; +end; + +procedure tcuchart.paint(const acanvas: tcanvas); +begin + checklayout; + inherited; +end; + +procedure tcuchart.setcolorchart(const avalue: colorty); +begin + if fcolorchart <> avalue then begin + fcolorchart:= avalue; + exclude(fstate,chs_chartvalid); //for tchartrecorder + changed; + end; +end; + +procedure tcuchart.setxdials(const avalue: tchartdialshorz); +begin + fxdials.assign(avalue); +end; + +procedure tcuchart.setydials(const avalue: tchartdialsvert); +begin + fydials.assign(avalue); +end; + +procedure tcuchart.directionchanged(const dir: graphicdirectionty; + const dirbefore: graphicdirectionty); +begin + //dummy +end; + +function tcuchart.getdialrect: rectty; +begin + result:= innerclientrect; + deflaterect1(result,ffitframe); + if fframechart <> nil then begin +{$warnings off} + deflaterect1(result,fframechart.innerframe); +{$warnings on} + end; +end; + +function tcuchart.getlimitrect: rectty; +begin + result:= innerclientrect; +end; + +procedure tcuchart.internalcreateframe; +begin + tchartframe.create(iscrollframe(self),self); +end; + +procedure tcuchart.changed; +begin + invalidate; +end; + +procedure tcuchart.defineproperties(filer: tfiler); +begin + inherited; +end; + +function tcuchart.getxstart: real; +begin + result:= fxstart; +end; + +procedure tcuchart.setxstart(const avalue: real); +begin + fxstart:= avalue; + fxdials.start:= avalue; +end; + +function tcuchart.getystart: real; +begin + result:= fystart; +end; + +procedure tcuchart.setystart(const avalue: real); +begin + fystart:= avalue; + fydials.start:= avalue; +end; + +function tcuchart.getxrange: real; +begin + result:= fxrange; +end; + +procedure tcuchart.setxrange(const avalue: real); +begin + fxrange:= avalue; + fxdials.range:= avalue; +end; + +function tcuchart.getyrange: real; +begin + result:= fyrange; +end; + +procedure tcuchart.setyrange(const avalue: real); +begin + fyrange:= avalue; + fydials.range:= avalue; +end; + +procedure tcuchart.setstatfile(const avalue: tstatfile); +begin + setstatfilevar(istatfile(self),avalue,fstatfile); +end; + +procedure tcuchart.dostatread(const reader: tstatreader); +begin + fxdials.dostatread(reader); + fydials.dostatread(reader); +end; + +procedure tcuchart.dostatwrite(const writer: tstatwriter); +begin + fxdials.dostatwrite(writer); + fydials.dostatwrite(writer); +end; + +procedure tcuchart.statreading; +begin + //dummy +end; + +procedure tcuchart.statread; +begin + //dummy +end; + +function tcuchart.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +procedure tcuchart.initscrollstate; +var + int1: integer; +begin + fshiftsum:= 0; + fscrollsum:= 0; + fsampleco:= 0; + fstate:= fstate - [chs_hasdialscroll,chs_hasdialshift]; + for int1:= 0 to fxdials.count -1 do begin + with fxdials[int1] do begin + if do_scrollwithdata in options then begin + include(self.fstate,chs_hasdialscroll); + end; + if do_shiftwithdata in options then begin + self.fstate:= self.fstate + [chs_hasdialscroll,chs_hasdialshift]; + end; + shift:= 0; + end; + end; +end; + +procedure tcuchart.layoutchanged; +begin + exclude(fstate,chs_layoutvalid); + invalidate; +end; + +procedure tcuchart.chartchange; +begin + exclude(fstate,chs_chartvalid); + invalidate; +end; + +function tcuchart.fit(const asides: rectsidesty = allrectsides): boolean; +var + ext1: rectextty; + int1: integer; + fra1: framety; + rect1: rectty; + si1: sizety; + shift1,shift2: integer; + + procedure handle(const adial: tcustomdialcontroller1; + const active1,active2,isx: boolean); + var + int1: integer; + begin + with adial do begin + if visible then begin + if do_opposite in options then begin + if active2 then begin + indent1:= -shift2-fitdist; + end; + end + else begin + if active2 then begin + indent1:= -shift1-fitdist; + end; + end; + checklayout; + expandrectext1(ext1,tdialticks1(ticks).fdim); + expandrectext1(ext1,tdialmarkers1(markers).fdim); + with tdialticks1(ticks).fdim do begin + if isx then begin + int1:= fitdist + bottom - top; + end + else begin + int1:= fitdist + right - left; + end; + end; + if do_opposite in options then begin + shift2:= shift2 + int1; + end + else begin + shift1:= shift1 + int1; + end; + end; + end; + end; + +begin + result:= false; + si1:= clientsize; + rect1:= getdialrect; + ext1.topleft:= rect1.pos; + ext1.bottomright:= addpoint(rect1.pos,pointty(rect1.size)); + shift1:= 0; + shift2:= 0; + for int1:= 0 to fxdials.count-1 do begin + {$warnings off} + handle(tcustomdialcontroller1(fxdials[int1]), + rs_bottom in asides,rs_top in asides,true); + {$warnings on} + end; + shift1:= 0; + shift2:= 0; + for int1:= 0 to fydials.count-1 do begin + {$warnings off} + handle(tcustomdialcontroller1(fydials[int1]), + rs_right in asides,rs_left in asides,false); + {$warnings on} + end; + extendfit(asides,ext1); + inflaterectext1(ext1,tcustomframe1(fframe).fi.innerframe); + if fframechart <> nil then begin + inflaterectext1(ext1,fframechart.framei); + end; + + fra1:= ffitframe; + + if rs_left in asides then begin + fra1.left:= fra1.left - ext1.left; + end; + if rs_top in asides then begin + fra1.top:= fra1.top - ext1.top; + end; + if rs_right in asides then begin + fra1.right:= fra1.right + (ext1.right - si1.cx); + end; + if rs_bottom in asides then begin + fra1.bottom:= fra1.bottom + (ext1.bottom - si1.cy); + end; + + if not frameisequal(fra1,ffitframe) then begin + result:= true; + fitframe:= fra1; + end; +end; + +procedure tcuchart.setoptionschart(const avalue: optionschartty); +begin + if foptionschart <> avalue then begin + foptionschart:= avalue; + layoutchanged; + end; +end; + +function tcuchart.checklayout: boolean; +begin + result:= false; + if not (chs_layoutvalid in fstate) then begin + if foptionschart * rectsidesmask <> [] then begin + result:= fit(rectsidesty(foptionschart*rectsidesmask)) or result; + end; + fchartframerect:= getdialrect; + if framechart <> nil then begin + inflaterect1(fchartframerect,fframechart.innerframe); + end; + end; + include(fstate,chs_layoutvalid); +end; + +function tcuchart.actualcolorchart(): colorty; +begin + result:= fcolorchart; + if result = cl_default then begin + if fframe <> nil then begin + result:= fframe.colorclient; + end; + end; + if result = cl_default then begin + result:= actualcolor; + end; +end; + +procedure tcuchart.setfitframe(const avalue: framety); +begin + ffitframe:= avalue; + invalidatelayout; +end; + +procedure tcuchart.setfitframe_left(const avalue: integer); +begin + if ffitframe.left <> avalue then begin + ffitframe.left:= avalue; + invalidatelayout; + end; +end; + +procedure tcuchart.setfitframe_top(const avalue: integer); +begin + if ffitframe.top <> avalue then begin + ffitframe.top:= avalue; + invalidatelayout; + end; +end; + +procedure tcuchart.setfitframe_right(const avalue: integer); +begin + if ffitframe.right <> avalue then begin + ffitframe.right:= avalue; + invalidatelayout; + end; +end; + +procedure tcuchart.setfitframe_bottom(const avalue: integer); +begin + if ffitframe.bottom <> avalue then begin + ffitframe.bottom:= avalue; + invalidatelayout; + end; +end; + +procedure tcuchart.fontchanged; +begin + invalidatelayout; + inherited; +end; + +function tcuchart.getfacechart: tface; +begin + getoptionalobject(ffacechart,{$ifdef FPC}@{$endif}createfacechart); + result:= ffacechart; +end; + +procedure tcuchart.setfacechart(const avalue: tface); +begin + setoptionalobject(avalue,ffacechart,{$ifdef FPC}@{$endif}createfacechart); + invalidate; +end; + +procedure tcuchart.createfacechart; +begin + if ffacechart = nil then begin + ffacechart:= tface.create(iface(self)); + end; +end; + +procedure tcuchart.createframechart; +begin + if fframechart = nil then begin + fframechart:= tframe(tframe.newinstance); + {$warnings off} + include(tcustomframe1(fframechart).fstate,fs_nosetinstance); + {$warnings on} + fframechart.create(iframe(self)); + end; +end; + +function tcuchart.getframechart: tframe; +begin + getoptionalobject(fframechart,{$ifdef FPC}@{$endif}createframechart); + result:= fframechart; +end; + +procedure tcuchart.setframechart(const avalue: tframe); +begin + setoptionalobject(avalue,fframechart,{$ifdef FPC}@{$endif}createframechart); + invalidate; +end; + +procedure tcuchart.extendfit(const asides: rectsidesty; var aext: rectextty); +begin + //dummy +end; + +function tcuchart.getzoomrefframe: framety; +begin + result:= inherited getzoomrefframe; + addframe1(result,ffitframe); + if fframechart <> nil then begin + addframe1(result,fframechart.innerframe); + end; +end; + +function tcuchart.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +{ tcustomchart } + +constructor tcustomchart.create(aowner: tcomponent); +begin + if ftraces = nil then begin + ftraces:= ttraces.create(self); + end; + inherited; +end; + +destructor tcustomchart.destroy; +begin + ftraces.free; + inherited; +end; + +procedure tcustomchart.clear; +var + int1: integer; +begin + initscrollstate; + include(fstate,chs_chartvalid); + for int1:= 0 to ftraces.count - 1 do begin + ftraces[int1].clear; + end; +end; + +procedure tcustomchart.addsample(const asamples: array of real); +var + int1: integer; + rea1,rea2: real; +begin + if not (chs_chartvalid in fstate) then begin + initscrollstate; + include(fstate,chs_chartvalid); + end; + int1:= high(asamples); + if int1 >= ftraces.count then begin + int1:= ftraces.count-1; + end; + for int1:= 0 to int1 do begin + ttrace(ftraces.fitems[int1]).addxseriesdata(asamples[int1]); + end; + if chs_hasdialscroll in fstate then begin + inc(fsampleco); + if cto_adddataright in ftraces.options then begin + int1:= 1; + end + else begin + int1:= 0; + if fsampleco >= ftraces.maxcount then begin + int1:= fsampleco-ftraces.maxcount; + fsampleco:= fsampleco - int1; + end; + end; + if (int1 <> 0) and (ftraces.maxcount > 0) then begin + fscrollsum:= fscrollsum + int1; + fshiftsum:= fshiftsum + int1; + rea1:= (fshiftsum)/ftraces.maxcount; + if fscrollsum > ftraces.maxcount then begin + fscrollsum:= fscrollsum - ftraces.maxcount; + end; + rea2:= (fscrollsum)/ftraces.maxcount; + for int1:= 0 to fxdials.count - 1 do begin + with fxdials[int1] do begin + if do_shiftwithdata in options then begin + shift:= rea1*range; + end + else begin + shift:= rea2*range; + end; + end; + end; + end; + end; +end; + +procedure tcustomchart.settraces(const avalue: ttraces); +begin + ftraces.assign(avalue); +end; + +procedure tcustomchart.clientrectchanged; +begin + ftraces.clientrectchanged; + inherited; +end; + +procedure tcustomchart.doclipcontent1(const acanvas: tcanvas); +begin + inherited; + ftraces.clipoverlay(acanvas); +end; + +procedure tcustomchart.dopaintcontent(const acanvas: tcanvas); +var + rect1: rectty; +begin + inherited; + acanvas.save; + rect1:= getdialrect; + inc(rect1.cx); + inc(rect1.cy); + acanvas.intersectcliprect(rect1); + acanvas.move(rect1.pos); + ftraces.paint(acanvas); + acanvas.restore; +// acanvas.remove(innerclientpos); +end; + +procedure tcustomchart.dopaintcontent1(const acanvas: tcanvas); +begin + inherited; + ftraces.paintoverlay(acanvas); +end; + +procedure tcustomchart.setxstart(const avalue: real); +begin + inherited; + ftraces.xstart:= avalue; + fxdials.start:= avalue; +end; + +procedure tcustomchart.setystart(const avalue: real); +begin + inherited; + ftraces.ystart:= avalue; + fydials.start:= avalue; +end; + +procedure tcustomchart.setxrange(const avalue: real); +begin + inherited; + ftraces.xrange:= avalue; + fxdials.range:= avalue; +end; + +procedure tcustomchart.setyrange(const avalue: real); +begin + inherited; + ftraces.yrange:= avalue; + fydials.range:= avalue; +end; + +procedure tcustomchart.dostatread(const reader: tstatreader); +begin + inherited; + ftraces.dostatread(reader); +end; + +procedure tcustomchart.dostatwrite(const writer: tstatwriter); +begin + inherited; + ftraces.dostatwrite(writer); +end; + +function calctracerange(var min: real; const max: real; const log: boolean; + const startmargin: real = 0; const endmargin: real = 0): real; +var + rea1,rea2,rea3: real; + logmin,logmax: real; +begin + rea2:= 1-startmargin-endmargin; + rea1:= max-min; + if log then begin + if min <= 0 then begin + min:= max/100; + end; + if (min > 0) and (max > 0) and (rea1 > 0) and (rea2 > 0.01) then begin + logmin:= ln(min); + logmax:= ln(max); + rea1:= logmax-logmin; + rea2:= 1/rea2; + min:= exp(logmin - startmargin*rea2*rea1); + rea3:= exp(logmax + endmargin*rea2*rea1); + result:= rea3-min; + end + else begin//invalid + min:= 0.1; + result:= 0.9; + end; + end + else begin + if (rea1 = 0) or (rea2 < 0.01) then begin //invalid + result:= min; + if result = 0 then begin + result:= 1; + end; + min:= min - result / 2; + end + else begin + rea2:= 1/rea2; + min:= min - startmargin*rea2*rea1; + rea3:= max + endmargin*rea2*rea1; + result:= rea3 - min; + end; + end; +end; + +procedure tcustomchart.autoscalex(const astartmargin: real = 0; + const aendmargin: real = 0); +var + rea1,rea2: real; + min,max,ra: real; + int1: integer; +begin + min:= bigreal; + max:= -bigreal; + for int1:= 0 to traces.count - 1 do begin + with traces[int1] do begin + minmaxx(rea1,rea2); + if rea1 < min then begin + min:= rea1; + end; + if rea2 > max then begin + max:= rea2; + end; + end; + end; + ra:= calctracerange(min,max,cto_logx in traces.options, + astartmargin,aendmargin); + xstart:= min; + xrange:= ra; +end; + +procedure tcustomchart.autoscaley(const astartmargin: real = 0; + const aendmargin: real = 0); +var + rea1,rea2: real; + min,max,ra: real; + int1: integer; +begin + min:= bigreal; + max:= -bigreal; + for int1:= 0 to traces.count - 1 do begin + with traces[int1] do begin + minmaxy(rea1,rea2); + if rea1 < min then begin + min:= rea1; + end; + if rea2 > max then begin + max:= rea2; + end; + end; + end; + ra:= calctracerange(min,max,cto_logy in traces.options, + astartmargin,aendmargin); + ystart:= min; + yrange:= ra; +end; + +procedure tcustomchart.layoutchanged; +begin + inherited; + ftraces.change; +end; + +procedure tcustomchart.extendfit(const asides: rectsidesty; var aext: rectextty); +var + rect1: rectty; +// int1: integer; +begin + inherited; + with ftraces do begin + if legend_placement in [tlp_above,tlp_below] then begin +// checkgraphic; + rect1:= self.getdialrect; + calclegendrect; + if legend_placement = tlp_above then begin + legend_dist:= rect1.y - aext.top + legend_fitdist; + aext.top:= aext.top - flegendsize.cy - legend_fitdist; + end + else begin + legend_dist:= aext.bottom - rect1.y - rect1.cy + legend_fitdist; + aext.bottom:= aext.bottom + flegendsize.cy + legend_fitdist; + end; + end; + { + if legend_placement in [tlp_above,tlp_below] then begin + checkgraphic; + rect1:= self.getdialrect; + int1:= flegendsize.cy + legend_fitdist; + if legend_placement = tlp_above then begin + legend_dist:= rect1.y - aext.top + legend_fitdist; + aext.top:= aext.top - int1; + end + else begin + legend_dist:= aext.bottom - rect1.y - rect1.cy + legend_fitdist; + aext.bottom:= aext.bottom + int1; + end; + end; + } + end; +end; + +{ trecordertraces } + +constructor trecordertraces.create; +begin + inherited create(trecordertrace); +end; + +class function trecordertraces.getitemclasstype: persistentclassty; +begin + result:= trecordertrace; +end; + +{ trecordertrace } + +constructor trecordertrace.create; +begin + frange:= 1; + fcolor:= cl_glyph; + inherited; +end; + +procedure trecordertrace.setrange(const avalue: real); +begin + checknullrange(avalue); + frange:= avalue; +end; + +{ tchartrecorder } + +constructor tchartrecorder.create(aowner: tcomponent); +begin + fsamplecount:= 100; + fchart:= tmaskedbitmap.create(bmk_rgb{false}); + ftraces:= trecordertraces.create; + inherited; + include(fstate,chs_nocolorchart); +end; + +destructor tchartrecorder.destroy; +begin + fchart.free; + ftraces.free; + inherited; +end; +{ +procedure tchartrecorder.clientrectchanged; +begin + chartchange; + inherited; +end; +} +procedure tchartrecorder.checkinit; +var + int1: integer; + bo1: boolean; +begin + if not (csloading in componentstate) and + not (chs_chartvalid in fstate) then begin + fstate:= fstate - chartrecorderstatesmask; +// fstarted:= false; + bo1:= false; + initscrollstate; + for int1:= 0 to fxdials.count -1 do begin + with fxdials[int1] do begin + if not (do_front in options) then begin + bo1:= true; + end; + end; + end; + if not bo1 then begin + for int1:= 0 to fydials.count -1 do begin + if not (do_front in fydials[int1].options) then begin + bo1:= true; + break; + end; + end; + end; + with fchart do begin + masked:= bo1; + fchartclientrect:= innerclientrect; + fchartwindowrect.size:= fchartclientrect.size; + fchartrect.cx:= fchartclientrect.cx + 10; //room for linewidth + fchartrect.cy:= fchartclientrect.cy; + size:= fchartrect.size; + fstep:= {$ifdef FPC}real({$endif}fchartwindowrect.cx{$ifdef FPC}){$endif} / + fsamplecount; + fstepsum:= 0; + fxref:= fchartwindowrect.x; + if cro_adddataright in foptions then begin + include(fstate,chs_full); + end; + init(actualcolorchart); + canvas.capstyle:= cs_round; + if masked then begin + mask.init(cl_0); + mask.canvas.capstyle:= cs_round; + end; + end; + include(fstate,chs_chartvalid); + end; +end; + +procedure tchartrecorder.dopaintcontent(const acanvas: tcanvas); +begin + checkinit; + fchart.paint(acanvas,fchartclientrect.pos); +// canvas.copyarea(fchart.canvas,fchartwindowrect,fchartclientrect.pos); +end; + +procedure tchartrecorder.setsamplecount(const avalue: integer); +begin + if fsamplecount <> avalue then begin + fsamplecount:= avalue; + if fsamplecount <= 0 then begin + fsamplecount:= 1; + end; + chartchange; + end; +end; + +procedure tchartrecorder.addsample(const asamples: array of real); +var + acanvas,mcanvas: tcanvas; + amasked: boolean; + + procedure shift(const adist: integer); + begin + fshiftsum:= fshiftsum+adist; + fscrollsum:= fscrollsum+adist; + acanvas.copyarea(acanvas,fchartrect,makepoint(-adist,0)); + acanvas.fillrect(makerect(fchartrect.cx-adist,0,adist,fchartrect.cy),fcolorchart); + if amasked then begin + mcanvas.copyarea(mcanvas,fchartrect,makepoint(-adist,0)); + mcanvas.fillrect(makerect(fchartrect.cx-adist,0,adist,fchartrect.cy),cl_0); + end; + end; //shift + +var + int1,int2: integer; + startx,endx,y: integer; + rea1,rea2: real; +begin + mcanvas:= nil; + if (chs_hasdialshift in fstate) and (fshiftsum < 0) then begin + exclude(fstate,chs_chartvalid); + end; + checkinit; + fstepsum:= fstepsum + fstep; + int1:= round(fstepsum); + fstepsum:= fstepsum - int1; + with fchart do begin + acanvas:= canvas; + amasked:= masked; + if amasked then begin + mcanvas:= mask.canvas; + end; + end; + if chs_full in fstate then begin + startx:= fchartwindowrect.cx-int1; + endx:= fchartwindowrect.cx; + shift(int1); + end + else begin + startx:= fxref; + fxref:= fxref+int1; + endx:= fxref; + int1:= endx-fchartwindowrect.cx; + if int1 >= 0 then begin + if int1 <> 0 then begin //should not happen + shift(int1); + startx:= startx-int1; + endx:= endx-int1; + end; + include(fstate,chs_full); + end; + end; + if (chs_hasdialscroll in fstate) and (fchartwindowrect.cx > 0) then begin + rea1:= fshiftsum/fchartwindowrect.cx; + if fscrollsum > fchartwindowrect.cx then begin + fscrollsum:= fscrollsum - fchartwindowrect.cx; + end; + rea2:= fscrollsum/fchartwindowrect.cx; + for int1:= 0 to fxdials.count -1 do begin + with fxdials[int1] do begin + if do_shiftwithdata in options then begin + shift:= rea1*range; + end + else begin + shift:= rea2*range; + end; + end; + end; + end; + int1:= high(asamples); + if int1 > high(ftraces.fitems) then begin + int1:= high(ftraces.fitems); + end; + for int2:= 0 to int1 do begin + with trecordertrace(ftraces.fitems[int2]) do begin + y:= fchartrect.cy - round(fchartrect.cy * ((asamples[int2] - fstart)/frange)); + if chs_started in fstate then begin + acanvas.linewidth:= fwidth; + acanvas.drawline(makepoint(startx,fybefore),makepoint(endx,y),fcolor); + if amasked then begin + mcanvas.linewidth:= fwidth; + mcanvas.drawline(makepoint(startx,fybefore),makepoint(endx,y),cl_1); + end; + end; + fybefore:= y; + end; + end; + invalidaterect(fchartclientrect); + include(fstate,chs_started); +end; + +procedure tchartrecorder.settraces(const avalue: trecordertraces); +begin + ftraces.assign(avalue); +end; + +procedure tchartrecorder.clear; +begin + exclude(fstate,chs_chartvalid); + invalidate; +end; +{ +procedure tchartrecorder.changed; +begin + fchartvalid:= false; + inherited; +end; +} +{ tchartdialshorz } + +function tchartdialshorz.getitemclass: dialcontrollerclassty; +begin + result:= tchartdialhorz; +end; + +procedure tchartdialshorz.setitems(const aindex: integer; + const avalue: tchartdialhorz); +begin + getitems(aindex).assign(avalue); +end; + +function tchartdialshorz.getitems(const aindex: integer): tchartdialhorz; +begin + result:= tchartdialhorz(inherited getitems(aindex)); +end; + +procedure tchartdialshorz.createitem(const index: integer; + var item: tpersistent); +begin + inherited; + with tchartdialhorz(item) do begin + start:= ichartdialcontroller(fintf).getxstart; + range:= ichartdialcontroller(fintf).getxrange; + end; +end; + +class function tchartdialshorz.getitemclasstype: persistentclassty; +begin + result:= tchartdialhorz; +end; + +{ tchartdialsvert } + +function tchartdialsvert.getitemclass: dialcontrollerclassty; +begin + result:= tchartdialvert; +end; + +procedure tchartdialsvert.setitems(const aindex: integer; + const avalue: tchartdialvert); +begin + getitems(aindex).assign(avalue); +end; + +function tchartdialsvert.getitems(const aindex: integer): tchartdialvert; +begin + result:= tchartdialvert(inherited getitems(aindex)); +end; + +procedure tchartdialsvert.createitem(const index: integer; + var item: tpersistent); +begin + inherited; + with tchartdialvert(item) do begin + start:= ichartdialcontroller(fintf).getystart; + range:= ichartdialcontroller(fintf).getyrange; + end; +end; + +class function tchartdialsvert.getitemclasstype: persistentclassty; +begin + result:= tchartdialvert; +end; + +{ tchartdials } + +procedure tchartdials.changed; +var + int1: integer; +begin + for int1:= high(fitems) downto 0 do begin + tcustomdialcontroller1(fitems[int1]).changed; + end; +end; + +procedure tchartdials.paint(const acanvas: tcanvas); +var + int1: integer; +begin + for int1:= high(fitems) downto 0 do begin + tcustomdialcontroller(fitems[int1]).paint(acanvas); + end; +end; + +procedure tchartdials.afterpaint(const acanvas: tcanvas); +var + int1: integer; +begin + for int1:= high(fitems) downto 0 do begin + tcustomdialcontroller(fitems[int1]).afterpaint(acanvas); + end; +end; + +constructor tchartdials.create(const aintf: ichartdialcontroller); +begin + inherited create(aintf); +end; + +procedure tchartdials.setitems(const aindex: integer; + const avalue: tcustomdialcontroller); +begin + inherited getitems(aindex).assign(avalue); +end; + +function tchartdials.getitems(const aindex: integer): tcustomdialcontroller; +begin + result:= tcustomdialcontroller(inherited getitems(aindex)); +end; + +{ txytrace } + +constructor txytrace.create(aowner: tobject); +begin + inherited; +end; + +procedure txytrace.setoptions(const avalue: charttraceoptionsty); +begin + if txytraces(ftraces).fxordered then begin + inherited setoptions(avalue + [cto_xordered]); + end + else begin + inherited; + end; +end; + +procedure txytrace.setkind(const avalue: tracekindty); +begin + inherited setkind(trk_xy); +end; + +{ txytraces } + +constructor txytraces.create(const aowner: tcustomchart; const axordered: boolean); +begin + fxordered:= axordered; + inherited create(aowner); + kind:= trk_xy; + options:= defaultxytraceoptions; +end; + +class function txytraces.getitemclasstype: persistentclassty; +begin + result:= txytrace; +end; + +procedure txytraces.setoptions(const avalue: charttraceoptionsty); +begin + if fxordered then begin + inherited setoptions(avalue + [cto_xordered]); + end + else begin + inherited; + end; +end; + +procedure txytraces.setkind(const avalue: tracekindty); +begin + inherited setkind(trk_xy); +end; + +{ tbarframe } + +constructor tbarframe.create(const aintf: iframe); +begin + inherited; + include(fstate,fs_nowidget); +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/msechartedit.pas b/mseide-msegui/lib/common/widgets/msechartedit.pas new file mode 100644 index 0000000..ef40a34 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msechartedit.pas @@ -0,0 +1,2019 @@ +{ MSEgui Copyright (c) 1999-2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msechartedit; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,msechart,mseguiglob,mseevent,mseeditglob,msegraphutils, + msetypes, + mseobjectpicker,msepointer,msegraphics,mseclasses,msestat,msestatfile, + msestrings,msedial,msegui,msemenus,mseglob; + +const + defaultsnapdist = 4; + markersnapdist = 2; + defaultchartoptionsedit1 = [oe1_checkvalueafterstatread,oe1_savevalue, + oe1_savestate]; + defaultcharteditoptionswidget = defaultchartoptionswidget + [ow_mousefocus]; + +type + setcomplexareventty = procedure(const sender: tobject; + var avalue: complexarty; var accept: boolean) of object; + setrealareventty = procedure(const sender: tobject; + var avalue: realarty; var accept: boolean) of object; + charteditoptionty = (ceo_thumbtrack,ceo_markerthumbtrack, + ceo_noinsert,ceo_nodelete, + ceo_tracehint,ceo_markerhint); + charteditoptionsty = set of charteditoptionty; + + charteditmovestatety = (cems_markermoving,cems_canbottomlimit,cems_cantoplimit, + cems_xbottomlimit,cems_ybottomlimit, + cems_xtoplimit,cems_ytoplimit); + charteditmovestatesty = set of charteditmovestatety; + + tcustomchartedit = class; + tracehinteventty = procedure(const sender: tcustomchartedit; + const atrace,aindex: integer; var ahint: hintinfoty) of object; + markerhinteventty = procedure(const sender: tcustomchartedit; + const isy: boolean; const adial,aindex: integer; + var ahint: hintinfoty) of object; + markerseteventty = procedure(const sender: tcustomchartedit; + const isy: boolean; const adial,aindex: integer; + var avalue: realty) of object; + + tcustomchartedit = class(tcustomchart,iobjectpicker) + private + factivetrace: integer; + foptionsedit: optionseditty; + foptionsedit1: optionsedit1ty; + fobjectpicker: tobjectpicker; + fsnapdist: integer; + foffsetmin: pointty; + foffsetmax: pointty; + fonchange: notifyeventty; + fondataentered: notifyeventty; + foptions: charteditoptionsty; + fpickref: pointty; + fmovestate: charteditmovestatesty; + fmarkermovestartpos: int32; + fontracehint: tracehinteventty; + fonmarkerhint: markerhinteventty; + fnodehintindex: integer; + fnodehinttrace: integer; + fonsetmarker: markerseteventty; + fonmarkerentered: notifyeventty; + procedure setactivetrace(avalue: integer); + function limitmoveoffset(const aoffset: pointty): pointty; + function getreadonly: boolean; + procedure setreadonly(const avalue: boolean); + procedure setoptions(const avalue: charteditoptionsty); + procedure dopickmove(const sender: tobjectpicker); + procedure setoptionsedit(const avalue: optionseditty); + protected + procedure resetnodehint; + function hasactivetrace: boolean; + function nodepos(const atrace: integer; const aindex: integer): pointty; + function nearestnode(const apos: pointty; const all: boolean; + out atrace,aindex: integer): boolean; + function nodesinrect(const arect: rectty): integerarty; + function encodenodes(const atrace: integer; + const aindex: array of integer): integerarty; + function decodenodes(const aitems: integerarty; + out atrace: integer; out aindex: integerarty): boolean; + + function chartcoordxy(const atrace: integer; + const avalue: complexty): pointty; + function tracecoordxy(const atrace: integer; + const apos: pointty): complexty; + function chartcoordxseries(const atrace: integer; + const avalue: xseriesdataty): pointty; + function tracecoordxseries(const atrace: integer; + const apos: pointty): xseriesdataty; + + function encodemarker(const isy: boolean; + const adial,aindex: integer): integerarty; + function decodemarker(const aitems: integerarty; out isy: boolean; + out adial: integer; out aindex: integer): boolean; + function xmarkertochart(const avalue: real; const adial: integer): integer; + function ymarkertochart(const avalue: real; const adial: integer): integer; + function xcharttomarker(const apos: integer; const adial: integer): real; + function ycharttomarker(const apos: integer; const adial: integer): real; + function getmarker(const apos: pointty; const nolimited: boolean; + out isy: boolean; out adial,aindex: integer): boolean; + + procedure tracehint(const atrace,aindex: integer); + procedure markerhint(const apos: pointty; const isy: boolean; + const adial,aindex: integer); + procedure clientmouseevent(var info: mouseeventinfoty); override; + procedure dokeydown(var ainfo: keyeventinfoty); override; + procedure dobeforepaint(const acanvas: tcanvas); override; + procedure doafterpaint(const acanvas: tcanvas); override; + procedure change; + procedure dochange; virtual; + procedure domarkerchange; virtual; + function chartdataxy: complexarty; + function chartdataxseries: realarty; + function activetraceitem: ttrace; + + procedure doreadvalue(const reader: tstatreader); virtual; abstract; + procedure dowritevalue(const writer: tstatwriter); virtual; abstract; + procedure dostatread(const reader: tstatreader); override; + procedure dostatwrite(const writer: tstatwriter); override; + procedure statread; override; + procedure loaded; override; + procedure docheckvalue(var accept: boolean); virtual; abstract; + procedure doclear; virtual; abstract; + procedure drawcrosshaircursor(const canvas: tcanvas; + const center: pointty); virtual; + + //iobjectpicker + function getcursorshape(const sender: tobjectpicker; + var shape: cursorshapety): boolean; + procedure getpickobjects(const sender: tobjectpicker; + var objects: integerarty); + procedure beginpickmove(const sender: tobjectpicker); + procedure pickthumbtrack(const sender: tobjectpicker); + procedure endpickmove(const sender: tobjectpicker); + procedure cancelpickmove(const sender: tobjectpicker); + procedure paintxorpic(const sender: tobjectpicker; const canvas: tcanvas); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure clear; override; + function checkvalue: boolean; + property readonly: boolean read getreadonly write setreadonly; + property activetrace: integer read factivetrace + write setactivetrace default 0; + property optionsedit: optionseditty read foptionsedit write setoptionsedit + default defaultoptionsedit; + property optionsedit1: optionsedit1ty read foptionsedit1 write foptionsedit1 + default defaultchartoptionsedit1; + property snapdist: integer read fsnapdist write fsnapdist + default defaultsnapdist; + property options: charteditoptionsty read foptions + write setoptions default []; + property onchange: notifyeventty read fonchange write fonchange; + property onsetmarker: markerseteventty read fonsetmarker write fonsetmarker; + property onmarkerentered: notifyeventty read fonmarkerentered + write fonmarkerentered; + property ontracehint: tracehinteventty read fontracehint write fontracehint; + property onmarkerhint: markerhinteventty read fonmarkerhint + write fonmarkerhint; + published + property optionswidget default defaultcharteditoptionswidget; + end; + + tcustomxychartedit = class(tcustomchartedit) + private + fonsetvalue: setcomplexareventty; + function getvalue: complexarty; + procedure setvalue(const avalue: complexarty); + function getvalueitems(const index: integer): complexty; + procedure setvalueitems(const index: integer; const avalue: complexty); + function getreitems(const index: integer): real; + procedure setreitems(const index: integer; const avalue: real); + function getimitems(const index: integer): real; + procedure setimitems(const index: integer; const avalue: real); + protected + fvalue: complexarty; + procedure dochange; override; + procedure docheckvalue(var accept: boolean); override; + procedure doreadvalue(const reader: tstatreader); override; + procedure dowritevalue(const writer: tstatwriter); override; + class function xordered: boolean; virtual; + procedure doclear; override; + public + constructor create(aowner: tcomponent); override; + property value: complexarty read getvalue write setvalue; + property valueitems[const index: integer]: complexty read getvalueitems + write setvalueitems; + property reitems[const index: integer]: real read getreitems write setreitems; + property imitems[const index: integer]: real read getimitems write setimitems; + property ondataentered: notifyeventty read fondataentered + write fondataentered; + property onsetvalue: setcomplexareventty read fonsetvalue write fonsetvalue; + end; + + txychartedit = class(tcustomxychartedit) + published + property traces; + property colorchart; + property facechart; + property framechart; + property xstart; + property ystart; + property xrange; + property yrange; + property xdials; + property ydials; + property fitframe_left; + property fitframe_top; + property fitframe_right; + property fitframe_bottom; + property statfile; + property statvarname; + property statpriority; + property onbeforepaint; + property onpaintbackground; + property onpaint; + property onafterpaint; + + property ondataentered; + property onsetvalue; + property activetrace; + property optionsedit; + property optionsedit1; + property snapdist; + property tracehint_captionx; + property tracehint_captiony; + property options; + property optionschart; + property onchange; + property onsetmarker; + property onmarkerentered; + property ontracehint; + property onmarkerhint; + end; + + tcustomorderedxychartedit = class(tcustomxychartedit) + protected + class function xordered: boolean; override; + public + end; + + torderedxychartedit = class(tcustomorderedxychartedit) + published + property traces; + property colorchart; + property facechart; + property framechart; + property xstart; + property ystart; + property xrange; + property yrange; + property xdials; + property ydials; + property fitframe_left; + property fitframe_top; + property fitframe_right; + property fitframe_bottom; + property statfile; + property statvarname; + property statpriority; + property onbeforepaint; + property onpaintbackground; + property onpaint; + property onafterpaint; + + property ondataentered; + property onsetvalue; + property activetrace; + property optionsedit; + property optionsedit1; + property snapdist; + property tracehint_captionx; + property tracehint_captiony; + property options; + property optionschart; + property onchange; + property onsetmarker; + property onmarkerentered; + property ontracehint; + property onmarkerhint; + end; + + tcustomxserieschartedit = class(tcustomchartedit) + private + fonsetvalue: setrealareventty; + function getvalue: realarty; + procedure setvalue(const avalue: realarty); + function getvalueitems(const index: integer): real; + procedure setvalueitems(const index: integer; const avalue: real); + protected + fvalue: realarty; + procedure dochange; override; + procedure docheckvalue(var accept: boolean); override; + procedure doreadvalue(const reader: tstatreader); override; + procedure dowritevalue(const writer: tstatwriter); override; + procedure doclear; override; + public + property value: realarty read getvalue write setvalue; + property valueitems[const index: integer]: real read getvalueitems + write setvalueitems; + public + property ondataentered: notifyeventty read fondataentered + write fondataentered; + property onsetvalue: setrealareventty read fonsetvalue write fonsetvalue; + end; + + txserieschartedit = class(tcustomxserieschartedit) + published + property traces; + property colorchart; + property facechart; + property framechart; + property xstart; + property ystart; + property xrange; + property yrange; + property xdials; + property ydials; + property fitframe_left; + property fitframe_top; + property fitframe_right; + property fitframe_bottom; + property statfile; + property statvarname; + property statpriority; + property onbeforepaint; + property onpaintbackground; + property onpaint; + property onafterpaint; + + property ondataentered; + property onsetvalue; + property activetrace; + property optionsedit; + property optionsedit1; + property snapdist; + property tracehint_captionx; + property tracehint_captiony; + property options; + property optionschart; + property onchange; + property onsetmarker; + property onmarkerentered; + property ontracehint; + property onmarkerhint; + end; + +implementation +uses + msereal,msekeyboard,msedatalist,sysutils,msearrayutils,mseformatstr; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + ttraces1 = class(ttraces); + ttrace1 = class(ttrace); + tdialmarkers1 = class(tdialmarkers); + tdialmarker1 = class(tdialmarker); + tcustomdialcontroller1 = class(tcustomdialcontroller); + tchartdialshorz1 = class(tchartdialshorz); + tchartdialhorz1 = class(tchartdialhorz); + tchartdialsvert1 = class(tchartdialsvert); + tchartdialvert1 = class(tchartdialvert); + +{ tcustomchartedit } + +constructor tcustomchartedit.create(aowner: tcomponent); +begin + fsnapdist:= defaultsnapdist; + foptionsedit:= defaultoptionsedit; + foptionsedit1:= defaultchartoptionsedit1; + resetnodehint; + inherited; + optionswidget:= defaultcharteditoptionswidget; + traces.count:= 1; + fobjectpicker:= tobjectpicker.create(iobjectpicker(self)); + fobjectpicker.options:= [opo_mousemoveobjectquery,opo_rectselect, + opo_multiselect]; +end; + +destructor tcustomchartedit.destroy; +begin + fobjectpicker.free; + inherited; +end; + +procedure tcustomchartedit.setactivetrace(avalue: integer); +begin + if avalue < 0 then begin + avalue:= -1; +// raise exception.create('Negative value'); + end; + factivetrace:= avalue; +// if traces.count <= avalue then begin +// traces.count:= avalue+1; +// end; +end; + +function tcustomchartedit.activetraceitem: ttrace; +begin + result:= nil; + if factivetrace >= 0 then begin + if factivetrace >= traces.count then begin + traces.count:= factivetrace+1; + end; + result:= ttrace(ttraces1(traces).fitems[factivetrace]); + end; +end; + +procedure tcustomchartedit.resetnodehint; +begin + fnodehintindex:= -1; + fnodehinttrace:= -1; +end; + +function tcustomchartedit.hasactivetrace: boolean; +begin + result:= (factivetrace >= 0) and (factivetrace < traces.count) and + traces[factivetrace].visible; +end; + +procedure tcustomchartedit.tracehint(const atrace,aindex: integer); +var + info: hintinfoty; + x,y: real; + mstr1,mstr2: msestring; +begin + fillchar(info,sizeof(info),0); + with info do begin + with posrect do begin + pos:= nodepos(atrace,aindex); + addpoint1(pos,mp(-20,-20)); + cx:= 40; + cy:= 40; + end; + placement:= cp_bottomleft; + end; + with ttrace1(traces[atrace]) do begin + y:= yvalue[aindex]; + if kind = trk_xy then begin + x:= xvalue[aindex]; + end + else begin + x:= aindex; + end; + mstr1:= hintx; + if mstr1 = '' then begin + mstr1:= 'x: '+formatfloatmse(x,''); + end + else begin + mstr1:= formatfloatmse(x,mstr1); + end; + mstr2:= hinty; + if mstr2 = '' then begin + mstr2:= 'y: '+formatfloatmse(y,''); + end + else begin + mstr2:= formatfloatmse(y,mstr2); + end; + info.caption:= mstr1+lineend+mstr2; + end; + if canevent(tmethod(fontracehint)) then begin + fontracehint(self,atrace,aindex,info); + end; + if info.caption <> '' then begin + application.showhint(self,info); + end; +end; + +procedure tcustomchartedit.markerhint(const apos: pointty; const isy: boolean; + const adial,aindex: integer); +var + info: hintinfoty; + mstr1: msestring; + marker1: tdialmarker; + +begin + fillchar(info,sizeof(info),0); + with info do begin + with posrect do begin + pos:= apos; + addpoint1(pos,mp(-20,-20)); + cx:= 40; + cy:= 40; + placement:= cp_bottomleft; + end; + if isy then begin + marker1:= ydials[adial].markers[aindex]; + end + else begin + marker1:= xdials[adial].markers[aindex]; + end; + end; + with marker1 do begin + mstr1:= hintcaption; + if mstr1 = '' then begin + mstr1:= markerhintcaption; + end; + info.caption:= formatfloatmse(value,mstr1) + end; + if canevent(tmethod(fonmarkerhint)) then begin + fonmarkerhint(self,isy,adial,aindex,info); + end; + if info.caption <> '' then begin + application.showhint(self,info); + end; +end; + +procedure tcustomchartedit.clientmouseevent(var info: mouseeventinfoty); +var + co1: complexty; + co2: xseriesdataty; + trace1: integer; + ar1: integerarty; + int1,int2: integer; + bo1: boolean; +begin + if not (es_processed in info.eventstate) then begin + fobjectpicker.mouseevent(info); + if (not (es_processed in info.eventstate) or + (info.eventkind = ek_mousepark)) and + not (csdesigning in componentstate) then begin + case info.eventkind of + ek_mousepark: begin + if ceo_tracehint in foptions then begin + if not decodenodes(fobjectpicker.currentobjects,trace1,ar1) then begin + resetnodehint; + end + else begin + if (ar1[0] <> fnodehintindex) or (trace1 <> fnodehinttrace) then begin + tracehint(trace1,ar1[0]); + exit; +// include(info.eventstate,es_processed); + end; + end; + end; + if (ceo_markerhint in foptions) and + getmarker(info.pos,true,bo1,int1,int2) then begin + markerhint(info.pos,bo1,int1,int2); + exit; +// include(info.eventstate,es_processed); + end; + end; + ek_clientmouseleave: begin + resetnodehint; + end; + ek_buttonpress: begin + if not (oe_readonly in foptionsedit) and + not (ceo_noinsert in foptions) and hasactivetrace and + (info.shiftstate * shiftstatesmask = [ss_left]) then begin + if pointinrect(info.pos,getdialrect) then begin + with activetraceitem do begin + if kind = trk_xseries then begin + co2:= tracecoordxseries(factivetrace,info.pos); + insertxseriesdata(co2); + end + else begin + co1:= tracecoordxy(factivetrace,info.pos); + addxydata(co1.re,co1.im); + end; + end; + include(info.eventstate,es_processed); + checkvalue; + end; + end; + end; + end; + if not (es_processed in info.eventstate) then begin + inherited; + end; + end; + end; +end; + +function tcustomchartedit.xmarkertochart(const avalue: real; + const adial: integer): integer; +var + rect1: rectty; +begin + rect1:= getdialrect; +{$warnings off} + with tcustomdialcontroller1(xdials[adial]) do begin +{$warnings on} + if do_log in options then begin + result:= rect1.x + + chartround(rect1.cx*(chartln(avalue)-flnsstart)/flnrange); + end + else begin + result:= rect1.x + chartround(((avalue-fsstart)/frange)*rect1.cx); + end; + end; +end; + +function tcustomchartedit.ymarkertochart(const avalue: real; + const adial: integer): integer; +var + rect1: rectty; +begin + rect1:= getdialrect; +{$warnings off} + with tcustomdialcontroller1(ydials[adial]) do begin +{$warnings on} + if do_log in options then begin + result:= rect1.y + rect1.cy - + chartround(rect1.cy*(chartln(avalue)-flnsstart)/flnrange); + end + else begin + result:= rect1.y + rect1.cy - chartround(((avalue-fsstart)/frange)*rect1.cy); + end; + end; +end; + +function tcustomchartedit.xcharttomarker(const apos: integer; + const adial: integer): real; +var + rect1: rectty; +begin + rect1:= getdialrect; +{$warnings off} + with tcustomdialcontroller1(xdials[adial]) do begin +{$warnings on} + if do_log in options then begin + result:= exp(((apos - rect1.x) / rect1.cx)*flnrange+flnsstart); + end + else begin + result:= start + ((apos - rect1.x) / rect1.cx)*range; + end; + end; +end; + +function tcustomchartedit.ycharttomarker(const apos: integer; + const adial: integer): real; +var + rect1: rectty; +begin + rect1:= getdialrect; +{$warnings off} + with tcustomdialcontroller1(ydials[adial]) do begin +{$warnings on} + if do_log in options then begin + result:= exp( + ((rect1.y+rect1.cy-apos) / rect1.cy)*flnrange+flnsstart); + end + else begin + result:= start + ((rect1.y+rect1.cy-apos) / rect1.cy)*range; + end; + end; +end; + +function tcustomchartedit.tracecoordxy(const atrace: integer; + const apos: pointty): complexty; +var + rect1: rectty; +begin + if (atrace >= 0) and (atrace < ftraces.count) then begin + rect1:= getdialrect; + with ttrace1(traces[atrace]) do begin + if rect1.cx <= 0 then begin + result.re:= xstart; + end + else begin + if cto_logx in options then begin + result.re:= exp(((apos.x - rect1.x) / rect1.cx)*flnxrange+flnxstart); + end + else begin + result.re:= xstart + ((apos.x - rect1.x) / rect1.cx)*xrange; + end; + end; + if rect1.cy <= 0 then begin + result.im:= ystart; + end + else begin + if cto_logy in options then begin + result.im:= exp( + ((rect1.y+rect1.cy-apos.y) / rect1.cy)*flnyrange+flnystart); + end + else begin + result.im:= ystart + ((rect1.y+rect1.cy-apos.y) / rect1.cy)*yrange; + end; + end; + end; + end + else begin + result:= nullcomplex; + end; +end; + +function tcustomchartedit.tracecoordxseries(const atrace: integer; + const apos: pointty): xseriesdataty; +var + rect1: rectty; +begin + if (atrace >= 0) and (atrace < ftraces.count) then begin + rect1:= getdialrect; + with traces[atrace] do begin + result.index:= 0; + if (count > 0) and (rect1.cx > 0) then begin + if cto_seriescentered in options then begin + result.index:= ((apos.x-rect1.x)*count + rect1.cx div 2) div rect1.cx; + end + else begin + result.index:= ((apos.x-rect1.x)*(count-1)) div rect1.cx; + end; + end; + if rect1.cy <= 0 then begin + result.value:= ystart; + end + else begin + result.value:= ystart + ((rect1.y+rect1.cy-apos.y) / rect1.cy)*yrange; + end; + end; + end + else begin + result.value:= 0; + result.index:= -1; + end; +end; + +function tcustomchartedit.chartcoordxy(const atrace: integer; + const avalue: complexty): pointty; +var + rect1: rectty; + x,y: real; +begin + if (atrace >= 0) and (atrace < ftraces.count) then begin + rect1:= getdialrect; + with ttrace1(traces[atrace]) do begin + if cto_logx in options then begin + x:= rect1.x + (rect1.cx*(chartln(avalue.re)-flnxstart)/flnxrange); + end + else begin + x:= rect1.x + (((avalue.re-xstart)/xrange)*rect1.cx); + end; + if cto_logy in options then begin + y:= rect1.y + rect1.cy - + (rect1.cy*(chartln(avalue.im)-flnystart)/flnyrange); + end + else begin + y:= rect1.y + rect1.cy - (((avalue.im-ystart)/yrange)*rect1.cy); + end; + end; + if x > 100000 then begin + result.x:= 100000; + end + else begin + if x < -100000 then begin + result.x:= -100000; + end + else begin + result.x:= round(x); + end; + end; + if y > 100000 then begin + result.y:= 100000; + end + else begin + if y < -100000 then begin + result.y:= -100000; + end + else begin + result.y:= round(y); + end; + end; + end + else begin + result:= nullpoint; + end; +end; + +function tcustomchartedit.chartcoordxseries(const atrace: integer; + const avalue: xseriesdataty): pointty; +var + rect1: rectty; + y: real; +begin + if (atrace >= 0) and (atrace < ftraces.count) then begin + rect1:= getdialrect; + with ttrace1(traces[atrace]) do begin + if (cto_seriescentered in options) or (count = 1) then begin + result.x:= rect1.x + (avalue.index * rect1.cx+rect1.cx div 2) div count; + end + else begin + result.x:= rect1.x + (avalue.index * rect1.cx) div (count-1); + end; + if cto_logy in options then begin + y:= rect1.y + rect1.cy - + (rect1.cy*(chartln(avalue.value)-flnystart)/flnyrange); + end + else begin + y:= rect1.y + rect1.cy - (((avalue.value-ystart)/yrange)*rect1.cy); + end; + if y > 100000 then begin + result.y:= 100000; + end + else begin + if y < -100000 then begin + result.y:= -100000; + end + else begin + result.y:= round(y); + end; + end; + end; + end + else begin + result:= nullpoint; + end; +end; + +function tcustomchartedit.nodepos(const atrace: integer; + const aindex: integer): pointty; +begin + if (atrace >= 0) and (atrace < ftraces.count) then begin + with traces[atrace] do begin + if kind = trk_xseries then begin + result:= chartcoordxseries(atrace,makexseriesdata(yvalue[aindex],aindex)); + end + else begin + result:= chartcoordxy(atrace,xyvalue[aindex]); + end; + end; + end + else begin + result:= nullpoint; + end; +end; + +function tcustomchartedit.nearestnode(const apos: pointty; const all: boolean; + out atrace,aindex: integer): boolean; +var + dist: integer; + + function checkdist(const atrace: integer): integer; + //todo: optimze for ordered data + var + int1: integer; + + procedure handlepoint(const pt1: pointty); + var + int2,int3: integer; + begin + int2:= apos.x - pt1.x; + if abs(int2) > fsnapdist then begin + exit; + end; + int3:= apos.y - pt1.y; + if abs(int3) > fsnapdist then begin + exit; + end; + int2:= int2*int2; + int3:= int3*int3; + int3:= int2+int3; + if int3 < dist then begin + dist:= int3; + result:= int1; + end; + end; //handlepoint + + var + datahigh: integer; + px,py: preal; + pxy: pcomplexty; + begin + result:= -1; + with ftraces[atrace] do begin + if visible then begin + datahigh:= count-1; + if kind = trk_xseries then begin + py:= ydatapo; + if py <> nil then begin + for int1:= 0 to datahigh do begin + handlepoint(chartcoordxseries(atrace,makexseriesdata(py^,int1))); + inc(py); + end; + end; + end + else begin + pxy:= xydatapo; + if pxy <> nil then begin + for int1:= 0 to datahigh do begin + handlepoint(chartcoordxy(atrace,pxy^)); + inc(pxy); + end; + end + else begin + px:= xdatapo; + py:= ydatapo; + if (px <> nil) and (py <> nil) then begin + for int1:= 0 to datahigh do begin + handlepoint(chartcoordxy(atrace,makecomplex(px^,py^))); + inc(px); + inc(py); + end; + end; + end; + end; + end; + end; + end; //checkdist + +var + int1,int2: integer; + +begin + aindex:= 0; + dist:= maxint; + if hasactivetrace and not all then begin + atrace:= factivetrace; + aindex:= checkdist(factivetrace); + end + else begin + if hasactivetrace then begin + aindex:= checkdist(factivetrace); + atrace:= factivetrace; + end; + for int1:= 0 to traces.count-1 do begin + int2:= checkdist(int1); + if int2 >= 0 then begin + aindex:= int2; + atrace:= int1; + end; + end; + end; + if (dist >= fsnapdist*fsnapdist) then begin + aindex:= -1; + atrace:= -1; + end; + result:= aindex >= 0; +end; + +function tcustomchartedit.nodesinrect(const arect: rectty): integerarty; +var + px,py: preal; + pxy: pcomplexty; + int1,int2: integer; +begin + result:= nil; + if hasactivetrace then begin + with traces[factivetrace] do begin + int2:= 0; + setlength(result,count); + if kind = trk_xseries then begin + py:= ydatapo; + if py <> nil then begin + for int1:= 0 to high(result) do begin + if pointinrect(chartcoordxseries(factivetrace, + makexseriesdata(py^,int1)),arect) then begin + result[int2]:= int1; + inc(int2); + end; + inc(py); + end; + end; + end + else begin + pxy:= xydatapo; + if pxy <> nil then begin + for int1:= 0 to high(result) do begin + if pointinrect(chartcoordxy(factivetrace,pxy^),arect) then begin + result[int2]:= int1; + inc(int2); + end; + inc(pxy); + end; + end + else begin + px:= xdatapo; + py:= ydatapo; + if (px <> nil) and (py <> nil) then begin + for int1:= 0 to high(result) do begin + if pointinrect(chartcoordxy(factivetrace, + makecomplex(px^,py^)),arect) then begin + result[int2]:= int1; + inc(int2); + end; + inc(px); + inc(py); + end; + end; + end; + end; + setlength(result,int2); + end; + end; +end; + +function tcustomchartedit.getcursorshape(const sender: tobjectpicker; + var shape: cursorshapety): boolean; +var + int1: integer; + bo1: boolean; +begin + result:= not (cems_markermoving in fmovestate) and sender.moving and + sender.hascurrentobjects; + if result then begin + shape:= cr_none; + end + else begin + if not sender.hascurrentobjects or (cems_markermoving in fmovestate) then begin + result:= getmarker(sender.pickrect.pos,false,bo1,int1,int1); + if result then begin + if bo1 then begin + shape:= cr_sizever; + end + else begin + shape:= cr_sizehor; + end; + end; + end; + end; +end; + +function tcustomchartedit.encodenodes(const atrace: integer; + const aindex: array of integer): integerarty; +var + int1,int2: integer; +begin + int2:= 0; + for int1:= 0 to atrace - 1 do begin + int2:= int2 + ftraces[int1].count; + end; + setlength(result,length(aindex)); + for int1:= 0 to high(result) do begin + result[int1]:= int2 + aindex[int1]; + end; +end; + +function tcustomchartedit.decodenodes(const aitems: integerarty; + out atrace: integer; out aindex: integerarty): boolean; +var + int1,int2,int3: integer; + min,max: integer; +begin + min:= 0; + max:= 0; + atrace:= -1; + setlength(aindex,length(aitems)); + for int1:= 0 to high(aindex) do begin + int2:= aitems[int1]; + if int2 >= 0 then begin + if atrace < 0 then begin + min:= 0; + max:= 0; + for int3:= 0 to ftraces.count - 1 do begin + min:= max; + max:= max + ttrace(ttraces1(ftraces).fitems[int3]).count; + atrace:= int3; + if max > int2 then begin + break; + end; + end; + max:= max-min; + end; + int2:= int2 - min; + if (int2 < 0) or (int2 >= max) then begin //in other trace, invalid + aindex:= nil; + atrace:= -1; + break; + end; + end; + aindex[int1]:= int2; + end; + result:= atrace >= 0; +end; + +procedure tcustomchartedit.getpickobjects(const sender: tobjectpicker; + var objects: integerarty); +var + int1,int2: integer; + bo1: boolean; + rect: rectty; +begin + objects:= nil; + rect:= sender.pickrect; + if sender.rectselecting then begin + if not readonly then begin + objects:= encodenodes(factivetrace,nodesinrect(rect)); + end; + end + else begin + if nearestnode(rect.pos,false,int1,int2) then begin + objects:= encodenodes(int1,int2); + end + else begin + if sender.picking then begin + if getmarker(sender.pickpos,false,bo1,int1,int2) then begin + objects:= encodemarker(bo1,int1,int2); + end; + end; + end; + end; +end; + +function tcustomchartedit.limitmoveoffset(const aoffset: pointty): pointty; +begin + result:= addpoint(aoffset,fpickref); + fmovestate:= fmovestate - [cems_xbottomlimit,cems_ybottomlimit, + cems_xtoplimit,cems_ytoplimit]; + if ops_moving in fobjectpicker.state then begin + if result.x > foffsetmax.x then begin + result.x:= foffsetmax.x; + include(fmovestate,cems_xtoplimit); + end; + if result.y > foffsetmax.y then begin + result.y:= foffsetmax.y; + include(fmovestate,cems_ytoplimit); + end; + if result.x < foffsetmin.x then begin + result.x:= foffsetmin.x; + include(fmovestate,cems_xbottomlimit); + end; + if result.y < foffsetmin.y then begin + result.y:= foffsetmin.y; + include(fmovestate,cems_ybottomlimit); + end; + end; + subpoint1(result,fpickref); +end; + +procedure tcustomchartedit.beginpickmove(const sender: tobjectpicker); +var + rect1: rectty; + int1,int2,int3,int4: integer; + mi,ma: pointty; + pt1: pointty; + ar1: pointarty; + objs: integerarty; + trace1: integer; + isy: boolean; + dial1,index1: integer; +begin + objs:= nil; + ar1:= nil; + trace1:= 0; + fpickref:= nullpoint; + rect1:= getdialrect; + mi.x:= maxint; + mi.y:= maxint; + ma.x:= minint; + ma.y:= minint; + if decodemarker(sender.currentobjects,isy,dial1,index1) then begin + fobjectpicker.thumbtrack:= ceo_markerthumbtrack in options; + include(fmovestate,cems_markermoving); + fmovestate:= fmovestate - [cems_canbottomlimit,cems_cantoplimit]; + with rect1 do begin + if isy then begin + with ydials[dial1].markers[index1] do begin + int3:= pos; + fmarkermovestartpos:= int3; + ma.y:= y-int3; + mi.y:= y+cy-int3; + if (dmo_ordered in options) then begin + if index1 < ydials[dial1].markers.count - 1 then begin + int4:= ydials[dial1].markers[index1+1].pos; + if int4 > y then begin + ma.y:= int4-int3; + include(fmovestate,cems_canbottomlimit); + end; + end; + if index1 > 0 then begin + int4:= ydials[dial1].markers[index1-1].pos; + if int4 < y+cy then begin + mi.y:= int4-int3; + include(fmovestate,cems_cantoplimit); + end; + end; + end; + end; + end + else begin //x + with xdials[dial1].markers[index1] do begin + int3:= pos; + fmarkermovestartpos:= int3; + ma.x:= x-int3; + mi.x:= x+cx-int3; + if (dmo_ordered in options) then begin + if index1 > 0 then begin + int4:= xdials[dial1].markers[index1-1].pos; + if int4 > x then begin + ma.x:= int4-int3; + include(fmovestate,cems_canbottomlimit); + end; + end; + if index1 < xdials[dial1].markers.count - 1 then begin + int4:= xdials[dial1].markers[index1+1].pos; + if int4 < x+cx then begin + mi.x:= int4-int3; + include(fmovestate,cems_cantoplimit); + end; + end; + end; + end; + end; + end; + end + else begin + exclude(fmovestate,cems_markermoving); + fobjectpicker.thumbtrack:= ceo_thumbtrack in options; + if readonly then begin + sender.clear; + exit; + end + else begin + if decodenodes(sender.currentobjects,trace1,objs) then begin + setlength(ar1,length(objs)); + for int1:= 0 to high(objs) do begin + pt1:= nodepos(trace1,objs[int1]); + ar1[int1]:= pt1; + if pt1.x < mi.x then begin + mi.x:= pt1.x; + end; + if pt1.y < mi.y then begin + mi.y:= pt1.y; + end; + if pt1.x > ma.x then begin + ma.x:= pt1.x; + end; + if pt1.y > ma.y then begin + ma.y:= pt1.y; + end; + end; + end; + end; + end; + if cems_markermoving in fmovestate then begin + foffsetmin:= ma; + foffsetmax:= mi; + end + else begin + with rect1 do begin + foffsetmin.x:= x - mi.x; + foffsetmin.y:= y - mi.y; + foffsetmax.x:= x + cx - ma.x; + foffsetmax.y:= y + cy - ma.y; + end; + with ftraces[trace1] do begin + if kind = trk_xseries then begin + foffsetmin.x:= 0; + foffsetmax.x:= 0; + end + else begin + if cto_xordered in options then begin + //limit to neighbours + for int1:= 0 to high(ar1) do begin + int2:= objs[int1]; + if (int2 > 0) and ((int1 = 0) or (objs[int1-1] <> int2 - 1)) then begin + pt1:= nodepos(trace1,int2-1); + int3:= pt1.x - ar1[int1].x; + if int3 > foffsetmin.x then begin + foffsetmin.x:= int3; + end; + end; + int4:= ftraces[trace1].count - 1; + if (int2 < int4) and ((int1 = high(ar1)) or + (objs[int1+1] <> int2 + 1)) then begin + pt1:= nodepos(trace1,int2+1); + int3:= pt1.x - ar1[int1].x; + if int3 < foffsetmax.x then begin + foffsetmax.x:= int3; + end; + end; + end; + end; + end; + end; + end; +end; + +function tcustomchartedit.encodemarker(const isy: boolean; + const adial,aindex: integer): integerarty; +begin + setlength(result,1); + result[0]:= (-2*(aindex+1)) and ((not adial shl 24) or $80fffffe); + if isy then begin + inc(result[0]); + end; +end; + +function tcustomchartedit.decodemarker(const aitems: integerarty; + out isy: boolean; out adial,aindex: integer): boolean; +begin + result:= (high(aitems) = 0) and (aitems[0] < 0); + if result then begin + aindex:= aitems[0]; + isy:= odd(aindex); + adial:= (not aindex and $7f000000) shr 24; + aindex:= integer(-((aindex or $7f000000) and $fffffffe)) div 2 - 1; +// end +// else begin +// aindex:= -1; +// adial:= -1; +// isy:= false; + end; +end; + +procedure tcustomchartedit.dopickmove(const sender: tobjectpicker); +var + int1,int2: integer; + pt1: pointty; + rea1: real; + da1: xseriesdataty; + co1,co2: complexty; + offs: pointty; + objs: integerarty; + marker1: tdialmarker; + trace1,tracebefore: integer; + dialindex: integer; + bo1: boolean; + +begin + offs:= limitmoveoffset(subpoint(sender.pickoffset,fpickref)); + if cems_markermoving in fmovestate then begin + decodemarker(sender.currentobjects,bo1,dialindex,int1); + if bo1 then begin + marker1:= ydials[dialindex].markers[int1]; + if fmovestate * [cems_cantoplimit,cems_ytoplimit] = + [cems_cantoplimit,cems_ytoplimit] then begin + marker1.value:= ydials[dialindex].markers[int1-1].value; + //y is screen reversed + end + else begin + if fmovestate * [cems_canbottomlimit,cems_ybottomlimit] = + [cems_canbottomlimit,cems_ybottomlimit] then begin + marker1.value:= ydials[dialindex].markers[int1+1].value; + //y is screen reversed + end + else begin + if offs.y <> 0 then begin + rea1:= ycharttomarker(fmarkermovestartpos+offs.y,dialindex); + if canevent(tmethod(fonsetmarker)) then begin + fonsetmarker(self,true,dialindex,int1,realty(rea1)); + end; + marker1.value:= rea1; + domarkerchange; + if canevent(tmethod(fonmarkerentered)) then begin + fonmarkerentered(self); + end; + end; + end; + end; + end + else begin + marker1:= xdials[dialindex].markers[int1]; + if fmovestate * [cems_cantoplimit,cems_xtoplimit] = + [cems_cantoplimit,cems_xtoplimit] then begin + marker1.value:= xdials[dialindex].markers[int1+1].value; + end + else begin + if fmovestate * [cems_canbottomlimit,cems_xbottomlimit] = + [cems_canbottomlimit,cems_xbottomlimit] then begin + marker1.value:= xdials[dialindex].markers[int1-1].value; + end + else begin + if offs.x <> 0 then begin + rea1:= xcharttomarker(fmarkermovestartpos + offs.x,dialindex); + if canevent(tmethod(fonsetmarker)) then begin + fonsetmarker(self,false,dialindex,int1,realty(rea1)); + end; + marker1.value:= rea1; + domarkerchange; + if canevent(tmethod(fonmarkerentered)) then begin + fonmarkerentered(self); + end; + end; + end; + end; + end; + end + else begin + addpoint1(fpickref,offs); + if decodenodes(sender.currentobjects,trace1,objs) then begin + tracebefore:= activetrace; + activetrace:= trace1; + try + with activetraceitem do begin + if kind = trk_xseries then begin + for int1:= 0 to high(objs) do begin + int2:= objs[int1]; + pt1:= nodepos(trace1,int2); + rea1:= yvalue[int2]; + da1:= tracecoordxseries(trace1,addpoint(pt1,offs)); + if offs.y <> 0 then begin //no rounding if nochange + rea1:= da1.value; + end; + yvalue[int2]:= rea1; + end; + end + else begin + for int1:= 0 to high(objs) do begin + int2:= objs[int1]; + pt1:= nodepos(trace1,int2); + co1:= xyvalue[int2]; + co2:= tracecoordxy(trace1,addpoint(pt1,offs)); + if offs.x <> 0 then begin //no rounding if nochange + co1.re:= co2.re; + end; + if offs.y <> 0 then begin //no rounding if nochange + co1.im:= co2.im; + end; + xyvalue[int2]:= co1; + end; + end; + end; + checkvalue; + finally + activetrace:= tracebefore; + end; + end; + end; +end; + +procedure tcustomchartedit.pickthumbtrack(const sender: tobjectpicker); +begin +// if not (cems_markermoving in fmovestate) then begin + dopickmove(sender); +// end; +end; + +procedure tcustomchartedit.endpickmove(const sender: tobjectpicker); +begin + dopickmove(sender); + if not (cems_markermoving in fmovestate) and not readonly then begin + addpoint1(sender.mouseeventinfopo^.pos,subpoint(fpickref,sender.pickoffset)); + end; + exclude(fmovestate,cems_markermoving); + fobjectpicker.thumbtrack:= false; +end; + +procedure tcustomchartedit.cancelpickmove(const sender: tobjectpicker); +begin + exclude(fmovestate,cems_markermoving); + fobjectpicker.thumbtrack:= false; +end; + +procedure tcustomchartedit.drawcrosshaircursor(const canvas: tcanvas; + const center: pointty); +begin + with center do begin + canvas.drawline(makepoint(0,y),makepoint(clientwidth,y)); + canvas.drawline(makepoint(x,0),makepoint(x,clientheight)); + end; +end; + +procedure tcustomchartedit.paintxorpic(const sender: tobjectpicker; + const canvas: tcanvas); +var + ar1: pointarty; + ar2: segmentarty; + int1,int2,int3: integer; + dialindex: integer; + offs: pointty; + objs: integerarty; + trace1: integer; + rect1: rectty; + bo1: boolean; +begin + with sender do begin + if cems_markermoving in fmovestate then begin + offs:= limitmoveoffset(pickoffset); +// rect1:= getdialrect; + rect1:= innerclientrect; + decodemarker(sender.currentobjects,bo1,dialindex,int1); + with rect1 do begin + if bo1 then begin + int2:= ydials[dialindex].markers[int1].pos + offs.y; + canvas.drawline(makepoint(x,int2),makepoint(x+cx,int2)); + end + else begin + int2:= xdials[dialindex].markers[int1].pos + offs.x; + canvas.drawline(makepoint(int2,y),makepoint(int2,y+cy)); + end; + end; + end + else begin + if decodenodes(currentobjects,trace1,objs) then begin + if ceo_thumbtrack in foptions then begin + offs:= nullpoint; + end + else begin + offs:= limitmoveoffset(pickoffset); + end; + setlength(ar1,length(objs)); + setlength(ar2,length(objs)*2); //max + int2:= 0; + for int1:= 0 to high(objs) do begin + ar1[int1]:= addpoint(nodepos(trace1,objs[int1]),offs); + int3:= objs[int1]-1; + if int3 >= 0 then begin + ar2[int2].a:= nodepos(trace1,int3); + ar2[int2].b:= ar1[int1]; + if finditem(objs,int3) >= 0 then begin + addpoint1(ar2[int2].a,offs); + end; + inc(int2); + end; + int3:= objs[int1]+1; + if int3 < traces[trace1].count then begin + ar2[int2].a:= ar1[int1]; + ar2[int2].b:= nodepos(trace1,int3); + if finditem(objs,int3) < 0 then begin + inc(int2); + end; + end; + end; + setlength(ar2,int2); + canvas.drawlinesegments(ar2); + for int1:= 0 to high(ar1) do begin + canvas.drawellipse(makerect(ar1[int1],makesize(6,6))); + end; + if (ops_moving in fobjectpicker.state) then begin + if decodenodes(sender.mouseoverobjects,trace1,objs) then begin + drawcrosshaircursor(canvas,addpoint(nodepos(trace1,objs[0]),offs)); + end; + end; + end; + end; + end; +end; + +function tcustomchartedit.getreadonly: boolean; +begin + result:= oe_readonly in foptionsedit; +end; + +procedure tcustomchartedit.setreadonly(const avalue: boolean); +begin + if avalue then begin + optionsedit:= optionsedit + [oe_readonly]; + end + else begin + optionsedit:= optionsedit - [oe_readonly]; + end; +end; + +procedure tcustomchartedit.dokeydown(var ainfo: keyeventinfoty); +var + trace1,tracebefore: integer; + ar1: integerarty; +begin + if not (es_processed in ainfo.eventstate) then begin + inherited; + end; + if not (es_processed in ainfo.eventstate) then begin + fobjectpicker.dokeydown(ainfo); + end; + if not (es_processed in ainfo.eventstate) and (ainfo.key = key_delete) and + not readonly and not (ceo_nodelete in foptions) and + (ainfo.shiftstate*shiftstatesmask = []) and + fobjectpicker.hascurrentobjects then begin + if decodenodes(fobjectpicker.currentobjects,trace1,ar1) then begin + tracebefore:= activetrace; + activetrace:= trace1; + try + activetraceitem.deletedata(ar1); + fobjectpicker.clear; + include(ainfo.eventstate,es_processed); + checkvalue; + finally + activetrace:= tracebefore; + end; + end; + end; +end; + +procedure tcustomchartedit.dobeforepaint(const acanvas: tcanvas); +begin + fobjectpicker.dobeforepaint(acanvas); + inherited; +end; + +procedure tcustomchartedit.doafterpaint(const acanvas: tcanvas); +begin + inherited; + fobjectpicker.doafterpaint(acanvas); +end; + +function tcustomchartedit.chartdataxy: complexarty; +begin + with ttrace1(activetraceitem) do begin + forcexyarray; + result:= copy(xydata); + end; +end; + +function tcustomchartedit.chartdataxseries: realarty; +begin + result:= copy(activetraceitem.ydata); +end; + +procedure tcustomchartedit.dochange; +begin + resetnodehint; + if not (ws_loadedproc in fwidgetstate) then begin + if canevent(tmethod(fonchange)) then begin + fonchange(self); + end; + end; +end; + +procedure tcustomchartedit.domarkerchange; +begin + if not (ws_loadedproc in fwidgetstate) then begin + if canevent(tmethod(fonchange)) then begin + fonchange(self); + end; + end; +end; + +procedure tcustomchartedit.change; +begin + if not (csloading in componentstate) then begin + dochange; + end; +end; + +function tcustomchartedit.checkvalue: boolean; +begin + result:= true; + docheckvalue(result); + if result then begin + if canevent(tmethod(fondataentered)) then begin + fondataentered(self); + end; + end; +end; + +procedure tcustomchartedit.dostatread(const reader: tstatreader); +var + co1: complexty; + pt1: pointty; +begin + if canstatstate(optionsedit1,reader) then begin + inherited; + with frame do begin + co1:= zoom; + co1.re:= reader.readreal('zoomx',co1.re,1,1000); + co1.im:= reader.readreal('zoomy',co1.im,1,1000); + zoom:= co1; + pt1:= scrollpos; + pt1.x:= reader.readinteger('scrollx',pt1.x,-bigint,0); + pt1.y:= reader.readinteger('scrolly',pt1.y,-bigint,0); + scrollpos:= pt1; + end; + activetrace:= reader.readinteger('activetrace',activetrace,0,ftraces.count-1); + end; + if canstatvalue(optionsedit1,reader) then begin + doreadvalue(reader); + end; +end; + +procedure tcustomchartedit.dostatwrite(const writer: tstatwriter); +var + co1: complexty; + pt1: pointty; +begin + if canstatstate(optionsedit1,writer) then begin + inherited; + with frame do begin + co1:= zoom; + writer.writereal('zoomx',co1.re); + writer.writereal('zoomy',co1.im); + pt1:= scrollpos; + writer.writeinteger('scrollx',pt1.x); + writer.writeinteger('scrolly',pt1.y); + end; + writer.writeinteger('activetrace',activetrace); + end; + if canstatvalue(optionsedit1,writer) then begin + dowritevalue(writer); + end; +end; + +procedure tcustomchartedit.statread; +var + rea1: real; + i1,i2: int32; +begin + inherited; + if (oe1_checkvalueafterstatread in foptionsedit1) and hasactivetrace then begin + checkvalue; + if canevent(tmethod(fonsetmarker)) then begin + for i1:= 0 to xdials.count-1 do begin + with tchartdialhorz1(tchartdialshorz1(xdials).fitems[i1]) do begin + for i2:= 0 to markers.count-1 do begin + with tdialmarker1(tdialmarkers1(markers).fitems[i2]) do begin + if dmo_savevalue in options then begin + rea1:= value; + fonsetmarker(self,false,i1,i2,realty(rea1)); + finfo.value:= rea1; + end; + end; + end; + end; + end; + for i1:= 0 to ydials.count-1 do begin + with tchartdialvert1(tchartdialsvert1(ydials).fitems[i1]) do begin + for i2:= 0 to markers.count-1 do begin + with tdialmarker1(tdialmarkers1(markers).fitems[i2]) do begin + if dmo_savevalue in options then begin + rea1:= value; + fonsetmarker(self,true,i1,i2,realty(rea1)); + finfo.value:= rea1; + end; + end; + end; + end; + end; + end; + end; +end; + +procedure tcustomchartedit.setoptions(const avalue: charteditoptionsty); +begin + if avalue <> foptions then begin + foptions:= avalue; + +// with fobjectpicker do begin +// if avalue * [ceo_thumbtrack{,ceo_markerthumbtrack}] <> [] then begin +// options:= options + [opo_thumbtrack]; +// end +// else begin +// options:= options - [opo_thumbtrack]; +// end; +// end; + end; +end; + +procedure tcustomchartedit.loaded; +begin + inherited; + include(fwidgetstate,ws_loadedproc); + try + change; + finally + exclude(fwidgetstate,ws_loadedproc); + end; +end; + +procedure tcustomchartedit.clear; +begin + inherited; + doclear; + change; +end; + +function tcustomchartedit.getmarker(const apos: pointty; + const nolimited: boolean; out isy: boolean; + out adial,aindex: integer): boolean; +var + int1,int3: integer; + marker1: tdialmarker; +begin + result:= false; + for int3:= 0 to xdials.count -1 do begin +{$warnings off} + with tcustomdialcontroller1(xdials[int3]) do begin +{$warnings on} + checklayout; + for int1:= 0 to high(tdialmarkers1(markers).fitems) do begin + marker1:= tdialmarker(tdialmarkers1(markers).fitems[int1]); + if not (dmo_fix in marker1.options) and + (not nolimited or not marker1.limited) and marker1.active and + (abs(apos.x-marker1.pos) <= markersnapdist) then begin + result:= true; + isy:= false; + adial:= int3; + aindex:= int1; + exit; + end; + end; + end; + end; + for int3:= 0 to ydials.count -1 do begin +{$warnings off} + with tcustomdialcontroller1(ydials[int3]) do begin +{$warnings on} + checklayout; + for int1:= 0 to high(tdialmarkers1(markers).fitems) do begin + marker1:= tdialmarker(tdialmarkers1(markers).fitems[int1]); + if not (dmo_fix in marker1.options) and + (not nolimited or not marker1.limited) and marker1.active and + (abs(apos.y-marker1.pos) <= markersnapdist) then begin + result:= true; + isy:= true; + adial:= int3; + aindex:= int1; + exit; + end; + end; + end; + end; +end; + +procedure tcustomchartedit.setoptionsedit(const avalue: optionseditty); +begin + if foptionsedit <> avalue then begin + transferoptionsedit(self,avalue,foptionsedit,foptionsedit1); + if oe_readonly in foptionsedit then begin + fobjectpicker.options:= fobjectpicker.options - [opo_rectselect]; + end + else begin + fobjectpicker.options:= fobjectpicker.options + [opo_rectselect]; + end; + + end; +end; + +{ tcustomxychartedit } + +constructor tcustomxychartedit.create(aowner: tcomponent); +begin + if ftraces = nil then begin + ftraces:= txytraces.create(self,xordered); + end; + inherited; +end; + +function tcustomxychartedit.getvalue: complexarty; +begin + result:= fvalue; +end; + +procedure tcustomxychartedit.setvalue(const avalue: complexarty); +begin + fvalue:= avalue; + change; +end; + +procedure tcustomxychartedit.dochange; +begin + if hasactivetrace then begin + activetraceitem.xydata:= fvalue; + end; + inherited; +end; + +procedure tcustomxychartedit.docheckvalue(var accept: boolean); +var + ar1: complexarty; +begin + ar1:= chartdataxy; + if canevent(tmethod(fonsetvalue)) then begin + fonsetvalue(self,ar1,accept); + end; + if accept then begin + value:= ar1; + end; +end; + +procedure tcustomxychartedit.doreadvalue(const reader: tstatreader); +var + int1: integer; +begin + for int1:= 0 to ftraces.count - 1 do begin + ftraces[int1].xydata:= reader.readarray('value'+inttostrmse(int1), + ftraces[int1].xydata); + end; + if hasactivetrace then begin + value:= activetraceitem.xydata; + end; +// value:= reader.readarray('value',fvalue); +end; + +procedure tcustomxychartedit.dowritevalue(const writer: tstatwriter); +var + int1: integer; +begin + for int1:= 0 to ftraces.count - 1 do begin + writer.writearray('value'+inttostrmse(int1),ftraces[int1].xydata); + end; +// writer.writearray('value',fvalue); +end; + +function tcustomxychartedit.getvalueitems(const index: integer): complexty; +begin + checkarrayindex(fvalue,index); + result:= fvalue[index]; +end; + +procedure tcustomxychartedit.setvalueitems(const index: integer; + const avalue: complexty); +begin + checkarrayindex(fvalue,index); + fvalue[index]:= avalue; + change; +end; + +function tcustomxychartedit.getreitems(const index: integer): real; +begin + checkarrayindex(fvalue,index); + result:= fvalue[index].re; +end; + +procedure tcustomxychartedit.setreitems(const index: integer; const avalue: real); +begin + checkarrayindex(fvalue,index); + fvalue[index].re:= avalue; + change; +end; + +function tcustomxychartedit.getimitems(const index: integer): real; +begin + checkarrayindex(fvalue,index); + result:= fvalue[index].im; +end; + +procedure tcustomxychartedit.setimitems(const index: integer; const avalue: real); +begin + checkarrayindex(fvalue,index); + fvalue[index].im:= avalue; + change; +end; + +class function tcustomxychartedit.xordered: boolean; +begin + result:= false; +end; + +procedure tcustomxychartedit.doclear; +begin + fvalue:= nil; +end; + +{ tcustomxserieschartedit } + +function tcustomxserieschartedit.getvalue: realarty; +begin + result:= fvalue; +// result:= traces[factivetrace].xydata; +end; + +procedure tcustomxserieschartedit.setvalue(const avalue: realarty); +begin + fvalue:= avalue; + change; +end; + +procedure tcustomxserieschartedit.dochange; +begin + if hasactivetrace then begin + activetraceitem.ydata:= fvalue; + end; + inherited; +end; + +procedure tcustomxserieschartedit.docheckvalue(var accept: boolean); +var + ar1: realarty; +begin + ar1:= chartdataxseries; + if canevent(tmethod(fonsetvalue)) then begin + fonsetvalue(self,ar1,accept); + end; + if accept then begin + value:= ar1; + end; +end; + +procedure tcustomxserieschartedit.doreadvalue(const reader: tstatreader); +begin + value:= reader.readarray('value',fvalue); +end; + +procedure tcustomxserieschartedit.dowritevalue(const writer: tstatwriter); +begin + writer.writearray('value',fvalue); +end; + +function tcustomxserieschartedit.getvalueitems(const index: integer): real; +begin + checkarrayindex(fvalue,index); + result:= fvalue[index]; +end; + +procedure tcustomxserieschartedit.setvalueitems(const index: integer; + const avalue: real); +begin + checkarrayindex(fvalue,index); + fvalue[index]:= avalue; + change; +end; + +procedure tcustomxserieschartedit.doclear; +begin + fvalue:= nil; +end; + +{ tcustomorderedxychartedit } + +class function tcustomorderedxychartedit.xordered: boolean; +begin + result:= true; +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/msedial.pas b/mseide-msegui/lib/common/widgets/msedial.pas new file mode 100644 index 0000000..15acf99 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msedial.pas @@ -0,0 +1,3037 @@ +{ MSEgui Copyright (c) 2009-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msedial; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +interface +uses + classes,mclasses,msewidgets,msegraphutils,msegraphics,msegui,msearrayprops, + mseclasses, + msetypes,mseglob,mseguiglob,msestrings,msemenus,mseevent,msestat; + +const + defaultdialcolor = cl_dkgray; + +type + rectsidety = (rs_left,rs_top,rs_right,rs_bottom); + rectsidesty = set of rectsidety; + + dialstatety = (dis_layoutvalid,dis_needstransform); + dialstatesty = set of dialstatety; + + tickcaptionty = record + caption: msestring; + width: integer; + pos: pointty; + angle: real; + end; + tickcaptionarty = array of tickcaptionty; + + tdialpropfont = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + tdialfont = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + dialdatakindty = (dtk_real,dtk_datetime); + + diallineinfoty = record + color: colorty; + widthmm: real; + dashes: string; + indent: integer; + length: integer; + captiondist: integer; + captionoffset: integer; + escapement: real; + font: tdialpropfont; + caption: msestring; + captionunit: msestring; +// kind: dialdatakindty; + end; + + dialtickoptionty = (dto_invisible,dto_opposite,dto_rotatetext, + dto_multiplecaptions, + dto_alignstart,dto_aligncenter,dto_alignend); + //allow captions of different ticks at same position + + dialtickoptionsty = set of dialtickoptionty; + + dialtickinfoty = record + ticks: segmentarty; + ticksreal: realarty; + captions: tickcaptionarty; + intervalco: real; + interval: real; + afont: tfont; + options: dialtickoptionsty; + end; + + tdialprop = class(townedpersistent) + private + fli: diallineinfoty; + procedure setcolor(const avalue: colorty); + procedure setwidthmm(const avalue: real); + procedure setdashes(const avalue: string); + procedure setindent(const avalue: integer); + procedure setlength(const avalue: integer); + procedure setcaption(const avalue: msestring); + procedure setcaptionunit(const avalue: msestring); + procedure setcaptiondist(const avalue: integer); + procedure setcaptionoffset(const avalue: integer); + function getfont: tdialpropfont; + procedure setfont(const avalue: tdialpropfont); + function isfontstored: boolean; + procedure fontchanged(const sender: tobject); + procedure setescapement(const avalue: real); + + protected + flayoutvalid: boolean; + procedure changed; virtual; + function getactcaption(const avalue: real; const aformat: msestring): msestring; + function actualcolor: colorty; + function actualwidthmm: real; + public + constructor create(aowner: tobject); override; + destructor destroy; override; + procedure createfont; + published + property color: colorty read fli.color write setcolor + default cl_default; + property widthmm: real read fli.widthmm write setwidthmm; + //0 -> withmm of dialcontroller + property dashes: string read fli.dashes write setdashes; + property indent: integer read fli.indent + write setindent default 0; + property length: integer read fli.length + write setlength default 0; + //0 -> whole innerclientrect + property caption: msestring read fli.caption write setcaption; + property captionunit: msestring read fli.captionunit write setcaptionunit; + property captiondist: integer read fli.captiondist write setcaptiondist + default 2; + property captionoffset: integer read fli.captionoffset write setcaptionoffset + default 0; + property font: tdialpropfont read getfont write setfont stored isfontstored; + property escapement: real read fli.escapement write setescapement; + end; + + dialmarkeroptionty = (dmo_invisible,dmo_opposite,dmo_back,dmo_rotatetext, + dmo_bar,dmo_barfront, + dmo_hideoverload,dmo_limitoverload,dmo_limitoverloadi, + dmo_hidelimit, + dmo_fix,dmo_ordered,dmo_savevalue); //for tchartedit + dialmarkeroptionsty = set of dialmarkeroptionty; + + tmarkerframe = class(tframe) + public + constructor create(const aintf: iframe); + end; + + markerinfoty = record + active: boolean; + limited: boolean; + line: segmentty; + value: realty; + captionpos: pointty; + aangle: real; + afont: tfont; + acaption: msestring; + options: dialmarkeroptionsty; + barrect: rectty; + bar_color: colorty; + bar_width: integer; + bar_shift: integer; + bar_frame: tframe; + bar_face: tface; + end; + +const + defaultmarkerwidth = 3; + +type + tdialmarker = class(tdialprop,iframe,iface) + private + fhintcaption: msestring; + procedure checklayout; + procedure readvalue(reader: treader); + procedure setvalue(const avalue: realty); + procedure setoptions(const avalue: dialmarkeroptionsty); + function getvisible: boolean; + procedure setvisible(const avalue: boolean); + function getbar_frame: tframe; + procedure setbar_frame(const avalue: tframe); + function getbar_face: tface; + procedure setbar_face(const avalue: tface); + procedure setbar_width(const avalue: integer); + procedure setbar_shift(const avalue: integer); + procedure setbar_color(const avalue: colorty); + protected + finfo: markerinfoty; + procedure defineproperties(filer: tfiler); override; + procedure updatemarker; + //iframe + procedure setframeinstance(instance: tcustomframe); + procedure setstaticframe(value: boolean); + function getstaticframe: boolean; + procedure scrollwidgets(const dist: pointty); + procedure clientrectchanged; + function getcomponentstate: tcomponentstate; + function getmsecomponentstate: msecomponentstatesty; + procedure invalidate; + procedure invalidatewidget; + procedure invalidaterect(const rect: rectty; + const org: originty = org_client; const noclip: boolean = false); + function getwidget: twidget; + function getwidgetrect: rectty; + function getframestateflags: framestateflagsty; + //iface + function translatecolor(const acolor: colorty): colorty; + function getclientrect: rectty; + procedure setlinkedvar(const source: tmsecomponent; var dest: tmsecomponent; + const linkintf: iobjectlink = nil); + procedure widgetregioninvalid; + public + constructor create(aowner: tobject); override; + destructor destroy; override; + procedure createframe; + procedure createface; + function pos: integer; + procedure paint(const acanvas: tcanvas); + property visible: boolean read getvisible write setvisible; + property active: boolean read finfo.active; + property limited: boolean read finfo.limited; + published + property value: realty read finfo.value write setvalue {stored false}; + property options: dialmarkeroptionsty read finfo.options + write setoptions default []; + property hintcaption: msestring read fhintcaption + write fhintcaption; + property bar_color: colorty read finfo.bar_color + write setbar_color default cl_none; + property bar_width: integer read finfo.bar_width write setbar_width + default defaultmarkerwidth; + property bar_shift: integer read finfo.bar_shift write setbar_shift + default 0; + property bar_frame: tframe read getbar_frame write setbar_frame; + property bar_face: tface read getbar_face write setbar_face; + end; + + tcustomdialcontroller = class; + + tdialmarkers = class(townedpersistentarrayprop) + private + function getitems(const aindex: integer): tdialmarker; + procedure changed; + protected + fdim: rectextty; + procedure dosizechanged; override; + public + constructor create(const aowner: tcustomdialcontroller); reintroduce; + procedure paint1(const acanvas: tcanvas); + procedure paint2(const acanvas: tcanvas); + class function getitemclasstype: persistentclassty; override; + property items[const index: integer]: tdialmarker read getitems; default; + end; + + tdialtick = class(tdialprop) + private + finfo: dialtickinfoty; + function getintervalcount: real; + procedure setintervalcount(const avalue: real); + procedure setoptions(const avalue: dialtickoptionsty); + function getinterval: real; + procedure setinterval(const avalue: real); + function isintervalcountstored: boolean; + function isintervalstored: boolean; + function getvisible: boolean; + procedure setvisible(const avalue: boolean); + protected + public + property visible: boolean read getvisible write setvisible; + published + property intervalcount: real read getintervalcount write setintervalcount + stored isintervalcountstored; + //0 -> off + property interval: real read getinterval write setinterval + stored isintervalstored; + //0 -> off + property options: dialtickoptionsty read finfo.options + write setoptions default []; + end; + + tdialticks = class(townedpersistentarrayprop) + private + function getitems(const aindex: integer): tdialtick; + protected + fdim: rectextty; + procedure changed; + procedure change(const index: integer); override; + procedure createitem(const index: integer; var item: tpersistent); override; + public + constructor create(const aowner: tcustomdialcontroller); reintroduce; + class function getitemclasstype: persistentclassty; override; + property items[const index: integer]: tdialtick read getitems; default; + end; + + dialoptionty = (do_invisible,do_opposite,do_sideline,do_boxline,do_log, + do_front,do_smooth,do_scrollwithdata,do_shiftwithdata, + do_savestate); + dialoptionsty = set of dialoptionty; + + idialcontroller = interface(inullinterface) + procedure directionchanged(const dir,dirbefore: graphicdirectionty); + procedure layoutchanged; + function getwidget: twidget; + function getdialrect: rectty; + function getlimitrect: rectty; + end; + + tcustomdialcontroller = class(tvirtualpersistent) + private + fdirection: graphicdirectionty; + fstate: dialstatesty; + fmarkers: tdialmarkers; + fticks: tdialticks; + foptions: dialoptionsty; + fintf: idialcontroller; + ffont: tdialfont; + fcolor: colorty; + fwidthmm: real; + fboxlines: segmentarty; + fstartang,farcang: real; + fsidearc: rectty; + fboxarc: rectty; + fkind: dialdatakindty; + fangle: real; + fa: real; //0.5 * angle in radiant + fr: real; //radius + fscalep: real; //periphery scale, 2/size + foffsr: integer; //radius offset + foffsp: integer; //periphery shift before/after transform + fendr: integer; //radius end for reversed direction + farcscale: real; //factor diallenght arc / diallenght linear + findent1: integer; + findent2: integer; + ffitdist: integer; + procedure setstart(const avalue: real); + procedure setshift(const avalue: real); + procedure setrange(const avalue: real); + procedure setmarkers(const avalue: tdialmarkers); + procedure setoptions(const avalue: dialoptionsty); + procedure setticks(const avalue: tdialticks); + function getfont: tdialfont; + procedure setfont(const avalue: tdialfont); + function isfontstored: boolean; + procedure setcolor(const avalue: colorty); + procedure setwidthmm(const avalue: real); + procedure setkind(const avalue: dialdatakindty); + procedure setangle(const avalue: real); + procedure readstart(reader: treader); + procedure setindent1(const avalue: integer); + procedure setindent2(const avalue: integer); + function getlog: boolean; + procedure setlog(const avalue: boolean); + function getvisible: boolean; + procedure setvisible(const avalue: boolean); + function getopposite: boolean; + procedure setopposite(const avalue: boolean); + function getsideline: boolean; + procedure setsideline(const avalue: boolean); + function getboxline: boolean; + procedure setboxline(const avalue: boolean); + function getfront: boolean; + procedure setfront(const avalue: boolean); + procedure setfitdist(const avalue: integer); + protected + fsstart: real; + flnsstart: real; + fstart: real; + fshift: real; + frange: real; + flnrange: real; + procedure setdirection(const avalue: graphicdirectionty); virtual; + procedure layoutchanged; + procedure changed; + procedure calclineend(const ainfo: diallineinfoty; const aopposite: boolean; + const arect: rectty; out linestart,lineend: integer; + out linedirection: graphicdirectionty; + out adim: rectextty); + procedure adjustcaption(const dir: graphicdirectionty; + const arotatetext: boolean; + const ainfo: diallineinfoty; const afont: tfont; + const stringwidth: integer; var pos: pointty); + procedure checklayout; + procedure invalidate; + procedure fontchanged(const sender: tobject); + procedure transform(var apoint: pointty); + procedure defineproperties(filer: tfiler); override; + function getactdialrect(out arect: rectty): boolean; + procedure paintdial(const acanvas: tcanvas); + public + constructor create(const aintf: idialcontroller); reintroduce; virtual; + destructor destroy; override; + procedure createfont; + procedure paint(const acanvas: tcanvas); + procedure afterpaint(const acanvas: tcanvas); + property options: dialoptionsty read foptions write setoptions default []; + //first! + property visible: boolean read getvisible write setvisible; + property opposite: boolean read getopposite write setopposite; + property sideline: boolean read getsideline write setsideline; + property boxline: boolean read getboxline write setboxline; + property log: boolean read getlog write setlog; + property front: boolean read getfront write setfront; + + property direction: graphicdirectionty read fdirection write setdirection + default gd_right; + property indent1: integer read findent1 write setindent1 default 0; + property indent2: integer read findent2 write setindent2 default 0; + property fitdist: integer read ffitdist write setfitdist default 0; + property start: real read fstart write setstart; + property shift: real read fshift write setshift; //added to start + property range: real read frange write setrange; //default 1.0 + property kind: dialdatakindty read fkind write setkind default dtk_real; + property markers: tdialmarkers read fmarkers write setmarkers; + property ticks: tdialticks read fticks write setticks; + property color: colorty read fcolor write setcolor default defaultdialcolor; + property widthmm: real read fwidthmm write setwidthmm; + //linewidth, default 0.3 + property font: tdialfont read getfont write setfont stored isfontstored; + property angle: real read fangle write setangle; //0 -linear, 1 -> 360 grad + end; + + dialcontrollerclassty = class of tcustomdialcontroller; + + tcustomdialcontrollers = class(tpersistentarrayprop) + private + fstart: real; + frange: real; + procedure setstart(const avalue: real); + procedure setrange(const avalue: real); + protected + fintf: idialcontroller; + function getitemclass: dialcontrollerclassty; virtual; + procedure createitem(const index: integer; var item: tpersistent); override; + procedure changed; + public + constructor create(const aintf: idialcontroller); + procedure dostatread(const reader: tstatreader); + procedure dostatwrite(const writer: tstatwriter); + published + property start: real read fstart write setstart; + property range: real read frange write setrange; + end; + +const + defaultdialcontrolleroptions = [do_opposite]; + +type + tdialcontroller = class(tcustomdialcontroller) + public + constructor create(const aintf: idialcontroller); override; + published + property options default defaultdialcontrolleroptions; //first! + property color; + property widthmm; + property direction; + property indent1; + property indent2; + property start; + property range; + property kind; + property markers; + property ticks; + property font; + property angle; + end; + + optiondialty = (odi_autofitleft,odi_autofittop,odi_autofitright, + odi_autofitbottom); //same layout as rectsidesty + optionsdialty = set of optiondialty; + +const + allrectsides = [rs_left,rs_top,rs_right,rs_bottom]; + rectsidesmask = [odi_autofitleft,odi_autofittop,odi_autofitright, + odi_autofitbottom]; + defaultoptionsdial = [odi_autofitleft,odi_autofittop,odi_autofitright, + odi_autofitbottom]; +type + dialwidgetstatety = (dws_layoutvalid); + dialwidgetstatesty = set of dialwidgetstatety; + + tcustomdial = class(tpublishedwidget,idialcontroller) + private + fdial: tdialcontroller; + ffitframe: framety; + foptions: optionsdialty; + fstate: dialwidgetstatesty; + procedure setdial(const avalue: tdialcontroller); + procedure setfitframe(const avalue: framety); + procedure setfitframe_left(const avalue: integer); + procedure setfitframe_top(const avalue: integer); + procedure setfitframe_right(const avalue: integer); + procedure setfitframe_bottom(const avalue: integer); + procedure setoptions(const avalue: optionsdialty); + protected + procedure dopaintforeground(const acanvas: tcanvas); override; + procedure clientrectchanged; override; + procedure invalidatelayout; + function checklayout: boolean; virtual; //true if changes made + //idialcontroller + procedure layoutchanged; + procedure directionchanged(const dir,dirbefore: graphicdirectionty); + function getdialrect: rectty; + function getlimitrect: rectty; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure paint(const acanvas: tcanvas); override; + function fit(const asides: rectsidesty = allrectsides): boolean; + //adjust fitframe for extents of dial + //returns true if changes made + property dial: tdialcontroller read fdial write setdial; + property fitframe: framety read ffitframe write setfitframe; + property fitframe_left: integer read ffitframe.left + write setfitframe_left default 0; + property fitframe_top: integer read ffitframe.top + write setfitframe_top default 0; + property fitframe_right: integer read ffitframe.right + write setfitframe_right default 0; + property fitframe_bottom: integer read ffitframe.bottom + write setfitframe_bottom default 0; + property options: optionsdialty read foptions write setoptions + default defaultoptionsdial; + published + property color default cl_transparent; + property optionswidget default defaultoptionswidgetnofocus; + end; + + tdial = class(tcustomdial) + published + property dial; + property bounds_cy default 15; + property bounds_cx default 100; + property fitframe_left; + property fitframe_top; + property fitframe_right; + property fitframe_bottom; + property options; + end; + +procedure checknullrange(const avalue: real); +function chartln(const avalue: real): real; + //big neg value for avalue <= 0 +function chartround(const avalue: real): integer; //limit to +-bigint + +implementation +uses + sysutils,msereal,msestreaming,mseformatstr,math,msebits; +type + tcustomframe1 = class(tcustomframe); + twidget1 = class(twidget); + +procedure checknullrange(const avalue: real); +begin + if avalue = 0 then begin + raise exception.create('Range can not be 0.0.'); + end; +end; + +function chartln(const avalue: real): real; +begin + if avalue <= 0 then begin + result:= -100000; + end + else begin + result:= ln(avalue); + end; +end; + +function chartround(const avalue: real): integer; //limit to +-bigint +begin + if avalue > bigint then begin + result:= bigint; + end + else begin + if avalue < -bigint then begin + result:= -bigint; + end + else begin + result:= round(avalue); + end; + end; +end; + +procedure extenddim(const textwidth,asc,desc: integer; const pos: pointty; + var dim: rectextty); +var + int2: integer; +begin + with dim do begin + int2:= pos.x + textwidth; + if pos.x < left then begin + left:= pos.x; + end; + if int2 > right then begin + right:= int2; + end; + if top > pos.y - asc then begin + top:= pos.y - asc; + end; + if bottom < pos.y + desc then begin + bottom:= pos.y + desc; + end; + end; +end; + +{ tdialpropfont } + +class function tdialpropfont.getinstancepo(owner: tobject): pfont; +begin + result:= @tdialprop(owner).fli.font; +end; + +{ tdialfont } + +class function tdialfont.getinstancepo(owner: tobject): pfont; +begin + result:= @tcustomdialcontroller(owner).ffont; +end; + +{ tdialprop } + +constructor tdialprop.create(aowner: tobject); +begin + fli.color:= cl_default; + fli.captiondist:= 2; +// fli.widthmm:= 0.3; + inherited; +end; + +destructor tdialprop.destroy; +begin + fli.font.free; + inherited; +end; + +procedure tdialprop.changed; +begin + flayoutvalid:= false; + tcustomdialcontroller(fowner).layoutchanged; +end; + +procedure tdialprop.setcolor(const avalue: colorty); +begin + if fli.color <> avalue then begin + fli.color:= avalue; + tcustomdialcontroller(fowner).invalidate; + end; +end; + +procedure tdialprop.setwidthmm(const avalue: real); +begin + fli.widthmm:= avalue; +// changed; + tcustomdialcontroller(fowner).invalidate; +end; + +procedure tdialprop.setdashes(const avalue: string); +begin + fli.dashes:= avalue; + tcustomdialcontroller(fowner).invalidate; +end; + +procedure tdialprop.setindent(const avalue: integer); +begin + if fli.indent <> avalue then begin + fli.indent:= avalue; + changed; + end; +end; + +procedure tdialprop.setlength(const avalue: integer); +begin + if fli.length <> avalue then begin + fli.length:= avalue; + changed; + end; +end; + +procedure tdialprop.setcaption(const avalue: msestring); +begin + fli.caption:= avalue; + changed; +end; + +procedure tdialprop.setcaptionunit(const avalue: msestring); +begin + fli.captionunit:= avalue; + changed; +end; + +procedure tdialprop.setcaptiondist(const avalue: integer); +begin + if fli.captiondist <> avalue then begin + fli.captiondist:= avalue; + changed; + end; +end; + +procedure tdialprop.setcaptionoffset(const avalue: integer); +begin + if fli.captionoffset <> avalue then begin + fli.captionoffset:= avalue; + changed; + end; +end; + +procedure tdialprop.fontchanged(const sender: tobject); +begin + changed; +end; + +procedure tdialprop.createfont; +begin + if fli.font = nil then begin + fli.font:= tdialpropfont.create; + fli.font.onchange:= {$ifdef FPC}@{$endif}fontchanged; + end; +end; + +function tdialprop.getfont: tdialpropfont; +begin + getoptionalobject(tcustomdialcontroller(fowner).fintf.getwidget.componentstate, + fli.font,{$ifdef FPC}@{$endif}createfont); + if fli.font <> nil then begin + result:= fli.font; + end + else begin +{$warnings off} + result:= tdialpropfont(tcustomdialcontroller(fowner).getfont); +{$warnings on} + end; +end; + +procedure tdialprop.setfont(const avalue: tdialpropfont); +begin + if avalue <> fli.font then begin + setoptionalobject(tcustomdialcontroller(fowner).fintf.getwidget.componentstate, + avalue,fli.font,{$ifdef FPC}@{$endif}createfont); + changed; + end; +end; + +function tdialprop.isfontstored: boolean; +begin + result:= fli.font <> nil; +end; + +procedure tdialprop.setescapement(const avalue: real); +begin + if avalue <> fli.escapement then begin + fli.escapement:= avalue; + changed; + end; +end; + +function tdialprop.getactcaption(const avalue: real; const aformat: msestring): msestring; +begin + if tcustomdialcontroller(fowner).fkind = dtk_datetime then begin + result:= datetimetostring(avalue,aformat); + end + else begin + result:= formatfloatmse(avalue,aformat); + end; +end; + +function tdialprop.actualcolor: colorty; +begin + result:= fli.color; + if fli.color = cl_default then begin + result:= tcustomdialcontroller(fowner).fcolor; + end; +end; + +function tdialprop.actualwidthmm: real; +begin + result:= fli.widthmm; + if result = 0 then begin + result:= tcustomdialcontroller(fowner).fwidthmm; + end; +end; + +{ tdialmarker } + +constructor tdialmarker.create(aowner: tobject); +begin + finfo.bar_color:= cl_none; + finfo.bar_width:= defaultmarkerwidth; + inherited; +end; + +destructor tdialmarker.destroy; +begin + inherited; + finfo.bar_frame.free; + finfo.bar_face.free; +end; + +procedure tdialmarker.setvalue(const avalue: realty); +begin + if finfo.value <> avalue then begin + finfo.value:= avalue; + changed; + end; +end; + +procedure tdialmarker.paint(const acanvas: tcanvas); + procedure drawbar; + var + rect2: rectty; + begin + if finfo.bar_color <> cl_none then begin + acanvas.fillrect(finfo.barrect,finfo.bar_color); + end; + if finfo.bar_frame <> nil then begin + acanvas.save; + finfo.bar_frame.paintbackground(acanvas,finfo.barrect,true,true); + if finfo.bar_face <> nil then begin + rect2:= deflaterect(finfo.barrect,finfo.bar_frame.innerframe); + acanvas.remove(pointty(finfo.bar_frame.paintframe.topleft)); + finfo.bar_face.paint(acanvas,rect2); + end; + acanvas.restore; + finfo.bar_frame.paintoverlay(acanvas,finfo.barrect); + end + else begin + if finfo.bar_face <> nil then begin + finfo.bar_face.paint(acanvas,finfo.barrect); + end; + end; + end; //drawbar + +begin + checklayout; + with finfo,fli do begin + if active then begin + if not limited or not(dmo_hidelimit in options) then begin + if not (dmo_barfront in options) then begin + drawbar; + end; + acanvas.linewidthmm:= actualwidthmm; + if dashes <> '' then begin + acanvas.dashes:= dashes; + end; + acanvas.drawline(line.a,line.b,actualcolor); + if dashes <> '' then begin + acanvas.dashes:= ''; + end; + if dmo_barfront in options then begin + drawbar; + end; + end; + if caption <> '' then begin + acanvas.drawstring(acaption,captionpos,self.font,false,aangle); + end; + end; + end; +end; + +procedure tdialmarker.checklayout; +begin + if not flayoutvalid then begin + with finfo do begin + active:= not (finfo.value = emptyreal); + if active then begin + updatemarker; + end; + end; + flayoutvalid:= true; + end; +end; + +procedure tdialmarker.readvalue(reader: treader); +begin + value:= readrealty(reader); +end; +{ +procedure tdialmarker.writevalue(writer: twriter); +begin + writerealty(writer,finfo.value); +end; +} +procedure tdialmarker.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('val', + {$ifdef FPC}@{$endif}readvalue,nil,false); +end; + +procedure tdialmarker.updatemarker; +var + rect1: rectty; + + function snap(const avalue: real): integer; + //snap to ticks + var + int1,int2: integer; + begin + with tcustomdialcontroller(fowner) do begin + if not (dis_needstransform in fstate) then begin + with fticks do begin + for int1:= 0 to count - 1 do begin + with tdialtick(fitems[int1]).finfo do begin + for int2:= 0 to high(ticksreal) do begin + if abs(avalue-ticksreal[int2]) < 0.1 then begin + if direction in [gd_right,gd_left] then begin + result:= ticks[int2].a.x; + end + else begin + result:= ticks[int2].a.y; + end; + exit; + end; + end; + end; + end; + end; + end; + result:= round(avalue); + if direction in [gd_right,gd_left] then begin + result:= result + rect1.x; + end + else begin + result:= result + rect1.y; + end; + end; + end; + +var + linestart,lineend: integer; + dir1: graphicdirectionty; + rea1,rea2: real; + start1,stop1: real; + rect2: rectty; + pt1: pointty; + rectext1: rectextty; + int1: integer; + +begin + stop1:= 0; + start1:= 0; + with tcustomdialcontroller(fowner),fli,finfo,line do begin + getactdialrect(rect1); + active:= false; + limited:= false; + if (rect1.cx > 0) and (rect1.cy > 0) then begin + calclineend(fli,dmo_opposite in options,rect1,linestart,lineend,dir1, + rectext1); + if do_log in foptions then begin + rea2:= flnsstart; + rea1:= flnrange; + if rea1 = 0 then begin + exit; + end; + rea1:= (chartln(value) - rea2)/rea1; + end + else begin + rea1:= (value - fsstart)/frange; + end; + if dmo_hideoverload in options then begin + if (rea1 < 0) or (rea1 > 1) then begin + exit; + end; + end; + if dmo_limitoverloadi in options then begin + if rea1 < 0 then begin + rea1:= 0; + limited:= true; + end + else begin + if rea1 > 1 then begin + rea1:= 1; + limited:= true; + end; + end; + end + else begin + if dmo_limitoverload in options then begin + rect2:= fintf.getlimitrect; + case fdirection of + gd_right: begin + start1:= (rect2.x - rect1.x) / rect1.cx; + stop1:= (rect2.x + rect2.cx - rect1.x {- 1}) / rect1.cx; + end; + gd_up: begin + start1:= (rect1.y + rect1.cy - rect2.y - rect2.cy {- 1}) / rect1.cy; + stop1:= (rect1.y + rect1.cy - rect2.y) / rect1.cy; + end; + gd_left: begin + start1:= (rect1.x + rect1.cx - rect2.x - rect2.cx {- 1}) / rect1.cx; + stop1:= (rect1.x + rect1.cx - rect2.x) / rect1.cx; + end; + gd_down: begin + start1:= (rect2.y - rect1.y) / rect1.cy; + stop1:= (rect2.y + rect2.cy - rect1.y {- 1}) / rect1.cy; + end; + end; + if rea1 < start1 then begin + rea1:= start1; + limited:= true; + end + else begin + if rea1 > stop1 then begin + rea1:= stop1; + limited:= true; + end; + end; + end; + end; + case fdirection of + gd_right: begin + a.x:= snap(rect1.cx * rea1); + b.x:= a.x; + a.y:= linestart; + b.y:= lineend; + end; + gd_up: begin + a.y:= snap(rect1.cy - (rect1.cy * rea1)); + b.y:= a.y; + a.x:= linestart; + b.x:= lineend; + end; + gd_left: begin + a.x:= snap(rect1.cx - (rect1.cx * rea1)); + b.x:= a.x; + a.y:= linestart; + b.y:= lineend; + end; + gd_down: begin + a.y:= snap(rect1.cy * rea1); + b.y:= a.y; + a.x:= linestart; + b.x:= lineend; + end; + end; + if dmo_bar in options then begin + case fdirection of + gd_right: begin + barrect.x:= rect1.x; + barrect.cx:= a.x - barrect.x; + barrect.y:= rect1.y + (rect1.cy - bar_width) div 2 + bar_shift; + barrect.cy:= bar_width; + end; + gd_up: begin + barrect.y:= a.y; + barrect.cy:= rect1.y + rect1.cy - barrect.y; + barrect.x:= rect1.x + (rect1.cx - bar_width) div 2 + bar_shift; + barrect.cx:= bar_width; + end; + gd_left: begin + barrect.x:= a.x; + barrect.cx:= rect1.x + rect1.cx - barrect.x; + barrect.y:= rect1.y + (rect1.cy - bar_width) div 2 - bar_shift; + barrect.cy:= bar_width; + end; + gd_down: begin + barrect.y:= rect1.y; + barrect.cy:= a.y - barrect.y; + barrect.x:= rect1.x + (rect1.cx - bar_width) div 2 - bar_shift; + barrect.cx:= bar_width; + end; + end; + end + else begin + if fdirection in [gd_left,gd_right] then begin + barrect.x:= a.x - bar_width div 2; + if fdirection = gd_right then begin + barrect.x:= barrect.x + bar_shift; + end + else begin + barrect.x:= barrect.x - bar_shift; + end; + barrect.cx:= bar_width; + if linestart > lineend then begin + barrect.y:= lineend; + barrect.cy:= linestart-lineend; + end + else begin + barrect.y:= linestart; + barrect.cy:= lineend-linestart; + end; + end + else begin + barrect.y:= a.y - bar_width div 2; + if fdirection = gd_up then begin + barrect.y:= barrect.y - bar_shift; + end + else begin + barrect.y:= barrect.y + bar_shift; + end; + barrect.cy:= bar_width; + if linestart > lineend then begin + barrect.x:= lineend; + barrect.cx:= linestart-lineend; + end + else begin + barrect.x:= linestart; + barrect.cx:= lineend-linestart; + end; + end; + end; + if dmo_rotatetext in self.finfo.options then begin + aangle:= -angle * (rea1-0.5) * 2*pi; + end + else begin + aangle:= 0; + end; + aangle:= aangle + escapement*2*pi; + if caption <> '' then begin + afont:= self.font; + acaption:= getactcaption(value,caption); + captionpos:= a; + int1:= fintf.getwidget.getcanvas.getstringwidth(acaption,afont); + adjustcaption(dir1,dmo_rotatetext in self.finfo.options,fli,afont, + int1,captionpos); + extenddim(int1,afont.ascent,afont.descent,captionpos,fmarkers.fdim); + end; + transform(a); + transform(b); + if dmo_opposite in options then begin + pt1:= a; + a:= b; + b:= pt1; + end; + active:= true; + end; + end; +end; + +procedure tdialmarker.setoptions(const avalue: dialmarkeroptionsty); +begin + if finfo.options <> avalue then begin + finfo.options:= avalue; + changed; + end; +end; + +function tdialmarker.getvisible: boolean; +begin + result:= not (dmo_invisible in finfo.options); +end; + +procedure tdialmarker.setvisible(const avalue: boolean); +begin + if avalue then begin + options:= options - [dmo_invisible]; + end + else begin + options:= options + [dmo_invisible]; + end; +end; + +function tdialmarker.pos: integer; +begin + if tcustomdialcontroller(fowner).direction in [gd_left,gd_right] then begin + result:= finfo.line.a.x; + end + else begin + result:= finfo.line.a.y; + end; +end; + +function tdialmarker.getbar_frame: tframe; +begin + tcustomdialcontroller(fowner).fintf.getwidget.getoptionalobject( + finfo.bar_frame,{$ifdef FPC}@{$endif}createframe); + result:= finfo.bar_frame; +end; + +procedure tdialmarker.setbar_frame(const avalue: tframe); +begin + tcustomdialcontroller(fowner).fintf.getwidget.setoptionalobject( + avalue,finfo.bar_frame,{$ifdef FPC}@{$endif}createframe); + changed; +end; + +procedure tdialmarker.createframe; +begin + if finfo.bar_frame = nil then begin + tmarkerframe.create(iframe(self)); + end; +end; + +procedure tdialmarker.setframeinstance(instance: tcustomframe); +begin + finfo.bar_frame:= tframe(instance); +end; + +procedure tdialmarker.setstaticframe(value: boolean); +begin + //dummy +end; + +function tdialmarker.getstaticframe: boolean; +begin + result:= false; +end; + +procedure tdialmarker.scrollwidgets(const dist: pointty); +begin + //dummy +end; + +procedure tdialmarker.clientrectchanged; +begin + invalidate; +end; + +function tdialmarker.getcomponentstate: tcomponentstate; +begin + result:= tcustomdialcontroller(fowner).fintf.getwidget.componentstate; +end; + +function tdialmarker.getmsecomponentstate: msecomponentstatesty; +begin + result:= tcustomdialcontroller(fowner).fintf.getwidget.msecomponentstate; +end; + +procedure tdialmarker.invalidate; +begin + tcustomdialcontroller(fowner).fintf.getwidget.invalidate; +end; + +procedure tdialmarker.invalidatewidget; +begin + tcustomdialcontroller(fowner).fintf.getwidget.invalidatewidget; +end; + +procedure tdialmarker.invalidaterect(const rect: rectty; + const org: originty = org_client; const noclip: boolean = false); +begin + tcustomdialcontroller(fowner).fintf.getwidget.invalidaterect(rect,org,noclip); +end; + +function tdialmarker.getwidget: twidget; +begin + result:= tcustomdialcontroller(fowner).fintf.getwidget; +end; + +function tdialmarker.getwidgetrect: rectty; +begin + result:= finfo.barrect; +end; + +function tdialmarker.getframestateflags: framestateflagsty; +begin + result:= []; +end; + +function tdialmarker.getbar_face: tface; +begin + tcustomdialcontroller(fowner).fintf.getwidget.getoptionalobject( + finfo.bar_face,{$ifdef FPC}@{$endif}createface); + result:= finfo.bar_face; +end; + +procedure tdialmarker.setbar_face(const avalue: tface); +begin + tcustomdialcontroller(fowner).fintf.getwidget.setoptionalobject( + avalue,finfo.bar_face,{$ifdef FPC}@{$endif}createface); + changed; +end; + +procedure tdialmarker.createface; +begin + if finfo.bar_face = nil then begin + finfo.bar_face:= tface.create(iface(self)); + end; +end; + +function tdialmarker.translatecolor(const acolor: colorty): colorty; +begin + result:= acolor; + if acolor = cl_default then begin + result:= fli.color; + end + else begin + result:= acolor; + end; +end; + +function tdialmarker.getclientrect: rectty; +begin + result:= finfo.barrect; +end; + +procedure tdialmarker.setlinkedvar(const source: tmsecomponent; + var dest: tmsecomponent; const linkintf: iobjectlink = nil); +begin + twidget1(tcustomdialcontroller(fowner).fintf.getwidget).setlinkedvar( + source,dest,linkintf); +end; + +procedure tdialmarker.widgetregioninvalid; +begin + //dummy +end; + +procedure tdialmarker.setbar_width(const avalue: integer); +begin + if finfo.bar_width <> avalue then begin + finfo.bar_width:= avalue; + changed; + end; +end; + +procedure tdialmarker.setbar_shift(const avalue: integer); +begin + if finfo.bar_shift <> avalue then begin + finfo.bar_shift:= avalue; + changed; + end; +end; + +procedure tdialmarker.setbar_color(const avalue: colorty); +begin + if finfo.bar_color <> avalue then begin + finfo.bar_color:= avalue; + changed; + end; +end; + +{ tdialmarkers } + +constructor tdialmarkers.create(const aowner: tcustomdialcontroller); +begin + inherited create(aowner,tdialmarker); +end; + +class function tdialmarkers.getitemclasstype: persistentclassty; +begin + result:= tdialmarker; +end; + +function tdialmarkers.getitems(const aindex: integer): tdialmarker; +begin + result:= tdialmarker(inherited items[aindex]); +end; + +procedure tdialmarkers.paint1(const acanvas: tcanvas); +var + int1: integer; +begin + for int1:= high(fitems) downto 0 do begin + with tdialmarker(fitems[int1]) do begin + if visible and (dmo_back in options) then begin + paint(acanvas); + end; + end; + end; +end; + +procedure tdialmarkers.paint2(const acanvas: tcanvas); +var + int1: integer; +begin + for int1:= high(fitems) downto 0 do begin + with tdialmarker(fitems[int1]) do begin + if visible and not (dmo_back in options) then begin + paint(acanvas); + end; + end; + end; +end; + +procedure tdialmarkers.changed; +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + tdialmarker(fitems[int1]).flayoutvalid:= false; + end; +end; + +procedure tdialmarkers.dosizechanged; +begin + inherited; + tcustomdialcontroller(fowner).changed; +end; + +{ tdialtick } + +procedure tdialtick.setoptions(const avalue: dialtickoptionsty); +{$ifndef FPC} +const + mask1: dialtickoptionsty = [dto_alignstart,dto_aligncenter,dto_alignend]; +{$endif} +begin + if finfo.options <> avalue then begin + finfo.options:= dialtickoptionsty( + {$ifdef FPC} + setsinglebit(longword(avalue),longword(finfo.options), + longword([dto_alignstart,dto_aligncenter,dto_alignend]))); + {$else} + setsinglebit(byte(avalue),byte(finfo.options),byte(mask1))); + {$endif} + changed; + end; +end; + +function tdialtick.getintervalcount: real; +begin + if (finfo.intervalco <> 0) or + (do_log in tcustomdialcontroller(fowner).foptions) then begin + result:= finfo.intervalco; + end + else begin + if finfo.interval <> 0 then begin + result:= tcustomdialcontroller(fowner).range/finfo.interval; + if result > 1000 then begin + result:= 1000; + end; + end + else begin + result:= 0; + end; + end; +end; + +procedure tdialtick.setintervalcount(const avalue: real); +begin + if finfo.intervalco <> avalue then begin + finfo.intervalco:= avalue; + if not (do_log in tcustomdialcontroller(fowner).foptions) then begin + finfo.interval:= 0; + end; + changed; + end; +end; + +function tdialtick.getinterval: real; +begin + if (finfo.interval <> 0) or + (do_log in tcustomdialcontroller(fowner).foptions) then begin + result:= finfo.interval; + end + else begin + if finfo.intervalco <> 0 then begin + result:= tcustomdialcontroller(fowner).range/finfo.intervalco; + end + else begin + result:= 0; + end; + end; +end; + +procedure tdialtick.setinterval(const avalue: real); +begin + if avalue <> finfo.interval then begin + finfo.interval:= avalue; + if not (do_log in tcustomdialcontroller(fowner).foptions) then begin + finfo.intervalco:= 0; + end; + changed; + end; +end; + +function tdialtick.isintervalcountstored: boolean; +begin + result:= (do_log in tcustomdialcontroller(fowner).foptions) or + (finfo.intervalco <> 0); +end; + +function tdialtick.isintervalstored: boolean; +begin + result:= (do_log in tcustomdialcontroller(fowner).foptions) or + (finfo.interval <> 0); +end; + +function tdialtick.getvisible: boolean; +begin + result:= not (dto_invisible in finfo.options); +end; + +procedure tdialtick.setvisible(const avalue: boolean); +begin + if avalue then begin + options:= options - [dto_invisible]; + end + else begin + options:= options + [dto_invisible]; + end; +end; + +{ tdialticks } + +constructor tdialticks.create(const aowner: tcustomdialcontroller); +begin + inherited create(aowner,tdialtick); +end; + +class function tdialticks.getitemclasstype: persistentclassty; +begin + result:= tdialtick; +end; + +function tdialticks.getitems(const aindex: integer): tdialtick; +begin + result:= tdialtick(inherited items[aindex]); +end; + +procedure tdialticks.change(const index: integer); +begin + inherited; + if not (aps_destroying in fstate) then begin + tcustomdialcontroller(fowner).changed; + end; +end; + +procedure tdialticks.createitem(const index: integer; var item: tpersistent); +begin + inherited; + if do_log in tcustomdialcontroller(fowner).foptions then begin + tdialtick(item).interval:= 10; + end; +end; + +procedure tdialticks.changed; +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + tdialtick(fitems[int1]).flayoutvalid:= false; + end; +end; + +{ tcustomdialcontroller } + +constructor tcustomdialcontroller.create(const aintf: idialcontroller); +begin + fintf:= aintf; + fcolor:= defaultdialcolor; + fwidthmm:= 0.3; + frange:= 1.0; + fmarkers:= tdialmarkers.create(self); + fticks:= tdialticks.create(self); +end; + +destructor tcustomdialcontroller.destroy; +begin + fmarkers.free; + fticks.free; + ffont.free; + inherited; +end; + +procedure tcustomdialcontroller.setdirection(const avalue: graphicdirectionty); +var + dir1,dir2: graphicdirectionty; + int1: integer; +begin + if avalue <> fdirection then begin + dir1:= fdirection; + fdirection:= avalue; + if fdirection >= gd_none then begin + fdirection:= pred(fdirection); + end; + dir2:= fdirection; + changed; + if fintf.getwidget.componentstate * + [csreading,csdesigning] = [csdesigning] then begin + with fmarkers do begin + for int1:= 0 to high(fitems) do begin + with tdialmarker(fitems[int1]) do begin + if finfo.bar_frame <> nil then begin + finfo.bar_frame.changedirection(dir1,dir2); + end; + if finfo.bar_face <> nil then begin + finfo.bar_face.fade_direction:= rotatedirection( + finfo.bar_face.fade_direction,dir1,dir2); + end; + end; + end; + end; + end; + fintf.directionchanged(dir2,dir1); + end; +end; + +procedure tcustomdialcontroller.layoutchanged; +begin + fintf.layoutchanged; + exclude(fstate,dis_layoutvalid); +end; + +procedure tcustomdialcontroller.changed; +begin + fmarkers.changed; + fticks.changed; + layoutchanged; +end; + +procedure tcustomdialcontroller.calclineend(const ainfo: diallineinfoty; + const aopposite: boolean; + const arect: rectty; out linestart,lineend: integer; + out linedirection: graphicdirectionty; + out adim: rectextty); +var +// int1: integer; + bo1: boolean; +begin + linestart:= 0; + bo1:= (do_opposite in foptions) xor aopposite; + linedirection:= fdirection; + if bo1 then begin + linedirection:= graphicdirectionty((ord(fdirection)+2) and $3); + end; + with ainfo do begin + case linedirection of + gd_right: begin + linestart:= arect.y + arect.cy - indent {- 1}; + if length = 0 then begin + lineend:= linestart - arect.cy + indent; + end + else begin + lineend:= linestart - length; + end; + end; + gd_up: begin + linestart:= arect.x + arect.cx - indent {- 1}; + if length = 0 then begin + lineend:= linestart - arect.cx + indent; + end + else begin + lineend:= linestart - length; + end; + end; + gd_left: begin + linestart:= arect.y + indent; + if length = 0 then begin + lineend:= linestart + arect.cy - indent; + end + else begin + lineend:= linestart + length; + end; + end; + gd_down: begin + linestart:= arect.x + indent; + if length = 0 then begin + lineend:= linestart + arect.cx - indent; + end + else begin + lineend:= linestart + length; + end; + end; + end; + if linedirection in [gd_up,gd_down] then begin + adim.left:= linestart; + adim.right:= linestart; + adim.top:= arect.y; + adim.bottom:= arect.y + arect.cy; + end + else begin + adim.top:= linestart; + adim.bottom:= linestart; + adim.left:= arect.x; + adim.right:= arect.x + arect.cx; + end; + end; +end; + +procedure tcustomdialcontroller.transform(var apoint: pointty); + procedure trans(var pxy,ryx: integer); + var + r1: real; + p1: real; + begin + r1:= fr - ryx + foffsr; + p1:= fa*((pxy-foffsp)*fscalep); + pxy:= round(r1*sin(p1)) + foffsp; + ryx:= round(r1*(1-cos(p1))) + ryx; + end; +begin + if dis_needstransform in fstate then begin + case fdirection of + gd_left: begin + apoint.y:= fendr - apoint.y; + trans(apoint.x,apoint.y); + apoint.y:= fendr - apoint.y + end; + gd_down: begin + apoint.x:= fendr - apoint.x; + trans(apoint.y,apoint.x); + apoint.x:= fendr - apoint.x + end; + gd_up: begin + trans(apoint.y,apoint.x); + end; + else begin //gd_right + trans(apoint.x,apoint.y); + end; + end; + end; +end; + +procedure tcustomdialcontroller.adjustcaption(const dir: graphicdirectionty; + const arotatetext: boolean; const ainfo: diallineinfoty; + const afont: tfont; const stringwidth: integer; var pos: pointty); + + function adjustscale(const avalue: integer): real; + begin + if fangle = 0 then begin + result:= 1; + end + else begin + if fdirection in [gd_left,gd_down] then begin + result:= fendr - avalue; + end + else begin + result:= avalue; + end; + result:= fr - result + foffsr; + if result = 0 then begin + result:= 1; + end + else begin + result:= farcscale/result; + end; + end; + end; + +begin + with ainfo,pos do begin + case dir of + gd_right: begin + y:= y + captiondist; + x:= x + captionoffset; + if not arotatetext then begin + transform(pos); + end; + if escapement = 0 then begin + y:= y + afont.ascent; + x:= x - round((stringwidth div 2)*adjustscale(y)); + end; + end; + gd_down: begin + x:= x - captiondist; + y:= y + captionoffset; + if not arotatetext then begin + transform(pos); + end; + if escapement = 0 then begin + x:= x - stringwidth; + y:= y + round((afont.ascent - afont.glyphheight div 2)*adjustscale(x)); + end; + end; + gd_left: begin + y:= y - captiondist; + x:= x + captionoffset; + if not arotatetext then begin + transform(pos); + end; + if escapement = 0 then begin + y:= y - afont.descent; + x:= x - round((stringwidth div 2)*adjustscale(y)); + end; + end; + gd_up: begin + x:= x + captiondist; + y:= y + captionoffset; + if not arotatetext then begin + transform(pos); + end; + if escapement = 0 then begin + y:= y + round((afont.ascent - afont.glyphheight div 2)*adjustscale(x)); + end; + end; + end; + end; + if arotatetext then begin + transform(pos); + end; +end; + +procedure tcustomdialcontroller.checklayout; + +const + tolerance = 0.000001; + + function getico(const interval: real; const intervalcount: integer): integer; + begin + result:= intervalcount - + floor((1/interval) * intervalcount * (1 + tolerance)); + //ticks below decade + end; + + function getlogval(const avalue: integer; const interval: real; + const intervalcount: integer): real; + var + ico: integer; + int1: integer; + begin + ico:= getico(interval,intervalcount); + if ico = 0 then begin + result:= 0; + end + else begin + result:= power(interval,avalue div ico); + int1:= avalue mod ico; + if int1 <> 0 then begin + if int1 < 0 then begin + int1:= int1+ico; + result:= result * ((int1+intervalcount-ico)/intervalcount); + end + else begin + result:= result * interval * ((int1+intervalcount-ico)/intervalcount); + end; + end; + end; + end; + + function getlogn(const avalue: real; const interval: real; + const intervalcount: integer): integer; + var + rea1{,rea2}: real; + ico: integer; + begin + if avalue > 0 then begin + result:= floor(logn(interval,avalue) + tolerance); + rea1:= intpower(interval,result+1); + ico:= getico(interval,intervalcount); + result:= floor(result * ico + (avalue/rea1)*intervalcount+tolerance) - + intervalcount + ico; + end + else begin + result:= 0; + end; + end; + +var + asc,desc: integer; + +var + rect1: rectty; + canvas1: tcanvas; + linestart,lineend: integer; + step: real; + offs: real; + first: real; + valstep: real; + int1,int2,int3,int4: integer; + dir1: graphicdirectionty; + boxlines: array[0..1] of segmentty; + bo1: boolean; + rea1,rea2,rea3: real; + po1,po2: prectty; + po3: psegmentty; + horz1: boolean; + islog: boolean; + logstartn,intervalcount1: integer; + ar1: realarty; + ar2: booleanarty; + pt1: pointty; + rectext1: rectextty; + +begin + if not (dis_layoutvalid in fstate) then begin + intervalcount1:= 0; + logstartn:= 0; + first:= 0; + valstep:= 0; + ar1:= nil; + rea1:= 0; + canvas1:= fintf.getwidget.getcanvas; + bo1:= getactdialrect(rect1); + exclude(fstate,dis_needstransform); + fsidearc:= nullrect; + fboxarc:= nullrect; + farcscale:= 1; + horz1:= fdirection in [gd_right,gd_left]; + if fangle <> 0 then begin + if bo1 then begin + int2:= findent1; + end + else begin + int2:= findent2; + end; + with rect1 do begin + fa:= pi*fangle; //0.5 * angle in radiant + if fangle < 0.5 then begin + int1:= round(sin(fa)*int2); + end + else begin + int1:= int2; + end; + if horz1 then begin + x:= x + int1; + cx:= cx - 2 * int1; + foffsr:= y; + int1:= cx; + foffsp:= int1 div 2 + x; + if fdirection = gd_left then begin + fendr:= 2*foffsr + cy; + end; + end + else begin + y:= y + int1; + cy:= cy - 2 * int1; + foffsr:= x; + int1:= cy; + foffsp:= int1 div 2 + y; + if fdirection = gd_down then begin + fendr:= 2*foffsr + cx; + end; + end; + end; + if int1 > 0 then begin + include(fstate,dis_needstransform); + fscalep:= 2.0/int1; + fr:= int1/2.0; + if fangle < 0.5 then begin + fr:= fr/sin(fa); + end; + farcscale:= int1/(fa*2); + end; + int1:= round(abs(fr)); //radius to direction + if int1 < 30000 then begin + int2:= round(2*abs(fr)); //diameter + int3:= 0; //perpendicular to direction + if (fangle < 0) xor (direction in [gd_down,gd_left]) then begin + int3:= -int2; + end; + if (do_opposite in foptions) then begin + po1:= @fsidearc; + po2:= @fboxarc; + end + else begin + po1:= @fboxarc; + po2:= @fsidearc; + end; + case direction of + gd_right: begin + with po1^ do begin //normal circle + x:= foffsp - int1; + cx:= int2; + y:= foffsr + int3; + cy:= cx; + end; + with po2^ do begin //small/big circle + if fangle < 0 then begin + rea1:= 0.5+1; + x:= foffsp - int1 - rect1.cy; + cy:= int2 + rect1.cy + rect1.cy; + y:= foffsr + int3 - rect1.cy; + end + else begin + rea1:= 0.5; + x:= foffsp - int1 + rect1.cy; + cy:= int2 - rect1.cy - rect1.cy; + y:= foffsr + int3 + rect1.cy; + end; + cx:= cy; + end; + end; + gd_up: begin + with po1^ do begin //normal circle + y:= foffsp - int1; + cx:= int2; + x:= foffsr + int3; + cy:= cx; + end; + with po2^ do begin //small/big circle + if fangle < 0 then begin + rea1:= 0; + y:= foffsp - int1 - rect1.cx; + cx:= int2 + rect1.cx + rect1.cx; + x:= foffsr + int3 - rect1.cx; + end + else begin + rea1:= 1; + y:= foffsp - int1 + rect1.cx; + cx:= int2 - rect1.cx - rect1.cx; + x:= foffsr + int3 + rect1.cx; + end; + cy:= cx; + end; + end; + gd_left: begin + with po1^ do begin //normal circle + x:= foffsp - int1; + cx:= int2; + y:= foffsr + int3 + rect1.cy; + cy:= cx; + end; + with po2^ do begin //small/big circle + if fangle < 0 then begin + rea1:= 0.5; + x:= foffsp - int1 - rect1.cy; + cy:= int2 + rect1.cy + rect1.cy; + y:= foffsr + int3; + end + else begin + rea1:= -0.5; + x:= foffsp - int1 + rect1.cy; + cy:= int2 - rect1.cy - rect1.cy; + y:= foffsr + int3 + rect1.cy + rect1.cy; + end; + cx:= cy; + end; + end; + gd_down: begin + with po1^ do begin //normal circle + y:= foffsp - int1; + cy:= int2; + x:= foffsr + int3 + rect1.cx; + cx:= cy; + end; + with po2^ do begin //small/big circle + if fangle < 0 then begin + rea1:= 1; + y:= foffsp - int1 - rect1.cx; + cx:= int2 + rect1.cx + rect1.cx; + x:= foffsr + int3; + end + else begin + rea1:= 0; + y:= foffsp - int1 + rect1.cx; + cx:= int2 - rect1.cx - rect1.cx; + x:= foffsr + int3 + rect1.cx + rect1.cx; + end; + cy:= cx; + end; + end; + end; + fstartang:= pi*(rea1-fangle); + farcang:= 2*pi*fangle; + end; + end; + + with rect1 do begin + if horz1 then begin + boxlines[0].a.x:= x; + boxlines[0].b.x:= x + cx; + boxlines[1].a.x:= boxlines[0].a.x; + boxlines[1].b.x:= boxlines[0].b.x; + + boxlines[0].a.y:= y + cy; + boxlines[0].b.y:= boxlines[0].a.y; + boxlines[1].a.y:= y; + boxlines[1].b.y:= y; + end + else begin + boxlines[0].a.y:= y; + boxlines[0].b.y:= y + cy; + boxlines[1].a.y:= boxlines[0].a.y; + boxlines[1].b.y:= boxlines[0].b.y; + + boxlines[0].a.x:= x + cx; + boxlines[0].b.x:= boxlines[0].a.x; + boxlines[1].a.x:= x; + boxlines[1].b.x:= x; + end; + end; + if do_sideline in foptions then begin + setlength(fboxlines,1); + if bo1 then begin + fboxlines[0]:= boxlines[1]; + end + else begin + fboxlines[0]:= boxlines[0]; + end; + end + else begin + fboxlines:= nil; + end; + if do_boxline in foptions then begin + setlength(fboxlines,high(fboxlines)+2); + if bo1 then begin + fboxlines[high(fboxlines)]:= boxlines[0]; + end + else begin + fboxlines[high(fboxlines)]:= boxlines[1]; + end; + end; + islog:= do_log in foptions; + fticks.fdim:= emptyrectext; + for int4:= 0 to high(fticks.fitems) do begin + with tdialtick(fticks.fitems[int4]) do begin + finfo.afont:= font; + asc:= font.ascent; + desc:= font.descent; + linestart:= 0; //compiler warning + lineend:= 0; //compiler warning + with finfo,fli do begin + if intervalcount <= 0 then begin + ticks:= nil; + end + else begin + calclineend(fli,dto_opposite in options,rect1,linestart,lineend, + dir1,rectext1); + expandrectext1(fticks.fdim,rectext1); + if islog then begin + offs:= -flnsstart; + rea1:= flnrange; + if rea1 = 0 then begin + exit; + end; + step:= 1/rea1; //used for scaling + offs:= offs * step; + intervalcount1:= round(intervalcount); + if interval <= 0 then begin + interval:= 10; + end; + logstartn:= getlogn(fsstart,interval,intervalcount1); + rea1:= getlogval(logstartn,interval,intervalcount1); + if fsstart <> 0 then begin + if (fsstart-rea1)/fsstart > tolerance then begin + inc(logstartn); + end; + end; + rea1:= fsstart + frange; + int1:= getlogn(rea1,interval,intervalcount1); + int1:= int1 - logstartn; + end + else begin + step:= 1/intervalcount; + valstep:= step * frange; + first:= (fsstart*intervalcount)/range; + offs:= frac(first)/intervalcount; //scaled to 1.0 + first:= int(first); + if offs > 0.0001 then begin + offs:= offs - 1.0/intervalcount; + first:= first + 1; + end; + offs:= -offs; + int1:= trunc((1.0001-offs)*intervalcount); + first:= (first * frange) / intervalcount; //real value + end; + inc(int1); + if int1 < 0 then begin + int1:= 0; + end; + system.setlength(ticks,int1); + system.setlength(ticksreal,int1); + if islog then begin + system.setlength(ar1,int1); + end; + if horz1 then begin + step:= rect1.cx * step; + offs:= rect1.cx * offs; + if fdirection = gd_left then begin + step:= - step; + offs:= rect1.cx - offs{ + 1}; + end; + for int1:= 0 to high(ticks) do begin + with ticks[int1] do begin + if islog then begin + ar1[int1]:= getlogval(int1 + logstartn,interval,intervalcount1); + ticksreal[int1]:= chartln(ar1[int1])*step + offs; + end + else begin + ticksreal[int1]:= int1*step + offs; + end; + a.x:= rect1.x + round(ticksreal[int1]); + b.x:= a.x; + a.y:= linestart; + b.y:= lineend; + end; + end; + end + else begin + step:= rect1.cy * step; + offs:= rect1.cy * offs; + if fdirection = gd_up{gd_up} then begin + step:= - step; + offs:= rect1.cy - offs {+ 1}; + end; + for int1:= 0 to high(ticks) do begin + with ticks[int1] do begin + if islog then begin + ar1[int1]:= getlogval(int1 + logstartn,interval,intervalcount1); + ticksreal[int1]:= chartln(ar1[int1]) * step + offs; + end + else begin + ticksreal[int1]:= int1*step + offs; + end; + a.y:= rect1.y + round(ticksreal[int1]); + b.y:= a.y; + a.x:= linestart; + b.x:= lineend; + end; + end; + end; + ar2:= nil; + system.setlength(ar2,system.length(ticks)); + bo1:= not (dto_multiplecaptions in options); + for int1:= 0 to high(ticks) do begin //snap to existing ticks + po3:= nil; + rea1:= ticksreal[int1]; + for int2:= int4-1 downto 0 do begin + with tdialtick(fticks.fitems[int2]).finfo do begin + for int3:= 0 to high(ticks) do begin + if abs(rea1-ticksreal[int3]) < 0.1 then begin + po3:= @ticks[int3]; + ar2[int1]:= bo1 and (captions <> nil); + break; + end; + end; + end; + if (po3 <> nil) and (not bo1 or ar2[int1]) then begin + //else check more captions + break; + end; + end; + if po3 <> nil then begin + if horz1 then begin + with ticks[int1] do begin + a.x:= po3^.a.x; + b.x:= a.x; + end; + end + else begin + with ticks[int1] do begin + a.y:= po3^.a.y; + b.y:= a.y; + end; + end; + end; + end; + if (caption = '') and (captionunit = '') then begin + captions:= nil; + end + else begin + system.setlength(captions,system.length(ticks)); + rea3:= 0; //offset + rea2:= 0; //scale + if dto_rotatetext in options then begin + rea3:= angle*pi; //offset + if horz1 then begin + if rect1.cx <> 0 then begin + rea2:= -angle*2*pi/rect1.cx; + if direction = gd_left then begin + rea2:= -rea2; + rea3:= -rea3; + end; + end; + end + else begin + if rect1.cy <> 0 then begin + rea2:= -angle*2*pi/rect1.cy; + if direction = gd_up then begin + rea2:= -rea2; + rea3:= -rea3; + end; + end; + end; + end; + rea3:= rea3+escapement * 2 * pi; + int2:= -bigint; + bo1:= direction in [gd_left,gd_right]; + for int1:= 0 to high(captions) do begin + if islog then begin + rea1:= ar1[int1]; + end + else begin + rea1:= int1*valstep+first; + if abs(rea1/valstep) < 1e-6 then begin + rea1:= 0; + end; + end; + if ar2[int1] then begin + captions[int1].caption:= ''; + end + else begin + if (captionunit <> '') and (int1 = high(captions) - 1) and + (int1 > 0) then begin + captions[int1].caption:= captionunit; + end + else begin + captions[int1].caption:= getactcaption(rea1,caption); + end; + end; + with captions[int1] do begin + pos:= ticks[int1].a; + width:= canvas1.getstringwidth(caption,afont); + if width > int2 then begin + int2:= width; + end; + adjustcaption(dir1,dto_rotatetext in options,fli,afont, + width,pos); + if bo1 then begin + if dto_alignstart in options then begin + pos.x:= pos.x + width div 2; + end + else begin + if dto_alignend in options then begin + pos.x:= pos.x - width div 2; + end; + end; + end; + angle:= ticksreal[int1] * rea2 + rea3; + extenddim(width,asc,desc,pos,fticks.fdim); + end; + end; + if options * [dto_alignstart,dto_aligncenter,dto_alignend] <> [] then begin + if dto_aligncenter in options then begin + case direction of + gd_up,gd_down: begin + if (dto_opposite in options) xor opposite then begin + for int1:= 0 to high(captions) do begin + with captions[int1] do begin + pos.x:= pos.x - (int2-width) div 2; + end; + end; + end + else begin + for int1:= 0 to high(captions) do begin + with captions[int1] do begin + pos.x:= pos.x + (int2-width) div 2; + end; + end; + end; + end; + end; + end + else begin + if dto_alignend in options then begin + case direction of + gd_up,gd_down: begin + if (dto_opposite in options) xor opposite then begin + for int1:= 0 to high(captions) do begin + with captions[int1] do begin + pos.x:= pos.x - (int2-width); + end; + end; + end + else begin + for int1:= 0 to high(captions) do begin + with captions[int1] do begin + pos.x:= pos.x + (int2-width); + end; + end; + end; + end; + end; + end + else begin + if dto_alignstart in options then begin + end; + end; + end; + end; + //todo: variable unitcaption pos. + end; + end; + end; + end; + end; + if dis_needstransform in fstate then begin + for int4:= 0 to high(fticks.fitems) do begin + with tdialtick(fticks.fitems[int4]).finfo do begin + for int1:= 0 to high(ticks) do begin + with ticks[int1] do begin + transform(a); + transform(b); + end; + end; + end; + end; + end; + for int4:= 0 to high(fticks.fitems) do begin + with tdialtick(fticks.fitems[int4]).finfo do begin + if dto_opposite in options then begin + for int1:= 0 to high(ticks) do begin + with ticks[int1] do begin + pt1:= a; + a:= b; + b:= pt1; + end; + end; + end; + end; + end; + with fmarkers do begin + fdim:= emptyrectext; + for int1:= 0 to count - 1 do begin + with tdialmarker(fitems[int1]) do begin + flayoutvalid:= false; + checklayout; + end; + end; + end; + include(fstate,dis_layoutvalid); + end; +end; + +procedure tcustomdialcontroller.invalidate; +begin + fintf.getwidget.invalidate; +end; + +procedure tcustomdialcontroller.paintdial(const acanvas: tcanvas); +var + int1,int2: integer; +begin + fmarkers.paint1(acanvas); + if visible then begin + if (do_smooth in options) and (angle <> 0) then begin + acanvas.smooth:= true; + end; + for int1:= high(fticks.fitems) downto 0 do begin + with tdialtick(fticks.fitems[int1]),finfo do begin + if visible then begin + if ticks <> nil then begin + acanvas.linewidthmm:= actualwidthmm; + if dashes <> '' then begin + acanvas.dashes:= dashes; + end; + acanvas.drawlinesegments(ticks,actualcolor); + if dashes <> '' then begin + acanvas.dashes:= ''; + end; + end; + for int2:= 0 to high(captions) do begin + with captions[int2] do begin + acanvas.drawstring(caption,pos,afont,false,angle); + end; + end; + end; + end; + end; + end; + fmarkers.paint2(acanvas); + acanvas.linewidth:= 0; + acanvas.smooth:= false; +end; + +procedure tcustomdialcontroller.paint(const acanvas: tcanvas); +begin + checklayout; + if not (do_front in foptions) then begin + paintdial(acanvas); + end; +end; + +procedure tcustomdialcontroller.afterpaint(const acanvas: tcanvas); +begin + if do_front in foptions then begin + paintdial(acanvas); + end; + if foptions * [do_sideline,do_boxline] <> [] then begin + acanvas.capstyle:= cs_projecting; + acanvas.linewidthmm:= fwidthmm; + if fboxarc.cx <> 0 then begin + if do_smooth in options then begin + acanvas.smooth:= true; + end; + if fangle = 1 then begin + if do_boxline in foptions then begin + acanvas.drawellipse1(fboxarc,fcolor); + end; + if do_sideline in foptions then begin + acanvas.drawellipse1(fsidearc,fcolor); + end; + end + else begin + if do_boxline in foptions then begin + acanvas.drawarc1(fboxarc,fstartang,farcang,fcolor); + end; + if do_sideline in foptions then begin + acanvas.drawarc1(fsidearc,fstartang,farcang,fcolor); + end; + end; + acanvas.smooth:= false; + end + else begin + acanvas.drawlinesegments(fboxlines,fcolor); + end; + acanvas.capstyle:= cs_butt; + acanvas.linewidth:= 0; + end; +end; + +procedure tcustomdialcontroller.setstart(const avalue: real); +begin + if fstart <> avalue then begin + fstart:= avalue; + fsstart:= fshift+avalue; + flnsstart:= chartln(fsstart); + flnrange:= chartln(fsstart+frange)-flnsstart; + changed; + end; +end; + +procedure tcustomdialcontroller.setshift(const avalue: real); +begin + if fshift <> avalue then begin + fshift:= avalue; + fsstart:= fstart+avalue; + flnsstart:= chartln(fsstart); + flnrange:= chartln(fsstart+frange)-flnsstart; + changed; + end; +end; + +procedure tcustomdialcontroller.setrange(const avalue: real); +begin + if frange <> avalue then begin + checknullrange(avalue); + frange:= avalue; + flnrange:= chartln(fsstart+frange)-flnsstart; + changed; + end; +end; + +procedure tcustomdialcontroller.setkind(const avalue: dialdatakindty); +begin + if fkind <> avalue then begin + fkind:= avalue; + changed; + end; +end; + +procedure tcustomdialcontroller.setmarkers(const avalue: tdialmarkers); +begin + fmarkers.assign(avalue); +end; + +procedure tcustomdialcontroller.setoptions(const avalue: dialoptionsty); +const + mask: dialoptionsty = [do_scrollwithdata,do_shiftwithdata]; +begin + if foptions <> avalue then begin + foptions:= dialoptionsty( + setsinglebit({$ifdef FPC}longword{$else}word{$endif}(avalue), + {$ifdef FPC}longword{$else}word{$endif}(foptions), + {$ifdef FPC}longword{$else}word{$endif}(mask))); + changed; + end; +end; + +procedure tcustomdialcontroller.setticks(const avalue: tdialticks); +begin + fticks.assign(avalue); +end; + +function tcustomdialcontroller.getfont: tdialfont; +begin + getoptionalobject(fintf.getwidget.componentstate, + ffont,{$ifdef FPC}@{$endif}createfont); + if ffont <> nil then begin + result:= ffont; + end + else begin +{$warnings off} + result:= tdialfont(twidget1(fintf.getwidget).getfont); +{$warnings on} + end; +end; + +procedure tcustomdialcontroller.setfont(const avalue: tdialfont); +begin + if avalue <> ffont then begin + setoptionalobject(fintf.getwidget.componentstate, + avalue,ffont,{$ifdef FPC}@{$endif}createfont); + changed; + end; +end; + +function tcustomdialcontroller.isfontstored: boolean; +begin + result:= ffont <> nil; +end; + +procedure tcustomdialcontroller.createfont; +begin + if ffont = nil then begin + ffont:= tdialfont.create; + ffont.onchange:= {$ifdef FPC}@{$endif}fontchanged; + end; +end; + +procedure tcustomdialcontroller.fontchanged(const sender: tobject); +begin + changed; +end; + +procedure tcustomdialcontroller.setcolor(const avalue: colorty); +begin + if avalue <> fcolor then begin + fcolor:= avalue; + fintf.getwidget.invalidate; + end; +end; + +procedure tcustomdialcontroller.setwidthmm(const avalue: real); +begin + fwidthmm:= avalue; + fintf.getwidget.invalidate; +// changed; +end; + +procedure tcustomdialcontroller.setangle(const avalue: real); +begin + fangle:= avalue; + changed; +end; + +procedure tcustomdialcontroller.setindent1(const avalue: integer); +begin + if findent1 <> avalue then begin + findent1:= avalue; + changed; + end; +end; + +procedure tcustomdialcontroller.setindent2(const avalue: integer); +begin + if findent2 <> avalue then begin + findent2:= avalue; + changed; + end; +end; + +procedure tcustomdialcontroller.setfitdist(const avalue: integer); +begin + if ffitdist <> avalue then begin + ffitdist:= avalue; + changed; + end; +end; + +procedure tcustomdialcontroller.readstart(reader: treader); +begin + start:= reader.readfloat; +end; + +procedure tcustomdialcontroller.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('offset',{$ifdef FPC}@{$endif}readstart,nil,false); +end; + +function tcustomdialcontroller.getactdialrect(out arect: rectty): boolean; +var + int1,int2: integer; +begin + arect:= fintf.getdialrect; + result:= (fdirection in [gd_left,gd_down]) xor (do_opposite in foptions); + if result then begin + int1:= findent1; + int2:= findent2; + end + else begin + int2:= findent1; + int1:= findent2; + end; + with arect do begin + if fdirection in [gd_right,gd_left] then begin + y:= y + int1; + cy:= cy - int1 - int2; + end + else begin + x:= x + int1; + cx:= cx - int1 - int2; + end; + end; +end; + +function tcustomdialcontroller.getlog: boolean; +begin + result:= do_log in options; +end; + +procedure tcustomdialcontroller.setlog(const avalue: boolean); +begin + if avalue then begin + options:= options + [do_log]; + end + else begin + options:= options - [do_log]; + end; +end; + +function tcustomdialcontroller.getvisible: boolean; +begin + result:= not (do_invisible in foptions); +end; + +procedure tcustomdialcontroller.setvisible(const avalue: boolean); +begin + if avalue then begin + options:= options - [do_invisible]; + end + else begin + options:= options + [do_invisible]; + end; +end; + +function tcustomdialcontroller.getopposite: boolean; +begin + result:= do_opposite in foptions; +end; + +procedure tcustomdialcontroller.setopposite(const avalue: boolean); +begin + if avalue then begin + options:= options + [do_opposite]; + end + else begin + options:= options - [do_opposite]; + end; +end; + +function tcustomdialcontroller.getsideline: boolean; +begin + result:= do_sideline in foptions; +end; + +procedure tcustomdialcontroller.setsideline(const avalue: boolean); +begin + if avalue then begin + options:= options + [do_sideline]; + end + else begin + options:= options - [do_sideline]; + end; +end; + +function tcustomdialcontroller.getboxline: boolean; +begin + result:= do_boxline in foptions; +end; + +procedure tcustomdialcontroller.setboxline(const avalue: boolean); +begin + if avalue then begin + options:= options + [do_boxline]; + end + else begin + options:= options - [do_boxline]; + end; +end; + +function tcustomdialcontroller.getfront: boolean; +begin + result:= do_front in foptions; +end; + +procedure tcustomdialcontroller.setfront(const avalue: boolean); +begin + if avalue then begin + options:= options + [do_front]; + end + else begin + options:= options - [do_front]; + end; +end; + +{ tcustomdial } + +constructor tcustomdial.create(aowner: tcomponent); +begin + foptions:= defaultoptionsdial; + fdial:= tdialcontroller.create(idialcontroller(self)); + inherited; + size:= makesize(100,15); + color:= cl_transparent; + optionswidget:= defaultoptionswidgetnofocus; +end; + +destructor tcustomdial.destroy; +begin + fdial.free; + inherited; +end; + +procedure tcustomdial.setdial(const avalue: tdialcontroller); +begin + fdial.assign(avalue); +end; + +procedure tcustomdial.directionchanged(const dir,dirbefore: graphicdirectionty); +begin + if not (csloading in componentstate) then begin + if fframe <> nil then begin + rotateframe1(tcustomframe1(fframe).fi.innerframe,dirbefore,dir); + end; + rotateframe1(ffitframe,dirbefore,dir); + widgetrect:= changerectdirection(widgetrect,dirbefore,dir); + end; +end; + +function tcustomdial.getdialrect: rectty; +begin + result:= innerclientrect; + deflaterect1(result,ffitframe); +end; + +function tcustomdial.getlimitrect: rectty; +begin + result:= innerclientrect; +end; + +procedure tcustomdial.dopaintforeground(const acanvas: tcanvas); +begin + inherited; + fdial.paint(acanvas); + fdial.afterpaint(acanvas); +end; + +procedure tcustomdial.paint(const acanvas: tcanvas); +begin + checklayout; + inherited; +end; + +procedure tcustomdial.clientrectchanged; +begin + invalidatelayout; + inherited; +end; + +procedure tcustomdial.invalidatelayout; +begin + if componentstate * [csloading,csdestroying] = [] then begin + exclude(fstate,dws_layoutvalid); + fdial.changed; + end; +end; + +procedure tcustomdial.layoutchanged; +begin + exclude(fstate,dws_layoutvalid); + invalidate; +end; + +procedure tcustomdial.setfitframe(const avalue: framety); +begin + ffitframe:= avalue; + invalidatelayout; +end; + +procedure tcustomdial.setfitframe_left(const avalue: integer); +begin + if ffitframe.left <> avalue then begin + ffitframe.left:= avalue; + invalidatelayout; + end; +end; + +procedure tcustomdial.setfitframe_top(const avalue: integer); +begin + if ffitframe.top <> avalue then begin + ffitframe.top:= avalue; + invalidatelayout; + end; +end; + +procedure tcustomdial.setfitframe_right(const avalue: integer); +begin + if ffitframe.right <> avalue then begin + ffitframe.right:= avalue; + invalidatelayout; + end; +end; + +procedure tcustomdial.setfitframe_bottom(const avalue: integer); +begin + if ffitframe.bottom <> avalue then begin + ffitframe.bottom:= avalue; + invalidatelayout; + end; +end; + +procedure tcustomdial.setoptions(const avalue: optionsdialty); +begin + if avalue <> foptions then begin + foptions:= avalue; + invalidatelayout; + end; +end; + +function tcustomdial.fit(const asides: rectsidesty = allrectsides): boolean; +var + ext1: rectextty; +// int1: integer; + fra1: framety; + rect1: rectty; + si1: sizety; +begin + result:= false; + si1:= clientsize; + rect1:= getdialrect; + ext1.topleft:= rect1.pos; + ext1.bottomright:= addpoint(rect1.pos,pointty(rect1.size)); + fra1:= ffitframe; + + with fdial do begin + checklayout; + expandrectext1(ext1,fticks.fdim); + expandrectext1(ext1,fmarkers.fdim); + end; + + if fframe <> nil then begin + inflaterectext1(ext1,tcustomframe1(fframe).fi.innerframe); + end; + + if rs_left in asides then begin + fra1.left:= fra1.left - ext1.left; + end; + if rs_top in asides then begin + fra1.top:= fra1.top - ext1.top; + end; + if rs_right in asides then begin + fra1.right:= fra1.right + (ext1.right - si1.cx); + end; + if rs_bottom in asides then begin + fra1.bottom:= fra1.bottom + (ext1.bottom - si1.cy); + end; + + if not frameisequal(fra1,ffitframe) then begin + result:= true; + fitframe:= fra1; + end; +end; + +function tcustomdial.checklayout: boolean; +begin + result:= false; + if not (dws_layoutvalid in fstate) then begin + if foptions * rectsidesmask <> [] then begin + result:= fit(rectsidesty(foptions*rectsidesmask)); + end; + end; + include(fstate,dws_layoutvalid); +end; + +{ tcustomdialcontrollers } + +constructor tcustomdialcontrollers.create(const aintf: idialcontroller); +begin + fintf:= aintf; + frange:= 1; + inherited create(getitemclass); +end; + +procedure tcustomdialcontrollers.createitem(const index: integer; + var item: tpersistent); +begin + item:= dialcontrollerclassty(fitemclasstype).create(fintf); + tcustomdialcontroller(item).start:= fstart; + tcustomdialcontroller(item).range:= frange; +end; + +function tcustomdialcontrollers.getitemclass: dialcontrollerclassty; +begin + result:= tcustomdialcontroller; +end; + +procedure tcustomdialcontrollers.setstart(const avalue: real); +var + int1: integer; +begin + fstart:= avalue; + for int1:= 0 to high(fitems) do begin + tcustomdialcontroller(fitems[int1]).start:= avalue; + end; +end; + +procedure tcustomdialcontrollers.setrange(const avalue: real); +var + int1: integer; +begin + frange:= avalue; + for int1:= 0 to high(fitems) do begin + tcustomdialcontroller(fitems[int1]).range:= avalue; + end; +end; + +procedure tcustomdialcontrollers.dostatread(const reader: tstatreader); +var + int1,int2: integer; + mstr1: msestring; +begin + for int1:= 0 to count - 1 do begin + mstr1:= inttostrmse(int1); + with tcustomdialcontroller(fitems[int1]) do begin + if do_savestate in foptions then begin + start:= reader.readreal('start'+mstr1,start); + range:= reader.readreal('range'+mstr1,range); + end; + mstr1:= 'marker'+mstr1+'_'; + for int2:= 0 to markers.count - 1 do begin + with markers[int2] do begin + if dmo_savevalue in options then begin + value:= reader.readreal(mstr1+inttostrmse(int2),value); + end; + end; + end; + end; + end; +end; + +procedure tcustomdialcontrollers.dostatwrite(const writer: tstatwriter); +var + int1,int2: integer; + mstr1: msestring; +begin + for int1:= 0 to count - 1 do begin + mstr1:= inttostrmse(int1); + with tcustomdialcontroller(fitems[int1]) do begin + if do_savestate in options then begin + writer.writereal('start'+mstr1,start); + writer.writereal('range'+mstr1,range); + end; + mstr1:= 'marker'+mstr1+'_'; + for int2:= 0 to markers.count - 1 do begin + with markers[int2] do begin + if dmo_savevalue in options then begin + writer.writereal(mstr1+inttostrmse(int2),value); + end; + end; + end; + end; + end; +end; + +procedure tcustomdialcontrollers.changed; +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + with tcustomdialcontroller(fitems[int1]) do begin + changed; + end; + end; +end; + +{ tdialcontroller } + +constructor tdialcontroller.create(const aintf: idialcontroller); +begin + inherited; + options:= defaultdialcontrolleroptions; +end; + +{ tmarkerframe } + +constructor tmarkerframe.create(const aintf: iframe); +begin + inherited; + include(fstate,fs_nowidget); +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/msedispwidgets.pas b/mseide-msegui/lib/common/widgets/msedispwidgets.pas new file mode 100644 index 0000000..9528e88 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msedispwidgets.pas @@ -0,0 +1,1388 @@ +{ MSEgui Copyright (c) 1999-2015 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msedispwidgets; + +{$ifdef FPC} + {$mode objfpc}{$h+} +{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} + +interface +uses + msegraphics,classes,mclasses,msegui,mseguiglob,msewidgets, + msedrawtext,msegraphutils,mseassistiveclient, + msemenus,msetypes,msestrings,mseformatstr,mseevent,mseclasses,mserichstring + {$ifdef mse_with_ifi} + ,mseificomp,mseifiglob,mseificompglob,typinfo,msedatalist + {$endif}; + +const + defaultdisptextflags = [tf_ycentered]; + defaultdispwidgetwidth = 100; + defaultdispwidgetheight = 20; + defaultdispwidgetoptions = (defaultoptionswidget - + [ow_mousefocus,ow_tabfocus,ow_arrowfocus]){ + + [ow_fontglyphheight]}; + + defaultdispwidgetoptions1 = defaultoptionswidget1 + [ow1_fontglyphheight]; + +type + + tdispframe = class(tcustomcaptionframe) + protected + function actualcolorclient(): colorty override; + public + constructor create(const aintf: icaptionframe); + published + property options; + property levelo default -1; + property leveli; + property framewidth; + property colorframe; + property colorframeactive; + property colorframedisabled; + property colorframemouse; + property colorframeclicked; + property colorframedefault; + property colordkshadow; + property colorshadow; + property colorlight; + property colorhighlight; + property colordkwidth; + property colorhlwidth; + property hiddenedges; + property framei_left default 1; + property framei_top default 1; + property framei_right default 1; + property framei_bottom default 1; + property frameo_left; + property frameo_top; + property frameo_right; + property frameo_bottom; + + property frameimage_list; + property frameimage_left; + property frameimage_top; + property frameimage_right; + property frameimage_bottom; + property frameimage_offset; + property frameimage_offset1; + property frameimage_offsetdisabled; + property frameimage_offsetmouse; + property frameimage_offsetclicked; + property frameimage_offsetactive; + property frameimage_offsetfocused; +{ + property frameimage_offsetactivemouse; + property frameimage_offsetactiveclicked; +} + property frameface_list; + property frameface_offset; + property frameface_offset1; + property frameface_offsetdisabled; + property frameface_offsetmouse; + property frameface_offsetclicked; + property frameface_offsetactive; + property frameface_offsetfocused; +{ + property frameface_offsetactivemouse; + property frameface_offsetactiveclicked; +} + property optionsskin; + + property colorclient; + property caption; + property captiontextflags; + property captionpos; + property captiondist; +// property captiondistouter; +// property captionframecentered; + property captionoffset; +// property captionnoclip; + property focusrectdist; + property extraspace; + property imagedist; + property imagedist1; + property imagedist2; + property font; + property localprops; //before template + property localprops1; //before template + property template; + end; + + dispwidgetoptionty = (dwo_hintclippedtext,dwo_nogray, + dwo_showlocal,dwo_showutc, + dwo_blank); + //dwo_blank has only effect if componentstate csreading + //or csdesigning are set + dispwidgetoptionsty = set of dispwidgetoptionty; + dispwidgetflagty = (dwf_textrectvalid,dwf_cleared); + dispwidgetflagsty = set of dispwidgetflagty; + + tdispwidget = class(tpublishedwidget{$ifdef mse_with_ifi},iifidatalink{$endif}) + private + finfo: drawtextinfoty; + ftext: msestring; + foptions: dispwidgetoptionsty; + ftextflags: textflagsty; +// ftextrectvalid: boolean; + fonchange: notifyeventty; + procedure updatetextflags; + procedure settextflags(const value: textflagsty); + procedure settext(const avalue: msestring); + protected + fflags: dispwidgetflagsty; +{$ifdef mse_with_ifi} + fifilink: tifilinkcomp; + function getdefaultifilink: iificlient; override; + //iifidatalink + function getifilinkkind: ptypeinfo; + procedure setifilink(const avalue: tifilinkcomp); + function ifigriddata: tdatalist; + procedure updateifigriddata(const sender: tobject; const alist: tdatalist); + function getgriddata: tdatalist; + function getvalueprop: ppropinfo; + procedure getifivalue(var avalue) virtual; + procedure setifivalue(const avalue) virtual; + procedure updatereadonlystate; +{$endif} + procedure invalidatetext; + procedure setoptions(const avalue: dispwidgetoptionsty); virtual; + procedure valuechanged(); virtual; + procedure formatchanged(); + function getvaluetext: msestring; virtual; abstract; + procedure dopaintforeground(const canvas: tcanvas); override; + procedure clientrectchanged; override; + procedure getautopaintsize(var asize: sizety); override; + procedure fontchanged; override; + procedure internalcreateframe; override; + procedure doloaded; override; + procedure showhint(const aid: int32; var info: hintinfoty); override; + procedure enabledchanged; override; + function verticalfontheightdelta: boolean; override; + class function classskininfo: skininfoty; override; + //iassistiveclient + function getassistivetext(): msestring override; + function getassistiveflags(): assistiveflagsty override; + public + constructor create(aowner: tcomponent); override; + procedure initnewcomponent(const ascale: real); override; + procedure synctofontheight; override; + procedure clear; virtual; + procedure resetclear(); + property disptext: msestring read finfo.text.text; + published + property text: msestring read ftext write settext; + //overrides valuetext + property bounds_cx default defaultdispwidgetwidth; + property bounds_cy default defaultdispwidgetheight; + property font: twidgetfont read getfont write setfont stored isfontstored; + property textflags: textflagsty read ftextflags write settextflags + default defaultdisptextflags; + property optionswidget default defaultdispwidgetoptions; + property optionswidget1 default defaultdispwidgetoptions1; + property options: dispwidgetoptionsty read foptions + write setoptions default []; + property onchange: notifyeventty read fonchange write fonchange; + property onshowhint; + end; + + tbasestringdisp = class(tdispwidget) + private + {$ifdef mse_with_ifi} + function getifilink: tifistringlinkcomp; + procedure setifilink(const avalue: tifistringlinkcomp); + {$endif} + protected + published +{$ifdef mse_with_ifi} + property ifilink: tifistringlinkcomp read getifilink write setifilink; +{$endif} + end; + + tcustomstringdisp = class(tbasestringdisp) + private + fvalue: msestring; + fondatachange: updatestringeventty; + procedure setvalue(const Value: msestring); + protected + function getvaluetext: msestring; override; + procedure valuechanged; override; + public + procedure clear; override; + property value: msestring read fvalue write setvalue; + published + property ondatachange: updatestringeventty read fondatachange + write fondatachange; + end; + + tstringdisp = class(tcustomstringdisp) + published + property value; + end; + + tcustomrichstringdisp = class(tbasestringdisp,irichstringprop) + private +// fvalue: richstringty; + fondatachange: updaterichstringeventty; + procedure setvalue(const avalue: msestring); + function getrichvalue(): richstringty; + procedure setrichvalue(const avalue: richstringty); + procedure setformat(const avalue: formatinfoarty); + procedure readvalue(reader: treader); + procedure readrichvalue(reader: treader); + procedure writerichvalue(writer: twriter); + protected + function getvaluetext: msestring; override; + procedure valuechanged; override; + procedure defineproperties(filer: tfiler) override; + public + procedure clear; override; + property value: msestring read finfo.text.text write setvalue stored false; + property richvalue: richstringty read finfo.text write setrichvalue; + property formatvalue: formatinfoarty read finfo.text.format write setformat; + published + property ondatachange: updaterichstringeventty read fondatachange + write fondatachange; + end; + + trichstringdisp = class(tcustomrichstringdisp) + published + property value; + end; + + tbytestringdisp = class(tdispwidget) + private + fvalue: string; + fondatachange: updateansistringeventty; + fbase: numbasety; + procedure setvalue(const Value: string); + procedure setbase(const Value: numbasety); + protected + function getvaluetext: msestring; override; + procedure valuechanged; override; + public + constructor create(aowner: tcomponent); override; + procedure clear; override; + published + property value: string read fvalue write setvalue; + property ondatachange: updateansistringeventty read fondatachange + write fondatachange; + property base: numbasety read fbase write setbase default nb_hex; + end; + +const + defaultnumdisptextflags = defaultdisptextflags + [tf_right]; + +type + tnumdisp = class(tdispwidget) + protected + public + constructor create(aowner: tcomponent); override; + published + property textflags default defaultnumdisptextflags; + end; + + tcustomintegerdisp = class(tnumdisp) + private + fvalue: integer; + fondatachange: updateintegereventty; + fbase: numbasety; + fbitcount: integer; + procedure setvalue(const Value: integer); + procedure setbase(const Value: numbasety); + procedure setbitcount(const Value: integer); + {$ifdef mse_with_ifi} + function getifilink: tifiintegerlinkcomp; + procedure setifilink(const avalue: tifiintegerlinkcomp); + {$endif} + protected + function getvaluetext: msestring; override; + procedure valuechanged; override; + public + constructor create(aowner: tcomponent); override; + procedure clear; override; + property value: integer read fvalue write setvalue default 0; + published + property base: numbasety read fbase write setbase default nb_dec; + property bitcount: integer read fbitcount write setbitcount default 32; + property ondatachange: updateintegereventty read fondatachange + write fondatachange; +{$ifdef mse_with_ifi} + property ifilink: tifiintegerlinkcomp read getifilink write setifilink; +{$endif} + end; + + tintegerdisp = class(tcustomintegerdisp) + published + property value; + end; + + tcustomint64disp = class(tnumdisp) + private + fvalue: int64; + fondatachange: updateint64eventty; + fbase: numbasety; + fbitcount: integer; + procedure setvalue(const Value: int64); + procedure setbase(const Value: numbasety); + procedure setbitcount(const Value: integer); + {$ifdef mse_with_ifi} + function getifilink: tifiint64linkcomp; + procedure setifilink(const avalue: tifiint64linkcomp); + {$endif} + protected + function getvaluetext: msestring; override; + procedure valuechanged; override; + public + constructor create(aowner: tcomponent); override; + procedure clear; override; + property value: int64 read fvalue write setvalue default 0; + published + property base: numbasety read fbase write setbase default nb_dec; + property bitcount: integer read fbitcount write setbitcount default 64; + property ondatachange: updateint64eventty read fondatachange + write fondatachange; +{$ifdef mse_with_ifi} + property ifilink: tifiint64linkcomp read getifilink write setifilink; +{$endif} + end; + + tint64disp = class(tcustomint64disp) + published + property value; + end; + + tcustomrealdisp = class(tnumdisp) + private + fvalue: realty; + fondatachange: updaterealeventty; + fformat: msestring; + fvaluerange: real; + fvaluestart: real; + procedure setvalue(const avalue: realty); + procedure readvalue(reader: treader); +// procedure writevalue(writer: twriter); + procedure setformat(const avalue: msestring); + procedure setvaluerange(const avalue: real); + procedure setvaluestart(const avalue: real); + procedure readvaluescale(reader: treader); + {$ifdef mse_with_ifi} + function getifilink: tifireallinkcomp; + procedure setifilink(const avalue: tifireallinkcomp); + {$endif} + protected + procedure valuechanged; override; + function getvaluetext: msestring; override; + procedure defineproperties(filer: tfiler); override; + public + constructor create(aowner: tcomponent); override; + procedure clear; override; + property value: realty read fvalue write setvalue {stored false}; + published + property valuerange: real read fvaluerange write setvaluerange; + property valuestart: real read fvaluestart write setvaluestart; + property format: msestring read fformat write setformat; + property ondatachange: updaterealeventty read fondatachange + write fondatachange; +{$ifdef mse_with_ifi} + property ifilink: tifireallinkcomp read getifilink write setifilink; +{$endif} + end; + + trealdisp = class(tcustomrealdisp) + published + property value{stored false}; + end; + + tcustomdatetimedisp = class(tnumdisp) + private + fvalue: tdatetime; + fondatachange: updatedatetimeeventty; + fformat: msestring; + fkind: datetimekindty; + fconvert: dateconvertty; + procedure setvalue(const avalue: tdatetime); + procedure setformat(const avalue: msestring); + procedure setkind(const avalue: datetimekindty); + procedure readvalue(reader: treader); +// procedure writevalue(writer: twriter); + {$ifdef mse_with_ifi} + function getifilink: tifidatetimelinkcomp; + procedure setifilink(const avalue: tifidatetimelinkcomp); + {$endif} + protected + procedure setoptions(const avalue: dispwidgetoptionsty); override; + procedure valuechanged; override; + function getvaluetext: msestring; override; + procedure defineproperties(filer: tfiler); override; + public + constructor create(aowner: tcomponent); override; + procedure clear; override; + property value: tdatetime read fvalue write setvalue; + published + property format: msestring read fformat write setformat; + property ondatachange: updatedatetimeeventty read fondatachange + write fondatachange; + property kind: datetimekindty read fkind write setkind default dtk_date; +{$ifdef mse_with_ifi} + property ifilink: tifidatetimelinkcomp read getifilink write setifilink; +{$endif} + end; + + tdatetimedisp = class(tcustomdatetimedisp) + published + property value{ stored false}; + end; + + tcustombooleandisp = class(tdispwidget) + private + fvalue: boolean; + fondatachange: updatebooleaneventty; + ftext_false: msestring; + ftext_true: msestring; + procedure setvalue(const Value: boolean); + procedure settext_false(const avalue: msestring); + procedure settext_true(const avalue: msestring); + protected + procedure valuechanged; override; + function getvaluetext: msestring; override; + public + constructor create(aowner: tcomponent); override; + procedure clear; override; + property value: boolean read fvalue write setvalue default false; + published + property textflags default defaultdisptextflags + [tf_xcentered]; + property ondatachange: updatebooleaneventty read fondatachange + write fondatachange; + property text_false: msestring read ftext_false write settext_false; + property text_true: msestring read ftext_true write settext_true; + end; + + tbooleandisp = class(tcustombooleandisp) + published + property value; + end; + +implementation +uses + sysutils,msereal,math,msestreaming,msedate,msebits; + +{ tdispframe } + +constructor tdispframe.create(const aintf: icaptionframe); +begin + inherited; +// clientcolor:= cl_foreground; + fi.levelo:= -1; + inflateframe1(fi.innerframe,1); + internalupdatestate; +end; + +function tdispframe.actualcolorclient(): colorty; +begin + result:= fi.colorclient; + if result = cl_default then begin + result:= cl_noedit; + end; +end; + +{ tdispwidget } + +constructor tdispwidget.create(aowner: tcomponent); +begin + inherited; + foptionswidget:= defaultdispwidgetoptions; + foptionswidget1:= defaultdispwidgetoptions1; + fwidgetrect.cx:= defaultdispwidgetwidth; + fwidgetrect.cy:= defaultdispwidgetheight; + ftextflags:= defaultdisptextflags; + finfo.flags:= ftextflags; +end; + +class function tdispwidget.classskininfo: skininfoty; +begin + result:= inherited classskininfo; + result.objectkind:= sok_dispwidget; +end; + +function tdispwidget.getassistivetext(): msestring; +begin + result:= disptext; +end; + +function tdispwidget.getassistiveflags(): assistiveflagsty; +begin + result:= inherited getassistiveflags() + [asf_dispwidget,asf_readonly]; +end; + +procedure tdispwidget.initnewcomponent(const ascale: real); +begin + inherited; + internalcreateframe; + fframe.scale(ascale); +// synctofontheight; +end; + +procedure tdispwidget.settextflags(const value: textflagsty); +begin + if ftextflags <> value then begin + ftextflags:= checktextflags(ftextflags,value); + updatetextflags; + invalidatetext; + end; +end; + +procedure tdispwidget.clientrectchanged; +begin + exclude(fflags,dwf_textrectvalid); + inherited; + finfo.dest:= innerclientrect; +end; + +procedure tdispwidget.getautopaintsize(var asize: sizety); +var + fram1: framety; +begin + if fframe = nil then begin + fram1:= nullframe; + end + else begin + fram1:= fframe.framei; + end; + if not (dwf_textrectvalid in fflags) then begin + if finfo.font = nil then begin + finfo.font:= getfont; + end; + msedrawtext.textrect(getcanvas,finfo); + include(fflags,dwf_textrectvalid); + end; + asize.cx:= finfo.res.size.cx + fram1.left + fram1.right; + asize.cy:= finfo.res.size.cy + fram1.top + fram1.bottom; +end; + +procedure tdispwidget.dopaintforeground(const canvas: tcanvas); +begin + inherited; + if not (dwf_cleared in fflags) or (ftext <> '') then begin + drawtext(canvas,finfo); + if finfo.text.text = '' then begin + finfo.res.cy:= finfo.font.glyphheight; + end; + end + else begin + finfo.res.cx:= 0; + finfo.res.cy:= finfo.font.glyphheight; + end; + include(fflags,dwf_textrectvalid); +end; + +procedure tdispwidget.fontchanged; +begin + finfo.font:= getfont; + invalidatetext; + inherited; +end; + +procedure tdispwidget.internalcreateframe; +begin + tdispframe.create(iscrollframe(self)); +end; + +procedure tdispwidget.settext(const avalue: msestring); +begin + exclude(fflags,dwf_cleared); + ftext:= avalue; + if avalue = '' then begin + finfo.text.text:= getvaluetext; + end + else begin + finfo.text.text:= avalue; + end; + invalidatetext; +end; + +procedure tdispwidget.valuechanged(); +begin + if not (dwo_blank in foptions) or + (componentstate*[csreading,csdesigning] = []) and + not (ws_loadedproc in widgetstate) then begin + exclude(fflags,dwf_cleared); + end; + if ftext = '' then begin + finfo.text.text:= getvaluetext; + invalidatetext; + end; +{$ifdef mse_with_ifi} + if not (ws_loadedproc in fwidgetstate) then begin + if fifiserverintf <> nil then begin + iifidataserver(fifiserverintf).valuechanged(iifidatalink(self)); + end; + end; +{$endif} + if canevent(tmethod(fonchange)) then begin + fonchange(self); + end; +end; + +{$ifdef mse_with_ifi} +function tdispwidget.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iifidatalink); +end; + +procedure tdispwidget.setifilink(const avalue: tifilinkcomp); +begin + mseificomp.setifilinkcomp(iifidatalink(self),avalue,fifilink); +end; + +function tdispwidget.ifigriddata: tdatalist; +begin + result:= nil; +end; + +procedure tdispwidget.updateifigriddata(const sender: tobject; + const alist: tdatalist); +begin + //dummy +end; + +function tdispwidget.getgriddata: tdatalist; +begin + result:= nil; +end; + +function tdispwidget.getvalueprop: ppropinfo; +begin + result:= getpropinfo(self,'value'); +end; + +procedure tdispwidget.getifivalue(var avalue); +begin + //dummy +end; + +procedure tdispwidget.setifivalue(const avalue); +begin + //dummy +end; + +procedure tdispwidget.updatereadonlystate; +begin + //dummy +end; + +{$endif} + +procedure tdispwidget.formatchanged; +begin + if ftext = '' then begin + finfo.text.text:= getvaluetext; + end; + invalidatetext; +end; + +procedure tdispwidget.doloaded; +begin + inherited; + valuechanged; +end; + +procedure tdispwidget.showhint(const aid: int32; var info: hintinfoty); +begin + if (dwo_hintclippedtext in foptions) and getshowhint and + textclipped(getcanvas,finfo) then begin + info.caption:= finfo.text.text; + end; + inherited; +end; + +function tdispwidget.verticalfontheightdelta: boolean; +begin + result:= tf_rotate90 in textflags; +end; + +procedure tdispwidget.synctofontheight; +begin + syncsinglelinefontheight; +end; + +procedure tdispwidget.updatetextflags; +begin + if not (csloading in componentstate) then begin + if isenabled or (dwo_nogray in foptions) then begin + finfo.flags:= ftextflags; + end + else begin + finfo.flags:= ftextflags + [tf_grayed]; + end; + end; +end; + +procedure tdispwidget.enabledchanged; +begin + inherited; + updatetextflags; + invalidate; +end; + +procedure tdispwidget.setoptions(const avalue: dispwidgetoptionsty); +begin + if (componentstate*[csreading,csdesigning] <> []) then begin + if dwo_blank in avalue then begin + if not (dwf_cleared in fflags) then begin + include(fflags,dwf_cleared); + invalidatetext(); + end; + end + else begin + if dwf_cleared in fflags then begin + exclude(fflags,dwf_cleared); + invalidatetext(); + end; + end; + end; + if foptions <> avalue then begin + foptions:= avalue-[dwo_showlocal,dwo_showutc]; + updatetextflags; + invalidatetext; + end; +end; + +procedure tdispwidget.invalidatetext; +begin + exclude(fflags,dwf_textrectvalid); + invalidate; + checkautosize; +end; + +procedure tdispwidget.clear; +begin + if not (dwf_cleared in fflags) then begin + include(fflags,dwf_cleared); + invalidatetext(); + end; +end; + +procedure tdispwidget.resetclear(); +begin + if dwf_cleared in fflags then begin + exclude(fflags,dwf_cleared); + if ftext = '' then begin + invalidatetext(); + end; + end; +end; + +{$ifdef mse_with_ifi} + +function tdispwidget.getdefaultifilink: iificlient; +begin + result:= iifidatalink(self); +end; + +function tbasestringdisp.getifilink: tifistringlinkcomp; +begin + result:= tifistringlinkcomp(fifilink); +end; + +procedure tbasestringdisp.setifilink(const avalue: tifistringlinkcomp); +begin + inherited setifilink(avalue); +end; + +{$endif} + +{ tcustomstringdisp } + +function tcustomstringdisp.getvaluetext: msestring; +begin + result:= fvalue; +end; + +procedure tcustomstringdisp.setvalue(const Value: msestring); +begin + if (fvalue <> value) then begin + fvalue:= Value; + valuechanged(); + end + else begin + resetclear(); + end; +end; + +procedure tcustomstringdisp.valuechanged; +begin + if canevent(tmethod(fondatachange)) then begin + fondatachange(self,fvalue); + end; + inherited; +end; + +procedure tcustomstringdisp.clear; +begin + value:= ''; + inherited; +end; + +{ tcustomrichstringdisp } + +procedure tcustomrichstringdisp.setvalue(const avalue: msestring); +begin +// if (fvalue <> value) or (finfo.text.format <> nil) then begin + finfo.text.text:= avalue; + finfo.text.format:= nil; + valuechanged(); +// end +// else begin +// resetclear(); +// end; +end; + +function tcustomrichstringdisp.getrichvalue(): richstringty; +begin + result:= finfo.text; +end; + +procedure tcustomrichstringdisp.setrichvalue(const avalue: richstringty); +begin + finfo.text:= avalue; + valuechanged; +end; + +procedure tcustomrichstringdisp.setformat(const avalue: formatinfoarty); +begin + finfo.text.format:= copy(avalue); + valuechanged(); +end; + +procedure tcustomrichstringdisp.readvalue(reader: treader); +begin + value:= reader.readunicodestring(); +end; + +procedure tcustomrichstringdisp.readrichvalue(reader: treader); +begin + richvalue:= readrichstring(reader); +end; + +procedure tcustomrichstringdisp.writerichvalue(writer: twriter); +begin + writerichstring(writer,finfo.text); +end; + +procedure tcustomrichstringdisp.defineproperties(filer: tfiler); +var + b1: boolean; +begin + inherited; + filer.defineproperty('value',@readvalue,nil,false); + if filer.ancestor <> nil then begin + b1:= isequalrichstring(tcustomrichstringdisp(filer.ancestor).finfo.text, + finfo.text); + end + else begin + b1:= not isemptyrichstring(finfo.text); + end; + filer.defineproperty('richvalue',@readrichvalue,@writerichvalue,b1); +end; + +function tcustomrichstringdisp.getvaluetext: msestring; +begin + result:= finfo.text.text; +end; + +procedure tcustomrichstringdisp.valuechanged; +begin + if canevent(tmethod(fondatachange)) then begin + fondatachange(self,finfo.text); + end; + inherited; +end; + +procedure tcustomrichstringdisp.clear; +begin + richvalue:= emptyrichstring; + inherited; +end; + +{ tbytestringdisp } + +constructor tbytestringdisp.create(aowner: tcomponent); +begin + fbase:= nb_hex; + inherited; +end; + +function tbytestringdisp.getvaluetext: msestring; +begin + if length(fvalue) > 256 then begin + result:= msestring(bytestrtostr(copy(fvalue,1,256),fbase,' '))+'...'; + end + else begin + result:= msestring(bytestrtostr(fvalue,fbase,' ')); + end; +end; + +procedure tbytestringdisp.setbase(const Value: numbasety); +begin + if fbase <> value then begin + fbase:= Value; + formatchanged; + end; +end; + +procedure tbytestringdisp.setvalue(const Value: string); +begin + if fvalue <> value then begin + fvalue := Value; + valuechanged; + end + else begin + resetclear(); + end; +end; + +procedure tbytestringdisp.valuechanged; +begin + if canevent(tmethod(fondatachange)) then begin + fondatachange(self,fvalue); + end; + inherited; +end; + +procedure tbytestringdisp.clear; +begin + value:= ''; + inherited; +end; + +{ tnumdisp } + +constructor tnumdisp.create(aowner: tcomponent); +begin + inherited; + ftextflags:= defaultnumdisptextflags; + finfo.flags:= ftextflags; +end; + +{ tcustomintegerdisp } + +constructor tcustomintegerdisp.create(aowner: tcomponent); +begin + fbase:= nb_dec; + fbitcount:= 32; + inherited; +end; + +{$ifdef mse_with_ifi} + +function tcustomintegerdisp.getifilink: tifiintegerlinkcomp; +begin + result:= tifiintegerlinkcomp(fifilink); +end; + +procedure tcustomintegerdisp.setifilink(const avalue: tifiintegerlinkcomp); +begin + inherited setifilink(avalue); +end; +{$endif} + +function tcustomintegerdisp.getvaluetext: msestring; +begin + result:= msestring(intvaluetostr(fvalue,fbase,fbitcount)); +end; + +procedure tcustomintegerdisp.setbase(const Value: numbasety); +begin + if fbase <> value then begin + fbase := Value; + formatchanged; + end; +end; + +procedure tcustomintegerdisp.setbitcount(const Value: integer); +begin + if fbitcount <> value then begin + fbitcount := Value; + formatchanged; + end; +end; + +procedure tcustomintegerdisp.setvalue(const Value: integer); +begin + if fvalue <> value then begin + fvalue := Value; + valuechanged(); + end + else begin + resetclear(); + end; +end; + +procedure tcustomintegerdisp.valuechanged; +begin + if canevent(tmethod(fondatachange)) then begin + fondatachange(self,fvalue); + end; + inherited; +end; + +procedure tcustomintegerdisp.clear; +begin + value:= 0; + inherited; +end; + +{ tcustomint64disp } + +constructor tcustomint64disp.create(aowner: tcomponent); +begin + fbase:= nb_dec; + fbitcount:= 64; + inherited; +end; + +{$ifdef mse_with_ifi} + +function tcustomint64disp.getifilink: tifiint64linkcomp; +begin + result:= tifiint64linkcomp(fifilink); +end; + +procedure tcustomint64disp.setifilink(const avalue: tifiint64linkcomp); +begin + inherited setifilink(avalue); +end; +{$endif} + +function tcustomint64disp.getvaluetext: msestring; +begin + result:= msestring(intvaluetostr(fvalue,fbase,fbitcount)); +end; + +procedure tcustomint64disp.setbase(const Value: numbasety); +begin + if fbase <> value then begin + fbase := Value; + formatchanged; + end; +end; + +procedure tcustomint64disp.setbitcount(const Value: integer); +begin + if fbitcount <> value then begin + fbitcount := Value; + formatchanged; + end; +end; + +procedure tcustomint64disp.setvalue(const Value: int64); +begin + if fvalue <> value then begin + fvalue := Value; + valuechanged; + end + else begin + resetclear(); + end; +end; + +procedure tcustomint64disp.valuechanged; +begin + if canevent(tmethod(fondatachange)) then begin + fondatachange(self,fvalue); + end; + inherited; +end; + +procedure tcustomint64disp.clear; +begin + value:= 0; + inherited; +end; + +{ tcustomrealdisp } + +constructor tcustomrealdisp.create(aowner: tcomponent); +begin + fvalue:= emptyreal; + fvaluerange:= 1; + inherited; +end; + +procedure tcustomrealdisp.readvalue(reader: treader); +begin + value:= readrealty(reader); +end; +{ +procedure tcustomrealdisp.writevalue(writer: twriter); +begin + writerealty(writer,fvalue); +end; +} +procedure tcustomrealdisp.readvaluescale(reader: treader); +begin + valuerange:= valuescaletorange(reader); +end; + +procedure tcustomrealdisp.defineproperties(filer: tfiler); +begin + inherited; + filer.DefineProperty('val',{$ifdef FPC}@{$endif}readvalue,nil,false); + filer.defineproperty('valuescale',{$ifdef FPC}@{$endif}readvaluescale,nil,false); +end; + +function tcustomrealdisp.getvaluetext: msestring; +begin + result:= realtytostrrange(fvalue,fformat,fvaluerange,fvaluestart); +end; + +procedure tcustomrealdisp.setvalue(const avalue: realty); +begin + if fvalue <> avalue then begin + fvalue := avalue; + valuechanged; + end + else begin + resetclear(); + end; +end; + +{$ifdef mse_with_ifi} + +function tcustomrealdisp.getifilink: tifireallinkcomp; +begin + result:= tifireallinkcomp(fifilink); +end; + +procedure tcustomrealdisp.setifilink(const avalue: tifireallinkcomp); +begin + inherited setifilink(avalue); +end; +{$endif} + +procedure tcustomrealdisp.valuechanged; +begin + if canevent(tmethod(fondatachange)) then begin + fondatachange(self,real(fvalue)); + end; + inherited; +end; + +procedure tcustomrealdisp.setformat(const avalue: msestring); +begin + fformat:= avalue; + formatchanged; +end; + +procedure tcustomrealdisp.setvaluerange(const avalue: real); +begin + fvaluerange:= avalue; + formatchanged; +end; + +procedure tcustomrealdisp.setvaluestart(const avalue: real); +begin + fvaluestart:= avalue; + formatchanged; +end; + +procedure tcustomrealdisp.clear; +begin + value:= emptyreal; + inherited; +end; + +{ tcustomdatetimedisp } + +constructor tcustomdatetimedisp.create(aowner: tcomponent); +begin + fvalue:= emptydatetime; + inherited; +end; + +procedure tcustomdatetimedisp.setvalue(const avalue: tdatetime); +begin + if fvalue <> avalue then begin + fvalue := avalue; + valuechanged; + end + else begin + resetclear(); + end; +end; + +procedure tcustomdatetimedisp.setformat(const avalue: msestring); +begin + fformat := avalue; + formatchanged; +end; + +{$ifdef mse_with_ifi} +function tcustomdatetimedisp.getifilink: tifidatetimelinkcomp; +begin + result:= tifidatetimelinkcomp(fifilink); +end; + +procedure tcustomdatetimedisp.setifilink(const avalue: tifidatetimelinkcomp); +begin + inherited setifilink(avalue); +end; +{$endif} + +procedure tcustomdatetimedisp.valuechanged; +begin + if canevent(tmethod(fondatachange)) then begin + fondatachange(self,fvalue); + end; + inherited; +end; + +function tcustomdatetimedisp.getvaluetext: msestring; +var + dt1: tdatetime; +begin + dt1:= fvalue; + checkdatereconvert(fconvert,dt1); + case fkind of + dtk_time: begin + result:= mseformatstr.timetostring(dt1,fformat); + end; + dtk_date: begin + result:= mseformatstr.datetostring(dt1,fformat); + end; + else begin + result:= mseformatstr.datetimetostring(dt1,fformat); + end; + end; +end; + +procedure tcustomdatetimedisp.setkind(const avalue: datetimekindty); +begin + if fkind <> avalue then begin + fkind:= avalue; + formatchanged; + end; +end; + +procedure tcustomdatetimedisp.readvalue(reader: treader); +begin + value:= readrealty(reader); +end; +{ +procedure tcustomdatetimedisp.writevalue(writer: twriter); +begin + writerealty(writer,fvalue); +end; +} +procedure tcustomdatetimedisp.defineproperties(filer: tfiler); +begin + inherited; + filer.DefineProperty('val', + {$ifdef FPC}@{$endif}readvalue,nil,false); +end; + +procedure tcustomdatetimedisp.setoptions(const avalue: dispwidgetoptionsty); +{$ifndef FPC} +const + mask1: dispwidgetoptionsty = [dwo_showlocal,dwo_showutc]; +{$endif} +var + opt1: dispwidgetoptionsty; +begin + opt1:= foptions; + inherited; + foptions:= dispwidgetoptionsty( + {$ifdef FPC} + replacebits(setsinglebit(longword(avalue),longword(opt1), + longword([dwo_showlocal,dwo_showutc])), + longword(foptions), + longword([dwo_showlocal,dwo_showutc]))); + {$else} + replacebits(setsinglebit(byte(avalue),byte(opt1), + byte(mask1)),byte(foptions),byte(mask1))); + {$endif} + fconvert:= dc_none; + if dwo_showutc in foptions then begin + fconvert:= dc_tolocal; + end; + if dwo_showlocal in foptions then begin + fconvert:= dc_toutc; + end; + formatchanged; +end; + +procedure tcustomdatetimedisp.clear; +begin + value:= emptydatetime; + inherited; +end; + +{ tcustombooleandisp } + +constructor tcustombooleandisp.create(aowner: tcomponent); +begin + ftext_true:= 'T'; + ftext_false:= 'F'; + inherited; + finfo.flags:= finfo.flags + [tf_xcentered]; +end; + +function tcustombooleandisp.getvaluetext: msestring; +begin + if fvalue then begin + result:= ftext_true; + end + else begin + result:= ftext_false; + end; +end; + +procedure tcustombooleandisp.setvalue(const Value: boolean); +begin + if fvalue <> value then begin + fvalue := Value; + valuechanged; + end + else begin + resetclear(); + end; +end; + +procedure tcustombooleandisp.valuechanged; +begin + if canevent(tmethod(fondatachange)) then begin + fondatachange(self,fvalue); + end; + inherited; +end; + +procedure tcustombooleandisp.settext_false(const avalue: msestring); +begin + ftext_false:= avalue; + formatchanged; +end; + +procedure tcustombooleandisp.settext_true(const avalue: msestring); +begin + ftext_true:= avalue; + formatchanged; +end; + +procedure tcustombooleandisp.clear; +begin + value:= false; + inherited; +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/msedock.pas b/mseide-msegui/lib/common/widgets/msedock.pas new file mode 100644 index 0000000..53c3183 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msedock.pas @@ -0,0 +1,6027 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msedock; + +{$ifdef FPC}{$mode objfpc}{$h+}{$GOTO ON}{$interfaces corba}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + msewidgets,classes,mclasses,msedrag,msegui,msegraphutils,mseevent,mseclasses, + msegraphics,msestockobjects,mseglob,mseguiglob,msestat,msestatfile,msepointer, + msesplitter,msesimplewidgets,msetypes,msestrings,msebitmap,mseobjectpicker, + msetabsglob,msemenus,msedrawtext,mseshapes,msedragglob,mseinterfaces,msetabs; + +//todo: optimize + +const + defaultgripsize = 10; + defaultgripgrip = stb_none; + defaultgripcolor = cl_white; + defaultgripcoloractive = cl_activegrip; + defaultgrippos = cp_right; + defaultsplittersize = 3; + +type + optiondockty = (od_savepos,od_savezorder,od_savechildren, + od_canmove,od_cansize,od_canfloat,od_candock,od_acceptsdock, + od_dockparent,od_expandforfixsize, + od_splitvert,od_splithorz,od_tabed,od_proportional, + od_propsize,od_fixsize,od_top,od_background, + od_alignbegin,od_aligncenter,od_alignend, + od_nofit,od_banded,od_nosplitsize,od_nosplitmove, + od_lock,od_nolock,od_thumbtrack,od_captionhint,{od_buttonhints,} + od_childicons); //use odf_childicons instead + optionsdockty = set of optiondockty; + + dockbuttonrectty = (dbr_none,dbr_handle,dbr_close,dbr_maximize,dbr_normalize, + dbr_minimize,dbr_fixsize,dbr_float, + dbr_top,dbr_background,dbr_lock,dbr_nolock); +const + defaultoptionsdock = [od_savepos,od_savezorder,od_savechildren, + od_captionhint]; + defaultoptionsdocknochildren = defaultoptionsdock - [od_savechildren]; + deprecatedoptionsdock = [od_childicons]; + + dbr_first = dbr_handle; + dbr_last = dbr_nolock; + dbr_firstbutton = dockbuttonrectty(ord(dbr_first)+1); + dbr_lastbutton = dbr_last; + defaulttaboptions= [tabo_dragdest,tabo_dragsource]; + +type + twidgetdragobject = class(tdragobject) + private + function getwidget: twidget; + public + constructor create(const asender: twidget; var instance: tdragobject; + const apickpos: pointty); + property widget: twidget read getwidget; + end; + + tdockcontroller = class; + + tdockdragobject = class(twidgetdragobject) + private + fxorwidget: twidget; + fxorrect: rectty; //screen origin + fdock: tdockcontroller; + findex: integer; + fcheckeddockcontroller: tdockcontroller; + protected + procedure drawxorpic; + procedure setxorwidget(const awidget: twidget; const screenrect: rectty); + public + constructor create(const adock: tdockcontroller; const asender: twidget; + var instance: tdragobject; const apickpos: pointty); + destructor destroy; override; + procedure refused(const apos: pointty); override; + end; + + idockcontroller = interface(idragcontroller)[miid_idockcontroller] + function checkdock(var info: draginfoty): boolean; + function getbuttonrects(const index: dockbuttonrectty): rectty; + //origin = clientrect.pos + function getplacementrect: rectty; //origin = container.pos + function getminimizedsize(out apos: captionposty): sizety; + //cx = 0 -> normalwidth, cy = 0 -> normalheight + function getcaption: msestring; + function getchildicon: tmaskedbitmap; //own or first icon of dockchildren, + //can return nil + procedure dolayoutchanged(const sender: tdockcontroller); + procedure dodockcaptionchanged(const sender: tdockcontroller); + end; + + checkdockeventty = procedure(const sender: tobject; const apos: pointty; + const dockdragobject: tdockdragobject; + var accept: boolean) of object; + + tdockhandle = class(tpublishedwidget) + private + fcontroller: tdockcontroller; + fgrip_pos: captionposty; + fgrip_color: colorty; + fgrip_grip: stockbitmapty; + procedure setgrip_color(const Value: colorty); + procedure setgrip_grip(const Value: stockbitmapty); + procedure setgrip_pos(const Value: captionposty); + protected + function gethandlerect: rectty; + procedure clientmouseevent(var info: mouseeventinfoty); override; + procedure dopaintforeground(const canvas: tcanvas); override; + function gethint: msestring; override; + public + constructor create(aowner: tcomponent); override; + published + property grip_pos: captionposty read fgrip_pos write setgrip_pos default cp_bottomright; + property grip_grip: stockbitmapty read fgrip_grip write setgrip_grip default stb_none; + property grip_color: colorty read fgrip_color write setgrip_color default defaultgripcolor; + property bounds_cx default 15; + property bounds_cy default 15; + property anchors default [an_right,an_bottom]; + property color default cl_transparent; + property optionswidget default defaultoptionswidget + [ow_top{,ow_noautosizing}]; + property optionswidget1 default defaultoptionswidget1 + [ow1_noautosizing]; + end; + + dockstatety = (dos_layoutvalid,dos_sizing, + dos_updating1,dos_updating2,dos_updating3, + dos_updating4,dos_updating5,dos_tabedending, + { + dos_closebuttonclicked,dos_maximizebuttonclicked, + dos_normalizebuttonclicked,dos_minimizebuttonclicked, + dos_fixsizebuttonclicked,dos_floatbuttonclicked, + dos_topbuttonclicked,dos_backgroundbuttonclicked, + dos_lockbuttonclicked,dos_nolockbuttonclicked, + } + dos_moving,dos_hasfloatbutton, + {dos_proprefvalid,}dos_showed,dos_xorpic); + dockstatesty = set of dockstatety; + + splitdirty = (sd_none,sd_vert,sd_horz,sd_tabed); + mdistatety = (mds_normal,mds_maximized,mds_minimized,mds_floating); + + dockcontrollereventty = procedure(const sender: tdockcontroller) of object; + + docklayouteventty = procedure(const sender: twidget; + const achildren: widgetarty) of object; + mdistatechangedeventty = procedure(const sender: twidget; + const oldvalue,newvalue: mdistatety) of object; + dockrecteventty = procedure(const sender: twidget; + var arect: rectty) of object; + + bandinfoty = record + first: integer; + last: integer; + size: integer; + end; + + bandinfoarty = array of bandinfoty; + + tdockcontroller = class(tdragcontroller) + private + foncalclayout: docklayouteventty; + fonlayoutchanged: dockcontrollereventty; + fonboundschanged: dockcontrollereventty; + foncaptionchanged: dockcontrollereventty; + fonfloat: notifyeventty; + fondock: notifyeventty; + fonchilddock: widgeteventty; + fonchildfloat: widgeteventty; + foncheckdock: checkdockeventty; + fdockhandle: tdockhandle; + fsplitter_size: integer; + fcursorbefore: cursorshapety; + fsizeindex: integer; + fmoveindex: integer; + fsizingrect: rectty; + fsizeoffset: integer; + fdockstate: dockstatesty; + fcaption: msestring; + fsize: sizety; + fsplitter_color: colorty; + fsplitter_colorgrip: colorty; + fsplitter_grip: stockbitmapty; + fsplitterrects: rectarty; + frecalclevel: integer; + fsplitdir,fasplitdir: splitdirty; + fmdistate: mdistatety; + fnormalrect: rectty; + ftabwidget: ttabwidget; //tdocktabwidget + ftabpage: ttabpage; //tdocktabpage + ftaborder: msestringarty; + factivetab: integer; //used only for statreading + fuseroptions: optionsdockty; + floatdockcount: integer; + fonmdistatechanged: mdistatechangedeventty; + ftab_options: tabbaroptionsty; + ftab_size: integer; + ftab_sizemin: integer; + ftab_sizemax: integer; + ftab_color: colorty; + ftab_colortab: colorty; + ftab_coloractivetab: colorty; + ftab_frame: tframecomp; + ftab_face: tfacecomp; + ftab_facetab: tfacecomp; + ftab_faceactivetab: tfacecomp; + ftab_frametab: tframecomp; + fplacementrect: rectty; + fhiddensizeref: sizety; + fbands: bandinfoarty; + fbandstart: integer; + fbandgap: integer; + fsizes: integerarty; + frefsize: integer; + fwidgetsbefore: widgetarty; + fwidgetrectsbefore: rectarty; + ftab_textflags: textflagsty; + ftab_width: integer; + ftab_widthmin: integer; + ftab_widthmax: integer; + fdefaultsplitdir: splitdirty; + fchildren: stringarty; + ffocusedchild: integer; + fonbeforefloat: dockrecteventty; + fcolortab: colorty; + fcoloractivetab: colorty; + ffacetab: tfacecomp; + ffaceactivetab: tfacecomp; + procedure updaterefsize; + procedure setdockhandle(const avalue: tdockhandle); + function checksplit(const awidgets: widgetarty; + out propsize,varsize,fixsize,fixcount: integer; + out isprop,isfix: booleanarty; + const fixedareprop: boolean): widgetarty; overload; + function checksplit(out propsize,fixsize: integer; + out isprop,isfix: booleanarty; + const fixedareprop: boolean): widgetarty; overload; + function checksplit: widgetarty; overload; + procedure setcaption(const Value: msestring); + procedure setsplitter_size(const Value: integer); + procedure setsplitter_setgrip(const Value: stockbitmapty); + procedure setsplitter_color(const Value: colorty); + procedure setsplitter_colorgrip(const Value: colorty); + procedure splitterchanged; + procedure updategrip(const asplitdir: splitdirty; const awidget: twidget); + procedure setuseroptions(const avalue: optionsdockty); + function placementrect: rectty; + procedure settab_options(const avalue: tabbaroptionsty); + procedure settab_frame(const avalue: tframecomp); + procedure settab_face(const avalue: tfacecomp); + procedure settab_color(const avalue: colorty); + procedure settab_colortab(const avalue: colorty); + procedure settab_coloractivetab(const avalue: colorty); + procedure settab_facetab(const avalue: tfacecomp); + procedure settab_faceactivetab(const avalue: tfacecomp); + procedure settab_size(const avalue: integer); + procedure settab_sizemin(const avalue: integer); + procedure settab_sizemax(const avalue: integer); + procedure setbandgap(const avalue: integer); + + procedure settab_textflags(const avalue: textflagsty); + procedure settab_width(const avalue: integer); + procedure settab_widthmin(const avalue: integer); + procedure settab_widthmax(const avalue: integer); + procedure setsplitdir(const avalue: splitdirty); + procedure setcurrentsplitdir(const avalue: splitdirty); + function getdockrect: rectty; + procedure settab_frametab(const avalue: tframecomp); + function getactivetabpage: ttabpage; + procedure setcolortab(const avalue: colorty); + procedure setcoloractivetab(const avalue: colorty); + procedure setfacetab(const avalue: tfacecomp); + procedure setfaceactivetab(const avalue: tfacecomp); + protected + foptionsdock: optionsdockty; + fr: prectaccessty; + fw: pwidgetaccessty; + fplacing: integer; + fclickedbutton: dockbuttonrectty; + fwidgetstate: widgetstatesty; + + procedure checkdirection; + procedure objectevent(const sender: tobject; + const event: objecteventty) override; + function checkclickstate(const info: mouseeventinfoty): boolean override; + procedure dokeypress(const sender: twidget; var info: keyeventinfoty) + override; + + procedure drawxorpic(const ashow: boolean; var canvas1: tcanvas); + procedure endmouseop1(); + procedure endmouseop2(); + procedure cancelsizing(); + + function doclose(const awidget: twidget): boolean; + procedure setmdistate(const avalue: mdistatety); virtual; + procedure domdistatechanged(const oldstate,newstate: mdistatety); virtual; + function dofloat(const adist: pointty): boolean; virtual; + function dodock(const oldparent: tdockcontroller): boolean; virtual; + procedure dochilddock(const awidget: twidget); virtual; + procedure dochildfloat(const awidget: twidget); virtual; + function docheckdock(const info: draginfoty): boolean; virtual; + function dockdrag(const dragobj: tdockdragobject): boolean; + procedure childstatechanged(const sender: twidget; + const newstate,oldstate: widgetstatesty); virtual; + + property useroptions: optionsdockty read fuseroptions write setuseroptions + default defaultoptionsdock; + + function nogrip: boolean; + function canfloat: boolean; + procedure refused(const apos: pointty); + function calclayout(const dragobject: tdockdragobject; + const nonewplace: boolean): boolean; //false if canceled + procedure setpickshape(const ashape: cursorshapety); + procedure restorepickshape; + function checkbuttonarea(const apos: pointty): dockbuttonrectty; + procedure updatesplitterrects(const awidgets: widgetarty); + procedure checksplitdir(var asplitdir: splitdirty); + procedure setoptionsdock(const avalue: optionsdockty); virtual; + function isfullarea: boolean; + function istabed: boolean; + function ismdi: boolean; + function isfloating: boolean; + function canmdisize: boolean; + procedure dolayoutchanged; virtual; + procedure doboundschanged; + procedure docaptionchanged; + function findbandpos(const apos: integer; out aindex: integer; + out arect: rectty): boolean; + //false if not found, band index and band rect + function findbandwidget(const apos: pointty; out aindex: integer; + out arect: rectty): boolean; + //false if not found. widget index and widget rect + function findbandindex(const widgetindex: integer; out aindex: integer; + out arect: rectty): boolean; + function nofit: boolean; + function writechild(const index: integer): msestring; + procedure readchildrencount(const acount: integer); + procedure readchild(const index: integer; const avalue: msestring); + procedure receiveevent(const aevent: tobjectevent); override; + function canbegindrag: boolean; override; + procedure dostatplace(const aparent: twidget; + const avisible: boolean; arect: rectty); virtual; + procedure updatetabpage(const sender: ttabpage); + public + constructor create(aintf: idockcontroller); + destructor destroy; override; + + function beforedragevent(var info: draginfoty): boolean; override; + procedure enddrag; override; + procedure mouseevent(var info: mouseeventinfoty); override; + procedure clientmouseevent(var info: mouseeventinfoty); override; + procedure childormouseevent(const sender: twidget; + var info: mouseeventinfoty); override; + procedure checkmouseactivate(const sender: twidget; + var info: mouseeventinfoty); + procedure dopaint(const acanvas: tcanvas); + //canvasorigin = container.clientpos; + procedure doactivate; + procedure sizechanged(force: boolean = false; + scalefixedalso: boolean = false; const awidgets: widgetarty = nil); + procedure parentchanged(const sender: twidget); + procedure poschanged; + procedure statechanged(const astate: widgetstatesty); virtual; + procedure widgetregionchanged(const sender: twidget); + procedure updateminscrollsize(var asize: sizety); + procedure beginclientrectchanged; + procedure endclientrectchanged; + procedure beginplacement(); + procedure endplacement(); + procedure layoutchanged; //force layout calcualation + //istatfile + procedure dostatread(const reader: tstatreader); + procedure dostatwrite(const writer: tstatwriter; + const bounds: prectty = nil); + procedure statreading; + procedure statread; + function getdockcaption: msestring; + function getfloatcaption: msestring; + function getitems: widgetarty; //reference count = 1 + function getwidget: twidget; + function activewidget: twidget; //focused child + property tabwidget: ttabwidget read ftabwidget; //can be nil + property activetabpage: ttabpage read getactivetabpage; + + function getparentcontroller( + out acontroller: tdockcontroller): boolean; overload; + function getparentcontroller: tdockcontroller; overload; + function dockparentname(): string; //'' if none + function childicon(): tmaskedbitmap virtual; + + property mdistate: mdistatety read fmdistate write setmdistate; + property currentsplitdir: splitdirty read fsplitdir + write setcurrentsplitdir; + property dockrect: rectty read getdockrect; + //origin = getwidget.container.pos + function close: boolean; //simulates mr_windowclosed for owner + function closeactivewidget: boolean; + //simulates mr_windowclosed for active widget, true if ok + function float(): boolean; //false if canceled + function dockto(const dest: tdockcontroller; const apos: pointty): boolean; + procedure dock(const source: tdockcontroller; const arect: rectty); + //simulates dostatread, use in beginplacement()/endplacement() + published + property dockhandle: tdockhandle read fdockhandle write setdockhandle; + property splitter_size: integer read fsplitter_size + write setsplitter_size default defaultsplittersize; + property splitter_grip: stockbitmapty read fsplitter_grip + write setsplitter_setgrip default defaultsplittergrip; + property splitter_color: colorty read fsplitter_color + write setsplitter_color default defaultsplittercolor; + property splitter_colorgrip: colorty read fsplitter_colorgrip + write setsplitter_colorgrip default defaultsplittercolorgrip; + property tab_options: tabbaroptionsty read ftab_options write settab_options + default defaulttaboptions; + property tab_textflags: textflagsty read ftab_textflags write + settab_textflags default defaultcaptiontextflags; + property tab_width: integer read ftab_width write settab_width default 0; + property tab_widthmin: integer read ftab_widthmin + write settab_widthmin default 0; + property tab_widthmax: integer read ftab_widthmax + write settab_widthmax default 0; + + property tab_frame: tframecomp read ftab_frame write settab_frame; + property tab_face: tfacecomp read ftab_face write settab_face; + property tab_color: colorty read ftab_color write settab_color + default cl_default; + property tab_colortab: colorty read ftab_colortab + write settab_colortab default cl_transparent; + property tab_coloractivetab: colorty read ftab_coloractivetab + write settab_coloractivetab default cl_active; + property tab_frametab: tframecomp read ftab_frametab write settab_frametab; + property tab_facetab: tfacecomp read ftab_facetab write settab_facetab; + property tab_faceactivetab: tfacecomp read ftab_faceactivetab + write settab_faceactivetab; + property tab_size: integer read ftab_size write settab_size default 0; + property tab_sizemin: integer read ftab_sizemin write settab_sizemin + default defaulttabsizemin; + property tab_sizemax: integer read ftab_sizemax write settab_sizemax + default defaulttabsizemax; + property colortab: colorty read fcolortab + write setcolortab default cl_default; + property coloractivetab: colorty read fcoloractivetab + write setcoloractivetab default cl_default; + property facetab: tfacecomp read ffacetab write setfacetab; + property faceactivetab: tfacecomp read ffaceactivetab write setfaceactivetab; + property caption: msestring read fcaption write setcaption; + property splitdir: splitdirty read fdefaultsplitdir write setsplitdir + default sd_none; //sets default and current splitdir, + //returns default + property optionsdock: optionsdockty read foptionsdock write setoptionsdock + default defaultoptionsdock; + property bandgap: integer read fbandgap write setbandgap default 0; + + property oncalclayout: docklayouteventty read foncalclayout + write foncalclayout; + property onlayoutchanged: dockcontrollereventty read fonlayoutchanged + write fonlayoutchanged; + property onboundschanged: dockcontrollereventty read fonboundschanged + write fonboundschanged; + property oncaptionchanged: dockcontrollereventty read foncaptionchanged + write foncaptionchanged; + property onbeforefloat: dockrecteventty read fonbeforefloat + write fonbeforefloat; + property onfloat: notifyeventty read fonfloat write fonfloat; + property ondock: notifyeventty read fondock write fondock; + property onchilddock: widgeteventty read fonchilddock write fonchilddock; + property onchildfloat: widgeteventty read fonchildfloat write fonchildfloat; + property oncheckdock: checkdockeventty read foncheckdock write foncheckdock; + property onmdistatechanged: mdistatechangedeventty read fonmdistatechanged + write fonmdistatechanged; + end; + + tnochildrendockcontroller = class(tdockcontroller) + public + constructor create(aintf: idockcontroller); + published + property optionsdock default defaultoptionsdocknochildren; + end; + + idocktarget = interface(inullinterface)[miid_idocktarget] + function getdockcontroller: tdockcontroller; + end; + +type + gripoptionty = (go_closebutton,go_minimizebutton,go_normalizebutton, + go_maximizebutton, + go_fixsizebutton, + go_floatbutton,go_topbutton,go_backgroundbutton, + go_lockbutton,go_nolockbutton,go_buttonframe, + go_buttonhints, + go_horz,go_vert,go_opposite,go_showsplitcaption, + go_showfloatcaption); + gripoptionsty = set of gripoptionty; + +const + defaultgripoptions = [go_closebutton,go_buttonhints]; + defaultdockpaneloptionswidget = defaultoptionswidget + [ow_subfocus]; + defaulttextflagstop = [tf_ycentered,tf_clipo]; + defaulttextflagsleft = [tf_ycentered,tf_rotate90,tf_clipo]; + defaulttextflagsbottom = [tf_ycentered,tf_clipo]; + defaulttextflagsright = [tf_ycentered,tf_rotate90,tf_clipo]; + +type + gripstatety = (grps_sizevalid); + gripstatesty = set of gripstatety; + + tgripframe = class(tcaptionframe,iobjectpicker,iface) + private + fgrip_pos: captionposty; + fgrip_color: colorty; + fgrip_size: integer; + fgrip_grip: stockbitmapty; + fgrip_options: gripoptionsty; + fgrip_colorglyph: colorty; + fcontroller: tdockcontroller; + fgrip_coloractive: colorty; + fobjectpicker: tobjectpicker; + fgrip_colorbutton: colorty; + fgrip_colorbuttonactive: colorty; + fgrip_colorglyphactive: colorty; + fgrip_face: tface; + fgrip_faceactive: tface; + fgrip_textflagstop: textflagsty; + fgrip_textflagsleft: textflagsty; + fgrip_textflagsbottom: textflagsty; + fgrip_textflagsright: textflagsty; + fgrip_captiondist: integer; + fgrip_captionoffset: integer; + fgrip_hint: msestring; + procedure setgrip_color(const avalue: colorty); + procedure setgrip_grip(const avalue: stockbitmapty); + procedure setgrip_size(const avalue: integer); + procedure setgrip_options(avalue: gripoptionsty); + procedure setgrip_colorglyph(const avalue: colorty); + function getbuttonrects(const index: dockbuttonrectty): rectty; + procedure setgrip_coloractive(const avalue: colorty); + procedure setgrip_colorbutton(const avalue: colorty); + procedure setgrip_colorbuttonactive(const avalue: colorty); + procedure setgrip_colorglyphactive(const avalue: colorty); + function getgrip_face: tface; + procedure setgrip_face(const avalue: tface); + function getgrip_faceactive: tface; + procedure setgrip_faceactive(const avalue: tface); + procedure setgrip_textflagstop(const avalue: textflagsty); + procedure setgrip_textflagsright(const avalue: textflagsty); + procedure setgrip_textflagsbottom(const avalue: textflagsty); + procedure setgrip_textflagsrright(const avalue: textflagsty); + procedure setgrip_captiondist(const avalue: integer); + procedure setgrip_captionoffset(const avalue: integer); + protected + frects: array[dbr_first..dbr_last] of rectty; + fedges: array[dbr_first..dbr_last] of edgesty; + fgriprect: rectty; + fgripstate: gripstatesty; + factgripsize: integer; + fmousebutton: dockbuttonrectty; + procedure checkgripsize; + procedure updatewidgetstate; override; + procedure updaterects; override; + procedure updatestate; override; + procedure getpaintframe(var frame: framety); override; + function ishintarea(const apos: pointty; var aid: int32): boolean; override; + function calcsizingrect(const akind: sizingkindty; + const offset: pointty): rectty; + procedure drawgripbutton(const acanvas: tcanvas; + const akind: dockbuttonrectty; const arect: rectty; + const acolorglyph,acolorbutton: colorty; + const ahiddenedges: edgesty); virtual; + + //iface + function getclientrect: rectty; + procedure invalidatewidget(); + procedure invalidaterect(const rect: rectty; + const org: originty = org_client; const noclip: boolean = false); + function translatecolor(const acolor: colorty): colorty; + procedure setlinkedvar(const source: tmsecomponent; var dest: tmsecomponent; + const linkintf: iobjectlink = nil); + function getcomponentstate: tcomponentstate; + procedure widgetregioninvalid; + //iobjectpicker + function getwidget: twidget; + function getcursorshape(const sender: tobjectpicker; + var shape: cursorshapety): boolean; + //true if found + procedure getpickobjects(const sender: tobjectpicker; + var objects: integerarty); + procedure beginpickmove(const sender: tobjectpicker); + procedure pickthumbtrack(const sender: tobjectpicker); + procedure endpickmove(const sender: tobjectpicker); + procedure cancelpickmove(const sender: tobjectpicker); + procedure paintxorpic(const sender: tobjectpicker; const canvas: tcanvas); + procedure internalpaintoverlay(const canvas: tcanvas; + const arect: rectty) override; + + public + constructor create(const aintf: icaptionframe; + const acontroller: tdockcontroller); + destructor destroy; override; + procedure createface(); + procedure createfaceactive(); + + procedure checktemplate(const sender: tobject) override; + procedure showhint(const aid: int32; var info: hintinfoty); override; + procedure updatemousestate(const sender: twidget; + const info: mouseeventinfoty); override; + procedure mouseevent(var info: mouseeventinfoty); + property buttonrects[const index: dockbuttonrectty]: rectty + read getbuttonrects; + //client origin + function getminimizedsize(out apos: captionposty): sizety; + function griprect: rectty; //origin = pos + published + property grip_size: integer read fgrip_size write setgrip_size stored true; + //for optionalclass + property grip_textflagstop: textflagsty read fgrip_textflagstop + write setgrip_textflagstop default defaulttextflagstop; + property grip_textflagsleft: textflagsty read fgrip_textflagsleft + write setgrip_textflagsright default defaulttextflagsleft; + property grip_textflagsbottom: textflagsty read fgrip_textflagsbottom + write setgrip_textflagsbottom default defaulttextflagsbottom; + property grip_textflagsright: textflagsty read fgrip_textflagsright + write setgrip_textflagsrright default defaulttextflagsright; + property grip_captiondist: integer read fgrip_captiondist + write setgrip_captiondist default 1; + property grip_captionoffset: integer read fgrip_captionoffset + write setgrip_captionoffset default 0; + property grip_grip: stockbitmapty read fgrip_grip write setgrip_grip + default defaultgripgrip; + property grip_color: colorty read fgrip_color write setgrip_color + default defaultgripcolor; + property grip_coloractive: colorty read fgrip_coloractive + write setgrip_coloractive default defaultgripcoloractive; + property grip_colorglyph: colorty read fgrip_colorglyph write + setgrip_colorglyph default cl_glyph; + property grip_colorglyphactive: colorty read fgrip_colorglyphactive write + setgrip_colorglyphactive default cl_glyphactive; + property grip_colorbutton: colorty read fgrip_colorbutton write + setgrip_colorbutton default cl_transparent; + property grip_colorbuttonactive: colorty read fgrip_colorbuttonactive write + setgrip_colorbuttonactive default cl_transparent; + property grip_options: gripoptionsty read fgrip_options write setgrip_options + default defaultgripoptions; + property grip_face: tface read getgrip_face write setgrip_face; + property grip_faceactive: tface read getgrip_faceactive + write setgrip_faceactive; + property grip_hint: msestring read fgrip_hint write fgrip_hint; + end; + + tdockpanel = class(tscalingwidget,idockcontroller,idocktarget,istatfile) + private + fdragdock: tnochildrendockcontroller; + foptionswindow: windowoptionsty; + fstatfile: tstatfile; + fstatvarname: msestring; + ficon: tmaskedbitmap; + fstatpriority: integer; + fdockingareacaption: msestring; + procedure setdragdock(const Value: tnochildrendockcontroller); + function getframe: tgripframe; + procedure setframe(const Value: tgripframe); + procedure setstatfile(const Value: tstatfile); + procedure seticon(const avalue: tmaskedbitmap); + procedure iconchanged(const sender: tobject); + procedure setdockingareacaption(const avalue: msestring); + protected +// procedure mouseevent(var info: mouseeventinfoty); override; + procedure childmouseevent(const sender: twidget; + var info: mouseeventinfoty); override; + procedure updatewindowinfo(var info: windowinfoty); override; + procedure internalcreateframe; override; + procedure clientrectchanged; override; + procedure widgetregionchanged(const sender: twidget); override; + procedure setparentwidget(const Value: twidget); override; + procedure dopaintforeground(const acanvas: tcanvas); override; + procedure doactivate; override; + procedure statechanged; override; + procedure poschanged; override; + procedure parentchanged; override; + function calcminscrollsize: sizety; override; + procedure dopaintbackground(const canvas: tcanvas); override; + //idockcontroller + function checkdock(var info: draginfoty): boolean; + function getbuttonrects(const index: dockbuttonrectty): rectty; + function getplacementrect: rectty; + function getminimizedsize(out apos: captionposty): sizety; + function getcaption: msestring; + function getchildicon: tmaskedbitmap; + procedure dolayoutchanged(const sender: tdockcontroller); virtual; + procedure dodockcaptionchanged(const sender: tdockcontroller); virtual; + //istatfile + procedure dostatread(const reader: tstatreader); + procedure dostatwrite(const writer: tstatwriter); + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure dragevent(var info: draginfoty); override; + function getdockcontroller: tdockcontroller; + published + property dragdock: tnochildrendockcontroller read fdragdock write setdragdock; + property optionswidget default defaultdockpaneloptionswidget; + property optionswindow: windowoptionsty read foptionswindow + write foptionswindow default []; + property frame: tgripframe read getframe write setframe; + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read fstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + property icon: tmaskedbitmap read ficon write seticon; + property dockingareacaption: msestring read fdockingareacaption + write setdockingareacaption; + end; + +procedure paintdockingareacaption(const canvas: tcanvas; const sender: twidget; + const atext: msestring = 'Docking Area'); + +implementation +uses + msearrayutils,sysutils,msebits,{msetabs,}mseguiintf,{mseforms,}msestream, + mseformatstr,msekeyboard; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + twidget1 = class(twidget); + twindow1 = class(twindow); + tcustomframe1 = class(tcustomframe); + tcustomtabwidget1 = class(tcustomtabwidget); + tface1 = class(tface); + ttabwidget1 = class(ttabwidget); + +const + useroptionsmask: optionsdockty = [od_fixsize,od_top,od_background, + od_lock,od_nolock]; + +type + tchildorderevent = class(tobjectevent) + protected + fchildren: stringarty; + ffocusedchild: integer; + public + constructor create(const sender: tdockcontroller); + end; + + tdocktabwidget = class(ttabwidget) + private + fcontroller: tdockcontroller; + protected + procedure doclosepage(const sender: tobject); override; + procedure dopageremoved(const apage: twidget); override; + procedure tabchanged(const synctabindex: boolean); override; + procedure updateoptions; + public + constructor create(const acontroller: tdockcontroller; + const aparent: twidget); reintroduce; + destructor destroy; override; + end; + + tdocktabpage = class(ttabpage,idocktarget) + private + fcontroller: tdockcontroller; + ftarget: twidget; + ftargetanchors: anchorsty; + //idocktarget + function getdockcontroller: tdockcontroller; + protected + procedure unregisterchildwidget(const child: twidget); override; + procedure widgetregionchanged(const sender: twidget); override; + public + constructor create(const atabwidget: tdocktabwidget; const awidget: twidget); + reintroduce; + destructor destroy(); override; + end; + +procedure paintdockingareacaption(const canvas: tcanvas; const sender: twidget; + const atext: msestring = 'Docking Area'); +begin + if sender.visiblechildrencount = 0 then begin + canvas.save; + canvas.font.height:= 20; + drawtext(canvas,atext,sender.paintclientrect(), + [tf_xcentered,tf_ycentered,tf_grayed]); + canvas.restore; + end; +end; + +{ twidgetdragobject } + +constructor twidgetdragobject.create(const asender: twidget; + var instance: tdragobject; const apickpos: pointty); +begin + inherited create(asender,instance,apickpos); +end; + +function twidgetdragobject.getwidget: twidget; +begin + result:= twidget(fsender); +end; + +{ tdockdragobject } + +constructor tdockdragobject.create(const adock: tdockcontroller; + const asender: twidget; var instance: tdragobject; + const apickpos: pointty); +begin + fdock:= adock; + inherited create(asender,instance,apickpos); +end; + +destructor tdockdragobject.destroy; +begin + if fcheckeddockcontroller <> nil then begin + fcheckeddockcontroller.fasplitdir:= sd_none; + end; + inherited; +end; + +procedure tdockdragobject.drawxorpic; +begin + if fxorwidget <> nil then begin + with fxorwidget.getcanvas(org_screen) do begin + drawxorframe(fxorrect,-3,stockobjects.bitmaps[stb_dens50]); + end; + end; +end; + +procedure tdockdragobject.refused(const apos: pointty); +begin + inherited; + drawxorpic; + fxorwidget:= nil; + fdock.refused(apos); +end; + +procedure tdockdragobject.setxorwidget(const awidget: twidget; + const screenrect: rectty); +begin + if (awidget <> fxorwidget) or not rectisequal(fxorrect,screenrect) then begin + drawxorpic; + fxorwidget:= awidget; + fxorrect:= screenrect; + drawxorpic; + end; +end; + +{ tdocktabwidget } + +constructor tdocktabwidget.create(const acontroller: tdockcontroller; + const aparent: twidget); +begin + fcontroller:= acontroller; + inherited create(nil); + parentwidget:= aparent; + updateoptions; + synctofontheight; +end; + +procedure tdocktabwidget.updateoptions; +begin + with fcontroller do begin + self.tab_options:= ftab_options; + self.tab_color:= ftab_color; + self.tab_colortab:= ftab_colortab; + self.tab_coloractivetab:= ftab_coloractivetab; + self.tab_size:= ftab_size; + self.tab_sizemin:= ftab_sizemin; + self.tab_sizemax:= ftab_sizemax; + self.tab_textflags:= ftab_textflags; + self.tab_width:= ftab_width; + self.tab_widthmin:= ftab_widthmin; + self.tab_widthmax:= ftab_widthmax; + if ftab_frame <> nil then begin + self.tab_frame:= tstepboxframe1(1); + self.tab_frame.assign(ftab_frame); + end + else begin + self.tab_frame:= nil; + end; + if ftab_face <> nil then begin + self.tab_face:= tface(1); + self.tab_face.assign(ftab_face); + end + else begin + self.tab_face:= nil; + end; + if ftab_frametab <> nil then begin + self.tab_frametab:= ttabframe(1); + self.tab_frametab.assign(ftab_frametab); + end + else begin + self.tab_frametab:= nil; + end; + if ftab_facetab <> nil then begin + self.tab_facetab:= tface(1); + self.tab_facetab.assign(ftab_facetab); + end + else begin + self.tab_facetab:= nil; + end; + if ftab_faceactivetab <> nil then begin + self.tab_faceactivetab:= tface(1); + self.tab_faceactivetab.assign(ftab_faceactivetab); + end + else begin + self.tab_faceactivetab:= nil; + end; + end; +end; + +destructor tdocktabwidget.destroy; +begin + if fcontroller.ftabwidget = self then begin + fcontroller.ftabwidget:= nil; + end; + inherited; +end; + +procedure tdocktabwidget.doclosepage(const sender: tobject); +begin + fcontroller.doclose(tdocktabpage(items[fpopuptab]).ftarget); +end; + +procedure tdocktabwidget.dopageremoved(const apage: twidget); +begin + inherited; + if (count = 0) and not application.terminated then begin + fcontroller.ftabwidget:= nil; + fcontroller.fsplitterrects:= nil; + release; + end; + fcontroller.dolayoutchanged(); +end; + +procedure tdocktabwidget.tabchanged(const synctabindex: boolean); +begin + inherited; + if fcontroller.fintf.getwidget.componentstate * + [csloading,csdestroying] = [] then begin + fcontroller.dolayoutchanged(); + end; +end; + +{ tdocktabpage } + +constructor tdocktabpage.create(const atabwidget: tdocktabwidget; + const awidget: twidget); +var + intf1: idocktarget; +begin + fcontroller:= atabwidget.fcontroller; + inherited create(nil); + optionswidget:= optionswidget - [ow_destroywidgets]; + ftarget:= awidget; + ftargetanchors:= awidget.anchors; + if awidget.getcorbainterface(typeinfo(idocktarget),intf1) then begin + intf1.getdockcontroller.updatetabpage(self); +// caption:= intf1.getdockcontroller.getdockcaption; + + end + else begin + caption:= 'Page '+inttostrmse(atabwidget.count); + end; + awidget.anchors:= []; + parentwidget:= atabwidget; + insertwidget(awidget,paintpos); +end; + +destructor tdocktabpage.destroy(); +begin + fcontroller.ftabpage:= nil; + inherited; +end; + +procedure tdocktabpage.unregisterchildwidget(const child: twidget); +begin + inherited; + if (child = ftarget) then begin +// ftarget:= nil; + child.anchors:= ftargetanchors; + if not application.terminated then begin + visible:= false; + parentwidget:= nil; + release; + end; + end; +end; + +procedure tdocktabpage.widgetregionchanged(const sender: twidget); +var + focusedwidgetbefore: twidget; +begin + inherited; + if (sender <> nil) and (sender = ftarget) and not sender.visible and + (fparentwidget <> nil) and (fparentwidget.parentwidget <> nil) and + not (csdestroying in sender.componentstate) then begin + optionswidget:= optionswidget - [ow_tabfocus]; //don't accept focus + focusedwidgetbefore:= nil; + if entered then begin + setlinkedvar(window.focusedwidget,tmsecomponent(focusedwidgetbefore)); + end; + try + sender.parentwidget:= fparentwidget.parentwidget; //remove page + if (focusedwidgetbefore <> nil) and (window.focusedwidget = nil) then begin + focusedwidgetbefore.parentfocus; //restore focus + end; + finally + setlinkedvar(nil,tmsecomponent(focusedwidgetbefore)); + end; + end; +end; + +function tdocktabpage.getdockcontroller: tdockcontroller; +begin + result:= fcontroller; +end; + +{ tdockcontroller } + +constructor tdockcontroller.create(aintf: idockcontroller); +begin + fr:= @rectaccessx; + fw:= @widgetaccessx; + fsizeindex:= -1; + foptionsdock:= defaultoptionsdock; + fuseroptions:= defaultoptionsdock; + fsplitter_grip:= defaultsplittergrip; + fsplitter_color:= defaultsplittercolor; + fsplitter_colorgrip:= defaultsplittercolorgrip; + fsplitter_size:= defaultsplittersize; + ftab_options:= defaulttaboptions; + ftab_color:= cl_default; + ftab_colortab:= cl_transparent; + ftab_coloractivetab:= cl_active; + ftab_sizemin:= defaulttabsizemin; + ftab_sizemax:= defaulttabsizemax; + ftab_textflags:= defaultcaptiontextflags; + fcolortab:= cl_default; + fcoloractivetab:= cl_default; + fmdistate:= mds_floating; + inherited create(aintf); +end; + +destructor tdockcontroller.destroy; +begin + freeandnil(ftabwidget); + inherited; +end; + +function tdockcontroller.checksplit(const awidgets: widgetarty; + out propsize,varsize,fixsize,fixcount: integer; + out isprop,isfix: booleanarty; + const fixedareprop: boolean): widgetarty; + //calculate order and total widths/heights of elements +var + ar1: widgetarty; + int1,int2,int3: integer; + intf1: idocktarget; + opt1: optionsdockty; + fixend: boolean; + banded: boolean; +// needspropref: boolean; + dcont1: tdockcontroller; + widget1: twidget; + bo1: boolean; +begin + checkdirection; + banded:= (od_banded in foptionsdock) and (fsplitdir in [sd_vert,sd_horz]); + if awidgets = nil then begin + if (fsplitdir = sd_vert) then begin + ar1:= fintf.getwidget.getsortxchildren(banded); + end + else begin + if (fsplitdir = sd_horz) or (fsplitdir = sd_tabed) then begin + ar1:= fintf.getwidget.getsortychildren(banded); + end + else begin + ar1:= nil; + end; + end; + end + else begin + if fsplitdir = sd_tabed then begin + ar1:= nil; + end + else begin + ar1:= awidgets; + end; + end; + setlength(result,length(ar1)); + setlength(isprop,length(ar1)); + setlength(isfix,length(ar1)); + int2:= 0; + propsize:= 0; + varsize:= 0; + fixsize:= 0; + fixcount:= 0; + fixend:= foptionsdock * [od_nofit] <> []; +// needspropref:= false; + for int1:= 0 to high(ar1) do begin + widget1:= ar1[int1]; + with twidget1(widget1) do begin + include(fwidgetstate1,ws1_nominsize); + if not (ow1_noautosizing in foptionswidget1) then begin + if visible then begin + result[int2]:= ar1[int1]; + if fixend then begin + isfix[int2]:= true; + inc(fixcount); + end + else begin + if ar1[int1].getcorbainterface(typeinfo(idocktarget),intf1) then begin + dcont1:= intf1.getdockcontroller; + if dcont1.fmdistate = mds_floating then begin + dcont1.fmdistate:= mds_normal; //placed by setparent + end; + opt1:= dcont1.foptionsdock; +// needspropref:= needspropref or not (dos_proprefvalid in dcont1.fdockstate); + dcont1.fdockstate:= dcont1.fdockstate + [{dos_proprefvalid,}dos_showed]; + bo1:= false; + if dos_sizing in fdockstate then begin + if fsplitdir in [sd_vert,sd_horz] then begin + int3:= fr^.si(dcont1.fhiddensizeref); + bo1:= int3 > 0; //widget is visible again, restore old size + if bo1 and (opt1 * [od_propsize,od_fixsize] = [od_propsize]) then begin + fw^.setsize(widget1, + fw^.size(widget1)*fr^.si(fplacementrect.size) div int3); + //adjust to current container size + end; + end; + dcont1.fhiddensizeref:= nullsize; + end; +// include(dcont1.fdockstate,dos_proprefvalid); + if bo1 or not fixedareprop and (od_fixsize in opt1) then begin + isfix[int2]:= true; + inc(fixcount); + end; + if not bo1 and ((od_propsize in opt1) and not (od_fixsize in opt1) or + fixedareprop and (od_fixsize in opt1)) then begin + isprop[int2]:= true; + propsize:= propsize + fw^.size(ar1[int1]); + end + end; + end; + if not isprop[int2] then begin + fixsize:= fixsize + fw^.size(ar1[int1]); + if not isfix[int2] then begin + varsize:= varsize + fw^.size(ar1[int1]); + end; + end; + inc(int2); + end + else begin + if ar1[int1].getcorbainterface(typeinfo(idocktarget),intf1) then begin + dcont1:= intf1.getdockcontroller; + if dcont1.fmdistate = mds_floating then begin + dcont1.fmdistate:= mds_normal; //placed by setparent + end; + if dos_showed in dcont1.fdockstate then begin + exclude(dcont1.fdockstate,dos_showed); + if not (dos_updating4 in dcont1.fdockstate) then begin //no statreading + dcont1.fhiddensizeref:= fplacementrect.size; + end; + end; + end; + end; + end; + end; + end; +// if needspropref then begin +// updaterefsize; +// end; + setlength(result,int2); + setlength(isprop,int2); + setlength(isfix,int2); + if (awidgets = nil) and not banded and (fsplitdir in [sd_vert,sd_horz]) and + (high(result) > 0) and (fw^.pos(result[0]) = fw^.pos(result[1])) and + (finditem(pointerarty(fwidgetsbefore),pointer(result[1])) < 0) then begin + widget1:= result[0]; //probably revisible + result[0]:= result[1]; + result[1]:= widget1; + bo1:= isprop[0]; + isprop[0]:= isprop[1]; + isprop[1]:= bo1; + bo1:= isfix[0]; + isfix[0]:= isfix[1]; + isfix[1]:= bo1; + end; + fwidgetsbefore:= result; +end; + +function tdockcontroller.checksplit(out propsize,fixsize: integer; + out isprop,isfix: booleanarty; const fixedareprop: boolean): widgetarty; +var + int1,int2: integer; +begin + result:= checksplit(nil,propsize,int1,fixsize,int2,isprop,isfix,fixedareprop); +end; + +function tdockcontroller.checksplit: widgetarty; +var + ar1,ar2: booleanarty; + int1,int2,int3,int4: integer; +begin + if ftabwidget <> nil then begin + setlength(result,tdocktabwidget(ftabwidget).count); + int2:= 0; + for int1:= 0 to high(result) do begin + result[int2]:= tdocktabpage(tdocktabwidget(ftabwidget)[int1]).ftarget; + if result[int2] <> nil then begin + inc(int2); + end; + end; + setlength(result,int2); + end + else begin + result:= checksplit(nil,int1,int2,int3,int4,ar1,ar2,false); + end; +end; + +procedure tdockcontroller.sizechanged(force: boolean = false; + scalefixedalso: boolean = false; + const awidgets: widgetarty = nil); +var + ar1: widgetarty; + ar2: realarty; + prop,fix: booleanarty; + fixsize: integer; + propsize: integer; + banded: boolean; + opt1: optionsdockty; + + procedure calcsize; + var + int1: integer; + rea1,rea2: real; + begin + int1:= fr^.size(fplacementrect) - high(ar1) * fsplitter_size - fixsize; + if int1 < 0 then begin + int1:= 0; + end; + if (frefsize > 0) and (high(ar1) = high(fsizes)) then begin + rea1:= int1 / frefsize; + for int1:= 0 to high(ar1) do begin + if prop[int1] then begin + ar2[int1]:= fsizes[int1] * rea1; + end + else begin + ar2[int1]:= fw^.size(ar1[int1]); + end; + end; + end + else begin + if (propsize = 0) then begin + rea1:= 1; + end + else begin + rea1:= int1/propsize; + end; + for int1:= 0 to high(ar1) do begin + ar2[int1]:= fw^.size(ar1[int1]); + if prop[int1] then begin + ar2[int1]:= ar2[int1] * rea1; + end; + end; + end; + rea2:= 0; + for int1:= 0 to high(ar2) do begin + if (fw^.max(ar1[int1]) <> 0) and (ar2[int1] > fw^.max(ar1[int1])) then begin + ar2[int1]:= fw^.max(ar1[int1]); + end; + if ar2[int1] < fw^.min(ar1[int1]) then begin + ar2[int1]:= fw^.min(ar1[int1]); + end; + rea2:= rea2 + ar2[int1]; //total size + end; + rea1:= fr^.size(fplacementrect); + if not nofit then begin + //adjust sizes for fit + rea2:= rea1 - (rea2 + high(ar2) * fsplitter_size); + //delta + if rea2 < 0 then begin + for int1:= high(ar2) downto 0 do begin + if not (fix[int1] and not scalefixedalso) and not prop[int1] then begin + rea1:= fw^.min(ar1[int1]); + ar2[int1]:= ar2[int1] + rea2; + if ar2[int1] < rea1 then begin + rea2:= ar2[int1] - rea1; + ar2[int1]:= rea1; + end + else begin + break; + end; + end; + end; + end + else begin + for int1:= high(ar2) downto 0 do begin + if not fix[int1] and not prop[int1] then begin + rea1:= fw^.max(ar1[int1]); + ar2[int1]:= ar2[int1] + rea2; + if (ar2[int1] > rea1) and (rea1 > 0) then begin + rea2:= ar2[int1] - rea1; + ar2[int1]:= rea1; + end + else begin + break; + end; + end; + end; + end; + end; + rea2:= fr^.pos(fplacementrect); + ar2[0]:= ar2[0] + rea2 + fsplitter_size; + for int1:= 1 to high(ar1) do begin //calc pos vector + ar2[int1]:= ar2[int1-1] + fsplitter_size + ar2[int1]; + end; + end; //calcsize + +var + minsize1: integer; + + procedure calcpos; + var + bandindex: integer; + + procedure calcbandheight(const aindex: integer); + var + int2,int3,int4: integer; + begin + setlength(fbands,high(fbands)+2); + int3:= 0; + for int2:= bandindex to aindex - 1 do begin + int4:= fw^.osize(ar1[int2]); + if int4 > int3 then begin + int3:= int4; //find biggest widget + end; + end; + with fbands[high(fbands)] do begin + first:= bandindex; + last:= aindex-1; + size:= int3; + end; + bandindex:= aindex; + end; //calcbandheight + + var + rea1,rea2: real; + int1: integer; + rect1: prectty; + rect2: rectty; + ar3: rectarty; + int2: integer; + bandpos: integer; + + procedure clipwidget; + var + int1: integer; + begin + int1:= fr^.stop(fplacementrect) - fsplitter_size; + if fr^.stop(rect1^) > int1 then begin + fr^.setstop(rect1^,int1); + end; + end; //clipwidget + + begin + rea2:= fr^.pos(fplacementrect); + if not nofit then begin + setlength(fbands,1); + with fbands[0] do begin + first:= 0; + last:= high(ar1); + size:= fr^.osize(fplacementrect); + end; + rect2:= fplacementrect; + for int1:= 0 to high(ar1) do begin + fr^.setpos(rect2,round(rea2)); + fr^.setsize(rect2,round(ar2[int1] - rea2) - fsplitter_size); + ar1[int1].widgetrect:= rect2; + rea2:= rea2 + fw^.size(ar1[int1]) + fsplitter_size; + end; + minsize1:= fr^.stop(rect2) - fr^.pos(fplacementrect); + end + else begin + setlength(ar3,length(ar1)); + bandindex:= 0; + rea1:= 0; + int2:= 0; + for int1:= 0 to high(ar1) do begin + rect1:= @ar3[int1]; //set size + rect1^:= fplacementrect; + fr^.setpos(rect1^,round(rea2)); + fr^.setsize(rect1^,round(ar2[int1] - rea2 - rea1) - fsplitter_size); + if banded and + (fr^.stop(rect1^) + fsplitter_size > fr^.stop(fplacementrect)) then begin + if int1 > int2 then begin //next band + calcbandheight(int1); + int2:= int1; // minimal one widget in band + fr^.setpos(rect1^,fr^.pos(fplacementrect)); //restart + clipwidget; + rea1:= rea1 + rea2; + rea2:= fr^.pos(rect1^); + rea1:= rea1 - rea2; + end + else begin + clipwidget; + end; + end; + rea2:= rea2 + fr^.size(rect1^) + fsplitter_size; + end; + calcbandheight(length(ar1)); + if not banded then begin + fbands[0].size:= fr^.osize(fplacementrect); + end; + bandpos:= fbandstart; + for int2:= 0 to high(fbands) do begin + with fbands[int2] do begin + for int1:= first to last do begin + rect1:= @ar3[int1]; //set ortho size + fr^.setosize(rect1^,fw^.osize(ar1[int1])); + if opt1 = [od_aligncenter] then begin + fr^.setopos(rect1^, + bandpos + (size-fr^.osize(rect1^)) div 2); + end + else begin + if opt1 = [od_alignend] then begin + fr^.setopos(rect1^,bandpos + (size-fr^.osize(rect1^))); + end + else begin + if opt1 = [od_alignbegin] then begin + fr^.setopos(rect1^,bandpos); + end + else begin + fr^.setopos(rect1^,bandpos + fr^.osize(rect1^)); + end; + end; + end; + ar1[int1].widgetrect:= rect1^; + end; + bandpos:= bandpos + size + fbandgap; + end; + end; + end; + end; //calcpos + +var + needsfixscale: boolean; + hasparent1: boolean; + + procedure updateplacement; + var + widget1: twidget; + int1: integer; + begin + widget1:= fintf.getwidget; + int1:= minsize1 - fr^.size(fplacementrect); + if (int1 > 0) then begin //extend placementrect + if not scalefixedalso and + not (od_expandforfixsize in foptionsdock) then begin + needsfixscale:= true; + end + else begin + if hasparent1 then begin + fw^.setanchordsize(widget1,fw^.size(widget1)+int1); //extend size + { + if not fw^.anchstop(widget1) then begin + fw^.setsize(widget1,fw^.size(widget1)+int1); //extend size + end + else begin + if not fw^.anchboth(widget1) then begin //use setanchordsize? + widget1.parentwidget.clientsize:= + addsize(widget1.parentwidget.clientsize,fr^.makesize(int1,0)); + //not async +// widget1.parentwidget.changeclientsize(fr^.makesize(int1,0)); + end; + end; + } + end; + end; + end + else begin + if not nofit then begin + fw^.setstop(ar1[high(ar1)],fr^.stop(fplacementrect)); + end; + end; + end; + +var + int1,int2: integer; + widget1: twidget; + widget2: twidget; + +begin + widget2:= fintf.getwidget; + hasparent1:= widget2.parentwidget <> nil; + widget1:= widget2.container; + checkdirection; + if (widget1 <> nil) and + (widget1.ComponentState * [csloading,csdesigning] = []) then begin + banded:= od_banded in foptionsdock; + fplacementrect:= idockcontroller(fintf).getplacementrect; + fbandstart:= fr^.opos(fplacementrect); + if fsplitdir in [sd_vert,sd_horz] then begin + ar1:= nil; //compiler warning + if not sizeisequal(fsize,fplacementrect.size) or force then begin + fbands:= nil; + fsize:= fplacementrect.size; + if fdockstate * [dos_updating1,dos_updating2,dos_updating4] <> [] then begin + exclude(fdockstate,dos_layoutvalid); + end + else begin + needsfixscale:= false; + fdockstate:= fdockstate + [dos_layoutvalid,dos_updating2,dos_sizing]; + try + inc(frecalclevel); + ar1:= checksplit(awidgets,propsize,int1,fixsize,int2,prop,fix,false); + if high(ar1) >= 0 then begin + setlength(ar2,length(ar1)); + if not (od_proportional in foptionsdock) then begin + for int1:= 0 to high(prop) do begin + prop[int1]:= false; + end; + end; + minsize1:= 0; + opt1:= foptionsdock * [od_alignbegin,od_aligncenter,od_alignend]; + if fsplitdir in [sd_vert,sd_horz] then begin + calcsize; + calcpos; + end; + if (opt1 = []) and not nofit then begin + updateplacement; + end; + end; + finally + fdockstate:= fdockstate - [dos_updating1,dos_updating2,dos_sizing]; + if (not (dos_layoutvalid in fdockstate) or needsfixscale) and + (frecalclevel < 4) then begin + try + sizechanged(force or needsfixscale,needsfixscale); + finally + dec(frecalclevel); + end; + end + else begin + dec(frecalclevel); + updatesplitterrects(ar1); + end; + end; + end; + end; + end + else begin + if (fsplitdir = sd_tabed) and (ws_loadedproc in widget1.widgetstate) and + (awidgets = nil) then begin + calclayout(nil,false); + end; + fbands:= nil; + if ismdi then begin + case fmdistate of + mds_normal: begin + fnormalrect:= widget2.widgetrect; + end; + end; + end; + end; + end; + doboundschanged; +end; + +procedure tdockcontroller.dopaint(const acanvas: tcanvas); //canvasorigin = container.clientpos; +var + int1: integer; + color1: colorty; + brush1: tsimplebitmap; +begin + if fsplitterrects <> nil then begin + if fsplitter_color <> cl_none then begin + for int1:= 0 to high(fsplitterrects) do begin + acanvas.fillrect(fsplitterrects[int1],fsplitter_color); + end; + end; + if fsplitter_grip <> stb_none then begin + with acanvas do begin + color1:= color; + brush1:= brush; + brush:= stockobjects.bitmaps[fsplitter_grip]; + color:= fsplitter_colorgrip; + for int1:= 0 to high(fsplitterrects) do begin + fillrect(fsplitterrects[int1],cl_brushcanvas); + end; + brush:= brush1; + color:= color1; + end; + end; + end; +end; + +procedure tdockcontroller.doactivate; +var + size1: sizety; + intf1: idocktarget; + widget1: twidget; +begin + size1:= fintf.getwidget.size; + if (size1.cx <= 0) or (size1.cy <= 0) then begin + widget1:= fintf.getwidget.parentwidget; + if (widget1 <> nil) and widget1.getcorbainterface(typeinfo(idocktarget),intf1) then begin + intf1.getdockcontroller.calclayout(nil,false); + end; + end; +end; + +procedure tdockcontroller.updategrip(const asplitdir: splitdirty; + const awidget: twidget); +var + frame1: tcustomframe; + grippos1: captionposty; +begin + frame1:= twidget1(awidget).fframe; + if frame1 is tgripframe then begin + with tgripframe(frame1) do begin + grippos1:= fgrip_pos; + if fgrip_options * [go_horz,go_vert] = [] then begin + if asplitdir = sd_vert then begin + if go_opposite in fgrip_options then begin + fgrip_pos:= cp_bottom; + end + else begin + fgrip_pos:= cp_top; + end; + end + else begin + if (asplitdir = sd_horz) or (asplitdir = sd_tabed) or + (asplitdir = sd_none) then begin + if go_opposite in fgrip_options then begin + fgrip_pos:= cp_left; + end + else begin + fgrip_pos:= cp_right; + end; + end; + end; + end; + if grippos1 <> fgrip_pos then begin + internalupdatestate; + end; + end; + end; +end; + +procedure tdockcontroller.updatesplitterrects(const awidgets: widgetarty); +var + fixend: boolean; + + procedure calcsplitters; + var + rect1: rectty; + int1,int2: integer; + bandpos: integer; + begin + fr^.setsize(rect1,fsplitter_size); + bandpos:= fbandstart; + for int2:= 0 to high(fbands) do begin + with fbands[int2] do begin + fr^.setopos(rect1,bandpos); + fr^.setosize(rect1,size); + for int1:= first to last do begin + fr^.setpos(rect1,fw^.stop(awidgets[int1])); + fsplitterrects[int1]:= rect1; + end; + bandpos:= bandpos + size + fbandgap; + end; + end; + end; + +var + po1: pointty; + int1: integer; + sd1: splitdirty; +begin + sd1:= fsplitdir; + if nofit then begin + if sd1 = sd_vert then begin + sd1:= sd_horz; + end + else begin + sd1:= sd_vert; + end; + end; + for int1:= 0 to high(awidgets) do begin + updategrip(sd1,awidgets[int1]); + end; + if (high(awidgets) >= 0) and (fsplitter_size > 0) and + ((fsplitter_color <> cl_none) or (fsplitter_grip <> stb_none)) then begin + fixend:= foptionsdock * [od_nofit] <> []; + setlength(fsplitterrects,length(awidgets)); + calcsplitters; + if not fixend then begin + setlength(fsplitterrects,high(fsplitterrects)); + end; + po1:= fintf.getwidget.container.clientwidgetpos; + for int1:= 0 to high(fsplitterrects) do begin + subpoint1(fsplitterrects[int1].pos,po1); //clientorg + end; + end + else begin + fsplitterrects:= nil; + end; + fintf.getwidget.container.invalidate; +end; + +procedure tdockcontroller.checksplitdir(var asplitdir: splitdirty); +begin + if asplitdir = sd_none then begin + asplitdir:= fdefaultsplitdir; + end; + if not (od_splitvert in foptionsdock) and (asplitdir = sd_vert) then begin + asplitdir:= sd_none; + end; + if not (od_splithorz in foptionsdock) and (asplitdir = sd_horz) then begin + asplitdir:= sd_none; + end; + if not (od_tabed in foptionsdock) and (asplitdir = sd_tabed) then begin + asplitdir:= sd_none; + end; + if (asplitdir = sd_none) then begin + if od_splithorz in foptionsdock then begin + asplitdir:= sd_horz; + end + else begin + if od_splitvert in foptionsdock then begin + asplitdir:= sd_vert; + end + else begin + if od_tabed in foptionsdock then begin + asplitdir:= sd_tabed; + end; + end; + end; + end; +end; + +procedure tdockcontroller.setoptionsdock(const avalue: optionsdockty); +const + mask1: optionsdockty = [od_top,od_background]; + mask2: optionsdockty = [od_alignbegin,od_aligncenter,od_alignend]; + +var + splitdirbefore: splitdirty; + intf1: idocktarget; + cont1: tdockcontroller; + int1: integer; + val1,val2{,val3}: optionsdockty; + bo1: boolean; + optbefore: optionsdockty; +begin + if foptionsdock <> avalue then begin + optbefore:= foptionsdock; + bo1:= od_fixsize in foptionsdock; + splitdirbefore:= fsplitdir; + val1:= optionsdockty( + setsinglebit({$ifdef FPC}longword{$else}longword{$endif}(avalue), + {$ifdef FPC}longword{$else}longword{$endif}(foptionsdock), + {$ifdef FPC}longword{$else}longword{$endif}(mask1))); + val2:= optionsdockty( + setsinglebit({$ifdef FPC}longword{$else}longword{$endif}(avalue), + {$ifdef FPC}longword{$else}longword{$endif}(foptionsdock), + {$ifdef FPC}longword{$else}longword{$endif}(mask2))); + foptionsdock:= ((avalue - (mask1+mask2)) + val1*mask1 + val2*mask2) - + deprecatedoptionsdock; + if not (od_nofit in foptionsdock) then begin + if not (od_banded in optbefore) and (od_banded in foptionsdock) then begin + include(foptionsdock,od_nofit); + end + else begin + exclude(foptionsdock,od_banded); + end; + end; + if (od_banded in foptionsdock) and (foptionsdock * mask2 = []) then begin + include(foptionsdock,od_aligncenter); + end; + { + if bo1 xor (od_fixsize in foptionsdock) then begin + exclude(fdockstate,dos_proprefvalid); + end; + } + fuseroptions:= foptionsdock; + checksplitdir(fsplitdir); + with fintf.getwidget do begin + if od_top in foptionsdock then begin + optionswidget:= optionswidget + [ow_top]; + end + else begin + optionswidget:= optionswidget - [ow_top]; + end; + if od_background in foptionsdock then begin + optionswidget:= optionswidget + [ow_background]; + end + else begin + optionswidget:= optionswidget - [ow_background]; + end; + if not (csloading in componentstate) then begin + if (splitdirbefore <> fsplitdir) then begin + calclayout(nil,false); + with container do begin + if fsplitdir = sd_none then begin + for int1:= 0 to widgetcount - 1 do begin + with widgets[int1] do begin + if getcorbainterface(typeinfo(idocktarget),intf1) then begin + cont1:= intf1.getdockcontroller; + cont1.fmdistate:= mds_normal; + anchors:= [an_left,an_top]; + widgetrect:= cont1.fnormalrect; + end; + end; + end; + end; + end; + invalidate; + end + else begin + if (bo1 xor (od_fixsize in foptionsdock)) and + getparentcontroller(cont1) then begin + cont1.updaterefsize; + end; + end; + end; + end; + end; +end; + +{ +procedure tdockcontroller.invalidategripsize; + + procedure descend1(const awidget: twidget1); + var + int1: integer; + begin + if awidget.fframe is tgripframe then begin + with tgripframe(awidget.fframe) do begin + exclude(fgripstate,grps_sizevalid); + end; + end; + for int1:= 0 to awidget.widgetcount-1 do begin + descend1(twidget1(awidget.widgets[int1])); + end; + end; + + procedure descend2(const awidget: twidget1); + var + int1: integer; + begin + if awidget.fframe is tgripframe then begin + with tgripframe(awidget.fframe) do begin + internalupdatestate; + end; + end; + for int1:= 0 to awidget.widgetcount-1 do begin + descend2(twidget1(awidget.widgets[int1])); + end; + end; +var + widget1: twidget; + +begin //invalidategripsize + widget1:= fintf.getwidget; + if not (csloading in widget1.componentstate) then begin + descend1(twidget1(widget1)); + descend2(twidget1(widget1)); + end; +end; +} +procedure tdockcontroller.setuseroptions(const avalue: optionsdockty); + + +var + optbefore: optionsdockty; + widget1: twidget1; +begin + optbefore:= foptionsdock; + optionsdock:= optionsdockty(replacebits(longword(avalue), + longword(foptionsdock),longword(useroptionsmask))); + if (foptionsdock >< optbefore) * [od_lock,od_nolock] <> [] then begin + widget1:= twidget1(fintf.getwidget); + if not widget1.isloading then begin + widget1.parentchanged; + end; + end; +end; + +procedure tdockcontroller.splitterchanged; +begin + if not (csloading in fintf.getwidget.ComponentState) then begin + updatesplitterrects(checksplit); + end; +end; + +procedure tdockcontroller.checkdirection; +begin + if fsplitdir = sd_horz then begin + fr:= @rectaccessy; + fw:= @widgetaccessy; + end + else begin + fr:= @rectaccessx; + fw:= @widgetaccessx; + end; +end; + +function tdockcontroller.getparentcontroller( + out acontroller: tdockcontroller): boolean; +var + widget1: twidget; + intf1: idocktarget; +begin + result:= false; + acontroller:= nil; + widget1:= fintf.getwidget.parentwidget; + if widget1 <> nil then begin + if widget1.getcorbainterface(typeinfo(idocktarget),intf1) then begin + acontroller:= intf1.getdockcontroller; + result:= true; + end; + end; +end; + +function tdockcontroller.getparentcontroller: tdockcontroller; +var + widget1: twidget; + intf1: idocktarget; +begin + result:= nil; + widget1:= fintf.getwidget.parentwidget; + if widget1 <> nil then begin + if widget1.getcorbainterface(typeinfo(idocktarget),intf1) then begin + result:= intf1.getdockcontroller; + end; + end; +end; + +procedure tdockcontroller.updaterefsize; +var + int1: integer; + ar1: widgetarty; + ar2,ar3: booleanarty; +begin + if fsplitdir in [sd_vert,sd_horz] then begin + ar1:= checksplit(frefsize,int1,ar2,ar3,false); + setlength(fsizes,length(ar1)); + for int1:= 0 to high(ar1) do begin + fsizes[int1]:= fw^.size(ar1[int1]); + end; + end + else begin + fsizes:= nil; + end; +end; + +function tdockcontroller.calclayout(const dragobject: tdockdragobject; + const nonewplace: boolean): boolean; +var + rect1{,rect2}: rectty; + po1: pointty; + ar1: widgetarty; + int1{,int2}: integer; + step,stepsum,pos: real; + container1: twidget1; + widget1,widget2: twidget; + index: integer; + xorrect: rectty; + intf1: idocktarget; + propsize,varsize,fixsize,fixcount: integer; + prop,fix: booleanarty; + dirchanged: boolean; + newwidget: boolean; + controller1: tdockcontroller; + bo1: boolean; +label + endlab; +begin + result:= false; + container1:= twidget1(fintf.getwidget.container); + if container1.componentstate * [csdestroying,csdesigning] <> [] then begin + exit; + end; + checkdirection; + if (ftabwidget <> nil) and (fsplitdir = sd_tabed) then begin + include(fdockstate,dos_updating5); + int1:= 0; + while int1 <= high(container1.fwidgets) do begin + widget1:= container1.fwidgets[int1]; + if widget1.visible and (widget1 <> ftabwidget) then begin + tdocktabpage.create(tdocktabwidget(ftabwidget),widget1); + end + else begin + inc(int1); + end; + end; + exclude(fdockstate,dos_updating5); + end; + ar1:= checksplit; + if fasplitdir <> sd_none then begin + dirchanged:= fsplitdir <> fasplitdir; + fsplitdir:= fasplitdir; + fasplitdir:= sd_none; + end + else begin + dirchanged:= false; + end; + if (ar1 = nil) and (dragobject = nil) then begin + if fsplitdir = sd_none then begin + fsplitterrects:= nil; + end; + goto endlab; + end; + rect1:= fplacementrect;//idockcontroller(fintf).getplacementrect; + po1:= addpoint(pointty(rect1.size),rect1.pos); //lower right + include(fdockstate,dos_updating1); + if dragobject <> nil then begin + with dragobject do begin + widget1:= widget; + index:= findex; + xorrect:= fxorrect; + end; + end + else begin + widget1:= nil; + index:= 0; + end; + if (ftabwidget <> nil) and (fsplitdir <> sd_tabed) then begin + with tdocktabwidget(ftabwidget) do begin + for int1:= count - 1 downto 0 do begin + with tdocktabpage(items[int1]) do begin + widget2:= ftarget; + ftarget:= nil; + include(fdockstate,dos_tabedending); + try + widget2.anchors:= ftargetanchors; + widget2.parentwidget:= container1; + finally + exclude(fdockstate,dos_tabedending); + end; + end; + end; + freeandnil(ftabwidget); + end; + end; + if (widget1 <> nil) then begin + newwidget:= true; + if (widget1.parentwidget = container1) then begin + for int1:= 0 to high(ar1) do begin + if ar1[int1] = widget1 then begin + deleteitem(pointerarty(ar1),int1); + newwidget:= false; + break; + end; + end; + end + else begin + widget2:= widget1.parentwidget; + if fsplitdir <> sd_tabed then begin + widget1.size:= xorrect.size; + widget1.parentwidget:= container1; + if widget1.parentwidget <> container1 then begin + exit; //probably widget can not be defocused + end; + end; + if getparentcontroller(controller1) then begin + controller1.layoutchanged; //notify removing + end; + if (widget2 <> nil) and widget2.getcorbainterface(typeinfo(idocktarget),intf1) then begin + intf1.getdockcontroller.layoutchanged; + end; + end; + end + else begin + newwidget:= false; + end; + if (length(ar1) > 0) or (widget1 <> nil) then begin + step:= 0; //compiler warning + stepsum:= 0; + if (fsplitdir <> sd_none) then begin + if (widget1 <> nil) then begin + if index > length(ar1) then begin + index:= length(ar1); + end; + insertitem(pointerarty(ar1),index,widget1); + if nofit then begin +// if not newwidget then begin + fr^.setosize(fsizingrect,fw^.osize(widget1)); + //don't change height +// end; + widget1.widgetrect:= fsizingrect; + end; + end; + if fsplitdir = sd_tabed then begin //use all children + checksplit(ar1,propsize,varsize,fixsize,fixcount,prop,fix,false); + end + else begin //use visible children only + ar1:= checksplit(ar1,propsize,varsize,fixsize,fixcount,prop,fix,false); + end; + if dirchanged or (propsize = 0) and newwidget then begin + for int1:= 0 to high(prop) do begin //split even + prop[int1]:= true; + fix[int1]:= false; + propsize:= fixsize + propsize; + fixsize:= 0; + varsize:= 0; + fixcount:= 0; + end; + end; + if fixcount < length(ar1) then begin + if fsplitdir = sd_horz then begin + step:= rect1.cy; + end + else begin + step:= rect1.cx; + end; + stepsum:= (step - fixsize + varsize - fsplitter_size * high(ar1)); + if stepsum < 0 then begin + stepsum:= 0; + end; + step:= stepsum /(length(ar1) - fixcount); + end; + end; + case fsplitdir of + sd_vert,sd_horz: begin + if not nonewplace and not nofit then begin + pos:= fr^.pos(rect1); + bo1:= round(stepsum) = propsize+varsize; //no change if size matches + for int1:= 0 to high(ar1) do begin + fr^.setpos(rect1,round(pos)); + if prop[int1] and not bo1 then begin + pos:= pos + step; + end + else begin + pos:= pos + fw^.size(ar1[int1]); + end; + if int1 = high(ar1) then begin + fr^.setsize(rect1,fr^.pt(po1) - fr^.pos(rect1)); + end + else begin + fr^.setsize(rect1,round(pos) - fr^.pos(rect1)); + end; + ar1[int1].widgetrect:= rect1; + pos:= pos + fsplitter_size; + end; + end; + end; + sd_tabed: begin + include(fdockstate,dos_updating5); + try + fsplitterrects:= nil; + if ftabwidget = nil then begin + ftabwidget:= tdocktabwidget.create(self,container1); + include(ttabwidget1(ftabwidget).foptionswidget1,ow1_noautosizing); + ftabwidget.anchors:= [an_left,an_right,an_top,an_bottom]; + end; + with tdocktabwidget(ftabwidget) do begin + widgetrect:= fplacementrect; + for int1:= 0 to high(ar1) do begin + if (ar1[int1] <> ftabwidget) and + ((ar1[int1].parentwidget = nil) or + (ar1[int1].parentwidget.parentwidget <> ftabwidget)) then begin + tdocktabpage.create(tdocktabwidget(ftabwidget),ar1[int1]); + end; + end; + end; + finally + exclude(fdockstate,dos_updating5); + end; + end; + else begin + if widget1 <> nil then begin + widget1.parentwidget:= container1; + widget1.widgetrect:= translatewidgetrect(xorrect,nil,container1); + end; + end; + end; + end; + exclude(fdockstate,dos_updating1); + sizechanged(true,false,ar1); + updatesplitterrects(ar1); +endlab: + widget1:= fintf.getwidget; + if widget1.canevent(tmethod(foncalclayout)) and + not application.terminated then begin + foncalclayout(widget1,ar1); + end; + dolayoutchanged; + result:= true; +end; + +procedure tdockcontroller.updateminscrollsize(var asize: sizety); +var + rect1: rectty; + ar1: widgetarty; + int1,int2: integer; + bandlength,bandsize: integer; + placementlength{,placementsize}: integer; + maxlength,maxsize: integer; + bo1: boolean; + firstband: boolean; +begin + if (od_banded in optionsdock) and nofit then begin + if (fsplitdir = sd_vert) then begin + ar1:= fintf.getwidget.getsortxchildren(true); + end + else begin + ar1:= fintf.getwidget.getsortychildren(true); + end; + rect1:= idockcontroller(fintf).getplacementrect(); + placementlength:= fr^.size(rect1); +// placementsize:= fr^.osize(rect1); + bandlength:= 0; + bandsize:= 0; + maxlength:= 0; + maxsize:= 0; + bo1:= true; + firstband:= true; + for int1:= 0 to high(ar1) do begin + int2:= fw^.size(ar1[int1])+fsplitter_size; + bandlength:= bandlength+int2; + if bandlength >{=} placementlength then begin //next band + if not bo1 then begin //shift to next band + bandlength:= bandlength - int2; + if bandlength > maxlength then begin + maxlength:= bandlength; + end; + bandlength:= int2; + bandsize:= bandsize+maxsize; + if not firstband then begin + bandsize:= bandsize + fbandgap; + end; + maxsize:= fw^.osize(ar1[int1]); + end + else begin //at least one widget + if bandlength > maxlength then begin + maxlength:= bandlength; + end; + bandsize:= bandsize + fw^.osize(ar1[int1]); + if not firstband and (int1 < high(ar1)) then begin + bandsize:= bandsize + fbandgap; + end; + bandlength:= 0; + maxsize:= 0; + bo1:= true; //first widget of band + end; + firstband:= false; + end + else begin + bo1:= false; //not first widget of band + if bandlength > maxlength then begin + maxlength:= bandlength; + end; + int2:= fw^.osize(ar1[int1]); + if int2 > maxsize then begin + maxsize:= int2; + end; + end; + end; + bandsize:= bandsize+maxsize; + if not firstband then begin + bandsize:= bandsize + fbandgap; + end; + fr^.setsize(rect1,maxlength); + fr^.setosize(rect1,bandsize); + if rect1.cx > asize.cx then begin + asize.cx:= rect1.cx; + end; + if rect1.cy > asize.cy then begin + asize.cy:= rect1.cy; + end; + end; +end; + +function tdockcontroller.nofit: boolean; +begin + result:= (od_nofit in foptionsdock) and (fsplitdir in [sd_vert,sd_horz]); +end; + +function tdockcontroller.dockdrag(const dragobj: tdockdragobject): boolean; +var + parentbefore: tdockcontroller; +begin + dragobj.fdock.getparentcontroller(parentbefore); + result:= false; + if calclayout(tdockdragobject(dragobj),false) then begin + updaterefsize; + result:= dragobj.fdock.dodock(parentbefore); + end; +end; + +procedure tdockcontroller.childstatechanged(const sender: twidget; + const newstate: widgetstatesty; const oldstate: widgetstatesty); +var + dock1: tdockcontroller; +begin + if getparentcontroller(dock1) then begin + dock1.childstatechanged(sender,newstate,oldstate); + end; +end; + +function tdockcontroller.beforedragevent(var info: draginfoty): boolean; + +var + widget1: twidget; + container1: twidget; + rect1: rectty; + size1: sizety; + count1: integer; + sd1: splitdirty; + int1,int2: integer; + mouseinhandle: boolean; + ischild1: boolean; + + function checkaccept: boolean; + var + intf1: idocktarget; + widget2: twidget; + begin + ischild1:= false; + result:= (info.dragobjectpo^ is tdockdragobject); + if result then begin + ischild1:= + (tdockdragobject(info.dragobjectpo^).fdock.getparentcontroller = self); + result:= ischild1 or + (od_acceptsdock in foptionsdock) and + (od_candock in tdockdragobject(info.dragobjectpo^).fdock.foptionsdock); + end; + if result and not mouseinhandle and (od_dockparent in foptionsdock) and + not widget1.checkdescendent( + tdockdragobject(info.dragobjectpo^).fdock.fintf.getwidget) then begin + widget2:= widget1.parentwidget; + while widget2 <> nil do begin + if widget2.getcorbainterface(typeinfo(idocktarget),intf1) and + (od_acceptsdock in intf1.getdockcontroller.foptionsdock) then begin + result:= false; + break; + end; + widget2:= widget2.parentwidget; + end; + end; + end; + + procedure adjustdockrect; + var + nofit: boolean; + rect2: rectty; + pt1: pointty; + x1,y1: integer; + f1: flo64; + begin + with info,tdockdragobject(dragobjectpo^) do begin + nofit:= (od_nofit in optionsdock) and (fsplitdir in [sd_vert,sd_horz]); + if (fcheckeddockcontroller <> self) then begin + if fcheckeddockcontroller <> nil then begin + fcheckeddockcontroller.fasplitdir:= sd_none; + end; + fcheckeddockcontroller:= self; + end; + if fasplitdir = sd_none then begin + fasplitdir:= fsplitdir; + end; + if not widget.checkdescendent(widget1) and + idockcontroller(fintf).checkdock(info) and + docheckdock(info) then begin + accept:= true; + rect1:= makerect(pos,widget.size); + addpoint1(rect1.pos,widget1.clientwidgetpos); + addpoint1(rect1.pos,widget1.screenpos); + subpoint1(rect1.pos,addpoint(pickpos,widget.clientwidgetpos)); + if not nofit then begin +// size1:= widget1.clientsize; +// pt1:= addpoint(info.pos,container1.clientpos); //paint origin + pt1:= subpoint(info.pos,fplacementrect.pos); //paint origin +// size1:= container1.paintsize; + size1:= fplacementrect.size; + with size1 do begin + x1:= cx div 8; + y1:= (cy * 7) div 8; + end; + if (od_splitvert in foptionsdock) and + (pt1.x < x1) and (pt1.y < y1) then begin + fasplitdir:= sd_vert; + end + else begin + if (od_splithorz in foptionsdock) and + (pt1.y > y1) and (pt1.x > x1) then begin + fasplitdir:= sd_horz; + end + else begin + if (od_tabed in foptionsdock) and + (pt1.x > (size1.cx * 7) div 16) and + (pt1.x < (size1.cx * 9) div 16) and + (pt1.y > (size1.cy * 7) div 16) and + (pt1.y < (size1.cy * 9) div 16) then begin + fasplitdir:= sd_tabed; + end; + end; + end; +// size1:= container1.paintsize; + size1:= fplacementrect.size; + if (widget.anchors * [an_left,an_right] = []) and + (fsplitdir = sd_none) then begin + rect1.x:= container1.screenpos.x + fplacementrect.x; + //container1.paintpos.x; + rect1.cx:= size1.cx; + end; + if (widget.anchors * [an_top,an_bottom] = []) and + (fsplitdir = sd_none) then begin + rect1.y:= container1.screenpos.y + fplacementrect.y; + //container1.paintpos.y; + rect1.cy:= size1.cy; + end; + sd1:= fsplitdir; + fsplitdir:= fasplitdir; + count1:= length(checksplit); + fsplitdir:= sd1; + if (widget.parentwidget <> container1) and + not widget1.checkdescendent(ftabwidget) then begin + inc(count1); + end; + findex:= count1-1; + case fasplitdir of + sd_vert: begin + rect1.y:= container1.screenpos.y + fplacementrect.y; + //container1.paintpos.y; + rect1.cy:= size1.cy; + if count1 = 0 then begin + exit; //should not happen + end; + f1:= size1.cx / count1; + rect1.cx:= size1.cx div count1; + if rect1.cx > 0 then begin + findex:= (pt1.x div rect1.cx); + rect1.x:= round(findex * f1) + + container1.screenpos.x + fplacementrect.x; + //container1.paintpos.x; + end; + if count1 = 1 then begin + dec(rect1.cx,rect1.cx div 16); + end; + end; + sd_horz: begin + rect1.x:= container1.screenpos.x + fplacementrect.x; + //container1.paintpos.x; + rect1.cx:= size1.cx; + if count1 = 0 then begin + exit; //should not happen + end; + f1:= size1.cy / count1; + rect1.cy:= size1.cy div count1; + if rect1.cy > 0 then begin + findex:= (pt1.y div rect1.cy); + rect1.y:= round(findex * f1) + + container1.screenpos.y + fplacementrect.y; + //container1.paintpos.y; + end; + if count1 = 1 then begin + int1:= rect1.cy div 16; + dec(rect1.cy,int1); + inc(rect1.y,int1); + end; + end; + sd_tabed: begin + int1:= size1.cy div 16; + int2:= size1.cx div 16; + if int2 < int1 then begin + int1:= int2; + end; + rect1:= inflaterect(fplacementrect + {idockcontroller(fintf).getplacementrect},-int1); + translatewidgetpoint1(rect1.pos,container1,nil); + end; + end; + if fasplitdir = sd_none then begin +// subpoint1(rect1.pos,widget.paintpos); + if widget1 <> container1 then begin +// addpoint1(rect1.pos,subpoint(widget1.paintpos,widget.paintpos)); +// subpoint1(rect1.pos,container1.pos); + end; + setxorwidget(container1,clipinrect(rect1, + makerect(translatewidgetpoint(container1.clientwidgetpos, + container1,nil),container1.maxclientsize))); + end + else begin + setxorwidget(container1,clipinrect(rect1, + makerect(translatewidgetpoint(fplacementrect.pos{container1.paintpos}, + container1,nil),size1))); + end; + end + else begin //nofit +// pt1:= translateclientpoint(rect1.pos,nil,container1); + pt1:= addpoint(info.pos,widget1.paintpos); + if findbandwidget(pt1,int1,rect2) then begin + findex:= int1; + fr^.setsize(rect2,fr^.size(rect1)); + fsizingrect:= rect2; + translatewidgetpoint1(rect2.pos,container1,nil); + setxorwidget(container1,rect2); + end; + end; + result:= true; + end; + end; + end; + + procedure dockwidget; + begin + with info,tdockdragobject(dragobjectpo^) do begin + if container1 = fxorwidget then begin + with tdockdragobject(dragobjectpo^).fdock do begin + if fmdistate = mds_floating then begin + fmdistate:= mds_normal; + end + else begin + if fmdistate = mds_maximized then begin + fnormalrect:= widget1.widgetrect; + mdistate:= mds_normal; + end; + end; + translatewidgetpoint1(fsizingrect.pos,nil,container1); + //used incalclayout + end; + fsizes:= nil; + dockdrag(tdockdragobject(dragobjectpo^)); + { + calclayout(tdockdragobject(dragobjectpo^),false); + updaterefsize; + tdockdragobject(dragobjectpo^).fdock.dodock; +// dochilddock(widget); +} + result:= true; + end; + end; + end; + +begin + widget1:= fintf.getwidget; + container1:= widget1.container; + result:= false; + ischild1:= false; + if not(csdesigning in widget1.ComponentState) then begin + with info do begin + if fdockhandle <> nil then begin + mouseinhandle:= (fdockhandle <> nil) and + pointinrect(translateclientpoint(info.pos, + idockcontroller(fintf).getwidget,fdockhandle),fdockhandle.gethandlerect); + end + else begin + mouseinhandle:= + pointinrect({widget1.clientpostowidgetpos(}info.pos{)}, + idockcontroller(fintf).getbuttonrects(dbr_handle)); + end; +// mouseinhandle:= (fdockhandle <> nil) and pointinrect( +// translateclientpoint(info.pos,idockcontroller(fintf).getwidget,fdockhandle), +// fdockhandle.gethandlerect) or +// pointinrect({widget1.clientpostowidgetpos(}info.pos{)}, +// idockcontroller(fintf).getbuttonrects(dbr_handle)); + case eventkind of + dek_begin: begin + if mouseinhandle then begin + if (widget1.parentwidget <> nil) then begin + if od_canmove in foptionsdock then begin + tdockdragobject.create(self,widget1,dragobjectpo^,fpickpos); + result:= true; + end + else begin + if canfloat and not (dos_hasfloatbutton in fdockstate) and + not(csdesigning in widget1.componentstate) then begin + dofloat(nullpoint); + result:= true; + end; + end; + end + else begin + if (od_candock in foptionsdock) and (widget1.parentwidget = nil) and + (dragobjectpo^ = nil) then begin + tdockdragobject.create(self,widget1,dragobjectpo^,fpickpos); + result:= true; + end; + end; + if result then begin + fclickedbutton:= dbr_none; + end; + end + end; + dek_check: begin + if checkaccept then begin + adjustdockrect; + end; + end; + dek_drop: begin + if checkaccept and (not ischild1 or + (tdockdragobject(info.dragobjectpo^).fdock.fmdistate <> + mds_maximized)) then begin + dockwidget; + end; + end; + end; + end; + end; + if not result then begin + result:= inherited beforedragevent(info); + end; +end; + +procedure tdockcontroller.setdockhandle(const avalue: tdockhandle); +begin + if fdockhandle <> nil then begin + fdockhandle.fcontroller:= nil; + end; + setlinkedvar(avalue,tmsecomponent(fdockhandle)); + if fdockhandle <> nil then begin + fdockhandle.fcontroller:= self; + end; +end; + +function tdockcontroller.dodock(const oldparent: tdockcontroller): boolean; +var + widget1: twidget1; + int1: integer; + controller1: tdockcontroller; +begin + widget1:= twidget1(fintf.getwidget); + inc(floatdockcount); + int1:= floatdockcount; + if widget1.canevent(tmethod(fondock)) then begin + fondock(widget1); + end; + if floatdockcount = int1 then begin + if getparentcontroller(controller1) then begin + if (fmdistate <> mds_minimized) or (oldparent <> controller1) then begin + fmdistate:= mds_normal; + end; + if oldparent <> controller1 then begin + controller1.dochilddock(widget1); + end; + end; + end; + result:= floatdockcount = int1; +end; + +function tdockcontroller.dofloat(const adist: pointty): boolean; +var + widget1: twidget1; + wstr1: msestring; + int1: integer; + controller1: tdockcontroller; + rect1: rectty; +begin + widget1:= twidget1(fintf.getwidget); + if widget1.parentwidget = nil then begin + result:= true; + end + else begin + result:= false; + getparentcontroller(controller1); + with widget1 do begin + if not (fmdistate in [mds_normal,mds_floating]) then begin + rect1.pos:= translatewidgetpoint(fnormalrect.pos,parentwidget,nil); + rect1.size:= fnormalrect.size; + end + else begin + rect1.pos:= screenpos; + rect1.size:= size; + end; + addpoint1(rect1.pos,adist); + if canevent(tmethod(fonbeforefloat)) then begin + fonbeforefloat(widget1,rect1); + end; + parentwidget:= nil; + if parentwidget <> nil then begin + exit; + end; + widgetrect:= rect1; + if fmdistate = mds_maximized then begin + anchors:= [an_left,an_top]; + end; + end; + fmdistate:= mds_floating; + // widget1.pos:= addpoint(widget1.pos,adist); + wstr1:= getfloatcaption; + if wstr1 <> '' then begin + widget1.window.caption:= wstr1; + end; + updategrip(sd_none,widget1); + inc(floatdockcount); + int1:= floatdockcount; + if widget1.canevent(tmethod(fonfloat)) then begin + fonfloat(widget1); + end; + if (floatdockcount = int1) and (controller1 <> nil) then begin + fhiddensizeref:= nullsize; + controller1.dochildfloat(widget1); + widget1.activate; + end; + result:= floatdockcount = int1; + if result then begin + dolayoutchanged(); + end; + end; +end; + +function tdockcontroller.float(): boolean; + //false if canceled +begin + result:= dofloat(nullpoint); +end; + +function tdockcontroller.dockto(const dest: tdockcontroller; + const apos: pointty): boolean; +var + dragobj: tdockdragobject; + widget1: twidget; +begin + dragobj:= nil; + widget1:= fintf.getwidget; + dragobj:= tdockdragobject.create(self,widget1,tdragobject(dragobj),nullpoint); + try + with dragobj.fxorrect do begin + size:= widget1.size; + widget1:= dest.fintf.getwidget.container; + pos:= translatewidgetpoint(apos,widget1,nil); + addpoint1(pos,widget1.clientwidgetpos); +// addpoint1(dragobj.fxorrect.pos,dest.fplacementrect.pos); + result:= dest.dockdrag(dragobj); + end; + finally + dragobj.free; + end; +end; + +function tdockcontroller.canfloat: boolean; +begin + result:= (od_canfloat in foptionsdock) and + not (ismdi and (mdistate = mds_minimized)) +end; + +function tdockcontroller.nogrip: boolean; +var + parent: tdockcontroller; +begin + result:= (od_lock in foptionsdock) or + not (od_nolock in foptionsdock) and getparentcontroller(parent) and + parent.nogrip; +end; + +procedure tdockcontroller.refused(const apos: pointty); +var + widget1: twidget; + intf1: idocktarget; + dir1: splitdirty; +begin + if canfloat and not (dos_hasfloatbutton in fdockstate) then begin + widget1:= fintf.getwidget.parentwidget; + dir1:= sd_none; //compiler warning + if widget1 <> nil then begin + if widget1.getcorbainterface(typeinfo(idocktarget),intf1) then begin + with intf1.getdockcontroller do begin + dir1:= fasplitdir; + fasplitdir:= fsplitdir; //no change of dir in calclayout + end; + end; + dofloat(subpoint(apos,translateclientpoint(fpickpos,fintf.getwidget,nil))); + if intf1 <> nil then begin + with intf1.getdockcontroller do begin + fasplitdir:= dir1; + end; + end; + end; + end; +end; + +procedure tdockcontroller.dochilddock(const awidget: twidget); +var + widget1: twidget1; +begin + widget1:= twidget1(fintf.getwidget); + if widget1.canevent(tmethod(fonchilddock)) then begin + fonchilddock(widget1,awidget); + end; +end; + +procedure tdockcontroller.dochildfloat(const awidget: twidget); +var + widget1: twidget1; +begin + widget1:= twidget1(fintf.getwidget); + if widget1.canevent(tmethod(fonchildfloat)) then begin + fonchildfloat(widget1,awidget); + end; +end; + +procedure tdockcontroller.domdistatechanged(const oldstate,newstate: mdistatety); +var + widget1: twidget1; +begin + widget1:= twidget1(fintf.getwidget); + if widget1.canevent(tmethod(fonmdistatechanged)) then begin + fonmdistatechanged(widget1,oldstate,newstate); + end; +end; + +function tdockcontroller.docheckdock(const info: draginfoty): boolean; +var + widget1: twidget1; +begin + widget1:= twidget1(fintf.getwidget); + if widget1.canevent(tmethod(foncheckdock)) then begin + result:= false; + foncheckdock(widget1,info.pos,tdockdragobject(info.dragobjectpo^),result); + end + else begin + result:= true; + end; +end; + +procedure tdockcontroller.enddrag; +begin + if fdragobject is tdockdragobject then begin + with tdockdragobject(fdragobject) do begin + if fxorwidget <> nil then begin + fxorwidget.invalidatewidget; + end; + end; + end; + inherited; +end; + +procedure tdockcontroller.beginplacement(); +begin + if fplacing = 0 then begin + include(fdockstate,dos_updating4); + end; + inc(fplacing); +end; + +procedure tdockcontroller.endplacement(); +var + int1,int2,int3: integer; + str1: string; + widget1: twidget; +begin + dec(fplacing); + if fplacing = 0 then begin + exclude(fdockstate,dos_updating4); + sizechanged(true); + calclayout(nil,true); + if (ftaborder <> nil) then begin + if (fsplitdir = sd_tabed) and (ftabwidget <> nil) then begin + int3:= 0; + for int1:= 0 to high(ftaborder) do begin + str1:= ansistring(ftaborder[int1]); + for int2:= int3 to tdocktabwidget(ftabwidget).count - 1 do begin + widget1:= tdocktabpage(tdocktabwidget(ftabwidget)[int2]).ftarget; + if (widget1 <> nil) and (widget1.Name = str1) then begin + tdocktabwidget(ftabwidget).movepage(int2,int3); + inc(int3); + break; + end; + end; + end; + if factivetab < tdocktabwidget(ftabwidget).count then begin + tdocktabwidget(ftabwidget).activepageindex:= factivetab; + end; + end; + ftaborder:= nil; + end; + end; +end; + + //istatfile +procedure tdockcontroller.statreading; +begin + beginplacement(); +// include(fdockstate,dos_updating4); +end; + +procedure tdockcontroller.statread; +begin + fsize:= idockcontroller(fintf).getplacementrect.size; + endplacement(); +// exclude(fdockstate,dos_updating4); +// calclayout(nil,true); +end; + +function tdockcontroller.getdockcaption: msestring; +begin + if fcaption = '' then begin + result:= idockcontroller(fintf).getcaption; + end + else begin + result:= fcaption + end; +end; + +function tdockcontroller.getfloatcaption: msestring; +begin + result:= idockcontroller(fintf).getcaption; + if result = '' then begin + result:= fcaption + end; +end; + +procedure tdockcontroller.readchildrencount(const acount: integer); +begin + setlength(fchildren,acount); +end; + +procedure tdockcontroller.readchild(const index: integer; + const avalue: msestring); +var + na: ansistring; + rect1,rect2: rectty; + w1: twidget; +begin + decoderecord(avalue,[@na,@rect1.x,@rect1.y,@rect1.cx,@rect1.cy],'siiii'); + with fintf.getwidget do begin + w1:= findchild(na); + fchildren[index]:= na; + if w1 <> nil then begin + rect2:= application.screenrect(window); + shiftinrect(rect1,rect2); + clipinrect(rect1,rect2); + w1.widgetrect:= rect1; + end; + end; +end; + +procedure tdockcontroller.dostatplace(const aparent: twidget; + const avisible: boolean; arect: rectty); +var + intf1: idocktarget; + widget0: twidget; +begin + widget0:= fintf.getwidget(); + with widget0 do begin + if not avisible then begin + visible:= false; + end; + if (aparent <> nil) and + aparent.getcorbainterface(typeinfo(idocktarget), + intf1) then begin + intf1.getdockcontroller.frefsize:= 0; //invalid + end; + parentwidget:= aparent; + if (parentwidget <> nil) then begin + if not parentwidget.getcorbainterface(typeinfo(idocktarget), + intf1) then begin + arect:= clipinrect(arect,parentwidget.paintrect); //shift into widget + end; + widgetrect:= arect; + end + else begin + updategrip(sd_none,widget0); + arect:= clipinrect(arect,application.screenrect); //shift into screen + widgetrect:= arect; + application.postevent(tobjectevent.create(ek_checkscreenrange, + ievent(widget0))); + end; + visible:= avisible; + end; +end; + +procedure tdockcontroller.updatetabpage(const sender: ttabpage); +begin + ftabpage:= sender; + sender.caption:= getdockcaption; + if fcolortab <> cl_default then begin + sender.colortab:= fcolortab; + end; + if fcoloractivetab <> cl_default then begin + sender.coloractivetab:= fcoloractivetab; + end; + sender.facetab:= ffacetab; + sender.faceactivetab:= ffaceactivetab; +end; + +procedure tdockcontroller.dostatread(const reader: tstatreader); +var + rect1: rectty; + widget0,widget1: twidget; + str1: string; + bo1: boolean; +begin + if not (od_banded in foptionsdock) then begin + fsplitdir:= splitdirty(reader.readinteger('splitdir',ord(fsplitdir), + 0,ord(high(splitdirty)))); + end; + useroptions:= optionsdockty(longword( + reader.readinteger('useroptions',integer(longword(fuseroptions))))); +// setoptionsdock(foptionsdock); //check valid values + ftaborder:= reader.readarray('order',msestringarty(nil)); + factivetab:= reader.readinteger('activetab',0); + widget0:= fintf.getwidget; + with widget0 do begin + if od_savepos in foptionsdock then begin + if parentwidget = nil then begin + str1:= ''; + end + else begin + str1:= ownernamepath(parentwidget); + end; + str1:= reader.readstring('parent',str1); + fmdistate:= mdistatety(reader.readinteger('mdistate',ord(fmdistate))); + with fnormalrect do begin + x:= reader.readinteger('nx',x); + y:= reader.readinteger('ny',y); + cx:= reader.readinteger('ncx',cx,0); + cy:= reader.readinteger('ncy',cy,0); + end; + rect1:= widgetrect; + with rect1 do begin + x:= reader.readinteger('x',x); + y:= reader.readinteger('y',y); + cx:= reader.readinteger('cx',cx,0); + cy:= reader.readinteger('cy',cy,0); + end; + with fhiddensizeref do begin + cx:= reader.readinteger('rcx',cx); + cy:= reader.readinteger('rcy',cy); + end; + bo1:= visible; + bo1:= reader.readboolean('visible',bo1); + application.findwidget(str1,widget1); + dostatplace(widget1,bo1,rect1); + end; + if od_savechildren in foptionsdock then begin + ffocusedchild:= reader.readinteger('focusedchild',-1); + reader.readrecordarray('children',{$ifdef FPC}@{$endif}readchildrencount, + {$ifdef FPC}@{$endif}readchild); + if fchildren <> nil then begin + application.postevent(tchildorderevent.create(self)); + fchildren:= nil; + end; + end; + if (parentwidget = nil) and (od_savezorder in foptionsdock) then begin + str1:= '~'; + str1:= reader.readstring('stackedunder',str1); + if str1 <> '~' then begin + if trim(str1) = '' then begin + window.stackunder(nil); + end + else begin + if application.findwidget(str1,widget1) and (widget1 <> nil) then begin + window.stackunder(widget1.window); + end; + end; + end; + window.caption:= getfloatcaption; + end; + end; +end; + +procedure tdockcontroller.dock(const source: tdockcontroller; + const arect: rectty); +var + child1,parent1: twidget; +begin + fhiddensizeref:= arect.size; + fnormalrect:= arect; + child1:= source.getwidget(); + parent1:= getwidget().container; + source.dostatplace(parent1,child1.visible,arect); +end; + +function tdockcontroller.writechild(const index: integer): msestring; +begin + with twidget1(fintf.getwidget).container.widgets[index] do begin + result:= encoderecord([name,bounds_x,bounds_y,bounds_cx,bounds_cy]); + if entered then begin + ffocusedchild:= index; + end; + end; +end; + +procedure tdockcontroller.dostatwrite(const writer: tstatwriter; + const bounds: prectty = nil); +var + str1: string; + window1: twindow; + tabed: boolean; + ar1: msestringarty; + int1: integer; + po1: prectty; +begin + str1:= ''; + writer.writeinteger('splitdir',ord(fsplitdir)); + writer.writeinteger('useroptions', + {$ifdef FPC}longword{$else}longword{$endif}(fuseroptions)); + if ftabwidget <> nil then begin + with tdocktabwidget(ftabwidget) do begin + setlength(ar1,count); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= msestring(tdocktabpage(items[int1]).ftarget.Name); + end; + writer.writearray('order',ar1); + writer.writeinteger('activetab',activepageindex); + end; + end; + with twidget1(fintf.getwidget) do begin + if od_savezorder in foptionsdock then begin + if parentwidget = nil then begin + str1:= ''; + window1:= window.stackedunder; + if window1 <> nil then begin + writer.writestring('stackedunder',ownernamepath(window1.owner)); + end + else begin + writer.writestring('stackedunder',''); + end; + end; + end; + if od_savepos in foptionsdock then begin + tabed:= (parentwidget is tdocktabpage) and (parentwidget.parentwidget <> nil); + if parentwidget <> nil then begin + if tabed then begin + str1:= ownernamepath(parentwidget.parentwidget.parentwidget); + end + else begin + str1:= ownernamepath(parentwidget); + end; + end; + writer.writestring('parent',str1); + po1:= bounds; + if po1 = nil then begin + po1:= @fwidgetrect; + writer.writeboolean('visible',visible); + end; + writer.writeinteger('mdistate',ord(fmdistate)); + writer.writeinteger('nx',fnormalrect.x); + writer.writeinteger('ny',fnormalrect.y); + writer.writeinteger('ncx',fnormalrect.cx); + writer.writeinteger('ncy',fnormalrect.cy); + writer.writeinteger('x',po1^.x); + writer.writeinteger('y',po1^.y); + writer.writeinteger('cx',po1^.cx); + writer.writeinteger('cy',po1^.cy); + with fhiddensizeref do begin + writer.writeinteger('rcx',cx); + writer.writeinteger('rcy',cy); + end; + end; + if od_savechildren in foptionsdock then begin + writer.writerecordarray('children',container.widgetcount, + {$ifdef FPC}@{$endif}writechild); + writer.writeinteger('focusedchild',ffocusedchild); + end; + end; +end; + +procedure tdockcontroller.setsplitter_size(const Value: integer); +begin + if value <> fsplitter_size then begin + fsplitter_size := Value; + layoutchanged; + end; +end; + +procedure tdockcontroller.setsplitter_setgrip(const Value: stockbitmapty); +begin + if fsplitter_grip <> value then begin + fsplitter_grip:= Value; + splitterchanged; + end; +end; + +procedure tdockcontroller.setsplitter_color(const Value: colorty); +begin + if fsplitter_color <> value then begin + fsplitter_color := Value; + splitterchanged; + end; +end; + +procedure tdockcontroller.setsplitter_colorgrip(const Value: colorty); +begin + if fsplitter_colorgrip <> value then begin + fsplitter_colorgrip := Value; + splitterchanged; + end; +end; + +procedure tdockcontroller.setbandgap(const avalue: integer); +begin + if fbandgap <> avalue then begin + fbandgap:= avalue; + layoutchanged; + end; +end; + +procedure tdockcontroller.layoutchanged; +begin + if not (csloading in fintf.getwidget.ComponentState) then begin + calclayout(nil,false); + end; +end; + +procedure tdockcontroller.setpickshape(const ashape: cursorshapety); +begin + with fintf.getwidget do begin + if not (ds_cursorshapechanged in fstate) then begin + fcursorbefore:= cursor; + include(fstate,ds_cursorshapechanged); + end; + cursor:= ashape; + end; +end; + +procedure tdockcontroller.restorepickshape; +begin + if ds_cursorshapechanged in fstate then begin + fintf.getwidget.cursor:= fcursorbefore; + exclude(fstate,ds_cursorshapechanged); + end; +end; + +function tdockcontroller.checkbuttonarea(const apos: pointty): dockbuttonrectty; +var + dbr1: dockbuttonrectty; +begin + result:= dbr_none; + for dbr1:= dbr_firstbutton to dbr_lastbutton do begin + if pointinrect(apos,idockcontroller(fintf).getbuttonrects(dbr1)) then begin + result:= dbr1; + break; + end; + end; + if (result = dbr_none) then begin + if fdockhandle <> nil then begin + if pointinrect(apos,fdockhandle.paintparentrect) then begin + result:= dbr_handle; + end; + end + else begin + if pointinrect(apos, + idockcontroller(fintf).getbuttonrects(dbr_handle)) then begin + result:= dbr_handle; //handle rect can include buttons + end; + end; + end; +end; + +function tdockcontroller.findbandpos(const apos: integer; out aindex: integer; + out arect: rectty): boolean; +var + int1,int2: integer; +begin + result:= false; + int2:= fbandstart; + for int1:= 0 to high(fbands) do begin + with fbands[int1] do begin + if (apos >= int2) and (apos < int2 + size) then begin + result:= true; + aindex:= int1; + fr^.setopos(arect,int2); + fr^.setosize(arect,size); + fr^.setpos(arect,fr^.pos(fplacementrect)); + fr^.setsize(arect,fr^.size(fplacementrect)); + break; + end; + int2:= int2 + size + fbandgap; + end; + end; +end; + +function tdockcontroller.findbandwidget(const apos: pointty; out aindex: integer; + out arect: rectty): boolean; + //false if not found. widget index and widget rect +var + ar1: widgetarty; + int1,int2,int3,int4,int5: integer; +begin + result:= findbandpos(fr^.opt(apos),int4,arect); + if result then begin + ar1:= checksplit; + aindex:= -1; + if ar1 <> nil then begin + int3:= fr^.pos(arect); + int5:= fr^.pt(apos); + with fbands[int4] do begin + aindex:= last; + for int1:= first to last - 1 do begin + int2:= fw^.size(ar1[int1]) + fsplitter_size; + if int3 + int2 >= int5 then begin + aindex:= int1; + break; + end; + int3:= int3 + int2; + end; + end; + fr^.setpos(arect,int3); + fr^.setsize(arect,fw^.size(ar1[aindex])); + end; + end; +end; + +function tdockcontroller.findbandindex(const widgetindex: integer; out aindex: integer; + out arect: rectty): boolean; +var + int1,int2: integer; +begin + result:= false; + int2:= fbandstart; + for int1:= 0 to high(fbands) do begin + with fbands[int1] do begin + if last >= widgetindex then begin + result:= true; + aindex:= int1; + fr^.setopos(arect,int2); + fr^.setosize(arect,size); + fr^.setpos(arect,fr^.pos(fplacementrect)); + fr^.setsize(arect,fr^.size(fplacementrect)); + break; + end; + int2:= int2 + size + fbandgap; + end; + end; +end; + +function tdockcontroller.doclose(const awidget: twidget): boolean; +begin + result:= simulatemodalresult(awidget,mr_windowclosed); +end; + +function tdockcontroller.canbegindrag: boolean; +begin + result:= (fdockstate * [dos_moving,dos_sizing,dos_xorpic] = []) and + not ((fmdistate = mds_maximized) and not (od_canfloat in foptionsdock)); +end; + +procedure tdockcontroller.drawxorpic(const ashow: boolean; + var canvas1: tcanvas); +var + rect1: rectty; +begin + if canvas1 = nil then begin + canvas1:= fintf.getwidget().container.getcanvas(org_widget); + end; + if dos_moving in fdockstate then begin + canvas1.drawxorframe(fsizingrect,-2,stockobjects.bitmaps[stb_dens50]); + end + else begin + if not (od_thumbtrack in foptionsdock) then begin + if fsplitdir = sd_vert then begin + rect1:= moverect(fsizingrect,makepoint(fsizeoffset,0)); + end + else begin + rect1:= moverect(fsizingrect,makepoint(0,fsizeoffset)); + end; + canvas1.fillxorrect(rect1,stockobjects.bitmaps[stb_dens50]); + end; + end; + if ashow then begin + include(fdockstate,dos_xorpic); + end + else begin + exclude(fdockstate,dos_xorpic); + end; +end; + +procedure tdockcontroller.endmouseop1(); +var + c1: tcanvas; +begin + restorepickshape(); + if dos_xorpic in fdockstate then begin + c1:= nil; + drawxorpic(false,c1); //remove pic + end; + if fsizeindex >= 0 then begin + application.unregisteronkeypress(@dokeypress); + end; +end; + +const + resetmousedockstate = + [{dos_closebuttonclicked,dos_maximizebuttonclicked, + dos_normalizebuttonclicked,dos_minimizebuttonclicked, + dos_fixsizebuttonclicked,dos_floatbuttonclicked,dos_topbuttonclicked, + dos_backgroundbuttonclicked, + dos_lockbuttonclicked,dos_nolockbuttonclicked,}dos_moving]; + +procedure tdockcontroller.endmouseop2(); +begin + fdockstate:= fdockstate - resetmousedockstate; + fclickedbutton:= dbr_none; +end; + +procedure tdockcontroller.cancelsizing(); +var + i1: int32; +begin + endmouseop1(); + endmouseop2(); + fsizeindex:= -1; + if (od_thumbtrack in foptionsdock) and + (high(fwidgetrectsbefore) = high(fwidgetsbefore)) then begin + include(fdockstate,dos_updating1); + try + for i1:= 0 to high(fwidgetrectsbefore) do begin + fwidgetsbefore[i1].widgetrect:= fwidgetrectsbefore[i1]; + end; + finally + fwidgetrectsbefore:= nil; + exclude(fdockstate,dos_updating1); + calclayout(nil,true); + updaterefsize(); + end; + end; + fwidgetrectsbefore:= nil; +end; + +procedure tdockcontroller.clientmouseevent(var info: mouseeventinfoty); + +var + po1: pointty; + widget1: twidget1; + propsize,fixsize: integer; + ar1: widgetarty; + prop,fix: booleanarty; + fixend: boolean; + + function checksizing(const move: boolean): integer; + + function updatesizingrect: integer; + var + int1,int2: integer; + w1: twidget; + p1: integer; + bandnumber: integer; + bandrect: rectty; + lastitem: integer; + begin + result:= -1; + if not findbandpos(fr^.opt(po1),bandnumber,bandrect) then begin + exit; + end; + p1:= fr^.pt(po1); //widget direction + lastitem:= fbands[bandnumber].last; + if not fixend then begin + dec(lastitem); + end; + for int1:= fbands[bandnumber].first to lastitem do begin + w1:= twidget1(ar1[int1]); + int2:= fw^.stop(w1); + if (fsplitter_size = 0) and (p1 >= int2 - sizingtol) and + (p1 < int2 + sizingtol) or + (fsplitter_size <> 0) and (p1 >= int2) and + (p1 < int2 + fsplitter_size) then begin + fr^.setopos(fsizingrect,fr^.opos(bandrect)); + fr^.setosize(fsizingrect,fr^.osize(bandrect)); + if move then begin + fr^.setsize(fsizingrect,fw^.size(w1)); + fr^.setpos(fsizingrect,int2-fr^.size(fsizingrect)); + end + else begin + if fsplitter_size = 0 then begin + fr^.setpos(fsizingrect,int2-sizingtol); + fr^.setsize(fsizingrect,2*sizingtol); + end + else begin + fr^.setpos(fsizingrect,int2); + fr^.setsize(fsizingrect,fsplitter_size); + end; + end; + result:= int1; + break; + end; + end; + end; + + begin + ar1:= nil; //compilerwarning + result:= -1; + if move and (optionsdock * [od_nofit,od_nosplitmove] <> [od_nofit]) then begin + exit; + end; + if not move and (optionsdock * [od_nosplitsize] <> []) then begin + exit; + end; + ar1:= checksplit; + if fsplitdir in [sd_vert,sd_horz] then begin + result:= updatesizingrect; + if result >= 0 then begin + if fsplitdir = sd_vert then begin + setpickshape(cr_sizehor); + end + else begin + setpickshape(cr_sizever); + end; + end; + end; + if result < 0 then begin + restorepickshape; + end; + end; + + procedure checksizeoffset; + var + start,stop: integer; + int1,int2,int4: integer; + movestart: integer; + rect1: rectty; + bandindex: integer; + begin + stop:= 0; + start:= 0; + ar1:= checksplit(propsize,fixsize,prop,fix,false); + if fsizeindex <= high(ar1) then begin + movestart:= fr^.pos(fplacementrect); + start:= movestart - fw^.stop(ar1[fsizeindex]); + stop:= start + fr^.size(fplacementrect); + if not fixend then begin + for int1:= 0 to fsizeindex - 1 do begin + if fix[int1] then begin + start:= start + fw^.size(ar1[int1]); + end + else begin + start:= start + fw^.min(ar1[int1]); + end; + end; + for int1:= fsizeindex + 1 to high(ar1) do begin + if fix[int1] and (int1 <> fsizeindex + 1) then begin + stop:= stop - fw^.size(ar1[int1]); + end + else begin + stop:= stop - fw^.min(ar1[int1]); + end; + end; + start:= start + fsizeindex * fsplitter_size; + stop:= stop - (high(ar1)-fsizeindex) * fsplitter_size; + end + else begin + if dos_moving in fdockstate then begin + movestart:= movestart + fsplitter_size; + fmoveindex:= fsizeindex; + int4:= fsizeoffset + fw^.pos(ar1[fsizeindex]); //mouse position + if findbandpos(fr^.opt(po1),bandindex,rect1) then begin + with fbands[bandindex] do begin + fmoveindex:= last; + for int1:= first to last do begin + int2:= fw^.pos(ar1[int1]); + movestart:= movestart + int2 + fsplitter_size; + if movestart > int4 then begin + fmoveindex:= int1; + break; + end; + end; + end; + end + else begin + findbandindex(fsizeindex,int1,rect1); + end; + fr^.setopos(fsizingrect,fr^.opos(rect1)); + fr^.setosize(fsizingrect,fr^.osize(rect1)); + fr^.setpos(fsizingrect,fw^.pos(ar1[fmoveindex])); + end + else begin + start:= start + fw^.pos(ar1[fsizeindex]) - fr^.pos(fplacementrect) + + fw^.min(ar1[fsizeindex]); + stop:= stop - fsplitter_size; + end; + end; + end; + if fsizeoffset < start then begin + fsizeoffset:= start; + end; + if fsizeoffset > stop then begin + fsizeoffset:= stop; + end; + end; + + procedure calcdelta; + var + int1,int2,int3: integer; + wi1: twidget; + rect1,rect2: rectty; + begin + ar1:= checksplit(propsize,fixsize,prop,fix,false); + if high(ar1) > 0 then begin + int2:= fsizeoffset; + include(fdockstate,dos_updating4); + try + if not fixend then begin + for int1:= fsizeindex downto 0 do begin + if not fix[int1] or (int1 = fsizeindex) then begin + int3:= fw^.size(ar1[int1]); + fw^.setsize(ar1[int1],int3+int2); + int2:= int2 + int3 - fw^.size(ar1[int1]); + if int2 = 0 then begin + break; + end; + end; + end; + fw^.setsize(ar1[0],fw^.size(ar1[0]) + int2); //ev. rest + int2:= - fsizeoffset; + for int1:= fsizeindex + 1 to high(ar1) do begin + if not fix[int1] or (int1 = fsizeindex + 1) then begin + int3:= fw^.size(ar1[int1]); + fw^.setsize(ar1[int1],int3+int2); + int2:= int2 + int3 - fw^.size(ar1[int1]); + if int2 = 0 then begin + break; + end; + end; + end; + end; + if dos_moving in fdockstate then begin + findbandindex(fsizeindex,int1,rect1); + findbandindex(fmoveindex,int2,rect2); + int1:= fr^.opos(rect2)-fr^.opos(rect1); + wi1:= ar1[fsizeindex]; + fw^.setopos(wi1,fw^.opos(wi1)+int1); //shift in new band; + deleteitem(pointerarty(ar1),fsizeindex); + insertitem(pointerarty(ar1),fmoveindex,wi1); + int2:= 0; + for int1:= 0 to high(ar1) do begin + fw^.setpos(ar1[int1],int2); + int2:= int2 + fw^.size(ar1[int1]); + end; + end + else begin + fw^.setsize(ar1[fsizeindex],fw^.size(ar1[fsizeindex]) + int2); //ev. rest + end; + finally + exclude(fdockstate,dos_updating4); + end; + end; + updaterefsize; + end; + +var + canvas1: tcanvas; + + procedure dosize; + begin + checksizeoffset; + if high(ar1) > 0 then begin + calcdelta; + sizechanged(true); + end; + end; //dosize + + procedure setmousebutton(const abutton: dockbuttonrectty); + begin + if (widget1.fframe <> nil) and (widget1.fframe is tgripframe) then begin + with tgripframe(widget1.fframe) do begin + if abutton <> fmousebutton then begin + if fmousebutton <> dbr_none then begin + widget1.invalidaterect(frects[fmousebutton],org_widget); + end; + fmousebutton:= abutton; + if (fmousebutton >= dbr_first) and (fmousebutton <= dbr_last) then begin + widget1.invalidaterect(frects[fmousebutton],org_widget); + end; + end; + if (abutton <> fclickedbutton) and + (abutton >= dbr_first) and (abutton <= dbr_last) then begin + widget1.invalidaterect(frects[abutton],org_widget); + end; + end; + end; + if (abutton <> fclickedbutton) then begin + fclickedbutton:= dbr_none; + end; + end; //setmousebutton + +var + bu1: dockbuttonrectty; + i1: int32; + +begin + inherited; + with info do begin + if (eventstate * [es_processed] = []) then begin + canvas1:= nil; + fixend:= foptionsdock * [od_nofit] <> []; + widget1:= twidget1(fintf.getwidget); + po1:= translatewidgetpoint(addpoint(info.pos,widget1.clientwidgetpos), + widget1,widget1.container); //widget origin + case info.eventkind of + ek_mouseleave,ek_clientmouseleave: begin + setmousebutton(dbr_none); + if not (ds_clicked in fstate) or + (info.eventkind = ek_mouseleave) then begin + restorepickshape; + fsizeindex:= -1; + if dos_xorpic in fdockstate then begin + drawxorpic(false,canvas1); //remove pic + end; + exclude(fstate,ds_clicked); + fdockstate:= fdockstate - resetmousedockstate; + fclickedbutton:= dbr_none; + end; + end; + ek_mousemove: begin + if fsizeindex < 0 then begin + if not (csdesigning in widget1.componentstate) then begin + setmousebutton(checkbuttonarea(pos)); + end; + checksizing((dos_moving in fdockstate) or + (od_nosplitsize in foptionsdock)); + end + else begin + setmousebutton(dbr_none); + if od_thumbtrack in optionsdock then begin + if fsplitdir = sd_vert then begin + fsizeoffset:= pos.x - fpickpos.x; + end; + if fsplitdir = sd_horz then begin + fsizeoffset:= pos.y - fpickpos.y; + end; + dosize(); + if fsplitdir = sd_vert then begin + fpickpos.x:= fpickpos.x+fsizeoffset; + end; + if fsplitdir = sd_horz then begin + fpickpos.y:= fpickpos.y+fsizeoffset; + end; + end + else begin + if fsplitdir = sd_vert then begin + drawxorpic(false,canvas1); //remove pic + fsizeoffset:= pos.x - fpickpos.x; + checksizeoffset; + drawxorpic(true,canvas1); //draw pic + end; + if fsplitdir = sd_horz then begin + drawxorpic(false,canvas1); //remove pic + fsizeoffset:= pos.y - fpickpos.y; + checksizeoffset; + drawxorpic(true,canvas1); //draw pic + end; + end; + end; + end; + ek_buttonpress: begin + fsizeoffset:= 0; + if shiftstate - [ss_left,ss_shift] = [] then begin + fsizeindex:= checksizing((ss_shift in shiftstate) or + (od_nosplitsize in foptionsdock)); + if fsizeindex >= 0 then begin + if (ss_shift in shiftstate) or + (od_nosplitsize in foptionsdock) then begin + include(fdockstate,dos_moving); + end + else begin + application.registeronkeypress(@dokeypress); + exclude(fdockstate,dos_moving); + if od_thumbtrack in foptionsdock then begin + setlength(fwidgetrectsbefore,length(fwidgetsbefore)); + for i1:= 0 to high(fwidgetsbefore) do begin + fwidgetrectsbefore[i1]:= fwidgetsbefore[i1].widgetrect; + end; + end; + end; + drawxorpic(true,canvas1); + end; + if not (ss_shift in shiftstate) then begin + bu1:= checkbuttonarea(pos); + setmousebutton(bu1); + fclickedbutton:= bu1; + end; + end; + end; + ek_buttonrelease: begin + endmouseop1(); + if fsizeindex >= 0 then begin + fwidgetrectsbefore:= nil; + if od_thumbtrack in foptionsdock then begin + fsizeoffset:= 0; + end; + dosize(); + fsizeindex:= -1; + fintf.getwidget.invalidate(); + checksizing((dos_moving in fdockstate) or + (od_nosplitsize in foptionsdock)); + end + else begin + case checkbuttonarea(pos) of + dbr_close: begin + if fclickedbutton = dbr_close then begin + doclose(widget1); + end; + end; + dbr_maximize: mdistate:= mds_maximized; + dbr_normalize: mdistate:= mds_normal; + dbr_minimize: mdistate:= mds_minimized; + dbr_fixsize: begin + if fclickedbutton = dbr_fixsize then begin + useroptions:= optionsdockty( + togglebit({$ifdef FPC}longword{$else}longword{$endif}(fuseroptions), + ord(od_fixsize))); + widget1.invalidatewidget; + end; + end; + dbr_float: begin + if fclickedbutton = dbr_float then begin + if not (csdesigning in widget1.componentstate) then begin + dofloat(nullpoint); + end; + end; + end; + dbr_top: begin + if fclickedbutton = dbr_top then begin + useroptions:= optionsdockty( + togglebit({$ifdef FPC}longword{$else}longword{$endif}(fuseroptions), + ord(od_top))); + widget1.invalidatewidget; + end; + end; + dbr_background: begin + if fclickedbutton = dbr_background then begin + useroptions:= optionsdockty( + togglebit({$ifdef FPC}longword{$else}longword{$endif}(fuseroptions), + ord(od_background))); + widget1.invalidatewidget; + end; + end; + dbr_lock: begin + if fclickedbutton = dbr_lock then begin + useroptions:= optionsdockty( + togglebit({$ifdef FPC}longword{$else}longword{$endif}(fuseroptions), + ord(od_lock))); + widget1.invalidatewidget; + end; + end; + dbr_nolock: begin + if fclickedbutton = dbr_nolock then begin + useroptions:= optionsdockty( + togglebit({$ifdef FPC}longword{$else}longword{$endif}(fuseroptions), + ord(od_nolock))); + widget1.invalidatewidget; + end; + end; + end; + end; + endmouseop2(); + end; + end; + end; + end; +end; + +procedure tdockcontroller.checkmouseactivate(const sender: twidget; + var info: mouseeventinfoty); +var + widget1: twidget; + pt1: pointty; +begin + if (info.eventkind = ek_buttonpress) then begin + if ismdi then begin + widget1:= fintf.getwidget; + widget1.bringtofront; + if ((sender = widget1) or (sender = widget1.container)) and + widget1.canfocus and + not widget1.checkdescendent(widget1.window.focusedwidget)then begin + pt1:= sender.pos; + widget1.setfocus; + application.delayedmouseshift(subpoint(sender.pos,pt1)); + //follow shift in view ??? + end; + end; + end; +end; + +procedure tdockcontroller.mouseevent(var info: mouseeventinfoty); +begin + if ismdi then begin + with twidget1(fintf.getwidget) do begin + if (fframe is tgripframe) and + not (csdesigning in componentstate) then begin + tgripframe(fframe).mouseevent(info); + end; + end; + end; + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +procedure tdockcontroller.childormouseevent(const sender: twidget; + var info: mouseeventinfoty); +begin + checkmouseactivate(sender,info); + inherited; +end; + +procedure tdockcontroller.widgetregionchanged(const sender: twidget); +begin + if (sender <> nil) and + (fdockstate * [dos_updating1,dos_updating2,dos_updating3,dos_updating4, + dos_updating5] = []) then begin + with fintf.getwidget do begin + if (componentstate * [csloading,csdesigning] = []) and + not (ws_destroying in widgetstate) and + not (ow1_noautosizing in sender.optionswidget1) and + not(dos_tabedending in fdockstate)then begin + include(fdockstate,dos_updating3); + try + calclayout(nil,not(ws1_parentupdating in sender.widgetstate1)); + updaterefsize; + finally + exclude(fdockstate,dos_updating3); + end; + end; + end; + end; +end; + +procedure tdockcontroller.setcaption(const Value: msestring); +var + widget1: twidget; + mstr1: msestring; +begin + mstr1:= fcaption; + fcaption:= Value; + widget1:= fintf.getwidget; + if not (csdestroying in widget1.componentstate) then begin + if widget1.ownswindow then begin + widget1.window.caption:= fcaption; + end + else begin + if istabed and (widget1.parentwidget is tdocktabpage) then begin + tdocktabpage(widget1.parentwidget).caption:= value; + end; + end; + end; + if mstr1 <> fcaption then begin + docaptionchanged; + end; +end; + +procedure tdockcontroller.beginclientrectchanged; +begin + include(fdockstate,dos_updating1); +end; + +procedure tdockcontroller.endclientrectchanged; +begin + exclude(fdockstate,dos_updating1); + if (fdockstate * [dos_updating2,dos_updating4] = []) then begin + sizechanged; + end + else begin + exclude(fdockstate,dos_layoutvalid); + end; +end; + +function tdockcontroller.isfullarea: boolean; +var + acontroller: tdockcontroller; +begin + result:= getparentcontroller(acontroller) and + (acontroller.fsplitdir <> sd_none); +end; + +function tdockcontroller.istabed: boolean; +var + acontroller: tdockcontroller; +begin + result:= getparentcontroller(acontroller) and + (acontroller.fsplitdir = sd_tabed); +end; + +function tdockcontroller.ismdi: boolean; +var + acontroller: tdockcontroller; +begin + result:= (fintf.getwidget.parentwidget <> nil) and + (fmdistate <> mds_floating) and getparentcontroller(acontroller) and + (acontroller.fsplitdir = sd_none) and + not (dos_tabedending in acontroller.fdockstate); +end; + +function tdockcontroller.isfloating: boolean; +begin + with fintf.getwidget do begin + result:= (parentwidget = nil) or (csdesigning in componentstate) and + (parentwidget = owner); + end; +end; + +function tdockcontroller.canmdisize: boolean; +begin + result:= ismdi and (od_cansize in foptionsdock); +end; + +function tdockcontroller.getitems: widgetarty; //reference count = 1 +var + int1: integer; +begin + if ftabwidget <> nil then begin + with tdocktabwidget(ftabwidget) do begin + setlength(result,count); + for int1:= 0 to high(result) do begin + result[int1]:= tdocktabpage(items[int1]).ftarget; + end; + end; + end + else begin + if fsplitdir = sd_horz then begin + result:= fintf.getwidget.getsortxchildren(); + end + else begin + if fsplitdir = sd_tabed then begin + result:= nil; + end + else begin + result:= fintf.getwidget.getsortychildren(); + end; + end; + end; +end; + +procedure tdockcontroller.setmdistate(const avalue: mdistatety); +var + statebefore: mdistatety; + rect1: rectty; + pos1: captionposty; +begin + if fmdistate <> avalue then begin + if ismdi then begin + statebefore:= fmdistate; + with twidget1(fintf.getwidget) do begin + if fmdistate = mds_normal then begin + fnormalrect:= widgetrect; + end; + case avalue of + mds_normal: begin + fmdistate:= mds_normal; + anchors:= [an_left,an_top]; + widgetrect:= fnormalrect; + end; + mds_minimized: begin + if canclose(nil) then begin + fmdistate:= mds_minimized; + nextfocus; + with rect1 do begin + pos:= fnormalrect.pos; + size:= idockcontroller(fintf).getminimizedsize(pos1); + if cx = 0 then begin + cx:= fnormalrect.cx; + end; + if cy = 0 then begin + cy:= fnormalrect.cy; + end; + case pos1 of + cp_right: inc(x,fnormalrect.cx - cx); + cp_bottom: inc(y,fnormalrect.cy - cy); + end; + end; + anchors:= [an_left,an_top]; + widgetrect:= rect1; + end + else begin + exit; + end; + end; + mds_maximized: begin + fmdistate:= mds_maximized; + anchors:= []; + end; + end; + if (fframe <> nil) then begin + tcustomframe1(fframe).updatestate; + end; + domdistatechanged(statebefore,fmdistate); + end; + end + else begin + fmdistate:= avalue; + end; + end; +end; + +function tdockcontroller.placementrect: rectty; +var + contr1: tdockcontroller; +begin + if getparentcontroller(contr1) then begin + result:= idockcontroller(contr1.fintf).getplacementrect; + end + else begin + result:= nullrect; + end; +end; + +procedure tdockcontroller.parentchanged(const sender: twidget); +begin + exclude(twidget1(sender).fwidgetstate1,ws1_nominsize); + if not (csloading in sender.componentstate) and + (twidget1(sender).fframe is tgripframe) then begin + with tgripframe(twidget1(sender).fframe) do begin + exclude(fgripstate,grps_sizevalid); + internalupdatestate; + end; + end; +end; + +procedure tdockcontroller.poschanged; +var + pos1: captionposty; + widget1: twidget; +begin + if ismdi then begin + widget1:= fintf.getwidget; + case fmdistate of + mds_normal: begin + fnormalrect:= widget1.widgetrect; + end; + mds_minimized: begin + idockcontroller(fintf).getminimizedsize(pos1); + with widget1 do begin + case pos1 of + cp_left,cp_top: begin + fnormalrect.pos:= pos; + end; + cp_right: begin + fnormalrect.y:= bounds_y; + fnormalrect.x:= bounds_x + bounds_cx - fnormalrect.cx; + end; + cp_bottom: begin + fnormalrect.x:= bounds_x; + fnormalrect.y:= bounds_y + bounds_cy - fnormalrect.cy; + end; + end; + end; + end; + end; + end; +end; + +procedure tdockcontroller.statechanged(const astate: widgetstatesty); +var + dock1: tdockcontroller; +begin + if getparentcontroller(dock1) then begin + dock1.childstatechanged(fintf.getwidget(),astate,fwidgetstate); + end; + fwidgetstate:= astate; +end; + +procedure tdockcontroller.settab_options(const avalue: tabbaroptionsty); +begin + ftab_options:= avalue; + if ftabwidget <> nil then begin + tdocktabwidget(ftabwidget).updateoptions; + end; +end; + +procedure tdockcontroller.settab_color(const avalue: colorty); +begin + ftab_color:= avalue; + if ftabwidget <> nil then begin + tdocktabwidget(ftabwidget).updateoptions; + end; +end; + +procedure tdockcontroller.settab_colortab(const avalue: colorty); +begin + ftab_colortab:= avalue; + if ftabwidget <> nil then begin + tdocktabwidget(ftabwidget).updateoptions; + end; +end; + +procedure tdockcontroller.settab_coloractivetab(const avalue: colorty); +begin + ftab_coloractivetab:= avalue; + if ftabwidget <> nil then begin + tdocktabwidget(ftabwidget).updateoptions; + end; +end; + +procedure tdockcontroller.settab_size(const avalue: integer); +begin + ftab_size:= avalue; + if ftabwidget <> nil then begin + tdocktabwidget(ftabwidget).updateoptions; + end; +end; + +procedure tdockcontroller.settab_sizemin(const avalue: integer); +begin + ftab_sizemin:= avalue; + if ftabwidget <> nil then begin + tdocktabwidget(ftabwidget).updateoptions; + end; +end; + +procedure tdockcontroller.settab_sizemax(const avalue: integer); +begin + ftab_sizemax:= avalue; + if ftabwidget <> nil then begin + tdocktabwidget(ftabwidget).updateoptions; + end; +end; + +procedure tdockcontroller.settab_textflags(const avalue: textflagsty); +begin + ftab_textflags:= avalue; + if ftabwidget <> nil then begin + tdocktabwidget(ftabwidget).updateoptions; + end; +end; + +procedure tdockcontroller.settab_width(const avalue: integer); +begin + ftab_width:= avalue; + if ftabwidget <> nil then begin + tdocktabwidget(ftabwidget).updateoptions; + end; +end; + +procedure tdockcontroller.settab_widthmin(const avalue: integer); +begin + ftab_widthmin:= avalue; + if ftabwidget <> nil then begin + tdocktabwidget(ftabwidget).updateoptions; + end; +end; + +procedure tdockcontroller.settab_widthmax(const avalue: integer); +begin + ftab_widthmax:= avalue; + if ftabwidget <> nil then begin + tdocktabwidget(ftabwidget).updateoptions; + end; +end; + +procedure tdockcontroller.settab_frame(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftab_frame)); + if ftabwidget <> nil then begin + tdocktabwidget(ftabwidget).updateoptions; + end; +end; + +procedure tdockcontroller.settab_face(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftab_face)); + if ftabwidget <> nil then begin + tdocktabwidget(ftabwidget).updateoptions; + end; +end; + +procedure tdockcontroller.settab_facetab(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftab_facetab)); + if ftabwidget <> nil then begin + tdocktabwidget(ftabwidget).updateoptions; + end; +end; + +procedure tdockcontroller.settab_faceactivetab(const avalue: tfacecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftab_faceactivetab)); + if ftabwidget <> nil then begin + tdocktabwidget(ftabwidget).updateoptions; + end; +end; + +procedure tdockcontroller.settab_frametab(const avalue: tframecomp); +begin + setlinkedvar(avalue,tmsecomponent(ftab_frametab)); + if ftabwidget <> nil then begin + tdocktabwidget(ftabwidget).updateoptions; + end; +end; + +function tdockcontroller.getactivetabpage: ttabpage; +begin + result:= nil; + if ftabwidget <> nil then begin + result:= ttabpage(ftabwidget.activepage); + end; +end; + +procedure tdockcontroller.setcolortab(const avalue: colorty); +begin + if fcolortab <> avalue then begin + fcolortab:= avalue; + if ftabpage <> nil then begin + ftabpage.colortab:= fcolortab; + end; + end; +end; + +procedure tdockcontroller.setcoloractivetab(const avalue: colorty); +begin + if fcoloractivetab <> avalue then begin + fcoloractivetab:= avalue; + if ftabpage <> nil then begin + ftabpage.coloractivetab:= fcoloractivetab; + end; + end; +end; + +procedure tdockcontroller.setfacetab(const avalue: tfacecomp); +begin + if ffacetab <> avalue then begin + setlinkedvar(avalue,tmsecomponent(ffacetab)); + if ftabpage <> nil then begin + ftabpage.facetab:= ffacetab; + end; + end; +end; + +procedure tdockcontroller.setfaceactivetab(const avalue: tfacecomp); +begin + if ffaceactivetab <> avalue then begin + setlinkedvar(avalue,tmsecomponent(ffaceactivetab)); + if ftabpage <> nil then begin + ftabpage.faceactivetab:= ffaceactivetab; + end; + end; +end; + +procedure tdockcontroller.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (event = oe_changed) and (ftabwidget <> nil) then begin + tdocktabwidget(ftabwidget).updateoptions; + end; +end; + +procedure tdockcontroller.dolayoutchanged; +var + widget1: twidget; + intf1: idocktarget; +begin + idockcontroller(fintf).dolayoutchanged(self); + widget1:= fintf.getwidget; + if widget1.canevent(tmethod(fonlayoutchanged)) then begin + fonlayoutchanged(self); + end; + widget1:= widget1.parentwidget; + while widget1 <> nil do begin + if widget1.getcorbainterface(typeinfo(idocktarget),intf1) then begin + intf1.getdockcontroller.dolayoutchanged; + break; + end; + widget1:= widget1.parentwidget; + end; + doboundschanged; +end; + +procedure tdockcontroller.doboundschanged; +var + widget1: twidget; +begin + widget1:= fintf.getwidget; + if widget1.canevent(tmethod(fonboundschanged)) and + not application.terminated then begin + fonboundschanged(self); + end; +end; + +procedure tdockcontroller.docaptionchanged; +var + widget1: twidget; + intf1: idocktarget; +begin + idockcontroller(fintf).dodockcaptionchanged(self); + widget1:= fintf.getwidget; + if widget1.canevent(tmethod(foncaptionchanged)) then begin + foncaptionchanged(self); + end; + widget1:= widget1.parentwidget; + while widget1 <> nil do begin + if widget1.getcorbainterface(typeinfo(idocktarget),intf1) then begin + intf1.getdockcontroller.docaptionchanged; + break; + end; + widget1:= widget1.parentwidget; + end; +end; + + +function tdockcontroller.getwidget: twidget; +begin + result:= fintf.getwidget; +end; + +function tdockcontroller.activewidget: twidget; //focused child or active tab +var + tab1: tdocktabpage; +begin + result:= nil; + if ftabwidget <> nil then begin + tab1:= tdocktabpage(tdocktabwidget(ftabwidget).activepage); + if tab1 <> nil then begin + result:= tab1.ftarget; + end; + end + else begin + result:= fintf.getwidget.enteredchild; + end; +end; + +function tdockcontroller.dockparentname(): string; +var + parent: tdockcontroller; +begin + result:= ''; + if getparentcontroller(parent) then begin + result:= parent.getwidget.name; + end; +end; + +function tdockcontroller.childicon(): tmaskedbitmap; + + function check(const awidget: twidget; var res: tmaskedbitmap): boolean; + var + intf1: idockcontroller; + begin + result:= false; + if getcorbainterface(awidget,typeinfo(idockcontroller),intf1) then begin + res:= intf1.getchildicon(); + if (res <> nil) and res.hasimage() then begin + result:= true; + end; + end; + end; //check + +var + ar1: widgetarty; + i1: int32; +begin + if not check(activewidget,result) then begin + ar1:= getitems; + result:= nil; + for i1:= 0 to high(ar1) do begin + if check(ar1[i1],result) then begin + break; + end; + end; + end; +end; + +function tdockcontroller.close: boolean; //simulates mr_windowclosed for owner +begin + result:= doclose(fintf.getwidget); +end; + +function tdockcontroller.closeactivewidget: boolean; + //simulates mr_windowclosed for active widget, true if ok +begin + result:= doclose(activewidget); +end; + +function tdockcontroller.checkclickstate(const info: mouseeventinfoty): boolean; +begin + if od_nofit in foptionsdock then begin + result:= info.shiftstate - [ss_left,ss_shift] = []; + end + else begin + result:= info.shiftstate - [ss_left] = []; + end; +end; + +procedure tdockcontroller.dokeypress(const sender: twidget; + var info: keyeventinfoty); +begin + if (info.key = key_escape) and (fsizeindex >= 0) then begin + include(info.eventstate,es_processed); + cancelsizing(); + end; + inherited; +end; + +procedure tdockcontroller.setsplitdir(const avalue: splitdirty); +begin + if avalue <> fdefaultsplitdir then begin + fdefaultsplitdir:= avalue; + if (avalue <> sd_none) and + not (csloading in fintf.getwidget.componentstate) then begin + fasplitdir:= avalue; + checksplitdir(fasplitdir); + if (fasplitdir <> sd_none) then begin + calclayout(nil,false); + end; + end; + end; +end; + +procedure tdockcontroller.setcurrentsplitdir(const avalue: splitdirty); +begin + if (avalue <> sd_none) and (avalue <> fsplitdir) then begin + fasplitdir:= avalue; + calclayout(nil,false); + end; +end; + +function tdockcontroller.getdockrect: rectty; +var + w1: twidget; +begin + if (ftabwidget <> nil) and + (tdocktabwidget(ftabwidget).activepage <> nil) then begin + w1:= tdocktabwidget(ftabwidget).activepage.container; + result:= w1.paintrect; + translatewidgetpoint1(result.pos,w1,getwidget().container); + end + else begin + result:= idockcontroller(fintf).getplacementrect(); //origin container.pos + end; +end; + +procedure tdockcontroller.receiveevent(const aevent: tobjectevent); +var + int1: integer; + ar1: widgetarty; + widget1: twidget; +begin + if aevent is tchildorderevent then begin + with tchildorderevent(aevent) do begin + setlength(ar1,length(fchildren)); + widget1:= fintf.getwidget; + for int1:= 0 to high(fchildren) do begin + ar1[int1]:= widget1.findchild(fchildren[int1]); + end; + if (ffocusedchild >= 0) and (ffocusedchild <= high(ar1)) and + (ar1[ffocusedchild] <> nil) and ar1[ffocusedchild].canfocus then begin + ar1[ffocusedchild].setfocus(false); + end; + widget1.setchildorder(ar1); + end; + end + else begin + inherited; + end; +end; + +{ tnochildrendockcontroller } + +constructor tnochildrendockcontroller.create(aintf: idockcontroller); +begin + inherited; + foptionsdock:= defaultoptionsdocknochildren; +end; + +{ tgripframe } + +constructor tgripframe.create(const aintf: icaptionframe; + const acontroller: tdockcontroller); +begin + fgrip_color:= defaultgripcolor; + fgrip_coloractive:= defaultgripcoloractive; + fgrip_colorglyph:= cl_glyph; + fgrip_colorglyphactive:= cl_glyphactive; + fgrip_colorbutton:= cl_transparent; + fgrip_colorbuttonactive:= cl_transparent; + fgrip_size:= defaultgripsize; + fgrip_pos:= defaultgrippos; + fgrip_grip:= defaultgripgrip; + fgrip_options:= defaultgripoptions; + fgrip_textflagstop:= defaulttextflagstop; + fgrip_textflagsleft:= defaulttextflagsleft; + fgrip_textflagsbottom:= defaulttextflagsbottom; + fgrip_textflagsright:= defaulttextflagsright; + fgrip_captiondist:= 1; + fcontroller:= acontroller; + inherited create(aintf); + fobjectpicker:= tobjectpicker.create(iobjectpicker(self)); +end; + +destructor tgripframe.destroy; +begin + fobjectpicker.free; + fgrip_face.free; + fgrip_faceactive.free; + inherited; +end; + +procedure tgripframe.checktemplate(const sender: tobject); +begin + inherited; + if fgrip_face <> nil then begin + fgrip_face.checktemplate(sender); + end; + if fgrip_faceactive <> nil then begin + fgrip_faceactive.checktemplate(sender); + end; +end; + +procedure tgripframe.showhint(const aid: int32; var info: hintinfoty); +begin + case dockbuttonrectty(-(aid - hintidframe)) of + dbr_handle: begin + if fgrip_hint = '' then begin + info.caption:= fcontroller.getfloatcaption; + end + else begin + info.caption:= fgrip_hint; + end; + end; + dbr_close: begin + info.caption:= sc(sc_close); + end; + dbr_maximize: begin + info.caption:= sc(sc_maximize); + end; + dbr_normalize: begin + info.caption:= sc(sc_normalize); + end; + dbr_minimize: begin + info.caption:= sc(sc_minimize); + end; + dbr_fixsize: begin + info.caption:= sc(sc_fix_size); + end; + dbr_float: begin + info.caption:= sc(sc_float); + end; + dbr_top: begin + info.caption:= sc(sc_stay_on_top); + end; + dbr_background: begin + info.caption:= sc(sc_stay_in_background); + end; + dbr_lock: begin + info.caption:= sc(sc_lock_children); + end; + dbr_nolock: begin + info.caption:= sc(sc_no_lock); + end; + end; +end; + +procedure tgripframe.drawgripbutton(const acanvas: tcanvas; + const akind: dockbuttonrectty; const arect: rectty; + const acolorglyph: colorty; const acolorbutton: colorty; + const ahiddenedges: edgesty); + +var + hiddenedges1: edgesty; + + function calclevel(const aoption: optiondockty): integer; + begin + if (ord(aoption) >= 0) and ((aoption in fcontroller.foptionsdock) or + (fcontroller.fclickedbutton = akind)) then begin + result:= -1; + hiddenedges1:= [] + end + else begin + result:= 1; + end; + end; + +var + rect2: rectty; + int1: integer; + i1: int32; +begin + if akind = fmousebutton then begin + hiddenedges1:= []; + end + else begin + hiddenedges1:= ahiddenedges; + end; + with acanvas,arect do begin + fillrect(arect,acolorbutton); + i1:= calclevel(optiondockty(-1)); + case akind of + dbr_close: begin + if factgripsize >= 8 then begin + draw3dframe(acanvas,arect,i1,defaultframecolors.edges,hiddenedges1); + drawcross(inflaterect(arect,-2),acolorglyph); + end + else begin + drawcross(arect,acolorglyph); + end; + end; + dbr_maximize: begin + draw3dframe(acanvas,arect,i1,defaultframecolors.edges,hiddenedges1); + drawframe(inflaterect(arect,-2),-1,acolorglyph); + drawvect(makepoint(x+2,y+3),gd_right,cx-5,acolorglyph); + end; + dbr_normalize: begin + draw3dframe(acanvas,arect,i1,defaultframecolors.edges,hiddenedges1); + rect2.cx:= cx * 2 div 3 - 3; + rect2.cy:= rect2.cx; + rect2.pos:= addpoint(pos,makepoint(2,2)); + drawrect(rect2,acolorglyph); + rect2.x:= x + cx - 3 - rect2.cx; + rect2.y:= y + cy - 3 - rect2.cy; + drawrect(rect2,acolorglyph); + end; + dbr_minimize: begin + draw3dframe(acanvas,arect,i1,defaultframecolors.edges,hiddenedges1); + acanvas.move(pos); + case fgrip_pos of + cp_left: begin + drawvect(makepoint(2,2),gd_down,cy-5,acolorglyph); + drawvect(makepoint(3,2),gd_down,cy-5,acolorglyph); + end; + cp_right: begin + drawvect(makepoint(cx-3,2),gd_down,cy-5,acolorglyph); + drawvect(makepoint(cx-4,2),gd_down,cy-5,acolorglyph); + end; + cp_bottom: begin + drawvect(makepoint(2,cy-3),gd_right,cx-5,acolorglyph); + drawvect(makepoint(2,cy-4),gd_right,cx-5,acolorglyph); + end; + else begin //cp_top + drawvect(makepoint(2,2),gd_right,cx-5,acolorglyph); + drawvect(makepoint(2,3),gd_right,cx-5,acolorglyph); + end; + end; + acanvas.remove(pos); + end; + dbr_fixsize: begin + i1:= calclevel(od_fixsize); + draw3dframe(acanvas,arect,i1,defaultframecolors.edges,hiddenedges1); + drawframe(inflaterect(arect,-2),-1,acolorglyph); + end; + dbr_float: begin + draw3dframe(acanvas,arect,i1,defaultframecolors.edges,hiddenedges1); + int1:= cx div 2; + acanvas.move(pos); + drawlines([mp(2,int1),mp(2,2),mp(int1,2)],false,acolorglyph); + drawline(mp(cx-3,cy-3),mp(2,2),acolorglyph); + acanvas.remove(pos); + end; + dbr_top: begin + int1:= x + cx div 2; + i1:= calclevel(od_top); + draw3dframe(acanvas,arect,i1,defaultframecolors.edges,hiddenedges1); + drawlines([makepoint(int1-3,y+4),makepoint(int1,y+1), + makepoint(int1,y+cy-1)],false,acolorglyph); + drawline(makepoint(int1+3,y+4),makepoint(int1,y+1),acolorglyph); + end; + dbr_background: begin + int1:= x + cx div 2; + i1:= calclevel(od_background); + draw3dframe(acanvas,arect,i1,defaultframecolors.edges,hiddenedges1); + drawlines([makepoint(int1-3,y+cx-4),makepoint(int1,y+cy-1), + makepoint(int1,y+1)],false,acolorglyph); + drawline(makepoint(int1+3,y+cx-4),makepoint(int1,y+cy-1),acolorglyph); + end; + dbr_lock: begin + i1:= calclevel(od_lock); + draw3dframe(acanvas,arect,i1,defaultframecolors.edges,hiddenedges1); + drawellipse1(makerect(arect.x+2,arect.y+2,arect.cx-5,arect.cy-5), + acolorglyph); + end; + dbr_nolock: begin + i1:= calclevel(od_nolock); + draw3dframe(acanvas,arect,i1,defaultframecolors.edges,hiddenedges1); + fillellipse1(makerect(arect.x+2,arect.y+2,arect.cx-5,arect.cy-5), + acolorglyph); + drawellipse1(makerect(arect.x+2,arect.y+2,arect.cx-5,arect.cy-5), + acolorglyph); + end; + end; + end; +end; + +procedure tgripframe.internalpaintoverlay(const canvas: tcanvas; + const arect: rectty); + +var +// brushbefore: tsimplebitmap; +// colorbefore: colorty; + po1,po2: pointty; + int1,int2: integer; + rect1: rectty; + col1: colorty; + info1: drawtextinfoty; + floating: boolean; + colorbutton,colorglyph: colorty; + bo1: boolean; + dirbefore: graphicdirectionty; + face1: tface1; + isactive: boolean; +label + endlab; +begin + inherited; + dirbefore:= gd_none; + checkstate; + checkgripsize; + with canvas do begin + rect1:= clipbox; + if testintersectrect(rect1,fgriprect) then begin + isactive:= fintf.getwidget.active; + rect1:= frects[dbr_handle]; + info1.text.text:= fcontroller.caption; + floating:= fcontroller.isfloating; + face1:= tface1(fgrip_face); + if isactive and (fgrip_faceactive <> nil) then begin + face1:= tface1(fgrip_faceactive); + end; + + if face1 <> nil then begin + bo1:= fgrip_pos in [cp_left,cp_right]; + if bo1 then begin + with face1.fi do begin + dirbefore:= fade_direction; + fade_direction:= graphicdirectionty((ord(fade_direction) + 1) and 3); + end; + end; + face1.paint(canvas,rect1); + if bo1 then begin + with face1.fi do begin + fade_direction:= dirbefore; + end; + end; + end; + canvas.save(); + if isactive then begin + colorbutton:= fgrip_colorbuttonactive; + colorglyph:= fgrip_colorglyphactive; + end + else begin + colorbutton:= fgrip_colorbutton; + colorglyph:= fgrip_colorglyph; + end; + if go_closebutton in fgrip_options then begin + drawgripbutton(canvas,dbr_close,frects[dbr_close],colorglyph,colorbutton, + fedges[dbr_close]); + end; + if (frects[dbr_maximize].cx > 0) and + (go_maximizebutton in fgrip_options) then begin + drawgripbutton(canvas,dbr_maximize,frects[dbr_maximize],colorglyph, + colorbutton,fedges[dbr_maximize]); + end; + if (frects[dbr_normalize].cx > 0) and + (go_normalizebutton in fgrip_options) then begin + drawgripbutton(canvas,dbr_normalize,frects[dbr_normalize],colorglyph, + colorbutton,fedges[dbr_normalize]); + end; + if (frects[dbr_minimize].cx > 0) and + (go_minimizebutton in fgrip_options) then begin + drawgripbutton(canvas,dbr_minimize,frects[dbr_minimize],colorglyph, + colorbutton,fedges[dbr_minimize]); + end; + if (frects[dbr_fixsize].cx > 0) and + (go_fixsizebutton in fgrip_options) then begin + drawgripbutton(canvas,dbr_fixsize,frects[dbr_fixsize],colorglyph, + colorbutton,fedges[dbr_fixsize]); + end; + if (frects[dbr_float].cx > 0) and + (go_floatbutton in fgrip_options) then begin + drawgripbutton(canvas,dbr_float,frects[dbr_float],colorglyph,colorbutton, + fedges[dbr_float]); + end; + if (frects[dbr_top].cx > 0) and + (go_topbutton in fgrip_options) then begin + drawgripbutton(canvas,dbr_top,frects[dbr_top],colorglyph,colorbutton, + fedges[dbr_top]); + end; + if (frects[dbr_background].cx > 0) and + (go_backgroundbutton in fgrip_options) then begin + drawgripbutton(canvas,dbr_background,frects[dbr_background],colorglyph, + colorbutton,fedges[dbr_background]); + end; + if (frects[dbr_lock].cx > 0) and + (go_lockbutton in fgrip_options) then begin + drawgripbutton(canvas,dbr_lock,frects[dbr_lock],colorglyph,colorbutton, + fedges[dbr_lock]); + end; + if (frects[dbr_nolock].cx > 0) and + (go_nolockbutton in fgrip_options) then begin + drawgripbutton(canvas,dbr_nolock,frects[dbr_nolock],colorglyph, + colorbutton,fedges[dbr_nolock]); + end; + if (info1.text.text <> '') and + (not floating and (go_showsplitcaption in fgrip_options) or + floating and (go_showfloatcaption in fgrip_options) or + fcontroller.ismdi) then begin + with info1 do begin + text.format:= nil; + dest:= rect1; + clip:= rect1; + font:= self.font; + tabulators:= nil; + case fgrip_pos of + cp_top: begin + flags:= fgrip_textflagstop; + if not ((tf_right in flags) xor (tf_rotate180 in flags)) then begin + inc(dest.x,fgrip_captiondist); + end; + if not (tf_xcentered in flags) then begin + dec(dest.cx,fgrip_captiondist); + end; + inc(dest.y,fgrip_captionoffset); + if tf_clipi in flags then begin + clip.y:= -1000; //no vertical clip + clip.cy:= 2000; + end; + end; + cp_left: begin + flags:= fgrip_textflagsleft; + if (tf_right in flags) xor (tf_rotate180 in flags) then begin + inc(dest.y,fgrip_captiondist); + end + else begin + dec(dest.cy,fgrip_captiondist); + if tf_xcentered in flags then begin + dec(dest.y,fgrip_captiondist); + end; + end; + inc(dest.x,fgrip_captionoffset); + if tf_clipi in flags then begin + clip.x:= -1000; //no horicontal clip + clip.cx:= 2000; + end; + end; + cp_bottom: begin + flags:= fgrip_textflagsbottom; + if not ((tf_right in flags) xor (tf_rotate180 in flags))then begin + inc(dest.x,fgrip_captiondist); + end; + if not (tf_xcentered in flags) then begin + dec(dest.cx,fgrip_captiondist); + end; + dec(dest.y,fgrip_captionoffset); + if tf_clipi in flags then begin + clip.y:= -1000; //no vertical clip + clip.cy:= 2000; + end; + end; + cp_right: begin + flags:= fgrip_textflagsright; + if (tf_right in flags) xor (tf_rotate180 in flags) then begin + inc(dest.y,fgrip_captiondist); + end + else begin + dec(dest.cy,fgrip_captiondist); + if tf_xcentered in flags then begin + dec(dest.y,fgrip_captiondist); + end; + end; + dec(dest.x,fgrip_captionoffset); + if tf_clipi in flags then begin + clip.x:= -1000; //no horicontal clip + clip.cx:= 2000; + end; + end; + end; + drawtext(canvas,info1); + canvas.subcliprect(inflaterect(info1.res,1)); + end; + end; + if fgrip_grip = stb_none then begin + if fintf.getwidget.active then begin + col1:= fgrip_coloractive; + end + else begin + col1:= cl_shadow; + end; + with rect1 do begin + int1:= factgripsize div 4; + int2:= (factgripsize mod 4) div 2; + if fgrip_pos in [cp_left,cp_right] then begin + if cy > 4 then begin + po1.x:= x + int2; + po1.y:= y + 2; + po2.x:= po1.x; + po2.y:= y + cy - 3; + for int2:= 1 to int1 do begin + drawline(po1,po2,cl_highlight); + inc(po1.x,2); + inc(po2.x,2); + drawline(po1,po2,col1); + inc(po1.x,2); + inc(po2.x,2); + end; + end; + end + else begin + if cy > 4 then begin + po1.y:= y + int2; + po1.x:= x + 2; + po2.y:= po1.y; + po2.x:= x + cx - 3; + for int2:= 1 to int1 do begin + drawline(po1,po2,cl_highlight); + inc(po1.y,2); + inc(po2.y,2); + drawline(po1,po2,col1); + inc(po1.y,2); + inc(po2.y,2); + end; + end; + end; + end; + end + else begin +// brushbefore:= brush; + brush:= stockobjects.bitmaps[fgrip_grip]; + if fintf.getwidget.active then begin + color:= fgrip_coloractive; + end + else begin + color:= fgrip_color; + end; + fillrect(rect1,cl_brushcanvas); +// brush:= brushbefore; + // stockobjects.bitmaps[fgrip_grip].paint(canvas,fhandlerect, + // [al_xcentered,al_ycentered,al_tiled],fgrip_color,cl_transparent); + end; +endlab: + canvas.restore;//color:= colorbefore; + end; + end; +end; + +function tgripframe.getbuttonrects(const index: dockbuttonrectty): rectty; +begin + if (index >= dbr_first) and (index <= dbr_last) then begin + if index = dbr_handle then begin + result:= fgriprect; + end + else begin + result:= frects[index]; + end; + dec(result.x,fpaintrect.x+fclientrect.x); + dec(result.y,fpaintrect.y+fclientrect.y); + end + else begin + result:= nullrect; + end; +end; + +function tgripframe.getminimizedsize(out apos: captionposty): sizety; +begin + checkstate; + if fgrip_pos in [cp_right,cp_left] then begin + result.cy:= 0; + result.cx:= fpaintframe.left + fpaintframe.right; + end + else begin + result.cx:= 0; + result.cy:= fpaintframe.top + fpaintframe.bottom;; + end; + apos:= fgrip_pos; +end; + +procedure tgripframe.getpaintframe(var frame: framety); +begin + inherited; + checkgripsize; + case fgrip_pos of + cp_right: inc(frame.right,factgripsize); + cp_top: inc(frame.top,factgripsize); + cp_bottom: inc(frame.bottom,factgripsize); + else inc(frame.left,factgripsize); + end; +end; + +procedure tgripframe.setgrip_color(const avalue: colorty); +begin + if fgrip_color <> avalue then begin + fgrip_color := avalue; + fintf.invalidatewidget; + end; +end; + +procedure tgripframe.setgrip_coloractive(const avalue: colorty); +begin + if fgrip_coloractive <> avalue then begin + fgrip_coloractive:= avalue; + fintf.invalidatewidget; + end; +end; + +procedure tgripframe.setgrip_grip(const avalue: stockbitmapty); +begin + if fgrip_grip <> avalue then begin + fgrip_grip:= avalue; + fintf.invalidatewidget; + end; +end; + +procedure tgripframe.setgrip_size(const avalue: integer); +begin + if fgrip_size <> avalue then begin + fgrip_size:= avalue; + exclude(fgripstate,grps_sizevalid); + internalupdatestate; + end; +end; + +procedure tgripframe.setgrip_options(avalue: gripoptionsty); +const + amask: gripoptionsty = [go_horz,go_vert]; +begin + avalue:= gripoptionsty(setsinglebit( + {$ifdef FPC}longword{$else}word{$endif}(avalue), + {$ifdef FPC}longword{$else}word{$endif}(fgrip_options), + {$ifdef FPC}longword{$else}word{$endif}(amask))); + if fgrip_options <> avalue then begin + if go_floatbutton in avalue then begin + include(fcontroller.fdockstate,dos_hasfloatbutton); + end + else begin + exclude(fcontroller.fdockstate,dos_hasfloatbutton); + end; + fgrip_options:= avalue; + internalupdatestate; + end; +end; + +procedure tgripframe.setgrip_colorglyph(const avalue: colorty); +begin + if fgrip_colorglyph <> avalue then begin + fgrip_colorglyph := avalue; + internalupdatestate; + end; +end; + +procedure tgripframe.setgrip_colorglyphactive(const avalue: colorty); +begin + if fgrip_colorglyphactive <> avalue then begin + fgrip_colorglyphactive := avalue; + internalupdatestate; + end; +end; + +procedure tgripframe.setgrip_colorbutton(const avalue: colorty); +begin + if fgrip_colorbutton <> avalue then begin + fgrip_colorbutton := avalue; + internalupdatestate; + end; +end; + +procedure tgripframe.setgrip_colorbuttonactive(const avalue: colorty); +begin + if fgrip_colorbuttonactive <> avalue then begin + fgrip_colorbuttonactive := avalue; + internalupdatestate; + end; +end; + +procedure tgripframe.checkgripsize; +var + parentcontroller: tdockcontroller; +begin + if not (grps_sizevalid in fgripstate) then begin + factgripsize:= fgrip_size; + if not (od_nolock in fcontroller.foptionsdock) and + fcontroller.getparentcontroller(parentcontroller) and + parentcontroller.nogrip then begin + factgripsize:= 0; + end; + include(fgripstate,grps_sizevalid); + end; +end; + +procedure tgripframe.updaterects; + +var + firstbu,lastbu: dockbuttonrectty; + + procedure initrect(const index: dockbuttonrectty); + begin + if firstbu = dbr_none then begin + firstbu:= index; + end; + lastbu:= index; + with frects[dbr_handle] do begin + case fgrip_pos of + cp_right,cp_left: begin + frects[index].x:= x; + frects[index].y:= y; + inc(y,factgripsize); + dec(cy,factgripsize); + fedges[index]:= [edg_top,edg_bottom]; + end; + else begin //top,bottom + dec(cx,factgripsize); + frects[index].x:= x + cx; + frects[index].y:= y; + fedges[index]:= [edg_left,edg_right]; + end; + end; + end; + if go_buttonframe in fgrip_options then begin + fedges[index]:= []; + end; + with frects[index] do begin + cx:= factgripsize; + cy:= factgripsize; + end; + end; + +var + bo1,bo2,bo3,designing: boolean; + parentcontroller: tdockcontroller; + +begin //widget origin + inherited; + firstbu:= dbr_none; + checkgripsize; + with fgriprect do begin + case fgrip_pos of + cp_right: begin + x:= fpaintrect.x + fpaintrect.cx; + y:= fpaintrect.y; + cx:= factgripsize; + cy:= fpaintrect.cy; + end; + cp_left: begin + x:= fpaintrect.x - factgripsize; + y:= fpaintrect.y; + cx:= factgripsize; + cy:= fpaintrect.cy; + end; + cp_top: begin + x:= fpaintrect.x; + y:= fpaintrect.y - factgripsize; + cx:= fpaintrect.cx; + cy:= factgripsize; + end; + else begin //cp_bottom + x:= fpaintrect.x; + y:= fpaintrect.y + fpaintrect.cy; + cx:= fpaintrect.cx; + cy:= factgripsize; + end; + end; + end; + with fintf.getwidget do begin + fillchar(frects,sizeof(frects),0); + frects[dbr_handle]:= fgriprect; + designing:= csdesigning in componentstate; + bo1:= (parentwidget <> nil) and (fcontroller.fmdistate <> mds_floating) or + designing; + bo3:= fcontroller.isfullarea; + bo2:= not bo3 or designing; + if bo1 and (go_closebutton in fgrip_options) then begin + initrect(dbr_close); + end; + if fcontroller.ismdi or designing then begin + if (go_maximizebutton in fgrip_options) and + ((fcontroller.mdistate <> mds_maximized) or designing) then begin + initrect(dbr_maximize); + end; + if (go_normalizebutton in fgrip_options) and + ((fcontroller.mdistate <> mds_normal) or designing) then begin + initrect(dbr_normalize); + end; + if (go_minimizebutton in fgrip_options) and + ((fcontroller.mdistate <> mds_minimized) or designing) then begin + initrect(dbr_minimize); + end; + end; + if bo1{ or designing} then begin + if (go_fixsizebutton in fgrip_options) then begin + if designing or + bo3 and fcontroller.getparentcontroller(parentcontroller) and + not parentcontroller.nofit and + (parentcontroller.fsplitdir <> sd_tabed) then begin + initrect(dbr_fixsize); + end; + end; + if (go_floatbutton in fgrip_options) then begin + initrect(dbr_float); + end; + end; + if bo2 then begin + if go_topbutton in fgrip_options then begin + initrect(dbr_top); + end; + if go_backgroundbutton in fgrip_options then begin + initrect(dbr_background); + end; + end; + if go_lockbutton in fgrip_options then begin + initrect(dbr_lock); + end; + if bo1 and (go_nolockbutton in fgrip_options) and + ((fcontroller.getparentcontroller <> nil) or designing) then begin + initrect(dbr_nolock); + end; + end; + if firstbu <> dbr_none then begin + if fgrip_pos in [cp_right,cp_left] then begin + exclude(fedges[firstbu],edg_top); + exclude(fedges[lastbu],edg_bottom); + end + else begin + exclude(fedges[firstbu],edg_right); + exclude(fedges[lastbu],edg_left); + end; + end; +end; + +procedure tgripframe.updatestate; +begin + if go_horz in fgrip_options then begin + if go_opposite in fgrip_options then begin + fgrip_pos:= cp_bottom; + end + else begin + fgrip_pos:= cp_top; + end; + end + else begin + if go_vert in fgrip_options then begin + if go_opposite in fgrip_options then begin + fgrip_pos:= cp_left; + end + else begin + fgrip_pos:= cp_right; + end; + end; + end; + inherited; +end; + +function tgripframe.griprect: rectty; +begin + result:= frects[dbr_handle]; +end; + +function tgripframe.getwidget: twidget; +begin + result:= fcontroller.fintf.getwidget; +end; + +function tgripframe.getclientrect: rectty; +begin + result:= fcontroller.fintf.getwidget.clientrect; +end; + +procedure tgripframe.invalidatewidget(); +begin + fcontroller.fintf.getwidget.invalidatewidget(); +end; + +procedure tgripframe.invalidaterect(const rect: rectty; + const org: originty = org_client; const noclip: boolean = false); +begin + fcontroller.fintf.getwidget.invalidaterect(rect,org,noclip); +end; + +procedure tgripframe.setlinkedvar(const source: tmsecomponent; + var dest: tmsecomponent; const linkintf: iobjectlink = nil); +begin + with twidget1(fcontroller.fintf.getwidget) do begin + if not (csdestroying in componentstate) then begin + setlinkedvar(source,dest,linkintf); + end; + end; +end; + +function tgripframe.getcomponentstate: tcomponentstate; +begin + result:= fcontroller.fintf.getwidget.componentstate; +end; + +procedure tgripframe.widgetregioninvalid; +begin + twidget1(fcontroller.fintf.getwidget).widgetregioninvalid; +end; + +procedure tgripframe.updatemousestate(const sender: twidget; + const info: mouseeventinfoty); +begin + inherited; + if pointinrect(info.pos,fgriprect) or (fcontroller.canmdisize) then begin + with twidget1(sender) do begin + fwidgetstate:= fwidgetstate + [ws_wantmousemove,ws_wantmousebutton]; + end; + end; +end; + +procedure tgripframe.getpickobjects(const sender: tobjectpicker; + var objects: integerarty); +var + kind1: sizingkindty; + rect: rectty; +begin + rect:= sender.pickrect; + if fcontroller.canmdisize and + (fcontroller.mdistate <> mds_minimized) and + (not pointinrect(rect.pos,fgriprect) or + pointinrect(rect.pos,frects[dbr_handle])) then begin + with fintf.getwidget do begin + kind1:= calcsizingkind(rect.pos,makerect(nullpoint,size)); + if anchors * [an_left,an_right] = [] then begin + case kind1 of + sik_right,sik_left: kind1:= sik_none; + sik_topright,sik_topleft: kind1:= sik_top; + sik_bottomright,sik_bottomleft: kind1:= sik_bottom; + end; + end; + if anchors * [an_top,an_bottom] = [] then begin + case kind1 of + sik_top,sik_bottom: kind1:= sik_none; + sik_topleft,sik_bottomleft: kind1:= sik_left; + sik_topright,sik_bottomright: kind1:= sik_right; + end; + end; + end; + if kind1 <> sik_none then begin + setlength(objects,1); + objects[0]:= ord(kind1); + end + else begin + objects:= nil; + end; + end + else begin + objects:= nil; + end; +end; + +function tgripframe.getcursorshape(const sender: tobjectpicker; + var shape: cursorshapety): boolean; +var + ar1: integerarty; +begin + getpickobjects(sender,ar1); + result:= ar1 <> nil; + if result then begin + shape:= sizingcursors[sizingkindty(ar1[0])]; + end +end; + +procedure tgripframe.beginpickmove(const sender: tobjectpicker); +begin + //dummy +end; + +procedure tgripframe.pickthumbtrack(const sender: tobjectpicker); +begin + //dummy +end; + +function tgripframe.calcsizingrect(const akind: sizingkindty; + const offset: pointty): rectty; +var + cxmin,cymin: integer; + int1: integer; +begin + with fintf.getwidget do begin + cxmin:= bounds_cxmin; + cymin:= bounds_cymin; + if fgrip_pos in [cp_right,cp_left] then begin + int1:= fpaintframe.left + fpaintframe.right; + if cxmin < int1 then begin + cxmin:= int1; + end; + int1:= fpaintframe.top + fpaintframe.bottom + + fgriprect.cy - frects[dbr_handle].cy; + if cymin < int1 then begin + cymin:= int1; + end; + end + else begin + int1:= fpaintframe.top + fpaintframe.bottom; + if cymin < int1 then begin + cymin:= int1; + end; + int1:= fpaintframe.left + fpaintframe.right + + fgriprect.cx - frects[dbr_handle].cx; + if cxmin < int1 then begin + cxmin:= int1; + end; + end; + result:= adjustsizingrect(widgetrect,akind,offset, + cxmin,bounds_cxmax,cymin,bounds_cymax); + if parentwidget <> nil then begin + with parentwidget do begin + intersectrect(result,makerect(clientwidgetpos,maxclientsize),result); + end; + end; + end; +end; + +procedure tgripframe.endpickmove(const sender: tobjectpicker); +var + ar1: integerarty; +begin + ar1:= sender.currentobjects; + if ar1 <> nil then begin + fcontroller.fnormalrect:= calcsizingrect(sizingkindty(ar1[0]), + sender.pickoffset); + fcontroller.mdistate:= mds_normal; + fintf.getwidget.widgetrect:= fcontroller.fnormalrect; + end; +end; + +procedure tgripframe.paintxorpic(const sender: tobjectpicker; + const canvas: tcanvas); +var + rect1: rectty; + ar1: integerarty; +begin + ar1:= sender.currentobjects; + if ar1 <> nil then begin + rect1:= calcsizingrect(sizingkindty(ar1[0]),sender.pickoffset); + with fintf.getwidget do begin + subpoint1(rect1.pos,paintparentpos); + canvas.save; + canvas.addcliprect(paintrectparent); + canvas.drawxorframe(rect1,-3,stockobjects.bitmaps[stb_dens50]); + canvas.restore; + end; + end; +end; + +procedure tgripframe.mouseevent(var info: mouseeventinfoty); +begin + if not fcontroller.active then begin + fobjectpicker.mouseevent(info); + end; +end; + +procedure tgripframe.updatewidgetstate; +begin + inherited; + fintf.getwidget.invalidaterect(fgriprect,org_widget); +end; + +function tgripframe.getgrip_face: tface; +begin + fintf.getwidget.getoptionalobject(fgrip_face,@createface); + result:= fgrip_face; +end; + +procedure tgripframe.setgrip_face(const avalue: tface); +begin + fintf.getwidget.setoptionalobject(avalue,fgrip_face,@createface); +end; + +function tgripframe.getgrip_faceactive: tface; +begin + fintf.getwidget.getoptionalobject(fgrip_faceactive,@createfaceactive); + result:= fgrip_faceactive; +end; + +procedure tgripframe.setgrip_faceactive(const avalue: tface); +begin + fintf.getwidget.setoptionalobject(avalue,fgrip_faceactive,@createfaceactive); +end; + +procedure tgripframe.createface(); +begin + fgrip_face:= tface.create(iface(self)); +end; + +procedure tgripframe.createfaceactive(); +begin + fgrip_faceactive:= tface.create(iface(self)); +end; + +function tgripframe.translatecolor(const acolor: colorty): colorty; +begin + result:= fintf.getwidget.translatecolor(acolor); +end; + +procedure tgripframe.cancelpickmove(const sender: tobjectpicker); +begin + //dummy +end; + +function tgripframe.ishintarea(const apos: pointty; var aid: int32): boolean; + //widget origin +begin + result:= pointinrect(apos,fgriprect{frects[dbr_handle]}); + if result then begin + if go_buttonhints in fgrip_options then begin + aid:= hintidframe - ord(fcontroller.checkbuttonarea( + subpoint(apos,fcontroller.getwidget.clientwidgetpos))); + if not (od_captionhint in fcontroller.optionsdock) and + (aid = hintidframe-ord(dbr_handle)) then begin + result:= false; + end; + end + else begin + if (od_captionhint in fcontroller.optionsdock) then begin + aid:= hintidframe - ord(dbr_handle); + end; + end; + end + else begin + result:= inherited ishintarea(apos,aid); + end; +end; + +procedure tgripframe.setgrip_textflagstop(const avalue: textflagsty); +begin + if fgrip_textflagstop <> avalue then begin + fgrip_textflagstop:= checktextflags(fgrip_textflagstop,avalue); + fintf.invalidatewidget(); + end; +end; + +procedure tgripframe.setgrip_textflagsright(const avalue: textflagsty); +begin + if fgrip_textflagsleft <> avalue then begin + fgrip_textflagsleft:= checktextflags(fgrip_textflagsleft,avalue); + fintf.invalidatewidget(); + end; +end; + +procedure tgripframe.setgrip_textflagsbottom(const avalue: textflagsty); +begin + if fgrip_textflagsbottom <> avalue then begin + fgrip_textflagsbottom:= checktextflags(fgrip_textflagsbottom,avalue); + fintf.invalidatewidget(); + end; +end; + +procedure tgripframe.setgrip_textflagsrright(const avalue: textflagsty); +begin + if fgrip_textflagsright <> avalue then begin + fgrip_textflagsright:= checktextflags(fgrip_textflagsright,avalue); + fintf.invalidatewidget(); + end; +end; + +procedure tgripframe.setgrip_captiondist(const avalue: integer); +begin + if fgrip_captiondist <> avalue then begin + fgrip_captiondist:= avalue; + fintf.invalidatewidget(); + end; +end; + +procedure tgripframe.setgrip_captionoffset(const avalue: integer); +begin + if fgrip_captionoffset <> avalue then begin + fgrip_captionoffset:= avalue; + fintf.invalidatewidget(); + end; +end; + +{ tdockhandle } + +constructor tdockhandle.create(aowner: tcomponent); +begin + fgrip_color:= defaultgripcolor; + fgrip_pos:= cp_bottomright; + fgrip_grip:= stb_none; + inherited; + foptionswidget:= defaultoptionswidget + [ow_top{,ow_noautosizing}]; + foptionswidget1:= defaultoptionswidget1 + [ow1_noautosizing]; + size:= makesize(15,15); + anchors:= [an_right,an_bottom]; + color:= cl_transparent; +end; + +function tdockhandle.gethandlerect: rectty; +begin + result:= paintrect; +end; + +procedure tdockhandle.setgrip_color(const Value: colorty); +begin + if fgrip_color <> value then begin + fgrip_color:= value; + invalidate; + end; +end; + +procedure tdockhandle.setgrip_grip(const Value: stockbitmapty); +begin + if fgrip_grip <> value then begin + fgrip_grip:= value; + invalidate; + end; +end; + +procedure tdockhandle.setgrip_pos(const Value: captionposty); +begin + if fgrip_pos <> value then begin + fgrip_pos:= value; + invalidate; + end; +end; + +procedure tdockhandle.clientmouseevent(var info: mouseeventinfoty); +var + po1: pointty; +begin + inherited; + if not (es_processed in info.eventstate) and (fcontroller <> nil) then begin + po1:= translateclientpoint(nullpoint,self,fcontroller.fintf.getwidget); + addpoint1(info.pos,po1); + fcontroller.clientmouseevent(info); + subpoint1(info.pos,po1); + end; +end; + +procedure tdockhandle.dopaintforeground(const canvas: tcanvas); +var + rect1: rectty; + int1,int2,x,y: integer; +begin + inherited; + rect1:= innerclientrect; + if fgrip_grip <> stb_none then begin + with canvas do begin + brush:= stockobjects.bitmaps[fgrip_grip]; + color:= fgrip_color; + fillrect(rect1,cl_brushcanvas); + end; + end + else begin + case fgrip_pos of + cp_bottomright: begin + x:= rect1.x + rect1.cx - 1; + y:= rect1.y + rect1.cy - 1; + if rect1.cy < rect1.cx then begin + int2:= rect1.cy; + end + else begin + int2:= rect1.cx + end; + dec(int2); + int1:= 2; + while (int1 < int2) do begin + canvas.drawline(makepoint(x-int1,y),makepoint(x,y-int1),cl_shadow); + canvas.drawline(makepoint(x-int1-1,y-1),makepoint(x-1,y-int1-1),cl_highlight); + inc(int1,4); + end; + end; + end; + end; +end; + +function tdockhandle.gethint: msestring; +begin + result:= inherited gethint(); + if (result = '') and (fcontroller <> nil) and + (od_captionhint in fcontroller.optionsdock) then begin + result:= fcontroller.caption; + end; +end; + +{ tdockpanel } + +constructor tdockpanel.create(aowner: tcomponent); +begin + ficon:= tmaskedbitmap.create(bmk_rgb); + ficon.onchange:= {$ifdef FPC}@{$endif}iconchanged; + if fdragdock = nil then begin + fdragdock:= tnochildrendockcontroller.create(idockcontroller(self)); + end; + inherited; + optionswidget:= defaultdockpaneloptionswidget; +end; + +destructor tdockpanel.destroy; +begin + ficon.free; + inherited; + fdragdock.Free; +end; + +function tdockpanel.checkdock(var info: draginfoty): boolean; +begin + result:= true; +end; + +procedure tdockpanel.childmouseevent(const sender: twidget; + var info: mouseeventinfoty); +begin + if not (es_processed in info.eventstate) then begin + fdragdock.childormouseevent(sender,info); + if not (es_processed in info.eventstate) then begin + inherited; + end; + end; +end; + +procedure tdockpanel.internalcreateframe; +begin + tgripframe.create(iscrollframe(self),fdragdock); +end; + +procedure tdockpanel.dragevent(var info: draginfoty); +begin + if not fdragdock.beforedragevent(info) then begin + inherited; + end; + fdragdock.afterdragevent(info); +end; + +function tdockpanel.getframe: tgripframe; +begin + result:= tgripframe(inherited getframe); +end; + +procedure tdockpanel.setframe(const Value: tgripframe); +begin + inherited setframe(value); +end; + +procedure tdockpanel.setdragdock(const Value: tnochildrendockcontroller); +begin + fdragdock.assign(Value); +end; + +procedure tdockpanel.updatewindowinfo(var info: windowinfoty); +begin + inherited; + info.options:= foptionswindow; + getwindowicon(ficon,info.icon,info.iconmask); +end; + +function tdockpanel.getbuttonrects(const index: dockbuttonrectty): rectty; +begin + if fframe = nil then begin + if index = dbr_handle then begin + result:= clientrect; + end + else begin + result:= nullrect; + end; + end + else begin + result:= tgripframe(fframe).getbuttonrects(index); + end; +end; + +function tdockpanel.getminimizedsize(out apos: captionposty): sizety; +begin + if fframe = nil then begin + result:= nullsize; + end + else begin + result:= tgripframe(fframe).getminimizedsize(apos); + end; +end; + +function tdockpanel.getplacementrect: rectty; +begin + result:= innerpaintrect; + minsize:= nullsize; +end; + +function tdockpanel.getcaption: msestring; +begin + result:= ''; +end; + +function tdockpanel.getchildicon: tmaskedbitmap; +begin + result:= nil; +end; + +procedure tdockpanel.setstatfile(const Value: tstatfile); +begin + setstatfilevar(istatfile(self),value,fstatfile); +end; + +procedure tdockpanel.seticon(const avalue: tmaskedbitmap); +begin + ficon.assign(avalue); +end; + +procedure tdockpanel.iconchanged(const sender: tobject); +var + icon1,mask1: pixmapty; +begin + if ownswindow then begin + getwindowicon(ficon,icon1,mask1); + gui_setwindowicon(window.winid,icon1,mask1); + end; +end; + + //istatfile +procedure tdockpanel.dostatread(const reader: tstatreader); +begin + fdragdock.dostatread(reader); +end; + +procedure tdockpanel.dostatwrite(const writer: tstatwriter); +begin + fdragdock.dostatwrite(writer,nil); +end; + +procedure tdockpanel.statreading; +begin + fdragdock.statreading; +end; + +procedure tdockpanel.statread; +begin + fdragdock.statread; +end; + +function tdockpanel.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +procedure tdockpanel.clientrectchanged; +begin + fdragdock.beginclientrectchanged; + inherited; + fdragdock.endclientrectchanged; +end; + +procedure tdockpanel.widgetregionchanged(const sender: twidget); +begin + inherited; + fdragdock.widgetregionchanged(sender); +end; + +procedure tdockpanel.setparentwidget(const Value: twidget); +begin + if fframe <> nil then begin + exclude(tcustomframe1(fframe).fstate,fs_rectsvalid); + end; + inherited; +end; + +procedure tdockpanel.dopaintforeground(const acanvas: tcanvas); +begin + inherited; + fdragdock.dopaint(acanvas); +end; + +procedure tdockpanel.doactivate; +begin + fdragdock.doactivate; + inherited; +end; + +procedure tdockpanel.statechanged; +begin + fdragdock.statechanged(fwidgetstate); + inherited; +end; + +procedure tdockpanel.poschanged; +begin + fdragdock.poschanged; +end; + +procedure tdockpanel.parentchanged; +begin + inherited; + fdragdock.parentchanged(self); +end; + +function tdockpanel.getdockcontroller: tdockcontroller; +begin + result:= fdragdock; +end; + +procedure tdockpanel.dolayoutchanged(const sender: tdockcontroller); +begin + //dummy +end; + +procedure tdockpanel.dodockcaptionchanged(const sender: tdockcontroller); +begin + //dummy +end; + +function tdockpanel.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +function tdockpanel.calcminscrollsize: sizety; +begin + result:= inherited calcminscrollsize(); + if not (csdesigning in componentstate) then begin + fdragdock.updateminscrollsize(result); + end; +end; + +procedure tdockpanel.setdockingareacaption(const avalue: msestring); +begin + fdockingareacaption:= avalue; + invalidate; +end; + +procedure tdockpanel.dopaintbackground(const canvas: tcanvas); +begin + inherited; + if fdockingareacaption <> '' then begin + paintdockingareacaption(canvas,self,fdockingareacaption); + end; +end; + +{ tchildorderevent } + +constructor tchildorderevent.create(const sender: tdockcontroller); +begin + fchildren:= sender.fchildren; + ffocusedchild:= sender.ffocusedchild; + inherited create(ek_object,ievent(sender)); +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/msedockpanelform.pas b/mseide-msegui/lib/common/widgets/msedockpanelform.pas new file mode 100644 index 0000000..c1eb575 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msedockpanelform.pas @@ -0,0 +1,835 @@ +{ MSEgui Copyright (c) 1999-2014 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msedockpanelform; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + classes,mclasses,mselist,msetypes,mseglob,mseguiglob,mseguiintf,mseapplication, + msestat,msemenus,msegui,msedatalist, + msegraphics,msegraphutils,mseevent,mseclasses,mseforms,msedock, + msestrings,msestatfile; + +const + defaultdockpanelgripoptions = defaultgripoptions + + [go_fixsizebutton,go_topbutton,go_backgroundbutton,go_lockbutton]; + defaultdockpaneloptionsdock = defaultoptionsdock + + [od_canmove,od_canfloat,od_candock,od_acceptsdock,od_dockparent, + od_splitvert,od_splithorz,od_tabed,od_proportional,od_propsize]; + defaultdockpanelwidth = 350; + defaultdockpanelheight = 200; + defaultdockpaneloptions = + (defaultformoptions - [fo_autoreadstat,fo_autowritestat]) + + [fo_globalshortcuts,fo_screencentered]; + defaultdockpaneloptionswidget = + (defaultformwidgetoptions - [ow_destroywidgets]) + + [ow_mousefocus,ow_arrowfocusin,ow_arrowfocusout]; + defaultdockstatprio = 256; +type + tdockpanelformcontroller = class; + tdockpanelform = class; + + tdockpanelformmenuitem = class(tmenuitem) + private + fpanel: tdockpanelform; + public + constructor create(const apanel: tdockpanelform); + destructor destroy; override; + end; + + tdockpanelformscrollbox = class(tdockformscrollbox) + protected + fdockingareacaption: msestring; + procedure dopaintbackground(const canvas: tcanvas) override; + end; + + tdockpanelform = class(tdockformwidget) + private + fmenuitem: tdockpanelformmenuitem; + fnameindex: integer; //0 for unnumbered + fcontroller: tdockpanelformcontroller; + procedure showexecute(const sender: tobject); + procedure setdockingareacaption(const avalue: msestring); + function getdockingareacaption: msestring; + protected + procedure updatecaption(acaption: msestring); + procedure dodockcaptionchanged(const sender: tdockcontroller); override; + procedure dolayoutchanged(const sender: tdockcontroller); override; + class function hasresource: boolean; override; + class function getmoduleclassname: string; override; +// constructor docreate(aowner: tcomponent); override; + procedure docreate(aowner: tcomponent); override; + public + constructor create(aowner: tcomponent; load: boolean); override; + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure doonclose; override; + function canclose(const newfocus: twidget): boolean; override; + published + property visible default false; + property bounds_cx default defaultdockpanelwidth; + property bounds_cy default defaultdockpanelheight; + property options default defaultdockpaneloptions; + property optionswidget default defaultdockpaneloptionswidget; + property dockingareacaption: msestring read getdockingareacaption + write setdockingareacaption; + end; + + panelfoclassty = class of tdockpanelform; + + dockpanelupdatecaptioneventty = + procedure(const sender: tdockpanelformcontroller; const apanel: tdockpanelform; + var avalue: msestring) of object; + dockpanelupdatemenueventty = + procedure(const sender: tdockpanelformcontroller; const apanel: tdockpanelform; + const avalue: tmenuitem) of object; + createpaneleventty = + procedure(const sender: tdockpanelformcontroller; + var apanel: tdockpanelform) of object; +{ getpanelclasseventty = + procedure(const sender: tdockpanelcontroller; + var aclass: panelfoclassty) of object; +} + createdynamiccompeventty = + procedure(const sender: tdockpanelformcontroller; + const aclassname: string; + const aname: string; var acomponent: tmsecomponent) of object; + dynamiccompeventty = procedure(const sender: tdockpanelformcontroller; + const acomponent: tmsecomponent) of object; + + tdockpanelformcontroller = class(tmsecomponent,istatfile) + private + fpanellist: tpointerlist; + fmenu: tcustommenu; + fstatfile: tstatfile; + fstatvarname: msestring; + fmenunamepath: string; + fonupdatecaption: dockpanelupdatecaptioneventty; + fonupdatemenu: dockpanelupdatemenueventty; + fstatfileclient: tstatfile; + foncreatepanel: createpaneleventty; + foptionsdock: optionsdockty; + foptionsgrip: gripoptionsty; + fcaption: msestring; + fstatfileclients: tstatfilearrayprop; + fstatpriority: integer; + fdockingareacaption: msestring; + fdynamiccomps: msecomponentarty; + foncreatedynamiccomp: createdynamiccompeventty; + fonregisterdynamiccomp: dynamiccompeventty; + fonunregisterdynamiccomp: dynamiccompeventty; + procedure updatestat(const filer: tstatfiler); + procedure setmenu(const avalue: tcustommenu); +// procedure checkstatfile(const avalue: tstatfile; const ref: tstatfile); + procedure setstatfile(const avalue: tstatfile); + procedure setstatfileclient(const avalue: tstatfile); + procedure setstatfileclients(const avalue: tstatfilearrayprop); + protected + procedure objectevent(const sender: tobject; + const event: objecteventty) override; + //istatfile + procedure dostatread(const reader: tstatreader); virtual; + procedure dostatwrite(const writer: tstatwriter); virtual; + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function newpanel(aname: string = ''): tdockpanelform; + procedure updatewindowcaptions(const avalue: msestring); + procedure removepanels; + function createdynamiccomp(const aclassname: string): tmsecomponent; + //nil if not found + function createdynamiccomp( + const aclass: msecomponentclassty): tmsecomponent; + function createdynamicwidget(const aclass: widgetclassty): twidget; + procedure registerdynamiccomp(const acomp: tmsecomponent); + procedure unregisterdynamiccomp(const acomp: tmsecomponent); + property dynamiccomps: msecomponentarty read fdynamiccomps; + published + property menu: tcustommenu read fmenu write setmenu; + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read getstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default defaultdockstatprio; + property statfileclients: tstatfilearrayprop read fstatfileclients + write setstatfileclients; //called before statfileclient + property statfileclient: tstatfile read fstatfileclient + write setstatfileclient; //last called + + property menunamepath: string read fmenunamepath write fmenunamepath; + //delimiter = '.' + property caption: msestring read fcaption write fcaption; + property dockingareacaption: msestring read fdockingareacaption + write fdockingareacaption; + property optionsdock: optionsdockty read foptionsdock + write foptionsdock default defaultdockpaneloptionsdock; + property optionsgrip: gripoptionsty read foptionsgrip + write foptionsgrip default defaultdockpanelgripoptions; + property onupdatecaption: dockpanelupdatecaptioneventty + read fonupdatecaption write fonupdatecaption; + property onupdatemenu: dockpanelupdatemenueventty + read fonupdatemenu write fonupdatemenu; + property oncreatepanel: createpaneleventty read foncreatepanel + write foncreatepanel; + property oncreatedynamiccomp: createdynamiccompeventty + read foncreatedynamiccomp write foncreatedynamiccomp; + property onregisterdynamiccomp: dynamiccompeventty + read fonregisterdynamiccomp write fonregisterdynamiccomp; + property onunregisterdynamiccomp: dynamiccompeventty + read fonunregisterdynamiccomp write fonunregisterdynamiccomp; + end; + +function createdockpanelform(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; + +implementation +uses + {msedockpanelform_mfm,}sysutils,msekeyboard,mseactions,msearrayutils, + mseformatstr; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tcomponent1 = class(tcomponent); + tmsecomponent1 = class(tmsecomponent); + + pdockpanelform = ^tdockpanelform; + + tpanelformdockcontroller = class(tformdockcontroller) + public + constructor create(const aowner: tcustomdockform); +// constructor create(aintf: idockcontroller); + published + property optionsdock default defaultoptionsdock; + end; + +function createdockpanelform(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; + +begin + result:= tmsecomponent(aclass.newinstance); +{$warnings off} + tcomponent1(result).setdesigning(true); //used for wo_groupleader +{$warnings on} + tdockpanelform(result).create(nil,false); + tmsecomponent1(result).factualclassname:= aclassname; +end; + +{ tdockpanelformcontroller } + +constructor tdockpanelformcontroller.create(aowner: tcomponent); +begin + fstatpriority:= defaultdockstatprio; + foptionsdock:= defaultdockpaneloptionsdock; + foptionsgrip:= defaultdockpanelgripoptions; +// fcaption:= 'Panel'; + fpanellist:= tpointerlist.create; + fstatfileclients:= tstatfilearrayprop.create; + inherited; +end; + +destructor tdockpanelformcontroller.destroy; +var + i1: int32; +begin + for i1:= high(fdynamiccomps) downto 0 do begin + ievent(fdynamiccomps[i1]).unlink(ievent(self), + ievent(fdynamiccomps[i1])); + end; + fdynamiccomps:= nil; + inherited; + freeandnil(fpanellist); + fstatfileclients.free; +end; + +procedure tdockpanelformcontroller.updatestat(const filer: tstatfiler); +var + ar1,ar2,ar3: msestringarty; + i1: integer; + comp1: tmsecomponent; +begin + ar1:= nil; + if filer.iswriter then begin + setlength(ar1,fpanellist.count); + for i1:= 0 to high(ar1) do begin + ar1[i1]:= msestring(tdockpanelform(fpanellist[i1]).name); + end; + setlength(ar2,length(fdynamiccomps)); + for i1:= 0 to high(ar2) do begin + ar2[i1]:= msestring(fdynamiccomps[i1].classname+','+fdynamiccomps[i1].name); + end; + end; + filer.updatevalue('panels',ar1); + filer.updatevalue('dynamiccomps',ar2); + if not filer.iswriter then begin + if canevent(tmethod(foncreatedynamiccomp)) then begin + for i1:= 0 to high(ar2) do begin + ar3:= splitstring(ar2[i1],','); + if high(ar3) > 0 then begin + comp1:= nil; + foncreatedynamiccomp(self,string(ar3[0]),string(ar3[1]),comp1); + if comp1 <> nil then begin + comp1.name:= string(ar3[1]); + registerdynamiccomp(comp1); + end; + end; + end; + end; + for i1:= fpanellist.count - 1 downto 0 do begin + tdockpanelform(fpanellist[i1]).free; + end; + for i1:= 0 to high(ar1) do begin + try + with newpanel(ansistring(ar1[i1])) do begin + if statfile = self.statfile then begin + statreading(); + end; + end; + except + end; + end; + end; + with fstatfileclients do begin + for i1:= 0 to count - 1 do begin + with items[i1] do begin + if (statfile <> nil) and (statfile <> fstatfile) then begin + statfile.updatestat('client_'+inttostrmse(i1),filer); + end; + end; + end; + end; + if (fstatfileclient <> nil) and (fstatfile <> fstatfileclient) then begin + fstatfileclient.updatestat('clients',filer); + end; +end; + +function tdockpanelformcontroller.newpanel(aname: string = ''): tdockpanelform; +var + item1: tmenuitem; + int1,int2: integer; + ar1: integerarty; +begin + result:= nil; + item1:= nil; + int2:= 0; + if fmenu <> nil then begin + if fmenunamepath <> '' then begin + item1:= fmenu.menu.itembynames(splitstring(fmenunamepath,'.')); + end; + end; + if aname = '' then begin + setlength(ar1,fpanellist.count); + for int1:= 0 to high(ar1) do begin + ar1[int1]:= tdockpanelform(fpanellist[int1]).fnameindex; + end; + sortarray(ar1); + int2:= length(ar1); + for int1:= 0 to high(ar1) do begin //find first gap + if ar1[int1] <> int1 then begin + int2:= int1; + break; + end; + end; + end + else begin + int2:= strtoint(copy(aname,6,bigint))-1; + end; + + if canevent(tmethod(foncreatepanel)) then begin + foncreatepanel(self,result); + end; + if result = nil then begin + result:= tdockpanelform.create(self); + with result do begin + createframe; + dragdock.optionsdock:= defaultdockpaneloptionsdock; + frame.grip_options:= defaultdockpanelgripoptions; + dragdock.optionsdock:= foptionsdock; + frame.grip_options:= foptionsgrip; + container.frame.framei:= nullframe; + statfile:= self.fstatfileclient; + end; + end; + + int1:= int2 + 1; + if aname = '' then begin + aname:= 'panel'+inttostr(int1); + end; + with result do begin + name:= aname; + fnameindex:= int2; + if dockingareacaption = '' then begin + dockingareacaption:= self.dockingareacaption; + end; + if item1 <> nil then begin + tdockpanelformmenuitem.create(result); +// fmenuitem:= tmenuitem.create(nil,nil); + end; + updatecaption(''); + end; + if item1 <> nil then begin + if int2 >= fpanellist.count then begin + int2:= fpanellist.count-1; + end; + if int2 > item1.count - 2 then begin + int2:= item1.count - 2; + end; + if int2 < 0 then begin + int2:= 0; + end; + item1.submenu.insert(int2,result.fmenuitem); + end; +end; + +procedure tdockpanelformcontroller.setmenu(const avalue: tcustommenu); +begin + setlinkedvar(avalue,tmsecomponent(fmenu)); +end; +{ +procedure tdockpanelformcontroller.checkstatfile( + const avalue: tstatfile; const ref: tstatfile); +begin + if (avalue <> nil) and (avalue = ref) then begin + raise exception.create(self.name+':Invalid statfile '+avalue.name+'.'); + end; +end; +} +procedure tdockpanelformcontroller.setstatfile(const avalue: tstatfile); +begin +// checkstatfile(avalue,fstatfileclient); + setstatfilevar(istatfile(self),avalue,fstatfile); +end; + +procedure tdockpanelformcontroller.dostatread(const reader: tstatreader); +begin + updatestat(reader); +end; + +procedure tdockpanelformcontroller.dostatwrite(const writer: tstatwriter); +begin + updatestat(writer); +end; + +procedure tdockpanelformcontroller.statreading; +begin + while high(fdynamiccomps) >= 0 do begin + fdynamiccomps[high(fdynamiccomps)].destroy(); + end; +end; + +procedure tdockpanelformcontroller.statread; +begin + //dummy +end; + +function tdockpanelformcontroller.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +procedure tdockpanelformcontroller.setstatfileclient(const avalue: tstatfile); +begin +// checkstatfile(avalue,fstatfile); + setlinkedvar(avalue,tmsecomponent(fstatfileclient)); +end; + +procedure tdockpanelformcontroller.updatewindowcaptions(const avalue: msestring); +var + po1: pdockpanelform; + int1: integer; +begin + with fpanellist do begin + po1:= pointer(datapo); + for int1:= 0 to count - 1 do begin + po1^.caption:= avalue; + inc(po1); + end; + end; +end; + +procedure tdockpanelformcontroller.setstatfileclients( + const avalue: tstatfilearrayprop); +begin + fstatfileclients.assign(avalue); +end; + +procedure tdockpanelformcontroller.removepanels; +begin + while fpanellist.count > 0 do begin + tobject(fpanellist.items[fpanellist.count-1]).free; + end; +end; + +function tdockpanelformcontroller.createdynamiccomp( + const aclassname: string): tmsecomponent; +var + cla1: tpersistentclass; +begin + result:= nil; + cla1:= getclass(aclassname); + if cla1.inheritsfrom(tmsecomponent) then begin + application.createdatamodule(msecomponentclassty(cla1),result); +// result:= msecomponentclassty(cla1).create(nil); + end; +end; + +function tdockpanelformcontroller.createdynamiccomp( + const aclass: msecomponentclassty): tmsecomponent; +begin + application.createdatamodule(aclass,result); + registerdynamiccomp(result); +end; + +function tdockpanelformcontroller.createdynamicwidget( + const aclass: widgetclassty): twidget; +begin + application.createform(aclass,result); + registerdynamiccomp(result); +end; + +procedure tdockpanelformcontroller.objectevent(const sender: tobject; + const event: objecteventty); +var + i1: int32; +begin + if event = oe_destroyed then begin + for i1:= high(fdynamiccomps) downto 0 do begin + if fdynamiccomps[i1] = sender then begin + deleteitem(pointerarty(fdynamiccomps),i1); + if canevent(tmethod(fonunregisterdynamiccomp)) then begin + fonunregisterdynamiccomp(self,tmsecomponent(sender)); + end; + break; + end; + end; + end; + inherited; +end; + +procedure tdockpanelformcontroller.registerdynamiccomp( + const acomp: tmsecomponent); +var + i1: int32; +begin + for i1:= 0 to high(fdynamiccomps) do begin + if fdynamiccomps[i1] = acomp then begin + exit; + end; + end; + setlength(fdynamiccomps,high(fdynamiccomps)+2); + fdynamiccomps[high(fdynamiccomps)]:= acomp; + ievent(acomp).link(ievent(self),ievent(acomp)); + if canevent(tmethod(fonregisterdynamiccomp)) then begin + fonregisterdynamiccomp(self,acomp); + end; +end; + +procedure tdockpanelformcontroller.unregisterdynamiccomp( + const acomp: tmsecomponent); +var + i1: int32; +begin + for i1:= high(fdynamiccomps) downto 0 do begin + if fdynamiccomps[i1] = acomp then begin + ievent(fdynamiccomps[i1]).unlink(ievent(self), + ievent(fdynamiccomps[i1])); + deleteitem(pointerarty(fdynamiccomps),i1); + if canevent(tmethod(fonunregisterdynamiccomp)) then begin + fonunregisterdynamiccomp(self,acomp); + end; + exit; + end; + end; +end; + +function tdockpanelformcontroller.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +{ tdockpanelformmenuitem } + +constructor tdockpanelformmenuitem.create(const apanel: tdockpanelform); +begin + inherited create(nil,nil); + fpanel:= apanel; + apanel.fmenuitem:= self; +end; + +destructor tdockpanelformmenuitem.destroy; +begin + if fpanel <> nil then begin + fpanel.fmenuitem:= nil; + end; + inherited; +end; + +{ tdockpanelform } + +constructor tdockpanelform.create(aowner: tcomponent); +begin + if aowner is tdockpanelformcontroller then begin + setlinkedvar(tmsecomponent(aowner),tmsecomponent(fcontroller)); + end; + inherited; +end; + +constructor tdockpanelform.create(aowner: tcomponent; load: boolean); +begin + if fdragdock = nil then begin +// fdragdock:= tpanelformdockcontroller.create(idockcontroller(self)); + fdragdock:= tpanelformdockcontroller.create(self); + end; + include(fmsecomponentstate,cs_ismodule); + fscrollbox:= tdockpanelformscrollbox.create(self); + inherited; +end; + +//constructor tdockpanelform.docreate(aowner: tcomponent); +procedure tdockpanelform.docreate(aowner: tcomponent); +begin + inherited; + visible:= false; + options:= defaultdockpaneloptions; + optionswidget:= defaultdockpaneloptionswidget; + { + createframe; + options:= (options - [fo_autoreadstat,fo_autowritestat]) + + [fo_globalshortcuts,fo_screencentered]; + optionswidget:= (optionswidget - [ow_destroywidgets]) + + [ow_mousefocus,ow_arrowfocusin,ow_arrowfocusout]; + dragdock.optionsdock:= defaultdockpaneloptionsdock; + frame.grip_options:= defaultdockpanelgripoptions; + } + size:= makesize(defaultdockpanelwidth,defaultdockpanelheight); + if fcontroller <> nil then begin + statfile:= fcontroller.statfileclient; + fcontroller.fpanellist.add(self); + end; +end; + +destructor tdockpanelform.destroy; +begin + if fcontroller <> nil then begin + with fcontroller do begin + if fpanellist <> nil then begin + fpanellist.remove(self); + end; + if (fmenuitem <> nil) then begin + if (fmenuitem.owner <> nil) and + not (csdestroying in fmenuitem.owner.componentstate) then begin + fmenuitem.parentmenu.submenu.delete(fmenuitem.index); + end + else begin + fmenuitem.fpanel:= nil; + end; + end; + end; + end; + inherited; +end; + +procedure tdockpanelform.updatecaption(acaption: msestring); +var + menucapt: msestring; +begin + if acaption = '' then begin + if fcontroller <> nil then begin + acaption:= fcontroller.caption; + end; + end; + if fmenuitem <> nil then begin + menucapt:= acaption; + with fmenuitem do begin + onexecute:= {$ifdef FPC}@{$endif}showexecute; + if fnameindex < 9 then begin + shortcut:= (ord(key_f1) or key_modctrl) + fnameindex; + if menucapt <> '' then begin + menucapt:= acaption + ' '; + end; + menucapt:= menucapt + '&' + inttostrmse(fnameindex+1); + end + else begin + shortcut:= 0; + end; + caption:= menucapt; + if (fcontroller <> nil) and + fcontroller.canevent(tmethod(fcontroller.fonupdatemenu)) then begin + fcontroller.fonupdatemenu(fcontroller,self,fmenuitem); + end; + if shortcut <> 0 then begin + acaption:= acaption + ' ('+encodeshortcutname(shortcut)+')'; + end; + end; + end + else begin + acaption:= acaption+' '+inttostrmse(fnameindex+1); + end; + if (fcontroller <> nil) and + fcontroller.canevent(tmethod(fcontroller.fonupdatecaption)) then begin + fcontroller.fonupdatecaption(fcontroller,self,acaption); + end; + dragdock.caption:= acaption; +end; + +procedure tdockpanelform.showexecute(const sender: tobject); +begin + activate; +end; + +function tdockpanelform.canclose(const newfocus: twidget): boolean; + + function containerempty: boolean; + var + int1: integer; + begin + result:= container.widgetcount = 0; + if not result then begin + for int1:= 0 to container.widgetcount - 1 do begin + if container.widgets[int1].visible then begin + exit; + end; + end; + end; + result:= true; + end; + +begin + result:= inherited canclose(newfocus); + { + if result and (newfocus = nil) and containerempty then begin + release; + end; + } +end; + +procedure tdockpanelform.doonclose; + function containerempty: boolean; + var + int1: integer; + begin + result:= container.widgetcount = 0; + if not result then begin + for int1:= 0 to container.widgetcount - 1 do begin + if container.widgets[int1].visible then begin + exit; + end; + end; + end; + result:= true; + end; +begin + inherited; + if containerempty and not (csdesigning in componentstate) then begin + release; + end; +end; + +procedure tdockpanelform.dodockcaptionchanged(const sender: tdockcontroller); +var + intf1: idocktarget; + mstr1: msestring; + int1: integer; + ar1: widgetarty; +begin + mstr1:= ''; + ar1:= sender.getitems; + for int1:= 0 to high(ar1) do begin + if ar1[int1].getcorbainterface(typeinfo(idocktarget),intf1) then begin + mstr1:= mstr1 + intf1.getdockcontroller.getdockcaption+','; + end; + end; + updatecaption(copy(mstr1,1,length(mstr1)-1)); //remove last comma +end; + +procedure tdockpanelform.dolayoutchanged(const sender: tdockcontroller); +begin + dodockcaptionchanged(sender); +end; + +{ +procedure tdockpanelform.dolayoutchanged(const sender: tdockcontroller); +var + intf1: idocktarget; + mstr1: msestring; + int1: integer; + ar1: widgetarty; +begin + mstr1:= ''; + ar1:= sender.getitems; + for int1:= 0 to high(ar1) do begin + if ar1[int1].getcorbainterface(typeinfo(idocktarget),intf1) then begin + mstr1:= mstr1 + intf1.getdockcontroller.getdockcaption+','; + end; + end; + updatecaption(copy(mstr1,1,length(mstr1)-1)); //remove last comma +end; +} + +class function tdockpanelform.hasresource: boolean; +begin + result:= self <> tdockpanelform; +end; + +class function tdockpanelform.getmoduleclassname: string; +begin + result:= 'tdockpanelform'; +end; + +procedure tdockpanelform.setdockingareacaption(const avalue: msestring); +begin + with tdockpanelformscrollbox(fscrollbox) do begin + fdockingareacaption:= avalue; + invalidate; + end; +end; + +function tdockpanelform.getdockingareacaption: msestring; +begin + result:= tdockpanelformscrollbox(fscrollbox).fdockingareacaption; +end; + +{ tpanelformdockcontroller } + +constructor tpanelformdockcontroller.create(const aowner: tcustomdockform); +//constructor tpanelformdockcontroller.create(aintf: idockcontroller); +begin + inherited; + foptionsdock:= defaultoptionsdock; +end; + +{ tdockpanelformscrollbox } + +procedure tdockpanelformscrollbox.dopaintbackground(const canvas: tcanvas); +begin + inherited; + if fdockingareacaption <> '' then begin + paintdockingareacaption(canvas,self,fdockingareacaption); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/msedragglob.pas b/mseide-msegui/lib/common/widgets/msedragglob.pas new file mode 100644 index 0000000..014163f --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msedragglob.pas @@ -0,0 +1,131 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msedragglob; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseglob,msegraphutils,mseguiglob,mseevent; + +type + dragobjstatety = (dos_dropped,dos_sysdnd,dos_write,dos_sysdroppending); + dragobjstatesty = set of dragobjstatety; + + pdragobject = ^tdragobject; + tdragobject = class(tnullinterfacedobject) + private + fpickpos: pointty; + fdroppos: pointty; + function getdropped: boolean; + protected + finstancepo: pdragobject; + fsender: tobject; + fstate: dragobjstatesty; + fsysdndintf: isysdnd; + feventintf: ievent; + factions: dndactionsty; + function checksysdnd(const aaction: sysdndactionty; + const arect: rectty): boolean; + //isysdnd + function geteventintf: ievent; + public + constructor create(const asender: tobject; var instance: tdragobject; + const apickpos: pointty; //clientorigin + const aactions: dndactionsty = []); + destructor destroy; override; + function sender: tobject; + procedure acepted(const apos: pointty); virtual; //screenorigin + procedure refused(const apos: pointty); virtual; //screenorigin + property pickpos: pointty read fpickpos write fpickpos; //clientorigin + property droppos: pointty read fdroppos write fdroppos; //screenorigin + property state: dragobjstatesty read fstate; + property dropped: boolean read getdropped; + property actions: dndactionsty read factions write factions; + end; + + drageventkindty = (dek_begin,dek_check,dek_drop,dek_end, + dek_leavesysdnd,dek_leavewidget); + + draginfoty = record + eventkind: drageventkindty; + pos: pointty; //origin = clientrect.pos + pickpos: pointty; //origin = screenorigin + clientpickpos: pointty; //origin = clientrect.pos + dragobjectpo: pdragobject; + accept: boolean; + end; + +implementation + +uses + mseapplication,msegui,mseguiintf; +type + tguiapplication1 = class(tguiapplication); + +{ tdragobject } + +constructor tdragobject.create(const asender: tobject; var instance: tdragobject; + const apickpos: pointty; + const aactions: dndactionsty); +begin + fsender:= asender; + finstancepo:= @instance; + if finstancepo <> nil then begin + instance.Free; + instance:= self; + end; + fpickpos:= apickpos; + factions:= aactions; + tguiapplication1(application).dragstarted; +end; + +destructor tdragobject.destroy; +begin + checksysdnd(sdnda_destroyed,nullrect); + if finstancepo <> nil then begin + finstancepo^:= nil; + end; + inherited; +end; + +function tdragobject.getdropped: boolean; +begin + result:= dos_dropped in fstate; +end; + +procedure tdragobject.acepted(const apos: pointty); +begin + //dummy +end; + +procedure tdragobject.refused(const apos: pointty); +begin + //dummy +end; + +function tdragobject.sender: tobject; +begin + result:= fsender; +end; + +function tdragobject.checksysdnd(const aaction: sysdndactionty; + const arect: rectty): boolean; +begin + result:= false; + if dos_sysdnd in fstate then begin + gui_sysdnd(aaction,fsysdndintf,arect,result); + end; +end; + +function tdragobject.geteventintf: ievent; +begin + result:= feventintf; +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/mseeditglob.pas b/mseide-msegui/lib/common/widgets/mseeditglob.pas new file mode 100644 index 0000000..66642b4 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/mseeditglob.pas @@ -0,0 +1,273 @@ +{ MSEgui Copyright (c) 1999-2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseeditglob; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface +uses + mseglob,mseguiglob,{msegui,}msetypes,{msegraphics,}msegraphutils, + classes,mclasses; + +type + //used in MSEifi + optioneditty = (oe_readonly,oe_undoonesc, + oe_closequery,oe_checkmrcancel, + oe_nogray, + oe_linebreak, + // if oe_shiftreturn -> shift key_return inserts linebreak + // else -> key_return inserts linebreak + oe_shiftreturn, + oe_forcereturncheckvalue, + //call checkvalue unconditionally by key_return + oe_eatreturn, + // oe_returntaborder, //key_return selects next widget in taborder + //moved to twidget.optionswidget ow_keyreturntaborder + oe_resetselectonexit, + + //same layout as strincoleditoptionty + oe_exitoncursor, + oe_nofirstarrownavig, + oe_endonenter, + oe_homeonenter, + oe_autoselect, //selectall bei widget enter + oe_autoselectonfirstclick, + oe_caretonreadonly, + oe_focusrectonreadonly, + oe_trimright, + oe_trimleft, + oe_uppercase, + oe_lowercase, + oe_hintclippedtext, + oe_locate, + oe_casesensitive, + + oe_notnull, + oe_null, //accept empty value independent of min setting + //in trealedit + oe_directdbnullcheck, //check null by canclose() + oe_savevalue,oe_savestate,oe_saveoptions, //deprecated, + oe_checkvaluepaststatread //moved to optionsedit1ty + +// oe_autopopupmenu, //deprecated, moved to optionsedit1ty +// oe_keyexecute + ); + optionseditty = set of optioneditty; +const + deprecatedoptionsedit = [oe_savevalue,oe_savestate, + oe_saveoptions,oe_checkvaluepaststatread]; + invisibleoptionsedit = [ord(oe_savevalue),ord(oe_savestate), + ord(oe_saveoptions),ord(oe_checkvaluepaststatread)]; + +type + optionedit1ty = (oe1_noselectall,oe1_multiline, + oe1_autopopupmenu, + oe1_keyexecute, //alt+down-key starts dialog + oe1_readonlydialog, + oe1_savevalue,oe1_savestate,oe1_saveoptions, + oe1_checkvalueafterstatread, + oe1_sendchangeeventbycheckvalue, + oe1_nocellpaint, //draw widget image instead of cell image + //for titemedit value edits + oe1_thumbtrack //for tcoloredit + ); + optionsedit1ty = set of optionedit1ty; + + dataeditstatety = (des_edited,des_emptytext,des_grayed, + {des_isdataedit,}des_isdb,des_dbnull,des_dbnullcheck, + des_actualcursor,des_updating,des_valueread, + des_statreading, + des_disabled, //for tdatabutton + des_updatelayout,des_editing{,des_dropdowntextsetting}); + dataeditstatesty = set of dataeditstatety; + + editactionty = (ea_none,ea_beforechange,ea_textchanged,ea_resetemptytext, + ea_textedited,ea_undone, + ea_textentered,ea_indexmoved,{ea_selectindexmoved,} + ea_textsizechanged, + ea_delchar,ea_undo, + {ea_selectstart,ea_selectend,}ea_clearselection, + ea_deleteselection,ea_copyselection,ea_pasteselection, + ea_selectall,ea_exit,ea_caretupdating); + + editactionstatety = (eas_shift,eas_delete); + editactionstatesty = set of editactionstatety; + + editnotificationinfoty = record + state: editactionstatesty; + case action: editactionty of + ea_exit,ea_delchar:( + dir: graphicdirectionty; + ); + ea_caretupdating:( + caretrect: rectty; + showrect: rectty; + ); + ea_textsizechanged:( + sizebefore: sizety; + newsize: sizety; + ); + ea_pasteselection,ea_copyselection:( + bufferkind: clipboardbufferty; + ); + end; + + idataeditcontroller = interface (inullinterface) + procedure dokeydown(var info: keyeventinfoty); + procedure updatereadonlystate; + procedure internalcreateframe; + procedure mouseevent(var info: mouseeventinfoty); + procedure domousewheelevent(var info: mousewheeleventinfoty); + procedure editnotification(var info: editnotificationinfoty); + end; + +const + defaultoptionsedit = [oe_undoonesc,oe_closequery,oe_exitoncursor, + oe_focusrectonreadonly, + oe_shiftreturn,oe_eatreturn, + oe_autoselect,oe_endonenter, + oe_autoselectonfirstclick, + oe_resetselectonexit, + oe_checkmrcancel]; + defaultoptionsedit1 = [oe1_autopopupmenu,oe1_keyexecute, + oe1_checkvalueafterstatread,oe1_savevalue,oe1_savestate]; + + nullcoord: gridcoordty = (col: 0; row: 0); + invalidcell: gridcoordty = (col: invalidaxis; row: invalidaxis); + bigcoord: gridcoordty = (col: bigint; row: bigint); + +function makegridcoord(col: integer; row: integer): gridcoordty; {$ifdef FPC}inline;{$endif} + {$ifdef FPC}inline;{$endif} +function mgc(col: integer; row: integer): gridcoordty; {$ifdef FPC}inline;{$endif} + {$ifdef FPC}inline;{$endif} +function makegridsize(colcount: integer; rowcount: integer): gridsizety; + {$ifdef FPC}inline;{$endif} +function mgs(colcount: integer; rowcount: integer): gridsizety; + {$ifdef FPC}inline;{$endif} +function makegridrect(const pos: gridcoordty; const size: gridsizety): gridrectty; overload; + {$ifdef FPC}inline;{$endif} +function mgr(const pos: gridcoordty; const size: gridsizety): gridrectty; overload; + {$ifdef FPC}inline;{$endif} +function makegridrect(const start,stop: gridcoordty): gridrectty; overload; + //normalized rect, includes start and stop +function mgr(const start,stop: gridcoordty): gridrectty; overload; + //normalized rect, includes start and stop + +function gridcoordisequal(const a,b: gridcoordty): boolean; + +procedure transferoptionsedit(const sender: tcomponent; + const source: optionseditty; var dest: optionseditty; + var dest1: optionsedit1ty); + //move deprecated flags + +implementation +uses + msebits; + +function makegridcoord(col: integer; row: integer): gridcoordty; +begin + result.col:= col; + result.row:= row; +end; + +function mgc(col: integer; row: integer): gridcoordty; +begin + result.col:= col; + result.row:= row; +end; + +function gridcoordisequal(const a,b: gridcoordty): boolean; +begin + result:= (a.col = b.col) and (a.row = b.row); +end; + +function makegridsize(colcount: integer; rowcount: integer): gridsizety; +begin + result.colcount:= colcount; + result.rowcount:= rowcount; +end; + +function mgs(colcount: integer; rowcount: integer): gridsizety; +begin + result.colcount:= colcount; + result.rowcount:= rowcount; +end; + +function makegridrect(const pos: gridcoordty; const size: gridsizety): gridrectty; overload; +begin + result.pos:= pos; + result.size:= size; +end; + +function mgr(const pos: gridcoordty; const size: gridsizety): gridrectty; overload; +begin + result.pos:= pos; + result.size:= size; +end; + +function makegridrect(const start,stop: gridcoordty): gridrectty; overload; +begin + if stop.col >= start.col then begin + result.col:= start.col; + result.colcount:= stop.col - start.col + 1; + end + else begin + result.col:= stop.col; + result.colcount:= start.col - stop.col + 1; + end; + if stop.row >= start.row then begin + result.row:= start.row; + result.rowcount:= stop.row - start.row + 1; + end + else begin + result.row:= stop.row; + result.rowcount:= start.row - stop.row + 1; + end; +end; + +function mgr(const start,stop: gridcoordty): gridrectty; overload; +begin + if stop.col >= start.col then begin + result.col:= start.col; + result.colcount:= stop.col - start.col + 1; + end + else begin + result.col:= stop.col; + result.colcount:= start.col - stop.col + 1; + end; + if stop.row >= start.row then begin + result.row:= start.row; + result.rowcount:= stop.row - start.row + 1; + end + else begin + result.row:= stop.row; + result.rowcount:= start.row - stop.row + 1; + end; +end; + +procedure transferoptionsedit(const sender: tcomponent; + const source: optionseditty; var dest: optionseditty; + var dest1: optionsedit1ty); +begin + dest:= source - deprecatedoptionsedit; + if (csreading in sender.componentstate) and + (source * deprecatedoptionsedit <> []) then begin + updatebit(longword(dest1),ord(oe1_savevalue), + oe_savevalue in source); + updatebit(longword(dest1),ord(oe1_savestate), + oe_savestate in source); + updatebit(longword(dest1),ord(oe1_saveoptions), + oe_saveoptions in source); + updatebit(longword(dest1),ord(oe1_checkvalueafterstatread), + oe_checkvaluepaststatread in source); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/mseforms.pas b/mseide-msegui/lib/common/widgets/mseforms.pas new file mode 100644 index 0000000..e681cea --- /dev/null +++ b/mseide-msegui/lib/common/widgets/mseforms.pas @@ -0,0 +1,3308 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseforms; +{$ifdef FPC} + {$mode objfpc}{$h+}{$interfaces corba} +{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} + +interface +uses + msewidgets,msemenus,msegraphics,mseapplication,msegui,msegraphutils,mseevent, + msetypes,msestrings,mseglob,mseguiglob,mseguiintf,msedragglob,msepointer, + msemenuwidgets,msestat,msestatfile,mseclasses,classes,mclasses,msedock, + msesimplewidgets,msebitmap,typinfo,msesplitter,mseobjectpicker,msetabs, + mseassistiveclient + {$ifdef mse_with_ifi},mseifiglob,mseificompglob,mseificomp{$endif}; + +{$if defined(FPC) and (fpc_fullversion >= 020403)} + {$define mse_fpc_2_4_3} +{$ifend} + +type + formoptionty = (fo_main,fo_terminateonclose,fo_freeonclose, + fo_windowclosecancel, + fo_defaultpos,fo_screencentered,fo_screencenteredvirt, + fo_transientforcentered,fo_mainwindowcentered, + fo_modal,fo_createmodal, + fo_minimized,fo_maximized,fo_fullscreen,fo_fullscreenvirt, + fo_closeonesc,fo_cancelonesc,fo_closeonenter,fo_closeonf10, + fo_keycloseifwinonly,fo_nowindowclose, + fo_globalshortcuts,fo_localshortcuts, + fo_autoreadstat,fo_delayedreadstat,fo_autowritestat, + fo_savepos,fo_savezorder,fo_savestate); + formoptionsty = set of formoptionty; + +const + defaultformoptions = [fo_autoreadstat,fo_autowritestat, + fo_savepos,fo_savezorder,fo_savestate]; + defaultmainformoptions = defaultformoptions + [fo_main,fo_terminateonclose]; + defaultmainformoptionswindow = [wo_groupleader,wo_taskbar]; + + defaultformwidgetoptions = (defaultoptionswidgetmousewheel - + [{ow_mousefocus}{,ow_tabfocus}]) + [ow_subfocus,ow_hinton]; + defaultcontaineroptionswidget = defaultoptionswidgetmousewheel + + [ow_subfocus,ow_mousetransparent]; + +type + tcustommseform = class; + closequeryeventty = procedure(const sender: tcustommseform; + var amodalresult: modalresultty) of object; + + tformscrollbox = class(tscrollingwidgetnwr) + //for internal use only + private + procedure readdummy(reader: treader); + procedure writedummy(writer: twriter); + procedure readbounds(reader: treader); + procedure writebounds(writer: twriter); + protected + fboundsread: boolean; + procedure setoptionswidget(const avalue: optionswidgetty); override; + procedure defineproperties(filer: tfiler); override; + procedure clientrectchanged; override; + procedure widgetregionchanged(const sender: twidget); override; + procedure docheckautosize; + function getassistiveflags(): assistiveflagsty override; + public + constructor create(aowner: tcustommseform); reintroduce; + procedure dolayout(const sender: twidget); override; + published + property onscroll; + property onscrolled; + property onresize; + property onfontheightdelta; + property onlayout; + property oncalcminscrollsize; + property onchildmouseevent; + property onmouseevent; + property onclientmouseevent; + property onmousewheelevent; + property onbeforepaint; + property onpaint; + property onafterpaint; + property optionswidget default defaultcontaineroptionswidget; + end; + + syseventeventty = procedure(const sender: tcustommseform; + var aevent: syseventty; var handled: boolean) of object; + + formstatety = (fos_statreading); + formstatesty = set of formstatety; + optionsizingty = (osi_left,osi_top,osi_right,osi_bottom); + optionssizingty = set of optionsizingty; + + tcustommseform = class(tcustomeventwidget,istatfile,idockcontroller + {$ifdef mse_with_ifi},iififormlink{$endif}) + private + foncreate: notifyeventty; + foncreated: notifyeventty; + fonloaded: notifyeventty; + fondestroyed: notifyeventty; + foneventloopstart: notifyeventty; + fondestroy: notifyeventty; + fonbeforeclosequery: closequeryeventty; + fonclosequery: closequeryeventty; + fonclose: notifyeventty; + fonidle: idleeventty; + fonterminatequery: terminatequeryeventty; + fonterminated: notifyeventty; + fmainmenu: tmainmenu; + foptions: formoptionsty; + fstatfile: tstatfile; + fcaption: msestring; + fmainmenuwidget: tframemenuwidget; + foptionswindow: windowoptionsty; + fonstatread: statreadeventty; + fonstatafterread: notifyeventty; + fonstatbeforeread: notifyeventty; + fonstatafterwrite: notifyeventty; + fonstatbeforewrite: notifyeventty; + fonstatupdate: statupdateeventty; + fstatvarname: msestring; + fonstatwrite: statwriteeventty; + fonwidgetactivechanged: widgetchangeeventty; + fonwindowactivechanged: windowchangeeventty; + fonwindowdestroyed: windoweventty; + fonapplicationactivechanged: booleaneventty; + fonfontheightdelta: fontheightdeltaeventty; + ficon: tmaskedbitmap; + ficonchanging: integer; + fonsysevent: syseventeventty; + fonsyswindowevent: syseventeventty; + fonapplicationevent: applicationeventeventty; + factivatortarget: tactivator; + fstatpriority: integer; + ftaborderoverride: ttaborderoverride; +{$ifdef mse_with_ifi} + fifilink: tififormlinkcomp; + fwindowopacity: realty; + function getifilinkkind: ptypeinfo; + procedure setifilink(const avalue: tififormlinkcomp); +{$endif} + function getonlayout: notifyeventty; + procedure setonlayout(const avalue: notifyeventty); + procedure setmainmenu(const Value: tmainmenu); + procedure updatemainmenutemplates; + procedure setoptions(const Value: formoptionsty); + procedure setoptionswindow(const Value: windowoptionsty); + procedure setstatfile(const avalue: tstatfile); + procedure setscrollbox(const avalue: tformscrollbox); + function getonafterpaint: painteventty; + function getonbeforepaint: painteventty; + function getonpaint: painteventty; + procedure setonafterpaint(const Value: painteventty); + procedure setonbeforepaint(const Value: painteventty); + procedure setonpaint(const Value: painteventty); + procedure seticon(const avalue: tmaskedbitmap); + procedure registerhandlers; + procedure unregisterhandlers; + procedure setonsysevent(const avalue: syseventeventty); + procedure setonsyswindowevent(const avalue: syseventeventty); + procedure setonapplicationevent(const avalue: applicationeventeventty); + procedure readonchildscaled(reader: treader); + procedure setactivatortarget(const avalue: tactivator); + procedure settaborderoverride(const avalue: ttaborderoverride); + procedure setwindowopacity(const avalue: realty); + protected + fformstate: formstatesty; + fscrollbox: tformscrollbox; //needed to distinguish between scrolled and + //unscrolled (mainmenu...) widgets + function internalgeticon(): tmaskedbitmap; virtual; + procedure iconchanged(const sender: tobject); + procedure aftercreate; virtual; + function createmainmenuwidget: tframemenuwidget; virtual; + function ismainwindow(): boolean virtual; + procedure updateoptions; virtual; + function getoptions: formoptionsty; virtual; + procedure updatescrollboxrect; + procedure internalsetwidgetrect(Value: rectty; + const windowevent: boolean); override; + procedure clientrectchanged; override; + procedure rootchanged(const aflags: rootchangeflagsty) override; + procedure setparentwidget(const Value: twidget); override; + procedure updatewindowinfo(var info: windowinfoty); override; + function isgroupleader: boolean; override; + + procedure readstate(reader: treader); override; + procedure defineproperties(filer: tfiler); override; + procedure dooncreate; virtual; + procedure doafterload; override; + procedure loaded; override; + procedure autoreadstat; + procedure setoptionswidget(const avalue: optionswidgetty); override; + function nexttaborderoverride(const sender: twidget; + const down: boolean): twidget override; + + function getcaption: msestring; + procedure setcaption(const Value: msestring); virtual; + procedure getchildren(proc: tgetchildproc; root: tcomponent); override; + procedure doeventloopstart; virtual; + procedure doterminated(const sender: tobject); virtual; + procedure doterminatequery(var terminate: boolean); virtual; + procedure doidle(var again: boolean); virtual; + procedure dowidgetactivechanged(const oldwidget,newwidget: twidget); virtual; + procedure dowindowactivechanged(const oldwindow,newwindow: twindow); virtual; + procedure dowindowdestroyed(const awindow: twindow); virtual; + procedure doapplicationactivechanged(const avalue: boolean); virtual; + procedure dosysevent(const awindow: winidty; var aevent: syseventty; + var handled: boolean); virtual; + procedure doapplicationevent(var aevent: tmseevent; + var handled: boolean) virtual; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + procedure receiveevent(const event: tobjectevent); override; + procedure dokeydown(var info: keyeventinfoty); override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; + procedure windowcreated; override; + procedure dofontheightdelta(var delta: integer); override; + procedure widgetregionchanged(const sender: twidget); override; + + function getcontainer: twidget; override; + function getchildwidgets(const index: integer): twidget; override; + procedure getautopaintsize(var asize: sizety); override; + + procedure dostatread1(const reader: tstatreader); virtual; + procedure dostatwrite1(const writer: tstatwriter); virtual; + //istatfile + procedure dostatread(const reader: tstatreader); virtual; + procedure dostatwrite(const writer: tstatwriter); virtual; + procedure statreading; virtual; + procedure statread; virtual; + function getstatvarname: msestring; + function getstatpriority: integer; + function getwindowcaption: msestring; virtual; + //idockcontroller + function getchildicon: tmaskedbitmap; virtual; + function checkdock(var info: draginfoty): boolean; + function getbuttonrects(const index: dockbuttonrectty): rectty; + function getplacementrect: rectty; + function getminimizedsize(out apos: captionposty): sizety; + procedure dolayoutchanged(const sender: tdockcontroller); virtual; + procedure dodockcaptionchanged(const sender: tdockcontroller); virtual; + + procedure updatelayout(const sender: twidget); virtual; + //called from scrollbox.dolayout + //iassistiveclient + function getassistivecaption(): msestring override; + //iificommand + {$ifdef mse_with_ifi} + procedure executeificommand(var acommand: ificommandcodety); override; + //iififormlink + procedure setmodalresult(const avalue: modalresultty); + {$endif} + + procedure docreate(aowner: tcomponent); virtual; + public + constructor create(aowner: tcomponent); overload; override; + constructor create(aowner: tcomponent; load: boolean); reintroduce; overload; virtual; + destructor destroy; override; + procedure afterconstruction; override; + procedure freeinstance override; + procedure reload(const callafterload: boolean = false); + procedure writestate(writer: twriter); override; + + procedure insertwidget(const widget: twidget; const apos: pointty); override; + procedure dolayout(const sender: twidget); override; + function childrencount: integer; override; + + procedure beforeclosequery(var amodalresult: modalresultty); override; + procedure doonclose; virtual; + function canclose(const newfocus: twidget): boolean; override; + function close(const amodalresult: modalresultty = mr_windowclosed): boolean; + //true if ok + procedure beforedestruction; override; + property optionswidget default defaultformwidgetoptions; + property optionswindow: windowoptionsty read foptionswindow + write setoptionswindow default []; + property mainmenu: tmainmenu read fmainmenu write setmainmenu; + property font: twidgetfont read getfont write setfont stored isfontstored; + property fontempty: twidgetfontempty read getfontempty + write setfontempty stored isfontemptystored; + property options: formoptionsty read getoptions write setoptions + default defaultformoptions; + + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read getstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + + property caption: msestring read getcaption write setcaption; + property icon: tmaskedbitmap read ficon write seticon; + property windowopacity: realty read fwindowopacity write setwindowopacity; + //emptyreal -> undefined, 0.0 -> trasparent, 1.0 -> opaque + //default = emptyreal + + property oncreate: notifyeventty read foncreate write foncreate; + property oncreated: notifyeventty read foncreated write foncreated; + property onloaded: notifyeventty read fonloaded write fonloaded; + property oneventloopstart: notifyeventty read foneventloopstart + write foneventloopstart; + property ondestroy: notifyeventty read fondestroy write fondestroy; + property ondestroyed: notifyeventty read fondestroyed write fondestroyed; + property onbeforeclosequery: closequeryeventty read fonbeforeclosequery + write fonbeforeclosequery; + property onclosequery: closequeryeventty read fonclosequery + write fonclosequery; + property onclose: notifyeventty read fonclose write fonclose; + property onidle: idleeventty read fonidle write fonidle; + property onterminatequery: terminatequeryeventty read fonterminatequery + write fonterminatequery; + property onterminated: notifyeventty read fonterminated + write fonterminated; + + property onbeforepaint: painteventty read getonbeforepaint + write setonbeforepaint; + property onpaint: painteventty read getonpaint write setonpaint; + property onafterpaint: painteventty read getonafterpaint + write setonafterpaint; + + property onstatupdate: statupdateeventty read fonstatupdate + write fonstatupdate; + property onstatread: statreadeventty read fonstatread write fonstatread; + property onstatbeforeread: notifyeventty read fonstatbeforeread + write fonstatbeforeread; + property onstatafterread: notifyeventty read fonstatafterread + write fonstatafterread; + property onstatwrite: statwriteeventty read fonstatwrite write fonstatwrite; + property onstatbeforewrite: notifyeventty read fonstatbeforewrite + write fonstatbeforewrite; + property onstatafterwrite: notifyeventty read fonstatafterwrite + write fonstatafterwrite; + + property onwidgetactivechanged: widgetchangeeventty + read fonwidgetactivechanged write fonwidgetactivechanged; + property onwindowactivechanged: windowchangeeventty + read fonwindowactivechanged write fonwindowactivechanged; + property onwindowdestroyed: windoweventty read fonwindowdestroyed + write fonwindowdestroyed; + property onapplicationactivechanged: booleaneventty + read fonapplicationactivechanged write fonapplicationactivechanged; + + property onfontheightdelta: fontheightdeltaeventty read fonfontheightdelta + write fonfontheightdelta; + property onlayout: notifyeventty read getonlayout write setonlayout; + property onsysevent: syseventeventty read fonsysevent write setonsysevent; + property onsyswindowevent: syseventeventty read fonsyswindowevent + write setonsyswindowevent; + property onapplicationevent: applicationeventeventty + read fonapplicationevent write setonapplicationevent; + published + property container: tformscrollbox read fscrollbox write setscrollbox; +{$ifdef mse_with_ifi} + property ifilink: tififormlinkcomp read fifilink write setifilink; +{$endif} + property activatortarget: tactivator read factivatortarget + write setactivatortarget; + property taborderoverride: ttaborderoverride read ftaborderoverride + write settaborderoverride; + property onshortcut; + end; + + custommseformclassty = class of tcustommseform; + + tmseformwidget = class(tcustommseform) + published + property optionswidget; + property optionsskin; + property optionswindow; + property mainmenu; + property color; + property font; + property fontempty; + property options; + property statfile; + property statvarname; + property statpriority; + property caption; + property icon; + property windowopacity; + + property oncreate; + property oncreated; + property onloaded; + property oneventloopstart; + property ondestroy; + property ondestroyed; + property onbeforeclosequery; + property onclosequery; + property onclose; + property onidle; + property onwidgetactivechanged; + property onwindowactivechanged; + property onwindowdestroyed; + property onapplicationactivechanged; + property onterminatequery; + property onterminated; + + property onmouseevent; + property onclientmouseevent; + property onchildmouseevent; + property onmousewheelevent; + property onkeydown; + property onkeyup; + property onshortcut; + + property onbeforepaint; + property onpaint; + property onafterpaint; + + property onmove; + property onresize; + property onshow; + property onactivate; + property onenter; + property onexit; + property onfocusedwidgetchanged; + property ondeactivate; + property onhide; + property onevent; + property oncomponentevent; + property onasyncevent; + + property onstatupdate; + property onstatread; + property onstatbeforeread; + property onstatafterread; + property onstatwrite; + property onstatbeforewrite; + property onstatafterwrite; + + property onfontheightdelta; + property onlayout; + + property onsysevent; + property onsyswindowevent; + property onapplicationevent; + end; + + tmseform = class(tmseformwidget) + protected + class function getmoduleclassname: string; override; + class function hasresource: boolean; override; + public + constructor create(aowner: tcomponent; load: boolean); override; + end; + + tmainform = class(tmseform) + protected + class function getmoduleclassname: string; override; + class function hasresource: boolean; override; + procedure aftercreate; override; + public + published + property options default defaultmainformoptions; + property optionswindow default defaultmainformoptionswindow; + end; + + mainformclassty = class of tmainform; + tcustomdockform = class; + + optiondockformty = (odf_main,odf_childicons,odf_mainchildicon,odf_maintaskbar, + odf_mainmainwindow); //is mainwindow if it contains + //an odf_main dock + optionsdockformty = set of optiondockformty; + +const + defaultoptionsdockform = [odf_childicons,odf_mainchildicon,odf_maintaskbar, + odf_mainmainwindow]; + +type + tformdockcontroller = class(tnochildrendockcontroller) + private + procedure setoptionsdockform(const avalue: optionsdockformty); + protected + fowner: tcustomdockform; + foptionsdockform: optionsdockformty; + function hasmain(): boolean; + procedure setoptionsdock(const avalue: optionsdockty); override; + procedure dolayoutchanged(); override; + procedure childstatechanged(const sender: twidget; + const newstate,oldstate: widgetstatesty); override; + public + constructor create(const aowner: tcustomdockform); + function childicon(): tmaskedbitmap override; + published + property optionsdockform: optionsdockformty read foptionsdockform + write setoptionsdockform default defaultoptionsdockform; + end; + + tcustomdockform = class(tcustommseform,idocktarget) + private + fdockingareacaption: msestring; + function getdockcontroller: tdockcontroller; + procedure setdragdock(const Value: tformdockcontroller); + function getframe: tgripframe; + procedure setframe(const avalue: tgripframe); + procedure setdockingareacaption(const avalue: msestring); + protected + fdragdock: tformdockcontroller; + fhasdocktaskbaricon: boolean; + function ismainwindow(): boolean override; + function needsdocktaskbaricon(): boolean; + procedure updatewindowinfo(var info: windowinfoty) override; + procedure internalcreateframe; override; + function internalgeticon(): tmaskedbitmap; override; + procedure updateoptions; override; + function getoptions: formoptionsty; override; + procedure statreading; override; + procedure statread; override; + procedure dostatread1(const reader: tstatreader); override; + procedure dostatwrite1(const writer: tstatwriter); override; +// procedure dokeydown(var info: keyeventinfoty) override; + procedure childmouseevent(const sender: twidget; + var info: mouseeventinfoty); override; + procedure statechanged; override; + procedure poschanged; override; + procedure activechanged; override; + procedure doactivate; override; + procedure parentchanged; override; + function getwindowcaption: msestring; override; + procedure dolayoutchanged(const sender: tdockcontroller); override; + procedure checkdockicon(); + function getchildicon(): tmaskedbitmap; override; + procedure loaded(); override; + procedure doenter(); override; + procedure doexit(); override; + public + constructor create(aowner: tcomponent; load: boolean); override; + destructor destroy(); override; + procedure activate(const abringtofront: boolean = true; + const aforce: boolean = false); override; + function canfocus: boolean; override; + procedure dragevent(var info: draginfoty); override; + property dockingareacaption: msestring read fdockingareacaption + write setdockingareacaption; + published + property dragdock: tformdockcontroller read fdragdock write setdragdock; + property frame: tgripframe read getframe write setframe; + end; + + tdockformwidget = class(tcustomdockform) + published + property optionswidget; + property optionsskin; + property optionswindow; + property mainmenu; + property color; + property font; + property fontempty; + property options; + property statfile; + property statvarname; + property statpriority; + property caption; + property icon; + property dockingareacaption; + + property oncreate; + property oncreated; + property onloaded; + property oneventloopstart; + property ondestroy; + property ondestroyed; + property onbeforeclosequery; + property onclosequery; + property onclose; + property onidle; + property onwidgetactivechanged; + property onwindowactivechanged; + property onwindowdestroyed; + property onapplicationactivechanged; + property onterminatequery; + property onterminated; + + property onmouseevent; + property onclientmouseevent; + property onchildmouseevent; + property onmousewheelevent; + property onkeydown; + property onkeyup; + property onshortcut; + + property onbeforepaint; + property onpaint; + property onafterpaint; + + property onmove; + property onresize; + property onshow; + property onactivate; + property onenter; + property onexit; + property onfocusedwidgetchanged; + property ondeactivate; + property onhide; + property onevent; + property oncomponentevent; + property onasyncevent; + + property onstatupdate; + property onstatread; + property onstatbeforeread; + property onstatafterread; + property onstatwrite; + property onstatbeforewrite; + property onstatafterwrite; + + property onfontheightdelta; + property onlayout; + + property onsysevent; + property onsyswindowevent; + end; + + tdockform = class(tdockformwidget) + protected + class function getmoduleclassname: string; override; + class function hasresource: boolean; override; + public + constructor create(aowner: tcomponent; load: boolean); override; + end; + + tdockformscrollbox = class(tformscrollbox,idocktarget) + protected + procedure clientrectchanged; override; + procedure widgetregionchanged(const sender: twidget); override; + procedure dopaintforeground(const acanvas: tcanvas); override; + function getdockcontroller: tdockcontroller; + procedure mouseevent(var info: mouseeventinfoty); override; + procedure dopaintbackground(const canvas: tcanvas); override; + public + constructor create(aowner: tcustomdockform); reintroduce; + end; + + tsubform = class(tlayouter) + protected + class function getmoduleclassname: string; override; + class function hasresource: boolean; override; + procedure getchildren(proc: tgetchildproc; root: tcomponent); override; + public + constructor create(aowner: tcomponent); overload; override; + constructor create(aowner: tcomponent; load: boolean); + reintroduce; overload; virtual; + published + property onloaded; + end; + + subformclassty = class of tsubform; + + tscrollboxform = class(tscrollbox) + protected + class function getmoduleclassname: string; override; + class function hasresource: boolean; override; + procedure getchildren(proc: tgetchildproc; root: tcomponent); override; + public + constructor create(aowner: tcomponent); overload; override; + constructor create(aowner: tcomponent; load: boolean); + reintroduce; overload; virtual; + end; + + scrollboxformclassty = class of tscrollboxform; + + ttabformfonttab = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + ttabformfontactivetab = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + ttabform = class(tmseform,itabpage,iimagelistinfo) + private + ftabwidget: tcustomtabwidget; + fimagelist: timagelist; + fimagenr: integer; + fimagenrdisabled: integer; + fcolortab,fcoloractivetab: colorty; + ffacetab,ffaceactivetab: tfacecomp; + ftabhint: msestring; + ftabnoface: boolean; + fonselect: notifyeventty; + fondeselect: notifyeventty; + finvisible: boolean; + ffonttab: ttabformfonttab; + ffontactivetab: ttabformfontactivetab; + procedure settabwidget(const value: tcustomtabwidget); + function gettabwidget: tcustomtabwidget; + function getcolortab: colorty; + procedure setcolortab(const avalue: colorty); + function getcoloractivetab: colorty; + procedure setcoloractivetab(const avalue: colorty); + function gettabindex: integer; + procedure settabindex(const avalue: integer); + function gettabhint: msestring; + procedure settabhint(const avalue: msestring); + function gettabnoface: boolean; + procedure settabnoface(const avalue: boolean); + function getimagelist: timagelist; + procedure setimagelist(const avalue: timagelist); + function getimagenr: imagenrty; + procedure setimagenr(const avalue: imagenrty); + function getimagenrdisabled: imagenrty; + procedure setimagenrdisabled(const avalue: imagenrty); + function getinvisible: boolean; + procedure setinvisible(const avalue: boolean); + function getfonttab: tfont; + function getfontactivetab: tfont; + function getfonttab1: ttabformfonttab; + procedure setfonttab1(const avalue: ttabformfonttab); + procedure setfonttab(const avalue: tfont); + function isfonttabstored: boolean; + function getfontactivetab1: ttabformfontactivetab; + procedure setfontactivetab1(const avalue: ttabformfontactivetab); + procedure setfontactivetab(const avalue: tfont); + function isfontactivetabstored: boolean; + function getfacetab: tfacecomp; + procedure setfacetab(const avalue: tfacecomp); + function getfaceactivetab: tfacecomp; + procedure setfaceactivetab(const avalue: tfacecomp); + protected + class function getmoduleclassname: string; override; + procedure changed; + procedure fontchanged1(const sender: tobject); + procedure visiblechanged; override; + procedure setcaption(const value: msestring); override; + procedure doselect; virtual; + procedure dodeselect; virtual; + procedure loaded; override; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + class function hasresource: boolean; override; +// constructor docreate(aowner: tcomponent); override; + procedure docreate(aowner: tcomponent); override; + class function classskininfo: skininfoty; override; + public + destructor destroy; override; + procedure createfonttab; + procedure createfontactivetab; + function isactivepage: boolean; + property tabwidget: tcustomtabwidget read ftabwidget; + property tabindex: integer read gettabindex write settabindex; + published + property color default cl_default; + property colortab: colorty read getcolortab + write setcolortab default cl_default; + property coloractivetab: colorty read getcoloractivetab + write setcoloractivetab default cl_default; + property facetab: tfacecomp read getfacetab write setfacetab; + property faceactivetab: tfacecomp read getfaceactivetab + write setfaceactivetab; + property fonttab: ttabformfonttab read getfonttab1 write setfonttab1 + stored isfonttabstored; + property fontactivetab: ttabformfontactivetab read getfontactivetab1 + write setfontactivetab1 stored isfontactivetabstored; + property tabhint: msestring read gettabhint write settabhint; + property tabnoface: boolean read gettabnoface + write settabnoface default false; + property imagelist: timagelist read getimagelist write setimagelist; + property imagenr: imagenrty read getimagenr write setimagenr default -1; + property imagenrdisabled: imagenrty read getimagenrdisabled + write setimagenrdisabled default -2; + //-2 -> same as imagenr + property onselect: notifyeventty read fonselect write fonselect; + property ondeselect: notifyeventty read fondeselect write fondeselect; + property invisible: boolean read getinvisible write setinvisible default false; + property visible default false; + property optionsskin; + end; + + tabformclassty = class of ttabform; + +function createmseform(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; +function createmainform(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; +function createsubform(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; +function createscrollboxform(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; +function createtabform(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; + +implementation +uses + sysutils,mselist,msekeyboard,msebits,msestreaming,msestockobjects; +const + containercommonflags: optionswidgetty = + [ow_arrowfocus,ow_arrowfocusin,ow_arrowfocusout,ow_destroywidgets, + ow_parenttabfocus,ow_mousewheel{, + ow_subfocus,ow_mousefocus,ow_tabfocus}]; + +type + tcomponent1 = class(tcomponent); + tmsecomponent1 = class(tmsecomponent); + twidget1 = class(twidget); + twindow1 = class(twindow); + tcustomframe1 = class(tcustomframe); + treader1 = class(treader); + tframemenuwidget1 = class(tframemenuwidget); + tcustomtabwidget1 = class(tcustomtabwidget); + ttaborderoverride1 = class(ttaborderoverride); + + +function createmseform(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; + +begin + result:= custommseformclassty(aclass).create(nil,false); + tmsecomponent1(result).factualclassname:= aclassname; +end; + +function createmainform(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; + +begin + result:= tmsecomponent(aclass.newinstance); +{$warnings off} + tcomponent1(result).setdesigning(true); //used for wo_groupleader +{$warnings on} + tcustommseform(result).create(nil,false); + tmsecomponent1(result).factualclassname:= aclassname; +end; + +function createsubform(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; +begin + result:= subformclassty(aclass).create(nil,false); + tmsecomponent1(result).factualclassname:= aclassname; +end; + +function createscrollboxform(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; +begin + result:= scrollboxformclassty(aclass).create(nil,false); + tmsecomponent1(result).factualclassname:= aclassname; +end; + +function createtabform(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; +begin + result:= tabformclassty(aclass).create(nil,false); + tmsecomponent1(result).factualclassname:= aclassname; +end; + +{ tformscrollbox} + +constructor tformscrollbox.create(aowner: tcustommseform); +begin +// fowner:= aowner; + inherited create(aowner); //dockcontroller needs owner + setsubcomponent(true); + exclude(fwidgetstate,ws_iswidget); + include(fwidgetstate1,ws1_designactive); + foptionswidget:= defaultcontaineroptionswidget; +// parentwidget:= aowner; + setlockedparentwidget(aowner); + name:= 'container'; +end; + +procedure tformscrollbox.setoptionswidget(const avalue: optionswidgetty); +begin + if fparentwidget <> nil then begin + replacebits1(longword(twidget1(fparentwidget).foptionswidget),longword(avalue), + longword(containercommonflags)); + end; + inherited; +end; + +procedure tformscrollbox.readdummy(reader: treader); +begin + reader.driver.skipvalue; +end; + +procedure tformscrollbox.writedummy(writer: twriter); +begin + //dummy +end; + +procedure tformscrollbox.readbounds(reader: treader); +var + rect1: rectty; +begin + reader.readlistbegin; + rect1.x:= reader.readinteger; + rect1.y:= reader.readinteger; + rect1.cx:= reader.readinteger; + rect1.cy:= reader.readinteger; + reader.readlistend; + widgetrect:= rect1; + fboundsread:= true; +end; + +procedure tformscrollbox.writebounds(writer: twriter); +begin + writer.writelistbegin; + writer.writeinteger(fwidgetrect.x); + writer.writeinteger(fwidgetrect.y); + writer.writeinteger(fwidgetrect.cx); + writer.writeinteger(fwidgetrect.cy); + writer.writelistend; +end; + +procedure tformscrollbox.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('bounds_x',{$ifdef FPC}@{$endif}readdummy, + {$ifdef FPC}@{$endif}writedummy,false); + filer.defineproperty('bounds_y',{$ifdef FPC}@{$endif}readdummy, + {$ifdef FPC}@{$endif}writedummy,false); + filer.defineproperty('bounds_cx',{$ifdef FPC}@{$endif}readdummy, + {$ifdef FPC}@{$endif}writedummy,false); + filer.defineproperty('bounds_cy',{$ifdef FPC}@{$endif}readdummy, + {$ifdef FPC}@{$endif}writedummy,false); + filer.defineproperty('bounds_cxmin',{$ifdef FPC}@{$endif}readdummy, + {$ifdef FPC}@{$endif}writedummy,false); + filer.defineproperty('bounds_cymax',{$ifdef FPC}@{$endif}readdummy, + {$ifdef FPC}@{$endif}writedummy,false); + filer.defineproperty('anchors',{$ifdef FPC}@{$endif}readdummy, + {$ifdef FPC}@{$endif}writedummy,false); + filer.defineproperty('bounds',{$ifdef FPC}@{$endif}readbounds, + {$ifdef FPC}@{$endif}writebounds,true); +end; + +procedure tformscrollbox.dolayout(const sender: twidget); +begin + if owner <> nil then begin + tcustommseform(owner).updatelayout(sender); + end; + inherited; +end; + +procedure tformscrollbox.docheckautosize; +begin + if owner <> nil then begin + with tcustommseform(owner) do begin + if optionswidget1 * [ow1_autowidth,ow1_autoheight] <> [] then begin + checkautosize; + end; + end; + end; +end; + +function tformscrollbox.getassistiveflags(): assistiveflagsty; +begin + result:= inherited getassistiveflags(); + if twidget(owner).ownswindow then begin + include(result,asf_toplevel); + end; +end; + +procedure tformscrollbox.clientrectchanged; +begin + inherited; + docheckautosize; +end; + +procedure tformscrollbox.widgetregionchanged(const sender: twidget); +begin + inherited; + docheckautosize; +end; + +{ tdockformscrollbox } + +constructor tdockformscrollbox.create(aowner: tcustomdockform); +begin + inherited create(aowner); +end; + +procedure tdockformscrollbox.clientrectchanged; +begin + if not (ws_loadlock in fwidgetstate) and (owner <> nil) then begin + tcustomdockform(owner).fdragdock.beginclientrectchanged; + end; + inherited; + if not (ws_loadlock in fwidgetstate) and (owner <> nil) then begin + tcustomdockform(owner).fdragdock.endclientrectchanged; + end; +end; + +procedure tdockformscrollbox.widgetregionchanged(const sender: twidget); +begin + inherited; + if not (ws_loadlock in fwidgetstate) and + not (ws1_updateopaque in twidget1(sender).fwidgetstate1) then begin + tcustomdockform(owner).fdragdock.widgetregionchanged(sender); + end; +end; + +procedure tdockformscrollbox.dopaintforeground(const acanvas: tcanvas); +begin + inherited; + tcustomdockform(owner).fdragdock.dopaint(acanvas); +end; + +function tdockformscrollbox.getdockcontroller: tdockcontroller; +begin + result:= tcustomdockform(owner).fdragdock; +end; + +procedure tdockformscrollbox.mouseevent(var info: mouseeventinfoty); +begin + inherited; + getdockcontroller.checkmouseactivate(self,info); +end; + +procedure tdockformscrollbox.dopaintbackground(const canvas: tcanvas); +begin + inherited; + with tcustomdockform(owner) do begin + if fdockingareacaption <> '' then begin + paintdockingareacaption(canvas,self,fdockingareacaption); + end; + end; +end; + +{ tcustommseform } + +procedure tcustommseform.docreate(aowner: tcomponent); +begin + inherited create(aowner); + fwidgetrect.cx:= 100; + fwidgetrect.cy:= 100; + if fscrollbox = nil then begin + fscrollbox:= tformscrollbox.create(self); + end; + optionswidget:= defaultformwidgetoptions; +end; + +procedure tcustommseform.aftercreate; +begin + //dummy +end; + +constructor tcustommseform.create(aowner: tcomponent; load: boolean); + +begin + ftaborderoverride:= ttaborderoverride.create(self); + ficon:= tmaskedbitmap.create(bmk_rgb); + ficon.onchange:= {$ifdef FPC}@{$endif}iconchanged; + fwindowopacity:= emptyreal; + fwidgetrect.x:= 100; + fwidgetrect.y:= 100; + foptions:= defaultformoptions; + docreate(aowner); + aftercreate; + registerhandlers; + if load and not (csdesigning in componentstate) and + (cs_ismodule in fmsecomponentstate) then begin + loadmsemodule(self,tcustommseform); + end; + if not (acs_dooncreatecalled in factstate) then begin + dooncreate; + end; + if not load then begin +// autoreadstat; + doafterload; + end; + if (fo_createmodal in foptions) and + (componentstate*[csdesigning,csdestroying,csloading] = []){ and + showing} then begin + show(true); + end; +end; + +constructor tcustommseform.create(aowner: tcomponent); +begin + create(aowner,not (cs_noload in fmsecomponentstate)); +end; + +destructor tcustommseform.destroy; +var + bo1: boolean; +begin + bo1:= csdesigning in componentstate; + include(fwidgetstate,ws_destroying); + unregisterhandlers; + mainmenu:= nil; + ficon.free; + fscrollbox.free; + fmainmenuwidget.free; + statfile:= nil; //unlink client connection + inherited; //csdesigningflag is removed + ftaborderoverride.free(); + if not bo1 and candestroyevent(tmethod(fondestroyed)) then begin + fondestroyed(self); + end; +end; + +procedure tcustommseform.afterconstruction; +begin + inherited; + if assigned(foncreated) then begin + foncreated(self); + end; +end; + +procedure tcustommseform.beforedestruction; +begin + inherited; + if candestroyevent(tmethod(fondestroy)) then begin + fondestroy(self); + end; +end; + +procedure tcustommseform.unregisterhandlers; +begin + application.unregisteronterminated({$ifdef FPC}@{$endif}doterminated); + application.unregisteronterminate({$ifdef FPC}@{$endif}doterminatequery); + application.unregisteronidle({$ifdef FPC}@{$endif}doidle); + application.unregisteronwidgetactivechanged( + {$ifdef FPC}@{$endif}dowidgetactivechanged); + application.unregisteronwindowactivechanged( + {$ifdef FPC}@{$endif}dowindowactivechanged); + application.unregisteronwindowdestroyed( + {$ifdef FPC}@{$endif}dowindowdestroyed); + application.unregisteronapplicationactivechanged( + {$ifdef FPC}@{$endif}doapplicationactivechanged); + if not (csdesigning in componentstate) and + (assigned(fonsysevent) or assigned(fonsyswindowevent)) then begin + application.unregistersyseventhandler({$ifdef FPC}@{$endif}dosysevent); + end; + if not (csdesigning in componentstate) and + assigned(fonapplicationevent) then begin + application.unregisterapplicationeventhandler(@doapplicationevent); + end; +end; + +procedure tcustommseform.registerhandlers; +begin + application.registeronterminated({$ifdef FPC}@{$endif}doterminated); + application.registeronterminate({$ifdef FPC}@{$endif}doterminatequery); + application.registeronidle({$ifdef FPC}@{$endif}doidle); + application.registeronwidgetactivechanged( + {$ifdef FPC}@{$endif}dowidgetactivechanged); + application.registeronwindowactivechanged( + {$ifdef FPC}@{$endif}dowindowactivechanged); + application.registeronwindowdestroyed({$ifdef FPC}@{$endif}dowindowdestroyed); + application.registeronapplicationactivechanged( + {$ifdef FPC}@{$endif}doapplicationactivechanged); +end; + +procedure tcustommseform.dooncreate; +begin + if not (cs_inheritedloading in msecomponentstate) then begin + include(factstate,acs_dooncreatecalled); + if assigned(foncreate) then begin //csloading possibly set + beginsuspendgloballoading; + try + foncreate(self); + finally + endsuspendgloballoading; + end; + end; + end; +end; + +procedure tcustommseform.doafterload; +begin + inherited; + autoreadstat; + if canevent(tmethod(fonloaded)) then begin + fonloaded(self); + end; +end; + +procedure tcustommseform.loaded; +begin + if (factivatortarget <> nil) and + not (csdesigning in componentstate) then begin + factivatortarget.activaterecursive(); + end; + exclude(fscrollbox.fwidgetstate,ws_loadlock); + if not (csdesigning in componentstate) then begin + if fo_screencentered in foptions then begin + window.windowpos:= wp_screencentered; + end; + if fo_screencenteredvirt in foptions then begin + window.windowpos:= wp_screencenteredvirt; + end; + end; + inherited; + if fmainmenuwidget <> nil then begin + fmainmenuwidget.visible:= true; +// fmainmenuwidget.loaded; +// include(tframemenuwidget1(fmainmenuwidget).fwidgetstate,ws_visible); + end; + updateoptions; + updatemainmenutemplates; + application.postevent(tobjectevent.create(ek_loaded,ievent(self)){,true}); + //to the OS queue +end; + +procedure tcustommseform.freeinstance; +begin + if (factivatortarget <> nil) and + not (csdesigning in componentstate) then begin + try + factivatortarget.deactivaterecursive; + finally + inherited; + end; + end + else begin + inherited; + end; +end; + +procedure tcustommseform.readstate(reader: treader); +var + bo1: boolean; +begin + include(fscrollbox.fwidgetstate,ws_loadlock); + bo1:= false; +{$warnings off} + with treader1(reader) do begin +{$warnings on} + if floaded <> nil then begin + if floaded.IndexOf(fscrollbox) < 0 then begin + floaded.add(fscrollbox); +{$warnings off} + tcomponent1(fscrollbox).FComponentState:= + tcomponent1(fscrollbox).FComponentState + [csloading]; +{$warnings on} + end; + end; + bo1:= not (csreading in fscrollbox.componentstate); + if bo1 then begin +{$warnings off} + tcomponent1(fscrollbox).FComponentState:= + tcomponent1(fscrollbox).FComponentState + [csreading]; +{$warnings on} + end; + end; + inherited; + ttaborderoverride1(ftaborderoverride).endread(reader); + if bo1 then begin +{$warnings off} + exclude(tcomponent1(fscrollbox).FComponentState,csreading); +{$warnings on} + end; + if not (acs_dooncreatecalled in factstate) then begin + dooncreate; + end; +end; + +procedure tcustommseform.reload(const callafterload: boolean = false); +begin + name:= ''; + unregisterhandlers; + try + reloadmsecomponent(self); + finally + registerhandlers; + end; + if callafterload then begin + doafterload; + end; +end; + +procedure tcustommseform.writestate(writer: twriter); +begin + tscrollboxframe(fscrollbox.frame).scrollpos:= nullpoint; + inherited; +end; + +{$ifdef mse_with_ifi} +procedure tcustommseform.executeificommand(var acommand: ificommandcodety); +begin + inherited; + case acommand of + icc_close: begin + application.postevent(tobjectevent.create(ek_closeform,ievent(self))); + end; + end; +end; + +procedure tcustommseform.setmodalresult(const avalue: modalresultty); +begin + window.modalresult:= avalue; +end; + +function tcustommseform.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iififormlink); +end; + +procedure tcustommseform.setifilink(const avalue: tififormlinkcomp); +begin + mseificomp.setifilinkcomp(iififormlink(self),avalue,tifilinkcomp(fifilink)); +end; + +{$endif} + +procedure tcustommseform.beforeclosequery(var amodalresult: modalresultty); +begin + inherited; + if canevent(tmethod(fonbeforeclosequery)) then begin + fonbeforeclosequery(self,amodalresult); + end; + if (amodalresult = mr_windowclosed) and + (fo_windowclosecancel in foptions) then begin + amodalresult:= mr_cancel; + end; +end; + +procedure tcustommseform.doonclose; +begin + if canevent(tmethod(fonclose)) then begin + fonclose(self); + end; +end; + +function tcustommseform.canclose(const newfocus: twidget): boolean; +var + modres: modalresultty; +begin + result:= inherited canclose(newfocus); + if result and (newfocus = nil) and ((fwindow = nil) or + not (tws_candefocus in fwindow.state)) then begin + modres:= twindow1(window).fmodalresult; + if (modres = mr_windowclosed) and (fo_nowindowclose in foptions) then begin + result:= false; + exit; + end; + if modres = mr_none then begin + modres:= mr_canclose; + end; + if canevent(tmethod(fonclosequery)) then begin + fonclosequery(self,modres); + end; + {$ifdef mse_with_ifi} + if fifiserverintf <> nil then begin + fifiserverintf.closequery(iificlient(self),modres); + end; + {$endif} + result:= modres <> mr_none; +// if twindow1(window).fmodalresult <> mr_canclose then begin + if modres <> mr_canclose then begin + twindow1(window).fmodalresult:= modres; + end; + if result and ((twindow1(window).fmodalresult <> mr_none) or + (application.terminating) or (ws1_forceclose in fwidgetstate1)) then begin + doonclose; + {$ifdef mse_with_ifi} + if fifiserverintf <> nil then begin + fifiserverintf.sendmodalresult(iificlient(self),window.modalresult); + end; + {$endif} + if (fo_terminateonclose in foptions) and not application.terminating and + not (csdesigning in componentstate) then begin + result:= application.terminate(window); + end; + if result and (fstatfile <> nil) and (fo_autowritestat in foptions) and + not (csdesigning in componentstate) then begin + fstatfile.writestat; + end; + if result and (fo_freeonclose in foptions) and + not (csdesigning in componentstate) then begin + release; + end; + end; + end; +end; + +function tcustommseform.close( + const amodalresult: modalresultty = mr_windowclosed): boolean; + //simulates mr_windowclose, true if ok +begin + if ownswindow then begin + result:= window.close(amodalresult); + end + else begin + result:= simulatemodalresult(self,amodalresult); + end; +end; + +procedure tcustommseform.doterminated(const sender: tobject); +begin + if canevent(tmethod(fonterminated)) then begin + fonterminated(sender); + end; +end; + +procedure tcustommseform.doterminatequery(var terminate: boolean); +begin + if canevent(tmethod(fonterminatequery)) then begin + fonterminatequery(terminate); + end; +end; + +procedure tcustommseform.doidle(var again: boolean); +begin + if canevent(tmethod(fonidle)) then begin + fonidle(again); + end; +end; + +procedure tcustommseform.dowidgetactivechanged(const oldwidget, + newwidget: twidget); +begin + if canevent(tmethod(fonwidgetactivechanged)) then begin + fonwidgetactivechanged(oldwidget,newwidget); + end; +end; + +procedure tcustommseform.dowindowactivechanged(const oldwindow, + newwindow: twindow); +begin + if canevent(tmethod(fonwindowactivechanged)) then begin + fonwindowactivechanged(oldwindow,newwindow); + end; +end; + +procedure tcustommseform.dowindowdestroyed(const awindow: twindow); +begin + if canevent(tmethod(fonwindowdestroyed)) then begin + fonwindowdestroyed(awindow); + end; +end; + +procedure tcustommseform.doapplicationactivechanged(const avalue: boolean); +begin + if canevent(tmethod(fonapplicationactivechanged)) then begin + fonapplicationactivechanged(avalue); + end; +end; + +procedure tcustommseform.getchildren(proc: tgetchildproc; root: tcomponent); +begin + inherited; + fscrollbox.getchildren(proc,root); + getcompchildren(proc,root); +end; + +procedure tcustommseform.setoptionswidget(const avalue: optionswidgetty); +begin + inherited; + replacebits1(longword(fscrollbox.foptionswidget),longword(avalue), + longword(containercommonflags)); +end; + +function tcustommseform.nexttaborderoverride(const sender: twidget; + const down: boolean): twidget; +begin + result:= ftaborderoverride.nexttaborder(sender,down); + if result = nil then begin + result:= inherited nexttaborderoverride(sender,down); + end; +end; + +procedure tcustommseform.doeventloopstart; +begin + if (fstatfile <> nil) and not (csdesigning in componentstate) and + (foptions*[fo_autoreadstat,fo_delayedreadstat] = + [fo_autoreadstat,fo_delayedreadstat]) then begin + fstatfile.readstat; + end; + if canevent(tmethod(foneventloopstart)) then begin + foneventloopstart(self); + end; +end; + +procedure tcustommseform.receiveevent(const event: tobjectevent); +var + rect1: rectty; +begin + inherited; + case event.kind of + ek_loaded: begin + doeventloopstart; + if (fo_modal in foptions) and + (componentstate*[csloading,csdesigning] = []){ and showing} then begin + show(true); + end; + end; + ek_closeform: begin + close; + end; + ek_checkscreenrange: begin + if ownswindow and visible and (window.windowpos = wp_normal) then begin + rect1:= window.decoratedwidgetrect; + if clipinrect1(rect1,application.screenrect) then begin + window.decoratedwidgetrect:= rect1; + end; + end; + end; + end; +end; + +function tcustommseform.getonlayout: notifyeventty; +begin + result:= fscrollbox.onlayout; +end; + +procedure tcustommseform.setonlayout(const avalue: notifyeventty); +begin + fscrollbox.onlayout:= avalue; +end; + +procedure tcustommseform.updatemainmenutemplates; +begin +// if not (csloading in componentstate) then begin + if (fmainmenuwidget <> nil) and + (fmainmenu <> nil) then begin + fmainmenuwidget.assigntemplate(fmainmenu.template); + end; + updatescrollboxrect; +// end; +end; + +function tcustommseform.createmainmenuwidget: tframemenuwidget; +begin + result:= tframemenuwidget.create(self,fmainmenu); +end; + +procedure tcustommseform.setmainmenu(const Value: tmainmenu); +begin + if value <> fmainmenu then begin + freeandnil(fmainmenuwidget); + setlinkedvar(value,tmsecomponent(fmainmenu)); + if value <> nil then begin + fmainmenuwidget:= createmainmenuwidget; +{$warnings off} + twidget1(fmainmenuwidget).setdesigning(csdesigning in componentstate); +{$warnings on} + updatemainmenutemplates; + end + else begin + updatescrollboxrect; + end; + end; +end; + +procedure tcustommseform.objectevent(const sender: tobject; + const event: objecteventty); +begin + if sender = fmainmenu then begin + case event of + oe_destroyed: begin + setmainmenu(nil); + end; + oe_changed: begin + if not (csdestroying in componentstate) then begin + updatemainmenutemplates; + if fmainmenuwidget <> nil then begin + fmainmenuwidget.menuchanged(nil); + end; + end; + end; + end; + end; + inherited; +end; + +procedure tcustommseform.setoptions(const Value: formoptionsty); +{$ifndef FPC} +const + mask1: formoptionsty = [fo_screencentered,fo_screencenteredvirt, + fo_transientforcentered,fo_mainwindowcentered, + fo_defaultpos]; + mask2: formoptionsty = [fo_closeonesc,fo_cancelonesc]; + mask3: formoptionsty = [fo_maximized,fo_minimized,fo_fullscreen, + fo_fullscreenvirt]; + mask4: formoptionsty = [fo_modal,fo_createmodal]; +{$endif} +//var +// opt1,opt2: formoptionsty; +begin + if foptions <> value then begin + {$ifdef FPC} + foptions:= formoptionsty(setsinglebit(longword(value),longword(foptions), + [longword([fo_screencentered,fo_screencenteredvirt, + fo_transientforcentered,fo_mainwindowcentered,fo_defaultpos]), + longword([fo_closeonesc,fo_cancelonesc]), + longword([fo_maximized,fo_minimized,fo_fullscreen,fo_fullscreenvirt]), + longword([fo_modal,fo_createmodal]) + ])); + {$else} + foptions:= formoptionsty(setsinglebitar32(longword(value),longword(foptions), + [longword(mask1),longword(mask2),longword(mask3),longword(mask4)])); + {$endif} +(* + opt1:= formoptionsty(setsinglebit( + {$ifdef FPC}longword{$else}longword{$endif}(value), + {$ifdef FPC}longword{$else}longword{$endif}(foptions), + {$ifdef FPC}longword{$else}longword{$endif}(mask2))); + opt2:= formoptionsty(setsinglebit( + {$ifdef FPC}longword{$else}longword{$endif}(value), + {$ifdef FPC}longword{$else}longword{$endif}(foptions), + {$ifdef FPC}longword{$else}longword{$endif}(mask3))); + foptions:= formoptionsty(setsinglebit( + {$ifdef FPC}longword{$else}longword{$endif}(value), + {$ifdef FPC}longword{$else}longword{$endif}(foptions), + {$ifdef FPC}longword{$else}longword{$endif}(mask1))); + foptions:= formoptionsty(replacebits( + {$ifdef FPC}longword{$else}longword{$endif}(opt1), + {$ifdef FPC}longword{$else}longword{$endif}(foptions), + {$ifdef FPC}longword{$else}longword{$endif}(mask2))); + foptions:= formoptionsty(replacebits( + {$ifdef FPC}longword{$else}longword{$endif}(opt2), + {$ifdef FPC}longword{$else}longword{$endif}(foptions), + {$ifdef FPC}longword{$else}longword{$endif}(mask3))); +*) + updateoptions; + end; +end; + +function tcustommseform.ismainwindow(): boolean; +begin + result:= (fo_main in foptions) and not (csdesigning in componentstate); +end; + +procedure tcustommseform.updateoptions; +begin + if (componentstate * [csloading,csdestroying,csdesigning] = []) and + (window.owner = self) then begin + fwindow.globalshortcuts:= fo_globalshortcuts in foptions; + fwindow.localshortcuts:= fo_localshortcuts in foptions; + if ismainwindow() then begin + application.mainwindow:= fwindow; + end; + if fo_fullscreen in foptions then begin + fwindow.windowpos:= wp_fullscreen; + end + else begin + if fo_maximized in foptions then begin + fwindow.windowpos:= wp_maximized; + end + else begin + if fo_minimized in foptions then begin + fwindow.windowpos:= wp_minimized; + end + else begin + if fo_screencentered in foptions then begin + fwindow.windowpos:= wp_screencentered; + end + else begin + if fo_transientforcentered in foptions then begin + fwindow.windowpos:= wp_transientforcentered; + end + else begin + if fo_mainwindowcentered in foptions then begin + fwindow.windowpos:= wp_mainwindowcentered; + end + else begin + if fo_defaultpos in foptions then begin + fwindow.windowpos:= wp_default; + end; + end; + end; + end; + end; + end; + end; + end; +end; + +function tcustommseform.getoptions: formoptionsty; +begin + result:= foptions; +end; + +procedure tcustommseform.setoptionswindow(const Value: windowoptionsty); +const + mask1: windowoptionsty = [wo_taskbar,wo_notaskbar]; +begin + foptionswindow:= windowoptionsty(setsinglebit( + {$ifdef FPC}longword{$else}longword{$endif}(value), + {$ifdef FPC}longword{$else}longword{$endif}(foptionswindow), + {$ifdef FPC}longword{$else}longword{$endif}(mask1))); +end; + +procedure tcustommseform.setstatfile(const avalue: tstatfile); +begin + setstatfilevar(istatfile(self),avalue,fstatfile); +end; + +function tcustommseform.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +procedure tcustommseform.dostatread1(const reader: tstatreader); +var + rect1{,rect2}: rectty; + str1: string; + widget1: twidget; +begin + if fo_savepos in foptions then begin + rect1:= widgetrect; + with rect1 do begin + x:= reader.readinteger('x',x); + y:= reader.readinteger('y',y); + cx:= reader.readinteger('cx',cx,0); + cy:= reader.readinteger('cy',cy,0); + end; +// setclippedwidgetrect(rect1); + rect1:= clipinrect(rect1,application.screenrect); //shift into screen + widgetrect:= rect1; + application.postevent(tobjectevent.create(ek_checkscreenrange,ievent(self))); + end; + if fo_savezorder in foptions then begin + str1:= '~'; + str1:= reader.readstring('stackedunder',str1); + if str1 <> '~' then begin + if trim(str1) = '' then begin + window.stackunder(nil); + end + else begin + if application.findwidget(str1,widget1) and (widget1 <> nil) then begin + window.stackunder(widget1.window); + end; + end; + end; + end; +end; + +procedure tcustommseform.dostatread(const reader: tstatreader); +var + bo1: boolean; + pos1: windowposty; +begin + if canevent(tmethod(fonstatupdate)) then begin + fonstatupdate(self,reader); + end; + if canevent(tmethod(fonstatread)) then begin + fonstatread(self,reader); + end; + dostatread1(reader); + if fparentwidget = nil then begin + with reader do begin + if fo_savestate in foptions then begin + pos1:= windowposty(readinteger('wsize',ord(window.windowpos),0, + ord(high(windowposty)))); + bo1:= readboolean('visible',visible); + bo1:= visible or bo1; + if fo_main in foptions then begin + bo1:= true; + if pos1 = wp_minimized then begin + pos1:= wp_normal; + end; + end; + if bo1 then begin + if pos1 <> wp_minimized then begin + show; + end; + window.windowpos:= pos1; //does not work with kde and invisible window + end; + if readboolean('active',active) then begin + application.postevent(tobjectevent.create(ek_activate,ievent(self))); + //to the OS queue +// activate; + end; + end; + end; + end; +end; + +procedure tcustommseform.statreading; +begin + include(fformstate,fos_statreading); + if canevent(tmethod(fonstatbeforeread)) then begin + fonstatbeforeread(self); + end; +end; + +procedure tcustommseform.statread; +begin + exclude(fformstate,fos_statreading); + if canevent(tmethod(fonstatafterread)) then begin + fonstatafterread(self); + end; +end; + +procedure tcustommseform.dostatwrite1(const writer: tstatwriter); +var + window1: twindow; +begin + if fparentwidget = nil then begin + if fo_savezorder in foptions then begin + window1:= window.stackedunder; + if window1 <> nil then begin + writer.writestring('stackedunder',ownernamepath(window1.owner)); + end + else begin + writer.writestring('stackedunder',''); + end; + end; + if fo_savepos in foptions then begin + with window.normalwindowrect do begin + writer.writeinteger('x',x); + writer.writeinteger('y',y); + writer.writeinteger('cx',cx); + writer.writeinteger('cy',cy); + end; + end; + end; +end; + +procedure tcustommseform.dostatwrite(const writer: tstatwriter); +begin + if assigned(fonstatbeforewrite) then begin + fonstatbeforewrite(self); + end; + if assigned(fonstatupdate) then begin + fonstatupdate(self,writer); + end; + if assigned(fonstatwrite) then begin + fonstatwrite(self,writer); + end; + dostatwrite1(writer); + if fparentwidget = nil then begin + with writer do begin + if fo_savestate in foptions then begin + writeinteger('wsize',ord(window.windowpos)); + writeboolean('active',active); + writeboolean('visible',visible); + end; + end; + end; + if assigned(fonstatafterwrite) then begin + fonstatafterwrite(self); + end; +end; + +procedure tcustommseform.updatescrollboxrect; +var + rect1: rectty; +begin + if not (ws_destroying in fwidgetstate) and + (not (csloading in componentstate) or + not fscrollbox.fboundsread) then begin + rect1:= innerwidgetrect; + if fmainmenuwidget <> nil then begin + with tframemenuwidget1(fmainmenuwidget) do begin + setwidgetrect(makerect(self.paintpos,makesize( + self.paintsize.cx,bounds_cy))); + updatelayout(); + inc(rect1.y,bounds_cy); + dec(rect1.cy,bounds_cy); + end; + end; + if fscrollbox <> nil then begin + fscrollbox.setwidgetrect(rect1); + end; + end; +end; + +procedure tcustommseform.internalsetwidgetrect(Value: rectty; + const windowevent: boolean); +begin + inherited; + if csloading in componentstate then begin + updatescrollboxrect; //no clientrectchanged + end; +end; + +procedure tcustommseform.clientrectchanged; +begin + inherited; + updatescrollboxrect; +end; + +procedure tcustommseform.updatewindowinfo(var info: windowinfoty); +begin + inherited; + info.options:= foptionswindow; + if csdesigning in componentstate then begin + exclude(info.options,wo_groupleader); + end; + if fo_maximized in foptions then begin + info.initialwindowpos:= wp_maximized; + end + else begin + if fo_minimized in foptions then begin + info.initialwindowpos:= wp_minimized; + end + else begin + if fo_defaultpos in foptions then begin + info.initialwindowpos:= wp_default; + end; + end; + end; + getwindowicon(ficon,info.icon,info.iconmask); +end; + +procedure tcustommseform.rootchanged(const aflags: rootchangeflagsty); +begin + inherited; + if (rcf_windowset in aflags) and + (foptions * [fo_main,fo_globalshortcuts] = + [fo_main,fo_globalshortcuts]) then begin + window.globalshortcuts:= true; + end; +end; + +procedure tcustommseform.setparentwidget(const Value: twidget); +begin + if (value = nil) and (fparentwidget <> nil) and (fwindow <> nil) and + (foptions * [fo_main,fo_globalshortcuts] = + [fo_main,fo_globalshortcuts]) then begin + fwindow.globalshortcuts:= false; //restore + end; + if fframe <> nil then begin + exclude(tcustomframe1(fframe).fstate,fs_rectsvalid); + end; + inherited; +end; + +function tcustommseform.isgroupleader: boolean; +begin + result:= (wo_groupleader in foptionswindow) or (fo_main in foptions); +end; + +procedure tcustommseform.insertwidget(const widget: twidget; const apos: pointty); +begin +// if not (csloading in widget.componentstate) then begin + if not (csloading in componentstate) then begin + fscrollbox.insertwidget(widget,subpoint(apos,fscrollbox.fwidgetrect.pos)); + end + else begin + fscrollbox.insertwidget(widget,apos); + end; +end; + +function tcustommseform.getcontainer: twidget; +begin + result:= fscrollbox; +end; + +function tcustommseform.getchildwidgets(const index: integer): twidget; +begin + result:= fscrollbox.getchildwidgets(index); +end; + +function tcustommseform.childrencount: integer; +begin + result:= fscrollbox.childrencount; +end; + +procedure tcustommseform.dolayout(const sender: twidget); +begin + inherited; + if (fmainmenuwidget <> nil) and (fmainmenuwidget = sender) then begin + updatescrollboxrect; + end; +end; + +function tcustommseform.checkdock(var info: draginfoty): boolean; +begin + result:= true; +end; + +function tcustommseform.getbuttonrects(const index: dockbuttonrectty): rectty; +begin + if fframe = nil then begin + if index = dbr_handle then begin + result:= clientrect; + end + else begin + result:= nullrect; + end; + end + else begin + result:= tgripframe(fframe).buttonrects[index]; + end; +end; + +function tcustommseform.getplacementrect: rectty; +begin + with fscrollbox do begin + result:= paintrect; + deflaterect1(result,tcustomframe1(fframe).fi.innerframe); + addpoint1(result.pos,clientpos); //??? + end; +end; + +function tcustommseform.getminimizedsize(out apos: captionposty): sizety; +begin + if fframe = nil then begin + result:= nullsize; + end + else begin + result:= tgripframe(fframe).getminimizedsize(apos); + end; +end; + +function tcustommseform.getcaption: msestring; +begin + result:= fcaption; +end; + +procedure tcustommseform.setcaption(const Value: msestring); +begin + fcaption := Value; + if ownswindow then begin + window.caption:= fcaption; + end; +end; + +function tcustommseform.getwindowcaption: msestring; +begin + result:= fcaption; +end; + +function tcustommseform.getchildicon: tmaskedbitmap; +begin + result:= nil; + if not (csdestroying in componentstate) then begin + if ficon.hasimage then begin + result:= ficon; + end; + end; +end; + +procedure tcustommseform.windowcreated; +var + mstr1: msestring; +begin + inherited; + mstr1:= getwindowcaption; + if mstr1 <> '' then begin + window.caption:= mstr1; + end; + if fwindowopacity <> emptyreal then begin + window.opacity:= fwindowopacity; + end; +// if fcaption <> '' then begin +// caption:= fcaption; //set windowcaption +// end; +end; + +procedure tcustommseform.dofontheightdelta(var delta: integer); +begin + if canevent(tmethod(fonfontheightdelta)) then begin + fonfontheightdelta(self,delta); + end; +end; + +procedure tcustommseform.dokeydown(var info: keyeventinfoty); +var + modres1: modalresultty; +begin + inherited; + with info do begin + if not (es_processed in eventstate) and + (shiftstate * shiftstatesrepeatmask = []) and + (not (fo_keycloseifwinonly in foptions) or (fparentwidget = nil)) and + (((fo_closeonesc in foptions) or (fo_cancelonesc in foptions)) and + (key = key_escape) or + (fo_closeonf10 in foptions) and (key = key_f10) or + (fo_closeonenter in foptions) and isenterkey(self,key)) then begin + include(eventstate,es_processed); + if key = key_f10 then begin + modres1:= mr_f10; + end + else begin + if key = key_escape then begin + if fo_cancelonesc in foptions then begin + modres1:= mr_cancel; + end + else begin + modres1:= mr_escape; + end; + end + else begin + modres1:= mr_ok; + end; + end; + close(modres1); + end; + end; +end; + +procedure tcustommseform.doshortcut(var info: keyeventinfoty; const sender: twidget); +begin + if not (es_processed in info.eventstate) then begin + if (fmainmenu <> nil) and not ((csdesigning) in componentstate) then begin + fmainmenu.doshortcut(info); + end; + if not (es_processed in info.eventstate) then begin + inherited; +// if not info.processed and (fmainmenuwidget <> nil) and (info.shiftstate = [ss_alt]) then begin +// fmainmenuwidget.keydown +// end; + end; + end; +end; +{ +function tcustommseform.getframe: tgripframe; +begin + result:= tgripframe(inherited getframe); +end; + +procedure tcustommseform.setframe(const Value: tgripframe); +begin + inherited setframe(value); +end; +} +{ +function tcustommseform.getframescrollbox: tscrollboxframe; +begin + result:= fscrollbox.frame; +end; + +procedure tcustommseform.setframescrollbox(const Value: tscrollboxframe); +begin + fscrollbox.frame:= value; +end; +} +procedure tcustommseform.setscrollbox(const avalue: tformscrollbox); +begin + fscrollbox.Assign(avalue); +end; + +function tcustommseform.getonbeforepaint: painteventty; +begin + result:= fscrollbox.onbeforepaint; +end; + +procedure tcustommseform.setonbeforepaint(const Value: painteventty); +begin + fscrollbox.onbeforepaint:= value; +end; + +function tcustommseform.getonpaint: painteventty; +begin + result:= fscrollbox.onpaint; +end; + +procedure tcustommseform.setonpaint(const Value: painteventty); +begin + fscrollbox.onpaint:= value; +end; + +function tcustommseform.getonafterpaint: painteventty; +begin + result:= fscrollbox.onafterpaint; +end; + +procedure tcustommseform.setonafterpaint(const Value: painteventty); +begin + fscrollbox.onafterpaint:= value; +end; + +procedure tcustommseform.seticon(const avalue: tmaskedbitmap); +begin + ficon.assign(avalue); +end; + +procedure tcustommseform.setwindowopacity(const avalue: realty); +begin + fwindowopacity:= avalue; + if ownswindow then begin + window.opacity:= avalue; + end; +end; + +procedure tcustommseform.iconchanged(const sender: tobject); +var + icon1,mask1: pixmapty; +begin + if ficonchanging = 0 then begin + inc(ficonchanging); + if ownswindow then begin + getwindowicon(internalgeticon(),icon1,mask1); + gui_setwindowicon(window.winid,icon1,mask1); + if (fo_main in foptions) and not (csdesigning in componentstate) then begin + gui_setapplicationicon(icon1,mask1); + end; + end; + dec(ficonchanging); + end; +end; + +procedure tcustommseform.widgetregionchanged(const sender: twidget); +begin + inherited; + if (fmainmenuwidget <> nil) and (sender = fmainmenuwidget) then begin + updatescrollboxrect; + end; +end; + +procedure tcustommseform.setonsysevent(const avalue: syseventeventty); +begin + if not (csdesigning in componentstate) then begin + if assigned(avalue) then begin + if not assigned(fonsysevent) and not assigned(fonsyswindowevent) then begin + application.registersyseventhandler({$ifdef FPC}@{$endif}dosysevent); + end; + end + else begin + if assigned(fonsysevent) and not assigned(fonsyswindowevent) then begin + application.unregistersyseventhandler({$ifdef FPC}@{$endif}dosysevent); + end; + end; + end; + fonsysevent:= avalue; +end; + +procedure tcustommseform.setonsyswindowevent(const avalue: syseventeventty); +begin + if not (csdesigning in componentstate) then begin + if assigned(avalue) then begin + if not assigned(fonsysevent) and not assigned(fonsyswindowevent) then begin + application.registersyseventhandler({$ifdef FPC}@{$endif}dosysevent); + end; + end + else begin + if assigned(fonsyswindowevent) and not assigned(fonsysevent) then begin + application.unregistersyseventhandler({$ifdef FPC}@{$endif}dosysevent); + end; + end; + end; + fonsyswindowevent:= avalue; +end; + +procedure tcustommseform.setonapplicationevent( + const avalue: applicationeventeventty); +begin + if not (csdesigning in componentstate) then begin + if assigned(avalue) then begin + if not assigned(fonapplicationevent) then begin + application.registerapplicationeventhandler(@doapplicationevent); + end; + end + else begin + if assigned(fonapplicationevent) then begin + application.unregisterapplicationeventhandler(@doapplicationevent); + end; + end; + end; + fonapplicationevent:= avalue; +end; + +procedure tcustommseform.dosysevent(const awindow: winidty; + var aevent: syseventty; var handled: boolean); +begin + if assigned(fonsysevent) then begin + fonsysevent(self,aevent,handled); + end; + if assigned(fonsyswindowevent) and not handled and + (awindow <> 0) and (twindow1(window).fwindow.id = awindow) then begin + fonsyswindowevent(self,aevent,handled); + end; +end; + +procedure tcustommseform.doapplicationevent(var aevent: tmseevent; + var handled: boolean); +begin + if assigned(fonapplicationevent) then begin + fonapplicationevent(self,aevent,handled); + end; +end; + +procedure tcustommseform.updatelayout(const sender: twidget); +begin + //dummy +end; + +function tcustommseform.getassistivecaption(): msestring; +begin +{ + result:= ''; + if caption <> '' then begin + if ownswindow then begin + result:= sc(sc_window)+' '+caption; + end + else begin + result:= caption; + end; + end; +} + result:= caption; + if result = '' then begin + result:= inherited getassistivecaption(); + end; +end; + +procedure tcustommseform.readonchildscaled(reader: treader); +begin + onlayout:= notifyeventty(readmethod(reader)); +end; + +procedure tcustommseform.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('onchildscaled', + {$ifdef FPC}@{$endif}readonchildscaled,nil,false); +end; + +procedure tcustommseform.dolayoutchanged(const sender: tdockcontroller); +begin + //dummy +end; + +procedure tcustommseform.dodockcaptionchanged(const sender: tdockcontroller); +begin + //dummy +end; + +procedure tcustommseform.autoreadstat; +begin + if (fstatfile <> nil) and not (csdesigning in componentstate) and + (foptions*[fo_autoreadstat,fo_delayedreadstat] = + [fo_autoreadstat]) then begin + fstatfile.readstat; + end; +end; + +procedure tcustommseform.getautopaintsize(var asize: sizety); +var + size1: sizety; +begin + with fscrollbox do begin + asize:= calcminscrollsize; + size1:= frame.paintframedim; + subpoint1(pointty(size1),self.paintpos); + asize.cx:= asize.cx + fscrollbox.bounds_x + size1.cx; + asize.cy:= asize.cy + fscrollbox.bounds_y + size1.cy; + end; +end; + +procedure tcustommseform.setactivatortarget(const avalue: tactivator); +begin + setlinkedvar(avalue,tmsecomponent(factivatortarget)); +end; + +procedure tcustommseform.settaborderoverride(const avalue: ttaborderoverride); +begin + ftaborderoverride.assign(avalue); +end; + +function tcustommseform.internalgeticon(): tmaskedbitmap; +begin + result:= ficon; +end; + +function tcustommseform.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +{ tmseform } + +constructor tmseform.create(aowner: tcomponent; load: boolean); +begin + include(fmsecomponentstate,cs_ismodule); + inherited; +end; + +class function tmseform.getmoduleclassname: string; +begin +// result:= tmseform.ClassName; + //bug in dcc32: tmseform is replaced by self + result:= 'tmseform'; +end; + +class function tmseform.hasresource: boolean; +begin + result:= self <> tmseform; +end; + +{ tmainform } + +class function tmainform.getmoduleclassname: string; +begin +// result:= tmseform.ClassName; + //bug in dcc32: tmseform is replaced by self + result:= 'tmainform'; +end; + +class function tmainform.hasresource: boolean; +begin + result:= self <> tmainform; +end; + +procedure tmainform.aftercreate; +begin + inherited; + foptions:= defaultmainformoptions; + foptionswindow:= defaultmainformoptionswindow; +end; + +{ tformdockcontroller } + + +constructor tformdockcontroller.create(const aowner: tcustomdockform); +begin + fowner:= aowner; + foptionsdockform:= defaultoptionsdockform; + inherited create(idockcontroller(aowner)); +end; + +procedure tformdockcontroller.setoptionsdock(const avalue: optionsdockty); +begin + inherited; + updatebit(longword(tdockform(fintf.getwidget).foptions), + ord(fo_savepos),od_savepos in foptionsdock); + updatebit(longword(tdockform(fintf.getwidget).foptions), + ord(fo_savezorder),od_savezorder in foptionsdock); +end; + +procedure tformdockcontroller.setoptionsdockform( + const avalue: optionsdockformty); +begin + if foptionsdockform <> avalue then begin + foptionsdockform:= avalue; + if fowner.componentstate * [csloading,csdestroying] = [] then begin + layoutchanged(); + end; + end; +end; + +function tformdockcontroller.hasmain(): boolean; +var + ar1: widgetarty; + w1: twidget; + i1: int32; +begin + result:= false; + if not (csdestroying in fowner.componentstate) then begin + result:= odf_main in foptionsdockform; + if not result then begin + ar1:= getitems(); + for i1:= 0 to high(ar1) do begin + w1:= ar1[i1]; + if not (csdestroying in w1.componentstate) and + (w1 is tcustomdockform) then begin + result:= tcustomdockform(w1).fdragdock.hasmain(); + if result then begin + break; + end; + end; + end; + end; + end; +end; + +function tformdockcontroller.childicon(): tmaskedbitmap; + + function check(const avalue: tformdockcontroller): tmaskedbitmap; + var + ar1: widgetarty; + w1: twidget; + i1: int32; + begin + result:= nil; + with avalue do begin + if not (csdestroying in fowner.componentstate) then begin + if odf_main in foptionsdockform then begin + result:= fowner.ficon; + end + else begin + ar1:= getitems(); + for i1:= 0 to high(ar1) do begin + w1:= ar1[i1]; + if w1 is tcustomdockform then begin + result:= check(tcustomdockform(w1).fdragdock); + if result <> nil then begin + break; + end; + end; + end; + end; + end; + end; + end; //check + +begin + if (odf_mainchildicon in foptionsdockform) then begin + result:= check(self); + if result = nil then begin + result:= inherited childicon(); + end + else begin + if not result.hasimage then begin + result:= nil; + end; + end; + end + else begin + result:= inherited childicon; + end; +end; + +procedure tformdockcontroller.dolayoutchanged(); +begin + inherited; + if odf_childicons in foptionsdockform then begin + fowner.iconchanged(nil); + end; +end; + +procedure tformdockcontroller.childstatechanged(const sender: twidget; + const newstate: widgetstatesty; const oldstate: widgetstatesty); +begin + inherited; + if (odf_childicons in foptionsdockform) and (ws_entered in newstate) and + not (ws_entered in oldstate) then begin + fowner.iconchanged(nil); + end; +end; + +{ tcustomdockform } + +constructor tcustomdockform.create(aowner: tcomponent; load: boolean); +begin + if fdragdock = nil then begin + fdragdock:= tformdockcontroller.create(self); + end; + if fscrollbox = nil then begin + fscrollbox:= tdockformscrollbox.create(self); + end; + inherited; +end; + +destructor tcustomdockform.destroy(); +begin + inherited; + fdragdock.Free; +end; + +function tcustomdockform.getdockcontroller: tdockcontroller; +begin + result:= fdragdock; +end; + +procedure tcustomdockform.setdragdock(const value: tformdockcontroller); +begin + fdragdock.assign(value); +end; + +function tcustomdockform.getframe: tgripframe; +begin + result:= tgripframe(inherited getframe); +end; + +procedure tcustomdockform.setframe(const avalue: tgripframe); +begin + inherited setframe(avalue); +end; + +procedure tcustomdockform.internalcreateframe; +begin + tgripframe.create(iscrollframe(self),fdragdock); +end; + +function tcustomdockform.internalgeticon(): tmaskedbitmap; +begin + result:= inherited internalgeticon(); + if (result = nil) or not result.hasimage() and + (odf_childicons in fdragdock.optionsdockform) then begin + result:= fdragdock.childicon(); + end; +end; + +procedure tcustomdockform.dragevent(var info: draginfoty); +begin + if not fdragdock.beforedragevent(info) then begin + inherited; + end; + fdragdock.afterdragevent(info); +end; + +procedure tcustomdockform.updateoptions; +begin + updatebit({$ifdef FPC}longword{$else}longword{$endif}(fdragdock.foptionsdock), + ord(od_savepos),fo_savepos in foptions); + updatebit({$ifdef FPC}longword{$else}longword{$endif}(fdragdock.foptionsdock), + ord(od_savezorder),fo_savezorder in foptions); + inherited; +end; + +function tcustomdockform.getoptions: formoptionsty; +begin + if od_savepos in fdragdock.optionsdock then begin + include(foptions,fo_savepos); + end + else begin + exclude(foptions,fo_savepos); + end; + if od_savezorder in fdragdock.optionsdock then begin + include(foptions,fo_savezorder); + end + else begin + exclude(foptions,fo_savezorder); + end; + result:= inherited getoptions; +end; + +procedure tcustomdockform.dostatread1(const reader: tstatreader); +begin + tdockcontroller(fdragdock).dostatread(reader); +end; + +procedure tcustomdockform.dostatwrite1(const writer: tstatwriter); +var + rect1: rectty; +begin + if fparentwidget = nil then begin + rect1:= window.normalwindowrect; + fdragdock.dostatwrite(writer,@rect1); + end + else begin + fdragdock.dostatwrite(writer,nil); + end; +end; +{ +procedure tcustomdockform.dokeydown(var info: keyeventinfoty); +begin + fdragdock.keydown(info); + if not es_processed in info.eventstate then begin + inherited; + end; +end; +} +procedure tcustomdockform.statreading; +begin + tdockcontroller(fdragdock).statreading; + inherited; +end; + +procedure tcustomdockform.statread; +begin + tdockcontroller(fdragdock).statread; + inherited; +end; +(* +procedure tcustomdockform.mouseevent(var info: mouseeventinfoty); +var + bo1: boolean; +begin + inherited; + { + bo1:= info.eventkind = ek_buttonrelease; + if not (es_processed in info.eventstate) and bo1 then begin + fdragdock.mouseevent(info); + end; + inherited; + if not (es_processed in info.eventstate) and not bo1 then begin + fdragdock.mouseevent(info); + end; + } +end; +*) +procedure tcustomdockform.childmouseevent(const sender: twidget; + var info: mouseeventinfoty); +begin + if not (es_processed in info.eventstate) then begin + fdragdock.childormouseevent(sender,info); + if not (es_processed in info.eventstate) then begin + inherited; + end; + end; +end; + +procedure tcustomdockform.doactivate; +begin + fdragdock.doactivate; + inherited; +end; + +procedure tcustomdockform.parentchanged; +begin + inherited; + fdragdock.parentchanged(self); +end; + +function tcustomdockform.canfocus: boolean; +begin + result:= inherited canfocus and (fdragdock.mdistate <> mds_minimized); +end; + +procedure tcustomdockform.activate(const abringtofront: boolean = true; + const aforce: boolean = false); +begin + if fdragdock.mdistate = mds_minimized then begin + fdragdock.mdistate:= mds_normal; + end; + if fdragdock.ismdi then begin + bringtofront; + end; + inherited; +end; + +procedure tcustomdockform.activechanged; +begin + if fframe <> nil then begin + invalidaterect(tgripframe(fframe).griprect,org_widget); + end; + inherited; +end; + +procedure tcustomdockform.statechanged; +begin + fdragdock.statechanged(fwidgetstate); + inherited; +end; + +procedure tcustomdockform.poschanged; +begin + fdragdock.poschanged; + inherited; +end; + +function tcustomdockform.getwindowcaption: msestring; +begin + result:= fdragdock.getfloatcaption; +end; + +function tcustomdockform.ismainwindow(): boolean; +begin + result:= inherited ismainwindow() or not(csdesigning in componentstate) and + (odf_mainmainwindow in fdragdock.foptionsdockform) and + fdragdock.hasmain(); +end; + +procedure tcustomdockform.dolayoutchanged(const sender: tdockcontroller); +begin + inherited; + if not (csdestroying in componentstate) then begin + checkdockicon(); + if (window.owner = self) then begin + if ismainwindow() then begin + application.mainwindow:= fwindow; + end + else begin + if application.mainwindow = fwindow then begin + application.mainwindow:= nil; + end; + end; + end; + end; +end; + +procedure tcustomdockform.checkdockicon(); +begin + if odf_childicons in fdragdock.optionsdockform then begin + iconchanged(nil); + end; + if fhasdocktaskbaricon <> needsdocktaskbaricon() then begin + window.recreatewindow(); + end; +end; + +function tcustomdockform.getchildicon(): tmaskedbitmap; +begin + result:= inherited getchildicon(); + if (result = nil) and not (csdestroying in componentstate) then begin + result:= fdragdock.childicon(); + end; +end; + +procedure tcustomdockform.loaded(); +begin + inherited; + checkdockicon(); +end; + +procedure tcustomdockform.doenter(); +begin + inherited; + fdragdock.statechanged(fwidgetstate); +end; + +procedure tcustomdockform.doexit(); +begin + inherited; + fdragdock.statechanged(fwidgetstate); +end; + +procedure tcustomdockform.setdockingareacaption(const avalue: msestring); +begin + fdockingareacaption:= avalue; + invalidate; +end; + +function tcustomdockform.needsdocktaskbaricon(): boolean; +begin + result:= (odf_maintaskbar in fdragdock.foptionsdockform) and + fdragdock.hasmain(); +end; + +procedure tcustomdockform.updatewindowinfo(var info: windowinfoty); +begin + inherited; + fhasdocktaskbaricon:= needsdocktaskbaricon(); + if fhasdocktaskbaricon then begin + include(info.options,wo_taskbar); + end; +end; + +{ tdockform} + +constructor tdockform.create(aowner: tcomponent; load: boolean); +begin + include(fmsecomponentstate,cs_ismodule); + inherited; +end; + +class function tdockform.getmoduleclassname: string; +begin + result:= 'tdockform'; +end; + +class function tdockform.hasresource: boolean; +begin + result:= self <> tdockform; +end; + +{ tsubform } + +constructor tsubform.create(aowner: tcomponent); +begin + create(aowner,not (cs_noload in fmsecomponentstate)); +end; + +constructor tsubform.create(aowner: tcomponent; load: boolean); +begin + include(fmsecomponentstate,cs_ismodule); + fwidgetrect.x:= 100; + fwidgetrect.y:= 100; + inherited create(aowner); + fwidgetrect.cx:= 100; + fwidgetrect.cy:= 100; + if load and not (csdesigning in componentstate) and + (cs_ismodule in fmsecomponentstate) then begin + loadmsemodule(self,tsubform); + end; +end; + +class function tsubform.getmoduleclassname: string; +begin + result:= 'tsubform'; +end; + +class function tsubform.hasresource: boolean; +begin + result:= self <> tsubform; +end; + +procedure tsubform.getchildren(proc: tgetchildproc; root: tcomponent); +begin + inherited; + getcompchildren(proc,root); +end; + +{ tscrollboxform } + +constructor tscrollboxform.create(aowner: tcomponent); +begin + create(aowner,not (cs_noload in fmsecomponentstate)); +end; + +constructor tscrollboxform.create(aowner: tcomponent; load: boolean); +begin + include(fmsecomponentstate,cs_ismodule); + fwidgetrect.x:= 100; + fwidgetrect.y:= 100; + inherited create(aowner); + fwidgetrect.cx:= 100; + fwidgetrect.cy:= 100; + if load and not (csdesigning in componentstate) and + (cs_ismodule in fmsecomponentstate) then begin + loadmsemodule(self,tscrollboxform); + end; +end; + +class function tscrollboxform.getmoduleclassname: string; +begin + result:= 'tscrollboxform'; +end; + +class function tscrollboxform.hasresource: boolean; +begin + result:= self <> tscrollboxform; +end; + +procedure tscrollboxform.getchildren(proc: tgetchildproc; root: tcomponent); +begin + inherited; + getcompchildren(proc,root); +end; + +{ ttabformfonttab } + +class function ttabformfonttab.getinstancepo(owner: tobject): pfont; +begin + result:= @ttabform(owner).ffonttab; +end; + +{ ttabpagefontactivetab } + +class function ttabformfontactivetab.getinstancepo(owner: tobject): pfont; +begin + result:= @ttabform(owner).ffontactivetab; +end; + +{ ttabform } + +//constructor ttabform.docreate(aowner: tcomponent); +procedure ttabform.docreate(aowner: tcomponent); +begin + fcolortab:= cl_default; + fcoloractivetab:= cl_default; + fimagenr:= -1; + fimagenrdisabled:= -2; + inherited; +// inherited create(aowner); + fcolor:= cl_default; + exclude(fwidgetstate,ws_visible); +end; + +destructor ttabform.destroy; +begin + inherited; + freeandnil(ffonttab); + freeandnil(ffontactivetab); +end; + +class function ttabform.classskininfo: skininfoty; +begin + result:= inherited classskininfo; + result.objectkind:= sok_tabpage; +end; + +procedure ttabform.createfonttab; +begin + if ffonttab = nil then begin + ffonttab:= ttabformfonttab.create; + ffonttab.onchange:= {$ifdef FPC}@{$endif}fontchanged1; + end; +end; + +procedure ttabform.createfontactivetab; +begin + if ffontactivetab = nil then begin + ffontactivetab:= ttabformfontactivetab.create; + ffontactivetab.onchange:= {$ifdef FPC}@{$endif}fontchanged1; + end; +end; + +procedure ttabform.loaded; +begin + if fparentwidget is tcustomtabwidget then begin + include(fwidgetstate1,ws1_nodesignvisible); + end; + inherited; +end; + +class function ttabform.getmoduleclassname: string; +begin + result:= 'ttabform'; +end; + +procedure ttabform.changed; +begin + if ftabwidget <> nil then begin + tcustomtabwidget1(ftabwidget).pagechanged(itabpage(self)); + end; +end; + +procedure ttabform.fontchanged1(const sender: tobject); +begin + changed; +end; + +function ttabform.getcolortab: colorty; +begin + result:= fcolortab; +end; + +procedure ttabform.setcolortab(const avalue: colorty); +begin + if fcolortab <> avalue then begin + fcolortab:= avalue; + changed; + end; +end; + +function ttabform.getcoloractivetab: colorty; +begin + result:= fcoloractivetab; +end; + +procedure ttabform.setcoloractivetab(const avalue: colorty); +begin + if fcoloractivetab <> fcoloractivetab then begin + fcoloractivetab:= avalue; + changed; + end; +end; + +function ttabform.gettabwidget: tcustomtabwidget; +begin + result:= ftabwidget; +end; + +function ttabform.isactivepage: boolean; +begin + result:= (ftabwidget <> nil) and (ftabwidget.activepage = self); +end; + +procedure ttabform.setcaption(const value: msestring); +begin + inherited; + changed; +end; + +function ttabform.gettabhint: msestring; +begin + result:= ftabhint; +end; + +procedure ttabform.settabhint(const avalue: msestring); +begin + ftabhint:= avalue; + changed; +end; + +function ttabform.gettabnoface: boolean; +begin + result:= ftabnoface; +end; + +procedure ttabform.settabnoface(const avalue: boolean); +begin + if ftabnoface <> avalue then begin + ftabnoface:= avalue; + changed; + end; +end; + +procedure ttabform.settabwidget(const value: tcustomtabwidget); +begin + ftabwidget:= value; +end; + +procedure ttabform.visiblechanged; +begin + inherited; + changed; +end; + +function ttabform.gettabindex: integer; +begin + if tabwidget = nil then begin + result:= -1; + end + else begin + result:= tabwidget.indexof(self); + end; +end; + +procedure ttabform.settabindex(const avalue: integer); +begin + if tabwidget <> nil then begin + tabwidget.movepage(tabindex,avalue); + end; +end; + +procedure ttabform.doselect; +begin + if canevent(tmethod(fonselect)) then begin + fonselect(self); + end; +end; + +procedure ttabform.dodeselect; +begin + if canevent(tmethod(fondeselect)) then begin + fondeselect(self); + end; +end; + +function ttabform.getimagelist: timagelist; +begin + result:= fimagelist +end; + +procedure ttabform.setimagelist(const avalue: timagelist); +begin + if fimagelist <> avalue then begin + setlinkedvar(avalue,tmsecomponent(fimagelist)); + changed; + end; +end; + +function ttabform.getimagenr: imagenrty; +begin + result:= fimagenr; +end; + +procedure ttabform.setimagenr(const avalue: imagenrty); +begin + if fimagenr <> avalue then begin + fimagenr:= avalue; + changed; + end; +end; +{ +function ttabform.getimagenractive: integer; +begin + result:= fimagenractive; +end; + +procedure ttabform.setimagenractive(const avalue: integer); +begin + if fimagenractive <> avalue then begin + fimagenractive:= avalue; + changed; + end; +end; +} +function ttabform.getimagenrdisabled: imagenrty; +begin + result:= fimagenrdisabled; +end; + +procedure ttabform.setimagenrdisabled(const avalue: imagenrty); +begin + if fimagenrdisabled <> avalue then begin + fimagenrdisabled:= avalue; + changed; + end; +end; + +procedure ttabform.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if event = oe_destroyed then begin + if sender = fimagelist then begin + fimagelist:= nil; + changed; + end; + if sender = ffacetab then begin + ffacetab:= nil; + changed; + end; + if sender = ffaceactivetab then begin + ffaceactivetab:= nil; + changed; + end; + end + else begin + if event = oe_changed then begin + changed; + end; + end; +end; + +function ttabform.getinvisible: boolean; +begin + result:= finvisible; +end; + +procedure ttabform.setinvisible(const avalue: boolean); +begin + if finvisible <> avalue then begin + finvisible:= avalue; + changed; + end; +end; + +class function ttabform.hasresource: boolean; +begin + result:= self <> ttabform; +end; + +function ttabform.getfonttab: tfont; +begin + result:= ffonttab; +end; + +function ttabform.getfontactivetab: tfont; +begin + result:= ffontactivetab; +end; + +function ttabform.getfonttab1: ttabformfonttab; +begin + getoptionalobject(ffonttab, + {$ifdef FPC}@{$endif}createfonttab); + result:= ffonttab; +end; + +procedure ttabform.setfonttab1(const avalue: ttabformfonttab); +begin + if avalue <> ffonttab then begin + setoptionalobject(avalue,ffonttab, + {$ifdef FPC}@{$endif}createfonttab); + changed; + end; +end; + +procedure ttabform.setfonttab(const avalue: tfont); +begin + setfonttab1(ttabformfonttab(avalue)); +end; + +function ttabform.isfonttabstored: boolean; +begin + result:= ffonttab <> nil; +end; + +function ttabform.getfontactivetab1: ttabformfontactivetab; +begin + getoptionalobject(ffontactivetab, + {$ifdef FPC}@{$endif}createfontactivetab); + result:= ffontactivetab; +end; + +procedure ttabform.setfontactivetab1(const avalue: ttabformfontactivetab); +begin + if avalue <> ffontactivetab then begin + setoptionalobject(avalue,ffontactivetab, + {$ifdef FPC}@{$endif}createfontactivetab); + changed; + end; +end; + +procedure ttabform.setfontactivetab(const avalue: tfont); +begin + setfontactivetab1(ttabformfontactivetab(avalue)); +end; + +function ttabform.isfontactivetabstored: boolean; +begin + result:= ffontactivetab <> nil; +end; + +function ttabform.getfacetab: tfacecomp; +begin + result:= ffacetab; +end; + +procedure ttabform.setfacetab(const avalue: tfacecomp); +begin + if ffacetab <> avalue then begin + setlinkedvar(avalue,tmsecomponent(ffacetab)); + changed(); + end; +end; + +function ttabform.getfaceactivetab: tfacecomp; +begin + result:= ffaceactivetab; +end; + +procedure ttabform.setfaceactivetab(const avalue: tfacecomp); +begin + if ffaceactivetab <> avalue then begin + setlinkedvar(avalue,tmsecomponent(ffaceactivetab)); + changed(); + end; +end; + +{ +function ttabform.gettabwidth: integer; +begin + result:= ftabwidth; +end; + +procedure ttabform.settabwidth(const avalue: integer); +begin + ftabwidth:= avalue; + changed; +end; + +function ttabform.gettabwidthmin: integer; +begin + result:= ftabwidthmin; +end; + +procedure ttabform.settabwidthmin(const avalue: integer); +begin + ftabwidthmin:= avalue; + changed; +end; + +function ttabform.gettabwidthmax: integer; +begin + result:= ftabwidthmax; +end; + +procedure ttabform.settabwidthmax(const avalue: integer); +begin + ftabwidthmax:= avalue; + changed; +end; +} +end. + diff --git a/mseide-msegui/lib/common/widgets/msegrids.pas b/mseide-msegui/lib/common/widgets/msegrids.pas new file mode 100644 index 0000000..415f980 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msegrids.pas @@ -0,0 +1,19460 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msegrids; + +{$ifdef FPC} + {$mode objfpc}{$h+}{$interfaces corba}{$goto on} +{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses,sysutils,mseclasses,msegui,msedragglob, + msegraphics,msetypes,msestrings,msegraphutils,msebitmap,mseassistiveclient, + msescrollbar,msearrayprops,mseglob,mseguiglob,typinfo,msearrayutils, + msedatalist,msedrawtext,msewidgets,mseevent,mseinplaceedit,mseeditglob, + mseobjectpicker,msepointer,msetimer,msebits,msestat,msestatfile,msekeyboard, + msestream,msedrag,msemenus,msepipestream,mseshapes,msegridsglob,mselist + {$ifdef mse_with_ifi},mseificomp,mseifiglob,mseificompglob{$endif}; + +type + // listvievoptionty from mselistbrowser + // lvo_readonly,lvo_mousemoving,lvo_keymoving,lvo_horz, + coloptionty = (co_readonly, co_nofocus, co_invisible, co_disabled, + // lvo_drawfocus,lvo_mousemovefocus,lvo_leftbuttonfocusonly, + co_drawfocus,co_mousemovefocus,co_leftbuttonfocusonly, + // lvo_middlebuttonfocus, + co_middlebuttonfocus, + // lvo_noctrlmousefocus, + co_noctrlmousefocus, + // lvo_focusselect,lvo_mouseselect,lvo_keyselect, + co_focusselect, co_mouseselect, co_keyselect, + // lvo_multiselect,lvo_resetselectonexit{,lvo_noresetselect} + co_multiselect, co_resetselectonexit,{co_noresetselect,} + co_rowselect, + + co_fixwidth,co_fixpos,co_fill,co_proportional,co_nohscroll, +// co_autorowheight, + co_savevalue,co_savestate, +// co_rowfont,co_rowcolor,co_zebracolor, //deprecated -> co1_ +// co_rowcoloractive, //deprecated -> co1_ + + co_nosort,co_sortdescend,co_sortcaseinsensitive,co_norearange, + co_cancopy,co_canpaste,co_mousescrollrow,co_rowdatachange + ); + coloptionsty = set of coloptionty; +// celloptionty = (ceo_autorowheight); +// celloptionsty = set of celloptionty; + + coloption1ty = (co1_rowfont,co1_rowcolor,co1_zebracolor, + co1_rowcoloractive,co1_rowcolorfocused,co1_rowreadonly, +// co1_active, //not used + co1_autorowheight,co1_autocolwidth,co1_noautocolwidth, + co1_autoheaderwidth + ); + coloptions1ty = set of coloption1ty; + +const + deprecatedcoloptions = [{co_rowfont,co_rowcolor,co_zebracolor, + co_rowcoloractive}]; + invisiblecoloptions = [{ord(co_rowfont),ord(co_rowcolor),ord(co_zebracolor), + ord(co_rowcoloractive)}]; +// deprecatedcoloptions1 = [co1_active]; + +type + fixcoloptionty = (fco_invisible,fco_mousefocus,fco_mouseselect, + fco_rowfont,fco_rowcolor,fco_zebracolor{, + fco_rowcoloractive,fco_rowcolorfocus}{fco_active}); + fixcoloptionsty = set of fixcoloptionty; + fixrowoptionty = (fro_invisible,fro_mousefocus,fro_mouseselect); + fixrowoptionsty = set of fixrowoptionty; + +const + fixcoloptionsshift1 = ord(fco_rowfont)-ord(co1_rowfont); + fixcoloptionsmask: coloptions1ty = + [co1_rowfont,co1_rowcolor,co1_zebracolor{, + co1_rowcoloractive,co1_rowcolorfocus}]; + + defaultfixcoloptions = []; + defaultgridskinoptions = [osk_framebuttononly]; + sortglyphwidth = 11; + defaultwheelscrollheight = 0; + + rowstatefoldleveltag = 0; + rowstateissumtag = 1; + rowstatefoldhiddentag = 2; + gridautosizetag = 3; + +type + optiongridty = (og_colsizing,og_colmoving,og_keycolmoving, + og_rowsizing,og_rowmoving,og_keyrowmoving, + og_rowinserting,og_rowdeleting,og_selectedrowsdeleting, + og_focuscellonenter,og_containerfocusbackonesc, + og_autofirstrow,og_autoappend,og_appendempty,og_noinsertempty, + og_savestate,og_nosaveremoveappendedrow, + og_sorted,og_nodefaultsort,og_noreorderrow, + og_customsort, //externally sorted data by onsortchanged + og_folded,og_colmerged,og_rowheight, + og_colchangeontabkey,og_colchangeonreturnkey, + og_wraprow,og_wrapcol, + og_visiblerowpagestep, + og_autopopup, + og_mousescrollcol{, + og_noresetselect //deprecated -> og1_noresetselect} + ); + optionsgridty = set of optiongridty; + optiongrid1ty = (og1_norowdeletequery,og1_swaprowinsertappend,//for Ctrl+Insert + og1_forcerowsmodified, + //onrowsmodified fired by doremoveappinsrow() and + //appinsrow + og1_focusmorerows,og1_scrollmorerows, + og1_noresetselect,og1_pasteinselection); + optionsgrid1ty = set of optiongrid1ty; + +const + rowstateoptions = [og_colmerged,og_rowheight]; //variable rowstate size +// deprecatedoptionsgrid = [og_noresetselect]; + invisibleoptionsgrid = [{ord(og_noresetselect)}]; + newcomponentoptionsgridadd = [og_rowinserting,og_rowdeleting, + og_autofirstrow,og_autoappend]; + +type + pickobjectkindty = (pok_none,pok_fixcolsize,pok_fixcol,pok_datacolsize,pok_datacol, + pok_fixrowsize,pok_fixrow,pok_datarowsize,pok_datarow); + + stringcoleditoptionty = ( + scoe_undoonesc,scoe_forcereturncheckvalue,scoe_eatreturn, +// scoe_autorowheight, + + //same layout as editoptionty + scoe_exitoncursor, + scoe_nofirstarrownavig, + scoe_endonenter, + scoe_homeonenter, + scoe_autoselect, //selectall bei enter + scoe_autoselectonfirstclick, + scoe_caretonreadonly, + scoe_focusrectonreadonly, + scoe_trimright, + scoe_trimleft, + scoe_uppercase, + scoe_lowercase, + scoe_hintclippedtext, + scoe_locate, + scoe_casesensitive, + + scoe_checkbox + ); + + stringcoleditoptionsty = set of stringcoleditoptionty; + +const + stringcoloptionseditmask: optionseditty = [ + oe_exitoncursor, + oe_nofirstarrownavig, + oe_endonenter, + oe_homeonenter, + oe_autoselect, //selectall bei enter + oe_autoselectonfirstclick, + oe_caretonreadonly, + oe_focusrectonreadonly, + oe_trimright, + oe_trimleft, + oe_uppercase, + oe_lowercase, + oe_hintclippedtext, + oe_locate, + oe_casesensitive]; + stringcoloptionseditshift = ord(oe_exitoncursor) - + ord(scoe_exitoncursor); + + gridvaluevarname = 'values'; + pickobjectstep = integer(high(pickobjectkindty)) + 1; + layoutchangedcoloptions: coloptionsty = [co_fill,co_proportional,co_invisible, + co_nohscroll{,co_rowcoloractive}]; + layoutchangedcoloptions1: coloptions1ty = + [co1_rowcoloractive,co1_rowcolorfocused, + co1_autorowheight,co1_autocolwidth,co1_autoheaderwidth]; + notfixcoloptions = [co_fixwidth,co_fixpos,co_fill,co_proportional,co_nohscroll, + co_rowdatachange]; + defaultoptionsgrid = [og_autopopup,og_colchangeontabkey,og_focuscellonenter, + og_mousescrollcol,og_wrapcol]; + + mousescrolldist = 5; + griddefaultcolwidth = 50; + griddefaultrowheight = 20; + defaultcoltextflags = [tf_ycentered,tf_noselect]; + defaultactivecoltextflags = defaultcoltextflags - [tf_noselect]; + defaultgridlinewidth = 1; + defaultdatalinecolor = cl_gridline{cl_dkgray}; + defaultfixlinecolor = cl_gridlinefix{cl_black}; + + defaultselectedcellcolor = cl_gridselect{cl_active}; + defaultdatacoloptions = [{co_selectedcolor,}co_savestate,co_savevalue, + {co_rowfont,co_rowcolor,co_zebracolor,}co_mousescrollrow]; + defaultdatacoloptions1 = [co1_rowfont,co1_rowcolor,co1_zebracolor, + co1_rowcoloractive,co1_rowcolorfocused,co1_rowreadonly]; + defaultfixcoltextflags = [tf_ycentered,tf_xcentered]; + defaultstringcoleditoptions = [scoe_exitoncursor,scoe_undoonesc,scoe_autoselect, + scoe_autoselectonfirstclick,scoe_eatreturn, + scoe_focusrectonreadonly]; +// defaultcolheadertextflags = [tf_ycentered,tf_xcentered]; + + + slowrepeat = 200000; //us + fastrepeat = 100000; //us + + defaultgridwidgetoptions = defaultoptionswidgetmousewheel + + [ow_focusbackonesc{,ow_fontglyphheight}]; + defaultgridwidgetoptions1 = defaultoptionswidget1 + + [ow1_fontglyphheight]; + +type + tgridexception = class(exception); + + gridstatety = ( + gs_layoutvalid,gs_layoutupdating,gs_updatelocked,gs_changelock, +// gs_visiblerowsupdating, + gs_cellentered,gs_cellclicked,gs_emptyrowremoved, + gs_rowcountinvalid,gs_rowreadonly, + gs_scrollup,gs_scrolldown,gs_scrollleft,gs_scrollright, + gs_selectionchanged,gs_rowdatachanged,gs_focusedcellchanged,gs_invalidated, + gs_mouseentered,gs_childmousecaptured,gs_child, + gs_mousecellredirected,gs_restorerow,gs_cellexiting,gs_rowremoving, + gs_appending, + gs_hasactiverowcolor, + gs_needszebraoffset, //has zebrastep or autonumcol + gs_needsrowheight, + gs_islist,//contiguous select blocks + gs_isdb); //do not change rowcount + gridstatesty = set of gridstatety; + gridstate1ty = (gs1_showcellinvalid,gs1_sortvalid,gs1_rowsortinvalid, + gs1_sortmoving,gs1_sortchangelock,gs1_rowinserted, + gs1_gridsorted,gs1_dbsorted,gs1_customsort, + gs1_rowdeleting,gs1_autoappending,gs1_autoremoving, + gs1_autosizepending, + gs1_focuscellonenterlock,gs1_mousecaptureendlock, + gs1_forcenullcheck, + gs1_cellsizesyncing,gs1_userinput,gs1_autoappendlock, + gs1_scrolllimit,gs1_nocellassistive); + gridstates1ty = set of gridstate1ty; + + cellkindty = (ck_invalid,ck_data,ck_fixcol,ck_fixrow,ck_fixcolrow); + griderrorty = (gre_ok,gre_invaliddatacell,gre_differentrowcount, + gre_rowindex,gre_colindex,gre_invalidwidget); + +const + mousecellevents = [cek_mousemove,cek_mousepark,cek_firstmousepark, + cek_buttonpress,cek_buttonrelease]; + repeaterstates = [gs_scrollup,gs_scrolldown,gs_scrollleft,gs_scrollright]; + + +type + tcustomgrid = class; + + celleventinfoty = record //same layout as ificelleventinfoty + cell: gridcoordty; + grid: tcustomgrid; + case eventkind: celleventkindty of + cek_exit,cek_enter,cek_focusedcellchanged: + (cellbefore,newcell: gridcoordty; selectaction: focuscellactionty); + cek_select: + (selected: boolean; accept: boolean); + cek_mousemove,cek_mousepark,cek_firstmousepark, + cek_buttonpress,cek_buttonrelease: + (zone: cellzonety; mouseeventinfopo: pmouseeventinfoty; + gridmousepos: pointty); + cek_keydown,cek_keyup: + (keyeventinfopo: pkeyeventinfoty); + end; + pcelleventinfoty = ^celleventinfoty; + + tgridarrayprop = class; + + tcellframe = class(tframe) + public + constructor create(const aintf: iframe); + published + property framei_left default 1; + property framei_top default 1; + property framei_right default 1; + property framei_bottom default 1; + end; + + tfixcellframe = class(tcellframe) + end; + + tcellface = class(tface) + end; + + tfixcellface = class(tcellface) + end; + + rowfoldinfoty = record + foldlevel: byte; + isvisible: boolean; + haschildren: boolean; + isopen: boolean; + nolines: booleanarty; + end; + prowfoldinfoty = ^rowfoldinfoty; + rowfoldinfoarty = array of rowfoldinfoty; + rowfoldinfoaty = array[0..0] of rowfoldinfoty; + prowfoldinfoaty = ^rowfoldinfoaty; + + celldrawstatety = (cds_selected,cds_readonly,cds_focused,cds_active,cds_notext, + cds_usecoloractive,cds_ismousecell); + celldrawstatesty = set of celldrawstatety; + + cellinfoty = record + grid: tcustomgrid; + cell: gridcoordty; + rect: rectty; + innerrect: rectty; //origin rect.pos + frameinnerrect: rectty; //innerrect of cell frame or rect if nil + color: colorty; + colorline: colorty; + font: tfont; + drawstate: celldrawstatesty; +// selected: boolean; +// readonly: boolean; +// focused: boolean; +// active: boolean; +// notext: boolean; +// useactivecolor: boolean; +// ismousecell: boolean; + datapo: pointer; + rowstate: prowstatety; + foldinfo: prowfoldinfoty; +// needslayout: boolean; + calcautocellsize: boolean; // don't paint + autocellsize: sizety; + end; + pcellinfoty = ^cellinfoty; + + tgridpropfont = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + gridpropstatety = (gps_fix,gps_selected,gps_noinvalidate,gps_edited, + gps_readonlyupdating,gps_selectionchanged,gps_changelock, + gps_datalistvalid,gps_needsrowheight, + gps_maxsizevalid,gps_autosizevalid); + gridpropstatesty = set of gridpropstatety; + + tgridprop = class(tindexpersistent,iframe,iface) + private + fcellrect: rectty; + ftag: integer; + function getframe: tcellframe; + procedure setframe(const Value: tcellframe); + function getface: tcellface; + procedure setface(const Value: tcellface); + procedure setcolor(const Value: colorty); + function getfont: tgridpropfont; + function isfontstored: Boolean; + procedure setfont(const Value: tgridpropfont); + procedure setlinewidth(const Value: integer); + procedure setlinecolor(const Value: colorty); + procedure setlinecolorfix(const Value: colorty); + procedure setcolorselect(const Value: colorty); + procedure setcoloractive(avalue: colorty); + procedure setcolorfocused(avalue: colorty); +// procedure setcursor(const avalue: cursorshapety); + protected + fstate: gridpropstatesty; + fstart,fend: integer; + flinepos: integer; + flinewidth: integer; + flinecolor: colorty; + flinecolorfix: colorty; + fcolor: colorty; + fcursor: cursorshapety; + ffont: tgridpropfont; +// fgrid: tcustomgrid; + fframe: tcellframe; + fface: tcellface; + fcellinfo: cellinfoty; + foptions: coloptionsty; + fcolorselect: colorty; + fcoloractive: colorty; + fcolorfocused: colorty; + procedure updatelayout; virtual; + procedure changed; virtual; + procedure updatecellrect(const aframe: tcustomframe); + function getinnerframe: framety; virtual; + function step(getscrollable: boolean = true): integer; virtual; abstract; + function scrollable: boolean; virtual; abstract; + function framedim: sizety; + + //iframe + function getwidget: twidget; + procedure setframeinstance(instance: tcustomframe); + function getwidgetrect: rectty; + procedure setstaticframe(value: boolean); + function getstaticframe: boolean; + function widgetstate: widgetstatesty; + procedure scrollwidgets(const dist: pointty); + procedure clientrectchanged; + function getcomponentstate: tcomponentstate; + function getmsecomponentstate: msecomponentstatesty; + procedure invalidate; + procedure invalidatewidget; + procedure invalidaterect(const rect: rectty; const org: originty = org_client; + const noclip: boolean = false); + function getframestateflags: framestateflagsty; + + procedure updatecellheight(const canvas: tcanvas; var aheight: integer); virtual; + //iface + function getclientrect: rectty; + procedure setlinkedvar(const source: tmsecomponent; var dest: tmsecomponent; + const linkintf: iobjectlink = nil); + procedure widgetregioninvalid; + function translatecolor(const acolor: colorty): colorty; + + procedure fontchanged(const sender: tobject); virtual; + property font: tgridpropfont read getfont write setfont stored isfontstored; + public + constructor create(const agrid: tcustomgrid; + const aprop: tgridarrayprop); reintroduce; virtual; + destructor destroy; override; + procedure createfont; + procedure createframe(); + procedure createface(); + procedure drawcellbackground(const acanvas: tcanvas; + const aframe: tcustomframe; const aface: tcustomface); + procedure drawcelloverlay(const acanvas: tcanvas; const aframe: tcustomframe); + property grid: tcustomgrid read fcellinfo.grid; + property innerframe: framety read getinnerframe; + published + property color: colorty read fcolor write setcolor default cl_default; + property cursor: cursorshapety read fcursor write fcursor default cr_default; + property frame: tcellframe read getframe write setframe; + property face: tcellface read getface write setface; + property linewidth: integer read flinewidth write setlinewidth + default defaultgridlinewidth; + property linecolor: colorty read flinecolor write setlinecolor; + property linecolorfix: colorty read flinecolorfix write setlinecolorfix + default defaultfixlinecolor; + property colorselect: colorty read fcolorselect write setcolorselect + default cl_default; + property coloractive: colorty read fcoloractive write setcoloractive + default cl_none; + property colorfocused: colorty read fcolorfocused write setcolorfocused + default cl_none; + property tag: integer read ftag write ftag default 0; + end; + + gridpropclassty = class of tgridprop; + + colpaintinfoty = record + canvas: tcanvas; + ystart,ystep: integer; + rows: integerarty; + foldinfo: rowfoldinfoarty; + startrow,endrow: integer; //index in rows + calcautocellsize: boolean; + autocellsize: sizety; + end; + + tcols = class; + rangety = record + startindex,endindex: integer; + end; + cellaxisrangety = record + scrollables: boolean; + range1,range2: rangety; + end; + rowpaintinfoty = record + canvas: tcanvas; + cols: tcols; + colrange: cellaxisrangety; + fix: boolean; + calcautocellsize: boolean; + end; + rowspaintinfoty = record + rowinfo: rowpaintinfoty; + rowrange: cellaxisrangety; + end; + + tcolselectfont = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + tcol = class; + + celleventty = procedure(const sender: tobject; + var info: celleventinfoty) of object; + drawcelleventty = procedure(const sender: tcol; const canvas: tcanvas; + var cellinfo: cellinfoty) of object; + beforedrawcelleventty = procedure(const sender: tcol; const canvas: tcanvas; + var cellinfo: cellinfoty; var processed: boolean) of object; + tcol = class(tgridprop) + private + frowfontoffset: integer; + frowfontoffsetselect: integer; + frowcoloroffset: integer; + fonbeforedrawcell: beforedrawcelleventty; + fonafterdrawcell: drawcelleventty; + frowcoloroffsetselect: integer; + ffontactivenum: integer; + ffontfocusednum: integer; + fwidthmax: integer; + fwidthmin: integer; + function getcolindex: integer; + procedure setfocusrectdist(const avalue: integer); + procedure updatepropwidth; + procedure setrowcoloroffset(const avalue: integer); + procedure setrowcoloroffsetselect(const avalue: integer); + procedure setrowfontoffset(const avalue: integer); + procedure setrowfontoffsetselect(const avalue: integer); + function getfontselect: tcolselectfont; + function isfontselectstored: Boolean; + procedure setfontselect(const Value: tcolselectfont); + + procedure setfontactivenum(const avalue: integer); + procedure setfontfocusednum(const avalue: integer); + function getvisible: boolean; + procedure setvisible(const avalue: boolean); + function getreadonly: boolean; + procedure setreadonly(const avalue: boolean); + protected + foptions1: coloptions1ty; + fwidth: integer; + fpropwidth: real; + ffontselect: tcolselectfont; + ffocusrectdist: integer; + fmaxwidth: integer; + function getenabled: boolean; + procedure setenabled(const avalue: boolean); + function checkautocolwidth: boolean; //true if width changed + procedure updatecolwidth(const arow,acount: integer; var acolwidth: integer); + procedure createfontselect; + function getselected(const row: integer): boolean; virtual; + procedure updatewidth(var avalue: integer); virtual; + procedure setwidth(const Value: integer); virtual; + procedure invalidatelayout; + procedure setoptions(const Value: coloptionsty); virtual; + procedure setoptions1(const avalue: coloptions1ty); virtual; + procedure updatelayout; override; + procedure rearange(const list: integerarty); virtual; abstract; + + procedure checkmaxwidth; + function checkactivecolor(const aindex: integer): boolean; + //true if coloractive and fontactivenum active + function checkfocusedcolor(const aindex: integer): boolean; + //true if colorfocus and fontfocusnum active + function isopaque: boolean; virtual; + function needsfocusrect: boolean; virtual; + function getdatapo(const arow: integer): pointer; virtual; + procedure clean(const start,stop: integer); virtual; + procedure paint(var info: colpaintinfoty); virtual; + class function defaultstep(width: integer): integer; virtual; + function step(getscrollable: boolean = true): integer; override; + function scrollable: boolean; override; + procedure dobeforedrawcell(const acanvas: tcanvas; + var processed: boolean); virtual; + procedure doafterdrawcell(const acanvas: tcanvas); virtual; + + procedure drawcell(const acanvas: tcanvas); virtual; + procedure drawfocusedcell(const acanvas: tcanvas); virtual; + procedure rowcountchanged(const newcount: integer); virtual; + procedure drawfocus(const acanvas: tcanvas); virtual; + procedure moverow(const curindex,newindex: integer; + const count: integer = 1); virtual; abstract; + procedure insertrow(const aindex: integer; + const count: integer = 1); virtual; abstract; + procedure deleterow(const aindex: integer; + const count: integer = 1); virtual; abstract; + property options: coloptionsty read foptions write setoptions; + property options1: coloptions1ty read foptions1 write setoptions1 default []; + property focusrectdist: integer read ffocusrectdist write setfocusrectdist + default 0; + function getmerged(const row: integer): boolean; virtual; + procedure setmerged(const row: integer; const avalue: boolean); virtual; + property merged[const row: integer]: boolean read getmerged write setmerged; + public + constructor create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); override; + destructor destroy; override; + procedure invalidate; + procedure invalidatecell(const arow: integer); + procedure invalidatemaxsize(const arow: integer = -1); virtual; + //-1 -> all + function rowcolor(const aindex: integer): colorty; + function rowfont(const aindex: integer): tfont; + procedure changed; override; + procedure cellchanged(const row: integer); virtual; + function actualcolor: colorty; + function actualfont: tfont; virtual; + function maxwidth: integer; + function minmaxwidth(): integer; //bigger of fwidthmin, fmaxwidth + property colindex: integer read getcolindex; + function translatetocell(const arow: integer; const apos: pointty): pointty; + property visible: boolean read getvisible write setvisible; + property enabled: boolean read getenabled write setenabled; + property readonly: boolean read getreadonly write setreadonly; + published + property width: integer read fwidth write setwidth + default griddefaultcolwidth; + property rowcoloroffset: integer read frowcoloroffset + write setrowcoloroffset default 0; + property rowcoloroffsetselect: integer read frowcoloroffsetselect + write setrowcoloroffsetselect default 0; + property rowfontoffset: integer read frowfontoffset write + setrowfontoffset default 0; + property rowfontoffsetselect: integer read frowfontoffsetselect write + setrowfontoffsetselect default 0; + property fontselect: tcolselectfont read getfontselect write + setfontselect stored isfontselectstored; + property fontactivenum: integer read ffontactivenum + write setfontactivenum default -1; + //index in grid.rowfonts + property fontfocusednum: integer read ffontfocusednum + write setfontfocusednum default -1; + //index in grid.rowfonts + property onbeforedrawcell: beforedrawcelleventty read fonbeforedrawcell + write fonbeforedrawcell; + property onafterdrawcell: drawcelleventty read fonafterdrawcell + write fonafterdrawcell; + end; + + tdatacol = class; + + showcolhinteventty = procedure(const sender: tdatacol; const arow: integer; + var info: hintinfoty) of object; + datacoleventty = procedure(const sender: tdatacol) of object; + datacolchangeeventty = procedure(const sender: tdatacol; + const aindex: integer) of object; + + tdatacol = class(tcol) + private + foncellevent: celleventty; + fonshowhint: showcolhinteventty; + fselectedrow: integer; //-1 none, -2 more than one + fselectedrowcount: int32; + fonselectionchanged: datacoleventty; + fselectlock: integer; + procedure internaldoentercell(const cellbefore: gridcoordty; + var newcell: gridcoordty; const action: focuscellactionty); + procedure internaldoexitcell(const cellbefore: gridcoordty; + var newcell: gridcoordty; const selectaction: focuscellactionty); + procedure setwidthmax(const Value: integer); + procedure setwidthmin(const Value: integer); + function getcellorigin: pointty; + function getvisible: boolean; + procedure setvisible(const avalue: boolean); + function getenabled: boolean; + procedure setenabled(const avalue: boolean); + function getreadonly: boolean; + procedure setreadonly(const avalue: boolean); + function getselectedcells: integerarty; + procedure setselectedcells(const avalue: integerarty); + procedure setdata(const avalue: tdatalist); + function getsortdescend: boolean; + procedure setsortdescend(const avalue: boolean); + protected + fdata: tdatalist; + fname: string; + fnameb: string; + fonchange: datacolchangeeventty; + function getmerged(const row: integer): boolean; override; + procedure setmerged(const row: integer; const avalue: boolean); override; + procedure beginselect; + procedure endselect; + function getdatapo(const arow: integer): pointer; override; + function getrowdatapo: pointer; + procedure beforedragevent(var ainfo: draginfoty; const arow: integer; + var processed: boolean); virtual; + procedure afterdragevent(var ainfo: draginfoty; const arow: integer; + var processed: boolean); virtual; + procedure doselectionchanged; + procedure setselected(const row: integer; value: boolean); virtual; + function getselected(const row: integer): boolean; override; + procedure setoptions(const Value: coloptionsty); override; + function createdatalist: tdatalist; virtual; + procedure rowcountchanged(const newcount: integer); override; + procedure docellfocuschanged(enter: boolean; + const cellbefore: gridcoordty; var newcell: gridcoordty; + const selectaction: focuscellactionty); virtual; + procedure doactivate; virtual; + procedure dodeactivate; virtual; + procedure clientmouseevent(const acell: gridcoordty; + var info: mouseeventinfoty); virtual; + procedure dokeyevent(var info: keyeventinfoty; up: boolean); virtual; + procedure checkdirtyautorowheight(aindex: integer); + procedure afterrowcountupdate; virtual; + procedure datachange(const arow: integer); virtual; + procedure itemchanged(const sender: tdatalist; const aindex: integer); virtual; + procedure updatewidth(var avalue: integer); override; + procedure updatelayout; override; + procedure moverow(const fromindex,toindex: integer; const count: integer = 1); override; + procedure insertrow(const aindex: integer; const count: integer = 1); override; + procedure deleterow(const aindex: integer; const count: integer = 1); override; + procedure rearange(const list: integerarty); override; + function sortcompare(const index1,index2: integer): integer; virtual; + function sortcomparecaseinsensitive( + const index1,index2: integer): integer; virtual; + function isempty(const aindex: integer): boolean; virtual; + procedure docellevent(var info: celleventinfoty); virtual; + function getcursor(const arow: integer; const actcellzone: cellzonety; + const amousepos: pointty): cursorshapety; virtual; + function getdatastatname: msestring; + function getstatsuffix(): msestring; + procedure coloptionstoeditoptions(var dest: optionseditty; + var dest1: optionsedit1ty); + procedure clean(const start,stop: integer); override; + function defaultrowheight: integer; virtual; + public + constructor create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); override; + destructor destroy; override; + + function canfocus(const abutton: mousebuttonty; + const ashiftstate: shiftstatesty; + const noreadonly: boolean; + out canrowfocus: boolean): boolean; virtual; + function isreadonly: boolean; //col readonly or row readonly + procedure updatecellzone(const row: integer; const pos: pointty; + var result: cellzonety); virtual; + procedure autocellheightchanged(const aindex: integer); + procedure autocellwidthchanged(const aindex: integer); + property datalist: tdatalist read fdata write setdata; + procedure dostatread(const reader: tstatreader); override; + procedure dostatwrite(const writer: tstatwriter); override; + procedure clearselection; + function defaultcaption(): msestring; + property merged; + property selected[const row: integer]: boolean read getselected write setselected; + //row < 0 -> whole col + property selectedcells: integerarty read getselectedcells + write setselectedcells; +// function selectedcellcount: integer; + property selectedcellcount: int32 read fselectedrowcount; + property cellorigin: pointty read getcellorigin; //org = grid.paintpos + property visible: boolean read getvisible write setvisible; + property enabled: boolean read getenabled write setenabled; + property readonly: boolean read getreadonly write setreadonly; + property sortdescend: boolean read getsortdescend write setsortdescend; + published + property options default defaultdatacoloptions; + property options1 default defaultdatacoloptions1; + property widthmin: integer read fwidthmin write setwidthmin default 1; + property widthmax: integer read fwidthmax write setwidthmax default 0; + property name: string read fname write fname; + property nameb: string read fnameb write fnameb; //ex. sumlevel + property onchange: datacolchangeeventty read fonchange write fonchange; + property oncellevent: celleventty read foncellevent write foncellevent; + property onshowhint: showcolhinteventty read fonshowhint write fonshowhint; + property onselectionchanged: datacoleventty read fonselectionchanged write + fonselectionchanged; + property linecolor default defaultdatalinecolor; + end; + + datacolaty = array[0..0] of tdatacol; + pdatacolaty = ^datacolaty; + + tcelldragobject = class(tdragobject) + private + fgrid: tcustomgrid; + fcell: gridcoordty; + public + constructor create(const draginfo: draginfoty; const cellinfo: cellinfoty); + constructor create(const agrid: tcustomgrid; + var ainstance: tdragobject; const apos: pointty); + property grid: tcustomgrid read fgrid; + property cell: gridcoordty read fcell; + end; + + celldrageventty = procedure(const cellinfo: cellinfoty; + var draginfo: draginfoty; var dragobject: tcelldragobject; + var accept: boolean; var processed: boolean) of object; + + tdrawcol = class(tdatacol) + private + fondrawcell: drawcelleventty; + fonbeforedragevent: celldrageventty; + fonafterdragevent: celldrageventty; + protected + procedure drawcell(const canvas: tcanvas); override; + procedure beforedragevent(var ainfo: draginfoty; const arow: integer; + var processed: boolean) override; + procedure afterdragevent(var ainfo: draginfoty; const arow: integer; + var processed: boolean) override; + published + property focusrectdist; + property ondrawcell: drawcelleventty read fondrawcell write fondrawcell; + property onbeforedragevent: celldrageventty read fonbeforedragevent + write fonbeforedragevent; + property onafterdragevent: celldrageventty read fonafterdragevent + write fonafterdragevent; + property font; + end; + + tstringcoldatalist = class(tmsestringdatalist) + private + fgrid: tcustomgrid; + fnoparagraph: integerarty; + fvaluedefault: msestring; + protected + procedure afterrowcountupdate; + function getnoparagraphs(index: integer): boolean; override; + function getdefault: pointer; override; + public + constructor create(const agrid: tcustomgrid); reintroduce; + function add(const avalue: msestring; const anoparagraph: boolean): integer; + override; + function empty(const index: integer): boolean; override; //true wenn leer + function getparagraph(const index: integer; + const aseparator: msestring = ''): msestring; + property noparagraph[index: integer]: boolean read getnoparagraphs; + published + property facultative; + end; + + tcustomstringcol = class(tdatacol) + private + ftextflagsactive: textflagsty; + fpasswordchar: msechar; + fonsetvalue: setstringeventty; + fondataentered: notifyeventty; + foncopytoclipboard: updatestringeventty; + fonpastefromclipboard: updatestringeventty; + fvaluetrue: msestring; + fvaluefalse: msestring; + fcolorglyph: colorty; + fondrawcell: drawcelleventty; + procedure settextflags(const avalue: textflagsty); + function getdatalist: tstringcoldatalist; + procedure setdatalist(const value: tstringcoldatalist); + procedure settextflagsactive(const avalue: textflagsty); + function geteditpos: gridcoordty; + procedure seteditpos(const avalue: gridcoordty); + procedure setpasswordchar(const avalue: msechar); + function getchecked(aindex: integer): boolean; + procedure setchecked(aindex: integer; const avalue: boolean); + function getvaluedefault: msestring; + procedure setvaluedefault(const avalue: msestring); + procedure setcolorglyph(const avalue: colorty); + function getnoparagraph(const aindex: integer): boolean; + protected + ftextinfo: drawtextinfoty; + foptionsedit: stringcoleditoptionsty; + foptionsedit1: optionsedit1ty; + feditstate: dataeditstatesty; +// procedure setisdb; + function geteditstate: dataeditstatesty; + procedure seteditstate(const avalue: dataeditstatesty); + + function needsfocusrect: boolean; override; + function getoptionsedit: optionseditty; virtual; + function getitems(aindex: integer): msestring; virtual; + procedure setitems(aindex: integer; const Value: msestring); virtual; + function createdatalist: tdatalist; override; + procedure afterrowcountupdate; override; + procedure updatedisptext(var avalue: msestring); virtual; + function getrowtext(const arow: integer): msestring; virtual; + procedure drawcell(const canvas: tcanvas); override; + procedure docellevent(var info: celleventinfoty); override; + procedure updatelayout; override; + function getinnerframe: framety; override; + function getcursor(const arow: integer; const actcellzone: cellzonety; + const amousepos: pointty): cursorshapety; override; + procedure modified; virtual; + procedure checkcellvalue(var avalue: msestring; var accept: boolean); + function defaultrowheight(): integer; override; + public + constructor create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); override; + destructor destroy; override; + function edited: boolean; + function readpipe(const pipe: tpipereader; + const aoptions: addcharoptionsty = [aco_processeditchars]; +// const processeditchars: boolean = false; + const maxchars: integer = 0): integer; overload; + //returns added rowcount + function readpipe(const text: string; + const aoptions: addcharoptionsty = [aco_processeditchars]; +// const processeditchars: boolean = false; + const maxchars: integer = 0): integer; overload; + //returns added rowcount + procedure fillcol(const value: msestring); + property items[aindex: integer]: msestring read getitems + write setitems; default; + property noparagraph[const aindex: integer]: boolean read getnoparagraph; + property checked[aindex: integer]: boolean read getchecked write setchecked; + + property textflags: textflagsty read ftextinfo.flags write settextflags + default defaultcoltextflags; + property textflagsactive: textflagsty read ftextflagsactive + write settextflagsactive default defaultactivecoltextflags; + property optionsedit: stringcoleditoptionsty read foptionsedit + write foptionsedit default defaultstringcoleditoptions; + property optionsedit1: optionsedit1ty read foptionsedit1 + write foptionsedit1 default defaultoptionsedit1; + property passwordchar: msechar read fpasswordchar + write setpasswordchar default #0; + property font; + property datalist: tstringcoldatalist read getdatalist write setdatalist; + property editpos: gridcoordty read geteditpos write seteditpos; + property colorglyph: colorty read fcolorglyph write setcolorglyph + default cl_glyph; + property valuedefault: msestring read getvaluedefault write setvaluedefault; + property valuetrue: msestring read fvaluetrue write fvaluetrue; + property valuefalse: msestring read fvaluefalse write fvaluefalse; + property onsetvalue: setstringeventty read fonsetvalue write fonsetvalue; + //sender is tcustomstringcol + property ondataentered: notifyeventty read fondataentered write fondataentered; + //sender is tcustomstringcol + property oncopytoclipboard: updatestringeventty read foncopytoclipboard + write foncopytoclipboard; + //sender is tcustomstringcol + property onpastefromclipboard: updatestringeventty read fonpastefromclipboard + write fonpastefromclipboard; + //sender is tcustomstringcol + property ondrawcell: drawcelleventty read fondrawcell write fondrawcell; + end; + + tstringcol = class(tcustomstringcol) + published + property focusrectdist; + property textflags; + property textflagsactive; + property passwordchar; + property optionsedit1; //before optionsedit! + property optionsedit; + property font; + property datalist; + property valuedefault; + property valuefalse; + property valuetrue; + property fontselect; + property onsetvalue; + property ondataentered; + property oncopytoclipboard; + property onpastefromclipboard; + property ondrawcell; + end; + + stringcolclassty = class of tcustomstringcol; + + tfixcol = class(tcol) + private + fnumstart: integer; + fnumstep: integer; + fcaptions: tmsestringdatalist; + foptionsfix: fixcoloptionsty; + procedure settextflags(const Value: textflagsty); + procedure setnumstart(const Value: integer); + procedure setnumstep(const Value: integer); + procedure setcaptions(const Value: tmsestringdatalist); + function getcaptions: tmsestringdatalist; + function iscaptionsstored: Boolean; + procedure captionchanged(const sender: tdatalist; const aindex: integer); + procedure setoptionsfix(const avalue: fixcoloptionsty); + function getvisible: boolean; + procedure setvisible(const avalue: boolean); + protected + ftextinfo: drawtextinfoty; + procedure setoptions(const Value: coloptionsty); override; + procedure drawcell(const canvas: tcanvas); override; + procedure moverow(const fromindex,toindex: integer; const count: integer = 1); override; + procedure insertrow(const aindex: integer; const count: integer = 1); override; + procedure deleterow(const aindex: integer; const count: integer = 1); override; + procedure paint(var info: colpaintinfoty); override; + procedure rearange(const list: integerarty); override; + public + constructor create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); override; + destructor destroy; override; + property visible: boolean read getvisible write setvisible; + published + property linewidth; + property linecolor default defaultfixlinecolor; + property textflags: textflagsty read ftextinfo.flags write settextflags + default defaultfixcoltextflags; + property numstart: integer read fnumstart write setnumstart default 0; + property numstep: integer read fnumstep write setnumstep default 0; + property captions: tmsestringdatalist + read getcaptions write setcaptions stored iscaptionsstored; + property color default cl_parent; + property options: fixcoloptionsty read foptionsfix write setoptionsfix + default defaultfixcoloptions; + property font; + end; + fixcolclassty = class of tfixcol; + + tcolheaderfont = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + cellmergeflagty = (cmf_h,cmf_v,cmf_rline); + cellmergeflagsty = set of cellmergeflagty; + + tcolheader = class(tindexpersistent,iframe,iface,iimagelistinfo) + private + finfo: captioninfoty; + ffont: tcolheaderfont; + fcolor: colorty; + fhint: msestring; + fmergecols: integer; + fmergerows: integer; + fmergeflags: cellmergeflagsty; + fmergedcx: integer; + fmergedx: integer; + fmergedcy: integer; + fmergedy: integer; + frefcell: gridcoordty; + procedure setcaption(const avalue: msestring); + procedure settextflags(const avalue: textflagsty); + function getfont: tcolheaderfont; + procedure setfont(const Value: tcolheaderfont); + function isfontstored: Boolean; + function getframe: tfixcellframe; + procedure setframe(const avalue: tfixcellframe); + function getface: tfixcellface; + procedure setface(const avalue: tfixcellface); + procedure setcolor(const avalue: colorty); + procedure setmergecols(const avalue: integer); + procedure setmergerows(const avalue: integer); + procedure setimagelist(const avalue: timagelist); + procedure setimagenr(const avalue: imagenrty); + procedure setcolorglyph(const avalue: colorty); + procedure setimagepos(const avalue: imageposty); + procedure setimagedist(const avalue: integer); + procedure setcaptiondist(const avalue: integer); + procedure readcaptionpos(reader: treader); + protected + fgrid: tcustomgrid; + fframe: tfixcellframe; + fface: tfixcellface; + fautocellsize: sizety; + procedure defineproperties(filer: tfiler); override; + procedure changed; + procedure fontchanged(const sender: tobject); + procedure drawcell(const acanvas: tcanvas; const adest: rectty); virtual; + + //iframe + function getwidget: twidget; + procedure setframeinstance(instance: tcustomframe); + function getwidgetrect: rectty; + procedure setstaticframe(value: boolean); + function getstaticframe: boolean; + function widgetstate: widgetstatesty; + procedure scrollwidgets(const dist: pointty); + procedure clientrectchanged; + function getcomponentstate: tcomponentstate; + function getmsecomponentstate: msecomponentstatesty; + procedure invalidate; + procedure invalidatewidget; + procedure invalidaterect(const rect: rectty; const org: originty = org_client; + const noclip: boolean = false); + function getframestateflags: framestateflagsty; + //iface + function getclientrect: rectty; + procedure setlinkedvar(const source: tmsecomponent; var dest: tmsecomponent; + const linkintf: iobjectlink = nil); + procedure widgetregioninvalid; + function translatecolor(const acolor: colorty): colorty; + //iimagelistinfo + function getimagelist: timagelist; + public + constructor create(const aowner: tobject; + const aprop: tindexpersistentarrayprop); override; + destructor destroy; override; + procedure createfont; + procedure createframe; + procedure createface; + property mergedcx: integer read fmergedcx; + property mergedx: integer read fmergedx; + property mergedcy: integer read fmergedcy; + property mergedy: integer read fmergedy; + published + property color: colorty read fcolor write setcolor default cl_parent; + property caption: msestring read finfo.caption.text write setcaption; + property textflags: textflagsty read finfo.textflags write settextflags + default defaultcaptiontextflags; + property font: tcolheaderfont read getfont write setfont stored isfontstored; + property frame: tfixcellframe read getframe write setframe; + property face: tfixcellface read getface write setface; + property mergecols: integer read fmergecols write setmergecols default 0; + property mergerows: integer read fmergerows write setmergerows default 0; + property hint: msestring read fhint write fhint; + property imagelist: timagelist read finfo.imagelist write setimagelist; + property imagenr: imagenrty read finfo.imagenr write setimagenr default -1; + property imagedist: integer read finfo.imagedist write setimagedist + default 0; + property captiondist: integer read finfo.captiondist write setcaptiondist + default defaultshapecaptiondist; + property imagepos: imageposty read finfo.imagepos write setimagepos + default ip_center; + property colorglyph: colorty read finfo.colorglyph + write setcolorglyph default cl_glyph; + //cl_none -> no no glyph + end; + + datacolheaderoptionty = (dco_colsort,dco_wholecellsortclick, + dco_nodisabledsortindicator,dco_hintclippedtext, + dco_noautowidth); + datacolheaderoptionsty = set of datacolheaderoptionty; + + tdatacolheader = class(tcolheader) + private + foptions: datacolheaderoptionsty; + procedure setoptions(const avalue: datacolheaderoptionsty); + protected + procedure drawcell(const acanvas: tcanvas; const adest: rectty); override; + public + constructor create(const aowner: tobject; + const aprop: tindexpersistentarrayprop); override; + published + property options: datacolheaderoptionsty read foptions write setoptions + default [dco_hintclippedtext]; + end; + + tcolheaders = class(tindexpersistentarrayprop) + private + fgridprop: tgridprop; + ffixcol: boolean; + protected + fmergeflags: cellmergeflagsty; + procedure movecol(const curindex,newindex: integer); + procedure colcountchanged(const acount: integer); + procedure updatelayout(const cols: tgridarrayprop); + procedure dosizechanged; override; + public + constructor create(const agridprop: tgridprop); reintroduce; + end; + + tfixcolheaders = class(tcolheaders) + private + function getitems(const index: integer): tcolheader; + procedure setitems(const index: integer; const Value: tcolheader); + public + constructor create(const agridprop: tgridprop); + class function getitemclasstype: persistentclassty; override; + property items[const index: integer]: tcolheader read getitems + write setitems; default; + end; + + tdatacolheaders = class(tcolheaders) + private + function getitems(const index: integer): tdatacolheader; + procedure setitems(const index: integer; const Value: tdatacolheader); + public + class function getitemclasstype: persistentclassty; override; + property items[const index: integer]: tdatacolheader read getitems + write setitems; default; + end; + + tfixrow = class; + beforefixdrawcelleventty = procedure(const sender: tfixrow; const canvas: tcanvas; + var cellinfo: cellinfoty; var processed: boolean) of object; + drawfixcelleventty = procedure(const sender: tfixrow; const canvas: tcanvas; + const cellinfo: cellinfoty) of object; + + tfixrows = class; + tfixrow = class(tgridprop) + private + fheight: integer; + fnumstart: integer; + fnumstep: integer; + fcaptions: tdatacolheaders; + fcaptionsfix: tfixcolheaders; + foptionsfix: fixrowoptionsty; + fonbeforedrawcell: beforefixdrawcelleventty; + fonafterdrawcell: drawfixcelleventty; + procedure setheight(const Value: integer); + function getrowindex: integer; + procedure captionchanged(const sender: tarrayprop; const aindex: integer); + procedure setnumstart(const Value: integer); + procedure setnumstep(const Value: integer); + procedure settextflags(const Value: textflagsty); + procedure setcaptions(const Value: tdatacolheaders); + procedure setcaptionsfix(const Value: tfixcolheaders); + procedure setoptionsfix(const avalue: fixrowoptionsty); + function getvisible: boolean; + procedure setvisible(const avalue: boolean); + protected + ftextinfo: drawtextinfoty; + procedure datacolscountchanged(const acount: integer); + procedure fixcolscountchanged(const acount: integer); + procedure invalidatemaxsize(const acol: int32); + procedure cellchanged(const acol: integer); virtual; + procedure changed; override; + procedure updatelayout; override; + procedure updatemergedcells; + function step(getscrollable: boolean = true): integer; override; + procedure paint(const info: rowpaintinfoty); virtual; + procedure updateautocellsize(); + procedure drawcell(const canvas: tcanvas);{ virtual;} + procedure movecol(const curindex,newindex: integer; const aisfix: boolean); + procedure reorderdatacols(const neworder: integerarty); + procedure orderdatacols(const oldorder: integerarty); + procedure buttoncellevent(var info: celleventinfoty); + public + constructor create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); override; + destructor destroy; override; + procedure synctofontheight; + property rowindex: integer read getrowindex; + property visible: boolean read getvisible write setvisible; + published + property height: integer read fheight write setheight; + property textflags: textflagsty read ftextinfo.flags write settextflags + default defaultfixcoltextflags; + property numstart: integer read fnumstart write setnumstart default 0; + property numstep: integer read fnumstep write setnumstep default 0; + property captions: tdatacolheaders read fcaptions write setcaptions; + property captionsfix: tfixcolheaders read fcaptionsfix write setcaptionsfix; + property font; + property linecolor default defaultfixlinecolor; + property options: fixrowoptionsty read foptionsfix + write setoptionsfix default []; + property onbeforedrawcell: beforefixdrawcelleventty read fonbeforedrawcell + write fonbeforedrawcell; + property onafterdrawcell: drawfixcelleventty read fonafterdrawcell + write fonafterdrawcell; + end; + + tgridarrayprop = class(tindexpersistentarrayprop) + private + ffirstsize: integer; + ftotsize: integer; + foppositecount: integer; + ffirstopposite: integer; + flinewidth: integer; + flinecolor: colorty; + flinecolorfix: colorty; + fcolorselect: colorty; + fcoloractive: colorty; + fcolorfocused: colorty; + finnerframe: framety; + fcursor: cursorshapety; + fcolor: colorty; + procedure setlinewidth(const Value: integer); + procedure setlinecolor(const Value: colorty); + procedure setlinecolorfix(const Value: colorty); + procedure setcolorselect(const avalue: colorty); + procedure setcoloractive(avalue: colorty); + procedure setcolorfocused(avalue: colorty); + procedure setinnerframe(const avalue: framety); + procedure setinnerframe_left(const avalue: integer); + procedure setinnerframe_top(const avalue: integer); + procedure setinnerframe_right(const avalue: integer); + procedure setinnerframe_bottom(const avalue: integer); + procedure setcursor(const avalue: cursorshapety); + procedure setcolor(const avalue: colorty); + protected + freversedorder: boolean; + fgrid: tcustomgrid; + function geotoindex(const ageoindex: integer): integer; + function geoitems(const aindex: integer): tgridprop; + procedure updatelayout; virtual; + function getclientsize: integer; virtual; abstract; + procedure setoppositecount(const value: integer); + procedure setcount1(acount: integer; doinit: boolean); override; + procedure countchanged; virtual; + function scrollablecount: integer; + procedure dochange(const aindex: integer); override; + procedure getindexrange(startpos,length: integer; + out range: cellaxisrangety; ascrollables: boolean = true); + function itematpos(const pos: integer; + const getscrollable: boolean = true): integer; //-1 if none + procedure createitem(const index: integer; var item: tpersistent); override; + procedure fontchanged; + procedure checktemplate(const sender: tobject); + public + constructor create(aowner: tcustomgrid; aclasstype: gridpropclassty); reintroduce; + function fixindex(const index: integer): integer; + property oppositecount: integer read foppositecount write setoppositecount default 0; + property innerframe: framety read finnerframe write setinnerframe; + published + property cursor: cursorshapety read fcursor write setcursor default cr_default; + property linewidth: integer read flinewidth + write setlinewidth default defaultgridlinewidth; + property linecolor: colorty read flinecolor + write setlinecolor; + property linecolorfix: colorty read flinecolorfix + write setlinecolorfix default defaultfixlinecolor; + property color: colorty read fcolor write setcolor + default cl_default; + property colorselect: colorty read fcolorselect write setcolorselect + default cl_default; + property coloractive: colorty read fcoloractive write setcoloractive + default cl_none; + property colorfocused: colorty read fcolorfocused write setcolorfocused + default cl_none; + property innerframe_left: integer read finnerframe.left + write setinnerframe_left default 1; + property innerframe_top: integer read finnerframe.top + write setinnerframe_top default 1; + property innerframe_right: integer read finnerframe.right + write setinnerframe_right default 1; + property innerframe_bottom: integer read finnerframe.bottom + write setinnerframe_bottom default 1; + end; + + tcolsfont = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + tcolsfontselect = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + tcols = class(tgridarrayprop) + private + fwidth: integer; + foptions: coloptionsty; + foptions1: coloptions1ty; + ffocusrectdist: integer; + ffontactivenum: integer; + ffontfocusednum: integer; + ffontselect: tcolsfontselect; + ffont: tcolsfont; + function getcols(const index: integer): tcol; + procedure setwidth(const value: integer); + procedure setoptions(const avalue: coloptionsty); + procedure setoptions(const avalue: coloptionsty; const aforce: boolean); + procedure setoptions1(const Value: coloptions1ty); + procedure setfocusrectdist(const avalue: integer); + procedure setfontactivenum(const avalue: integer); + procedure setfontfocusednum(const avalue: integer); + function getfontselect: tcolsfontselect; + function isfontselectstored: Boolean; + procedure setfontselect(const avalue: tcolsfontselect); + procedure fontselectchanged(const sender: tobject); + function getfont: tcolsfont; + procedure setfont(const avalue: tcolsfont); + function isfontstored: Boolean; + protected + fdataupdating: integer; + procedure begindataupdate; virtual; + procedure enddataupdate; virtual; + function getclientsize: integer; override; + procedure paint(var info: colpaintinfoty; const scrollables: boolean = true); + procedure updaterowheight(const arow: integer; var arowheight: integer); + function totwidth: integer; + procedure rowcountchanged(const countbefore: int32; + const newcount: int32); virtual; + procedure updatelayout; override; + procedure countchanged; override; + procedure moverow(const curindex,newindex: integer; + const acount: integer = 1); virtual; + procedure insertrow(const index: integer; const acount: integer = 1) virtual; + procedure deleterow(const index: integer; const acount: integer = 1) virtual; + procedure rearange(const list: integerarty); virtual; + procedure resetpropwidth; + property options: coloptionsty read foptions + write setoptions default []; + property options1: coloptions1ty read foptions1 + write setoptions1 default []; + public + constructor create(aowner: tcustomgrid; aclasstype: gridpropclassty); + destructor destroy; override; + procedure invalidatemaxsize(const arow: integer = -1); + procedure createfont(); + procedure createfontselect(); + procedure move(const curindex,newindex: integer); override; + function mergedwidth(const acol: integer; const amerged: longword): integer; + //returns additional width + property cols[const index: integer]: tcol read getcols; default; + property focusrectdist: integer read ffocusrectdist + write setfocusrectdist default 0; + property fontselect: tcolsfontselect read getfontselect + write setfontselect stored isfontselectstored; + property font: tcolsfont read getfont + write setfont stored isfontstored; + published + property width: integer read fwidth + write setwidth default griddefaultcolwidth; + property fontactivenum: integer read ffontactivenum + write setfontactivenum default -1; + //index in grid.rowfonts + property fontfocusednum: integer read ffontfocusednum + write setfontfocusednum default -1; + //index in grid.rowfonts + end; + + trowstatelist = class(tcustomrowstatelist + {$ifdef mse_with_ifi},iifidatalink{$endif}) + private + fdirtyvisible: integer; + fdirtyrow: integer; + fdirtyrowheight: integer; + fdirtyautorowheight: integer; + ffolded: boolean; + fgrid: tcustomgrid; + fhiddencount: integer; + fvisiblerows: integerarty; + fvisiblerowmap: tintegerdatalist; + ffoldchangedrow: integer; + ftopypos: integer; + flinkfoldhidden: listlinkinfoty; + flinkfoldlevel: listlinkinfoty; + flinkissum: listlinkinfoty; + ffoldhiddensourcelock: integer; + ffoldlevelsourcelock: integer; + fissumsourcelock: integer; + procedure cleanfolding(arow: integer; visibleindex: integer); + function isvisible(const arow: integer): boolean; + procedure counthidden(var aindex: integer); + procedure setfoldlevel(const index: integer; avalue: byte); + procedure setfolded(const avalue: boolean); + procedure setheight(const index: integer; const avalue: integer); + procedure setlinewidth(const index: integer; avalue: rowlinewidthty); + function getrowypos(const index: integer): integer; + procedure setsourcefoldhidden1(const avalue: string); + procedure setsourcefoldhidden(const avalue: string); + procedure setsourcefoldlevel1(const avalue: string); + procedure setsourcefoldlevel(const avalue: string); + procedure setsourceissum1(const avalue: string); + procedure setsourceissum(const avalue: string); + procedure sourcenamechanged(const atag: integer); + {$ifdef mse_with_ifi} + //iifilink + function getifilinkkind: ptypeinfo; + //iificlient + procedure setifiserverintf(const aintf: iifiserver); + function getdefaultifilink: iificlient; virtual; + + //iifidatalink + procedure updateifigriddata(const sender: tobject; const alist: tdatalist); + procedure ifisetvalue(var avalue; var accept: boolean); + procedure getifivalue(var avalue); + procedure setifivalue(const avalue); + function getgriddata: tdatalist; reintroduce; + function getvalueprop: ppropinfo; + procedure updatereadonlystate; + {$endif} + protected + procedure sethidden(const index: integer; const avalue: boolean); override; + procedure setfoldissum(const index: integer; const avalue: boolean); override; + function getlinkdatatypes(const atag: integer): listdatatypesty; override; + procedure checksyncfoldlevelsource(const index: integer; + const acount: integer); + procedure checksyncfoldhiddensource(const index: integer; + const acount: integer); + procedure foldhiddentosource(const index: integer; const acount: integer); + procedure foldissumtosource(const index: integer; const acount: integer); + procedure checksyncfoldissumsource(const index: integer; + const acount: integer); + + function totchildrencount(const aindex: integer; + const acount: integer): integer; + procedure movegrouptoparent(const aindex: integer; const acount: integer); + //called before deleting of rows + procedure updatedeletedrows(const index: integer; const acount: integer); + procedure internalshow(var aindex: integer); + procedure internalhide(var aindex: integer); + procedure show(const aindex: integer); + procedure hide(const aindex: integer); + procedure initdirty; override; + procedure cleanvisible(visibleindex: integer); + procedure clean(arow: integer); reintroduce; + procedure cleanrowheight(const aindex: integer); + procedure invalidatedirtyrowheight(const arow: int32); + //-2 -> count change + procedure checkdirty(const arow: integer); override; + procedure checkdirtyautorowheight(const arow: integer); + procedure recalchidden; override; + procedure readstate(const reader; const acount: integer; + const name: msestring); override; + function getstatdata(const index: integer): msestring; override; + procedure setstatdata(const index: integer; const value: msestring); + override; + function internalheight(const aindex: integer): integer; + //no valid checks + function internalystep(const aindex: integer): integer; overload; + //no valid checks + procedure internalystep(const aindex: integer; out ay: integer; + out acy:integer); overload; + //no valid checks + public + constructor create(const aowner: tcustomgrid); reintroduce; + destructor destroy; override; + + procedure listdestroyed(const sender: tdatalist); override; + function getsourcecount: integer; override; + function getsourceinfo(const atag: integer): plistlinkinfoty; override; + procedure linksource(const source: tdatalist; const atag: integer); override; + procedure sourcechange(const sender: tdatalist; + const index: integer); override; + procedure foldleveltosource(const index: integer; const acount: integer); + + procedure clearmemberitem(const subitem: integer; + const index: integer); override; + procedure setmemberitem(const subitem: integer; + const index: integer; const avalue: integer); override; + + procedure change(const index: integer); override; + function cellrow(const arow: integer): integer; + function visiblerow(const arowindex: integer): integer; + //returns count of visible previous rows + function visiblerowcount: integer; + function visiblerowtoindex(const avisibleindex: integer): integer; + function visiblerows1(const astart: integer; const aendy: integer): integerarty; + procedure updatefoldinfo(const rows: integerarty; + var infos: rowfoldinfoarty); + function visiblerowstep(const arow: integer; const step: integer; + const autoappend: boolean): integer; + function rowhidden(const arow: integer): boolean; + function nearestvisiblerow(const arow: integer): integer; + procedure getfoldstate(const arow: integer; out aisvisible: boolean; + out afoldlevel: byte; out ahaschildren,aisopen: boolean); + procedure hidechildren(const arow: integer); + procedure showchildren(const arow: integer); + property folded: boolean read ffolded write setfolded; + procedure setupfoldinfo(asource: pbyte; const acount: integer); + property hidden[const index: integer]: boolean read gethidden write sethidden; + property foldlevel[const index: integer]: byte read getfoldlevel + write setfoldlevel; //0..63 + property foldissum[const index: integer]: boolean read getfoldissum + write setfoldissum; + property height[const index: integer]: integer read getheight + write setheight; + property linewidth[const index: integer]: rowlinewidthty + read getlinewidth write setlinewidth; + //-1 = default + function currentrowheight(const index: integer): integer; + property rowypos[const index: integer]: integer read getrowypos; + function rowindex(const aypos: integer): integer; + procedure fillfoldlevel(const index: integer; const acount: integer; + const avalue: byte); + published + property sourcefoldhidden: string read flinkfoldhidden.name + write setsourcefoldhidden; + property sourcefoldlevel: string read flinkfoldlevel.name + write setsourcefoldlevel; + property sourceissum: string read flinkissum.name + write setsourceissum; + end; + + tdatacols = class(tcols) + private + fselectedrow: integer; //-1 none, -2 more than one + fselectedrowcount: int32; + fsortcol: integer; + fsortcoldefault: integer; + fnewrowcol: integer; + fchangelock: integer; + flastvisiblecol: integer; + function getcols(const index: integer): tdatacol; + procedure setcols(const index: integer; const Value: tdatacol); + function getselectedcells: gridcoordarty; + procedure setselectedcells(const Value: gridcoordarty); + function getselectedrows: integerarty; + procedure setselectedrows(const avalue: integerarty); + function getselected(const cell: gridcoordty): boolean; + procedure setselected(const cell: gridcoordty; const Value: boolean); + function roworderinvalid: boolean; //true if accepted + procedure checkindexrange; + procedure setsortcol(const avalue: integer); + procedure setsortcoldefault(const avalue: integer); + procedure setnewrowcol(const avalue: integer); + function getrowselected(const index: integer): boolean; + procedure setrowselected(const index: integer; const avalue: boolean); + function getreadonly: boolean; + procedure setreadonly(const avalue: boolean); + protected + frowstate: trowstatelist; + fscrollsize: integer; + ffirsthscrollindex: integer; + procedure beginchangelock; + procedure endchangelock; + procedure datasourcechanged; virtual; + procedure begindataupdate; override; + procedure enddataupdate; override; + procedure dosizechanged; override; + procedure countchanged; override; + procedure mergechanged(const arow: integer); + procedure rearange(const list: integerarty); override; + procedure setcount1(acount: integer; doinit: boolean); override; + procedure setrowcountmax(const value: integer); + procedure rowcountchanged(const countbefore: int32; + const newcount: int32); override; + procedure createitem(const index: integer; var item: tpersistent); override; + procedure updatelayout; override; + function colatpos(const x: integer; + const getscrollable: boolean = true): integer; + //0..count-1, invalidaxis if invalid + procedure moverow(const fromindex,toindex: integer; + const acount: integer = 1); override; + procedure insertrow(const index: integer; + const acount: integer = 1); override; + procedure deleterow(const index: integer; + const acount: integer = 1); override; + procedure changeselectedrange(const start,oldend,newend: gridcoordty; + calldoselectcell: boolean); virtual; + procedure beginselect; + procedure endselect; + procedure decselect; + + function hassortstat: boolean; + function hasdatastat: boolean; + procedure dostatread(const reader: tstatreader; + const aorder: boolean); virtual; + procedure dostatwrite(const writer: tstatwriter; + const aorder: boolean); virtual; + + function cancopy: boolean; + function canpaste: boolean; + procedure updatedatastate(var accepted: boolean); overload; virtual; + + public + constructor create(aowner: tcustomgrid; aclasstype: gridpropclassty); + destructor destroy; override; + function sortfunc(const l,r: integer): integer; + function updatedatastate: boolean; overload; + procedure move(const curindex,newindex: integer); override; + function previosvisiblecol(aindex: integer): integer; + //invalidaxis if none + function nextvisiblecol(aindex: integer): integer; + //invalidaxis if none + property lastvisiblecol: integer read flastvisiblecol; + function rowempty(const arow: integer): boolean; + property cols[const index: integer]: tdatacol read getcols + write setcols; default; + function colbyname(const aname: string): tdatacol; + //name is case sensitive + function datalistbyname(const aname: string): tdatalist; //can be nil + function colsubdatainfo(const aname: string): subdatainfoty; + + procedure clearselection; + function hasselection: boolean; + property selectedrowcount: int32 read fselectedrowcount; + function selectedcellcount: integer; + function hascolselection: boolean; + property selectedcells: gridcoordarty read getselectedcells + write setselectedcells; + property selectedrows: integerarty read getselectedrows + write setselectedrows; + property rowselected[const index: integer]: boolean read getrowselected + write setrowselected; + property selected[const cell: gridcoordty]: boolean read Getselected write Setselected; + //col < 0 and row < 0 -> whole grid, col < 0 -> whole col, + //row = < 0 -> whole row + procedure setselectedrange(const rect: gridrectty; const value: boolean; + const calldoselectcell: boolean = false; + const checkmultiselect: boolean = false); overload; + procedure setselectedrange(const start,stop: gridcoordty; + const value: boolean; + const calldoselectcell: boolean = false; + const checkmultiselect: boolean = false); overload; virtual; + procedure mergecols(const arow: integer; const astart: longword = 0; + const acount: longword = bigint); + procedure unmergecols(const arow: integer = invalidaxis); + //invalidaxis = all + property rowstate: trowstatelist read frowstate; + function defaultrowheight: integer; + property readonly: boolean read getreadonly write setreadonly; + published + property sortcol: integer read fsortcol write setsortcol default -1; + //-1 -> all + property sortcoldefault: integer read fsortcoldefault + write setsortcoldefault default -1; + //-1 -> no + property newrowcol: integer read fnewrowcol write setnewrowcol default -1; + //-1 -> actual + property width; + property options default defaultdatacoloptions; + property options1 default defaultdatacoloptions1; + property font; + property fontselect; + property linewidth; + property linecolor default defaultdatalinecolor; + property linecolorfix; + end; + + tdrawcols = class(tdatacols) + private + function getcols(const index: integer): tdrawcol; + public + constructor create(aowner: tcustomgrid); + class function getitemclasstype: persistentclassty; override; + property cols[const index: integer]: tdrawcol read getcols; default; + published + property focusrectdist; + end; + + tstringcols = class(tdatacols) + private + foptionsedit: stringcoleditoptionsty; + foptionsedit1: optionsedit1ty; + ftextflags: textflagsty; + ftextflagsactive: textflagsty; + function getcols(const index: integer): tstringcol; + procedure settextflags(avalue: textflagsty); + procedure settextflagsactive(avalue: textflagsty); + procedure setoptionsedit(avalue: stringcoleditoptionsty); + procedure setoptionsedit1(avalue: optionsedit1ty); + protected + function getcolclass: stringcolclassty; virtual; + procedure updatedatastate(var accepted: boolean); override; + public + constructor create(aowner: tcustomgrid); + class function getitemclasstype: persistentclassty; override; + property cols[const index: integer]: tstringcol read getcols; default; //last! + published + property focusrectdist; + property textflags: textflagsty read ftextflags write settextflags + default defaultcoltextflags; + property textflagsactive: textflagsty read ftextflagsactive + write settextflagsactive default defaultactivecoltextflags; + property optionsedit: stringcoleditoptionsty read foptionsedit + write setoptionsedit default defaultstringcoleditoptions; + property optionsedit1: optionsedit1ty read foptionsedit1 + write setoptionsedit1 default defaultoptionsedit1; + end; + + tfixcols = class(tcols) + private + function getcols(const index: integer): tfixcol; + procedure setcols(const index: integer; const Value: tfixcol); + protected + procedure countchanged; override; + procedure updatelayout; override; + function colatpos(const x: integer): integer; //-cout..-1, 0 if invalid + public + constructor create(aowner: tcustomgrid); + class function getitemclasstype: persistentclassty; override; + property cols[const index: integer]: tfixcol read getcols write setcols; default; + //index -1..-count + published + property width; + property linewidth; + property linecolor default defaultfixlinecolor; + property linecolorfix; + property oppositecount; + end; + + tfixrows = class(tgridarrayprop) + private + function getrows(const index: integer): tfixrow; + procedure setrows(const index: integer; const Value: tfixrow); + protected + function getclientsize: integer; override; + procedure updatelayout; override; + procedure updatemergedcells; + function rowatpos(const y: integer): integer; //-count..-1, 0 if invalid + procedure paint(const info: rowspaintinfoty); + procedure movecol(const curindex,newindex: integer; const isfix: boolean); + procedure datacolscountchanged; + procedure fixcolscountchanged; + procedure reorderdatacols(const neworder: integerarty); + procedure orderdatacols(const oldorder: integerarty); + procedure dofontheightdelta(var delta: integer); + public + constructor create(aowner: tcustomgrid); + class function getitemclasstype: persistentclassty; override; + procedure synctofontheight; + property rows[const index: integer]: tfixrow read getrows write setrows; default; + //index -1..-count + published + property oppositecount; + property linewidth; + property linecolor default defaultfixlinecolor; + property linecolorfix default defaultfixlinecolor; + end; + + tgridframe = class(tcustomautoscrollframe) + protected + function getscrollbarclass(vert: boolean): framescrollbarclassty; override; + function actualcolorclient(): colorty override; + public + constructor create(const aintf: iscrollframe; const owner: twidget; + const autoscrollintf: iautoscrollframe); + published + property levelo default -2; + property leveli; + property framewidth; + property colorframe; + property colorframeactive; + property colorframedisabled; + property colorframemouse; + property colorframeclicked; + property colorframedefault; + property colordkshadow; + property colorshadow; + property colorlight; + property colorhighlight; + property colordkwidth; + property colorhlwidth; + property hiddenedges; + property colorclient {default cl_foreground}; + property framei_left default 0; + property framei_top default 0; + property framei_right default 0; + property framei_bottom default 0; + + property frameimage_list; + property frameimage_left; + property frameimage_top; + property frameimage_right; + property frameimage_bottom; + property frameimage_offset; + property frameimage_offset1; + property frameimage_offsetdisabled; + property frameimage_offsetmouse; + property frameimage_offsetclicked; + property frameimage_offsetactive; + property frameimage_offsetfocused; +{ + property frameimage_offsetactivemouse; + property frameimage_offsetactiveclicked; +} + property frameface_list; + property frameface_offset; + property frameface_offset1; + property frameface_offsetdisabled; + property frameface_offsetmouse; + property frameface_offsetclicked; + property frameface_offsetactive; + property frameface_offsetfocused; +{ + property frameface_offsetactivemouse; + property frameface_offsetactiveclicked; +} + property options; + property optionsskin; + + property sbvert; + property sbhorz; + property caption; + property captiontextflags; + property captionpos; + property captiondist; + property captionoffset; + property font; + property localprops; //before template + property localprops1; //before template + property template; + end; + + trowfontarrayprop = class(tpersistentarrayprop) + private + fgrid: tcustomgrid; + procedure setitems(const index: integer; const avalue: tfont); + protected + function getitems(const index: integer): tfont; + procedure createitem(const index: integer; var item: tpersistent); override; + public + constructor create(const aowner: tcustomgrid); + class function getitemclasstype: persistentclassty; override; + //used in dumpunitgroups + property items[const index: integer]: tfont read getitems + write setitems; default; + end; + + cellinnerlevelty = (cil_all,cil_noline,cil_paint,cil_inner); + cellselectmodety = (csm_select,csm_deselect,csm_reverse); + selectcellmodety = (scm_cell,scm_row,scm_col); + + optionfoldty = (of_insertsamelevel,of_deletetree,of_shiftdeltoparent, + of_shiftchildren,of_validatelevel); + optionsfoldty = set of optionfoldty; + + gridnotifyeventty = procedure(const sender: tcustomgrid) of object; + griddataeventty = procedure(const sender: tcustomgrid; + const acell: gridcoordty) of object; + griddatablockeventty = procedure(const sender: tcustomgrid; + const acell: gridcoordty; const acount: integer) of object; + gridblockmovingeventty = procedure(const sender: tcustomgrid; + var fromindex,toindex,acount: integer) of object; + gridblockmovedeventty = procedure(const sender: tcustomgrid; + const fromindex,toindex,acount: integer) of object; + gridbeforeblockeventty = procedure(const sender: tcustomgrid; + var aindex,acount: integer) of object; + gridblockeventty = procedure(const sender: tcustomgrid; + const aindex: integer; const acount: integer) of object; + gridsorteventty = procedure(const sender: tcustomgrid; + const lindex,rindex: integer; + var aresult: integer) of object; + gridmorerowseventty = procedure(const sender: tcustomgrid; + const count: integer) of object; + //negative -> before row 0 + gridscrolleventty = procedure(const sender: tcustomgrid; + var step: integer) of object; + copyselectioneventty = procedure(const sender: tcustomgrid; + var handled: boolean) of object; + pasteselectioneventty = procedure(const sender: tcustomgrid; + var handled: boolean) of object; + + tcustomgrid = class(tpublishedwidget,iautoscrollframe,iobjectpicker,iscrollbar, + idragcontroller,istatfile + {$ifdef mse_with_ifi},iifigridlink{$endif}, + iassistiveclientgrid) + private + frepeater: tsimpletimer; + frepeataction: focuscellactionty; + fystep: integer; + ffirstvisiblerow: integer; + flastvisiblerow: integer; + fvisiblerows: integerarty; + fvisiblerowfoldinfo: rowfoldinfoarty; + fvisiblerowsbase: integer; //number of visible rows below scrollwindow + + flayoutupdating: integer; + fvisiblerowsupdating: integer; + fnullchecking: integer; + frowdatachanging: integer; + frowdatachangestart: int32; + fnoshowcaretrect: integer; + finvalidatedcells: gridcoordarty; + + foncellevent: celleventty; + fonrowsmoved: gridblockmovedeventty; + fonrowdatachanged: griddataeventty; + fonrowsdatachanged: griddatablockeventty; + fonrowsinserting: gridbeforeblockeventty; + fonrowsinserted: gridblockeventty; + fonrowsdeleting: gridbeforeblockeventty; + fonrowsdeleted: gridblockeventty; + fonrowcountchanged: gridnotifyeventty; + fonlayoutchanged: gridnotifyeventty; + fonbeforeupdatelayout: gridnotifyeventty; + fonsort: gridsorteventty; + + fdatarowlinewidth: integer; + fdatarowlinecolor: colorty; + fdatarowlinecolorfix: colorty; + + foncolmoved: gridblockmovedeventty; + fonselectionchanged: notifyeventty; + fgridframecolor: colorty; + frowcolors: tcolorarrayprop; + frowfonts: trowfontarrayprop; + fmouseparkcell: gridcoordty; + fclickedcell: gridcoordty; + fclickedcellbefore: gridcoordty; + + fstatfile: tstatfile; + fstatvarname: msestring; + + fonkeydown: keyeventty; + + fmouserefpos: pointty; + + fwheelscrollheight: integer; + fonscrollrows: gridscrolleventty; + + fonsortchanged: gridnotifyeventty; + fdatarowheightmin: integer; + fdatarowheightmax: integer; + foptionsfold: optionsfoldty; + foncopyselection: copyselectioneventty; + fonpasteselection: pasteselectioneventty; + fongetmorerows: gridmorerowseventty; + foncolmoving: gridblockmovingeventty; + fonrowsmoving: gridblockmovingeventty; + fonrowsmodified: notifyeventty; + fstatpriority: integer; +{$ifdef mse_with_ifi} + fifilink: tifigridlinkcomp; + fonedited: notifyeventty; + fnorowedit: boolean; + procedure ifirowchange; + function getifilinkkind: ptypeinfo; + procedure setifilink(const avalue: tifigridlinkcomp); + //iifidatalink + procedure updateifigriddata(const sender: tobject; const alist: tdatalist); + function getgriddata: tdatalist; + function getvalueprop: ppropinfo; + procedure getifivalue(var avalue); + procedure setifivalue(const avalue); + procedure updatereadonlystate; + //iifigridlink + function getrowstate: tcustomrowstatelist; +{$endif} + procedure setframe(const avalue: tgridframe); + function getframe: tgridframe; + procedure setstatfile(const Value: tstatfile); + + procedure setrowcount(value: integer); + procedure setrowcountmax(const value: integer); + procedure setdatacols(const Value: tdatacols); + procedure setfixcols(const Value: tfixcols); + procedure setfixrows(const Value: tfixrows); + procedure setcol(const value: integer); + procedure setrow(const value: integer); + + procedure killrepeater; + procedure startrepeater(state: gridstatety; time: integer); + procedure repeatproc(const sender: tobject); + + procedure calcpropcolwidthref; + procedure updatevisiblerows; + procedure setdatarowlinewidth(const Value: integer); + procedure setdatarowlinecolor(const Value: colorty); + procedure setdatarowlinecolorfix(const Value: colorty); + + procedure decodepickobject(code: integer; out kind: pickobjectkindty; + out cell: gridcoordty; out col: tcol; out row: tfixrow); + procedure setgridframecolor(const Value: colorty); + procedure setrowcolors(const Value: tcolorarrayprop); + procedure setrowfonts(const Value: trowfontarrayprop); + function getrowcolorstate(index: integer): rowstatenumty; + procedure setrowcolorstate(index: integer; const Value: rowstatenumty); + function getrowlinecolorstate(index: integer): rowstatenumty; + procedure setrowlinecolorstate(index: integer; const Value: rowstatenumty); + function getrowlinecolorfixstate(index: integer): rowstatenumty; + procedure setrowlinecolorfixstate(index: integer; const Value: rowstatenumty); + function getrowfontstate(index: integer): rowstatenumty; + procedure setrowfontstate(index: integer; const Value: rowstatenumty); + procedure setdragcontroller(const avalue: tdragcontroller); + function getrowreadonlystate(index: integer): boolean; + procedure setrowreadonlystate(index: integer; const avalue: boolean); + function getrowhidden(index: integer): boolean; + procedure setrowhidden(index: integer; const avalue: boolean); + function getrowfoldlevel(index: integer): byte; + procedure setrowfoldlevel(index: integer; const avalue: byte); + function getrowfoldissum(index: integer): boolean; + procedure setrowfoldissum(index: integer; const avalue: boolean); + function getrowheight(index: integer): integer; + procedure setrowheight(index: integer; avalue: integer); + + procedure setzebra_color(const avalue: colorty); + procedure setzebra_start(const avalue: integer); + procedure setzebra_height(const avalue: integer); + procedure setzebra_step(const avalue: integer); + function getsorted: boolean; + procedure setsorted(const avalue: boolean); + function getfolded: boolean; + procedure setfolded(const avalue: boolean); + function getrowstatelist: trowstatelist; + procedure setrowstatelist(const avalue: trowstatelist); + function getrowlinewidth(index: integer): rowlinewidthty; + procedure setrowlinewidth(index: integer; const avalue: rowlinewidthty); + function doonsort(const l,r: integer): integer; + procedure readgridframewidth(reader: treader); + function getrowwindowpos: int32; + procedure setrowwindowpos(const avalue: int32); + function getcolwindowpos: int32; + procedure setcolwindowpos(const avalue: int32); + function getcellwindowpos: pointty; + procedure setcellwindowpos(const avalue: pointty); + protected + fupdating: integer; + ffocuscount: integer; + fcellvaluechecking: integer; + flastcol: integer; + fpropcolwidthref: integer; + fzebra_start: integer; + fzebra_color: colorty; + fzebra_height: integer; + fzebra_step: integer; + ffocusedcell: gridcoordty; + fmousecell: gridcoordty; + fmouseeventcol: integer; + factiverow: integer; + fstartanchor,fendanchor: gridcoordty; + foptionsgrid: optionsgridty; + foptionsgrid1: optionsgrid1ty; + fstate: gridstatesty; + fstate1: gridstates1ty; + fshowcell: gridcoordty; + fshowcellmode: cellpositionty; + ffixcols: tfixcols; + ffixrows: tfixrows; + fdatacols: tdatacols; + fdatarowheight: integer; + frowcount: integer; + frowcountmax: integer; + fscrollrect: rectty; + fdatarect,fdatarectx,fdatarecty: rectty; + //origin = clientrect.pos + frootbrushorigin: pointty; + fbrushorigin: pointty; + //origin windowpos + fdragcontroller: tdragcontroller; + fobjectpicker: tobjectpicker; + fpickkind: pickobjectkindty; + fnumoffset: integer; //for fixcols + fnonullcheck: integer; + fnocheckvalue: integer; + fappendcount: integer; + flastcellpos: pointty; + flastcellzone: cellzonety; + class function classskininfo: skininfoty; override; + + function checkrowindex(var aindex: integer): boolean; + procedure setselected(const cell: gridcoordty; + const avalue: boolean); virtual; + procedure internalselectionchanged; + procedure setoptionsgrid(const avalue: optionsgridty); virtual; + function updatesortcol(const avalue: integer): integer; virtual; + //used in dbgrid switching index + function getsortdescend(const acol: integer): boolean; + procedure checkrowreadonlystate; virtual; + procedure checkneedsrowheight; + procedure updaterowheight(const arow: integer; var arowheight: integer); + + function setuserinput(const avalue: boolean): boolean; //returns old value + procedure resetuserinput(const avalue: boolean); + procedure doinsertrow(const sender: tobject); virtual; + procedure doappendrow(const sender: tobject); virtual; + function deleterowconfirmation(): boolean; + procedure dodeleterow(const sender: tobject); virtual; + procedure dodeleteselectedrows(const sender: tobject); virtual; + procedure dodeleterows(const sender: tobject); + procedure docopycells(const sender: tobject); + procedure dopastecells(const sender: tobject); + + procedure initeventinfo(const cell: gridcoordty; eventkind: celleventkindty; + out info: celleventinfoty); + procedure invalidate; + procedure invalidatesinglecell(const cell: gridcoordty); + function caninvalidate: boolean; + function docheckcellvalue: boolean; + procedure dolayoutchanged; virtual; + procedure internalupdatelayout(const force: boolean = false); + procedure updatelayout; virtual; + function intersectdatarect(var arect: rectty): boolean; + procedure setdatarowheight(const value: integer); + function getcaretcliprect: rectty; override; + procedure checkdatacell(const coord: gridcoordty); + procedure datacellerror(const coord: gridcoordty); + procedure error(aerror: griderrorty; text: string = ''); + procedure indexerror(row: boolean; index: integer; text: string = ''); + + procedure defineproperties(filer: tfiler); override; + function getdisprect: rectty; override; + procedure dofontheightdelta(var delta: integer); override; + procedure fontchanged; override; + procedure clientrectchanged; override; + procedure internalcreateframe; override; + function getscrollrect: rectty; + procedure setscrollrect(const rect: rectty); + function scrollcaret(const vertical: boolean): boolean; virtual; + procedure firstcellclick(const cell: gridcoordty; + var info: mouseeventinfoty); virtual; + function getzebrastart: integer; virtual; + function getnumoffset: integer; virtual; + + function createdatacols: tdatacols; virtual; + procedure createdatacol(const index: integer; out item: tdatacol); virtual; + function createfixcols: tfixcols; virtual; + function createfixrows: tfixrows; virtual; + procedure initcellinfo(var info: cellinfoty); virtual; + function cellhasfocus: boolean; virtual; + + procedure colchanged(const sender: tcol); + procedure cellchanged(const sender: tcol; const row: integer); + procedure focusedcellchanged; virtual; + procedure rowchanged(const arow: integer); virtual; + procedure rowstatechanged(const arow: integer); virtual; + procedure scrolled(const dist: pointty); virtual; + function hascolumnsort: boolean; + procedure sortchanged(const all: boolean); + procedure checkinvalidate; + function startanchor: gridcoordty; + function endanchor: gridcoordty; + + procedure doselectionchanged; virtual; + procedure docolmoved(const fromindex,toindex: integer); virtual; + procedure dorowsmoved(const fromindex,toindex,count: integer); virtual; + procedure dorowsinserting(var index,count: integer); virtual; + procedure dorowsinserted(const index,count: integer); virtual; + procedure dorowsdeleting(var index,count: integer); virtual; + procedure dorowsdeleted(index,count: integer); virtual; + procedure dorowsmodified; + procedure doedited(); + procedure dorowsdatachanged(const acell: gridcoordty; + const acount: integer); virtual; + procedure dorowcountchanged(const countbefore,newcount: integer); virtual; + procedure docellevent(var info: celleventinfoty); virtual; + procedure cellmouseevent(const acell: gridcoordty; var info: mouseeventinfoty; + const acellinfopo: pcelleventinfoty = nil; + const aeventkind: celleventkindty = cek_none); + procedure dofocusedcellposchanged; virtual; + function isfirstrow: boolean; virtual; + function islastrow: boolean; virtual; + + procedure internalinsertrow(var aindex: integer; var acount: integer; + const auserinput: boolean); virtual; + procedure internaldeleterow(var aindex: integer; var acount: integer; + const auserinput: boolean); virtual; + function internalsort(const sortfunc: indexsortcomparemethodty; + var refindex: integer): boolean; + //true if moved + procedure updaterowdata; virtual; + + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + + procedure doasyncevent(var atag: integer) override; + procedure loaded; override; + procedure doexit; override; + procedure doenter; override; + procedure doactivate; override; + procedure dodeactivate; override; + procedure activechanged; override; + procedure getautopaintsize(var asize: sizety) override; + procedure mouseevent(var info: mouseeventinfoty); override; + procedure clientmouseevent(var info: mouseeventinfoty); override; + procedure domousewheelevent(var info: mousewheeleventinfoty); override; + procedure dokeydown(var info: keyeventinfoty); override; + procedure dokeyup(var info: keyeventinfoty); override; + procedure dopaintforeground(const acanvas: tcanvas); override; + procedure dobeforepaint(const canvas: tcanvas); override; + procedure doafterpaint(const canvas: tcanvas); override; + function getnoscroll(): boolean override; + procedure drawfocusedcell(const acanvas: tcanvas); virtual; + procedure drawcellbackground(const acanvas: tcanvas); + procedure drawcelloverlay(const acanvas: tcanvas); + + function caninsertrow: boolean; virtual; + function canappendrow: boolean; virtual; + function candeleterow: boolean; virtual; + function canmoverow: boolean; virtual; + + procedure updatepopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); override; + function rowatpos(y: integer): integer; + //0..rowcount-1, invalidaxis if invalid, client origin + function rowpos(arow: integer): integer; + //client origin + function ystep: integer; + function mergestart(const acol: integer; const arow: integer): integer; + function mergeend(const acol: integer; const arow: integer): integer; + function getmerged(const arow: integer): longword; + function nextfocusablecol(const acol: integer; const aleft: boolean; + const arow: integer; const noreadonly: boolean): integer; + procedure checkcellvalue(var accept: boolean); virtual; + //store edited value to grid + procedure checkmorerows(const acount: integer); + procedure beforefocuscell(const cell: gridcoordty; + const selectaction: focuscellactionty); virtual; + procedure afterfocuscell(const cellbefore: gridcoordty; + const selectaction: focuscellactionty); virtual; + function wheelheight: integer; + function calcshowshift(const rect: rectty; + const position: cellpositionty): pointty; + procedure focusrow(const arow: integer; const action: focuscellactionty; + const noreadonly: boolean; + const selectmode: selectcellmodety = scm_cell); + function doremoveappinsrow(const oldrow,newrow: integer): boolean; + //true if removed + function hassort: boolean; + function canautoappend: boolean; virtual; + + + //idragcontroller + function getdragrect(const apos: pointty): rectty; override; + //iscrollbar + procedure scrollevent(sender: tcustomscrollbar; event: scrolleventty); virtual; + + //idragcontroller + //iobjectpicker + function getcursorshape(const sender: tobjectpicker; + var shape: cursorshapety): boolean; + procedure getpickobjects(const sender: tobjectpicker; + var objects: integerarty); + procedure beginpickmove(const sender: tobjectpicker); + procedure pickthumbtrack(const sender: tobjectpicker); + procedure endpickmove(const sender: tobjectpicker); + procedure cancelpickmove(const sender: tobjectpicker); + procedure paintxorpic(const sender: tobjectpicker; const canvas: tcanvas); + + //istatfile + procedure dostatread(const reader: tstatreader); virtual; + procedure dostatwrite(const writer: tstatwriter); virtual; + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + + procedure beginnullchecking; + procedure endnullchecking; + procedure beginnonullcheck; + procedure endnonullcheck; + procedure beginnocheckvalue; + procedure endnocheckvalue; + function nocheckvalue: boolean; + procedure reorderrow; + + function getiassistiveclient(): iassistiveclient; override; + //iassistiveclient + function getassistiveflags(): assistiveflagsty; override; + //iassistiveclientgrid + function getassistivecellcaption(const acell: gridcoordty): msestring virtual; + function getassistivecelltext(const acell: gridcoordty; + out aflags: assistiveflagsty): msestring virtual; + function getassistivefocusedcell(): gridcoordty; + function getassistivegridinfo(): assistivegridinfoty virtual; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + + procedure initnewcomponent(const ascale: real); override; + procedure synctofontheight; override; + procedure dragevent(var info: draginfoty); override; + function internaldragevent(var info: draginfoty): boolean; virtual; + //true if processed + function actualcursor(const apos: pointty): cursorshapety; override; + + procedure beginupdate; + procedure endupdate(const nosort: boolean = false; + const invalidrowstart: int32 = 0); + function updating: boolean; reintroduce; + function calcminscrollsize: sizety; override; + procedure layoutchanged; + function cellclicked: boolean; + procedure rowdatachanged; overload; + procedure rowdatachanged(const acell: gridcoordty; + const count: integer = 1); overload; + //acell.col = invalidaxis -> col unknown + + procedure rowup(const action: focuscellactionty = fca_focusin; + const nowrap: boolean = false) virtual; + procedure rowdown(const action: focuscellactionty = fca_focusin; + const nowrap: boolean = false) virtual; + procedure pageup(const action: focuscellactionty = fca_focusin); virtual; + procedure pagedown(const action: focuscellactionty = fca_focusin); virtual; + procedure wheelup(const action: focuscellactionty = fca_focusin); virtual; + procedure wheeldown(const action: focuscellactionty = fca_focusin); virtual; + procedure lastrow(const action: focuscellactionty = fca_focusin); virtual; + procedure firstrow(const action: focuscellactionty = fca_focusin); virtual; + + procedure colstep(const action: focuscellactionty; const step: integer; + const rowchange: boolean; + const nocolwrap: boolean; + const noreadonly: boolean); virtual; + //step > 0 -> right, step < 0 left + + function hasdata: boolean; + function canexitrow(const force: boolean = false): boolean; + function cellexiting: boolean; + + function gridprop(const coord: gridcoordty): tgridprop; //nil if none + function isdatacell(const coord: gridcoordty): boolean; + function isvalidcell(const coord: gridcoordty): boolean; + function isfixrow(const coord: gridcoordty): boolean; + function isfixcol(const coord: gridcoordty): boolean; + function rowvisible(const arow: integer): integer; + //0 -> fully visible, < 0 -> below > 0 above + function rowsperpage: integer; + function cellatpos(const apos: pointty; + out coord: gridcoordty): cellkindty; overload; + //origin = paintrect.pos + function cellatpos(const apos: pointty): gridcoordty; overload; + function cellrect(const cell: gridcoordty; + const innerlevel: cellinnerlevelty = cil_all; + const nomerged: boolean = false; + const acellorigin: boolean = false): rectty; + //origin = paintrect.pos if acellorigin = false, + //cell origin otherwise + function clippedcellrect(const cell: gridcoordty; + const innerlevel: cellinnerlevelty = cil_all): rectty; + //origin = paintrect.pos, clipped by datarect + function cellvisible(const acell: gridcoordty): boolean; + //returns row.visible and col.visible, independent from scrolling + procedure invalidatecell(const cell: gridcoordty); + procedure invalidatefocusedcell; + procedure invalidaterow(const arow: integer); + + function selectcell(const cell: gridcoordty; + const amode: cellselectmodety; + const checkmultiselect: boolean = false): boolean; + //true if accepted + function getselectedrange: gridrectty; //selected by focuscell() +// function getselectedrows: integerarty; + //moved to tdatacols.selectedrows + + function focuscell(cell: gridcoordty; + selectaction: focuscellactionty = fca_focusin; + const selectmode: selectcellmodety = scm_cell; + const ashowcell: cellpositionty = cep_nearest): boolean; virtual; + //true if ok + procedure focuscolbyname(const aname: string); + //case sensitive + function focusedcellvalid: boolean; + function rowremoving: boolean; + function scrollingcol: boolean; //true if focusedcolvalid and no co_nohscroll + function noscrollingcol: boolean; //true if focusedcolvalid and co_nohscroll + + function defocuscell: boolean; + function defocusrow: boolean; + function showrect(const rect: rectty; + const position: cellpositionty = cep_nearest; + const noxshift: boolean = false): pointty; + //returns shifted amount + function showcaretrect(const arect: rectty; + const aframe: tcustomframe): pointty; overload; + function showcaretrect(const arect: rectty; + const aframe: framety): pointty; overload; + function showcellrect(const rect: rectty; + const origin: cellinnerlevelty = cil_paint): pointty; + procedure showcell(const cell: gridcoordty; + const position: cellpositionty = cep_nearest; + const force: boolean = false); + //scrolls cell into view, force true -> if scrollbar clicked also + procedure showrow(const arow: integer; + const position: cellpositionty = cep_nearest; + const force: boolean = false); + procedure showlastrow; + procedure scrollrows(step: integer); + procedure scrollleft; + procedure scrollright; + procedure scrollpageleft; + procedure scrollpageright; + + //distance of active cell topleft to datarect topleft + property cellwindowpos: pointty read getcellwindowpos + write setcellwindowpos; + property rowwindowpos: int32 read getrowwindowpos write setrowwindowpos; + property colwindowpos: int32 read getcolwindowpos write setcolwindowpos; + + function userinput: boolean; + procedure movecol(curindex,newindex: integer; + const auserinput: boolean = false); virtual; + procedure moverow(curindex,newindex: integer; count: integer = 1; + const auserinput: boolean = false); virtual; + function insertrow(aindex: integer; acount: integer = 1; + const auserinput: boolean = false): int32; + //returns index of first row; + procedure deleterow(aindex: integer; acount: integer = 1; + const auserinput: boolean = false); + function appinsrow(aindex: integer;const auserinput: boolean = false): int32; + //insert or append empty row, set focused row to index + //empty row removed by exit row if og_noinsertempty + //returns insert index + function isinsertempty: boolean; + //true if row will be removed by og_noinsertempty + function isautoappend: boolean; //true if last row is auto appended + function autoappending: boolean; //empty row appending by focuscell + function checkreautoappend: boolean; //true if row appended + procedure removeappendedrow; + function autoremoving: boolean; //removing empty row + + procedure clear; //sets rowcount to 0 + function appendrow(const checkautoappend: boolean = false): integer; + //returns index of new row, does not call change events, calls updatelayout. + //use for single visible append, + //do not use for multiple row append in a block. + function appenddatarow: integer; + //returns index of new row, use it in a beginupdate/endupdate block + + procedure sortinvalid(const acol: integer = invalidaxis; + const arow: integer = invalidaxis); + function checksort: boolean; //true if sortchanged called + procedure sort; + + function copyselection: boolean; virtual; //false if no copy + function pasteselection: boolean; virtual; //false if no paste + + property optionsgrid: optionsgridty read foptionsgrid write setoptionsgrid + default defaultoptionsgrid; //first! + property optionsgrid1: optionsgrid1ty read foptionsgrid1 write foptionsgrid1 + default []; + property optionsfold: optionsfoldty read foptionsfold + write foptionsfold default []; + property norowedit: boolean read fnorowedit write fnorowedit; + property sorted: boolean read getsorted write setsorted; + property folded: boolean read getfolded write setfolded; + + property datarowlinewidth: integer read fdatarowlinewidth + write setdatarowlinewidth default defaultgridlinewidth; + property datarowlinecolorfix: colorty read fdatarowlinecolorfix + write setdatarowlinecolorfix default defaultfixlinecolor; + property datarowlinecolor: colorty read fdatarowlinecolor + write setdatarowlinecolor default defaultdatalinecolor; + property datarowheight: integer read fdatarowheight + write setdatarowheight default griddefaultrowheight; + property datarowheightmin: integer read fdatarowheightmin + write fdatarowheightmin default 1; + property datarowheightmax: integer read fdatarowheightmax + write fdatarowheightmax default maxint; + + property datacols: tdatacols read fdatacols write setdatacols; + property fixcols: tfixcols read ffixcols write setfixcols; + property fixrows: tfixrows read ffixrows write setfixrows; + + property rowcount: integer read frowcount write setrowcount default 0; + function rowhigh: integer; //rowcount - 1 + function datarowhigh: integer; //without auto appended empty row + property rowcountmax: integer read frowcountmax + write setrowcountmax default bigint; + function visiblerow(const arow: integer): integer; + //returns index in visible rows, invaidaxis if not visible + property firstvisiblerow: integer read ffirstvisiblerow; + property lastvisiblerow: integer read flastvisiblerow; + property visiblerows: integerarty read fvisiblerows; + + + property focusedcell: gridcoordty read ffocusedcell; + //col,row = invalidaxis if none + property col: integer read ffocusedcell.col write setcol; + property row: integer read ffocusedcell.row write setrow; + property mousecell: gridcoordty read fmousecell; + +// property gridframewidth: integer read fgridframewidth +// write setgridframewidth default 0; + property gridframecolor: colorty read fgridframecolor + write setgridframecolor default cl_gridframe; + + //rowproperties index = -1 -> focused row + property rowcolors: tcolorarrayprop read frowcolors write setrowcolors; + property rowcolorstate[index: integer]: rowstatenumty read getrowcolorstate + + write setrowcolorstate; //default = -1 + property rowlinecolorstate[index: integer]: rowstatenumty read getrowlinecolorstate + write setrowlinecolorstate; + //default = -1, og_rowheight must be set + property rowlinecolorfixstate[index: integer]: rowstatenumty + read getrowlinecolorfixstate + write setrowlinecolorfixstate; + //default = -1, og_rowheight must be set + property rowlinewidth[index: integer]: rowlinewidthty read getrowlinewidth + write setrowlinewidth; + //default = -1, og_rowheight must be set + + property rowfonts: trowfontarrayprop read frowfonts write setrowfonts; + property rowfontstate[index: integer]: rowstatenumty read getrowfontstate + write setrowfontstate; //default = -1 + property rowreadonlystate[index: integer]: boolean read getrowreadonlystate + write setrowreadonlystate; + property rowhidden[index: integer]: boolean read getrowhidden + write setrowhidden; + property rowfoldlevel[index: integer]: byte read getrowfoldlevel + write setrowfoldlevel; + property rowfoldissum[index: integer]: boolean read getrowfoldissum + write setrowfoldissum; + function rowfoldinfo: prowfoldinfoty; //nil if focused row not visible + property rowheight[index: integer]: integer read getrowheight + write setrowheight; + //og_rowheight must be set + property rowstatelist: trowstatelist read getrowstatelist + write setrowstatelist; +{$ifdef mse_with_ifi} + property ifilink: tifigridlinkcomp read fifilink write setifilink; +{$endif} + + property zebra_color: colorty read fzebra_color write setzebra_color + default cl_zebra; + property zebra_start: integer read fzebra_start write setzebra_start default 0; + property zebra_height: integer read fzebra_height write setzebra_height default 0; + property zebra_step: integer read fzebra_step write setzebra_step default 2; + + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read getstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + + property onbeforeupdatelayout: gridnotifyeventty + read fonbeforeupdatelayout write fonbeforeupdatelayout; + property onlayoutchanged: gridnotifyeventty read fonlayoutchanged + write fonlayoutchanged; + property oncolmoving: gridblockmovingeventty read foncolmoving + write foncolmoving; + property oncolmoved: gridblockmovedeventty read foncolmoved + write foncolmoved; + property onrowcountchanged: gridnotifyeventty read fonrowcountchanged + write fonrowcountchanged; + property onrowsdatachanged: griddatablockeventty read fonrowsdatachanged + write fonrowsdatachanged; + property onrowdatachanged: griddataeventty read fonrowdatachanged + write fonrowdatachanged; + property onrowsmoving: gridblockmovingeventty read fonrowsmoving + write fonrowsmoving; + property onrowsmoved: gridblockmovedeventty read fonrowsmoved + write fonrowsmoved; + property onscrollrows: gridscrolleventty read fonscrollrows + write fonscrollrows; + property ongetmorerows: gridmorerowseventty read fongetmorerows + write fongetmorerows; + + property onrowsinserting: gridbeforeblockeventty read fonrowsinserting + write fonrowsinserting; + property onrowsinserted: gridblockeventty read fonrowsinserted + write fonrowsinserted; + + property onrowsdeleting: gridbeforeblockeventty read fonrowsdeleting + write fonrowsdeleting; + property onrowsdeleted: gridblockeventty read fonrowsdeleted + write fonrowsdeleted; + property onrowsmodified: notifyeventty read fonrowsmodified + write fonrowsmodified; + //called if user deletes, inserts or moves rows + property onedited: notifyeventty read fonedited write fonedited; + //called if user types celltext or chages a cell value + property onsort: gridsorteventty read fonsort write fonsort; + property onsortchanged: gridnotifyeventty read fonsortchanged + write fonsortchanged; + + property oncellevent: celleventty read foncellevent write foncellevent; + property onselectionchanged: notifyeventty read fonselectionchanged + write fonselectionchanged; + property oncopyselection: copyselectioneventty read foncopyselection + write foncopyselection; + property onpasteselection: pasteselectioneventty read fonpasteselection + write fonpasteselection; + + property drag: tdragcontroller read fdragcontroller write setdragcontroller; + + published + property frame: tgridframe read getframe write setframe; + property font: twidgetfont read getfont write setfont stored isfontstored; + property fontempty: twidgetfontempty read getfontempty + write setfontempty stored isfontemptystored; + property onkeydown: keyeventty read fonkeydown write fonkeydown; + property wheelscrollheight: integer read fwheelscrollheight write + fwheelscrollheight default defaultwheelscrollheight; + property optionswidget default defaultgridwidgetoptions; + property optionswidget1 default defaultgridwidgetoptions1; + property onshortcut; + end; + + tcellgrid = class(tcustomgrid) + protected + procedure clientmouseevent(var info: mouseeventinfoty); override; + end; + + tdrawgrid = class(tcellgrid) + private + function getdatacols: tdrawcols; + procedure setdatacols(const value: tdrawcols); + function getcols(index: integer): tdrawcol; + procedure setcols(index: integer; const avalue: tdrawcol); + protected + function createdatacols: tdatacols; override; + property cols[index: integer]: tdrawcol read getcols write setcols; default; + published + property optionsgrid; + property optionsgrid1; + property optionsfold; + property datacols: tdrawcols read getdatacols write setdatacols; + property rowstatelist; + property fixcols; + property fixrows; + property rowcount; + property rowcountmax; + property gridframecolor; +// property gridframewidth; + property rowcolors; + property rowfonts; + property zebra_color; + property zebra_start; + property zebra_height; + property zebra_step; + + property datarowlinewidth; + property datarowlinecolorfix; + property datarowlinecolor; + property datarowheight; + property datarowheightmin; + property datarowheightmax; + + property statfile; + property statvarname; + property statpriority; + + property oncopyselection; + property onpasteselection; + property onbeforeupdatelayout; + property onlayoutchanged; + property oncolmoving; + property oncolmoved; + property onrowcountchanged; + property onrowdatachanged; + property onrowsdatachanged; + property onrowsmoving; + property onrowsmoved; + property onrowsinserting; + property onrowsinserted; + property onrowsdeleting; + property onrowsdeleted; + property onrowsmodified; + property onedited; + property onscrollrows; + property ongetmorerows; + property oncellevent; + property onselectionchanged; + property onsort; + property onsortchanged; + property drag; + + end; + + tcustomstringgrid = class(tcellgrid,iedit) + private + function getdatacols: tstringcols; + procedure setdatacols(const value: tstringcols); + function getcols(index: integer): tstringcol; + procedure setcols(index: integer; const Value: tstringcol); + function getitems(const cell: gridcoordty): msestring; + procedure setitems(const cell: gridcoordty; const Value: msestring); + function getcaretwidth: integer; + procedure setcaretwidth(const value: integer); + protected + feditor: tinplaceedit; + procedure setupeditor(const acell: gridcoordty; const focusin: boolean); virtual; + procedure dofontheightdelta(var delta: integer); override; + procedure checkcellvalue(var accept: boolean); override; + procedure rootchanged(const aflags: rootchangeflagsty); override; + procedure updatelayout; override; + procedure firstcellclick(const cell: gridcoordty; + var info: mouseeventinfoty); override; + function createdatacols: tdatacols; override; + procedure docellevent(var info: celleventinfoty); override; + procedure drawfocusedcell(const canvas: tcanvas); override; + procedure scrolled(const dist: pointty); override; + function getcaretcliprect: rectty; override; //origin = clientrect.pos + property cols[index: integer]: tstringcol read getcols write setcols; default; + function currentdatalist: tmsestringdatalist; + + //iedit + function getoptionsedit: optionseditty; virtual; + procedure editnotification(var info: editnotificationinfoty); virtual; + function hasselection: boolean; + procedure updatecopytoclipboard(var atext: msestring); + procedure updatepastefromclipboard(var atext: msestring); + function locatecount: integer; //number of locate values + function locatecurrentindex: integer; //index of current row + procedure locatesetcurrentindex(const aindex: integer); + function getkeystring(const aindex: integer): msestring; //locate text + function getedited: boolean; + + procedure rowstatechanged(const arow: integer); override; + procedure dofocusedcellposchanged; override; + procedure focusedcellchanged; override; + procedure checkrowreadonlystate; override; + //interface to inplaceedit + procedure dokeydown(var info: keyeventinfoty); override; + procedure clientmouseevent(var info: mouseeventinfoty); override; + procedure doactivate; override; + procedure dodeactivate; override; + + procedure doselectionchanged; override; + procedure updatepopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); override; + //iassistiveclient + function getassistivecaretindex(): int32; override; + //iassistiveclientgrid + function getassistivecelltext(const acell: gridcoordty; + out aflags: assistiveflagsty): msestring; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure initnewcomponent(const ascale: real) override; + procedure synctofontheight; override; + function canclose(const newfocus: twidget): boolean; override; + function textclipped(const acell: gridcoordty; + out acellrect: rectty): boolean; overload; + function textclipped(const acell: gridcoordty): boolean; overload; + + function appendrow(const value: array of msestring; + const ashowlastrow: boolean = false): integer; overload; + function appendrow(const value: msestringarty; + const ashowlastrow: boolean = false): integer; overload; + function appendrow(const value: msestring; + const ashowlastrow: boolean = false): integer; overload; + //for visible single row append + + function appenddatarow(const value: array of msestring): integer; overload; + function appenddatarow(const value: msestringarty): integer; overload; + function appenddatarow(const value: msestring): integer; overload; + //for multiple data append in a beginupdate/endupdate block + + function copyselection: boolean; override; + function pasteselection: boolean; override; + property items[const cell: gridcoordty]: msestring read getitems write setitems; + property datacols: tstringcols read getdatacols write setdatacols; + property caretwidth: integer read getcaretwidth write setcaretwidth + default defaultcaretwidth; + end; + + tstringgrid = class(tcustomstringgrid) + public + procedure initnewcomponent(const ascale: real); override; + published + property optionsgrid; + property optionsgrid1; + property optionsfold; + property datacols; + property rowstatelist; + property fixcols; + property fixrows; + property rowcount; + property rowcountmax; + property gridframecolor; +// property gridframewidth; + property rowcolors; + property rowfonts; + property zebra_color; + property zebra_start; + property zebra_height; + property zebra_step; + + property datarowlinewidth; + property datarowlinecolorfix; + property datarowlinecolor; + property datarowheight; + property datarowheightmin; + property datarowheightmax; + property caretwidth; + + property statfile; + property statvarname; + property statpriority; + + property oncopyselection; + property onpasteselection; + property onbeforeupdatelayout; + property onlayoutchanged; + property oncolmoving; + property oncolmoved; + property onrowcountchanged; + property onrowdatachanged; + property onrowsdatachanged; + property onrowsmoving; + property onrowsmoved; + property onrowsinserting; + property onrowsinserted; + property onrowsdeleting; + property onrowsdeleted; + property onrowsmodified; + property onedited; + property onscrollrows; + property ongetmorerows; + property oncellevent; + property onselectionchanged; + property onsort; + property onsortchanged; + property drag; + end; + + cellclickrestrictionty = (ccr_buttonpress,ccr_dblclick, + ccr_nodefaultzone,ccr_nokeyreturn,ccr_data); + cellclickrestrictionsty = set of cellclickrestrictionty; + +function gridcoordtotext(const coord: gridcoordty): string; +function isequalgridcoord(const a,b: gridcoordty): boolean; + +function iscellkeypress(const info: celleventinfoty; + const akey: keyty = key_none; //key_none -> all keys + const shiftstatemustinclude: shiftstatesty = []; + const shiftstatemustnotinclude: shiftstatesty = []): boolean; + +function iscellclick(const info: celleventinfoty; + const restrictions: cellclickrestrictionsty = []; + const shiftstatemustinclude: shiftstatesty = []; + const shiftstatemustnotinclude: shiftstatesty = [ss_repeat]): boolean; + +function isrowenter(const info: celleventinfoty; + const noentergrid: boolean = false): boolean; +function isrowexit(const info: celleventinfoty; + const noexitgrid: boolean = false): boolean; +function isrowchange(const info: celleventinfoty): boolean; +function wasrowenter(const info: celleventinfoty; + const noentergrid: boolean = false): boolean; +function wasrowexit(const info: celleventinfoty; + const noexitgrid: boolean = false): boolean; +function cellkeypress(const info: celleventinfoty): keyty; + +implementation +uses + mseguiintf,msestockobjects,mseact,mseactions,rtlconsts,msegraphedits, + mseassistiveserver,mseformatstr; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tframe1 = class(tcustomframe); + tdatalist1 = class(tdatalist); + twidget1 = class(twidget); + tinplaceedit1 = class(tinplaceedit); + tcustomscrollbar1 = class(tcustomscrollbar); + +const + errorstrings: array[griderrorty] of string = ( + '', //ok + 'Ivalid datacell', + 'Rowcounts are different', + 'Invalid row index', + 'Invalid col index', + 'Invalid widget' + ); + +//var +// coloptionssplitinfo: setsplitinfoty; + +function iscellkeypress(const info: celleventinfoty; + const akey: keyty = key_none; //key_none -> all keys + const shiftstatemustinclude: shiftstatesty = []; + const shiftstatemustnotinclude: shiftstatesty = []): boolean; +begin + result:= false; + with info do begin + if (eventkind = cek_keydown) then begin + with keyeventinfopo^ do begin + if (key = akey) and + (shiftstate * shiftstatemustinclude = shiftstatemustinclude) and + (shiftstate * shiftstatemustnotinclude = []) then begin + include(eventstate,es_processed); + result:= true; + end; + end; + end; + end; +end; + +function iscellclick(const info: celleventinfoty; + const restrictions: cellclickrestrictionsty = []; + const shiftstatemustinclude: shiftstatesty = []; + const shiftstatemustnotinclude: shiftstatesty = [ss_repeat]): boolean; +begin + result:= false; + with info do begin + if not (ccr_data in restrictions) or + (info.cell.col >= 0) and (info.cell.row >= 0) then begin + case eventkind of + cek_keydown: begin + if not (ccr_nokeyreturn in restrictions) then begin + with info.keyeventinfopo^ do begin + if isenterkey(nil,key) and + (shiftstate * shiftstatemustinclude = shiftstatemustinclude) and + (shiftstate * shiftstatemustnotinclude = []) then begin + result:= true; + include(eventstate,es_processed); + end; + end; + end; + end; + cek_buttonpress,cek_buttonrelease: begin + if (zone <> cz_none) and not + ((zone = cz_default) and (ccr_nodefaultzone in restrictions)) then begin + with info.mouseeventinfopo^ do begin + if (button = mb_left) and not (es_objectpicking in eventstate) and + (shiftstate * shiftstatemustinclude = shiftstatemustinclude) and + (shiftstate * shiftstatemustnotinclude = []) then begin + if ((ccr_buttonpress in restrictions) and (eventkind = ek_buttonpress) or + not (ccr_buttonpress in restrictions) and + (eventkind = ek_buttonrelease)) then begin + if ccr_dblclick in restrictions then begin + result:= (ss_double in info.mouseeventinfopo^.shiftstate) and + (grid.fclickedcellbefore.row = cell.row) and + (grid.fclickedcellbefore.col = cell.col); + end + else begin + result:= true; + end; + if (eventkind = ek_buttonrelease) and + ((grid.fclickedcell.row <> cell.row) or + (grid.fclickedcell.col <> cell.col)) then begin + result:= false; + end; + end; + end; + end; + end; + end; + end; + end; + end; +end; + +function isrowenter(const info: celleventinfoty; + const noentergrid: boolean = false): boolean; +begin + with info do begin + result:= (eventkind = cek_enter) and + ((cellbefore.row <> newcell.row) or (selectaction = fca_focusinforce)) and + (not noentergrid or (selectaction <> fca_entergrid)); + end; +end; + +function isrowexit(const info: celleventinfoty; + const noexitgrid: boolean = false): boolean; +begin + with info do begin + result:= (eventkind = cek_exit) and (cellbefore.row <> newcell.row) and + (not noexitgrid or (info.selectaction <> fca_exitgrid)); + end; +end; + +function isrowchange(const info: celleventinfoty): boolean; +begin + with info do begin + result:= (eventkind = cek_focusedcellchanged) and (cellbefore.row <> newcell.row); + end; +end; + +function wasrowenter(const info: celleventinfoty; + const noentergrid: boolean = false): boolean; +begin + with info do begin + result:= isrowchange(info) and (newcell.row >= 0) and + (not noentergrid or (selectaction <> fca_entergrid)); + end; +end; + +function wasrowexit(const info: celleventinfoty; + const noexitgrid: boolean = false): boolean; +begin + with info do begin + result:= isrowchange(info) and (newcell.row < 0) and + (not noexitgrid or (selectaction <> fca_exitgrid)); + end; +end; + +function cellkeypress(const info: celleventinfoty): keyty; +begin + if info.eventkind = cek_keydown then begin + result:= info.keyeventinfopo^.key; + end + else begin + result:= key_none; + end; +end; + +function gridcoordtotext(const coord: gridcoordty): string; +begin + result:= 'Col: '+inttostr(coord.col) + ' Row: '+inttostr(coord.row); +end; + +function isequalgridcoord(const a,b: gridcoordty): boolean; +begin + result:= (a.col = b.col) and (a.row = b.row); +end; + +procedure stringcoltooptionsedit(const source: stringcoleditoptionsty; + var dest: optionseditty); +begin + if scoe_undoonesc in source then begin + include(dest,oe_undoonesc); + end; + if scoe_forcereturncheckvalue in source then begin + include(dest,oe_forcereturncheckvalue); + end; + if scoe_eatreturn in source then begin + include(dest,oe_eatreturn); + end; + dest:= optionseditty(replacebits( + longword({$ifdef FPC}longword{$else}longword{$endif}(source)) + shl stringcoloptionseditshift, + longword(dest),longword(stringcoloptionseditmask))); +end; + +procedure transferdeprecatedcoloptions(const source: coloptionsty; + var dest: coloptions1ty); +begin +{ + if co_rowfont in source then begin + include(dest,co1_rowfont); + end; + if co_rowcolor in source then begin + include(dest,co1_rowcolor); + end; + if co_zebracolor in source then begin + include(dest,co1_zebracolor); + end; + if co_rowcoloractive in source then begin + include(dest,co1_rowcoloractive); + end; +} +end; + +{ tcellframe } + +constructor tcellframe.create(const aintf: iframe); +begin + inherited; + include(fstate,fs_nowidget); + fi.innerframe.right:= 1; + fi.innerframe.top:= 1; + fi.innerframe.left:= 1; + fi.innerframe.bottom:= 1; +end; + +{ tgridframe } + +constructor tgridframe.create(const aintf: iscrollframe; const owner: twidget; + const autoscrollintf: iautoscrollframe); +begin + inherited; + fi.innerframe.right:= 0; + fi.innerframe.top:= 0; + fi.innerframe.left:= 0; + fi.innerframe.bottom:= 0; + internalupdatestate; + fi.levelo:= -2; +end; + +function tgridframe.actualcolorclient(): colorty; +begin + result:= fi.colorclient; + if result = cl_default then begin + result:= cl_foreground; + end; +end; + +function tgridframe.getscrollbarclass(vert: boolean): framescrollbarclassty; +begin + result:= tthumbtracknopagesizescrollbar; +end; + +{ tgridpropfont } + +class function tgridpropfont.getinstancepo(owner: tobject): pfont; +begin + result:= @tgridprop(owner).ffont; +end; + +{ tgridprop } + +constructor tgridprop.create(const agrid: tcustomgrid; + const aprop: tgridarrayprop); +begin + fcellinfo.grid:= agrid; + fcolor:= aprop.fcolor; + fcursor:= aprop.fcursor; + fcolorselect:= aprop.fcolorselect; + fcoloractive:= aprop.fcoloractive; + fcolorfocused:= aprop.fcolorfocused; + flinecolor:= aprop.linecolor; + flinecolorfix:= aprop.linecolorfix; + flinewidth:= aprop.linewidth; + inherited create(agrid,aprop); + agrid.initcellinfo(fcellinfo); +end; + +destructor tgridprop.destroy; +begin + inherited; + fframe.free; + fface.free; + ffont.free; +end; + +procedure tgridprop.createframe; +begin + if fframe = nil then begin + tcellframe.create(iframe(self)); + end; +end; + +procedure tgridprop.createface; +begin + if fface = nil then begin + fface:= tcellface.create(iface(self)); + end; +end; + +procedure tgridprop.setlinewidth(const Value: integer); +begin + if flinewidth <> value then begin + if value < 0 then begin + flinewidth:= 0; + end + else begin + flinewidth:= Value; + end; + fcellinfo.grid.layoutchanged; + end; +end; +{ +function tgridprop.islinewidthstored: Boolean; +begin + result:= flinewidth <> tcols(prop).flinewidth; +end; +} +procedure tgridprop.setlinecolor(const Value: colorty); +begin + if flinecolor <> value then begin + flinecolor:= Value; + fcellinfo.grid.layoutchanged; + end; +end; +{ +function tgridprop.islinecolorstored: Boolean; +begin + result:= flinecolor <> tcols(prop).flinecolor; +end; +} +procedure tgridprop.setlinecolorfix(const Value: colorty); +begin + if flinecolorfix <> value then begin + flinecolorfix:= Value; + fcellinfo.grid.layoutchanged; + end; +end; + +procedure tgridprop.setcolorselect(const Value: colorty); +begin + if value <> fcolorselect then begin + fcolorselect := Value; + changed; + end; +end; + +procedure tgridprop.setcoloractive(avalue: colorty); +begin + if avalue = cl_invalid then begin + avalue:= cl_none; + end; + if avalue <> fcoloractive then begin + fcoloractive:= avalue; + fcellinfo.grid.layoutchanged; + changed; + end; +end; + +procedure tgridprop.setcolorfocused(avalue: colorty); +begin + if avalue = cl_invalid then begin + avalue:= cl_none; + end; + if avalue <> fcolorfocused then begin + fcolorfocused:= avalue; + fcellinfo.grid.layoutchanged; + changed; + end; +end; +{ +function tgridprop.islinecolorfixstored: Boolean; +begin + result:= flinecolorfix <> tgridarrayprop(prop).flinecolorfix; +end; + +function tgridprop.iscolorselectstored: boolean; +begin + result:= fcolorselect <> tgridarrayprop(prop).fcolorselect; +end; + +function tgridprop.iscoloractivestored: boolean; +begin + result:= fcoloractive <> tgridarrayprop(prop).fcoloractive; +end; +} +function tgridprop.getframe: tcellframe; +begin + fcellinfo.grid.getoptionalobject(fframe,{$ifdef FPC}@{$endif}createframe); + result:= fframe; +end; + +function tgridprop.getface: tcellface; +begin + fcellinfo.grid.getoptionalobject(fface,{$ifdef FPC}@{$endif}createface); + result:= fface; +end; + + //iframe +function tgridprop.getwidget: twidget; +begin + result:= fcellinfo.grid; +end; + +function tgridprop.getclientrect: rectty; +begin + result:= fcellinfo.grid.clientrect; +end; + +procedure tgridprop.setlinkedvar(const source: tmsecomponent; + var dest: tmsecomponent; const linkintf: iobjectlink = nil); +begin + fcellinfo.grid.setlinkedvar(source,dest,linkintf); +end; + +procedure tgridprop.widgetregioninvalid; +begin + fcellinfo.grid.widgetregioninvalid; +end; + +procedure tgridprop.setframeinstance(instance: tcustomframe); +begin + fframe:= tcellframe(instance); +end; + +function tgridprop.getwidgetrect: rectty; +begin + result:= fcellrect; +end; +{ +procedure tgridprop.setwidgetrect(const rect: rectty); +begin + twidget1(getwidget).setwidgetrect(rect); +end; +} +procedure tgridprop.setstaticframe(value: boolean); +begin + //dummy +end; + +function tgridprop.getstaticframe: boolean; +begin + result:= false; +end; + +function tgridprop.widgetstate: widgetstatesty; +begin + result:= twidget1(getwidget).widgetstate; +end; + +procedure tgridprop.scrollwidgets(const dist: pointty); +begin + twidget1(getwidget).scrollwidgets(dist); +end; + +procedure tgridprop.clientrectchanged; +begin + fcellinfo.grid.layoutchanged; +end; + +function tgridprop.getcomponentstate: tcomponentstate; +begin + result:= getwidget.componentstate; +end; + +function tgridprop.getmsecomponentstate: msecomponentstatesty; +begin + result:= getwidget.msecomponentstate; +end; + +procedure tgridprop.invalidate; +begin + getwidget.invalidate; +end; + +procedure tgridprop.invalidatewidget; +begin + getwidget.invalidatewidget; +end; + +procedure tgridprop.invalidaterect(const rect: rectty; + const org: originty = org_client; const noclip: boolean = false); +begin + getwidget.invalidaterect(rect,org,noclip); +end; +{ +function tgridprop.getframefont: tfont; +begin + result:= twidget1(getwidget).getfont; +end; + +function tgridprop.getcanvas(aorigin: originty = org_client): tcanvas; +begin + result:= getwidget.getcanvas(aorigin); +end; + +function tgridprop.canfocus: boolean; +begin + result:= getwidget.canfocus; +end; + +function tgridprop.setfocus(aactivate: boolean = true): boolean; +begin + result:= getwidget.setfocus(aactivate); +end; +} +procedure tgridprop.setframe(const Value: tcellframe); +begin + fcellinfo.grid.setoptionalobject(value,fframe,{$ifdef FPC}@{$endif}createframe); + clientrectchanged; +end; + +procedure tgridprop.setface(const Value: tcellface); +begin + fcellinfo.grid.setoptionalobject(value,fface,{$ifdef FPC}@{$endif}createface); + fcellinfo.grid.invalidate; +end; + +procedure tgridprop.drawcellbackground(const acanvas: tcanvas; + const aframe: tcustomframe; const aface: tcustomface); +var + rect1: rectty; +// pt1: pointty; +begin + rect1:= makerect(nullpoint,fcellrect.size); + acanvas.fillrect(rect1,fcellinfo.color); + if aframe <> nil then begin + aframe.paintbackground(acanvas,rect1,true,true); + end; + acanvas.rootbrushorigin:= fcellinfo.grid.fbrushorigin; + if aface <> nil then begin + aface.paint(acanvas,makerect(nullpoint,fcellinfo.rect.size)); + end; +end; + +procedure tgridprop.drawcelloverlay(const acanvas: tcanvas; + const aframe: tcustomframe); +begin + if aframe <> nil then begin + aframe.paintoverlay(acanvas,makerect(nullpoint,fcellrect.size)); + end; +end; + +procedure tgridprop.setcolor(const Value: colorty); +begin + if color <> value then begin + fcolor := Value; + changed; + end; +end; + +procedure tgridprop.changed; +begin + //dummy +end; + +function tgridprop.getinnerframe: framety; +begin + result:= tgridarrayprop(prop).finnerframe; +end; + +procedure tgridprop.updatecellrect(const aframe: tcustomframe); +begin + fcellinfo.rect:= makerect(nullpoint,fcellrect.size); + if aframe <> nil then begin + deflaterect1(fcellinfo.rect,tframe1(aframe).fpaintframe); + with tframe1(aframe).fi.innerframe do begin + fcellinfo.innerrect.pos:= pointty(topleft); + fcellinfo.innerrect.cx:= fcellinfo.rect.cx - left - right; + fcellinfo.innerrect.cy:= fcellinfo.rect.cy - top - bottom; + fcellinfo.frameinnerrect:= fcellinfo.innerrect; + end; + end + else begin + fcellinfo.innerrect:= deflaterect(makerect(nullpoint,fcellinfo.rect.size), + getinnerframe); + fcellinfo.frameinnerrect:= fcellinfo.rect; + end; +end; + +procedure tgridprop.updatelayout; +begin + if fframe <> nil then begin + fframe.updatestate; + end; + updatecellrect(fframe); +end; + +//iface +function tgridprop.translatecolor(const acolor: colorty): colorty; +begin + result:= acolor; +end; + +procedure tgridprop.fontchanged(const sender: tobject); +begin + changed; +end; + +function tgridprop.getfont: tgridpropfont; +begin + getoptionalobject(fcellinfo.grid.componentstate,ffont, + {$ifdef FPC}@{$endif}createfont); + if ffont <> nil then begin + result:= ffont; + end + else begin + result:= tgridpropfont(pointer(fcellinfo.grid.getfont)); + end; +end; + +procedure tgridprop.setfont(const Value: tgridpropfont); +begin + if value <> ffont then begin + setoptionalobject(fcellinfo.grid.ComponentState,value,ffont, + {$ifdef FPC}@{$endif}createfont); + changed; + end; +end; + +function tgridprop.isfontstored: Boolean; +begin + result:= ffont <> nil; +end; + +procedure tgridprop.createfont; +begin + if ffont = nil then begin + ffont:= tgridpropfont.create; + ffont.onchange:= {$ifdef FPC}@{$endif}fontchanged; + end; +end; + +function tgridprop.getframestateflags: framestateflagsty; +begin + result:= []; +end; + +procedure tgridprop.updatecellheight(const canvas: tcanvas; var aheight: integer); +begin + //dummy +end; + +function tgridprop.framedim: sizety; +begin + if fframe = nil then begin + result:= nullsize; + end + else begin + result:= fframe.paintframedim; + end; +end; + +{ tcolselectfont } + +class function tcolselectfont.getinstancepo(owner: tobject): pfont; +begin + result:= @tcol(owner).ffontselect; +end; + +{ tcol} + +constructor tcol.create(const agrid: tcustomgrid; const aowner: tgridarrayprop); +begin + inherited create(agrid,aowner); + ffocusrectdist:= tcols(aowner).ffocusrectdist; + fwidth:= tcols(aowner).fwidth; + foptions:= tcols(aowner).foptions; + foptions1:= tcols(aowner).foptions1; + if co1_autorowheight in foptions1 then begin + include(fstate,gps_needsrowheight); + end; + flinewidth:= tcols(aowner).flinewidth; + flinecolor:= tcols(aowner).flinecolor; + ffontactivenum:= tcols(aowner).ffontactivenum; + ffontfocusednum:= tcols(aowner).ffontfocusednum; +end; + +destructor tcol.destroy; +begin + ffontselect.free; + inherited; +end; +(* +procedure tcol.readoptions(reader: treader); +var + set1,set2: tintegerset; +begin + if readsplitset(reader,coloptionssplitinfo,set1,set2) then begin + optionscell:= celloptionsty(set2); + end; + options:= coloptionsty(set1); +// options:= coloptionsty(readset(reader,typeinfo(coloptionsty))); +end; + +procedure tcol.defineproperties(filer: tfiler); +begin + filer.defineproperty('options',{$ifdef FPC}@{$endif}readoptions,nil,false); +end; +*) +procedure tcol.invalidate; +begin + fcellinfo.grid.colchanged(self); +end; + +procedure tcol.changed; +begin + inherited; + invalidate; +end; + +procedure tcol.cellchanged(const row: integer); +begin + fcellinfo.grid.cellchanged(self,row); +end; + +procedure tcol.invalidatecell(const arow: integer); +begin + fcellinfo.grid.invalidatecell(makegridcoord(colindex,arow)); +end; + +procedure tcol.drawcell(const acanvas: tcanvas); +begin + if not fcellinfo.calcautocellsize then begin + drawcellbackground(acanvas,fframe,fface); + end; +end; + +function tcol.actualcolor: colorty; +begin + if fcolor <> cl_default then begin + if fcolor = cl_parent then begin + result:= fcellinfo.grid.actualopaquecolor; + end + else begin + result:= fcolor; + end; + end + else begin + result:= tframe1(fcellinfo.grid.fframe).actualcolorclient; + end; +end; + +function tcol.isopaque: boolean; +begin + result:= actualcolor <> cl_transparent; +end; + +function tcol.checkactivecolor(const aindex: integer): boolean; + //true if coloractive and fontactivenum active +begin + result:= (fcellinfo.grid.entered {or (co1_active in foptions1)}) and + (aindex = fcellinfo.grid.ffocusedcell.row) and + ((gps_fix in fstate) or (co1_rowcoloractive in foptions1) or + (findex = fcellinfo.grid.ffocusedcell.col)) +end; + +function tcol.checkfocusedcolor(const aindex: integer): boolean; + //true if colorfocus and fontfocusnum active +begin + result:= //(fgrid.entered {or (co1_active in {tcols(prop).}foptions1)}) and + (aindex = fcellinfo.grid.ffocusedcell.row) and + ((gps_fix in fstate) or (co1_rowcolorfocused in foptions1) or + (findex = fcellinfo.grid.ffocusedcell.col)) +end; + +function tcol.rowcolor(const aindex: integer): colorty; +var + po1: prowstatety; + by1: byte; + int1: integer; + bo1: boolean; +begin + result:= cl_none; + if aindex >= 0 then begin + bo1:= getselected(aindex); + if co1_rowcolor in foptions1 then begin + po1:= fcellinfo.grid.fdatacols.frowstate.getitempo(aindex); + by1:= po1^.color and rowstatenummask; +// if by1 <> 0 then begin + int1:= by1 + frowcoloroffset - 1; + if bo1 then begin + int1:= int1 + frowcoloroffsetselect; + end; + if (int1 >= 0) and (int1 < fcellinfo.grid.frowcolors.count) then begin + result:= fcellinfo.grid.frowcolors[int1]; + end; +// end; + end; + if bo1 and (result = cl_none) and (fcolorselect <> cl_none) then begin + if fcolorselect <> cl_default then begin + result:= fcolorselect; + end + else begin + result:= defaultselectedcellcolor; + end; + end; + if (result = cl_none) and checkactivecolor(aindex) then begin + result:= fcoloractive; + end; + if (result = cl_none) and checkfocusedcolor(aindex) then begin + result:= fcolorfocused; + end; + if result = cl_none then begin + if (co1_zebracolor in foptions1) then begin + with fcellinfo.grid do begin + if (fzebra_step > 0) then begin + int1:= (aindex - getzebrastart) mod fzebra_step; + if int1 < 0 then begin + if int1 < fzebra_height - fzebra_step then begin + result:= fzebra_color; + end; + end + else begin + if int1 < fzebra_height then begin + result:= fzebra_color; + end; + end; + end; + end; + end; + end; + end; + if result = cl_none then begin + result:= actualcolor; + end; +end; + +function tcol.actualfont: tfont; +begin + if ffont = nil then begin + result:= tcols(prop).ffont; + if result = nil then begin + result:= fcellinfo.grid.getfont; + end; + end + else begin + result:= ffont; + end; +end; + +function tcol.rowfont(const aindex: integer): tfont; +var + po1: prowstatety; + by1: byte; + int1: integer; + bo1: boolean; +begin + result:= nil; + if aindex >= 0 then begin + bo1:= getselected(aindex); + if co1_rowfont in foptions1 then begin + po1:= fcellinfo.grid.fdatacols.frowstate.getitempo(aindex); + by1:= po1^.font and rowstatenummask; + if by1 <> 0 then begin + int1:= by1 + frowfontoffset - 1; + if bo1 then begin + int1:= int1 + frowfontoffsetselect; + end; + if (int1 >= 0) and (int1 < fcellinfo.grid.frowfonts.count) then begin + result:= tfont(fcellinfo.grid.frowfonts.fitems[int1]); + end; + end; + end; + if bo1 and (result = nil) then begin + result:= ffontselect; + if result = nil then begin + result:= tcols(prop).ffontselect; + end; + end; + end; + if result = nil then begin + if (ffontactivenum >= 0) and + (ffontactivenum < fcellinfo.grid.frowfonts.count) then begin + if checkactivecolor(aindex) then begin + result:= tfont(fcellinfo.grid.frowfonts.fitems[ffontactivenum]); + end; + end; + if result = nil then begin + if (ffontfocusednum >= 0) and + (ffontfocusednum < fcellinfo.grid.frowfonts.count) then begin + if checkfocusedcolor(aindex) then begin + result:= tfont(fcellinfo.grid.frowfonts.fitems[ffontfocusednum]); + end; + end; + if result = nil then begin + result:= actualfont; + end; + end; + end; +end; + +function tcol.getdatapo(const arow: integer): pointer; +begin + result:= nil; +end; + +function tcol.checkautocolwidth: boolean; +var + int1: integer; +begin + result:= false; + if (co1_autocolwidth in foptions1) and + not (gps_autosizevalid in fstate) and + not (csdesigning in fcellinfo.grid.componentstate) then begin + include(fstate,gps_autosizevalid); + int1:= width; + width:= maxwidth; + if width <> int1 then begin + result:= true; + end; + end; +end; + +procedure tcol.dobeforedrawcell(const acanvas: tcanvas; + var processed: boolean); +begin + fonbeforedrawcell(self,acanvas,fcellinfo,processed); +end; + +procedure tcol.doafterdrawcell(const acanvas: tcanvas); +begin + fonafterdrawcell(self,acanvas,fcellinfo); +end; + +function tcol.needsfocusrect: boolean; +begin + result:= co_drawfocus in foptions; +end; + +procedure tcol.paint(var info: colpaintinfoty); +var + int1,int2,int3: integer; + isgridcol,isfocusedcol,isfocusedcell: boolean; + bo1,bo2: boolean; + saveindex: integer; + linewidthbefore: integer; + font1: tfont; + canbeforedrawcell: boolean; + canafterdrawcell: boolean; + row1: integer; + hiddenlines: integerarty; + segments1: segmentarty; + po1: pdatacolaty; + nextcol: tdatacol; + widthextend,heightextend: integer; + checkmerge: boolean; + hasrowheight: boolean; + rowstatelist: trowstatelist; + endy: integer; + framedim1: sizety; +begin + if (not (co_invisible in foptions) or + (csdesigning in fcellinfo.grid.componentstate)) then begin + if not info.calcautocellsize and checkautocolwidth then begin + exit; + end; + checkmerge:= og_colmerged in fcellinfo.grid.foptionsgrid; + canbeforedrawcell:= fcellinfo.grid.canevent(tmethod(fonbeforedrawcell)); + canafterdrawcell:= fcellinfo.grid.canevent(tmethod(fonafterdrawcell)); + hiddenlines:= nil; + with info do begin + fcellinfo.calcautocellsize:= calcautocellsize; + framedim1:= framedim; + fcellinfo.autocellsize:= subsize(autocellsize,framedim1); + fcellinfo.grid.fbrushorigin.x:= fcellinfo.grid.frootbrushorigin.x; + if not (co_nohscroll in foptions) then begin + fcellinfo.grid.fbrushorigin.x:= + fcellinfo.grid.fbrushorigin.x + fcellinfo.grid.fscrollrect.x; + end; + fcellinfo.font:= nil; + isgridcol:= (fcellinfo.cell.col = fcellinfo.grid.ffocusedcell.col); + isfocusedcol:= isgridcol and (gs_cellentered in fcellinfo.grid.fstate); + canvas.drawinfopo:= @fcellinfo; + canvas.move(makepoint(fcellrect.x,fcellrect.y + ystart)); + fcellinfo.foldinfo:= nil; + nextcol:= nil; + po1:= nil; + if not (gps_fix in fstate) then begin + po1:= pointer(fcellinfo.grid.fdatacols.fitems); + if index <> fcellinfo.grid.datacols.lastvisiblecol then begin + nextcol:= po1^[index+1]; + end; + end; + clean(startrow,endrow); + hasrowheight:= og_rowheight in fcellinfo.grid.optionsgrid; + rowstatelist:= fcellinfo.grid.fdatacols.frowstate; + for int1:= startrow to endrow do begin + row1:= rows[int1]; + fcellinfo.cell.row:= row1; + fcellinfo.rowstate:= rowstatelist.getitempo(row1); + bo1:= false; + if checkmerge and (nextcol <> nil) and nextcol.merged[row1] then begin + bo1:= true; //has merged columns + additem(hiddenlines,row1); //by merged columns + end; + if not checkmerge or not merged[row1] then begin + isfocusedcell:= isfocusedcol and (row1 = fcellinfo.grid.ffocusedcell.row); + heightextend:= 0; + if hasrowheight then begin + with fcellinfo do begin + heightextend:= rowstatelist.internalheight(row1) - fcellinfo.grid.fdatarowheight;//rect.cy; + inc(fcellrect.cy,heightextend); + inc(rect.cy,heightextend); + inc(innerrect.cy,heightextend); + inc(frameinnerrect.cy,heightextend); + end; + end; + widthextend:= 0; + if bo1 then begin + for int2:= index + 1 to fcellinfo.grid.fdatacols.count - 1 do begin + with po1^[int2] do begin + if not (co_invisible in foptions) then begin + if merged[row1] then begin + inc(widthextend,step); + end + else begin + break; + end; + end; + end; + end; + with fcellinfo do begin + inc(fcellrect.cx,widthextend); + inc(rect.cx,widthextend); + inc(innerrect.cx,widthextend); + inc(frameinnerrect.cx,widthextend); + end; + end; + try + font1:= rowfont(row1); + if font1 <> fcellinfo.font then begin + fcellinfo.font:= font1; + canvas.font:= font1; + end; + if og_folded in fcellinfo.grid.foptionsgrid then begin + fcellinfo.foldinfo:= @foldinfo[int1]; + end; + fcellinfo.datapo:= getdatapo(row1); + fcellinfo.drawstate:= []; + if getselected(row1) then begin + include(fcellinfo.drawstate,cds_selected); + end; + if fcellinfo.grid.getrowreadonlystate(row1) then begin + include(fcellinfo.drawstate,cds_readonly); + end; + if isgridcol and (row1 = fcellinfo.grid.ffocusedcell.row) then begin + include(fcellinfo.drawstate,cds_focused); + end; + if isfocusedcell then begin + include(fcellinfo.drawstate,cds_active); + end; + if isfocusedcell or (co1_rowcoloractive in foptions1) and + (row1 = fcellinfo.grid.ffocusedcell.row) then begin + include(fcellinfo.drawstate,cds_usecoloractive); + end; + +// fcellinfo.notext:= false; + if (fcellinfo.grid.fmousecell.col = fcellinfo.cell.col) and + (fcellinfo.grid.fmousecell.row = row1) then begin + include(fcellinfo.drawstate,cds_ismousecell); + end; + saveindex:= canvas.save; + fcellinfo.color:= rowcolor(row1); + canvas.intersectcliprect(mr(nullpoint,fcellrect.size)); + bo2:= false; + if canbeforedrawcell then begin + dobeforedrawcell(canvas,bo2); + end; + if not bo2 then begin + if isfocusedcell then begin + drawfocusedcell(canvas); + if calcautocellsize then begin +// fcellinfo.focused:= false; + exclude(fcellinfo.drawstate,cds_active); + drawcell(canvas); //possibly bigger + end; + end + else begin + drawcell(canvas); + end; + end; + if canafterdrawcell then begin + doafterdrawcell(canvas); + end; + canvas.restore(saveindex); + if calcautocellsize then begin + continue; + end; + if not bo2 then begin + drawcelloverlay(canvas,fframe); + end; + if isfocusedcol and (row1 = fcellinfo.grid.ffocusedcell.row) and + needsfocusrect and + fcellinfo.grid.cellhasfocus and fcellinfo.grid.active then begin + if fframe <> nil then begin + canvas.move(fframe.fpaintrect.pos); + end; + drawfocus(canvas); + if fframe <> nil then begin + canvas.remove(fframe.fpaintrect.pos); + end; + end; + finally + if heightextend <> 0 then begin + with fcellinfo do begin //restore original values + dec(fcellrect.cy,heightextend); + dec(rect.cy,heightextend); + dec(innerrect.cy,heightextend); + dec(frameinnerrect.cy,heightextend); + end; + end; + if widthextend <> 0 then begin + with fcellinfo do begin //restore original values + dec(fcellrect.cx,widthextend); + dec(rect.cx,widthextend); + dec(innerrect.cx,widthextend); + dec(frameinnerrect.cx,widthextend); + end; + end; + end; + end; + if hasrowheight then begin + canvas.move(makepoint(0,rowstatelist.internalystep(row1))); + end + else begin + canvas.move(makepoint(0,ystep)); + end; + end; + if not calcautocellsize and (flinewidth > 0) then begin + linewidthbefore:= canvas.linewidth; + if flinewidth = 1 then begin + canvas.linewidth:= 0; + end + else begin + canvas.linewidth:= flinewidth; + end; + if hasrowheight then begin + endy:= rowstatelist.getrowypos(rows[endrow]+1) + end; + if hiddenlines = nil then begin + if hasrowheight then begin + int2:= endy - rowstatelist.getrowypos(rows[0]) + end + else begin + int2:= ystep * length(rows); + end; + canvas.drawline(makepoint(flinepos,-int2), + makepoint(flinepos,-1),flinecolor); + end + else begin + setlength(segments1,endrow-startrow+1); //max + int2:= 0; //index in hiddenlines + int3:= 0; //index in segments1 + bo1:= false; //line started + bo2:= false; //line stopped + for int1:= startrow to endrow do begin + if (int2 > high(hiddenlines)) or + (rows[int1] <> hiddenlines[int2]) then begin + if not bo1 then begin //start line + bo1:= true; + bo2:= false; + with segments1[int3] do begin + a.x:= flinepos; + b.x:= flinepos; + if hasrowheight then begin + a.y:= rowstatelist.getrowypos(rows[int1]) - endy; + end + else begin + a.y:= -ystep * (endrow-int1+1); + end; + end; + end; + end + else begin + if not bo2 and bo1 then begin //stop line + bo2:= true; + bo1:= false; + if hasrowheight then begin + segments1[int3].b.y:= rowstatelist.getrowypos(rows[int1]) - endy - 1; + end + else begin + segments1[int3].b.y:= -ystep * (endrow-int1+1)-1; + end; + inc(int3); + end; + inc(int2); + end; + end; + if bo1 and not bo2 then begin //finish last line + segments1[int3].b.y:= -1; + inc(int3); + end; + setlength(segments1,int3); + canvas.drawlinesegments(segments1,flinecolor); + end; + canvas.linewidth:= linewidthbefore; + end; + autocellsize:= addsize(fcellinfo.autocellsize,framedim1); + end; + end; +end; + +procedure tcol.rowcountchanged(const newcount: integer); +begin + //dummy +end; + +procedure tcol.updatepropwidth; +var + int1: integer; +begin + if not (csloading in fcellinfo.grid.componentstate) and + not (gs_updatelocked in fcellinfo.grid.fstate) then begin +// int1:= tgridframe(fgrid.fframe).fpaintrect.cx; + int1:= fcellinfo.grid.fpropcolwidthref; + if int1 <> 0 then begin + fpropwidth:= fwidth / int1; + end; + end; +end; + +procedure tcol.setwidth(const Value: integer); +begin + if fwidth <> value then begin + if value < 0 then begin + fwidth:= 0; + end + else begin + fwidth:= Value; + end; + updatewidth(fwidth); + updatepropwidth; + fcellinfo.grid.layoutchanged; + if (gps_needsrowheight in fstate) and + not (csloading in fcellinfo.grid.componentstate) then begin +// updatecellrect(fframe); + fcellinfo.grid.updatelayout; + fcellinfo.grid.datacols.rowstate.change(-1); + end; +// updatepropwidth; + end; +end; + +class function tcol.defaultstep(width: integer): integer; +begin + result:= width + defaultgridlinewidth; +end; + +function tcol.step(getscrollable: boolean = true): integer; +begin + result:= 0; + if (getscrollable xor (co_nohscroll in foptions)) and + (not (co_invisible in foptions) or + (csdesigning in fcellinfo.grid.ComponentState)) then begin + result:= fwidth + flinewidth; + end; +end; + +function tcol.scrollable: boolean; +begin + result:= not (co_nohscroll in foptions); +end; + +function tcol.getcolindex: integer; +begin + fcellinfo.grid.internalupdatelayout; + result:= fcellinfo.cell.col; +end; + +procedure tcol.drawfocusedcell(const acanvas: tcanvas); +begin + fcellinfo.grid.drawfocusedcell(acanvas); +end; + +function tcol.getselected(const row: integer): boolean; +begin + if row >= 0 then begin + result:= (gps_selected in fstate) or + (fcellinfo.grid.fdatacols.frowstate.getitempo(row)^.selected and + wholerowselectedmask <> 0); + end + else begin + result:= gps_selected in fstate; + end; +end; + +procedure tcol.invalidatelayout; +//var +// int1: integer; +begin + if not (csreading in fcellinfo.grid.componentstate) then begin + fcellinfo.grid.layoutchanged; + tcols(prop).resetpropwidth; + { + with tgridarrayprop(prop) do begin //grid propewidthref is invalid + for int1:= 0 to high(fitems) do begin + tcol(fitems[int1]).fpropwidth:= 0; + end; + end; + } + end; +end; + +procedure tcol.setoptions(const Value: coloptionsty); +var + valuebefore: coloptionsty; +begin + if foptions <> value then begin + valuebefore:= foptions; + foptions:= value - deprecatedcoloptions; + if csreading in fcellinfo.grid.componentstate then begin + transferdeprecatedcoloptions(value,foptions1); + end; + if bitschanged({$ifdef FPC}longword{$else}longword{$endif}(foptions), + {$ifdef FPC}longword{$else}longword{$endif}(valuebefore), + {$ifdef FPC}longword{$else}longword{$endif}(layoutchangedcoloptions)) then begin + invalidatelayout; + end + else begin + changed; + end; + end; +end; + +procedure tcol.setoptions1(const avalue: coloptions1ty); +var + optionsbefore: coloptions1ty; + opt1: coloptions1ty; +begin +// avalue:= avalue - deprecatedcoloptions1; + optionsbefore:= foptions1; + foptions1:= avalue; + opt1:= coloptions1ty({$ifdef FPC}longword{$else}word{$endif}(optionsbefore) xor + {$ifdef FPC}longword{$else}word{$endif}(foptions1)); + if co1_autorowheight in opt1 then begin + if co1_autorowheight in foptions1 then begin + include(fstate,gps_needsrowheight); + end + else begin + exclude(fstate,gps_needsrowheight); + end; + fcellinfo.grid.checkneedsrowheight; + end; + if opt1 * layoutchangedcoloptions1 <> [] then begin + invalidatelayout; + invalidatemaxsize(); + end; +end; + + +procedure tcol.setfocusrectdist(const avalue: integer); +begin + if ffocusrectdist <> avalue then begin + ffocusrectdist:= avalue; + changed; + end; +end; + +procedure tcol.drawfocus(const acanvas: tcanvas); +begin + drawfocusrect(acanvas,inflaterect(makerect(nullpoint,fcellinfo.rect.size), + -ffocusrectdist)); +end; + +procedure tcol.updatelayout; +var + bo1: boolean; +begin + fcellrect.size.cy:= fcellinfo.grid.fdatarowheight; + fcellrect.size.cx:= fwidth; + fcellrect.y:= 0; + bo1:= fcellinfo.cell.col < 0; + if bo1 and (fcellinfo.cell.col <= tgridarrayprop(prop).ffirstopposite) or + not bo1 and + (fcellinfo.cell.col >= tgridarrayprop(prop).ffirstopposite) then begin + flinepos:= -((flinewidth+1) div 2); + fcellrect.x:= flinewidth; + end + else begin + flinepos:= fwidth + flinewidth div 2; + fcellrect.x:= 0; + end; + inherited; +end; + +procedure tcol.setrowcoloroffset(const avalue: integer); +begin + if frowcoloroffset <> avalue then begin + frowcoloroffset:= avalue; + invalidate; + end; +end; + +procedure tcol.setrowcoloroffsetselect(const avalue: integer); +begin + if frowcoloroffsetselect <> avalue then begin + frowcoloroffsetselect:= avalue; + invalidate; + end; +end; + +procedure tcol.setrowfontoffset(const avalue: integer); +begin + if frowfontoffset <> avalue then begin + frowfontoffset:= avalue; + invalidate; + end; +end; + +procedure tcol.setrowfontoffsetselect(const avalue: integer); +begin + if frowfontoffsetselect <> avalue then begin + frowfontoffsetselect:= avalue; + invalidate; + end; +end; +{ +function tcol.iswidthstored: boolean; +begin + result:= fwidth <> tcols(prop).fwidth; +end; +} +function tcol.getfontselect: tcolselectfont; +begin + getoptionalobject(fcellinfo.grid.componentstate,ffontselect, + {$ifdef FPC}@{$endif}createfontselect); + if ffontselect <> nil then begin + result:= ffontselect; + end + else begin + result:= tcolselectfont(pointer(getfont)); + end; +end; + +procedure tcol.setfontselect(const Value: tcolselectfont); +begin + if value <> ffontselect then begin + setoptionalobject(fcellinfo.grid.ComponentState,value,ffontselect, + {$ifdef FPC}@{$endif}createfontselect); + changed; + end; +end; + +function tcol.isfontselectstored: Boolean; +begin + result:= ffontselect <> nil; +end; + +procedure tcol.setfontactivenum(const avalue: integer); +begin + if ffontactivenum <> avalue then begin + ffontactivenum:= avalue; + invalidate; + end; +end; + +procedure tcol.setfontfocusednum(const avalue: integer); +begin + if ffontfocusednum <> avalue then begin + ffontfocusednum:= avalue; + invalidate; + end; +end; + +procedure tcol.createfontselect; +begin + if ffontselect = nil then begin + ffontselect:= tcolselectfont.create; + ffontselect.onchange:= {$ifdef FPC}@{$endif}fontchanged; + end; +end; + +function tcol.translatetocell(const arow: integer; + const apos: pointty): pointty; +begin + result:= subpoint(apos, + fcellinfo.grid.cellrect(makegridcoord(colindex,arow)).pos); +end; + +function tcol.getmerged(const row: integer): boolean; +begin + result:= false; +end; + +procedure tcol.setmerged(const row: integer; const avalue: boolean); +begin + //dummy +end; + +procedure tcol.clean(const start,stop: integer); +begin + //dummy +end; + +procedure tcol.updatewidth(var avalue: integer); +begin + //dummy +end; + +function tcol.getvisible: boolean; +begin + result:= not (co_invisible in options); +end; + +procedure tcol.setvisible(const avalue: boolean); +begin + if avalue then begin + options:= options - [co_invisible]; + end + else begin + options:= options + [co_invisible]; + end; +end; + +function tcol.getenabled: boolean; +begin + result:= not (co_disabled in options); +end; + +procedure tcol.setenabled(const avalue: boolean); +begin + if avalue then begin + options:= options - [co_disabled]; + end + else begin + options:= options + [co_disabled]; + end; +end; + +function tcol.getreadonly: boolean; +begin + result:= co_readonly in options; +end; + +procedure tcol.setreadonly(const avalue: boolean); +begin + if avalue then begin + options:= options + [co_readonly]; + end + else begin + options:= options - [co_readonly]; + end; +end; + +procedure tcol.updatecolwidth(const arow,acount: integer; + var acolwidth: integer); +var + i1,i2: integer; + info: colpaintinfoty; +begin + fillchar(info,sizeof(info),0); + with info do begin + calcautocellsize:= true; + autocellsize.cx:= acolwidth; + autocellsize.cy:= fcellinfo.grid.datarowheight; + canvas:= fcellinfo.grid.getcanvas; + allocuninitedarray(acount,sizeof(rows[0]),rows); //including invisible rows + i2:= arow; + startrow:= arow; + endrow:= arow + acount - 1; + for i1:= arow to endrow do begin + rows[i1]:= i2; + inc(i2); + end; + paint(info); + acolwidth:= autocellsize.cx; + end; + if (index >= 0) and (co1_autoheaderwidth in foptions1) then begin + for i1:= 0 to grid.ffixrows.count - 1 do begin + with tfixrow(grid.ffixrows.fitems[i1]) do begin + if fcaptions.count > self.index then begin + with tdatacolheader(fcaptions[self.index]) do begin + if not (dco_noautowidth in options) then begin + updateautocellsize(); + if acolwidth < fautocellsize.cx then begin + acolwidth:= fautocellsize.cx; + end; + end; + end; + end; + end; + end; + end; +end; + +procedure tcol.checkmaxwidth; +begin + if not (gps_maxsizevalid in fstate) then begin + include(fstate,gps_maxsizevalid); + fmaxwidth:= 0; + updatecolwidth(0,fcellinfo.grid.rowcount,fmaxwidth); + end; +end; + +function tcol.maxwidth: integer; +begin + checkmaxwidth; + result:= fmaxwidth; +end; + +function tcol.minmaxwidth(): integer; +begin + if fmaxwidth > fwidthmin then begin + result:= fmaxwidth; + end + else begin + result:= fwidthmin; + end; +end; + +procedure tcol.invalidatemaxsize(const arow: integer = -1); +begin + fstate:= fstate - [gps_maxsizevalid,gps_autosizevalid]; +end; + +{ tcolheaderfont } + +class function tcolheaderfont.getinstancepo(owner: tobject): pfont; +begin + result:= @tcolheader(owner).ffont; +end; + +{ tcolheader } + +constructor tcolheader.create(const aowner: tobject; + const aprop: tindexpersistentarrayprop); +begin + initcaptioninfo(finfo); + with finfo do begin + imagenr:= -1; + colorglyph:= cl_glyph; + imagepos:= ip_center; + end; +// finfo.textflags:= defaultcolheadertextflags; + fcolor:= cl_parent; + inherited; + fgrid:= tcolheaders(fowner).fgridprop.fcellinfo.grid; +end; + +destructor tcolheader.destroy; +begin + inherited; + ffont.free; + fframe.free; + fface.free; +end; + +procedure tcolheader.readcaptionpos(reader: treader); +begin + imagepos:= readcaptiontoimagepos(reader); +end; + +procedure tcolheader.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('captionpos',{$ifdef FPC}@{$endif}readcaptionpos,nil,false); +end; + +procedure tcolheader.changed; +begin + tcolheaders(fowner).dochange(findex); +end; + +function tcolheader.getfont: tcolheaderfont; +begin + getoptionalobject(fgrid.componentstate,ffont,{$ifdef FPC}@{$endif}createfont); + if ffont <> nil then begin + result:= ffont; + end + else begin + result:= tcolheaderfont(pointer(tcolheaders(fowner).fgridprop.getfont)); + end; +end; + +procedure tcolheader.setfont(const Value: tcolheaderfont); +begin + if value <> ffont then begin + setoptionalobject(tcolheaders(fowner).fgridprop.fcellinfo.grid.ComponentState, + value,ffont,{$ifdef FPC}@{$endif}createfont); + changed; + end; +end; + +function tcolheader.isfontstored: Boolean; +begin + result:= ffont <> nil; +end; + +procedure tcolheader.createfont; +begin + if ffont = nil then begin + ffont:= tcolheaderfont.create; + ffont.onchange:= {$ifdef FPC}@{$endif}fontchanged; + end; +end; + +procedure tcolheader.fontchanged(const sender: tobject); +begin + changed; +end; + +procedure tcolheader.drawcell(const acanvas: tcanvas; const adest: rectty); +var + si1: sizety; +begin + with finfo do begin + font:= getfont; + dim:= adest; + with cellinfoty(acanvas.drawinfopo^) do begin + if calcautocellsize then begin + si1:= calccaptionsize(acanvas,finfo); + fautocellsize:= rect.size; + fautocellsize.cx:= fautocellsize.cx + si1.cx - adest.cx - fmergedcx; + fautocellsize.cy:= fautocellsize.cy + si1.cy - adest.cy - fmergedcy; + end + else begin + drawcaption(acanvas,finfo); + end; + end; + end; +end; + + //iframe +function tcolheader.getwidget: twidget; +begin + result:= fgrid; +end; + +function tcolheader.getclientrect: rectty; +begin + result:= fgrid.clientrect; +end; + +procedure tcolheader.setlinkedvar(const source: tmsecomponent; + var dest: tmsecomponent; const linkintf: iobjectlink = nil); +begin + fgrid.setlinkedvar(source,dest,linkintf); +end; + +procedure tcolheader.widgetregioninvalid; +begin + fgrid.widgetregioninvalid; +end; + +procedure tcolheader.setframeinstance(instance: tcustomframe); +begin + fframe:= tfixcellframe(instance); +end; + +function tcolheader.getwidgetrect: rectty; +begin + result:= nullrect; +// result:= fcellrect; +end; + +procedure tcolheader.setstaticframe(value: boolean); +begin +// twidget1(getwidget).setstaticframe(value); +end; + +function tcolheader.getstaticframe: boolean; +begin + result:= false; +end; + +function tcolheader.widgetstate: widgetstatesty; +begin + result:= twidget1(getwidget).widgetstate; +end; + +procedure tcolheader.scrollwidgets(const dist: pointty); +begin +// twidget1(getwidget).scrollwidgets(dist); +end; + +procedure tcolheader.clientrectchanged; +begin + changed; +// fgrid.layoutchanged; +end; + +function tcolheader.getcomponentstate: tcomponentstate; +begin + result:= getwidget.componentstate; +end; + +function tcolheader.getmsecomponentstate: msecomponentstatesty; +begin + result:= getwidget.msecomponentstate; +end; + +procedure tcolheader.invalidate; +begin + changed; +// getwidget.invalidate; +end; + +procedure tcolheader.invalidatewidget; +begin + changed; +// getwidget.invalidatewidget; +end; + +procedure tcolheader.invalidaterect(const rect: rectty; + const org: originty = org_client; const noclip: boolean = false); +begin + changed; +// getwidget.invalidaterect(rect,org); +end; + +//iface +function tcolheader.translatecolor(const acolor: colorty): colorty; +begin + result:= acolor; +end; + +procedure tcolheader.setcaption(const avalue: msestring); +begin + finfo.caption.text:= avalue; + changed; +end; + +procedure tcolheader.settextflags(const avalue: textflagsty); +begin + if finfo.textflags <> avalue then begin + finfo.textflags:= checktextflags(finfo.textflags,avalue); + changed; + end; +end; + +function tcolheader.getframe: tfixcellframe; +begin + fgrid.getoptionalobject(fframe,{$ifdef FPC}@{$endif}createframe); + result:= fframe; +end; + +procedure tcolheader.setframe(const avalue: tfixcellframe); +begin + fgrid.setoptionalobject(avalue,fframe,{$ifdef FPC}@{$endif}createframe); + clientrectchanged; +end; + +function tcolheader.getface: tfixcellface; +begin + fgrid.getoptionalobject(fface,{$ifdef FPC}@{$endif}createface); + result:= fface; +end; + +procedure tcolheader.setface(const avalue: tfixcellface); +begin + fgrid.setoptionalobject(avalue,fface,{$ifdef FPC}@{$endif}createface); + fgrid.invalidate; +end; + +procedure tcolheader.createframe(); +begin + if fframe = nil then begin + tfixcellframe.create(iframe(self)); + end; +end; + +procedure tcolheader.createface(); +begin + if fface = nil then begin + fface:= tfixcellface.create(iface(self)); + end; +end; + +procedure tcolheader.setcolor(const avalue: colorty); +begin + if fcolor <> avalue then begin + fcolor:= avalue; + changed; + end; +end; + +procedure tcolheader.setmergecols(const avalue: integer); +begin + if fmergecols <> avalue then begin + fmergecols:= avalue; + fgrid.layoutchanged; + if fgrid.componentstate * [csloading,csdesigning,csdestroying] = + [csdesigning] then begin + fgrid.updatelayout; //check colheaders.count + end; + end; +end; + +procedure tcolheader.setmergerows(const avalue: integer); +begin + if fmergerows <> avalue then begin + fmergerows:= avalue; + fgrid.layoutchanged; + if fgrid.componentstate * [csloading,csdesigning,csdestroying] = + [csdesigning] then begin + fgrid.updatelayout; //check colheaders.count + end; + end; +end; + +function tcolheader.getframestateflags: framestateflagsty; +begin + result:= []; +end; + +procedure tcolheader.setimagenr(const avalue: imagenrty); +begin + if finfo.imagenr <> avalue then begin + finfo.imagenr:= avalue; + changed; + end; +end; + +procedure tcolheader.setcolorglyph(const avalue: colorty); +begin + if finfo.colorglyph <> avalue then begin + finfo.colorglyph:= avalue; + changed; + end; +end; + +procedure tcolheader.setimagepos(const avalue: imageposty); +begin + if finfo.imagepos <> avalue then begin + finfo.imagepos:= simpleimagepos[avalue]; + changed; + end; +end; + +procedure tcolheader.setimagedist(const avalue: integer); +begin + if finfo.imagedist <> avalue then begin + finfo.imagedist:= avalue; + changed; + end; +end; + +procedure tcolheader.setcaptiondist(const avalue: integer); +begin + if finfo.captiondist <> avalue then begin + finfo.captiondist:= avalue; + changed; + end; +end; + +function tcolheader.getimagelist: timagelist; +begin + result:= finfo.imagelist; +end; + +procedure tcolheader.setimagelist(const avalue: timagelist); +begin + setlinkedvar(avalue,tmsecomponent(finfo.imagelist)); + changed; +end; + +{ tdatacolheader } + +constructor tdatacolheader.create(const aowner: tobject; + const aprop: tindexpersistentarrayprop); +begin + foptions:= [dco_hintclippedtext]; + inherited; +end; + +procedure tdatacolheader.setoptions(const avalue: datacolheaderoptionsty); +begin + if foptions <> avalue then begin + foptions:= avalue; + changed(); + end; +end; + +procedure tdatacolheader.drawcell(const acanvas: tcanvas; const adest: rectty); +var + rect1: rectty; + al1: alignmentsty; + int1,int2: integer; +begin + if (dco_colsort in foptions) and (index < fgrid.datacols.count) then begin + rect1:= adest; + al1:= [al_right,al_ycentered]; + with tdatacol(fgrid.fdatacols.fitems[index]) do begin + if co_sortdescend in options then begin + int1:= ord(stg_arrowupsmall); + end + else begin + int1:= ord(stg_arrowdownsmall); + end; + if not (fgrid.hassort) or + (co_nosort in options) or + (fgrid.datacols.sortcol >= 0) and (fgrid.datacols.sortcol <> index) or + (fgrid.datacols.sortcol < 0) and + (og_nodefaultsort in fgrid.foptionsgrid) then begin + if dco_nodisabledsortindicator in self.foptions then begin + int1:= -1; + end; + include(al1,al_grayed); + end; + end; + int2:= (15-sortglyphwidth) div 2; + inc(rect1.cx,int2); + if not cellinfoty(acanvas.drawinfopo^).calcautocellsize then begin + stockobjects.glyphs.paint(acanvas,int1,rect1,al1,finfo.colorglyph); + end; + int2:= sortglyphwidth+int2; + if int1 >= 0 then begin + with rect1 do begin + acanvas.subcliprect(mr(x+cx-int2,y,int2,cy)); + end; + end; + dec(rect1.cx,int2); + inherited drawcell(acanvas,rect1); + end + else begin + inherited; + end; +end; + +{ tcolheaders } + +constructor tcolheaders.create(const agridprop: tgridprop); +begin + fgridprop:= agridprop; + inherited create(self,indexpersistentclassty(getitemclasstype)); +end; + +procedure tcolheaders.movecol(const curindex,newindex: integer); +var + int1: integer; +begin + if (curindex <= high(fitems)) or (newindex <= high(fitems)) then begin + int1:= curindex; + if newindex > high(fitems) then begin + count:= newindex + 1; + end; + if curindex > high(fitems) then begin + count:= high(fitems) + 2; + int1:= high(fitems); + end; + move(int1,newindex); + end; +end; + +procedure tcolheaders.colcountchanged(const acount: integer); +begin + //dummy +end; + +procedure tcolheaders.updatelayout(const cols: tgridarrayprop); +var + int1,int2,int3,int4: integer; + headers1: tcolheaders; + header1: tcolheader; + lastmergedcol: integer; + lastmergedrow: integer; + bo1: boolean; + cell1: gridcoordty; + mergedcxbefore: int32; +begin + int2:= count; + for int1:= 0 to count - 1 do begin + with tcolheader(fitems[int1]) do begin //extend count for mergecols + fmergeflags:= []; + int3:= int1 + fmergecols; + if int3 >= int2 then begin + int2:= int3 + 1; + end; + end; + end; + if int2 > count then begin + count:= int2; + end; + cell1.row:= -fgridprop.index - 1; + for int1:= 0 to count -1 do begin + if ffixcol then begin + cell1.col:= -int1-1; + end + else begin + cell1.col:= int1; + end; + with tcolheader(fitems[int1]) do begin + mergedcxbefore:= fmergedcx; + lastmergedcol:= int1 + fmergecols; + if lastmergedcol >= count then begin + lastmergedcol:= count - 1; + end; + if lastmergedcol >= cols.count then begin + lastmergedcol:= cols.count - 1; + end; + if int1 < lastmergedcol then begin + fmergedcx:= tgridprop(cols.fitems[int1]).flinewidth - + tgridprop(cols.fitems[lastmergedcol]).flinewidth; + if cols.freversedorder then begin + fmergedx:= -fmergedcx; + end + else begin + fmergedx:= 0; + end; + bo1:= tgridprop(cols.fitems[int1]).scrollable; + for int2:= int1 + 1 to lastmergedcol do begin + with tcolheader(fitems[int2]) do begin + include(fmergeflags,cmf_h); + frefcell:= cell1; + end; + int4:= tgridprop(cols.fitems[int2]).step(bo1); + inc(fmergedcx,int4); + if cols.freversedorder then begin + dec(fmergedx,int4); + end; + end; + end + else begin + fmergedcx:= 0; + fmergedx:= 0; + end; + if not ffixcol and (mergedcxbefore <> fmergedcx) and + not (dco_noautowidth in tdatacolheader(fitems[int1]).options) and + (int1 < cols.count) and + (co1_autoheaderwidth in tcol(cols.fitems[int1]).options1) then begin + tfixrow(fgridprop).invalidatemaxsize(int1); + end; + + lastmergedrow:= fgridprop.index + fmergerows; + if lastmergedrow >= fgrid.fixrows.count then begin + lastmergedrow:= fgrid.fixrows.count-1; + end; + if fgridprop.index < lastmergedrow then begin + fmergedcy:= fgridprop.flinewidth - + tfixrow(fgrid.ffixrows.fitems[lastmergedrow]).flinewidth; + fmergedy:= -fmergedcy; + if lastmergedcol < int1 then begin + lastmergedcol:= int1; + end; + bo1:= fgridprop.index >= fgrid.ffixrows.count - + fgrid.ffixrows.foppositecount; + for int2:= fgridprop.index + 1 to lastmergedrow do begin + with tfixrow(fgrid.ffixrows.fitems[int2]) do begin + int4:= step; + inc(fmergedcy,int4); + dec(fmergedy,int4); + if ffixcol then begin + headers1:= fcaptionsfix; + end + else begin + headers1:= fcaptions; + end; + end; + if headers1.count <= lastmergedcol then begin + headers1.count:= lastmergedcol + 1; + end; + header1:= tcolheader(headers1.fitems[int1]); + include(header1.fmergeflags,cmf_v); + header1.frefcell:= cell1; + if not bo1 then begin + include(header1.fmergeflags,cmf_rline); + end; + for int3:= int1 + 1 to lastmergedcol do begin + with tcolheader(headers1.fitems[int3]) do begin + if not bo1 then begin + fmergeflags:= fmergeflags + [cmf_v,cmf_h,cmf_rline]; + end + else begin + fmergeflags:= fmergeflags + [cmf_v,cmf_h]; + end; + frefcell:= cell1; + end; + end; + end; + if bo1 then begin + for int2:= fgridprop.index to lastmergedrow - 1 do begin + with tfixrow(fgrid.ffixrows.fitems[int2]) do begin + if ffixcol then begin + headers1:= fcaptionsfix; + end + else begin + headers1:= fcaptions; + end; + end; + header1:= tcolheader(headers1.fitems[int1]); + include(header1.fmergeflags,cmf_rline); + for int3:= int1 + 1 to lastmergedcol do begin + with tcolheader(headers1.fitems[int3]) do begin + include(fmergeflags,cmf_rline); + end; + end; + end; + end; + end + else begin + fmergedcy:= 0; + fmergedy:= 0; + end; + end; + end; + fmergeflags:= []; + for int1:= 0 to count - 1 do begin + fmergeflags:= fmergeflags + tcolheader(fitems[int1]).fmergeflags; + end; +end; + +procedure tcolheaders.dosizechanged; +begin + inherited; + fgridprop.fcellinfo.grid.layoutchanged; +end; + +{ tfixcolheaders } + +constructor tfixcolheaders.create(const agridprop: tgridprop); +begin + ffixcol:= true; + inherited; +end; + +class function tfixcolheaders.getitemclasstype: persistentclassty; +begin + result:= tcolheader; +end; + +function tfixcolheaders.getitems(const index: integer): tcolheader; +begin + result:= tcolheader(inherited getitems(-index-1)); +end; + +procedure tfixcolheaders.setitems(const index: integer; + const Value: tcolheader); +begin + inherited getitems(-index-1).Assign(value); +end; + +{ tdatacolheaders } + +class function tdatacolheaders.getitemclasstype: persistentclassty; +begin + result:= tdatacolheader; +end; + +function tdatacolheaders.getitems(const index: integer): tdatacolheader; +begin + result:= tdatacolheader(inherited getitems(index)); +end; + +procedure tdatacolheaders.setitems(const index: integer; + const Value: tdatacolheader); +begin + inherited getitems(index).Assign(value); +end; + +{ tfixrow } + +constructor tfixrow.create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); +begin + ftextinfo.flags:= defaultfixcoltextflags; + fcaptions:= tdatacolheaders.create(self); + fcaptions.onchange:= {$ifdef FPC}@{$endif}captionchanged; + fcaptionsfix:= tfixcolheaders.create(self); + fcaptionsfix.onchange:= {$ifdef FPC}@{$endif}captionchanged; +// fhints:= tmsestringarrayprop.create; + inherited create(agrid,aowner); + fheight:= agrid.fdatarowheight; +end; + +destructor tfixrow.destroy; +begin + inherited; + fcaptions.free; + fcaptionsfix.free; +end; + +procedure tfixrow.movecol(const curindex,newindex: integer; const aisfix: boolean); +begin + if aisfix then begin + fcaptionsfix.movecol(curindex,newindex); + end + else begin + fcaptions.movecol(curindex,newindex); + end; +end; + +procedure tfixrow.datacolscountchanged(const acount: integer); +begin + fcaptions.colcountchanged(acount); +end; + +procedure tfixrow.fixcolscountchanged(const acount: integer); +begin + fcaptionsfix.colcountchanged(acount); +end; + + +procedure tfixrow.reorderdatacols(const neworder: integerarty); +begin + if fcaptions.count > 0 then begin + fcaptions.count:= length(neworder); + fcaptions.reorder(neworder); + end; +end; + +procedure tfixrow.orderdatacols(const oldorder: integerarty); +begin + if fcaptions.count > 0 then begin + fcaptions.count:= length(oldorder); + fcaptions.order(oldorder); + end; +end; + +procedure tfixrow.synctofontheight; +begin + if fframe <> nil then begin + fframe.checkstate; + height:= {height + }font.glyphheight + fframe.finnerframe.top + + fframe.finnerframe.bottom; + end + else begin + with tgridarrayprop(prop).finnerframe do begin + height:= font.glyphheight + top + bottom; + end; + end; +end; + +function tfixrow.getrowindex: integer; +begin + fcellinfo.grid.internalupdatelayout; + result:= fcellinfo.cell.row; +end; + +procedure tfixrow.setheight(const Value: integer); +begin + if fheight <> value then begin + if value < 1 then begin + fheight:= 1; + end + else begin + fheight := Value; + end; + fcellinfo.grid.layoutchanged; + end; +end; + +procedure tfixrow.drawcell(const canvas: tcanvas); +var + int1,linewidthbefore: integer; + frame1: tcustomframe; + face1: tcustomface; + headers1: tcolheaders; + pt1: pointty; + sizebefore: sizety; + linemerged: boolean; + +label + endlab,endlab2; +begin + with cellinfoty(canvas.drawinfopo^) do begin + if cell.col >= 0 then begin + int1:= cell.col; + headers1:= fcaptions; + end + else begin + headers1:= fcaptionsfix; + int1:= -cell.col-1; + end; + + frame1:= fframe; + face1:= fface; + pt1:= nullpoint; + sizebefore:= fcellrect.size; + linemerged:= false; + if (int1 >= 0) and (int1 < headers1.count) then begin + with tcolheader(headers1.fitems[int1]) do begin + linemerged:= cmf_rline in fmergeflags; + if fmergeflags * [cmf_v,cmf_h] <> [] then begin + goto endlab; + end; + if fcolor <> cl_parent then begin + fcellinfo.color:= fcolor; + end; + inc(fcellrect.cx,fmergedcx); + inc(fcellrect.cy,fmergedcy); + pt1.x:= fmergedx; + pt1.y:= fmergedy; + if fframe <> nil then begin + frame1:= fframe; + tframe1(frame1).checkstate; + end; + if fface <> nil then begin + face1:= fface; + end; + end; + end; + canvas.move(pt1); + updatecellrect(frame1); + ftextinfo.dest:= fcellinfo.innerrect; + ftextinfo.clip:= fcellinfo.rect; + canvas.save; + canvas.intersectcliprect(makerect(nullpoint,fcellrect.size)); + if not calcautocellsize then begin + drawcellbackground(canvas,frame1,face1); + end; + if (int1 >= 0) and (int1 < headers1.count) then begin + tcolheader(headers1.fitems[int1]).drawcell(canvas,ftextinfo.dest); + end + else begin + if (fnumstep <> 0) and (cell.col >= 0) then begin + ftextinfo.text.text:= inttostrmse(fnumstart+fnumstep*cell.col); + if calcautocellsize then begin + textrect(canvas,ftextinfo); + end + else begin + drawtext(canvas,ftextinfo); + end; + end; + end; + canvas.restore; + if calcautocellsize then begin + goto endlab2; + end; + drawcelloverlay(canvas,frame1); + canvas.remove(makepoint(0,pt1.y)); +endlab: + if (flinewidth > 0) and not linemerged then begin + linewidthbefore:= canvas.linewidth; + if flinewidth = 1 then begin + canvas.linewidth:= 0; + end + else begin + canvas.linewidth:= flinewidth; + end; + canvas.drawline(makepoint(fcellrect.x,flinepos), + makepoint(fcellrect.x+fcellrect.cx{-1},flinepos),colorline); + canvas.linewidth:= linewidthbefore; + end; + canvas.remove(makepoint(pt1.x,0)); +endlab2: + fcellrect.size:= sizebefore; + end; +end; + +procedure tfixrow.paint(const info: rowpaintinfoty); +var + pt1,pt2: pointty; + +var + linewidthbefore: integer; + color1: colorty; + canbeforedrawcell,canafterdrawcell: boolean; + + procedure paintcols(const range: rangety); + var + int1,int2,int3: integer; + bo1,bo2: boolean; + headers1: tcolheaders; + begin + with info do begin + if fix then begin + headers1:= fcaptionsfix; + end + else begin + headers1:= fcaptions; + end; + int2:= range.startindex; + if range.startindex < headers1.count then begin + for int3:= range.startindex downto 0 do begin + int2:= int3; + if not (cmf_h in tcolheader(headers1.fitems[int3]).fmergeflags) then begin + break; + end; + end; + end; + for int1:= int2 to range.endindex do begin + with tcol(cols.fitems[int1]) do begin + bo1:= (colrange.scrollables xor (co_nohscroll in foptions)) and + (not (co_invisible in foptions) or + (csdesigning in fcellinfo.grid.componentstate)); + if bo1 then begin + self.fcellrect.cx:= fwidth; + self.fcellinfo.cell.col:= fcellinfo.cell.col; + pt2.x:= pt1.x + fstart + fcellrect.x; + end; + end; + if bo1 then begin + fcellinfo.color:= color1; + if fix then begin + fcellinfo.cell.col:= -int1-1; + end + else begin + fcellinfo.cell.col:= int1; + if (fcolorselect <> cl_none) and + (gps_selected in fcellinfo.grid.fdatacols[int1].fstate) then begin + if fcolorselect <> cl_default then begin + fcellinfo.color:= fcolorselect; + end + else begin + fcellinfo.color:= defaultselectedcellcolor; + end; + end; + end; + canvas.origin:= pt2; + bo2:= false; + if canbeforedrawcell then begin + fonbeforedrawcell(self,canvas,fcellinfo,bo2); + end; + if not bo2 then begin + drawcell(canvas); + end; + if canafterdrawcell then begin + fonafterdrawcell(self,canvas,fcellinfo); + end; + end; + end; + end; + end; + +begin + if (not (co_invisible in foptions) or info.calcautocellsize) or + (csdesigning in fcellinfo.grid.ComponentState) then begin + with info do begin + fcellinfo.calcautocellsize:= calcautocellsize; + if ffont = nil then begin + ftextinfo.font:= fcellinfo.grid.getfont; + end + else begin + ftextinfo.font:= ffont; + end; + canvas.drawinfopo:= @fcellinfo; + if fcolor <> cl_default then begin + color1:= fcolor; + end + else begin + color1:= fcellinfo.grid.actualopaquecolor; + end; + pt1:= canvas.origin; + linewidthbefore:= canvas.linewidth; + if fix then begin + fcellinfo.colorline:= flinecolorfix; + end + else begin + fcellinfo.colorline:= flinecolor; + end; + pt2.y:= pt1.y+fcellrect.y; + canbeforedrawcell:= fcellinfo.grid.canevent(tmethod(fonbeforedrawcell)); + canafterdrawcell:= fcellinfo.grid.canevent(tmethod(fonafterdrawcell)); + paintcols(colrange.range2); + paintcols(colrange.range1); + canvas.linewidth:= linewidthbefore; //??? + canvas.origin:= pt1; + end; + end; +end; + +procedure tfixrow.updateautocellsize(); +var + info: rowpaintinfoty; +begin + if not (gps_autosizevalid in fstate) then begin + include(fstate,gps_autosizevalid); + info.calcautocellsize:= true; + info.canvas:= fcellinfo.grid.getcanvas; + info.cols:= fcellinfo.grid.fdatacols; + info.fix:= false; + info.colrange.range1.startindex:= 0; + info.colrange.range1.endindex:= info.cols.count-1; + info.colrange.range2.startindex:= 0; + info.colrange.range2.endindex:= -1; + info.colrange.scrollables:= false; + paint(info); + info.colrange.scrollables:= true; + paint(info); + end; +end; + +function tfixrow.step(getscrollable: boolean = true): integer; +begin + if (not (co_invisible in foptions) or + (csdesigning in fcellinfo.grid.ComponentState)) then begin + result:= fheight+flinewidth; + end + else begin + result:= 0; + end; +end; + +procedure tfixrow.updatelayout; +begin + fcellrect.size.cy:= fheight; + if fcellinfo.cell.row <= tgridarrayprop(prop).ffirstopposite then begin + flinepos:= -((flinewidth+1) div 2); + fcellrect.y:= flinewidth; +// fcellrect.y:= 0; + end + else begin + flinepos:= fheight + flinewidth div 2; + fcellrect.y:= 0; + end; + inherited; +end; + +procedure tfixrow.updatemergedcells; +begin + fcaptionsfix.updatelayout(fcellinfo.grid.ffixcols); + fcaptions.updatelayout(fcellinfo.grid.fdatacols); +end; + +procedure tfixrow.changed; +begin + inherited; + exclude(fstate,gps_autosizevalid); + if fcellinfo.grid.caninvalidate then begin + fcellinfo.grid.invalidaterect( + fcellinfo.grid.cellrect(makegridcoord(invalidaxis,getrowindex))); + end; +end; + +procedure tfixrow.setcaptions(const Value: tdatacolheaders); +begin + fcaptions.assign(Value); +end; + +procedure tfixrow.setcaptionsfix(const Value: tfixcolheaders); +begin + fcaptionsfix.assign(Value); +end; + +procedure tfixrow.setnumstart(const Value: integer); +begin + if fnumstep <> value then begin + fnumstart := Value; + changed; + end; +end; + +procedure tfixrow.setnumstep(const Value: integer); +begin + if fnumstep <> value then begin + fnumstep := Value; + changed; + end; +end; + +procedure tfixrow.settextflags(const Value: textflagsty); +var + int1: integer; +begin + if ftextinfo.flags <> value then begin + ftextinfo.flags := Value; + if not (csloading in fcellinfo.grid.componentstate) then begin + for int1:= 0 to fcaptions.count - 1 do begin + fcaptions[int1].textflags:= value; + end; + end; + end; +end; + +procedure tfixrow.captionchanged(const sender: tarrayprop; + const aindex: integer); +begin + if aindex < 0 then begin + changed; + end + else begin + if sender = fcaptionsfix then begin + cellchanged(aindex-fcaptionsfix.count); + end + else begin + cellchanged(aindex); + end; + end; +end; + +procedure tfixrow.invalidatemaxsize(const acol: int32); +begin + if acol >= 0 then begin + fstate:= fstate - [gps_autosizevalid,gps_maxsizevalid]; + if (acol < fcaptions.count) and (acol < grid.fdatacols.count){ and + (dco_autowidth in tdatacolheader(fcaptions.fitems[acol]).options)} then begin + with tdatacol(grid.fdatacols.fitems[acol]) do begin + invalidatemaxsize(); + end; + end; + end; +end; + +procedure tfixrow.cellchanged(const acol: integer); +begin + if not (csloading in fcellinfo.grid.componentstate) then begin + invalidatemaxsize(acol); + fcellinfo.grid.invalidatecell(makegridcoord(acol,getrowindex)); + end; +end; + +procedure tfixrow.setoptionsfix(const avalue: fixrowoptionsty); +begin + foptionsfix:= avalue; + if (fro_invisible in avalue) xor (co_invisible in foptions) then begin + if fro_invisible in avalue then begin + foptions:= foptions + [co_invisible]; + end + else begin + foptions:= foptions - [co_invisible]; + end; + fcellinfo.grid.layoutchanged; + end; +end; + +function tfixrow.getvisible: boolean; +begin + result:= not (fro_invisible in options); +end; + +procedure tfixrow.setvisible(const avalue: boolean); +begin + if avalue then begin + options:= options - [fro_invisible]; + end + else begin + options:= options + [fro_invisible]; + end; +end; + +procedure tfixrow.buttoncellevent(var info: celleventinfoty); +var + opt1: datacolheaderoptionsty; +begin + if (info.cell.col >= 0) and (info.cell.col < fcaptions.count) then begin + opt1:= fcaptions[info.cell.col].options; + if (dco_colsort in opt1) and + iscellclick(info,[ccr_nokeyreturn]{,[ss_ctrl]}) then begin + with fcellinfo.grid.datacols[info.cell.col] do begin + if ((opt1 * [dco_wholecellsortclick,dco_nodisabledsortindicator] <> []) and + (info.mouseeventinfopo^.pos.x > 0) or + (info.mouseeventinfopo^.pos.x > fwidth - 15)) and + //button click of merged cells not supported + not (co_nosort in foptions) then begin + if (fcellinfo.grid.datacols.sortcol = info.cell.col) and + fcellinfo.grid.hassort then begin + if ss_ctrl in info.mouseeventinfopo^.shiftstate then begin + if fcellinfo.grid.datacols.sortcoldefault >= 0 then begin + fcellinfo.grid.datacols.sortcol:= + fcellinfo.grid.datacols.sortcoldefault; + end + else begin + fcellinfo.grid.sorted:= false; + fcellinfo.grid.fdatacols.fsortcol:= -1; + end; + end + else begin + if co_sortdescend in foptions then begin + options:= foptions - [co_sortdescend]; + end + else begin + options:= foptions + [co_sortdescend]; + end; + fcellinfo.grid.datacols.sortcol:= fcellinfo.grid.datacols.sortcol; + //call updatesortcol + end; + end + else begin + fcellinfo.grid.datacols.sortcol:= info.cell.col; + if fcellinfo.grid.datacols.sortcol = info.cell.col then begin + fcellinfo.grid.sorted:= true; + end; + end; + end; + end; + end; + end; +end; + +{ tgridarrayprop } + +constructor tgridarrayprop.create(aowner: tcustomgrid; + aclasstype: gridpropclassty); +begin + ffirstopposite:= -bigint; + fgrid:= aowner; + flinewidth:= defaultgridlinewidth; + flinecolorfix:= defaultfixlinecolor; + fcolor:= cl_default; + fcolorselect:= cl_default; + fcoloractive:= cl_none; + fcolorfocused:= cl_none; + fcursor:= cr_default; + finnerframe:= minimalframe; + inherited create(self,aclasstype); +end; + +procedure tgridarrayprop.setcursor(const avalue: cursorshapety); +var + int1: integer; +begin + if fcursor <> avalue then begin + fcursor := avalue; + if not (csloading in fgrid.componentstate) then begin + for int1:= 0 to count - 1 do begin + tgridprop(items[int1]).cursor:= avalue; + end; + end; + end; +end; + +procedure tgridarrayprop.setlinewidth(const Value: integer); +var + int1: integer; +begin + if flinewidth <> value then begin + flinewidth := Value; + if not (csloading in fgrid.componentstate) then begin + for int1:= 0 to count - 1 do begin + tgridprop(items[int1]).linewidth:= value; + end; + end; + end; +end; + +procedure tgridarrayprop.setlinecolor(const Value: colorty); +var + int1: integer; +begin + if flinecolor <> value then begin + flinecolor := Value; + if not (csloading in fgrid.componentstate) then begin + for int1:= 0 to count - 1 do begin + tgridprop(items[int1]).linecolor:= value; + end; + end; + end; +end; + +procedure tgridarrayprop.setlinecolorfix(const Value: colorty); +var + int1: integer; +begin + if flinecolorfix <> value then begin + flinecolorfix := Value; + if not (csloading in fgrid.componentstate) then begin + for int1:= 0 to count - 1 do begin + tgridprop(items[int1]).linecolorfix:= value; + end; + end; + end; +end; + +procedure tgridarrayprop.setcolor(const avalue: colorty); +var + int1: integer; +begin + if fcolor <> avalue then begin + fcolor:= avalue; + if not (csloading in fgrid.componentstate) then begin + for int1:= 0 to count - 1 do begin + tgridprop(items[int1]).color:= avalue; + end; + end; + end; +end; + +procedure tgridarrayprop.setcolorselect(const avalue: colorty); +var + int1: integer; +begin + if fcolorselect <> avalue then begin + fcolorselect:= avalue; + if not (csloading in fgrid.componentstate) then begin + for int1:= 0 to count - 1 do begin + tgridprop(items[int1]).colorselect:= avalue; + end; + end; + end; +end; + +procedure tgridarrayprop.setcoloractive(avalue: colorty); +var + int1: integer; +begin + if avalue = cl_invalid then begin + avalue:= cl_none; + end; + if fcoloractive <> avalue then begin + fcoloractive:= avalue; + if not (csloading in fgrid.componentstate) then begin + for int1:= 0 to count - 1 do begin + tgridprop(items[int1]).coloractive:= avalue; + end; + end; + end; +end; + +procedure tgridarrayprop.setcolorfocused(avalue: colorty); +var + int1: integer; +begin + if avalue = cl_invalid then begin + avalue:= cl_none; + end; + if fcolorfocused <> avalue then begin + fcolorfocused:= avalue; + if not (csloading in fgrid.componentstate) then begin + for int1:= 0 to count - 1 do begin + tgridprop(items[int1]).colorfocused:= avalue; + end; + end; + end; +end; + +function tgridarrayprop.fixindex(const index: integer): integer; +begin + result:= -index-1; +end; + +procedure tgridarrayprop.countchanged; +begin + fgrid.layoutchanged; +end; + +procedure tgridarrayprop.dochange(const aindex: integer); +begin + fgrid.layoutchanged; + inherited; +end; + +procedure tgridarrayprop.createitem(const index: integer; var item: tpersistent); +begin + item:= gridpropclassty(fitemclasstype).create(fgrid,self); +end; + +procedure tgridarrayprop.setcount1(acount: integer; doinit: boolean); +begin + if acount < foppositecount then begin + foppositecount:= acount; + end; + inherited; + countchanged; +end; + +function tgridarrayprop.geoitems(const aindex: integer): tgridprop; +var + int1: integer; +begin + if freversedorder then begin + int1:= aindex + ffirstopposite + 2; + if int1 > 0 then begin + result:= tgridprop(fitems[count-int1]); + end + else begin + result:= tgridprop(fitems[-int1]); + end; + end + else begin + result:= tgridprop(fitems[aindex]); + end; +end; + +function tgridarrayprop.geotoindex(const ageoindex: integer): integer; +var + int1: integer; +begin + if freversedorder then begin + int1:= count - foppositecount - ageoindex - 1; + if ageoindex + foppositecount - count >= 0 then begin + result:= count + int1; + end + else begin + result:= int1; + end; + end + else begin + result:= ageoindex; + end; +end; + +procedure tgridarrayprop.updatelayout; +var + int1,int2,int3: integer; +begin + if freversedorder then begin //fixrows or fixcols + int3:= getclientsize; + int2:= 0; + for int1:= count - foppositecount to count - 1 do begin + with tgridprop(fitems[int1]) do begin + fend:= int3; + dec(int3,step); + inc(int2,step); + fstart:= int3; + end; + end; + ftotsize:= int2; + int2:= 0; + for int1:= count - foppositecount - 1 downto 0 do begin + with tgridprop(fitems[int1]) do begin + if not (co_nohscroll in foptions) then begin + fstart:= int2; + inc(int2,step); + fend:= int2; + end; + end; + end; + ffirstsize:= int2; + ftotsize:= ftotsize + int2; + end + else begin //datacols + with tdatacols(self) do begin + int2:= 0; + fscrollsize:= 0; + for int1:= ffirsthscrollindex to count - foppositecount - 1 do begin + with tgridprop(fitems[int1]) do begin + // if not (co_nohscroll in foptions) then begin + fstart:= int2; + inc(int2,step); + fend:= int2; + // end; + end; + end; + fscrollsize:= int2; + end; + end; +end; + +procedure tgridarrayprop.setoppositecount(const value: integer); +begin + if value <> foppositecount then begin + if csloading in fgrid.componentstate then begin + foppositecount:= value; //count is invalid + end + else begin + if count < value then begin + foppositecount:= count; + end + else begin + foppositecount := Value; + end; + fgrid.layoutchanged; + end; + end; +end; + +procedure tgridarrayprop.getindexrange(startpos, length: integer; + out range: cellaxisrangety; ascrollables: boolean = true); + + procedure calcrange(first,last: integer; out range: rangety); + var + int1: integer; + begin //todo: optimize + with range do begin + endindex:= -1; + if first > last then begin + startindex:= 0; + end + else begin + startindex:= -1; + for int1:= first to last do begin + with geoitems(int1) do begin + if ascrollables xor (co_nohscroll in foptions) then begin + if fstart >= length then begin + if int1 > first then begin + endindex:= int1 - 1; + end; + break; + end; + if (startindex < 0) and (fend > startpos) then begin + startindex:= int1; + end; + end; + end; + end; + if startindex < 0 then begin + startindex:= 0; + end + else begin + if endindex < 0 then begin + endindex:= last; + end; + end; + if freversedorder and (endindex >= startindex) then begin + startindex:= geotoindex(startindex); + endindex:= geotoindex(endindex); + if startindex > endindex then begin + int1:= startindex; + startindex:= endindex; + endindex:= int1; + end; + end; + end; + end; + end; + +begin + length:= startpos + length; + with range do begin + scrollables:= ascrollables; + calcrange(count-foppositecount,count-1,range1); + calcrange(0,count-foppositecount-1,range2); + end; +end; + +function tgridarrayprop.itematpos(const pos: integer; + const getscrollable: boolean = true): integer; +var + int1,int2: integer; +begin + result:= invalidaxis; + for int1:= 0 to count - 1 do begin + with geoitems(int1) do begin + if (not (co_invisible in foptions) or + (csdesigning in fgrid.componentstate)) and + (getscrollable xor (co_nohscroll in foptions)) then begin + if (pos >= fstart) and (pos < fend) then begin + if freversedorder then begin + int2:= int1 + ffirstopposite + 2; + if int2 > 0 then begin + result:= count-int2; + end + else begin + result:= -int2; + end; + end + else begin + result:= int1; + end; + break; + end; + end; + end; + end; +end; + +function tgridarrayprop.scrollablecount: integer; +var + int1: integer; +begin + result:= 0; + for int1:= 0 to count - 1 do begin + with tgridprop(items[int1]) do begin + if (not (co_invisible in foptions) or (csdesigning in fgrid.componentstate)) and + not(co_nohscroll in foptions) then begin + inc(result); + end; + end; + end; +end; + +procedure tgridarrayprop.fontchanged; +var + int1: integer; +begin + for int1:= 0 to count -1 do begin + tgridprop(items[int1]).fontchanged(fgrid); + end; +end; + +procedure tgridarrayprop.checktemplate(const sender: tobject); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + with tgridprop(fitems[int1]) do begin + if fframe <> nil then begin + fframe.checktemplate(sender); + end; + if face <> nil then begin + fface.checktemplate(sender); + end; + end; + end; +end; + +procedure tgridarrayprop.setinnerframe(const avalue: framety); +begin + finnerframe:= avalue; + fgrid.layoutchanged; +end; + +procedure tgridarrayprop.setinnerframe_left(const avalue: integer); +begin + if finnerframe.left <> avalue then begin + finnerframe.left:= avalue; + fgrid.layoutchanged; + end; +end; + +procedure tgridarrayprop.setinnerframe_top(const avalue: integer); +begin + if finnerframe.top <> avalue then begin + finnerframe.top:= avalue; + fgrid.layoutchanged; + end; +end; + +procedure tgridarrayprop.setinnerframe_right(const avalue: integer); +begin + if finnerframe.right <> avalue then begin + finnerframe.right:= avalue; + fgrid.layoutchanged; + end; +end; + +procedure tgridarrayprop.setinnerframe_bottom(const avalue: integer); +begin + if finnerframe.bottom <> avalue then begin + finnerframe.bottom:= avalue; + fgrid.layoutchanged; + end; +end; + +{ tdatacol } + +constructor tdatacol.create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); +begin + fwidthmin:= 1; + fselectedrow:= -1; + inherited; + fdata:= createdatalist; + if fdata <> nil then begin + fdata.count:= fcellinfo.grid.rowcount; + fdata.maxcount:= fcellinfo.grid.frowcountmax; + fdata.onitemchange:= {$ifdef FPC}@{$endif}itemchanged; + end; +end; + +destructor tdatacol.destroy; +begin + if (fdata <> nil) and not (dls_remote in fdata.state) then begin + fdata.destroy; + end; + inherited; +end; + +function tdatacol.getcellorigin: pointty; +begin + fcellinfo.grid.internalupdatelayout; + result.x:= fstart + flinewidth + fcellrect.x; + if not (co_nohscroll in foptions) then begin + result.x:= result.x + fcellinfo.grid.fdatarect.x + + fcellinfo.grid.fscrollrect.x; + end; + result.y:= fcellrect.y + fcellinfo.grid.fdatarect.y + + fcellinfo.grid.fscrollrect.y; +end; + +function tdatacol.createdatalist: tdatalist; +begin + result:= nil; //dummy +end; + +procedure tdatacol.rowcountchanged(const newcount: integer); +var + int1: integer; +begin + if fdata <> nil then begin + with tdatalist1(fdata) do begin + int1:= newcount - fscrolled; + if int1 < fcellinfo.grid.frowcount then begin + int1:= fcellinfo.grid.frowcount; + end; + count:= int1; + fscrolled:= 0; + end; + end; + inherited; + invalidatemaxsize(-1); +end; + +procedure tdatacol.docellfocuschanged(enter: boolean; + const cellbefore: gridcoordty; var newcell: gridcoordty; + const selectaction: focuscellactionty); +var + info: celleventinfoty; + bo1: boolean; +begin +{ + if fgrid.updating then begin + fgrid.factiverow:= newcell.row; + exit; + end; +} + bo1:= (gs_hasactiverowcolor in fcellinfo.grid.fstate) and + (newcell.row <> cellbefore.row); + if enter then begin + fcellinfo.grid.factiverow:= newcell.row; + if bo1 then begin + fcellinfo.grid.invalidaterow(newcell.row); + end + else begin + if (co_drawfocus in foptions) or (fcoloractive <> cl_none) or + (fcolorfocused <> cl_none) then begin + invalidatecell(newcell.row); + end; + end; + fcellinfo.grid.initeventinfo(newcell,cek_enter,info); + end + else begin + if selectaction <> fca_exitgrid then begin + fcellinfo.grid.factiverow:= newcell.row; + end; + if bo1 then begin + fcellinfo.grid.invalidaterow(cellbefore.row); + end + else begin + if (co_drawfocus in foptions) or (fcoloractive <> cl_none) or + (fcolorfocused <> cl_none) then begin + invalidatecell(cellbefore.row); + end; + end; + fcellinfo.grid.initeventinfo(cellbefore{newcell},cek_exit,info); + end; + info.selectaction:= selectaction; + info.cellbefore:= cellbefore; + info.newcell:= newcell; + fcellinfo.grid.docellevent(info); + newcell:= info.newcell; +end; + +procedure tdatacol.dokeyevent(var info: keyeventinfoty; up: boolean); +var + event: celleventkindty; + cellinfo: celleventinfoty; +begin + with cellinfo do begin + if up then begin + event:= cek_keyup; + end + else begin + event:= cek_keydown; + end; + if event <> cek_none then begin + fcellinfo.grid.initeventinfo(fcellinfo.grid.ffocusedcell,event,cellinfo); + keyeventinfopo:= @info; + fcellinfo.grid.docellevent(cellinfo); + end; + end; +end; + +procedure tdatacol.updatecellzone(const row: integer; const pos: pointty; + var result: cellzonety); +begin + fcellinfo.grid.internalupdatelayout; + if pointinrect(pos,fcellinfo.rect) then begin + result:= cz_default; + end + else begin + result:= cz_none; + end; +end; + +procedure tdatacol.clientmouseevent(const acell: gridcoordty; + var info: mouseeventinfoty); +var + cellinfo: celleventinfoty; + po1: pointty; +begin + if info.eventkind = ek_clientmouseleave then begin + fcellinfo.grid.cellmouseevent(acell,info,nil); + end + else begin + fcellinfo.grid.cellmouseevent(acell,info,@cellinfo); + if cellinfo.eventkind <> cek_none then begin + po1:= fcellinfo.grid.cellrect(cellinfo.cell).pos; + try + subpoint1(info.pos,po1); + updatecellzone(acell.row,info.pos,cellinfo.zone); + fcellinfo.grid.flastcellzone:= cellinfo.zone; + fcellinfo.grid.docellevent(cellinfo); + finally + addpoint1(info.pos,po1); + end; + end; + end; +end; + +function tdatacol.getselected(const row: integer): boolean; +begin + if ident <= selectedcolmax then begin + if row >= 0 then begin + result:= (gps_selected in fstate) or + (fcellinfo.grid.fdatacols.frowstate.getitempo(row)^.selected and + (bits[ident] or wholerowselectedmask) <> 0); + end + else begin + result:= gps_selected in fstate; + end; + end + else begin + result:= inherited getselected(row); + end; +end; + +procedure tdatacol.setselected(const row: integer; value: boolean); +var + po1,po2,pe: prowstatety; + ca1: longword; + int1,int2: integer; +begin + if ident <= selectedcolmax then begin + if row >= 0 then begin + with fcellinfo.grid.fdatacols.frowstate.getitempo(row)^ do begin + if fdata <> nil then begin + tdatalist1(fdata).setitemselected(row,value); + end; + ca1:= selected; + if value then begin + selected:= selected or bits[ident]; + end + else begin + if gps_selected in fstate then begin + ca1:= bits[ident]; + with fcellinfo.grid.fdatacols.frowstate do begin + int1:= fsize; + po2:= datapo; + pe:= pointer(po2) + count * int1; + while po2 < pe do begin + po2^.selected:= po2^.selected or ca1; + inc(pointer(po2),int1); + end; + end; + fselectedrowcount:= fcellinfo.grid.rowcount-1; + case fselectedrowcount of + 0: begin + fselectedrow:= -1; + end; + 1: begin + fselectedrow:= 0; + end; + else begin + fselectedrow:= -2; + end; + end; + selected:= selected and not (ca1 or wholerowselectedmask); + exclude(fstate,gps_selected); + invalidatecell(invalidaxis); + doselectionchanged(); + exit; + end + else begin + selected:= selected and not (bits[ident] or wholerowselectedmask); + end; + end; + if ca1 <> selected then begin + if value then begin + inc(fselectedrowcount); + if fselectedrow = -1 then begin + fselectedrow:= row; + end + else begin + fselectedrow:= -2; + end; + end + else begin + dec(fselectedrowcount); + if (fselectedrow = row) or (fselectedrowcount = 0) then begin + fselectedrow:= -1; + end; + end; + invalidatecell(row); + doselectionchanged; + end; + end; + end + else begin //row < 0 + if fdata <> nil then begin + tdatalist1(fdata).setitemselected(row,value); + end; + if value then begin + if not (gps_selected in fstate) then begin + include(fstate,gps_selected); + fselectedrowcount:= fcellinfo.grid.rowcount; + fselectedrow:= -2; + changed; + doselectionchanged; + end; + end + else begin + exclude(fstate,gps_selected); + if fselectedrow <> -1 then begin + po1:= fcellinfo.grid.fdatacols.frowstate.datapo; + ca1:= not (bits[ident] {or wholerowselectedmask}); + int2:= fcellinfo.grid.fdatacols.frowstate.fsize; + if fselectedrow >= 0 then begin + with prowstatety(pchar(po1)+fselectedrow*int2)^ do begin + selected:= selected and ca1; + end; + invalidatecell(fselectedrow); + end + else begin + for int1:= 0 to fcellinfo.grid.frowcount - 1 do begin + po1^.selected:= po1^.selected and ca1; + inc(pchar(po1),int2); + end; + changed; + end; + fselectedrowcount:= 0; + fselectedrow:= -1; + doselectionchanged; + end; + end; + end; + end; +end; + +function tdatacol.getmerged(const row: integer): boolean; +begin + if index = 0 then begin + result:= false; + end + else begin + if index > mergedcolmax then begin + result:= fcellinfo.grid.fdatacols.frowstate.getitempocolmerge(row)^. + colmerge.merged = mergedcolall; + end + else begin + result:= fcellinfo.grid.fdatacols.frowstate.getitempocolmerge(row)^. + colmerge.merged and bits[index-1] <> 0; + end; + end; +end; + +procedure tdatacol.setmerged(const row: integer; const avalue: boolean); +begin + if (index > 0) and (index <= mergedcolmax) then begin + if updatebit(fcellinfo.grid.fdatacols.frowstate.getitempocolmerge(row)^. + colmerge.merged,index-1,avalue) then begin + fcellinfo.grid.fdatacols.mergechanged(row); + end; + end; +end; + +function tdatacol.getselectedcells: integerarty; +const + capacitystep = 64; +var + int1,int3: integer; +begin + result:= nil; + with tdatacols(prop) do begin + if hasselection then begin //todo: optimize + int3:= 0; + for int1:= 0 to frowstate.count - 1 do begin + if frowstate.getitempo(int1)^.selected <> 0 then begin + if self.selected[int1] then begin + if int3 >= length(result) then begin + setlength(result,length(result)*2 + capacitystep); + end; + result[int3]:= int1; + inc(int3); + end; + end; + end; + setlength(result,int3); + end; + end; +end; + +procedure tdatacol.setselectedcells(const avalue: integerarty); + //todo: optimize +var + int1: integer; +begin + grid.beginupdate; + try + beginselect; + clearselection; + for int1:= 0 to high(avalue) do begin + setselected(avalue[int1],true); + end; + endselect; + finally + grid.endupdate; + end; +end; + +procedure tdatacol.doselectionchanged; +begin + if (fselectlock = 0) then begin + if assigned(fonselectionchanged) then begin + inc(fselectlock); //avoid recursion + try + fonselectionchanged(self); + finally + dec(fselectlock); + end; + end; + end + else begin + include(fstate,gps_selectionchanged); + end; + fcellinfo.grid.internalselectionchanged; +end; + +procedure tdatacol.beginselect; +begin + inc(fselectlock); +end; + +procedure tdatacol.endselect; +begin + dec(fselectlock); + if fselectlock = 0 then begin + if gps_selectionchanged in fstate then begin + exclude(fstate,gps_selectionchanged); + doselectionchanged; + end; + end; +end; +(* +function tdatacol.selectedcellcount: integer; +var + int1{,int2}: integer; +begin + result:= 0; + if fselectedrow <> -1 then begin + for int1:= 0 to fcellinfo.grid.rowhigh do begin + if selected[int1] then begin + inc(result); + end; + end; + end; +end; +*) +procedure tdatacol.clearselection; +begin + setselected(-1,false); +end; + +function tdatacol.defaultcaption(): msestring; +begin + result:= ''; + if fcellinfo.grid.ffixrows.count > 0 then begin + with tfixrow(fcellinfo.grid.fixrows.fitems[0]) do begin + if fcaptions.count > self.findex then begin + result:= tcolheader(fcaptions.fitems[self.findex]).caption; + end; + end; + end; +end; + +procedure tdatacol.internaldoentercell(const cellbefore: gridcoordty; + var newcell: gridcoordty; const action: focuscellactionty); +begin + if not (gs_cellentered in fcellinfo.grid.fstate) or + (action = fca_entergrid) then begin + include(fcellinfo.grid.fstate,gs_cellentered); +// include(fgrid.fstate1,gs1_focusedcellchanged); + docellfocuschanged(true,cellbefore,newcell,action); + end; +end; + +procedure tdatacol.internaldoexitcell(const cellbefore: gridcoordty; + var newcell: gridcoordty; const selectaction: focuscellactionty); +begin + if gs_cellentered in fcellinfo.grid.fstate then begin + exclude(fcellinfo.grid.fstate,gs_cellentered); +// include(fgrid.fstate1,gs1_focusedcellchanged); + docellfocuschanged(false,cellbefore,newcell,selectaction); + end + else begin + if ((co1_rowcoloractive in foptions1) or (co1_rowcolorfocused in foptions1) or + (ffontactivenum >= 0) or (ffontfocusednum >= 0)) and + (cellbefore.row >= 0) then begin + invalidatecell(cellbefore.row); + end; + end; +end; + +procedure tdatacol.checkdirtyautorowheight(aindex: integer); +begin + if gps_needsrowheight in fstate then begin + tdatacols(prop).rowstate.checkdirtyautorowheight(aindex); + end; +end; + +procedure tdatacol.afterrowcountupdate; +begin + //dummy +end; + +procedure tdatacol.datachange(const arow: integer); +begin + if (datalist = nil) and not (gps_noinvalidate in fstate) and + not (csloading in fcellinfo.grid.componentstate) then begin + checkdirtyautorowheight(arow); + end; +end; + +procedure tdatacol.itemchanged(const sender: tdatalist; const aindex: integer); +var + coord1: gridcoordty; + int1: integer; +begin + if (aindex < 0) then begin + with tdatalist1(sender) do begin + int1:= count + fscrolled; + if int1 <> fcellinfo.grid.frowcount then begin + if fcellinfo.grid.fupdating = 0 then begin + fcellinfo.grid.rowcount:= int1; + afterrowcountupdate; + end + else begin + include(fcellinfo.grid.fstate,gs_rowcountinvalid) + end; + end; + end; + end; + if not (gps_noinvalidate in fstate) and + not (csloading in fcellinfo.grid.componentstate) then begin + checkdirtyautorowheight(aindex); + if aindex < 0 then begin + cellchanged(invalidaxis); + end + else begin + cellchanged(aindex); + end; + if (co_rowdatachange in foptions) and + (fcellinfo.grid.frowdatachanging = 0) then begin + //no recursion + coord1.col:= index; + if aindex < 0 then begin + coord1.row:= 0; + fcellinfo.grid.rowdatachanged(coord1,fcellinfo.grid.frowcount); + end + else begin + coord1.row:= aindex; + fcellinfo.grid.rowdatachanged(coord1); + end; + end; + end; + if not (co_nosort in foptions) then begin + fcellinfo.grid.sortinvalid(index,aindex); + end; + invalidatemaxsize(aindex); + if not (gps_changelock in fstate) and + fcellinfo.grid.canevent(tmethod(fonchange)) then begin + fonchange(self,aindex); + end; +end; + +procedure tdatacol.doactivate; +begin + if (co_drawfocus in foptions) and (fcellinfo.grid.row >= 0) then begin + invalidatecell(fcellinfo.grid.row); + end; +end; + +procedure tdatacol.dodeactivate; +begin + if (co_drawfocus in foptions) and (fcellinfo.grid.row >= 0) then begin + invalidatecell(fcellinfo.grid.row); + end; +end; + +procedure tdatacol.setwidthmax(const Value: integer); +begin + if fwidthmax <> value then begin + if value < 0 then begin + fwidthmax:= 0; + end + else begin + fwidthmax:= Value; + end; + fcellinfo.grid.layoutchanged; + end; +end; + +procedure tdatacol.setwidthmin(const Value: integer); +begin + if fwidthmin <> value then begin + if value < 0 then begin + fwidthmin:= 0; + end + else begin + fwidthmin:= Value; + end; + fcellinfo.grid.layoutchanged; + end; +end; + +procedure tdatacol.updatewidth(var avalue: integer); +begin + if (fwidthmax <> 0) and (avalue > fwidthmax) then begin + avalue:= fwidthmax; + end; + if (fwidthmin <> 0) and (avalue < fwidthmin) then begin + avalue:= fwidthmin; + end; +end; + +procedure tdatacol.updatelayout; +begin + if fpropwidth = 0 then begin + updatepropwidth; + end; + if (co_proportional in foptions) and (fpropwidth <> 0) then begin + fwidth:= round(fcellinfo.grid.fpropcolwidthref * fpropwidth); +// fwidth:= round(tgridframe(fgrid.fframe).fpaintrect.cx * fpropwidth); + end; + updatewidth(fwidth); + inherited; +end; + +procedure tdatacol.moverow(const fromindex, toindex: integer; + const count: integer); +begin + if (fdata <> nil) and not (co_norearange in foptions) then begin + fdata.blockmovedata(fromindex,toindex,count); + end; +end; + +procedure tdatacol.insertrow(const aindex: integer; const count: integer); +begin + if fdata <> nil then begin + fdata.insertitems(aindex,count); + end; +end; + +procedure tdatacol.deleterow(const aindex: integer; const count: integer); +begin + if fdata <> nil then begin + fdata.deleteitems(aindex,count); + end; +end; + +procedure tdatacol.setoptions(const Value: coloptionsty); +const + mask: coloptionsty = [co_fill,co_proportional]; +var + optionsbefore: coloptionsty; + optionsplusdelta: coloptionsty; +begin + optionsbefore:= foptions; + inherited setoptions(coloptionsty(setsinglebit( + {$ifdef FPC}longword{$else}longword{$endif}(value), + {$ifdef FPC}longword{$else}longword{$endif}(foptions), + {$ifdef FPC}longword{$else}longword{$endif}(mask)))); + if coloptionsty(longword(optionsbefore) xor longword(foptions)) * + [co_nosort,co_sortdescend,co_sortcaseinsensitive] <> [] then begin + fcellinfo.grid.sortinvalid(index,-1); + fcellinfo.grid.checksort; + end; + optionsplusdelta:= coloptionsty((longword(optionsbefore) xor longword(foptions)) and + longword(value)); + if (co_focusselect in optionsplusdelta) and + (fcellinfo.grid.ffocusedcell.col = findex) and + (fcellinfo.grid.ffocusedcell.row >= 0) then begin + fcellinfo.grid.selectcell( + makegridcoord(findex,fcellinfo.grid.ffocusedcell.row),csm_select); + end; + if (co_disabled in optionsplusdelta) and + (fcellinfo.grid.ffocusedcell.col = colindex) then begin + fcellinfo.grid.colstep(fca_focusin,1,false,false,false); + end; +end; + +function tdatacol.canfocus(const abutton: mousebuttonty; + const ashiftstate: shiftstatesty; + const noreadonly: boolean; + out canrowfocus: boolean): boolean; +begin + canrowfocus:= ((abutton = mb_left) or (abutton = mb_none) or + not (co_leftbuttonfocusonly in foptions) or + (abutton = mb_middle) and (co_middlebuttonfocus in foptions)) and + ((ashiftstate*[ss_ctrl] = []) or + not (co_noctrlmousefocus in foptions)); + result:= (foptions * [co_invisible,co_disabled,co_nofocus] = []) and + canrowfocus and (not noreadonly or not(co_readonly in options)); +end; + +procedure tdatacol.rearange(const list: integerarty); +begin + if not (co_norearange in foptions) and (fdata <> nil) then begin + fdata.rearange(list); + fdata.change(-1); + end; +end; + +function tdatacol.sortcompare(const index1,index2: integer): integer; +begin + result:= 0; + if fdata <> nil then begin + with tdatalist1(fdata) do begin + result:= tdatalist1(fdata).compare((fdatapo+index1*fsize)^, + (fdatapo+index2*fsize)^); + end; + end; +end; + +function tdatacol.sortcomparecaseinsensitive( + const index1,index2: integer): integer; +begin + result:= 0; + if fdata <> nil then begin + with tdatalist1(fdata) do begin + result:= tdatalist1(fdata).comparecaseinsensitive((fdatapo+index1*fsize)^, + (fdatapo+index2*fsize)^); + end; + end; +end; + +function tdatacol.isempty(const aindex: integer): boolean; +begin + if fdata <> nil then begin + result:= (aindex >= fdata.count) or fdata.empty(aindex); + end + else begin + result:= true; + end; +end; + +procedure tdatacol.docellevent(var info: celleventinfoty); +var + hintinfo: hintinfoty; +begin + if fcellinfo.grid.canevent(tmethod(foncellevent)) then begin + foncellevent(self,info); + end; + if (info.eventkind = cek_firstmousepark) and + fcellinfo.grid.canevent(tmethod(fonshowhint)) and + application.active then begin + application.inithintinfo(hintinfo,fcellinfo.grid); + fonshowhint(self,info.cell.row,hintinfo); + application.showhint(fcellinfo.grid,hintinfo); + end; +end; + +function tdatacol.getcursor(const arow: integer; const actcellzone: cellzonety; + const amousepos: pointty): cursorshapety; +begin + result:= cursor; +// result:= cr_arrow; +end; + +function tdatacol.getdatastatname: msestring; +begin + if fname <> '' then begin + result:= msestring(fname); + end + else begin + result:= gridvaluevarname + inttostrmse(ident); + end; +end; + +function tdatacol.getstatsuffix(): msestring; +begin + if fname <> '' then begin + result:= '_'+msestring(fname); + end + else begin + result:= inttostrmse(ident); + end; +end; + + +procedure tdatacol.coloptionstoeditoptions(var dest: optionseditty; + var dest1: optionsedit1ty); +begin + updatebit(longword(dest),ord(oe_readonly),isreadonly); + updatebit(longword(dest1),ord(oe1_savevalue),co_savevalue in foptions); +end; + +procedure tdatacol.dostatread(const reader: tstatreader); +var + bo1: boolean; + mstr1: msestring; +begin + if (fdata <> nil) and not (dls_remote in fdata.state) and + (co_savevalue in foptions) and + not (gs_isdb in fcellinfo.grid.fstate) and reader.candata then begin + reader.readdatalist(getdatastatname,fdata); + end; + if (co_savestate in foptions) and reader.canstate then begin + mstr1:= getstatsuffix(); + if not (co_fixwidth in foptions) and + (og_colsizing in fcellinfo.grid.optionsgrid) then begin + width:= reader.readinteger('width'+mstr1,fwidth,0); + end; + bo1:= reader.readboolean('sortdescend'+mstr1,co_sortdescend in foptions); + if bo1 then begin + options:= options + [co_sortdescend]; + end + else begin + options:= options - [co_sortdescend]; + end; + end; +end; + +procedure tdatacol.dostatwrite(const writer: tstatwriter); +var + mstr1: msestring; +begin + inherited; + if (fdata <> nil) and not (dls_remote in fdata.state) and + (co_savevalue in foptions) and + not (gs_isdb in fcellinfo.grid.fstate) and + writer.candata then begin + writer.writedatalist(getdatastatname,fdata); + end; + if (co_savestate in foptions) and writer.canstate then begin + mstr1:= getstatsuffix(); + if not (co_fixwidth in foptions) and + (og_colsizing in fcellinfo.grid.optionsgrid) then begin + writer.writeinteger('width'+mstr1,fwidth); + end; + writer.writeboolean('sortdescend'+mstr1,co_sortdescend in foptions); + end; +end; +{ +procedure tdatacol.cellchanged(const row: integer); +var + coord1: gridcoordty; +begin + inherited; + if (co_rowdatachange in foptions) and (fgrid.frowdatachanging = 0) then begin + //no recursion + coord1.col:= index; + if row < 0 then begin + coord1.row:= 0; + fgrid.rowdatachanged(coord1,fgrid.frowcount); + end + else begin + coord1.row:= row; + fgrid.rowdatachanged(coord1); + end; + end; +end; +} +function tdatacol.getvisible: boolean; +begin + result:= not (co_invisible in foptions); +end; + +procedure tdatacol.setvisible(const avalue: boolean); +begin + if avalue then begin + options:= options - [co_invisible]; + end + else begin + options:= options + [co_invisible]; + end; +end; + +function tdatacol.getenabled: boolean; +begin + result:= not (co_disabled in foptions); +end; + +procedure tdatacol.setenabled(const avalue: boolean); +begin + if avalue then begin + options:= options - [co_disabled]; + end + else begin + options:= options + [co_disabled]; + end; +end; + +function tdatacol.getreadonly: boolean; +begin + result:= co_readonly in foptions; +end; + +procedure tdatacol.setreadonly(const avalue: boolean); +begin + if avalue then begin + options:= options + [co_readonly]; + end + else begin + options:= options - [co_readonly]; + end; +end; + +function tdatacol.getsortdescend: boolean; +begin + result:= co_sortdescend in foptions; +end; + +procedure tdatacol.setsortdescend(const avalue: boolean); +begin + if avalue then begin + options:= options + [co_sortdescend]; + end + else begin + options:= options - [co_sortdescend]; + end; +end; + + +function tdatacol.getdatapo(const arow: integer): pointer; +begin + if (fdata <> nil) and (arow < fdata.count) then begin + result:= fdata.getitempo(arow); + end + else begin + result:= nil; + end; +end; + +function tdatacol.getrowdatapo: pointer; +begin + result:= nil; + if fcellinfo.grid.row >= 0 then begin + result:= getdatapo(fcellinfo.grid.row); + end; +end; + +{ +function tdatacol.ismerged: boolean; +begin + with fcellinfo.rowstate^ do begin + result:= merged <> 0; + if result then begin + result:= (index <> 0) and + ((merged = mergedcolall) or (index < mergedcolmax) and + (merged and bits[index] <> 0)); + end; + end; +end; +} +procedure tdatacol.beforedragevent(var ainfo: draginfoty; const arow: integer; + var processed: boolean); +begin + //dummy +end; + +procedure tdatacol.afterdragevent(var ainfo: draginfoty; const arow: integer; + var processed: boolean); +begin + //dummy +end; + +function tdatacol.isreadonly: boolean; +begin + result:= (co1_rowreadonly in foptions1) and + (gs_rowreadonly in fcellinfo.grid.fstate) or + (co_readonly in foptions); +end; + +procedure tdatacol.clean(const start,stop: integer); +begin + if fdata <> nil then begin + fdata.clean(start,stop); + end; +end; + +procedure tdatacol.setdata(const avalue: tdatalist); +begin + fdata.assign(avalue); +end; + +procedure tdatacol.autocellheightchanged(const aindex: integer); +begin + checkdirtyautorowheight(aindex); +end; + +procedure tdatacol.autocellwidthchanged(const aindex: integer); +begin + //dummy +end; + +function tdatacol.defaultrowheight: integer; +begin + result:= tcustomgrid(fowner).datarowheight; +end; + +{ tdrawcol } + +procedure tdrawcol.drawcell(const canvas: tcanvas); +begin + inherited; + if assigned(fondrawcell) then begin + fondrawcell(self,canvas,cellinfoty(canvas.drawinfopo^)); + end; +end; + +procedure tdrawcol.beforedragevent(var ainfo: draginfoty; const arow: integer; + var processed: boolean); +begin + if not processed and assigned(fonbeforedragevent) then begin + fcellinfo.cell.row:= arow; + fonbeforedragevent(fcellinfo,ainfo,tcelldragobject(ainfo.dragobjectpo^), + ainfo.accept,processed); + end; + if not processed then begin + inherited; + end; +end; + +procedure tdrawcol.afterdragevent(var ainfo: draginfoty; const arow: integer; + var processed: boolean); +begin + if not processed and assigned(fonafterdragevent) then begin + fcellinfo.cell.row:= arow; + fonafterdragevent(fcellinfo,ainfo,tcelldragobject(ainfo.dragobjectpo^), + ainfo.accept,processed); + end; + if not processed then begin + inherited; + end; +end; + +{ tstringcoldatalist } + +constructor tstringcoldatalist.create(const agrid: tcustomgrid); +begin + fgrid:= agrid; + inherited create; +end; + +function tstringcoldatalist.add(const avalue: msestring; + const anoparagraph: boolean): integer; +begin + result:= inherited add(avalue,anoparagraph); + if anoparagraph then begin + if (nochange = 0) and (fgrid.fupdating = 0) then begin + fgrid.fdatacols.frowstate.flag1[result]:= true; + end + else begin + additem(fnoparagraph,result); + end; + end; +end; + +procedure tstringcoldatalist.afterrowcountupdate; +var + int1: integer; +begin + with fgrid.fdatacols.frowstate do begin + for int1:= 0 to high(fnoparagraph) do begin + if fnoparagraph[int1] < count then begin + flag1[fnoparagraph[int1]]:= true; + end; + end; + end; + fnoparagraph:= nil; +end; + +function tstringcoldatalist.getparagraph(const index: integer; + const aseparator: msestring = ''): msestring; +var + int1: integer; + start{,stop}: integer; +begin + start:= index; + with fgrid.fdatacols.frowstate do begin + while start >= 0 do begin + if not flag1[start] then begin + break; + end; + dec(start); + end; + result:= self.items[start]; + for int1:= start+1 to count-1 do begin + if not flag1[int1] then begin + break; + end; + result:= result + aseparator + self.items[int1]; + end; + end; +end; + +function tstringcoldatalist.getnoparagraphs(index: integer): boolean; +begin + result:= fgrid.fdatacols.frowstate.flag1[index]; +end; + +function tstringcoldatalist.getdefault: pointer; +begin + if fvaluedefault = '' then begin + result:= nil; //use block fillchar() + end + else begin + result:= @fvaluedefault; + end; +end; + +function tstringcoldatalist.empty(const index: integer): boolean; +begin + result:= pmsestring(getitempo(index))^ = fvaluedefault; +end; + +{ tcustomstringcol } + +constructor tcustomstringcol.create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); +begin + fvaluetrue:= '1'; + fvaluefalse:= '0'; + fcolorglyph:= cl_glyph; + foptionsedit:= tstringcols(aowner).foptionsedit; + foptionsedit1:= tstringcols(aowner).foptionsedit1; + ftextinfo.flags:= tstringcols(aowner).ftextflags; + ftextflagsactive:= tstringcols(aowner).ftextflagsactive; + inherited; +end; + +destructor tcustomstringcol.destroy; +begin + inherited; +end; + +procedure tcustomstringcol.settextflags(const avalue: textflagsty); +begin + if ftextinfo.flags <> avalue then begin + ftextinfo.flags:= checktextflags(ftextinfo.flags,avalue); + changed; + end; +end; + +procedure tcustomstringcol.settextflagsactive(const avalue: textflagsty); +begin + if ftextflagsactive <> avalue then begin + ftextflagsactive:= checktextflags(ftextflagsactive,avalue); + end; + changed; +end; + +function tcustomstringcol.createdatalist: tdatalist; +begin + result:= tstringcoldatalist.create(fcellinfo.grid); +end; + +function tcustomstringcol.getinnerframe: framety; +begin + result:= inherited getinnerframe; +end; + +function tcustomstringcol.getcursor(const arow: integer; + const actcellzone: cellzonety; + const amousepos: pointty): cursorshapety; +begin + result:= inherited getcursor(arow,actcellzone,amousepos); + if result = cr_default then begin + if not isreadonly and not (scoe_checkbox in foptionsedit) then begin + result:= cr_ibeam; + end; + end; +end; + +procedure tcustomstringcol.modified; +begin + include(fstate,gps_edited); + //dummy +end; + +procedure tcustomstringcol.checkcellvalue(var avalue: msestring; + var accept: boolean); +begin + updatedisptext(avalue); + if fcellinfo.grid.canevent(tmethod(fonsetvalue)) then begin + fonsetvalue(self,avalue,accept); + end; + if accept then begin + items[fcellinfo.grid.ffocusedcell.row]:= avalue; + if fcellinfo.grid.canevent(tmethod(fondataentered)) then begin + fondataentered(self); + end; + end; + exclude(fstate,gps_edited); +end; + +function tcustomstringcol.geteditpos: gridcoordty; +begin + result.row:= invalidaxis; + result.col:= invalidaxis; + if (fcellinfo.grid.row >= 0) and (fcellinfo.grid.col >= index) then begin + result.row:= fcellinfo.grid.row; + result.col:= tcustomstringgrid(fcellinfo.grid).feditor.curindex; + end; +end; + +procedure tcustomstringcol.seteditpos(const avalue: gridcoordty); +begin + if (fcellinfo.grid.row >= 0) and (fcellinfo.grid.col >= index) then begin + fcellinfo.grid.focuscell(makegridcoord(index,avalue.row)); + if (fcellinfo.grid.row >= 0) and (fcellinfo.grid.col >= index) then begin + tcustomstringgrid(fcellinfo.grid).feditor.curindex:= avalue.col; + end; + end; +end; + +procedure tcustomstringcol.updatelayout; +begin + inherited; + ftextinfo.clip.pos:= nullpoint; + ftextinfo.clip.size:= fcellinfo.rect.size; + ftextinfo.dest:= fcellinfo.innerrect; +end; + +function tcustomstringcol.getrowtext(const arow: integer): msestring; +begin + result:= items[arow]; +end; + +procedure tcustomstringcol.updatedisptext(var avalue: msestring); +begin + if scoe_trimleft in foptionsedit then begin + avalue:= trimleft(avalue); + end; + if scoe_trimright in foptionsedit then begin + avalue:= trimright(avalue); + end; + if scoe_uppercase in foptionsedit then begin + avalue:= mseuppercase(avalue); + end + else begin + if scoe_lowercase in foptionsedit then begin + avalue:= mselowercase(avalue); + end; + end; +end; + +procedure tcustomstringcol.setpasswordchar(const avalue: widechar); +begin + if fpasswordchar <> avalue then begin + fpasswordchar:= avalue; + changed; + end; +end; + +procedure tcustomstringcol.drawcell(const canvas: tcanvas); +var + int1: integer; +begin + inherited; + ftextinfo.font:= canvas.font; + ftextinfo.text.format:= nil; + with cellinfoty(canvas.drawinfopo^) do begin + if cell.row < fcellinfo.grid.rowcount then begin + if scoe_checkbox in foptionsedit then begin + if calcautocellsize then begin + textrect(canvas,ftextinfo); + int1:= rect.cx - innerrect.cx + ftextinfo.res.cx; + if defaultboxsize > autocellsize.cx then begin + autocellsize.cx:= defaultboxsize; + end; + if defaultboxsize > autocellsize.cy then begin + autocellsize.cy:= defaultboxsize; + end; + end + else begin + if checked[cell.row] then begin + stockobjects.paintglyph(canvas,stg_checked,innerrect, + co_disabled in foptions,fcolorglyph); + end; + end; + end + else begin + ftextinfo.dest.cx:= innerrect.cx; + ftextinfo.dest.cy:= innerrect.cy; + ftextinfo.clip.cx:= rect.cx; + ftextinfo.clip.cy:= rect.cy; + ftextinfo.text.text:= getrowtext(cell.row); + updatedisptext(ftextinfo.text.text); + if passwordchar <> #0 then begin + ftextinfo.text.text:= charstring(passwordchar,length(ftextinfo.text.text)); + end; + if calcautocellsize then begin + textrect(canvas,ftextinfo); + int1:= rect.cx - innerrect.cx + ftextinfo.res.cx; + if int1 > autocellsize.cx then begin + autocellsize.cx:= int1; + end; + int1:= rect.cy - innerrect.cy + ftextinfo.res.cy; + if int1 > autocellsize.cy then begin + autocellsize.cy:= int1; + end; + end + else begin + drawtext(canvas,ftextinfo); + end; + end; + end; + end; + if assigned(fondrawcell) then begin + fondrawcell(self,canvas,cellinfoty(canvas.drawinfopo^)); + end; +end; + +function tcustomstringcol.defaultrowheight(): integer; +var + int1: integer; + fra1: framety; +begin + result:= actualfont.lineheight; + if ffontselect <> nil then begin + int1:= ffontselect.height; + if int1 > result then begin + result:= int1; + end; + end; + if (scoe_checkbox in foptionsedit) and (result < defaultboxsize) then begin + result:= defaultboxsize; + end; + fra1:= getinnerframe; + result:= result + fra1.top + fra1.bottom + framedim.cy; +end; + +function tcustomstringcol.getitems(aindex: integer): msestring; +begin + if aindex = -1 then begin + aindex:= fcellinfo.grid.row; + end; + if aindex >= 0 then begin + result:= tmsestringdatalist(fdata)[aindex]; + end + else begin + tdatalist1(fdata).getgriddefaultdata(result); + end; +end; + +procedure tcustomstringcol.setitems(aindex: integer; const Value: msestring); +begin + if aindex = -1 then begin + aindex:= fcellinfo.grid.row; + end; + if aindex >= 0 then begin + tmsestringdatalist(fdata)[aindex]:= value; + end; +// cellchanged(aindex); //??? already called? +end; + +function tcustomstringcol.getchecked(aindex: integer): boolean; +begin + result:= getitems(aindex) = fvaluetrue;; +end; + +procedure tcustomstringcol.setchecked(aindex: integer; const avalue: boolean); +begin + if avalue then begin + setitems(aindex,fvaluetrue); + end + else begin + setitems(aindex,fvaluefalse); + end; +end; + +function tcustomstringcol.getvaluedefault: msestring; +begin + result:= tstringcoldatalist(fdata).fvaluedefault; +end; + +procedure tcustomstringcol.setvaluedefault(const avalue: msestring); +begin + tstringcoldatalist(fdata).fvaluedefault:= avalue; +end; + + +function tcustomstringcol.getdatalist: tstringcoldatalist; +begin + result:= tstringcoldatalist(fdata); +end; + +procedure tcustomstringcol.setdatalist(const value: tstringcoldatalist); +begin + fdata.Assign(value); +end; + +function tcustomstringcol.readpipe(const text: string; +// const processeditchars: boolean = false; + const aoptions: addcharoptionsty = [aco_processeditchars]; + const maxchars: integer = 0): integer; +var + mstr1: msestring; +begin + mstr1:= msestring(text); + result:= datalist.addchars(mstr1,aoptions,maxchars); +end; + +function tcustomstringcol.readpipe(const pipe: tpipereader; + const aoptions: addcharoptionsty = [aco_processeditchars]; +// const processeditchars: boolean = false; + const maxchars: integer = 0): integer; +var + str1: string; +begin + try + str1:= pipe.readdatastring; + except + end; + result:= readpipe(str1,aoptions,maxchars); +end; + +function tcustomstringcol.geteditstate: dataeditstatesty; +begin + result:= feditstate; +end; + +procedure tcustomstringcol.seteditstate(const avalue: dataeditstatesty); +begin + feditstate:= avalue; +end; +{ +procedure tcustomstringcol.setisdb; +begin + //dummy +end; +} +function tcustomstringcol.getoptionsedit: optionseditty; +begin + result:= []; + stringcoltooptionsedit(foptionsedit,result); +end; + +function tcustomstringcol.needsfocusrect: boolean; +begin + result:= inherited needsfocusrect or + (scoe_focusrectonreadonly in foptionsedit) and + ((co_readonly in foptions) or (oe_readonly in getoptionsedit)); +end; + +procedure tcustomstringcol.docellevent(var info: celleventinfoty); +var + hintinfo: hintinfoty; + mstr1: msestring; + bo1: boolean; +begin + if scoe_checkbox in foptionsedit then begin + if not isreadonly and (info.cell.row >= 0) then begin + if iscellclick(info) or (info.eventkind = cek_keyup) and + (info.keyeventinfopo^.key = key_space) and + (info.keyeventinfopo^.shiftstate = []) then begin + if checked[info.cell.row] then begin + mstr1:= fvaluefalse; + end + else begin + mstr1:= fvaluetrue; + end; + bo1:= true; + checkcellvalue(mstr1,bo1); + end; + end; + end + else begin + if (scoe_hintclippedtext in foptionsedit) and + (info.eventkind = cek_firstmousepark) and application.active and + fcellinfo.grid.getshowhint and + tcustomstringgrid(fcellinfo.grid).textclipped(info.cell) then begin + application.inithintinfo(hintinfo,fcellinfo.grid); + hintinfo.caption:= self[info.cell.row]; + application.showhint(fcellinfo.grid,hintinfo); + end; + end; + inherited; +end; + +procedure tcustomstringcol.afterrowcountupdate; +//var +// int1: integer; +begin + inherited; + if fdata <> nil then begin + tstringcoldatalist(fdata).afterrowcountupdate; + end; +end; + +function tcustomstringcol.edited: boolean; +begin + result:= gps_edited in fstate; +end; + +procedure tcustomstringcol.setcolorglyph(const avalue: colorty); +begin + if fcolorglyph <> avalue then begin + fcolorglyph:= avalue; + invalidate; + end; +end; + +procedure tcustomstringcol.fillcol(const value: msestring); +begin + datalist.fill(datalist.count,value); +end; + +function tcustomstringcol.getnoparagraph(const aindex: integer): boolean; +begin + result:= tcustomgrid(fowner).fdatacols.frowstate.flag1[aindex]; +end; + +{ tfixcol } + +constructor tfixcol.create(const agrid: tcustomgrid; + const aowner: tgridarrayprop); +begin + foptionsfix:= defaultfixcoloptions; + ftextinfo.flags:= defaultfixcoltextflags; + fcaptions:= tmsestringdatalist.create; + fcaptions.onitemchange:= {$ifdef FPC}@{$endif}captionchanged; + inherited; + include(fstate,gps_fix); + fcolor:= cl_parent; +end; + +destructor tfixcol.destroy; +begin + inherited; + fcaptions.Free; +end; + +procedure tfixcol.setoptionsfix(const avalue: fixcoloptionsty); +var + opt1: coloptions1ty; +begin + foptionsfix:= avalue; + opt1:= coloptions1ty( + {$ifndef FPC}word({$endif} + replacebits( + longword( + {$ifndef FPC}byte({$endif}avalue{$ifndef FPC}){$endif}) + shr longword(fixcoloptionsshift1), + longword(foptions), + longword( + {$ifndef FPC}word({$endif} + fixcoloptionsmask + {$ifndef FPC}){$endif} + ) + ) + {$ifndef FPC}){$endif} + ); + inherited options1:= opt1; + if fco_invisible in avalue then begin + inherited options:= inherited options + [co_invisible]; + end + else begin + inherited options:= inherited options - [co_invisible]; + end; + { + if fco_active in avalue then begin + options1:= options1 + [co1_active]; + end + else begin + options1:= options1 - [co1_active]; + end; + } +end; + +procedure tfixcol.drawcell(const canvas: tcanvas); +begin + inherited; + with cellinfoty(canvas.drawinfopo^) do begin + if not (cds_notext in drawstate) then begin + ftextinfo.dest:= innerrect; + if cell.row < fcaptions.count then begin + ftextinfo.text.text:= fcaptions[cell.row]; + drawtext(canvas,ftextinfo); + end + else begin + if fnumstep <> 0 then begin + ftextinfo.text.text:= + inttostrmse(fcellinfo.grid.fnumoffset+fnumstart+fnumstep*cell.row); + drawtext(canvas,ftextinfo); + end; + end; + end; + end; +end; + +procedure tfixcol.moverow(const fromindex, toindex: integer; + const count: integer = 1); +begin + +end; + +procedure tfixcol.insertrow(const aindex: integer; const count: integer = 1); +begin + //dummy +end; + +procedure tfixcol.deleterow(const aindex: integer; const count: integer = 1); +begin + //dummy +end; + +procedure tfixcol.setoptions(const Value: coloptionsty); +begin + inherited setoptions(value - notfixcoloptions); +end; + +procedure tfixcol.settextflags(const Value: textflagsty); +begin + if ftextinfo.flags <> value then begin + ftextinfo.flags := checktextflags(ftextinfo.flags,Value); + changed; + end; +end; + +procedure tfixcol.setnumstart(const Value: integer); +begin + if fnumstart <> value then begin + fnumstart:= Value; + changed; + end; +end; + +procedure tfixcol.setnumstep(const Value: integer); +begin + if fnumstep <> value then begin + fnumstep := Value; + changed; + end; +end; + +{ +procedure tfixcol.updatelayout; +begin + inherited; + ftextinfo.dest:= fcellinfo.innerrect; +end; +} + +procedure tfixcol.paint(var info: colpaintinfoty); +begin + if ffont = nil then begin + ftextinfo.font:= fcellinfo.grid.getfont; + end + else begin + ftextinfo.font:= ffont; + end; + inherited; +end; + +procedure tfixcol.setcaptions(const Value: tmsestringdatalist); +begin + fcaptions.assign(Value); +end; + +function tfixcol.getcaptions: tmsestringdatalist; +begin + result:= fcaptions; +end; + +function tfixcol.iscaptionsstored: Boolean; +begin + result:= fcaptions.count > 0; +end; + +procedure tfixcol.captionchanged(const sender: tdatalist; const aindex: integer); +begin + if aindex < 0 then begin + changed; + end + else begin + cellchanged(aindex); + end; +end; + +procedure tfixcol.rearange(const list: integerarty); +begin + if not (co_norearange in foptions) and (fnumstep = 0) and + (fcaptions.count = length(list)) then begin + fcaptions.rearange(list); + end; +end; + +function tfixcol.getvisible: boolean; +begin + result:= not (fco_invisible in options); +end; + +procedure tfixcol.setvisible(const avalue: boolean); +begin + if avalue then begin + options:= options - [fco_invisible]; + end + else begin + options:= options + [fco_invisible]; + end; +end; + +{ tcolsfont } + +class function tcolsfont.getinstancepo(owner: tobject): pfont; +begin + result:= @tcols(owner).ffont; +end; + +{ tcolsfontselect } + +class function tcolsfontselect.getinstancepo(owner: tobject): pfont; +begin + result:= @tcols(owner).ffontselect; +end; + +{ tcols } + +constructor tcols.create(aowner: tcustomgrid; aclasstype: gridpropclassty); +begin + fwidth:= griddefaultcolwidth; + ffontactivenum:= -1; + ffontfocusednum:= -1; + inherited; +end; + +destructor tcols.destroy; +begin + inherited; + ffont.free; + ffontselect.free; +end; + +function tcols.mergedwidth(const acol: integer; const amerged: longword): integer; +var + int1: integer; +begin + result:= 0; + if (amerged <> 0) and (acol < mergedcolmax) then begin + if (acol = 0) or (amerged and bits[acol-1] = 0) then begin + if amerged = mergedcolall then begin + for int1:= 1 to count -1 do begin + with tcol(fitems[int1]) do begin + if not (co_invisible in foptions) then begin + result:= result + step; + end; + end; + end; + end + else begin + for int1:= acol to count -1 do begin + if amerged and bits[int1] <> 0 then begin + with tcol(fitems[int1]) do begin + if not (co_invisible in foptions) then begin + result:= result + step; + end; + end; + end + else begin + break; + end; + end; + end; + end; + end; +end; + +procedure tcols.paint(var info: colpaintinfoty; const scrollables: boolean = true); +var + startx,endx: integer; + pt1,pt2: pointty; + int1,int2,int3,int4: integer; + ar1: integerarty; +// po1: prowstatety; +begin + with info do begin + pt1:= canvas.origin; + with canvas.clipbox do begin + startx:= x {+ po1.x}; + endx:= startx + cx; + end; + pt2:= pt1; + setlength(ar1,count); + if (og_colmerged in fgrid.foptionsgrid) and (self is tdatacols) then begin + for int1:= 0 to high(ar1) do begin + with tcol(fitems[int1]) do begin + int4:= 0; + if int1 < mergedcolmax then begin + for int2:= 0 to high(info.rows) do begin + int3:= mergedwidth(int1,tdatacols(self).frowstate.merged[int2]); + if int3 > int4 then begin + int4:= int3; + end; + end; + end; + ar1[int1]:= fend + int4; + end; + end; + end + else begin + for int1:= 0 to high(ar1) do begin + ar1[int1]:= tcol(fitems[int1]).fend; + end; + end; + for int1:= 0 to count-1 do begin + with tcol(fitems[int1]) do begin + if (scrollables xor (co_nohscroll in foptions)) and + (calcautocellsize or not ((startx < fstart) and (endx <= fstart) or + (startx >= ar1[int1]) and (endx > ar1[int1]))) then begin + pt2.x:= fstart + pt1.x; + canvas.origin:= pt2; + paint(info); + end; + end; + end; + canvas.origin:= pt1; + end; +end; + +procedure tcols.updaterowheight(const arow: integer; var arowheight: integer); +var + info: colpaintinfoty; +begin + fillchar(info,sizeof(info),0); + with info do begin + calcautocellsize:= true; + autocellsize.cx:= 0; + autocellsize.cy:= arowheight; + canvas:= fgrid.getcanvas; + setlength(rows,1); + rows[0]:= arow; //startrow = endrow = 0 + paint(info,true); + paint(info,false); + arowheight:= autocellsize.cy; + end; +end; + +procedure tcols.updatelayout; +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + tcol(fitems[int1]).updatelayout; + end; + inherited; +end; + +procedure tcols.rowcountchanged(const countbefore: int32; + const newcount: integer); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + tcol(fitems[int1]).rowcountchanged(newcount); + end; +end; + +function tcols.totwidth: integer; +var + int1: integer; +begin + result:= 0; + for int1:= 0 to count-1 do begin + inc(result,tcol(items[int1]).step); + end; +end; + +function tcols.getclientsize: integer; +begin + result:= tgridframe(fgrid.fframe).finnerclientrect.cx; +end; + +function tcols.getcols(const index: integer): tcol; +begin + result:= tcol(items[index]); +end; + +procedure tcols.setwidth(const Value: integer); +var + int1: integer; +begin + if fwidth <> value then begin + fwidth:= value; + if not (csloading in fgrid.componentstate) then begin + for int1:= 0 to count - 1 do begin + tcol(items[int1]).width:= value; + end; + end; + end; +end; + +procedure tcols.setoptions(const avalue: coloptionsty; + const aforce: boolean); +var + int1: integer; + mask: longword; +begin + mask:= longword(avalue - deprecatedcoloptions) xor longword(foptions); + foptions:= avalue - deprecatedcoloptions; + if csreading in fgrid.componentstate then begin + transferdeprecatedcoloptions(avalue,foptions1); + end; + if not (csloading in fgrid.componentstate) or aforce then begin + for int1:= 0 to count - 1 do begin + tcol(items[int1]).options:= coloptionsty(replacebits(longword(foptions), + longword(tcol(items[int1]).options),mask)); + end; + end; +end; + +procedure tcols.setoptions(const avalue: coloptionsty); +begin + if foptions <> avalue then begin + setoptions(avalue,false); + end; +end; + +procedure tcols.setoptions1(const value: coloptions1ty); +var + int1: integer; + mask: {$ifdef FPC}longword{$else}byte{$endif}; +begin + if foptions1 <> value then begin + mask:= {$ifdef FPC}longword{$else}word{$endif}(value) xor + {$ifdef FPC}longword{$else}word{$endif}(foptions1); + foptions1:= Value; + if not (csloading in fgrid.componentstate) then begin + for int1:= 0 to count - 1 do begin + tcol(items[int1]).options1:= coloptions1ty( + replacebits( + {$ifdef FPC}longword{$else}word{$endif}(value), + {$ifdef FPC}longword{$else}word{$endif}(tcol(items[int1]).options1), + mask)); + end; + end; + fgrid.invalidate; + end; +end; + +procedure tcols.setfontactivenum(const avalue: integer); +var + int1: integer; +begin + if ffontactivenum <> avalue then begin + ffontactivenum:= avalue; + if not (csloading in fgrid.componentstate) then begin + for int1:= 0 to count - 1 do begin + tcol(items[int1]).fontactivenum:= avalue; + end; + end; + end; +end; + +procedure tcols.setfontfocusednum(const avalue: integer); +var + int1: integer; +begin + if ffontfocusednum <> avalue then begin + ffontfocusednum:= avalue; + if not (csloading in fgrid.componentstate) then begin + for int1:= 0 to count - 1 do begin + tcol(items[int1]).fontfocusednum:= avalue; + end; + end; + end; +end; + +procedure tcols.setfocusrectdist(const avalue: integer); +var + int1: integer; +begin + if ffocusrectdist <> avalue then begin + if not (csloading in fgrid.componentstate) then begin + for int1:= 0 to count - 1 do begin + tcol(items[int1]).focusrectdist:= avalue; + end; + end; + end; +end; + +function tcols.getfont: tcolsfont; +begin + getoptionalobject(fgrid.componentstate,ffont,@createfont); + if ffont <> nil then begin + result:= ffont; + end + else begin + result:= tcolsfont(pointer(fgrid.font)); + end; +end; + +procedure tcols.setfont(const avalue: tcolsfont); +begin + if avalue <> ffont then begin + setoptionalobject(fgrid.ComponentState,avalue,ffont, + @createfont); + fgrid.invalidate; + end; +end; + +function tcols.isfontstored: Boolean; +begin + result:= ffont <> nil; +end; + +procedure tcols.createfont; +begin + if ffont = nil then begin + ffont:= tcolsfont.create; + ffont.onchange:= @fontselectchanged; + end; +end; + +procedure tcols.fontselectchanged(const sender: tobject); +begin + fgrid.invalidate; +end; + +function tcols.getfontselect: tcolsfontselect; +begin + getoptionalobject(fgrid.componentstate,ffontselect,@createfontselect); + if ffontselect <> nil then begin + result:= ffontselect; + end + else begin + result:= tcolsfontselect(pointer(fgrid.font)); + end; +end; + +procedure tcols.setfontselect(const avalue: tcolsfontselect); +begin + if avalue <> ffontselect then begin + setoptionalobject(fgrid.ComponentState,avalue,ffontselect,@createfontselect); + fgrid.invalidate; + end; +end; + +function tcols.isfontselectstored: Boolean; +begin + result:= ffontselect <> nil; +end; + +procedure tcols.createfontselect; +begin + if ffontselect = nil then begin + ffontselect:= tcolsfontselect.create; + ffontselect.onchange:= @fontselectchanged; + end; +end; + +procedure tcols.move(const curindex, newindex: integer); +begin + inherited; + fgrid.ffixrows.movecol(curindex,newindex,freversedorder); + fgrid.layoutchanged; +end; + +procedure tcols.moverow(const curindex,newindex: integer; const acount: integer); +var + int1: integer; +begin + begindataupdate; + try + for int1:= 0 to self.count - 1 do begin + tcol(items[int1]).moverow(curindex,newindex,acount); + end; + finally + enddataupdate; + end; +end; + +procedure tcols.insertrow(const index: integer; const acount: integer = 1); +var + int1: integer; +begin + for int1:= 0 to self.count - 1 do begin + tcol(items[int1]).insertrow(index,acount); + end; +end; + +procedure tcols.deleterow(const index: integer; const acount: integer = 1); +var + int1: integer; +begin + for int1:= 0 to self.count - 1 do begin + tcol(items[int1]).deleterow(index,acount); + end; +end; + +procedure tcols.rearange(const list: integerarty); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + cols[int1].rearange(list); + end; +end; + +procedure tcols.begindataupdate; +begin + inc(fdataupdating); +end; + +procedure tcols.enddataupdate; +begin + dec(fdataupdating); +end; + +procedure tcols.resetpropwidth; +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + tcol(fitems[int1]).fpropwidth:= 0; + end; +end; + +procedure tcols.countchanged; +begin + resetpropwidth; + inherited; +end; + +procedure tcols.invalidatemaxsize(const arow: integer = -1); +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + tcol(fitems[int1]).invalidatemaxsize(arow); + end; +end; + +{ tdatacols } + +constructor tdatacols.create(aowner: tcustomgrid; aclasstype: gridpropclassty); +begin + fselectedrow:= -1; + fsortcol:= -1; + fsortcoldefault:= -1; + fnewrowcol:= -1; + flastvisiblecol:= -1; + frowstate:= trowstatelist.create(aowner); + inherited; + flinecolor:= defaultdatalinecolor; + foptions:= defaultdatacoloptions; + foptions1:= defaultdatacoloptions1; +end; + +destructor tdatacols.destroy; +begin + inherited; + frowstate.free; +end; + +procedure tdatacols.setcols(const index: integer; const Value: tdatacol); +begin + tdatacol(items[index]).Assign(value); +end; + +function tdatacols.getcols(const index: integer): tdatacol; +begin + result:= tdatacol(items[index]); +end; + +function tdatacols.colatpos(const x: integer; + const getscrollable: boolean = true): integer; +begin + result:= itematpos(x,getscrollable); +end; + +procedure tdatacols.updatelayout; +var + int1,int2: integer; +begin + int2:= -1; + flastvisiblecol:= -1; + for int1:= 0 to count - 1 do begin + with tdatacol(fitems[int1]) do begin + fcellinfo.cell.col:= int1; + if foptions * [co_fill,co_invisible,co_nohscroll] = [co_fill] then begin + int2:= int1; + end; + if not (co_invisible in foptions) then begin + flastvisiblecol:= int1; + end; + end; + end; + if int2 >= 0 then begin //last co_fill + with tdatacol(fitems[int2]) do begin + if co1_autocolwidth in foptions1 then begin + fwidth:= minmaxwidth; + end + else begin + fwidth:= fwidthmin; + end; + end; + end; + ffirstopposite:= 0; + for int1:= count-1 downto 0 do begin + with tdatacol(fitems[int1]) do begin + if not (co_nohscroll in foptions) then begin + ffirstopposite:= int1+1; + break; + end; + end; + end; + if ffirstopposite = 0 then begin + ffirstopposite:= count; + end; + inherited; + if int2 >= 0 then begin + int1:= totwidth; + if int1 < fgrid.fdatarect.cx then begin + with tdatacol(fitems[int2]) do begin + fwidth:= fwidth + fgrid.fdatarect.cx - int1{ - (step-fwidth)}; + if (gps_needsrowheight in fstate) then begin + rowstate.change(-1); + end; + end; + inherited; + end; + end; +end; + +procedure tdatacols.createitem(const index: integer; var item: tpersistent); +begin + item:= nil; + fgrid.createdatacol(index,tdatacol(item)); + if item = nil then begin + inherited; + end; +end; + +procedure tdatacols.rowcountchanged(const countbefore: int32; + const newcount: int32); +var + int1: integer; +begin + if fselectedrow >= newcount then begin + fselectedrow:= -1; + end; + if (newcount < countbefore) and (fselectedrow = -2) then begin + fselectedrowcount:= length(getselectedrows); + end; + for int1:= 0 to count - 1 do begin + with tdatacol(items[int1]) do begin + if fselectedrow >= newcount then begin + fselectedrow:= -1; + end; + if (newcount < countbefore) and (fselectedrow = -2) then begin + fselectedrowcount:= length(getselectedcells); + end; + end; + end; + with frowstate do begin + if folded and (newcount < count) then begin + updatedeletedrows(newcount,count-newcount); + end; + count:= newcount; + if fvisiblerowmap <> nil then begin + fvisiblerowmap.count:= newcount; + checkdirty(newcount); + end; + end; + inherited; +end; + +procedure tdatacols.setrowcountmax(const value: integer); +var + int1: integer; +begin + with frowstate do begin + maxcount:= value; + if fvisiblerowmap <> nil then begin + fvisiblerowmap.maxcount:= value; + checkdirty(value); + end; + end; + for int1:= 0 to count - 1 do begin + with tdatacol(items[int1]) do begin + if fdata <> nil then begin + fdata.maxcount:= value; + end; + end; + end; +end; + +function tdatacols.roworderinvalid: boolean; +var + int1: integer; +begin + if fselectedrow <> -1 then begin + fselectedrow:= -2; + end; + for int1:= 0 to count - 1 do begin + with tdatacol(items[int1]) do begin + if fselectedrow <> -1 then begin + fselectedrow:= -2; + end; + end; + end; + result:= true; + updatedatastate(result); +end; + +procedure tdatacols.checkindexrange; +begin + if not (csloading in fgrid.componentstate) then begin + if fsortcol >= count then begin + fsortcol:= count - 1; + end; + if fsortcoldefault >= count then begin + fsortcoldefault:= count - 1; + end; + if fnewrowcol >= count then begin + fnewrowcol:= count - 1; + end; + end; +end; + +procedure tdatacols.setsortcol(const avalue: integer); +var + int1: integer; +begin + int1:= fgrid.updatesortcol(avalue); + if int1 <> avalue then begin + fgrid.sorted:= false; + end; + if fsortcol <> int1 then begin + fsortcol := avalue; + checkindexrange; + fgrid.sortchanged(true); + end; +end; + +procedure tdatacols.setsortcoldefault(const avalue: integer); +begin + if fsortcoldefault <> avalue then begin + fsortcoldefault:= avalue; + checkindexrange; + fgrid.sortchanged(true); + end; +end; + +procedure tdatacols.setnewrowcol(const avalue: integer); +begin + if fnewrowcol <> avalue then begin + fnewrowcol := avalue; + checkindexrange; + end; +end; + +procedure tdatacols.moverow(const fromindex, toindex: integer; const acount: integer = 1); +begin +// roworderinvalid; + with frowstate do begin + blockmovedata(fromindex,toindex,acount); + if fvisiblerowmap <> nil then begin + fvisiblerowmap.blockmovedata(fromindex,toindex,acount); + checkdirty(fromindex); + checkdirty(toindex); + end; + end; + inherited; +end; + +procedure tdatacols.insertrow(const index: integer; const acount: integer = 1); +begin +// roworderinvalid; + with frowstate do begin + insertitems(index,acount); + if fvisiblerowmap <> nil then begin + fvisiblerowmap.insertitems(index,acount); + checkdirty(index); + end; + end; + inherited; +end; + + +procedure tdatacols.deleterow(const index: integer; const acount: integer = 1); +begin +// roworderinvalid; + with frowstate do begin + if fvisiblerowmap <> nil then begin + updatedeletedrows(index,acount); + fvisiblerowmap.deleteitems(index,acount); + end; + deleteitems(index,acount); + end; + inherited; +end; + +procedure tdatacols.beginchangelock; +var + int1: integer; +begin + if fchangelock = 0 then begin + for int1:= 0 to count-1 do begin + with tdatacol(fitems[int1]) do begin + include(fstate,gps_changelock); + end; + end; + end; + inc(fchangelock); +end; + +procedure tdatacols.endchangelock; +var + int1: integer; + col1: tdatacol; +begin + dec(fchangelock); + if fchangelock = 0 then begin + for int1:= 0 to count-1 do begin + with tdatacol(fitems[int1]) do begin + exclude(fstate,gps_changelock); + end; + end; + if fgrid.componentstate * + [csloading,csdesigning,csdestroying] = [] then begin + for int1:= 0 to count - 1 do begin + col1:= tdatacol(fitems[int1]); + if assigned(col1.fonchange) then begin + col1.fonchange(col1,-1); + end; + end; + end; + end; +end; + +procedure tdatacols.setcount1(acount: integer; doinit: boolean); +begin + roworderinvalid; + if fgrid.ffocusedcell.col >= acount then begin + if csdestroying in fgrid.componentstate then begin + fgrid.ffocusedcell:= invalidcell; + end + else begin + fgrid.col:= invalidaxis; + end; + end; + inherited; +end; + +function tdatacols.getselected(const cell: gridcoordty): boolean; +var + int1: integer; +begin + if cell.col >= 0 then begin + result:= cols[cell.col].getselected(cell.row); + end + else begin + if cell.row >= 0 then begin + result:= (frowstate.getitempo(cell.row)^.selected and + wholerowselectedmask <> 0); + end + else begin + result:= true; + for int1:= 0 to count - 1 do begin + if not (gps_selected in cols[int1].fstate) then begin + result:= false; + break; + end; + end; + end; + end; +end; + +procedure tdatacols.setselected(const cell: gridcoordty; const Value: boolean); +var + int1: integer; + po1: prowstatety; + ca1: longword; + bo1: boolean; + rowstatesize: integer; + +begin + fgrid.setselected(cell,value); +// if not (gs_isdb in fgrid.fstate) then begin + if cell.col >= 0 then begin + cols[cell.col].setselected(cell.row,value); + end + else begin //select-deselect whole row + fgrid.beginupdate; + try + for int1:= 0 to count - 1 do begin + cols[int1].setselected(cell.row,value); + end; + if value then begin + ca1:= $ffffffff; + end + else begin + ca1:= 0; + end; + bo1:= false; + if cell.row >= 0 then begin + po1:= frowstate.getitempo(cell.row); + if ca1 <> po1^.selected then begin + if value then begin + inc(fselectedrowcount); + if fselectedrow = -1 then begin + fselectedrow:= cell.row; + end + else begin + fselectedrow:= -2; + end; + end + else begin + dec(fselectedrowcount); + if (fselectedrow = cell.row) or (fselectedrowcount = 0) then begin + fselectedrow:= -1; + end; + end; + po1^.selected:= ca1; + fgrid.invalidaterow(cell.row); //for fixcols + bo1:= true; + end; + end + else begin + po1:= frowstate.datapo; + rowstatesize:= frowstate.fsize; + if value then begin + for int1:= 0 to frowstate.count - 1 do begin + if ca1 <> po1^.selected then begin + po1^.selected:= ca1; + fgrid.invalidaterow(int1); //for fixcols + end; + inc(pchar(po1),rowstatesize); + end; + fselectedrowcount:= fgrid.rowcount; + fselectedrow:= -2; + end + else begin + if fselectedrow <> -1 then begin + if fselectedrow >= 0 then begin + prowstatety(pchar(po1) + fselectedrow * rowstatesize)^.selected:= ca1; + fgrid.invalidaterow(fselectedrow); //for fixcols + bo1:= true; + end + else begin + for int1:= 0 to frowstate.count - 1 do begin + if ca1 <> po1^.selected then begin + po1^.selected:= ca1; + fgrid.invalidaterow(int1); //for fixcols + bo1:= true; + end; + inc(pchar(po1),rowstatesize); + end; + end; + fselectedrowcount:= 0; + fselectedrow:= -1; + end; + end; + end; + if bo1 then begin + fgrid.internalselectionchanged; + end; + finally + fgrid.endupdate; + end; + end; +// end; +end; + +function tdatacols.Getrowselected(const index: integer): boolean; +begin + result:= getselected(makegridcoord(invalidaxis,index)); +end; + +procedure tdatacols.Setrowselected(const index: integer; const avalue: boolean); +begin + setselected(makegridcoord(invalidaxis,index),avalue); +end; + +function tdatacols.getreadonly: boolean; +begin + result:= co_readonly in foptions; +end; + +procedure tdatacols.setreadonly(const avalue: boolean); +begin + if avalue then begin //propagate to items independent of loading state + setoptions(foptions + [co_readonly],true); + end + else begin + setoptions(foptions - [co_readonly],true); + end; +end; + +procedure tdatacols.clearselection; +begin + setselected(invalidcell,false); +end; + +procedure tdatacols.setselectedrange(const start,stop: gridcoordty; + const value: boolean; + const calldoselectcell: boolean = false; + const checkmultiselect: boolean = false); +var + int1,int2: integer; + mo1: cellselectmodety; + rect: gridrectty; +begin + rect.pos:= start; + rect.colcount:= stop.col - start.col; + rect.rowcount:= stop.row - start.row; + normalizerect1(rectty(rect)); + if calldoselectcell then begin + if value then begin + mo1:= csm_select; + end + else begin + mo1:= csm_deselect; + end; + for int1:= rect.col to rect.col + rect.colcount - 1 do begin + cols[int1].beginselect; + for int2:= rect.row to rect.row + rect.rowcount - 1 do begin + fgrid.selectcell(makegridcoord(int1,int2),mo1,checkmultiselect); + end; + end; + for int1:= rect.col to rect.col + rect.colcount - 1 do begin + try + cols[int1].endselect; + except + application.handleexception; + end; + end; + end + else begin + for int1:= rect.col to rect.col + rect.colcount - 1 do begin + with cols[int1] do begin + beginselect; + if not value or not checkmultiselect or + (co_multiselect in options) then begin + for int2:= rect.row to rect.row + rect.rowcount - 1 do begin + selected[int2]:= value; + end; + end; + end; + end; + for int1:= rect.col to rect.col + rect.colcount - 1 do begin + dec(cols[int1].fselectlock); + end; + end; +end; + +procedure tdatacols.setselectedrange(const rect: gridrectty; const value: boolean; + const calldoselectcell: boolean = false; + const checkmultiselect: boolean = false); +begin + setselectedrange(rect.pos, + makegridcoord(rect.col+rect.colcount,rect.row+rect.rowcount), + value,calldoselectcell,checkmultiselect); +end; + +procedure tdatacols.changeselectedrange(const start,oldend,newend: gridcoordty; + calldoselectcell: boolean); +begin +//dummy +end; + +function tdatacols.hasselection: boolean; +var + int1: integer; +begin + result:= fselectedrow <> -1; + if not result then begin + for int1:= 0 to count - 1 do begin + if cols[int1].fselectedrow <> -1 then begin + result:= true; + break; + end; + end; + end; +end; + +procedure tdatacols.mergecols(const arow: integer; const astart: longword = 0; + const acount: longword = bigint); +begin + if frowstate.mergecols(arow,astart,acount) then begin + mergechanged(arow); + end; +end; + +procedure tdatacols.unmergecols(const arow: integer = invalidaxis); +begin + if frowstate.unmergecols(arow) then begin + mergechanged(arow); + end; +end; + +function tdatacols.previosvisiblecol(aindex: integer): integer; +var + int1: integer; +begin + result:= invalidaxis; + if aindex >= count then begin + aindex:= count - 1; + end; + for int1:= aindex - 1 downto 0 do begin + if not (co_invisible in tdatacol(fitems[int1]).foptions) or + (csdesigning in fgrid.ComponentState) then begin + result:= int1; + break; + end; + end; +end; + +function tdatacols.nextvisiblecol(aindex: integer): integer; +var + int1: integer; +begin + result:= invalidaxis; + if aindex < 0 then begin + aindex:= 0; + end; + for int1:= aindex + 1 to count-1 do begin + if not (co_invisible in tdatacol(fitems[int1]).foptions) or + (csdesigning in fgrid.ComponentState) then begin + result:= int1; + break; + end; + end; +end; + +function tdatacols.selectedcellcount: integer; +var + {int1,}int2: integer; +// bo1: boolean; +begin + result:= 0; + for int2:= 0 to count - 1 do begin + with tdatacol(fitems[int2]) do begin + result:= result + selectedcellcount; + end; + end; +{ + if hasselection then begin + bo1:= hascolselection; + for int1:= 0 to frowstate.count - 1 do begin + if bo1 or (frowstate.getitempo(int1)^.selected <> 0) then begin + for int2:= 0 to count - 1 do begin + if tdatacol(fitems[int2]).selected[int1] then begin + inc(result); + end; + end; + end; + end; + end; +} +end; + +function tdatacols.hascolselection: boolean; +var + int1: integer; +begin + result:= false; + for int1:= 0 to count - 1 do begin + if gps_selected in tdatacol(fitems[int1]).fstate then begin + result:= true; + exit; + end; + end; +end; + +function tdatacols.getselectedcells: gridcoordarty; +const + capacitystep = 64; +var + int1,int2,int3: integer; + cell: gridcoordty; + bo1: boolean; +begin + result:= nil; + if hasselection then begin //todo: optimize + int3:= 0; + bo1:= hascolselection; + for int1:= 0 to frowstate.count - 1 do begin + if bo1 or (frowstate.getitempo(int1)^.selected <> 0) then begin + cell.row:= int1; + for int2:= 0 to count - 1 do begin + if tdatacol(fitems[int2]).selected[int1] then begin + if int3 >= length(result) then begin + setlength(result,length(result)*2 + capacitystep); + end; + cell.col:= int2; + result[int3]:= cell; + inc(int3); + end; + end; + end; + end; + setlength(result,int3); + end; +end; + +procedure tdatacols.beginselect; +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + tdatacol(fitems[int1]).beginselect; + end; +end; + +procedure tdatacols.endselect; +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + try + tdatacol(fitems[int1]).endselect; + except + application.handleexception; + end; + end; +end; + +procedure tdatacols.decselect; +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + with tdatacol(fitems[int1]) do begin + dec(fselectlock); + end; + end; +end; + +procedure tdatacols.setselectedcells(const Value: gridcoordarty); +var + int1: integer; +begin + fgrid.beginupdate; + beginselect; + clearselection; + for int1:= 0 to high(value) do begin + setselected(value[int1],true); + end; + endselect; + fgrid.endupdate; +end; + +function tdatacols.getselectedrows: integerarty; +var + int1,int2,int3: integer; + po1: prowstatety; +begin + result:= nil; + po1:= frowstate.datapo; + int2:= 0; + int3:= frowstate.fsize; + for int1:= 0 to fgrid.frowcount - 1 do begin + if po1^.selected and wholerowselectedmask <> 0 then begin + additem(result,int1,int2); + end; + inc(pchar(po1),int3); + end; + setlength(result,int2); +end; + +procedure tdatacols.setselectedrows(const avalue: integerarty); +var + int1: integer; +begin + fgrid.beginupdate; + beginselect; + clearselection; + for int1:= 0 to high(avalue) do begin + setselected(makegridcoord(invalidaxis,avalue[int1]),true); + end; + endselect; + fgrid.endupdate; +end; + +function tdatacols.sortfunc(const l,r: integer): integer; +var + int1: integer; +begin + result:= 0; + if fsortcol < 0 then begin + for int1:= 0 to count-1 do begin + with tdatacol(fitems[int1]) do begin + if not(co_nosort in foptions) then begin + if co_sortcaseinsensitive in foptions then begin + result:= sortcomparecaseinsensitive(l,r); + end + else begin + result:= sortcompare(l,r); + end; + if result <> 0 then begin + if co_sortdescend in foptions then begin + result:= - result; + end; + break; + end; + end; + end; + end; + end + else begin + with tdatacol(fitems[fsortcol]) do begin + if not(co_nosort in foptions) then begin + result:= sortcompare(l,r); + if co_sortdescend in foptions then begin + result:= - result; + end; + end; + end; + if (result = 0) and (fsortcoldefault >= 0) then begin + with tdatacol(fitems[fsortcoldefault]) do begin + if not(co_nosort in foptions) then begin + result:= sortcompare(l,r); + if co_sortdescend in foptions then begin + result:= - result; + end; + end; + end; + end; + end; +end; + +procedure tdatacols.updatedatastate(var accepted: boolean); +begin +//dummy +end; + +function compcol(const l,r): integer; +begin + result:= tdatacol(l).fcellinfo.cell.col - tdatacol(r).fcellinfo.cell.col; +end; + +procedure tdatacols.dostatread(const reader: tstatreader; const aorder: boolean); +var + int1: integer; + ar1: integerarty; + int2: integer; +begin + ar1:= nil; //compiler warning + fgrid.beginupdate; + try + if (og_savestate in fgrid.foptionsgrid) and reader.canstate then begin + if og_colmoving in fgrid.optionsgrid then begin + fgrid.ffixrows.orderdatacols(originalorder); + ar1:= readorder(reader); + if ar1 <> nil then begin + fgrid.fixrows.reorderdatacols(ar1); + fgrid.layoutchanged; + end; + end; + end; + for int1:= 0 to count - 1 do begin + cols[int1].dostatread(reader); + end; + if hassortstat then begin + sortcol:= reader.readinteger('sortcol',sortcol,-1,count-1); + end; + if not (gs_isdb in fgrid.fstate) then begin + int2:= -1; + if (og_savestate in fgrid.foptionsgrid) and + (fgrid.foptionsgrid * [og_folded,og_colmerged,og_rowheight] <> []) and + hasdatastat and reader.candata then begin + reader.readdatalist('rowstate',frowstate); + int2:= frowstate.count; + end; + for int1:= 0 to count - 1 do begin + with cols[int1] do begin + if (fdata <> nil) and (fdata.count > int2) then begin + int2:= fdata.count; + end; + end; + end; + if int2 >= 0 then begin + frowstate.count:= int2; + for int1:= 0 to count - 1 do begin + with cols[int1] do begin + if (fdata <> nil) then begin + fdata.count:= int2; + end; + end; + end; + fgrid.rowcount:= int2; + if frowstate.folded then begin + frowstate.recalchidden; + end; + end; + end; + finally + fgrid.endupdate; + end; +end; + +procedure tdatacols.dostatwrite(const writer: tstatwriter; const aorder: boolean); +begin + inherited; + if (og_savestate in fgrid.foptionsgrid) and writer.canstate and + hassortstat then begin + writer.writeinteger('sortcol',sortcol); + end; + if (fgrid.foptionsgrid * [og_folded,og_colmerged,og_rowheight] <> []) and + writer.candata then begin + writer.writedatalist('rowstate',frowstate); + end; +end; + +function tdatacols.cancopy: boolean; +var + int1: integer; +begin + result:= false; + for int1:= 0 to count-1 do begin + with tdatacol(fitems[int1]) do begin + if co_cancopy in foptions then begin + result:= true; + break; + end; + end; + end; +end; + +function tdatacols.canpaste: boolean; +var + int1: integer; +begin + result:= false; + for int1:= 0 to count-1 do begin + with tdatacol(fitems[int1]) do begin + if co_canpaste in foptions then begin + result:= true; + break; + end; + end; + end; +end; + +function tdatacols.rowempty(const arow: integer): boolean; +var + int1: integer; +begin + result:= true; + for int1:= 0 to count - 1 do begin + if not tdatacol(fitems[int1]).isempty(arow) then begin + result:= false; + break; + end; + end; +end; + +procedure tdatacols.rearange(const list: integerarty); +begin + inherited; + frowstate.rearange(list); +end; + +procedure tdatacols.move(const curindex: integer; const newindex: integer); + + procedure domove(var avalue: integer); + begin + if avalue >= 0 then begin + if avalue = curindex then begin + avalue:= newindex; + end + else begin + if (avalue > curindex) and (avalue <= newindex) then begin + dec(avalue); + end + else begin + if (avalue < curindex) and (avalue >= newindex) then begin + inc(avalue); + end; + end; + end; + end; + end; //domove + +begin + inherited; + domove(fnewrowcol); + domove(fsortcol); + domove(fsortcoldefault); +end; + +procedure tdatacols.dosizechanged; +begin + checkindexrange; + inherited; +end; + +function tdatacols.colbyname(const aname: string): tdatacol; +var + int1: integer; +begin + result:= nil; + for int1:= 0 to count - 1 do begin + if tdatacol(fitems[int1]).fname = aname then begin + result:= tdatacol(fitems[int1]); + break; + end; + end; +end; + +function tdatacols.datalistbyname(const aname: string): tdatalist; //can be nil +var + col1: tdatacol; +begin + result:= nil; + col1:= colbyname(aname); + if col1 <> nil then begin + result:= col1.datalist; + end; +end; + +function tdatacols.colsubdatainfo(const aname: string): subdatainfoty; +var + int1: integer; +begin + result.subindex:= 0; + result.list:= nil; + for int1:= 0 to count - 1 do begin + with tdatacol(fitems[int1]) do begin + if fname = aname then begin + result.list:= datalist; + break; + end; + if fnameb = aname then begin + result.list:= datalist; + result.subindex:= 1; + break; + end; + end; + end; +end; + +procedure tdatacols.datasourcechanged; +begin + //dummy +end; + +procedure tdatacols.begindataupdate; +var + int1: integer; +begin + if fdataupdating = 0 then begin + for int1:= 0 to count - 1 do begin + with tdatacol(fitems[int1]) do begin + if fdata <> nil then begin + fdata.beginupdate; + end; + end; + end; + end; + inherited; +end; + +procedure tdatacols.enddataupdate; +var + int1: integer; +begin + inherited; + if fdataupdating = 0 then begin + for int1:= 0 to count - 1 do begin + try + with tdatacol(fitems[int1]) do begin + if fdata <> nil then begin + fdata.endupdate; + end; + end; + except + application.handleexception(fgrid); + end; + end; + end; +end; + +procedure tdatacols.countchanged; +begin + if flastvisiblecol >= count then begin + flastvisiblecol:= count - 1; + end; + fgrid.ffixrows.datacolscountchanged; + inherited; +end; + +procedure tdatacols.mergechanged(const arow: integer); +begin + if (arow < 0) or (arow >= 0) and (arow = fgrid.row) then begin + fgrid.layoutchanged; + end + else begin + fgrid.invalidaterow(arow); + end; + fgrid.rowstatechanged(arow); +end; + +function tdatacols.hassortstat: boolean; +var + int1,int2,int3: integer; +begin + result:= false; + int3:= high(fitems); + for int1:= 0 to fgrid.ffixrows.count-1 do begin + with tfixrow(fgrid.ffixrows.fitems[int1]) do begin + for int2:= 0 to high(fcaptions.fitems) do begin + if int2 >= int3 then begin + break; + end; + with tdatacolheader(fcaptions.fitems[int2]) do begin + if dco_colsort in foptions then begin + result:= true; + break; + end; + end; + end; + if result then begin + break; + end; + end; + end; +end; + +function tdatacols.hasdatastat: boolean; +var + int1: integer; +begin + result:= false; + for int1:= 0 to high(fitems) do begin + with tdatacol(fitems[int1]) do begin + if co_savevalue in foptions then begin + result:= true; + break; + end; + end; + end; +end; + + +function tdatacols.updatedatastate: boolean; +begin + result:= true; + updatedatastate(result); +end; + +function tdatacols.defaultrowheight: integer; +var + int1: integer; + int2: integer; +begin + if fitems = nil then begin + result:= fgrid.datarowheight; + end + else begin + result:= 0; + for int1:= 0 to high(fitems) do begin + int2:= tdatacol(fitems[int1]).defaultrowheight; + if int2 > result then begin + result:= int2; + end; + end; + end; +end; + +{ tdrawcols } + +constructor tdrawcols.create(aowner: tcustomgrid); +begin + inherited create(aowner,tdrawcol); +end; + +class function tdrawcols.getitemclasstype: persistentclassty; +begin + result:= tdrawcol; +end; + +function tdrawcols.getcols(const index: integer): tdrawcol; +begin + result:= tdrawcol(items[index]); +end; + +{ tstringcols } + +constructor tstringcols.create(aowner: tcustomgrid); +begin + ftextflags:= defaultcoltextflags; + ftextflagsactive:= defaultactivecoltextflags; + foptionsedit:= defaultstringcoleditoptions; + foptionsedit1:= defaultoptionsedit1; + inherited create(aowner,getcolclass); +end; + +class function tstringcols.getitemclasstype: persistentclassty; +begin + result:= tstringcol; +end; + +function tstringcols.getcolclass: stringcolclassty; +begin + result:= tstringcol; +end; + +function tstringcols.getcols(const index: integer): tstringcol; +begin + result:= tstringcol(items[index]); +end; + +procedure tstringcols.settextflags(avalue: textflagsty); +var + int1: integer; + mask: {$ifdef FPC}longword{$else}word{$endif}; +begin + if ftextflags <> avalue then begin + avalue:= checktextflags(ftextflags,avalue); + mask:= {$ifdef FPC}longword{$else}longword{$endif}(avalue) xor + {$ifdef FPC}longword{$else}longword{$endif}(ftextflags); + ftextflags:= avalue; + if not (csloading in fgrid.componentstate) then begin + for int1:= 0 to count - 1 do begin + tstringcol(items[int1]).textflags:= + textflagsty(replacebits({$ifdef FPC}longword{$else}longword{$endif}(avalue), + {$ifdef FPC}longword{$else}longword{$endif}(tstringcol(items[int1]).textflags),mask)); + end; + end; + end; +end; + +procedure tstringcols.settextflagsactive(avalue: textflagsty); +var + int1: integer; + mask: {$ifdef FPC}longword{$else}word{$endif}; +begin + if ftextflagsactive <> avalue then begin + avalue:= checktextflags(ftextflagsactive,avalue); + mask:= {$ifdef FPC}longword{$else}longword{$endif}(avalue) xor + {$ifdef FPC}longword{$else}longword{$endif}(ftextflagsactive); + ftextflagsactive := avalue; + if not (csloading in fgrid.componentstate) then begin + for int1:= 0 to count - 1 do begin + tstringcol(items[int1]).textflagsactive:= + textflagsty(replacebits( + {$ifdef FPC}longword{$else}longword{$endif}(avalue), + {$ifdef FPC}longword{$else}longword{$endif} + (tstringcol(items[int1]).textflagsactive),mask)); + end; + end; + end; +end; + +procedure tstringcols.setoptionsedit(avalue: stringcoleditoptionsty); +var + int1: integer; + mask: {$ifdef FPC}longword{$else}byte{$endif}; +begin +// exclude(avalue,scoe_autopost); + if foptionsedit <> avalue then begin + mask:= {$ifdef FPC}longword{$else}longword{$endif}(avalue) xor + {$ifdef FPC}longword{$else}longword{$endif}(foptionsedit); + foptionsedit := avalue; + if not (csloading in fgrid.componentstate) then begin + for int1:= 0 to count - 1 do begin + tstringcol(items[int1]).optionsedit:= stringcoleditoptionsty( + replacebits({$ifdef FPC}longword{$else}longword{$endif}(avalue), + {$ifdef FPC}longword{$else}longword{$endif} + (tstringcol(items[int1]).optionsedit),mask)); + end; + end; + end; +end; + +procedure tstringcols.setoptionsedit1(avalue: optionsedit1ty); +var + int1: integer; + mask: {$ifdef FPC}longword{$else}byte{$endif}; +begin +// exclude(avalue,scoe_autopost); + if foptionsedit1 <> avalue then begin + mask:= {$ifdef FPC}longword{$else}byte{$endif}(avalue) xor + {$ifdef FPC}longword{$else}byte{$endif}(foptionsedit1); + foptionsedit1:= avalue; + if not (csloading in fgrid.componentstate) then begin + for int1:= 0 to count - 1 do begin + tstringcol(items[int1]).optionsedit1:= optionsedit1ty( + replacebits({$ifdef FPC}longword{$else}byte{$endif}(avalue), + {$ifdef FPC}longword{$else}byte{$endif} + (tstringcol(items[int1]).optionsedit1),mask)); + end; + end; + end; +end; + +procedure tstringcols.updatedatastate(var accepted: boolean); +begin + fgrid.checkcellvalue(accepted); + inherited; +end; + +{ tfixcols } + +constructor tfixcols.create(aowner: tcustomgrid); +begin + freversedorder:= true; + inherited create(aowner,tfixcol); + flinecolor:= defaultfixlinecolor; +end; + +class function tfixcols.getitemclasstype: persistentclassty; +begin + result:= tfixcol; +end; + +function tfixcols.getcols(const index: integer): tfixcol; +begin + result:= tfixcol(items[-index-1]); +end; + +procedure tfixcols.setcols(const index: integer; const Value: tfixcol); +begin + tfixcol(items[-index-1]).assign(value); +end; + +function tfixcols.colatpos(const x: integer): integer; +begin + result:= itematpos(x); + if result < 0 then begin + result:= 0; + end + else begin + result:= -result - 1; + end; +end; + +procedure tfixcols.updatelayout; +var + int1: integer; +begin + if foppositecount > count then begin + foppositecount:= count; + end; + ffirstopposite:= -(count-foppositecount)-1; + for int1:= 0 to count - 1 do begin + tfixcol(fitems[int1]).fcellinfo.cell.col:= -int1-1; + end; + inherited; +end; + +procedure tfixcols.countchanged; +begin + fgrid.fixrows.fixcolscountchanged; + inherited; +end; + +{ tfixrows } + +constructor tfixrows.create(aowner: tcustomgrid); +begin + freversedorder:= true; + inherited create(aowner,tfixrow); + flinecolor:= defaultfixlinecolor; +end; + +class function tfixrows.getitemclasstype: persistentclassty; +begin + result:= tfixrow; +end; + +function tfixrows.getrows(const index: integer): tfixrow; +begin + result:= tfixrow(items[-index-1]); +end; + +procedure tfixrows.setrows(const index: integer; const Value: tfixrow); +begin + tfixrow(items[-index-1]).Assign(value); +end; + +function tfixrows.rowatpos(const y: integer): integer; +begin + result:= itematpos(y); + if result < 0 then begin + result:= 0; + end + else begin + result:= -result - 1; + end; +end; + +procedure tfixrows.updatelayout; +var + int1: integer; +begin + if foppositecount > count then begin + foppositecount:= count; + end; + ffirstopposite:= -(count-foppositecount)-1; + for int1:= 0 to count - 1 do begin + tfixrow(fitems[int1]).fcellinfo.cell.row:= -int1-1; + end; + inherited; + for int1:= 0 to count - 1 do begin + tfixrow(items[int1]).updatelayout; + end; +end; + +procedure tfixrows.updatemergedcells; +var + int1: integer; +begin + for int1:= count - 1 downto 0 do begin //top down for row merging + tfixrow(items[int1]).updatemergedcells; + end; +end; + +procedure tfixrows.paint(const info: rowspaintinfoty); +var + po1,po2: pointty; + linewidthbefore: integer; + + procedure paintrows(const range: rangety); + var + int1: integer; + begin + with info do begin + for int1:= range.startindex to range.endindex do begin + with tfixrow(fitems[int1]) do begin + po2.y:= po1.y + fstart; + with rowinfo do begin + canvas.origin:= po2; + paint(rowinfo); + end; + end; + end; + end; + end; + +var + int1,int2,int3,int4: integer; + reg: regionty; + +begin + with info,rowinfo do begin + calcautocellsize:= false; + if (info.rowinfo.cols.count > 0) and //fpc bug 4130 +// if (cols.count > 0) and + (rowrange.range1.endindex >= rowrange.range1.startindex) or + (rowrange.range2.endindex >= rowrange.range2.startindex) then begin +{ + po1:= canvas.origin; + po2.x:= po1.x; + paintrows(rowrange.range1); + paintrows(rowrange.range2); + canvas.origin:= po1; +} + reg:= canvas.copyclipregion; + canvas.subcliprect(makerect(0, + fgrid.fdatarect.y-tframe1(fgrid.fframe).fi.innerframe.top, + bigint{tframe1(fgrid.fframe).fpaintrect.cx)},fgrid.fdatarect.cy)); + if fix then begin + with fgrid.ffixcols do begin + int3:= fgrid.fdatarecty.cx - ftotsize+ffirstsize; + int4:= -1-ffirstopposite; + end; + end + else begin + with fgrid.fdatacols do begin + int3:= fgrid.fdatarecty.cx - + fgrid.ffixcols.ftotsize + fgrid.ffixcols.ffirstsize - + ftotsize + ffirstsize; + if colrange.scrollables then begin + int3:= int3 - fgrid.fscrollrect.x; + end; + int4:= ffirstopposite; + end; + end; + for int1:= 0 to cols.count - 1 do begin + with cols[int1] do begin + if (flinewidth > 0) and (colrange.scrollables xor + (co_nohscroll in foptions)) and + (not(co_invisible in foptions) or + (csdesigning in fgrid.componentstate)) then begin + int2:= fstart + flinepos + fcellrect.x; + if (index >= int4) or + (int2 < int3) then begin + //not overlapped by right side columns + linewidthbefore:= canvas.linewidth; + if flinewidth = 1 then begin + canvas.linewidth:= 0; + end + else begin + canvas.linewidth:= flinewidth; + end; + //todo: merged cells should be clipped + canvas.drawline(makepoint(int2,0), + makepoint(int2, + tframe1(fgrid.fframe).finnerclientrect.cy{ - 1}), + flinecolorfix); + canvas.linewidth:= linewidthbefore; + end; + end; + end; + end; + canvas.clipregion:= reg; + //todo: should be on top because of overwriting + //overlapping co_nohscroll grid lines + + po1:= canvas.origin; + po2.x:= po1.x; + paintrows(rowrange.range1); + paintrows(rowrange.range2); + canvas.origin:= po1; + end; + end; +end; + +procedure tfixrows.movecol(const curindex,newindex: integer; + const isfix: boolean); +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + tfixrow(fitems[int1]).movecol(curindex,newindex,isfix); + end; +end; + +procedure tfixrows.datacolscountchanged; +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + tfixrow(fitems[int1]).datacolscountchanged(count); + end; +end; + +procedure tfixrows.fixcolscountchanged; +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + tfixrow(fitems[int1]).fixcolscountchanged(count); + end; +end; + +procedure tfixrows.reorderdatacols(const neworder: integerarty); +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + tfixrow(fitems[int1]).reorderdatacols(neworder); + end; +end; + +procedure tfixrows.orderdatacols(const oldorder: integerarty); +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + tfixrow(fitems[int1]).orderdatacols(oldorder); + end; +end; + +procedure tfixrows.dofontheightdelta(var delta: integer); +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + with tfixrow(fitems[int1]) do begin + if ffont = nil then begin + height:= height + delta; + end; + end; + end; +end; + +procedure tfixrows.synctofontheight; +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + tfixrow(fitems[int1]).synctofontheight; + end; +end; + +function tfixrows.getclientsize: integer; +begin + result:= tgridframe(fgrid.fframe).finnerclientrect.cy; +end; + +{ tcustomgrid } + +constructor tcustomgrid.create(aowner: tcomponent); +begin + include(fstate,gs_updatelocked); + fmouseeventcol:= -1; + fmousecell:= invalidcell; + fwheelscrollheight:= defaultwheelscrollheight; + frowcountmax:= bigint; + frowcolors:= tcolorarrayprop.Create; + frowfonts:= trowfontarrayprop.Create(self); + ffocusedcell:= invalidcell; + fstartanchor:= invalidcell; + fendanchor:= invalidcell; + fmouseparkcell:= invalidcell; + factiverow:= invalidaxis; + flastcol:= invalidaxis; + + foptionsgrid:= defaultoptionsgrid; + fdatarowlinewidth:= defaultgridlinewidth; + fdatarowlinecolorfix:= defaultfixlinecolor; + fdatarowlinecolor:= defaultdatalinecolor; + + fdatarowheight:= griddefaultrowheight; + fdatarowheightmin:= 1; + fdatarowheightmax:= maxint; + + fgridframecolor:= cl_gridframe; + + fdatacols:= createdatacols; + ffixcols:= createfixcols; + ffixrows:= createfixrows; + + fdragcontroller:= tdragcontroller.create(idragcontroller(self)); + fzebra_color:= cl_zebra; + fzebra_step:= 2; + + inherited; + include(fwidgetstate1,ws1_designactive); + internalcreateframe; + fobjectpicker:= tobjectpicker.create(iobjectpicker(self)); +// fobjectpicker.options:= fobjectpicker.options + [opo_candoubleclick]; + foptionswidget:= defaultgridwidgetoptions; + foptionswidget1:= defaultgridwidgetoptions1; + exclude(fstate,gs_updatelocked); + internalupdatelayout; +end; + +destructor tcustomgrid.destroy; +begin + killrepeater; + inherited; + fdragcontroller.Free; + fobjectpicker.Free; + fdatacols.Free; + ffixcols.Free; + ffixrows.Free; + frowcolors.Free; + frowfonts.Free; +end; + +procedure tcustomgrid.initeventinfo(const cell: gridcoordty; + eventkind: celleventkindty; out info: celleventinfoty); +begin + fillchar(info,sizeof(info),0); + info.cell:= cell; + info.eventkind:= eventkind; +end; + +procedure tcustomgrid.invalidate; +begin + if fnoinvalidate = 0 then begin + finvalidatedcells:= nil; + end; + if caninvalidate then begin + inherited; + exclude(fstate,gs_invalidated); + end; +end; + +function tcustomgrid.caninvalidate: boolean; +begin + if fnoinvalidate = 0 then begin + result:= (fupdating = 0) and not (csloading in componentstate); + include(fstate,gs_invalidated); + end + else begin + result:= false; + end; +end; + +procedure tcustomgrid.layoutchanged; +begin + if fstate * [gs_layoutvalid,gs_layoutupdating] = [gs_layoutvalid] then begin + exclude(fstate,gs_layoutvalid); + invalidate; + end; +end; + +procedure tcustomgrid.rowdatachanged(const acell: gridcoordty; + const count: integer = 1); +begin + if not (csloading in componentstate) then begin + sortinvalid; + if acell.col >= 0 then begin + fdatacols[acell.col].checkdirtyautorowheight(acell.row); + end + else begin + if gs_needsrowheight in fstate then begin + fdatacols.rowstate.checkdirtyautorowheight(acell.row); + end; + end; + if fupdating = 0 then begin + exclude(fstate,gs_rowdatachanged); + inc(frowdatachanging); + try + dorowsdatachanged(acell,count); + finally + dec(frowdatachanging); + end; + end + else begin + include(fstate,gs_rowdatachanged); + if acell.row < frowdatachangestart then begin + frowdatachangestart:= acell.row; + end; + end; + end; +end; + +procedure tcustomgrid.rowdatachanged; +begin + if frowcount > 0 then begin + rowdatachanged(mgc(invalidaxis,0),frowcount); + end; +end; + +procedure tcustomgrid.setselected(const cell: gridcoordty; const avalue: boolean); +begin + //dummy +end; + +procedure tcustomgrid.internalselectionchanged; +begin + if fupdating = 0 then begin + exclude(fstate,gs_selectionchanged); + doselectionchanged; + end + else begin + include(fstate,gs_selectionchanged); + end; +end; + +procedure tcustomgrid.doselectionchanged; +begin + if assigned(fonselectionchanged) then begin + fonselectionchanged(self); + end; +end; + +function tcustomgrid.getscrollrect: rectty; +begin + internalupdatelayout; + result:= fscrollrect; +end; + +procedure tcustomgrid.setscrollrect(const rect: rectty); +var + po2,po3: pointty; + bo1: boolean; +begin + po2:= subpoint(rect.pos,fscrollrect.pos); + fscrollrect.size:= rect.size; + if (po2.x <> 0) or (po2.y <> 0) then begin + bo1:= fobjectpicker.removexorpic; + po3.x:= 0; + po3.y:= po2.y; + scrollrect(po3,fdatarecty,scrollcaret(true)); + fscrollrect.y:= rect.y; + updatevisiblerows; + scrolled(po3); + po3.x:= po2.x; + po3.y:= 0; + scrollrect(po3,fdatarectx,scrollcaret(false)); + fscrollrect.x:= rect.x; + scrolled(po3); + if bo1 then begin + update; + fobjectpicker.paintxorpic; + end; + end; +end; + +function tcustomgrid.calcminscrollsize: sizety; +begin + internalupdatelayout; + if not (gs_updatelocked in fstate) then begin + result.cx:= fdatacols.fscrollsize + fdatacols.ftotsize + + ffixcols.ftotsize + + tgridframe(fframe).fi.innerframe.left + + tgridframe(fframe).fi.innerframe.right; + if og_rowheight in foptionsgrid then begin + result.cy:= fdatacols.frowstate.rowypos[frowcount]; + end + else begin + result.cy:= (frowcount - fdatacols.frowstate.fhiddencount) * fystep; + end; + result.cy:= result.cy + ffixrows.ftotsize + + tgridframe(fframe).fi.innerframe.top + + tgridframe(fframe).fi.innerframe.bottom; + end + else begin + result:= nullsize; + end; +end; + +procedure tcustomgrid.calcpropcolwidthref; +var + int1,int3: integer; +begin + with tgridframe(fframe) do begin + fpropcolwidthref:= self.fwidgetrect.cx - + fouterframe.left - fouterframe.right - + 2*(fi.levelo+fi.framewidth+fi.leveli) - + finnerframe.left - finnerframe.right{ - + 2 * gridframewidth}; + end; + int3:= 0; + for int1:= 0 to fdatacols.count - 1 do begin + with fdatacols[int1] do begin + if not (co_invisible in options) then begin + if options * [co_proportional,co_fill] = [] then begin + fpropcolwidthref:= fpropcolwidthref - width; + end + else begin + if co1_autocolwidth in options1 then begin + fpropcolwidthref:= fpropcolwidthref - minmaxwidth; + int3:= int3 + minmaxwidth; + end + else begin + int3:= int3 + widthmin; + end; + end; + end; + end; + end; + for int1:= 0 to ffixcols.count - 1 do begin + with tfixcol(ffixcols.items[int1]) do begin + if not (fco_invisible in options) then begin + fpropcolwidthref:= fpropcolwidthref - width; + end; + end; + end; + if fpropcolwidthref < int3 then begin + fpropcolwidthref:= int3; + end; +end; + +procedure tcustomgrid.updatelayout; +var + scrollstate: framestatesty; + int1,int2,int3: integer; + loopcount{,firsthscrollindex}: integer; + bo1: boolean; + reshowfocusedcell: boolean; + propcolwidthrefchanged: boolean; + i1: int32; +begin + reshowfocusedcell:= false; + if focusedcellvalid then begin + bo1:= gs_updatelocked in fstate; + include(fstate,gs_updatelocked); + reshowfocusedcell:= not + rectisequal(clippedcellrect(ffocusedcell,cil_paint),nullrect); + if not bo1 then begin + exclude(fstate,gs_updatelocked); + end; + end; + bo1:= fobjectpicker.removexorpic; + exclude(fstate,gs_hasactiverowcolor); + exclude(fstate,gs_needszebraoffset); + if (zebra_step <> 0) then begin + include(fstate,gs_needszebraoffset); + end; + for int1:= 0 to ffixcols.count -1 do begin + with tfixcol(ffixcols.items[int1]) do begin + if numstep <> 0 then begin + include(self.fstate,gs_needszebraoffset); + end; + if (coloractive <> cl_none) or (colorfocused <> cl_none) or + (fontactivenum >= 0) or (fontfocusednum >= 0) then begin + include(self.fstate,gs_hasactiverowcolor); + end; + end; + end; + if not (gs_hasactiverowcolor in fstate) then begin + for int1:= 0 to fdatacols.count -1 do begin + with tdatacol(fdatacols.items[int1]) do begin + if ((fcoloractive <> cl_none) or (fontactivenum >= 0)) and + (co1_rowcoloractive in foptions1) or + ((fcolorfocused <> cl_none) or (fontfocusednum >= 0)) and + (co1_rowcolorfocused in foptions1) then begin + include(self.fstate,gs_hasactiverowcolor); + break; + end; + end; + end; + end; + loopcount:= 0; + repeat + i1:= fpropcolwidthref; + calcpropcolwidthref; + propcolwidthrefchanged:= fpropcolwidthref <> i1; + scrollstate:= frame.state; + fystep:= fdatarowheight + fdatarowlinewidth; + ffixcols.updatelayout; + ffixrows.updatelayout; +// { + fdatacols.ffirsthscrollindex:= fdatacols.count; + int3:= fixcols.ffirstsize; + for int1:= 0 to fdatacols.count - 1 do begin + with tdatacol(fdatacols.fitems[int1]) do begin + if not (co_nohscroll in foptions) then begin + fdatacols.ffirsthscrollindex:= int1; + break; + end; + fstart:= int3; + inc(int3,step(false)); + fend:= int3; + end; + end; + fdatacols.ffirstsize:= int3 - fixcols.ffirstsize; +// } + with tgridframe(fframe) do begin + checkstate; + with fdatarecty,ffixrows do begin +// finnerdatarect.y:= ffirstsize + fi.innerframe.top; +// finnerdatarect.cy:= finnerclientrect.cy - ftotsize; + x:= fi.innerframe.left; + cx:= finnerclientrect.cx; + y:= ffirstsize + fi.innerframe.top; + cy:= finnerclientrect.cy-ftotsize; + if cx < 0 then begin + cx:= 0; + end; + if cy < 0 then begin + cy:= 0; + end; + { + if finnerdatarect.cy < 0 then begin + finnerdatarect.cy:= 0; + end; + } + end; + with fdatarectx,ffixcols do begin + int2:= finnerclientrect.cx - ftotsize + ffirstsize; + int3:= int2; + fdatacols.foppositecount:= 0; + for int1:= fdatacols.count - 1 downto fdatacols.ffirsthscrollindex do begin + with fdatacols[int1] do begin + if not (co_nohscroll in foptions) then begin + fdatacols.foppositecount:= fdatacols.count-int1-1; + break; + end; + fend:= int3; + dec(int3,step(false)); + fstart:= int3; + end; + end; + fdatacols.ftotsize:= fdatacols.ffirstsize + int2 - int3; //width +// finnerdatarect.x:= ffirstsize + fi.innerframe.left + fdatacols.ffirstsize; +// finnerdatarect.cx:= finnerclientrect.cx - ftotsize - fdatacols.ftotsize; + y:= fi.innerframe.top; + cy:= finnerclientrect.cy; + x:= fi.innerframe.left + ffirstsize + fdatacols.ffirstsize; + { + x:= ffirstnohscroll; + if foppositecount = count then begin + inc(x,fi.innerframe.left); + end + else begin + if (ffirstsize > 0) then begin + x:= ffirstsize + fi.innerframe.left + ffirstnohscroll; + end; + end; + } + cx:= fpaintrect.cx - x - ftotsize + ffirstsize - + fdatacols.ftotsize + fdatacols.ffirstsize - + fi.innerframe.right; + { + cx:= fpaintrect.cx - x; + if (foppositecount > 0) and (ftotsize - ffirstsize > 0) then begin + cx:= cx - ftotsize + ffirstsize - fi.innerframe.right; + end + else begin + cx:= cx - fi.innerframe.right; + end; + } + if cx < 0 then begin + cx:= 0; + end; + if cy < 0 then begin + cy:= 0; + end; +// if finnerdatarect.cx < 0 then begin +// finnerdatarect.cx:= 0; +// end; + end; + with fdatarect do begin + x:= fdatarectx.x; + cx:= fdatarectx.cx; + y:= fdatarecty.y; + cy:= fdatarecty.cy; + end; + end; + fdatacols.updatelayout; + ffixrows.updatemergedcells; + updatevisiblerows; //scroll needs valid visiblerows + tgridframe(fframe).updatestate; + inc(loopcount); + until not propcolwidthrefchanged and + (frame.state * scrollbarframestates = + scrollstate * scrollbarframestates) or (loopcount > 40); + + if bo1 then begin + fobjectpicker.paintxorpic; + end; + if reshowfocusedcell and focusedcellvalid then begin + showcell(ffocusedcell); + end; +end; + +procedure tcustomgrid.dolayoutchanged; +begin + if canevent(tmethod(fonlayoutchanged)) then begin + fonlayoutchanged(self); + if not (gs_layoutvalid in fstate) and (flayoutupdating < 16) then begin + inc(flayoutupdating); + try + internalupdatelayout; + finally + dec(flayoutupdating); + end; + end; + end; +end; + +procedure tcustomgrid.internalupdatelayout(const force: boolean); +var + bo1: boolean; +begin + if (fstate * [gs_layoutvalid,gs_updatelocked] = []) and + not (csdestroying in componentstate) and + (force or (fupdating = 0)) then begin + bo1:= not (gs_layoutupdating in fstate); + if bo1 and canevent(tmethod(fonbeforeupdatelayout)) then begin + fonbeforeupdatelayout(self); + end; + try + fstate:= fstate + [gs_layoutvalid,gs_layoutupdating]; + updatelayout; + finally + if bo1 then begin + exclude(fstate,gs_layoutupdating); + dolayoutchanged; + end; + end; + end; +end; + +function tcustomgrid.intersectdatarect(var arect: rectty): boolean; +begin + internalupdatelayout; + result:= intersectrect(fdatarect,arect,arect); +end; + +procedure tcustomgrid.dopaintforeground(const acanvas: tcanvas); + +var + rect1: rectty; + arowinfo: rowspaintinfoty; + colinfo: colpaintinfoty; + lines: segmentarty; + int1,int2,int3,int4,int5: integer; + dataclip: rectty; + fixdataclip: rectty; + reg: regionty; + saveindex: integer; + linewidthbefore: integer; + rowheight1: boolean; + rowstate1: trowstatelist; + lineinfos: array of record + lcolor: colorty; + lcolorfix: colorty; + lwidth: integer; + end; + +begin + inherited; + lines:= nil; + lineinfos:= nil; + rowheight1:= og_rowheight in foptionsgrid; + rowstate1:= fdatacols.frowstate; + internalupdatelayout(true); + fnumoffset:= getnumoffset; + saveindex:= acanvas.save; + acanvas.move(pointty(tframe1(fframe).fi.innerframe.topleft)); + frootbrushorigin:= clientwidgetpos; + frootbrushorigin.x:= frootbrushorigin.x + fdatarect.x + rootpos.x; + frootbrushorigin.y:= frootbrushorigin.y + fdatarect.y + rootpos.y; + fbrushorigin.x:= frootbrushorigin.x; + fbrushorigin.y:= frootbrushorigin.y + fscrollrect.y; + rect1:= acanvas.clipbox; + if (rect1.cx > 0) or (rect1.cy > 0) then begin + fixdataclip:= mr(fdatarecty.x-tframe1(fframe).fi.innerframe.left,0, + fdatarecty.cx-ffixcols.ftotsize+ffixcols.ffirstsize,bigint); + if fixdataclip.cx < 0 then begin + fixdataclip.cx:= 0; + end; + with arowinfo do begin + ffixrows.getindexrange(rect1.y,rect1.cy,rowrange); + if (rowrange.range1.endindex >= rowrange.range1.endindex) or + (rowrange.range2.endindex >= rowrange.range2.endindex) then begin + ffixcols.getindexrange(rect1.x,rect1.cx,rowinfo.colrange); + with rowinfo do begin + canvas:= acanvas; + cols:= ffixcols; + fix:= true; + end; + ffixrows.paint(arowinfo); + rowinfo.cols:= fdatacols; + rowinfo.fix:= false; + fdatacols.getindexrange(rect1.x,rect1.cx,rowinfo.colrange,false); + acanvas.save; + acanvas.intersectcliprect(fixdataclip); + ffixrows.paint(arowinfo); + acanvas.intersectcliprect(makerect(fdatarect.x - + tframe1(fframe).fi.innerframe.left,0, + fdatarect.cx,tframe1(fframe).fpaintrect.cy)); + acanvas.move(makepoint(ffixcols.ffirstsize+fdatacols.ffirstsize+ + fscrollrect.x,0)); + rect1:= acanvas.clipbox; + if (rect1.cx > 0) and (rect1.cy > 0) then begin + fdatacols.getindexrange(rect1.x,rect1.cx,rowinfo.colrange); + fixrows.paint(arowinfo); + end; + acanvas.restore; + end; + end; + + rect1.x:= -tframe1(fframe).fi.innerframe.left; + rect1.y:= fdatarecty.y-tframe1(fframe).fi.innerframe.top; + rect1.cx:= tframe1(fframe).fpaintrect.cx; + rect1.cy:= fdatarecty.cy; + acanvas.intersectcliprect(rect1); + acanvas.move(makepoint(0,fscrollrect.y + ffixrows.ffirstsize)); + //move to clientorigin + rect1:= acanvas.clipbox; + if (rect1.cx > 0) and (rect1.cy > 0) then begin + if high(fvisiblerows) >= 0 then begin + with colinfo do begin + calcautocellsize:= false; + autocellsize:= nullsize; + ystep:= self.fystep; + if rowheight1 then begin + startrow:= -1; + for int1:= high(fvisiblerows) downto 0 do begin + with prowstaterowheightty(rowstate1.getitempo(fvisiblerows[int1]))^ do begin + if rect1.y >= rowheight.ypos then begin + startrow:= int1; + ystart:= rowheight.ypos; + break; + end; + end; + end; + if startrow < 0 then begin + startrow:= 0; + ystart:= prowstaterowheightty( + rowstate1.getitempo(fvisiblerows[0]))^.rowheight.ypos; + end; + endrow:= high(fvisiblerows); + int2:= rect1.y + rect1.cy; + for int1:= startrow to high(fvisiblerows) do begin + if prowstaterowheightty( + rowstate1.getitempo(fvisiblerows[int1]))^.rowheight.ypos >= + int2 then begin + endrow:= int1-1; + break; + end; + end; + end + else begin + startrow:= rect1.y div ystep - fvisiblerowsbase; + if startrow < 0 then begin + startrow:= 0; + end; + ystart:= (startrow + fvisiblerowsbase) * ystep; + endrow:= (rect1.y + rect1.cy - 1) div ystep - fvisiblerowsbase; + end; + rows:= fvisiblerows; + foldinfo:= fvisiblerowfoldinfo; + if endrow > high(fvisiblerows) then begin + endrow:= high(fvisiblerows); + end; + if endrow >= startrow then begin + canvas:= acanvas; + ffixcols.paint(colinfo); + dataclip:= makerect( + fdatarect.x-tframe1(fframe).fi.innerframe.left-fdatacols.ffirstsize, + -fscrollrect.y,fdatarecty.cx-ffixcols.ftotsize,fdatarect.cy); + if dataclip.cx < 0 then begin + dataclip.cx:= 0; + end; + + linewidthbefore:= acanvas.linewidth; + if (fdatarowlinewidth > 0) or rowheight1 then begin + acanvas.linewidth:= fdatarowlinewidth; + int1:= endrow-startrow+1; + setlength(lines,int1); + if rowheight1 then begin + setlength(lineinfos,int1); + int2:= ystart; + end + else begin + int2:= ystart - (fdatarowlinewidth + 1) div 2; + end; + int3:= tframe1(fframe).finnerclientrect.cx{ - 1}; + int5:= rowcolors.count; + int4:= 0; + for int1:= 0 to high(lines) do begin + if rowheight1 then begin + with rowstate1.getitemporowheight( + fvisiblerows[int1+startrow])^.rowheight, + lineinfos[int1] do begin + int4:= (linecolor and rowstatemask) - 1; + if (int4 < 0) or (int4 >= int5) then begin + lcolor:= fdatarowlinecolor; + end + else begin + lcolor:= rowcolors[int4]; + end; + int4:= (linecolorfix and rowstatemask) - 1; + if (int4 < 0) or (int4 >= int5) then begin + lcolorfix:= fdatarowlinecolorfix; + end + else begin + lcolorfix:= rowcolors[int4]; + end; + if linewidth = 0 then begin + lwidth:= fdatarowlinewidth; + end + else begin + lwidth:= linewidth-1; + end; + int4:= (lwidth + 1) div 2; + end; + inc(int2,rowstate1.internalystep(fvisiblerows[int1+startrow])); + end + else begin + inc(int2,ystep); + end; + with lines[int1] do begin + a.x:= 0; + a.y:= int2-int4; + b.x:= int3; + b.y:= int2-int4; + end; + end; + if ffixcols.count > 0 then begin //draw horz lines fixcols + reg:= acanvas.copyclipregion; + acanvas.subcliprect(dataclip); + if not acanvas.clipregionisempty then begin + if rowheight1 then begin + for int1:= 0 to high(lines) do begin + with lines[int1],lineinfos[int1] do begin + if lwidth > 0 then begin + acanvas.linewidth:= lwidth; + acanvas.drawline(a,b,lcolorfix); + end; + end; + end; + end + else begin + acanvas.drawlinesegments(lines,fdatarowlinecolorfix); + end; + end; + acanvas.clipregion:= reg; + end; + end; + + acanvas.intersectcliprect(fixdataclip); + fdatacols.paint(colinfo,false); //draw fix datacols + + acanvas.intersectcliprect(dataclip); + int1:= fscrollrect.x + fdatacols.fscrollsize + + fdatarect.x - tframe1(fframe).fi.innerframe.left; + int2:= fdatarect.x + fdatarect.cx - tframe1(fframe).fi.innerframe.left; + if int1 < int2 then begin + acanvas.subcliprect(mr(int1,dataclip.y,int2-int1,dataclip.cy)); + end; + if not acanvas.clipregionisempty then begin //draw horz lines datacols + int2:= fdatarecty.cx - ffixcols.ftotsize + ffixcols.ffirstsize; + if int2 < fdatarect.x then begin + int2:= fdatarect.x; + end; + int3:= ffixcols.ffirstsize; + if int2 > paintrect.cx then begin + int2:= paintrect.cx; + end; + if int3 < 0 then begin + int3:= 0; + end; + if length(lines) > 0 then begin //draw horz lines datacols + for int1:= 0 to high(lines) do begin + with lines[int1] do begin + a.x:= int3; + b.x:= int2; +//b.y:= b.y -3; + end; + end; + if rowheight1 then begin + for int1:= 0 to high(lines) do begin + with lines[int1],lineinfos[int1] do begin + if lwidth > 0 then begin + acanvas.linewidth:= lwidth; + acanvas.drawline(a,b,lcolor); + end; + end; + end; + end + else begin + acanvas.drawlinesegments(lines,fdatarowlinecolor); + end; + end; + if fdatacols.fscrollsize > 0 then begin + acanvas.intersectcliprect( + mr(fdatacols.ffirstsize+ffixcols.ffirstsize,-fscrollrect.y, + fdatarect.cx,fscrollrect.size.cy)); + end; + acanvas.move(mp(fdatacols.ffirstsize+ffixcols.ffirstsize+ + fscrollrect.x,0)); + acanvas.linewidth:= linewidthbefore; + fdatacols.paint(colinfo,true); //draw normal cols + end; + acanvas.linewidth:= linewidthbefore; + end; //endrow >= startrow + end; //with colinfo + end; //fvisiblerows <> nil + end; //rect1 not empty + end; //if cliprect not empty + + acanvas.restore(saveindex); + with tgridframe(fframe).fi do begin + acanvas.drawframe(clientrect,innerframe,fgridframecolor); + end; +end; + +procedure tcustomgrid.setstatfile(const Value: tstatfile); +begin + setstatfilevar(istatfile(self),value,fstatfile); +end; + +procedure tcustomgrid.setframe(const avalue: tgridframe); +begin + inherited setframe(avalue); +end; + +function tcustomgrid.getframe: tgridframe; +begin + result:= tgridframe(inherited getframe); +end; + +procedure tcustomgrid.dostatread(const reader: tstatreader); +var + po1: gridcoordty; +begin + beginupdate; + try + if reader.canstate then begin + fpropcolwidthref:= reader.readinteger('propcolwidthref',fpropcolwidthref,0); + end; + fdatacols.dostatread(reader,foptionsgrid * [og_savestate,og_colmoving] = + [og_savestate,og_colmoving]); + if (og_savestate in foptionsgrid) and reader.canstate then begin + sorted:= reader.readboolean('sorted',sorted); + po1.col:= reader.readinteger('col',ffocusedcell.col); + if not (gs_isdb in fstate) then begin + po1.row:= reader.readinteger('row',ffocusedcell.row); + end + else begin + po1.row:= ffocusedcell.row; + end; + if og_rowsizing in foptionsgrid then begin + datarowheight:= reader.readinteger('rowheight',datarowheight); + end; + if ((po1.col < 0) or (po1.col < fdatacols.count)) and + ((po1.row < 0) or (po1.row < frowcount)) then begin + focuscell(po1); + end; + end; + finally + endupdate; + end; +end; + +procedure tcustomgrid.dostatwrite(const writer: tstatwriter); +var + int1: integer; +begin + int1:= row; + if not (og_nosaveremoveappendedrow in foptionsgrid) then begin + removeappendedrow; //calls docheckcellvalue + end + else begin + docheckcellvalue; + end; + if writer.canstate then begin + writer.writeinteger('propcolwidthref',fpropcolwidthref); + end; + fdatacols.dostatwrite(writer,foptionsgrid * [og_savestate,og_colmoving] = + [og_savestate,og_colmoving]); + row:= int1; + if (og_savestate in foptionsgrid) and writer.canstate then begin + writer.writeboolean('sorted',hassort); + writer.writeinteger('col',ffocusedcell.col); + if not (gs_isdb in fstate) then begin + writer.writeinteger('row',ffocusedcell.row); + end; + writer.writeinteger('rowheight',datarowheight); + end; +end; + +procedure tcustomgrid.statreading; +begin + //dummy +end; + +procedure tcustomgrid.statread; +begin + //dummy +end; + +function tcustomgrid.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +function tcustomgrid.rowhigh: integer; +begin + result:= frowcount - 1; +end; + +function tcustomgrid.datarowhigh: integer; //without auto appended empty row +begin + result:= frowcount - 1; + if isautoappend then begin + dec(result); + end; +end; + +procedure tcustomgrid.setrowcount(Value: integer); +var + int1: integer; + bo1,bo2: boolean; +begin + if frowcount <> value then begin + beginupdate; + try + if factiverow >= value then begin + factiverow:= invalidaxis; + end; + if ffocusedcell.row >= value then begin + int1:= frowcount; + exclude(fstate,gs_emptyrowremoved); + include(fstate,gs_rowremoving); + try + defocusrow; + finally + exclude(fstate,gs_rowremoving); + end; + if (gs_emptyrowremoved in fstate) then begin + dec(int1); + end; + if (frowcount <> int1) then begin + exit; + end; + bo2:= frowcount = value; + bo1:= true; + end + else begin + bo1:= false; + bo2:= false; + end; + int1:= frowcount; + if value > frowcountmax then begin + frowcount:= frowcountmax; + if ffocusedcell.row >= 0 then begin + dec(ffocusedcell.row,value-frowcount); + if ffocusedcell.row < 0 then begin + ffocusedcell.row:= invalidaxis; + fstate:= fstate - [gs_cellentered]; + end; + factiverow:= ffocusedcell.row; + end; + end + else begin + frowcount := Value; + end; + if not bo2 then begin + dorowcountchanged(int1,value); + end; + layoutchanged; + if not (gs_isdb in fstate) and entered and + (bo1 and ((og_autoappend in foptionsgrid) and (frowcount <> 0) or + (frowcount = 0) and (og_autofirstrow in foptionsgrid))) then begin + row:= frowcount; + end; + finally + endupdate; + end; + end; +end; + +procedure tcustomgrid.setrowcountmax(const Value: integer); +begin + if (value < frowcount) {and (value <> 0)} then begin + rowcount:= value; + end; + if value <> frowcountmax then begin + fdatacols.setrowcountmax(value); + frowcountmax := Value; + end; +end; + +procedure tcustomgrid.setdatarowlinewidth(const Value: integer); +begin + if fdatarowlinewidth <> value then begin + if value < 0 then begin + fdatarowlinewidth:= 0; + end + else begin + fdatarowlinewidth := Value; + end; + rowstatelist.change(-1); + layoutchanged; + end; +end; + +procedure tcustomgrid.setdatarowlinecolor(const Value: colorty); +begin + if fdatarowlinecolor <> value then begin + fdatarowlinecolor := Value; + invalidate; + end; +end; + +procedure tcustomgrid.setdatarowlinecolorfix(const Value: colorty); +begin + if fdatarowlinecolorfix <> value then begin + fdatarowlinecolorfix:= Value; + invalidate; + end; +end; + +function tcustomgrid.wheelheight: integer; +begin + if fwheelscrollheight <= 0 then begin + result:= application.mousewheelacceleration(1); + end + else begin + result:= rowsperpage - 1; + if fwheelscrollheight < result then begin + result:= fwheelscrollheight; + end; + end; +end; + +procedure tcustomgrid.scrollevent(sender: tcustomscrollbar; event: scrolleventty); +begin + if sender.tag = 1 then begin + case event of + sbe_stepup: scrollrows(-1); + sbe_stepdown: scrollrows(1); + sbe_pageup: scrollrows(-(rowsperpage-1)); + sbe_pagedown: scrollrows(rowsperpage-1); + sbe_wheelup: scrollrows(-wheelheight); + sbe_wheeldown: scrollrows(wheelheight); + end; + end + else begin + case event of + sbe_stepup: scrollleft; + sbe_stepdown: scrollright; + sbe_pageup,sbe_wheelup: scrollpageleft; + sbe_pagedown,sbe_wheeldown: scrollpageright; + end; + end; +end; + +function tcustomgrid.caninsertrow: boolean; +begin + result:= not fnorowedit; +end; + +function tcustomgrid.canappendrow: boolean; +begin + result:= not fnorowedit; +end; + +function tcustomgrid.candeleterow: boolean; +begin + result:= not fnorowedit; +end; + +function tcustomgrid.canmoverow: boolean; +begin + result:= not fnorowedit; +end; + +procedure tcustomgrid.updatepopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); + + function menustates(const aenabled: boolean): actionstatesarty; + begin + if aenabled then begin + result:= nil; + end + else begin + setlength(result,1); + result[0]:= [as_disabled] + end; + end; //menustates + +var + bo1: boolean; + state1: actionstatesty; + sepchar: msechar; +begin + if (og_autopopup in foptionsgrid) then begin + if popupmenu <> nil then begin + sepchar:= popupmenu.shortcutseparator; + end + else begin + sepchar:= tcustommenu.getshortcutseparator(amenu); + end; + bo1:= false; + if fdatacols.cancopy or canevent(tmethod(foncopyselection)) then begin + if fdatacols.hasselection then begin + state1:= []; + end + else begin + state1:= [as_disabled]; + end; + tpopupmenu.additems(amenu,self,mouseinfo,[ + stockobjects.captions[sc_copy_cells]+sepchar+ + '('+encodeshortcutname(sysshortcuts[sho_copycells])+')'], + [],[state1],[{$ifdef FPC}@{$endif}docopycells],not bo1); + bo1:= true; + end; + if fdatacols.canpaste or canevent(tmethod(fonpasteselection)) then begin + if fdatacols.readonly then begin + state1:= [as_disabled]; + end + else begin + state1:= []; + end; + tpopupmenu.additems(amenu,self,mouseinfo,[ + stockobjects.captions[sc_paste_cells]+sepchar+ + '('+encodeshortcutname(sysshortcuts[sho_pastecells])+')'], + [],[state1],[{$ifdef FPC}@{$endif}dopastecells],not bo1); + bo1:= true; + end; + + if og_rowinserting in foptionsgrid then begin + tpopupmenu.additems(amenu,self,mouseinfo,[ + stockobjects.captions[sc_insert_rowhk]+sepchar+ + '('+encodeshortcutname(sysshortcuts[sho_rowinsert])+')'],[], + menustates(caninsertrow), + [{$ifdef FPC}@{$endif}doinsertrow],not bo1); + bo1:= true; + tpopupmenu.additems(amenu,self,mouseinfo,[ + stockobjects.captions[sc_append_rowhk]+sepchar+ + '('+encodeshortcutname(sysshortcuts[sho_rowappend])+')'],[], + menustates(canappendrow),[{$ifdef FPC}@{$endif}doappendrow],not bo1); + bo1:= true; + end; + if og_rowdeleting in foptionsgrid then begin + if (ffocusedcell.row >= 0) and candeleterow then begin + state1:= []; + end + else begin + state1:= [as_disabled]; + end; + tpopupmenu.additems(amenu,self,mouseinfo,[ + stockobjects.captions[sc_delete_rowhk]+sepchar+ + '('+encodeshortcutname(sysshortcuts[sho_rowdelete])+')'], + [[mao_nocandefocus]],[state1],[{$ifdef FPC}@{$endif}dodeleterows],not bo1); + bo1:= true; + end; + end; + inherited; +end; + +procedure tcustomgrid.setdatacols(const Value: tdatacols); +begin + fdatacols.assign(Value); +end; + +procedure tcustomgrid.setfixcols(const Value: tfixcols); +begin + ffixcols.assign(Value); +end; + +procedure tcustomgrid.setfixrows(const Value: tfixrows); +begin + ffixrows.assign(Value); +end; + +procedure tcustomgrid.setcol(const value: integer); +begin + focuscell(makegridcoord(value,ffocusedcell.row)); +end; + +procedure tcustomgrid.setrow(const value: integer); +begin + focuscell(makegridcoord(ffocusedcell.col,value)); +end; + +function tcustomgrid.visiblerow(const arow: integer): integer; + //returns index in visible rows, invalidaxis if not visible +begin + if not (csdesigning in componentstate) then begin + result:= fdatacols.frowstate.visiblerow(arow); + end + else begin + result:= arow; + if (arow < 0) or (arow >= frowcount) then begin + result:= invalidaxis; + end; + end; +end; + +function tcustomgrid.createdatacols: tdatacols; +begin +{$warnings off} + result:= tdatacols.create(self,tdatacol); +{$warnings on} +end; + +function tcustomgrid.createfixcols: tfixcols; +begin + result:= tfixcols.create(self); +end; + +function tcustomgrid.createfixrows: tfixrows; +begin + result:= tfixrows.create(self); +end; + +procedure tcustomgrid.initcellinfo(var info: cellinfoty); +begin + //dummy +end; + +function tcustomgrid.ystep: integer; +begin + internalupdatelayout; + result:= fystep; +end; + +procedure tcustomgrid.setdatarowheight(const value: integer); +begin + if fdatarowheight <> value then begin + if value < fdatarowheightmin then begin + fdatarowheight:= fdatarowheightmin; + end + else begin + if value > fdatarowheightmax then begin + fdatarowheight:= fdatarowheightmax; + end + else begin + fdatarowheight:= value; + end; + end; + rowstatelist.change(-1); + layoutchanged; + end; +end; + +procedure tcustomgrid.internalcreateframe; +begin + tgridframe.create(iscrollframe(self),self,iautoscrollframe(self)); +end; + +procedure tcustomgrid.dorowcountchanged(const countbefore,newcount: integer); +begin + if (fclickedcell.row >= 0) and (newcount <= fclickedcell.row) then begin + exclude(fstate,gs_cellclicked); + end; + layoutchanged; + ffixcols.rowcountchanged(countbefore,newcount); + fdatacols.rowcountchanged(countbefore,newcount); + if canevent(tmethod(fonrowcountchanged)) then begin + fonrowcountchanged(self); + end; +end; + +procedure tcustomgrid.dorowsdatachanged(const acell: gridcoordty; + const acount: integer); +var + int1: integer; + coord1: gridcoordty; +begin + if canevent(tmethod(fonrowsdatachanged)) then begin + fonrowsdatachanged(self,acell,acount); + end; + if canevent(tmethod(fonrowdatachanged)) then begin + coord1.col:= acell.col; + for int1:= acell.row to acell.row + acount-1 do begin + coord1.row:= int1; + fonrowdatachanged(self,coord1); + end; + end; +end; + +procedure tcustomgrid.invalidatecell(const cell: gridcoordty); +begin + internalupdatelayout; + if (cell.row < 0) or + (cell.row >= ffirstvisiblerow) and + (cell.row <= flastvisiblerow) then begin + invalidaterect(cellrect(cell)); + end; +end; + +procedure tcustomgrid.invalidatesinglecell(const cell: gridcoordty); +begin + if (cell.row <> invalidaxis) and (cell.col <> invalidaxis) then begin + invalidatecell(cell); + end; +end; + +procedure tcustomgrid.invalidaterow(const arow: integer); +begin + invalidatecell(makegridcoord(invalidaxis,arow)); +end; + +procedure tcustomgrid.invalidatefocusedcell; +begin + if (ffocusedcell.row >= 0) and (ffocusedcell.col >= 0) then begin + invalidatecell(ffocusedcell); + end; +end; + +procedure tcustomgrid.cellchanged(const sender: tcol; const row: integer); +var + bo1: boolean; +begin + bo1:= (ffocusedcell.row >= 0) and (sender.colindex = ffocusedcell.col) and + ((row < 0) or (row = ffocusedcell.row)); + if fupdating = 0 then begin + if row >= 0 then begin + invalidatecell(makegridcoord(sender.colindex,row)); + end + else begin + colchanged(sender); + end; + if bo1 then begin + focusedcellchanged; + end; + end + else begin + if bo1 then begin + include(fstate,gs_focusedcellchanged); + end; + if fnoinvalidate = 0 then begin + if fstate * [gs_invalidated,gs_layoutvalid] = [gs_layoutvalid] then begin + if high(finvalidatedcells) > 20 then begin + include(fstate,gs_invalidated); + finvalidatedcells:= nil; + end + else begin + incrementarraylength(pointer(finvalidatedcells),typeinfo(gridcoordarty)); + finvalidatedcells[high(finvalidatedcells)]:= + makegridcoord(sender.colindex,row); + end; + end; + end; + end; +end; + +procedure tcustomgrid.focusedcellchanged; +begin + exclude(fstate,gs_focusedcellchanged); +end; + +procedure tcustomgrid.colchanged(const sender: tcol); +var + rect1: rectty; +begin + if not (csloading in componentstate) then begin + internalupdatelayout; + rect1:= cellrect(makegridcoord(sender.colindex,0)); + rect1.y:= 0; + rect1.cy:= tgridframe(fframe).fpaintrect.cy; + invalidaterect(rect1); + end; +end; + +procedure tcustomgrid.rowchanged(const arow: integer); +var + rect1: rectty; +begin + if fnoinvalidate = 0 then begin + internalupdatelayout; + rect1:= cellrect(makegridcoord(0,arow)); + rect1.x:= 0; + rect1.cx:= tgridframe(fframe).fpaintrect.cx; + invalidaterect(rect1); + end; +end; + +procedure tcustomgrid.rowstatechanged(const arow: integer); +begin + //dummy +end; + +function tcustomgrid.cellatpos(const apos: pointty; + out coord: gridcoordty): cellkindty; +var + po1: pointty; +begin + result:= ck_invalid; + coord:= invalidcell; + internalupdatelayout; + with tgridframe(fframe) do begin + if not pointinrect(apos,clientrect) then begin + exit; + end; + end; + po1.x:= apos.x - tgridframe(fframe).fi.innerframe.left; + po1.y:= apos.y - tgridframe(fframe).fi.innerframe.top; + + with po1,coord do begin + row:= ffixrows.rowatpos(y); + if row < 0 then begin + col:= ffixcols.colatpos(x); + if col = 0 then begin + col:= fdatacols.colatpos(x,false); + if col < 0 then begin + dec(x,fscrollrect.x+ffixcols.ffirstsize+fdatacols.ffirstsize); + col:= fdatacols.colatpos(x,true); + end; + if col >= 0 then begin + result:= ck_fixrow; + end; + end + else begin + result:= ck_fixcolrow; + end; + end + else begin //datarows + dec(y,fscrollrect.y+ffixrows.ffirstsize); + row:= rowatpos(y); + col:= ffixcols.colatpos(x); + if col = 0 then begin + col:= fdatacols.colatpos(x,false); + if col < 0 then begin + dec(x,fscrollrect.x+ffixcols.ffirstsize+fdatacols.ffirstsize); + col:= fdatacols.colatpos(x,true); + end; + if (col >= 0) and (row >= 0) then begin + result:= ck_data; + end; + end + else begin + if row >= 0 then begin + result:= ck_fixcol; + end; + end; + end; + end; +end; + +function tcustomgrid.cellatpos(const apos: pointty): gridcoordty; +begin + cellatpos(apos,result); +end; + +function tcustomgrid.rowatpos(y: integer): integer; +//var +// int1: integer; +begin + result:= invalidaxis; + if y >= 0 then begin + if og_rowheight in foptionsgrid then begin + result:= fdatacols.frowstate.rowindex(y); + end + else begin + result:= fdatacols.frowstate.visiblerowtoindex(y div fystep); + end; + end; +end; + +function tcustomgrid.rowpos(arow: integer): integer; +begin + result:= 0; + if arow < 0 then begin + arow:= 0; + end; + if arow >= frowcount then begin + arow:= frowcount-1; + end; + if arow > 0 then begin + if og_rowheight in foptionsgrid then begin + result:= fdatacols.frowstate.rowypos[arow]; + end + else begin + result:= fdatacols.frowstate.visiblerow(arow) * fystep; + end; + end; +end; + +procedure tcustomgrid.firstcellclick(const cell: gridcoordty; + var info: mouseeventinfoty); +begin + //dummy +end; + +function tcustomgrid.getzebrastart: integer; +begin + result:= fzebra_start; +end; + +function tcustomgrid.getnumoffset: integer; +begin + result:= 0; +end; + +procedure tcustomgrid.mouseevent(var info: mouseeventinfoty); +begin + tgridframe(fframe).mouseevent(info); + inherited; +end; + +function tcustomgrid.actualcursor(const apos: pointty): cursorshapety; +var + prop1: tgridprop; +begin + prop1:= gridprop(fmousecell); + if prop1 <> nil then begin + result:= prop1.cursor; + if result <> cr_default then begin + exit; + end; + end; + + with fmousecell do begin + if (row >= 0) and (col >= 0) and (col < datacols.count) then begin + result:= datacols[fmousecell.col].getcursor(fmousecell.row,flastcellzone, + subpoint(apos,flastcellpos)); + end + else begin + result:= inherited actualcursor(apos); + end; + end; +end; + +procedure tcustomgrid.clientmouseevent(var info: mouseeventinfoty); + + procedure mouseleavecol; + var + info1: mouseeventinfoty; + begin + if fmouseeventcol >= 0 then begin + if fmouseeventcol < fdatacols.count then begin + fillchar(info1,sizeof(info1),0); + info1.eventkind:= ek_clientmouseleave; + fdatacols[fmouseeventcol].clientmouseevent(makegridcoord(fmouseeventcol,-1), + info1); + fmouseeventcol:= -1; + end; + end; + end; + +var + cellkind: cellkindty; + + procedure checkfocuscell; + + function getfocusact(const canselect: boolean): focuscellactionty; + begin + result:= fca_focusin; + if canselect then begin + if info.shiftstate * keyshiftstatesmask = [ss_shift] then begin + result:= fca_selectend; + end + else begin + if info.eventkind = ek_buttonpress then begin + result:= fca_reverse; + end; + end; + end; + end; + + var + po1: pointty; + action: focuscellactionty; + bo1,bo2: boolean; + cell1: gridcoordty; + rowfocus: boolean; + pos1: cellpositionty; + begin //checkfocuscell + po1:= fscrollrect.pos; + action:= fca_focusin; + case cellkind of + ck_data: begin + if not (gs_mousecellredirected in fstate) then begin + cell1:= fmousecell; + cell1.col:= mergestart(cell1.col,cell1.row); + bo2:= fdatacols[cell1.col].canfocus(info.button,info.shiftstate,false, + rowfocus); + if not bo2 then begin + if rowfocus then begin + cell1.col:= mergestart(ffocusedcell.col,cell1.row); + //try to focus mouse row + if (cell1.col < 0) or + (co_nofocus in fdatacols[cell1.col].options) then begin + cell1.col:= nextfocusablecol(0,false,cell1.row,false); + end; + end + else begin + cell1.col:= invalidaxis; + end; + end; + if (cell1.col >= 0) and + fdatacols[cell1.col].canfocus(info.button, + info.shiftstate,false,bo1) then begin + bo1:= not gridcoordisequal(cell1,ffocusedcell); + if (info.shiftstate * [ss_left,ss_middle,ss_right] = [ss_left]) and + (co_mouseselect in fdatacols[cell1.col].foptions) then begin + if (info.shiftstate * keyshiftstatesmask = [ss_shift]) then begin + action:= fca_selectend; + end + else begin + if info.shiftstate * keyshiftstatesmask = [ss_ctrl] then begin + if (info.button = mb_left) or (cell1.col <> ffocusedcell.col) or + (cell1.row <> ffocusedcell.row) then begin + action:= fca_reverse; + end; + end; + end; + end + else begin + if (action = fca_focusin) and (ss_shift in info.shiftstate) then begin + action:= fca_focusinshift; + end; + end; + pos1:= cep_nearest; + if not bo2 then begin + pos1:= cep_none; + end; + focuscell(cell1,action,scm_cell,pos1); + if not bo2 then begin + showcell(fmousecell); + end + else begin + if bo1 then begin + firstcellclick(cell1,info); + end; + end; + end + else begin + if (fmousecell.row >= 0) and rowfocus then begin + focuscell(makegridcoord(invalidaxis,fmousecell.row)); + end + else begin + showcell(fmousecell); + end; + end; + end; + end; + ck_fixcol: begin + with fixcols[fmousecell.col] do begin + if (fco_mousefocus in options) then begin + if (fmousecell.row <> ffocusedcell.row) or + (info.eventkind = ek_buttonpress) then begin + focusrow(fmousecell.row,getfocusact(fco_mouseselect in options), + true,scm_row); + end; + end + else begin + if (info.eventkind = ek_buttonpress) and + (fco_mouseselect in fixcols[fmousecell.col].options) then begin + fdatacols.selected[fmousecell]:= not fdatacols.selected[fmousecell]; + end; + showcell(fmousecell); + end; + end; + end; + ck_fixrow: begin + with fixrows[fmousecell.row] do begin + if (fro_mousefocus in options) then begin + if (fmousecell.col <> ffocusedcell.col) or + (info.eventkind = ek_buttonpress) then begin + focuscell(makegridcoord(fmousecell.col,row), + getfocusact(fro_mouseselect in options),scm_col); + end; + end + else begin + if (info.eventkind = ek_buttonpress) and + (fro_mouseselect in fixrows[fmousecell.row].options) then begin + fdatacols.selected[fmousecell]:= not fdatacols.selected[fmousecell]; + end; + showcell(fmousecell); + end; + end; + end; + ck_fixcolrow: begin + if (info.eventkind = ek_buttonpress) and + (fro_mouseselect in fixrows[fmousecell.row].options) and + (fco_mouseselect in fixcols[fmousecell.col].options) then begin + fdatacols.selected[fmousecell]:= not fdatacols.selected[fmousecell]; + end; + end; + end; + addpoint1(info.pos,subpoint(tgridframe(fframe).scrollpos,po1)); + //shift mouse with grid; + end; + + procedure checkrepeater(const drag: boolean); + var + bo1: boolean; + begin + with info do begin + if gs_cellclicked in fstate then begin + if drag then begin + frepeataction:= fca_none; + end + else begin + if ss_shift in shiftstate then begin + if co_mouseselect in fdatacols[ffocusedcell.col].foptions then begin + frepeataction:= fca_selectend; + end + else begin + frepeataction:= fca_focusinshift; + end; + end + else begin + frepeataction:= fca_focusinrepeater; + end; + end; + if pos.y < fdatarect.y - mousescrolldist then begin + if (ffocusedcell.col >= 0) and + (co_mousescrollrow in datacols[ffocusedcell.col].options) then begin + startrepeater(gs_scrolldown,fastrepeat); + end; + end + else begin + if pos.y - mousescrolldist >= fdatarect.y + fdatarect.cy then begin + if (ffocusedcell.col >= 0) and + (co_mousescrollrow in datacols[ffocusedcell.col].options) then begin + startrepeater(gs_scrollup,fastrepeat); + end; + end + else begin + bo1:= not ((focusedcell.col >= 0) and + (co_nohscroll in + tcol(fdatacols.fitems[ffocusedcell.col]).options)); + if bo1 and (pos.x < fdatarect.x - mousescrolldist) then begin + if og_mousescrollcol in foptionsgrid then begin + startrepeater(gs_scrollleft,slowrepeat); + end; + end + else begin + if bo1 and (pos.x - mousescrolldist >= + fdatarect.x + fdatarect.cx) then begin + if og_mousescrollcol in foptionsgrid then begin + startrepeater(gs_scrollright,slowrepeat); + end; + end + else begin + killrepeater; + end; + end; + end; + end; + end; + end; + end; + +var + coord1: gridcoordty; + str1: msestring; + hintinfo: hintinfoty; + mousewidgetbefore: twidget; + bo1: boolean; + +begin + inherited; + bo1:= es_processed in info.eventstate; + if not bo1 then begin + fobjectpicker.mouseevent(info); + if (info.eventkind = ek_buttonpress) and + not(csdesigning in componentstate) and + (fobjectpicker.currentobjects <> nil) and + (pickobjectkindty(fobjectpicker.currentobjects[0] mod pickobjectstep) in + [pok_datacol,pok_datarow]) then begin + exclude(info.eventstate,es_processed); //allow mouse row selecting + end; + if not (es_processed in info.eventstate) then begin + fdragcontroller.clientmouseevent(info); + end; + end; + if not(csdesigning in componentstate) then begin + if es_processed in info.eventstate then begin + if info.eventkind in [ek_mousemove,ek_mousepark] then begin + checkrepeater(true); + end; + if not bo1 and isvalidcell(fmousecell) then begin + cellmouseevent(fmousecell,info); + end; + end + else begin + with info do begin + if eventkind = ek_buttonpress then begin + checkreautoappend; + end; + if eventkind in mouseposevents then begin + coord1:= fmousecell; + cellkind:= cellatpos(pos,fmousecell); + if (coord1.col <> fmousecell.col) or + (coord1.row <> fmousecell.row) then begin + if isvalidcell(coord1) then begin + cellmouseevent(coord1,info,nil,cek_mouseleave); + end; + if (fmousecell.row <> invalidaxis) and + (fmousecell.col <> invalidaxis) then begin + cellmouseevent(fmousecell,info,nil,cek_mouseenter); + end; + end; + if (fmousecell.row <> fmouseparkcell.row) or + (fmousecell.col <> fmouseparkcell.col) then begin + fmouseparkcell:= invalidcell; + end; + end + else begin + cellkind:= ck_invalid; + end; + case eventkind of + ek_clientmouseenter: begin + include(fstate,gs_mouseentered); + end; + ek_clientmouseleave: begin + if isvalidcell(fmousecell) then begin + cellmouseevent(fmousecell,info,nil,cek_mouseleave); + end; + fmousecell:= invalidcell; + fmouseparkcell:= invalidcell; + end; + ek_buttonpress: begin + mousewidgetbefore:= application.mousewidget; + checkfocuscell; + if (mousewidgetbefore = application.mousewidget) and + //not interrupted by beginmodal + (button = mb_left) then begin + fclickedcellbefore:= fclickedcell; + fclickedcell:= fmousecell; + if isdatacell(fmousecell) then begin + include(fstate,gs_cellclicked); + end; + end; + end; + ek_mousemove,ek_mousepark: begin + if not (es_child in info.eventstate) then begin + if cellkind = ck_data then begin + application.widgetcursorshape:= + datacols[fmousecell.col].getcursor(fmousecell.row, + flastcellzone,subpoint(info.pos,flastcellpos)); + end + else begin + application.widgetcursorshape:= cr_default; + if (eventkind = ek_mousepark) and + (cellkind in [ck_fixrow,ck_fixcolrow]) and + ((fmousecell.row <> fmouseparkcell.row) or + (fmousecell.col <> fmouseparkcell.col)) then begin + fmouseparkcell:= fmousecell; + str1:= ''; + with ffixrows[fmouseparkcell.row] do begin + if fmouseparkcell.col >= 0 then begin + if fmouseparkcell.col < fcaptions.count then begin + with fcaptions[fmouseparkcell.col] do begin + str1:= hint; + if (str1 = '') and (dco_hintclippedtext in options) and + finfo.captionclipped then begin + str1:= caption; + end; + end; + end; + end + else begin + if -fmouseparkcell.row <= fcaptionsfix.count then begin + with fcaptionsfix[fmouseparkcell.col] do begin + str1:= hint; + end; + end; + end; + end; + if (str1 <> '') and application.active then begin + application.inithintinfo(hintinfo,self); + hintinfo.caption:= str1; + application.showhint(self,hintinfo); + end; + end; + end; + if (info.shiftstate * [ss_left,ss_middle,ss_right] = [ss_left]) and + (ws_lclicked in fwidgetstate) then begin + checkfocuscell; + end + else begin + if (shiftstate = []) and (cellkind = ck_data) and + (co_mousemovefocus in fdatacols[fmousecell.col].foptions) and + not (aso_nogridmousemove in assistiveoptions) then begin + if gs_mouseentered in fstate then begin + exclude(fstate,gs_mouseentered); + fmouserefpos:= info.pos; + end; + if (distance(fmouserefpos,info.pos) > 3) and active then begin + fmouserefpos:= info.pos; + if not fdatacols[fmousecell.col].canfocus( + info.button,info.shiftstate,false,bo1) then begin + showcell(fmousecell); + end + else begin + focuscell(fmousecell); + end; + end; + end; + end; + end; + checkrepeater(false); + end; + end; + if cellkind = ck_data then begin + if fmousecell.col <> fmouseeventcol then begin + mouseleavecol; + end; + fmouseeventcol:= fmousecell.col; + if not (es_processed in info.eventstate) and + (fmousecell.col >= 0) then begin //ek_clientmouseleave otherwise + coord1:= ffocusedcell; + fdatacols[fmousecell.col].clientmouseevent(fmousecell,info); + if not gridcoordisequal(ffocusedcell,coord1) then begin + include(fstate,gs_mousecellredirected); + end; + end; + end + else begin + mouseleavecol; + if not (es_processed in info.eventstate) then begin + cellmouseevent(fmousecell,info); + end; + end; + end; + end; + end; + if (info.eventkind = ek_buttonrelease) or + (info.eventkind = ek_mousecaptureend) and + not (gs1_mousecaptureendlock in fstate1) then begin + if gs_cellclicked in fstate then begin + killrepeater; + end; + fstate:= fstate - [gs_mousecellredirected,gs_cellclicked]; + end; +end; + +procedure tcustomgrid.docellevent(var info: celleventinfoty); +begin + with info do begin + grid:= self; + if canevent(tmethod(foncellevent)) then begin + foncellevent(self,info); + end; + if info.cell.col >= 0 then begin + datacols[info.cell.col].docellevent(info); + end; + if canassistive() and not (gs1_nocellassistive in fstate1) then begin + assistiveserver.docellevent(iassistiveclientgrid(getiassistiveclient()), + info); + end; + {$ifdef mse_with_ifi} + if fifilink <> nil then begin + fifilink.controller.docellevent(ificelleventinfoty(info)); + end; + {$endif} + if eventkind = cek_mousepark then begin + if (fmouseparkcell.row <> cell.row) or + (fmouseparkcell.col <> cell.col) then begin + fmouseparkcell:= cell; + if isdatacell(cell) then begin + eventkind:= cek_firstmousepark; + docellevent(info); + end; + end; + end; + end; +end; + +procedure tcustomgrid.cellmouseevent(const acell: gridcoordty; + var info: mouseeventinfoty; + const acellinfopo: pcelleventinfoty = nil; + const aeventkind: celleventkindty = cek_none); +var + cellinfo: celleventinfoty; +// po1: pointty; + cellinfopo: pcelleventinfoty; +begin + cellinfopo:= acellinfopo; + if cellinfopo = nil then begin + cellinfopo:= @cellinfo; + end; + fillchar(cellinfopo^,sizeof(cellinfo),0); + with cellinfopo^ do begin + mouseeventinfopo:= @info; + cell:= acell; + grid:= self; + gridmousepos:= info.pos; + eventkind:= aeventkind; + if eventkind = cek_none then begin + case info.eventkind of + ek_mousemove: eventkind:= cek_mousemove; + ek_mousepark: eventkind:= cek_mousepark; + ek_buttonpress: eventkind:= cek_buttonpress; + ek_buttonrelease: eventkind:= cek_buttonrelease; + end; + end; + if (acellinfopo = nil) and (eventkind <> cek_none) then begin + if eventkind in mousecellevents then begin + zone:= cz_default; + end; + flastcellpos:= cellrect(cellinfo.cell).pos; + try + subpoint1(info.pos,flastcellpos); + if (eventkind = cek_buttonrelease) and (cell.row < 0) and + (cell.row <> invalidaxis) then begin + docellevent(cellinfopo^); + if not (es_processed in mouseeventinfopo^.eventstate) then begin + fixrows[cell.row].buttoncellevent(cellinfopo^); + end; + end + else begin + docellevent(cellinfopo^); + end; + finally + addpoint1(info.pos,flastcellpos); + end; + end; + end; +end; + +procedure tcustomgrid.dofocusedcellposchanged; +begin + //dummy +end; + +function tcustomgrid.isfirstrow: boolean; +begin + result:= (ffocusedcell.row <= 0); +end; + +function tcustomgrid.islastrow: boolean; +begin + result:= (ffocusedcell.row < 0) or (ffocusedcell.row = rowhigh); +end; + +function tcustomgrid.selectcell(const cell: gridcoordty; + const amode: cellselectmodety; + const checkmultiselect: boolean = false): boolean; + //calls onselectcell +var + info: celleventinfoty; + bo1: boolean; + int1: integer; +begin + initeventinfo(cell,cek_select,info); + info.accept:= true; + case amode of + csm_reverse: begin + info.selected:= not fdatacols.selected[cell]; + end; + csm_select: begin + info.selected:= true; + end; + else begin + info.selected:= false; + end; + end; + if (amode = csm_reverse) or + (cell.row = invalidaxis) or (cell.col = invalidaxis) or + (info.selected <> fdatacols.selected[cell]) then begin + bo1:= info.selected; + docellevent(info); + result:= info.accept; + if result then begin + bo1:= bo1 and checkmultiselect; + if bo1 then begin + beginupdate; + end; + try + if bo1 then begin + if fdatacols.foptions * + [co_multiselect,co_rowselect] = [co_rowselect] then begin + if fdatacols.fselectedrow >= 0 then begin + fdatacols.rowselected[fdatacols.fselectedrow]:= false; + end + else begin + if fdatacols.fselectedrow = -2 then begin + fdatacols.rowselected[invalidaxis]:= false; + end; + end; + end; + for int1:= 0 to fdatacols.count - 1 do begin + with tdatacol(fdatacols.fitems[int1]) do begin + if not (co_multiselect in foptions) then begin + selected[invalidaxis]:= false; + end; + end; + end; + end; + if (cell.col >= 0) and + (co_rowselect in fdatacols[cell.col].foptions) then begin +// fdatacols.selected[makegridcoord(invalidaxis,cell.row)]:= info.selected; + fdatacols.rowselected[cell.row]:= info.selected; + end + else begin + fdatacols.selected[cell]:= info.selected; + end; + finally + if bo1 then begin + endupdate; + end; + end; + end; + end + else begin + result:= true; + end; +end; + +function tcustomgrid.canexitrow(const force: boolean = false): boolean; +begin + if force then begin + include(fstate1,gs1_forcenullcheck); + end; + try + result:= container.canclose(nil); + //for notnull check in twidgetgrid + finally + exclude(fstate1,gs1_forcenullcheck); + end; +end; + +procedure tcustomgrid.checkmorerows(const acount: integer); + //<0 -> before +begin + if canevent(tmethod(fongetmorerows)) then begin + fongetmorerows(self,acount); + end; +end; + +procedure tcustomgrid.beforefocuscell(const cell: gridcoordty; + const selectaction: focuscellactionty); +begin + if (og1_focusmorerows in foptionsgrid1) and + (cell.row <> invalidaxis) then begin + if cell.row >= frowcount then begin + checkmorerows(cell.row - frowcount + 1); + end + else begin + if cell.row < 0 then begin + checkmorerows(cell.row); + end; + end; + end; +end; + +procedure tcustomgrid.afterfocuscell(const cellbefore: gridcoordty; + const selectaction: focuscellactionty); +var + info: celleventinfoty; +begin + initeventinfo(ffocusedcell,cek_focusedcellchanged,info); + info.cellbefore:= cellbefore; + info.newcell:= ffocusedcell; + info.selectaction:= selectaction; + docellevent(info); +end; + +function tcustomgrid.focuscell(cell: gridcoordty; + selectaction: focuscellactionty = fca_focusin; + const selectmode: selectcellmodety = scm_cell; + const ashowcell: cellpositionty = cep_nearest): boolean; + + function isappend(const arow: integer): boolean; + begin + result:= canappendrow and + (not (gs_isdb in fstate) and not (gs1_autoappendlock in fstate1) and + ((og_autoappend in foptionsgrid) and + (arow >= frowcount) and (frowcount <> 0) or + (arow = 0) and (frowcount = 0) and (og_autofirstrow in foptionsgrid))); + end; + + procedure doselectaction; + + procedure startanchors; + begin + fstartanchor:= cell; + fendanchor:= invalidcell; + end; + + procedure changeselectedrange(rows: boolean); + type + rectaccessty = record pos: integer; dummy: integer; count: integer end; + var + rect1: gridrectty; + int1: integer; + po1,po3: pinteger; + po2: ^rectaccessty; + begin + rect1:= self.getselectedrange; + if rows then begin + po1:= @cell.row; + po2:= @rect1.row; + po3:= @fstartanchor.row; + end + else begin + po1:= @cell.col; + po2:= @rect1.col; + po3:= @fstartanchor.col; + end; + if po1^ < po2^.pos then begin + po2^.count:= po2^.pos - po1^; + po2^.pos:= po1^; + fdatacols.setselectedrange(rect1,true,true,true); + end + else begin + if po1^ >= po3^ then begin //right side + int1:= po1^ - po2^.pos - po2^.count; + if int1 >= 0 then begin + po2^.pos:= po2^.pos + po2^.count; + po2^.count:= int1 + 1; + fdatacols.setselectedrange(rect1,true,true,true); + end + else begin + po2^.pos:= po1^ + 1; + po2^.count:= -int1 - 1; + fdatacols.setselectedrange(rect1,false,true,true); + end; + end + else begin //left side + int1:= po2^.pos - po1^; + if int1 >= 0 then begin + po2^.pos:= po1^; + po2^.count:= int1; + fdatacols.setselectedrange(rect1,true,true,true); + end + else begin + po2^.count:= -int1; + fdatacols.setselectedrange(rect1,false,true,true); + end; + end; + end; + end; + + procedure doselectcell(const mode: cellselectmodety); + begin + case selectmode of + scm_row: begin + selectcell(makegridcoord(invalidaxis,cell.row),mode,true); + end; + scm_col: begin + selectcell(makegridcoord(cell.col,invalidaxis),mode,true); + end; + else begin + selectcell(cell,mode,true); + end; + end; + end; + + var + cells,celle: gridcoordty; + rect1: gridrectty; + int1: integer; + + begin //doselectaction + beginupdate; + try + case selectaction of + fca_entergrid,fca_focusin,fca_focusinshift,fca_focusinrepeater, + fca_focusinforce,fca_setfocusedcell: begin + if (selectaction <> fca_entergrid) then begin + if not (og1_noresetselect in foptionsgrid1) then begin + fdatacols.selected[invalidcell]:= false; + end; + end; + startanchors; + if isdatacell(cell) and (co_focusselect in fdatacols[cell.col].foptions) then begin + doselectcell(csm_select); + end; + end; + fca_reverse: begin + doselectcell(csm_reverse); + startanchors; + end; + fca_selectstart: begin + fdatacols.selected[invalidcell]:= false; + doselectcell(csm_select); + startanchors; + end; + fca_selectend: begin + getselectedrange; //ev. adjust startanchor to rowcount + if fstartanchor.col < 0 then begin + fstartanchor:= ffocusedcell; + end; + if fstartanchor.col >= 0 then begin + cells:= fstartanchor; + celle:= cell; + case selectmode of + scm_row: begin + cells.col:= 0; + celle.col:= fdatacols.count - 1; + end; + scm_col: begin + cells.row:= 0; + celle.row:= rowhigh; + end; + end; + if fendanchor.col >= 0 then begin + case selectmode of + scm_row: begin + celle.col:= cells.col; + end; + scm_col: begin + celle.row:= cells.row; + end; + end; + if gs_islist in fstate then begin + fdatacols.changeselectedrange(fstartanchor,fendanchor,cell,true); + end + else begin //todo: optimize for selectmode <> scm_cell + if (selectmode <> scm_cell) or ((cell.col >= fstartanchor.col) xor + (fendanchor.col >= fstartanchor.col)) or + ((cell.row >= fstartanchor.row) xor + (fendanchor.row >= fstartanchor.row)) then begin + rect1:= makegridrect(celle,cells); + fdatacols.selected[invalidcell]:= false; + fdatacols.setselectedrange(rect1,true,true,true); + case selectmode of + scm_row: begin + beginupdate; + rect1.col:= invalidaxis; + for int1:= rect1.rowcount - 1 downto 0 do begin + fdatacols.selected[rect1.pos]:= true; + inc(rect1.row); + end; + endupdate; + end; + scm_col: begin + beginupdate; + rect1.row:= invalidaxis; + for int1:= rect1.colcount - 1 downto 0 do begin + fdatacols.selected[rect1.pos]:= true; + inc(rect1.col); + end; + endupdate; + end; + end; + end + else begin + changeselectedrange(false); + fendanchor.col:= cell.col; + changeselectedrange(true); + end; + end; + end + else begin + if celle.col < cells.col then begin + dec(celle.col); + end + else begin + inc(celle.col); + end; + if celle.row < cells.row then begin + dec(celle.row); + end + else begin + inc(celle.row); + end; + fdatacols.setselectedrange(cells,celle,true,true,true); + end; + end; + fendanchor:= cell; + end; + end; + finally + ffocusedcell:= cell; + endupdate(true); + end; + end; //doselectaction() + +var + sortchecked: boolean; + + procedure dosortcheck(const isappend: boolean); //follow sort order + var + int1: integer; + begin + if not sortchecked and not isautoappend then begin + sortchecked:= true; + int1:= cell.row - ffocusedcell.row; + if (int1 <> 0) or (selectaction = fca_focusinforce) then begin + checksort; + if cell.row >= 0 then begin + if (cell.row >= 0) and (ffocusedcell.row >= 0) then begin + cell.row:= ffocusedcell.row + int1; + if cell.row < 0 then begin + cell.row:= 0; + end; + if isappend then begin + if cell.row > frowcount then begin + cell.row:= frowcount; + end; + end + else begin + if cell.row >= frowcount then begin + cell.row:= frowcount-1; + end; + end; + end; + end; + end; + end; + end; //dosortcheck + +var + focuscount: integer; + coord1,coord2: gridcoordty; + bo1,bo2,bo3: boolean; + int1: integer; + rect1: rectty; + nullchecklocked: boolean; + cellbefore: gridcoordty; + rowcountbefore: integer; + autorowappended: boolean; + +begin //focuscell + if selectaction <> fca_exitgrid then begin + if (cell.row > invalidaxis) and (cell.col > invalidaxis) then begin + rect1:= cellrect(cell); + with rect1 do begin + bo1:= (cell.row >= 0); + if bo1 then begin + int1:= fdatarect.y - y; + bo1:= (int1 > 0) and (int1 < fdatarect.cy); + end; + if not bo1 then begin + bo1:= (cell.col >= 0) and (cell.col < fdatacols.count) and + not (co_nohscroll in tcol(fdatacols.fitems[cell.col]).foptions); + if bo1 then begin + int1:= fdatarect.x - x; + bo1:= (int1 > 0) and (int1 < fdatarect.cx); + end; + end; + if bo1 then begin + update; //scrolling needed, update pending paintings with old focused cell + end; + end; + end; + end; + inc(ffocuscount); + focuscount:= ffocuscount; + beforefocuscell(cell,selectaction); + if focuscount <> ffocuscount then begin + exit; + end; + result:= false; + exclude(fstate,gs_mousecellredirected); + nullchecklocked:= false; + if ffocusedcell.row = cell.row then begin + nullchecklocked:= true; + beginnonullcheck; + end; + autorowappended:= (ffocusedcell.row = frowcount-1) and isautoappend; + rowcountbefore:= frowcount; + try + if (fnocheckvalue = 0) and not (gs_rowremoving in fstate) then begin + int1:= ffocusedcell.row; + if ((cell.row <> ffocusedcell.row) or (cell.col <> ffocusedcell.col) or + (selectaction = fca_focusinforce)) and + not docheckcellvalue or (focuscount <> ffocuscount) then begin + exit; + end; + if cell.row = int1 then begin + cell.row:= ffocusedcell.row; //follow possible change by sort + end; + if ((cell.row <> ffocusedcell.row) or (selectaction = fca_focusinforce)) and + (ffocusedcell.row >= 0) and container.entered and + not ((gs1_rowdeleting in fstate1) or + container.canclose(window.focusedwidget)) then begin + //for notnull check in twidgetgrid + + exit; + end; + end; + if (selectaction in [fca_focusin,fca_focusinrepeater,fca_focusinforce]) and + ((cell.col < 0) or (cell.col >= fdatacols.count) or + not fdatacols[cell.col].canfocus(mb_none,[],false,bo1)) then begin + selectaction:= fca_setfocusedcell; + end; + if selectaction = fca_entergrid then begin + if cell.row < 0 then begin + cell.row:= 0; + end; + if cell.col < 0 then begin + cell.col:= 0; + end; + cell.col:= nextfocusablecol(cell.col,false,cell.row,true); + if (gs_hasactiverowcolor in fstate) and (cell.row < frowcount) then begin + invalidaterow(cell.row); + end; + end; + if cell.row < 0 then begin + cell.row:= invalidaxis; + end; + if cell.col < 0 then begin + cell.col:= invalidaxis; + end; + if (cell.row >= 0) and (cell.col >= 0) then begin + if cell.col >= fdatacols.count then begin + cell.col:= fdatacols.count - 1; + if cell.col < 0 then begin + exit; + end; + end; + if (cell.row >= frowcount) and not isappend(cell.row) then begin + cell.row:= frowcount - 1; + if cell.row < 0 then begin + if selectaction = fca_entergrid then begin + cell.row:= invalidaxis; + end + else begin + exit; + end; + end; + end; + cell.col:= mergestart(cell.col,cell.row); + end; + bo1:= ((cell.col <> invalidaxis) or (cell.row <> invalidaxis)) and + (ashowcell <> cep_none); + if (cell.col <> ffocusedcell.col) or (cell.row <> ffocusedcell.row) or + (selectaction in [fca_entergrid,fca_focusinforce]) or + (gs_restorerow in fstate) then begin + exclude(fstate,gs_restorerow); + coord1:= ffocusedcell; + if (selectaction <> fca_entergrid) and isdatacell(coord1) then begin + include(fstate,gs_cellexiting); + fdatacols[coord1.col].internaldoexitcell(coord1,cell,selectaction); + exclude(fstate,gs_cellexiting); + if ffocuscount <> focuscount then begin + exit; + end; + end + else begin + coord1:= invalidcell; + end; + sortchecked:= false; + if isappend(cell.row) then begin + dosortcheck(true); + if (frowcount = 0) or (og_appendempty in foptionsgrid) or + not fdatacols.rowempty(frowcount-1) then begin + cell.row:= frowcount; + if fdatacols.fnewrowcol >= 0 then begin + cell.col:= fdatacols.fnewrowcol; + end; + bo2:= gs1_sortchangelock in fstate1; + include(fstate1,gs1_sortchangelock); + bo3:= gs1_autoappending in fstate1; + include(fstate1,gs1_autoappending); + try + insertrow(frowcount,1,og1_forcerowsmodified in foptionsgrid1); + include(fstate1,gs1_rowsortinvalid); + if ffocuscount <> focuscount then begin + focuscell(mgc(ffocusedcell.col,cell.row)); + exit; + end; + autorowappended:= true; + finally + if not bo2 then begin + exclude(fstate1,gs1_sortchangelock); + end; + if not bo3 then begin + exclude(fstate1,gs1_autoappending); + end; + end; + end + else begin + factiverow:= coord1.row; + include(fstate,gs_restorerow); + focuscell(coord1,selectaction); //restore previous row + exit; + end; + end; +// else begin + if cell.row >= frowcount then begin + cell.row:= frowcount - 1; + if cell.row < 0 then begin + cell.row:= invalidaxis; + end; + end; +// end; + cellbefore:= ffocusedcell; + if (selectaction = fca_exitgrid) or + ((cell.row <> ffocusedcell.row) and + (coord1.row >= 0) and + ((coord1.row >= frowcount-1) and (cell.row < coord1.row) or + not autorowappended and + ((cell.row <= rowcountbefore{-1}) and not (gs_restorerow in fstate) or + (cell.row < frowcount) + ) + ) + ) then begin + int1:= ffocusedcell.row; + ffocusedcell.row:= invalidaxis; + updaterowdata; //for twidgetgrid, data invalid + bo2:= false; + if (int1 <> cell.row) and doremoveappinsrow(int1,cell.row) then begin + if (cell.row > int1) then begin + dec(cell.row); + bo2:= true; + end; + end; + if int1 >= frowcount then begin + int1:= frowcount-1; + end; + if (int1 >= 0) and not ((selectaction = fca_exitgrid) and + (gs_rowremoving in fstate)) and + ((cell.row >= 0) or (selectaction = fca_exitgrid)) then begin + ffocusedcell.row:= int1; +// if bo2 and (cell.row = cell.row) then begin +// updaterowdata; //no focusin data update +// end; + end; + if ffocusedcell.row >= 0 then begin + updaterowdata; //current values + end; + end; + dosortcheck(false); + + if not (selectaction in [fca_exitgrid,fca_entergrid]) then begin + ffocusedcell:= invalidcell; + end; + if selectaction = fca_exitgrid then begin + factiverow:= ffocusedcell.row; + for int1:= 0 to fdatacols.count - 1 do begin + if co_resetselectonexit in fdatacols[int1].foptions then begin + fdatacols.selected[makegridcoord(int1,-1)]:= false; + end; + end; + if gs_emptyrowremoved in fstate then begin + cell:= ffocusedcell; + selectaction:= fca_focusin; + doselectaction; + end; + end + else begin + doselectaction; +// ffocusedcell:= cell; moved to doselectaction + end; + if bo1 then begin + showcell(cell,ashowcell); + end; + if isdatacell(cell) then begin + checkrowreadonlystate; + coord2:= cell; + fdatacols[cell.col].internaldoentercell(coord1,cell,selectaction); + if ffocuscount <> focuscount then begin + exit; + end; + if ((cell.col <> coord2.col) or (cell.row <> coord2.row)) then begin + focuscell(cell,selectaction); + exit; + end; + end; + if (gs_hasactiverowcolor in fstate) and + (ffocusedcell.row <> cellbefore.row) then begin + if cellbefore.row >= 0 then begin + invalidaterow(cellbefore.row); + end; + if ffocusedcell.row >= 0 then begin + invalidaterow(ffocusedcell.row); + end; + end; + end + else begin //cell = ffocusedcell + cellbefore:= ffocusedcell; + if bo1 then begin + showcell(cell,ashowcell); + end; + if not (selectaction in [fca_focusin,fca_focusinrepeater, + fca_setfocusedcell,fca_none]) then begin + doselectaction; + end; + end; + finally + if nullchecklocked then begin + endnonullcheck; + end; + end; + factiverow:= ffocusedcell.row; + afterfocuscell(cellbefore,selectaction); + flastcol:= ffocusedcell.col; + result:= true; +end; + +function tcustomgrid.defocuscell: boolean; +begin + result:= focuscell(invalidcell{,fca_none}); +end; + +function tcustomgrid.defocusrow: boolean; +begin + result:= focuscell(makegridcoord(ffocusedcell.col,invalidaxis){,fca_none}); +end; + +function tcustomgrid.focusedcellvalid: boolean; +begin + result:= (ffocusedcell.col >= 0) and (ffocusedcell.row >= 0) and + not (gs_cellexiting in fstate); +end; + +function tcustomgrid.rowremoving: boolean; +begin + result:= gs_rowremoving in fstate; +end; + +function tcustomgrid.scrollingcol: boolean; + //true if focusedcolvalid and no co_nohscroll +begin + result:= (ffocusedcell.col >= 0) and + not (co_nohscroll in fdatacols[ffocusedcell.col].foptions); +end; + +function tcustomgrid.noscrollingcol: boolean; + //true if focusedcolvalid and co_nohscroll +begin + result:= (ffocusedcell.col >= 0) and + (co_nohscroll in fdatacols[ffocusedcell.col].foptions); +end; + +function tcustomgrid.cellexiting: boolean; +begin + result:= gs_cellexiting in fstate; +end; + +function tcustomgrid.isinsertempty: boolean; +begin + result:= (gs1_rowinserted in fstate1) and + (og_noinsertempty in foptionsgrid) and + (ffocusedcell.row >= 0) and fdatacols.rowempty(ffocusedcell.row); +end; + +function tcustomgrid.isautoappend: boolean; + //true if last row is auto appended + //todo: simplify, use gs1_rowinserted +begin + result:= not (gs_isdb in fstate) and (frowcount > 0) and + ((frowcount = 1) and (og_autofirstrow in foptionsgrid) or + (foptionsgrid * [og_autoappend,og_appendempty] = [og_autoappend]) + ) and fdatacols.rowempty(frowcount - 1); +end; + +function tcustomgrid.autoappending: boolean; +begin + result:= gs1_autoappending in fstate1; +end; + +function tcustomgrid.autoremoving: boolean; +begin + result:= gs1_autoremoving in fstate1; +end; + +function tcustomgrid.doremoveappinsrow(const oldrow,newrow: integer): boolean; +var + b1: boolean; +begin + result:= false; + if not (gs_isdb in fstate) then begin + b1:= gs1_autoremoving in fstate1; + include(fstate1,gs1_autoremoving); + try + if gs1_rowinserted in fstate1 then begin + if (og_noinsertempty in foptionsgrid) and + (oldrow >= 0) and fdatacols.rowempty(oldrow) then begin + fstate1:= fstate1-[gs1_rowinserted,gs1_rowsortinvalid]; + if not (gs_rowremoving in fstate) then begin + result:= true; + deleterow(oldrow); + end; + exit; + end; + end + else begin + if (newrow <> frowcount-1) and (oldrow = frowcount-1) and + isautoappend then begin + if row >= 0 then begin + if row = 0 then begin + row:= invalidaxis; + end + else begin + row:= newrow-1; + end; + end + else begin + if newrow = frowcount-1 then begin + exclude(fstate1,gs1_rowsortinvalid); + end; + if not (gs_rowremoving in fstate) and + not (og_appendempty in optionsgrid) then begin + result:= true; + deleterow(frowcount-1,1,og1_forcerowsmodified in foptionsgrid1); + include(fstate,gs_emptyrowremoved); + end; + end; + end + end; + finally + if not b1 then begin + exclude(fstate1,gs1_autoremoving); + end; + end; + end; + exclude(fstate1,gs1_rowinserted); +end; + +procedure tcustomgrid.removeappendedrow; +begin + docheckcellvalue; + doremoveappinsrow(row,invalidaxis); +end; + +function tcustomgrid.hasdata: boolean; +begin + result:= (rowcount > 1) or (rowcount = 1) and not isautoappend; +end; + +function tcustomgrid.gridprop(const coord: gridcoordty): tgridprop; //nil if none +begin + result:= nil; + with coord do begin + if row < 0 then begin + if row >= - ffixrows.count then begin + result:= tgridprop(ffixrows.fitems[-1-row]); + exit; + end; + end; + if {(row = invalidaxis) or} (row >= 0) and (row < frowcount) then begin + if col < 0 then begin + if col >= -fixcols.count then begin + result:= tgridprop(ffixcols.fitems[-1-col]); + exit; + end; + end + else begin + if col < fdatacols.count then begin + result:= tgridprop(fdatacols.fitems[col]); + exit; + end; + end; + end; + end; +end; + +function tcustomgrid.isdatacell(const coord: gridcoordty): boolean; +begin + with coord do begin + result:= (col >= 0) and (row >= 0) and + (col < fdatacols.count) and (row < frowcount); + end; +end; + +function tcustomgrid.isvalidcell(const coord: gridcoordty): boolean; +begin + with coord do begin + result:= (col < fdatacols.count) and (col >= -ffixcols.count) and + (row < frowcount) and (row >= -ffixrows.count); + end; +end; + +function tcustomgrid.isfixrow(const coord: gridcoordty): boolean; +begin + with coord do begin + result:= (row < 0) and (fixrows.count + row >= 0); + end; +end; + +function tcustomgrid.isfixcol(const coord: gridcoordty): boolean; +begin + with coord do begin + result:= (col < 0) and (fixcols.count + col >= 0); + end; +end; + +procedure tcustomgrid.checkdatacell(const coord: gridcoordty); +begin + if not isdatacell(coord) then begin + datacellerror(coord); + end; +end; + +procedure tcustomgrid.datacellerror(const coord: gridcoordty); +begin + error(gre_invaliddatacell,gridcoordtotext(coord)); +end; + +procedure tcustomgrid.error(aerror: griderrorty; text: string); +begin + if aerror <> gre_ok then begin + if text <> '' then begin + raise tgridexception.create(errorstrings[aerror]+' '+text+'.'); + end + else begin + raise tgridexception.create(errorstrings[aerror]+'.'); + end; + end; +end; + +procedure tcustomgrid.indexerror(row: boolean; index: integer; text: string); +begin + if row then begin + error(gre_colindex,text+' '+inttostr(index)); + end + else begin + error(gre_rowindex,text+' '+inttostr(index)); + end; +end; + +procedure tcustomgrid.scrollrows(step: integer); +var + int1: integer; +begin + if og1_scrollmorerows in foptionsgrid1 then begin + if step > 0 then begin + int1:= firstvisiblerow - step; + if int1 < 0 then begin + checkmorerows(int1); + end; + end + else begin + int1:= lastvisiblerow - step - rowcount+1; + if int1 > 0 then begin + checkmorerows(int1); + end; + end; + end; + if canevent(tmethod(fonscrollrows)) then begin + fonscrollrows(self,step); + end; + tgridframe(fframe).scrollpos:= addpoint(tgridframe(fframe).scrollpos, + makepoint(0,ystep*step)); +end; + +procedure tcustomgrid.scrollleft; +var + int1: integer; + coord1: gridcoordty; + rect1: rectty; +begin + if fdatacols.scrollablecount <= 1 then begin + tgridframe(fframe).scrollpos:= subpoint(tgridframe(fframe).scrollpos, + makepoint(fdatarect.cx div 10 + 1,0)); + end + else begin + cellatpos(makepoint(fdatarect.x+fdatarect.cx-1,fdatarect.y),coord1); + if coord1.col >= 0 then begin + rect1:= cellrect(coord1); + if rect1.x + rect1.cx = fdatarect.x + fdatarect.cx then begin + if coord1.col < fdatacols.Count - 1 then begin + rect1:= cellrect(makegridcoord(coord1.col+1,coord1.row)); + end + else begin + rect1.x:= fdatarect.x + fdatarect.cx - rect1.cx; + end; + end; + int1:= fdatarect.x + fdatarect.cx - rect1.x - rect1.cx; + tgridframe(fframe).scrollpos:= addpoint(tgridframe(fframe).scrollpos, + makepoint(int1,0)); + end; + end; +end; + +procedure tcustomgrid.scrollright; +var + int1: integer; + coord1: gridcoordty; + rect1: rectty; +begin + if fdatacols.scrollablecount <= 1 then begin + tgridframe(fframe).scrollpos:= addpoint(tgridframe(fframe).scrollpos, + makepoint(fdatarect.cx div 10 + 1,0)); + end + else begin + cellatpos(fdatarect.pos,coord1); + if coord1.col >= 0 then begin + rect1:= cellrect(coord1); + if rect1.x = fdatarect.x then begin + if coord1.col > 0 then begin + rect1:= cellrect(makegridcoord(coord1.col-1,coord1.row)); + end + else begin + rect1.x:= fdatarect.x; + end; + end; + int1:= fdatarect.x - rect1.x; + tgridframe(fframe).scrollpos:= addpoint(tgridframe(fframe).scrollpos, + makepoint(int1,0)); + end; + end; +end; + +procedure tcustomgrid.scrollpageleft; +var + int1,int2: integer; + coord1: gridcoordty; + rect1: rectty; +begin + if fdatacols.scrollablecount <= 1 then begin + tgridframe(fframe).scrollpos:= subpoint(tgridframe(fframe).scrollpos, + makepoint(fdatarect.cx,0)); + end + else begin + cellatpos(fdatarect.pos,coord1); + if coord1.col >= 0 then begin + rect1:= cellrect(coord1); + int2:= fdatacols[coord1.col].step; + for int1:= coord1.col to datacols.count - 1 do begin + inc(int2,fdatacols[int1].step); + if int2 > fdatarect.cx then begin + dec(int2,fdatacols[int1].step); + break; + end; + end; + int2:= int2 + rect1.x; + tgridframe(fframe).scrollpos:= subpoint(tgridframe(fframe).scrollpos, + makepoint(int2,0)); + end; + end; +end; + +procedure tcustomgrid.scrollpageright; +var + int1,int2: integer; + coord1: gridcoordty; + rect1: rectty; +begin + if fdatacols.scrollablecount <= 1 then begin + tgridframe(fframe).scrollpos:= addpoint(tgridframe(fframe).scrollpos, + makepoint(fdatarect.cx,0)); + end + else begin + cellatpos(fdatarect.pos,coord1); + if coord1.col >= 0 then begin + rect1:= cellrect(coord1); + int2:= -rect1.x; + if coord1.col > 0 then begin + inc(int2,fdatacols[coord1.col-1].step); + end; + for int1:= coord1.col - 1 downto 0 do begin + inc(int2,fdatacols[int1].step); + if int2 > fdatarect.cx then begin + dec(int2,fdatacols[int1].step); + break; + end; + end; + tgridframe(fframe).scrollpos:= addpoint(tgridframe(fframe).scrollpos, + makepoint(int2,0)); + end; + end; +end; + +function tcustomgrid.calcshowshift(const rect: rectty; const position: cellpositionty): pointty; +var + po1,po2: pointty; +begin + po1:= nullpoint; //left, up + po2:= nullpoint; //right, down + with rect do begin + po1.x:= fdatarect.x + fdatarect.cx - (x + cx); //rangeend-endpos + po2.x:= fdatarect.x - x; //rangestart-startpos + case position of + cep_nearest: begin + if po1.x >= 0 then begin //no left shift + po1.x:= 0; + if po2.x <= 0 then begin //no right shift + po2.x:= 0; + end; + end + else begin //left shift + if po2.x >= 0 then begin //right shift + po2.x:= 0; //no change + po1.x:= 0; + end + else begin + if po2.x >= 0 then begin //right shift + po1.x:= 0; //no left shift + end + else begin + if po1.x - po2.x < 0 then begin //left shift to big + po1.x:= 0; //shift to left margin + end + else begin + po2.x:= 0; //left shift + end; + end; + end; + end; + end; + else begin + po1.x:= 0; + po2.x:= 0; + end; + end; + po1.y:= fdatarect.y + fdatarect.cy - (y + cy); //rangeend-endpos + case position of + cep_nearest: begin + if po1.y > 0 then begin + po1.y:= 0; + end; + end; + end; + po2.y:= fdatarect.y - y; //rangestart-startpos + case position of + cep_nearest: begin + if po2.y <= 0 then begin + po2.y:= 0; + end + else begin + po1.y:= 0; + end; + end; + cep_rowcentered: begin + po1.y:= -(y - fdatarect.y - (fdatarect.cy - cy) div 2); + po2.y:= 0; + end; + cep_rowcenteredif: begin + if (po1.y < 0) or (po2.y > 0) then begin + result:= calcshowshift(rect,cep_rowcentered); + end + else begin + result:= nullpoint; + end; + exit; + end; + cep_top: begin + po1.y:= 0; + end; + cep_bottom: begin + po2.y:= 0; + end; + else begin + po1.y:= 0; + po2.y:= 0; + end; + end; + end; + result:= addpoint(po1,po2); +end; + +function tcustomgrid.showrect(const rect: rectty; + const position: cellpositionty = cep_nearest; + const noxshift: boolean = false): pointty; +var + po1: pointty; + int1: integer; +begin + with tgridframe(fframe) do begin + result:= scrollpos; + po1:= calcshowshift(rect,position); + if noxshift then begin + po1.x:= 0; + end; + if (po1.x <> 0) then begin + int1:= po1.x + result.x + fscrollrect.cx - + tgridframe(fframe).fpaintrect.x - tgridframe(fframe).fpaintrect.cx; + if int1 < 0 then begin + dec(po1.x,int1); + end; + int1:= po1.x + fscrollrect.x; + if int1 > 0 then begin + dec(po1.x,int1); + end; + end; + + scrollpos:= addpoint(result,po1); + result:= subpoint(scrollpos,result); + end; +end; + +function tcustomgrid.showcaretrect(const arect: rectty; + const aframe: framety): pointty; +var + rect1: rectty; +begin + if not window.activating and + ([gs_cellexiting,gs_layoutupdating] * fstate =[]) and + (fnoshowcaretrect = 0) and + not (frame.sbhorz.clicked or frame.sbvert.clicked) and + intersectrect(inflaterect(arect,aframe),cellrect(ffocusedcell),rect1) then begin + result:= showrect(rect1,cep_nearest,noscrollingcol); + end + else begin + result:= nullpoint; + end; +end; + +function tcustomgrid.showcaretrect(const arect: rectty; + const aframe: tcustomframe): pointty; +begin + if aframe <> nil then begin + result:= showcaretrect(arect,aframe.innerframe); + end + else begin + result:= showcaretrect(arect,nullframe); + end; +end; + +function tcustomgrid.showcellrect(const rect: rectty; + const origin: cellinnerlevelty = cil_paint): pointty; +var + rect1: rectty; +begin + if focusedcellvalid then begin + rect1:= cellrect(ffocusedcell,origin); + inc(rect1.x,rect.x); + inc(rect1.y,rect.y); + rect1.cx:= rect.cx; + rect1.cy:= rect.cy; + result:= showrect(rect1,cep_nearest,noscrollingcol); + end + else begin + result:= nullpoint; + end; +end; + +procedure tcustomgrid.showcell(const cell: gridcoordty; + const position: cellpositionty = cep_nearest; + const force: boolean = false); +var + coord1: gridcoordty; + rect1: rectty; + po1: pointty; +begin + if position = cep_none then begin + exit; + end; + if (fupdating > 0) then begin + include(fstate1,gs1_showcellinvalid); + fshowcell:= cell; + fshowcellmode:= position; + end + else begin + if force or not (frame.sbhorz.clicked or frame.sbvert.clicked) then begin + coord1:= cell; + with coord1 do begin + if col >= fdatacols.count then begin + col:= fdatacols.count - 1; + end; + if row >= frowcount then begin + row:= frowcount-1; + end; + rect1:= cellrect(coord1); //updatelayout + po1:= calcshowshift(rect1,position); + if (col < 0) or (co_nohscroll in fdatacols[col].foptions){noscrollingcol} then begin + po1.x:= 0; + end; + if coord1.row < 0 then begin + po1.y:= 0; + end; + tgridframe(fframe).scrollpos:= addpoint(tgridframe(fframe).scrollpos,po1); + end; + end; + end; +end; + +procedure tcustomgrid.showrow(const arow: integer; + const position: cellpositionty = cep_nearest; + const force: boolean = false); +begin + showcell(mgc(invalidaxis,arow),position,force); +end; + +procedure tcustomgrid.showlastrow; +begin + showcell(makegridcoord(col,rowhigh)); +end; + +function tcustomgrid.cellrect(const cell: gridcoordty; + const innerlevel: cellinnerlevelty = cil_all; + const nomerged: boolean = false; + const acellorigin: boolean = false): rectty; + + procedure updatex(const aprop: tgridprop); + begin + with result,aprop do begin + case innerlevel of + cil_paint: begin + inc(x,fcellinfo.rect.x); + cx:= fcellinfo.rect.cx; + end; + cil_inner: begin + inc(x,fcellinfo.rect.x); + inc(x,fcellinfo.innerrect.x); + cx:= fcellinfo.innerrect.cx; + end; + end; + end; + end; + + procedure updatey(const aprop: tgridprop); + begin + with result,aprop do begin + case innerlevel of + cil_paint: begin + inc(y,fcellinfo.rect.y); + dec(cy,fdatarowheight-fcellinfo.rect.cy); +// cy:= fcellinfo.rect.cy; + end; + cil_inner: begin + inc(y,fcellinfo.rect.y); + inc(y,fcellinfo.innerrect.y); + dec(cy,fdatarowheight-fcellinfo.innerrect.cy); +// cy:= fcellinfo.innerrect.cy; + end; + end; + end; + end; + +var + isfixr: boolean; + int1,int2: integer; + po1: prowstatecolmergety; + +begin //cellrect + result:= nullrect; + if (cell.col >= fdatacols.count) or (cell.row >= frowcount) and + not(csdesigning in componentstate) then begin + exit; + end; + internalupdatelayout; + isfixr:= false; + with result,cell do begin + if row < 0 then begin + isfixr:= -row <= ffixrows.count; + if isfixr then begin + with ffixrows[row] do begin + if not acellorigin then begin + y:= fstart; + end; + cy:= fend-fstart; + if innerlevel = cil_noline then begin + dec(cy,linewidth); + if -row > ffixrows.count - ffixrows.oppositecount then begin + inc(y,linewidth); + end; + end; + updatey(ffixrows[row]); + if fframe <> nil then begin + with fframe do begin + if innerlevel >= cil_paint then begin + checkstate; + inc(x,fpaintframe.left); + dec(cx,fpaintframe.left + fpaintframe.right); + end; + if innerlevel >= cil_inner then begin + inc(x,fi.innerframe.left); + dec(cx,fi.innerframe.left + fi.innerframe.right); + end; + end; + end; + if not nomerged then begin + if col >= 0 then begin + if col < fcaptions.count then begin + with tcolheader(fcaptions.fitems[col]) do begin + if fmergeflags * [cmf_v,cmf_h] <> [] then begin + result:= cellrect(frefcell,innerlevel,false,acellorigin); + exit; + end; + inc(cx,fmergedcx); + inc(y,fmergedy); + inc(cy,fmergedcy); + end; + end; + end + else begin + int1:= -col - 1; + if int1 < fcaptionsfix.count then begin + with tcolheader(fcaptionsfix.fitems[int1]) do begin + if fmergeflags * [cmf_v,cmf_h] <> [] then begin + result:= cellrect(frefcell,innerlevel,false,acellorigin); + exit; + end; + inc(x,fmergedx); + inc(cx,fmergedcx); + inc(y,fmergedy); + inc(cy,fmergedcy); + end; + end; + end; + end; + end; + end + else begin //whole height + y:= 0; + cy:= tgridframe(fframe).finnerclientrect.cy; + end; + end + else begin //datarows + int1:= visiblerow(row); + if (int1 >= 0) or (csdesigning in componentstate) then begin + if (og_rowheight in foptionsgrid) and (int1 >= 0) then begin + fdatacols.frowstate.cleanrowheight(row); + fdatacols.frowstate.internalystep(row,y,cy); + if acellorigin then begin + y:= 0; + end; + end + else begin + cy:= fystep; + if not acellorigin then begin + if int1 < 0 then begin + y:= row * cy; + end + else begin + y:= int1 * cy; + end; + end; + end; + if not acellorigin then begin + y:= y + ffixrows.ffirstsize + fscrollrect.y; + end; + if innerlevel > cil_all then begin + int2:= fdatarowlinewidth; + if (og_rowheight in foptionsgrid) and + (row >= 0) and (row < frowcount) then begin + with prowstaterowheightty( + fdatacols.frowstate.getitempo(row))^.rowheight do begin + if linewidth > 0 then begin + int2:= linewidth-1; + end; + end; + end; + dec(cy,int2); + end; + if col < 0 then begin + if -col <= ffixcols.count then begin + updatey(ffixcols[col]); + end; + end + else begin + updatey(fdatacols[col]); + end; + end; + end; + if col < 0 then begin + if -col <= ffixcols.count then begin + with ffixcols[col] do begin + if not acellorigin then begin + x:= x + fstart; + end; + cx:= cx + fend - fstart; + if (innerlevel = cil_noline) or isfixr and + (innerlevel >= cil_noline) then begin + dec(cx,flinewidth); + if -cell.col > ffixcols.count - ffixcols.oppositecount then begin + inc(x,flinewidth); + end; + end; + if not isfixr then begin + updatex(ffixcols[col]); + end; + end; + end + else begin //whole width + x:= 0; + cx:= tgridframe(fframe).finnerclientrect.cx; + end; + end + else begin + with fdatacols[col] do begin + cx:= cx + fend-fstart; + if not acellorigin then begin + if co_nohscroll in foptions then begin + x:= x + fstart; + end + else begin + x:= x + fstart + ffixcols.ffirstsize + fdatacols.ffirstsize + + fscrollrect.x; + end; + end; + if (innerlevel >= cil_noline) or + isfixr and (innerlevel >= cil_noline) then begin + dec(cx,flinewidth); + if (co_nohscroll in foptions) and + (index >= fdatacols.ffirsthscrollindex) then begin + inc(x,flinewidth); + end; + end; + if not isfixr then begin + updatex(fdatacols[col]); + if (og_colmerged in foptionsgrid) and not nomerged then begin + if (row >= 0) and (row < frowcount) and + (col < fdatacols.flastvisiblecol) then begin + po1:= fdatacols.frowstate.getitempocolmerge(row); + if po1^.colmerge.merged <> 0 then begin //has merged cols + for int1:= col to fdatacols.flastvisiblecol-1 do begin + if (po1^.colmerge.merged = mergedcolall) or + (int1 < mergedcolmax) and (po1^.colmerge.merged and + bits[int1] <> 0) then begin + with tdatacol(fdatacols.fitems[int1+1]) do begin + if not (co_invisible in foptions) then begin + inc(result.cx,step); + end; + end; + end + else begin + break; + end; + end; + end; + end; + end; + end; + end; + end; + end; + if not acellorigin then begin + addpoint1(result.pos,pointty(tgridframe(fframe).fi.innerframe.topleft)); + end; +end; //cellrect + +function tcustomgrid.clippedcellrect(const cell: gridcoordty; + const innerlevel: cellinnerlevelty = cil_all): rectty; + //origin = paintrect.pos, clipped by datarect +begin + result:= cellrect(cell,innerlevel); + intersectdatarect(result); +end; + +procedure tcustomgrid.clientrectchanged; +begin + inherited; + if (componentstate * [csloading,csdestroying] = []) and + not (gs_updatelocked in fstate) then begin + layoutchanged; + updatevisiblerows; + end; +end; + +procedure tcustomgrid.drawcellbackground(const acanvas: tcanvas); +begin + with fdatacols[ffocusedcell.col] do begin + drawcellbackground(acanvas,fframe,fface); + end; +end; + +procedure tcustomgrid.drawcelloverlay(const acanvas: tcanvas); +begin + with fdatacols[ffocusedcell.col] do begin + drawcelloverlay(acanvas,fframe); + end; +end; + +procedure tcustomgrid.drawfocusedcell(const acanvas: tcanvas); +begin + fdatacols[ffocusedcell.col].drawcell(acanvas); +end; + +function tcustomgrid.getcaretcliprect: rectty; +begin + internalupdatelayout; + if noscrollingcol then begin + result:= fdatarecty; + end + else begin + result:= fdatarect; + end; +end; + +procedure tcustomgrid.scrolled(const dist: pointty); +begin + //dummy +end; + +procedure tcustomgrid.createdatacol(const index: integer; + out item: tdatacol); +begin + //dummy +end; + +function tcustomgrid.rowvisible(const arow: integer): integer; +var + rect1: rectty; +begin + internalupdatelayout; + rect1:= cellrect(makegridcoord(0,arow)); + if rect1.y < fdatarect.y then begin + result:= -1; + end + else begin + if rect1.y + rect1.cy > fdatarect.y + fdatarect.cy then begin + result:= 1; + end + else begin + result:= 0; + end; + end; +end; + +function tcustomgrid.rowsperpage: integer; +begin + internalupdatelayout; + result:= fdatarect.cy div ystep; +end; + +procedure tcustomgrid.focusrow(const arow: integer; + const action: focuscellactionty; + const noreadonly: boolean; + const selectmode: selectcellmodety = scm_cell); +var + int1,int2: integer; +begin + int1:= flastcol; + focuscell(makegridcoord( + nextfocusablecol(flastcol,false,arow,noreadonly),arow),action,selectmode); + int2:= mergestart(flastcol,ffocusedcell.row); + if (int2 <= int1) and (mergeend(flastcol,ffocusedcell.row) > int1) or + (int2 > 0) and not (co_nofocus in datacols[int2].options) then begin + flastcol:= int1; + end; +end; + +procedure tcustomgrid.rowup(const action: focuscellactionty = fca_focusin; + const nowrap: boolean=false); +begin + if ffocusedcell.row = 0 then begin + checkmorerows(-1); + end; + with fdatacols.frowstate do begin + if visiblerowcount > 0 then begin + if (ffocusedcell.row > 0) or not (og_wraprow in foptionsgrid) then begin + focusrow(visiblerowstep(ffocusedcell.row,-1,false),action,false); + end + else begin + if not nowrap and (og_wraprow in foptionsgrid) then begin + focusrow(visiblerowstep(frowcount-1,0,false),action,false); + end; + end; + end; + end; +end; + +procedure tcustomgrid.rowdown(const action: focuscellactionty = fca_focusin; + const nowrap: boolean=false); +//var +// int1: integer; +begin + if ffocusedcell.row = frowcount - 1 then begin + checkmorerows(1); + end; + with fdatacols.frowstate do begin + if visiblerowcount > 0 then begin + if not (og_wraprow in foptionsgrid) or + (visiblerow(ffocusedcell.row) < visiblerowcount - 1) then begin + focusrow(visiblerowstep(ffocusedcell.row,1,og_autoappend in foptionsgrid), + action,false); + end + else begin + if not nowrap and (og_wraprow in foptionsgrid) then begin + focusrow(visiblerowstep(0,0,false),action,false); + end; + end; + end; + end; +end; + +procedure tcustomgrid.pageup(const action: focuscellactionty = fca_focusin); +var + int1: integer; +begin + if (ffocusedcell.row >= 0) then begin + int1:= ffocusedcell.row - rowsperpage; + if int1 < 0 then begin + checkmorerows(int1); + end; + end; + with fdatacols.frowstate do begin + if visiblerowcount > 0 then begin + int1:= visiblerowstep(ffocusedcell.row,-rowsperpage+1,false); + if visiblerow(int1) < visiblerowcount then begin + scrollrows(rowsperpage - 1); + focusrow(int1,action,false); + end; + end; + end; +end; + +procedure tcustomgrid.pagedown(const action: focuscellactionty = fca_focusin); +var + int1: integer; +begin + int1:= (ffocusedcell.row+rowsperpage)-frowcount+1; + if int1 > 0 then begin + checkmorerows(int1); + end; + with fdatacols.frowstate do begin + if visiblerowcount > 0 then begin + int1:= visiblerowstep(ffocusedcell.row,rowsperpage-1,false); + if int1 >= 0 then begin + scrollrows(-(rowsperpage - 1)); + focusrow(int1,action,false); + end; + end; + end; +end; + +procedure tcustomgrid.wheelup(const action: focuscellactionty = fca_focusin); +var + int1: integer; +begin + int1:= ffocusedcell.row - wheelheight; + if int1 < 0 then begin + int1:= 0; + end; + if int1 < frowcount then begin + scrollrows(wheelheight); + focusrow(int1,action,false); + end; +end; + +procedure tcustomgrid.wheeldown(const action: focuscellactionty = fca_focusin); +var + int1: integer; +begin + int1:= ffocusedcell.row + wheelheight; + if int1 > frowcount - 1 then begin + int1:= frowcount -1; + end; + if int1 >= 0 then begin + scrollrows(-wheelheight); + focusrow(int1,action,false); + end; +end; + +procedure tcustomgrid.firstrow(const action: focuscellactionty = fca_focusin); +begin + if frowcount > 0 then begin + focusrow(0,action,false); + end; +end; + +procedure tcustomgrid.lastrow(const action: focuscellactionty = fca_focusin); +begin + if frowcount > 0 then begin + focusrow(frowcount-1,action,false); + end; +end; + +procedure tcustomgrid.domousewheelevent(var info: mousewheeleventinfoty); +begin + if not (es_transientfor in info.eventstate) or + not (gs_isdb in fstate) then begin + frame.domousewheelevent(info,fwheelscrollheight = -1); + end; + inherited; +end; + +function tcustomgrid.canautoappend: boolean; +begin + result:= (rowcount = 0) and (og_autofirstrow in foptionsgrid) and canappendrow; +end; + +function tcustomgrid.checkreautoappend: boolean; +begin + result:= (og_focuscellonenter in foptionsgrid) and + canautoappend and entered and (row < 0); + if result then begin + row:= 0; + end; +end; + +procedure tcustomgrid.dokeydown(var info: keyeventinfoty); +var + action,actioncol: focuscellactionty; + focusbefore: gridcoordty; + mo1: cellselectmodety; + celleventinfo: celleventinfoty; + cellbefore: gridcoordty; + bo1: boolean; + shiftstate: shiftstatesty; + + procedure checkselection; + begin + if (es_processed in info.eventstate) then begin + if not checkreautoappend and (ffocusedcell.col >= 0) then begin + if co_keyselect in fdatacols[ffocusedcell.col].foptions then begin + if ss_shift in shiftstate then begin + if fstartanchor.col < 0 then begin + fstartanchor:= focusbefore; + end; + action:= fca_selectend; + end + else begin + action:= fca_focusin; + end; + focuscell(ffocusedcell,action); + end; + end; + end; + end; +var + gd1: graphicdirectionty; +label + checkwidgetexit; +begin + actioncol:= fca_none; + exclude(fstate1,gs1_scrolllimit); + if canevent(tmethod(fonkeydown)) then begin + fonkeydown(self,info); + end; + if not(es_processed in info.eventstate) then begin + shiftstate:= info.shiftstate * shiftstatesmask; + if ffocusedcell.col >= 0 then begin + fdatacols[ffocusedcell.col].dokeyevent(info,false); + end + else begin + with celleventinfo do begin + initeventinfo(ffocusedcell,cek_keydown,celleventinfo); + keyeventinfopo:= @info; + docellevent(celleventinfo); + end; + end; + cellbefore:= focusedcell; + bo1:= (ow_arrowfocusout in optionswidget) and (shiftstate = []) and + not(((info.key = key_up) or (info.key = key_pageup)) and not isfirstrow or + ((info.key = key_down) or (info.key = key_pagedown)) and not islastrow); + //test for db rows, exit widget + if shiftstate - [ss_shift,ss_ctrl] = [] then begin + if not (es_processed in info.eventstate) then begin + if ss_shift in shiftstate then begin + if (ffocusedcell.col >= 0) and + (co_keyselect in fdatacols[ffocusedcell.col].foptions) then begin + action:= fca_selectend; + actioncol:= action; + end + else begin + action:= fca_focusinshift; + actioncol:= action; + end; + end + else begin + action:= fca_focusinforce; + actioncol:= fca_focusin; + end; + focusbefore:= ffocusedcell; + include(info.eventstate,es_processed); + case info.key of + key_up: begin + if shiftstate = [ss_ctrl] then begin + if (og_keyrowmoving in foptionsgrid) and canmoverow() then begin + if ffocusedcell.row > 0 then begin + moverow(ffocusedcell.row,ffocusedcell.row - 1,1,true); + showcell(ffocusedcell); + end; + end + else begin + scrollrows(1); + end; + exit; + end + else begin + rowup(action,aso_gridnavig in assistiveoptions); + checkselection; + gd1:= gd_up; + goto checkwidgetexit; + end; + end; + key_down: begin + if shiftstate = [ss_ctrl] then begin + if (og_keyrowmoving in foptionsgrid) and canmoverow then begin + if (ffocusedcell.row >= 0) and (ffocusedcell.row < frowcount-1) then begin + moverow(ffocusedcell.row,ffocusedcell.row + 1,1,true); + showcell(ffocusedcell); + end; + end + else begin + scrollrows(-1); + end; + exit; + end + else begin + rowdown(action,aso_gridnavig in assistiveoptions); + checkselection; + gd1:= gd_down; + goto checkwidgetexit; + end; + end; + key_home: begin + if ss_ctrl in shiftstate then begin + focuscell(makegridcoord(nextfocusablecol(0,false,0,true),0),action); + end + else begin + exclude(info.eventstate,es_processed); + end; + end; + key_end: begin + if ss_ctrl in shiftstate then begin + focuscell(makegridcoord( + nextfocusablecol(datacols.count-1,true,frowcount-1,true), + frowcount-1),action); + end + else begin + exclude(info.eventstate,es_processed); + end; + end; + key_pageup: begin + if ss_ctrl in shiftstate then begin + if og_visiblerowpagestep in foptionsgrid then begin + focuscell(makegridcoord(ffocusedcell.col,ffirstvisiblerow),action); + end + else begin + firstrow(action); + end; + end + else begin + pageup(action); + end; + end; + key_pagedown: begin + if ss_ctrl in shiftstate then begin + if og_visiblerowpagestep in foptionsgrid then begin + focuscell(makegridcoord(ffocusedcell.col,flastvisiblerow),action); + end + else begin + lastrow(action); + end; + end + else begin + pagedown(action); + end; + end; + else begin + exclude(info.eventstate,es_processed); + end; + end; + end; + if not(es_processed in info.eventstate) and + (ffocusedcell.col >= 0) then begin + include(info.eventstate,es_processed); + case info.key of + key_return: begin + if (og_colchangeonreturnkey in foptionsgrid) and + (shiftstate = []) then begin + colstep(fca_focusin,1,true,false,true); + end + else begin + exclude(info.eventstate,es_processed); + end; + end; + key_tab,key_backtab: begin + if not (og_colchangeontabkey in foptionsgrid) or (rowcount = 0) then begin + exclude(info.eventstate,es_processed); + dokeydownaftershortcut(info); + end + else begin + if shiftstate - [ss_shift] = [] then begin + if docheckcellvalue then begin + action:= fca_focusin; + if shiftstate = [ss_shift] then begin + colstep(actioncol,-1,true,false,true); + end + else begin + colstep(actioncol,1,true,false,true); + end; + end; + end + else begin + exclude(info.eventstate,es_processed); + end; + end; + end; + key_left: begin + if shiftstate = [ss_ctrl] then begin + if og_keycolmoving in foptionsgrid then begin + if ffocusedcell.col > 0 then begin + movecol(ffocusedcell.col,ffocusedcell.col-1); + end; + end + else begin + scrollleft; + end; + exit; + end + else begin + colstep(actioncol,-1,false,(aso_gridnavig in assistiveoptions) or + not (og_wrapcol in foptionsgrid),false); + checkselection; + gd1:= gd_left; + goto checkwidgetexit; + end; + end; + key_right: begin + if shiftstate = [ss_ctrl] then begin + if og_keycolmoving in foptionsgrid then begin + if (ffocusedcell.col >= 0) and + (ffocusedcell.col < fdatacols.count-1) then begin + moverow(ffocusedcell.col,ffocusedcell.col + 1); + end; + end + else begin + scrollright; + end; + exit; + end + else begin + colstep(actioncol,1,false,(aso_gridnavig in assistiveoptions) or + not (og_wrapcol in foptionsgrid),false); + checkselection; + gd1:= gd_right; + goto checkwidgetexit; + end; + end; + else begin + exclude(info.eventstate,es_processed); + end; + end; + end; + checkselection; + if not (es_processed in info.eventstate) and (ffocusedcell.col >= 0) then begin + with fdatacols[ffocusedcell.col] do begin + if (info.key = key_space) and (co_keyselect in foptions) and + ((shiftstate = [ss_shift]) or (shiftstate = [ss_ctrl])) then begin + if shiftstate = [ss_ctrl] then begin + mo1:= csm_reverse; + end + else begin + mo1:= csm_select; + end; + selectcell(ffocusedcell,mo1,true); + include(info.eventstate,es_processed); + end; + end; + end; + end; + if not (es_processed in info.eventstate) then begin + if {issysshortcut(sho_copy,info) or} + issysshortcut(sho_copycells,info) and + (fdatacols.cancopy or canevent(tmethod(foncopyselection))) and + copyselection then begin + include(info.eventstate,es_processed); + end + else begin + if issysshortcut(sho_pastecells,info) and + (fdatacols.canpaste or canevent(tmethod(fonpasteselection))) and + pasteselection then begin + include(info.eventstate,es_processed); + end; + end; + end; + if not (es_processed in info.eventstate) then begin + if og_rowinserting in foptionsgrid then begin + if issysshortcut(sho_rowinsert,info) then begin + if og1_swaprowinsertappend in foptionsgrid1 then begin + if canappendrow then begin + doappendrow(nil); + end; + end + else begin + if caninsertrow then begin + doinsertrow(nil); + end; + end; + include(info.eventstate,es_processed); + end + else begin + if issysshortcut(sho_rowappend,info) then begin + if og1_swaprowinsertappend in foptionsgrid1 then begin + if caninsertrow then begin + doinsertrow(nil); + end; + end + else begin + if canappendrow then begin + doappendrow(nil); + end; + end; + include(info.eventstate,es_processed); + end; + end; + end; + if not (es_processed in info.eventstate) then begin + if (og_rowdeleting in foptionsgrid) and + issysshortcut(sho_rowdelete,info) then begin + if candeleterow then begin + dodeleterows(nil); + end; + include(info.eventstate,es_processed); + end; + end; + end; + if not (es_processed in info.eventstate) then begin + inherited; + end; + end; + exit; + +checkwidgetexit: + if (row = cellbefore.row) and (col = cellbefore.col) then begin + if bo1 then begin + exclude(info.eventstate,es_processed); + if es_child in info.eventstate then begin + dokeydownaftershortcut(info); + end; + end + else begin + if canassistive() and ((gd1 in [gd_left,gd_right]) or + not (gs_isdb in fstate) or (gs1_scrolllimit in fstate1)) then begin + assistiveserver.dogridbordertouched( + iassistiveclientgrid(getiassistiveclient),gd1); + end; + exclude(fstate1,gs1_scrolllimit); + end; + end; +end; + +procedure tcustomgrid.dokeyup(var info: keyeventinfoty); +var + celleventinfo: celleventinfoty; +begin + if ffocusedcell.col >= 0 then begin + fdatacols[ffocusedcell.col].dokeyevent(info,true); + end + else begin + with celleventinfo do begin + initeventinfo(ffocusedcell,cek_keyup,celleventinfo); + keyeventinfopo:= @info; + docellevent(celleventinfo); + end; + end; + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +procedure tcustomgrid.updatevisiblerows; + //todo: optimize +var + cell: gridcoordty; + int1: integer; +begin +// if not (gs_visiblerowsupdating in fstate) then begin +// include(fstate,gs_visiblerowsupdating); +// try + inc(fvisiblerowsupdating); + if frowcount = 0 then begin + fvisiblerowfoldinfo:= nil; + fvisiblerows:= nil; + ffirstvisiblerow:= invalidaxis; + flastvisiblerow:= invalidaxis; + fvisiblerowsbase:= invalidaxis; + end + else begin + int1:= fvisiblerowsupdating; + cellatpos(makepoint(0,fdatarecty.y),cell); //calls updatelayout + if int1 <> fvisiblerowsupdating then begin + exit; //recursion + end; + int1:= fvisiblerowsupdating; + ffirstvisiblerow:= cell.row; + cellatpos(makepoint(0,fdatarecty.y+fdatarecty.cy-1),cell); + if int1 <> fvisiblerowsupdating then begin + exit; //recursion + end; + flastvisiblerow:= cell.row; + if ffirstvisiblerow < 0 then begin + ffirstvisiblerow:= 0; + end; + if flastvisiblerow < 0 then begin + flastvisiblerow:= frowcount - 1; + end; + fvisiblerowsbase:= fdatacols.frowstate.visiblerow(ffirstvisiblerow); + if fvisiblerowsbase < 0 then begin + flastvisiblerow:= invalidaxis; + end; + if flastvisiblerow < 0 then begin + fvisiblerows:= nil; + end + else begin + fvisiblerows:= fdatacols.frowstate.visiblerows1(fvisiblerowsbase, + fdatarect.cy - fscrollrect.y{ div fdatarowheight + 2}); + int1:= high(fvisiblerows); + if int1 >= 0 then begin + while fvisiblerows[int1] > flastvisiblerow do begin + dec(int1); + end; + setlength(fvisiblerows,int1+1); + end; + end; + if (og_folded in foptionsgrid) then begin + with fdatacols.frowstate do begin + updatefoldinfo(self.fvisiblerows,fvisiblerowfoldinfo); + { + if (row >= 0) then begin + int1:= row; + row:= nearestvisiblerow(row); + if row = int1 then begin //no focuscell + if row >= ffoldchangedrow then begin + dofocusedcellposchanged; + fdatacols.frowstate.ffoldchangedrow:= bigint; + end; + end; + end; + } + end; + end + else begin + fvisiblerowfoldinfo:= nil; + end; + end; +// finally +// exclude(fstate,gs_visiblerowsupdating); +// end; +// end; +end; + +function tcustomgrid.getselectedrange: gridrectty; +begin + if fstartanchor.row >= frowcount then begin //ev. appended row removed + fstartanchor.row:= frowcount - 1; + if fstartanchor.row < 0 then begin + fstartanchor.col:= invalidaxis; + end; + end; + if fendanchor.row >= frowcount then begin //ev. appended row removed + fendanchor.row:= frowcount - 1; + if fendanchor.row < 0 then begin + fendanchor.col:= invalidaxis; + end; + end; + if (fstartanchor.col < 0) or (fendanchor.col < 0) then begin + result.pos:= invalidcell; + result.size:= gridsizety(nullsize); + end + else begin + result:= makegridrect(fstartanchor,fendanchor); + end; +end; + +procedure tcustomgrid.doenter; +begin + inherited; + if ((og_focuscellonenter in foptionsgrid) or + (ffocusedcell.col >= 0) and (ffocusedcell.row >= 0)) and + not (gs1_focuscellonenterlock in fstate1)then begin + focuscell(ffocusedcell,fca_entergrid); + end; +end; +{ +procedure tcustomgrid.dofocus; +begin + inherited; + if og_focuscellonenter in foptionsgrid then begin + focuscell(ffocusedcell,fca_entergrid); + end; +end; +} +procedure tcustomgrid.initnewcomponent(const ascale: real); +begin + ffixrows.count:= 1; + inherited; +end; + +procedure tcustomgrid.loaded; +var + int1: integer; + col1: tdatacol; +begin + inherited; + fdatacols.resetpropwidth; + ffixcols.resetpropwidth; + checkneedsrowheight; + updatelayout; //set propwidthref of cols + fdatacols.checkindexrange; + fdatacols.frowstate.sourcenamechanged(-1); + checksort; + for int1:= 0 to fdatacols.count - 1 do begin + col1:= tdatacol(fdatacols.fitems[int1]); + with col1 do begin + if (fdata <> nil) and canevent(tmethod(fonchange)) then begin + fonchange(col1,-1); + end; + end; + end; + dorowsdatachanged(makegridcoord(invalidaxis,0),frowcount); +end; + +procedure tcustomgrid.doexit; +begin + if not (csdestroying in componentstate) then begin + focuscell(invalidcell,fca_exitgrid); + end; + inherited; +end; + +procedure tcustomgrid.doactivate; +begin + if focusedcellvalid then begin + fdatacols[ffocusedcell.col].doactivate; + end; + inherited; +end; + +procedure tcustomgrid.dodeactivate; +begin + exclude(fstate,gs_cellclicked); + if focusedcellvalid then begin + fdatacols[ffocusedcell.col].dodeactivate; + end; + inherited; +end; + +procedure tcustomgrid.activechanged; +begin + inherited; + if (ffocusedcell.row >= 0) and (gs_hasactiverowcolor in fstate) then begin + invalidaterow(ffocusedcell.row); + end; +end; + +procedure tcustomgrid.doasyncevent(var atag: integer); +begin + if atag = gridautosizetag then begin + exclude(fstate1,gs1_autosizepending); + checkautosize(); + designchanged; + end + else begin + inherited; + end; +end; + +procedure tcustomgrid.getautopaintsize(var asize: sizety); +begin + if foptionswidget1 * [ow1_autowidth,ow1_autoheight] = [] then begin + inherited; + end + else begin + if fstate*[gs_updatelocked,gs_layoutupdating] <> [] then begin + if not (gs1_autosizepending in fstate1) then begin + include(fstate1,gs1_autosizepending); + asyncevent(gridautosizetag,[peo_local]); + end; + end + else begin + asize:= calcminscrollsize(); + end; + inherited; + end; +end; + +procedure tcustomgrid.getpickobjects(const sender: tobjectpicker; + var objects: integerarty); +var + cellkind: cellkindty; + cell: gridcoordty; + rect1: rectty; + + function cancolsizing(col: integer): boolean; + begin + result:= (col <> invalidaxis) and ((csdesigning in componentstate) or + (col >= 0) and + (og_colsizing in foptionsgrid) and + not (co_fixwidth in fdatacols[col].foptions)); + end; + + function cancolmoving: boolean; + begin + result:= (csdesigning in componentstate) or + (og_colmoving in foptionsgrid) and + not (co_fixpos in fdatacols[cell.col].foptions); + end; + + function canrowsizing: boolean; + begin + result:= (csdesigning in componentstate) or (og_rowsizing in foptionsgrid); + end; + + function canrowmoving: boolean; + begin + result:= (csdesigning in componentstate) or + ((og_rowmoving in foptionsgrid) and canmoverow); + end; + + function checkfixcol(nofixed: boolean = false): boolean; + begin + result:= false; + with sender.pickrect do begin + if (cell.row >= 0) and (pos.y <= rect1.y + sizingtol) then begin + if canrowsizing then begin + objects[0]:= pickobjectstep * (cell.row-1) + integer(pok_datarowsize); + end; + end + else begin + if (cell.row >= 0) and (pos.y >= rect1.y + rect1.cy - sizingtol) then begin + if canrowsizing then begin + objects[0]:= pickobjectstep * (cell.row) + integer(pok_datarowsize); + end; + end + else begin + if (csdesigning in componentstate) and not nofixed then begin + if (pos.x <= rect1.x + sizingtol) and //left line + (cell.col <> ffixcols.ffirstopposite + 1) then begin + //not left col + if cell.col <= ffixcols.ffirstopposite then begin //right of table + objects[0]:= -pickobjectstep * (cell.col) + integer(pok_fixcolsize); + end + else begin //left of table + objects[0]:= -pickobjectstep * (cell.col-1) + integer(pok_fixcolsize); + end; + end + else begin + if (pos.x >= rect1.x + rect1.cx - sizingtol) then begin //right line + if (cell.col <> ffixcols.ffirstopposite) then begin //not right col + if cell.col <= ffixcols.ffirstopposite then begin //right of table + objects[0]:= -pickobjectstep * (cell.col+1) + integer(pok_fixcolsize); + end + else begin + objects[0]:= -pickobjectstep * (cell.col) + integer(pok_fixcolsize); + end; + end; + end; + end; + end + else begin + if canrowmoving and not nofixed then begin + objects[0]:= pickobjectstep * (cell.row) + integer(pok_datarow); + result:= true; + end; + end; + end; + end; + end; + end; + + function checkfixrow(nofixed: boolean = false): boolean; + var + int1: integer; + begin + result:= false; + with sender.pickrect do begin + if (pos.x >= rect1.x + rect1.cx - sizingtol) then begin + if (cell.col >= 0) then begin + int1:= cell.col; + if int1 >= fdatacols.ffirstopposite then begin + int1:= fdatacols.nextvisiblecol(int1); + end; + if cancolsizing(int1) then begin + objects[0]:= pickobjectstep * (int1) + integer(pok_datacolsize); + end; + end; + end + else begin + if (pos.x <= rect1.x + sizingtol) then begin + int1:= cell.col; + if cell.col < fdatacols.ffirstopposite then begin + int1:= fdatacols.previosvisiblecol(int1); + end; + if (int1 >= 0) and cancolsizing(int1) then begin + objects[0]:= pickobjectstep * (int1) + integer(pok_datacolsize); + end; + end + else begin + if (csdesigning in componentstate) and not nofixed then begin + if (pos.y <= rect1.y + sizingtol) then begin + //top line + if cell.row <> ffixrows.ffirstopposite + 1 then begin //not top row + if cell.row <= ffixrows.ffirstopposite then begin //below the table + objects[0]:= -pickobjectstep * (cell.row) + integer(pok_fixrowsize); + end + else begin //above the table + objects[0]:= -pickobjectstep * (cell.row-1) + integer(pok_fixrowsize); + end; + end; + end + else begin + if (pos.y >= rect1.y + rect1.cy - sizingtol) and + (cell.row <> ffixrows.ffirstopposite) then begin + //bottom line, not bottom row + if cell.row <= ffixrows.ffirstopposite then begin //below the table + objects[0]:= -pickobjectstep * (cell.row+1) + integer(pok_fixrowsize); + end + else begin + objects[0]:= -pickobjectstep * (cell.row) + integer(pok_fixrowsize); + end; + end + else begin + if not (gs_child in fstate) then begin + objects[0]:= pickobjectstep * cell.col + integer(pok_datacol); + result:= true; + end; + end; + end; + end + else begin + if cancolmoving and not nofixed and not (gs_child in fstate) then begin + with fixrows[cell.row] do begin + if (cell.col >= fcaptions.count) or + not (dco_colsort in fcaptions[cell.col].options) or + (pos.x < rect1.x + rect1.cx - sortglyphwidth) or + (csdesigning in componentstate) then begin + objects[0]:= pickobjectstep * cell.col + integer(pok_datacol); + result:= true; + end; + end; + end; + end; + end; + end; + end; + end; + +begin + if ((sender.shiftstate * shiftstatesmask) - [ss_left] <> []) or + (gs_child in fstate) then begin + exit; + end; + setlength(objects,1); + objects[0]:= -1; //none + with sender.pickrect do begin + cellkind:= cellatpos(pos,cell); + rect1:= cellrect(cell,cil_noline,true); + case cellkind of + ck_fixcolrow: begin + if (csdesigning in componentstate) then begin + if checkfixcol or (objects[0] < 0) then begin + if checkfixrow or (objects[0] < 0) then begin + objects[0]:= -pickobjectstep * (cell.row) + integer(pok_fixrow); + end; + end; + end; + end; + ck_fixcol: begin + checkfixcol; + end; + ck_fixrow: begin + checkfixrow; + end; + ck_data: begin + if ffixcols.count = 0 then begin + checkfixcol(true); + end; + if ffixrows.count = 0 then begin + checkfixrow(true); + end; + end; + end; + end; + if objects[0] < 0 then begin + objects:= nil; + end; +end; + +function tcustomgrid.getcursorshape(const sender: tobjectpicker; + var shape: cursorshapety): boolean; +var + objects1: integerarty; +begin + getpickobjects(sender,objects1); + if length(objects1) > 0 then begin + fpickkind:= pickobjectkindty(objects1[0] mod pickobjectstep); + result:= true; + case fpickkind of + pok_datacolsize,pok_fixcolsize: shape:= cr_sizehor; + pok_datarowsize,pok_fixrowsize: shape:= cr_sizever; + else begin + result:= false; + end; + end; + end + else begin + result:= false; + fpickkind:= pok_none; + end; +end; + +procedure tcustomgrid.beginpickmove(const sender: tobjectpicker); +begin + //dummy +end; + +procedure tcustomgrid.pickthumbtrack(const sender: tobjectpicker); +begin + //dummy +end; + +procedure tcustomgrid.decodepickobject(code: integer; out kind: pickobjectkindty; + out cell: gridcoordty; out col: tcol; out row: tfixrow); +var + int1: integer; +begin + kind:= pickobjectkindty(code mod pickobjectstep); + int1:= code div pickobjectstep; + if kind in [pok_fixcol,pok_fixcolsize,pok_fixrow,pok_fixrowsize] then begin + int1:= -int1; + end; + if kind in [pok_fixrow,pok_fixrowsize,pok_datarow,pok_datarowsize] then begin + cell:= makegridcoord(invalidaxis,int1); + end + else begin + cell:= makegridcoord(int1,invalidaxis); + end; + if kind in [pok_datacol,pok_datacolsize] then begin + col:= fdatacols[int1]; + end + else begin + if kind in [pok_fixcol,pok_fixcolsize] then begin + col:= ffixcols[int1]; + end + else begin + col:= nil; + if kind in [pok_fixrow,pok_fixrowsize] then begin + row:= ffixrows[int1]; + end + else begin + row:= nil; + end; + end; + end; +end; + +procedure tcustomgrid.endpickmove(const sender: tobjectpicker); +var + kind: pickobjectkindty; + cell,cell1: gridcoordty; + col1: tcol; + fixrow: tfixrow; + int1,int2: integer; + offset: pointty; + apos: pointty; + ar1: integerarty; +begin + killrepeater; + ar1:= sender.currentobjects; + if ar1 <> nil then begin + decodepickobject(ar1[0],kind,cell,col1,fixrow); + offset:= sender.pickoffset; + apos:= sender.pos; + case kind of + pok_datacolsize,pok_fixcolsize: begin + if (ss_double in sender.mouseeventinfopo^.shiftstate) and + not(co1_noautocolwidth in col1.foptions1) then begin + col1.width:= col1.maxwidth; + end + else begin + if (kind = pok_fixcolsize) and (cell.col <= fixcols.ffirstopposite) or + (kind = pok_datacolsize) and + (cell.col >= fdatacols.ffirstopposite) then begin + col1.width:= col1.width - offset.x; + end + else begin + int1:= offset.x; + with col1 do begin + if co_nohscroll in foptions then begin + if fend + int1 > fdatarect.x + fdatarect.cx then begin + int1:= fdatarect.x + fdatarect.cx - fend; + end; + end; + if co_fill in options then begin + if (int1 < 0) then begin + if width + int1 < fwidthmin then begin + int1:= fwidthmin - width; + end; + end + else begin + if (fwidthmax <> 0) and + (width + int1 > fwidthmax) then begin + int1:= fwidthmax - width; + end; + end; + for int2:= index to datacols.count - 1 do begin + with datacols[int2] do begin + if options * [co_fixwidth,co_fill,co_invisible] = [] then begin + width:= width - int1; + int1:= 0; + break; + end; + end; + end; + if int1 <> 0 then begin + for int2:= index-1 downto 0 do begin + with datacols[int2] do begin + if options * [co_fixwidth,co_fill,co_invisible] = [] then begin + width:= width - int1; + int1:= 0; + break; + end; + end; + end; + end; + end; + width:= width + int1; + end; + end; + end; + end; + pok_fixrowsize: begin + if cell.row <= fixrows.ffirstopposite then begin + fixrow.height:= fixrow.height - offset.y; + end + else begin + fixrow.height:= fixrow.height + offset.y; + end; + end; + pok_datarowsize: begin + if og_rowheight in foptionsgrid then begin + if ss_double in sender.shiftstate then begin + rowheight[cell.row]:= 0; + end + else begin + int1:= fdatacols.frowstate.currentrowheight(cell.row); + rowheight[cell.row]:= int1 + offset.y; + end; + end + else begin + datarowheight:= fdatarowheight + offset.y; + end; + end; + pok_datacol: begin + //cellkind:= + cellatpos(makepoint(apos.x,fdatarect.y),cell1); + if (cell1.col >= 0) and (cell.col <> cell1.col) and not + ((co_nohscroll in tdatacol(fdatacols.fitems[cell1.col]).options) xor + (co_nohscroll in tdatacol(fdatacols.fitems[cell.col]).options)) then begin + movecol(cell.col,cell1.col); + end + else begin + end; + end; + pok_datarow: begin + // cellkind:= + cellatpos(makepoint(fdatarect.x,apos.y),cell1); + if (cell1.row >= 0) and (cell.row <> cell1.row) then begin + moverow(cell.row,cell1.row,1,true); + end + else begin + end; + end; + end; + designchanged; + end; +end; + +procedure tcustomgrid.cancelpickmove(const sender: tobjectpicker); +begin + //dummy +end; + +procedure tcustomgrid.paintxorpic(const sender: tobjectpicker; + const canvas: tcanvas); + + procedure drawhorzline(pos: integer); + begin + with tframe1(fframe) do begin + canvas.intersectcliprect(makerect(fdatarecty.x,0, + fdatarecty.cx,fpaintrect.cy)); + canvas.fillxorrect(makepoint(finnerclientrect.x,pos),finnerclientrect.cx, + gd_right,2,stockobjects.bitmaps[stb_dens50]); + end; + end; + + procedure drawvertline(pos: integer); + begin + with tframe1(fframe) do begin + canvas.intersectcliprect(makerect(0,fdatarectx.y, + fpaintrect.cx,fdatarectx.cy)); + canvas.fillxorrect(makepoint(pos,finnerclientrect.y),finnerclientrect.cy, + gd_down,2,stockobjects.bitmaps[stb_dens50]); + end; + end; + +var + kind: pickobjectkindty; + cell,cell1: gridcoordty; + col1: tcol; + fixrow: tfixrow; + int1,int2: integer; + rect1: rectty; + offset: pointty; + apos: pointty; + ar1: integerarty; + {bo1,}s1,d1: boolean; +begin + int1:= 0; + offset:= sender.pickoffset; + apos:= sender.pos; + ar1:= sender.currentobjects; + if ar1 = nil then begin + exit; + end; + decodepickobject(ar1[0],kind,cell,col1,fixrow); + rect1:= cellrect(cell); + with rect1 do begin + case kind of + pok_datacolsize,pok_fixcolsize: begin + if (kind = pok_fixcolsize) and (cell.col <= fixcols.ffirstopposite) or + (kind = pok_datacolsize) and (cell.col >= + fdatacols.ffirstopposite) then begin + int1:= offset.x+x; + end + else begin + int1:= offset.x+x+cx; + end; + drawvertline(int1); + end; + pok_datarowsize,pok_fixrowsize: begin + if (kind = pok_fixrowsize) and (cell.row < + -(fixrows.count-fixrows.foppositecount)) then begin + int1:= offset.y+y; + end + else begin + int1:= offset.y+y+cy; + end; + drawhorzline(int1); + end; + pok_datarow: begin + cellatpos(makepoint(fdatarect.x,apos.y),cell1); + if cell1.row >= 0 then begin + rect1:= cellrect(cell1); + killrepeater; + if cell1.row > cell.row then begin + int1:= rect1.y+rect1.cy; + if int1 > fdatarect.y + fdatarect.cy then begin + startrepeater(gs_scrolldown,slowrepeat); + end + else begin + drawhorzline(int1); + end; + end + else begin + if (cell1.row > 0) and (rect1.y {- fystep} < fdatarect.y) then begin + startrepeater(gs_scrollup,slowrepeat); + end + else begin + drawhorzline(rect1.y); + end; + end; + end + else begin + if apos.y < fdatarect.y then begin + startrepeater(gs_scrollup,fastrepeat); + end + else begin + rect1:= cellrect(makegridcoord(0,frowcount-1)); + drawhorzline(rect1.y+rect1.cy-2); + startrepeater(gs_scrolldown,fastrepeat); + end; + end; + end; + pok_datacol: begin + s1:= co_nohscroll in tdatacol(fdatacols.fitems[cell.col]).options; + cellatpos(makepoint(apos.x,fdatarect.y),cell1); + d1:= not s1; //inhibit + if cell1.col >= 0 then begin + d1:= co_nohscroll in tdatacol(fdatacols.fitems[cell1.col]).options; + rect1:= cellrect(cell1); + int1:= rect1.x; + if cell1.col > cell.col then begin + int1:= rect1.x+rect1.cx; + end; + end; + killrepeater; + if not s1 then begin + if int1 < fdatarect.x then begin + int1:= fdatarect.x; + end + else begin + int2:= fdatarect.x + fdatarect.cx; + if int1 > int2 then begin + int1:= int2; + end; + end; + if (apos.x < fdatarect.x) then begin + startrepeater(gs_scrollleft,slowrepeat); + end + else begin + if (apos.x >= fdatarect.x + fdatarect.cx) then begin + startrepeater(gs_scrollright,slowrepeat); + end; + end; + end; + if s1 = d1 then begin + drawvertline(int1); + end; + { + else begin + if not s1 then begin + if (apos.x < fdatarect.x) then begin + startrepeater(gs_scrollleft,slowrepeat); + end + else begin +// rect1:= cellrect(makegridcoord(fdatacols.count-1,0)); +// if cell1.col <> invalidaxis then begin +// drawvertline(rect1.x+rect1.cx-2); +// end; + startrepeater(gs_scrollright,slowrepeat); + end; + end; + end; + } + end; + end; + end; +end; + +procedure tcustomgrid.killrepeater; +begin + freeandnil(frepeater); + fstate:= fstate - repeaterstates; +end; + + +procedure tcustomgrid.dobeforepaint(const canvas: tcanvas); +begin + fobjectpicker.dobeforepaint(canvas); + inherited; +end; + +procedure tcustomgrid.doafterpaint(const canvas: tcanvas); +begin + inherited; + fobjectpicker.doafterpaint(canvas); +end; + +function tcustomgrid.getnoscroll(): boolean; +begin + result:= inherited getnoscroll() or (ws1_widgetrectsetting in fwidgetstate1); +end; + +procedure tcustomgrid.repeatproc(const sender: tobject); +var + bo1: boolean; +begin + bo1:= (gs_cellclicked in fstate) and (frepeataction <> fca_none); + if gs_scrollup in fstate then begin + if bo1 then begin + if row < rowcount - 1 then begin + rowdown(frepeataction); + end; + end + else begin + scrollrows(1); + end; + end + else begin + if gs_scrolldown in fstate then begin + if bo1 then begin + if row > 0 then begin + rowup(frepeataction); + end; + end + else begin + scrollrows(-1); + end; + end + else begin + if gs_scrollleft in fstate then begin + if bo1 then begin + if (ffocusedcell.col < 0) or (ffocusedcell.col > 0) and + not (co_nohscroll in + tcol(fdatacols.fitems[ffocusedcell.col-1]).options) then begin + colstep(frepeataction,-1,false,false,false); + end; + end + else begin + scrollright; + end; + end + else begin + if gs_scrollright in fstate then begin + if bo1 then begin + if (ffocusedcell.col < 0) or (ffocusedcell.col < fdatacols.count - 1) and + not (co_nohscroll in + tcol(fdatacols.fitems[ffocusedcell.col+1]).options) then begin + colstep(frepeataction,1,false,false,false); + end; + end + else begin + scrollleft; + end; + end + end; + end; + end; +end; + +procedure tcustomgrid.startrepeater(state: gridstatety; time: integer); +begin + if not (state in fstate) then begin + killrepeater; + include(fstate,state); + frepeater:= tsimpletimer.create(time,{$ifdef FPC}@{$endif}repeatproc,true,[]); + end; +end; + +procedure tcustomgrid.movecol(curindex, newindex: integer; + const auserinput: boolean = false); +var + colbefore: integer; + count: integer; + bo1: boolean; +begin + bo1:= setuserinput(auserinput); + try + if canevent(tmethod(foncolmoving)) then begin + count:= 1; + foncolmoving(self,curindex,newindex,count); + if count <= 0 then begin + exit; + end; + end; + if curindex <> newindex then begin + colbefore:= ffocusedcell.col; + beginupdate; + if curindex >= 0 then begin //datacols + if (ffocusedcell.col = curindex) then begin + ffocusedcell.col:= newindex; + end + else begin + if (ffocusedcell.col >= newindex) and (ffocusedcell.col < curindex) then begin + inc(ffocusedcell.col); + end + else begin + if (ffocusedcell.col <= newindex) and (ffocusedcell.col > curindex) then begin + dec(ffocusedcell.col); + end; + end; + end; + fdatacols.move(curindex,newindex); + end; + endupdate; + docolmoved(curindex,newindex); + if colbefore <> ffocusedcell.col then begin + dofocusedcellposchanged; + end; + end; + finally + resetuserinput(bo1); + end; +end; + +procedure tcustomgrid.moverow(curindex, newindex: integer; count: integer = 1; + const auserinput: boolean = false); +var + int1: integer; + rowbefore: integer; + bo1: boolean; +begin + bo1:= setuserinput(auserinput); + try + if canevent(tmethod(fonrowsmoving)) then begin + fonrowsmoving(self,curindex,newindex,count); + end; + if (count > 0) and (curindex <> newindex) then begin + if (curindex < 0) or (curindex + count > rowcount) then begin + tlist.Error(SListIndexError,curindex); + end; + if (newindex < 0) or (newindex >= rowcount) then begin + tlist.Error(SListIndexError,newindex); + end; + + rowbefore:= ffocusedcell.row; + beginupdate; + if curindex >= 0 then begin //datarows + if not (gs_changelock in fstate) then begin + include(fstate,gs_changelock); + fdatacols.beginchangelock; + end; + if not fdatacols.roworderinvalid then begin + exit; + end; + fdatacols.moverow(curindex,newindex,count); + if (ffocusedcell.row >= 0) then begin + if (ffocusedcell.row >= curindex) and + (ffocusedcell.row < curindex + count) then begin + //focus in moved block + int1:= newindex; + if int1 >= curindex + count then begin + int1:= int1 - count + 1; + end; + ffocusedcell.row:= ffocusedcell.row + int1 - curindex; + end + else begin + if (ffocusedcell.row > curindex) and (ffocusedcell.row < newindex + count) then begin + dec(ffocusedcell.row,count); + end + else begin + if (ffocusedcell.row < curindex) and (ffocusedcell.row >= newindex) then begin + inc(ffocusedcell.row,count); + end; + end; + end; + end; + if factiverow >= 0 then begin + factiverow:= ffocusedcell.row; + end; + invalidate //for fixcols colorselect + end; + include(fstate,gs_rowdatachanged); + endupdate(gs1_sortmoving in fstate1); + dorowsmoved(curindex,newindex,count); + if rowbefore <> ffocusedcell.row then begin + dofocusedcellposchanged; + end; + end; + finally + resetuserinput(bo1); + end; +end; + +procedure tcustomgrid.internalinsertrow(var aindex: integer; + var acount: integer; const auserinput: boolean); +var + rowbefore: integer; + bo1: boolean; +// int1{,int2}: integer; +begin + if acount > 0 then begin + bo1:= setuserinput(auserinput); + try + dorowsinserting(aindex,acount); + if acount > 0 then begin + rowbefore:= ffocusedcell.row; + beginupdate; + try + if aindex >= 0 then begin //datarows + if not (gs_changelock in fstate) then begin + include(fstate,gs_changelock); + fdatacols.beginchangelock; + end; + if not fdatacols.roworderinvalid then begin + exit; + end; + fdatacols.insertrow(aindex,acount); + ffixcols.insertrow(aindex,acount); + if (ffocusedcell.row >= 0) then begin + if (ffocusedcell.row >= aindex) then begin + inc(ffocusedcell.row,acount); + if (factiverow >= 0) then begin + factiverow:= ffocusedcell.row; + end; + end; + end; + inc(frowcount,acount); + if frowcount > frowcountmax then begin + frowcount:= frowcountmax; + end; + if of_insertsamelevel in foptionsfold then begin + with fdatacols.frowstate do begin + if folded then begin + if (gs_appending in self.fstate) or (aindex+acount >= frowcount) then begin + if (aindex > 0) then begin + fillfoldlevel(aindex,acount,foldlevel[aindex-1]); + end; + end + else begin + fillfoldlevel(aindex,acount,foldlevel[aindex+acount]); + end; + end; + end; + end; + dorowcountchanged(frowcount-acount,frowcount); + end; + finally + endupdate; + end; + dorowsinserted(aindex,acount); + if rowbefore <> ffocusedcell.row then begin + dofocusedcellposchanged; + end; + end; + finally + resetuserinput(bo1); + end; + end; +end; + +function tcustomgrid.insertrow(aindex: integer; acount: integer = 1; + const auserinput: boolean = false): int32; +begin + internalinsertrow(aindex,acount,auserinput); + result:= aindex; +end; + +procedure tcustomgrid.internaldeleterow(var aindex: integer; + var acount: integer; const auserinput: boolean); +var + cellbefore: gridcoordty; + countbefore: integer; + defocused: boolean; + bo1,bo2,bo3: boolean; +begin + if acount > 0 then begin + bo3:= setuserinput(auserinput); + try + if (aindex >= 0) and (of_deletetree in foptionsfold) then begin + acount:= fdatacols.rowstate.totchildrencount(aindex,acount); + end; + dorowsdeleting(aindex,acount); + if acount > 0 then begin + defocused:= false; + cellbefore:= ffocusedcell; + beginupdate; + bo2:= gs1_rowdeleting in fstate1; + inc(fnonullcheck); + include(fstate1,gs1_rowdeleting); + try + if aindex >= 0 then begin //datarows + if not fdatacols.roworderinvalid then begin + exit; + end; + if (fclickedcell.row >= 0) and + (aindex <= fclickedcell.row) and + (fclickedcell.row < aindex + acount) then begin + exclude(fstate,gs_cellclicked); + end; + if (factiverow >= 0) then begin + if (factiverow >= aindex + acount) then begin + dec(factiverow,acount); + end + end; + if (ffocusedcell.row >= 0) then begin + if (ffocusedcell.row >= aindex + acount) then begin + dec(ffocusedcell.row,acount); + end + else begin + if ffocusedcell.row >= aindex then begin + countbefore:= frowcount; + bo1:= gs_rowremoving in fstate; + if ffocusedcell.row < aindex + acount then begin + include(fstate,gs_rowremoving); + end; + try + focuscell(makegridcoord(ffocusedcell.col,invalidaxis)); //defocus row + finally + if not bo1 then begin + exclude(fstate,gs_rowremoving); + end; + end; + if ffocusedcell.row <> invalidaxis then begin + factiverow:= ffocusedcell.row; + exit; + end; + defocused:= true; + if aindex + acount > frowcount then begin + dec(acount,countbefore - frowcount); //correct removed empty last row + end; + end; + end; + end; + if acount > 0 then begin + if not (gs_changelock in fstate) then begin + include(fstate,gs_changelock); + fdatacols.beginchangelock; + end; + if of_shiftdeltoparent in foptionsfold then begin + fdatacols.frowstate.movegrouptoparent(aindex,acount); + end; + bo1:= gs1_sortchangelock in fstate1; + include(fstate1,gs1_sortchangelock); + try + fdatacols.deleterow(aindex,acount); + finally + if not bo1 then begin + exclude(fstate1,gs1_sortchangelock); + end; + end; + ffixcols.deleterow(aindex,acount); + dec(frowcount,acount); + dorowcountchanged(frowcount+acount,frowcount); + end; + end; + finally + dec(fnonullcheck); + if not bo2 then begin + exclude(fstate1,gs1_rowdeleting); + end; + endupdate; + end; + dorowsdeleted(aindex,acount); + if cellbefore.row <> ffocusedcell.row then begin + dofocusedcellposchanged; + end; + if (og_focuscellonenter in foptionsgrid) and defocused then begin + cellbefore.row:= aindex; + if cellbefore.row >= frowcount then begin + cellbefore.row:= frowcount - 1; + if cellbefore.row < 0 then begin + cellbefore.row:= 0; + end; + end; + focuscell(cellbefore,fca_focusin); + //ev. auto first row + end; + end; + finally + resetuserinput(bo3); + end; + end; +end; + +procedure tcustomgrid.deleterow(aindex: integer; acount: integer = 1; + const auserinput: boolean = false); +begin + internaldeleterow(aindex,acount,auserinput); +end; + +procedure tcustomgrid.clear; //sets rowcount to 0 +begin + rowcount:= 0; +end; + +function tcustomgrid.appendrow(const checkautoappend: boolean = false): integer; //returns index of new row +var + updatingbefore: integer; + noinvalidatebefore: integer; + po1: pointty; + statebefore: framestatesty; + scrollheightbefore: integer; + + procedure updatelayout1; + begin + fupdating:= 0; + internalupdatelayout; + fupdating:= updatingbefore; + end; + +var + canscroll: boolean; + +begin + if checkautoappend and isautoappend then begin + result:= rowhigh; + end + else begin + statebefore:= tgridframe(fframe).fstate; + scrollheightbefore:= + tcustomscrollbar1(tgridframe(fframe).fvert).fdrawinfo.areas[sbbu_move].ca.dim.cy; + noinvalidatebefore:= fnoinvalidate; + updatingbefore:= fupdating; + beginupdate; + try + if frowcount >= frowcountmax then begin + canscroll:= showing and (fappendcount < 5); + inc(fappendcount); + po1.x:= 0; + po1.y:= -fystep; + if canscroll then begin + updatelayout1; + checkinvalidate; + scrollrect(po1,fdatarecty,scrollcaret(true)); + end + else begin + invalidate; + end; + inc(fnoinvalidate); + rowcount:= frowcount+1; + updatelayout1; + dec(fnoinvalidate); + if canscroll then begin + rowchanged(frowcount-1); + end; + end + else begin + inc(fnoinvalidate); + rowcount:= rowcount+1; + updatelayout1; + dec(fnoinvalidate); + rowchanged(frowcount-1); + end; + result:= frowcount-1; + if statebefore * scrollbarframestates <> + tgridframe(fframe).fstate * scrollbarframestates then begin + invalidatewidget; + end + else begin + if tcustomscrollbar1(tgridframe(fframe).fvert). + fdrawinfo.areas[sbbu_move].ca.dim.cy <> + scrollheightbefore then begin + tcustomscrollbar1(tgridframe(fframe).fvert).invalidate; + end; + end; + finally + fnoinvalidate:= noinvalidatebefore; + fupdating:= updatingbefore + end; + end; +end; + +function tcustomgrid.appenddatarow: integer; +begin + result:= rowcount; + rowcount:= rowcount+1; +end; + +procedure tcustomgrid.checkinvalidate; +var + int1: integer; +begin + if gs_invalidated in fstate then begin + invalidate; + end + else begin + if finvalidatedcells <> nil then begin + for int1:= 0 to high(finvalidatedcells) do begin + with finvalidatedcells[int1] do begin + if (row < 0) and (col < 0) then begin + invalidate; + break; + end + else begin + invalidatecell(finvalidatedcells[int1]); + end; + end; + end; + finvalidatedcells:= nil; + end; + end; +end; + +procedure tcustomgrid.beginupdate; +begin + if fupdating = 0 then begin + exclude(fstate,gs_emptyrowremoved); //possibly checked in endupdate + fappendcount:= 0; + frowdatachangestart:= rowcount; + end; + inc(fupdating); +end; + +procedure tcustomgrid.endupdate(const nosort: boolean = false; + const invalidrowstart: int32 = 0); +var + int1,int2: integer; +{$ifdef mse_with_ifi} + bo1: boolean; +{$endif} +begin + dec(fupdating); + if fupdating = 0 then begin +{$ifdef mse_with_ifi} + bo1:= fstate * + [gs_rowcountinvalid,gs_rowdatachanged,gs_selectionchanged] <> []; +{$endif} + if gs_rowcountinvalid in fstate then begin + int2:= bigint; + for int1:= 0 to datacols.count - 1 do begin + with datacols[int1] do begin + if (fdata <> nil) and (fdata.count < int2) then begin + int2:= fdata.count; + end; + end; + end; + exclude(fstate,gs_rowcountinvalid); + if int2 <> bigint then begin + rowcount:= int2; + end; + end; + if not nosort then begin + checksort; + end; + checkinvalidate; + if gs_changelock in fstate then begin + exclude(fstate,gs_changelock); + fdatacols.endchangelock; + end; + if gs_rowdatachanged in fstate then begin + updaterowdata; + if frowdatachangestart < rowcount then begin + rowdatachanged(makegridcoord(invalidaxis,frowdatachangestart), + frowcount-frowdatachangestart); + end; +// rowdatachanged(makegridcoord(invalidaxis,invalidrowstart), +// frowcount-invalidrowstart); + end; + if gs_selectionchanged in fstate then begin + internalselectionchanged; + end; + {$ifdef mse_with_ifi} + if bo1 and (fifiserverintf <> nil) and not(ws_loadedproc in fwidgetstate) and + not (gs_emptyrowremoved in fstate) and not isautoappend then begin + iifidataserver(fifiserverintf).valuechanged(iifigridlink(self)); + end; + {$endif} + if (gs1_showcellinvalid in fstate1) then begin + showcell(fshowcell,fshowcellmode); + exclude(fstate1,gs1_showcellinvalid); + end; + if (gs_focusedcellchanged in fstate) and + (ffocusedcell.col >= 0) and (ffocusedcell.row >= 0) then begin + focusedcellchanged; + end; + end; +end; + +procedure tcustomgrid.docolmoved(const fromindex, toindex: integer); +begin + if canevent(tmethod(foncolmoved)) then begin + foncolmoved(self,fromindex,toindex,1); + end; +end; + +procedure tcustomgrid.dorowsmoved(const fromindex, toindex, count: integer); +begin + if canevent(tmethod(fonrowsmoved)) then begin + fonrowsmoved(self,fromindex,toindex,count); + end; + dorowsmodified; +end; + +procedure tcustomgrid.dorowsinserting(var index, count: integer); +begin + {$ifdef mse_with_ifi} + if fifilink <> nil then begin + fifilink.controller.dorowsinserting(index,count,userinput); + end; + {$endif} + if canevent(tmethod(fonrowsinserting)) then begin + fonrowsinserting(self,index,count); + end; +end; + +procedure tcustomgrid.dorowsinserted(const index, count: integer); +begin + {$ifdef mse_with_ifi} + if fifilink <> nil then begin + fifilink.controller.dorowsinserted(index,count,userinput); + end; + {$endif} + if canevent(tmethod(fonrowsinserted)) then begin + fonrowsinserted(self,index,count); + end; + dorowsdatachanged(makegridcoord(invalidaxis,index),count); + dorowsmodified; +end; + +procedure tcustomgrid.dorowsdeleting(var index, count: integer); +begin + if canevent(tmethod(fonrowsdeleting)) then begin + fonrowsdeleting(self,index,count); + end; + {$ifdef mse_with_ifi} + if fifilink <> nil then begin + fifilink.controller.dorowsdeleting(index,count,userinput); + end; + {$endif} +end; + +procedure tcustomgrid.dorowsdeleted(index, count: integer); +begin + {$ifdef mse_with_ifi} + if fifilink <> nil then begin + fifilink.controller.dorowsdeleted(index,count,userinput); + end; + {$endif} + if canevent(tmethod(fonrowsdeleted)) then begin + fonrowsdeleted(self,index,count); + end; + dorowsmodified; +end; + +class function tcustomgrid.classskininfo: skininfoty; +begin + result:= inherited classskininfo; + result.objectkind:= sok_grid; +end; + +procedure tcustomgrid.setoptionsgrid(const avalue: optionsgridty); +const + mask1: optionsgridty = rowstateoptions; +var + optionsbefore: optionsgridty; +begin + if foptionsgrid <> avalue then begin +{ + if (csreading in componentstate) then begin + if (og_noresetselect in avalue) then begin + include(foptionsgrid1,og1_noresetselect); + end; + end; +} + optionsbefore:= foptionsgrid; + foptionsgrid:= avalue; +// foptionsgrid:= optionsgridty( +// setsinglebit(card32(avalue),card32(foptionsgrid), +// card32([og_customsorted,og_sorted]))); +// foptionsgrid:= avalue-deprecatedoptionsgrid; + if (longword(avalue) xor longword(optionsbefore)) + and longword(mask1) <> 0 then begin + fdatacols.frowstate.free; + fdatacols.frowstate:= trowstatelist.create(self); + fdatacols.frowstate.count:= rowcount; + end; + fdatacols.frowstate.folded:= og_folded in avalue; + layoutchanged; + if og_sorted in foptionsgrid then begin + include(fstate1,gs1_gridsorted); + end + else begin + exclude(fstate1,gs1_gridsorted); + end; + if og_customsort in foptionsgrid then begin + include(fstate1,gs1_customsort); + end + else begin + exclude(fstate1,gs1_customsort); + end; + if (og_sorted in foptionsgrid) and not(og_sorted in optionsbefore) then begin + exclude(fstate1,gs1_sortvalid); + checksort(); + end; + end; +end; + +function tcustomgrid.scrollcaret(const vertical: boolean): boolean; +begin + result:= false; +end; + +procedure tcustomgrid.synctofontheight; +begin + inherited; + ffixrows.synctofontheight; +end; + +function tcustomgrid.internaldragevent(var info: draginfoty): boolean; +begin + result:= false; +end; + +procedure tcustomgrid.dragevent(var info: draginfoty); +var + bo1,bo2: boolean; + cell1: gridcoordty; +begin + cell1:= cellatpos(info.pos); + bo2:= isdatacell(cell1); + if not fdragcontroller.beforedragevent(info) then begin + if bo2 then begin + bo1:= false; + datacols[cell1.col].beforedragevent(info,cell1.row,bo1); + if not bo1 then begin + if not internaldragevent(info) then begin + inherited; + end; + end; + end + else begin + if not internaldragevent(info) then begin + inherited; + end; + end; + end; + if not fdragcontroller.afterdragevent(info) then begin + bo1:= false; + if bo2 then begin + datacols[cell1.col].afterdragevent(info,cell1.row,bo1); + end; + end; +end; + +function tcustomgrid.getdisprect: rectty; +begin + if (ffocusedcell.row = invalidaxis) and + (ffocusedcell.col = invalidaxis) then begin + result:= inherited getdisprect; + end + else begin + result:= cellrect(ffocusedcell); + addpoint1(result.pos,paintpos); + end; +end; + +procedure tcustomgrid.dofontheightdelta(var delta: integer); +begin + if ow1_autoscale in optionswidget1 then begin + ffixrows.dofontheightdelta(delta); + end; +end; + +procedure tcustomgrid.fontchanged; +begin + inherited; + fdatacols.fontchanged; + ffixrows.fontchanged; + ffixcols.fontchanged; +end; + +procedure tcustomgrid.setgridframecolor(const Value: colorty); +begin + if fgridframecolor <> value then begin + fgridframecolor := Value; + invalidate; + end; +end; +{ +procedure tcustomgrid.setgridframewidth(const Value: integer); +begin + if fgridframewidth <> value then begin + if componentstate * [csdesigning,csloading] = [csdesigning] then begin + with tframe1(fframe),fi.innerframe do begin + if right = self.fgridframewidth then begin + right:= value; + end; + if top = self.fgridframewidth then begin + top:= value; + end; + if left = self.fgridframewidth then begin + left:= value; + end; + if bottom = self.fgridframewidth then begin + bottom:= value; + end; + self.fgridframewidth := Value; + self.layoutchanged; + tframe1(fframe).updatestate; + end; + end + else begin + fgridframewidth := Value; + layoutchanged; + end; + end; +end; +} +function tcustomgrid.getmerged(const arow: integer): longword; +begin + result:= 0; + if (og_colmerged in foptionsgrid) and (arow >= 0) and + (arow < frowcount) then begin + result:= fdatacols.frowstate.getitempocolmerge(arow)^.colmerge.merged; + end; +end; + +function tcustomgrid.mergestart(const acol: integer; const arow: integer): integer; +var + int1: integer; + merged1: longword; +begin + result:= acol; + if acol >= 0 then begin + merged1:= getmerged(arow); + if merged1 <> 0 then begin + if merged1 = mergedcolall then begin + result:= 0; + end + else begin + if result < mergedcolmax then begin + result:= 0; + for int1:= acol - 1 downto 0 do begin + if merged1 and bits[int1] = 0 then begin + result:= int1 + 1; + break; + end; + end; + end; + end; + end; + end; +end; + +function tcustomgrid.mergeend(const acol: integer; const arow: integer): integer; +var + int1,int2: integer; + merged1: longword; +begin + result:= acol; + if acol >= 0 then begin + merged1:= getmerged(arow); + if merged1 <> 0 then begin + if merged1 = mergedcolall then begin + result:= fdatacols.count; + end + else begin + if (acol < mergedcolmax) and + ((acol = 0) or (merged1 and bits[acol-1] <> 0)) then begin + result:= fdatacols.count; + int2:= fdatacols.count - 1; + if int2 >= mergedcolmax then begin + int2:= mergedcolmax - 1; + end; + for int1:= acol to int2 do begin + if merged1 and bits[int1] = 0 then begin + result:= int1 + 1; + break; + end; + end; + end; + end; + end; + end; +end; + +procedure tcustomgrid.colstep(const action: focuscellactionty; + const step: integer; + const rowchange: boolean; const nocolwrap: boolean; + const noreadonly: boolean); +var + int1: integer; + row1: integer; + bo1: boolean; + finished: boolean; + act1: focuscellactionty; + step1: integer; + +begin + if fdatacols.count > 0 then begin + act1:= action; + step1:= step; + row1:= ffocusedcell.row; + int1:= ffocusedcell.col; + if int1 < 0 then begin + exit; + end; + finished:= true; + repeat + if step1 > 0 then begin + inc(int1); + finished:= int1 <= ffocusedcell.col; + int1:= mergeend(int1,row1); + finished:= finished and (int1 >= ffocusedcell.col); + if int1 >= fdatacols.count then begin + if nocolwrap then begin + exit; + end; + if rowchange then begin + inc(row1); + if act1 = fca_focusin then begin + act1:= fca_focusinforce; + end; + end; + int1:= 0; + finished:= int1 = ffocusedcell.col; + end; + if fdatacols[int1].canfocus(mb_none,[],noreadonly,bo1) then begin + dec(step1); + end; + end + else begin + dec(int1); + finished:= int1 >= ffocusedcell.col; + int1:= mergestart(int1,row1); + finished:= finished and (int1 <= ffocusedcell.col); + if int1 < 0 then begin + if nocolwrap then begin + exit; + end; + if rowchange then begin + dec(row1); + if act1 = fca_focusin then begin + act1:= fca_focusinforce; + end; + end; + int1:= mergestart(fdatacols.count - 1,row1); + finished:= int1 <= ffocusedcell.col; + end; + if fdatacols[int1].canfocus(mb_none,[],noreadonly,bo1) then begin + inc(step1); + end; + end; + if step1 = 0 then begin + if row1 < 0 then begin + row1:= rowcount-1; + end + else begin + if row1 >= rowcount then begin + if not (gs_isdb in fstate) and (og_autoappend in foptionsgrid) then begin + if fdatacols.rowempty(rowcount - 1) then begin + row1:= rowcount-1; + end + else begin + row1:= rowcount; + end; + end + else begin + row1:= 0; + end; + end; + end; + focuscell(makegridcoord(int1,row1),act1); + finished:= false; + break; + end; + until finished; //none found + if finished and noreadonly then begin + colstep(action,step,rowchange,nocolwrap,false); //try readonly + end; + end; +end; + +function tcustomgrid.nextfocusablecol(const acol: integer; + const aleft: boolean; const arow: integer; + const noreadonly: boolean): integer; +var + int1{,int2}: integer; + loopcount: integer; + bo1: boolean; + col1: integer; +begin + result:= -1; + col1:= acol; + if fdatacols.count > 0 then begin + if col1 > fdatacols.count then begin + col1:= fdatacols.count; + end; + if col1 < -1 then begin + col1:= -1; + end; + loopcount:= -1; + if aleft then begin + if col1 = fdatacols.count then begin + col1:= fdatacols.count - 1; + end; + int1:= col1; + repeat + if int1 < 0 then begin + int1:= fdatacols.count - 1; + inc(loopcount); + end; + int1:= mergestart(int1,arow); + if fdatacols[int1].canfocus(mb_none,[],noreadonly,bo1) then begin + result:= int1; + break; + end; + dec(int1); + until (int1 = col1) or (loopcount > 0); + end + else begin + if col1 < 0 then begin + col1:= 0; + end; + int1:= mergestart(col1,arow); + repeat + if int1 >= fdatacols.count then begin + int1:= 0; + inc(loopcount); + end; + if fdatacols[int1].canfocus(mb_none,[],noreadonly,bo1) then begin + result:= int1; + break; + end; + inc(int1); + int1:= mergeend(int1,arow); + until (int1 = col1) or (loopcount > 0); + end; + end; + if noreadonly and (result = -1) then begin + result:= nextfocusablecol(acol,aleft,arow,false); //try readonly cols + end; +end; + +procedure tcustomgrid.checkcellvalue(var accept: boolean); +begin + //dummy +end; + +function tcustomgrid.docheckcellvalue: boolean; +begin + result:= true; + if focusedcellvalid and (fnullchecking = 0) and + not(gs1_rowdeleting in fstate1) then begin + inc(fcellvaluechecking); + try + checkcellvalue(result); + finally + dec(fcellvaluechecking); + end; + end; +end; + +function tcustomgrid.internalsort(const sortfunc: indexsortcomparemethodty; + var refindex: integer): boolean; +var + ar1: integerarty; + bo1: boolean; + int1: integer; +begin + result:= false; + int1:= frowcount; + if int1 > 0 then begin + bo1:= not (gs_isdb in fstate) and (og_autoappend in foptionsgrid) and + fdatacols.rowempty(int1-1); + if bo1 then begin + dec(int1); //do not sort last row + end; + mergesort(int1,sortfunc,ar1,refindex,result); + if result then begin + if bo1 then begin + additem(ar1,int1); + end; + for int1:= 0 to fdatacols.count - 1 do begin + include(tdatacol(fdatacols.fitems[int1]).fstate,gps_noinvalidate); + end; + try + fdatacols.rearange(ar1); + finally + for int1:= 0 to fdatacols.count - 1 do begin + exclude(tdatacol(fdatacols.fitems[int1]).fstate,gps_noinvalidate); + end; + end; + ffixcols.rearange(ar1); + end; + end; +end; +(* +function tcustomgrid.internalsort(sortfunc: gridsorteventty; + var refindex: integer): boolean; + //true if rows moved, refindex is new indexpos +var + list: tintegerdatalist; + bewegt: boolean; + //todo: use merge sort + procedure quicksort(L, R: Integer); + var + I, J: Integer; + P, T: integer; + int1: integer; + begin + if r >= l then begin + repeat + I := L; + J := R; + P := list.items[(L + R) shr 1]; + repeat + repeat + int1:= 0; + sortfunc(self,List.items[I], P,int1); + if int1 = 0 then begin + int1:= list.items[i] - p; + end; + if int1 >= 0 then break; + inc(i); + until false; + repeat + int1:= 0; + sortfunc(self,List.items[j], P,int1); + if int1 = 0 then begin + int1:= list.items[j] - p; + end; + if int1 <= 0 then break; + dec(j); + until false; +// while (sortfunc(List.items[I], P,self) < 0) do Inc(I); +// while (sortfunc(List.items[J], P,self) > 0) do Dec(J); + if I <= J then + begin + if i <> j then begin + bewegt:= true; + T := List.items[I]; + List.items[I] := List.items[J]; + List.items[J] := T; + end; + Inc(I); + Dec(J); + end; + until I > J; + if L < J then QuickSort(L, J); + L := I; + until I >= R; + end; + end; + +var + int1: integer; + bo1: boolean; + +begin + bewegt:= false; + int1:= frowcount; + if int1 > 0 then begin + bo1:= not (gs_isdb in fstate) and (og_autoappend in foptionsgrid) and + fdatacols.rowempty(int1-1); + if bo1 then begin + dec(int1); //do not sort last row + end; + list:= tintegerdatalist.create; + try + list.count:= int1; + list.number(0,1); + quicksort(0,list.count-1); + if bewegt then begin + if bo1 then begin + list.add(int1); + end; + for int1:= 0 to fdatacols.count - 1 do begin + include(tdatacol(fdatacols.fitems[int1]).fstate,gps_noinvalidate); + end; + try + fdatacols.rearange(list); + finally + for int1:= 0 to fdatacols.count - 1 do begin + exclude(tdatacol(fdatacols.fitems[int1]).fstate,gps_noinvalidate); + end; + end; + ffixcols.rearange(list); + if refindex >= 0 then begin + for int1:= 0 to list.count-1 do begin //neue position bestimmen + if list.items[int1] = refindex then break; + end; + refindex:= int1; + end; + end; + finally + list.free; + end; + end; + result:= bewegt; +end; +*) + +procedure tcustomgrid.reorderrow; +var + lo,hi,pivot: integer; + sf: indexsortcomparemethodty; + bo1: boolean; +// int1: integer; + + function check(const a,b: integer): integer; + begin + result:= sf(a,b); + if result = 0 then begin + result:= a-b; + end; + end; //check + +begin + exclude(fstate1,gs1_rowsortinvalid); + if og_noreorderrow in foptionsgrid then begin + exclude(fstate1,gs1_sortvalid); + sort; + exit; + end; + if not (gs_isdb in fstate) then begin + if assigned(fonsort) then begin + sf:= {$ifdef FPC}@{$endif}doonsort; + end + else begin + sf:= {$ifdef FPC}@{$endif}fdatacols.sortfunc; + end; + if frowcount > 1 then begin + bo1:= true; + if row > 0 then begin + bo1:= sf(row-1,row) <= 0; + end; + if bo1 and (row < rowhigh) then begin + bo1:= sf(row+1,row) >= 0; + end; + if not bo1 then begin //position changed + lo:= 0; + hi:= rowhigh; + if check(hi,row) < 0 then begin //last? + lo:= hi; + end + else begin + if check(lo,row) > 0 then begin //first? + hi:= lo; + end + else begin + while hi-lo > 1 do begin + pivot:= (lo+hi) div 2; + if pivot = row then begin + if row - lo > hi-row then begin + dec(pivot); + end + else begin + inc(pivot); + end; + end; + if check(row,pivot) <= 0 then begin + hi:= pivot; + end + else begin + lo:= pivot; + end; + end; + end; + end; + bo1:= gs1_sortmoving in fstate1; + include(fstate1,gs1_sortmoving); + try + if row < lo then begin + moverow(row,lo); + end + else begin + moverow(row,hi); + end; + include(fstate1,gs1_sortvalid); + finally + if not bo1 then begin + exclude(fstate1,gs1_sortmoving); + end; + end; + end; + end; + end; +end; + +function tcustomgrid.getiassistiveclient(): iassistiveclient; +begin + result:= iassistiveclientgrid(self); +end; + +function tcustomgrid.getassistiveflags(): assistiveflagsty; +begin + result:= inherited getassistiveflags() + [asf_grid]; + if gs1_scrolllimit in fstate1 then begin + include(result,asf_scrolllimit); + end; +end; + +function tcustomgrid.getassistivecellcaption( + const acell: gridcoordty): msestring; +begin + result:= ''; + if isvalidcell(acell) then begin + if acell.row < 0 then begin + with fixrows[acell.row] do begin + if acell.col < 0 then begin + if -acell.col <= captionsfix.count then begin + result:= captionsfix[acell.col].caption; + end; + end + else begin + if acell.col < captions.count then begin + result:= captions[acell.col].caption; + end; + end; + end; + end; + end; +end; + +function tcustomgrid.getassistivecelltext(const acell: gridcoordty; + out aflags: assistiveflagsty): msestring; +begin + result:= ''; + aflags:= [asf_gridcell]; + if (acell.col >= 0) and (acell.col < datacols.count) then begin + if tdatacol(fdatacols.fitems[acell.col]).readonly then begin + include(aflags,asf_readonly); + end; + end; +end; + +function tcustomgrid.getassistivefocusedcell(): gridcoordty; +begin + result:= ffocusedcell; +end; + +function tcustomgrid.getassistivegridinfo(): assistivegridinfoty; +begin + with result do begin + colmin:= -fixcols.count; + colmax:= datacols.count-1; + rowmin:= -fixrows.count; + rowmax:= rowhigh; + end; +end; + +procedure tcustomgrid.sort; +var + bo1: boolean; + int1: integer; +begin + if gs_isdb in fstate then begin + include(fstate1,gs1_sortvalid); + exclude(fstate1,gs1_rowsortinvalid); + end + else begin + fdatacols.roworderinvalid; + beginupdate; + try + bo1:= factiverow = ffocusedcell.row; + for int1:= 0 to high(fdatacols.fitems) do begin + with tdatacol(fdatacols.fitems[int1]) do begin + if fdata <> nil then begin + tdatalist1(fdata).fgridsortdescend:= co_sortdescend in options; + end; + end; + end; + if assigned(fonsort) then begin + internalsort({$ifdef FPC}@{$endif}doonsort{fonsort},ffocusedcell.row); + end + else begin + internalsort({$ifdef FPC}@{$endif}fdatacols.sortfunc,ffocusedcell.row); + end; + if bo1 then begin + factiverow:= ffocusedcell.row; + end; + include(fstate1,gs1_sortvalid); + exclude(fstate1,gs1_rowsortinvalid); + layoutchanged; + finally + endupdate; + end; + if ffocusedcell.row >= 0 then begin + showcell(makegridcoord(invalidaxis,ffocusedcell.row)); + end; + end; +end; + +function tcustomgrid.copyselection: boolean; + //false if no copy +begin + result:= false; + if canevent(tmethod(foncopyselection)) then begin + foncopyselection(self,result); + end; +end; + +function tcustomgrid.pasteselection: boolean; + //false if no paste +begin + result:= false; + if canevent(tmethod(fonpasteselection)) then begin + fonpasteselection(self,result); + end; +end; + +function tcustomgrid.hascolumnsort: boolean; +begin + result:= (og_sorted in foptionsgrid) and + (assigned(fonsort) or (fdatacols.fsortcol >= 0) or + not (og_nodefaultsort in foptionsgrid)); +end; + +procedure tcustomgrid.sortchanged(const all: boolean); +begin + if not(csloading in componentstate) then begin + if assigned(fonsortchanged) then begin + fonsortchanged(self); + end; + if hascolumnsort and not (gs1_customsort in fstate1) then begin + if not all and (gs1_sortvalid in fstate1) and + (ffocusedcell.row >= 0) then begin + reorderrow; + end + else begin + sort; + end; + end + else begin + include(fstate1,gs1_sortvalid); + exclude(fstate1,gs1_rowsortinvalid); + invalidate; //for sort indicator + end; + end; +end; + +procedure tcustomgrid.sortinvalid(const acol: integer; const arow: integer); +begin + if not (gs1_sortchangelock in fstate1) and + ((acol < 0) or (fdatacols.fsortcol < 0) or + (acol = fdatacols.fsortcol) or + (acol = fdatacols.fsortcoldefault) or + assigned(fonsort)) then begin + if ((arow < 0) or (arow <> ffocusedcell.row)) then begin + exclude(fstate1,gs1_sortvalid); + end + else begin + include(fstate1,gs1_rowsortinvalid); + end; + end; +end; + +function tcustomgrid.checksort: boolean; +begin + result:= false; + if (fstate1 * [gs1_sortvalid,gs1_rowsortinvalid] <> [gs1_sortvalid]) and + not (gs1_sortchangelock in fstate1) and (fupdating = 0) then begin + sortchanged(false); + result:= true; + end; +end; + +procedure tcustomgrid.setrowcolors(const Value: tcolorarrayprop); +begin + frowcolors.assign(Value); +end; + +procedure tcustomgrid.setrowfonts(const Value: trowfontarrayprop); +begin + frowfonts.assign(Value); +end; + +function tcustomgrid.checkrowindex(var aindex: integer): boolean; +begin + if aindex < 0 then begin + if aindex = -1 then begin + aindex:= ffocusedcell.row; + end; + end; + result:= aindex >= 0; +end; + +function tcustomgrid.getrowcolorstate(index: integer): rowstatenumty; +begin + if checkrowindex(index) then begin + result:= fdatacols.frowstate.color[index]; + end + else begin + result:= -1; + end; +end; + +procedure tcustomgrid.setrowcolorstate(index: integer; const Value: rowstatenumty); +begin + if checkrowindex(index) then begin + fdatacols.frowstate.color[index]:= value; + rowchanged(index); + rowstatechanged(index); + end; +end; + +function tcustomgrid.getrowlinecolorstate(index: integer): rowstatenumty; +begin + if checkrowindex(index) then begin + result:= fdatacols.frowstate.linecolor[index]; + end + else begin + result:= -1; + end; +end; + +procedure tcustomgrid.setrowlinecolorstate(index: integer; const Value: rowstatenumty); +begin + if checkrowindex(index) then begin + fdatacols.frowstate.linecolor[index]:= value; + rowchanged(index); + rowstatechanged(index); + end; +end; + +function tcustomgrid.getrowlinecolorfixstate(index: integer): rowstatenumty; +begin + if checkrowindex(index) then begin + result:= fdatacols.frowstate.linecolorfix[index]; + end + else begin + result:= -1; + end; +end; + +procedure tcustomgrid.setrowlinecolorfixstate(index: integer; + const Value: rowstatenumty); +begin + if checkrowindex(index) then begin + fdatacols.frowstate.linecolorfix[index]:= value; + rowchanged(index); + rowstatechanged(index); + end; +end; + +function tcustomgrid.getrowlinewidth(index: integer): rowlinewidthty; +begin + if checkrowindex(index) then begin + result:= fdatacols.frowstate.linewidth[index]; + end + else begin + result:= fdatarowlinewidth; + end; +end; + +procedure tcustomgrid.setrowlinewidth(index: integer; + const avalue: rowlinewidthty); +begin + if checkrowindex(index) then begin + fdatacols.frowstate.linewidth[index]:= avalue; + end; +end; + +function tcustomgrid.getrowfontstate(index: integer): rowstatenumty; +begin + if checkrowindex(index) then begin + result:= fdatacols.frowstate.font[index]; + end + else begin + result:= -1; + end; +end; + +procedure tcustomgrid.setrowfontstate(index: integer; const Value: rowstatenumty); +begin + if checkrowindex(index) then begin + fdatacols.frowstate.font[index]:= value; + rowchanged(index); + rowstatechanged(index); + end; +end; + +function tcustomgrid.getrowreadonlystate(index: integer): boolean; +begin + if checkrowindex(index) then begin + result:= fdatacols.frowstate.readonly[index]; + end + else begin + result:= false; + end; +end; + +procedure tcustomgrid.setrowreadonlystate(index: integer; + const avalue: boolean); +begin + if checkrowindex(index) then begin + fdatacols.frowstate.readonly[index]:= avalue; + if index = row then begin + checkrowreadonlystate; + end; + rowstatechanged(index); + end; +end; + + +function tcustomgrid.getrowhidden(index: integer): boolean; +begin + if checkrowindex(index) then begin + result:= fdatacols.frowstate.hidden[index]; + end + else begin + result:= false; + end; +end; + +procedure tcustomgrid.setrowhidden(index: integer; const avalue: boolean); +begin + if checkrowindex(index) then begin + fdatacols.frowstate.hidden[index]:= avalue; + end; +end; + +function tcustomgrid.getrowfoldlevel(index: integer): byte; +begin + if checkrowindex(index) then begin + result:= fdatacols.frowstate.foldlevel[index]; + end + else begin + result:= 0; + end; +end; + +procedure tcustomgrid.setrowfoldlevel(index: integer; const avalue: byte); +begin + if checkrowindex(index) then begin + fdatacols.frowstate.foldlevel[index]:= avalue; + end; +end; + +function tcustomgrid.getrowfoldissum(index: integer): boolean; +begin + if checkrowindex(index) then begin + result:= fdatacols.frowstate.foldissum[index]; + end + else begin + result:= false; + end; +end; + +procedure tcustomgrid.setrowfoldissum(index: integer; const avalue: boolean); +begin + if checkrowindex(index) then begin + fdatacols.frowstate.foldissum[index]:= avalue; + end; +end; + +function tcustomgrid.getrowheight(index: integer): integer; +begin + if checkrowindex(index) then begin + result:= fdatacols.frowstate.height[index]; + end + else begin + result:= 0; + end; +end; + +procedure tcustomgrid.setrowheight(index: integer; avalue: integer); +begin + if checkrowindex(index) then begin + if (avalue <> 0) and (avalue < fdatarowheightmin) then begin + avalue:= fdatarowheightmin; + end + else begin + if avalue > fdatarowheightmax then begin + avalue:= fdatarowheightmax; + end; + end; + fdatacols.frowstate.height[index]:= avalue; + end; +end; + +function tcustomgrid.rowfoldinfo: prowfoldinfoty; + //nil if focused row not visible +var + int1: integer; +begin //todo: optimize + result:= nil; + if row >= 0 then begin + internalupdatelayout; + if (fvisiblerowfoldinfo <> nil) and (row >= fvisiblerows[0]) and + (row <= fvisiblerows[high(fvisiblerows)]) then begin + for int1:= 0 to high(fvisiblerows) do begin + if fvisiblerows[int1] = row then begin + result:= @fvisiblerowfoldinfo[int1]; + break; + end; + end; + end; + end; +end; + +procedure tcustomgrid.checkrowreadonlystate; +begin + if (row >= 0) and rowreadonlystate[row] then begin + include(fstate,gs_rowreadonly); + end + else begin + exclude(fstate,gs_rowreadonly); + end; +end; + +procedure tcustomgrid.checkneedsrowheight; +var + int1: integer; + bo1: boolean; +begin + if not (csloading in componentstate) then begin + bo1:= gs_needsrowheight in fstate; + exclude(fstate,gs_needsrowheight); + with fdatacols do begin + for int1:= 0 to count -1 do begin + if gps_needsrowheight in tgridprop(pointerarty(fitems)[int1]).fstate then begin + include(self.fstate,gs_needsrowheight); + if not bo1 and (frowcount > 0) then begin + fdatacols.rowstate.change(-1); + end; + break; + end; + end; + end; + end; +end; + +procedure tcustomgrid.updaterowheight(const arow: integer; + var arowheight: integer); +begin + fdatacols.updaterowheight(arow,arowheight); +// ffixcols.updaterowheight(arow,arowheight); not used up to now +end; + +procedure tcustomgrid.setdragcontroller(const avalue: tdragcontroller); +begin + fdragcontroller.assign(avalue); +end; + +procedure tcustomgrid.setzebra_color(const avalue: colorty); +begin + if fzebra_color <> avalue then begin + fzebra_color:= avalue; + invalidate; + end; +end; + +procedure tcustomgrid.setzebra_start(const avalue: integer); +begin + if fzebra_start <> avalue then begin + fzebra_start:= avalue; + invalidate; + end; +end; + +procedure tcustomgrid.setzebra_height(const avalue: integer); +begin + if fzebra_height <> avalue then begin + fzebra_height:= avalue; + invalidate; + end; +end; + +procedure tcustomgrid.setzebra_step(const avalue: integer); +begin + if fzebra_step <> avalue then begin + fzebra_step:= avalue; + invalidate; + end; +end; + +function tcustomgrid.appinsrow(aindex: integer; + const auserinput: boolean = false): int32; +var + int1,int2: integer; + bo1: boolean; +begin + result:= invalidaxis; + if docheckcellvalue and container.canclose(window.focusedwidget) then begin + //for not null check in twidgetgrid + int1:= ffocusedcell.row; + checksort; + aindex:= aindex+ffocusedcell.row-int1; + if aindex < 0 then begin + aindex:= 0; + end; + if aindex > rowcount then begin + aindex:= rowcount; + end; + bo1:= gs1_sortchangelock in fstate1; + include(fstate1,gs1_sortchangelock); + try + int2:= 1; + internalinsertrow(aindex,int2,auserinput); + if int2 = 0 then begin + exit; + end; + if fdatacols.fnewrowcol < 0 then begin + int1:= ffocusedcell.col; + end + else begin + int1:= fdatacols.fnewrowcol; + end; + finally + if not bo1 then begin + exclude(fstate1,gs1_sortchangelock); + end; + end; + focuscell(makegridcoord(int1,aindex)); + if ffocusedcell.row = aindex then begin + fstate1:= fstate1 + [gs1_rowsortinvalid,gs1_rowinserted]; + end; + result:= aindex; + end; +end; + +procedure tcustomgrid.doinsertrow(const sender: tobject); +//var +// int1: integer; +begin + appinsrow(ffocusedcell.row,true); +end; + +procedure tcustomgrid.doappendrow(const sender: tobject); +var + bo1: boolean; +begin + bo1:= gs_appending in fstate; + include(fstate,gs_appending); + try + appinsrow(ffocusedcell.row+1,true); + finally + if not bo1 then begin + exclude(fstate,gs_appending); + end; + end; +end; + +function tcustomgrid.deleterowconfirmation(): boolean; +begin + with stockobjects do begin + result:= (og1_norowdeletequery in foptionsgrid1) or + askok(captions[sc_Delete_row_question],captions[sc_Confirmation]); + end; +end; + +procedure tcustomgrid.dodeleterow(const sender: tobject); +begin + if deleterowconfirmation() then begin + deleterow(ffocusedcell.row,1,true); + end; +end; + +procedure tcustomgrid.dodeleteselectedrows(const sender: tobject); +var + ar1: integerarty; + int1: integer; +begin + ar1:= fdatacols.getselectedrows; + if high(ar1) >= 0 then begin + if askok(stockobjects.textgenerators[tg_delete_n_selected_rows]( + [integer(length(ar1))]), + stockobjects.captions[sc_Confirmation]) then begin + beginupdate; + try + for int1:= high(ar1) downto 0 do begin + deleterow(ar1[int1],1,true); + end; + finally + endupdate; + end; + end; + end; +end; + +procedure tcustomgrid.dodeleterows(const sender: tobject); +begin + if (og_selectedrowsdeleting in foptionsgrid) and + (high(fdatacols.getselectedrows) >= 0) then begin + dodeleteselectedrows(sender); + end + else begin + if (og_rowdeleting in foptionsgrid) and (ffocusedcell.row >= 0) then begin + dodeleterow(sender); + end; + end; +end; + +procedure tcustomgrid.docopycells(const sender: tobject); +begin + copyselection; +end; + +procedure tcustomgrid.dopastecells(const sender: tobject); +begin + pasteselection; +end; + +function tcustomgrid.endanchor: gridcoordty; +begin + result:= fendanchor; +end; + +function tcustomgrid.startanchor: gridcoordty; +begin + result:= fstartanchor; +end; + +procedure tcustomgrid.beginnullchecking; +begin + inc(fnullchecking); +end; + +procedure tcustomgrid.endnullchecking; +begin + dec(fnullchecking); +end; + +procedure tcustomgrid.beginnonullcheck; +begin + inc(fnonullcheck); +end; + +procedure tcustomgrid.endnonullcheck; +begin + dec(fnonullcheck); +end; + +procedure tcustomgrid.beginnocheckvalue; +begin + inc(fnocheckvalue); +end; + +procedure tcustomgrid.endnocheckvalue; +begin + dec(fnocheckvalue); +end; + +function tcustomgrid.nocheckvalue: boolean; +begin + result:= fnocheckvalue > 0; +end; + +function tcustomgrid.cellclicked: boolean; +begin + result:= gs_cellclicked in fstate; +end; + +function tcustomgrid.cellvisible(const acell: gridcoordty): boolean; +var + int1: integer; +begin + result:= false; + if acell.col >= 0 then begin + if acell.col < fdatacols.count then begin + result:= fdatacols[acell.col].visible; + end; + end + else begin + int1:= - acell.col - 1; + if int1 < ffixcols.count then begin + result:= tfixcol(ffixcols.fitems[int1]).visible; + end; + end; + if result then begin + if acell.row < 0 then begin + int1:= -acell.row - 1; + if int1 < ffixrows.count then begin + result:= tfixrow(ffixrows.fitems[int1]).visible; + end + else begin + result:= false; + end; + end + else begin + result:= acell.row < frowcount; + end; + end; +end; + +procedure tcustomgrid.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if event = oe_changed then begin //todo: optimize + fdatacols.checktemplate(sender); + ffixcols.checktemplate(sender); + ffixrows.checktemplate(sender); + end; +end; + +procedure tcustomgrid.focuscolbyname(const aname: string); +var + col1: tdatacol; +begin + col1:= fdatacols.colbyname(aname); + if col1 <> nil then begin + col:= col1.index; + if not entered then begin + setfocus; + end; + end; +end; + +function tcustomgrid.getdragrect(const apos: pointty): rectty; +var + cell1: gridcoordty; +begin + cell1:= cellatpos(apos); + if isdatacell(cell1) then begin + result:= cellrect(cell1); + end + else begin + result:= inherited getdragrect(apos); + end; +end; + +procedure tcustomgrid.updaterowdata; +begin + //dummy +end; + +function tcustomgrid.getsorted: boolean; +begin + result:= og_sorted in optionsgrid; +end; + +procedure tcustomgrid.setsorted(const avalue: boolean); +begin + if avalue then begin + optionsgrid:= optionsgrid + [og_sorted]; + end + else begin + optionsgrid:= optionsgrid - [og_sorted]; + end; +end; + +function tcustomgrid.getfolded: boolean; +begin + result:= og_folded in optionsgrid; +end; + +procedure tcustomgrid.setfolded(const avalue: boolean); +begin + if avalue then begin + optionsgrid:= optionsgrid + [og_folded]; + end + else begin + optionsgrid:= optionsgrid - [og_folded]; + end; +end; + +function tcustomgrid.getrowstatelist: trowstatelist; +begin + result:= fdatacols.frowstate; +end; + +procedure tcustomgrid.setrowstatelist(const avalue: trowstatelist); +begin + fdatacols.frowstate.assign(avalue); +end; + +function tcustomgrid.updating: boolean; +begin + result:= fupdating > 0; +end; + +{$ifdef mse_with_ifi} + +procedure tcustomgrid.ifirowchange; +begin + if (fupdating = 0) and (fifiserverintf <> nil) and + not(ws_loadedproc in fwidgetstate) then begin + iifidataserver(fifiserverintf).valuechanged(iifigridlink(self)); + end; +end; + +function tcustomgrid.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iifigridlink); +end; + +function tcustomgrid.getrowstate: tcustomrowstatelist; +begin + result:= fdatacols.frowstate; +end; + +procedure tcustomgrid.setifilink(const avalue: tifigridlinkcomp); +begin + mseificomp.setifilinkcomp(iifigridlink(self),avalue,tifilinkcomp(fifilink)); +end; + +procedure tcustomgrid.updateifigriddata(const sender: tobject; + const alist: tdatalist); +begin + //dummy +end; + +function tcustomgrid.getgriddata: tdatalist; +begin + result:= nil; +end; + +function tcustomgrid.getvalueprop: ppropinfo; +begin + result:= nil; +end; + +procedure tcustomgrid.getifivalue(var avalue); +begin + //dummy +end; + +procedure tcustomgrid.setifivalue(const avalue); +begin + //dummy +end; + +procedure tcustomgrid.updatereadonlystate; +begin + //dummy +end; + +{$endif} + +function tcustomgrid.hassort: boolean; +begin + result:= fstate1 * [gs1_gridsorted,gs1_dbsorted] <> []; +end; + +function tcustomgrid.updatesortcol(const avalue: integer): integer; +begin + result:= avalue; +end; + +function tcustomgrid.getsortdescend(const acol: integer): boolean; +begin + result:= false; + if (acol >= 0) and (acol < fdatacols.count) then begin + result:= co_sortdescend in tdatacol(fdatacols.fitems[acol]).foptions; + end; +end; + +function tcustomgrid.cellhasfocus: boolean; +begin + result:= entered; +end; + +function tcustomgrid.doonsort(const l,r: integer): integer; +begin + result:= 0; + fonsort(self,l,r,result); +end; + +procedure tcustomgrid.readgridframewidth(reader: treader); +var + int1: integer; +begin + int1:= reader.readinteger; + fframe.framei_right:= int1; + fframe.framei_top:= int1; + fframe.framei_left:= int1; + fframe.framei_bottom:= int1; +end; + +function tcustomgrid.getcellwindowpos: pointty; +var + rect1: rectty; +begin + if focusedcellvalid() then begin + internalupdatelayout; + rect1:= cellrect(focusedcell); + result:= subpoint(rect1.pos,fdatarect.pos); + end + else begin + result:= nullpoint; + end; +end; + +procedure tcustomgrid.setcellwindowpos(const avalue: pointty); +var + rect1: rectty; +begin + if focusedcellvalid() then begin + internalupdatelayout; + rect1:= cellrect(focusedcell); + subpoint1(rect1.pos,fdatarect.pos); //current distance + tgridframe(fframe).scrollpos:= addpoint(tgridframe(fframe).scrollpos, + subpoint(avalue,rect1.pos)); + end; +end; + +function tcustomgrid.getrowwindowpos: int32; +begin + result:= getcellwindowpos.y; +end; + +procedure tcustomgrid.setrowwindowpos(const avalue: int32); +begin + setcellwindowpos(mp(getcolwindowpos,avalue)); +end; + +function tcustomgrid.getcolwindowpos: int32; +begin + result:= getcellwindowpos.x; +end; + +procedure tcustomgrid.setcolwindowpos(const avalue: int32); +begin + setcellwindowpos(mp(avalue,getrowwindowpos)); +end; + +procedure tcustomgrid.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('gridframewidth',{$ifdef FPC}@{$endif}readgridframewidth, + nil,false); +end; + +procedure tcustomgrid.resetuserinput(const avalue: boolean); +begin + if avalue then begin + include(fstate1,gs1_userinput); + end + else begin + exclude(fstate1,gs1_userinput); + end; +end; + +function tcustomgrid.setuserinput(const avalue: boolean): boolean; +begin + result:= gs1_userinput in fstate1; + resetuserinput(avalue); +end; + +function tcustomgrid.userinput: boolean; +begin + result:= gs1_userinput in fstate1; +end; + +procedure tcustomgrid.dorowsmodified; +begin + if userinput and canevent(tmethod(fonrowsmodified)) then begin + fonrowsmodified(self); + end; +end; + +procedure tcustomgrid.doedited(); +begin + if canevent(tmethod(fonedited)) then begin + fonedited(self); + end; +end; + +function tcustomgrid.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +{ tdrawgrid } + +function tdrawgrid.createdatacols: tdatacols; +begin + result:= tdrawcols.create(self); +end; + +function tdrawgrid.getdatacols: tdrawcols; +begin + result:= tdrawcols(fdatacols); +end; + +procedure tdrawgrid.setdatacols(const value: tdrawcols); +begin + fdatacols.assign(value); +end; + +function tdrawgrid.getcols(index: integer): tdrawcol; +begin + result:= tdrawcol(fdatacols[index]); +end; + +procedure tdrawgrid.setcols(index: integer; const avalue: tdrawcol); +begin + tdrawcol(fdatacols[index]).assign(avalue); +end; + +{ tcellgrid } + +procedure tcellgrid.clientmouseevent(var info: mouseeventinfoty); +var + bo1,bo2: boolean; +begin + bo1:= es_child in info.eventstate; + bo2:= gs_cellclicked in fstate; + if bo2 and (info.shiftstate * keyshiftstatesmask = []) then begin + include(info.eventstate,es_child); + end; + inherited; + if not bo1 then begin + exclude(info.eventstate,es_child); + end; +end; + +{ tcustomstringgrid } + +constructor tcustomstringgrid.create(aowner: tcomponent); +begin + inherited; + feditor:= tinplaceedit.create(self,iedit(self)); +end; + +destructor tcustomstringgrid.destroy; +begin + inherited; + feditor.free; +end; + +function tcustomstringgrid.createdatacols: tdatacols; +begin + result:= tstringcols.create(self); +end; + +function tcustomstringgrid.getcols(index: integer): tstringcol; +begin + result:= tstringcol(fdatacols[index]); +end; + +procedure tcustomstringgrid.setcols(index: integer; const Value: tstringcol); +begin + fdatacols[index].Assign(value); +end; + +function tcustomstringgrid.getdatacols: tstringcols; +begin + result:= tstringcols(fdatacols); +end; + +procedure tcustomstringgrid.setdatacols(const value: tstringcols); +begin + fdatacols.assign(value); +end; + +procedure tcustomstringgrid.drawfocusedcell(const canvas: tcanvas); +var + po1: pointty; + rect1: rectty; + int1: integer; +begin + with cellinfoty(canvas.drawinfopo^) do begin + if scoe_checkbox in tcustomstringcol( + fdatacols.fitems[ffocusedcell.col]).foptionsedit then begin + inherited; + end + else begin + if calcautocellsize then begin + rect1:= feditor.textrect; + int1:= rect.cx - innerrect.cx + rect1.cx; + if int1 > autocellsize.cx then begin + autocellsize.cx:= int1; + end; + int1:= rect.cy - innerrect.cy + rect1.cy; + if int1 > autocellsize.cy then begin + autocellsize.cy:= int1; + end; + end + else begin + drawcellbackground(canvas); + po1:= cellrect(ffocusedcell,cil_paint).pos; + canvas.remove(po1); + feditor.dopaint(canvas); + canvas.move(po1); + end; + end; + end; +end; + +procedure tcustomstringgrid.doselectionchanged; +begin + if isdatacell(focusedcell) then begin + feditor.font:= fdatacols[ffocusedcell.col].rowfont(ffocusedcell.row) + end; + inherited; +end; + +procedure tcustomstringgrid.updatepopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); +begin + if isdatacell(ffocusedcell) and (oe1_autopopupmenu in + tcustomstringcol(fdatacols.fitems[ffocusedcell.col]). + foptionsedit1) then begin + feditor.updatepopupmenu(amenu,popupmenu,mouseinfo,false); + end; + inherited; +end; + +function tcustomstringgrid.getassistivecaretindex(): int32; +begin + result:= feditor.curindex; +end; + +function tcustomstringgrid.getassistivecelltext(const acell: gridcoordty; + out aflags: assistiveflagsty): msestring; +begin + result:= inherited getassistivecelltext(acell,aflags); + include(aflags,asf_textedit); + if isdatacell(acell) then begin + result:= self[acell.col].getrowtext(acell.row); + end; +end; + +procedure tcustomstringgrid.setupeditor(const acell: gridcoordty; + const focusin: boolean); +var + col1: tcustomstringcol; + mstr1: msestring; + int1: integer; +begin + col1:= tcustomstringcol(fdatacols[acell.col]); + mstr1:= col1.getrowtext(acell.row); + col1.updatedisptext(mstr1); + int1:= 0; + if not focusin then begin + int1:= feditor.curindex; + end; + feditor.optionsedit1:= col1.foptionsedit1; + feditor.setup(mstr1,int1,not focusin,cellrect(acell,cil_inner), + cellrect(acell,cil_paint),nil,nil, + fdatacols[acell.col].rowfont(acell.row)); + feditor.textflags:= col1.textflags; + feditor.textflagsactive:= col1.ftextflagsactive; + feditor.passwordchar:= col1.passwordchar; + if scoe_checkbox in tcustomstringcol(fdatacols.fitems[acell.col]).optionsedit then begin + feditor.dodefocus; + end + else begin + if focusin then begin + feditor.dofocus; + end; + if active then begin + feditor.doactivate; + end; + end; +end; + +procedure tcustomstringgrid.rowstatechanged(const arow: integer); +begin + inherited; + if (arow = ffocusedcell.row) and (ffocusedcell.col >= 0) then begin + feditor.font:= fdatacols[ffocusedcell.col].rowfont(ffocusedcell.row) + end; +end; + +procedure tcustomstringgrid.dofocusedcellposchanged; +begin + inherited; + if ffocusedcell.col >= 0 then begin + feditor.updatepos(cellrect(ffocusedcell,cil_inner), + cellrect(ffocusedcell,cil_paint)); + end; +end; + +procedure tcustomstringgrid.focusedcellchanged; +begin + inherited; + setupeditor(ffocusedcell,true); +end; + +procedure tcustomstringgrid.checkrowreadonlystate; +begin + inherited; + if isdatacell(ffocusedcell) then begin + feditor.updatecaret; + end; +end; + +procedure tcustomstringgrid.docellevent(var info: celleventinfoty); +begin + inherited; + with info do begin + case eventkind of + cek_enter: begin + setupeditor(newcell,true); + end; + cek_exit: begin + feditor.dodefocus; + end; + end; + end; +end; + +procedure tcustomstringgrid.scrolled(const dist: pointty); +var + po1: pointty; +begin + inherited; + if focusedcellvalid then begin + po1:= dist; + if not scrollingcol then begin + po1.x:= 0; + end; + feditor.scroll(po1); + end; +end; + +procedure tcustomstringgrid.firstcellclick(const cell: gridcoordty; + var info: mouseeventinfoty); +begin + inherited; + feditor.setfirstclick(info); +end; + +procedure tcustomstringgrid.clientmouseevent(var info: mouseeventinfoty); +var + bo2: boolean; +begin + bo2:= gs_cellclicked in fstate; + inherited; + if (not (es_processed in info.eventstate) or (es_drag in info.eventstate)) and + focusedcellvalid and + (info.eventkind in mouseposevents) and + (gridcoordisequal(ffocusedcell,fmousecell) or bo2) and + not (scoe_checkbox in tcustomstringcol( + fdatacols.fitems[ffocusedcell.col]).optionsedit) then begin + feditor.mouseevent(info); + end; +end; + +procedure tcustomstringgrid.doactivate; +begin + if focusedcellvalid and + not (scoe_checkbox in tcustomstringcol( + fdatacols.fitems[ffocusedcell.col]).optionsedit) then begin + feditor.doactivate; + + end; + inherited; +end; + +procedure tcustomstringgrid.dodeactivate; +begin + if focusedcellvalid then begin + feditor.dodeactivate; + end; + inherited; +end; + +procedure tcustomstringgrid.dokeydown(var info: keyeventinfoty); +begin + if focusedcellvalid and not (scoe_checkbox in tcustomstringcol( + fdatacols.fitems[ffocusedcell.col]).optionsedit) then begin + feditor.dokeydown(info); + end; + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +function tcustomstringgrid.copyselection: boolean; +var + ar1: gridcoordarty; + wstr1: msestring; + int1,int2: integer; +begin + result:= inherited copyselection; + if result then begin + exit; + end; + ar1:= nil; //compiler waring + ar1:= datacols.selectedcells; + if ar1 <> nil then begin + wstr1:= ''; + int2:= ar1[0].row; + for int1:= 0 to high(ar1) do begin + if ar1[int1].row <> int2 then begin + removetabterminator(wstr1); + wstr1:= wstr1 + lineend; + int2:= ar1[int1].row; + end; + if co_cancopy in datacols[ar1[int1].col].foptions then begin + wstr1:= wstr1 + self.items[ar1[int1]] + c_tab; + end; + end; + removetabterminator(wstr1); + wstr1:= wstr1 + lineend; //terminator + msewidgets.copytoclipboard(wstr1); + result:= true; + end; +end; + +function tcustomstringgrid.pasteselection: boolean; +var + wstr1: msestring; + int1,int2,int3,int5: integer; + ar4,ar5: msestringarty; + ar1: gridcoordarty; + bo2: boolean; +begin + result:= inherited pasteselection; + if result = true then begin + exit; + end; + ar4:= nil; //compiler warning + ar5:= nil; //compiler warning + if fdatacols.canpaste{bo1} and pastefromclipboard(wstr1) then begin + ar4:= breaklines(wstr1); + bo2:= high(ar4) > 0; + if high(ar4) >= 0 then begin + if ar4[high(ar4)] = '' then begin + setlength(ar4,high(ar4)); //remove terminator + end; + beginupdate; + try + if (og1_pasteinselection in optionsgrid1) and (high(ar4) = 0) and + datacols.hasselection and (findchar(ar4[0],c_tab) = 0) then begin + ar1:= datacols.selectedcells; + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + datacols[col][row]:= ar4[0]; + end; + end; + end + else begin + if not bo2 then begin + exit; + end; + int5:= row; + if int5 < 0 then begin + int5:= 0; + end; + datacols.clearselection; + // int1:= row; + bo2:= og_rowinserting in optionsgrid; + if bo2 then begin + insertrow(int5,length(ar4)); + end; + if high(ar4) >= rowcount - int5 then begin + setlength(ar4,rowcount-int5); + end; + // for int2:= int1 to int1 + high(ar4) do begin + // end; + for int1:= 0 to high(ar4) do begin + if bo2 then begin + datacols.selected[makegridcoord(invalidaxis,int5)]:= true; + end; + ar5:= splitstring(ar4[int1],c_tab); + int3:= 0; + for int2:= 0 to high(ar5) do begin + while (int3 < datacols.count) and + not (co_canpaste in datacols[int3].options) do begin + inc(int3); + end; + if int3 >= datacols.count then begin + break; + end; + if not bo2 then begin + datacols[int3].selected[int5]:= true; + end; + datacols[int3][int5]:= ar5[int2]; + inc(int3); + end; + inc(int5); + end; + end; + finally + endupdate; + end; + result:= true; + end; + end; +end; + +procedure tcustomstringgrid.editnotification(var info: editnotificationinfoty); +var + frame1: framety; + bo1: boolean; +begin + if focusedcellvalid then begin + with tcustomstringcol(fdatacols[ffocusedcell.col]) do begin + case info.action of + ea_textedited: begin + modified; + self.doedited(); + end; + ea_textentered: begin + bo1:= true; + if (gps_edited in fstate) or + (scoe_forcereturncheckvalue in foptionsedit) then begin + include(fstate,gps_edited); + bo1:= docheckcellvalue; + if scoe_eatreturn in foptionsedit then begin + info.action:= ea_none; + end; + end; + if bo1 and + (og_colchangeonreturnkey in fcellinfo.grid.optionsgrid) then begin + info.action:= ea_none; + self.colstep(fca_focusin,1,true,false,true); + end; + end; + ea_undo: begin + exclude(fstate,gps_edited); + end; + ea_caretupdating: begin + if not (gs_layoutupdating in self.fstate) then begin + frame1:= nullframe; + if fframe <> nil then begin + frame1:= fframe.innerframe; + end + else begin + frame1.left:= fcellinfo.innerrect.x; + end; + addpoint1(info.caretrect.pos, + showcaretrect(info.caretrect,frame1)); + end; + end; + end; + end; + end; +end; + +procedure tcustomstringgrid.dofontheightdelta(var delta: integer); +begin + inherited; + if ow1_autoscale in foptionswidget1 then begin + datarowheight:= datarowheight + delta; + end; +end; + +procedure tcustomstringgrid.checkcellvalue(var accept: boolean); +var + mstr1: msestring; + strcol: tcustomstringcol; +begin + if isdatacell(ffocusedcell) + and not (oe_readonly in feditor.optionsedit) then begin + strcol:= datacols[ffocusedcell.col]; + if gps_edited in strcol.fstate then begin + mstr1:= feditor.text; + strcol.checkcellvalue(mstr1,accept); + feditor.dofocus; + end; + end; +end; + +procedure tcustomstringgrid.rootchanged(const aflags: rootchangeflagsty); +begin + inherited; + feditor.poschanged; +end; + +procedure tcustomstringgrid.updatelayout; +var + rect2: rectty; +begin + inherited; + if focusedcellvalid then begin + rect2:= cellrect(ffocusedcell,cil_inner); + feditor.updatepos(rect2,rect2); + end; +end; + +function tcustomstringgrid.getoptionsedit: optionseditty; +begin + result:= [oe_exitoncursor]; + with tcustomstringcol(fdatacols[ffocusedcell.col]) do begin + if (ffocusedcell.col < 0) or isreadonly{(co_readonly in foptions)} then begin + include(result,oe_readonly); + end; + result:= result + getoptionsedit; +// stringcoltooptionsedit(foptionsedit,result); + end; +end; + +procedure tcustomstringgrid.updatecopytoclipboard(var atext: msestring); +var + col1: tcustomstringcol; +begin + col1:= tcustomstringcol(fdatacols[ffocusedcell.col]); + with col1 do begin + if canevent(tmethod(foncopytoclipboard)) then begin + foncopytoclipboard(col1,atext); + end; + end; +end; + +procedure tcustomstringgrid.updatepastefromclipboard(var atext: msestring); +var + col1: tcustomstringcol; +begin + col1:= tcustomstringcol(fdatacols[ffocusedcell.col]); + with col1 do begin + if canevent(tmethod(fonpastefromclipboard)) then begin + fonpastefromclipboard(col1,atext); + end; + end; +end; + + +function tcustomstringgrid.hasselection: boolean; +begin + result:= false; +end; + +function tcustomstringgrid.getitems(const cell: gridcoordty): msestring; +begin + result:= cols[cell.col][cell.row]; +end; + +procedure tcustomstringgrid.setitems(const cell: gridcoordty; const Value: msestring); +begin + cols[cell.col][cell.row]:= value; +end; + +function tcustomstringgrid.getcaretwidth: integer; +begin + result:= feditor.caretwidth; +end; + +procedure tcustomstringgrid.setcaretwidth(const value: integer); +begin + tinplaceedit1(feditor).fcaretwidth:= value; +end; + +procedure tcustomstringgrid.synctofontheight; +begin + inherited; + datarowheight:= datacols.defaultrowheight(); + { + if ow1_fontlineheight in optionswidget1 then begin + datarowheight:= font.lineheight; + end + else begin + with fdatacols.finnerframe do begin + datarowheight:= font.glyphheight + top + bottom; + end; + end; + } +end; + +function tcustomstringgrid.textclipped(const acell: gridcoordty; + out acellrect: rectty): boolean; +var + rect2: rectty; + canvas1: tcanvas; +begin + result:= isdatacell(acell); + if result then begin + acellrect:= clippedcellrect(acell,cil_inner); + canvas1:= getcanvas; + with datacols[acell.col] do begin + rect2:= textrect(canvas1,getrowtext(acell.row),acellrect,textflags,font); + end; + result:= not rectinrect(rect2,acellrect); + end + else begin + acellrect:= nullrect; + end; +end; + +function tcustomstringgrid.textclipped(const acell: gridcoordty): boolean; +var + rect1: rectty; +begin + result:= textclipped(acell,rect1); +end; + +function tcustomstringgrid.appendrow(const value: msestringarty; + const ashowlastrow: boolean = false): integer; +var + int1: integer; +begin + result:= inherited appendrow; + for int1:= 0 to high(value) do begin + datacols[int1][result]:= value[int1]; + end; + if ashowlastrow then begin + showlastrow(); + end; +end; + +function tcustomstringgrid.appendrow(const value: array of msestring; + const ashowlastrow: boolean = false): integer; +var + int1: integer; +begin + result:= inherited appendrow; + for int1:= 0 to high(value) do begin + datacols[int1][result]:= value[int1]; + end; + if ashowlastrow then begin + showlastrow(); + end; +end; + +function tcustomstringgrid.appendrow(const value: msestring; + const ashowlastrow: boolean = false): integer; +var + ar1: msestringarty; +begin + setlength(ar1,1); + ar1[0]:= value; + result:= appendrow(ar1,ashowlastrow); +end; + +function tcustomstringgrid.appenddatarow(const value: msestringarty): integer; +var + int1: integer; +begin + result:= inherited appenddatarow; + for int1:= 0 to high(value) do begin + datacols[int1][result]:= value[int1]; + end; +end; + +function tcustomstringgrid.appenddatarow(const value: array of msestring): integer; +var + int1: integer; +begin + result:= inherited appenddatarow; + for int1:= 0 to high(value) do begin + datacols[int1][result]:= value[int1]; + end; +end; + +function tcustomstringgrid.appenddatarow(const value: msestring): integer; +var + ar1: msestringarty; +begin + setlength(ar1,1); + ar1[0]:= value; + result:= appenddatarow(ar1); +end; + +function tcustomstringgrid.getcaretcliprect: rectty; +var + pt1: pointty; +begin + result:= cellrect(ffocusedcell); + if ffocusedcell.col >= 0 then begin + pt1:= clientpos; + with fdatarect do begin + if co_nohscroll in tcol(fdatacols.fitems[ffocusedcell.col]).options then begin + with fdatacols do begin + if ffocusedcell.col >= ffirsthscrollindex then begin + intersectrect1(result, + mr(fdatarecty.x+fdatarecty.cx-ffixcols.ftotsize+ffixcols.ffirstsize- + ftotsize+ffirstsize+pt1.x,y+pt1.y, + ftotsize-ffirstsize,cy)); + end + else begin + intersectrect1(result, + mr(fdatarecty.x+ffixcols.ffirstsize+pt1.x,y+pt1.y,ffirstsize,cy)); + end; + end; + end + else begin + intersectrect1(result,mr(x+pt1.x,y+pt1.y,cx,cy)); + end; + end; + end; +end; + +function tcustomstringgrid.canclose(const newfocus: twidget): boolean; +begin + result:= inherited canclose(newfocus); + if result then begin + checkcellvalue(result); + end; +end; + +function tcustomstringgrid.currentdatalist: tmsestringdatalist; +begin + result:= nil; + if ffocusedcell.col >= 0 then begin + result:= tmsestringdatalist( + tcustomstringcol(fdatacols.fitems[ffocusedcell.col]).fdata); + end; +end; + +procedure tcustomstringgrid.initnewcomponent(const ascale: real); +begin + inherited; + datacols.count:= 1; + synctofontheight(); +end; + +function tcustomstringgrid.locatecount: integer; +begin + result:= rowcount; + if currentdatalist = nil then begin + result:= 0; + end; +end; + +function tcustomstringgrid.locatecurrentindex: integer; +begin + result:= row; +end; + +procedure tcustomstringgrid.locatesetcurrentindex(const aindex: integer); +begin + row:= aindex; +end; + +function tcustomstringgrid.getkeystring(const aindex: integer): msestring; +var + list1: tmsestringdatalist; +begin + result:= ''; + list1:= currentdatalist; + if list1 <> nil then begin + result:= list1[aindex]; + end; +end; + +function tcustomstringgrid.getedited: boolean; +begin + result:= isdatacell(ffocusedcell) and cols[ffocusedcell.col].edited; +end; + +{ trowfontarrayprop } + +constructor trowfontarrayprop.create(const aowner: tcustomgrid); +begin + fgrid:= aowner; + inherited create(nil); +end; + +class function trowfontarrayprop.getitemclasstype: persistentclassty; +begin + result:= tfont; +end; + +procedure trowfontarrayprop.createitem(const index: integer; + var item: tpersistent); +begin + item:= tfont.create; + item.assign(stockobjects.fonts[stf_default]); +end; + +procedure trowfontarrayprop.setitems(const index: integer; const avalue: tfont); +begin + checkindex(index); + if fitems[index] <> nil then begin + fitems[index].assign(avalue); + end; +end; + +function trowfontarrayprop.getitems(const index: integer): tfont; +begin + result:= tfont(inherited getitems(index)); +end; + +{ trowstatelist } + +constructor trowstatelist.create(const aowner: tcustomgrid); +var + level1: rowinfolevelty; +begin + fgrid:= aowner; + level1:= ril_normal; + if og_colmerged in aowner.optionsgrid then begin + level1:= ril_colmerge; + end; + if og_rowheight in aowner.optionsgrid then begin + level1:= ril_rowheight; + end; + inherited create(level1); +end; + +destructor trowstatelist.destroy; +begin + unlinksource(flinkfoldlevel); + unlinksource(flinkissum); + unlinksource(flinkfoldhidden); + inherited; + fvisiblerowmap.free; +end; + +function trowstatelist.isvisible(const arow: integer): boolean; +var +// po1: pintegeraty; + po2: prowstatety; + int1: integer; + by1: byte; +begin + if arow < fdirtyrow then begin + result:= prowstatety(inherited getitempo(arow))^.fold and + currentfoldhiddenmask = 0; + end + else begin + result:= false; + po2:= datapo; + inc(pchar(po2),arow*fsize); + for int1:= arow downto 0 do begin + by1:= po2^.fold and not currentfoldhiddenmask; + if by1 = 0 then begin + result:= true; + break; + end; + if (by1 and foldhiddenmask <> 0) or (by1 and foldlevelmask = 0) then begin + break; + end; + dec(pchar(po2),fsize); + end; + end; +end; + +procedure trowstatelist.counthidden(var aindex: integer); +var //todo: optimize + po1: prowstatety; + level1,level2: byte; +begin + po1:= datapo; + inc(pchar(po1),aindex*fsize); + level1:= po1^.fold and foldlevelmask; + while (aindex < count) do begin + level2:= po1^.fold and foldlevelmask; + if level2 < level1 then begin + break; + end; + if po1^.fold and foldhiddenmask = 0 then begin + if level2 > level1 then begin + counthidden(aindex); + end + else begin //same level + inc(fhiddencount); + inc(aindex); + inc(pchar(po1),fsize); + end; + end + else begin + inc(aindex); + inc(pchar(po1),fsize); + end; + end; +end; + +procedure trowstatelist.recalchidden; +var + int1: integer; + po1: prowstatety; + lev1: byte; + s1: integer; +begin + checkdirty(0); + fhiddencount:= 0; + po1:= datapo; + int1:= count; + s1:= size; + while int1 > 0 do begin + if po1^.fold and foldhiddenmask <> 0 then begin + inc(fhiddencount); + lev1:= po1^.fold and foldlevelmask; + dec(int1); + inc(pchar(po1),s1); + while (int1 > 0) and (po1^.fold and foldlevelmask > lev1) do begin + inc(fhiddencount); + dec(int1); + inc(pchar(po1),s1); + end; + end + else begin + dec(int1); + inc(pchar(po1),s1); + end; + end; +end; + +procedure trowstatelist.setupfoldinfo(asource: pbyte; + const acount: integer); +var + po1: prowstatety; + var int1: integer; + s1: integer; +begin + fgrid.rowcount:= acount; + po1:= datapo; + s1:= size; + for int1:= count-1 downto 0 do begin + po1^.fold:= asource^; + inc(pchar(po1),s1); + inc(asource); + end; + recalchidden; +end; + +procedure trowstatelist.internalshow(var aindex: integer); +var + int1,int2: integer; + po1: prowstatety; +begin + dec(fhiddencount); + int1:= aindex+1; + if (int1 < count) then begin + po1:= datapo; + inc(pchar(po1),fsize*aindex); + if (prowstatety(pchar(po1)+fsize)^.fold and foldlevelmask) > + (po1^.fold and foldlevelmask) then begin + int2:= fhiddencount; + counthidden(int1); + fhiddencount:= fhiddencount - 2*(fhiddencount-int2); + end; + end; + aindex:= int1; +end; + +procedure trowstatelist.show(const aindex: integer); +var + int1: integer; +begin + int1:= aindex; + internalshow(int1); + checkdirty(aindex); +end; + +procedure trowstatelist.internalhide(var aindex: integer); +var + int1: integer; + po1: prowstatety; +begin + inc(fhiddencount); + int1:= aindex+1; + if (int1 < count) then begin + po1:= datapo; + inc(pchar(po1),int1*fsize); + if (po1^.fold and foldlevelmask) > + (prowstatety(pchar(po1)-fsize)^.fold and foldlevelmask) then begin + counthidden(int1); + end; + end; + aindex:= int1; +end; + +procedure trowstatelist.hide(const aindex: integer); +var + int1: integer; +begin + int1:= aindex; + internalhide(int1); + checkdirty(aindex); +end; + +procedure trowstatelist.hidechildren(const arow: integer); +var + int1{,int2}: integer; + po0: pchar; + po1: prowstatety; + level1,level2: byte; + bo1: boolean; + s1: integer; +begin + checkindexrange(arow); + po0:= datapo; + s1:= size; + po1:= prowstatety(po0+arow*s1); + level1:= po1^.fold and foldlevelmask; + int1:= arow+1; + bo1:= false; + while int1 < count do begin + po1:= prowstatety(po0+int1*s1); + with po1^ do begin + level2:= fold and foldlevelmask; + if level2 <= level1 then begin + break; + end; + if fold and foldhiddenmask = 0 then begin + bo1:= true; + fold:= fold or foldhiddenmask; + fgrid.rowstatechanged(int1); + internalhide(int1); + end + else begin + while (int1 < count) and (po1^.fold and foldhiddenmask > + level2) do begin + inc(int1); + inc(pchar(po1),s1); + end; + end; + end; + end; + if bo1 then begin + checkdirty(arow+1); + fgrid.layoutchanged; + end; +end; + +procedure trowstatelist.showchildren(const arow: integer); +var + int1,int2: integer; + po0: pchar; + po1: prowstatety; + level1,level2: byte; + bo1: boolean; + s1: integer; +begin + checkindexrange(arow); + po0:= datapo; + s1:= size; + po1:= prowstatety(po0+arow*s1); + level1:= po1^.fold and foldlevelmask; + int1:= arow+1; + bo1:= false; + while int1 < count do begin + po1:= prowstatety(po0+int1*s1); + int2:= int1; + with po1^ do begin + level2:= fold and foldlevelmask; + if level2 <= level1 then begin + break; + end; + if fold and foldhiddenmask <> 0 then begin + bo1:= true; + fold:= fold and not foldhiddenmask; + fgrid.rowstatechanged(int1); + internalshow(int1); + end + else begin + while (int1 < count) and (po1^.fold and foldhiddenmask > + level2) do begin + inc(int1); + inc(pchar(po1),s1); + end; + end; + end; + if int1 = int2 then begin + break; //invalid + end; + end; + if bo1 then begin + checkdirty(arow+1); + fgrid.layoutchanged; + end; +end; + +procedure trowstatelist.sethidden(const index: integer; const avalue: boolean); +var + po1: prowstatety; + bo1: boolean; +begin + if ffolded then begin + po1:= getitempo(index); + bo1:= isvisible(index); + if updatebit(po1^.fold,foldhiddenbit,avalue) then begin + if avalue then begin + if bo1 then begin + hide(index); + end; + end + else begin + if not bo1 then begin + show(index); + end; + end; + checksyncfoldhiddensource(index,1); + fgrid.layoutchanged; + fgrid.rowstatechanged(index); + end; + end + else begin + raise exception.create('Grid not folded.'); + end; +end; + +procedure trowstatelist.setfoldlevel(const index: integer; avalue: byte); +var + po1,po2: prowstatety; + by1,by2: byte; + delta: integer; + int1: integer; + bo1: boolean; +begin + bo1:= of_validatelevel in fgrid.foptionsfold; + if bo1 then begin + if index = 0 then begin + if avalue = 0 then begin + bo1:= false; + end; + avalue:= 0; + end + else begin + by1:= (getitempo(index-1)^.fold and foldlevelmask) + 1; + if avalue > by1 then begin + avalue:= by1; + end + else begin + bo1:= false; + end; + end; + end; //bo1 -> avalue modified + + if of_shiftchildren in fgrid.foptionsfold then begin + normalizering; + po1:= getitempo(index); + po2:= po1; + by1:= po1^.fold and foldlevelmask; + delta:= integer(avalue) - integer(by1); + if delta <> 0 then begin + for int1:= index to fcount-1 do begin + by2:= po1^.fold and foldlevelmask; + if (by2 <= by1) and (int1 <> index) then begin + break; + end; + by2:= by2 + delta; + po1^.fold:= po1^.fold and not foldlevelmask or by2 and foldlevelmask; + inc(pbyte(po1),fsize); + end; + checkdirty(index); + checksyncfoldlevelsource(index,(pchar(po1)-pchar(po2)) div fsize); + end + else begin + if bo1 then begin + checksyncfoldlevelsource(index,1); + end; + end; + end + else begin + po1:= getitempo(index); + if replacebits1(byte(po1^.fold),byte(avalue),byte(foldlevelmask)) then begin + checkdirty(index); +// change(index); +// if bo1 then begin + checksyncfoldlevelsource(index,1); +// end +// else begin +// fgrid.rowstatechanged(index); +// end; + end + else begin + if bo1 then begin + checksyncfoldlevelsource(index,1); + end; + end; + end; +end; + +procedure trowstatelist.setfoldissum(const index: integer; + const avalue: boolean); +var + po1: prowstatety; + bo1: boolean; +begin + po1:= getitempo(index); + bo1:= po1^.flags and foldissummask <> 0; + if bo1 xor avalue then begin + if avalue then begin + po1^.flags:= po1^.flags or foldissummask; + end + else begin + po1^.flags:= po1^.flags and not foldissummask; + end; + checkdirty(index); + checksyncfoldissumsource(index,1); + end; +end; + +procedure trowstatelist.foldleveltosource(const index: integer; + const acount: integer); +var + po1: prowstatety; + po2: pinteger; + int1: integer; +begin + inc(ffoldlevelsourcelock); + try + with flinkfoldlevel.source do begin + if acount > 1 then begin + self.normalizering; + normalizering; + end; + po1:= self.getitempo(index); + po2:= getitempo(index); + for int1:= 0 to acount-1 do begin + po2^:= po1^.fold and foldlevelmask; + inc(pchar(po1),self.size); + inc(pchar(po2),size); + end; + if acount = 1 then begin + change(index); + end + else begin + change(-1); + end; + end; + if acount = 1 then begin + change(index); + fgrid.rowstatechanged(index); + end + else begin + change(-1); + fgrid.rowstatechanged(-1); + end; + finally + dec(ffoldlevelsourcelock); + end; +end; + +procedure trowstatelist.foldhiddentosource(const index: integer; + const acount: integer); +var + po1: prowstatety; + po2: pinteger; + int1: integer; +begin + inc(ffoldhiddensourcelock); + try + with flinkfoldhidden.source do begin + if acount > 1 then begin + self.normalizering; + normalizering; + end; + po1:= self.getitempo(index); + po2:= getitempo(index); + for int1:= 0 to acount-1 do begin + plongbool(po2)^:= po1^.fold and foldhiddenmask <> 0; + inc(pchar(po1),self.size); + inc(pchar(po2),size); + end; + if acount = 1 then begin + change(index); + end + else begin + change(-1); + end; + end; + if acount = 1 then begin + change(index); + fgrid.rowstatechanged(index); + end + else begin + change(-1); + fgrid.rowstatechanged(-1); + end; + finally + dec(ffoldhiddensourcelock); + end; +end; + + +procedure trowstatelist.foldissumtosource(const index: integer; + const acount: integer); +var + po1: prowstatety; + po2: pinteger; + int1: integer; +begin + inc(fissumsourcelock); + try + with flinkissum.source do begin + if acount > 1 then begin + self.normalizering; + normalizering; + end; + po1:= self.getitempo(index); + po2:= getitempo(index); + for int1:= 0 to acount-1 do begin + if po1^.flags and foldissummask <> 0 then begin + po2^:= longint(longbool(true)); + end + else begin + po2^:= 0; + end; + inc(pchar(po1),self.size); + inc(pchar(po2),size); + end; + if acount = 1 then begin + change(index); + end + else begin + change(-1); + end; + end; + if acount = 1 then begin + change(index); + fgrid.rowstatechanged(index); + end + else begin + change(-1); + fgrid.rowstatechanged(-1); + end; + finally + dec(fissumsourcelock); + end; +end; + +procedure trowstatelist.fillfoldlevel(const index: integer; + const acount: integer; const avalue: byte); +var + po1: prowstatety; + int1: integer; + bo1: boolean; +begin + if acount > 0 then begin + checkindexrange(index,acount); + normalizering; + po1:= getitempo(index); + checkdirty(index); + bo1:= false; + for int1:= 0 to acount-1 do begin + bo1:= bo1 or replacebits1(byte(po1^.fold),byte(avalue),byte(foldlevelmask)); + inc(pbyte(po1),fsize); + end; + if bo1 then begin + checksyncfoldlevelsource(index,acount); + end; + end; +end; + +procedure trowstatelist.setfolded(const avalue: boolean); +begin + if avalue <> ffolded then begin + ffolded:= avalue; + if avalue then begin + setlength(fvisiblerows,count); + fvisiblerowmap:= tintegerdatalist.create; + fvisiblerowmap.count:= count; + fdirtyvisible:= 0; + fdirtyrow:= 0; + end + else begin + fvisiblerows:= nil; + freeandnil(fvisiblerowmap); + fhiddencount:= 0; + end; + checkdirty(0); + end; +end; + +function trowstatelist.cellrow(const arow: integer): integer; +begin + result:= arow; + if ffolded and (arow >= 0) then begin + clean(arow); + result:= fvisiblerowmap[arow]; + end; +end; + +procedure trowstatelist.checkdirty(const arow: integer); +begin + if ffolded then begin + if arow < fdirtyrowheight then begin + fdirtyrowheight:= arow; + end; + if arow < fdirtyrow then begin + fdirtyrow:= arow; + fdirtyvisible:= 0; + if arow > 0 then begin + fdirtyvisible:= fvisiblerowmap[arow-1]; + end; + fgrid.layoutchanged; + end; + if arow < ffoldchangedrow then begin + ffoldchangedrow:= arow; + end; + end; +end; + +procedure trowstatelist.invalidatedirtyrowheight(const arow: int32); + //-2 -> count change +begin + if (arow = -2) then begin + if count < fdirtyrowheight then begin + fdirtyrowheight:= count; + end + else begin + if fdirtyrowheight > 0 then begin + dec(fdirtyrowheight); //could be above previous count + end; + end; + if count < fdirtyautorowheight then begin + fdirtyautorowheight:= count; + end + else begin + if fdirtyautorowheight > 0 then begin + dec(fdirtyautorowheight); //could be above previous count + end; + end; + end + else begin + fdirtyrowheight:= 0; + fdirtyautorowheight:= 0; + end; +end; + +procedure trowstatelist.checkdirtyautorowheight(const arow: integer); +var + bo1: boolean; +begin + bo1:= false; + if arow < 0 then begin + invalidatedirtyrowheight(arow); + bo1:= true; + end + else begin + if (finfolevel >= ril_rowheight) and (arow < count) then begin + with prowstaterowheightty(getitempo(arow))^ do begin + if rowheight.height <= 0 then begin + rowheight.height:= 0; + bo1:= true; + end; + end; + end; + if arow < fdirtyrowheight then begin + fdirtyrowheight:= arow; + bo1:= true; + end; + if arow < fdirtyautorowheight then begin + fdirtyautorowheight:= arow; + bo1:= true; + end; + end; + if bo1 then begin + fgrid.layoutchanged; + end; +end; + +procedure trowstatelist.change(const index: integer); +begin + if (finfolevel >= ril_rowheight) and (index < 0) then begin + invalidatedirtyrowheight(index); + inherited; + fgrid.layoutchanged; + end + else begin + inherited; + end; +end; + +procedure copyfoldlevel(const source,dest: pointer); +begin + prowstatety(dest)^.fold:= prowstatety(dest)^.fold and not foldlevelmask + or pinteger(source)^ and foldlevelmask; +end; + +procedure copyfoldhidden(const source,dest: pointer); +begin + if pinteger(source)^ <> 0 then begin + prowstatety(dest)^.fold:= prowstatety(dest)^.fold or foldhiddenmask; + end + else begin + prowstatety(dest)^.fold:= prowstatety(dest)^.fold and not foldhiddenmask; + end; +end; + +procedure copyissum(const source,dest: pointer); +begin + if pinteger(source)^ <> 0 then begin + prowstatety(dest)^.flags:= prowstatety(dest)^.flags or foldissummask; + end + else begin + prowstatety(dest)^.flags:= prowstatety(dest)^.flags and not foldissummask; + end; +end; + +procedure trowstatelist.cleanfolding(arow: integer; visibleindex: integer); +var + int1,int2: integer; + rowstat1: prowstatety; + visirow1: pinteger; + level1: byte; + bo1: boolean; +begin //todo: optimize + bo1:= sourceischanged(flinkfoldlevel) or sourceischanged(flinkfoldhidden); + checksourcecopy(flinkfoldlevel,@copyfoldlevel); + checksourcecopy(flinkfoldhidden,@copyfoldhidden); + checksourcecopy(flinkissum,@copyissum); + if bo1 then begin + recalchidden; + end; + int2:= 0; + if fdirtyvisible > 0 then begin + int2:= fvisiblerows[fdirtyvisible-1]+1; //first row to check + end; + rowstat1:= prowstatety(pchar(datapo)+int2*fsize); + visirow1:= @pintegeraty(fvisiblerowmap.datapo)^[int2]; + if fdirtyvisible < 0 then begin + int1:= -1; + end + else begin + int1:= fdirtyvisible-1; //visible row index + end; + while int1 < visibleindex do begin + while (rowstat1^.fold and foldhiddenmask <> 0) and (int2 <= arow) do begin + rowstat1^.fold:= rowstat1^.fold or currentfoldhiddenmask; + level1:= rowstat1^.fold and foldlevelmask; + visirow1^:= int1; + inc(pchar(rowstat1),fsize); + inc(visirow1); + inc(int2); + while (int2 <= arow) and + (rowstat1^.fold and foldlevelmask > level1) do begin + visirow1^:= int1; + rowstat1^.fold:= rowstat1^.fold or currentfoldhiddenmask; + inc(pchar(rowstat1),fsize); + inc(visirow1); + inc(int2); + end; + end; + if int2 <= arow then begin + inc(int1); + visirow1^:= int1; + if int1 > high(fvisiblerows) then begin //????? + setlength(fvisiblerows,high(fvisiblerows)+2); + end; + fvisiblerows[int1]:= int2; + rowstat1^.fold:= rowstat1^.fold and not currentfoldhiddenmask; + inc(int2); + inc(pchar(rowstat1),fsize); + inc(visirow1); + end + else begin + break; + end; + end; + fdirtyvisible:= int1 + 1; + fdirtyrow:= int2; +end; + +procedure trowstatelist.cleanvisible(visibleindex: integer); +var + int1: integer; +begin + if ffolded then begin + int1:= visiblerowcount; + if visibleindex >= int1 then begin + visibleindex:= int1 - 1; + end; + if (visibleindex >= fdirtyvisible) then begin + cleanfolding(count-1,visibleindex); + end; + end; +end; + +procedure trowstatelist.clean(arow: integer); +var + int1: integer; +begin + if ffolded then begin + int1:= count; + if arow >= int1 then begin + arow:= int1 -1; + end; + if arow >= fdirtyrow then begin + cleanfolding(arow,bigint); + end; + end; +end; + +procedure trowstatelist.cleanrowheight(const aindex: integer); + +//todo: optimize cleaning with co1_autorowheight + +var + int1,int2,int3,int4,int5: integer; + po1: prowstaterowheightty; + needsrowheightupdate: boolean; +begin + if aindex >= fdirtyrowheight then begin + ftopypos:= 0; + if count > 0 then begin + needsrowheightupdate:= gs_needsrowheight in fgrid.fstate; + po1:= dataporowheight; + inc(pchar(po1),fdirtyrowheight*fsize); + if fdirtyrowheight = 0 then begin + po1^.rowheight.ypos:= 0; + end; + int3:= po1^.rowheight.ypos; + if ffolded then begin + cleanvisible(aindex); + end; + for int1:= fdirtyrowheight to aindex do begin + if po1^.rowheight.linewidth = 0 then begin + int4:= fgrid.fdatarowlinewidth; + end + else begin + int4:= po1^.rowheight.linewidth - 1; + end; + int2:= fgrid.fdatarowheight + int4; + po1^.rowheight.ypos:= int3; + if not folded or (po1^.normal.fold and currentfoldhiddenmask = 0) then begin + if po1^.rowheight.height <= 0 then begin + if needsrowheightupdate then begin + int5:= fgrid.fdatarowheight; + if (po1^.rowheight.height = 0) or (int1 >= fdirtyautorowheight) then begin + fgrid.updaterowheight(int1,int5); + po1^.rowheight.height:= -int5; + end + else begin + int5:= -po1^.rowheight.height; + end; + int3:= int3 + int5 + int4; + end + else begin + int3:= int3 + int2; + end; + end + else begin + int3:= int3 + po1^.rowheight.height + int4; + end; + end; + inc(pchar(po1),fsize); + end; + if aindex >= count-1 then begin + ftopypos:= int3; + end + else begin + po1^.rowheight.ypos:= int3; + end; + fdirtyrowheight:= aindex+1; + if fdirtyrowheight > fdirtyautorowheight then begin + fdirtyautorowheight:= fdirtyrowheight; + end; + end; + end; +end; + + +function trowstatelist.visiblerows1(const astart: integer; + const aendy: integer): integerarty; +var + int1,int2: integer; + acount: integer; +begin //todo: optimize + result:= nil; + if count > 0 then begin + if og_rowheight in fgrid.foptionsgrid then begin + int1:= rowindex(aendy); + if int1 < 0 then begin + acount:= cellrow(count-1); + end + else begin + acount:= cellrow(int1); + end; + end + else begin + acount:= aendy div fgrid.fdatarowheight; + end; + acount:= acount - astart + 2; + if ffolded then begin + cleanvisible(astart+acount); + int1:= visiblerowcount; + if astart + acount > int1 then begin + acount:= int1 - astart; + end; + if acount > 0 then begin + result:= copy(fvisiblerows,astart,acount); + end + else begin + result:= nil; + end; + end + else begin + int1:= count - astart; + if acount > int1 then begin + acount:= int1; + end; + setlength(result,acount); + int2:= astart; + for int1:= 0 to high(result) do begin + result[int1]:= int2; + inc(int2); + end; + end; + end; +end; + +procedure trowstatelist.updatefoldinfo(const rows: integerarty; + var infos: rowfoldinfoarty); +var + int1,int2: integer; + po1: prowstatety; + po2: prowstatety; + po3: prowfoldinfoty; + level1,level2: byte; + lastrow: integer; +// visible1: boolean; + ar1: booleanarty; +begin + setlength(infos,length(rows)); + if high(rows) >= 0 then begin + for int1:= high(rows) downto 0 do begin + with infos[int1] do begin + getfoldstate(rows[int1],isvisible,foldlevel,haschildren,isopen); + setlength(nolines,foldlevel); + fillchar(nolines[0],(foldlevel)*sizeof(boolean),0); + end; + end; + po1:= datapo; + lastrow:= rows[high(rows)]; + po2:= prowstatety(pchar(po1)+lastrow*fsize); + level1:= po2^.fold and foldlevelmask; //level of last row + setlength(ar1,level1+1); + for int1:= lastrow+1 to count-1 do begin //mark linecontinuations + inc(pchar(po2),fsize); + with po2^ do begin + if fold and foldhiddenmask = 0 then begin + level2:= fold and foldlevelmask; + if (level2 = 0) then begin + break; + end; + if level2 <= level1 then begin + ar1[level2]:= true; //line continuation found + level1:= level2; + end; + end; + end; + end; + po3:= @infos[high(infos)]; + for int1:= high(ar1) downto 1 do begin + po3^.nolines[int1-1]:= not ar1[int1]; //set missing continuations + end; + for int1:= high(infos) - 1 downto 0 do begin + with infos[int1] do begin + for int2:= 0 to high(nolines) do begin + nolines[int2]:= (int2 > high(po3^.nolines)) or + (int2 < high(po3^.nolines)) and po3^.nolines[int2]; + end; + end; + dec(po3); + end; + end; +end; + +function trowstatelist.visiblerowstep(const arow: integer; const step: integer; + const autoappend: boolean): integer; +begin + if not folded then begin + result:= arow + step; + if result < 0 then begin + result:= 0; + end; + if result >= fgrid.frowcount then begin + if autoappend then begin + result:= fgrid.frowcount; + end + else begin + result:= fgrid.frowcount - 1; + end; + end; + end + else begin + result:= visiblerowtoindex(visiblerow(arow)+step); + if result < 0 then begin + if step < 0 then begin + result:= visiblerowtoindex(0); + end + else begin + if autoappend then begin + result:= fgrid.frowcount; + end + else begin + if visiblerowcount > 0 then begin + result:= visiblerowtoindex(visiblerowcount - 1); + end; + end; + end; + end; + end; +end; + +function trowstatelist.visiblerow(const arowindex: integer): integer; +begin + result:= invalidaxis; + if (arowindex >= 0) and (arowindex < count) then begin + if not ffolded then begin + result:= arowindex; + end + else begin + if not hidden[arowindex] then begin + clean(arowindex); + result:= fvisiblerowmap[arowindex]; + end; + end; + end; +end; + +function trowstatelist.visiblerowcount: integer; +begin + result:= count - fhiddencount; +end; + +function trowstatelist.visiblerowtoindex(const avisibleindex: integer): integer; +begin + result:= invalidaxis; + if (avisibleindex >= 0) then begin + if not ffolded then begin + if avisibleindex < count then begin + result:= avisibleindex; + end; + end + else begin + cleanvisible(avisibleindex); + if avisibleindex < visiblerowcount then begin +// cleanvisible(avisibleindex); + if fvisiblerows <> nil then begin + if avisibleindex > high(fvisiblerows) then begin + result:= fvisiblerows[high(fvisiblerows)]; + end + else begin + result:= fvisiblerows[avisibleindex]; + end; + end + end; + end; + end; +end; +{ +procedure trowstatelist.setcount(const value: integer); +var + bo1: boolean; +begin + if ffolded then begin + bo1:= value < fcount; + setlength(fvisiblerows,count); //????? + inherited; + if bo1 then begin + setlength(fvisiblerows,count); //????? + end; + end + else begin + inherited; + end; +end; + +procedure trowstatelist.clearbuffer; +begin + fvisiblerows:= nil; + inherited; +end; +} +procedure trowstatelist.updatedeletedrows(const index: integer; + const acount: integer); +var + int1: integer; + int2: integer; + po1: pinteger; +begin + if acount >= count then begin + fhiddencount:= 0; + end + else begin + clean(index+acount-1); + po1:= @pintegeraty(fvisiblerowmap.datapo)[index]; + dec(po1); + if index = 0 then begin + int2:= -1; + end + else begin + int2:= po1^; + end; + for int1:= acount-1 downto 0 do begin + inc(po1); + if (po1^ = int2) then begin + dec(fhiddencount); + end; + int2:= po1^; + end; + end; + checkdirty(index); +end; + +function trowstatelist.rowhidden(const arow: integer): boolean; +begin + result:= ffolded; + if result then begin + result:= hidden[arow]; + end; +end; + +function trowstatelist.nearestvisiblerow(const arow: integer): integer; +var + po1: prowstatety; + int1: integer; +begin + result:= arow; + if rowhidden(arow) then begin + po1:= datapo; + inc(pbyte(po1),arow*fsize); + for int1:= arow to count -1 do begin + if po1^.fold and foldhiddenmask = 0 then begin + result:= int1; + exit; + end; + inc(pbyte(po1),fsize); + end; + result:= invalidaxis; + po1:= datapo; + inc(pbyte(po1),(arow-1)*fsize); + for int1:= arow - 1 downto 0 do begin + if po1^.fold and foldhiddenmask = 0 then begin + result:= int1; + exit; + end; + dec(pbyte(po1),fsize); + end; + end; +end; + +procedure trowstatelist.getfoldstate(const arow: integer; + out aisvisible: boolean; out afoldlevel: byte; + out ahaschildren,aisopen: boolean); +var + po1: prowstatety; + nextfoldlevel: byte; + by1: byte; + bo1: boolean; +begin + by1:= 0; + nextfoldlevel:= 0; + checkindexrange(arow); + po1:= datapo; + inc(pchar(po1),arow*fsize); + with po1^ do begin + afoldlevel:= fold and foldlevelmask; + aisvisible:= fold and foldhiddenmask = 0; + bo1:= arow < count-1; + if bo1 then begin + by1:= prowstatety(pchar(po1)+fsize)^.fold; + nextfoldlevel:= by1 and foldlevelmask; + end; + ahaschildren:= bo1 and (nextfoldlevel > afoldlevel); + aisopen:= ahaschildren and (by1 and foldhiddenmask = 0); + end; +end; + +function trowstatelist.getstatdata(const index: integer): msestring; +var + int1: integer; +begin + with prowstaterowheightty(inherited getitempo(index))^ do begin + result:= inttostrmse(normal.fold + normal.flags shl 8); + if finfolevel >= ril_colmerge then begin + result:= result + ' ' + inttostrmse(colmerge.merged); + end; + if (finfolevel >= ril_rowheight) and + (og_savestate in fgrid.foptionsgrid) then begin + int1:= rowheight.height; + if int1 < 0 then begin + int1:= 0; //auto height + end; + result:= result + ' ' + inttostrmse(int1); + end; + end; +end; + +procedure trowstatelist.setstatdata(const index: integer; + const value: msestring); +var + ar1: msestringarty; + int1: integer; +begin + splitstring(value,ar1,msechar(' ')); + if high(ar1) >= 0 then begin + with prowstaterowheightty(inherited getitempo(index))^ do begin + int1:= strtoint(ar1[0]); + normal.fold:= int1 and $ff; + normal.flags:= (int1 shr 8) and $ff; + if (finfolevel >= ril_colmerge) and (high(ar1) > 0) then begin + colmerge.merged:= strtoint(ar1[1]); + end; + if (og_savestate in fgrid.foptionsgrid) and (finfolevel >= ril_rowheight) and (high(ar1) > 1) then begin + rowheight.height:= strtoint(ar1[2]); + if (rowheight.height < 0) then begin + rowheight.height:= 0; + end; + if (rowheight.height > 0) and + (rowheight.height < fgrid.fdatarowheightmin) then begin + rowheight.height:= fgrid.fdatarowheightmin; + end; + if rowheight.height > fgrid.fdatarowheightmax then begin + rowheight.height:= fgrid.fdatarowheightmax; + end; + end; + end; + end; +end; + +procedure trowstatelist.setheight(const index: integer; + const avalue: integer); +begin + with getitemporowheight(index)^ do begin + if avalue <> rowheight.height then begin + rowheight.height:= avalue; + if index < fdirtyrowheight then begin + fdirtyrowheight:= index; + fgrid.layoutchanged; + end; + end; + end; +end; + +procedure trowstatelist.setlinewidth(const index: integer; + avalue: rowlinewidthty); +begin + inc(avalue); + with getitemporowheight(index)^ do begin + if avalue <> rowheight.linewidth then begin + rowheight.linewidth:= avalue; + if index < fdirtyrowheight then begin + fdirtyrowheight:= index; + fgrid.layoutchanged; + end; + end; + end; +end; + +function trowstatelist.getrowypos(const index: integer): integer; +begin + result:= 0; + if index >= count then begin + if index > 0 then begin + cleanrowheight(count-1); + result:= ftopypos; + end; + end + else begin + cleanrowheight(index); + result:= getitemporowheight(index)^.rowheight.ypos; + end; +end; + +function trowstatelist.internalystep(const aindex: integer): integer; +begin + with prowstaterowheightty(getitempo(aindex))^ do begin + if aindex >= count - 1 then begin + result:= ftopypos - rowheight.ypos; + end + else begin + result:= prowstaterowheightty(getitempo(aindex+1))^.rowheight.ypos - rowheight.ypos; + end; + end; +end; + +procedure trowstatelist.internalystep(const aindex: integer; out ay: integer; + out acy: integer); +begin + with prowstaterowheightty(getitempo(aindex))^ do begin + ay:= rowheight.ypos; + if aindex >= count - 1 then begin + acy:= ftopypos - ay; + end + else begin + acy:= prowstaterowheightty(getitempo(aindex+1))^.rowheight.ypos - ay; + end; + end; +end; + +function trowstatelist.internalheight(const aindex: integer): integer; +begin + with prowstaterowheightty(getitempo(aindex))^.rowheight do begin + if height = 0 then begin + result:= fgrid.fdatarowheight; + end + else begin + result:= height; + if result < 0 then begin + result:= -result; //auto height + end; + end; + end; +{ + with prowstaterowheightty(getitempo(aindex))^ do begin + if aindex >= count - 1 then begin + result:= ftopypos - rowheight.ypos; + end + else begin + result:= prowstaterowheightty(getitempo(aindex+1))^.rowheight.ypos - rowheight.ypos; + end; + end; + result:= result - fgrid.fdatarowlinewidth; +} +end; + +function trowstatelist.currentrowheight(const index: integer): integer; +begin + cleanrowheight(index); + result:= internalheight(index); +end; + +function comprowypos(const l,r): integer; +begin + result:= integer(l) - rowstaterowheightty(r).rowheight.ypos; +end; + +function trowstatelist.rowindex(const aypos: integer): integer; +var + po1: prowstaterowheightty; + int1,int2: integer; + bo1: boolean; +begin + cleanrowheight(count-1); + po1:= dataporowheight; + bo1:= findarrayvalue(aypos,po1,fsize,count,@comprowypos,result); + if not bo1 then begin + dec(result); + if (result = count-1) then begin + with prowstaterowheightaty(po1)^[result] do begin + if aypos >= ftopypos then begin + result:= invalidaxis; + end; + end; + end; + if (result >= 0) and ffolded then begin + cleanvisible(result); + int2:= invalidaxis; + inc(pbyte(po1),result*fsize); + for int1:= result downto 0 do begin + if po1^.normal.fold and currentfoldhiddenmask = 0 then begin + int2:= int1; + break; + end; + dec(pbyte(po1),fsize); + end; + result:= int2; + end; + end; +end; + +procedure trowstatelist.initdirty; +begin + fdirtyvisible:= 0; + fdirtyrow:= 0; + fdirtyrowheight:= 0; + fdirtyautorowheight:= 0; +end; + +procedure trowstatelist.clearmemberitem(const subitem: integer; + const index: integer); +begin + case rowstatememberty(subitem-1) of + rsm_select: begin + selected[index]:= 0; + fgrid.invalidaterow(index); //todo: update selectstate + end; + rsm_color: begin + fgrid.rowcolorstate[index]:= -1; + end; + rsm_font: begin + fgrid.rowfontstate[index]:= -1; + end; + rsm_readonly: begin + fgrid.rowreadonlystate[index]:= false; + end; + rsm_foldlevel: begin + fgrid.rowfoldlevel[index]:= 0; + end; + rsm_foldissum: begin + fgrid.rowfoldissum[index]:= false; + end; + rsm_hidden: begin + if folded then begin + fgrid.rowhidden[index]:= false; + end; + end; + rsm_merged: begin + if finfolevel >= ril_colmerge then begin + merged[index]:= 0; + fgrid.datacols.mergechanged(index); + end; + end; + rsm_height: begin + if finfolevel >= ril_rowheight then begin + fgrid.rowheight[index]:= 0; + end; + end; + end; +end; + +procedure trowstatelist.setmemberitem(const subitem: integer; + const index: integer; const avalue: integer); +begin + case rowstatememberty(subitem-1) of + rsm_select: begin + selected[index]:= avalue; + fgrid.invalidaterow(index); //todo: update selectstate + end; + rsm_color: begin + fgrid.rowcolorstate[index]:= avalue; + end; + rsm_font: begin + fgrid.rowfontstate[index]:= avalue; + end; + rsm_readonly: begin + fgrid.rowreadonlystate[index]:= avalue <> 0; + end; + rsm_foldlevel: begin + fgrid.rowfoldlevel[index]:= avalue; + end; + rsm_foldissum: begin + fgrid.rowfoldissum[index]:= avalue <> 0; + end; + rsm_hidden: begin + if folded then begin + fgrid.rowhidden[index]:= avalue <> 0; + end; + end; + rsm_merged: begin + if finfolevel >= ril_colmerge then begin + merged[index]:= avalue; + fgrid.datacols.mergechanged(index); + end; + end; + rsm_height: begin + if finfolevel >= ril_rowheight then begin + fgrid.rowheight[index]:= avalue; + end; + end; + end; +end; + +function trowstatelist.totchildrencount(const aindex: integer; + const acount: integer): integer; +var + lev1,lev2: byte; + ind1: integer; + int1: integer; + po1: prowstatety; +begin + lev2:= 0; + checkindexrange(aindex,acount); + normalizering; + po1:= getitempo(aindex); + lev1:= po1^.fold and foldlevelmask; + ind1:= aindex; + for int1:= acount - 1 downto 0 do begin + lev2:= po1^.fold and foldlevelmask; + if lev2 < lev1 then begin + lev1:= lev2; + ind1:= aindex - int1 + acount-1 + end; + inc(pbyte(po1),fsize); + end; + po1:= getitempo(ind1); + for int1:= ind1+1 to fcount-1 do begin + inc(pbyte(po1),fsize); + if po1^.fold and foldlevelmask <= lev2 then begin + break; + end; + end; + result:= int1 - aindex; +end; + +procedure trowstatelist.checksyncfoldlevelsource(const index: integer; + const acount: integer); +var + int1: integer; +begin + if flinkfoldlevel.source <> nil then begin + foldleveltosource(index,acount); + end + else begin + for int1:= index to index + acount - 1 do begin + change(int1); + fgrid.rowstatechanged(int1); + end; + end; +end; + +procedure trowstatelist.checksyncfoldhiddensource(const index: integer; + const acount: integer); +var + int1: integer; +begin + if flinkfoldhidden.source <> nil then begin + foldhiddentosource(index,acount); + end + else begin + for int1:= index to index + acount - 1 do begin + change(int1); + fgrid.rowstatechanged(int1); + end; + end; +end; + +procedure trowstatelist.checksyncfoldissumsource(const index: integer; + const acount: integer); +begin + if flinkissum.source <> nil then begin + foldissumtosource(index,acount); + end + else begin + if acount = 1 then begin + change(index); + fgrid.rowstatechanged(index); + end + else begin + change(-1); + fgrid.rowstatechanged(-1); + end; + end; +end; + +procedure trowstatelist.movegrouptoparent(const aindex: integer; + const acount: integer); +var + po1,po2,po3,po4: prowstatety; + lev1,lev2: integer; + int1,int2: integer; + by1: byte; +begin + if acount > 0 then begin + checkindexrange(aindex,acount); + normalizering; + int1:= aindex+acount-1; + po1:= getitempo(int1); + po3:= po1; + po4:= nil; + lev1:= 0; + for int1:= int1 downto aindex do begin + lev2:= po1^.fold and foldlevelmask; + po2:= po1; + for int2:= int1+1 to fcount -1 do begin + inc(pbyte(po2),fsize); + by1:= po2^.fold and foldlevelmask; + if by1 <= lev2 then begin + break; + end; + replacebits1(byte(po2^.fold),by1-1,byte(foldlevelmask)); + po3:= po2; + if po4 = nil then begin + po4:= po2; + end; + end; + if lev2 < lev1 then begin + break; + end; + inc(pbyte(po1),fsize); + end; + if po4 <> nil then begin + checksyncfoldlevelsource((pchar(po4)-pchar(datapo)) div fsize, + (pchar(po3)-pchar(getitempo(aindex))) div fsize); + end; + end; +end; + +procedure trowstatelist.sourcenamechanged(const atag: integer); +var + datalist1: tdatalist; + str1: string; + int1: integer; +begin + if not (csloading in fgrid.componentstate) then begin + if atag >= 0 then begin + str1:= getsourcename(atag); + datalist1:= nil; + if str1 <> '' then begin + datalist1:= fgrid.datacols.datalistbyname(str1); + end; + linksource(datalist1,atag); + end + else begin + for int1:= 0 to getsourcecount-1 do begin + str1:= getsourcename(int1); //link all source lists + datalist1:= nil; + if str1 <> '' then begin + datalist1:= fgrid.datacols.datalistbyname(str1); + end; + linksource(datalist1,int1); + end; + end; + end; +end; + +procedure trowstatelist.setsourcefoldlevel1(const avalue: string); +begin + flinkfoldlevel.name:= avalue; + sourcenamechanged(rowstatefoldleveltag); +end; + +procedure trowstatelist.setsourcefoldlevel(const avalue: string); +begin + {$ifdef mse_with_ifi} +// setifilinkfoldlevel1(nil); + {$endif} + setsourcefoldlevel1(avalue); +end; + +procedure trowstatelist.setsourcefoldhidden1(const avalue: string); +begin + flinkfoldhidden.name:= avalue; + sourcenamechanged(rowstatefoldhiddentag); +end; + +procedure trowstatelist.setsourcefoldhidden(const avalue: string); +begin + {$ifdef mse_with_ifi} +// setifilinkfoldlevel1(nil); + {$endif} + setsourcefoldhidden1(avalue); +end; + +procedure trowstatelist.setsourceissum1(const avalue: string); +begin + flinkissum.name:= avalue; + sourcenamechanged(rowstateissumtag); +end; + +procedure trowstatelist.setsourceissum(const avalue: string); +begin + {$ifdef mse_with_ifi} +// setifilinkissum1(nil); + {$endif} + setsourceissum1(avalue); +end; + +procedure trowstatelist.sourcechange(const sender: tdatalist; + const index: integer); +begin + inherited; + if sender <> nil then begin + if (sender = flinkfoldlevel.source) and (ffoldlevelsourcelock = 0) then begin + if checksourcechange(flinkfoldlevel,sender,index) then begin + if (of_shiftchildren in fgrid.optionsfold) and (index >= 0) then begin + foldlevel[index]:= pinteger(flinkfoldlevel.source.getitempo(index))^; + end + else begin + checkdirty(index); + change(index); + fgrid.rowstatechanged(index); + end; + end; + end + else begin + if (sender = flinkissum.source) and (fissumsourcelock = 0) then begin + if checksourcechange(flinkissum,sender,index) then begin + checkdirty(index); + change(index); + fgrid.rowstatechanged(index); + end; + end + else begin + if (sender = flinkfoldhidden.source) and (ffoldhiddensourcelock = 0) then begin + if checksourcechange(flinkfoldhidden,sender,index) then begin + checkdirty(index); + change(index); + fgrid.rowstatechanged(index); + end; + end + end; + end; + end; +end; + +function trowstatelist.getsourcecount: integer; +begin + result:= 3; +end; + +function trowstatelist.getsourceinfo(const atag: integer): plistlinkinfoty; +begin + case atag of + rowstatefoldleveltag: begin + result:= @flinkfoldlevel; + end; + rowstateissumtag: begin + result:= @flinkissum; + end; + rowstatefoldhiddentag: begin + result:= @flinkfoldhidden; + end; + else begin + result:= nil; + end; + end; +end; + +procedure trowstatelist.linksource(const source: tdatalist; + const atag: integer); +begin + case atag of + rowstatefoldleveltag: begin + internallinksource(source,atag,flinkfoldlevel.source); + end; + rowstateissumtag: begin + internallinksource(source,atag,flinkissum.source); + end; + rowstatefoldhiddentag: begin + internallinksource(source,atag,flinkfoldhidden.source); + end; + end; +end; + +function trowstatelist.getlinkdatatypes(const atag: integer): listdatatypesty; +begin + result:= []; + case atag of + rowstatefoldleveltag,rowstateissumtag,rowstatefoldhiddentag: begin + result:= [dl_integer]; + end; + end; +end; + +procedure trowstatelist.readstate(const reader; const acount: integer; + const name: msestring); +begin + inherited; + if (infolevel > ril_normal) or folded then begin + fgrid.layoutchanged; + end; +end; + +procedure trowstatelist.listdestroyed(const sender: tdatalist); +begin + if sender = flinkfoldhidden.source then begin + flinkfoldhidden.source:= nil; + end; + if sender = flinkfoldlevel.source then begin + flinkfoldlevel.source:= nil; + end; + if sender = flinkissum.source then begin + flinkissum.source:= nil; + end; + inherited; +end; + +{$ifdef mse_with_ifi} + +function trowstatelist.getifilinkkind: ptypeinfo; +begin + result:= typeinfo(iifidatalink); +end; + +procedure trowstatelist.setifiserverintf(const aintf: iifiserver); +begin + //dummy +end; + +procedure trowstatelist.updateifigriddata(const sender: tobject; + const alist: tdatalist); +begin + //dummy +end; + +procedure trowstatelist.ifisetvalue(var avalue; var accept: boolean); +begin + //dummy +end; + +procedure trowstatelist.getifivalue(var avalue); +begin + //dummy +end; + +procedure trowstatelist.setifivalue(const avalue); +begin + //dummy +end; + +function trowstatelist.getgriddata: tdatalist; +begin + result:= self; +end; + +function trowstatelist.getvalueprop: ppropinfo; +begin + result:= nil; +end; + +procedure trowstatelist.updatereadonlystate; +begin + //dummy +end; + +function trowstatelist.getdefaultifilink: iificlient; +begin + result:= iifidatalink(self); +end; + +{$endif} + +{ tstringgrid } + +procedure tstringgrid.initnewcomponent(const ascale: real); +begin + inherited; + optionsgrid:= optionsgrid + newcomponentoptionsgridadd; +end; + +{ tcelldragobject } + +constructor tcelldragobject.create(const draginfo: draginfoty; + const cellinfo: cellinfoty); +begin + fgrid:= cellinfo.grid; + fcell:= cellinfo.cell; + inherited create(cellinfo.grid,draginfo.dragobjectpo^,draginfo.pickpos); +end; + +constructor tcelldragobject.create(const agrid: tcustomgrid; + var ainstance: tdragobject; const apos: pointty); +begin + fgrid:= agrid; + fcell:= agrid.cellatpos(apos); + inherited create(agrid,ainstance,apos); +end; + +end. + diff --git a/mseide-msegui/lib/common/widgets/msegridsglob.pas b/mseide-msegui/lib/common/widgets/msegridsglob.pas new file mode 100644 index 0000000..0e951ce --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msegridsglob.pas @@ -0,0 +1,35 @@ +{ MSEgui Copyright (c) 1999-2010 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msegridsglob; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +interface + +type + cellpositionty = (cep_none,cep_nearest,cep_topleft,cep_top,cep_topright, + cep_bottomright, + cep_bottom,cep_bottomleft,cep_left, + cep_rowcentered,cep_rowcenteredif); + + celleventkindty = (cek_none,cek_enter,cek_exit,cek_select, + cek_focusedcellchanged, + cek_mousemove,cek_mousepark,cek_firstmousepark, + cek_buttonpress,cek_buttonrelease, + cek_mouseenter,cek_mouseleave, + cek_keydown,cek_keyup); + + focuscellactionty = (fca_none,fca_entergrid,fca_exitgrid, + fca_reverse,fca_focusin,fca_focusinforce, + fca_focusinshift,fca_focusinrepeater,fca_setfocusedcell, + fca_selectstart,fca_selectend); + + cellzonety = (cz_none,cz_default,cz_checkbox,cz_image,cz_caption,cz_child); + +implementation +end. diff --git a/mseide-msegui/lib/common/widgets/mseguirttistat.pas b/mseide-msegui/lib/common/widgets/mseguirttistat.pas new file mode 100644 index 0000000..8900637 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/mseguirttistat.pas @@ -0,0 +1,92 @@ +{ MSEgui Copyright (c) 2012 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseguirttistat; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} +interface +uses + msegui,mserttistat,mseglob,mseclasses,msestat,msestatfile; + +type + rttistatoption = (rso_autowritestat); + rttistatoptionsty = set of rttistatoption; + + getwidgetclassprocty = procedure (const sender: tobject; + var aclass: widgetclassty) of object; + tguirttistat = class(trttistat) + private + fongetdialogclass: getwidgetclassprocty; + fdialogclass: widgetclassty; + foptions: rttistatoptionsty; + fdialog: twidget; + fonbeforeedit: notifyeventty; + fonafteredit: notifyeventty; + fediting: boolean; + public + function edit: modalresultty; + property dialogclass: widgetclassty read fdialogclass write fdialogclass; + property dialog: twidget read fdialog; + property editing: boolean read fediting; + published + property options: rttistatoptionsty read foptions write foptions default []; + property ongetdialogclass: getwidgetclassprocty read fongetdialogclass + write fongetdialogclass; + property onbeforeedit: notifyeventty read fonbeforeedit write fonbeforeedit; + property onafteredit: notifyeventty read fonafteredit write fonafteredit; + end; + +implementation +uses + sysutils; + +{ tguirttistat } + +function tguirttistat.edit: modalresultty; +var +// dia1: twidget; + cla1: widgetclassty; +begin + result:= mr_none; + cla1:= fdialogclass; + if canevent(tmethod(fongetdialogclass)) then begin + fongetdialogclass(self,cla1); + end; + if cla1 <> nil then begin + fdialog:= cla1.create(nil); + fediting:= true; + try + {$ifdef mse_with_ifi} + objtovalues(fdialog); + {$endif} + if canevent(tmethod(fonbeforeedit)) then begin + fonbeforeedit(self); + end; + result:= fdialog.show(ml_application); + if result = mr_ok then begin + {$ifdef mse_with_ifi} + valuestoobj(fdialog); + {$endif} + if canevent(tmethod(fonafteredit)) then begin + fonafteredit(self); + end; + if (rso_autowritestat in foptions) and (statfile <> nil) then begin + statfile.writestat; + end; + end; + finally + fediting:= false; + freeandnil(fdialog); + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/mseimage.pas b/mseide-msegui/lib/common/widgets/mseimage.pas new file mode 100644 index 0000000..965cdb3 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/mseimage.pas @@ -0,0 +1,188 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseimage; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + classes,mclasses,msegraphics,msegraphutils,msewidgets, + msebitmap,msegui,msemenus,mseevent,mseguiglob; +const + defaultimageoptionswidget = defaultoptionswidgetnofocus + [ow_mousewheel]; +type + timageframe = class(tscrollboxframe) + protected + procedure initinnerframe; override; + published + property framei_left default 0; + property framei_top default 0; + property framei_right default 0; + property framei_bottom default 0; + end; + + timage = class(tscrollingwidget) + private + fbitmap: tmaskedbitmap; + fcolorforeground: colorty; + fcolorbackground: colorty; + procedure setbitmap(const Value: tmaskedbitmap); + procedure bitmapchanged(const sender: tobject); + procedure setcolorbackground(const Value: colorty); + procedure setcolorforeground(const Value: colorty); + protected + procedure paintbmp(const acanvas: tcanvas; const abmp: tmaskedbitmap; + const dest: rectty); + procedure dopaintforeground(const canvas: tcanvas); override; + function calcminscrollsize: sizety; override; + procedure internalcreateframe; override; + procedure getautopaintsize(var asize: sizety); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure changed; virtual; + published + property bitmap: tmaskedbitmap read fbitmap write setbitmap; + property colorforeground: colorty read fcolorforeground //for monochrome bitmaps + write setcolorforeground default cl_black; + property colorbackground: colorty read fcolorbackground //for monochrome bitmaps + write setcolorbackground default cl_white; + property optionswidget default defaultimageoptionswidget; + property onmouseevent; + property onclientmouseevent; + property onchildmouseevent; + property onmousewheelevent; + property onkeydown; + property onkeyup; + property onbeforepaint; + property onpaintbackground; + property onpaint; + property onafterpaint; +end; + +implementation +uses + mseguiintf,msebits,msekeyboard; + +{ timage } + +constructor timage.create(aowner: tcomponent); +begin + fcolorforeground:= cl_black; + fcolorbackground:= cl_white; + fbitmap:= tmaskedbitmap.create(bmk_rgb); + fbitmap.onchange:= {$ifdef FPC}@{$endif}bitmapchanged; + inherited; + optionswidget:= defaultimageoptionswidget; +end; + +destructor timage.destroy; +begin + inherited; + fbitmap.Free; +end; + +procedure timage.changed; +begin + invalidate; + minscrollsizechanged; +end; + +procedure timage.paintbmp(const acanvas: tcanvas; const abmp: tmaskedbitmap; + const dest: rectty); +//var +// col1,col2: colorty; +begin +// col1:= acanvas.color; +// col2:= acanvas.colorbackground; +// acanvas.color:= fcolorforeground; +// acanvas.colorbackground:= fcolorbackground; +// abmp.paint(acanvas,makerect(nullpoint,clientsize)); +// abmp.paint(acanvas,innerclientrect); + abmp.paint(acanvas,dest,fcolorforeground,fcolorbackground); +// acanvas.color:= col1; +// acanvas.colorbackground:= col2; +end; + +procedure timage.dopaintforeground(const canvas: tcanvas); +begin + inherited; +// paintbmp(canvas,fbitmap,makerect(nullpoint,clientsize)); + paintbmp(canvas,fbitmap,innerclientrect); +end; + +procedure timage.setbitmap(const Value: tmaskedbitmap); +begin + fbitmap.assign(Value); +end; + +procedure timage.bitmapchanged(const sender: tobject); +begin + changed; +// invalidate; +end; + +procedure timage.setcolorbackground(const Value: colorty); +begin + if fcolorbackground <> value then begin + fcolorbackground := Value; + changed; + end; +end; + +procedure timage.setcolorforeground(const Value: colorty); +begin + if fcolorforeground <> value then begin + fcolorforeground := Value; + changed; + end; +end; + +function timage.calcminscrollsize: sizety; +var + size1: sizety; +begin + result:= inherited calcminscrollsize; + if fbitmap.alignment * [al_fit,al_thumbnail] = [] then begin + size1:= result; + if not (al_stretchx in fbitmap.alignment) then begin + size1.cx:= fbitmap.bitmap.width+innerframewidth.cx; + end; + if not (al_stretchy in fbitmap.alignment) then begin + size1.cy:= fbitmap.bitmap.height+innerframewidth.cy; + end; + if (result.cx < size1.cx) then begin + result.cx:= size1.cx; + end; + if (result.cy < size1.cy) then begin + result.cy:= size1.cy; + end; + end; +end; + +procedure timage.internalcreateframe; +begin + timageframe.create(iscrollframe(self),self); +end; + +procedure timage.getautopaintsize(var asize: sizety); +begin + asize:= fbitmap.size; + innertopaintsize(asize); +end; + +{ timageframe } + +procedure timageframe.initinnerframe; +begin + //dummy +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/mseinplaceedit.pas b/mseide-msegui/lib/common/widgets/mseinplaceedit.pas new file mode 100644 index 0000000..f08cc3b --- /dev/null +++ b/mseide-msegui/lib/common/widgets/mseinplaceedit.pas @@ -0,0 +1,3026 @@ +{ MSEgui Copyright (c) 1999-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseinplaceedit; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +{$ifndef mse_no_ifi} + {$define mse_with_ifi} +{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + msegui,mseguiglob,msegraphics,msedrawtext,msegraphutils, + mserichstring,msetimer,mseevent,msetypes,msestrings,mseeditglob,msedatalist, + msemenus,mseactions,mseact,mseglob,msegridsglob,mseassistiveclient, + mseificompglob{$ifdef mse_with_ifi},mseifiglob{$endif}; + +const + defaultundomaxcount = 256; + defaultundobuffermaxsize = 100000; + defaultcaretwidth = -1; //use globalcaretwith + defaultglobalcaretwith = -300; //30% of 'o' + +type + editnotificationeventty = procedure(const sender: tobject; + var info: editnotificationinfoty) of object; + + iedit = interface(inullinterface) + function hasselection: boolean; + function getoptionsedit: optionseditty; + procedure editnotification(var info: editnotificationinfoty); + function getwidget: twidget; + procedure updatecopytoclipboard(var atext: msestring); + procedure updatepastefromclipboard(var atext: msestring); + function locatecount: integer; //number of locate values + function locatecurrentindex: integer; //index of current row + procedure locatesetcurrentindex(const aindex: integer); + function getkeystring(const aindex: integer): msestring; //locate text + function getedited: boolean; + end; + + inplaceeditstatety = (ies_focused,ies_emptytext, + ies_poschanging,ies_firstclick,ies_istextedit, + ies_forcecaret,ies_textrectvalid,ies_touched, + ies_edited, + ies_cangroupundo,ies_caretposvalid); + inplaceeditstatesty = set of inplaceeditstatety; + + tinplaceedit = class(tobject,iassistiveclientedit) + private + fwidget: twidget; + fintf: iedit; + finfo: drawtextinfoty; + ftextrectbefore: rectty; + ffont: tfont; + ffontstyle: fontstylesty; + ffontcolor: colorty; + ffontcolorbackground: colorty; + foldtext: msestring; + fselstart: integer; + fsellength: halfinteger; + fcurindex: integer; + curindexbackup,selstartbackup,sellengthbackup: integer; + fupdatecaretcount: integer; + fmoveindexcount: integer; + fcaretpos: pointty; + ftextrect: rectty; + ftextflags: textflagsty; + ftextflagsactive: textflagsty; + fmaxlength: integer; + fpasswordchar: msechar; + fmousemovepos: pointty; + fscrollsum: pointty; //for getcaretpos + frepeater: tsimpletimer; + ffiltertext: msestring; + foptionsedit1: optionsedit1ty; + procedure resetoffset; + function getinsertstate: boolean; + procedure setinsertstate(const Value: boolean); + procedure setsellength(const avalue: halfinteger); + procedure setselstart(const avalue: integer); + function getforcecaret: boolean; + procedure setforcecaret(const avalue: boolean); + procedure internalupdatecaret(force: boolean = false; + nocaret: boolean = false); + procedure updateselect; + procedure updatetextflags(active: boolean); + function internaldeleteselection(textinput: boolean): boolean; + procedure invalidatetextrect(const left,right: integer); + function invalidatepos: integer; + procedure invalidatetext(textinput,trailing: boolean; + startpos: integer = -bigint; endpos: integer = bigint); + //textinput-> notify client, trailing-> from curindex to right + procedure notify(var info: editnotificationinfoty); overload; + procedure notify(action: editactionty); overload; + procedure settextflags(const Value: textflagsty); + procedure settextflagsactive(const Value: textflagsty); + procedure setpasswordchar(const Value: msechar); + procedure setcaretwidth(const Value: integer); + procedure settext(const Value: msestring); + procedure setmaxlength(const Value: integer); + procedure checkmaxlength; + procedure movemouseindex(const sender: tobject); + procedure killrepeater; + procedure setrichtext(const avalue: richstringty); + procedure setformat(const avalue: formatinfoarty); + function nofullinvalidateneeded: boolean; + procedure setfont(const avalue: tfont); + procedure checktextrect; + function gettextrect: rectty; + + procedure setfiltertext(const avalue: msestring); + function getcaretpos: pointty; + protected + fupdating: integer; + fstate: inplaceeditstatesty; + fcaretwidth: integer; + frow: integer; + fbackup: msestring; + function caretonreadonly(): boolean; + function initactioninfo(aaction: editactionty): editnotificationinfoty; + function updateindex(const avalue: int32): int32; + procedure checkindexvalues; + procedure setcurindex(const avalue: integer); + procedure moveindex1(newindex: integer; shift: boolean = false; + donotify: boolean = true); + procedure deletechar; virtual; + procedure deleteback; virtual; + procedure internaldelete(start,len,startindex: integer; + selected: boolean); virtual; + function checkaction(const aaction: editactionty): boolean; overload; + function checkaction(var info: editnotificationinfoty): boolean; overload; + procedure enterchars(const chars: msestring); virtual; + function locating: boolean; + + procedure onundo(const sender: tobject); + procedure onredo(const sender: tobject); + procedure oncopy(const sender: tobject); + procedure oncut(const sender: tobject); + procedure onpaste(const sender: tobject); + procedure onselectall(const sender: tobject); + procedure redo; virtual; + function canredo: boolean; virtual; + function pastefromclipboard( + const buffer: clipboardbufferty): boolean; virtual; + //true if pasted + function copytoclipboard(const buffer: clipboardbufferty): boolean; //true if copied + function cuttoclipboard(const buffer: clipboardbufferty): boolean; virtual; //true if cut + function getiassistiveclient(): iassistiveclientedit virtual; + //iassistiveclient + function getassistiveparent(): iassistiveclient; + function getinstance: tobject; + function getassistivewidget(): tobject; + function getassistivename(): msestring; + function getassistivecaption(): msestring; + function getassistivetext(): msestring; + function getassistivecaretindex(): int32; //-1 -> none + function getassistivehint(): msestring; + function getassistiveflags(): assistiveflagsty; + {$ifdef mse_with_ifi} + function getifidatalinkintf(): iifidatalink; //can be nil + {$endif} + public + constructor create(aowner: twidget; editintf: iedit; + istextedit: boolean = false); + destructor destroy; override; + procedure setup(const text: msestring; cursorindex: integer; shift: boolean; + const atextrect,aclientrect: rectty; + const format: formatinfoarty = nil; + const tabulators: tcustomtabulators = nil; + const font: tfont = nil; noinvalidate: boolean = false); + procedure updatepos(const atextrect,aclientrect: rectty); + procedure movepos(const adist: pointty); //shifts textrects + procedure setscrollvalue(const avalue: real; const horz: boolean); + property font: tfont read ffont write setfont; + property fontstyle: fontstylesty read ffontstyle write ffontstyle default []; + property fontcolor: colorty read ffontcolor write ffontcolor default cl_none; + property fontcolorbackground: colorty read ffontcolor write + ffontcolorbackground default cl_none; + + property widget: twidget read fwidget; + function getfontcanvas: tcanvas; + + function beforechange: boolean; //true if not aborted + procedure begingroup; virtual; + procedure endgroup; virtual; + procedure scroll(const dist: pointty; const scrollcaret: boolean = true); + procedure beginupdate; //no caret update by index change + procedure endupdate; + function updating: boolean; + + procedure updatecaret; + + procedure dokeydown(var kinfo: keyeventinfoty); + procedure mouseevent(var minfo: mouseeventinfoty); + procedure updatepopupmenu(var amenu: tpopupmenu; const popupmenu: tpopupmenu; + var mouseinfo: mouseeventinfoty; + const hasselection: boolean); + procedure setfirstclick(var ainfo: mouseeventinfoty); + procedure doactivate; + procedure dodeactivate; + procedure dofocus; + procedure dodefocus; + procedure dopaint(const canvas: tcanvas); + procedure poschanged; + procedure dragstarted; //kills repeater + + procedure clear; virtual; + procedure initfocus; + procedure moveindex(newindex: integer; shift: boolean = false; + donotify: boolean = true); virtual; + procedure inserttext(const text: msestring; nooverwrite: boolean = true); + function copytoclipboard: boolean; //true if copied + function cuttoclipboard: boolean; //true if cut + function pastefromclipboard: boolean; //true if pasted + procedure deleteselection; + procedure clearundo; + procedure undo; virtual; + procedure selectall; + procedure clearselection; + property forcecaret: boolean read getforcecaret write setforcecaret; + + function optionsedit: optionseditty; + function canedit: boolean; + function canundo: boolean; virtual; + function cancopy: boolean; + function canpaste: boolean; + function getinsertcaretwidth(const canvas: tcanvas; + const afont: tfont): integer; + property insertstate: boolean read getinsertstate write setinsertstate; + property selstart: integer read fselstart write setselstart; + property sellength: halfinteger read fsellength write setsellength; + function selectedtext: msestring; + function hasselection: boolean; + property curindex: integer read fcurindex write setcurindex; + property caretpos: pointty read getcaretpos; + function lasttextclipped: boolean; //result of last drawing + function lasttextclipped(const acliprect: rectty): boolean; + function textclipped: boolean; + function mousepostotextindex(const apos: pointty): integer; + function textindextomousepos(const aindex: integer): pointty; + + property optionsedit1: optionsedit1ty read foptionsedit1 + write foptionsedit1 default defaultoptionsedit1; + property textflags: textflagsty read ftextflags write settextflags; + property textflagsactive: textflagsty read ftextflagsactive + write settextflagsactive; + property passwordchar: msechar read fpasswordchar + write setpasswordchar default #0; + property maxlength: integer read fmaxlength write setmaxlength default -1; + //<0-> no limit + property caretwidth: integer read fcaretwidth write setcaretwidth + default defaultcaretwidth; + //<0-> proportional to width of char 'o', -1024 -> 100% + property text: msestring read finfo.text.text write settext; + property oldtext: msestring read foldtext write foldtext; + property richtext: richstringty read finfo.text write setrichtext; + property format: formatinfoarty read finfo.text.format write setformat; + property destrect: rectty read finfo.dest; + property cliprect: rectty read finfo.clip; + property textrect: rectty read gettextrect; + property filtertext: msestring read ffiltertext write setfiltertext; + end; + + undotypety = (ut_none,ut_setpos,ut_inserttext,ut_overwritetext, + ut_deletetext); + undoflagty = (uf_selected,uf_backwards); + undoflagsty = set of undoflagty; + + undoinfoty = record + text: msestring; //first! + utype: undotypety; + selectstartpos,startpos,endpos: gridcoordty; + flags: undoflagsty; + textbefore: msestring; + link: boolean; + end; + + pundoinfoty = ^undoinfoty; + + iundo = interface(inullinterface) + procedure setedpos(const Value: gridcoordty; const select: boolean; + const donotify: boolean; const ashowcell: cellpositionty); + procedure deletetext(const startpos,endpos: gridcoordty); + procedure inserttext(const pos: gridcoordty; const text: msestring; + selected: boolean; + insertbackwards: boolean); + procedure getselectstart(var selectstartpos: gridcoordty); + procedure setselectstart(const selectstartpos: gridcoordty); + end; + + ttextundolist = class(tdynamicdatalist) + private + fintf: iundo; + flock: integer; + fundopo: integer; + flinked: integer; + fmaxsize: integer; + fbuffersize: integer; + function getitems(const index: integer): pundoinfoty; + function checkrecord(atype: undotypety; const astartpos,aendpos: gridcoordty; + selected: boolean; backwards: boolean; alink: boolean; + textlength: integer): pundoinfoty; + property items[const index: integer]: pundoinfoty read getitems; + function getcanundo: boolean; + function getcanredo: boolean; + function getlocked: boolean; + protected + procedure freedata(var data); override; //gibt daten frei + procedure beforecopy(var data); override; + public + constructor create(intf: iundo); reintroduce; + procedure clear; override; + procedure beginlink(linkto: undotypety; forcenew: boolean); + procedure endlink(forcenew: boolean); + procedure setpos(const endpos: gridcoordty; selected: boolean; + alink: boolean = false); + procedure inserttext(const startpos,endpos: gridcoordty; + const atext: msestring; + selected: boolean; backwards: boolean; alink: boolean = false); + procedure overwritetext(const startpos,endpos: gridcoordty; + const atext,atextbefore: msestring; selected: boolean; + alink: boolean = false); + procedure deletetext(const startpos,endpos: gridcoordty; + const atext: msestring; selected: boolean; + backwards: boolean; alink: boolean = false); + procedure undo; + procedure redo; + property canundo: boolean read getcanundo; + property canredo: boolean read getcanredo; + property maxcount default defaultundomaxcount; + property maxsize: integer read fmaxsize write fmaxsize default defaultundobuffermaxsize; + property locked: boolean read getlocked; + end; + + tundoinplaceedit = class(tinplaceedit) + private + protected + fundolist: ttextundolist; + procedure deletechar; override; + procedure deleteback; override; + procedure internaldelete(start,len,startindex: integer; selected: boolean); override; + procedure enterchars(const chars: msestring); override; + function pastefromclipboard( + const buffer: clipboardbufferty): boolean; override; + function cuttoclipboard(const buffer: clipboardbufferty): boolean; override; + public + constructor create(aowner: twidget; editintf: iedit; undointf: iundo; + istextedit: boolean); + destructor destroy; override; + procedure begingroup; override; + procedure endgroup; override; + function canundo: boolean; override; + function canredo: boolean; override; + procedure undo; override; + procedure redo; override; + procedure moveindex(newindex: integer; shift: boolean = false; + donotify: boolean = true); override; + + property undolist: ttextundolist read fundolist; + end; + +var + globalcaretwidth: integer = defaultglobalcaretwith; + +function textendpoint(const start: pointty; const text: msestring): pointty; + +implementation +uses + msekeyboard,sysutils,msesysutils,msebits,msewidgets,classes,msestockobjects, + mseassistiveserver; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + twidget1 = class(twidget); + +var + overwrite: boolean; //insertstate + +function textendpoint(const start: pointty; const text: msestring): pointty; +var + y: integer; +begin + y:= countchars(text,c_linefeed); + result.y:= start.y + y; + if y = 0 then begin + result.x:= start.x + length(text); + end + else begin + result.x:= length(lastline(text)); + end; +end; + +{ tinplaceedit } + +constructor tinplaceedit.create(aowner: twidget; editintf: iedit; + istextedit: boolean = false); +begin + fwidget:= aowner; + fintf:= editintf; + fcaretwidth:= defaultcaretwidth; + fmaxlength:= -1; + ffontcolor:= cl_none; + ffontcolorbackground:= cl_none; + foptionsedit1:= defaultoptionsedit1; + if istextedit then begin + include(fstate,ies_istextedit); + end; +end; + +destructor tinplaceedit.destroy; +begin + killrepeater; + inherited; +end; + +procedure tinplaceedit.onundo(const sender: tobject); +begin + undo; +end; + +procedure tinplaceedit.onredo(const sender: tobject); +begin + redo; +end; + +procedure tinplaceedit.oncopy(const sender: tobject); +begin + copytoclipboard; +end; + +procedure tinplaceedit.oncut(const sender: tobject); +begin + cuttoclipboard; +end; + +procedure tinplaceedit.onpaste(const sender: tobject); +begin + pastefromclipboard; +end; + +procedure tinplaceedit.onselectall(const sender: tobject); +begin + selectall(); +end; + +procedure tinplaceedit.updatepopupmenu(var amenu: tpopupmenu; + const popupmenu: tpopupmenu; var mouseinfo: mouseeventinfoty; + const hasselection{, cangridcopy}: boolean); +var + states: array of actionstatesty; + sepchar: msechar; + bo1: boolean; + undoindex,redoindex,copyindex,cutindex,pasteindex: integer; +begin + if ies_cangroupundo in fstate then begin + setlength(states,5); + undoindex:= 0; + redoindex:= 1; + copyindex:= 2; + cutindex:= 3; + pasteindex:= 4; + if canredo then begin + states[redoindex]:= []; + end + else begin + states[redoindex]:= [as_disabled]; + end; + end + else begin + setlength(states,4); + undoindex:= 0; + redoindex:= 0; //invalid + copyindex:= 1; + cutindex:= 2; + pasteindex:= 3; + end; + if canundo then begin + states[undoindex]:= []; //undo + end + else begin + states[undoindex]:= [as_disabled]; + end; + bo1:= (cancopy or hasselection) and (passwordchar = #0); + if bo1 {or cangridcopy} then begin + states[copyindex]:= []; //copy + if bo1 and canedit then begin + states[cutindex]:= []; + end + else begin + states[cutindex]:= [as_disabled]; //cut + end; + end + else begin + states[copyindex]:= [as_disabled]; //copy + states[cutindex]:= [as_disabled]; //cut + end; + if canpaste then begin + states[pasteindex]:= []; //paste + end + else begin + states[pasteindex]:= [as_disabled]; + end; + if popupmenu <> nil then begin + sepchar:= popupmenu.shortcutseparator; + end + else begin + sepchar:= tcustommenu.getshortcutseparator(amenu); + end; + if ies_cangroupundo in fstate then begin + tpopupmenu.additems(amenu,fintf.getwidget,mouseinfo, + [stockobjects.captions[sc_Undohk]+sepchar+ + '('+encodeshortcutname(sysshortcuts[sho_groupundo])+')', + stockobjects.captions[sc_Redohk]+sepchar+ + '('+encodeshortcutname(sysshortcuts[sho_groupredo])+')', + stockobjects.captions[sc_Copyhk]+sepchar+ + '('+encodeshortcutname(sysshortcuts[sho_copy])+')', + stockobjects.captions[sc_Cuthk]+sepchar+ + '('+encodeshortcutname(sysshortcuts[sho_cut])+')', + stockobjects.captions[sc_Pastehk]+sepchar+ + '('+encodeshortcutname(sysshortcuts[sho_paste])+')', + stockobjects.captions[sc_Select_allhk]+sepchar+ + '('+encodeshortcutname(sysshortcuts[sho_selectall])+')' + ], + [[mao_nocandefocus],[mao_nocandefocus],[mao_nocandefocus], + [mao_nocandefocus],[mao_nocandefocus]], + states,[@onundo,@onredo,@oncopy,@oncut,@onpaste,@onselectall]); + end + else begin + tpopupmenu.additems(amenu,fintf.getwidget,mouseinfo, + [stockobjects.captions[sc_Undohk]+sepchar+'(Esc)', + stockobjects.captions[sc_Copyhk]+sepchar+ + '('+encodeshortcutname(sysshortcuts[sho_copy])+')', + stockobjects.captions[sc_Cuthk]+sepchar+ + '('+encodeshortcutname(sysshortcuts[sho_cut])+')', + stockobjects.captions[sc_Pastehk]+sepchar+ + '('+encodeshortcutname(sysshortcuts[sho_paste])+')', + stockobjects.captions[sc_Select_allhk]+sepchar+ + '('+encodeshortcutname(sysshortcuts[sho_selectall])+')' + ], + [[mao_nocandefocus],[mao_nocandefocus],[mao_nocandefocus], + [mao_nocandefocus],[mao_nocandefocus]], + states,[@onundo,@oncopy,@oncut,@onpaste,@onselectall]); + end; +end; + +procedure tinplaceedit.notify(var info: editnotificationinfoty); +begin + fintf.editnotification(info); +end; + +procedure tinplaceedit.notify(action: editactionty); +var + info: editnotificationinfoty; +begin + info:= initactioninfo(action); + notify(info); +end; + +function tinplaceedit.checkaction(var info: editnotificationinfoty): boolean; +var + aaction: editactionty; +begin + aaction:= info.action; + fintf.editnotification(info); + result:= aaction = info.action; +end; + +function tinplaceedit.checkaction(const aaction: editactionty): boolean; +var + info: editnotificationinfoty; +begin + info:= initactioninfo(aaction); + result:= checkaction(info); +end; + +function tinplaceedit.beforechange: boolean; +begin + result:= checkaction(ea_beforechange); +end; + +procedure tinplaceedit.killrepeater; +begin + freeandnil(frepeater); +end; + +function tinplaceedit.locating: boolean; +begin + result:= iedit(fintf).getoptionsedit * [oe_locate,oe_readonly] = + [oe_locate,oe_readonly]; +end; + +procedure tinplaceedit.setup(const text: msestring; + cursorindex: integer; shift: boolean; + const atextrect, aclientrect: rectty; + const format: formatinfoarty = nil; + const tabulators: tcustomtabulators = nil; + const font: tfont = nil; + noinvalidate: boolean = false); +begin +// exclude(fstate,ies_emptytext); + finfo.text.text:= text; + ffiltertext:= ''; + if locating then begin + fcurindex:= 0; + end + else begin + fcurindex:= cursorindex; + end; + ftextrect := atextrect; + finfo.dest:= atextrect; + finfo.clip:= aclientrect; + if atextrect.cx < 0 then begin + ftextrect.cx:= 0; + finfo.dest.cx:= 0; + end; + if atextrect.cy < 0 then begin + ftextrect.cy:= 0; + finfo.dest.cy:= 0; + end; + if aclientrect.cx < 0 then begin + finfo.clip.cx:= 0; + end; + ffont:= font; + resetoffset; + finfo.text.format:= copy(format); + finfo.tabulators:= tabulators; + if not shift then begin + fselstart:= updateindex(fcurindex); + fsellength:= 0; + end; + setselected1(finfo.text,fselstart,fsellength); + if fcurindex > length(text) then begin + fcurindex:= length(text); + end; + if not noinvalidate then begin + invalidatetext(false,false); + end; + internalupdatecaret; +end; + +procedure tinplaceedit.updatepos(const atextrect,aclientrect: rectty); +begin + ftextrect := atextrect; + finfo.dest:= atextrect; + finfo.clip:= aclientrect; + invalidatetext(false,false); + internalupdatecaret; +end; + +procedure tinplaceedit.movepos(const adist: pointty); +begin + addpoint1(ftextrect.pos,adist); + addpoint1(finfo.dest.pos,adist); + addpoint1(finfo.clip.pos,adist); + invalidatetext(false,false); + internalupdatecaret; +end; + +procedure tinplaceedit.setfont(const avalue: tfont); +begin + if ffont <> avalue then begin + ffont:= avalue; + invalidatetext(false,false); + internalupdatecaret; + end; +end; + +procedure tinplaceedit.clear; +begin + fsellength:= 0; + fselstart:= 0; + finfo.text.text:= ''; + finfo.text.format:= nil; + clearundo; + invalidatetext(true,false); +end; + +function tinplaceedit.initactioninfo(aaction: editactionty): editnotificationinfoty; +begin + finalize(result); + fillchar(result,sizeof(result),0); + result.action:= aaction; +end; + +function tinplaceedit.getinsertcaretwidth(const canvas: tcanvas; const afont: tfont): integer; +var + int1: integer; +begin + if fcaretwidth = -1 then begin + int1:= globalcaretwidth; + end + else begin + int1:= fcaretwidth; + end; + if int1 < 0 then begin + result:= (canvas.getfontmetrics('o',afont).sum * - int1 - + int1 div 2) div 1024; //round + if result = 0 then begin + result:= 1; + end + end + else begin + result:= int1; + end; +end; + +function tinplaceedit.caretonreadonly(): boolean; +begin + result:= (oe_caretonreadonly in fintf.getoptionsedit) or fwidget.canassistive; +end; + +procedure tinplaceedit.internalupdatecaret(force: boolean = false; + nocaret: boolean = false); +var + wstr1: msestring; + metrics: fontmetricsty; + po1: pointty; + canvas: tcanvas; + afont,font1: tfont; + actioninfo: editnotificationinfoty; + int1,int2: integer; + posbefore: rectty; + updatecaretcountref: integer; +// options1: optionseditty; + haspasswordchar: boolean; + +begin + if (fupdating > 0) or (ws_destroying in fwidget.widgetstate) or + (csdestroying in fwidget.componentstate) then begin + exit; //no createwindow by getcanvas + end; + wstr1:= ''; //compiler warning + inc(fupdatecaretcount); + updatecaretcountref:= fupdatecaretcount; + posbefore:= finfo.dest; +// options1:= fintf.getoptionsedit; + if not (canedit or caretonreadonly()) then begin + nocaret:= true; + end; + actioninfo:= initactioninfo(ea_caretupdating); + if fwidget.active or (ies_forcecaret in fstate) or force then begin + canvas:= getfontcanvas; + haspasswordchar:= (fpasswordchar <> #0) and not (ies_emptytext in fstate); + if haspasswordchar then begin + wstr1:= finfo.text.text; + finfo.text.text:= stringfromchar(fpasswordchar,length(wstr1)); + end; +// fcaretpos:= textindextopos(canvas,finfo,fcurindex); + fcaretpos:= textindextomousepos(fcurindex); + //updates finfo.res + include(fstate,ies_caretposvalid); + fscrollsum:= nullpoint; + int1:= finfo.dest.x + finfo.res.cx; + int2:= ftextrect.x + ftextrect.cx; + if int1 < int2 then begin //right margin + int1:= int2 - int1 + finfo.dest.x; + if int1 > ftextrect.x then begin + int1:= ftextrect.x; + end; + finfo.dest.x:= int1; + end; + int1:= finfo.dest.y + finfo.res.cy; + int2:= ftextrect.y + ftextrect.cy; + if int1 < int2 then begin //bottom margin + int1:= int2 - int1 + finfo.dest.y; + if int1 > ftextrect.y then begin + int1:= ftextrect.y; + end; + finfo.dest.y:= int1; + end; + fcaretpos.x:= fcaretpos.x + finfo.dest.x - posbefore.x; + fcaretpos.y:= fcaretpos.y + finfo.dest.y - posbefore.y; + //add shift + + if haspasswordchar then begin + finfo.text.text:= wstr1; + end; + with finfo,actioninfo do begin + int1:= getinsertcaretwidth(canvas,ffont); + afont:= canvas.font; + if insertstate and not nocaret then begin + caretrect.cx:= int1; + showrect.x:= fcaretpos.x; //for clamp in view + showrect.cx:= caretrect.cx div 2; + if showrect.cx = 0 then begin + showrect.cx:= 1; + end; + caretrect.x:= fcaretpos.x - showrect.cx; + inc(caretrect.x,afont.caretshift); + if showrect.x > caretrect.x then begin + showrect.x:= caretrect.x; + end; + int1:= caretrect.x+caretrect.cx-(showrect.x+showrect.cx); + if int1 > 0 then begin + showrect.cx:= showrect.cx+int1; + end; + end + else begin + font1:= tfont.create; + font1.assign(afont); + font1.style:= getcharstyle(text.format,fcurindex).fontstyle; + if fcurindex < length(text.text) then begin + metrics:= canvas.getfontmetrics(text.text[fcurindex+1],font1); + end + else begin + metrics:= canvas.getfontmetrics('o',font1); + end; + font1.Free; + caretrect.cx:= metrics.width; + if caretrect.cx < int1 then begin + caretrect.cx:= int1; + end; + if not nocaret then begin + caretrect.x:= fcaretpos.x + metrics.leftbearing; + end + else begin + caretrect.x:= fcaretpos.x; + caretrect.cx:= 0; + end; + showrect.x:= caretrect.x; + showrect.cx:= caretrect.cx; + end; + + caretrect.y:= fcaretpos.y - afont.ascent; + caretrect.cy:= afont.ascent + afont.descent; + showrect.y:= caretrect.y; + showrect.cy:= caretrect.cy; + + po1:= nullpoint; + if ies_focused in fstate then begin + with showrect do begin //bring caret into clientrect; + if x < ftextrect.x then begin + po1.x:= ftextrect.x - x; + end + else begin + if x + cx > ftextrect.x + ftextrect.cx then begin + po1.x:= ftextrect.x + ftextrect.cx - x -cx; + end; + end; + if y < ftextrect.y then begin + po1.y:= ftextrect.y - y; + end + else begin + if y + cy > ftextrect.y + ftextrect.cy then begin + po1.y:= ftextrect.y + ftextrect.cy - y -cy; + end; + end; + end; + if not isnullpoint(po1) then begin + if not (tf_clipi in flags) then begin + addpoint1(dest.pos,po1); + int1:= dest.x - ftextrect.x; + if int1 > 0 then begin //use cliprect space + int2:= ftextrect.x - clip.x; + if int1 > int2 then begin + int1:= int2; + end; + po1.x:= po1.x - int1; + dest.x:= dest.x - int1; + end; + end + else begin + if tf_right in flags then begin + dest.cx:= dest.cx + po1.x; + end + else begin + if tf_xcentered in flags then begin + dest.x:= dest.x + po1.x; + int1:= dest.x - ftextrect.x; + int2:= ftextrect.y+ftextrect.cx - (dest.x+dest.cx); + if int2 > int1 then begin //adjust to textrect + int1:= int2; + end; + dest.x:= dest.x - int1; + dest.cx:= dest.cx + 2*int1; + end + else begin + dest.x:= dest.x + po1.x; + dest.cx:= dest.cx - po1.x; + end; + end; + if tf_bottom in flags then begin + dest.cy:= dest.cy + po1.y; + end + else begin + if tf_ycentered in flags then begin + dest.y:= dest.y + po1.y; + int1:= dest.y - ftextrect.y; + int2:= ftextrect.y+ftextrect.cy - (dest.y+dest.cy); + if int2 > int1 then begin //adjust to textrect + int1:= int2; + end; + dest.y:= dest.y - int1; + dest.cy:= dest.cy + 2*int1; + end + else begin + dest.y:= dest.y + po1.y; + dest.cy:= dest.cy - po1.y; + end; + end; + end; + addpoint1(fcaretpos,po1); + addpoint1(caretrect.pos,po1); + addpoint1(showrect.pos,po1); + end; + end; + end; + if (ies_poschanging in fstate) or checkaction(actioninfo) then begin + if updatecaretcountref <> fupdatecaretcount then begin + exit; + end; + if (fwidget.activefocused or (ies_forcecaret in fstate)) and + not nocaret then begin + fwidget.getcaret; + with application.caret do begin + bounds:= actioninfo.caretrect; + show; + end; + end; + if nocaret then begin + if fwidget.hascaret then begin + application.caret.hide; + end; + end; + end; + end; + if (finfo.dest.x <> posbefore.x) or (finfo.dest.y <> posbefore.y) or + (finfo.dest.cx <> posbefore.cx) or + (finfo.dest.cy <> posbefore.cy) then begin + invalidatetextrect(minint,bigint); + end; +end; + +function tinplaceedit.getforcecaret: boolean; +begin + result:= ies_forcecaret in fstate; +end; + +procedure tinplaceedit.setforcecaret(const avalue: boolean); +begin + if avalue then begin + include(fstate,ies_forcecaret); + end + else begin + exclude(fstate,ies_forcecaret); + end; + internalupdatecaret(true); +end; + +procedure tinplaceedit.invalidatetextrect(const left,right: integer); +var + rect1: rectty; +begin + exclude(fstate,ies_textrectvalid); + rect1.x:= left; + rect1.cx:= right-left; + rect1.y:= finfo.clip.y; + rect1.cy:= finfo.clip.cy; + if msegraphutils.intersectrect(finfo.clip,rect1,rect1) then begin + fwidget.invalidaterect(rect1,org_client); + end; +end; + +procedure tinplaceedit.updateselect; +begin + if fselstart + fsellength > length(finfo.text.text) then begin + fsellength:= length(finfo.text.text) - fselstart; + end; + if fsellength < 0 then begin + fsellength:= 0; + end; + setselected1(finfo.text,fselstart,fsellength); + invalidatetextrect(minint,bigint); +end; + +procedure tinplaceedit.resetoffset; +begin + finfo.dest:= ftextrect; +end; + +procedure tinplaceedit.updatetextflags(active: boolean); +var + textflagsbefore: textflagsty; +begin + textflagsbefore:= finfo.flags; + if active then begin + finfo.flags:= ftextflagsactive; + end + else begin + finfo.flags:= ftextflags; + end; + if finfo.flags <> textflagsbefore then begin + resetoffset; + invalidatetext(false,false); + end; +end; + +procedure tinplaceedit.invalidatetext(textinput, trailing: boolean; + startpos: integer = -bigint; endpos: integer = bigint); +begin + if trailing then begin + invalidatetextrect(invalidatepos,endpos); + end + else begin + invalidatetextrect(startpos,endpos); + end; + notify(ea_textchanged); + if textinput then begin + notify(ea_textedited); + end; + if fcurindex > length(finfo.text.text) then begin + fcurindex:= length(finfo.text.text); + end; +end; + +function tinplaceedit.nofullinvalidateneeded: boolean; +begin + result:= finfo.flags * [tf_wordbreak,tf_xcentered,tf_right] = []; + +end; + +function tinplaceedit.getinsertstate: boolean; +begin + result:= not overwrite; +end; + +procedure tinplaceedit.setinsertstate(const Value: boolean); +var + m1: editinputmodety; +begin + overwrite:= not value; + internalupdatecaret; + if twidget1(fwidget).canassistive() then begin + m1:= eim_insert; + if overwrite then begin + m1:= eim_overwrite; + end; + assistiveserver.doeditinputmodeset(getiassistiveclient(),m1); + end; +end; + +function tinplaceedit.optionsedit: optionseditty; +begin + result:= fintf.getoptionsedit; +end; + +function tinplaceedit.canedit: boolean; +begin + result:= not (oe_readonly in iedit(fintf).getoptionsedit); +end; + +function tinplaceedit.canundo: boolean; +begin + result:= (ies_edited in fstate) or not (ies_emptytext in fstate) and + (fbackup <> finfo.text.text) or fintf.getedited; +end; + +function tinplaceedit.cancopy: boolean; +begin + result:= fsellength > 0; +end; + +function tinplaceedit.canpaste: boolean; +begin + result:= canedit and canpastefromclipboard; +end; + +function tinplaceedit.textclipped: boolean; +begin +// msedrawtext.textrect(getfontcanvas,finfo); +// result:= not rectinrect(finfo.res,fowner.innerclientrect); + result:= not rectinrect(gettextrect,fwidget.innerclientrect); +end; + +function tinplaceedit.lasttextclipped: boolean; +begin + result:= not rectinrect(finfo.res,finfo.clip); +end; + +function tinplaceedit.lasttextclipped(const acliprect: rectty): boolean; +begin + result:= not rectinrect(finfo.res,intersectrect(finfo.clip,acliprect)); +end; + +function tinplaceedit.mousepostotextindex(const apos: pointty): integer; +var + mstr1: msestring; +begin + if (fpasswordchar <> #0) and not (ies_emptytext in fstate) then begin + mstr1:= finfo.text.text; + finfo.text.text:= stringfromchar(fpasswordchar,length(mstr1)); + postotextindex(getfontcanvas,finfo,apos,result); + finfo.text.text:= mstr1; + end + else begin + if ies_emptytext in fstate then begin + result:= 0; + end + else begin + postotextindex(getfontcanvas,finfo,apos,result); + end; + end; +end; + +function tinplaceedit.textindextomousepos(const aindex: integer): pointty; +var + mstr1: msestring; +begin + ftextrectbefore:= finfo.res; + if (fpasswordchar <> #0) and not (ies_emptytext in fstate) then begin + mstr1:= finfo.text.text; + finfo.text.text:= stringfromchar(fpasswordchar,length(mstr1)); + result:= textindextopos(getfontcanvas,finfo,aindex); + finfo.text.text:= mstr1; + end + else begin + if ies_emptytext in fstate then begin + result:= textindextopos(getfontcanvas,finfo,0); + end + else begin + result:= textindextopos(getfontcanvas,finfo,aindex); + end; + end; + checktextrect; +end; + +procedure tinplaceedit.deleteselection; +var + s1: msestring; +begin + if twidget1(fwidget).canassistive() then begin + s1:= selectedtext(); + end; + if fsellength > 0 then begin + clearundo; + end; + internaldeleteselection(true); //every time called for ttextedit + if (s1 <> '') and twidget1(fwidget).canassistive() then begin + assistiveserver.doedittextblock(getiassistiveclient(),etbm_delete,s1); + end; +end; + +procedure tinplaceedit.clearundo; +begin + if ies_emptytext in fstate then begin + fbackup:= ''; + end + else begin + fbackup:= finfo.text.text; + end; + exclude(fstate,ies_edited); + foldtext:= fbackup; + curindexbackup:= fcurindex; + selstartbackup:= fselstart; + sellengthbackup:= fsellength; +end; + +procedure tinplaceedit.undo; +begin + if checkaction(ea_undo) then begin + finfo.text.text:= fbackup; + fselstart:= selstartbackup; + fsellength:= sellengthbackup; + updateselect; + curindex:= curindexbackup; + invalidatetext(false,false); + fstate:= fstate - [ies_touched,ies_edited]; + notify(ea_undone); + if twidget1(fwidget).canassistive() then begin + assistiveserver.doeditwithdrawn(getiassistiveclient); + end; + end; +end; + +procedure tinplaceedit.deleteback; +var + bo1: boolean; + ch1: msechar; + s1: msestring; +begin + if ies_emptytext in fstate then begin + exit; + end; + if fcurindex > 0 then begin + ch1:= finfo.text.text[fcurindex]; + end + else begin + ch1:= #0; + end; + bo1:= nofullinvalidateneeded and (ch1 <> c_return) and (ch1 <> c_linefeed); + if (fcurindex > 1) and + ((card16(ch1) and $fc00 = $dc00) or + (finfo.text.text[fcurindex-1] = c_return) and + (ch1 = c_linefeed)) then begin + s1:= copy(finfo.text.text,fcurindex-1,2); + richdelete(finfo.text,fcurindex-1,2); + fcurindex:= fcurindex - 2; + end + else begin + s1:= copy(finfo.text.text,fcurindex,1); + richdelete(finfo.text,fcurindex,1); + fcurindex:= fcurindex - 1; + end; + fstate:= fstate + [ies_touched,ies_edited]; + internalupdatecaret(true); + if twidget1(fwidget).canassistive() then begin + assistiveserver.doeditchardelete(getiassistiveclient(),s1); + end; + invalidatetext(true,bo1); + notify(ea_indexmoved); +end; + +procedure tinplaceedit.deletechar; +var + bo1: boolean; + ch1: msechar; + s1: msestring; +begin + if ies_emptytext in fstate then begin + exit; + end; + if fcurindex < length(finfo.text.text) then begin + ch1:= finfo.text.text[fcurindex+1]; + end + else begin + ch1:= #0; + end; + bo1:= nofullinvalidateneeded and (ch1 <> c_return) and (ch1 <> c_linefeed); + if (card16(ch1) and $fc00 = $d800) or + (ch1 = c_linefeed) and (fcurindex > 0) and + (finfo.text.text = c_return) then begin + s1:= copy(finfo.text.text,fcurindex+1,2); + richdelete(finfo.text,fcurindex+1,2); + end + else begin + s1:= copy(finfo.text.text,fcurindex+1,1); + richdelete(finfo.text,fcurindex+1,1); + end; + fstate:= fstate + [ies_touched,ies_edited]; + invalidatetext(true,bo1); + if twidget1(fwidget).canassistive() then begin + assistiveserver.doeditchardelete(getiassistiveclient(),s1); + end; +// if not bo1 then begin + internalupdatecaret; +// end; +end; + +procedure tinplaceedit.dokeydown(var kinfo: keyeventinfoty); +var + nochars: boolean; + finished: boolean; + actioninfo: editnotificationinfoty; + bo1: boolean; + opt1: optionseditty; + locating1: boolean; + shiftstate1,shiftstate2: shiftstatesty; + int1: integer; + ismultilinectrl: boolean; + s1: msestring; + +begin + with kinfo do begin + shiftstate1:= shiftstate * keyshiftstatesmask; + if (es_processed in eventstate) then begin + exit; + end; + opt1:= iedit(fintf).getoptionsedit; + locating1:= opt1 * [oe_locate,oe_readonly] = [oe_locate,oe_readonly]; + include(eventstate,es_processed); + actioninfo:= initactioninfo(ea_exit); + if ss_shift in shiftstate1 then begin + include(actioninfo.state,eas_shift); + end; + nochars:= true; + finished:= true; + if not(oe1_noselectall in foptionsedit1) and + issysshortcut(sho_selectall,kinfo) then begin + selectall; + end + else begin + if issysshortcut(sho_copy,kinfo) then begin + if (passwordchar = #0) and hasselection then begin + finished:= copytoclipboard(cbb_clipboard);; + end + else begin + finished:= false; + end; + end + else begin + if issysshortcut(sho_paste,kinfo) then begin + if canedit then begin + finished:= pastefromclipboard(cbb_clipboard); + end + else begin + finished:= false; + end; + end + else begin + if issysshortcut(sho_cut,kinfo) then begin + if canedit and (passwordchar = #0) and hasselection then begin + finished:= cuttoclipboard(cbb_clipboard); + end + else begin + finished:= false; + end; + end + else begin + finished:= false; + if ies_cangroupundo in fstate then begin + if issysshortcut(sho_groupundo,kinfo) then begin + if canundo then begin + undo; + finished:= true; + end; + end + else begin + if issysshortcut(sho_groupredo,kinfo) then begin + if canredo then begin + redo; + finished:= true; + end; + end; + end; + end; + end; + end; + end; + end; + if finished then begin + exit; + end; + ismultilinectrl:= (oe1_multiline in foptionsedit1) and + ((key = key_end) or (key = key_home)); + if (shiftstate1 <> [ss_ctrl]) or ismultilinectrl then begin + finished:= true; + bo1:= true; + if (key = key_return) {or (key = key_enter)} then begin + removechar1(chars,c_return); + removechar1(chars,c_linefeed); + if (shiftstate1 - [ss_shift] = []) and (oe_linebreak in opt1) and + ((oe_shiftreturn in opt1) xor (shiftstate1 = []))then begin + finished:= false; + nochars:= false; + bo1:= false; + chars:= chars + lineend; + fwidget.invalidate; + end; + end; + if bo1 then begin + if (shiftstate1 = []) then begin + case key of + key_return{,key_enter}: begin + if checkaction(ea_textentered) then begin + exclude(eventstate,es_processed); + end; + end; + key_escape: begin + if canundo and (oe_undoonesc in opt1) and + not (ies_cangroupundo in fstate) then begin + undo; + end + else begin + exclude(eventstate,es_processed); + end; + end; + key_insert: begin + insertstate:= not insertstate; + end; + key_backspace: begin + if locating1 then begin + filtertext:= copy(filtertext,1,length(filtertext)-1); + end + else begin + include(actioninfo.state,eas_delete); + actioninfo.dir:= gd_left; + if canedit then begin + if fsellength > 0 then begin + deleteselection; + end + else begin + if fcurindex > 0 then begin + actioninfo.action:= ea_delchar; + if checkaction(actioninfo) then begin + deleteback; + end; + end + else begin + if checkaction(actioninfo) then begin + finished:= false; + end; + end; + end; + end + else begin + exclude(eventstate,es_processed); + end; + end; + end; + key_delete: begin + if canedit then begin + if fsellength > 0 then begin + s1:= selectedtext(); + internaldeleteselection(true); + if twidget1(fwidget).canassistive() then begin + assistiveserver.doedittextblock(getiassistiveclient(), + etbm_delete,s1); + end; + end + else begin + actioninfo.action:= ea_delchar; + actioninfo.dir:= gd_none; + if checkaction(actioninfo) then begin + if fcurindex < length(finfo.text.text) then begin + deletechar; + end + else begin + finished:= false; + end; + end; + end; + end + else begin + exclude(eventstate,es_processed); + end; + end; + key_tab: begin + exclude(eventstate,es_processed); + if (finfo.tabulators <> nil) then begin + nochars:= false; + end; + end; + else begin + finished:= false; + nochars:= false; + end; + end; + end + else begin + if shiftstate1 = [ss_shift] then begin + finished:= false; + nochars:= false; + end + else begin + finished:= false; + end; + end; + end; + if not finished then begin + finished:= true; + shiftstate2:= shiftstate1; + if ismultilinectrl then begin + exclude(shiftstate2,ss_ctrl); + end; + if (shiftstate2 = []) or (shiftstate2 = [ss_shift]) then begin + case key of + key_tab,key_backtab,key_escape,key_backspace,key_delete: begin //nochars + finished:= false; + nochars:= true; + end; + key_home: begin + if locating1 and (shiftstate2 = []) then begin + filtertext:= ''; + end + else begin + if not (oe1_multiline in foptionsedit1) or + (ss_ctrl in shiftstate1) then begin + moveindex1(0,ss_shift in shiftstate1); + end + else begin + int1:= mousepostotextindex(mp(-bigint,fcaretpos.y)); + moveindex1(int1,ss_shift in shiftstate1); + end; + end; + end; + key_end: begin + if locating1 and (shiftstate2 = []) then begin + filtertext:= finfo.text.text; + end + else begin + if not (oe1_multiline in foptionsedit1) or + (ss_ctrl in shiftstate1) then begin + moveindex1(length(finfo.text.text),ss_shift in shiftstate1); + end + else begin + int1:= mousepostotextindex(mp(bigint,fcaretpos.y)); + moveindex1(int1,ss_shift in shiftstate1); + end; + end; + end; + key_left: begin + if not(oe_nofirstarrownavig in opt1) and (shiftstate1 <> [ss_shift]) and + ((fsellength = length(finfo.text.text)) or + not(ies_touched in fstate) and + (fcurindex = length(finfo.text.text)) + ) or + (fcurindex = 0) and + ((fsellength = 0) or (shiftstate1 <> [ss_shift]) or + (ies_istextedit in fstate) + ) or + (oe_readonly in opt1) and not caretonreadonly()then begin + actioninfo.dir:= gd_left; + if checkaction(actioninfo) then begin + if not(oe_exitoncursor in opt1) then begin + if shiftstate1 <> [ss_shift] then begin + sellength:= 0; + end; + end + else begin + finished:= false; + end; + end; + end + else begin + moveindex1(fcurindex-1,shiftstate1 = [ss_shift]); + end; + end; + key_right: begin + if not(oe_nofirstarrownavig in opt1) and (shiftstate1 <> [ss_shift]) and + ((fsellength = length(finfo.text.text)) or + not(ies_touched in fstate) and + (fcurindex = 0) + ) or + (fcurindex = length(finfo.text.text)) and + ((shiftstate1 <> [ss_shift]) or (fsellength = 0) or + (ies_istextedit in fstate) or + (fsellength = length(finfo.text.text)) and + (oe_autoselect in opt1) and (shiftstate1 <> [ss_shift]) + ) or + (oe_readonly in opt1) and not caretonreadonly() then begin + actioninfo.dir:= gd_right; + if checkaction(actioninfo) then begin + if not(oe_exitoncursor in opt1) or + ((fsellength = length(finfo.text.text)) and (fsellength <> 0)) and + (shiftstate1 <> [ss_shift]) and + (oe_nofirstarrownavig in opt1) then begin + if shiftstate1 <> [ss_shift] then begin + sellength:= 0; + end; + end + else begin + finished:= false; + end; + end; + end + else begin + moveindex1(fcurindex+1,shiftstate1 = [ss_shift]); + end; + end + else begin + finished:= false; + nochars:= false; + end; + end; + end + else begin + finished:= false; + if (shiftstate1 = [ss_ctrl,ss_alt]) and + not (ss_second in shiftstate) then begin + nochars:= false; + end; + end; + end; + end; + if not finished then begin + exclude(eventstate,es_processed); + end; + if not (es_processed in eventstate) and not nochars and (chars <> '') then begin + if locating1 then begin + filtertext:= filtertext + chars; + include(eventstate,es_processed); + end + else begin + if canedit then begin + enterchars(chars); + fselstart:= updateindex(fcurindex); + include(eventstate,es_processed); + end; + end; + end; + end; +end; + +procedure tinplaceedit.setfirstclick(var ainfo: mouseeventinfoty); +begin + include(fstate,ies_firstclick); + resetoffset; + finfo.flags:= ftextflags; //restore flags before activate +end; + +procedure tinplaceedit.mouseevent(var minfo: mouseeventinfoty); +var + po1: pointty; + int1: integer; + opt1: optionseditty; + autoselect1: boolean; +begin + with minfo do begin + if es_drag in eventstate then begin + killrepeater; + end + else begin + opt1:= fintf.getoptionsedit; + autoselect1:= (oe_autoselectonfirstclick in opt1) and + (opt1 * [oe_locate,oe_readonly] <> [oe_locate,oe_readonly]); + case eventkind of + ek_buttonpress: begin + if pointinrect(pos,finfo.clip) and + (minfo.button = mb_left) or (minfo.button = mb_middle) and + not (oe_readonly in opt1) then begin + if not ((minfo.button = mb_middle) and + (minfo.shiftstate * shiftstatesmask <> [ss_middle])) then begin + if not fwidget.focused and fwidget.canfocus and + (ow_mousefocus in fwidget.optionswidget) then begin + if minfo.button = mb_left then begin + include(fstate,ies_firstclick); + end; + include(minfo.eventstate,es_processed); + int1:= mousepostotextindex(pos); + moveindex(int1,false); + internalupdatecaret(true); + po1:= fcaretpos; + include(eventstate,es_nofocus); + if not fwidget.setfocus then begin + exclude(fstate,ies_firstclick); + exit; + end; + if autoselect1 and (minfo.button = mb_left) then begin + selectall; + subpoint1(po1,textindextomousepos(int1)); + end + else begin + moveindex(int1,false); + subpoint1(po1,fcaretpos); + end; + end + else begin + int1:= mousepostotextindex(pos); + po1:= textindextomousepos(int1); + if (ies_firstclick in fstate) then begin + finfo.flags:= ftextflagsactive; + if autoselect1 and (minfo.button = mb_left) then begin + selectall; + end + else begin + initfocus; + moveindex(int1,false); + end; + end + else begin + moveindex(int1,ss_shift in shiftstate); + end; + subpoint1(po1,textindextomousepos(int1)); + end; + if (minfo.button = mb_middle) and + not (oe_readonly in fintf.getoptionsedit) then begin + //cold be changed by moveindex + addpoint1(po1,textindextomousepos(int1)); + clearselection; + pastefromclipboard(cbb_primary); + subpoint1(po1,textindextomousepos(int1)); + end; + subpoint1(pos,po1); + if pos.x < ftextrect.x then begin + pos.x:= ftextrect.x; + end; + if pos.x > ftextrect.x + ftextrect.cx then begin + pos.x:= ftextrect.x + ftextrect.cx; + end; + if pos.y < ftextrect.y then begin + pos.y:= ftextrect.y; + end; + if pos.y > ftextrect.y + ftextrect.cy then begin + pos.y:= ftextrect.y + ftextrect.cy; + end; + end; + end; + end; + ek_buttonrelease,ek_mousecaptureend: begin + killrepeater; + exclude(fstate,ies_firstclick); + end; + ek_mousemove: begin + if fwidget.clicked and + not ((ies_firstclick in fstate) and autoselect1) then begin + fmousemovepos:= minfo.pos; + if not pointinrect(pos,ftextrect) then begin + if frepeater = nil then begin + movemouseindex(nil); + frepeater:= tsimpletimer.create(100000, + {$ifdef FPC}@{$endif}movemouseindex,true,[]); + end; + end + else begin + killrepeater; + movemouseindex(nil); + end; + end; + end; + end; + end; + end; +end; + +procedure tinplaceedit.movemouseindex(const sender: tobject); +begin + moveindex(mousepostotextindex(fmousemovepos),true); + if passwordchar = #0 then begin + copytoclipboard(cbb_primary); + end; +// msewidgets.copytoclipboard(selectedtext,cbb_primary); +end; + +function tinplaceedit.invalidatepos: integer; +begin + result:= fcaretpos.x - getfontcanvas.getfontmetrics('o').width; +end; + +procedure tinplaceedit.inserttext(const text: msestring; + nooverwrite: boolean = true); +var + int1,int2,int3: integer; +begin + if ies_emptytext in fstate then begin + finfo.text.text:= ''; + end; + if insertstate or nooverwrite then begin + richinsert(text,finfo.text,fcurindex+1); + end + else begin + replacetext1(finfo.text.text,fcurindex+1,text); + end; + checkmaxlength; + if ies_emptytext in fstate then begin + notify(ea_resetemptytext); //remove empty_text settings + end; + int3:= getfontcanvas.getfontmetrics('o').width; + int1:= fcaretpos.x - int3; + moveindex(fcurindex + length(text),false); + if nofullinvalidateneeded then begin + if (fcurindex = length(finfo.text.text)) then begin + int2:= fcaretpos.x + int3; + invalidatetext(true,false,int1,int2); + end + else begin + invalidatetext(true,false,int1); + end; + end + else begin + invalidatetext(true,false); + end; + { + if twidget1(fwidget).canassistive() then begin + assistiveserver.doedittextblock(getiassistiveclient(),etbm_insert,text); + end; + } +end; + +procedure tinplaceedit.moveindex(newindex: integer; shift: boolean; + donotify: boolean); + //cursor verschieben +var + anchor: integer; + selstartbefore,sellengthbefore: integer; + info: editnotificationinfoty; + int1: integer; + moveindexcountref: integer; + +begin + if (newindex <> 0) and (ies_emptytext in fstate) then begin + exit; + end; + include(fstate,ies_touched); + inc(fmoveindexcount); + moveindexcountref:= fmoveindexcount; + selstartbefore:= fselstart; + sellengthbefore:= fsellength; + if newindex > length(finfo.text.text) then begin + newindex:= length(finfo.text.text); + end + else begin + if newindex < 0 then begin + newindex:= 0; + end; + end; + if finfo.text.text <> '' then begin + if (newindex < fcurindex) and + (card16(finfo.text.text[newindex]) and $fc00 = $d800) then begin + dec(newindex); //surrogate pair + end + else begin + if (newindex > fcurindex) and + (card16(finfo.text.text[newindex]) and $fc00 = $d800) then begin + inc(newindex); //surrogate pair + end; + end; + end; + if shift then begin + if fcurindex = fselstart then begin + anchor:= fselstart + fsellength; + end + else begin + anchor:= fselstart; + end; + if newindex <= anchor then begin + fselstart:= newindex; + fsellength:= anchor-newindex; + end + else begin + fselstart:= anchor; + fsellength:= newindex - anchor; + end; + end + else begin + fselstart:= newindex; + fsellength:= 0; + notify(ea_clearselection); + if moveindexcountref <> fmoveindexcount then begin + exit; + end; + end; + if (ies_istextedit in fstate) or (sellengthbefore <> fsellength) or + (selstartbefore <> fselstart) and (fsellength <> 0) then begin + updateselect; + end; + int1:= fcurindex; + curindex:= newindex; + if moveindexcountref <> fmoveindexcount then begin + exit; + end; + if (fcurindex > newindex) and (int1 > newindex) then begin + curindex:= newindex-1; //linebreak + end; + if donotify then begin + internalupdatecaret(true); + if moveindexcountref <> fmoveindexcount then begin + exit; + end; + info:= initactioninfo(ea_indexmoved); + if shift then begin + include(info.state,eas_shift); + end; + notify(info); + { + if twidget1(fwidget).canassistive() then begin + assistiveserver.doeditindexmoved(getiassistiveclient(),fcurindex); + end; + } + end; +end; + +procedure tinplaceedit.moveindex1(newindex: integer; shift: boolean = false; + donotify: boolean = true); +begin + moveindex(newindex,shift,donotify); + if twidget1(fwidget).canassistive() then begin + assistiveserver.doeditindexmoved(getiassistiveclient(),fcurindex); + end; +end; + +function tinplaceedit.updateindex(const avalue: int32): int32; +begin + result:= avalue; + if result > length(finfo.text.text) then begin + result:= length(finfo.text.text); + end + else begin + if result < 0 then begin + result:= 0; + end; + end; + if (finfo.text.text <> '') and + (card16(finfo.text.text[result]) and $fc00 = $d800) then begin + inc(result); //surrogate pair + end; +end; + +procedure tinplaceedit.setcurindex(const avalue: integer); +begin + include(fstate,ies_touched); + fcurindex:= updateindex(avalue); + exclude(fstate,ies_caretposvalid); + internalupdatecaret(ies_forcecaret in fstate); +end; + +procedure tinplaceedit.setsellength(const avalue: halfinteger); +begin + if fsellength <> avalue then begin + fsellength:= updateindex(fselstart+avalue) - fselstart; + updateselect; + end; +end; + +procedure tinplaceedit.setselstart(const avalue: integer); +begin + if fselstart <> avalue then begin + fselstart:= updateindex(avalue); + if fsellength > 0 then begin + updateselect; + end; + end; +end; + +function tinplaceedit.copytoclipboard(const buffer: clipboardbufferty): boolean; +var + mstr1: msestring; + info: editnotificationinfoty; +begin + info:= initactioninfo(ea_copyselection); + info.bufferkind:= buffer; + result:= true; + if checkaction(info) then begin + if fsellength > 0 then begin + mstr1:= selectedtext; + fintf.updatecopytoclipboard(mstr1); + msewidgets.copytoclipboard(mstr1,info.bufferkind); + if twidget1(fwidget).canassistive() then begin + assistiveserver.doedittextblock(getiassistiveclient(),etbm_copy, + selectedtext); + end; + end + else begin + result:= false; + end; + end; +end; + +function tinplaceedit.copytoclipboard: boolean; +begin + result:= copytoclipboard(cbb_clipboard); +end; + +function tinplaceedit.cuttoclipboard(const buffer: clipboardbufferty): boolean; +var + s1: msestring; +begin + s1:= selectedtext; + result:= copytoclipboard(buffer); + deleteselection; + if twidget1(fwidget).canassistive() then begin + assistiveserver.doedittextblock(getiassistiveclient(),etbm_cut, + s1); + end; +end; + +function tinplaceedit.getiassistiveclient(): iassistiveclientedit; +begin + result:= iassistiveclientedit(self); +end; + +function tinplaceedit.getassistiveparent(): iassistiveclient; +begin + result:= twidget1(fwidget).getassistiveparent(); +end; + +function tinplaceedit.getinstance: tobject; +begin + result:= twidget1(fwidget).getinstance(); +end; + +function tinplaceedit.getassistivewidget(): tobject; +begin + result:= twidget1(fwidget).getassistivewidget(); +end; + +function tinplaceedit.getassistivename(): msestring; +begin + result:= twidget1(fwidget).getassistivename(); +end; + +function tinplaceedit.getassistivecaption(): msestring; +begin + result:= twidget1(fwidget).getassistivecaption(); +end; + +function tinplaceedit.getassistivetext(): msestring; +begin + result:= twidget1(fwidget).getassistivetext(); +end; + +function tinplaceedit.getassistivecaretindex(): int32; +begin + result:= twidget1(fwidget).getassistivecaretindex(); +end; + +function tinplaceedit.getassistivehint(): msestring; +begin + result:= twidget1(fwidget).getassistivehint(); +end; + +function tinplaceedit.getassistiveflags(): assistiveflagsty; +begin + result:= twidget1(fwidget).getassistiveflags(); + include(result,asf_inplaceedit); +end; + +function tinplaceedit.getifidatalinkintf(): iifidatalink; +begin + result:= twidget1(fwidget).getifidatalinkintf(); +end; + +function tinplaceedit.cuttoclipboard: boolean; +begin + result:= cuttoclipboard(cbb_clipboard); +end; + +function tinplaceedit.pastefromclipboard( + const buffer: clipboardbufferty): boolean; +var + int1: integer; + info: editnotificationinfoty; + wstr1: msestring; +begin + info:= initactioninfo(ea_pasteselection); + info.bufferkind:= buffer; + result:= true; + if checkaction(info) then begin + if msewidgets.pastefromclipboard(wstr1,info.bufferkind) then begin + fintf.updatepastefromclipboard(wstr1); + deleteselection; + int1:= fcurindex; + inserttext(wstr1); + fselstart:= int1; + fsellength:= length(wstr1); + updateselect; + if twidget1(fwidget).canassistive() then begin + assistiveserver.doedittextblock(getiassistiveclient(),etbm_paste,wstr1); + end; + end + else begin + result:= false; + end; + end; +end; + +function tinplaceedit.pastefromclipboard: boolean; +begin + result:= pastefromclipboard(cbb_clipboard); +end; + +function tinplaceedit.internaldeleteselection(textinput: boolean): boolean; +var + aselstart,asellength: integer; +begin + beforechange; + result:= checkaction(ea_deleteselection); + if result then begin + if fsellength > 0 then begin + aselstart:= fselstart; + asellength:= fsellength; + if asellength > 0 then begin + internaldelete(aselstart,asellength,fcurindex,true); + end; + include(fstate,ies_edited); + moveindex(fselstart,false); + sellength:= 0; + invalidatetext(textinput,nofullinvalidateneeded); + end; + end; +end; + +procedure tinplaceedit.internaldelete(start, len, startindex: integer; + selected: boolean); + //selected is for tundoinplaceedit +begin + richdelete(finfo.text,start+1,len); +end; + +procedure tinplaceedit.selectall; +begin + if ies_emptytext in fstate then begin + exit; + end; + if checkaction(ea_selectall) then begin + resetoffset; + fcurindex:= 0; + fselstart:= 0; + fsellength:= length(finfo.text.text); + updateselect; + if oe_homeonenter in optionsedit then begin + curindex:= 0; + end + else begin + curindex:= fsellength; + end; + end; +end; + +procedure tinplaceedit.clearselection; +begin + fstate:= fstate + [ies_touched,ies_edited]; + if fsellength > 0 then begin + fsellength:= 0; + updateselect; + end; +end; + +procedure tinplaceedit.doactivate; +begin + updatetextflags(true); + internalupdatecaret; +end; + +procedure tinplaceedit.dodeactivate; +begin + updatetextflags(false); + application.caret.hide; +end; + +procedure tinplaceedit.initfocus; +var + opt1: optionseditty; +begin + ffiltertext:= ''; + resetoffset; + invalidatetextrect(-bigint,bigint); + opt1:= iedit(fintf).getoptionsedit; + if opt1 * [oe_locate,oe_readonly] = [oe_locate,oe_readonly] then begin + curindex:= 0; + fselstart:= 0; + fsellength:= 0; + updateselect; + end + else begin + if ies_emptytext in fstate then begin + moveindex(0,false,false); + end + else begin + if (oe_autoselect in opt1) then begin + selectall; + end + else begin + if oe_endonenter in opt1 then begin + moveindex(bigint,false,false); + end + else begin + if oe_homeonenter in opt1 then begin + moveindex(0,false,false); + end + end; + end; + end; + end; + clearundo(); + exclude(fstate,ies_touched); + updatecaret(); +end; + +procedure tinplaceedit.dofocus; +begin + include(fstate,ies_focused); + initfocus; +end; + +procedure tinplaceedit.dodefocus; +begin + exclude(fstate,ies_focused); + updatetextflags(false); + if oe_resetselectonexit in iedit(fintf).getoptionsedit then begin + sellength:= 0; + resetoffset; + end; + internalupdatecaret(true,true); +end; + +procedure tinplaceedit.settextflags(const Value: textflagsty); +begin + if ftextflags <> value then begin + ftextflags := Value+[tf_clipo]; + updatetextflags(fwidget.focused); + end; +end; + +procedure tinplaceedit.settextflagsactive(const Value: textflagsty); +begin + if ftextflagsactive <> value then begin + ftextflagsactive:= Value+[tf_clipo]; + updatetextflags(fwidget.active); + end; +end; + +procedure tinplaceedit.dopaint(const canvas: tcanvas); +var + str1: msestring; + co1,co2: rgbtriplety; + haspasswordchar: boolean; +begin + str1:= ''; + ftextrectbefore:= finfo.res; + if length(finfo.text.text) > 0 then begin + canvas.save(); + haspasswordchar:= (fpasswordchar <> #0) and not (ies_emptytext in fstate); + if haspasswordchar then begin + str1:= finfo.text.text; + finfo.text.text:= stringfromchar(fpasswordchar,length(str1)); + end; + if ffont <> nil then begin + canvas.font:= ffont; + end; + if ffontstyle <> [] then begin + canvas.font.style:= ffontstyle; + end; + if ffontcolor <> cl_none then begin + canvas.font.color:= ffontcolor; + end; + if ffontcolorbackground <> cl_none then begin + canvas.font.colorbackground:= ffontcolorbackground; + end; + with defaulteditfontcolors do begin + if canvas.font.color = cl_default then begin + canvas.font.color:= text; + end; + if canvas.font.colorbackground = cl_default then begin + canvas.font.colorbackground:= textbackground; + end; + co1:= colortorgb(cl_selectedtext); + co2:= colortorgb(cl_selectedtextbackground); + setcolormapvalue(cl_selectedtext,selectedtext); + setcolormapvalue(cl_selectedtextbackground,selectedtextbackground); + end; + msedrawtext.drawtext(canvas,finfo); + setcolormapvalue(cl_selectedtext,co1.red,co1.green,co1.blue); + setcolormapvalue(cl_selectedtextbackground,co2.red,co2.green,co2.blue); + if haspasswordchar then begin + finfo.text.text:= str1; + end; + canvas.restore(); + end; + checktextrect; +end; + +procedure tinplaceedit.checktextrect; +var + info: editnotificationinfoty; +begin + include(fstate,ies_textrectvalid); + if (ftextrectbefore.cx <> finfo.res.cx) or + (ftextrectbefore.cy <> finfo.res.cy) then begin + info:= initactioninfo(ea_textsizechanged); + info.sizebefore:= ftextrectbefore.size; + info.newsize:= finfo.res.size; + checkaction(info); + end; +end; + +function tinplaceedit.gettextrect: rectty; +begin + if not (ies_textrectvalid in fstate) then begin + ftextrectbefore:= finfo.res; + msedrawtext.textrect(getfontcanvas,finfo); + checktextrect; + end; + result:= finfo.res; +end; + +function tinplaceedit.getfontcanvas: tcanvas; +begin + result:= fwidget.getcanvas; + if ffont <> nil then begin + result.font:= ffont; + end; + if ffontstyle <> [] then begin + result.font.style:= ffontstyle; + end; +end; + +procedure tinplaceedit.setpasswordchar(const Value: msechar); +begin + if fpasswordchar <> value then begin + fpasswordchar:= Value; + invalidatetext(false,false); + end; +end; + +procedure tinplaceedit.setcaretwidth(const Value: integer); +begin + if fcaretwidth <> value then begin + fcaretwidth:= Value; + internalupdatecaret; + end; +end; + +procedure tinplaceedit.checkindexvalues(); +begin + fcurindex:= updateindex(fcurindex); + fselstart:= updateindex(fselstart); + fsellength:= updateindex(fselstart+fsellength)-fselstart; +end; + +procedure tinplaceedit.settext(const Value: msestring); +begin + finfo.text.text:= Value; + checkindexvalues(); + invalidatetext(false,false); + if ies_focused in fstate then begin + internalupdatecaret; + end; +end; + +procedure tinplaceedit.setrichtext(const avalue: richstringty); +begin + beforechange; + finfo.text := avalue; + setlength(finfo.text.format,length(finfo.text.format)); + invalidatetext(false,false); + checkindexvalues(); + if ies_focused in fstate then begin + internalupdatecaret; + end; +end; + +procedure tinplaceedit.setformat(const avalue: formatinfoarty); +begin + finfo.text.format:= copy(avalue); + updateselect(); + invalidatetext(false,false); + if ies_focused in fstate then begin + internalupdatecaret; + end; +end; + +procedure tinplaceedit.checkmaxlength; +begin + if (fmaxlength >= 0) and (length(finfo.text.text) > fmaxlength) then begin + setlength(finfo.text.text,fmaxlength); + if fcurindex > fmaxlength then begin + curindex:= fmaxlength; + end; + invalidatetext(false,false); + end; +end; + +procedure tinplaceedit.setmaxlength(const Value: integer); +begin + if fmaxlength <> value then begin + fmaxlength := Value; + checkmaxlength; + end; +end; + +procedure tinplaceedit.scroll(const dist: pointty; + const scrollcaret: boolean = true); +begin + with finfo do begin + addpoint1(dest.pos,dist); + addpoint1(clip.pos,dist); + end; + addpoint1(ftextrect.pos,dist); + if scrollcaret then begin + fwidget.scrollcaret(dist); + end; +end; + +procedure tinplaceedit.updatecaret; +//var +// int1: integer; +begin +// int1:= fupdating; +// fupdating:= 0; + internalupdatecaret; +// fupdating:= int1; +end; + +function tinplaceedit.getcaretpos: pointty; +begin + if not (ies_caretposvalid in fstate) then begin + fcaretpos:= textindextomousepos(fcurindex); + include(fstate,ies_caretposvalid); + fscrollsum:= nullpoint; + end; + result:= addpoint(fcaretpos,fscrollsum); +end; + +procedure tinplaceedit.poschanged; +begin + if fstate * [ies_focused,ies_poschanging] = [ies_focused] then begin + include(fstate,ies_poschanging); + try + internalupdatecaret; + finally + exclude(fstate,ies_poschanging); + end; + end; +end; + +function tinplaceedit.selectedtext: msestring; +begin + if fsellength > 0 then begin + result:= copy(finfo.text.text,fselstart+1,fsellength); + end + else begin + result:= ''; + end; +end; + +procedure tinplaceedit.enterchars(const chars: msestring); +begin + begingroup; + try + deleteselection; + if twidget1(fwidget).canassistive() then begin + assistiveserver.doeditcharenter(getiassistiveclient(),chars); + end; + inserttext(chars,false); + finally + endgroup; + end; + { + if twidget1(fwidget).canassistive() then begin + assistiveserver.doeditcharenter(getiassistiveclient(),chars); + end; + } +end; + +procedure tinplaceedit.begingroup; +begin + //dummy +end; + +procedure tinplaceedit.endgroup; +begin + //dummy +end; + +procedure tinplaceedit.beginupdate; +begin + application.caret.remove; + inc(fupdating); +end; + +procedure tinplaceedit.endupdate; +begin + dec(fupdating); + if fupdating = 0 then begin + internalupdatecaret; + invalidatetextrect(minint,bigint); + end; + application.caret.restore; +end; + +procedure tinplaceedit.setscrollvalue(const avalue: real; const horz: boolean); +var + rect1: rectty; + int1: integer; +begin + rect1:= textrect; + subsize1(rect1.size,ftextrect.size); + if horz then begin + if rect1.cx > 0 then begin + int1:= -(finfo.dest.x + round(rect1.cx*avalue) - ftextrect.x); + if int1 <> 0 then begin + fwidget.scrollrect(makepoint(int1,0),finfo.clip,true); + inc(finfo.dest.x,int1); + inc(fscrollsum.x,int1); + end; + end; + end + else begin + if rect1.cy > 0 then begin + int1:= -(finfo.dest.y + round(rect1.cy*avalue) - ftextrect.y); + if int1 <> 0 then begin + fwidget.scrollrect(makepoint(0,int1),finfo.clip,true); + inc(finfo.dest.y,int1); + inc(fscrollsum.y,int1); + end; + end; + end; +end; + +procedure tinplaceedit.dragstarted; +begin + killrepeater; +end; + +procedure tinplaceedit.setfiltertext(const avalue: msestring); +var + int1,int2,int3: integer; + foundindex: integer; + mstr1: msestring; + casesensitive: boolean; +begin + if avalue <> '' then begin + int1:= fintf.locatecount; + if int1 > 0 then begin + casesensitive:= oe_casesensitive in fintf.getoptionsedit; + if casesensitive then begin + mstr1:= avalue; + end + else begin + mstr1:= mseuppercase(avalue); + end; + foundindex:= -1; + int2:= fintf.locatecurrentindex; + if int2 < 0 then begin + int2:= 0; + end; + if casesensitive then begin + for int3:= int2 to int1 - 1 do begin + if msecomparestrlen(mstr1,fintf.getkeystring(int3)) = 0 then begin + foundindex:= int3; + break; + end; + end; + end + else begin + for int3:= int2 to int1 - 1 do begin + if msecomparetextlenupper(mstr1,fintf.getkeystring(int3)) = 0 then begin + foundindex:= int3; + break; + end; + end; + end; + if foundindex < 0 then begin + if casesensitive then begin + for int3:= int2-1 downto 0 do begin + if msecomparestrlen(mstr1,fintf.getkeystring(int3)) = 0 then begin + foundindex:= int3; + break; + end; + end; + end + else begin + for int3:= int2-1 downto 0 do begin + if msecomparetextlenupper(mstr1,fintf.getkeystring(int3)) = 0 then begin + foundindex:= int3; + break; + end; + end; + end; + end; + if foundindex >= 0 then begin + fintf.locatesetcurrentindex(foundindex); + ffiltertext:= avalue; + fselstart:= 0; + fsellength:= length(ffiltertext); + curindex:= fselstart+fsellength; + updateselect; + end; + end; + end + else begin + ffiltertext:= ''; + fselstart:= 0; + fsellength:= 0; + curindex:= 0; + updateselect; + end; +end; + +function tinplaceedit.updating: boolean; +begin + result:= fupdating > 0; +end; + +procedure tinplaceedit.redo; +begin + //dummy +end; + +function tinplaceedit.canredo: boolean; +begin + result:= false; +end; + +function tinplaceedit.hasselection: boolean; +begin + result:= (fsellength > 0) or fintf.hasselection(); +end; + +{ ttextundolist } + +constructor ttextundolist.create(intf: iundo); +begin + fintf:= intf; + fmaxsize:= defaultundobuffermaxsize; + inherited create; + fsize:= sizeof(undoinfoty); + maxcount:= defaultundomaxcount; +end; + +procedure ttextundolist.beforecopy(var data); +begin + inherited; + with undoinfoty(data) do begin + stringaddref(text); + stringaddref(textbefore); +// reallocstring(text); +// reallocstring(textbefore); + end; +end; + +procedure ttextundolist.freedata(var data); +begin + inherited; + with undoinfoty(data) do begin + dec(fbuffersize,length(text)); + text:= ''; + textbefore:= ''; + end; +end; + +function ttextundolist.getitems(const index: integer): pundoinfoty; +begin + result:= pundoinfoty(getitempo(index)); +end; + +function ttextundolist.checkrecord(atype: undotypety; const astartpos,aendpos: gridcoordty; + selected: boolean; backwards: boolean; alink: boolean; + textlength: integer): pundoinfoty; + + procedure newrecord; + begin + count:= fundopo; + count:= fcount + 1; + inc(fbuffersize,textlength); + while (count > 4) and (fbuffersize > fmaxsize) do begin + deleteitems(0,1); + end; + result:= items[fcount-1]; + with result^ do begin + utype:= atype; + fintf.getselectstart(selectstartpos); + startpos:= astartpos; + endpos:= aendpos; + updatebit({$ifdef FPC}longword{$else}byte{$endif}(flags),ord(uf_selected),selected); + updatebit({$ifdef FPC}longword{$else}byte{$endif}(flags),ord(uf_backwards),backwards); + end; + fundopo:= count; + end; + +var + undocount: integer; + forcednew: boolean; +begin + result:= nil; + alink:= alink or (flinked > 0); + forcednew:= (dls_forcenew in fstate); + if (fcount = 0) then begin + newrecord; + undocount:= fundopo-1; + end + else begin + undocount:= fundopo-1; + if undocount < 0 then begin + undocount:= 0; + end + else begin + if undocount >= fcount then begin + undocount:= fcount - 1; + end; + end; + result:= items[undocount]; + end; + with result^ do begin + if atype = ut_setpos then begin + if utype = ut_setpos then begin + if forcednew or + ((selected xor (uf_selected in flags)) or (fundopo = 1)) then begin + newrecord; + end + else begin + endpos:= aendpos; + end; + end + else begin + if forcednew or + ((aendpos.row <> endpos.row) or (aendpos.col <> endpos.col)) then begin + newrecord; + end; + end; + end + else begin + if forcednew or + (utype <> atype) or + selected and not(uf_selected in flags) or + backwards and not(uf_backwards in flags) then begin + newrecord; + end + else begin + endpos:= aendpos; + count:= undocount+1; //cut history + end; + end; + end; + result^.link:= alink; + exclude(fstate,dls_forcenew); +end; + +procedure ttextundolist.setpos(const endpos: gridcoordty; selected: boolean; + alink: boolean = false); +begin + if flock <> 0 then exit; + checkrecord(ut_setpos,gridcoordty(nullpoint),endpos,selected,false,alink,0); +end; + +procedure ttextundolist.inserttext(const startpos,endpos: gridcoordty; + const atext: msestring; selected: boolean; backwards: boolean; + alink: boolean = false); +begin + if flock <> 0 then exit; + with checkrecord(ut_inserttext,startpos,endpos,selected,backwards,alink,length(atext))^ do begin + text:= text + atext; + end; +end; + +procedure ttextundolist.overwritetext(const startpos,endpos: gridcoordty; + const atext, atextbefore: msestring; selected: boolean; + alink: boolean = false); +begin + if flock <> 0 then exit; + with checkrecord(ut_overwritetext,startpos,endpos,selected,false, + alink,length(atext))^ do begin + text:= text + atext; + textbefore:= textbefore + atextbefore; + end; +end; + +procedure ttextundolist.deletetext(const startpos,endpos: gridcoordty; + const atext: msestring; selected: boolean; backwards: boolean; + alink: boolean = false); +begin + if flock <> 0 then exit; + with checkrecord(ut_deletetext,startpos,endpos,selected,backwards, + alink,length(atext))^ do begin + if backwards then begin + text:= atext + text; + end + else begin + text:= text + atext; + end; + end; +end; + +procedure ttextundolist.undo; +var + linked: boolean; +begin + if fundopo < 1 then begin + exit; + end; + inc(flock); + linked:= true; //compiler warning + try + repeat + if fundopo < 1 then begin + break; + end; + dec(fundopo); + with items[fundopo]^ do begin + case utype of + ut_setpos: begin + if fundopo > 0 then begin + with items[fundopo-1]^ do begin + if uf_selected in flags then begin + fintf.setselectstart(selectstartpos); + end; + fintf.setedpos(endpos,uf_selected in flags,false,cep_nearest); + end; + end; + end; + ut_inserttext: begin + fintf.deletetext(startpos,endpos); + end; + ut_overwritetext: begin + fintf.deletetext(startpos,endpos); + fintf.inserttext(startpos,textbefore,uf_selected in flags,false); + end; + ut_deletetext: begin + fintf.inserttext(endpos,text,uf_selected in flags, + not(uf_backwards in flags)); + end; + end; + if utype <> ut_setpos then begin + fintf.setedpos(startpos,uf_selected in flags,false,cep_nearest); + end; + linked:= (fundopo > 0) and items[fundopo-1]^.link; + end; + until not linked; + finally + dec(flock); + end; +end; + +procedure ttextundolist.redo; +var + linked: boolean; +begin + if fundopo >= fcount then begin + exit; + end + else begin + inc(flock); + try + repeat + with items[fundopo]^ do begin + case utype of + ut_setpos: begin + fintf.setedpos(endpos,uf_selected in flags,false,cep_nearest); + end; + ut_inserttext: begin + fintf.inserttext(startpos,text,uf_selected in flags,false); + end; + ut_overwritetext: begin + fintf.deletetext(startpos,endpos); + fintf.inserttext(startpos,text,uf_selected in flags,false); + end; + ut_deletetext: begin + fintf.deletetext(endpos,gridcoordty(textendpoint(pointty(endpos),text))); + end; + end; + if utype <> ut_setpos then begin + fintf.setedpos(endpos,uf_selected in flags,false,cep_nearest); + end; + inc(fundopo); + linked:= (fundopo < fcount) and items[fundopo-1]^.link; + end; + until not linked; + finally + dec(flock); + end; + end; +end; + +function ttextundolist.getcanundo: boolean; +begin + result:= (fundopo > 2); +end; + +function ttextundolist.getcanredo: boolean; +begin + result:= fundopo < fcount; +end; + +procedure ttextundolist.beginlink(linkto: undotypety; forcenew: boolean); +var + po1: pundoinfoty; +begin + if flock = 0 then begin + if (flinked = 0) then begin + if forcenew then begin + include(fstate,dls_forcenew); + end; + if (fundopo > 0) then begin + po1:= items[fundopo-1]; + if (po1^.utype = linkto) then begin + po1^.link:= true; + end; + end; + end; + inc(flinked); + end; +end; + +procedure ttextundolist.endlink(forcenew: boolean); +begin + if flock = 0 then begin + dec(flinked); + if flinked = 0 then begin + if forcenew then begin + include(fstate,dls_forcenew); + end; + if fundopo > 0 then begin + items[fundopo-1]^.link:= false; + end; + end; + end; +end; + +function ttextundolist.getlocked: boolean; +begin + result:= flock <> 0; +end; + +procedure ttextundolist.clear; +begin + fundopo:= 0; + inherited; +end; + +{ tundoinplaceedit } + +constructor tundoinplaceedit.create(aowner: twidget; editintf: iedit; + undointf: iundo; istextedit: boolean); +begin + inherited create(aowner,editintf,istextedit); + include(fstate,ies_cangroupundo); + fundolist:= ttextundolist.create(undointf); +end; + +destructor tundoinplaceedit.destroy; +begin + fundolist.Free; + inherited; +end; + +procedure tundoinplaceedit.enterchars(const chars: msestring); +begin + if insertstate then begin + fundolist.beginlink(ut_inserttext,false); + try + deleteselection; + fundolist.inserttext(makegridcoord(fcurindex,frow), + makegridcoord(fcurindex+length(chars),frow),chars,false,false); + inherited; + finally + fundolist.endlink(false); + end; + end + else begin + fundolist.beginlink(ut_overwritetext,false); + try + deleteselection; + fundolist.overwritetext(makegridcoord(fcurindex,frow),makegridcoord(fcurindex+length(chars),frow), + chars,copy(finfo.text.text,fcurindex+1,length(chars)),false); + inherited; + finally + fundolist.endlink(false); + end; + end; +end; + +procedure tundoinplaceedit.internaldelete(start, len, startindex: integer; selected: boolean); +begin + fundolist.deletetext(makegridcoord(startindex,frow),makegridcoord(start,frow), + copy(finfo.text.text,start+1,len),selected,false); + inherited; +end; + +procedure tundoinplaceedit.deleteback; +begin + fundolist.deletetext(makegridcoord(fcurindex,frow),makegridcoord(fcurindex-1,frow), + finfo.text.text[fcurindex],false,true); + inherited; +end; + +procedure tundoinplaceedit.deletechar; +begin + fundolist.deletetext(makegridcoord(fcurindex,frow),makegridcoord(fcurindex,frow), + finfo.text.text[fcurindex+1],false,false); + inherited; +end; + +procedure tundoinplaceedit.moveindex(newindex: integer; shift: boolean = false; + donotify: boolean = true); +begin + inherited; + fundolist.setpos(makegridcoord(fcurindex,frow),shift); +end; + +function tundoinplaceedit.cuttoclipboard( + const buffer: clipboardbufferty): boolean; +begin + fundolist.beginlink(ut_none,true); + try + result:= inherited cuttoclipboard(buffer); + finally + fundolist.endlink(true); + end; +end; + +function tundoinplaceedit.pastefromclipboard( + const buffer: clipboardbufferty): boolean; +begin + fundolist.beginlink(ut_none,true); + try + result:= inherited pastefromclipboard(buffer); + finally + fundolist.endlink(true); + end; +end; + +procedure tundoinplaceedit.begingroup; +begin + inherited; + fundolist.beginlink(ut_none,true); +end; + +procedure tundoinplaceedit.endgroup; +begin + fundolist.endlink(true); + inherited; +end; + +procedure tundoinplaceedit.redo; +begin + fundolist.redo; +end; + +procedure tundoinplaceedit.undo; +begin + fundolist.undo; +end; + +function tundoinplaceedit.canundo: boolean; +begin + result:= fundolist.canundo; +end; + +function tundoinplaceedit.canredo: boolean; +begin + result:= fundolist.canredo; +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/msemenuwidgets.pas b/mseide-msegui/lib/common/widgets/msemenuwidgets.pas new file mode 100644 index 0000000..d5dd5a7 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msemenuwidgets.pas @@ -0,0 +1,2483 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msemenuwidgets; + +{$ifdef FPC}{$mode objfpc}{$h+}{$goto on}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + mseapplication,classes,mclasses,msewidgets,mseshapes,msemenus,msegraphutils, + msegraphics, + msetypes,msegui,mseglob,mseguiglob,mseevent,mseclasses,msestrings, + mseassistiveclient; + +const + defaultpopupmenuwidgetoptions = + defaultoptionstoplevelwidget - [ow_tabfocus,ow_arrowfocus,ow_mousefocus]; +type + menucellinfoty = record + buttoninfo: shapeinfoty; +// caption: msestring; + dimouter: rectty; + fontinactive: tfont; + fontactive: tfont; + colorglyphactive: colorty; + // coloractive: colorty; + end; + menucellinfoarty = array of menucellinfoty; + + menulayoutoptionty = (mlo_horz,mlo_keymode,mlo_main,mlo_childreninactive); + //used for popup close by second click); + menulayoutoptionsty = set of menulayoutoptionty; + menulayoutstatety = (mls_valid,mls_updating,mls_assistivelocked); + menulayoutstatesty = set of menulayoutstatety; + + menulayoutinfoty = record + menu: tmenuitem; + state: menulayoutstatesty; + activeitem: integer; + popupdirection: graphicdirectionty; + mousepos: pointty; + options: menulayoutoptionsty; + sizerect: rectty; + frameactivediff: framety; + imagedistactivediff: int32; + imagedist1activediff: int32; + imagedist2activediff: int32; + cells: menucellinfoarty; +// colorglyph: colorty; + itemframetemplate: tframetemplate; + itemface: tcustomface; + itemframetemplateactive: tframetemplate; + itemfaceactive: tcustomface; + separatorframetemplate: tframetemplate; + checkboxframetemplate: tframetemplate; + end; + + ppopupmenuwidget = ^tpopupmenuwidget; + tpopupmenuwidget = class(tpopupwidget) + private + fnextpopup,fprevpopup: tpopupmenuwidget; + fposrect: rectty; + fposition: graphicdirectionty; + factposition: graphicdirectionty; + finstancepo: pobject; + frefpos: pointty; + fselecteditem: tmenuitem; + ftemplates: menutemplatety; + fmenucomp: tcustommenu; + fclickeditem: integer; + fmouseitem: integer; + procedure internalsetactiveitem(const avalue: integer; + const aclicked: boolean; const force: boolean; + const nochildreninactive: boolean); virtual; + function getactiveitem: integer; + procedure setactiveitem(const value: integer); + procedure applicationactivechanged(const avalue: boolean); + protected + flayout: menulayoutinfoty; + flocalframeandface: boolean; + procedure doafteractivate() override; + procedure clientrectchanged; override; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + function transientforwindoworwindow: twindow; + function translatetoscreen(const value: pointty): pointty; virtual; + procedure invalidatelayout(); + procedure updatelayout; virtual; + procedure nextpopupshowing; virtual; + function isinpopuparea(const apos: pointty): boolean; virtual; + function checkprevpopuparea(const apos: pointty): boolean; virtual; + procedure activatemenu( + const keymode,aclicked,nokeymodereset: boolean); virtual; + procedure deactivatemenu; virtual; + procedure selectmenu(const keymode: boolean; + const keyreturn: boolean); virtual; + function rootpopup: tpopupmenuwidget; + procedure closepopupstack(aselecteditem: tmenuitem; + const cancelmodal: boolean = false); + procedure updatepos; virtual; + procedure beginkeymode; + procedure dopaintforeground(const canvas: tcanvas); override; + procedure mouseevent(var info: mouseeventinfoty); override; + procedure dokeydown(var info: keyeventinfoty); override; + procedure childdeactivated(const sender: tpopupmenuwidget); virtual; + procedure fontchanged; override; + procedure internalcreateframe; override; + function activateoptionset: boolean; + procedure showhint(const aid: int32; var info: hintinfoty); override; + function trycancelmodal(const newactive: twindow): boolean; override; + + procedure release1(const acancelmodal: boolean); virtual; + class function classskininfo(): skininfoty; override; + function getassistiveflags(): assistiveflagsty override; + function getassistivecaption(): msestring override; + function getassistivetext(): msestring override; + function getassistivehint(): msestring override; + function prevmenuitem(const info: menulayoutinfoty): integer; + function nextmenuitem(const info: menulayoutinfoty): integer; + procedure assistivemenuactivated(); + public + constructor create(instance: ppopupmenuwidget; + const amenu: tmenuitem; const atransientfor: twindow; + const aowner: tcomponent = nil; + const menucomp: tcustommenu = nil); overload; + destructor destroy; override; + procedure paint(const canvas: tcanvas); override; + procedure menuchanged(const sender: tmenuitem); + procedure release(const nomodaldefer: boolean=false); override; + procedure updatetemplates; + procedure assigntemplate(const source: menutemplatety); virtual; + function showmenu(const aposrect: rectty; aposition: graphicdirectionty; + aactivate: boolean): tmenuitem; + //returns selected item, nil if none + property activeitem: integer read getactiveitem write setactiveitem; + published + property optionswidget default defaultpopupmenuwidgetoptions; + end; + + mainmenuwidgetoptionty = (mwo_vertical); + mainmenuwidgetoptionsty = set of mainmenuwidgetoptionty; + mainmenuwidgetstatety = (mws_firstactivated,mws_forced,mws_raised); + mainmenuwidgetstatesty = set of mainmenuwidgetstatety; + + tcustommainmenuwidget = class(tpopupmenuwidget) + private + factivewindowbefore: twindow; +// fstackedoverbefore: twindow; + fstackedunderbefore: twindow; + fstate: mainmenuwidgetstatesty; +// flayoutcalcing: integer; + procedure internalsetactiveitem(const Value: integer; + const aclicked: boolean; const force: boolean; + const nochildreninactive: boolean); override; + procedure checkactivate(const force,noraise: boolean); + protected + foptions: mainmenuwidgetoptionsty; + procedure restorefocus; + function checkprevpopuparea(const apos: pointty): boolean; override; + procedure nextpopupshowing; override; + procedure getautopaintsize(var asize: sizety); override; + procedure updatelayout; override; + procedure updatepos; override; + function isinpopuparea(const apos: pointty): boolean; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; + procedure childdeactivated(const sender: tpopupmenuwidget); override; + procedure activatemenu( + const keymode,aclicked,nokeymodereset: boolean); override; + procedure deactivatemenu; override; + procedure selectmenu(const keymode: boolean; + const keyreturn: boolean); override; + procedure internalcreateframe; override; + procedure loaded; override; + procedure mouseevent(var info: mouseeventinfoty); override; + procedure release1(const acancelmodal: boolean); override; + public + end; + + tframemenuwidget = class(tcustommainmenuwidget) + protected + public + constructor create(const aparent: twidget; + const amenu: tmenuitem); overload; + constructor create(const aparent: twidget; + const amenu: tmainmenu); overload; + procedure loaded; override; + end; + + tmainmenuwidget = class(tcustommainmenuwidget) + private + procedure setmenu(const avalue: twidgetmainmenu); + function getmenu: twidgetmainmenu; + procedure setoptions(const avalue: mainmenuwidgetoptionsty); + protected +// function checkprevpopuparea(const apos: pointty): boolean; override; + procedure objectevent(const sender: tobject; const event: objecteventty); override; + procedure loaded; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure initnewcomponent(const ascale: real); override; + published + property menu: twidgetmainmenu read getmenu write setmenu; + property options: mainmenuwidgetoptionsty read foptions write setoptions default []; + property popupdirection: graphicdirectionty read flayout.popupdirection write + flayout.popupdirection default gd_down; + end; + + mainmenupainterstatety = (mmps_layoutvalid); + mainmenupainterstatesty = set of mainmenupainterstatety; + + setmainmenuinstanceprocty = procedure(const value: tmainmenu) of object; + +function showpopupmenu(const menu: tmenuitem; const transientfor: twidget; + const pos: rectty; const dir: graphicdirectionty; + const menucomp: tcustommenu = nil): tmenuitem; overload; +function showpopupmenu(const menu: tmenuitem; const transientfor: twidget; + const pos: graphicdirectionty; + const menucomp: tcustommenu = nil): tmenuitem; overload; +function showpopupmenu(const menu: tmenuitem; const transientfor: twidget; + const pos: pointty; + const menucomp: tcustommenu = nil): tmenuitem; overload; + { +function showpopupmenu(const menu: tmenuitem; const transientfor: twidget; + var mouseinfo: mouseeventinfoty): tmenuitem; overload; + } + +var + menuexehandlerdesign: menuitemprocty; + +implementation +uses + msedrawtext,mserichstring,msestockobjects,sysutils,msekeyboard,msebits, + mseact,mseguiintf,msebitmap,msesysutils,mseassistiveserver; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + tmenuitem1 = class(tmenuitem); + tmenuitems1 = class(tmenuitems); + twidget1 = class(twidget); +// tcustomframe1 = class(tcustomframe); + twindow1 = class(twindow); + tmsecomponent1 = class(tmsecomponent); + tframetemplate1 = class(tframetemplate); + tcustomframe1 = class(tcustomframe); + tguiapplication1 = class(tguiapplication); + +function showpopupmenu(const menu: tmenuitem; const transientfor: twidget; + const pos: rectty; const dir: graphicdirectionty; + const menucomp: tcustommenu = nil): tmenuitem; overload; +var + widget: tpopupmenuwidget; + window1: twindow; +begin + if menu.canshow then begin +// tmenuitem1(menu).ftransientfor:= transientfor; + window1:= nil; + if transientfor <> nil then begin + window1:= transientfor.window; + end; + tpopupmenuwidget.create(@widget,menu,window1,nil,menucomp); + try + if window1 <> nil then begin + widget.color:= window1.owner.actualopaquecolor; + end; + result:= widget.showmenu(pos,dir,true); + finally + widget.Free; +// tmenuitem1(menu).ftransientfor:= nil; + end; + end + else begin + result:= nil; + end; +end; + +function showpopupmenu(const menu: tmenuitem; const transientfor: twidget; + const pos: graphicdirectionty; + const menucomp: tcustommenu = nil): tmenuitem; +begin + result:= showpopupmenu(menu,transientfor, + makerect(transientfor.screenpos,transientfor.size),pos,menucomp); +end; + +function showpopupmenu(const menu: tmenuitem; const transientfor: twidget; + const pos: pointty; + const menucomp: tcustommenu = nil): tmenuitem; overload; +begin + result:= showpopupmenu(menu,transientfor, + makerect(translateclientpoint(pos,transientfor,nil),nullsize), + gd_right,menucomp); +end; + +procedure initlayoutinfo(const aowner: tmsecomponent; + var info: menulayoutinfoty; const amenu: tmenuitem; + const aoptions: menulayoutoptionsty{; const acolorglyph: colorty}); +begin + with info do begin + cells:= nil; + fillchar(info,sizeof(info),0); + tmsecomponent1(aowner).getobjectlinker.setlinkedvar(ievent(aowner),amenu,tlinkedpersistent(menu)); + activeitem:= -1; + options:= aoptions; +// colorglyph:= acolorglyph; + end; +end; + +procedure movemenulayout(var layout: menulayoutinfoty; const dist: pointty); +//todo: optimize multiple call by loaded() + +var + int1: integer; +begin + with layout do begin + addpoint1(sizerect.pos,dist); + for int1:= 0 to high(cells) do begin + with cells[int1].buttoninfo.ca.dim.pos do begin + x:= x + dist.x; + y:= y + dist.y; + end; + with cells[int1].dimouter.pos do begin + x:= x + dist.x; + y:= y + dist.y; + end; + end; + end; +end; + +procedure calcmenulayout(var layout: menulayoutinfoty; const canvas: tcanvas; + const maxsize: integer = bigint); + function gettextrect(const acell: menucellinfoty; + const atext: richstringty): sizety; + var + size1: sizety; + begin + with acell do begin + result:= textrect(canvas,atext,[],fontinactive).size; + if fontinactive <> fontactive then begin + size1:= textrect(canvas,atext,[],fontactive).size; + if size1.cx > result.cx then begin + result.cx:= size1.cx; + end; + if size1.cy > result.cy then begin + result.cy:= size1.cy; + end; + end; + end; + end; + +const + shortcutdist = 5; +var + int1,int2: integer; + ay,ax: integer; + sizemax1: integer; + atextsize: sizety; + maxheight: integer; + textwidth: integer; + tabpos1: integer; + ashortcutwidth,shortcutwidth: integer; + item1,item2: tmenuitem1; + hassubmenu: boolean; + hascheckbox: boolean; + shift,regioncount: integer; + amax: integer; + frame1: framety; + frame2: framety; + framewidth,frameheight: integer; +// framehalfwidth: integer; +// framewidth1: integer; + extrasp: integer; + imagedi: integer; + imageditop: integer; + imagedibottom: integer; + ar1: richstringarty; + commonwidth: boolean; + needsmenuarrow: boolean; + parentcolor: colorty; + parentcoloractive: colorty; + noanim1: boolean; + nomouseanim1: boolean; + noclickanim1: boolean; + nofocusanim1: boolean; + checkboxwidth: integer; + checkboxheight: integer; + size1: sizety; + hasnormalitem: boolean; + +label + suppressed; + +begin + ar1:= nil; //compiler warning + with layout,tmenuitem1(menu) do begin + sizerect.pos:= nullpoint; + commonwidth:= (owner <> nil) and (mo_commonwidth in owner.options) and + (mlo_horz in layout.options); +// framehalfwidth:= 0; + needsmenuarrow:= not (mlo_horz in layout.options) or (owner <> nil) and + (mo_mainarrow in owner.options); + checkboxwidth:= menucheckboxwidth; + checkboxheight:= menucheckboxheight; + if checkboxframetemplate <> nil then begin + with checkboxframetemplate do begin + if fso_flat in optionsskin then begin + dec(checkboxwidth,2); + dec(checkboxheight,2); + end; + size1:= innerframedim(); + size1.cx:= size1.cx + frameo_left + frameo_right; + size1.cy:= size1.cy + frameo_top + frameo_bottom; + end; + checkboxwidth:= checkboxwidth + size1.cx; + checkboxheight:= checkboxheight + size1.cy; + end; + imagedistactivediff:= 0; + imagedist1activediff:= 0; + imagedist2activediff:= 0; + if itemframetemplateactive <> nil then begin + with tframetemplate1(itemframetemplateactive) do begin + frame2:= paintframe; + imagedistactivediff:= imagedist; + imagedist1activediff:= imagedist1; + imagedist2activediff:= imagedist2; + end; + end + else begin + frame2:= nullframe; + end; + frameactivediff:= frame2; + if itemframetemplate <> nil then begin + with tframetemplate1(itemframetemplate) do begin + imagedistactivediff:= imagedistactivediff - imagedist; + imagedist1activediff:= imagedist1activediff - imagedist1; + imagedist2activediff:= imagedist2activediff - imagedist2; + frame1:= paintframe; + subframe1(frameactivediff,frame1); + if frame1.left > frame2.left then begin + frame2.left:= frame1.left; + end; + if frame1.top > frame2.top then begin + frame2.top:= frame1.top; + end; + if frame1.right > frame2.right then begin + frame2.right:= frame1.right; + end; + if frame1.bottom > frame2.bottom then begin + frame2.bottom:= frame1.bottom; + end; +// int1:= (abs(levelo) + abs(leveli) + framewidth); +// if int1 > framehalfwidth then begin +// framehalfwidth:= int1; +// end; + frame1:= fi.ba.innerframe; + extrasp:= fi.ba.extraspace; + imagedi:= fi.ba.imagedist; + imageditop:= fi.ba.imagedist1; + imagedibottom:= fi.ba.imagedist2; + noanim1:= fso_noanim in optionsskin; + nomouseanim1:= fso_nomouseanim in optionsskin; + noclickanim1:= fso_noclickanim in optionsskin; + nofocusanim1:= fso_nofocusanim in optionsskin; + end; + end + else begin + frame1:= nullframe; + extrasp:= 0; + imagedi:= 0; + imageditop:= 0; + imagedibottom:= 0; + noanim1:= false; + nomouseanim1:= false; + noclickanim1:= false; + nofocusanim1:= false; + end; + framewidth:= frame2.left + frame2.right + extrasp; + frameheight:= frame2.top + frame2.bottom + extrasp; +// framewidth1:= framehalfwidth * 2; +// framewidth1:= framewidth1 + extrasp; + setlength(cells,count); + maxheight:= 0; +// ay:= framehalfwidth; +// ax:= framehalfwidth; + ay:= frame2.top; + ax:= frame2.left; + textwidth:= 0; + shortcutwidth:= 0; + hassubmenu:= false; + hascheckbox:= false; + parentcolor:= actualcolor; + parentcoloractive:= actualcoloractive; + hasnormalitem:= false; //for separator check + for int1:= 0 to count - 1 do begin + item1:= tmenuitem1(fsubmenu[int1]); + with cells[int1] do begin +// caption:= item1.caption; + fontinactive:= item1.font; + fontactive:= item1.fontactive; + with buttoninfo,ca do begin + actionstatestoshapestates(item1.finfo,state); + captiondist:= defaultshapecaptiondist; + textflags:= [tf_ycentered]; + imagedist:= imagedi; + imagelist:= timagelist(item1.finfo.imagelist); + ar1:= splitrichstring(item1.finfo.caption1,msechar(c_tab)); + atextsize:= gettextrect(cells[int1],ar1[0]); + atextsize.cx:= atextsize.cx + frame1.left + frame1.right; + atextsize.cy:= atextsize.cy + frame1.top + frame1.bottom; + inc(atextsize.cy,2); //for 3D level + if imagelist <> nil then begin + tabpos:= -(imagelist.width+imagedi); + atextsize.cx:= atextsize.cx - tabpos; + int2:= imagelist.height + imageditop + imagedibottom; + if atextsize.cy < int2 then begin + atextsize.cy:= int2; + end; + end + else begin + tabpos:= 0; + end; + exclude(state,shs_suppressed); + if mlo_horz in layout.options then begin + include(state,shs_horz); + end + else begin + exclude(state,shs_horz); + end; + tabpos:= tabpos - frame1.right - frame1.left; + if high(ar1) > 0 then begin + ashortcutwidth:= gettextrect(cells[int1],ar1[1]).cx; + end + else begin + ashortcutwidth:= 0; + end; + if needsmenuarrow and (item1.count > 0) then begin + include(state,shs_menuarrow); + if mlo_horz in layout.options then begin + if (ashortcutwidth = 0) or commonwidth then begin + dec(tabpos,menuarrowwidthhorz); + inc(atextsize.cx,menuarrowwidthhorz); + end + else begin + inc(ashortcutwidth,menuarrowwidthhorz); + end; + end; + end + else begin + exclude(state,shs_menuarrow); + end; + if ashortcutwidth > shortcutwidth then begin + shortcutwidth:= ashortcutwidth; + end; + colorglyph:= item1.actualcolorglyph(); + //finfo.colorglyph; //layout.colorglyph; + colorglyphactive:= item1.actualcolorglyphactive(); + caption:= item1.finfo.caption1; + imagenr:= item1.finfo.imagenr; + imagenrdisabled:= item1.finfo.imagenrdisabled; +// actionstatestoshapestates(item1.finfo,state); + if (item1.color = cl_default) or (item1.color = cl_parent) then begin + color:= parentcolor; + end + else begin + color:= item1.color; + end; + if (item1.coloractive = cl_default) or (item1.coloractive = cl_parent) then begin + coloractive:= parentcoloractive; + end + else begin + if item1.coloractive = cl_normal then begin + coloractive:= color; + end + else begin + coloractive:= item1.coloractive; + end; + end; + if mao_separator in item1.options then begin + exclude(state,shs_flat); + end + else begin + include(state,shs_flat); + end; + updatebit(longword(state),ord(shs_noanimation),noanim1); + updatebit(longword(state),ord(shs_nomouseanimation),nomouseanim1); + updatebit(longword(state),ord(shs_noclickanimation),noclickanim1); + updatebit(longword(state),ord(shs_nofocusanimation),nofocusanim1); + + if not (shs_invisible in state) then begin + if shs_separator in state then begin + if shs_optional in state then begin + include(state,shs_suppressed); + if hasnormalitem then begin + for int2:= int1+1 to count - 1 do begin + item2:= tmenuitem1(fsubmenu[int2]); + if item2.options * [mao_separator,mao_optional] = + [mao_separator] then begin + break; + end; + if not (mao_separator in item2.options) and + not (as_invisible in item2.state) then begin + exclude(state,shs_suppressed); + break; + end; + end; + end; + end; + hasnormalitem:= false; + end + else begin + hasnormalitem:= true; + end; + if shs_suppressed in state then begin + goto suppressed; + end; + hassubmenu:= hassubmenu or (shs_menuarrow in state); + if [shs_checkbox,shs_radiobutton] * state <> [] then begin + hascheckbox:= true; + if checkboxheight > atextsize.cy then begin + atextsize.cy:= checkboxheight; + end; + end; + with dim do begin + if mlo_horz in layout.options then begin //horizontal + if shs_separator in state then begin + if separatorframetemplate <> nil then begin + cx:= separatorframetemplate.innerframedim.cx; + end + else begin + cx:= 2; + end; + end + else begin + if [shs_checkbox,shs_radiobutton] * state <> [] then begin + inc(atextsize.cx,checkboxwidth); + dec(tabpos,checkboxwidth); + end; + cx:= atextsize.cx + 4; + if (ashortcutwidth > 0) then begin + tabpos:= tabpos + atextsize.cx + shortcutdist; + cx:= cx + shortcutdist + ashortcutwidth; + end; + end; + x:= ax; + y:= ay; + if commonwidth then begin + atextsize.cx:= cx; + end; + inc(ax,cx+framewidth); + end + else begin //vertical + y:= ay; + if shs_separator in state then begin + if separatorframetemplate <> nil then begin + cy:= separatorframetemplate.innerframedim.cy; + end + else begin + cy:= 2; + end; + end + else begin + cy:= atextsize.cy; + end; + inc(ay,cy+frameheight); + end; + end; + if atextsize.cy > maxheight then begin + maxheight:= atextsize.cy; + end; + if atextsize.cx > textwidth then begin + textwidth:= atextsize.cx; + end; + end + else begin + dim:= nullrect; + end; +suppressed: + end; //with cells[int1].buttoninfo + end; //with cells[int1] + end; + if (shortcutwidth > 0) and not commonwidth then begin + tabpos1:= textwidth + shortcutdist; + textwidth:= tabpos1 + shortcutwidth; + end + else begin + tabpos1:= 0; + end; + if not (as_invisible in state) then begin + shift:= 0; + regioncount:= 1; + if mlo_horz in layout.options then begin //horizontal + if mao_singleregion in layout.menu.options then begin + amax:= bigint; + end + else begin + amax:= maxsize; + end; + if commonwidth then begin + ax:= frame2.left; + end; + sizemax1:= 0; + for int1:= 0 to count - 1 do begin + with cells[int1].buttoninfo,ca do begin + if state * [shs_invisible,shs_suppressed] = [] then begin + if commonwidth then begin + dim.x:= ax; + if not (shs_separator in state) then begin + dim.cx:= textwidth; + end; + ax:= ax + dim.cx + framewidth; + end; + dim.x:= dim.x + shift; + if (int1 > 0) and + (dim.x + dim.cx + frame2.right > amax) then begin + shift:= shift - dim.x + frame2.left; + dim.x:= frame2.left; + inc(regioncount); + end; + int2:= dim.x + dim.cx + shift; + if int2 > sizemax1 then begin + sizemax1:= int2; + end; + dim.y:= frame2.top + (maxheight+frameheight) * (regioncount - 1); + dim.cy:= maxheight; + end; + end; + end; + sizerect.cx:= sizemax1+frame2.right {- extrasp - frame2.right}; +// sizerect.cx:= ax - extrasp - frame2.right; + sizerect.cy:= regioncount * (maxheight + frameheight) - extrasp; + end + else begin //vertical + if mao_singleregion in layout.menu.options then begin + amax:= bigint; + end + else begin + amax:= maxsize; + end; + ax:= frame2.left; + textwidth:= textwidth + 4; + if hassubmenu then begin + textwidth:= textwidth + menuarrowwidth; + end; + if hascheckbox then begin + textwidth:= textwidth + checkboxwidth; + end; + maxheight:= 0; + for int1:= 0 to count - 1 do begin + with cells[int1].buttoninfo,ca,dim do begin + tabpos:= tabpos + tabpos1; + y:= y + shift; + int2:= y + cy + frameheight; + if (int1 > 0) and (int2 - extrasp > amax) then begin + shift:= shift - y + frame2.top; + y:= frame2.top; + ax:= ax + textwidth + framewidth; + inc(regioncount); + end + else begin + if int2 > maxheight then begin + maxheight:= int2; + end; + end; + x:= ax; + cx:= textwidth; + end; + end; + sizerect.cx:= regioncount * (textwidth + framewidth) - extrasp; + sizerect.cy:= maxheight - frame2.bottom - extrasp; + end; + end + else begin + sizerect.size:= nullsize; + end; + for int1:= 0 to count - 1 do begin + with cells[int1],buttoninfo,ca do begin + dimouter:= inflaterect(dim,frame2); + imagedist1:= imageditop; + imagedist2:= imagedibottom; + end; + end; + end; +end; + +function getcellatpos(const info: menulayoutinfoty; const pos: pointty): integer; +var + int1: integer; +begin + with info do begin + if pointinrect(pos,sizerect) then begin + result:= -2; + for int1:= 0 to high(cells) do begin + with cells[int1].buttoninfo do begin + if (state * + [shs_disabled,shs_invisible,shs_suppressed,shs_separator] = []) and + pointinrect(pos,ca.dim) then begin + result:= int1; + break; + end; + end; + end; + end + else begin + result:= -1; + end; + end; +end; + +procedure drawmenu(const canvas: tcanvas; const layout: menulayoutinfoty); +var + int1: integer; + po1,po2: pframety; + colorglyphbefore: colorty; +begin + with layout do begin + if itemframetemplate <> nil then begin + po1:= @tframetemplate1(itemframetemplate).fi.ba.innerframe; + end + else begin + po1:= nil; + end; + if itemframetemplateactive <> nil then begin + po2:= @tframetemplate1(itemframetemplateactive).fi.ba.innerframe; + end + else begin + po2:= nil; + end; + for int1:= 0 to high(cells) do begin + with cells[int1],buttoninfo do begin + if state * [shs_invisible,shs_suppressed] = [] then begin + colorglyphbefore:= ca.colorglyph; + checkboxframe:= checkboxframetemplate; + if int1 = activeitem then begin + ca.colorglyph:= colorglyphactive; + if itemframetemplateactive <> nil then begin + itemframetemplateactive.paintbackground(canvas,ca.dim, + combineframestateflags(shs_disabled in state,false,false, + shs_clicked in state,false)); + if ca.colorglyph = cl_default then begin + ca.colorglyph:= itemframetemplateactive.colorglyph; + end; + end; + if ca.colorglyph = cl_default then begin + ca.colorglyph:= cl_glyphactive; + end; + face:= itemfaceactive; + ca.font:= fontactive; + state:= state + [shs_focused,shs_active,shs_focusanimation]; + deflaterect1(ca.dim,frameactivediff); + ca.imagedist:= ca.imagedist + imagedistactivediff; + ca.imagedist1:= ca.imagedist1 + imagedist1activediff; + ca.imagedist2:= ca.imagedist2 + imagedist2activediff; + drawmenubutton(canvas,buttoninfo,po2); + if itemframetemplateactive <> nil then begin + itemframetemplateactive.paintoverlay(canvas,ca.dim, + combineframestateflags(false,true,true,shs_clicked in state,false)); + end; + inflaterect1(ca.dim,frameactivediff); + ca.imagedist:= ca.imagedist - imagedistactivediff; + ca.imagedist1:= ca.imagedist1 - imagedist1activediff; + ca.imagedist2:= ca.imagedist2 - imagedist2activediff; + end + else begin + if (shs_separator in state) and (separatorframetemplate <> nil) then begin + separatorframetemplate.paintbackgroundframe(canvas,ca.dim); + if not (fso_flat in separatorframetemplate.optionsskin) then begin + draw3dframe(canvas, + inflaterect(deflaterect(ca.dim,separatorframetemplate.innerframe),1), + -1,defaultframecolors.edges,[]); + end; + separatorframetemplate.paintoverlayframe(canvas,ca.dim); + end + else begin + if itemframetemplate <> nil then begin + itemframetemplate.paintbackground(canvas,ca.dim, + combineframestateflags(shs_disabled in state,false,false, + shs_clicked in state,false)); + if ca.colorglyph = cl_default then begin + ca.colorglyph:= itemframetemplate.colorglyph; + end; + end; + face:= itemface; + ca.font:= fontinactive; + state:= state - [shs_focused,shs_active,shs_focusanimation]; + if ca.colorglyph = cl_default then begin + ca.colorglyph:= cl_glyph; + end; + drawmenubutton(canvas,buttoninfo,po1); + if itemframetemplate <> nil then begin + itemframetemplate.paintoverlay(canvas,ca.dim, + combineframestateflags(shs_disabled in state,false,false, + shs_clicked in state,false)); + end; + end; + end; + ca.colorglyph:= colorglyphbefore; + end; //visible + end; + end; + end; +end; + +function tpopupmenuwidget.prevmenuitem(const info: menulayoutinfoty): integer; +var + dir1: graphicdirectionty; +begin + with info do begin + result:= activeitem; + repeat + dec(result); + if result < 0 then begin + if aso_menunavig in assistiveoptions then begin + result:= activeitem; + if canassistive and active or (mlo_main in info.options) then begin + dir1:= gd_up; + if mlo_horz in info.options then begin + dir1:= gd_left; + end; + assistiveserver.donavigbordertouched(getiassistiveclient,dir1); + end; + break; + end; + result:= menu.count - 1; + end; + until menu[result].canactivate or (result = activeitem); + end; +end; + +function tpopupmenuwidget.nextmenuitem(const info: menulayoutinfoty): integer; +var + dir1: graphicdirectionty; +begin + with info do begin + if menu.count = 0 then begin + result:= -1; + end + else begin + result:= activeitem; + repeat + inc(result); + if result >= menu.count then begin + if aso_menunavig in assistiveoptions then begin + result:= activeitem; + if canassistive and active or (mlo_main in info.options) then begin + dir1:= gd_down; + if mlo_horz in info.options then begin + dir1:= gd_right; + end; + assistiveserver.donavigbordertouched(getiassistiveclient,dir1); + end; + break; + end; + if activeitem = -1 then begin + result:= -1; + break; + end + else begin + result:= 0; + end; + end; + until menu[result].canactivate or (result = activeitem); + end; + end; +end; + +function checkshortcut(const layout: menulayoutinfoty; + var info: keyeventinfoty; out multiple: boolean; + currentindex: integer = -1): integer; + + function getshortcut(currentindex: integer): integer; + var + int1: integer; + begin + result:= -1; + inc(currentindex); + if currentindex >= length(layout.cells) then begin + currentindex:= 0; + end; + int1:= currentindex; + repeat + with layout.cells[currentindex] do begin + if (buttoninfo.state * [shs_disabled,shs_invisible,shs_suppressed] = []) and + msegui.checkshortcut(info, + tmenuitem(tmenuitems1(tmenuitem1(layout.menu).fsubmenu). + fitems[currentindex]).caption,false) then begin + result:= currentindex; + include(info.eventstate,es_processed); + break; + end; + end; + inc(currentindex); + if currentindex >= length(layout.cells) then begin + currentindex:= 0; + end; + until currentindex = int1; + end; + +begin + result:= -1; + multiple:= false; + if length(layout.cells) > 0 then begin + result:= getshortcut(currentindex); + if result >= 0 then begin + exclude(info.eventstate,es_processed); + multiple:= getshortcut(result) <> result; + end; + end; +end; + +{ tpopupmenuwidget } + +constructor tpopupmenuwidget.create(instance: ppopupmenuwidget; const amenu: tmenuitem; + const atransientfor: twindow; + const aowner: tcomponent = nil; const menucomp: tcustommenu = nil); +begin + fclickeditem:= -1; + fmouseitem:= -1; + finstancepo:= pobject(instance); + fmenucomp:= menucomp; + if finstancepo <> nil then begin + instance^:= self; + end; + initlayoutinfo(self,flayout,amenu,[]{,cl_black}); + inherited create(aowner,atransientfor); + optionswidget:= defaultpopupmenuwidgetoptions; + internalcreateframe; + if menucomp <> nil then begin + assigntemplate(menucomp.template); + end + else begin + if (atransientfor <> nil) and (atransientfor.owner is tpopupmenuwidget) then begin + assigntemplate(tpopupmenuwidget(atransientfor.owner).ftemplates); + end; + end; + application.registeronapplicationactivechanged( + {$ifdef FPC}@{$endif}applicationactivechanged); +end; + +destructor tpopupmenuwidget.destroy; +begin + application.unregisteronapplicationactivechanged( + {$ifdef FPC}@{$endif}applicationactivechanged); + if finstancepo <> nil then begin + finstancepo^:= nil; + end; + if flayout.menu <> nil then begin + flayout.menu.onchange:= nil; + end; + freeandnil(fnextpopup); + inherited; + flayout.itemface.free; + flayout.itemfaceactive.free; +end; + +procedure tpopupmenuwidget.release(const nomodaldefer: boolean=false); +begin + if finstancepo <> nil then begin + finstancepo^:= nil; + end; + finstancepo:= nil; + fprevpopup:= nil; + inherited; +end; + +procedure tpopupmenuwidget.internalcreateframe; +begin + inherited; + tcustomframe1(fframe).fi.levelo:= 1; //do not set localprops +end; + +procedure tpopupmenuwidget.updatetemplates; +begin + with ftemplates do begin + if not flocalframeandface then begin + if frame <> nil then begin + if fframe = nil then begin + internalcreateframe; + end; + fframe.assign(frame); + end + else begin + freeandnil(fframe); //restore original values + internalcreateframe; + end; + if face <> nil then begin + if fface = nil then begin + internalcreateface; + end; + fface.assign(face); + end + else begin + freeandnil(fface); + end; + end; + if itemframe <> nil then begin + flayout.itemframetemplate:= itemframe.template; + end + else begin + flayout.itemframetemplate:= nil; + end; + if itemface <> nil then begin + if flayout.itemface = nil then begin + flayout.itemface:= tcustomface.create(iface(self)); + end; + flayout.itemface.assign(itemface.template); + end + else begin + freeandnil(flayout.itemface); + end; + if itemframeactive <> nil then begin + flayout.itemframetemplateactive:= itemframeactive.template; + end + else begin + flayout.itemframetemplateactive:= nil; + end; + if itemfaceactive <> nil then begin + if flayout.itemfaceactive = nil then begin + flayout.itemfaceactive:= tcustomface.create(iface(self)); + end; + flayout.itemfaceactive.assign(itemfaceactive.template); + end + else begin + freeandnil(flayout.itemfaceactive); + end; + if separatorframe <> nil then begin + flayout.separatorframetemplate:= separatorframe.template; + end + else begin + flayout.separatorframetemplate:= nil; + end; + if checkboxframe <> nil then begin + flayout.checkboxframetemplate:= checkboxframe.template; + end + else begin + flayout.checkboxframetemplate:= nil; + end; + invalidatelayout(); + end; +end; + +procedure tpopupmenuwidget.assigntemplate(const source: menutemplatety); +begin + setlinkedvar(source.frame,tmsecomponent(ftemplates.frame)); + setlinkedvar(source.face,tmsecomponent(ftemplates.face)); + setlinkedvar(source.itemframe,tmsecomponent(ftemplates.itemframe)); + setlinkedvar(source.itemface,tmsecomponent(ftemplates.itemface)); + setlinkedvar(source.itemframeactive,tmsecomponent(ftemplates.itemframeactive)); + setlinkedvar(source.itemfaceactive,tmsecomponent(ftemplates.itemfaceactive)); + setlinkedvar(source.separatorframe,tmsecomponent(ftemplates.separatorframe)); + setlinkedvar(source.checkboxframe,tmsecomponent(ftemplates.checkboxframe)); + updatetemplates; +end; + +function tpopupmenuwidget.translatetoscreen(const value: pointty): pointty; +begin + result:= translateclientpoint(value,self,nil); +end; + +function tpopupmenuwidget.transientforwindoworwindow: twindow; +begin + result:= window.transientfor; + if result = nil then begin + result:= self.window; + end; +end; + +procedure tpopupmenuwidget.updatepos; +var + rect1: rectty; + workarea: rectty; + int1: integer; +begin + rect1.size:= addsize(flayout.sizerect.size,innerclientframewidth); + workarea:= application.workarea(transientforwindoworwindow); + factposition:= fposition; + int1:= 0; + with fposrect do begin + repeat + case factposition of + gd_none: begin + inc(int1); + rect1.x:= x + (cx - rect1.cx) div 2; + rect1.y:= y + (cy - rect1.cy) div 2; + end; + gd_right: begin + rect1.pos:= makepoint(x + cx, y); + with rect1 do begin + if (int1 = 0) and (x + cx > workarea.x + workarea.cx) then begin + factposition:= gd_left; + end + else begin + inc(int1); + end; + end; + end; + gd_up: begin + rect1.pos:= makepoint(x, y-rect1.cy); + with rect1 do begin + if (int1 = 0) and (y < workarea.y) then begin + factposition:= gd_down; + end + else begin + inc(int1); + end; + end; + end; + gd_left: begin + rect1.pos:= makepoint(x-rect1.cx,y); + with rect1 do begin + if (int1 = 0) and (x < workarea.x) then begin + factposition:= gd_right; + end + else begin + inc(int1); + end; + end; + end; + gd_down: begin + rect1.pos:= makepoint(x,y+cy); + with rect1 do begin + if (int1 = 0) and (y + cy > workarea.y + workarea.cy) then begin + factposition:= gd_up; + end + else begin + inc(int1); + end; + end; + end; + end; + inc(int1); + until int1 >= 2; + end; + shiftinrect(rect1,workarea); + setwidgetrect(rect1); +end; + +procedure tpopupmenuwidget.updatelayout(); +begin + if flayout.state * [mls_valid,mls_updating] = [] then begin + include(flayout.state,mls_updating); + try + flayout.popupdirection:= gd_right; + calcmenulayout(flayout,getcanvas, + // application.screenrect(transientforwindoworwindow).cy - + application.workarea(transientforwindoworwindow).cy - + innerclientframewidth.cy); + movemenulayout(flayout,innerclientrect.pos); + updatepos(); + invalidate(); + include(flayout.state,mls_valid); + finally + exclude(flayout.state,mls_updating); + end; + end; +end; + +procedure tpopupmenuwidget.invalidatelayout(); +begin + if (componentstate * [csloading,csdestroying] = []) then begin + exclude(flayout.state,mls_valid); + invalidate(); + if (flayout.menu <> nil) and (flayout.menu.submenu.count > 0) and + ((fwidgetrect.cx <= 0) or (fwidgetrect.cy <= 0)) then begin + updatelayout(); //there will be no paint event + end; + end; +end; + +procedure tpopupmenuwidget.nextpopupshowing; +begin + //dummy; +end; + +function tpopupmenuwidget.showmenu(const aposrect: rectty; + aposition: graphicdirectionty; aactivate: boolean): tmenuitem; +var + transientforwindow: twindow; +begin + result:= nil; + flayout.menu.doupdate; + flayout.menu.onchange:= {$ifdef FPC}@{$endif}menuchanged; + fposrect:= aposrect; + fposition:= aposition; + updatelayout(); + if fprevpopup <> nil then begin + frefpos:= fprevpopup.screenpos; + fprevpopup.window.registermovenotification(ievent(self)); + end; + if fprevpopup <> nil then begin + transientforwindow:= fprevpopup.window; + color:= transientforwindow.owner.actualopaquecolor; + end + else begin + transientforwindow:= application.activewindow; + end; + if aactivate and (flayout.activeitem < 0) then begin + show(); //window must be visible for mouse grab + capturemouse(); + setactiveitem(nextmenuitem(flayout)); +// if flayout.activeitem < 0 then begin +// exit; +// end; + end; + show(aactivate,transientforwindow); + if aactivate then begin + result:= fselecteditem; + if fprevpopup = nil then begin + flayout.menu.owner.checkexec; + end; + end; +end; + +procedure tpopupmenuwidget.menuchanged(const sender: tmenuitem); +begin + invalidatelayout(); +end; + +procedure tpopupmenuwidget.dopaintforeground(const canvas: tcanvas); +begin + inherited; + canvas.move(clientpos); + drawmenu(canvas,flayout); +end; + +function tpopupmenuwidget.isinpopuparea(const apos: pointty): boolean; +begin + result:= pointinrect(apos,fwidgetrect); +end; + +function tpopupmenuwidget.checkprevpopuparea(const apos: pointty): boolean; +begin + result:= false; + if not pointinrect(apos,fwidgetrect) then begin + if fprevpopup <> nil then begin + result:= fprevpopup.isinpopuparea(apos); + end; + if result then begin + deactivatemenu; + end; + end; +end; + +procedure tpopupmenuwidget.mouseevent(var info: mouseeventinfoty); +var + bo1: boolean; + itembefore: integer; +// int1: integer; + pt1: pointty; + + procedure resetmouseflag(); + begin + with flayout do begin + if (fmouseitem >= 0) and (fmouseitem <= high(cells)) then begin + with cells[fmouseitem],buttoninfo do begin + if state * [shs_clicked,shs_mouse] <> [] then begin + state:= state - [shs_clicked,shs_mouse]; + invalidaterect(dimouter); + end; + end; + fmouseitem:= -1; + end; + end; + end; //resetmouseflag + + procedure setmouseitem(const sender: tpopupmenuwidget; const apos: pointty); + var + pt2: pointty; + begin + with sender,flayout do begin + pt2:= subpoint(apos,paintpos); + internalsetactiveitem(getcellatpos(flayout,pt2), + ss_left in info.shiftstate,false,pointinrect(pt2,sizerect)); + if activeitem >= 0 then begin + include(cells[activeitem].buttoninfo.state,shs_mouse); + fmouseitem:= activeitem; + if (itembefore <> activeitem) and + tmenuitem1(menu.items[activeitem]).canshowhint then begin + application.restarthint(self); + end; + end + else begin + resetmouseflag; + end; + end; + end; //setmouseitem + +var + canmousemove1: boolean; + b1: boolean; +begin + if (csdesigning in componentstate) and (ws_iswidget in fwidgetstate) then begin + inherited; + end + else begin + with info,flayout do begin + canmousemove1:= (csdesigning in componentstate) or + not (aso_nomenumousemove in assistiveoptions) or + (eventkind in mouseposevents - [ek_mousemove,ek_mousepark]); + itembefore:= activeitem; + pt1:= translatewidgetpoint(info.pos,self,nil); + if (mlo_keymode in options) and + (eventkind in [ek_mousemove,ek_buttonpress, + ek_buttonrelease,ek_mousepark]) then begin + if (distance(pt1,mousepos) <= 3) and + (eventkind in [ek_mousemove,ek_mousepark]) then begin + exit; + end + else begin + exclude(options,mlo_keymode); + end; + end; + if (fnextpopup <> nil) and + pointinrect(pt1,fnextpopup.fwidgetrect) and + not (mlo_childreninactive in options) then begin + if (eventkind = ek_mousemove) and canmousemove1 or + (eventkind = ek_buttonpress) and + (aso_nomenumousemove in assistiveoptions) and + not(csdesigning in componentstate) then begin + invalidaterect(cells[activeitem].dimouter); + b1:= false; + if eventkind = ek_buttonpress then begin + b1:= not fnextpopup.active(); + setmouseitem(fnextpopup,translatewidgetpoint(pos,self,fnextpopup)); + if fnextpopup.activeitem >= 0 then begin + with fnextpopup,flayout,cells[activeitem],buttoninfo do begin + include(state,shs_clicked); + end; + end; + end; + if b1 then begin + with fnextpopup,flayout do begin + assistiveserver.doitementer( + tmenuitem1(menu).getiassistiveclient(),cells,activeitem); + end; + end; + fnextpopup.activatemenu(false,ss_left in info.shiftstate,true); + exit; + end; + end; + if (eventkind in mouseposevents) and canmousemove1 then begin + if not checkprevpopuparea(pt1) then begin + if pointinrect(pos,paintrect) then begin + setmouseitem(self,pos); + end + else begin + resetmouseflag; + if eventkind = ek_buttonpress then begin + closepopupstack(nil); + exit; + end; + end; + end; + end; + case eventkind of + ek_buttonpress: begin + if (activeitem >= 0) and (button = mb_left) then begin + if (fnextpopup <> nil) and (activeitem = itembefore) then begin + fclickeditem:= activeitem; //prepare for close popupup + end; + if mlo_childreninactive in options then begin + exclude(options,mlo_childreninactive); + activeitem:= -1; + include(state,mls_assistivelocked); + try + mouseevent(info); + finally + exclude(state,mls_assistivelocked); + end; + if (activeitem >= 0) and + tmenuitem1(menu.items[activeitem]).canshowhint then begin + application.hidehint; + end; + exit; + end; + with cells[activeitem],buttoninfo do begin + include(state,shs_clicked); + invalidaterect(dimouter); + end; + end; + end; + ek_buttonrelease: begin + if (activeitem >= 0) and (button = mb_left) then begin + with cells[activeitem],buttoninfo do begin + bo1:= shs_clicked in state; + exclude(state,shs_clicked); + if not (csdesigning in componentstate) or + (aso_nomenumousemove in assistiveoptions) then begin + exclude(state,shs_mouse); + end; + invalidaterect(dimouter); + if bo1 then begin + include(info.eventstate,es_processed); + selectmenu(false,false); + if (mlo_main in options) and (fclickeditem = activeitem) then begin + fclickeditem:= -1; + closepopupstack(nil); + exit; + end; + fclickeditem:= activeitem; + end; + end; + end; + end; + ek_clientmouseleave: begin + resetmouseflag; + if (fnextpopup = nil) then begin + setactiveitem(-1); + end; + end; + end; + end; + if not (es_processed in info.eventstate) then begin + inherited; + end; + end; +end; + +procedure tpopupmenuwidget.internalsetactiveitem(const avalue: integer; + const aclicked: boolean; const force: boolean; + const nochildreninactive: boolean); +var + value1: integer; + activeitembefore: int32; +begin + with flayout do begin + activeitembefore:= activeitem; + value1:= avalue; + if (value1 < 0) or (menu = nil) then begin + value1:= -1; + end; + if (activeitem <> value1) or force then begin + fclickeditem:= -1; + if (menu <> nil) and (activeitem >= 0) and + (activeitem < menu.submenu.count) then begin + if (fnextpopup <> nil) then begin + fnextpopup.release1(false); + end; + with cells[activeitem],buttoninfo do begin + state:= state - [shs_clicked,{shs_mouse,}shs_active,shs_focused]; + if value1 <> -1 then begin + state:= state - [shs_mouse]; + end; + invalidaterect(dimouter); + end; + end; + activeitem:= value1; + if menu <> nil then begin + tmenuitem1(menu).factiveitem:= value1; //for iassistiveclient + end; + if activeitem >= 0 then begin + if not menu[value1].canactivate then begin + activeitem:= nextmenuitem(flayout); + end; + with cells[activeitem],buttoninfo do begin + state:= state + [shs_focused]; +// state:= state + [shs_mouse]; + if aclicked then begin + include(state,shs_clicked); + end; + invalidaterect(dimouter); + if not (mlo_childreninactive in options) and + (tmenuitem1(menu).fsubmenu[activeitem].count > 0) then begin + tpopupmenuwidget.create(@fnextpopup,tmenuitem1(menu).fsubmenu[activeitem], + fwindow); + fnextpopup.fprevpopup:= self; + nextpopupshowing; + fnextpopup.showmenu(makerect(translatetoscreen(ca.dim.pos),ca.dim.size), + popupdirection,false); + fnextpopup.beginkeymode; + end; + end; + capturemouse; + if canassistive and not (mls_assistivelocked in flayout.state) and + (active or (mlo_main in flayout.options )) then begin + //for mainmenu + if activeitembefore < 0 then begin + assistivemenuactivated(); + end + else begin + assistiveserver.doitementer(tmenuitem1(menu).getiassistiveclient(), + cells,activeitem); + end; + end; + end; + end + else begin + if aclicked and (value1 >= 0) then begin + with cells[activeitem],buttoninfo do begin + if not (shs_clicked in state) then begin + include(state,shs_clicked); + invalidaterect(dimouter); + end; + end; + end; + end; + if (activeitem < 0) and (mlo_main in options) and + not nochildreninactive then begin + include(options,mlo_childreninactive); + releasemouse; + end; + end; +end; + +function tpopupmenuwidget.getactiveitem: integer; +begin + with flayout do begin + if menu = nil then begin + activeitem:= -1; + end; + result:= activeitem; + end; +end; + +procedure tpopupmenuwidget.setactiveitem(const value: integer); +begin + internalsetactiveitem(value,false,false,false); +end; + +procedure tpopupmenuwidget.activatemenu( + const keymode,aclicked,nokeymodereset: boolean); +begin + capturekeyboard; + capturemouse; + if keymode then begin + beginkeymode; + end + else begin + if not nokeymodereset then begin + exclude(flayout.options,mlo_keymode); + end; + end; + if (flayout.menu.count > 0) and (flayout.activeitem < 0) then begin + if keymode then begin + internalsetactiveitem(0,aclicked,true,false); + end; + if (show(true,nil) <> mr_windowdestroyed) and (fprevpopup = nil) then begin +// window.removefocuslock; + flayout.menu.owner.checkexec; + end; + end; +end; + +procedure tpopupmenuwidget.childdeactivated(const sender: tpopupmenuwidget); +begin + capturemouse; + capturekeyboard; +end; + +procedure tpopupmenuwidget.deactivatemenu; +begin + setactiveitem(-1); + window.endmodal; + if fprevpopup <> nil then begin + fprevpopup.childdeactivated(self); + end; +end; + +procedure tpopupmenuwidget.selectmenu(const keymode: boolean; + const keyreturn: boolean); +var + i1: integer; + bo1: boolean; +begin + with flayout do begin + bo1:= not((menu.owner <> nil) and + (csdesigning in menu.owner.componentstate)); + i1:= activeitem; + if mlo_childreninactive in options then begin + exclude(options,mlo_childreninactive); + include(flayout.state,mls_assistivelocked); + try + internalsetactiveitem(i1,false,true,false); + finally + exclude(flayout.state,mls_assistivelocked); + end; + end; + if (fnextpopup <> nil) then begin + if keymode and (bo1 or not keyreturn) then begin + fnextpopup.activatemenu(keymode,false,false); + end + else begin + fnextpopup.window.bringtofront; //win32 workaround + end; + end + else begin + if i1 >= 0 then begin + with menu[i1] do begin + if (mao_asyncexecute in options) then begin + closepopupstack(menu[i1]); + if bo1 then begin + asyncexecute; + end; + end + else begin + releasemouse; + if bo1 then begin + execute; + end; + closepopupstack(menu[i1]); + end; + end; + end; + end; + if not bo1 and assigned(menuexehandlerdesign) and (i1 >= 0) and + (not (mlo_main in options) or (fclickeditem = i1) or + (menu[i1].submenu.count = 0)) then begin + closepopupstack(menu[i1]); + menuexehandlerdesign(menu[i1]); + end; + end; +end; + +function tpopupmenuwidget.rootpopup: tpopupmenuwidget; +begin + result:= self; + while result.fprevpopup <> nil do begin + result:= result.fprevpopup; + end; +end; + +procedure tpopupmenuwidget.beginkeymode; +begin + include(flayout.options,mlo_keymode); + flayout.mousepos:= application.mouse.pos; +end; + +procedure tpopupmenuwidget.paint(const canvas: tcanvas); +begin + if not (mls_valid in flayout.state) then begin + updatelayout(); + end; + inherited; +end; + +procedure tpopupmenuwidget.dokeydown(var info: keyeventinfoty); + + procedure checkshortcut(widget: tpopupmenuwidget); + var + int1: integer; + bo1: boolean; + begin + if widget <> nil then begin + with widget do begin + int1:= msemenuwidgets.checkshortcut(flayout,info,bo1,flayout.activeitem); + if int1 >= 0 then begin + if not bo1 then begin + include(flayout.state,mls_assistivelocked); + end; + try + setactiveitem(int1); + beginkeymode; + finally + exclude(flayout.state,mls_assistivelocked); + end; + if not bo1 then begin + selectmenu(true,false); + end; + end; + end; + end; + end; + + procedure swapkeys; + begin + if mlo_horz in flayout.options then begin + with info do begin + case key of + key_right: key:= key_down; + key_up: key:= key_left; + key_left: key:= key_up; + key_down: key:= key_right; + end; + end; + end; + end; + + function isup(position: graphicdirectionty): boolean; + begin + if mlo_horz in flayout.options then begin + result:= (position = gd_up) xor (info.key = key_right); + end + else begin + result:= (position = gd_left) xor (info.key = key_right); + end; + end; + +var + int1: integer; + intf1: iassistiveclientmenu; + dir1: graphicdirectionty; + b1: boolean; +begin + with info,flayout do begin + if (shiftstate*shiftstatesmask = []) then begin + swapkeys; + include(eventstate,es_processed); + beginkeymode; + case key of + key_return,{key_enter,}key_space: begin + if not (ss_repeat in shiftstate) and + not ((aso_noreturnkeymenuexecute in assistiveoptions) and + (key = key_return)) then begin + selectmenu(true,true); + end; + end; + key_up: begin + setactiveitem(prevmenuitem(flayout)); + end; + key_down: begin + setactiveitem(nextmenuitem(flayout)); + end; + key_left,key_right: begin + if (fnextpopup <> nil) and isup(fnextpopup.factposition) then begin + fnextpopup.activatemenu(true,false,false); + end + else begin + exclude(options,mlo_keymode); + if not isup(factposition) then begin + deactivatemenu; + if (fprevpopup <> nil) and + (fprevpopup.flayout.options * [mlo_main,mlo_horz] = + [mlo_main,mlo_horz]) then begin + exclude(eventstate,es_processed); + end; + end + else begin + b1:= true; + if rootpopup <> self then begin + with rootpopup,flayout do begin + if mlo_main in flayout.options then begin + exclude(eventstate,es_processed); + swapkeys; + int1:= activeitem; + if canassistive and + not (mls_assistivelocked in flayout.state) then begin + //for mainmenu + intf1:= tmenuitem1(menu).getiassistiveclient(); + assistiveserver.domenuactivated(intf1); + end; + dokeydown1(info); + if activeitem = int1 then begin + include(options,mlo_keymode); + self.capturekeyboard; //ignore the key + end; + swapkeys; + include(eventstate,es_processed); + b1:= false; + end; + end; + end; + if b1 and canassistive and + not (mls_assistivelocked in flayout.state) then begin + dir1:= gd_right; + if mlo_horz in options then begin + dir1:= gd_down; + end; + assistiveserver.donavigbordertouched(getiassistiveclient,dir1); + end; + end; + end; + end; + key_escape: begin + beginkeymode; + deactivatemenu; + end + else begin + exclude(eventstate,es_processed); + exclude(flayout.options,mlo_keymode); + checkshortcut(self); //actual popup first + if not (es_processed in eventstate) then begin + checkshortcut(fnextpopup); + end; + end; + end; + swapkeys; + end + else begin + if shiftstate = [ss_alt] then begin //check nextpopup first + checkshortcut(fnextpopup); + if not (es_processed in eventstate) then begin + checkshortcut(self); + end; + end + else begin + if (shiftstate = [ss_shift]) and (key = key_menu) and + (fnextpopup = nil) then begin + include(eventstate,es_processed); + include(flayout.state,mls_assistivelocked); + try + setactiveitem(0); + beginkeymode(); + selectmenu(true,false); + finally + exclude(flayout.state,mls_assistivelocked); + end; + end; + end; + end; + if not (es_processed in eventstate) and (fprevpopup <> nil) then begin + fprevpopup.dokeydown1(info); + end; + end; +end; + +procedure tpopupmenuwidget.closepopupstack(aselecteditem: tmenuitem; + const cancelmodal: boolean = false); +var + widget1: tpopupmenuwidget; +begin + widget1:= self; + while true do begin + with widget1 do begin + if not (mlo_main in flayout.options) then begin + window.endmodal; + end; + end; + if widget1.fprevpopup <> nil then begin + widget1:= widget1.fprevpopup; + end + else begin + break; + end; + end; + widget1.fselecteditem:= aselecteditem; //return value for procedure showmenu + widget1.release1(cancelmodal); +end; + +procedure tpopupmenuwidget.clientrectchanged; +begin + inherited; + if not (mls_updating in flayout.state) then begin + invalidatelayout(); + updatelayout(); + end; +end; + +procedure tpopupmenuwidget.objectevent(const sender: tobject; + const event: objecteventty); +var + po1: pointty; +begin + inherited; + if (event = oe_changed) then begin + if (fprevpopup <> nil) and (sender = fprevpopup.window) then begin + po1:= fprevpopup.screenpos; + addpoint1(fposrect.pos,subpoint(po1,frefpos)); + frefpos:= po1; + updatepos; + end; + if (sender <> nil) and ((sender = ftemplates.frame) or + (sender = ftemplates.face) or + (sender = ftemplates.itemframe) or + (sender = ftemplates.itemface)) then begin + updatetemplates; //refresh +// if not (csloading in componentstate) then begin +// invalidatelayout(); +// end; + end; + end; +end; + +procedure tpopupmenuwidget.fontchanged; +begin + invalidatelayout(); + if fparentwidget <> nil then begin + fparentwidget.dolayout(self); + end; +end; + +procedure tpopupmenuwidget.applicationactivechanged(const avalue: boolean); +begin + if not avalue and not (mlo_main in flayout.options) and visible then begin + closepopupstack(nil); + end; +end; + +procedure tpopupmenuwidget.assistivemenuactivated(); +var + intf1: iassistiveclientmenu; +begin + with flayout do begin + intf1:= tmenuitem1(menu).getiassistiveclient(); + assistiveserver.domenuactivated(intf1); + assistiveserver.doitementer(intf1,cells,activeitem); + end; +end; + +procedure tpopupmenuwidget.doafteractivate(); +begin + inherited; + if canassistive() then begin + assistivemenuactivated(); + end; +end; + +function tpopupmenuwidget.activateoptionset: boolean; +begin + result:= (fmenucomp <> nil) and (mo_activate in fmenucomp.options); +end; + +procedure tpopupmenuwidget.showhint(const aid: int32; var info: hintinfoty); +begin + inherited; + with flayout do begin + if (activeitem >= 0) and + tmenuitem1(menu.items[activeitem]).canshowhint then begin + info.caption:= menu.items[activeitem].hint; + end; + end; +end; + +function tpopupmenuwidget.trycancelmodal(const newactive: twindow): boolean; +var + widget2: tpopupmenuwidget; +// window1: twindow; + int1: integer; +begin + result:= false; + if newactive <> nil then begin + widget2:= self; + int1:= 1; + while (widget2 <> nil) do begin + if widget2.window = newactive then begin + exit; + end; + if widget2.window.modal then begin + inc(int1); + end; + widget2:= widget2.fprevpopup; + end; + if application.modallevel = int1 then begin + result:= true; //no lower modal window, accept new active window +{$ifdef mse_debugwindowfocus} + debugwriteln('closepopupstack '+inttostr(int1)); +{$endif} + closepopupstack(nil,true); + end; + end; +end; + +procedure tpopupmenuwidget.release1(const acancelmodal: boolean); +begin + visible:= false; + release; +end; + +class function tpopupmenuwidget.classskininfo(): skininfoty; +begin + result:= inherited classskininfo(); + result.objectkind:= sok_mainmenuwidget; +end; + +function tpopupmenuwidget.getassistiveflags(): assistiveflagsty; +begin + result:= inherited getassistiveflags() + [asf_menu]; +end; + +function tpopupmenuwidget.getassistivecaption(): msestring; +begin + result:= tmenuitem1(flayout.menu).getassistivecaption(); + if result = '' then begin + result:= inherited getassistivecaption(); + end; +end; + +function tpopupmenuwidget.getassistivetext(): msestring; +begin + result:= tmenuitem1(flayout.menu).getassistivetext(); + if result = '' then begin + result:= inherited getassistivetext(); + end; +end; + +function tpopupmenuwidget.getassistivehint(): msestring; +begin + result:= tmenuitem1(flayout.menu).getassistivehint(); + if result = '' then begin + result:= inherited getassistivehint(); + end; +end; + +{ tcustommainmenuwidget } + +procedure tcustommainmenuwidget.internalcreateframe; +begin + inherited; + tcustomframe1(fframe).fi.levelo:= 0; //do not set localprops +end; + +procedure tcustommainmenuwidget.loaded; +begin + inherited; +// updatelayoutx(); +end; + +procedure tcustommainmenuwidget.updatepos; +begin + //dummy +end; + +procedure tcustommainmenuwidget.getautopaintsize(var asize: sizety); +begin + asize:= addsize(flayout.sizerect.size,innerframewidth); +end; + +procedure tcustommainmenuwidget.updatelayout(); +var + rect1: rectty; + size1: sizety; +begin + if flayout.state * [mls_valid,mls_updating] = [] then begin + include(flayout.state,mls_updating); + try + size1:= innerclientrect.size; + if ow1_autowidth in foptionswidget1 then begin + size1.cx:= bigint; + end; + if ow1_autoheight in foptionswidget1 then begin + size1.cy:= bigint; + end; + if mlo_horz in flayout.options then begin + calcmenulayout(flayout,getcanvas,size1.cx); + end + else begin + calcmenulayout(flayout,getcanvas,size1.cy); + end; + movemenulayout(flayout,innerclientrect.pos); + rect1:= fwidgetrect; + if mlo_horz in flayout.options then begin + rect1.cy:= flayout.sizerect.size.cy + innerclientframewidth.cy; + if an_bottom in fanchors then begin + rect1.y:= rect1.y + fwidgetrect.cy - rect1.cy; + end; + end + else begin + rect1.cx:= flayout.sizerect.size.cx + innerclientframewidth.cx; + if an_right in fanchors then begin + rect1.x:= rect1.x + fwidgetrect.cx - rect1.cx; + end; + end; + widgetrect:= rect1; + include(flayout.state,mls_valid); + invalidate(); + finally + exclude(flayout.state,mls_updating); + end; + end; +end; + +procedure tcustommainmenuwidget.nextpopupshowing; +begin + inherited; + if fmenucomp <> nil then begin + fnextpopup.assigntemplate(tmainmenu(fmenucomp).popuptemplate); + end; +end; + +procedure tcustommainmenuwidget.release1(const acancelmodal: boolean); +begin + if acancelmodal then begin + setlinkedvar(nil,tlinkedobject(factivewindowbefore)); + //do not restore active window + end; + setactiveitem(-1); + releasemouse; +// activeitem:= int1; +end; + +function tcustommainmenuwidget.isinpopuparea(const apos: pointty): boolean; +begin + result:= pointinrect(translatewidgetpoint(apos,nil,parentwidget),fwidgetrect); +end; + +procedure tcustommainmenuwidget.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + inherited; + if not (csdesigning in componentstate) then begin + if not (es_processed in info.eventstate) and + not (es_modal in info.eventstate) and + ((info.shiftstate = [ss_alt]) or + (info.shiftstate = [ss_shift]) and (info.key = key_menu)) then begin + dokeydown1(info); + end; + if not (es_processed in info.eventstate) and (fmenucomp <> nil) then begin + fmenucomp.menu.doshortcut(info); + end; + end; +end; + +procedure tcustommainmenuwidget.childdeactivated(const sender: tpopupmenuwidget); +begin + inherited; + if mlo_keymode in sender.flayout.options then begin + deactivatemenu; + end; +end; + +procedure tcustommainmenuwidget.restorefocus; +var + ar1: winidarty; + ar2: integerarty; +begin + twindow1(window).unlockactivate; + releasekeyboard; + if mws_firstactivated in fstate then begin + if factivewindowbefore <> fwindow then begin + if mws_raised in fstate then begin + if (fstackedunderbefore <> nil) then begin + if fstackedunderbefore.visible then begin + setlength(ar1,2); + ar1[0]:= fstackedunderbefore.winid; + ar1[1]:= fwindow.winid; + gui_getzorder(ar1,ar2); + if ar2[1] > ar2[0] then begin + {$ifdef mse_debugzorder} + debugwindow('**mainmenuwidget.restorefocus',fwindow.winid); + debugwindow(' before ',fstackedunderbefore.winid); + {$endif} + gui_stackunderwindow(fwindow.winid,fstackedunderbefore.winid); + tguiapplication1(application).zorderinvalid; + end; + end; + end + { + if (fstackedoverbefore <> nil) then begin + if fstackedoverbefore.visible then begin + setlength(ar1,2); + ar1[0]:= fstackedoverbefore.winid; + ar1[1]:= fwindow.winid; + gui_getzorder(ar1,ar2); + if ar2[1] > ar2[0] then begin + gui_stackoverwindow(fwindow.winid,fstackedoverbefore.winid); + end; + end; + end + } + else begin +// if activateoptionset then begin +// window.stackover(nil); + window.sendtobacklocal; +// end; + end; + end; + end; + if application.active and not ((fmenucomp = nil) or + (csdesigning in fmenucomp.componentstate)) and + (factivewindowbefore <> nil) and factivewindowbefore.visible then begin + factivewindowbefore.reactivate(); + end; + setlinkedvar(nil,tlinkedobject(factivewindowbefore)); + setlinkedvar(nil,tlinkedobject(fstackedunderbefore)); + end; +end; + +procedure tcustommainmenuwidget.checkactivate(const force,noraise: boolean); +begin + if force then begin + include(fstate,mws_forced); + end; + if not (mws_firstactivated in fstate) or force then begin + if not (mws_firstactivated in fstate) then begin + include(fstate,mws_firstactivated); + setlinkedvar(fwindow.stackedunder(true),tlinkedobject(fstackedunderbefore)); + end; + if force or activateoptionset then begin + capturekeyboard; + if (factivewindowbefore = nil) then begin + setlinkedvar(application.activewindow,tlinkedobject(factivewindowbefore)); + end; + if application.active and (fmenucomp <> nil) and not noraise then begin + window.bringtofrontlocal; + include(fstate,mws_raised); + end; + end; + end; + if mws_forced in fstate then begin + twindow1(window).lockactivate; + capturekeyboard; + end; + if (factivewindowbefore <> nil) then begin + factivewindowbefore.deactivateintermediate(); + end; +end; + +procedure tcustommainmenuwidget.internalsetactiveitem(const Value: integer; + const aclicked: boolean; const force: boolean; + const nochildreninactive: boolean); +begin + if (value >= 0) and not (csdesigning in componentstate) then begin + checkactivate(false,ow_background in window.owner.optionswidget); + end; + inherited; + if value = -1 then begin + restorefocus; + fstate:= []; + end; +end; + +procedure tcustommainmenuwidget.activatemenu( + const keymode,aclicked,nokeymodereset: boolean); +begin + inherited; + flayout.menu.owner.checkexec; +end; + +procedure tcustommainmenuwidget.selectmenu(const keymode: boolean; + const keyreturn: boolean); +begin + checkactivate(true,fnextpopup = nil); + if fnextpopup <> nil then begin + window.activate; + end; + include(fstate,mws_raised); + inherited; + flayout.menu.owner.checkexec; +end; + +procedure tcustommainmenuwidget.mouseevent(var info: mouseeventinfoty); +begin + inherited; + if (activeitem >= 0) and (info.eventkind = ek_buttonpress) then begin + if factivewindowbefore <> nil then begin + twindow1(window).lockactivate; + capturekeyboard; +// factivewindowbefore.deactivateintermediate; + end; + end; +end; + +procedure tcustommainmenuwidget.deactivatemenu; +begin + inherited; + releasemouse; +end; + +function tcustommainmenuwidget.checkprevpopuparea(const apos: pointty): boolean; +var + po1: pointty; +begin + po1:= translatewidgetpoint(apos,nil,parentwidget); + result:= not pointinrect(po1,fwidgetrect) and + pointinrect(apos,rootwidget.widgetrect); + if result then begin + capturemouse; + release1(false); + end; +end; + +{ tframemenuwidget } + +constructor tframemenuwidget.create(const aparent: twidget; + const amenu: tmenuitem); +begin + inherited create(nil,amenu,nil,nil,fmenucomp); + foptionswidget:= foptionswidget-[ow_mousefocus,ow_tabfocus,ow_arrowfocus]; + fwidgetstate:= fwidgetstate - [ws_iswidget]; + setlockedparentwidget(aparent); + flayout.options:= [mlo_horz,mlo_main,mlo_childreninactive]; + flayout.popupdirection:= gd_down; + if not (csloading in aparent.ComponentState) and + not (csloading in componentstate) then begin +// updatelayout(); + visible:= true; + end; +end; + +constructor tframemenuwidget.create(const aparent: twidget; const amenu: tmainmenu); +begin + fmenucomp:= amenu; + create(aparent,amenu.menu); +end; + +procedure tframemenuwidget.loaded; +begin + include(fwidgetstate,ws_visible); + inherited; +end; + +{ tmainmenuwidget } + +constructor tmainmenuwidget.create(aowner: tcomponent); +begin + flocalframeandface:= true; + setlinkedvar(twidgetmainmenu.create(self{nil}),tmsecomponent(fmenucomp)); + fmenucomp.setsubcomponent(true); + inherited create(nil,fmenucomp.menu,nil,aowner,fmenucomp); + if csdesigning in componentstate then begin +{$warnings off} + tmsecomponent1(fmenucomp).setdesigning(true); +{$warnings on} + end; + freeandnil(fframe); + flayout.options:= [mlo_horz,mlo_main,mlo_childreninactive]; + flayout.popupdirection:= gd_down; + if not (csloading in componentstate) then begin +// updatelayout; + end; + visible:= true; +end; + +destructor tmainmenuwidget.destroy; +begin + fmenucomp.free; + inherited; +end; + +procedure tmainmenuwidget.initnewcomponent(const ascale: real); +begin + inherited; + with fmenucomp.menu.submenu do begin + if count = 0 then begin + insert(0,['Item0'],[],[],[]); + end; + end; + bounds_cx:= 100; +end; + +procedure tmainmenuwidget.setmenu(const avalue: twidgetmainmenu); +begin + fmenucomp.assign(avalue); +end; + +function tmainmenuwidget.getmenu: twidgetmainmenu; +begin + result:= twidgetmainmenu(fmenucomp); +end; + +procedure tmainmenuwidget.setoptions(const avalue: mainmenuwidgetoptionsty); +begin + if foptions <> avalue then begin + foptions:= avalue; + if mwo_vertical in foptions then begin + exclude(flayout.options,mlo_horz); + end + else begin + include(flayout.options,mlo_horz); + end; + if not (csloading in componentstate) then begin +// invalidatelayout(); + end; + end; +end; + +procedure tmainmenuwidget.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (event = oe_changed) and (sender = fmenucomp) and + not (csloading in componentstate) then begin + assigntemplate(fmenucomp.template); +// invalidatelayout(); + end; +end; + +procedure tmainmenuwidget.loaded; +begin + inherited; + assigntemplate(fmenucomp.template); +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/mseobjectpicker.pas b/mseide-msegui/lib/common/widgets/mseobjectpicker.pas new file mode 100644 index 0000000..e35fc0c --- /dev/null +++ b/mseide-msegui/lib/common/widgets/mseobjectpicker.pas @@ -0,0 +1,733 @@ +{ MSEgui Copyright (c) 1999-2015 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit mseobjectpicker; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface +uses + mseevent,mseglob,mseguiglob,mseclasses,msegui,msegraphics,msegraphutils, + msepointer,msetypes; + +type + ihintcontroller = interface(inullinterface) + function getwidget: twidget; + end; + + thintcontroller = class + private + fintf: ihintcontroller; + public + constructor create(const intf: ihintcontroller); + procedure mouseevent(var info: mouseeventinfoty); + end; + + tobjectpicker = class; + + iobjectpicker = interface(inullinterface) + function getwidget: twidget; + function getcursorshape(const sender: tobjectpicker; + var ashape: cursorshapety): boolean; + //true if object found + procedure getpickobjects(const sender: tobjectpicker; var objects: integerarty); +// procedure getmouseoverobjects(const sender: tobjectpicker; var objects: integerarty); + procedure beginpickmove(const sender: tobjectpicker); + procedure pickthumbtrack(const sender: tobjectpicker); + procedure endpickmove(const sender: tobjectpicker); + procedure cancelpickmove(const sender: tobjectpicker); + procedure paintxorpic(const sender: tobjectpicker; const acanvas: tcanvas); + end; + + objectpickerstatety = (ops_picking,ops_rectselecting, + ops_multiselecting,ops_moving, + ops_xorpicpainted,ops_xorpicremoved, + ops_newwidgetgrab,ops_newwindowgrab); + objectpickerstatesty = set of objectpickerstatety; +const + activestates = [ops_picking,ops_rectselecting,ops_multiselecting,ops_moving]; +type + objectpickeroptionty = (opo_mousemoveobjectquery,opo_rectselect, + opo_multiselect,opo_thumbtrack); + objectpickeroptionsty = set of objectpickeroptionty; + + tobjectpicker = class //todo: area selecting, area deselecting + private + fintf: iobjectpicker; + fmouseoverobjects: integerarty; + fselectobjects: integerarty; + fpickrect: rectty; + fpickoffset: pointty; + fstate: objectpickerstatesty; + forigin: originty; + foptions: objectpickeroptionsty; + fmouseeventinfopo: pmouseeventinfoty; + fkeyeventinfopo: pkeyeventinfoty; + fcursorshape: cursorshapety; + procedure dopaint(const acanvas: tcanvas); + procedure dokeypress(const sender: twidget; var info: keyeventinfoty); + procedure endmoving(const resetflag: boolean); + procedure initxorcanvas(const acanvas: tcanvas); + function getpos: pointty; + function getshiftstate: shiftstatesty; + function getcurrentobjects: integerarty; + function getthumbtrack: boolean; + procedure setthumbtrack(const avalue: boolean); + public + constructor create(const intf: iobjectpicker; aorigin: originty = org_client); + destructor destroy; override; + procedure mouseevent(var info: mouseeventinfoty); + procedure dokeydown(var ainfo: keyeventinfoty); + function removexorpic: boolean; + function paintxorpic: boolean; + procedure dobeforepaint(const acanvas: tcanvas); + procedure doafterpaint(const acanvas: tcanvas); + +// procedure restorexorpic(const canvas: tcanvas); + procedure clear; + function hasselectobjects: boolean; + function hasmouseoverobjects: boolean; + function hascurrentobjects: boolean; + function picking: boolean; + function rectselecting: boolean; + function multiselecting: boolean; + function moving: boolean; + function active: boolean; + + property mouseoverobjects: integerarty read fmouseoverobjects; + property selectobjects: integerarty read fselectobjects; + property currentobjects: integerarty read getcurrentobjects; + //mouseoverobjects or selectobjects dependent on state + property options: objectpickeroptionsty read foptions write foptions; + property thumbtrack: boolean read getthumbtrack write setthumbtrack; + property state: objectpickerstatesty read fstate; + property pickoffset: pointty read fpickoffset; + property pickpos: pointty read fpickrect.pos; + property pickrect: rectty read fpickrect; + property cursor: cursorshapety read fcursorshape; + property mouseeventinfopo: pmouseeventinfoty read fmouseeventinfopo; + property keyeventinfopo: pkeyeventinfoty read fkeyeventinfopo; + property shiftstate: shiftstatesty read getshiftstate; + property pos: pointty read getpos; + end; + +implementation +uses + msekeyboard,msearrayutils; + +type + twidget1 = class(twidget); + +{ tobjectpicker } + +constructor tobjectpicker.create(const intf: iobjectpicker; + aorigin: originty = org_client); +begin + fintf:= intf; + forigin:= aorigin; + fcursorshape:= cr_default; +end; + +destructor tobjectpicker.destroy; +begin + application.unregisteronkeypress({$ifdef FPC}@{$endif}dokeypress); + inherited; +end; + +procedure tobjectpicker.endmoving(const resetflag: boolean); +var + widget1: twidget; +begin + application.unregisteronkeypress({$ifdef FPC}@{$endif}dokeypress); + removexorpic; + widget1:= twidget1(fintf.getwidget); + if ops_newwidgetgrab in fstate then begin + widget1.releasemouse(not (ops_newwindowgrab in fstate)); + end + else begin + if ops_newwindowgrab in fstate then begin + widget1.window.releasemouse; + end; + end; + application.widgetcursorshape:= cr_default; + if resetflag then begin + addpoint1(fpickrect.pos,fpickoffset); + fpickrect.size:= nullsize; + fpickoffset:= nullpoint; + if opo_thumbtrack in foptions then begin + fintf.pickthumbtrack(self); + end; + exclude(fstate,ops_moving); + end; + exclude(fstate,ops_rectselecting); + fpickrect.size:= nullsize; +end; + +procedure tobjectpicker.mouseevent(var info: mouseeventinfoty); +var +// shape: cursorshapety; + widget1: twidget1; + shiftstates1: shiftstatesty; + + procedure domousemovequery(const force: boolean); + var + ar1: integerarty; + po1: pointer; + pt1,pt2: pointty; + begin + if opo_mousemoveobjectquery in foptions then begin + ar1:= copy(fmouseoverobjects); + pt1:= fpickrect.pos; + pt2:= fpickoffset; + fpickrect.pos:= info.pos; + fpickoffset:= nullpoint; + fintf.getpickobjects(self,fmouseoverobjects); + if (force or not isequalarray(ar1,fmouseoverobjects)) and + ((fselectobjects = nil) or (ops_multiselecting in fstate)) then begin + po1:= pointer(fmouseoverobjects); + pointer(fmouseoverobjects):= pointer(ar1); + fpickrect.pos:= pt1; + fpickoffset:= pt2; + removexorpic; + fpickrect.pos:= info.pos; + fpickoffset:= nullpoint; + pointer(fmouseoverobjects):= po1; + if (fmouseoverobjects <> nil) or (fselectobjects <> nil) and + (ops_multiselecting in fstate) then begin + paintxorpic; + end; + end; + end; + end; //domousemovequery + + procedure doend; + var + bo1: boolean; + pt1: pointty; + widget1: twidget; + begin + widget1:= fintf.getwidget; + pt1:= widget1.refpos(forigin); + endmoving(false); + fintf.endpickmove(self); + exclude(fstate,ops_moving); + addpoint1(fpickrect.pos,fpickoffset); + addpoint1(fpickrect.pos,subpoint(pt1,widget1.refpos(forigin))); + fpickrect.size:= nullsize; + fpickoffset:= nullpoint; + + with fintf.getwidget do begin + fcursorshape:= actualcursor(widgetmousepos(info)); + end; + bo1:= fintf.getcursorshape(self,fcursorshape); + application.widgetcursorshape:= fcursorshape; //restore pick cursor + if not bo1 then begin + fcursorshape:= cr_default; + end; + info.eventstate:= info.eventstate+[es_processed,es_objectpicking]; +// include(info.eventstate,es_processed); + fmouseoverobjects:= nil; + domousemovequery(true); + end; //doend + + procedure checkcursorshape; + begin + with fintf.getwidget do begin + fcursorshape:= actualcursor(widgetmousepos(info)); + end; + if fintf.getcursorshape(self,fcursorshape) then begin + info.eventstate:= info.eventstate+[es_processed,es_objectpicking]; +// include(info.eventstate,es_processed); + end + else begin + fcursorshape:= cr_default; + end; + application.widgetcursorshape:= fcursorshape; + end; //checkcursorshape + + function hasintersection(const ar1: integerarty): boolean; + var + int1,int2: integer; + begin + result:= false; + for int1:= 0 to high(ar1) do begin + for int2:= 0 to high(fselectobjects) do begin //check intersection + if ar1[int1] = fselectobjects[int2] then begin + result:= true; + break; + end; + end; + if result then begin + break; + end; + end; + end; //hasintersection + + procedure removeintersection(const ar1: integerarty); + var + int1: integer; + begin + for int1:= 0 to high(ar1) do begin + removeitem(fselectobjects,ar1[int1]); + end; + end; //removeintersection + + procedure addintersection(const ar1: integerarty); + var + int1,int2,int3: integer; + begin + for int1:= 0 to high(ar1) do begin + int3:= length(fselectobjects); + for int2:= 0 to high(fselectobjects) do begin + if fselectobjects[int2] = ar1[int1] then begin + int3:= -1; + break; //no duplicates; + end; + if fselectobjects[int2] > ar1[int1] then begin + int3:= int2; + break; + end; + end; + if int3 >= 0 then begin + insertitem(fselectobjects,int3,ar1[int1]); + end; + end; + end; //addintersection + +var + ar1: integerarty; + bo1: boolean; + infopobefore: pmouseeventinfoty; +// int1,int2,int3: integer; + +begin + infopobefore:= fmouseeventinfopo; + fmouseeventinfopo:= @info; + try + shiftstates1:= info.shiftstate * shiftstatesmask; + if (opo_multiselect in foptions) and + (shiftstates1*keyshiftstatesmask = [ss_ctrl]) xor + (ops_multiselecting in fstate) then begin + bo1:= removexorpic; + if (shiftstates1*keyshiftstatesmask = [ss_ctrl]) then begin + include(fstate,ops_multiselecting); + end + else begin + exclude(fstate,ops_multiselecting); + end; + if bo1 then begin + paintxorpic; + end; + end; + case info.eventkind of + ek_buttonpress: begin + if info.button = mb_left then begin + removexorpic; + fstate:= fstate - [ops_moving,ops_rectselecting]; + fpickrect.pos:= info.pos; + fpickrect.size:= nullsize; + fpickoffset:= nullpoint; + ar1:= nil; + include(fstate,ops_picking); + try + fintf.getpickobjects(self,ar1); + finally + exclude(fstate,ops_picking); + end; + if shiftstates1 = [ss_left] then begin + fmouseoverobjects:= ar1; + if (ar1 = nil) then begin + if fselectobjects <> nil then begin + info.eventstate:= info.eventstate+[es_processed,es_objectpicking]; +// include(info.eventstate,es_processed); + fselectobjects:= nil; + end; + end + else begin + if not hasintersection(ar1) then begin + fselectobjects:= nil; + end; + application.registeronkeypress({$ifdef FPC}@{$endif}dokeypress); + include(fstate,ops_moving); + widget1:= twidget1(fintf.getwidget); + fstate:= fstate - [ops_newwidgetgrab,ops_newwindowgrab]; + if not widget1.window.mousecaptured then begin + include(fstate,ops_newwindowgrab); + end; + if (ws_newmousecapture in widget1.fwidgetstate) or + not widget1.mousecaptured then begin + include(fstate,ops_newwidgetgrab); + end; + widget1.capturemouse(true); + fintf.beginpickmove(self); + widget1.window.update; + paintxorpic; + info.eventstate:= info.eventstate+[es_processed,es_objectpicking]; +// include(info.eventstate,es_processed); + checkcursorshape; + end; + end + else begin + if (shiftstates1 = [ss_shift,ss_left]) and + (opo_rectselect in foptions) then begin + application.registeronkeypress({$ifdef FPC}@{$endif}dokeypress); + include(fstate,ops_rectselecting); + info.eventstate:= info.eventstate+[es_processed,es_objectpicking]; + //include(info.eventstate,es_processed); + end + else begin + if (shiftstates1 = [ss_ctrl,ss_left]) and + (opo_multiselect in foptions) and (ar1 <> nil) then begin + fmouseoverobjects:= ar1; + if hasintersection(ar1) then begin + removeintersection(ar1); + end + else begin + addintersection(ar1); + end; + paintxorpic; + info.eventstate:= info.eventstate+[es_processed,es_objectpicking]; + // include(info.eventstate,es_processed); + checkcursorshape; + end; + end; + end; + end; + end; + ek_buttonrelease: begin + if (info.button = mb_left) then begin + if ops_moving in fstate then begin + doend; + if opo_mousemoveobjectquery in foptions then begin + fintf.getpickobjects(self,fmouseoverobjects); + end; + if hascurrentobjects then begin + paintxorpic; + end; + checkcursorshape; + end + else begin + if ops_rectselecting in fstate then begin + removexorpic; + fpickrect.size:= sizety(subpoint(info.pos,fpickrect.pos)); + ar1:= nil; + bo1:= (fpickrect.cx < 0) or (fpickrect.cy < 0); + normalizerect1(fpickrect); + fintf.getpickobjects(self,ar1); + if (ar1 <> nil) then begin + if bo1 then begin + removeintersection(ar1); + end + else begin + addintersection(ar1); + end; + end; + exclude(fstate,ops_rectselecting); + fpickrect.size:= nullsize; + if fselectobjects <> nil then begin + paintxorpic; + end; + end; + end; + end; + end; + ek_mousemove,ek_mousepark: begin + if ops_moving in fstate then begin + removexorpic; + fpickoffset:= subpoint(info.pos,fpickrect.pos); + if opo_thumbtrack in foptions then begin + fintf.pickthumbtrack(self); + end; + paintxorpic; + info.eventstate:= info.eventstate+[es_processed,es_objectpicking]; + // include(info.eventstate,es_processed); + end + else begin + if ops_rectselecting in fstate then begin + removexorpic; + fpickrect.size:= sizety(subpoint(info.pos,fpickrect.pos)); + paintxorpic; + end + else begin + if shiftstate * buttonshiftstatesmask = [] then begin + fpickrect.pos:= info.pos; + fpickoffset:= nullpoint; + checkcursorshape; + domousemovequery(false); + end; + end; + end; + end; + ek_mouseleave,ek_clientmouseleave: begin + if fselectobjects = nil then begin + removexorpic; + end; + fmouseoverobjects:= nil; + end; + end; + finally + fmouseeventinfopo:= infopobefore; + end; +end; + +procedure tobjectpicker.initxorcanvas(const acanvas: tcanvas); +begin + with acanvas do begin + rasterop:= rop_xor; + color:= cl_white; + dashes:= #1#1; + end; +end; + +procedure tobjectpicker.dopaint(const acanvas: tcanvas); +begin + if not (opo_thumbtrack in foptions) then begin + fintf.paintxorpic(self,acanvas); + end; + if ops_rectselecting in fstate then begin + acanvas.dashes:= #3#3; + acanvas.drawrect(fpickrect); + end; +end; + +function tobjectpicker.paintxorpic: boolean; +var + canvas1: tcanvas; + widget1: twidget; +begin + result:= not (ops_xorpicpainted in fstate); + if result then begin + widget1:= fintf.getwidget; +// widget1.update; + canvas1:= widget1.getcanvas(forigin); + initxorcanvas(canvas1); + dopaint(canvas1); + include(fstate,ops_xorpicpainted); + end; +end; + +function tobjectpicker.removexorpic: boolean; +var + canvas1: tcanvas; +begin + result:= ops_xorpicpainted in fstate; + if result then begin + canvas1:= fintf.getwidget.getcanvas(forigin); + initxorcanvas(canvas1); + dopaint(canvas1); + exclude(fstate,ops_xorpicpainted); + end; +end; +{ +procedure tobjectpicker.restorexorpic(const canvas: tcanvas); +var + int1: integer; +begin + if ops_moving in fstate then begin + int1:= canvas.save; + initxorcanvas(canvas); + if not (forigin = org_widget) then begin //todo org_screen + canvas.intersectcliprect(fintf.getwidget.clientrect); + canvas.move(fintf.getwidget.clientwidgetpos); + end; + fintf.paintxorpic(self,canvas); + include(fstate,ops_xorpicpainted); + canvas.restore(int1); + end; +end; +} +procedure tobjectpicker.dokeypress(const sender: twidget; + var info: keyeventinfoty); +begin + case info.key of + key_escape: begin + if (fstate * [ops_moving,ops_rectselecting] <> []) then begin + fkeyeventinfopo:= @info; + try + endmoving(true); + if fselectobjects <> nil then begin + paintxorpic; + end; + include(info.eventstate,es_processed); + fintf.cancelpickmove(self); + finally + fkeyeventinfopo:= nil; + end; + end; + end; + end +end; + +procedure tobjectpicker.dokeydown(var ainfo: keyeventinfoty); +begin + case ainfo.key of + key_escape: begin + if (fstate * [ops_moving,ops_rectselecting] = []) and + (fselectobjects <> nil) and (ainfo.shiftstate*shiftstatesmask = []) then begin + removexorpic; + fselectobjects:= nil; + include(ainfo.eventstate,es_processed); + end; + end; + end; +end; + +function tobjectpicker.getpos: pointty; +begin + result:= addpoint(fpickrect.pos,fpickoffset); +end; + +function tobjectpicker.getshiftstate: shiftstatesty; +begin + result:= []; + if fmouseeventinfopo <> nil then begin + result:= fmouseeventinfopo^.shiftstate; + end + else begin + if fkeyeventinfopo <> nil then begin + result:= fkeyeventinfopo^.shiftstate; + end + end; +end; + +procedure tobjectpicker.clear; +begin + fselectobjects:= nil; + fmouseoverobjects:= nil; +// exclude(fstate,ops_moving); +end; + +function tobjectpicker.hasselectobjects: boolean; +begin + result:= fselectobjects <> nil; +end; + +function tobjectpicker.hasmouseoverobjects: boolean; +begin + result:= fselectobjects <> nil; +end; + +function tobjectpicker.picking: boolean; +begin + result:= ops_picking in fstate; +end; + +function tobjectpicker.rectselecting: boolean; +begin + result:= ops_rectselecting in fstate; +end; + +function tobjectpicker.multiselecting: boolean; +begin + result:= ops_multiselecting in fstate; +end; + +function tobjectpicker.moving: boolean; +begin + result:= ops_moving in fstate; +end; + +function tobjectpicker.active: boolean; +begin + result:= fstate*activestates <> []; +end; + +function tobjectpicker.getcurrentobjects: integerarty; +//var +// int1: integer; +begin +{ + if ops_multiselecting in fstate then begin + result:= fselectobjects; + for int1:= 0 to high(fmouseoverobjects) do begin + if finditem(result,fmouseoverobjects[int1]) < 0 then begin + additem(result,fmouseoverobjects[int1]); + end; + end; + end + else begin +} + if (fselectobjects <> nil) or (ops_multiselecting in fstate) then begin + result:= fselectobjects; + end + else begin + result:= fmouseoverobjects; + end; +// end; +end; + +function tobjectpicker.getthumbtrack: boolean; +begin + result:= opo_thumbtrack in foptions; +end; + +procedure tobjectpicker.setthumbtrack(const avalue: boolean); +begin + if avalue then begin + include(foptions,opo_thumbtrack); + end + else begin + exclude(foptions,opo_thumbtrack); + end; +end; + +function tobjectpicker.hascurrentobjects: boolean; +begin + result:= getcurrentobjects <> nil; +end; + +procedure tobjectpicker.dobeforepaint(const acanvas: tcanvas); +var + int1: integer; +begin + if ops_xorpicpainted in fstate then begin + include(fstate,ops_xorpicremoved); + int1:= acanvas.save; + if not (forigin = org_widget) then begin //todo org_screen + acanvas.intersectcliprect(fintf.getwidget.clientrect); + acanvas.move(fintf.getwidget.clientwidgetpos); + end; + initxorcanvas(acanvas); + dopaint(acanvas); + exclude(fstate,ops_xorpicpainted); + acanvas.restore(int1); + end; +end; + +procedure tobjectpicker.doafterpaint(const acanvas: tcanvas); +var + int1: integer; +begin + if ops_xorpicremoved in fstate then begin + exclude(fstate,ops_xorpicremoved); + int1:= acanvas.save; + if not (forigin = org_widget) then begin //todo org_screen + acanvas.intersectcliprect(fintf.getwidget.clientrect); + acanvas.move(fintf.getwidget.clientwidgetpos); + end; + initxorcanvas(acanvas); + dopaint(acanvas); + include(fstate,ops_xorpicpainted); + acanvas.restore(int1); + end; +end; + +{ thintcontroller } + +constructor thintcontroller.create(const intf: ihintcontroller); +begin + fintf:= intf; +end; + +procedure thintcontroller.mouseevent(var info: mouseeventinfoty); +begin + +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/msepickwidget.pas b/mseide-msegui/lib/common/widgets/msepickwidget.pas new file mode 100644 index 0000000..408ae7e --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msepickwidget.pas @@ -0,0 +1,191 @@ +{ MSEgui Copyright (c) 2008-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msepickwidget; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,mseclasses,msesimplewidgets,mseobjectpicker,msegraphutils, + msegui,mseguiglob,msepointer,msetypes,msegraphics,mseevent,msemenus; + +// todo: +// select rect + +type + tcustompickwidget = class; + + getcursorshapeeventty = + procedure (const sender: tcustompickwidget; const picker: tobjectpicker; + var shape: cursorshapety; var found: boolean) of object; + getpickobjectseventty = procedure (const sender: tcustompickwidget; + const picker: tobjectpicker; + var objects: integerarty) of object; + pickmoveeventty = procedure(const sender: tcustompickwidget; + const picker: tobjectpicker) of object; + paintxorpiceventty = procedure(const sender: tcustompickwidget; + const picker: tobjectpicker; + const canvas: tcanvas) of object; + + tcustompickwidget = class(teventwidget,iobjectpicker) + private + fobjectpicker: tobjectpicker; + fongetcursorshape: getcursorshapeeventty; + fongetpickobjects: getpickobjectseventty; + fonbeginpickmove: pickmoveeventty; + fonpickthumbtrack: pickmoveeventty; + fonendpickmove: pickmoveeventty; + fonpaintxorpic: paintxorpiceventty; + foncancelpickmove: pickmoveeventty; + function getoptions: objectpickeroptionsty; + procedure setoptions(const avalue: objectpickeroptionsty); + protected + procedure clientmouseevent(var info: mouseeventinfoty); override; + procedure dokeydown(var ainfo: keyeventinfoty); override; + //iobjectpicker + function getcursorshape(const sender: tobjectpicker; + var shape: cursorshapety): boolean; + procedure getpickobjects(const sender: tobjectpicker; + var objects: integerarty); + procedure beginpickmove(const sender: tobjectpicker); + procedure pickthumbtrack(const sender: tobjectpicker); + procedure endpickmove(const sender: tobjectpicker); + procedure cancelpickmove(const sender: tobjectpicker); + procedure paintxorpic(const sender: tobjectpicker; const canvas: tcanvas); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property options: objectpickeroptionsty read getoptions + write setoptions default []; + property ongetcursorshape: getcursorshapeeventty read fongetcursorshape + write fongetcursorshape; + property ongetpickobjects: getpickobjectseventty read fongetpickobjects + write fongetpickobjects; + property onbeginpickmove: pickmoveeventty read fonbeginpickmove + write fonbeginpickmove; + property onpickthumbtrack: pickmoveeventty read fonpickthumbtrack + write fonpickthumbtrack; + property onendpickmove: pickmoveeventty read fonendpickmove + write fonendpickmove; + property oncancelpickmove: pickmoveeventty read foncancelpickmove + write foncancelpickmove; + property onpaintxorpic: paintxorpiceventty read fonpaintxorpic + write fonpaintxorpic; + end; + + tpickwidget = class(tcustompickwidget) + published + property options; + property ongetcursorshape; + property ongetpickobjects; + property onbeginpickmove; + property onendpickmove; + property onpaintxorpic; + end; + +implementation + +{ tcustompickpickwidget } + +constructor tcustompickwidget.create(aowner: tcomponent); +begin + fobjectpicker:= tobjectpicker.create(iobjectpicker(self)); + inherited; +end; + +destructor tcustompickwidget.destroy; +begin + inherited; + fobjectpicker.free; +end; + +function tcustompickwidget.getoptions: objectpickeroptionsty; +begin + result:= fobjectpicker.options; +end; + +procedure tcustompickwidget.setoptions(const avalue: objectpickeroptionsty); +begin + fobjectpicker.options:= avalue; +end; + +function tcustompickwidget.getcursorshape(const sender: tobjectpicker; + var shape: cursorshapety): boolean; +var + bo1: boolean; +begin + bo1:= false; + if canevent(tmethod(fongetcursorshape)) then begin + fongetcursorshape(self,sender,shape,bo1); + end; + result:= bo1; +end; + +procedure tcustompickwidget.getpickobjects(const sender: tobjectpicker; + var objects: integerarty); +begin + if canevent(tmethod(fongetpickobjects)) then begin + fongetpickobjects(self,sender,objects); + end; +end; + +procedure tcustompickwidget.beginpickmove(const sender: tobjectpicker); +begin + if canevent(tmethod(fonbeginpickmove)) then begin + fonbeginpickmove(self,sender); + end; +end; + +procedure tcustompickwidget.pickthumbtrack(const sender: tobjectpicker); +begin + if canevent(tmethod(fonpickthumbtrack)) then begin + fonpickthumbtrack(self,sender); + end; +end; + +procedure tcustompickwidget.endpickmove(const sender: tobjectpicker); +begin + if canevent(tmethod(fonendpickmove)) then begin + fonendpickmove(self,sender); + end; +end; + +procedure tcustompickwidget.cancelpickmove(const sender: tobjectpicker); +begin + if canevent(tmethod(foncancelpickmove)) then begin + foncancelpickmove(self,sender); + end; +end; + +procedure tcustompickwidget.paintxorpic(const sender: tobjectpicker; + const canvas: tcanvas); +begin + if canevent(tmethod(fonpaintxorpic)) then begin + fonpaintxorpic(self,sender,canvas); + end; +end; + +procedure tcustompickwidget.clientmouseevent(var info: mouseeventinfoty); +begin + fobjectpicker.mouseevent(info); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +procedure tcustompickwidget.dokeydown(var ainfo: keyeventinfoty); +begin + if not (es_processed in ainfo.eventstate) then begin + inherited; + end; + if not (es_processed in ainfo.eventstate) then begin + fobjectpicker.dokeydown(ainfo); + end; +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/msepolygon.pas b/mseide-msegui/lib/common/widgets/msepolygon.pas new file mode 100644 index 0000000..fc3fcd1 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msepolygon.pas @@ -0,0 +1,648 @@ +{ MSEgui Copyright (c) 2008-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msepolygon; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +uses + msegui,mseguiglob,msewidgets,msegraphutils,msegraphics,classes,mclasses, + msetypes,msebitmap,msesimplewidgets,msemenus,mseevent; + +type + polygonstatety = (pos_geometryvalid); + polygonstatesty = set of polygonstatety; + + polygoninfoty = record + dim: rectty; + ppmm: real; + edgecount: integer; + edgeradiusmm: real; + edgeradiusvertexcount: integer; + rotation: real; + vertex: pointarty; + color: colorty; + colorline: colorty; + colorlinegap: colorty; + dashes: ansistring; + linewidthmm: real; + joinstyle: joinstylety; + brush: tmaskedbitmap; + brushoffset: pointty; + smooth: boolean; + end; + + projvectty = array[0..1] of real; + projmatrixty = array[0..2] of projvectty; //[row][col] + + tpolygon = class(tpaintbox) + private + finfo: polygoninfoty; + procedure setpoly_edgecount(const avalue: integer); + procedure setpoly_edgeradiusmm(const avalue: real); + procedure setpoly_edgeradiusvertexcount(const avalue: integer); + procedure setpoly_color(const avalue: colorty); + procedure setpoly_colorline(const avalue: colorty); + procedure setpoly_colorlinegap(const avalue: colorty); + procedure setpoly_dashes(const avalue: ansistring); + procedure setpoly_rotation(const avalue: real); + procedure setpoly_linewidthmm(const avalue: real); + procedure setpoly_joinstyle(const avalue: joinstylety); + procedure setpoly_brush(const avalue: tmaskedbitmap); + procedure setpoly_brushoffset_x(const avalue: integer); + procedure setpoly_brushoffset_y(const avalue: integer); + procedure setpolysmooth(const avalue: boolean); + protected + fstate: polygonstatesty; + procedure change; + procedure dopaintforeground(const canvas: tcanvas); override; + procedure checkgeometry(const appmm: real); + procedure clientrectchanged; override; + procedure bitmapchanged(const sender: tobject); + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + published + property poly_edgecount: integer read finfo.edgecount + write setpoly_edgecount default 0; + //0 -> circle + property poly_edgeradiusmm: real read finfo.edgeradiusmm + write setpoly_edgeradiusmm; + property poly_edgeradiusvertexcount: integer read finfo.edgeradiusvertexcount + write setpoly_edgeradiusvertexcount default 2; + property poly_rotation: real read finfo.rotation write setpoly_rotation; + //0..1 -> 0..360° CCW + property poly_color: colorty read finfo.color write setpoly_color + default cl_white; + property poly_colorline: colorty read finfo.colorline write setpoly_colorline + default cl_black; + property poly_colorlinegap: colorty read finfo.colorlinegap + write setpoly_colorlinegap default cl_transparent; + property poly_linewidthmm: real read finfo.linewidthmm + write setpoly_linewidthmm; + property poly_dashes: ansistring read finfo.dashes write setpoly_dashes; + property poly_joinstyle: joinstylety read finfo.joinstyle + write setpoly_joinstyle default js_miter; + property poly_brush: tmaskedbitmap read finfo.brush write setpoly_brush; + property poly_brushoffset_x: integer read finfo.brushoffset.x write + setpoly_brushoffset_x; + property poly_brushoffset_y: integer read finfo.brushoffset.y write + setpoly_brushoffset_y; + property poly_smooth: boolean read finfo.smooth + write setpolysmooth default false; + end; + +const + unityprojmatrix: projmatrixty = ((1,0),(0,1),(0,0)); + +function movepoint(const start: complexty; const angle: real; + const dist: real): complexty; +function angle(const start, stop: complexty): real; +function halfangle(a,b: real): real; +function arcangle(a,b: real): real; + +procedure projtranslate(var matrix: projmatrixty; const tx,ty: real); +procedure projscale(var matrix: projmatrixty; const sx,sy: real); +procedure projrotate(var matrix: projmatrixty; const angle: real); //radiant +procedure projconcat(const a,b: projmatrixty; out dest: projmatrixty); + +procedure project(const matrix: projmatrixty; var point: pointty); overload; +procedure project(const matrix: projmatrixty; var point: complexty); overload; +procedure project(const matrix: projmatrixty; var points: complexarty); overload; +procedure realtointpoints(const source: complexarty; out dest: pointarty); + +implementation +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + pi2 = 2*pi; + pid2 = pi/2; + pi3d2 = 3*pi/2; + +procedure realtointpoints(const source: complexarty; out dest: pointarty); +var + int1: integer; +begin + setlength(dest,length(source)); + for int1:= 0 to high(dest) do begin + dest[int1].x:= round(source[int1].re); + dest[int1].y:= round(source[int1].im); + end; +end; + +procedure project(const matrix: projmatrixty; var point: pointty); overload; +var + int1,int2: integer; +begin + int1:= round(matrix[0,0]*point.x + matrix[1,0]*point.y + matrix[2,0]); + int2:= round(matrix[0,1]*point.x + matrix[1,1]*point.y + matrix[2,1]); + point.x:= int1; + point.y:= int2; +end; + +procedure project(const matrix: projmatrixty; var point: complexty); overload; +var + rea1,rea2: real; +begin + rea1:= matrix[0,0]*point.re + matrix[1,0]*point.im + matrix[2,0]; + rea2:= matrix[0,1]*point.re + matrix[1,1]*point.im + matrix[2,1]; + point.re:= rea1; + point.im:= rea2; +end; + +procedure project(const matrix: projmatrixty; var points: complexarty); overload; +var + int1: integer; +begin + for int1:= 0 to high(points) do begin + project(matrix,points[int1]); + end; +end; + +procedure projtranslate(var matrix: projmatrixty; const tx,ty: real); +begin + if (tx <> 0) or (ty <> 0) then begin + matrix[2,0]:= matrix[2,0] + tx; + matrix[2,1]:= matrix[2,1] + ty; + end; +end; + +procedure projscale(var matrix: projmatrixty; const sx,sy: real); +var + ma: projmatrixty; +begin + if (sx <> 1) or (sy <> 1) then begin + ma[0,0]:= sx; + ma[0,1]:= 0; + ma[1,0]:= 0; + ma[1,1]:= sy; + ma[2,0]:= 0; + ma[2,1]:= 0; + projconcat(matrix,ma,matrix); + end; +end; + +procedure projrotate(var matrix: projmatrixty; const angle: real); +var + si,co: real; + ma: projmatrixty; +begin + if angle <> 0 then begin + si:= sin(angle); + co:= cos(angle); + ma[0,0]:= co; + ma[0,1]:= -si; //for counterclockwise rotation of screeen coordinates + ma[1,0]:= si; + ma[1,1]:= co; + ma[2,0]:= 0; + ma[2,1]:= 0; + projconcat(matrix,ma,matrix); + end; +end; + +procedure projconcat(const a,b: projmatrixty; out dest: projmatrixty); +var + o00,o01, + o10,o11, + o20,o21: real; + +begin + o00:= a[0,0]*b[0,0] + a[0,1]*b[1,0] {+ a[0,2]*b[2,0]}; + o01:= a[0,0]*b[0,1] + a[0,1]*b[1,1] {+ a[0,2]*b[2,1]}; + o10:= a[1,0]*b[0,0] + a[1,1]*b[1,0] {+ a[1,2]*b[2,0]}; + o11:= a[1,0]*b[0,1] + a[1,1]*b[1,1] {+ a[1,2]*b[2,1]}; + o20:= a[2,0]*b[0,0] + a[2,1]*b[1,0] + {a[2,2]*}b[2,0]; + o21:= a[2,0]*b[0,1] + a[2,1]*b[1,1] + {a[2,2]*}b[2,1]; + dest[0,0]:= o00; + dest[0,1]:= o01; + dest[1,0]:= o10; + dest[1,1]:= o11; + dest[2,0]:= o20; + dest[2,1]:= o21; +end; + +function movepoint(const start: complexty; const angle: real; + const dist: real): complexty; +begin + result.re:= start.re + cos(angle) * dist; + result.im:= start.im + sin(angle) * dist; +end; + +function angle(const start, stop: complexty): real; +var + dx,dy: real; +begin + dx:= stop.re - start.re; + dy:= stop.im - start.im; + if abs(dx) > abs(dy) then begin + result:= arctan(dy/dx); + if dx < 0 then begin + result:= result + pi; + end; + end + else begin + result:= pid2 - arctan(dx/dy); + if dy < 0 then begin + result:= result + pi; + end; + end; + if result < 0 then begin + result:= result+pi2; + end; +end; + +procedure normalizeangle(var angle: real); +begin + angle:= angle-int(angle/pi2)*pi2; //0..2pi + if angle < 0 then begin + angle:= angle + pi2; + end; +end; + +procedure normalizeanglehalf(var angle: real); +begin + angle:= angle-int(angle/pi2)*pi2; //0..2pi + if angle > pi then begin + angle:= angle - pi2; + end; +end; + +function halfangle(a,b: real): real; +begin + normalizeangle(a); + normalizeangle(b); + result:= (a + b)/2; + if b < a then begin + result:= result - pi; + if result < 0 then begin + result:= result + pi2; + end; + end; +end; + +function arcangle(a,b: real): real; +begin + normalizeangle(a); + normalizeangle(b); + result:= b - a; + if result < 0 then begin + result:= result + pi2; + end; +end; + +procedure arc(const center: complexty; const radius: real; + const startang, endang: real; const vertexcount: integer; + const dest: pcomplexaty); +var + step: real; + int1: integer; + rea1: real; +begin + if vertexcount >= 2 then begin + step:= arcangle(startang,endang)/(vertexcount-1); + for int1:= 0 to vertexcount - 1 do begin + rea1:= int1*step + startang; + dest^[int1].re:= radius * cos(rea1) + center.re; + dest^[int1].im:= radius * sin(rea1) + center.im; + end; + end; +end; + +{ tpolygon } + +constructor tpolygon.create(aowner: tcomponent); +begin + with finfo do begin + color:= cl_white; + colorline:= cl_black; + colorlinegap:= cl_transparent; + joinstyle:= js_miter; + edgeradiusvertexcount:= 2; + brush:= tmaskedbitmap.create(bmk_rgb{false}); + brush.onchange:= {$ifdef FPC}@{$endif}bitmapchanged; + end; + inherited; +end; + +destructor tpolygon.destroy; +begin + inherited; + finfo.brush.free; +end; + +procedure tpolygon.change; +begin + exclude(fstate,pos_geometryvalid); + invalidate; +end; + +procedure tpolygon.dopaintforeground(const canvas: tcanvas); +var + rect1: rectty; +begin + inherited; + checkgeometry(canvas.ppmm); + with finfo do begin + canvas.save; + canvas.smooth:= smooth; + canvas.linewidthmm:= linewidthmm; + canvas.dashes:= dashes; + canvas.colorbackground:= colorlinegap; + canvas.joinstyle:= joinstyle; + if (color = cl_brush) and brush.hasimage then begin + canvas.brush:= brush.bitmap; + canvas.adjustbrushorigin(moverect(dim,brushoffset),brush.alignment); + end; + case edgecount of + 0: begin + rect1.pos:= vertex[0]; + rect1.size:= sizety(vertex[1]); + canvas.fillellipse(rect1,color,colorline); + end; + 1: begin + canvas.drawline(vertex[0],vertex[1],colorline); + end; + else begin + canvas.fillpolygon(vertex,color,colorline); + end; + end; + canvas.restore; + end; +end; + +procedure tpolygon.setpoly_edgecount(const avalue: integer); +begin + if finfo.edgecount <> avalue then begin + finfo.edgecount:= avalue; + change; + end; +end; + +procedure tpolygon.setpoly_edgeradiusmm(const avalue: real); +begin + if finfo.edgeradiusmm <> avalue then begin + finfo.edgeradiusmm:= avalue; + change; + end; +end; + +procedure tpolygon.setpoly_edgeradiusvertexcount(const avalue: integer); +begin + if finfo.edgeradiusvertexcount <> avalue then begin + finfo.edgeradiusvertexcount:= avalue; + change; + end; +end; + +procedure tpolygon.setpoly_color(const avalue: colorty); +begin + if avalue <> finfo.color then begin + finfo.color:= avalue; + invalidate; + end; +end; + +procedure tpolygon.setpoly_colorline(const avalue: colorty); +begin + if avalue <> finfo.colorline then begin + finfo.colorline:= avalue; + invalidate; + end; +end; + +procedure tpolygon.setpoly_colorlinegap(const avalue: colorty); +begin + if avalue <> finfo.colorlinegap then begin + finfo.colorlinegap:= avalue; + invalidate; + end; +end; + +procedure tpolygon.setpoly_dashes(const avalue: ansistring); +begin + finfo.dashes:= avalue; + invalidate; +end; + +procedure tpolygon.setpoly_linewidthmm(const avalue: real); +begin + if avalue <> finfo.linewidthmm then begin + finfo.linewidthmm:= avalue; + change; + end; +end; + +procedure tpolygon.setpoly_joinstyle(const avalue: joinstylety); +begin + if avalue <> finfo.joinstyle then begin + finfo.joinstyle:= avalue; + invalidate; + end; +end; + +procedure tpolygon.setpoly_rotation(const avalue: real); +begin + if finfo.rotation <> avalue then begin + finfo.rotation:= avalue; + change; + end; +end; + +procedure tpolygon.checkgeometry(const appmm: real); +var +// rect1: rectty; + ar1,ar2: complexarty; + rea1,rea2,rea3: real; + int1,int2: integer; + ma: projmatrixty; + minx,miny,maxx,maxy: real; + si,co: real; + ptpo1,ptpo2,ptpo3: pcomplexty; + ang1,ang2: real; + pt1: complexty; + +begin + if not (pos_geometryvalid in fstate) or (finfo.ppmm <> appmm) then begin + include(fstate,pos_geometryvalid); + with finfo do begin + dim:= innerclientrect; + ppmm:= appmm; + int1:= round(linewidthmm*appmm/2); + if int1 = 0 then begin + int1:= 1; + end; + int2:= 2*int1-1; + dec(dim.cx,int2); + dec(dim.cy,int2); + dec(int1); + inc(dim.x,int1); + inc(dim.y,int1); + case edgecount of + 0: begin + setlength(vertex,2); + with dim do begin + vertex[0].x:= x + cx div 2; //center + vertex[0].y:= y + cy div 2; + vertex[1].x:= cx; //size + vertex[1].y:= cy; + end; + end; + 1,2: begin + setlength(ar1,2); + si:= sin(rotation*pi2); + co:= cos(rotation*pi2); + if abs(si) > abs(co) then begin + rea1:= co/si; //cotan + ar1[0].re:= -1; + ar1[0].im:= -rea1; + ar1[1].re:= 1; + ar1[1].im:= rea1; + end + else begin + rea1:= si/co; //tan + ar1[0].re:= -rea1; + ar1[0].im:= -1; + ar1[1].re:= rea1; + ar1[1].im:= 1; + end; + ma:= unityprojmatrix; + projtranslate(ma,1,1); + projscale(ma,dim.cx/2,dim.cy/2); //scale to destination rect + projtranslate(ma,dim.x,dim.y); //move to destrect + project(ma,ar1); + realtointpoints(ar1,vertex); + end; + else begin + setlength(ar1,edgecount); + rea1:= 2*pi/(edgecount); + rea2:= (pid2+rea1/2); + for int1:= 0 to high(ar1) do begin + rea3:= int1*rea1+rea2; //edge at bottom + ar1[int1].im:= sin(rea3); + ar1[int1].re:= cos(rea3); + end; + ma:= unityprojmatrix; + projrotate(ma,rotation*pi2); + project(ma,ar1); + minx:= 0; + miny:= 0; + maxx:= 0; + maxy:= 0; + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + if re < minx then begin + minx:= re; + end; + if im < miny then begin + miny:= im; + end; + if re > maxx then begin + maxx:= re; + end; + if im > maxy then begin + maxy:= im; + end; + end; + end; + ma:= unityprojmatrix; + projtranslate(ma,-(minx+maxx)/2,-(miny+maxy)/2); //center polygon + projscale(ma,1/(maxx-minx),1/(maxy-miny)); //norm to 1 + projtranslate(ma,0.5,0.5); //move to first quadrant + projscale(ma,dim.cx,dim.cy); //scale to destination rect + projtranslate(ma,dim.x,dim.y); //move to destrect + project(ma,ar1); + if (edgeradiusmm <> 0) and (edgeradiusvertexcount >= 2) then begin + setlength(ar2,length(ar1)*edgeradiusvertexcount); + rea1:= edgeradiusmm*ppmm; //radius in pixel + for int1:= 0 to high(ar1) do begin + ptpo1:= @ar1[int1]; + ptpo2:= @ar1[(int1+1) mod edgecount]; + ptpo3:= @ar1[(int1+2) mod edgecount]; + ang1:= angle(ptpo2^,ptpo1^); + ang2:= angle(ptpo2^,ptpo3^); + rea2:= halfangle(ang2,ang1); //angle of center -> vertex, center -> tangent + rea3:= arcangle(ang2,ang1)/2; + pt1:= movepoint(ptpo2^,rea2,rea1/sin(rea3)); + arc(pt1,rea1,ang1+pid2,ang2-pid2,edgeradiusvertexcount, + @ar2[int1*edgeradiusvertexcount]); + //center of circle +// ar2[int1*2]:= movepoint(pt1,ang1+pid2,rea1); //tangent +// ar2[int1*2+1]:= movepoint(pt1,ang2-pid2,rea1); //tangent +// ar2[int1*2]:= ptpo2^; +// ar2[int1*2+1]:= ptpo2^; +// ar2[int1*2+1]:= pt1; + end; + end + else begin + ar2:= ar1; + end; + realtointpoints(ar2,vertex); + removeduplicatedpoints(vertex); + end; + end; + end; + end; +end; + +procedure tpolygon.clientrectchanged; +begin + change; + inherited; +end; + +procedure tpolygon.setpoly_brush(const avalue: tmaskedbitmap); +begin + finfo.brush.assign(avalue); +end; + +procedure tpolygon.bitmapchanged(const sender: tobject); +begin + invalidate; +end; + +procedure tpolygon.setpoly_brushoffset_x(const avalue: integer); +begin + if avalue <> finfo.brushoffset.x then begin + finfo.brushoffset.x:= avalue; + invalidate; + end; +end; + +procedure tpolygon.setpoly_brushoffset_y(const avalue: integer); +begin + if avalue <> finfo.brushoffset.y then begin + finfo.brushoffset.y:= avalue; + invalidate; + end; +end; + +procedure tpolygon.setpolysmooth(const avalue: boolean); +begin + if avalue <> finfo.smooth then begin + finfo.smooth:= avalue; + invalidate; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/msesimplewidgets.pas b/mseide-msegui/lib/common/widgets/msesimplewidgets.pas new file mode 100644 index 0000000..9955f52 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msesimplewidgets.pas @@ -0,0 +1,2828 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msesimplewidgets; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +uses + msegui,mseglob,mseguiglob,msetypes,msestrings,msegraphics,mseevent, + mseact,msewidgets, + mserichstring,mseshapes,classes,mclasses,mseclasses,msebitmap,msedrawtext, + msedrag,msestockobjects,msegraphutils,msemenus,msetimer; + +const + defaultbuttonwidth = 50; + defaultbuttonheight = 20; + defaultlabeltextflags = [tf_ycentered]; + defaultlabeloptionswidget = (defaultoptionswidget {+ + [ow_fontglyphheight]}) - + [ow_mousefocus,ow_tabfocus,ow_arrowfocus]; + defaultlabeloptionswidget1 = defaultoptionswidget1 + + [ow1_autowidth,ow1_autoheight,ow1_fontglyphheight]; + defaultlabelwidgetwidth = 100; + defaultlabelwidgetheight = 20; + + defaulticonoptionswidget = defaultoptionswidget - + [ow_mousefocus,ow_tabfocus,ow_arrowfocus]; + defaulticonoptionswidget1 = defaultoptionswidget1 + + [ow1_autowidth,ow1_autoheight]; + defaulticonwidgetwidth = 16; + defaulticonwidgetheight = 16; + +type + + teventwidget = class(tcustomeventwidget) + published + property onfocusedwidgetchanged; + property onenter; + property onexit; + property onfocus; + property ondefocus; + + property onmouseevent; + property onchildmouseevent; + property onclientmouseevent; + property onmousewheelevent; + + property onkeydown; + property onkeyup; + property onshortcut; + + property onloaded; + + property onbeforepaint; + property onpaintbackground; + property onpaint; + property onafterpaint; + + property onshow; + property onhide; + property onactivate; + property ondeactivate; + property onresize; + property onmove; + property onclosequery; + + property onasyncevent; + property oncomponentevent; + end; + + tcustombutton = class; + buttoneventty = procedure(const sender: tcustombutton) of object; + + tcustombutton = class(tactionsimplebutton,iactionlink,iimagelistinfo) + private + fmodalresult: modalresultty; + factioninfo: actioninfoty; + fautosize_cx: integer; + fautosize_cy: integer; + fonupdate: buttoneventty; + procedure setcaption(const Value: captionty); + function getframe: tframe; + procedure setframe(const Value: tframe); + function getcaption: captionty; + procedure setonexecute(const value: notifyeventty); + function isonexecutestored: boolean; + procedure setonbeforeexecute(const avalue: accepteventty); + function isonbeforeexecutestored: boolean; + procedure setonafterexecute(const value: notifyeventty); + function isonafterexecutestored: boolean; + procedure setaction(const value: tcustomaction); virtual; + function iscaptionstored: boolean; + function getstate: actionstatesty; + procedure setstate(const value: actionstatesty); virtual; + function isstatestored: boolean; + function getimagelist: timagelist; + procedure setimagelist(const Value: timagelist); + function isimageliststored: Boolean; + procedure setimagenr(const Value: imagenrty); + function isimagenrstored: boolean; + procedure setimagenrdisabled(const avalue: imagenrty); + function isimagenrdisabledstored: Boolean; + procedure setcolorglyph(const avalue: colorty); + function iscolorglyphstored: boolean; + procedure setimagepos(const avalue: imageposty); + procedure setcaptiondist(const avalue: integer); + procedure setautosize_cx(const avalue: integer); + procedure setautosize_cy(const avalue: integer); + procedure setimagedist(const avalue: integer); + procedure setimagedist1(const avalue: integer); + procedure setimagedist2(const avalue: integer); + procedure setshortcut(const avalue: shortcutty); + function isshortcutstored: boolean; + function getshortcut: shortcutty; + function getshortcut1: shortcutty; + procedure setshortcut1(const avalue: shortcutty); + function isshortcut1stored: boolean; + procedure readcaptionpos(reader: treader); + procedure settextflags(const avalue: textflagsty); + procedure setshortcuts(const avalue: shortcutarty); + procedure setshortcuts1(const avalue: shortcutarty); + procedure readshortcut(reader: treader); + procedure readshortcut1(reader: treader); + procedure readsc(reader: treader); + procedure writesc(writer: twriter); + procedure readsc1(reader: treader); + procedure writesc1(writer: twriter); + procedure setdisabled(const avalue: boolean); + function isenabledstored(): boolean; + protected + fexeccanceled: boolean; + function getdisabled(): boolean override; + procedure defineproperties(filer: tfiler); override; + procedure fontchanged; override; + procedure setcolor(const avalue: colorty); override; + procedure doidle(var again: boolean); + //iactionlink + function getactioninfopo: pactioninfoty; + function shortcutseparator: msechar; + procedure calccaptiontext(var ainfo: actioninfoty) virtual; + procedure actionchanged; + + procedure setoptions(const avalue: buttonoptionsty); override; + function gethint: msestring; override; + procedure sethint(const Value: msestring); override; + function ishintstored: boolean; override; + //iassistiveclient + function getassistivecaption(): msestring; override; + + procedure setenabled(const avalue: boolean); override; + procedure setvisible(const avalue: boolean); override; + procedure readstate(reader: treader); override; + procedure loaded; override; + procedure clientrectchanged; override; + procedure doexecute; override; + procedure doenter; override; + procedure doexit; override; + procedure dopaintforeground(const canvas: tcanvas); override; + function checkfocusshortcut(var info: keyeventinfoty): boolean; override; + procedure doshortcut(var info: keyeventinfoty; const sender: twidget); override; + procedure getautopaintsize(var asize: sizety); override; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + function verticalfontheightdelta: boolean; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure synctofontheight; override; + procedure doupdate; + procedure updatehotkeys() override; + + property bounds_cx default defaultbuttonwidth; + property bounds_cy default defaultbuttonheight; +// property frame: tframe read getframe write setframe; + property font: twidgetfont read getfont write setfont stored isfontstored; + property modalresult: modalresultty read fmodalresult write fmodalresult + default mr_none; + property action: tcustomaction read factioninfo.action write setaction; + property caption: captionty read getcaption write setcaption stored iscaptionstored; + property textflags: textflagsty read finfo.ca.textflags + write settextflags default defaultcaptiontextflags; + property imagepos: imageposty read finfo.ca.imagepos write setimagepos + default ip_center; + property captiondist: integer read finfo.ca.captiondist write setcaptiondist + default defaultshapecaptiondist; + property imagelist: timagelist read getimagelist write setimagelist + stored isimageliststored; + property imagenr: imagenrty read factioninfo.imagenr write setimagenr + stored isimagenrstored default -1; + property imagenrdisabled: imagenrty read factioninfo.imagenrdisabled + write setimagenrdisabled + stored isimagenrdisabledstored default -2; + + property imagedist: integer read finfo.ca.imagedist + write setimagedist default 0; + property imagedist1: integer read finfo.ca.imagedist1 + write setimagedist1 default 0; + property imagedist2: integer read finfo.ca.imagedist2 + write setimagedist2 default 0; + property colorglyph: colorty read factioninfo.colorglyph write setcolorglyph + stored iscolorglyphstored default cl_default; + property shortcut: shortcutty read getshortcut write setshortcut + stored false default 0; + property shortcut1: shortcutty read getshortcut1 write setshortcut1 + stored false default 0; + property shortcuts: shortcutarty read factioninfo.shortcut write setshortcuts; + property shortcuts1: shortcutarty read factioninfo.shortcut1 + write setshortcuts1; + property onupdate: buttoneventty read fonupdate write fonupdate; + property onexecute: notifyeventty read factioninfo.onexecute + write setonexecute stored isonexecutestored; + property onbeforeexecute: accepteventty read factioninfo.onbeforeexecute + write setonbeforeexecute stored isonbeforeexecutestored; + property onafterexecute: notifyeventty read factioninfo.onafterexecute + write setonafterexecute stored isonafterexecutestored; + property autosize_cx: integer read fautosize_cx + write setautosize_cx default 0; + property autosize_cy: integer read fautosize_cy + write setautosize_cy default 0; + property disabled: boolean read getdisabled write setdisabled; + //sets as_disabled + published + property options; //before state! + property visible stored false; + property enabled stored isenabledstored; + property state: actionstatesty read getstate write setstate + stored isstatestored default []; + end; + + tbutton = class(tcustombutton) + published + property autosize_cx; + property autosize_cy; + property action; + property caption; + property textflags; + property shortcut; + property shortcut1; + property imagepos; + property captiondist; + property font; + property modalresult; + property imagelist; + property imagenr; + property imagenrdisabled; + property imagedist; + property imagedist1; + property imagedist2; + property colorglyph; + property focusrectdist; + property onupdate; + property onexecute; + property onbeforeexecute; + property onafterexecute; + end; + + tstockglyphbutton = class(tcustombutton) + private + fglyph: stockglyphty; + procedure setglyph(const avalue: stockglyphty); + procedure setstate(const avalue: actionstatesty); override; + procedure setaction(const avalue: tcustomaction); override; + public + constructor create(aowner: tcomponent); override; + published + property glyph: stockglyphty read fglyph write setglyph default stg_none; + property autosize_cx; + property autosize_cy; + property action; + property caption; + property textflags; + property shortcut; + property shortcut1; + property imagepos; + property captiondist; + property font; + property modalresult; + property colorglyph; + property imagedist; + property imagedist1; + property imagedist2; + property options; + property focusrectdist; + property onupdate; + property onexecute; + property onbeforeexecute; + property onafterexecute; + end; + + tcustomrichbutton = class(tcustombutton,irichstringprop) + private + ffaceactive: tcustomface; + ffacedisabled: tcustomface; + ffacemouse: tcustomface; + ffaceclicked: tcustomface; + fimagenrmouse: imagenrty; + fimagenrclicked: imagenrty; + fcaptionrich: msestring; + function getfaceactive: tcustomface; + procedure setfaceactive(const avalue: tcustomface); + function getfacemouse: tcustomface; + procedure setfacemouse(const avalue: tcustomface); + function getfaceclicked: tcustomface; + procedure setfaceclicked(const avalue: tcustomface); + function getfacedisabled: tcustomface; + procedure setfacedisabled(const avalue: tcustomface); + procedure setimagenrmouse(const avalue: imagenrty); + procedure setimagenrclicked(const avalue: imagenrty); + procedure setcaptionrich(const avalue: msestring); + procedure setrichvalue(const avalue: richstringty); + function getrichvalue(): richstringty; + procedure readrichcaption(reader: treader); + procedure writerichcaption(writer: twriter); + protected + function getactface: tcustomface override; + procedure dopaintforeground(const canvas: tcanvas) override; + procedure objectchanged(const sender: tobject) override; + procedure richcaptionchanged(); + procedure calccaptiontext(var ainfo: actioninfoty) override; + procedure defineproperties(filer: tfiler) override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure createfaceactive; + procedure createfacedisabled; + procedure createfacemouse; + procedure createfaceclicked; + property faceactive: tcustomface read getfaceactive write setfaceactive; + property facemouse: tcustomface read getfacemouse write setfacemouse; + property faceclicked: tcustomface read getfaceclicked write setfaceclicked; + property facedisabled: tcustomface read getfacedisabled write setfacedisabled; + property imagenrmouse: imagenrty read fimagenrmouse + write setimagenrmouse default -1; + property imagenrclicked: imagenrty read fimagenrclicked + write setimagenrclicked default -1; + property captionrich: msestring read fcaptionrich + write setcaptionrich stored false; + property richcaption: richstringty read finfo.ca.caption write setrichvalue; + published + property onmouseevent; + property onbeforepaint; + property onpaintbackground; + property onpaint; + property onafterpaint; + end; + + trichbutton = class(tcustomrichbutton) + published + property faceactive; + property facemouse; + property faceclicked; + property facedisabled; + property onmouseevent; + property onclientmouseevent; + property onbeforepaint; + property onpaintbackground; + property onpaint; + property onafterpaint; + + property autosize_cx; + property autosize_cy; + property action; + property caption; + property captionrich; + property textflags; + property shortcut; + property shortcut1; + property imagepos; + property captiondist; + property font; + property modalresult; + property imagelist; + property imagenr; + property imagenrdisabled; + property imagenrmouse; + property imagenrclicked; + property imagedist; + property imagedist1; + property imagedist2; + property colorglyph; + property options; + property focusrectdist; + property onupdate; + property onexecute; + property onbeforeexecute; + property onafterexecute; + end; + + trichstockglyphbutton = class(tcustomrichbutton) + private + fglyph: stockglyphty; + procedure setglyph(const avalue: stockglyphty); + procedure setstate(const avalue: actionstatesty); override; + procedure setaction(const avalue: tcustomaction); override; + public + constructor create(aowner: tcomponent); override; + published + property glyph: stockglyphty read fglyph write setglyph default stg_none; + property faceactive; + property facemouse; + property faceclicked; + property facedisabled; + property onmouseevent; + property onclientmouseevent; + property onbeforepaint; + property onpaintbackground; + property onpaint; + property onafterpaint; + + property autosize_cx; + property autosize_cy; + property action; + property caption; + property captionrich; + property textflags; + property shortcut; + property shortcut1; + property imagepos; + property captiondist; + property font; + property modalresult; + property imagedist; + property imagedist1; + property imagedist2; + property colorglyph; + property options; + property focusrectdist; + property onupdate; + property onexecute; + property onbeforeexecute; + property onafterexecute; + end; + + labeloptionty = (lao_nogray,lao_nounderline); + labeloptionsty = set of labeloptionty; + +type + tcustomlabel = class(tpublishedwidget) + private + frichcaption: richstringty; + fcaption: msestring; + factualtextflags: textflagsty; + ftextflags: textflagsty; + foptions: labeloptionsty; + procedure setcaption(const avalue: msestring); +// function getcaption: msestring; + procedure updatetextflags; + procedure settextflags(const Value: textflagsty); + procedure setoptions(const avalue: labeloptionsty); + protected + procedure dopaintforeground(const canvas: tcanvas); override; + procedure enabledchanged; override; + procedure getautopaintsize(var asize: sizety); override; + procedure fontchanged; override; + procedure clientrectchanged; override; + function verticalfontheightdelta: boolean; override; + function checkfocusshortcut(var info: keyeventinfoty): boolean; override; + public + constructor create(aowner: tcomponent); override; + procedure synctofontheight; override; + procedure updatehotkeys() override; + procedure initnewcomponent(const ascale: real); override; + property caption: msestring read fcaption write setcaption; + property font: twidgetfont read getfont write setfont stored isfontstored; + property fontempty: twidgetfontempty read getfontempty + write setfontempty stored isfontemptystored; + property textflags: textflagsty read ftextflags write settextflags default + defaultlabeltextflags; + property options: labeloptionsty read foptions write setoptions default []; + published + property optionswidget default defaultlabeloptionswidget; + property optionswidget1 default defaultlabeloptionswidget1; + property bounds_cx default defaultlabelwidgetwidth; + property bounds_cy default defaultlabelwidgetheight; + end; + + tlabel = class(tcustomlabel) + published + property options; //first + property caption; + property font; + property textflags; + end; + + animationoptionty = (ano_singleshot,ano_designactive); + animationoptionsty = set of animationoptionty; + + tcustomicon = class(tpublishedwidget) + private + fimagelist: timagelist; + fimagenum: integer; + fcolorglyph: colorty; + fcolorbackground: colorty; + falignment: alignmentsty; + fopacity: colorty; + fimagesize: sizety; + fanim_intervalus: int32; + fanim_count: int32; + fanim_enabled: boolean; + fanim_options: animationoptionsty; + procedure setimagelist(const avalue: timagelist); + procedure setimagenum(const avalue: integer); + procedure setcolorglyph(const avalue: colorty); + procedure setcolorbackground(const avalue: colorty); + procedure setalignment(const avalue: alignmentsty); + procedure setopacity(const avalue: colorty); + procedure readtransparency(reader: treader); + procedure setanim_intervalus(const avalue: int32); + procedure setanim_count(const avalue: int32); + procedure setanim_enabled(const avalue: boolean); + procedure setanim_options(const avalue: animationoptionsty); + procedure setcurrentanimoffset(const avalue: int32); + protected + fanimimagenum: int32; + fcurrentanimoffset: int32; + ftimer: tsimpletimer; + procedure resetanim(); + procedure animtick(const sender: tobject); + procedure updateanim(); + procedure dopaintforeground(const canvas: tcanvas); override; + procedure enabledchanged; override; + procedure getautopaintsize(var asize: sizety); override; + procedure clientrectchanged; override; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + procedure defineproperties(filer: tfiler); override; + procedure loaded(); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy(); override; + property imagelist: timagelist read fimagelist write setimagelist; + property imagenum: integer read fimagenum write setimagenum default -1; + property colorglyph: colorty read fcolorglyph + write setcolorglyph default cl_default; + property colorbackground: colorty read fcolorbackground + write setcolorbackground default cl_default; + property opacity: colorty read fopacity + write setopacity default cl_default; + property alignment: alignmentsty read falignment + write setalignment default [al_xcentered,al_ycentered]; + property currentanimoffset: int32 read fcurrentanimoffset + write setcurrentanimoffset; + procedure animrestart(); + property anim_intervalus: int32 read fanim_intervalus + write setanim_intervalus default 0; + //micro seconds, 0 = animation off + property anim_count: int32 read fanim_count write setanim_count default 0; + //starts from imagenum, < 2 -> animation off + property anim_enabled: boolean read fanim_enabled write + setanim_enabled default false; + property anim_options: animationoptionsty read fanim_options write + setanim_options default []; + published + property optionswidget default defaulticonoptionswidget; + property optionswidget1 default defaulticonoptionswidget1; + property bounds_cx default defaulticonwidgetwidth; + property bounds_cy default defaulticonwidgetheight; + end; + + ticon = class(tcustomicon) + published + property imagelist; + property imagenum; + property colorglyph; + property colorbackground; + property opacity; + property alignment; + property anim_intervalus; + property anim_count; + property anim_enabled; + property anim_options; + end; + + tgroupboxframe = class(tcaptionframe) + public + constructor create(const aintf: icaptionframe); + published + property framei_left default 2; + property framei_top default 2; + property framei_right default 2; + property framei_bottom default 2; + property levelo default -1; + property leveli default 1; + property captiondist default 0; + property options + default defaultcaptionframeoptions + [cfo_captionframecentered]; + property captionoffset default 4; + end; + + optionscalety = (osc_expandx,osc_shrinkx,osc_expandy,osc_shrinky, + osc_invisishrinkx,osc_invisishrinky, + osc_expandshrinkx,osc_expandshrinky); + //expand minshrinksize to minscrollsize + optionsscalety = set of optionscalety; +const + defaultoptionsscale = [osc_expandshrinkx,osc_expandshrinky]; +type + tcustomscalingwidget = class(tpublishedwidget) + private + fonfontheightdelta: fontheightdeltaeventty; + fonlayout: notifyeventty; + fscaling: integer; + fonresize: notifyeventty; + fonmove: notifyeventty; + fsizebefore: sizety; + procedure setoptionsscale(const avalue: optionsscalety); + procedure readonchildscaled(reader: treader); + procedure settaborderoverride(const avalue: ttaborderoverride); + protected + foptionsscale: optionsscalety; + ftaborderoverride: ttaborderoverride; + procedure beginscaling; + procedure endscaling; + procedure updateoptionsscale(); + procedure dofontheightdelta(var delta: integer); override; + procedure widgetregionchanged(const sender: twidget); override; + procedure clientrectchanged; override; + procedure poschanged; override; + procedure sizechanged; override; + procedure loaded; override; + procedure visiblepropchanged; override; + function calcminshrinksize(): sizety; override; + function nexttaborderoverride(const sender: twidget; + const down: boolean): twidget override; + procedure defineproperties(filer: tfiler); override; + procedure readstate(reader: treader); override; + public + constructor create(aowner: tcomponent); override; + destructor destroy(); override; + procedure writestate(writer: twriter); override; + procedure dolayout(const sender: twidget); override; + property onresize: notifyeventty read fonresize write fonresize; + property onmove: notifyeventty read fonmove write fonmove; + published + property taborderoverride: ttaborderoverride read ftaborderoverride + write settaborderoverride; + property optionsscale: optionsscalety read foptionsscale write setoptionsscale + default defaultoptionsscale; + property onfontheightdelta: fontheightdeltaeventty read fonfontheightdelta + write fonfontheightdelta; + property onlayout: notifyeventty read fonlayout write fonlayout; + end; + + tscalingwidget = class(tcustomscalingwidget) + published + property font: twidgetfont read getfont write setfont stored isfontstored; + property optionsscale; + property onfontheightdelta; + property onlayout; + property onresize; + property onmove; + end; + +const + defaultgroupboxoptionswidget = (defaultoptionswidget + + [ow_arrowfocusin,ow_arrowfocusout,ow_parenttabfocus,ow_subfocus])- + [ow_mousefocus]; + +type + tgroupbox = class(tscalingwidget) + private + fonfocusedwidgetchanged: widgetchangeeventty; + protected + procedure internalcreateframe; override; + procedure dofocuschanged(const oldwidget,newwidget: twidget); override; + class function classskininfo: skininfoty; override; + public + constructor create(aowner: tcomponent); override; + procedure initnewcomponent(const ascale: real); override; + published + property optionswidget default defaultgroupboxoptionswidget; + property onfocusedwidgetchanged: widgetchangeeventty + read fonfocusedwidgetchanged write fonfocusedwidgetchanged; + end; + +const + defaultscrollboxoptionsscale = + defaultoptionsscale - [osc_expandshrinkx,osc_expandshrinky]; + defaultscrollboxoptionswidget = defaultoptionswidgetmousewheel + [ow_subfocus]; + +type + tscrollbox = class(tscalingwidget) + private + fonscroll: pointeventty; + fonscrolled: pointeventty; + function getframe: tscrollboxframe; + procedure setframe(const value: tscrollboxframe); + protected + procedure internalcreateframe; override; + procedure widgetregionchanged(const sender: twidget); override; + procedure mouseevent(var info: mouseeventinfoty); override; + procedure childmouseevent(const sender: twidget; + var info: mouseeventinfoty); override; + procedure domousewheelevent(var info: mousewheeleventinfoty); override; + procedure doscroll(const dist: pointty); override; + procedure doscrolled(const dist: pointty); override; +// procedure setclientpos(const avalue: pointty); + public + constructor create(aowner: tcomponent); override; + procedure clampinview(const arect: rectty; + const bottomright: boolean = false); override; + published + property frame: tscrollboxframe read getframe write setframe; + property onscroll: pointeventty read fonscroll write fonscroll; + property onscrolled: pointeventty read fonscrolled write fonscrolled; + property optionswidget default defaultscrollboxoptionswidget; + property optionsscale default defaultscrollboxoptionsscale; + end; + + tpaintbox = class(tscrollbox) + private + protected + published + property font: twidgetfont read getfont write setfont stored isfontstored; + property onbeforepaint; + property onpaintbackground; + property onpaint; + property onafterpaint; + + property onmouseevent; + property onchildmouseevent; + property onclientmouseevent; + property onmousewheelevent; + + property onkeydown; + property onkeyup; + property onshortcut; + + property onresize; + property onmove; + end; + + tstepboxframe = class(tcustomstepframe) + published + property levelo; + property leveli; + property framewidth; + property colorframe; + property colorframeactive; + property colorframedisabled; + property colorframemouse; + property colorframeclicked; + property colorframedefault; + property colordkshadow; + property colorshadow; + property colorlight; + property colorhighlight; + property colordkwidth; + property colorhlwidth; + property hiddenedges; + property colorclient; + property colorbutton; + property colorglyph; + property framei_left; + property framei_top; + property framei_right; + property framei_bottom; + property frameo_left; + property frameo_top; + property frameo_right; + property frameo_bottom; + + property frameimage_list; + property frameimage_left; + property frameimage_top; + property frameimage_right; + property frameimage_bottom; + property frameimage_offset; + property frameimage_offset1; + property frameimage_offsetdisabled; + property frameimage_offsetmouse; + property frameimage_offsetclicked; + property frameimage_offsetactive; + property frameimage_offsetfocused; +{ + property frameimage_offsetactivemouse; + property frameimage_offsetactiveclicked; +} + property frameface_list; + property frameface_offset; + property frameface_offset1; + property frameface_offsetdisabled; + property frameface_offsetmouse; + property frameface_offsetclicked; + property frameface_offsetactive; + property frameface_offsetfocused; +{ + property frameface_offsetactivemouse; + property frameface_offsetactiveclicked; +} + property optionsskin; + + property options; + property caption; + property captiontextflags; + property captionpos; + property captiondist; + property captionoffset; + property focusrectdist; + property extraspace; + property imagedist; + property imagedist1; + property imagedist2; + property font; + property buttonface; + property buttonframe; + property buttonsize; + property buttonpos; + property buttonslast; + property buttonsinline; + property buttonsinvisible; + property buttonsvisible; + property localprops; + property localprops1; //before template + property template; + end; + + tstepboxframe1 = class(tstepboxframe) + published + property mousewheel; + end; + + stepdirty = (sd_right,sd_up,sd_left,sd_down); + + stepeventty = procedure (const sender: tobject; const stepkind: stepkindty; + var handled: boolean) of object; + + tcustomstepbox = class(tpublishedwidget,istepbar,idragcontroller) + private + fonstep: stepeventty; + function getframe: tstepboxframe; + procedure setframe(const value: tstepboxframe); + protected + fdragcontroller: tdragcontroller; + procedure internalcreateframe; override; + procedure widgetregionchanged(const sender: twidget); override; + procedure clientmouseevent(var info: mouseeventinfoty); override; + procedure mouseevent(var info: mouseeventinfoty); override; + procedure mousewheelevent(var info: mousewheeleventinfoty); override; + function dostep(const event: stepkindty; const adelta: real; + ashiftstate: shiftstatesty): boolean; virtual; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property onstep: stepeventty read fonstep write fonstep; + published + property optionswidget default defaultoptionswidgetnofocus; + property frame: tstepboxframe read getframe write setframe; + end; + + tstepbox = class(tcustomstepbox) + published + property onstep; + end; + +implementation +uses + msekeyboard,sysutils,mseactions,msestreaming,mseassistiveserver; +type + tcustomframe1 = class(tcustomframe); + ttaborderoverride1 = class(ttaborderoverride); + +{ tcustombutton } + +constructor tcustombutton.create(aowner: tcomponent); +begin + initcaptioninfo(finfo.ca); + finfo.ca.imagepos:= ip_center; + initactioninfo(factioninfo); + inherited; + include(fwidgetstate1,ws1_nodesignframe); + size:= makesize(defaultbuttonwidth,defaultbuttonheight); +end; + +destructor tcustombutton.destroy; +begin + if bo_updateonidle in foptions then begin + application.unregisteronidle({$ifdef FPC}@{$endif}doidle); + end; + inherited; +end; + +procedure tcustombutton.setoptions(const avalue: buttonoptionsty); +var + delta: buttonoptionsty; +begin + if avalue <> foptions then begin + delta:= buttonoptionsty( + {$ifdef FPC}longword{$else}longword{$endif}(foptions) xor + {$ifdef FPC}longword{$else}longword{$endif}(avalue)); + if bo_updateonidle in delta then begin + if (bo_updateonidle in avalue) and + not (csdesigning in componentstate) then begin + application.registeronidle({$ifdef FPC}@{$endif}doidle); + end + else begin + application.unregisteronidle({$ifdef FPC}@{$endif}doidle); + end; + end; + end; + inherited; + if bo_shortcutcaption in avalue then begin + setactionoptions(iactionlink(self),factioninfo.options + [mao_shortcutcaption]); + end + else begin + setactionoptions(iactionlink(self),factioninfo.options - [mao_shortcutcaption]); + end; +end; + +function tcustombutton.verticalfontheightdelta: boolean; +begin + result:= tf_rotate90 in textflags; +end; + +procedure tcustombutton.updatehotkeys(); +begin + inherited; + calccaptiontext(factioninfo); +end; + +procedure tcustombutton.synctofontheight; +begin + inherited; + if tf_rotate90 in textflags then begin + bounds_cx:= font.glyphheight + innerclientframewidth.cx + 6; + end + else begin + bounds_cy:= font.glyphheight + innerclientframewidth.cy + 6; + end; +end; + +procedure tcustombutton.doexecute; +var + b1: boolean; +begin + if (fmodalresult <> mr_none) or + (options * [bo_nocandefocus,bo_candefocuswindow] <> [bo_candefocuswindow]) or + rootwidget.canparentclose then begin + fexeccanceled:= not doactionexecute1( + self,factioninfo,b1,false,(fmodalresult <> mr_none) or + (options * [bo_nocandefocus,bo_candefocuswindow] <> [])); + end + else begin + fexeccanceled:= true; + end; + if fmodalresult <> mr_none then begin + window.modalresult:= fmodalresult; + end; +end; + +procedure tcustombutton.dopaintforeground(const canvas: tcanvas); +begin + finfo.ca.font:= getfont; + inherited; +end; + +function tcustombutton.checkfocusshortcut(var info: keyeventinfoty): boolean; +begin + result:= inherited checkfocusshortcut(info) or + (bo_focusonshortcut in options) and + msegui.checkshortcut(info,factioninfo.captiontext, + bo_altshortcut in options) and canfocus; +end; + +procedure tcustombutton.doshortcut(var info: keyeventinfoty; const sender: twidget); +var + bo1,bo2: boolean; +begin + if not (es_processed in info.eventstate) and + not (csdesigning in componentstate) and + not (shs_disabled in finfo.state) then begin +{ + if checkfocusshortcut(info) then begin + setfocus(); + end; +} + bo1:= doactionshortcut(self,factioninfo,info); + if bo1 then begin + if (bo_focusonactionshortcut in foptions) and canfocus then begin + setfocus(); + end; + if fmodalresult <> mr_none then begin + window.modalresult:= fmodalresult; + end; + end; + if not bo1 and not (es_preview in info.eventstate) then begin +// bo2:= es_processed in info.eventstate; +// exclude(info.eventstate,es_processed); + bo2:= msegui.checkshortcut(info,factioninfo.captiontext, + bo_altshortcut in options); + exclude(info.eventstate,es_processed); + bo1:= (bo_executeonshortcut in options) and bo2 or + ((finfo.state * [shs_invisible,shs_disabled,shs_default] = [shs_default]) and + (info.key = key_return) and + ((info.shiftstate = []) or + (bo_executedefaultonenterkey in options) and + (info.shiftstate = [ss_second]))) and + not (aso_nodefaultbutton in assistiveoptions); + //no default button if assisted + if bo1 then begin + fexeccanceled:= false; + internalexecute(); + if not fexeccanceled then begin + if checkfocusshortcut(info) then begin + setfocus(); + end; + end; + include(info.eventstate,es_processed); + end; + end; + if not (es_processed in info.eventstate) then begin + inherited; + end; + end + else begin + inherited; + end; +end; + +function tcustombutton.getframe: tframe; +begin + result:= tframe(fframe); +end; + +procedure tcustombutton.setframe(const Value: tframe); +begin + fframe.Assign(value); +end; +{ +procedure tcustombutton.enabledchanged; +begin + inherited; + invalidate; +end; +} +procedure tcustombutton.actionchanged; +begin + finfo.color:= fcolor; + actioninfotoshapeinfo(self,factioninfo,finfo,foptions); + inherited setcolor(finfo.color); + finfo.color:= cl_transparent; +// if csdesigning in componentstate then begin + exclude(finfo.state,shs_invisible); +// end; + checkautosize; +end; + +procedure tcustombutton.readcaptionpos(reader: treader); +begin + imagepos:= readcaptiontoimagepos(reader); +end; + +procedure tcustombutton.readshortcut(reader: treader); +begin + shortcut:= translateshortcut(reader.readinteger); +end; + +procedure tcustombutton.readshortcut1(reader: treader); +begin + shortcut1:= translateshortcut(reader.readinteger); +end; + +procedure tcustombutton.readsc(reader: treader); +begin + shortcuts:= readshortcutarty(reader); +end; + +procedure tcustombutton.writesc(writer: twriter); +begin + writeshortcutarty(writer,factioninfo.shortcut); +end; + +procedure tcustombutton.readsc1(reader: treader); +begin + shortcuts1:= readshortcutarty(reader); +end; + +procedure tcustombutton.writesc1(writer: twriter); +begin + writeshortcutarty(writer,factioninfo.shortcut1); +end; + +procedure tcustombutton.setdisabled(const avalue: boolean); +begin + if avalue then begin + state:= state + [as_disabled]; + end + else begin + state:= state - [as_disabled]; + end; +end; + +function tcustombutton.isenabledstored(): boolean; +begin + result:= bo_noassistivedisabled in foptions; +end; + +procedure tcustombutton.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('captionpos', + {$ifdef FPC}@{$endif}readcaptionpos,nil,false); + filer.defineproperty('shortcut',{$ifdef FPC}@{$endif}readshortcut,nil,false); + filer.defineproperty('shortcut1',{$ifdef FPC}@{$endif}readshortcut1,nil,false); + filer.defineproperty('sc',{$ifdef FPC}@{$endif}readsc, + {$ifdef FPC}@{$endif}writesc, + isactionshortcutstored(factioninfo) and + ((filer.ancestor = nil) and (factioninfo.shortcut <> nil) or + ((filer.ancestor <> nil) and + not issameshortcut(factioninfo.shortcut, + tcustombutton(filer.ancestor).shortcuts)))); + filer.defineproperty('sc1',{$ifdef FPC}@{$endif}readsc1, + {$ifdef FPC}@{$endif}writesc1, + isactionshortcut1stored(factioninfo) and + ((filer.ancestor = nil) and (factioninfo.shortcut1 <> nil) or + ((filer.ancestor <> nil) and + not issameshortcut(factioninfo.shortcut, + tcustombutton(filer.ancestor).shortcuts)))); +end; + +procedure tcustombutton.fontchanged; +begin + inherited; + checkautosize; +end; + +procedure tcustombutton.setcolor(const avalue: colorty); +begin + if csloading in componentstate then begin + inherited; //no actionchanged + end; + setactioncolor(iactionlink(self),avalue); +end; + +function tcustombutton.getactioninfopo: pactioninfoty; +begin + result:= @factioninfo; +end; + +function tcustombutton.shortcutseparator: msechar; +begin + result:= ' '; +end; + +procedure tcustombutton.calccaptiontext(var ainfo: actioninfoty); +begin + mseactions.calccaptiontext(ainfo,shortcutseparator); +end; + +procedure tcustombutton.setaction(const value: tcustomaction); +begin + linktoaction(iactionlink(self),value,factioninfo); +end; + +procedure tcustombutton.setonexecute(const value: notifyeventty); +begin + setactiononexecute(iactionlink(self),value,csloading in componentstate); +end; + +function tcustombutton.isonexecutestored: boolean; +begin + result:= isactiononexecutestored(factioninfo); +end; + +procedure tcustombutton.setonbeforeexecute(const avalue: accepteventty); +begin + setactiononbeforeexecute(iactionlink(self),avalue,csloading in componentstate); +end; + +function tcustombutton.isonbeforeexecutestored: boolean; +begin + result:= isactiononbeforeexecutestored(factioninfo); +end; + +procedure tcustombutton.setonafterexecute(const value: notifyeventty); +begin + setactiononafterexecute(iactionlink(self),value,csloading in componentstate); +end; + +function tcustombutton.isonafterexecutestored: boolean; +begin + result:= isactiononafterexecutestored(factioninfo); +end; + +function tcustombutton.getcaption: captionty; +begin + result:= factioninfo.captiontext; +end; + +procedure tcustombutton.setcaption(const Value: captionty); +begin + setactioncaption(iactionlink(self),value); +end; + +function tcustombutton.iscaptionstored: boolean; +begin + result:= isactioncaptionstored(factioninfo); +end; + +function tcustombutton.getimagelist: timagelist; +begin + result:= timagelist(factioninfo.imagelist); +end; + +procedure tcustombutton.setimagelist(const Value: timagelist); +begin + setactionimagelist(iactionlink(self),Value); +end; + +function tcustombutton.isimageliststored: Boolean; +begin + result:= isactionimageliststored(factioninfo); +end; + +procedure tcustombutton.setimagenr(const Value: imagenrty); +begin + setactionimagenr(iactionlink(self),Value); +end; + +function tcustombutton.isimagenrstored: Boolean; +begin + result:= isactionimagenrstored(factioninfo); +end; + +procedure tcustombutton.setimagenrdisabled(const avalue: imagenrty); +begin + setactionimagenrdisabled(iactionlink(self),avalue); +end; + +function tcustombutton.isimagenrdisabledstored: Boolean; +begin + result:= isactionimagenrdisabledstored(factioninfo); +end; + +procedure tcustombutton.setcolorglyph(const avalue: colorty); +begin + setactioncolorglyph(iactionlink(self),avalue); +end; + +function tcustombutton.iscolorglyphstored: boolean; +begin + result:= isactioncolorglyphstored(factioninfo); +end; + +function tcustombutton.gethint: msestring; +begin + result:= factioninfo.hint; +end; + +procedure tcustombutton.sethint(const Value: msestring); +begin + setactionhint(iactionlink(self),value); +end; + +function tcustombutton.ishintstored: boolean; +begin + result:= isactionhintstored(factioninfo); +end; + +function tcustombutton.getassistivecaption(): msestring; +begin + result:= factioninfo.captiontext; + if result = '' then begin + result:= inherited getassistivecaption(); + end; +end; + +function tcustombutton.getdisabled(): boolean; +begin + result:= as_disabled in factioninfo.state; +end; + +procedure tcustombutton.setshortcut(const avalue: shortcutty); +begin + setactionshortcut(iactionlink(self),avalue); +end; + +function tcustombutton.isshortcutstored: boolean; +begin + result:= isactionshortcutstored(factioninfo); +end; + +function tcustombutton.getshortcut: shortcutty; +begin + result:= getsimpleshortcut(factioninfo); +end; + +function tcustombutton.getshortcut1: shortcutty; +begin + result:= getsimpleshortcut1(factioninfo); +end; + +procedure tcustombutton.setshortcut1(const avalue: shortcutty); +begin + setactionshortcut1(iactionlink(self),avalue); +end; + +function tcustombutton.isshortcut1stored: boolean; +begin + result:= isactionshortcut1stored(factioninfo); +end; + +function tcustombutton.getstate: actionstatesty; +begin + result:= factioninfo.state; +end; + +procedure tcustombutton.setstate(const value: actionstatesty); +begin + setactionstate(iactionlink(self),value); + visible:= not (as_invisible in factioninfo.state); + if (bo_noassistivedisabled in foptions){ and canassistive()} then begin + if not disabled then begin + enabled:= true; + end; + end + else begin + enabled:= not (as_disabled in factioninfo.state); + end; +end; + +procedure tcustombutton.setenabled(const avalue: boolean); +begin + if not isenabledstored then begin + if avalue then begin + setactionstate(iactionlink(self),state - [as_disabled]); + end + else begin + setactionstate(iactionlink(self),state + [as_disabled]); + end; + end; + inherited; +end; + +procedure tcustombutton.setvisible(const avalue: boolean); +begin + if avalue then begin + setactionstate(iactionlink(self),state - [as_invisible]); + end + else begin + setactionstate(iactionlink(self),state + [as_invisible]); + end; + inherited; +end; + +function tcustombutton.isstatestored: boolean; +begin + result:= isactionstatestored(factioninfo); +end; + +procedure tcustombutton.setimagepos(const avalue: imageposty); +begin + if avalue <> finfo.ca.imagepos then begin +// if avalue in [ip_left,ip_right,ip_top,ip_bottom, +// ip_leftcenter,ip_rightcenter, +// ip_topcenter,ip_bottomcenter] then begin + finfo.ca.imagepos:= avalue; +// end +// else begin +// finfo.ca.imagepos:= ip_center; +// end; + checkautosize; + invalidate; + end; +end; + +procedure tcustombutton.setcaptiondist(const avalue: integer); +begin + if avalue <> finfo.ca.captiondist then begin + finfo.ca.captiondist:= avalue; + checkautosize(); + end; +end; + +procedure tcustombutton.setimagedist(const avalue: integer); +begin + if avalue <> finfo.ca.imagedist then begin + finfo.ca.imagedist:= avalue; + checkautosize(); + end; +end; + +procedure tcustombutton.setimagedist1(const avalue: integer); +begin + if avalue <> finfo.ca.imagedist1 then begin + finfo.ca.imagedist1:= avalue; + checkautosize(); + end; +end; + +procedure tcustombutton.setimagedist2(const avalue: integer); +begin + if avalue <> finfo.ca.imagedist2 then begin + finfo.ca.imagedist2:= avalue; + checkautosize(); + end; +end; + +{ +procedure tcustombutton.setenabled(const Value: boolean); +begin + inherited; + if value then begin + state:= state -[ss_disabled]; + end + else begin + state:= state +[ss_disabled]; + end; +end; + +function tcustombutton.isenabledstored: Boolean; +begin + result:= isactionenabledstored(factioninfo); +end; + + +procedure tcustombutton.setvisible(const Value: boolean); +begin + inherited; + setactionvisible(iactionlink(self),value); +end; + +function tcustombutton.isvisiblestored: Boolean; +begin + result:= isactionvisiblestored(factioninfo); +end; +} +procedure tcustombutton.readstate(reader: treader); +begin + actionbeginload(iactionlink(self)); + inherited; +end; + +procedure tcustombutton.loaded; +begin + inherited; + actionendload(iactionlink(self)); +// actionchanged; +end; +{ +procedure tcustombutton.doidle; +begin + actiondoidle(factioninfo); + inherited; +end; +} +procedure tcustombutton.doenter; +var + int1: integer; + widget1: twidget; +begin + if fparentwidget <> nil then begin + for int1:= 0 to fparentwidget.widgetcount - 1 do begin + widget1:= fparentwidget.widgets[int1]; + if widget1 is tcustombutton then begin + with tcustombutton(widget1) do begin + if shs_default in finfo.state then begin + exclude(finfo.state,shs_default); + invalidateframestate(); + end; + end; + end; + end; + end; + inherited; +end; + +procedure tcustombutton.doexit; +var + int1: integer; + widget1: twidget; +begin + if fparentwidget <> nil then begin + for int1:= 0 to fparentwidget.widgetcount - 1 do begin + widget1:= fparentwidget.widgets[int1]; + if widget1 is tcustombutton then begin + with tcustombutton(widget1) do begin + if as_default in factioninfo.state then begin + if not (shs_default in finfo.state) then begin + include(finfo.state,shs_default); + invalidateframestate(); + end; + end; + end; + end; + end; + end; + inherited; +end; + +procedure tcustombutton.getautopaintsize(var asize: sizety); +begin + if fframe <> nil then begin + asize:= calccaptionsize(getcanvas,finfo.ca,@tcustomframe1(fframe).fi.innerframe); + end + else begin + asize:= calccaptionsize(getcanvas,finfo.ca,nil); + end; + inc(asize.cx,8+fautosize_cx); + inc(asize.cy,6+fautosize_cy); + if (fframe <> nil) then begin + if fso_flat in fframe.optionsskin then begin + dec(asize.cx,2); + dec(asize.cy,2); + end; + if fso_noanim in fframe.optionsskin then begin + dec(asize.cx,2); + dec(asize.cy,2); + end; + end; + if not (shs_noinnerrect in finfo.state) then begin + outertopaintsize(asize); +// innertopaintsize(asize); + end; + inherited; //check min/max size +end; + +procedure tcustombutton.clientrectchanged; +begin + inherited; + checkautosize; //for frame.framei +end; + +procedure tcustombutton.setautosize_cx(const avalue: integer); +begin + if fautosize_cx <> avalue then begin + fautosize_cx:= avalue; + checkautosize; + end; +end; + +procedure tcustombutton.setautosize_cy(const avalue: integer); +begin + if fautosize_cy <> avalue then begin + fautosize_cy:= avalue; + checkautosize; + end; +end; + +procedure tcustombutton.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if sender = finfo.ca.imagelist then begin + if (event = oe_changed) then begin + actionchanged; + end; + if (event = oe_destroyed) then begin + finfo.ca.imagelist:= nil; + end; + end; +end; + +procedure tcustombutton.settextflags(const avalue: textflagsty); +begin + if finfo.ca.textflags <> avalue then begin + finfo.ca.textflags:= checktextflags(finfo.ca.textflags,avalue); + invalidate; + checkautosize; + end; +end; + +procedure tcustombutton.setshortcuts(const avalue: shortcutarty); +begin + setactionshortcuts(iactionlink(self),avalue); +end; + +procedure tcustombutton.setshortcuts1(const avalue: shortcutarty); +begin + setactionshortcuts1(iactionlink(self),avalue); +end; + +procedure tcustombutton.doupdate; +begin + if factioninfo.action <> nil then begin + factioninfo.action.doupdate; + end; + if canevent(tmethod(fonupdate)) then begin + fonupdate(self); + end; +end; + +procedure tcustombutton.doidle(var again: boolean); +begin + doupdate; +end; + +{ tcustomrichbutton } + +constructor tcustomrichbutton.create(aowner: tcomponent); +begin + fimagenrmouse:= -1; + fimagenrclicked:= -1; + inherited; +end; + +destructor tcustomrichbutton.destroy; +begin + inherited; + ffaceactive.free; + ffacedisabled.free; + ffacemouse.free; + ffaceclicked.free; +end; + +procedure tcustomrichbutton.setimagenrmouse(const avalue: imagenrty); +begin + if fimagenrmouse <> avalue then begin + fimagenrmouse:= avalue; + invalidate; + end; +end; + +procedure tcustomrichbutton.setimagenrclicked(const avalue: imagenrty); +begin + if fimagenrclicked <> avalue then begin + fimagenrclicked:= avalue; + invalidate; + end; +end; + +procedure tcustomrichbutton.setcaptionrich(const avalue: msestring); +begin + fcaptionrich:= avalue; + factioninfo.caption1.text:= avalue; + if avalue = '' then begin + factioninfo.caption1.format:= nil; + end; + richcaptionchanged(); +end; + +procedure tcustomrichbutton.setrichvalue(const avalue: richstringty); +begin + factioninfo.caption1:= avalue; + fcaptionrich:= avalue.text; + richcaptionchanged(); +end; + +function tcustomrichbutton.getrichvalue(): richstringty; +begin + result:= factioninfo.caption1; +end; + +function tcustomrichbutton.getfaceactive: tcustomface; +begin + getoptionalobject(ffaceactive,{$ifdef FPC}@{$endif}createfaceactive); + result:= ffaceactive; +end; + +procedure tcustomrichbutton.setfaceactive(const avalue: tcustomface); +begin + setoptionalobject(avalue,ffaceactive,{$ifdef FPC}@{$endif}createfaceactive); + invalidate; +end; + +function tcustomrichbutton.getfacemouse: tcustomface; +begin + getoptionalobject(ffacemouse,{$ifdef FPC}@{$endif}createfacemouse); + result:= ffacemouse; +end; + +procedure tcustomrichbutton.setfacemouse(const avalue: tcustomface); +begin + setoptionalobject(avalue,ffacemouse,{$ifdef FPC}@{$endif}createfacemouse); + invalidate; +end; + +function tcustomrichbutton.getfaceclicked: tcustomface; +begin + getoptionalobject(ffaceclicked,{$ifdef FPC}@{$endif}createfaceclicked); + result:= ffaceclicked; +end; + +procedure tcustomrichbutton.setfaceclicked(const avalue: tcustomface); +begin + setoptionalobject(avalue,ffaceclicked,{$ifdef FPC}@{$endif}createfaceclicked); + invalidate; +end; + +function tcustomrichbutton.getfacedisabled: tcustomface; +begin + getoptionalobject(ffacedisabled,{$ifdef FPC}@{$endif}createfacedisabled); + result:= ffacedisabled; +end; + +procedure tcustomrichbutton.setfacedisabled(const avalue: tcustomface); +begin + setoptionalobject(avalue,ffacedisabled,{$ifdef FPC}@{$endif}createfacedisabled); + invalidate; +end; + + +procedure tcustomrichbutton.createfaceactive; +begin + ffaceactive:= tface.create(iface(self)); +end; + +procedure tcustomrichbutton.createfacedisabled; +begin + ffacedisabled:= tface.create(iface(self)); +end; + +procedure tcustomrichbutton.createfacemouse; +begin + ffacemouse:= tface.create(iface(self)); +end; + +procedure tcustomrichbutton.createfaceclicked; +begin + ffaceclicked:= tface.create(iface(self)); +end; + +function tcustomrichbutton.getactface: tcustomface; +begin + result:= inherited getactface; + if active then begin + if ffaceactive <> nil then begin + result:= ffaceactive; + end; + end + else begin + if not isenabled then begin + if ffacedisabled <> nil then begin + result:= ffacedisabled; + end; + end + else begin + if (shs_clicked in finfo.state) and (ffaceclicked <> nil) then begin + result:= ffaceclicked; + end + else begin + if (shs_mouse in finfo.state) and (ffacemouse <> nil) then begin + result:= ffacemouse; + end; + end; + end; + end; +end; + +procedure tcustomrichbutton.dopaintforeground(const canvas: tcanvas); +begin + finfo.ca.imagenr:= factioninfo.imagenr; + if shs_mouse in finfo.state then begin + if fimagenrmouse <> -1 then begin + finfo.ca.imagenr:= fimagenrmouse; + end; + end; + if shs_clicked in finfo.state then begin + if fimagenrclicked <> -1 then begin + finfo.ca.imagenr:= fimagenrclicked; + end; + end; + inherited; +end; + +procedure tcustomrichbutton.objectchanged(const sender: tobject); +begin + inherited; + if ffaceactive <> nil then begin + ffaceactive.checktemplate(sender); + end; + if ffacedisabled <> nil then begin + ffacedisabled.checktemplate(sender); + end; + if ffacemouse <> nil then begin + ffacemouse.checktemplate(sender); + end; + if ffaceclicked <> nil then begin + ffaceclicked.checktemplate(sender); + end; +end; + +procedure tcustomrichbutton.richcaptionchanged(); +begin + if not (csloading in componentstate) then begin + calccaptiontext(factioninfo); + actioninfotoshapeinfo(self,factioninfo,finfo,foptions); + invalidate(); + checkautosize(); + end; +end; + +procedure tcustomrichbutton.calccaptiontext(var ainfo: actioninfoty); +begin + if fcaptionrich = '' then begin //else don't display text of fcaption + inherited; + end; +end; + +procedure tcustomrichbutton.readrichcaption(reader: treader); +begin + richcaption:= readrichstring(reader); +end; + +procedure tcustomrichbutton.writerichcaption(writer: twriter); +begin + writerichstring(writer,finfo.ca.caption); +end; + +procedure tcustomrichbutton.defineproperties(filer: tfiler); +var + b1: boolean; +begin + inherited; + if filer.ancestor <> nil then begin + b1:= isequalrichstring( + tcustomrichbutton(filer.ancestor).factioninfo.caption1, + factioninfo.caption1); + end + else begin + b1:= not isemptyrichstring(factioninfo.caption1); + end; + filer.defineproperty('richcaption',@readrichcaption,@writerichcaption,b1); +end; + +{ +procedure tcustomrichbutton.dobeforepaint(const canvas: tcanvas); +begin + inherited; + if canevent(tmethod(fonbeforepaint)) then begin + fonbeforepaint(self,canvas); + end; +end; + +procedure tcustomrichbutton.dopaintbackground(const canvas: tcanvas); +begin + inherited; + if canevent(tmethod(fonpaintbackground)) then begin + fonpaintbackground(self,canvas); + end; +end; + +procedure tcustomrichbutton.doonpaint(const canvas: tcanvas); +begin + inherited; + if canevent(tmethod(fonpaint)) then begin + fonpaint(self,canvas); + end; +end; + +procedure tcustomrichbutton.doafterpaint(const canvas: tcanvas); +begin + inherited; + if canevent(tmethod(fonafterpaint)) then begin + fonafterpaint(self,canvas); + end; +end; + +procedure tcustomrichbutton.mouseevent(var info: mouseeventinfoty); +begin + if canevent(tmethod(fonmouseevent)) then begin + fonmouseevent(self,info); + end; + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; +} +{ tstockglyphbutton } + +constructor tstockglyphbutton.create(aowner: tcomponent); +begin + inherited; + imagelist:= stockobjects.glyphs; + glyph:= stg_none; +end; + +procedure tstockglyphbutton.setglyph(const avalue: stockglyphty); +begin + fglyph:= avalue; + imagenr:= ord(avalue); +end; + +procedure tstockglyphbutton.setstate(const avalue: actionstatesty); +begin + inherited setstate(avalue + [as_localimagelist,as_localimagenr]); +end; + +procedure tstockglyphbutton.setaction(const avalue: tcustomaction); +begin + inherited; + glyph:= glyph; + imagelist:= stockobjects.glyphs; +end; + +{ trichstockglyphbutton } + +constructor trichstockglyphbutton.create(aowner: tcomponent); +begin + inherited; + imagelist:= stockobjects.glyphs; + glyph:= stg_none; +end; + +procedure trichstockglyphbutton.setglyph(const avalue: stockglyphty); +begin + fglyph:= avalue; + imagenr:= ord(avalue); +end; + +procedure trichstockglyphbutton.setstate(const avalue: actionstatesty); +begin + inherited setstate(avalue + [as_localimagelist,as_localimagenr]); +end; + +procedure trichstockglyphbutton.setaction(const avalue: tcustomaction); +begin + inherited; + glyph:= glyph; + imagelist:= stockobjects.glyphs; +end; + +{ tcustomlabel } + +constructor tcustomlabel.create(aowner: tcomponent); +begin + ftextflags:= defaultlabeltextflags; + inherited; + foptionswidget:= defaultlabeloptionswidget; + foptionswidget1:= defaultlabeloptionswidget1; + fwidgetrect.cx:= defaultlabelwidgetwidth; + fwidgetrect.cy:= defaultlabelwidgetheight; +end; + +procedure tcustomlabel.dopaintforeground(const canvas: tcanvas); +begin + inherited; + drawtext(canvas,frichcaption,innerclientrect,factualtextflags,font); +end; +{ +function tcustomlabel.getcaption: msestring; +begin + if lao_nounderline in foptions then begin + result:= fcaption.text; + end + else begin + result:= richstringtocaption(fcaption); + end; +end; +} +procedure tcustomlabel.setcaption(const avalue: msestring); +begin + fcaption:= avalue; + if lao_nounderline in foptions then begin + frichcaption.text:= avalue; + end + else begin + captiontorichstring(avalue,frichcaption); + end; + checkautosize; + invalidate; +end; + +procedure tcustomlabel.updatehotkeys(); +begin + inherited; + setcaption(fcaption); +end; + +procedure tcustomlabel.settextflags(const Value: textflagsty); +begin + if ftextflags <> value then begin + ftextflags:= Value; + updatetextflags; + checkautosize; + invalidate; + end; +end; + +function tcustomlabel.verticalfontheightdelta: boolean; +begin + result:= tf_rotate90 in textflags +end; + +procedure tcustomlabel.synctofontheight; +begin + syncsinglelinefontheight; +end; + +procedure tcustomlabel.updatetextflags; +begin + if not (csloading in componentstate) then begin + if isenabled or (lao_nogray in foptions) then begin + factualtextflags:= ftextflags; + end + else begin + factualtextflags:= ftextflags + [tf_grayed]; + end; + end; +end; + +procedure tcustomlabel.enabledchanged; +begin + inherited; + updatetextflags; + invalidate; +end; + +procedure tcustomlabel.setoptions(const avalue: labeloptionsty); +var + opt1: labeloptionsty; +begin + if foptions <> avalue then begin + opt1:= foptions >< avalue; + foptions:= avalue; + updatetextflags; + invalidate; + if (lao_nounderline in opt1) and not(csreading in componentstate) then begin + if lao_nounderline in avalue then begin + frichcaption.text:= fcaption; + frichcaption.format:= nil; + end + else begin + captiontorichstring(fcaption,frichcaption); + end; + checkautosize(); + end; + end; +end; + +procedure tcustomlabel.getautopaintsize(var asize: sizety); +begin + asize:= textrect(getcanvas,frichcaption,innerclientrect,ftextflags).size; + innertopaintsize(asize); +end; + +procedure tcustomlabel.fontchanged; +begin + inherited; + checkautosize; +end; + +procedure tcustomlabel.clientrectchanged; +begin + inherited; + checkautosize; //for frame.framei +end; + +procedure tcustomlabel.initnewcomponent(const ascale: real); +begin + inherited; + caption:= msestring(name); +end; + +function tcustomlabel.checkfocusshortcut(var info: keyeventinfoty): boolean; +begin + result:= canfocus and checkshortcut(info,fcaption,true); +end; + +{ tcustomicon } + +constructor tcustomicon.create(aowner: tcomponent); +begin + fimagenum:= -1; + fcolorglyph:= cl_default; + fcolorbackground:= cl_default; + fopacity:= cl_default; + falignment:= [al_xcentered,al_ycentered]; + inherited; + foptionswidget:= defaulticonoptionswidget; + foptionswidget1:= defaulticonoptionswidget1; + fwidgetrect.cx:= defaulticonwidgetwidth; + fwidgetrect.cy:= defaulticonwidgetheight; +end; + +destructor tcustomicon.destroy; +begin + freeandnil(ftimer); + inherited; +end; + +procedure tcustomicon.setimagelist(const avalue: timagelist); +begin + if fimagelist <> avalue then begin + setlinkedvar(avalue,tmsecomponent(fimagelist)); + checkautosize; + invalidate; + end; +end; + +procedure tcustomicon.setimagenum(const avalue: integer); +begin + if fimagenum <> avalue then begin + fimagenum:= avalue; + invalidate; + end; +end; + +procedure tcustomicon.dopaintforeground(const canvas: tcanvas); +var + i1: int32; +begin + inherited; + if fimagelist <> nil then begin + i1:= fimagenum; + if ftimer <> nil then begin + i1:= i1 + fcurrentanimoffset; + end; + fimagelist.paint(canvas,i1,innerclientrect,falignment,fcolorglyph, + fcolorbackground,fopacity); + end; +end; + +procedure tcustomicon.enabledchanged; +begin + inherited; + invalidate; +end; + +procedure tcustomicon.getautopaintsize(var asize: sizety); +begin + inherited; + if fimagelist <> nil then begin + if frame <> nil then begin + with tcustomframe1(fframe) do begin + asize.cx:= fimagelist.width + fi.innerframe.left + fi.innerframe.right; + asize.cy:= fimagelist.height + fi.innerframe.top + fi.innerframe.bottom; + end; + end + else begin + asize:= fimagelist.size; + end; + end; +end; + +procedure tcustomicon.clientrectchanged; +begin + inherited; + checkautosize; //for framei +end; + +procedure tcustomicon.setcolorglyph(const avalue: colorty); +begin + if fcolorglyph <> avalue then begin + fcolorglyph:= avalue; + invalidate; + end; +end; + +procedure tcustomicon.setcolorbackground(const avalue: colorty); +begin + if fcolorbackground <> avalue then begin + fcolorbackground:= avalue; + invalidate; + end; +end; + +procedure tcustomicon.setopacity(const avalue: colorty); +begin + if fopacity <> avalue then begin + fopacity:= avalue; + invalidate; + end; +end; + +procedure tcustomicon.setalignment(const avalue: alignmentsty); +begin + if falignment <> avalue then begin + falignment:= avalue; + checkautosize; + invalidate; + end; +end; + +procedure tcustomicon.objectevent(const sender: tobject; + const event: objecteventty); +var + size1: sizety; +begin + inherited; + if (sender = fimagelist) and (event = oe_changed) then begin + size1:= fimagelist.size; + if (size1.cx <> fimagesize.cx) or (size1.cy <> fimagesize.cy) then begin + fimagesize:= size1; + checkautosize; + end; + invalidate; + end; +end; + +procedure tcustomicon.readtransparency(reader: treader); +begin + opacity:= transparencytoopacity(reader.readinteger); +end; + +procedure tcustomicon.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('transparency',@readtransparency,nil,false); +end; + +procedure tcustomicon.setanim_intervalus(const avalue: int32); +begin + if avalue <> fanim_intervalus then begin + fanim_intervalus:= avalue; + updateanim(); + end; +end; + +procedure tcustomicon.setanim_count(const avalue: int32); +begin + if avalue <> fanim_count then begin + fanim_count:= avalue; + updateanim(); + end; +end; + +procedure tcustomicon.setanim_enabled(const avalue: boolean); +begin + if avalue <> fanim_enabled then begin + fanim_enabled:= avalue; + updateanim(); + end; +end; + +procedure tcustomicon.setanim_options(const avalue: animationoptionsty); +begin + if avalue <> fanim_options then begin + fanim_options:= avalue; + updateanim(); + end; +end; + +procedure tcustomicon.animtick(const sender: tobject); +begin + inc(fcurrentanimoffset); + if fcurrentanimoffset >= fanim_count then begin + if ano_singleshot in fanim_options then begin + dec(fcurrentanimoffset); + if ftimer <> nil then begin + ftimer.enabled:= false; + end; + end + else begin + fcurrentanimoffset:= 0; + end; + end; + invalidate(); +end; + +procedure tcustomicon.resetanim(); +begin + fcurrentanimoffset:= -1; + animtick(nil); +end; + +procedure tcustomicon.setcurrentanimoffset(const avalue: int32); +begin + fcurrentanimoffset:= avalue; + invalidate(); +end; + +procedure tcustomicon.updateanim; +begin + if not (csloading in componentstate) then begin + if (fanim_intervalus > 0) and (fanim_count > 1) and + (not (csdesigning in componentstate) or + (ano_designactive in fanim_options)) then begin + if fanim_enabled then begin + if ftimer = nil then begin + resetanim(); + ftimer:= tsimpletimer.create(fanim_intervalus,@animtick,false); + end + else begin + ftimer.interval:= fanim_intervalus; + end; + if ano_singleshot in fanim_options then begin + resetanim(); + end; + ftimer.enabled:= true; + end + else begin + if ftimer <> nil then begin + ftimer.enabled:= false; + end; + end; + end + else begin + freeandnil(ftimer); + end; + end +end; + +procedure tcustomicon.loaded(); +begin + inherited; + updateanim(); +end; + +procedure tcustomicon.animrestart(); +begin + updateanim(); + resetanim(); +end; + +{ tgroupboxframe } + +constructor tgroupboxframe.create(const aintf: icaptionframe); +begin + inherited; + fi.levelo:= -1; + fi.leveli:= 1; + fi.innerframe.left:= 2; + fi.innerframe.top:= 2; + fi.innerframe.right:= 2; + fi.innerframe.bottom:= 2; + fcaptiondist:= 0; + fcaptionoffset:= 4; + include(foptions,cfo_captionframecentered); +end; + +{ tcustomscalingwidget } + +constructor tcustomscalingwidget.create(aowner: tcomponent); +begin + ftaborderoverride:= ttaborderoverride.create(self); + inherited; + foptionsscale:= defaultoptionsscale; +end; + +destructor tcustomscalingwidget.destroy(); +begin + inherited; + ftaborderoverride.free(); +end; + +procedure tcustomscalingwidget.dolayout(const sender: twidget); +begin + if canevent(tmethod(fonlayout)) then begin + fonlayout(self); + end + else begin + inherited; + end; +end; + +procedure tcustomscalingwidget.dofontheightdelta(var delta: integer); +begin + if canevent(tmethod(fonfontheightdelta)) then begin + fonfontheightdelta(self,delta); + end; + inherited; +end; + +procedure tcustomscalingwidget.setoptionsscale(const avalue: optionsscalety); +begin + if foptionsscale <> avalue then begin + foptionsscale:= avalue; + updateoptionsscale; + end; +end; + +procedure tcustomscalingwidget.updateoptionsscale(); +var + size1,size2: sizety; + rect1: rectty; + bo1: boolean; + box,boy: boolean; +begin + if foptionsscale * [osc_expandx,osc_expandy, + osc_shrinkx,osc_shrinky, + osc_invisishrinkx,osc_invisishrinky] <> [] then begin + if (componentstate * [csloading,csdestroying] = []) then begin + if fscaling <> 0 then begin + include(fwidgetstate1,ws1_scaled); + end + else begin + inc(fscaling); + try + exclude(fwidgetstate1,ws1_scaled); + size1:= calcminscrollsize; + bo1:= not isvisible; + size2:= paintsize; + box:= false; + boy:= false; + if (osc_invisishrinkx in foptionsscale) then begin + if bo1 then begin + if fsizebefore.cx = 0 then begin + fsizebefore.cx:= size2.cx; + end; + size1.cx:= paintsize.cx-bounds_cx; + end + else begin + if fsizebefore.cx <> 0 then begin + if foptionsscale * [osc_shrinkx,osc_expandx] <> + [osc_shrinkx,osc_expandx] then begin + size1.cx:= fsizebefore.cx; + end; + fsizebefore.cx:= 0; + box:= true; + end; + end; + end; + if (osc_invisishrinky in foptionsscale) then begin + if bo1 then begin + if fsizebefore.cy = 0 then begin + fsizebefore.cy:= size2.cy; + end; + size1.cy:= paintsize.cy-bounds_cy; + end + else begin + if fsizebefore.cy <> 0 then begin + if foptionsscale * [osc_shrinky,osc_expandy] <> + [osc_shrinky,osc_expandy] then begin + size1.cy:= fsizebefore.cy; + end; + fsizebefore.cy:= 0; + boy:= true; + end; + end; + end; + rect1.cx:= size1.cx - size2.cx; + rect1.cy:= size1.cy - size2.cy; + if not (bo1 and (osc_invisishrinkx in foptionsscale)) then begin + if not (osc_expandx in foptionsscale) and not box then begin + if rect1.cx > 0 then begin + rect1.cx:= 0; + end; + end; + if not (osc_shrinkx in foptionsscale) then begin + if rect1.cx < 0 then begin + rect1.cx:= 0; + end; + end; + end; + if not (bo1 and (osc_invisishrinky in foptionsscale)) then begin + if not (osc_expandy in foptionsscale) and not boy then begin + if rect1.cy > 0 then begin + rect1.cy:= 0; + end; + end; + if not (osc_shrinky in foptionsscale) then begin + if rect1.cy < 0 then begin + rect1.cy:= 0; + end; + end; + end; + rect1.pos:= fwidgetrect.pos; + if fanchors*[an_right,an_left] = [an_right] then begin + dec(rect1.x,rect1.cx); + end; + if fanchors*[an_bottom,an_top] = [an_bottom] then begin + dec(rect1.y,rect1.cy); + end; + addsize1(rect1.size,fwidgetrect.size); + internalsetwidgetrect(rect1,false); + if bo1 then begin + parentwidgetregionchanged(self); + end; + finally + dec(fscaling) + end; + end; + end; + end; +end; + +function tcustomscalingwidget.calcminshrinksize(): sizety; +var + size1: sizety; + box,boy: boolean; +begin + result:= inherited calcminshrinksize; + box:= (fanchors * [an_left,an_right] = [an_left,an_right]) and + (osc_expandshrinkx in foptionsscale) or + (osc_expandx in foptionsscale); + boy:= (fanchors * [an_top,an_bottom] = [an_top,an_bottom]) and + (osc_expandshrinky in foptionsscale) or + (osc_expandy in foptionsscale); + if box or boy then begin + size1:= minscrollsize; + addsize1(size1,framedim); + if box and (result.cx < size1.cx) then begin + result.cx:= size1.cx; + end; + if boy and (result.cy < size1.cy) then begin + result.cy:= size1.cy; + end; + end; +end; + +function tcustomscalingwidget.nexttaborderoverride(const sender: twidget; + const down: boolean): twidget; +begin + result:= ftaborderoverride.nexttaborder(sender,down); + if result = nil then begin + result:= inherited nexttaborderoverride(sender,down); + end; +end; + +procedure tcustomscalingwidget.beginscaling; +begin + if fscaling = 0 then begin + exclude(fwidgetstate1,ws1_scaled); + end; + inc(fscaling); +end; + +procedure tcustomscalingwidget.endscaling; +begin + dec(fscaling); + if (fscaling = 0) and (ws1_scaled in fwidgetstate1) then begin + updateoptionsscale; + end; +end; + +procedure tcustomscalingwidget.widgetregionchanged(const sender: twidget); +begin + inherited; + if not (ws_loadlock in fwidgetstate) then begin + updateoptionsscale; + end; +end; + +procedure tcustomscalingwidget.clientrectchanged; +begin + inherited; + updateoptionsscale; +end; + +procedure tcustomscalingwidget.poschanged; +begin + inherited; + if canevent(tmethod(fonmove)) then begin + fonmove(self); + end; +end; + +procedure tcustomscalingwidget.sizechanged; +begin + inherited; + if canevent(tmethod(fonresize)) then begin + fonresize(self); + end; +end; + +procedure tcustomscalingwidget.visiblepropchanged; +begin + inherited; + if foptionsscale * [osc_invisishrinkx,osc_invisishrinky] <> [] then begin + updateoptionsscale; + end; +end; + +procedure tcustomscalingwidget.writestate(writer: twriter); +begin + if (fframe <> nil) and (fframe is tcustomscrollboxframe) then begin + tcustomscrollboxframe(fframe).showrect(nullrect,false); + end; + inherited; +end; + +procedure tcustomscalingwidget.readonchildscaled(reader: treader); +begin + onlayout:= notifyeventty(readmethod(reader)); +end; + +procedure tcustomscalingwidget.settaborderoverride( + const avalue: ttaborderoverride); +begin + ftaborderoverride.assign(avalue); +end; + +procedure tcustomscalingwidget.readstate(reader: treader); +begin + inherited; + ttaborderoverride1(ftaborderoverride).endread(reader); +end; + +procedure tcustomscalingwidget.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('onchildscaled', + {$ifdef FPC}@{$endif}readonchildscaled,nil,false); +end; + +procedure tcustomscalingwidget.loaded; +begin + inherited; + if canevent(tmethod(fonlayout)) then begin + postchildscaled; + end; +end; + +{ tgroupbox } + +constructor tgroupbox.create(aowner: tcomponent); +begin + inherited; + optionswidget:= defaultgroupboxoptionswidget; +end; + +procedure tgroupbox.initnewcomponent(const ascale: real); +begin + inherited; + internalcreateframe; + fframe.scale(ascale); +end; + +procedure tgroupbox.internalcreateframe; +begin + tgroupboxframe.create(iscrollframe(self)); +end; + +procedure tgroupbox.dofocuschanged(const oldwidget: twidget; + const newwidget: twidget); +begin + inherited; + if canevent(tmethod(fonfocusedwidgetchanged)) and + (checkdescendent(oldwidget) or checkdescendent(newwidget)) then begin + fonfocusedwidgetchanged(oldwidget,newwidget); + end; +end; + +class function tgroupbox.classskininfo: skininfoty; +begin + result:= inherited classskininfo; + result.objectkind:= sok_groupbox; +end; + +{ tscrollbox } + +constructor tscrollbox.create(aowner: tcomponent); +begin + inherited; + include(fwidgetstate1,ws1_designactive); + foptionswidget:= defaultoptionswidgetmousewheel; + foptionsscale:= defaultscrollboxoptionsscale; + internalcreateframe; +end; + +procedure tscrollbox.internalcreateframe; +begin + tscrollboxframe.create(iscrollframe(self),self); +end; + +function tscrollbox.getframe: tscrollboxframe; +begin + result:= tscrollboxframe(inherited getframe); +end; + +procedure tscrollbox.mouseevent(var info: mouseeventinfoty); +begin + inherited; + if not (es_processed in info .eventstate) then begin + tscrollboxframe(fframe).mouseevent(info); + end; +end; + +procedure tscrollbox.childmouseevent(const sender: twidget; + var info: mouseeventinfoty); +begin + frame.childmouseevent(sender,info); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +procedure tscrollbox.domousewheelevent(var info: mousewheeleventinfoty); +begin + tscrollboxframe(fframe).domousewheelevent(info,false); + inherited; +end; + +procedure tscrollbox.setframe(const value: tscrollboxframe); +begin + inherited setframe(value); +end; + +procedure tscrollbox.widgetregionchanged(const sender: twidget); +begin + inherited; + if not (ws_loadlock in fwidgetstate) and not (csdestroying in componentstate) then begin + tscrollboxframe(fframe).updateclientrect; + end; +end; + +procedure tscrollbox.doscroll(const dist: pointty); +begin + inherited; + if canevent(tmethod(fonscroll)) then begin + fonscroll(self,dist); + end; +end; + +procedure tscrollbox.doscrolled(const dist: pointty); +begin + inherited; + if canevent(tmethod(fonscrolled)) then begin + fonscrolled(self,dist); + end; +end; + +procedure tscrollbox.clampinview(const arect: rectty; const bottomright: boolean); +begin + frame.showrect(removerect(arect,clientpos),bottomright); +// frame.showrect(removerect(arect,clientwidgetpos)); +// frame.showrect(arect); +end; +{ +procedure tscrollbox.setclientpos(const avalue: pointty); +begin + tscrollboxframe(fframe).setclientpos(avalue); +end; +} +{ tcustomstepbox } + +constructor tcustomstepbox.create(aowner: tcomponent); +begin + inherited; + internalcreateframe; + if fdragcontroller = nil then begin + fdragcontroller:= tdragcontroller.create(idragcontroller(self)); + end; + optionswidget:= defaultoptionswidgetnofocus; +end; + +destructor tcustomstepbox.destroy; +begin + inherited; + fdragcontroller.Free; +end; + +procedure tcustomstepbox.internalcreateframe; +begin + tstepboxframe.create(iscrollframe(self),istepbar(self)); +end; + +procedure tcustomstepbox.clientmouseevent(var info: mouseeventinfoty); +begin + inherited; + if not (es_processed in info.eventstate) then begin + fdragcontroller.clientmouseevent(info); + end; +end; + +procedure tcustomstepbox.mouseevent(var info: mouseeventinfoty); +begin + tstepboxframe(fframe).mouseevent(info); + inherited; +end; + +function tcustomstepbox.getframe: tstepboxframe; +begin + result:= tstepboxframe(inherited getframe); +end; + +procedure tcustomstepbox.setframe(const value: tstepboxframe); +begin + inherited setframe(value); +end; + +procedure tcustomstepbox.widgetregionchanged(const sender: twidget); +begin + inherited; + tscrollboxframe(fframe).updateclientrect; +end; + +function tcustomstepbox.dostep(const event: stepkindty; + const adelta: real; ashiftstate: shiftstatesty): boolean; +begin + result:= false; + if canevent(tmethod(fonstep)) then begin + result:= true; + fonstep(self,event,result); + end; +end; + +procedure tcustomstepbox.mousewheelevent(var info: mousewheeleventinfoty); +begin + frame.domousewheelevent(info); + inherited; +end; + +{ tpaintbox } +{ +procedure tpaintbox.dobeforepaint(const canvas: tcanvas); +var + pt1: pointty; +begin + inherited; + if canevent(tmethod(fonbeforepaint)) then begin + pt1:= clientwidgetpos; + canvas.move(pt1); + fonbeforepaint(self,canvas); + canvas.remove(pt1); + end; +end; + +procedure tpaintbox.dopaintbackground(const canvas: tcanvas); +begin + inherited; + if canevent(tmethod(fonpaintbackground)) then begin + fonpaintbackground(self,canvas); + end; +end; + +procedure tpaintbox.doonpaint(const canvas: tcanvas); +begin + inherited; + if canevent(tmethod(fonpaint)) then begin + fonpaint(self,canvas); + end; +end; + +procedure tpaintbox.doafterpaint(const canvas: tcanvas); +var + pt1: pointty; +begin + inherited; + if canevent(tmethod(fonafterpaint)) then begin + pt1:= clientwidgetpos; + canvas.move(pt1); + fonafterpaint(self,canvas); + canvas.remove(pt1); + end; +end; +} +end. + diff --git a/mseide-msegui/lib/common/widgets/msesizingform.pas b/mseide-msegui/lib/common/widgets/msesizingform.pas new file mode 100644 index 0000000..2e040d5 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msesizingform.pas @@ -0,0 +1,219 @@ +{ MSEgui Copyright (c) 2016 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msesizingform; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseforms,mseclasses,mseobjectpicker,msegui,mseguiglob,msepointer,msetypes, + msegraphics,msegraphutils; + +type + tsizingform = class(tmseform,iobjectpicker) + private + foptionssizing: optionssizingty; + fobjectpicker: tobjectpicker; + procedure setoptionssizing(const avalue: optionssizingty); + protected + fpickedges: optionssizingty; + fpickedgesrect: rectty; + class function getmoduleclassname: string; override; + class function hasresource: boolean; override; + procedure mousepreview(const sender: twidget; + var info: mouseeventinfoty); override; + //iobjectpicker + function getcursorshape(const sender: tobjectpicker; + var ashape: cursorshapety): boolean; + //true if found + procedure getpickobjects(const sender: tobjectpicker; + var aobjects: integerarty); + procedure beginpickmove(const sender: tobjectpicker); + procedure pickthumbtrack(const sender: tobjectpicker); + procedure endpickmove(const sender: tobjectpicker); + procedure cancelpickmove(const sender: tobjectpicker); + procedure paintxorpic(const sender: tobjectpicker; const acanvas: tcanvas); + public + destructor destroy(); override; + published + property optionssizing: optionssizingty read foptionssizing + write setoptionssizing default []; + end; + + sizingformclassty = class of tsizingform; + +function createsizingform(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; + +implementation +uses + sysutils,mseevent; +type + tmsecomponent1 = class(tmsecomponent); + +function createsizingform(const aclass: tclass; + const aclassname: pshortstring): tmsecomponent; + +begin + result:= sizingformclassty(aclass).create(nil,false); + tmsecomponent1(result).factualclassname:= aclassname; +end; + +{ tsizingform } + +destructor tsizingform.destroy(); +begin + fobjectpicker.free; + inherited; +end; + +class function tsizingform.getmoduleclassname: string; +begin + result:= 'tsizingform'; +end; + +class function tsizingform.hasresource: boolean; +begin + result:= self <> tsizingform; +end; + +procedure tsizingform.setoptionssizing(const avalue: optionssizingty); +begin + foptionssizing:= avalue; + if avalue = [] then begin + freeandnil(fobjectpicker); + end + else begin + if fobjectpicker = nil then begin + fobjectpicker:= tobjectpicker.create(iobjectpicker(self),org_widget); + fobjectpicker.thumbtrack:= true; + end; + end; +end; + +procedure tsizingform.mousepreview(const sender: twidget; + var info: mouseeventinfoty); +begin + if (fobjectpicker <> nil) then begin + translatewidgetpoint1(info.pos,sender,self); + fobjectpicker.mouseevent(info); + translatewidgetpoint1(info.pos,self,sender); + if not (es_processed in info.eventstate) then begin + inherited; + end; + end + else begin + inherited; + end; +end; + +const + shapes: array[0..15] of cursorshapety = ( + cr_default, // , , , + cr_sizehor, //osi_left, , , + cr_sizever, // ,osi_top, , + cr_topleftcorner, //osi_left,osi_top, , + cr_sizehor, // , ,osi_right, + cr_default, //osi_left, ,osi_right, + cr_toprightcorner, // ,osi_top,osi_right, + cr_default, //osi_left,osi_top,osi_right, + cr_sizever, // , , ,osi_bottom + cr_bottomleftcorner, //osi_left, , ,osi_bottom + cr_default, // ,osi_top, ,osi_bottom + cr_default, //osi_left,osi_top, ,osi_bottom + cr_bottomrightcorner, // , ,osi_right,osi_bottom + cr_default, //osi_left, ,osi_right,osi_bottom + cr_default, // ,osi_top,osi_right,osi_bottom + cr_default //osi_left,osi_top,osi_right,osi_bottom + ); + +function tsizingform.getcursorshape(const sender: tobjectpicker; + var ashape: cursorshapety): boolean; +const + sitol = 2*sizingtol; +var + pt1: pointty; +begin + result:= false; + fpickedges:= []; + pt1:= sender.pickpos; + if (sender.shiftstate * keyshiftstatesmask = []) and + pointinrect(pt1,mr(nullpoint,size)) then begin + if pt1.x < sitol then begin + include(fpickedges,osi_left); + end; + if pt1.y < sitol then begin + include(fpickedges,osi_top); + end; + if pt1.x >= fwidgetrect.cx-sitol then begin + include(fpickedges,osi_right); + end; + if pt1.y >= fwidgetrect.cy-sitol then begin + include(fpickedges,osi_bottom); + end; + fpickedges:= fpickedges * foptionssizing; + result:= fpickedges <> []; + if result then begin + ashape:= shapes[int32(fpickedges)]; + end; + end; +end; + +procedure tsizingform.getpickobjects(const sender: tobjectpicker; + var aobjects: integerarty); +begin + if fpickedges <> [] then begin + setlength(aobjects,1); + end; +end; + +procedure tsizingform.beginpickmove(const sender: tobjectpicker); +begin + fpickedgesrect:= fwidgetrect; + //dummy +end; + +procedure tsizingform.pickthumbtrack(const sender: tobjectpicker); +var + rect1: rectty; +begin + rect1:= fpickedgesrect; + if osi_left in fpickedges then begin + rect1.x:= rect1.x + sender.pickoffset.x; + rect1.cx:= rect1.cx - sender.pickoffset.x; + end; + if osi_top in fpickedges then begin + rect1.y:= rect1.y + sender.pickoffset.y; + rect1.cy:= rect1.cy - sender.pickoffset.y; + end; + if osi_right in fpickedges then begin + rect1.cx:= rect1.cx + sender.pickoffset.x; + end; + if osi_top in fpickedges then begin + rect1.cy:= rect1.cy + sender.pickoffset.y; + end; + widgetrect:= rect1; +end; + +procedure tsizingform.endpickmove(const sender: tobjectpicker); +begin + //dummy +end; + +procedure tsizingform.cancelpickmove(const sender: tobjectpicker); +begin + widgetrect:= fpickedgesrect; +end; + +procedure tsizingform.paintxorpic(const sender: tobjectpicker; + const acanvas: tcanvas); +begin + //dummy +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/msesplitter.pas b/mseide-msegui/lib/common/widgets/msesplitter.pas new file mode 100644 index 0000000..77bb401 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msesplitter.pas @@ -0,0 +1,2602 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msesplitter; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + msegui,msewidgets,mseobjectpicker,classes,mclasses,msegraphutils, + msepointer,msetypes, + msestrings,msegraphics,mseevent,msestat,msestatfile,msestockobjects,mseclasses, + msesimplewidgets,mseguiglob,msemenus; +type + + splitteroptionty = (spo_hmove,spo_hprop,spo_hsizeprop, + spo_vmove,spo_vprop,spo_vsizeprop, + spo_dockleft,spo_docktop,spo_dockright,spo_dockbottom, + spo_hshrinkzero,spo_vshrinkzero, + spo_hrefstart,spo_vrefstart, + spo_thumbtrack); + splitteroptionsty = set of splitteroptionty; + +const + docksplitteroptions = [spo_dockleft,spo_docktop,spo_dockright,spo_dockbottom]; + defaultsplitteroptions = docksplitteroptions; + defaultsplittercolor = cl_light; + defaultsplittercolorgrip = cl_shadow; + defaultsplittergrip = stb_dens25; + updatepropeventtag = 0; + retrypropeventtag = 1; + +type + splitterstatety = (sps_propnotified); + splitterstatesty = set of splitterstatety; + + texpandingwidget = class(tscalingwidget) + public + constructor create(aowner: tcomponent); override; + published + property optionswidget default defaultgroupboxoptionswidget; + end; + + tcustomsplitter = class(tscalingwidget,iobjectpicker,istatfile) + private + fobjectpicker: tobjectpicker; + foptions: splitteroptionsty; + flinktop: twidget; + flinkleft: twidget; + flinkright: twidget; + flinkbottom: twidget; + fhprop,fvprop: real; + fhsizeprop,fvsizeprop: real; + fstatfile: tstatfile; + fstatvarname: msestring; + fcolorgrip: colorty; + fgrip: stockbitmapty; + fonupdatelayout: notifyeventty; + fupdating: integer; + fpropsetting: integer; +// fnotified: integer; + fregionchangedcount: integer; + fregionchangedmark: integer; + frefrect: rectty; + fshrinkpriority: integer; + fpropoffsetrecursion: integer; + fstatpriority: integer; + fwidgetrectbefore: rectty; + fdist_left: integer; + fdist_top: integer; + fdist_right: integer; + fdist_bottom: integer; + procedure setstatfile(const avalue: tstatfile); + procedure setlinkbottom(const avalue: twidget); + procedure setlinkleft(const avalue: twidget); + procedure setlinkright(const avalue: twidget); + procedure setlinktop(const avalue: twidget); + procedure setclippedpickoffset(const aoffset: pointty); + procedure setpickoffset(const aoffset: pointty); + procedure setcolorgrip(const avalue: colorty); + procedure setgrip(const avalue: stockbitmapty); + procedure setoptions(const avalue: splitteroptionsty); + procedure setdist_left(const avalue: integer); + procedure setdist_top(const avalue: integer); + procedure setdist_right(const avalue: integer); + procedure setdist_bottom(const avalue: integer); + protected + fstate: splitterstatesty; + procedure postupdatepropevent; + function clippoint(const aoffset: pointty): pointty; + procedure calcoffset(const refsize: sizety; + out offset,clippedoffset: pointty; out newsize: sizety); + procedure setpropoffset(const aoffset: pointty; const asize: sizety); +// function getminshrinkpos: pointty; override; + procedure mouseevent(var info: mouseeventinfoty); override; + procedure poschanged1; + procedure poschanged; override; + procedure sizechanged; override; + procedure parentclientrectchanged; override; + procedure doasyncevent(var atag: integer); override; + procedure dopaintforeground(const acanvas: tcanvas); override; + procedure parentwidgetregionchanged(const sender: twidget); override; + function getshrinkpriority: integer; override; + procedure tryshrink(const aclientsize: sizety); override; + procedure loaded; override; + procedure updatedock; + procedure updatelinkedwidgets(const delta: pointty); + + //istatfile + procedure dostatread(const reader: tstatreader); + procedure dostatwrite(const writer: tstatwriter); + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + + //iobjectpicker + function getcursorshape(const sender: tobjectpicker; + var shape: cursorshapety): boolean; + procedure getpickobjects(const sender: tobjectpicker; + var objects: integerarty); + procedure beginpickmove(const sender: tobjectpicker); + procedure pickthumbtrack(const sender: tobjectpicker); + procedure endpickmove(const sender: tobjectpicker); + procedure cancelpickmove(const sender: tobjectpicker); + procedure paintxorpic(const sender: tobjectpicker; const canvas: tcanvas); + class function classskininfo: skininfoty; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + function actualcolor: colorty; override; + function actualopaquecolor: colorty; override; + + procedure move(const dist: pointty); + + property options: splitteroptionsty read foptions write setoptions + default defaultsplitteroptions; + property shrinkpriority: integer read getshrinkpriority + write fshrinkpriority default 0; + property linkleft: twidget read flinkleft write setlinkleft; + property linktop: twidget read flinktop write setlinktop; + property linkright: twidget read flinkright write setlinkright; + property linkbottom: twidget read flinkbottom write setlinkbottom; + + property dist_left: integer read fdist_left + write setdist_left default 0; + property dist_top: integer read fdist_top + write setdist_top default 0; + property dist_right: integer read fdist_right + write setdist_right default 0; + property dist_bottom: integer read fdist_bottom + write setdist_bottom default 0; + +// property color default defaultsplittercolor; + property grip: stockbitmapty read fgrip write setgrip default stb_default; + property colorgrip: colorty read fcolorgrip write setcolorgrip + default cl_default; + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read getstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + property onupdatelayout: notifyeventty read fonupdatelayout + write fonupdatelayout; + published + property optionswidget default defaultoptionswidgetnofocus; + end; + + tsplitter = class(tcustomsplitter) + published +// property optionswidget; + property options; + property shrinkpriority; + property linkleft; + property linktop; + property linkright; + property linkbottom; + property dist_left; + property dist_top; + property dist_right; + property dist_bottom; + + property color; + property grip; + property colorgrip; + property statfile; + property statvarname; + property statpriority; + property onupdatelayout; + end; + + spaceroptionty = (spao_glueright,spao_gluebottom); + spaceroptionsty = set of spaceroptionty; + + tcustomspacer = class(tscalingwidget) + private + flinkleft: twidget; + flinktop: twidget; + flinkright: twidget; + flinkbottom: twidget; + fupdating: integer; + fdist_left: integer; + fdist_top: integer; + fdist_right: integer; + fdist_bottom: integer; + foptions: spaceroptionsty; + procedure setlinkleft(const avalue: twidget); + procedure setlinktop(const avalue: twidget); + procedure setlinkright(const avalue: twidget); + procedure setlinkbottom(const avalue: twidget); + procedure updatespace; + procedure setdist_left(const avalue: integer); + procedure setdist_top(const avalue: integer); + procedure setdist_right(const avalue: integer); + procedure setdist_bottom(const avalue: integer); + protected + procedure loaded; override; + procedure parentwidgetregionchanged(const sender: twidget); override; + public + constructor create(aowner: tcomponent); override; + property linkleft: twidget read flinkleft write setlinkleft; + property linktop: twidget read flinktop write setlinktop; + property linkright: twidget read flinkright write setlinkright; + property linkbottom: twidget read flinkbottom write setlinkbottom; + property dist_left: integer read fdist_left + write setdist_left default 0; + property dist_top: integer read fdist_top + write setdist_top default 0; + property dist_right: integer read fdist_right + write setdist_right default 0; + property dist_bottom: integer read fdist_bottom + write setdist_bottom default 0; + property options: spaceroptionsty read foptions write foptions default []; + property optionswidget default defaultoptionswidgetnofocus; + published + property visible default false; + end; + + tspacer = class(tcustomspacer) + published + property linkleft; + property linktop; + property linkright; + property linkbottom; + property dist_left; + property dist_top; + property dist_right; + property dist_bottom; + property options; + property optionswidget; + end; + + layoutoptionty = (lao_alignx,lao_placex,lao_aligny,lao_placey, + lao_scaleleft,lao_scaletop, + lao_scalewidth,lao_scaleheight, + lao_scalefont,lao_scalechildfont, + lao_syncmaxautosize, + lao_synccaptiondistx,lao_synccaptiondisty, + lao_syncpaintwidth,lao_syncpaintheight); + layoutoptionsty = set of layoutoptionty; +const + defaultlayoutoptions = []; + +type + placeoptionty = (plo_noinvisible,plo_scalesize, + plo_scalefullref, //use whole innerclientrect as size reference + plo_endmargin,plo_propmargin, + plo_syncmaxautosize, + plo_synccaptiondistx,plo_synccaptiondisty, + plo_syncpaintwidth,plo_syncpaintheight); + placeoptionsty = set of placeoptionty; +const + deprecatedplaceoptions = [plo_syncmaxautosize, + plo_synccaptiondistx,plo_synccaptiondisty, + plo_syncpaintwidth,plo_syncpaintheight]; + invisibleplaceoptions = [ord(plo_syncmaxautosize), + ord(plo_synccaptiondistx),ord(plo_synccaptiondisty), + ord(plo_syncpaintwidth),ord(plo_syncpaintheight)]; +type + widgetlayoutinfoty = record + widget: twidget; + layoutplacingbefore: boolean; + pos: pointty; + size: sizety; + curminsize: sizety; + actpos: pointty; + actsize: sizety; + refsize: sizety; + scalesize: sizety; + actscalesize: sizety; + refscalesize: sizety; + reffontsize: sizety; + fontheight: integer; + actfontheight: integer; + fontxscale: real; + actfontxscale: real; + end; + pwidgetlayoutinfoty = ^widgetlayoutinfoty; + widgetlayoutinfoarty = array of widgetlayoutinfoty; + + layouterstatety = (las_propsizing,las_scalesizerefvalid, + las_scalesizerefset,las_widgetinfoloaded, + las_delayedupdatelayoutpending); + layouterstatesty = set of layouterstatety; + + tcustomlayouter = class; + layoutereventty = procedure(const sender: tcustomlayouter) of object; + + tcustomlayouter = class(tcustomspacer) + private + foptionslayout: layoutoptionsty; + flayoutupdating: integer; + falign_mode: widgetalignmodety; + falign_leader: twidget; + fplace_mindist: integer; + fplace_maxdist: integer; + falign_glue: widgetalignmodety; + fplace_mode: widgetalignmodety; + fplace_options: placeoptionsty; + fwidgetinfos: widgetlayoutinfoarty; + fstate: layouterstatesty; + fscalesizeref: sizety; + fscalesizeextension: sizety; + ffontsizeref: sizety; + ffontheightref: integer; + ffontxscaleref: real; + fonbeforelayout: layoutereventty; + fonafterlayout: layoutereventty; + procedure setoptionslayout(const avalue: layoutoptionsty); + procedure setalign_mode(const avalue: widgetalignmodety); + procedure setalign_leader(const avalue: twidget); + procedure setplace_mindist(const avalue: integer); + procedure setplace_maxdist(const avalue: integer); + procedure setalign_glue(const avalue: widgetalignmodety); + procedure setplace_mode(const avalue: widgetalignmodety); + procedure setplace_options(avalue: placeoptionsty); + protected + procedure scalebasechanged(const sender: twidget); override; + function scalesizeref: sizety; + function childrenleft: integer; + function childrentop: integer; + function childrenright: integer; + function childrenbottom: integer; + function childrenwidth: integer; + function childrenheight: integer; + function childrenminwidth: integer; + function childrenminheight: integer; + procedure scalesizerefchanged; + procedure updatescalesizeref; + procedure delayedupdatelayout(); + procedure checkwidgetinfo(); + procedure updatelayout; + procedure readstate(reader: treader); override; + procedure loaded; override; + procedure fontchanged; override; + procedure widgetregionchanged(const sender: twidget); override; + procedure childclientrectchanged(const sender: twidget); override; + procedure childautosizechanged(const sender: twidget); override; + procedure clientrectchanged; override; + function calcminscrollsize: sizety; override; + procedure registerchildwidget(const child: twidget); override; + procedure unregisterchildwidget(const child: twidget); override; + function widgetinfoindex(const awidget: twidget): integer; + procedure updatewidgetinfo(var ainfo: widgetlayoutinfoty; + const awidget: twidget; const force: boolean = false); + procedure doasyncevent(var atag: integer); override; + public + constructor create(aowner: tcomponent); override; + property optionslayout: layoutoptionsty read foptionslayout write setoptionslayout + default defaultlayoutoptions; + property align_mode: widgetalignmodety read falign_mode write setalign_mode + default wam_center; + property align_leader: twidget read falign_leader write setalign_leader; + property align_glue: widgetalignmodety read falign_glue write setalign_glue + default wam_none; + property place_mindist: integer read fplace_mindist + write setplace_mindist default 0; + property place_maxdist: integer read fplace_maxdist write setplace_maxdist + default bigint; + property place_mode: widgetalignmodety read fplace_mode write setplace_mode + default wam_start; + property place_options: placeoptionsty read fplace_options + write setplace_options default []; + property onbeforelayout: layoutereventty read fonbeforelayout + write fonbeforelayout; + property onafterlayout: layoutereventty read fonafterlayout + write fonafterlayout; + published + property visible default true; + property optionswidget default defaultgroupboxoptionswidget; + end; + + tlayouter = class(tcustomlayouter) + published + property optionslayout; + property align_mode; + property align_leader; + property align_glue; + property place_mindist; + property place_maxdist; + property place_mode; + property place_options; + property onbeforelayout; + property onafterlayout; + + property linkleft; //tspacer + property linktop; + property linkright; + property linkbottom; + property dist_left; + property dist_top; + property dist_right; + property dist_bottom; + property options; + end; + +implementation +uses + msebits,math; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +type + twidget1 = class(twidget); + tcustomframe1 = class(tcustomframe); + ttaborderoverride1 = class(ttaborderoverride); + +{$define useround} + +{ tcustomsplitter } + +constructor tcustomsplitter.create(aowner: tcomponent); +begin +// include(fwidgetstate1,ws1_tryshrink); + foptions:= defaultsplitteroptions; + fcolorgrip:= cl_default; + fgrip:= stb_default; + frefrect.x:= -bigint; + frefrect.y:= -bigint; + frefrect.cx:= -bigint; + frefrect.cy:= -bigint; + include(fwidgetstate1,ws1_framemouse); + inherited; +// color:= defaultsplittercolor; + optionswidget:= defaultoptionswidgetnofocus; + fobjectpicker:= tobjectpicker.create(iobjectpicker(self),org_widget); +end; + +destructor tcustomsplitter.destroy; +begin + fobjectpicker.Free; + inherited; +end; + +procedure tcustomsplitter.mouseevent(var info: mouseeventinfoty); +begin + inherited; + if not (es_processed in info.eventstate) then begin + fobjectpicker.mouseevent(info); + end; +end; + +function tcustomsplitter.getcursorshape(const sender: tobjectpicker; + var shape: cursorshapety): boolean; +begin + result:= canmouseinteract and + pointinrect(sender.pos,makerect(nullpoint,fwidgetrect.size)); + if result then begin + if spo_hmove in foptions then begin + if spo_vmove in foptions then begin + shape:= cr_sizeall; + end + else begin + shape:= cr_sizehor; + end; + end + else begin + if spo_vmove in foptions then begin + shape:= cr_sizever; + end + else begin + result:= false; + end; + end; + if result and (cursor <> cr_default) then begin + shape:= cursor; + end; + end; +end; + +procedure tcustomsplitter.getpickobjects(const sender: tobjectpicker; + var objects: integerarty); +begin + if (foptions * [spo_hmove,spo_vmove] <> []) and canmouseinteract then begin + setlength(objects,1); + end; +end; + +function tcustomsplitter.clippoint(const aoffset: pointty): pointty; +var + int1,i2: integer; + rect1,rect2: rectty; +begin + if fparentwidget <> nil then begin + rect1:= twidget1(fparentwidget).clientwidgetrect; + rect2:= twidget1(fparentwidget).innerwidgetrect; + if not (an_right in fanchors) then begin + rect1.cx:= rect2.x+rect2.cx-rect1.x; + end; + if not (an_bottom in fanchors) then begin + rect1.cy:= rect2.y+rect2.cy-rect1.y; + end; + result:= subpoint( + clipinrect( + makerect(addpoint(aoffset,fwidgetrect.pos),fwidgetrect.size), + rect1).pos,fwidgetrect.pos); + end + else begin + result:= aoffset; + end; + if [spo_hmove,spo_hprop] * foptions = [] then begin + result.x:= 0; + end; + if [spo_vmove,spo_vprop] * foptions = [] then begin + result.y:= 0; + end; + if flinkleft <> flinkright then begin + if (flinkleft <> nil) then begin + with twidget1(flinkleft) do begin + int1:= widgetminsize.cx; + i2:= minshrinksize.cx; + if i2 > int1 then begin + int1:= i2; + end; + if fwidgetrect.cx + result.x < int1 then begin + result.x:= int1 - fwidgetrect.cx; + end; + if bounds_cxmax > 0 then begin + if fwidgetrect.cx + result.x > bounds_cxmax then begin + result.x:= bounds_cxmax - fwidgetrect.cx; + end; + end; + end; + end; + if flinkright <> nil then begin + with twidget1(flinkright) do begin + int1:= widgetminsize.cx; + i2:= minshrinksize.cx; + if i2 > int1 then begin + int1:= i2; + end; + if fwidgetrect.cx - result.x < int1 then begin + result.x:= - (int1 - fwidgetrect.cx); + end; + if bounds_cxmax > 0 then begin + if fwidgetrect.cx - result.x > bounds_cxmax then begin + result.x:= - (bounds_cxmax - fwidgetrect.cx); + end; + end; + end; + end; + end; + if flinktop <> flinkbottom then begin + if (flinktop <> nil) then begin + with twidget1(flinktop) do begin + int1:= widgetminsize.cy; + i2:= minshrinksize.cy; + if i2 > int1 then begin + int1:= i2; + end; + if fwidgetrect.cy + result.y < int1 then begin + result.y:= int1 - fwidgetrect.cy; + end; + if bounds_cymax > 0 then begin + if fwidgetrect.cy + result.y > bounds_cymax then begin + result.y:= bounds_cymax - fwidgetrect.cy; + end; + end; + end; + end; + if flinkbottom <> nil then begin + with twidget1(flinkbottom) do begin + int1:= widgetminsize.cy; + i2:= minshrinksize.cy; + if i2 > int1 then begin + int1:= i2; + end; + if fwidgetrect.cy - result.y < int1 then begin + result.y:= - (int1 - fwidgetrect.cy); + end; + if bounds_cymax > 0 then begin + if fwidgetrect.cy - result.y > bounds_cymax then begin + result.y:= - (bounds_cymax - fwidgetrect.cy); + end; + end; + end; + end; + end; +end; + +procedure tcustomsplitter.paintxorpic(const sender: tobjectpicker; + const canvas: tcanvas); +begin + if fparentwidget <> nil then begin + canvas.addcliprect(makerect(-fwidgetrect.x,-fwidgetrect.y, + twidget1(fparentwidget).fwidgetrect.cx, + twidget1(fparentwidget).fwidgetrect.cy)); + end; + canvas.drawxorframe(makerect(clippoint(sender.pickoffset),fwidgetrect.size),-4, + stockobjects.bitmaps[stb_dens25]); +end; + +class function tcustomsplitter.classskininfo: skininfoty; +begin + result:= inherited classskininfo; + result.objectkind:= sok_splitter; +end; + +procedure tcustomsplitter.updatelinkedwidgets(const delta: pointty); +var + rect1: rectty; +begin + inc(fupdating); + try + if flinkleft = flinkright then begin + if flinkright <> nil then begin + flinkright.bounds_x:= flinkright.bounds_x + delta.x; + end; + end + else begin + if flinkleft <> nil then begin + flinkleft.bounds_cx:= flinkleft.bounds_cx + delta.x; + end; + if flinkright <> nil then begin + rect1:= twidget1(flinkright).fwidgetrect; + rect1.x:= rect1.x + delta.x; + rect1.cx:= rect1.cx - delta.x; + flinkright.widgetrect:= rect1; + end; + end; + if flinktop = flinkbottom then begin + if flinkbottom <> nil then begin + flinkbottom.bounds_y:= flinkbottom.bounds_y + delta.y; + end; + end + else begin + if flinktop <> nil then begin + flinktop.bounds_cy:= flinktop.bounds_cy + delta.y; + end; + if flinkbottom <> nil then begin + rect1:= twidget1(flinkbottom).fwidgetrect; + rect1.y:= rect1.y + delta.y; + rect1.cy:= rect1.cy - delta.y; + flinkbottom.widgetrect:= rect1; + end; + end; + if canevent(tmethod(fonupdatelayout)) then begin + fonupdatelayout(self); + end; + finally + dec(fupdating); + end; +end; + +procedure tcustomsplitter.setclippedpickoffset(const aoffset: pointty); +begin + inc(fupdating); + try + self.pos:= addpoint(self.pos,aoffset); + finally + dec(fupdating); + end; + updatelinkedwidgets(aoffset); +end; + +procedure tcustomsplitter.setpickoffset(const aoffset: pointty); +begin + setclippedpickoffset(clippoint(aoffset)); +end; + +procedure tcustomsplitter.move(const dist: pointty); +begin + setpickoffset(dist); +end; + +procedure tcustomsplitter.endpickmove(const sender: tobjectpicker); +begin + setpickoffset(sender.pickoffset); +end; + +procedure tcustomsplitter.cancelpickmove(const sender: tobjectpicker); +begin + widgetrect:= fwidgetrectbefore; +end; + +procedure tcustomsplitter.beginpickmove(const sender: tobjectpicker); +begin + fwidgetrectbefore:= fwidgetrect; +end; + +procedure tcustomsplitter.pickthumbtrack(const sender: tobjectpicker); +begin + setpickoffset(sender.pickoffset); +end; + +procedure tcustomsplitter.setstatfile(const avalue: tstatfile); +begin + setstatfilevar(istatfile(self),avalue,fstatfile); +end; + +procedure tcustomsplitter.dostatread(const reader: tstatreader); +var + po1,po2: pointty; +begin + if reader.canstate then begin + po1:= parentclientpos; + if spo_hmove in foptions then begin + po2.x:= reader.readinteger('x',po1.x); + end + else begin + po2.x:= po1.x; + end; + if spo_vmove in foptions then begin + po2.y:= reader.readinteger('y',po1.y); + end + else begin + po2.y:= po1.y; + end; + setclippedpickoffset(subpoint(po2,po1)); + if foptions * [spo_hmove,spo_hprop] = [spo_hmove,spo_hprop] then begin + fhprop:= reader.readreal('xprop',fhprop,0,1); + end; + if foptions * [spo_vmove,spo_vprop] = [spo_vmove,spo_vprop] then begin + fvprop:= reader.readreal('yprop',fvprop,0,1); + end; + end; +end; + +procedure tcustomsplitter.dostatwrite(const writer: tstatwriter); +var + po1: pointty; +begin + if writer.canstate then begin + po1:= parentclientpos; + writer.writeinteger('x',po1.x); + writer.writeinteger('y',po1.y); + writer.writereal('xprop',fhprop); + writer.writereal('yprop',fvprop); + end; +end; + +procedure tcustomsplitter.statreading; +begin +{ + if fparentwidget <> nil then begin + postupdatepropevent; + end; +} +end; + +procedure tcustomsplitter.statread; +begin + //dummy +end; + +function tcustomsplitter.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +procedure tcustomsplitter.setlinkbottom(const avalue: twidget); +begin +// if flinkbottom <> nil then begin +// twidget1(flinkbottom).fminshrinkposoffset.y:= 0; +// end; + setlinkedvar(avalue,tmsecomponent(flinkbottom)); + updatedock; +end; + +procedure tcustomsplitter.setlinkleft(const avalue: twidget); +begin + setlinkedvar(avalue,tmsecomponent(flinkleft)); + updatedock; +end; + +procedure tcustomsplitter.setlinkright(const avalue: twidget); +begin +// if flinkright <> nil then begin +// twidget1(flinkright).fminshrinkposoffset.x:= 0; +// end; + setlinkedvar(avalue,tmsecomponent(flinkright)); + updatedock; +end; + +procedure tcustomsplitter.setlinktop(const avalue: twidget); +begin + setlinkedvar(avalue,tmsecomponent(flinktop)); + updatedock; +end; + +procedure tcustomsplitter.poschanged1; +var + int1,int2,int3: integer; +begin + int3:= 0; + if not (spo_hrefstart in foptions) then begin + int3:= bounds_cx; + end; + int2:= bounds_x + int3; + if frefrect.x <> int2 then begin + frefrect.x:= int2; + fhprop:= 0; + int1:= fparentwidget.clientsize.cx; + if (int1 > 0) then begin + fhprop:= (parentclientpos.x+int3) / + {$ifdef FPC} real({$endif}int1{$ifdef FPC}){$endif}; + end; + end; + int3:= 0; + if not (spo_vrefstart in foptions) then begin + int3:= bounds_cy; + end; + int2:= bounds_y + int3; + if frefrect.y <> int2 then begin + frefrect.y:= int2; + fvprop:= 0; + int1:= fparentwidget.clientsize.cy; + if (int1 > 0) then begin + fvprop:= (parentclientpos.y+int3) / + {$ifdef FPC} real({$endif}int1{$ifdef FPC}){$endif}; + end; + end; +end; + +procedure tcustomsplitter.poschanged; +begin + inherited; + if (fparentwidget <> nil) then begin + if not (csloading in componentstate) and (fpropsetting = 0) then begin + poschanged1; + end; + end; +end; + +procedure tcustomsplitter.sizechanged; +var + int1: integer; +begin + inherited; + if (fparentwidget <> nil) then begin + if not (csloading in componentstate) and (fpropsetting = 0) then begin + if frefrect.cx <> bounds_cx then begin + frefrect.cx:= bounds_cx; + fhsizeprop:= 0; + int1:= fparentwidget.clientsize.cx; + if (int1 > 0) then begin + fhsizeprop:= fwidgetrect.cx / {$ifdef FPC} real({$endif}int1{$ifdef FPC}){$endif}; + end; + end; + if frefrect.cy <> bounds_cy then begin + frefrect.cy:= bounds_cy; + fvsizeprop:= 0; + int1:= fparentwidget.clientsize.cy; + if (int1 > 0) then begin + fvsizeprop:= fwidgetrect.cy / {$ifdef FPC} real({$endif}int1{$ifdef FPC}){$endif}; + end; + end; + poschanged1; + end; + end; +end; + +procedure tcustomsplitter.calcoffset(const refsize: sizety; + out offset,clippedoffset: pointty; out newsize: sizety); +//var +// size1: sizety; +var + int1: integer; +begin +// size1:= fparentwidget.clientsize; + offset:= nullpoint; + newsize:= size; + if spo_hsizeprop in foptions then begin + newsize.cx:= {$ifdef useround}round{$else}floor{$endif}(refsize.cx * fhsizeprop); + if not(an_right in fanchors) xor (spo_hrefstart in foptions) then begin + offset.x:= bounds_cx - newsize.cx; + end; + end; + if spo_vsizeprop in foptions then begin + newsize.cy:= {$ifdef useround}round{$else}floor{$endif}(refsize.cy * fvsizeprop); + if not(an_bottom in fanchors) xor (spo_vrefstart in foptions) then begin + offset.y:= bounds_cy - newsize.cy; + end; + end; + if spo_hprop in foptions then begin + int1:= 0; + if not (spo_hrefstart in foptions) then begin + int1:= bounds_cx; + end; + offset.x:= offset.x + {$ifdef useround}round{$else}floor{$endif}(fhprop * refsize.cx) - parentclientpos.x - + int1; + end; + if (spo_vprop in foptions) then begin + int1:= 0; + if not (spo_vrefstart in foptions) then begin + int1:= bounds_cy; + end; + offset.y:= offset.y + {$ifdef useround}round{$else}floor{$endif}(fvprop * refsize.cy) - parentclientpos.y - + int1; + end; + clippedoffset:= clippoint(offset); +// pt2:= pt1; +end; + +procedure tcustomsplitter.setpropoffset(const aoffset: pointty; + const asize: sizety); +begin + inc(fpropsetting); + try + size:= asize; + setclippedpickoffset(aoffset); + frefrect:= fwidgetrect; + with frefrect do begin + if not(spo_hrefstart in foptions) then begin + x:= x + cx; + end; + if not(spo_vrefstart in foptions) then begin + y:= y + cy; + end; + end; + finally + dec(fpropsetting); + end; +end; + +function tcustomsplitter.actualcolor: colorty; +begin + if fcolor = cl_default then begin + result:= defaultsplittercolor; + end + else begin + result:= inherited actualcolor(); + end; +end; + +function tcustomsplitter.actualopaquecolor: colorty; +begin + if fcolor = cl_default then begin + result:= defaultsplittercolor; + end + else begin + result:= inherited actualopaquecolor(); + end; +end; + +procedure tcustomsplitter.doasyncevent(var atag: integer); +var + pt1,pt2: pointty; + size2: sizety; + +begin //doasyncevent + inherited; + case atag of + updatepropeventtag,retrypropeventtag: begin + if atag = updatepropeventtag then begin + exclude(fstate,sps_propnotified); + end; + try + if fparentwidget <> nil then begin + calcoffset(fparentwidget.clientsize,pt1,pt2,size2); + if (([spo_hmove,spo_hprop] * foptions <> []) and (pt1.x <> pt2.x) or + ([spo_vmove,spo_vprop] * foptions <> []) and (pt1.y <> pt2.y)) and + (fregionchangedmark <> fregionchangedcount) then begin + fregionchangedmark:= fregionchangedcount; + inc(fupdating); + asyncevent(retrypropeventtag,[peo_local]); + end + else begin + inc(fpropoffsetrecursion); + if fpropoffsetrecursion < 16 then begin + setpropoffset(pt2,size2); + if not(sps_propnotified in fstate) then begin + fpropoffsetrecursion:= 0; + end; + end + else begin + fpropoffsetrecursion:= 0; + end; + end; + end; + finally + if atag = retrypropeventtag then begin + dec(fupdating); + if fupdating = 0 then begin + updatedock; + end; + end; + end; + end; + end; +end; + +procedure tcustomsplitter.tryshrink(const aclientsize: sizety); +var + pt1,pt2: pointty; + size1,size2: sizety; +begin + if fupdating = 0 then begin + if spo_hshrinkzero in foptions then begin + size1.cx:= 0; + end + else begin + size1:= fparentwidget.clientsize; + if size1.cx > aclientsize.cx then begin + size1.cx:= aclientsize.cx; + end; + end; + if spo_vshrinkzero in foptions then begin + size1.cy:= 0; + end + else begin + if size1.cy > aclientsize.cy then begin + size1.cy:= aclientsize.cy; + end; + end; + calcoffset(size1,pt1,pt2,size2); + try + setpropoffset(pt2,size2); + finally + updatedock; + end; + end; +end; + +procedure tcustomsplitter.postupdatepropevent; +begin + if not (sps_propnotified in fstate) then begin + include(fstate,sps_propnotified); + asyncevent(updatepropeventtag,[peo_local,peo_first]); + end; +end; + +procedure tcustomsplitter.parentclientrectchanged; +begin + inherited; + if (componentstate * [csloading{,csdesigning}] = []) and canmouseinteract and + (fparentwidget <> nil) then begin + postupdatepropevent; + end; +end; + +procedure tcustomsplitter.setcolorgrip(const avalue: colorty); +begin + if fcolorgrip <> avalue then begin + fcolorgrip:= avalue; + invalidate; + end; +end; + +procedure tcustomsplitter.setgrip(const avalue: stockbitmapty); +begin + if fgrip <> avalue then begin + fgrip:= avalue; + invalidate; + end; +end; + +procedure tcustomsplitter.dopaintforeground(const acanvas: tcanvas); +begin + inherited; + if fgrip <> stb_none then begin + with acanvas do begin + if fgrip = stb_default then begin + brush:= stockobjects.bitmaps[defaultsplittergrip]; + end + else begin + brush:= stockobjects.bitmaps[fgrip]; + end; + if fcolorgrip = cl_default then begin + color:= defaultsplittercolorgrip; + end + else begin + color:= fcolorgrip; + end; + fillrect(innerclientrect,cl_brushcanvas); + end; + end; +end; + +procedure tcustomsplitter.parentwidgetregionchanged(const sender: twidget); +begin + inc(fregionchangedcount); + inherited; + if (sender <> nil) and ((sender = flinkleft) or (sender = flinktop) or + (sender = flinkright) or (sender = flinkbottom) or + (sender = self)) then begin + updatedock; + end; +end; + +procedure tcustomsplitter.loaded; +begin + inherited; + updatedock; +end; + +procedure tcustomsplitter.updatedock; +var + pt1: pointty; + rect1: rectty; +begin + if (componentstate * [csloading,csdestroying] = []) and + (foptions * docksplitteroptions <> []) and + (fparentwidget <> nil) and (fupdating = 0) then begin + inc(fupdating); + pt1:= addpoint(pos,pointty(size)); + try + if flinkright <> nil then begin + with twidget1(flinkright) do begin +// fminshrinkposoffset.x:= - fwidgetrect.x; + end; + end; + if flinkbottom <> nil then begin + with twidget1(flinkbottom) do begin +// fminshrinkposoffset.y:= - fwidgetrect.y; + end; + end; + if (flinkleft = flinkright) and + (foptions * [spo_dockleft,spo_dockright] = + [spo_dockleft,spo_dockright])then begin + if flinkleft <> nil then begin + flinkleft.widgetrect:= makerect(bounds_x+fdist_left,flinkleft.bounds_y, + bounds_cx-fdist_left-fdist_right,flinkleft.bounds_cy); + end; + end + else begin + if (flinkleft <> nil) and (spo_dockleft in foptions) then begin + flinkleft.bounds_cx:= bounds_x - flinkleft.bounds_x - fdist_left; + end; + if (flinkright <> nil) and (spo_dockright in foptions) then begin + rect1:= flinkright.widgetrect; + rect1.cx:= rect1.cx + (rect1.x - pt1.x) - fdist_right; + rect1.pos.x:= pt1.x + fdist_right; + flinkright.widgetrect:= rect1; + end; + end; + if (flinktop = flinkbottom) and + (foptions * [spo_docktop,spo_dockbottom] = + [spo_docktop,spo_dockbottom]) then begin + if flinktop <> nil then begin + flinktop.widgetrect:= makerect(flinktop.bounds_x,bounds_y+fdist_top, + flinktop.bounds_cx,bounds_cy- + fdist_top-fdist_bottom); + end; + end + else begin + if (flinktop <> nil) and (spo_docktop in foptions) then begin + flinktop.bounds_cy:= bounds_y - flinktop.bounds_y - fdist_top; + end; + if (flinkbottom <> nil) and (spo_dockbottom in foptions) then begin + rect1:= flinkbottom.widgetrect; + rect1.cy:= rect1.cy + (rect1.y - pt1.y) - fdist_bottom; + rect1.pos.y:= pt1.y + fdist_bottom; + flinkbottom.widgetrect:= rect1; + end; + end; + finally + dec(fupdating); + end; + end; +end; +{ +function tcustomsplitter.getminshrinkpos: pointty; +var + int1: integer; +begin + result:= fwidgetrect.pos; + if flinkleft <> nil then begin + result.x:= result.x - flinkleft.bounds_cx + flinkleft.bounds_cxmin; + end + else begin + if spo_hprop in foptions then begin + result.x:= 0; + end; + end; + if flinktop <> nil then begin + result.y:= result.y - flinktop.bounds_cy + flinktop.bounds_cymin; + end + else begin + if spo_vprop in foptions then begin + result.y:= 0; + end; + end; +end; +} +procedure tcustomsplitter.setoptions(const avalue: splitteroptionsty); +begin + if foptions <> avalue then begin + foptions:= avalue; + if avalue * [spo_hprop,spo_vprop] <> [] then begin + include(fwidgetstate1,ws1_tryshrink); + end + else begin + exclude(fwidgetstate1,ws1_tryshrink); + end; + if spo_thumbtrack in avalue then begin + fobjectpicker.options:= fobjectpicker.options + [opo_thumbtrack]; + end + else begin + fobjectpicker.options:= fobjectpicker.options - [opo_thumbtrack]; + end; + updatedock; + end; +end; + +procedure tcustomsplitter.setdist_left(const avalue: integer); +begin + if fdist_left <> avalue then begin + fdist_left:= avalue; + updatedock(); + end; +end; + +procedure tcustomsplitter.setdist_top(const avalue: integer); +begin + if fdist_top <> avalue then begin + fdist_top:= avalue; + updatedock(); + end; +end; + +procedure tcustomsplitter.setdist_right(const avalue: integer); +begin + if fdist_right <> avalue then begin + fdist_right:= avalue; + updatedock(); + end; +end; + +procedure tcustomsplitter.setdist_bottom(const avalue: integer); +begin + if fdist_bottom <> avalue then begin + fdist_bottom:= avalue; + updatedock(); + end; +end; + +function tcustomsplitter.getshrinkpriority: integer; +begin + result:= fshrinkpriority; +end; + +function tcustomsplitter.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +{ tcustomspacer } + +constructor tcustomspacer.create(aowner: tcomponent); +begin + inherited; + foptionswidget:= defaultoptionswidgetnofocus; + fwidgetstate:= fwidgetstate - (defaultwidgetstates-defaultwidgetstatesinvisible); +end; + +procedure tcustomspacer.setlinkleft(const avalue: twidget); +begin + setlinkedvar(avalue,tmsecomponent(flinkleft)); + updatespace; +end; + +procedure tcustomspacer.setlinktop(const avalue: twidget); +begin + setlinkedvar(avalue,tmsecomponent(flinktop)); + updatespace; +end; + +procedure tcustomspacer.setlinkright(const avalue: twidget); +begin + setlinkedvar(avalue,tmsecomponent(flinkright)); + updatespace; +end; + +procedure tcustomspacer.setlinkbottom(const avalue: twidget); +begin + setlinkedvar(avalue,tmsecomponent(flinkbottom)); + updatespace; +end; + +procedure tcustomspacer.setdist_left(const avalue: integer); +begin + fdist_left:= avalue; + updatespace; +end; + +procedure tcustomspacer.setdist_top(const avalue: integer); +begin + fdist_top:= avalue; + updatespace; +end; + +procedure tcustomspacer.setdist_right(const avalue: integer); +begin + fdist_right:= avalue; + updatespace; +end; + +procedure tcustomspacer.setdist_bottom(const avalue: integer); +begin + fdist_bottom:= avalue; + updatespace; +end; + +function alive(const acomponent: tcomponent): boolean; +begin + result:= (acomponent <> nil) and + not (csdestroying in acomponent.componentstate); +end; + +procedure tcustomspacer.updatespace; +var + rect1: rectty; + pt1: pointty; +begin + if (componentstate * [csloading,csdestroying] = []) and + (fparentwidget <> nil) and (fupdating = 0) then begin + inc(fupdating); + try + rect1:= fwidgetrect; + if spao_glueright in foptions then begin + if alive(flinkright) then begin + if an_left in fanchors then begin + rect1.cx:= flinkright.bounds_x - bounds_x - fdist_right; + end + else begin + rect1.x:= flinkright.bounds_x - bounds_cx - fdist_right; + end; + end; + end + else begin + if alive(flinkleft) then begin + rect1.x:= flinkleft.bounds_x + flinkleft.bounds_cx + fdist_left; + end; + end; + if spao_gluebottom in foptions then begin + if alive(flinkbottom) then begin + if an_top in fanchors then begin + rect1.cy:= flinkbottom.bounds_y - bounds_y - fdist_bottom; + end + else begin + rect1.y:= flinkbottom.bounds_y - bounds_cy - fdist_bottom; + end; + end; + end + else begin + if alive(flinktop) then begin + rect1.y:= flinktop.bounds_y + flinktop.bounds_cy + fdist_top; + end; + end; + widgetrect:= rect1; + pt1:= pos; + addpoint1(pt1,pointty(size)); + pt1.x:= pt1.x + fdist_right; + pt1.y:= pt1.y + fdist_bottom; + if spao_glueright in foptions then begin + if alive(flinkleft) then begin + rect1:= flinkleft.widgetrect; + if an_left in flinkleft.anchors then begin + rect1.cx:= bounds_x - fdist_left - flinkleft.bounds_x; + with twidget1(flinkleft) do begin + fparentclientsize.cx:= twidget1(fparentwidget).minclientsize.cx; + //no change by pending parentclientrectchanged() + end; + end + else begin + rect1.x:= bounds_x - fdist_left - flinkleft.bounds_cx; + end; + flinkleft.widgetrect:= rect1; + end; + end + else begin + if alive(flinkright) then begin + rect1:= flinkright.widgetrect; + if an_right in flinkright.anchors then begin + rect1.cx:= rect1.cx + (rect1.x - pt1.x); + end; + rect1.pos.x:= pt1.x; + flinkright.widgetrect:= rect1; + end; + end; + if spao_gluebottom in foptions then begin + if alive(flinktop) then begin + rect1:= flinktop.widgetrect; + if an_top in flinktop.anchors then begin + rect1.cy:= bounds_y - fdist_top - flinktop.bounds_y; + with twidget1(flinktop) do begin + fparentclientsize.cy:= twidget1(fparentwidget).minclientsize.cy; + //no change by pending parentclientrectchanged() + end; + end + else begin + rect1.y:= bounds_y - fdist_top - flinktop.bounds_cy; + end; + flinktop.widgetrect:= rect1; + end; + end + else begin + if alive(flinkbottom) then begin + rect1:= flinkbottom.widgetrect; + if an_bottom in flinkbottom.anchors then begin + rect1.cy:= rect1.cy + (rect1.y - pt1.y); + end; + rect1.pos.y:= pt1.y; + flinkbottom.widgetrect:= rect1; + end; + end; + finally + dec(fupdating); + end; + end; +end; + +procedure tcustomspacer.loaded; +begin + inherited; + updatespace; +end; + +procedure tcustomspacer.parentwidgetregionchanged(const sender: twidget); +begin + inherited; + if (sender <> nil) and ((sender = flinkleft) or (sender = flinktop) or + (sender = flinkright) or (sender = flinkbottom) or + (sender = self)) then begin + updatespace; + end; +end; + +{ tcustomlayouter } + +constructor tcustomlayouter.create(aowner: tcomponent); +begin + foptionslayout:= defaultlayoutoptions; + falign_mode:= wam_center; +// faligny_mode:= wam_center; + fplace_maxdist:= bigint; + fplace_mode:= wam_start; +// fplacey_maxdist:= bigint; + inherited; + foptionswidget:= defaultgroupboxoptionswidget; + include(fwidgetstate,ws_visible); +end; + +procedure tcustomlayouter.setoptionslayout(const avalue: layoutoptionsty); +const + mask1: layoutoptionsty = [lao_alignx,lao_placex]; + mask2: layoutoptionsty = [lao_aligny,lao_placey]; +var + lao1,lao2: layoutoptionsty; +begin + if avalue <> foptionslayout then begin + lao1:= layoutoptionsty(setsinglebit({$ifdef FPC}longword{$else}word{$endif}(avalue), + {$ifdef FPC}longword{$else}word{$endif}(foptionslayout), + {$ifdef FPC}longword{$else}word{$endif}(mask1)))*mask1; + lao2:= layoutoptionsty(setsinglebit({$ifdef FPC}longword{$else}word{$endif}(avalue), + {$ifdef FPC}longword{$else}word{$endif}(foptionslayout), + {$ifdef FPC}longword{$else}word{$endif}(mask2)))*mask2; + foptionslayout:= (avalue - (mask1+mask2)) + lao1 + lao2; + updatelayout; + end; +end; + +function tcustomlayouter.childrenwidth: integer; +var + int1: integer; +begin + result:= 0; + for int1:= 0 to high(fwidgets) do begin + with twidget1(fwidgets[int1]) do begin + if (not(plo_noinvisible in fplace_options) or isvisible) then begin + result:= result + fwidgetrect.cx; + end; + end; + end; +end; + +function tcustomlayouter.childrenheight: integer; +var + int1: integer; +begin + result:= 0; + for int1:= 0 to high(fwidgets) do begin + with twidget1(fwidgets[int1]) do begin + if (not(plo_noinvisible in fplace_options) or isvisible) then begin + result:= result + fwidgetrect.cy; + end; + end; + end; +end; + +function tcustomlayouter.childrenminwidth: integer; +var + i1,i2,i3,i5: int32; + variable,space,fix: int32; +begin + variable:= 0; + space:= innerframewidth.cx; + i1:= high(fwidgets); + if i1 > 0 then begin + space:= space + fplace_mindist * i1; + end; + if i1 >= 0 then begin + if plo_propmargin in fplace_options then begin + space:= space + 2 * fplace_mindist; + end; + end; + fix:= space; + for i1:= 0 to high(fwidgetinfos) do begin + with fwidgetinfos[i1],widget do begin + if not (plo_noinvisible in fplace_options) or isvisible then begin + if (anchors * [an_left,an_right] = [an_left,an_right]) then begin + fix:= fix + minshrinksize.cx;//minscrollsize.cx; + end + else begin + if (plo_scalesize in fplace_options) and + not (osk_nopropwidth in optionsskin) then begin + variable:= variable + bounds_cx; + end + else begin + fix:= fix + bounds_cx; + end; + end; + end; + end; + end; + if plo_scalesize in fplace_options then begin + //(x-extension)*(1/ref)*variable + fix = x + //x = (fix*ref - extension*variable) / (ref - variable) + + result:= 0; + i1:= fix*scalesizeref.cx - fscalesizeextension.cx*variable; + i2:= scalesizeref.cx - variable; + if i2 <> 0 then begin + result:= (i1 + i2 div 2) div i2; //with rounding + end; + i3:= 0; + for i1:= 0 to high(fwidgetinfos) do begin + with fwidgetinfos[i1],widget do begin + if (not (plo_noinvisible in fplace_options) or isvisible) then begin + if not (osk_nopropwidth in optionsskin) then begin + if scalesize.cx > 0 then begin + i5:= curminsize.cx * refscalesize.cx div scalesize.cx; + if i3 < i5 then begin + i3:= i5; + end; + end; + end; + end; + end; + end; + i3:= i3 + fscalesizeextension.cx; //add not scaling values + if result < i3 then begin + result:= i3; + end; + end + else begin + result:= variable + fix; + end; +end; + +function tcustomlayouter.childrenminheight: integer; +var + i1,i2,i3,i5: int32; + variable,space,fix: int32; +begin + variable:= 0; + space:= innerframewidth.cy; + i1:= high(fwidgets); + if i1 > 0 then begin + space:= space + fplace_mindist * i1; + end; + if i1 >= 0 then begin + if plo_propmargin in fplace_options then begin + space:= space + 2 * fplace_mindist; + end; + end; + fix:= space; + for i1:= 0 to high(fwidgetinfos) do begin + with fwidgetinfos[i1],widget do begin + if not (plo_noinvisible in fplace_options) or isvisible then begin + if (anchors * [an_top,an_bottom] = [an_top,an_bottom]) then begin + fix:= fix + minshrinksize.cy; //minscrollsize.cy; + end + else begin + if (plo_scalesize in fplace_options) and + not (osk_nopropwidth in optionsskin) then begin + variable:= variable + bounds_cy; + end + else begin + fix:= fix + bounds_cy; + end; + end; + end; + end; + end; + if plo_scalesize in fplace_options then begin + //(y-extension)*(1/ref)*variable + fix = y + //y = (fix*ref - extension*variable) / (ref - variable) + + result:= 0; + i1:= fix*scalesizeref.cy - fscalesizeextension.cy*variable; + i2:= scalesizeref.cy - variable; + if i2 <> 0 then begin + result:= (i1 + i2 div 2) div i2; //with rounding + end; + i3:= 0; + for i1:= 0 to high(fwidgetinfos) do begin + with fwidgetinfos[i1],widget do begin + if (not (plo_noinvisible in fplace_options) or isvisible) then begin + if not (osk_nopropwidth in optionsskin) then begin + if scalesize.cy > 0 then begin + i5:= curminsize.cy * refscalesize.cy div scalesize.cy; + if i3 < i5 then begin + i3:= i5; + end; + end; + end; + end; + end; + end; + i3:= i3 + fscalesizeextension.cy; //add not scaling values + if result < i3 then begin + result:= i3; + end; + end + else begin + result:= variable + fix; + end; +end; +(* +function tcustomlayouter.childrenminheight: integer; +var + int1: integer; +begin + result:= 0; + for int1:= 0 to high(fwidgetinfos) do begin + with fwidgetinfos[int1],widget do begin + if not(plo_noinvisible in fplace_options) or isvisible then begin + if (anchors * [an_top,an_bottom] = [an_top,an_bottom]) or + (plo_scalesize in fplace_options) and + not(osk_nopropheight in optionsskin) then begin +// result:= result + minscrollsize.cy; + result:= result + curminsize.cy; + end + else begin + result:= result + bounds_cy; + end; + end; + end; + end; +end; +*) +function tcustomlayouter.childrenleft: integer; +var + int1: integer; +begin + result:= bigint; + for int1:= 0 to high(fwidgets) do begin + with twidget1(fwidgets[int1]) do begin + if (not(plo_noinvisible in fplace_options) or isvisible) and + (fwidgetrect.x < result) and + not (osk_noalignx in optionsskin) then begin + result:= fwidgetrect.x; + end; + end; + end; + if result = bigint then begin + result:= 0; + end; +end; + +function tcustomlayouter.childrenright: integer; +var + int1: integer; + int2: integer; +begin + result:= -bigint; + for int1:= 0 to high(fwidgets) do begin + with twidget1(fwidgets[int1]) do begin + int2:= fwidgetrect.x + fwidgetrect.cx; + if (not(plo_noinvisible in fplace_options) or isvisible) and + (int2 > result) and + not (osk_noalignx in optionsskin) then begin + result:= int2; + end; + end; + end; + if result = -bigint then begin + result:= 0; + end; +end; + +function tcustomlayouter.childrentop: integer; +var + int1: integer; +begin + result:= bigint; + for int1:= 0 to high(fwidgets) do begin + with twidget1(fwidgets[int1]) do begin + if (not(plo_noinvisible in fplace_options) or isvisible) and + (fwidgetrect.y < result) and + not (osk_noaligny in optionsskin) then begin + result:= fwidgetrect.y; + end; + end; + end; + if result = bigint then begin + result:= 0; + end; +end; + +function tcustomlayouter.childrenbottom: integer; +var + int1: integer; + int2: integer; +begin + result:= -bigint; + for int1:= 0 to high(fwidgets) do begin + with twidget1(fwidgets[int1]) do begin + int2:= fwidgetrect.y + fwidgetrect.cy; + if (not (plo_noinvisible in fplace_options) or isvisible) and + (int2 > result) and + not (osk_noaligny in optionsskin) then begin + result:= int2; + end; + end; + end; + if result = -bigint then begin + result:= 0; + end; +end; + +procedure tcustomlayouter.checkwidgetinfo(); +var + i1: integer; +begin + if not (las_widgetinfoloaded in fstate) and + not(csloading in componentstate) then begin + include(fstate,las_widgetinfoloaded); + for i1:= high(fwidgetinfos) downto 0 do begin + updatewidgetinfo(fwidgetinfos[i1],nil,true); + end; + end; +end; + +procedure tcustomlayouter.updatelayout; +var + ar2: integerarty; + space,margin: integer; + + procedure calcarray(const awidgets: widgetarty; const awidth: integer; + const amin,amax: integer); + var + int1,int2: integer; + rea1,rea2: real; + begin + margin:= 0; + if high(awidgets) > 0 then begin + if plo_propmargin in fplace_options then begin + rea1:= awidth / (high(awidgets)+2); + end + else begin + rea1:= awidth / high(awidgets); + end; + if rea1 < amin then begin + rea1:= amin; + end; + if rea1 > amax then begin + rea1:= amax; + end; + if plo_propmargin in fplace_options then begin + margin:= round(rea1); + end; + rea2:= rea1; + setlength(ar2,high(awidgets)); + space:= 0; + for int1:= 0 to high(ar2) do begin + int2:= round(rea2); + space:= space + int2; + ar2[int1]:= int2; + rea2:= rea2 - ar2[int1] + rea1; + end; + end + else begin + space:= 0; + if plo_propmargin in fplace_options then begin + margin:= awidth div 2; + if margin < amin then begin + margin:= amin; + end; + if margin > amax then begin + margin:= amax; + end; + end; + end; + end; //calcarray + + function getalignwidgets(const isx: boolean): widgetarty; + var + int1,int2: integer; + begin + setlength(result,widgetcount); + int2:= 0; + if (falign_leader <> nil) and + (falign_leader.parentwidget = self) then begin + result[0]:= falign_leader; + int2:= 1; + end; + for int1:= 0 to high(result) do begin + if fwidgets[int1] <> falign_leader then begin + if isx and not (osk_noalignx in fwidgets[int1].optionsskin) or + not isx and not (osk_noaligny in fwidgets[int1].optionsskin) then begin + result[int2]:= fwidgets[int1]; + inc(int2); + end; + end; + end; + setlength(result,int2); + end; //getalignwidgets + +var + int1,int2,int3,int4: integer; + ar1: widgetarty; + size1: sizety; +// outerwidth1: int32; +// bo1: boolean; + i1,i2: int32; +begin + if (componentstate * [csloading,csdestroying] = []) and + (flayoutupdating = 0) then begin + for int1:= 0 to high(fwidgets) do begin + if csloading in fwidgets[int1].componentstate then begin + delayedupdatelayout(); + exit; + end; + end; + if canevent(tmethod(fonbeforelayout)) then begin + fonbeforelayout(self); + end; + checkwidgetinfo(); + inc(flayoutupdating); + try + updateoptionsscale; + beginscaling; + if widgetcount > 0 then begin + for i1:= 0 to high(fwidgetinfos) do begin + with fwidgetinfos[i1],twidget1(widget) do begin + layoutplacingbefore:= ws1_layoutplacing in fwidgetstate1; + include(fwidgetstate1,ws1_layoutplacing); + end; + end; + if (foptionslayout*[lao_placex,lao_placey] <> []) and + (plo_scalesize in fplace_options) then begin + //scale to variable clientsize + size1:= scalesizeref; + if lao_placex in foptionslayout then begin + for int1:= high(fwidgetinfos) downto 0 do begin + with fwidgetinfos[int1] do begin + if not (osk_nopropwidth in widget.optionsskin) and + (refscalesize.cx <> 0) then begin + with twidget1(widget) do begin +// bo1:= ws1_layoutplacing in fwidgetstate1; +// try +// include(fwidgetstate1,ws1_layoutplacing); + i1:= (scalesize.cx * size1.cx) div refscalesize.cx; + i2:= curminsize.cx; + if i1 < i2 then begin + i1:= i2; + end; + widget.width:= i1; + actscalesize.cx:= widget.width; +// finally +// if not bo1 then begin +// exclude(fwidgetstate1,ws1_layoutplacing); +// end; +// end; + end; + end; + end; + end; + end + else begin + for int1:= high(fwidgetinfos) downto 0 do begin + with fwidgetinfos[int1] do begin + if not (osk_nopropheight in widget.optionsskin) and + (refscalesize.cy <> 0) then begin + with twidget1(widget) do begin +// bo1:= ws1_layoutplacing in fwidgetstate1; +// try +// include(fwidgetstate1,ws1_layoutplacing); + i1:= (scalesize.cy * size1.cy) div refscalesize.cy; + i2:= minshrinksize().cy; + if i1 < i2 then begin + i1:= i2; + end; + widget.height:= i1; + actscalesize.cy:= widget.height; +// finally +// if not bo1 then begin +// exclude(fwidgetstate1,ws1_layoutplacing); +// end; +// end; + end; + end; + end; + end; + end; + end; + if lao_syncmaxautosize in foptionslayout then begin + syncmaxautosize(fwidgets); + end; + if lao_syncpaintwidth in foptionslayout then begin + int1:= -1; + if (lao_alignx in foptionslayout) and + (falign_glue in [wam_start,wam_end]) then begin + int1:= innerclientsize.cx; + end; + syncpaintwidth(fwidgets,int1); + end; + if lao_syncpaintheight in foptionslayout then begin + int1:= -1; + if (lao_aligny in foptionslayout) and + (falign_glue in [wam_start,wam_end]) then begin + int1:= innerclientsize.cy; + end; + syncpaintheight(fwidgets); + end; + if lao_synccaptiondistx in foptionslayout then begin + synccaptiondistx(fwidgets); + end; + if lao_synccaptiondisty in foptionslayout then begin + synccaptiondisty(fwidgets); + end; + if lao_alignx in foptionslayout then begin + if (align_mode <> wam_none) or (align_glue <> wam_none) then begin + ar1:= getalignwidgets(true); + int2:= 0; + case falign_glue of + wam_start: begin + int2:= innerclientpos.x; + end; + wam_end: begin + int2:= clientwidth - (innerclientpos.x + innerclientsize.cx); + end; + else begin //wam_center + with innerclientframe do begin + int2:= right-left; + end; + end; + end; + alignx(align_mode,ar1,align_glue,int2); + end; + end; + if lao_aligny in foptionslayout then begin + if (align_mode <> wam_none) or (align_glue <> wam_none) then begin + ar1:= getalignwidgets(false); + int2:= 0; + case falign_glue of + wam_start: begin + int2:= innerclientpos.y; + end; + wam_end: begin + int2:= clientheight - (innerclientpos.y + innerclientsize.cy); + end; + else begin //wam_center + with innerclientframe do begin + int2:= bottom-top; + end; + end; + end; + aligny(align_mode,ar1,align_glue,int2); + end; + end; + if (fplace_mode <> wam_none) and + (foptionslayout * [lao_placex,lao_placey] <> []) then begin + if plo_noinvisible in fplace_options then begin + ar1:= getvisiblewidgets; + end + else begin + ar1:= copy(fwidgets); + end; + if lao_placex in foptionslayout then begin + sortwidgetsxorder(ar1,self); + int4:= childrenwidth; + calcarray(ar1,innerclientsize.cx - int4,fplace_mindist,fplace_maxdist); + if plo_endmargin in fplace_options then begin + placexorder(innerclientpos.x + margin,ar2,ar1, + innerclientframe.right + margin); + end + else begin + case fplace_mode of + wam_start: begin + int3:= innerclientpos.x + margin; + end; + wam_center: begin + int3:= innerclientpos.x + (innerclientsize.cx - int4 - space) div 2; + end; + wam_end: begin + int3:= innerclientpos.x + innerclientsize.cx - int4 - space - margin; + end; + end; + placexorder(int3,ar2,ar1); + end; + end; + if (lao_placey in foptionslayout) and (fplace_mode <> wam_none) then begin + sortwidgetsyorder(ar1,self); + int4:= childrenheight; + calcarray(ar1,innerclientsize.cy - int4,fplace_mindist,fplace_maxdist); + if plo_endmargin in fplace_options then begin + placeyorder(innerclientpos.y + margin,ar2,ar1, + innerclientframe.bottom + margin); + end + else begin + case fplace_mode of + wam_start: begin + int3:= innerclientpos.y + margin; + end; + wam_center: begin + int3:= innerclientpos.y + (innerclientsize.cy - int4 - space) div 2; + end; + wam_end: begin + int3:= innerclientpos.y + innerclientsize.cy - int4 - space - margin; + end; + end; + placeyorder(int3,ar2,ar1); + end; + end; + end; + end; + finally + for i1:= 0 to high(fwidgetinfos) do begin + with fwidgetinfos[i1],twidget1(widget) do begin + if not layoutplacingbefore then begin + exclude(fwidgetstate1,ws1_layoutplacing); + end; + end; + end; + endscaling; + dec(flayoutupdating); + end; + if canevent(tmethod(fonafterlayout)) then begin + fonafterlayout(self); + end; + end; +end; + +procedure tcustomlayouter.readstate(reader: treader); +begin + inherited; + ttaborderoverride1(ftaborderoverride).endread(reader); +end; + +procedure tcustomlayouter.updatescalesizeref; +var + int1,int3: integer; + sum: sizety; + bo1: boolean; +begin + include(fstate,las_scalesizerefvalid); + if plo_scalesize in fplace_options then begin + if foptionslayout * [lao_placex,lao_placey] <> [] then begin + if las_scalesizerefset in fstate then begin + checkwidgetinfo(); //store initial values set in loaded state + end; + fscalesizeref:= innerclientsize; + sum:= nullsize; + if not (plo_scalefullref in fplace_options) then begin + bo1:= not (plo_noinvisible in fplace_options); + for int1:= 0 to high(fwidgets) do begin + with widgets[int1] do begin + if (bo1 or visible) then begin + if osk_nopropwidth in optionsskin then begin + addsize1(sum,size); + end + else begin +// addsize1(sum,framedim); + end; + end + else begin + end; + end; + end; + if bo1 then begin + int3:= length(fwidgets); + end + else begin + int3:= 0; + for int1:= 0 to high(fwidgets) do begin + if fwidgets[int1].visible then begin + inc(int3); + end; + end; + end; + if not (plo_propmargin in fplace_options) then begin + dec(int3); + end; + subsize1(fscalesizeref,sum); + if int3 > 0 then begin + int3:= int3 * fplace_mindist; + fscalesizeref.cx:= fscalesizeref.cx - int3; + fscalesizeref.cy:= fscalesizeref.cy - int3; + end; + end; + fscalesizeextension.cx:= fwidgetrect.cx - fscalesizeref.cx; + fscalesizeextension.cy:= fwidgetrect.cy - fscalesizeref.cy; + include(fstate,las_scalesizerefset); + checkwidgetinfo(); //store initial values + end; + end; +end; + +function tcustomlayouter.calcminscrollsize: sizety; +var + int1,int2,int3,int4: integer; +begin + result:= inherited calcminscrollsize; + if lao_placex in foptionslayout then begin + result.cx:= childrenminwidth; + end; + if lao_placey in foptionslayout then begin + result.cy:= childrenminheight; + end; + if (high(fwidgets) >= 0) and (align_glue <> wam_none) and + (align_mode <> wam_none)then begin + int2:= -bigint; + int3:= bigint; + if lao_alignx in foptionslayout then begin + for int1:= 0 to high(fwidgets) do begin + with fwidgets[int1] do begin + if isvisible or + (ow1_invisibleparentsizeextend in foptionswidget1) then begin + with fwidgetrect do begin + if x < int3 then begin + int3:= x; + end; + int4:= x + cx; + if int4 > int2 then begin + int2:= int4; + end; + end; + end; + end; + end; + if int2 > int3 then begin + int2:= int2-int3; + end + else begin + int2:= 0; + end; + int2:= int2 + innerframewidth.cx; + if int2 < bounds_cxmin then begin + int2:= bounds_cxmin; + end; + result.cx:= int2; + end; + if lao_aligny in foptionslayout then begin + for int1:= 0 to high(fwidgets) do begin + with fwidgets[int1] do begin + if isvisible or + (ow1_invisibleparentsizeextend in foptionswidget1) then begin + with fwidgetrect do begin + if y < int3 then begin + int3:= y; + end; + int4:= y + cy; + if int4 > int2 then begin + int2:= int4; + end; + end; + end; + end; + end; + if int2 > int3 then begin + int2:= int2-int3; + end + else begin + int2:= 0; + end; + int2:= int2 + innerframewidth.cy; + if int2 < bounds_cymin then begin + int2:= bounds_cymin; + end; + result.cy:= int2; + end; + end; +end; + +procedure tcustomlayouter.loaded; +begin + inherited; + updatelayout; +end; + +procedure tcustomlayouter.fontchanged; +begin + inherited; + if flayoutupdating = 0 then begin + ffontheightref:= getfont.height; +// if ffontheightref = 0 then begin +// ffontheightref:= font.glyphheight; +// end; + ffontxscaleref:= getfont.xscale; + ffontsizeref:= clientsize; + end; +end; + +procedure tcustomlayouter.childclientrectchanged(const sender: twidget); +var + int1: integer; +begin + inherited; + if not (las_propsizing in fstate) then begin + int1:= widgetinfoindex(sender); + if int1 >= 0 then begin + updatewidgetinfo(fwidgetinfos[int1],sender); + end; + end; +end; + +procedure tcustomlayouter.widgetregionchanged(const sender: twidget); +var + int1: integer; +begin + inherited; + if not (csloading in componentstate) then begin + if not (las_propsizing in fstate) then begin + int1:= widgetinfoindex(sender); + if int1 >= 0 then begin + updatewidgetinfo(fwidgetinfos[int1],sender); + end; + end; + if not (ws_loadedproc in fwidgetstate) then begin + scalesizerefchanged; + if (flayoutupdating = 0) and (plo_scalesize in fplace_options) and + (sender.optionsskin * [osk_nopropwidth,osk_nopropheight] <> []) then begin + scalebasechanged(sender); + end; + updatelayout; + end; + end; +end; + +procedure tcustomlayouter.setalign_mode(const avalue: widgetalignmodety); +begin + if avalue <> falign_mode then begin + falign_mode:= avalue; + updatelayout; + end; +end; + +procedure tcustomlayouter.setalign_glue(const avalue: widgetalignmodety); +begin + if falign_glue <> avalue then begin + falign_glue:= avalue; + updatelayout; + end; +end; + +procedure tcustomlayouter.setalign_leader(const avalue: twidget); +begin + if falign_leader <> avalue then begin + setlinkedvar(avalue,tmsecomponent(falign_leader)); + updatelayout; + end; +end; + +procedure tcustomlayouter.setplace_mindist(const avalue: integer); +begin + if fplace_mindist <> avalue then begin + fplace_mindist:= avalue; + scalebasechanged(nil); + updatelayout; + end; +end; + +procedure tcustomlayouter.setplace_maxdist(const avalue: integer); +begin + if fplace_maxdist <> avalue then begin + fplace_maxdist:= avalue; + updatelayout; + end; +end; + +procedure tcustomlayouter.setplace_mode(const avalue: widgetalignmodety); +begin + if fplace_mode <> avalue then begin + fplace_mode:= avalue; + updatelayout; + end; +end; + +procedure tcustomlayouter.setplace_options(avalue: placeoptionsty); +var + diff1: placeoptionsty; +begin + if (csreading in componentstate) and + (avalue * deprecatedplaceoptions <> []) then begin + optionslayout:= optionslayout + + layoutoptionsty(card32(avalue * deprecatedplaceoptions) shl + (ord(lao_syncmaxautosize) - ord(plo_syncmaxautosize))); + end; + avalue:= avalue - deprecatedplaceoptions; + diff1:= fplace_options >< avalue; + if diff1 <> [] then begin + fplace_options:= avalue; + if diff1 * [plo_scalesize,plo_scalefullref,plo_noinvisible] <> [] then begin + exclude(fstate,las_scalesizerefvalid); + if plo_scalesize in fplace_options then begin + scalebasechanged(nil); + end; + end; + updatelayout(); + end; +end; + +procedure tcustomlayouter.clientrectchanged; +var + refsi: sizety; + pt1: pointty; + size1: sizety; + int1: integer; +begin + inc(flayoutupdating); + try + inherited; + exclude(fstate,las_scalesizerefvalid); + if componentstate * [csloading,csdestroying] = [] then begin + if (foptionslayout * [lao_scalewidth,lao_scaleheight,lao_scalefont, + lao_scalechildfont] <> []) and + not (las_propsizing in fstate) then begin + beginscaling; + include(fstate,las_propsizing); + try + if (lao_scalefont in foptionslayout) and (ffontsizeref.cx <> 0) and + (ffontsizeref.cy <> 0) then begin + font.height:= round((ffontheightref*clientheight)/ffontsizeref.cy); + if clientheight > 0 then begin + font.xscale:= (ffontxscaleref * (clientwidth/ffontsizeref.cx))/ + (clientheight/ffontsizeref.cy); + end; + end; + if foptionslayout * + [lao_scalewidth,lao_scaleheight,lao_scalefont] <> [] then begin + refsi:= innerclientsize; + for int1:= high(fwidgetinfos) downto 0 do begin + with fwidgetinfos[int1] do begin + if (lao_scalechildfont in foptionslayout) and + not (osk_nopropfont in widget.optionsskin) and + (twidget1(widget).ffont <> nil) and + (reffontsize.cx <> 0) and (reffontsize.cy <> 0) and + (refsi.cy > 0) then begin + twidget1(widget).ffont.height:= + round(fontheight * refsi.cy / reffontsize.cy); + twidget1(widget).ffont.xscale:= (fontxscale * (refsi.cx/refsi.cy))/ + (reffontsize.cx/reffontsize.cy); + end; + pt1:= widget.pos; + size1:= widget.clientsize; + if refsize.cx <> 0 then begin + if (lao_scaleleft in foptionslayout) and + not (osk_nopropleft in widget.optionsskin) then begin + pt1.x:= (pos.x * refsi.cx) div refsize.cx; + end; + if (lao_scalewidth in foptionslayout) and + not (osk_nopropwidth in widget.optionsskin) then begin + size1.cx:= (size.cx * refsi.cx) div refsize.cx; + end; + end; + if refsize.cy <> 0 then begin + if (lao_scaletop in foptionslayout) and + not (osk_noproptop in widget.optionsskin) then begin + pt1.y:= (pos.y * refsi.cy) div refsize.cy; + end; + if (lao_scaleheight in foptionslayout) and + not (osk_nopropheight in widget.optionsskin) then begin + size1.cy:= (size.cy * refsi.cy) div refsize.cy; + end; + end; + widget.clientsize:= size1; + widget.pos:= pt1; + end; + end; + end; + finally + exclude(fstate,las_propsizing); + endscaling; + end; + end; + end; + finally + dec(flayoutupdating); + end; + updatelayout; +end; + +procedure tcustomlayouter.childautosizechanged(const sender: twidget); +begin + inherited; + updatelayout; +end; + +procedure tcustomlayouter.registerchildwidget(const child: twidget); +begin + setlength(fwidgetinfos,high(fwidgetinfos)+2); + updatewidgetinfo(fwidgetinfos[high(fwidgetinfos)],child); + inherited; +end; + +procedure tcustomlayouter.unregisterchildwidget(const child: twidget); +var + int1: integer; +begin + if not (csdestroying in componentstate) then begin + int1:= widgetinfoindex(child); + if int1 >= 0 then begin + finalize(fwidgetinfos[int1]); + move(fwidgetinfos[int1+1],fwidgetinfos[int1], + (high(fwidgetinfos)-int1)*sizeof(widgetlayoutinfoty)); + setlength(fwidgetinfos,high(fwidgetinfos)); + end; + end; + inherited; +end; + +function tcustomlayouter.widgetinfoindex(const awidget: twidget): integer; +var + int1: integer; +begin + result:= -1; + for int1:= high(fwidgetinfos) downto 0 do begin + if fwidgetinfos[int1].widget = awidget then begin + result:= int1; + break; + end; + end; +end; + +procedure tcustomlayouter.updatewidgetinfo(var ainfo: widgetlayoutinfoty; + const awidget: twidget; const force: boolean = false); +var + size1,size2: sizety; + int1: integer; + rea1: real; +begin + with ainfo do begin + if awidget <> nil then begin + widget:= awidget; + end; + if not (csloading in componentstate) then begin +// size1:= widget.clientsize; + with twidget1(widget) do begin + curminsize:= minshrinksize(); +// if fframe <> nil then begin +// subsize1(curminsize,fframe.outerframedim); +// end; + end; + size1:= widget.size; + if (flayoutupdating = 0) or force then begin + //synchronize ref values with changed widget values + size2:= self.scalesizeref; + if size1.cx <> actscalesize.cx then begin + refscalesize.cx:= size2.cx; + scalesize.cx:= size1.cx; + actscalesize.cx:= scalesize.cx; + end; + if size1.cy <> actscalesize.cy then begin + refscalesize.cy:= size2.cy; + scalesize.cy:= size1.cy; + actscalesize.cy:= scalesize.cy; + end; + end; + size2:= innerclientsize; + if widget.bounds_x <> actpos.x then begin + refsize.cx:= size2.cx; + pos.x:= widget.bounds_x; + actpos.x:= pos.x; + end; + if widget.bounds_y <> actpos.y then begin + refsize.cy:= size2.cy; + pos.y:= widget.bounds_y; + actpos.y:= pos.y; + end; + if size1.cx <> actsize.cx then begin + refsize.cx:= size2.cx; + size.cx:= size1.cx; + actsize.cx:= size1.cx; + end; + if size1.cy <> actsize.cy then begin + refsize.cy:= size2.cy; + size.cy:= size1.cy; + actsize.cy:= size1.cy; + end; + if twidget1(widget).ffont <> nil then begin + int1:= twidget1(widget).ffont.height; + rea1:= twidget1(widget).ffont.xscale; + if (int1 <> actfontheight) or (rea1 <> actfontxscale) then begin + reffontsize:= size2; + fontheight:= int1; + actfontheight:= int1; + fontxscale:= rea1; + actfontxscale:= rea1; + end; + end; + end; + end; +end; + +function tcustomlayouter.scalesizeref: sizety; +begin + if not (las_scalesizerefvalid in fstate) then begin + updatescalesizeref; + end; + result:= fscalesizeref; +end; + +procedure tcustomlayouter.scalesizerefchanged; +begin + if (componentstate * [csloading,csdestroying] = []) and + (flayoutupdating = 0) then begin + exclude(fstate,las_scalesizerefvalid); + end; +end; + +procedure tcustomlayouter.scalebasechanged(const sender: twidget); +var + int1: integer; + size1: sizety; +begin + if not (csloading in componentstate) then begin + scalesizerefchanged; + size1:= scalesizeref; + for int1:= high(fwidgetinfos) downto 0 do begin + with fwidgetinfos[int1] do begin +// scalesize:= widget.clientsize; + scalesize:= widget.size; + actscalesize:= scalesize; + refscalesize:= size1; + end; + end; + end; +end; + +const + updatelayouttag = 8436026; + +procedure tcustomlayouter.delayedupdatelayout; +begin + if not (las_delayedupdatelayoutpending in fstate) then begin + include(fstate,las_delayedupdatelayoutpending); + asyncevent(updatelayouttag,[peo_local,peo_first]); + //before childscaled events + end; +end; + +procedure tcustomlayouter.doasyncevent(var atag: integer); +begin + inherited; + if atag = updatelayouttag then begin + exclude(fstate,las_delayedupdatelayoutpending); + updatelayout(); + end; +end; + +{ texpandingwidget } + +constructor texpandingwidget.create(aowner: tcomponent); +begin + inherited; + foptionswidget:= defaultgroupboxoptionswidget; +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/msetabs.pas b/mseide-msegui/lib/common/widgets/msetabs.pas new file mode 100644 index 0000000..22e84a5 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msetabs.pas @@ -0,0 +1,5524 @@ +{ MSEgui Copyright (c) 1999-2017 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msetabs; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} + +interface +uses + msetabsglob,msewidgets,mseclasses,msearrayprops,classes,mclasses,mseshapes, + mserichstring,msetypes,msegraphics,msegraphutils,mseevent,mseinterfaces, + mseglob,mseguiglob,msegui,msebitmap,msedragglob, + {mseforms,}rtlconsts,msesimplewidgets,msedrag,mseact, + mseobjectpicker,msepointer,msestat,msestatfile,msestrings,msemenus, + msedrawtext,msetimer; + +const + defaulttaboptionswidget = defaultoptionswidgetmousewheel + + [ow_subfocus{,ow_fontglyphheight}]; + defaulttaboptionsskin = defaultoptionsskin + [osk_colorcaptionframe]; + defaultcaptiondist = 1; + defaultimagedist = 0; + defaulttabshift = -100; //-> 1 + defaultedgelevel = -100; //-> -1 + defaultimagepos = ip_right; + defaulttabpageskinoptions = defaultcontainerskinoptions; + defaultoptionswidgettab = defaultoptionswidgetnofocus; + defaultoptionswidget1tab = [ow1_autoheight]; + defaultcolortab = cl_transparent; + defaultcoloractivetab = cl_active; + +type + tcustomtabbar = class; + tabstatety = (ts_invisible,ts_disabled,ts_active,ts_updating,ts_captionclipped, + ts_noface); + tabstatesty = set of tabstatety; + + ttabfont = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + ttabfontactive = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + ttab = class(tindexpersistent,iimagelistinfo) + private + frichcaption: richstringty; + fcaption: msestring; + fhint: msestring; + fstate: tabstatesty; + fcolor: colorty; + fcoloractive: colorty; + fident: integer; + fimagelist: timagelist; + fimagenr: imagenrty; + fimagenrdisabled: imagenrty; +// function getcaption: captionty; + fface: tfacecomp; + ffaceactive: tfacecomp; + procedure setcaption(const avalue: captionty); + procedure changed; + procedure setstate(const Value: tabstatesty); + procedure setcolor(const Value: colorty); + procedure setcoloractive(const Value: colorty); + function getactive: boolean; + procedure setactive(const Value: boolean); + procedure setimagelist(const avalue: timagelist); + procedure setimagenr(const avalue: imagenrty); + procedure setimagenrdisabled(const avalue: imagenrty); + function getimagelist: timagelist; + function getfont: ttabfont; + procedure setfont(const avalue: ttabfont); + function isfontstored: boolean; + function getfontactive: ttabfontactive; + procedure setfontactive(const avalue: ttabfontactive); + function isfontactivestored: boolean; + procedure setface(const avalue: tfacecomp); + procedure setfaceactive(const avalue: tfacecomp); + protected + ftag: integer; + ffont: ttabfont; + ffontactive: ttabfontactive; + procedure fontchanged(const sender: tobject); + procedure execute(const tag: integer; const info: mouseeventinfoty); + procedure doshortcut(var info: keyeventinfoty; const sender: twidget); + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + public + constructor create(const aowner: tcustomtabbar); reintroduce; + destructor destroy; override; + procedure createfont; + procedure createfontactive; + function tabbar: tcustomtabbar; + property ident: integer read fident; + property active: boolean read getactive write setactive; + published + property caption: captionty read fcaption write setcaption; + property state: tabstatesty read fstate write setstate default []; + property color: colorty read fcolor write setcolor default cl_default; + property coloractive: colorty read fcoloractive + write setcoloractive default cl_default; + property face: tfacecomp read fface write setface; + property faceactive: tfacecomp read ffaceactive write setfaceactive; + property font: ttabfont read getfont write setfont stored isfontstored; + property fontactive: ttabfontactive read getfontactive write setfontactive + stored isfontactivestored; + property imagelist: timagelist read fimagelist write setimagelist; + property imagenr: imagenrty read fimagenr write setimagenr default -1; + property imagenrdisabled: imagenrty read fimagenrdisabled + write setimagenrdisabled default -2; + //-2 -> same as imagenr + property tag: integer read ftag write ftag default 0; + property hint: msestring read fhint write fhint; + end; + tabarty = array of ttab; + tabaty = array[0..0] of ttab; + ptabaty = ^tabaty; + + ttabs = class; + + createtabeventty = procedure(const sender: tcustomtabbar; const index: integer; + var tab: ttab) of object; + + ttabframe = class(tframe) + public + constructor create(const aintf: iframe); + published + property framei_left default defaultcaptiondist; + property framei_top default defaultcaptiondist; + property framei_right default defaultcaptiondist; + property framei_bottom default defaultcaptiondist; + property imagedist default defaultimagedist; + end; + + ttabsfont = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + ttabsfontactive = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + ttabs = class(tindexpersistentarrayprop,iframe) + private + fcolor: colorty; + fcoloractive: colorty; + fimagepos: imageposty; +// fcaptionframe: framety; +// fimagedist: integer; + fframe: ttabframe; + fface: tface; + ffaceactive: tface; + fhint: msestring; + foncreatetab: createtabeventty; + factcellindex: integer; + ftabshift: integer; + fshift: integer; + ftextflags: textflagsty; + fwidth: integer; + fwidthmin: integer; + fwidthmax: integer; + fedge_level: int32; + fedge: edgecolorpairinfoty; + fedge_imagelist: timagelist; + fedge_imageoffset: int32; + fedge_imagepaintshift: int32; + procedure setitems(const index: integer; const Value: ttab); + function getitems(const index: integer): ttab; reintroduce; + function getface: tface; + procedure setface(const avalue: tface); + function getfaceactive: tface; + procedure setfaceactive(const avalue: tface); + procedure setcolor(const avalue: colorty); + procedure setcoloractive(const avalue: colorty); + procedure setimagepos(const avalue: imageposty); + { + procedure setcaptionframe_left(const avalue: integer); + procedure setcaptionframe_top(const avalue: integer); + procedure setcaptionframe_right(const avalue: integer); + procedure setcaptionframe_bottom(const avalue: integer); + procedure setimagedist(const avalue: integer); + } + function getframe: ttabframe; + procedure setframe(const avalue: ttabframe); + procedure setshift(const avalue: integer); + function getfont: ttabsfont; + procedure setfont(const avalue: ttabsfont); + function isfontstored: boolean; + function getfontactive: ttabsfontactive; + procedure setfontactive(const avalue: ttabsfontactive); + function isfontactivestored: boolean; + procedure readcaptionpos(reader: treader); + procedure readcaptionframe_left(reader: treader); + procedure readcaptionframe_top(reader: treader); + procedure readcaptionframe_right(reader: treader); + procedure readcaptionframe_bottom(reader: treader); + procedure readimagedist(reader: treader); + procedure settextflags(const avalue: textflagsty); + procedure setwidth(const avalue: integer); + procedure setwidthmin(const avalue: integer); + procedure setwidthmax(const avalue: integer); + procedure setedge_level(const avalue: int32); + procedure setedge_colordkshadow(const avalue: colorty); + procedure setedge_colorshadow(const avalue: colorty); + procedure setedge_colorlight(const avalue: colorty); + procedure setedge_colorhighlight(const avalue: colorty); + procedure setedge_colordkwidth(const avalue: int32); + procedure setedge_colorhlwidth(const avalue: int32); + procedure setedge_imagelist(const avalue: timagelist); + procedure setedge_imageoffset(const avalue: int32); + procedure setedge_imagepaintshift(const avalue: int32); + protected + fskinupdating: integer; + ffont: ttabsfont; + ffontactive: ttabsfontactive; + procedure defineproperties(filer: tfiler); override; + procedure changed; + procedure fontchanged(const sender: tobject); + procedure createitem(const index: integer; var item: tpersistent); override; + procedure dochange(const index: integer); override; + procedure checktemplate(const sender: tobject); + //iframe + procedure setframeinstance(instance: tcustomframe); + procedure setstaticframe(value: boolean); + function getstaticframe: boolean; + function getwidgetrect: rectty; + function getcomponentstate: tcomponentstate; + function getmsecomponentstate: msecomponentstatesty; + procedure scrollwidgets(const dist: pointty); + procedure clientrectchanged; + procedure invalidate; + procedure invalidatewidget; + procedure invalidaterect(const rect: rectty; const org: originty = org_client; + const noclip: boolean = false); + function getwidget: twidget; + function getframestateflags: framestateflagsty; virtual; + function getedgeshift(): int32; + public + constructor create(const aowner: tcustomtabbar; + aclasstype: indexpersistentclassty); reintroduce; + destructor destroy; override; + class function getitemclasstype: persistentclassty; override; + procedure createfont; + procedure createfontactive; + procedure createframe; + procedure createface; + procedure createfaceactive; + procedure add(const item: ttab); + procedure insert(const item: ttab; const aindex: integer); + procedure additems(const aitems: msestringarty); + function indexof(const item: ttab): integer; + property items[const index: integer]: ttab read getitems write setitems; default; + property oncreatetab: createtabeventty read foncreatetab write foncreatetab; + published + property color: colorty read fcolor + write setcolor default cl_default; + property coloractive: colorty read fcoloractive + write setcoloractive default cl_default; + property font: ttabsfont read getfont write setfont stored isfontstored; + property fontactive: ttabsfontactive read getfontactive write setfontactive + stored isfontactivestored; + + property width: integer read fwidth write setwidth default 0; + property widthmin: integer read fwidthmin write setwidthmin default 0; + property widthmax: integer read fwidthmax write setwidthmax default 0; + property textflags: textflagsty read ftextflags write settextflags + default defaultcaptiontextflags; + property imagepos: imageposty read fimagepos write + setimagepos default defaultimagepos; +{ + property captionframe_left: integer read fcaptionframe.left write + setcaptionframe_left default defaultcaptiondist; + property captionframe_top: integer read fcaptionframe.top write + setcaptionframe_top default defaultcaptiondist; + property captionframe_right: integer read fcaptionframe.right write + setcaptionframe_right default defaultcaptiondist; + property captionframe_bottom: integer read fcaptionframe.bottom write + setcaptionframe_bottom default defaultcaptiondist; + property imagedist: integer read fimagedist write setimagedist + default defaultimagedist; +} + property shift: integer read fshift write setshift default defaulttabshift; + //defaulttabshift (-100) -> 1 + property edge_level: int32 read fedge_level write setedge_level + default defaultedgelevel; + //defaultedgelevel (-100) -> -1 + property edge_colordkshadow: colorty read fedge.shadow.effectcolor + write setedge_colordkshadow default cl_default; + property edge_colorshadow: colorty read fedge.shadow.color + write setedge_colorshadow default cl_default; + property edge_colorlight: colorty read fedge.light.color + write setedge_colorlight default cl_default; + property edge_colorhighlight: colorty read fedge.light.effectcolor + write setedge_colorhighlight default cl_default; + property edge_colordkwidth: int32 read fedge.shadow.effectwidth + write setedge_colordkwidth default -1; + //-1 = default + property edge_colorhlwidth: int32 read fedge.light.effectwidth + write setedge_colorhlwidth default -1; + //-1 = default + property edge_imagelist: timagelist read fedge_imagelist + write setedge_imagelist; + //imagenr 0 -> startpoint, 1 -> edge, imagenr 2 -> endpoint + property edge_imageoffset: int32 read fedge_imageoffset + write setedge_imageoffset default 0; + property edge_imagepaintshift: int32 read fedge_imagepaintshift + write setedge_imagepaintshift default 0; + + property frame: ttabframe read getframe write setframe; + //frameimage_offset1 active for first tab + property face: tface read getface write setface; + property faceactive: tface read getfaceactive write setfaceactive; + property hint: msestring read fhint write fhint; + end; + + tabbarlayoutinfoty = record + tabs: ttabs; + dim: rectty; + captionframe: framety; + totsize: sizety; + activetab: integer; + focusedtab: integer; + cells: shapeinfoarty; + firsttab: integer; + lasttab: integer; + notfull: boolean; + stepinfo: framestepinfoty; + options: shapestatesty; + end; + + movingeventty = procedure(const sender: tobject; var curindex: integer; + var newindex: integer) of object; + movedeventty = procedure(const sender: tobject; const curindex: integer; + const newindex: integer) of object; + tabschangedeventty = procedure(const synctabindex: boolean) of object; + + tabbarstatety = (tbs_layoutvalid,tbs_designdrag,tbs_shrinktozero, + tbs_updatesizing,tbs_repeatup); + tabbarstatesty = set of tabbarstatety; + + tcustomtabbar = class(tcustomstepbox) + private + flayoutinfo: tabbarlayoutinfoty; + fhintedbutton: integer; + fonactivetabchange: notifyeventty; + fupdating: integer; + finternaltabchange: tabschangedeventty; + fontabmoving: movingeventty; + fontabmoved: movedeventty; + fonclientmouseevent: mouseeventty; + frepeater: trepeater; + procedure settabs(const Value: ttabs); + procedure layoutchanged; + procedure checklayout; + procedure updatelayout(); + function getactivetab: integer; + procedure setactivetab(const Value: integer); + procedure tabschanged(const sender: tarrayprop; const index: integer); + procedure setfirsttab(Value: integer); + procedure setoptions(const avalue: tabbaroptionsty); + function gethintpos(const aindex: integer): rectty; + function getbuttonhint(const aindex: integer): msestring; + procedure repeatproc(const sender: tobject); + procedure startrepeater(const up: boolean); + procedure killrepeater(); + protected + fstate: tabbarstatesty; + foptions: tabbaroptionsty; + class function classskininfo: skininfoty; override; + function dostep(const event: stepkindty; const adelta: real; + ashiftstate: shiftstatesty): boolean; override; + procedure doactivetabchanged; + procedure tabchanged(const sender: ttab); + procedure tabclicked(const sender: ttab; const info: mouseeventinfoty); + procedure enabledchanged; override; + procedure loaded; override; + procedure dopaintforeground(const canvas: tcanvas); override; + procedure clientmouseevent(var info: mouseeventinfoty); override; + procedure statechanged; override; + procedure fontchanged; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; + procedure clientrectchanged; override; + procedure getautopaintsize(var asize: sizety); override; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + procedure dokeydown(var info: keyeventinfoty); override; + function upstep(const norotate: boolean): boolean; + function downstep(const norotate: boolean): boolean; + //iassistiveclient + function getassistivecaption(): msestring; override; + function getassistivehint(): msestring; override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure synctofontheight; override; + procedure beginupdate; + procedure endupdate; + function tabatpos(const apos: pointty; const enabledonly: boolean = false): integer; + procedure movetab(curindex,newindex: integer); + function activetag: integer; //0 if no activetab, activetab.tag otherwise + procedure dragevent(var info: draginfoty); override; + property activetab: integer read getactivetab write setactivetab; + property tabs: ttabs read flayoutinfo.tabs write settabs; + property firsttab: integer read flayoutinfo.firsttab write setfirsttab default 0; + property onactivetabchange: notifyeventty read fonactivetabchange + write fonactivetabchange; + property font: twidgetfont read getfont write setfont stored isfontstored; + property options: tabbaroptionsty read foptions write setoptions default []; + property ontabmoving: movingeventty read fontabmoving write fontabmoving; + property ontabmoved: movedeventty read fontabmoved write fontabmoved; + property onclientmouseevent: mouseeventty read fonclientmouseevent write fonclientmouseevent; + published + property optionswidget default defaultoptionswidgettab; + property optionswidget1 default defaultoptionswidget1tab; + end; + + tcustomtabbar1 = class(tcustomtabbar) + protected + procedure internalcreateframe; override; + end; + + ttabbar = class(tcustomtabbar,istatfile) + private + fstatfile: tstatfile; + fstatvarname: msestring; + fstatpriority: integer; + procedure setstatfile(const Value: tstatfile); + procedure setdragcontroller(const Value: tdragcontroller); + protected + //istatfile + procedure dostatread(const reader: tstatreader); + procedure dostatwrite(const writer: tstatwriter); + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + published + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read getstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + property onstep; + property tabs; + property firsttab; + property onactivetabchange; + property ontabmoving; + property ontabmoved; + property onclientmouseevent; + property font; + property options; + property drag: tdragcontroller read fdragcontroller write setdragcontroller; + end; + + tcustomtabwidget = class; + + itabpage = interface(inullinterface)[miid_itabpage] + procedure settabwidget(const value: tcustomtabwidget); + function gettabwidget: tcustomtabwidget; + function getwidget: twidget; + function getcaption: msestring; + function gettabhint: msestring; + function gettabnoface: boolean; + function getcolortab: colorty; + function getcoloractivetab: colorty; + function getfacetab: tfacecomp; + function getfaceactivetab: tfacecomp; + function getfonttab: tfont; + function getfontactivetab: tfont; + function getimagelist: timagelist; + function getimagenr: imagenrty; + function getimagenrdisabled: imagenrty; + function getinvisible: boolean; + procedure setcolortab(const avalue: colorty); + procedure setcoloractivetab(const avalue: colorty); + procedure setfacetab(const avalue: tfacecomp); + procedure setfaceactivetab(const avalue: tfacecomp); + procedure setfonttab(const avalue: tfont); + procedure setfontactivetab(const avalue: tfont); + procedure doselect; + procedure dodeselect; + end; + + ttabpagefonttab = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + ttabpagefontactivetab = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + ttabpage = class; + getsubformeventty = procedure(const sender: ttabpage; + var submoduleclass: widgetclassty; + var instancevarpo: pwidget) of object; + initsubformeventty = procedure(const sender: ttabpage; + const asubform: twidget) of object; + + ttabpage = class(tscrollingwidget,itabpage,iimagelistinfo) + private + ftabwidget: tcustomtabwidget; + fcaption: msestring; + ftabhint: msestring; + ftabnoface: boolean; + fimagelist: timagelist; + fimagenr: integer; + fimagenrdisabled: integer; + fcolortab,fcoloractivetab: colorty; + fonselect: notifyeventty; + fondeselect: notifyeventty; + finvisible: boolean; + ffonttab: ttabpagefonttab; + ffontactivetab: ttabpagefontactivetab; + fongetsubform: getsubformeventty; + fsubform: twidget; + fsubforminstancevarpo: pwidget; + foninitsubform: initsubformeventty; + ffacetab: tfacecomp; + ffaceactivetab: tfacecomp; + ftaborderoverride: ttaborderoverride; + function getcaption: captionty; + procedure setcaption(const Value: captionty); + function gettabhint: msestring; + procedure settabhint(const avalue: msestring); + function gettabnoface: boolean; + procedure settabnoface(const avalue: boolean); + function getcolortab: colorty; + procedure setcolortab(const avalue: colorty); + function getcoloractivetab: colorty; + procedure setcoloractivetab(const avalue: colorty); + procedure settabwidget(const value: tcustomtabwidget); + function gettabwidget: tcustomtabwidget; + function gettabindex: integer; + procedure settabindex(const avalue: integer); + function getimagelist: timagelist; + procedure setimagelist(const avalue: timagelist); + function getimagenr: imagenrty; + procedure setimagenr(const avalue: imagenrty); + function getimagenrdisabled: imagenrty; + procedure setimagenrdisabled(const avalue: imagenrty); + function getinvisible: boolean; + procedure setinvisible(const avalue: boolean); + function getfonttab: tfont; + function getfontactivetab: tfont; + function getfonttab1: ttabpagefonttab; + procedure setfonttab1(const avalue: ttabpagefonttab); + procedure setfonttab(const avalue: tfont); + function isfonttabstored: boolean; + function getfontactivetab1: ttabpagefontactivetab; + procedure setfontactivetab1(const avalue: ttabpagefontactivetab); + procedure setfontactivetab(const avalue: tfont); + function isfontactivetabstored: boolean; + procedure setfacetab(const avalue: tfacecomp); + procedure setfaceactivetab(const avalue: tfacecomp); + function getfacetab: tfacecomp; + function getfaceactivetab: tfacecomp; + function isvisiblestored: boolean; + procedure settaborderoverride(const avalue: ttaborderoverride); + protected + class function classskininfo: skininfoty; override; + procedure changed; + procedure fontchanged1(const sender: tobject); + procedure visiblechanged; override; + procedure enabledchanged; override; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + procedure registerchildwidget(const child: twidget); override; + procedure designselected(const selected: boolean); override; + procedure doselect; virtual; + procedure dodeselect; virtual; + procedure loaded; override; + function getisactivepage: boolean; + procedure setisactivepage(const avalue: boolean); + function nexttaborderoverride(const sender: twidget; + const down: boolean): twidget override; + procedure readstate(reader: treader) override; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure initnewcomponent(const ascale: real); override; + procedure createfonttab; + procedure createfontactivetab; + property tabwidget: tcustomtabwidget read ftabwidget; + property tabindex: integer read gettabindex write settabindex; + property isactivepage: boolean read getisactivepage write setisactivepage; + property subform: twidget read fsubform; + published + property invisible: boolean read getinvisible + write setinvisible default false; + property taborderoverride: ttaborderoverride read ftaborderoverride + write settaborderoverride; + + property caption: captionty read getcaption write setcaption; + property tabhint: msestring read gettabhint write settabhint; + property tabnoface: boolean read gettabnoface + write settabnoface default false; + property colortab: colorty read getcolortab + write setcolortab default cl_default; + property coloractivetab: colorty read getcoloractivetab + write setcoloractivetab default cl_default; + property facetab: tfacecomp read getfacetab write setfacetab; + property faceactivetab: tfacecomp read getfaceactivetab + write setfaceactivetab; + property fonttab: ttabpagefonttab read getfonttab1 write setfonttab1 + stored isfonttabstored; + property fontactivetab: ttabpagefontactivetab read getfontactivetab1 + write setfontactivetab1 stored isfontactivetabstored; + property imagelist: timagelist read getimagelist write setimagelist; + property imagenr: imagenrty read getimagenr write setimagenr default -1; + property imagenrdisabled: imagenrty read getimagenrdisabled + write setimagenrdisabled default -2; + //-2 -> same as imagenr + property font: twidgetfont read getfont write setfont stored isfontstored; + property optionswidget default defaulttaboptionswidget; + property onlayout; + property onfontheightdelta; + property onshow; + property onhide; + property onselect: notifyeventty read fonselect write fonselect; + property ondeselect: notifyeventty read fondeselect write fondeselect; + property ongetsubform: getsubformeventty read fongetsubform + write fongetsubform; + property oninitsubform: initsubformeventty read foninitsubform + write foninitsubform; + property visible stored isvisiblestored default false; + property optionsskin default defaulttabpageskinoptions; + end; + + + tpagetab = class(ttab) + private + fpageintf: itabpage; + public + constructor create(const aowner: tcustomtabbar; const apage: itabpage); + function page: twidget; + end; + pagetabaty = array[0..0] of tpagetab; + ppagetabaty = ^pagetabaty; + + ttab_font = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + ttab_fonttab = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + ttab_fontactivetab = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + tcustomtabwidget = class(tactionwidget,iobjectpicker,istatfile) + private + fobjectpicker: tobjectpicker; + factivepageindex: integer; + factivepageindex1: integer; + fonactivepagechanged: notifyeventty; + fonpageadded: widgeteventty; + fonpageremoved: widgeteventty; + ftab_size: integer; + ftab_sizemin: integer; + ftab_sizemax: integer; + fstatfile: tstatfile; + fstatvarname: msestring; + fvisiblepage: integer; + fstatpriority: integer; + procedure setstatfile(const value: tstatfile); + function getitems(const index: integer): twidget; + function getitemsintf(const index: integer): itabpage; + function getactivepageindex: integer; + procedure setactivepageindex(value: integer); + procedure setactivepageindex1(const avalue: integer); + function getactivepage: twidget; + function getactivepageintf: itabpage; + procedure setactivepage(const value: twidget); + procedure updatesize(const page: twidget); + function gettab_options: tabbaroptionsty; + procedure settab_options(const avalue: tabbaroptionsty); + function gettab_color: colorty; + procedure settab_color(const avalue: colorty); + function gettab_frame: tstepboxframe1; + procedure settab_frame(const avalue: tstepboxframe1); + function gettab_face: tface; + procedure settab_face(const avalue: tface); + procedure settab_size(const avalue: integer); + procedure settab_sizemin(const avalue: integer); + procedure settab_sizemax(const avalue: integer); + function gettab_colortab: colorty; + procedure settab_colortab(const avalue: colorty); + function gettab_coloractivetab: colorty; + procedure settab_coloractivetab(const avalue: colorty); + function gettab_frametab: ttabframe; + procedure settab_frametab(const avalue: ttabframe); + function gettab_facetab: tface; + procedure settab_facetab(const avalue: tface); + function gettab_faceactivetab: tface; + procedure settab_faceactivetab(const avalue: tface); + function checktabsizingpos(const apos: pointty): boolean; + function getidents: integerarty; + function gettab_imagepos: imageposty; + procedure settab_imagepos(const avalue: imageposty); + { + function gettab_captionframe_left: integer; + procedure settab_captionframe_left(const avalue: integer); + function gettab_captionframe_top: integer; + procedure settab_captionframe_top(const avalue: integer); + function gettab_captionframe_right: integer; + procedure settab_captionframe_right(const avalue: integer); + function gettab_captionframe_bottom: integer; + procedure settab_captionframe_bottom(const avalue: integer); + function gettab_imagedist: integer; + procedure settab_imagedist(const avalue: integer); + } + function gettab_shift: integer; + procedure settab_shift(const avalue: integer); + function gettab_optionswidget: optionswidgetty; + procedure settab_optionswidget(const avalue: optionswidgetty); + function gettab_optionswidget1: optionswidget1ty; + procedure settab_optionswidget1(const avalue: optionswidget1ty); + function gettab_font: ttab_font; + procedure settab_font(const avalue: ttab_font); + function istab_fontstored: boolean; + function gettab_fonttab: ttab_fonttab; + procedure settab_fonttab(const avalue: ttab_fonttab); + function istab_fonttabstored: boolean; + function gettab_fontactivetab: ttab_fontactivetab; + procedure set_tabfontactivetab(const avalue: ttab_fontactivetab); + function istab_fontactivetabstored: boolean; + procedure readtab_captionpos(reader: treader); + procedure readoptions(reader: treader); + procedure readtab_captionframe_left(reader: treader); + procedure readtab_captionframe_top(reader: treader); + procedure readtab_captionframe_right(reader: treader); + procedure readtab_captionframe_bottom(reader: treader); + procedure readtab_imagedist(reader: treader); + function gettab_textflags: textflagsty; + procedure settab_textflags(const avalue: textflagsty); + function gettab_width: integer; + procedure settab_width(const avalue: integer); + function gettab_widthmin: integer; + procedure settab_widthmin(const avalue: integer); + function gettab_widthmax: integer; + procedure settab_widthmax(const avalue: integer); + function gettab_optionsskin: optionsskinty; + procedure settab_optionsskin(const avalue: optionsskinty); + function getedge_level: int32; + procedure setedge_level(const avalue: int32); + function getedge_colordkshadow: colorty; + procedure setedge_colordkshadow(const avalue: colorty); + function getedge_colorshadow: colorty; + procedure setedge_colorshadow(const avalue: colorty); + function getedge_colorlight: colorty; + procedure setedge_colorlight(const avalue: colorty); + function getedge_colorhighlight: colorty; + procedure setedge_colorhighlight(const avalue: colorty); + function getedge_colordkwidth: int32; + procedure setedge_colordkwidth(const avalue: int32); + function getedge_colorhlwidth: int32; + procedure setedge_colorhlwidth(const avalue: int32); + function getedge_imagelist: timagelist; + procedure setedge_imagelist(const avalue: timagelist); + function getedge_imageoffset: int32; + procedure setedge_imageoffset(const avalue: int32); + function getedge_imagepaintshift: int32; + procedure setedge_imagepaintshift(const avalue: int32); + protected + ftabs: tcustomtabbar1; + fupdating: integer; + fpopuptab: integer; + factivepageindexdesign: integer; + procedure defineproperties(filer: tfiler) override; + procedure internaladd(const page: itabpage; aindex: integer); + procedure internalremove(const page: itabpage); + procedure registerchildwidget(const child: twidget); override; + procedure unregisterchildwidget(const child: twidget); override; + procedure pagechanged(const sender: itabpage); + procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override; + procedure tabchanged(const synctabindex: boolean); virtual; + procedure loaded; override; + procedure clientrectchanged; override; + procedure widgetregionchanged(const sender: twidget); override; + procedure doactivepagechanged; virtual; + procedure dopageadded(const apage: twidget); virtual; + procedure dopageremoved(const apage: twidget); virtual; + procedure createpagetab(const sender: tcustomtabbar; + const index: integer; var tab: ttab); + procedure dokeydown(var info: keyeventinfoty); override; + procedure childmouseevent(const sender: twidget; + var info: mouseeventinfoty); override; + procedure dobeforepaint(const canvas: tcanvas); override; + procedure doafterpaint(const canvas: tcanvas); override; +// procedure dofontheightdelta(var delta: integer); override; + procedure doclosepage(const sender: tobject); virtual; + procedure updatepopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); override; + + //istatfile + procedure dostatread(const reader: tstatreader); + procedure dostatwrite(const writer: tstatwriter); + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + + function checkpickoffset(const aoffset: pointty): pointty; + //iobjectpicker + function getcursorshape(const sender: tobjectpicker; + var shape: cursorshapety): boolean; + //true if found + procedure getpickobjects(const sender: tobjectpicker; + var objects: integerarty); + procedure beginpickmove(const sender: tobjectpicker); + procedure pickthumbtrack(const sender: tobjectpicker); + procedure endpickmove(const sender: tobjectpicker); + procedure cancelpickmove(const sender: tobjectpicker); + procedure paintxorpic(const sender: tobjectpicker; const canvas: tcanvas); + + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + + procedure createtabframe(); + procedure createtabface(); + procedure createtabfont(); + procedure createtabframetab(); + procedure createtabfacetab(); + procedure createtabfonttab(); + procedure createtabfaceactivetab(); + procedure createtabfontactivetab(); + + procedure beginupdate; + procedure endupdate; + procedure synctofontheight; override; + function indexof(const page: twidget): integer; + function count: integer; + procedure clear; + procedure clearorder; //ident order = indexorder + procedure nextpage(newindex: integer; down: boolean); + procedure changepage(step: integer); + procedure movepage(const curindex,newindex: integer); + procedure add(const aitem: itabpage; const aindex: integer = bigint); + function pagebyname(const aname: string): twidget; + //case sensitive! + + property items[const index: integer]: twidget read getitems; default; + property itemsintf[const index: integer]: itabpage read getitemsintf; + property activepage: twidget read getactivepage write setactivepage; + property activepageintf: itabpage read getactivepageintf; + property idents: integerarty read getidents; + property activepageindex: integer read getactivepageindex + write setactivepageindex1 default -1; + property onactivepagechanged: notifyeventty read fonactivepagechanged + write fonactivepagechanged; + property onpageadded: widgeteventty read fonpageadded write fonpageadded; + property onpageremoved: widgeteventty read fonpageremoved + write fonpageremoved; + property optionswidget default defaulttaboptionswidget; + property font: twidgetfont read getfont write setfont stored isfontstored; + property fontempty: twidgetfontempty read getfontempty + write setfontempty stored isfontemptystored; + property tab_options: tabbaroptionsty read gettab_options write + settab_options default []; + property tab_frame: tstepboxframe1 read gettab_frame write settab_frame; + property tab_face: tface read gettab_face write settab_face; + property tab_color: colorty read gettab_color + write settab_color default cl_default; + property tab_colortab: colorty read gettab_colortab + write settab_colortab default cl_default; + property tab_coloractivetab: colorty read gettab_coloractivetab + write settab_coloractivetab default cl_default; + property tab_font: ttab_font read gettab_font write settab_font + stored istab_fontstored; + property tab_fonttab: ttab_fonttab read gettab_fonttab write settab_fonttab + stored istab_fonttabstored; + property tab_fontactivetab: ttab_fontactivetab read gettab_fontactivetab + write set_tabfontactivetab stored istab_fontactivetabstored; + property tab_imagepos: imageposty read gettab_imagepos write + settab_imagepos default defaultimagepos; + property tab_textflags: textflagsty read gettab_textflags write + settab_textflags default defaultcaptiontextflags; + property tab_width: integer read gettab_width write settab_width default 0; + property tab_widthmin: integer read gettab_widthmin + write settab_widthmin default 0; + property tab_widthmax: integer read gettab_widthmax + write settab_widthmax default 0; +{ + property tab_captionframe_left: integer read gettab_captionframe_left write + settab_captionframe_left default defaultcaptiondist; + property tab_captionframe_top: integer read gettab_captionframe_top write + settab_captionframe_top default defaultcaptiondist; + property tab_captionframe_right: integer read gettab_captionframe_right write + settab_captionframe_right default defaultcaptiondist; + property tab_captionframe_bottom: integer read gettab_captionframe_bottom write + settab_captionframe_bottom default defaultcaptiondist; + property tab_imagedist: integer read gettab_imagedist write settab_imagedist + default defaultimagedist; +} + property tab_shift: integer read gettab_shift write settab_shift + default defaulttabshift; + //defaulttabshift (-100) -> 1 + property tab_edge_level: int32 read getedge_level write setedge_level + default defaultedgelevel; + //defaultedgelevel (-100) -> -1 + property tab_edge_colordkshadow: colorty read getedge_colordkshadow + write setedge_colordkshadow default cl_default; + property tab_edge_colorshadow: colorty read getedge_colorshadow + write setedge_colorshadow default cl_default; + property tab_edge_colorlight: colorty read getedge_colorlight + write setedge_colorlight default cl_default; + property tab_edge_colorhighlight: colorty read getedge_colorhighlight + write setedge_colorhighlight default cl_default; + property tab_edge_colordkwidth: int32 read getedge_colordkwidth + write setedge_colordkwidth default -1; + //-1 = default + property tab_edge_colorhlwidth: int32 read getedge_colorhlwidth + write setedge_colorhlwidth default -1; + //-1 = default + property tab_edge_imagelist: timagelist read getedge_imagelist + write setedge_imagelist; + //imagenr 0 -> startpoint, 1 -> edge, imagenr 2 -> endpoint + property tab_edge_imageoffset: int32 read getedge_imageoffset + write setedge_imageoffset default 0; + property tab_edge_imagepaintshift: int32 read getedge_imagepaintshift + write setedge_imagepaintshift default 0; + + property tab_frametab: ttabframe read gettab_frametab write settab_frametab; + property tab_facetab: tface read gettab_facetab write settab_facetab; + property tab_faceactivetab: tface read gettab_faceactivetab + write settab_faceactivetab; + property tab_size: integer read ftab_size write settab_size; + property tab_sizemin: integer read ftab_sizemin write settab_sizemin + default defaulttabsizemin; + property tab_sizemax: integer read ftab_sizemax write settab_sizemax + default defaulttabsizemax; + property tab_optionswidget: optionswidgetty read gettab_optionswidget + write settab_optionswidget default defaultoptionswidgettab; + property tab_optionsskin: optionsskinty read gettab_optionsskin + write settab_optionsskin default []; + property tab_optionswidget1: optionswidget1ty read gettab_optionswidget1 + write settab_optionswidget1 default defaultoptionswidget1tab; + + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read getstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + end; + + ttabwidget = class(tcustomtabwidget) + published + property optionswidget; + property optionswidget1; + property optionsskin default defaulttaboptionsskin; + property bounds_x; + property bounds_y; + property bounds_cx; + property bounds_cy; + property bounds_cxmin; + property bounds_cymin; + property bounds_cxmax; + property bounds_cymax; + property color; + property cursor; + property frame; + property face; + property anchors; + property taborder; + property hint; + property popupmenu; + property onpopup; + property onshowhint; + + property enabled; + property visible; + + property activepageindex; + property onactivepagechanged; + property onpageadded; + property onpageremoved; + property font; + property fontempty; + property tab_options; + property tab_font; + property tab_fonttab; + property tab_fontactivetab; + property tab_frame; + property tab_face; + property tab_color; + property tab_imagepos; + property tab_textflags; + property tab_width; + property tab_widthmin; + property tab_widthmax; + { + property tab_captionframe_left; + property tab_captionframe_top; + property tab_captionframe_right; + property tab_captionframe_bottom; + property tab_imagedist; + } + property tab_shift; + property tab_edge_level; + property tab_edge_colordkshadow; + property tab_edge_colorshadow; + property tab_edge_colorlight; + property tab_edge_colorhighlight; + property tab_edge_colordkwidth; + property tab_edge_colorhlwidth; + property tab_edge_imagelist; + property tab_edge_imageoffset; + property tab_colortab; + property tab_coloractivetab; + property tab_frametab; + property tab_facetab; + property tab_faceactivetab; + property tab_sizemin; + property tab_sizemax; + property tab_size; + property tab_optionswidget; + property tab_optionswidget1; + property tab_optionsskin; + property tab_edge_imagepaintshift; + property statfile; + property statvarname; + property statpriority; + end; + +implementation +uses + sysutils,msearrayutils,msekeyboard,msestockobjects,msebits; + +type + twidget1 = class(twidget); + tmsecomponent1 = class(tmsecomponent); + tcustomstepframe1 = class(tcustomstepframe); + ttabframe1 = class(ttabframe); + ttaborderoverride1 = class(ttaborderoverride); + +procedure calctablayout(var layout: tabbarlayoutinfoty; + const canvas: tcanvas; const focused: boolean); + +var + horzimage: boolean; + vertimage: boolean; + imagedi: int32; + imagedi1: int32; + imagedi2: int32; + + procedure docommon(const tab: ttab; var cell: shapeinfoty; var textrect: rectty); + begin + with tab,cell,ca do begin + caption:= frichcaption; + textflags:= layout.tabs.ftextflags; + imagedist:= imagedi; + imagedist1:= imagedi1; + imagedist2:= imagedi2; + imagepos:= layout.tabs.fimagepos;//captiontoimagepos[layout.tabs.fcaptionpos]; + imagelist:= fimagelist; + imagenr:= fimagenr; + imagenrdisabled:= fimagenrdisabled; + if imagelist <> nil then begin + if not vertimage then begin + inc(textrect.cx,fimagelist.width+imagedist); + end; + if not horzimage then begin + inc(textrect.cy,fimagelist.height+imagedist); + end; + end; + facetemplate:= nil; + if ts_active in fstate then begin + if tab.faceactive <> nil then begin + facetemplate:= tab.faceactive.template; + end; + end + else begin + if tab.face <> nil then begin + facetemplate:= tab.face.template; + end; + end; + end; + end; //docommon + + procedure dofont(const tab: ttab; var cell: shapeinfoty); + begin + with tab,cell,ca do begin + if ts_active in tab.state then begin + font:= tab.fontactive; + end + else begin + font:= tab.font; + end; + end; + end; //dofont + +var + int1,int2: integer; + asize: integer; + aval: integer; + endval: integer; + rect1: rectty; + bo1: boolean; + cxinflate: integer; + cyinflate: integer; + cxsizeinflate: integer; + cysizeinflate: integer; + frame1: framety; + textflags1: textflagsty; + negtabshift1: boolean; + tabshift1: int32; + edgesize: int32; + normpos,normsize: int32; + extraspace1: int32; + extra1: int32; + imageinflate: int32; + i1: int32; + maximagesize: int32; + +begin + with layout do begin + horzimage:= tabs.imagepos in horzimagepos; + vertimage:= tabs.imagepos in vertimagepos; + cells:= nil; + setlength(cells,tabs.count); + if firsttab > high(cells) then begin + firsttab:= 0; + end; + lasttab:= -1; + edgesize:= tabs.getedgeshift(); + textflags1:= tabs.textflags - [tf_ellipseleft,tf_ellipseright]; + tabshift1:= tabs.ftabshift; + negtabshift1:= tabshift1 < 0; + if tabs.fframe <> nil then begin + with tabs.fframe do begin + extraspace1:= extraspace; +// captionframe:= nullframe; + captionframe:= framei; + imagedi:= imagedist; + imagedi1:= imagedist1; + imagedi2:= imagedist2; + end; + end + else begin + extraspace1:= 0; + captionframe.left:= defaultcaptiondist; + captionframe.top:= defaultcaptiondist; + captionframe.right:= defaultcaptiondist; + captionframe.bottom:= defaultcaptiondist; + imagedi:= defaultimagedist; + imagedi1:= 0; + imagedi2:= 0; + end; + cxinflate:= captionframe.left + captionframe.right + 2; //for not flat button + cyinflate:= captionframe.top + captionframe.bottom + 2; //for not flat button + imageinflate:= imagedi1 + imagedi2 + 2; //for not flat button + if tabs.fframe <> nil then begin + with tabs.fframe do begin + frame1:= frameo; + cxinflate:= cxinflate + frame1.left + frame1.right + frameframecx; + cyinflate:= cyinflate + frame1.top + frame1.bottom + frameframecy; + if fso_flat in optionsskin then begin + cxinflate:= cxinflate - 2; + cyinflate:= cyinflate - 2; + imageinflate:= imageinflate - 2; + end; + end; + end; + + cxsizeinflate:= cxinflate; + cysizeinflate:= cyinflate; + if shs_vert in options then begin + cxsizeinflate:= cxsizeinflate + edgesize; + normsize:= dim.cx - edgesize; + normpos:= dim.x; + if negtabshift1 then begin + cxsizeinflate:= cxsizeinflate - tabshift1; + normsize:= normsize + tabshift1; + end; + if shs_opposite in options then begin + normpos:= normpos + edgesize; + end + else begin + if negtabshift1 then begin + normpos:= normpos - tabshift1; + end; + end; + end + else begin + cysizeinflate:= cysizeinflate + edgesize; + normsize:= dim.cy - edgesize; + normpos:= dim.y; + if negtabshift1 then begin + cysizeinflate:= cysizeinflate - tabshift1; + normsize:= normsize + tabshift1; + end; + if shs_opposite in options then begin + normpos:= normpos + edgesize; + end + else begin + if negtabshift1 then begin + normpos:= normpos - tabshift1; + end; + end; + end; + if shs_vert in options then begin + totsize.cx:= 0; + aval:= dim.y; + asize:= aval; + endval:= dim.y + dim.cy; + for int1:= 0 to high(cells) do begin + with tabs[int1],cells[int1],ca do begin + extra1:= 0; + if int1 <> 0 then begin + aval:= aval + extraspace1; + end; + if int1 <> high(cells) then begin + extra1:= extraspace1; + end; + dim.y:= aval; + dofont(tabs[int1],cells[int1]); + rect1:= textrect(canvas,frichcaption, + makerect(normpos,aval,normsize-cxinflate,bigint), + textflags1,font); + docommon(tabs[int1],cells[int1],rect1); + if rect1.cx > totsize.cx then begin + totsize.cx:= rect1.cx; + end; + if rect1.cx <= layout.dim.cx - cxinflate then begin + textflags:= textflags - [tf_ellipseleft,tf_ellipseright]; + exclude(fstate,ts_captionclipped); + end + else begin + include(fstate,ts_captionclipped); + end; + dim.cy:= rect1.cy+cyinflate; + if (imagelist <> nil) and not vertimage and + (imagelist.height+imageinflate > dim.cy) then begin + dim.cy:= imagelist.height+imageinflate; + end; + bo1:= (ts_invisible in fstate) or (int1 < firsttab); + if bo1 or (aval >= endval) then begin + include(state,shs_invisible); + if not bo1 then begin + inc(asize,dim.cy+extra1); + end; + end + else begin + inc(aval,dim.cy); + inc(asize,dim.cy+extra1); + if (aval <= endval) then begin + lasttab:= int1; + end; + end; + if ts_active in fstate then begin + dim.cx:= layout.dim.cx; + if not negtabshift1 then begin + dim.cx:= dim.cx - tabshift1; + if not (shs_opposite in options) then begin + dim.x:= tabshift1; + end; + end; + end + else begin + dim.x:= normpos; + dim.cx:= normsize; + end; + dim.x:= dim.x + layout.dim.x; + end; + end; + totsize.cy:= asize-dim.y; + totsize.cx:= totsize.cx + cxsizeinflate; + end + else begin //horizontal + aval:= dim.x; + asize:= aval; + endval:= dim.x + dim.cx; + totsize.cy:= 0; + maximagesize:= 0; + for int1:= 0 to high(cells) do begin + with tabs[int1],cells[int1],ca do begin + extra1:= 0; + if int1 <> 0 then begin + aval:= aval + extraspace1; + end; + if int1 <> high(cells) then begin + extra1:= extraspace1; + end; + dim.x:= aval; + dofont(tabs[int1],cells[int1]); + rect1:= textrect(canvas,frichcaption, + makerect(aval,normpos,bigint,normsize-cyinflate), + textflags1,font); + docommon(tabs[int1],cells[int1],rect1); + if rect1.cy > totsize.cy then begin + totsize.cy:= rect1.cy; + end; + int2:= rect1.cx; + with layout.tabs do begin + if width <> 0 then begin + int2:= width; + end; + if (widthmax <> 0) and (rect1.cx > widthmax) then begin + int2:= widthmax; + end; + if (widthmin <> 0) and (rect1.cx < widthmin) then begin + int2:= widthmin; + end; + end; + if int2 >= rect1.cx then begin + textflags:= textflags - [tf_ellipseleft,tf_ellipseright]; + exclude(fstate,ts_captionclipped); + end + else begin + include(fstate,ts_captionclipped); + end; + rect1.cx:= int2; + + dim.cx:= rect1.cx + cxinflate; + if (imagelist <> nil) then begin + i1:= imagelist.height; + if not vertimage then begin + i1:= i1 + imageinflate; + if i1 > maximagesize then begin + maximagesize:= i1; + end; + end; + end; + bo1:= (ts_invisible in fstate) or (int1 < firsttab); + if bo1 or (aval >= endval) then begin + include(state,shs_invisible); + if not bo1 then begin + inc(asize,dim.cx+extra1); + end; + end + else begin + inc(aval,dim.cx); + inc(asize,dim.cx+extra1); + if (aval <= endval) then begin + lasttab:= int1; + end; + end; + if ts_active in fstate then begin + dim.cy:= layout.dim.cy; + if not negtabshift1 then begin + dim.cy:= dim.cy - tabshift1; + if not (shs_opposite in options) then begin + dim.y:= tabshift1; + end; + end; + end + else begin + dim.y:= normpos; + dim.cy:= normsize; + end; + dim.y:= dim.y + layout.dim.y; + end; + end; + totsize.cx:= asize-dim.x; + if totsize.cy = 0 then begin + totsize.cy:= twidget1(tabs.fowner).getfont1.glyphheight; + end; + totsize.cy:= totsize.cy + cysizeinflate; + maximagesize:= maximagesize + cysizeinflate - cyinflate; + //space for tabshift and edge + if totsize.cy < maximagesize then begin + totsize.cy:= maximagesize; + end; + end; //horizontal + bo1:= not twidget(tabs.fowner).isenabled; + for int1:= 0 to high(cells) do begin + with tabs[int1],cells[int1],ca do begin + state:= (state + [shs_showfocusrect] + options * [shs_vert,shs_opposite]) - + [shs_focused]; + if ts_active in fstate then begin + include(state,shs_active); + if focused then begin + state:= state + [shs_focused]; + end; + if fcoloractive = cl_default then begin + color:= tabs.fcoloractive; + end + else begin + color:= fcoloractive; + end; + if color = cl_default then begin + color:= defaultcoloractivetab; + end; + coloractive:= color; + face:= tabs.ffaceactive; + end + else begin + exclude(state,shs_active); + if fcolor = cl_default then begin + color:= tabs.fcolor; + end + else begin + color:= fcolor; + end; + if color = cl_default then begin + color:= defaultcolortab; + end; + face:= tabs.face; + end; + if ts_noface in fstate then begin + face:= nil; + end; + if bo1 or (ts_disabled in fstate) then begin + include(state,shs_disabled); + end; + doexecute:= {$ifdef FPC}@{$endif}execute; + end; + end; + with stepinfo do begin + up:= 0; + for int1:= firsttab to high(cells) do begin + if not (shs_invisible in cells[int1].state) and (up = 0) then begin + up:= int1-firsttab; + break; + end; + end; + if up = 0 then begin + up:= 1; + end; + pageup:= lasttab - firsttab + 1; + if firsttab = 0 then begin + pagedown:= 0; + end + else begin + pagedown:= 1; + end; + aval:= 0; + pagelast:= 0; + endval:= 0; + down:= 0; + if shs_vert in options then begin + for int1:= firsttab - 1 downto 0 do begin + with cells[int1].ca do begin + dec(pagedown); + if not (ts_invisible in tabs[int1].fstate) then begin + inc(aval,dim.cy); + if down = 0 then begin + down:= int1-firsttab; + end; + end; + end; + if aval >= dim.cy then begin + break; + end; + if int1 = 0 then begin + dec(pagedown); + end; + end; + for int1:= high(cells) downto 0 do begin + with cells[int1].ca do begin + inc(pagelast); + if not (ts_invisible in tabs[int1].fstate) then begin + inc(endval,dim.cy); + end; + end; + if endval >= dim.cy then begin + break; + end; + end; + if endval > dim.cy then begin + dec(pagelast); + end; + end + else begin + for int1:= firsttab - 1 downto 0 do begin + with cells[int1].ca do begin + dec(pagedown); + if not (ts_invisible in tabs[int1].fstate) then begin + inc(aval,dim.cx); + if down = 0 then begin + down:= int1-firsttab; + end; + end; + end; + if aval >= dim.cx then begin + break; + end; + if int1 = 0 then begin + dec(pagedown); + end; + end; + for int1:= high(cells) downto 0 do begin + with cells[int1].ca do begin + inc(pagelast); + if not (ts_invisible in tabs[int1].fstate) then begin + inc(endval,dim.cx); + end; + end; + if endval >= dim.cx then begin + break; + end; + end; + if endval > dim.cx then begin + dec(pagelast); + end; + end; + if down = 0 then begin + down:= -1; + end; + pagelast:= length(cells)-pagelast-firsttab; + end; + inc(lasttab); + notfull:= lasttab > high(cells); + if notfull then begin + lasttab:= high(cells); + end; + end; +end; + +{ ttabfont } + +class function ttabfont.getinstancepo(owner: tobject): pfont; +begin + result:= @ttab(owner).ffont; +end; + +{ ttabfontactive } + +class function ttabfontactive.getinstancepo(owner: tobject): pfont; +begin + result:= @ttab(owner).ffontactive; +end; + +{ ttab } + +constructor ttab.create(const aowner: tcustomtabbar); +begin + fcolor:= cl_default; + fcoloractive:= cl_default; + fimagenr:= -1; + fimagenrdisabled:= -2; + inherited create(aowner,aowner.flayoutinfo.tabs); +end; + +destructor ttab.destroy; +begin + ffont.free; + ffontactive.free; + inherited; +end; + +procedure ttab.changed; +begin + if not (ts_updating in fstate) then begin + tcustomtabbar(fowner).tabchanged(self); + end; +end; + +procedure ttab.createfont; +begin + if ffont = nil then begin + ffont:= ttabfont.create; + ffont.onchange:= {$ifdef FPC}@{$endif}fontchanged; + end; +end; + +function ttab.getfont: ttabfont; +begin + getoptionalobject(ttabbar(fowner).componentstate,ffont, + {$ifdef FPC}@{$endif}createfont); + if ffont <> nil then begin + result:= ffont; + end + else begin + result:= ttabfont(pointer(ttabs(prop).getfont)); + end; +end; + +procedure ttab.setfont(const avalue: ttabfont); +begin + if avalue <> ffont then begin + setoptionalobject(ttabbar(fowner).ComponentState,avalue,ffont, + {$ifdef FPC}@{$endif}createfont); + changed; + end; +end; + +function ttab.isfontstored: boolean; +begin + result:= ffont <> nil; +end; + +procedure ttab.createfontactive; +begin + if ffontactive = nil then begin + ffontactive:= ttabfontactive.create; + ffontactive.onchange:= {$ifdef FPC}@{$endif}fontchanged; + end; +end; + +function ttab.getfontactive: ttabfontactive; +begin + getoptionalobject(ttabbar(fowner).componentstate,ffontactive, + {$ifdef FPC}@{$endif}createfontactive); + if ffontactive <> nil then begin + result:= ffontactive; + end + else begin + result:= ttabfontactive(pointer(ttabs(prop).getfontactive)); + end; +end; + +procedure ttab.setfontactive(const avalue: ttabfontactive); +begin + if avalue <> ffontactive then begin + setoptionalobject(ttabbar(fowner).ComponentState,avalue,ffontactive, + {$ifdef FPC}@{$endif}createfontactive); + changed; + end; +end; + +function ttab.isfontactivestored: boolean; +begin + result:= ffontactive <> nil; +end; + +{ +function ttab.getcaption: captionty; +begin + result:= richstringtocaption(fcaption); +end; +} +procedure ttab.setcaption(const avalue: captionty); +begin + fcaption:= avalue; + captiontorichstring(avalue,frichcaption); + changed; +end; + +function ttab.tabbar: tcustomtabbar; +begin + result:= tcustomtabbar(fowner); +end; + +procedure ttab.setstate(const Value: tabstatesty); +begin + if fstate <> value then begin + fstate := Value; + { + if (fstate * [ts_invisible,ts_disabled] <> []) and + not (csdesigning in tcustomtabbar(fowner).componentstate) then begin + exclude(fstate,ts_active); + end; + } + changed; + end; +end; + +procedure ttab.execute(const tag: integer; const info: mouseeventinfoty); +begin + tabbar.tabclicked(self,info); +end; + +procedure ttab.doshortcut(var info: keyeventinfoty; const sender: twidget); +begin + if checkshortcut(info,fcaption,true) then begin + active:= true; + end; +end; + +procedure ttab.setcolor(const Value: colorty); +begin + if fcolor <> value then begin + fcolor := Value; + changed; + end; +end; + +procedure ttab.setcoloractive(const Value: colorty); +begin + if fcoloractive <> value then begin + fcoloractive := Value; + changed; + end; +end; + +procedure ttab.setface(const avalue: tfacecomp); +begin + if fface <> avalue then begin + setlinkedvar(avalue,tmsecomponent(fface)); + changed(); + end; +end; + +procedure ttab.setfaceactive(const avalue: tfacecomp); +begin + if ffaceactive <> avalue then begin + setlinkedvar(avalue,tmsecomponent(ffaceactive)); + changed(); + end; +end; + +function ttab.getactive: boolean; +begin + result:= ts_active in fstate; +end; + +procedure ttab.setactive(const Value: boolean); +begin + if value then begin + state:= fstate + [ts_active]; + end + else begin + state:= fstate - [ts_active]; + end; +end; + +procedure ttab.setimagelist(const avalue: timagelist); +begin + if avalue <> fimagelist then begin + setlinkedvar(avalue,tmsecomponent(fimagelist)); + changed; + end; +end; + +procedure ttab.setimagenr(const avalue: imagenrty); +begin + if fimagenr <> avalue then begin + fimagenr:= avalue; + changed; + end; +end; + +procedure ttab.setimagenrdisabled(const avalue: imagenrty); +begin + if fimagenrdisabled <> avalue then begin + fimagenrdisabled:= avalue; + changed; + end; +end; + +procedure ttab.objectevent(const sender: tobject; const event: objecteventty); +begin + inherited; + if event = oe_destroyed then begin + if sender = fimagelist then begin + fimagelist:= nil; + changed(); + end; + if sender = fface then begin + fface:= nil; + changed(); + end; + if sender = ffaceactive then begin + ffaceactive:= nil; + changed(); + end; + end + else begin + if event = oe_changed then begin + changed; + end; + end; +end; + +function ttab.getimagelist: timagelist; +begin + result:= fimagelist; +end; + +procedure ttab.fontchanged(const sender: tobject); +begin + changed; +end; +{ +procedure ttab.setwidth(const avalue: integer); +begin + if fwidth <> avalue then begin + fwidth:= avalue; + changed; + end; +end; + +procedure ttab.setwidthmin(const avalue: integer); +begin + if fwidthmin <> avalue then begin + fwidthmin:= avalue; + changed; + end; +end; + +procedure ttab.setwidthmax(const avalue: integer); +begin + if fwidthmax <> avalue then begin + fwidthmax:= avalue; + changed; + end; +end; +} +{ ttabframe } + +constructor ttabframe.create(const aintf: iframe); +begin + fi.innerframe.left:= defaultcaptiondist; + fi.innerframe.top:= defaultcaptiondist; + fi.innerframe.right:= defaultcaptiondist; + fi.innerframe.bottom:= defaultcaptiondist; + fi.imagedist:= defaultimagedist; + inherited; + include(fstate,fs_needsmouseinvalidate); +end; + +{ ttabsfont } + +class function ttabsfont.getinstancepo(owner: tobject): pfont; +begin + result:= @ttabs(owner).ffont; +end; + +{ ttabsfontactive } + +class function ttabsfontactive.getinstancepo(owner: tobject): pfont; +begin + result:= @ttabs(owner).ffontactive; +end; + +{ ttabs } + +constructor ttabs.create(const aowner: tcustomtabbar; + aclasstype: indexpersistentclassty); +begin + fcolor:= cl_default; + fcoloractive:= cl_default; + fimagepos:= defaultimagepos; + ftextflags:= defaultcaptiontextflags; + { + fcaptionframe.left:= defaultcaptiondist; + fcaptionframe.top:= defaultcaptiondist; + fcaptionframe.right:= defaultcaptiondist; + fcaptionframe.bottom:= defaultcaptiondist; + fimagedist:= defaultimagedist; + } + fshift:= defaulttabshift; + ftabshift:= 1; + fedge_level:= defaultedgelevel; + initdefaultvalues(fedge); + inherited create(aowner,aclasstype); +end; + +destructor ttabs.destroy; +begin + fface.free; + ffaceactive.free; + fframe.free; + ffont.free; + ffontactive.free; + inherited; +end; + +class function ttabs.getitemclasstype: persistentclassty; +begin + result:= ttab; +end; + +procedure ttabs.readcaptionpos(reader: treader); +begin + imagepos:= readcaptiontoimagepos(reader); +end; + +procedure ttabs.readcaptionframe_left(reader: treader); +begin + createframe(); + ttabframe1(fframe).fi.innerframe.left:= reader.readinteger; +end; + +procedure ttabs.readcaptionframe_top(reader: treader); +begin + createframe(); + ttabframe1(fframe).fi.innerframe.top:= reader.readinteger; +end; + +procedure ttabs.readcaptionframe_right(reader: treader); +begin + createframe(); + ttabframe1(fframe).fi.innerframe.right:= reader.readinteger; +end; + +procedure ttabs.readcaptionframe_bottom(reader: treader); +begin + createframe(); + ttabframe1(fframe).fi.innerframe.bottom:= reader.readinteger; +end; + +procedure ttabs.readimagedist(reader: treader); +begin + createframe(); + ttabframe1(fframe).fi.imagedist:= reader.readinteger; +end; + +procedure ttabs.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('captionpos', @readcaptionpos,nil,false); + filer.defineproperty('captionframe_left', @readcaptionframe_left,nil,false); + filer.defineproperty('captionframe_top', @readcaptionframe_top,nil,false); + filer.defineproperty('captionframe_right', @readcaptionframe_right,nil,false); + filer.defineproperty('captionframe_bottom', @readcaptionframe_bottom,nil,false); + filer.defineproperty('imagedist', @readimagedist,nil,false); +end; + +procedure ttabs.changed; +begin + tcustomtabbar(fowner).layoutchanged; +end; + +procedure ttabs.createface; +begin + if fface = nil then begin + fface:= tface.create(iface(tcustomtabbar(fowner))); + end; +end; + +procedure ttabs.createfaceactive; +begin + if ffaceactive = nil then begin + ffaceactive:= tface.create(iface(tcustomtabbar(fowner))); + end; +end; + +function ttabs.getface: tface; +begin + tcustomtabbar(fowner).getoptionalobject(fface,{$ifdef FPC}@{$endif}createface); + result:= fface; +end; + +procedure ttabs.setface(const avalue: tface); +begin + tcustomtabbar(fowner).setoptionalobject(avalue,fface,{$ifdef FPC}@{$endif}createface); + changed; +end; + +function ttabs.getfaceactive: tface; +begin + tcustomtabbar(fowner).getoptionalobject(ffaceactive, + {$ifdef FPC}@{$endif}createfaceactive); + result:= ffaceactive; +end; + +procedure ttabs.setfaceactive(const avalue: tface); +begin + tcustomtabbar(fowner).setoptionalobject(avalue,ffaceactive, + {$ifdef FPC}@{$endif}createfaceactive); + changed; +end; + +procedure ttabs.setcolor(const avalue: colorty); +begin + if avalue <> fcolor then begin + fcolor:= avalue; + changed; + end; +end; + +procedure ttabs.setcoloractive(const avalue: colorty); +begin + if avalue <> fcoloractive then begin + fcoloractive:= avalue; + changed; + end; +end; + +procedure ttabs.setimagepos(const avalue: imageposty); +begin + if avalue <> fimagepos then begin + fimagepos:= avalue; + changed; + end; +end; + +procedure ttabs.settextflags(const avalue: textflagsty); +begin + if avalue <> ftextflags then begin + ftextflags:= checktextflags(ftextflags,avalue); + changed; + end; +end; + +procedure ttabs.setwidth(const avalue: integer); +begin + if avalue <> fwidth then begin + fwidth:= avalue; + changed; + end; +end; + +procedure ttabs.setwidthmin(const avalue: integer); +begin + if avalue <> fwidthmin then begin + fwidthmin:= avalue; + changed; + end; +end; + +procedure ttabs.setwidthmax(const avalue: integer); +begin + if avalue <> fwidthmax then begin + fwidthmax:= avalue; + changed; + end; +end; + +procedure ttabs.setedge_level(const avalue: int32); +begin + if avalue <> fedge_level then begin + fedge_level:= avalue; + changed(); + end; +end; + +procedure ttabs.setedge_colordkshadow(const avalue: colorty); +begin + if avalue <> fedge.shadow.effectcolor then begin + fedge.shadow.effectcolor:= avalue; + changed(); + end; +end; + +procedure ttabs.setedge_colorshadow(const avalue: colorty); +begin + if avalue <> fedge.shadow.color then begin + fedge.shadow.color:= avalue; + changed(); + end; +end; + +procedure ttabs.setedge_colorlight(const avalue: colorty); +begin + if avalue <> fedge.light.color then begin + fedge.light.color:= avalue; + changed(); + end; +end; + +procedure ttabs.setedge_colorhighlight(const avalue: colorty); +begin + if avalue <> fedge.light.effectcolor then begin + fedge.light.effectcolor:= avalue; + changed(); + end; +end; + +procedure ttabs.setedge_colordkwidth(const avalue: int32); +begin + if avalue <> fedge.shadow.effectwidth then begin + fedge.shadow.effectwidth:= avalue; + changed(); + end; +end; + +procedure ttabs.setedge_colorhlwidth(const avalue: int32); +begin + if avalue <> fedge.light.effectwidth then begin + fedge.light.effectwidth:= avalue; + changed(); + end; +end; + +procedure ttabs.setedge_imagelist(const avalue: timagelist); +begin + if avalue <> fedge_imagelist then begin + tcustomtabbar(fowner).setlinkedvar(avalue,tmsecomponent(fedge_imagelist)); + changed(); + end; +end; + +procedure ttabs.setedge_imageoffset(const avalue: int32); +begin + if avalue <> fedge_imageoffset then begin + fedge_imageoffset:= avalue; + changed(); + end; +end; + +procedure ttabs.setedge_imagepaintshift(const avalue: int32); +begin + if avalue <> fedge_imagepaintshift then begin + fedge_imagepaintshift:= avalue; + changed(); + end; +end; +{ +procedure ttabs.setcaptionframe_left(const avalue: integer); +begin + if avalue <> fcaptionframe.left then begin + fcaptionframe.left:= avalue; + changed; + end; +end; + +procedure ttabs.setcaptionframe_top(const avalue: integer); +begin + if avalue <> fcaptionframe.top then begin + fcaptionframe.top:= avalue; + changed; + end; +end; + +procedure ttabs.setcaptionframe_right(const avalue: integer); +begin + if avalue <> fcaptionframe.right then begin + fcaptionframe.right:= avalue; + changed; + end; +end; + +procedure ttabs.setcaptionframe_bottom(const avalue: integer); +begin + if avalue <> fcaptionframe.bottom then begin + fcaptionframe.bottom:= avalue; + changed; + end; +end; + +procedure ttabs.setimagedist(const avalue: integer); +begin + if avalue <> fimagedist then begin + fimagedist:= avalue; + changed; + end; +end; +} +procedure ttabs.setshift(const avalue: integer); +begin + if avalue <> fshift then begin + fshift:= avalue; + if avalue = defaulttabshift then begin + ftabshift:= 1; + end + else begin + ftabshift:= avalue; + end; + changed; + end; +end; + +procedure ttabs.add(const item: ttab); +begin + inherited add(item); +end; + +procedure ttabs.insert(const item: ttab; const aindex: integer); +begin + tcustomtabbar(fowner).beginupdate; + try + inherited add(item); + move(count-1,aindex); + finally + tcustomtabbar(fowner).endupdate + end; +end; + +procedure ttabs.additems(const aitems: msestringarty); +var + int1,int2: integer; + +begin + tcustomtabbar(fowner).beginupdate; + try + int1:= count; + count:= count + length(aitems); + for int2:= 0 to high(aitems) do begin + items[int1].caption:= aitems[int2]; + inc(int1); + end; + finally + tcustomtabbar(fowner).endupdate; + end; +end; + +procedure ttabs.createitem(const index: integer; var item: tpersistent); +begin + if item = nil then begin + if assigned(foncreatetab) then begin + foncreatetab(tcustomtabbar(fowner),index,ttab(item)); + end; + if item = nil then begin + item:= ttab.create(tcustomtabbar(fowner)); + end; + end; + ttab(item).findex:= index; +end; + +function ttabs.getitems(const index: integer): ttab; +begin + result:= ttab(inherited items[index]); +end; + +function ttabs.indexof(const item: ttab): integer; +var + int1: integer; +begin + result:= -1; + for int1:= 0 to high(fitems) do begin + if items[int1] = item then begin + result:= int1; + break; + end; + end; +end; + +procedure ttabs.setitems(const index: integer; const Value: ttab); +begin + inherited items[index].assign(value); +end; + +procedure ttabs.checktemplate(const sender: tobject); +begin + if frame <> nil then begin + fframe.checktemplate(sender); + end; + if fface <> nil then begin + fface.checktemplate(sender); + end; + if ffaceactive <> nil then begin + ffaceactive.checktemplate(sender); + end; +end; + +// iframe + +procedure ttabs.setframeinstance(instance: tcustomframe); +begin + fframe:= ttabframe(instance); +end; + +procedure ttabs.setstaticframe(value: boolean); +begin + //dummy +end; + +function ttabs.getstaticframe: boolean; +begin + result:= false; +end; + +function ttabs.getwidgetrect: rectty; +begin + result:= nullrect; +end; + +function ttabs.getcomponentstate: tcomponentstate; +begin + result:= tcustomtabbar(fowner).componentstate; +end; + +function ttabs.getmsecomponentstate: msecomponentstatesty; +begin + result:= tcustomtabbar(fowner).msecomponentstate; +end; + +procedure ttabs.scrollwidgets(const dist: pointty); +begin + //dummy +end; + +procedure ttabs.clientrectchanged; +begin + changed; +end; + +procedure ttabs.invalidate; +begin + tcustomtabbar(fowner).invalidate; +end; + +procedure ttabs.invalidatewidget; +begin + tcustomtabbar(fowner).invalidatewidget; +end; + +procedure ttabs.invalidaterect(const rect: rectty; + const org: originty = org_client; const noclip: boolean = false); +begin + tcustomtabbar(fowner).invalidaterect(rect,org,noclip); +end; + +function ttabs.getwidget: twidget; +begin + result:= tcustomtabbar(fowner); +end; + +function ttabs.getframestateflags: framestateflagsty; +begin + with tcustomtabbar(fowner).flayoutinfo do begin + result:= shapestatetoframestate(factcellindex,cells); + if factcellindex = firsttab then begin + include(result,fsf_offset1); + end; + end; +end; + +function ttabs.getedgeshift(): int32; +begin + result:= 1; //default + if fedge_imagelist <> nil then begin + if tabo_vertical in tcustomtabbar(fowner).foptions then begin + result:= fedge_imagelist.height; + end + else begin + result:= fedge_imagelist.width; + end; + result:= result + fedge_imagepaintshift; + end + else begin + if fedge_level <> defaultedgelevel then begin + result:= fedge_level; + end; + end; +end; + +procedure ttabs.dochange(const index: integer); +begin + inherited; + if (index < 0) and (fskinupdating = 0) and (count > 0) and + not (csloading in tcustomtabbar(fowner).componentstate) then begin + tcustomtabbar(fowner).updateskin; + //could be a new item which needs skin setup + end; +end; + +function ttabs.getframe: ttabframe; +begin + tcustomtabbar(fowner).getoptionalobject(fframe, + {$ifdef FPC}@{$endif}createframe); + result:= fframe; +end; + +procedure ttabs.setframe(const avalue: ttabframe); +var int1: integer; +begin + tcustomtabbar(fowner).setoptionalobject(avalue,fframe, + {$ifdef FPC}@{$endif}createframe); + if fframe = nil then begin + with tcustomtabbar(fowner).flayoutinfo do begin + for int1:= 0 to high(cells) do begin + with cells[int1] do begin + state:= state - [shs_flat,shs_noanimation]; + end; + end; + end; + end; + changed; +// tcustomtabbar(fowner).invalidatewidget; +end; + +procedure ttabs.createframe; +begin + if fframe = nil then begin + fframe:= ttabframe.create(iframe(self)); + end; +end; + +procedure ttabs.createfont; +begin + if ffont = nil then begin + ffont:= ttabsfont.create; + ffont.onchange:= {$ifdef FPC}@{$endif}fontchanged; + end; +end; + +function ttabs.getfont: ttabsfont; +begin + getoptionalobject(ttabbar(fowner).componentstate,ffont, + {$ifdef FPC}@{$endif}createfont); + if ffont <> nil then begin + result:= ffont; + end + else begin + result:= ttabsfont(pointer(ttabbar(fowner).getfont)); + end; +end; + +procedure ttabs.setfont(const avalue: ttabsfont); +begin + if avalue <> ffont then begin + setoptionalobject(ttabbar(fowner).ComponentState,avalue,ffont, + {$ifdef FPC}@{$endif}createfont); + changed; + end; +end; + +function ttabs.isfontstored: boolean; +begin + result:= ffont <> nil; +end; + +procedure ttabs.createfontactive; +begin + if ffontactive = nil then begin + ffontactive:= ttabsfontactive.create; + ffontactive.onchange:= {$ifdef FPC}@{$endif}fontchanged; + end; +end; + +function ttabs.getfontactive: ttabsfontactive; +begin + getoptionalobject(ttabbar(fowner).componentstate,ffontactive, + {$ifdef FPC}@{$endif}createfontactive); + if ffontactive <> nil then begin + result:= ffontactive; + end + else begin + result:= ttabsfontactive(pointer(ttabbar(fowner).getfont)); + end; +end; + +procedure ttabs.setfontactive(const avalue: ttabsfontactive); +begin + if avalue <> ffontactive then begin + setoptionalobject(ttabbar(fowner).ComponentState,avalue,ffontactive, + {$ifdef FPC}@{$endif}createfontactive); + changed; + end; +end; + +function ttabs.isfontactivestored: boolean; +begin + result:= ffontactive <> nil; +end; + +procedure ttabs.fontchanged(const sender: tobject); +begin + changed; +end; + +{ tcustomtabbar } + +constructor tcustomtabbar.create(aowner: tcomponent); +begin + flayoutinfo.tabs:= ttabs.create(self,nil); + flayoutinfo.tabs.onchange:= {$ifdef FPC}@{$endif}tabschanged; + flayoutinfo.activetab:= -1; + flayoutinfo.focusedtab:= -1; + flayoutinfo.lasttab:= -1; + fhintedbutton:= -2; + inherited; + fwidgetrect.cy:= font.glyphheight + 4; + foptionswidget1:= defaultoptionswidget1tab; +end; + +destructor tcustomtabbar.destroy; +begin + killrepeater(); + flayoutinfo.tabs.free(); + inherited; +end; + +procedure tcustomtabbar.settabs(const Value: ttabs); +begin + flayoutinfo.tabs.assign(Value); +end; + +procedure tcustomtabbar.updatelayout(); +var + int1,int2,int3: integer; +begin + with flayoutinfo do begin + options:= []; + if tabo_vertical in foptions then begin + include(options,shs_vert); + end; + if tabo_opposite in foptions then begin + include(options,shs_opposite); + end; + if tabo_vertical in foptions then begin + frame.buttonpos:= sbp_top; + frame.buttonslast:= ((tabo_opposite in foptions) xor + (tabo_buttonsoutside in foptions)); + end + else begin + frame.buttonpos:= sbp_right; + frame.buttonslast:= ((tabo_opposite in foptions) xor + (tabo_buttonsoutside in foptions)); + end; + for int3:= 7 downto 0 do begin; + dim:= innerclientrect; + calctablayout(flayoutinfo,getcanvas,focused); + + int2:= tabs.count; + for int1:= int2 - 1 downto 0 do begin + if not (ts_invisible in tabs[int1].fstate) then begin + int2:= int1+1; //count to last visible + break; + end + else begin + if int1 = 0 then begin + int2:= 0; + end; + end; + end; +{ + if shs_vert in options then begin + int4:= dim.size.cy - totsize.cy + tcustomstepframe1(fframe).fdim.cy; + end + else begin + int4:= dim.size.cx - totsize.cx + tcustomstepframe1(fframe).fdim.cx; + end; + notfull:= int4 >= 0; +} + if (firsttab = 0) and notfull then begin + int2:= 0; + end; + frame.updatebuttonstate(firsttab,stepinfo.pageup,int2); + include(fstate,tbs_layoutvalid); + checkautosize; + if sizeisequal(dim.size,innerclientsize) then begin + break; + end; + end; + end; +end; + +procedure tcustomtabbar.checklayout; +begin + if not (tbs_layoutvalid in fstate) then begin + updatelayout; + end; +end; + +procedure tcustomtabbar.layoutchanged; +begin + exclude(fstate,tbs_layoutvalid); + invalidate; + { + if not (csloading in componentstate) and + not (ws_loadedproc in fwidgetstate) and + not ((owner <> nil) and + ([csloading,csdestroying]*owner.ComponentState <> [])) and + not ((fparentwidget <> nil) and + (ws_loadedproc in twidget1(fparentwidget).fwidgetstate)) then begin + //todo: support for cssubcomponent in fpc +// updatelayout; +// checkautosize; + invalidate; + end; + } +end; + +function comptabs(const l,r): integer; +begin + result:= msecomparetext(ttab(l).frichcaption.text,ttab(r).frichcaption.text); +end; + +procedure tcustomtabbar.tabchanged(const sender: ttab); + + procedure updateactivetabindex; + var + int1: integer; + bo1: boolean; + begin + with flayoutinfo do begin + bo1:= false; + for int1:= 0 to tabs.count - 1 do begin + with tabs[int1] do begin + if ts_active in fstate then begin + bo1:= true; + if (activetab <> int1) then begin + if (activetab >= 0) and (activetab <= high(tabs.fitems)) then begin + exclude(tabs.items[activetab].fstate,ts_active); + end; + activetab:= int1; + end; + end; + end; + end; + if not bo1 then begin + activetab:= -1; + end; + end; + end; + +var + int1,int2: integer; + bo1: boolean; + activetabbefore: integer; +begin + if fupdating = 0 then begin + with flayoutinfo do begin + activetabbefore:= activetab; + updateactivetabindex; + bo1:= activetabbefore <> activetab; + if bo1 and assigned(finternaltabchange) then begin + finternaltabchange(false); + end; + if tabo_sorted in foptions then begin + sortarray(pointerarty(flayoutinfo.tabs.fitems), + {$ifdef FPC}@{$endif}comptabs); + updateactivetabindex; + if assigned(finternaltabchange) then begin + finternaltabchange(true); + end; + end; + if bo1 then begin + if (activetab >= 0) and (activetab <= high(cells)) then begin + if (tabo_acttabfirst in foptions) and (activetab <> 0) then begin + flayoutinfo.tabs.move(activetab,0); + updateactivetabindex; + end; + if activetab < firsttab then begin + firsttab:= activetab; + end + else begin + if activetab >= firsttab + stepinfo.pageup then begin + firsttab:= activetab + 1; + int2:= 0; + if shs_vert in options then begin + for int1:= activetab downto 0 do begin + if not (ts_invisible in tabs[int1].fstate) then begin + inc(int2,cells[int1].ca.dim.cy); + if int2 >= dim.cy then begin + break; + end; + dec(firsttab); + end; + end; + end + else begin + for int1:= activetab downto 0 do begin + if not (ts_invisible in tabs[int1].fstate) then begin + inc(int2,cells[int1].ca.dim.cx); + if int2 >= dim.cx then begin + break; + end; + dec(firsttab); + end; + end; + end; + if firsttab > activetab then begin + firsttab:= activetab; + end; + end; + end; + end; + doactivetabchanged; + end; + layoutchanged; + end; + end; +end; + +procedure tcustomtabbar.tabclicked(const sender: ttab; + const info: mouseeventinfoty); +begin + if (tabo_clickedtabfirst in foptions) or + (tabo_dblclickedtabfirst in foptions) and + (ss_double in info.shiftstate) then begin + movetab(sender.findex,0); + end; + sender.active:= true; + checklayout(); + include(flayoutinfo.cells[sender.index].state,shs_mouse); +end; + +procedure tcustomtabbar.tabschanged(const sender: tarrayprop; + const index: integer); +begin + tabchanged(nil); +end; + +procedure tcustomtabbar.loaded; +begin + inherited; +// updatelayout; + doactivetabchanged; +end; + +procedure tcustomtabbar.dopaintforeground(const canvas: tcanvas); +var + int1{,int2,int3}: integer; +// color1: colorty; + rect1: rectty; + size1: sizety; + edgelevel1: int32; + hiddenedges1: edgesty; + actcell1: int32; + po1: pshapeinfoty; +begin + inherited; + checklayout; + with flayoutinfo do begin +// int1:= high(cells); + edgelevel1:= tabs.fedge_level; + if edgelevel1 = defaultedgelevel then begin + edgelevel1:= -1; + end; + actcell1:= -1; + po1:= @cells[firsttab]; + for int1:= firsttab to lasttab do begin + with po1^ do begin + if int1 = activetab then begin + actcell1:= int1; + end + else begin + tabs.factcellindex:= int1; + frame:= tabs.fframe; //todo: move to layoutcalc + if frame <> nil then begin + drawtab(canvas,po1^,nil); + end + else begin + drawtab(canvas,po1^,@captionframe); + end; + end; + end; + inc(po1); + end; + if (tabs.fedge_imagelist <> nil) or (edgelevel1 <> 0) then begin + if shs_vert in options then begin + if shs_opposite in options then begin + int1:= -4; //imagebase + hiddenedges1:= [edg_top,edg_bottom,edg_right]; + end + else begin + int1:= 0; + hiddenedges1:= [edg_left,edg_top,edg_bottom]; + end; + end + else begin + if shs_opposite in options then begin + int1:= -6; + hiddenedges1:= [edg_left,edg_bottom,edg_right]; + end + else begin + int1:= -2; + end; + end; + rect1:= paintsizerect; + size1:= tcustomstepframe1(fframe).fdim.size; //todo: button positions + if shs_vert in options then begin + rect1.y:= rect1.y - size1.cy; + rect1.cy:= rect1.cy + size1.cy; + if shs_opposite in options then begin + hiddenedges1:= [edg_top,edg_bottom,edg_right]; + end + else begin + hiddenedges1:= [edg_left,edg_top,edg_bottom]; + end; + end + else begin + rect1.cx:= rect1.cx + size1.cx; + if shs_opposite in options then begin + hiddenedges1:= [edg_left,edg_bottom,edg_right]; + end + else begin + hiddenedges1:= [edg_left,edg_top,edg_right]; + end; + end; + if edgelevel1 <> 0 then begin + draw3dframe(canvas,rect1,edgelevel1, + tabs.fedge,hiddenedges1); + end; + if tabs.fedge_imagelist <> nil then begin + drawimageframe(canvas,tabs.fedge_imagelist,tabs.fedge_imageoffset+int1, + rect1,hiddenedges1); + end; + end; + if actcell1 >= 0 then begin + tabs.factcellindex:= actcell1; + po1:= @cells[actcell1]; + po1^.frame:= tabs.fframe; //todo: move to layoutcalc + if tabs.fframe = nil then begin + drawtab(canvas,po1^,@captionframe); + end + else begin + drawtab(canvas,po1^,nil); + end; + end; + end; +end; + +function tcustomtabbar.getactivetab: integer; +begin + result:= flayoutinfo.activetab; +end; + +procedure tcustomtabbar.setactivetab(const Value: integer); +var + int1: integer; + +begin + if value < 0 then begin + if activetab >= 0 then begin + flayoutinfo.tabs.items[activetab].state:= + flayoutinfo.tabs.items[activetab].state - [ts_active]; + end; + end + else begin + int1:= value; + if int1 >= tabs.count then begin + int1:= tabs.count - 1 + end; + if int1 >= 0 then begin + flayoutinfo.tabs.items[int1].state:= + flayoutinfo.tabs.items[int1].state + [ts_active]; + end; + end; +end; + +function tcustomtabbar.activetag: integer; + //0 if no activetab, activetab.tag otherwise +begin + with flayoutinfo do begin + if activetab < 0 then begin + result:= 0; + end + else begin + result:= tabs[activetab].ftag; + end; + end; +end; + +procedure tcustomtabbar.clientmouseevent(var info: mouseeventinfoty); +begin + if not (es_processed in info.eventstate) and + canevent(tmethod(fonclientmouseevent)) then begin + fonclientmouseevent(self,info); + end; + inherited; + if updatemouseshapestate(flayoutinfo.cells,info,self, + flayoutinfo.focusedtab,flayoutinfo.tabs.fframe) and + (not (csdesigning in componentstate) or + (tbs_designdrag in fstate)) then begin + include(info.eventstate,es_processed); + end; + if not (csdesigning in componentstate) or + (ws1_designactive in fwidgetstate1) then begin + with flayoutinfo do begin + checkbuttonhint(self,info,fhintedbutton,cells, + {$ifdef FPC}@{$endif}getbuttonhint, + {$ifdef FPC}@{$endif}gethintpos); + end; + end; +end; + +procedure tcustomtabbar.statechanged; +begin + inherited; + with flayoutinfo do begin + if (activetab >= 0) and (activetab <= high(cells)) then begin + updatewidgetshapestate(flayoutinfo.cells[activetab],self,false,fframe); + end; + end; +end; + +procedure tcustomtabbar.doshortcut(var info: keyeventinfoty; const sender: twidget); +var + int1,int2: integer; +begin + if not (csdesigning in componentstate) then begin + int2:= activetab + 1; + if int2 >= tabs.count then begin + int2:= 0; + end; + for int1:= int2 to tabs.count - 1 do begin + if es_processed in info.eventstate then begin + break; + end; + flayoutinfo.tabs[int1].doshortcut(info,sender); + end; + for int1:= 0 to int2 - 1 do begin + if es_processed in info.eventstate then begin + break; + end; + flayoutinfo.tabs[int1].doshortcut(info,sender); + end; + end; + inherited; +end; + +procedure tcustomtabbar.clientrectchanged; +begin + inherited; + layoutchanged; +end; +{ +procedure tcustomtabbar.dofontheightdelta(var delta: integer); +begin + if not (tabo_vertical in foptions) then begin + inherited; + if delta <> 0 then begin + synctofontheight; + end; + end + else begin + layoutchanged; + end; +end; +} +procedure tcustomtabbar.fontchanged; +begin + inherited; + layoutchanged; +end; + +procedure tcustomtabbar.getautopaintsize(var asize: sizety); +begin + inherited; + checklayout; + asize.cx:= flayoutinfo.totsize.cx; + asize.cy:= flayoutinfo.totsize.cy; + addsize1(asize,innerframewidth); + if tbs_shrinktozero in fstate then begin + if tabo_vertical in foptions then begin + asize.cx:= 0; + end + else begin + asize.cy:= 0; + end; + end; +end; + +procedure tcustomtabbar.synctofontheight; +var + size1: sizety; +begin + inherited; + if not (tabo_vertical in options) then begin + size1:= paintsize; + getautopaintsize(size1); + size1:= addsize(size1,fframe.paintframedim); + bounds_cy:= size1.cy; + end; +end; + +procedure tcustomtabbar.doactivetabchanged; +begin + if canevent(tmethod(fonactivetabchange)) then begin + fonactivetabchange(self); + end; +end; + +procedure tcustomtabbar.beginupdate; +begin + inc(fupdating); +end; + +procedure tcustomtabbar.endupdate; +begin + dec(fupdating); + if fupdating = 0 then begin + tabchanged(nil); + end; +end; + +function tcustomtabbar.tabatpos(const apos: pointty; const enabledonly: boolean = false): integer; +begin + begin + checklayout; + if enabledonly then begin + result:= findshapeatpos(flayoutinfo.cells,apos,[shs_invisible,shs_disabled]); + end + else begin + result:= findshapeatpos(flayoutinfo.cells,apos,[shs_invisible]); + end; + end; +end; + +procedure tcustomtabbar.movetab(curindex,newindex: integer); +begin + if canevent(tmethod(fontabmoving)) then begin + fontabmoving(self,curindex,newindex); + end; + flayoutinfo.tabs.move(curindex,newindex); + if canevent(tmethod(fontabmoved)) then begin + fontabmoved(self,curindex,newindex); + end; + if csdesigning in componentstate then begin + designchanged; + end; +end; + +function tcustomtabbar.dostep(const event: stepkindty; const adelta: real; + ashiftstate: shiftstatesty): boolean; +var + stepinfo1: framestepinfoty; + i1: int32; +begin + result:= false; + if frame.canstep then begin + stepinfo1:= flayoutinfo.stepinfo; + if ss_ctrl in ashiftstate then begin + with stepinfo1 do begin //reverst step height + i1:= pagedown; + pagedown:= down; + down:= i1; + i1:= pageup; + pageup:= up; + up:= i1; + end; + if stepinfo1.pagedown < -1 then begin + stepinfo1.pagedown:= -1; + end; + if stepinfo1.pageup > 1 then begin + stepinfo1.pageup:= 1; + end; + end; + firsttab:= frame.executestepevent(event,stepinfo1,flayoutinfo.firsttab); + result:= true; + end; +end; + +procedure tcustomtabbar.setfirsttab(Value: integer); +begin + with flayoutinfo do begin + if value >= tabs.count - 1 then begin + value:= tabs.count - 1; + end; + if value < 0 then begin + value:= 0; + end; + if firsttab <> value then begin + firsttab:= value; + layoutchanged; + end; + end; +end; + +procedure tcustomtabbar.setoptions(const avalue: tabbaroptionsty); +var + optionsbefore: tabbaroptionsty; + delta: tabbaroptionsty; + ow1: optionswidget1ty; +begin + if avalue <> foptions then begin + optionsbefore:= foptions; + foptions:= avalue; + delta:= avalue >< optionsbefore; + if not (csloading in componentstate) then begin + if (csdesigning in componentstate) and + (delta * [tabo_vertical] <> []) then begin + ow1:= optionswidget1; + if tabo_vertical in avalue then begin + exclude(ow1,ow1_autowidth); + if ow1_autowidth in optionswidget1 then begin + include(ow1,ow1_autoheight); + end + else begin + exclude(ow1,ow1_autoheight); + end; + end + else begin + include(ow1,ow1_autoheight); + if ow1_autoheight in optionswidget1 then begin + include(ow1,ow1_autowidth); + end + else begin + exclude(ow1,ow1_autowidth); + end; + end; + optionswidget1:= ow1; + end; + if (delta * [tabo_sorted,tabo_acttabfirst] <> []) then begin + tabchanged(nil); + end; + end; + if delta * [tabo_vertical,tabo_opposite,tabo_buttonsoutside] <> [] then begin + layoutchanged; + end; + end; +end; + +procedure tcustomtabbar.dragevent(var info: draginfoty); +var + int1: integer; + + function candest: boolean; + begin + with info do begin + if (dragobjectpo^ is ttagdragobject) and (dragobjectpo^.sender = self) and + ((tabo_dragdest in foptions) or (csdesigning in componentstate)) then begin + int1:= tabatpos(pos,(tabo_dragdestenabledonly in foptions) and + not(csdesigning in componentstate)); + result:= (ttagdragobject(dragobjectpo^).tag <> int1) and + ((int1 >= 0) {or (csdesigning in componentstate)}); + end + else begin + result:= false; + end; + end; + end; + +begin + if not fdragcontroller.beforedragevent(info) then begin + int1:= 0; + with info do begin + case eventkind of + dek_begin: begin + if (not (csdesigning in componentstate) or (tbs_designdrag in fstate)) and + (dragobjectpo^ = nil) and not (tabo_sorted in foptions) and + ((tabo_dragsource in foptions) or (csdesigning in componentstate)) then begin + int1:= tabatpos(pos,(tabo_dragsourceenabledonly in foptions) and + not (csdesigning in componentstate)); + if int1 >= 0 then begin + ttagdragobject.create(self,dragobjectpo^,fdragcontroller.pickpos,int1); + end; + end; + end; + dek_check: begin + int1:= tabatpos(pos,false); + with flayoutinfo do begin + if (int1 < 0) or not ((int1 = firsttab) or (int1 = lasttab)) then begin + killrepeater; + end + else begin + if (frepeater = nil) or + (not(int1 = firsttab) xor (tbs_repeatup in fstate)) then begin + startrepeater(int1 <> firsttab); + end; + end; + end; + if candest then begin + accept:= true; + end; + end; + dek_drop: begin + killrepeater(); + if candest then begin + movetab(ttagdragobject(dragobjectpo^).tag,int1); + end; + end; + dek_leavewidget: begin + killrepeater(); + end; + end; + end; + end; + fdragcontroller.afterdragevent(info); + if not info.accept then begin + inherited; + end; +end; + +procedure tcustomtabbar.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if event = oe_changed then begin + flayoutinfo.tabs.checktemplate(sender); + end; +end; + +function tcustomtabbar.gethintpos(const aindex: integer): rectty; +begin + result:= flayoutinfo.cells[aindex].ca.dim; + inc(result.cy,12); +end; + +function tcustomtabbar.getbuttonhint(const aindex: integer): msestring; +begin + result:= ''; + with flayoutinfo.tabs[aindex] do begin + if hint <> '' then begin + result:= hint; + end + else begin + if (ts_captionclipped in fstate) and + (tabo_hintclippedtext in options) then begin + result:= caption; + end; + end; + end; +end; + +procedure tcustomtabbar.enabledchanged; +begin + inherited; + if not (ws_loadedproc in fwidgetstate) then begin + layoutchanged; + end; +end; + +class function tcustomtabbar.classskininfo: skininfoty; +begin + result:= inherited classskininfo; + result.objectkind:= sok_tabbar; +end; + +function tcustomtabbar.upstep(const norotate: boolean): boolean; +var + int1: integer; +begin + result:= false; + with flayoutinfo do begin + for int1:= activetab + 1 to high(cells) do begin + if tabs[int1].state * [ts_invisible,ts_disabled] = [] then begin + result:= true; + self.activetab:= int1; + exit; + end; + end; + if not norotate then begin + for int1:= 0 to activetab - 1 do begin + if tabs[int1].state * [ts_invisible,ts_disabled] = [] then begin + result:= true; + self.activetab:= int1; + exit; + end; + end; + end; + end; +end; + +function tcustomtabbar.downstep(const norotate: boolean): boolean; +var + int1: integer; +begin + result:= false; + with flayoutinfo do begin + for int1:= activetab -1 downto 0 do begin + if tabs[int1].state * [ts_invisible,ts_disabled] = [] then begin + result:= true; + self.activetab:= int1; + exit; + end; + end; + if not norotate then begin + for int1:= high(cells) downto activetab + 1 do begin + if tabs[int1].state * [ts_invisible,ts_disabled] = [] then begin + result:= true; + self.activetab:= int1; + exit; + end; + end; + end; + end; +end; + +function tcustomtabbar.getassistivecaption(): msestring; +begin + with flayoutinfo do begin + if (focusedtab >= 0) and (focusedtab < tabs.count) then begin + result:= tabs[focusedtab].caption; + end + else begin + result:= inherited getassistivecaption(); + end; + end; +end; + +function tcustomtabbar.getassistivehint(): msestring; +begin + with flayoutinfo do begin + if (focusedtab >= 0) and (focusedtab < tabs.count) then begin + result:= tabs[focusedtab].hint; + end + else begin + result:= inherited getassistivehint(); + end; + end; +end; + +procedure tcustomtabbar.dokeydown(var info: keyeventinfoty); +var + bo1: boolean; +begin + if not (es_processed in info.eventstate) then begin + bo1:= false; + if shs_vert in flayoutinfo.options then begin + case info.key of + key_down: begin + bo1:= upstep(ow_arrowfocusout in optionswidget); + end; + key_up: begin + bo1:= downstep(ow_arrowfocusout in optionswidget); + end; + end; + end + else begin + case info.key of + key_right: begin + bo1:= upstep(ow_arrowfocusout in optionswidget); + end; + key_left: begin + bo1:= downstep(ow_arrowfocusout in optionswidget); + end; + end; + end; + if bo1 then begin + include(info.eventstate,es_processed); + end + else begin + inherited; + end; + end; +end; + +procedure tcustomtabbar.startrepeater(const up: boolean); +begin + killrepeater; + updatebit(longword(fstate),ord(tbs_repeatup),up); + frepeater:= trepeater.create(500000,200000,@repeatproc); +end; + +procedure tcustomtabbar.killrepeater; +begin + freeandnil(frepeater); +end; + +procedure tcustomtabbar.repeatproc(const sender: tobject); +begin + if tbs_repeatup in fstate then begin + checklayout(); + if flayoutinfo.notfull then begin + killrepeater; + end + else begin + firsttab:= firsttab + 1; + end; + end + else begin + firsttab:= firsttab - 1; + end; +end; + +{ ttabbar } + +procedure ttabbar.dostatread(const reader: tstatreader); +begin + flayoutinfo.tabs.dostatread(reader,tabo_dragdest in foptions); + if reader.canstate then begin + activetab:= reader.readinteger('activetab',activetab); + end; +end; + +procedure ttabbar.dostatwrite(const writer: tstatwriter); +begin + flayoutinfo.tabs.dostatwrite(writer,tabo_dragdest in foptions); + if writer.canstate then begin + writer.writeinteger('activetab',activetab); + end; +end; + +function ttabbar.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +procedure ttabbar.setdragcontroller(const Value: tdragcontroller); +begin + fdragcontroller.assign(Value); +end; + +procedure ttabbar.setstatfile(const Value: tstatfile); +begin + setstatfilevar(istatfile(self),value,fstatfile); +end; + +procedure ttabbar.statreading; +begin + //dummy +end; + +procedure ttabbar.statread; +begin + //dummy +end; + +function ttabbar.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +{ ttabpagefonttab } + +class function ttabpagefonttab.getinstancepo(owner: tobject): pfont; +begin + result:= @ttabpage(owner).ffonttab; +end; + +{ ttabpagefontactivetab } + +class function ttabpagefontactivetab.getinstancepo(owner: tobject): pfont; +begin + result:= @ttabpage(owner).ffontactivetab; +end; + +{ ttabpage } + +constructor ttabpage.create(aowner: tcomponent); +begin + ftaborderoverride:= ttaborderoverride.create(self); + inherited; + fcolortab:= cl_default; + fcoloractivetab:= cl_default; + fimagenr:= -1; +// fimagenractive:= -2; + fimagenrdisabled:= -2; + foptionswidget:= defaulttaboptionswidget; + optionsskin:= defaulttabpageskinoptions; + exclude(fwidgetstate,ws_visible); +end; + +destructor ttabpage.destroy; +begin + inherited; + freeandnil(ffonttab); + freeandnil(ffontactivetab); + ftaborderoverride.free(); +end; + +class function ttabpage.classskininfo: skininfoty; +begin + result:= inherited classskininfo; + result.objectkind:= sok_tabpage; +end; + +procedure ttabpage.loaded; +begin + if fparentwidget is tcustomtabwidget then begin + include(fwidgetstate1,ws1_nodesignvisible); + end; + inherited; +end; + +procedure ttabpage.changed; +begin + if (ftabwidget <> nil) then begin + ftabwidget.pagechanged(itabpage(self)); + end; +end; + +procedure ttabpage.fontchanged1(const sender: tobject); +begin + changed; +end; + +function ttabpage.getcaption: captionty; +begin + result:= fcaption; +end; + +procedure ttabpage.setcaption(const Value: captionty); +begin + fcaption:= value; + changed; +end; + +function ttabpage.gettabhint: msestring; +begin + result:= ftabhint; +end; + +procedure ttabpage.settabhint(const avalue: msestring); +begin + ftabhint:= avalue; + changed; +end; + +function ttabpage.gettabnoface: boolean; +begin + result:= ftabnoface; +end; + +procedure ttabpage.settabnoface(const avalue: boolean); +begin + if ftabnoface <> avalue then begin + ftabnoface:= avalue; + changed; + end; +end; + +function ttabpage.getcolortab: colorty; +begin + result:= fcolortab; +end; + +procedure ttabpage.setcolortab(const avalue: colorty); +begin + if fcolortab <> avalue then begin + fcolortab:= avalue; + changed; + end; +end; + +function ttabpage.getcoloractivetab: colorty; +begin + result:= fcoloractivetab; +end; + +procedure ttabpage.setcoloractivetab(const avalue: colorty); +begin + if fcoloractivetab <> avalue then begin + fcoloractivetab:= avalue; + changed; + end; +end; + +procedure ttabpage.setfacetab(const avalue: tfacecomp); +begin + if ffacetab <> avalue then begin + setlinkedvar(avalue,tmsecomponent(ffacetab)); + changed(); + end; +end; + +procedure ttabpage.setfaceactivetab(const avalue: tfacecomp); +begin + if ffaceactivetab <> avalue then begin + setlinkedvar(avalue,tmsecomponent(ffaceactivetab)); + changed(); + end; +end; + +function ttabpage.getfacetab: tfacecomp; +begin + result:= ffacetab; +end; + +function ttabpage.getfaceactivetab: tfacecomp; +begin + result:= ffaceactivetab; +end; + +function ttabpage.isvisiblestored: boolean; +begin + result:= not (fparentwidget is tcustomtabwidget); +end; + +procedure ttabpage.settaborderoverride(const avalue: ttaborderoverride); +begin + ftaborderoverride.assign(avalue); +end; + +procedure ttabpage.registerchildwidget(const child: twidget); +begin + if child is ttabpage then begin + child.parentwidget:= parentwidget; + end + else begin + inherited; + end; +end; + +function ttabpage.gettabwidget: tcustomtabwidget; +begin + result:= ftabwidget; +end; + +procedure ttabpage.settabwidget(const value: tcustomtabwidget); +begin + ftabwidget:= value; +end; + +procedure ttabpage.visiblechanged; +begin + inherited; + changed; +end; + +procedure ttabpage.enabledchanged; +begin + inherited; + changed; +end; + +procedure ttabpage.designselected(const selected: boolean); +begin + inherited; + if selected then begin + if ftabwidget <> nil then begin + ftabwidget.activepage:= self; + end; + end; +end; + +function ttabpage.getisactivepage: boolean; +begin + result:= (ftabwidget <> nil) and (ftabwidget.activepage = self); +end; + +procedure ttabpage.setisactivepage(const avalue: boolean); +begin + if ftabwidget <> nil then begin + ftabwidget.activepage:= self; + end; +end; + +function ttabpage.nexttaborderoverride(const sender: twidget; + const down: boolean): twidget; +begin + result:= ftaborderoverride.nexttaborder(sender,down); + if result = nil then begin + result:= inherited nexttaborderoverride(sender,down); + end; +end; + +procedure ttabpage.readstate(reader: treader); +begin + inherited; + ttaborderoverride1(ftaborderoverride).endread(reader); +end; + +function ttabpage.gettabindex: integer; +begin + if tabwidget = nil then begin + result:= -1; + end + else begin + result:= tabwidget.indexof(self); + end; +end; + +procedure ttabpage.settabindex(const avalue: integer); +begin + if tabwidget <> nil then begin + tabwidget.movepage(tabindex,avalue); + end; +end; + +procedure ttabpage.doselect; +var + subformclass: widgetclassty; + po1: pwidget; + wi1: twidget; +begin + if assigned(fongetsubform) then begin + if fsubform = nil then begin + subformclass:= nil; + fsubforminstancevarpo:= nil; + fongetsubform(self,subformclass,fsubforminstancevarpo); + if subformclass <> nil then begin + po1:= fsubforminstancevarpo; + if po1 = nil then begin + po1:= @wi1; + end; + mseclasses.createmodule(self,subformclass,po1^); + setlinkedvar(po1^,tmsecomponent(fsubform)); +// setlinkedvar(subformclass.create(self),tmsecomponent(fsubform)); + insertwidget(fsubform,nullpoint); +// if fsubforminstancevarpo <> nil then begin +// fsubforminstancevarpo^:= fsubform; +// end; + if assigned(foninitsubform) then begin + foninitsubform(self,fsubform); + end; + fsubform.visible:= true; + end; + end; + end; + if assigned(fonselect) then begin + fonselect(self); + end; +end; + +procedure ttabpage.dodeselect; +begin + if canevent(tmethod(fondeselect)) then begin + fondeselect(self); + end; + if fsubform <> nil then begin + if fsubform.forceclose then begin + fsubform.free; + end + else begin + tabwidget.activepageindex:= tabindex; //reactivate + end; + end; +end; + +function ttabpage.getimagelist: timagelist; +begin + result:= fimagelist +end; + +procedure ttabpage.setimagelist(const avalue: timagelist); +begin + if fimagelist <> avalue then begin + setlinkedvar(avalue,tmsecomponent(fimagelist)); + changed; + end; +end; + +function ttabpage.getimagenr: imagenrty; +begin + result:= fimagenr; +end; + +procedure ttabpage.setimagenr(const avalue: imagenrty); +begin + if fimagenr <> avalue then begin + fimagenr:= avalue; + changed; + end; +end; +{ +function ttabpage.getimagenractive: integer; +begin + result:= fimagenractive; +end; + +procedure ttabpage.setimagenractive(const avalue: integer); +begin + if fimagenractive <> avalue then begin + fimagenractive:= avalue; + changed; + end; +end; +} +function ttabpage.getimagenrdisabled: imagenrty; +begin + result:= fimagenrdisabled; +end; + +procedure ttabpage.setimagenrdisabled(const avalue: imagenrty); +begin + if fimagenrdisabled <> avalue then begin + fimagenrdisabled:= avalue; + changed; + end; +end; + +function ttabpage.getinvisible: boolean; +begin + result:= finvisible; +end; + +procedure ttabpage.setinvisible(const avalue: boolean); +begin + if finvisible <> avalue then begin + finvisible:= avalue; + changed; + end; +end; + +procedure ttabpage.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (event = oe_destroyed) and (sender = fsubform) then begin + if fsubforminstancevarpo <> nil then begin + fsubforminstancevarpo^:= nil; + end; + end; + if sender = fimagelist then begin + if event = oe_destroyed then begin + fimagelist:= nil; + changed; + end + else begin + if event = oe_changed then begin + changed; + end; + end; + end; +end; + +procedure ttabpage.initnewcomponent(const ascale: real); +begin + inherited; + caption:= 'caption'; +end; + +procedure ttabpage.createfonttab; +begin + if ffonttab = nil then begin + ffonttab:= ttabpagefonttab.create; + ffonttab.onchange:= {$ifdef FPC}@{$endif}fontchanged1; + end; +end; + +procedure ttabpage.createfontactivetab; +begin + if ffontactivetab = nil then begin + ffontactivetab:= ttabpagefontactivetab.create; + ffontactivetab.onchange:= {$ifdef FPC}@{$endif}fontchanged1; + end; +end; + +function ttabpage.getfonttab: tfont; +begin + result:= ffonttab; +end; + +function ttabpage.getfontactivetab: tfont; +begin + result:= ffontactivetab; +end; + +function ttabpage.getfonttab1: ttabpagefonttab; +begin + getoptionalobject(ffonttab, + {$ifdef FPC}@{$endif}createfonttab); + result:= ffonttab; +end; + +procedure ttabpage.setfonttab1(const avalue: ttabpagefonttab); +begin + if avalue <> ffonttab then begin + setoptionalobject(avalue,ffonttab, + {$ifdef FPC}@{$endif}createfonttab); + changed; + end; +end; + +procedure ttabpage.setfonttab(const avalue: tfont); +begin + setfonttab1(ttabpagefonttab(avalue)); +end; + +function ttabpage.isfonttabstored: boolean; +begin + result:= ffonttab <> nil; +end; + +function ttabpage.getfontactivetab1: ttabpagefontactivetab; +begin + getoptionalobject(ffontactivetab, + {$ifdef FPC}@{$endif}createfontactivetab); + result:= ffontactivetab; +end; + +procedure ttabpage.setfontactivetab1(const avalue: ttabpagefontactivetab); +begin + if avalue <> ffontactivetab then begin + setoptionalobject(avalue,ffontactivetab, + {$ifdef FPC}@{$endif}createfontactivetab); + changed; + end; +end; + +procedure ttabpage.setfontactivetab(const avalue: tfont); +begin + setfontactivetab1(ttabpagefontactivetab(avalue)); +end; + +function ttabpage.isfontactivetabstored: boolean; +begin + result:= ffontactivetab <> nil; +end; + + +{ +function ttabpage.gettabwidth: integer; +begin + result:= ftabwidth; +end; + +procedure ttabpage.settabwidth(const avalue: integer); +begin + ftabwidth:= avalue; + changed; +end; + +function ttabpage.gettabwidthmin: integer; +begin + result:= ftabwidthmin; +end; + +procedure ttabpage.settabwidthmin(const avalue: integer); +begin + ftabwidthmin:= avalue; + changed; +end; + +function ttabpage.gettabwidthmax: integer; +begin + result:= ftabwidthmax; +end; + +procedure ttabpage.settabwidthmax(const avalue: integer); +begin + ftabwidthmax:= avalue; + changed; +end; +} +{ ttab_font } + +class function ttab_font.getinstancepo(owner: tobject): pfont; +begin + result:= @tcustomtabwidget(owner).ftabs.ffont; +end; + +{ ttab_fonttab } + +class function ttab_fonttab.getinstancepo(owner: tobject): pfont; +begin + result:= @tcustomtabwidget(owner).ftabs.tabs.ffont; +end; + +{ ttab_fontactivetab } + +class function ttab_fontactivetab.getinstancepo(owner: tobject): pfont; +begin + result:= @tcustomtabwidget(owner).ftabs.tabs.ffontactive; +end; + +{ tcustomtabwidget } + +constructor tcustomtabwidget.create(aowner: tcomponent); +begin + factivepageindex:= -1; + factivepageindexdesign:= -1; + ftab_sizemin:= defaulttabsizemin; + ftab_sizemax:= defaulttabsizemax; + inherited; + foptionswidget:= defaulttaboptionswidget; + optionsskin:= defaulttaboptionsskin; + ftabs:= tcustomtabbar1.create(self,nil,true); + include(ftabs.fwidgetstate1,ws1_designactive); + include(ftabs.fstate,tbs_designdrag); + ftabs.fanchors:= [an_left,an_top,an_right]; + ftab_size:= ftabs.size.cy; + ftabs.SetSubComponent(true); + ftabs.tabs.oncreatetab:= {$ifdef FPC}@{$endif}createpagetab; + exclude(ftabs.fwidgetstate,ws_iswidget); + ftabs.setlockedparentwidget(self); + ftabs.finternaltabchange:= {$ifdef FPC}@{$endif}tabchanged; + fobjectpicker:= tobjectpicker.create(iobjectpicker(self),org_widget); +end; + +destructor tcustomtabwidget.destroy; +begin + fobjectpicker.free; + ftabs.free; + inherited; +end; + +procedure tcustomtabwidget.clear; +begin + beginupdate(); + try + while count > 0 do begin + items[count-1].Free; + end; + finally + endupdate(); + end; +end; + +function tcustomtabwidget.getitems(const index: integer): twidget; +begin + result:= tpagetab(ftabs.tabs[index]).page; +end; + +function tcustomtabwidget.getitemsintf(const index: integer): itabpage; +begin + result:= tpagetab(ftabs.tabs[index]).fpageintf; +end; + +procedure tcustomtabwidget.pagechanged(const sender: itabpage); +var + widget1: twidget1; + int1: integer; + activepageindexbefore: integer; + bo1: boolean; + updatingbefore: boolean; +begin + if not (ws_destroying in fwidgetstate) then begin + widget1:= twidget1(sender.getwidget); + int1:= indexof(widget1); + if widget1.visible then begin + fvisiblepage:= int1; + end; + with ftabs.tabs[int1] do begin + updatingbefore:= ts_updating in fstate; + include(fstate,ts_updating); + if not (csloading in componentstate) and + not (ws_loadedproc in fwidgetstate) and (fupdating <= 0) then begin + activepageindexbefore:= factivepageindex; + caption:= sender.getcaption; + hint:= sender.gettabhint; + color:= sender.getcolortab; + coloractive:= sender.getcoloractivetab; + face:= sender.getfacetab; + faceactive:= sender.getfaceactivetab; + bo1:= sender.gettabnoface; + if bo1 then begin + state:= state + [ts_noface]; + end + else begin + state:= state - [ts_noface]; + end; + font:= ttabfont(sender.getfonttab); + fontactive:= ttabfontactive(sender.getfontactivetab); + imagelist:= sender.getimagelist; + imagenr:= sender.getimagenr; + imagenrdisabled:= sender.getimagenrdisabled; + bo1:= not (csdesigning in componentstate) and sender.getinvisible; + + if not widget1.enabled then begin + state:= state + [ts_disabled]; + end + else begin + state:= state - [ts_disabled]; + end; + if bo1 then begin + state:= state + [ts_invisible] + end + else begin + state:= state - [ts_invisible] + end; + if (not bo1 or (activepageindexbefore <> int1)) and widget1.isvisible and + (widget1.enabled or (csdesigning in widget1.componentstate)) then begin + state:= state - [ts_invisible]; + setactivepageindex(int1); + end + else begin + if (activepageindexbefore = int1) and + not (csdestroying in componentstate) then begin + changepage(1); + if factivepageindex = activepageindexbefore then begin + setactivepageindex(-1); //select none + end + else begin + if (activepage <> nil) and not activepage.entered and + (entered or ((fwindow <> nil) and + (fwindow.focusedwidget = nil))) and activepage.canfocus then begin + //probably page destroyed + activepage.setfocus(active); + end; + end; + end; + end; + if not updatingbefore then begin + exclude(fstate,ts_updating); + changed; + end; + end + else begin + caption:= sender.getcaption; //no updatelayout + if not updatingbefore then begin + exclude(fstate,ts_updating); + end; + end; + end; + end; +end; + +procedure tcustomtabwidget.loaded; +var + int1: integer; + po1: ppagetabaty; +begin + inc(fdesignchangedlock); + if factivepageindexdesign >= count then begin + factivepageindex:= -1; + factivepageindexdesign:= -1; + end; + if not (csdesigning in componentstate) and (factivepageindexdesign >= 0) then begin + factivepageindex:= factivepageindexdesign; + end; + if factivepageindex >= 0 then begin + if (fvisiblepage >= 0) and (fvisiblepage <> factivepageindex) and + (fvisiblepage < count) then begin + items[fvisiblepage].visible:= false; + end; + items[factivepageindex].visible:= true; + end; + inherited; + ftabs.loaded; + updatesize(nil); +// int1:= factivepageindex; + factivepageindex:= -1; +// setactivepageindex(int1); + with ftabs.flayoutinfo.tabs do begin + po1:= pointer(fitems); + for int1:= 0 to high(fitems) do begin + pagechanged(po1^[int1].fpageintf); + end; + end; +// ftabs.loaded; + dec(fdesignchangedlock); +end; + +procedure tcustomtabwidget.updatesize(const page: twidget); +var + rect1: rectty; + + procedure updatepagesize(const apage: twidget); + var + rect2: rectty; + begin + with rect2 do begin + if tabo_vertical in ftabs.options then begin + cx:= rect1.cx - ftabs.bounds_cx; + y:= rect1.y; + cy:= rect1.cy; + if tabo_opposite in ftabs.options then begin + x:= rect1.x; + end + else begin + x:= rect1.x + ftabs.bounds_cx; + end; + end + else begin + cy:= rect1.cy - ftabs.bounds_cy; + x:= rect1.x; + cx:= rect1.cx; + if tabo_opposite in ftabs.options then begin + y:= rect1.y; + end + else begin + y:= rect1.y + ftabs.bounds_cy; + end; + end; + end; + apage.widgetrect:= rect2; + end; + +var + int1: integer; + bo1: boolean; +begin + if not (csloading in componentstate) and + not (tbs_updatesizing in ftabs.fstate) then begin + //recursion lock + include(ftabs.fstate,tbs_updatesizing); + try + rect1:= innerwidgetrect; + if page <> nil then begin + updatepagesize(page); + end + else begin + bo1:= (tabo_notabsdesign in ftabs.options) or + not (csdesigning in componentstate) and + ((tabo_multitabsonly in ftabs.options) and (count < 2) or + (tabo_notabs in ftabs.options)); + if bo1 then begin + include(ftabs.fstate,tbs_shrinktozero); + end + else begin + exclude(ftabs.fstate,tbs_shrinktozero); + end; + if tabo_vertical in ftabs.options then begin + if tabo_opposite in ftabs.options then begin + if bo1 then begin + ftabs.setwidgetrect(makerect(rect1.x+rect1.cx,rect1.y, + 0,rect1.cy)); + end + else begin + ftabs.setwidgetrect(makerect(rect1.x+rect1.cx-ftab_size,rect1.y, + ftab_size,rect1.cy)); + end; + end + else begin + if bo1 then begin + ftabs.setwidgetrect(makerect(rect1.x,rect1.y,0,rect1.cy)); + end + else begin + ftabs.setwidgetrect(makerect(rect1.x,rect1.y,ftab_size,rect1.cy)); + end; + end; + end + else begin + if tabo_opposite in ftabs.options then begin + if bo1 then begin + ftabs.setwidgetrect(makerect(rect1.x,rect1.y+rect1.cy, + rect1.cx,0)); + end + else begin + ftabs.setwidgetrect(makerect(rect1.x,rect1.y+rect1.cy-ftab_size, + rect1.cx,ftab_size)); + end; + end + else begin + if bo1 then begin + ftabs.setwidgetrect(makerect(rect1.x,rect1.y,rect1.cx,0)); + end + else begin + ftabs.setwidgetrect(makerect(rect1.x,rect1.y,rect1.cx,ftab_size)); + end; + end; + end; + for int1:= 0 to ftabs.tabs.count - 1 do begin + updatepagesize(items[int1]); + end; + end; + finally + exclude(ftabs.fstate,tbs_updatesizing); + end; + end; +end; + +procedure tcustomtabwidget.readtab_captionpos(reader: treader); +begin + tab_imagepos:= readcaptiontoimagepos(reader); +end; + +procedure tcustomtabwidget.readoptions(reader: treader); +begin + tab_options:= tabbaroptionsty( + {$ifndef FPC}word(integer({$endif} + readset(reader,typeinfo(tabbaroptionsty)) + {$ifndef FPC})){$endif}); + if tabo_vertical in tab_options then begin + tab_optionswidget1:= []; + end; +end; + +procedure tcustomtabwidget.readtab_captionframe_left(reader: treader); +begin + ftabs.flayoutinfo.tabs.createframe(); + ttabframe1(ftabs.flayoutinfo.tabs.fframe).fi.innerframe.left:= + reader.readinteger(); +end; + +procedure tcustomtabwidget.readtab_captionframe_top(reader: treader); +begin + ftabs.flayoutinfo.tabs.createframe(); + ttabframe1(ftabs.flayoutinfo.tabs.fframe).fi.innerframe.top:= + reader.readinteger(); +end; + +procedure tcustomtabwidget.readtab_captionframe_right(reader: treader); +begin + ftabs.flayoutinfo.tabs.createframe(); + ttabframe1(ftabs.flayoutinfo.tabs.fframe).fi.innerframe.right:= + reader.readinteger(); +end; + +procedure tcustomtabwidget.readtab_captionframe_bottom(reader: treader); +begin + ftabs.flayoutinfo.tabs.createframe(); + ttabframe1(ftabs.flayoutinfo.tabs.fframe).fi.innerframe.bottom:= + reader.readinteger(); +end; + +procedure tcustomtabwidget.readtab_imagedist(reader: treader); +begin + ftabs.flayoutinfo.tabs.createframe(); + ttabframe1(ftabs.flayoutinfo.tabs.fframe).fi.imagedist:= reader.readinteger(); +end; + +procedure tcustomtabwidget.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('tab_captionpos',@readtab_captionpos,nil,false); + filer.defineproperty('options',@readoptions,nil,false); + filer.defineproperty('tab_captionframe_left', + @readtab_captionframe_left,nil,false); + filer.defineproperty('tab_captionframe_top', + @readtab_captionframe_top,nil,false); + filer.defineproperty('tab_captionframe_right', + @readtab_captionframe_right,nil,false); + filer.defineproperty('tab_captionframe_bottom', + @readtab_captionframe_bottom,nil,false); + filer.defineproperty('tab_imagedist', @readtab_imagedist,nil,false); +end; + +procedure tcustomtabwidget.internaladd(const page: itabpage; aindex: integer); +var + tab: tpagetab; + widget1: twidget1; +begin + widget1:= twidget1(page.getwidget); + if indexof(widget1) < 0 then begin + include(widget1.fmsecomponentstate,cs_parentwidgetrect); + if aindex > count then begin + aindex:= count; + end; + widget1.visible:= false; + tab:= tpagetab.create(ftabs,page); + if not (csreading in componentstate) then begin +// if not (csloading in componentstate) then begin + ftabs.tabs.insert(tab,aindex); + with widget1 do begin + parentwidget:= self; + anchors:= [an_bottom,an_top,an_left,an_right]; + end; + updatesize(widget1); + end + else begin + ftabs.tabs.beginupdate; + ftabs.tabs.insert(tab,aindex); + ftabs.tabs.endupdate(true); + end; + include(widget1.fwidgetstate1,ws1_nodesignvisible); + page.settabwidget(self); + pagechanged(page); +// if not (csloading in componentstate) then begin + if not (csreading in componentstate) then begin +// activepageindex:= aindex; + setactivepageindex(aindex); + end; + dopageadded(widget1); + end; +end; + +procedure tcustomtabwidget.internalremove(const page: itabpage); +var + int1: integer; + widget1: twidget1; + activebefore: integer; + + procedure check(var aindex: integer); + begin + if aindex >= 0 then begin + if aindex > int1 then begin + dec(aindex); + end + else begin + if aindex = int1 then begin + aindex:= -1; + end; + end; + end; + end; //check + +begin + if ftabs <> nil then begin + widget1:= twidget1(page.getwidget); + int1:= indexof(widget1); + if int1 >= 0 then begin + exclude(widget1.fmsecomponentstate,cs_parentwidgetrect); + activebefore:= factivepageindex; + check(factivepageindex); + check(factivepageindexdesign); + ftabs.flayoutinfo.activetab:= factivepageindex; + ftabs.tabs.delete(int1); + with widget1 do begin + exclude(fwidgetstate1,ws1_nodesignvisible); + if page.gettabwidget = self then begin + page.settabwidget(nil); + end; + end; + dopageremoved(widget1); + if (activebefore <> factivepageindex) and (factivepageindex = -1) then begin + nextpage(activebefore,true); + if factivepageindex = -1 then begin + doactivepagechanged; + end; + end; + end; + end; +end; + +procedure tcustomtabwidget.registerchildwidget(const child: twidget); +var + intf: itabpage; +begin + inherited; + if twidget1(child).getcorbainterface(typeinfo(itabpage),intf) then begin + internaladd(intf,bigint); + end; +end; + +procedure tcustomtabwidget.add(const aitem: itabpage; + const aindex: integer = bigint); +begin + internaladd(aitem,aindex); +end; + +procedure tcustomtabwidget.unregisterchildwidget(const child: twidget); +var + intf: itabpage; +begin + inherited; + if not (csdestroying in componentstate) and + twidget1(child).getcorbainterface(typeinfo(itabpage),intf) then begin + internalremove(intf); + end; +end; + +function tcustomtabwidget.indexof(const page: twidget): integer; +var + int1: integer; +begin + result:= -1; + for int1:= 0 to count-1 do begin + if items[int1] = page then begin + result:= int1; + break; + end; + end; +end; + +procedure tcustomtabwidget.GetChildren(Proc: TGetChildProc; Root: TComponent); +var + int1: integer; + widget1: twidget1; +begin + for int1:= 0 to high(fwidgets) do begin + exclude(twidget1(fwidgets[int1]).fwidgetstate1,ws1_isstreamed); + end; + for int1:= 0 to count-1 do begin + widget1:= twidget1(items[int1]); + if widget1.owner = root then begin + proc(widget1); + include(widget1.fwidgetstate1,ws1_isstreamed); + end; + end; + for int1:= 0 to widgetcount - 1 do begin + widget1:= twidget1(fwidgets[int1]); + if not (ws1_isstreamed in widget1.fwidgetstate1) and + (widget1.owner = root) and + (ws_iswidget in widget1.fwidgetstate) then begin + proc(widget1); + end; + end; +end; + +procedure tcustomtabwidget.setactivepageindex(Value: integer); +var + int1: integer; + parenttabfocus: boolean; + widget1,widget2: twidget; +begin + if (value <> factivepageindex) or (fupdating > 0) then begin + if csloading in componentstate then begin + factivepageindex:= value; + factivepageindex1:= value; + exit; + end; + if (value >= 0) then begin + ftabs.flayoutinfo.tabs.checkindex(value); + end + else begin + value:= -1; + end; + if fupdating > 0 then begin + factivepageindex1:= value; + end + else begin + parenttabfocus:= ow_parenttabfocus in foptionswidget; + exclude(foptionswidget,ow_parenttabfocus); + try + if factivepageindex >= 0 then begin + widget1:= items[factivepageindex]; + int1:= factivepageindex; + if not (csdestroying in widget1.componentstate) then begin + widget2:= widget1; + if ow1_canclosenil in widget1.optionswidget1 then begin + widget2:= nil; + end; + if not widget1.canparentclose(widget2) then begin + ftabs.tabs[factivepageindex].active:= true; + exit; + end; + factivepageindex:= -1; + if not (csloading in componentstate) then begin + tpagetab(ftabs.tabs[int1]).fpageintf.dodeselect; + if (factivepageindex <> -1) then begin + exit; + end; + end; + items[int1].visible:= false; + if (factivepageindex <> -1) or items[int1].visible then begin + exit; + end; + end; + ftabs.tabs[int1].active:= false; //if items[int1] was already invisible + end; + factivepageindex:= Value; + if value >= 0 then begin + defaultfocuschild:= items[value]; + if not (csloading in componentstate) then begin + tpagetab(ftabs.tabs[value]).fpageintf.doselect; + if factivepageindex <> value then begin + exit; + end; + end; + with items[value] do begin + bringtofront; //needed in design mode where all widgets are visible + inc(fupdating); + try + visible:= true; + finally + dec(fupdating); + end; + if self.entered and canfocus and not ftabs.focused then begin + setfocus(false); + end; + end; + end + else begin + defaultfocuschild:= nil; + end; + if (value = factivepageindex) then begin + doactivepagechanged; + if (value >= 0) and (value = factivepageindex) then begin + ftabs.tabs[value].active:= true + end; + end; + finally + if parenttabfocus then begin + include(foptionswidget,ow_parenttabfocus); + end; + end; + end; + end; +end; + +procedure tcustomtabwidget.tabchanged(const synctabindex: boolean); +begin + if synctabindex and (factivepageindex >= 0) then begin + factivepageindex:= ftabs.activetab; + end + else begin + setactivepageindex(ftabs.activetab); + end; +// activepageindex:= ftabs.activetab; +end; + +function tcustomtabwidget.count: integer; +begin + result:= ftabs.tabs.count; +end; + +function tcustomtabwidget.getactivepage: twidget; +begin + if factivepageindex >= 0 then begin + result:= items[factivepageindex]; + end + else begin + result:= nil; + end; +end; + +function tcustomtabwidget.getactivepageintf: itabpage; +begin + if factivepageindex >= 0 then begin + result:= itemsintf[factivepageindex]; + end + else begin + result:= nil; + end; +end; + +procedure tcustomtabwidget.setactivepage(const value: twidget); +begin + if value = nil then begin + setactivepageindex(-1); + end + else begin + setactivepageindex(indexof(value)); + end; +end; + +procedure tcustomtabwidget.clientrectchanged; +var + size1: sizety; +begin + inherited; + if not (csloading in componentstate) then begin + size1:= innerclientsize; + if tabo_vertical in ftabs.foptions then begin + if size1.cx < tab_size then begin + tab_size:= size1.cx + end + else begin + updatesize(nil); + end; + end + else begin + if size1.cy < tab_size then begin + tab_size:= size1.cy + end + else begin + updatesize(nil); + end; + end; + end; +end; + +procedure tcustomtabwidget.doactivepagechanged; +begin + if canevent(tmethod(fonactivepagechanged)) then begin + fonactivepagechanged(self); + end; +// designchanged; +end; + +procedure tcustomtabwidget.dopageadded(const apage: twidget); +begin + if canevent(tmethod(fonpageadded)) then begin + fonpageadded(self,apage); + end; +end; + +procedure tcustomtabwidget.dopageremoved(const apage: twidget); +begin + if canevent(tmethod(fonpageremoved)) then begin + fonpageremoved(self,apage); + end; +end; + +procedure tcustomtabwidget.nextpage(newindex: integer; down: boolean); +var + int1: integer; +begin + if count > 0 then begin + if (newindex >= count) or (newindex < 0) then begin + if down then begin + newindex:= count - 1; + end + else begin + newindex:= 0; + end; + end; + int1:= newindex; + repeat + if (items[int1].enabled) and not (ts_invisible in ftabs.tabs[int1].state) or + (csdesigning in componentstate) then begin + setactivepageindex(int1); + break; + end + else begin + if down then begin + dec(int1); + if int1 < 0 then begin + int1:= count - 1; + end; + end + else begin + inc(int1); + if int1 >= count then begin + int1:= 0; + end; + end; + end; + until int1 = newindex; + if int1 = factivepageindex then begin + if not ((items[int1].enabled) and not (ts_invisible in ftabs.tabs[int1].state) + or (csdesigning in componentstate)) then begin + setactivepageindex(-1); + end; + end; + end; +end; + +procedure tcustomtabwidget.changepage(step: integer); +begin + nextpage(factivepageindex+step,step < 0); +end; + +procedure tcustomtabwidget.movepage(const curindex,newindex: integer); +begin + ftabs.movetab(curindex,newindex); +end; + +procedure tcustomtabwidget.dokeydown(var info: keyeventinfoty); +begin + with info do begin + if (shiftstate = [ss_ctrl]) or (shiftstate = [ss_shift,ss_ctrl]) then begin + include(eventstate,es_processed); + case key of + key_tab: begin + changepage(1); + end; + key_backtab: begin + changepage(-1); + end + else begin + exclude(eventstate,es_processed); + end; + end; + end; + if not (es_processed in eventstate) then begin + inherited; + end; + end; +end; + +procedure tcustomtabwidget.childmouseevent(const sender: twidget; + var info: mouseeventinfoty); +begin + inherited; + if not (es_processed in info.eventstate) and + not ftabs.fdragcontroller.active and + ((sender = self) or (sender = ftabs) or (sender = activepage)) then begin + translatewidgetpoint1(info.pos,sender,self); + fobjectpicker.mouseevent(info); + translatewidgetpoint1(info.pos,self,sender); + end; +end; + +procedure tcustomtabwidget.dobeforepaint(const canvas: tcanvas); +begin + fobjectpicker.dobeforepaint(canvas); + inherited; +end; + +procedure tcustomtabwidget.doafterpaint(const canvas: tcanvas); +begin + inherited; + fobjectpicker.doafterpaint(canvas); +end; + +procedure tcustomtabwidget.synctofontheight; +begin + inherited; + if not (tabo_vertical in tab_options) then begin + ftabs.synctofontheight; + tab_size:= ftabs.bounds_cy; + end; +end; + +function tcustomtabwidget.checktabsizingpos(const apos: pointty): boolean; +begin + with ftabs,moverect(ftabs.paintrect,ftabs.fwidgetrect.pos) do begin + if tabo_tabsizing in foptions then begin + if tabo_vertical in foptions then begin + if tabo_opposite in foptions then begin + result:= pointinrect(apos,makerect(x-sizingtol,y,sizingwidth,cy)); + end + else begin + result:= pointinrect(apos,makerect(x+cx-sizingtol,y,sizingwidth,cy)); + end; + end + else begin + if tabo_opposite in foptions then begin + result:= pointinrect(apos,makerect(y,y-sizingtol,cx,sizingwidth)); + end + else begin + result:= pointinrect(apos,makerect(y,y+cy-sizingtol,cx,sizingwidth)); + end; + end; + end + else begin + result:= false; + end; + end; +end; + +function tcustomtabwidget.getidents: integerarty; +begin + result:= ftabs.flayoutinfo.tabs.idents; +end; + +procedure tcustomtabwidget.setstatfile(const Value: tstatfile); +begin + setstatfilevar(istatfile(self),value,fstatfile); +end; + + //istatfile +procedure tcustomtabwidget.dostatread(const reader: tstatreader); +begin + ftabs.flayoutinfo.tabs.dostatread(reader,tabo_dragdest in tab_options); + if reader.canstate then begin + if tabo_tabsizing in tab_options then begin + tab_size:= reader.readinteger('tabsize',tab_size); + end; + ftabs.firsttab:= reader.readinteger('firsttab',ftabs.firsttab); + setactivepageindex(reader.readinteger('index',activepageindex,-1,count-1)); + end; +end; + +procedure tcustomtabwidget.dostatwrite(const writer: tstatwriter); +begin + ftabs.flayoutinfo.tabs.dostatwrite(writer,tabo_dragdest in tab_options); + if writer.canstate then begin + if tabo_tabsizing in tab_options then begin + writer.writeinteger('tabsize',tab_size); + end; + writer.writeinteger('firsttab',ftabs.firsttab); + writer.writeinteger('index',activepageindex); + end; +end; + +procedure tcustomtabwidget.statreading; +begin + //dummy; +end; + +procedure tcustomtabwidget.statread; +begin + //dummy; +end; + +function tcustomtabwidget.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + + //iobjectpicker +function tcustomtabwidget.getcursorshape(const sender: tobjectpicker; + var shape: cursorshapety): boolean; + //true if found +begin + result:= checktabsizingpos(sender.pos); + if result then begin + if tabo_vertical in ftabs.foptions then begin + shape:= cr_sizehor; + end + else begin + shape:= cr_sizever; + end; + end +end; + +procedure tcustomtabwidget.getpickobjects(const sender: tobjectpicker; + var objects: integerarty); +begin + if checktabsizingpos(sender.pos) then begin + setlength(objects,1); + end; +end; + +procedure tcustomtabwidget.beginpickmove(const sender: tobjectpicker); +begin + //dummy +end; + +function tcustomtabwidget.checkpickoffset(const aoffset: pointty): pointty; +begin + result:= aoffset; + with ftabs do begin + if tabo_opposite in foptions then begin + result.x:= -result.x; + result.y:= -result.y; + end; + if tabo_vertical in foptions then begin + if tab_size + result.x > tab_sizemax then begin + result.x:= tab_sizemax - tab_size; + end; + if tab_size + result.x > self.paintrect.cx then begin + result.x:= self.paintrect.cx - tab_size; + end; + if tab_size + result.x < tab_sizemin then begin + result.x:= tab_sizemin - tab_size; + end; + end + else begin + if tab_size + result.y > tab_sizemax then begin + result.y:= tab_sizemax - tab_size; + end; + if tab_size + result.y > self.paintrect.cy then begin + result.y:= self.paintrect.cy - tab_size; + end; + if tab_size + result.y < tab_sizemin then begin + result.y:= tab_sizemin - tab_size; + end; + end; + if tabo_opposite in foptions then begin + result.x:= -result.x; + result.y:= -result.y; + end; + end; +end; + +procedure tcustomtabwidget.endpickmove(const sender: tobjectpicker); +var + offset1: pointty; +begin + offset1:= checkpickoffset(sender.pickoffset); + with ftabs do begin + if tabo_vertical in foptions then begin + if tabo_opposite in foptions then begin + tab_size:= tab_size - offset1.x; + end + else begin + tab_size:= tab_size + offset1.x; + end; + end + else begin + if tabo_opposite in foptions then begin + tab_size:= tab_size - offset1.y; + end + else begin + tab_size:= tab_size + offset1.y; + end; + end; + end; +end; + +procedure tcustomtabwidget.paintxorpic(const sender: tobjectpicker; + const canvas: tcanvas); +var + offset1: pointty; +begin + offset1:= checkpickoffset(sender.pickoffset); + with ftabs,ftabs.fwidgetrect do begin + if tabo_vertical in options then begin + if tabo_opposite in foptions then begin + canvas.fillxorrect(makepoint(x+offset1.x,y),cy,gd_down,2, + stockobjects.bitmaps[stb_dens50]); + end + else begin + canvas.fillxorrect(makepoint(x+cx+offset1.x,y),cy,gd_down,2, + stockobjects.bitmaps[stb_dens50]); + end; + end + else begin + if tabo_opposite in foptions then begin + canvas.fillxorrect(makepoint(x,y+offset1.y),cx,gd_right,2, + stockobjects.bitmaps[stb_dens50]); + end + else begin + canvas.fillxorrect(makepoint(x,y+cy+offset1.y),cx,gd_right,2, + stockobjects.bitmaps[stb_dens50]); + end; + end; + end; +end; + +function tcustomtabwidget.gettab_options: tabbaroptionsty; +begin + result:= ftabs.options; +end; + +procedure tcustomtabwidget.settab_options(const avalue: tabbaroptionsty); +var + optionsbefore: tabbaroptionsty; +begin + optionsbefore:= ftabs.options; + ftabs.options:= avalue; + if (optionsbefore >< ftabs.options) * + [tabo_vertical,tabo_opposite, + tabo_multitabsonly,tabo_notabs,tabo_notabsdesign] <> [] then begin + if tabo_vertical in avalue then begin + ftabs.anchors:= [an_left,an_top,an_bottom]; + end + else begin + ftabs.anchors:= [an_left,an_top,an_right]; + end; + updatesize(nil); + end; +end; + +function tcustomtabwidget.gettab_color: colorty; +begin + Result := ftabs.color; +end; + +procedure tcustomtabwidget.settab_color(const avalue: colorty); +begin + ftabs.color:= avalue; +end; + +function tcustomtabwidget.gettab_frame: tstepboxframe1; +begin + result:= tstepboxframe1(ftabs.frame); +end; + +procedure tcustomtabwidget.settab_frame(const avalue: tstepboxframe1); +begin + ftabs.frame:= avalue; +end; + +function tcustomtabwidget.gettab_face: tface; +begin + Result:= ftabs.face; +end; + +procedure tcustomtabwidget.settab_face(const avalue: tface); +begin + ftabs.face:= avalue; +end; + +function tcustomtabwidget.gettab_colortab: colorty; +begin + result:= ftabs.tabs.color; +end; + +procedure tcustomtabwidget.settab_colortab(const avalue: colorty); +begin + ftabs.tabs.color:= avalue; +end; + +function tcustomtabwidget.gettab_coloractivetab: colorty; +begin + result:= ftabs.tabs.coloractive; +end; + +procedure tcustomtabwidget.settab_coloractivetab(const avalue: colorty); +begin + ftabs.tabs.coloractive:= avalue; +end; + +function tcustomtabwidget.gettab_frametab: ttabframe; +begin + result:= ftabs.tabs.frame; +end; + +procedure tcustomtabwidget.settab_frametab(const avalue: ttabframe); +begin + ftabs.tabs.frame:= avalue; +end; + +function tcustomtabwidget.gettab_facetab: tface; +begin + result:= ftabs.tabs.face; +end; + +procedure tcustomtabwidget.settab_facetab(const avalue: tface); +begin + ftabs.tabs.face:= avalue; +end; + +function tcustomtabwidget.gettab_faceactivetab: tface; +begin + result:= ftabs.tabs.faceactive; +end; + +procedure tcustomtabwidget.settab_faceactivetab(const avalue: tface); +begin + ftabs.tabs.faceactive:= avalue; +end; + +function tcustomtabwidget.gettab_imagepos: imageposty; +begin + result:= ftabs.tabs.imagepos; +end; + +procedure tcustomtabwidget.settab_imagepos(const avalue: imageposty); +begin + ftabs.tabs.imagepos:= avalue; +end; +{ +function tcustomtabwidget.gettab_captionframe_left: integer; +begin + result:= ftabs.tabs.captionframe_left; +end; + +procedure tcustomtabwidget.settab_captionframe_left(const avalue: integer); +begin + ftabs.tabs.captionframe_left:= avalue; +end; + +function tcustomtabwidget.gettab_captionframe_top: integer; +begin + result:= ftabs.tabs.captionframe_top; +end; + +procedure tcustomtabwidget.settab_captionframe_top(const avalue: integer); +begin + ftabs.tabs.captionframe_top:= avalue; +end; + +function tcustomtabwidget.gettab_captionframe_right: integer; +begin + result:= ftabs.tabs.captionframe_right; +end; + +procedure tcustomtabwidget.settab_captionframe_right(const avalue: integer); +begin + ftabs.tabs.captionframe_right:= avalue; +end; + +function tcustomtabwidget.gettab_captionframe_bottom: integer; +begin + result:= ftabs.tabs.captionframe_bottom; +end; + +procedure tcustomtabwidget.settab_captionframe_bottom(const avalue: integer); +begin + ftabs.tabs.captionframe_bottom:= avalue; +end; + +function tcustomtabwidget.gettab_imagedist: integer; +begin + result:= ftabs.tabs.imagedist; +end; + +procedure tcustomtabwidget.settab_imagedist(const avalue: integer); +begin + ftabs.tabs.imagedist:= avalue; +end; +} +function tcustomtabwidget.gettab_shift: integer; +begin + result:= ftabs.tabs.shift; +end; + +procedure tcustomtabwidget.settab_shift(const avalue: integer); +begin + ftabs.tabs.shift:= avalue; +end; + +procedure tcustomtabwidget.createpagetab(const sender: tcustomtabbar; + const index: integer; var tab: ttab); +begin + tab:= tpagetab.create(sender,nil); +end; + +procedure tcustomtabwidget.settab_size(const avalue: integer); +begin + if ftab_size <> avalue then begin + ftab_size:= avalue; + if ftab_size < ftab_sizemin then begin + ftab_size:= ftab_sizemin; + end + else begin + if ftab_size > ftab_sizemax then begin + ftab_size:= ftab_sizemax; + end; + end; + if not (csloading in componentstate) then begin + updatesize(nil); + end; + end; +end; + +procedure tcustomtabwidget.widgetregionchanged(const sender: twidget); +begin + inherited; + if not (csdestroying in componentstate) and (sender = ftabs) and + not (ws1_updateopaque in twidget1(sender).fwidgetstate1) and + not (tbs_shrinktozero in ftabs.fstate) then begin + if tabo_vertical in ftabs.options then begin + tab_size:= ftabs.bounds_cx; + end + else begin + tab_size:= ftabs.bounds_cy; + end; + end; +end; + + +procedure tcustomtabwidget.settab_sizemin(const avalue: integer); +begin + ftab_sizemin:= avalue; + if avalue > ftab_size then begin + tab_size:= avalue; + end; +end; + +procedure tcustomtabwidget.settab_sizemax(const avalue: integer); +begin + ftab_sizemax:= avalue; + if avalue < ftab_size then begin + tab_size:= avalue; + end; +end; + +function tcustomtabwidget.pagebyname(const aname: string): twidget; +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + result:= items[int1]; + if result.name = aname then begin + exit; + end; + end; + raise exception.create('Tabpage '''+aname+''' not found.'); +end; + +procedure tcustomtabwidget.doclosepage(const sender: tobject); +begin + items[fpopuptab].visible:= false; + ftabs.tabs[fpopuptab].state:= ftabs.tabs[fpopuptab].state + [ts_invisible]; +end; + +procedure tcustomtabwidget.updatepopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); +begin + if (tabo_autopopup in tab_options) then begin + fpopuptab:= ftabs.tabatpos(translateclientpoint(mouseinfo.pos,self,ftabs)); + if fpopuptab >= 0 then begin + tpopupmenu.additems(amenu,self,mouseinfo, + [stockobjects.captions[sc_close_page]], + [],[],[{$ifdef FPC}@{$endif}doclosepage]); + end; + end; + inherited; +end; + +function tcustomtabwidget.gettab_optionswidget: optionswidgetty; +begin + result:= ftabs.optionswidget; +end; + +procedure tcustomtabwidget.settab_optionswidget(const avalue: optionswidgetty); +begin + ftabs.optionswidget:= avalue; +end; + +function tcustomtabwidget.gettab_optionswidget1: optionswidget1ty; +begin + result:= ftabs.optionswidget1; +end; + +procedure tcustomtabwidget.settab_optionswidget1(const avalue: optionswidget1ty); +begin + ftabs.optionswidget1:= avalue; +end; + +function tcustomtabwidget.gettab_optionsskin: optionsskinty; +begin + result:= ftabs.optionsskin; +end; + +procedure tcustomtabwidget.settab_optionsskin(const avalue: optionsskinty); +begin + ftabs.optionsskin:= avalue; +end; + +function tcustomtabwidget.getedge_level: int32; +begin + result:= ftabs.tabs.edge_level; +end; + +procedure tcustomtabwidget.setedge_level(const avalue: int32); +begin + ftabs.tabs.edge_level:= avalue; +end; + +function tcustomtabwidget.getedge_colordkshadow: colorty; +begin + result:= ftabs.tabs.edge_colordkshadow; +end; + +procedure tcustomtabwidget.setedge_colordkshadow(const avalue: colorty); +begin + ftabs.tabs.edge_colordkshadow:= avalue; +end; + +function tcustomtabwidget.getedge_colorshadow: colorty; +begin + result:= ftabs.tabs.edge_colorshadow; +end; + +procedure tcustomtabwidget.setedge_colorshadow(const avalue: colorty); +begin + ftabs.tabs.edge_colorshadow:= avalue; +end; + +function tcustomtabwidget.getedge_colorlight: colorty; +begin + result:= ftabs.tabs.edge_colorlight; +end; + +procedure tcustomtabwidget.setedge_colorlight(const avalue: colorty); +begin + ftabs.tabs.edge_colorlight:= avalue; +end; + +function tcustomtabwidget.getedge_colorhighlight: colorty; +begin + result:= ftabs.tabs.edge_colorhighlight; +end; + +procedure tcustomtabwidget.setedge_colorhighlight(const avalue: colorty); +begin + ftabs.tabs.edge_colorhighlight:= avalue; +end; + +function tcustomtabwidget.getedge_colordkwidth: int32; +begin + result:= ftabs.tabs.edge_colordkwidth; +end; + +procedure tcustomtabwidget.setedge_colordkwidth(const avalue: int32); +begin + ftabs.tabs.edge_colordkwidth:= avalue; +end; + +function tcustomtabwidget.getedge_colorhlwidth: int32; +begin + result:= ftabs.tabs.edge_colorhlwidth; +end; + +procedure tcustomtabwidget.setedge_colorhlwidth(const avalue: int32); +begin + ftabs.tabs.edge_colorhlwidth:= avalue; +end; + +function tcustomtabwidget.getedge_imagelist: timagelist; +begin + result:= ftabs.tabs.edge_imagelist; +end; + +procedure tcustomtabwidget.setedge_imagelist(const avalue: timagelist); +begin + ftabs.tabs.edge_imagelist:= avalue; +end; + +function tcustomtabwidget.getedge_imageoffset: int32; +begin + result:= ftabs.tabs.edge_imageoffset; +end; + +procedure tcustomtabwidget.setedge_imageoffset(const avalue: int32); +begin + ftabs.tabs.edge_imageoffset:= avalue; +end; + +function tcustomtabwidget.getedge_imagepaintshift: int32; +begin + result:= ftabs.tabs.edge_imagepaintshift; +end; + +procedure tcustomtabwidget.setedge_imagepaintshift(const avalue: int32); +begin + ftabs.tabs.edge_imagepaintshift:= avalue; +end; + +function tcustomtabwidget.gettab_font: ttab_font; +begin +{$warnings off} + result:= ttab_font(ftabs.font); +{$warnings on} +end; + +procedure tcustomtabwidget.settab_font(const avalue: ttab_font); +begin +{$warnings off} + ftabs.font:= twidgetfont(avalue); +{$warnings on} +end; + +function tcustomtabwidget.istab_fontstored: boolean; +begin + result:= ftabs.ffont <> nil; +end; + +function tcustomtabwidget.gettab_fonttab: ttab_fonttab; +begin +{$warnings off} + result:= ttab_fonttab(ftabs.tabs.font); +{$warnings on} +end; + +procedure tcustomtabwidget.settab_fonttab(const avalue: ttab_fonttab); +begin +{$warnings off} + ftabs.tabs.font:= ttabsfont(avalue); +{$warnings on} +end; + +function tcustomtabwidget.istab_fonttabstored: boolean; +begin + result:= ftabs.tabs.ffont <> nil; +end; + +function tcustomtabwidget.gettab_fontactivetab: ttab_fontactivetab; +begin +{$warnings off} + result:= ttab_fontactivetab(ftabs.tabs.fontactive); +{$warnings on} +end; + +procedure tcustomtabwidget.set_tabfontactivetab(const avalue: ttab_fontactivetab); +begin +{$warnings off} + ftabs.tabs.fontactive:= ttabsfontactive(avalue); +{$warnings on} +end; + +function tcustomtabwidget.istab_fontactivetabstored: boolean; +begin + result:= ftabs.tabs.ffontactive <> nil; +end; + +function tcustomtabwidget.gettab_textflags: textflagsty; +begin + result:= ftabs.tabs.ftextflags; +end; + +procedure tcustomtabwidget.settab_textflags(const avalue: textflagsty); +begin + ftabs.tabs.textflags:= avalue; +end; + +function tcustomtabwidget.gettab_width: integer; +begin + result:= ftabs.tabs.width; +end; + +procedure tcustomtabwidget.settab_width(const avalue: integer); +begin + ftabs.tabs.width:= avalue; +end; + +function tcustomtabwidget.gettab_widthmin: integer; +begin + result:= ftabs.tabs.widthmin; +end; + +procedure tcustomtabwidget.settab_widthmin(const avalue: integer); +begin + ftabs.tabs.widthmin:= avalue; +end; + +function tcustomtabwidget.gettab_widthmax: integer; +begin + result:= ftabs.tabs.widthmax; +end; + +procedure tcustomtabwidget.settab_widthmax(const avalue: integer); +begin + ftabs.tabs.widthmax:= avalue; +end; + +procedure tcustomtabwidget.pickthumbtrack(const sender: tobjectpicker); +begin + //dummy +end; + +procedure tcustomtabwidget.cancelpickmove(const sender: tobjectpicker); +begin + //dummy +end; + +function tcustomtabwidget.getactivepageindex: integer; +begin + if fupdating > 0 then begin + result:= factivepageindex1; + end + else begin + result:= factivepageindex; + end; + if csdesigning in componentstate then begin + result:= factivepageindexdesign; + end; +end; + +procedure tcustomtabwidget.setactivepageindex1(const avalue: integer); +begin + setactivepageindex(avalue); + factivepageindexdesign:= avalue;//factivepageindex; +end; + +procedure tcustomtabwidget.beginupdate; +begin + if fupdating = 0 then begin + factivepageindex1:= factivepageindex; + end; + inc(fupdating); + ftabs.beginupdate; +end; + +procedure tcustomtabwidget.endupdate; +var + int1: integer; +begin + dec(fupdating); + if fupdating = 0 then begin + if factivepageindex1 < count then begin + activepageindex:= factivepageindex1; + end; + with ftabs.tabs do begin + for int1:= 0 to high(fitems) do begin + with tpagetab(fitems[int1]) do begin + self.pagechanged(fpageintf); + end; + end; + end; + end; + ftabs.endupdate; + if fupdating = 0 then begin + updatesize(nil); + end; +end; + +procedure tcustomtabwidget.clearorder; +begin + ftabs.tabs.clearorder; +end; + +function tcustomtabwidget.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +procedure tcustomtabwidget.createtabframe(); +begin + ftabs.createframe(); +end; + +procedure tcustomtabwidget.createtabface(); +begin + ftabs.createface(); +end; + +procedure tcustomtabwidget.createtabfont(); +begin + ftabs.createfont(); +end; + +procedure tcustomtabwidget.createtabframetab(); +begin + ftabs.tabs.createframe(); +end; + +procedure tcustomtabwidget.createtabfacetab(); +begin + ftabs.tabs.createface(); +end; + +procedure tcustomtabwidget.createtabfonttab(); +begin + ftabs.tabs.createfont(); +end; + +procedure tcustomtabwidget.createtabfaceactivetab; +begin + ftabs.tabs.createfaceactive(); +end; + +procedure tcustomtabwidget.createtabfontactivetab; +begin + ftabs.tabs.createfontactive(); +end; + +{ tpagetab } + +constructor tpagetab.create(const aowner: tcustomtabbar; const apage: itabpage); +begin + fpageintf:= apage; + inherited create(aowner); +end; + +function tpagetab.page: twidget; +begin + result:= fpageintf.getwidget; +end; + +{ tcustomtabbar1 } + +procedure tcustomtabbar1.internalcreateframe; +begin + tstepboxframe1.create(iscrollframe(self),istepbar(self)); +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/msetabsglob.pas b/mseide-msegui/lib/common/widgets/msetabsglob.pas new file mode 100644 index 0000000..fc30f63 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msetabsglob.pas @@ -0,0 +1,30 @@ +{ MSEgui Copyright (c) 1999-2007 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msetabsglob; +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$endif} +interface +const + defaulttabsizemin = 15; + defaulttabsizemax = 200; + +type + tabbaroptionty = (tabo_dragsource,tabo_dragdest, + tabo_dragsourceenabledonly,tabo_dragdestenabledonly, + //no action on disabled pages + tabo_vertical,tabo_opposite, + tabo_multitabsonly,tabo_notabs,tabo_notabsdesign, + tabo_buttonsoutside,tabo_tabsizing, + tabo_acttabfirst,tabo_clickedtabfirst, + tabo_dblclickedtabfirst, + tabo_sorted,tabo_autopopup,tabo_hintclippedtext); + tabbaroptionsty = set of tabbaroptionty; + +implementation +end. diff --git a/mseide-msegui/lib/common/widgets/msetoolbar.pas b/mseide-msegui/lib/common/widgets/msetoolbar.pas new file mode 100644 index 0000000..3bc239d --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msetoolbar.pas @@ -0,0 +1,2013 @@ +{ MSEgui Copyright (c) 1999-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msetoolbar; + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + msetypes,classes,mclasses,msewidgets,msearrayprops,mseclasses,msebitmap, + mseact,mseshapes,msemenus,msedragglob, + msegraphutils,msegraphics,mseevent, + mseglob,mseguiglob,msegui,msesimplewidgets, + msestat,msestatfile,msedrag,msestrings; + +type + + tcustomtoolbar = class; + + tcustomtoolbutton = class(tindexpersistent,iactionlink,iimagelistinfo) + private + finfo: actioninfoty; +// fonupdate: actioneventty; + procedure setaction(const Value: tcustomaction); + procedure setimagenr(const Value: imagenrty); + procedure setimagenrdisabled(const Value: imagenrty); + procedure setcolorglyph(const avalue: colorty); + function iscolorglyphstored: boolean; + procedure setcolor(const avalue: colorty); + function iscolorstored: boolean; + procedure setimagecheckedoffset(const Value: integer); + function getstate: actionstatesty; + function isstatestored: Boolean; + procedure setstate(const Value: actionstatesty); + function isimagenrstored: Boolean; + function isimagenrdisabledstored: Boolean; + function isimagecheckedoffsetstored: Boolean; + function isimageliststored: Boolean; virtual; + function getimagelist: timagelist; + procedure setimagelist(const Value: timagelist); virtual; + function isgroupstored: Boolean; + procedure setgroup(const Value: integer); + procedure changed; + function getchecked: boolean; + procedure setchecked(const Value: boolean); + procedure sethint(const Value: msestring); + function ishintstored: Boolean; + procedure setonexecute(const avalue: notifyeventty); + function isonexecutestored: Boolean; + procedure setonbeforeexecute(const avalue: accepteventty); + function isonbeforeexecutestored: Boolean; + procedure setonafterexecute(const avalue: notifyeventty); + function isonafterexecutestored: Boolean; + procedure setoptions(const Value: menuactionoptionsty); + procedure setshortcut(const value: shortcutty); + function isshortcutstored: boolean; + function getshortcut: shortcutty; + function getshortcut1: shortcutty; + procedure setshortcut1(const value: shortcutty); + function isshortcut1stored: boolean; + function getenabled: boolean; + function getvisible: boolean; + procedure setenabled(const avalue: boolean); + procedure setvisible(const avalue: boolean); + procedure readbool(reader: treader); + procedure writebool(writer: twriter); + procedure setshortcuts(const avalue: shortcutarty); + procedure setshortcuts1(const avalue: shortcutarty); + protected + ftag: integer; + ftagpo: pointer; + procedure doexecute(const tag: integer; const info: mouseeventinfoty); + procedure objectevent(const sender: tobject; const event: objecteventty); override; + procedure defineproperties(filer: tfiler); override; + //iactionlink + procedure actionchanged; + function getactioninfopo: pactioninfoty; + procedure doshortcut(var info: keyeventinfoty); + function getinstance: tobject; override; + function loading: boolean; + function shortcutseparator: msechar; + procedure calccaptiontext(var ainfo: actioninfoty); + + public + constructor create(const aowner: tobject; + const aprop: tindexpersistentarrayprop); overload; override; + constructor create(aowner: tcustomtoolbar); reintroduce; overload; + function toolbar: tcustomtoolbar; + function index: integer; + procedure execute; + procedure doupdate; + property checked: boolean read getchecked write setchecked; + property visible: boolean read getvisible write setvisible default true; + property enabled: boolean read getenabled write setenabled default true; + property shortcuts: shortcutarty read finfo.shortcut write setshortcuts; + property shortcuts1: shortcutarty read finfo.shortcut1 write setshortcuts1; + property imagelist: timagelist read getimagelist write setimagelist + stored isimageliststored; + property imagenr: imagenrty read finfo.imagenr write setimagenr + stored isimagenrstored default -1; + property imagenrdisabled: imagenrty read finfo.imagenrdisabled + write setimagenrdisabled + stored isimagenrdisabledstored default -2; + property colorglyph: colorty read finfo.colorglyph write setcolorglyph + stored iscolorglyphstored default cl_default; + property color: colorty read finfo.color write setcolor + stored iscolorstored default cl_default; + property imagecheckedoffset: integer read finfo.imagecheckedoffset + write setimagecheckedoffset + stored isimagecheckedoffsetstored default 0; + property hint: msestring read finfo.hint write sethint stored ishintstored; + property action: tcustomaction read finfo.action write setaction; + property state: actionstatesty read getstate write setstate + stored isstatestored default []; + property shortcut: shortcutty read getshortcut write setshortcut + stored isshortcutstored default 0; + property shortcut1: shortcutty read getshortcut1 write setshortcut1 + stored isshortcut1stored default 0; + property options: menuactionoptionsty read finfo.options + write setoptions default []; + property group: integer read finfo.group write setgroup + stored isgroupstored default 0; + property tag: integer read ftag write ftag default 0; + property tagpo: pointer read ftagpo write ftagpo; + property tagpointer: pointer read ftagpo write ftagpo; + deprecated 'Use tagpo instead'; + property onexecute: notifyeventty read finfo.onexecute write setonexecute + stored isonexecutestored; + property onbeforeexecute: accepteventty read finfo.onbeforeexecute + write setonbeforeexecute stored isonbeforeexecutestored; + property onafterexecute: notifyeventty read finfo.onafterexecute + write setonafterexecute stored isonafterexecutestored; +// property onupdate: actioneventty read fonupdate write fonupdate; + end; + + ttoolbutton = class(tcustomtoolbutton) + published + property imagelist; + property imagenr; + property imagenrdisabled; + property colorglyph; + property color; + property imagecheckedoffset; + property hint; + property action; + property state; + property shortcut; + property shortcut1; + property tag; + property options; + property group; + property onexecute; + property onbeforeexecute; + property onafterexecute; + end; + ptoolbutton = ^ttoolbutton; + + tcustomstockglyphtoolbutton = class(tcustomtoolbutton) + private + function isimageliststored: boolean; override; + procedure setimagelist(const Value: timagelist); override; + public + constructor create(const aowner: tobject; + const aprop: tindexpersistentarrayprop); overload; override; + end; + + tstockglyphtoolbutton = class(tcustomstockglyphtoolbutton) + published + property imagelist; + property imagenr; + property imagenrdisabled; + property colorglyph; + property color; + property imagecheckedoffset; + property hint; + property action; + property state; + property shortcut; + property shortcut1; + property tag; + property options; + property group; + property onexecute; + property onbeforeexecute; + property onafterexecute; + end; + +const + defaulttoolbuttonoptionsskin = [fso_flat,fso_nofocusrect,fso_nodefaultrect]; + defaulttoolseparatoroptionsskin = defaulttoolbuttonoptionsskin - [fso_flat]; + +type + ttoolbuttonframe = class(tframe) + public + constructor create(const aintf: iframe); + published + property optionsskin default defaulttoolbuttonoptionsskin; + end; + + ttoolseparatorframe = class(ttoolbuttonframe) + public + constructor create(const aintf: iframe); + published + property optionsskin default defaulttoolseparatoroptionsskin; + end; + + toolbuttonsstatety = (tbs_nocandefocus); + toolbuttonsstatesty = set of toolbuttonsstatety; + toolbuttonclassty = class of tcustomtoolbutton; + + tcustomtoolbuttons = class(tindexpersistentarrayprop) + private + fheight: integer; + fwidth: integer; + fimagelist: timagelist; + fcolorglyph: colorty; + fcolor: colorty; + fface: tface; + ffacechecked: tface; + fframe: ttoolbuttonframe; + fframechecked: ttoolbuttonframe; + fframesephorz: ttoolseparatorframe; + fframesepvert: ttoolseparatorframe; + procedure setitems(const index: integer; const Value: tcustomtoolbutton); + function getitems(const index: integer): tcustomtoolbutton; reintroduce; + procedure setheight(const Value: integer); + procedure setwidth(const Value: integer); + procedure setimagelist(const avalue: timagelist); + procedure setcolorglyph(const avalue: colorty); + procedure setcolor(const avalue: colorty); + function getface: tface; + procedure setface(const avalue: tface); + function getfacechecked: tface; + procedure setfacechecked(const avalue: tface); + function getframe: tframe; + procedure setframe(const avalue: tframe); + function getframechecked: tframe; + procedure setframechecked(const avalue: tframe); + function getframesephorz: tframe; + procedure setframesephorz(const avalue: tframe); + function getframesepvert: tframe; + procedure setframesepvert(const avalue: tframe); + protected + fbuttonstate: toolbuttonsstatesty; + procedure createitem(const index: integer; var item: tpersistent); override; + procedure dochange(const index: integer); override; + procedure objectchanged(const sender: tobject); + class function getbuttonclass: toolbuttonclassty; virtual; + public + constructor create(const aowner: tcustomtoolbar); reintroduce; + destructor destroy(); override; + class function getitemclasstype(): persistentclassty; override; + procedure createface(); + procedure createfacechecked(); + procedure createframe(); + procedure createframechecked(); + procedure createframesephorz(); + procedure createframesepvert(); + procedure doupdate(); + procedure resetradioitems(const group: integer); + function getcheckedradioitem(const group: integer): tcustomtoolbutton; + function add: tcustomtoolbutton; + property items[const index: integer]: tcustomtoolbutton + read getitems write setitems; default; + published + property width: integer read fwidth write setwidth default 0; + property height: integer read fheight write setheight default 0; + property imagelist: timagelist read fimagelist write setimagelist; + property colorglyph: colorty read fcolorglyph + write setcolorglyph default cl_default; + //cl_default -> cl_glyph + property color: colorty read fcolor write setcolor default cl_default; + //cl_default -> cl_transparent + property face: tface read getface write setface; + property facechecked: tface read getfacechecked write setfacechecked; + property frame: tframe read getframe write setframe; + property framechecked: tframe read getframechecked write setframechecked; + property framesephorz: tframe read getframesephorz + write setframesephorz; + property framesepvert: tframe read getframesepvert + write setframesepvert; + end; + + ttoolbuttons = class(tcustomtoolbuttons) + protected + class function getbuttonclass: toolbuttonclassty; override; + published + property width; + property height; + property imagelist; + property colorglyph; + property color; + property face; + property frame; + property framesephorz; + property framesepvert; + end; + + tstockglyphtoolbuttons = class(ttoolbuttons) + protected + class function getbuttonclass: toolbuttonclassty; override; + end; + + toolbaroptionty = (tbo_dragsource,tbo_dragdest, + tbo_dragsourceenabledonly,tbo_dragdestenabledonly, + tbo_nohorz,tbo_novert, + tbo_shortcuthint); + toolbaroptionsty = set of toolbaroptionty; + + toolbarlayoutinfoty = record + vert: boolean; + buttons: ttoolbuttons; + cells: shapeinfoarty; + stepinfo: framestepinfoty; +// maxbuttons: integer; + focusedbutton: integer; + lines: integer; + buttonsize: sizety; + defaultsize: sizety; + end; + + toolbuttoneventty = procedure(const sender: tobject; + const button: tcustomtoolbutton) of object; + + tcustomtoolbar = class(tcustomstepbox,istatfile,iframe) + private + flayoutok: boolean; + foptions: toolbaroptionsty; + fonbuttonchanged: toolbuttoneventty; + fhintedbutton: integer; + fupdating: integer; + ffirstbutton: integer; + fstatfile: tstatfile; + fstatvarname: msestring; + fstatpriority: integer; + procedure setbuttons(const Value: ttoolbuttons); + procedure setoptions(const Value: toolbaroptionsty); + function gethintpos(const aindex: integer): rectty; + function getbuttonhint(const aindex: integer): msestring; + procedure setfirstbutton(value: integer); + procedure buttonschanged(const sender: tarrayprop; const index: integer); + procedure setstatfile(const Value: tstatfile); + procedure setdragcontroller(const Value: tdragcontroller); + protected + flayout: toolbarlayoutinfoty; + class function classskininfo: skininfoty; override; + procedure buttonchanged(sender: tcustomtoolbutton); + procedure checkvert(const asize: sizety); + function getseparatorwidth(): integer; + procedure getautopaintsize(var asize: sizety); override; + procedure updatelayout; + procedure clientrectchanged; override; + procedure dopaintforeground(const canvas: tcanvas); override; + procedure clientmouseevent(var info: mouseeventinfoty); override; + procedure showhint(const aid: int32; var info: hintinfoty); override; + function dostep(const event: stepkindty; const adelta: real; + ashiftstate: shiftstatesty): boolean; override; + procedure doshortcut(var info: keyeventinfoty; const sender: twidget); override; + procedure objectchanged(const sender: tobject); override; + //iassistiveclient + function getassistivehint(): msestring; override; + //istatfile + procedure dostatread(const reader: tstatreader); virtual; + procedure dostatwrite(const writer: tstatwriter); virtual; + procedure statreading; + procedure statread; + function getstatvarname: msestring; + function getstatpriority: integer; + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure dragevent(var info: draginfoty); override; + procedure beginupdate; + procedure endupdate; + function buttonatpos(const apos: pointty; const enabledonly: boolean = false): tcustomtoolbutton; + + property buttons: ttoolbuttons read flayout.buttons write setbuttons; + property firstbutton: integer read ffirstbutton write setfirstbutton default 0; + property options: toolbaroptionsty read foptions write setoptions default []; + property statfile: tstatfile read fstatfile write setstatfile; + property statvarname: msestring read getstatvarname write fstatvarname; + property statpriority: integer read fstatpriority + write fstatpriority default 0; + + property onbuttonchanged: toolbuttoneventty read fonbuttonchanged write fonbuttonchanged; + property drag: tdragcontroller read fdragcontroller write setdragcontroller; + + end; + + ttoolbar = class(tcustomtoolbar) + published + property frame; + property onstep; + + property optionswidget default defaultoptionswidgetnofocus; + property buttons; + property firstbutton; + property options; + property statfile; + property statvarname; + property statpriority; + property onbuttonchanged; + property drag; + end; + +implementation +uses + sysutils,msebits,mseactions,msestockobjects; + +const + separatorwidth = 3; +type + tcustomstepframe1 = class(tcustomstepframe); + twidget1 = class(twidget); + +procedure drawtoolbuttons(const canvas: tcanvas; + var layout: toolbarlayoutinfoty); +var + int1: integer; + rect1: rectty; + po1: pshapeinfoty; +begin + with layout do begin + rect1:= canvas.clipbox; + for int1:= 0 to high(cells) do begin + po1:= @cells[int1]; + with po1^ do begin + if testintersectrect(rect1,ca.dim) then begin + if shs_checked in state then begin + face:= buttons.ffacechecked; + end + else begin + face:= buttons.fface; + end; + if shs_separator in state then begin + if vert then begin + frame:= buttons.framesepvert; + end + else begin + frame:= buttons.framesephorz; + end; + end + else begin + if shs_checked in state then begin + frame:= buttons.framechecked; + end + else begin + frame:= buttons.frame; + end; + end; + drawtoolbutton(canvas,po1^); + end; + end; + end; + end; +end; + +{ tcustomtoolbutton } + +constructor tcustomtoolbutton.create(const aowner: tobject; + const aprop: tindexpersistentarrayprop); +begin + initactioninfo(finfo); + finfo.color:= ttoolbuttons(aprop).color; + finfo.colorglyph:= ttoolbuttons(aprop).colorglyph; + inherited; +end; + +constructor tcustomtoolbutton.create(aowner: tcustomtoolbar); +begin + create(aowner,aowner.buttons); +end; + +procedure tcustomtoolbutton.objectevent(const sender: tobject; const event: objecteventty); +begin + inherited; + if sender = finfo.imagelist then begin + if event = oe_destroyed then begin + finfo.imagelist:= nil; + end; + changed; + end; +end; + +procedure tcustomtoolbutton.actionchanged; +begin + changed; +end; + +function tcustomtoolbutton.getactioninfopo: pactioninfoty; +begin + result:= @finfo; +end; + +function tcustomtoolbutton.toolbar: tcustomtoolbar; +begin + result:= tcustomtoolbar(fowner); +end; + +procedure tcustomtoolbutton.setaction(const Value: tcustomaction); +begin + linktoaction(iactionlink(self),value,finfo); +end; + +function tcustomtoolbutton.getstate: actionstatesty; +begin + result:= finfo.state; +end; + +procedure tcustomtoolbutton.setstate(const Value: actionstatesty); +begin + setactionstate(iactionlink(self),value); +end; + +function tcustomtoolbutton.isstatestored: Boolean; +begin + result:= isactionstatestored(finfo); +end; + +function tcustomtoolbutton.getimagelist: timagelist; +begin + result:= timagelist(finfo.imagelist); +end; + +procedure tcustomtoolbutton.setimagelist(const Value: timagelist); +begin + setactionimagelist(iactionlink(self),value); +end; + +function tcustomtoolbutton.isimageliststored: Boolean; +begin + result:= isactionimageliststored(finfo); +end; + +function tcustomtoolbutton.getshortcut: shortcutty; +begin + result:= getsimpleshortcut(finfo); +end; + +function tcustomtoolbutton.getshortcut1: shortcutty; +begin + result:= getsimpleshortcut1(finfo); +end; + +procedure tcustomtoolbutton.setshortcut(const Value: shortcutty); +begin + setactionshortcut(iactionlink(self),value); +end; + +function tcustomtoolbutton.isshortcutstored: Boolean; +begin + result:= isactionshortcutstored(finfo); +end; + +procedure tcustomtoolbutton.setshortcut1(const Value: shortcutty); +begin + setactionshortcut1(iactionlink(self),value); +end; + +function tcustomtoolbutton.isshortcut1stored: Boolean; +begin + result:= isactionshortcut1stored(finfo); +end; + +procedure tcustomtoolbutton.setimagenr(const Value: imagenrty); +begin + setactionimagenr(iactionlink(self),value); +end; + +procedure tcustomtoolbutton.setimagenrdisabled(const Value: imagenrty); +begin + setactionimagenrdisabled(iactionlink(self),value); +end; + +procedure tcustomtoolbutton.setcolorglyph(const avalue: colorty); +begin + setactioncolorglyph(iactionlink(self),avalue); +end; + +function tcustomtoolbutton.iscolorglyphstored: boolean; +begin + result:= isactioncolorglyphstored(finfo); +end; + +procedure tcustomtoolbutton.setcolor(const avalue: colorty); +begin + setactioncolor(iactionlink(self),avalue); +end; + +function tcustomtoolbutton.iscolorstored: boolean; +begin + result:= isactioncolorstored(finfo); +end; + +procedure tcustomtoolbutton.setimagecheckedoffset(const Value: integer); +begin + setactionimagecheckedoffset(iactionlink(self),value); +end; + +function tcustomtoolbutton.isimagenrstored: Boolean; +begin + result:= isactionimagenrstored(finfo); +end; + +function tcustomtoolbutton.isimagenrdisabledstored: Boolean; +begin + result:= isactionimagenrdisabledstored(finfo); +end; + +function tcustomtoolbutton.isimagecheckedoffsetstored: Boolean; +begin + result:= isactionimagecheckedoffsetstored(finfo); +end; + +procedure tcustomtoolbutton.sethint(const Value: msestring); +begin + setactionhint(iactionlink(self),value); +end; + +function tcustomtoolbutton.ishintstored: Boolean; +begin + result:= isactionhintstored(finfo); +end; + +procedure tcustomtoolbutton.setonexecute(const avalue: notifyeventty); +begin + setactiononexecute(iactionlink(self),avalue, + csloading in toolbar.componentstate); +end; + +function tcustomtoolbutton.isonexecutestored: Boolean; +begin + result:= isactiononexecutestored(finfo); +end; + +procedure tcustomtoolbutton.setonbeforeexecute(const avalue: accepteventty); +begin + setactiononbeforeexecute(iactionlink(self),avalue, + csloading in toolbar.componentstate); +end; + +function tcustomtoolbutton.isonbeforeexecutestored: Boolean; +begin + result:= isactiononbeforeexecutestored(finfo); +end; + +procedure tcustomtoolbutton.setonafterexecute(const avalue: notifyeventty); +begin + setactiononafterexecute(iactionlink(self),avalue, + csloading in toolbar.componentstate); +end; + +function tcustomtoolbutton.isonafterexecutestored: Boolean; +begin + result:= isactiononafterexecutestored(finfo); +end; + +procedure tcustomtoolbutton.setgroup(const Value: integer); +begin + setactiongroup(iactionlink(self),value); +end; + +function tcustomtoolbutton.isgroupstored: Boolean; +begin + result:= isactiongroupstored(finfo); +end; + +procedure tcustomtoolbutton.changed; +begin + tcustomtoolbar(fowner).buttonchanged(self); +end; + +function tcustomtoolbutton.index: integer; +begin + result:= findex; +end; + +function tcustomtoolbutton.getchecked: boolean; +begin + result:= as_checked in finfo.state; +end; + +procedure tcustomtoolbutton.setchecked(const Value: boolean); +begin + if value then begin + state:= state + [as_checked]; + end + else begin + state:= state - [as_checked]; + end; +end; + +procedure tcustomtoolbutton.doexecute(const tag: integer; + const info: mouseeventinfoty); +begin + if doactionexecute(self,finfo,false, + tbs_nocandefocus in ttoolbuttons(prop).fbuttonstate) then begin + changed; + end; +end; + +procedure tcustomtoolbutton.execute; +begin + doexecute(-1,pmouseeventinfoty(nil)^); +end; + +procedure tcustomtoolbutton.setoptions(const Value: menuactionoptionsty); +begin + if finfo.options <> value then begin + finfo.options := Value; + changed; + end; +end; + +procedure tcustomtoolbutton.doshortcut(var info: keyeventinfoty); +begin + if doactionshortcut(self,finfo,info) then begin + changed; + end; +end; + +function tcustomtoolbutton.getenabled: boolean; +begin + result:= not (as_disabled in finfo.state); +end; + +procedure tcustomtoolbutton.setenabled(const avalue: boolean); +begin + if avalue then begin + state:= state - [as_disabled]; + end + else begin + state:= state + [as_disabled]; + end; +end; + +function tcustomtoolbutton.getvisible: boolean; +begin + result:= not (as_invisible in finfo.state); +end; + +procedure tcustomtoolbutton.setvisible(const avalue: boolean); +begin + if avalue then begin + state:= state - [as_invisible]; + end + else begin + state:= state + [as_invisible]; + end; +end; + +function tcustomtoolbutton.getinstance: tobject; +begin + result:= fowner; +end; + +function tcustomtoolbutton.loading: boolean; +begin + result:= (fowner is tcomponent) and + (csloading in tcomponent(fowner).componentstate); +end; + +function tcustomtoolbutton.shortcutseparator: msechar; +begin + result:= ' '; +end; + +procedure tcustomtoolbutton.calccaptiontext(var ainfo: actioninfoty); +begin + mseactions.calccaptiontext(ainfo,shortcutseparator); +end; + +procedure tcustomtoolbutton.readbool(reader: treader); +begin + reader.readboolean; //dummy +end; + +procedure tcustomtoolbutton.writebool(writer: twriter); +begin + //dummy +end; + +procedure tcustomtoolbutton.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('visible',{$ifdef FPC}@{$endif}readbool, + {$ifdef FPC}@{$endif}writebool,false); + filer.defineproperty('enabled',{$ifdef FPC}@{$endif}readbool, + {$ifdef FPC}@{$endif}writebool,false); +end; + +procedure tcustomtoolbutton.setshortcuts(const avalue: shortcutarty); +begin + setactionshortcuts(iactionlink(self),avalue); +end; + +procedure tcustomtoolbutton.setshortcuts1(const avalue: shortcutarty); +begin + setactionshortcuts1(iactionlink(self),avalue); +end; + +procedure tcustomtoolbutton.doupdate; +begin + if finfo.action <> nil then begin + finfo.action.doupdate; + end; +end; + +{ ttoolbuttonframe } + +constructor ttoolbuttonframe.create(const aintf: iframe); +begin + include(fstate,fs_nosetinstance); + inherited; + fi.optionsskin:= defaulttoolbuttonoptionsskin; +end; + +{ ttoolseparatorframe } + +constructor ttoolseparatorframe.create(const aintf: iframe); +begin + inherited; + fi.optionsskin:= defaulttoolseparatoroptionsskin; +end; + +{ tcustomtoolbuttons } + +constructor tcustomtoolbuttons.create(const aowner: tcustomtoolbar); +begin + fcolorglyph:= cl_default; + fcolor:= cl_default; + inherited create(aowner,getbuttonclass); +end; + +destructor tcustomtoolbuttons.destroy; +begin + inherited; + fface.free; + ffacechecked.free; + fframe.free(); + fframechecked.free(); + fframesephorz.free(); + fframesepvert.free(); +end; + +class function tcustomtoolbuttons.getitemclasstype: persistentclassty; +begin + result:= ttoolbutton; +end; + +function tcustomtoolbuttons.add: tcustomtoolbutton; +begin + count:= count + 1; + result:= items[count-1]; +end; + +procedure tcustomtoolbuttons.createitem(const index: integer; var item: tpersistent); +begin + inherited; + if not (csloading in tcustomtoolbar(fowner).componentstate) then begin + with tcustomtoolbutton(item) do begin + if fimagelist <> nil then begin + imagelist:= fimagelist; + end; + if fcolorglyph <> cl_default then begin + colorglyph:= fcolorglyph; + end; + if fcolor <> cl_default then begin + color:= fcolor; + end; +// state:= state - [as_localimagelist,as_localcolorglyph,as_localcolor]; + end; + end; +end; + +procedure tcustomtoolbuttons.dochange(const index: integer); +var + int1: integer; + po1: ptoolbutton; +begin + if index < 0 then begin + po1:= pointer(fitems); + for int1:= 0 to high(fitems) do begin + po1^.findex:= int1; + inc(po1); + end; + end + else begin + tcustomtoolbutton(fitems[index]).findex:= index; + end; + inherited; +end; + +function tcustomtoolbuttons.getcheckedradioitem( + const group: integer): tcustomtoolbutton; +var + int1: integer; +begin + result:= nil; + for int1:= 0 to count - 1 do begin + with items[int1] do begin + if (finfo.group = group) and + (mao_radiobutton in finfo.options) and (as_checked in finfo.state) then begin + result:= items[int1]; + break; + end; + end; + end; +end; + +procedure tcustomtoolbuttons.resetradioitems(const group: integer); +var + int1: integer; +begin + for int1:= 0 to count - 1 do begin + with items[int1] do begin + if (finfo.group = group) and (as_checked in finfo.state) then begin + state:= finfo.state - [as_checked]; + end; + end; + end; +end; + +function tcustomtoolbuttons.getitems(const index: integer): tcustomtoolbutton; +begin + result:= tcustomtoolbutton(inherited items[index]); +end; + +procedure tcustomtoolbuttons.setitems(const index: integer; + const Value: tcustomtoolbutton); +begin + inherited items[index].assign(value); +end; + +procedure tcustomtoolbuttons.setheight(const Value: integer); +begin + if fheight <> value then begin + fheight:= Value; + dochange(-1); + end; +end; + +procedure tcustomtoolbuttons.setwidth(const Value: integer); +begin + if fwidth <> value then begin + fwidth:= Value; + dochange(-1); + end; +end; + +procedure tcustomtoolbuttons.setimagelist(const avalue: timagelist); +var + int1: integer; +begin + setlinkedvar(avalue,tmsecomponent(fimagelist)); + if not (csloading in tcomponent(fowner).componentstate) then begin + for int1:= 0 to count - 1 do begin + items[int1].imagelist:= avalue; + end; + end; +end; + +procedure tcustomtoolbuttons.setcolorglyph(const avalue: colorty); +var + int1: integer; +begin + fcolorglyph:= avalue; + if not (csloading in tcomponent(fowner).componentstate) then begin + for int1:= 0 to count - 1 do begin + items[int1].colorglyph:= avalue; + end; + end; +end; + +procedure tcustomtoolbuttons.setcolor(const avalue: colorty); +var + int1: integer; +begin + fcolor:= avalue; + if not (csloading in tcomponent(fowner).componentstate) then begin + for int1:= 0 to count - 1 do begin + items[int1].color:= avalue; + end; + end; +end; + +procedure tcustomtoolbuttons.createface; +begin + if fface = nil then begin + fface:= tface.create(iface(tcustomtoolbar(fowner))); + end; +end; + +procedure tcustomtoolbuttons.createfacechecked(); +begin + if ffacechecked = nil then begin + ffacechecked:= tface.create(iface(tcustomtoolbar(fowner))); + end; +end; + +function tcustomtoolbuttons.getface: tface; +begin + tcustomtoolbar(fowner).getoptionalobject(fface,@createface); + result:= fface; +end; + +procedure tcustomtoolbuttons.setface(const avalue: tface); +begin + tcustomtoolbar(fowner).setoptionalobject(avalue,fface,@createface); + tcustomtoolbar(fowner).invalidate; +end; + +function tcustomtoolbuttons.getfacechecked: tface; +begin + tcustomtoolbar(fowner).getoptionalobject(ffacechecked,@createfacechecked); + result:= ffacechecked; +end; + +procedure tcustomtoolbuttons.setfacechecked(const avalue: tface); +begin + tcustomtoolbar(fowner).setoptionalobject(avalue,ffacechecked, + @createfacechecked); + tcustomtoolbar(fowner).invalidate; +end; + +function tcustomtoolbuttons.getframe: tframe; +begin + tcustomtoolbar(fowner).getoptionalobject(fframe,@createframe); + result:= fframe; +end; + +procedure tcustomtoolbuttons.setframe(const avalue: tframe); +begin + tcustomtoolbar(fowner).setoptionalobject(avalue,fframe,@createframe); + tcustomtoolbar(fowner).clientrectchanged(); +end; + +function tcustomtoolbuttons.getframechecked: tframe; +begin + tcustomtoolbar(fowner).getoptionalobject(fframe,@createframechecked); + result:= fframechecked; +end; + +procedure tcustomtoolbuttons.setframechecked(const avalue: tframe); +begin + tcustomtoolbar(fowner).setoptionalobject(avalue,fframechecked, + @createframechecked); + tcustomtoolbar(fowner).clientrectchanged(); +end; + +function tcustomtoolbuttons.getframesephorz: tframe; +begin + tcustomtoolbar(fowner).getoptionalobject(fframesephorz, + @createframesephorz); + result:= fframesephorz; +end; + +procedure tcustomtoolbuttons.setframesephorz(const avalue: tframe); +begin + tcustomtoolbar(fowner).setoptionalobject(avalue,fframesephorz, + @createframesephorz); + tcustomtoolbar(fowner).clientrectchanged(); +end; + +function tcustomtoolbuttons.getframesepvert: tframe; +begin + tcustomtoolbar(fowner).getoptionalobject(fframesepvert, + @createframesepvert); + result:= fframesepvert; +end; + +procedure tcustomtoolbuttons.setframesepvert(const avalue: tframe); +begin + tcustomtoolbar(fowner).setoptionalobject(avalue,fframesepvert, + @createframesepvert); + tcustomtoolbar(fowner).clientrectchanged(); +end; + +procedure tcustomtoolbuttons.createframe(); +begin + if fframe = nil then begin + fframe:= ttoolbuttonframe.create(iframe(tcustomtoolbar(fowner))); + end; +end; + +procedure tcustomtoolbuttons.createframechecked(); +begin + if fframechecked = nil then begin + fframechecked:= ttoolbuttonframe.create(iframe(tcustomtoolbar(fowner))); + end; +end; + +procedure tcustomtoolbuttons.createframesephorz(); +begin + if fframesephorz = nil then begin + fframesephorz:= ttoolseparatorframe.create(iframe(tcustomtoolbar(fowner))); + end; +end; + +procedure tcustomtoolbuttons.createframesepvert(); +begin + if fframesepvert = nil then begin + fframesepvert:= ttoolseparatorframe.create(iframe(tcustomtoolbar(fowner))); + end; +end; + +procedure tcustomtoolbuttons.objectchanged(const sender: tobject); +begin + if fface <> nil then begin + fface.checktemplate(sender); + end; +end; + +class function tcustomtoolbuttons.getbuttonclass: toolbuttonclassty; +begin + result:= tcustomtoolbutton; +end; + +procedure tcustomtoolbuttons.doupdate; +var + int1: integer; +begin + for int1:= 0 to high(fitems) do begin + with tcustomtoolbutton(fitems[int1]) do begin + doupdate; + end; + end; +end; + +{ ttoolbuttons } + +class function ttoolbuttons.getbuttonclass: toolbuttonclassty; +begin + result:= ttoolbutton; +end; + +{ tcustomtoolbar } + +constructor tcustomtoolbar.create(aowner: tcomponent); +begin + if flayout.buttons = nil then begin + flayout.buttons:= ttoolbuttons.create(self); + end; + flayout.buttons.onchange:= {$ifdef FPC}@{$endif}buttonschanged; + fhintedbutton:= -2; + inherited; +end; + +destructor tcustomtoolbar.destroy; +begin + inherited; + flayout.buttons.Free; +end; + +procedure tcustomtoolbar.checkvert(const asize: sizety); +var + si1: sizety; +begin + with flayout do begin + si1:= framesize; + vert:= si1.cy > si1.cx; +// vert:= asize.cy > asize.cx; + if (tbo_novert in foptions) then begin + vert:= false; + end; + if (tbo_nohorz in foptions) then begin + vert:= true; + end; + buttonsize:= asize; + if vert then begin + if buttons.fwidth > 0 then begin + buttonsize.cx:= buttons.fwidth; + end; + if buttons.fheight = 0 then begin + buttonsize.cy:= buttonsize.cx; + end + else begin + buttonsize.cy:= buttons.fheight; + end; + end + else begin + if buttons.fheight > 0 then begin + buttonsize.cy:= buttons.fheight; + end; + if buttons.fwidth = 0 then begin + buttonsize.cx:= buttonsize.cy; + end + else begin + buttonsize.cx:= buttons.fwidth; + end; + end; + end; +end; + +procedure tcustomtoolbar.getautopaintsize(var asize: sizety); +var + int1: integer; + size1: sizety; + sepwidth1: integer; +begin + with flayout do begin + if (defaultsize.cx = 0) or (buttons.width = 0) or + (defaultsize.cy = 0) or (buttons.height = 0) then begin + size1:= asize; + if fframe <> nil then begin + size1.cx:= size1.cx - fframe.framei_left - fframe.framei_right; + size1.cy:= size1.cy - fframe.framei_top - fframe.framei_bottom; + end; + checkvert(size1); + sepwidth1:= getseparatorwidth(); + if vert then begin + defaultsize.cx:= buttonsize.cx; + defaultsize.cy:= 0; + for int1:= 0 to buttons.count - 1 do begin + with buttons[int1] do begin + if not (as_invisible in state) then begin + if mao_separator in options then begin + inc(defaultsize.cy,sepwidth1); + end + else begin + inc(defaultsize.cy,buttonsize.cy); + end; + end; + end; + end; + end + else begin + defaultsize.cy:= buttonsize.cy; + defaultsize.cx:= 0; + for int1:= 0 to buttons.count - 1 do begin + with buttons[int1] do begin + if not (as_invisible in state) then begin + if mao_separator in options then begin + inc(defaultsize.cx,sepwidth1); + end + else begin + inc(defaultsize.cx,buttonsize.cx); + end; + end; + end; + end; + end; + if fframe <> nil then begin + defaultsize.cx:= defaultsize.cx + fframe.framei_left + fframe.framei_right; + defaultsize.cy:= defaultsize.cy + fframe.framei_top + fframe.framei_bottom; + end; + end; + asize:= defaultsize; + end; +end; + +procedure tcustomtoolbar.updatelayout; + +var + buttonsizecxy: integer; + sepwidth1: integer; + + function step(const index: integer): integer; + begin + result:= 0; + with flayout,buttons[index] do begin + if not (as_invisible in state)then begin + if mao_separator in options then begin + result:= sepwidth1; + end + else begin + result:= buttonsizecxy; + end; + end; + end; + end; + +var + int1,int2,int3: integer; + i2: int32; + rect1,rect2: rectty; + endxy: integer; +// bu1: stepbuttonposty; + loopcount: integer; + size1: sizety; + pageend: integer; + bo1: boolean; + bu1: stepkindsty; +begin + if fupdating <> 0 then begin + flayoutok:= false; + end + else begin + inc(fupdating); + try + loopcount:= 0; + tcustomstepframe1(fframe).neededbuttons:= []; + repeat + flayoutok:= true; + rect1:= innerclientrect; + rect2:= rect1; + inc(loopcount); + with flayout do begin + defaultsize:= nullsize; + checkvert(rect1.size); + sepwidth1:= getseparatorwidth(); +// bu1:= frame.buttonpos; + if frame.buttonpos in [sbp_top,sbp_right] then begin + if vert then begin + frame.buttonpos:= sbp_top; + end + else begin + frame.buttonpos:= sbp_right; + end; + end + else begin + if vert then begin + frame.buttonpos:= sbp_bottom; + end + else begin + frame.buttonpos:= sbp_left; + end; + end; + rect1.size:= buttonsize; + if vert then begin + if rect1.cx > 0 then begin + lines:= rect2.cx div rect1.cx; + if lines <= 0 then begin + lines:= 1; + end; + end + else begin + lines:= 1; + end; + end + else begin + if rect1.cy > 0 then begin + lines:= rect2.cy div rect1.cy; + if lines <= 0 then begin + lines:= 1; + end; + end + else begin + lines:= 1; + end; + end; + + setlength(cells,buttons.count); + if vert then begin + endxy:= rect2.y + rect2.cy; + end + else begin + endxy:= rect2.x + rect2.cx; + end; + if vert then begin + buttonsizecxy:= rect1.cy; + end + else begin + buttonsizecxy:= rect1.cx; + end; + int3:= lines - 1; +// for int1:= 0 to high(cells) do begin +// actioninfotoshapeinfo(buttons[int1].finfo,cells[int1]); +// end; + with stepinfo do begin + pageend:= buttons.count; + pageup:= pageend; + up:= 0; + if ffirstbutton >= pageend then begin + ffirstbutton:= 0; //count changed + end; + for int1:= ffirstbutton to pageend - 1 do begin + with cells[int1] do begin + color:= cl_parent; + actioninfotoshapeinfo(buttons[int1].finfo,cells[int1]); + if color = cl_default then begin + color:= cl_transparent; + end; + if ca.colorglyph = cl_default then begin + ca.colorglyph:= cl_glyph; + end; + if shs_separator in state then begin + exclude(state,shs_flat); + end + else begin + include(state,shs_flat); + end; + if state * [shs_checkbox,shs_radiobutton] <> [] then begin + include(state,shs_checkbutton); + end; + doexecute:= {$ifdef FPC}@{$endif}buttons[int1].doexecute; + if not (as_invisible in buttons[int1].state) then begin + if vert then begin + rect1.cy:= step(int1); + end + else begin + rect1.cx:= step(int1); + end; + if not (mao_separator in buttons[int1].options) then begin + if up = 0 then begin + up:= int1 - ffirstbutton; + end; + end; + if vert and (rect1.y + rect1.cy > endxy) or + not vert and (rect1.x + rect1.cx > endxy) then begin + i2:= int1; + if i2 = ffirstbutton then begin + inc(i2); + end; + if stepinfo.pageup = buttons.count then begin //first loop + pageup:= i2; + end; + if (int3 > 0) then begin + dec(int3); + if vert then begin + inc(rect1.x,rect1.cx); + rect1.y:= rect2.y; + end + else begin + inc(rect1.y,rect1.cy); + rect1.x:= rect2.x; + end; + end + else begin + pageend:= i2; + break; + end; + end; + ca.dim:= rect1; + if vert then begin + inc(rect1.y,rect1.cy); + end + else begin + inc(rect1.x,rect1.cx); + end; + end + else begin + include(state,shs_invisible); + end; + end; + end; + pagedown:= 0; + down:= 0; + if vert then begin + int2:= rect2.cy; + end + else begin + int2:= rect2.cx; + end; + for int1:= ffirstbutton - 1 downto 0 do begin + include(cells[int1].state,shs_invisible); + if not (as_invisible in buttons[int1].state)then begin + if mao_separator in buttons[int1].options then begin + dec(int2,sepwidth1); + end + else begin + if vert then begin + dec(int2,buttons.fheight); + end + else begin + dec(int2,buttons.fwidth); + end; + if down = 0 then begin + down:= int1 - ffirstbutton; + end; + end; + if int2 < 0 then begin + if int1 = ffirstbutton - 1 then begin + pagedown:= int1; + end + else begin + pagedown:= int1 + 1; + end; + break; + end; + end; + end; + for int1:= pageend to high(cells) do begin + include(cells[int1].state,shs_invisible); + end; + pagelast:= 0; + int3:= lines; + if vert then begin + int2:= rect2.cy; + end + else begin + int2:= rect2.cx; + end; + bo1:= false; + for int1:= high(cells) downto 0 do begin //calc pagelast + dec(int2,step(int1)); + if int2 < 0 then begin + dec(int3); + if int3 = 0 then begin + pagelast:= int1+1; + break; + end; + if vert then begin + int2:= rect2.cy; + end + else begin + int2:= rect2.cx; + end; + if bo1 then begin //at least one button + dec(int2,step(int1)); //move button on next line + bo1:= false; + end; + end + else begin + bo1:= true; + end; + if pagelast > high(cells) then begin + pagelast:= high(cells); + end; + end; + pagelast:= pagelast - ffirstbutton; + pageup:= pageup - ffirstbutton; + pagedown:= pagedown - ffirstbutton; + if up = 0 then begin + up:= 1; + end; + if down = 0 then begin + down:= -1; + end; + bu1:= tcustomstepframe1(fframe).neededbuttons; + frame.updatebuttonstate(ffirstbutton,pageend-ffirstbutton,buttons.count); + flayoutok:= flayoutok and (bu1 = tcustomstepframe1(fframe).neededbuttons); + end; + if flayoutok then begin + size1:= self.size; + checkautosize; + if (size1.cx <> bounds_cx) or (size1.cy <> bounds_cy) then begin + tcustomstepframe1(fframe).neededbuttons:= []; + flayoutok:= false; //try again + end; + end; + end; + until flayoutok or (loopcount > 8); + invalidate; + finally + dec(fupdating); + end; + end; +end; + +class function tcustomtoolbar.classskininfo: skininfoty; +begin + result:= inherited classskininfo; + result.objectkind:= sok_toolbar; +end; + +procedure tcustomtoolbar.buttonchanged(sender: tcustomtoolbutton); +var + int1: integer; + button1: tcustomtoolbutton; + bo1: boolean; +begin + with flayout do begin + if sender.checked and (mao_radiobutton in sender.options) then begin + for int1:= 0 to buttons.count -1 do begin + button1:= buttons[int1]; + if (button1 <> sender) and (button1.checked) and + (button1.group = sender.group) then begin + button1.checked:= false; + end; + end; + end; + for int1:= 0 to buttons.count - 1 do begin + button1:= buttons[int1]; + if int1 >= length(cells) then begin + break; + end; + if button1 = sender then begin + with cells[int1] do begin + bo1:= (shs_invisible in state) xor (as_invisible in button1.finfo.state) or + ((shs_separator in state) xor (mao_separator in button1.options)) or + ((shs_checkbox in state) xor (mao_checkbox in button1.options)) or + ((shs_radiobutton in state) xor (mao_radiobutton in button1.options)); + actionstatestoshapestates(button1.finfo,state); + ca.imagenr:= buttons[int1].finfo.imagenr; + ca.colorglyph:= buttons[int1].finfo.colorglyph; + if ca.colorglyph = cl_default then begin + ca.colorglyph:= cl_glyph; + end; + color:= buttons[int1].finfo.color; + if color = cl_default then begin + color:= cl_transparent; + end; + ca.imagelist:= timagelist(buttons[int1].finfo.imagelist); + doexecute:= {$ifdef FPC}@{$endif}buttons[int1].doexecute; + invalidaterect(ca.dim); + if bo1 then begin + updatelayout; + end; + end; + break; + end; + end; + end; + if canevent(tmethod(fonbuttonchanged)) then begin + fonbuttonchanged(self,sender); + end; +end; + +procedure tcustomtoolbar.setbuttons(const Value: ttoolbuttons); +begin + flayout.buttons.assign(Value); +end; +{ +procedure ttoolbar.setimagebase(const Value: integer); +begin + if fimagebase <> value then begin + fimagebase:= Value; + invalidate; + end; +end; + +procedure ttoolbar.setimagelist(const Value: timagelist); +begin + setcomponentvar(value,tmsecomponent(fimagelist)); + invalidate; +end; +} +procedure tcustomtoolbar.setoptions(const Value: toolbaroptionsty); +const + mask: toolbaroptionsty = [tbo_nohorz,tbo_novert]; +var + valbefore: toolbaroptionsty; +begin + if foptions <> value then begin + valbefore:= foptions; + foptions:= toolbaroptionsty(setsinglebit( + {$ifdef FPC}longword{$else}byte{$endif}(value), + {$ifdef FPC}longword{$else}byte{$endif}(foptions), + {$ifdef FPC}longword{$else}byte{$endif}(mask))); + if ({$ifdef FPC}longword{$else}byte{$endif}(valbefore) xor + {$ifdef FPC}longword{$else}byte{$endif}(foptions)) and + {$ifdef FPC}longword{$else}byte{$endif}(mask) <> 0 then begin + updatelayout; + end; + end; +end; + +procedure tcustomtoolbar.setfirstbutton(value: integer); +begin + if value >= flayout.buttons.count - 1 then begin + value:= flayout.buttons.count - 1; + end; + if value < 0 then begin + value:= 0; + end; + if ffirstbutton <> value then begin + ffirstbutton:= value; + updatelayout; + end; +end; + +procedure tcustomtoolbar.buttonschanged(const sender: tarrayprop; const index: integer); +begin + updatelayout; +end; + +procedure tcustomtoolbar.clientrectchanged; +begin + inherited; + updatelayout; +end; + +procedure tcustomtoolbar.dopaintforeground(const canvas: tcanvas); +begin + inherited; + drawtoolbuttons(canvas,flayout) +end; + +function tcustomtoolbar.gethintpos(const aindex: integer): rectty; +begin + result:= flayout.cells[aindex].ca.dim; + inc(result.cy,12); +end; + +function tcustomtoolbar.getbuttonhint(const aindex: integer): msestring; +begin + with buttons[aindex] do begin + result:= hint; + if (tbo_shortcuthint in self.foptions) and (shortcut <> 0) then begin + if result <> '' then begin + result:= result + ' '; + end; + result:= result + '('+encodeshortcutname(shortcut)+')'; + end; + end; +end; + +procedure tcustomtoolbar.clientmouseevent(var info: mouseeventinfoty); +begin + inherited; + if not (csdesigning in componentstate) or + (ws1_designactive in fwidgetstate1) then begin + with flayout do begin + if updatemouseshapestate(cells,info,self,flayout.focusedbutton) then begin + end; + checkbuttonhint(self,info,fhintedbutton,flayout.cells, + {$ifdef FPC}@{$endif}getbuttonhint,{$ifdef FPC}@{$endif}gethintpos); + end; + end; +end; + +procedure tcustomtoolbar.showhint(const aid: int32; var info: hintinfoty); +begin + inherited; +end; + +function tcustomtoolbar.dostep(const event: stepkindty; + const adelta: real;ashiftstate: shiftstatesty): boolean; +begin + result:= false; + if frame.canstep then begin + firstbutton:= frame.executestepevent(event,flayout.stepinfo,ffirstbutton); + result:= true; + end; +end; + +procedure tcustomtoolbar.beginupdate; +begin + inc(fupdating); +end; + +procedure tcustomtoolbar.endupdate; +begin + dec(fupdating); + updatelayout; +end; +{ +procedure tcustomtoolbar.setinvisiblebuttons(const Value: stepkindsty); +begin + inherited; + if not (csloading in componentstate) then begin + updatelayout; + end; +end; +} +function tcustomtoolbar.buttonatpos(const apos: pointty; const enabledonly: boolean = false): tcustomtoolbutton; +var + int1: integer; +begin + begin + if enabledonly then begin + int1:= findshapeatpos(flayout.cells,apos,[shs_invisible,shs_disabled]); + end + else begin + int1:= findshapeatpos(flayout.cells,apos,[shs_invisible]); + end; + if int1 >= 0 then begin + result:= flayout.buttons[int1]; + end + else begin + result:= nil; + end; + end; +end; + +procedure tcustomtoolbar.dragevent(var info: draginfoty); +var + button1: tcustomtoolbutton; + + function candest: boolean; + begin + with info do begin + if (tbo_dragdest in foptions) and (dragobjectpo^.sender = self) and + (dragobjectpo^ is tobjectdragobject) then begin + button1:= buttonatpos(pos,tbo_dragdestenabledonly in foptions); + result:= (button1 <> nil) and (tobjectdragobject(dragobjectpo).data <> button1); + end + else begin + result:= false; + end; + end; + end; + +begin + button1:= nil; + if not fdragcontroller.beforedragevent(info) then begin + with info do begin + case eventkind of + dek_begin: begin + if (dragobjectpo^ = nil) and (tbo_dragsource in foptions) then begin + button1:= buttonatpos(pos,tbo_dragsourceenabledonly in foptions); + if button1 <> nil then begin + tobjectdragobject.create(self,dragobjectpo^,fdragcontroller.pickpos,button1); + end; + end; + end; + dek_check: begin + if candest then begin + accept:= true; + end + else begin + inherited; + end; + end; + dek_drop: begin + if candest then begin + buttons.move(tcustomtoolbutton(tobjectdragobject(dragobjectpo^).data).index,button1.index); + end + else begin + inherited; + end; + end; + end; + end; + end; + fdragcontroller.afterdragevent(info); +end; + +procedure tcustomtoolbar.doshortcut(var info: keyeventinfoty; const sender: twidget); +var + int1: integer; +begin + for int1:= 0 to flayout.buttons.count - 1 do begin + if es_processed in info.eventstate then begin + exit; + end; + flayout.buttons[int1].doshortcut(info); + end; + inherited; +end; + +function tcustomtoolbar.getstatvarname: msestring; +begin + result:= fstatvarname; +end; + +procedure tcustomtoolbar.setstatfile(const Value: tstatfile); +begin + setstatfilevar(istatfile(self),value,fstatfile); +end; + +procedure tcustomtoolbar.dostatread(const reader: tstatreader); +begin + flayout.buttons.dostatread(reader,tbo_dragdest in foptions); +end; + +procedure tcustomtoolbar.dostatwrite(const writer: tstatwriter); +begin + flayout.buttons.dostatwrite(writer,tbo_dragdest in foptions); +end; + +procedure tcustomtoolbar.statreading; +begin + //dummy +end; + +procedure tcustomtoolbar.statread; +begin + //dummy +end; + +procedure tcustomtoolbar.setdragcontroller(const Value: tdragcontroller); +begin + fdragcontroller.Assign(Value); +end; + +procedure tcustomtoolbar.objectchanged(const sender: tobject); +begin + inherited; + flayout.buttons.objectchanged(sender); +end; + +function tcustomtoolbar.getassistivehint(): msestring; +begin + if flayout.focusedbutton >= 0 then begin + result:= flayout.buttons[flayout.focusedbutton].hint; + end + else begin + result:= inherited getassistivehint(); + end; +end; + +function tcustomtoolbar.getstatpriority: integer; +begin + result:= fstatpriority; +end; + +function tcustomtoolbar.getseparatorwidth: integer; +begin + if flayout.vert then begin + if flayout.buttons.fframesepvert <> nil then begin + with flayout.buttons.fframesepvert do begin + result:= innerframedim.cy; + if not (fso_flat in optionsskin) then begin + inc(result,separatorwidth); + end; + end; + end + else begin + result:= separatorwidth; + end; + end + else begin + if flayout.buttons.fframesephorz <> nil then begin + with flayout.buttons.fframesephorz do begin + result:= innerframedim.cx; + if not (fso_flat in optionsskin) then begin + inc(result,separatorwidth); + end; + end; + end + else begin + result:= separatorwidth; + end; + end; +end; + +{ tdocktoolbar } +{ +constructor tdocktoolbar.create(aowner: tcomponent); +begin + if fdragcontroller = nil then begin + fdragcontroller:= tdockcontroller.create(idockcontroller(self)); + end; + inherited; +end; + +procedure tdocktoolbar.createframe; +begin + tgripframe.create(iframe(self)); +end; + +function tdocktoolbar.getframe: tgripframe; +begin + result:= tgripframe(inherited getframe); +end; + +procedure tdocktoolbar.setframe(const avalue: tgripframe); +begin + inherited setframe(avalue); +end; + +function tdocktoolbar.getdrag: tdockcontroller; +begin + result:= tdockcontroller(fdragcontroller); +end; + +procedure tdocktoolbar.setdragcontroller(const avalue: tdockcontroller); +begin + inherited setdragcontroller(avalue); +end; + +function tdocktoolbar.checkdock(var info: draginfoty): boolean; +begin + result:= true; +end; + +function tdocktoolbar.gethandlerect: rectty; +begin + if fframe = nil then begin + result:= clientrect; + end + else begin + result:= tgripframe(fframe).handlerect; + end; +end; + +function tdocktoolbar.gethidebuttonrect: rectty; +begin + if fframe = nil then begin + result:= nullrect; + end + else begin + result:= tgripframe(fframe).hidebuttonrect; + end; +end; + +function tdocktoolbar.getplacementrect: rectty; +begin + result:= innerpaintrect; +end; + } + +{ tcustomstockglyphtoolbutton } + +constructor tcustomstockglyphtoolbutton.create(const aowner: tobject; + const aprop: tindexpersistentarrayprop); +begin + inherited; + finfo.imagelist:= stockobjects.glyphs; +end; + +function tcustomstockglyphtoolbutton.isimageliststored: boolean; +begin + result:= inherited isimageliststored and + (finfo.imagelist <> stockobjects.glyphs); +end; + +procedure tcustomstockglyphtoolbutton.setimagelist(const Value: timagelist); +begin + if value = nil then begin + inherited setimagelist(stockobjects.glyphs); + end + else begin + inherited setimagelist(value); + end; +end; + +{ tstockglyphtoolbuttons } + +class function tstockglyphtoolbuttons.getbuttonclass: toolbuttonclassty; +begin + result:= tstockglyphtoolbutton; +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/msetraywidget.pas b/mseide-msegui/lib/common/widgets/msetraywidget.pas new file mode 100644 index 0000000..5fc9d29 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msetraywidget.pas @@ -0,0 +1,499 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msetraywidget; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifndef mswindows} + {$ifndef mse_no_dbus} + {$define mse_usedbus} + {$endif} +{$endif} +interface +uses + msetypes,mseclasses,classes,mclasses,msesimplewidgets,mseguiglob,msebitmap, + msegui, + mseevent,mseglob,msegraphics,msestrings,msetimer,msemenus,msegraphutils + {$ifdef mse_usedbus},msestatusnotifieritem{$endif}; + +const + trayoptionswidget = [ow_appinactivehint]; + +type + traywidgetoptionty = (two_usedbus); + traywidgetoptionsty = set of traywidgetoptionty; + + ttraywidget = class(teventwidget) + private + ficon: tmaskedbitmap; + ficonchanging: integer; + fimagelist: timagelist; + fimagenum: integer; + fmessageid: longword; + ftimer: tsimpletimer; + fcaption: msestring; + foptions: traywidgetoptionsty; + fondbusactivate: notifyeventty; + fondbussecondaryactivate: notifyeventty; + procedure seticon(const avalue: tmaskedbitmap); + procedure setimagelist(const avalue: timagelist); + procedure setimagenum(const avalue: integer); + procedure setcaption(const avalue: msestring); + procedure setoptions(const avalue: traywidgetoptionsty); + protected + {$ifdef mse_usedbus} + fstatusnotifieritem: tstatusnotifieritem; + procedure dbusdocontextmenu(const sender: tstatusnotifieritem; + const apos: pointty); + procedure dbusdoactivate(const sender: tstatusnotifieritem; + const apos: pointty); + procedure dbusdosecondaryactivate(const sender: tstatusnotifieritem; + const apos: pointty); + {$endif} + {$ifdef mswindows} + procedure showhint(const aid: int32; var info: hintinfoty); override; + {$endif} + procedure dotimer(const sender: tobject); + procedure settrayhint; + procedure sethint(const avalue: msestring); override; + procedure dopaintforeground(const acanvas: tcanvas); override; + procedure objectevent(const sender: tobject; + const event: objecteventty); override; + procedure iconchanged(const sender: tobject); + {$ifdef mse_usedbus} + function hasdbus: boolean; + {$endif} + function dock: boolean; //true if OK + procedure undock; + procedure setvisible(const avalue: boolean); override; + procedure loaded; override; + procedure updatewindowinfo(var info: windowinfoty) override; + procedure dopopup(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); override; + + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + procedure showmessage(const amessage: msestring; + const timeoutms: integer = 0); + procedure showmessage(const amessage: msestring; const atitle: msestring; + const timeoutms: integer = 0); + //for dbus org.freedesktop.Notifications + procedure cancelmessage(); + published + property icon: tmaskedbitmap read ficon write seticon; + property imagelist: timagelist read fimagelist write setimagelist; + property imagenum: integer read fimagenum write setimagenum default -1; + property caption: msestring read fcaption write setcaption; + property optionswidget default defaultoptionswidget + trayoptionswidget; + property options: traywidgetoptionsty read foptions + write setoptions default []; + property ondbusactivate: notifyeventty read fondbusactivate write + fondbusactivate; + property ondbussecondaryactivate: notifyeventty + read fondbussecondaryactivate write fondbussecondaryactivate; + end; + +implementation +uses + mseguiintf,sysutils,msewidgets; + +{ ttraywidget } + +constructor ttraywidget.create(aowner: tcomponent); +begin +(* + {$ifdef mse_usedbus} + if not (csdesigning in componentstate) then begin + fstatusnotifieritem:= tstatusnotifieritem.create(); + fstatusnotifieritem.oncontextmenu:= @dbusdocontextmenu; + end; + {$endif} +*) + fimagenum:= -1; + ficon:= tcenteredbitmap.create(bmk_rgb{false}); + ficon.onchange:= {$ifdef FPC}@{$endif}iconchanged; + inherited; + foptionswidget:= foptionswidget + trayoptionswidget; +end; + +destructor ttraywidget.destroy; +begin + visible:= false; + undock(); + freeandnil(ftimer); + ficon.free; + inherited; +{$ifdef mse_usedbus} + fstatusnotifieritem.free(); +{$endif} +end; + +procedure ttraywidget.setoptions(const avalue: traywidgetoptionsty); +begin + if avalue <> foptions then begin + foptions:= avalue; + {$ifdef mse_usedbus} + if (two_usedbus in foptions) and (fstatusnotifieritem = nil) then begin + fstatusnotifieritem:= tstatusnotifieritem.create(); + fstatusnotifieritem.oncontextmenu:= @dbusdocontextmenu; + fstatusnotifieritem.onactivate:= @dbusdoactivate; + fstatusnotifieritem.onsecondaryactivate:= @dbusdosecondaryactivate; + end + else begin + freeandnil(fstatusnotifieritem); + end; + {$endif} + end; +end; + +function ttraywidget.dock: boolean; +var + bo1: boolean; +begin + result:= true; +{$ifdef mse_usedbus} + if hasdbus then begin + //nothing to do + end + else begin +{$endif} + if (parentwidget <> nil) or (window.syscontainer <> sywi_tray) then begin + bo1:= visible; + visible:= false; + parentwidget:= nil; + try + window.syscontainer:= sywi_tray; + except + result:= false; + exit; + end; + visible:= bo1; + end; +{$ifdef mse_usedbus} + end; +{$endif} +end; + +procedure ttraywidget.undock; +begin + if ownswindow then begin + window.syscontainer:= sywi_none; + end; +end; + +{$ifdef mse_usedbus} +function ttraywidget.hasdbus(): boolean; +begin + result:= (fstatusnotifieritem <> nil) and + fstatusnotifieritem.checkdesktop(); +end; +{$endif} + +procedure ttraywidget.setvisible(const avalue: boolean); +begin +{$ifdef mse_usedbus} + if (componentstate * [csdesigning,csloading] = []) and + (hasdbus and (avalue <> fstatusnotifieritem.active) or + not hasdbus and (avalue <> visible)) then begin +{$else} + if (componentstate * [csdesigning,csloading] = []) and + (avalue <> visible) then begin +{$endif} + if avalue then begin + if dock() then begin + setcaption(fcaption); + iconchanged(nil); + settrayhint; + {$ifdef mse_usedbus} + if hasdbus then begin + fstatusnotifieritem.active:= true; + end + else begin + {$endif} + inherited; + {$ifdef mse_usedbus} + end; + {$endif} + end; + end + else begin + cancelmessage(); + {$ifdef mse_usedbus} + if hasdbus then begin + fstatusnotifieritem.active:= false; + end + else begin + {$endif} + inherited; + {$ifdef mse_usedbus} + end; + {$endif} + undock(); + end; + end + else begin + inherited; + end; +end; + +procedure ttraywidget.loaded; +begin + if not(csdesigning in componentstate) and visible then begin + visible:= false; + inherited; + if dock() then begin + visible:= true; + end; + end + else begin + inherited; + end; +end; + +procedure ttraywidget.updatewindowinfo(var info: windowinfoty); +begin + inherited; + info.options:= info.options + [wo_embedded,wo_noframe]; +end; + +procedure ttraywidget.seticon(const avalue: tmaskedbitmap); +begin + ficon.assign(avalue); +end; + +procedure ttraywidget.settrayhint(); +{$ifdef mse_usedbus} +var + tt1: tooltipinfoty; +{$endif} +begin +{$ifdef mse_usedbus} + if hasdbus then begin + tt1.title:= stringtoutf8(hint); + fstatusnotifieritem.settooltip(tt1); + end + else begin +{$endif} + if ownswindow then begin + gui_settrayhint(windowpo^,hint); + end; +{$ifdef mse_usedbus} + end; +{$endif} +end; + +procedure ttraywidget.iconchanged(const sender: tobject); +var + icon1,mask1: pixmapty; + bmp1: tmaskedbitmap; +begin + if not (csloading in componentstate) then begin + if ficonchanging = 0 then begin + inc(ficonchanging); + bmp1:= tmaskedbitmap.create(bmk_rgb{false}); + try + if (fimagelist = nil) or (fimagenum < 0) or + (fimagenum >= fimagelist.count) then begin + bmp1.assign(ficon); + end + else begin + bmp1.options:= fimagelist.options; + fimagelist.getimage(fimagenum,bmp1); + end; + invalidate; +// bmp1.colormask:= false; + {$ifdef mse_usedbus} + if hasdbus then begin + fstatusnotifieritem.seticonpixmap(bmp1); + end + else begin + {$endif} + if ownswindow and not (csdesigning in componentstate) then begin + getwindowicon(bmp1,icon1,mask1,true); + gui_settrayicon(windowpo^,icon1,mask1); + end; + {$ifdef mse_usedbus} + end; + {$endif} + finally + dec(ficonchanging); + bmp1.free; + end; + end; + end; +end; + +procedure ttraywidget.objectevent(const sender: tobject; + const event: objecteventty); +begin + inherited; + if (sender = fimagelist) and (event = oe_changed) then begin + iconchanged(nil); + end; +end; + +procedure ttraywidget.setimagelist(const avalue: timagelist); +begin + setlinkedvar(avalue,tmsecomponent(fimagelist)); + iconchanged(nil); +end; + +procedure ttraywidget.setimagenum(const avalue: integer); +begin + if avalue <> fimagenum then begin + fimagenum:= avalue; + iconchanged(nil); + end; +end; + +procedure ttraywidget.dopaintforeground(const acanvas: tcanvas); +begin + inherited; + if (fimagelist <> nil) and (fimagenum >= 0) then begin + fimagelist.paint(acanvas,fimagenum,innerclientrect,ficon.alignment); + end + else begin + if not ficon.isempty then begin + ficon.paint(acanvas,innerclientrect,ficon.alignment); + end; + end; +end; + +procedure ttraywidget.sethint(const avalue: msestring); +begin + inherited; + if not (csloading in componentstate) then begin + settrayhint; + end; +end; + +procedure ttraywidget.dopopup(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); +begin + {$ifdef mswindows} + if ownswindow then begin + gui_settrayhint(windowpo^,''); + try + inherited; + finally + gui_settrayhint(windowpo^,hint); + end; + end + else begin + inherited; + end; + {$else} + inherited; + {$endif} +end; + +procedure ttraywidget.showmessage(const amessage: msestring; + const atitle: msestring; const timeoutms: integer = 0); +begin +{$ifdef mse_usedbus} + if visible or hasdbus and fstatusnotifieritem.active then begin +{$else} + if visible then begin +{$endif} + cancelmessage; + if amessage <> '' then begin + {$ifdef mse_usedbus} + if hasdbus then begin + fstatusnotifieritem.showmessage(amessage,atitle,fmessageid,timeoutms); + end + else begin + {$endif} + gui_traymessage(windowpo^,amessage,fmessageid,timeoutms); + {$ifdef mse_usedbus} + end; + {$endif} + if timeoutms > 0 then begin + ftimer:= tsimpletimer.create(timeoutms*1000,{$ifdef FPC}@{$endif}dotimer, + true,[to_single]); + end; + end; + end; +end; + +procedure ttraywidget.showmessage(const amessage: msestring; + const timeoutms: integer); +begin + showmessage(amessage,'',timeoutms); +end; + +procedure ttraywidget.cancelmessage; +begin + if fmessageid <> 0 then begin + freeandnil(ftimer); + {$ifdef mse_usedbus} + if hasdbus then begin + fstatusnotifieritem.cancelmessage(fmessageid); + end + else begin + {$endif} + gui_canceltraymessage(windowpo^,fmessageid); + {$ifdef mse_usedbus} + end; + {$endif} + fmessageid:= 0; + end; +end; + +procedure ttraywidget.dotimer(const sender: tobject); +begin + cancelmessage; +end; + +procedure ttraywidget.setcaption(const avalue: msestring); +begin + fcaption:= avalue; + if ownswindow then begin + window.caption:= fcaption; + end; +{$ifdef mse_usedbus} + if hasdbus then begin + fstatusnotifieritem.settitle(stringtoutf8ansi(avalue)); + end; +{$endif} +end; + +{$ifdef mse_usedbus} +procedure ttraywidget.dbusdocontextmenu(const sender: tstatusnotifieritem; + const apos: pointty); +begin + if popupmenu <> nil then begin + popupmenu.show(nil,apos); + end; +end; + +procedure ttraywidget.dbusdoactivate(const sender: tstatusnotifieritem; + const apos: pointty); +begin + if canevent(tmethod(fondbusactivate)) then begin + fondbusactivate(self); + end; +end; + +procedure ttraywidget.dbusdosecondaryactivate(const sender: tstatusnotifieritem; + const apos: pointty); +begin + if canevent(tmethod(fondbussecondaryactivate)) then begin + fondbussecondaryactivate(self); + end; +end; +{$endif} + +{$ifdef mswindows} +procedure ttraywidget.showhint(const aid: int32; var info: hintinfoty); +begin + //dummy; +end; +{$endif} + +end. diff --git a/mseide-msegui/lib/common/widgets/msewidgets.pas b/mseide-msegui/lib/common/widgets/msewidgets.pas new file mode 100644 index 0000000..ae345d6 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msewidgets.pas @@ -0,0 +1,6475 @@ +{ MSEgui Copyright (c) 1999-2018 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msewidgets; + +{$ifdef FPC}{$mode objfpc}{$h+}{$interfaces corba}{$goto on}{$endif} + +interface +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} +uses + classes,mclasses,msegui,mseguiglob,msetypes,msestrings,msegraphutils, + msegraphics,msesystypes,mseassistiveclient,mselist, + mseevent,msescrollbar,msemenus,mserichstring,msedrawtext,mseglob,mseact, + mseshapes,mseclasses,msebitmap,msetimer; + +type + + sizeeventty = procedure(const sender: tobject; var asize: sizety) of object; + + tframefont = class(tparentfont) + public + class function getinstancepo(owner: tobject): pfont; override; + end; + + captionframeoptionty = (cfo_fixleft,cfo_fixright,cfo_fixtop,cfo_fixbottom, + cfo_autowidth,cfo_autoheight, + //paint area as big as possible + cfo_captionnogray, + cfo_captiondistouter,cfo_captionframecentered, + cfo_captionnoclip,cfo_nofocusrect,cfo_forcefocusrect, + cfo_focusrect, //override template fso_nofocusrect + cfo_captionfocus,cfo_framerectfocus + {,cfo_captionbackground}); + captionframeoptionsty = set of captionframeoptionty; + +const + defaultcaptionframeoptions = []; +type + doublewidgetty = record + a,b: twidget; + end; + pdoublewidgetty = ^doublewidgetty; + doublewidgetarty = array of doublewidgetty; + ttaborderoverride = class; + tabordereventty = procedure(const sender: ttaborderoverride; + const current: twidget; const down: boolean; + var next: twidget) of object; + ttaborderoverride = class(tlinkedpersistent) + private + fontaborder: tabordereventty; + procedure readitems(reader: treader); + procedure writeitems(writer: twriter); + protected + fowner: twidget; + fitems: doublewidgetarty; + fwidgetnames: stringarty; + procedure defineproperties(filer: tfiler) override; + procedure objevent(const sender: iobjectlink; + const event: objecteventty) override; + procedure endread(const reader: treader); + public + constructor create(const aowner: twidget); reintroduce; + destructor destroy(); override; + procedure clear(); + function nexttaborder(sender: twidget; const down: boolean): twidget; + procedure add(const aa,ab: twidget); + property owner: twidget read fowner; + published + property ontaborder: tabordereventty read fontaborder write fontaborder; + end; + + tcustomcaptionframe = class(tcustomframe) + private + fcaptionpos: captionposty; + fupdating: integer; + fcaption: msestring; +// function getcaption: msestring; + procedure setcaption(const avalue: msestring); + procedure fontchanged(const sender: tobject); + function isfontstored: Boolean; + procedure setfont(const Value: tframefont); + function getfont: tframefont; + procedure setcaptionpos(const avalue: captionposty); + procedure setcaptiondist(const Value: integer); + function iscaptiondiststored: boolean; + procedure setcaptionoffset(const Value: integer); + function iscaptionoffsetstored: boolean; + procedure readouterframe(reader: treader); + procedure writeouterframe(writer: twriter); + procedure readcaptionnoclip(reader: treader); + procedure readcaptiondistouter(reader: treader); + procedure setoptions(const avalue: captionframeoptionsty); + procedure setcaptiontextflags(const avalue: textflagsty); + protected + ffont: tframefont; + finfo: drawtextinfoty; + fcaptiondist: integer; + fcaptionoffset: integer; + foptions: captionframeoptionsty; + procedure settemplateinfo(const ainfo: frameinfoty); override; + procedure parentfontchanged; override; + procedure fontcanvaschanged; override; + procedure visiblechanged; override; + + function updatetextflags(const aflags: textflagsty): textflagsty; + procedure updaterects; override; + procedure updatehotkeys() override; + procedure dominsize(var asize: sizety); + procedure checkminshrinksize(var asize: sizety) override; + procedure defineproperties(filer: tfiler); override; + procedure setdisabled(const value: boolean); override; + procedure dopaintfocusrect(const canvas: tcanvas; + const rect: rectty); override; + function checkfocusshortcut(var info: keyeventinfoty): boolean; override; + function needsfocuspaint: boolean; override; + function haspaintrectfocus(): boolean; override; //checks caption + procedure updatemousestate(const sender: twidget; + const info: mouseeventinfoty); override; + procedure internalpaintoverlay(const canvas: tcanvas; + const arect: rectty) override; + + //iassistiveclient + function getassistivecaption(): msestring; override; + + public + constructor create(const aintf: icaptionframe); + destructor destroy; override; + procedure scale(const ascale: real); override; + procedure createfont; + function pointincaption(const point: pointty): boolean; override; + //origin = widgetrect + procedure checkwidgetsize(var asize: sizety); override; + //extends to minimal size + + property options: captionframeoptionsty read foptions + write setoptions default defaultcaptionframeoptions; + property caption: msestring read fcaption write setcaption; + property captiontextflags: textflagsty read finfo.flags write + setcaptiontextflags default []; + property captionpos: captionposty read fcaptionpos + write setcaptionpos default cp_topleft; + property captiondist: integer read fcaptiondist write setcaptiondist + stored iscaptiondiststored default 1; + property captionoffset: integer read fcaptionoffset write setcaptionoffset + stored iscaptionoffsetstored default 0 ; + property font: tframefont read getfont + write setfont stored isfontstored; + end; + + tcaptionframe = class(tcustomcaptionframe) + published + property options; + property levelo; + property leveli; + property framewidth; + property colorframe; + property colorframeactive; + property colorframedisabled; + property colorframemouse; + property colorframeclicked; + property colorframedefault; + property colordkshadow; + property colorshadow; + property colorlight; + property colorhighlight; + property colordkwidth; + property colorhlwidth; + property hiddenedges; + property framei_left; + property framei_top; + property framei_right; + property framei_bottom; + property frameo_left; + property frameo_top; + property frameo_right; + property frameo_bottom; + + property frameimage_list; + property frameimage_left; + property frameimage_top; + property frameimage_right; + property frameimage_bottom; + property frameimage_offset; + property frameimage_offset1; + property frameimage_offsetdisabled; + property frameimage_offsetmouse; + property frameimage_offsetclicked; + property frameimage_offsetactive; + property frameimage_offsetfocused; +{ + property frameimage_offsetactivemouse; + property frameimage_offsetactiveclicked; +} + property frameface_list; + property frameface_offset; + property frameface_offset1; + property frameface_offsetdisabled; + property frameface_offsetmouse; + property frameface_offsetclicked; + property frameface_offsetactive; + property frameface_offsetfocused; +{ + property frameface_offsetactivemouse; + property frameface_offsetactiveclicked; +} + property optionsskin; + + property colorclient; + property caption; + property captiontextflags; + property captionpos; + property captiondist; + property captionoffset; + property focusrectdist; + property extraspace; + property imagedist; + property imagedist1; + property imagedist2; + property font; + property localprops; //before template + property localprops1; //before template + property template; + end; + + timpressedcaptionframe = class(tcaptionframe) + public + constructor create(const aintf: icaptionframe); + published + property levelo default -2; + end; + +const + defaultscrollboxscrollbaroptions = [sbo_thumbtrack,sbo_moveauto,sbo_showauto]; + scrollbarframestates: framestatesty = [fs_sbleft,fs_sbtop,fs_sbright,fs_sbbottom]; + +type + tscrollboxscrollbar = class(tnopagesizescrollbar) + public + constructor create(intf: iscrollbar; org: originty = org_client; + ondimchanged: proceventty = nil); override; + published + property options default defaultscrollboxscrollbaroptions; + end; + +const + defaultthumbtrackscrollbaroptions = [sbo_thumbtrack,sbo_showauto]; + +type + tthumbtrackscrollbar = class(tnomoveautoscrollbar) + public + constructor create(intf: iscrollbar; org: originty = org_client; + ondimchanged: proceventty = nil); override; + published + property options default defaultthumbtrackscrollbaroptions; + end; + + tthumbtracknopagesizescrollbar = class(tnomoveautonopagesizescrollbar) + public + constructor create(intf: iscrollbar; org: originty = org_client; + ondimchanged: proceventty = nil); override; + published + property options default defaultthumbtrackscrollbaroptions; + end; + + framescrollbarclassty = class of tcustomscrollbar; + + optionscrollty = (oscr_drag,oscr_zoomwidth,oscr_zoomheight, + oscr_key,oscr_mousewheel); + optionsscrollty = set of optionscrollty; + +const + defaultoptionsscroll = [oscr_mousewheel]; + defaultdragbuttons = [ss_middle]; + +type + tcustomscrollframe = class(tcustomcaptionframe) + private + fdragbuttons: shiftstatesty; + procedure setsbhorz(const Value: tcustomscrollbar); + procedure setsbvert(const Value: tcustomscrollbar); + procedure setdragbuttons(const avalue: shiftstatesty); + protected + fhorz,fvert: tcustomscrollbar; + foptionsscroll: optionsscrollty; + procedure settemplateinfo(const ainfo: frameinfoty); override; + procedure updatestate; override; + procedure updatevisiblescrollbars; virtual; + procedure updaterects; override; + procedure getpaintframe(var frame: framety); override; + procedure addscrollbarwidth(var asize: sizety) override; + procedure subscrollbarwidth(var asize: sizety) override; + function getscrollbarclass(vert: boolean): framescrollbarclassty; virtual; + procedure activechanged; override; + procedure updatemousestate(const sender: twidget; + const info: mouseeventinfoty); override; + procedure internalpaintoverlay(const canvas: tcanvas; + const arect: rectty) override; + public + constructor create(const aintf: iscrollframe; const scrollintf: iscrollbar); + destructor destroy; override; + procedure checktemplate(const sender: tobject); override; + //true if match + procedure mouseevent(var info: mouseeventinfoty); virtual; + procedure domousewheelevent(var info: mousewheeleventinfoty; + const pagingreversed: boolean); virtual; + property optionsscroll: optionsscrollty read foptionsscroll + write foptionsscroll default defaultoptionsscroll; + property dragbuttons: shiftstatesty read fdragbuttons write setdragbuttons + default defaultdragbuttons; + property state: framestatesty read fstate; + property sbhorz: tcustomscrollbar read fhorz write setsbhorz; + property sbvert: tcustomscrollbar read fvert write setsbvert; + end; + + tscrollframe = class(tcustomscrollframe) + private + procedure setsbhorz(const avalue: tscrollbar); + function getsbhorz: tscrollbar; + procedure setsbvert(const avalue: tscrollbar); + function getsbvert: tscrollbar; + protected + function getscrollbarclass(vert: boolean): framescrollbarclassty; override; + published + property options; + property levelo; + property leveli; + property framewidth; + property colordkshadow; + property colorshadow; + property colorlight; + property colorhighlight; + property colorhlwidth; + property hiddenedges; + property colorframe; + property colorframeactive; + property colorframedisabled; + property colorframemouse; + property colorframeclicked; + property colorframedefault; + property framei_left; + property framei_top; + property framei_right; + property framei_bottom; + property frameo_left; + property frameo_top; + property frameo_right; + property frameo_bottom; + + property frameimage_list; + property frameimage_left; + property frameimage_top; + property frameimage_right; + property frameimage_bottom; + property frameimage_offset; + property frameimage_offset1; + property frameimage_offsetdisabled; + property frameimage_offsetmouse; + property frameimage_offsetclicked; + property frameimage_offsetactive; + property frameimage_offsetfocused; +{ + property frameimage_offsetactivemouse; + property frameimage_offsetactiveclicked; +} + property frameface_list; + property frameface_offset; + property frameface_offset1; + property frameface_offsetdisabled; + property frameface_offsetmouse; + property frameface_offsetclicked; + property frameface_offsetactive; + property frameface_offsetfocused; +{ + property frameface_offsetactivemouse; + property frameface_offsetactiveclicked; +} + property optionsskin; + + property sbhorz: tscrollbar read getsbhorz write setsbhorz; + property sbvert: tscrollbar read getsbvert write setsbvert; + property colorclient; + property caption; + property captiontextflags; + property captionpos; + property captiondist; + property captionoffset; + property focusrectdist; + property extraspace; + property imagedist; + property imagedist1; + property imagedist2; + property font; + property localprops; //before template + property localprops1; //before template + property template; + end; + + tcustomthumbtrackscrollframe = class(tcustomscrollframe) + protected + function getscrollbarclass(vert: boolean): framescrollbarclassty; override; + end; + + iscrollbox = interface(iscrollbar) + function getscrollsize: sizety; + end; + +type + tcustomscrollboxframe = class(tcustomscrollframe,iscrollbox) + private + fscrolling: integer; + fclientsize: sizety; + fclientsizemin: sizety; + fdragging: boolean; + fpickpos: pointty; + fpickref: pointty; + fzoom: complexty; + fzoomwidthstep: real; + fzoomheightstep: real; + fzoomwheelsensitivity: real; + procedure clientrecttoscrollbar(const rect: rectty); + procedure setclientsize(const avalue: sizety); + procedure setclientheight(const avalue: integer); + procedure setclientwidth(const avalue: integer); + procedure setclientsizemin(const avalue: sizety); + procedure setclientheightmin(const avalue: integer); + procedure setclientwidthmin(const avalue: integer); + procedure calcclientrect(var aclientrect: rectty); + function getwidget: twidget; + procedure setsbhorz(const avalue: tscrollboxscrollbar); + function getsbhorz: tscrollboxscrollbar; + procedure setsbvert(const avalue: tscrollboxscrollbar); + function getsbvert: tscrollboxscrollbar; + procedure setzoom1(const avalue: complexty); + procedure setzoom(const avalue: complexty); + procedure setzoomwidth(const avalue: real); + procedure setzoomheight(const avalue: real); + function getscrollpos_x: integer; + procedure setscrollpos_x(const avalue: integer); + function getscrollpos_y: integer; + procedure setscrollpos_y(const avalue: integer); + procedure readzoomwidthstep(reader: treader); + procedure writezoomwidthstep(writer: twriter); + procedure readzoomheightstep(reader: treader); + procedure writezoomheightstep(writer: twriter); + procedure readzoomwheelsensitivity(reader: treader); + procedure writezoomwheelsensitivity(writer: twriter); + protected + fowner: twidget; + procedure scrollpostoclientpos(var aclientrect: rectty); virtual; + procedure checkminscrollsize(var asize: sizety); override; + procedure checkminclientsize(var asize: sizety); override; + function isdragstart(const sender: twidget; + const info: mouseeventinfoty): boolean; + procedure initinnerframe; virtual; + function getscrollbarclass(vert: boolean): framescrollbarclassty; override; + procedure updatevisiblescrollbars; override; + procedure scrollevent(sender: tcustomscrollbar; event: scrolleventty); virtual; + procedure dokeydown(var info: keyeventinfoty); override; + function getclientpos: pointty; + procedure setclientpos(apos: pointty); + procedure setscrollpos(apos: pointty); + procedure updatemousestate(const sender: twidget; + const info: mouseeventinfoty); override; + procedure defineproperties(filer: tfiler); override; + //iscrollbar + function translatecolor(const acolor: colorty): colorty; + procedure invalidaterect(const rect: rectty; const org: originty; + const noclip: boolean = false); + //iscrollbox + function getscrollsize: sizety; + public + constructor create(const aintf: iscrollframe; const owner: twidget); + procedure childmouseevent(const sender: twidget; + var info: mouseeventinfoty); virtual; + procedure domousewheelevent(var info: mousewheeleventinfoty; + const pagingreversed: boolean); override; + procedure updateclientrect; override; + procedure showrect(const arect: rectty; const bottomright: boolean); + //origin paintpos + property scrollpos: pointty read getclientpos write setscrollpos; + property scrollpos_x: integer read getscrollpos_x write setscrollpos_x; + property scrollpos_y: integer read getscrollpos_y write setscrollpos_y; + //origin = paintpos + property zoom: complexty read fzoom write setzoom; //default 1,1 + property zoomwidth: real read fzoom.re write setzoomwidth; //default 1 + property zoomheight: real read fzoom.im write setzoomheight; //default 1 + property zoomwidthstep: real read fzoomwidthstep + write fzoomwidthstep stored false; + //default 1 + property zoomheightstep: real read fzoomheightstep + write fzoomheightstep stored false; + //default 1 + property zoomwheelsensitivity: real read fzoomwheelsensitivity + write fzoomwheelsensitivity stored false; + //default 0 + property clientsize: sizety read fclientsize write setclientsize; + property clientwidth: integer read fclientsize.cx + write setclientwidth default 0; + property clientheight: integer read fclientsize.cy + write setclientheight default 0; + property clientsizemin: sizety read fclientsizemin write setclientsizemin; + property clientwidthmin: integer read fclientsizemin.cx + write setclientwidthmin default 0; + property clientheightmin: integer read fclientsizemin.cy + write setclientheightmin default 0; + property framei_left default 2; + property framei_top default 2; + property framei_right default 2; + property framei_bottom default 2; + property sbhorz: tscrollboxscrollbar read getsbhorz write setsbhorz; + property sbvert: tscrollboxscrollbar read getsbvert write setsbvert; + end; + + tscrollboxframe = class(tcustomscrollboxframe) + published + property options; + property optionsscroll; + property dragbuttons; + property clientwidth; + property clientheight; + property clientwidthmin; + property clientheightmin; + property zoomwidthstep; + property zoomheightstep; + property zoomwheelsensitivity; + property levelo; + property leveli; + property framewidth; + property colorframe; + property colorframeactive; + property colorframedisabled; + property colorframemouse; + property colorframeclicked; + property colorframedefault; + property colordkshadow; + property colorshadow; + property colorlight; + property colorhighlight; + property colordkwidth; + property colorhlwidth; + property hiddenedges; + property colorclient; + property framei_left; + property framei_top; + property framei_right; + property framei_bottom; + property frameo_left; + property frameo_top; + property frameo_right; + property frameo_bottom; + + property frameimage_list; + property frameimage_left; + property frameimage_top; + property frameimage_right; + property frameimage_bottom; + property frameimage_offset; + property frameimage_offset1; + property frameimage_offsetdisabled; + property frameimage_offsetmouse; + property frameimage_offsetclicked; + property frameimage_offsetactive; + property frameimage_offsetfocused; +{ + property frameimage_offsetactivemouse; + property frameimage_offsetactiveclicked; +} + property frameface_list; + property frameface_offset; + property frameface_offset1; + property frameface_offsetdisabled; + property frameface_offsetmouse; + property frameface_offsetclicked; + property frameface_offsetactive; + property frameface_offsetfocused; +{ + property frameface_offsetactivemouse; + property frameface_offsetactiveclicked; +} + property optionsskin; + + property caption; + property captiontextflags; + property captionpos; + property captiondist; + property captionoffset; + property focusrectdist; + property extraspace; + property imagedist; + property imagedist1; + property imagedist2; + property font; + property localprops; //before template + property localprops1; //before template + property template; + property sbhorz; + property sbvert; + end; + + stepkindty = (sk_right,sk_up,sk_left,sk_down,sk_first,sk_last); + stepkindsty = set of stepkindty; +const + allstepkinds = [sk_right,sk_up,sk_left,sk_down,sk_first,sk_last]; +type + istepbar = interface(inullinterface) + function translatecolor(const aclor: colorty): colorty; + procedure invalidaterect(const rect: rectty; const org: originty; + const noclip: boolean = false); + function dostep(const event: stepkindty; const adelta: real; + ashiftstate: shiftstatesty): boolean; + //true on action + end; + stepbuttonposty = (sbp_right,sbp_top,sbp_left,sbp_bottom); + + framestepinfoty = record + down,up,pagedown,pageup,pagelast: integer; + end; + +const + defaultstepbuttonsize = 13; + +type + stepframestatety = (sfs_spinedit,sfs_canstep); + stepframestatesty = set of stepframestatety; + + tcustomstepframe = class(tcustomcaptionframe,iframe) + private + fstepintf: istepbar; + fbuttonsize: integer; + fbuttons: shapeinfoarty; + fcolorbutton: colorty; + fbuttonpos: stepbuttonposty; + fbuttonslast: boolean; + fdisabledbuttons: stepkindsty; + fneededbuttons: stepkindsty; + fbuttonsinline: boolean; + fmousewheel: boolean; + frepeater: tsimpletimer; + frepeatedbutton: integer; + fbuttonface: tface; + fbuttonframe: tframe; + factbuttonindex: integer; + fcolorglyph: colorty; + procedure setbuttonsize(const Value: integer); + procedure setbuttonpos(const Value: stepbuttonposty); + procedure setbuttonsinline(const value: boolean); + procedure setbuttonslast(const avalue: boolean); + procedure setcolorbutton(const avalue: colorty); + procedure setdisabledbuttons(const avalue: stepkindsty); + procedure setbuttonsinvisible(const avalue: stepkindsty); + procedure setbuttonsvisible(const avalue: stepkindsty); + procedure setneededbuttons(const avalue: stepkindsty); + function getbuttonface: tface; + procedure setbuttonface(const avalue: tface); + function getbuttonframe: tframe; + procedure setbuttonframe(const avalue: tframe); + procedure setcolorglyph(const avalue: colorty); + protected + fforceinvisiblebuttons: stepkindsty; + fforcevisiblebuttons: stepkindsty; + fstepstate: stepframestatesty; + fdim: rectty; + procedure dorepeat(const sender: tobject); + procedure killrepeater; + procedure layoutchanged; + procedure updaterects; override; + procedure getpaintframe(var frame: framety); override; + procedure updatelayout; + procedure execute(const tag: integer; const info: mouseeventinfoty); + property neededbuttons: stepkindsty read fneededbuttons + write setneededbuttons; + //iframe + procedure setframeinstance(instance: tcustomframe); + procedure setstaticframe(value: boolean); + function getstaticframe: boolean; + function getwidgetrect: rectty; + function getcomponentstate: tcomponentstate; + function getmsecomponentstate: msecomponentstatesty; + procedure scrollwidgets(const dist: pointty); + procedure clientrectchanged; + procedure invalidate; + procedure invalidatewidget; + procedure invalidaterect(const rect: rectty; + const org: originty = org_client; const noclip: boolean = false); + function getwidget: twidget; + function getframestateflags: framestateflagsty; virtual; + procedure internalpaintoverlay(const canvas: tcanvas; + const arect: rectty) override; + public + constructor create(const aintf: icaptionframe; const stepintf: istepbar); + destructor destroy; override; + procedure createbuttonface; + procedure createbuttonframe; + + procedure updatemousestate(const sender: twidget; + const info: mouseeventinfoty); override; + procedure mouseevent(var info: mouseeventinfoty); virtual; + procedure domousewheelevent(var info: mousewheeleventinfoty); virtual; + procedure checktemplate(const sender: tobject); override; + procedure updatebuttonstate(const first,delta,count: integer); + function canstep: boolean; + function executestepevent(const event: stepkindty; + const stepinfo: framestepinfoty; const aindex: integer): integer; + property buttonsize: integer read fbuttonsize write setbuttonsize + default defaultstepbuttonsize; + property colorbutton: colorty read fcolorbutton + write setcolorbutton default cl_default; + //cl_default maps to widget color + property colorglyph: colorty read fcolorglyph + write setcolorglyph default cl_default; + //cl_default maps to widget color + property buttonface: tface read getbuttonface write setbuttonface; + property buttonframe: tframe read getbuttonframe write setbuttonframe; + + property disabledbuttons: stepkindsty read fdisabledbuttons + write setdisabledbuttons default []; + property buttonsinvisible: stepkindsty read fforceinvisiblebuttons + write setbuttonsinvisible default [sk_first,sk_last]; + property buttonsvisible: stepkindsty read fforcevisiblebuttons + write setbuttonsvisible default []; + property buttonpos: stepbuttonposty read fbuttonpos + write setbuttonpos default sbp_right; + property buttonslast: boolean read fbuttonslast + write setbuttonslast default false; + property buttonsinline: boolean read fbuttonsinline + write setbuttonsinline default false; + property mousewheel: boolean read fmousewheel write fmousewheel default true; + end; + + tstepframe = class(tcustomstepframe) + published + property options; + property levelo; + property leveli; + property framewidth; + property colorframe; + property colorframeactive; + property colorframedisabled; + property colorframemouse; + property colorframeclicked; + property colorframedefault; + property colordkshadow; + property colorshadow; + property colorlight; + property colorhighlight; + property colordkwidth; + property colorhlwidth; + property hiddenedges; + property colorclient; + property colorbutton; + property colorglyph; + property framei_left; + property framei_top; + property framei_right; + property framei_bottom; + property frameo_left; + property frameo_top; + property frameo_right; + property frameo_bottom; + + property frameimage_list; + property frameimage_left; + property frameimage_top; + property frameimage_right; + property frameimage_bottom; + property frameimage_offset; + property frameimage_offset1; + property frameimage_offsetdisabled; + property frameimage_offsetmouse; + property frameimage_offsetclicked; + property frameimage_offsetactive; + property frameimage_offsetfocused; +{ + property frameimage_offsetactivemouse; + property frameimage_offsetactiveclicked; +} + property frameface_list; + property frameface_offset; + property frameface_offset1; + property frameface_offsetdisabled; + property frameface_offsetmouse; + property frameface_offsetclicked; + property frameface_offsetactive; + property frameface_offsetfocused; +{ + property frameface_offsetactivemouse; + property frameface_offsetactiveclicked; +} + property optionsskin; + + property caption; + property captiontextflags; + property captionpos; + property captiondist; + property captionoffset; + property focusrectdist; + property extraspace; + property imagedist; + property imagedist1; + property imagedist2; + property font; + property localprops; //before template + property localprops1; //before template + property template; + property disabledbuttons; + property buttonface; + property buttonframe; + property buttonsvisible; + property buttonsinvisible; + property buttonsize; + property buttonpos; + property buttonslast; + property buttonsinline; + property mousewheel; + end; + + queryeventty = procedure(const sender: tobject; var answer: boolean) of object; + popupeventty = procedure(const sender: tobject; var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty) of object; + + tactionwidget = class(twidget) + private + fpopupmenu: tpopupmenu; + fonpopup: popupeventty; + fonshowhint: showhinteventty; + fonenter: notifyeventty; + fonexit: notifyeventty; + fonfocus: notifyeventty; + fondefocus: notifyeventty; + fonactivate: notifyeventty; + fondeactivate: notifyeventty; + + fonloaded: notifyeventty; + fonmouseevent: mouseeventty; + fonmousewheelevent: mousewheeleventty; + fonchildmouseevent: mouseeventty; + fonclientmouseevent: mouseeventty; + fonkeyup: keyeventty; + fonkeydown: keyeventty; + fonshortcut: shortcuteventty; + fonpaint: painteventty; + fonbeforepaint: painteventty; + fonafterpaint: painteventty; + fonmove: notifyeventty; + fonresize: notifyeventty; + fonhide: notifyeventty; + fonshow: notifyeventty; + fonclosequery: queryeventty; + fonevent: eventeventty; + fonasyncevent: asynceventeventty; + fonfocusedwidgetchanged: widgetchangeeventty; + fonpaintbackground: painteventty; + + foncomponentevent: componenteventeventty; + procedure setpopupmenu(const Value: tpopupmenu); + function getframe: tcaptionframe; + procedure setframe(const value: tcaptionframe); + function getface: tface; + procedure setface(const Value: tface); + protected + procedure mouseevent(var info: mouseeventinfoty); override; + procedure clientmouseevent(var info: mouseeventinfoty); override; + procedure childmouseevent(const sender: twidget; + var info: mouseeventinfoty); override; + procedure domousewheelevent(var info: mousewheeleventinfoty); override; + + procedure dobeforepaint(const canvas: tcanvas); override; + procedure doonpaintbackground(const canvas: tcanvas); override; + procedure doonpaint(const canvas: tcanvas); override; + procedure doafterpaint(const canvas: tcanvas); override; + + procedure showhint(const aid: int32; var info: hintinfoty); override; + procedure getpopuppos(var apos: pointty); virtual; + procedure updatepopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); virtual; + procedure dopopup(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); virtual; + procedure doafterpopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); virtual; + + procedure poschanged; override; + procedure sizechanged; override; + + procedure doloaded; override; + procedure doenter; override; + procedure doexit; override; + procedure dofocus; override; + procedure dodefocus; override; + procedure dofocuschanged(const oldwidget: twidget; + const newwidget: twidget); override; + procedure doactivate; override; + procedure dodeactivate; override; + procedure dohide; override; + procedure doshow; override; + + procedure doonkeydown(var info: keyeventinfoty); + procedure dokeydown(var info: keyeventinfoty); override; + procedure dokeyup(var info: keyeventinfoty); override; + procedure doshortcut(var info: keyeventinfoty; const sender: twidget); override; + procedure receiveevent(const event: tobjectevent); override; + procedure componentevent(const event: tcomponentevent) override; + procedure doasyncevent(var atag: integer); override; + + procedure internalcreateframe; override; + procedure enabledchanged; override; + + property frame: tcaptionframe read getframe write setframe; + property face: tface read getface write setface; + property popupmenu: tpopupmenu read fpopupmenu write setpopupmenu; + property onpopup: popupeventty read fonpopup write fonpopup; + property onshowhint: showhinteventty read fonshowhint write fonshowhint; + property onenter: notifyeventty read fonenter write fonenter; + property onexit: notifyeventty read fonexit write fonexit; + property onfocus: notifyeventty read fonfocus write fonfocus; + property ondefocus: notifyeventty read fondefocus write fondefocus; + property onactivate: notifyeventty read fonactivate write fonactivate; + property ondeactivate: notifyeventty read fondeactivate write fondeactivate; + + property onfocusedwidgetchanged: widgetchangeeventty + read fonfocusedwidgetchanged write fonfocusedwidgetchanged; + + property onmouseevent: mouseeventty read fonmouseevent write fonmouseevent; + property onchildmouseevent: mouseeventty read fonchildmouseevent + write fonchildmouseevent; + property onclientmouseevent: mouseeventty read fonclientmouseevent + write fonclientmouseevent; + property onmousewheelevent: mousewheeleventty read fonmousewheelevent + write fonmousewheelevent; + + property onkeydown: keyeventty read fonkeydown write fonkeydown; + property onkeyup: keyeventty read fonkeyup write fonkeyup; + property onshortcut: shortcuteventty read fonshortcut write fonshortcut; + + property onloaded: notifyeventty read fonloaded write fonloaded; + + property onbeforepaint: painteventty read fonbeforepaint + write fonbeforepaint; + property onpaintbackground: painteventty read fonpaintbackground + write fonpaintbackground; + property onpaint: painteventty read fonpaint write fonpaint; + property onafterpaint: painteventty read fonafterpaint write fonafterpaint; + + property onshow: notifyeventty read fonshow write fonshow; + property onhide: notifyeventty read fonhide write fonhide; + property onresize: notifyeventty read fonresize write fonresize; + property onmove: notifyeventty read fonmove write fonmove; + property onclosequery: queryeventty read fonclosequery write fonclosequery; + + property onevent: eventeventty read fonevent write fonevent; + property oncomponentevent: componenteventeventty read foncomponentevent + write foncomponentevent; + property onasyncevent: asynceventeventty read fonasyncevent write fonasyncevent; + public + function canclose(const newfocus: twidget = nil): boolean; override; + end; + + tactionpublishedwidgetnwr = class(tactionwidget) + published + property optionswidget1; //first! + property optionswidget; + property optionsskin; + property color; + property cursor; + property frame; + property face; + property taborder; + property hint; + property popupmenu; + property onpopup; + property onshowhint; + property onenter; + property onexit; + property onfocus; + property ondefocus; + property onactivate; + property ondeactivate; + property onbeforepaint; + property onpaintbackground; + property onpaint; + property onafterpaint; + end; + + tactionpublishedwidget = class(tactionpublishedwidgetnwr) + published + property bounds_x; + property bounds_y; + property bounds_cx; + property bounds_cy; + property bounds_cxmin; + property bounds_cymin; + property bounds_cxmax; + property bounds_cymax; + property anchors; + end; + + tpublishedwidgetnwr = class(tactionpublishedwidgetnwr) + published + property enabled; + property visible; + end; + + tpublishedwidget = class(tpublishedwidgetnwr) + published + property bounds_x; + property bounds_y; + property bounds_cx; + property bounds_cy; + property bounds_cxmin; + property bounds_cymin; + property bounds_cxmax; + property bounds_cymax; + property anchors; + end; + + tsimplewidget = class(tpublishedwidget) + public + constructor create(aowner: tcomponent); override; + published + property visible default false; + end; + + tcustomeventwidgetnwr = class(tpublishedwidgetnwr) + (* + private + fonloaded: notifyeventty; + fonmouseevent: mouseeventty; + fonmousewheelevent: mousewheeleventty; + fonchildmouseevent: mouseeventty; + fonclientmouseevent: mouseeventty; + fonkeyup: keyeventty; + fonkeydown: keyeventty; + fonshortcut: keyeventty; + fonpaint: painteventty; + fonbeforepaint: painteventty; + fonafterpaint: painteventty; + fonmove: notifyeventty; + fonresize: notifyeventty; + fonhide: notifyeventty; + fonshow: notifyeventty; + fonclosequery: queryeventty; + fonevent: eventeventty; + fonasyncevent: asynceventeventty; + fonfocusedwidgetchanged: focuschangeeventty; + fonpaintbackground: painteventty; + protected + procedure poschanged; override; + procedure sizechanged; override; + procedure dobeforepaint(const canvas: tcanvas); override; + procedure dopaintbackground(const canvas: tcanvas); override; + procedure doonpaint(const canvas: tcanvas); override; + procedure doafterpaint(const canvas: tcanvas); override; + procedure mouseevent(var info: mouseeventinfoty); override; + procedure clientmouseevent(var info: mouseeventinfoty); override; + procedure childmouseevent(const sender: twidget; var info: mouseeventinfoty); override; + procedure domousewheelevent(var info: mousewheeleventinfoty); override; + procedure dokeydown(var info: keyeventinfoty); override; + procedure dokeyup(var info: keyeventinfoty); override; + procedure doshortcut(var info: keyeventinfoty; const sender: twidget); override; + procedure dofocuschanged(const oldwidget,newwidget: twidget); override; + procedure doloaded; override; + procedure dohide; override; + procedure doshow; override; + procedure receiveevent(const event: tobjectevent); override; + procedure doasyncevent(var atag: integer); override; + public + function canclose(const newfocus: twidget): boolean; override; + property onfocusedwidgetchanged: focuschangeeventty + read fonfocusedwidgetchanged write fonfocusedwidgetchanged; + + property onmouseevent: mouseeventty read fonmouseevent write fonmouseevent; + property onchildmouseevent: mouseeventty read fonchildmouseevent + write fonchildmouseevent; + property onclientmouseevent: mouseeventty read fonclientmouseevent + write fonclientmouseevent; + property onmousewheelevent: mousewheeleventty read fonmousewheelevent + write fonmousewheelevent; + + property onkeydown: keyeventty read fonkeydown write fonkeydown; + property onkeyup: keyeventty read fonkeyup write fonkeyup; + property onshortcut: keyeventty read fonshortcut write fonshortcut; + + property onloaded: notifyeventty read fonloaded write fonloaded; + + property onbeforepaint: painteventty read fonbeforepaint write fonbeforepaint; + property onpaintbackground: painteventty read fonpaintbackground write fonpaintbackground; + property onpaint: painteventty read fonpaint write fonpaint; + property onafterpaint: painteventty read fonafterpaint write fonafterpaint; + + property onshow: notifyeventty read fonshow write fonshow; + property onhide: notifyeventty read fonhide write fonhide; +// property onactivate: notifyeventty read fonactivate write fonactivate; +// property ondeactivate: notifyeventty read fondeactivate write fondeactivate; + property onresize: notifyeventty read fonresize write fonresize; + property onmove: notifyeventty read fonmove write fonmove; + property onclosequery: queryeventty read fonclosequery write fonclosequery; + + property onevent: eventeventty read fonevent write fonevent; + property onasyncevent: asynceventeventty read fonasyncevent write fonasyncevent; +*) + end; + + tcustomeventwidget = class(tcustomeventwidgetnwr) + published + property bounds_x; + property bounds_y; + property bounds_cx; + property bounds_cy; + property bounds_cxmin; + property bounds_cymin; + property bounds_cxmax; + property bounds_cymax; + property anchors; + end; + + const + defaultoptionstoplevelwidget = defaultoptionswidget + [ow_subfocus]; + +type + + ttoplevelwidget = class(tcustomeventwidget) + public + constructor create(aowner: tcomponent); override; + property visible default false; + published + property optionswidget default defaultoptionstoplevelwidget; + property optionsskin default defaultcontainerskinoptions; + end; + + tcaptionwidget = class(ttoplevelwidget) + private + fcaption: msestring; + protected + function getcaption: msestring; virtual; + procedure setcaption(const Value: msestring); virtual; + procedure windowcreated; override; + //iassistiveclient + function getassistivecaption(): msestring; override; + public + property caption: msestring read getcaption write setcaption; + end; + + tscrollbarwidget = class(tcustomeventwidget,iscrollbar) + private + function getframe: tscrollframe; + procedure setframe(const Value: tscrollframe); + protected + procedure internalcreateframe; override; + procedure mouseevent(var info: mouseeventinfoty); override; + procedure scrollevent(sender: tcustomscrollbar; event: scrolleventty); virtual; + public + constructor create(aowner: tcomponent); override; + published + property frame: tscrollframe read getframe write setframe; + end; + + iautoscrollframe = interface(inullinterface) + function getscrollrect: rectty; + procedure setscrollrect(const rect: rectty); + procedure scrollevent(sender: tcustomscrollbar; event: scrolleventty); + end; + + tcustomautoscrollframe = class(tcustomscrollboxframe) + private + function getscrollpos: pointty; + procedure setscrollpos(const avalue: pointty); + function getscrollpos_x: integer; + procedure setscrollpos_x(const avalue: integer); + function getscrollpos_y: integer; + procedure setscrollpos_y(const avalue: integer); + protected + fintf1: iautoscrollframe; + procedure scrollevent(sender: tcustomscrollbar; event: scrolleventty); override; + procedure updaterects; override; + public + constructor create(const aintf: iscrollframe; const owner: twidget; + const autoscrollintf: iautoscrollframe); + procedure updateclientrect; override; + property scrollpos: pointty read getscrollpos write setscrollpos; + property scrollpos_x: integer read getscrollpos_x write setscrollpos_x; + property scrollpos_y: integer read getscrollpos_y write setscrollpos_y; + //origin = paintpos + end; + + fontheightdeltaeventty = procedure (const sender: tobject; + var delta: integer) of object; + + tscrollface = class(tface) + procedure internalpaint(const canvas: tcanvas; const rect: rectty); override; + public + end; + + tscrollingwidgetnwr = class; + calcminscrollsizeeventty = procedure(const sender: tscrollingwidgetnwr; + var asize: sizety) of object; + + tscrollingwidgetnwr = class(tcustomeventwidgetnwr) + private + fonscroll: pointeventty; + fonfontheightdelta: fontheightdeltaeventty; + fonlayout: notifyeventty; + foncalcminscrollsize: calcminscrollsizeeventty; + fminclientsize: sizety; + fonscrolled: pointeventty; + function getframe: tscrollboxframe; + procedure setframe(const Value: tscrollboxframe); +// procedure setclientpos(const avalue: pointty); + procedure readonchildscaled(reader: treader); + protected + fminminclientsize: sizety; //exteded in design mode + procedure widgetregionchanged(const sender: twidget); override; + procedure sizechanged; override; + procedure minscrollsizechanged; + procedure dofontheightdelta(var delta: integer); override; + procedure internalcreateframe; override; + procedure doscroll(const dist: pointty); override; + procedure doscrolled(const dist: pointty); override; + procedure mouseevent(var info: mouseeventinfoty); override; + procedure childmouseevent(const sender: twidget; + var info: mouseeventinfoty); override; + procedure domousewheelevent(var info: mousewheeleventinfoty); override; + procedure internalcreateface; override; + function calcminscrollsize: sizety; override; + procedure setclientsize(const asize: sizety); override; + procedure loaded; override; + //origin paintpos + procedure defineproperties(filer: tfiler); override; + public + constructor create(aowner: tcomponent); override; + procedure clampinview(const arect: rectty; + const bottomright: boolean = false); override; + function maxclientsize: sizety; override; + procedure writestate(writer: twriter); override; + procedure dolayout(const sender: twidget); override; + property onscroll: pointeventty read fonscroll write fonscroll; + property onscrolled: pointeventty read fonscrolled write fonscrolled; + property onfontheightdelta: fontheightdeltaeventty read fonfontheightdelta + write fonfontheightdelta; + property onlayout: notifyeventty read fonlayout write fonlayout; + property oncalcminscrollsize: calcminscrollsizeeventty + read foncalcminscrollsize write foncalcminscrollsize; +// property scrollpos: pointty read getclientpos write setclientpos; + published + property frame: tscrollboxframe read getframe write setframe; + property optionswidget default defaultoptionswidgetmousewheel; + property optionsskin default defaultcontainerskinoptions; + end; + + tscrollingwidget = class(tscrollingwidgetnwr) + published + property bounds_x; + property bounds_y; + property bounds_cx; + property bounds_cy; + property bounds_cxmin; + property bounds_cymin; + property bounds_cxmax; + property bounds_cymax; + property anchors; + end; + + tpopupwidget = class(ttoplevelwidget) + private + ftransientfor: twindow; + protected + function getassistiveflags(): assistiveflagsty override; + procedure updatewindowinfo(var info: windowinfoty); override; + function internalshow(const modallevel: modallevelty; + const transientfor: pwindow; + const windowevent,transientforshow: boolean): modalresultty; override; + public + constructor create(aowner: tcomponent; + transientfor: twindow); reintroduce; overload; + property transientfor: twindow read ftransientfor; + end; + + const + defaultoptionshintwidget = defaultoptionstoplevelwidget + [ow_top]; + +type + tcustomhintwidget = class(tpopupwidget) + public + constructor create(const aowner: tcomponent; const atransientfor: twindow; + var info: hintinfoty; const sender: tobject); virtual; reintroduce; + published + property optionswidget default defaultoptionshintwidget; + end; + hintwidgetclassty = class of tcustomhintwidget; + + thintwidget = class(tcustomhintwidget) + private + fcaption: captionty; + protected + procedure dopaintforeground(const canvas: tcanvas); override; + public + constructor create(const aowner: tcomponent; const atransientfor: twindow; + var info: hintinfoty; const sender: tobject); override; + end; + + tmessagewidget = class(tcaptionwidget) + private + fpopuptransient: boolean; + fhasaction: boolean; + protected + procedure updatewindowinfo(var info: windowinfoty); override; + procedure dokeydown(var info: keyeventinfoty); override; + function getcaption: msestring; override; + procedure setcaption(const Value: msestring); override; + procedure internalcreateframe; override; + public + constructor create(const aowner: tcomponent; const apopuptransient: boolean; + const ahasaction: boolean); + reintroduce; + function canclose(const newfocus: twidget): boolean; override; + end; + +type + tactionsimplebutton = class(tactionpublishedwidget) + private + procedure setcolorglyph(const value: colorty); + protected + foptions: buttonoptionsty; + finfo: shapeinfoty; + class function classskininfo: skininfoty; override; + procedure setoptions(const avalue: buttonoptionsty); virtual; + procedure internalexecute(); + procedure doshapeexecute(const atag: integer; const info: mouseeventinfoty); + procedure doexecute; virtual; + procedure doasyncevent(var atag: integer); override; + procedure statechanged; override; + procedure clientmouseevent(var info: mouseeventinfoty); override; + procedure dokeydown(var info: keyeventinfoty); override; + procedure dokeyup(var info: keyeventinfoty); override; + procedure dopaintforeground(const canvas: tcanvas); override; + procedure clientrectchanged; override; + function getframestateflags: framestateflagsty; override; + function navigstartrect: rectty; override; + function getassistiveflags(): assistiveflagsty override; + function getdisabled(): boolean virtual; + public + constructor create(aowner: tcomponent); override; + procedure execute; + procedure pressbutton; + function releasebutton(const aexecute: boolean): boolean; + //true if clicked + property options: buttonoptionsty read foptions write setoptions + default defaultbuttonoptions; + property colorglyph: colorty read finfo.ca.colorglyph write setcolorglyph + default cl_black; + property focusrectdist: integer read finfo.focusrectdist + write finfo.focusrectdist default defaultshapefocusrectdist; + published + property optionswidget default defaultoptionswidget - [ow_mousefocus]; + end; + + tsimplebutton = class(tactionsimplebutton) +// published +// property enabled; +// property visible; + end; + +type + messagepositionty = (mepo_default,mepo_screencentered,mepo_windowcentered); + +function readcaptiontoimagepos(const reader: treader): imageposty; + +procedure synccaptiondistx(const awidgets: array of twidget); + //adjusts captiondist for equal distouter + //don't set cfo_captiondistouter! +procedure synccaptiondisty(const awidgets: array of twidget); + //adjusts captiondist for equal distouter + //don't set cfo_captiondistouter! + +function getmaxdropdownheight(const parent: twidget): integer; +procedure getdropdownpos(const parent: twidget; const right: boolean; + var rect: rectty); + + +//following routines are thread safe and run in main thread context +//exttext will be appended for copy to clipboard +function showmessage(const atext,caption: msestring; + const buttons: array of modalresultty; + const defaultbutton: modalresultty = mr_cancel; + const noshortcut: modalresultsty = []; + const minwidth: integer = 0; + const exttext: msestring = ''; + const position: messagepositionty = mepo_default): modalresultty; overload; +function showmessage(const atext,caption: msestring; + const buttons: array of modalresultty; + const defaultbutton: modalresultty; + const noshortcut: modalresultsty; + const minwidth: integer; + const actions: array of notifyeventty; + const exttext: msestring = ''; + const position: messagepositionty = mepo_default): modalresultty; overload; +function showmessage(const atext,caption: msestring; + const buttons: array of modalresultty; + const adest: rectty; const awidget: twidget = nil; + //origin = awidget.clientpos, screen if awidget = nil + const placement: captionposty = cp_bottomleft; + const defaultbutton: modalresultty = mr_cancel; + const noshortcut: modalresultsty = []; + const minwidth: integer = 0; + const exttext: msestring = ''): modalresultty; overload; +function showmessage(const atext: msestring; const caption: msestring = ''; + const minwidth: integer = 0; + const exttext: msestring = ''): modalresultty; overload; +procedure showmessage1(const atext: msestring; const caption: msestring); + //for ps +procedure showerror(const atext: msestring; caption: msestring = 'ERROR'; + const minwidth: integer = 0; + const exttext: msestring = ''; + const async: boolean = false); + //no wait if not in main thread or asnyc = true +function askok(const atext: msestring; const caption: msestring = ''; + const defaultbutton: modalresultty = mr_ok; + const minwidth: integer = 0): boolean; + //true if ok pressed +function askyesno(const atext: msestring; const caption: msestring = ''; + const defaultbutton: modalresultty = mr_yes; + const minwidth: integer = 0): boolean; + //true if yes pressed +function askconfirmation(const atext: msestring; + const defaultbutton: modalresultty = mr_yes; + const minwidth: integer = 0): boolean; + //true if yes pressed +function askconfirmationcancel(const atext: msestring; + const defaultbutton: modalresultty = mr_yes; + const minwidth: integer = 0): modalresultty; +function askyesnocancel(const atext: msestring; const caption: msestring = ''; + const defaultbutton: modalresultty = mr_yes; + const minwidth: integer = 0): modalresultty; +function confirmsavechangedfile(const filename: filenamety; + out modalresult: modalresultty; multiple: boolean = false): boolean; +function showsyserrormessage(const error: syserrorty; + const text: msestring = ''): boolean; + //returns true for sye_ok +function showsyserrormessage(const error: syserrorty; + const sender: tobject; const text: msestring = ''): boolean; + //returns true for sye_ok + +//end threadsave routines + +procedure copytoclipboard(const value: msestring; + const buffer: clipboardbufferty = cbb_clipboard); +function canpastefromclipboard( + const buffer: clipboardbufferty = cbb_clipboard): boolean; +function pastefromclipboard(out value: msestring; + const buffer: clipboardbufferty = cbb_clipboard): boolean; + //false if empty +function placepopuprect(const awindow: twindow; const adest: rectty; //screenorig + const placement: captionposty; const asize: sizety): rectty; + //placement currently only cp_bottomleft and cp_center + //todo +function placepopuprect(const awidget: twidget; + const adest: rectty; //widgetorig + const placement: captionposty; const asize: sizety): rectty; +function placeclientpopuprect(const awidget: twidget; + const adest: rectty; //clientorig + const placement: captionposty; const asize: sizety): rectty; +procedure getwindowicon(const abitmap: tmaskedbitmap; out aicon,amask: pixmapty; + const anodefault: boolean = false); + +procedure buttonoptionstoshapestate(avalue: buttonoptionsty; + var astate: shapestatesty); + +implementation +uses + msebits,mseguiintf,msestockobjects,msekeyboard,sysutils,msemenuwidgets, + mseactions,msepointer,msestreaming,msesys,msearrayutils,mseassistiveserver; +{$ifndef mse_allwarnings} + {$if fpc_fullversion >= 030100} + {$warn 5089 off} + {$warn 5090 off} + {$warn 5093 off} + {$warn 6058 off} + {$endif} +{$endif} + +const + captionmargin = 1; //distance focusrect to caption in tcaptionframe + +type + twidget1 = class(twidget); + twindow1 = class(twindow); + tcustomscrollbar1 = class(tcustomscrollbar); + tbitmap1 = class(tbitmap); + tcustomframe1 = class(tcustomframe); + + tmessagebutton = class(tsimplebutton) + private + fcaption: msestring; + procedure setcaption(const avalue: msestring); + protected + modalresult: modalresultty; + procedure doexecute; override; + procedure doshortcut(var info: keyeventinfoty; + const sender: twidget); override; + function getassistivecaption(): msestring override; + public + onexecute: notifyeventty; + property caption: msestring read fcaption write setcaption; + end; + + showmessageinfoty = record + atext,caption: msestring; + buttons: array of modalresultty; + defaultbutton: modalresultty; + noshortcut: modalresultsty; + placementrect: prectty; placement: captionposty; + minwidth: integer; actions: array of notifyeventty; + exttext: msestring; + async: boolean; + result: modalresultty; + end; + pshowmessageinfoty = ^showmessageinfoty; + + tshowmessagewidget = class(tmessagewidget) + protected + info: drawtextinfoty; + fexttext: msestring; + finfo: pshowmessageinfoty; + procedure dopaintforeground(const canvas: tcanvas); override; + procedure dokeydown(var ainfo: keyeventinfoty); override; + procedure doidle(var again: boolean); + //iassistiveclient + function getassistivetext(): msestring override; + function getassistiveflags(): assistiveflagsty override; + public + constructor create(const aowner: tcomponent; const apopuptransient: boolean; + const ahasaction: boolean; const exttext: msestring; + const ainfo: pshowmessageinfoty); + destructor destroy(); override; + end; + +procedure buttonoptionstoshapestate(avalue: buttonoptionsty; + var astate: shapestatesty); +begin + if bo_ellipsemouse in avalue then begin + include(astate,shs_ellipsemouse); + end + else begin + exclude(astate,shs_ellipsemouse); + end; + if bo_coloractive in avalue then begin + include(astate,shs_focuscolor); + end + else begin + exclude(astate,shs_focuscolor); + end; +end; + +function readcaptiontoimagepos(const reader: treader): imageposty; +begin + result:= captiontoimagepos[captionposty( + readenum(reader,typeinfo(captionposty)))]; +end; + +procedure synccaptiondistx(const awidgets: array of twidget); + //adjusts captiondist for equal distouter to paintrect + //don't set cfo_captiondistouter +var + int1,int2,int3,int4: integer; +begin + int2:= bigint; + int3:= 0; + for int1:= 0 to high(awidgets) do begin + with twidget1(awidgets[int1]) do begin + if (fframe <> nil) and + (fs_cancaptionsyncx in tcustomframe1(fframe).fstate) then begin + with tcustomcaptionframe(fframe) do begin + checkstate(); + if fcaptiondist < int2 then begin + int2:= fcaptiondist; + end; + int4:= finfo.dest.cx; + if fcaptionpos in rightcaptionpos then begin + int4:= int4 + fwidth.right; + end + else begin + int4:= int4 + fwidth.left; + end; + if int4 > int3 then begin + int3:= int4; + end; + end; + end; + end; + end; + int3:= int3 + int2; //max outer dist + for int1:= 0 to high(awidgets) do begin + with twidget1(awidgets[int1]) do begin + if (fframe <> nil) and + (fs_cancaptionsyncx in tcustomframe1(fframe).fstate) then begin + with tcustomcaptionframe(fframe) do begin + if fcaptionpos in rightcaptionpos then begin + captiondist:= int3 - finfo.dest.cx - fwidth.right; + end + else begin + captiondist:= int3 - finfo.dest.cx - fwidth.left; + end; + end; + end; + end; + end; +end; + +procedure synccaptiondisty(const awidgets: array of twidget); + //adjusts captiondist for equal distouter + //don't set cfo_captiondistouter +var + int1,int2,int3,int4: integer; +begin + int2:= bigint; + int3:= 0; + for int1:= 0 to high(awidgets) do begin + with twidget1(awidgets[int1]) do begin + if (fframe <> nil) and + (fs_cancaptionsyncy in tcustomframe1(fframe).fstate) then begin + with tcustomcaptionframe(fframe) do begin + checkstate(); + if fcaptiondist < int2 then begin + int2:= fcaptiondist; + end; + int4:= finfo.dest.cy; + if fcaptionpos in bottomcaptionpos then begin + int4:= int4 + fwidth.bottom; + end + else begin + int4:= int4 + fwidth.top; + end; + if int4 > int3 then begin + int3:= int4; + end; + end; + end; + end; + end; + int3:= int3 + int2; //max outer dist + for int1:= 0 to high(awidgets) do begin + with twidget1(awidgets[int1]) do begin + if (fframe <> nil) and + (fs_cancaptionsyncy in tcustomframe1(fframe).fstate) then begin + with tcustomcaptionframe(fframe) do begin + if fcaptionpos in bottomcaptionpos then begin + captiondist:= int3 - finfo.dest.cy - fwidth.bottom; + end + else begin + captiondist:= int3 - finfo.dest.cy - fwidth.top; + end; + end; + end; + end; + end; +end; + +procedure copytoclipboard(const value: msestring; + const buffer: clipboardbufferty = cbb_clipboard); +begin + gui_copytoclipboard(value,buffer); +end; + +function canpastefromclipboard( + const buffer: clipboardbufferty = cbb_clipboard): boolean; +begin + result:= gui_canpastefromclipboard(buffer); +end; + +function pastefromclipboard(out value: msestring; + const buffer: clipboardbufferty = cbb_clipboard): boolean; +begin + result:= gui_pastefromclipboard(value,buffer) = gue_ok; +end; + +function confirmsavechangedfile(const filename: filenamety; + out modalresult: modalresultty; multiple: boolean = false): boolean; +begin + with stockobjects do begin + if multiple then begin + modalresult:= showmessage(captions[sc_file]+' '+filename+' '+ + captions[sc_is_modified_save],captions[sc_confirmation], + [mr_yes,mr_all,mr_no,mr_noall,mr_cancel],mr_yes); + end + else begin + modalresult:= showmessage(captions[sc_file]+' '+filename+' '+ + captions[sc_is_modified_save],captions[sc_confirmation], + [mr_yes,mr_no,mr_cancel],mr_yes); + end; + end; +{ + if multiple then begin + modalresult:= showmessage('File '+filename+' is modified. Save?','Confirmation', + [mr_yes,mr_all,mr_no,mr_noall,mr_cancel],mr_yes); + end + else begin + modalresult:= showmessage('File '+filename+' is modified. Save?','Confirmation', + [mr_yes,mr_no,mr_cancel],mr_yes); + end; +} + if modalresult = mr_windowclosed then begin + modalresult:= mr_cancel; + end; + result:= modalresult in [mr_yes,mr_all]; +end; + +function showsyserrormessage(const error: syserrorty; + const text: msestring = ''): boolean; + //returns true for sye_ok +begin + result:= error = sye_ok; + if not result then begin + showerror(buildsyserrormessage(error,text)); + end; +end; + +function showsyserrormessage(const error: syserrorty; + const sender: tobject; const text: msestring = ''): boolean; + //returns true for sye_ok +begin + result:= error = sye_ok; + if not result then begin + showerror(buildsyserrormessage(error,sender,text)); + end; +end; + +function getmaxdropdownheight(const parent: twidget): integer; +var + rect1: rectty; + int1: integer; +begin + rect1:= application.workarea(parent.window); + int1:= translatewidgetpoint(parent.framerect.pos,parent,nil).y; + result:= int1 - rect1.y; + int1:= rect1.y + rect1.cy - (int1 + parent.framerect.cy); + if int1 > result then begin + result:= int1; + end; +end; + +procedure getdropdownpos(const parent: twidget; const right: boolean; + var rect: rectty); +var + int1,int2: integer; + size1: sizety; + workarea: rectty; +begin + size1:= parent.framesize; + rect.pos:= translatewidgetpoint(parent.framerect.pos,parent,nil); + if right then begin + rect.x:= rect.x + size1.cx - rect.cx; + end; + workarea:= application.workarea(parent.window); + inc(rect.y,size1.cy); + int1:= (workarea.y + workarea.cy); + int2:= rect.y + rect.cy; + if (int2 > int1) and (rect.y - rect.cy - workarea.y > int1 - int2) then begin + dec(rect.y,size1.cy); + int1:= rect.y - workarea.y; + if rect.cy > int1 then begin + rect.cy:= int1; + end; + dec(rect.y,rect.cy); //shift above + end + else begin + int1:= workarea.y + workarea.cy - rect.y; + if rect.cy > int1 then begin + rect.cy:= int1; + end; + end; + int1:= (workarea.x + workarea.cx) - (rect.x + rect.cx); + if int1 < 0 then begin + inc(rect.x,int1); + end; + if rect.x < workarea.x then begin + rect.x:= workarea.x; + end; +end; + +function placepopuprect(const awindow: twindow; const adest: rectty; + const placement: captionposty; const asize: sizety): rectty; + //placement currently cp_bottomleft and cp_center only, + //todo + +var + int1: integer; + rect1: rectty; +begin + result.size:= asize; + with adest do begin + if placement = cp_bottomleft then begin + result.x:= x; + result.y:= y + cy; + end + else begin + result.x:= x + (cx - asize.cx) div 2; + result.y:= y + (cy - asize.cy) div 2; + end; + rect1:= application.workarea(awindow); + with result do begin //shift in workarea + int1:= (rect1.x + rect1.cx) - (x + cx); + if int1 < 0 then begin + inc(x,int1); + end; + if x < rect1.x then begin + x:= rect1.x; + end; + if y + cy > rect1.y + rect1.cy then begin + if placement = cp_bottomleft then begin + y:= adest.y - asize.cy; //above destrect + end + else begin + y:= rect1.y + rect1.cy - asize.cy; + end; + if y < rect1.y then begin + y:= rect1.y; + end; + end; + end; + end; +end; + +function placepopuprect(const awidget: twidget; const adest: rectty; //widgetorig + const placement: captionposty; const asize: sizety): rectty; +begin + result:= placepopuprect(awidget.window,moverect(adest, + translatewidgetpoint(nullpoint,awidget,nil)),placement,asize); +end; + +function placeclientpopuprect(const awidget: twidget; + const adest: rectty; //clientorig + const placement: captionposty; const asize: sizety): rectty; +begin + result:= placepopuprect(awidget.window,moverect(adest, + translateclientpoint(nullpoint,awidget,nil)),placement,asize); +end; + +procedure getwindowicon(const abitmap: tmaskedbitmap; out aicon,amask: pixmapty; + const anodefault: boolean = false); +var + bmp: tmaskedbitmap; +begin + aicon:= 0; + amask:= 0; + if abitmap <> nil then begin + if abitmap.source <> nil then begin + bmp:= abitmap.source.bitmap; + end + else begin + bmp:= abitmap; + end; + if not bmp.isempty then begin + if bmp.masked then begin + amask:= bmp.mask.handle; //first because it possibly destroys bmp.handle + end; + aicon:= bmp.handle; + end; + end; + if (aicon = 0) and not anodefault then begin + getwindowicon(stockobjects.mseicon,aicon,amask); + end; +end; + +function messagerect(const position: messagepositionty; + out arect: rectty): prectty; +var + window1: twindow; +begin + application.lockifnotmainthread; + try + result:= nil; + if position <> mepo_screencentered then begin + window1:= application.unreleasedactivewindow; + if (window1 <> nil) and + ((position = mepo_windowcentered) or + (wo_windowcentermessage in window1.options)) then begin + arect:= window1.owner.widgetrect; + result:= @arect; + end + else begin + result:= nil; + end; + end; + finally + application.unlockifnotmainthread; + end; +end; + + +procedure syncshowmessage(const adata: pointer); +const + maxtextwidth = 500; + verttextdist = 10; + horztextdist = 10; + buttondist = 10; +var + buttonheight: integer; + buttonwidth: integer; + widget: tshowmessagewidget; + widget1: twidget; //dummy parent to get invisible canvas + but: array[0..integer(high(modalresultty))] of tmessagebutton; + int1,int2: integer; + rect1{,rect2}: rectty; + acanvas: tcanvas; + textoffset: integer; + transientfor: twindow; + +begin + with pshowmessageinfoty(adata)^ do begin + application.lockifnotmainthread; + try + transientfor:= application.unreleasedactivewindow; + widget1:= twidget.create(nil); + widget1.visible:= false; + //stays invisible, no wm_configured processing on win32 + widget:= tshowmessagewidget.create(nil,(transientfor <> nil) and + (transientfor.ispopup) and transientfor.owner.visible, + high(actions) >= 0,exttext,pshowmessageinfoty(adata)); + widget.name:= '_showmessage'; //debug purpose + widget.parentwidget:= widget1; //do not create window handle of widget + try + acanvas:= widget1.getcanvas; + buttonheight:= acanvas.font.glyphheight + 6; + buttonwidth:= 50; + for int1:= 0 to ord(high(buttons)) do begin + int2:= acanvas.getstringwidth( + stockobjects.modalresulttextnoshortcut[buttons[int1]]) + 10; + if int2 > buttonwidth then begin + buttonwidth:= int2; + end; + end; + widget.caption:= caption; + acanvas.font:= stockobjects.fonts[stf_message]; + rect1:= textrect(acanvas,atext); + if rect1.cx > maxtextwidth then begin + rect1.cx:= maxtextwidth; + rect1.cy:= bigint; + rect1:= textrect(acanvas,atext,rect1,[tf_wordbreak]); + widget.info.flags:= [tf_wordbreak]; + end; + rect1.x:= horztextdist; + rect1.y:= verttextdist; + textoffset:= minwidth - rect1.cx; + if textoffset > 0 then begin + rect1.cx:= minwidth; + end + else begin + textoffset:= 0; + end; + with widget.info do begin + dest:= rect1; + text.text:= atext; + end; + int1:= length(buttons); + if int1 > 0 then begin + int2:= int1 * buttonwidth; + int2:= int2 + buttondist * (int1 - 1); + inc(rect1.cy,buttonheight+verttextdist); + end + else begin + int2:= 0; + end; + if int2 > rect1.cx then begin + rect1.cx:= int2; //width of buttons greater then text width + widget.info.dest.cx:= int2; + end; + + inc(rect1.cx,2*horztextdist); + inc(rect1.cy,2*verttextdist); + + widget.parentwidget:= nil; //remove dummy parent + widget.clientsize:= rect1.size; + if placementrect = nil then begin + widget.window.windowpos:= wp_screencentered; + end + else begin +// rect2:= placementrect^; + { + if placement = cp_bottomleft then begin + dec(rect2.y,8); + inc(rect2.cy,28); //for windowdecoration + end; + } + widget.widgetrect:= placepopuprect(transientfor, + placementrect^,placement,widget.size); + end; + + with widget.info.dest do begin + rect1.x:= x + (cx - int2) div 2; + rect1.y:= y + cy + verttextdist + widget.paintpos.y; + rect1.cx:= buttonwidth; + rect1.cy:= buttonheight; + end; + for int1:= 0 to high(buttons) do begin + but[int1]:= tmessagebutton.create(widget); + with but[int1] do begin + widgetrect:= rect1; + parentwidget:= widget; + if buttons[int1] in noshortcut then begin + caption:= + stockobjects.modalresulttextnoshortcut[buttons[int1]]; +{ + captiontorichstring( + stockobjects.modalresulttextnoshortcut[buttons[int1]], + finfo.ca.caption); +} + end + else begin + caption:= stockobjects.modalresulttext[buttons[int1]]; +{ + captiontorichstring(stockobjects.modalresulttext[buttons[int1]], + finfo.ca.caption); +} + end; + if int1 <= high(actions) then begin + onexecute:= actions[int1]; + end; + modalresult:= buttons[int1]; + end; + if buttons[int1] = defaultbutton then begin + widget.defaultfocuschild:= but[int1]; + end; + inc(rect1.x,buttonwidth + buttondist); + end; + inc(widget.info.dest.x,textoffset div 2); + dec(widget.info.dest.cx,textoffset); + widget.updateskin(true); + { + if placementrect <> nil then begin + widget.visible:= true; + application.processmessages(); //decorate window + widget.window.decoratedwidgetrect:= placepopuprect(transientfor, + placementrect^,placement,widget.window.decoratedsize); + end; + } + result:= widget.show(true,transientfor); + finally + widget1.free; + widget.Free; + end; + finally + application.unlockifnotmainthread; + end; + end; +end; + +function internalshowmessage(const atext_,caption_: msestring; + buttons_: array of modalresultty; + defaultbutton_: modalresultty; + noshortcut_: modalresultsty; + placementrect_: prectty; placement_: captionposty; + minwidth_: integer; actions_: array of notifyeventty; + const exttext_: msestring; + const async_: boolean = false): modalresultty; +var + info: showmessageinfoty; +begin + with info do begin + atext:= atext_; + caption:= caption_; + setlength(buttons,length(buttons_)); + move(buttons_[0],buttons[0],length(buttons)*sizeof(buttons[0])); + defaultbutton:= defaultbutton_; + noshortcut:= noshortcut_; + placementrect:= placementrect_; + placement:= placement_; + minwidth:= minwidth_; + setlength(actions,length(actions_)); + move(actions_[0],actions[0],length(actions)* + sizeof({$ifndef FPC}@{$endif}actions[0])); + exttext:= exttext_; + async:= async_; + end; + if application.ismainthread then begin + syncshowmessage(@info); + end + else begin + application.synchronize(@syncshowmessage,@info); + end; + result:= info.result; +end; + +function showmessage(const atext,caption: msestring; + const buttons: array of modalresultty; + const defaultbutton: modalresultty = mr_cancel; + const noshortcut: modalresultsty = []; + const minwidth: integer = 0; + const exttext: msestring = ''; + const position: messagepositionty = mepo_default): modalresultty; +var + rect1: rectty; +begin + result:= internalshowmessage(atext,caption,buttons,defaultbutton, + noshortcut,messagerect(position,rect1),cp_center,minwidth,[],exttext); +end; + +function showmessage(const atext,caption: msestring; + const buttons: array of modalresultty; + const defaultbutton: modalresultty; + const noshortcut: modalresultsty; + const minwidth: integer; + const actions: array of notifyeventty; + const exttext: msestring = ''; + const position: messagepositionty = mepo_default): modalresultty; +var + rect1: rectty; +begin + result:= internalshowmessage(atext,caption,buttons,defaultbutton, + noshortcut,messagerect(position,rect1),cp_center, + minwidth,actions,exttext); +end; + +function showmessage(const atext,caption: msestring; + const buttons: array of modalresultty; + const adest: rectty; const awidget: twidget = nil; + //origin = awidget.clientpos, screen if awidget = nil + const placement: captionposty = cp_bottomleft; + const defaultbutton: modalresultty = mr_cancel; + const noshortcut: modalresultsty = []; + const minwidth: integer = 0; + const exttext: msestring = ''): modalresultty; overload; +var + rect1: rectty; +begin + if awidget = nil then begin + rect1.pos:= adest.pos; + end + else begin + application.lockifnotmainthread; + try + rect1.pos:= translateclientpoint(adest.pos,awidget,nil); + finally + application.unlockifnotmainthread; + end; + end; + rect1.size:= adest.size; + result:= internalshowmessage(atext,caption,buttons,defaultbutton,noshortcut, + @rect1,placement,minwidth,[],exttext); +end; + +function showmessage(const atext: msestring; const caption: msestring = ''; + const minwidth: integer = 0; + const exttext: msestring = ''): modalresultty; +begin + result:= showmessage(atext,caption,[mr_ok],mr_ok,[],minwidth,exttext); +end; + +procedure showmessage1(const atext: msestring; const caption: msestring); + //for ps +begin + showmessage(atext,caption); +end; + +type + tshowerrormessageevent = class(texecuteevent) + private + ftext: msestring; + fcaption: msestring; + fminwidth: integer; + fexttext: msestring; + protected + procedure execute; override; + public + constructor create(const text: msestring; const caption: msestring; + const minwidth: integer; const exttext: msestring); + end; + +{ tshowerrormessageevent } + +constructor tshowerrormessageevent.create(const text: msestring; + const caption: msestring; const minwidth: integer; + const exttext: msestring); +begin + ftext:= text; + fcaption:= caption; + fminwidth:= minwidth; + fexttext:= exttext; + inherited create; + application.postevent(self); +end; + +procedure tshowerrormessageevent.execute; +var + rect1: rectty; +begin + internalshowmessage(ftext,fcaption,[mr_ok],mr_ok, + [],messagerect(mepo_default,rect1),cp_center,0,[],fexttext,true); +// showmessage(ftext,fcaption,fminwidth,fexttext); +end; + +procedure showerror(const atext: msestring; caption: msestring = 'ERROR'; + const minwidth: integer = 0; + const exttext: msestring = ''; + const async: boolean = false); +begin + if caption = 'ERROR' then begin + caption:= sc(sc_errorupper); + end; + if async or not application.ismainthread then begin + tshowerrormessageevent.create(atext,caption,minwidth,exttext); + end + else begin + showmessage(atext,caption,minwidth,exttext); + end; +end; + +function askok(const atext: msestring; const caption: msestring = ''; + const defaultbutton: modalresultty = mr_ok; + const minwidth: integer = 0): boolean; + //true if ok pressed +begin + result:= showmessage(atext,caption,[mr_ok,mr_cancel],defaultbutton,[], + minwidth) = mr_ok; +end; + +function askyesno(const atext: msestring; const caption: msestring = ''; + const defaultbutton: modalresultty = mr_yes; + const minwidth: integer = 0): boolean; + //true if yes pressed +begin + result:= showmessage(atext,caption,[mr_yes,mr_no],defaultbutton,[], + minwidth) = mr_yes; +end; + +function askyesnocancel(const atext: msestring; const caption: msestring = ''; + const defaultbutton: modalresultty = mr_yes; + const minwidth: integer = 0 ): modalresultty; +begin + result:= showmessage(atext,caption,[mr_yes,mr_no,mr_cancel],defaultbutton,[], + minwidth); + if not (result in [mr_yes,mr_no]) then begin + result:= mr_cancel; + end; +end; + +function askconfirmation(const atext: msestring; + const defaultbutton: modalresultty = mr_yes; + const minwidth: integer = 0): boolean; + //true if yes pressed +begin + result:= showmessage(atext,sc(sc_confirmation),[mr_yes,mr_no],defaultbutton,[], + minwidth) = mr_yes; +end; + +function askconfirmationcancel(const atext: msestring; + const defaultbutton: modalresultty = mr_yes; + const minwidth: integer = 0): modalresultty; +begin + result:= askyesnocancel(atext,sc(sc_confirmation),defaultbutton,minwidth); +end; + +{ tframefont} + +class function tframefont.getinstancepo(owner: tobject): pfont; +begin + result:= @tcustomcaptionframe(owner).ffont; +end; + +{ tactionsimplebutton} + +constructor tactionsimplebutton.create(aowner: tcomponent); +begin + foptions:= defaultbuttonoptions; + inherited; + optionswidget:= defaultoptionswidget - [ow_mousefocus]; + initshapeinfo(finfo); + finfo.ca.dim:= innerclientrect; + finfo.color:= cl_transparent; + finfo.ca.colorglyph:= cl_black; + finfo.doexecute:= {$ifdef FPC}@{$endif}doshapeexecute; + finfo.state:= finfo.state+[shs_showfocusrect,shs_showdefaultrect]; +end; +{ +procedure tactionsimplebutton.setoptionswidget(const avalue: optionswidgetty); +begin + if ow_nofocusrect in avalue then begin + exclude(finfo.state,ss_showfocusrect); + end + else begin + include(finfo.state,ss_showfocusrect); + end; + inherited; +end; +} +procedure tactionsimplebutton.clientrectchanged; +begin + inherited; + frameskinoptionstoshapestate(fframe,finfo); + finfo.ca.dim:= clientrect; + if (fframe <> nil) and not(shs_noinnerrect in finfo.state) then begin + //otherwise mouse rect + deflaterect1(finfo.ca.dim,fframe.frameo); + end; +{ + if shs_noinnerrect in finfo.state then begin + finfo.ca.dim:= clientrect; + end + else begin + finfo.ca.dim:= innerclientrect; + end; +} + if shs_flat in finfo.state then begin + exclude(fwidgetstate1,ws1_nodesignframe); + end + else begin + include(fwidgetstate1,ws1_nodesignframe); + end; +end; + +procedure tactionsimplebutton.doexecute; +begin + //dummy +end; + +procedure tactionsimplebutton.doasyncevent(var atag: integer); +begin + if atag = 0 then begin + doexecute; + end; +end; + +procedure tactionsimplebutton.internalexecute(); +begin + if bo_asyncexecute in foptions then begin + asyncevent; + end + else begin + doexecute; + end; +end; + +procedure tactionsimplebutton.doshapeexecute(const atag: integer; + const info: mouseeventinfoty); +begin + internalexecute; +end; + +procedure tactionsimplebutton.dopaintforeground(const canvas: tcanvas); +begin + inherited; + finfo.frame:= fframe; + drawbutton(canvas,finfo); +end; + +procedure tactionsimplebutton.clientmouseevent(var info: mouseeventinfoty); +begin + inherited; + if not (csdesigning in componentstate) and + not (es_processed in info.eventstate) then begin + updatemouseshapestate(finfo,info,self,fframe,nil,bo_executeonclick in foptions); + end; +end; + +procedure tactionsimplebutton.execute; +begin + if not (shs_disabled in finfo.state) then begin + internalexecute; + end; +end; + +procedure tactionsimplebutton.pressbutton; +begin + include(finfo.state,shs_clicked); + invalidateframestaterect(finfo.ca.dim,fframe); +end; + +function tactionsimplebutton.releasebutton(const aexecute: boolean): boolean; + //true if clicked +begin + result:= shs_clicked in finfo.state; + exclude(finfo.state,shs_clicked); + if result then begin + invalidateframestaterect(finfo.ca.dim,fframe); + if aexecute then begin + internalexecute; + end; + end; +end; + +procedure tactionsimplebutton.dokeydown(var info: keyeventinfoty); +begin +// inherited; + with info do begin + if not getdisabled() and (shiftstate * shiftstatesrepeatmask = []) and + (bo_executeonkey in foptions) then begin + if (key = key_space) then begin + include(info.eventstate,es_processed); + pressbutton; + end + else begin + if (isenterkey(self,key) or (key = key_period)) and + not (aso_noreturnbutton in assistiveoptions) then begin + //only space key if assisted + include(eventstate,es_processed); + internalexecute; + end; + end; + end; + end; + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +procedure tactionsimplebutton.dokeyup(var info: keyeventinfoty); +begin + inherited; + if not getdisabled() and (info.key = key_space) and + releasebutton((info.shiftstate = []) and + (bo_executeonkey in foptions)) then begin + include(info.eventstate,es_processed); + end; +end; + +procedure tactionsimplebutton.statechanged; +begin + inherited; + updatewidgetshapestate(finfo,self,getdisabled(),{false,}fframe); +end; + +procedure tactionsimplebutton.setcolorglyph(const value: colorty); +begin + if finfo.ca.colorglyph <> value then begin + finfo.ca.colorglyph := value; + invalidate; + end; +end; + +class function tactionsimplebutton.classskininfo: skininfoty; +begin + result:= inherited classskininfo; + result.objectkind:= sok_simplebutton; +end; + +procedure tactionsimplebutton.setoptions(const avalue: buttonoptionsty); +begin + if foptions <> avalue then begin + foptions:= avalue; + buttonoptionstoshapestate(avalue,finfo.state); + invalidate; + end; +end; + +function tactionsimplebutton.getframestateflags: framestateflagsty; +begin + result:= combineframestateflags(not isenabled,focused,active, + shs_mouse in finfo.state,shs_clicked in finfo.state); + if not (bo_nodefaultframeactive in foptions) and + ((shs_default in finfo.state) or focused) then begin + include(result,fsf_offset1); + include(result,fsf_default); + end; +end; + +function tactionsimplebutton.navigstartrect: rectty; +begin + result:= inherited navigstartrect; +// result.x:= result.x + result.cx div 2; +// result. cx:= 0; +end; + +function tactionsimplebutton.getassistiveflags(): assistiveflagsty; +begin + result:= inherited getassistiveflags() + [asf_button]; + if getdisabled() then begin + include(result,asf_disabled); + end; +end; + +function tactionsimplebutton.getdisabled(): boolean; +begin + result:= false; +end; + +{ +function tactionsimplebutton.getframeclicked: boolean; +begin + result:= ss_clicked in finfo.state; +end; + +function tactionsimplebutton.getframemouse: boolean; +begin + result:= ss_mouse in finfo.state; +end; + +function tactionsimplebutton.getframeactive: boolean; +begin + result:= not (bo_nodefaultframeactive in foptions) and + (ss_default in finfo.state) or active; +end; +} +{ tmessagebutton } + +procedure tmessagebutton.setcaption(const avalue: msestring); +begin + fcaption:= avalue; + captiontorichstring(avalue,finfo.ca.caption); + invalidate(); +end; + +procedure tmessagebutton.doexecute; +begin + if assigned(onexecute) then begin + onexecute(self); + end; + window.modalresult:= modalresult; +end; + +procedure tmessagebutton.doshortcut(var info: keyeventinfoty; const sender: twidget); +begin + if checkshortcut(info,caption,bo_altshortcut in options) then begin + include(info.eventstate,es_processed); + internalexecute; + end + else begin + inherited; + end; +end; + +function tmessagebutton.getassistivecaption(): msestring; +//var +// capt1: richstringty; +begin + result:= fcaption; +// captiontorichstring(fcaption,capt1); +// result:= capt1.text; +end; + +{ tshowmessagewidget } + +constructor tshowmessagewidget.create(const aowner: tcomponent; + const apopuptransient: boolean; const ahasaction: boolean; + const exttext: msestring; const ainfo: pshowmessageinfoty); +begin + fexttext:= exttext; + finfo:= ainfo; + inherited create(aowner,apopuptransient,ahasaction); + if finfo^.placementrect <> nil then begin + application.registeronidle(@doidle); + end; +end; + +destructor tshowmessagewidget.destroy(); +begin + application.unregisteronidle(@doidle); + inherited; +end; + +procedure tshowmessagewidget.dopaintforeground(const canvas: tcanvas); +begin + inherited; + canvas.font:= stockobjects.fonts[stf_message]; + drawtext(canvas,info); +end; + +procedure tshowmessagewidget.dokeydown(var ainfo: keyeventinfoty); +begin + if issysshortcut(sho_copy,ainfo) or issysshortcut(sho_cut,ainfo) then begin + copytoclipboard(replacechar(info.text.text+fexttext,#0 ,' ')); + end; + inherited; +end; + +procedure tshowmessagewidget.doidle(var again: boolean); +begin + application.unregisteronidle(@doidle); + if finfo^.placementrect <> nil then begin + window.decoratedwidgetrect:= placepopuprect(window.transientfor, + finfo^.placementrect^,finfo^.placement,window.decoratedsize); + end; +end; + +function tshowmessagewidget.getassistivetext(): msestring; +begin + result:= info.text.text; +end; + +function tshowmessagewidget.getassistiveflags(): assistiveflagsty; +begin + result:= inherited getassistiveflags + [asf_message]; + if finfo^.async then begin + include(result,asf_async); + end; +end; + +{ tcustomcaptionframe } + +constructor tcustomcaptionframe.create(const aintf: icaptionframe); +begin + fcaptionpos:= cp_topleft; + fcaptiondist:= 1; + inherited create(aintf); + if ffont = nil then begin + finfo.font:= icaptionframe(fintf).getframefont; + end; +end; + +destructor tcustomcaptionframe.destroy; +begin + inherited; + ffont.free; +end; +{ +function tcustomcaptionframe.getcaption: msestring; +begin + result:= richstringtocaption(finfo.text); +end; +} +procedure tcustomcaptionframe.setcaption(const avalue: msestring); +begin + fcaption:= avalue; + captiontorichstring(avalue,finfo.text); + internalupdatestate(); +end; + +procedure tcustomcaptionframe.setcaptionpos(const avalue: captionposty); +begin + if (fcaptionpos <> avalue) then begin + { + case avalue of + cp_leftcenter: fcaptionpos:= cp_left; + cp_rightcenter: fcaptionpos:= cp_right; + cp_topcenter: fcaptionpos:= cp_top; + cp_bottomcenter: fcaptionpos:= cp_bottom; + else fcaptionpos:= avalue; + end; + } + fcaptionpos:= avalue; + internalupdatestate; + end; +end; + +procedure tcustomcaptionframe.fontchanged(const sender: tobject); +begin + internalupdatestate; +end; + +procedure tcustomcaptionframe.fontcanvaschanged; +begin + exclude(fstate,fs_rectsvalid); +end; + +function tcustomcaptionframe.haspaintrectfocus(): boolean; +begin + result:= inherited haspaintrectfocus() or (finfo.text.text = ''); +end; + +procedure tcustomcaptionframe.dopaintfocusrect(const canvas: tcanvas; + const rect: rectty); +begin + if haspaintrectfocus then begin + inherited; + end + else begin + drawfocusrect(canvas,inflaterect(finfo.dest,captionmargin)); + end; +end; + +procedure tcustomcaptionframe.internalpaintoverlay(const canvas: tcanvas; + const arect: rectty); +var + reg1: regionty; + flagsbefore: textflagsty; +begin + reg1:= 0; + if not (cfo_captionnoclip in foptions) and (finfo.text.text <> '') then begin + reg1:= canvas.copyclipregion; + canvas.subcliprect(inflaterect(finfo.dest,captionmargin)); + end; + inherited; + if reg1 <> 0 then begin + canvas.clipregion:= reg1; + end; + if finfo.text.text <> '' then begin + flagsbefore:= finfo.flags; + finfo.flags:= updatetextflags(finfo.flags); + drawtext(canvas,finfo); + finfo.flags:= flagsbefore; + end; +end; +{ +procedure tcustomcaptionframe.afterpaint(const canvas: tcanvas); +begin + if finfo.text.text <> '' then begin + drawtext(canvas,finfo); + end; + inherited; +end; +} +procedure tcustomcaptionframe.createfont; +begin + if ffont = nil then begin + ffont:= tframefont.create; + ffont.onchange:= {$ifdef FPC}@{$endif}fontchanged; + finfo.font:= ffont; + end; +end; + +function tcustomcaptionframe.getfont: tframefont; +begin +// getoptionalobject(fintf.getcomponentstate,ffont,{$ifdef FPC}@{$endif}createfont); + icaptionframe(fintf).getwidget.getoptionalobject(ffont, + {$ifdef FPC}@{$endif}createfont); + if ffont <> nil then begin + result:= ffont; + end + else begin + result:= tframefont(icaptionframe(fintf).getframefont); + end; +end; + +procedure tcustomcaptionframe.setfont(const Value: tframefont); +begin + if value <> ffont then begin + setoptionalobject(fintf.getcomponentstate,value,ffont,{$ifdef FPC}@{$endif}createfont); + if ffont <> nil then begin + finfo.font:= ffont; + end + else begin + finfo.font:= icaptionframe(fintf).getframefont; + end; + internalupdatestate(); + end; +end; + +function tcustomcaptionframe.isfontstored: Boolean; +begin + result:= ffont <> nil; +end; + +procedure tcustomcaptionframe.parentfontchanged; +begin + inherited; + if ffont = nil then begin + finfo.font:= icaptionframe(fintf).getframefont; + if not (ws_loadedproc in icaptionframe(fintf).getwidget.widgetstate) then begin + internalupdatestate; + end; + end; +end; + +procedure tcustomcaptionframe.visiblechanged; +begin + inherited; + if finfo.text.text <> '' then begin + internalupdatestate; + end; +end; + +function tcustomcaptionframe.updatetextflags( + const aflags: textflagsty): textflagsty; +begin + result:= finfo.flags; + if (fs_disabled in fstate) and not (cfo_captionnogray in foptions) then begin + include(result,tf_grayed); + end; +end; + +procedure tcustomcaptionframe.updaterects; +var + canvas: tcanvas; + fra1: framety; + rect1,rect2: rectty; + bo1,bo2: boolean; + widget1: twidget1; + flagsbefore: textflagsty; +begin + inherited; + fra1:= fouterframe; + fstate:= fstate - [fs_cancaptionsyncx,fs_cancaptionsyncy]; + if finfo.text.text <> '' then begin + flagsbefore:= finfo.flags; + finfo.flags:= updatetextflags(finfo.flags); + canvas:= icaptionframe(fintf).getcanvas; + canvas.font:= getfont; + finfo.dest.size:= icaptionframe(fintf).getwidgetrect.size; + rect1:= deflaterect(makerect(nullpoint,finfo.dest.size),fouterframe); + textrect(canvas,finfo); + finfo.flags:= flagsbefore; +// finfo.flags:= flagsbefore-[tf_xcentered,tf_ycentered,tf_right,tf_bottom]; + finfo.dest:= finfo.res; + bo1:= cfo_captiondistouter in foptions; + bo2:= cfo_captionframecentered in foptions; + rect2:= inflaterect(finfo.dest,captionmargin); + with rect2 do begin + if fcaptionpos = cp_center then begin //precision position for record + x:= (rect1.x + rect1.x + rect1.cx - rect2.cx) div 2 + fcaptiondist; + y:= (rect1.y + rect1.y + rect1.cy - rect2.cy) div 2 + fcaptionoffset; +// finfo.flags:= finfo.flags + [tf_xcentered,tf_ycentered]; + end + else begin + { + if fcaptionpos in [cp_left,cp_right] then begin + include(finfo.flags,tf_ycentered); + end + else begin + if fcaptionpos in [cp_top,cp_bottom] then begin + include(finfo.flags,tf_xcentered); + end; + end; + if fcaptionpos in [cp_left,cp_lefttop,cp_leftbottom] then begin + include(finfo.flags,tf_right); + end + else begin + if fcaptionpos in [cp_top,cp_topleft,cp_topright] then begin + include(finfo.flags,tf_bottom); + end; + end; + } + case fcaptionpos of + cp_lefttop,cp_left,cp_leftbottom: begin + include(fstate,fs_cancaptionsyncx); + x:= rect1.x - fcaptiondist; + if not bo1 then begin + x:= x - cx; + if bo2 then begin + x:= x + (cx + fwidth.left) div 2; + end; + end; + end; + cp_topleft,cp_bottomleft: begin + include(fstate,fs_cancaptionsyncy); + x:= rect1.x + fcaptionoffset; + end; + cp_top,cp_bottom: begin + include(fstate,fs_cancaptionsyncy); + x:= rect1.x + (rect1.cx - cx) div 2 + fcaptionoffset; + end; + cp_topright,cp_bottomright: begin + include(fstate,fs_cancaptionsyncy); + x:= rect1.x + rect1.cx - cx + fcaptionoffset; + end; + cp_righttop,cp_right,cp_rightbottom: begin + include(fstate,fs_cancaptionsyncx); + x:= rect1.x + rect1.cx + fcaptiondist; + if bo1 then begin + x:= x - cx; + end + else begin + if bo2 then begin + x:= x - (fwidth.right + cx) div 2; + end; + end; + end; + end; + case fcaptionpos of + cp_topleft,cp_top,cp_topright: begin + y:= rect1.y - fcaptiondist; + if not bo1 then begin + y:= y - cy; + if bo2 then begin + y:= y + (cy+fwidth.top) div 2; + end; + end; + end; + cp_lefttop,cp_righttop: begin + y:= rect1.y + fcaptionoffset; + end; + cp_left,cp_right: begin + y:= rect1.y + (rect1.cy - cy) div 2 + fcaptionoffset; + end; + cp_leftbottom,cp_rightbottom: begin + y:= rect1.y + rect1.cy - cy + fcaptionoffset; + end; + cp_bottomleft,cp_bottom,cp_bottomright: begin + y:= rect1.y + rect1.cy + fcaptiondist; + if bo1 then begin + y:= y - cy; + end + else begin + if bo2 then begin + y:= y - (cy + fwidth.bottom) div 2; + end; + end; + end; + end; + end; + fouterframe.left:= rect1.x - x; + if fouterframe.left < 0 then begin + fouterframe.left:= 0; + end; + fouterframe.top:= rect1.y - y; + if fouterframe.top < 0 then begin + fouterframe.top:= 0; + end; + fouterframe.right:= x + cx - (rect1.x + rect1.cx); + if fouterframe.right < 0 then begin + fouterframe.right:= 0; + end; + fouterframe.bottom:= y + cy - (rect1.y + rect1.cy); + if fouterframe.bottom < 0 then begin + fouterframe.bottom:= 0; + end; + end; + finfo.dest:= inflaterect(rect2,-captionmargin); + if bo1 then begin + fstate:= fstate - [fs_cancaptionsyncx,fs_cancaptionsyncy]; + //captiondistouter set + end; + end + else begin //caption = '' or invisible + fouterframe:= nullframe; + finfo.dest:= nullrect; + end; + subframe1(fra1,fouterframe); + + widget1:= twidget1(icaptionframe(fintf).getwidget); + + if (cfo_autowidth in foptions) or + (widget1.anchors * [an_left,an_right] = [an_left,an_right]) then begin + if fcaptionpos in [cp_topleft,cp_bottomleft, + cp_top,cp_bottom,cp_center] then begin + fouterframe.right:= 0; + end; + if fcaptionpos in [cp_topright,cp_bottomright, + cp_top,cp_bottom,cp_center] then begin + fouterframe.left:= 0; + end; + end; + if (cfo_autoheight in foptions) or + (widget1.anchors * [an_top,an_bottom] = [an_top,an_bottom]) then begin + if fcaptionpos in [cp_lefttop,cp_righttop, + cp_left,cp_right,cp_center] then begin + fouterframe.bottom:= 0; + end; + if fcaptionpos in [cp_leftbottom,cp_rightbottom, + cp_left,cp_right,cp_center] then begin + fouterframe.top:= 0; + end; + end; + + if not isnullframe(fra1) then begin + if widget1.fwidgetstate1 * + [ws1_anchorsizing,ws1_layoutplacing] = [] then begin + subpoint1(finfo.dest.pos,pointty(fra1.topleft)); + if fupdating < 16 then begin + inc(fupdating); + try + rect1:= icaptionframe(fintf).getwidgetrect; + rect2:= deflaterect(rect1,fra1); + if cfo_fixleft in foptions then begin + rect2.x:= rect1.x; + if cfo_fixright in foptions then begin + rect2.cx:= rect1.cx; + end; + end + else begin + if cfo_fixright in foptions then begin + rect2.x:= rect1.x+rect1.cx-rect2.cx; + end; + end; + if cfo_fixtop in foptions then begin + rect2.y:= rect1.y; + if cfo_fixbottom in foptions then begin + rect2.cy:= rect1.cy; + end; + end + else begin + if cfo_fixbottom in foptions then begin + rect2.y:= rect1.y+rect1.cy-rect2.cy; + end; + end; + if (fupdating = 1) and + rectisequal(icaptionframe(fintf).getwidgetrect,rect2) then begin + if widget1.fparentwidget <> nil then begin + twidget1(widget1.fparentwidget).childautosizechanged(widget1); + end; //activate tlayouter + end + else begin + icaptionframe(fintf).setwidgetrect(rect2); + end; + finally + dec(fupdating); + end; + end; + end; + end; + inherited; +end; + +procedure tcustomcaptionframe.updatehotkeys(); +begin + captiontorichstring(fcaption,finfo.text); + internalupdatestate(); +end; + +procedure tcustomcaptionframe.dominsize(var asize: sizety); +var + si1: sizety; + framesi1: sizety; +begin + framesi1.cx:= fpaintframe.left + fpaintframe.right - + (fouterframe.left + fouterframe.right); + framesi1.cy:= fpaintframe.top + fpaintframe.bottom - + (fouterframe.top + fouterframe.bottom); + if asize.cx < framesi1.cx then begin + asize.cx:= framesi1.cx; + end; + if asize.cy < framesi1.cy then begin + asize.cy:= framesi1.cy; + end; + if finfo.text.text <> '' then begin + checkstate(); + si1.cx:= finfo.dest.size.cx + 2*captionmargin; + si1.cy:= finfo.dest.size.cy + 2*captionmargin; + case captionpos of + cp_center: begin + si1.cx:= si1.cx + abs(fcaptiondist); + si1.cy:= si1.cy + abs(fcaptionoffset); + end; + cp_righttop,cp_right,cp_rightbottom,cp_lefttop,cp_left,cp_leftbottom: begin + si1.cx:= framesi1.cx + si1.cx + abs(fcaptiondist); + if fcaptionoffset > 0 then begin + si1.cy:= si1.cy + fcaptionoffset; + end; + end + else begin + si1.cy:= framesi1.cy + si1.cy + abs(fcaptiondist); + if fcaptionoffset > 0 then begin + si1.cx:= si1.cx + fcaptionoffset; + end; + end; + end; + if asize.cx < si1.cx then begin + asize.cx:= si1.cx; + end; + if asize.cy < si1.cy then begin + asize.cy:= si1.cy; + end; + end; +end; + +procedure tcustomcaptionframe.checkminshrinksize(var asize: sizety); +begin + inherited; + dominsize(asize); +end; + +procedure tcustomcaptionframe.checkwidgetsize(var asize: sizety); +begin //for autosize + dominsize(asize); +end; + +procedure tcustomcaptionframe.setcaptiondist(const Value: integer); +begin + include(flocalprops1,frl1_captiondist); + if fcaptiondist <> value then begin + fcaptiondist := Value; + internalupdatestate; + end; +end; + +function tcustomcaptionframe.iscaptiondiststored: boolean; +begin + result:= (ftemplate = nil) or (frl1_captiondist in flocalprops1); +end; + +procedure tcustomcaptionframe.setcaptionoffset(const Value: integer); +begin + include(flocalprops1,frl1_captionoffset); + if fcaptionoffset <> value then begin + fcaptionoffset:= Value; + internalupdatestate(); + end; +end; + +procedure tcustomcaptionframe.setcaptiontextflags(const avalue: textflagsty); +begin + if finfo.flags <> avalue then begin + finfo.flags:= checktextflags(finfo.flags,avalue); + internalupdatestate(); + end; +end; + + +function tcustomcaptionframe.iscaptionoffsetstored: boolean; +begin + result:= (ftemplate = nil) or (frl1_captionoffset in flocalprops1); +end; + +procedure tcustomcaptionframe.setoptions(const avalue: captionframeoptionsty); +const +// mask1: captionframeoptionsty = [cfo_captiondistouter,cfo_captionframecentered]; + mask2: captionframeoptionsty = [cfo_captiondistouter]; +var + optionsbefore: captionframeoptionsty; + size1: sizety; +begin + if avalue <> foptions then begin + optionsbefore:= foptions; + (* + foptions:= captionframeoptionsty(setsinglebit( + {$ifdef FPC}longword{$else}word{$endif}(avalue), + {$ifdef FPC}longword{$else}word{$endif}(foptions), + {$ifdef FPC}longword{$else}word{$endif}(mask1))); + *) + foptions:= captionframeoptionsty( + setsinglebit(longword(avalue),longword(foptions), + [longword([cfo_captiondistouter,cfo_captionframecentered]), + longword([cfo_focusrect,cfo_nofocusrect])])); + if (({$ifdef FPC}longword{$else}word{$endif}(optionsbefore) xor + {$ifdef FPC}longword{$else}word{$endif}(foptions)) and + {$ifdef FPC}longword{$else}word{$endif}(mask2) <> 0) and + (fintf.getcomponentstate * [csdesigning,csloading] = [csdesigning]) and + (caption <> '') then begin + size1.cy:= font.glyphheight + 2 * captionmargin; + size1.cx:= icaptionframe(fintf).getcanvas.getstringwidth(caption,getfont) + + 2 * captionmargin; + case captionpos of + cp_center: begin + end; + cp_lefttop,cp_left,cp_leftbottom,cp_rightbottom,cp_right,cp_righttop: begin + if cfo_captiondistouter in foptions then begin + fcaptiondist:= fcaptiondist + size1.cx; + end + else begin + fcaptiondist:= fcaptiondist - size1.cx; + end; + end; + cp_topright,cp_top,cp_topleft,cp_bottomleft,cp_bottom,cp_bottomright: begin + if cfo_captiondistouter in foptions then begin + fcaptiondist:= fcaptiondist + size1.cy; + end + else begin + fcaptiondist:= fcaptiondist - size1.cy; + end; + end; + end; + end; + internalupdatestate; + end; +end; + +(* +function tcustomcaptionframe.getcaptiondistouter: boolean; +begin + result:= fs_captiondistouter in fstate; +end; + +function tcustomcaptionframe.getcaptionframecentered: boolean; +begin + result:= fs_captionframecentered in fstate; +end; + +procedure tcustomcaptionframe.setcaptionframecentered(const avalue: boolean); +begin + if updatebit({$ifdef FPC}longword{$else}longword{$endif}(fstate), + ord(fs_captionframecentered),avalue) then begin + if avalue then begin + exclude(fstate,fs_captiondistouter); + end; + internalupdatestate; + end; +end; + +procedure tcustomcaptionframe.setcaptiondistouter(const Value: boolean); +var + size1: sizety; +begin + if updatebit({$ifdef FPC}longword{$else}longword{$endif}(fstate), + ord(fs_captiondistouter),value) then begin + if value then begin + exclude(fstate,fs_captionframecentered); + end; + if (fintf.getcomponentstate * [csdesigning,csloading] = [csdesigning]) and + (caption <> '') then begin + size1.cy:= font.glyphheight + 2 * captionmargin; + size1.cx:= icaptionframe(fintf).getcanvas.getstringwidth(caption,getfont) + + 2 * captionmargin; + case captionpos of + cp_center: begin + end; + cp_lefttop,cp_left,cp_leftbottom,cp_rightbottom,cp_right,cp_righttop: begin + if fs_captiondistouter in fstate then begin + fcaptiondist:= fcaptiondist + size1.cx; + end + else begin + fcaptiondist:= fcaptiondist - size1.cx; + end; + end; + cp_topright,cp_top,cp_topleft,cp_bottomleft,cp_bottom,cp_bottomright: begin + if fs_captiondistouter in fstate then begin + fcaptiondist:= fcaptiondist + size1.cy; + end + else begin + fcaptiondist:= fcaptiondist - size1.cy; + end; + end; + end; + end; + internalupdatestate; + end; +end; + +function tcustomcaptionframe.getcaptionnoclip: boolean; +begin + result:= fs_captionnoclip in fstate; +end; + +procedure tcustomcaptionframe.setcaptionnoclip(const avalue: boolean); +begin + if updatebit({$ifdef FPC}longword{$else}longword{$endif}(fstate), + ord(fs_captionnoclip),avalue) then begin + internalupdatestate; + end; +end; +*) +procedure tcustomcaptionframe.defineproperties(filer: tfiler); +var + bo1: boolean; +begin + inherited; + if filer.ancestor <> nil then begin + bo1:= not frameisequal(fouterframe,tcustomcaptionframe(filer.ancestor).fouterframe); + end + else begin + bo1:= not isnullframe(fouterframe); + end; + filer.DefineProperty('outerframe',{$ifdef FPC}@{$endif}readouterframe, + {$ifdef FPC}@{$endif}writeouterframe,bo1); + filer.DefineProperty('captiondistouter', //backward compatibility + {$ifdef FPC}@{$endif}readcaptiondistouter,nil,false); + filer.DefineProperty('captionnoclip', //backward compatibility + {$ifdef FPC}@{$endif}readcaptionnoclip,nil,false); +end; + +procedure tcustomcaptionframe.readouterframe(reader: treader); +begin + with fouterframe,reader do begin + readlistbegin; + left:= ReadInteger; + top:= ReadInteger; + right:= ReadInteger; + bottom:= ReadInteger; + readlistend; + end; +end; + +procedure tcustomcaptionframe.writeouterframe(writer: twriter); +begin + with fouterframe,writer do begin + writelistbegin; + writeinteger(left); + writeinteger(top); + writeinteger(right); + writeinteger(bottom); + writelistend; + end; +end; + +procedure tcustomcaptionframe.readcaptionnoclip(reader: treader); +begin + if reader.readboolean then begin + options:= options + [cfo_captionnoclip]; + end + else begin + options:= options - [cfo_captionnoclip]; + end; +end; + +procedure tcustomcaptionframe.readcaptiondistouter(reader: treader); +begin + if reader.readboolean then begin + options:= options + [cfo_captiondistouter]; + end + else begin + options:= options - [cfo_captiondistouter]; + end; +end; + +function tcustomcaptionframe.checkfocusshortcut( + var info: keyeventinfoty): boolean; +begin + result:= msegui.checkshortcut(info,fcaption,true); +end; + +procedure tcustomcaptionframe.setdisabled(const value: boolean); +begin + if (finfo.text.text <> '') and ((fs_disabled in fstate) xor value) then begin + fintf.invalidatewidget; + end; + inherited; +end; + +function tcustomcaptionframe.pointincaption(const point: pointty): boolean; +var + rect1: rectty; + int1: integer; +begin + if finfo.text.text = '' then begin + result:= false; + end + else begin + checkstate; + rect1:= finfo.dest; + with rect1 do begin + case fcaptionpos of + cp_left,cp_lefttop,cp_leftbottom: begin + int1:= fpaintrect.x - (x + cx); + if int1 > 0 then begin + inc(rect1.cx,int1); + end; + end; + cp_top,cp_topleft,cp_topright: begin + int1:= fpaintrect.y - (y + cy); + if int1 > 0 then begin + inc(rect1.cy,int1); + end; + end; + cp_right,cp_righttop,cp_rightbottom: begin + int1:= x - (fpaintrect.x + fpaintrect.cx); + if int1 > 0 then begin + dec(rect1.x,int1); + inc(rect1.cx,int1); + end; + end; + cp_bottom,cp_bottomleft,cp_bottomright: begin + int1:= y - (fpaintrect.y + fpaintrect.cy); + if int1 > 0 then begin + dec(rect1.y,int1); + inc(rect1.cy,int1); + end; + end; + end; + end; + result:= pointinrect(point,rect1); + end; +end; + +procedure tcustomcaptionframe.updatemousestate(const sender: twidget; + const info: mouseeventinfoty); +begin + inherited; + with twidget1(sender) do begin + if not (ow_mousetransparent in foptionswidget) then begin + if pointincaption(info.pos) then begin + include(fwidgetstate,ws_wantmousebutton); //for twidget.iswidgetclick + if cfo_captionfocus in foptions then begin + include(fwidgetstate,ws_wantmousefocus); + end; + if fs_captionhint in fstate then begin + include(fwidgetstate,ws_wantmousemove); + end; + end; + if (cfo_framerectfocus in foptions) and + pointinrect(info.pos,framerect) then begin + include(fwidgetstate,ws_wantmousefocus); + end; + end; + end; +end; + +function tcustomcaptionframe.getassistivecaption(): msestring; +begin + result:= fcaption; +end; + +procedure tcustomcaptionframe.scale(const ascale: real); +begin + if ffont <> nil then begin + ffont.scale(ascale); + end; + inherited; +end; + +function tcustomcaptionframe.needsfocuspaint: boolean; +begin + result:= (inherited needsfocuspaint or + (ftemplate <> nil) and + (fso_forcefocusrect in ftemplate.template.optionsskin)) and + not (cfo_nofocusrect in foptions) and + ((cfo_focusrect in foptions) or (ftemplate = nil) or + not (fso_nofocusrect in ftemplate.template.optionsskin)); + result:= result or (cfo_forcefocusrect in foptions); + if result then begin + if cfo_captionfocus in foptions then begin + include(fstate,fs_captionfocus); + exclude(fstate,fs_paintrectfocus); + end + else begin + include(fstate,fs_paintrectfocus); + exclude(fstate,fs_captionfocus); + end; + end; +end; + +procedure tcustomcaptionframe.settemplateinfo(const ainfo: frameinfoty); +begin + if not (frl1_font in flocalprops1) and (ainfo.capt.font <> nil) then begin + createfont; + ffont.assign(ainfo.capt.font); + if not (frl1_captiondist in flocalprops1) then begin + fcaptiondist:= ainfo.capt.captiondist; + end; + if not (frl1_captionoffset in flocalprops1) then begin + fcaptionoffset:= ainfo.capt.captionoffset; + end; + end; + inherited; +end; + +{ tcustomscrollframe } + +constructor tcustomscrollframe.create(const aintf: iscrollframe; + const scrollintf: iscrollbar); +begin + aintf.setstaticframe(true); + foptionsscroll:= defaultoptionsscroll; + fdragbuttons:= defaultdragbuttons; + inherited create(aintf); + fhorz:= getscrollbarclass(false).create(scrollintf,org_widget, + {$ifdef FPC}@{$endif}updatestate); + fvert:= getscrollbarclass(true).create(scrollintf,org_widget, + {$ifdef FPC}@{$endif}updatestate); + fvert.tag:= 1; + fvert.direction:= gd_down; +end; + +destructor tcustomscrollframe.destroy; +begin + fhorz.Free; + fvert.free; + inherited; +end; + +procedure tcustomscrollframe.checktemplate(const sender: tobject); + //true if match +begin + inherited; + fhorz.checktemplate(sender); + fvert.checktemplate(sender); +end; + +function tcustomscrollframe.getscrollbarclass(vert: boolean): framescrollbarclassty; +begin + result:= tcustomscrollbar; +end; + +procedure tcustomscrollframe.getpaintframe(var frame: framety); +begin + with frame do begin + if fs_sbleft in fstate then inc(left,fvert.width); + if fs_sbtop in fstate then inc(top,fhorz.width); + if fs_sbright in fstate then inc(right,fvert.width); + if fs_sbbottom in fstate then inc(bottom,fhorz.width); + end; +end; + +procedure tcustomscrollframe.addscrollbarwidth(var asize: sizety); +begin + with asize do begin + if fs_sbleft in fstate then inc(cx,fvert.width); + if fs_sbtop in fstate then inc(cy,fhorz.width); + if fs_sbright in fstate then inc(cx,fvert.width); + if fs_sbbottom in fstate then inc(cy,fhorz.width); + end; +end; + +procedure tcustomscrollframe.subscrollbarwidth(var asize: sizety); +begin + with asize do begin + if fs_sbleft in fstate then inc(cx,fvert.width); + if fs_sbtop in fstate then inc(cy,fhorz.width); + if fs_sbright in fstate then inc(cx,fvert.width); + if fs_sbbottom in fstate then inc(cy,fhorz.width); + end; +end; + +procedure tcustomscrollframe.mouseevent(var info: mouseeventinfoty); +begin + if not (ws_clientmousecaptured in iscrollframe(fintf).widgetstate) then begin + if fs_sbhorzon in fstate then begin + fhorz.mouseevent(info); + end; + if fs_sbverton in fstate then begin + fvert.mouseevent(info); + end; + end; +end; + +procedure tcustomscrollframe.domousewheelevent(var info: mousewheeleventinfoty; + const pagingreversed: boolean); +var + scrollbar: tcustomscrollbar; +begin + with info do begin + if not (es_processed in eventstate) then begin + scrollbar:= nil; + if (fs_sbverton in fstate) and pointinrect(info.pos,sbvert.dim) then begin + scrollbar:= sbvert; + end + else begin + if (fs_sbhorzon in fstate) and pointinrect(info.pos,sbhorz.dim) then begin + scrollbar:= sbhorz; + end + else begin + if oscr_mousewheel in foptionsscroll then begin + if (fs_sbverton in fstate) then begin + scrollbar:= sbvert; + end + else begin + if fs_sbhorzon in fstate then begin + scrollbar:= sbhorz; + end + else begin + end; + end; + end; + end; + end; + if scrollbar <> nil then begin + scrollbar.mousewheelevent(info,pagingreversed); + end; + end; + end; +end; + +procedure tcustomscrollframe.internalpaintoverlay(const canvas: tcanvas; + const arect: rectty); +begin + inherited; + if fs_sbverton in fstate then begin + fvert.paint(canvas); + end; + if fs_sbhorzon in fstate then begin + fhorz.paint(canvas); + end; +end; + +procedure tcustomscrollframe.updatemousestate(const sender: twidget; + const info: mouseeventinfoty); +begin + inherited; + if (fs_sbverton in fstate) and fvert.wantmouseevent(info.pos) or + (fs_sbhorzon in fstate) and fhorz.wantmouseevent(info.pos) then begin + with twidget1(sender) do begin + fwidgetstate:= (fwidgetstate - [ws_mouseinclient]) + + [ws_wantmousebutton,ws_wantmousemove]; + end; + end; +end; + +procedure tcustomscrollframe.updaterects; +var + rect1: rectty; + int1,int2: integer; + + procedure checkvert; + begin + with tcustomscrollbar1(fvert) do begin + if findentstart < 0 then begin + int1:= 0; + end + else begin + if findentstart = 0 then begin + int1:= fpaintframedelta.top; + end + else begin + int1:= findentstart; + end; + end; + if findentend < 0 then begin + int2:= 0; + end + else begin + if findentend = 0 then begin + int2:= fpaintframedelta.bottom; + end + else begin + int2:= findentend; + end; + end; + end; + end; + + procedure checkhorz; + begin + with tcustomscrollbar1(fhorz) do begin + if findentstart < 0 then begin + int1:= 0; + end + else begin + if findentstart = 0 then begin + int1:= fpaintframedelta.left; + end + else begin + int1:= findentstart; + end; + end; + if findentend < 0 then begin + int2:= 0; + end + else begin + if findentend = 0 then begin + int2:= fpaintframedelta.right; + end + else begin + int2:= findentend; + end; + end; + end; + end; + +begin + int1:= 0; + int2:= 0; + fstate:= fstate - [fs_sbleft,fs_sbtop,fs_sbright,fs_sbbottom]; + if fs_sbhorzon in fstate then begin + if fs_sbhorztop in fstate then begin + include(fstate,fs_sbtop); + end + else begin + include(fstate,fs_sbbottom); + end; + end; + if fs_sbverton in fstate then begin + if fs_sbvertleft in fstate then begin + include(fstate,fs_sbleft); + end + else begin + include(fstate,fs_sbright); + end; + end; + inherited; + rect1:= inflaterect(fpaintrect,fpaintframedelta); + with rect1 do begin + if fs_sbleft in fstate then begin + checkvert; + with fvert do begin + dim:= makerect(x,y+int1,width,cy-int1-int2); + end; + end; + if fs_sbright in fstate then begin + checkvert; + with fvert do begin + dim:= makerect(x + cx-width,y+int1,width,cy-int1-int2); + end; + end; + if fs_sbtop in fstate then begin + checkhorz; + with fhorz do begin + dim:= makerect(x+int1,y,cx-int1-int2,width); + end; + end; + if fs_sbbottom in fstate then begin + checkhorz; + with fhorz do begin + dim:= makerect(x+int1,y+cy-width,cx-int1-int2,width); + end; + end; + end; +end; + +procedure tcustomscrollframe.updatevisiblescrollbars; +begin + updatebit({$ifdef FPC}longword{$else}longword{$endif}(fstate),ord(fs_sbhorztop), + sbo_opposite in fhorz.options); + updatebit({$ifdef FPC}longword{$else}longword{$endif}(fstate),ord(fs_sbvertleft), + sbo_opposite in fvert.options); + if sbo_show in fhorz.options then begin + include(fstate,fs_sbhorzon); + end + else begin + if not (sbo_showauto in fhorz.options) then begin + exclude(fstate,fs_sbhorzon); + end + else begin + if fhorz.pagesize = 1 then begin + exclude(fstate,fs_sbhorzon); + end + else begin + include(fstate,fs_sbhorzon); + end; + end; + end; + if sbo_show in fvert.options then begin + include(fstate,fs_sbverton); + end + else begin + if not (sbo_showauto in fvert.options) then begin + exclude(fstate,fs_sbverton); + end + else begin + if fvert.pagesize = 1 then begin + exclude(fstate,fs_sbverton); + end + else begin + include(fstate,fs_sbverton); + end; + end; + end; +end; + +procedure tcustomscrollframe.updatestate; +var + statebefore: framestatesty; +begin + statebefore:= fstate; + updatevisiblescrollbars; + inherited; + if ({$ifdef FPC}longword{$else}longword{$endif}(statebefore) xor + {$ifdef FPC}longword{$else}longword{$endif}(fstate)) and + {$ifdef FPC}longword{$else}longword{$endif}(scrollbarframestates) <> 0 then begin + iscrollframe(fintf).getwidget.invalidatewidget; + end; +end; +{ +function tcustomscrollframe.getsbhorz: tcustomscrollbar; +begin + result:= fhorz; +end; +} +procedure tcustomscrollframe.setsbhorz(const Value: tcustomscrollbar); +begin + fhorz.assign(Value); +end; +{ +function tcustomscrollframe.getsbvert: tcustomscrollbar; +begin + result:= fvert; +end; +} +procedure tcustomscrollframe.setsbvert(const Value: tcustomscrollbar); +begin + fvert.assign(Value); +end; + +procedure tcustomscrollframe.setdragbuttons(const avalue: shiftstatesty); +begin + fdragbuttons:= avalue * buttonshiftstatesmask; +end; + +procedure tcustomscrollframe.activechanged; +begin + inherited; + fvert.activechanged; + fhorz.activechanged; +end; + +procedure tcustomscrollframe.settemplateinfo(const ainfo: frameinfoty); +begin + inherited; + if not (frl1_colorglyph in flocalprops1) and + (ainfo.ba.colorglyph <> cl_default) then begin + sbhorz.colorglyph:= ainfo.ba.colorglyph; + sbvert.colorglyph:= ainfo.ba.colorglyph; + end; + if not (frl1_colorpattern in flocalprops1) and + (ainfo.ba.colorpattern <> cl_default) then begin + sbhorz.colorpattern:= ainfo.ba.colorpattern; + sbvert.colorpattern:= ainfo.ba.colorpattern; + end; +end; + +{ tcustomstepframe } + +constructor tcustomstepframe.create(const aintf: icaptionframe; + const stepintf: istepbar); +begin + fstepintf:= stepintf; + fbuttonsize:= defaultstepbuttonsize; + fforceinvisiblebuttons:= [sk_first,sk_last]; + fcolorbutton:= cl_default; + fcolorglyph:= cl_default; + aintf.setstaticframe(true); + fmousewheel:= true; + frepeatedbutton:= -1; + inherited create(aintf); +end; + +destructor tcustomstepframe.destroy; +begin + killrepeater; + inherited; + fbuttonface.free; + fbuttonframe.free; +end; + +procedure tcustomstepframe.killrepeater; +begin + freeandnil(frepeater); + frepeatedbutton:= -1; +end; + +procedure tcustomstepframe.execute(const tag: integer; + const info: mouseeventinfoty); +begin + if @info = nil then begin + fstepintf.dostep(stepkindty(tag),0,application.lastshiftstate); + end + else begin + fstepintf.dostep(stepkindty(tag),0,info.shiftstate); + end; +end; + +procedure tcustomstepframe.getpaintframe(var frame: framety); +begin + case fbuttonpos of + sbp_right: begin + inc(frame.right,fdim.cx); + end; + sbp_top: begin + inc(frame.top,fdim.cy); + end; + sbp_left: begin + inc(frame.left,fdim.cx); + end; + sbp_bottom: begin + inc(frame.bottom,fdim.cy); + end; + end; +end; + +procedure tcustomstepframe.layoutchanged; +var + widget: twidget; +begin + widget:= icaptionframe(fintf).getwidget; + if not (csloading in widget.ComponentState) then begin + updatestate; + widget.invalidaterect(fdim,org_widget); + end; +end; + +procedure tcustomstepframe.dorepeat(const sender: tobject); +begin + with tsimpletimer(sender) do begin +// if interval < 0 then begin + if singleshot then begin + interval:= repeatrepeattime; + enabled:= true; + end; + execute(frepeatedbutton,pmouseeventinfoty(nil)^); + end; +end; + +procedure tcustomstepframe.mouseevent(var info: mouseeventinfoty); +var + int1: integer; + clickedbutton: integer; +begin + clickedbutton:= -1; + for int1:= 0 to high(fbuttons) do begin + if updatemouseshapestate(fbuttons[int1],info,nil,nil) then begin + icaptionframe(fintf).getwidget.invalidaterect( + fbuttons[int1].ca.dim,org_widget); + if info.eventkind in [ek_buttonpress,ek_buttonrelease] then begin + include(info.eventstate,es_processed); + end; + end; + if shs_clicked in fbuttons[int1].state then begin + clickedbutton:= int1; + end; + end; + if frepeatedbutton <> clickedbutton then begin + killrepeater; + if clickedbutton >= 0 then begin + frepeatedbutton:= clickedbutton; + frepeater:= tsimpletimer.create(repeatdelaytime, + {$ifdef FPC}@{$endif}dorepeat,true,[to_single]); + end; + end; +end; + +procedure tcustomstepframe.internalpaintoverlay(const canvas: tcanvas; + const arect: rectty); +var + int1: integer; + po1: pshapeinfoty; +begin + inherited; + for int1:= 0 to high(fbuttons) do begin + factbuttonindex:= int1; //widgetstateflags for button frame + po1:= @fbuttons[int1]; + po1^.face:= fbuttonface; + po1^.frame:= fbuttonframe; + drawtoolbutton(canvas,po1^); + end; +end; + +procedure tcustomstepframe.updatebuttonstate(const first,delta,count: integer); +var + disabled: stepkindsty; +begin + disabled:= []; + if first = 0 then begin + include(disabled,sk_left); + include(disabled,sk_up); + include(disabled,sk_first); + end; + if first+delta >= count then begin + include(disabled,sk_right); + include(disabled,sk_down); + { + if (frepeatedbutton >= 0) and + (stepkindty(frepeatedbutton) in [sk_right,sk_down]) then begin + killrepeater(); + end; + } + end; + disabledbuttons:= disabled; + if (first+delta >= count) and (first <= 0) then begin + neededbuttons:= []; +// invisiblebuttons:= [sk_right,sk_up,sk_left,sk_down]; + end + else begin + neededbuttons:= [sk_right,sk_up,sk_left,sk_down,sk_first,sk_last]; +// invisiblebuttons:= forceinvisiblebuttons; + end; +end; + +function tcustomstepframe.executestepevent(const event: stepkindty; + const stepinfo: framestepinfoty; const aindex: integer): integer; +var + steps: array[stepkindty] of integer; +begin + with stepinfo do begin + steps[sk_first]:= -bigint; + steps[sk_last]:= pagelast; + case fbuttonpos of + sbp_right,sbp_left: begin + steps[sk_right]:= 0; + if not (sk_right in disabledbuttons) then begin + steps[sk_right]:= up; + end; + steps[sk_left]:= down; + steps[sk_up]:= pagedown; + steps[sk_down]:= 0; + if not (sk_down in disabledbuttons) then begin + steps[sk_down]:= pageup; + end; + end; + sbp_top: begin + steps[sk_right]:= 0; + if not (sk_down in disabledbuttons) then begin + steps[sk_right]:= pageup; + end; + steps[sk_left]:= pagedown; + steps[sk_up]:= down; + steps[sk_down]:= 0; + if not (sk_right in disabledbuttons) then begin + steps[sk_down]:= up; + end; + end; + else begin //sbp_bottom + steps[sk_right]:= 0; + if not (sk_down in disabledbuttons) then begin + steps[sk_right]:= pageup; + end; + steps[sk_left]:= pagedown; + steps[sk_up]:= down; + steps[sk_down]:= 0; + if not (sk_right in disabledbuttons) then begin + steps[sk_down]:= up; + end; + end; + end; + end; + result:= aindex + steps[event]; +end; + +procedure tcustomstepframe.setbuttonsize(const Value: integer); +begin + if fbuttonsize <> value then begin + fbuttonsize := Value; + layoutchanged; + end; +end; + +procedure tcustomstepframe.setbuttonpos(const Value: stepbuttonposty); +begin + if fbuttonpos <> value then begin + fbuttonpos := Value; + layoutchanged; + end; +end; + +procedure tcustomstepframe.setbuttonsinline(const Value: boolean); +begin + if fbuttonsinline <> value then begin + fbuttonsinline := Value; + layoutchanged; + end; +end; + +procedure tcustomstepframe.setbuttonslast(const avalue: boolean); +begin + if fbuttonslast <> avalue then begin + fbuttonslast:= avalue; + layoutchanged; + end; +end; + +procedure tcustomstepframe.setcolorbutton(const avalue: colorty); +begin + if fcolorbutton <> avalue then begin + fcolorbutton:= avalue; + updatelayout; + icaptionframe(fintf).getwidget.invalidaterect(fdim,org_widget); + end; +end; + +procedure tcustomstepframe.setcolorglyph(const avalue: colorty); +begin + if fcolorglyph <> avalue then begin + fcolorglyph:= avalue; + updatelayout; + icaptionframe(fintf).getwidget.invalidaterect(fdim,org_widget); + end; +end; + +procedure tcustomstepframe.setdisabledbuttons(const avalue: stepkindsty); +begin + if fdisabledbuttons <> avalue then begin + fdisabledbuttons:= avalue; + layoutchanged; + end; +end; + +procedure tcustomstepframe.setbuttonsinvisible(const avalue: stepkindsty); +begin + if fforceinvisiblebuttons <> avalue then begin + fforceinvisiblebuttons:= avalue; + layoutchanged; + end; +end; + +procedure tcustomstepframe.setbuttonsvisible(const avalue: stepkindsty); +begin + if fforcevisiblebuttons <> avalue then begin + fforcevisiblebuttons:= avalue; + layoutchanged; + end; +end; + +procedure tcustomstepframe.setneededbuttons(const avalue: stepkindsty); +begin + if fneededbuttons <> avalue then begin + fneededbuttons:= avalue; + layoutchanged; + end; +end; + +type + buttonarty = array[stepkindty] of stepkindty; + buttonposarty = array[boolean,stepbuttonposty] of buttonarty; +const + buttonposstep: buttonposarty = + ( + ( //not fbuttonsinline + (sk_left,sk_right,sk_up,sk_down,sk_first,sk_last), //sbp_right + (sk_left,sk_up,sk_right,sk_down,sk_first,sk_last), //sbp_top + (sk_left,sk_right,sk_up,sk_down,sk_first,sk_last), //sbp_left + (sk_up,sk_left,sk_down,sk_right,sk_first,sk_last) //sbp_bottom + ), + ( //fbuttonsinline + (sk_left,sk_right,sk_up,sk_down,sk_first,sk_last), //sbp_right + (sk_up,sk_down,sk_left,sk_right,sk_first,sk_last), //sbp_top + (sk_left,sk_right,sk_up,sk_down,sk_first,sk_last), //sbp_left + (sk_up,sk_down,sk_left,sk_right,sk_first,sk_last) //sbp_bottom + ) + ); + buttonposspin: buttonposarty = + ( + ( //not fbuttonsinline + (sk_left,sk_right,sk_up,sk_last,sk_down,sk_first), //sbp_right + (sk_left,sk_up,sk_right,sk_down,sk_last,sk_first), //sbp_top + (sk_left,sk_right,sk_up,sk_last,sk_down,sk_first), //sbp_left + (sk_up,sk_left,sk_down,sk_right,sk_last,sk_first) //sbp_bottom + ), + ( //fbuttonsinline + (sk_left,sk_right,sk_up,sk_down,sk_last,sk_first), //sbp_right + (sk_up,sk_down,sk_left,sk_right,sk_first,sk_last), //sbp_top + (sk_left,sk_right,sk_up,sk_down,sk_last,sk_first), //sbp_left + (sk_up,sk_down,sk_left,sk_right,sk_first,sk_last) //sbp_bottom + ) + ); + + images: array[stepkindty] of stockglyphty = + ( stg_arrowrightsmall,stg_arrowupsmall,stg_arrowleftsmall,stg_arrowdownsmall, + stg_arrowfirstsmall,stg_arrowlastsmall); + imagesedit: array[stepkindty] of stockglyphty = + ( stg_arrowrightsmall,stg_arrowupsmall,stg_arrowleftsmall,stg_arrowdownsmall, + stg_arrowbottomsmall,stg_arrowtopsmall); + +procedure tcustomstepframe.updatelayout; +var + buttoncount: integer; + acx,acy: integer; + ax,ay: integer; + + procedure checkbutton(button: stepkindty; vert: boolean); + begin + with fbuttons[ord(button)] do begin + if button in fdisabledbuttons then begin + include(state,shs_disabled); + end + else begin + exclude(state,shs_disabled); + end; + if (button in fforcevisiblebuttons) or + not (button in fforceinvisiblebuttons) and (button in fneededbuttons) then begin + inc(buttoncount); + ca.dim.x:= ax; + ca.dim.y:= ay; + if vert then begin + inc(ay,acy); + end + else begin + inc(ax,acx); + end; + end; + end; + end; + +var + a,b: integer; + int1: integer; + akind: stepkindty; + bo1: boolean; + bo2: boolean; + color1: colorty; + buttonpos1: ^buttonposarty; + +begin //updatelayout + if sfs_spinedit in fstepstate then begin + buttonpos1:= @buttonposspin; + end + else begin + buttonpos1:= @buttonposstep; + end; + + setlength(fbuttons,ord(high(stepkindty)) + 1); + buttoncount:= 0; + a:= 0; //compilerwarning + b:= 0; //compilerwarning + for akind:= low(stepkindty) to high(stepkindty) do begin +// if not (akind in finvisiblebuttons) or (akind in fvisiblebuttons) then begin + if (akind in fforcevisiblebuttons) or + not (akind in fforceinvisiblebuttons) and (akind in fneededbuttons) then begin + inc(buttoncount); + exclude(fbuttons[ord(akind)].state,shs_invisible); + end + else begin + include(fbuttons[ord(akind)].state,shs_invisible); + end; + end; + if buttoncount = 0 then begin + fdim.cx:= 0; + fdim.cy:= 0; + end + else begin + if not fbuttonsinline then begin + a:= (buttoncount + 1) div 2; + b:= (buttoncount + a - 1) div a; + bo2:= a > 1; + end + else begin + bo2:= false; + end; + if not bo2 then begin + a:= buttoncount; + b:= 1; + end; + if fbuttonpos in [sbp_left,sbp_right] then begin + acy:= fpaintrect.cy div a; + if acy > fbuttonsize then begin + acy:= fbuttonsize; + end; + if fbuttonslast then begin + ay:= fpaintrect.y + fpaintrect.cy - a * acy; + end + else begin + ay:= fpaintrect.y; + end; + acx:= fbuttonsize; + if fbuttonpos = sbp_left then begin + ax:= fpaintrect.x - acx * b; + end + else begin + ax:= fpaintrect.x + fpaintrect.cx; + end; + end + else begin + acx:= fpaintrect.cx div a; + if acx > fbuttonsize then begin + acx:= fbuttonsize; + end; + if fbuttonslast then begin + ax:= fpaintrect.x; + end + else begin + ax:= fpaintrect.x + fpaintrect.cx - a * acx; + end; + acy:= fbuttonsize; + if fbuttonpos = sbp_top then begin + ay:= fpaintrect.y - acy * b; + end + else begin + ay:= fpaintrect.y + fpaintrect.cy; + end; + end; + color1:= fcolorbutton; + if (color1 = cl_parent) or (color1 = cl_default) then begin + color1:= icaptionframe(fintf).getwidget.actualcolor; + end; + for int1:= 0 to high(fbuttons) do begin + with fbuttons[int1] do begin + ca.imagelist:= stockobjects.glyphs; + if sfs_spinedit in fstepstate then begin + ca.imagenr:= ord(imagesedit[stepkindty(int1)]); + end + else begin + ca.imagenr:= ord(images[stepkindty(int1)]); + end; + imagenrdisabled:= -2; + color:= color1; + ca.colorglyph:= fcolorglyph; + tag:= int1; + doexecute:= {$ifdef FPC}@{$endif}execute; + ca.dim.cx:= acx; + ca.dim.cy:= acy; + end; + end; + fdim.x:= ax; + fdim.y:= ay; + bo1:= fbuttonpos in [sbp_left,sbp_right]; + buttoncount:= 0; + for akind:= low(stepkindty) to high(stepkindty) do begin + if bo2 then begin + if not odd(buttoncount) and (akind <> low(stepkindty)) then begin + if bo1 then begin + ax:= fdim.x; + end + else begin + ay:= fdim.y; + end; + end; + checkbutton(buttonpos1^[fbuttonsinline][fbuttonpos][akind],not odd(buttoncount) xor bo1); + end + else begin + checkbutton(buttonpos1^[fbuttonsinline][fbuttonpos][akind],bo1); + end; + end; + if bo1 then begin //left or right + fdim.cx:= acx * b; + fdim.cy:= acy * a; + end + else begin + fdim.cx:= acx * a; + fdim.cy:= acy * b; + end; + end; + if (buttoncount > 0) or (fneededbuttons <> []) then begin + include(fstepstate,sfs_canstep); + end + else begin + exclude(fstepstate,sfs_canstep); + end; +end; + +procedure tcustomstepframe.updaterects; +begin + updatelayout; + inherited; + updatelayout; +end; + +procedure tcustomstepframe.updatemousestate(const sender: twidget; + const info: mouseeventinfoty); +begin + inherited; + if pointinrect(info.pos,fdim) then begin + with twidget1(sender) do begin + fwidgetstate:= fwidgetstate + [ws_wantmousebutton,ws_wantmousemove]; + end; + end; +end; + +const + stepdirstep: array[stepbuttonposty,boolean] of stepkindty = + //down //up + ((sk_down, sk_up), //sbp_right + (sk_right, sk_left), //sbp_top + (sk_down, sk_up), //sbp_left + (sk_right, sk_left)); //sbp_bottom + stepdirspin: array[boolean] of stepkindty = (sk_down,sk_up); + +procedure tcustomstepframe.domousewheelevent(var info: mousewheeleventinfoty); +var + sk1: stepkindty; +begin + if fmousewheel and (info.wheel <> mw_none) and + not (es_transientfor in info.eventstate)then begin + if sfs_spinedit in fstepstate then begin + sk1:= stepdirspin[info.wheel = mw_up]; + end + else begin + if fneededbuttons = [] then begin + exit; + end; + sk1:= stepdirstep[fbuttonpos][info.wheel = mw_up] + end; + if canstep and fstepintf.dostep(sk1,info.delta,info.shiftstate) then begin + include(info.eventstate,es_processed); + end; + end; +end; + +procedure tcustomstepframe.createbuttonface; +begin + if fbuttonface = nil then begin + fbuttonface:= tface.create(iface(fintf.getwidget)); + end; +end; + +procedure tcustomstepframe.createbuttonframe; +begin + if fbuttonframe = nil then begin + fbuttonframe:= tframe.create(iframe(self)); + end; +end; + +function tcustomstepframe.getbuttonface: tface; +begin + fintf.getwidget.getoptionalobject(fbuttonface, + {$ifdef FPC}@{$endif}createbuttonface); + result:= fbuttonface; +end; + +procedure tcustomstepframe.setbuttonface(const avalue: tface); +begin + fintf.getwidget.setoptionalobject(avalue,fbuttonface, + {$ifdef FPC}@{$endif}createbuttonface); + fintf.invalidatewidget; +end; + +function tcustomstepframe.getbuttonframe: tframe; +begin + fintf.getwidget.getoptionalobject(fbuttonframe, + {$ifdef FPC}@{$endif}createbuttonframe); + result:= fbuttonframe; +end; + +procedure tcustomstepframe.setbuttonframe(const avalue: tframe); +var + int1: integer; +begin + fintf.getwidget.setoptionalobject(avalue,fbuttonframe, + {$ifdef FPC}@{$endif}createbuttonframe); + if fbuttonframe = nil then begin + for int1:= 0 to high(fbuttons) do begin + with fbuttons[int1] do begin + state:= state - [shs_flat,shs_noanimation]; + end; + end; + end; + fintf.invalidatewidget; +end; + +procedure tcustomstepframe.checktemplate(const sender: tobject); +begin + inherited; + if fbuttonface <> nil then begin + fbuttonface.checktemplate(sender); + end; + if fbuttonframe <> nil then begin + fbuttonframe.checktemplate(sender); + end; +end; + +procedure tcustomstepframe.setframeinstance(instance: tcustomframe); +begin + fbuttonframe:= tframe(instance); +end; + +procedure tcustomstepframe.setstaticframe(value: boolean); +begin + //dummy +end; + +function tcustomstepframe.getstaticframe: boolean; +begin + result:= false; +end; + +function tcustomstepframe.getwidgetrect: rectty; +begin + result:= nullrect; +end; + +function tcustomstepframe.getcomponentstate: tcomponentstate; +begin + result:= fintf.getwidget.componentstate; +end; + +function tcustomstepframe.getmsecomponentstate: msecomponentstatesty; +begin + result:= fintf.getwidget.msecomponentstate; +end; + +procedure tcustomstepframe.scrollwidgets(const dist: pointty); +begin + //dummy +end; + +procedure tcustomstepframe.clientrectchanged; +begin + fintf.invalidatewidget; +end; + +procedure tcustomstepframe.invalidate; +begin + fintf.getwidget.invalidaterect(fdim,org_widget); +end; + +procedure tcustomstepframe.invalidatewidget; +begin + fintf.invalidatewidget; +end; + +procedure tcustomstepframe.invalidaterect(const rect: rectty; + const org: originty = org_client; const noclip: boolean = false); +begin + fintf.getwidget.invalidaterect(rect,org,noclip); +end; + +function tcustomstepframe.getwidget: twidget; +begin + result:= fintf.getwidget +end; + +function tcustomstepframe.getframestateflags: framestateflagsty; +begin + result:= shapestatetoframestate(factbuttonindex,fbuttons); +end; + +function tcustomstepframe.canstep: boolean; +begin + result:= sfs_canstep in fstepstate; +end; + +{ tscrollboxscrollbar } + +constructor tscrollboxscrollbar.create(intf: iscrollbar; org: originty; + ondimchanged: proceventty); +begin + inherited; + foptions:= defaultscrollboxscrollbaroptions; +end; + +{ tthumbtrackscrollbar } + +constructor tthumbtrackscrollbar.create(intf: iscrollbar; org: originty; + ondimchanged: proceventty); +begin + inherited; + foptions:= defaultthumbtrackscrollbaroptions; +end; + +{ tthumbtracknopagesizescrollbar } + +constructor tthumbtracknopagesizescrollbar.create(intf: iscrollbar; org: originty; + ondimchanged: proceventty); +begin + inherited; + foptions:= defaultthumbtrackscrollbaroptions; +end; + +{ tcustomscrollboxframe } + +constructor tcustomscrollboxframe.create(const aintf: iscrollframe; + const owner: twidget); +begin + fzoom.re:= 1; + fzoom.im:= 1; + fzoomwidthstep:= 1; + fzoomheightstep:= 1; +// fzoomwheelsensitivity:= 1; + fowner:= owner; + inherited create(aintf,iscrollbox(self)); + fstate:= fstate+ [fs_canclientextendx,fs_canclientextendy]; + initinnerframe; + internalupdatestate; +// options:= defaultscrolloptions; +end; + +procedure tcustomscrollboxframe.initinnerframe; +begin + fi.innerframe.left:= 2; + fi.innerframe.top:= 2; + fi.innerframe.right:= 2; + fi.innerframe.bottom:= 2; +end; + +procedure tcustomscrollboxframe.clientrecttoscrollbar(const rect: rectty); +var + int1: integer; +begin + inc(fscrolling); + with rect do begin + if fstate * [fs_sbhorzon,fs_sbhorzfix] = [fs_sbhorzon] then begin + if cx = 0 then begin + fhorz.pagesize:= 1; + end + else begin + fhorz.pagesize:= fpaintrect.cx/cx; + end; + int1:= cx - fpaintrect.cx; + if int1 = 0 then begin + fhorz.value:= 0; + end + else begin + fhorz.value:= ({fpaintrect.x}-x)/int1; + end; + end; + if fstate * [fs_sbverton,fs_sbvertfix] = [fs_sbverton] then begin + if cy = 0 then begin + fvert.pagesize:= 1; + end + else begin + fvert.pagesize:= fpaintrect.cy/cy; + end; + int1:= cy - fpaintrect.cy; + if int1 = 0 then begin + fvert.value:= 0; + end + else begin + fvert.value:= ({fpaintrect.y}-y)/int1; + end; + end; + end; + dec(fscrolling); +end; + +procedure tcustomscrollboxframe.scrollpostoclientpos(var aclientrect: rectty); +begin + with aclientrect do begin + x:= - round(fhorz.value * (cx-fpaintrect.cx)); + y:= - round(fvert.value * (cy-fpaintrect.cy)); +// inc(x,fpaintrect.x); +// inc(y,fpaintrect.y); + end; +end; + +procedure tcustomscrollboxframe.updatevisiblescrollbars; +begin + updatebit({$ifdef FPC}longword{$else}longword{$endif}(fstate), + ord(fs_sbhorztop),sbo_opposite in fhorz.options); + updatebit({$ifdef FPC}longword{$else}longword{$endif}(fstate), + ord(fs_sbvertleft),sbo_opposite in fvert.options); + updatebit({$ifdef FPC}longword{$else}longword{$endif}(fstate), + ord(fs_sbhorzon),sbo_show in fhorz.options); + updatebit({$ifdef FPC}longword{$else}longword{$endif}(fstate), + ord(fs_sbverton),sbo_show in fvert.options); +end; + +function tcustomscrollboxframe.getwidget: twidget; +begin + result:= fowner; +end; + +procedure tcustomscrollboxframe.calcclientrect(var aclientrect: rectty); + +var + asize: sizety; + statebefore: framestatesty; + int1: integer; + +begin + updatevisiblescrollbars; + updaterects; + inc(fscrolling); + int1:= 0; + repeat + statebefore:= fstate; + asize:= twidget1(fowner).calcminscrollsize; + with asize do begin + if fclientsize.cx <> 0 then begin + cx:= fclientsize.cx; + end; + if fclientsize.cy <> 0 then begin + cy:= fclientsize.cy; + end; + if sbo_showauto in fhorz.options then begin + if cx > fpaintrect.cx then begin + include(fstate,fs_sbhorzon); + end + else begin + exclude(fstate,fs_sbhorzon); + fhorz.value:= 0; + end; + end; + if sbo_showauto in fvert.options then begin + if cy > fpaintrect.cy then begin + include(fstate,fs_sbverton); + end + else begin + exclude(fstate,fs_sbverton); + fvert.value:= 0; + end; + end; + end; + if state = statebefore then begin + break; + end; + updaterects; + inc(int1); + until int1 > 16; //emergency brake + dec(fscrolling); + + aclientrect.size:= asize; + with aclientrect.size do begin + if cx < fpaintrect.cx then begin + cx:= fpaintrect.cx; + end; + if cy < fpaintrect.cy then begin + cy:= fpaintrect.cy; + end; + int1:= fpaintrect.cx {+ fpaintrect.x} - aclientrect.cx - aclientrect.x; + if int1 > 0 then begin + inc(aclientrect.x,int1); + end; + int1:= fpaintrect.cy {+ fpaintrect.y} - aclientrect.cy - aclientrect.y; + if int1 > 0 then begin + inc(aclientrect.y,int1); + end; + end; + clientrecttoscrollbar(aclientrect); +end; + +procedure tcustomscrollboxframe.updateclientrect; +var + rect1: rectty; +begin + rect1:= fclientrect; + calcclientrect(fclientrect); + finnerclientrect:= deflaterect(fclientrect,fi.innerframe); + twidget1(fowner).scroll(subpoint(fclientrect.pos,rect1.pos)); + if (rect1.cx <> fclientrect.cx) or (rect1.cy <> fclientrect.cy) then begin + twidget1(fowner).clientrectchanged; + end; +end; + +function tcustomscrollboxframe.getclientpos: pointty; +begin + checkstate; + result:= fclientrect.pos; +end; + +procedure tcustomscrollboxframe.setclientpos(apos: pointty); +var + pt1: pointty; +begin + if apos.x + fclientrect.cx < fpaintrect.cx then begin + apos.x:= fpaintrect.cx-fclientrect.cx; + end; + if apos.y + fclientrect.cy < fpaintrect.cy then begin + apos.y:= fpaintrect.cy-fclientrect.cy; + end; + if apos.x > 0 then begin + apos.x:= 0; + end; + if apos.y > 0 then begin + apos.y:= 0; + end; + pt1:= subpoint(apos,fclientrect.pos); +// twidget1(fowner).scroll(pt1); + fclientrect.pos:= apos; + addpoint1(finnerclientrect.pos,pt1); + twidget1(fowner).scroll(pt1); +end; + +procedure tcustomscrollboxframe.setscrollpos(apos: pointty); +begin + setclientpos(apos); + clientrecttoscrollbar(fclientrect); +end; + +procedure tcustomscrollboxframe.scrollevent(sender: tcustomscrollbar; + event: scrolleventty); +var + rect1: rectty; +begin + if fscrolling = 0 then begin + if event = sbe_setvalue{valuechanged} then begin + rect1:= fclientrect; + scrollpostoclientpos(rect1); + setclientpos(rect1.pos); +{ + po1:= fclientrect.pos; + scrollpostoclientpos(fclientrect); + po1:= subpoint(fclientrect.pos,po1); + addpoint1(finnerclientrect.pos,po1); + twidget1(fowner).scroll(po1); +} + end; + end; +end; + +procedure tcustomscrollboxframe.dokeydown(var info: keyeventinfoty); +begin + with info do begin + if (oscr_key in foptionsscroll) and not (es_processed in info.eventstate) and + (((shiftstate * shiftstatesmask) - [ss_ctrl]) = []) then begin + include(eventstate,es_processed); + case key of + key_pageup: begin + if ss_ctrl in shiftstate then begin + fvert.value:= 0; + end + else begin + fvert.pagedown; + end; + end; + key_pagedown: begin + if ss_ctrl in shiftstate then begin + fvert.value:= 1; + end + else begin + fvert.pageup; + end; + end; + else begin + exclude(eventstate,es_processed); + end; + end; + if ss_ctrl in shiftstate then begin + include(eventstate,es_processed); + case key of + key_right: begin + fhorz.stepup; + end; + key_left: begin + fhorz.stepdown; + end; + key_down: begin + fvert.stepup; + end; + key_up: begin + fvert.stepdown; + end; + else begin + exclude(eventstate,es_processed); + end; + end; + end; + end; + end; +end; + +function tcustomscrollboxframe.translatecolor(const acolor: colorty): colorty; +begin + result:= fowner.translatecolor(acolor); +end; + +procedure tcustomscrollboxframe.invalidaterect(const rect: rectty; + const org: originty; const noclip: boolean = false); +begin + fowner.invalidaterect(rect,org,noclip); +end; + +function tcustomscrollboxframe.getscrollsize: sizety; +begin + checkstate; + result:= fclientrect.size; +end; + +procedure tcustomscrollboxframe.setclientsize(const avalue: sizety); +begin + if (fclientsize.cx <> avalue.cx) or (fclientsize.cy <> avalue.cy) then begin + fclientsize:= avalue; + if fclientsize.cx < 0 then begin + fclientsize.cx:= 0; + end; + if fclientsize.cy < 0 then begin + fclientsize.cy:= 0; + end; + internalupdatestate; + end; +end; + +procedure tcustomscrollboxframe.setclientwidth(const avalue: integer); +begin + setclientsize(ms(avalue,fclientsize.cy)); +end; + +procedure tcustomscrollboxframe.setclientheight(const avalue: integer); +begin + setclientsize(ms(fclientsize.cx,avalue)); +end; + +procedure tcustomscrollboxframe.setclientsizemin(const avalue: sizety); +begin + if (fclientsizemin.cx <> avalue.cx) or + (fclientsizemin.cy <> avalue.cy) then begin + fclientsizemin:= avalue; + if fclientsizemin.cx < 0 then begin + fclientsizemin.cx:= 0; + end; + if fclientsizemin.cy < 0 then begin + fclientsizemin.cy:= 0; + end; + internalupdatestate; + end; +end; + +procedure tcustomscrollboxframe.setclientwidthmin(const avalue: integer); +begin + setclientsizemin(ms(avalue,fclientsizemin.cy)); +end; + +procedure tcustomscrollboxframe.setclientheightmin(const avalue: integer); +begin + setclientsizemin(ms(fclientsizemin.cx,avalue)); +end; + +procedure tcustomscrollboxframe.showrect(const arect: rectty; + const bottomright: boolean); +var + scrollvalue: pointty; +// po1: pointty; + int1: integer; + + procedure adjuststart; + begin + int1:= fclientrect.x + scrollvalue.x + arect.x; + if int1 < 0 then begin + dec(scrollvalue.x,int1); + end; + int1:= fclientrect.x + scrollvalue.x; + if int1 > 0 then begin + dec(scrollvalue.x,int1); + end; + int1:= fclientrect.y + scrollvalue.y + arect.y; + if int1 < 0 then begin + dec(scrollvalue.y,int1); + end; + int1:= fclientrect.y + scrollvalue.y; + if int1 > 0 then begin + dec(scrollvalue.y,int1); + end; + end; + + procedure adjustend; + begin + int1:= fclientrect.x + scrollvalue.x + arect.x + arect.cx - fpaintrect.cx; + if int1 > 0 then begin + dec(scrollvalue.x,int1); + end; + int1:= fclientrect.x + scrollvalue.x + fclientrect.cx - fpaintrect.cx; + if int1 < 0 then begin + dec(scrollvalue.x,int1); + end; + int1:= fclientrect.y + scrollvalue.y + arect.y + arect.cy - fpaintrect.cy; + if int1 > 0 then begin + dec(scrollvalue.y,int1); + end; + int1:= fclientrect.y + scrollvalue.y + fclientrect.cy - fpaintrect.cy; + if int1 < 0 then begin + dec(scrollvalue.y,int1); + end; + end; + +begin + scrollvalue:= nullpoint; + checkstate; +// po1:= addpoint(fclientrect.pos,arect.pos); + if bottomright then begin + adjuststart; + adjustend; + end + else begin + adjustend; + adjuststart; + end; + if (scrollvalue.y <> 0) or (scrollvalue.x <> 0) then begin + addpoint1(fclientrect.pos,scrollvalue); + addpoint1(finnerclientrect.pos,scrollvalue); + twidget1(fowner).scroll(scrollvalue); + clientrecttoscrollbar(fclientrect); + end; +end; + +function tcustomscrollboxframe.getscrollbarclass( + vert: boolean): framescrollbarclassty; +begin + result:= tscrollboxscrollbar; +end; + +procedure tcustomscrollboxframe.setsbhorz(const avalue: tscrollboxscrollbar); +begin + inherited setsbhorz(avalue); +end; + +function tcustomscrollboxframe.getsbhorz: tscrollboxscrollbar; +begin + result:= tscrollboxscrollbar(inherited sbhorz); +end; + +procedure tcustomscrollboxframe.setsbvert(const avalue: tscrollboxscrollbar); +begin + inherited setsbvert(avalue); +end; + +function tcustomscrollboxframe.getsbvert: tscrollboxscrollbar; +begin + result:= tscrollboxscrollbar(inherited sbvert); +end; + +procedure tcustomscrollboxframe.updatemousestate(const sender: twidget; + const info: mouseeventinfoty); +begin + inherited; + with twidget1(sender) do begin + if fdragging then begin + fwidgetstate:= fwidgetstate + [ws_wantmousemove,ws_wantmousebutton]; + end + else begin + if (oscr_drag in foptionsscroll) and isdragstart(sender,info) then begin + include(fwidgetstate,ws_wantmousebutton); + end; + end; + end; +end; + +procedure tcustomscrollboxframe.childmouseevent(const sender: twidget; + var info: mouseeventinfoty); +var + po1: pointty; +begin + with info do begin + if not (es_processed in eventstate) then begin + po1:= translatewidgetpoint(pos,sender,fowner); + if fdragging then begin + case eventkind of + ek_mouseleave,ek_buttonrelease: begin + application.cursorshape:= cr_default; + fowner.releasemouse; + fdragging:= false; + include(eventstate,es_processed); + end; + ek_mousemove: begin + showrect(makerect(subpoint(subpoint(fpickpos,po1),fpickref), + fclientrect.size),false); + include(eventstate,es_processed); + end; + end; + end + else begin + if isdragstart(sender,info) then begin + fowner.capturemouse; + fpickpos:= po1; + fpickref:= fclientrect.pos; + application.cursorshape:= cr_sizeall; + fdragging:= true; + include(eventstate,es_processed); + end; + end; + end; + end; +end; + +function tcustomscrollboxframe.isdragstart(const sender: twidget; + const info: mouseeventinfoty): boolean; +var + ss1: shiftstatesty; +begin + with info do begin + ss1:= (shiftstate*buttonshiftstatesmask)*fdragbuttons; + result:= (oscr_drag in foptionsscroll) and + (eventkind = ek_buttonpress) and (ss1 <> []) and + pointinrect(translatewidgetpoint(pos,sender,fowner),fpaintrect) and + ((fclientrect.cx <> fpaintrect.cx) or + (fclientrect.cy <> fpaintrect.cy)); + end; + if result and not ((ss1 = [ss_middle]) or (sender = fowner)) then begin + twidget1(sender).updatemousestate(info); + result:= not (ws_wantmousebutton in twidget1(sender).fwidgetstate); + end; +end; + +procedure tcustomscrollboxframe.checkminscrollsize(var asize: sizety); +begin + inherited; + if (clientwidthmin > 0) and (clientwidthmin > asize.cx) then begin + asize.cx:= clientwidthmin; + end; + if (clientheightmin > 0) and (clientheightmin > asize.cy) then begin + asize.cy:= clientheightmin; + end; +end; + +procedure tcustomscrollboxframe.checkminclientsize(var asize: sizety); +begin + if clientwidth <> 0 then begin + asize.cx:= clientwidth; + end; + if clientheight <> 0 then begin + asize.cy:= clientheight; + end; + inherited; +end; + +procedure tcustomscrollboxframe.setzoom1(const avalue: complexty); +var + size1: sizety; +begin + fzoom:= avalue; + if fzoom.re < 1 then begin + fzoom.re:= 1; + end; + if fzoom.im < 1 then begin + fzoom.im:= 1; + end; + checkstate; + size1:= nullsize; + with fpaintframedelta do begin + if avalue.re > 1 then begin + size1.cx:= round((fpaintrect.cx+left+right)*avalue.re); + //do not use scrollbarwidth + end; + if avalue.im > 1 then begin + size1.cy:= round((fpaintrect.cy+top+bottom)*avalue.im); + //do not use scrollbarwidth + end; + end; + fclientsize:= size1; +end; + +procedure tcustomscrollboxframe.setzoom(const avalue: complexty); +begin + setzoom1(avalue); + internalupdatestate; +end; + +procedure tcustomscrollboxframe.setzoomwidth(const avalue: real); +begin + setzoom(makecomplex(avalue,fzoom.im)); +end; + +procedure tcustomscrollboxframe.setzoomheight(const avalue: real); +begin + setzoom(makecomplex(fzoom.re,avalue)); +end; + +function tcustomscrollboxframe.getscrollpos_x: integer; +begin + result:= getclientpos.x; +end; + +procedure tcustomscrollboxframe.setscrollpos_x(const avalue: integer); +begin + setscrollpos(makepoint(avalue,getclientpos.y)); +end; + +function tcustomscrollboxframe.getscrollpos_y: integer; +begin + result:= getclientpos.y; +end; + +procedure tcustomscrollboxframe.setscrollpos_y(const avalue: integer); +begin + setscrollpos(makepoint(getclientpos.x,avalue)); +end; + +procedure tcustomscrollboxframe.domousewheelevent(var info: mousewheeleventinfoty; + const pagingreversed: boolean); +var + size1: sizety; + pt1,pt2: pointty; + co1: complexty; + bo1: boolean; + ma1: shiftstatesty; + rea1: real; + fra1: framety; +begin + with info do begin + if not (es_processed in eventstate) then begin + if (oscr_mousewheel in foptionsscroll) and (ss_ctrl in shiftstate) and + (foptionsscroll*[oscr_zoomwidth,oscr_zoomheight] <> []) then begin + ma1:= shiftstatesmask - [ss_ctrl]; + if foptionsscroll*[oscr_zoomwidth,oscr_zoomheight] = + [oscr_zoomwidth,oscr_zoomheight] then begin + ma1:= ma1 - [ss_alt,ss_shift]; + end; + if shiftstate * ma1 = [] then begin + include(eventstate,es_processed); + size1:= fclientrect.size; + co1:= fzoom; + bo1:= false; + rea1:= 1 + (abs(delta) - application.mousewheeldeltamin)* + fzoomwheelsensitivity*application.mousewheeldeltamin; + if (fzoomwidthstep <> 1) and (fzoomwidthstep > 0) and + (oscr_zoomwidth in foptionsscroll) and + not (ss_shift in shiftstate) then begin + bo1:= true; + if wheel = mw_down then begin + co1.re:= zoomwidth / (fzoomwidthstep*rea1); + end + else begin + co1.re:= zoomwidth * (fzoomwidthstep*rea1); + end; + end; + if (fzoomheightstep <> 1) and (fzoomheightstep > 0) and + (oscr_zoomheight in foptionsscroll) and + not (ss_alt in shiftstate) then begin + bo1:= true; + if wheel = mw_down then begin + co1.im:= zoomheight / (fzoomheightstep*rea1); + end + else begin + co1.im:= zoomheight * (fzoomheightstep*rea1); + end; + end; + if bo1 then begin + setzoom1(co1); + pt1:= fclientrect.pos; + fra1:= iscrollframe(fintf).getzoomrefframe; + with fra1 do begin + size1.cx:= size1.cx - left - right; + size1.cy:= size1.cy - top - bottom; + if size1.cx > 0 then begin + pt1.x:= info.pos.x - fpaintrect.x - left - + round((info.pos.x - fpaintrect.x - fclientrect.x - left)* + (fclientsize.cx-left-right)/size1.cx); + end; + if size1.cy > 0 then begin + pt1.y:= info.pos.y - fpaintrect.y - top - + round((info.pos.y - fpaintrect.y - fclientrect.y - top)* + (fclientsize.cy-top-bottom)/size1.cy); + end; + end; + { + pt1:= nullpoint; + with pt2 do begin + x:= info.pos.x-fpaintrect.x; + if x < 0 then begin + x:= 0; + end; + if x > fpaintrect.cx then begin + x:= fpaintrect.cx; + end; + x:= x - fclientrect.x; + y:= info.pos.y-fpaintrect.y; + if y < 0 then begin + y:= 0; + end; + if y > fpaintrect.cy then begin + y:= fpaintrect.cy; + end; + y:= y - fclientrect.y; + end; + if (size1.cx > 0) and (fclientsize.cx > 0) then begin + pt1.x:= -round(pt2.x*((fclientsize.cx/size1.cx)-1.0)); + end; + if (size1.cy > 0) and (fclientsize.cy > 0) then begin + pt1.y:= -round(pt2.y*((fclientsize.cy/size1.cy)-1.0)); + end; +// setscrollpos(addpoint(fclientrect.pos,pt1)); +} + pt2:= fclientrect.pos; + fclientrect.pos:= pt1; + if fclientrect.x > 0 then begin + fclientrect.x:= 0; + end; + if fclientrect.y > 0 then begin + fclientrect.y:= 0; + end; + fowner.scrollwidgets(subpoint(fclientrect.pos,pt2)); + internalupdatestate; + end; + end; + end + else begin + inherited; + end; + end; + end; +end; + +procedure tcustomscrollboxframe.readzoomwidthstep(reader: treader); +begin + zoomwidthstep:= reader.readfloat; +end; + +procedure tcustomscrollboxframe.writezoomwidthstep(writer: twriter); +begin + writer.writefloat(zoomwidthstep); +end; + +procedure tcustomscrollboxframe.readzoomheightstep(reader: treader); +begin + zoomheightstep:= reader.readfloat; +end; + +procedure tcustomscrollboxframe.writezoomheightstep(writer: twriter); +begin + writer.writefloat(zoomheightstep); +end; + +procedure tcustomscrollboxframe.readzoomwheelsensitivity(reader: treader); +begin + zoomwheelsensitivity:= reader.readfloat; +end; + +procedure tcustomscrollboxframe.writezoomwheelsensitivity(writer: twriter); +begin + writer.writefloat(zoomwheelsensitivity); +end; + +procedure tcustomscrollboxframe.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('zoomwidthstep',@readzoomwidthstep,@writezoomwidthstep, + (filer.ancestor = nil) and (fzoomwidthstep <> 1) or + (filer.ancestor <> nil) and + (tcustomscrollboxframe(filer.ancestor).fzoomwidthstep <> fzoomwidthstep)); + filer.defineproperty('zoomheightstep',@readzoomheightstep,@writezoomheightstep, + (filer.ancestor = nil) and (fzoomheightstep <> 1) or + (filer.ancestor <> nil) and + (tcustomscrollboxframe(filer.ancestor).fzoomheightstep <> fzoomheightstep)); + filer.defineproperty('zoomwheelsensitivity', + @readzoomwheelsensitivity,@writezoomwheelsensitivity, + (filer.ancestor = nil) and (fzoomwheelsensitivity <> 0) or + (filer.ancestor <> nil) and + (tcustomscrollboxframe(filer.ancestor).fzoomwheelsensitivity <> + fzoomwheelsensitivity)); +end; + +{ tcustomautoscrollframe } + +constructor tcustomautoscrollframe.create(const aintf: iscrollframe; + const owner: twidget; const autoscrollintf: iautoscrollframe); +begin + fintf1:= autoscrollintf; + inherited create(aintf,owner); +end; + +function tcustomautoscrollframe.getscrollpos: pointty; +begin + result:= fintf1.getscrollrect.pos; +end; + +procedure tcustomautoscrollframe.setscrollpos(const avalue: pointty); +var + rect1: rectty; +begin + rect1:= fintf1.getscrollrect; + if (rect1.x <> avalue.x) or (rect1.y <> avalue.y) then begin + rect1.pos:= avalue; + with rect1 do begin + if x + cx < fpaintrect.cx then begin + x:= fpaintrect.cx - rect1 .cx; + end; + if x > 0{fpaintrect.x} then begin + x:= 0{fpaintrect.x}; + end; + if y + cy < fpaintrect.cy then begin + y:= fpaintrect.cy - cy; + end; + if y > 0{fpaintrect.y} then begin + y:= 0{fpaintrect.y}; + end; + end; + clientrecttoscrollbar(rect1); + fintf1.setscrollrect(rect1); + end; +end; + +function tcustomautoscrollframe.getscrollpos_x: integer; +begin + result:= getscrollpos.x; +end; + +procedure tcustomautoscrollframe.setscrollpos_x(const avalue: integer); +begin + setscrollpos(makepoint(avalue,getscrollpos.y)); +end; + +function tcustomautoscrollframe.getscrollpos_y: integer; +begin + result:= getscrollpos.y; +end; + +procedure tcustomautoscrollframe.setscrollpos_y(const avalue: integer); +begin + setscrollpos(makepoint(getscrollpos.x,avalue)); +end; + +procedure tcustomautoscrollframe.scrollevent(sender: tcustomscrollbar; + event: scrolleventty); +var + rect1: rectty; +begin + if fscrolling = 0 then begin + if event = sbe_valuechanged then begin + rect1:= fintf1.getscrollrect; + scrollpostoclientpos(rect1); + fintf1.setscrollrect(rect1); + end + else begin + fintf1.scrollevent(sender,event); + end; + end; +end; + +procedure tcustomautoscrollframe.updaterects; +begin + inherited; + fclientrect.pos:= nullpoint; + fclientrect.size:= fpaintrect.size; + finnerclientrect:= deflaterect(fclientrect,fi.innerframe); +end; + +procedure tcustomautoscrollframe.updateclientrect; +var + rect1: rectty; +begin + rect1:= fintf1.getscrollrect; + calcclientrect(rect1); + fintf1.setscrollrect(rect1); +end; + + +{ tactionwidget } + +procedure tactionwidget.updatepopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); +begin + if (fpopupmenu <> nil) and not ((es_child in mouseinfo.eventstate) and + (mo_noinsert in fpopupmenu.options)) then begin + tpopupmenu.additems(amenu,self,mouseinfo,fpopupmenu); + amenu.menu.caption:= fpopupmenu.menu.caption; //for tassistivehandler + end; +end; + +procedure tactionwidget.dopopup(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); + procedure doparent(const after: boolean); + var + widget1: twidget; + bo1: boolean; + begin + if (fpopupmenu = nil) or not (mo_stopinsert in fpopupmenu.options) then begin + widget1:= fparentwidget; + while widget1 <> nil do begin + if widget1 is tactionwidget then begin + translateclientpoint1(mouseinfo.pos,self,widget1); + bo1:= not (es_child in mouseinfo.eventstate); + include(mouseinfo.eventstate,es_child); + try + if after then begin + tactionwidget(widget1).doafterpopupmenu(amenu,mouseinfo); + end + else begin + tactionwidget(widget1).dopopup(amenu,mouseinfo); + end; + finally + if bo1 then begin + exclude(mouseinfo.eventstate,es_child); + end; + translateclientpoint1(mouseinfo.pos,widget1,self); + end; + break; + end; + widget1:= twidget1(widget1).fparentwidget; + end; + end; + end; //doparent() + +var + menu1: tpopupmenu; + +begin + menu1:= amenu; + try + updatepopupmenu(amenu,mouseinfo); + if canevent(tmethod(fonpopup)) then begin + fonpopup(self,amenu,mouseinfo); + end; + if not (es_parent in mouseinfo.eventstate) then begin + doparent(false); + if (amenu <> nil) and + (mouseinfo.eventstate * [es_processed,es_child] = []) then begin + amenu.show(self,mouseinfo); + doafterpopupmenu(amenu,mouseinfo); + doparent(true); + end; + end; + finally + if not (es_child in mouseinfo.eventstate) then begin + if amenu <> menu1 then begin + freetransientmenu(tcustommenu(menu1)); //if amenu overwritten + end; + freetransientmenu(tcustommenu(amenu)); + end; + end; +end; + +procedure tactionwidget.mouseevent(var info: mouseeventinfoty); +begin + if canevent(tmethod(fonmouseevent)) then begin + fonmouseevent(self,info); + end; + inherited; +end; + +procedure tactionwidget.clientmouseevent(var info: mouseeventinfoty); +var + dummy: tpopupmenu; + po1: pointty; +begin + if canevent(tmethod(fonclientmouseevent)) then begin + fonclientmouseevent(self,info); + end; + inherited; + with info do begin + if (eventkind = ek_buttonrelease) and (ws_rclicked in fwidgetstate) and + not (csdesigning in componentstate) and + (eventstate * [es_processed,es_child] = []) and + (button = mb_right) then begin + dummy:= nil; + po1:= pos; + dopopup(dummy,info); + pos:= po1; //no mousemove by change of popup pos + end; + end; +end; + +procedure tactionwidget.childmouseevent(const sender: twidget; + var info: mouseeventinfoty); +begin + if canevent(tmethod(fonchildmouseevent)) then begin + fonchildmouseevent(sender,info); + end; + inherited; +end; + +procedure tactionwidget.domousewheelevent(var info: mousewheeleventinfoty); +begin + if canevent(tmethod(fonmousewheelevent)) then begin + fonmousewheelevent(self,info); + end; + inherited; +end; + +procedure tactionwidget.dobeforepaint(const canvas: tcanvas); +var + pt1: pointty; +begin + inherited; +// canvas.font:= getfont; + if canevent(tmethod(fonbeforepaint)) then begin + pt1:= clientwidgetpos; + canvas.move(pt1); + fonbeforepaint(self,canvas); + canvas.remove(pt1); + end; +end; + +procedure tactionwidget.doonpaintbackground(const canvas: tcanvas); +begin + inherited; + if canevent(tmethod(fonpaintbackground)) then begin + fonpaintbackground(self,canvas); + end; +end; + +procedure tactionwidget.doonpaint(const canvas: tcanvas); +begin + inherited; + if canevent(tmethod(fonpaint)) then begin + fonpaint(self,canvas); + end; +end; + +procedure tactionwidget.doafterpaint(const canvas: tcanvas); +var + pt1: pointty; +begin + inherited; + if canevent(tmethod(fonafterpaint)) then begin + pt1:= clientwidgetpos; + canvas.move(pt1); + fonafterpaint(self,canvas); + canvas.remove(pt1); + end; +end; + +procedure tactionwidget.doonkeydown(var info: keyeventinfoty); +begin + if not (ws1_onkeydowncalled in fwidgetstate1) then begin + include(fwidgetstate1,ws1_onkeydowncalled); + if canevent(tmethod(fonkeydown)) then begin + fonkeydown(self,info); + end; + end; +end; + +procedure tactionwidget.dokeydown(var info: keyeventinfoty); +var + dummy: tpopupmenu; + mouseinfo: mouseeventinfoty; +begin + if not (es_processed in info.eventstate) then begin + doonkeydown(info); + end; + with info do begin + if (key = key_menu) and (shiftstate = []) and + not(es_processed in eventstate) then begin + dummy:= nil; + fillchar(mouseinfo,sizeof(mouseinfo),0); + with mouseinfo do begin + with application.caret do begin + if active then begin + mouseinfo.pos:= pos; + mouseinfo.pos.y:= mouseinfo.pos.y + height; + end + else begin + mouseinfo.pos:= rectcenter(clippedpaintrect); + end; + end; + getpopuppos(pos); + button:= mb_none; + end; + dummy:= nil; + dopopup(dummy,mouseinfo); + if not (es_processed in mouseinfo.eventstate) then begin + inherited; + end; + end + else begin + inherited; + end; + end; +end; + +procedure tactionwidget.dokeyup(var info: keyeventinfoty); +begin + if not (es_processed in info.eventstate) and canevent(tmethod(fonkeyup)) then begin + fonkeyup(self,info); + end; + inherited; +end; + +procedure tactionwidget.showhint(const aid: int32; var info: hintinfoty); +begin + inherited; + if canevent(tmethod(fonshowhint)) then begin + fonshowhint(self,info); + end; +end; + +procedure tactionwidget.internalcreateframe; +begin + tcaptionframe.create(iscrollframe(self)); +end; + +procedure tactionwidget.enabledchanged; +begin + inherited; + if (fframe <> nil) and + (tcustomcaptionframe(fframe).finfo.text.text <> '') then begin + invalidatewidget; + end; +end; + +function tactionwidget.getframe: tcaptionframe; +begin + result:= tcaptionframe(inherited getframe); +end; + +procedure tactionwidget.setframe(const value: tcaptionframe); +begin + inherited setframe(value); +end; + +function tactionwidget.getface: tface; +begin + result:= tface(inherited getface); +end; + +procedure tactionwidget.setface(const Value: tface); +begin + inherited setface(value); +end; + +procedure tactionwidget.setpopupmenu(const Value: tpopupmenu); +begin + setlinkedvar(value,tmsecomponent(fpopupmenu)); +end; + +procedure tactionwidget.poschanged; +begin + inherited; + if canevent(tmethod(fonmove)) then begin + fonmove(self); + end; +end; + +procedure tactionwidget.sizechanged; +begin + inherited; + if canevent(tmethod(fonresize)) then begin + fonresize(self); + end; +end; + +procedure tactionwidget.doloaded; +begin + inherited; + if canevent(tmethod(fonloaded)) then begin + fonloaded(self); + end; +end; + +procedure tactionwidget.doenter; +begin + inherited; + if canevent(tmethod(fonenter)) then begin + fonenter(self); + end; +end; + +procedure tactionwidget.doexit; +begin + inherited; + if canevent(tmethod(fonexit)) then begin + fonexit(self); + end; +end; + +function tactionwidget.canclose(const newfocus: twidget): boolean; +begin + result:= inherited canclose(newfocus); + if result and assigned(fonclosequery) then begin + fonclosequery(self,result); + end; +end; + +procedure tactionwidget.dofocus; +begin + inherited; + if canevent(tmethod(fonfocus)) then begin + fonfocus(self); + end; +end; + +procedure tactionwidget.dodefocus; +begin + inherited; + if canevent(tmethod(fondefocus)) then begin + fondefocus(self); + end; +end; + +procedure tactionwidget.dofocuschanged(const oldwidget: twidget; + const newwidget: twidget); +begin + inherited; + if canevent(tmethod(fonfocusedwidgetchanged)) and + (checkdescendent(oldwidget) or checkdescendent(newwidget)) then begin + fonfocusedwidgetchanged(oldwidget,newwidget); + end; +end; + +procedure tactionwidget.doactivate; +begin + inherited; + if canevent(tmethod(fonactivate)) and + ((ow1_modalcallonactivate in foptionswidget1) or + not (tws_modalcalling in twindow1(window).fstate)) then begin + fonactivate(self); + end; +end; + +procedure tactionwidget.dodeactivate; +begin + inherited; + if canevent(tmethod(fondeactivate)) and + ((ow1_modalcallondeactivate in foptionswidget1) or + not (tws_modalcalling in twindow1(window).fstate)) then begin + fondeactivate(self); + end; +end; + +procedure tactionwidget.dohide; +begin + if canevent(tmethod(fonhide)) then begin + fonhide(self); + end; + inherited; +// include(fwidgetstate,ws_hidden); +// exclude(fwidgetstate,ws_showed); +end; + +procedure tactionwidget.doshow; +begin +// inherited; + if canevent(tmethod(fonshow)) then begin + fonshow(self); + end; + inherited; +// include(fwidgetstate,ws_showed); +// exclude(fwidgetstate,ws_hidden); +end; + + +procedure tactionwidget.getpopuppos(var apos: pointty); +begin + //dummy +end; + +procedure tactionwidget.doshortcut(var info: keyeventinfoty; + const sender: twidget); +begin + if not (es_processed in info.eventstate) and canevent(tmethod(fonshortcut)) then begin + fonshortcut(self,info,sender); + end; + if (fpopupmenu <> nil) and (sender <> nil) //no broadcast + and not(csdesigning in componentstate) then begin + fpopupmenu.doshortcut(info); + end; + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +procedure tactionwidget.receiveevent(const event: tobjectevent); +begin + if canevent(tmethod(fonevent)) then begin + fonevent(self,event); + end; + inherited; +end; + +procedure tactionwidget.componentevent(const event: tcomponentevent); +begin + if canevent(tmethod(foncomponentevent)) then begin + foncomponentevent(self,event); + end; + inherited; +end; + +procedure tactionwidget.doasyncevent(var atag: integer); +begin + if canevent(tmethod(fonasyncevent)) then begin + fonasyncevent(self,atag); + end; + inherited; +end; + +procedure tactionwidget.doafterpopupmenu(var amenu: tpopupmenu; + var mouseinfo: mouseeventinfoty); +begin + //dummy +end; + +{ ttoplevelwidget } + +constructor ttoplevelwidget.create(aowner: tcomponent); +begin + inherited; + visible:= false; + foptionswidget:= defaultoptionstoplevelwidget; + optionsskin:= defaultcontainerskinoptions; +// fcolor:= cl_background; +end; + +{ tcaptionwidget } + +function tcaptionwidget.getcaption: msestring; +begin + result:= fcaption; +end; + +procedure tcaptionwidget.setcaption(const Value: msestring); +begin + fcaption := Value; + if (fwindow <> nil) and (fwindow.winid <> 0) then begin + gui_setwindowcaption(fwindow.winid,fcaption); + end; +end; + +procedure tcaptionwidget.windowcreated; +begin + inherited; + if fcaption <> '' then begin + caption:= fcaption; //set windowcaption + end; +end; + +function tcaptionwidget.getassistivecaption(): msestring; +begin + result:= getcaption(); +end; + +{ tscrollface } + +procedure tscrollface.internalpaint(const canvas: tcanvas; const rect: rectty); +begin + inherited internalpaint(canvas,fintf.getclientrect); +end; + +{ tscrollingwidgetnwr } + +constructor tscrollingwidgetnwr.create(aowner: tcomponent); +begin + inherited; + include(fwidgetstate1,ws1_designactive); + foptionswidget:= defaultoptionswidgetmousewheel; + optionsskin:= defaultcontainerskinoptions; + internalcreateframe; + setstaticframe(true); +end; + +procedure tscrollingwidgetnwr.internalcreateframe; +begin + tscrollboxframe.create(iscrollframe(self),self); +end; + +function tscrollingwidgetnwr.getframe: tscrollboxframe; +begin + result:= tscrollboxframe(pointer(inherited getframe)); +end; + +procedure tscrollingwidgetnwr.setframe(const Value: tscrollboxframe); +begin + inherited setframe(tcaptionframe(pointer(value))); +end; + +procedure tscrollingwidgetnwr.mouseevent(var info: mouseeventinfoty); +begin + inherited; + if not (es_processed in info.eventstate) then begin + tscrollframe(fframe).mouseevent(info); + end; +end; + +procedure tscrollingwidgetnwr.childmouseevent(const sender: twidget; + var info: mouseeventinfoty); +//var +// po1: pointty; +begin + frame.childmouseevent(sender,info); + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +procedure tscrollingwidgetnwr.domousewheelevent(var info: mousewheeleventinfoty); +begin + inherited; + if not (es_processed in info.eventstate) then begin + tscrollframe(fframe).domousewheelevent(info,false); + end; +end; + +procedure tscrollingwidgetnwr.doscroll(const dist: pointty); +begin + inherited; + if canevent(tmethod(fonscroll)) then begin + fonscroll(self,dist); + end; +end; + +procedure tscrollingwidgetnwr.doscrolled(const dist: pointty); +begin + inherited; + if canevent(tmethod(fonscroll)) then begin + fonscroll(self,dist); + end; +end; + +procedure tscrollingwidgetnwr.widgetregionchanged(const sender: twidget); +begin + inherited; + if ((sender = nil) or + not (ws1_anchorsizing in twidget1(sender).fwidgetstate1)) and + not (ws_destroying in fwidgetstate) and + (componentstate*[csloading,csdestroying] = []) then begin + tcustomscrollboxframe(fframe).updateclientrect; + end; +// else begin +// tscrollboxframe(fframe).updatestate; ww +// end; +end; + +procedure tscrollingwidgetnwr.writestate(writer: twriter); +begin + frame.sbhorz.value:= 0; + frame.sbvert.value:= 0; + inherited; +end; + +procedure tscrollingwidgetnwr.internalcreateface; +begin + tscrollface.create(twidget(self)); +end; + +procedure tscrollingwidgetnwr.sizechanged; +begin + inherited; + tcustomscrollboxframe(fframe).updatestate; +// tcustomscrollboxframe(fframe).updateclientrect; + //set endresult of autosizing +end; + +procedure tscrollingwidgetnwr.minscrollsizechanged; +begin + tcustomscrollboxframe(fframe).updatestate; +end; + +function tscrollingwidgetnwr.calcminscrollsize: sizety; +begin + result:= inherited calcminscrollsize; + if result.cx < fminclientsize.cx then begin + result.cx:= fminclientsize.cx; + end; + if result.cy < fminclientsize.cy then begin + result.cy:= fminclientsize.cy; + end; +// result:= inherited calcminscrollsize; + if checkcanevent(owner,tmethod(foncalcminscrollsize)) then begin + foncalcminscrollsize(self,result); + end; +end; + +procedure tscrollingwidgetnwr.setclientsize(const asize: sizety); +begin + with tcustomscrollboxframe(fframe) do begin + fminclientsize:= fminminclientsize; + if (asize.cx > fclientrect.cx) then begin + fminclientsize.cx:= asize.cx; + end; + if (asize.cy > fclientrect.cy) then begin + fminclientsize.cy:= asize.cy; + end; + if (fminclientsize.cx > 0) or (fminclientsize.cy > 0) then begin + updatestate; + fminclientsize:= fminminclientsize; + end; + end; +end; + +procedure tscrollingwidgetnwr.dolayout(const sender: twidget); +begin + if canevent(tmethod(fonlayout)) then begin + fonlayout(self); + end + else begin + inherited; + end; +end; + +procedure tscrollingwidgetnwr.loaded; +begin + inherited; + if canevent(tmethod(fonlayout)) then begin + postchildscaled; + end; +end; + +procedure tscrollingwidgetnwr.dofontheightdelta(var delta: integer); +begin + if canevent(tmethod(fonfontheightdelta)) then begin + fonfontheightdelta(self,delta); + end; + inherited; +end; + +procedure tscrollingwidgetnwr.clampinview(const arect: rectty; const bottomright: boolean); +begin + updateroot; + frame.showrect(removerect(arect,clientpos),bottomright); + inherited; +// frame.showrect(removerect(arect,clientwidgetpos)); +// frame.showrect(arect); +end; + +function tscrollingwidgetnwr.maxclientsize: sizety; +begin + result:= makesize(bigint,bigint); +end; +{ +procedure tscrollingwidgetnwr.setclientpos(const avalue: pointty); +begin + frame.showrect(makerect(avalue,paintsize),false); +end; +} +procedure tscrollingwidgetnwr.readonchildscaled(reader: treader); +begin + onlayout:= notifyeventty(readmethod(reader)); +end; + +procedure tscrollingwidgetnwr.defineproperties(filer: tfiler); +begin + inherited; + filer.defineproperty('onchildscaled',{$ifdef FPC}@{$endif}readonchildscaled, + nil,false) +end; + +{ tscrollbarwidget } + +constructor tscrollbarwidget.create(aowner: tcomponent); +begin + inherited; + internalcreateframe; +end; + +procedure tscrollbarwidget.internalcreateframe; +begin + tscrollframe.create(self,iscrollbar(self)); +end; + +function tscrollbarwidget.getframe: tscrollframe; +begin + result:= tscrollframe(pointer(inherited getframe)); +end; + +procedure tscrollbarwidget.setframe(const Value: tscrollframe); +begin + inherited setframe(tcaptionframe(pointer(value))); +end; + +procedure tscrollbarwidget.scrollevent(sender: tcustomscrollbar; + event: scrolleventty); +begin + //dummy +end; + +procedure tscrollbarwidget.mouseevent(var info: mouseeventinfoty); +begin + tscrollframe(fframe).mouseevent(info); + inherited; +end; + +{ tpopupwidget } + +function tpopupwidget.getassistiveflags(): assistiveflagsty; +begin + result:= inherited getassistiveflags(); + if ownswindow then begin + result:= result + [asf_popup]; + end; +end; + +constructor tpopupwidget.create(aowner: tcomponent; transientfor: twindow); +begin + inherited create(aowner); + if transientfor <> nil then begin + getobjectlinker.setlinkedvar(ievent(self),transientfor,tlinkedobject(ftransientfor)); + end; + window.localshortcuts:= true; +end; + +function tpopupwidget.internalshow(const modallevel: modallevelty; + const transientfor: pwindow; + const windowevent,transientforshow: boolean): modalresultty; +begin + if transientfor^ = nil then begin + result:= inherited internalshow(modallevel,@ftransientfor,windowevent, + transientforshow); + end + else begin + result:= inherited internalshow(modallevel,transientfor,windowevent, + transientforshow); + end; +end; + +procedure tpopupwidget.updatewindowinfo(var info: windowinfoty); +begin + with info do begin + options:= [wo_popup]; + transientfor:= ftransientfor; + end; +end; + +{ tcustomhintwidget } + +constructor tcustomhintwidget.create(const aowner: tcomponent; + const atransientfor: twindow; + var info: hintinfoty; const sender: tobject); +var + rect1,rect2: rectty; +begin + inherited create(aowner,atransientfor); + foptionswidget:= defaultoptionshintwidget; + if atransientfor = nil then begin + include(foptionswidget,ow_ultratop); + end; + internalcreateframe; + fframe.levelo:= 1; + fframe.framei_left:= 1; + fframe.framei_top:= 1; + fframe.framei_right:= 1; + fframe.framei_bottom:= 1; + color:= cl_infobackground; + rect2:= deflaterect(application.workarea(atransientfor),fframe.innerframe); + rect1:= textrect(getcanvas,info.caption,rect2,[tf_wordbreak], + stockobjects.fonts[stf_hint]); + addsize1(rect1.size,fframe.innerframedim); +// inc(rect1.cx,fframe.innerframedim.cx); +// inc(rect1.cy,fframe.innerframedim.cy); + widgetrect:= placepopuprect(atransientfor,info.posrect,info.placement, + rect1.size); +end; + +{ thintwidget} + +constructor thintwidget.create(const aowner: tcomponent; + const atransientfor: twindow; var info: hintinfoty; + const sender: tobject); +begin + fcaption:= info.caption; + inherited; +end; + +procedure thintwidget.dopaintforeground(const canvas: tcanvas); +begin + inherited; + drawtext(canvas,fcaption,innerclientrect,[tf_wordbreak], + stockobjects.fonts[stf_hint]); +end; + +{ tmessagewidget } + +constructor tmessagewidget.create(const aowner: tcomponent; + const apopuptransient: boolean; const ahasaction: boolean); +begin + fpopuptransient:= apopuptransient; + fhasaction:= ahasaction; + inherited create(aowner); + if apopuptransient then begin + color:= cl_active; +//exit; + createframe; + with tcustomcaptionframe(fframe) do begin + colorframe:= cl_black; + framewidth:= 2; + captionpos:= cp_top; + end; + end; +end; + +procedure tmessagewidget.dokeydown(var info: keyeventinfoty); +begin + with info do begin + if not((key = key_escape) and (shiftstate = []) and window.close) then begin + inherited; + end; + end; +end; + +procedure tmessagewidget.updatewindowinfo(var info: windowinfoty); +begin + inherited; + info.options:= [wo_message]; + if fpopuptransient then begin + include(info.options,wo_popup); + end; + window.localshortcuts:= true; +end; + +function tmessagewidget.getcaption: msestring; +begin + if fframe <> nil then begin + result:= tcustomcaptionframe(fframe).caption; + end + else begin + result:= inherited getcaption; + end; +end; + +procedure tmessagewidget.setcaption(const Value: msestring); +begin + if fframe <> nil then begin + tcustomcaptionframe(fframe).caption:= value; + end + else begin + inherited; + end; +end; + +procedure tmessagewidget.internalcreateframe; +begin + tcustomcaptionframe.create(iscrollframe(self)); +end; + +function tmessagewidget.canclose(const newfocus: twidget): boolean; +begin + result:= not fhasaction or (window.modalresult <> mr_windowclosed); +end; + +{ tcustomthumbtrackscrollframe } + +function tcustomthumbtrackscrollframe.getscrollbarclass(vert: boolean): framescrollbarclassty; +begin + result:= tthumbtrackscrollbar; +end; + +{ tscrollframe } + +function tscrollframe.getscrollbarclass(vert: boolean): framescrollbarclassty; +begin + result:= tscrollbar; +end; + +procedure tscrollframe.setsbhorz(const avalue: tscrollbar); +begin + inherited setsbhorz(avalue); +end; + +function tscrollframe.getsbhorz: tscrollbar; +begin + result:= tscrollbar(inherited sbhorz); +end; + +procedure tscrollframe.setsbvert(const avalue: tscrollbar); +begin + inherited setsbvert(avalue); +end; + +function tscrollframe.getsbvert: tscrollbar; +begin + result:= tscrollbar(inherited sbvert); +end; + +{ tsimplewidget } + +constructor tsimplewidget.create(aowner: tcomponent); +begin + inherited; + exclude(fwidgetstate,ws_visible); +end; + +{ timpressedcaptionframe } + +constructor timpressedcaptionframe.create(const aintf: icaptionframe); +begin + inherited; + fi.levelo:= -2; + internalupdatestate(); +end; + +{ ttaborderoverride } + +constructor ttaborderoverride.create(const aowner: twidget); +begin + fowner:= aowner; + inherited create(); +end; + +destructor ttaborderoverride.destroy(); +begin +// clear(); + inherited; +end; + +procedure ttaborderoverride.clear(); +var + p1,pe: pdoublewidgetty; +begin + p1:= pointer(fitems); + if p1 <> nil then begin + pe:= p1 + high(fitems); + while p1 <= pe do begin + setlinkedvar(nil,tmsecomponent(p1^.a)); + setlinkedvar(nil,tmsecomponent(p1^.b)); + inc(p1); + end; + fitems:= nil; + end; +end; + +procedure ttaborderoverride.readitems(reader: treader); +begin + clear(); + fwidgetnames:= nil; + reader.readlistbegin(); + while not reader.endoflist() do begin + additem(fwidgetnames,reader.readstring()); + end; + reader.readlistend(); +end; + +procedure ttaborderoverride.writeitems(writer: twriter); +var + p1,pe: pdoublewidgetty; +begin + writer.writelistbegin(); + p1:= pointer(fitems); + pe:= p1 + length(fitems); + while p1 < pe do begin + writer.writestring(ownernamepath(writer.root,p1^.a)); + writer.writestring(ownernamepath(writer.root,p1^.b)); + inc(p1); + end; + writer.writelistend(); +end; + +procedure ttaborderoverride.defineproperties(filer: tfiler); +var + b1: boolean; + p1,p2,pe: pdoublewidgetty; +begin + inherited; + b1:= fitems <> nil; + if (filer is twriter) and (filer.ancestor <> nil) then begin + with ttaborderoverride(filer.ancestor) do begin + b1:= high(fitems) <> high(self.fitems); + if not b1 then begin + p1:= pointer(fitems); + pe:= p1 + length(fitems); + p2:= pointer(self.fitems); + while p1 < pe do begin + if ((p1^.a = nil) <> (p2^.a = nil)) or + ((p1^.b = nil) <> (p2^.b = nil)) or + (p1^.a <> nil) and (p1^.a.name <> p2^.a.name) or + (p1^.b <> nil) and (p1^.b.name <> p2^.b.name) then begin + //todo: better check for changed owner + b1:= true; + break; + end; + inc(p1); + inc(p2); + end; + end; + end; + end; + filer.defineproperty('items',@readitems,@writeitems,b1); +end; + +procedure ttaborderoverride.objevent(const sender: iobjectlink; + const event: objecteventty); +var + p1,pe: pdoublewidgetty; + w1: tobject; +begin + if event = oe_destroyed then begin + if csdestroying in fowner.componentstate then begin + fitems:= nil; + end + else begin + w1:= sender.getinstance(); + p1:= pointer(fitems); + if p1 <> nil then begin + pe:= p1 + high(fitems); + while p1 <= pe do begin + if p1^.a = w1 then begin + p1^.a:= nil; + end; + if p1^.b = w1 then begin + p1^.b:= nil; + end; + inc(p1); + end; + end; + end; + end; + inherited; +end; + +procedure ttaborderoverride.endread(const reader: treader); +var + p1,pe: pstring; + compa,compb: tcomponent; +begin + if (fwidgetnames <> nil) then begin + clear; + p1:= pointer(fwidgetnames); + pe:= p1+high(fwidgetnames); + while p1 < pe do begin + compa:= findsubcomponentbynamepath(p1^,reader.root); + inc(p1); + compb:= findsubcomponentbynamepath(p1^,reader.root); + inc(p1); + if ((compa = nil) or (compa is twidget)) and + ((compb = nil) or (compb is twidget)) then begin + add(twidget(compa),twidget(compb)); + end; + end; + fwidgetnames:= nil; + end; +end; + +function ttaborderoverride.nexttaborder(sender: twidget; + const down: boolean): twidget; +var + ar1: doublewidgetarty; + p1,pe: pdoublewidgetty; +label + restartlab,endlab; +begin + result:= nil; + if fitems <> nil then begin + ar1:= copy(fitems); + while true do begin +restartlab: + if down then begin + pe:= pointer(ar1); + p1:= pe+high(ar1); + while p1 >= pe do begin + if p1^.b = sender then begin + result:= p1^.a; + if (result <> nil) and not result.canfocus() then begin + p1^.b:= nil; //avoid circles + sender:= result; + goto restartlab; //next try + end + else begin + goto endlab; + end; + end; + dec(p1); + end; + goto endlab; //no match + end + else begin + p1:= pointer(ar1); + pe:= p1+high(ar1); + while p1 <= pe do begin + if p1^.a = sender then begin + result:= p1^.b; + if (result <> nil) and not result.canfocus() then begin + p1^.a:= nil; //avoid circles + sender:= result; + goto restartlab; //next try + end + else begin + goto endlab; + end; + end; + inc(p1); + end; + goto endlab; //no match + end; + end; + end; +endlab: + if (result <> nil) and not result.canfocus() then begin + result:= result.nexttaborder(down) + end; + if fowner.canevent(tmethod(fontaborder)) then begin + fontaborder(self,sender,down,result); + end; +end; + +procedure ttaborderoverride.add(const aa: twidget; const ab: twidget); +begin + if (aa <> nil) or (ab <> nil) then begin + setlength(fitems,high(fitems)+2); + with fitems[high(fitems)] do begin + a:= aa; + b:= ab; + if aa <> nil then begin + getobjectlinker.link(iobjectlink(self),ievent(aa)); + end; + end; + end; +end; + +end. diff --git a/mseide-msegui/lib/common/widgets/msewindowwidget.pas b/mseide-msegui/lib/common/widgets/msewindowwidget.pas new file mode 100644 index 0000000..7294428 --- /dev/null +++ b/mseide-msegui/lib/common/widgets/msewindowwidget.pas @@ -0,0 +1,568 @@ +{ MSEgui Copyright (c) 2007-2013 by Martin Schreiber + + See the file COPYING.MSE, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit msewindowwidget; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + classes,mclasses,mseclasses,msegui,msetypes,msegraphutils,mseguiintf,msewidgets, + msegraphics,msesimplewidgets,mseevent,msemenus,mseguiglob,msetimer; + +type + tcustomwindowwidget = class; + + windowwidgeteventty = procedure(const sender: tcustomwindowwidget) of object; + windowwidgetpainteventty = procedure(const sender: tcustomwindowwidget; + const aupdaterect: rectty) of object; + createwinideventty = procedure(const sender: tcustomwindowwidget; + const aparent: winidty; + const awidgetrect: rectty; var aid: winidty) of object; + destroywinideventty = procedure(const sender: tcustomwindowwidget; + const aid: winidty) of object; + clientwindowoptionty = (cwo_trackboundsimmediate,cwo_highrestimer,cwo_noleak); + clientwindowoptionsty = set of clientwindowoptionty; + + tcustomwindowwidget = class(teventwidget) + private + fclientwindow: windowty; + fchildrect: rectty; + fviewport: rectty; + faspect: real; + foncreatewinid: createwinideventty; + fondestroywinid: destroywinideventty; + fonclientpaint: windowwidgetpainteventty; + fonclientrectchanged: windowwidgeteventty; + fondestroy: windowwidgeteventty; + fonloaded: windowwidgeteventty; + fonwindowmouseevent: mouseeventty; + fwindowmouseentered: boolean; + fonwindowmousewheelevent: mousewheeleventty; + frenderstep: real; + frendertimestampus: longword; + frendered: boolean; + frendercount: longword; +// ftimerrendercount: longword; + ftimer: tsimpletimer; + ffpsmax: real; + foptionsclient: clientwindowoptionsty; + function getclientwinid: winidty; + procedure windowscrolled(const sender: tobject); + function getchildrect: rectty; + function getviewport: rectty; + procedure setfpsmax(const avalue: real); + procedure setoptionsclient(const avalue: clientwindowoptionsty); + protected + procedure resetrenderstep; + procedure dotimer(const sender: tobject); + procedure checktimer; + procedure checkwindowrect; + procedure checkclientwinid; + procedure checkclientvisible; + procedure clientrectchanged; override; +// procedure poschanged; override; + procedure visiblechanged; override; + procedure winiddestroyed(const awinid: winidty); + procedure docreatewinid(const aparent: winidty; const awidgetrect: rectty; + var aid: winidty); virtual; + procedure dodestroywinid; virtual; + procedure doclientrectchanged; virtual; + function canclientpaint: boolean; virtual; + procedure doclientpaint(const aupdaterect: rectty); virtual; + procedure doonpaint(const acanvas: tcanvas); override; + procedure doloaded; override; + procedure updateviewport(const arect: rectty); virtual; + procedure clientmouseevent(var info: mouseeventinfoty); override; + procedure domousewheelevent(var info: mousewheeleventinfoty); override; + + procedure clienttoviewport(var apoint: pointty; const arect: rectty); + procedure viewporttoclient(var apoint: pointty; const arect: rectty); + + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + property rendertimestampus: longword read frendertimestampus; //us + property renderstep: real read frenderstep; + //elapsed secods since last paint + function createchildwindow: winidty; + function hasclientwinid: boolean; + procedure invalidateviewpointrect(arect: rectty); + property clientwinid: winidty read getclientwinid; + procedure destroyclientwindow; + property childrect: rectty read getchildrect; + property viewport: rectty read getviewport; + property aspect: real read faspect; + property fpsmax: real read ffpsmax write setfpsmax; //default -1 -> none + //0 -> as fast as possible + property optionsclient: clientwindowoptionsty read foptionsclient + write setoptionsclient default []; + property oncreatewinid: createwinideventty read foncreatewinid + write foncreatewinid; + property ondestroywinid: destroywinideventty read fondestroywinid + write fondestroywinid; + property onclientpaint: windowwidgetpainteventty read fonclientpaint + write fonclientpaint; + property onclientrectchanged: windowwidgeteventty read fonclientrectchanged + write fonclientrectchanged; + property ondestroy: windowwidgeteventty read fondestroy write fondestroy; + property ondloaded: windowwidgeteventty read fonloaded write fonloaded; + property onwindowmouseevent: mouseeventty read fonwindowmouseevent + write fonwindowmouseevent; //origin viewport.pos + property onwindowmousewheelevent: mousewheeleventty read + fonwindowmousewheelevent write fonwindowmousewheelevent; + end; + + twindowwidget = class(tcustomwindowwidget) + published + property optionswidget; + property optionsskin; + property bounds_x; + property bounds_y; + property bounds_cx; + property bounds_cy; + property bounds_cxmin; + property bounds_cymin; + property bounds_cxmax; + property bounds_cymax; + property color; + property cursor; + property frame; + property face; + property anchors; + property taborder; + property hint; + property popupmenu; + property onpopup; + property onshowhint; + property enabled; + property visible; + property fpsmax; + property optionsclient; + property oncreatewinid; + property ondestroywinid; + property onclientpaint; + property onclientrectchanged; + property onwindowmouseevent; + property onwindowmousewheelevent; + property ondestroy; + end; + +implementation +uses + msesysutils; +type + twindow1 = class(twindow); + +{ tcustomwindowwidget } + +constructor tcustomwindowwidget.create(aowner: tcomponent); +begin + ffpsmax:= -1; + application.registeronwiniddestroyed({$ifdef FPC}@{$endif}winiddestroyed); + inherited; + ftimer:= tsimpletimer.create(0,{$ifdef FPC}@{$endif}dotimer,false,[to_leak]); +end; + +destructor tcustomwindowwidget.destroy; +begin + if fwindow <> nil then begin + fwindow.unregisteronscroll({$ifdef FPC}@{$endif}windowscrolled); + end; + if candestroyevent(tmethod(fondestroy)) then begin + fondestroy(self); + end; + application.unregisteronwiniddestroyed({$ifdef FPC}@{$endif}winiddestroyed); + destroyclientwindow; + inherited; + ftimer.free; +end; + +function tcustomwindowwidget.getclientwinid: winidty; +begin + checkclientwinid; + result:= fclientwindow.id; +end; + +function tcustomwindowwidget.createchildwindow: winidty; +var + options1: internalwindowoptionsty; + rect1: rectty; +begin + rect1:= innerwidgetrect; + addpoint1(rect1.pos,rootpos); + fillchar(options1,sizeof(options1),0); + options1.parent:= window.winid; + guierror(gui_createwindow(rect1,options1,fclientwindow),self); + result:= fclientwindow.id; +end; + +procedure tcustomwindowwidget.checkclientwinid; +var +// options1: internalwindowoptionsty; + rect1: rectty; +begin + if fclientwindow.id = 0 then begin + rect1:= innerwidgetrect; + addpoint1(rect1.pos,rootpos); + docreatewinid(window.winid,rect1,fclientwindow.id); + if fclientwindow.id = 0 then begin + createchildwindow; + end; + if fwindow <> nil then begin + fwindow.registeronscroll({$ifdef FPC}@{$endif}windowscrolled); + end; + checkclientvisible; + end; +end; + +procedure tcustomwindowwidget.destroyclientwindow; +begin + if fclientwindow.id <> 0 then begin + dodestroywinid; + end; + gui_destroywindow(fclientwindow); + fillchar(fclientwindow,sizeof(fclientwindow),0); + fchildrect:= nullrect; +end; + +procedure tcustomwindowwidget.doclientrectchanged; +begin + if canevent(tmethod(fonclientrectchanged)) then begin + fonclientrectchanged(self); + end; +end; + +procedure tcustomwindowwidget.checkwindowrect; +var + rect1,rect2{,rect3}: rectty; + bo1: boolean; +begin + if fclientwindow.id <> 0 then begin + bo1:= false; + rect1:= innerwidgetrect; + rect2:= intersectrect(rect1,clippedpaintrect); + rect1.x:= rect1.x - rect2.x; + rect1.y:= rect2.y + rect2.cy - rect1.y - rect1.cy; + addpoint1(rect2.pos,rootpos); + if not rectisequal(rect2,fchildrect) then begin + bo1:= true; + fchildrect:= rect2; + gui_setembeddedwindowrect(fclientwindow.id,rect2); + end; + if not rectisequal(rect1,fviewport) then begin + bo1:= true; + if rect1.cy = 0 then begin + faspect:= 1; + end + else begin + faspect:= -rect1.cx/rect1.cy; + end; + fviewport:= rect1; + updateviewport(fviewport); + end; + if bo1 then begin + doclientrectchanged; + end; + end; +end; + +procedure tcustomwindowwidget.clientrectchanged; +begin + inherited; + if cwo_trackboundsimmediate in foptionsclient then begin + checkwindowrect; + end; + { + if canevent(tmethod(fonclientrectchanged)) then begin + fonclientrectchanged(self); + end; + } +end; +{ +procedure tcustomwindowwidget.poschanged; +begin +// checkwindowrect; + inherited; +end; +} + +procedure tcustomwindowwidget.resetrenderstep; +begin + frenderstep:= 0; + frendered:= false; + frendercount:= 0; +// ftimerrendercount:= 0; + ftimer.enabled:= false; +end; + +procedure tcustomwindowwidget.visiblechanged; +begin + resetrenderstep; + inherited; + checkclientvisible; + checktimer; +end; + +procedure tcustomwindowwidget.doloaded; +begin + resetrenderstep; + checkclientvisible; + checktimer; + inherited; + if canevent(tmethod(fonloaded)) then begin + fonloaded(self); + end; +end; + +procedure tcustomwindowwidget.checkclientvisible; +begin + if fclientwindow.id <> 0 then begin + if isvisible and parentisvisible then begin + gui_showwindow(fclientwindow.id); + end + else begin + gui_hidewindow(fclientwindow.id); + end; + end; +end; + +procedure tcustomwindowwidget.winiddestroyed(const awinid: winidty); +begin + if awinid = fclientwindow.id then begin + fclientwindow.id:= 0; + end; + if (fwindow <> nil) and (fwindow.haswinid) and + (fwindow.winid = awinid) then begin + destroyclientwindow; + end; +end; + +procedure tcustomwindowwidget.docreatewinid(const aparent: winidty; + const awidgetrect: rectty; var aid: winidty); +begin + resetrenderstep; + checktimer; + if canevent(tmethod(foncreatewinid)) then begin + foncreatewinid(self,aparent,awidgetrect,aid); + end; +end; + +procedure tcustomwindowwidget.dodestroywinid; +begin + resetrenderstep; + if canevent(tmethod(fondestroywinid)) then begin + fondestroywinid(self,fclientwindow.id); + end; +end; + +function tcustomwindowwidget.canclientpaint: boolean; +begin + result:= assigned(fonclientpaint); +end; + +procedure tcustomwindowwidget.doclientpaint(const aupdaterect: rectty); +begin + if canevent(tmethod(fonclientpaint)) then begin + fonclientpaint(self,aupdaterect); + end; +end; + +procedure tcustomwindowwidget.doonpaint(const acanvas: tcanvas); +var + lwo1: longword; + rect1: rectty; +begin + if not (csdesigning in componentstate) and canclientpaint then begin + checkclientwinid; + checkwindowrect; + lwo1:= timestamp; + if frendered then begin + frenderstep:= (lwo1-frendertimestampus)/1000000; + end; + frendertimestampus:= lwo1; + frendered:= true; + inc(frendercount); + if acanvas <> nil then begin + rect1:= acanvas.clipbox; + rect1.y:= rect1.y+rect1.cy; + clienttoviewport(rect1.pos,innerclientrect); + doclientpaint(rect1); + end + else begin + doclientpaint(makerect(nullpoint,fviewport.size)); //called from timer + end; + end; + if acanvas <> nil then begin + ftimer.interval:= ftimer.interval; + inherited; + end; +end; + +function tcustomwindowwidget.hasclientwinid: boolean; +begin + result:= fclientwindow.id <> 0; +end; + +function tcustomwindowwidget.getchildrect: rectty; +begin + checkwindowrect; + result:= fchildrect; +end; + +function tcustomwindowwidget.getviewport: rectty; +begin + checkwindowrect; + result:= fviewport; +end; + +procedure tcustomwindowwidget.updateviewport(const arect: rectty); +begin + //dummy +end; + +procedure tcustomwindowwidget.clienttoviewport(var apoint: pointty; + const arect: rectty); +begin + apoint.x:= apoint.x - arect.x; + apoint.y:= arect.cy - apoint.y + arect.y; +end; + +procedure tcustomwindowwidget.viewporttoclient(var apoint: pointty; + const arect: rectty); +begin + apoint.x:= apoint.x + arect.x; + apoint.y:= arect.cy + arect.y - apoint.y; +end; + + +procedure tcustomwindowwidget.clientmouseevent(var info: mouseeventinfoty); + procedure enterevent(const aenter: boolean); + var + info1: mouseeventinfoty; + begin + if aenter xor fwindowmouseentered then begin + fwindowmouseentered:= aenter; + info1:= info; + if aenter then begin + info1.eventkind:= ek_clientmouseenter; + end + else begin + info1.eventkind:= ek_clientmouseleave; + end; + end; + info1.pos:= nullpoint; + fonwindowmouseevent(self,info1); + end; +var + rect1: rectty; +begin + inherited; + if canevent(tmethod(fonwindowmouseevent)) then begin + if info.eventkind in mouseposevents then begin + checkwindowrect; + rect1:= innerclientrect; + if pointinrect(info.pos,rect1) or + (ws_clientmousecaptured in fwidgetstate) then begin + enterevent(true); + clienttoviewport(info.pos,rect1); + if not (es_processed in info.eventstate) then begin + try + fonwindowmouseevent(self,info); + finally + viewporttoclient(info.pos,rect1); + end; + end; + end + else begin + enterevent(false); + end; + end + else begin + if info.eventkind = ek_clientmouseleave then begin + enterevent(false); + end; + end; + end; +end; + +procedure tcustomwindowwidget.domousewheelevent(var info: mousewheeleventinfoty); +var + rect1: rectty; +begin + if canevent(tmethod(fonwindowmousewheelevent)) then begin + rect1:= innerclientrect; + if pointinrect(info.pos,rect1) then begin + clienttoviewport(info.pos,rect1); + try + fonwindowmousewheelevent(self,info); + finally + viewporttoclient(info.pos,rect1); + end; + end; + end; + if not (es_processed in info.eventstate) then begin + inherited; + end; +end; + +procedure tcustomwindowwidget.windowscrolled(const sender: tobject); +begin + checkwindowrect; +end; + +procedure tcustomwindowwidget.setfpsmax(const avalue: real); +begin + ffpsmax:= avalue; + checktimer; +end; + +procedure tcustomwindowwidget.setoptionsclient( + const avalue: clientwindowoptionsty); +begin + if avalue <> foptionsclient then begin + foptionsclient:= avalue; + checktimer(); // check highres + end; +end; + +procedure tcustomwindowwidget.checktimer; +begin + if componentstate * [csloading,csdesigning,csdestroying] <> [] then begin + ftimer.enabled:= false; + end + else begin + ftimer.highres:= cwo_highrestimer in foptionsclient; + ftimer.leak:= not (cwo_noleak in foptionsclient); + if (ffpsmax >= 0) and showing then begin + if ffpsmax = 0 then begin + ftimer.interval:= 0; + end + else begin + ftimer.interval:= round(1000000/ffpsmax); + end; + ftimer.enabled:= true; + end + else begin + ftimer.enabled:= false; + end; + end; +end; + +procedure tcustomwindowwidget.dotimer(const sender: tobject); +begin + doonpaint(nil); +end; + +procedure tcustomwindowwidget.invalidateviewpointrect(arect: rectty); +begin //todo: test + arect.x:= arect.x + fviewport.x; + arect.y:= fviewport.y + fviewport.cy - (arect.y + arect.cy); + invalidaterect(arect,org_inner); +end; + +end. diff --git a/mseide-msegui/msegui.svg b/mseide-msegui/msegui.svg new file mode 100644 index 0000000..b1d5b2b --- /dev/null +++ b/mseide-msegui/msegui.svg @@ -0,0 +1,245 @@ + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/msegui_24.png b/mseide-msegui/msegui_24.png new file mode 100644 index 0000000000000000000000000000000000000000..88524968d1e77381477daeaa134bdc3f82e0a2e3 GIT binary patch literal 1836 zcmV+{2h;e8P)L4(E^ zgB_Eq@ltOc(^N5vAc-simUd7twf!WhGYj1+#M1wh%^8Oj44?_IRYHG-C70SU6HC zUR#w20BC6saCB73Q^Wpe)lgtQjRfYJpXy#&@be3&CNFPZ3IJe?jSq1~F#nmd4mbPO zC}r%IRX5pVt1mKHp={VMv%FOo?k=;!wQa0mO&d#^cagz$iDfQnz4PW?x9?Qbu4Tq4ZMA@2LM0_ux(=sECvCaw%>p+s3PcRSon)hl)vAN-T@g& zHXa5&!?&W3i=8C*0(awLaJ;YVdDl3sQ24i43M$4jRu6rL+z zV#zD5u!L^n-B;%$majx`kYL15aiVH6K6oP?7L$M_1WG{RFN{6 z5^+5~O)$T-*p4k#x6siw3WJWvjGVuqVsjM^?0p`xA|N55A9IS%;gj>F__WG3evq;q zH_-5f!ZWHksUT(OXUi7_0APx2XR4G!71{aE4jJ42*o%OlV%G;l&~U)&CmDi4J+8D( zg~|8?Ufq}vw}(eicBA@8G}bMO$F3uNs5$C~9OOZ@QW~d9DNK>=gfRx=tnLz7MQD-5mIrJkF8;!XhoY;oR-j^T^}Di^xDH|yrbf0 zi73c60|0g(>BH}L^rP{Uc`%!USY7-crsiLQXpErh{gtp6N|4nU_!Jq|C=Ika4qa{u zH*NxyOgJeRCVV7}wWDF!5s z+RJnC@vdU%v>Yy78%4=)Z=kVOK}6=EY5-0T1%xQv7y#!dg!ch}Z$Ln2yNW59M%3-j zMzl$TMeCEWb7v8vT@I{YQHcff_Mj)=fJPtyfZTKg8V+P((?&CFY3jEe;(dg0{xKeK zyqEBNKX{=}XHl_sRTOrYJMmskA1o#Tm77zLn`Xo-FC^et^W&J5p9iCf;E5O7;2n_x z06a%fxiJMhUr$6*8Ulpp`@!+vu?z&wZNh82^-*kK$#X_*-{gR-FdX{Ki>)sujbHeo zlU_)S!j)=3ZFLq>?Rpfw*p3yyx{BZIbK`Gkhme_~$L19leSEy%Mg+}m0RTd$H6C$> z;(5A|Bv)^7qV;+Z?;Pv}&l5~_nE(K%&V7S3=Y2@eBWP(0Lf{EL+?tN!(#tsfp$w{x zfNF;jW#s}BqJ^tNfvCTS>NTEmJy6JiGDAr|)@-)P|hnmpW6Icioy; z9SoWq98L~Jc@ywtNju)C97HGtlq{Zv_=y6#t}*=KNFM-TN~Qs-sDknUCmI@fQU4E4 zqi?<|KKJNBxWUlKiN?=)ov}6;)^^O<&>1;h&kzi881VzOEh9KyKLSPK@zIGPsFWci zSqF$1;dG{xyv|t5iN?>v4Ti?MG0FFdzHa7dK9xh$s1$ybDG?V{WG7T5KF%(q|27YR zgGNX3>#`W?Ocb%AeE6?CA5+I^^v&N5eqR7!OdpsW$)Spr!Bi=QscIZ!Y7`g*5GaK3 zzN~EDW0S1J($Hcp1p<1sDgKEhjQXwu7ox#;E!3uYwTHPq}aeoa~X#*e>61 a|Gxl-cn#}F>2t3D00000D$WG{Ir#G%iAiom0lnCCa?{Gn?|beaTYsIKa_8ffH8oe#-vJRe2th#z zr*a@6JF9)t{K=__>;BewrM9u(3@XVr!BVC1$6|L;Ab$M8p>dit_iCO0S-WFwL|8^H zw~XF`nVEJ)QgbrwSpINY`qQs9&TFpM>j6+mmXg;moO9rf0k#-T!nzNeVtFJ`BqXKU zUZh?mvU)DKSMq-!0oo;7RT{HkO4__z3%ivi$DP__ncmyD5gf%Mfui;Rw*kOIcRA^p zLN!g6`~|`Y56;R8ij$%e|BsW60*o#fq4H0PYSRYqj z33Bk`n3pe-G;Y?Bi0H-ep z;b{_yEE2qxMS`PwBs78>q2b&J720nzGRc@PZ%P?|c=itx(9~h=2g?24u)%TXuta)d z)1a8mFJ!nzjNtKB1bF6;)c^pyjpDtPIdJu6cz8l;$NtZcwIkvqAeOw#-VGdzN`ZqS~Wm|SPv+MKYM^c&3qDz!Giu%AJ)Kp~z}aFKq&wisjO##&ZY7w)9aQ`6Hha-akEF0F(w$Pf&3a4xX$l`5=y_bT?6 zx1+&rA+NWF?#U_uf&2m!@2}2|{nv*6_M9Ge-21C@-rB~*^<9oYFE*XrGI|Tk=))}| zr}~_t-nsZRJYKUCiIIci;JG4U*n{O*_WBjHRY~Y$-;NmZ92UQD2;OQ5$I3!DSl*5o z7p0+m^Ub)uFaZECchv>!>k9b*Gg3^w*mMHlx`v!tJp?l|g=O^89f7>8EC!!npm=@- z4!<)Hb{oaXivhgyRt;WTvL1lI^4~1LjJrzl>Z&yWfc!p}Fl)tH%$uHyrL!`isow~^ zac2WQE)B3?Ya*jIGm|r`2cR^{9cRx>mtbZ(XI4ghqNVToLq6L47VcVn8iS^vz+20D zWBmsWn19c^cwoj306=SV0xnhc=m24s1VtBJz$-2VvEq$dcYV&;_I zxb2Qlv0?p8giL{{&z!~1SMxv!(B`)=dC6HcomW99AeiM6j5)zss^Ba|zNUY?;4DFK zs~c59DbDT!mI?R+46bAaLnf-obZYqQP%A#zJ|1@2!k2r8VcqNL7(SB2Ie-6jqPY8}5q44=);BW+S;zS;7y~5bNVIcZs*gIkb z!VKF#_h93WCZncN)XK;>MT8L0ZuQ^JdELD3DS^8S^XxIJ7i1x~$2S`p7kKKmOW3;6 zi<*kD(K#kzVA4K}7=0YsH(kc@f9KfaOhA3ZFMpP2p9#p3=mcO zTGAYQBwNhxXb}=(03=KZ2@58n`LYC06>#!s9rQ$o?r9QszS$RZR-Q-cks&z#`VgqG z0x>>Mhe~HFdclzjOc|RTt&4aCe_xY_UHe<`_}a^;sZ;=qUV|fHfP_JaL8BAYPbl?+ zNInplAOHk`o**!DauSZcHwaa=A=ES(*tot2%6AMv<+i~PDcx{S$=g`8U^%8g^fD|k zgbm)Qb|#EY!im2Q!i0$`;#~%!@g*Oj)K3WYM=4RsOQ_UFsMG=~djtXEG7K!3m4a6n z^@KzTo?c&#LAf!QGBz0wy95Au?$HdCHRobqeKDpjNm4a3?w=Tk6%R*WxgB44(As8U&Eo7% zf$bWFkOgAxGJf}DPi+5fE+P?N*z9ubKGF))>TLH`&(Ff_NpV_yiZ2aRY9dr}%K#AE zEBUn|rJhJits^0V@kP2=|5Pt>edF>sYvAgpqHpFmH-mHFm+P(|s2gbaN3U){KL_@| zlaGnNsKksVmtcuU%ViUq-9N-{Fi&u=5s3g}g+0Ta$5q-C= z%q6Wp3&+m+@&0Z%n%oSVR%Ug|X6gFNX!SD8nc59ocedbERRH3aS|=iJW>^u{kaR-}()MrAlM^#I}N_R6V~ax*kU)x(*OO>sg9VC~jgtlQFnhBGR9 z4kmbPa(C3aBcO!hV3{9bgF{m(CByYOay3=7lT@*trn0S)$m+T4n4Jhj4kWbL zi_J0)q7Wfu3Lq{q9Gm5`CEhZ(3}-5Upj!hG1e7vR3Y1?6A{YQ#-4fPrsl&1dGXMa( zPQS@q(M}RYJ3$m%IZ#5DCh7dsh=8X7nAfsgx5{`iQ z?|WOb&_1==UQA3uXoy?X>u!!YFUdwPPOJ>UESKO`a{X0V8S}^)xa%cw8qK5rDrN6| z+Dzw8a1z53A<3riC$f5h%C<_P*ebpY{(}UrE1{QAAE8nUr*fl^l$xlMVNStW5(JBF zxGFRNl&Ii@kg#FsfeqUlM$Mhzj0r@TpQ`!+D*t$AbmP5Y)HAxSIhh2(xdRZ|_1+L5 zVM3`tDY>~IE-p0A=U4yi4fI|6-+IFvBG5skggLI+w|F7Aqf2*8sQ=ot?*5^SzdQZ| X{z%xP)MK~!jg)mnLURn@uw?Y+-%&&ka^hd@GrkOTtAAR4L&Viggs zmRDb`6H>Kmt=4LthpNlgS*x`UXsy!LI*YbcpMVOh8bOdb3?UO4$ef#d&%I~b-}~bx zflGq6+V$3Yd#$Xjb@o2{`~B|T`}@BA`wk-_{C{rBe_|3g@1s27jwVej@`=a*NgaR+ zkO05{5Wsu@E*Q5NV^J_3u~zfwx3>LlR=_-28b0gEQ`w%+d@0j)p>2v;Wp@)%0H8Pl z0s|W)z+A>y3`{ycuV0|6_V`#V_@t(nRew`5-)IHQll>q`KbxeVNocxs?y;$<@BF4* zo%Q1{r|qn*yHdvTHpB@)0TBaZ1i%BBOQNg92=<*dbG#AA%}7>PeH!J`v+pzJi7v)P zhqYRS|6>Fg10%xF5}6C6M!uIv(#wPIXOZ->C8wg<6+vAQ3@h)i&?le2`P8u0Yr@wf zARO943_cI^7o?_#r@nMssaRB%fyZBK#y>u_bIFZO0#`anh-_n?(#C|+W_`$=Z$*I3 z`zSBCKwF=3DjNIyy=#m>RWnJifPAlDfJ8P)KU;E<+|=&)0L17V9V_lERepHK?h~!{ z^cF}a2w)5#XtrV|N3z#HHI?QXu>>?T~mTFg&ZPa zgZqG)7Q>C_kHYlQV1kKlwGmD> zWt>*M>YmHToO;#S`3wL$`&``pLX&)MWg8<$x9uJ^0AE1M@5O<)k41KxI`r=TmKdg7 zunEzYAVh8m?e86jwBVr~DVdCa0b{B_t2l4?ZIbRsVaW^^Af)Q^_lFt3o`?$g%Jev zA`q^EyI*KZc)z3|fM;)-fTTPN=|MFCe4Jnu8W-R`1Cs!JKZ`u4lstO^dCqw0xh2wb zi#@+#iLP(@C_h90gQ{xjXoU`;f0BHD+KPr~t&Q${4wZ~4eM<1+}KE**0TJ)fS)2`crjW0~YghFE&ft~dhd>;_|lX2f4 zn(^X$?a0qj5$jZN;858eW=snR1ie^km zZNa)Xmkk+T*7Q0~`p%zGHFsMAcmO#4w2$$?YZu_*UyQ@jMY$txNdUO~{#rC1kns9V z!BsyKzL!Z{NoUf}Ao4Q+-h61iq)Z{{r;_y3Kz=$&KLb8eRUwd~oalqn=-8UT2GI)41? zy?AYHCmwyJ1+GVsx(ivCjK^PSNA~HTL5V5YziVs)fbQ;8Z1{94Lfx5IIQNgZ>*i~* zWBUZW_4;@5_`^#Yb)Nb?imJtXT60hAF4&H*#x8bX(lPtNXGGjWC}??#XMOW zjEG>)_p+oLtCX%?Dcx8ldG=)K#wwXlNsI_0H3lQ-BW4p+g+nM3u9Q$X2bUaPtpOt@ zu;MS*VcvpI@#Pm4xbBL(aqAt0IAtMW`&Qt^|aohN`-Sfuy+G%TCo$QEXync@UN3OjHz`D9q6jiul;Ds~3622 zu#=9-#IY4Y%$S&rlq50YKFv;3F*ZMds~*}1SSn`C+6GODN7LM##IdRhRLvnwm{>pb zjB|ZMMYX@p=h!&OW2aL(K;Od4w@%;C7iw%0|1cP?+7vv$+&a?dTB zKj?*2O>aH-wBwT|K7aExo@|Z`c%-&wQ!gmS@$6G~;(JRz002Du*!fuX#?Rt$VPGo9 z2G+h0oN!8FUe(o=3Z*cHlV%2S&AA0QWmY=)QBq7zWf(uo!0buM;)Bn7(ipfhFq8z~ zRCM=yG8`Q-?Kx_D;oXDCQ@V!01Hfh1u7DlghdZtncz-3w+ploUo2sC3Kg0TuW(|$o zyL&8t_uC6Wg0OUPE>4|&bnrXtEnITnUdlhSTHgP1`#$Lw-N2Y8<7eQcSf#YB=|XS( z2~(o8mYkHyFFPxb&8ZwYZ5V9bArIr0Y(Q1=KD_nDPZRq7@Wc;s&$YjRAYjIcn=xiW zBera+z|NiHQ8r~C(nodR)BO|SngWgsP?C$2W~Ab(CHWX%Xdo2vv3-98?^pNYqfNc& zi}-LOfv|K_H*k@(k*k3%TnlU+BrsXJu_@BEr%1Q|SgwX<8Yxb4lF4xC;yhfuC>JFK zi7D|bA9mo%2lpY?t|Hhi@Wp5Uh1~p(q5hjLzYY6qigEvQcVld6BLKjT>6laT7Me{H zc1{#OIyDF1ot=hlwHAK=W-F{d2B8APB{*Y{jzGAF1D*m&0!%0^Yydb{^{reTB4C%t z3B)R;8=Fe5T}hr>#JLAO#RVA-%8E=ZTbzSQV@+KD+j{J-i-B=MUY3ToZU=dt4t{dM z8%R&@$NCRvW7S*p@r&D^!Ow18oJX3yN%n+kei_;fCqr2 zfWY#b$K!&9+4%31^WJb6e*v1rn`{9vza0Mb@++v(Z80TRy-VY}Fi2-1M)LrPK`|;|% z6NkV9z;i1PLP&w1{h$Cx#*UOEflJTKgIgFylV>1%hQM_)vDBOCy%)jZ0$2!ZhsnCN4ihZyI*06>}pvmk=M zJv<4Ej#&C9UTc9(9o3qNKx?VGgC2Vx}lkwozs9gPR2#ZTFnm=q&N>TF8UZ3yk$`R)=bdG;KQo*N8(9@J)>uknFA2<&IUv(q%B2)GBgQu*xvs9dYV&WS*{w39VMdzC@(fpQV>9XmWJGP6|P5^`_rvH^Cv7&^z7<{8=1A5M~!)+3tZ`7 z+|M>Lx~DBYBbSc^{;4-xvAM>=aN;Lu_3APr14KB%-QZaRXuN_Nj8LTHHTtpcc z9VA3Hp{=aAfM-5@_1Gad(b4PT!;QUocYQbB{HPNu1n&It$g<_*ueM@8*DKBE7`LqT>?} zb$gGCdtYqAv+uM)aNxZMr(jI3j}#~8m;RBGA!}PE6up}+=2w1lye|GSw)ZPfuuMD zUQrvEP@Cc;lmi1KT9{DU4#ztzd9^;|j^LA)drtZ73W`?<%3jTpvV{q?o+)Yr2??pX zShhH>Ce$=on0d*Uxc;#Q#2SL|I!pvo374LANNq554w4*RNX1>xHy&vcML9a8Dvt!; zz!a^XD{3QC)B{W?&5SE8M^L7dr4QEQn{>jv!A z4`EQ$#*r#EN0ry3Yt&XIv<9YVbzD*FxuWi8infm_dVNQqBNtq=jc$9o307+m($WuQ zj+_v)fL-KGv^`AG_cBG>#}#!ySJe7} z`anZ;joLaA&ZAdo07TcSO-yKYOwnqYqSbOm+sj#Sb0lQ!{P=UfG18t<3#RtQ!2^T; zV-W=_-tRzjhl6GJ?M1Xl8%l{|JsO^Ty#=Ajp_^aKks$C+u4;R@qV461ws+7b6Ixw# zt=e=nj9*)3jjmOjjQQ~rDZpdk+>&lyh@$F>J zXEt#jA)kkdi4bwoLsIF4?`1Ob)8nF(OeQIlKx9}QnhN;3L!6iZfeqyFj76hi#vgmN zrR;|D3IzZ(x7!{Q%03Q#&w#sZVfSzeS10~P zpBfxqsgDc7gL0ot0!ic0rv^|!#KD-vK&5`*A`&I_V1;4!T|9GQkT&kNnq2Fcg-jC% z|J_RcxBgZlu4>1%N{}=`WPJU%5-bYFEsyq3kQB}4QhU|==hWtJg5g^cIFbxVCjDQ3 at@6JL)uJS^IepUr0000Y literal 0 HcmV?d00001 diff --git a/mseide-msegui/msegui_64.png b/mseide-msegui/msegui_64.png new file mode 100644 index 0000000000000000000000000000000000000000..c808ed1f25898d50efbffea184f2bcabedb98ad1 GIT binary patch literal 7603 zcmV;k9ZcehP)eSi4U+t>ed)F>vX8iwL)c=W(gytJRnEhb(0j!u| z0W1KBLCp+6h6oNoE{JRpr4wsJ`ty{HJ`W8D&1W*QBiruX`y)UIL4iG%7{8gpelS~L zs0;ye&}$kX1A+@8hd^nNutAh05(y9`K%zIXhCWk)KT`ri^Nk+{Kd0)nn1}`YScJg52DCfE54*9w2~;3;-7( zmq4yoZO2M0dX^lw@!f8POA(E4m?M^xq}o-y$G1pCydWW25t! zbsmh#WuvnJJKtp!oH!;30J!6d3VgITffv^uxXjpcH5p$Lp86lO20%kVBhYdhQ>x;U z`6amb+A5S6`S91bI(1uz8PBd=1tEKwMU;%m4$YNa5V9+=hV zz+$!D0iQ_HWjb~JFZ?w9VUoTaHg3Tn67tyS+zbiXQjpu$H9$ZpAh7y@qiOmTn}gkM z$5a!|?md_Q4)^+%l?wgs{$qxKPdf%F+X$gWHXEmsh3+PnQLu?Hn=r8nfjJbK%Lfu` zRr_a7fD}}D!zJZ7sxnAFczEwkj;Pw&Cm3$;W2nwr`Dr%1(mFfDAy)P?02VT3C(?=M)Zm=i{0LhyZp_ zWVBPku2aFTQ$Q#15&OI2iVBP$6NJi5Kp24hX+SW3xN!7{?YGw? z;1de$x_$ju7~KclJqWy0#>OdS?Ua5R5{^hfXg*7U$h*7hld8Ve8&M?*w|#32cK=}( z{pgaiV17Zm8j-eRDXXgrDxFIPptObdZU;MR6T|xSS%hcroCK{La4-${H0ICBLwS*J zL>ad2>xGjNAOpadT=u~C)eLy2jEz&q+AU@6j$-4EV(pHi)80Nwp0@tkz}&a?(Cl@0 z|H}lhaf=mI*D57ae}AuQ$g`@_0PelE3eBrdpyw7Jg_+0t3E45I;vPV0C?WB{?;A(# zcjlxl+psmG@1dIbZO0l;{3&!1xr^ z@JnAAvNDfIKxjToHo73Q&lj@Mh0s0{9IU@>SslCj$o|76^NaA@U6VkTK~Jy2mG|r( zPCy?6@J4#1@^MYC*ETzab7tpa{bSSc_$}iB00j1?gfKpt-8Du8;}wgpst}u2%n(zn z!~K1%|F9c>exqI3E^Zwr!-!usIxl0~6nOi*Tf|xyaU#-M*PO=fPt+cf003Apw+Q!N zKNcXyD;v77Y-RJ1=Xwy4t(`WSJ8U$xrIE4+v~=6P1pGq6H3mzrtHP;MvmuB;83GVU zLl$)7sA@lbuwn-8ys`pH4iH<@oWfUsx?NjRy%qGG`1-*z4)X>>^NpWfZ!c%q0sx?fGj@lzrIfIq$7j)iyZ1Y@WS zSpkVF&Mv`~XP4j`i+5qqZWpfK#-gh#u&XYK|6Y3lNcf?A3}ZRC^U4a(wipB)0J`HY zW?j9-)VH`zFypTiBC?B=RX^B)8m<9G=Q3v;9HaBV{o3G7g`_WplpmKa-iey#)Da2r zTLM40s0=c|;F!XhH*Le(4?O!|>)u}Yp%ALeL#RFv)vkl%vf5GQZ^e^;Zo|y0Hsh0q zBxI+zaNqsg20XvE3z8K$n8wVher#Aieb}f205kB7pMAo0Eq2shnSf| zOySUc3Y2UZU>MmepA2_fQO68L__mUzZ*Sd3WVmmg+@D7?AleV zol4K@va2%YXC+iBm;4S?&;<+uV3ZUoyuEB1#uN`HVekGFj=y>{;+=$(3+wU4*&9Is z)~q`o@6}cT0RyWogr|OWC(b+nwPEjneZeDG``!%b@?O}|!9{b5aL;!tF@AJ#Slhwn zZ*O8leS2{ojAwIr?D#2Oli$bd~4Y_gb578{cV))CLOH4!#C8^RzGl6d{mskr^}G1#zt zI<7jW1e!FOT3t-Ld=uW>(%s)(Z%X5-ms)X5apN%X0C2~m$B>sDM>=t63$V4-bBu~| ztxp9$nKt<9t=nNI1vnN08=cK;A}}TgtRrkZeDG=*7`zBFhuD}fmT^NImt#M%jSzrPiCF0VsZ%*6|Db|95z%&Mv#QP@Brg_7cS zbazJZ)0=OB)^b>zXMcA-ge%a{mcs7F<&AbY+Q4N4Eeupg5cfUZi1PC{ z;M)85z)JW~zkAGx!Zy^GVt-v3h=He{xCm#Q`V3aDoC9WWHNX8QH{+duegXc@AUGj$ z?k(HVn>w_M|J&8AcF{g%q9e6)_~03KaO2{tkL#3cAc^8 z+T)D2$Fl2G!I&J+4%d)HaX366h-EC8ga8=mR;`e}8dAP}q^uetefvoHYDii8L}vK? zVB=%vK<0NK^E(JOA!2}}0hEUBu^=4l!0B4gq@cJ z1mlKl7oldarwQv{KOSHI(v!I4(gG}9W-w=-!R*r+x8KG1c)=HdoOb!w$jgR*B!WahG5;DMWj6rFE z59LLE2m*)*+Awz2ClE_$5CN9-H5;eomr@nKE~IZ?#t>o!W(#n_S~Q;~Bk?a9t^HLc z0X}7FE{>a=h2xHjV8+BO1pP-2A`t=SoRW_l9^MOKJi9#{Orfo*7{owU7DfaQ02g0o z&`{qp1Uvvpsd3)ixA4xAsdz7*0t}OC*>c~t*&cHW6SP19{j`p z;j7H^CTv3~!h*SlxbA|| zAra(5mC8|mRF3lFD<|g5Pp@u6 zIL>(PrJGPv>ctQ&pM!^%FT$SfRao)ZSlo2`&{ciy-w97H6_|d)@Gu$xy!ww*;FQL3 z`B}wy_y^U<4iDct4^`qxji+C3#e>i7H}$P)!<_Rf6pKDzKp5&7B>?;3KQ{TR%Y)*w zGmHO6zyaWcU2)X5rm$ef)_(APB@|BK`XB!eH(zlVx>|v%@r+0=@aigomsSy&7;nEh z6C2*1j^j_>0swGbi6!@Z7pqs!fg0b9EuZuvme8MyfZdHr{OT{wc=E5!Y&$T<4Qv%$ z`DZ2b-UA?rnGu|0k7d`c*1C7Hp{C1O#Ai;e4)b@;FQtp;6(K+SUpqm&ZCNcIdZr0K znYS9Z-}UIQ=joImCsn?L=z$yvCKzJmkLtvz(QT-$8I7KJ7+E=SOgsK#ga|LizTQ^6ec$fN||{?Ap}^v6-y8X9$(fBf)g`N%^?)Y;TbnyxJdJ;z^C4JXV8W zzt{}_fe>cpx8Sw6FCEs-u`Qff@iG#zAkM$!@3{Q?f57BvUc{)gJr@_9`8am%sD>R$ z!!AoA8BQbYmzX*}j9v9fbjBQ5S^|pU!l1GwfJDk5o^+8&8wdd?ZNW}RKwE(8?zq3UW%m;U4b9`@TvZG%!EgmT#1g3T&#HUCd@s1{g8h0 z3#0ha9Z%qz%kD#LViYqcMR3QJ<8jW(`5^K_XKUV%;zy6{!;ZQnMBI4HI=Hl5`4j@<`!R!g2VD{-7kxp57Z{196 z**FDcfOR{*hRSin!{*Uw1QRF!9X;c_(6Z`86z2^;-_VA!Y-J06`s*5`k^mnFf>M4k z0W26sAoCl5lo z?rYwUw5f+rTTt494mh~w($V<&)m5lzPT@~$J75AX-q|_@Z?=pDa$PvkaA&q5+!V&H zZR1BI;N5kzU}vW>xgsAy7>&td1~X8I+U>y!q%PVP9@xNZ8=ulF#)%Ja}1K@3EXkl_u#riSMpdajAf5p0u(qn=hP#| z91C(REc@{UtXgt3!UYyk{(uQ`#|q*3eVp!7muy0fm@jE{CC zQCy->_xy3gyf*;&$NOD4I1CR`W6In<01`}&U8brxVMpiPDk(KbWvqZ9Q)Y0c=mc-!8ak1u?#|#6% zac3MKd=iIN8n<3HdPML5@TKGOFm+rQ=}`%=0Fo18C_GAI!PjzOmDv!kz`D)dIOE2x zhm8XqT%;h}eN7eq`)8A(!Zt*9-0xxXGR-phk|0VZ)`;{#mR28F61_ws2|>Le5hoIH zZ$Shg7@{bKtXzYCJ~j=rr{xS2;K@}j@R2|yq;S>QqYf+V4GYVW%1MF=u%(N8zgvZ; zZl8#cp7{c*DlG^iyt_4y)2{yrd-oqX1V6Z3G^Y^%_~kJOMjXG4v`>OGc7}*vknmFP zFgPSelprB`K?A^vL@$Jhfkcc2LlnkPP)K<9iRqXzF>BaI6DfmdUulIQ;Co*$MJRB1 z)s+HJg1`ds(LhGY*wO$tET4hXzmN?UjIBG9IOdz1@c4_(hwbm+a{BZfyz}@p%FQ)7 z6lnP(NW?+Zo56W70b&5S5OI)dvGtlbi-Dx{UD0EmNbkx zOy`+$Y;_o`A2?bV*p*uDKhe`@5eJE0V9>!xVhwRteHo`iy&NH8WJC{y?13@eEOa-^WRQIE(xo?!KkP}&oy%*nw=o3`#*GWh z4+}o+7+n90y|B_2oPrb#GpwEfK4};^@_Y5Uqj18M2rl^Pb~Nl~_?q&-mWHtm8loEY zHA(z4&}0upOPIy6^wGm9vM$N?N9e4Vo| znp@1*T~K;RFX*kUJ-Gk(jS!B)%qan!Fy+uh0l*Cp@AERh0>FiH3egjHv1WZ7tx*T< z-3|(KhFgEfR)=xVwNfH%wJg4P8PM3))I+2#_;Uq>2y(5!f<-838;|iiB(@q1s8P4id71r0jr@9VBEY z3E6dUZt=*G4k5dU{dLla_QzgmE_v*QX10_}O9q-#<^AT1+~D=jhrzz})8_|e5x z!;YyBL>(;sQxhKfa}#=#8XOIPa#L9R?W%r9C*booBR8h-)Jv^cbXDbuPLR(cl;r!+ z+O0vhH2_`!AlM{TD@oPnRe6AEoelFRf-zp26~| zRuZa>ggih(9ynAY^)Ttf za$P6T5drlEhN!BS*fsP!buB3f0qFN4(A+UJW$xE6G()8PVDh5EZnq!LzS4%;5mIo*migfr4M^GMfwwZXPbSrz zk+Zc=_QT;jVz@W4hIDAYYRM=Z0A%ttNuw`#VpQzrU)AKKZ9_-})94L)=3>T!?2jWb z07qi;Cvo)jdSUI|jY+({tq16hfcl0b?T17P|M5&Cmi>7A5P3=qd@#%)DVs=Gtt3J~H}lyPpU%z~+8Q{VS9 ze=}NOHTA7ei8bVm0B1<~)B*p*8gfGORa3?_&RlB~DG;TgMM4^X8$;(q>Rcw%4I%rI z6SDfx;~5q}P{xOg@7w_bK|2CYXJq(L*nWpNrIxL1p`Twfa8lJDUQnu$U^S7H9ht4J zorF99>8bsvy)W=Dop^YiTFs%ki zkOYP@(ONHnDbhmcP)ASGnJd?K^hcgH?u@~2$!_NGE)uefgzW4i;d8q)G$IMF$#`gf ze}p9lA$q+0LXl0vWV4Z3#3qY{34%F9UebjhU>}$j9qQJY7rM5+0H!}B$v=MSpPI&g z?es#y3_SlvyLOG-rj%7jB)drbd$-0ulZ%tX?+xnA+~;tA&XIR@*3Zn=NcRRY_}-uw zx=w>AZA8adLv1&maY8O4AxY1_(cu!6eATC_HhvcO20yo(qwv!0!d~JP2fZo4zJKNB zC}q|dml}^E(eX1SM046zj|O}*pZ=_Fj(%=;hrMhp4h<}T#`pjH-Qh!(|C?`*|8Kp| Vbe`VmBdGuY002ovPDHLkV1f`^TH62s literal 0 HcmV?d00001 diff --git a/mseide-msegui/tools/bmp2pas.pas b/mseide-msegui/tools/bmp2pas.pas new file mode 100644 index 0000000..288dcc1 --- /dev/null +++ b/mseide-msegui/tools/bmp2pas.pas @@ -0,0 +1,112 @@ +{ MSEide Copyright (c) 1999-2014 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +program bmp2pas; + +// commandline: bmp2pas -oDESTFILE BITMAPFILE ... +// 'bmp2pas -oregcomps_bmp.pas tcomp1.bmp tcomp2.bmp tcomp3.bmp' +// -> bitmapunit for tcomp1,tcomp2,tcomp3 + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifndef FPC} +{$APPTYPE CONSOLE} +{$endif} + +uses + {$ifdef FPC}{$ifdef unix}cthreads,{$endif}{$endif} + mseguiinifini, + SysUtils, + msetypes, + msesysenv, + msestrings, + msefileutils, + msesysutils, + msebitmap, + mseclasses, + mseformdatatools,mseguiintf, + mseformatpngread,mseformatbmpicoread, + msegraphutils; + +type + argty = (arg_dest,arg_names); + +const + arguments: array[argty] of argumentdefty = + ((kind: ak_pararg; name: 'o'; anames: nil; flags: []; initvalue: ''), + (kind: ak_arg; name: ''; anames: nil; flags: []; initvalue: '') + ); + +var + sysenv: tsysenvmanager; + ar1,ar2: msestringarty; + int1: integer; + bmps: array of tbitmapcomp; + str1,str2: msestring; + +begin + try + sysenv:= tsysenvmanager.create(nil); + sysenv.init(arguments); + str1:= sysenv.value[ord(arg_dest)]; + ar1:= sysenv.values[ord(arg_names)]; + try + setlength(bmps,length(ar1)); + try + for int1:= 0 to high(ar1) do begin + if ar1[int1] <> '' then begin + bmps[int1]:= tbitmapcomp.create(nil); + ar2:= nil; + splitstring(ar1[int1],ar2,widechar(',')); + if (length(ar2) < 1) or (length(ar2)>2) then begin + errorhalt('Invalid parameter: '+ar1[int1]); + end; + if length(ar2) > 1 then begin + bmps[int1].name:= ar2[1]; + end + else begin + bmps[int1].name:= removefileext(filename(ar2[0])); + end; + writestdout( + 'Converting file "'+ar2[0]+'" componentname "'+bmps[int1].name+'".',true); + with bmps[int1].bitmap do begin + loadfromfile(ar2[0],'',[]); + if fileext(ar2[0]) = 'png' then begin + transparentcolor:= cl_none; + colormask:= true; + masked:= true; + end; + end; + end; + end; + str2:= removefileext(filename(str1)); + writestdout( + 'Write unitfile "'+str1+'".',true); + componentstoobjsource(componentarty(bmps),str1,'msebitmap',str2); + finally + for int1:= 0 to high(bmps) do begin + bmps[int1].Free; + end; + end; + except + on e: exception do begin + sysenv.destroy(); + errorhalt(e.message); + end; + end; + finally + sysenv.destroy(); + end; +end. diff --git a/mseide-msegui/tools/bmp2pas.prj b/mseide-msegui/tools/bmp2pas.prj new file mode 100644 index 0000000..8f64f82 --- /dev/null +++ b/mseide-msegui/tools/bmp2pas.prj @@ -0,0 +1,967 @@ +[componentpalette] +order0=0 +order1=0 +order2=0 +order3=0 +order4=0 +order5=0 +order6=0 +order7=0 +order8=0 +order9=0 +order10=0 +order11=0 +order12=0 +order13=0 +order14=0 +order15=0 +order16=0 +order17=0 +order18=0 +[projectoptions] +projectdir=/home/mse/packs/standard/git/mseide-msegui/tools +projectfilename=/home/mse/packs/standard/git/mseide-msegui/tools/bmp2pas.prj +mainfile=bmp2pas.pas +targetfile=bmp2pas${EXEEXT} +messageoutputfile= +makecommand=${COMPILER} +makedir= +unitdirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}kernel/ + ${MSELIBDIR}*/ +unitpref=-Fu +incpref=-Fi +libpref=-Fl +objpref=-Fo +targpref=-o +befcommand=0 +aftcommand=0 +makeoptions=4 + -Xg -l -Mobjfpc -Sh -Fcutf8 + -gl + -B + -OG2p3 -XX -CX -Xs +codetemplatedirs=1 + ${TEMPLATEDIR} +toolmenus=0 +toolfiles=0 +toolparams=0 +fontnames=0 +scriptbeforecopy= +scriptaftercopy= +newprojectfiles=0 +newprojectfilesdest=0 +newfinames=3 + Program + Unit + Textfile +newfifilters=3 + "*.pas" "*.pp" + "*.pas" "*.pp" + +newfiexts=3 + pas + pas + +newfisources=3 + ${TEMPLATEDIR}default/program.pas + ${TEMPLATEDIR}default/unit.pas + +newfonames=11 + Mainform + Simple Form + Docking Form + Datamodule + Subform + Scrollboxform + Tabform + Dockpanel + Report + Scriptform + Inherited Form +newfonamebases=11 + form + form + form + module + form + form + form + form + report + script + form +newfosources=11 + ${TEMPLATEDIR}default/mainform.pas + ${TEMPLATEDIR}default/simpleform.pas + ${TEMPLATEDIR}default/dockingform.pas + ${TEMPLATEDIR}default/datamodule.pas + ${TEMPLATEDIR}default/subform.pas + ${TEMPLATEDIR}default/scrollboxform.pas + ${TEMPLATEDIR}default/tabform.pas + ${TEMPLATEDIR}default/dockpanelform.pas + ${TEMPLATEDIR}default/report.pas + ${TEMPLATEDIR}default/pascform.pas + ${TEMPLATEDIR}default/inheritedform.pas +newfoforms=11 + ${TEMPLATEDIR}default/mainform.mfm + ${TEMPLATEDIR}default/simpleform.mfm + ${TEMPLATEDIR}default/dockingform.mfm + ${TEMPLATEDIR}default/datamodule.mfm + ${TEMPLATEDIR}default/subform.mfm + ${TEMPLATEDIR}default/scrollboxform.mfm + ${TEMPLATEDIR}default/tabform.mfm + ${TEMPLATEDIR}default/dockpanelform.mfm + ${TEMPLATEDIR}default/report.mfm + ${TEMPLATEDIR}default/pascform.mfm + ${TEMPLATEDIR}default/inheritedform.mfm +forcezorder=0 +stripmessageesc=0 +copymessages=0 +closemessages=1 +checkmethods=1 +colorerror=-1610612712 +colorwarning=-1610612717 +colornote=-1610612716 +usercolors=30 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +usercolorcomment=30 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +formatmacronames=0 +formatmacrovalues=0 +settingsfile= +settingseditor=0 +settingsdebugger=0 +settingsstorage=0 +settingsprojecttree=0 +settingsautoload=0 +settingsautosave=0 +modulenames=0 +moduletypes=0 +modulefiles=0 +befcommandon=0 +makeoptionson=4 + 63 + 31 + 34 + 32 +aftcommandon=0 +unitdirson=3 + 65599 + 196671 + 65599 +macroon=0 +macronames=0 +macrovalues=0 +macrogroup=0 +groupcomments=6 + + + + + + +toolsave=0 +toolhide=0 +toolparse=0 +toolmessages=0 +toolshortcuts=0 +fontalias=0 +fontancestors=0 +fontheights=0 +fontwidths=0 +fontoptions=0 +fontxscales=0 +expandprojectfilemacros=0 +loadprojectfile=0 +newinheritedforms=11 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 +uid=0 +sourcefilemasks=3 + "*.pas" "*.dpr" "*.lpr" "*.pp" "*.inc" + "*.c" "*.cc" "*.h" + "*.mfm" +syntaxdeffiles=3 + ${SYNTAXDEFDIR}pascal.sdef + ${SYNTAXDEFDIR}cpp.sdef + ${SYNTAXDEFDIR}objecttext.sdef +filemasknames=3 + Source + Forms + All Files +filemasks=3 + "*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + *.mfm + * +showgrid=1 +snaptogrid=1 +moveonfirstclick=1 +noformdesignerdocking=0 +gridsizex=8 +gridsizey=8 +autoindent=1 +blockindent=1 +linenumberson=0 +rightmarginon=1 +rightmarginchars=80 +scrollheight=0 +tabstops=4 +spacetabs=0 +showtabs=0 +tabindent=0 +editfontname=mseide_source +editfontheight=0 +editfontwidth=0 +editfontextraspace=0 +editfontcolor=-1879048183 +editbkcolor=-1879048186 +statementcolor=14745599 +editfontantialiased=1 +editmarkbrackets=1 +backupfilecount=2 +encoding=1 +codetemplatedirs=1 + ${TEMPLATEDIR} +debugcommand=${DEBUGGER} +debugoptions= +debugtarget= +runcommand= +xtermcommand=xterm -S${PTSN}/${PTSH} +remoteconnection= +uploadcommand= +gdbprocessor=auto +gdbservercommand= +gdbservercommandattach= +beforeconnect= +afterconnect= +beforeload= +afterload= +beforerun= +sourcebase= +sourcedirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ + ./ +defines=0 +progparameters= +progworkingdirectory= +envvarnames=0 +envvarvalues=0 +defineson=0 +stoponexception=0 +valuehints=1 +activateonbreak=1 +raiseonbreak=1 +showconsole=0 +externalconsole=0 +settty=1 +gdbdownload=0 +downloadalways=0 +startupbkpt=0 +startupbkpton=0 +gdbsimulator=0 +gdbserverstartonce=0 +gdbloadtimeout= +gdbserverwait=0 +nogdbserverexit=0 +gdbservertty=0 +exceptclassnames=1 + EconvertError +exceptignore=1 + 0 +nodebugbeginend=0 +sigsettings=27 + 1,1,T,F + 3,3,T,F + 4,4,T,F + 6,6,T,F + 7,7,T,F + 8,8,T,F + 9,9,T,F + 10,10,T,F + 11,11,T,F + 12,12,T,F + 13,13,T,F + 15,15,T,F + 16,16,T,F + 17,17,F,F + 18,18,T,F + 19,19,T,F + 20,20,T,F + 21,21,T,F + 22,22,T,F + 23,23,T,F + 24,24,T,F + 25,25,T,F + 26,26,T,F + 27,27,T,F + 28,28,T,F + 29,29,T,F + 30,30,T,F +defaultmake=1 +[breakpoints] +on=0 +path=0 +line=0 +address=0 +addbkpt=0 +ignore=0 +condition=0 +panels=2 + panel1 + panel2 +units= + ( + a=0,4132,6,Pascal Units + ) +cmodules= + ( + a=0,4132,6,C Modules + ) +files= + ( + a=0,4132,6,Text Files + ) +[componentstore] +storedir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ +filename= +[components] +[selecteditpage] +colwidth=100 +x=0 +y=0 +cx=0 +cy=0 +[progparams] +progparamhistory=0 +workdirparamhistory=0 +envvarons=0 +[edit] +hintwidth=0 +hintheight=0 +finddtext= +findhistory=0 +findoptions=1 +editpos=1 + 0,0 +bookmarks0=0 +sourcefiles=1 + /home/mse/packs/standard/git/mseide-msegui/tools/bmp2pas.pas +relpaths=1 + bmp2pas.pas +ismoduletexts=1 + 0 +modules=0 +moduleoptions=0 +visiblemodules=0 +nomenumodules=0 +[sourcefo.tabwidget] +tabsize=134 +firsttab=0 +index=0 +[layout] +windowlayout=531 + [mainfo.openform] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.projectfiledia] + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + [mainfo.openfile] + filenames=0 + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + filehistory=1 + /home/mse/packs/standard/git/mseide-msegui/tools/bmp2pas.pas + filefilterindex=0 + filefilter="*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + [mainfo.basedock] + splitdir=2 + useroptions=146560 + [mainfo] + splitdir=0 + useroptions=33554555 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=25 + cx=323 + cy=64 + rcx=0 + rcy=0 + wsize=0 + active=1 + visible=1 + [targetconsolefo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=554 + cx=323 + cy=169 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [threadsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=37 + y=270 + cx=349 + cy=276 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo] + splitdir=0 + useroptions=16507 + stackedunder=componentpalettefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=100 + y=100 + cx=453 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo.add] + value=0 + [memoryfo.memon] + value=0 + [memoryfo.bitwidth] + value=0 + [memoryfo.cnt] + value=0 + [disassfo] + splitdir=0 + useroptions=16491 + stackedunder=mainfo.panel2 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=162 + y=502 + cx=564 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [findinfilefo] + splitdir=0 + useroptions=16491 + stackedunder=disassfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=548 + y=115 + cx=369 + cy=198 + rcx=0 + rcy=0 + [projecttreefo] + splitdir=0 + useroptions=16491 + stackedunder=memoryfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=263 + y=431 + cx=286 + cy=201 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [projecttreefo.grid] + propcolwidthref=135 + width0=141 + sortdescend0=0 + width1=129 + sortdescend1=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=16 + [stackfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=276 + rcx=0 + rcy=0 + [watchpointsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=120 + y=368 + cx=483 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [watchpointsfo.grid] + propcolwidthref=352 + sortdescend0=0 + values1=0 + values1_ci=-1 + width1=33 + sortdescend1=0 + values2=0 + width2=158 + sortdescend2=0 + width4=34 + sortdescend4=0 + values5=0 + values5_ci=-1 + width5=38 + sortdescend5=0 + values6=0 + width6=184 + sortdescend6=0 + [breakpointsfo] + splitdir=0 + useroptions=16491 + stackedunder=projecttreefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=107 + y=404 + cx=636 + cy=128 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [breakpointsfo.bkptson] + value=1 + [objectinspectorfo] + splitdir=0 + useroptions=16491 + stackedunder=breakpointsfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=724 + y=157 + cx=296 + cy=566 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [objectinspectorfo.grid] + propcolwidthref=286 + width0=105 + sortdescend0=0 + width1=175 + sortdescend1=0 + [symbolfo] + splitdir=0 + useroptions=16507 + stackedunder=findinfilefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=142 + y=257 + cx=361 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [symbolfo.grid] + propcolwidthref=222 + values0=0 + width0=111 + sortdescend0=0 + width1=135 + sortdescend1=0 + [symbolfo.symbol] + [watchfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=279 + cx=313 + cy=221 + rcx=0 + rcy=0 + [watchfo.grid] + propcolwidthref=118 + values0=0 + values0_ci=-1 + sortdescend0=0 + values1=0 + width1=152 + sortdescend1=0 + values3=0 + values3_ci=-1 + sortdescend3=0 + values4=0 + values4_ci=-1 + width4=13 + sortdescend4=0 + [watchfo.watchon] + [watchfo.expression] + [watchfo.watcheson] + value=1 + [messagefo] + splitdir=0 + useroptions=49259 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=510 + cx=675 + cy=95 + rcx=0 + rcy=0 + [componentstorefo] + splitdir=0 + useroptions=24699 + stackedunder=symbolfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=305 + y=101 + cx=445 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentstorefo.grid] + propcolwidthref=435 + width0=111 + sortdescend0=0 + sortdescend1=0 + width2=112 + sortdescend2=0 + width3=185 + sortdescend3=0 + [componentstorefo.storefiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.groupfiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.compfiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentpalettefo] + splitdir=0 + useroptions=24683 + stackedunder=componentstorefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=25 + cx=685 + cy=103 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentpalettefo.componentpages] + activetab=0 + [debuggerfo] + splitdir=0 + useroptions=24683 + parent=mainfo.basedock + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=28 + rcx=0 + rcy=0 + [sourcefo] + splitdir=0 + useroptions=16489 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=675 + cy=507 + rcx=0 + rcy=0 + [actionsmo.watchesonact] + checked=1 + [actionsmo.bluedotsonact] + checked=1 + [cpui386fo] + irqoff=0 + splitdir=0 + useroptions=16491 + stackedunder=mainfo.panel1 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=25 + cx=273 + cy=207 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel1] + splitdir=2 + useroptions=33586667 + stackedunder=targetconsolefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=118 + cx=685 + cy=605 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel2] + splitdir=2 + useroptions=33586667 + stackedunder=cpui386fo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=25 + cx=323 + cy=500 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 +[targetconsole] +finddtext= +findhistory=0 +findoptions=1 diff --git a/mseide-msegui/tools/data2pas.pas b/mseide-msegui/tools/data2pas.pas new file mode 100644 index 0000000..be63f7f --- /dev/null +++ b/mseide-msegui/tools/data2pas.pas @@ -0,0 +1,75 @@ +{ MSEide Copyright (c) 2017 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +program data2pas; + +// commandline: data2pas -oDESTFILE SOURCEFILE +// 'data2pas -odata.pas data.bin +// -> dataunit for data.bin + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifndef FPC} +{$APPTYPE CONSOLE} +{$endif} + +uses + {$ifdef FPC}{$ifdef unix}cthreads,{$endif}{$endif} + SysUtils,msesys,msesysutils, + msetypes, + msesysenv, + msestrings, + msefileutils, + mseformdatatools,msestream; + +type + argty = (arg_dest,arg_names); + +const + arguments: array[argty] of argumentdefty = + ((kind: ak_pararg; name: 'o'; anames: nil; flags: [arf_mandatory]; + initvalue: ''), + (kind: ak_arg; name: ''; anames: nil; flags: []; initvalue: '') + ); + +var + sysenv: tsysenvmanager; + s1,s2: msestring; + source1: tmsefilestream; + dest1: ttextstream; + dir1,file1,ext1: filenamety; +begin + source1:= nil; + dest1:= nil; + sysenv:= tsysenvmanager.create(nil); + try + if sysenv.init(arguments) then begin + s1:= sysenv.value[ord(arg_dest)]; + s2:= sysenv.value[ord(arg_names)]; + splitfilepath(s1,dir1,file1,ext1); + if ext1 = '' then begin + ext1:= '.pas'; + end; + s1:= filepath(dir1,file1+ext1); + dest1:= ttextstream.create(s1,fm_create); + source1:= tmsefilestream.create(s2,fm_read); + datatoobjsource(source1,dest1,file1); + end; + finally + sysenv.destroy(); + source1.free(); + dest1.free(); + end; +end. diff --git a/mseide-msegui/tools/data2pas.prj b/mseide-msegui/tools/data2pas.prj new file mode 100644 index 0000000..d755fd0 --- /dev/null +++ b/mseide-msegui/tools/data2pas.prj @@ -0,0 +1,43 @@ +[projectoptions] +mainfile=data2pas.pas +targetfile=data2pas${EXEEXT} +makecommand=${COMPILER} +makedir= +unitdirs=5 + ${MSEDIR}lib/addon/*/ + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ + ../../toolsskin + ../lib +unitpref=-Fu +incpref=-Fi +libpref=-Fl +objpref=-Fo +targpref=-o +befcommand=0 +aftcommand=0 +makeoptions=4 + -Xg -l -Mobjfpc -Sh -Fcutf8 ${fpcflags} + -gl -O- -gh + -B + -O2 -XX -Xs -CX +reversepathorder=0 +makeoptpurpose=4 + + + + +befcommandon=0 +makeoptionson=4 + 63 + 31 + 34 + 32 +aftcommandon=0 +unitdirson=5 + 196671 + 65599 + 65599 + 983103 + 983103 +uid=0 diff --git a/mseide-msegui/tools/dist/copybin.sh b/mseide-msegui/tools/dist/copybin.sh new file mode 100755 index 0000000..8817773 --- /dev/null +++ b/mseide-msegui/tools/dist/copybin.sh @@ -0,0 +1,31 @@ +#!/bin/sh +DESTDIR=/home/mse/proj/mseguidist/bin +MSELINUXDIR=/home/mse/packs/standard/git +MSEWINDOWSDIR=/windows/F/git +MSELINUX64DIR=/opensuse_64/home/mse/packs/standard/git +MSEBSDDIR=/freebsd/home/mse/packs/standard/git +sudo mount -t ufs -o ufstype=ufs2,ro /dev/sda2 /freebsd + +set -e + +#exeext, sourcedir, destdir +docopy(){ +echo DEST: $3 + TMP=$2/mseide-msegui/apps/ide/mseide$1 + echo " Copying $TMP" + cp $TMP ${DESTDIR}/$3 + TMP=$2/mseuniverse/tools/msespice/msespice$1 + echo " Copying $TMP" + cp $TMP ${DESTDIR}/$3 + TMP=$2/mseuniverse/tools/msegit/msegit$1 + echo " Copying $TMP" + cp $TMP ${DESTDIR}/$3 + TMP=$2/mseuniverse/tools/mserun/mserun$1 + echo " Copying $TMP" + cp $TMP ${DESTDIR}/$3 +} + +docopy "" ${MSELINUXDIR} i386-linux +docopy "" ${MSELINUX64DIR} x86_64-linux +docopy "" ${MSEBSDDIR} x86_64-freebsd +docopy ".exe" ${MSEWINDOWSDIR} i386-win32 \ No newline at end of file diff --git a/mseide-msegui/tools/dist/makdist.mrp b/mseide-msegui/tools/dist/makdist.mrp new file mode 100644 index 0000000..d36186d --- /dev/null +++ b/mseide-msegui/tools/dist/makdist.mrp @@ -0,0 +1,315 @@ +[mainmo.projectstat] +savedmemoryfiles=6 + run.sta + macros.sta + memodialog.sta + testedit.sta + edit.sta + groupedit.sta +run.sta=6 + [runfo] + stackedunder= + x=348 + y=198 + cx=897 + cy=460 +macros.sta=9 + [macrosfo] + stackedunder= + x=145 + y=63 + cx=1195 + cy=491 + wsize=0 + active=1 + visible=1 +memodialog.sta=8 + [msememodialogfo] + x=507 + y=359 + cx=481 + cy=255 + wsize=0 + active=1 + visible=1 +testedit.sta=9 + [testeditfo] + stackedunder= + x=632 + y=260 + cx=596 + cy=581 + wsize=0 + active=1 + visible=1 +edit.sta=9 + [groupeditfo] + stackedunder= + x=225 + y=419 + cx=596 + cy=581 + wsize=0 + active=1 + visible=1 +groupedit.sta=9 + [groupeditfo] + stackedunder= + x=225 + y=419 + cx=596 + cy=581 + wsize=0 + active=1 + visible=1 +[tree] +kind=0 +a=0,665,0, +c=1 + ( + kind=1 + a=0,665,4, + c=2 + ( + kind=1 + a=0,665,4,MSEide-MSEgui + c=1 + ( + kind=2 + a=0,648,1,MSEide + teststate=1 + path=apps/ide/mseide.pas + comment= + cc= + cd= + rc= + rd= + in= + eo= + ao=0 + ee= + ae=0 + eec=0 + cr=0 + ao=0 + ae=0 + aec=0 + ie=0 + ) + teststate=1 + path=${MSEBASEDIR}/mseide-msegui${MAC_IFDEF(DIREXT)}/ + comment= + cc= + cd= + rc= + rd= + in= + eo= + ao=0 + ee= + ae=0 + eec=0 + cdef= + pdef= + ) + ( + kind=1 + a=0,665,4,MSEuniverse + c=4 + ( + kind=2 + a=0,648,1,MSEgit + teststate=1 + path=msegit/msegit.pas + comment= + cc= + cd= + rc= + rd= + in= + eo= + ao=0 + ee= + ae=0 + eec= + cr=0 + ao=0 + ae=0 + aec=0 + ie=0 + ) + ( + kind=2 + a=0,648,1,MSEspice + teststate=1 + path=msespice/msespice.pas + comment= + cc= + cd= + rc= + rd= + in= + eo= + ao=0 + ee= + ae=0 + eec= + cr=0 + ao=0 + ae=0 + aec=0 + ie=0 + ) + ( + kind=2 + a=0,648,1,MSErun + teststate=1 + path=mserun/mserun.pas + comment= + cc= + cd= + rc= + rd= + in= + eo= + ao=0 + ee= + ae=0 + eec= + cr=0 + ao=0 + ae=0 + aec=0 + ie=0 + ) + ( + kind=2 + a=0,648,1,MSEkicadBOM + teststate=1 + path=kicad/bom/msekicadbom.pas + comment= + cc=${FPC} -Fu${MSEBASEDIR}/mseuniverse/tools/toolsskin -Fu../lib ${FILE} + cd=${file_noname($file)} + rc= + rd= + in= + eo= + ao=0 + ee= + ae=0 + eec= + cr=0 + ao= + ae= + aec=0 + ie=0 + ) + teststate=1 + path=${MSEBASEDIR}/mseuniverse${MAC_IFDEF(DIREXT)}/tools/ + comment= + cc=${FPC} -Fu${MSEBASEDIR}/mseuniverse/tools/toolsskin ${FILE} + cd= + rc= + rd= + in= + eo= + ao=0 + ee= + ae=0 + eec= + cdef= + pdef= + ) + teststate=1 + path= + comment= + cc=${FPC} ${FILE} + cd= + rc= + rd= + in= + eo= + ao=0 + ee= + ae=0 + eec=0 + cdef= + pdef= + ) +teststate=0 +[options] +[mainmo.stoponfirsterr] +checked=0 +[mainmo.stoponcomperr] +checked=0 +[mainmo.trttistat1] +macronames=10 + FPCINSTDIR + COMPILERBIN + COMPILERBIN + MSEBASEDIR + MSELIBDIR + FPCUNITS + MSEUNITS + COMPILER + FPCFLAGS + FPC +macrovalues=10 + + ppc386 + ppcx64 + /home/mse/packs/standard/git/ + ${FILE_SYS(${MSEBASEDIR}/mseide-msegui${MAC_IFDEF(DIREXT)}/lib/common/)} + -Fu${FILE_SYS(${FPCINSTDIR}/${FPCUNITDIR}/*)} + -Fu${MSELIBDIR}* -Fu${FILE_SYS(${MSELIBDIR}kernel/)}${TARGET} + ${FPCINSTDIR}${FILE_SYS(${COMPILERBIN})} + -n -viwn -Xg -B -O2 -XX -Xs -CX -l -Fcutf8 -dmse_with_deprecated ${MSEUNITS} ${FPCUNITS} ${MAC_IFDEF(OPT)} + ${COMPILER} ${FPCFLAGS} +macroon=10 + 0 + 0 + 0 + 0 + 63 + 63 + 63 + 63 + 63 + 63 +macrogroup=0 +groupcomment=6 + 386 + x64 + + + + +[mainfo] +stackedunder= +x=129 +y=75 +cx=588 +cy=254 +wsize=0 +active=1 +visible=1 +[mainfo.grid] +propcolwidthref=497 +width0=50 +sortdescend0=0 +width1=151 +sortdescend1=0 +width2=294 +sortdescend2=0 +width3=221 +sortdescend3=0 +sortdescend4=0 +rowstate=8 + 0 0 + 0 0 + 0 0 + 0 0 + 0 0 + 0 0 + 0 0 + 0 0 diff --git a/mseide-msegui/tools/dist/makeallfp.sh b/mseide-msegui/tools/dist/makeallfp.sh new file mode 100644 index 0000000..95bbeac --- /dev/null +++ b/mseide-msegui/tools/dist/makeallfp.sh @@ -0,0 +1,8 @@ +#!/bin/sh +BASEDIR=/home/mse/packs/standard/svn/fp/ +FPCDIR=/fixes_3_0 +INSTALLDIR=$BASEDIR/builds/fixes_3_0 +PWDBEFORE=$PWD +cd $BASEDIR/$FPCDIR +make clean all install INSTALL_PREFIX=$INSTALLDIR +cd $PWDBEFORE diff --git a/mseide-msegui/tools/dist/runmake.sh b/mseide-msegui/tools/dist/runmake.sh new file mode 100755 index 0000000..546922b --- /dev/null +++ b/mseide-msegui/tools/dist/runmake.sh @@ -0,0 +1,15 @@ +#!/bin/sh +MSERUN=/home/mse/packs/standard/git/mseuniverse/tools/mserun/mserun +FPCINSTDIR=/home/mse/packs/standard/svn/fp/builds/fixes_3_0/ +# +#FPCUNITDIR=lib/fpc/3.0.1/units/x86_64-linux +#COMPILERBIN=lib/fpc/3.0.1/ppcx64 +#OPT="-Fl/usr/local/lib" +FPCUNITDIR=lib/fpc/3.0.1/units/i386-linux +COMPILERBIN=lib/fpc/3.0.1/ppc386 +OPT="-Fl/usr/local/lib" +# +TARGET=linux +MSEBASEDIR=/home/mse/packs/standard/git/ +echo $OPT +$MSERUN --macrodef=FPCINSTDIR,$FPCINSTDIR --macrodef=COMPILERBIN,$COMPILERBIN --macrodef=MSEBASEDIR,$MSEBASEDIR --macrodef=FPCUNITDIR,$FPCUNITDIR --macrodef=TARGET,$TARGET "--macrodef=OPT,$OPT" makdist.mrp diff --git a/mseide-msegui/tools/doc/README.TXT b/mseide-msegui/tools/doc/README.TXT new file mode 100644 index 0000000..c5938d0 --- /dev/null +++ b/mseide-msegui/tools/doc/README.TXT @@ -0,0 +1,4 @@ +2008-01-07 mse + +doc has been moved to +https://gitlab.com/mseuniverse/mseuniverse/tree/master/attic/msedocumenting/mse/trunk/tools/doc diff --git a/mseide-msegui/tools/form2pas.pas b/mseide-msegui/tools/form2pas.pas new file mode 100644 index 0000000..2afa152 --- /dev/null +++ b/mseide-msegui/tools/form2pas.pas @@ -0,0 +1,91 @@ +{ MSEide Copyright (c) 1999-2006 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +program form2pas; + +//convert form files (*.mfm) to pascal files (*_mfm.pas) +//commandline: form2pas FORMFILE[,UNITNAME] ... +//Default UNITNAME is FORMFILE without extension. +// +//'form2pas main.mfm formdesigner.mfm' -> +//convert main.mfm to main_mfm.pas, formdesigner.mfm to formdesigner_mfm.pas + +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifndef FPC} +{$APPTYPE CONSOLE} +{$endif} + +uses + {$ifdef FPC}{$ifdef unix}cthreads,{$endif}{$endif} + SysUtils, + msetypes, + msesysenv, + msestrings, + msefileutils, + msestream, + msesysutils, + msesys, + mseformdatatools; + +const + arguments: array[0..0] of argumentdefty = + ((kind: ak_arg; name: ''; anames: nil; flags: []; initvalue: '')); + +var + sysenv: tsysenvmanager; + ar1,ar2: msestringarty; + int1: integer; + formname,formclass,unitname: string; + stream: ttextstream; +begin + sysenv:= tsysenvmanager.create(nil); + sysenv.init(arguments); + ar1:= sysenv.values[0]; + try + for int1:= 0 to high(ar1) do begin + if ar1[int1] <> '' then begin + {$ifdef msefp} + setlength(ar2,0); //ar2:= nil -> av! + {$else} + ar2:= nil; + {$endif} + splitstring(ar1[int1],ar2,widechar(',')); + if (length(ar2) < 1) or (length(ar2)>2) then begin + errorhalt('Invalid parameter: '+ar1[int1]); + end; + if length(ar2) > 1 then begin + unitname:= ar2[1]; + end + else begin + unitname:= removefileext(filename(ar2[0])); + end; + stream:= ttextstream.Create(ar2[0],fm_read); + try + getobjforminfo(stream,formname,formclass); + finally + stream.free; + end; + writestdout( + 'Converting file "'+ar2[0]+'" class "'+formclass+'" unit "'+unitname+'"''.',true); + formtexttoobjsource(ar2[0],formclass,unitname); + end; + end; + except + on e: exception do begin + errorhalt(e.message); + end; + end; +end. diff --git a/mseide-msegui/tools/form2pas.prj b/mseide-msegui/tools/form2pas.prj new file mode 100644 index 0000000..0c3e3bb --- /dev/null +++ b/mseide-msegui/tools/form2pas.prj @@ -0,0 +1,953 @@ +[componentpalette] +order0=0 +order1=0 +order2=0 +order3=0 +order4=0 +order5=0 +order6=0 +order7=0 +order8=0 +order9=0 +order10=0 +order11=0 +order12=0 +order13=0 +order14=0 +order15=0 +order16=0 +order17=0 +order18=0 +[projectoptions] +projectdir=/home/mse/packs/standard/git/mseide-msegui/tools +projectfilename=/home/mse/packs/standard/git/mseide-msegui/tools/form2pas.prj +mainfile=form2pas.pas +targetfile=form2pas${EXEEXT} +messageoutputfile= +makecommand=${COMPILER} +makedir= +unitdirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}kernel/ + ${MSELIBDIR}*/ +unitpref=-Fu +incpref=-Fi +libpref=-Fl +objpref=-Fo +targpref=-o +befcommand=0 +aftcommand=0 +makeoptions=4 + -Xg -l -Mobjfpc -Sh -Fcutf8 + -gl + -B + -OG2p3 -XX -CX -Xs +codetemplatedirs=1 + ${TEMPLATEDIR} +toolmenus=0 +toolfiles=0 +toolparams=0 +fontnames=0 +scriptbeforecopy= +scriptaftercopy= +newprojectfiles=0 +newprojectfilesdest=0 +newfinames=3 + Program + Unit + Textfile +newfifilters=3 + "*.pas" "*.pp" + "*.pas" "*.pp" + +newfiexts=3 + pas + pas + +newfisources=3 + ${TEMPLATEDIR}default/program.pas + ${TEMPLATEDIR}default/unit.pas + +newfonames=8 + Mainform + Simple Form + Docking Form + Datamodule + Subform + Report + Scriptform + Inherited Form +newfonamebases=8 + form + form + form + module + form + report + script + form +newfosources=8 + ${TEMPLATEDIR}default/mainform.pas + ${TEMPLATEDIR}default/simpleform.pas + ${TEMPLATEDIR}default/dockingform.pas + ${TEMPLATEDIR}default/datamodule.pas + ${TEMPLATEDIR}default/subform.pas + ${TEMPLATEDIR}default/report.pas + ${TEMPLATEDIR}default/pascform.pas + ${TEMPLATEDIR}default/inheritedform.pas +newfoforms=8 + ${TEMPLATEDIR}default/mainform.mfm + ${TEMPLATEDIR}default/simpleform.mfm + ${TEMPLATEDIR}default/dockingform.mfm + ${TEMPLATEDIR}default/datamodule.mfm + ${TEMPLATEDIR}default/subform.mfm + ${TEMPLATEDIR}default/report.mfm + ${TEMPLATEDIR}default/pascform.mfm + ${TEMPLATEDIR}default/inheritedform.mfm +forcezorder=0 +stripmessageesc=0 +copymessages=0 +closemessages=1 +checkmethods=1 +colorerror=-1610612712 +colorwarning=-1610612717 +colornote=-1610612716 +usercolors=30 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +usercolorcomment=30 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +formatmacronames=0 +formatmacrovalues=0 +settingsfile= +settingseditor=0 +settingsdebugger=0 +settingsstorage=0 +settingsprojecttree=0 +settingsautoload=0 +settingsautosave=0 +modulenames=0 +moduletypes=0 +modulefiles=0 +befcommandon=0 +makeoptionson=4 + 63 + 31 + 34 + 32 +aftcommandon=0 +unitdirson=3 + 65599 + 196671 + 65599 +macroon=0 +macronames=0 +macrovalues=0 +macrogroup=0 +groupcomments=6 + + + + + + +toolsave=0 +toolhide=0 +toolparse=0 +toolmessages=0 +toolshortcuts=0 +fontalias=0 +fontancestors=0 +fontheights=0 +fontwidths=0 +fontoptions=0 +fontxscales=0 +expandprojectfilemacros=0 +loadprojectfile=0 +newinheritedforms=8 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 +uid=0 +sourcefilemasks=3 + "*.pas" "*.dpr" "*.lpr" "*.pp" "*.inc" + "*.c" "*.cc" "*.h" + "*.mfm" +syntaxdeffiles=3 + ${SYNTAXDEFDIR}pascal.sdef + ${SYNTAXDEFDIR}cpp.sdef + ${SYNTAXDEFDIR}objecttext.sdef +filemasknames=3 + Source + Forms + All Files +filemasks=3 + "*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + *.mfm + * +showgrid=1 +snaptogrid=1 +moveonfirstclick=1 +noformdesignerdocking=0 +gridsizex=8 +gridsizey=8 +autoindent=1 +blockindent=1 +linenumberson=0 +rightmarginon=1 +rightmarginchars=80 +scrollheight=0 +tabstops=4 +spacetabs=0 +showtabs=0 +tabindent=0 +editfontname=mseide_source +editfontheight=0 +editfontwidth=0 +editfontextraspace=0 +editfontcolor=-1879048183 +editbkcolor=-1879048186 +statementcolor=14745599 +editfontantialiased=1 +editmarkbrackets=1 +backupfilecount=2 +encoding=1 +codetemplatedirs=1 + ${TEMPLATEDIR} +debugcommand=${DEBUGGER} +debugoptions= +debugtarget= +runcommand= +xtermcommand=xterm -S${PTSN}/${PTSH} +remoteconnection= +uploadcommand= +gdbprocessor=auto +gdbservercommand= +gdbservercommandattach= +beforeconnect= +afterconnect= +beforeload= +afterload= +beforerun= +sourcebase= +sourcedirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ + ./ +defines=0 +progparameters= +progworkingdirectory= +envvarnames=0 +envvarvalues=0 +defineson=0 +stoponexception=0 +valuehints=1 +activateonbreak=1 +raiseonbreak=1 +showconsole=0 +externalconsole=0 +settty=1 +gdbdownload=0 +downloadalways=0 +startupbkpt=0 +startupbkpton=0 +gdbsimulator=0 +gdbserverstartonce=0 +gdbloadtimeout= +gdbserverwait=0 +nogdbserverexit=0 +gdbservertty=0 +exceptclassnames=1 + EconvertError +exceptignore=1 + 0 +nodebugbeginend=0 +sigsettings=27 + 1,1,T,F + 3,3,T,F + 4,4,T,F + 6,6,T,F + 7,7,T,F + 8,8,T,F + 9,9,T,F + 10,10,T,F + 11,11,T,F + 12,12,T,F + 13,13,T,F + 15,15,T,F + 16,16,T,F + 17,17,F,F + 18,18,T,F + 19,19,T,F + 20,20,T,F + 21,21,T,F + 22,22,T,F + 23,23,T,F + 24,24,T,F + 25,25,T,F + 26,26,T,F + 27,27,T,F + 28,28,T,F + 29,29,T,F + 30,30,T,F +defaultmake=1 +[breakpoints] +on=0 +path=0 +line=0 +address=0 +addbkpt=0 +ignore=0 +condition=0 +panels=2 + panel1 + panel2 +units= + ( + a=0,4132,6,Pascal Units + ) +cmodules= + ( + a=0,4132,6,C Modules + ) +files= + ( + a=0,4132,6,Text Files + ) +[componentstore] +storedir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ +filename= +[components] +[selecteditpage] +colwidth=100 +x=0 +y=0 +cx=0 +cy=0 +[progparams] +progparamhistory=0 +workdirparamhistory=0 +envvarons=0 +[edit] +hintwidth=0 +hintheight=0 +finddtext= +findhistory=0 +findoptions=1 +editpos=1 + 0,0 +bookmarks0=0 +sourcefiles=1 + /home/mse/packs/standard/git/mseide-msegui/tools/form2pas.pas +relpaths=1 + form2pas.pas +ismoduletexts=1 + 0 +modules=0 +moduleoptions=0 +visiblemodules=0 +nomenumodules=0 +[sourcefo.tabwidget] +tabsize=134 +firsttab=0 +index=0 +[layout] +windowlayout=532 + [mainfo.openform] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.projectfiledia] + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + [mainfo.openfile] + filenames=0 + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + filehistory=2 + /home/mse/packs/standard/git/mseide-msegui/tools/form2pas.pas + /home/mse/packs/standard/git/mseide-msegui/tools/bmp2pas.pas + filefilterindex=0 + filefilter="*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + [mainfo.basedock] + splitdir=2 + useroptions=146560 + [mainfo] + splitdir=0 + useroptions=33554555 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=25 + cx=323 + cy=64 + rcx=0 + rcy=0 + wsize=0 + active=1 + visible=1 + [targetconsolefo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=554 + cx=323 + cy=169 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [threadsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=37 + y=270 + cx=349 + cy=276 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo] + splitdir=0 + useroptions=16507 + stackedunder=componentpalettefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=100 + y=100 + cx=453 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo.add] + value=0 + [memoryfo.memon] + value=0 + [memoryfo.bitwidth] + value=0 + [memoryfo.cnt] + value=0 + [disassfo] + splitdir=0 + useroptions=16491 + stackedunder=mainfo.panel2 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=162 + y=502 + cx=564 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [findinfilefo] + splitdir=0 + useroptions=16491 + stackedunder=disassfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=548 + y=115 + cx=369 + cy=198 + rcx=0 + rcy=0 + [projecttreefo] + splitdir=0 + useroptions=16491 + stackedunder=memoryfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=263 + y=431 + cx=286 + cy=201 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [projecttreefo.grid] + propcolwidthref=135 + width0=141 + sortdescend0=0 + width1=129 + sortdescend1=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=16 + [stackfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=276 + rcx=0 + rcy=0 + [watchpointsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=120 + y=368 + cx=483 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [watchpointsfo.grid] + propcolwidthref=352 + sortdescend0=0 + values1=0 + values1_ci=-1 + width1=33 + sortdescend1=0 + values2=0 + width2=158 + sortdescend2=0 + width4=34 + sortdescend4=0 + values5=0 + values5_ci=-1 + width5=38 + sortdescend5=0 + values6=0 + width6=184 + sortdescend6=0 + [breakpointsfo] + splitdir=0 + useroptions=16491 + stackedunder=projecttreefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=107 + y=404 + cx=636 + cy=128 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [breakpointsfo.bkptson] + value=1 + [objectinspectorfo] + splitdir=0 + useroptions=16491 + stackedunder=breakpointsfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=724 + y=157 + cx=296 + cy=566 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [objectinspectorfo.grid] + propcolwidthref=286 + width0=105 + sortdescend0=0 + width1=175 + sortdescend1=0 + [symbolfo] + splitdir=0 + useroptions=16507 + stackedunder=findinfilefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=142 + y=257 + cx=361 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [symbolfo.grid] + propcolwidthref=222 + values0=0 + width0=111 + sortdescend0=0 + width1=135 + sortdescend1=0 + [symbolfo.symbol] + [watchfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=279 + cx=313 + cy=221 + rcx=0 + rcy=0 + [watchfo.grid] + propcolwidthref=118 + values0=0 + values0_ci=-1 + sortdescend0=0 + values1=0 + width1=152 + sortdescend1=0 + values3=0 + values3_ci=-1 + sortdescend3=0 + values4=0 + values4_ci=-1 + width4=13 + sortdescend4=0 + [watchfo.watchon] + [watchfo.expression] + [watchfo.watcheson] + value=1 + [messagefo] + splitdir=0 + useroptions=49259 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=510 + cx=675 + cy=95 + rcx=0 + rcy=0 + [componentstorefo] + splitdir=0 + useroptions=24699 + stackedunder=symbolfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=305 + y=101 + cx=445 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentstorefo.grid] + propcolwidthref=435 + width0=111 + sortdescend0=0 + sortdescend1=0 + width2=112 + sortdescend2=0 + width3=185 + sortdescend3=0 + [componentstorefo.storefiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.groupfiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.compfiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentpalettefo] + splitdir=0 + useroptions=24683 + stackedunder=componentstorefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=25 + cx=685 + cy=103 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentpalettefo.componentpages] + activetab=0 + [debuggerfo] + splitdir=0 + useroptions=24683 + parent=mainfo.basedock + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=28 + rcx=0 + rcy=0 + [sourcefo] + splitdir=0 + useroptions=16489 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=675 + cy=507 + rcx=0 + rcy=0 + [actionsmo.watchesonact] + checked=1 + [actionsmo.bluedotsonact] + checked=1 + [cpui386fo] + irqoff=0 + splitdir=0 + useroptions=16491 + stackedunder=mainfo.panel1 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=25 + cx=273 + cy=207 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel1] + splitdir=2 + useroptions=33586667 + stackedunder=targetconsolefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=118 + cx=685 + cy=605 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel2] + splitdir=2 + useroptions=33586667 + stackedunder=cpui386fo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=25 + cx=323 + cy=500 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 +[targetconsole] +finddtext= +findhistory=0 +findoptions=1 diff --git a/mseide-msegui/tools/i18n/main.mfm b/mseide-msegui/tools/i18n/main.mfm new file mode 100644 index 0000000..9bc587e --- /dev/null +++ b/mseide-msegui/tools/i18n/main.mfm @@ -0,0 +1,614 @@ +object mainfo: tmainfo + visible = False + bounds_x = 107 + bounds_y = 283 + bounds_cx = 624 + bounds_cy = 390 + container.frame.levelo = 1 + container.frame.localprops = [frl_levelo] + container.frame.sbhorz.facebutton.template = concavex + container.frame.sbhorz.facebutton.dummy = 0 + container.frame.sbhorz.faceendbutton.template = concavex + container.frame.sbhorz.faceendbutton.dummy = 0 + container.frame.sbvert.facebutton.template = concavey + container.frame.sbvert.facebutton.dummy = 0 + container.frame.sbvert.faceendbutton.template = concavey + container.frame.sbvert.faceendbutton.dummy = 0 + container.bounds = ( + 0 + 20 + 624 + 370 + ) + optionswindow = [wo_groupleader] + mainmenu = mainmenu1 + options = [fo_main, fo_terminateonclose, fo_savepos, fo_savezorder, fo_savestate] + statfile = projectfo.projectstat + caption = 'MSEi18n' + icon.transparentcolor = -2147483642 + icon.options = [bmo_masked] + oncreate = tmainfooncreate + onloaded = loadedexe + oneventloopstart = tmainfoonloaded + ondestroy = tmainfoondestroy + onclosequery = mainclosequery + moduleclassname = 'tmseform' + object tgroupbox1: tgroupbox + frame.captiondist = -4 + frame.localprops1 = [frl1_captiondist] + frame.dummy = 0 + face.template = concavex + face.dummy = 0 + bounds_x = 1 + bounds_y = 1 + bounds_cx = 622 + bounds_cy = 24 + anchors = [an_top] + end + object grid: twidgetgrid + frame.sbvert.facebutton.template = concavey + frame.sbvert.facebutton.dummy = 0 + frame.sbvert.faceendbutton.template = concavey + frame.sbvert.faceendbutton.dummy = 0 + frame.sbhorz.facebutton.template = concavex + frame.sbhorz.facebutton.dummy = 0 + frame.sbhorz.faceendbutton.template = concavex + frame.sbhorz.faceendbutton.dummy = 0 + taborder = 5 + bounds_x = 1 + bounds_y = 25 + bounds_cx = 622 + bounds_cy = 344 + anchors = [an_left, an_top, an_right, an_bottom] + optionsgrid = [og_colsizing, og_focuscellonenter, og_rowheight, og_colchangeontabkey, og_wrapcol, og_autopopup] + fixcols.count = 1 + fixcols.items = < + item + width = 39 + numstart = 1 + numstep = 1 + end> + fixrows.count = 1 + fixrows.items = < + item + face.template = convexx + face.dummy = 0 + height = 16 + captions.count = 5 + captions.items = < + item + caption = 'Name' + end + item + caption = 'Type' + end + item + caption = 'NT' + end + item + caption = 'Comment' + end + item + caption = 'Value' + end> + end> + datacols.count = 5 + datacols.options = [co_proportional, co_savestate] + datacols.options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcoloractive, co1_rowcolorfocused, co1_rowreadonly, co1_autorowheight] + datacols.items = < + item[tree] + width = 195 + options = [co_readonly, co_proportional, co_savestate] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcoloractive, co1_rowcolorfocused, co1_rowreadonly, co1_autorowheight] + widgetname = 'tree' + dataclass = ttreeitemeditlist + end + item[typedisp] + options = [co_readonly, co_savestate] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcoloractive, co1_rowcolorfocused, co1_rowreadonly, co1_autorowheight] + widgetname = 'typedisp' + dataclass = tgridenumdatalist + end + item[donottranslate] + width = 19 + options = [co_drawfocus, co_savestate] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcoloractive, co1_rowcolorfocused, co1_rowreadonly, co1_autorowheight] + widgetname = 'donottranslate' + dataclass = tgridintegerdatalist + end + item[comment] + width = 124 + options = [co_proportional, co_savestate] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcoloractive, co1_rowcolorfocused, co1_rowreadonly, co1_autorowheight] + widgetname = 'comment' + dataclass = tgridmsestringdatalist + end + item[value] + width = 102 + options = [co_readonly, co_proportional, co_savestate] + options1 = [co1_rowfont, co1_rowcolor, co1_zebracolor, co1_rowcoloractive, co1_rowcolorfocused, co1_rowreadonly, co1_autorowheight] + widgetname = 'value' + dataclass = tgridmsestringdatalist + end> + datarowheight = 16 + statfile = projectfo.projectstat + reffontheight = 14 + object tree: ttreeitemedit + optionswidget1 = [ow1_fontglyphheight] + color = -1879048185 + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 195 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + optionsedit = [oe_readonly, oe_undoonesc, oe_checkmrcancel, oe_exitoncursor, oe_hintclippedtext] + textflags = [tf_ycentered, tf_clipo, tf_noselect, tf_ellipseleft] + onupdaterowvalues = treeonupdaterowvalues + options = [teo_treecolnavig] + reffontheight = 14 + end + object typedisp: tenumtypeedit + optionswidget1 = [ow1_fontglyphheight] + color = -1879048185 + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.button.options = [fbo_invisible, fbo_disabled] + taborder = 2 + visible = False + bounds_x = 196 + bounds_y = 0 + bounds_cx = 50 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + optionsedit = [oe_readonly, oe_undoonesc, oe_checkmrcancel, oe_exitoncursor] + dropdown.options = [deo_selectonly, deo_autodropdown, deo_disabled] + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + oninit = typedisponinit + reffontheight = 14 + end + object donottranslate: tbooleanedit + color = -2147483646 + frame.levelo = 0 + frame.localprops = [frl_levelo] + frame.dummy = 0 + taborder = 3 + bounds_x = 247 + bounds_y = 0 + bounds_cx = 19 + bounds_cy = 16 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + visible = False + onsetvalue = donottranslateonsetvalue + end + object comment: tmemodialogedit + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.button.width = 13 + frame.button.color = -2147483646 + frame.button.imagenr = 17 + taborder = 4 + visible = False + bounds_x = 267 + bounds_y = 0 + bounds_cx = 124 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_hintclippedtext] + font.height = 12 + font.name = 'stf_default' + font.xscale = 1 + font.dummy = 0 + onsetvalue = commentonsetvalue + reffontheight = 14 + end + object value: tmemodialogedit + optionswidget1 = [ow1_fontglyphheight] + color = -1879048185 + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.button.imagenr = 17 + frame.button.options = [fbo_invisible, fbo_disabled] + taborder = 5 + visible = False + bounds_x = 392 + bounds_y = 0 + bounds_cx = 102 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate] + optionsedit = [oe_readonly, oe_undoonesc, oe_checkmrcancel, oe_exitoncursor, oe_hintclippedtext] + reffontheight = 14 + end + end + object flat: tbooleanedit + color = -2147483645 + frame.caption = 'flat' + frame.dummy = 0 + frame.outerframe = ( + 0 + 1 + 19 + 2 + ) + taborder = 1 + bounds_x = 9 + bounds_y = 5 + bounds_cx = 32 + bounds_cy = 16 + statfile = projectfo.projectstat + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + ondataentered = formatchanged + end + object stringonly: tbooleanedit + color = -2147483645 + frame.caption = 'string only' + frame.dummy = 0 + frame.outerframe = ( + 0 + 1 + 59 + 2 + ) + taborder = 2 + bounds_x = 57 + bounds_y = 5 + bounds_cx = 72 + bounds_cy = 16 + statfile = projectfo.projectstat + ondataentered = formatchanged + end + object nont: tbooleanedit + color = -2147483645 + frame.caption = 'no NT' + frame.dummy = 0 + frame.outerframe = ( + 0 + 1 + 36 + 2 + ) + taborder = 3 + bounds_x = 153 + bounds_y = 5 + bounds_cx = 49 + bounds_cy = 16 + statfile = projectfo.projectstat + ondataentered = formatchanged + onsetvalue = nontonsetvalue + end + object ntonly: tbooleanedit + color = -2147483645 + frame.caption = 'NT only' + frame.dummy = 0 + frame.outerframe = ( + 0 + 1 + 44 + 2 + ) + taborder = 4 + bounds_x = 233 + bounds_y = 5 + bounds_cx = 57 + bounds_cy = 16 + statfile = projectfo.projectstat + ondataentered = formatchanged + onsetvalue = ntonlyonsetvalue + end + object coloron: tbooleanedit + color = -2147483645 + frame.caption = 'Show Color' + frame.dummy = 0 + frame.outerframe = ( + 0 + 1 + 67 + 2 + ) + taborder = 6 + bounds_x = 321 + bounds_y = 5 + bounds_cx = 80 + bounds_cy = 16 + statfile = projectfo.projectstat + ondataentered = showcolordataentered + value = True + end + object mainstatfile: tstatfile + filename = 'msei18n.sta' + filedir = '"^/.mseide"' + options = [sfo_createpath, sfo_transaction, sfo_activatorread, sfo_activatorwrite] + onstatupdate = mainupdatestat + left = 16 + top = 96 + end + object mainmenu1: tmainmenu + onupdate = mainmenuupdate + facetemplate = convexx + itemframetemplate = menuitemframe + itemframetemplateactive = menuitemframe + menu.submenu.count = 10 + menu.submenu.items = < + item + caption = '&Open' + name = 'open' + state = [as_localcaption, as_localonexecute] + onexecute = onprojectopen + end + item + caption = '&Save' + name = 'save' + state = [as_localcaption, as_localonexecute] + onexecute = onprojectsave + end + item + caption = 'Save &as' + name = 'saveas' + state = [as_localcaption, as_localonexecute] + onexecute = saveasexecute + end + item + caption = '&New' + name = 'new' + state = [as_localcaption, as_localonexecute] + onexecute = newprojectexe + end + item + caption = '&Edit' + name = 'edit' + state = [as_localcaption, as_localonexecute] + onexecute = onprojectedit + end + item + caption = '&Import' + name = 'import' + state = [as_localcaption, as_localonexecute] + onexecute = importonexecute + end + item + caption = 'Ex&port' + name = 'export' + state = [as_localcaption, as_localonexecute] + onexecute = exportonexecute + end + item + caption = '&Make' + name = 'make' + state = [as_localcaption, as_localonexecute] + onexecute = makeonexecute + end + item + submenu.count = 2 + submenu.items = < + item + caption = '&About' + state = [as_localcaption, as_localonexecute] + onexecute = aboutexe + end + item + caption = '&Configure MSEi18n' + state = [as_localcaption, as_localonexecute] + onexecute = configureonexecute + end> + caption = 'Se&ttings' + name = 'settings' + state = [as_localcaption] + end + item + caption = 'E&xit' + state = [as_localcaption, as_localonexecute] + onexecute = exitexe + end> + left = 256 + top = 160 + end + object projectfiledialog: tfiledialog + statfile = mainstatfile + controller.filterlist.data = ( + ( + 'Translate project' + '*.trp' + ) + ) + controller.defaultext = 'trp' + controller.options = [fdo_checkexist, fdo_chdir] + controller.captionopen = 'Open translate project' + controller.captionsave = 'Save translate project' + left = 120 + top = 156 + end + object threadcomp: tthreadcomp + onexecute = makeexecute + onterminate = maketerminate + left = 209 + top = 115 + end + object convexx: tfacecomp + template.fade_pos.count = 2 + template.fade_pos.items = ( + 0 + 1 + ) + template.fade_color.count = 2 + template.fade_color.items = ( + -1610612732 + -1610612731 + ) + template.fade_direction = gd_up + left = 385 + top = 103 + end + object convexy: tfacecomp + template.fade_pos.count = 2 + template.fade_pos.items = ( + 0 + 1 + ) + template.fade_color.count = 2 + template.fade_color.items = ( + -1610612732 + -1610612731 + ) + template.fade_direction = gd_left + left = 481 + top = 103 + end + object concavex: tfacecomp + template.fade_pos.count = 2 + template.fade_pos.items = ( + 0 + 1 + ) + template.fade_color.count = 2 + template.fade_color.items = ( + -1610612732 + -1610612731 + ) + template.fade_direction = gd_down + left = 385 + top = 135 + end + object concavey: tfacecomp + template.fade_pos.count = 2 + template.fade_pos.items = ( + 0 + 1 + ) + template.fade_color.count = 2 + template.fade_color.items = ( + -1610612732 + -1610612731 + ) + left = 481 + top = 135 + end + object sysenv: tsysenvmanager + left = 24 + top = 160 + end + object c: tstringcontainer + strings.data = ( + 'name' + 'type' + 'notranslate' + 'comment' + 'value' + '' + 'Can not read module' + 'New translate project' + 'Exec error' + 'Making' + 'overwrites itself' + 'ERROR' + 'Finished OK' + 'Configure MSEi18n' + 'Data has changed' + 'Do you wish to save' + 'CONFIRMATION' + 'Close error:' + '' + ) + left = 64 + top = 200 + end + object tskincontroller1: tskincontroller + extenders = 0 + left = 176 + top = 224 + end + object iconbmp: tbitmapcomp + bitmap.origformat = 'png' + bitmap.image = { + 00000000000000001800000018000000AC080000000000000000000000000000 + 0000000000000000000000000000000000000000EBEBEB01EAEAEA01E9E9E901 + E8E8E801E7E7E701E6E6E601E4E4E401E3E3E301DDE0DD01E0D3CC01E3CBC001 + E4C7B901E2C5B701E0C8BD01DECEC901DADADA01D9D9D901D8D8D801D6D6D601 + D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101EBEBEB01EAEAEA01E9E9E901 + E8E8E801E7E7E701E6E6E601E5DBD701E7C6B60179A65A0164A75201CEA56601 + E4A56A01E3A46901E3A67001C3A66F015FA14B01BCB49201DAD0CC01D6D6D601 + D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101EBEBEB01EAEAEA01E9E9E901 + BED5BD01B6D1B401E9CCBE01E8B59201E6A76C017EA95401F7FBF70167A03A01 + D69B1801D99B1801A099230180B46701C1E0BF01A89B4E01E0AD8A01DCBFB101 + D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101EBEBEB01EAEAEA01E9E9E901 + 84BC81019ECC980170A45001BC9C4001DB9C210173A12F01FEFFFE01D6EAD301 + 769E1F01B49D000189BD7401FFFFFF01A2CB9101BB981B01DE9C4701E0A47301 + DDB7A301D4D4D401D3D3D301D2D2D201D1D1D101EBEBEB01EAEAEA01E9E9E901 + B9B88C01B5D5AC01FAFDFA0198C484016DA130017D9A0E01B4D6A801FFFFFF01 + 9ECA8D01669E2001EBF5EA01FFFFFF017BB45D01CE9F0001D59B0501DD9A3701 + DFA26C01BDAE8C0165AB61019ABD9801D1D1D101EBEBEB01EAEAEA01ECCFC101 + EAAE7D0175A84E01FFFFFF02FEFFFE018CC0760152A13401FBFDFB01EFF7EF01 + 50A03201FFFFFF0269A83C016AA537017C9E1E01C49A0001769C380191C08301 + BDDDBA0197BC9601D1D1D101EBEBEB01EBE1DD01EBB89501E4A24D01A19A1101 + A2CA8C01FFFFFF0369AB430180BA6701E2F0E101519F240174B250018BC17901 + 599E220168AF54015E9E26017DB45F01EDF6ED01EFF7EF0168A34F01D2CAC401 + D1D1D101EBEBEB01ECCBBB01E9AA6F01DC9D2201989C0D01609B1E01B7D7AB01 + FFFFFF025FA93D016CC447015EAB350177C02F0120F8DF0151DC88016DA41301 + 68AC4601DFEEDC01FFFFFF01FDFEFD016DA84A01CF9E5E01D9B8A801D1D1D101 + EBEBEB01ECBC9E01E4A24D01D39C000168AA4A01BFDBB401539F2C0193C58001 + 9BCB8B0141CF79010EFFF9014FE6900152E48B010EFFF90129F4CF0169AC4001 + FFFFFF0387BB6F01B09A0701DD9B4601DCAC8E01D1D1D101EDDDD801EBB28701 + DF9D3301D19F00017CA11E016AA83C01579E1F0165A3120162A6160161DF7201 + 15FCED0165D54F015CA901016AD148017ED4440170BB3001A5CF9701FFFFFF01 + A3CE960188A01501CF9F0001D4982E01DEA57A01D5C5C001EDD5CA01C6A66501 + 7D9C2D0174A83F0186BB6C01A8D09B01C2E0C001DAECD90171B65F0188BF0801 + 8DD31C0132980001068000013E9D000131F2BF0113FDF2016ABC400156A22C01 + 60A537017CB1530183B8650180B5640171A14C01ACB48F01EED1C30148973201 + D6EAD501FFFFFF0569B0440127F6CF011DFADE0154B60B011D8E00016AB70001 + 3EEDA60114FDF00166B52B018AC27C01FFFFFF02F9FCF901B5D6AA016DA95601 + B2B18F01EED1C301D8A766017D9A240171AB4A01CEE5C801FFFFFF02A4CF9701 + 70B01D0115FCEB010EFFF9016DE145014FEB7D014EE9860185C615015BB23C01 + 6DAD370155A22D0173AC3F0174AD4701729F2501A8961501DD9F6401D8BBAD01 + EDD5CA01EAAD7701DC9D2201CBA00001869F0F016CA8390157A3350157A63601 + 3C9A250183C5160161C1350167C631010EFFF90256BA4701F7FBF701FFFFFF01 + D4E9D10162A63801A8A30501CFA00001D99A1F01DEA16B01D7BFB401EDDDD801 + EBB28701DF9D3301D19F0001CAA500018CA4100180BA6601F5FAF50153A53701 + 88C27501D2E8D10169B24C016CDA52016DCA390158A83101FCFEFC01FFFFFF02 + FCFEFC018DBF7701859E1C01DB992F01DEA57A01D5C5C001EBEBEB01ECBC9E01 + E4A24D01D49C00019D9E0B018DC07501FFFFFF019AC9880164AC4701FFFFFF02 + C5E1C1016AAB07016DB45D015CAA3E0159A53901EDF6EC01FFFFFF03BAD9AF01 + 8B9C3F01DCAC8E01D1D1D101EBEBEB01ECCBBB01E9AA6F01B49B22017FB56201 + FFFFFF01FAFDFA0159A23301CFE6CB01FFFFFF0284BE6A016DA5020197C98601 + FBFDFB0175B55B01539F2A0179B35A0195C48001B9DAB301D7EBD60197C78F01 + 97AB7701D1D1D101EBEBEB01EBE1DD01DCB48C0172AC5801FAFDFA01D3E9D201 + 76B460015DA23601FFFFFF02C1DEB80153A12B0154A22E0172B15201FFFFFF02 + 6DAC4801C8A60001BB9E0001A69505019799390187A15B01BDC2B001D1D1D101 + EBEBEB01EAEAEA01BABF970166A24A01799D390192980D018F980501ABD19F01 + FFFFFF01A0CB8F016CA11C018CBF75017DB65E016BA42701F6FBF601FFFFFF01 + 85BA6B01C6A00001D49C0001DC993601DFA37201DABDAF01D2D2D201D1D1D101 + EBEBEB01EAEAEA01E9E9E901ECC6B201E8AB7501E19E3B01749D2901E1F0DF01 + 6BA842019FA0090184A01401E0EFDF018DBF7601999F03019EC98D01FFFFFF01 + A9D09C01B2970401DD9A3701DFA26C01DCB6A201D3D3D301D2D2D201D1D1D101 + EBEBEB01EAEAEA01E9E9E901E8E8E801EBC5B101E9AD7C019A9F4201729B2E01 + CD9B0001D19F0001A29B0601A4CE9B016B9F2701CFA000016DA23101FCFEFC01 + C4E1C201A7963601E0A47301DDB7A301D4D4D401D3D3D301D2D2D201D1D1D101 + EBEBEB01EAEAEA01E9E9E901E8E8E801E7E7E701E9CCBE01E8B59201E6A76C01 + E2A04B01DE9C3201D89C20017D982101CA991601DA9B2001B9982C019AC68B01 + B1D4AA01B6A56F01DCBFB101D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101 + EBEBEB01EAEAEA01E9E9E901E8E8E801E7E7E701E6E6E601E5DBD701E7C6B601 + E7B79901E6AD8201E5A87201E4A56A01E3A46901E3A67001E3AA7F0178A55A01 + 66A95B01CBCBBE01D6D6D601D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101 + EBEBEB01EAEAEA01E9E9E901E8E8E801E7E7E701E6E6E601E4E4E401E3E3E301 + E2E2E201E4D4CF01E3CBC001E4C7B901E2C5B701E0C8BD01DECEC901CDD5CD01 + CCD4CC01D8D8D801D6D6D601D5D5D501D4D4D401D3D3D301D2D2D201D1D1D101 + } + left = 296 + top = 224 + end + object menuitemframe: tframecomp + template.levelo = -1 + template.leveli = 1 + left = 256 + top = 192 + end +end diff --git a/mseide-msegui/tools/i18n/main.pas b/mseide-msegui/tools/i18n/main.pas new file mode 100644 index 0000000..97d7a1a --- /dev/null +++ b/mseide-msegui/tools/i18n/main.pas @@ -0,0 +1,1199 @@ +{ MSEtools Copyright (c) 1999-2012 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit main; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseforms,msefiledialog,msestat,msestatfile,msesimplewidgets,msegrids, + msewidgetgrid,msegraphics,msegraphutils,mselistbrowser,msedataedits,typinfo, + msedatanodes,msegraphedits,msestream,mseglob,msemenus,classes,mclasses, + msetypes,msestrings,msethreadcomp,mseguiglob,msegui,mseresourceparser, + msedialog,msememodialog,mseobjecttext,mseifiglob,msesysenv,msemacros, + msestringcontainer,mseclasses,mseskin,msebitmap,msejson; + +const + msei18nversiontext = mseguiversiontext; + drcext = '_DRC.rc'; + rstext = '_rst'; + variantshift = 5; + +type + resfilekindty = (rfk_module,rfk_unit,rfk_resource,rfk_resstrings); + + tmainfo = class(tmseform) + mainstatfile: tstatfile; + clear: tbutton; + flat: tbooleanedit; + stringonly: tbooleanedit; + nont: tbooleanedit; + ntonly: tbooleanedit; + grid: twidgetgrid; + convexx: tfacecomp; + convexy: tfacecomp; + concavex: tfacecomp; + concavey: tfacecomp; + tgroupbox1: tgroupbox; + tree: ttreeitemedit; + threadcomp: tthreadcomp; + typedisp: tenumtypeedit; + donottranslate: tbooleanedit; + comment: tmemodialogedit; + value: tmemodialogedit; + scan: tbutton; + mainmenu1: tmainmenu; + projectfiledialog: tfiledialog; + coloron: tbooleanedit; + sysenv: tsysenvmanager; + c: tstringcontainer; + tskincontroller1: tskincontroller; + iconbmp: tbitmapcomp; + menuitemframe: tframecomp; + procedure onprojectopen(const sender: tobject); + procedure onprojectsave(const sender: tobject); + procedure onprojectedit(const sender: tobject); + // procedure readonexecute(const sender: tobject); + // procedure writeonexecute(const sender: tobject); + procedure exportonexecute(const sender: tobject); + procedure importonexecute(const sender: tobject); + procedure clearonexecute(const sender: tobject); + procedure edoninit(const sender: tenumtypeedit); + procedure typedisponinit(const sender: tenumtypeedit); + procedure treeonupdaterowvalues(const sender: tobject; const aindex: integer; + const aitem: tlistitem); + procedure tmainfooncreate(const sender: tobject); + procedure tmainfoonloaded(const sender: tobject); + procedure tmainfoondestroy(const sender: tobject); + procedure formatchanged(const sender: tobject); + procedure nontonsetvalue(const sender: tobject; var avalue: boolean; + var accept: boolean); + procedure ntonlyonsetvalue(const sender: tobject; var avalue: boolean; + var accept: boolean); + procedure donottranslateonsetvalue(const sender: tobject; var avalue: boolean; + var accept: boolean); + procedure commentonsetvalue(const sender: tobject; var avalue: msestring; + var accept: boolean); + procedure variantonsetvalue(const sender: tobject; var avalue: msestring; + var accept: boolean); + +// procedure scanonexecute(const sender: tobject); + procedure makeonexecute(const sender: tobject); + procedure mainupdatestat(const sender: TObject; const filer: tstatfiler); + procedure configureonexecute(const sender: TObject); + procedure makeexecute(const sender: tthreadcomp); + procedure maketerminate(const sender: tthreadcomp); + procedure mainclosequery(const sender: tcustommseform; + var amodalresult: modalresultty); + procedure saveasexecute(const sender: TObject); + procedure newprojectexe(const sender: TObject); + procedure mainmenuupdate(const sender: tcustommenu); + procedure aboutexe(const sender: TObject); + procedure exitexe(const sender: TObject); + procedure beforelangdrawcell(const sender: tcol; const canvas: tcanvas; + var cellinfo: cellinfoty; var processed: Boolean); + procedure showcolordataentered(const sender: TObject); + procedure loadedexe(const sender: TObject); + private + datastream: ttextdatastream; +// alang: integer; + fdatachanged: boolean; + procedure datachanged; + procedure updatecaption; + procedure updatedata; + procedure refreshnodedata; + procedure writerecord(const sender: ttreenode); + procedure writeexprecord(const sender: ttreenode); + procedure checkitem(const sender: ttreelistitem; var delete: boolean); + function filternode(const anode: ttreenode): boolean; + function readunit(const stream: tmsefilestream): msestring; + function readstringresource(const stream: tmsefilestream; + const fpcformat: boolean): msestring; + function readmodule(const stream: tmsefilestream): msestring; + procedure doread(stream: ttextdatastream; aencoding: charencodingty); + procedure dowrite(stream: ttextdatastream; aencoding: charencodingty); + procedure doimport(stream: ttextdatastream; aencoding: charencodingty); + procedure doexport(stream: ttextdatastream; aencoding: charencodingty); + function getcolumnheaders: msestringarty; + function checksave(cancelonly: boolean = false): boolean; + public + procedure loadproject; + procedure readprojectdata; + procedure writeprojectdata; + end; + +var + mainfo: tmainfo; + rootnode: tpropinfonode; + +implementation +uses + main_mfm,msefileutils,msesystypes,msesys,sysutils,mselist,project, + rtlconsts,mseprocutils,msestockobjects, + msewidgets,mseparser,mseformdatatools,mseresourcetools, + msearrayutils,msesettings,messagesform,mseeditglob,mseformatstr; +type + strinconsts = ( + sc_name, //0 + sc_type, //1 + sc_notranslate, //2 + sc_comment, //3 + sc_value, //4 + sc_noproject, //5 + sc_cannotreadmodule, //6 + sc_newtranslateproject,//7 + sc_execerror, //8 + sc_making, //9 + sc_overwritesitself, //10 + sc_error, //11 + sc_finishedok, //12 + sc_configuremsei18n, //13 + sc_datahaschanged, //14 + sc_doyouwishtosave, //15 + sc_confirmation, //16 + sc_closeerror //17 + ); +const + translateext = 'trans'; + exportext = 'csv'; +type + envvarty = (env_macrodef); +const + sysenvvalues: array[envvarty] of argumentdefty = + ((kind: ak_pararg; name: '-macrodef'; anames: nil; flags: []; initvalue: '') + ); + +type + ttreenode1 = class(ttreenode); + tpropinfonode1 = class(tpropinfonode); + +{ tmainfo } + +const + sn_header = 'header'; + sn_prop = '.prop'; + svn_compclass = 'compclass'; + svn_compname = 'compname'; + svn_name = 'name'; + svn_type = 'type'; + svn_value = 'value'; + +procedure tmainfo.tmainfooncreate(const sender: tobject); +var + wstr1: msestring; +begin + stockobjects.mseicon.assign(iconbmp.bitmap); + iconchanged(nil); +// iconbmp.free; + sysenv.init(sysenvvalues); + wstr1:= filepath(statdirname); + if not finddir(wstr1) then begin + createdir(wstr1); + end; + {$ifdef mswindows} + mainstatfile.filename:= 'msei18nwi.sta'; + {$endif} + {$ifdef linux} + mainstatfile.filename:= 'msei18nli.sta'; + {$endif} + {$ifdef openbsd} + mainstatfile.filename:= 'msei18nobsd.sta'; + {$endif} + {$ifdef bsd} + mainstatfile.filename:= 'msei18nbsd.sta'; + {$endif} + rootnode:= tpropinfonode.Create; + application.createform(tprojectfo, projectfo); + updatecaption; +end; + +procedure tmainfo.tmainfoonloaded(const sender: tobject); +begin + mainstatfile.readstat; + show; +end; + +procedure tmainfo.tmainfoondestroy(const sender: tobject); +begin + freeandnil(rootnode); +end; + +procedure tmainfo.edoninit(const sender: tenumtypeedit); +begin + sender.typeinfopo:= typeinfo(tvaluetype); +end; + +procedure tmainfo.typedisponinit(const sender: tenumtypeedit); +begin + sender.typeinfopo:= typeinfo(tvaluetype); +end; + +procedure tmainfo.treeonupdaterowvalues(const sender: tobject; + const aindex: integer; const aitem: tlistitem); +var + int1: integer; +begin + with tpropinfoitem(aitem) do begin + if node <> nil then begin + with node do begin + typedisp[aindex]:= ord(info.valuetype); + donottranslate[aindex]:= info.donottranslate; + comment[aindex]:= info.comment; + value[aindex]:= valuetext; + for int1:= 0 to grid.datacols.count - variantshift - 1 do begin + with tmemodialogedit(grid.datacols[int1+variantshift].editwidget) do begin + if high(info.variants) >= int1 then begin + gridvalue[aindex]:= info.variants[int1]; + end + else begin + gridvalue[aindex]:= ''; + end; + end; + end; + end; + end; + end; +end; + +function tmainfo.filternode(const anode: ttreenode): boolean; +begin + result:= true; + if result and stringonly.value then begin + result:= tpropinfonode(anode).info.valuetype in + [vastring,valstring,vawstring,vautf8string, + vanull,valist,vacollection]; + end; + if result then begin + if nont.value then begin + result:= not tpropinfonode(anode).info.donottranslate; + end + else begin + if ntonly.value then begin + result:= tpropinfonode(anode).info.donottranslate or + (tpropinfonode(anode).info.valuetype in [vanull,valist,vacollection]); + end; + end; + end; +end; + +procedure tmainfo.checkitem(const sender: ttreelistitem; var delete: boolean); +begin + with tpropinfoitem(sender),node,info do begin + delete:= (sender.count = 0) and (valuetype in [vanull,valist,vacollection]) and + (stringonly.value or ntonly.value and not donottranslate); + if not delete and flat.value then begin + sender.caption:= msestring(node.rootstring); + end; + end; +end; + +function tmainfo.getcolumnheaders: msestringarty; +var + int1: integer; +begin + setlength(result,variantshift + projectfo.grid2.rowcount); + result[0]:= c[ord(sc_name)]; + result[1]:= c[ord(sc_type)]; + result[2]:= c[ord(sc_notranslate)]; + result[3]:= c[ord(sc_comment)]; + result[4]:= c[ord(sc_value)]; + for int1:= 0 to projectfo.grid2.rowcount - 1 do begin + result[int1 + variantshift]:= projectfo.lang[int1]; + end; +end; + +procedure tmainfo.updatecaption; +var + mstr1: msestring; +begin + mstr1:= 'MSEi18n ('; + if fdatachanged then begin + mstr1:= mstr1+'*'; + end; + if projectfo.projectstat.filename = '' then begin + mstr1:= mstr1+c[ord(sc_noproject)]; + end + else begin + mstr1:= mstr1+msefileutils.filename(projectfo.projectstat.filename); + end; + caption:= mstr1 + ')'; +end; + +procedure tmainfo.datachanged; +begin + fdatachanged:= true; + updatecaption; +end; + +procedure tmainfo.updatedata; +var + int1: integer; + item: ttreelistedititem; + ar1: msestringarty; + edit1: tmemodialogedit; +begin + ar1:= getcolumnheaders; +// grid.datacols.count:= variantshift; + grid.datacols.count:= length(ar1); + grid.fixrows[-1].captions.count:= length(ar1); + for int1:= variantshift to high(ar1) do begin + grid.fixrows[-1].captions[int1].caption:= getcolumnheaders[int1]; + with grid.datacols[int1] do begin + if editwidget = nil then begin + edit1:= tmemodialogedit.create(self); + edit1.initgridwidget; + edit1.frame.button.width:= 13; + edit1.onsetvalue:= {$ifdef FPC}@{$endif}variantonsetvalue; + edit1.Tag:= int1 - variantshift; + edit1.optionsedit:= (edit1.optionsedit - [oe_savevalue]) + + [oe_hintclippedtext]; + grid.datacols[int1].editwidget:= edit1; + end; + onbeforedrawcell:= @beforelangdrawcell; + end; + end; + grid.beginupdate; + try + item:= rootnode.converttotreelistitem(flat.value,false, + {$ifdef FPC}@{$endif}filternode); + item.checkitems({$ifdef FPC}@{$endif}checkitem); + tree.itemlist.assign(item); + finally + grid.endupdate; + end; +end; + +procedure tmainfo.refreshnodedata; +begin + tree.itemlist.refreshitemvalues; +end; + +function tmainfo.readunit(const stream: tmsefilestream): msestring; +var + scanner: tscanner; + parser: tconstparser; + ar1: constinfoarty; + node,node1: tpropinfonode; + int1: integer; +begin + scanner:= nil; + parser:= nil; + try + scanner:= tscanner.Create; + scanner.source:= stream.readdatastring; + parser:= tconstparser.Create; + parser.scanner:= scanner; + node:= tpropinfonode.Create; + node.info.name:= parser.getconsts(ar1); + result:= msestring(node.info.name); + rootnode.add(node); + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + if resource then begin + node1:= tpropinfonode.Create; + node1.info.name:= name; + node1.info.msestringvalue:= value; + node1.info.valuetype:= valuetype; + node1.info.coffset:= offset; + node1.info.clen:= len; + node.add(node1); + end; + end; + end; + updatedata; + finally + parser.Free; + scanner.Free; + stream.Free; + end; +end; + +function tmainfo.readstringresource(const stream: tmsefilestream; + const fpcformat: boolean): msestring; +var + scanner: tscanner; + parser: tparser; + ar1: constinfoarty; + node,node1,node2: tpropinfonode; + int1,int2: integer; + str1: string; +// po1: pchar; +begin + scanner:= nil; + parser:= nil; + try + if fpcformat and (fileext(stream.filename) = 'rsj') then begin + ar1:= rsjgetconsts(stream); + end + else begin + if fpcformat then begin + scanner:= tpascalscanner.Create; + scanner.source:= stream.readdatastring; + parser:= tfpcresstringparser.create(nil); + end + else begin + scanner:= tcscanner.Create; + scanner.source:= stream.readdatastring; + parser:= tresstringlistparser.Create(nil); + end; + parser.scanner:= scanner; + if fpcformat then begin + tfpcresstringparser(parser).getconsts(ar1); + end + else begin + tresstringlistparser(parser).getconsts(ar1); + end; + end; + node:= tpropinfonode.Create; + node.info.name:= ansistring(filename(stream.filename)); + result:= msestring(node.info.name); + str1:= ''; + for int1:= 0 to high(ar1) do begin + with ar1[int1] do begin + if valuetype = vawstring then begin + if fpcformat then begin + int2:= msestrings.findchar(name,'.'); + end + else begin + int2:= msestrings.findchar(name,'_'); + end; + if int2 > 0 then begin + str1:= copy(name,1,int2-1); + name:= copy(name,int2+1,bigint); + node1:= nil; + for int2:= 0 to node.count - 1 do begin + if node[int2].info.name = str1 then begin + node1:= node[int2]; + break; + end; + end; + if node1 = nil then begin + node1:= tpropinfonode.Create; + node1.info.name:= str1; + node.add(node1); + end; + node2:= tpropinfonode.Create; + node2.info.name:= name; + node2.info.msestringvalue:= value; + node2.info.valuetype:= valuetype; + node2.info.coffset:= offset; + node2.info.clen:= len; + node1.add(node2); + end; + end; + end; + end; + rootnode.add(node); +// updatedata; + finally + parser.Free; + scanner.Free; + stream.Free; + end; +end; + +function tmainfo.readmodule(const stream: tmsefilestream): msestring; +var + memstream: tmemorystream; + node: tpropinfonode; +// int1: integer; +begin + memstream:= tmemorystream.Create; + result:= ''; + try + objecttexttobinarymse(stream,memstream); + memstream.Position:= 0; + node:= tpropinfonode.Create; + readprops(memstream,node); + result:= msestring(node.info.name); + rootnode.add(node); + except + application.handleexception(self,c[ord(sc_cannotreadmodule)]+' '+stream.filename+':'); + end; + memstream.Free; + stream.Free; +end; + +procedure tmainfo.writerecord(const sender: ttreenode); +var + rec: varrecarty; + str1,str2: string; + mstr3: msestring; + int1: integer; +begin + rec:= nil; //compilerwarning + if ttreenode1(sender).fparent <> nil then begin + with tpropinfonode(sender),info do begin + str1:= rootstring(','); + str2:= ansistring(typedisp.enumname(ord(valuetype))); + mstr3:= valuetext; + rec:= mergevarrec([str1,str2,donottranslate,comment,mstr3],[]); + for int1:= 0 to high(variants) do begin + rec:= mergevarrec(rec,[variants[int1]]); + end; + end; + datastream.writerecord(rec); + end; +end; + +procedure tmainfo.donottranslateonsetvalue(const sender: tobject; + var avalue, accept: boolean); +begin + tpropinfoitem(tree.item).node.info.donottranslate:= avalue; + datachanged; + grid.invalidaterow(grid.row); +end; + +procedure tmainfo.commentonsetvalue(const sender: tobject; + var avalue: msestring; var accept: boolean); +begin + tpropinfoitem(tree.item).node.info.comment:= avalue; + datachanged; +end; + +procedure tmainfo.variantonsetvalue(const sender: tobject; + var avalue: msestring; var accept: boolean); +begin + with tpropinfoitem(tree.item).node.info,twidget(sender) do begin + if high(variants) < tag then begin + setlength(variants,tag+1); + end; + variants[tag]:= avalue; + end; + datachanged; +end; + +procedure tmainfo.formatchanged(const sender: tobject); +begin + updatedata; +end; + +procedure tmainfo.doread(stream: ttextdatastream; aencoding: charencodingty); +var + aname: string; + notranslate: boolean; + acomment: msestring; + node: tpropinfonode; + str1: string; + ar1: stringarty; + avariants: msestringarty; + pointers: pointerarty; + int1: integer; +begin + try + stream.encoding:= aencoding; + stream.readln(str1); //header + splitstringquoted(str1,ar1,'"',','); + int1:= length(ar1); + if int1 < variantshift then begin + int1:= variantshift; + end; + setlength(pointers,int1); + str1:= 's bSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS'; + setlength(str1,length(pointers)); + pointers[0]:= @aname; + pointers[2]:= @notranslate; + pointers[3]:= @acomment; + while not stream.eof do begin + aname:= ''; + notranslate:= false; + setlength(avariants,length(pointers) - variantshift); + for int1:= 0 to high(avariants) do begin + avariants[int1]:= ''; + pointers[int1 + variantshift]:= @avariants[int1]; + end; + if stream.readrecord(pointers,str1) then begin + node:= rootnode.findsubnode(','+aname); + if node <> nil then begin + with node.info do begin + donottranslate:= notranslate; + comment:= acomment; + variants:= avariants; + end; + end + else begin + //todo: errorlist + end; + end + else begin + //todo: errormesage + end; + end; + finally + stream.Free; + end; +// refreshnodedata; +// updatedata; +end; + +procedure tmainfo.doimport(stream: ttextdatastream; aencoding: charencodingty); +begin + doread(stream,aencoding); + fdatachanged:= true; + updatecaption; +end; + +procedure tmainfo.importonexecute(const sender: tobject); +var + stream: ttextdatastream; + str1: filenamety; +begin + if checksave and + projectfo.impexpfiledialog.controller.execute(str1,fdk_open) then begin + stream:= ttextdatastream.create(str1,fm_read); + doimport(stream,charencodingty(projectfo.impexpencoding.value)); + updatedata; + end; +end; + +procedure tmainfo.writeexprecord(const sender: ttreenode); +var + bo1,bo2: boolean; + int1: integer; +begin + with tpropinfonode1(sender) do begin + bo2:= not nont.value or not info.donottranslate; + if fparent <> nil then begin + bo1:= not stringonly.value or (info.valuetype in + [vastring,valstring,vawstring,vautf8string]); + if bo1 and bo2 then begin + writerecord(sender); + end; + end; + if bo2 then begin + for int1:= 0 to fcount -1 do begin + writeexprecord(fitems[int1]); + end; + end; + end; +end; + +procedure tmainfo.doexport(stream: ttextdatastream; aencoding: charencodingty); +begin + stream.encoding:= aencoding; + datastream:= stream; + try + datastream.writerecord(getcolumnheaders); + writeexprecord(rootnode); + finally + datastream.Free; + end; +end; + +procedure tmainfo.exportonexecute(const sender: tobject); +var + stream: ttextdatastream; + str1: filenamety; +begin + if projectfo.impexpfiledialog.controller.execute(str1,fdk_save) then begin + stream:= ttextdatastream.create(str1,fm_create); + doexport(stream,charencodingty(projectfo.impexpencoding.value)); + end; +end; + +procedure tmainfo.clearonexecute(const sender: tobject); +begin + rootnode.clear; + updatedata; +end; + +procedure tmainfo.loadproject; +var + int1: integer; + file1: tmsefilestream; + mstr1: msestring; +begin + rootnode.clear; + try + for int1:= 0 to projectfo.grid.rowcount - 1 do begin + file1:= tmsefilestream.create(projectfo.filename[int1]); + case resfilekindty(projectfo.filekind[int1]) of + rfk_module: begin + mstr1:= readmodule(file1); + end; + rfk_unit: begin + mstr1:= readunit(file1); + end; + rfk_resstrings: begin + mstr1:= readstringresource(file1,true); + end; + rfk_resource: begin + mstr1:= readstringresource(file1,false); + end; + end; + projectfo.rootname[int1]:= mstr1; + end; + rootnode.initlang(projectfo.grid2.rowcount); + readprojectdata; + updatedata; + finally + updatecaption; + end; +end; + +procedure tmainfo.readprojectdata; +begin + if projectfo.datafilename.value <> '' then begin + try + doread(ttextdatastream.Create(projectfo.datafilename.value),ce_utf8); + except + application.handleexception(self); + end; + end; +end; + +procedure tmainfo.dowrite(stream: ttextdatastream; aencoding: charencodingty); +begin + stream.encoding:= aencoding; + datastream:= stream; + try + datastream.writerecord(getcolumnheaders); + rootnode.iterate({$ifdef FPC}@{$endif}writerecord); + finally + datastream.Free; + end; +end; + +procedure tmainfo.writeprojectdata; +var + stream: ttextdatastream; +begin + stream:= ttextdatastream.Create(projectfo.datafilename.value,fm_create); + dowrite(stream,ce_utf8); + fdatachanged:= false; + updatecaption; +end; + +procedure tmainfo.onprojectopen(const sender: tobject); +begin + if projectfiledialog.execute = mr_ok then begin + projectfo.projectstat.filename:= projectfiledialog.controller.filename; + projectfo.projectstat.readstat; + end; +end; + +procedure tmainfo.onprojectsave(const sender: tobject); +begin + writeprojectdata; +end; + +procedure tmainfo.newprojectexe(const sender: TObject); +begin + if checksave and (projectfiledialog.controller.execute(fdk_save, + c[ord(sc_newtranslateproject)]) = mr_ok) then begin + projectfo.free; + application.createform(tprojectfo, projectfo); + clearonexecute(nil); + with projectfo.projectstat do begin + filename:= projectfiledialog.controller.filename; + if not fileexists(filename) then begin + projectfo.datafilename.value:= replacefileext(filename,'trd'); + projectfo.impexpfiledialog.controller.clear; + projectfo.impexpfiledialog.controller.filename:= replacefileext(filename,'csv'); + writeprojectdata; + end + else begin + writestat; + end; + end; + updatecaption; + end; +end; + +procedure tmainfo.saveasexecute(const sender: TObject); +begin + if projectfiledialog.controller.execute(fdk_save) = mr_ok then begin + projectfo.projectstat.filename:= projectfiledialog.controller.filename; + projectfo.projectstat.writestat; + writeprojectdata; + end; +end; + +procedure tmainfo.onprojectedit(const sender: tobject); +begin + projectfo.show(true); + projectfo.projectstat.writestat; + projectfo.projectstat.readstat; +end; + +procedure tmainfo.makeexecute(const sender: tthreadcomp); + + procedure addmessage(const amessage: msestring); + begin + application.lock; + messagesfo.messages.addchars(amessage); + application.unlock; + end; + +var + macroar: macroinfoarty; + error: boolean; + + function doproc(const commandstr: msestring): boolean; + var + mstr1: msestring; + int3: integer; + begin + result:= false; + mstr1:= expandmacros(commandstr,macroar); + int3:= messagesfo.messages.execprog(mstr1); + if int3 = invalidprochandle then begin + error:= true; + end + else begin + int3:= messagesfo.messages.waitforprocess; + if int3 <> 0 then begin + addmessage(c[ord(sc_execerror)]+' '+inttostrmse(int3)+'.'); + error:= true; + end + else begin + result:= true; + end; + end; + end; + +var + int1,int2,int3: integer; + stream,stream1: tmsefilestream; + stream2: ttextstream; + node: tpropinfonode; + afilename: filenamety; + modulenames,resourcenames: stringarty; + str1: string; + commandstring: msestring; + mstr1: msestring; +// actdir: filenamety; + dirbefore: filenamety; + basename: filenamety; + +begin +// basename:= filenamebase(projectfo.projectstat.filename); + basename:= projectfo.destname.value; + if basename = '' then begin + basename:= filenamebase(projectfo.datafilename.value); + end; + if basename = '' then begin + basename:= filenamebase(projectfo.projectstat.filename); + end; + commandstring:= expandmacros(projectfo.makecommand.value, + sysenv.getcommandlinemacros(ord(env_macrodef),-1,-1, + getsyssettingsmacros)); + setlength(macroar,2); + macroar[0].name:= 'LIBFILE'; + macroar[1].name:= 'LIBFILEBASE'; + dirbefore:= getcurrentdirmse; + error:= false; + for int1:= 0 to projectfo.grid2.rowcount - 1 do begin + if error then break; + rootnode.transferlang(int1); + try + addmessage(c[ord(sc_making)]+' "'+projectfo.dir[int1]+'".'+lineend); + modulenames:= nil; + resourcenames:= nil; + for int2:= 0 to projectfo.grid.rowcount - 1 do begin + if error then break; + node:= nil; + afilename:= filepath(projectfo.dir[int1],msefileutils.filename(projectfo.filename[int2])); + if issamefilename(afilename,filepath(projectfo.filename[int2])) then begin + addmessage(afilename+' '+c[ord(sc_overwritesitself)]+'.'); + error:= true; + break; + end; + for int3:= 0 to rootnode.count - 1 do begin + if rootnode[int3].info.name = + ansistring(projectfo.rootname[int2]) then begin + node:= rootnode[int3]; + break; + end; + end; + if node <> nil then begin + case resfilekindty(projectfo.filekind[int2]) of + rfk_resource: begin + stream:= tmsefilestream.Create(projectfo.filename[int2],fm_read); + try + stream1:= tmsefilestream.Create(removefileext(afilename)+drcext,fm_create); + try + writeresources(stream,stream1,node); + finally + stream1.Free; + end; + finally + stream.Free; + end; + end; + rfk_resstrings: begin + stream2:= ttextstream.Create(afilename,fm_create); + try + writefpcresourcestrings(stream2,node); + finally + stream2.Free; + end; + str1:= ansistring(filenamebase(afilename))+rstext; + resourcetexttoresourcesource(afilename,str1,true); + additem(resourcenames,str1); + end; + rfk_unit: begin + stream:= tmsefilestream.Create(projectfo.filename[int2],fm_read); + try + stream1:= tmsefilestream.Create(afilename,fm_create); + try + writeconsts(stream,stream1,node); + finally + stream1.Free; + end; + finally + stream.Free; + end; + end; + rfk_module: begin + stream:= tmsefilestream.Create; //memory + try + writeprops(stream,node); + stream.Position:= 0; + stream1:= tmsefilestream.Create(afilename,fm_create); + try + objectbinarytotextmse(stream,stream1); + finally + stream1.Free; + end; + finally + stream.Free; + end; + formtexttoobjsource(afilename,'','',of_default,true); + additem(modulenames,ansistring(filenamebase(afilename))); + end; + end; + end; + end; + if (modulenames <> nil) or (resourcenames <> nil) then begin + with projectfo do begin + macroar[0].value:= basename+'_'+lang[int1]+'.pas'; + macroar[1].value:= filenamebase(macroar[0].value); + createlanglib(dir[int1]+macroar[0].value,modulenames,resourcenames); + if makeon.value then begin + try + setcurrentdirmse(dir[int1]); + if beforemake.value <> '' then begin + if not doproc(beforemake.value) then begin + break; + end; + end; + if doproc(commandstring) then begin + if aftermake.value <> '' then begin + doproc(aftermake.value); + end + else begin + mstr1:= macroar[1].value; + {$ifdef mswindows} + mstr1:= mstr1+'.dll'; + {$else} + mstr1:= 'lib'+mstr1+'.so'; + {$endif} + copyfile(mstr1,'../'+mstr1,true); + end; + end; + finally + setcurrentdirmse(dirbefore); + end; + end; + end; + end; + except + on e: exception do begin + addmessage(msestring(e.message+lineend)); + error:= true; + end; + else begin + error:= true; + end; + end; + end; + if error then begin + addmessage('**** '+c[ord(sc_error)]+' ****'+lineend); + end + else begin + addmessage(c[ord(sc_finishedok)]+lineend); + end; + application.lock; + messagesfo.running:= false; + application.unlock; +end; + +procedure tmainfo.makeonexecute(const sender: tobject); +begin + if checksave(true) then begin + messagesfo.messages.clear; + messagesfo.running:= true; + messagesfo.show; //winid must exist + threadcomp.run; + messagesfo.show(true); + loadproject; + end; +end; + +procedure tmainfo.maketerminate(const sender: tthreadcomp); +begin + messagesfo.running:= false; +end; + +procedure tmainfo.nontonsetvalue(const sender: tobject; var avalue, + accept: boolean); +begin + if avalue then begin + ntonly.value:= false; + end; +end; + +procedure tmainfo.ntonlyonsetvalue(const sender: tobject; var avalue, + accept: boolean); +begin + if avalue then begin + nont.value:= false; + end; +end; + +procedure tmainfo.mainupdatestat(const sender: TObject; const filer: tstatfiler); +var + mstr1: msestring; +begin + updatesettings(filer); + mstr1:= projectfo.projectstat.filename; + filer.updatevalue('projectfile',mstr1); + projectfo.projectstat.filename:= mstr1; + if mstr1 <> '' then begin + try + setcurrentdirmse(filedir(mstr1)); + except + application.handleexception(nil); + end; + end; + if filer.iswriter then begin + projectfo.projectstat.writestat; + end + else begin + projectfo.projectstat.readstat; + end; +end; + +procedure tmainfo.configureonexecute(const sender: TObject); +begin + editsettings(c[ord(sc_configuremsei18n)]); +end; + +function tmainfo.checksave(cancelonly: boolean = false): boolean; +var + mstr1: msestring; +begin + result:= true; + if fdatachanged then begin + mstr1:= c[ord(sc_datahaschanged)]+'.'+lineend+c[ord(sc_doyouwishtosave)]+'?'; + if cancelonly then begin + if askok(mstr1,c[ord(sc_confirmation)]) then begin + writeprojectdata; + end + else begin + result:= false; + end; + end + else begin + case askyesnocancel(mstr1,c[ord(sc_confirmation)]) of + mr_no: begin end; + mr_yes: begin + writeprojectdata; + end; + else begin + result:= false; + end; + end; + end; + end; +end; + +procedure tmainfo.mainclosequery(const sender: tcustommseform; + var amodalresult: modalresultty); +begin + if not checksave then begin + amodalresult:= mr_none; + end + else begin + try + mainstatfile.writestat; + except + on e: exception do begin + if showmessage(c[ord(sc_closeerror)]+lineend+msestring(e.message), + c[ord(sc_error)],[mr_ignore,mr_cancel]) <> mr_ignore then begin + amodalresult:= mr_none; + end; + end; + end; + end; +end; + +procedure tmainfo.mainmenuupdate(const sender: tcustommenu); +var + bo1: boolean; +begin + bo1:= projectfo.projectstat.filename <> ''; + with mainmenu.menu do begin + itembyname('save').enabled:= bo1; + itembyname('saveas').enabled:= bo1; + itembyname('edit').enabled:= bo1; + itembyname('import').enabled:= bo1; + itembyname('export').enabled:= bo1; + itembyname('make').enabled:= bo1; + end; +end; + +procedure tmainfo.aboutexe(const sender: TObject); +begin + showmessage('MSEgui version: '+mseguiversiontext+lineend+ + 'MSEi18n version: ' + msei18nversiontext,'About MSEi18n'); +end; + +procedure tmainfo.exitexe(const sender: TObject); +begin + close; +end; + +procedure tmainfo.beforelangdrawcell(const sender: tcol; const canvas: tcanvas; + var cellinfo: cellinfoty; var processed: Boolean); +var + int1: integer; +begin + if coloron.value then begin + with cellinfo.cell do begin + int1:= typedisp[row]; + if ((int1 = ord(vastring)) or (int1 = ord(vawstring))) and + not donottranslate[row] and + (tstringedit(grid.datacols[col].editwidget)[row] = + value[row]) and (value[row] <> '') then begin + cellinfo.color:= cl_ltred; + end; + end; + end; +end; + +procedure tmainfo.showcolordataentered(const sender: TObject); +begin + grid.invalidate; +end; + +procedure tmainfo.loadedexe(const sender: TObject); +begin + iconbmp.free; +end; + +end. diff --git a/mseide-msegui/tools/i18n/main_mfm.pas b/mseide-msegui/tools/i18n/main_mfm.pas new file mode 100644 index 0000000..6be9ee6 --- /dev/null +++ b/mseide-msegui/tools/i18n/main_mfm.pas @@ -0,0 +1,654 @@ +unit main_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,main; + +const + objdata: record size: integer; data: array[0..12734] of byte end = + (size: 12735; data: ( + 84,80,70,48,7,116,109,97,105,110,102,111,6,109,97,105,110,102,111,7, + 118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,107,8, + 98,111,117,110,100,115,95,121,3,27,1,9,98,111,117,110,100,115,95,99, + 120,3,112,2,9,98,111,117,110,100,115,95,99,121,3,134,1,22,99,111, + 110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,101,118,101,108,111, + 2,1,26,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108, + 111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108, + 111,0,42,99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,115, + 98,104,111,114,122,46,102,97,99,101,98,117,116,116,111,110,46,116,101,109, + 112,108,97,116,101,7,8,99,111,110,99,97,118,101,120,39,99,111,110,116, + 97,105,110,101,114,46,102,114,97,109,101,46,115,98,104,111,114,122,46,102, + 97,99,101,98,117,116,116,111,110,46,100,117,109,109,121,2,0,45,99,111, + 110,116,97,105,110,101,114,46,102,114,97,109,101,46,115,98,104,111,114,122, + 46,102,97,99,101,101,110,100,98,117,116,116,111,110,46,116,101,109,112,108, + 97,116,101,7,8,99,111,110,99,97,118,101,120,42,99,111,110,116,97,105, + 110,101,114,46,102,114,97,109,101,46,115,98,104,111,114,122,46,102,97,99, + 101,101,110,100,98,117,116,116,111,110,46,100,117,109,109,121,2,0,42,99, + 111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,115,98,118,101,114, + 116,46,102,97,99,101,98,117,116,116,111,110,46,116,101,109,112,108,97,116, + 101,7,8,99,111,110,99,97,118,101,121,39,99,111,110,116,97,105,110,101, + 114,46,102,114,97,109,101,46,115,98,118,101,114,116,46,102,97,99,101,98, + 117,116,116,111,110,46,100,117,109,109,121,2,0,45,99,111,110,116,97,105, + 110,101,114,46,102,114,97,109,101,46,115,98,118,101,114,116,46,102,97,99, + 101,101,110,100,98,117,116,116,111,110,46,116,101,109,112,108,97,116,101,7, + 8,99,111,110,99,97,118,101,121,42,99,111,110,116,97,105,110,101,114,46, + 102,114,97,109,101,46,115,98,118,101,114,116,46,102,97,99,101,101,110,100, + 98,117,116,116,111,110,46,100,117,109,109,121,2,0,16,99,111,110,116,97, + 105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,20,3,112,2,3, + 114,1,0,13,111,112,116,105,111,110,115,119,105,110,100,111,119,11,14,119, + 111,95,103,114,111,117,112,108,101,97,100,101,114,0,8,109,97,105,110,109, + 101,110,117,7,9,109,97,105,110,109,101,110,117,49,7,111,112,116,105,111, + 110,115,11,7,102,111,95,109,97,105,110,19,102,111,95,116,101,114,109,105, + 110,97,116,101,111,110,99,108,111,115,101,10,102,111,95,115,97,118,101,112, + 111,115,13,102,111,95,115,97,118,101,122,111,114,100,101,114,12,102,111,95, + 115,97,118,101,115,116,97,116,101,0,8,115,116,97,116,102,105,108,101,7, + 21,112,114,111,106,101,99,116,102,111,46,112,114,111,106,101,99,116,115,116, + 97,116,7,99,97,112,116,105,111,110,6,7,77,83,69,105,49,56,110,21, + 105,99,111,110,46,116,114,97,110,115,112,97,114,101,110,116,99,111,108,111, + 114,4,6,0,0,128,12,105,99,111,110,46,111,112,116,105,111,110,115,11, + 10,98,109,111,95,109,97,115,107,101,100,0,8,111,110,99,114,101,97,116, + 101,7,15,116,109,97,105,110,102,111,111,110,99,114,101,97,116,101,8,111, + 110,108,111,97,100,101,100,7,9,108,111,97,100,101,100,101,120,101,16,111, + 110,101,118,101,110,116,108,111,111,112,115,116,97,114,116,7,15,116,109,97, + 105,110,102,111,111,110,108,111,97,100,101,100,9,111,110,100,101,115,116,114, + 111,121,7,16,116,109,97,105,110,102,111,111,110,100,101,115,116,114,111,121, + 12,111,110,99,108,111,115,101,113,117,101,114,121,7,14,109,97,105,110,99, + 108,111,115,101,113,117,101,114,121,15,109,111,100,117,108,101,99,108,97,115, + 115,110,97,109,101,6,8,116,109,115,101,102,111,114,109,0,9,116,103,114, + 111,117,112,98,111,120,10,116,103,114,111,117,112,98,111,120,49,17,102,114, + 97,109,101,46,99,97,112,116,105,111,110,100,105,115,116,2,252,17,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,16,102,114,108, + 49,95,99,97,112,116,105,111,110,100,105,115,116,0,11,102,114,97,109,101, + 46,100,117,109,109,121,2,0,13,102,97,99,101,46,116,101,109,112,108,97, + 116,101,7,8,99,111,110,99,97,118,101,120,10,102,97,99,101,46,100,117, + 109,109,121,2,0,8,98,111,117,110,100,115,95,120,2,1,8,98,111,117, + 110,100,115,95,121,2,1,9,98,111,117,110,100,115,95,99,120,3,110,2, + 9,98,111,117,110,100,115,95,99,121,2,24,7,97,110,99,104,111,114,115, + 11,6,97,110,95,116,111,112,0,0,0,11,116,119,105,100,103,101,116,103, + 114,105,100,4,103,114,105,100,32,102,114,97,109,101,46,115,98,118,101,114, + 116,46,102,97,99,101,98,117,116,116,111,110,46,116,101,109,112,108,97,116, + 101,7,8,99,111,110,99,97,118,101,121,29,102,114,97,109,101,46,115,98, + 118,101,114,116,46,102,97,99,101,98,117,116,116,111,110,46,100,117,109,109, + 121,2,0,35,102,114,97,109,101,46,115,98,118,101,114,116,46,102,97,99, + 101,101,110,100,98,117,116,116,111,110,46,116,101,109,112,108,97,116,101,7, + 8,99,111,110,99,97,118,101,121,32,102,114,97,109,101,46,115,98,118,101, + 114,116,46,102,97,99,101,101,110,100,98,117,116,116,111,110,46,100,117,109, + 109,121,2,0,32,102,114,97,109,101,46,115,98,104,111,114,122,46,102,97, + 99,101,98,117,116,116,111,110,46,116,101,109,112,108,97,116,101,7,8,99, + 111,110,99,97,118,101,120,29,102,114,97,109,101,46,115,98,104,111,114,122, + 46,102,97,99,101,98,117,116,116,111,110,46,100,117,109,109,121,2,0,35, + 102,114,97,109,101,46,115,98,104,111,114,122,46,102,97,99,101,101,110,100, + 98,117,116,116,111,110,46,116,101,109,112,108,97,116,101,7,8,99,111,110, + 99,97,118,101,120,32,102,114,97,109,101,46,115,98,104,111,114,122,46,102, + 97,99,101,101,110,100,98,117,116,116,111,110,46,100,117,109,109,121,2,0, + 8,116,97,98,111,114,100,101,114,2,5,8,98,111,117,110,100,115,95,120, + 2,1,8,98,111,117,110,100,115,95,121,2,25,9,98,111,117,110,100,115, + 95,99,120,3,110,2,9,98,111,117,110,100,115,95,99,121,3,88,1,7, + 97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110,95, + 116,111,112,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116,116, + 111,109,0,11,111,112,116,105,111,110,115,103,114,105,100,11,12,111,103,95, + 99,111,108,115,105,122,105,110,103,19,111,103,95,102,111,99,117,115,99,101, + 108,108,111,110,101,110,116,101,114,12,111,103,95,114,111,119,104,101,105,103, + 104,116,20,111,103,95,99,111,108,99,104,97,110,103,101,111,110,116,97,98, + 107,101,121,10,111,103,95,119,114,97,112,99,111,108,12,111,103,95,97,117, + 116,111,112,111,112,117,112,0,13,102,105,120,99,111,108,115,46,99,111,117, + 110,116,2,1,13,102,105,120,99,111,108,115,46,105,116,101,109,115,14,1, + 5,119,105,100,116,104,2,39,8,110,117,109,115,116,97,114,116,2,1,7, + 110,117,109,115,116,101,112,2,1,0,0,13,102,105,120,114,111,119,115,46, + 99,111,117,110,116,2,1,13,102,105,120,114,111,119,115,46,105,116,101,109, + 115,14,1,13,102,97,99,101,46,116,101,109,112,108,97,116,101,7,7,99, + 111,110,118,101,120,120,10,102,97,99,101,46,100,117,109,109,121,2,0,6, + 104,101,105,103,104,116,2,16,14,99,97,112,116,105,111,110,115,46,99,111, + 117,110,116,2,5,14,99,97,112,116,105,111,110,115,46,105,116,101,109,115, + 14,1,7,99,97,112,116,105,111,110,6,4,78,97,109,101,0,1,7,99, + 97,112,116,105,111,110,6,4,84,121,112,101,0,1,7,99,97,112,116,105, + 111,110,6,2,78,84,0,1,7,99,97,112,116,105,111,110,6,7,67,111, + 109,109,101,110,116,0,1,7,99,97,112,116,105,111,110,6,5,86,97,108, + 117,101,0,0,0,0,14,100,97,116,97,99,111,108,115,46,99,111,117,110, + 116,2,5,16,100,97,116,97,99,111,108,115,46,111,112,116,105,111,110,115, + 11,15,99,111,95,112,114,111,112,111,114,116,105,111,110,97,108,12,99,111, + 95,115,97,118,101,115,116,97,116,101,0,17,100,97,116,97,99,111,108,115, + 46,111,112,116,105,111,110,115,49,11,11,99,111,49,95,114,111,119,102,111, + 110,116,12,99,111,49,95,114,111,119,99,111,108,111,114,14,99,111,49,95, + 122,101,98,114,97,99,111,108,111,114,18,99,111,49,95,114,111,119,99,111, + 108,111,114,97,99,116,105,118,101,19,99,111,49,95,114,111,119,99,111,108, + 111,114,102,111,99,117,115,101,100,15,99,111,49,95,114,111,119,114,101,97, + 100,111,110,108,121,17,99,111,49,95,97,117,116,111,114,111,119,104,101,105, + 103,104,116,0,14,100,97,116,97,99,111,108,115,46,105,116,101,109,115,14, + 7,4,116,114,101,101,1,5,119,105,100,116,104,3,195,0,7,111,112,116, + 105,111,110,115,11,11,99,111,95,114,101,97,100,111,110,108,121,15,99,111, + 95,112,114,111,112,111,114,116,105,111,110,97,108,12,99,111,95,115,97,118, + 101,115,116,97,116,101,0,8,111,112,116,105,111,110,115,49,11,11,99,111, + 49,95,114,111,119,102,111,110,116,12,99,111,49,95,114,111,119,99,111,108, + 111,114,14,99,111,49,95,122,101,98,114,97,99,111,108,111,114,18,99,111, + 49,95,114,111,119,99,111,108,111,114,97,99,116,105,118,101,19,99,111,49, + 95,114,111,119,99,111,108,111,114,102,111,99,117,115,101,100,15,99,111,49, + 95,114,111,119,114,101,97,100,111,110,108,121,17,99,111,49,95,97,117,116, + 111,114,111,119,104,101,105,103,104,116,0,10,119,105,100,103,101,116,110,97, + 109,101,6,4,116,114,101,101,9,100,97,116,97,99,108,97,115,115,7,17, + 116,116,114,101,101,105,116,101,109,101,100,105,116,108,105,115,116,0,7,8, + 116,121,112,101,100,105,115,112,1,7,111,112,116,105,111,110,115,11,11,99, + 111,95,114,101,97,100,111,110,108,121,12,99,111,95,115,97,118,101,115,116, + 97,116,101,0,8,111,112,116,105,111,110,115,49,11,11,99,111,49,95,114, + 111,119,102,111,110,116,12,99,111,49,95,114,111,119,99,111,108,111,114,14, + 99,111,49,95,122,101,98,114,97,99,111,108,111,114,18,99,111,49,95,114, + 111,119,99,111,108,111,114,97,99,116,105,118,101,19,99,111,49,95,114,111, + 119,99,111,108,111,114,102,111,99,117,115,101,100,15,99,111,49,95,114,111, + 119,114,101,97,100,111,110,108,121,17,99,111,49,95,97,117,116,111,114,111, + 119,104,101,105,103,104,116,0,10,119,105,100,103,101,116,110,97,109,101,6, + 8,116,121,112,101,100,105,115,112,9,100,97,116,97,99,108,97,115,115,7, + 17,116,103,114,105,100,101,110,117,109,100,97,116,97,108,105,115,116,0,7, + 14,100,111,110,111,116,116,114,97,110,115,108,97,116,101,1,5,119,105,100, + 116,104,2,19,7,111,112,116,105,111,110,115,11,12,99,111,95,100,114,97, + 119,102,111,99,117,115,12,99,111,95,115,97,118,101,115,116,97,116,101,0, + 8,111,112,116,105,111,110,115,49,11,11,99,111,49,95,114,111,119,102,111, + 110,116,12,99,111,49,95,114,111,119,99,111,108,111,114,14,99,111,49,95, + 122,101,98,114,97,99,111,108,111,114,18,99,111,49,95,114,111,119,99,111, + 108,111,114,97,99,116,105,118,101,19,99,111,49,95,114,111,119,99,111,108, + 111,114,102,111,99,117,115,101,100,15,99,111,49,95,114,111,119,114,101,97, + 100,111,110,108,121,17,99,111,49,95,97,117,116,111,114,111,119,104,101,105, + 103,104,116,0,10,119,105,100,103,101,116,110,97,109,101,6,14,100,111,110, + 111,116,116,114,97,110,115,108,97,116,101,9,100,97,116,97,99,108,97,115, + 115,7,20,116,103,114,105,100,105,110,116,101,103,101,114,100,97,116,97,108, + 105,115,116,0,7,7,99,111,109,109,101,110,116,1,5,119,105,100,116,104, + 2,124,7,111,112,116,105,111,110,115,11,15,99,111,95,112,114,111,112,111, + 114,116,105,111,110,97,108,12,99,111,95,115,97,118,101,115,116,97,116,101, + 0,8,111,112,116,105,111,110,115,49,11,11,99,111,49,95,114,111,119,102, + 111,110,116,12,99,111,49,95,114,111,119,99,111,108,111,114,14,99,111,49, + 95,122,101,98,114,97,99,111,108,111,114,18,99,111,49,95,114,111,119,99, + 111,108,111,114,97,99,116,105,118,101,19,99,111,49,95,114,111,119,99,111, + 108,111,114,102,111,99,117,115,101,100,15,99,111,49,95,114,111,119,114,101, + 97,100,111,110,108,121,17,99,111,49,95,97,117,116,111,114,111,119,104,101, + 105,103,104,116,0,10,119,105,100,103,101,116,110,97,109,101,6,7,99,111, + 109,109,101,110,116,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114, + 105,100,109,115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0, + 7,5,118,97,108,117,101,1,5,119,105,100,116,104,2,102,7,111,112,116, + 105,111,110,115,11,11,99,111,95,114,101,97,100,111,110,108,121,15,99,111, + 95,112,114,111,112,111,114,116,105,111,110,97,108,12,99,111,95,115,97,118, + 101,115,116,97,116,101,0,8,111,112,116,105,111,110,115,49,11,11,99,111, + 49,95,114,111,119,102,111,110,116,12,99,111,49,95,114,111,119,99,111,108, + 111,114,14,99,111,49,95,122,101,98,114,97,99,111,108,111,114,18,99,111, + 49,95,114,111,119,99,111,108,111,114,97,99,116,105,118,101,19,99,111,49, + 95,114,111,119,99,111,108,111,114,102,111,99,117,115,101,100,15,99,111,49, + 95,114,111,119,114,101,97,100,111,110,108,121,17,99,111,49,95,97,117,116, + 111,114,111,119,104,101,105,103,104,116,0,10,119,105,100,103,101,116,110,97, + 109,101,6,5,118,97,108,117,101,9,100,97,116,97,99,108,97,115,115,7, + 22,116,103,114,105,100,109,115,101,115,116,114,105,110,103,100,97,116,97,108, + 105,115,116,0,0,13,100,97,116,97,114,111,119,104,101,105,103,104,116,2, + 16,8,115,116,97,116,102,105,108,101,7,21,112,114,111,106,101,99,116,102, + 111,46,112,114,111,106,101,99,116,115,116,97,116,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,14,0,13,116,116,114,101,101,105,116,101,109, + 101,100,105,116,4,116,114,101,101,14,111,112,116,105,111,110,115,119,105,100, + 103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112,104,104, + 101,105,103,104,116,0,5,99,111,108,111,114,4,7,0,0,144,12,102,114, + 97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99, + 111,108,111,114,99,108,105,101,110,116,4,2,0,0,128,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101, + 118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116, + 0,8,116,97,98,111,114,100,101,114,2,1,7,118,105,115,105,98,108,101, + 8,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95, + 121,2,0,9,98,111,117,110,100,115,95,99,120,3,195,0,9,98,111,117, + 110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116, + 49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117, + 14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95, + 115,97,118,101,115,116,97,116,101,0,11,111,112,116,105,111,110,115,101,100, + 105,116,11,11,111,101,95,114,101,97,100,111,110,108,121,12,111,101,95,117, + 110,100,111,111,110,101,115,99,16,111,101,95,99,104,101,99,107,109,114,99, + 97,110,99,101,108,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111, + 114,18,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116, + 0,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101,110, + 116,101,114,101,100,8,116,102,95,99,108,105,112,111,11,116,102,95,110,111, + 115,101,108,101,99,116,14,116,102,95,101,108,108,105,112,115,101,108,101,102, + 116,0,17,111,110,117,112,100,97,116,101,114,111,119,118,97,108,117,101,115, + 7,21,116,114,101,101,111,110,117,112,100,97,116,101,114,111,119,118,97,108, + 117,101,115,7,111,112,116,105,111,110,115,11,16,116,101,111,95,116,114,101, + 101,99,111,108,110,97,118,105,103,0,13,114,101,102,102,111,110,116,104,101, + 105,103,104,116,2,14,0,0,13,116,101,110,117,109,116,121,112,101,101,100, + 105,116,8,116,121,112,101,100,105,115,112,14,111,112,116,105,111,110,115,119, + 105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121,112, + 104,104,101,105,103,104,116,0,5,99,111,108,111,114,4,7,0,0,144,12, + 102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101, + 46,99,111,108,111,114,99,108,105,101,110,116,4,2,0,0,128,16,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95, + 108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101, + 110,116,0,20,102,114,97,109,101,46,98,117,116,116,111,110,46,111,112,116, + 105,111,110,115,11,13,102,98,111,95,105,110,118,105,115,105,98,108,101,12, + 102,98,111,95,100,105,115,97,98,108,101,100,0,8,116,97,98,111,114,100, + 101,114,2,2,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115, + 95,120,3,196,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117, + 110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,16, + 12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97, + 117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121, + 101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116, + 101,0,11,111,112,116,105,111,110,115,101,100,105,116,11,11,111,101,95,114, + 101,97,100,111,110,108,121,12,111,101,95,117,110,100,111,111,110,101,115,99, + 16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,15,111,101, + 95,101,120,105,116,111,110,99,117,114,115,111,114,0,16,100,114,111,112,100, + 111,119,110,46,111,112,116,105,111,110,115,11,14,100,101,111,95,115,101,108, + 101,99,116,111,110,108,121,16,100,101,111,95,97,117,116,111,100,114,111,112, + 100,111,119,110,12,100,101,111,95,100,105,115,97,98,108,101,100,0,19,100, + 114,111,112,100,111,119,110,46,99,111,108,115,46,99,111,117,110,116,2,1, + 19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,105,116,101,109,115, + 14,1,0,0,6,111,110,105,110,105,116,7,14,116,121,112,101,100,105,115, + 112,111,110,105,110,105,116,13,114,101,102,102,111,110,116,104,101,105,103,104, + 116,2,14,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,14,100, + 111,110,111,116,116,114,97,110,115,108,97,116,101,5,99,111,108,111,114,4, + 2,0,0,128,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,0,11,102,114,97,109,101,46,100,117,109,109, + 121,2,0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117,110,100, + 115,95,120,3,247,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,120,2,19,9,98,111,117,110,100,115,95,99,121,2, + 16,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110, + 100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114, + 121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111, + 101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116, + 115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116, + 111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116, + 101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95, + 97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105, + 99,107,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17,111,101, + 49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101,49,95, + 107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118,101,115, + 116,97,116,101,0,7,118,105,115,105,98,108,101,8,10,111,110,115,101,116, + 118,97,108,117,101,7,24,100,111,110,111,116,116,114,97,110,115,108,97,116, + 101,111,110,115,101,116,118,97,108,117,101,0,0,15,116,109,101,109,111,100, + 105,97,108,111,103,101,100,105,116,7,99,111,109,109,101,110,116,12,102,114, + 97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99, + 111,108,111,114,99,108,105,101,110,116,4,2,0,0,128,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101, + 118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116, + 0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,119,105,100,116,104, + 2,13,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111, + 114,4,2,0,0,128,20,102,114,97,109,101,46,98,117,116,116,111,110,46, + 105,109,97,103,101,110,114,2,17,8,116,97,98,111,114,100,101,114,2,4, + 7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,11, + 1,8,98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95, + 99,120,2,124,9,98,111,117,110,100,115,95,99,121,2,16,12,111,112,116, + 105,111,110,115,101,100,105,116,49,11,17,111,101,49,95,97,117,116,111,112, + 111,112,117,112,109,101,110,117,14,111,101,49,95,107,101,121,101,120,101,99, + 117,116,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101,0,11,111, + 112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111, + 110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111, + 101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101, + 97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108, + 101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99, + 117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13, + 111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116, + 111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,18, + 111,101,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116,0,11, + 102,111,110,116,46,104,101,105,103,104,116,2,12,9,102,111,110,116,46,110, + 97,109,101,6,11,115,116,102,95,100,101,102,97,117,108,116,11,102,111,110, + 116,46,120,115,99,97,108,101,2,1,10,102,111,110,116,46,100,117,109,109, + 121,2,0,10,111,110,115,101,116,118,97,108,117,101,7,17,99,111,109,109, + 101,110,116,111,110,115,101,116,118,97,108,117,101,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,14,0,0,15,116,109,101,109,111,100,105,97, + 108,111,103,101,100,105,116,5,118,97,108,117,101,14,111,112,116,105,111,110, + 115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108, + 121,112,104,104,101,105,103,104,116,0,5,99,111,108,111,114,4,7,0,0, + 144,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97, + 109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,2,0,0,128,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,20,102,114,97,109,101,46,98,117,116,116,111,110,46,105, + 109,97,103,101,110,114,2,17,20,102,114,97,109,101,46,98,117,116,116,111, + 110,46,111,112,116,105,111,110,115,11,13,102,98,111,95,105,110,118,105,115, + 105,98,108,101,12,102,98,111,95,100,105,115,97,98,108,101,100,0,8,116, + 97,98,111,114,100,101,114,2,5,7,118,105,115,105,98,108,101,8,8,98, + 111,117,110,100,115,95,120,3,136,1,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,2,102,9,98,111,117,110,100,115, + 95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105,116,49,11,17, + 111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111,101, + 49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49,95,115,97,118, + 101,115,116,97,116,101,0,11,111,112,116,105,111,110,115,101,100,105,116,11, + 11,111,101,95,114,101,97,100,111,110,108,121,12,111,101,95,117,110,100,111, + 111,110,101,115,99,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99, + 101,108,15,111,101,95,101,120,105,116,111,110,99,117,114,115,111,114,18,111, + 101,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116,0,13,114, + 101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,0,12,116,98, + 111,111,108,101,97,110,101,100,105,116,4,102,108,97,116,5,99,111,108,111, + 114,4,3,0,0,128,13,102,114,97,109,101,46,99,97,112,116,105,111,110, + 6,4,102,108,97,116,11,102,114,97,109,101,46,100,117,109,109,121,2,0, + 16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0, + 2,1,2,19,2,2,0,8,116,97,98,111,114,100,101,114,2,1,8,98, + 111,117,110,100,115,95,120,2,9,8,98,111,117,110,100,115,95,121,2,5, + 9,98,111,117,110,100,115,95,99,120,2,32,9,98,111,117,110,100,115,95, + 99,121,2,16,8,115,116,97,116,102,105,108,101,7,21,112,114,111,106,101, + 99,116,102,111,46,112,114,111,106,101,99,116,115,116,97,116,11,111,112,116, + 105,111,110,115,101,100,105,116,11,12,111,101,95,117,110,100,111,111,110,101, + 115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111,101,95, + 99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101,97,116, + 114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99, + 116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114, + 115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101, + 95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115, + 101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0,13,111, + 110,100,97,116,97,101,110,116,101,114,101,100,7,13,102,111,114,109,97,116, + 99,104,97,110,103,101,100,0,0,12,116,98,111,111,108,101,97,110,101,100, + 105,116,10,115,116,114,105,110,103,111,110,108,121,5,99,111,108,111,114,4, + 3,0,0,128,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,11, + 115,116,114,105,110,103,32,111,110,108,121,11,102,114,97,109,101,46,100,117, + 109,109,121,2,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97, + 109,101,1,2,0,2,1,2,59,2,2,0,8,116,97,98,111,114,100,101, + 114,2,2,8,98,111,117,110,100,115,95,120,2,57,8,98,111,117,110,100, + 115,95,121,2,5,9,98,111,117,110,100,115,95,99,120,2,72,9,98,111, + 117,110,100,115,95,99,121,2,16,8,115,116,97,116,102,105,108,101,7,21, + 112,114,111,106,101,99,116,102,111,46,112,114,111,106,101,99,116,115,116,97, + 116,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7,13,102,111,114, + 109,97,116,99,104,97,110,103,101,100,0,0,12,116,98,111,111,108,101,97, + 110,101,100,105,116,4,110,111,110,116,5,99,111,108,111,114,4,3,0,0, + 128,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,5,110,111,32, + 78,84,11,102,114,97,109,101,46,100,117,109,109,121,2,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,1,2,36, + 2,2,0,8,116,97,98,111,114,100,101,114,2,3,8,98,111,117,110,100, + 115,95,120,3,153,0,8,98,111,117,110,100,115,95,121,2,5,9,98,111, + 117,110,100,115,95,99,120,2,49,9,98,111,117,110,100,115,95,99,121,2, + 16,8,115,116,97,116,102,105,108,101,7,21,112,114,111,106,101,99,116,102, + 111,46,112,114,111,106,101,99,116,115,116,97,116,13,111,110,100,97,116,97, + 101,110,116,101,114,101,100,7,13,102,111,114,109,97,116,99,104,97,110,103, + 101,100,10,111,110,115,101,116,118,97,108,117,101,7,14,110,111,110,116,111, + 110,115,101,116,118,97,108,117,101,0,0,12,116,98,111,111,108,101,97,110, + 101,100,105,116,6,110,116,111,110,108,121,5,99,111,108,111,114,4,3,0, + 0,128,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,7,78,84, + 32,111,110,108,121,11,102,114,97,109,101,46,100,117,109,109,121,2,0,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2, + 1,2,44,2,2,0,8,116,97,98,111,114,100,101,114,2,4,8,98,111, + 117,110,100,115,95,120,3,233,0,8,98,111,117,110,100,115,95,121,2,5, + 9,98,111,117,110,100,115,95,99,120,2,57,9,98,111,117,110,100,115,95, + 99,121,2,16,8,115,116,97,116,102,105,108,101,7,21,112,114,111,106,101, + 99,116,102,111,46,112,114,111,106,101,99,116,115,116,97,116,13,111,110,100, + 97,116,97,101,110,116,101,114,101,100,7,13,102,111,114,109,97,116,99,104, + 97,110,103,101,100,10,111,110,115,101,116,118,97,108,117,101,7,16,110,116, + 111,110,108,121,111,110,115,101,116,118,97,108,117,101,0,0,12,116,98,111, + 111,108,101,97,110,101,100,105,116,7,99,111,108,111,114,111,110,5,99,111, + 108,111,114,4,3,0,0,128,13,102,114,97,109,101,46,99,97,112,116,105, + 111,110,6,10,83,104,111,119,32,67,111,108,111,114,11,102,114,97,109,101, + 46,100,117,109,109,121,2,0,16,102,114,97,109,101,46,111,117,116,101,114, + 102,114,97,109,101,1,2,0,2,1,2,67,2,2,0,8,116,97,98,111, + 114,100,101,114,2,6,8,98,111,117,110,100,115,95,120,3,65,1,8,98, + 111,117,110,100,115,95,121,2,5,9,98,111,117,110,100,115,95,99,120,2, + 80,9,98,111,117,110,100,115,95,99,121,2,16,8,115,116,97,116,102,105, + 108,101,7,21,112,114,111,106,101,99,116,102,111,46,112,114,111,106,101,99, + 116,115,116,97,116,13,111,110,100,97,116,97,101,110,116,101,114,101,100,7, + 20,115,104,111,119,99,111,108,111,114,100,97,116,97,101,110,116,101,114,101, + 100,5,118,97,108,117,101,9,0,0,9,116,115,116,97,116,102,105,108,101, + 12,109,97,105,110,115,116,97,116,102,105,108,101,8,102,105,108,101,110,97, + 109,101,6,11,109,115,101,105,49,56,110,46,115,116,97,7,102,105,108,101, + 100,105,114,6,11,34,94,47,46,109,115,101,105,100,101,34,7,111,112,116, + 105,111,110,115,11,14,115,102,111,95,99,114,101,97,116,101,112,97,116,104, + 15,115,102,111,95,116,114,97,110,115,97,99,116,105,111,110,17,115,102,111, + 95,97,99,116,105,118,97,116,111,114,114,101,97,100,18,115,102,111,95,97, + 99,116,105,118,97,116,111,114,119,114,105,116,101,0,12,111,110,115,116,97, + 116,117,112,100,97,116,101,7,14,109,97,105,110,117,112,100,97,116,101,115, + 116,97,116,4,108,101,102,116,2,16,3,116,111,112,2,96,0,0,9,116, + 109,97,105,110,109,101,110,117,9,109,97,105,110,109,101,110,117,49,8,111, + 110,117,112,100,97,116,101,7,14,109,97,105,110,109,101,110,117,117,112,100, + 97,116,101,12,102,97,99,101,116,101,109,112,108,97,116,101,7,7,99,111, + 110,118,101,120,120,17,105,116,101,109,102,114,97,109,101,116,101,109,112,108, + 97,116,101,7,13,109,101,110,117,105,116,101,109,102,114,97,109,101,23,105, + 116,101,109,102,114,97,109,101,116,101,109,112,108,97,116,101,97,99,116,105, + 118,101,7,13,109,101,110,117,105,116,101,109,102,114,97,109,101,18,109,101, + 110,117,46,115,117,98,109,101,110,117,46,99,111,117,110,116,2,10,18,109, + 101,110,117,46,115,117,98,109,101,110,117,46,105,116,101,109,115,14,1,7, + 99,97,112,116,105,111,110,6,5,38,79,112,101,110,4,110,97,109,101,6, + 4,111,112,101,110,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101, + 120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7,13,111, + 110,112,114,111,106,101,99,116,111,112,101,110,0,1,7,99,97,112,116,105, + 111,110,6,5,38,83,97,118,101,4,110,97,109,101,6,4,115,97,118,101, + 5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116, + 105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116, + 101,0,9,111,110,101,120,101,99,117,116,101,7,13,111,110,112,114,111,106, + 101,99,116,115,97,118,101,0,1,7,99,97,112,116,105,111,110,6,8,83, + 97,118,101,32,38,97,115,4,110,97,109,101,6,6,115,97,118,101,97,115, + 5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97,112,116, + 105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99,117,116, + 101,0,9,111,110,101,120,101,99,117,116,101,7,13,115,97,118,101,97,115, + 101,120,101,99,117,116,101,0,1,7,99,97,112,116,105,111,110,6,4,38, + 78,101,119,4,110,97,109,101,6,3,110,101,119,5,115,116,97,116,101,11, + 15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115,95, + 108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101,120, + 101,99,117,116,101,7,13,110,101,119,112,114,111,106,101,99,116,101,120,101, + 0,1,7,99,97,112,116,105,111,110,6,5,38,69,100,105,116,4,110,97, + 109,101,6,4,101,100,105,116,5,115,116,97,116,101,11,15,97,115,95,108, + 111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108, + 111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101, + 7,13,111,110,112,114,111,106,101,99,116,101,100,105,116,0,1,7,99,97, + 112,116,105,111,110,6,7,38,73,109,112,111,114,116,4,110,97,109,101,6, + 6,105,109,112,111,114,116,5,115,116,97,116,101,11,15,97,115,95,108,111, + 99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111, + 110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7, + 15,105,109,112,111,114,116,111,110,101,120,101,99,117,116,101,0,1,7,99, + 97,112,116,105,111,110,6,7,69,120,38,112,111,114,116,4,110,97,109,101, + 6,6,101,120,112,111,114,116,5,115,116,97,116,101,11,15,97,115,95,108, + 111,99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108, + 111,110,101,120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101, + 7,15,101,120,112,111,114,116,111,110,101,120,101,99,117,116,101,0,1,7, + 99,97,112,116,105,111,110,6,5,38,77,97,107,101,4,110,97,109,101,6, + 4,109,97,107,101,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97, + 108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101, + 120,101,99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7,13,109, + 97,107,101,111,110,101,120,101,99,117,116,101,0,1,13,115,117,98,109,101, + 110,117,46,99,111,117,110,116,2,2,13,115,117,98,109,101,110,117,46,105, + 116,101,109,115,14,1,7,99,97,112,116,105,111,110,6,6,38,65,98,111, + 117,116,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97, + 112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101,99, + 117,116,101,0,9,111,110,101,120,101,99,117,116,101,7,8,97,98,111,117, + 116,101,120,101,0,1,7,99,97,112,116,105,111,110,6,18,38,67,111,110, + 102,105,103,117,114,101,32,77,83,69,105,49,56,110,5,115,116,97,116,101, + 11,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,17,97,115, + 95,108,111,99,97,108,111,110,101,120,101,99,117,116,101,0,9,111,110,101, + 120,101,99,117,116,101,7,18,99,111,110,102,105,103,117,114,101,111,110,101, + 120,101,99,117,116,101,0,0,7,99,97,112,116,105,111,110,6,9,83,101, + 38,116,116,105,110,103,115,4,110,97,109,101,6,8,115,101,116,116,105,110, + 103,115,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99,97, + 112,116,105,111,110,0,0,1,7,99,97,112,116,105,111,110,6,5,69,38, + 120,105,116,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108,99, + 97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111,110,101,120,101, + 99,117,116,101,0,9,111,110,101,120,101,99,117,116,101,7,7,101,120,105, + 116,101,120,101,0,0,4,108,101,102,116,3,0,1,3,116,111,112,3,160, + 0,0,0,11,116,102,105,108,101,100,105,97,108,111,103,17,112,114,111,106, + 101,99,116,102,105,108,101,100,105,97,108,111,103,8,115,116,97,116,102,105, + 108,101,7,12,109,97,105,110,115,116,97,116,102,105,108,101,26,99,111,110, + 116,114,111,108,108,101,114,46,102,105,108,116,101,114,108,105,115,116,46,100, + 97,116,97,1,1,6,17,84,114,97,110,115,108,97,116,101,32,112,114,111, + 106,101,99,116,6,5,42,46,116,114,112,0,0,21,99,111,110,116,114,111, + 108,108,101,114,46,100,101,102,97,117,108,116,101,120,116,6,3,116,114,112, + 18,99,111,110,116,114,111,108,108,101,114,46,111,112,116,105,111,110,115,11, + 14,102,100,111,95,99,104,101,99,107,101,120,105,115,116,9,102,100,111,95, + 99,104,100,105,114,0,22,99,111,110,116,114,111,108,108,101,114,46,99,97, + 112,116,105,111,110,111,112,101,110,6,22,79,112,101,110,32,116,114,97,110, + 115,108,97,116,101,32,112,114,111,106,101,99,116,22,99,111,110,116,114,111, + 108,108,101,114,46,99,97,112,116,105,111,110,115,97,118,101,6,22,83,97, + 118,101,32,116,114,97,110,115,108,97,116,101,32,112,114,111,106,101,99,116, + 4,108,101,102,116,2,120,3,116,111,112,3,156,0,0,0,11,116,116,104, + 114,101,97,100,99,111,109,112,10,116,104,114,101,97,100,99,111,109,112,9, + 111,110,101,120,101,99,117,116,101,7,11,109,97,107,101,101,120,101,99,117, + 116,101,11,111,110,116,101,114,109,105,110,97,116,101,7,13,109,97,107,101, + 116,101,114,109,105,110,97,116,101,4,108,101,102,116,3,209,0,3,116,111, + 112,2,115,0,0,9,116,102,97,99,101,99,111,109,112,7,99,111,110,118, + 101,120,120,23,116,101,109,112,108,97,116,101,46,102,97,100,101,95,112,111, + 115,46,99,111,117,110,116,2,2,23,116,101,109,112,108,97,116,101,46,102, + 97,100,101,95,112,111,115,46,105,116,101,109,115,1,2,0,2,1,0,25, + 116,101,109,112,108,97,116,101,46,102,97,100,101,95,99,111,108,111,114,46, + 99,111,117,110,116,2,2,25,116,101,109,112,108,97,116,101,46,102,97,100, + 101,95,99,111,108,111,114,46,105,116,101,109,115,1,4,4,0,0,160,4, + 5,0,0,160,0,23,116,101,109,112,108,97,116,101,46,102,97,100,101,95, + 100,105,114,101,99,116,105,111,110,7,5,103,100,95,117,112,4,108,101,102, + 116,3,129,1,3,116,111,112,2,103,0,0,9,116,102,97,99,101,99,111, + 109,112,7,99,111,110,118,101,120,121,23,116,101,109,112,108,97,116,101,46, + 102,97,100,101,95,112,111,115,46,99,111,117,110,116,2,2,23,116,101,109, + 112,108,97,116,101,46,102,97,100,101,95,112,111,115,46,105,116,101,109,115, + 1,2,0,2,1,0,25,116,101,109,112,108,97,116,101,46,102,97,100,101, + 95,99,111,108,111,114,46,99,111,117,110,116,2,2,25,116,101,109,112,108, + 97,116,101,46,102,97,100,101,95,99,111,108,111,114,46,105,116,101,109,115, + 1,4,4,0,0,160,4,5,0,0,160,0,23,116,101,109,112,108,97,116, + 101,46,102,97,100,101,95,100,105,114,101,99,116,105,111,110,7,7,103,100, + 95,108,101,102,116,4,108,101,102,116,3,225,1,3,116,111,112,2,103,0, + 0,9,116,102,97,99,101,99,111,109,112,8,99,111,110,99,97,118,101,120, + 23,116,101,109,112,108,97,116,101,46,102,97,100,101,95,112,111,115,46,99, + 111,117,110,116,2,2,23,116,101,109,112,108,97,116,101,46,102,97,100,101, + 95,112,111,115,46,105,116,101,109,115,1,2,0,2,1,0,25,116,101,109, + 112,108,97,116,101,46,102,97,100,101,95,99,111,108,111,114,46,99,111,117, + 110,116,2,2,25,116,101,109,112,108,97,116,101,46,102,97,100,101,95,99, + 111,108,111,114,46,105,116,101,109,115,1,4,4,0,0,160,4,5,0,0, + 160,0,23,116,101,109,112,108,97,116,101,46,102,97,100,101,95,100,105,114, + 101,99,116,105,111,110,7,7,103,100,95,100,111,119,110,4,108,101,102,116, + 3,129,1,3,116,111,112,3,135,0,0,0,9,116,102,97,99,101,99,111, + 109,112,8,99,111,110,99,97,118,101,121,23,116,101,109,112,108,97,116,101, + 46,102,97,100,101,95,112,111,115,46,99,111,117,110,116,2,2,23,116,101, + 109,112,108,97,116,101,46,102,97,100,101,95,112,111,115,46,105,116,101,109, + 115,1,2,0,2,1,0,25,116,101,109,112,108,97,116,101,46,102,97,100, + 101,95,99,111,108,111,114,46,99,111,117,110,116,2,2,25,116,101,109,112, + 108,97,116,101,46,102,97,100,101,95,99,111,108,111,114,46,105,116,101,109, + 115,1,4,4,0,0,160,4,5,0,0,160,0,4,108,101,102,116,3,225, + 1,3,116,111,112,3,135,0,0,0,14,116,115,121,115,101,110,118,109,97, + 110,97,103,101,114,6,115,121,115,101,110,118,4,108,101,102,116,2,24,3, + 116,111,112,3,160,0,0,0,16,116,115,116,114,105,110,103,99,111,110,116, + 97,105,110,101,114,1,99,12,115,116,114,105,110,103,115,46,100,97,116,97, + 1,6,4,110,97,109,101,6,4,116,121,112,101,6,11,110,111,116,114,97, + 110,115,108,97,116,101,6,7,99,111,109,109,101,110,116,6,5,118,97,108, + 117,101,6,12,60,110,111,32,112,114,111,106,101,99,116,62,6,19,67,97, + 110,32,110,111,116,32,114,101,97,100,32,109,111,100,117,108,101,6,21,78, + 101,119,32,116,114,97,110,115,108,97,116,101,32,112,114,111,106,101,99,116, + 6,10,69,120,101,99,32,101,114,114,111,114,6,6,77,97,107,105,110,103, + 6,17,111,118,101,114,119,114,105,116,101,115,32,105,116,115,101,108,102,6, + 5,69,82,82,79,82,6,11,70,105,110,105,115,104,101,100,32,79,75,6, + 17,67,111,110,102,105,103,117,114,101,32,77,83,69,105,49,56,110,6,16, + 68,97,116,97,32,104,97,115,32,99,104,97,110,103,101,100,6,19,68,111, + 32,121,111,117,32,119,105,115,104,32,116,111,32,115,97,118,101,6,12,67, + 79,78,70,73,82,77,65,84,73,79,78,6,12,67,108,111,115,101,32,101, + 114,114,111,114,58,6,0,0,4,108,101,102,116,2,64,3,116,111,112,3, + 200,0,0,0,15,116,115,107,105,110,99,111,110,116,114,111,108,108,101,114, + 16,116,115,107,105,110,99,111,110,116,114,111,108,108,101,114,49,9,101,120, + 116,101,110,100,101,114,115,2,0,4,108,101,102,116,3,176,0,3,116,111, + 112,3,224,0,0,0,11,116,98,105,116,109,97,112,99,111,109,112,7,105, + 99,111,110,98,109,112,17,98,105,116,109,97,112,46,111,114,105,103,102,111, + 114,109,97,116,6,3,112,110,103,12,98,105,116,109,97,112,46,105,109,97, + 103,101,10,224,8,0,0,0,0,0,0,0,0,0,0,24,0,0,0,24, + 0,0,0,172,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,235, + 235,235,1,234,234,234,1,233,233,233,1,232,232,232,1,231,231,231,1,230, + 230,230,1,228,228,228,1,227,227,227,1,221,224,221,1,224,211,204,1,227, + 203,192,1,228,199,185,1,226,197,183,1,224,200,189,1,222,206,201,1,218, + 218,218,1,217,217,217,1,216,216,216,1,214,214,214,1,213,213,213,1,212, + 212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,235,235,235,1,234, + 234,234,1,233,233,233,1,232,232,232,1,231,231,231,1,230,230,230,1,229, + 219,215,1,231,198,182,1,121,166,90,1,100,167,82,1,206,165,102,1,228, + 165,106,1,227,164,105,1,227,166,112,1,195,166,111,1,95,161,75,1,188, + 180,146,1,218,208,204,1,214,214,214,1,213,213,213,1,212,212,212,1,211, + 211,211,1,210,210,210,1,209,209,209,1,235,235,235,1,234,234,234,1,233, + 233,233,1,190,213,189,1,182,209,180,1,233,204,190,1,232,181,146,1,230, + 167,108,1,126,169,84,1,247,251,247,1,103,160,58,1,214,155,24,1,217, + 155,24,1,160,153,35,1,128,180,103,1,193,224,191,1,168,155,78,1,224, + 173,138,1,220,191,177,1,213,213,213,1,212,212,212,1,211,211,211,1,210, + 210,210,1,209,209,209,1,235,235,235,1,234,234,234,1,233,233,233,1,132, + 188,129,1,158,204,152,1,112,164,80,1,188,156,64,1,219,156,33,1,115, + 161,47,1,254,255,254,1,214,234,211,1,118,158,31,1,180,157,0,1,137, + 189,116,1,255,255,255,1,162,203,145,1,187,152,27,1,222,156,71,1,224, + 164,115,1,221,183,163,1,212,212,212,1,211,211,211,1,210,210,210,1,209, + 209,209,1,235,235,235,1,234,234,234,1,233,233,233,1,185,184,140,1,181, + 213,172,1,250,253,250,1,152,196,132,1,109,161,48,1,125,154,14,1,180, + 214,168,1,255,255,255,1,158,202,141,1,102,158,32,1,235,245,234,1,255, + 255,255,1,123,180,93,1,206,159,0,1,213,155,5,1,221,154,55,1,223, + 162,108,1,189,174,140,1,101,171,97,1,154,189,152,1,209,209,209,1,235, + 235,235,1,234,234,234,1,236,207,193,1,234,174,125,1,117,168,78,1,255, + 255,255,2,254,255,254,1,140,192,118,1,82,161,52,1,251,253,251,1,239, + 247,239,1,80,160,50,1,255,255,255,2,105,168,60,1,106,165,55,1,124, + 158,30,1,196,154,0,1,118,156,56,1,145,192,131,1,189,221,186,1,151, + 188,150,1,209,209,209,1,235,235,235,1,235,225,221,1,235,184,149,1,228, + 162,77,1,161,154,17,1,162,202,140,1,255,255,255,3,105,171,67,1,128, + 186,103,1,226,240,225,1,81,159,36,1,116,178,80,1,139,193,121,1,89, + 158,34,1,104,175,84,1,94,158,38,1,125,180,95,1,237,246,237,1,239, + 247,239,1,104,163,79,1,210,202,196,1,209,209,209,1,235,235,235,1,236, + 203,187,1,233,170,111,1,220,157,34,1,152,156,13,1,96,155,30,1,183, + 215,171,1,255,255,255,2,95,169,61,1,108,196,71,1,94,171,53,1,119, + 192,47,1,32,248,223,1,81,220,136,1,109,164,19,1,104,172,70,1,223, + 238,220,1,255,255,255,1,253,254,253,1,109,168,74,1,207,158,94,1,217, + 184,168,1,209,209,209,1,235,235,235,1,236,188,158,1,228,162,77,1,211, + 156,0,1,104,170,74,1,191,219,180,1,83,159,44,1,147,197,128,1,155, + 203,139,1,65,207,121,1,14,255,249,1,79,230,144,1,82,228,139,1,14, + 255,249,1,41,244,207,1,105,172,64,1,255,255,255,3,135,187,111,1,176, + 154,7,1,221,155,70,1,220,172,142,1,209,209,209,1,237,221,216,1,235, + 178,135,1,223,157,51,1,209,159,0,1,124,161,30,1,106,168,60,1,87, + 158,31,1,101,163,18,1,98,166,22,1,97,223,114,1,21,252,237,1,101, + 213,79,1,92,169,1,1,106,209,72,1,126,212,68,1,112,187,48,1,165, + 207,151,1,255,255,255,1,163,206,150,1,136,160,21,1,207,159,0,1,212, + 152,46,1,222,165,122,1,213,197,192,1,237,213,202,1,198,166,101,1,125, + 156,45,1,116,168,63,1,134,187,108,1,168,208,155,1,194,224,192,1,218, + 236,217,1,113,182,95,1,136,191,8,1,141,211,28,1,50,152,0,1,6, + 128,0,1,62,157,0,1,49,242,191,1,19,253,242,1,106,188,64,1,86, + 162,44,1,96,165,55,1,124,177,83,1,131,184,101,1,128,181,100,1,113, + 161,76,1,172,180,143,1,238,209,195,1,72,151,50,1,214,234,213,1,255, + 255,255,5,105,176,68,1,39,246,207,1,29,250,222,1,84,182,11,1,29, + 142,0,1,106,183,0,1,62,237,166,1,20,253,240,1,102,181,43,1,138, + 194,124,1,255,255,255,2,249,252,249,1,181,214,170,1,109,169,86,1,178, + 177,143,1,238,209,195,1,216,167,102,1,125,154,36,1,113,171,74,1,206, + 229,200,1,255,255,255,2,164,207,151,1,112,176,29,1,21,252,235,1,14, + 255,249,1,109,225,69,1,79,235,125,1,78,233,134,1,133,198,21,1,91, + 178,60,1,109,173,55,1,85,162,45,1,115,172,63,1,116,173,71,1,114, + 159,37,1,168,150,21,1,221,159,100,1,216,187,173,1,237,213,202,1,234, + 173,119,1,220,157,34,1,203,160,0,1,134,159,15,1,108,168,57,1,87, + 163,53,1,87,166,54,1,60,154,37,1,131,197,22,1,97,193,53,1,103, + 198,49,1,14,255,249,2,86,186,71,1,247,251,247,1,255,255,255,1,212, + 233,209,1,98,166,56,1,168,163,5,1,207,160,0,1,217,154,31,1,222, + 161,107,1,215,191,180,1,237,221,216,1,235,178,135,1,223,157,51,1,209, + 159,0,1,202,165,0,1,140,164,16,1,128,186,102,1,245,250,245,1,83, + 165,55,1,136,194,117,1,210,232,209,1,105,178,76,1,108,218,82,1,109, + 202,57,1,88,168,49,1,252,254,252,1,255,255,255,2,252,254,252,1,141, + 191,119,1,133,158,28,1,219,153,47,1,222,165,122,1,213,197,192,1,235, + 235,235,1,236,188,158,1,228,162,77,1,212,156,0,1,157,158,11,1,141, + 192,117,1,255,255,255,1,154,201,136,1,100,172,71,1,255,255,255,2,197, + 225,193,1,106,171,7,1,109,180,93,1,92,170,62,1,89,165,57,1,237, + 246,236,1,255,255,255,3,186,217,175,1,139,156,63,1,220,172,142,1,209, + 209,209,1,235,235,235,1,236,203,187,1,233,170,111,1,180,155,34,1,127, + 181,98,1,255,255,255,1,250,253,250,1,89,162,51,1,207,230,203,1,255, + 255,255,2,132,190,106,1,109,165,2,1,151,201,134,1,251,253,251,1,117, + 181,91,1,83,159,42,1,121,179,90,1,149,196,128,1,185,218,179,1,215, + 235,214,1,151,199,143,1,151,171,119,1,209,209,209,1,235,235,235,1,235, + 225,221,1,220,180,140,1,114,172,88,1,250,253,250,1,211,233,210,1,118, + 180,96,1,93,162,54,1,255,255,255,2,193,222,184,1,83,161,43,1,84, + 162,46,1,114,177,82,1,255,255,255,2,109,172,72,1,200,166,0,1,187, + 158,0,1,166,149,5,1,151,153,57,1,135,161,91,1,189,194,176,1,209, + 209,209,1,235,235,235,1,234,234,234,1,186,191,151,1,102,162,74,1,121, + 157,57,1,146,152,13,1,143,152,5,1,171,209,159,1,255,255,255,1,160, + 203,143,1,108,161,28,1,140,191,117,1,125,182,94,1,107,164,39,1,246, + 251,246,1,255,255,255,1,133,186,107,1,198,160,0,1,212,156,0,1,220, + 153,54,1,223,163,114,1,218,189,175,1,210,210,210,1,209,209,209,1,235, + 235,235,1,234,234,234,1,233,233,233,1,236,198,178,1,232,171,117,1,225, + 158,59,1,116,157,41,1,225,240,223,1,107,168,66,1,159,160,9,1,132, + 160,20,1,224,239,223,1,141,191,118,1,153,159,3,1,158,201,141,1,255, + 255,255,1,169,208,156,1,178,151,4,1,221,154,55,1,223,162,108,1,220, + 182,162,1,211,211,211,1,210,210,210,1,209,209,209,1,235,235,235,1,234, + 234,234,1,233,233,233,1,232,232,232,1,235,197,177,1,233,173,124,1,154, + 159,66,1,114,155,46,1,205,155,0,1,209,159,0,1,162,155,6,1,164, + 206,155,1,107,159,39,1,207,160,0,1,109,162,49,1,252,254,252,1,196, + 225,194,1,167,150,54,1,224,164,115,1,221,183,163,1,212,212,212,1,211, + 211,211,1,210,210,210,1,209,209,209,1,235,235,235,1,234,234,234,1,233, + 233,233,1,232,232,232,1,231,231,231,1,233,204,190,1,232,181,146,1,230, + 167,108,1,226,160,75,1,222,156,50,1,216,156,32,1,125,152,33,1,202, + 153,22,1,218,155,32,1,185,152,44,1,154,198,139,1,177,212,170,1,182, + 165,111,1,220,191,177,1,213,213,213,1,212,212,212,1,211,211,211,1,210, + 210,210,1,209,209,209,1,235,235,235,1,234,234,234,1,233,233,233,1,232, + 232,232,1,231,231,231,1,230,230,230,1,229,219,215,1,231,198,182,1,231, + 183,153,1,230,173,130,1,229,168,114,1,228,165,106,1,227,164,105,1,227, + 166,112,1,227,170,127,1,120,165,90,1,102,169,91,1,203,203,190,1,214, + 214,214,1,213,213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209, + 209,209,1,235,235,235,1,234,234,234,1,233,233,233,1,232,232,232,1,231, + 231,231,1,230,230,230,1,228,228,228,1,227,227,227,1,226,226,226,1,228, + 212,207,1,227,203,192,1,228,199,185,1,226,197,183,1,224,200,189,1,222, + 206,201,1,205,213,205,1,204,212,204,1,216,216,216,1,214,214,214,1,213, + 213,213,1,212,212,212,1,211,211,211,1,210,210,210,1,209,209,209,1,4, + 108,101,102,116,3,40,1,3,116,111,112,3,224,0,0,0,10,116,102,114, + 97,109,101,99,111,109,112,13,109,101,110,117,105,116,101,109,102,114,97,109, + 101,15,116,101,109,112,108,97,116,101,46,108,101,118,101,108,111,2,255,15, + 116,101,109,112,108,97,116,101,46,108,101,118,101,108,105,2,1,4,108,101, + 102,116,3,0,1,3,116,111,112,3,192,0,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tmainfo,''); +end. diff --git a/mseide-msegui/tools/i18n/messagesform.mfm b/mseide-msegui/tools/i18n/messagesform.mfm new file mode 100644 index 0000000..78a5523 --- /dev/null +++ b/mseide-msegui/tools/i18n/messagesform.mfm @@ -0,0 +1,51 @@ +object messagesfo: tmessagesfo + optionswidget = [ow_arrowfocus, ow_subfocus, ow_destroywidgets, ow_hinton] + visible = False + bounds_x = 298 + bounds_y = 263 + bounds_cx = 421 + bounds_cy = 234 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.bounds = ( + 0 + 0 + 421 + 234 + ) + options = [fo_closeonesc, fo_closeonenter, fo_autoreadstat, fo_autowritestat, fo_savepos, fo_savestate] + caption = 'Make Language Units' + onclosequery = formclosquery + moduleclassname = 'tmseform' + object twidgetgrid1: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_focusbackonesc, ow_destroywidgets] + bounds_x = 0 + bounds_y = 0 + bounds_cx = 421 + bounds_cy = 234 + anchors = [] + datacols.count = 1 + datacols.options = [co_fill, co_savestate] + datacols.items = < + item[messages] + width = 1024 + options = [co_fill, co_savestate] + widthmin = 1024 + widgetname = 'messages' + dataclass = tgridrichstringdatalist + end> + datarowlinewidth = 0 + datarowheight = 16 + reffontheight = 14 + object messages: tterminal + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 1024 + bounds_cy = 16 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savestate, oe1_checkvalueafterstatread] + options = [teo_readonly] + reffontheight = 14 + end + end +end diff --git a/mseide-msegui/tools/i18n/messagesform.pas b/mseide-msegui/tools/i18n/messagesform.pas new file mode 100644 index 0000000..b52927c --- /dev/null +++ b/mseide-msegui/tools/i18n/messagesform.pas @@ -0,0 +1,31 @@ +unit messagesform; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseguiglob,msegui,mseclasses,mseforms,mseterminal,msewidgetgrid,msethreadcomp, + mseglob; + +type + tmessagesfo = class(tmseform) + messages: tterminal; + twidgetgrid1: twidgetgrid; + procedure formclosquery(const sender: tcustommseform; + var amodalresult: modalresultty); + public + running: boolean; + end; +var + messagesfo: tmessagesfo; +implementation +uses + messagesform_mfm; + +procedure tmessagesfo.formclosquery(const sender: tcustommseform; + var amodalresult: modalresultty); +begin + if running then begin + amodalresult:= mr_none; + end; +end; + +end. diff --git a/mseide-msegui/tools/i18n/messagesform_mfm.pas b/mseide-msegui/tools/i18n/messagesform_mfm.pas new file mode 100644 index 0000000..aee1bf0 --- /dev/null +++ b/mseide-msegui/tools/i18n/messagesform_mfm.pas @@ -0,0 +1,74 @@ +unit messagesform_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,messagesform; + +const + objdata: record size: integer; data: array[0..1121] of byte end = + (size: 1122; data: ( + 84,80,70,48,11,116,109,101,115,115,97,103,101,115,102,111,10,109,101,115, + 115,97,103,101,115,102,111,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,13,111,119,95,97,114,114,111,119,102,111,99,117,115,11,111,119,95, + 115,117,98,102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119, + 105,100,103,101,116,115,9,111,119,95,104,105,110,116,111,110,0,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,42,1,8,98, + 111,117,110,100,115,95,121,3,7,1,9,98,111,117,110,100,115,95,99,120, + 3,165,1,9,98,111,117,110,100,115,95,99,121,3,234,0,23,99,111,110, + 116,97,105,110,101,114,46,111,112,116,105,111,110,115,119,105,100,103,101,116, + 11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116, + 97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117, + 115,11,111,119,95,115,117,98,102,111,99,117,115,19,111,119,95,109,111,117, + 115,101,116,114,97,110,115,112,97,114,101,110,116,17,111,119,95,100,101,115, + 116,114,111,121,119,105,100,103,101,116,115,0,16,99,111,110,116,97,105,110, + 101,114,46,98,111,117,110,100,115,1,2,0,2,0,3,165,1,3,234,0, + 0,7,111,112,116,105,111,110,115,11,13,102,111,95,99,108,111,115,101,111, + 110,101,115,99,15,102,111,95,99,108,111,115,101,111,110,101,110,116,101,114, + 15,102,111,95,97,117,116,111,114,101,97,100,115,116,97,116,16,102,111,95, + 97,117,116,111,119,114,105,116,101,115,116,97,116,10,102,111,95,115,97,118, + 101,112,111,115,12,102,111,95,115,97,118,101,115,116,97,116,101,0,7,99, + 97,112,116,105,111,110,6,19,77,97,107,101,32,76,97,110,103,117,97,103, + 101,32,85,110,105,116,115,12,111,110,99,108,111,115,101,113,117,101,114,121, + 7,13,102,111,114,109,99,108,111,115,113,117,101,114,121,15,109,111,100,117, + 108,101,99,108,97,115,115,110,97,109,101,6,8,116,109,115,101,102,111,114, + 109,0,11,116,119,105,100,103,101,116,103,114,105,100,12,116,119,105,100,103, + 101,116,103,114,105,100,49,13,111,112,116,105,111,110,115,119,105,100,103,101, + 116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95, + 116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99, + 117,115,17,111,119,95,102,111,99,117,115,98,97,99,107,111,110,101,115,99, + 17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0,8, + 98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,3,165,1,9,98,111,117,110,100, + 115,95,99,121,3,234,0,7,97,110,99,104,111,114,115,11,0,14,100,97, + 116,97,99,111,108,115,46,99,111,117,110,116,2,1,16,100,97,116,97,99, + 111,108,115,46,111,112,116,105,111,110,115,11,7,99,111,95,102,105,108,108, + 12,99,111,95,115,97,118,101,115,116,97,116,101,0,14,100,97,116,97,99, + 111,108,115,46,105,116,101,109,115,14,7,8,109,101,115,115,97,103,101,115, + 1,5,119,105,100,116,104,3,0,4,7,111,112,116,105,111,110,115,11,7, + 99,111,95,102,105,108,108,12,99,111,95,115,97,118,101,115,116,97,116,101, + 0,8,119,105,100,116,104,109,105,110,3,0,4,10,119,105,100,103,101,116, + 110,97,109,101,6,8,109,101,115,115,97,103,101,115,9,100,97,116,97,99, + 108,97,115,115,7,23,116,103,114,105,100,114,105,99,104,115,116,114,105,110, + 103,100,97,116,97,108,105,115,116,0,0,16,100,97,116,97,114,111,119,108, + 105,110,101,119,105,100,116,104,2,0,13,100,97,116,97,114,111,119,104,101, + 105,103,104,116,2,16,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,14,0,9,116,116,101,114,109,105,110,97,108,8,109,101,115,115,97,103, + 101,115,8,116,97,98,111,114,100,101,114,2,1,7,118,105,115,105,98,108, + 101,8,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115, + 95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,0,4,9,98,111, + 117,110,100,115,95,99,121,2,16,12,111,112,116,105,111,110,115,101,100,105, + 116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110, + 117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101,49, + 95,115,97,118,101,115,116,97,116,101,27,111,101,49,95,99,104,101,99,107, + 118,97,108,117,101,97,102,116,101,114,115,116,97,116,114,101,97,100,0,7, + 111,112,116,105,111,110,115,11,12,116,101,111,95,114,101,97,100,111,110,108, + 121,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0, + 0,0) + ); + +initialization + registerobjectdata(@objdata,tmessagesfo,''); +end. diff --git a/mseide-msegui/tools/i18n/msei18n.ico b/mseide-msegui/tools/i18n/msei18n.ico new file mode 100644 index 0000000000000000000000000000000000000000..4eb945d76be790f2f9835caeb145394829423dde GIT binary patch literal 16958 zcmeHv2Uu0tw(h0`h$b;=EE@y_6zO2af=U&87tq+TcT_Zr9UEd7J48VRmEHs!iUk3Y z-Z#A?QY>`kzhfZecyf~5ocm7Bz3;w9zTw(s?KS5=#y`p&bFByjV)UP(p@9DFEl@KS z2)YXd0yPr)NU(>5KX3h`?|%IUK=4<~r-|Q4f1L2mcg^F!`Jrk2H$9uib(AMjBvJZ8 z_`N)T&*$;^{JXz;Zhyt~TPA)ZM)UuMaC9e3y&K1NRIfMhs9R^=VMwi6hY_`=9Y%jJ z?O;S=`h^(r=lngN$LI6!`1gDrz8+uqubA(@>Y8k?RvVLD8^(6jt~2W}lySZ{=`jAC zvCQKfQ#o3C)0d!8%0AUeGBy^Lh|(`!t#blJj)v_5t%z!JccCp3yI;+`FlQ( z&(9q$8T!Ih9F@-kXj-5DiaZ<zM=b@a2ti%n9VBnv0GH$ zzTBo<^J1G)Rk*EuMd&(VNx;hPc_bMLBL!tKGlVTIADi3I1JyAP@xnxaQbVa7JT8yV z^Wa#?^ZF}wz&vXj-%-f1xy|NQ?4#_nWbc#A-NK=g0r^8D!r87ro$V^JJ=?W(`RT4T zQ?GPx8hyPp3|u>7%FjKp{-QjNomGbSNe#R_G6ZQy43K_wILTmS9MwhE5v`{50~#&K z8wMiLbR-fqMz-qUU21eI{-TkR7kOMBpW{p$7j$`ke}zBLHNPUB$y0nA$Z?r;zmROc znd4W%2ub(kQR2xN!^PttE$SH`ZXwKjYAIjkvAK7%&1pG|a_C`!Ge^dWF~~S+g7j0Pk>xT4xfdoN=cpMHH;=}X zaRYEit{3u#Nd|MA;PH7LJRhDH&yVNH^Zi$Gp$)qN#~hC9?B^8Q>{@M3{vBf~T^%*P zL(9_@DhOYu((rVd8Xm9K!S!w0SbaLyj<~&}kmz8F)N@mjbz=c?Zp=mYH49`qPeSV9QAn}shde!vIP$Mh zjxRh9o)6E9=g0FT9Vq-ObU@dTV12e>pUnBXVwChQj?WysA6m(U-H z!{yo}18{HIK)9^a#PYog7mlQDOvJ%!g^@sb3ad_r95wDIIWQ8Io7rMJ8`Sc?u^|(aJq72&&y_c#u&FYjDW)iRm`{R0fU2t*P%1i4|j&bXj>PNdmjrG7>prhs)MQC5rfYt?dXq-_--vgb{XaDz5I@B3`FZP4FvpP)9 zYQlDpHe6O~!EcEcLYM2}&OCWMuvWs;by|qpJ{0l$Ms4UsG#JCK4S@Eo{?NSLAKD)Mp>snQx>w1^&ntb_1L>gep-#kk z74$o$0+l0jkl!HKI*8dZ9P#^xB6*i?ee!CJthh;P;ZM5syTQ4U>jR2iQ@Bq2Gk(Bp3a+b} zH*qGCVXtN@ef-!^+gf`BEgpy<>mdkUHXOlAh9GdhPOCm{S}Ni2>b|f%pp2nzdeHV6 z3{Bs`(DE4qZ7+)Pw+BMoT@PBW+EBZo3}uJ!(0gA;DD3$bN=N0Pu)izhwo5{OmjqN! zc8A*KUeLTOhk-7#n0QhMyY)i2SP0=Up&M=(2ykNSxI`=&e_+c%W!gVuORbz++z^!?A)OuVk*+`;vAv7yx7XmhCs(c#4{ca{x7 z5Md5lIuv)7567Jq!*FMrKIuXq*H#V0nr+G$>7)YnYyF@ZI2>95B>uyo<)`1O3ys?Y zpmt3QeO&rM;aGRb?fV+CJEfqw`&+2)=!gMZBr$56BqotQEFF4b(Oy}s-Y&#;8zD|F z5aQYl!aue%u8$Dl#!vw~h6`|OlmOmiBoREL6T+4#;`zFMh}@`xC>w=}sHJjgujIac zk!C1yH`!PsAi+fZc9x0cJjVBX`Jm1As-&wiTuX30pE*k6zSqRg2$)MX8tLH9a>h^C zm+KRLdQWn3<3P-D=m))v3Q%=bf~G&&J;(ssqz6sHukJGls<-r@d`$yNE~@B#K?S{t z19JPnhU(6*V76Wy%NI&u$K0=QbcGzwEfnI)Y$0yU65{4GA#P6<;?^Xx{b;{oX)e6>6x)^tatbti;R{u(ad3R+@j$$pHnQ25BPtZb~zpx@)b z=X}>;5ZQhvuV;8I!}Yw+gw7@2Q+gn15yhWngFoY5O2?&x5WI9CPHoc0j8j_BpqjqV z6$Pl>)Pxq{*ChL^dk;k4o4QbT*M!my!tbUAr7NmXyr>AdBVS{noitW2kica#F?btG z!+)|6ek8tAgzzEU-i&|z_qahg-HG?i|7*knmh1HT`X~vwn@GcJN@v_zsEmi}wDEM4 z8lG?Jjk^na;kps0f1t?y2=@*?mW`D*{jE4au~Cd-q!QWQh}Tu*H+y*<$7>ni30?Di z2*2<2UI<#OhhXde2wtp%-~}2K1Nz}S)xC2Ms-pj;eo%H+fbtb3sQC>;Ki}c#<2eY* z9*kcLO74XJhC2GW^@FxcALu!LkBPQY*kdV)Yh%RWGrl9mRl-eNZ`d6* zNe3RJqgxZY5+8ctHtFaV>59d3sx16|?1Q_j2jcOjL3nJVijWmTcoCQ0XT&o0mK0+N zcgDv!8Sj^V!1OTs7eTG5hW`E+p8nm62D5lF}&3-xTw(Sh3 z`C{;yERH)9#Sk*96Yk6rBG8hqIkP8jn@QuQA;miq4@0q59(WNSJc$=9jQ>j=cuiM8 z0NLd3nn4I#uZ2fze5i%a? zq2^G%V+>W_AsFJ?4>pdy;I~zX_zglNulydd^8|QlC60(6sm@s184+Z&@I~EmXR;*x z#&Db$;I`>k@SfTo-qXn+NWRoTyB%ycwNQ43&LFLWh4d`Z({-cOa<^CD?q>mve%D4-~sXLuC*MF zZ&8EA+0hu}HJR`m66Z&ukDm!N0!*OqJ_s|<_Jt$m`RDtD$lOa}FGR|wuaL4v45=%` zk+fP239BR!zp4YG7l`4Rl^DXN3lKV03c*%A;Y+dbKgUmenARJ zL4DA8!3)O2xX8Dy+kBvRJN~w~ug>){*9+WtWA1a`hH%$-84+$X!c6uE8Ye*Tcmdgm zWU2r@^Sa=owGhWvDqzPB9V~S+!_;$zm~>_^tWNaBwzC?zc3cVJM|&aVm=JjB3QLE;&{rh+E_cH9#L2$?9ry(uJw-Jk5^K7)L7ZU+Rc5+cB+H+*(!;I_RQJhxLk z-tjeF?EeO-C%d8Gk`SdXLcDerqT-qmWoN%a*$FWepO8V;g)T_H&<&ZVx*&g#6!N!< zLu4y}Xh&D1ZWAJwd?jMJ5cjDL;CRC^^0#zwi(-P?q#xiqr5nXZ;>_5t@Ej}MbZhcg z8H|TBEz*OijK&jXdnHSbeDU8KHDKg!bTw?R|*kE{uWHNLAyVA zwZ(&*6rY`D%VL+^5bUJ2(W!NVaASr%Zkd0JpC^5vcfe97jO)Q)VgS{6?Rk)DqMp3( z!g~)~FLED``>@3Gl3=oVD{iv)L$dYbnF53nX1BQl{Io<22bU23MHIWNiLa{!NZs`f zvZ&{kbx9HFXTC@F`A#Uk_%+^KlR))tG1Pbq@Xkko4_;y@4ef%wF!G59B%wm&1__bv zOTOXS1r^7{Q06F!QuY-G($8)o5^YHb#Is*?z&xOQ;4z^yPEYR&o0WZFu~#26ju~O8 zqY?K0Gz1qGsNnn})sjQo#yn$OjE`|LUdGM#r`RXYdrzGAIYw|Fo_o=ulLZyb^9N+_ zFv1;fNiv5xzfgd!t0b{}>$fjZbRui!Mj3pP*=?d@GG{){?9eivl%1FG?3k3mvQ1Vz8B9Srj@(oc?Y>1*VLll>f zMseu~G{*KpQ?vr!lP+GT)4A!&C?P$Ryy}Ts;zqrvIBKtpkq(Fl7X&CjE{39mQplp% zn6Q%kjr{K}@$%Yq8SGfALN(PWjCLA@k&c65U{Af5-I^G&QxgXJbYOaPc+I>ElVb_L zC*xzBjF;=cFY&)Nl3JT+ED^(dE(t62TVm{}*J7iHmo`F#Y^HT6>3%KQ+}>Uer}oL? z#vUa^*!M*e^(&*!Xyf@+>eUC2K;h#-)HBe=o0L%~D4&eNs%a>CI~~RErlI6LNzEiQ zr42@Nk`9{V)X*G5e2A7seN=ZeKJJL7yI-LpSQ77ozDBiA2UNL9qv{OB0|x=}b_$Tb zkz&mjF5f1#<=!sxLwH7}=j{ZtWli_`+7p0PmO?*53kRlvF3vamWPi?y^qy=_nVd~Y8- z+pmU%qgqHiHvoyQLy!?L5@nHN@HS-v-X@Mjbw zt{!-~NfrT{RAGPG9F`AOVPb?0COln-@nI`5E_5lz_|AjL_31EkoeT@-2`y3PQXk`u zCE|*Vr0jlWf5mDOnX%O4sw=#Hs1-Z^lX-a|(oar6(hd#mIi>*fpB1p4dN`pDsz^Pg ziA+a5h@7Yw?K&JOUIxetGec$44Ad1Z!26sTsLiuNN&O}ifBXq0pSGc-WgALA+M=O! zA)0Hf(cH8g&Gq!Uj`Z<%3Ytqu4+*NMOX!Ufkt#}(6;MPvD4^Jwdrye+D;-dJLO}VT z1F{eHM4TP1L8w2r$89DoUT(#-)ZLhtvI|oa?JzlhJ0?YKB3+PPLYCr3KWmf*I#a!^ z_9@a#vN_dM;vn%~kzoE3{}W9l{G-N7x8ytTLQ~BfWL}($T-T+@a2$obE*dZj?1P23 z`r?+81`?0~Yv_W(83N$y&NArhSXf7Is`ZR5n6b>LA^h0s7A_`+U{P5VV(U<6!{{!aF0=9QvCVn*Ul%zm~N%e<@! zD$vr@M78A*#Eg}S`6d3h<^M`!8S4~7iBRG}1IK`rgN7}+SC=5?>fISiwp>cISw zCXU?DLHOChh(B+D#A`-)5@Z73$A)+sI}OEoYfxXg2TkuBQCGSX4JGzyDn5*+GDouS zVUh#Hd3!YD3<-UPeP||LG=C(WkZ&|sPDMl3FqFI=O*$CZs)M2=c@#v+qAaizsxDI9 za9n_#-IQ-_#Bp!kcW^i{6tkbN!_4$Ou*f<9tL%fYq@$(i0Op7eV|n6XY;|3Lsuy=? z&0+SD`-w*V*8S-Q;z{uaf|>$XYvf;;i_;#4FnOp3y>NM0`77Zl?b)5D zo}N?CP;84Zz=mW)T+XsYV)0hItv-Q@5f{p5p()20rPbq5Qa%bL1$rpX=!?SGUa0n$Mx`6|a4tw8?=Y>MY{l?+ zZ3j5nYhrQWY|M;W1IvWXuu9xQN82{piaGJyTK7!ZrZHn>N(zjnwsO7OUjO}3{acxyhWq*}T7GS!L>JrQHu6&{;=VXNB&%#U1;c}ZI^KhYLH#%+S- zs|}bQwdT|0h?V7;Bg7+%45TjoR{j4+>%XEa3u;Q87vqk%H8wuB#PDZBpb*vr-R^&l zZVzQ3`@9QOUiHP8^r^7TJA#Y(KDd(`fb_iEc$a?@O-0^>`6*$KYLgdu-SmXG;7u`* z@Hf!0(T((Rocv-7no5_W{`Fim=TmOT8jglE9W=gFK;5(N@%~{ae0V5}N?I=z(^@L~ zDD@F`^}?M!n%Mud8J5P_U`g5zEG1czYKKM1KjFt1o0{2=SN!4nkHP}Sz~5Z|i~0*n zOI_FCq4x@GdpsA$5vEX!8Un=#>f=Tzpx5(mP>Ae?VZ{GM+551!&=0N!4-j1tf{KCw zynlV4Vt+iv{zQ@lk~orADE}BiSbfPCJV;znU*UwR`co7m9q9Y*cwapa&3Pth${2)( zq`s(o*$efr`r!SeUZ|usLh%*CPwVN#o$?5^AAlpCv#}!H7At8EYqR!YW!7FSNVmhR zWZP2iWBk$jpYf9~{AT|rd!V>T1-qAk!fhm9)|iKz*z_;aB_xf7WqX#O_l;z(E5z_*zq(+m0ooJy=25 ztuuDQGSRkqO58dT_p!L2^~>7tH~K%^5Bt6TU;g#wRX%}Bu_SyJh9*pgN+j9;nFiz@ zc1O?9uOWQ=Ei~i%W8&+bSX~!{Lyc*;*7zDBRrG?fPt<|ibfB%UOf2|sawa%0u|MQF@3M1AHUG-i!JU92|VJyIt8awz&)4)NzS z;C^i?_J(f6zI!&<^Lz_dBy7bzihpyTt-|7A(QB zu>(=_P!+Ge6(G9W2Y0R;W6#~ySpCcnPM&k&;XVZpVas6aKNE+~>%;MA|GW)9PYUNg zHutl6ecQI~`G@{*n-9=__doXk-(0nh&%U*~IyiVGHiylG!K1+Pc-l*uop_*I-&4fC%QMN7apD-h?CbXuqk8>9LfGS&yR=SDKk8D z7>uXXGYXq4Xc3K+2x(pOe_r#Bp}wDLd*AO%?Cr04f2@7~k9EfT$m~Dd56BPPRvs6$ z8O~wLvE+p%%u;7TD`qIpKFPCY38Vj9ER5qHBjWG zh@4B^knZpeqIPw}?E`Aqd2=4-hi}Kquua(Ky8;)Tt#Hp?A2HkdAY<1|-nXygeN3|b zEXKw7+OhuDv5f<*`@e1bK)bnb#`hZ41nf#F3bd<@xND2^33gbTWrGnZ6QLZX0r@B; zs3Z=+u)H}~@a7~=zI}xIA1Lt97y2OR0PROoZ}j{jT`Y6A#H4UL zSVSJc^6;J5M|q53bX_H7AMZ^KUPJ`MoWe^k5sTp6|zsN4u~ua6Li!{MS&H zkC)SXe0*sx{p|Prp3eNcIKcNw@Y;~?o8bKt@`KIn2l2*|d2tIgT5_Y#A>rj|xF;RL zrp!%L`&mFMULQ&?HK`6TfpyLn+%EM(PH_Y(MNd$g8;Ok4REX-UP+DJ&w{_L1Cm(1c zzo;!p!u$Mq)K=!Ami(cvGLih?X)6ytHUySaf zDI6_zg73qA^Td}giJ-)z@JT!Zr*wO)6>Wrh`b=mi8bB|}7_&tyaWU%*UM9PvAngtc zMURkIm5JQ9g~>ovr`qeVZS&-v1SADis;Or2og(`>@+C>YjcS*U}wvPIM49 zA{&@z%z}Q(IE+oS!1{O_oKHLf|716WQ?84wOv0<`EW~^$MQr_Bh)4(J6*<)VdrUpi zNaR$PAe(ejP@ar((H)d0UPV^aNhCknhgA0k$Z)nq9QpN=b2D+@X$C@1OoQj?8944X zw|;ft^1SH})<#mC_RlqtycJ_EUBdgl8G9^SY7(Bd&X(`t;rp1Vm;FyYQ^NQEy*HE5 zr{@pq%R{cVA^+PUAoCRbGfv=g@-8fmor4K66EHE(0zbyD!rH{$*q!B!<8L0|a#b{L z)}+DjT>6yIk1HEy~rLGbC>HQwjuWO04ZIg0joTJQg>G?HGCW-4*~!QB_r&kSS1t_?(7ctX&w(#0|ZQP<3 zn^&|>j9G~-v=-YHYlp*mS8$}n7pKbZ!=)?|H_PJ@T1@-#Sx=E1>5i1>+lb6~jIcM^ zc>J*z;lzQc+-Rgfxqyt|?MU+7fH>DhxPNsauH0M&N3V4_?6bc4n9rti+Mi3|`xCgY z%X?eDb^m9ynP3?8JFe6HxmgjWg8lyt_V#mMm0DACmL z;v(vkZlg3K5Kl`Z;r%`n9<{l+K^(ZA_k`p*t{26?y(A7dh!Z~f(Rdc?15xOHl!RjSQlxK89+nd|KK=Re3V>WjTj|AK*EG*%Q*tmuIlBgw`L zJwX*o%@4eM{23!99`N;f93GFym8$`gfoIDjFeqE!IRTpYutU<8m~; zDQUe%jHNzf*vIR49*4*KGi#ZD zr#^T-Y!C7aC3Txn^ zeEt7vxPPr<;-gsQln$L@OvLxanuzaDHI-b*v6(r`_g(yNeg5~?dT4*o_ToL3R&LN< c8}Z|R_4D8Dxc_fB{`&t1@c-Zczomiy0E%iwhyVZp literal 0 HcmV?d00001 diff --git a/mseide-msegui/tools/i18n/msei18n.pas b/mseide-msegui/tools/i18n/msei18n.pas new file mode 100644 index 0000000..7f5dffd --- /dev/null +++ b/mseide-msegui/tools/i18n/msei18n.pas @@ -0,0 +1,35 @@ +{ MSEtools Copyright (c) 1999-2014 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +program msei18n; +{$ifdef FPC} + {$mode objfpc}{$h+} + {$ifdef mswindows}{$apptype gui}{$endif} +{$endif} +{$ifdef mswindows} + {$R msei18n.res} +{$endif} + +uses + {$ifdef FPC}{$ifdef unix}cthreads,{$endif}{$endif}msegui, + main,messagesform,project; + +begin + application.createForm(tmainfo,mainfo); + application.createForm(tmessagesfo,messagesfo); + application.run; +end. + diff --git a/mseide-msegui/tools/i18n/msei18n.prj b/mseide-msegui/tools/i18n/msei18n.prj new file mode 100644 index 0000000..2a6f3b8 --- /dev/null +++ b/mseide-msegui/tools/i18n/msei18n.prj @@ -0,0 +1,1076 @@ +[componentpalette] +order0=0 +order1=0 +order2=0 +order3=0 +order4=0 +order5=0 +order6=0 +order7=0 +order8=0 +order9=0 +order10=0 +order11=0 +order12=0 +order13=0 +order14=0 +order15=0 +order16=0 +[projectoptions] +projectdir=/D:/mse/packs/standard/git/mseide-msegui/tools/i18n +projectfilename=/D:/mse/packs/standard/git/mseide-msegui/tools/i18n/msei18n.prj +sourcefilemasks=3 + "*.pas" "*.dpr" "*.lpr" "*.pp" "*.inc" + "*.c" "*.cc" "*.h" + "*.mfm" +syntaxdeffiles=3 + ${SYNTAXDEFDIR}pascal.sdef + ${SYNTAXDEFDIR}cpp.sdef + ${SYNTAXDEFDIR}objecttext.sdef +filemasknames=3 + Source + Forms + All Files +filemasks=3 + "*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + *.mfm + * +codetemplatedirs=1 + ${TEMPLATEDIR} +showgrid=1 +snaptogrid=1 +moveonfirstclick=1 +noformdesignerdocking=0 +componenthints=1 +gridsizex=8 +gridsizey=8 +autoindent=1 +blockindent=1 +linenumberson=0 +rightmarginon=1 +rightmarginchars=80 +scrollheight=0 +tabstops=4 +spacetabs=0 +showtabs=0 +tabindent=0 +editfontname=mseide_source +editfontheight=0 +editfontwidth=0 +editfontextraspace=0 +editfontcolor=-1879048183 +editbkcolor=-1879048186 +statementcolor=14745599 +pairmarkcolor=-2147483642 +pairmaxrowcount=100 +editfontantialiased=1 +editmarkbrackets=1 +editmarkpairwords=0 +backupfilecount=2 +encoding=1 +eolstyle=1 +trimtrailingwhitespace=0 +debugcommand=${DEBUGGER} +debugoptions= +debugtarget= +runcommand= +xtermcommand=xterm -S${PTSN}/${PTSH} +remoteconnection= +uploadcommand= +gdbprocessor=auto +gdbservercommand= +gdbservercommandattach= +beforeconnect= +afterconnect= +beforeload= +afterload= +beforerun= +sourcebase= +sourcedirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ + ./ +defines=0 +progparameters= +progworkingdirectory= +envvarnames=0 +envvarvalues=0 +defineson=0 +stoponexception=0 +valuehints=1 +activateonbreak=1 +raiseonbreak=1 +showconsole=0 +externalconsole=0 +settty=1 +gdbdownload=0 +downloadalways=0 +startupbkpt=0 +startupbkpton=0 +gdbsimulator=0 +gdbserverstartonce=0 +gdbloadtimeout= +gdbserverwait=0 +nogdbserverexit=0 +gdbservertty=0 +exceptclassnames=1 + EconvertError +exceptignore=1 + 0 +nodebugbeginend=0 +fpcgdbworkaround=1 +mainfile=msei18n.pas +targetfile=msei18n${EXEEXT} +makecommand=${COMPILER} +makedir= +unitdirs=4 + + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}kernel/ + ${MSELIBDIR}*/ +unitpref=-Fu +incpref=-Fi +libpref=-Fl +objpref=-Fo +targpref=-o +befcommand=0 +aftcommand=0 +makeoptions=4 + -l -Mobjfpc -Sh -Fcutf8 + -gl -O- + -B + -O2 -XX -Xs -CX +reversepathorder=0 +makeoptpurpose=0 +befcommandon=0 +makeoptionson=4 + 63 + 31 + 34 + 32 +aftcommandon=0 +unitdirson=4 + 983103 + 65599 + 196671 + 65599 +uid=0 +macroon=0 +macronames=0 +macrovalues=0 +groupcomments=6 + + + + + + +fontalias=0 +fontnames=0 +fontancestors=0 +fontoptions=0 +fontheights=0 +fontwidths=0 +fontxscales=0 +usercolors=30 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +usercolorcomment=30 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +formatmacronames=0 +formatmacrovalues=0 +scriptbeforecopy= +scriptaftercopy= +newprojectfiles=4 + ${TEMPLATEDIR}default/project.pas + ${TEMPLATEDIR}default/main.pas + ${TEMPLATEDIR}default/main.mfm + ${TEMPLATEDIR}default/main_mfm.pas +newprojectfilesdest=4 + ${%PROJECTNAME%}.pas + + + +newfinames=3 + Program + Unit + Textfile +newfifilters=3 + "*.pas" "*.pp" + "*.pas" "*.pp" + +newfiexts=3 + pas + pas + +newfisources=3 + ${TEMPLATEDIR}default/program.pas + ${TEMPLATEDIR}default/unit.pas + +newfonames=11 + Mainform + Simple Form + Docking Form + Datamodule + Subform + Scrollboxform + Tabform + Dockpanel + Report + Scriptform + Inherited Form +newfonamebases=11 + form + form + form + module + form + form + form + form + report + script + form +newfosources=11 + ${TEMPLATEDIR}default/mainform.pas + ${TEMPLATEDIR}default/simpleform.pas + ${TEMPLATEDIR}default/dockingform.pas + ${TEMPLATEDIR}default/datamodule.pas + ${TEMPLATEDIR}default/subform.pas + ${TEMPLATEDIR}default/scrollboxform.pas + ${TEMPLATEDIR}default/tabform.pas + ${TEMPLATEDIR}default/dockpanelform.pas + ${TEMPLATEDIR}default/report.pas + ${TEMPLATEDIR}default/pascform.pas + ${TEMPLATEDIR}default/inheritedform.pas +newfoforms=11 + ${TEMPLATEDIR}default/mainform.mfm + ${TEMPLATEDIR}default/simpleform.mfm + ${TEMPLATEDIR}default/dockingform.mfm + ${TEMPLATEDIR}default/datamodule.mfm + ${TEMPLATEDIR}default/subform.mfm + ${TEMPLATEDIR}default/scrollboxform.mfm + ${TEMPLATEDIR}default/tabform.mfm + ${TEMPLATEDIR}default/dockpanelform.mfm + ${TEMPLATEDIR}default/report.mfm + ${TEMPLATEDIR}default/pascform.mfm + ${TEMPLATEDIR}default/inheritedform.mfm +expandprojectfilemacros=4 + 1 + 1 + 1 + 0 +loadprojectfile=4 + 1 + 1 + 1 + 0 +newinheritedforms=11 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 +toolmenus=0 +toolfiles=0 +toolparams=0 +toolsave=0 +toolhide=0 +toolparse=0 +toolmessages=0 +toolshortcuts=0 +settingsfile= +settingsautoload=0 +settingsautosave=0 +settingseditor=0 +settingsdebugger=0 +settingsmake=1 +settingsmacros=0 +settingsfontalias=0 +settingsusercolors=0 +settingsformatmacros=0 +settingstemplates=0 +settingstools=0 +settingsstorage=0 +settingscomponentstore=0 +settingsprojecttree=0 +settingslayout=0 +messageoutputfile= +modulenames=2 + MAINFO + PROJECTFO +moduletypes=2 + TMAINFO + TPROJECTFO +modulefiles=2 + /D:/mse/packs/standard/git/mseide-msegui/tools/i18n/main.mfm + /D:/mse/packs/standard/git/mseide-msegui/tools/i18n/project.mfm +macrogroup=0 +forcezorder=0 +stripmessageesc=0 +copymessages=0 +closemessages=1 +checkmethods=1 +colorerror=-1610612712 +colorwarning=-1610612717 +colornote=-1610612716 +sigsettings=27 + 1,1,T,F + 3,3,T,F + 4,4,T,F + 6,6,T,F + 7,7,T,F + 8,8,T,F + 9,9,T,F + 10,10,T,F + 11,11,T,F + 12,12,T,F + 13,13,T,F + 15,15,T,F + 16,16,T,F + 17,17,F,F + 18,18,T,F + 19,19,T,F + 20,20,T,F + 21,21,T,F + 22,22,T,F + 23,23,T,F + 24,24,T,F + 25,25,T,F + 26,26,T,F + 27,27,T,F + 28,28,T,F + 29,29,T,F + 30,30,T,F +defaultmake=1 +units= + ( + a=0,8228,6,Pascal Units + ) +cmodules= + ( + a=0,8228,6,C Modules + ) +files= + ( + a=0,8228,6,Text Files + ) +[breakpoints] +on=0 +path=0 +line=0 +address=0 +addbkpt=0 +ignore=0 +condition=0 +panels=2 + panel1 + panel2 +[componentstore] +storedir=/D:/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ +filename= +[components] +[selecteditpage] +colwidth=100 +x=0 +y=0 +cx=0 +cy=0 +[progparams] +progparamhistory=0 +workdirparamhistory=0 +envvarons=0 +[edit] +hintwidth=0 +hintheight=0 +finddtext= +findhistory=0 +findoptions=1 +editpos=2 + 0,0 + 0,-1073741823 +bookmarks0=0 +bookmarks1=0 +sourcefiles=2 + /D:/mse/packs/standard/git/mseide-msegui/tools/i18n/main.pas + /home/mse/packs/standard/git/mseide-msegui/tools/i18n/project.pas +relpaths=2 + main.pas + project.pas +ismoduletexts=2 + 0 + 0 +modules=2 + /D:/mse/packs/standard/git/mseide-msegui/tools/i18n/main.mfm + /D:/mse/packs/standard/git/mseide-msegui/tools/i18n/project.mfm +moduleoptions=2 + 0 + 0 +visiblemodules=2 + -1 + -1 +nomenumodules=2 + 0 + 0 +[sourcefo.tabwidget] +tabsize=118 +firsttab=0 +index=0 +[layout] +windowlayout=589 + [mainfo.openform] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/tools/i18n/project.mfm + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + filehistory=1 + /home/mse/packs/standard/git/mseide-msegui/tools/i18n/project.mfm + filefilterindex=0 + filefilter=*.mfm + [mainfo.projectfiledia] + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + [mainfo.openfile] + filenames=0 + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + filehistory=1 + /home/mse/packs/standard/git/mseide-msegui/tools/i18n/main.pas + filefilterindex=0 + filefilter="*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + [mainfo.basedock] + splitdir=2 + useroptions=268582016 + [mainfo] + splitdir=0 + useroptions=838860923 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=8 + y=30 + cx=323 + cy=64 + rcx=0 + rcy=0 + wsize=0 + active=1 + visible=1 + [targetconsolefo] + splitdir=0 + useroptions=805322857 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=209 + y=385 + cx=368 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [threadsfo] + splitdir=0 + useroptions=805322857 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=37 + y=270 + cx=349 + cy=276 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo] + splitdir=0 + useroptions=805322875 + stackedunder=cpuc86_64fo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=100 + y=100 + cx=453 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo.add] + value=0 + [memoryfo.memon] + value=0 + [memoryfo.bitwidth] + value=0 + [memoryfo.cnt] + value=0 + [disassfo] + splitdir=0 + useroptions=805322859 + stackedunder=breakpointsfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=162 + y=502 + cx=564 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [findinfilefo] + splitdir=0 + useroptions=268451947 + stackedunder=disassfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=548 + y=115 + cx=369 + cy=198 + rcx=0 + rcy=0 + [projecttreefo] + splitdir=0 + useroptions=805322859 + stackedunder=memoryfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=263 + y=431 + cx=286 + cy=201 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [projecttreefo.grid] + propcolwidthref=135 + width0=141 + sortdescend0=0 + width1=129 + sortdescend1=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=16 + [stackfo] + splitdir=0 + useroptions=805331049 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=295 + rcx=0 + rcy=0 + [watchpointsfo] + splitdir=0 + useroptions=805322857 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=120 + y=368 + cx=483 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [watchpointsfo.grid] + propcolwidthref=332 + sortdescend0=0 + values1=0 + values1_ci=-1 + width1=33 + sortdescend1=0 + values2=0 + width2=149 + sortdescend2=0 + width4=34 + sortdescend4=0 + values5=0 + values5_ci=-1 + width5=38 + sortdescend5=0 + values6=0 + width6=172 + sortdescend6=0 + [breakpointsfo] + splitdir=0 + useroptions=268451947 + stackedunder=projecttreefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=107 + y=404 + cx=636 + cy=128 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [breakpointsfo.bkptson] + value=1 + [objectinspectorfo] + splitdir=0 + useroptions=805322859 + stackedunder=mainfo.panel2 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=724 + y=157 + cx=296 + cy=566 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [objectinspectorfo.grid] + propcolwidthref=286 + width0=105 + sortdescend0=0 + width1=175 + sortdescend1=0 + [symbolfo] + splitdir=0 + useroptions=805322875 + stackedunder=findinfilefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=142 + y=257 + cx=361 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [symbolfo.grid] + propcolwidthref=222 + values0=18 + + + + + + + + + + + + + + + + + + + width0=111 + sortdescend0=0 + width1=135 + sortdescend1=0 + [symbolfo.symbol] + [watchfo] + splitdir=0 + useroptions=805331049 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=298 + cx=313 + cy=236 + rcx=0 + rcy=0 + [watchfo.grid] + propcolwidthref=116 + values0=0 + values0_ci=-1 + sortdescend0=0 + values1=0 + width1=152 + sortdescend1=0 + values3=0 + values3_ci=-1 + sortdescend3=0 + values4=0 + values4_ci=-1 + width4=13 + sortdescend4=0 + [watchfo.watchon] + [watchfo.expression] + [watchfo.watcheson] + value=1 + [messagefo] + splitdir=0 + useroptions=805355627 + parent=mainfo.panel1.container + visible=0 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=510 + cx=675 + cy=95 + rcx=675 + rcy=605 + [componentstorefo] + splitdir=0 + useroptions=805331067 + stackedunder=symbolfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=305 + y=101 + cx=445 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentstorefo.grid] + propcolwidthref=435 + width0=111 + sortdescend0=0 + sortdescend1=0 + width2=112 + sortdescend2=0 + width3=185 + sortdescend3=0 + [componentstorefo.storefiledialog] + filenames=1 + /home/mse/proj/dist/mseguidist/test/msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/proj/dist/mseguidist/test/msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.groupfiledialog] + filenames=1 + /home/mse/proj/dist/mseguidist/test/msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/proj/dist/mseguidist/test/msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.compfiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentpalettefo] + splitdir=0 + useroptions=805331051 + stackedunder=objectinspectorfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=30 + cx=685 + cy=103 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [componentpalettefo.componentpages] + activetab=0 + [debuggerfo] + splitdir=0 + useroptions=268460139 + parent=mainfo.basedock + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=30 + rcx=0 + rcy=0 + [sourcefo] + splitdir=0 + useroptions=805322857 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=675 + cy=605 + rcx=0 + rcy=0 + [actionsmo.watchesonact] + checked=1 + [actionsmo.bluedotsonact] + checked=1 + [cpuc86_64fo] + irqoff=0 + splitdir=0 + useroptions=268451947 + stackedunder=watchpointsfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=183 + y=113 + cx=352 + cy=277 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [mainfo.panel1] + splitdir=2 + useroptions=838893035 + stackedunder=mainfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=8 + y=118 + cx=685 + cy=605 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel2] + splitdir=2 + useroptions=838893035 + stackedunder=_mse_projectfo_mse_ + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=189 + cx=323 + cy=534 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [_mse_mainfo_mse_] + splitdir=0 + useroptions=805322875 + stackedunder=mainfo.panel1 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=107 + y=283 + cx=634 + cy=390 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [_mse_projectfo_mse_] + splitdir=0 + useroptions=805322875 + stackedunder=_mse_mainfo_mse_ + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=149 + y=167 + cx=693 + cy=501 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 +[targetconsole] +finddtext= +findhistory=0 +findoptions=1 diff --git a/mseide-msegui/tools/i18n/msei18n.rc b/mseide-msegui/tools/i18n/msei18n.rc new file mode 100644 index 0000000..9e726a9 --- /dev/null +++ b/mseide-msegui/tools/i18n/msei18n.rc @@ -0,0 +1,24 @@ +MAINICON ICON "msei18n.ico" +1 VERSIONINFO +FILEVERSION 2,8,0,0 +PRODUCTVERSION 2,8,0,0 +FILEFLAGSMASK 0 +FILEOS 0x40000 +FILETYPE 1 +{ + BLOCK "StringFileInfo" + { + BLOCK "040904E4" + { + VALUE "CompanyName","" + VALUE "FileDescription","MSEi18n" + VALUE "FileVersion","2.8.0.0" + VALUE "InternalName","msei18n" + VALUE "LegalCopyright","2011 (c) Martin Schreiber" + VALUE "OriginalFilename","MSEi18n" + VALUE "ProductName","MSEi18n" + VALUE "ProductVersion","2.8.0" + } + } +} + diff --git a/mseide-msegui/tools/i18n/msei18n.res b/mseide-msegui/tools/i18n/msei18n.res new file mode 100644 index 0000000000000000000000000000000000000000..ad8a2e04cb918c5b7193e9977e4f3174a8b019ab GIT binary patch literal 17680 zcmeHv2V7NGm+zqjh$gYcazQ{uks`&41(hl`Y$%|yqheQ7G>W||cCkwo3s`7U1RIJ4 z0g>K&FCxW4SN^ls75q#l$>f{&WoF*Icl|BTJ?HMT_x`WG*FFb95QJ_-z-OYbzxt>f zxBM)9Q)l5jbpz1v0==2 zT^dHWRwPm;Qu&JbT#0j_rv{hzkkPk|5bgmyu>mlxz>$ptzBc* zY7pamZ_;YaJ7c-YZ;j<_s*L1jRT|07t2C6GUuh`2@E=6ybe(_acHExtL+dcHExtdu1k*k+{bE6PlWUPoEIGc<{$abLnS19*@i8^F01lI{a7rVS6OoR3|S?VYbL6_~3p6`V6r>RHYJsj%z;l95DF zUr{7q=ij*3tAy6@?G31hbT36m{1aFDQar^*w~C7sEmAw7bXIV z4P`d*xI8}3gMB5>>+j?N>siB?)*|-J%`&%P8)cg%c^_rn%^xJ~n>$b{gys74$qwlb zCp#3|9q&*z@nXA%5m(#6z_lGF{L&dK&nn{3$?otxs)?5e1|s=@0a6YQAsT?xgSyB# z(7PdJw`Nnqs(y$w9fnxVVPYP{YU7y zc7l#e7wBH-h=CrxFyyWd#(1f~(Nz-xM}{E5$qXrn%#nIzBvOx>Am!KyWVlQ~_L;HB zI%tNtwIlFkbYI+2=!%@d(gExzczm7*&xhy5^W%B)eE(It(2QM)eGdC|wsZ1rj$)aU zeMg$gR)&vh)%0|cDnb^j);(RQj>k)NaCL(=mL5{Ufb$*E>+FxvI@yUx1dWr#k6Sv> z_U{M1pgu5hSHZ?JI`G~*2rsq{LGR4=yXTV7FZf{g3j@JV70f-+1M3c}Vc$VbxbN+cuoIIJciI}sE;EpJc^1;I{)Dviok2?V&-WwZ8*2ojO3vSpj<2^q_Zh0CYVD zK>J#6^ggSA0cX0x;G7aho>##N=RR;dG8)gE#^KfBiHLKyLehnwkbGtml8+i8b>AQ) zI%-$N*s5j34^<0IZLRLj^Wyn6^T0xE3*-;}vv$D#lzpAp-buHb<<8h|`%Ug1=5MKz z6EH=!Hei|t0&VqicZC@Oml@;6s-f7wN)59dJHucP;oaX38vEKoYj1mKG9Qi+epemn zUF{<#or_vfKhcHsLIIlR6rts!gt1o!Veb(W`0pHvXFJRhzGo~V4^2YUfzgQFZ-T^w zCgd}RB56mT+LYy*Iq73H!m`_H-WKyftOs)QKl_8$y8oHD!11)eTy}VYnaqreW_xEH zW4Zeh_S=)Y=lV`ot@pF)1wR`N+$J9Q+YQ6D6+^LeYk$me)`h{DZqPhJvUmE7Uz6}_ z>?a-^>Ihwz-q8JpNgLW{)uB$;G!Az`FJ}>YT~LMo<$ka`HWV(Kh9hY0Fg$V?h9{23 zc)D%?!Zzw7dZ!`z2ooe77>1PHee2U#_s&hX)C^1iQIqxHq}U&jPvp43vGJeD57=g2 zkCxL6HJa#ZWLK9iNoeI|D+zdc#C!Pl}U{HCbEkB**Gd%$&p9=2~D z0ITDA7;;4$I_}!&eMJkJrwXi7)TTkI1#E^ut*{D6Fz@?Z4@tS=<{(J#!TK4v+uLHTn(6#JaTZ5uWC zSoehY6cr*>_*nJC?J3>iJy`{=KdEB#N>x}p55V9neW87$543Lffwp@e=v>oj|W zO1nBhVWTt@w@5+tXeX$j?+UH+3h3t|k8wvua9k;Zi{xSfq?771bCQ8;r2K= z1ljzEkVR?;chEzWqYk2e)~E`b(=+kesGdQbABg=S<%!L9(DOf9Gx55LV+ZHgg@!WQ zBg|#$()Z14y0dT~{0X!FfP&(8J3Ol}q{AL*_Z~Y!>n_8pqI%y2wAPo!RhxPuh zn7dsbOE-$J(O!h(vqiXKN%%*#!_}bzt_>34K19Hc;Q~BIN+ZCs4T9$@FMOvd*|@t|4uYQ(FNoJ(*%pEg|TzQ?$B z@SQ<98u8$c9pfkLcKU>$&WX;h?uY67dqMB464YE(pmm$%?r#8X;)539*YN5OwHtcq zenk^1E^6p@MipI22NZUF3$@MPz-*-??B+;e(~NI$aFGH|%@N_^G!d>%72*0M5pGTt z;f4jteuVTF{MQB(ABYF;#DiPJ1K+9b@PK#_vQ!bF%Q_*XAD;Xu%|BrOwbG&QSpJYFU*E779;e6g}Y`Y@Q37z3Tm;BGd0iSU%pyPu62w2b$ z$JS`W@>p+ZQcmCFq7u}vYoRyc*CP3Ac=kij>$>RfrUjL2g#WTSR4%GP`K&S&4t$G# zjTf*^}LR|JyBHQGoJ8Ubbyyd zJBkC!@SUazUmFqpiF{_NV9R<I%kp8Pf z`+^GjbVV%NrGTvt?ch910$$@Kac7(a0;jgYo#`U@SyP`=y5OdnEUp`pzaw%tlo0EI z2kFBt(hDZW|1}RhCM&_0WO8>|e*~}WjYrEA@pwr`L{5?a^vYBwn{hEd#`)WPfOMi0 z*XuZ5a@~e&7rcJ=G?q&DGXK8Ob7U*hPbu=d4zUDy-A3p1WJUpzrlb`M@)`PnX zl;A%}qRDr(P*GqYeUWi7KE}y-zm`AgM7L($w`IS_>ng5Y5awbJBMC5h8Vm3-6>xi$ z0N=4Bub+Oz1JbX%whB1BP90V!N1(sQc*1W;IzJped`zI}YXW_@{+M#IC!8qGKi?rj z+IFIyA|$T)28qigkhDk=@k=ETyF>~xOIjgfwgjHpNFaE!fS`#o2(ak_Z}NrzF@DmA zN!{T6Q*Q*!)qFuFBlKwBHOlYwt;Rf_?!K{2ItG1FL2$Bb)V}tguBYa zh;W+`W|D{hXaNCZ1dm;MIItL@X8I z3H5)Ebj^=)0B`aQEjsYE9*Av${eVSRc#Q4>&vBjMGqD41kCCkMA1A~x9>&G^7$@h% zEpdQs;RjylaLt+hKIhL|f6MGInd)sSG~8~%Jyt;AI05%25E1sVTvTB1Dm`gxZO4pYj0qH|!&Sj|Vr%CtSAp5v~(D zl7A$f8Px%|M#(nZ82?Qw<6&Hkk8v_y#?3mw@t`^9`E2`?H*pQp*IdZ)C0!@|L7;_z zyM+7xBms{I_kBwVxJ{9Os}<=5+3sVC-(jnMq+C=HaeI^yzwKM3?~*{SlLX0|>UHO& z@y6{3RNQKZ${XLK;-Y|Zmv4~a-31w5BBb9Un{X2$)wK%>4#=Tk2i;4&%ic}bHi;0s zT7oMds-?C_eiw-dvGFA?K6X6B%-~rjf?MZFmX7&x7C%4Bc%0VVMXu;UAHw?G; z!KnR%V6)!*3_MDm*#<-e&;5^35xSR1Si+%s+oOds^yFqb3@`0s9ceOj>y>yTi zqK~xL0mw<#LteTr@-wti8KZ*w5R!46A_|kbp)kHH3Zvyw$h-(8A91%ms$C`VmTaW* zoD9m(w@2wI;tTU&8~KBk9q`EJ8;U`c|BaTxt~m;@+S(V!R2LhzO&7y9X<@`x9T@HE zi;?>V!t$_D#p;W*A{iIq-^;mua|}>!#?N`5Dc6m7&6sH*^&r|%vi$L^ADSLblfaWX za(KR^J={tEb~}o&h+^2BJ@PoXLjfV%l#sYf1yN2t@z7ZV!RNXo?pjym`Sw83V_l@D z8zU#z5P5}$C@3*RVd)4I77s;zR1Y*nDB(Tv;&lqOP3evz;zQA^E~qBmsJ$hL>Z=mO z1JZ*t0!j}{pkR*-GRQZ^E+%^;`@2hed1bO3HZ51BoN72mI1k4#rvWh7Nwt@)S{S-n z3kExMV0v&!)yy;FqX_>k#>Y4rFXw?@<9}@=vpmjNDw6kHVi)N*MLJTg#ao&YbbsRhX{GphIc~!r18%GTU2_r zLd9iSRGc7xuwOvVW&tUy$=58Dz|(m@z-y5*cJ3O6sUEXn?mGu&H*H}2%QzUGFv76C z{V;TwE{u*Ee6l`0DnDgB`^pUQ%75LWetnfk^cohLW(6c$+vDZ{vocGRp$_ALgN; zc0LO07oeztsNNQpl{TPFOf(jcCZc2E2sEbZ5g(M%7}^mHPkumIbQcu9l1Dz-L+-;a zC~^B9Z;nW!aE}BsY0a3jr88cxk%#XZHS9cY4(kU?FfP;{W1p_TnBc`29kc)=y=TJY z>SUO?j)&ESu}$ITG9P1%rJ@UrWE_7Zf8|OOxlvT(s>#2)SB#ziOFKUYDM!a5ev>A) z9a4h%FG^TRHJqURYDn6vg)}EUq&rhB+I0vLJq(Z$Y=-i9OVkw1#``QwROi^BsCEqs zKmLrOPa9Cwv;oB*9Z*+12aQ#>Xl$@UV=aBJA%47_fW{)?L#!HVV!NRzT@6JEN+=*6 ztY7bxFW{}g5>-I!!5wTJXynP7hL|8XW#x5G!tHsxN}f`+O$NIN?N z*{%za>NFhNT{L0j*8_8I^u!HkO~f7SgY={N$U1L;^c%*A@Ew7;r(;l>HXAjit593I z0yTw;QC+eQWwm=yghME9azb^5BguOu8b5ADBk`p1qdgiM7oo9k78*ZHMPtEm)Fx}A zD8Dc9pce`gl#w4PkDMnW6neEonKR`RWC!Vv0%F$v0RQbI8+R*M5nju*otTWX%vp>Q7>N}Nc(`-pav&hJDcP7u*G>_8*wMdL@}3E4(t`9#!Z3`WuG5yXRj zVjdL4DhQk7~wo<&cm&CmlKVbinL74V@1*W8IgH^_E*kta3H65+f zcVl|`KG?&&Xx*P;AQ>NHAXMeK+9LPN3>wxAHi-93S*DSr zLQ|`FU{joDQpCLuiEbK+pRf(I=<_bnbV6#{lQX#J|r7>j5l>bqzl*3`0gfQ_aeGVbe8BK z`GNJM|I^W!XMw7+u_!4YiK5~mC{EWx)$<=I9!QGgK{@5hh36?(+}{O}4jtgWwky_O z9*bFFD={;E9cINj;HT&{uzs})lf##N8Xvm2G;OG4Sb>4ex!=qG|7`tNaB+53@r8M~ z<7tc4kF7D}*+3`-cSgti-=gC~Imkb657k#aF*0Q$9C8leY_1pXWcwl|=O*6eUPnWL zCt-d{*u$IY1ztBiAzkn!A4vG?=vaT5_;Hx*VjUWa?NIxA1{!lIHe?JzU9t}9Un-&I zSzEk+*ajaS%A=gt3x%|n$~;JQge_fhXPXvw{bGg%k@lFMya@}4<|jE~Zo<#_Dbl`b z+T%rky8a`#z&`MI*Z=8#gyLe?Wq9bh2pb;HfN`iP)WZitIh5+Sp-Slbyd#vtI$|*C z|J=+S*q-kL*SrUa$O}YSo-f|NzE8eChJ1eA1~`2-?{f2X0Nn zq8JA(ra3In*n!0v+c7)E5mOT!in)&QXX}5)Pqy&8^`FdslIiL0%Nox-Sd1AjY%u5* z)i)xBpj)^Wks9QmbcB3p8|cLi!KBRfSp6mt$7(a-{Vp4?3d522<|Xn!CK09SkESIW$g)UXjjqEUssLS^ND?{fFyee^md=y=qtC z<+lLyL#AR-?0Be#k^G-&Lg8U2bP4(vqQ~DuE2a;|z21zaHU8LJpNuQ@uMt?9iipxQ z#55Ekr!gA^_36m3PosPwnefJwAGnK#Qh&nygeZvU7SVaaPdY%cvEuz))aMwYHmyJE zGlrrjN*nJUbtn7^DELJIF{d=)c4Z>A2d&1Ad-mA&d>t0WuE$LBe>0vf!94#N6-)dk zM{(_g>zRL6|NFE0Z>g(oPTZ|UaC$HUqn?^U?Xfnx__s%A9~pG^CwlZ9)YAsT`1Nwk zet#JoYa?)~u@Ihb3lLJ8fv^wdh-#=pQe7D`>vB-gkcM|vFDWkECqHnPFozPcfAl3{ z9XLv~1#fB>p)SV^)u{uC2L`B)>W8X_YIyCbg!D^2aObKqw%uKdrOzDUd}{{W-6mjv z@IpA;o`QX+_2G1|PtK}eEJC=B&Gl?v-!`v%{$2gI*#>C8``_39-(0ed$-J?&G9X|v z)&@_3!J`4_7SIWuy=BqKkM`}t6`+!=i-CpHF}dn6R@B_b0h0Aq(t)6|Y`iSVMq+6` zGRkvM@+Ju%N+M8O@B}sa!Klj*M0s@x;eABJy5L51l5}7vs>|k}Hq#s*k_O^!m^vyS z^+0)G50qT*M$dxuK%mPo?D3fkhoF_Xe9;2IM+d{hWi;H*8NzFQNBFGzF5mvFg)i@8 zu;1r>4aV0J_Zain)EozXwg1C41KI<4obI(IE5>JaquX6OEPgx*2DGkKyRQP}r`;j{ zLJ`VwYS7IY1M@c%WaT!-)S=a?BD?jL}sR5J>mAvC2AlL{2C`9H6DM^fESt)=ewHTIV8 zyg$~m|HnMzePp&Dt_S4$Z77ZQUyBRDc9{Rd8fHmT(K~Vw6hl>@6xkh`q@#vKi!rxY^s@K8q9xsFKL{~f}&w8qWd>ezgJCT4|f#NyyJ*x|hh zXD`^`-cEf)Zs>v3EmL^kzJ~WPN%m727vpQe`g_M_9T4yTHtz#%<+>R^YgFaCC9%NI zu{!jw15U>}VnK#Ih9-_f_i#-phO0m|t}h1XOvmguM{)G+Bi#Q$zOSYjuS!x8Q<90a z*Ex7yUxN>y8c^3*gZk=n)RtsWe#Dea-y>+v;78a`qo!yF<bjB<*)nzKPSO!Lw;_8_e;nQ z*0LSM7)$3w&(>_p4nKw1m&f52zZYxL)==(eh2AmxP%oUC7gR=X zM&TVR#JZW_&IJS9Iz0$JdoA z7vlUs%tV;_TdaR{&iMfE5s2$z^c+q82$>`N9QK`e~J=)9tsd}GdCyifN;Mba;L9pQvr%59QdE%D-{8J_Id$FpsH@L>A@TsS%k%Wuqq z#r;+F;~qNXj(g;oOZ%LkV(kWes?JUn&$H#f)SWXwg^iNSr1M|N`p?dr?LhqeSCpwt zSj_xBAH~mMH+Slmau8QioNy|A5A4(JVV*h_`iY}4D$WWkW9)G{?g(xtTt*1Ry0G$i zysFGVN6<6HuCd2c>bBkP&_q2~Tz)$!#`L zFIXd*?E1;6DY)-!iJ&8saO=1w4qu*8yVTDvXYzyPVdST8XB$Z0h%}ci;{D##ZPray zu}{UbC8$JofR z7#D4YpJJ9^dE8cP&A5QWZyw-$MFg%_CBx@k9`1c8K}1y{GO{9&7k39KY0nW|Q9yZO zHDap@kdpBPnc)`@9lR4y104`~aXO;TTH)Ts*|_Y!7#G}^;=0Rx1RS4M<#}p)2Iu!2 zqiBCe{QO_Jk?f*mQ>nu*N6V%1GY>Jgx(%tjW`XKHH7|{XZ)x^_SqIn`#G6W4b3gU3 z3;qF|zSWiFA@AaLL{9F~#B1y2(Q}*ZU(q@-axvD?T5L;{BlhK7#DOAj94omGmy$4C zFO5M^A??R!JVip78xkXKA}sYWg5PA~@yBX}kPd`rM3n$zo&8I}^+O0Vm!bG7R}(j!)=2u2aT)z2vwjI(Q~AsDHMsozXZVEfL`c$Q zJWRQcfOKE@WCi1P-U~d)4#BhV%LomIBoVKoJdu5OFG_sZ zqu6^j60a|X&-Fz(c4Ha#Tv}MU|J=MR&PV<$p8sVYkl%Qob$k_lC7BoJh~L2=UHVAR z75SA8l{vuq0qY;{}z9))fTk$ZLu()&y1a{oLIkH_P3J)7eb z_#CxM3$?`DtW%S&5srL{taIDVxM zmWt&5c^n>($K~;P9vr85PxtS5{y%J#>MN>FL!JL+|Ho~gjTWSzn+Rs)JKMM1%lQH4NSr4!?>WEbeKnpJ zuQkJ|#{T+&`xhLa>T0O&JfP{NnQTqgK&h8(zeNA;{hw$f>5}lV-!<`j9$$Y*2S244 zN_mNK(>Od{v&{d?-~Vah0mlaBIp@{9wxIcl-~W1JEVq#LrSj$dFA&mp&E)-;hU}qI z-sG?U@cplXq0(2POk{F7o@6-Lq2W!DxQ|F{rN#skDL2ABg~#FXcw8Qz=g~5!|BfTC zDR^B)^AW%Q_m=d5u+|iLpBB$u{Old&ju}SME^M=`zeIoh{@*ZJ#}p%}>$Dg1E^JJz zPnpM7aO`eMGLhQB>vtZ9$NMX5ng2?D@O)SvWEU#*-kt~fjZZHpc5Gx_h&PdPVL$cH zy#GmiauZ{XrCcJ%v`(PsaAPY+%c*n!|I={)mdB)z66F(GwTU#5+!19Wxhu(3dJg+$ z)>(e;;(zP=zrW=}%Q?%7_gKWbL3?eaAOEZ0|8Bwkf5Y*&e-GgQpZ~wbfgcI39ue?^ zU?CU@qlNKACc*?dwtT++yAu4@BqRhw!_R+Jg8vGIgkUNuH2WM#p8{n@BDcvUD?F_$qCdUeOiv<6Y+o2^y{xbCE^Q~ z!dhXquvl0j*a;))xJ+0;J+BZJ3M;AkGjSU|p+6xVOw^y|z%%Mjy-5((mBMmil`xmu zZy?lj>1@H5K?cz*B);@%O24cTY{g@(qA?fKy(`3REeMkto%az2iLdDW>OL#FZ#CWd zkM?~99crmVvteQx@Hjl@wc@rbXdcVHn$2>$d%;)z+X(X1ejHu16Srg(t7!hr1v_C8 z^&$v;sna_JvD5`=#Pae1c~ literal 0 HcmV?d00001 diff --git a/mseide-msegui/tools/i18n/msei18n.svg b/mseide-msegui/tools/i18n/msei18n.svg new file mode 100644 index 0000000..ab04050 --- /dev/null +++ b/mseide-msegui/tools/i18n/msei18n.svg @@ -0,0 +1,342 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mseide-msegui/tools/i18n/msei18n_24.png b/mseide-msegui/tools/i18n/msei18n_24.png new file mode 100644 index 0000000000000000000000000000000000000000..b356f02446fc1325bb960e8bc7b0c99366a5107b GIT binary patch literal 1878 zcmV-c2dVgpP)HAc+tmKtdA8#SPg_ z_I}Rk2WBWJ;`{CS@cjSpJHL6}|0AfX%A<}@C`1^mF2%`GACsyP^ZYe(4;cuPh%`oe)6<_?urV%@wDQ`8MXEd~2!Mh=Li$2Gpx^H4-&`K~2Y21-BkEDy z57UwEFA~=$50^xpsqJ*_x7s9ccGwckh>v#kKQ!Zy@niNbSzOsu-~thgTCU0K(-b{B zbA@i=&8io)Nq4lm>Bg$S!HDYb8ffk>Y-Zc6-;Y{xIQy9e{}NJ8%nSAIda+ej5_FP| zU6YsTlTCZM#HNo>9G)qP)$Z2y=?8eFd*e=Wh3D1EWu zedn67t>cD9Z+2b}7&&<9D1+k%vUKnOQiV@gkux8F%GNs6XlsgW_e_@Uo(YQ8Jw9^j zwmCWPk3K$VOV*4B40O|jnLXauOgqkh8qjLAtRA&UI5+RFEKalVZpALbN|^bXQ;E^E z5pRsUd!cR@BO-Q^EFFkY!t&@9OCE;h4hO~MNt(d75^r9_R7i*dR8cRs&#;$WQ!FHKrdK)Fvw%%h{P`Zv2p64PIQ-ULG z2&DoQl6e9Nf>X9*2sscHYJ73LbM`|#s>FNOE+UCCb4I4pE!R-inZPGCK1v77AuPsm z$Kqz&`TZ=;n#IhVlNwSf3=ljgO#{AElsD2;C2o4&Y|oj509G~`B~WvI$Am~iAEf~9K`5!$l*|^ zy1B8Tp-K0Kq-q3xl6}+kL(_Ix2E`Bj-Xt~${d}3b8;j&6^X3S8yzO8g%&kxj3Igqc zFjG^9v3B(GyS(HehrantYVEoe)ewwTg@~5|nQH3AmlOJY^oybK!Cq^goXZG%HUQhs z7x8vOCFdp=5h(_k+?Y>}u@Qr!vax;y=^bAa3dP{+ueuY1}Rv zV)jXbqWTFZceVt7dAqr%%X#YfF$NiS5e~H@h@kIoCgaRfQo`2=YlFN#vJ8OFFX;Jr z;vV#po{Md@EGpf=Y56%qLOKGbJ6c)e7Zla6(Ry@ULO^n90-_5wg06^XxD-w$+d7c4 zyj{eYtmMmDcBa2dQiq0_SLTshkx!dTgI3f6FeD*^lRw`Gtb4kEkP_mCOmBWQ%+@z$z^hsJCfVyY z)=53J*C!>GS++gDf$FvzHdO3IL}FNC762vJ%lZ6f6@vwV%G+8bjl{l5>zMe@rR?`i zfp!nV`LAEg?$(#1N|ax(4v5n2yW-8J1yoCcdPkG;9x}U1HY-fetS`M`3G~a zUs=7Q+x62EeYH(WZpsskFJ8i`S{1))Tq(wE<_`Or+(O%G= Q>Hq)$07*qoM6N<$f{~(-y8r+H literal 0 HcmV?d00001 diff --git a/mseide-msegui/tools/i18n/msei18n_32.png b/mseide-msegui/tools/i18n/msei18n_32.png new file mode 100644 index 0000000000000000000000000000000000000000..9a3d32c5f175db6c738fcf3f83140696571735fb GIT binary patch literal 2946 zcmV-|3w`v7P)Ke%0EkjF&8O#P4WG6|Q3FG7RlUB3MDGN$Z~$Q1hOm{GNG8Hk_TToxlqzE< zHtc;680A|VKZ&fy<6YGJWTEM4?U?D;r){3PHg)X!`LEv!{OJJVe!eXml6_3;l=0T1 z3kFT|tvR--=JuV)e638m5m(hJdn@Jx1Eem`9hm0u{Pga{xyv=j&vVSQXcyrzzlS$j zpgB_2uKq5(`q-TGUmjUi)+o>iABdof#czyX9+I#Lo6j z&?>{bX?P$2x1^4o-~YL}yM5)8uhyNrR3Bb^9j~Xr^2R%dlBNbQtIu??r~06_v#CN$ zIC|45_9pvh{5w9UkK3Ud5^}!V%!-Vl)tPInc82Xp_}r5mXQMk@xBedy~0nYxKz~Als7#z{SQ& zn&nPzGc!6u(vn#?lc~0%xlJJ)?nyCXebapDF8{#BMR(Q#NZ)Mkn?R-#T;Vx-^Kwj2 z>O4{OeQ{>qZpWsvqr_0>N(^DMNQZU-QqL{4_lyPH0v=iSKYnvLf^XuBTc ziyr6mncG<0dm!f;FL9#wO91kGd8i^r&y3cVXJr z*}>ZCQOnz%0a1#k<|hm9o%TeL<)iCOX%XYL&Ex3IEu_2rZ4krqdh=m(j6v(m=#ySV zU20#RC=R1)AF=TGAsRgWX$_vl8@$fH4EY)J`p!Tg0GPY$CF9i9A)gv|Ux4aZadp{ zn>n^Ck!QQi{M6)8_Dz46pdMuW_PO+a?{E0y*rlxgas%^6Sj@^l1VEGJp-RtgYm!7l zH3NUq{6b?TuN{4#CigP8>`LSbw=+k$?QEc05v6Eqp^=W$%CJ={6Umh891|Gx{%q1T zFG6*_T*xYaGFxCVsf%Id=VUEdoJM z4>I|~7pQgr3QSA3RV!0Ctqe;u(nYCDQ@k#G2?r^*!%VfE;SN%wf-LDc27=aPoLqMY z`gsBr&X{Jo_7rx?Svx5=H8pK=w^Al|dxg$v zo%r)Ov-KkJG?QGlnU+X52-VzskO<>9u27&h12CYY$-iFf&b8{#nABx73;X?qo|!$q zF5|ovy4`8|_Bnrd)cWL{Vp~G-W^Nw+XhBiR8)KJB-#qc(jBp~%^;k2<`mV;WMCswF z<;mXT;OZBU(*yjS2$>o_InK#YKB;%Nuz%*qbnzFp)rc4o{^Qaf{_WJZ=K-6u5s-X zuCi#yWLE5PD=+rAl@)&6R;$vp%@6pVE6Q_yCX?sMV&Q>*B7y|6gPsGrGOOb`wzZUC zO0czH0|51gk3rjpu%_QkrWBXa6l-SAo<$sP5i~i+fSm(o8X}@LN%g+{Qmt#hQt#TY z$O)Hj+C~gRL@`AKxgfnx`x$j|3txVD7;k(dd9un!WowwdcM%6KhNwL4#$}vA%FTg- z`&TWNOKKv-l;Sb~(p`RbOnH}GU+v|^@)cZnJcA`VfGHvvA}VYpCMR6F)EXl!3_`+? zTSP($VhOM$z=PMQ;pw75oSLXw__ZmD5IpQ&7YYCD(b97b&nGxFR*=3JP-l%r2z z84>hkdl59T>l2)Qb~}?&kC3KsMkJJ=Fyt0t5NeGPmh5tLNq01nkQzl?YQU0BY>5ux zZM@K}C(B2_f-Gcy`PpxHB&#P=iznfAdI4BE^hGMKv~cY6Tg-Dhh}bgy*G-@%T-y%9 z=k)Qxl;1PI*iWkcwwHv|DCv$SyBu8tu%n_*MCH3u%vmd9a!pF?V}4xd=G75D2Vm!w z-8Ab7-Wau{U13djfMMX%GWcETYkV|u6>%E|uAj=jYoB6RM!WZyje3b^O1yb~|0})h zsHlVcKO;S?-BDA_+jgsY)0eV4I=2(F zQ@N1nPpkWN5Eimfk%YwA`U^y@YywgVD=OY$$*_A{<&kBifL19&&WmzTJ5SJcS_&#> z|6HE86Quyr9j;q)KshM_+83hHQxR+&dg%Gx?=@Ehep=fqCYu-zFr0)aNvhF?&; zi2^H{$g@=|({?7)>co`PQJeq4+rU$CA+lnaB2sUBU)p$Xd*19mGbG)J#H0q#VL9Ti zQUd?CG5J<+__Z~|mn^j0@rP`;nS;~HupMS94%>||?|DO8HZVj~B=y!uisnCka^AkQ zlD9_Q{A%z1vESL6eKYPQs+UEndPDQcxx#H{Tbhw>J4mrb()AbS)bNHHQahN%Yx+!& sCd`%kPWAG))&Hw2@V_SfKil*F29X)#Ucf)P-T(jq07*qoM6N<$f|m`}%m4rY literal 0 HcmV?d00001 diff --git a/mseide-msegui/tools/i18n/msei18n_48.png b/mseide-msegui/tools/i18n/msei18n_48.png new file mode 100644 index 0000000000000000000000000000000000000000..8163514f59c07da308343c3d39a345223f293717 GIT binary patch literal 5486 zcmV-!6_M(RP)r{v9PzTzo=vAx5h@zsX6|16%N+5%TFoY=+N#6OK_nfouhhQ`U zc6{#h-2FV~%O2MH|IZ%Q+G}kgrR3jL#5`2`@J4hD$3>Gm3V_JsstR^r7K;cO`2xn75QFDC1V z|DO{O^H2jO`B~MxjN~g>z|pKf0#h9mZGd`6(~Nd!1X%06kmAyF%#s;FVA~U zKk$iJ*7}{*pE}mUMugOqJu~1+T%@pZFi{r`^@kQ6J+Y|5QxwYAUSGHUb$7$Ed)&0q zsXInzqK@`|1dsN;><~iI&rsA7@?Z`Xf$R`GPNCy>3#8`cNmVO7a9FjjDH?TWJZDUJ zGvdW^?~15AsICvO*`CtrCWl@0eDe zw^omucy|1~OKZOb#4W)gA#dIXVG6dUIuHGo-}6k|@j62tzg;XnPLcFkMR;YN)Q3m5 z^|iZzQW74{;<=A1XTE&(_+)gkg9s{nq`9Qub0V2P7%R_PE~@e?0oWODmnn)pN+>-} zXhyp<-5f=eVSmO625bG>{+`)T_TOX&eVTX3t+Q@AJXrYA>&nE#9(D`gIz)!eF(Q(w zBy3j7P-eXJ4JmAkw~Mbwoj7I==S(;G2Xtsi8E3i=urf>JWGrw*CJV0ajX7H5f z5;iMEBvUEF<`|;p7&~lNxc>Ag|HpB~S z3|ADp;cTTFvc}4gHP#MhE8LJd$_|>NrQa#{pOh*6rwI6#rG|Lrh)Qu7R~MvI_T?gZ^J8MMp%C#OrqEym>Nodr(>@5sIG zZxRUBQiP9^Soi5G@A>G#?AP`A{yZKy{tmJ6s(OA}J(6h8WrTXKMe$AH)(`F+B%?g1 zjK@y6mr(az{SUp< z$GnqS!$2LR5kIg16;F2xc7&RcrLK)vNyAXK`NyQphk%KFX*vTpy1 zT(z?vl@vG3SirQQQ`nX40NF*j_cAKPv%G)KQsvI0Z&f^M|7!W;my6|#4X?({um0=a zZ|feg#9|(*VOv#1(p7FaTPY%$N;hPUb;9OYXbcAW7Vy?tFEV}jLHi^Tx8fAtGZMvH z#0>{tzzs95;pOI6IQOmFvGrVZnT5=D(&-({C_S82+dsh#P9+bAXlGc9Az?Dz8lX4FS~zpw!nz>%qm``k{)i z?OraPd;tp&eTf`z&R##obWDzW_B2wQ(IM1RQ&MyCT(6Srrmb8sz9ArL3Hf|Z#MYb~ zyiP89Hcxt-TtrM0y?61aGnY^lDCCDPp36=v$e~ZprtY-GROXKb;I5DVo3c?8_~iJP z29#emJdY`#-OM354Fll6E+-YO=I&G}_aA#F=O1v+K9?lGC9nO2t!5Fn{}M;ZX7liB zxiX{VXoeFJwS;6HaRtEVro*n`Mih@5k-8nlaHG<2a!?F(HN=oW5!Hng`23>x8SYcq z87%WcH1I4?B5#OVik1}QJ~b~Cr=6FyFkpfOcEsO_bWsW^(tSG!yG3;yZ) zXL;$X_eh1WM;cBJh8vZ-9aTJT#5LTA&rOG6&ne_8N>J){P^xYS-3duuhEZKVii#DQ z$3?F#;7<)Nao?(kupI{y^(4!$@kA?blU+wOpc`8@o>oc>$rCF z4_TWW#`B#Aa!1>2QYCYF;Il=%x$&*Nz&CU@a{24mk;uChR3E6WU+OZ9?u4Z3hNNx> zT}2532u_o#-%ZtIbF69+wI(>xOpP1KOptza7@7l0488YJe0B?I>7WaNMuM!>i>CPy zdW6`BQ_%88v1I&%92;HF>SQVBZ9J0=AHEFj^$;n6(wQ*qaPpNjr{;c6xu=WQHs|sA zM@w0G&KuMeRU?tS)VPEz-}pJ5p&#RFm0(+7D+trmp(MwCsrE#_kiEt_y~n6eDgLz@ zeRyS#@SsYsquPFy4LM{#jd~Idc%3Fv>95ES6f>@{ifKb8FrlD|aRpTj4-Y41#`tu{ zYA$`_r}Wu#IZ?ZegTfp6G*yDz@ddPh+5b!Xw!pe)AX>(G6;0e$QU}0Q!vym2T-c(sU*VJePC z=*_wQ$ig`&>q=)7&lE?DIFM<@KW0ktB*LEXKG$i1KcBMbNG^Z#T8NZ!aA+gClI^#q zR?pzh(t)04Dt)^KsuUqPdu%65x1G%c%_|9I(*zZlD<>Vv+_CpEzF^$9B?!y0Sl6*W zeDnLaAMvhdR!u;8bh75SXedH63VwCM@fAg-i%$Bp5;8*j-CW--?`(b#R}b^l0k3g- z-f95u>pYyF$E!dnAosWtiUvcf$k7IG+^%eZVEbzvR#d@)X$v`~{3sN$ZztJM4MyjV z;-H~ZwdF0#bChJRsz@D03KX=BqkA$jnXr<7H+X>Gf4P{v;UfpY16*D3J`;!QFy$l| zHV#TB!O_2fKpyYLD+c;CrHZ*{%W>euIKSo$jvIB%e!(|%HuB@8SGvXbj&|-^S=Zoh zd*njJJj51(lVp({PS%jyIY}+NdA`uz7=LQjDau8Y&Spl*^zQ|~JH4Ax4^L#`%oABY z^_f9!5AHsMpLHFFKr+L#jnQfks}mzxmn@;$Xs6Ka;FHD>=HlU@FJJK{xg!1F{q`7(=_V|ij8kP(aUzs zr8%3=qs2?8F#0b$8CR#W{+IMLeuTR9U4B%3CdZDPMSW)jk9_uf5?Vf*>wptSQT({t z2x7`a(5HYHZL2-rFX{8tYrVcNMX#q`+Z|XdB6DPp8BWy5h*@ptniC0Us+}CO8YAn+ zS&J|IIwV$5Sy0IZHK#MaU>w)Hb2Cl7+fm3e#GlKq_;v!5=W}J%W^(idE0SYa(l?fy zidS$$;fg`Tuh}w}$DdzD(?HddEm+*P|W3FGl3{v-y z^_JjsGdx}UJ7$hJj4_W)W>$zXfdm{Sg`=kXF^Yc7 z5i&wbiMQ4qEAulG2%FVTG&4a)vJ>1;W-OWw>YmSTAh7dB?mp^9E}e1_0Nv@`jC^oB zNS7T~xA5)bH)h5ddjA-b2VGBLK+?B$J$7<8YNm@LLj^3I_Z*t?y>T^GZv88#|M^08 zD>KQ;Ynnx`u}FuhNGl#1xN)_YYFc7 zCC|@&YydpK<7rB7tFUM!_o zSZYr{_>Ty6-^{CLJja}h*@F~3_}L<|nVl>+@bY~EIKKQy{Hb=xW;nKN7Prj0kx$Nl zmt0}jnfm)9xb1_xXzFUlbj*Fq@o7Gmo%NzxQyeMKiq1L4vDCh= zW2Xam;$SUBPB1afiDs+ZPA&sG^)-KX!2Vrjk!@?zuijJT% zcO>OGBPk9Ip(s#D*0q`S7a`Kl!2idJbJ=?jLRR*!c}#| zOBRCzyRB|^XFI5G??7qWVFjGm61r@6kh>LI_89@CsG&EwVjEn_AOi9QoM5fd>6liY z>%0C3WjQkEo?~wt2n}?mx_G;F1+TWe&7YfJLDLGk@z9^{6a4+F9^&mSpAc4I)kUkQ zer!61r;s%}KWEy|se}5?89keYD<1$??LRP-VW5?QP+e^Arc_ejAmT=|hRcO*Oc^#^zH_!mzhgvQdd>L`trFt%VEpT}L6wJhI@KzU9XX>%7ivY*7BPo(rV zky5si*0-w}Z6_&hr%dX*z8iAi>mWAq?4Y;iftTxBj!c>B_7ly3ulWPJ)4K=htI8{f%yv^rcsD2sy@iC)DiZo8nKU-5No@;h+V+>N*>8Rz z^|G%`B(zOxLfa%0Myp5~EhM}xq&%BD6FcNF&&-tz|N5j%<~)VtI|Ce}-)porObTi0 zZU*49oondIq(Gkp48ipu#a$mgFi6+9f>9Wmt-T_yZy@1q5lN#(CX7}!p=}ZgZBy!H zU)%n0eou-CQm=Toij>-_B|I%k+_Ou}JzYfnvE#YYq zDYZ5Aig)YxVf=n?YR^mrYq5kQO~(>R;aB61`RhLEvx?%r7)gAvo^w^_j+625Ci_!F@ k^7>f!Kc)Zw`*WNB1-3G)BL*E$ZvX%Q07*qoM6N<$f_PHTdjJ3c literal 0 HcmV?d00001 diff --git a/mseide-msegui/tools/i18n/msei18n_64.png b/mseide-msegui/tools/i18n/msei18n_64.png new file mode 100644 index 0000000000000000000000000000000000000000..0bee5d14f61a4de36008e76a3142b37434d5d94c GIT binary patch literal 8537 zcmV-fA*SAmP)wx_ABVDf|09=lsq-`|K@@G5l|c5D2E?(20YERTx2<00AHzOoxX?p(r5W83JSY zUr|i_rw986&1**@)IMVl3exacmvhNF-Jd0VoU_9ZEYy69{DjDYa*1V_qst zmP5#x8R-9rp5HYA;!u)_ILRQdEBY|( zcZPgq*<;3ZoqCs3KkF4MP+dw{?Xj+CN84OF|0nv}|87MwjaV$3EmlQVv2-X39bKsH zpg_7RUq`%RrL)n|C8Gei@u2JYxbah7Sas_OO7FBt$en$Jkq9As2rwEWG+Km4Q6xnMAI$}lPg0tqc|ImH6>CoY|OCc)bCK*)W zt4tTz*1DxWyzF%BDcNUwV9J2v$Eh*lI4^D9*{tTM5%Ld3%g z5m!T1EF3B#LAgm}%3~jA%ftkn@00+LwcTDf-yeS-A78x0+HGJ(l^F2jnL)`_Cz(XH zl6X)-%&Ra7RjK1)rH*@5${J{I?5gY2(*8sD<+=l}#_9Ym=z5R}WELm&AeT-2F;m8z z(x=X6%_|T>ViKbUn1re%=2Z|6Donz!P>GlIy z-%Eb_=K8lofa;>*EWYp^dCMU;T2|zlgJkT$Y1+Phf{tz+rsH0viTQ(YR8&QGXI|~X ze%rj^plcafG#sb>_MXwtybP+7EB3pr-|{P3KF4u}V&Y<;j(e3lt}0ACsMPUbs7VAv zP0TAd5nZMeVVR1BLr9n*v0QHOx0wk$BtYDPj8$a^iLUSc^NZFm>!e9|m*b}6J@L}r(A z#PGu?&nxR!kI$MvCv=8^)ZnO?i3Q~*9t_p7u$*XEPE3`Vcu*!{L79n#LzEj1CTa%9 zs;qwI9cSjeGns&nI$s?qY zSBQH>>{}5~IGLg#;SW#|GeEoX67BD@>bHyU*Zmn^j&wL}*QqSNU;#^i@IGgbIT)+; zZbEkqk1e0g3#(r0w~uMNOd(V$0zuTagMl2Hb zN~IH&sz^A%M9e@FUh~Py*6CxPSuuxcyG+?0Z;T(j2ag>807ni#l(V0|023L;1utE~ zilO^3C^4{CS-I5?LNhQipx^e^w5=u39)z{HbyEoZhOME+Bx8>b z-KlhE{&Lc@V)sE~x3%-vPoC1QbZc`z$$7nW=&#dQHd`!hU7}r8DkHj-NH{>ad$~d$ z-g5o?TTQ6L?Gmt6rtfwdPn2IVf2)N+Ii~E$>N&xhXbbs<$^9m3Gr~3ttuil5Z z&zsNv$Nd4&VA{9LiW=L_oHNuik5t}t&@be&AG{~O3Vz{+Ma)_Gob*EPnm#&w{Xy}O z6sVY0tfN7RiRcm&QKcdhmg0t`I(m7kwsWJne*R70NC5Oq@jH+B73eIlt$m#bmp#<$ z|F42>Of}Jv+RVnTP2|Gdw&$NVeTM4}APl;>~$Ct0uenWS4osA9rr7B!mBi~uxHPW z2bCrs3^nSdBH4ZuFPuJy$)k?_MiM;bQT_W}X;4ujejRU}`#KZL_6FdY6>~U!&e@o+ z8E(mFA?NLW2IuX5HfKJ60jvEybk_&Wm~;cH+E(+_XU|}ghheKWO!gygoOB)69r*KJ zzyUhFPA1GcP;cz$s$<=Y7mALZR^^_JZusgcvKIkGCsP0x19R}%NDOd_c4vGBYK z9aj}57L+3uvU4U$e*w!cTFmgmVc$r?9gFT_#-e-C@e$)(Yh}uP+(kLU?RE* zJ1jIVMaB(_d$u5hF20;>(<&y-K8i)>&7-oQV!Pm1wyfeei~op;mJyD;oYb1TIpWVp zQ&m)rFoqyn!GPj8w~u_1Gl#r`6b6If=GD`n{Tx4z@w)YXn$^)Yr95F09e;yV2L;EPPw!Mal4^N`oE@Aw{DI7j% z9YPphs~gC&FTOzL8c|iJ@x;WJICbEMed-^(_`@#H@6Q7_q_jGQpRHT zX?dJF%#L#Fe`x-%(@wD$`h;F{_enE&x8@^m}%e(*kf3?8>b-~g-J)^Pfq zb0Kzu!aCnW>wM*yJmHWpU6W_IDw&9rgdPGU^q9P%>m`h(lSYOKY3Zc2RUVGYGj^Dd zrK9LZ@*)MyKl>kCf8Z}z{QU)-KW;iYY@sfjV~;=W$6M>awEfdTn%N&e!A>Jbaq5sy z`Y1ZHdJct=Zn8T#kvI4SK*)f^pl<~}8)iBA>FM~g0$q5GW$Z8?N99Rd<;gABjHQ#I z>m|f3J=lA;!3D&PBjU!l5k=1Q$zL9`SU%i|!+SU`4%mm@U77W_aN$rLSX_GLHjvGhBSwI}NEP-T4ErXgs=luzgO_kYLT z@BIcL1fpPfYIJqK%C7f{*$@_irFfv}K;B7Jb3^&xIjQ6$1cuAkPUr2eQ807_LHiO; zcxoz3E_{cCljyg-N0Mu9IQ4PI$vjJQ#x1J;&DY3*4q_3H-(7HEmcI1Mr#StnC= zjmWs`Ov+trrK0OZ&eUY)#5UPNAR;Hp2r`TyO%!moMHHzcSSH#7)Id-N;W~oEB!vA5 zcGyA~G!tfOuyY%zDjZIcTSP~$leSz79qr37I)$k|neVSTmsfWA9V4Sn%c||2G_i zjO56-rt$uwC)lriZ!)3J$BoO;7))dYPS`{cbTA}2l=A#Cgpf#Kp-jlC=9Q+~?-T-w zEe6%;rXSuZ>o1$@OSi_R6NdsEV}vbaXH-RRpWw)s_Ay?kQ&lvA{mUn?cli|dE}Ovk z!Q+V8vA#-wO$36;qmJdW*RKI54#JSIb3Ndt0-fz2Jiw+!R8^Gp0uNvb&56|=ENZ=u zMGb$4(8F;DpmGiDlyLa|9zW;Ukw>%3fPRnFVtwZZmT&%ud*1)u;6>bWZ;*Wcc9y<- zhmD10>(CBuZHI+d9O<}k9&p({mx`AC~27BddM;oko~{UaxbjI>*8GUiM;!nw=Ju{MXbg-zlss!wziqzSyfgOtM>%Kg>D+tN-Q-8| zzqLLoKgH~i|H3`*|6XnASZ_>v|5pklNZSMmq6icFphOtQ|IOk*IMqef^6cHu__x6? zZCFNa+gc`19J>wtR!K;ot4rVFg0Uwsf<>un4oKDj5E_e{ zYft96*8Q>L^H|>aDcyeRTM@9jZ4LK*_yDv1IotRu(8?RXM0Q;Nc%=EH_e_8g1;?49 zATKi_j0e>^zkZA^yml(q>$~ngXbwZs z;o1YP;;gY}^fJLWc5UMA^$U4>!$RIzw~%%1t8tx*&{xN=leu%>7hOX?mnnO#opEZM z?)X|!c#?Z5mf7BIKt$6BTW45-LaqCMXI-x!h{?<@)*wF<1CIHb#$+{{nsVs zr}+82>v>?wpD>ljvfH?QS+YkTM=ZXv8NT`&QpV=={ExY`=zVsNZU&$wOmO5EKW0U` z3|ecj*3Ct?E+^sUvHPIiSk>|cZJ8FV=nzDhLWL=+ibjwLGo-w3GJZEwI!Jd6p)(%i z?t=&qsFf*qE$PTQ(G^)MQ}$Xr?bNtIe68K#q2m@BiAETO7NKC@P95E=F-&wO@!sI? zn_lL{)zc`96mizr(>QnB+3YoB&t9NjS^X+M{KsW%PPJl6_QL91#iyS-{JP{YuBn*6 zt(-w{XVW3H1bIAHIh$kidb`a_?KC$Hd6m;wo`bdI9`+ovCpS*}8sJ zA~_0~-AHMyn4_u>|+8H>6<8X)j}hH(;-=og_nWcf!_jse)BQPD z?Ry!w9eOkCI%?T-*1lxR4#N!I18dWKoX#4;Tqi2b!sugo`sgN3DEPDwxEI>TaoS6T zjLFvX*~Lq?yW{{`vu#{A|3+pldl*@8465XEFo~~>zMYXNr$(gR8j*_BSlxCF8K=gi zqHBHW)<~Y|iOE4(zBbaAq3}@B7fO0U2@fLx!I$4aY*)n;Xw-8P+t5}r`fL-k=Y zLtq<&iJz)Hqb(0Da)2)tIjyCK5osq% zc+>j`VKKSl7_K~N7LzIu+@`cPn%8UQ@$pCRa8%(>_}SnERJyIydZpa9={P=X%|mo= zhGJ_Txf!qch0XoELn2DWP%;Qu3%Bf>c?xoE2Z{Ca*8_ZzW z;n}HuPj6C4Za?fczW4ZXEUG(&MV&u@R0CquTUgmS2)7W+j&bL^|HXlo`+qC*8(?UD zISbF7%gqaJ<5!FB!1(J7_O%(b$Y?EdBDAtnNlyeOXJum^Y;lOBvSbxjR)ivBg(4%A zNE3>T2xUenneH|6+QV+RfoN_SbI*LG5BMbwOIcdK1mm^x^Zl;q1AeOd$czq2OW#h*K&FI}DFT`L5_}rF;Y#vU z4GYhm%R!X~^ig2evPW^;Qu5p+7wmEF4we1s-ao=LeF(}zWi~VO(3^SmgopU(qQz9l z@{v;VUj08gc=l1OZLj&(Bmhj^lLDMX}%QGCyKBw&>?9N$czX~hC|3~Bf!i+ z+kPZ1luQY2r?rwP9a`N4R<{W4E|kon(>P5(W`Nbod*{z*{NO$Mbeah=JpSpEXqDyC z2^SG};yYB*5*C&f0c~MNifKwW0WiF97>h4>i$f~*0hQyU_Dzg^U;+;;o%Jt~aB$T@ zynFt9Q50_}CI8G5gtpT{$&~F!(p$r5w!MPW8B)r(QoP19sFerhJ3}nq${C@e7eEvTD zc`n)OLR7AiT%?L0|NUni_4x73uU)|U&JAeu&7nYJ2kyqpr_YgEt{xSZo_>h(tyDVm zWw2$ho1yp#xk{7AFcr&HnPgC9lEE-yex-Kq9d8GZmM%Jf{&p`TeC0Ft!HLv#)iY)E z(fsw4|K6cuuh+c6(T`8YlpT)`?Wr0ANuE`{P-W2qup|h&Y^NWp*Oa4 zDKDs`y0DTFg;i7(R8W~;No7F=l?4?HObpnzGu^iESKP8-W+-d#+S`BlN6WXi-ODE( zv7%i;knS>$)rqeo1)tj&x07tXNwJG|F}&^}Ryrc6d3e3YPCGi%z|K>X>8Q$4{C4wV1XqWzoj> zm^AxvaI4v~q=*l{-+ye-R=MQwKjD$(k7K0Z)KSOM<)?UU^Lj{qPUDrED2wO_Md*p^cqwaa~)vsQT z_L>34V2Y27cBCyoUj*ct_;vdaN)|eQI{v<1;FVD*n!~HS<_pw-^!K1Cv|M zmHR%nL-2q3`==K&{Zt3gV`b}V-mHC#l;4Hp4kBzx(h3GNDgca12)atIRlT z#ix|SwZ0sAZG|FdZqTS>`74M10k|rFYgK)61 z!oeUM(l6l%_`&!KdbM-syLWT*TQgC@AuKo6rO03p3|%YrzMtiTXHY= zA56X7o5_xsX-^(^{tA=GbgHN-(}YM%+iFXQyVPiHP$sGdy6I=*7mh!V!e}ATb1{0} z3m5U+$`??@=Ro09kg=Z7;4sBrW#fogk!^i#odIYEzxW~^TYd*W-~UQR6_4zr*XZKm zyw|*%aLbw(Ijc!#?M8gNk*w2Tc~+D0ttOeVn=DT>i?rL^@yhmtsCO7An4U_(BXH=B&pVCAevGEO}?r(R~=dXaH9VLHv$prn;8tJwRYNxZOnK5Ec!A^-be^0qiA zBnZjZQxw*BtVc=*h(qEitVks@-}!aFIt?!xj;$LIp4~1o&L)|4>&ZFwWSn{{XEmCP z(;zbTW|^}ajS`LNi8Sp9;|>WhGtk-fu|{%Yv*p{HMb>UGS*KoPoO-fWJvqBhX6-tR z)VVOnBg4spyW8hBMvPFHxOJia*q#Aqm^T4u4A$|~;0?;;o@*Mv1@e|Z` ztnW)e;V=Tf-iWNdNoMUja&{eAt6pTBdXshPMb>Vxe0wuFu{paw*7!}4K8)Vw97oMya*+`v8JDX(2*@PL~ef1mHnG0XO1kXM>6BIt0LzMT7xRSkG zR3e{Nn%m)8aKxUJvaun-kL@k^rOM`JldxP8%Gee@ZU9D+8U5b0FC%s87w+Sw$s zkvieYdYQKCt*qTZS~O&%(amNF!8hUiR`~+vX?!su+7PSCYAa_cj0|)b_%akZ6Uwa8 zzk4Z&{&k#?;{(AF+GI?APjG@x8cQdTTiiavfU`f!Xy(^0VC=x%IQEHCu-yuLci$ee z0F1zopU0!i@8rgVu4QO``8Hh~Yl~Mpry4}ot(TtFqCMFnJ*V07M6*#eX6vJk-v<1* zCIEV7g19ACpZI{#;QN*~o>nSnl*kG_Chhn$8dXFW5$FQp=zQVGJY(r3wvJ=zIF^YT z%S4c+t{s_RPk;8@9xty|g zld(7A$yUp^T6EyFh_u_BnMjkF^X(HR{-vCuE$eA>;bhm#MNQ69R#uxJW0aK=PS7m^ z-68_Np|+;XpiLl@^w3c+ zG)Lv`U;1#>O_Q#dTkVUjOGl>d^)hGG$(+-wL)jY3xh*?-+kYnnY?Y3eX&2KXxmY@z zF*=%-j_x*&=n}pv5U$J@4*9~;N#TYGW0{1MI;t(A!qP4nN635|adA)5R6wt!DG&il z`cjco=Ijk^`l;bBta@pi=V?j(QX(?1ovz(h>Oi)WRc&4@(zd;Q{y#zh^ceJLLy!Of z0Ln>3K~zf+t1CW|R5m}?We2iLIZnO_f_&+kJR`$|2CSrtgzBz49 zcz`d%aam!H829@R?%U~TKwG z3FC;kg^C$RM2%FDe>ZhDtem!+UG(N}EUZmgmA>2D nil) or withrootnode then begin + result:= info.name; + if fparent <> nil then begin + if (tpropinfonode(fparent).fparent <> nil) or withrootnode then begin + result:= tpropinfonode(fparent).rootstring(separator) + separator + result; + end; + end; + end + else begin + result:= ''; + end; +end; + +function tpropinfonode.findsubnode(const nametree: string): tpropinfonode; +var + ar1: stringarty; + anode,anode1: tpropinfonode; + int1,int2: integer; +begin + ar1:= nil; + splitstring(nametree,ar1,','); + if (high(ar1) >= 0) and (info.name = ar1[0]) then begin + anode:= self; + anode1:= self; + for int1:= 1 to high(ar1) do begin + anode1:= nil; + for int2:= 0 to anode.fcount - 1 do begin + anode1:= tpropinfonode(anode.fitems[int2]); + if anode1.info.name = ar1[int1] then begin + break; + end + else begin + anode1:= nil; + end; + end; + if anode1 = nil then begin + break; + end + else begin + anode:= anode1; + end; + end; + result:= anode1; + end + else begin + result:= nil; + end; +end; + +procedure tpropinfonode.nodetoitem(const listitem: ttreelistitem); +begin + with tpropinfoitem(listitem) do begin + fcaption:= msestring(self.info.name); + node:= self; + end; +end; +{ +procedure tpropinfonode.itemtonode(const listitem: ttreelistitem); +begin + with tpropinfoitem(listitem) do begin + self.info:= info; + end; +end; +} +procedure tpropinfonode.clear; +begin + inherited; + finalize(info); + fillchar(info,sizeof(info),0); +end; + +procedure readprops(const stream: tstream; const node: tpropinfonode); + +var + reader: treader; + + procedure readobj(const node: tpropinfonode); + procedure readpropdat(const node: tpropinfonode); + procedure readpropval(const node: tpropinfonode); + var + str1,str2: string; + int1,int2: integer; + aitem: tpropinfonode; + begin + with treader1(reader) do begin + with node.info do begin + valuetype:= nextvalue; + case valuetype of + vaNull,vanil: begin + readvalue;{ no value field, just an identifier } + end; + vaFalse, vaTrue: begin + readvalue;{ no value field, just an identifier } + booleanvalue:= valuetype = vatrue; + end; + vaBinary: begin + readvalue; + {$ifdef FPC} + stringvalue:= driver.readstring(valstring); + {$else} + Read(int1, SizeOf(int1)); + setlength(stringvalue,int1); + read(pchar(pointer(stringvalue))^,int1); + {$endif} + end; + vaList: begin + readvalue; + int1:= 0; + while not endoflist do begin + aitem:= node.newnode; + aitem.info.name:= inttostr(int1)+':'; + readpropval(aitem); + inc(int1); + end; + readlistend; + end; + vaInt8,vaint16,vaint32: begin + integervalue:= readinteger; + end; + vaInt64: begin + int64value:= readint64; + end; + vaSingle: begin + realvalue:= readsingle; + end; + vaCurrency: begin + realvalue:= readcurrency; + end; + vaDate: begin + realvalue:= readdate; + end; + vaExtended: begin + realvalue:= readfloat; + end; + vaIdent: begin + readvalue; + stringvalue:= {$ifdef FPC}driver.{$endif}readstr; + end; + vastring,valstring,vaWString,vautf8string: begin + msestringvalue:= treader_readmsestring(reader); + end; + vaSet: begin + readvalue; + str1:= ''; + while true do begin + str2:= {$ifdef FPC}driver.{$endif}readstr; + if str2 = '' then begin + break; + end; + str1:= str1 + str2 + ','; + end; + stringvalue:= '['+copy(str1,1,length(str1)-1)+']'; + end; + vaCollection: begin + readvalue; + int2:= 0; + while not EndOfList do begin + aitem:= node.newnode; + aitem.info.valuetype:= valist; + if NextValue in [vaInt8, vaInt16, vaInt32] then begin + int1:= readinteger; + aitem.info.name:= inttostr(int1); + end + else begin + if NextValue in [vaident] then begin + aitem.info.name:= readident; + end + else begin + aitem.info.name:= inttostr(int2)+':'; + end; + end; + readlistbegin; + while not endoflist do begin + readpropdat(aitem.newnode); + end; + readlistend; + inc(int2); + end; + ReadListEnd; + end; + end; + end; + end; + end; + + begin //writepropdat + with treader1(reader) do begin + {$ifdef FPC} + node.info.name:= driver.beginproperty; + {$else} + node.info.name:= readstr; + {$endif} + readpropval(node); + end; + end; + + var + compclass,compname: string; + flags: tfilerflags; + pos: integer; + + begin //writeobj + with treader1(reader) do begin + {$ifdef FPC} + driver.begincomponent(flags,pos,compclass,compname); + {$else} + pos:= 0; + ReadPrefix(flags,pos); + compclass := ReadStr; + compname := ReadStr; + {$endif} + node.info.name:= compname; + node.info.stringvalue:= compclass; + node.info.integervalue:= (pos shl 3) or {$ifdef FPC}longword{$else}byte{$endif}(flags) and $07; + while not endoflist do begin + readpropdat(node.newnode); + end; + ReadListEnd; + while not EndOfList do begin; + readobj(node.newnode); + end; + ReadListEnd; + end; + end; + +begin //readprops + reader:= treader.Create(stream,4096); + try + with treader1(reader) do begin + {$ifdef FPC} + driver.beginrootcomponent; + {$else} + readsignature; + {$endif} + readobj(node); + end; + finally + reader.Free; + end; +end; + +procedure writeprops(const stream: tstream; const node: tpropinfonode); + +var + writer: twritermse; + + procedure writeobj(const node: tpropinfonode); + procedure writepropdat(const node: tpropinfonode); + procedure writepropval(const node: tpropinfonode); + type + setinfoty = record + kind: ttypekind; + namelen: byte; + data: ttypedata; + end; + var + int1,int2: integer; + ar1: stringarty; + str1: string; + {$ifdef FPC} +// setinfo: setinfoty; +// po1: ^setinfoty; +// po2: ^shortstring; +// lwo1: longword; + {$endif} + begin + {$ifdef FPC}{$warnings off}{$endif} + with twriter1(writer) do begin + {$ifdef FPC}{$warnings on}{$endif} + with node.info do begin + case valuetype of + vaNull: begin + writeident('Null'); + end; + vaNil: begin + writeident('nil'); + end; + vaFalse: begin + writeident('False'); + end; + vaTrue: begin + writeident('True'); + end; + vaBinary: begin + {$ifdef FPC} + driver.writebinary(stringvalue[1],length(stringvalue)); + {$else} + writevalue(vabinary); + int1:= length(stringvalue); + write(int1, sizeof(int1)); + if int1 <> 0 then begin + write(stringvalue[1],int1); + end; + {$endif} + end; + vaList: begin + writelistbegin; + for int1:= 0 to node.fcount - 1 do begin + writepropval(node[int1]); + end; + writelistend; + end; + vaInt8,vaint16,vaint32: begin + writeinteger(integervalue); + end; + vaInt64: begin + writeinteger(int64value); + end; + vaSingle: begin + writesingle(realvalue); + end; + vaCurrency: begin + writecurrency(realvalue); + end; + vaDate: begin + writedate(realvalue); + end; + vaExtended: begin + writefloat(realvalue); + end; + vaIdent: begin + writeident(stringvalue); + end; + vaString,vaLString,vaWString,vautf8string: begin + twriter_writemsestring(writer,msestringvalue); + end; + vaSet: begin + ar1:= nil; + str1:= trim(stringvalue); + str1:= copy(stringvalue,2,length(str1)-2); + splitstring(str1,ar1,',',true); + {$ifdef FPC} + with tbinaryobjectwriter1(driver) do begin + writevalue(vaset); + for int1:= 0 to high(ar1) do begin + writestr(ar1[int1]); + end; + writestr(''); + end; + {$else} + writevalue(vaset); + for int1:= 0 to high(ar1) do begin + writestr(ar1[int1]); + end; + writestr(''); + {$endif} + end; + vaCollection: begin + {$ifdef FPC} + driver.begincollection; + {$else} + writevalue(vacollection); + {$endif} + for int1:= 0 to node.fcount - 1 do begin + with node[int1] do begin + if (info.name <> '') then begin + if info.name[1] in ['0'..'9'] then begin + if (info.name[length(info.name)] <> ':') then begin + writeinteger(strtoint(info.name)); + end; + end + else begin + writeident(info.name); + end; + end; + end; + writelistbegin; + for int2:= 0 to node[int1].fcount-1 do begin + writepropdat(node[int1][int2]); + end; + writelistend; + end; + writeListEnd; + end; + end; + end; + end; + end; + + begin //writepropdat + {$ifdef FPC}{$warnings off}{$endif} + with twriter1(writer) do begin + {$ifdef FPC}{$warnings on}{$endif} + {$ifdef FPC} + driver.beginproperty(node.info.name); + {$else} + writestr(node.info.name); + {$endif} + writepropval(node); + end; + end; + + var + compclass,compname: string; + flags: tfilerflags; + pos: integer; + int1: integer; + {$ifdef FPC} + Prefix: Byte; + {$endif} + begin //writeobj + {$ifdef FPC}{$warnings off}{$endif} + with twriter1(writer) do begin + {$ifdef FPC}{$warnings on}{$endif} + compname:= node.info.name; + compclass:= node.info.stringvalue; + flags:= tfilerflags({$ifdef FPC}longword{$else}byte{$endif}(node.info.integervalue and $07)); + pos:= node.info.integervalue shr 3; + {$ifdef FPC} + with tbinaryobjectwriter1(driver) do begin + if not FSignatureWritten then begin + Write(FilerSignature, SizeOf(FilerSignature)); + FSignatureWritten := True; + end; + { Only write the flags if they are needed! } + if Flags <> [] then begin + Prefix := Integer(Flags) or $f0; + Write(Prefix, 1); + if ffChildPos in Flags then begin + WriteInteger(pos); + end; + end; + writestr(compclass); + writestr(compname); + end; + {$else} + writeprefix(flags,pos); + writestr(compclass); + writestr(compname); + {$endif} + int1:= 0; + while int1 < node.fcount do begin + with node[int1] do begin + if info.valuetype = vanull then begin + break; + end; + end; + writepropdat(node[int1]); + inc(int1); + end; + writelistend; + while int1 < node.fcount do begin + writeobj(node[int1]); + inc(int1); + end; + writeListEnd; + end; + end; + +begin //writeprops + writer:= twritermse.Create(stream,4096); + try + {$ifdef FPC}{$warnings off}{$endif} + with twriter1(writer) do begin + {$ifdef FPC}{$warnings on}{$endif} + {$ifdef FPC} +// driver.beginrootcomponent; //signature written by begincomponent + {$else} + writesignature; + {$endif} + writeobj(node); + end; + finally + writer.Free; + end; +end; + +procedure writeconsts(const instream,outstream: tstream; + const node: tpropinfonode); +var + int1: integer; + str1: string; +begin + for int1:= 0 to node.fcount - 1 do begin + with tpropinfonode(node.fitems[int1]).info do begin + case valuetype of +// vaString,vaLString: begin +// str1:= stringtopascalstring(stringvalue); +// end; + vastring,valstring,vaWString,vautf8string: begin + str1:= stringtopascalstring(msestringvalue); + end; + else begin + str1:= ''; + end; + end; + if str1 <> '' then begin + if coffset <> instream.Position then begin + outstream.CopyFrom(instream,coffset-instream.position); + end; + instream.Position:= coffset + clen; + outstream.WriteBuffer(str1[1],length(str1)); + end; + end; + end; + outstream.CopyFrom(instream,instream.Size-instream.position); +end; + +function comppos(const l,r): integer; +begin + result:= tpropinfonode(l).info.coffset - tpropinfonode(r).info.coffset; +end; + +procedure writeresources(const instream,outstream: tstream; + const node: tpropinfonode); +var + int1,int2,int3: integer; + ar1: pointerarty; + str1: string; +begin + int2:= 0; + for int1:= 0 to node.fcount - 1 do begin + inc(int2,tpropinfonode(node.fitems[int1]).fcount); + end; + setlength(ar1,int2); + int2:= 0; + for int1:= 0 to node.fcount - 1 do begin + int3:= tpropinfonode(node.fitems[int1]).fcount; + if int3 > 0 then begin + move(tpropinfonode(node.fitems[int1]).fitems[0],ar1[int2],int3 * sizeof(pointer)); + inc(int2,int3); + end; + end; + sortarray(ar1,{$ifdef FPC}@{$endif}comppos); + for int1:= 0 to high(ar1) do begin + with tpropinfonode(ar1[int1]).info do begin + case valuetype of +// vaString,vaLString: begin +// str1:= stringtocstring(stringvalue); +// end; + vastring,valstring,vaWString,vautf8string: begin + str1:= stringtocstring(msestringvalue); + end; + else begin + str1:= ''; + end; + end; + if str1 <> '' then begin + if coffset <> instream.Position then begin + outstream.CopyFrom(instream,coffset-instream.position); + end; + instream.Position:= coffset + clen; + outstream.WriteBuffer(str1[1],length(str1)); + end; + end; + end; + outstream.CopyFrom(instream,instream.Size-instream.position); +end; + +procedure getjsonresourcestrings(var json: jsonvaluety; + const node: tpropinfonode); +var + node1,node2: tpropinfonode; + mstr1: msestring; + int1: int32; +begin + for int1:= 0 to node.count - 1 do begin + node1:= node[int1]; + with node1.info do begin + if valuetype = vawstring then begin + node2:= tpropinfonode(node1.fparent); + mstr1:= msestring(name); + repeat + mstr1:= msestring(node2.info.name) + '.' + mstr1; + node2:= tpropinfonode(node2.fparent); + until (node2.fparent = nil) or (node2.parent.parent = nil); + jsonadditems(jsonaddvalues(json,[nil])^, + ['hash','name','value'], + [hash(stringtoutf8ansi(msestringvalue)),mstr1, + msestringvalue]); + end + else begin + getjsonresourcestrings(json,node1); + end; + end; + end; +end; + +procedure writefpcresourcestrings(const outstream: ttextstream; + const node: tpropinfonode); +var + int1: integer; + node1,node2: tpropinfonode; + str1,str2: string; + mstr1: msestring; + po1: pmsechar; + i1: int32; + json: jsonvaluety; + pj: pjsonvaluety; +begin + if fileext(outstream.filename) = 'rsj' then begin + jsonvalueinit(json); + try + pj:= jsonadditems(json,['version','strings'],[1,nil]); + getjsonresourcestrings(pj^,node); + syserror(jsonencode(json,outstream)); + finally + jsonvaluefree(json); + end; + end + else begin + for int1:= 0 to node.count - 1 do begin + node1:= node[int1]; + with node1.info do begin + if valuetype = vawstring then begin + node2:= tpropinfonode(node1.fparent); + str1:= name; + repeat + str1:= node2.info.name + '.' + str1; + node2:= tpropinfonode(node2.fparent); + until (node2.fparent = nil) or (node2.parent.parent = nil); + outstream.writeln(''); + outstream.writeln('# hash value = '+ + inttostr(hash(ansistring(msestringvalue)))); + str2:= ansistring(msestringvalue); + setlength(mstr1,length(str2)); + po1:= pmsechar(mstr1); + for i1:= 1 to length(mstr1) do begin + po1^:= msechar(byte(str2[i1])); //use locale encoding + inc(po1); + end; + outstream.writeln(str1+'='+stringtopascalstring(mstr1)); + end + else begin + writefpcresourcestrings(outstream,node1); + end; + end; + end; + end; +end; + +procedure tpropinfonode.dotransferlang(const sender: ttreenode); + + procedure doerror(mess: string); + begin + showmessage(msestring(mess)); + end; + +begin + with tpropinfonode(sender).info do begin + if not donottranslate and (alang <= high(variants)) then begin + case valuetype of +// vaString,vaLString: begin +// stringvalue:= variants[alang]; +// end; + vastring,valstring,vaWString,vautf8string: begin + msestringvalue:= variants[alang]; + end; + vaint8,vaint16,vaint32: begin + if variants[alang] <> '' then begin + try + integervalue:= strtoint(variants[alang]); + except + doerror('Invalid integer'); + end; + end; + end; + vaint64: begin +// result:= inttostr(info.int64value); + end; + vaSingle,vaCurrency,vaDate,vaExtended: begin +// result:= floattostr(info.realvalue); + end; + end; + end; + end; +end; + +procedure tpropinfonode.transferlang(lang: integer); +begin + alang:= lang; + iterate({$ifdef FPC}@{$endif}dotransferlang); +end; + +procedure tpropinfonode.dodeletelang(const sender: ttreenode); +begin + with tpropinfonode(sender).info do begin + if high(variants) >= alang then begin + deleteitem(variants,alang); + end; + end; +end; + +procedure tpropinfonode.deletelang(lang: integer); +begin + alang:= lang; + iterate({$ifdef FPC}@{$endif}dodeletelang); +end; + +procedure tpropinfonode.doinitlang(const sender: ttreenode); +var + int1: integer; +begin + with tpropinfonode(sender).info do begin + case valuetype of +// vaString,vaLString: begin +// setlength(variants,alang); +// for int1:= 0 to alang - 1 do begin +// variants[int1]:= stringvalue; +// end; +// end; + vastring,valstring,vaWString,vautf8string: begin + setlength(variants,alang); + for int1:= 0 to alang - 1 do begin + variants[int1]:= msestringvalue; + end; + end; + end; + end; +end; + +procedure tpropinfonode.initlang(acount: integer); +begin + alang:= acount; + iterate({$ifdef FPC}@{$endif}doinitlang); +end; + + +end. diff --git a/mseide-msegui/tools/i18n/project.mfm b/mseide-msegui/tools/i18n/project.mfm new file mode 100644 index 0000000..3ba5ef2 --- /dev/null +++ b/mseide-msegui/tools/i18n/project.mfm @@ -0,0 +1,452 @@ +object projectfo: tprojectfo + optionswidget = [ow_arrowfocus, ow_subfocus, ow_destroywidgets, ow_hinton] + visible = False + bounds_x = 149 + bounds_y = 167 + bounds_cx = 683 + bounds_cy = 501 + container.optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_subfocus, ow_mousetransparent, ow_destroywidgets] + container.frame.localprops = [] + container.frame.localprops1 = [] + container.onlayout = childscaled + container.bounds = ( + 0 + 0 + 683 + 501 + ) + options = [fo_closeonesc, fo_savepos, fo_savestate] + statfile = projectstat + caption = 'Edit Translate Project' + onlayout = childscaled + moduleclassname = 'tmseform' + object impexpencoding: tenumtypeedit + frame.caption = 'Encoding for imp/exp files' + frame.captionpos = cp_right + frame.localprops = [] + frame.localprops1 = [] + frame.button.color = -2147483646 + frame.outerframe = ( + 0 + 0 + 126 + 0 + ) + taborder = 6 + bounds_x = 8 + bounds_y = 476 + bounds_cx = 226 + bounds_cy = 19 + anchors = [an_left, an_bottom] + statfile = projectstat + valuedefault = 1 + min = 0 + max = 2 + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + oninit = impexpencinit + reffontheight = 13 + end + object grid: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_focusbackonesc, ow_destroywidgets] + frame.localprops = [] + frame.localprops1 = [] + taborder = 4 + bounds_x = 0 + bounds_y = 264 + bounds_cx = 683 + bounds_cy = 104 + anchors = [an_top] + optionsgrid = [og_colsizing, og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_colchangeontabkey, og_wrapcol, og_autopopup] + fixrows.count = 1 + fixrows.items = < + item + height = 15 + captions.count = 3 + captions.items = < + item + caption = 'Rootname' + textflags = [] + end + item + caption = 'File' + textflags = [] + end + item + caption = 'Kind' + textflags = [] + end> + end> + datacols.count = 3 + datacols.items = < + item[rootname] + width = 71 + options = [co_readonly, co_savevalue, co_savestate] + widgetname = 'rootname' + dataclass = tgridmsestringdatalist + end + item[filename] + width = 479 + options = [co_fill, co_savevalue] + widgetname = 'filename' + dataclass = tgridmsestringdatalist + end + item[filekind] + width = 126 + widgetname = 'filekind' + dataclass = tgridenumdatalist + end> + datarowheight = 15 + statfile = projectstat + reffontheight = 13 + object rootname: tstringedit + optionswidget1 = [ow1_fontglyphheight] + color = -1879048185 + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 71 + bounds_cy = 15 + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_savevalue, oe1_savestate] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick] + reffontheight = 13 + end + object filename: tfilenameedit + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + taborder = 2 + visible = False + bounds_x = 72 + bounds_y = 0 + bounds_cx = 479 + bounds_cy = 15 + ondataentered = filenamedataentered + controller.historymaxcount = 0 + controller.captionopen = 'Select unit or form file' + reffontheight = 13 + end + object filekind: tenumtypeedit + optionswidget1 = [ow1_fontglyphheight] + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.button.color = -2147483646 + taborder = 3 + visible = False + bounds_x = 552 + bounds_y = 0 + bounds_cx = 126 + bounds_cy = 15 + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + oninit = filekindoninit + reffontheight = 13 + end + end + object datafilename: tfilenameedit + frame.caption = 'Datafile' + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 16 + 0 + 0 + ) + taborder = 1 + bounds_x = 0 + bounds_y = 0 + bounds_cx = 683 + bounds_cy = 35 + anchors = [an_top] + statfile = projectstat + controller.filterlist.data = ( + ( + 'MSEi18n Data Files' + '*.trd ' + ) + ( + 'All files' + '"*"' + ) + ) + controller.defaultext = 'trd' + controller.historymaxcount = 0 + reffontheight = 13 + end + object grid2: twidgetgrid + optionswidget = [ow_mousefocus, ow_tabfocus, ow_arrowfocus, ow_focusbackonesc, ow_destroywidgets] + frame.localprops = [] + frame.localprops1 = [] + taborder = 5 + bounds_x = 0 + bounds_y = 376 + bounds_cx = 683 + bounds_cy = 90 + anchors = [an_top, an_bottom] + optionsgrid = [og_colsizing, og_rowmoving, og_keyrowmoving, og_rowinserting, og_rowdeleting, og_focuscellonenter, og_autofirstrow, og_autoappend, og_wrapcol, og_autopopup] + fixrows.count = 1 + fixrows.items = < + item + height = 15 + captions.count = 2 + captions.items = < + item + caption = 'Language' + textflags = [] + end + item + caption = 'Directory' + textflags = [] + end> + end> + datacols.count = 2 + datacols.items = < + item[lang] + width = 94 + widgetname = 'lang' + dataclass = tgridmsestringdatalist + end + item[dir] + width = 583 + options = [co_fill, co_savevalue] + widgetname = 'dir' + dataclass = tgridmsestringdatalist + end> + datarowheight = 15 + statfile = projectstat + onrowsdeleted = langdeleted + reffontheight = 13 + object lang: tstringedit + optionswidget1 = [ow1_fontglyphheight] + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 94 + bounds_cy = 15 + reffontheight = 13 + end + object dir: tdirdropdownedit + frame.levelo = 0 + frame.colorclient = -2147483646 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.button.color = -2147483646 + taborder = 2 + visible = False + bounds_x = 95 + bounds_y = 0 + bounds_cx = 583 + bounds_cy = 15 + reffontheight = 13 + end + end + object splitter: tsplitter + color = -1879048189 + taborder = 8 + bounds_x = 0 + bounds_y = 368 + bounds_cx = 683 + bounds_cy = 3 + anchors = [an_top] + options = [spo_vmove, spo_vprop] + linktop = grid + linkbottom = grid2 + end + object makecommand: tmemodialogedit + frame.caption = 'Make command' + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + imagenr = 17 + end> + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 16 + 0 + 0 + ) + taborder = 2 + onshowhint = showhintexe + bounds_x = 0 + bounds_y = 144 + bounds_cx = 644 + bounds_cy = 35 + anchors = [an_left, an_top, an_right] + statfile = projectstat + value = '${COMPILER} -Fu${MSELIBDIR}i18n ${LIBFILE}' + onsetvalue = makecommandsetvalue + reffontheight = 13 + end + object makeon: tbooleanedit + frame.caption = 'on' + frame.captionpos = cp_top + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 16 + 1 + 0 + ) + taborder = 3 + bounds_x = 656 + bounds_y = 149 + bounds_cx = 14 + bounds_cy = 29 + anchors = [an_top, an_right] + statfile = projectstat + value = True + end + object ok: tbutton + taborder = 7 + bounds_x = 558 + bounds_y = 473 + bounds_cx = 50 + bounds_cy = 22 + anchors = [an_right, an_bottom] + state = [as_default, as_localdefault, as_localcaption] + caption = 'OK' + modalresult = mr_ok + end + object cancel: tbutton + bounds_x = 622 + bounds_y = 473 + bounds_cx = 50 + bounds_cy = 22 + anchors = [an_right, an_bottom] + state = [as_localcaption] + caption = 'Cancel' + modalresult = mr_cancel + end + object destname: tstringedit + frame.caption = 'Destination Basename (empty = Datafile name)' + frame.localprops = [] + frame.localprops1 = [] + frame.outerframe = ( + 0 + 16 + 0 + 0 + ) + taborder = 9 + bounds_x = 0 + bounds_y = 56 + bounds_cx = 683 + bounds_cy = 35 + anchors = [an_top] + statfile = projectstat + reffontheight = 13 + end + object beforemake: tmemodialogedit + frame.caption = 'Before make' + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + imagenr = 17 + end> + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 16 + 0 + 0 + ) + taborder = 10 + onshowhint = showhintexe + bounds_x = 0 + bounds_y = 104 + bounds_cx = 683 + bounds_cy = 35 + anchors = [an_top] + statfile = projectstat + reffontheight = 13 + end + object aftermake: tmemodialogedit + frame.caption = 'After make' + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + imagenr = 17 + end> + frame.button.imagenr = 17 + frame.outerframe = ( + 0 + 16 + 0 + 0 + ) + taborder = 11 + onshowhint = showhintexe + bounds_x = 0 + bounds_y = 184 + bounds_cx = 683 + bounds_cy = 35 + anchors = [an_top] + statfile = projectstat + reffontheight = 13 + end + object projectstat: tstatfile + onstatupdate = projectstatonupdatestat + onstatbeforewrite = projectstatonbeforewritestat + onstatafterread = projectstatonafterreadstat + left = 128 + top = 56 + end + object impexpfiledialog: tfiledialog + statfile = projectstat + controller.filename = 'default.csv' + controller.filterlist.data = ( + ( + 'Data exchange files' + '*.csv' + ) + ) + controller.defaultext = 'csv' + controller.historymaxcount = 0 + controller.captionopen = 'Open import file' + controller.captionsave = 'Save export file' + left = 240 + top = 56 + end +end diff --git a/mseide-msegui/tools/i18n/project.pas b/mseide-msegui/tools/i18n/project.pas new file mode 100644 index 0000000..7eeba8f --- /dev/null +++ b/mseide-msegui/tools/i18n/project.pas @@ -0,0 +1,158 @@ +{ MSEtools Copyright (c) 1999-2006 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit project; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface +uses + mseforms,msewidgetgrid,msefiledialog,msestat,msestatfile,msegraphedits, + msedataedits,msesimplewidgets,msesplitter,msegui,msestrings,msedbedit,msegrids, + msetypes,mseedit,mseglob,mseguiglob,mseifiglob,msemenus,msememodialog; + +type + tprojectfo = class(tmseform) + projectstat: tstatfile; + grid: twidgetgrid; + filename: tfilenameedit; + filekind: tenumtypeedit; + datafilename: tfilenameedit; + impexpfiledialog: tfiledialog; + grid2: twidgetgrid; + lang: tstringedit; + dir: tdirdropdownedit; + rootname: tstringedit; + splitter: tsplitter; + makecommand: tmemodialogedit; + makeon: tbooleanedit; + ok: tbutton; + cancel: tbutton; + impexpencoding: tenumtypeedit; + destname: tstringedit; + beforemake: tmemodialogedit; + aftermake: tmemodialogedit; + procedure projectstatonupdatestat(const sender: TObject; + const filer: tstatfiler); + procedure projectstatonafterreadstat(const sender: tobject); + procedure filekindoninit(const sender: tenumtypeedit); + procedure childscaled(const sender: TObject); + procedure showhintexe(const sender: TObject; var info: hintinfoty); + procedure makecommandsetvalue(const sender: TObject; + var avalue: msestring; var accept: Boolean); + procedure impexpencinit(const sender: tenumtypeedit); + procedure langdeleted(const sender: tcustomgrid; const aindex: integer; + const acount: integer); + procedure projectstatonbeforewritestat(const sender: TObject); + procedure filenamedataentered(const sender: TObject); + public + // colwidths: integerarty; + end; + +var + projectfo: tprojectfo; + +implementation + +uses + main,project_mfm,msesysenv,msesettings,msestream,msemacros; +const + defaultmakecommand = '${COMPILER} -Fu${MSELIBDIR}i18n -FE.. -FU. ${LIBFILE}'; + +procedure tprojectfo.filekindoninit(const sender: tenumtypeedit); +begin + tenumtypeedit(sender).typeinfopo:= typeinfo(resfilekindty); +end; + +procedure tprojectfo.projectstatonbeforewritestat(const sender: TObject); +//var +// int1: integer; +begin +{ + setlength(colwidths,mainfo.grid.datacols.count - variantshift); + for int1:= 0 to high(colwidths) do begin + colwidths[int1]:= mainfo.grid.datacols[int1+variantshift].width; + end; +} +end; + +procedure tprojectfo.projectstatonupdatestat(const sender: TObject; + const filer: tstatfiler); +var + int1: integer; +begin + int1:= mainfo.grid.datacols.count; + filer.updatevalue('colcount',int1); + mainfo.grid.datacols.count:= int1+variantshift; +end; + +procedure tprojectfo.projectstatonafterreadstat(const sender: tobject); +//var +// int1: integer; +begin + try + mainfo.loadproject; + except + application.handleexception(nil); + end; + { + for int1:= 0 to high(colwidths) do begin + if int1 >= mainfo.grid.datacols.count + variantshift then begin + break; + end; + mainfo.grid.datacols[int1+variantshift].width:= colwidths[int1]; + end; +} +end; + +procedure tprojectfo.childscaled(const sender: TObject); +begin + placeyorder(0,[0,0,2,0,0,0,0,4],[datafilename,destname, + beforemake,makecommand,aftermake, + grid,splitter,grid2,ok],4); + aligny(wam_center,[makecommand,makeon]); + aligny(wam_center,[ok,cancel,impexpencoding]); +end; + +procedure tprojectfo.showhintexe(const sender: TObject; var info: hintinfoty); +begin + info.caption:= expandmacros(makecommand.value,getsyssettingsmacros); +end; + +procedure tprojectfo.makecommandsetvalue(const sender: TObject; + var avalue: msestring; var accept: Boolean); +begin + if avalue = '' then begin + avalue:= defaultmakecommand; + end; +end; + +procedure tprojectfo.impexpencinit(const sender: tenumtypeedit); +begin + sender.typeinfopo:= typeinfo(charencodingty); +end; + +procedure tprojectfo.langdeleted(const sender: tcustomgrid; const aindex: integer; + const acount: integer); +begin + rootnode.deletelang(aindex); +end; + +procedure tprojectfo.filenamedataentered(const sender: TObject); +begin + rootname.value:= ''; +end; + +end. diff --git a/mseide-msegui/tools/i18n/project_mfm.pas b/mseide-msegui/tools/i18n/project_mfm.pas new file mode 100644 index 0000000..4d4ec07 --- /dev/null +++ b/mseide-msegui/tools/i18n/project_mfm.pas @@ -0,0 +1,396 @@ +unit project_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,project; + +const + objdata: record size: integer; data: array[0..7571] of byte end = + (size: 7572; data: ( + 84,80,70,48,10,116,112,114,111,106,101,99,116,102,111,9,112,114,111,106, + 101,99,116,102,111,13,111,112,116,105,111,110,115,119,105,100,103,101,116,11, + 13,111,119,95,97,114,114,111,119,102,111,99,117,115,11,111,119,95,115,117, + 98,102,111,99,117,115,17,111,119,95,100,101,115,116,114,111,121,119,105,100, + 103,101,116,115,9,111,119,95,104,105,110,116,111,110,0,7,118,105,115,105, + 98,108,101,8,8,98,111,117,110,100,115,95,120,3,149,0,8,98,111,117, + 110,100,115,95,121,3,167,0,9,98,111,117,110,100,115,95,99,120,3,171, + 2,9,98,111,117,110,100,115,95,99,121,3,245,1,23,99,111,110,116,97, + 105,110,101,114,46,111,112,116,105,111,110,115,119,105,100,103,101,116,11,13, + 111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119,95,116,97,98, + 102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111,99,117,115,11, + 111,119,95,115,117,98,102,111,99,117,115,19,111,119,95,109,111,117,115,101, + 116,114,97,110,115,112,97,114,101,110,116,17,111,119,95,100,101,115,116,114, + 111,121,119,105,100,103,101,116,115,0,26,99,111,110,116,97,105,110,101,114, + 46,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,27, + 99,111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,18,99,111,110,116,97,105,110,101,114,46, + 111,110,108,97,121,111,117,116,7,11,99,104,105,108,100,115,99,97,108,101, + 100,16,99,111,110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2, + 0,2,0,3,171,2,3,245,1,0,7,111,112,116,105,111,110,115,11,13, + 102,111,95,99,108,111,115,101,111,110,101,115,99,10,102,111,95,115,97,118, + 101,112,111,115,12,102,111,95,115,97,118,101,115,116,97,116,101,0,8,115, + 116,97,116,102,105,108,101,7,11,112,114,111,106,101,99,116,115,116,97,116, + 7,99,97,112,116,105,111,110,6,22,69,100,105,116,32,84,114,97,110,115, + 108,97,116,101,32,80,114,111,106,101,99,116,8,111,110,108,97,121,111,117, + 116,7,11,99,104,105,108,100,115,99,97,108,101,100,15,109,111,100,117,108, + 101,99,108,97,115,115,110,97,109,101,6,8,116,109,115,101,102,111,114,109, + 0,13,116,101,110,117,109,116,121,112,101,101,100,105,116,14,105,109,112,101, + 120,112,101,110,99,111,100,105,110,103,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,26,69,110,99,111,100,105,110,103,32,102,111,114,32,105, + 109,112,47,101,120,112,32,102,105,108,101,115,16,102,114,97,109,101,46,99, + 97,112,116,105,111,110,112,111,115,7,8,99,112,95,114,105,103,104,116,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,18,102, + 114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111,114,4,2,0, + 0,128,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1, + 2,0,2,0,2,126,2,0,0,8,116,97,98,111,114,100,101,114,2,6, + 8,98,111,117,110,100,115,95,120,2,8,8,98,111,117,110,100,115,95,121, + 3,220,1,9,98,111,117,110,100,115,95,99,120,3,226,0,9,98,111,117, + 110,100,115,95,99,121,2,19,7,97,110,99,104,111,114,115,11,7,97,110, + 95,108,101,102,116,9,97,110,95,98,111,116,116,111,109,0,8,115,116,97, + 116,102,105,108,101,7,11,112,114,111,106,101,99,116,115,116,97,116,12,118, + 97,108,117,101,100,101,102,97,117,108,116,2,1,3,109,105,110,2,0,3, + 109,97,120,2,2,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46, + 99,111,117,110,116,2,1,19,100,114,111,112,100,111,119,110,46,99,111,108, + 115,46,105,116,101,109,115,14,1,0,0,6,111,110,105,110,105,116,7,13, + 105,109,112,101,120,112,101,110,99,105,110,105,116,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,13,0,0,11,116,119,105,100,103,101,116,103, + 114,105,100,4,103,114,105,100,13,111,112,116,105,111,110,115,119,105,100,103, + 101,116,11,13,111,119,95,109,111,117,115,101,102,111,99,117,115,11,111,119, + 95,116,97,98,102,111,99,117,115,13,111,119,95,97,114,114,111,119,102,111, + 99,117,115,17,111,119,95,102,111,99,117,115,98,97,99,107,111,110,101,115, + 99,17,111,119,95,100,101,115,116,114,111,121,119,105,100,103,101,116,115,0, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8, + 116,97,98,111,114,100,101,114,2,4,8,98,111,117,110,100,115,95,120,2, + 0,8,98,111,117,110,100,115,95,121,3,8,1,9,98,111,117,110,100,115, + 95,99,120,3,171,2,9,98,111,117,110,100,115,95,99,121,2,104,7,97, + 110,99,104,111,114,115,11,6,97,110,95,116,111,112,0,11,111,112,116,105, + 111,110,115,103,114,105,100,11,12,111,103,95,99,111,108,115,105,122,105,110, + 103,12,111,103,95,114,111,119,109,111,118,105,110,103,15,111,103,95,107,101, + 121,114,111,119,109,111,118,105,110,103,15,111,103,95,114,111,119,105,110,115, + 101,114,116,105,110,103,14,111,103,95,114,111,119,100,101,108,101,116,105,110, + 103,19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101, + 114,15,111,103,95,97,117,116,111,102,105,114,115,116,114,111,119,13,111,103, + 95,97,117,116,111,97,112,112,101,110,100,20,111,103,95,99,111,108,99,104, + 97,110,103,101,111,110,116,97,98,107,101,121,10,111,103,95,119,114,97,112, + 99,111,108,12,111,103,95,97,117,116,111,112,111,112,117,112,0,13,102,105, + 120,114,111,119,115,46,99,111,117,110,116,2,1,13,102,105,120,114,111,119, + 115,46,105,116,101,109,115,14,1,6,104,101,105,103,104,116,2,15,14,99, + 97,112,116,105,111,110,115,46,99,111,117,110,116,2,3,14,99,97,112,116, + 105,111,110,115,46,105,116,101,109,115,14,1,7,99,97,112,116,105,111,110, + 6,8,82,111,111,116,110,97,109,101,9,116,101,120,116,102,108,97,103,115, + 11,0,0,1,7,99,97,112,116,105,111,110,6,4,70,105,108,101,9,116, + 101,120,116,102,108,97,103,115,11,0,0,1,7,99,97,112,116,105,111,110, + 6,4,75,105,110,100,9,116,101,120,116,102,108,97,103,115,11,0,0,0, + 0,0,14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,3,14, + 100,97,116,97,99,111,108,115,46,105,116,101,109,115,14,7,8,114,111,111, + 116,110,97,109,101,1,5,119,105,100,116,104,2,71,7,111,112,116,105,111, + 110,115,11,11,99,111,95,114,101,97,100,111,110,108,121,12,99,111,95,115, + 97,118,101,118,97,108,117,101,12,99,111,95,115,97,118,101,115,116,97,116, + 101,0,10,119,105,100,103,101,116,110,97,109,101,6,8,114,111,111,116,110, + 97,109,101,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100, + 109,115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,8, + 102,105,108,101,110,97,109,101,1,5,119,105,100,116,104,3,223,1,7,111, + 112,116,105,111,110,115,11,7,99,111,95,102,105,108,108,12,99,111,95,115, + 97,118,101,118,97,108,117,101,0,10,119,105,100,103,101,116,110,97,109,101, + 6,8,102,105,108,101,110,97,109,101,9,100,97,116,97,99,108,97,115,115, + 7,22,116,103,114,105,100,109,115,101,115,116,114,105,110,103,100,97,116,97, + 108,105,115,116,0,7,8,102,105,108,101,107,105,110,100,1,5,119,105,100, + 116,104,2,126,10,119,105,100,103,101,116,110,97,109,101,6,8,102,105,108, + 101,107,105,110,100,9,100,97,116,97,99,108,97,115,115,7,17,116,103,114, + 105,100,101,110,117,109,100,97,116,97,108,105,115,116,0,0,13,100,97,116, + 97,114,111,119,104,101,105,103,104,116,2,15,8,115,116,97,116,102,105,108, + 101,7,11,112,114,111,106,101,99,116,115,116,97,116,13,114,101,102,102,111, + 110,116,104,101,105,103,104,116,2,13,0,11,116,115,116,114,105,110,103,101, + 100,105,116,8,114,111,111,116,110,97,109,101,14,111,112,116,105,111,110,115, + 119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103,108,121, + 112,104,104,101,105,103,104,116,0,5,99,111,108,111,114,4,7,0,0,144, + 12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109, + 101,46,99,111,108,111,114,99,108,105,101,110,116,4,2,0,0,128,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108, + 95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105, + 101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,8,116,97,98,111,114,100,101,114,2,1,7,118,105,115,105, + 98,108,101,8,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110, + 100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,71,9,98, + 111,117,110,100,115,95,99,121,2,15,12,111,112,116,105,111,110,115,101,100, + 105,116,49,11,17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101, + 110,117,14,111,101,49,95,107,101,121,101,120,101,99,117,116,101,13,111,101, + 49,95,115,97,118,101,118,97,108,117,101,13,111,101,49,95,115,97,118,101, + 115,116,97,116,101,0,11,111,112,116,105,111,110,115,101,100,105,116,11,11, + 111,101,95,114,101,97,100,111,110,108,121,12,111,101,95,117,110,100,111,111, + 110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114,121,16,111, + 101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,12,111,101,95,101, + 97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108, + 101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99, + 117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13, + 111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116, + 111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,0, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,13,0,0,13,116, + 102,105,108,101,110,97,109,101,101,100,105,116,8,102,105,108,101,110,97,109, + 101,12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97, + 109,101,46,99,111,108,111,114,99,108,105,101,110,116,4,2,0,0,128,16, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114, + 108,95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108, + 105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,49,11,0,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46, + 99,111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116,116,111,110, + 115,46,105,116,101,109,115,14,1,5,99,111,108,111,114,4,2,0,0,128, + 7,105,109,97,103,101,110,114,2,17,0,0,18,102,114,97,109,101,46,98, + 117,116,116,111,110,46,99,111,108,111,114,4,2,0,0,128,20,102,114,97, + 109,101,46,98,117,116,116,111,110,46,105,109,97,103,101,110,114,2,17,8, + 116,97,98,111,114,100,101,114,2,2,7,118,105,115,105,98,108,101,8,8, + 98,111,117,110,100,115,95,120,2,72,8,98,111,117,110,100,115,95,121,2, + 0,9,98,111,117,110,100,115,95,99,120,3,223,1,9,98,111,117,110,100, + 115,95,99,121,2,15,13,111,110,100,97,116,97,101,110,116,101,114,101,100, + 7,19,102,105,108,101,110,97,109,101,100,97,116,97,101,110,116,101,114,101, + 100,26,99,111,110,116,114,111,108,108,101,114,46,104,105,115,116,111,114,121, + 109,97,120,99,111,117,110,116,2,0,22,99,111,110,116,114,111,108,108,101, + 114,46,99,97,112,116,105,111,110,111,112,101,110,6,24,83,101,108,101,99, + 116,32,117,110,105,116,32,111,114,32,102,111,114,109,32,102,105,108,101,13, + 114,101,102,102,111,110,116,104,101,105,103,104,116,2,13,0,0,13,116,101, + 110,117,109,116,121,112,101,101,100,105,116,8,102,105,108,101,107,105,110,100, + 14,111,112,116,105,111,110,115,119,105,100,103,101,116,49,11,19,111,119,49, + 95,102,111,110,116,103,108,121,112,104,104,101,105,103,104,116,0,12,102,114, + 97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109,101,46,99, + 111,108,111,114,99,108,105,101,110,116,4,2,0,0,128,16,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108,95,108,101, + 118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105,101,110,116, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111,108,111,114, + 4,2,0,0,128,8,116,97,98,111,114,100,101,114,2,3,7,118,105,115, + 105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,40,2,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,2,126, + 9,98,111,117,110,100,115,95,99,121,2,15,19,100,114,111,112,100,111,119, + 110,46,99,111,108,115,46,99,111,117,110,116,2,1,19,100,114,111,112,100, + 111,119,110,46,99,111,108,115,46,105,116,101,109,115,14,1,0,0,6,111, + 110,105,110,105,116,7,14,102,105,108,101,107,105,110,100,111,110,105,110,105, + 116,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,13,0,0,0, + 13,116,102,105,108,101,110,97,109,101,101,100,105,116,12,100,97,116,97,102, + 105,108,101,110,97,109,101,13,102,114,97,109,101,46,99,97,112,116,105,111, + 110,6,8,68,97,116,97,102,105,108,101,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,19,102,114,97,109,101,46,98,117,116, + 116,111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46,98, + 117,116,116,111,110,115,46,105,116,101,109,115,14,1,5,99,111,108,111,114, + 4,2,0,0,128,7,105,109,97,103,101,110,114,2,17,0,0,18,102,114, + 97,109,101,46,98,117,116,116,111,110,46,99,111,108,111,114,4,2,0,0, + 128,20,102,114,97,109,101,46,98,117,116,116,111,110,46,105,109,97,103,101, + 110,114,2,17,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109, + 101,1,2,0,2,16,2,0,2,0,0,8,116,97,98,111,114,100,101,114, + 2,1,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115, + 95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,171,2,9,98,111, + 117,110,100,115,95,99,121,2,35,7,97,110,99,104,111,114,115,11,6,97, + 110,95,116,111,112,0,8,115,116,97,116,102,105,108,101,7,11,112,114,111, + 106,101,99,116,115,116,97,116,26,99,111,110,116,114,111,108,108,101,114,46, + 102,105,108,116,101,114,108,105,115,116,46,100,97,116,97,1,1,6,18,77, + 83,69,105,49,56,110,32,68,97,116,97,32,70,105,108,101,115,6,6,42, + 46,116,114,100,32,0,1,6,9,65,108,108,32,102,105,108,101,115,6,3, + 34,42,34,0,0,21,99,111,110,116,114,111,108,108,101,114,46,100,101,102, + 97,117,108,116,101,120,116,6,3,116,114,100,26,99,111,110,116,114,111,108, + 108,101,114,46,104,105,115,116,111,114,121,109,97,120,99,111,117,110,116,2, + 0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,13,0,0,11, + 116,119,105,100,103,101,116,103,114,105,100,5,103,114,105,100,50,13,111,112, + 116,105,111,110,115,119,105,100,103,101,116,11,13,111,119,95,109,111,117,115, + 101,102,111,99,117,115,11,111,119,95,116,97,98,102,111,99,117,115,13,111, + 119,95,97,114,114,111,119,102,111,99,117,115,17,111,119,95,102,111,99,117, + 115,98,97,99,107,111,110,101,115,99,17,111,119,95,100,101,115,116,114,111, + 121,119,105,100,103,101,116,115,0,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,5,8, + 98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,3, + 120,1,9,98,111,117,110,100,115,95,99,120,3,171,2,9,98,111,117,110, + 100,115,95,99,121,2,90,7,97,110,99,104,111,114,115,11,6,97,110,95, + 116,111,112,9,97,110,95,98,111,116,116,111,109,0,11,111,112,116,105,111, + 110,115,103,114,105,100,11,12,111,103,95,99,111,108,115,105,122,105,110,103, + 12,111,103,95,114,111,119,109,111,118,105,110,103,15,111,103,95,107,101,121, + 114,111,119,109,111,118,105,110,103,15,111,103,95,114,111,119,105,110,115,101, + 114,116,105,110,103,14,111,103,95,114,111,119,100,101,108,101,116,105,110,103, + 19,111,103,95,102,111,99,117,115,99,101,108,108,111,110,101,110,116,101,114, + 15,111,103,95,97,117,116,111,102,105,114,115,116,114,111,119,13,111,103,95, + 97,117,116,111,97,112,112,101,110,100,10,111,103,95,119,114,97,112,99,111, + 108,12,111,103,95,97,117,116,111,112,111,112,117,112,0,13,102,105,120,114, + 111,119,115,46,99,111,117,110,116,2,1,13,102,105,120,114,111,119,115,46, + 105,116,101,109,115,14,1,6,104,101,105,103,104,116,2,15,14,99,97,112, + 116,105,111,110,115,46,99,111,117,110,116,2,2,14,99,97,112,116,105,111, + 110,115,46,105,116,101,109,115,14,1,7,99,97,112,116,105,111,110,6,8, + 76,97,110,103,117,97,103,101,9,116,101,120,116,102,108,97,103,115,11,0, + 0,1,7,99,97,112,116,105,111,110,6,9,68,105,114,101,99,116,111,114, + 121,9,116,101,120,116,102,108,97,103,115,11,0,0,0,0,0,14,100,97, + 116,97,99,111,108,115,46,99,111,117,110,116,2,2,14,100,97,116,97,99, + 111,108,115,46,105,116,101,109,115,14,7,4,108,97,110,103,1,5,119,105, + 100,116,104,2,94,10,119,105,100,103,101,116,110,97,109,101,6,4,108,97, + 110,103,9,100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109, + 115,101,115,116,114,105,110,103,100,97,116,97,108,105,115,116,0,7,3,100, + 105,114,1,5,119,105,100,116,104,3,71,2,7,111,112,116,105,111,110,115, + 11,7,99,111,95,102,105,108,108,12,99,111,95,115,97,118,101,118,97,108, + 117,101,0,10,119,105,100,103,101,116,110,97,109,101,6,3,100,105,114,9, + 100,97,116,97,99,108,97,115,115,7,22,116,103,114,105,100,109,115,101,115, + 116,114,105,110,103,100,97,116,97,108,105,115,116,0,0,13,100,97,116,97, + 114,111,119,104,101,105,103,104,116,2,15,8,115,116,97,116,102,105,108,101, + 7,11,112,114,111,106,101,99,116,115,116,97,116,13,111,110,114,111,119,115, + 100,101,108,101,116,101,100,7,11,108,97,110,103,100,101,108,101,116,101,100, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,13,0,11,116,115, + 116,114,105,110,103,101,100,105,116,4,108,97,110,103,14,111,112,116,105,111, + 110,115,119,105,100,103,101,116,49,11,19,111,119,49,95,102,111,110,116,103, + 108,121,112,104,104,101,105,103,104,116,0,12,102,114,97,109,101,46,108,101, + 118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108, + 105,101,110,116,4,2,0,0,128,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102, + 114,108,95,99,111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,8,116,97,98,111, + 114,100,101,114,2,1,7,118,105,115,105,98,108,101,8,8,98,111,117,110, + 100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,2,0,9,98,111, + 117,110,100,115,95,99,120,2,94,9,98,111,117,110,100,115,95,99,121,2, + 15,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,13,0,0,16, + 116,100,105,114,100,114,111,112,100,111,119,110,101,100,105,116,3,100,105,114, + 12,102,114,97,109,101,46,108,101,118,101,108,111,2,0,17,102,114,97,109, + 101,46,99,111,108,111,114,99,108,105,101,110,116,4,2,0,0,128,16,102, + 114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,10,102,114,108, + 95,108,101,118,101,108,111,15,102,114,108,95,99,111,108,111,114,99,108,105, + 101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,18,102,114,97,109,101,46,98,117,116,116,111,110,46,99,111, + 108,111,114,4,2,0,0,128,8,116,97,98,111,114,100,101,114,2,2,7, + 118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,95,8, + 98,111,117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120, + 3,71,2,9,98,111,117,110,100,115,95,99,121,2,15,13,114,101,102,102, + 111,110,116,104,101,105,103,104,116,2,13,0,0,0,9,116,115,112,108,105, + 116,116,101,114,8,115,112,108,105,116,116,101,114,5,99,111,108,111,114,4, + 3,0,0,144,8,116,97,98,111,114,100,101,114,2,8,8,98,111,117,110, + 100,115,95,120,2,0,8,98,111,117,110,100,115,95,121,3,112,1,9,98, + 111,117,110,100,115,95,99,120,3,171,2,9,98,111,117,110,100,115,95,99, + 121,2,3,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,0, + 7,111,112,116,105,111,110,115,11,9,115,112,111,95,118,109,111,118,101,9, + 115,112,111,95,118,112,114,111,112,0,7,108,105,110,107,116,111,112,7,4, + 103,114,105,100,10,108,105,110,107,98,111,116,116,111,109,7,5,103,114,105, + 100,50,0,0,15,116,109,101,109,111,100,105,97,108,111,103,101,100,105,116, + 11,109,97,107,101,99,111,109,109,97,110,100,13,102,114,97,109,101,46,99, + 97,112,116,105,111,110,6,12,77,97,107,101,32,99,111,109,109,97,110,100, + 16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17, + 102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,19, + 102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2, + 1,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109, + 115,14,1,7,105,109,97,103,101,110,114,2,17,0,0,20,102,114,97,109, + 101,46,98,117,116,116,111,110,46,105,109,97,103,101,110,114,2,17,16,102, + 114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,16, + 2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,2,10,111,110,115, + 104,111,119,104,105,110,116,7,11,115,104,111,119,104,105,110,116,101,120,101, + 8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95,121, + 3,144,0,9,98,111,117,110,100,115,95,99,120,3,132,2,9,98,111,117, + 110,100,115,95,99,121,2,35,7,97,110,99,104,111,114,115,11,7,97,110, + 95,108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104, + 116,0,8,115,116,97,116,102,105,108,101,7,11,112,114,111,106,101,99,116, + 115,116,97,116,5,118,97,108,117,101,6,42,36,123,67,79,77,80,73,76, + 69,82,125,32,45,70,117,36,123,77,83,69,76,73,66,68,73,82,125,105, + 49,56,110,32,36,123,76,73,66,70,73,76,69,125,10,111,110,115,101,116, + 118,97,108,117,101,7,19,109,97,107,101,99,111,109,109,97,110,100,115,101, + 116,118,97,108,117,101,13,114,101,102,102,111,110,116,104,101,105,103,104,116, + 2,13,0,0,12,116,98,111,111,108,101,97,110,101,100,105,116,6,109,97, + 107,101,111,110,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6,2, + 111,110,16,102,114,97,109,101,46,99,97,112,116,105,111,110,112,111,115,7, + 6,99,112,95,116,111,112,16,102,114,97,109,101,46,108,111,99,97,108,112, + 114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101,114,102,114, + 97,109,101,1,2,0,2,16,2,1,2,0,0,8,116,97,98,111,114,100, + 101,114,2,3,8,98,111,117,110,100,115,95,120,3,144,2,8,98,111,117, + 110,100,115,95,121,3,149,0,9,98,111,117,110,100,115,95,99,120,2,14, + 9,98,111,117,110,100,115,95,99,121,2,29,7,97,110,99,104,111,114,115, + 11,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116,0,8,115, + 116,97,116,102,105,108,101,7,11,112,114,111,106,101,99,116,115,116,97,116, + 5,118,97,108,117,101,9,0,0,7,116,98,117,116,116,111,110,2,111,107, + 8,116,97,98,111,114,100,101,114,2,7,8,98,111,117,110,100,115,95,120, + 3,46,2,8,98,111,117,110,100,115,95,121,3,217,1,9,98,111,117,110, + 100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2,22,7, + 97,110,99,104,111,114,115,11,8,97,110,95,114,105,103,104,116,9,97,110, + 95,98,111,116,116,111,109,0,5,115,116,97,116,101,11,10,97,115,95,100, + 101,102,97,117,108,116,15,97,115,95,108,111,99,97,108,100,101,102,97,117, + 108,116,15,97,115,95,108,111,99,97,108,99,97,112,116,105,111,110,0,7, + 99,97,112,116,105,111,110,6,2,79,75,11,109,111,100,97,108,114,101,115, + 117,108,116,7,5,109,114,95,111,107,0,0,7,116,98,117,116,116,111,110, + 6,99,97,110,99,101,108,8,98,111,117,110,100,115,95,120,3,110,2,8, + 98,111,117,110,100,115,95,121,3,217,1,9,98,111,117,110,100,115,95,99, + 120,2,50,9,98,111,117,110,100,115,95,99,121,2,22,7,97,110,99,104, + 111,114,115,11,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116, + 116,111,109,0,5,115,116,97,116,101,11,15,97,115,95,108,111,99,97,108, + 99,97,112,116,105,111,110,0,7,99,97,112,116,105,111,110,6,6,67,97, + 110,99,101,108,11,109,111,100,97,108,114,101,115,117,108,116,7,9,109,114, + 95,99,97,110,99,101,108,0,0,11,116,115,116,114,105,110,103,101,100,105, + 116,8,100,101,115,116,110,97,109,101,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,44,68,101,115,116,105,110,97,116,105,111,110,32,66,97, + 115,101,110,97,109,101,32,40,101,109,112,116,121,32,61,32,68,97,116,97, + 102,105,108,101,32,110,97,109,101,41,16,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,49,11,0,16,102,114,97,109,101,46,111,117,116,101, + 114,102,114,97,109,101,1,2,0,2,16,2,0,2,0,0,8,116,97,98, + 111,114,100,101,114,2,9,8,98,111,117,110,100,115,95,120,2,0,8,98, + 111,117,110,100,115,95,121,2,56,9,98,111,117,110,100,115,95,99,120,3, + 171,2,9,98,111,117,110,100,115,95,99,121,2,35,7,97,110,99,104,111, + 114,115,11,6,97,110,95,116,111,112,0,8,115,116,97,116,102,105,108,101, + 7,11,112,114,111,106,101,99,116,115,116,97,116,13,114,101,102,102,111,110, + 116,104,101,105,103,104,116,2,13,0,0,15,116,109,101,109,111,100,105,97, + 108,111,103,101,100,105,116,10,98,101,102,111,114,101,109,97,107,101,13,102, + 114,97,109,101,46,99,97,112,116,105,111,110,6,11,66,101,102,111,114,101, + 32,109,97,107,101,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112, + 115,49,11,0,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,99, + 111,117,110,116,2,1,19,102,114,97,109,101,46,98,117,116,116,111,110,115, + 46,105,116,101,109,115,14,1,7,105,109,97,103,101,110,114,2,17,0,0, + 20,102,114,97,109,101,46,98,117,116,116,111,110,46,105,109,97,103,101,110, + 114,2,17,16,102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101, + 1,2,0,2,16,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2, + 10,10,111,110,115,104,111,119,104,105,110,116,7,11,115,104,111,119,104,105, + 110,116,101,120,101,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117, + 110,100,115,95,121,2,104,9,98,111,117,110,100,115,95,99,120,3,171,2, + 9,98,111,117,110,100,115,95,99,121,2,35,7,97,110,99,104,111,114,115, + 11,6,97,110,95,116,111,112,0,8,115,116,97,116,102,105,108,101,7,11, + 112,114,111,106,101,99,116,115,116,97,116,13,114,101,102,102,111,110,116,104, + 101,105,103,104,116,2,13,0,0,15,116,109,101,109,111,100,105,97,108,111, + 103,101,100,105,116,9,97,102,116,101,114,109,97,107,101,13,102,114,97,109, + 101,46,99,97,112,116,105,111,110,6,10,65,102,116,101,114,32,109,97,107, + 101,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11,0, + 17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0, + 19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116, + 2,1,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101, + 109,115,14,1,7,105,109,97,103,101,110,114,2,17,0,0,20,102,114,97, + 109,101,46,98,117,116,116,111,110,46,105,109,97,103,101,110,114,2,17,16, + 102,114,97,109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2, + 16,2,0,2,0,0,8,116,97,98,111,114,100,101,114,2,11,10,111,110, + 115,104,111,119,104,105,110,116,7,11,115,104,111,119,104,105,110,116,101,120, + 101,8,98,111,117,110,100,115,95,120,2,0,8,98,111,117,110,100,115,95, + 121,3,184,0,9,98,111,117,110,100,115,95,99,120,3,171,2,9,98,111, + 117,110,100,115,95,99,121,2,35,7,97,110,99,104,111,114,115,11,6,97, + 110,95,116,111,112,0,8,115,116,97,116,102,105,108,101,7,11,112,114,111, + 106,101,99,116,115,116,97,116,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,13,0,0,9,116,115,116,97,116,102,105,108,101,11,112,114,111, + 106,101,99,116,115,116,97,116,12,111,110,115,116,97,116,117,112,100,97,116, + 101,7,23,112,114,111,106,101,99,116,115,116,97,116,111,110,117,112,100,97, + 116,101,115,116,97,116,17,111,110,115,116,97,116,98,101,102,111,114,101,119, + 114,105,116,101,7,28,112,114,111,106,101,99,116,115,116,97,116,111,110,98, + 101,102,111,114,101,119,114,105,116,101,115,116,97,116,15,111,110,115,116,97, + 116,97,102,116,101,114,114,101,97,100,7,26,112,114,111,106,101,99,116,115, + 116,97,116,111,110,97,102,116,101,114,114,101,97,100,115,116,97,116,4,108, + 101,102,116,3,128,0,3,116,111,112,2,56,0,0,11,116,102,105,108,101, + 100,105,97,108,111,103,16,105,109,112,101,120,112,102,105,108,101,100,105,97, + 108,111,103,8,115,116,97,116,102,105,108,101,7,11,112,114,111,106,101,99, + 116,115,116,97,116,19,99,111,110,116,114,111,108,108,101,114,46,102,105,108, + 101,110,97,109,101,6,11,100,101,102,97,117,108,116,46,99,115,118,26,99, + 111,110,116,114,111,108,108,101,114,46,102,105,108,116,101,114,108,105,115,116, + 46,100,97,116,97,1,1,6,19,68,97,116,97,32,101,120,99,104,97,110, + 103,101,32,102,105,108,101,115,6,5,42,46,99,115,118,0,0,21,99,111, + 110,116,114,111,108,108,101,114,46,100,101,102,97,117,108,116,101,120,116,6, + 3,99,115,118,26,99,111,110,116,114,111,108,108,101,114,46,104,105,115,116, + 111,114,121,109,97,120,99,111,117,110,116,2,0,22,99,111,110,116,114,111, + 108,108,101,114,46,99,97,112,116,105,111,110,111,112,101,110,6,16,79,112, + 101,110,32,105,109,112,111,114,116,32,102,105,108,101,22,99,111,110,116,114, + 111,108,108,101,114,46,99,97,112,116,105,111,110,115,97,118,101,6,16,83, + 97,118,101,32,101,120,112,111,114,116,32,102,105,108,101,4,108,101,102,116, + 3,240,0,3,116,111,112,2,56,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tprojectfo,''); +end. diff --git a/mseide-msegui/tools/msedirclear.cmd b/mseide-msegui/tools/msedirclear.cmd new file mode 100644 index 0000000..6b29c40 --- /dev/null +++ b/mseide-msegui/tools/msedirclear.cmd @@ -0,0 +1,5 @@ +@echo off +if "%1"=="" @echo A directory must be supplied! & exit -1 +dir /ad %1 +if not %errorlevel% equ 0 (@echo %1 must be an existing directory! & exit -1) +for /R %%F in ("%1") do cd %%F && del *.o 2>nul & del *.ppu 2>nul & del *.a 2>nul & for %%M in (*.mfm) do form2pas %%M diff --git a/mseide-msegui/tools/msedirclear.sh b/mseide-msegui/tools/msedirclear.sh new file mode 100755 index 0000000..f85718d --- /dev/null +++ b/mseide-msegui/tools/msedirclear.sh @@ -0,0 +1,35 @@ +#!/bin/sh + +# Assumes that "/usr/local/bin" contains symlinks to: +# {$mse_dir}/tools/form2pas (shouldn't be renamed!) +# {$mse_dir}/tools/msedirclear.sh (this script) + +[ -z $1 ] && { + echo "A directory must be supplied!" + exit -1 +} + +[ -d $1 ] || { + echo "$1 must be an existing directory!" + exit -1 +} + +DIRS=`for d in \`find $1 -iregex '.*\.\(ppu\|o\|a\|mfm\)' 2>/dev/null\`; +do + tmp=\`dirname $d\` + [ -d $tmp ] && echo -e $tmp +done | sort -ru` + +CURDIR=`pwd` + +for d in $DIRS; do + cd $CURDIR && cd $d 2>/dev/null && { + rm -f -- *.a *.o *.ppu *.A *.O *.PPU + for f in `ls -A1 *.mfm *.MFM 2>/dev/null`; do + [ -f $f ] && form2pas $f + done + } +done + +cd $CURDIR +exit 0 diff --git a/mseide-msegui/tools/unitdep/main.mfm b/mseide-msegui/tools/unitdep/main.mfm new file mode 100644 index 0000000..6353629 --- /dev/null +++ b/mseide-msegui/tools/unitdep/main.mfm @@ -0,0 +1,219 @@ +object mainfo: tmainfo + visible = False + bounds_x = 188 + bounds_y = 220 + bounds_cx = 403 + bounds_cy = 280 + container.frame.localprops = [] + container.frame.localprops1 = [] + container.bounds = ( + 0 + 0 + 403 + 280 + ) + statfile = tstatfile1 + caption = 'MSEunitdep' + windowopacity = -Inf + moduleclassname = 'tmainform' + object filename: tfilenameedit + frame.localprops = [] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + imagenr = 17 + end> + frame.button.color = -2147483646 + frame.button.imagenr = 17 + hint = 'FPC -vu compiler message file' + bounds_x = 1 + bounds_y = 6 + bounds_cx = 344 + anchors = [an_left, an_top, an_right] + statfile = tstatfile1 + textflags = [tf_ycentered, tf_noselect, tf_ellipseleft] + ondataentered = filenamedatentexe + controller.filterlist.data = ( + ( + 'textfiles' + '*.txt' + ) + ) + controller.options = [fdo_checkexist, fdo_savelastdir] + reffontheight = 14 + end + object tbutton1: tbutton + taborder = 1 + bounds_x = 349 + bounds_y = 7 + bounds_cx = 50 + bounds_cy = 19 + anchors = [an_top, an_right] + state = [as_localcaption, as_localonexecute] + caption = '&scan' + onexecute = scanexe + end + object grid: twidgetgrid + frame.localprops = [] + frame.localprops1 = [] + taborder = 2 + bounds_x = 1 + bounds_y = 31 + bounds_cx = 401 + bounds_cy = 186 + anchors = [an_left, an_top, an_right, an_bottom] + fixrows.count = 1 + fixrows.items = < + item + height = 16 + captions.count = 1 + captions.items = < + item + end> + end> + datacols.count = 1 + datacols.items = < + item[treeedit] + width = 396 + options = [co_readonly, co_fill, co_savevalue, co_savestate, co_mousescrollrow] + widgetname = 'treeedit' + dataclass = ttreeitemeditlist + end> + datarowlinewidth = 0 + datarowheight = 16 + reffontheight = 14 + object treeedit: ttreeitemedit + optionsskin = [osk_framebuttononly] + frame.levelo = 0 + frame.colorclient = -2147483645 + frame.localprops = [frl_levelo, frl_leveli, frl_colorclient] + frame.localprops1 = [] + taborder = 1 + visible = False + bounds_x = 0 + bounds_y = 0 + bounds_cx = 396 + bounds_cy = 16 + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_locate] + options = [teo_treecolnavig] + reffontheight = 14 + end + end + object start: tdropdownlistedit + frame.caption = 'Start Unit' + frame.localprops = [] + frame.localprops1 = [] + frame.button.color = -2147483646 + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + end> + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 3 + bounds_x = 1 + bounds_y = 218 + bounds_cx = 198 + bounds_cy = 37 + anchors = [an_left, an_bottom] + statfile = tstatfile1 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_forcereturncheckvalue, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly] + ondataentered = pathdatentexe + ifilink = dropdownunits + dropdown.options = [deo_selectonly, deo_autodropdown, deo_keydropdown, deo_cliphint] + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + reffontheight = 14 + end + object dest: tdropdownlistedit + frame.caption = 'Dest. Unit' + frame.localprops = [] + frame.localprops1 = [] + frame.button.color = -2147483646 + frame.buttons.count = 1 + frame.buttons.items = < + item + color = -2147483646 + end> + frame.outerframe = ( + 0 + 17 + 0 + 0 + ) + taborder = 4 + bounds_x = 202 + bounds_y = 218 + bounds_cx = 201 + bounds_cy = 37 + anchors = [an_left, an_right, an_bottom] + statfile = tstatfile1 + optionsedit = [oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_forcereturncheckvalue, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly] + ondataentered = pathdatentexe + ifilink = dropdownunits + dropdown.options = [deo_selectonly, deo_autodropdown, deo_keydropdown, deo_cliphint] + dropdown.cols.count = 1 + dropdown.cols.items = < + item + end> + reffontheight = 14 + end + object pathdisp: tmemodialogedit + frame.levelo = -1 + frame.colorclient = -1879048184 + frame.localprops = [frl_levelo, frl_colorclient] + frame.localprops1 = [] + frame.buttons.count = 1 + frame.buttons.items = < + item + imagenr = 17 + end> + frame.button.imagenr = 17 + taborder = 5 + bounds_x = 1 + bounds_y = 259 + bounds_cx = 401 + bounds_cy = 18 + anchors = [an_left, an_right, an_bottom] + optionsedit1 = [oe1_autopopupmenu, oe1_keyexecute, oe1_readonlydialog, oe1_savevalue, oe1_savestate, oe1_checkvalueafterstatread] + optionsedit = [oe_readonly, oe_undoonesc, oe_closequery, oe_checkmrcancel, oe_shiftreturn, oe_eatreturn, oe_resetselectonexit, oe_exitoncursor, oe_endonenter, oe_autoselect, oe_autoselectonfirstclick, oe_focusrectonreadonly, oe_hintclippedtext] + reffontheight = 14 + end + object tsplitter1: tsplitter + color = -1879048189 + taborder = 6 + visible = False + bounds_x = 199 + bounds_y = 234 + bounds_cx = 3 + bounds_cy = 20 + options = [spo_hprop, spo_dockleft, spo_docktop, spo_dockright, spo_dockbottom] + linkleft = start + linkright = dest + end + object tstatfile1: tstatfile + filename = 'mseunitdep.sta' + filedir = '"^/.mseide"' + options = [sfo_createpath, sfo_transaction, sfo_activatorread, sfo_activatorwrite] + left = 16 + top = 8 + end + object dropdownunits: tifidropdownlistlinkcomp + controller.optionsvalue = [vco_nosync] + controller.dropdown.cols.count = 1 + controller.dropdown.cols.items = < + item + end> + left = 32 + top = 72 + end +end diff --git a/mseide-msegui/tools/unitdep/main.pas b/mseide-msegui/tools/unitdep/main.pas new file mode 100644 index 0000000..4767c96 --- /dev/null +++ b/mseide-msegui/tools/unitdep/main.pas @@ -0,0 +1,582 @@ +{ MSEide Copyright (c) 2011-2013 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +unit main; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +interface +uses + mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui, + msegraphics,msegraphutils,mseevent,mseclasses,mseforms,msestatfile,msebitmap, + msedataedits,msedatanodes,mseedit,msefiledialog,msegrids,mseifiglob, + mselistbrowser,msestrings,msesys,msetypes,msesimplewidgets,msewidgets, + msewidgetgrid,mselist,classes,mclasses,mseificomp,mseificompglob,msedispwidgets, + msesplitter,msevaluenodes,msememodialog; + +type + tdependencylist = class; + tunitdependencynode = class(trecordtreelistedititem) + private +// frecursion: msestring; + flist: tdependencylist; + fsubitemschecked: boolean; + protected + procedure actionnotification(var ainfo: nodeactioninfoty); override; + public + constructor create(const alist: tdependencylist); + end; + + dependencyinfoty = record + name: string; + depend: string; + checked: boolean; + end; + pdependencyinfoty = ^dependencyinfoty; + dependencyinfoaty = array [0..0] of dependencyinfoty; + pdependencyinfoaty = ^dependencyinfoaty; + + tdependencylist = class(trecordmap) + private + fapplication: string; + protected + function comparename(const l,r): integer; + function comparedep(const l,r): integer; + procedure finalizerecord(var item); override; + procedure copyrecord(var item); override; + procedure resetchecked(); + public + constructor create; + procedure parse(const afilename: filenamety); +// function gettoplevelnodes: treelistedititemarty; + function getnodes(const aname: string): treelistedititemarty; +// function getdependencytree: ttreelistedititem; + function find(const aname: string; out aindex: integer): pdependencyinfoty; + function finddep(const adepend: string; out aindex: integer): pdependencyinfoty; + function getunitnames: msestringarty; + function findpath(const astart,adest: string): msestringarty; + //dest = '' -> find first start + function finddependnames(const aname: string): msestringarty; + end; + + tmainfo = class(tmainform) + tstatfile1: tstatfile; + filename: tfilenameedit; + tbutton1: tbutton; + grid: twidgetgrid; + treeedit: ttreeitemedit; + dropdownunits: tifidropdownlistlinkcomp; + start: tdropdownlistedit; + dest: tdropdownlistedit; + pathdisp: tmemodialogedit; + tsplitter1: tsplitter; + procedure scanexe(const sender: TObject); + procedure pathdatentexe(const sender: TObject); + procedure filenamedatentexe(const sender: TObject); + private + flist: tdependencylist; + protected + public + constructor create(aowner: tcomponent); override; + destructor destroy; override; + end; + +var + mainfo: tmainfo; + +implementation + +uses + main_mfm,msestream,strutils,msedatalist,msearrayutils; +type + ttreelistitem1 = class(ttreelistitem); + +constructor tmainfo.create(aowner: tcomponent); +begin + flist:= tdependencylist.create; + inherited; +end; + +destructor tmainfo.destroy; +begin + inherited; + flist.free; +end; + +procedure tmainfo.scanexe(const sender: TObject); +var +// ar1: treelistedititemarty; + str1,str2: msestring; +begin + flist.parse(filename.value); + with treeedit.itemlist do begin + clear; + add(flist.getnodes(flist.fapplication)); + end; + grid.fixrows[-1].captions[0].caption:= msestring(flist.fapplication); + str1:= start.value; + str2:= dest.value; + dropdownunits.controller.dropdown.cols[0].asarray:= flist.getunitnames; + start.value:= str1; + dest.value:= str2; + pathdatentexe(nil); +end; + +procedure tmainfo.pathdatentexe(const sender: TObject); +begin + if (start.value <> '') or (dest.value <> '') then begin + if dest.value = '' then begin + pathdisp.value:= concatstrings( + flist.finddependnames(ansistring(start.value)),':'); + end + else begin + if start.value = '' then begin + pathdisp.value:= concatstrings( + flist.finddependnames(ansistring(dest.value)),':'); + end + else begin + pathdisp.value:= concatstrings(flist.findpath(ansistring(start.value), + ansistring(dest.value)),','); + end; + end; + end + else begin + pathdisp.value:= ''; + end; +end; + +procedure tmainfo.filenamedatentexe(const sender: TObject); +begin + treeedit.itemlist.clear; + pathdisp.value:= ''; +end; + +{ tdependencylist } + +constructor tdependencylist.create; +begin + inherited create(sizeof(dependencyinfoty), + [rels_needsinitialize,rels_needsfinalize,rels_needscopy]); + setcomparefuncs([@comparename,@comparedep]); +end; + +procedure tdependencylist.finalizerecord(var item); +begin + finalize(dependencyinfoty(item)); +end; + +procedure tdependencylist.copyrecord(var item); +begin + with dependencyinfoty(item) do begin + stringaddref(name); + stringaddref(depend); + end; +end; + +procedure tdependencylist.parse(const afilename: filenamety); +var + stream1: ttextstream; + str1: string; + int1,int2: integer; + info1: dependencyinfoty; + name1{,depend1}: string; + b1: boolean; + i1: int32; +begin + stream1:= ttextstream.create(afilename); + try + clear; + while not stream1.eof do begin + stream1.readln(str1); + if str1 <> '' then begin + if str1[1] = '(' then begin + int1:= pos(')',str1); + if int1 > 0 then begin + name1:= struppercase(copy(str1,2,int1-2)); + if (fapplication = '') and + (name1 <> 'PROGRAM') and (name1 <> 'SYSTEM') then begin + b1:= false; + for i1:= 1 to high(name1) do begin + if (name1[i1] < '0') or (name1[i1] > '9') then begin + b1:= true; + break; + end; + end; + if b1 then begin + fapplication:= name1; + end; + end; + if name1 = fapplication then begin + int2:= posex(' Load from ',str1,int1); + if int2 >= int1+1 then begin + info1.name:= name1; + info1.depend:= copy(str1,findlastchar(str1,' ')+1,bigint); + add(info1); + end; + end + else begin + int2:= posex(' Load from ',str1,int1); + if int2 >= int1+1 then begin + info1.name:= name1; + info1.depend:= copy(str1,findlastchar(str1,' ')+1,bigint); + if stringicomp(info1.name,info1.depend) <> 0 then begin + add(info1); + end; + end + else begin + int2:= posex(' depends on ',str1,int1); //FPC 2.6 + if int2 > 0 then begin + info1.name:= name1; + info1.depend:= copy(str1,int2+12,bigint); + add(info1); + end + else begin + int2:= posex(' Add dependency of ',str1,int1); //FPC 2.4 + if int2 > 0 then begin + info1.name:= name1; + info1.depend:= copy(str1,findlastchar(str1,' ')+1,bigint); + add(info1); + end + end; + end; + end; +// } + end; + end; + end; + end; +// sorted:= true; + finally + stream1.free; + end; +end; + +function tdependencylist.comparename(const l; const r): integer; +begin + with dependencyinfoty(l) do begin + result:= stringcomp(name,dependencyinfoty(r).name); + if result = 0 then begin + result:= stringcomp(depend,dependencyinfoty(r).depend); + end; + end; +end; + +function tdependencylist.comparedep(const l; const r): integer; +begin + with dependencyinfoty(l) do begin + result:= stringcomp(depend,dependencyinfoty(r).depend); + if result = 0 then begin + result:= stringcomp(name,dependencyinfoty(r).name); + end; + end; +end; + +(* +function tdependencylist.getdependencytree: ttreelistedititem; +var + pend: pdependencyinfoty; + + procedure loadnode(const aparent: ttreelistedititem; + start: pdependencyinfoty; + out aend: pdependencyinfoty); + var + str1: string; + mstr1: msestring; + n1: ttreelistitem; + n2: tunitdependencynode; + begin + if start <> nil then begin + n2:= tunitdependencynode.create; + str1:= start^.name; + mstr1:= str1; + n2.caption:= mstr1; + aparent.add(n2); + n1:= aparent; + while (n1 <> nil) and ((n1.caption) <> mstr1) do begin + n1:= n1.parent; + end; + if (n1 <> nil) and (n1.parent <> nil) then begin + n2.frecursion:= n1.parent.caption; + end + else begin + while (start < pend) and (start^.name = str1) do begin + loadnode(n2,find(start^.depend),aend); + inc(start); + end; + end; + end; + aend:= start; + end; + +var + po1: pdependencyinfoty; +begin + result:= ttreelistedititem.create; + po1:= datapo; + pend:= dataend; + repeat + loadnode(result,po1,po1); + until po1 >= pend; +end; +*) + +function tdependencylist.find(const aname: string; + out aindex: integer): pdependencyinfoty; +var + info1: dependencyinfoty; +begin + result:= nil; + info1.name:= aname; + internalfind(0,info1,aindex,result); + if (result <> nil) and (result^.name <> aname) then begin + result:= nil; + end; +end; + +function tdependencylist.finddep(const adepend: string; + out aindex: integer): pdependencyinfoty; +var + info1: dependencyinfoty; +begin + result:= nil; + info1.depend:= adepend; + internalfind(1,info1,aindex,result); + if (result <> nil) and (result^.depend <> adepend) then begin + result:= nil; + end; +end; +{ +function tdependencylist.gettoplevelnodes: treelistedititemarty; +var + count1: integer; + po1: pdependencyinfoty; + n1: tunitdependencynode; + ar1: pointerarty; + int1: integer; +begin + result:= nil; + order:= 0; + find(fapplication,int1); + if int1 >= 0 then begin + count1:= 0; + ar1:= findexes[0]; + while (int1 < fcount) do begin + with pdependencyinfoty(ar1[int1])^ do begin + if name <> fapplication then begin + break; + end; + n1:= tunitdependencynode.create(self); + n1.caption:= depend; + additem(pointerarty(result),pointer(n1),count1); + inc(int1); + end; + end; + setlength(result,count1); + end; +end; +} +function tdependencylist.getnodes(const aname: string): treelistedititemarty; +var + count1: integer; +// po1: pdependencyinfoty; + n1: tunitdependencynode; + ar1: pointerarty; + int1: integer; + dep1: string; +begin + result:= nil; + order:= 0; + find(aname,int1); + if int1 >= 0 then begin + count1:= 0; + ar1:= findexes[0]; + dep1:= ''; + while (int1 < fcount) do begin + with pdependencyinfoty(ar1[int1])^ do begin + if name <> aname then begin + break; + end; + if depend <> dep1 then begin + dep1:= depend; + n1:= tunitdependencynode.create(self); + n1.caption:= msestring(depend); + additem(pointerarty(result),pointer(n1),count1); + end; + inc(int1); + end; + end; + setlength(result,count1); + end; +end; + +function tdependencylist.getunitnames: msestringarty; +var + int1,int2: integer; + str1: string; + ar1: pointerarty; +begin + setlength(result,fcount); //max + int2:= 0; + ar1:= findexes[0]; + str1:= ''; + for int1:= 0 to fcount - 1 do begin + if str1 <> pdependencyinfoty(ar1[int1])^.name then begin + str1:= pdependencyinfoty(ar1[int1])^.name; + result[int2]:= msestring(str1); + inc(int2); + end; + end; + setlength(result,int2); +end; + +function tdependencylist.finddependnames(const aname: string): msestringarty; +var + po1,po2: pdependencyinfoty; + i1,i2: int32; + name1: string; + ar1: msestringarty; +begin + result:= nil; + po1:= finddep(aname,i1); + if po1 <> nil then begin + name1:= ''; + while i1 < count do begin + po1:= findexes[1][i1]; + if po1^.depend <> aname then begin + break; + end; + if po1^.name <> name1 then begin + name1:= po1^.name; + resetchecked(); + ar1:= nil; + po2:= po1; + repeat + additem(ar1,msestring(po2^.depend)); + po2^.checked:= true; + po2:= finddep(po2^.name,i2); + until (po2 = nil) or po2^.checked or (po2^.name = fapplication); + if po2 <> nil then begin + additem(result,concatstrings(ar1,',')); + end; + end; + inc(i1); + end; + end; +end; + +procedure tdependencylist.resetchecked(); +var + po1,po2: pdependencyinfoty; +begin + po1:= datapo; + po2:= dataend; + while po1 < po2 do begin + po1^.checked:= false; + inc(po1); + end; +end; + +function tdependencylist.findpath(const astart: string; + const adest: string): msestringarty; +var + destar1: stringarty; + maxlevel: integer; + maxlevelfound: boolean; + + function find1(const aname: string; const alevel: integer): boolean; + var +// po1: pdependencyinfoty; + int1: integer; +// str1: string; + begin + result:= aname = adest; + if not result then begin + if find(aname,int1) <> nil then begin + if alevel > maxlevel then begin + maxlevelfound:= true; + exit; + end; + while int1 < fcount do begin + with pdependencyinfoty(findexes[0][int1])^ do begin + if (name <> aname) or checked then begin + break; + end; + checked:= true; + result:= find1(depend,alevel+1); + if result then begin + break; + end; + inc(int1); + end; + end; + end; + end; + if result then begin + additem(destar1,aname); + end; + end; +var + int1,int2: integer; +begin + result:= nil; + maxlevel:= 0; + repeat + resetchecked(); + maxlevelfound:= false; + if find1(astart,0) then begin + setlength(result,length(destar1)); + int2:= 0; + for int1:= high(destar1) downto 0 do begin + result[int2]:= msestring(destar1[int1]); + inc(int2); + end; + break; + end; + inc(maxlevel); + until not maxlevelfound; +end; + +{ tunitdependencynode } + +constructor tunitdependencynode.create(const alist: tdependencylist); +begin + flist:= alist; + inherited create; + include(fstate,ns_subitems); +end; + +procedure tunitdependencynode.actionnotification(var ainfo: nodeactioninfoty); +var + int1: integer; + n1,n2: ttreelistitem; +begin + if (ainfo.action = na_expand) and not fsubitemschecked then begin + fsubitemschecked:= true; + add(flist.getnodes(ansistring(caption))); + for int1:= 0 to fcount - 1 do begin + n1:= fitems[int1]; + n2:= n1.parent; + while n2 <> nil do begin + if n2.caption = n1.caption then begin + exclude(tunitdependencynode(n1).fstate,ns_subitems); //recursive + break; + end; + n2:= n2.parent; + end; + end; + end; + inherited; +end; + +end. diff --git a/mseide-msegui/tools/unitdep/main_mfm.pas b/mseide-msegui/tools/unitdep/main_mfm.pas new file mode 100644 index 0000000..89cafa9 --- /dev/null +++ b/mseide-msegui/tools/unitdep/main_mfm.pas @@ -0,0 +1,247 @@ +unit main_mfm; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} + +interface + +implementation +uses + mseclasses,main; + +const + objdata: record size: integer; data: array[0..4585] of byte end = + (size: 4586; data: ( + 84,80,70,48,7,116,109,97,105,110,102,111,6,109,97,105,110,102,111,7, + 118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3,188,0, + 8,98,111,117,110,100,115,95,121,3,220,0,9,98,111,117,110,100,115,95, + 99,120,3,147,1,9,98,111,117,110,100,115,95,99,121,3,24,1,26,99, + 111,110,116,97,105,110,101,114,46,102,114,97,109,101,46,108,111,99,97,108, + 112,114,111,112,115,11,0,27,99,111,110,116,97,105,110,101,114,46,102,114, + 97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,16,99,111, + 110,116,97,105,110,101,114,46,98,111,117,110,100,115,1,2,0,2,0,3, + 147,1,3,24,1,0,8,115,116,97,116,102,105,108,101,7,10,116,115,116, + 97,116,102,105,108,101,49,7,99,97,112,116,105,111,110,6,10,77,83,69, + 117,110,105,116,100,101,112,13,119,105,110,100,111,119,111,112,97,99,105,116, + 121,5,0,0,0,0,0,0,0,128,255,255,15,109,111,100,117,108,101,99, + 108,97,115,115,110,97,109,101,6,9,116,109,97,105,110,102,111,114,109,0, + 13,116,102,105,108,101,110,97,109,101,101,100,105,116,8,102,105,108,101,110, + 97,109,101,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115, + 11,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49, + 11,0,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117, + 110,116,2,1,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105, + 116,101,109,115,14,1,5,99,111,108,111,114,4,2,0,0,128,7,105,109, + 97,103,101,110,114,2,17,0,0,18,102,114,97,109,101,46,98,117,116,116, + 111,110,46,99,111,108,111,114,4,2,0,0,128,20,102,114,97,109,101,46, + 98,117,116,116,111,110,46,105,109,97,103,101,110,114,2,17,4,104,105,110, + 116,6,29,70,80,67,32,45,118,117,32,99,111,109,112,105,108,101,114,32, + 109,101,115,115,97,103,101,32,102,105,108,101,8,98,111,117,110,100,115,95, + 120,2,1,8,98,111,117,110,100,115,95,121,2,6,9,98,111,117,110,100, + 115,95,99,120,3,88,1,7,97,110,99,104,111,114,115,11,7,97,110,95, + 108,101,102,116,6,97,110,95,116,111,112,8,97,110,95,114,105,103,104,116, + 0,8,115,116,97,116,102,105,108,101,7,10,116,115,116,97,116,102,105,108, + 101,49,9,116,101,120,116,102,108,97,103,115,11,12,116,102,95,121,99,101, + 110,116,101,114,101,100,11,116,102,95,110,111,115,101,108,101,99,116,14,116, + 102,95,101,108,108,105,112,115,101,108,101,102,116,0,13,111,110,100,97,116, + 97,101,110,116,101,114,101,100,7,17,102,105,108,101,110,97,109,101,100,97, + 116,101,110,116,101,120,101,26,99,111,110,116,114,111,108,108,101,114,46,102, + 105,108,116,101,114,108,105,115,116,46,100,97,116,97,1,1,6,9,116,101, + 120,116,102,105,108,101,115,6,5,42,46,116,120,116,0,0,18,99,111,110, + 116,114,111,108,108,101,114,46,111,112,116,105,111,110,115,11,14,102,100,111, + 95,99,104,101,99,107,101,120,105,115,116,15,102,100,111,95,115,97,118,101, + 108,97,115,116,100,105,114,0,13,114,101,102,102,111,110,116,104,101,105,103, + 104,116,2,14,0,0,7,116,98,117,116,116,111,110,8,116,98,117,116,116, + 111,110,49,8,116,97,98,111,114,100,101,114,2,1,8,98,111,117,110,100, + 115,95,120,3,93,1,8,98,111,117,110,100,115,95,121,2,7,9,98,111, + 117,110,100,115,95,99,120,2,50,9,98,111,117,110,100,115,95,99,121,2, + 19,7,97,110,99,104,111,114,115,11,6,97,110,95,116,111,112,8,97,110, + 95,114,105,103,104,116,0,5,115,116,97,116,101,11,15,97,115,95,108,111, + 99,97,108,99,97,112,116,105,111,110,17,97,115,95,108,111,99,97,108,111, + 110,101,120,101,99,117,116,101,0,7,99,97,112,116,105,111,110,6,5,38, + 115,99,97,110,9,111,110,101,120,101,99,117,116,101,7,7,115,99,97,110, + 101,120,101,0,0,11,116,119,105,100,103,101,116,103,114,105,100,4,103,114, + 105,100,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,11, + 0,17,102,114,97,109,101,46,108,111,99,97,108,112,114,111,112,115,49,11, + 0,8,116,97,98,111,114,100,101,114,2,2,8,98,111,117,110,100,115,95, + 120,2,1,8,98,111,117,110,100,115,95,121,2,31,9,98,111,117,110,100, + 115,95,99,120,3,145,1,9,98,111,117,110,100,115,95,99,121,3,186,0, + 7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116,6,97,110, + 95,116,111,112,8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116, + 116,111,109,0,13,102,105,120,114,111,119,115,46,99,111,117,110,116,2,1, + 13,102,105,120,114,111,119,115,46,105,116,101,109,115,14,1,6,104,101,105, + 103,104,116,2,16,14,99,97,112,116,105,111,110,115,46,99,111,117,110,116, + 2,1,14,99,97,112,116,105,111,110,115,46,105,116,101,109,115,14,1,0, + 0,0,0,14,100,97,116,97,99,111,108,115,46,99,111,117,110,116,2,1, + 14,100,97,116,97,99,111,108,115,46,105,116,101,109,115,14,7,8,116,114, + 101,101,101,100,105,116,1,5,119,105,100,116,104,3,140,1,7,111,112,116, + 105,111,110,115,11,11,99,111,95,114,101,97,100,111,110,108,121,7,99,111, + 95,102,105,108,108,12,99,111,95,115,97,118,101,118,97,108,117,101,12,99, + 111,95,115,97,118,101,115,116,97,116,101,17,99,111,95,109,111,117,115,101, + 115,99,114,111,108,108,114,111,119,0,10,119,105,100,103,101,116,110,97,109, + 101,6,8,116,114,101,101,101,100,105,116,9,100,97,116,97,99,108,97,115, + 115,7,17,116,116,114,101,101,105,116,101,109,101,100,105,116,108,105,115,116, + 0,0,16,100,97,116,97,114,111,119,108,105,110,101,119,105,100,116,104,2, + 0,13,100,97,116,97,114,111,119,104,101,105,103,104,116,2,16,13,114,101, + 102,102,111,110,116,104,101,105,103,104,116,2,14,0,13,116,116,114,101,101, + 105,116,101,109,101,100,105,116,8,116,114,101,101,101,100,105,116,11,111,112, + 116,105,111,110,115,115,107,105,110,11,19,111,115,107,95,102,114,97,109,101, + 98,117,116,116,111,110,111,110,108,121,0,12,102,114,97,109,101,46,108,101, + 118,101,108,111,2,0,17,102,114,97,109,101,46,99,111,108,111,114,99,108, + 105,101,110,116,4,3,0,0,128,16,102,114,97,109,101,46,108,111,99,97, + 108,112,114,111,112,115,11,10,102,114,108,95,108,101,118,101,108,111,10,102, + 114,108,95,108,101,118,101,108,105,15,102,114,108,95,99,111,108,111,114,99, + 108,105,101,110,116,0,17,102,114,97,109,101,46,108,111,99,97,108,112,114, + 111,112,115,49,11,0,8,116,97,98,111,114,100,101,114,2,1,7,118,105, + 115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,2,0,8,98,111, + 117,110,100,115,95,121,2,0,9,98,111,117,110,100,115,95,99,120,3,140, + 1,9,98,111,117,110,100,115,95,99,121,2,16,11,111,112,116,105,111,110, + 115,101,100,105,116,11,11,111,101,95,114,101,97,100,111,110,108,121,12,111, + 101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101, + 113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99, + 101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101, + 95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115, + 101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111, + 110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101, + 114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97, + 117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99, + 107,22,111,101,95,102,111,99,117,115,114,101,99,116,111,110,114,101,97,100, + 111,110,108,121,9,111,101,95,108,111,99,97,116,101,0,7,111,112,116,105, + 111,110,115,11,16,116,101,111,95,116,114,101,101,99,111,108,110,97,118,105, + 103,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0, + 0,17,116,100,114,111,112,100,111,119,110,108,105,115,116,101,100,105,116,5, + 115,116,97,114,116,13,102,114,97,109,101,46,99,97,112,116,105,111,110,6, + 10,83,116,97,114,116,32,85,110,105,116,16,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,11,0,17,102,114,97,109,101,46,108,111,99, + 97,108,112,114,111,112,115,49,11,0,18,102,114,97,109,101,46,98,117,116, + 116,111,110,46,99,111,108,111,114,4,2,0,0,128,19,102,114,97,109,101, + 46,98,117,116,116,111,110,115,46,99,111,117,110,116,2,1,19,102,114,97, + 109,101,46,98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,5,99, + 111,108,111,114,4,2,0,0,128,0,0,16,102,114,97,109,101,46,111,117, + 116,101,114,102,114,97,109,101,1,2,0,2,17,2,0,2,0,0,8,116, + 97,98,111,114,100,101,114,2,3,8,98,111,117,110,100,115,95,120,2,1, + 8,98,111,117,110,100,115,95,121,3,218,0,9,98,111,117,110,100,115,95, + 99,120,3,198,0,9,98,111,117,110,100,115,95,99,121,2,37,7,97,110, + 99,104,111,114,115,11,7,97,110,95,108,101,102,116,9,97,110,95,98,111, + 116,116,111,109,0,8,115,116,97,116,102,105,108,101,7,10,116,115,116,97, + 116,102,105,108,101,49,11,111,112,116,105,111,110,115,101,100,105,116,11,12, + 111,101,95,117,110,100,111,111,110,101,115,99,13,111,101,95,99,108,111,115, + 101,113,117,101,114,121,16,111,101,95,99,104,101,99,107,109,114,99,97,110, + 99,101,108,14,111,101,95,115,104,105,102,116,114,101,116,117,114,110,24,111, + 101,95,102,111,114,99,101,114,101,116,117,114,110,99,104,101,99,107,118,97, + 108,117,101,12,111,101,95,101,97,116,114,101,116,117,114,110,20,111,101,95, + 114,101,115,101,116,115,101,108,101,99,116,111,110,101,120,105,116,15,111,101, + 95,101,120,105,116,111,110,99,117,114,115,111,114,13,111,101,95,101,110,100, + 111,110,101,110,116,101,114,13,111,101,95,97,117,116,111,115,101,108,101,99, + 116,25,111,101,95,97,117,116,111,115,101,108,101,99,116,111,110,102,105,114, + 115,116,99,108,105,99,107,22,111,101,95,102,111,99,117,115,114,101,99,116, + 111,110,114,101,97,100,111,110,108,121,0,13,111,110,100,97,116,97,101,110, + 116,101,114,101,100,7,13,112,97,116,104,100,97,116,101,110,116,101,120,101, + 7,105,102,105,108,105,110,107,7,13,100,114,111,112,100,111,119,110,117,110, + 105,116,115,16,100,114,111,112,100,111,119,110,46,111,112,116,105,111,110,115, + 11,14,100,101,111,95,115,101,108,101,99,116,111,110,108,121,16,100,101,111, + 95,97,117,116,111,100,114,111,112,100,111,119,110,15,100,101,111,95,107,101, + 121,100,114,111,112,100,111,119,110,12,100,101,111,95,99,108,105,112,104,105, + 110,116,0,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,99,111, + 117,110,116,2,1,19,100,114,111,112,100,111,119,110,46,99,111,108,115,46, + 105,116,101,109,115,14,1,0,0,13,114,101,102,102,111,110,116,104,101,105, + 103,104,116,2,14,0,0,17,116,100,114,111,112,100,111,119,110,108,105,115, + 116,101,100,105,116,4,100,101,115,116,13,102,114,97,109,101,46,99,97,112, + 116,105,111,110,6,10,68,101,115,116,46,32,85,110,105,116,16,102,114,97, + 109,101,46,108,111,99,97,108,112,114,111,112,115,11,0,17,102,114,97,109, + 101,46,108,111,99,97,108,112,114,111,112,115,49,11,0,18,102,114,97,109, + 101,46,98,117,116,116,111,110,46,99,111,108,111,114,4,2,0,0,128,19, + 102,114,97,109,101,46,98,117,116,116,111,110,115,46,99,111,117,110,116,2, + 1,19,102,114,97,109,101,46,98,117,116,116,111,110,115,46,105,116,101,109, + 115,14,1,5,99,111,108,111,114,4,2,0,0,128,0,0,16,102,114,97, + 109,101,46,111,117,116,101,114,102,114,97,109,101,1,2,0,2,17,2,0, + 2,0,0,8,116,97,98,111,114,100,101,114,2,4,8,98,111,117,110,100, + 115,95,120,3,202,0,8,98,111,117,110,100,115,95,121,3,218,0,9,98, + 111,117,110,100,115,95,99,120,3,201,0,9,98,111,117,110,100,115,95,99, + 121,2,37,7,97,110,99,104,111,114,115,11,7,97,110,95,108,101,102,116, + 8,97,110,95,114,105,103,104,116,9,97,110,95,98,111,116,116,111,109,0, + 8,115,116,97,116,102,105,108,101,7,10,116,115,116,97,116,102,105,108,101, + 49,11,111,112,116,105,111,110,115,101,100,105,116,11,12,111,101,95,117,110, + 100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114, + 121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111, + 101,95,115,104,105,102,116,114,101,116,117,114,110,24,111,101,95,102,111,114, + 99,101,114,101,116,117,114,110,99,104,101,99,107,118,97,108,117,101,12,111, + 101,95,101,97,116,114,101,116,117,114,110,20,111,101,95,114,101,115,101,116, + 115,101,108,101,99,116,111,110,101,120,105,116,15,111,101,95,101,120,105,116, + 111,110,99,117,114,115,111,114,13,111,101,95,101,110,100,111,110,101,110,116, + 101,114,13,111,101,95,97,117,116,111,115,101,108,101,99,116,25,111,101,95, + 97,117,116,111,115,101,108,101,99,116,111,110,102,105,114,115,116,99,108,105, + 99,107,22,111,101,95,102,111,99,117,115,114,101,99,116,111,110,114,101,97, + 100,111,110,108,121,0,13,111,110,100,97,116,97,101,110,116,101,114,101,100, + 7,13,112,97,116,104,100,97,116,101,110,116,101,120,101,7,105,102,105,108, + 105,110,107,7,13,100,114,111,112,100,111,119,110,117,110,105,116,115,16,100, + 114,111,112,100,111,119,110,46,111,112,116,105,111,110,115,11,14,100,101,111, + 95,115,101,108,101,99,116,111,110,108,121,16,100,101,111,95,97,117,116,111, + 100,114,111,112,100,111,119,110,15,100,101,111,95,107,101,121,100,114,111,112, + 100,111,119,110,12,100,101,111,95,99,108,105,112,104,105,110,116,0,19,100, + 114,111,112,100,111,119,110,46,99,111,108,115,46,99,111,117,110,116,2,1, + 19,100,114,111,112,100,111,119,110,46,99,111,108,115,46,105,116,101,109,115, + 14,1,0,0,13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14, + 0,0,15,116,109,101,109,111,100,105,97,108,111,103,101,100,105,116,8,112, + 97,116,104,100,105,115,112,12,102,114,97,109,101,46,108,101,118,101,108,111, + 2,255,17,102,114,97,109,101,46,99,111,108,111,114,99,108,105,101,110,116, + 4,8,0,0,144,16,102,114,97,109,101,46,108,111,99,97,108,112,114,111, + 112,115,11,10,102,114,108,95,108,101,118,101,108,111,15,102,114,108,95,99, + 111,108,111,114,99,108,105,101,110,116,0,17,102,114,97,109,101,46,108,111, + 99,97,108,112,114,111,112,115,49,11,0,19,102,114,97,109,101,46,98,117, + 116,116,111,110,115,46,99,111,117,110,116,2,1,19,102,114,97,109,101,46, + 98,117,116,116,111,110,115,46,105,116,101,109,115,14,1,7,105,109,97,103, + 101,110,114,2,17,0,0,20,102,114,97,109,101,46,98,117,116,116,111,110, + 46,105,109,97,103,101,110,114,2,17,8,116,97,98,111,114,100,101,114,2, + 5,8,98,111,117,110,100,115,95,120,2,1,8,98,111,117,110,100,115,95, + 121,3,3,1,9,98,111,117,110,100,115,95,99,120,3,145,1,9,98,111, + 117,110,100,115,95,99,121,2,18,7,97,110,99,104,111,114,115,11,7,97, + 110,95,108,101,102,116,8,97,110,95,114,105,103,104,116,9,97,110,95,98, + 111,116,116,111,109,0,12,111,112,116,105,111,110,115,101,100,105,116,49,11, + 17,111,101,49,95,97,117,116,111,112,111,112,117,112,109,101,110,117,14,111, + 101,49,95,107,101,121,101,120,101,99,117,116,101,18,111,101,49,95,114,101, + 97,100,111,110,108,121,100,105,97,108,111,103,13,111,101,49,95,115,97,118, + 101,118,97,108,117,101,13,111,101,49,95,115,97,118,101,115,116,97,116,101, + 27,111,101,49,95,99,104,101,99,107,118,97,108,117,101,97,102,116,101,114, + 115,116,97,116,114,101,97,100,0,11,111,112,116,105,111,110,115,101,100,105, + 116,11,11,111,101,95,114,101,97,100,111,110,108,121,12,111,101,95,117,110, + 100,111,111,110,101,115,99,13,111,101,95,99,108,111,115,101,113,117,101,114, + 121,16,111,101,95,99,104,101,99,107,109,114,99,97,110,99,101,108,14,111, + 101,95,115,104,105,102,116,114,101,116,117,114,110,12,111,101,95,101,97,116, + 114,101,116,117,114,110,20,111,101,95,114,101,115,101,116,115,101,108,101,99, + 116,111,110,101,120,105,116,15,111,101,95,101,120,105,116,111,110,99,117,114, + 115,111,114,13,111,101,95,101,110,100,111,110,101,110,116,101,114,13,111,101, + 95,97,117,116,111,115,101,108,101,99,116,25,111,101,95,97,117,116,111,115, + 101,108,101,99,116,111,110,102,105,114,115,116,99,108,105,99,107,22,111,101, + 95,102,111,99,117,115,114,101,99,116,111,110,114,101,97,100,111,110,108,121, + 18,111,101,95,104,105,110,116,99,108,105,112,112,101,100,116,101,120,116,0, + 13,114,101,102,102,111,110,116,104,101,105,103,104,116,2,14,0,0,9,116, + 115,112,108,105,116,116,101,114,10,116,115,112,108,105,116,116,101,114,49,5, + 99,111,108,111,114,4,3,0,0,144,8,116,97,98,111,114,100,101,114,2, + 6,7,118,105,115,105,98,108,101,8,8,98,111,117,110,100,115,95,120,3, + 199,0,8,98,111,117,110,100,115,95,121,3,234,0,9,98,111,117,110,100, + 115,95,99,120,2,3,9,98,111,117,110,100,115,95,99,121,2,20,7,111, + 112,116,105,111,110,115,11,9,115,112,111,95,104,112,114,111,112,12,115,112, + 111,95,100,111,99,107,108,101,102,116,11,115,112,111,95,100,111,99,107,116, + 111,112,13,115,112,111,95,100,111,99,107,114,105,103,104,116,14,115,112,111, + 95,100,111,99,107,98,111,116,116,111,109,0,8,108,105,110,107,108,101,102, + 116,7,5,115,116,97,114,116,9,108,105,110,107,114,105,103,104,116,7,4, + 100,101,115,116,0,0,9,116,115,116,97,116,102,105,108,101,10,116,115,116, + 97,116,102,105,108,101,49,8,102,105,108,101,110,97,109,101,6,14,109,115, + 101,117,110,105,116,100,101,112,46,115,116,97,7,102,105,108,101,100,105,114, + 6,11,34,94,47,46,109,115,101,105,100,101,34,7,111,112,116,105,111,110, + 115,11,14,115,102,111,95,99,114,101,97,116,101,112,97,116,104,15,115,102, + 111,95,116,114,97,110,115,97,99,116,105,111,110,17,115,102,111,95,97,99, + 116,105,118,97,116,111,114,114,101,97,100,18,115,102,111,95,97,99,116,105, + 118,97,116,111,114,119,114,105,116,101,0,4,108,101,102,116,2,16,3,116, + 111,112,2,8,0,0,24,116,105,102,105,100,114,111,112,100,111,119,110,108, + 105,115,116,108,105,110,107,99,111,109,112,13,100,114,111,112,100,111,119,110, + 117,110,105,116,115,23,99,111,110,116,114,111,108,108,101,114,46,111,112,116, + 105,111,110,115,118,97,108,117,101,11,10,118,99,111,95,110,111,115,121,110, + 99,0,30,99,111,110,116,114,111,108,108,101,114,46,100,114,111,112,100,111, + 119,110,46,99,111,108,115,46,99,111,117,110,116,2,1,30,99,111,110,116, + 114,111,108,108,101,114,46,100,114,111,112,100,111,119,110,46,99,111,108,115, + 46,105,116,101,109,115,14,1,0,0,4,108,101,102,116,2,32,3,116,111, + 112,2,72,0,0,0) + ); + +initialization + registerobjectdata(@objdata,tmainfo,''); +end. diff --git a/mseide-msegui/tools/unitdep/mseunitdep.pas b/mseide-msegui/tools/unitdep/mseunitdep.pas new file mode 100644 index 0000000..b4e0f64 --- /dev/null +++ b/mseide-msegui/tools/unitdep/mseunitdep.pas @@ -0,0 +1,28 @@ +{ MSEtools Copyright (c) 2011-2014 by Martin Schreiber + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} +program mseunitdep; +{$ifdef FPC}{$mode objfpc}{$h+}{$endif} +{$ifdef FPC} + {$ifdef mswindows}{$apptype gui}{$endif} +{$endif} +uses + {$ifdef FPC}{$ifdef unix}cthreads,{$endif}{$endif} + msegui,mseforms,main; +begin + application.createform(tmainfo,mainfo); + application.run; +end. diff --git a/mseide-msegui/tools/unitdep/mseunitdep.prj b/mseide-msegui/tools/unitdep/mseunitdep.prj new file mode 100644 index 0000000..281f9b4 --- /dev/null +++ b/mseide-msegui/tools/unitdep/mseunitdep.prj @@ -0,0 +1,1120 @@ +[componentpalette] +order0=0 +order1=0 +order2=0 +order3=0 +order4=0 +order5=0 +order6=0 +order7=0 +order8=0 +order9=0 +order10=0 +order11=0 +order12=0 +order13=0 +order14=0 +order15=0 +order16=0 +[projectoptions] +projectdir=/f:/proj/mseide-msegui/tools/unitdep +projectfilename=/f:/proj/mseide-msegui/tools/unitdep/mseunitdep.prj +options=110 + [projectoptionsfo.toolshortcuts] + dropdowncolwidths=3 + 70 + 70 + 70 + [projectoptionsfo.twidgetgrid3] + propcolwidthref=726 + sortdescend0=0 + sortdescend1=0 + sortdescend2=0 + sortdescend3=0 + width4=97 + sortdescend4=0 + width5=78 + sortdescend5=0 + width6=50 + sortdescend6=0 + width7=50 + sortdescend7=0 + width8=101 + sortdescend8=0 + width9=296 + sortdescend9=0 + [projectoptionsfo.twidgetgrid4] + propcolwidthref=550 + width0=96 + sortdescend0=0 + sortdescend1=0 + width2=73 + sortdescend2=0 + width3=263 + sortdescend3=0 + width4=277 + sortdescend4=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=15 + [projectoptionsfo.newfile] + firsttab=0 + index=0 + [projectoptionsfo.fontaliasgrid] + propcolwidthref=389 + width0=98 + sortdescend0=0 + width1=378 + sortdescend1=0 + width2=50 + sortdescend2=0 + width3=50 + sortdescend3=0 + width4=50 + sortdescend4=0 + width5=50 + sortdescend5=0 + width6=70 + sortdescend6=0 + [projectoptionsfo.macrosplitter] + x=0 + y=121 + xprop=1 + yprop=0.23846153846154 + [projectoptionsfo.macrogrid] + propcolwidthref=533 + sortdescend0=0 + sortdescend1=0 + sortdescend2=0 + sortdescend3=0 + sortdescend4=0 + sortdescend5=0 + width6=146 + sortdescend6=0 + width7=521 + sortdescend7=0 + [projectoptionsfo.makegroupbox] + firsttab=0 + index=1 + [projectoptionsfo.exceptionsgrid] + propcolwidthref=710 + width0=47 + sortdescend0=0 + width1=704 + sortdescend1=0 + [projectoptionsfo.ttabwidget1] + firsttab=0 + index=0 + [projectoptionsfo.grid] + propcolwidthref=511 + width0=219 + sortdescend0=0 + width1=504 + sortdescend1=0 + [projectoptionsfo.filefiltergrid] + propcolwidthref=618 + width0=112 + sortdescend0=0 + width1=611 + sortdescend1=0 + [projectoptionsfo.ttabwidget2] + firsttab=0 + index=0 + [projectoptionsfo.tabwidget] + firsttab=0 + index=2 + [projectoptionsfo] + stackedunder= + x=19 + y=122 + cx=759 + cy=568 +mainfile=${projectname}.pas +targetfile=${projectname}${exeext} +messageoutputfile= +makecommand=${COMPILER} +makedir= +unitdirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR + ${MSELIBDIR}kernel/ + ${MSELIBDIR}*/ +unitpref=-Fu +incpref=-Fi +libpref=-Fl +objpref=-Fo +targpref=-o +befcommand=0 +aftcommand=0 +makeoptions=4 + -l -Mobjfpc -Sh -Fcutf8 + -gl -gh + -B + -OG2p3 -XX -Xs +codetemplatedirs=1 + ${TEMPLATEDIR} +toolmenus=0 +toolfiles=0 +toolparams=0 +fontnames=0 +scriptbeforecopy= +scriptaftercopy= +newprojectfiles=4 + ${TEMPLATEDIR}default/project.pas + ${TEMPLATEDIR}default/main.pas + ${TEMPLATEDIR}default/main.mfm + ${TEMPLATEDIR}default/main_mfm.pas +newprojectfilesdest=4 + ${%PROJECTNAME%}.pas + + + +newfinames=3 + Program + Unit + Textfile +newfifilters=3 + "*.pas" "*.pp" + "*.pas" "*.pp" + +newfiexts=3 + pas + pas + +newfisources=3 + ${TEMPLATEDIR}default/program.pas + ${TEMPLATEDIR}default/unit.pas + +newfonames=11 + Mainform + Simple Form + Docking Form + Datamodule + Subform + Scrollboxform + Tabform + Dockpanel + Report + Scriptform + Inherited Form +newfonamebases=11 + form + form + form + module + form + form + form + form + report + script + form +newfosources=11 + ${TEMPLATEDIR}default/mainform.pas + ${TEMPLATEDIR}default/simpleform.pas + ${TEMPLATEDIR}default/dockingform.pas + ${TEMPLATEDIR}default/datamodule.pas + ${TEMPLATEDIR}default/subform.pas + ${TEMPLATEDIR}default/scrollboxform.pas + ${TEMPLATEDIR}default/tabform.pas + ${TEMPLATEDIR}default/dockpanelform.pas + ${TEMPLATEDIR}default/report.pas + ${TEMPLATEDIR}default/pascform.pas + ${TEMPLATEDIR}default/inheritedform.pas +newfoforms=11 + ${TEMPLATEDIR}default/mainform.mfm + ${TEMPLATEDIR}default/simpleform.mfm + ${TEMPLATEDIR}default/dockingform.mfm + ${TEMPLATEDIR}default/datamodule.mfm + ${TEMPLATEDIR}default/subform.mfm + ${TEMPLATEDIR}default/scrollboxform.mfm + ${TEMPLATEDIR}default/tabform.mfm + ${TEMPLATEDIR}default/dockpanelform.mfm + ${TEMPLATEDIR}default/report.mfm + ${TEMPLATEDIR}default/pascform.mfm + ${TEMPLATEDIR}default/inheritedform.mfm +forcezorder=0 +stripmessageesc=0 +copymessages=0 +closemessages=1 +checkmethods=1 +colorerror=-1610612712 +colorwarning=-1610612717 +colornote=-1610612716 +usercolors=30 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +usercolorcomment=30 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +formatmacronames=0 +formatmacrovalues=0 +settingsfile= +settingseditor=0 +settingsdebugger=0 +settingsstorage=0 +settingsprojecttree=0 +settingsautoload=0 +settingsautosave=0 +modulenames=1 + MAINFO +moduletypes=1 + TMAINFO +modulefiles=1 + /f:/proj/mseide-msegui/tools/unitdep/main.mfm +befcommandon=0 +makeoptionson=4 + 63 + 31 + 34 + 32 +aftcommandon=0 +unitdirson=3 + 65599 + 196671 + 65599 +macroon=0 +macronames=0 +macrovalues=0 +macrogroup=0 +groupcomments=6 + + + + + + +toolsave=0 +toolhide=0 +toolparse=0 +toolmessages=0 +toolshortcuts=0 +fontalias=0 +fontancestors=0 +fontheights=0 +fontwidths=0 +fontoptions=0 +fontxscales=0 +expandprojectfilemacros=4 + 1 + 1 + 1 + 0 +loadprojectfile=4 + 1 + 1 + 1 + 0 +newinheritedforms=11 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + -1 +uid=0 +sourcefilemasks=3 + "*.pas" "*.dpr" "*.lpr" "*.pp" "*.inc" + "*.c" "*.cc" "*.h" + "*.mfm" +syntaxdeffiles=3 + ${SYNTAXDEFDIR}pascal.sdef + ${SYNTAXDEFDIR}cpp.sdef + ${SYNTAXDEFDIR}objecttext.sdef +filemasknames=3 + Source + Forms + All Files +filemasks=3 + "*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + *.mfm + * +showgrid=1 +snaptogrid=1 +moveonfirstclick=1 +noformdesignerdocking=0 +gridsizex=8 +gridsizey=8 +autoindent=1 +blockindent=1 +linenumberson=0 +rightmarginon=1 +rightmarginchars=80 +scrollheight=0 +tabstops=4 +spacetabs=0 +showtabs=0 +tabindent=0 +editfontname=mseide_source +editfontheight=0 +editfontwidth=0 +editfontextraspace=0 +editfontcolor=-1879048183 +editbkcolor=-1879048186 +statementcolor=14745599 +editfontantialiased=1 +editmarkbrackets=1 +backupfilecount=2 +encoding=1 +codetemplatedirs=1 + ${TEMPLATEDIR} +debugcommand=${DEBUGGER} +debugoptions= +debugtarget= +runcommand= +xtermcommand=xterm -S${PTSN}/${PTSH} +remoteconnection= +uploadcommand= +gdbprocessor=auto +gdbservercommand= +gdbservercommandattach= +beforeconnect= +afterconnect= +beforeload= +afterload= +beforerun= +sourcebase= +sourcedirs=3 + ${MSELIBDIR}kernel/$TARGETOSDIR/ + ${MSELIBDIR}*/ + ./ +defines=0 +progparameters= +progworkingdirectory= +envvarnames=0 +envvarvalues=0 +defineson=0 +stoponexception=0 +valuehints=1 +activateonbreak=1 +raiseonbreak=1 +showconsole=0 +externalconsole=0 +settty=1 +gdbdownload=0 +downloadalways=0 +startupbkpt=0 +startupbkpton=0 +gdbsimulator=0 +gdbserverstartonce=0 +gdbloadtimeout= +gdbserverwait=0 +nogdbserverexit=0 +gdbservertty=0 +exceptclassnames=1 + EconvertError +exceptignore=1 + 0 +nodebugbeginend=0 +sigsettings=27 + 1,1,T,F + 3,3,T,F + 4,4,T,F + 6,6,T,F + 7,7,T,F + 8,8,T,F + 9,9,T,F + 10,10,T,F + 11,11,T,F + 12,12,T,F + 13,13,T,F + 15,15,T,F + 16,16,T,F + 17,17,F,F + 18,18,T,F + 19,19,T,F + 20,20,T,F + 21,21,T,F + 22,22,T,F + 23,23,T,F + 24,24,T,F + 25,25,T,F + 26,26,T,F + 27,27,T,F + 28,28,T,F + 29,29,T,F + 30,30,T,F +defaultmake=1 +[breakpoints] +on=0 +path=0 +line=0 +address=0 +addbkpt=0 +ignore=0 +condition=0 +panels=2 + panel1 + panel2 +units= + ( + a=0,4132,6,Pascal Units + ) +cmodules= + ( + a=0,4132,6,C Modules + ) +files= + ( + a=0,4132,6,Text Files + ) +[componentstore] +storedir=/f:/proj/mseide-msegui/apps/ide/compstore/ +filename= +[components] +[selecteditpage] +colwidth=100 +x=0 +y=0 +cx=0 +cy=0 +[progparams] +progparamhistory=0 +workdirparamhistory=0 +envvarons=0 +[edit] +hintwidth=0 +hintheight=0 +finddtext= +findhistory=0 +findoptions=1 +editpos=1 + 0,0 +bookmarks0=0 +sourcefiles=1 + /f:/proj/mseide-msegui/tools/unitdep/main.pas +relpaths=1 + main.pas +ismoduletexts=1 + 0 +modules=1 + /f:/proj/mseide-msegui/tools/unitdep/main.mfm +moduleoptions=1 + 0 +visiblemodules=1 + -1 +nomenumodules=1 + 0 +[sourcefo.tabwidget] +tabsize=134 +firsttab=0 +index=0 +[layout] +windowlayout=552 + [mainfo.openform] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + filehistory=0 + filefilterindex=0 + filefilter= + [mainfo.projectfiledia] + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + [mainfo.openfile] + filenames=0 + filecolwidth=174 + x=0 + y=0 + cx=0 + cy=0 + filehistory=3 + /home/mse/packs/standard/git/mseide-msegui/tools/unitdep/main.pas + /home/mse/packs/standard/git/mseide-msegui/tools/form2pas.pas + /home/mse/packs/standard/git/mseide-msegui/tools/bmp2pas.pas + filefilterindex=0 + filefilter="*.pp" "*.pas" "*.inc" "*.dpr" "*.lpr" + [mainfo.basedock] + splitdir=2 + useroptions=146560 + [mainfo] + splitdir=0 + useroptions=33554555 + stackedunder= + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=25 + cx=323 + cy=64 + rcx=0 + rcy=0 + wsize=0 + active=1 + visible=1 + [targetconsolefo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=209 + y=385 + cx=368 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [threadsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=37 + y=270 + cx=349 + cy=276 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo] + splitdir=0 + useroptions=16507 + stackedunder=cpui386fo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=100 + y=100 + cx=453 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [memoryfo.add] + value=0 + [memoryfo.memon] + value=0 + [memoryfo.bitwidth] + value=0 + [memoryfo.cnt] + value=0 + [disassfo] + splitdir=0 + useroptions=16491 + stackedunder=_mse_mainfo_mse_ + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=162 + y=502 + cx=564 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [findinfilefo] + splitdir=0 + useroptions=16491 + stackedunder=disassfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=548 + y=115 + cx=369 + cy=198 + rcx=0 + rcy=0 + [projecttreefo] + splitdir=0 + useroptions=16491 + stackedunder=memoryfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=263 + y=431 + cx=286 + cy=201 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [projecttreefo.grid] + propcolwidthref=135 + width0=141 + sortdescend0=0 + width1=129 + sortdescend1=0 + sorted=0 + col=-1073741823 + row=-1073741823 + rowheight=15 + [stackfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=295 + rcx=0 + rcy=0 + [watchpointsfo] + splitdir=0 + useroptions=16489 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=120 + y=368 + cx=483 + cy=210 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [watchpointsfo.grid] + propcolwidthref=352 + sortdescend0=0 + values1=0 + values1_ci=-1 + width1=33 + sortdescend1=0 + values2=0 + width2=158 + sortdescend2=0 + width4=34 + sortdescend4=0 + values5=0 + values5_ci=-1 + width5=38 + sortdescend5=0 + values6=0 + width6=184 + sortdescend6=0 + [breakpointsfo] + splitdir=0 + useroptions=16491 + stackedunder=projecttreefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=107 + y=404 + cx=636 + cy=128 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [breakpointsfo.bkptson] + value=1 + [objectinspectorfo] + splitdir=0 + useroptions=16491 + stackedunder=mainfo.panel2 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=724 + y=157 + cx=296 + cy=566 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [objectinspectorfo.grid] + propcolwidthref=286 + width0=105 + sortdescend0=0 + width1=175 + sortdescend1=0 + [symbolfo] + splitdir=0 + useroptions=16507 + stackedunder=findinfilefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=142 + y=257 + cx=361 + cy=137 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [symbolfo.grid] + propcolwidthref=222 + values0=0 + width0=111 + sortdescend0=0 + width1=135 + sortdescend1=0 + [symbolfo.symbol] + [watchfo] + splitdir=0 + useroptions=24681 + parent=mainfo.panel2.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=298 + cx=313 + cy=236 + rcx=0 + rcy=0 + [watchfo.grid] + propcolwidthref=118 + values0=0 + values0_ci=-1 + sortdescend0=0 + values1=0 + width1=152 + sortdescend1=0 + values3=0 + values3_ci=-1 + sortdescend3=0 + values4=0 + values4_ci=-1 + width4=13 + sortdescend4=0 + [watchfo.watchon] + [watchfo.expression] + [watchfo.watcheson] + value=1 + [messagefo] + splitdir=0 + useroptions=49259 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=510 + cx=675 + cy=95 + rcx=0 + rcy=0 + [componentstorefo] + splitdir=0 + useroptions=24699 + stackedunder=symbolfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=305 + y=101 + cx=445 + cy=354 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [componentstorefo.grid] + propcolwidthref=435 + width0=111 + sortdescend0=0 + sortdescend1=0 + width2=112 + sortdescend2=0 + width3=185 + sortdescend3=0 + [componentstorefo.storefiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.groupfiledialog] + filenames=1 + /home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir=/home/mse/packs/standard/git/mseide-msegui/apps/ide/compstore/ + filehistory=0 + filefilterindex=0 + filefilter= + [componentstorefo.compfiledialog] + filenames=0 + filecolwidth=0 + x=0 + y=0 + cx=0 + cy=0 + lastdir= + filehistory=0 + filefilterindex=0 + filefilter= + [componentpalettefo] + splitdir=0 + useroptions=24683 + stackedunder=mainfo.panel1 + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=335 + y=25 + cx=685 + cy=103 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [componentpalettefo.componentpages] + activetab=0 + [debuggerfo] + splitdir=0 + useroptions=24683 + parent=mainfo.basedock + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=313 + cy=30 + rcx=0 + rcy=0 + [sourcefo] + splitdir=0 + useroptions=16489 + parent=mainfo.panel1.container + visible=1 + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=0 + y=0 + cx=675 + cy=507 + rcx=0 + rcy=0 + [actionsmo.watchesonact] + checked=1 + [actionsmo.bluedotsonact] + checked=1 + [cpui386fo] + irqoff=0 + splitdir=0 + useroptions=16491 + stackedunder=componentstorefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=337 + y=295 + cx=273 + cy=207 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=0 + [mainfo.panel1] + splitdir=2 + useroptions=33586667 + stackedunder=objectinspectorfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=4 + y=118 + cx=685 + cy=605 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [mainfo.panel2] + splitdir=2 + useroptions=33586667 + stackedunder=mainfo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=697 + y=189 + cx=323 + cy=534 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 + [_mse_mainfo_mse_] + splitdir=0 + useroptions=16507 + stackedunder=componentpalettefo + parent= + mdistate=0 + nx=0 + ny=0 + ncx=0 + ncy=0 + x=188 + y=220 + cx=413 + cy=280 + rcx=0 + rcy=0 + wsize=0 + active=0 + visible=1 +[targetconsole] +finddtext= +findhistory=0 +findoptions=1 diff --git a/mseide-msegui/tools/valgrind/fixes_3_0.supp b/mseide-msegui/tools/valgrind/fixes_3_0.supp new file mode 100644 index 0000000..96b9577 --- /dev/null +++ b/mseide-msegui/tools/valgrind/fixes_3_0.supp @@ -0,0 +1,21 @@ +{ + + Memcheck:Addr4 + fun:SYSUTILS_$$_STRSCAN$PCHAR$CHAR$$PCHAR +} +{ + + Memcheck:Addr4 + fun:SYSTEM_$$_INDEXBYTE$formal$LONGINT$BYTE$$LONGINT +} +{ + + Memcheck:Cond + fun:XcursorImageHash + fun:XcursorNoticePutBitmap + fun:_XNoticePutBitmap + fun:XPutImage + fun:MSEGUIINTF_$$_GUI_IMAGETOPIXMAP$IMAGETY$LONGWORD$LONGWORD$$GDIERRORTY +} + + diff --git a/mseide-msegui/tools/valgrind/fixes_3_0_64.supp b/mseide-msegui/tools/valgrind/fixes_3_0_64.supp new file mode 100644 index 0000000..667da3a --- /dev/null +++ b/mseide-msegui/tools/valgrind/fixes_3_0_64.supp @@ -0,0 +1,20 @@ +{ + + Memcheck:Addr4 + fun:SYSUTILS_$$_STRSCAN$PCHAR$CHAR$$PCHAR +} +{ + + Memcheck:Addr16 + fun:SYSTEM_$$_INDEXBYTE$formal$INT64$BYTE$$INT64 +} +{ + + Memcheck:Cond + fun:XcursorImageHash + fun:XcursorNoticePutBitmap + fun:XPutImage + fun:MSEGUIINTF_$$_GUI_IMAGETOPIXMAP$IMAGETY$QWORD$LONGWORD$$GDIERRORTY +} + + diff --git a/mseide-msegui/tools/xft2gs/README.TXT b/mseide-msegui/tools/xft2gs/README.TXT new file mode 100644 index 0000000..5e2c6fa --- /dev/null +++ b/mseide-msegui/tools/xft2gs/README.TXT @@ -0,0 +1,4 @@ +2008-01-07 mse + +xft2gs has been moved to +https://msedocumenting.svn.sourceforge.net/svnroot/msedocumenting/mse/trunk/tools/xft2gs From f5d1d0c1114bb520f31cd2b7c7f035e3335ff88f Mon Sep 17 00:00:00 2001 From: Nadir Date: Sun, 1 Mar 2026 07:24:15 +0100 Subject: [PATCH 2/3] Added build script (Arch Linux) --- build.sh | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100755 build.sh diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..c00d15c --- /dev/null +++ b/build.sh @@ -0,0 +1,104 @@ +#!/bin/bash +set -e + +# Build script for PacmanXG on Arch Linux +# Requires: fpc, msegui (mseide-msegui) or msegui source + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# --- Check / install dependencies --- +echo "=== Checking dependencies ===" + +if ! command -v fpc &>/dev/null; then + echo "Free Pascal Compiler (fpc) not found. Installing..." + sudo pacman -S --needed --noconfirm fpc +fi + +# MSEgui: check common install locations +MSEDIR="" +for candidate in \ + /usr/lib/mseide-msegui \ + /usr/local/lib/mseide-msegui \ + /opt/mseide-msegui \ + "$PWD/mseide-msegui" \ + "$HOME/mseide-msegui" \ + "$HOME/msegui"; do + if [ -d "$candidate/lib" ]; then + MSEDIR="$candidate/" + break + fi +done + +if [ -z "$MSEDIR" ]; then + echo "MSEgui libraries not found." + echo "" + echo "Install via AUR (e.g. with yay):" + echo " yay -S mseide-msegui" + echo "" + echo "Or clone manually:" + echo " git clone https://gitlab.com/mseide-msegui/mseide-msegui.git ~/mseide-msegui" + echo "" + echo "Then re-run this script." + exit 1 +fi + +MSELIBDIR="${MSEDIR}lib/common/" +TARGETOSDIR="linux" + +echo "=== Using MSEgui at: ${MSEDIR} ===" +echo "=== MSELIBDIR: ${MSELIBDIR} ===" + +# --- Gather unit directories --- +# From the .prj file: +# ${MSEDIR}lib/addon/*/ +# ${MSELIBDIR}kernel/$TARGETOSDIR/ +# ${MSELIBDIR}kernel/ +# ${MSELIBDIR}*/ +UNIT_ARGS="" + +# ${MSEDIR}lib/addon/*/ +for d in "${MSEDIR}"lib/addon/*/; do + [ -d "$d" ] && UNIT_ARGS+=" -Fu${d}" +done + +# ${MSELIBDIR}kernel/linux/ +[ -d "${MSELIBDIR}kernel/${TARGETOSDIR}" ] && \ + UNIT_ARGS+=" -Fu${MSELIBDIR}kernel/${TARGETOSDIR}/" + +# ${MSELIBDIR}kernel/ +[ -d "${MSELIBDIR}kernel" ] && \ + UNIT_ARGS+=" -Fu${MSELIBDIR}kernel/" + +# ${MSELIBDIR}*/ +for d in "${MSELIBDIR}"*/; do + [ -d "$d" ] && UNIT_ARGS+=" -Fu${d}" +done + +# Include paths (same as unit paths) +INC_ARGS="" +for d in "${MSELIBDIR}"*/; do + [ -d "$d" ] && INC_ARGS+=" -Fi${d}" +done +[ -d "${MSELIBDIR}kernel/${TARGETOSDIR}" ] && \ + INC_ARGS+=" -Fi${MSELIBDIR}kernel/${TARGETOSDIR}/" +[ -d "${MSELIBDIR}kernel" ] && \ + INC_ARGS+=" -Fi${MSELIBDIR}kernel/" + +# --- Compile --- +echo "=== Compiling pacmanxg ===" + +cd "$SCRIPT_DIR" + +fpc \ + -Mobjfpc \ + -Sh \ + -Fcutf8 \ + -O2 -XX -Xs -CX \ + $UNIT_ARGS \ + $INC_ARGS \ + -Fu"$SCRIPT_DIR" \ + -Fi"$SCRIPT_DIR" \ + -o"${SCRIPT_DIR}/pacmanxg" \ + "${SCRIPT_DIR}/pacmanxg.pas" + +echo "=== Build successful: ${SCRIPT_DIR}/pacmanxg ===" From b95b743aa3130078694b232e79448fa6de31f292 Mon Sep 17 00:00:00 2001 From: Nadir Date: Sun, 1 Mar 2026 07:26:16 +0100 Subject: [PATCH 3/3] Fixed code - now it builds. I wonder if this program ever worked --- main.mfm | 12 ++++++------ main.pas | 3 +-- msefiledialog.pas | 36 +++++++++++++++++++++--------------- pacmanxg | Bin 871648 -> 0 bytes 4 files changed, 28 insertions(+), 23 deletions(-) delete mode 100755 pacmanxg diff --git a/main.mfm b/main.mfm index a19dc3a..b48d423 100755 --- a/main.mfm +++ b/main.mfm @@ -4409,7 +4409,7 @@ object mainfo: tmainfo faceclicked.dummy = 0 caption = 'News' textflags = [tf_ycentered, tf_wordbreak] - imagepos = ip_leftcenter + imagepos = ip_left captiondist = 0 imagelist = timagelist1 imagenr = 31 @@ -4433,7 +4433,7 @@ object mainfo: tmainfo faceclicked.dummy = 0 caption = 'Package Management' textflags = [tf_ycentered, tf_wordbreak] - imagepos = ip_leftcenter + imagepos = ip_left captiondist = 0 imagelist = timagelist1 imagenr = 27 @@ -4456,7 +4456,7 @@ object mainfo: tmainfo faceclicked.dummy = 0 caption = 'Tasks' textflags = [tf_ycentered, tf_wordbreak] - imagepos = ip_leftcenter + imagepos = ip_left captiondist = 0 imagelist = timagelist1 imagenr = 19 @@ -4523,7 +4523,7 @@ object mainfo: tmainfo faceclicked.dummy = 0 caption = 'Logs' textflags = [tf_ycentered, tf_wordbreak] - imagepos = ip_leftcenter + imagepos = ip_left captiondist = 0 imagelist = timagelist1 imagenr = 18 @@ -4547,7 +4547,7 @@ object mainfo: tmainfo faceclicked.dummy = 0 caption = 'Settings' textflags = [tf_ycentered, tf_wordbreak] - imagepos = ip_leftcenter + imagepos = ip_left imagelist = timagelist1 imagenr = 7 onexecute = on_navigate_menu @@ -4569,7 +4569,7 @@ object mainfo: tmainfo faceclicked.dummy = 0 caption = 'Pacman key management' textflags = [tf_ycentered, tf_wordbreak] - imagepos = ip_leftcenter + imagepos = ip_left captiondist = 0 imagelist = timagelist1 imagenr = 39 diff --git a/main.pas b/main.pas index 633efb5..9ba66ff 100755 --- a/main.pas +++ b/main.pas @@ -2451,8 +2451,7 @@ procedure tmainfo.on_run_util(const sender: TObject); begin cmd := (findcomponent('d' + (sender as trichbutton).name) as tdropdownlistedit).value; cmd := check_util_cmdline(cmd); - shell(cmd + ' &'); - //Exec(cmd, false); + Exec(cmd + ' &', false); end; diff --git a/msefiledialog.pas b/msefiledialog.pas index cc99e04..4bb88fc 100755 --- a/msefiledialog.pas +++ b/msefiledialog.pas @@ -14,7 +14,7 @@ interface uses - mseglob,mseguiglob,msegui,mseforms,Classes,mseclasses,msewidgets,msegrids, + mseglob,mseguiglob,msegui,mseforms,mseclasses,msewidgets,msegrids, mselistbrowser,mseedit,msesimplewidgets,msedataedits,msedialog,msetypes, msestrings,msesystypes,msesys,msedispwidgets,msedatalist,msestat,msestatfile, msebitmap,msedatanodes,msefileutils,msedropdownlist,mseevent,msegraphedits, @@ -75,7 +75,7 @@ tfilelistview = class(tlistview) // procedure setoptions(const Value: listviewoptionsty); override; procedure docellevent(var info: celleventinfoty); override; public - constructor create(aowner: tcomponent); override; + constructor create(aowner: tmsecomponent); destructor destroy; override; procedure readlist; procedure updir; @@ -231,8 +231,7 @@ tfiledialogcontroller = class(tlinkedpersistent) end; const - defaultfiledialogoptionsedit = defaultoptionsedit+ - [oe_savevalue,oe_savestate,oe_saveoptions]; + defaultfiledialogoptionsedit = [oe1_savevalue,oe1_savestate,oe1_saveoptions]; type tfiledialog = class(tdialog,istatfile) @@ -240,8 +239,9 @@ tfiledialog = class(tdialog,istatfile) fcontroller: tfiledialogcontroller; fstatvarname: msestring; fstatfile: tstatfile; + fstatpriority: integer; fdialogkind: filedialogkindty; - foptionsedit: optionseditty; + foptionsedit: optionsedit1ty; procedure setcontroller(const value: tfiledialogcontroller); procedure setstatfile(const Value: tstatfile); protected @@ -251,8 +251,9 @@ tfiledialog = class(tdialog,istatfile) procedure statreading; procedure statread; function getstatvarname: msestring; + function getstatpriority: integer; public - constructor create(aowner: tcomponent); override; + constructor create(aowner: tmsecomponent); destructor destroy; override; function execute: modalresultty; overload; override; function execute(const akind: filedialogkindty): modalresultty; @@ -267,7 +268,7 @@ tfiledialog = class(tdialog,istatfile) property controller: tfiledialogcontroller read fcontroller write setcontroller; property dialogkind: filedialogkindty read fdialogkind write fdialogkind default fdk_none; - property optionsedit: optionseditty read foptionsedit write foptionsedit + property optionsedit: optionsedit1ty read foptionsedit write foptionsedit default defaultfiledialogoptionsedit; end; @@ -302,7 +303,7 @@ tcustomfilenameedit = class(tcustomdialogstringed) procedure updatecopytoclipboard(var atext: msestring); override; procedure updatepastefromclipboard(var atext: msestring); override; public - constructor create(aowner: tcomponent); override; + constructor create(aowner: tmsecomponent); destructor destroy; override; procedure componentevent(const event: tcomponentevent); override; property controller: tfiledialogcontroller read fcontroller write setcontroller; @@ -463,7 +464,7 @@ implementation uses msefiledialog_mfm,sysutils,msebits, msestringenter,msedirtree,msefiledialogres,msekeyboard, - msestockobjects,msesysintf,msearrayutils; + msestockobjects,msesysintf,msearrayutils,Classes; procedure getfileicon(const info: fileinfoty; var imagelist: timagelist; out imagenr: integer); @@ -718,7 +719,7 @@ function filedialog(var afilename: filenamety; { tfilelistview } -constructor tfilelistview.create(aowner: tcomponent); +constructor tfilelistview.create(aowner: tmsecomponent); begin fcaseinsensitive:= filesystemiscaseinsensitive; fincludeattrib:= [fa_all]; @@ -727,7 +728,7 @@ constructor tfilelistview.create(aowner: tcomponent); foptionsfile:= defaultfilelistviewoptions; ffilelist:= tfiledatalist.create; ffilelist.onchange:= {$ifdef FPC}@{$endif}filelistchanged; - inherited; + inherited create(aowner); options:= defaultlistviewoptionsfile; checkcasesensitive; end; @@ -2093,11 +2094,11 @@ function tfiledialogcontroller.getsyscommandline: filenamety; { tfiledialog } -constructor tfiledialog.create(aowner: tcomponent); +constructor tfiledialog.create(aowner: tmsecomponent); begin foptionsedit:= defaultfiledialogoptionsedit; fcontroller:= tfiledialogcontroller.create(nil); - inherited; + inherited create(aowner); end; destructor tfiledialog.destroy; @@ -2158,6 +2159,11 @@ function tfiledialog.getstatvarname: msestring; result:= fstatvarname; end; +function tfiledialog.getstatpriority: integer; +begin + result:= fstatpriority; +end; + procedure tfiledialog.setstatfile(const Value: tstatfile); begin setstatfilevar(istatfile(self),value,fstatfile); @@ -2195,10 +2201,10 @@ function tfilenameeditcontroller.execute(var avalue: msestring): boolean; { tcustomfilenameedit } -constructor tcustomfilenameedit.create(aowner: tcomponent); +constructor tcustomfilenameedit.create(aowner: tmsecomponent); begin fcontroller:= tfiledialogcontroller.create(self,{$ifdef FPC}@{$endif}formatchanged); - inherited; + inherited create(aowner); end; destructor tcustomfilenameedit.destroy; diff --git a/pacmanxg b/pacmanxg deleted file mode 100755 index 2cd97277c777a6b837e0deb127fa277de96601d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 871648 zcmXtf3p`W*|Nk~KGqW?y{W90g{gP`gbH5b1mqK%o+!h-vmtn{pN_Sn+RX5Rvg)(>D zKB*L4Fr`wXR*4nu{O8;6@9{Wx_I^Fzuk(C9Ur(#q!SoLBfy3bvu>bo)z$9RB@%eb@ zW0=kVUlc#uz_eiq80mj2tM&hV;khuF_*hvl`@chSbrBEy-~L)O3|8xBie5ebhZTQA z{a>9mz_N%4j?}S4%VJlT1WAVfI~K&}W#VIXLmu(mZ{{jD@l_>Y>c#EID$+gb_IL56x>dVma7E& zYVpR13B!{OQR--^nBn<1{d|&!ha3z=M)0EMvnI5pP(vXfXo)a5`GCH^m_e{VR7_Wb zar4kHw7(v#4SKU^k)9flN;Jb}(i!GCS?1O-*Z>mtW=g;FC+a@j3KoFUhIP7R#lwqH zgGI!rsMkN8pQzC{-nmD4^3(a-HWbP9$PMb7`H4*Xi$EjFRk;libR9gH>Y|ErV(uE7 z^d>$*T_6sjt~F0g&ZCIos0`)$Af?lvc8w|Lqa6A#MeREMX~N!YQ^R{u2VuhOOHtTzO)`H{k!{h~CSBk9gBVJjN*n{AYi#sE^umcpwR^`r1 zWM4^Q6}miNSb9lHD%)e*@cB^`Tn3zuSD2?v5c>wqOSjb5kSnLa7^HH1cP6Dryb?5} zN7jNsUc9m#g}%B{agcl#GWZ{6KgAg$ndi3Fkq5gipqM#b4vCUYIWOJ?l5NQmL`NON znO3PWX;q{cB#mZ%fx4xXJJI#8y2o8(TfvFRMYS|7ENq5yyIXm{o36@qCuezVn~SFu z5Z_6NC1(F8{kl7YLTd$MlE?z)uXyDi?jW}<@F1x3kW zl&`p^b7g9#zEH@2N0~a;Jm2E^%XbYb!V#&wOA1XQ~rzp8Kc!I1@n@Pfj_P zs7Y}|n_mFQho{Pk!r6F^SGU_~@vGuq@OC&+*PD{cw#IMYhDa5Mcq17sV~LX>i+iW+26zq315&U7)p{xq_?o-^)E zje*iA=E^ej@ytEMsW7pZSR$VI2ojGn_vX|*S(*&S5R@rodrB+&Zf%4qjJS`v%D0{Z z)&FM7MPrpqp?lq{D<{a|Q-c(N+N)uR&Os6P1<<1q*u8)0I;*WhwN`^sIz55yoyAmYbZF zjcH2E4$a(5&B`hLDv3@iCvQh46LS`G@{tlu%MnXN!_LMH80NSZPQCyG+=Py@DkRcuwl}xP+nPoL#%ycoO4x6VrV$ z+cV5nAHCi~IhjpUf|*tkZjLp-!)DJ+^^;~3FqGts)aJ&6Lgh!f#&8BSc zT*g|e_lYgE#GN@RUh;YF*%WuDNWaJ+q*pdof7dSWV{T8e(QbZ!w5WyGq$}R|asrhU8Tvm^EK=0R$37J9Efeb`8xAi&c7a1f`cFjiSOsJl)HoSGTWW~12;XL64?6ZsQMD9DX9rL-VDxCU&TB<+hiM+?vOyw zVc%XmwC8Sk!FhjArYHmV+$XXyGB(*EAS)}4PSv@Eh@UF$5IPqrs4y$ilZ&}wR=*nsnm-(Mrd5co?j%Kz6pY$yd~_8lv=MjcH)R) z5mmpm#YB*lNh31jtjFaNf_L9SN4&&-99y?hJ}1~Zed8WksT3c4PKrooaHj*d+0557 ztF~>614Sd6mbBm3c<}qz_~}A+3PA=(k4MENbUTvzE--V3{Cm#F2wJ={l42hF|K4%* zjOBEO<;SE+O;ns&&mD?+stFpYd1AZOqde?Z9vqSUZV#1P}b_m^Pmr0p!pU%o! z?`!u(TMT|}q-VryFeBBgtYj7AE+oBhcJ3v#Ute-J&r`_@&r;8dj-+nz&Nz0Cx+~Z? zGimJ%)uDAuE5+mG@l&wzO)bV=YHFsk@VGQ<8mdP1o;D*^sm=eqDAV-S41;X_S?r?~%*7n2KzF-Tc$=kHzU* z-ZJEK8htyZRYSe(w(~b~_12HUCVmIg;~2)7-@{rX^Aacsbwpoy);>u~B%;jltd+1l zX3u$dbNTz>*-2bmuY`KrFrAmKkBV~=j?+>+XJyv$-rgnVGctT7rCav;D}4=nGh) zMrKgV4>UXg7hOxQdnX_h-D}Q=xCDkz@FR|09 zUus(}#Yq2sR&v=<#Gb^q2dZ*vmYmz#;YpW|>$J^LvbX27AJ~4gM^1*FjTQ!|1h80s zIX)*b9@J*l{ED2jmV`$NYkMt%GB(pX?>-XvUS4?V7N3(tPJm?0^)JJG1N=QaDc0te z3hNzaYOSo-63|oJjeigl>aTuxC`$lH1@-akf4#-;Q8vI}k}$Z0RE?&+mISN@;k2Fi zw1NyvlY)h{ejA^HtD|7j_6Qa_XZ~9(Q$qZn0`VTbS^Nl@aO^S^5KOp<5LJrw1f}dz z!2E5KEcg=)3@!zOSG48I=19mGA_DtLWrk1}uOK`&AXzu_&z8lIMoT4Ke)8Zb2(PvM z9zHcyRoK#B+pp(bbQb`A9sDLI%X3UNT_%Q%s zK@RY>7YHr}&XobrPJPgNTM5)w1E{Zea6LfXA>cs?tU@P6c-qIA9 zwKU?0Wsq!u*~`ey;|@TbGvL5eLoQVSbzVT4QuM_ZKcF@Mh@xqha)JSu{{T<=i&AtX zKo)g)=h1MmSioHbcz~Ht%|w8w2=Ee3oQa|VJ|e(Z1o(Nk&nk%ke-W@=BnET<8$>{W z2oM9nKoPJ}1O$oe6Cxm31cZnHF~B=i1cZrza4{fL1Vo5{O(H;yII~#PL_p@h4p}0ADgt)?>yRx1a{j5Ji2%9?$aVXlDuxKy zRh;?#r3klM1mr7CymJxZ3PeERzYawrfGGlsyOc-7zLXT+0``l5EHUW=BH-X&+@XJf!y@3wKfqBDQ1{Q- zVRfa{t z{eM?^AOaqWfJf5*8~S4r@SpcsiBmJ~bTu#{+CL%=*;5hlY@@i^g?lanMn%Aje_p*5 z0b~EX8W#btL;$?WPOdJDW&L+jMA>AQQqq?fqXYw4D-f)lOOqtoHn9{ra=F;3zUz=} zv`=Dm zQb4F%rC+tU8XjC5DJ~v96kC@ft|pzNHZa81W9N#SD#g_`S8H49#AW|m4IFXxKvP!> zceTpt=MIajmxdpWjEJkoiIQ2-Ga zAglTK*F+&iTnX!{&4q~8BBHoS0MZTZw@MWojE`KUN{CfirJABa)n28_&@U#fQmr(t zU8QPSXVb7s)uG9`WtFNM$BVm4)o(apWR+_0c=#$+UgT`_Dpf(OFwwsw{2B}a5z(vr z)A3Z5)%`SW1}R32D6lMs#9S{B%OGOqKd#jfvGyO=LlChpptDZQ^&~`W5Tjxs;yH-e zBvzyh5wAi-v7mt#h*piYR$gNQTpx)BzT1oW@P9JFfHYKsL(Y?Z=lixr4?;DOD6*e;~oDs{9UHh5J! zK9Uf-DqTfv)v9!DhW@JbVp65)s`Og1RjX5K5L>l6r4~2N>Xf{=e#7Fbb-;+&DzU-g zVyjl|j}}|C;l%^}L>LkxuI?8nh`PF8oFK;Peo}$us@!5|)v8swl@L*E)hgFohu3|3)&p zYSsVZ^LEv$&|l*C%s`URzZPPvR$GYe5?i&}LMTp_n0i>({#C11sf&|^U8OEg)~a-I zvQk#1i<8Azl`c+J<*Ia3u~nfcU)<3ydAz}+eo)gQx1rb3F{k~dgekBdw*H?3E4NTT*ehd43jn`i#Rj3-tnh~-U zgRRecq1m#2rS+b#WHbZ3FcIOQJ1|=YzO^IK(qSPU9PE+ux4CoX!iBRmY;9xtf0X6r zLIgCzSs{U%vD%M|IdE0}tG>U>n_#|W_73Pc(jA_teu2@4ABx^P2P3+ z?t6OUuCmXuY5GXBugs-u!)JmWwbA$PIQ}fq-dO9ya{guTwX{7146h*R6>ceDjEn@j= z*^A)c_J%%1>dt5Bjl2fv8DEk!^Ph`QfKMLE5=0M4%3LZ`kM3cQ(;8Jr=!5Uv7)wfq z*9(h(l;!m`!eoLd0#OD~7T~DLo@D>HQ>@JybLIfUPLIB}%i^`o4O|#LwMQ41wAk-J zC07UbbcA*6RC}jD7R{dY24&qa(9;dAWRtq_fY^PGe(cwGsQ1_Uvh2tGPjRXO*Ev|T z?nFwb$ABgMDUs>aa>(_Z*TgF*@2K|*J3?3!I9?OM<-jkI9SR-Zws*6FSIY53&|CP` zTQKCkK<7-6$JJKAX>Lwx((@j-+7QGxmO~DbSb4gB%P2)VJcg*(gkC zPU6|o=9j%(u?^iB!J@0IS&hN+H+1PCuKzkQwucqZK2HF6*bFld{w0|WV1>V5ceSKb?a2Lyku ze^Wvc!lpam;n5fY6z3Dk5<_v7j*$=Igh!>D2aw|_*1$F;@O)693t6L zYzmsPOLF)S6hswSFuu#~k@$k;P~16)^w;nBQXrWvv36?W97YB!0xhGT>pUr6gm2Ww zw)AgpR8({I=sy25?=pNFb<-m}E1wX1LnsqlOsK!6G9(F;=|=WM>j*n1{D#pD48>`_ zVbS2rx1GLPjnZx`=K+8N5Qj>avOy#?qUpta7InI-RQx&FhL+#AeplXoOTKgyE}1w*b^ado&3~L#G+HL- zI{Dr1PcW7*eVony)nawr8v8>dE%;Z;)>c;^d|3giy4qhbruofU+ect@@T!H-VCG)k zrtarp%e8AxlG}FE)Yyyu8%Pi7ZcCN3GK+i+nEPk_K1rdu^VWKWo*S=>p0fYD4Dl?y z2%t>Kv;eSq;y6P0fi}jj81BCL$GH?+JLGwN1G4-+O@h58OJWZhU2DW?aX-)0lf@FF z1%(*SqocF7>lsQ`+76P^0cgD!<{T9=(ryg&b>>xAj=%I9#37xuT3!%&87~4N_4z>r zRxJ82?bWBEFtXF<)xkJh)n_Awid+y8_sL-Z}6rzg#iW!#0Ap%d-r@KOiX@THu!N#+#ya(#a9vl{4!mJP=547>?dJmLG-F^yO*T^#4z4&(GDm+#ZBj#+ zl3ox)O1E#-kBsHmSp^F3lSk~I8~)bMQyy>x%%#h?OEY^cZX1sL%w_*YKmRVsF!k7S2r- zL|RM|6!*eQR~Bk~;rsZtCcC;*0>FrcjTXWQyYVghlWJNuK07TE+;^NcV0zS0t1`<43TicRgPOPfM2m>b+f>Hsi6lmX#8_^}z$I*Wwq=C&5Mn6D87` zuMoLV7Cy+A-c}`1DdoGt@n_y5`;SR@2ZLDi$T{VTO|!#GXO-@2v(0XX+{)fcxsrEP z;ij+W-QhBEEm1r6Biv?&JG!MIB@6k15X@W9A)G1XC-w7N2>iq&)igh;n3)_Y= zI+jb#YHH6t9|6~|6aTPtu5X=-We=|0ktE#!cPqxqZ3Oq!^M7fkAC)}Z3wj*tIkuSJ z!(NZau|2UEypmcfo4QkC$kSaCOCYGKs;X#c!x8Y4jeD3)y)e%nUF41m+2A-2YmE~i zzRodt1pR@K37;#G)U|nOg3|UUAg_e>ZQN>Il9F6*HuCbJe-ZN34k=T`wxV+k^f!zv zj&X|Ti#!KNWJ&}eF)g#GhTK7?fE@si0_J>_Xk#MYPMm`(D(&?|{MU+3k^;M^c04vm zmMl<#VRL1S!;BOmgt=0r)D7A7Y^|)bI%;Yekix9-ZuORi#)kDuTjjT??Z!7u2x1Fo zwmNLV@=e#TqwT%c5=z)#XSJR&QS32-4+!>o>&8+w-vQAzikr=YS<@505ciODEKn5b zqo)-+%r6K~qDW$1$Ss79)K;Q}mw5|xb#SfnBOfgU9ebl!=Ts=e!s&HWKcc=uvXju@ zZvUiY85^HBI^JDqp|nQ9;6&enFcOEa!djlm$tqRuz^qkok`A|Ks~tkO2!^^nN@A-O z{k|3lKiDpi_)m#lr-zZNR*ZpCmkQGk78f@h#3~(VFp|OQd|+a)-tNq#OLc1UrDSTz zuZ|kqQ)W9(v);k4w9FE;Wd+}F$toQlpVED-p$7*Rx^cwnkahhJFK}tqizRl?w8ndt zS`DYcMroPu=f-R2BzPL2RA1nfJZosug)t;mLbs>m*yEq1It$qY{J4d|i19L;a8T;6 z(&vL4Oa3V3$YmqFlTR!dj5zk?R`C(2XD`DN<{ig#aDDrl$Zaxfj0>E8vF$-Arbj7e z12Zf%M1i{endM^H1fye`w}26(ebBd8SOrMY&2np$3tRv}+1MqfmE@Yj%_U-H7-efH9Rfs59~UFIMjdI2ob!&KYxlu;_9S`I)$CW zynp{mT)*&%&;Ryq75Ve$($ezsE-O;+G{qJ6H2+DO1>>1Y4$4_%*^l~mcWE+1$qw~X z=^kpkk|kne!R3mTN|Tsqop|YwVw(`g@8Y;8C$>24~r3ELXj_R zP7GrP379@25wl8AU0qpOL19%s0LaKl{S+L(ASEG@+6KRH`)jjn8@jSwOGyi(whC2K zQj(X)twM1a3<|Y%x$Oc1u^XNIQ&U9~qq@4Ts;DR@x2j)OR$5x}g2~`6PNE(W@0gdFJzZ_MJQ3AuXtnpFP>z?(g1#4XN!Jj}M z4OTSWMkuW-L9k`4Ag}zqXE$N~NV+mG*()iMxZcK^M$q4eGH${vm+O2A5>%p((BJ|| zLN(!Ulb#2!@=y&Tw=vhrW>2~Wh}s(8_!wVc7q0(SsY{nuhVKehEO-Df*%Qf=y9(_) zz;{~S%z-TY%D6P_$fZ7h5{Uh(pd_>{LOMl`FSs*~j#Jmqv1V_e@!ZT26!l6j_KzeR zTiWNcbL~2*A@_qNz2^)Sx)n}bhI_olI(Z;-Q6JB%j|*{m4bXmSIfLl=+dkM*lV{>XdI9xIKjFlg;oNK30py)R|k0N+hA zqF%tj+{rlm++U%J#w_0HYYwI`ma4K-;fV3zzNCs!tvUKm_EclGW+721L<2YmM$`31 zuC_pW+(>wFV*e#GSH2yTE9;rvvx!q)&F)J=c_;qTCRa(m59Ee7G8@#_`(dZf;n^ym zrzw?^Bd$kYJ zNJd7>z4E($O8)%??sQpbGiK&_q2^EcRvpXYkw;Kp;G3vwScyYaoKy|{;6nMR;D!FAk+#P#!ga`YL9y)4(}(NgKeBzJ zicf`WFyCxOCjnPsTBZKCrAf2M`w_I#=f~fCUC-9dW^t6=uojFGcZvW#!y)cqKw=nHCU~=FeU_zZT6w=y{@~jHYCQu^RLoF)o8;X{P0{S$=Gj!IYf^~2JM8%l~jA#xaZV|9p!91k$Yq||53EO){vVw zsfUMoTHGegHrkzg^p|g3UWdlT5sASCFlJ%-#9yPcwd^I<6S#RgR(go-1ph(ba@Ks^ zNOqS1J}%sFauWtcKJ$=22Cl=Fwnyn9fgNC=NjZ?=LBcGr=shx#~4;Aj)_~}qX@Od5i%}Jy0QOV<`wS7;mwsKg*=)H&<52UJjL};al zY=g|}2#G;>7$NwO9QY;h1?m$I#DaQoZ6`NYYBL$TU|cAaRl&yMpx$-5T%XQum4{U- z-Gmh@UX!{Ys50=%5cm;@>2nHi9ZFyLaG3aGghjfez*G5wJBNhaOEo7Y0 z0Zmts z$H5rO_5t{Ey$0~pMlzCKxWE%plZw%42o*;@rS@IX*v*g`JrNj%EWfAh$cHT1DtsR{ z1<7~cfOMiS*v0I7lWmC>=9!Q!*PjkU_D-Dr8iMDe7JOBq%1Xr^HLA(MjZ-DP4Lyyw zPLnrboc#_5fKSLIxKiNr@wYsR;)sonc3?|HA?|{Nl1#_(Cv+{EjO6Z!y)(3$h}7e@ zLhc>yrPvEa;@@MnVUFLxL)~BG1`dA=>|+mkWmGtwP~@mwiA|SEvE$vUzrvR@0+mhK zQdQd$Wu3f{O4jVH$c@;e{B@C=z80@2?{jl5$iU8(L>fj&#V;-h6-c(iPZPOk*HJqE zD$Y4E3glUU0K-CK6MNnvY9eCug%Qoeo4we`Du^`6lZFzUDz-}2iVD3Pf9ASfDSH_H zs$~d$OJtASTy9dso$t569c6?lm%@7;U)xX?qSH|53&Cyfi-<{TbsWsAyIVEIT8)xg zY$7$Is-vk{{G4;TYP|f_hGTS@WSIF|-kK=}U%%edStaDBR`S_BA6*wcXJ4I#DU;5| z?my*KAbI5>C_7rLv7e{F?6*4P$0oa=$~=R6@2$fJ>(zESZXv!{>X~jF3H_?p(U5Wn zHf=jOA={}59qcD~>qyV(`;=}<2?-e(=uXr+IoaU4=gZ@;bEn5x5Ih(ErDF)e_ydL7 zJi4E7s|K$8H1T-l+oJ^~HuDK#>mJ>*Woxbkd8uexx)!UUU>(JH_=2b3m_!MK&2m$? zk$uZZA1_Br{NQ2SU}`DhPqkzn5&%PFUYc{nk(bRBgkM9yhB?vWc}Xs%t++N;YdWohrHp4JJH_> zLrLZyDr`R!oUE?jo(6fGu?+0ck9Uy+3fW#xo9&wvzB+~$MPtuA9M6w$kcr%WEPqIY z{SDC2;k>sRwu?|^XnLIdui@N%8P^5^xqPumT?toI>{q_M60C`LI}S&@q2HF5#> z<_8FfkH(g8e&Xv}^Aav6S=w3pilhVnYmS*(+PET*B|114E*5alxjX29wI}bSOR21J z(31~9;H1sD>P~A3VDZVc7%BF2R!Sdnw@J3DAsunA7Iz^fM)sPb;BWP~L~$g#t`0#e z`MPDw1dPNd2vswAXYm&#jwWb$zOesqr(b>a1tvb?$^m-Q>8m;{(funoHq{Fr)hAzx zkUAidygu3VK&>5b=_Y*o)$GKHS*6An0+l6ra6bF9;;jX)aMw2Dqx~x*FvMv5fn(W7 z6Eybe=M1Q+=m?$k7|?KuovY*N49=3&hx&xE z!sP>|rupjhww0trM`V47e9rUZO~mDjUfEwS9GW6q(Z-0p{3s`PZ%nvB-#u0l1brXY>s7k7y`S=Z0A!K7dX4m0#a@^5Sx&S*w`*?p8<5|@GeYi@9C#jOLWwBYPBPw*jvR- za`J~UZ&nwwoqW-Z}4}D z5f(T?fz(BavRzZ{<$^s?4tyK)uS}o@J}BK2i5vorSF58wQ<&Fj@vLl8CCX68`if^NuP|- z6WY+7aT+d<&)&KJcRv6I zPyhV|*d;f}$n@Pe>9LBGhfgI~J+U2@gCg_koe#rEW)g0ZeA`?2Za^-Bk#5W$SF|kS zHQuACee~u=JD8C03LR1jXu>wl#$V*6ieRvc?4%6?4li#j+hdujRWfr+Xt8Bz)>39FZ;IJlwju7MM4?*Bh+TD2;)SJim`U zpa6OV#sv)YcR#N#LG-301MB0L(AdeUmQ=pEz<$U>%Ll(}$V=U~Ht5*WUfV+{j^lKU z{LrSvmGMjEP-ZT+VuXFx!;9-#CmCRR%SPo}?e^=z-;boKs62I1s0m(?w-C^3SY_1# z`ZG4d8n5QGF-gQhdsc7JwBg>;G0m!XAZw|!)Fp2yYgkZo5WOqMmlfaRPEt|P=p(A0 z-ovudB59dg7JLug4Fs`2)wFo6+;Jbn&UyYk--Owch!vXs4HoUM)MdZ#={$peW?cTQYI1U%6<5N`o%#>BmIR|sbWp- zzC~@0#%q?&`2L!8+Uk}F7WuDzlk1uWUaHYLBq{R0*}MHoQ2=eDLTuGOq1Lw8xnN6! z(OSlFhx@IkrtdzsBenB7)6}BD*vhWW#SL>*HKVNUvrNRtarWnqjvrFdj7@{3a+{`$>k!u_QHy59OQTiZ zD-78d0~ncCW9hMPp-8_bcei2fN7K6EBGidXS|*(53#zK1+xAAQ)?Mps=;gs*2@U$PPk)MvK zVUJtm%VPJR$Dwh3-WY!$2a_qqfivoED4J5wSqJR)vdHpoK6#j6hZ$CA;f}MQj9vq z4Hh-)@yBSR%PjU=q-7*uVXfkb=PLt&->V~`>iWjva~5HRrxb+pihys)3K0$!g`(H9 z{#a%gJcaZR<5kqr_6~D9=i#3>1PX0o$I&e$Zh~GY)@J5_?2SFw_OUr`WwumJEv1ce zs!kCzk7wkx=78&mD?f*URbL+D(Myi)K4EyGCp+W~sQv{yXg{wrjLWBCt{+Ho-=ead z@v4cDrf~zVbEWCK?pn8oJ>EGTV>OM|yzky@xsZ_E-djs{ytS`hKjbY?L_nyt2tk1_ z6exfQfn}4nXFQ~5EaX(d4d}(>_N=Sfy8bjtB!;i1)fLF&%RBt^c$4|eAM2z>mn!3V z-{3t)QjpcmE@>y=koW9y_tV94Tk#uW=ug!gsL9F^e)5~~xIE-mInky+1p0B)*mj_2 z)1n?>cF*$r<1|GF1R}>GeBYYiZ?rG-^%4+tb^OoR<5C;Er88n=oQuQuzu)CH^Sse- z04R%4xD{4~RUQ`6$H7nc;|xOaFGnoD#cEF|JITCH(h&&l?R z%8s%K5@KawxA>+~qPD_Mvyc=W2R?QDQLDOJWJa#%Aw-}7TV^}VwAA+R;o=nOH#@GU zA`GSuA4{<>i&c3l=}33R?o{x$tOYcfx|5c2mA~cadJkdWSYT(6->?fdJZs7lH-um_ zyMOxeueF8mBpvX&6oLiHg8IHSx--~c&NGFo3wL;<&NJIClMPZM7U4s~MjgCsJ6?}q zjU0-0D){*-ey-RV5bUdLcki~(KEp4_@3LBg$4HC1621HTej@2|HP})jV0^nq{xj8U zKcX>cgnO#gNw3cysLm?k%2ty-uqr!gCqy7&e+}Wt(+}^)(3WL0<-^$U$3t7Cz@= z^un_0|44+P_iKhm$~NFj4!jzE6t%3)NmvE zXk?e(E+HSI`8|8M54qlb4N z#&ROEz4^elKngo1`O$nqu-7pyg`mJk)Ao7>gBxk8RuK}X?Krah1D1hRIcVxrV{)4w z1(A+-)~i$0D1PQ=B&7gWpGQPbxw;*kmfcqsyi!Iobz6ss)!4As`sThbM>ei?-la=y zO?ahV1|#kn)+6pzpBz!CyxZ+>iqd0pbKO_A4SDGY4#Y^dxEv!Wg$noe0aJfjE^c@~ z_RzgF$E5=6jrV*Qhjz=Y)z(ITJ@x+J9Q|aozBDjzI1B4kV)Y^8nd*{*H=o%9hq(9Q z^Uaf6$-U$l8$$%7Lw=={D-Q-xdrhD zr&Y7V^q%h5f8DHEO2b1o2oMDeMF5p%@}1pM7oM1kcgAX<}YP6EWppKLUgl=(hg?d7XN)#!Y>AG_>XHq zx4l$JAaHWP3xRBvbbMEtQqu9dA&O^=wI5ejM|Y3Go_{m`S>g_T|CW50n z28gNp>HogZ67*ZqMr97_>R121=~S(9!_hAR*GB0Thx;_j>D9%pqRFA+y@y{>Y&ljVE)~a1OQ#Orv$?J9J=_gc-Q1*d zaQt2eR}Chqf##==sxq#e-T~xP(>) z?9`N^jL#Qs=X2_IEM)b$a0852ck!c2RrG#Fy{HmXwo=l_kMLzLFCD)>`0F&{+`5mo zi_@T*T+O2zeIuwhqq7ShL~Pn=ymzycUY&I6I)q%1 z9|+3G#5dgUF6XuiI%x7{?|o<8g#mT^4Qm+%dNkNVwF_MVJXrgzVqV|G5+0QJFI4 znembjse`V==0$L~C~Vbm2}KWMx5=u&!)9>Me(G$mN%iAmvyRwj*1RfR-+ae7nXfVp zyj>6CcpBQt`h-tBpDD|2`eis*&H+EK+?SOByTdv8Hp0+ShcLmD$`R0R(;nj`IP+!rF1|?Qns~R_Gx;kD_MAOWuQ0HJ-B|Tn6jv6HqXa& z)6vdV=FP>oK<#@(ld^HlIu1LnH|@%7h9Gw_%3zNQUoMX>ZP1#cio5XBQXhqO;9`ah zq*+#RA=4Wkc+B>72b1(Y>i6F(4tAgihU|cGyt@9#9|=zBz_(;_2m5a9LzwFvy?^D3 zhmhNLzdKHcAv3jOg?R`gr{_3QV7i{Y=mCPAGCU-!3S<|XeWw$E=~g)dHn7g)m)njb zb7L`8eU*v_+sQUI=eV*(kJx>!v4T*ltqpEG&c}dimZCd8(lHWjh8p3&x)UW!NI5c$ zo6dmCZtUq1f9@h%;_7+kkPpLG9;l0>Ub6BYyAKU#|$n76&z2Mm-zNtYrs#3Q6zm1SaCex7`_yLgEOEOxJO=kK=ELb3I zINJyt1Ye65k!vFrJ8IWTqMiI$;9vFZ1H`lVX5O`S53IvBy}DH5MN1U2n=|Bh;tMNW zJzZWS-ucy)t4@YB2cys5;^nQ3+j>F=j zhhTdd2B$n*)_lHklUO6oR*=_2d<^Qj$=GwlU>4oc@acXx;*IjRA;lA{NQK5eqpN#L z>bU}mwslh*qoi3Nr{w8TKfa!Eyp8nd?#sH_l9bLjdi@J~gJrMOd|Rg>72q{&>zALN z6#Z8+rN&eHcQoPS%*Tcq6MZy6DP}@{$F8{Qo&as4qE&!@7-{yLqK@Zqjx>kkZKiNc zGnQLTA~JcN4%0vMO?Nx&>2hJbJY!4J+wWI?Yu@c16eMKm1#!cWqYTNCIhB{(A7}`> zk8@D)wM(BMJIJoqw=L5jjnp^&VMxkH2brFV6W?BUkE1wYN{TyClXv-0lssFYynp{O zSnf>_T%LsUO8Qk2O6K0*it*bWWZ5PAvgXix^&eWxr)qZdLG(whG+mgPHQ0og4R&z1 z?Y=!59Lf6ZGF89TQ^$0}MHH?Qf9A+0ALLz!7J?(hELnkBcGj(zI)bgK|4u}gpKVt? zdZ_m-nn}0aV~_N$sBuY71kEU`eq2iR;07Tfbx!gPZlbAJJ;Prcmj7hUx+bw@#vg&usb zFU+2<>QO6u-bq2>`nw2yLJYK2Ty)7LGN4bffRs$bHq|0Vu=rHM1;lC4uyeb*#y z9;7`hmajiuzM*QG@_y@{%r8}SQPBoN#ic^KwqgYh^f`~SqA40XruxR9DWHP9cCE?k z^x>)YknUouF4(-z4fgQ#dEFx0tFUi!Z6E;*&Q`2z2C792Bmt)j$&_Tu*v zL6Kh82ZT*S5j7FnmMM6@2ki@>V#t9J#3VN|lhD?)p(%9XO>}V~%C)~AORe8{yu^=T z=_-^3i(MMvrs$&w7smza@m4mmL&aU5saQRR7Cgf0vE8&LmMu4fmME_rE#VbIjCm_R zzpHNAWYpnYWi?G`lv>b1ofou@NtB_D8y0s9yrWcl^a>99s8&2TJDC^QK#yrCUkG-( zQ(No9`(-y%{Ga5(!;ZSt5uVQRK*9dH0nk#R8Ew|A&^Vw>8|ccYG-UEG>kD~H<9>f; zfVVL+74x{72(lHL*kNS#c2l1v`ubRJYsk4R0V!G1inin1S%(URXuj-CZ#|f!q581F zzMe}+e^>wW$^2Lb^ry<>(i-zi==;oDPk~4DDa?=pV(Ey2bUS-cVfo#&{)F}>J&ZwngcAQToESSGQAWHY&niYl$L*{?{r@Ps_HZWO zKfJS^J*yfP)`5ZDvCZ`FdkO`p^X^TR}jLnQuqEZM&sismxm_rU7b#^KveN!X) ze#J`V=l8zX^?cszeXr~NR6Nk-MV&@39Q}9di;G9@c+<# zNM>s|{l2$2&7SP!;)#Alc2&e~%+Nu9(sXiM$fPXtj%}0keEF-SQ0GRY9nSyS-*$4r z3U9dfv>ZBybsc10-@Mz1J#MCB6so8Xs8xG}?qm0pa1NdRCXIj#2ga12q(7?M^mb_a zQPXQ!02mM!5U8Ib@~YVsUVD8}8Nl;49=JOWpXKK2u&WIlaC(%a>%H$K& zAEo=RF0~EhEa$X%V1d0SYcBBbnKKQIM^c?fH`zr%a15rt90a!{cS2?6Cg`sbKPuUM zqpHNRtNP7Mx1r1B_+=+%PNM;kfRhjgd=Omz>QR^cJ}KOwSU)A%>M#I6hJUQO#t*A> zg?7BR5=emd1d0B_Yf!X+mpiu;k~{Bl#8RwmXT7xPTfAV|TOh;VHnhB#$NU`&06{?3 zIx4P1-)rtxUN{?bu}q||D)P;3>7em&&%sX5#upz7`V4`j)Cs zIYL*5C`d#1vRE2#;Xl!6g52-D@k{8n85xYBcvN4(Fy%X#LWW4uQbKc67426-WsD0$cN=|bSp8;=bNsI|q>fP~P?Uo2a&W(gh#?p<3dUZ!7YZ0DwZ4G&b>pp0v zY1o6FQ4>4)%KTG?{LX=94m|wsU{N|e(){aPz|mg5NH{DT&f_zNc*il>peC-MD*kPV zd;W4ep;oRu-9S}0$n7?;Rl%(ZpEzB!s+Ax3px7$rkU?D}`89->SGVjLok>udFgKT4 zM9VSs8Uu%hi&Tn0+Qd}e(j4rG66?Pm`N`vT_3jIH@p*BGf{|fP*dS)D{vpAIXe3n%g~1416m(6~GF3Lc(NRT)KdF zVu}P`XY4u(V&s3mH2_LSdR&_rS1ie-_@?dHFMay$;Lq}&2v+C=BEZ*2PNgL)F zA7boZs*CnVk8kKO0|M#yPaH3A*Z5K0nWRy9Fb9l1V8=g~?%0l?3Kbt@wo_!yn9lzwn9AAmgrT*lin-Zuz zVpsS9kn|SMgw$lWz~g=7Z1+LB-}MJZi~9`QnJ@RfMtrl_df8}jco#pQzo^-I2B;Ty zb-2`c&-C7_dFTB`ZE5|s2;cS9^}c>YUPbJf>m17Pp!aK{_q=zSsatY28n-y=Mi6`U zp}wV>nWGdbbPXL)ZqC>oKy%cVv#t2I$_Qu#GGe$K>LbItY3PI>Zjam4cd$vl6nW2! zuk46=Ck7jqV?6oqv-a1yv$o4@=IaJy*)pB#I+a33_jb)@k?OKV~Ab z>I-s4_CJ*Gfyx6;f=1neR>kx{Z<+7)a0mwqK~EhW3XZyg*$68Tg^>y=id zGhkb~reb)U$oNnr6|&8MC~R7KYH9^-*WjTI?#<#xxs1q-)b`kIZxaLM@7JBf+v*pj zv__(-MEBz9LeQf%2LAA|EL33F3Xk>1>)e zHlN4`q`NHexOzX4F#y-RwykLdj1{pQ9zpCizdddQ)HZY1ox@Epw*bW>qhMW8?q2<2 zFRY;pcd_r%=^;a-2HpH3x`vr?NJi@|^Kv68yWGf7@ao8$E29-WbA~313b1VEXeXIc zSrNGPk*v`i_f=LlT{WjpJ^M#3=+X%5BX^qnuZo2Xp1qaFYBk#igT_=3v6{dKO4-xu zgRFCISuz2_zUaPe@WWWNoIB?gFCX&V#c3ReLfr&BkY^Q}LUwS^eA~=h(nze7%3IV2 z1Mf~GHub1mo4Bjx?z$kE(EHf@A2IKQr3Qfb4=%f<9uHn_nYok)jV1c2cFy2gsj5NC9~f>>Xr8kO0L6Drv?OcNfj&H#dXOba9ri#ok-QE3T>|hw zBq!Xm2r&ndBc2uyLQ*5lK_oONiR*>>!0fBob0lRTwdLSWnCaq)%^>g0lr2?+oj#)* zyJ><&>hqE(r#dvfN$e6PAl8e-gAK(ClKfzcFxL7m+eOUQ6`m)_1;&8mwze0_!KEgO zB;Co+Jhjh!dEAxat>E$;{fb3IrzV%De99;qt-V{Fsb77-gECo4meG&Ya^Hh*Te@IY zNpf^$e6aQtC1c1tBWKe_p3;XY%Y8NyZpXoOI>BEN0s|@DnVhNV(^)~DoY|r@qJ`Y% z;;(Onu_mZQ2cP@9ld|SKlu7gzcnCeUCD{qsLS8#F;c{}!MEyR+KkKCI=_rnzWo(%! z`>j0gq{Pw|E|p^$ue#rTMZeK~Cva6mR-dYIcGWXo@+a>dSLL5Ckxr~D-MYH{sMskb zWfjx%IPNGc)(XdShld(z@>CU{&;}G|j(iEu&e7WTwDrGC^}xr7PVTn%!o!zwy|Frw z+i$;W*|!`~`k~UuA$gT>*}dNVyLe5YzVqB?AXT|tB)NzPsZM#S%Bp9y5-`R(1M1!f zgVHz5riyi#7np#`?dso+{jbfyh2ag*G_ZtEGh_PqNt@dxwYJLKUjx;7| zi3iMa1?fA7)%6Cf^ZJ(@<~fHI4p|+|^(2(&^VO(*O>f2A@1F?4m8YMbjq!!wLgU_n zACbpZusD>Txo58`{>BEt1zhKGZg-03z`> zB5vyN(u6rvi}2z5djP9Ds_MNr4kG(7HYK@q-1Y6XIEA|it=}dD>($4fG>#GUagzaP z*Qh)9_apMYD5571!?8Ph3=YeFF8#%Q`1yVhLAnoZkL7vdkdrHR2|dcH&pMm9u{c&{@6 zV+E~`ChmQwZzJz7sXV&Z5x?z+M^SEL)J3B-=ta1(Q?pv|F4}1TQ2N%iC)a96-(f|L z8$3ZuYa)CAem8HiY&J}^jAfAiF6jXocDL05)oD!Sdqd8*yG5Am>LU4eJ+cu4bs~aN zUmYbDd2F)+O+PN}rUutto(f*zjl2w#6B+t$7P&vwUpqckFMrr%4pWDR|xKFFJ)KZIl1@^`iBCl zvF3U1KisAK8AC8wXMKlhbcMm&N{lhUVcpX)ukPt}`l)Hs_&YZGih^buPUdjn{I~{&Od6&%c0qt`Bo9Gw@&MaYu z^jBHWsImGY08rxf8%=Hl6nZZY%PhV=oEi$xcHo_U?U~Dp?t!KSM{~I2@16=+dx*!; zpWg~q?_Fr$p=WlQc|GgaRcsF5mU2m!7hNY%U0}tgujyfw+iRgvOT-O)HRlyK{pA{S zPkWz+so3Klx6SD2YqH!IW0SQv5wW$MMK+=-q-${cHDT5YvDdjbDsMuGeORBQdX4%I zAFu1Fl6`U)_zt~b_$Gv&(6M>|sQ4c&oyx!cpGP=HzTt=U$U@*!oAShS_%15-znqNM zZ>J1va6GL3opx{?c09sKfto-~udZX3fTGj6WsJ}rh%OjMG`Qu-Nb+*~_mnD8KrgWF zao4wHh?FqDPSV;|FYtNo(>c?*{9PaTM+q2Sw;!+Xb_!tlpkcny{#d&}8!$COoSBOy z(&dtm-RN9k3Y!C(4l`_%AL?sITgDLYWvd#JD4D+BNG`eNGznF9ISD0^G;~fbbI4a> zh?BF0?@fQ`eVe=u2p5;8Q58M5Z*GpK+B++th%K&}uAj<8 zr###_YxWuNh1Hss2j!Qn@()Ckcdb-@!%&+(SUai0)yn}q`Ugi=&xCM9kPSRICT6ILynRTM?rWZiJHid zil1lb1yGl($`zo-h8_}~f)EjU^st$0%=Us2H7cus=@U-38MoZ#e=*CG#HWzVdAV** zAX?5pdr1fDxsER|sQI{?MOe}P>SS7Cru>Nui5p6QM327uCc4X2F9~CU{4~)B6B831 z^8$RC^Cin*tEb%K(?b`MNi@~2L4I%V3yL^ZzXu`?s0>d-|Aj3fDRi_{wR;-V4dz2k z(oo252=sahv#s8@#i1ztbFX$BcaND}1%sfldLdms3#(?eIq+Y_fcduHF0`@{tD>4m z*e(yE+KQ+3#wsrf37NuludiPyqP?*s1N!Fg_ppf*C4DR3b94-JX%FwEuwCA>hgC54 z7d=PDu?Ox$`=G34kEPJr1+H+=Yp`ztMF0TsR>#XFVav8RQ#9bpf9U~%d%J-EhR&s= z?9FtwZUB)99me&Iig_v;9h(Q2hF&b2FLUJNP-!Iy(mVebDi^x;7|6%sDi`0AgKh&m zo^DjE#%l}xdyXOxn;aQcAScb24#PumYOiXs;D?Kj(}^{2$v)ecb58O~0`wt*d;UJs z=bKOTJPvrfqrIj}bf6B}2)QYj)qEEVEC`cRg>Snh4+$IudMu{_l^%YCkTxT-^|i?r zX{<9KiVV^@QJr&vA>?`?j5)!VCrlq4-`+C=X@@B1;GlBXLXcw*DJ8rpyDhc%C(lcG zS+n@}bK=quIFi;W0t#`BVuK}t9s^c?i+CzBIKW5)!~_q;Kl`?Q(>r*A7u=l+kO7yu zpLzH50GO>eb}CJ;CAyL|(_KzYA7-JJbB^Zp0wvpf95V*Lt?Jig zVZzD@3q=7VID-_OER(|q*Y7kMRBZsvrWA5+M^-A(8)%gaYDoK+?x@K3fCn|If|N{U zw3tECIeqirg2E1*^*TwPTu_56Z)>;KwB>>l7LMD#K+kOfrNWf(>-aiP3k-wG6MKGf zqX=sg{TBp-jhnqo!l-o|SwI=anz@hy-S^DQ`kmKXZp; zv1-eD`#dw>C<<^)oOqIay?29PFr@&yw|(lB;d6`I(;Ib^U06&euL)tIb`w~>9#gB* zoyLIjj!~rX>uY%pO!A!x4l1APxqjq;2`<1Ew-=&>i5f#V9+zr$B{_H5bioQbk4>UX zyX5YWDf@ngyE7e?kIIQQZ7|K`j#5N7R;A!4*V%UaXnpuIy%HxM=~J}!v}Ap5xg*jgO%ymeAVNXtDet8v7@A((+m9! z)aJ)(dlWXktvDcnrSDK$BL>A>qr7^wo~dpqD&Y3QP%pS`TlB*RU#@%r{P_od_>nJ( zJj)Apqtb^K3n)a#*9`)wjy(aQLzF zM}?GtW@h-V1b3`h1kJv+XNxi>2of9%E>MS97sED`DW2;1fn;D1T)v)zO~HRT;}Rxw zbje+#!BfFMmFLj3*XGx&u{O$1Lg4hT4Ap&_nmlb^wC{C`H=ljKXW|1lZ`&l~dp6`K zo{!iBjObkn^kqJZK=sPMGKCQ`FKL6 zi0mGtYuc*b0VbitkJS_RW5Lh){J}&{2gL3gA&xqaD6thRjUh4TnkiPH-4@YI$tRr)>Ge7a2kDp( zdxsu*;9l|>|0KR$F5poI*kV2YHi6y0)>@hto6?#53V^zvUyo02!OKk-ku9@op1@wb zYu~f7J|t#(q;ZqF>A6t?+sNA#u0G1$&OUOvXFkWvV#fQF4B+`))tlt_?yz__d zBDZHox?|JV``YZVx^EBn`M6=00Fz__AhAu zwiww5D7>OSLD~EJSa1+3Zm__|aL3`|KYPHzwyJMLQMx3f(Ko(|*sT7M*L)4Ylz+7% z?ra9+7;ZeP7k=qd(ZdM_tXJ;wZj6)T(EuaV8NiP>uhN$U_uh==UOorNOI%^(=W647 z(`KL@U~g`vKo3JflRHBmzQ(#U;*&-7D!~8NxDQ_sKHe&DHm*azrRl3HPUDApR|VQ! zE#Wrag#$g!l25O@S3=&HRqeYk&^E`yuKpO}F>1fNATD+z29%{n_3#9ceop+{&L$FHsrE`(V@CYP2l(gLpS=I^Br|{KHKRY5ZY@NiQA>C<|!zJ zTlqxawzz}Yc$BL7=mOhm*WFeq&cc;< zT8mQKlB|A=s?4SOe}?_a?YOCQrspCxz2o(dy=EBN2qXc%dVSvG?We<_UZ0aQqZ6df zxw%`B8EB+wZM+MjoK)Sf*mvYa<$)6vlH;g+?;3cQh?gWOS(GEJt&_Y=D6F(AYcpQgVqper~!(8O)Do0u3vAqFot;HClvd7e_ z&vcr0Gu%XVakjbtQLcb_U%fz#ZVG?z{|Np=PD zGe|$a*WOEp`%&M#AcsyQ15h{eLnzZeFb6=yFHmbC{^3`g^Sr3-cfl{aXIpF6DCuE2 z#*t2CLM39?tsaHCeTO=c>M5XCAMJV$0P0fUXEft;ep+xE0Q3DCjzgXIGkUgGxAOU` zyjH!OgRdW6awiPgn)btnNy3k81D{l(@IlNqO*Z;Z`NvOAZ^pz{W3<`eqn>OOt!a!e z;#k}l*QpmO*EsF%Q5cn~28)ojqDURu#&p0N#`j(?Tj!B=45N`+U`|G{nN*FtvOz!t z9+bw*80w*=VEp&-Z3+)*)3tt5IImjMhd|8cTzVgIy0?J~M>*b0KLEIYO=y?@gC7-ddeLNg0tf5>0HT;v@)GWV8$*`4 zQzyyXw!+sRB8Wj-0MxB6%8Rg&&9@1Q)j16}k^(qf$a(U$>>BT-+MCzZ%n_3+Tf=@Q zL^c;2wykB`=Tk-`|H#K;NI`QcQU`-*gfa6W)(Ip^3|p1YeFy*gp=teW@v2Nq;1V^L z^`VBxYSXmJR7KxE&SN=80kksr=lJ=?${7+=U*Jin--ClQj%?7g5~U8YMz4!pX{AELX<2&JZa*K*L7E{}zb7pmC&iWIv9$*| zfVEN6Jiwc;a~|~lU&v({e2g^gZn|rNG{(8?AhuqVBbO+@14|T zR7w%MtuBW9n{#Cc#&qv=HMH?1o2?g-!MvTBJO8ZehRfzFD$9T_NSzfSr7U-&%Wix)q2 z(Lk*myAL4sf8daA*vSYBiR8<)sxv4|-dP|Ib`op^h$bN8 zXd0Sg=ef}A4xUk`nltNd~e&D)pMRQQY zWItarrl0pV7kVTf?#D1~YBJRzMRPttDp~}(4thHveq*V!(_h@LI(JZME(|@zBOm!! z_?Dyd$s-DVs>2yM006H0r2xN})>G~QOGSMLoDSEmyG$DK5^dw$dxq&)Ote4_*@ zNiH=e%n%VTN2M5sUGAuRcBbzPy5vyzrmRIHm0*2Uj_M;VxQLbl?YPO`*CoFpC@MHj z=c38s>%ih(cy&uKXa{kr3bc+?fDgF)=t)p+XAYJEoqDdJ-`EnRsHlLbf~EUJ`#YO# znI#7ONc8c~0D>DsUxBbtmnQqi?F^Hyl*PPLwuxwRRohbf*}+_@$yQnAm35yw10nSW zURnYGc7k*e#^NpBJTwK|Gv_XMVj6*W5|jMqWu{4mJ3bms_S>^^TC`b2?w^6d_KLAJ z1b~)Oe@<%j;ouB>mcI3L_YC}*r#CXvuGc5!=IGqI_r^b!FN;c6gX9+S|B-oSPwT2} zZ72jiAU-+*2;T#Jx$%8!;o^dG&b`*2A{Vdh9$|!<6deYa&sRd!VZYsk`y;!}_{?WD z8ny7xUuwydC#|cT(Zr|^Z&AB;zt_<#Ku;<~t#FXI;~*87EBYe)3(B4#oBq%gUq{yv~b+}pR0b0dbgwh zn+5zB`Q6TVbw#;1;J3APc6elEgMwq*l(h*1qdr=_xBq@=ww@a)8@y=E;;Ab|f|%6? zY96;R+;Kr;K4mjEZu$r?Mjg*rW?g3fr!c49ji=G#M%$y^*QhY-9LwnJ8Vmtc2wZT2 zd?3ppE?V>|NFKZQ`NaIuT96v-k8p$Sa>Hg`|8A@ynzPr%t9Lt%?6sgtfs4OpZt)Y4 z-Hh@t8F%trD~HsP4+|bys;m|);bAxQi@cA=4~d%k?qz#x~a9+Qv7Ux$5P%OujT?^!yerq9Ao}U_5zNtuw zIpr5>#wU{)A+Ct0o|`(?<_M71D+dVEXAw|316C3Y3WY`=lP;8K*qUajT8`1Qv70W7&`%r94c zK$f#XQI1oUn2vW-Ed<>!ap3m$vBl;2pFSJ&AIFlH61gRLhZsj*j9-+-Y<)4Ivl;T- z?}1IW#oi&}y9rHYhHe?JLCxi%LhMbGn9I$sTh5i0N^`9`RNZoqqnA>?FAk~T)sM*; z<0?`>#vpR^$3~1()<}FHCOsh>-?k*<_Q@B?H|LlYoG0PB&9#FL`AV2RJKer>wqVj> zFL-vM7qgPQNLI*i?otk|Cy2^H2cc8M`I7&_li{+GIayH0Ix+%1Xx|qb*iG zPkggu#A2@xJ`n87?^u0aZi_8EqtwaU@0oKLK&@hix#najX9vkKwNz_B+e*$EpXYjM zcJ;l+QMuVsyD5yNFoy%{Jrz7+3g&upFe-DUop20_huBf(u3}+wjFG8nl^|^NYJubn zWU12XbwI({9e&e4EACVP*1QT~4iSLJoB7osJ6=J>rUF`qlXW};PWr+(Ord&D@dT7Z zX|O-MG6mxi4=aXUW_2bk?=NR>4Pcl2H39e4OoQEO!JEa=PVbr^WW6HLwy5#*(8Ml~ zjQI0W*W^AD6=2q3A_tO-vsdk!3pF`SH>S~+Q&upK%2e$HK$V1DsE_T`f(vb3n?ZBw zvyxAEUYOu4#n=v=u?jht5}TD4Zf;uUAZXXe@d6lAQs!0y&9nAGxG_qspqq`A9RNmqhOW1>c*7kqx*m>x^*e9TEC~xr*+i7s;9O=;$PKF zSrB}f8eOiDBEjrs2j~mIpDHDFK~9ZE(W~5ifXTCz$dX&Y%dB39+8jOb%RjQzne;z* z-352&Dec5;8qIxgDn%y_8VBWMjxc34;?n6HJxe^gvF!$kJ+o=V`KqEgJXKer=BSjtlrH99SJyJ*7qAAf?9fVR5KL(&RXOJpL zJ24@*rd=?4UnLR7If(qSyn1Y|gOK4P7p??y8ajFTruY31fa$i$_@a=U#R*{z^FY#+9Pr<)WZC@q!G?9X;4v{nSGN)(ZM2 z1Kd|18V*irv_{Xr`Ie(>+j{^|ev^3fWI!YC10MdS0|WW(u3)hq636vE(=Or58)Y>9 zKxu^Q=Jl!u3n2k#&Yp<@E5>gtH3flGGHgwYmv5UYtyeT|uBy$d%8U=hJzyk{gX`3_bUnz$?H zjl|Igc??NbQMIPU*CL(PC#Z;Kob^ar#M+%h|EhUcik*IqBy`Ef7QCNmKVd()4HW&( zQ0Uj^z>)2WV&(1PuVw<<>0TY`ew3!Q1bIzIU>&VAs~}A5#t+&R?AB`OgOQDc$WnJyWj4PXFFM;ESaD5X2{k z-`cpLAG~1x%nqkEbF+lxBpOhndAH}j}rN#F1zw2ROl>1pWn?U&(kz}^?X zESv~yr~NoXJuiM5KeBBjjz= zcfh4aoq7v&*Yw}!ArV0bX3@{hMS!-c+(%4jjK9w%C>PYjHk20Q$rqKJ*H&~x5tbb9 z-*-Y0AP>xRKXWd)PHbX`rn!(u$__z3U3qcj5fh78A2nS&M|zVqDb5`lf@+GNU-Mgz z1Iz;9iCVLOS%7PtLBTBGOga>h3P^qM8gK%TIuB0*I0H1atTskxukinmhnTt>WBr4a z_~`eh>52xn9upz^78t4_@e0r(BPx8W_7MebIct&^VkN~>_VRU7mi(1;;}d%+pMC?) z4uDdLikersY3-yxjiIGS9ZWjnKmf13rYhOGCL$5!;J;|NOY4IR+@*4jOS`QG zDu1^DJ?~mbk-x&bx(Ig%d+#$3-HrEKBu%MkVGEjFOBCKb%inH9ixGAX9Nq+-9hC#> z_RE3!QBH@0X3}RAQ_^Dp0$VC#YAJ^d^4?wO?xlr?hGeCX*00+)@)*s$Ea7l;o3Uf&S-h|%gsS%gHz#ikU0o6b%;0zx!aUaoRxuP z6MHDd0-5ZDU>1IEb~Y96>~**q)(p!f&j&Zd{%eLEwqTFeg(FV5Z6gS*qoZE&sL^+9 z{?%$@{&x0E;dUxU`kFgaABiRWT%}5JFcQ^RCttA{vn5FqMg(0#3z{Hnlz%VKuLQD78Ug@5YyMChSI6EnvQsLta)h^vO^ z%s!NBpa$0y%gffY`{D{q_Jq!+>oqV-_^Qd&ypTLoEsUF4C~N;OtIcQqi5fj@v7vo! z*k-cua(1ih$(xlJ^2HDE;@xn5ap_ucA~>f*;fJtzmu)l(E!ZShs7)79InXd#;^>R8 zC$G}IVUWR>gO-@1c@n2Ou<7-}Cfy#eRNLvIVqPMvj$fz@wWI>$KiQ)M3Qnp8$FEHf zdIl%Lq=_&fk_@@w8mw38*;0p5={a+t$I;k}cu9MLgNBY~D6?%}2yed)*&GeG*m)=_ zW(=V}%hb0AJ|s9fja4kn?BX8g4)8mT4eKwDA1vYiickw&4+a1Ih|#E%dJX0{kX z8Qz9=!uO)~F5nx}`g;#I+CLf%g2%9N&%Le7w2-ii(?UQG<;45D;HC~J;#0i82`jW% zqtcHCk~YK~5}H|NoM&qHH1(rcn<#8Z5x@g{+LY~No%!nVIdz4wIH&^wNANq;;@p%) z`d$OYoHK%UmH`XPjp6_pEC>qU3S*?Ofke^kOXmoXLBnlSt(C2fCkPPpo4{9BTf)*t zOpyBB)RRM+hTnOP8wJ!j`didp!uJHKlTbLXFXj(7 znx%>~0E;)7b39Y7q}|E6EOsF%FkR0-PS3eaFH=yq5o&~DDnQBk3Co|WN{sXRfM@gNyu3co>I|Dh74()NhbYBy6r9m4rFhmg^pHm%xj2*MC6}5PIqc=- zdNy|q==!-xLGS;MtAzc<8}ap=OrQKO1%4Qps_&C(z4`2 zX>PP=?)Fk1_wj;fw8|*iSm9y619vo@NJSXPJLmOeWZzyAWMnZxU=ajA);#zS{`)T)sBOqAs2rAa z8iMP;jZ9R%iz238;0F}gr*j#pcjvwX|+gMKoqMf_1-O6yTHOn=<( zZ3ekjOEr72E5F@+*Ik~$_w2G?v+S4I@|hI3C5KrP*>R5pfX9T*j?7|78v-y42}1EI z0;luDd0=gVll{l{?4>rrAtwCGAdvMPS1&8;lk><_`KCTs>yy;1F)-o)`tjP<=b(}N zn9DjuVh(Z(ez>d1V~3+6cZtO9)hOI9(N&@i_Z-g!D?j)nXZCx%B({v{3AG-rW&YF{ z?>+B$bCsFTNYpE=QvLV)6S7tuDSH4KU%Zcu;A)=+z@z&8+&Ky4C%pvlg`!04`71pA z4LDli>PY_-cgQe@r{?%jcX*_~q<2btE<|G|kL_Lr87YSR_J!p9#5{p3s)mlNq5nc- zdQyUODfmIqz`lD1kitt$E)ZWeJgudYdbk*o1W?}QvMc=)b-$ayRPCUIaofFqvjPue zn^GxN@>#cUv$_ODVvH3G_NZbm@_XyLbSoP#41tTIJyp{KycMo;R*TUZ;P?MI4a6bk z7iE>KJP0021x$KW0q7R9fqUW#I zl%6EL4(s1HAx~6Q&r_u(q%%8mV&B5Q^rebl?XW!(B=*~9HF;dQqon9?6mFxv#7J=* z?2g#F?oEZcFuWu-@EANE1U22eiISzn7ibuHi{xt(f(Y3oAgi3~H7%pz?D{|7BPX1r z*fp5X?36#T>M9S+^X+_4)6egFVfg$we!2f2_uWoCF+hXUnTX9=_vGJcwky0h`h9C{ zfL(QwkD_wt+A0tG#*dTZftx9ojlgo_CVvrV2<%BoBsQN&ZFxSXZx~@sHKJ>bpH`rm z@E?xua`)c>uZd6?I4H*`>18q@^WO4fv6SyicZc|CLHy49HScQyJ!~f&d-}Zx?RcHl z5lu6ak5SyWht4Owd11t0(M5dlU%t}j{k^K6!-;t_>P|-AiSl!a{M|-7=5BoNn>_W+ zViHqJMdA5)HU}||RT{{sl160!JL_iQaVT0+3K4SsS*yeyns7vr zXS3j9sU+j}_*ye>=dSWw6^(dDx7J^sp5F)UFRw8rBLB?R#4#%ni0z8B+D=;TTBD=E za$))7Gva3>w%R=TqnGN~LU#{khj1e+G%`6$)g1Ty0-s&KtBicbxW48gxF8RjV>NXb z^ySa`y8C#PkjuEMprkX$%@SRE$IWEGP2ya0TMh5sS9-}2uJ(FoO4`^D!o;z++V|YGK7|V$GIo#3}g$Z&m2Q^T(nZdTJ~L=^gof;rZ9X% z&o1#JLw(Kn%4d!=U;qZZh$5Co5^3-z3d1%?Y^SQY&y2@|um_T&yNLv~p}Y7+?AEtD z$pMxZWV#l8jGwCv*q@`Jm<66c=28kdW#P?AV~UUOJR7WeM`{z{SQEOI^YttsA-e2z z5g_}Hi+sxGYNa#1cwT+yjW4`VD9=YRke9XOwhhm#+$A6iC2D}lgW^KK!H1o-pT>bN zY$gp=f!}#$Ise)TP2cgxPOfa@F*{Jxqw8v+>A=^Q5Qy?^?siV<_paC}`wkXp+1Qp~ zA`hk5xC{~L-gzjF&BjqwRU-^#Q|#|TUp|1!mo#A9^uGK$1(X=JrGTHyIgLJFRUg3X z3~_t$^tKjD&m7L%>UduM=6%Y-=={hNT%lZzur01%$C-U9;ak+*kMLYz26yZ|IXA&? z-xG)d!lTi5C33bVtnOU5*c5gnVgPD9t+e;&C*W?Qfhz0=Um&vw+9OB6CVe%l-BrJ9 zn99t9xK!f&`ZTTcAaYDTxZ>#u{4XrR;Fh*RpDdS~`@&p9@Yw@!mihEEE#YGr(@mA` zaQfju?c)I9FUb+Y2g8qH!rIq7l)?&gx+q9$9^WgAdW(U|H;5p~j%(vv?|avnhn1)* zXp-b>1~ovlSslisBA%z32%X%V7>>DQLKiOJSvP3^66B;~0=Yo+sjphehm>7qHMJxB z5$Qqw@B%+=DlV#mOT$V#M@Hg|D1;pN1M_CJ!}8|xnV>yZ_6dE;>H9&}E>X*dz|-T2 zChIVZuCb7w)j$AjB>WOy@Qj<>SfsidYA)(D?0qG}> zb?V^$j9fC2?Ob=_d7Le3Eh(QIQM0q8U8@?bB3iv?Ce-XcoBMV4UR9OhQ#v&4nqgq0 zPAbWT6jhUC&(>FpOMZ)fL4!D952Ca^7M*zJ8w{?o^hW{LBv*G`IM0_nUor%gnVu^H zq6wXeKiaI;?O&}wO?=0Qde@WqU*e6#lEkBlA;`=|Guq!-&@*JC?%!=Uy&k?ZQfPAW z85R;ZF9^(vTxx5^Lytn6NPCOc&a_<&XO*zOsA+VgsW!A(BDHEm2!y#28P zzuYC>9eC&~ocFlAAjRX5-tUV~FL=_zuNjXt?P7|=s1D{Br|Yy5q=&-~%gdWa=K^}* zJ%$;t6d~X-_96E}LThGBQhAB@>;qtrpQWXJ9Si+H)dj!igV<{9s_Gr^s!L8u#L=TQ zMY>1+Q|6CqjZ{sv%7|vgS)R#G{KHGp3hxQAN69;3g8po)PhDE_s+E+Lga0*<0Du5s z8*=E=hMJPFWKaRLvf`nH9}a%iKn!bYzao~H-<}x(xS)ZjLt(RMpqM~l`r8;-Sp~!W zSc_E)p7{a`>ly(u4z6*gvi_m4tY{4QC(oEX-{4qi^~nTY@0XB?+ZmmqW~{u%%f2;oVcoqW=^ zoU}oYQuNa*O=fMv2m~%oS+aaC4F=L2c5%>8D`H1p*=}V;h8qTM5uUrN7FZNBVIXwM zyI#HZBGYqV7o7Ia>!L8AdL#`=$`+k{h~7HD(?yWzr#ibS=G<0|yNV9980# zoxVhD0J`(b&qcKi{7IscKRE(R_ahoCWe{E z+1N}MRMph0^+L288Ttpbzcy^ImNTx5hYo*W9bKX2fD6huxXAdX$mZtec40De>ZS4@ zjZHswfPSr)j(Wd7+j-fH-0nO|9ER`I$~*R%J6K$nzLCaS>Wyo{JBRgaIv<`Q6EWc~ zqb~e%{*$xM3qb!Q@(8aepNVti#&e(<&fSFy0XT|h!41=T5@Bqo-R;jgV#y=?3pN>= zJSl5~0mK<2G&w+j`#hP~pyc}V_r>qR0nDA*Mb$iMrpu{>WF@}(*CD^;qCKgE3W+2? zNk-VsXID8^#efRmShX&HQV+6w%it;tl4 z^ruWMc3EY>7Mu%^82?~e{&x`|Wz+Li@%|uKNkuZQ0||7<2)6!_tlyzi13l4& z>wvxvF^|rDnrzk41v&Wc=9Zd{+zM0+*=i>_NU_OaLV6Nf z0Y)Ag2pFjPvA#qT$-7cgTWfNYK;1KaDY3G5@3J?BkhU|3AL_ z`!V-(m(5Mc-NH7niF3Wic(EDCOU@2oOD`INp+%h zjt)*Ll}g9Y@2~4|z2ARbpU3C%`CQlgdcU48$Qk`#AzDdrZ}TjqsN3z+J(zW9l+?D& z34MRWd>wmfpA;05O<%JqkNZyFFQmon7~bZ)W_;H9QO9xG{QYpW0{>_ho@9`dxxU!D z1UT#86v#<`e552Z_<1ONRUj<{&`YF;0c!QGzE3#T9A-#P#x5k&y0Gvhxgx;2P={dl zTarK1nn~nXZ-Ir4IYblt_YZkE7Z=Y_R6pL+Xa{X*(MNillx2u`8yj8$UP^lTTKzWu z0_0iN{`Dn4kRtwrZx&9VBTal&z4!bNG9g1PD&^45E98#~*9=q5lcivT&LwQnwo@JB z#u&AK^Eo)yx%|wRA`h}!X?Nh1GaI@zpFfokJep_@t$0+$_^Ne`2Qxwss6WDIVc)5{ zXiig;`dT$z4sOm%RuT)=jLXUuvy0XMWidKgSr3Bx8)IVO_Yrj4q6pq z{!h)#YPc4f@s6i{E4RMGpY{9aE+gO5*S8M^ci($C`yjdWv1x|ivd7pEQuSW7iSS)c zmpkKr{<&Iy&veJA!IY|x`N2Y{^F8l$j#Frk%NdT85a|R#@E|!BWK21EYl0JLJ8jKs z@fKS%vF%nir-39Hxhpld=(&e7)b~vW7k5X!kKhio;?`MB%G3AIA@S^=H00PoL z_ar2INiTemzCX#PRsKX-nXS|A8WMqq?D1hIoR8#xLlQ&#m?MzvI{#ND@q_7g91S@A zZSee+z=Mdvtt&9lfW~dZa>!TG4yFl^K7L*9=HLlI%RM#2Z8vF(J(vi<{}g#>VVB|E zB(9-tNdV%H(Jr+PeQall!rf4X1LKKts!;<+U*xu&l6N_?ni#|}`hY;BY5-vN9@xhE zI{PrH>|X8_{6 z#9g{IafwQbm7^H3`6nEm^wGcBqKQDq=+Pbi{0$H8_qyUi5aYZ8ugBEyU8uCrTTJYYzqK}Me%j?d53EtXle%xjfcw$7^_Zt1&s5KB zefNGXv?n#mIQBC6p>E0HJaF|j)ThDWc=s(Smp>zO&eIy0GuC^;4SI~@c8dR#zT$rZ zI!U)+p)rKvPFX#j_|l1+M_;|L=>=l?$x|YC-F#b|Ke4op7E-^Zz9B|6KFzwEvmTPtqPC z*N4Bo!{~y~Cm)i}iMFio1+q_rz;v|*C#lz`S}(6xX6oP1$gfmw>(>J~AAAs;c}EyQ z_V?D>nWlTH!$l`yv4enU7@?4XrI6vLLWq^7w%HSHLU2|l5u8Z$y`3(cJ&_atAFs;RRxX_p%)qi*beakLU{nvn+CIk|AzO(ZhMKDUEa$RP_>e zp(Mf)+qT3;ewnW%8y=d&a$e{h5z`u>?;O6>n3S1-B!=YTfhmn?O z>$M}eCs#cUoloJ{V#Os%^oj=K5_+p~O9?nTyL7%S48MYWZ0dR+Vsub` zG7i|xW7g~yxj^Zy%s@|osVK8OLW&eodDk{IL$*5AK(e@!j1UitSx@szH=B8vna2#( zg77nPu%YJ;u>G*;r;K%Gw7=DODsgb*S7}E|C^j?e_|mhmx!jBKiI?h zyClVRgC|g1flNV?$!MKcgV+1zv!h~bKuz|5Ya*9%% zqD9hBv(sR?yK4CIt~S<{K?^>Q{HFssiReBgnK`S&P_w<}-KR4fWK`!q;dmdmB^zvx zNhyafgZ_!SCsP%h$Cv$8!3fv3a$L8uz5V<3qFyDAWNDl2yg34v%H!RxA+~HjzSSk` z>_!TGLmwP&h3`5kI5)%MD;o%ry!!_RUZAB_wJ7kzvj!W?IbL+>_KSQ~LjqiP=r*0N zdIUb<_@>ve`kmo5%VL^QJv**u_VAUNKK-tNBG!3u*GKx=GXXgvA;api(P4=1G$wBC zmVfly-R|0dd!^RRC#JNYRq<6H!|P7Y4IAHzjp@k1{akti4ZW3XY5U^Juk&XN6RyrK zZJ#plZ(N97(zGmp9F8X?P4yFb&6jacR#_!4j%Eo7cI`KTEojAy(q*9PuQ&))Qa1KX z+=3GP{E zDflSJ9~Iq;=K4*IGsW$pe`0GGKmedk7-yPaCTp3w>W*w-VW1x}{y-9`#Bk*4pO_2P zz%c=BZAk+{)S!J7Fl&a>oHl=^1)<27=}u`r)$D(&lYG1t?#RFYWIo$(eTICV=~F%p zlOUWJmOJh71w|M<&h}}6wBI5Suipg*(F_aD7qAzYA+5)!l-Nb4EPSh{JRFmsr47au z$aZQvSxm0sh%L?US_3bNQa`Cql2Q;(%F`}`j8Xm63%BM18ChiIT4Nk7;R7IgsAIbO zK?xW9U|M*KWBqICoItqPd21L(zPPz*lK)_e(-N8wlp?`b<|6mAfPCai!2>41ZTw=+?IsZf|V=lCpY1 z4tNZdF#*1(E*p93+#HHm=h#Tjtz^uP?bj_8xd4?g!$F_sKAM2(4*p^z89V3yGR(p~ z>!9x)J2BHY^=az%Ie>hAzM18}ORg>n2-qH>a8ax(z|BUY9+y?!Or`m%xCh^6Xo=U! zGpfOsP%<=5F5Svi>!v8~C;)CoM~QT~Cn>mA*Kf+?k)Tbv;|j_6wkOJ-nFb4m)&`br zTTC3Sqf94*_LV!Q4eNfHksPK|NmIc&XT+k4896YSMXJ!irrhz)vLtS59uqW zWn1l|Jo$C7v@zei5M9K4&bd;XhT|27;(;JvsCc(d*EmIn9X#{1nl>YyxrmuI*cNABJ*i96ZwUKjUc(_843%ecVCGuVG z!)KXc9h;YCnN5j2Rxw)2H%>vb|tpQ8?Me1Lw zJD?)Y$5nI4oKM+YmPQoxasg3`6NY#e1WPth%ac<8vMl1x=Seb(OlE!9hZ+0cboMJ_nzn zoE0&9URi~C)|m>7hyA#Ejzbr+Kla~nWPS4VRp-B3jij2{>wI>8;1p!% zF}*5jUfSsck<}#YpPYbk5EBMY9{S|A{Wr^%Si& zUNe{8NfFuq^AMhdrax?nIO~b-*4RZUci#upaXH-f zzG!ndvm4gqgBQI>Ewo{iOs^hTy#MaUe>Oe;4b&N#7n<(I{zN%s$adg}zEbeOj zM;nIb>>FWVc688=wvsGPD7%!yz<(?bvkQMF;rYSe@0;VxwfNue`L~5qZptf9nMO(P z*wLo%{66QieOl3??bo)dUDDY|OE8L4mxoPO2uA@xx+=~i%}nzLUvU_ej7Tm4`>4QBmlTK z;4s|WJ$n|5KO8=m^i_rwv4kbp8fD#Zs7UV8IBJc}OYL=`e)@c(wlF}hzM@0`0Q+Z4 zasXLSy_MOLxyQU{9+(Iwazr*FFcAP}iC7{A)kmqL>_p@;U->9`V#pM4IpRX+{*){L zUp=&%J=wsz<#htAj;lw*>aVo1ucA<_E5$)u9bW(d(2x$MH!T3$ER3K|C^?S(V~95H zF39pqDFWz+%6FaGxI8?>lVAD_vD>nC0YtltSi7}Pb^(Xb&Ho5$lhUZRH`RE-!TLiYFg0nF>5{5n?Z*=(tHjS+Yx0$i_l-q-&tio*( z)_{TP$PH*{_=hz3%<|=AlyxUucPo?v&bW*Qe`fVE%_9e&V~^&!pn)<8T&bPIX%KTm zh~c#&vjuIZ@(^gf-zAa1SN@Df4oZe(rk}`Vv?blrXeOg@|Gooh-PO7`3V341kM8WqBlFkeCz(c!+4}f==#f!tVpIA4cSqht#1}$mK=x5vzb4SI zEzDRDl>%JIhu*DGfxth%z#-4|cMKmRJZ&mBhN1C%1*3043mm79>t z7PjL(gm)12i4RbAbD^F%4C+BBSU*jj*%AtV5aJcQ9S|ahkXL}DJTc@!C(M*eZ0XE& zOq+g?`Yh14%jf(X1}rhkyoM3U43WQ~QgsMg1P=2RM9JYn&-8Ug(vkrK{c0A>M|@NJ)Kc&e`<2pu3%4D4N$5cOEY$fWpG)9k(>DrMir{uxZW z$ztn!Ni;&ear3mj4~NjF6;4?+p|Yq2z%KwGO$|4-tJlYl`Bh|7e~L}rP4ypkrGBsR zf!qzN@h9pH-zca4@8?@;Zfg5toXmX&*#61Y9SAoce_ViHsZZIy@D^Wh3Ie5oj+_H- zS=q5eXZ%O%pXHOPLcR9h!e9pXdbK!T6rgDZCWE1k07U5aY{<&VP`1g|L2W7e@~_Z^ z-f;jT?{Dm9L_NS6mVMaY3MtrZUH;#F37D~wjJ};>4;b7o6BM1yC(dizqq+G+WhnJY z;V@thnei8Bk3aEAb2fj~zK%oDg4%KBbyp=#{8eHhZkwSczl)o1LCk1ydB;Ew7ty&H zPpuF8t#bATb8~<3`AZGE^JI+t^YxZ|w}~epwdaR*Y*zUUQXg}j{5BfplU@oE$~OR6 zUqZt%-+7(ej(D9q`j}OK(6PefV1N^6mU4ur?*H!oS8cnu-Q4f_%MVO!mG89`z861+ zKiEH9LWqWod85uzGx=A~T%SSslxT-}Ql-<+2Y z^ZjEZZX<{2t=94i%w+!g;$Nuc4ARQtc5aIBf#tUZ!@GYsGu3PnzA_^{O|SMmbyv|^ zh1xB3n?mC=31@?|A~S_1Q-YF4O|{`?{tGjXI$xujcS9JmOoxMxvDvEa!p(tv;PZDU z`?aQ!m!bs5!n#KG;tRm#9Z{(-Ty+h}g`JXfDC1sN^>I%i$20mdVjhA&i2m-K(~rp- zP07eAbJs)zUtVPx}0l|CpU9Rim$5@}hm)$I9b> z2%_S4-NMY&R8C-3{2AQT-s;e!{wFp#4(Zu$4>z=b3CieeZSNb<^Q<-4ND|P^`l*m< zH!MZ9&@f|(mj@+&#CPhYEY*<6l1 z*<23abMv5m3JF|A0{c`9PTC}6U>Ml@B(N_MZA_kF?k?B;)hRw#{f4w;IQZqCM9HIV z5!(+-`9(eUW_8-$Rbyql)Fz8MJOyRNvr(~eOSrQ0+1dJWWsv~Aax$(=qi)5V>6+&q zcQoiFREKcZ{)v$_^iV(Az`93r8r0-d0@dg|1lZ=YH?VBb+IEm`s6R30njKvBdu^3aBA*pp5MNWgDdQv@TY|lojq@?+>%Yk4k8ey`0#@{xO!$aV z&#S$FlUho6I|mg&?CQHr8530d#o)?l##c4=V>+Fs49A#rf`8&KySPI)i%g;MqO&DC zGg7;b8__L{HJcK0NAuPS-SN?02|xP_dre* zPip_FdzluG!}}fLt3Q^)PVF`;b zuB4P)o|4KdyEbv)vyYjUHP432`O6+}R=>sKs59Bosz1(?)=L}rdIbd3|J?bXhPnMD zH-RaTbGwo@lnu;?n;xU%`q-s7noPq`9qnNgxy&nH3tLL1f{1- ze}#Zc!GdvuEz7OxTIS$^Xe-}xnvkG-r!RhdxZ1u4#%_lP;B3B@mEw&a zry;{!$|4O-N;jZ-rK?JWOf2`9nJzVl&7phghTGPuv-m zkv470^KLi$KYmj$Y=@{nqlnmzJ0Bo8&EL_YF~J6eC(b+6S-N-Z?Kq|LOc7BF;t4t^1ye zf>M;J0&V2lyPmKsBf4P9oECk7KdR%T*=_kgq>^#l(1sfHRaDC!};$I*;MX_q&G{RQ#j?gOR!$v-}%J@aA9utEWiBfcYwgrs`fBw zPhH^|+x1woH64dMl)kggLa5Kv4Xb`F`O z4o^%^8PetM5%K*y;yg8|jx#!&{nF3Fq>yaZ70y|Ygx>+DY%5!)6jhzAz_X~qWZmO; zS%Uza-d16MQ(aq`L+~H~d^Wu`d+l4dO}~TI@P-QtaC$C0Z-{vhH_gGD1N_hRBkP+t zS|Az?rQKD&^+v49SexdEFGm^RJ?yQ&V`{{X-BRyKXZJc@@f9y$pUthFGD7Pot?8}4 zLO?i#gO=-DfnctT3*1-TMR&P{FB#g0@|gfYwB}(slyV0Tj>JG8i8aJJ+`ZR_#p08! zMrfSyJ1a5cK5ml%f0;J|IVEbTLz=X~<%-5w^y z?{S)(&p#zl_iix^4r{oERmBf__55i9`X~?u3e2<@$d`RbvhM|F26m}0hZ&(hHcL|D zIQ(5>ZIL7d*kOFJ8n@fwwX3<7gh^)VSJ!knFqxcDwg|`>a%Ce97{PBkIQm@LLS;HI zg-A=+cy3{_V_9X^T~DBAN=!m)E}zcq)6Dh{4Ezo9A85}p^c~f$xx9DU|Gtja99T8z z<;P(Vn%}3Fa044=C!!!od;NK80Ub%^#%4FOR&}&wh*Q@$EPA0^E+(F`*i(k0A{1}< zexcJ7*?b%)Mq`!SfcOF!l` z)?aGU$JvZWkKhH(F(XIk)@2&FKS6J~hh&7zLx;fe{=+HVH|I-f16n3jyC1qrlB;yj zB3KNHnQ$D?mNEh4?nk7#zfG(|@xwJR8?PXN-Ha2SZ0yo}u+9?@pi>3k!TIH>4*Pqk zVfH#SPiH8U`e{DxU9G`Eg~JfTT7<{!f7n*Y9!8w0&fO0nQAAe0B82ekhURKWQwC_h z;-TU+@>auXEC+)W&wVj|Gfa|dFY$(Y`Vxbu>Q5UVATcyfcMj1M#PJTi$9U1Jz%;3j zXZncB4t0CFq;t6NdphZW?2-Gi={f9;j+?-OdUGh6ZjIm8#wrVsG0?1P4p*D&bCN0c zLQV>_AW#-$zeLVVe)VWKkUIC#?(d4tsS;=$D-Rl%{E)w2n&VphKj|17Qo!ut`U#Y=$p5rpHl`;1@yx-%5gBg3W5U*_@e zLVLC+mfGCw_@?rY{Z&LPp@57K4BIXHML{t5LSG`iWMR~rmh~VJ^E?zW+|ohFafL1tvHPoe;HAG|&}{Q%?RW3DVddNYb?%N;0{7OW<8X47 z&pcG&_I~75LGY~9HGjU^Dq)ePcyNRf@nu~>DoMa~jJ)*>W9UEi)VSwqvj!1EFZqLi$48Llu+J;cf+WPwpAwFekKQc+C1u(Rg0>7h2g z5U{=8rwLR&qGYs~IoK`|Oj;F1DE+w^3lwgwO8YEey-C90$4U5kt^A@y9PlSybrd%+ zbl_2!&2uWdtKbb$BX>fj>JSBFAa~O`-!a}kufdlXYMi@ar42$_%2GzZyiw=Nnni;$ zk%_#6j+-x1$RsAe6;6(p>L8l`ps6}|{1N>7&aqcF4_Mpa1Em%kKTFQunCxvvU(S1! zxKmmN{jMLiEEUio%}mZizv-h=J?hboSm1gA+0Xy(LReAbWPh-QD;q&m)e*NiYc~4c^yyr`z z3v})dmi7R=uS+8MCYU&wx`Q*iIl4R9=n8K0iF1gIJJ|*_jG|~74Ov(`cYXFmn>~Z_ z)7JL;RFpF`_0RsvVL?qSV)(K!9(e;s<~0+R6HL8#|2G^t_PKnoxe{?-iLfqGxPmfe z2kB6|o-V+bx1>drU0bRw&408{&isy9d{6_lXpo?!$RP;Qmt9Wjs9e)L(*AO)5olvf znCiWaIrVzk;5H6jr+vrQ9gFKV-#q6#a_(8n$Q35ew{KNL+q-;gE2fJ>Q6E6qTU*8K ziV&~Dcb^4rK-hs&$o%2*mrx6ml&^5%}TAq}kM5d;#W}^7boFu4T~z$iW;KnL`>dm+V#AYAo4ge3TtH zmQ;0X+gNT%oaT=of8N@u@v}Rt_;SbYfQu#HU$pP6tYIE#edF2N_pCHW>uAKLP*1e! zVIJ#NF?6ENY-ER`WB2p_$iiqo&-xCc`=Q1KxO$_?V!rx#9M`Rzxk8b5>1~*rv9$4? zRSj9jh*-t)L3;=zXr3;%{gqJi;GSB^aON<1P$-S|2}>!qi-p`?QS2QsJkGuLhh>fy z>r}QI{UT+)NpnyBprBZ7(H#Cc>yGw4Ahxo{s;{IIYHMP3R^AvSFZeU~8ppM}D*aeq z+fyoT;>G~RRxA*&xVVc2a>}5$IFnuShH+j_CMwjTOR=gyTC`kCdIgQp5nyQ`@z}f1 zyIBr0G<49Cmw}iv#+RjfLy+3WrQlZ}WI1F>$2nM@hbRKtCBW7A-@db$IEFTRs|@3U z9rwQdoEbq9dzXP&ac%{J9qM2{EKiRO0J942#j@2>=FYso7nF}iltsx6g|~t_Wiw}o z8M>l36qoP@5U7B59obgW>hi3cc^~%+r9H@8|6C+pRwM!bDucLjY7=Fs^X>GARf6d- zO=6JFvq7mDts<52>zU^)s0h zP$ljYV=fD!2BILdP{{;^VP&3qC2*u2cVo%)iK)4!KWo2+S#|8|VR#ET<~(#^jPv~< zu7f+&Sfet8zx7N=GF`=?799<#<^g{5Jv!rb_=Z``1=ZeMVHI1kqtwBh*f2dSbzFm9HYK}YMiIQQ+ znhKf4mzaYe=+gdwo<8ITI{s|m98=Xo0vxfmiqp*-HRk>KaNb6Va8n|7Bc!M$AXp4P z_?na&3+0lip|Oj95AO_;tm_76TBn>$$Taszfk%B~YTQp96s4ZjO6Df#LI(HwU-C^) z=4!R%`@hJjRAqPVdzmyp=kiM0vRh>}lW z5K@YU(c9?07@uL#5)J`9JxrRj<1?Vw;3qg;B*sY>GW^{57XnoHkLXn{f(5UC_nC+@ zzu1i>N3CL6^9Ldtipq|_dYH(@+~&K_-CATxI+C{GaI2mWq3|!heJ9EYer0=bUmc;lm&*A4s{Foz-mmDA+T#HYl33kv9xHBR&bX);5zuDCvu}L6Z zS5=A~s(2X6u~@~BJI?c6k?T2tmqT6}397{@qqb3Thn4abDs>aMP)dKc5+VziswKUd zl10g_yo|zz?o}ksRt^cd=5+HZbFh~dIo4dADyB`5$j-a@_BDl`*0PK)FCT*1f+&bU zAh5sGMDeXsW3))Esr~Q?oh1a`ote@LsBTVfX90mB7@b>7W->XBKplA6tMX$ey2wL1 zc`iv{O=rT#ww7P`kiIZKKDFZ{Ap&ZxZl9(~aVP_d+Ix$RNJJn_Zx-bF$S^2$hcHMW zfRWK^@llU48-6bZi>UqsW<^!-6i>FZ3q@s`&*lx`PCoYOUCcUZlb?}sB$C|I^k%WNP~Pk2!$;JG_M*RkUK1&jD5(#FrptKj#cU6gFc^ zn}nyfRlzX6Vu2QFkD2jK$L|aL43$;F$E&Xyq~LXU-#$RSeWJ9PuSh)t^m1->fG0N_ zIq6`&@f8Yfr&P{ctNe1KAGbcgsU+f!yk_WFDw+JtH-Fw8*oWLgZz)}^>RD~qpX#z(M|pk4ECRP!ZcO;KYVihEe^-T=82gNo~}Tjv=#1 zl0ZU}ByO>Smo+?%2I5-Z@}Iuu5D~DT$&xBz#xE8-w?|4}mF;isiX=f)`{|O7D7z}5 z$DNBrM^>YbbLqJ;tT?44b)Wu#A4{S&miYQ)>DxtIDq+n6#cDBC>E^w0^9O?{JHPrQ zs+g7fkhA`0Y6W>>+~dd0VsC>?Oh8N*ur_Vv**)9s^E#XMWOq;Izl2#3gz>$eoZmD0>X0Sq zi?KQ6`qP#SvsH_85748pWv;D5rE2D+u>efX{g{+-ZGnVdYk7a z-xdbV5$mhTD%84#UO{hp4TcpY+UnxYF|T$1|M+uc#DpkhLXJvN&dEiwOhr|SS;VLR zro5{b>{XX1r2Vx^!>?|#Mp0RFdTK-c@b(kBOhMu&S-lu`GJQqRqpbCD?->@XUnn8I z?$lrF7Q}6!SF=C`Yg?w20Cs@>HIBTe{YbMB0917^0TFruG2~wu3h@Skw^QJ;#m&G0 zIcr#U~vXA&@%BxGF1vF(XO^WV};VjUeSH5}aunCZ z0*bN@78_EgERyZ=Q=As7p9Y1w5Z>vyYqs$nQT_z_yJAHZbc2FmdbqN;)qJWY3ThEp zL7Y?X3(!!!C?^M)BPuKeZjDT)Dh=`vYuTZZ1!{SAtTz`u<`QPW4(+CO;8x)vua0dr+WZDyd~T%WzbSNx@evs^-mzPM23Z2y+6e?W`?=<6MC6Us2(wj+Pj0(3-6nm z;FZ_q^gy;tTmL8%1@+eU0z&qQP2XyJ@kG5eiK$sABSD`Bm8ZUScXqO50alai$dTxWnUQMP@mI75B`SA|QlW*H{B} zv~{sqpH!BK;Hrd4X=>V6Zm)UlbQf^L25ot3b=joDyP6qeoWvgwA?9wCBW1t-n~sij zmSV!kenk22Xl_8!{5)#m-A4Rknb8`R8Tu>VQD zGbvyjM=G&UOLA1R&i-AV^gt1su8J23)D{*bP_}?A@(bQ4DA$xqj`V7XEeIw?5H;Vc zYQ`;tJcv=!yiOJ{*=O79>FLyb=it}PSsf`lqtz-m{vyc!!sN^LM+A^baa}_Dmt_h_ zjWf=*B{-jxYz7ht&Q^anm$>jOL5BD4nzK8$8flr*XD#w_d-Z=ebuaz)@1e~FUz|)j zEUSUq9QU*b*~P^KTU>6Kt@)#7eXkTgKrubWJs|=Ls_E-ZCLoXGQ{tt|N01iCg9#rL zB}VFCV|0$8Xj&&58U}M>#x7XBMrmJ?|5d3;QiV}tRt3+Uqizl83%szv+bNfOn&G_A zum~yO`xPCK!B=kjXi1-n7u_Snv-fV~PXLySos!(oTFK2m;l2RB;%nvQd24w}K#1e? zOn2;`?TrMMCNS0eU*aRlud1FF{nN?V#1{tYWrnloI!##36MfJS576rsOsGKT<^fcW zugx@c;;GMld$nd zN!ei1kr7h=(os7`2Ch8yy`2i9RS+@Xs-TO2~Ag*8=4Xu_xq9U!`e!zUSDn*$S?Mr{E` zl*Q1z1G7{6_@hs)NB8QJynY}WD9ik(02+Q&ah#?~A@eVyrYXGIb#9_Ozvc`~=o_ zlYxwa>`E%uGxeXgl+UeCt-#hTCU2~xe0Qk8Z!b^(Dq@&WBy4O2Dl8D|uw~z-!nQ~qBZdrkWt@U4A3ykFD?9xz`kf26xzMioN2g=iI6c8BXL<2w5dp_Kz4u|T zk<-ht+x~4P@p3xao0m%5DJVmGqQRqO=gT(N*gHDp+rygyzdXw?~RWRV;28|~8@;;IbCd9>va&tbBlZV#qWluu!0*To%b7J50MBIfP@ z#Hz$W40kaeDI1KZZTZ|BCj32?F98JtJ2)3s3xZLVHT>DD=uZeOkzDa_f8Md)dptSJ^5`K2@L#gk{ z<{b!2PRDIPQ)`ywm*lc8c_*;$Mi8KR_D~I2jO~0GuOA>i#Ib@k2i&KuP@d%ay%p3j zFbSk^GD|Qv9X9822d6na3Ga$tesL`zPSk_U1fE8Wnk@KjUxu@`4v>vO1a) zPO(b_6g-NtZjZ|xL>K^cJQ>c_w`|SwH2d5m9yUAD6&GjL4)eYFkI4s(Tjmre;ZZJ2W7-@BEy$b|B#+#y zx7fjgLQd58&&141aqP{KSTIX8)HE81Q_D-dY=x9-Zg9|98NvV(RxQPXBkJ<(K@#!h z=MU%}SQ$MvDz*Z8kNe~UqlZHg#5ZU9F3ofGWHa>@8h-7kwGM+k(c=pmw-TP^6;uCrRgxJAC{1YZ%PUz z=3oSsswbEY;1LM-#fCXNxeRi01F``b0UakCQBhwHsL~@lBtwinc8v9u6a2Fz z8v6(1i+4Z&7H0~Q;_kvsAlCKF^hbLT%5bGdP$MV@H?d{8?d*rp3U4B264kAc01Hmx zFrvv831|*LobYI3>SZImZKcffUYyj>dx0HYG5Ae{@T^ z6`HJu^6va?uhZykpdvr}Rpzl$=SE^eH$NI$-W^|+yG2~Q!JkdHZZoCXzCD|fY0x&E z>^>jGeTMd4amMh*yYbXjM=_C>WCPLQ=qn9`&EJo=xgG(h)HCn(tW#@)oJZD3G8 zwR;j7996oY$H_9dIQlKq^j}YBzlNV~Nf8tBJ=a2hW{&oFEB8$>L!>iSDDZ{qy^Djz z>wDnIY2F-6uu*U@EZHaDIeBYfh7`u;1jAyVBQvb~7iv|gLihoFk-S`@B!oK=qzXM9 zKPNe>?2AA2)pHaedoyo3XKv(i_4GN>%>+*8 z3-xv{j@awHiV`FT+h?uKOoK)TVJqGd#fF%0!*=hU6>rgTMtJMcjQ1*`>AY716cK{o zLPUU_#H895Q**G-3NKennGcOPnNn4@*1J-;Z&O-x$fv?p>XCn$2|I`G7a<2A!F{76L6y&w=LjNEfbU`a6i&3u_@>7}_b5J%r6Z2ylvEXG=rt zry5S#0=)G5w~Qx3FtI+{pkRwZcyP>@-M2ClhnR@}A=FWwj&t8g{29UnmUhx@mjrqO zt4W6^3iPd0a3Z^V(*W$_ulBDWEaZ(03o2!C^%mP3wg{wQJvrv&oSqr!2WshpbkPcR z+Fb9Z6>5F3C4+{T7<>_CreA%R!*LFDGC!Z6AHv)Ml-V<53%5;(Vhb~#BP$pD4n9W~ zs!;R zrwAkhsa~BPDElOnA$?wr5P(Ci7Y`hrK#?a}p!V}CAy8Pgp7g?6h(E^M!4E_8IzTlm z`C9%7^lix3=Y5pd*@L~r-(GH4>y4`81Bo@$Gfa(_>z(s6K<{!aBKwuq8}E`Nq~90s znH6Zwzo3i)=87pU2G8~H&>`8xb91|S#bXp+>g~}R{+9)%&t@M4Y{}5HsCLw0;{~8V z^c6mj{1)}!=6eJAVY}r2qv+hjnSS3mzQbqp*=%eKbDr}tR!L4}=6tF-D`cb+(FiH0 z&75YGP^lC`sq{_fMKWi~_nV@O4yIHzGE%Kl`|bDFu3gvtJi9;7b?tLK&;7jb*E{64 zO?WyK@>c+9>~1%OKmsVt^1Ggtx6ICShQ!|m5Os>e11JPm$(c2W!8!Tzvv=Spj4Q9@ z1M&c(I+8R|NI*>3l9|K4uD+anSzGy3c_wG7N(HlE&Hjzf?tCh*1}#F(u0rJv{vCZf z8VM*z0?vmO!jm=oxu?`Gb`;^nPB=XtgSx@0kr)TL>6oi>#hOtD-8PHnY=O^>L47;!m|jih1VV06 zgb*^?!K6Cp2y`dLz&i~CX{(N^FltgVS-(-GDI@`X@M76oyTD&Feq&6V+E#-(1@AXL za3kAiP5<`YGq|^QDrM(+qMPTVAFu#pAf-af>-p$^7WcAe z+1XIV=SHpAQ=0B8FSs)YEQrI7u$|SZ5)c+ooOezw$Tkp+kw`y}6+t?hxDM|xror5s zIGa*p_j@;l%yroE-zA_L(zd19?$mt#tzusDD} z5{}#lJ24#=j+{^%Cfz>a=jY~C6orsCJz^>xws_!FgRDWGz?^F-j64y!!N^1gBnH8_ z$kY>2?MCCX^DLk2&vp-S7;SyK1;LlQ@~-UUkl(j;i*0(^eXz( zo-%zqF*=EUpMULeOM8a07dPv)6D9&`?)AWK2$z+K3W9TKAvW8olS<&X{Gcb{Km6d0 zPzDL-!`I}Sx+UZl?8R}g>^8+S)Vx}b0Ct4hL||$keiq7R_&2$T`0&O;XP)6U38pag zaLs$wc0or>A#69yzp1ZKfZoK2NANbL=$%SNHBQhu&w6IwM0xG`&I|8qN^9~sh9d3l zsv%cinf0z|B$ugIT$`<@P|P31nYZ!J_#kI#v=Qh7A1fh!*!NN;T}<3AD=-8x7_;VQ zW}UW&Gp%GXOh!SaET*F3pGx0L)pzPEuf$R6NB=+5LR*{9wp4R~MxtG+gr4E^?I^Ms z+UTq-WHc_*Toxk~&dPqQq)Gh$nZyrYuT(fw3{(RmAP@y>dmkBIMnVi2GSnrhEO+3H z?N4HGHUVCws)v+HO;YNxESGQw^vo<`Ll(J0mLIu*hm5NI&*QsVRFh3h|1ZPn!ws_FQPp$8)3RWpaCJx)jJx++d^$26BhCvBPF1O)cZEq6BYo2& z74y1GQ&sF(ia(@^vS*9va*C_G#z)jh6=m5?b(PefibPo1Nfl+;z36J?N62Co1X9H= zge-V;c1jj|MD|U2$oJB!R*1R}GQ(Y3(N(dHR8>m}iNroQiCHL>(!1zsvhisZJFmpi z!=#KZ#xvPcvNgwlBQOqu;qJ@!h;kV91i4gn!)xgt?i;V^PrnScv1!%gP@V~t` zcQZRFNM2rK1bhgQ+5)#4v7GOu-_KRqlFad^mp-5jiIh(_k;cpjz3VOmO1qq!Kco&< z&{c00=?*co{)^Szt~ZzwZPKXSAa>-(xWqjcYrBxiEylY&3izfsXZrXTft+Y6OWg}Q z9!xS;$4VVa!uI`5Vsg_9xH(64Pn48Qvli-c9CPSv!5HUmTpp`I=0eeZr}njiJ3$eL zDY_-9H>jVLwpQ;_y{XOP0mNX2 zb&xk3@&wHOLAue#lW5+_4%|62QH=>bjU_3VQTcLM8?>E2KVqJp0;~ItuY!+if` z()WMy+f{upjJye|6~XCA^(Gz2kt1}2BjIAlbrg1VJNYT#Ahb>_1Q!yHtUjpk5$_Iw z9hB(K42|mV?!iD_A2-~cT*K8^0WWaA><1i8ix>P0D#XeME|vRN8_9ipsp^2;OW;vL zf1fbPhbKIK0I|}!EhAoC%-rHg@-OAmGm(^*Tw6|}Iuwk(8ZEKI)m%hH%jNTpn6@R^$u;ACST(Glfol=cV zF@bwSRk>S`DcbwZ`dD{vT37;P$uVuS6{9x3KZ-w*(zLU0kTdC7B?jtM?ldG6RMB^y z%)k7zcVAI8TE9KBSrwn)Aep-fx>jE;Jow;r<*{8z&XBwX-qkBQYz>xyN`B*#w0nsB zn)yJ?89JPjWm|C5Xl?buUawxVAkW|WaL`Wq!#|m}|GM{i)1lXm{LI@8*bUr1=lq!|Kr8!2VvhXojn91!uJIpyDyz5I$$L zH)Kt(JmmivHHk6-hmo=5YS_|6{)JO;97L)r=K-x->;v}W@7J+ht7DH{2g|Ak(p9h( zJ_{$|^X`RNC|=WB_TP;MuY2G;n$RBGGJ326b$*0=-Zrs4P~2V~ZDyKR_*Wf>Z79xX$ED@{9S^7tOjSvh3_wnA?J02_gi!?o*9V#z)c6aH+l~}m*6?eS%5?QxI?$!`;)!8B?1p~ z24{ZSYbOn;+Y9Q3Jb=)auEBm)^PVSi8<&AwDIps&dRxGzI^e|_mh%p6wq%u z`~chxNw~k?z%&qXqW*r!(b68|S6G_2gSS@xdQlP$8)1xbSx6z<>|$F=hvb3e{4QAdilp39hyxpi2-`y=XD|?! zhhy9y!{?qFBccBU_3)ng7dSA&1;t-sGnbe%x#I=pAz?w)s^pKP!Wt+wd}BdnV6OIhZ;t{>@}rKY%>I4XROXjE)ZQYa}Zj z-xFtc1ag>b>~hhCzvp*o5xaCQ%M<{;7I@OVx;za?=FaFp zzk(Z2cxHw2=HS4~?dpdl{S~LmD^4rOxFy+C(0!ApGL?wgjM}T%s;L_5_R^ic&7C`( zf4f>q&fZ?^I(rowu5pdMF2I||eiCGgsBoo(ZG~sjl)3CfBStZ%?mDE*yJOh&QCYQF zmnFk59MTnINi645cERYo%BqN^I55k@8l*XJq*8n6N6rbn@5Xi--*%u8kKv@`w$G2s55Rx9*&Sf2czfbpx48%U#O zj;DkTkPGUc_4&Pl?Dg$C$e^M;-9q?#R8IqjdIY29&WYTvVz2%9I}Y^SS3r-IQzHi{ zBp+azcM$Oz_j>5j!4Q5wYQNk4fJK~2%Zaq0?`1V^QJN-CiS|XAHyTR70%?piG>jof=&l6Uu-M=qg-E2IClh6Zij3(rsSPH(Z?f( zYl01+jV2r$r1m1fwXXIeZ1`bD6+ne#(H03B!y!Oo;~q@M-1LszI?338~DTw z29%ViQ*?1?JG-IiJDf2nDuL3k#Hgnx7R~aJ#ao5>2T&qQ(6`UXu^1&tMLBA*819xm zhaF`toTrrvVHof9e6-#Piwsw}Hht!?(GCPbsAQty)q6l_8ZPVQT|dKmAquX*KeCZ6 zgxl5sqtDVKn7PM&@qF%fg}GVV@c484n)z1lrb51^3RG(Nkl%c~Kz3gs7c8XT_~`7~ z#JmYv?+vvUTcr#@)eOYnSBk~ttCp?l={`_1!ZquD^txL2hjN$WK3AQpny6G@)K86# zhG;3DXug9jxJDkJ?8g@s+l)*1yu8L6Wm)7LKT!yyD5RVZCODbFRm!$Bts7(6%$*|! zY?{5GOC+39!pErAtLAICKQw|E{DNKyc^D(Czq4)M&lXce(@%{6CBC#0vLWycvaRBV z6vmEMdKHeD*0@Uw4tVF^oM4Jz2$!LkTauct!?;{O8`Q^|6Y?(&Xepa_ZqpRJ0JiLQ z9}lYOl#yO)m!NwR?(3)Oy05XW-}jAjE)^vT5ocC#pz?_dFsI<#CA^Ap)Je@1(u zqo3FUb_xH@3tNm?v5)(Uk9Y()-vvwXDf1g61}*oS;GiZN3fJnRqUzm_#|c!o?W=jp zPdf*)O|1R+)KABv1WRq-1PPGs&$t4EBzEM* zpdhTy;NY$}L=-GtUarYY#^N1ygvY-Zb}s{pg~d%J2K9s7!V}Uo-SvftH(tl87A#h~ z{>aQUpo)dx6fEru_=<)6b>I!r9QhOzcVQ11PfKCGGi8UQY5C7zS1_B<9`$&rIPt_T z)b7&kH@KR-Z@A2Pv%B-RX4LR7BYy!0`q=Ff18!9f8e&}00#3uXVd}%AHVFYf4;oBgaO94URGFks)*Km{OfS&ams?v` zO7E0!P4VW{M7}dv4cFy7&OM8fJTL(V4ReU9{gMT80r}HAcOF|aFt+gxYtaMVAzh>R zT~l&??(^_rc8ag-b>+om-;63Z1niqzf-M{trvo-nVO~WkF1SR^ z;^CH?HD#NNG!QK+=D0=}tV?BM+r_Hk0?K+;xflF>g|l1Xu9Vu!dj!JUG_o79ZRMQD6)8zzH-F8V#b&Mq^iEU-`apT*-3{ z!a%cd_DvW-HIL|-QK?9(6pB=>u~3s)2v?5Z+{E}x>))u3Ge2;^MNENB+ROk|D=c+C zqekgQ47Uo?V#e2l=AQoZ9Lj2yOV=_n&=8DLhRWHq7wcJsLr0QQ!tEfs3^5u4ZY{-U za9w3uQf`!Q^y)Lv&}4PN@ZKh8Mu_CY6$f|kbF~I0H)}#GS51Ds`K&HtOQE83UGw05 zkAbVl3dk8-GGC#d_Vf-Y=dT)_+?-(G0mW@Fa@_zLB3xykHb^(appJxza8H!HOcQlL zf1-E5EPKQ1nLXLv?i-Bc${M>vdP8b^TO+PUEd)Hw{5EvmZ}F;7ux0KWdfaMOrYl<8 zV_&H@ERQ=v7^n85$VasI$V6mAV8!bfjFNcN!V!}I+*P}^Bia$3E-mjdM~_5kF}#lD zA5{h{kB(il4T*3%?ss%g{Mo5sx+nblgN&3Z&osR6{!oh^q&k#K+X6UDX+^GG4 zJ~8m@-*smkXDee2vT6(!I%W&Ewg~sP98F0pbdYL4tky~zN9`F27;3omM|d<~=!#%< z515ryvU^yIWqQ3d%Ek|Hx7%|OW_HHwH{*ogV)!0J{FzdJ_w|`iN)F8NO*hv(ac`Lm zZpnJ}h8vgQ`EU=)%e^sw^zDq+H>~P);L0xsKGXBzwtF zYKh*1l9t`9><7Bekmm}@3>`xxS@PN?oLh{>QKkt3>=j^}IbVb#VG4O%Ro^-?*xrr492&~eo z1;PU3ehaR*g23jUuLc97wzHhSm>^PCO+bM+cyO^m=dqR{N5C%{-@mzw{BV=bg>}+R zZY$;_o0>7twH(PSu_A9;ixV}=Nw>>cNNLr(ZpV3AjVayddYPwW$}5J1l~}ITZxx3e z;{0NLLtOa*yZCn1f3^LOu^?K{q=f6fdc=0aAO%Qg7VKWq4?`_&$V9X=aBjE~fw9CJ zYzr(WH(;sz<{H zBL2o`@YMVzc!dd532^w931%()Jg%dn%)$c4`LwZV3eApwUpquo)RH?*Yet6Pd-654 zR{RH4SwU}zoN`oaOa0xNc>k)~g5A7Rr`z(*axCKaLH}^>CSI#o^XcCX=w|RJ#x^0j;Im{Yd zsK>3 zRnvJkM9dTBNb}6lfXU2JlZ_q5=DSs%h|<1${OIJeJntb(&PwELae zqYVYHlO`qV=aPiG-Km_(pSH}xay>=J-iIzp;Fn8I_Y0*5;L$b}U5QTlKfm34u{QHk zK!KYA`H*Yv8j{5~m*pW%iIh>!u!aq6Xe?=JfH)DxMyVb5 zEzn>KS$I2|ok@f&grWKTa>xx>i=FR}JL%V_d)PDngRLUpmQM!z= zs%G>#H)n24=G}XQZ(5MFO<$>6WUNhSv36!54c}*bTT#vN{uA7n%^SRPSlG!TO4=3| z2MTx~Q?sVfL#8Df+(Wc9BtYenx#gS7{PU)8s+cSI=pu!N(P<|k4I*~_&>VZ=FJF;E zDV{a0x5?y>!9Uo_pLY|QK>65N>9ZJ^_-t7>?9(hlYL-3UE;W*)M`p6KF#ix?u48WD zeZH;*KF=V~{6k(q+W<;mq^x3ndIP27`#P;#$NTIy$Ac#(lxhs2Dvbt|Y292(fq6EG zZrat=%}>~L)ZZXW7t>JIbAorSj>ke$&mkIc$gRlcxn5^FdSUX1tFtxR7x#|XZ-J?F zDrJD%x{6E)UKU zxYa=~_d}gc#P}JevqGBZ1-9!EUzZ7MR~nRR_f!Wc%7?GKRv;3y-mlkX@F|`jpX+jC zS~Q~D8XJQFc;2}J)+Lw!Y!wV&C=`)TAx)Pdt?8shC)H?xb6u%0RVx{129^14-@1^KC15AJZj-9R}TFgHeE=va#PrRjs^%VW6w}oj>^@F-=>9_mr%@ zi^%NpQNG$q8Or-$*p#e(u3QK)n05s$RKkJ_)P@S*$-2e@SU}k2-SNHYcbF9EEoB=;V>_h!r7?z%@gYdrooIcJ->_O$v7IZgfs;)}}p zrS#UJYIKYkPk?^MtO2fL#`Z*o7y-*D_I={cza7Gx)&vQ|cOBFFvMC5E7ShxgPe{4f z_uH_AxJ^Bucb}8->RBVa558@HQ!@Q9H?N-?h55r|y@dMPO(qmIeL&{%Boe;Y5*YPR z37dFz$;C)1*u&u=^r`}zN=@UpbETbQ_Z&ZFtDkx(S>0CZ21-lhXd2i@p5#2yy0djn zP=ZESiACt$j%m7n1?+bDl64KX^B+CObhr5WA?gjgaOjWscFT7n#9=6;dFAT&CI4S< zAYDyk;_?X_@#M>=)Hicv<#mzwD@y*j5QEKs0~;#Lqx1GTE9(#pZNXly{3p(GE?FEF zJjI#dYGg>OD)f?xb0*?>j9e_SE2lQV%WmAJ9)2UcqDW66IwQcO9%18tSj@wco@EE{ zp1(m3$(%Iqj?!TocMC##7hu6k<=*LQ)8r~(ss71&&ZMAaW`p{YM#_iP12{~~_3 z`jwkrE?|FgQlZf$z1WZld7Iw92Jlh}ri6-7!(wgNHf#k2Ma3E&e5nJKm_*Bub!;80 z@}r+VVZHGp&jjIQn&*len31@8t%Hr z-%UHh8yV8g_i+Vl624sV+a&+b$cfDLRLMwo=yp#P|8dn!A2o-e@WZ2x{O9T8(VSoA z^Q?SN8Rh*vP|jRJUCq083I>Ur~eFwHcd^*vE& z%+$TeS?&avN=E0_SOMum%2T?!aHz6<5nOa6=AC(4_`>a7BgaF@nwRB1q&MEMDtNAnj$I7!s8v zg2sb*PZ=k7qk!(EM$#`BYM73_NbP4ls`wyaDihE}m+uuq)IOYgv^^MvKXOb|*(?lE zB3j=Sn&CNNR&(7#^p|aglbxJdXiwCiW)bmqeEwf6YI!hj!>lgPjXENri9s zk#gYA_GIjP1t&S0r?s3n>(RMYeEKtVI5k7$xjXWAHuriN7 z9I{@#C-a3*K@|T|K9mgPHx4`%y=L3~GTCsO=zlbPD$}!9EwugoH;CpaXH0OWBt)H6 z^5N;RV5lB^TD|4HTs%Yyfqa;4d`>lwHU*Th0dLokPtgFklHj4(%BZ>s=Xx7O(pRH=4t4AGsJVK29-B@%A<-h`>T$Ol zTA06L4-BeMW9qu=rYM%MQkqZ(mSTo?D~X? zMrz-vL&dCzOq*=~+V1x1v!`HEa(1_tfkbpPerhJ#mhKOMK)TJn$XBLY5EEjToO7#? z2-ATaXf{lGfV0y54$cv>H>DM1@X`ZnNHqI#z2fhY-9p;n@Ts3!{w>?;f=pG*p1sRR z%Mun5?DjtBp7-+m@u^MjxJk=;;vrL!{|8r|@l3AAYy4K1QTdmRg9`Vp6t9LsmRw2N z88T4ruYOm-2^`{lHzmBBFdb4`y6p>Qp9pPVc#Km1sf&feC3iq2ZM<(K<~n~1oOVn=i;;<6=z(()eLJ`;1-@-pG<8W15w8NiE3*2XEj$ z5+FFsQE&m{&N%yR=neQ=!~i{uMi~~XJ(;|xSmn`Y61c8`?b;mnAjuwchhRvXo?F)Q z*JN*f`$fS}nk(;2;p`RNzP{rJOGlcnz6@nMt!3(7yO#!veC!8uO9v{1aYwX_3;Ydp z4GHm)1D`)g$Bd2@{lL9RCL(J0SIlaY5b2KqO(jEAqSTWxvakPWVZ0SZlpb- z5Eory__f>>x2W~9U~f^R+y&-75cmBpXJJ!2A!)HpVc7Y1L_R3R1kyM|?GR6L*durk z=-lIv2^g>|8T=fW{p!|;%izD-{qtIS}uW>7}N1pGr< zAm^uC!$+A5aDSd5RM*1U`So3)uahbr3lx{uAqPjG>_)?@4eD9 z|2e9rf7A<#($2T8gmamm?z7rciQPu2|8XH3JD($k;(s5fYrM1~#KPqcpTszwl-weI zT3w&bs#U!Ij3dAfh}>{OSYY6+x^K+Y3nEFsMDbxuGNquhz5Y~xvFAF)>a)xr+|xw? zVBJ=nI0JshYL#mNkE5U=5(!I_I1C`e;vsjk?{akk)Rn%xR>k1%*JpcfZ(Es6HWKIP zJ?xXC*L)PfjEof@?ejWr67Zu43tI%A&kATv#14pa_%#(zy)Mn~=k1`4_?&5Oh$-%k zPDkKLN#|y0TR@$g8zv}#^o^P9+kyg%kvNU$Iz5P<%g`lr!BHP8u@(aWv` zXRfRDQ1|xQ7BkK>Jol@rD$xE!(%Ut2VeaT<1DMDXv4sv@q^DY=S z2*}5k6K-vq&Q08pG0Ii%o`X4-<>H?uVtCz^@mn#rt`PbVT6UOrw#s)W*L8IxX1eMp zQa}-$^SyiXXT|!jIcV+?zdHM|^repm`FL)74<&A9OqBErkvg;+>0Z4_HqRs? z%ZlYQNo;RP3pb?c>w3I0!{y$vZd>7{d%gi3h9wX>%i#Jr;2eF_{WC2+s%p~1%dsaX zWaJ#H&+yX5x@Hvd>b{kOIxP$PF(<5^(P^01YVk|Tcq3z9T_L8sxUz=R!x^pXU5}Sf zkVd1_Tv%zc>kq{@rO41%_cVD$Q=o-_W*YpPlL?KEQ6izWxh7Iwjl}x(d3GUKr|J8n z4`_S>+J9ijH5T{yfRL;9smyRjZ#r66|GmLXdZ@9S;=R$%6F6E)t^}J#rSshP?{_9*pTJEmVe% zLZn4%NWi(vc)nrBz8VPRQ)$(6_VW%_&kSLwL&N5fHG_BY)k%xNQ43e^FRY7NeIW7f zMup3>T#jqs>#R}suSqQSuQ?ze&fa&#U+m42`z?Q*>%U-922py=FMXP*>@^OcfW3OS zH|K6s*@k(i6}F7`ZHB!E>zqJ$gp?EVUWW7CpB`CIIADDfah1~>Y`RtxU@yqEzI^1H z>f0&m=7X}E%kNdA>ZhKiKRN$e-eS zB9=LSg-8vKtOK)jMSd(1PmGC{hA_wSM#4#4n=vdUlGt``Y!raYgsM9g?=_%-3}DQ_ zZ7AB}_l?#uUmA&H^BDi?F@U>BD&QKpJ~WW)`W|4)`Xy#c4~}N5EcAB&)@8qkLj~Ou z7&M^`J_QpgU6N~05-~Tc-|!jj7Q%e1A*y<0yRXq?2c}{jGc%JiP6%qR8jNa!XTFW5 zW=>5j@a^f-IU(b{|Ja@q)J}-3^9F}E4jD{mYct;Zc1=&dwa@!V9;6ta!x)AKz%E-< zLmGVi#~yZ(gtK$?H%~Do7g^$qI`P531plprauMf$m0P{MKXiY&ra+=0ow(eo!xxxH z=k=1DCX-rmA{s3;a3@uSX0%xw{C`4ch?acu9duEPqiTdx_lUqA4ha4;)_Y-tp=TgkNE z_47SFv@jGWeI?_jsVkWa8ar2xR(zOlZ+N2_-}8y6?FdI)ddw zwD*iOV|Jl;4&yf^P<)knrKZcee-6K?EU9%gV%9Yb#ki_^5*X1F!6r< zacs|qcG`vWy`Ws0P2_%g`Tc6SO6{XA2LS8xeAkbzYH#*J5!Q-$uIxmvoexhPPt($D z$+RV$8c@nHHznaML!6Soe*bL^NW+sId5k2d) zxuH`^@(M*yR=C^HRLfRBpyU}6+(ilVsxyqSp)g&6X#k-@N8FyatA}^@Ij3oTvRKxS z&x}e3Q%(*O5ze}dNTlUP>x7h!biHa`JLNHt1fp*K*|@hv1gr3M%2k-_&y;#RBuW(< z-Fb%=^;Pm|<17lFGkIKuWA6NQaUVD8jxH{jGbQ~oMa_t*ZEHHqeKD@H881z*?k`NU z5KCAe$&HkD~n_op@+f}X@s%Sc8ug?m5!J?%8bFuBPzJ*qdqYq26+uQ{L>o~ zhF~GXO)wwMpsG7=W7`Sv?5-dD9JigIJg)G0EoLfUJaDbkerkcz9RT@<2EC7FDz_Xx z1ga?AZp-15N}w)wd7svaBk!_n^a)I&7Aom>pyJma+;)}kfTH#R!`y$m2Yb-mKcEPO zQ}zmt?rg6kLvpwHM~e?i?hS}6GfLs53U)(jx(X8ZQVe_1WHDcA2(u&+f5MsbB&YPG z!#BU7Ts^28!0b`^95iKg)iUiM&~4TudV%|$|5Xd@3FmUl5@S`yNxjmfmxNdUB1KSd zrCe+@*jae&3q~*X%f^FL`^R}eGXBA4++i29XD7*~f1gS1oONH31A9qrpI=})XN;fk zPGF+g^8-IMQZbJt`|p7|KUXzKij{md(PkCsX4H367tWK<=Fg^*enqc5fNAWt1DaJFk2g2{Y?BChz0E^K86pc{xkjl{X%&iCHuN_3m9+ z>>=HQ%J(>+2k#DZeKo;arZfFY^Y&%UY&Bii&BetB zPP7fqTOKIz%vz1tXKgRo`{n1sRWFYC5U$)|+8ND%G9-F7f7$c0+qt;T&u(6S_f}>s zddH`3Y`68?OdB?Xv%Iy2hs5MA*dR<393@wgbR!=%y}jlYZnz_W$07`VdKvQJqK;9K zzPft2m)%gquq)sSz<|qF6Pvgz?J>TQ(N&L7!=+dY@Wo;Bl6xnqbvb3ltn+w^L;$65G=YG@5o#tor%9 z!?IITYE#q4xLK0I;ijgOdIIzK1Ay@v#8Z;RxzB<_2Bx>(sg%y`Re{7l)Z6e0b;7x4KKJH=XM$192|L^>@*e?m)^D zR|HLeNlsZBo-(gfxFY?Vi^S}^#DNyPO zr5U9MQX=AdQP*u<(+b?P^c}aM7V|W(6JO{2zbhW+yYGmyFAouG&v>+C&4AnhaSAZX zzuYk@!g3uYq7pvwKaCl5*oqgbL5{5aR3=+h#$9dfa^7sndppk-!m~*k2O?l6(ole+ z=+}3VW|YC(a4~xb>L-VX*=*eb|D`+`x5?K$l%0W&QiQ!dp7!BnY)z~?2DRIW!Nf=Z z_qfZ@s_f49BIA_s=vg?Zf-o%%i=dU}p$!uZ{Qnk|$n zp7$$tmqhSm$bMkm4+CMyXuWivC?YPknCZrEEnlD9mirJeypHeD8N-AUZ>0Ih_tu+` zP3z8U)n6D0OSMtF=ZeWtdZhA559Go>wX~C);jz%uXLgx+(iI1(#6b_J#j%ucx=MZe zMQcwkFg0O|FmVS{?ln+w9F;J?^O6>`b<3%RBUVf*sL9`Xm5@yJ^PKs0qa*EkI#n5m zQ|h?Ws0mJfy%h@CDN=vtbbl{w5-fN2ttV}R{AYD`_0TrM7u?fcpvBt^m4i`4S1|hO zLx>ABJ+nBxbe_2DqWkyTobLvMU{g9?YWlF{lSu7zxrg#CX#4GyvaXtv&6qV_SfS{d zb(z<}+bCW*n}IOkrLv`mOzf8#&Hnx*JH1EUkfFquP$ zAEK0M?_CFX{^YW`nC}1TgGsKGizw4@4#lEh3`ivNQeW(f#ul-XY-`kJFAw#`f|4j~ z9grK3yL4Loz`_`G9se2b3)xcrQg@UyWxo5oprN_W*}O%Y-3w0r;1JnBwYg!BA+T(6 zFopYKTI6I1iTJjg{qF3S!}E-6%QY4DXIvT%r9^tO?rrT8Taof3Bx=JW1lEEw#Ojzg zE6;$8WoXI`u4H{eDXK*xbC(31!K3#R(azo!l8E8Xh07Imy>O&$ZmvE$NYe>ESc2JtY^-j|RC6%%CW64xa^NF(?n!JO5E+IB3qp>v6 z{DCbo-YR&9?+3L~L+|p1w?Q9Chssx@^iLKGxwfxL?a~TsX^}Q&-QS?$zDte_xJ_j> z9mjQ_8d_Iy=JJ;jn@y}R((@1Qe*2}jTq-WzDT5=EEforel8#GvS?Z?w{~fyd*I4oA zm;C#`r6ZO|PiU%cTb(6Lam&j66=090j4r1OTdM+w=Pmtijoh62^BwYca6NLz!P#=R z9-#g%s_D&Th|s+PJ<}gji-lkF`^kwS(cc6RX&UDcd=IOixv^{D3tR;E74Vlqpa8VM zkfDelrynfwrkCu<$nGUkq5#^Czd<#v`0-sZ3S?+bkb91|{Ui~!~ zcW{w~Oc6ob4FUqhBRG z=z7)Ki{=a|10Yw@5<^C^p<0kG4jfZbfCXs>nuWH{)6|ZvAX9%T1keBg zW;;Cj^G|8O8WGvp6*t9N3lBhVDKD%s@Ib&fHM0(0ravh^xkb*7Yy9AM(Yo_kWDTnO zp9&?o0Db8^3&eB~1yFu1yGR^Wkuf+1&!7i%0a7m;xwh z?mOjs^MN!}TgxI379zpFC=aPU$&U?FOC;SaMr9A_evMq|%zr1^xf`#ua^XBIi3^M3 z?gVz}US-VGn{#*gCfhZg3fr48p6jm%?*hkyq<5-`0&r_6}6V$(rcNDFTCK{F> zvocFSdb`vUsRaS84x?P*wYVJ+uNJJ?6bpAqr-_BzPrtwL z^T(wZC%rUx943~$KK5Gs^#@nIgyRe@YZJ_e+pBim;cVCKqW6I*QM_z z0+1Pu@pi6d9^+4p<2iu}^U9+m`8&TCPS;Yz!(uV%HR8^UQLT}PY;AD+`e9THHr^Bz zc>U?6$0RQdmGqWmlrTg3b-9pUSoHTtR_Pm!zFkDyu{MeK#Nd5f17)Dhk4hU$nNTr@ zI#Swoi>)0lgJ6e@7P`c$V!Hcv^&~%lb?M4R1C$}?dPH)9K!h@aMCa>eGV>hL&_<#h z|Lz8afBKexl~{B_u_F(5zxXWLrE=VePD5RZ?kcb@MOeTw?i&1zljTxvB=W)lWWQG? z_LQqf;CF3_@#ou{)_F;U_K&mGb}C7ngG+RKL`e)#)yIW)&7s;vw8_* zb|USoXsvPR_}zuJS1zwvDoGn8B}13nq~eJ~rSmt+ls@d_!Qu!ecOK2uqcLq{lvJPM zRQCjb$sk0w!4gNJwy24KEEbO^aa?$e7p4Ac(~#d*nBu4{HGF7gbhoNG{e2!BHg<0 z+z#ow`2~5)bbu7WY|z2)Oprn~9epk2?lFCT=-!#<^JE@WRcA9&HN@#>sBSuXmQ%-!2aUc@wRp(OID~95^TVZ9Cj# zD;XFBN)D-JW;Lo4G=A2o*8%hxRu8fc`a5c;`JV(__xrM?zk!jr@ygHS#tSW~6~e#e z;b%M8ZlYvd?? zw^QHUuy)wwnczWQ?%9!J`SFFu+y{TodB~8yr>_&?zhGSeUw-fLr){T$aTxNa;kiY?X2b}0alW>qe{azG%vZqU zTD29!`NO-lw)eyDA8SMP%Myp0iLGU$i!7LC&(R8&@Gh$1Iouv$Z?E!S`47cIE)n;h zz??a73wh^s*@udbV;S3vaYXYMxP=BWX`veK%nJi4Q|yL@9|edHnj2`*{AhI#WaEL- zKf3&-tTE*4Xg8&<^bhSNnLid}I^~Y|?)_d-GQ~YWS<4mXNkr^ zd-T1=6i5Kh173LLv!hoHr0Uvn2J)+uaQXGeYi{Sh?tHtD;8=USe=;-3{H^OTH*th>s%tAs|~t% z<^Lh*Fu&=+j_0Y30ym^RRoew0EhGkY={!VV!s6FlG<-)e|M#LkXvoHB3IC_kG=K^c zn-0*j(3=x~j93B<`PnP^K#FxC&M3LFtSDJVRN4pb0R;H=WFY=AnK*1+#SkazwCOne zstJi^iLpN#KjBtC99`|Sqj=z+wG3pPrMSrZ0Q*ePQD?B<#rj7?j&c$2+ zwu=owlea`=_oE>XFt=t`b|JS|hg!Q*m^tDt*VrJOKL%-c8EF%Pn`~yj8NEly+d;%$ zzovcIfDHxqo;*ZbUhqvRF$m{=0mXnAWnB9zCFT)eyDm82SBv@91Fd&1SXqeD3e}>H zlAl^>dTXxenKZSXyr5@WztW?o{n~8h`0*j9*5l5Lw{Ou$g9`ON{I?GfNl743qtm$O zKjs+0(?Gnh6kec%?_SWYB--xT!Z@GHMgHJtZ^IRrd0{ZUtK>ZACEHn zatK8CFhYwphl87;h2^QLJ&akFlcwwLAdR9H$k3JRDyHE^eQi=<@V`c3er9ckDIoQ` zT1G;sT|~}eL74Y)YUH{Un_wxNb0EYdw@-NKO2Jsi2$G%))VthV+|7e zkJ60kvXleK5P7l0EA5=vcPqmp+WK>1a8sFZQ55UmpS6(zaDd#36>hF;(uz%FK=h(n zcvCvHlg%19;0yXtIT@?vr;hYv#a>#gqBgL^x!2m_(k+6TP81 z_E~WMJb);c>S^rU>SG{d0+Z{k%I=5L0^xUg#7FIrLU;QbqD?~K%fXRXj0B4)?W0B4 zo12iyV8)!Y5GiDNA{wKwB(2@JXxU9|P&X?iD%m%4FrYPeaInlzx((fX8=b0x){@6P zf8Z>ogLrYmCNogVk)4(7Oo|*7#(KF_pi9PO5+~x;GYc0hdR=wW(Zt; zP(UyzXsYWZ4+2t~xuyZzciA**t0{JXNf|^l3kcG)r2=@X^UuQL19@Ouu$9D2PKPf5 z@#W%qdXM@CQHyyElEqpRM&5g#h7H-i2_c$8wH3j$|9CZ_%?+PkoztbJsRY>dE-xMd zcDG+iuR}+2dTYGR0pFKH-$(Jk9|f@L^N>g{NZI;U+QPn z#6HzGORqQHb$&Oz6|D{!4de3wq{xWMaOh7jz%x(;!p+$Cl9hyvW}Tas3RI>9A7&;Y z;R{vsR|Q`~Lj%3hmZc>wN091*R@%V=+eFV!#+wy$roma`!c$IX{A~*>(gaG)-yNA+43kF5_3R%?hH@rJm6}-$0_

1)KUFOW0!4IN;qUMhEHmVV(oSr=e%sWkt zs6n2FQmo~xpjm%|nH>52Tijb{9)`VW;E$aq;dw`nP5V)&$H2_HuN*A%exolZ= zp6?pkrT9_^)EQl?o|j^?xr1ejyPez)Zp$%ITRNP(ggS^bPw6 zTmam>IeG8aJR>?oy!a>n($EfRhk<{Q2I|f05(Q+nYw$|ESGb}m%~{y-r)mNBI!7^6 zB1f*C=J~DM;r@iyoInD&FT*YX#hmUWDTq4{Ez8? z6=p9I+sYq9DzbV-1wz|1b8mBW!d3Wj3+>w%(C;2756{$kJy1bEG_V@dn-Emqi+rQe z`m&4(l}!ydq`c>5@+R5V6BG8G?k?0LLmj5XWp6xS8rV1Sl`3_i!6Y0 z2f-oSZwTLqRlta<#}2eEXQ8i+8)n*t4>}Uqhub)_*^C&Ve8_*YTIE!{_h&vzCV4$O zWy^5D>2HO+d&E}k?-oJ>F;H))p-hoFuW%oO^Zzx_ zHqBx40#(L7{8RDf<)MeRf7!(yy3hX9VvlgYY_jWqptOTZ!3&^t(T;RL|LE^zcXi$6 zRrU3)K<%Zg!ro?oWHE$V?$&#-QppA%${I}rzR86UYyQhKiKre+Q-1D10$ zG>}aruO6X02=^pLo5g5g`88u@N>8vmR)9UMd>O{HhoT!*g#R|z6Q6DXSBc*K=xTD^ z{UtoFTJQ!Ct;eZxg|NsT)_1O-c!zQHTHgzqEZRe^`wg#4pw(sqI+7Hc&k*F6U7t_e zw1W@g5<#)(&8>>BZ|>e30jKO+~x;Kv>#Ka~BUEfM?H>d}2jtr&|y8XI< z*#`^NE<)~f@QtashOC>?&aIr^zn;TT$T`!BbPBF_^o!*hxs;CEFxVOZaXHow$VJl< z)+<@h)@xN<+Ky&h<*C#G1e8eNS0dY}x&(ThMh+GYd|h#JA7!o)XXh%ToNk6X;QB7{ zdRu&0TRadqD)+3`)?-cR-1_+=q46#;WkEpvlFru!O~u(3)EK(9l*0eXQh1ENCmtY^U1n`J!I9H^A^@d5|(-)n}w9pd{)2j?hN!tzJeMlKF=Q@{c^^c^&c7Al5!WX7VLnpt1RF!g$N>Azni_k5(rL^ZQ{0%TN54Aal~Ypt>t-Xu@Isf`ggSeU!xIbSC$n?JL5kFTaC@3z18??qYT%tJ=I0r5C5FpSk* zb86_M&X}@;Pz9^J5%S*qgOuESy@?`W9#ayW|{!Ega<)Z{v%s{BJ8EZ*73`C_+3oO0Tp}KmdMse_g5Z)$IGuM<5;zmQ|Z&nXk z-kWl^P)pZ;A6m8{Fn7rkPLMeZLUQs0{`WRKE1RaC@Y?-(whkq6DoZ=iFS{r4e|{*k zA2B}$Pzn@nz`}d6H@(biulG56$uM&kwXwG>%Xwt?=6C*xS(l8NS*zCqkpqzB208}n z{df4!(*~DOvheG(3EeFqD%kA_Lc~01ud&o~%h?UHoRP;Pa}FUXe|&34{uE_`1zSD> zf^Y=kX}U(-z73 ze_#6@S$z+7htH#FY7lCIM=R*GkHDO|5hU8}5M-aklDc?HkdjeL&5pS~wNboR z8xl+6b75V=2OrvjSKqqC0@)+nM%%_m)?ve+PIE{AVBLL)Zh3ht;la%Z;TvyGcdV@p zFRbtGkiWuKir7ODjm^><-^%I$HYYx)bNTj7`_uyOWDaC(i$Vd+uBySwbtGVN>4+1l zfrh&iR3!Ks0WfyX6>tICu3-@lkVXKf{wiH;R&Uh7Gez>6-aoT&oXgfL#Ss|Pegju`FG*&(M!tB!Kz}(9y{8u6Xm9>ad4x`jA3s13 z#AbbjZuz~`&rUeSy4^K0C`37Mmd78aOwz)i{u>qb>>+auO^iOR4oI4Q(@l7r>L|M4BYt}=U^i@hy4<*PI! zzbS#Bj>)%VII!N{cH9FreSh zCDB#1-C%_c-~gElx0$+PdH`wFnk)i|jpg57?lR@Zd4m=TtvR=T22BEQW(w(|yGDR} z1mkw!sEn=c+6Wtnkdp9->V{i4(-Vz^m~uS-JwgL2U$UX)K3d?@!iFQC6U^CrlG`g9 zr@;OvtSIN9{FA{I+IiPsS|pM35lw{uDPI!Pmab`l}TjhhLTR)a*{La)RXNNuK(w~#qcy$IackViM_}PLifil6quHg zjbeRG32rTHc(a-s`x;##*doT0Z)>7S?!TdX+=SiA0L6csrT311Dw6{oxrv}QgY%#n z^T6LduPRPnAg6+9yesK3W8MJ##+b()S*j0iHLB`pm;c$hzJmbx?gm`z)c=Fw+v&0H zG&0y9Rr!M|x04W;1PF*7d-XEezyu088nUETiR1L42Y_=+48m!}zIhSoTVv@@O||yB zD-ob;=%e^Pp{g~jsC75oYXR+=UKINP5Ev34igQ1P`@+Py{Zv%ySlk?cJ%Jn~u7nFJ(-`(c0=zr9Y zxmI5J=ykiC2aUvfxatAdz+8ZP)nMkgOg&^$TJcbILDKwZS0p4lI^?}jG?$XWA(9zX^3(|2bU_Q62@N+a-*3>JWj z2xN5vhy0||njhSM?CIEsz9w?-{U0@?fYaNC7yzG0K$UiI8)%f#K?>X(%-00X90h}r z9utUx77g~`>j=wKxZAd(@WHd&DALfqJQ4jxWlKEUXLoDnK`Ft=zQmK@C5jJpBjP3{XVT4=al0#f^;ZcE3Vhhpq1#n8Pjx5#;l1D8rC&LZ- zqX6zK5cqiXw}A3=NhL%InJ>cAowz?heB{}jJ1YAlB@RlOzZOtQp#l+nJbv|6%7DrS zBGqZm?dHyT8xY7|Bhr^Gf)kaK?;@KH6eIio{uMJ(Bhy;I14etmhPes6-W6X3!?M{n(RRjqrU`;#! zdk$2omH+FC#!m$|H0iUD0D)b}?ej&JQF9CPci`=h2tI(lQk`O9cD$9C?hkQLSVMHM zCFlbi-do`}xmom5VV{QYfi~6luD{tg_F6pRGsJ*vRU9st56k_)nL$_!{O@*se=d@2 za>9SayLSBL%eU-+Cz+Am zwxB2V%J5BUC?JAM)kH<&IiVn(WRjH|uKSf+46q}xbu89N3U@z$XtM!NEVV=x8OC3= zoks78bpmLdq1B5MvE8Fh_2SOY3vsQV{Q_Y}p0>8apJA`JS|P&6iha_~G+qE#a@T0C zX1+vU?)!6G3mPii@eE)#d^J37ThTyy*QdDXIJ?kA?>s?&QAmYLJ!&=&n8GhFghQ=3jb!w6)AWYKL)`hgc$@~Q)#2MaQWk@Nv6fQEaj=;Mn7h@7fUc)>KN6l_ zT;(dv@?E{mYDPh25133HnYD%5T%%6Ewni-cztBa=4-xrM1Ie_vMKf=+8=@|yk-{2@ z9aZ~NSDH{u*M6$4Sfim&RL83Fzvng0z-#eEGWZb8x*9!yESXiEr=aLv3zkIft%>G; z*GQ4vL-$}^A$VqP6KKI^=QhzNmX{$+XL6ZBh(Tw-m!p=Ow?{fx;7YtA0t5Ve_oTkI zs&M@18%cvAH42x z*KP0FwhHwdER>mn>c>#JPJ*h|DH_Drx~WV=`f`1jW^%nkki=SZ?&Jby)W0UJa%nWU zAsc<`A|!Xh8fcqX)XZhngRq0N<#wMX^QXreL@Y@=9}mBrmLXuly1rusw6F~rOYrU# z6X&91{biv>47ct|n&3!sIS(P|4X%ATrSUWAz>xYvOYyi!`akhI3v#s8av+eqt}+1| zPsn4erIaH_-uP>T7(qV!Z$FCAt-w80+mZ5KbK7lq@`rFnz_9ypFC^dn6MeF0@Q$&F zF)K#x57mlbtUlf|f^|wqe1|2)ZwuxVjFTLmaTe;)@U8DrC)n`AHivOM*RnjtqZJ9K zA5;^vez7~D{H@uHCY=uDd*T|v=^1L5X2jZ7zsZlYf~O&n9$F;QC0lL0f5_EzCPlEuLxYICh-oF;zjr1s`QH2BrR5#yQW zmI?r?0eqiJI%g;*Y%s&!l?VE8(b{NJ8c8)dNJP0cvUp|C3A+x{jN&U z0`7Cr(7Fbg`r*3cEd&Q^Gu-|%P7ugOh+<)6>7?zp<-qNh+@fJ!$I2;hg`b-s3=joD z>2GpUmba3`59V@=#OdL`Jj~~Ud{KJ-RqEd;l@u?^k{~v#Z=c{GsZS{&=Mj~2=qK=X}vqr8?=_csv=f&cN z_FLHy)LVxxa@JP}s$5`A?ZjIJM+E3QseX)?{#|NlkJ=c|yw*4HW|`kC-L1SOWjf&< z>zOYS2?qJhkd4jm^CvWlUu=0%Pk2fKfY4|Hp#C@ZyLzM-1hqnysrx|J-c7#4t|Xd` z=bpltFD$l-bs?Dh7^EyX;jrPrK+x#A0{|c8#*9s1CDmrE><4&7L*=oXK=ikoiiW5| zkZ1R$56^b1=qJ?cyb8WZ~XHToK?>^kzUY@ z$!$4X?Eb%sIZuuFa%)(;x4&i}?>#*_ zb4kAk#oFj$`3aoupyR~ANQ!ggRc zmvzyy*z~92au5zar?otVR;Z!QAA2p>Yp9$k9rrK$A5s~qn8JIVF^Qk44TbZg%u85x zX$v!hzkC zpX|Wyv9lI-SFK6i&>~L4SuGy0{Zr3o$RK*88xli*#4<%tMCO{0HB(H+w@O|YDIq6x z;??ZZ(C|Ei`y#Za?jyHpG=Dhx@Z88o4KVM;(UDt+mF0k9G)1L6dB@t$0;7A@@B#X1 z+YN)x$o4asupydip5yC= z@3ax}x53uh@Yc6BsY_blGq`3jMmclM-y7dl9&jR#cQNo@@voDRa*>?9nVq&Ewr#GH zB^snXI2qPv9&Pq!0tnkuY=u6p)A=F}y=E{gsT8XpI!k9wBhg#mToIcc?eRqz)_gxv zX_BpQkNbI+O}CuwBjn7ZZAhuovn{7?B+*Q#WAB_T9`)-|!`GUYA8XKqCrXAaWzn8G zQ#;R%50w-f#U`V}<}-emQFa%)$kO*f`DjktzdLqAOq1l?TMN~LQYDQnLY_5rt*$74 z5jB6G%faokat)t?uK3bq=65_@m}pWDH)}|)IVos`TSMS@pRRa;qo@rDi{`Sg?eI9S zBa|7l1YLs@@Qbqu9+ETzP*!DfNuJ{x~4gV-^&U#Ky!J- z&F}R$XMZ>0A6Vg2=MajNs~-rd0PGo)gYHG45FJ!+zqcRIX5BCC?$kQt?<|`xi)HHE zWx1-%sJY&%PM)zNpY+o0QXa|teNUTqa>FEVFU3+PIu8q>)w&NCQ|AYV!h$V)17pnQ zlzS?ft|-rqkV5-vtl2%6qa)GkTMbc#JT1?ACP=ofGzO;Pin%P5GZ8s5@Ic#FyJ7Ai z_5@2baQj$&%S>{f_;|BqTReIraKA+H=0nVU5`5cb@a^OrLpo^l^xvC+hpxPm{ivSy zQvnjzbg9#MV;`yB2e0y}_>;GM6Foz!(==R)hK8}fyP z@*@s=GC6Ni3x#@y!a{{GAANs|5#d|mDL;5Qux~3p__z4TYu58>9AM8jEKl|NHO;6u z`1icOl3RAlLMh~f9sE9MY1;2<;k}3!wQ~^MxRzPO#~Qr&?mrUQg-emzcTsDolZH{q zfV0n_-$i}!y3*K22E@ELvejlZb4v z?x6oFsad7ms7Of*J3A03Q(s-nJwnC|X9uR>#oT$u!90n2jKz@vQ$(7An@l;FlabJ8 zzPfogN!MgJ)foVsnK$UHyOriB0r+IhIGD%eXJllM_16&lZazfb4J>kjTe1MS1~Q}@ zg=QQ6J<|WeeqYOH0UaF@qN!7MW5yEL_tjIgI7KP{-$PCpeHC4r&Ga7%gaCU=fBV4N zn5O7E9wj&4DDGO}3j%9kf8o=HsBRfXdG_|58-LaLiY{OPge%4Nu$nOjx&1%Z470w5 zM@8a&2i2=;dvU&(KbC7w$RSRZ$!&;0#-MoSP|n&w{9+IKVH`Xggj&N2&Ao}<4e12Y zq6w?fsJLqLg~@DO!)Im-88kyr(y1bM;eF=NPhHOV5Da%4a%(9d7>d_z+bt+=a(RRpajlW%&Q0zQEV@oRAyaw{4oMid*(%s!}$^J$<@2D{TE+4 z$5Y7lEr;M!h0oW54;>`@Ksulpysw~&d%#RhQ@(NFrQpDQ+Cs4^g}gOtJBL`0~raB2|oc0a-b5<<8Tb z3#gt#Sd8YFwpHM|hK7L{g4R0sf0<_iW`0*+^t}=3FuRqv93$5I$jElpdI?W**qWk| znLMvxoK`-d_RhpPGwR2a0Etb@)6?xUWe=`!vm;Iv(zJ}d7{jE7e39~4e5fl6FYFmi zb_z$&AM$(O?Vt-4f!5G}4cO>r@Rpc3>NVmvf~Q&F?pf6f1QP#smwaT0^Xa0#y|m9= zq9sdptKB;>KKHZE0QS5(q`ovPpmsg+p})jbF)@~=RoKqn@ZlUS+UE;}g~2b^Meo+~ zDf^&}?JhFLMr(b~8>P8))BS1wGqmlz5Br=^xafW)mX$_pyA<;(imR}bV0nJkCx%Ej`7M0W;43f>J5L)_jNnu@O1L`Xm}NJlM1r-aM%>>5TtqOfnV4# zk$!O0OP%r+cHt#45B=E|GH!tn^sj4%xd^Ms>dDkI>Pw9esk>U5`LP zT_|YTfM?GAo-s77KOXST$?QJiTz3N?d^iJQ>34A2pc1XtvMH#ZDL8o^3x4jGD~*O% z;FEg{H5Ml*{JA0Tjqx>K%eeJH5xs&)k1;-|Mts>7C+?5R-}IrKa8o`Vl?M$}taD~xOVRK*4J&8SA za!+7RN2}?5K0l&8dSxEc2{y7T!m7i~I>-l-6GK#k&sc5sphmc&wq|e1oJ#W}p0!no zERpyi<+c3~-P~)Lu{W@j?1$z;V$juwO(AqFk+$Bo0Cgj{2dO&6r`L{@;txpfsRgRm z`mW6=GTnAlw5Ds|pg@H9n&<3EOz=0aVL@@R)iVuI&ZdFe9RF6BpwRKL=$N}&fk8j9 zLbdWkSHMNrzk$m~wpm}QXLYL{lRk3m+in|2X_ZvKOIUFag!J%lnQFE`o1 z0`+jveKftZEqw9Vw_RP*1%gP7nxe=_k&pV4k=+2{wk1yxOB>f0`#9k#3sLcAezQmR zl`6pAIcz~I8n{Nw8_c2zUzRe#|2D!P++cTI>BFf={x-N(4rRx_o}yYv9sjLI@nV*i zaVXjf?-94UX|IU!Jz%whbj5Y)Wcs0&3YqTVJ zZ%Vn{CQY=hN}v|6!M;1dEbv??8g11Rynq?p{!1rEbKW{zIF9XV2t^Y+#(|67DnD`f zAVJ`XLe&7GDrQ4vi_AC2w9P2L?O4Re_)<;m2QQ|mVD==xw^k5nYEg%@;qAnCi%-#P zSbf;Ca|za#L)HC_1W8>TPiWg)bQjA~y+_|>vYQHzltChD8e*`9#zI;-^}G8>aTd1j z7HOEHd$-^`eb@&DIdZuHKpSp+OO)WZpjk?OZ+u()-J_e&_NIZrjR>`jNUuIE z%*-TzaAhkx)b*!o00LZ^!Dp?bTts)zpB*&ySq=8%=|{XbeZ}+48RjJ@HWRCEZ?XXx zrfEcHT;*}~VfZ*(!cS!E!DbtqM z7&X7z4!B6^-toRLYeci!PD7u)-^QQ^rhO2`kwLTzZ}3gYJrTVj^FRU_(bM3alQt39`gHPBB)gL{^t$flG)y9m<@bc zjq>k+N$rHT8`K7#H5-l>_XOrhMgX?}?I0DOYg(jF7JearI6{*RbEw0fYBYz1E8?`j zV3L)W!-8J;`DX$?TDNTY)+Z0ve288z^T-6(=7prRL*8a;=4R(yo|9pHU+g_I2=fc~@xBDg z!*)~L3n9<8VSkQ#+c2ZKn}}My6_N%@$tqCMhCt!Ylb^j-?pz>RTG(qQvlye6)7_>Z-(SxJh!wKhrG;y z%9Y`*%0cw?XCiLp39)Z$YaJT!?$Y9L3*Q=hu22#BN4ox-W-a94*|@M)KDM$fOjCY@ zb(d&4_ig>nzCA_z1o^kAUITnfK16YCUNs0FWk(?$#6MT6m z?czH9pd;uF(cNE5v)kB|Zvf_}NA+~gm8?@%8A~#a7$T5Zh*aZCX5OpBS9ELt7=PV| z@Bu$2Eh_j9{hDDzEWl6iREV;miS}TnDTEJh@>iomn(CIPGE=^-MaQ+#d@AZ}KzVOX zlX60LHuU(dRHlA><7=9;>Oj8}6tc;OcE+(+6kDikV=FFD_lf5(V=<3kZhz8aH3&^r z;?d=L2#iYFfORi~riT)OZQyz$?Rr|g*%gH!P9Sb*sQB5gdvS+@V(Y-$E5hYWASg`z z&N|5%vB7Ncb+th#L8YbbL7A9uL{|A&oah%66}CiF%1b$IAynl`CV-)HaEN0!%;^Dy z?=<8%Uhb2!V;j1CF3d77fp$AZrw+QixM>_)&y)NToh8)(x=Y3dF^+m`r&P7Ja1Do2 zBGvVp!xUM(lb%s0Gt7(g=eN60p;mZ9IwYSVoSN#BjzdxJ_&?(0j(U=kV(;KW6~16S z#y#DF_|wDbr$DTost(s6trn{2>X;s+=fHtB37=3p54rQWCS1_X-dL|`dVCeHpm?r8 z@H6!JJfx|j9cJcR)ihP@GOO{n+>=m2%DHBu^dIs*zcHI*ZpXG^%6Nn-T%IS!!r?MyUuBI#YnkhrT|iMbwi>Wxb2=FWPFY zHKLOIT!bg5K6_c9^uj*I`N;WWaQv0+R%*Q}7nV^cT|b}L1a1NlYsMS`h0zxZZi)k{ zV}De9!%7Y^%<1i)VH-E@G~n#~*A2!WBwqf~Ep~=q*Ht>5mCqR5v%$Fu4>4_UO#AqI zPW7h`ivPQ+GHdTtL-)FQqdpYJ?g({rsvG?jK-#H!G1{V&uN{DKD0(c(_tKFfh>v9seVq3vFL~URJy8@fj4#FQD-BQr$nWhsb9R`h`y<9^GDA<9Ab2ySJWn~9 z4Oh>;tO>@j`(%x#z(?zde+;#;WriUW3ykMy7L)zS55fww`u z-r1}NvC92WxNZgCwsx0lg2d&{W-#%B0WLC%YXm-5?lhYw6NGmf^jbuS7)k>MgZ(uN zBzR^@W}?5`V$4GvhbiB}O{CHufrg}$g}DE08D^^PQ$9=&zhWNSW18i-*vh!eN&btz362j zI=gj1A_7;a;oJoWat&kx_{j;;6F=Nje6T^X>H(TzV)pGsm}~Z{srV{((R1boDpq2& z!nmV%8GUDxB$Hw915yNz_HMtSOf7J3GeS2Y5{_Iw*NAHx$u2Jfqxz0B5H7P~x=09W z=+u#DEU2iDI6ECf{}qWHDJl2_O!|+WHT3>N_EbtwN{caf_)CFgVB0X|=0i0*5}Z0} z^qkVG8AyNeEmH}}1d1pS8@MO@aZD2%9aKRu^PAi$vXuhVps#vEDLPh^lk6z?#-Ld) zxP`4hF5(C9eD%Wj{knb)R(L2quKan*c-e%st~L(!{aBma_q81wa)o@mhnF`U@;-sz z^B+2Cx8?SJ;&QK9?`TYkfi++&?!ZBHJx^y2ry0p=cVSJB{tT_sXeJk!pl;`_G#DB% zMxia-zv}s~WV-96``>8X)mz(Cd5SpK_r-imF4@{7gmU9DAxdZ6Q#Mj-0}#Mj{|>ag zqOuZyDp6YqHK292jNzDJxdK1J{F#JkFh_4n5ilttDJ$&p`A?q=VGabtIqL6 zp3G3`EH3|2SOY%bI9vrGA10~K)|E(UMZC-g+bH*sXw!8 zNmk1XEEeZ8brDKOOcOPxf)|7B@N0HV#?<>=^O>C$B>9~ln8fzo@fo!xWIL12E>Z&2 z%2-N9oyyJ2g?A6(zHLzngwW$LQ4SfG8hd;(jP4Rei+zR5wQiD7i=?&Imx@NLFAt;{ zinZ!eVhur=<=EfVfu>$%`;~!+1>P-xb29pwEqdYv7N}uEGB%#YEvBehg_I8)q z>8jHHz{d~>?y;a;YwMoJAkJfMlCO1(+lRm7@OP@2JL6Co^bp1WqRM1zL#_3FRQx(` z>U{Ioo0;8*NfY(t4+70&u9wOsSsxZ!ha<1v^n39|0D)Wzv3X@HXaks zmyD7|uCkK%as0NdF{+<1Q}Z^n+|3UbdXy!W!bH)J*Z!cvVoYB+kQUHEoGsK1e?dDr)>Jco@~Y?B}{_4hlrQfiE>^XQ5J01tAe5Ym3HT3xn-?HHJe9eHt)Hqg%$98Ufa`D+oj61_i ztd+5F69jI*YFMCJG2H0PYV5zfZPx~$g@2T9{zY51l;!%R5eQg zFNoOfGC$6ZIki-o`+IP{*+CU;YllMoS(!?1o;a$%y!m?^0BRz|a~7C>SDZlIHFbJ^ ztLDO?3b(yvsBH$s<|nY?;Q;2QvX1Q?^_szk**o+5_FtkO-VIN=R0r;azEK)TbEV)M{DlmdFoJ@B2>+)dL1t8k6On z{Y|*frP>&WqJ33gLu`T?_ic3$<~rYRtkY}cFNNZes%@nZp8zk2hP`FGg{V$mSd>B7 z7)QTAZ)&D9QN7>hZrm<3Rzm5gnh^iob!67%wZ2f<3w&>0k##3yy;3c=sKO3YsB^1O zEpDZQaXIz!c=z}FJLUh|PTYh`7gX3?#3pSYvc69;B;N!YN2A}85hyM=T`w`Tks%a$ zCbBbEP()x80eQG36p#kR;TWCYJVabNax_Hew#XWM|EFE{9N%xr}K@4sf> zJ8eUw^g?%RvNLSP{^uUOjzr{deR)zxcfXs%Jp6hi6jnKZ#k%*#;Lo=s6a&CmtpR;8 z<-hW`!Us7;><0o0;Q)0D$`guKU5K|YOcR{?X;f%l)M=s9VMd4O{neO1xBGSmR2yIr z!TD5>6W9;6RbiT?iwyt~+_%wRD$DnrHQqI~v?aaKWVR@mG!L>PXjCC=E=i4&@}p3T`@)USe%!9%_}NpszRP&2IUh=a=xIG3UEZjUSn4|itOPaHwX>;YL-HKfxga=xbiZB zWVMvXDeld-@-CmP6BSNX6<%uyFYm68=a&uW?ziurNO;5-9y9%QGgMX9bW*@xB5f;n zZX?Xt$!m`f3YyUWr|8k|e1nCf}lM=CYX; zp;QV{Q7RQRQsxr6e2bFS)ksBCOrZgP&JtpqEa_g^XVCJxA9npvFwvBRmPN^RT zaeY~=1RcumNR{eBQ!YIx&nMIt3ZIV3bMa_3e(-@3`p7RC{=BH<_ABn1L;bq2+wSxg z%7#0}-uT<&%!|g))Zga-vnet~ohGaF^O#ZzQUmgMK+;0cIxk?5qdDr$+9{F=om&QG_mc1uO{!(wTu1D zq1YO1c~*h#Z1~Hvt$&6v812k6EXOaUEL_@dmAyCkLGq>Wf>kKc-0;`R?UnGk;OM;% zA>-y^$6uSMbSzQyu8#YIk)`f<%1fb32BywBM8Tc5@>42^`W=gI93Xu(x6TfnV^uDj@jxIeL! zKM8Zc}3DVROb4KF@-{I>tuvstVv$&IZ4W?pQ-^o*3O_1e2W4I*=^13_a zp&7;q=UKV0z#2Jdd;b?u)f+dvU|4lTk*{L$!`|xb8&|;3MF&$K0UY!*ALu^6>$%S3 zZd!3w4&EmPf^$21DJOcgGFlqx=5)mTVp}vwJ@Hn`MPW2H`uNMPp=e3|S@9-Ne&vE>o zSJ`a-LaM%TIz03n-Egz^Z}cMn z@jNOX*a;IhcYakac`i0<*~SasNRc1SHN$z1!a$!?X|&Vn;)5|rXeNH(@YXW@oS~x zOeeI4WnB{3!t54fS_gK*-{lmide`ZjH{$@Qri0M37J;sXl{YIhl_JCTpRqA0eBgb_ zcm!54C(!=pbbrOXXIp~?y?xPA7x0166?dsGEuw|A_CLZeVz)+3zETdN7CB|BB_p0{daZrqU3q18%#dC@v<7$iP8)*^HaNxV1q z%yFD4zW2VavI+z=jn!2qVmc|YCzI}tOP`A!iRtNC+joNI9LdDFAiv90a>`mwr_iWt zb&i?RNn4wOgv_QJGeLe;Rkt1Iva~OcuL;`MrgWk7KSxmP11SjhpCcs-sxa_;#D#oO zHh$6|3PqaPZuc7mwR?mYNR#lfkqtUhKs|{(bkD$uLpErrAiKnilbVfY9JE%vU>FRn zZ)L;h(_jlV_vX&?b;i##k!RdB6uh^Yqs|?`(x&@(08n~wbKhuL0W4i}TdRUib}r$) z8>-Oq*G=VhAdLdP2f(VuSGYyDIoA>E)iYJNcz))BJb#}A7R7kQF6vX^>E7IpY3;2K7kHF-VmN- z&V~M0v${;Mu*wDQEW=l5qWoLWL4@5N<7Bv*4PavZTn_4~-`rVg#84WNdZ5!dOuQh$p( z^F^-XmjSAy`Mpr^kI~`z5qpYC)l2&*wgyb2Alg^a0) zDa4RljB!cvzxw`=1(W_?h__w?*FghypqQSBL#iq+Lm)dahSZ{2h-(}B<|O+Uac~^C zuw1^lmcQBTR5iEwU%sZ+K$)_B^3^4@;m=;-qIN=~8IWi8lb+mLl^g^rN_ZH#`=edp z&1n%=A8+O=d!g`d>c&drfA zNO0kZE`l*ySF4lzcnzI#4t0?P6&_v0Nn<*PmloeA)#*h5d3AeAag&VHO1j5Q2$zaquo^S-8=y9 z$6OycIjjd_aWN_s@g#`lK^+z=SVtc0s^vy&i4~iw9=vftWfB2&%@{8N%z3)l*UQ)% zVdK`S#w(4~i&7G<$arTy~262C|Gv=KcI@R37y2Yxc0p!MJ zWc^s-@Kw>PBf99ix#OL@5-8JrH*W_ByPh=dJ$N&xaKR)7T>oU`fVZgFW!cQLhT~HZ zS@5C!2(wCr-~+#Gv^5+~`#rQi_^56}m}0(Z#rl0AGhL?%r1y8%(EY+lndT{PP>C7K zL*9DGoI`d`YW#ENiEqEqcXe3tIf`Zfi$tp|+oO;u0>i_dtCzUJF>)jX88HH5D*+NH z+sOEW!R7`x8aAr;6!f3G4}GLu`f7c{ zi2awpPkrkbOkI;2)<0_XU~RfnF>n8{=^1OOJ(!Merv4GEemVD`w)RX>6S(oA7ts=m z=DX*ip|}Yn6#E5Wu99$tq`d5KNB7jH%Eifti|_&j-(nr(uDUMD9?P>+a3- zWfC5=*1&yP-ymM03)W>*7k8ydArZ4% z+x^l|R(TEJ*_zaLQJ7;k)^^O`^24e-WX7ih+O1wSaPcjSuCg+Pv$yhK71DqJk@G?R z1%t!XV40Qh+&$zeMn7+6cS^O=>QtbUz+-3<%07z> ztZ25{1t6x0Upp@l6W1ua<`%OChK&+RRrq}A2;b1~mjT_#O#QXWAvZP0gOqXS9!|e9 zA|ftimww4+##LV1y`fp%NmscnHAJ?5AF^2?&R4iV9GtpDFbU9(`VG~}XWa3)Fm;Y4 z(I{zTOLVbMPbdG@dto*YdRh^zT58Kg>AhG>&ncv;CqhtE{Z- zn}nd$iAg7}@GbTtu?~=p-7n7GUYHEPKqI0P_3%S?GJaq)^l6G%=GH2|jO(e`ChtyV z;ke%xKR>bb83^OIHi%>jb@9LpCHrS7`d^f=Rr*FoM%Q0FTN`4>0+*TSGCk>^m_xU{ zpD}F>r(nrbc!H+pab-Olmw?KL8SBtfoAhIpw`TFzu4dms-jNx_*SGg#^P(4~d!XPX zgL0i$hCN^$1Sr?pJBBbpg4QMj1&r!iEyv;2)~b%W26nCPRfI=_x5f^{MH=H!R+v>d z3kiZe*9S@y$4bezV{4P0J!b7VQ5A>(|C*Zm|JO9IaFe;xM1{4D$jfHV%hF18*JjRI zvwxk3dyTB_rGzPbQK5F9XMX6fe?nZ!x}zrzz&QInk1l+SWJ`~sa%|1(q8o0KpdKSr z?;azk*wb_Odm`8ML>l(QX!pce_kAO&^q49b%N1HZDQ~I@196Rrfi81o(@QK$@I>?N`>0gzxFV`&0rS_%jKp!3Nv~7$1&!^#XTcutv_}+(_mzrOV6GF(_C<`h&2oPf905?d zYoOF}xlP#hJOi$XY@^%;PWGe}Rv)tnNbsnf&TZ49-7q(@^`m4a4JsXl>lp>9yR zW}D#!1E~tN8I-%lrPeWDE6p3Rjg25E56G|C2NRMTqX|*qok7XHimTd2QYAa(EO2CC zoiIWPp`V?j=%kXYUpb+;>)Mnu$YX1otkXknO|v>Zr1>(i!7Z0uW(>jwZ5Q5y6zfGa zXh&peXMqMfj&z%NbE9~#CwYn&Co)rS?1P|3VJQz_G@Q$xSch;z{=$8Ar z%JS0j2>xyfjQtbXyU0kz#A|s_pZ+qZBq2WEJNup=>V<^rH=hlMzAi60y2W=YC%b&FzNuE>} zjSwBB`6s<`x0AAb9^PRj8sW2I;t*tIHz#cuV5h1laVFdn$Z@6$M^Rh12780HSl~mc zK)s)0Yq8S%@h44~9PnAv5+lZFW3VeBq1!;cO0J`AH{JYJk|wWF!N0Q=)Vb7irbyL=rVS2zprx5&J z%8c1uP_TkrjewYw1O4-OLR>B$%oKa1oqr>e=jvpET~me2@X2B zKa%jQ-QTkb1I=~8GJU#(^|y#n1n$oeTt!Cv@g)X`#po5k_HZEOu4!-^ z0mt-cijZ}wVST zuQyAUEX#q)$`ym5(;tiW$02RR%b}~p>)(wh7(G~!cI@=@<6AQupMKVhj`25h`{iD) zK0f6t0~w9@OZ_)fHV&jOZ8GEe-}4*bnk8OaUX4}d76py1WZ4{qYjfqX^405mX9 zIBup3+9;sDco9{nym<_4pP^W^{hj{?zQ0TLQq81_rU<^CT-!7@{Mp}uOdb$dIxI4E zeI5?B`A4O-^#C*?!NXIf^^|{NZOH4_N~Xasb>d8k!_ZF0x341Jw!zk$xuXnbvQ!C5 zte8_f37d(t0%6{TbTL^M5e~Dw`8~l1*78QQ5Axi?@1J8{@li*?ki+0s{Zm$h+9|im z0^(l8)-3R@;5#q2Q%O4g_~(E^BhrUka2N!a*p><-oh2kC8K%jfHxw?qbeN?sg`8tkmCFcMle%n-KX=!1oZIcfT&Tu})gxQ04 zjJz0&lc$5v)Kw-|a=X{juevoc#z#wA|Ejg&G7I;Pb&T`*QU*smt3`BvZhiB(MB71? za1){F*j}5jZP!1Ap&|q8WKDLbG5^kyb-)CoLBMY{EWfnF1IOLAYkLj9&T;**uS)Zd zJp%kcg0|y5_egE>JlmaLcR_@=6tpfw3W36Kkealgh z0GIKyO&13CJ8w6KEh= zWjScGJfa|>hO@;8m{x1~1}rx2qpz_f!i@zq?B$v0=FXeuJ!to4;^q7;tD}M$%374e ztg(6A@#S7$_mF7^u5UYXgJD@P7uNJy-EMYbp5i*)MuEXSB)3!l$U|jS=$jZWHiL)B z7&e@71L?2_0EuKYfB>#e)ww_{8t0X|!>h50hHB$2wIYh|0^}mD@JJ z$|BaQ%FWAd>LuM*hSko~x;`8L+O`q(BfM{dJRS@nhq=Ft8rC7-x2se&fSu~sk1yl= zzsv-F`6se9wgLRb@o8j0)_wK(A6X^7@Q%)COhYiSYUyAJiNF~obA}9NZ;`ERF(*nx zsAlkJxZl5-c1x{e5^FIu3#h;0;oEle?b%0Qu{Wt_pI^b75cp{g%H?{2>UpoTZ;Ug% z1HSp`C?TO-2koskTLRzZZ2~$C(_oc!RXYoVY%?>&f2d-Y3cv2?hECj{NYe$U;&P=n zo)pq_GCGr6(A&fZj%ibSul+ev-#o;0)RMQ74)0(={8O9Vhg8SLJ`;%tNW|TtJKPH{ znG+0y5^__M?6omq^?`e##LI}o&089b5WK^o^#h^3CODi+G92ROi(8M#02}^h!{(LjS^->8BAGH~cAS z4-9=V3&#Ep?0whhirVJP!LkR?W}%vSrOnl>-IyEUaZ(bkV8IU=6kX_*SQrt{pSH^KA{xte->Wz9 zZ$)#xW`aS!qILVxbzTleRb+8zG^pbH-o#(t(|l@3L>AEgx~=8G{xuf)^H(P#67^%n z!SsmT_&fw__rZOCzsbS%J1QT)q;GO1pNQu^Lc|gqG^8^-=s!EcUdecO=|wJ~SQz^gmMBFd>Y7Xgn`$&qDn7?Wz^zAgE=` z^LQpD;7O=gt){fEFg{GrF4Y!xs|vWryX;5zg4{%ad~+|vaSX$y-!gg0v|xc`-DdFu#&a4yr`Z$dCh5>`{45Vawlqhjqr7tiFm!sR;YK#`R{iNiQ(EK-<7+andrBKdvaJBDx>n;T`CRzY>GaY>nB%^ zR>z@{uWf#etA(REM^dPK$eq$x+H#m~z#Hz(6vuN3zvMP+7M9}$DXEg8yNd99POm)K zv70x3*GkIJyCHaj z`lqoSZK#+$#d(m;Bv%(9m+WX2q~w+V_8>G3H*MA`993ixS(FN9EawGjRR=xt7%gs_ zH#+16=N$O)!(46Bu!vMhbVzm?N2V$MJBNAQMp4kt`mt|vi^JQA&(>``3fez{#~<3w zT?rQ#gZawp=bFxhfAY*e6Eo441uh5`kC=GMBo?7k(4N|gTqXIwL|({@j_?c<-g?NG zGGg(t6eQ)}hOWBYI*Ru*YBY4@e(mQ)CN7((mq}AlmtPglFvp$%Yc6rC5U*`Ly_v5D z{Wlw-7VqjD!M5+I0irnz=W~h&`qkwBJx*C*QDnRtK%rhlM4(4M0%^2}%@@HSuV6X( zAVPvCan_7?KA$#J!B78UDrK0Tc@6+c#w)*s1&Xsz=-QfSQ`T2{$dIS1>k!&KLhBaf zIw;hD&8q0&WF>9j^quBs3N$;eawI-Z*S7pLDB#m5tBn87#ZqnXPer+ag`7M)^Vvs?EsSZtV?kmu4>=kuUL?w!~vIL_E%z2 z5#n)It@bhEG5VuGg6|B#q*xwq2N|e<+^xVRh76BOAQ<@s1~Z35trM6#Em!PDE^?*j zbgV*H3Y0BSDJrH~i=CsSls#!t(_f)yqX%)P10sRKP;m<39Q6IFfmCD#_E$@Zh6o;X z7LLHd#eVH9zUO;CM1k-W$&sXA&KB!u`zxuJtCG=I+_PnAE`F$iZL(HB)H7Yye2LD~ zvZ;EcZosHofl#68$HUHx3gB@L^bokodbl%SaJ33}21HfVl2WfH9ym>k!9YyIo(l&E zPcYdPT-cQ`(y!>baZAj1*fpyl|4rPtalF6lKsdiJ^bI_@;t1v590&i_=W|*F;|ugO zv>|};T4MCD)xTnoR zxO>INNTm-UjPyT{siFWbh=FdsZJy-mB10i6HdLn z^jX7N?Qi6(ES5OKu~Z+AS;{E%X!GeDXw>VNNE)QxFT8P-#kih!`-K#Me_@ z>?0Po?onO$br;`v<)n`Vi{?97Q$;x!*S7Ov>5Dy1)}XO9^%|_Al$BgiXhW$A;KRk` z(=T6zL*O}J@HeC_V&D^$HORD#VdWfn%GnG7z#L7pNwT#2PN1(i*mn+4(En4~wEB;@@L*=xGc?&nx9kJs?XlN++ z+g9xBJCOn0U$}w?2LXTS$*(n|w?LINyNL0*VDs^u_MT&?%r z)(aeTciMkUF_m(w07g5Y62RL+o8kU4bqHv-+=zStMDYRkOG*jBcbeiWjo&+eIO+dGIH|%Zmz2@Gu#xCF-f>~pOn+Ec zzUIMyqH+-5tGRKBQSymY&@V&Bx9P(hPsWp#1qaTOE4YpE1~do-9}~qcF>qQbLO^zl z$eJtpzZ|fFA9!e&I>aPBh?jDF$59IRQR;MeL_Pb%+og%0JUe8|6a2q16)J@x0G3jf z6dE27<=gz^gpPwP8Dp^JVMrinjIkFGwRJsag#i+6DiL=A@k1|cFUp1z|G^~y$5I;8 zGsCp)8!s`TQe?nJAnL86O0gGbqK{dAg!zt6Zvzxp(!cv<_pyH2qBG9 zo_hEb3oGO@CEGD5=+?rAbVd1!7B{qReLUlFUI%Fr9t?v1D}UXqv(L zs+%!S$?yD|rKEu7cq)+8*AN zZfvG1C#33_O&88DUAaKgfyO2CC`4QWEqif(NMF_<;ufK21s-Yz`tUKoL|CytXR7ku z^!5WTqC5?C&P!fc;m=#XEN_7l?leGy26<+Btc!biBE@wqS#sONld;SLINd)o0pp3o zO4*bc;=nCQ>>ra3Zd%Y@t-M;_e*}nz^=b#>Rz4dq)A{!jkaOFNoc5n~yU(w9J1^cq^AZL-dygcBt1afU7t!UqK zZb5-k9>P04%iHhkjO9WBXF%ZQlvxY^?J;tmS{M!KEQ=@CWIT^AZrEl>n}3dt%f{2a zXQug~qnJ3CUB`F3*@aqo7AkEmY&8BGLv|=@`=#%pOxQCk1`XaTTle$8`SggfMK3L611s!VA2m4p1G-9 z$IvI4^2MJ}QV{Y2K;~1PCPM7}kn?lMJiiO%(7b}lvWs_MKfr%t<^f*tcbY7NplANN z8FEH&Lk}C*$UJatFI4%6p5Z^v(l$RM{lBnJ=X<3{**G^cB+A=R-|0H|jzRUo5?QeM zac`rV1`2v{bKHN0!cV*yH-2v$>$n>4hNdA{ekP&j$$ z*D8@0pF&;H>c>+X!n+2Ifv+~&nUrgw+^2D-2gxNkegS}1vBOxsnt<_YD|SK^_r0dS zRoZxPJA;Rb{gA1o7i?Btt#}6vhw#<}0}$I%*dqd1A9V(zkz5v}nb@@P7v}qqS-m9J z@q;vy8HmxeT`9;ToX+G;eT@M~*~+Ir@bd4Q_f@o|rGW9En*Eq!(u?e;hcyh;<@D7SA1m&~R{~PwHbli{ zaGi92zZ>tU()uSx>FX$d>Rwh7r9JDS27x}cxXeRQ+WkRE>zu!#g_>n9WRA9<4J`XbH?Vymg@l1qAT8X3_VYN2rPW#melxDi}~1)HP?@HIhv2J zdZEux{Re$X7@E$C#2nA1EvkMzPR*PLZ)GVK-^A@SlEwd4jIR!=o0CslU%xi=J~f5N z`W@0l2YEOaZ{q(q>UW>$h|`#zx)r3krjs71wR4K*$}|@CnrrrmxTi)?#>wA~NQXyKWT`P#lExUP&wwUtWbS~*C1gn~365F1#h$8tX?AQS8_~1f&9ju6T}MDH zZ0$>}G$8ojg{FHr{fu)I_^xjIopMIIJgAU{u?C~F3GTR@Wz`Y%Ui(MTq09TLuoMHV zbmTSEq}1`)i1Uq9=oxeE;X6JvXkAnu9hciOq7 zepi5*Lc$+kkh4a+zSk(l zqyS{rsyUK2t)EY=rY73`N0|INGkOjxaj7b`ku_B9+x*+=oA>b)WdmMxg5Jm`%t!hl zy0JA@he5ZowLVA!UFSraV%US(5jH~vNcF=pFQpkcYcMcWYY=!R+^eK%g8f*9TTX@y ze>DJrOl4EE^3DKm|8)H=>DBftuL*wzDPS6+`9vr$@|_}POaPb#Tq^|&R6r-~2L`b@ z0#Pqj=R$TKrX4XLkDnpYr`m(w8Cb*uTGzCia$2;`IB08`p19aM$@3N+4n1^{_jf!r zz;b=SdmD2wkIhbBrQD%!hZvi2NB=!&{g6L=t7w>~h8RNWWY(^N1EdC+9_@KNK1?0& zGQ2ZB3~c*3X#iwJ4ZJ$${09ZWq3fkRK(uDyxyNI#iV^&gVe{*4!)2);a3jk8xK@AP zie4I#IRxnZsTho?*!mqz;k=~2%P||&v}^WI`EYLR&|q|n^@7a$$Rjg>0@lJ4d|bS1 z*1V=v=f=j0G4}$_ARni=C9P0`a0dTtHj9|N2n8$Q=C5>pWfgG=UM+=cBf`K9rQYp7m8)h0RJRpOqwx*<*Z!1ITm|qUB>%&xZlro4jXF!eP zpGhE(evUh5@L`!E!xCmTZGx+C!E{))plX=TN_w|{72x@MRe?dlPB8V>$XY~EU^XJs zaiV#M(f8Ia#$h%((<^(28lrE+p{+*${$&;2(mI)k*X-4lE6{ULJePXW*(C2IhDx(9 zzPWvi8l`0-uH07$&6oaZDdb^7g}R|=)Ww?N(CfQsL)u@p{wC=!HS-e=pwcq_s!-vjnL1;q!d@*mt`a=s=DPqE^Ln6Zz2$I+>R-vGX%9mLeux z+W8I?hP#7491%xb$`Nt5n-di6VHSh8$Vi(Jw|_>|t!lY!4;K`7fL{_9u2gF9Mn6#u z4tS*;ym!Ql=!RJfS2zN)Gf;dzwG+;a4Fa_Y3$A`YKa8el)~?+SiM+WJ-0o4Fgt%tn zWLUDxvJIF>eTKVGY>de<`x-i*0geY!>gNh|$ImGXAO0P4yTQO`t6{7lcUvkwEH4cg{kN6r?LS8Z^3~1f9V25S3WyUX1OQ$(p&MaAmpmiGMoRT3W!YSru)Bep$3ZPl*Fl(J% z`TMxCwSpPp`o?l_z+>=9%CqgoA=%lSFOLP@*;lrQ*LK?gyn#DhF}L4dj$` zBU>eBlvEy+zO6V870?J9-bD8WOpLf9#f|6o&g6zXw&aJ3ls1vK@3bMfG}9*Q)RVob z;@sE@<%McJt}ij(479^XqFYEhy|EZ#{9?z=eF$e0b`anfXn%Z%T7){PciOsX#w9Q7 zp1O2EOi=X9LbZzYj()>;7WF=~VsxJ$R{TTRxAwPY<*wpcV(AKAoqb6`sut$!!4-Xm zbA`?bqth9rR4qu-D^py7`G%l!Uqn$-f{=;*)pIbiF$430cfk69M^Kg5i*kmNkHb;c z2lpjyhCOI?;0qy)`=1o=9n3|uM}54pmB2N&DoEGo$EzmBXWZaW5XwYbO|A}ZiR#xd zZ(4+}Su@YlpMyY*p!s-ylT|iEg)NQe%G_7{3(Ulk3qt?_ z>4H=}85`s2Qmyg>t-SKgV(Q_Ld0>TaRxZ4<^7l*W*=vSwZeAgDE7PJx-`8O| zRH`{egjy&#T*mjQD-puz8+Qzy11(7Z_;>iJWq!V;#oN>zQ|r$?ay6|=H}*WaDcQqv zEr+2L{5AJNBw^OsO=Exad%wSW9fFh&p!VFM^mClZ%%mF~$T)rWnIl+wWE>r-pFuJ1 zK<8r>xslEC7I0y-68iux*Qa>ld>&0c(GSM+?#TT}5{6 z-{UI>^1L!N>Q11<+IcjLnC>v+4>($5_l~8yOy2Qhuj4Yr2I zSV2{xV(x|$l(;UU9kVc5>&35P23kcCG+MHbm8L3h{67=s8I;O|Gz#B2Ece5W%zlu4 z!tg5|SGKGV!hIck${s}MkJ=>?usw6^tUa(e_U@wqUWnkr-*{Dkw#ix0HKI|K()uI5 zrzrM{xb(|5XYyX^Pq~0s)=h|mOJL-Xq!iZ9i?>4%+wSO8dtGl`*9N+2c?3Ej$6VGr znSo_Iz5TgD%zk`}9Ic#&wH_|BR%hx|^e+<4J~KhDRdSRtZ#*;AxJzqW=bgZif!{<- zIST;()FXmfTy!`xhHSXmQ6Cv`*W$ar3mmV&eE?-V3c;WZ@XoVa0T{W{VB}i6XH2nY zKO)$;{i*X^WeN3_CMhhh1r(rA(%FWQu{)rSn*nkhJYYMrd%6rlS+C!ChpnXngzwy8 zhUIE}^pZV)`=#3T1-*Cb!Z_nIS4v1fn>EBR0!-^4I671r(8b$Hw=^7NybDvtJ3Vqk zzN+VNhhBk23gr&qSVZ~z!gK2L_-X%~gB;D>$E{)|7$#q;ieJQrIC)dif)S_XmX4Txxz+G2(p|X3-uG)8tW3uufHT{S8 zh8Smj<-c{`%0|~^{KFM>NA}QeAP`dnhFacNn3xc>r@ZTexezM%BH0whshW@XHyVsR zs2_E&n0mRtQDG!RrZZ)psQ!HrePwER=I_Qdj(y#nf>i`Sf}-oLz5pPWV`C z$WSfcf7JGsWx#@MQ`}mXOVkX085^ML)F==l{&d%kvKxDD zIOz0R`wCoj@;#8Rk?@s=66b@y7f(z{>`vHZMMD-Z?_XqdfM90ygIOM`Q&N(jNLNR| z&4?8@FV@VvG3iTUmpFB(b}QUZ2z46dea|@YV;-Ru8af*~ES~^{*L~EkKtQl&mbM!52;nlUk##m^0}!6Wh85BldN&8pmDme_GujzE{B`c{&Uh{&fUT zSz&J0lkn#NN=3DagtCyHa24U|Y)@=?H;C$Iq=2E2puti^BVypHLakrmZ1L*5ipd$> z9@9;CZg)nFmjjQk1Y<$f;|3pIA}BT6_TPeb$ljD;W7yj)-`C z%RX_u#KsJ8YnR7=R2K6lv%bz2q=PA4{ypylT=-!>*k>K29SajB*9i#V`k`CpVq>!mEI6xCU%!;%&U*x!Ve^MY1|bwBpJB`HIR@Q%Ax>qa{g4t9tbl zV)`MHOmd^6-8W0tfB@-7LHlaaU2lICs`op% zL05{eA~i66S|sQ@?J4@c{T`WCV2S(q!kThF%%6CN>mCvUe(vc2q*|GpLkq5`Y}m-j zi-?W(4f1c=^LC;2RRM)9Z1DwfM<_FZIs%aF;YqMx(Ae=Rsz?N&e?a^O=C>j92>$*s5{OQ@2(>WU$&Fv6Lj9C8F6p0fp4}$$q{*rn+pOGZ0m}4m{#6>-qSTo zvUMB&NmZhonzh8wRsNElGG?x}7UUxn>m(SD=26gvu7~a(IB`r{Vq1YfG5V)T@C2}z ztcl=hCpHV%NkX8Trw~ga3Bc`CEkveAK)>Md-el-C?rovckI>;J2iB^i9W%C8$&=gl zwqbWMXoJEwbt{Fuov-_|RCcN>r6^jd1vQD`f8u9 z;b`b^v^T-|?8MVve+c5*%?PhGC%AkaS7C+SJkP%q$h=DPcHHiyg*ciMl${fcsJ!MI zw?9c1yvN387cne!HMjYE+tV68pBCF1)fTa&o0j>^+eCGB_6*uy@bE zEz;|qx{^#K-ah;#j4I_VkA@$p*&n(K^DEFQ)vfBS{As63zEUb$?W`h6GhsQ-mQN4l zQBWy8JVs$3#2}eFRUTKRPyfg33lFYda~N4zfc>OQ^Bp}yOgGz}(-+dFQ~ymZI=I{! zZ0=5Eg1v2i-pltHf+7#nrj1~PRPd7+NoZ>O@j1$&dog}7Ah@SlkQO{gZ-;mw7loCh(muz8Br{bg%6RtAAf4 zda!WYT{Vl=XX+n&fSzY9>Lg?EgrG39eaa;yR72v<1PF8Et15$QXy2kLp64ct%Diq( z0MdJ^I2PoB1P^#-@x7Dqok$G&=IUraV|u3_Ur*RqkXK@>(kBbV61^SquV-GY|)!dD1Z6p9!Q z>@MF{Wm!NUwjG}ggeEHiqk@`Mx==+})OcTXrpUao+kt5dz1L_HSIUPHp9^&wc3SA3QAxK#%|a zA4lgN&*c06@q0&`&1{Zy%H}vZ=d^N~&0)@S76~04OGWt<*%&snQc)^}P%4U0O9vZb zl?qAdU`nN?TBWS0ef@s_T-P7h5}cKCcyRi1VS;bLTF zTd^jK;hE_9Vh7By>h@ol4!-`;h5mB zzgEdE^9~=|ZqiYCTffRB))3UfN0N(+>M?;v zQu+EkNpjGCwn{C3_ua^4@v0_y&{Olc@4!j0=2F|=Sg5CdC#~hLCc-&Km%v4RNYb@~ z{&b47v^@O(cf0fur-C`rgC$73PskQJqLzQIJjnmjQ?@%Y9mc>O$X-}6Bg-NYD(l^V z^%&?2@B(TZJ;3o{*%+m7xRl@9KJvPFiCCHGW?3$sih|az665>;p5eb3lVoG{-1vt| z!)jG*;AA2J+4{jTHt!4Z*SzO-Y&KGg$w3PsMHKL_qyk&gbW?rQNUcp)1o;`EFC6i2 zgEC$$mXi^+%_csGmC~TtyU|FYSU2wxfK|HXCsi_)CozT4^(#omM&H^=D9y*B)pSlJ zP=bOvk`mYBr&rBiT1EO`Z=Vv6D2D{x1QO+D82GrYGPrGr6uOV`DBJk)SB#HiSc=Gu z!dKPV*F){GYyLJPjo1r2Zje~o!Zex+pdH2Y4(E%6d-h|S=@OpLG!$B2*mE6v zTkG(>ML`IN6&5hz8?~%jb#AYQ7gy^oeRUICM>iJ`hnbYYvg$v)y#n+l#8^+kp(XxJCvEg1Z#_snj_YILcKQX`3eq?x~j1AhH70Mdbur+ zp_6@!K2#rs7(kVqn?OELK6mkX_q`xA(8_SCL7*9wQMK6_QTSgSnY)QUdeHKo*nrtPGii`nz^m zb3IDFAE!BY`f8nIo1KmZ`2_gwg*D~aN5gjQn(8tR@A*1|KAbV5;42$pO$-CDtU z>W{y4{iiiWL2RzTF5blV=y#WSkF?IIgXTg4!;tn0*1S%rT$95+Ls9(m?kn?#6woca zD5->osyCVScSy4Q6(ub;qsrp$0lU-XDiv?3T#p z?6y&TY^8e|`gYU0mFAr2)z6}a4{W(m71!NR;W$mDiR zl$^$Q7^EPT!o%vdwgWFNd?~7oN!Yq_-14n{uLi6($eT6R`OvdkblkFnvDXu_I$q;+ zC4>3kGe}ZiT3&Cn#Te^`Dd@6B0Vr1j0O z{7vUZK3^JZQ>%vj&Er8Ey8K&vh&1-PIE}-;1JAdhF$Hs^Io(#xAXA_E2fcuzP@8qB za$9u)N2vj;Tk}H)15rt+yHO1!1ydxh_=&Wx$|au-J~I|O5No0Fuj-och^BStRqnf&&JIqM!@N#H&_0_0KtUkK@!nuqecSAv)H8`{~FaJ$DLW3546@K=Cd=-K_ z>4Y;7>qM(*LH8)FX}83<`9q~vC+yo+xlT1J^-ok8a7mTc>vx2E`KI1cx<6#lHH(3s z7Ub6`dsnjH=iTkjg)?+AqJUVHne`LjMZ(I#>P#9-L>Yv4AgNzh@~B**#3*2EC8)fw zx6*|?cOGM2n~>>dgsg>b3N^x3YrYG_JLxu|2~qMPoFTqvM}4Dc`c$?NI^FB}bzg0z zi)LMYb<+{h*3}Hen-!*GVt8N1+v!77Ga+MzF8G3kPkNFsJDZjxGOYDeg=ZGM!A2(6 zEKdPGi>pQ2dit4s4X~-60Tt#x8MX~UOtVY_LzF42`zwKLA_*2w$%#9444IOsWnweY>7H3%bfP|zyk=qhwt?S^Z063zZ+%kCP6{4q zRcsb;`_fQm%KN6HzSGZ>x8P&dVax&q(BB_|dx-|JG5J5NM>s+}{N)3&Xw^#R$=`2o zz@%~@RjLupqd*{!khxyBVgDW3OXh0&{YDfdPK1WqA2#IeNz>=bMCGl6zU(8Euj+z& z-BnU^@IBHTn`wNf!Fz5ERv{}K!0hso*+$p)*AuRWXLVJamM0seSoGD**nBfHrVBs@jyv&lIGZEBRngW6+&p|Ky|2@T>)Oo}0O~>;{D!}%AeFBKm z>cn669;un`eb6tr>_BfkEFiiXSvadp_Xk&9Dj$C;e}Gpyig7JnKk{Z;+KN{Zs0{x0 z31)}D6m6h`UL__pf<<&p5n>Ba+H#I*J1<4*j||S8^U|!#QD}#SA4r<8#(Yfv1cs~x zEcRMpHx(yr&Y|hz^iGFK9EsvXa+d<| zpLOeBQRH^K=;M7&P|Zy(*MoX0OUqljoF-hZ^@Gu7GKSo%7REgl>AT`_`}92b_^d*| z&ZMou?VDd{yaqj@*6_OCo07m$M__T$Z%;PbT+6tBCEv2TwlX>NMhrr2tt%wHkEmEHyS6=Aoo#JaXbP26qvg}00?8HTywnNdEu{9Tun7p8A|1RvX2u35y z?^u}H1e5GFSC6P+sfMNbxdZw!V_fh3(hs5nqcW(3hhJ6&D=KRS26zbM<2Sa!R?+(C z#StEs7zM98>gFb_%ALAiC@l4IL-wtf{4%b6xcHO^79k&|&vqWP_75r!eZRhsR@OEt0mMU)qkBofeK0tE-N6gP! zbr3zNbZyF*WjM@nPq*sT36TKN>kS&vgQXlC-T}F>8_tDP(7l13%lC!2>At>h$^%Mo zky=f#eg789R6SXhlL3l|2=uwXj{rhhE=XYL=B%JtIDWz_mCPMXGg8Ba^|O%dw8Uws z7F_Fi6!wqsb&xAW3*}=O0egNoI&0MJK%8b0{fauB3|j>^N9-b7s4KOD>?hYXGgp9r z{Yd}T^*93PP;MO~3Yw<%aeg1074-6A8l8w&DQ|uASc@WCwJK^}(~MDo)EHfQtZCt6 z&WN5D+W22tvha?Y(;V9JF@86$z({64`;5LwiQKUDW7i&|wWi`MkyCmraVU^OZEub! zH38LH=lTD69YlX?3>&WYEEq=Q@R?V!gni*JClpAy~k2&U;WgNjH;?TFP zA7#!}%R1CZy|*N;-YVAkZ~4_Nq2LTfHSj_p)bHa~?XNAONI| z4S$9j#-2VtT=(isf}9VH&?Xai=}LQg7X9TGzl!gl&Gh;e07wQwVv3y4Z*cGZH^h&U zYqGMui}gn1d)*2twZv1;C>NJO#2#g8ZsNu8TOYw@?omd zZL*q@?Jm=YDa~y9>ub!Wf6xd#pZ40K31dasqrVc0QX??r_AMH<`G{mi*}(Q);&1x{ z)Ap(iF5j6IDldJ7PHyz8j=aU=nddLofKV0gm8a7&+>kIw#-HOGItm> zV4QV==lG~{)zy=x#gPwsuRiG+)=#k7vTrOw0)sGuzJX~K+h+@*PZ&`LwmslJFHH5U z__7jwGE}Num@qr=m24SWif!Kbe19m&i*jXCg52D=hXfV_^X)X8L_l4<@dS1+QpEjp ztN#URg7Y@dbNf|{$?8BSqcZdz$WOZdwv~o+{0sq-IO<9;{Y-Vc=2vkrb@!)1H_N?Q zZK@_>?i14>=f|2ASL`Szg}V)S!l375gQmTF!UwP2TI1{Lb8l%UIR5)~;!Xm#{v3H{ zu$07p)bZJcKrP zwu}>oWY1P~5P^XaGhNs6Cmx!Vbg^Xpk?QttF4wcX;C7%TyuhlF6Wkod5bh|5-v}L0 zg8rAb7~G!+WSJ@*6!4>pjghV+2S_K?eTR!&)fk%#4w&wiZ8HLIbGHRli-`uhZc1Z2HU@1zqKt{{5JG^O zU&$8x`#Z{fWNN)PH}7Tk?H554p=Wo!a(5|EI|KwZbPBAwyaqN`V^ZnM0S8J`$oVblN?OTVEj+FyXp%0K`W3m(U1aa zNUr5j^21I*56JBEvviW)A87|2+}rQ*Lt+|e_^Kwmu1)%W1sq4m& zlLyP{o_aC4>(j-p2ow0_Q+1@~(&D)QQhOV2=Npya3yLh~KbY1u- z>JfDPxlQ#Fl{bu*1!RzZv4{W2jN!sbFhEs5_%iw83Oe+a2x+k6BbN#;D4N({SvYV5 z_7)smsMQ1Ng)=vvz(PTQ(zIKl&bO!kK!ND>4!9>MNSRi`%CBd>-Ka?eD$= zXGU3jOxfU~^T_7V0uziL*jrE2fC3E>A`E+A1stfLk?G7YetkuFkjT?8G1Xx!8GJhp z?t>wVWT=*=-@*F++3xe)d?+{OrxJQp8iwn=aDeoSGCEp1Sr}j?Q~T5kl%7 zV9>To=dwrbMGbL)qUw~csbVWGt;GbzqajN#F23wll}Vl9Y)#8juu8~Galx6t#xMV zS>ISNS*iROU!V_dG=bdrfJk>Sn>H)GQ>h*9z4AtWk9wzrM0lE|J+i>ULP9>YJ4UcT zp$d(0Bg>w5g{ZZxW3|NrpfB0f2e$qeVBgbmMN3TtgQH2FBT-*Y510R=$M~7+W%ass z;qh;6gFWe>9QC_b#q_1HuUrQyR*%}C#`1AzY%xtME~r3l7A_~6bB)6_Aavv-&2z5MHq_F0to*iL%NlVHeu) zem9FD(M8oxtcs&VOR;}P5%ZDn{K)r|b97ie_r~9>`DI>wBcTCPR~5EQcI77wl#aaB zJ$g}c^YZZUX8nqTpNntY%JG>CF^KzczgOho+&1Bd5^F6@`t9`af(aEis_8E z4aV+ifIn@%^LUFIb2& zePOTEVxE;{jH^}SZOY{jZo?CXfy5+-0V6eUsJKYEq7ZM=sGaO0O9h_8N@uiw37ffo zhsAn&=b&t_Oy~n)!;TqXF1^g>&RzJ>bh@8Lecw8~{C2)R>eA6q!u&WS%Up&=E1i1q zsb}(Q`l`k6(^`D6I|31|67iaL`tng^Q16Ybmx6SAq9#~y0 zWU060S>lhg=6RnRe|wk&v*v{+)fctZ`(@j{QXYtyKI*P~lUtxv!~WSb?ruo*(tOlx zA{Q$~#c=OjXC5X2tMT`gLUvH)Taa-(ZD!{7GvvI@i$2&BN`55WE@TQP8HDuvpIKwz$~!!jBVzYvOC^V-868I5J@wrCKMI-37CCG{(9$? zE3Eet=2xVJLf-3N7bSRYK8k9;+%oygwUyDE6aH?Y#R%gI~qF^ARgN z=Ptt9-wjZ^U;ZMf?H>EvlyC6sOnslfRDCNszF3&OC&CzO{{gUs`6>c+y9wIK zJ)gVEkM|2Nga0A^Qr_}>+O6puNa{0Z+9-a}Kq(H1Ut->}xFV0j4#A6p#Tn3|ts$8O zYj0X25Q_soPeJfez;+Az#l7EJYmv9Oa#7p2xLk(Sv26YyP*L!@IrjLFp{yx@C9#- z8@HZ{XcDx6)b3=XZvCr2e(m)bYf|rDx8$+Dy+CzHN6kRo;Qpa^N9Q*I7V!g6zpQ1q z+Hksm931lRshnqgrCrDA&&3wx0u%L~oSsyj;lF$I{-s_*UWzE_wwst(Y-k)jCy-*TxRW$Ry+<}o-4cPXAYVyt(^2fgSvegM~S49G*vjL)};@=xs$Xuyg(FC>_7e$KBgc;6;E}b zm`ud-Ku!>M?qMa_b=pPu(>mu#V+J;^sWm zc%>ZTJ>V#uB4@|G$HGDdb<9(SRWu)Z#h#u=0+uL zGAVdQ^6?ti3PGn_GZ$B&?G)t|#TAg<<=AE$2G7S(~ zY4wrG3Yik;D;D>K$-ImeZ>OF<;A53Gp?K=Vu_iVPnYBFx!V7JcZ}Mdga9t9;|wS%R$)bQ@&f2|;`Q5Z4WPB1$&L41XB%T+f{vOJr@w8_$1r zpYj_1*Qlf}Y<`Q5Kup{*>Fsb)jMrj%nKYqUb8(>+7BGzI&J|a5lCF8vPkXnmhOQ{I zy@esW}q?0mcHhFKH64aJS*+DT)pgCpBMys$JX&a=_qNM zrQvqGb}l7rtffsdg>9K2%EmyW`fbbt!AnC^bDHEO2H$-DeuZNmGj9w1RD?D?h(SMf zc{V6Ea%J2S8=10UWuhl-2*Lc~W{eEy3?NT^~hKUlFSdOZz5E)jBMYF+wko^}4cP|{C*uA?h<8?0KcveQ^ zf1RKnLsE8#Sp|fWn_W`k9MCp9G8Y-t`SQP6q98G($-->(6ZOnl zcjVd^MOUQus0lHcD499VEyRP+pkJJZnh8sS7_?hxnZmiig(^)z z1~QO{7ZqNubkL$T5r+%jbTT}edA|3IrpMCy-c21pEE@HVVaUd~70-4M1> z91A>I^qS29`N$p0K~&kfRl)ox%jze|=arTD3b6pR4dpn(&h}kJP zw_873uT`WHIaZf1;xodon$FaT?h}jjH^j!Su6h8CUD*H`<$B?s&Bm=l&sy}G+r*t~ zt+8KCKT^aC8VskC!XBtLy6B(EvNoDxD%9zo)w+9Y3=QgafVO~&;~jPfM}jPR2d{05 zcLq7fDbad2W-M+%yL&-B{h-B$o8#9Wpk}i7fglNMtpbo7j}3LvH^Ky>gTs5*C@0lD zz5@P|5Fk$hYan9oucQx(eCA^29)yjbgcmKRnCBLm$*6nOd7;qL79-qZ&FlnvnwFm} z!@_jS;Ra$7tYPomH9Ihr^wh9Kw-P(e6Be<%9t-q020*;@22!qs#Vk}X8w}fe1icZX zw#qWk^W1M5RN;(Nm@B%s!Wzc+80JQWtMc;E<_!waOc`xgLl&|W|2Zf5J{)T{Lqm^P z2k)5vjTUb zZEj@K8&|_Zt?3l>F~iv?2TjAK2({7`VksDL2AckdCkUhN7kjEM!ETB8z7(oNF@yLGR915 zH^>a$7wNmYW3@JT6b%$YKG!uG${y|AKhUnEao1LGTE&^Uy@_U)RqWrJ zR?zcO;}2Gq(#?3ozo`!7R$(2vE?QqqW>S}uXvl9!@ZPOdjYK@9*Y9R#CT~MHG%3u} zkknB9Agnp&2uw+0MkK1LlLjU2$bVFsp0;mL?8Sf_CBsy@l|yLl*GPhIN@&kRr-AX*u8fW>R5Bh0iO(S{Sb85(%GLfpdiw z>WTQ>9HJnUpVN|lQ|D>r_^&Rj2*xqybq_*$i^ik8jF9S){f=MqCyKq4OzHd;vq$?T zkA5OWc%iQ8{@Jewy*OeGtwf%xb^n1ZYE;NXAzOmv#s)I~z&x0dIpart4qbz@1#{IK zT9=|`kz-M9-~kWaEv*NhM1tkL$Dl25z?ZXa(fyZuaBR8?!Zl;IdXqJko>-u6hXa%F z^lZuYeeKzP)dSQ47M+kHyZ3nMMMVp2!Xlw8=_O>#I#ht*j*n#bY78@9xOx2(`q!MC zwjy5AFzAT*#hoH=s2x+MC#^b3DalikkI%Gw8EK#Hnt~4pfA4j@mjTn$2Zc!^ZUi$6 z2|KARmHndQIcBfK-!M|btvAO1wPoveSXuapdki(|P3f0gHC0;Xn|yw$+-w=AyMosF zW2`cq=(eG)n&q1(wAx$O*sp=Ol)+=nU($xmUDlJV{D!y~^W=N>kuNDE8}p%+>odyK zUs}$ZAN_eR>!o5yy6rlC-GcV)iLrO&vm0nf{YQqPhLqv(#qD7ub_v2;c4UjLO=1z_ ztphS7)bZ%6=YF`Wj$5A%*_3YBv2ws52TvN5@zX(~C5w?5x|=gcf47_4T9Al%A|Ant zp-{lGfCrRDA2AcS3hh`IgRzr%y`wylT2!=3zb5B8-p!H`5En|r@k7|!Q~6tGvK%Ag zn^j}&!8KTywhd8BBc(k75U1Ra8`fe~`7~Bn@jiv|ai;U8LX~i@UdZv6H|nzM;97?s z*4I6Uw>)A_w2EDLR+l?8Tn*MY>!)89TY$~IoZ4M44oeNKu|?1s=g-`zbZFJfs^ZV@ zFIpg~)_8Et_KyAEq60T-h)j^{8iI0?`h1`uL-KiXmKbZ*`tZ5;;R!mhUF35cl#(1j zA<)s!yz^^QFqEsk+U|avZHh*Z*bRjwxHNp)0J7YWY~r#t4I3N4E4Ut4yizaiX+H+O z*wyu-OMG9p_;}+~QJy-YNEeJifO$o5`A=n9duroeXQf6<%7i_gNQxsyF;-xS8mjc& z**b16gr!Wo?4p+62eInl%IQ!EX!z@~wta=|)$cs)o36M1LP#A_T~f#QC9_XMU9tH{ zcZLA`8SAue82_7u$X7;$yL;qJz5-Zud;;&%w=@Cg)jWz@(GnqCEE)frja;MzXII%| zE59v3v=Ow$#5RO3529>15b=urn$@wuEBbDAJ!-A|hHi)NN?V&JN~Pk%3@*3&>Phb@ zZjt@>x;4b;Q2V>R+dqqnB)G4|Bf;72pA&b$%3Dt!CAazx_G&&b&QhHhJaRTY-_N7% z3CtYu3+%V}#T~4V8d~dNvTTl3B0DUNCL1O{>_cCy3S9l1m=LS0Y5MPhsjIVei*(as zQTp<#uesUktx@t^O)2f*P|48n2oC+*iRTioCw;+#Caz}fck z)6b<%fZHpviY6>N2`DV{b=?2%*Ten^Cl!Nc?3@GV5W_h$#HAO(DBv&wZq;B&||GbnM!~UHhN_N0FKenur+FdtXhS?E%eUZ zw{DGYjQpw`KppFBhh8H|wYm#NoxIIFtS7I*Cq9*!)~l+1M~XT@$61;I z!XtCF)Tm))g~#AwFy_yf3EmAs^`iaUy}Ht${L*h#4gR)0N`MtDml5PPZ6S8@LSGO3HGBDd zUY;G)gk*7OUvPbXrlE8054WGf(~$F?2#c4-C4bo8-(25h=hZ8j;Eble6xPKS^avFy zLBIP{P9XR(hy=q$K7Eh)fz3A&7vcvYbvMCgSh~&Hh13)4Q zPi;!vYC>O z3<^xniwftJwB->bxTwPy$ecx%w(0S|(l)n}aQ4i^emMFEN zI77XL*n13ebFO@o8$ih|W%Fv47khID%wHz5+@ow(cXwvo5(NtKU8z{&PNrsYhT%Xo zGHuph|HM9&3)q&|=Gc(3w7MAMLy9#q*zRoC4s}d2=^|}^Fb=S-=^BC?kZx(Hl>so( zW|bLl+qpACkZOmes3HrB-5@^+NPyV3)7)eR@B+$|6j~VnYm43{_z%%c%VI50W0JBq z^+#4^vs((qJ6gHEq9^g&VXZF_9s-UyTd(NW!t2#qEd^KPw2I~p${`D7VNinI5yhE8 z9Q)X1CM!PoL}#tKGO>x_Ay{Mvbw*^lTq-43=`B$+MtH2{ zL3ljLLs*b`pRm!DwYB{O_3z6dV3~4hKdi?Ck0Q=uBWv&IT?Us_WIF8w#{>umW3Q&X z+NLbO8w*A}Ge{y^FSCHZm`DfjFi_FqJRGQX8hSSkeU+s0=q@bgu=0RkF!#3u^!Dyb zW)Y&qGQM4IFp)H<#;?%7(pI>OVC9bjg#whQu-qPK+k2fN#OOSbYOLk{wqzTDl(;e%`ivtr zaiXDa`eC{jv!045;9xnr3e@VEY8t||=$kPRgMs93f#jym93z;+SQ9y52!?1_hXq0& zkfsw#+J;x1Jei9z_QGzSpa!RLk`r*UUtUnF?2xUPRJqOZitoA3_TZGQA4kGv?vxv+ za)CH4W^=mJrg~Uo8{lWa((CuRqc;a+6{5Bvl0hsX<#Ko{D7Kb&W^`0pzKz?JdpWNS z1KvoxMB2e&YaSV8E3a0YJ^D#}w|s#hL%sB=_*@;2Yz6(t46NjWY;#v2Su)WFutnkQ z0{6qPN}rW3bZco|6w{{C7Q)<7vG8hS#(~*w_eEca#Ej{O-s?43q0$pmhlVIgN#fx{ z|JIDblb|O&y8V zKPsEBU$)FJBUi+}&zm8!I@ftV%%&q*4yT5B=Djdh_-k9#3eJ1nV#D;TI->0-w{Zb~M#4a#fcmixw=PIW{bw zHvd=)h>AIhztPrm?b>(0S^`M&Z}uOMt6cazR$D#xQZcZT&!fHkqs*_04ZDBn&i1&B z)Z+QWO?>*eV{u-l-R{%v-^QWI-2{KaM+{mRe9ORRm6}AO`3wE4`s!Gu5--sWViEcj z1w4qId01&Mt7Gt&BtY27@qjIZSLG9ZGH~)tOniLjeLHCMx3@igdGZ(u=K(AR}_vs>8jz9XE@rz*LIsfVos@282PM{BCE68d^ z`Wo;?4aguE{P|rJOQWW&&ZQ3g3`!HgDw5BnjuB3^7aTD`vxce&1TrCPK#PHRI zUR89rop@o-E~u*p(ml>-ajq9;p1&8-XbWsq!WCHX=VBu zT1aZS{84c0`X^0dWO3UqWUJpTM1s#kdi7i7An(4x@)D-PyD+iak|NgO=7KP+= z*)HTdLhs0Q`PJdxZ| zPf3InKp!I15%|*j=1EI1AO4>@D~ZWe>=~;FfbiswsVN!d)T_M}<}664d5V2mWnv<*-|}{& zB=~x+nd$nPoyT<;PQ{ceH{unBSya~D#9PgJ6^##Dw42}j-L(%5|Bb51u&m+Y3VoXz zcGi?u!AZxnch;3scHhI*?5sJG$mq8T_J-$-H6G(Qhypv0(zBYM_ALtbXY^94P)*XiUZCgw?+Dv2W6J zd}Z@zUjt{Ht^wNotXaBR4$TF223LJ=3)R_yim}PTv}t-NrR-5;15Yv4;z#yBjC3s9 z-fM#1qk;8JmiLwMLBqCNa-mI%ce%k^cH22yC;agNHJC&|FR-3ZV;E(daBYOif-MZI za-(C~e<-uyEhJ0+v58}9TQ2CH1a=(3+XvL1)7-;Wd}Kz!`v1&*1?h2omLsh2zMl%P za&=2erLZh`xlG5~Y~yN`BW=W^;{Bjf-Tc2u@j4tTXB<-W7^Fw--pb7hnXyycYU37l zz6Ew4p5_sEl21_WZ02dZ5DmzF0zYxw^pIq+L_b}ma?ie8+v&*Gp9w~i-7=}V-Yrq3 zZav=A)6c>&KzICCaDvq-#_78tRo#}1i$eEM$#fd$#mvpm!IqDkhPgCl~o zL#o(5$)BerZ`ja$-uVgx@}!p&o@bIjHnc5#Ter$!#c-7O5i2ru84h-Ox&q;)B%3ya z43!)&<%ktMmI%X8R{_rxcdnLcoIqqinrv7iM}-tZbcF9Qxc99Wn(xZMMj)zC(m!Tn z$`OPpwpmYsiBh%z(>w@2!2Hkxk#})0AnwE&&Bo@89#7N}Uj2G(g>nK^e0vWhD zdk$6*o4eMIMqCL1HOlHImQ~!<+Pi&qFE*3e`B4r&Q#?s}3cAQgoRhacV<}6eZAOX$ zg`%%O<7^nE09!-G0{AnDisUO$M2|MsSynP8QVTFfc(Qk5bDO2gwURLJj|_+>i^IXl zvB)$qkF&OdS_wU9je#R->!u*!6?*rdtTW!qMcdBnSs*2W(PdbiO=uAM+@a$=U8li2 z&PRb5Q})wj4M`;e<*my6c`38{&EfqYrC^n8Td`4G*GOCq~#*$6gg3})J!2v8;ANm zz0y&?&QYG`DPLi3xlt$0)N?cu<*x;Hm#H-s7z$#MU+pUev0j4`*CQ@jRn{B-cKoOE zk*`1Tfd=KK!dR6`jj9qq>O|)GH-w)$M?uBh?vA13SAJKq`mgr=xr6|wp_AbpFPgWG z|B~{8n!yq$_SvpKz3azTy}F$SR%6AKE>CL7h#tc{&~k~b$v%{lr=cnV3L`&vdbpjpYq|C zeyFL7VQM(}cJm}0Z~8V+k_~?Bt?)Q2?3F-J-9o**W=-f^anJ>0(rV;olb!d4UY{&p zotRSyl|dYLYU-T&<;l5M2@XIjyQBJ|YZ_(maY}XWFn2ebS+RMp^ug3cXvOC4Btrwl z#EvJ)Vb}orB=4b_zdBaQYW=y}CMKei7~o(%v`|}RTIf7U*^$%upWjSF{i=2&2TrU> z5?PQ~=k`dgV2B7;Jq+)HDw&XA1alT@-&e}S6Mx&B`Jw@E(cK3O(Czc{gWkonoe0y< zKGM)&w90kk+$14*lZRff`v~~0*kAV)^0v^)<{fw*+P3$`wOJ{uzG8Ir6$6yVy`fJN zMr1aD%WflC-;oJDnui%6?*Gm!Mg`AD~jeJ#k) zfQXiSJ!dq`%pV4_y>F3i4y|uo*Ium|sC-NnTeI@wJF{1V{`r>Gl4j2wS&;#fOxZno zSbo%)f_uMrks&pIgsU2&KoOOCmTU2*gfgWXf?M*Xze?`I-{YLZ()PFs$yKN z8t|!=<-L`zP$+7Hl}s8v2kWs}K_5-mFe5wWRfIX~kcMvzpwqWIw9ei*dv~qsA;SE6 zjgMG~x}2<5@m9T*_q2EClU%Xv45xpk9ZyiL*8-mQ#`d-7b*eM>*?txXgnELkmJ7vY zgDr&4bC$vn*D#UTS5t{BbNtq0lL2q!>~BsHj{MxhbW2flI|2 z<8`UeZ8WxOd@+F@z&_A-r*`b?;(8HyTa--*G{j}v))T{J{`Ps?*8uioyahWn!Z zo9lr7?} zav-XgWkvrGyXUfB5~=!TwLO=h67M&TwZJ}gko+bIDEIaU;F)+bWk~%^5&UAAT7Pm28BO;2ny%zBZ!idVe;V&$n=-#g4sFa=a7qH zvd>TxWL0dEa~t9IhAG{r7Ku-1$Q+1Eljk&+%;8PvsWcH%X4!WGGXA2?OfS<#_#*%@)t!d-xjaD6N}Pz$#34h{Cgwx0&^I8ZS$`uqDF{I#se?ZQOjz{D47< zlQsQU3KsC&rt_lAW&RwyZzk&FXcuUig}(YJm$i3IpYY0{&zuPp(z{)9KyBYv_x(lr zv+A>5j=6@AwN$+EW;otNg1s1uhh<=}HaUqx#psms#IE3o=m!;o7%RWbYAvT!At_nu zX+%2$kM71jGO^1c^ECIkrumsP!*ypo)+}ZfV$VU0T>?%rorYOa_lu20ngpCCT`sd| zzN2Uoe7cTsPTfQUEES6iRz!eNCE_s;!!=aNUcU~ zH_Y>8zE*HS(SB^{yXBl$U&@F)?2~W}seeuLW;vEStQawmI>8Qv<4@yXyEV^Tu#nZ} zP(eLOjPLN5?rjWQ<{?J0=Z3@A2~`650=I=;aB$8a{PHrejg z&(UPn?chm72T{3eq}xL9w&(hU!*8Cr#bR}ljrmXZUBi(Rb%p_87XZi6KC*j2z_COB zZDsufDxH|agg5*4CiqmI0~<%(Of>iY8qTnl_zrLC=A0;$@Qv==9a|PRsBg!lardB^ z2b4yKkyBKi@A{`G;K?|#FR9HF#S6q+djF?ZT0&EjYHv355@v`cIml!`UoT@%CUY1R zwOR}NMmzsK(rP?%kvb9tyhxfWqh^(dXJAsHoz*?HTFjXErR{TZkb4%-a)M{FWI*_> ze`Y-2LzGMUX@&2=l8VUTxPo@WjLQPkk&T?G%TiSqUXZR0sc8~8@4yxOg=?cP2gUpy zkR9x$;Y%8tve6bj8SkzWdyqy86aY8^~!f5Tk9MwTT1j;=b&fWLmAlkuT zc?;==)G{&GKfUb{<^Up;`#`F?*$-N`X0Od5>qPX&AW278kH!ftGfe1bC?Z_F5mcLC z4;UW7TIpcdq*WnppWWj>9*5`8&=~o{HY6-s<7&>s7?b}|bnfv?zyBM5?`X4OwqcIj zoaLNDgluEXsfHXPZ4Sw?maG)A*&Jr}iK0||P?Uw)~9182;RQrc)2tfIR(&_CL`pNRU515(>`a z_##DALK#%xM?eJRd{ztFhEdzN4d13z;8jq3vlR0DHKIW7W>SfakjX!okB(qI*3~C> zxm4!g1OSYPQrCH@(cKE2k}vAHDhmQe&m@(X%6Bt!+~)$~-ETSg z;W%Wndrmy`?OvAH_-6=pT&`^4r6Abx)XZ-EtRp|{PIJ11rXB;tzSR^zr%)CW~ytEMIU zIS>wU`%~zDX{t8yLh-;b<~c8gv(Y#+@5sQ{tdeCK9uY#jQOSNtwCi$E=kPR}-Xno= zwQ^Ka*HOR3$JEj;YbZriKzR>VzMiOZJpPEqxFrDIhRA9X9t}GTMGmd_>kN0h_GO|! z^bQgGkuO}kZxs*xw2I@16`&rU!jQjtD}UKH?+ZF_OHKb47(ee?F_lOpgizqV=PKrV zo=AV8PUHkAD|=w%rC<(PIdW$JGA=LHsHJoG{1~%d`pkj%e$zjFFu!Bb!=Dd~CHpCk zDV#3V54~HuHwHONF;9V7PkZ`?xH7@)x@q(QYFt#TziFMFVRMlC1;ld+CUUoUHPa!P zcgH-7Wk{|s)52~(Qxoa~cO`_|+1Wk59UHTCt}YjueS|#Pe#SbhzSYv={9oA`ta^yZ zHMp~2a;hpDv|Xt4RA1v3_3gIjvu{1g z9UM-FW4@CNe}LIOSH}P)gg$LQ+zjd3rY+7PtN}PWF{b*6ytiSbJV_N>u@4bDoFV%vfT1n3|-iDnAuX&y=cyJe3|yU6#m;z=CdXEKnT& zo|Y=IHzzbEH)MWBAB2Gaspr3UP`4zj?61kdM1aLU2!sXOo${1jXCE&gGgTAI6yt$hUh1v0hekOcFp@ z+&JyzHJyFdeF9OX+|eK(s1ypW?lBETRE&$@Iu)Al_(dZ@`PM3T_3=dgRcGPu8tZG(o)G-?ieZ zgr=lWMH6l;cvzZhl}<=uv=GmwLpc&Eq8zbuA|;bCBhD>-(Ea0w`Q}bZ*)@il^pZJN z%)9G%-aI)~UBn`Chjmv9Fa8~CJeCUXht%~hJ)0N{K|FJzfZ2}Mr=MFk%g29S2`|tu zyj&YuASI&NAYGC;Bi1{qJ5xTM!P#4@p0qx3bf;VHLXMeVB*c5mOP&BdH88!RzF8P< z!bTmzt9910WnOmyus{<&0lj?%$laaySp4hj1cOew0G>WRsGV!%l75I*7^*%#*H)loo@IHeS{-nj#8JDrD;3jYhGP(*{WN< zGlextOSRu7vI&Ap5)xblWw90gvg@Pwk2+iXl57ojkl#59_ZI&OzM%F<4wLN^;I@yP z4u#@Q@^QQ~0X{b3SWL3u#P{w~pyt}z+I?lb^@1;=66>v6=MUr~MBA50_UKOgM*5t} zV*qNVZ1<=H)DQ(yMe7$HF-ZBdG%u#r{<)OtrV{wX;ZKCyC2)1M#c2m{V#T9&+r(+~ zG|6=5OxW&ml4GRBf{mI9?%RcLrWOkeJO|#VInb&c9af;pKH>=45545vLm88&ObH@K ztK6;bLL)CAq0jp^_Vu0fNqAlNb}H|prYVKt-p=klVihA|pp}M5Q7X7vQF04Xp+-Ek zh`txj?{0(ahmn*n=xd7l%s3g{5#Nhh%&9sIKCsZ^qDAW_9IAS+!{1Z&3zjdms7Te2 zyewmOqM~L=)UHEAfz9r1x1Mu&bbC5bzs4L0uLn-Rf%5?-K@INWLp;hX47`-izPjGl zyi*cZ%Fz3L1~y(r7Ukg%6P2hi5X!laH}U6{LEowL$%&*L>5kJX(MyW* zeaehE2S}y7Jv~0F9d&GGXg$XYCYc5PQ)@0NToxcjWo5&m^`btL6lko-UbyS#T*1PY z;#Z#!PEttaq&uOwA7)Yu?Yj-=p&Fw5{pHF6e?x1AROpn zt^dKrm2z56DCgP}mVz=hj7!S807m1Qi&w6^wsoneEO1UBupY!=S1qIxypyd+P~1d&Z%R^34S~TS z_h9MwhOE^7IoX*(*~@u#_VhVrMoyrpZR((Ajd!L(9keXEB_y}aw3V%&-jUbOFP7DV z`Bx76dlx+5-fG{~z_ZLUz@P~mqatougYX!LKaX88ygp-<2bR`c55OlL@=Y3glxte9 zbVCG$3x~ZBAjdgzXs7t}@J!5X(=S`aJ`Ti=h7yg_*wg&^<(hfzH3{2uVR0?Mu?(vR3|5>gQPd7oUgYX6ParpJr2zQr z6b}v?M@eXhZvzRsDtE=Pmoo!2s=$esaCOG~jo`6kR0N!cRz+u8Tro{%TQ-GX0G_sM z6Vb>rQgiDoHBGsaI^fwoG*&rptgZDfx2TbKFCcR_LH(xIn3ZBoH7$Vqs=T;WhyO%n z9rL>Gd?;NT9?#aBTSfy!$vsExeZblsQGX|G^%jy8MfStKUjK2-a_14L2cLm(f*%;$ z36Ar@RAet0w{M8$K;x|HpFV8u_VY)_qwzHF*o@as0n=t7~!VWnuLOzU^1Vl?BtvjJ8a_h}PcF!h7hYWD7+LPbdyuuMwbVm;RlwyQd7PUl{%16tm7{ zqrjuqn6x zg*YYVOo81AEBkk4@i+{64d?t)H{Jk0c^=A-wtoz6E5M(q+7#pq78PLPTX@p(aEbPl zl6)L{^GGCq26jQ^lr*T(%NB4chkAI#RJIpKxgiPJlE@M`%kM~&jHS5dTOl)xwzwx zTK&A1|7iKsw)O$yAgV`iR6QM64WPM>8{QYjo=T>ZcDBjYAM{g??u}Hr@784f91hSG zUtpjYc=L4n*!?Swjjz6kqn}|=V@YsqboPQ?aa?fD?|}o5x~haIEvOyj1`H-HcetBc z2WE-0Gx4Fk^x#-GCDnP5?PaasP6&`4P`w$Fs#1SI=T0SmLZ(F zUz>3=_4i2CK>57;3XTYoSK;Z{BM@Uw}=;X&QD9@_tTF} zbV$E9q?RH!D0@jHYxUbhxGh_2IJZ(M9Jh%A5AeVDuUudBLujou#)IFKPtVrg%U9q2 zN}Ia^Z6NKH;j}3w&wSpIRTDiT{b0i=t3nfg(z_Y=svD61I$Pvn{(-5C*VgT@(q#Aa^AmXqE?NWx8=g9C^C zp7a*lK2c!jof!~MyfUVWr55keXi%aSx2gv>0W4WonYo>cMSuOdaB0Ae1+35wFLGtCG}sY94k2`_6rkA<6W?$3Rfn`O}Zo z9}HR3x)ApEe}>LxDHE;1p*1a^bL?3fC~^(iuitD5c`MQmq2x!i^gXmyK=3ICE?BO0jrq znr+(V`2v4>AYJws5ez+*me25KB{yNcpG;#;F8@U#CJm|&Tj~DX2=X%?f`a45P9kPV z`&O!<70#!yn|?phTbSe@kHjk9LWEFeP&<@F1N0C?nB!Cv>kxB_*YSHzRN4Mv|1i^G zD2E=qPK183%-fS`?tWoVx4*;ATHkVT?drB|8cArB!IFs$mqUvrReOn=UAv#~Pn3N{ zxFxi2D`rFcNMXw0cT>NDrKwv=Dq&=!gt=Dxb zt^%98>=(q*G=tU;tsWsYc8EqFWwrOKtXSjXgu|oUG5FYG6wsc5hK5IJCrc?(L8s7c z=Fzj?s;zL)SIYSAfWSwg?g%x*p+8u0vDED$IMgaI(8u<@byri}Gb`iHzbA#z+EL|6 z8s@b%rK^B!6*W4&>*)Wo3=sv}$ClbPpQss{gY)UzKW=S$#&qG9-O-8oEGM0P zSe3z24r#*JgqwTjYx7R(m9jo&NN6b%E$N|z$vsH$woFY%W-#NLb~EYjwL2<*KRn#9 z9~`T$g6#@XUdnwbtz+&68(Iuu;mpS65Xg3vZFbUr#Eqph%VSK@Va6E{rXgyHe@v|O zAKfNvc?^ZAu2UztCyC{2o*4A0gSPuMbu73Pff8aZ2HJh21kz%MkNk?$c0{A=d0KbP zTg>5EEws}yLT1}eTS=&3MBk8LW;0i59n;3^I)u#2gomXF$R1*4V-=$IAoRv(zwXp3~Xl4bUVTsGyAU@coolaXcH; z)4GEu`ZqEw8tX>eN>reCfcNz}gpBRj6ux;Hnb^5NZ{#Z!7qiQw-oJ}ow_xyG9)g%J zMgOWKrxl)3yIJnoX814qFCJQo`q1gQCypdI*iI<3y&uc!h+K$XyJkf?6_9Cp2l8uN zu3c7et~oGhZY3DmgYH_(zPb#C^i}u;yABCkZfs!bn`aeCHnSb`>|w`i<=ZJZ+dApJ zOG`U$g)MZx7^s)L6~}aT+7tSYdIfmeb;PQ~O-yzEAvM4c0BcM~ta?Y_GXELy%|jh9 zrnG8;g4L6dGaXfGTaSo+b{&Ae7yMq|xO-M5<59P#ronaW_oFi<>CMhd)-=vPQ8|bf z0jKzsc4XHncN>hsYJdLM{!eW1iQ^T)Cg8a*C#aZyDgglW;l|IAo=2ZkrtwqZV4b}| zzJw#6@WSF(+7n4idR;Vqh^WD*;K!IarfSNQj*cM~-$HPdm90_z_-u28{0z^>#sAIp zB@7~ZzfpPnxw=KJpJ^b53bnWkZ7|D>Y-_v7X90qFtskPX+dDl-vC26^Qta0=Bz}qs-mV?sb17Cn?}gKAds8mbWdwLv*BIf zxJ#Jw(h1MbYLL^)3rX0jMpeTF{>YxY7FlF;L!34-{lYr4#?2%7pEYOf(_qG1yM~Iw zXyWj{5XoQ4>^*MGsym}J$A?y?tgLC+wL^`9Sm2)dqrL@-WjOo7)hwPt_d9 ze-k4X>oEa@8QO2W+$04;MFst#ZG7waca2zafM;^NO|h&<5;r^nr|JJZj6swcfLW-R+)*Oe^@fmWaPTq}8!dK$Xk&P&N|8dG&N zys!p7i;#HX1e+5XTm82eO#RafZld)YhAe?%+rG-?5Q&G?Zmh;IRxxf2JR4@}sYOsL zY8!AmAK-oopKWXzJ|q^_Sayh8r463`DO^dL!TLf8jxNZi(;hZ z?&j|_1dutlq=vJX_o5{hSgA%tl=dUYQT6c831mQ=Y#VEH;N0U z-afN<+EZEZw(7JQ%@YU8@V%rR_m*uXKR)o?HPFR)#&Pxc)rH{hKDl1Hsb*PuM*{zn zbyK1L-yasz1PBWPe!IL zb%$=(iT_bnW=#8oY1U&0RS}v;-x@Om1K~sq+Y3LvbO}LK|ckqP^iH{MxCs%I*##lbREe(#_ssx zGY?DX_=V?wz(4SYEU@N{zNL%y{zUW%m}U5D3pi*CY~AM*JY{M6#y;`FnP|V0;ziZw zP$)TTSMp7!9x98ZR9(z8-W}-~9E&&q=^@}{S4*hGAdL@L9b}@P)16%U*ez>qnF-cn4r3D{FKfos;p% zUuE8J;d0&7i>Z4H0x2`zXLN?nf1+uWo=j(LLR1)kXN^WC8&(*90&5|j6Ir`hPCR3? zCi7>fr1?-i|>r`9v0+8u?(QmZqa*yG(gKJ0K|j#c}c$qV-~*}o35^|RvRa{Bu$oeCOjwxob1L<7~RZLo3oF^oLt$7J_&orGZ7XeNE}6H zA72Ba=jDKkiQ^eD6ZD&)9P%K{p)_MeL!WGuuMsT9U=AfgGNE856Imaaz36wY zmAS``R2vlyRlL}I>F1`SVyEC-1-yV%*}Ul$xn3sgF&tz(u`%RyqSF4$tGx18W!`zt z&KcbXTy=xfs(?}(z}Dy*w?m75S1neBiaW)VCQCU36y_7@&7K|~C=tUuctsAYv$`;k zFBU_-NoQ=ndIwL@^c<&r?Zh5@?$VnL`PUwlZ}^&5x&?lH>Fp6@tZlErx7HK@y z-5g?TGa57qkUjH9OlH5X_+4gqZplZ_4P?pvPZ-9m|Ccdm1k5750ZnoVG*-nTAU5q> zIjh3va*6Andzn=#xg+#N1$_}Rq22k|_=B`#@$K%4XOz5^qQy^_b+LYnM8Gjl>J>D* zc$-as#U_0PZcL4aB2@`LzIeCLSTdONzGX%vby~mxwRvOTunq~NfwytbN&*M?gRWpa zl)v_&ff!g@G%;E<_=P}Hg?buIHGzWVwa6(2`ns-=KpjklzZ9XDt%v#B%8^`~13cw4 zOTLs&MyUWNPBj)cd6GmH<*7t?!Xu7Au+XOxvp z16{{DP*>7|lQSf_^IiRWvD(9FhJ9u~z@JWB)wBc-nCj`DYr=cHo$(97OspPT$saPG z#vh-*_$E$A<0G^b>&zqdn}It_ke7qRH>S>KLb^QL5S34|hDAX=u>(U7^22?Pj7eh0 z#)ZrvdJn8seI4_pw^Kf6{?@Ra@!_aDU8}eA@&jiqsNRTHhlLc~K*u1Dtf{k5wSV0t zf|de)WpHh567lK!sy{>ww=^!GA#)UQ3I+#6g>E zGym)LFn=aJGUPgR8JF?p!bYcC#zr~=!fVY4@D8=uXXYvpd?(t|Qab zdeQ%sEPqk{rdNr0wM0RO5a7@7Xx6)iye*@;P$54keLD&=U87Gp?38RGSx-%nw*>iZ z%9YH6V$9Whexzz`cKu`~4jLA7O3!LOS`}rr$#6rbtraiW?nr5-J;}OqbH4B1z|9$F zxx0Gz#Uf!-xY@y6DJ~<}1xE#&{e;UfY4%gF4(2{GE*QH!88bzIVLuAGg zlu0+Y?SlG78SN`qNyGL}G5CCFC(@mXefF`KS<{_we=r6`SPQay*Al8P_jvB&?ujM~ ziO5^9O^Z;Ah^3oMfWr`n!DnSsQ|Ni%0LA{Gt+A)!Y-x%yqg@JF3= zz8;+b_Ef>vYZHh$G+LrqCg6E)`@+>rV&A=Tf7VcUkq@I)se1mTXtaU9lqq3eYn_T- zvuNZU<_#>4bGJnFtIodkdWbeqx)7{3c`ERa4-Z7{S`W41g1q>x;L@-zuFp=QQX&<1NC&anWCtF-6$Oo_r-U zyjtWZrMagss7BlQKkwZr*WHRyl7RT~|x!Oq148%0le^*l=#op>JBM)x)6CiXB%E6@QB=`Gv^#&)PEPz?Nuov$fd2 z|0wNc3x59PVl}J;yD9RD*ubhm}`D!;I+=+Am>oN98Z6-A|*Tz9DK zP{>)#%MK>F2?ALwIQG7J*q?X4QPs91zDEYB7+xGc2&N#sSyLRS`|V-Y1Q4TrU&VCq zd5kU_-q1r64?WMu@Vy?0h8*nfI}0d!;cA5s7gYz||4-crq}ZK1f9Ch;~>brNyn3BxR|o-^dJpfMt%_rin>$!o+a>=%Xk+L|}?=I3P0^d$Y+ zMXajbWX6#5e4Ew-xp|9R|K);NF}crRMUK?i!J^y0hkff4!TC?RDy8b1|Fz-&53Q7Q zKxkkW8vfEmsW|QClSTpf6_XufFy+h z05*|Vwel)3kV9TsPDl5mbrIGf{;soIf_?OwVf^xY2wk+OLGM^qr9t;0|HzOF6-H^= zBOt4~Vk5S8xHo%asZoMeix#K!eXd?+*P~I8O__dDnPBngn_v$hSF7(CNd4**&U39n zQ%$a9?H#+^;e3^fuy?C;J4~oxyz;tB@7Oi`aq06!wA?LxK-U9gY4n?F8YT@|iF$GW zbB|oxqQmp9t@O5K^15};E3{Zm_fX)jXX*0b?*oU02R`Q_wO{?Ix;Y%vw6A&gaa8hD z+Vww8p3Sx{veZf06D6XCwbQ=Z+rb@~h7Ohpe}I*)pZI*(tK&Z-t~0c>*HE_1hC;sk zFGH^7r1?{AvV(Yy%K@n5RSb}|oP7*(GWUR#sfz%uEAxMq0wPw9f0mJ5U_X4Cwr~SC zbo(Hn_TtL_w~GDha_t(8uuO7rUyT<9$>Po)Qav6uI-nHM>img0h~75*d!M~yo$v6A zjzXZj8#Y6X;Kve7p>9BQSodXBH+jHD@zirZq-SRrA`B&dRlBa3nR3L0&QT6U=0R4x z;YQc24|@<0bL3?ZJ3bVGOR?D#vN^=@-@rvnWtQ6Cto7@&T8Ga}I$=O7QIUwWFyB+> z(hD~qSkZY$9Z+5zaUN?OG@8@gPMcRAHaa&B*PYgMroB_1aO_Yspp;e8fC@GJ{5zzT zeNc5BM_gP=0QnJyumTRr^UU7gyZQX)F^gv!BF3~?LYbH91nAw+ZY}kyxhApSiUTF~ zagXZud84_7Jz%|&>w}$((}^meG%Khv3Tv&1eY|0iratC`iSd2Sn{2ffub}*(Z$Yve zgux~BAW1COK(>o=D{H8O7K4V1stJ+bZ=s_fSt0WuI>H7Xj1j%;#PuF>`~zU8*^To1 z`^OBY+gJDb-F})L7olr@V90F9aIWm3hD`2G976s8w?<|Au85pI-LSnY@)}Sc9<)WD zv(un?r77#$p})!Sq5g>$mA#1~m0^pf!*UNQSV=~ikC-nM+6Rbo4`ym6rqtWghJFrj zbkz&AovRIcr!r&?=M#@*p%`y{0x#;H;;N47maWu~hKvP2!5P%XJ3lq0`^^v;8$kOl zan`u!mHucWj9hQS<%vH*I(NV-xI3!oJMaUf-8Uz{h+b8}GbsqwOt%WrMZ4FD{>pVr zfA|J@6pNo~YwqPZL>5`~sZ2rSP23bHKtG@T1bqehL$#d!I3js^6jfO8$cdAT`c?&^57STMaiRNkg~nY&WRdFL#~;4KgFPQDJZE+PV5K3 z_Gmd=O6?o7mvMXyn{}>-oD&x~-kuC`WQA}ZJZ#PIj~JTv6v#c~=47NAbktzlL~gO$ zg1SOhmBMBqj{1oj{3ZJ|1L>*S~q=XM5^Mj-ENB1wpvo^y!(rx(h00RaMrU6@YC8*81Y1ZhL5-oqS8} z22;Yj`{V?ica?1^I>FE^a}YdcUhJheiw)QtTJ|dDS@Wx+)i|zz+*frGleG%E?HG7sK%=^PhbMbi@`8JN?m5lOqr> zyzm8L1P1YH+^>yLF>3EemsS7SDqqZwL8zLd(in?Q*{MKc}@;>nA zo-s9DCi%SBGiQ6N87#iTk(WCU*uDn;VTP64?6^@eW7U$QA7XHwIg07#6`a}BKFmrT#(8|B3#pK)@vvfglXnE1*YwXl1{AO-+CoH(Bzzcnr zo0J?BCn&P(7qlUOobx!(8x7gW-oiv!Xzg2=tHTEyhWb@N%eo#c)^ zmxU)UiTr2tg<~@(GRfe)yyD^klL&HYsYb?wu(Go41=}+!DykZ=q!U$^xJU`>SgbuK z967f;?2>ho<^3xQnd`l<=A%P5Zq#E9Qn7diRyiC7VjWxHX5LN6i@&m9z*X+YX$#F% zUEh@n%gRdE7O&EZ3P4D)>pe^Bs=pSURJ3ba=2PovJOY(0e`P>+ORl0!O1AZ#E_E~( z=S)R^JhoM&7Jm9pQEQ^Eh;0nnk966~@@mb6dS0I=VkXX|z>?Bv!1E0-vPE#z z-|NJ5$l<-kKzXCi1u!Un3NX_%@GFa7O}@k`$|&8Ya+TYbG$4EK?aHb!DaK?}boR1y z)M1fH=?E|HtVl>i>htI%_>*1+gxvU9#VdNX8qBfj-E!rsORB`&5~ zVdJ0lU%vjMpTYt4r{P?_9?&ialMk(|U9c(nbt`@Nsq?UXFg#0;CoulhL=2y_H|vCC;yTjC>bAt4S6g4MC{Ppq?de zt3QgIx(u6f&ePiJaqmb8ursboUXeJaXR$(|{5@wGW7IA;XTscA}ozci6J#!9M9?BMC` z=S?MMd8WFs(ylwDq=<_@Jjk4pNw48>%T#mSo=vT(yJAw4x`DN1GQnV_o0!^Bi$qFh zuxYi7XI{0*EEib!_4Pj}EI~FY&-k~&N!vA6zBXErwH_FKbM^$qRn>3PqBEBD+H30$ zFRKt5Wlw_dSr=S{m9Wxd%|Zk9p7vy0B#>036nz9qmLAl-E7FKF(;aBgK+(Y~EQ*n9 z)WsPA&vvFOxVUKSG?9Q zVPw|7-1Zb#7>1YTd76bsMO|)n?3d>g5yBmiOAYIgtY_zaj~;Np#X0;AUZ^|b>rO#V z)Va=^WQoj`4OU@zLays8A-EC3SN7CrjX| zw7p2aVW8H<+;h%BWsJ1TQ^!-um8Vyggh(pBpyS5Q8}OX^CPDO3?0ym*NkOgf&T~>v zs(>88PX1BmxJHT*OR=` z!jq!QrePcWl(8L@kNpVW6i43&8=NgIg_&$MgGlu1UqqL-KvQub606`u8i9po$IS!a z32Wf6Ug_dAMfDw{YJ1dwCPnOz05!a_fmWR~i&_96d5L3*dm$XhX`I8#SsmZ3com*) z!DdMb{PKsLtUgQzBEBRrj!!(JgcoH~Zt3s@J$wD`O)ABq_??g#P&4jyhboX>TjzCt zO1y>vqS7G9sa2IE=yqqN1uQ$sYpAp0+~Jqk5(Y#{Fg?vpLo25f+SGmD+LyYf0jGvW zQ~p(|Pc*kE2Q8$oau=w8UifDEhHVV1@xZTfu+)z6BilTkjfyy;?rR5)PySKbm6{}X zjKCL|EN$d^x^`LvTgVIdMGGbv0I+n_<$JPh2RN`o!M{{0GLG~nJBwbQ--;;OSqG_e zdz(iU&eGij2s*kjj>6`eO&=u-BwoFQ?J2j$bkto1PFf3NXvV$a=-+AA9EW--s<|0yFQK^Wn$oO7(C9(^D0P2 z25%gBewsi2XxGBe-5x{vDWzs_n?ecMhhw>^_=VUET?Ro`i6~5;+`54CFa(zGf}c;MS_sN0Fi5PH#zKQ(rt_e zS(D6L^Bt>5K|d~O*D1?f=kuu)NkH_ZnJhzvjp;g=C z2ifNNdw2;d0IXzjXfXRZeoU+XYCp`ps-??3Rrxzu>`!ZjF<9`woI z!2ijWMdR6BE3*x=fDiEzST|mfq`2D6pa7xB$a~iynlP39YT8Y;S(haFH@LQHcw;dZ zLtZgY*4XS5JpGdYAlN->-h|=`{j$vuXU}hMx&VwIrl^n}X$s)luOZd^bu415M_|<_ z#s&Bf*dD?L3+Ngh##6<|;)94jpIqZc$`PfT=Bk_c&g&<0=h_zivL>bLn!(E7_vD!Y zX59hhX^w6&b2&kPCUi*=G^fxjl5J?2Tnu^_v-heN%Oz~CZM946rqQ+BR;-}USLNNf zWTiaQdv#B-__pRXgsW#g)F}3mtr|4M1RY$fhn3EDUIPR_2(dA;mu1x5!ktHt4ldJ} za?pD4O(-|Ao_J&5 zm=PD!kdH`T<7oaSmV2pYxYMn$^#b`gwJx6!6l5J4^m-w4}7VB_d3PgEeO#J|C$ zO3l6+3=vOIFB$bRVIjlSuw%?Ecu=y&-inLCPqSo+x zsy>`_|ILHRm}0q^zTH|4kQ*UX$N7g6&ZxrnlC@GTse1C!2Ff9p|0G1D&5SC} z+CGW=56`hvc~jSC67x!$>8StQhp8~Cvm+yjreELeuz-qm?cas8?jr}|7-KG^HBO+# zMRylp=Z&WxXijE@D*Fe&+&>G^-4reUZVmcjyz!Q5F#2e`R?aomv0jja-unBHx8m;l-e6s|s~PxONw3>UfC}k-nOk!d3T@S{I;BwMo#^#S&Mr&j#eYoQgtBQE za|OPW!^>T~7dYTFl!d$7fj(_L_Dy%t^lq5+D^)w{WYW?Ozb}GpvFsl`u%Rr%Vkojo zt(sn~p+2(gH{*F&vKA`(aQyDQyQyiMYrq7YtJ<-_$V+f7-7IO}pHDfO*9a{~%fJ=8 zoe5Jn_h(tMtAU_*_S?l$E18bkoQHM+rb7ztxCXL9U!5RBI+uc^RAXT&YHx<_L_*F8 zh%Wuzqmmh;>wgq+%R!rry5nfU?c`RWn#8o~!EBUTdkT&~Ze2TKM{wrkCLH71flnGm<)XfJH}08I z2Stz&LXStN3GazA86Qi!WnNoiHlp}jWx9g{FHy6)PF@%{8s2Wdw+FuPDnw0agfqPx zIN@!q+Z}^_V{n*%`MUYRUp*f2vKje-gwa^Q=yI1NWH;F5g({r%Yd`q%I;=9i*h;Nde z$W(@Gg6$g5d-+~;5OM4qkPVfMen-3qosg^T&9|38nl}!1AJae0Q86r<# zZE=NbJH|BU=!3i*;1vqBjIYiZcxnmX9h3{M@gMVG*)DB72x z{+wT>7Q@sf;AK~+7xZF3i^Zk8jWx*4S91{TaVcwF1o;2j?_Mk136?JUG~|Lb{ey!qgJ5plNs)ffyxov&RG%~NkxyL zh%Hs3uF~^lSNj7Wf<52<-dJ%pw%pKuqzs}{)%b^q3R{qNUHm2A+J#!<_ z04p=o31GYa8&GAu!k;=IxAXw%xwpZ<9%0Mip1O5!2Z;H&OIK?@0-o^Lhtq=G>i~Q^ zYV0fTO<>m6115_FC?=Iry{6&L2_r@Z>O~`&@iT#4Oxx9VQ7!d^K+4+4wyI;4y^DfK zAzRh)$ae3FBFX?CvD|q_?FOZeNj}w0L&YjTq^**zw7+BuOs~`?VEj$X zG6o!}2eA{(IWAZ{s-5q+6+2C|faUFYI*QWHTEwh_me}~W-eOg|N=XGjLMuQwbRf(w_-A05BB>2;_~m9-HP*6P~jd-(O~FbXHu zh6bgbZjczSbWkMT)udL&0>E37ZteQ$4J0r;`kuTRW2lprpQAJNb?A2RO%p__7|%x- ztyA?5)5(|Yjds=9a4$DGaqHLIuvX*IoFZ+Lhg<@}%Bf|SR5Mtu`T9K5+OrCf&W8}2 zKz*V)!M)Pu6bo_qz^soP`CQX7Ogdwd&Zv!KI0#As=J8io@NQ)y_J=BeIY>8O{lDFR zH1yEzU&39dr2k7W;x5po;Qc8v#nSKc)Ytty>yuTljI?u)gMUJP!q$Q7CEZXvgYL%r zVNz5t>6Y_J^<8F);V={kG27Y?xL<3Da2kT&+Mi#3+5hB_g zH$6BLnI(B3Wz0XP4{j}*hCoye)grT~QS34?Hfi>izbUV%$xS%K?`#3qT}P1HgVmCT-Mlvp#U`M@O8oN-C-JRK<*`Z zaPL*iYn?&Sx8N8NKXt(>VQ?qM&I)sn6y_LTjLyIm+lM1$w+{vjyrMUU%z;i;!mi8w z9lDdsiKz~Py51XgF&sHnjl%5OS)j36m3zvD5zLTqch4E%vkml?`fULC z&cP3Z-aR<2k>?F28e!>I0fjXjOsF*hMWhZr!56ANjJrDOj_~b9CV93fk&iQr1T(OtPz&+E2dqM@=wjv zU`gZ&3NS#8Rn7id*IuZEI*Yy$HFmXrqyXhxq1&}wFccE`x?t?iTw;tI6_nEC`x<(y zb(1j-VfLP4qtt{R!(h!CaR;eMCkm8Z9+g@GQq+&d1xnOSoK3-mk*F~nvZyf~Q}E-X z2Uc7ua)g~sY;hDzi<|=E=DlkQr29T|7-PNhZZ){2%OADB6#^2iGDX2KOZ&e2NXYPC zM{q|+YjBt0|9qgw;clqIxSWE+S}5^%i!R-iwm99bnkGj=pOW8^yTdV}nL!3!ktg<2 z0sD8lZ9A+Vvq=zNfBr z)V2n=hL0GHU-F-8iHVFhpLOb^c$JvPC}6yW5H#tFt3FX`|7F?&J3qYQo@aCCMRfU} zPy&8T0YodY^j8U8@p4NERgn8?B~at4sh&f;obXH=*PxfIbz{PtFG?TQK$lS&gQQxCF2{yCVCaI6prouKG=ir0vhC!XbDnaHobVcT>48_T>b9a%F%IAB5ZKlpaIa^N zDnuX%qc+p7lwY`_B`E#(2;IaeG z%Ol0y6)@!e&4Ux>-l(av_4izkuZzGu=0dr?tj6sZF!`N*G~f{ zXC#k5>YizIe`(PfYdz1LVn)0@bKslX%aI^p5v(-Nm56-x>eaDyZ2(TM^Tg2~nrned zH3)#!3(mn=kd)J$G*_fS<{Yu_nHD}?x{X-Btaf?kS*R0oQhNUnKdOSK4OzHr}v z@Jz}3&w5eOAXIyf4C7?fC)xt@e4kl0Z`23)tPTGx)Xd`tvT+?wUeqgn#afZ4q^Xtk z9DitvQetKUCUFH&gc=^_8~gVlOnc=iz=<_8hJ^s%fKEUa_H zP7Sl9X@&Ze&pj6iQ&Tt0@+O_`Oh>z{1VxlhDo%+Vrtcv!r|;2`r&g3^G|qhs`b7Fv zsV6ShTTrzm@Z~o=?}fIOG9EbRDbA*uO`6rwdbY|gxD_^u^+a%#j%c)X>m@2U>=nVq za)wnY6{QAUmMEj<)K<+hz`Fu`O?^?iyZ!a9;|-(Nr6B)u1s|g7!`O?i{AR3eKqMvLLRsIuJ*iNiRITO5U|G2eBp>QzkQl2 z-F{(!kAy^~4{DJpGqT1kyMhCatnzFB5*&Ro*}6ngB*y4b%rrhTK99Wf(NlFztk2C6PC z?;M<|Sq17(6%>@cEohQ75AF=o2>S4(Qy)Tk^76GXD6twv#mlC z0xj39=hyaI7D9EY#;l8B!K|`7$^K*4raz;~Pcq7;xcBrj4A?fIcM|&dS&Tpu#NpTs(#fdbFmnU_ExP`-=r^d?%+)O8xj!M)_$zz{RJaEg-e`m5h z;o$jb_#nRqrGddvl&Z=J1k%@X6NkBd7?RW3J6+`-PJBB}!=sw8Dwz5yn^)$tQ|eV` zYJA}YxPi_sPBuoXf=qYe|wD!+lZ68qQ?d{hrOC`G_4N|E)>eK7aH2ZE7YWxd?p*A)+Gp z37{t>9(<_JC*A`?&|stNsnd-`H;U!0lNU4EwZ)p{n-0v|y4?aLt%^g#|CKIn*im8q z=Nkf0Aq#)IPZecwzyJk)`7Q4v1BIu8q$++6Pa$>cNsp~$G6HDiD!kXYABa2yP|<18 zSuX*6Ug_t5#easMjrN^cRa(OR3@t_>yO;RzR9C|#Kuo6Vt+JgpiM!HMb08uw@{Dt( zm4dKWBs{OJ5#1xS9$%c4q=mU*2HZ4((SR<+qal+V8|fht&Ji^K#$zH&%fb|k`K7$s z2njv-I%97b#K!ZV*E(qa5@(ws0jxJ}mLwA*Gp7l#w)$>xzuwxmg302OuYj$AGgd(w ziPeZY^Yy-iccz03bMiiVFfy#y>-ZRbC-B?W>khfn&yF=MmBfg{}@wJsZ6X%Umow{^GGUye1f!jIp0{e8EZt1C(`2BC5yTi?)^WgO|#4ESr z_KpO1aBN!4-Ov38?*VDhlW8oqi!(RiyA4TKvMeyDqnrLW`o0V3X%3IhU?rhAoAT*- zm{GP6bsg{&qC7I@c?vkiJ-n?7j#BR(r>RU>kwcTtp@`t14zOe;+`9aa%5$po}z)F_P}(9}{%2^x25udth(9x;_+7k3`I^B_M!Wg8iOw3y)zSq%F7^ zS2|Od8CTQ^BY?|tmFo;Jxw`899gx3uUhJB=afsMMi`~C@2;re6cS@#nV?DI8Oem$x zFd=D>0UWaej>21DC7)c#(GZ#UTgc5f`o!O7Sy?LgM-(tA0~#yX(-R6#XN872JA+)) zF&tTX&_HIr*^`$>J?m2Rf32Jq#wYj8^xGgU`yz#ZuBn+J^s(<|0I6%kL?Fu4_{`n6 zApQJ1y#-g(0Y}oJ+2rZaz|!wUC6JmGA>(`QVlxYZg$r45em^8uLIP5BHo9RR+U>E0 zlokWj7|^7*YNzwpYS|Vu9$Ij*=b8ory@1Y7OBq6`qUQ7Mkgix`8L+6Wexvt!nIZkf zCU{wAD-{W6sgWK-Oe}doL!)+hDd0qq>B4Oky;YPSngCqmQx=Ex9Rh~3ycS>sc12zv zQoiS3Sj{CutTJeF&wi_z$?t_1)h=!Lz3HL4$Yay}PhV}1t3#CG@Z#J%uAS@|u7>oI z0oQw8&xcEA|H0j!sVVWatoR6bp{nGS$BvPA0WVmN>+2=#c6||$SlMrqKmH;=;vV;y zL6Tb2aG%N^@5*iwq?pAT1p;#P8XAD(&XMZpk5PDz@Jxqlu`62{B(;5O`WKg8!uB(B ztkrF;L>bnEB_7x}z}j6%GZAwU9?weV1tsr3M|qd7Z15`_+C;dC_jn zOBQZaMMG3Km6@+B*CecebqV$#cix;UBfuC?I~WZN4x zzARU|)^--(v0(-bzt4g9Gmhbs4}01*&O-~7EQz-Jb@XQxpDCM@&;hn=O5MUVCIHn| zcdg*mLiI&bm8n>5S zXME|gvGvF_ygHtxgVljHB?-q=>+5z@r^B1XaX3(MwL2q-o*>$umdE>feCRpou_?_P zRY#M|^fW)|36WgcU7iK*%5tAaDOo3$zHh3JGV5&h{HYanr%Ml(XO_hR0bU#$goU5z zDhq3YH65ogj6gVXfPw7!Cgl{xW^)qBk%zIo@_2u*a3;^O7efRxbX}&^GSwwZ9z1{R zjeJ>6`E@$xj0R*UT;eFypzf9xAv(F=Jy&4w{9HZ@{}XqvM@lt0C5}Sr^x%lj9nO+_ zD40}8CDy+tNFDIv8wZZKoGV=t7JBrYEo6d1SUx`qoMiSyEKH;Gsd7wGLHQ7J!NAkD z+c6svx%-w>F&grX5Lc~9GF^J5OegQj za&jM`IoOzUOh;Q?>7|b6)|(1<@b((>N2ECR0vFj?|p#V zc-F}_luFxDImr;p;l#rgRrWAKt3OrwL}3XfMwc9uo>pAtiu&A_MW^oZ2Wk{TpEILR zKu(;kPqgUwkZu!iByaZ>i9Q|VmL9?hOP#tc(~5xiHN~Z)m&6COY+0^%MUKYN&r2TP z{Cb6~lzgSYNG)XLpSLLdRzXR1wFb=evB;Uk2tSOnBXtJ8^@7-+`<%NKHPG!73KMOE z8v;9L_>UmeVTd9#C@jgi0|%K^uEptz*P4sf3CCo7;cPDbp@-3+X8jS_h3;@8{}QynVOej_74lt+ z7HCh?Hj*pYP*b@xllZ#_9+JObCP~Kt))l*#sF=Q5kgEvL?aKOuBV5DTD=3hZC&g(A zp@Lw^(+Qx2e+8W>E_-FHUpF$}=OQ7#A-(!`!X>ncd&u1lL`PqJ!?GpeaYxZy@J_V^ zt^jV&<9)180@F8MA-t-86#;?iU>>8%B=}neoo+xvhALOuf)Oo!heaH!jQG<5n`he{ zU4uS53K;Rl9rm2N8r(B+G2n4S#Vo2Gt3G!PYN`*Ps%}l83QoLc)PVTelW!qTE1-Sw zd9d<+6B*rOjDdmDh;L|9)z-NVn3X4_Kn(v2g8#=(625aKiY{^qVAM%$q33q|2} zWJ`2DMdq`6aSvd9u>bt+9qbYle?@pl9qmY{!LCOai3 zJ?_h4*#D}O2zt7&BgiYss;1EDM6hc|4C3W4<8CycemxAgC;7d?M|O12-})mdmgDyT zrI|!>YU|9gT^Fy@(+3MpRbfEJj{Ngnm8)I~Rp=^r=92|kvr`aU=_m=G!_ug?#~$lM_t}n^t>!}q73{jLU;+lRO&f4nQzHcX(wGU$wI}w%$rnfnz)LgS=L~;EoFQ8exz5`3oGU4zGX=wGcgU(*`HBO{RCA zqnfZRwahgm`T^_x|0b7FijT7)vFd^8ppe;^-#KWsifarI-XZwB{jPoQmY)zTvJhkZ z#`k+Gq@k#d|X6T6xGpn2KNTBbueRoTaj_umNzAGm+7Zw3vyEqv^{b{&xakbd_? zD%cWYfjqGO{!xzObrEIZ0M9j5z76W`PpMD#hW_Hq6QBuiDdiC!ptmo9Fvd~3qI_E$ zvvJow#s8WKNJ&)=7pI^@6jyhnNBD7O>Frs`#gqte&$_!{^;^TvLW`_WQ3x$~SGUIb zB1w$qNEcV8$MnDT3qG4c?m9=oC12$E8bXSCQ!K0vw93N1vqJQ6=UwRZ4fO0Go&rMN zKUW-vN|7m;!p6ls-i&a1Hc3q1gV3GXldQARmf5|k?mAHpF=woB;J=}_jwP|}OQr^A zp5It~=`IcN0Ci#RbZ}Q^b&sd6&-S5uQ+OHcVYT4bO5A1uV5|J&ZL&KDj);+C;p*`z6r2j<9`&nE@i?|^n-_#BYQ;yc~tC+KFn2H z>j-caN2~R!?+>FGh(C+Q9BQcz7KaDyr47BwuoZ|<5$v~i#Y$-xNjueVNBCwvPB%Cr z^;TtMIK2X13O%%*y1ATHM)Hb{&8C78*Ea0$BW>SL%-_SoQU&m@QH&QwH!R^;(766) zZn2JBO{tnGILT_B+#N3**cI_nvklw4nt`zUY_6eLEmZ_5@GrcH*WWbpS41((3ELiL z8y)MnQzfy_V?GDe`V;$fS)?5zlwnK#>K($75qm!$(D3e|Re+x5+Ety8iWgf(h-xvu zKsS?oSBa&@bgMmR=mJp%@5|1ZuOw!Gf%%23L>G_ejaT9cNhvQTm3xd$$2vCI4yJYAwTHvsu+rvkhW8 zTd&#rMMw8O? zGH+1!fZw;|;x)EyT@bPJ?qI!p$h55J&l=)whhdxN%I~#Ta>`K$)ZHTfJUK(pY-aSA z58zt9cG`VB+-mB=U*(JxW(FOy-RpBubJ4T03Pjg^MS_)(0bEWED*Ib7bN9a5$jEwI z_@jrf@{{*=&6(dD+bGR0YOep;Yv^>uA8OoUm#L$OYWov@GuU#OveKETz)v9j4LH=) z;{HMZ=9tg!xPj$?3uV;F?-K(Pckfd)xIJGh*v=0eRgtb`g-!pqmQ1uf-v_@%5%#6? zZw!7!=kHboH~}gt_BIyE25bIgVp05JfR!}JE(SBn^OoA>66%~>@9ggmTdC0#J}OtJ zMKxpIlEF@I-YT3|f|a)9Sm}FcPw3Sn4g6rUk5CJ*C4A&H*rQn!ZJmS#8=nlU+Fygr z^I@Jq{>mRrr%n-2?;^E=nc#HeMv0!;rEu_5SWZO`eMqY5kUO&AdmO_1ZPyc6(MunV zCucIWeA6LNEvfFGkVC2r;#D;a4&&cj`w*`{ zSl@$U1#cU1)AuDHIBti$y;021Fgu{AhTkU+I5eV*r>oDr2@%m}D8h;1y7;>igSr}pLWn>{GtOOn$x;7r*^3qyoJ5P! zZ|J?{oj)zY`|#%hOmhp1zInhrfaF$xoRzDvEo(=64UO0L!9A-!O}$XX!UC}Cxs|@Y z{pN9t<}8jiRV;XCAR8nRA(yDc+e&g{u0s0D0p>t>b9$PR^+Bm#=}zy09iTUi?1wqu z4T14MZ_z2QdMuYNqEi%u-5$+DI&iejW#fE}%tA}Y{AZ!}{mxTXJ z^Jat-N6fyScpUAP18cHAe>KfieSGd-MZ6wu1~`?{j<EJNb~ja`m>q~9RR(-cX8l?Pzoes-_Q^R9*xQC(WfVV3xz!& z-1A*|Q2u+cfQ=`0PY+Wx2R;G@Mgaqgnm=>y0S20#UjloNL~NV_S60zX2~&pbSwH|i zCI#nrn{dw(8I=G_arj=^dZxhsbL#mQ|0=pXM=*@PdG1H+oNSW()o$Ltxt%$@FwX`Q zo%f^U(1H+KWS5ngip)o(e^P?yamBpFvx~VJv2}+gh3^KvY!vg#-8aKejn2#dvZK5pb#9r}lYe$$ zti^5~4`$(^y6Q`cmv|V({;|_=j%?=-5sN1B?xR|N3BN6jsQ}H77+zee`vI^S^My6P z@Ga#r4lUjM`agixg3c1(10-5ND0BxUdWiloQo;J!fuO+u9T$YKoSqy^#mVf_N#KR% z#4Mjwq(fH4*$7xD(H9O@9qcK7GJp9Q&(B}qmY1-nq=!Sr=__OZ-ARXRLW;*~+P{x;D6DFh|Qo07}NsB&ozyuOcN2h~K_bxe}$(afG z(1mazG8YQ~nqqC4kO+H00o-5qAWO*I*cAYj*wWv6Z#KtJvL8(G$vXJe+i}t|UxWaA z=GP-iff5B_)NVl0`(*}e9jCStb;*5J0JMAdC}Y?Muzf@53}AlyAq8I-UP9(<=RJRC z#0+qkJLS$`L)9SHvP$%bECjwC;{G~j?mPHI!rwx`z8PKiDlZ7Tr}KzVTsbMR*c_yE zvi=*^DR!-LPJa9Bwsn`#v0|J8bAFFcYn0SEl=?-7ST zIcnOR5~G(w-I2*!K;3)^11t9w1k;zm8AmEly~%-f)Agv!yrEoP3|abs$y54jWO2V}?P zlRkPZItH$Edhvc1;7{(gvs5Mo;S{8Ju6dT-0BbL~J`_#$t~sx$;92TQ`rw6C8O@5n z7+{;1WB?yX4yb4-(9}KHh(C(|cE7}GSyYg@V7MMhbP|c&8GX4I#KE%?=h?fP9pFFL z7x;C53yv=En4Zxqp+IB6r{9`=L0frFU0M33!T}_QU7WLE1OZa#Uzg=y^HSp+nM{o}Gf8bXau$VhL0kT^$L+9fdP?PSgu`k#b$P>&404UlF&w zHOEl^prW@w!9S#&%lx5_M_zl_%d&SE$&_{RyqdhzdRl?)tBfZq{{#=qnpk~3q$zwG z{Bw*dFvz?-+LV4;{@)2J-Z%L_%Bt+|4Rc6s09Z(0O`ogDf3E_(4hSoJ#8NO7?SCT( zPW|wVbwq=5ui7O7@-$ls``r?&$`tl}V!?-rqbcg7^l3m#yaE_I0KON6WCckCfCJXD zKsX{dizpTY=^G>;e)zq-R;L521Pf)OUp5P%wPD3W2c+)qFOts)@|rB)mEQ8)={5Ri zz_Am&+EOHcsf*|LV%q9;xL@mcE}L{{dSzbtUwoVFemm!aaJ#NGww>^=z_s>5F~1d* zYzDIE8LNI_1oGL!#Bi`S&+(=;*OULe zo);3dYyR!@Ao9ojv!xOxnvY37Z@@%})w@gc$8oczMo=RNQ*`=t38txuU=AkhwX_iI z$yM$xEiIsm(tqrOq3d`wkzD5M>S2bqdqVYVn*GQXUG68mN6+2G zwuIC5Or&Uc(G_zf<&`$`EM@jS^NBUGl0pR*y+3DPw>O_1+bB}%NXf6SLh;C|!t++q zS09p;@&(w?!aMoTlrEQ+Jrd;SBlaIkOhSu9nm83oZ0t4yZu8q3djj_)LKSgyr<=|jCP$gj=M}u@7kJ@G-QDi}&fLE-q(Nn8$WgQ2nXQrTejP7uW%Ja9N1!Ow zbZ&6Y4nPXiRCon*84;UHuT>(Kn#a2Iy6Ov!b}73}FlIScc8yW_W_LgIx!)qIjR+MC zAZ+EY?xvRRro20_$DkeI%8;G|9X6sU<+gch@D9v1PuFvxzqO&0>Ko`k%ln~u8*1lI zQ*rr&y9XgEZ}_!zOWj&SA=R6(2nOc?YyYWMD^EW?6b$zo@@#(Xg$E44f7F)u*PnEm_jglM ztC9Qr`?~_J#!s(!P_^?cp;L4<#0Lu3wJVmYlC-(MlMBWC;YF5Q-w)>vK&CY|{{Cit z1jQRvT|Ci%gxub@!E@=GK6rJmQ)IbA^uN+8Bv*SvqObBqfjni!batD2wdpA~YW;V~ z_^H{Q0rfy8k8^f+V&r}J%Bqgn+ZuWgl99eJ+LVi!f~IG9{HFQ+(3 zEC^Vt2N=P)ii+LoO;ocMg8z#QU5(vl2An5iyP8h2{SR3^!!*ce7Z$(h=tcqqVqDA4$i&brse0e>J++o^KjzpQ4@1XpuIYo7~^R#K_Ck4%1Y0;V@z zYx*R0mpIi4%C6oXuli(px+03f5S3#$m#Gp#}rpnO)0+>P`?d+iH?P0f^Jizis-lv@wF5wEVp_K{~!(0ld<(c;`%pOVu* zvMg|4PUHa2CbZy4H1N(MB@Hw)UsfQ~8ky*VW*CCdcCmB2L~Tc`Ibc$r7JvQ=?TjAY z{HQ=zvOVeLls85OH3arn9elVMD`0Zgq-%PDE$Sd>kN0YVIWA}y(}M1fD2k!7Uv~%S{kn!zt_d#K-2?5Gu1%a!=&scS0pg?5 zDg$ck-kvzC%*w3N6oMZH$RAvPiWFShjJK5aB+f4X&2V2HU;uWKOnFYM{Yb0pvOsLY z$i!?R=z^+Nm}2=*tc=oQXEmD4l+x@IW_4~aYdKWc^z1AnlHDL0glwX0BARq zIkeJyaAMsln_;Z)GqV8L6yuxp-cJ6jxvqN?aDYDm(|MmMH3|VmVJPRq_`P*`cE)ST zS8CC^od8nxw2u_s;|#!Xl>P~h#^h!8y5zZRQNrv9_B-$XpsB8Fyj4`EJUQFu7%#}q zz!m!iDgBLE8t#6$0t~HDru|6=ehG9|4YB!=$>LfRcHX!PP&4c;XkFCB-ix z`k&ORBTMA5Peagz3#-u28&CH~fxv1-saN3d8n5g8$By`g=ogHZqO@^oGHuzvs#Z&s z8@c|#Ih0Gqh^FAYrl?47QES7#m8xRzt}XP`JY78ewXRjAAv+P?**Uu(2PJFjWKfoi z{GUJ@P3qPuNz;S&c$$sRagE)0E%j&73R!TG;wHR;)avKRtyhqS6I!%5%QeBhc-Pqpfrt)Rgyc7^>`F zH|?^r>%vQfacqt|sbcyF0<=qV=lApKpr}2_gwhLidl~<-SkMZ(Tsp(Pz8(5H4?cUn zPp)WYdSIn57OeiWJWgkaXuTDC`AN?@N3}LqS&?7Rkh_ys(B_Sm?~I70Dk$>#EPf-D8V#DZ8p5;GmG4I#F`KEVzgU`K%)|EU!GdL-3!1WHOzKLiSPzrC={ z&kWkl)1)f=1wqNUeWtO$dJalFbTW)PA3uK6FtT4}I?^vG_xRw^WlT|W8C;!0bst+nfFbwQY+Y| zmU3HPGc(D=!}=QCd(n}&DU(TLQ%N1kn~3KITn00g`3<-AQ|DEe4+*-9dpohmASauq zy@xzpU6NUR4+XM8w~I+cS(8qc#?n)5 zu8kNGiG0Q7Xj|^t-j6F|gO6H&r+(-TV29$p_A9pDyfP@_HvpZaaN?xrhnG4~Y3DHl zck;%fsGRd9`48s{Tp6R7b^^yrbyUf}Ro8O-tcsfpGacxzkrW0AKVj`QU3xuDIR`8Z zha3tOEqEb1mBVi1h_a)Xq(-A{)wZ$S;36~>JEY~Af(Tf9$Ena z0F9cfVMZ1F zti(pwE2kZN=mEfJo`ps_$G28@;qKJ=jXg)BHM zs;!9{8|yjbIYcv6Xm6dPgL9SjKSaI^r7fe5LKv5x9m*U3cI%|59WRYM--s%z;^5j) zahz)%_B7{ZzU&zzbk~mVO1dMQu9Klh<7VlET$a2ctay`9T$y*=OyBCdx5nm0$?E8Q(re2Y4Rd(__T_Tv5i-H-`|H#$Ca?>*CDigv8Y3i9Vm3t3IA}Nlq zx;hScNAz{?=h$Y)P&fgo2zsvaz#GMCxsWKus==?c-B8s3FBS(ev9AtrDczBX?4}dw z`T*34y)JxDT@{A>7Mdcvq4ZV8Dpms6^{rgv;Pmp*&p%ZSet#fUZyGoNj=}++>UR-n zH!hi##LCYg3rORZy<@nASDMi6r!&nXHcsm(}@8&+mD?B5%!PlZ!M4B!P+B!wR8n8w4UWpG-RrjgW zjd?{uskaLZ2;YJY4_;r#1a##O00dwwm;)+<#|EFtyzO&Qwm`YXP6B<$gJ`+)bmB?) zG!FGLsaw~7z{vcF$|vCu(M2zUOPOqaHF&GjR^jXZynloH%rZ-xdGlQz&$I7cC zk%wTA+>P2rVlm)oSoU)ofcMU-`Q%f`#D=H@_-KKp*2BMEnt9vY8Qoi>S<< z4iIkVfF^%!^LtaCsa80c14x#BtREm;zMyDzEMHc5DL~?&6xB2dixxap5u6HF?~A7Yt=YRGU2CEqEYt>-M|M zgHq&|_oCd^OM%quUA#p_{OESTfSEBEc=t5?4hc*E8}oox3At`n6ek$mC1~gkNaqT8 zeaq;S=Y=#+KJ$)O+*N@9(9i{xm5Z}=qMhw)JVE51EegavpPl6~etWCY{(*bzpc2Tv zC0luBAajPH(E<7kC=>MtwoZFa6c404G>ga6bPpK3c?cUBjm9m(h*a)cCUu6L zVdq%OIq9i}9|e^D>a~Sfgw+Yn)OWjnY2-%6NH=wgVApnMSbhY*=mQLF+U4v@D&rnK zwx(06XFukzK}JBj690I7HSVMw6XtnnH2S0V4G%*#Ry$ZwMNN2oS%b5tQAdqx2_Y+8bU;oxXrepF8@J)EP?!0cfCrZD8mNGr#NLAywUX z=@a-{D}Ytp1~a3z9eZi`g>rrt43z}6#~hw;q$oHX$ixd2G9wkr1TJJ^3qU78+PPj2 zh7}1M>oBw5bmoU$WMma$u5bhykw$nc{Lg1Yt0m@!5^V_Tr&N<0o&TnnmFh4@ZUepL z`@K#8$71?cC1A+RLB&r)=zJ5;wVRhyGzKYk`_l;e60m07`3vy-=O}y>9iTccIVl;# zKmq{wm7#aWCL|`3NQZL)6R}Y&wUEb6i_z?~>F5N+<>*gbw#k{;u|#%G1jwD+^E9YP z`TkG#YK+ECE^CyNDe?@yjww0QgN~yV{Y=ZdQS+$Lv8GP1xuFHp=bH?HD?MmMbXY1J z9b8S99!6>*)s;w;>-jhZsZygQ@5b@6bFF>Nmt5kZQi6Ci^Ojsh1o10$B zUG2o#bE|tAa{|JgmW*Z>T3ZWLf?}P_?VOMW;!yTJeUl&zlnV;AqqmS^d7%j!g%kbgM?0qhbXTwVh~%)OBZ)nEHgFJ z3^_J>6sR#4D{ij~W4JLtTubC8PqVNQ^%I2X*w9>|w5mCjl-(M8PW6?_U!qu_C`K^n z>~Ffu%TLPmX|4hL5Rp2C2}>F)tLe4%tN2&MsL}<1jj=Q7h2>o+8wB*PvhPYdsI(xZg}~<;-Uk=~InpF~DI%{eT+c7m zlS`2BUIiQDHiUk@QkYf$9(l-QA6;`p&tDeEhi6os;FtK5W&TE~x9F#A{Rt?%J2G${ z=o7KeBb^%I7l8%ZYQlZWt@IU!BBEP>B`ij(&X&`M!*o>fwJJBxlg?kiv$0~ZzJzi* zJKpx8euD0u(m#~lb6NogtrA=ZkiBoH^DbArgLcQXGz=s$E28)0j2X`+1Gn$HU0R-M z9}2RAS#0C`mjp|I#GX7qUl;jy#`HKcB_A<13K|u|vMq|)%)gv7jbO0?h#7ZhhQcq=q_?!)`udQ&hy4JMU zXfk0kh%^bIzWW`tC)Z^9ZaKmo4oWI;8x z=G9M0GTinJI6!Q;Eph*=lL`NqVP3|~9wC0y5azX5#3jFU15Xg!fMqwXU*qMo?D~Ds z*!+MIR<I| zqa_ZR-aZGPBZSQDwE%LKa&AEmulK`zd8slt5;JZ~?56>C2}K!ks6HH`q4%MiUVR_D zKs&GZek2V482;(_eQdKgrerS&z!%oA5*N zKw#MpQnW--mTHfOIJ~P@q7@89#7uXi`U3LZb6Gld4qqP|Ze=tx7pn{S+1|#2+k`zaEO1xN(N;EWuixk26rD`auM=d&m;j21w~HO z0$QAj)A>)tB%qzp$qV+saQC=pWK{XF)6tL)e<8nPlZO5A^sH|=Mo)WptJID=H?vjz zHy_AjuU?_fq2K*JqDIMJsGZ2g+%PriB_bY($JLeHL z7)wOC=|lk4J?9mkreR0+hAd4245kE`1GXnBzQi<)>_iAW=lfK&@r=ZYaRMK==jRIzUz1RZF1ih2IK*ExUF{g`pn@V{2`f-BCDdDEAn2uL57*fz)1>u z?f^$m4kB-z4Zgej5I`$&W#jzUj#pcpC{26r5}x+_du~x(r~^)N1_!L*C2%x2(`Z!f zpRtt1Q9e!39cl+Xps0>%VZNr2+t!1>s5K^Jao5?!LW}h8GTG8PD`Qvr1XrneyUN2^ z7R2o@r{np;Ha!K;9A$`ggkP!75^IRtFnTe0mkm$UP2XI`a4>Lpf%q-Sxs9O8xLb8b z$$l$)G>n&OU^G(MZI`Xn;?CBC*PrW002P)v<^AgB8}pVAlmhuqOE?RA{5;)35n~Dr zLX0r&xO)%z$pwuswgVcTb#tdf)@e(8fod`kQUSkFe_e~&%g#NU_#Nz&y)CIT)ySX9 z77YEo^gzFTYZhMeqUBVFCWdykQ$m`zS%k3E>qdSPZ0JK|ob3cMQ$ ze&0)G3o*FXC$4D_ouapsZ(DF86&o+eM$D#V;C-`zA`a4_=9dk`u9IY@Xp!!d{7B!i zZh_Ftk3M4XLyszfJGb32xm=ic#alTf(fUBqUr_z|?lBP(I79$++VYC3;)Xe|(T2pL z(_eFp?My_F*LUt<9y(T85^FV6qZ8YR) zk)si3+NL5+v2o--as9Ra-5Rdx;nG5T!13g%DiraxBL(F;WD`U z7WT)2EOUq=w0}2$U7!O_M#wm#Q}2{Xz}LAyUC5C2j~sQG?(jW3&D=V*q#UIr{%tOL zRQ12(33^VZq z$__&Uv!>33io3282IHXIanK&ai*w_k^{ZiM9WmO6w;(lj#s^~+R42Nh0goC_o8Bi= zT@e6h8gFF~Q+O~m8|G3ioQW%xHQu)IeX{B{>4?+Zje~on0`BRylXUQzpA4-83t#xl7W^~`wz`Lcbi6e_Q)xB7g+7MsF3f9Z@cTPtE4J`M=90m8BG8R z0eB9GPPqyQxH03Q)_!Y(#lEl?quivl3auWhi;kPe^fY?5jPMh61|U;jT3~KAyChcu0pSiI4QGdGrOo_hFQT|B{w3b~XbZ0HLoPJhurHw_uvL z4$ubn^4iV}m@H0w4hH=Y2P{+7QsAloN71>*Gui)teCG|rY{SObFiglutdPwd<~-*K zZKRw_Md?P{7&bFaRFpy_I&xE_WDYrWq}-+BsP1n>H@X#fr~Ul?x*m_~kL%Ctx<0S> z>-~JnQ&3TBUU&;$VDejrqcXfCV)pASe#xqvF$%F}%raPVjg$trf&((f83C`sHfq6# zRA!>VfB*+bpIQGD?uWC7gI|fJ|ql0wM_iSiHpFU z`mp6^;!1pgTXdbhLH)ei-fM$Dbr<59w08Z4z0woII+~WiX4>?fp_BWIlR-(v={n=L zc(^D3zL;IDIH5TCGV?#&o3nAFByf5+t|Bvw*FX*v*$1&`&2#Q}8kJm^m42sK(+6}i z3=Nz@L-cVvgc><%4RII^%JIit5c*i7L0|vT^ETpgXBvoe9X0D%S_%#Ugwjlu$dFG` z7*+K+Vl%{1r1u=sY6yC%k!j=Ox*kiI)U&VKQn9#D_psCSX_ftg1RgQ4e%raPNml_r z&S)D!k0Tu&BC5H9K~`+j>GkeabHsd{Fa@&L<0uSYRmL5IY?aOzkKmdGa z2A~4=W1D#W3&Ra6205LihR(yYL3{M4DL(}DfGk8D#o#iTd}duOsa6p34)*Y+9=2^W z)YXasBpOg)PVsjN>kr187G&wn9a{ou?K=UIPn*{m>BN9;^fXtRpld8atrjm5$=at>DNJvk`h@G~BUz zVfa`~8}M%N+9SkB0SdQ-`aP&f1{Oa}*uz?TQ{w0%U3adgm?%OAc3Nz!`NUW-_F6z~ zWJbLZifF#08b8yR1J2^sVt^vL(&@ylf+gQ)cY`*fyz8d*b_v}_$QL-I#MX!WZ+EA_P1&?jkmm3X1O^c)UjU3HQ^EU4=0v>t=R5)dGD<< z8yTiWt!BZ;Do)@B^3K1>&f2P%3OSAB=4FBlAD$^O0^I6WyH}y_kgZAvJ-E?Wu<;V; zcnOl)H0$`wx#_odbDEpmf8Mt8U8-0= zCpdZXvM935FuC>WX|mW*ez?r>%(kgJUh*AVdSw};_j&4=H>eGO2l)oGEB-|5S-|J% z?a6E39HV!owiM@?m&I$lOdl7FqH#nbyai4;Br~rv3i0o)-;M!4% z7TpFU0*o}=(G$8{@!bKq0CQc04UCtW9xB=O)+4I@O#lF2*uXjc_TYf0otN4`-g z+%2$wx?pRvzpCa5%Y5MN&3?#XWV;LU)DeheRfgWvJiNpoMd}6V?M}KX#daayph0}6jj0%G!#@fXiQXS#SdFXMKR@j+T$Dnz*^4DR-6@FiLQI5We11ZK| z?sfA^bPt}_jCPNwc&M)x|8g~WTx|vYoNlv5rgAH`uIX)L+aw}EJm(d2aqpb^=L`Bi zy7Z|EP*^_xWIHyM6Xo&r=jt`mf@#`r`3xMQiv*AWDk4!3Oxk3LqFtI0NST z2j%L3bXx-ir(bMHxK=DuoZg26HUgDhAPfQM(a6?lNeJ0x{l3oCbbTH{5f6IU#z&;= zkX!3Y+TV{X4g9@*;-LYmMZiT;rl^HOj_y2}qukvzygLyeO~N?zZUgQ+pcR>#OCzVM z`fE(DBG87z8tK{)l_Y!3mwiP^ty;2LOJrPv>dtCw!xFFPu)uoWi0Mk!_xN{Kwv~L>gj$?_3 z{?Y?2UryIivsq6Z!>nt;+3iW@hJscJr}e7BAN4TUz^M8gJxk*+N?|2TZ~xkLu}xWq z(q8k!4gSYsy($r%qF3freyvG`6-J#I`3hsqifyL$>UdDr?SpqoiDKKnsCDJMWBlqVEU>n_{INfR3t*b$z=<2NM>L zPci>8C9Hm%^nht;l$@DNI3r&YPw_1dPXblbebvR04{mTBD-|slxM2<$QbK#yYHa;X zvt-`qL6pnvSI2|DeJC;vN`QgxotbdayTBR9nAbJWN*U$Y!fkSHF~4TasJV!JNZWh} zYi8+oGN1QYG7$Bq{HLOHHycvo<3qshu59h{$$HjZAb9sGOa5INOzK=6d03c4S%v+| z1!!0Mt^xpHP$ao8iT>a$5vARtU;j`K44V5_P-TQb;fSKUnh5?QGzqovbU)^k;6M_A zi5l2*?&{il8p0V=Y=1Cv*Zd8AyS9o`7{Fkd_Oap)_W>f*-a(9{%=71O(hpB_hbADP z?`ZJCXeVL|0(neZOJn+qVeHsMKpmUCV;4`Tk*A6G{56W14rcMgaDCexfR2 zQQhZ1HcsI9Sx*JzP|GW9@pwoFEdN0gH8vGjrHi4!`fe@Pu zfjY}Ajm^J(u<{ldS1}Q0)F&$x>4F)jo_@iK0l-#^Tw&Okzf`dGmSQCiF1V)GU4QAn z5Q7bf2n1bF{oNnWsS~ASclqfXw#iD5)5oZ^oB@QrMbCPG=L^ zGv~4HvyuT1R=C|6n5Q+#e9yZi_dgAA*6z}AtgivAoEAF=k0+bb-Oe##=eRsxA7Otx zIFXx}cvIed{H;I$L{@7Fh=xEij_W{@Mq$BkimP5s9VtGJOjTFgjTylwaV>8znr+97 z82TvY8h+$FeC`u-tHm7i2E-xQ+^lYS3IJB0a;rfdxq}ugy;qlb zhlagSPBkvp-Gq6r=tB{n_y-Y#dNzI;A2m| zby0)Z>PgM_SY3kLMq+fA{1OfplC2{O^BgXZu2~c%Q2G{Gianc;;8j*89>Drw#h+k2 zqj}d(d!S9P%YOXPN{#o!C0nEtbqG0Hw;;)Xhk)-p_3O@6c}xLSgJa|W91{DvU3a`Z zXJ=i9l%3cMJL0ccEW~}*Q?at7!8)zamBKb1_NL+uHhq8{86+7lZ2GLpuQUO+MhiS8 zLua8Bsr|;eZ>|k+vR+R=30s?sksgCP-i44;R{w(F(4DVz^mmtQ0DAt(k3u_qZXJ%& zfy|@K>U*WzFaJ2L4CMp&%BA)s#8o%YGgGui?N-6{&9Sh_5zNvIVDy6j@z5L7q-(OY zw<$9-VaM(-O9O5kC|E8X-DhsK&T0Lh7sRYaH-`;3aBkP;afb9hy9ke-x*cW~fC7dq zvavErK~x-RNfbcH9ngzy?+{x{6~;TL1uhK)0x3rl5IDaV>zH|wguSjd?+n^o9I;Lnr*cxtsrnvhrL0jl`CGC-KZcVL_*0h47*wN#^x3NUJiBi}uI@b((w-u?gDKgm!fVbuOk^)Z$L(W#W`uHE=cZd!Gj>zy@$3E0~azF-!PI z^1YvuqA&2wh5?pg@obOZ{EyNI3u?W;3Sh>>B^?C(o?S#4(jj$)Q=j3}y1|(Lwv4~_ z({*|sZ0sSG+Up6~5ac?n%T%s*TJFT3wG?9JQ+B!rdAkL(1WzJcW(LgsHC;2a2_GN$ z9Wv`=obV*qkq%ksuoC!pZzaFzR+?Y--&VN_>8UfCiU<7}pKaY`EKOi~z1y-&>$!o^ zIMb;skQo(e$|bU9MVaS+YF$0ep=9e2%U?&1b8@iIe4~TF29w60Y5J^xMsXC|5Ll$3 zYb6gagqNw0i)U<`;a3|*%FW~ZkLU?i&xIaaTet0Eh1vVVS@LKRSTCi`wZ*@}`eeKHTgy^fY*1p%Suav}aKDjMScgqU2 z!AGp_#(=Eb3CGBX>rzKeT$^C0Lv%Y_UhYIxWN#{5Idl+YK6LIysOO@=I3moV=w!xm zTz|w$B`}2dN)xmbAyU|VR2Npt3wK;E8^&Awly0At8PoGgPSRUCq6v^;9cV-p`;$KQ zE@C?(uwy|hh(6$PuPCk9(6d0-C)uE7=b!OwcpxFQt6j?`l2Pygwk;4CGFOI`AIdh# z!%cZTd_A8D@in2CiL0AEAG>ct-JaR^BLEzhXZ(u+UgYS`nswDTK94ID_r3}Ye+GT> z0x*fgk@-ex-1oQaG4Ejqk{jl+qzF3C{4XBV2Ig*zXxex=nrRHNq4E3sL3>Wfb{)mF zwoly8&obu-(?Ethjv#f=YexFa(fLhG9c$D#cFVkP=@Css_0fly0+AFbVINVZQB`3Q z$*0;hZNRT>j(3Nt)?`9w{C~*HkW=@g!lq$ z0AO5*oIi31%w97KlNRs%D!`B)V(PWFkxl2%ebTjOUzSA}Xe2R{JI#6A`^o>w9snMX z(s`a=(O80oNg+4kU(XuWbM7YX`t-F31q!YGXQ|XTK>*X=J zFUxK<_v(Dj5laiR?N_EVC+o0FSx&3N`8^uB+G;Zz`SYkAxEYGtg4U>D%FhYi*8odp zL3pI_FdMK}Zpi`?0~W$aKum{tkXUW5|3wISHoGPX;R-*I(>ciF$i$y2E_4- z2(0qzG0BH>?xSfOb_`ix+-Ee#=wDN^IpmTL_1y3b#Cm2x;NaG$Zu`j;p3iuIUJq)+FHP^%@Ct0Dy|~%bNT;pWUDB zy;{5ipgPV3pUK{OK^Ih;h|omLW1IoP7`6LvFNxBu@8?5(D`J1BUy#TH+>i8Mffw+l zl{_7zXj0DVWU3Ppw>2X=qZ`Bx$Rj)@48sfT3~RSMl)P0^Ae7~F@B*beA5+wjoO&&q>@!olYLL2R) z35NH&NiXQEfden;FOOr6h`rjJmJU@yj*S^4I0|Q4a&*q$Tjoy#+|2c{#44%agEo6w z%&q2Y`Qiu^YWpBD$DIT`TKx=hsc%oUwt8E#d!L|QJ=UfZaG$@okEQievbUwLY4#71 zqZ;4mbG=)7a-W>vvcHNzt{MgSj4`Tbw}-O@Dis5|#Xn9JFP74hf189~sW;jEQCF2% ze{}qbWZ4>)LLpXdX!&)=Be6g*H7yNI)JF`u1JxO4Ql0q17qB6wE09Uo40x@0G?S_pjV+0W|dk!kLmd_0P;7y&!ok-S{Tw|`W$D2{O(A- zSq7xH+A-$is1fYurR5^wCG>qU_$LqTL8NPIAbygux5Lu4=!VR6K^r1a=@j-yqkFtP z={9S0*T-^NashRNi@SPF;&x?bX1gCOQIMJ6Ne1DFti;{auU>;e!~hZsk7u*fJ=kVk zJPw1{U@5BGED*$4zlw{J+oc%;Dn7`CZsoK=_o}LOy9T(rdN-5W&kA4f32=yc?n45ot0wWg`Bu23m-6QN1p?QcaYY z%+HY|$F68+i@miBBG{MJ8Xzo6pV~RydRa0_W9GTzRt#Mh=S~G$zx5$E8v4mSq>Cq( ze*}|LUX~flkoc94DwAl1&#>;hasJ1r<+KcweFmCw1E3N2gwR&LrLXLNIS_4>Vp!1;9)mQ}oZP_X}!0#Ow>oKc7}; zq>wE!a-C$7i{WRPbOPZWP;)`WO+4mnvDDPG5l`CE)U*V=l<3!Fz*SgrVf$irJC;gg zGJm+o-nD#}`KGuBrIgy~-I*wqS}VTf=xs2=;!*~-d<)Tx#pJl2L1*H6G3^xT&{nHM zW{Bd+9fMDS;Di|z04M+`tbQcS&@JnzAT@8BV|JK7b8bB&6)aU$D{-W}<8_B<(mH>u zKdJn~;1Po%@fYy6!S3#|WLYs|vqzCO;wI5zNgEJa(Lsqj*_6cb{TJ~{qxbbH-7_aE zLjMneASp;=|7K6UZ8c5vI)SUUXAX{#6WvUtHdzUSk!$%n@iRW=w6Sf-;T_3iXdcTfyX8GQ(s^xGq5Z3a%;O~ERP)Oo`*`w&qeb0s(@1UG9+ z7lf^v$vO?0pMy3w-P){r4kQrE$~UfAveTq=(0f&;Pf;3xX(A z8suGJ(3Jh>0*##}kFuO(m9)0&=iLFn4tEJJMy-VZEIB)*G2q%;WI6-Y^rgv?tGany zjsL}vdq1UieD$W~ZA9t`GqhS=2ze%(eCXXTelb(LrtL2){DJmzddo6VG@hPThkJBm z8`J*Adagr+XJ5>51U;6VrBk!uL+m|Pm{P~zI^8<)Th{ncT6aQ8kuR(IH(+l|$gI7c z2I+H)i%CibOQE39^dV0clh2o)`j`Jivc`%LP8DW39O5gn=yc*~Rf`|n@VN?DwESfe zv0jbh*qDom?j0A@8FgB0T1c{nIu|rAff4l~x}v7zyd5Yl6@}qI+Mfpictbv>Rqr}_ zMo$|NS+eBWUhnN?f+#V+W^?O39wZ~ayX@8gZ!TCHF4d1F!!8|@ zYn#k!qk|*!KTCb)x}&R76D5ZzU20}pi2TXMqC(>M6?vv|N(wu?McQEq&_}pe+7BPt z)6#sfB%j@*Y4Rnf5+>qDeQCAE7rtA4h-g{@Us7I}NGp~=fN7WvG@9D}p z;Ae%p16n|zUCJu*FkRcTvAYdm1wT`djl2vd;#2Qc4Bvf39o~qa_}+wGI$rsQ9R8y4 z0y1{=k0{M}bJ>fuIp?)&@z)e))vJQN+M?_gAmIm{AO#d1U%RU<{JYA_JOYJV=tMPW zi`>Rx!=b%yVb??#KFipUu0z<}x}2tj#6@;$;3u;f1&N)9Gl>P#+wx3Z7X8+aG$hY& zk?i@~Yx~C3;Vqhr^gvQ)FXfqx&p*mSfn9iM6>Qm?w&X+MP$bW$i$HVp<*hU>9H0$gOeWoIz3*a6*2DbHF{T5(DoAn zSR9on(w>@EB6%Q&Mech~tXN8ZEwLqQzsh9&gWe>ZixTBWYuwtM zsh|Aqk>}lPu8F>pD3`lR{CTn2yA^M$_3FvfY^MWKRL{G%1~XGj$)I*l>>t@6(%Vy~ zH0a%?)|cKlUqB>V@Mx=?+ogBFIrFrAaf*Eo{+_7=cMIW!aCXkDSx6^u90$lIj$LC6 z)WPCgq(3yEhzIAAQF|!9nO9d(0F9Ny+~<3@dpsMK>RmFHw-MIj zo%Ap&n5aS+%mM&A5c4;h{7z}$+bXt86Ktf~=to1x?ap16vT3VF&vr;F>}P56bZwE9(eIVAG-AEhIRm#dX@UTHa;7Xu9%07 zfLxTb4S-?pGx7Z?;xNqUXo&@}O+k;kb0jEVk6kpNbx+fBZGNg-*z>jio8&uUNTbc@ zV-|72tEt~Q?sSHDWBmmS9`MR(UH|x+ySZO%mQqxJ-@!$yeB#8&JlbdJ$a!zwv@NUI zrFV}tB7RHPvi+g>GT@`|z4_EO0}6j;a1Wtx1~}kdt5Em-wH}BRs}R4Ap}3=3>Ss3I zfvT~uhwH%3u*(jg#oYk;2Q1pkQ%|&DoY2%Q)&H}U7ZScPDH!i5A5MUw%Lj3{6!ZW6 zltMpBa<%D5xn{7BrH}1sFvuhTY!z>bb6~4%>z@OBZsYi?9%1JZIVWmy`|vnnh_Vis z2RZ9HjSJ({Fa>6r8lR;HIA!O(r#G?oRLflP-7FPn8VA|-6mb~m&+*M4-FZNqBc*e; zFys`KI~C9H4$_K^jr9&?j_qZ|_L+R3;PCFTN91kt*t6?ERWb-dJ`E)YLF&RNHP`kP7{$q^EcE7r zM;oSC?OC>&h(^Jf@_Z(Ei#W%a8;{rmk=_sVM3^O9E5a->^o9PU98epGVl_+!#VTL_ zQQ!|y!epElVH7f>?BB;}X@F~GkGfdEP33U_OaO*Gl0Q$MLXW87>EY|=3}!Kg6U$pB zi`)_c`QqBI_G)LMF3X}MFJ2E=36ys^9T(XE^a#5I(WGScSQWWyCnKJiSL5q#b(^xl zN27D^aLgyvK-%4zUG787k|HijG3Ajgj_Jq8_tI=?tJ}CzI!ua>si+Y5)q<9vnI871 z7mXpTZr9r})7{6yUCNOBOxosqEUwoI?cARhzEy{8{U)6;aMZn7k!V3uIp8NPF%P)) zYggML@f8-uv9_gebW91fdCKS;zU=t5q0FxE2uC|?C$NvF=bh)!IIPMrRz2U0l?Ks! zGP~}6?Su@cP|)|%ItAw+v;&SNsB>W%xD6{-JJrAB=>?r(hyMBCut~`xTA1amd0jlH z>&NIZ$!uWB5WH>hJ~H9ad4Zupnd2-bu%(Xp#+gKrpzQHKqgOu9#X zq0x%~`kgZBgy3F-)&&otl3NdWTw&=0xC^*j52z>WjaC5IX#9tl??(EX+DIoET5U~D zd*VsproP-vs7=W#)X7&WRa65>5Y!RbZy8;aX2ZoaX->`kuQE%_uHcnPcM#?~b~(pX zie1pVOn0)9^2@sAQ%!^0_h%=6P$VdNJ!~By;EMm*%lCjD&qh{q4?Hj>3dl|a-2&m`5U z#JX~!m(5SclWcWjpMrOyjw!2@m)TPhhx8xUo^oimT`%{BDZ1)+)&gf%i#qh3RPU_; z@FxY;da0AyHj{<55vA3_r*R$^K|+4~`4S>Tj3p-`^vP%w42DqT`To875vA0pb8sn= z#AaKc=z&k>4;~MGTR08QMjrxtIsU$yvayyn?@6CBSgdF*Ey&(-khTA>ZKh8*_{;f_ zi)iB~q^ISrgW;;DfoIX2Of30u;_S##;V-*?tbF9blJ8QOQpZi;Jk{hASES;WA^(U z!M#lfrGw;2m0{^14D1YoR6_VLbv8N2I&9Y`E~Sn$J#yTt3-JO|_g#nD%4zeKiiOolOh-1HboXTgz$wN}bp;-YM(HV=!w`Sfc}z+FDsZx= z(mm%)&V&Bk;5=%t9ozO=$l7I3vJ*FG(sz0&J4g$y0x=W=tTsE*nWo|JK^(E#&w79U z@AoKyf~t0Gr-~2ko~IWA-U+nSBH=%$Sp%lE-&Bev1*{wzB@{x}w!W6-$g`J(`wgYI zH#Bj((VfkhWrD12lNc@36urPS%sv5~>rhiuU;LU~Rd#u;dK<#y0yX*hg4)}H2XUU! zn%#&dyQL=>p?l`+ye_v#tURhZm1@WzaVbkz@W}nS*)LyyKFUIAuyG58JCHo{#Cop} z^QNTZ_lJCtSV$=VDPg=W=S@>JtMZgDOYW~a9#v(}9(JW1m@&^Tc(&~{P-ED!)}Ebn z7&rIopfI8j=|afX)&-D6@BD&X}T8 zoH`ln;CZ~g@iy@;ToTYw$~=uj4Fqms1|+7JE5^^LYbLUg>l$O#gbX3_Ht+(0Y5lE| zsa`;67u7x9)aGyFxbYrQmpicbi;-lY@@D~PVZ{2_yC3PW%RudxSZTb;lR%&MctqQt zDSf*j%(8~Fm9+4XWMoXUq2DMNB3TR4VdtzX=B34Z0CND}%sEBkG-{01aAq)8jX4|Q zJ!x*4a0-bpw{II$Sll7B6A#|_cD$E4>f0;kMCf^*NOat^>610+ZK`VTTegnpQo`r- z{T%kSsP1OnX?gr8lfmmdeJ@!eohH$;0xQvc5X208G5XZA*6EE_XrK{!Ne~495Qzkk z_qw?25g4HXq}`4hFat~5AtWhlXi{1ky!;GMP=<$T!PoQRic(-@cHhh1MOW3Wz@M^+ zl|HTh-}L|wO=;XZt-}utM({cHJ2!we|NPbwQe*Tbsn}7UgpKxCqb@6%|%S(ZRc zQ3fwb*WD^T{k6QvDorwh*vVB>@OqSwy#E@<#3l~<-Xeg0CB9J~fXW6}OF-q*QAg_= zS4+T7-Ozdi0too(3%b)5yqBI+`v@=x+)b|b4{m4XEo&myaB2PsAmEu+`)Kxj_P-X# zU!u>JK*>e+$Nr(g{u}m=SjtB@ncdwsv?~k=9N%lKYYS@N&+>MM#cPjVt0rj4_QYz9g( z-u2ELkYz~}%feMN4ol`ASf#cL7aZXb?PFeRcBWAMf+Go=R(b%NO#k!PC=`-)!&oDf z)<|^SxHoUR%h`}Cq62d;?V^|zrMZPbo5Dofs47r75LlE9Xy8T7NO0@nFQ-KD0UhUo~-gX=C85oLh_@u*Y3hX7gGDJc0 z1m_peXP;@i;toRQWeBjbTJj~U_8$BzD;)5ZaZ%!bg=f&Fe;;rDqm{+r^<#Ut{{veg zZ~pJ6$O}R^K=(i?iZe=jWSN$3I;8?dr0w@$&PyrI_r9iNAY#Op}@tL0YV-{I@g_iLxP`W z2L~~z0yZ(WyQ0;Hl(DdY5$Y+_ZZ16E@w%8~=3<&>eA72VRCrZm!GmNn+y95;jqE$@ zf3?WPdAJVi-|k~V8Vg+Hq<5nPh>K)9PQDsSBaqS#Htc$JpF};Pz1bqup&P%Ni_F1j z0h>#AfPZ;hRJ)8794EeVK%N9>YyEKf7DGAlB9Bn$9{_Tu_l|e@^!FU!GVkyM2|saz zZoa9IkAy(AVak;KHbeyZQ>)pAe*qg)r*or0_VmaT3kCM4Ugem4-?I@luZA1}F#o5n znTPZECm3Po1=ld2LVz0sV0u3rCuJ4+`WS`PC0smK1HBOvbK_95vDOwM~=L?I1`z+#r-XUG>0yT}o+6%xGMYJw^}pRu#x& zM=(v1sQq?2B<{DOJqzndd^M9zRhQ?+Hsx1&$xHebC)FHCyX3*SN4=^`nwr$Nnu^L7 zPW?g4``WRq$$cVGJtSD}o)U~U~OxUl%2DLiP zb?)uA1Z~lDr*K}5F1(qC*=R{2TOO7{8oqE^kv6eHfpSk+CN_EAL%2J@h!tdUgXwyd z<%)4dcs#$9rWL#;r#3l=L`#N_?_?C0QY&bryr*720+Qo8yLnU&BQ9^WO;Y^#y<+iE z+qm@j(AI4-PG$YwuhbDHM0IzUbN_cqpeQ`gO{F!ZaBGKFR~;{^;^pJGa4uV%5)J`5_mlZIWAV z@Ax0I`<2c-92Eo9%PXDjL22Gnlf>2^>_MsTo4fp0Hd)^qUM$Lr)hR%B7mEy&vKH3u z-XkK_?+8%{*8+8M=WF1^d9~NW(g&XCO1BBbc)6@zg6e#AP-W_piOR=HA7;ajGrDGcf^rk^&^HX8wFUK8@WQN|=p6fF(2~CeMuWoE$Pb8`nvypC7xwL-YchQ{JoBs-?S9BQktXukon3D~*(k6dIu8t7vBLSq zRf0(;1?QZ$ew?O)vv7|k|I-1cmp0ge|4jLnt6u~>e~+~JMzVtJTw4#=sA+Tg0Tu`o zJU9UjHN#jIkltFGG+cE&O`WUWqw7{bnSgw8guGTH_b)yW9^eM-zxs7kX{;9Ls;4}1 z2%Q;(%HRLk?NrCV(!zPST}$3<4}pQl4opVO%i@3cLP1-fbPuaPf~s-zi;S83!cc~KJD4)(66|9{2l@u45|3swV_x5C0f0DZUuIHLL8rCXDFF#U*;8_8VX zCG_F}Y1~)RQooDTQ1+G}|5o1gh&5-w>-I5t&~TESE*m18P}8%Y06w>K?zGAYwmD)< zqB^_go^Sc+P#6$W9M!KE>cY?0-Nb(ErCtnq*zCE^2e|JVa14j*-t__?@ZUkLTQ?!V ze(SjoCUk=V;2o0f9}mx-+fg$B>AaW2$PRh)!d)`s*3JK?keMS`s_U0jC_@if%u0os z#9<*5KoBh{G`ksuf=W)^4OdHhPqmsob*sKZD5oE4)NzHS&JUQS{g!8j)tLH4$dE%2 zT=N2MGJ(S#hxxX;mqz?F1yzOZ(~;|)I}7W6yJGtWx!FHpS$~K604?wkTz&5-;Z5jH zNeUPkoej+dsoRbNGy=MivHShK5CMkD=Y6a3_AF6ImocT@7Ge^>X_l*{xK`_4U18&8$a_Z7l%u}P5b7gGaZAI|bM zheA(S(AnuWKTk-(NB?4C4$BBAlgAduPhu_f!NR$q(2eCjF;A;#tA?vfgJriWqMvC@}zLpCqY;$g@ z*GdA8&riZU>X8=8~3Wxbyl3EsKCoOp=RN z;<;D8jx?t?JyRAT{ArZvZb(w05Ix+t+_wURe}!vL^}%(!DevO}`)pSW@0N+)R%Dyt zD@V#~n{X*oXgA|$`euq$6&6e_ugUo_aTT(plct|=rm$L>Ss2d}g& znyk&+6-vE&#?-z*8uFiR?l#kipTU%wqLoYX_0X$)f4@H9_MxpVjnI~U#XvT-H0P^7 zocK5(`50bXId|f(HgQs#cdrXB{j~z4)!O#`x2vIP^;z9uwq|b1H-?QfQVe z7nVrnmuJ+hSlo;dH3YX#WZZO4w$?8lfy|ugR-J4D)W8e8112%EaCMEG2(I{P@3shv z<`qSd=vC1v&?D_sz?kQBKdB>dat24I?3~PYhT7~&a$fp(N*A0F@!;m`f8orfg2QY$ zWQm9C-B6(yX)oYRv_Nd9dmBL(_4e*wD~RfW>mQy8#X~0XjTz22?ZH&NLiD;og>>*R z?B9`}Gi3SHa~w%wN=o6TkbRc*aX0bflsU71>H&bduCR(SE=dmNu60jEFRbd;Zufl{7(f3@VaYk(5v*-J> zVCZK~+eM<1PLgG2;@BbagYKGn`ao4c>Xz|oiosQvC$o+E?Ldb32bbt4a`bR7p9X)6 z8ake|2(?HZcmsQ5#05wnO}ZnZ2{i1~$NVf!#y8J<+y2LyC*gzD-_H`yEsQFBjHBj^ zF1>PAfWOv*)WM}-FZYw}@#=2!aFF%I39C4pv4_Sa8+u;gBjV@8hlUKf_CuIut*?6paVv^Wo#_S(i{?wR(l0_^N(^T? zlLvv0jPD%}+gh-}x~cZ;s1(H&|)MD{$Y3 z6E#GLdTZ6z^$1XHQC)07%(Gj655(mWUd{Li-YTqmihX8qmE5tH1^YJsq_CP%t-I~v zGjq5wP(0d?uP)xlIZ)D1AKQ2FdZ4^$&s3I69Fx#0&##SL5jtW@SYAJWqB|Oju9^6R zxGXAnX0xX(*1#&uK_Mny2eFxe0hS|@%q3sE=w{G?O_6+K&G9ljKuh-^OmCC04tj1+ zlI3c5@3Q*oeglI)`oC-XsWk#s18>U$l)_X%5dhtMrLzQg%$XzQ6EA}f#P54g*m9}5 z@y~rCG1HwvPGzh1#jc(Gqd4V+ogA9wZ>0Sn%fT=6{ptD>lj{i&bO#k%;a=O^Bnhmx z6nn~l{ar?$(S7j9B<^j2(V>XieAN0dwS?+@V4w+8aF>C)K5_xoPWPI{z@10MFJ+{B ztB()vvg} zM^SIK^gBUyKT_30qh$3j>gCBK;@Mzzcgo|QdIOs&ikGlR4pzf1;I}>s)X+kGcQo;i z)YY-GjXRJiE#|{mbr-g3=7X4bLVfFU zaij@Ex^U;tr7VM)*?sZLy}!+Z5joh7Zc=Y}R-1ig+>?H#^&J-6Iq>q=@%^2G7s=A> z;p;ym?2uXvtMW%XIJSgTuWftn| z6w6+>-+yPBs11~qm*afJ>#JM->P0(ucp*TMhK*)K4Ycs3iof5gHuUFz&nKBx&9<-! z%YieK8|%57Y zp|^Vkcu59yEDCgk1md0ie!qn@tdo#g5zMg~h&<{z%e6|2cjPBM1+Ly+K7>gbR{V=@c^VU3pA(Si6rNaCqq#6Cx}>YfDhM8OJ}LOa+{D2A#r3E64!0<}>SAeuaFQWcfP$mc@RQvz>)*8I&eT*&fGP-M?OSwbP> zbA*S`%g(t(>xH6~c{9j%z)aEMK5fGf(;snDgK*>S^%xGM;giX8$W^WuPaL22ok^pX z<9mv>3)`B3-(k~kg-<7xbXg zH5wK%evP*yeBmMDYE#pGC3oaQu~|-X$-|PAqcMtT9QJ`*hd9?A_N=?^Stg6y1^uZR z&dOTf9M7}u%}qhUi{`>QfU6~O(qHd}86zB!xeI z`;U$<(}%vnG<0(2Sys2fL9T@t2IG^hcg=5-SOuqug_0R#eBe2c%%eCUd`)^cB~Dg% z+BHxJyC6_zkp5CbZqpA2sh>Qr_Nc2_p1eVGRBB?j(z5vh?Y(7rRG?WK@coFuFaJi& zzjob#mnPg!n!x1I8;{1{2DjLfj!sZxdrvVc>_G&G$k@9}U3rC*q}gM9;$KbV3IDMk zeR1rZ6hgiNj>&ZA<62~(-CVy(G#W6te7z-BSfiC6i+Hbrc%b(OHbOTBBS)gGb&1%Qq9lz{LcNy zy`1aZ_doYJ*Y&wR@AvD?-37FEvGzPmLut>xMq2o^fu_XVS;Eg~w2qd!c`Qo^CrRek z(cjFx$ilWNPk@NUoqetaVbR2&2wY1xY#1@&3d^UJJr^rDDR5v1qQjjPK5tCkcR+9R zG6|gf@~Np$qCtoWxTM_z%Q7J9aX0pPlohSzjBxXt0yjeAqWZAkrp~kes0IA^h&c~6 zD4uFc2sU@Z1oYE|0C%TZUiH)iC2;SYYD~~m(6=d&e_+^7>44UA1*_fc`zM&0EXylJ zEzThR+4POi+HcCdFbFKpy|UHs*Wa>Q&I+rUHlU&KO<64e~}SeXjH3&2xH*-yUdI=3T}U5zgf>i-RK2Wad$KL?1{ zSe6e>z2@RH7K{~c#IlFtAA3Ot*{~ttg~S25{&L2kD@J@OGNA^cESnf|BPTY?6LxjS z8#m*Iuc`tZ*>AqC2y)(nY|hJVVUgDmqH*qrsjZJU%Ju^wHRWSDBTY&0YG{Jcd zJcZ|S8XHugUJD|yAR)n_!_yG-#(}Gl|2hiuO4Y*CVNp#@Hch)}$EF?Ij8jL3N9=mc zFAi4(dTsN+_&rPgO)LT+jr6btPQR_W>pL~zC5i!(Rd(pe9=-PDe}^x(;O%7QOLrIy;5 z!)5HG);)6}94Z~8-Ts>K_Nw-uh@roN19cXwInO%P7xHj)OGKgD+cOx%26|!7Hh~7S z^W*5}!mOo}wCko)5IWtc$y!M000#3!ZsO*g-kpyqO90-Yqjnfe)6uD(M=T?i zfaA)V{5Ni->G#**|E*avYN4jfpUjiy1yiMcdY>$%`t~ z08$+l@`m3FJ>BBH!G_Z1V(`>rdQ-LUPo&xJrN_X1owQ6KckszJm-QhfIN2yOov!Fq zp$Qz`wjcP}{lMja#2is&&%l#yuX^Ow|MO!MfA?FE8)_ zj`t%-tMchfbEn#D&vUkRgv=Nox5pu7>*3b`7))xIP-ZGz+HtyU@_pXMz9ad<==>a z6!ojA>^jT53$3vHoaG2zhz_ZyGSomt74Er}l2Af`DJ^h>ZQ`l3?)*y=atR194>Edk zqF(|^Sa1UUWxv7D6*yOr#2mEgFMR^{IZd6;EY=O5~jwUcpfcW<6KA^?k|+v>iq$Z_7AvfLL*4C2XO1 zX!m9s8is4*ZdnH~!m-r!P;PYv017bd^xIyKO4??eiL|nZSn=hKb8+@^f`x{XZUP-vfU-iB{GS2+s>r_JMRFH8K zYWa0NyIo-83Qwa zAN1`3%Cu%>h>PBh>RY&FUJWm%?zH9MQP(44BN9FJoxJe=TKZIT)y9f1kWl?O{Z@e$*I#I_QSiN96iGk6h{pDP}q%!26ENM+7d<)DAmGD;5m zBmQTeuaMZI^vjMkRgIbKT~gg%FwfiSdUX%$z1BN#jUzGjp1M6Llw3{cSq#*ho*0V5 ze*@9J@iou(>^IKGS_sr0KP6XM`d-}MLW@2hGe&q7-I^aQI^h=m4<&PH`4~!j?8Jfr zqhivbc)%e;c{`U9 zPG~g#FH=!i9uHTjZu8oA+qzP+Y4%%O0c@sJX%=>5wG1ehsLV1elKd?cF%NEYH6Gh%Lcj@hmq%P#p|8&6apTr;RV8fv%9jl_Eo;8ByKmg4un{nP7UNvtixh*SAN)%I!<26-!x%j7ZZ zSbl|4f)~)g2&bX;hi1BoHty3=MC?PQE~?E4PoY187jD99SAil3;H!PEh1MKo)ejst z-0)8U5?`YdGuJqGts=)_j`N1AZ6dGU1p!=QKQogjR9se3Sc60jn{T_-|3IbU(c3B7 zJ2@fsih+WR=34l+ZuyOWr%8m{J=u)$M^1PSS4s0%iCx|57VcIwiW=SqP>>5vB}~JV zC4I@9k|8g8{^R@gu=KOP-nsd$=G$m5z5nw5i!7hGJfE+!Isj>Uv{3kS7f*nv0|b(5 zwE*M{KzW|SaPIHLUnVhD^>Z*{0H*zzfj4&Q&p!5Rzj?^&XMBm!O+~885x)ez`iKA@ z5&X4ao%$;C>k&b5_8GDgy5s^4uqE-(uR~;z z;eSB_ZF?-3(U7xf8EGr&h31()r%&_o~tgzZ3}r-Hv~)ypsG# zAav#V39L&&=`h&5;JpB__r5-H^8Towl`J9+ia)?M9B%06EZ+i_^%UqoBs=s&IIj#S z*(G+3nt3G>(Kl4S-TbDe*%hO=jmtcC-XIh@3=)x1!o~tA$TifUu>izSj}K2!Fzsz3 z$ScA!)vn0dm<(9im&&bP%@<~2zvSr6Xu>YX{0>@~x0!YwosVj)JeQ@76L z`U*Sgv!MG0U1lm&oJ^ly$xX0^fEyci=J(-j#vuhTP@9XjB#CPM3)I)?LrH|_{{nFo zzP#$j!F2Eu^&9yMv`KSe5#-Pn{T|xGWPwLP8qWO$kPS_z0xUHZD4u|c_9`I&JPQE( ze0kN0bBX8xr)0q=dJ8-{PqT3=l&iY+5d}~ePIEJ#08@?>(g2NYA?#w~SpWSRx_|6i z2>kJJ$Z}>{p8Bv*(P~Wl&>msC?_eYV03y%4;@x)d~S9xeOa2Qq4RvJ$OmBX zU_#@|%^ zWtnR3LSD?d)zhn5|DI;24wf3a`?`;RkU*Z_Lb#jzJw+@%(n{$!GTC`Ix<>ujv8Zhu z3-zTp5%SrKho;G-nfR$0zp2FwnEi2SR(#Ytyx2HyfmCJU&W#@)P|R>Fc%$=9XU|=u z15jn3H!w&CjmdI^4yr0a!B0<7=8DVammQW@J@GE5#`W(%LIBQDT$U4|0Q$c1Q=N_G zdrz$$+5g?JBw_Ee@-@*x>E7b+>1bD!INY%%d!8Sx8iMK3fa@~(;mc8wZl*0qm2B>{ z8V?xl<=jK$5M18=MSdB*>Q+>Y;;K3_X(&Zj%&u-#t&sJE*eM`>Ss(7we6->=?9u2m zm4u<%Wy*L42G2Q>=dzp%{=gA~l`wC$kFCn>$BEllS68?HW&FQW4eBrB)zuTu5~imN zG#~?gnXfq`1O4xqpD;i2|5p>$rkDQz>X2hmu!n*SFd%d~(lK-hIgV==mMsAPGQNa1 zCxaJ=;BmmxGQggOni8WnZk|p{#y9RZ#K~9lDFm^HEN#~WaMLey00i>C=dmannh1uk zu4^WOvoTSs=6E*-Oi_Xu{|1i$XVcJ2(uzig`-KnKHRCPLizb=*j!7kE{IK=jYm&6m)}=k_Y=$Edw= z86tEcL?`Elb%ihVvs(uEKz>5Wu?VL0yizH@uHxj|fz8`1 zx16a_M{j)rvby{#vb=93$-M~N3^BfeN!maVgS?ukcRQ5J8WGpbI0;oNB__Hsjr5eo znSC4W$S#v6>ArUu9O+Ib4IOZ3DCUpBF|92 z*)Hm=Vv+DOd*(rtW8yUNP0aE8~hQ7yL-F{lPH9r&i zE&Wt_(o+V4I^dL-jEfKz+ynrZivdz1xJya+v^{)Pn~7@Lm7C}m4N zcC3vmkuxPvjh0{1kFC+KxU~D8T(%`=`I9AifK#nu z_h@af7PGfAN(7jKZ=fnoS3tsQ;Su=}0n~^{iiE0Db*x*1h#(yh`RFVbU(k%v$2<(5W?*{Tb3Y{Jfik%18STjyHb3mjH5d zy272dEjv$z8)mPBRv}}--!|o%Cv%T?XS*=hULfw`7q|cDJt_Ph4=%`zS{?|j$u`52KY7sP>CgvN+r+3oV%-0^_H&@RUOJ3xlK47aSK$o50lK?=ot~D_+3*JV-1r| zz|K0N&tSJz?MPUR>JH#ONSjVOk;62EH$K2zN?@MMY(IhtgYF~0fH*q>&HI(& z?0~+mngR_b^{(ZS?WMApSU^i6g?6*gq9Q+TO?6XkM7U~U<`wPxL!D|`*^_eM+gqZy7tDQb-=T(6pm9^rp zc_TVIR?uW3aRqW>p#g>Ar%X7X#wSzSjN&UNVS z2Il=aDOagPXsDpnU2^_1TkI`-f&WZ2TrO?>M)*B-8?LJdPtg~amwProbzBI%9QM&p z?dK_DQ?rA*CtT(Q`6@67Vwp|v1SE*JRq4x<*Gm(9)5%ND|44^U18$m=EXcM2_6OXL z2e8ijLpc7BkkVxk5OPXGucZ`|pt2lGR{Wcw9L*lk0c#~UB0U9Itu4(%^2?IDBU9@2 zzUop;6us4|)nd|8c;m(jM?BR3_fuLUl}M;}@+DIbz>Yp^Ds{DPaY=r;qmrwjvX<<@ z{>Ec&4E((5Z~rS*K*Y`p(LlN?ncLV1sQ?_CMG=q!d<7w`52cM6J57bQ#L_ZUkS^te zR+X48+DOFhZH)gaw|4?&pEy@(QfEVigZjw@TdRN|l3lNB<61hQ$t8hcDOD z^arxB;UN7dk;d`nMdBVy;#m(`8o*wtz%pn5Z?>%9*MQVWwE9pu3QF>nIhv5FsPKQ< z$h{`ID3h(=0^@UrGb~xLis(=bR%-(fnf6Yld=@_y*JecDc?k0RFlS?`qQD$|F#5}` z%XN_JePMW+8j*R!sd+6}6}V`-Qu27uye`Q5AM{X;q$)S?h}Z7dhTf1X-jHk{ za9ee3?I0hfpMB$kb{GRsrpgdaFDNvR#6n?>)%Fy&J zn?cD8w%q~0B}1gp#{D1}d;tFsN-=3oaf}>dCZ36A_C_ z?hM=0MAw|381~F=YE1-=9@I=s%x-NEG0?M6XXc;X`F6L$?E`M&083Y$XA>_@aKSOt zs(QTlib*=e+1Ta5-<5fqxDBg5nj_e+(xGZXOEcM&9F^_BmgzB9Jq-{#~Sj zvtf8%zCyX#Ul4cBhhCJG{SK0o?^^OSd1zlAPT05OE*axS;we^sBHDGiCg9>#4Qd z+W4qkAnC;Xp`g=t+-k$M+w}FOV+NJ~+sAg>nrpSM7-1?!*%`?gQw;k1+ff455xKM6 zOf^jDgb&b6-NEtnWdk{MiUDl0Tu4L>7__qGslZ2poPV%(+03h(mJGiv7HzH)qc-Wk zK#SD_26Y>Zv>?}!<}as2k53M06E}nP%N)Y?5YhZA=`B7HFU{c|bfzcl``6uU#N$|W zpL$Rs2^(7_cVX-xi3humSqBpibVgA!&5ce$%I8=pmJSLvfkfXQM@mpb`e5aJl?`Oz z^y8*?KmfpSU`Jkc?4Pm+KJc7kfO_|Z(-G_}TnR;h_^ zuNYvIt-Qx~|Cd@0#m~qS5v~@li3?>xN;gweec-S=IDPs$iDo_Vp7?~e9Uq*{IKa|z z(2N`pCweMhVr&G}7>%wgru;Tf9Vp2ayJre8N;cRz zGk!$v84+`%V!+x{xWKSWc%e9omq=^K83Rppw>X&fRntO+Jet4M4FZ04B(?-0yiG$DoKe1n(xqRmx(|898*9&(T& zkP{s=&1p%jfj!%dFivnoC&$_lWtRZF&m1Yib0646dE!7mH%to!G_5GkpBjst43miCB|F^Iq@GaVhGcjUXHNVoujLJj{k1LBKe-ucInRaTTNHcFFZ%AW2C>xMDRg4D8YL~g*lPdZ zL_naTjq72(w+zwy^Hh7QF1=8oH9|C)@q%q%-pT>XLsxrOGt#%A z7?hW#OGwd$6};34kd};bUkOe-On-GNig(DN>d7<^W_ieqA@+E9s+wa{zF*&x^BY$3 z3n(+^vx85l&JPuvg|Uw-__rm0rU5^`wFt~$e0`}owL#P9lA`zkufB$f@?B6JO76PS zs)V%!kC>cIIP4`GB>;%|DP~Gqpv`f>Nx-*H3|cV&}}ZZx|9U|EI0&mOotNIW@eu zucV}BIN>iH6k}}&(ods*ZnPl^ue1z&(Cm8$S2V&CfyMBDi0`N)uZ#RXr%1@^PtR}c zZe5|X4Nc~2fbKW=eev~6pBwsKr<8|I@Ahw#sv5V@_Q0tYIp%6;oi>D1(}mK`s7A`@*r}lXi9q3PX@N`ePwVJX?K7ETZ3bQ^++$ zVwmwaASYE8S~ptCY)dU4#0A37T-Xi;+Pg^3n>K~LrS$8pr3PU>dm?&^1yVK;yKo1& zPI5s^JI+4x0q<4puulaCfPY_-fI~W`azzkA!u&^MJL{{Rc!(-dyGsfuJl`O~8_nTP zU94vbAI7-ROci4-+zcb)?gP;yWTN^&AFN83){krgY9f_a=+h3T{g$}rj9B@0@6_}n zaECYl;ILqN`VI_Xi(Q~Bd-Jx%_RQt3OEgN$Q7GqUp7k+tw^)>VPj|-l^`8Gi>_gYY zss)hvj7=5%n;GyI=5ucK&^)sl?^wbHF0Aw)mZ!vSt3#~xGYPM~GjV-rx_8|>`1?)R zZE=^23XJVD6CcJo5a<%r8+a}qo#j&t`xu|Z#w2rWDZ7(E2|?&4Sx~e@|K2ARHM59p zQ6AzTc}27E#<=H z8^`bZjHX^ck+)6q`*B4bcpnd@c_0ja@4@4Itn~xoZSL4vpq!QnPD;u1h7;b7V>UUV z-DQl`WNF%LOgtBh(aN+nQ=@o*M9#CnPSSV}AhImw+1Fh#RB?%_hpNo*$a(+1Cic?g z6EYhvoFz+~Xr4>#3t)>5w~oY{OIrqcF%xTB_6SBT4Oim$`kzggXv#F@12n*j2Ws}? zLC2K*sj_k`wt>O|8`8mr8B3djeZqeGra#o81-x)k$8jS=X10_ryZ$UzRO1%l-%#&E z)_xEFdxiR#E}!u)jkI(5x$bi2tVii#xGvd6*{%L6la7u0f!8@lVwjh#L1}P1j@@Xe zqd<=j-0!#K`NlxpOfcvYw)e~!{`tsdkKGR|D2DeZvM`F_^?GfepoGX;?^p^C4O|KP z;kpl;>H(ay*f()(LXe%WmxgdiElYd_OAj^Lfl{BtCqNDe0+urYdV_|_hQmC5zf+eP z*nC0hUG$$ol4w6g-Hyu-hZ-h;W!jo-rS&4173oZv8XV--^|Ibz*1fSf6v(Ad{bI7c zp<7HDxyDacZ3Jit)EMN= zj5{1Fa&LkgYUch!1%iEwbc3uMZ}Mj%TB-(Aai48eFd(g~F$~n*_(Rn3l;VK{V3poq zJht7hOHDh2?C*-+2sMSnz4@Qpq-Nq1GjOaI>3)8@Kjux8u}W#4Vc*Lg+hfAhfN7+* zLXFWFeJpRY_XbhTG81swZ$YJ_3aTUDB>M0e*Zc_9Wi}B7Q|8IL0bJmyNu1j${d@Cy z+Dt=HhsUn7UsgCbqm!^#-lo)V zP+9#nTVfy`3ayPN+;7`^b*pokNHxcQu649&Q%`yoV6K`Kmz*poLI$`LTBN|;Ov~t7 zX@AvnQ+LzxjE^`eMzJ$x=g72z;tN1OfcUL|c0#t0J|L(0-WAgs334`pMus2}Z-+g} zkO3=9Cm=ZdSH!gTc;wxNA#P`fGJImELRPc^Yu?AwS&DhQHGPOc;B8BS6Tl*EozPFGG3Wi786Leuf-bP4+Lf_T09Oz6{~NsX(!~ ztQHKXsyQcysB)P=|C#3W3h*Nz`i|zRggM@Z=cM4Gv|e(3dP@LWXnhQ|akJtz)zA&W zXw1EW-|41nZ}b7@lu>I;3=nR^>XiEM|2}}6@G;8YKAD{tHjwRB#m&E3#@;?F)acSi za_u9bEpBt397OoKoa`<;42IiU(ka+6ni){0xv>8w9~bFcE(T+@T_#_`9fwrDGs=!d z7s?BxKIGz;pytSr z$}GcaCHrNCK7Pk3v2~J=t-k~m-9JNAdu{jowlsn+L18mo(k=>leBH{N`!_@+{B6=` zp3>*xlPa+A`h&)Lj+iED*eH$sY+|UfQBO!}H+h5Hluir6xDu5*cV^4q(fc<`KyZbl z)^mAaphC_p_#-r#_9+C(z#jdKF_z$#r+Pbo3xfWWK&{js_FQ(?9xlvz7F-_|;HjFv zw|~J=uvR(*nhZ$;FQB_o2fNBDMZW78GeU5V(27;a*#GwX!I?F&+oJAu>g7c{h^C9g z=(^l;C+KF&aFx}akmZI$d5B)_kNlk@Jv}pt2Zut2%(*%uW<8KryEc^Rqd(95ZKj4d zPtY$Wqp7g1CEJIOj?8W~O50ja-nF2>G^?r^j4@G$ zKPQce;ZdHqFb0_Kq$equ+Xdld_oc!oFK>kh=~=_EW?j|OSEZL(Y_Mf@i2cNwrk1u| zr+K4kP%3^sSu)0q8)IhUupQc7k3eLtc8GKaxwT&f(sXRQu<#BTw_nwb2!8bnG8ATX zo2oLEg4zd6ZI5S8*_0LeU@HjY{7FD6NrHsxb@K>Iw>F?#jV}0Wmb9OciGmOnh%x4< z8%<597=!pYWIpsJsV))Xh*d`6W94E@c1OKHgEhXNW9{xP0x@M;01i)izB8i zlqcerkz2(E^UIN~AcyQmWt=e~Pe1^MCH66m36F(id%|GhN7$w}qizasDbm_Xw!wFu zC35a*Jx#ENQ_`j8izU$@hfDAm?W{FnAzXFAL9@NqOOS+L#9ZXx39O}nR4-IKCF%PC zR(zDk!E!bQB<}cRa27qt_8}APg3^KoiN10Vb@R(J^|xm&xyIQsT`k8jYWgw^9@>&a~jjPimFP8?0#z|y{IwIctm zJ##A7b)Cz9{Wwp_=a9vm^A!N3Hkv@UnZcD~Px%_*XGG7j2X-kH6`a9O4gOuipTuY3 zm5=PdbjlGpxUHNoHUlCn0LV9iA+PcLX>HZHVg!7vat+Sg!^Nbp0rZ*5Gqnb}G8AtN zM72Yw4ooR*@J+Nyr+rxYFu(!jVgSkek~X^junv0uVG1vpPmW+;|c z1slo=-4{9Z$?YNC-V}}wV~(jmQk3G0NIc*ie7;s3G3LnENREdeeVMQRz_XJ%qVfLMu^nF6es6hOa>)ep) zf3}&}v|iLk0cMq+Yq#(F_}Gn=00R_QQ4(WemX_r6!5TRTjdF#(mHy0h{nKiue;l*geH^+R3`=%ob;FO zH)ALGJ+-q%=4elqpFnd_tHfZYj+5_Y>cvKiw7R(j3=exfdz6|d>P|T z7MW-W1+3lo>OEwrhJy*bktdPNaWm!PuX-fr6ZCSEvHV~ymuRzgz;>uX0?z;i^x23h zT!I!w7mYN5*1Q#$UWG#bmxH%<^gky+LQJqp3L!$SA=rd99MiOv>+y`y!eTuxZmZt4u^N3SBjcD*TUbz*% zQx8nw|Fa)&VGluBs9n(-+vc10e;5Z9t z99WC&D`|9F*s+n0`|w`_R$s~VgVCdu!ph$H%V~7c0>Cc`n5Gh$_|Yek-~_0maP{Hq z?Zk>^vV3m6a4%M1c%hyM`L>+wiRS78ht5{Ys$N&BBY{KB^|g7|_7vChSBsxK25FCz z_tY|;44)9&vW+ZhqAR!OuM7sW&)?nks%F?~8ca&Bm|(c&^_ptTLA<=IrgXnAW*ke+ z_}o1X&eYy@X&nza<%4#w{B3(`0T4#Rn7^}YR@*&aLURA}`)(Ge){)>M2YT}E298F9vSaKbT|2{l;IvBL4 zWN6wnDH3IPkdynBwoz?Z=PlRV4s#&Xx0d^1V^d1?v zzd$RAORuF1$8xwQXqRLaFV3=MH_vJu>C~AxnD}lPyv)-nQ*R1`C8{+9|9&>8#Zafl z?WEip@{rg@&TXF9b;P{ZR^rm>cos_;JLax3k_K;g^23uL_PrTcsyj4tq8=R^mA4 z`FE(kmh%csxOeV`lw_*>Dk+Rf`rZkMs1Y5T^6QE66YSvU3JI-e%5Q_VsmLBC#*pOA zj^Uk~niH34jL&aA7KO`k{DNiCSN`MTb~}jDX5h>cHSI8{ASAjUQ-nR|%t&GZZCI?n zHO+b{g4;;#>pTPbjw?1XY;Ko852;iiu#N2;obu~H`>y_R!{LbshkR!m6Jcv^XORwx zT~y9@dC7V&5K{Tm?ancz$8Slu?I-D;Mryw_PT|yA@fp5?>)jvaE}+707_q*pH_8a* zaiaG3d~`irA=a$2q@(#>Gp4tzX<>g@T$WphuA|bSlCd4R5nEbzI1U|h+|?58_NrKQ z1nBw-(y^(n)wE0DjHX|Wc6ON*M|6j8i(~)FQ(!56y%rmyHU}N8l@2Kv-2z|M3F~}z zgF15+lr>5aAOk2izLG`rQI2ci7Dv|2uN-VK&F>=qbPijC-E|!8{9aj9BFoaLzpFy0 zDw*#E15iuh`8}Zgh2s~Ttq>OGB5%%Zy8@Z*vu`h1Fbrx6~++$f7HI`^3Y%SL@B?b_~^PiAb-KUqeqpw)9P);_|1U{2;(c?ofIT zqW@->v9X9fcc`#ZmQL!w38~fTnfQ`DLFZU#atdMa06_g)0vvcnabf$pIn~2{e9ghP z5YZT@TIrT=oU0}E##aS8w^7k{XNwvb<#r||TrF!P@$2h=A=TgX1AD;@@W?rKX9OG< zO>3aYG}^IF+OR!ejK>Z%J=yb5@DR||YW(cZU|_i)f9&>e>z)^@W8CfVA^G9Rtz|uT zw*>WmNGPt~D+CmLZZnj3_Jh91K2u8>B=I=_xNw;Lf(3846%67}A~$5q0JU)dYEyun zR@;G+&x6kfE9}YVk+twphuydo_Hw*zyEEcZ+M|H9)o#Q{03KNE^HEZgTPzpx4luw< z2Bm7{(Hwb~Uj?V6^_tdYl}j0K?lY3jpYgnpT?cBAa50#N#wsxeLW@vj6GmsB^&a#` zw&GSgzo6R9@|dn2oYms46Do1K)fmXU!vswK`eU{=590%`OP`asEyqRRa78XJ&>+jx zp~`}1PX;5Gn}tsn%ADX115@KF6Z9A9H~-u<(E9s@^RsrTSzjIBOE7gdMeK9)yx&X& zEo>y*vHU>m(w%x4c($)e1OUJa?`V{%#8%XfAEKNAj&4rcW1(DoR&@^lj;8H7g36i_ zs5)P59M7ut*M=$6dS>p3L2>)?R@|U&~+b8n*}{IGDNWb8OwWZI>R0u*yh3(*`=Rxq?Bdg zSlLZyIvIP;>{=2)jZ@e~1-quISEZI{6auDFIw(! zs|h+4FLO;&3G3n)4o?iB@I`rq7u;?_88K0Oq^Ns2{MS0Hjj~aJe#UcTZYo@^-lmwP zb&kyVi&9Ck%8#G+P&iPr`I+i_R?e%cu4~!JmD}AWUpfE!xxgOWV4q#fX$|jBXPjZ&8z;ehdbeiIRRZ3pR{wL=` zOZ_0xdl&6k9yUN~yI5bSeLtyMU%ekHKHR_#T6@J2+j@K#-?5aYVBsaJQPMDtUu8T~ zLl5R3&|fahPekn2y!FG+do&=rhFGaVz~AFiO>F7m{$CvhQp^?c&1?03KeB;Vvy%Wv zIkHFe)kW?OCV!wHd&s`8DG}l0`ei*T+hTXw+uOVOvC!-a{@~99b%Lxmv_B=tjhyS5Qxt23Iav<5 zow8o~?E(*;bDi)K&;i)O<6D7Wnj0TFt$g5c8hZb}r4Mx! zwt{+eQC9xApeI}}F5{NDF|yx$A35~TIw4TR$b9!a{3xmn>JylCRFT#2xC1$zkp#VR zFPzJ}IKK>08yu&A-dUHB6;jjt#vM@%lFnb(^1HnI=yv&TVC6uqykN(gGRKPjv-v$0 z`=zDz`Dcu^^-ehEg}XH6qm@ygTX@lbcjk9;{I)M9PL!z9JFtSHp_~>$Vv`ptL7Cg~ zvOZ_dwEz4IGT?Gvzr)bJ^A3DVz5{>oqx}S$UlCC8?hx?_sluUx9d@cEX`aotr?3rU zv(4J*eu0SW$;SpYKdR;j;M~y?^94OY*lIQ|>NmXZ` z{PHrpo@X0q%|C*IpAkb;nu|-anQd<(m^{OXV11#OM{%u7B4hkd4wPE zbJPZu=*iHjL>Av=yTgxu(3Ltzxr=;M!e4QhHzTi=ytzBeL6YxYGHB$|Cp{-s*X$js zf^hGjb~rSx+@HBmoxT*ma9@>7iPM2xv_3k!g;jE9zSE~r=8NH%&;C)KXO$*}L&$-u z;lhk+BXOhkQ* zkp!>V@8n!fZu%-^UXUCB*JT08iG z&z9%5sQdFjjO{IWpnCWEPHyfl(B7XY@GP&)cIZNI8*L}+IdxO<#M%$$PslE!dZf-z_`X>mmHU_o-5e5e z*}okUtl@8+QuA;-sf395d-DL{bA!UxtOZ4V7Y^k0*^-5BmUuC`9sK%KD_2yX)U`Ss zS`9lE_Gpj7av3&yiEFi(9DI<+p4)HtZE2bVXXEW0Y-bh7PxFiS=Z5~uiGIS!vl-fQEML{MV){q= zl1WdrY=%)EB0puR7BcqhD5W6_eez}8B@5BGMJ{vv0i3+n(wH{}v^+5R&rRUIv-A} zWgzBU=D-?WLC25V;VW||d^_m_zo#XId~BnZ-$LPT+Oa6b4z{6b$PPs>XSvwBsFT6J z-WY~MerVSzc!vO;eBEDZUVAqA&@YMp4nGTN)i`=lL8s9PJRW(xz%H_JJs( z>7e-_5F`Fna}lh3d<~P1w9nC)1^z7AR@>7b>0_I|Bj5x6!at;#-`jp+gPECHnXVs+ zq^$p>L__DR8O8=P4R&W0U>2<`WiQ>ow4G}ZZ3U)pqS`ukeGYIs-vz@_S(`oNUY~?J z^!Y3*8zlolp7qm3u4@=PW5SUDEpZVzK)qDd(ib*EOi1Vt7%gQ1Lz#>%{jHln4UoQ| zf#c#~*Vb2TRAuOVFDF42B-4I_SgI3+?lYpF@_YuHm47~&@3d2Mfhk2S9-P^c3$h$$ zUG^&L$UzzQ=F_;vEZcTqYeG&gE77?1SDkgf@wdXtGE3IuJe6z2W{qRb!F$*IA<)p8 zVv5=OHLixzA<>j4z@iL6tffaA7%E_<>M3q8K=XOkp}RY-y7{Ay#hJ3!i2!<{zasM7 zp==A*j+;%Tv|EV&-)p{{XZ4E?|Hsg||1Y_mC^%_-;1`LJXgW6pDmk{n7o zBr20~*k(>Mb4Wrb6s1pu5+h{}Idmk-LYZ`+DbrV3rF{JZ_YZsAk9+U;b-iBC=N>ro ziv*)^{jJv$MsJhg_&9SPaYxRY6eo{mGJZj2OC`#=8C%AN0H}+P2C*y7Z$#FxY-8H| z6&P#+m727OM}Pqjm^L!PJ#>!~ju06?=JIrzNPN>4lp~i}DTh=o(}l|zz^*-0JQZ2Y zMiKkeqT3OTmq<1Gy`Jke-yRY(pA|xM@b>>AvvHdoDmhh+e58npU|%YpTm}ceJmDDn z;%)FxTa=z@Pfpw)R$uY0C3a51%2%*BK3ZcRbSVrYL-P9^WDW!Gl;8RgC~=%O4VQ7i zS4qd||FtQjCKyLNIRVzWyg1TN{)&>88k^i>*ihA|x6sLGIhJtp!4$=50lG3;Hv~*8 z+5c>!NcJN4FYYC4q|bhnO@^Q;+T=EMIkrozI=z({P2)r)m+d%2>)T%4isHQ=c%fHn zS*NouM`gYE6O6I!8&v9BuOxv zTdQx&#v9a!Df%F>5EuWrvkQ~O^eWD`ur=7W0DTwmTG)|&VX)yi2R1^+0`K6|StvJE z)$sIT-YgJwuzN2}et;{T^lYA2Hrq2+Hp-U>GLisR#Hp7_n}kAKT7QD@DzA#8PkS6)7X8^oB(fa!xK$W2PNevy9QT!?*mww0Q zblemWl%L|I=1qi%e52rZx1^)%qt{$RHANMOY|DEt{v|w0L;dx)M@$@)jB~?!TJLl+c z1j1WY`g+?#ceim)BU=^c0XgJLw>wY5L6Oj)Rf7jCWunWQGz-mZ2C4ERsZfBS!J-_G zEdvhJ!BA@FN9z~P*21Go^HR)oIfr`yYOuy3$A|;cuIc)Lr)%)axu681CX5%M#y&GH zKI1w7y&a_TNCVlaglhPx1Hg6fwro9Nb2bXQ7Nd=Hy4Pr!EF;u45ULjBo_wh+L>UY3 zHQ=^!u>XU@lkU@~<#Fs<*<3~GcU7>6)PPgA`A4h_|B%vF)YRebLEZx~P-nVF z^&Pzqkl9ZA@ma`b-?}}4Fft|+$Qsd+=23Tm31>>gHW$V}U?^Ekg+OFBOYvw>7u9}C7YI^OIqq2-^#IeW_ zZ>Wa{oYQbfHTz%=ZY+}k-D!~OBkDk#FYfeP0J z%01s;ydo@F^Zx*OUWeDHa*ihiaLg8^sjdq9vk4HgKF>rmW)TPWy3x-l(;+RD*SP@) zZ%ohu1};y5RjU|RCH368XVF=E4}PMWuJ#6`__bWl`=#4})}G$oLxtaMuy-vl`5W8d zIDRpd8zk%~!T9iwI|plZyx0}W1!|awO7mFWtib|ybxt3TV)k(f1OOO|0g-g6z$WO< zn#E9~U#URxNtY4JI!U#Ukc0Q9NISk1b^G4sNgAAg_EQYoSi%>4y}oxj%YohBQd<41cJ+oB=?ogDO4m{` zqJ<0TrR@l{K|%^xm-Dn~R!f4sEBwyuM(g@TaM|k?EJt~%XJjcPA;7m`5jMSWVY==l zRr*@{br+d@SROBR{xEc;zia0zW-N70?HedtB2_*E19&}>c&1yaeSWL`=4?vu3&HFM zW_ZA+Jy(C+b9Nu<*$Qw%@_D78S2w3A}GPHg4`M}tCrpd`<;$P;{MJt?dGfg%x73Mf0 z%h4^9%w?N*QKieg5ma+fu2#vSqJ@rOrDgC{RW*ASo%Oro>6tcmz@MtbHTfN zx39=Av6m#9fT^8>>(+63Fl>m}F}~?o7B1pxW>DDl0nBrgpIfA-(NBF_V9km#K|Maf zm!2w)Y$eMS=M^O4+?yI`sruObJMylC0qtlr^lBYD$B2p4&ys|wX11BmIMIbCG|;Ek z!%20$qGGw}g@{T-n1qVtI*enfrWLi)ZltJ~UMdsUkQ{cZ?oa=RQef+ zdd|@-3F9M~c`}hLdJwt!!V141OuHid3iZkhM_x%%?q7pp{5l~~B7`zO~?Ipei@U+aAdgLx}hso31ODxK1S13_L{Aiav`$|IQ z>?@xvhtmrB-(zaQLBs~3z9&uoWzWf&Ndqy!%VEMHYA+A=IJ|Fq>75$QjDyMOxDMJK!sB-B?mi`Ns>xsb7Qbx1&X=&L?M%~;` zm09B>v}*?q%Rra(>hc1#VP8itpRN0jZ(tS61_7_Zub%MoQs?HWS_p}x2^O!-JOJBl zBU%wE+P2t9Sgcr%-b`)KR-O=OrPnA)3!@59MNcJl>TM-+WxyzRbt~YleRY&bVqrrY zEE_V-DZ2zFIa|`fO^20lVmrb<9A8Gyi)LKTQr*~LyYD6g9KXw6?thyjm}6I5Q%s>I z54slUzo@CTapW7Z2T99wj3yTaGBFOxm$|z3c9R4} z$_+j@;=_yyV71bXgO+;}M+B;{} zntjN`8-fo5rZs>$;R#(X>BdL{*%|i%yO@#J@E2$+>>w|j5Z375Fxe0la~%M0J@ia;2OWTp^!+1klJ@3Ay3ixEj&7hk z?zv6~-3LP*Qde~J%VWGW)NWS>nz`+@(Trr9_^+?bL59!gct@9Hx#{vmtdUrW2KD~d zAA>@Suj>j@E==;$r(W5;~XAIT7 z1$;S2{@s;odpmdk>A{n7xNB+-`fZugueRx6+X>d|N@sx|7Z%|ggFT($#*LGGe)O^= zsKtqFH~C72j|j;AMi0k}<$D0w868b;`o7(GHG*(l7yMW8Y#T^o%N5I1+x39RhaTG~ zSo_^%)~_yeLyOCf-Y96E$cVy4wb|wU^g~`!bB|*eET)vdK4#Eq)H6%esmjwvBJ; zHcPKrGhRoOyl#-{W{3G#Z@kP25_o7*%^K5}9NLbXPgR|K(R&Bxf>L3 zmX<@{8hxvBJpv{svfKDNAu2#lk9YUxg!T^yG~Ips#jAMgK{pOLrF23q$1pY7mTVS0 zI0E_?_?o?oAv|GkCMcyR-g6wtj+PKSNxzb1J-?FV?_FLcNh4UFldRaGg3vHJi1HH5 zzO|r4`Q-=!EV1Fy<0?9R^*|2@)Xm-mU$j68&DK_>@6BNMuwq?+v|Mi%UO?t`axnXo5{z&fZ>H{2|7a+c;QSRCL<#+I!VL8Keh>Uq7Kh5mp^Qu1cm+{Y%vzv%eu$&(SOqGl zXfQIN+6~jsH;8yN7(|L}dBV}QaLpOmV`C8%s~OJAwb9g>OmP;Hr3x3Yml9c|iIAnP zqC!iAwhJ;JyfAb$=UJS6l!MqnY|!cqPcqq|=$pW}-?iX{X!Y8TeD^EaOM1fxcMaM_ z06p$$AsQ zeOtgcC9K==N3OfQ*#(Zng|@2XM;e-*a~Q8R<6$#FH;XE$!%+18${R%+l>Tvr$lr?R zMbt9rsDUUWSwx5U$(?uC$``X|-|$K;b});&*+`||Uylk{MVI$L$gFbSPTm8 z)bgn?;jG|>jRiE}h?E!>pYA)F7#Vcuowc-zjYKph7cqJx5p_MN8V-#B-%8OSAo8eeKIFj}!#u?BPlPd)HAI2c+x=vt<|!iLL1}*f-82!q1)B=xCS?S2fLyM5DlY1Zr`b=qsBy-FZhJc z3rJZT!x@OGS9pE!8&jknP((`Xml|K}x~UBEzn6|vs7hXxd@6X5oY!#3>w%~<$jap(O*zDQP0Zbwp~BqbE_KKbu)wpK4_Tk&CL3qnU2}E z5j{|CdDFAXf+@y*v!M|9?(Q<{oLrxM5Tzk?kWf2LxCfe>|PV2~0_VlqS z(nt`%Wm|6_+9xdfCP1$0{DQHFGy_M8xg3)x2tfP4>lo^Igv0jEU4M zS+1`z_EfY=-smWU#q5C6oN&YFDPHZaR(~1A6Ywy?Ug>AJYptj(gxy9N;NHHBqb)Ps z!D$hz&;OiqZ6C@lN?fjKVcg=%V<}+q(Sb0^eD810#37|D$m?%&M;FsWa3E%zUfoX zpF55xn+yDn7j(YJR`3)=5rL-}sMbbc!cm8mp2nNSr8I|jocg$INqZUZ#uN_K3=N61mO$T59LdT1F>{9G z3MolDO=ck^4_y5x!bJ!&!+*=bE)IWc*aK552dvyu0AaG+&c=t7J$%W*jB3CR+Z9a7 zX`w#|@Qjy6YxWRHsvK+dUUkvx1w;q!)<)T^kt6EuKl%z922H<5TJIN~4RIUncNj3n zq->vk7Kw5@Kr|S3XlP57`3rQypShe{+y;m^EJS)`R_h6?AZx7u@xIdV7Y2;q7?a_` z9nM7#mC7ei`JX*E5u}c0)^1>{qD~pgb*BSiogRl7N#zMbC2dC}`f$zM*)oeSd0_Xe z7?(3cko*=kCKWmMx@zwt;>Bi5k%8tWYWSrfaK zaTfdX_%40UT@-{he+|q{}bc&b6XMY=|%D`GVxcXBUVZMsZjJQRbx!F^*@k@K+ zrBuv(%8Tb1C*zLkyL~bgw|BOw-ISk{9X(~FULRX@)HCIEE?jCD_vk$r&I z*fzrZF{_|A@GelcS0b^ZEiCWhJFrM!(*cyYSEMJALW2($Qw@}O`*W+R9C=-Nv!ZU6 z`qMW)j zh&5ACWSjFK-!9KNJOPje*m#pK`#MFexNDF#W9n7voNJ^XKi~zOm9@Uc_xIggzUndvwbN&&zf%(^}D^#i+Vc&u?+1joX zA$3d9kJeZ-uOj6f?g8h4gF?j70{QLkn!3*NS+#zxjhU}y>W2lpCoGZCj~;b$Mh=V( zx}cs|V$3EtT>I)DVdAvYv4Fg%Ed$U}RXwVnPQoa}L%nIe0R3BKk8+<>7_5 z@SE;qg1XI%^8iP_4w<>n)o5YZKe;$c*ZYW+y!3Oo-a&uI@nle$Za4nQe#ot{WR!}Z z4PDFI#=kgVEe9XE+ab)Vsi%-{#`!kfBz!Ck}#-DNdRUK z6z-$Rw*xWP0RtNYtG2npOZ&8Q%&#H|wumyLTltDF<-FTM5@k;CB#lfJ)=rG(!h@~M zQlU7Y(7aFIKrMmrn4uz*5t327@c3K1Y_ZNp1;h9k@bPDJkiw*2%VgT2MP(RrWQ_g; z(9Fwvtho)fDbd3NLFT9R2#{qPng9)(IAO!mb!B8xW40OCy0tCa}FK{h=8TaQ)oC za+By=&u-t@Mu$h(^qH5m4+CbGlLD}iaqP-Dza}kHLIyJVcPP4--0%4DHlh0ABg-S; zl?d^Roa5a$$T()`MvdVIKn>oZIejWd#bEMnq1cF~MSheNT}2+DlnsNiS}*knp0h@*iilM)2#)(#oZpT^|%LbN)wO@64up zy2o!g$sn{I2Z?VZTn%Ey;8SmU+%2CmB2{SFE8?d8b} zd4sz*^0C?@`T2e&NoKM6X7UcpK)I5YM)nm2h!h8sYg#`V_NQxqib&|lm(7c2xpADA z@{LYj@a92=r15#DcVlxK&1$ox`!oEdg8Hm?AYS-EQFi2zd*_X!R_c+1cKHrWlv+vN zAX8C$_QJ)4MFL^yryN(TU9$Pr%ea3mR^YM2L7B@U4IRBP{L=sO>mioPGjEPVMeqRlL83V5%1VzjB@lHparn}pqE4Y*H= zygmDp(P*SX00fn6C^#C4Q4B^`Ej-MDmvJH_G8%KoC9Vxds+*WAaW|NW21;KD0#7bg zHL=3>Khs`We*ByL3ftL^zD3K6=}*Ddcey+mPhzZRyDl15yIX~j8vsBbhye^vMxYh- zrK*&y3-+Q%|F-(Zh{0`MQodjFQ}U^Lema}LGi7kYV14)mCc4QR-ahmbHUvxFkIMA1 z3yYUDjD*-!YbckVW&boffPcY6J!_{A5RcXN>l)A_s%Tx?W9fIkFIewGQFK{U%Rvm7 zs_T5?AGRGX&sJd$X$(G5fuD_}mnxl-QE}`6KQjDbAjP(RbpyCaw_SRb|3F0Df)y=! zSLB{dR^QnMLqW`dr!T2Urci-fgR-h|%k~^>I$N1x;@S617yI<(=cXjpanNEt6_koF zeI)^ig!TbdF@ix3)jxXf5R$vKK+p1R*4-CLLWv05ktRSNVWz!zb#MV>6;Mh^?FoOk=zZHzLc#X=fYU5d|zTylHgR4QOUsCgSprx0_U!n3a^3WKkt_vKMEf9NXq=TGqD= zgc>*+(wgBd$X3{De=;C#WU+Q2srYhv8^DF+rqjjwaiMW9zb)gg=!gE7z@a}+b&oCm zU8;{`vU5Pn(<@cV!3{3jGiE-;K9)MVXgKA==vb}~e8vo0Mz2!d3*G$~yI4kA@BStR zi?Ws66cvCP<53)Si$WamvD8*j%17ks{9y9wsbI0C#!Eo_irSfC!pQD7Q+onIxesuO ziLKseH1Edp)wjI-PBpB%<=8dsrgUrm;UuwodbpfzSho%g!Fu2o1pd?sFW^_V;4g z+|BpbK1IG@YjPCLfD?cPHoy{Ub-SD}$Cd%$*m*I_Uz`s3sRA$`@XSS6=t6Pq4zM19 zMso=P@DLwRl7rsMZx<@8 zg{-e;AIS{UVLjU}e+G$QQRunr?bWuPTPQI-BNdQJU6eumTnAE>Ni!5s{sV!N7WP-B z$$ju;k|3Lka&nE5DMvR?1al+%&&CSm!-NLvJ{*2z9f}PE4*1sY)L)o42Hs<%o}qIJ zyJVgciX_3TKQ6<8w;y(FP5cLl$f$n`>Znffd&2I z_$2!U=d1e!&%(ggl7>WTZZj2)bE?5$L43s7#}kQ#^4iNLW|Y_DGEWVHhKvtS1CxA!lQ0+`%?TU&yw za=_(RC;=?x{WbfpHLrwn_|W|WfZI0b{Pf6$rh6ZK)ySPXHzI;=WA3wJD@A~Xl$<5z zmO%&~11(m&l@y~O2cDmQk59^a!KvWYDu&hpHhj(w8OA{JJ1cmgM|x`4K#{x@OXGrw z@UhM9?W+99o}fcd^eNc=2RAFYMFO;p>Hs7XM3g<0Dj&M2X8eH=p6ZP( z-l2U3B%yS;PJ3Tw8&5VSQe%rMx>$_|gDv0O)W>nvGb6Nv9+86A%k+p*BXu_^bl+}h&)9HvIu-C~BT!Yuh{i;J8xFcS^{M52#ll;$VdUlFws z`s2eN-|lYqMLm@KTPq{#Rb)$5Fvh><2D7y=f%F22g9ou~p0DfNbmZ2~^5l$KSbtby z8H8{SyHv01Ed3*^1Sxx%!`#q^;ksc865PvqMhn;`0y#XS=Kb~3MZECv{p6s^J`1Id zVOc8D{I4F#d@~X60FKpj!}ql(fz~ej9xG(qU}LUtc}D9>M0$1ZE=28sa47Iz@`uyA zrbb>WOG&ZbNu}n>zqycK331w~dA&qAiiV{-Qhkb?+Rh>&VMRDRZM(T9|0J$t49Yyg0{+Zi}U%iSkg>>{BJFZA5{ zx58$c$`?o_Q4N`E#K60%YOQWzxuPhmaG|e;I{oPz?SesK1?v_Ks4vNANw?%3&Z{j3 zq7X_X%HX_@L4ZDl7RSk>AIedsGRVgAEp8Hm|*m!uglB~@aX7aLyLbbe|u zy8pz)R7e@SZ1^Q@8Lh&onbsaxjgM-0df8`=p26Iue|Pz-3~x1qCHlx3nZ_`Md3sG- zm2b}nr^rg13sa6MB)ksGuW)Q7OGZikWac5nsli7~ahU~*$1s@^Tx|~p{d|E5*hj^S zSo;gTn(O}L+&FES;F+uWgn~v&>0+5?_jMdFUzN~zb;vMX6uU{#4vuQI~ zV!Q5!eMLSx@o&kL?_2j*l8JMoJw*5Se73Bk*>#xt03y~8L|;vdOhw$rL#Psc(EdKm z#LBkn1R!-Tq+K{eTDrMn+AwE{0SGMTYhY=~tHJ@lWtlDC8&|w{l*xo;p1mdbk7)+T z+DG-3q$~8V^)p(2+!DQgA$$2j4%9_473iM#Q$EdxZ@P9tB+HNx9@A8r?HSq~m2oiK z)w9N{CVEq$M-#Qk|Dq@3>de2v8vV`XOH$hvnXgTvp%ZE^_`Zx&#w)Cl_2pkd5&ZYj z1(gddq0Ey_yTg3jFQ^5BXIgLx9R>clF3&j!sr%u11V00dcM6v>gMifrOa|cEkb0Iv zt=1K{bcg~R;OhXA*l|ZdUjVqOg7cm$ytjIh^lh-+-{g_2f~Ipmpvb#NWrzp9joTD| z?vt91drz4C_|3ANs&#cO>Jj)DRlMKw0=C}Q0|a#?%$SYD#YjgEhkhSaJfU%O304S} zeHSfQmhi(-#YYCuGee_#3k~i7xSe{NM|{_%CbENPywDcelGX|YnHL_K5~ag%*5SW}KR$T@Xd8(#odFPw>WfJy$;QBK{D`ho3w!9f z-3QM=GhpuOhP^@&(`y%mNPF**n)6qJs<}m7c_Icp59zPIA*Ca-v4lZ)9Hp4iB+HpG zyZ$77l_aX$jkb<{EkBbZ7hOaW$#wfQ)NY~3113lS=ZXD^>ZUhX@I~9Os}SneWKlcq zLzzyujf0J?Ux1!V&d92Q=3(YTl>mO$Jvmgq27_I)jUE8PIsyZD4oh zIh*{8Aes%`614C&&#Y2XI&fVIV-*P3U*H*7-6j!ZI|4ReL(JFp#I-Lm=NV7nfSX>m z-56gyFyn6)IWvg%ECC?8BCYdL)MIuUO+0hXA?u?~l0m!x@1YwdwLltALJFP=@Ru(K*HTcJc9P@>F)d>2B+(NtlN2oXJUwH`eRpOp{s5n58(|S?X z0>)b2+g_ZqzJ2ag)Y-ceHFkhW+~Z`aU1%Fj5%awT2f?_1q~cl$l>zyeojO&!{z~R~ z&rfY%40#U$Wr1(6oLsK%k^laI1Tbu(mqCz&+E26TH`pP?H&fZ?u@EI;bN`ofjr`S9 z3Ns*BWTqi#O`^9f-&Zu&9ISS6k3!kk3j-!xxjNcBGwM;%gZNwM#4tFT(S9=>^^wjF zWRDHLs*^LA?*pDd1x3A8)!43PS#7bILE*i@rwoEJk>y!KG2vf?x*2>*o$Xg83Ajf- zwkhQh__+Ud_sh{EeFVokE(5Z_n%A!3J|0-c@|)tJfsBAx#EiqcF?|UrDRR>1gVgNbLUgv zs3|%qXAf6&hy{RqeH5sw@=h31w+M~jC9VF90&epYy!rzGpc(Oi=Y4F(Br9Qx!MkbK zgVq~b;W3hQ@U{Et5)5B$>BHo(zTJ{wah(z(a*m<}A0QCF!7VrC+6FKT>ipIgqb(E? zxj}brN2lahVhZ`AUjoqcu=BGhqX{!)*pnp}Bz+*1%?<-I>K>WN&O608LH{4a}63#&~; zTXg_~;#*o=K6xmxL&q=HnE!3VdF%(lbXC}pyuu-Wqu1-gPd6av&7!h{qJ(~+hbakL zCDoGr@4_*?WDtPFZ=W-V$NHntg&%24CceY%4(8+=kWqIDmuuR0Jq#_4H7g1g4L1~% z13!SJd4)$%GSZWjh)A;~SD9|5JqZAmj8m95!5ibIlLbvyS!ipkHlx9i#8rjqLf__c zxW>gZ+pW>5oCKTqJ*~ruKWwAof2r&T0_xkZDm_SZMkLN1a`XQm71T?5AlqjiRP~d` zAZe84LycCThgmt}A)KPs^1K|@Z?A4}je%p0CWmC%1`2~{oz-v56GmrP?zg1a-jsJz zYX29piEE8RXmy+)ukdwXoczos&gjJNND&`4N_9&;_fr`6b`JWAKR(V!ErbXy5Xhfz zwvgswMe9))C4O0df=TGd=pNLlQ>tv8FI&q4pW#;70vrCjW9_W+b_jO$n)c88s<8RN z`{n636j|~PuAG39hyVww$j}ySbZWviL?B$7JqM6OqibXB29Re|vKpf5rEl$YgBV9@ z^pCIquW(YPJpz{JiL1y`rQCsvUY0xa~!rjb@1=WRcRy?ADWR&?WEy=X?)G1`$^YsRue) zrlgu$;LWbmZ7y3t$^snLV4~{jcX4^VfLOCW6F#6RVlrMH=eH;v;__5 z!6YyAYQ-Pj8eXd|Byn>Ms(^i(bXON*n5OiK=?N}t(7tTb?xU8@tyC-MBw`A8 zKi&zORP^>f%x%U7PG^a1H`>;KR1zPpnE*iOj7UhqZpm1w@+&7Iwg7cuD@BeX;|WJe zl;4-pOha|pIi*j3a&u`P4&@>ktwb)W=;+E0nL`?bt<_tKG%<7p&X~MK*na3a)Gk<~ zY>>g-Lm0iak-W@MSf;voC4?@_Jp*z)?kAFI&%J-A9dNkVsxIZksH@T3oLpF}%MO^7 z3tLY=%TRnp4@X`3A>|^J+*;y?f(!n~MolbbYZwE6y8Q@QlEI`tjdtj0Y2H6U)k$Uz z0{#SJIrf-s<}=~Qo&Q*FD>Fe%CWPxhjD;~mB_o5S_VeC1tT`qr!9JY+@}G5^R_uCy z=z52F6;-b~JRGXi)-P7=>2Y6RYcBi;XsFfZ`G+Hy7&yh&BEEfd^RJ`RTyAP znp=&?om1YE6Ofjg5r6-unpdg`5^_@J0t$M4xikgx0XwI2$>{Y-{YCw|f;sMRF6@Gi zta8=^fNX2Hi3XGG_%k%eCV5q*aL@&kA_)kU{*B9>ZMFc11yPPF`~-n-toj>AoM^wx z=P&(~8us>NM(x^A=IcN5fSXfKaVUT!*)n zSAS$0r4L9OD@}1IdFM>z?nYJb1zh%xiku=+B4sUC(D0-Is8M_5XZ{9r$#d7-S2VjK zOENcR^KmQG)~J?XyvMBX!%g6gqG%XmTSIf|Ju-3pezHfe8uV%9bCtZSgd0bx`v}s- zT}_Jx!}kxFi@3wm^+7-Amq3_F+3 z8eWvKOyB)7-B+3kA7|$av@w@-bPKmVxZ5+PSajc!wk5=>y!{?Icj?O9pwh8NU=uKt zO%FKOFgfnRay6-=mdycZA%T5f9iL#z%JA-7R8A)m$b6_ajxXFI~?qV zC_Jf67ziLmB{Tp+NxeXlppq{}M0rb$#a9Z%P`f}`3hEsvq!jecgMpNDK>81*z*boy zbN;geNgx86*v3c>;eWNgfx7NbAMXP_Z0+pI!IeGr$~>*gdkpyeojC-``9AlDb-SK# zjDKSqRtFr6U)C3Nx1k_e$YlLq3%Oy%q;wzSe|xR<l( zIPXE24jxc~*^;MHP<31X(*L}L#CL7DNpu4jl=j@#!GHkHXlyE;a?4dpHv~f)p%=g2 zvgQmkP()r~N*AQ}ssd_Ev`>0K$`nm2QhPq>pnKd`QKWk(adbpAO|y7vhrBaM1q`ki z54t}jjk_qLIUbUfc9*nMV%UvdrPG_SYA{>NL)p^<6GI~xeuTq)U%_+v8^|$r_ECb3Y$CJE_Yn@ z#Y0|xkPjQZJ;O@+_{UOp#PtvW5hv8WQMv9E*UdRX;xZ{0+%sck%!^u%*l%yF`UXK} zaoU&9|9Q|PH{yQuje82>ier>iJz!_l4<2CH@*}^YY;8u4CRJblE!mH9$Wfdv!OA|W zoN{#0y(Z;5jP1T}pD7_Z{R!_d?x7KerO%>UVs<$b*HqK&UmnG|DXc4BELFgsyAZk} zlLfuz?DJRoq9#xC+(0@96`RC8g$N95f~&rJ_})$3urhher{w3BKw{O! z6E53HQRtL)W>?=gS=6_I2ip=A#zzDBtU=2oK!Q{TC6Y^4 zkYoz*Q_9x%;su}ZJf5v?(QBWZZc%LqFZ%x!;L?3FY*KJo8pfZ0c5-}b_OAb1Wmtt+ zm%j=Z!jr2SUJPvT_kxYG{MrZk>O#%$>dI)a$N5fQ=hpG>>G@DuJqM*-k9@pvLsm+e z*)&w&&Im}3d4*7BehUBkU-+6m(HnuIq+}ztubhW81bzegne8sbNE63NnB&ndwg>Os zJjQy?)X3eo7;43PcmbcK-QTH@ZVQS8RGXK=wCPwf<;qJ3xZr+TsE?Q4g=2)7N(}d@ z`Uzidx~uVq>njGZhSexO*b5C&lAF;H z$j-S%Y>TJ^e`7_cNoC0+tJ-E z+d+AHK4{R;e(J= z{Oqq`^3o5cQl82QlK7j(%^sww$}E}ZOc5UQxOMYZnx95w`}F~!3}7Fv7X?BtP)EUIz)RnKDZYYD+H8c@Gfny?(b0g*xkmP?`w{r> z9oQoGX~fbtT6kV)P?IhR^cP`Nf-WwxWg-4x89(&-ouni|I%}lc_x!!T*9MB&ftkkR zgIfSA@%vf@{fA(<%EVu_%)>>lzYvtR$3xdHg?0mf0wG+RYr{~uQCKF$om$eL|B0$md+Zg;$D-d3TvdC$b-;Oo zhYtP14mzQ-`}WXl;($?g$(!2GBuvMAfR9UD8qeM1JKQ^!7jz zMe^7_E!mhbz&m?uu=MR)Kcm*1VMI~Tt0ydGfpo}L1a{NlA>4BWX} znNa}s@$o8804ALx-v6q|`mR%6m(HDJr=wbH7X~P_Nu!Nnl)Z)2YNz82jl?_VJyKS@ z>W(@*Ed%3c56uwSLGR+!6pxs*#Ijoiyjj!}1y_S>4~Tn)Yr&1H>h6L0Vj7x#egyn3 z`X*=G4YlJpktKp$7#JS2&{jK8519|ywEsb~97Kolw@&(S@j3_?MN2NNVbYuI;Rn|s z4{v5*YFOt;!1Ll($TtarzkMQ4*(v89?>TGS_Aw&sLN=7a>{>4plD&5Xe&E7y&DQhjYXsI$&+#JsJF~~a{ymL4asF*wo{le^J1;#adLO;V^LWcLt>Y^6+o4 z_au8y$6;xsxCt1)Tm?XXG@xf^BRVFR>i8>D`JJ>{Ri}Gy5%HmuRBz0m>@kd+i>=Ic|CZU z6T)NZLu3vUGx_k{ySkhq+Wg;tHY(;*O0`5Ry#QEUGIIi(E_LJmZ#@sdD*05-x1BQR z>(LU(TMBMF9S#kPoYx3;U+*wp5EMMag7zJfqN=&19I=Tyq5GTpntQBjd!c&go9F{4 zQ+RjXO#>#UGW21NT>P5S@7Jnd|EgN}e7W$qY-jm}pIt_xYy(uV*K+~bSAUEZppo|j zUlzg3ME-k#+mUXbF`TJ7RunvMUhHS;kP#P|O8VMcXRmLYd76#M0CNxMZ=5c%-RD?s z3lBbEJHUEFI40wtG}}CTMmP5)9hQ!sCq3;`)i&19--98hdy%*SC-nxtI~7sdxN{WEjkld^@DDcmv<|nt-d6M0<9j)n6zV32ED-Qh4pJh=cTKgXs+o&Zr91G1{-ApORSH>tQog%~Rg_6#XXb z%GNYN;(c!sMq*lZx6+4KZ~8;bz`%O0qB5Xitto^{n~hoxN`5%`cJwhnbWTLh57ey> zz7I*bU!=im;14SI)z{*c7h2V+R*)a<^MV1&IG*##xx{MO8;etxmkncz@8%$j!B-JG zkE%UtDF|qbH!mj<$i^cIZ;L{^_fg}2S@AdMQF16@V3SxSoU<@pea1?;E8Xg-9T^Li zxHdrhEv^6BLK=Wo2L=8LQAza4|BR@ap)-|_uF^-IWAr@?rKmL@<33u)7w;2LS1L~F zt22(y4$qj5DTvhCj~vm@wRC50IT$pWApM(ojx_G&AXp!-F+LiIGrjsw;+6lMZe{WPh2z#vC2LcxN@0tP z2y=v5YfhvCo0-`y^?DUrxIhKdy22|yy>F47-`Z}=$tJCgjJZKI-7gL@3~o9EgUPAB zh$Z_yOVz%Dw_hPrP7+nViT6Z&-joIVa3p{ztnw!&Jo5bUlH4)3>Ga~~rrJg|j z^~l@A7wnU)nf5o1AAnt#-WBMz)MI)+cVBvP3c(yiNMhbz`2#%$rnw;Lc&nCU&xSp| z&Ci?wjW@iuy^tE2iM*lR;I-?6jwd`}j%w0CgX)H?En4DUw1lwmggg5Ub|jUgX+e>z zQh*2FQO1~DU=vp~nW?splHLgpKC8ym;;FE%lU$stXR%YEAr9pqzhlLghocpOCQa#L z&ajkkZ=|+r%Ma1;7huEBvL2wyTolCH|2-T!HCd^Z%U`Fb4li#`KCmU-h}q}dUslxp zISpf$k#o4u-uBgx>YfpHFKB;)A{ERZyFfo*RH1cqt5^T1Gh&2uEo5cr0Cg6#fUIxx zOZZEwjxuwGLF;F7{jn(NTdK=thnI1_yfxZ>)aNe0S-%|obUhe%*Nke4FMiXQ-sq;% z9KVunwG7#;CdL-Ou>8Ch@^QynwW#j|rAO4|wh4cSxW6=gpHmoLQ#mg7NtM8Q;g6*7 zjxjEG2noKqGd}p#FSeLx*TtU*>9K^T~T>SQ~A*VJdm1%SKyxB9kqZ%EriWdcwC^TU+1WdBI-Ir4E{%WjJ*?5GJn~@VsiGMnxq5 zh|9R_LB`1~!l9ZA;Bg>a!Hb!$hgmPUpFwz}o22~uxN?L~!6gakfJs*wu|LBH>u7+U zmoLstqmMH~6Xtma`gELaBTb7{wDl~l&bXDc@6wZ(A}4Zj94NVv{ShU=1kPB}?6bcv z%5~ugFLU%jtXshwK@_09IHzPWlf|l0+juGXtJJRyKF=jEY3P%|+WgT#CB1SB9rE3L zBPeoJYLZ#^=a?@vt;&7y*Q}OCyeg|SwVzAGRhN&-8oU{J#wm9ExO7bGV}jGqogj^_ zx_uuO^K_5Z;&F(xNvVI;-C#vtu&(Sq*YUY#3kgmiTQBw}EGD)u49>tRT_7DQ=m20S zAk3$Q=%FRN%=+&bB>MevQ19#57GUYAKl9OMz#&PCzgCSwA;)ATrhdv!gnve49C&xh zItbLL;-yt|xhAX0Npoin-w%sgyApWfFmFE#d#$^?O(G2zgze);gHhF7fTp$D)|dsm z`k6d8Yw$Cp!vdeD?rK$XYNY>ee@CT6Py8+%7~GQJy}nYqWQ6u5 z2#W4wNsWB@xm}`+{xN47Z>U%>{>JTyAW^{GW;R%DZQ>k3y8ezhWd`mO%k_UA)~!Us zvu)@Bhr^cWmFGWI@AoIj#x3ZVNYhc7@PPhE0|9-Yk?~tKEF@FF-`3GRNriVz#bZL) z)Vg+Pf&QD$>CQxZyX}XL4w4^b6Y;BxwV(9NF*BjZiJ8r@d-TOEggLQ&6FWXz{VoVJ zuHNX~nUrd57nFGd3WjbCQ6g1FVTG8)=RGg!o>!4hBfqI{NK5WD|Au6`2u=t^uF6SS zlQ~|v_&DpE#LShT$W|q+V&mS-3rrk;_gve8*N_rQi>*A^QOgK5fcRhOKs%0#^(R?bCB?gzwmxB@K*(DKSd zSB9mKe%7u-^LA9e_~<87u`fdZp1)aC{KQ8uwD@3LD)ZT7vAwDJAFG9v)<(H0W$*t> z&xEEt{+;gW1FX+~_wv0nEZYFFIrtXhkCDAr)NZ{WX9`!TEcba@#hcxHb)gE_xmbB5sjGX^%1IbUF)@_zfygb0UBi9S{i+J*fB5 zQt4$1{B^xpHQ$Cph+<=^`Cbz$GkX5z(hkNmPsMiBV9;O?->)qL{CV|ZP{gcN3Ay|w z#oTaE6#t*qY~`f~a?gJS8iNPw#7i)*H3qo&>_@ymTfH!O+fN-poLi&xqGFPDUunD^ zSeY4IVgD*ej*6DcBLT8B+oP%T@6>>oFSQWsSx{jA2%@zZ=%e$fsOZ=z$j<=ZM?Avt z`*~|Tc<(blX1wr(?{>)!F2t;+sjpu=|}cAp410TN=~@kM;e%>b?Nh5Ptv*9uVj@>AOXnlRhin z*36`47aeymL;mjh)g4$kLn-DW#uKB*!BdUbuKP~vi$tTIcBeZH)$=7!AeuSJ9K;JP zLCBV^vGi_E+JsGML_GC}lxYz?;VS2PqYEJu}bGqO~lO`0#E^Jbp=Ab7+eNs7U z^W|MWf7H zU1Xr%b)XK#JF0&JH7wO|;^@*CnM)jJv;cxYE;=wG!(lCFKDz0TZ=;f8n3>-Eazz^? z1U-g>&@#Kq$Wc$X+=_e^K=J41n6hvOcANlB1DPe{&)Jk^Q8xbEbju zNoX9;f6|bAWlAeugGNv!^i zU6B5J*KS}`b^b1B?;E*FmtXzxwwQrM=r#5pt^%E-e>K|U*yG{l`*yJn|aa(YU+C}URZxdU*{q#c3=Z^J{;j@%|uze8IK2N zGM8b~<}-tjlJ^qXTPnqYv6tET}6FyEyw5vpP?LZ_QU#SWCbH-xwdS-3dmxxlV!Bs2WArE2q{$Aus z^?JEArgpHW4`rv+J^v3RLzNkQk3^yz+|xm`CA2IVMt9^u-JwRrShpM`zU-r{cZ_N8o{4}9?bYlbZX9HQBN+MgiT z(X%;fj9QnZK?Y~h-7M(bVKDs~OTuZ=ZwI;nEyK3$7q=o;Dj1dw%E&IAfc9bj0edAZPhQP_nPG@X6S|1=Zrf z%q4b*p&_>(y`J{rb427kVEix%M5vpCg9FYbd^962%;p$e*0KO(!J6oZyiyb{@4^@w zpPHwryOv`^I|u?r=txN^E1E@ex!J9GVj{1xKA>;}`sSROBc;c(8aaND7Mks3;6AR+ z-++k>H9j((CfDzmuPIfxxcvI_jX^dvU=7SGs8|q?xd(Sl<&H6epo<|#8C8lY%^e|WI z20z~O*=f;SO(okfZie%qu1T`k^c>h#D`nR9nN=nA0sZdRzRc|GVGM3T(GcctM3 zZ35YoFg@AE8$?&LKIHo5|9y_z@>CG)2Y#ykN)Y*MjznzKwZyczogadcc;p5L1%FV$ ziLqZ1;9ZL;dR2he;|EFn#5T!2ljA7{m%();;m-6#wF=E7(J5PbT*b?9y~^X(k0iF# zz|qn*zbm%XB0SusBgNg0msE4&VyXV@1M^_bhIA&60}y{^5I_C#xQX-%XI} zQdf9G4SW9i`w_sw*0mKdgkJ~MfiAzU9ny=OyTAI<9{Ph^{w9C;ZX=WMC9W;~E7x%M zv|uIdxWqMb6G9{B3~fzzvr%-ekAS}Wu@k}3NRSMa<3$|Vncbv`%VH#wQ@ zwfi(p#CntnR3Lu&2$FbgjLa3;{F;+j<*a)+!>T;%&?y_{ zr@LjrcDL}N#lO7?#X){LeAHoP;mb1*K3ZG%9Z%Q?SQe4qEtQN#NVO7HMMYiH-gi2H z>bW%^4ip!79F1dm;#!MHd4(;V=Q!qj9m4BR0=Wwz3Gf+1C?L?A+j1i8^vA-gMsF=l z9QEz|Jxy@)s!Ud!-mocA*~5;8wou}ceJDbp+w1B{z1RIGiVPG9q2DQmbIF*alJPWz zV8wxU8f4a^L(Y*+HCFU}-XiLvnf6tb#!K#)%RO_Cam+TDpqEu{hrAo)|Nb@1!206W zy=j45GF7XS_C+m~@q`Blk?WdoZe_Ex%1!?9#l%=oi_ZKrPWL9SI}2}JEy-p(2U_P# z5A63vhg22hFT*O!505pqDnjVw?VQ0RI-$b!@{*su-u6f(>>3GqMo%Er-3N7VtNV*0 zAtj8*#|lad2M+IBDvDGV)uv5n`|F9L)p%#f44<+(U?ohI@|a!s7bkX1x+Q&%@>N-j zc`4ZF7Ya1W>Qr8_#STJlG3J=`ZO`fe;+^J~_-zET0D9D=6R#Y2Yt*?(v?EotcQ`L;PVg&G_bOk$0zqpqkCfye;`&dXBSG3K@xwpadNE*IzGG&ZPV15fJBZX zPn&mV26S4C1&8D$uGeA*>wbk9uSPBtEm%J%43;+(PFsW0lI`o}Kt-i|=8wAqeKp=J z<$PapY4p!fOAA`=4Ucz2$n+ZoWLNb|K@xFmn=C@TxCU0&8b@q(H4f(vttL7GPb)^) zGCTRo+RF1^;Tx4@b-e3}jkookA#=0pimg<+Du=W^O)?30e4rC_$yX4isblrz;lq=8 z8ycd*{61P9A~prf26`>(j%`)DW0iMA1|+f)JK~}bBqBMR{x@8r*4)wP->xUj3O%FO z-G>z)28;M#7O`SMTTFXnlzN_#@D%V^qAHtc*(a&z2wz&yz+d61dYKf^?v@VewS!7S zAxlg7##r0TR|!N@D=Hxs!yqMB5D}bsJH>-qnLNt9g#+UB#dqEAC=Qvf4LP)?njgn1 zf^RT*HV-nZ%HsUegYdan$o!L~(&o;Hqh*PrjKX`XF;*vdCFeUkUugN#a>G82(xcn_ zN5kRywrwa=mAJl8ko!24{VD1ELJVd^SvV`ev}BlWa(ED3=eZdAd0HW*^~Cc>T`yQe z4Ss;EdtJIdUPN`;HV8P{BNxyHVr%1SE$>+fz~W4sbSIHu%T6dGAR# zZj!^Qd+f&1HPnXH`%E4Dr{Vhu@W>U=dNd~yb>rVl>*1bX^VD`d-AD(Y8v5@~k~;>H z``_^mE9QWwdnP>pEJrhQkHJX0a9(>t^F@4~u183y^_Nqp@yD)p3J0Da2m)zbG~|D6 zJ$O-U8~b!U3pnj=aPLlBYrST%mTXWT;F)Bx4pOt-MoLR$CXF*!((dRv(pJEROl9UE zVwo6kHhk-X}oQc5`t;nqp{7#}^GJ~1!ZGqdKdT~<&y7RjX13aJIr!1I(lUO?*rfJFDbtqUE0Xdh_7D{RX)7t zi0JU|3!Bw1db}O`(c5m}BlCXg5oBlzG{cg+H+uxOA4yQTf>F&n{3HP1b z*8o0A-T6hy?e`=Sv^yw$_(b(JhgAJ?9~7&^uly17yiKO`FBQ?Y9y8K=3f)>N$E-6& z;7#|m!mBsy+y*@Q2G8o**2fic7AiEQk@knrjP|HiX!TCq%A111@!*LqM}^`^*omzw z7R9?(8k>AYQ&CsQuMndj-k{R;>Fj*eC?G zLG!WR7Nx=uq%lnRGzXr?i^anMUT-ndKrzI z`HLqsVsqg{hQoW2BUi6G%?@$q$7aJ5V-j~>7 zYiXB@gL!E)rP4j+F&}j94tqQMq0kP1f>3>Vr-v`K1^>Uzm;YOIX+NT4<(1!QD(rdU zs<>1hHe;7in*(!e$hY;MU1`rauybcvsWm0X9VSAoF8P^Ti_A)UKShx(#me&N{DjOm z0!F+8WlA8>#gUtN82y-wu- z^^UTnN5g;E-M`z@e>lS?eX=tH&FJ3OP3|9B-GMw}kQmc_jD4HscpaK=aO@!VLg2J> zdn4rl+C|sRhtS>`oxh&$-rnaKkvClwwF~fyEVRAgoEPb$2 zgrm3p;n#vd8_?N$2Efi zn9+3pP%6(!w5=7maE{zVki9dq3<$EW5FTwm&iZ%4m-v0JAx9=!ulJL;NS6yiE8u=c@s_n|gLhv~+ z2GgXhVflt49IQ?Yy1Y8QDH&pjZDRrx~VTs63nb^Ul+}Z`;U}?x}6~@?jIzu@%m0V_VEE)jw(nz!Ul_HOLz5(e1AX zAx!XJ9A+~CT2-7wTJQUY$zI(WbwoM*T?XtLOBZk{-P(}ZY^%Fg=5PDb`14WYhtjSl zIOx|&Wo5b^-y{ZHR<_aTrs3B$+2#Lf!UndqGM^M0wKFw6iaf7h$Zz1iEt{?*h?B+% zCM>WQ)Ex$X4?+2%Y+A^yk@DsULo02*&k z$Qoe8t0Uw^|0>hG)IBN>PZvI4+%>!ls65=M7YQTjbz1^WCoqX_4~vr${XX}yM;LG9 z7C695E&l|@ryg0yRlNOJqiI=yD1;~>lvP$ab#*UCb%7?|!zM{H82y*TjY9{v0?$TN zFaRpAgFhX0q1p;l_psHK3ff3_vahJxO->8e>XV$$#NX1wDdNE;keM=vwNrnAXc{f$ zU1-Jn0bU{-W(32s)kQ}me{b63+|}j#Q!G&^@~Bsf53$&zie&lKN=%yF_A{o_fm*^n zB=B7%eYiH}8-9I9Si-%&gV)a|VVn-9SG}p36z?wnt+Xax4t^{Gu?RHBms}ZV`e-d` z`PMTDg|Oh=s?5_;G0K@hJlMupe=6@ZvdYve-LKFC>i4}D2sSi9DHo&D+bN+uVXznl z>iNtV^dC7~#94LQGRVxNIxc8?0_A9)Zo`?5ZEJUx8Jb`5Z0h4s2Y=n_j{UHBQW&s4 z-;81MfcPr9|WyJ;rV2*yDn2-xRm*-;AGSUrPmKoWP^I~TA*%saHg z;sDxuRW3N*I|y%D!CUhzV*FVa|5^B`o_UA1cr6$dt~G0}Be|2?D&ZDAMr<315&o=s zkxQ~1h#){EFJ7pUbS11l>G`8>g!h)sx!(DKZ&mLKuPX|){QPOiSAle zrDkLIBFL=}?>e>dO{*sNU$?Adlt4Tu7mr2)bBiYU14ekS6|iP2sPtk+yzC%;2D`g> zz3GT5xIncT+$YK~1`a>A#Hc~e3%UMOc6~!s`uU!cyNM3%r$kE29Rw9)Iy3(SQ%_31 z=OKu)qg?8sn#t@hvx7JSGntT5wzN*RW{z#uk}U#=?cnWM`cnljRW$WaI~RT^gFGPLGFkXA zY=5O)XXfYHls{tBKE?Guo5GJ$5`x<{0GcK8b}g5o8G;s$ehd?MvsMEM0))@!yYn?? zT~8((knN_~lU4N&Bpt{#)rdFa{=;6bH*|`-jHce>*5E!vOs&P;glG13K>V2<{d|gG z8gYr5Z~$Crg^&M}u9EG3Q74C(dncujPu;AH6huTj6V1TMRa*#0d*!h^&eTl)(Zun} z_QO9gMcZ2kuN}J`r3{mN2Eq`k56btNf_7Q^JJ6PIz|%nYeP}RbFsHFQi7O?-ee!}r`VZAhXvWlx zP&XE{)#}rf&g;Mau=ad}SH1*YNxAnSm1n+0Pr6}u{EPJ$bx2Qg*xD)G>dhSvd!m&I zj}YS5^nC{GqTwRWh9hp%hprkO6p z%uL)rx9H=$GXC??=fW}NE2a>}WpuEutO2BFckWVVG((&$AOnB4CPgO?{IhKrs}XW@ zm%WKI++rGd(ebBEu`8$uc$Q0R8^ zQ$GfMy^O*Goy1=sC#X3#NN&urH$I}(O}Ft>OzRpBdFQZomsF0mg%^y?ah)ulA*OvB6fNIjNtbb%@uz&dT?*4;z^eN*Xoz- zC5Me%@sN;s=j`yOu7UGOLwAN-`)!4Bh*AEBrseeS` z{Cfw&3~)USegviLq`nHoQ=3F)-AnmuqlN7x1}x48uHn|JIesmK*EV5o*do~*Q0(Rb zglbD5Hmc25YNgFKPHgvk;eNztht&xrz=TIiN)86^^3lP$6 zZ}Cm_7Z9_OZjal0SAW#mx<1ZWtH3ZTe?h;GaoL+850<|Wozc4?b--elK!X{VqR(1a z@<%v1S(~fOVc)9#zQITuu(A*n7}?5tfIm3y|6^s(w$kIbx0dkz|Km%`2k(8Kko<7w z;{IE9!))(-6o;5KO`O_#yZVh3{02n|*;=JCI z*+qw>$K{_xq8b8W)_{P!2yxgu`}KKuWBX|pb2F-i@3l&^uZ6btf5r!%=lVkqKK~8@ zFY9`ck6*2i>-G)_-R_m|w$Dlr_Azw{EIm#d)p!=k(6YA72iK6|H}5@S4}9%8`W^?% zz(l?u@0hdxr9D_Qwa24!SF#6Fl9fl`8vhZA@^pMaax@WsyM?nBGr0K0_bfRU`y*+l zobp7*wl01w^;PQnwQwR#PLDE?BDLk!9MSsc5n?)fP{f=1Mx&ZiWkk$6%;v{lXw6R_ zsKozVl@mLI1fYQ>F=kp{KM2#tf1-VhYE3&_nUYAPXJ*2WB=1Os6Yqkvzx1+)DGqlL zRBW~pQJ5^#IAY|7T{c_XX*ZVtUC_69YXexeqA&c8JiQwLf3udI7t}hRY7d`XW&Lg8 z9%lDe0UOa8a{e^oxo-no_pr<7jWp*?8EE!Noj_jG9()tEfQr%blXhO)T;lavu3M#nOC(H=LSq!pIvaPo=MeQ48wpO#EHicH z25ljAwMikY1S7g%CxPXOj?qC?;&@;uk&RA0l&wYutrGF5p!XJ^!xS~?MWGPwL)m*W zEO%1x=CEu_e8>_t{Q9S={}Xl|X}*8Qv4gsCrim9}M4U;m3S0aSf$@0_b*pS_Em><| z!OWG&wlucT@4tNMA$I^9mgw*#{4WH<`t$cm@ue*M2{FvXKS}Gke@WNXT?vhC@$Z>_ zZ!=^|r4e4@pg+^4glP#c>x2^dpO$8$*n3B4a^r3*125sf!-i=K!Zg8g0wjG(^V0^5 zxfOrffjJ&Vs7`<5J?7^jG^;d^dM+YDChMyHy&xH}q-k?y;41uA^~P*d{U*x`Y~!>WT7{7po8BCb2f6}all*B} zV!(!gA`^pAeT>`9-?~nJZx30j(S7U>Z&^wEo4%^onK0ks`ot(sPd4#?egS)=^Bzg8BP-6yuRXLydok+F^8;_rvySq3rikQ2C(=j=(N2T~^wYCaUUg5XX-zLZU6(L% z^3!X~z6`>xwwkv5?;(n!*1uU$^5Ab1?rX5-qkSi))2&bBTr{%enVE%oNJ;f`gsJ;v zJsZ>Ff)hXLU-tMfKF==j0J@5X?caTut0cyU&4VGLcU{Pcrpys$G>U$iqc*VA#t;vub(?IG zUJO!F7lc9DXcg1FN1og%0cGqRV@oqLV(t8JfAclqHJ9jex!z7(oZ+Hu9?cBUv{o+fuELi%S)G%IheeJ7wI?uJ)pITc!`I*)ESLuek|@{O30pCLWqtLp z2nV;3Au{E?8}v{5yB&jY`el9_8PNBik*tliHqckYF!O+kLf9a%a=G);JI2lZP{7dE z6MpG4Cv_b381&C*mKh{R)aVa%75mzmgtVllZ&s!$-0|YzwG6oj|7Up=u!Lhg&bCqp zHMqq=7q*bi|BWkVq~e}@@b)<3EGZP1u%SL@e8E^)Fk zd3)>iF^#c3Cs&*Wz3U&;-t=XO!hr&`(JgB$kFE#HW+<@zj^m3sOMS`p(_5BY4(KxO zo@ntxl@yO$)t^5*Uh~ETRvxLsHMX&?KSBU3zMjdytS5<5TVNJGf1HEXAc;XaZ5yV~ zNYVU~yGkW7q_6E%g^lO;cPVl;s!eW-E=(I_bFTrtV!rzRYPpRh2g^y{iQ)u;@2?>`PNAW{ zt@OGaVV+o8tV%324WliBd^|_;plhfFiBJnek6`{6S4FK+g%+6d&Y*rT9DHHyK+sa9 zLHWuG|52gZCQ44dpHp#SpDmc5SQfhAAyNhGMyVZnw8Ang@Uvipq#;B+%|_5Yb7iGH z47)+4>9?x!&b}_JedR8P2-IF^=IK%yT=72(dLL`G=YLz*kd)zh0yW&_N${l)#V8VA zawG||ms3|ut+y~~Lt%7G8WrlLCy$>sde>gdA4xXfskyCJ^c-2PIyeKMVpYJ>%1CC@ zDcC=MbXB~}#wT{@41*JdNCuLD`P}uXt3hveelR< zJnrbxYymwNR^;O!mMYkU%6D}wOH!4^yJXmeE#dG?;qf#YQDyW=JJlCL@k@pxWlyK@ z;BcUB!iTiAr#M`6o$xbaHK_`Q+t~e}jCja?nM(%|hf}&i{6_ z0LVX0JqT1AaP6=->O+CvnDL(=i(F%A0ZNZg56K9>uS?3)$v0R9>QZZeNxos;L`*JU z!5P0xWI>9DE-@iv z{6p98#a5y!HTUvgwUB3D0C|>yM7~}%uO|5`ULN%^jBW^A`kgDMd~ruy0`fhG-eHJ6 zWpdq_2M6M^&Pj-kz^p%F3LLMry|2a;mK z3rn<4yJUJfdv2Rq8=&%ATiqElthve3H~xW8w?eb-G^kUhxc`SFOSs9ekpFNhTOIUo zCzcB=S;_s;jl)y9#{Azn$7}4AVL?cjX~+H4q!8bUTpONW>S2>b<~TJG_$@JXn}H-! z{s2c^Sk(*}{0U6cr+C)!wg2e$yfXXd9ZS8t?Dp9LO{2S|lyv>!rJS7D%Hwa|*6hc4 zZz`nUIQC^zVD1U?vki}&h_`sB8n0XTA7+#TZ@xJKN4uRj83@oHyRXgFulu^LrXPk> zH_~e_m0)2=!hf{RuB{*6ddQh)E(BaY?mwOs)a{D3-$;eeX;~Nrw`N&-FTrzXbfq)`R7gt)b2C{<|L9;V?r*WTX`c06aBK3!o_6#dBp1|=~% zL~<1hXXAkX;e8JodA&-voX07;(4LZafE;gSA73}PTX+rUAc5uLauwlKfP!C;k4b6hGs=nehVj*p3?;SLwK)GsQO)7+) z@Ihk}tStbH17wtT$8_0RVIi9hIigzv&#cE)Zde5A5NQEcO z>V$o{Mdrs$V_l|ikJdPwscHLR=U7&*N3ioJm>886Jk*cjpN%oQ%Uh2wf+@B0pFzXe z?cfqlP7<#L5(s&ST>FG7pp{rPd`p1czQNHfkXi&8I26PjqQ1rw7RGK!A`Sb$E< z%$e`9`!O(|d>gd5Vf@+u{G|jpj`B_M%Cn)<%mzF?aTERtF~xfK6-F#^P#s)S5(-Y% z9~n3Rno$GZ!&CxO0FK`m=~dRwqFK(1Yh@c#;kCTPSnS)e!m$END}p33x4sz(+VsTx zU1dnpjz3o-{mnAmxH%hRlh%PK>6#pnN&n_fW1xLMrCrOEJiNs{PyQMmY62{`3QB6D zGSN`T?bMPAqc+32Ra!zR=*ZwlYdAe1UYGE3!xpW8jaVl2w0=Xf49KrHLIwJg`J&2F zj+QBfa?fKBL#Sd%8Z2;C7yo%EL-%7^#2VaPr%ACC$_jW73E%VfbrD0eK(@b3kgO&c z64f~nn@lOy!Srhcp8Zmht-l8nPvn~Vpk|_LpIamyUA(IG{5yucYI5uk=TxVP?4iRF z-48YEbkN8^EyI-kEi(pkphp9wwjo>pck+5eQlfYtium{p#<{*%53NBUZqy}DC&~m* zK^27NN-+E8i&()`-2PX-WQCI;YGMO&MP>v>gB&Q4Tu{Nk@W<40V}Sp)tXT96F*}`~ zDOU?>@V#hld+j8sV2lJd!5ORQ!cF*f!^be{Oc%W{)7x1X@+j2~ z5ClQdUJO<~dSdl9k>NbkF!Hq6-Gy3M%M7LQA6ch+m46?5^t+vTgBhx31!>Tx5*Qj| z7X<+E;G;*shL{XSJL7Zuh}CN-tKG}v%@CJWz>eLrLcq@1$ zZ-evKuB6(07J~#l_dhQibP!!a^Q)(a?p)1Gz2D^CAoHj_tE+&9KoM*o!fFlGa zMtZ@C#Y|+3%w&6SBsftCtpbS?uR^u2{wN=~a#lH%0h+zC-+zq1GzR1fN4K(^@5Y3&blF00%6Na$ApF(0p_q3jAkV_?((Jg%FUld3Nhu?>o`a)QgtX^ zr5Nw4H2GA^juNrw4Plx&78I34pX%UY4#iF^{^;U}va-u-_C8Aa(<$`sy=Zv=@2xVE zoXpi4hyVOlL`7kTIPl}w!_4(6y4kvOFp{@V@U%smy1`~SW-6&~;-UlI>?dhYm8Nn1 zsmA2v<9d=#l(Q6ZWe6>q(J919l0i}6=nY`W6|7HHDA^^OgQ)(M?;gZ9KL6QGBPeKH-I1CChhv z!Q4Qxl*>7HTq7)ZWh32*mZJ=Upr!ov0z-cNAM6!KuXJqDGiRQF0TqLUTVcQ!dtLss6hz-MBQm0p=xKOjsz7`l(L> z4>|Q*^R>)=ti#&T6;`I=*%s$t4a8@MoG^-LVzNkW$u>*zD!yO#P9L!Gwenk!$x<^Q zEL^{?J~gye4GmLA=YK|cWB6ZZPSnVAyV(!AwW9~0tLk?ijN53gp5!N@W}b-A_-Pf9 z?VSSF-?z87H&uJDO3~cXw+4R4^MV zEgOE~CK6akFEYpeq}C~W%tJ-b1UtW3iU^NY*|gR*0yyl~vW#JUMnCVOM*y;zRF%Xjfv(zl=@>uMo^ zDo+ZQwk7#7hu=e9UUkfVlJA|5y>#fIa*&?h1PvFv3GHaeV z7_!+MbOovNMlP!-N)R?|qFdH#hPe|zZ+6JGNNpc1arb`L=0Y|oNJJ%kWrK`z%QlD{ z9%-!=&b*INQ;pxa{*%zQ+`cd!qp07K4*Z*rE|1re4X7Iq<+E=VyGBNXw)=^1&pb;J z{$pqf4%*?Y7ay+Bcx^FPqAb1u^WEJ5tQ-}>^h*l2hE)&r`@^gTUfn)Nrd4?FQ*xx{ zix#%MLxKV(bPcH^NVLt>dUQ_1M8&P!6+9(}+MH84@>bb`(%LCdIrS9QWx9PZsxsQf z&!uN{h3B(j<2Q5NVCD*WC~eeh5}BLaaSlcL2_s#GXsxx)E#e>aqjjoayvla4MW8s! zK`NkO_9L%w)PNa^Oirrgz4c%Z-`@G!Z(50xeQdV2IBE>0Q|qXy4R7o-3R!zwTL+%f z7}cRrGz=YudmsAJXp}9SghdpwM^8evmE9bD#(GUU z@IOYYP`VFcEGv#C;L~L4cCXzioP{p^O&h;qaG09e?pZ%8jH$~t)1}@UDCuc5N-@ug z$b_m+s{|bXuOWn4WUl1(mjTKGO1Gi!f1?J(Ffe#^Gk;(b@>wag_Iobw3pQA#i^M#XBORiZ8KpG zSkp&2`g-!BPc9C}!kZ^LaS?s0b+|e(QHL!3V%I6M7AOmAHn^=~VR4154lk?Xe>bQ+ z6Vmy>E{*wt0*mw^k-H8|mK3gAu~a`IHPq8+XO1ayuuEL+V*C%zQU0P#-Sl+wS((c1 zI}BNSa9?NE%)dCU=u$$BgY2QAipZ7d7T?bh{}nFY>_i6L2aW@`?4cJ|sU!-min~ZC zlImjg3z7_wY^*;8du0ZIWF+0Y*YaUyH-ctDF|t#z0wjk3YFw%+m+=R;3OL#SN723i zGu{7x0Do_0Hrs5>VGP@x&xf2Qrx{~TIVFUgbBIz=D(r~OsL44AArwVYOJpdN4l0$7 zC|#GDicgBG)4slc!u$66<@I{LpO44=d3P?f(fQs=$0=wmY|8AB zyW+EZZfA59R#Yqm!k|Jhn1RB~Uwmu-A6R1zaUn>Mg8CnLzhMs z4IQsP@cvQVI0AZS@j}3%c{`zH>oq{OiAC7JpAS?PcdoF7{LjPa8Ro=PNG&+p7U3l1Bb11Eoyrbf8>!n(3aGXoCxdbDpc?$ot&~%t`?k0)+_yTy=hJ=2A_9- zi`3)%i#azm`Am1F`I?8X8Bo)EjVc=63LByatCU0zR)2Y1;0=}7OkZ8PIFaI z9jm6yp+>6kDCrRH>?^WZ+$2478<26^Old4NMnb5Q8Q`zCTVe(ES{{NP#h+$-GCuo* zw@n2y_#^w{!d}ql5>5*D#xh`__>qS#VkVBVu)+cu;D^EM#qkd=@i#P+@;j4V=+_}{ z&)3iieFZ8iu63%tQuOTH@0yuvH4!#u>En$m3Lr{RTKa>0q*`PZQ17n z1$>|Bo&WJP!bqxy#8M~XR3W-p;Gphe0U!QIecjf|r@fBh8pF-fw)x;P9A31ImY8Oh zrJd?1m4y>v+-4z>_W?0uU(lWg$D|4x2iYDG!;fqdo|zhCPCqytLoDvOmN=HHuz<^W zw0W8SfvF6C6yzU822mG@-eeGQhiz2tY-DIz<Lj;g(G%w$RHp8 zTVSQwJ}D#~656{mvIKdX0V7*&J^&QN%~8qgPn|9C@a4KZP=4+8^2u>;&-Y~qHOuY^B71HZGARB| z9_c}}{44w!HU+P8KF($KEhVw1fAn*i;$+T8sa1Q7(sMi!C{&=k zF?B?@(-Qy3D%8s2?mKhbYPaH>fBjT!hoVw3j?kqk&}9Ei`gR=6!!lU+qKa;&NUtj) zevV7)?Qz46?$dFVx@|B>kAglyrl&48Dxk{0%w@!8%=u31IA)O4X2Hv)ycM zQ{#24=HxJC$`;tDSCY5p#2auk6|`Z*-z?qAkHh_Za>ojQof9z0Za>+cs)T?>F*t~? zM7WGH3IZQ22_78_#()5+QEBkwxe)nLk^b}osCX-Ccc1$Qqu<_{PG0^w3Nek_crX`R`{ew?+8lhcpL(DY^+wu(|w)#ZgPsKT~Hxal|-fBuo={ zpmuX2en}x5T^Jyh=s-*k1cAoPof7009KSvD^gIH0T;D%6kfb4}Ec58gm3v2^uOCao z8oLwrl$w+}+m|;FNg@4_=G}m99C4ztY}$HjU?Xr($GNdQsjB)*&VK4yBWsJZXJ{-q zlrE-2|HJN4T{yT0_cBX<=>$hXsgA~a!fb9ESWKO`a!*P9f*Q~id8=;}>Of)EJ!Ytj zc^bn+8D{%0e4y~(d%%|rzX5^LA5t6C>fb#SQo=2%RQ!}q%qKNt%0nE``lr1@{MysNJ@Ix_?3UofAQ=x_tbH8RmD|G$l$xjub(@;fykK=5 zvAh*i-)0z@tjMWI9gjoB8kr}6hcEbg)(X7GF&7KXpFeCi$(t82qwhHXp?HIDB;_D4 z^*HSmhwe&zF37l*2@V83n-&{Y>C6|+Fm2-PI|{++J-*#;m=^Jl#tvX(TW{aI%r80) z<;k!D07FpDmhab?XwS@yWd~O(V2!*$LWwqN3Ic|86z&I3Blte_*{n{UO;Vs$+@| z<@#5jtQ&z}H;*p^p!_Q8HQU*Iq>A_aE+sc)ox71;!gj>-*uve^h`Bu;!#-L_BEmn$ zWA6;y-#?wXGMK+2r=#GhZx>YfV3Z0Od13nt^bw_34--tcG*gBR)!^Ja&t>TU_@8yD zA2%R+CXC{FZl{ zjZjwq$#pm|_rnoX#axB~`hVxE_y6ZKD`+mqgoiwvkZmHh%8eq{Qd^UOSY^-wkDd7H z^*yO=mk;N4kIfJvlir+PuWmkac{BIc@5r3cFFOg6;kRz@J39YXOQ21Y?2E{Uz3-M| zuAf1#Yn3^K2bmt3ho$a$yxwb~{*^NdwLF(pk%c?DEQ#DN*>-U9XC1CB2R=!h)AHCI zaPJ=SgjneeJRfy%x=fcikpjIJ%#-p~10!}E^yY{${*lFo!AY+*dUnCpUvD^J8Oi4S z#;to8?<2DyiEUlWmawjVbE4dr0Q`fC6^6%{l-YPJR$Z zbbq$r)r7taZ#3Jfb9N&0^STtd_+@8QYkoW=-mr+MHM-||L^6iWs&1hqi(%SqM8P{B zraLsLh$Z$kT&V{d}D zMEl!}H}6gTlB(n2lW-3si!K?X)7YEiJ z@Gvn7!v)G0rNz*^NC9;!WjWh>OI{S2Wo(eA9>eQ@>Pn~HxAL{gfCPrStD;X_yDoh3 zR69FkLG2RN0f{*+aYswc7v;MUFlT}ip2B{oVGg^lwz5*KF^9X7=EI~AJ;dyzTk?Os9@-#no?A1Y zD7#SBto1Q*-jpeZXK!gJ{~-&i7$DBk_+3HoF3NhF>H?W3nT>|wQzTVk{AzZm>~*h0 zMd%@uH^m)_6eJui4>ZXDN99U)rnwx!Dac{^9u$_ndJdgP1HSXjd(T3^A2VPeqee{n z{PWmae%NV`^UoA@Z+yC0+fItusqRxwDq5lPeoZGmB-10TBb-LkF{wevXp4u5%2CAM z${1EfDRc?0boq2i4u<)a_F7Tz#ti8w`_u)uR~v!rpQn31&F?hw)}^;Aqxyd6efk*O zj;S?2h0|NO{xPiTJYw`3^50JdQMp@J0VrC1L(gbwX)0;Kq3d$M(nhAqtM!~f#q)(q zR?hoqkYule! z=@d`UhT~|ywi|}$w#Qqe{O*G~%KP#TkWN^w!`ApWh+6&hu3pQIh@TWck6?K#q*{xJ zqP*+)0k4>oBiFdQa*WSUGCW|r7rt|U0WHc4pgfy7992uLCtoaP{FG`#n;qc_(syi(iy)@JP5Okq31O7xnty_&jfv86BGwxLVI*4B3dH(%`G{c+Ec@#S=P={=Uu zsM!kPnfj@nRCUdXn_2cIMkgX_S%NNsDFAr+fIU8PVw+?Uts~eX+D^j75ooKt1+F1r zWlGHiu&4{(Io-*UVB$ql)3kxTOfF;0O|1e1VbG8uc-Ka^h85m7YQl=h{^9f0ot%#8 z*}CL$o;c_qeMv#o!JkbO9k`TnS~SN!7zNwP%zj9FP4(jJN>~y#`Ms~|OrYP}(^Qmm zLuGB)B<5<^(d|UM;TJ+)=M|V{M#}QgM?2bDX3J>U!wvjWzWQ4u+Mmrs)atbMQ<|v$ za*No*70MXdvONetl2n;9r8h!n+(GU;`_hq{p$YEIxGC9LU~^NVMF7}+rG59JUJF}h zA)k|Yhc*lcXK&AMeQEHt#Ip-@CX+YD!}6{aUT(N|n?n~b?yDNZPgs}9Ml9Y+pdsEB z$fwOH;%M#5w2?ZS&t2L3lp@r7BpM^-Q$Z;!8xIQp2O6A@c#!CHv_M%vqpEwTC7T96 z_1vI5S9A)pv;gNalms+ma*Q1H_d9M5d;zXzgc2>0-TeW(J7WQ+RxhP~@gR@FjT>sg zub^ZeGJZ#%7R6CN!tTRAV8y+RR}}C@xcxST*>st7@V<{|S0{**(kEU}!{MfL-}y0X z-;X!Bo8?|v#h_r94)xu}DRQY&xAu-iid&>173YM5s6C+wcd|Wi(_W4M2Y|}t0c)v46c$r(Zo15WheNzZJ$~AFPv7O}=;X56Qre`E&}xYIm5-dP?@ZXZweYBmpI4 zoak_=)Fj|PxM*jsIj32pxM}9%9wi4nhQ*|~-MPzI6a(vWrvZ(Me5#eXCUNx91(wwlm8U zV1?WUP&Ztq&#}-Sb^Gq+mz9)rI+JqkZQC1%mur1NsHLU)VZObv3uyOWe1BBr_l zg?Yetr?X<5qJ?${*cTG8GGWuPdu^iJ5#IG{&S9ktBIJ*oQgbgBfR-5#ekSsNNJ5}j zyrG;)3h$DK7xT@4w$J3K0R`ZUlkR(pcC1LWjvM(gGu$Vi*1BX4IDl!(4Ed7$t%qk` zy|@6PWy2f_&Uni^G`%?FagAN&!B-hIu+kN5$7q~tuLg72oAaUWm=!pp(fTLklpr-e zYv!e|RYRNid|HlEOzeNdXs*ifm(-r1B!L^Bs;Ju6mU>|>b$e(;tVxFlsvOo-zUon^ zNI-6g$~ar%b&h}Jkz=@5$C`kAm~IlUjpM`+o}+jv2*Ev|q(w>(s5)_d#{3=&lS9YW z&Yn`j>;a;v=L#E)dAs3iF-fz%B5cQrY{N;5&ZyirYIy#g@6@zr@mM(*(CaHyqHL zk;6aLf}2?x{SdA;@->riN>8hMl$`YZ(aX;+!Wmuf)N8Y9m#$P#WxUo3k4x~KIuseS zT_-f0_9k49fw^ad19>BBVN#2QtrDaL691=r~Y6vu;z~hT}9- zPfQW0ONSS22c|3bq54F8Xh`X_N2;6P4qqd77D((lyQxfVnY;kZ0d+}dS%sQOf0B|7 zV`F~Do0j=??xUPe#vC<;wL#z4=KEn_nCDJP1>id zysBIKojzQ~CW83K$n(Q=S0$t=Fmka^;cJ#39XY{xXU|oGgZ8=HqG{%AFVy58TPO`^ znwPm_&#i4s@tqZnogL6W$Us_SV6kRw*s{SGTB}?$oIN6LpvLWQ+;+bD6F2?zDH zU==%Fof!oOcpe0gvUb>xt(*=?2uZmu=Z#gG^DH3K^H!amDQC9p*>*BF=_XG-tCp8% z@V6{{7!z!6`LSR27z5DVTr(%ARUTZRBrmJ{ma1v>_{qqd8YurvK7xFH6OS}DqEhsH zrfbRB_QeA7*HfO*?dG0()5ZXo*hX}!u=m?IS-SF63Y#%B0QDL%bNxF}U#eX-YLp~$ zaOSlNEJUvnr;WTm7wF6uc<0Gj=BvdGk371FVW|8G%jkKu%ht#?%rtE1f~*75w$NjsL zU3(uwiPU_ibb5hqmiR;!Y+11#TD`bGvn94pmN9Hj6#X> zgb(Ot%b5Iy1*)Q;hJv1ACf_Uosb=}wuxbckwH3AEdzy@uc~rl?AHC`oJwA%e8Ax-G z>oeRv5+BE))G))Bi{9}BA&x?)Vj-b&Ui1huf`RA51XVb*?O73Y6~pkmV$7F|=rf*m z39{%mT1s{=tXdQLIm~zmCDTw-n29(ii=G1I=lhH-dfe#OCWZ!GP>bGk=tPM7r9?=t>5D~N&!wwnfuzRu5^ zKq zYvisz|Hpbn3+K%6wWOo)R5`PC{6!FEBBxmU$Ed(8{HI09+Pmo zuhRG%<>;%&yA8n>&TxQiDhd+I^%ho1fog4iSm*4VN5mKo@=6hQ50 zlqB;yKQU*Lw&eKQN+Sd}Pq0b`P+Q+pf6t;`yXW3mlfV%O*L0cOwXj9O8u~c)2Xxfj z;wCi9JLUI%=vM%!zTB;kpl(2Oke3Bs*`}l=Im5@09oc;0R}c_AQN7Pft8D_Q8xPvDl%{)HAy;OL!YB2`h_ z9IWhepN$4Q?t|HZ+!nn_dXP&oREduMLD@o?Uo5KJUwhh4*`h0ROJ#2@#uaGXY(tgi zFn*sXA{6v?M%3qdRuovDv?rqk5Vm58=D5d`a}zlhhw=w*E;LUFlm#EF8HBGKImBl) zm!y@N3b2kj@l@Fqi`6L>GZuJB+qk_T1H9fXELzqar%t|q5%=dNX|Zs&Dm9_32qQb> zZR}Xe$5)mEgF}X!?l0+yvJ>XFyB2zFWA%K*Z)XoOg~>X_O)ZgwZ#eMImOLgNyK)5R z^FA(}+H9oQi^&eCD?@`3*B8cesv}^WCI$W|*d1F(i9!^>R72rGX6{yd6!*D%U1F|s zLJCuu)62FSnQ8%P*@JPdQT&l*QQYrHLE-%}{;0Ou;2dn_JB0NB+{ld6m2D0fIvwP6 zG?997R^C>H6s%XG8+!nAMPcp+y|DLpxL_ELOjnO(ss~cQhnj-K8^GFTOqli%a#f>D z;dX2y%T;M%7!a`ig1j?mO2vr|GRS0%Zd&KnP3@?Tm?CYBpRT1+@OdpK`5lNiwR;`aw|eQh;%Od#f^PfLUH7pSV2Di8 zEpzZ6)=>W?mI9mCobHaz{SB|we)crQ5WE8&&jp|*n0^Gsg(r7K;UI_J*8Lr0W2)h%zqU`ZLzJ65op z30?ao>zctgW^FH=W<-&i>;X(@hCa6N5l?IwyGyMJa)W_FW47rB^T+*wYo1TcDL?3e z>~;1Z42BBQITZ+wA_JD^CL}!x?4Fa1XPdh}O=n~CWp4sNJ72D1>VH(t-gVpkX1+oK zvV5KOb%yI@H~ge}CcUV&>Z=NcIq9|wxp#Cc#cAa=UJbHBQ02c6IUavco_^%fLuCGZ zm}_wPiUO4W6aoeBm6K5!6KJc{4TOe34r*qaQVib-!iWu}s`5mbq(lFzI%bcJQW53( zF`0VhClygY!lZH%|Mw1)_)H|AX>WBXEz;NgmzUZ-Mo>?Y;-@C?HmtWn)=DIj1%%{C zm5u0eQsdvLP1nk*c_5yQM7|Si^3reC#l3ac83*YTA)=Z&JS-%YM=MkcQ)PKX0{9X% zB-XWuAJBn3J8CR#KBKqb0ax)56z4T-pTl+$RBRO6$}&-5J>|Mz0BtgEu`EY)$wApG z?pxAF@9MYXtP?!~%pn{-sq9DJbeRPRF#!v*6^MJUJM4^?*_(n`iJPjeckTEQw_vv- z%g&cnaa-)5OI9nM63i}PWhelZy@xSFRm-y+X?HR|mKgurrKw-`D5`OG3!5A32G{9` zmE*a0W9N7>r~SKj?uiClnZTrxsbQvWM#!7ax1*kkLoMa5JJXkmf0{ONd5A5skN%nTRr>>+^?&|855gsD#+e(A=+X^5Y}`$ zB`>$H=Z$e3dHT@nV|l@x)n`^Z7NM%s#v6}HJz2UDeC0#XsXd0fNpn(<^@V#@LOX^3 z{OF%m@+dAP?x2J4U+X7oT_JjWsGGnS%32UBmW{l0Seti)kMOj|+<=cym!F+8VQ!;S z)1^=bj|v@g<4u@74x}o0h=6xQD;z^=UII6Zos}JwEjW;)-aTikcz<4RfYMM#TOqsY z(dV4e9)*qcx6YJ`Qs3yep1$M{D-Vu#khj{ZNKs8zQU!8ZZZ7|yU$Hv=V>apzWue;z z{`SD&6S4bA%ub^+zo2W^%mwnXeA$LAzmEAr)Jv7NSQXur!*`l81N_$Upidwjj&!wl5^I!tU$>z;NCImIUCP5Af3NIM?Z|UVqvpOb$NnuA8w}*@D zPfUTCCy?Mz~CXKdGwh?pjw zcK4@N(bh22C8SFCd(gUm*SOfYAVLt8RZ%j`?Zp}BtZj>K4mg}qwH3!-dFrvBsK#(3 zk*#iZKrN#kbSt+MX^nu<$`RSCaP?UkbyN1l1?9@x&fyt9zYC3v`~X(nw9E=RX&JHr z*D0uJ0ycJFs1w_@$^lCSnf+8frD+tNm#`>cZOcVk4lBpZkTdkpH3k-fAB6lbNtm^p znm7#4HYu{#V&2i-&%|%YV?cQ@gDV*Jo=&bmSaxklD- zv;3*G)8Sj*atdBb4@CGf;T&SX$Xe~(a#x6e0{PtRu;EE5K|Fz z%j>a8L%#17=*F`FA+vtC^v}9*t@YU7<2b9obn`m<#*kO`+*!eYgtN%tb`q&~0K$qFDi z(G5kL#Z*Gwi=q07CvyIDLXW#VM^&Y={D{J<9}~4FI4i44%d%FEi%V;GA;$~EczIVm z@3tRI_LgD2klw6d$phTbgN(G3D~D5a^if}CK~~uK*z>LiKK!}4vMeJHxqy=|0JueD z3&E|UyR-cXL?5fLW%Mt&ZNySQG1{|S%z90rYwn#LBamo-_SH$oIptcQkv&SacYP(a zU-=cJ^ou{e3dt1&Q`13&uoVG)u8f*B*61&4DXdZYRvTz-&7CLk+NI3>Ix6rNvJ7Ej z%2D$!yio+UHc`%Tu|s4?Hq<;Y**p3FQ-S5#UXC%$&McLB~oR8M;R zRia3mBYbgvzUxIR1$#UuYxbH7s%2VxRuSmEm)&xi1}RD+OI}$}mS4x`=c-*D5=5E$ zIGQA5rjC&T5=MD4AUASy<> zhRz??MH?sCnlk#0iMP41+f^jecq}rHG(5llTZA*yWiQ?^w_m4@KNz`;yJ2biKvjwB zt~LGNERqPBal}L>ab4WaBUn6hud5avten57BSGpH{O}4Gk;>W%#VWK@^T(@#2@r1MhWs^3s;%@v4+2IdzQh8Ff}5r zD(;x;a@|nnAy(gz**$&dAButj58mOGf<)ss+t)5(E9g}Ih}tvjjM^#5;aZ2?iG`OB z=$jwQ9ld2msc?4bd3F3?zFkg7%Nj%bbdlx>^RTu41z3L^xt-)hTYeGolzUSUBc3Y~ zh8IdL9R2tnI4XA73Ih!$$POD$7{^1_O$RL^;)1KLdh7B>yYP7{yFTq7(d zJm(Hi67HczaMUn_Zy@#ydIhPmmgCP@AqW^M)(&PYM-^2}+5Udwl{^o(x@NdfSyyv6 zK9Q3bN|AZ{V$}8r0ZU3wspy^?PYFQ~vh}X?Y(v0Cal&Xsd)Z>M zHpMcKT9FN!8gRrY&$SXx9z#vi zvXa{;#}6ORn1)DRl(vA4Zk$+^&hPr2>>@M8~ZAasZc)#>4D*MgCg7U zz1Q&S1t)#2GIuHNvo(I0O5|2=MT|l`dk(!? zNc;|CqF)S%@1zxp>_Bd8?*YC0Jpz3>Bwb|*WANhiqYyyMB-LExO=pDKW?aw4Ix)xF zvqC+y+UjTFl(F{g(CuHgZJW%_8oY^>R^Ot^`F${_TzTgbx-SYmdQJaXAb6$c+0ws% z1Q$SjC7EXGj5`d@#Uwz6xx_;Mt^c-Iq9w2k87gI*Ebu=&W;xEAtv=cAp71Vtmh8&$ z-SM%4-YDE`KG#)n1G_$Mtu_!Z%Rh`l)XW1<@%!Ap&xl3`WQU-F;(6eD>k+x*Pfd?g zQ>XDKTeSWolWk5Oh}l--@^w)mZad;LAvsP)?tzqb=&%_VI(;qj23A_3%tW0Wu409C zcQ+E|qg%cHz)K+zoSFNMC=qTSr!Vttu>S1jvV`WZJ>N0^4#6XGFEHKv7=(m)9VHsB z1s~Uj>Qn=CRovaCnod3&PFL;RM>lxavqk~}Rb=1}Cy09|cR1;e%g}y{vJe69vO*QX z7Q6tyZ~5K@!Nc|dS#W3`Y48D+;s!T zrt<-T(k^`C6+L6~9iYmP+-F9rrVBD_EX_N_vrnF>bd)*2Qv*ajC}@pvcIT#Ho#JNR zrOM5Zz5!eTRG5zqPJl03Z$0#@`=Y<|bRO{yPnv}`)NK0LkkRoGt)6sf*H^dN+`Oe@ z^JmOY> zw{ju7z9{fva4=R|QwE#$QYGjrEZ@M7|FZNbnu`tu7mmmSSd6pQnDHkkSFhdU4~3fb zQK{{z*`z^VAkFW1p6ZFDgjXhV?F|_^nSf)4uAj?~05jdXKtzK?pM3zqw)#kF#8%qB z56D(L3$YV?{yNgcoQteLZ0_=~mDI)?9Sft+M45szGMHAvsqE~8>Z*hx#{08i%6_}E zUx=$Na;*bGEx11H-Xj9ZY{a}?0oH-WKN^1-)Ty+Gaw@r-WUA;)UH%a?&~`)=A9~>A zKG(SGJ9t?T>VcCt^2sXmQ-uY8q*4W^NvV!=x=t*lo;hT7tgsRuf_19NKAge6?1>i& zDu+|!#vaNi<0~rvX#1EYEj~v|4F8J)R=@xtfH=o*ABJZ(u~6ROwWRp>msW5E^cK|P zC4ts%W6xm%>ZkI}AwZEodVsY-)ldAyaL$|=FXm!a1eDK7aW+iSma0!3F&oklru>Tc zWsqpGFxetia52-%B>9W$P83>)N%|@9~?Fby&OIEe8ejlRbo8`1+CqMD-Sz z-lI)EX=e7d$CBf0edeO%26=?kY_cLlS+oGswuue!K^{+EUgLpq`pNBp>uYX=turm0b`l_P501lc~uD z+^uzF^yIWL+%vegXUobFsc{n60cW#%<=rPsu}`K>x->1_<8V@d=Y7#9{`Qw+4a@3@ zSU_vp=ckH&h(lSK<5|#w0Kk^@||XT~t2&`Dpx!gBw)2M2TN^Ic)3M-AcSU z-ckbojcQK%@Uq>ZvvTFvsk=y#QHQGoF`2dPcxQk*etGS-2L|zJSI`}r>*&?6EpgiY zoOkQ=_y4=(@yF;vL3EOwa42AyCAio#rac&d*(!iPgy2!X_f9bLhEUJz4}4Z;dvTkO zB>7Q#4sp;E5TV~OdT#U8?d;q>{+J^86m@^bB}>0pj(cv+%AJUvTfqSy@7Gyskf~S7 z!W~xC4-~(p^vE6pGJPR8O%>qY6epVrb%`tmcWI{R)T1Q#&44nFEw`IjTE?=b>(W-c z3!N$V{w;YYPTrSi{QT^iW>5t@7kA5g`Pc3@Zj&vOf-`9cCQD28E(0{b|DQ zi^7k^m6e{VLCzVFYms{F_bTlOPkD1qcKF$8ublxsrK;QhWk&9a-Cz*0QKe4HQA-&qoZfCNjU+7L8SCB{ z05V5=rkHE#)rjVpT(=`ZcN(u2MYsd5&704@Yz@}?CGXuZ!;|syUDDoq&l<8q9S8c^ zdO#9sVH;Z=3ZCH>IKIsGar}k@B}90Aa1OAVh8<8_%s!o6Tx#D}itVF*2O{>)FQt8B4VCh~Cpi%c=-uIL4b4{T~GAJoT(PHLW8i z0y6Bz1Lk#)mO>7OAhG8VFOCh;{ILRY7%wAKCH*?%B;i&_PN!Oc4dLyF9t!e&T>}C4gQQURX|ylsNpM_ z6~VQ8vbAG?kLyPNtSDbkx_=&xnbqCaL&Cy!VqPsbFKxEzG-xPKYPKQs9$v@1k}=nA z?)(G2oo%2dG1n$u+yNO=5I}e==7dMeXkI5;b9!hxRbpbNs$~?g+`fysH&Wa8EhN`| zr+q=+Us$J>u%aWte=y6iY($h5cXzYZ8j@%bpO60IqLa(i^B%lSTOo=ale;@Wa$$od z$-nh=YjYxyf_J*Lvfh=Li!W+-apZldI%hee5VOPM< zvK^lf{;ySE=E{#Lwp{cnU&ilgl(JCkrDj(`r>_mcU?{-6}(q22F|x zfv#*`&9jC1`Spi&$u8|%e$1zzhlo#6r|R~+aaWT#b+yu%|44GyV^voE{08Twt7uxqVTt@h5Sga1|5Q`F zm-FnleO1K{{B0gUJ&*hR7x(Myxqe;q@}=_QOBh_X&j>b420Hu!*pxDzlP2CM3CRpX z)U_h<*7y_A6f-A`0%-b0c2157I6lQp(w>8#&}MbN&_aHY#Ot%dZEw3s-al2kxE+_A zP3Ht4kVvee{i=pA}6DOlPPvWe5>8eKoYQ4F@V_fc#3~&SJ+U++dwi=t2 z+AWQnaM1$m7Asp|A-pg3Dd4OtEB9n$MC@79Ev1;1zAHOc!Buo4&U-iOaQvK~h88C# zEadV=ZwTaaIli#YcZtqlV~1~~=9%rk#+&vN$q_G19ApJLVA5UquJT{~mbNtju{i?#V36aPs8$avoUXr7k2sDL zyTa!6UoKrbv~-zu>c7t+80g>>w2F#JCL+NK0VCEy=0N=*!QAB(vr&O0a~W{P{(F*z zZUW02Loe%|AJn(TW9MI}t#}*)u8DN{UYhcGawZ@F@9-n}3P0`;uTe=@^Hf=IRE@{T zN=vzs8lz#Uh2THkf;l()Z7#wZrXii&&t}g-^nUU6n^1FO@FQ~D4M(wo=O8-iijk*739c%F3=DQTOk zY(lYW^s$JzN8=v0U?kY0un`dvY&NXPb{*flFCz8Ld+`nw?3KBInX2gCuEhgT@{<(v zeLGdG&&OK-{BumW10kQO7_RuBopBlT*4;6jB7biQ__?%m+WT^R+?(#8{pLX(t1WHr zZEovqb`fi;US9jk$ekEH>4aJjJLpo%nVxg1*pKrlnXeJ60`-?YWnk_9MJcpbOv*+x zKQ0}?x!crDL)hPhnL@;=A*CofkaBIO)O)9b%F38fowlg9^IIA8%gE-nMH93G<7TU3 z2%slbeuDwY!AtittZ?+h=5X;V-wLPMC-NHjd|@`EPu(t(!-~!zn>EWve)wnUb5Y3$ zt0G9(3sBjE;GU|3v<#3;9d=d|Gp@a+YW!hV?tI+4#pT+d__jSonD5Kt5wHv`P}nJl z#ord9E9pk;s+81@`4~AZN>fyqN^2RdX*62z+<$`l{xwvtyWRgzw>UhjPzX~5{+X2+ zzMJD_rQ`uQsCPydTKFqDTO;Xst&{NUMUd6WNs0@7bjMPfWEHizJNgD&oV1lXQC$0^ z*CjglG=$A7F1260Ln@8#-JaW{HX-B{N4IT$HX0=OnD&CbXIC^-zPLxYuM!btMyP*X zJbZ`p_+53PQ0Tft(=4zfac7g7`L5{J#HN7SME@YOfmW5%(}_alr1AC2G>cO7{HMmK zQcnJoH0ORQ(`Hv~GkRu+Hn>QD{wKX5ze8Gzx|0lWnly(cC?^h28=>|{i=rF$NLXK) zM9C&xRaIP(@=AfHG$o~54Ra?<;ag_Z;qV;JODu!}oYhHA==cWh0L}{S;M8?Brqe6)N4MGtTtcu`n7Uw82+) zVL}?`=$^5EWsafkq2QMYsl8!8Z&ANlZoM^pWi&4DpZI~8#V3YndPkPWi%SBBYPC1TWd%Rn6)4{VvvT(frohvCV-tL+sabOq zhB`U?x%d6Ef?}V&T?WxL*gxKd)i_gW@xzyaMfQq!N@X)>OPZ#TEq}XhS=ihOcJTm@G zIL$ovX3Wucv&~_G09uA_;Xi#AY-^c15YT{>Y~BAkH3ag)(($0-aXz(K_b}kEe8#4A z)jxiRn|jnbW4?isfT_Bt2a8u8FBC`CCYhJaNx`v^wY)+~#)gX+AR>Mr@SjYfgF?JMKx^G!FYuX1VJY}8`&}P80 zK-ahOXw%3iZNv|HUzy?>d%v8S5mdG6`adAr#vZ&51#2j?lKdOY{EBHZz6%Xo$y$yx z`0&x9C18gAynwrEO!JWBX2KL$s#|;b4CQF0(IaK z@!su`u%8jwRrp~Z^!;{^Z@P0qJ*ro_f#+tVfIhS^PFHNU6y-I(QjGv=WH|5&FNk`VR3CECD-vOB6oG zk(_cpE;CT);1xS1UkE9ZbP2PRpPhR*gHTZ<4}vDTA<6k!o0B@`=yV92*j^YfcoQj?dcQ6* z7{^j_RQq$Kd^c%_2u8FnX)l~$^1iYsdg(8%Y?`Iu=RqGjs!W=ntNEO4&@iw*V^ z@-*X2*pzb(co2}=n&QNgU4$sCfbXDLpRtXYX2~D9Z)qg#CVThN+rr?DM8&kh4ps`a zFQYuC3!j=QVweIu#YX{AjRwe2*CjID_V%f;9|%cHdU^7xd#Gs#SAo z$ZgHqqWAGH+Ib`JjATJ{+MvL;aqiZ4qAHEu7X+2H9f5_I#lff z%w`j;3DV0x>O$ql)-`&6Rs_-OaP`5}QK1jbMIR4EH z1UZzU*szb5pwLk)4?&m+io6g}y4}T^owD55=slf8RE>vGOqa9O1>&3y^=_7Org6Ty z_6R0Tz5irHGdW3cEWXICNi|fEKsj^`qq10k*;G8+qZajYFqWd`$kyK^cyclF+DKMf zP7fAZ`%h9ACUc{YS>yTO2JDqKMSeaq<)S$jly&N-*Dm_IwkFM2(y)!huRC6+q$cCh za=C)Ko<}rE>XNQjC#8ePyr6^&!n6q}r3r2W-WjgtJ7rEBk6C}^$Cn2zz&!7arRgP4 zrmR~Sre|{4)K6T++jKnMturRn03dSD^7+GA$B!M{S*4`-kJ%n|W7EjQ{u;=50f`T6 ziXF#1;M^deueJ*dN-V)g_@P+@^;PP`yFl?eBu~|A{Y)9Bl$hcF#{^vr>Ed#qLZ=Vd zr%sje7Magt!3#%VIQPU)ho9@CZ>i))P9Zcy9z%DzCrdmubdW#ltinGN{pZI*JQ{<< zgiF_~f-!sAGHt*2uHX+h?HFOahO$PPps(nfE~H!WBmi{EZtDR)=kXc4(h{(V;!7c< zWueC9=huT2e?k)z4NjLTm7=HM&?OZM1q#0qDo|9prOq()fde#eU=4{ zM>+r}>-~LQ)MjX|O1?33tIB0{P51ftIiZo(_IOtE$Bcd!^afNsiB~#th|BsaN{XS} z6%QSCDpycJQ!nPz-bnNV)c>euTgfKJZ5}vF8D|zgrzWeuqp)c>joW7hkHqr-H?2Qk z>tXg6VM1wV+l3mL7adF3#8)qGFZ`iDI@U%hzJ@qz_-8k>AmT0oM|AEwdSZ+s@tbMp zdurjVjcbOAx#287SoL0xUr4u4EIs~swQ$_tsm>Wv93p2IYeESfQF(z$6!YLeVFsyE zm2f@ccFcl$Op)a_?0g8$;3 zz2lB5=gLC?Fy_f$9Q?mCD|2azUS@ichWinbj4trhD>P!wjLSodt106>!QKNwo*cky8kLA&zQ{Oo5|sx zhL5quEi~7#oPMzuh=^`VLJ2t8FM{V^d3t1u34&slVwln>GS4-u5Tt*oWwJ^2;S^Eh zzfUx$JbaW|_Nl`(@|`Hp5l{1oSf;OoF3X)6#NYU+of`G#lUq#DD61zSYBp$%u+5zf zdMw`(iEiZ_3au0%UIhIlZN2}jPrA$04RxqD>vkr;@G2rHdx@caIul1)`^Nhk`#!1{ z3_rBj{TBe-_8OUXAJ{xOlDE6W7{2G2TI4t06J4(dRO|Hcaor*%fb=Qz zGV5OM<0DnKFS{%36N(jSsh3&Q;62XX#^#=GCv(-^4VK`(sT4A(Cq4e~W#S$`rkZH< zh8}zns?!R0yNs_OOx1lxAJ6rB^kr@{MvSGNHXr2D4ru_Q_nyqrG>h=fhqwHvhmi!r>8+dp zwZB*>Hr*?c+W6wF-Q!Q?{^rIB`Nh9wqQIVtu-(5*ExYlTGnib6b(_2V=udtr*F63( zK@{>7k7OeoxKGHlj6Ko*CTXRRkg1L)n-Jppevu=0+32pK;_}f-?iZ9I4UbCH>Fi|+ z4c=i{(0`bNz%k4C;h160w7Wr8?mWP5eDtyx8Z{#CZj)|R2Vo0m4l1%VHdDCI8ce1K zo_E$DoQx}Wg9S|-d*Nr5Msia^j(nt!niqR z;k6Z64`T~ffX!5^lKQEL{|e@S1btp1N^*O~m~MBgWi{bX{BcJH_mTnI<~%O#0cnOX zs8f^;xjC@BvZ|*x?0seWn-E4bJE}zSdn0PRD#71mmZ~lPUi%yA{@W=?~ z?U{djXqfHh{Gfr$O%Q55wL4$nWy6lJe}8ft@aT^%Ux?nXb&6wk7sdbbvtNO@?&@2u zY8$?&WU%g^=yKQk5~y17DSP39diOu_JkrfP0lCwW>od}BH+RV|$m>r#<0|BK1diwV7!%t<5DuRX#9 zwCU6%g7sy@A-PwZq44*{kBTvG_$Mxo^Oioi6}dN2JmP8Ha$brC7gHC6Cl!~-xWR?H zK8T(cJ8G%+!No15KptnA(x4*vB3v%uAkIvxdmG2cD^*vya`A?ZKOJfPS+&Gf)~gL3 zSv_yO8_p3`iEEO!1!O7Sa4&(NQvl&KFiTdF;fIP!DtC}Vs8owDR6Rx!P%Lthvpsv+ zMb8fgUEY&-(vdFb#GN=rpP4jqfTbc2u_!=N|a+ zuSGDi)a6)1E_6QFr%1R9eRjRx*jox8kn-hqxH)yO^^2Bv7Ul7o8a~mVRH7cwO2xn% zV&Y-$is^41LBGo|YD2A2S%2I-4v5&0GK^Ij#z$MN)jB+2a|J6hCQ?Um!>uUX&jqAw za>Ti}i}cfL6Z~GMth{DZuTlQ-Q`>W1`hOhS_P#jJNuW@U}dgbh`X1tamD;EpffTwvb^`P}c3Yeh=O zb2q3vXBG+5K(w_Yts@=wDp=Tm0DzLGEyPr6anx<&gBB>4QB z$fJu46EIV%nhxA7IE>#rvH4{72Mw2tc|C8A}^GqVf#hswT& z^Es7kkaFnnE#Opjs0tbh>bofj+yu*^TcjAl8+M=Fi=d6zWzi+@9!CcNpj?=_VDoaX zA|y=9jdm=h{3*Yp#90w~ECc~*KDOhvRhE4j>6x>hjqpNg@Z&ccucY+13#fUg=)FUs zm0(!svlkt_G0#jZF{m=ZerMqR{+0qY|LCV%6?ubOiTMt_?8{@cG+|90)vggO-|fYmn#a(SegA!bQy-Kt?+~L8N-_IlE3_Md{A~Vm zf_s9ihHQ@0S@1p6C1L{H`+LEA{o8U7aiknSnYHjb5LUpktrnl;q@;%+2C>)&JE9hu z>V_f5B?o~DU$dp>b(e1Qey)Hbz3q&V8@=%*N}FfiZm$`o5Zy}}POdYSN&<55WuT2$HF@yc?Wi1{Kx$Z*eI^glq*;)E*5x$V7jb#kNSBZQ+y|Ea|_xudX1e`Tz3L z$o_G+OtPOx02ve=XYf&PF917eNm6CLH*xMQ%pkQ7nU_(Iq#B0DJvo2~#7%icZ>OF= zzLocNE~Oe64SxkrS3j*hzkkN;zofV{U+cbXVpeJ!Vah?kad(eNwdqcRVCZTAdq#Y; z;h32_iJ}TwFK<-d;UIkv<{+qY2qOZ`v{O+{Img-^8aWn;5g(zvY~kC;MEx`;_It0f z@%;o0M`CfasbGMT{H&uP$FZ>DB0prc#?iC~Jf6#!yGV9=97LQQ_`7uk6-))qSMU+l z3BWcG_?hyzGW%oTD;|`A0AN@3ga2+7aH?)*YL6Bf2_i>Ffdj$6rSUSGSdzxzXzQs# zL!IFb+Su@9l3JhPH4*8%(qmb}651S(5Ax0%g{yBoCod3ir=Icx*a7P{3nvn~)k?&j z(1<*qd(dY<)T(_{(l!Krv28QjB{Hpq z!u0|GpP?AAfXjt;iB2*1kRn6sD4Ox8^#r*r4pW1-FVGDF^(%1-B$fdlXLj8?04Q}> zPudJASp&C6O{OkrZ&wEo$-j{>e>bp2z6&4^MC)ntA15jEA`>FRlFyCsA_pY!ojE}V z{YDe58PxD8mPwhxYYr%qgc!4a15rCGI-uZkxg=AeFm(R}^xT@(E^wP!)wx~Fr}7So z2B~KNEC`W0FdqgKdb`69I*pK#;!$7}_y-`utQtp{yLw^G^3x%fb7~hKpIVT=!|prJ z1w9^V(pD^BIC!D%ZM8HaZ}YbD-9;*i=YpR2wx2eHPAON=yYxiX#sa>_6gkCqFBe2K z%dyj9R_GAq?Of1qmF-3efg6+`Oqk(mWD4xT7Mr>p{p=zQJ8rxMOXppCU943MuCe93 z$nB15$Jy6F&%5>%SKJGe(6e)KAWQN!wkhqV$JdFDR9tRoJy1_}eAh0*HNXi7#{-Mf z=ThTboUChvE=@AH;@rr^9gwy+au5D3)VPBy@y6b-5f_5cBNj#}IaCsrhkZG95~gEY z?RBGUaErcu#B{hVrm%b)7Uno+gC-R^DEmB8k`cyMFm$Q2(m# zqox4EW2bW?o4%O`nYYt&rcQ#^&iS17&Czvy`{&N23*w+}zl&1c$ZD^OS|Lfjhynm) z^}@5d>P9?_&yX6hj=fPAS~Ng4t5Y;@jJrcq6o}y39qw;vc1QKKprGqgzYyp=8(;on zFieo&U+J?+n1EUp>N+c7WBAdj7nOT&T@N)2ScpCXZA2t`lq@*??`6BYRMRfcX91dF zCemT_P>$$Rg{fJwNvIEu+cbG2s;Xx1?Nm9rj#Vrjy9UxWvBSSmbau-`sT(eByuO{= zFBy$dx>%H2up4xh)E|Q5Ys&w^ohB=7HmyR4kaL~LB|!${EFhfvv5IrMpn25>$5)Lg zkWVGRl?lhgXt4Q@C%jD!>I)L1&k_Kw(^Gwh3Siaa0Z!gE-l0AozScBT#b1;%q*l~$ zPj4f%tE)m9(`$v6Ak8SG4JR-P5|d&i@b}ou)#CSV(b|%+<^Bbu*X~+CkDV}A&~CqC zC^_NmsELI5$w&(Ah1Q?1$2xncZe?Dn4*+?069u7G}>7#l=f$7 z5#W%Ii5`8uPU~3e#H8s(WI7F%Z*se}-rlO&nfF7SUY(rG{tGRY57B2o(#MBiPUY=< zFF-+vFLhP_g(>-F9iqqlMwbNXRPgboDWCS>tI0vW=A#d;Zv+Cp-l7Zm!{>My|YZ__Cz01$=61leSbnQv|NG@)**` zRVyOCWHM|l)uI8un!s?TL-aj(b(j=Q_=LRd z@eR?p0A&xE@o%~1PP||b^NgjSVJ&00i<3upTSN#&Ji4pYfuvR8Qz(e1M<7^5<@#*X?rg{X^~pTSM~P zSQ-Z(we(ZQ=sLlQ8icEwHYrR&7q9y^vg?3*2T?l@L%1q>qzW0)wzRgoQ{UQ9fOa03pQ_p5%nfQJ=tgD zn68P~YFaX}C{DUTq&#yMWhkiafAEK{U7G9ikOVzGene{c znBd!=3nJfW2V+(H7+?5zHA@PY_SsszysXpY@kl*5-dcJxioUd|0OMQFhAGfRiU)zkAKgg2W?2z241%(q8Fm78O4wPnS&2rGo}{ z_7Z?S`L(+D=Tg&_t{v1?kcl5jd%K;u3C?PUZPvbTG0w42fVZWRozd9<*`+-mDLSy z{vIFe<998WtVGsZ4UR-EI0c|Cy=Gv|P3;Z_zs*r%d}K*MXJ1#J5FRr#57Yha?RvCE z)=fSr+{yVxVr=g6ewnY+S8YWlRvA=v#dhbYT^rsDgL_o6$TltoBR@MnI$MS!3od{0 z+h6L~+YSyLin+yldc@C14UJVpmKH-l*VY$W1!J?r(+@gQleS^6tPB_BI)#t4XWl#; z8J-EQjbVFQ(X& zm!(AiV@i4%DTJVjhTA%B_?#(eUWG$ySovcI;4eivf}&Kj#tPTcB-6fw0zoiG=&W$G zS`B{0p)5&l{zcaQ!^p$_#pm(Yo422GU&wZqSnkl+#{K61-K6Hjz9I<~`$7E)rV!%A z*kW9xSqE%ofEe+Sf>UgMTib4Ur%ObU10 zYGT-_t@7Y*|CDl(zL*muNafpNv&jvHuT0O)fRF(KZiEI5Hrn0-{j*m!mx8y}#}HY2 z+*2C6M`HwrfU)XLC4*g9cucsD$R&Gwu)@u{AA7dPs%pf!L)XJ$EA17DD@@{I=oAOm zrT;+W+HT`L`DZ0RO%n2a<>gp{$tQi~pyjXIQnx{oUxP$vyO9s_Yd7bhn_k2SC(;4t)p~~O z>Fsy>iMsgfVN)5b3NkwKi+G)HG*f`*f`JOdwVD?n%D_NNN37xvANezbjb>$M#V5!& zt0f2{!8I8~kR%x@-f2ykKpZ;1 z9iGwkTO&p@=wm?+&aMaZa?`6evb@=zRxr&7KTEov4yq|dlFRo6pX(o$Y;cWC^sqkR z>QIIyh~5QZ_!xd|5BPoN0Q`;^n>(KruFV`ZzFKf(Z55dH&?{rUdzH%S1gCr2cn^~Q zJxsbk^9+3ypM!rQiBx9_OaGBZAHlugdcZNafIYW%1k@}Cdn;^5-kRTi(XxNrl5;^a zShL5=ik6x&WGX{44&MzyYfD81DW=XsR`u)RPmBBZbMtsA$0miR_f5^6aqkw|ED>&v z?vHDXZqY>q(fli7Asrf-7Ox1gL$O)34ylEMie||(iQVlKw+7>~lN6(@p#l@)0=Tq& z&ZY3BNugpR;h4{+ci`}RA;_KXWbQ_MQsgp{&PHi+m z)hI&>pP&w~B!b<>bhuvc!VWScSaZRPZedt>|FaWIZ>7bGVKE5l{+HrLSii12y9P!> z35hRVn7%rvIvhZusTjBT(6W1;xp(`Str1DUaB5vlrA?gbQ1ey4?QP$q2RE?t*USd# z3Yeo)=*L(yw-|T-$9?_rZAMfbUcq#Hp^*k0ECd5^LAxTBRrN)tq5spNI z${tKI>Zii%&?k4eD{}h;F=>J=7PK-e^6O^Jr4|1Em4wW4mQhKjUP0U*4&`4kgNk={ z*SXfW=SYAT0hkJl{nANa^~<-u9i?Rq|O%4lyuZrO)Uu#uwBJ7?aBH~k7ahvr5KxAJm_wVx)V^pk<^^jKTBcx^NW;>w&Y&bB9fK zm=WzIF+iszb}#Y@ya2G-j-bMw{a){-=iK2wojT5LH-fGbE}NQ;ev@@fnkn+DX~x4v zAn7uSBE4!`_(gHv7k`zI&?NhQA>9of>S+PD0tc1(bu9t5sMw;ZKcDOqf2VUK@RyNN zQw*OT64Img+VstS9+XCRm7rL?q!AYQZW^^q+N(YD>MP5RwmQnU1RHnU?XPQ_RyI^f zda<xlcWiXoMKV@p4q-p@EY2a=o#-nl~jwL>2pPYb6`o7ms7<2~DI zz8BsoR1lk*SlB+s`@+GP+%)y7T;n8c_`X;-lf1CZrGiM7(n}l@R{Z<8`s}0jrB-EKw-i z6*+e8ZV>c&SA(sVg>E5s05nSU4J-mE!|)P#ZBJS%-%@*FBFQ@mrL`Ve&YDq`Md+<< zbWQw^t#B`-jngW<<(3``~|(ecEkn z)OBm`$dh$vm_0C(ZCyUnfr86-R!~88z0(Iy!zahem2}Np9xLANT;aAP!}o|p|H}l- z5)tgr0ew8L0m>eHQ@FzWP30r)5kDMb%avi-M_%1cGKgG>WT+C}g~74WT7?$=+9_yj zDE}2xxAUU1N?8E0bK(?_FCoYG&K(;JyFq!FpH>1u`M-*KEoPdX<@WCCPIO_McJg}Z zDW?dG{7wW!EOvan0{BU8KRl$li5RqhIA#IEL|ZTE4MXND%2XujQ)k8~c?L!Z{_(T! zf&IWFGrl&yv^dk&QJQ1QJ%t`DHUTN(1G&P>$yvMU>y=AR1F9|vjzPgR zkjrQ>h5GzTh@5dWfAf7UzmPKrJ@j2bx6~ChbHR6&A-PHPM@Hs+rS1xat@`90CTrrQ z6N71B$HCWfI!1o2#dc<^@pkp(bQPKn`rSg>>w;rx%gUQDka)xiW9j>i)MCbva(CazoB_0UIT6H_^ z79u0|d~Ej?Kl0;2PJ0qF1NHSTKKVRCq;m)`VqtCEzRb)_p|@rXF#|YRNV_&Mnf?#p zTyja?-p-Bo{uGg}d_!gDwq2vy*lmHlcGww_gbh~MuuYJw&^}~3YFZoR<_qeK(VO99A_8u-^Snwn5oB9B-ygLP z@+km%W6xO_ftt~^r{^>wJ$+o}ej-cJ*Oytf1T9ltC?;6swVCuELQ5_I;f&0#?iF+f zZWb&=PUDMASc3=tTKE4sY01KFHAj?1%M-X8YDMykdqC|Z+R7iy?ntSNO) z;f~rp-@D=}e>{$IHgV5%aaQ55@FR)E++76#@k)ydcM#9tUQ`CdB^*w>R;p=L%a^9o zK5~f)%@+o`)(qKOXuYq-Z;0L6j@h)Y;IwI^(bibaXx~kz`6hfk$9}*Ryc5GiJA8`e zZV6|Zgg}jewa^#vy7giTrf;e1JB(mD*8d{zghG|k&bO*#jgX+K`P@NSSc10dFrx-4 zIzTdT;b;rc)p{2c;uT4(@aa+{ilS*k&}LDcosuV8uUHNJ(UST?hVm@ZQQTmn*s?FF zh;HgUwu0uj!?!9TVwf+=`O^oe&xA(8XQo3ALZLR&iIicbHTDL+-e{Ao)CW}s?L{uw zaqNo5%`z&JZ@4AYkT!nOO-LlMTL(s zUwz{esAkS98t>rc>6cC52fZ;$hBJE;RIXoHgTDzQSc-Gu;h8r(ZxbXxOk-nrsg{P- zb)T)fT+p>A2Fzo_jR|dIJP0uXr_xR0TjL?!Hw?m6tP9j z?6YkrN`r)qm8dZ8J@07`Nf=+{0?Ca8_Rz<41M;`3#R`-sHN>mHy{gT{3&1r(VlD*cT>7)qF8_s?YNt1Jw<1yCA^iF?` z;?lWgozSHFR_L;w@EZbCvzMPRWBF!j!94n;A97Y^Bv|c=`(!vLllt#sT#W+F9e<>j zwSW~$@d$>r(h&Y)!)Lv*qpxtoMpqa1Rg68?>onQv$?!TeR=5jRy-&?`!7OT1XC2e@ zHf~!V3KJvO+?C~1gn`AK90|aItWb&1y?=i`$ATU)R^%1z^x2>W#*e3FV?E4seWz>2 zAMD7}Ol`o0kZ2EN6QU6tOUW*;fd%)pLq)=M#CLszz?>sF^{^BC)!OzN*5b^jQQ_g~ z*JnrJ^9fzQ$4s1oCo@?(xvzHlFGI%uT1!JdoLiB^y&D~Sty_vH%sDAc+wt#7>!p4f zQR)F@S&Vd3>Ux7fWHP02R|l7}#vQdGm0>^0r1=%$YO^s*D7s9-)CfC9-{u{?ZVeZ?DyIOD;T~5u;2!kRtw4$R>Ukfg#d_M_i2B8O6QXmfb3X36r>%EgjI`!HS zxcdskU1mM;7XQb6an*e(QTP7V>qlh_bc_P9`^h;~N`N5R-{_A~lpPT|~U$V2&SKhRR+D_A0y{l2+CX z3hp0$0yUirXs`XHVEN8jWpM93*8xEnQLTmO?K}HtQQnmr1hb%_`Y)^P6pb7e{w=~4 z`r2^8Q)L@!G4Dg5@=excYjSgpapq4-GPMvAt4QJQ<=$q>Ppe7K&!l5Y70aI8}PDd#J{$e6ZqZDhfgy=~O zhw4iC*Bol!u3I!r#{`@>@Y9~$Pd1&&*G^oJ-gbSxc_+1T*Pt6tu=0fK)=Nyq6~l>) z>zxg^anJX-Dos@64s918;EybZE|gvWOXrM&Uht=QbZE-7dDS2pQyP2y(hCsYwvm@{ znw#?96mTr}wog4_5On2Wdz__WU`PaLU4zZ6PjYo z3EKDjCfS)SY)oHE(9qC2%xVO+Aa2^GX75 z^*aaT_zT0|3w3^X?%#&|2DB4zEB}z_C`n&;n|}B?$6TNDWyr?gHqO>Z741MNQemV)BJ{05Bmxobc)Tkju7~}1M{cso@ z_qt(*?t})WdimG;Lt(&YDGkxXQl&? zr9xO}QuN3J$Oy1$v`6BzL?Q>y5fTU$==O}zfg`E^>K<5ppIZ*cJ!;uK)(NtgluJ!t z-%J|T+xNf6Eyj-DApv*0<_=A}z9SLrjbykFpNwAWWzB_tFmVlmY`;p<8^s;n=fCal zDER*$oqdZ3M$6ZcymNw&q!L+Yi#(K@9`__JBD>r6PMZ~D4Lah%p555pO`<6|J|*LZ zphkn0mtFzI+59OxYxj^_ckQFtwsD|o1$Etc@e9wy+4O5HyJbMx_zpwhukA}#tnX8* zGn$5_-+c$b%>T(F--f=B{$?qd8)2$Y>W=|)GU(!F1~_D41VA8Rrj8LY^18VNd+zay zz_aX2JPWs_#1D@BQ$)U{D!k6JGYoQT2)%jkrl(7%(Q4U- zI$OuO;y+Cx3p}vZFx>NW1tMH?cSIS*e1LF?cueLolE5izti^^YYA8x#1^3;xr<4fFHX& zKZlQc{)d0dspy04iu@&Sc>(dApdjf7E$Jv}kaOgEu6dtxxND?5HYp#%W+re@y=?437LM46w(q!UlNn?Z|)JzQn zH&d&0E53=xnvo0(j<`&ATVv9HDo*MczFG{8aa^n8^*+l(Z5pYlIHC&9?WdlG)$Q0Z z&zpM2FS)+54w}Xrtom%m3(5<#L)s=M#y_&U3NaIP5G3J|N*yk!c$%*U?1#Gbe^inJ zb#$;c4Kjw*Zs;fGLdPD1yQ#{I4XK!Q#;n{Iymy+f6pyR)9duhd!M>)hGZy_t>AMNV z>^S%$Wmo@>zQ@PkeuZ~_X8%>RYfUPt4SC|2Ef{K4vV6}Q-u|!hZrbfU%U9~M6L95c zzEa{$h)Hw$cq)GMx_&i3|LZTTq=TuL2?2l^ox)XJhZNlWFFt=(GJMH+!V1~GsH*gL zL!B`DDMN`b^0X+joSpLBN^i>R6DQ*TTlicR)WL%9Le$Tmw(eiXX-k&sM0xTLrUJsBH!0aFS!gxZ+^w=p_iZ{>Ac{}_@Q zz_SF-=9N7{FBJ6ej=%(i2aYHu{&r3IZy39Dhg_|!{=B#RFjc5b@w-14a0z7`Is)F_ z#T!a#sQjtQt9JyV zKP4e`v*_+geOxUvik0mn~lVyht* zKO+_md$ROH<;yW44oa}Udc3biKeV?Ux8aS;o*2%`qtFedEElk~(E(BbS4f=V+65rx zEZ$fbXR+{(J--ZZ_^PW{>q`y8X0@2h$T5OJyOKGh+jk_+O-D>z>eBC^DjLEaxpTU} z48JnIrY1}2!pNmM^N?=EN2?{bpq+TbsvJbJrs4k(3E!?wCQR;DKcp-pa!A`ku5H%} zU(842Oq6BJiPbTd-?9O%FEy1IA8M{k7zfAjHt zYRMjQ-Hy|671}e=M-~eB7id^f32f80YUkd;$PDeQ}ZY zxOovJGMO6mKfG}QS8rUxLd`?HNeegBpc`oT3g#1Jnzjc6+1CF*#jxorqf@E|i3p0b zA=P85La5)2{yzipeL>Af;r6&>1tLJm&a^w4LW#7YhHgXI-yAV&K_hID zk3l?D9kZd0d94v%2&|*7M*p&vj)H zVh&o>%bp?HG)?pSMxf9Jn9(JGIc*JAqsZ53#kFg*yDuvp`e-pEfVEx#y|mxdqD1YR zG_LY$RT4zDa7RR?w_7%=U53Lz3)t8*cc$B{EPX??58H^R+n5)uTj(G^c!|$P`OGGe zRJEL1^fZ*uolp4lMDcFz`b9`9akpvvT_CP6$6~qb(&j6};b)aW@xFa#GR>%T;I-5+ z|Cd7Y7{sj?5^~wJ$M&m9Rx9tRDG~nkvA20}-fS@Ou)*7Pi%8pC47WEg88nog;m9?S z>`gqm203f>Gzuo)-=hl7m!yH^FgnbyAn3qZ@%p>=Z^hDyGDPDO75(uYQ=OE!WIk3t&<2{xPT6nmRlyE|o zk!EAD_#texH^#c3fwCyj^Kd_pI|--g+w`BmS;Lo*S~pzTa^cu6PIH1Ur9VbqP5P}Z zuY^JYpivjmNIXIrzSs+LJ`0GzfPBXT1@$RzIUz>pd5*XBaoU3O9>`0DAHVtXkzT^*%=_%doE3pbj z{2AdB>7f&FF}i~dGaUW^B^D?n!BX^oSlUICpE(RGUa68{`)mGKjB0O?!VPqV3%n4h zsW5Z?Qm<|K^m0jMoO9rlX-+{kj*pcE6IrTjVJiPJTlr3c{orVGw3j>vUIcA~F=w>W z-Q9P|xApFC*fO`93IL}V+5if2$@!iXn;D2xsd{W^_qx)1hw-2FDJm`59en1JH>|x| z98Y5O;KU3p@9W)Ocp)-l>YWgECDTSesC~+;Ah#(%- z%ZD05IBySDn2+$@$~zQVm6>(ftVPXUBrKOVB#;3<9v+)h@ep5VoA?~7x2PN!M;HXe zb?sa?-@00MBeaemE+H7c-aSV#nRM;1b8zF=fKMmThUgku?d{m<1#oUn9{Z;L9QiF5 zw|_~650bC<qPU#VX+Ib*WKohg%Q{vZ_1Eg!df9NLO1+8^ z7l70X*e(O2Qj1rrNg>Pb4;gSEuRDZXuB4fga9cH#S8!1<^2{PkculkF?}$XfK65i& zGtW{AN3(FyZVWkUs!<`>T=t|eN#USRuh0P0WEBFyQ3Xy}c{zN3=lBtcSp@=gG=Dhe>A5NpY@LB*Q+W#LJRGZqvSMBIb-i<(Gi@$EE#$27TfI^iax5uz{S-D$qxhv-8K_+7u6WOcYHr~j`C|5{5` z{qYck`>u^DM8p~c6aDwNLWZJ5nUZJi;RG$S^ngi-35~=|)kH3Tr;(2JT_W|x{&1&< zw-7%>>$&Qv2<65yJxh zd`2XVi3*j$Ueqv1}59GFYm5 zOSR|oGOdoP!I(%q>%_ecW;A9%NM55%#edc3C81=^ zj^zdGA@&yG^;$dxB`z$C%MVNgBQ%&THV%vo_6ES6NDoB%^=Jr>a0T;2Gc%f_b_(91B)aA_ z%1~v`+D9AF_!!3&w~w|ZV6qp&SfNOA%5*`maRg6-Mpw1$^`dG5@$b)rtdEEWIAFUS zGZP)oQm=gO5D;DiNg0V^;m(`Gv{QYV;Zw2DIz|mIzgEi;|6E=_injlst=`w2@R?R< zcT>i^C>Aj5iDhD^_`>$5qs1ez_a(f7`$qRUCmH?==djc?*EN{Ld04EK;|r-d&xh(K zZy-Ti$*iuK6RcODhpyUIsCJsTm0+~g7huL`vsP~KZWz99ZwKddGwL6%Iq}|vL>FB( z>Sq4>%*rMsDljE~P?tdx*W{P1BLOLA!FeD^4(Xx!TNO|PzSP5y#qkREVRP3EX4{;S zZDQV)+`f@2c|jKvTgbcySMTf2uSw{YLB zYhb}atvpGB7i9G-6R@qfES|icGGg9VVqdq|EZ61Q3dejFu1|9xtmV4AOt zXh7mzcDbMyRQFNtHNBDvt;s65rfpp>sr#l%9{kz8M@hmvuXY>Gx4=BR=a*p*G4pjC z?5+>xNJ6h!Z9$mdWJInBU}5B$E1ozdqb~J`>rbEeB6Df_>+eWMu;HyWw#iZ6XAM5$ z_Ia){B1s+mVDo;GrW0E^FhB#aZS{Yvl;uvDUF9w5c7NGgJPL$?Iudbg$&uxC6&i2d ze-Q#E-sd&lLDM9Zx_LbUC?iyL_uO^K7$6=E$RReWkKe;hWsRwBB)9TI$ddDzI{A-^ zw90?#q_8C@l`1?PO812nkk2U|1B30!gc*`lts#!Yq0|-Vag^2ctNGadqW<8>i`YL=@$o_ zij&Xq3l+JeY$Q~4DgMDPH*JyPdY=!xJ(un*#_>V>78&u}8cNM2(7ut{+7QF*+(8Nv zR&4BK54UUSX9BJLbl%Wl{o1i&^QkRC4KBv<~5rw#||=_Y!Qz! ztXt>aMNC{Kcu82geI{>}j-V{F{cXmj6%+FDhIi>x zf53o1Xr*i(GX-jg$LkLzyNmizNWYo-_N%~!^)O^H-&r1gmxb;~jg?fvH<3J+TAsOW z^~2Y92#SaO`ml6|F zJFX^9y#YNU86jB%``UsM^tV_~eak(PB(W$1e;~5AS?H|Z%rP(5S3g=I`-tTH0`LE= zTB1}a=AXc{QnFR^02Lftx`4@TnGKQB?mAnPT+I=`0W(1xrg8Vz#AOl?Se%htJ;R=V zRzub=ULyFbranoKY^C0_Y3Z-qqAf$8^T2#FX$qNB5Zf<7r;mrVOt0^}U3wK45afXs zGZgfMlns%A-KUVcGEBo#X{7GS58DZaecQ%~1-Q|CUeL=nyS;z~?A zl)cH;I9Jm~kRf;q1ZUxS5S{{D?)v1BxvR2kT(M+j{l7xvtT&Go`%N!YkqntggYX6B z-!dgbmu|1SK}$k*dCpEUaXjc3>%g+t(gI-t+Ec)WJze8?==kxE<|QHve23Egb3qAPf+KE|V(4D~8u;g!SoQU)xu9>^tr&;X zF7@Mw72(J6r97a{6R!Si>#^X<5R*6Y2UFENFRM0cP8k+mH(|z$43$LkpAzLLpsO~#@4JR6r~$QQ7Vd>Lzy$BJC#ZYq0~)ObKi@Slh6 zvdqV-a(5DX!O)3icfsxAXxn1IE)=L+?^1CJ_~pn*VTUVZ`$u(%-q4h%%O3Z+2a5JB zjCXM{LSt3ef3j_9C&#YAmFQ~L{E@>2NSC2B;QT>)WdGxVzY8_%nh)-RNqPT2@!>VOwro538I_3u@k$7pO+RQ-ngyj)aB zx}Pag%ySZiT8hn}L>U#i&ySpJV8vllUu#AJC@d!ix5-zUCUVO99VgGRNnyA85Ruj9@b4Q&xO zSZC=~QQ5|rQDXq0E(}x6SSZr_1KCCo+VuitHufZ@vck*)tpXfvP1pu04p68wA}B1l z8Q|YunFmJR2|- ztdFuQFadfOMq_wS5YgoSGG zBu~9-yynnba=?J%evjl3*uJZ6*RFs>R*iY_vp3}cZRoML5WPPDz!Q|hUjRro@xz^q zm~1;DOGS$4k+yk@k8AVsJjAjRT@L(G3Q|1`;|HT>m@jysLA-gK@-5z{B1akw<(&KbK+#TmM_xtQ<9VQx=eFei^xM#Xy#; zA7%y??GsSQfvM3h7ubgb0xKuN?xzf9m;;#_1B}ELBj!P1UD~2_#k8?97NNA5@R}@d zMwb5%ptvU`*~dkrYD7ik9*g19#uw`vl-5*<-DqWE*UUa5jH7DA)0E~-!OY4fqgHl4 zI1O}Ej&w-vSkNrpQgtze)a)`##vE`tz>VettpsMst-LKxRK$i4@yQOjqGU)usLmhR zK#)AZPVMIk(&s;9c?()W%^)|?lm(TT^ZL=iwBHGQUO}I{ zUemt16DTCEO@}}Ct)|=OBpPog>!9C6Q78n+9B7}w56vO`(*Cv+jtvK_{xNm~@!J<| zf!g5A(;a}US2Zg{XX{D)bhJxi{h!P`>cDAO3g0UW_<-*XHv>HXxwZ@Dn?0+l{!$tB zv2`B2loW4NWDK+c)40%LSUXeiUuhvW?tl=G#)~; zEz5?CE;Y+%%+{Ad;Q|1CU2hacj zo}UFnO`rUmox5&W8weG!KLrTb^>Uw|;99Oa@)=fu%lR`q`;cHHP6X5h6#WQANf)+y zIF_VjQ8FE_)?3tS1pv?9$(pt~CSEq)XaHd*sr5sqLeIZh=VFi2?0}828wGI=t%p_Roc2t zzc005w=!j?wXq<_pM_2nFhd^^c8k|iR1IFJ?0rqH23LcLj|?tXgRzM11)5IZ$3^JF z(}rAZHFHkLwo2j78m$bxG_N&P#*w!!z>!HH5=a!?M6@lU7dWOd5M;hpZg8yGUsk*d zN05!3O!{Y40lsR_g^#RKI{33}sRZi$Az4HK%$5z(V4Fsu#l2o;IW`-y0(hL@4BJr= zR2F2h{8`})+yU$3$ghB@wXYs8P9F97tC=G|#4h};mSO2+))xYzIAWpocc3<)OHB(Q z(h!ibFcF|esjQ~R2!RC*;MU2}VzsRkZb;eZHu)_b0lSkPh-w4o*B+@iZrswu8E;w% zG$^=PS7A#+%xK%&VJs@2?o0^gV#fk|k2q#{%ZR73E{@>`MBj_(pjbMHKE~=j1)_tn zLRb0pkufYeW#d4r+yM$~+pg%@XyTU69vz*)8gIioat+Vf=Z_^6(6ENpowlwnyR*P# zNSKAzFI!Mo%92vS55RO zBG;|C5Xd9!9SiGhCJq6>TLARL0Tp_jeX04?oLp=aa1=eQCQk9>pl+f6*)}0Ik{er` zI(Puu5=XW&>~9xpYTX#qC4$E(lhZ)DFRZ9-zH47Ms}w-cVRV0QCu|nwB8uj~@qn$b z?v`Ns4$@{(G`kz^Z6>XP=#_xC+6~S)rgRt@v?I0~@nk^A{|542a3kg4UKV*46EP& zErJWgu&PB}=UrvV@U8h5FsvYpT#a)#y$(=rMQ(ez8bw$}?xbHfW!F|e?s{>A&q(*; z;%%a;=N-ucJmM*(v}KogEp9G@OLp*zaQtH{F`vx^^Sw3$@y*|q-~E#3Jkbf-e4?PI zyy(rxbyLNfAZH2TF%s{C`Y#tsR|$PmWJIQOBYcN&DhkoJ*jx z6F@Q<<~ApDsxD%K;ZlciAO55K@9}5uiS8bw>jvPS)<#N(Sx);c!&%`?UIySftHfTvr;l+?@pZEm>E&1gP>otrTnzQ6->SFb zx!C{8xlvHkjJehwFc`d;T4Hl765s8|Ab{G2Py?YY&B4;ZKn~X>&s|R@K5zlK&Ako> zhBxCFyV7+=W&REa&FKLSC)8JMZ>BvdZ9j91>tclUnQUQ5Jv8$S*Go6{Zw;jf8UA-u zK5s1a@AfL+n%3P1YJ1O?pXE;TesP!jB52ThxpK;fm(oc9$=0i-ZIbMGFlb;u0=gi_ z2|&9EPcs!mARlZyulXT0udwT%bR4LO~U+Dh_^)*79JeMc2;lvNBg zG~^mwH5*|D=7b*cEvLh(eAay8CX}}7bv!|Qs0hNUHqJ0rI2qp3Mb?hidiW2&O1b|z zixrm5`IW?z4DC|j6mFH)2Fq$I-LBU<^jcBdjzgWLpsX7A3yhOemUdC_lezVBUeOQ4 zU9qPxZCvv9ETYa+b%}|1U+{|ZTY-9mdNX~KLg5n$P@PNFPb8D{`smPa$QBRL=k1x%YA^J?r7o367!+R?QRY&Kv zvI2nH>*D4VjyO?{x?@s}2q|us7<|!CmEuUzGn(3lv7o)ZPtfnxpyvNK-P|HxDbu5N ziCHgswz@3x5^zG4%%b1x3VN#=L$nqCnRz`wW5m8h=X)w2U+8>xDVUW|AL~+mMO^UT zaXK{`d7g(u_s4uI^q5o(q4lk4Rd7}k^RY+Fi5Z#pS3^7Av=j>+y8IUEEHzG}?@}lQ zPY#!^Z0faaYsuF?$(u9)J1Kpw3NR1w$7QuBn{Rv_r0@qEYL3Lj5$w3roXw$w>Dhj7 z;ezu$(_8%m#VtD$IPE`73s6^H+TeVi+_&`F00NHE3e2whNTlw^VaM9K&%6x3D>8?) zLW)-kHN2*upiZc5#gdA88cjBM5ga$ERQft@y;;t^isDd3qpiMOf99s@JFI(`=k6Hj z$fZKW!PK!GdJMS-)e!(gmoD@$Yp%&Eb&f*#8CuVqyw-ohm*&Yn;zDvnp`Wab#l zPEvW-IWxIlng%2rH|uey2{bp7rS$HI(-RZgk7oL`;fp`aA0)QlB#bvbvwJtymAdcQ zG`7Wc0EeGViciA?AAN@@rT$=tAZ9p@n9&df+m#$RmkI@~UDR5$(EmoPqru`!L@h?= z^yg)^Pe}3I(^nBOI8OOB(rEpCv#vXDRqt@Xu5SMFa+pB|a--VQM-oT$_?cRa_J}bRDNaRiC1h3|7(GLi&SYSSj6vq7YVErz5 z9?t#*3J$A5BOToO^Q`~wjS1}y8sH=^=e5-w)YWc)K2*vYWtrN7j>ZFn2Syp5;Z;X9 z5YaR*P`>Nfx8}~~p>LiPDBY3;J=n+OpVQ9HGt$y2o8!l9`1LzgbglQlK6s31 zE!A39@lx*jj7TBDEsrZbIzHe3U<$co(@y< zT(Dst&~+j2NUPD0W+12d>#!dBtaMf!z~+2NJ^8p~dNx)Oa4VFNMa6h!`4W|2o*q`Q zS-}O+qG$q_w54K1kj_HT!f=5d&& zSO(pryQpPhq__@2hw|Bm8n-PlHJM{+YI5atz^RyxwZ}x&hz%#dV>?d)6z}Z6u2DDH zzz1&FO#GczHrZmn{%F^y?LiF+_wD=|WeX6IDO)ynn+?+M6vXGvOVV4LApU;CNPcB@ zttd4HV#)}KA#TW|riipQYR1U3=$%#Pm&`I7wX-&L1(6otq?whk$b=r*ti0UPvWnmpf}K!ZwtNw-p1@LPDQrg-3w;XsNiWOz3X;Cf#$%yDPrpvRJs zA+$X@q~lOB>aBg&a~_AD41!gS=G$F|%xUuS`mg4iWw)^Tp+@E}v|SR13NiY;L|9Pb z4Qa1CFkXQt#5a^Mp4CYO;l3VG|3p2D24*(gRT{R_C@}GQCWlJ722nGa6hp|Mp=dsJFg&K?BeqY9()lg$yNrDC^ry6Zx zLosGu_QG@YjnjumPdykl{KwKw_=kQ@R&lGk2_b`~kqe4dvhwzMjmo%GBf|&vL)84$ z(bt+*%|V9FVF6<@D&W*BP_0g_zk@2!7f*K{jD=C+>>jH+ijG?VVn><)%)D2>`B+ zCq_dPG^*qXU2TPvnfCt5*!mx{x=Me}$&BZr`6d1KC{2xO&bqo)8Oy1k=!`*sHP;0H zFiSkwhrOo>M(-Lo)&y&Uw=B62`~G)OYr+ZE1ovoyJteG4zyFu<_j`cm|BSx^L|lrY ziIJb9<80AxWf%}2e~;TQqQ;ND`0Ju1adaF~uNZ<_=F8ocQB3>3ssU>UINM8PenV5V z_}^qSp4Db2p-fgyA_y!UcBR>?>aej|+#>Xoz_1S`MNXR-tciS-3}@dBuz*d^9> z%w1J|7}!9)h;S5(czZx1AyAC)CJ(oe_UP9M)ANL?^gX+MeL*`f$n*MxeZe0MP7cO~ zfUsn%Q?8c+0;=b>lKB5#+_LaDG02vIeDdPc7ib#6GcQpc6#sj0@kk{GQ zBEhCT1~#gzk)B^su!DKKRIWlrS?GpQ#=IFU`R_TJ=pM|C65S-tF=AmLe{>7VUy+1`}pqxYxy$$FzZUqIra4vb29N@#NU6&F(iBGgt=^IDPQ$ge2~V@Ng=@GoQI zE}N)tTUKFam?6ra!VnN#3_c`UMY30Kzl-%t@lJ>Y18S&tF34*&-U@a_{UuHY^6x#z znxyHtW`u|tmzU(fh#u${PBHqxbQ~(K-nj{!vU%O?6eSXoQ4LmkOfM38Wngioh=e}Z ztm4}lfn7S}ag~u^0WG(S0ch@@W157hPzI4876J zPDMeUP0DTy_(6CEUM~fxKM@NotLpfW`BjPPBER%1jy=ilCr+_&9BG^=D{8p`*Dzyx`2$y1 z=3}}1_qI2&x=MP;3$`lI_&VQV9SdDQiID)R+Bc?j{hMGXsN-?5)ulDH8 z$3l+ctkI`jH;h)@eftpUBVR$D(KpiLU!>l4rUJ0(m;QRX`?D`%aG`)G`cn1Ep9t%7 z=)y9sV9h49J7NbJP;i_tHbQ*oaiSbw#(@x=vaI$St(SecmSEJf5jy~xd=3DSaYWc8 z*^KNy7mq3G<7_2+Zo1oRHt#f9G6*;z5-0y2pn=Hd{Cv%f?Lr3fr;a{N+;-*>TNzhh zB2f$^7G*^D+v44~Z<*wAICE23&@3H&W{Zjp1o$&T%^I#Da+FYkLl85dj3aiow0Wty{XFNQzHTsmH zf)&c5o;$o0)A)eo9Xe4}B>TR73~V~I@%4alJLnyA(S5T9M7K!pc>f z$&S6}cevwBB_Kkt^6lbJ*+pv6htDjb>1NU}SQlp^`-+PZ52<};eEEO_AnxK2-AYsO zSR^cRogo;bexpSL56-iOcw^oME)Py7OlPA~-ZT7rDC`gI8m0iC`?AuY{j0ln5cf7< z%iR7?PSJ)Nfv9m8)#_?y{HmrSZ)DghZ>);6J@t*X)NgFx*yJE+;!H-e25^3u3OUYu zsXQV(J8d^Tzq7z-QUE#gey^@s%-`ywqN_`rc=r3R2g9<8*}p(}9{$D6@p(^mXm(|J z*8r;U+GXb*8fMdMk8NW|T!wfhgQg`c>a?S07i|uh{=cj$GKydzDJDkyp2? zkJ7%qdk@*{XP7xbpWKISdyI~D4H%bk1lBvfLI6)2%=z-%AKS-wGHf4IywlYs)jd_x zD^SU@K<4W1*qee>Y;HPRm0oemxb-8|IoAxp_#8)mbl)-DG`ufb2ryiO z$}FLC7w`THT66`NGXPtgj&rrAf*Ak?04sl>l~7E>inaf*`2@A#xQ`*grB z*zKpBKxoe-PlE*W04rE3v6OWqr26oT+p{mzXaYvK2CP@TuYk5*axmBBOq6S<@f0g_ zyxiEaJLTF`N%fAW3?k)fR{2lp^f8AnTTO_wG(TX^-~{Q=_@qaGh0>VQLzx@9Y?JFR z#@%AJdf3{*^}JmMG2%fVKYitmQ*PGRVY)RM48?$d&+#cx=FfW*g8I1Z2zgSuaRHdA zq~LsDQNeoLrp?)bvPLDlEv@4{&s2nLI6$_V@f9(OU=d}`!(@2YUR}95 zBJ|MOp!o$KMau`8Z1L*4!i;rAkTnJNQCNZJz4V%z(o{8ib=DEP4>RmDjMQ4!nxXg) z`)Cbr84=C4!vqh~c`|rgDRZUm{dvVB*t@fxckj}BTjZ&A3(IqIn)Xk;KD(SfJnD)l z{Oz}}=%@2msdP?l2!6o=C-13P;O6fWJCdt6o(qN}se?ayS8g{)Wjy6uus7i6$kvUE zkqXF6v66aF#p0ywUP|`JtC)67kCwCo6M5Wa$bHeZ^*u%67g>O57V!oXgoCwZsoPq( zT-W)9xj9c@v*6aN1q+Obc!%u=+n4)O{_2oMRGfnGo1@@?lltz9 z#>EW-IxJ3e8@pd#@@L)3nBqJ;=!W*g(p<@%_VY^}At$E|t@B|lL9`#>qr9vRB*i~7 z^{7>uGY1_<7fbVde(n7@EiWjX6tn?=7CT$dCMX*@>G#{V1y@w3Q<{0%!Y7rCD*v zL}}g%#`h>P05nmo(pC#5JPDdb3yVq(Go8|*T+C^|h5o80&uW?52X%Bv)_`^6$Ryww zj-g_nzDd0n?19o$$yZtQEGJia`X>BarP7u%7 z-jQZ*3ak3rsht^;LNbWKT~M!~7)9t^0XK}CBs|8&%k42c`@S9|Ipy`SBNS6(zP?|D zA@=7at-Duh)Q$`T2DkxWRRlYFrF6rFP(o#58P=Q0tYw!s*fMVyJ+GUq5x9hM)qgGW zt+T7?Akg7Jn4XLEH&)1!m9VSwW2&tNgSe z6~P!w0u~laX8c;y;w~F`YLgi9yjauP+0)bHRU~w58RzuPn(uy{SI4NXV`W%_Wcu~L zpDGCV(`=Y`>pz-KSROB;&6j_ldS4{et3s$Rxh%EM;~ zDZqv>^`GJ!%xljmii$ATt7jL9WUE5I6dx$yCXf60S$Y4i;o%Ni)%xSrxRPbd_Dw0t zaK0F{0x6E)x1he;x2xVk8D1X-2+Bgn^skN6SWlE{dM4S_{(^mtb(L>-fE5l^%Z^~K zlO|N$;AJZJJumGAE@J!p{exSpJ3M7KZd|{j^p#;+&jYc4!4(e_DjeCC(*IdsVdY)k zrg09oIc(JJvqcNGsQ|suk4*_-{$KQpV&H-LBrz6ER!ELnmEUYIvvJ z=Vy2$@x<{z%{d;t5ldPP?4pP#aOJ~(x{DN;rJ6~l3j2(NvJ*o01-t%uar0eWF{G$4 zieIQ`g!8E)?gBIaN&l0@5c8%}`Gv*f1C%OzDwB-In=o8j1Z*(`N4VjmCWfRNhrGh) zb1t(a0%0%Y(AM^>SJt(?4-z76bI%$~gw24iNsG_bgWzngI(k`_U9Z3e1DDBsfXYG3f>gEG#9 zm5~^QvK@pci{g?SH#836vUn1!Dc;6Z&2fRu7A(DF_=tivI&u0eQ~7?i`i&BeNrVf` z&XDMOfhoO3t=KLr#r($G_I^^r^D5bQ-<_7{*~IdcOA1yk^9#6aN!ln|6L7nuDn)T3 zSyv?sh&p=ai`m=byK>pBp)WnV=MG-#MasONJ4n5!6MeG7s{&aoK`C4gZjL7C-9iRz zx9E^;bO*Znx#cJX)KX`WLCwr&E}OqzCs@r=2CiQnm9@6$x;vt)4+6Ty?V0GqD=H)s z!q7Gu4!nd6`Yc{PH-mXj*C?LfsoFu2ktK8F660iZl_jUm_8mf=IqG9>ZYUV}?V7i* zwL#8`L;Lp$U15IT_9Zn&-?W@+=9xtmxpyO_WFVWV)%^t-4NL9RXs-yt<%vG%?Kf&z zFNMO|8z_@Cru>p}CP?<>>1wG0A@nLGw|-J)#5(w;*cEd+6Ve>dZ?IO&5%ixM`WSI2 zcn4@b<0GWVa#?8)!1aYlWq+i{(Z;|3)vt@G1@}_{g0#4$Zl}{X#$m;D^Q)C>4 zL;|mss7Vu+-pRUej4(8a1kZ?w4*l0T#jVbL4XPOHa?E6pf7|JIHVd@mM`k0M7zg3G_gU|g!HBw8L5rQ#( ziWnu|901hUZ0^A6mp&H6ctc~Komh|7f`B&)pnZ4SeK4YAzE-2lQ43UD;{g~>r3 zMTM>56zHZuFb{G&&+*Qe4C(WT(8WV^wT1e@=OI%#h|CJb^`wl^fu%oYJaJ9PS=CI`QB;YjICNGN;ckn*+d^K;x#|rKUuE8__PXqTGi1_|w>fsq zXfSjVAB~jg9!I2Yk=q-rY50!HmeCU;P$~P)KsD@|s?%AEC zhpLVz#yuABMBU2AV`I4oForH>-n{`jD{`aux<)eE{cEIqH9{lQY#^((NwNsK*K^o$f=CuUOxpoBZf4|qI^;NPq$BPr`MVNc3!4)P?|<7 z)>IGlt`7Mzv>zhZ+9dcjidQ!Kbmw2&d;Bgin4k%VRg;A@F&&JFBw?OMb-~`F#q`ge8Pi7gYdyu zBg%Qx!OGK=TcXZ;h)i5(pnwxCEKhi99LN1;!~~HRIsU;N`BkST+gEtMPB9{IixLcGXl-?0OqfvMS;1tKZ!#

e zofxOEsIuZGHXLQr@W_(HY9+`u+V(U0A;HJ#`x_3TMKqssfCL;d5aRS->gwRy&1TLQ z(XBfxQ|ZdF;D#MVyvctKjEUu|GR!lwc6}m%vqB}%xOZDMD8~t>!}olT;5RWTCUr%T zL|CGVM+{7n9{5U2NBvRBxn4Oj0PuoKoM$3xWw&V*?YkQ)b_ab-;k%1Bfus{6?=F0!jn9gnanfJ8f8GR|2KbtK2i?)L5}YG!9CKg2$4D{dr-OFZbSoMgJ#FKB0Da-F zvFE?SY#tCDM`xC45$C*>6_md}QygnLd_7m6?=JaztzX+hqET@;+66cIW9`nG9_cxY z_TtXBfDjZjoVHB4{>lK4QtcpXL#{r_Iq@RY>$v#NE^i94+YR}s%`&|}q7K?`kouz} zh(>g~)#*?YxM|D-3&KzH;@btyp4;TTVD21+60x~HnT)K?G{49oS%3zs;WXdAtEYzb z0b6PAN_-i(N+6AaxhK7Uz~99ME9X|wxUtgbUK<0qfb7$Q0#AYG;q_chNHxvJVcV=m zFe)Bja{3QC;NO?B>IM7(8PBO%NJJ>C(M@*#PLemouoyL4qLc5!55_wv zjz8W2vNi_JomxEx+oh$z^jDRvTa7516_^QxDPXT(fVm@_#kxexY&8|-eM>1{&&f6s z_33pEsquypql(*2ieE-K<~c7JpWP>_wPJ#=Ak74jRxkb2p|bTo>@igz0i=fa#=F4( zZP68*`F;Rlh6Gi8pIX7PM2SkS4LTD!JBUiWR{&$nXQmsPzu0!W6b&J{IPPF7WQp?q z%ftG@;@2~ezzRAPEx#epXW8}pv>pwaHmm5b3iZ+@S$`UYZ%P#MMu>Jw|c!lcYXsPLofZ?gTzGa^C=z$7jNTD`>rbO&~}EA{(|BR_~OdQen1q z90uGEy2tx=s`*z1Qc?D;5L2b1i%kA0O*=h#8`uc7?EAAx%?^r@B%eWI!$$w3KjFO5U3G&H_wafaK!+AXj6S{z<-S+%T`@PO|yd*RAz z;8q$WKydRLLU9~%O+>Kj!9il^hd|$Y#&bjTVEUXzjEK@2ksACByaUe=#W047WyBzF zZXUeAod)@*IRnjQOl=z$dy9dwlirh7KufRVP9Z~oy*ybB+av&XyK>VAFSeg5sQEWk z7$mQ8WT4^)Eg=3}T!YBRw=7^Oh)_nko4K$bG+lRya@{@U_;p5eF&BS^s2kVkZgo42 zaFWQ@klai^S^J$ErPgwIKi#(^S{68}jfm2QR4KXu z8nJ08w%0Myi1+>E+By|Qfr`C)%HsQ;*P~f?*aeiJEmTjB11W$lOb|Ue!SYqiLah(@ zwGp=w8$Xt*rEpAZ(P6rU0T!8!Mwc)DW}QiBzzGAwXx0SgHs@#k-irx`q@y!{1OU z_aLGIefG-7Rc3X^A`b;KBKrx_T1b2rz7Gd^%lbEs1ZN$8aA9N+Xo_e%LNwK~>TOfe zrH7rihtFg|ko1quqo;c{pIgP_M7K{)qtz%`GT6wzzdK%{WRAPHsto?}bZKUDr?p{s zsAF37p;CsrPJOCWzn+p6D!qNG*ps>9e}2xiXQY010eN?kBe^3mHLY3^Z2b9$J)q*S zhF0T1vcP+vBldE(9NOC!rb$>^N9Sz|Lf71aqv&P`RL&8;0QtQC4ooRdlsVg5%wMY< zmOZ%6P!7*z>xUB|&`dLPE8MDtflna!tnX0B*Xjdd0ATFq3A49f0fiU&Rml9fR8D#u z>gcKP8o#~1szAy#gjgD40RVyyO!$q1PYutueH)oxL8tsy20RgMg1fqxdHIb|Wx(#9@X$@lR)VpSpZ-x_Y)13%RZU};# zIo;q{Mp?&l){R((J%2P;H`yvb9PQYuH5 zgB9oKy*FPt#okd9ND5duMeGWp(EqnY2gLnvNsLPwWLkARN{3nB37$&>+E8H_?|zys zPzB|PImU2`5;5$Hj&YZ8n0h)R+)!KIk-Gj&@NH)a7?{T?zz8_br3aLrCOHo~8^*2T z&W0Ip#x7sn((eX3O?cxk?+%|`l zt7UC#yWdv5UqAQ}-S-Sbu!qp#{OvA|fa`yhDhSJ(+wRxIaeOp}X%xjjDp(e#Vo5n9 zl90)2ct(0;%Me6~Y(4Kn4**;qp%|{0gP+try^bLf30wJG5p z-+RWsk}q{JnhM87>jeNpm#`>)AnZHy0K zKKd_>&u0%YR9%QXxfTBLzcMLViOBNq@CvYEo6$l+QFXGzeI&6c{H=o5#G-7%` z5WJsHovhV)2*j`wdwW0R71*x^3! zjo~Q})noEfUK=${L>Uy|h~k%LjvDdv#(4C^zK4#hn5xIJfoW1N&_@HJ5^dVO$u;Rf z;2nh{)h_78bh+3Hd7i}(hGHaU`8QM6)XIcAoE>Qci3OCSr(G0Pnt~pp#IFOl)G#(f zte}qm$8kIg$ea~99V}Gt>jTX7pR!`41LPj7Y!@@{G_5z2Kyti{0ZV=W4!^-nJW{6=gFPA*C)Z( z?izl{Yl)cT-gCQU5s%|N^dtGdgJ0l2o2cR+vN+@)$7gLAoTT=@RRtaPrMFlEBYHxx zZKS;>QnNbnHz@wgs#pq2W_GByPDYkIFcL#x*EC`$U7hQkE-0w41P zzUTSe`hnzC%w9gL`NM5N03m}Df5>URFlhQtC)v)lD(4dLKCjAGy1Dzfc-<+pP?6RC zAd6V<+i*v_#1&1XXs*r-N z_vs%Jc^lw?Z(QKzHcR%M0N`Uj_i_=W9WngRaW>0lKz>!7=sq$0?Fm|j_kJK3_)l@s z!}|o-wjM@Gl6O1-^Ox<6V z|0RIpT(;Q8Kq~x8(;XN>v(eike!^r^$;V8;474B8aPP5k;f;MYo-;KIq5k2$9F}B_vNXeTWfKCE5K!y9JKdR>0|dHr|*N9 zwFv5)s+H!lK=w!>WZ!WNRqWAWv)hdS3Y zAKahf4ZH{$CV*hd>nU9`TA-PQWgp|}3Xt^dc_wj?4+?6Wdo6Qh+hCzVPQ2GkP7K%g zOm$(8>@)IbD&&|-6BXjMxV&fKRhu8P@qH_G*=hRDM{m>z!-MBl*>S!GLM>N6m^tm* zf=9xoV=osu;^415i7^VczD_Y?9P*ky_k8U4fGJS1|EsLhBEL$NiteXQCy|pV;`7RL z;lJh|czFeA8b97)L|5K+4CUiyx{uNIIr|6ya)=l5X3OeQUu=57p!%R@xRPL4_=ps$ zbYJ&_xPL@`{99+tR&su}e%_smG7kK%vR%S$)Hp{+?R|i5#VI)(zkC*u=OR4idza7Z zYx=GAc)q5eM^jq1$e~$7b*0AU@+G?8&_1}@__Mf6hj0xrE0X3|n??*8jj@Xp?UAB= z`bo}_v&xTs&`6;%P8;~t2c39|ScAslYFL579I5eE*PdR*Gt!iBJVyk&y@hn`3uOgB zh^JH#(PtjGk4;Tqj5`G(VaMJKt{!k4UmKgC#S3fc0|@Cx=I*g78c{LVc9JOvW|~Bi zV2+X}3hC9hi*E;y;eox$DRO&L_U7(VLJM_f+Ssq3pch-XuHE{+zi>|Ot)rT!^8_L} z)&B_U9eMJuREo@|o>QnO*S(32>_7j9F*l(Tx(7S6oGvon!?(SfsiREs=HvCY`$A?f zn$Nz{zw36t(!io7rU=yvCKPUJXgs~a-BGjcwf1yy#Jc{mJ0JqjrWUj0*yVXS@4`D z(ZSpW>r))o*~nR0=@;>xxn$qyT=iA1}iM!KlTZs=rc8+&4lumX+P0 z@#2Wgv>~*%`{rxtrDuMz+9nTxo+PjA$Kaj|9*JY$Ly%c+Lh2|gW=tP(E$PjXNmiFi zs~1P}c<5$8q>fPG2z)xLzQJ$HKT{TbuzV~%%ivk-8TDXj++l;f?WDj~Z;i`e{@ZG$ zeVjC;Ze4M*Sv9p$XKA15C)gr0gD`APRt7h^^v8m}v71aoHz7FA{K>Il#$lw>gPEUr z^pp(k%#QZZS4~0ju2qSz%^h;b6FEI&{KRu_)z1(IwhaVvGB`_Yy#9DGU#(mIZRpRy z*HePL;%Dpgi%`i0{lEOCfFqPk&ia{ID>F53NwPJX{G z<>|vBm(jPSzA6hi?o~hF_w+IS?JamMI5pm7R(_j(|0|tBGN1|+h3Ep6sopjrLO!oP zQlj=G!tL5M{+>(@kFu<6Xq(obS>DM&riB<%ITp)rB2KQ(r8G6UD?b(@Sb6-Ymq#K<UoUaU0aiMOI5|s|M|7L zkt^5oYk2J?Iu@b-=BGJWDWnHJl|K#1CBoqQ&;E8jhE+x{`W6Iz~}l3lpO;< z=b8D$fy)QN20C@_h!dleU})#RpIz7e^nVPU`#aPBAI9H1u_K$~7`8bdl5+?db3V@b z5II(qN=2=lHXAl06P1ckgrbN_M{@|BzR}5|G99NW^idXSU)S}%-haUBhu8Id-mm+< zA2Ij0{%5snSqQYf&o;dJoT9l+kzGQjo;mhxHqb!64PTSHvzl5imkKWSJ00#lSb5jy zt({5?xmcj&-+vW=3}z>nr1xjV#p1LujeZ79muON?rPBK8fpQE=RWRG%4jP%d!xL1q zHYFwE(>}WbQEMZI!=lwV;tB}x#g z@*!{ZuBB5tEwGviw7-mSDyT;~o_`6*A-Q+?2GVJWm3`BugKlI=ro zW$rv16FD={Szb8`(T&^J0zIKYqnC*F49XQkx@a&MQlqa)N3r=Ii`NfbiN@}=f9k*+ zp*ooQH-;bzN_a^dj3<`8ub&@jY=w)8q(>WeeYoS`T!!8T?DoBCSvua!*zD8~un$@_ddBb0cVG9$m#FE43NBaEjLW?@+6j%I z8Qdd(jMC)a>sh%~qnM~ZCWp|5Io%Q3Hi<=zkSVTjC~ zwp{4(fO~2vZg%K@Lmr(!C~;Q)5^b~Dv|}A`TngITaP^^DBz^JdGc@82)Erx z)@!Gyb=5OHMJa=LlYXZ_1%}0UX`YH1mWGe7+95Y<)T9-<#!~9+Y$`AfeI^1$Ru14F zZs)$$#YQZ>szUb6>M6f`WCNd7KXdWHqKvEI6R)L`;(8brbF<%KQ~ffRFF-`0)j#0K z{X>C>ER%A5(ZW=Fqa$P$PY)DvK?D2B!?qhkDm=3Ve+PKM+M}nV+>0-?&lnivvJeft z^g;luDvAK`d*6++h~GI zHJ|SLAfG82HqTD(1_8Ay$?}edk>?*>@_L=`?IVy!2P1z(XKC&&!q|;fdTC)2o#K!| z@EJA6zXpp}4wv-F*y|?BIIa`sA#o7&vXRZ%>HxRz>gB$7O6GJ2k0GunrpNFi>B_i& z6QCcm8|$63{k1x>u#8=x(n*TgK@~OxAK$a!vIl?(Ne_RIT9yK?pvYtYaZpdwNHq}bGa}|4Vu4%9#&#}y`+l{mWuo=1dRG`uZ)>SUp9=L|Kw<?Z5^iQ+aNjRI<{rsD1ZLVTg(9;9<8r8?g2`(`ExG#<*ripN~55JV^@Ga<1 zp77i|Hj47yOJ@5wwDb*~aLL;4pKieQ1P)|@>YoH^sarmA99!HDv_XK>;ems4gUYf9 z(ckaCIlY&i+|#mfHXIsSv_b37=I+{tySw9EGOpB#NRW;GnJ!M5nxK-ABj1fx4TX$# zZNvNtR}XrzLaY1$R)Hwj$;)t4lFgf~W6Xl;O{R&0mr zEAB854HlyH4>gP>6Ryz>NZjcNO8EKlf_4b@N&@uNUV#m{IX{)Vz*L}aMrlG7z!x0Y z7mH=hx*^+%=Q#>-Z`nUIcX027Rl=>T?%f>ljVj;_dFr7?!Qe)LJ)lt!kzjl3YY;a3 z_pIe{)v@x+to>OiT@{s@6Rr(m5Inc;KK#jBh92(UJA*xVJcK^a&r>#|-ZVVTNvv&# zECuwtnY*UBB?Tn5yi8EiI`9zwvOJws7>wm&si-3uFXl_}dMR!57?tPW`b=9;ugv%x zeML>7)wTSKHRvGLB7O>f0E)z_YLUt>n48eO=L~I3Zn6J&-3+=72HRZ=nLW{ZBWK)TMoiLte5dz{o58S*_C)5UigN>1~O%%S#|kd~Z&V-pVuHr+QvC{qNm^ z`}Sx&_f7vF;*{yzK=^c?_$(w|tQZb;H6@{{>j`xyx2_^Y+sUYe;9oi`U={lsZY<0iQ; z#KzyDV2kHFz8Ii(Bta@(h2cSMT3wzd@*S72%1A+aZA8yr&<9G{_y3Br8yJJI|J>I3 zSQ)tkC>wN7@bK9GuK!nL554C}aRcjs^f>oovhXg9oyET-sPbRfK)Rl-1xS>AqAI&N z`HLX0?=e&HbiJU*$Lp{BFN>E$PT50qi+^Q-Ln?T&r~1&iUnX*6^G0)^LHkplTEbs_ zYyt#wPx{+Gt_a*Y`I6CTQ)z!vGG9m3J5T5tvz|iTv4j zdh4jqqsg5k(0it%vcPBdv@wNjwQVH{3cq#kgy`RrL|)JJZ|7g-G+gJ!s~s%XDS$j+ zeV4z=DqFk@9*iXD@M5r??}l%elb*Ez<;El{E>KLcndsfuOSt-m{&$f}+jL`7q@b>Y z3K2ES0I(^RUM8ys`pz_W{w0QHd9xDSrVzKvj`N8Id}Wn_e{}Q+#gq7gKILzJ3QU^h z`Lf_nI%^_Ired|A3pSb#{xZ5c7Va@^@IMzsxTzMqTc#H}`(cDyh5MWopLu9RLHhwH zzN}_q83hWv035Z6mkqS2ZcOldtFpzt(*SMUG1JSkR7 zqmL^c`@9IG*ACe$^ z_k9GHLmfx6wCthAm6)iC+YDM<5kymu=8%M=CZD)e4ZFBO8^*&;qtn6gzE!cmA{IFi zqG#M)s;!19kk6NY(UZLMWzHvYLLM%On>|~%aBWu^ft_V$FjK-9lgrZMve+8YXZlBe zVmZ3iUMgc{%5CAHqCOiJKJ#zUHr_2Xn&%pH@B3LSop-j1SH%V_;rvk7phcJqTXS~p z;h<=JNJ$vnX^B0v#dn}LV#g9qbVCT`@3?>Y_kXp50+GrN=06O8Mka=vg08Hs2{sI# zPTNVT8-74I7vvD&%l0c=x_13v=t^R?aW?toP~xGt_xyUi=k_+YpJQD%0!uU;L+-iV zwg<_sD<>Jlj#=Jes`t1jvz`<+emxFBF3}61I*k-p-B;}KH5hDqeouBjju(mMsZtK* z^4&aG?yG&bo;w-SSCvX-D=0LQyjm1(rIBs9uR?({Uuf8QoBq^Ib>~%4KksCV*R({% z#JwCF)>-KFqKo5a3`6beR`oT8vHC_eS0?(}xf7hghKGq;p|)A=u1YcnX6A3=&2}EH z5%F%v9<@w5Dmu6QWpW?#uj5LdvcUqbkG2C*B+G;KwKe=bO;5qrxA0a8hM9FB+HWIn<$sXd zJ8{q{qUq)87=v#(qr0zzGWO*O#XUD!MZ!1-{rofQ*&r)`e>fhU0KE!k-lU>DGorOGMg8n{V=K`=|K>fP(8pw2_5`P*YqW=Ic&oGO~ltH<{W<(RpROtNX6DkjOpaADcu zUTn!D!Es)MG{}!B=Ts0KJ!jmh_g&!UoDX*?2=TbIXPWu}A$UJBfjYV&IUDN1JC+!$2LVNDY*w3` z{$3i{pzJN(v%!0>-v`t3lDv|7r6|GxXd$1rE|IThmOPf2lCF)pnyBtE+oO8QT>V11 z;7^}yOdvl<@nFh)JUrIj@lOU6lgd|2&!P}Q*;hb>Nbp3;TAK8ZwQ6`w9h1|*&lrgg zp@9-UT5BM;N~zAFzrdNFHyDDms58=^-3`rbOv?Lzxgs;5pI(Uuent<<6Eo_X)T^^eS+rs1jIMB(g#K;nX=^6 zf-OqteEk|CP{4pwKKpU~E%WS@a`e%h!aU$#lL+>HU9d_;rkCHW=SOJtJ z*vmbJK5Fjsbjl3KgI@VM)+oJu{KRDm!YDJVH!2<4_tt{fUDlN&r?GuDN)_ZL((l;? z$Xf9*_Kai~hI>Z5aHEBmMO?s6UXN^vAKYEpeXWj=N&-cu?eH}}!mk3OAb4g6f)oLr zcD5)s-JbCtAf+@kvWbrtZr^30Wb*nB(4b||1xTS|6JrEqm1_yTn`C*lVuKTQAzHOT zLyxDz-lTbr@ZLQYUI32BeK{fO@B`@~S7$om2I#&^3I`(U_owluoWoIqhzme{;bJ!ZXqjbOB8nZQuGG(2o3h#>1paYvNWYLP|riwq2l#=oEM-rPf6&N0W;mDu~F{K^{b5 z1aKes*~2rc{TjLePGc|Aq_?wFH+iQ&I=%j|N{=%*+uUNT_g)#?Dw}ZEITEX+SgoB4 zehY=FNpuHbhb&L1gjg^N!*>S8^(BX+2Kt_Kjc#~5n(cSBp;+}V>X0zoSr)W`P`AxQ z;mA5Grq#QALjTw$wXJ_Ddd#R1n}yYmmHP3~M2$19vdsjzV@x7k;h1vks^!K9 z;Idr3#6WWVcQ6P7nm-I5O&do8Tf0yY@8{H#a#uc&h(z*^_a)Hi16*YEe1{N1OX#H( z_mzmxrx1~No>wq7{tD2&nT&mi#5*Y5(Emdd`FyKe&zqr&Q7KF2k^Z5#v_0j$?f%&A zL+q_Ruil)cL6Bgqu5(~e83;dKPn31Di%JLTUOrN|O)4qUu0HlyGxl~YECE$K~Rkla9lBMwpH)+byykc4BhhT3a`u4J0n(y71%(}vmRM1Z) zT9V26Gp|XAHz#P5k{xF^d8i~-;QFde14a3{cEQ}=$4cA{5HV-ftA3noQZ)<#S^`*6 zCd~iUZNdCoer`%i0xhJg`f(uzuI{5G^0eG0S^}XcarVY9&I=hzEuJDGM`82ehxHz3 z@;hxdCXq*(7@wCB(#lL8!>{)e!D|QZskMkS^QT_$wftqus>?2i0bAha%PD3zMCl~w zV38n&$QK=H5`R4}U!=u?-c!7RBGf!1Ujyv5K!vK^9f0bgk|JK0;=ygZ2KZfNB%a>nneCC=_WH7RQ^N zK(i02X6{Glu`1aQ?3O7Gz>Gw{5648!qp%8(7aeH|{7MR#(H=Cf0FmE9fALHsWBX>9 zlc#tPXqjspS(1=FM|=*i03D+i2o}kv+~sK*b~9v;cxqS`hSJdnzr5|Ep0x$Vy0H7u zVS~oaU&Ag)aa@`hAeunG%m>c2M`0Z&2^W_N{iGor=zyC9_ulWgoh8;`FWfUv}JV(57%|JbqWN zV@c}|zTV%GNJ^IXJv6F>54(8B@@=@qZ(EdKf5u}r?r&rl$kWR3Gbe9Pp7}U=7ic@6 zs9E!il{cnI*T%D(Ua#=t6VH!jDX(9!?wkE-GJP-3+`8~)-sltx zb;SH9O5I93l%9|G|h`(8I(-zr0)#BH)=HoK^&5~b1l1%XKNtR!MSxhupa za&SoBf&!T7J-%yATAzwFYM=nBBzo5=1sy_1P%|LIQ{Pd(jF{Kj6V^&MkeS^$?R_Xi zT~aO03BW2edQ%M(DH6CVxRJ>{3Qpla_^O; znI#ZlqiN6C9kZ|h>aVTqrlbs7X1r}QAuD+YC>l@r>xB5GPZ((ffUCxNFkc=;Upc}z zaU&w;5UgjQkEgJaPMq62J#>L-@?NK#F#%rSA3Z0$1kKq&9vV>^m&`oOq# zzb{ENpV9Q~A+VX{1IAfK26)iruBqNP2aT<4iRJ-=jSe{=3ZMTZodm6SjFv}e8CXtz zK!2YZP*$Sr?HXlU{@!@7R@kx=pS~}<4sY-izCk~GB5ltew8Knt^qrwI%zF{KouiON zY@l=<7V@k4?9T+xB7eFe7}#}J2#AE_QI0iqY@mw5an zcN))U!96-l0nmAr2x<#^$+#0J>dix~zg&I-BM>n@fxGXu_am{DZ*nmmm=CL2sKA>8 zm?OAtpeG7e>e=MoSWA8qta2YDswDa55^uj2HWWyxH#p`Njf2CUiBw-5CMj!MlMtk{ zGkW}O$o}(vm#2-8&SM)SdEdL}qw#jK<+&xa#kI zc+!FdX9XS8m#nRDa~qg%LxPt`au5vlfIISFp3@!w<9KL*Ts~poXytgKhxt(P?85Fu zuDn8I%|+w=3a_+Zs}1y(LG3>!czELoNuSxHM=NkSa4tcPu~SPQK<=or-JdI7d8=fYJ%j@Xhg>@v!);f=xq2^L7 z?++JS8gapX=n>$f0IA{KGNQ^BnCIxh6yByZ_cokJ5P%Sk#J(A?Xw#L|Aj%y^rjb@# zrA-?5;fnH;4UxTLrHZ#W2|8PiH!$*PmM_Ie-|H6{-ey~;%vOv}i%T~RY|cu| zNX_iDydBs?qbp{x4V;m}D_)r~BM99g&*|m((3`KRq%cihn62`;?9ml8FErylLfM@= z_TagPp<>_D6PY;O`f#FND(O>r>YhYfH`m&1g7$yW1G|*1#*JNS63=DPbeSoxdwK5P z{Ua%wx>i;d)KNEZ@X7N@>5$%Qe-QOK1p(3A0d2c#+g4S(wjGCv(PGr-44;A*hjSZj;^jwEq8`!u@`-(IiqLCnOqA6A|pRgCp^e8YaEg7=o zO)hzDuFay+IF}{%QUb4JEALb<2moMm7aN#H3B79DG5YC^ua4>Ncsx)kfG?aEc)xge zt5p!$?y#w^IcN#+W;f(#@ONR*Li2`?9%tQn79M@;YQ0XF+IsKnBM@8(0 zmouj;^lFhd>km!`+Y&6GgY_s&I$=Z~Wd8SmonXs)2YnW6Vos$2|6XfKN%X^x#Pg6- zl-JIErH3+kP-OEDHf@3;-UfX{@!QuChiB{vcy$^PO|=07hiL(BT_frj`>5Q3eatZk zm6Abr!P%YM3U4Jvi!9MTBy!2SLV=z@WzOXK1BbTj$5iaooG z!W4(O_d}x6zQ6Yd97l@h^f5_Msr!L%XU&H+GCKIs|F*_OWh%RmIyEtuf59Knci0mY zV=aG=ax7}S>GtbUkLyT7y18L)_48yIP`!>?N@Dw zZ7;7NG3oe?fHa{8uuDKp$WO6q3w&)BD?|=8xwN@X->}&jX0FQi^T|@lG5Bz(R}rq5 z8vp}2k4ex-wJDqRUo~&#i_gS4@iyDGD?LoPlZJc$db!O+ z9w2i0oXZHVpQU(UD8Ozo;pRe^$HfNC%pnEMXF}s5kABY9I|~h-V~ns9C!t&1N#Lu{ zSuK0Y=ZHhMpbvl_CLhdC-ICAFTJ)tC?1%s49NJ0z^SF02@P`th0G z3oyJ*`!n9*4JjCP7eC=WoD3FlcP^{N&B%EfhIUZgZ-xX+6MziqJ^Fd5kOgq%BJ9@?+hZ_*EXv}++l z?@GQp4=hpWPz*vtES4?lPLQ;97QlIzyGWu)wqC*kfmssbR%|eXypv=794ZE7&pGlN zqyOXTa&cxQ><)-L^JtqR7{YoCu4>Ep5c1k1t;ktf=C{z6J=Z(dJ1H(12EjJIc|jNm zd1*cRX%j=LwxyUoE+(YJ=v}M(RS(Vly>JWC(Pcbqw6*Vm!HF%hQ%UfgCeX7A8U?9T zgor!m2n*gMI|;U=F;1K%Ytlxe`v$ZV%QV`n2;s&5JZ^?Vfq9Z8H5kT#$_}`4d=oe? zc*Sl7jH72?q8GXp8#)j9KkOK(8@|I$@u0F@H+?)ur_?=5#&Wk+x{dZ?v^oe5Wk+;@&BurdngtxQ{4`fjl zwMkn$fytn8P9eudV0A{cMqqLVTV;yewKX~Sno0}FTm=;KR}eXHC#8fVDcexCRcaKL z5qNDQ)FfGW3e(Ge8`ZRNud!;!e_n{#2ZmfxKUsX_Uc?j8Da6WtNpCsfV-2UdALeP% zlpTg@@zQh{N*G~Xon41X#XoRh@ZfgaiR7!I@Ot~fAZ;s5Op9iHB1sjB=lrKqYfYLy z2#c%rTL)KvD7-K=kKVT(ybtJ>or(j2Lec9X6%9E7(^5rL+CFo; zhMCiz&OPbfVnt_9!L9X8g$cr8>c_Lp(2no_$5VGs*n6wpeu`v{k|+wMDL0)uH)R8} zIX&?%+(9PzgC0tH#?|Mrjs)IzU>9f(Y;^5tp-{a}qXOsfM3SXYFa*HiILP2|7{YAR zs`4ZFKc{GBNO~@+}%(aks5e3MgA^e_=+El|n=a3io@zg*hKiRgP6~eBz~S z+ba}09DpZaT&{RqiKN6Wo}h+fe7&6(+DuK4`s`o5*{EQa7-)+ZKQAPK^ZfP|me%(y zK6h9$t?vQMPB+$tv3E;li0F1~Y(k9>hr?0;^^&>Taqksc^RZ(Exn3MR2yysWOVVsYmVk@$d^qeW-Y1uWvHf`a*JaSm z85$0MjKeR$A7a*kXkG63TKy;D&7NxnQk7ETDA@m!SHtb0f`ATTEC+HusN62L z=WiD2rCC*iTF0%)e@bv06~{6IMF5Bbc;52gYX-)CB(t=pQbiyG5?Jo^rcnyCjsevg z{VsS2fXv|Fo}^Q?SVkK>O{IiuJFWpNjsOxxxhBHy$*@TU)p-dE!(;ac zM(txIs-Q1_HG%H(C5OEl_KLM?Fr{!#=V21jXz&Gs=Hu;p41U+5O;bXGG zR$jwkiUsAKi6*X;#Pmja*9V*08?6xHtDxxh-AY_qb$x57f|cXBOR%cx`DK;>5xaP~ zF57~~B7zxD8uWR6Q)<@~Hn>EmfCU{cn7DEcPZU@-;!8 zEBrgm-gs73_06c653KCfbl)o_+sW%cl$G8*xbVQoNcnI&?6g@gj4W4l^6hNW)OlY) zmsRaG6gGBp+N$^Kt=UJTL7p$WAB)3VU0fdgdBYm_YOd-v85dG!Z;7sieGu}uhVE2) zvXMk@?=5SQZ*>)0sHcH~x ztl1E&+YMp=4g)}2Qlf3an<-E)2n2=sf2u%d5s;gQ5d(v&tG@QBH#e6)8my7V<;~Cip9@K9hlCSV&-iWb zX4x7o%!xey%H4JGCOWR`v|hJd_zhSh1y;Oc1bK>hcY3c> zBcrw6nU4)*Lw0j;OlH8t(XuCHtsK9JvgMK)*7(bM-Z9SVjV=+-UwZ7jQp?gOp%P>_ z13)wS1lga@*Bhv+JzhC;#Bp+k)5#t(Q%GuxUN??y2UuaTuF)pj&usrk5XriO!0#1M z-JPf;<8kxmH{AZj+sJS~#ZzCg>7&0?7|$8m1>Yhnl?sA~$hw#iV&vhulkN*T+&d!Q z06GX@hrx4D<;WMLM4P^JQJcSOg#!D6xpG!%_95gx07{em1#0R{L3XXlJJqzQ}f*^6p+x zy??J07R3razJRVn9d!DhaS1tYogFV#-)2ld0;%5*rVs*Y=_sXgPp8hODW--@ZW^{q z5HzKjNXY^L^@Z{rUt&-Vub}X)wU*E5b=7JD7kANXj>4>(273e8`~PG12=WsmR1btrHTZnI~`bDl`o)89g`- z_S>#|TvIcJpdp{7U_?8!a%h7D_K}N<92f86 zZN9LV($mX-UgkYGS>~iBF~;5LBz53U$*C?$6t6K7)W+pHKNSCa<^^3X9uV0U*z9kE z%Kh?I-M`0@fziJOtq^ECahPv=`BT?f(l?lhg*+|aPikgn(dLp#{6Ws>-4zK z=9O|j`;J@q2GrX5SRPC7YoT8F?`{WG(zx9m!@e&>%u@L!55M_sdvTRCGMI0GiI%LX zZ@#c383r4?E-yKlmIkOgpyRKIGg+kEoe|3z}$Ph;A&urb1O8v>)!jD&}t&Jh7xZuI^HWn4WnNFulLO@ zYZm{IH;aOV zKDDddVWYM>(bk8nsOTi_&loGA2<|emeb#_X7a8z*Mr&sihroBB3f#%6KUBHY!lH$r z^@#vD1|Nmzcfr?Kd7psX?N19;-)knxH|~^4l7hr27k;jR$b4nq$s=3gG^nUkt7}P1 z==Las6(7GJj`qeO>}M|cFL{a+ut~8(HiHJ@dP;U17km+?IjU;;Yn5p8 zn0cZY33A}BxHfdYW@|HTt*5&BU{daiH~d&l)NqbSkHmV@@5w(x5F3yG*|WZurR=`Pi3RWS56~(|1SNMGtQVZG;<*lWJ=!Go-_r~BOMVRw>11Lv-`>ozkP-cTVUpVwW zn{*>sE5D{pY3r}(Ecf^1*5W<$NgT3sB~pNwIC&(pcH0SQi&2K>nz(=P#fF(<%F2_g z3=gl1C$sY!%a^Zpx<0$VGyMbqu-m4uy-Jpy&s5iW!hpFn(K3CAn6NNgx^BzZ;<+@e zSi9*ND(*j?_u1bk$7j?AeX>x{xb3sLNLn_b{Qetw?YLK7o^?ZygnW95t6&c?W|T|9 zcMsJVi+I7Ll;@YOzyG|CTP!hDygL){29@Qk$tb{Hp(k*9RvyYhhrMxtk%cew9{-rw zDJ*vTWSGv+pAUVI32YUA%H`W(!0>dz1OiNC_KRWMpv7O|tZxtIxhsmr3(WWpkt!2% z8&wX?d#SYSPt=!iO5Fpi8*CUR+Fm;1_a5&AUIDs{I~-`B8igGDd>Jw9I@X@~R9d_uFH+ZOV~?VUx6G-IG)aJw?Ld(}c766KR5IwV@qfrP595#D#XOmziYP6?b8S-E zrS$q@0#$?yEg)F7u4Y0&uS4Cx9+qPwkVd;Q<;gtWml z53}FtA8g%W(|ss9^BwaGe332!fRvqG3O5*`0}_3M5kNRP8I^Z2Eh*VnamMi9ZU)IZ zW7pFV;!8n368091%+?R%s`?a)3-b*=r<(uH%#qKg3pO%B8)Z7nCAoCM zRolxu%A2Yx$+kIS<$vlkzr7*eSw>JBiO&`qujGgRd*A^}K%!l|-O$q(s8uqNxlv=` zg!IV4=%y1?l0<#)^{Ig?sXWL1QWM(X&5${%*(HbB^8#^m!AN*w?)bwJNyM6+XsAZC zy*3ZpoZ=bkW)?VtlG{)&BypvBTEp^Ply~7uHxrkkc`1hGs#)|WiavqV^@5D#Z%X#F zR^`VYg%Sc7e#GH#~*5H_)PH(at*RFA`5jsJCkzrMgT`Zy8W2YwvdUi^Jloh$VmkV|5k z^l7IG6gJLrczHU`D|q~B^QKTNdBD>@bqzU@g>u0eY#a?md@N~~51~ULdLPX-CD+NH zDl6_#(wm5Q3Hpwl;~iMa=EQP+g=n{2#1hwPHfe84$x=Pfe%`zpuYPn-$xaMH-S13@ zaN{4I#;6IzOu-ENJTduK@y&m5>P>oZdJ9uee>1Qh)PBHG9eoZn z0QOI@xS}pGc0W9Jxq5*`ERo>-;L27rXr{JL?!qrzhPY5{6#u<2YI9+wbU%@I{uQJo z8yWC;0B1Cy>H<8aL^~vr?E0?#kBm0`+uDXnzcql?U#qd!H}@>aZ)ig0GXffTK8f6L zN-8RL0|W!KV3Z?u)jYSiD-F8dO$HQpRz2If(KN*)W8S;Cvs%Gf(2?S%c7*HYArG_e zx+Njs-3@*@7DV3oajQ9C6vhm{0hVdr2ztEN6d8t$8?jNddUA&z(Q6qQ1A}tz&cJ}RPVvf2r z!`blZ>A6y{`%CD9!RYe-542#m5j@TTYc>o5$P>GLcVVg%8uiK^)XU%tzGq3RQ%g|3 z+pbp&pjx3qT^b}$V(qH}0t+4$K`>!y@c(HBCG=}zW@0t!4U`V3s2`8r=4?b2lCWHl8a zQ8>{ZD(b_neXDm|q3X{D&0lT1u^CL#%72qZbXj9^dV;aX-W=-DFU9(cU!3Qw>D4EQ zqRIq;y9vC*iHfah$vglYX5+Kff49==e$QFF`uB8rN(BSF+@{)2RSV%gzf_C+FD=^5 z2*8ZpWR-9FO4dfs24}>0Y1KaenDbqNa<6LPGT2RZcx0y!?ofX_k9a#-DA1XO;OH+8A}w* zDepe0ckkuNl%3#@e|YHHtw|I$>?;|DSg0rni|lYaXq)w^C$kfR%kDC6US-6ZbY8Z! z>g>rfiC!{wx2&+Tqu+9SUo;P z98-o`7$*s-BnJ|A#ZHT4d243hmxQ&!ljJz<_$}O@CRXcY$5$zG+p2%B&r}4ZWyd@z z*0?YXPs;v_OhRr{>ilmz4?J+_5Q0^s;SMEWlsx1je@j>1su$(|3_N{&X79i0Bh>hB z_?J0=gyy)Mhjjz(R6MZg>n5m>```Vi8HV`^0e^gh+b;;d-VdJ3!v##bpD?Vs=_|7F zYd6hT44gfDkLP~TwD2ilnCKa11fM1%;=!Hy;*gXl`pi$VHMgP?q8-5(?aeJ*`wDB_Dl9d;ioYUj228<^{ z)faXjXfuMZz8~N&98@h0{A3$L@h2R8RnNsLy@D1r29mDSHwADXkCKvF61MFxtTy#) z#U~g8E`ORXp!SPa!uBIgR3c^B?NMTPaj1J!cEgRhW2U&K)=!UB!p9<-aIJAgPq9y0VExn9UvNJxV?nR5Uu3nXx5=hwTCDE-#r^)k74F3FSRj}H z9+@yL0^rwo{?+)@Os&szZJ3)MDSD{Dp~tPaTELZed9laXoTN?Yj7Qqzu7u;y{6Cg% zX$NqY9=wWp5uo}NUUC;)^5f@{6eZh_Vgx7_%Bj-5K zBTB|=BL)#J>6~+%jAVBojSmjl?)o2|!akow^>wLwty-WCGO>bS@IGG}`e53~#XPos zngpd0t@_>2+#T*oEX>3U>I*-^_(G&FVats>+W$2?UTbC}92szNRBPjMdXuunisf)vdE-8x8|>fCqvc%Li9c#x>D>SFG1-U(ei;-gHLs;BN7 zF>+8=2y|+JLPmSYCbaO|Y&0qQV{7!Qu0iG48Y6MSv(3rW`mqb4=1_)o9p{VP*i@v$ z4uW4uks)o6B%#;eo81ebNEqfCnIWGDGJI5e{KNz7^Ze)85Y{NDq|X6bqDDL#uSllG z{Yo$zpiOYQU!1R8;6$fmmW%T)AP!4LiKhAe+< zGXbrn)6JdEMstjv0}N0l^okH;5GuiM&%s$#DWFT$M;fDb{pHT&SInenu)j8#Bb&-@%L$hxVh{Q6CCVLGfkK=v%}4 zP$G0%Y_16(m^*pQ3;JC!5BvV9oQ^HezGQc!bN6Ze7bHtmCKk)1pZaf^g&IYgzq7Nx zs5r5QT@OwjOyw17Wxgpe`IZP;gs`NTJjW4*8~3I(XC$>4+RunYOt^afsW?KaMP}AR z4}^h3H0^tay6*qn@^z5K*gU+(?~NYXSRX4;a~1l)!GnkNoJJp@SHm7Xnl%?_J2P1( zKKKsQBDSYp!O{flfI%EET~@Os<)d&Coj=wk&|s?)ZDh|BAE9&_`zj~HrRN^#fFUaT z$mEdWA>b5N8-9KJG;8151+61mZMG%?1Lt2-Vi@GMEjK1rfK;gIGp zNjOWTuSKXaNyQw{uf>oRB$rXX8#UCBvG!+_D5P>P>`(6si}@+iUkAG(9yEtXyZz5C z)nwp@98>ecbz9IQ*|cijG%YUJQa#!w$lr3j!}zF^+Bnb1K_gWPy5^o}(*F^oc#hFa zDtC`=#>Pq2(JZYxB+M{C06 z@0(7k>#SkMG!zwn2Ey)}VIbv@3uulq12k0J0#)G%u7#Rz=-6t2FMKi+h^>6pa0TN> za}74NG*%S>$)6;h*xWtSx?uUR_(YQ??Km(_zgm?CsOv5q%?16V0JBw@CR;-T*DPQK zZoXn!CgljWRJjYj5qBgLr_nCY_*4b(7!gGYQnl}t7GBI~X_=|XWBlkc-X})INMGa^ z4h*ZL8uKXcj*FNQ4PNLqir_hhBtnC*wW?YI;|9w(*)jG-j_i8+d)w-F_cBpMbpHkl z1$-0QOKyx)IXFtEjIiuW7)Htt;09+)=?2IN_s!8~{2v?Xmj9oma}Q_w|NsAvjBRWT zbKV^1Oyn$M=6sk_2$`saM41#a=CGO7h|&?El!T&&%ADy)sT?!XJDN&;lvT8!@AdoZ z`MR#x^SWNI>vg@Z>-o4I_xt_!h+sc}CBaQ*BJh}Ic2vnf39UqO_WXt>r?N2S3S2ew zdfQgFP?HpWVTgL}wM(ZItouQMSeNH|2%l_3JcaTGyoSkpN|xtAtd>*v5~uTU&p-J& zn_PZ>+Qkh&<{ARe7f3eMQ-E-eA5UkOXRQ~W4s1A*zHG#Ra6);)p;+j?Ommy@W%xgl z`m@y9Kg_Y#JD~***|S-KBDG`+OyBoZWs1(C-&nh~0|jCCw|CA1fxqS&<#1B}>o3dU zf-aRKR0rFfUF`h|;NAmzD#C5!QAy|}UVh%d$1m5UPTi#;@)#pTp|ld0ue3%*^w@-7 z45ys&sdd_ODvq7ML8Jo`b_D4T_P9)rFTZ<0QlEZ3u3_S%!crLG>^>msfEY_0_C~%t z*EgIawCh!V^|+|sH32kgZcg@l`@tTiK3jO=zUSU>S-+>Ne;ywRyXdp ztbTxfQu3F3f>#dy41w+LfqPkmcDwaR)!~B=znF0Ebvz>ukhSHH0_Mdb&I%3NvVO-; zYZqcsc|JnPusAbjN-*L-S(@%nIGYk%0_t}$vY6LIw+tD1D+E6k%8#YT0y>y@D)0vG z9=z~q!NajbS79&!R+qGKd!wjTlYV+pCibBSojhST`No^ST?iM8YSQNQQCia;brUP> zNF2!x%<9>>kk{Ao-5U!W*>F|7W5a?yjYmD`E9^K7H@@2b!%j~*eh)~W2YLA9fc01a zNtyW7DCi^J)tQhe!7;Czfa`|rFqUma6dq^KfJE7CleQR zYqT1|>V@$2JnNcJ0ziRtg1~iCZj7e2Lz1x~fJkQ8X~mWaC4CXBhPvEp+zyhd6V4mn ztb733gfH{O*(ggOf}aMH3Avp7jO8$yv>;qHm!*5U$62R8$y%XjEOGLA>^_&^j8MT5 zwvOqwT_K^%kAg8gc%j?c;b7u~YxKF4bs0LvJBbimJ-S#tEC?cumG1j)gCD zsl99gG>%EKvZzRuN~lC(jo(ocEY7LQ6QbFx9HODfN@6HPAdCK5#ShCGbp^Ek01Uw^?6+R)Nhg zJ~8mZ|ET*1OZWcc{oqM922uk`u%$p_Eu|-41)ys5a=$?J*W>cgTml>dLO-@`vvm%T z#zw`Y2t4~9`L4NT@T0mb*2u?ItI(PE2Z86gar%%n(KRPZBxgHRC+8Y{ws4>S&@$?Q zgS08=LAp$~kr?KciK5(ZR|4=P@3Om^HCLy>fLrN|3`l71%)P#1=yBS=wo_xJ({3k4 z;G+uRpcXbC73T@e4F_sDh#LVieCc3k6Z`|!+L6Eg&h^SD_mO&lHs|(j_*uY-h?5RM zAePC4AZf(SrfQWVAJckn0~9#&?wj`&u`?t0d|RSQwajyCuFX2A*^HJwW#3ahQdRHa zSpyiJt#ml4Eu|F}9x5lQ{EWysdj!i6paDvbDak0B;|S9|*`c6WCo`aJhuX!dzvfyj zyhG~t+i*zs8LXW?2BJ&BMiy$MV&~S}R{5J;`lzR7n^1ATk0*P~=PZ1qj|f{dxgo)b z3rTE!(Y3z|7+^6%r?*%7rz1YCC|Z2&@dS$}pcaNQ6Y|xOnyz ztXKsWP=+-%L0s0~icI*6>M`WxK4s)4tK={EuLrX|%9~IH1-l_K;H~dL`FxWt$qFij z6a!08R6O+apx_P4@Z>C@%UHsOGrbq8ZXnLbh@Q=Jy zJe4;lL=S@^q$8Te`~(tk1|lw_%d>m3vd8ADRNVpt#tpL{Q}2Hlzh+1GFuDsasxE!e zPM42oUeZshEdxycv+rXw{*+WK&oiGM0c5L$at>^`hq%^_sosm$P@2RK?0$NtN+-h; z#wYR3YCIWK*p{$agk7^VHdbfv-f8H?odXY~oJYAZz~u z3WibN6|+H+9uH8`8!j|r<7aH*_M_Hq*J{KxbVnIh7nPB87AZopCe?dZ*{845j8)*+t#*)_(wD0F0kDYAf8`c+!W%;Zjf7NYrEhwI5**j*t z_F5^vr;l%6=;_PGgsw^KN1QbbCC6bZ~dVque@GR~U<_X;}-F$NHfQO5YL~ zs?30b8~Qcpuc()6KrL~=NJ-yUpxrrym}74BLq2a%M;#GJsr#2EdK256Wi~(=kZ=F< zTgB5L)2|qMAtCtH*;By9;s@}mNv~C>1S-@w1r(b+dftv{UXeD^AnjthTz2VNd<>>g>hTAC?5$p*bN%p@@@*LJHTEqpjFL* zVy~lnsb=rQj2$>{br}kfob6bSh3(@zob70|lJj-u-Vtzf_t26*_}R(-las^t?W2D} zm%dYxqIhlF56CNZL2s{wd&UB2q@65KP?NzHKadEH;oHJW8MS96gl2cH0QehpD{wEK z$8g=oP30c~$$PGDBeyi=HTeGo635C!LerSV-;FH>eq`GbcC<{bnP^#b1TFuRj`Ha4 zrLtYJ>zeF1ubvM`{;L{b4wm0#x4E6tN`~B~Edmtox_aL4uG{qrGF7IZ&~rtoYC*Y= z4tXe=G}nRiJRaFWl}fiPO5j&**|ZxOc7LH-0d;K~Mw|UuBy(6VAZ=nW~Vp#E0=(}O!$QwNRY#b9oXcW^zl+-ltjPY)~wb>{c z7_r|*1E?g|-8RUo+Zz}h!=?#cO??756wfzM@XaZ4VD63=x}lq)n6O4Ge~=1V*>vD+ z>@Xc=2Vkuo@MPx=_WV);6ueXOEYS#x6EM078CQ+L*SB%*p?LAQ!A(@ns3{Eh?$Uh` zgr=y}cSP>ZEjEJ+0RUEpN?ymr1XtHUAukh|V^cKJm)-B=#pk|kqgx6();;oM*^*s! zMJSl%P%p`%41!pb{N)8cC(yI{D*O`EM?t2>ZtDTbUhlI1igJK2j3tUSV_KSc*#5Us zB<|5H=hLL_!D|z2XkkB4wnJTCpLi&X{{9^=cq4Qq$yWF0Oy~llq@nM*x6<_X$fA8= zf4{)PU}=nlz8n8bQ!9~EnXjebeFx(|Dw#<+Huh{)X?ViQ2!vYHi9dSq{_5o33IO1< zEXLIaeyzTXo6){^FYF#SgS@Uf7Bo8?Ujn1^M!onqbZuk{=cmPP5iXuWWEW69KxfLq z(o_m4ltg<=09m+~{t}9L&53^-&D;AwCjxF-E=2H^nF?Eb$v4+~97RuL@6#8|QDe_3 zuLoOS070@P%*oPw=g+U_UK>%S56VTI|6VyHkh>%X)_(K+_m=5bUt%V}7g;pgJOls+ z%!6VF$){9?N$~mvnrh*%BDvAhB*RL;RSCDuw>Lj=RU>k?HA73L&HFU57Dp@G)p`ey zky)d8EQgm}AALtICd(`l(DGp_w@gIq93sJajS{e!rjzbt%CAg>R=m!$?sp#Vwl-?* z)6M*DS$N~76}6rwhvjQRvJZCyP)I}Xn|TjV%4x*4+e(7nYy8Zl(+_tl{zP2k|B~5b z0Mb6U1GK-e-A~Hdpz`dh#47BYY9u3{fgyIDIagPJ$QYbE*)0E$SNu?@SAa+B$8}4% zCKu%R(RWqm)}oNcJ&$YEU@?XkzRJkTfy80Gg740zN!fim% zV?wJW{Dxf$N3}kT4E#>68C9is$ZK|L22qW=8pGKNhX)ih9Q|tWm{1Ef2D4`6vd!r@ z>hQw?>dZA!;cnvfb9U=j8d|(M89A3(H%#a$psLH0#eg2&gAO~sH`iRcXehQ7lk3gu z75D%Nsf3YC5cM!PNt}~6_=C9VcY~l+0&t8>Cv$dM5>M3;irFfOI@H;>`6GQnd)PDV zZ@gCuwyn-E4kRxL@h5g~{%rUPjqFe0(<(l8?`-YmSC=8gwoJe&f#ODeiBS-GM$(NSB;pvJW$ zWJz25>kTzEq*{Z+`X%G!HTA)Y_e`O>aIp=7D6P+_kT$@f=jVsD?vO<1~XH>i24Co6?!j}4B0lTnCP?R*ydL1($fmzF2 z?Y}}$K3OT_Y-}#gti52Mru)D+SjGMZluQtlU2SjF>O3do9H0V;OKK#v{f%1e1u`b5 zS}JFSSLlXD+^B^^AHaT(moMNN8uxz=%Rf7Pa}IU2zzz79g)4;DNo_X+gO%XC$3?Ed zf2Yqk&P9(6+Nc6$zU)SG;HaQI^g25kquAm4c+`8{{pW1h+*dX4M`ko(*^r5k>R;mx zN)V?3PPD<%(kpP(u|i*^djmVSr?qTEKB3!G!gKq~8qr4{@a#OlmD`ZYvc(RXM|Gxw za&F>Fhu(a{N))2WHAy=z?1B2c1nd$#pT7bRt+A+M0YB6n&e0V7ml;|!_`&%G&qn=m zvwrp}WK@=TXQ}m!0b*9okgBch_{<*%)yduwwN1gpfcpNfx0<;DUA@3T#>Uz32_I)` zb4!i|5)2#4F3vxqUQDjJfLrr5$TJrJkgjR{Iit6yL6SDG)h=J3Vp_6gV_;cUkd&@q zF`6B5bG~RT#e$_Ds(MmORo@|+u1tpuJn7c-wgB^0F+GWI#dZTh*r9@MspCK))ZLvSLQK7uN=qg_>&+ieC~;`v;2At;-ncXj+=(@Z$&$0 z>eV_Qh(HyQw*a{yJ}k8>rfj|A@Gnakex@iR9d*13;e=wclWd*rXM+TQ6%0f7ZOXrL#Nv@1y)r#Z+4(8(b_a3e{xahI>>QCDn0Pqtw&ov1*vh zNywe8(1Ov40oQjya$&)QXB*ZnE1_X+*B{V3uS9+LV7Jtn-P@gMXU={k-UawprM#<< z126DzeMkHxgn@I5i_pDu$nY%CCAA%pEGE<1G#COtc|1Hk9-!=6pwkKSSJf%xgdbkHgj*>=}3IdVMv6)lW0%Cn>Y~I;J!wcftO0$jdIvLRrYXbgZUN8-q<= z4qcW>kw+yhhoA-{b$|1l=I^qkxnx+nz+fwS`jAx6(-v0$cM3PdWsD&Nt53LIzE|k- z&T0HE@WfzlKZuiqhHDtVCM==rv(VWlbN5=cqbW2U_MbrN ztUhUlAy8O9Oo^9p$hAdT>sh>1X=dcRY58$Cc|pVAL1OxY#k18hTG}%NT94T9MDFsM#QQ*PmVg=pRytnX>SkQG;yY_ z>Ui!v#Rsi=(wytJZTu&|cG8z1DUPNcPzT2r=ay1=u-ld8W72D^opqq)G@n}oNs2Yg zMWRCeoZ#B3(B))+4fKkViaOT8ry=qlz>D)x;%CkSofViIH+T7)+XLyAq|bS4Y-3_- zFNeyeK6RdT$4X>5z9;U|%zA}_rG$7M?)498ab99z>T4tVdFMj%Tu9B%1qTpC+IR0? zAhZI8XO>~^ZPH~Q;vVd4kuCJ-5gvdgwJVL&qTT^n#4ReXarPxYJftK{?Xb$YVi_CO zG6BS*uvXs3laQi&-w9184H8)WWxXL?NUl0p_BFiaeK8Gw&7tHFJaxTw`V%UA&4d-{V*`s|ptqw2Xyc5x&QrHoah%&sPeCq-` zDBiji+3t8vqHKlM>#>VZ0l1VFwi@Su`roZ@UF}^pyqmeuj3pkA5`o@i`-i`)1)S&g zh{CbvPSI@gW(E9kMRg~w@5ORZB+^F2yH0P48daY@XKyxxW4Ag0qzs!f6))Zs8` zKik#Y8zo;KINl!3eA#{ueX*{0MZ17vP{QS^;)%3+TqiOz{0;>sK$X zH=uXt9Ac{{?0}L2gUc}0$cdA&3w5}I3gH_Kd7-dDGWOD>L!W9Wu0A>(d+E{=s1u`u zBDxcz4>F?@T1Z*BI5d>5n$Eqk5-#$+2lGPf*|C=lQqn{zPS zGegBjW9L|&hk<}8Ha(DG8(>4b;PJA_A*Ut_cR-x4begO8#p~ULJg`myWvw1PHd(ri z&LkkXQ3pfNkOXwM^q^B(>WO?tvCnhR~Li+Q@r$JbYFTK>lPoiZ$PMj`%0&()!!KJ7c&(ajnaFJU6Hn_k=D!1>=j;n5j0UPAt3p+~f zBnAA7lM3uw1H+#!kM=v04@N$>1%FmhRso3Ty_oG2Dy^e$S^S}6x3Hne1U;n%D2KO%N-Rwd7& z9+sKbKD3})dAU6Jdv6hJ#fjG_)K?!-)38I9P`O2li9xotiydl z#-t(9UmyXa{qq9zJuq~&tX@%x($Ehdznb}bZHuMPKy(TO34VS#=>HTMbE8a!28ch@@g?Qbs`qHQv^d+rKpP{@rdgKxkkyL6Cvo~ z1Cz*2iUsrRQw<2qgBS?{)h*i7rgTbPAlcF3hurovSP9*xpmzey&TV&BY5_Y#a$n>4f ziuWP?%i7SSSM8xdOU}&ocJQ$d)*3~dL8UZvEM?;X+*}D^l3_O8qUf7C2Q?n5*;nw69YJ8MPHwfLLzS`LC3zt)zjslwaE4Y3DLSL6?a&` z^GB0Bq;0uhVnLQLeoj_!U-yiEoX2A$yR~cwhzl2VTx~2x++-^%36U1thscVLC8=A0 z6z(8;JVyD`14P^R#{^ys6w=ye`bTisa787 zF;svGK>dUOe@Qirp#WFm;yqo_3wY2?>4@;lJl*Wzp*r4Jj&mZ=;vt96TT&gkj(&9L z>4=5j(msG;`VW(}s!Ui}mb7c;BxIo(C#@>~=`^esW)09k0s0UKE>Nts$SW8N5%k9h zfe7fDg~EmQSQtZnO~l^4+@n$AiPT`H_5)t7O+nsQHX>19Evg_5;vW6I>2=OSHqo%b z-PiiarfC5vu4e?et}Y(=z+yPgEDg! z|ApGUf82V@Oid3Yo0W$B+*P(c6-|6*IVSx9u^|}3_njov>^qo zq%y7Wex{SAs;!S(%=Mp{MlT9pwQgd)nukgi5ME;A1HncS@)M9k=t}%|`pZ$1?tvys zI#`#Hh^M5Uen)MzP9=c<|^+)S2x@=uSfS053tVqw%0GrIW`PMXReYIvz z)Y143B~N$ z5&-jEX2%?PT9ybz%^W>nzUw;ue?d$T4s`O1ezPDw-)oo+7x(^iMO zR`mgadT}B5kQYpx`p5r9X3p{k^<7c3Vx?u-`z9J8Pp_4}xC{EWd_)fyk;LHV0Nosl9{Mi}B z{Jj>ysp+On^20^+Gy_Ck*i@GWE72tH3=w63NK}`NFBwK*|6CVK%$^_mUO!AksW%!^ z6ArCuJ|P0`m~ON=++BMH`Z}ShPJy`kQ{yjOeF6<5Cdr0IUL8T~P()rio_DTSA@(ob z#XbLcPR$#)!g-gMFh)-~yj|N$;(1-BLQv2KKn{)Z#9pKS7a&6f&Y++3?fM}L*GA zKSLmwo0Mz?Vv}v*w6r(35N0%`T3Rv>$h$olP@YM*+L2KWqz6tHq&?|F`y)_n1?&|gyeEk86%aW?3)whlT-1fW!TBzy^;r9WY z4Pyml0iwx*u^N7SaO{}~rGD9hGlpsF%h6hIaqE}zMlzcjlIbc)j>^fZ`%mv)nj#gMKaYKpWE4?4=p_Fh{;i1|*hGgKd9$9U&Rao&cx&rWW zn8M-)t*_y>od7$HIUb%qE9YyxHnEUcRg!+wmBPp=O-7C=bY8WO3Om$boF7`q>{b_+ z>_eRqmtxF!!(wvR_e)SW5HuL;l-!^G00c{-#0U9b=w{7~p(QJ9(ZGl(JEN?B^bBjr zjGiSU`|gMe#2;qzdmBV4h~ZemN>H-*`xqjvZRo|8sXh&_?FKtA7X4pC{@3LbS|`q4 z$a4^yt2w}QTB#4*<-kHEi){~5{DoXF*0*3@T8+ScbbN8`5=bu3L~9;ui)wYyyO5mv z6FKC``jK|Q2bq>XZ=p0?gJqNbI3C#PJg;j(@pzLQ}^J{R5 zp_nZC*rzRhNc>@tALmt9%U<8rAdr~YcGl| z;k*3!0Ben`05Ls#%Y$*|P{a~>Ril^A7^-Q?97qXNgs*AfsZm-b`S-_qO0U0R{CWDv z`=Z|xpY99_vhAZe7O(0&GG98fO6Gon%HsUV+%^jdi7a;JS5Lf>|Fd9DXDHX8gR82w zRCu?tubaCb8nW5}Dki6|#_3RS1k6`l-Kkv)L^9a=g@)V^*&cH?S4FvWTim;p>?rJVL?jm7&t+{=^vwEHucH`pXW zkHJOH=XFKLY*L;9^>e!WZ4U+-IUbaw}zO(pxe%sCXK_W_Rl~}PKcHUGP zF~VfNTQia`bvOXT>A{~igQXD3-_`T=(9*{*B!*lS zfP3`y@`QeTKrixh+8IX+0}Sj+bEpNxypcJ96c;WkEaKzt0s2n`7cH6@HiVAV;66U5 zslU3VRrx_i9mdRJ{dj~1f)*+cUTc*Jyu_TeP(%rb=3@*Yj`#ogZO$On(GOPz@8T)a zW{r<%#tMwL}<2+6$Zce6@xy&AR~K_Md$B-?`J#T1I7rk z0pQc-Z{OrH`#lz50Wiup6jJ41g(!E1Ihh+{dz!2Ct(3~(=rd0fV!GBofS87T9s}WF zt&7*%=G~+79S_FJ9lci4v$l?&VvcC^SoL5=q?W!-ew&mV{r~H^w_5GF0G^w%q9_`s z4;1yQ48eaWkkkzH?%5bk`5twHySvkuNaKFsc;;RN`j?8UAsRYz3^;xiEnX{p8#p4f zR?M|Bl-7hv=`7Y(FDc(_e-lnJ1jZ0U#Y-+2shI!W>C-OK_ASH&$3UZ$6W8RY5{3qE z(ihz^K#T1XH4}5s4Vml&x`~oQO*#uH42otP>w?KNzDbgjMX(egw^RDfeT~00mt2K;#3O8lu|5Nc z-YG)oMR2DdhIOg9tE!6qF_nM9oJgcJXDm$il7vNBkn3Fzy#1ru({pZD6 z{ytU3wu~ZJ2d%#4uG;?9&J9f>j3fV?HHlPn2TGDJd(E~!C`7=@4(({|b^T521+rlP z(3bJ%jf7sm`id^h=g|*3d%yTyb~X$zoxBD^eq(s=QD}>IR_<4+sRFGOTZxvNHhAW0 zP4usRTnv}jxT0Fop+y5lR$Vdvr9g3A&V+B;<{1L8XcHT2a|L4)W*dv~Y}mN!uh(8^ zbyI-}@iW6jnOjhh*FWk8H7O{Fgf=a?g?u)VhwM;D$d)wp)RpZjO;xL_|2*zjt)k|N ztyUp8PDUv4TJdy=Zxdivb)Y;+Su*Rq7rk9;hI zeFPoBz=t%)y)|yuf~xnGnDYkP8pp1o3S&$L_HSmgqM7$P@VNNCk%J3mwm-@6tyX#b zX4hHEQeOKNF7{uVu%SY=3V68_Jhl6D>#yj`^LIzKr>n&Jpqu+xzns_wl5?;8X6MMW z7k#?I=F>Cr&kjzuQr6^MXl6(5>$v)0b1%PMJr)JfTJKtx-4Y2+qCen90GqW86TQ=+ zo7Ieg1O(!Bm7QK#oZ)dgwjfXd*t+YW&S z0OHcL-$Z+%f-&&@Sp=dy$f74;uhmZlCQdagI?0q`DNoj#@=8 z=IekhPlf7wTK|i%9Z{#PXWLS6A9Xie3Grz7x3Kc{-n<2|+s2xrswr%pU2TVXJj>lm z$$b{+vga~szF1(LI{W|u#7yT2T-n8OvZwXW&VGQn$d=kX?o#T=>nS#-nAl~ao1eZK zrdMC=LI_V}Bm#Am;Ly1|bMw=Oa5JqWN|^1~{JI8cwHKolk}>>#aK^ur(0hHw%HG7W zp7;ePO!_n-194h@ftfdw^86x{n>rKTMW!ME_r8VbLP|9s2d;3$m*YQ4zkyzJXZo#M z=-|M2hWVHBxI|C(J9e1)8VUhEWI3nd2y6e!lP%B(Du;7&KW%n4Y8R{IvgVw)o$ayF z+;fgpD3s6FA{9Z*!jvB;7=6}D0IRY^&*@U@9S`fqSTP#1#sr2F>b%*?9pLXI{Ifmu zsQe)53af{8T6w^<)C5(K`>ppSDOMe)dWprU%psb2M!4fo^ zJunHip7-*rCsj+Ov_W1wjR>~ztyN%p+h4OTsFZ$7cp^wRT~d~=nD1l-P(pp`0`)HX z6hS0!yfCNSzFDRJd1O0C0vf&`1o2HCUV7V$?1O4X73U4bC8g`lk)qb{3&Ah5qnz-! z+iQCe;>C74B!)$?+8|nuWSJ@}QLVmVfi-u$?6>-RXr?Z~p}HA#NhQ4nc5v!(jB?ee z+q86*#dn`dlLOLVA`uvWCXaE9LXRj`anFn(B^NY-D$|Z8Q!+cu%gjSWieJ}t4LmV1X-xlYy zrSDG0dF3A*S8U*wK^@VBppVPeD0ei5M+)H^{3lmAVnGTi%#O^-PN6#mOd#tw}_ z4+M6H!HTW#fI4>h5z~HE(Ppg+WFd?=@WB6NaLh`ziEA9H=A2BJb(iZn*Sa;YBX(kL z;`u~}syUt8sSr&(I{W6-m{5D~g$AJ10iJyPG`8T0=*aeOOCG7Nc?^hq`gYR)FQb{c z?J`EX{V;+#@N&URs24NKjV-ZNob4}*ZFvqO<*S2RTw0zAV$~dew#cq+6vbxIwiA_N z+7i6<8A{SZNIATGb{2r%9J>7@iFgCZAfRxUd~wJ*&})n?1QK=A#ds?O2E6v}^%y*n z;Bf`J?hbB3I@7y%HC7m(IY9akbj7y#XAH`y6*$Crt;ikc@8sqIFpD>fsDRO-o{^0= z61hU??`;a8oB~P<3=nfOcBZy2dUnZ1vY?Q%#CChh2;@!K!!A-jMf*J^vA5_gGV?4- zde64{w^Nh#`cx>91Gc15gv7>}TSaCX`ICS@5|*S=tW2G{IAW)wXX!QTWI6c=m5JH6rw`I=RJ-nE=60EnA-M9ctsq`5+d4w zx^5%|Z`H}L=ILy`GoKg#xEwY+|L4!KbB(m}fBT*9c2 zW{r6o=1Nvipr@uT{sv3xtnt=>xHB5%Yer2n%LEg+!n!2Av^JiO2@mb7tl59mr7uh@^CjU;_jf)T5p{AD9GrtdbGWxnP(;&T0kIrz zt7g0MLfGtE8Bbdni(3Gkl&tU6gp`6C_k2PmbHs`{TT01Q1nr=}HTT?LpL+h7!vMlpw8UMl1Ug6I~ zfVs;$V~)8A37RvLPKSFq=NgZ>ds^*Q<+UtB7=Is2ie@Jj|09&7&)VBf?l#<1Kx(mz z8h8G6_>y0tuHMK}5K0frrbTqUiD6E%o$(Zsil*Pm5Xcll?)tL_5S57Z>Qlq4KZxvD zLGL1HMV|>%tx`DSGQ4^Zk2t_Ga4rl$1(*bQ!2aypS0`!tEJw5hSeJS)!thyzwFji@ zhWdnd;v4ej2`gTnQP1N*0(b3eN=VcsGfFlNF{~W{4p&^U5frr2KGl=-;uZf{ z8>e_DXgk~s#LTObTV0d?i-|VKDyv`X7J4Nu*~hyzJFk;uWSrK84(og$huZZR$~XBU z`%s*r!qjwU>i5E5hz(8H$Ayp*i@bEB6GkC4EJOojzd`IhQ42^8cP(-^dt*BC?VE!g_m8iTEv$2+AevO-f9xmh6kfY%Z_0U@FMTGC0 zu>$9)b;zMx&7vv9rJof&5cy5rP0lE;czs=sP}mrI-ph2CJ z)+`mvpn4gr$HzDnNT+P-XKJd9F%wa7*i8oa;zE(Blu?Z4uS*jD6#Wn@?u!>&6B**j z|CD9Nk~z)@m2!b^&fi*rtT9a4uXZep-WG#7tgJezIeXSuLAeX*p9MHrszFw1SQTx2Hl3VtaU^sqVnb*nAeEf ztPQ0qJCfDMA#?_O|65C6XE*{T0RhLRR)8}vN=0E`h8v)cTiGAdPe@9BB_yCS!#iM z^yhmfHBqQ$9F>R*H3v+Z1XybFLc_bC@JYkB?;9VvK`YP0;g-*1L(T>@VcHWtduxe) z$@Ofa^Q*8tj~)cx7Aw=7iM+CmbGAB>hyyxa&djEl&45M-3lQ`}U?`l8Prd*=(Hg#7 zrBl!-j7f`3;31B(d-hQd;pg4e_f^PM(!4lJR&+et@0G$I;U0lur8@!-^Hr;D|ZiI6ng^s%Ara*UKy0M(=5$uTv z?|pOxkK4Od*4+^Iy@BDYJo5R#MAXrN8!GNpVeP8Li0UfTc7R*cpA&q7K9qaEJmPI!s#6b(sl$qKZuWe2!5298d^OIIvYDw~g zr4-rDu*?U2$$!{};cRk{Xmw5kQ2;JwVMc*F29Gm!fJ>MiI=-7+gZOeaHR^S)myE4# zx~rZY5eD5-dlRmefV;u%4Glf5qwS8yx`M1oylE+B9^$nR>4-%$Q(8dxiWAL~~aFlX9-9>!!mf=>ubh=z6!taz|0{Z-ghF(|5855C>_fm$w zp;9RGgrA^pr}Uq8;0H|-Z{RMdvYzRx2H^%nj>rFvN>!(MEy=F8BAP(o=8uoqB&ysv zemQtVM-qcsSEWI@e`JqWHA<{PzMU6wBqXjS!0i1Y9kWS%&Ka|%T}i>5zPc~32~*MM>%a#;iw_eV4n6v zIt8(Rr_QpHJp`fCub$$&>WNPdQHZB0wu#hh$9)SJnJT{t zar55j9+f{Va)ioX)*2$hN+W+R;|LCy)q> z7sea-%}KjYf~^`=N^cUv?JP0X?e^Jh3>xO|1)x>&AaXKoheHFKeoKo#?ePq7PbU5k ztI+tV%RNv6`4OmT=~%B$w0nQ5N*^`A!Qoh-5{+Y@dG2 zF=^WnWQ#dopnY*!Zdx7%SW zE76Xr@de*8cSuSdWKGLpY<%}W19wlJ-`JwNgw^;5nZz>0}SFImWCI3K9Zx(t#C_E2x7iaAHbu#Y} z!V!|_?kgVCcyVFoBC#agq4hYj8=Jeyoi5sjkHjOIBNMjj6q1Iu#uu*xpV*BZRfKk? zv(1jdE-&Sb+y3%J>rEW=>PFu(7xk%X1U#NrvtEWB_{}j-3Gm0rmh+w0%p?v~BO*k@ zBy3%Nm*qz~3C;BtR7Tg9hpWm2la5Hft>p&$?g+s;mZ0b{IEl4C|7iHdb(+d!406UN zYZ3>GV;u`;x(W?KkG5S(a@P#qhkZ;4HP7_+GL+M)$s2}zia#kVZ{PV`ybm@cVrX3d zrr`mq>jD(0bV@q`TD8(vGHno5y{gYjz>jRP7m0<>P;i*8U|%*7Q;1Z}R*hrdbF>W- zOST~B6w%N?CaTZOPV2pUz8IT&P6J^@#VCc}&;t_Ojd#YbN!)?xbUCUio@toxIb4je z{ArVJx8(?JOHQ(+Y3Z)`zY6uGq47}}K&M#U;2!~;5r`0I-v+pFN_ro-WFw+>Fvj|v zG!NzM-k%!GZ~us>8b6P8+@bUZp{TVAc)M%wo^qnZb!scBtmSq_kqhEe za@qVB6$ea+Gt@z={nE^IlyoNSlzeZIbe(3pi*S#j(QZ3?G5=h92HdB1=7jVW#r=n|eO$E6qByEM zDiNibfYUR5;mO}JI{|Ksxpu$OBJ8Dq4dcj6v}U#8K;Pn%y~*1rVU9WA5n_*M4;2W* z_f#Af#q`*#g`?O$#p8veInY(ry%#?OU;n&r@PuXPlbSc9cM4|PBJn8aIn{bk!Y2C| zWSeGA*TLznMJ8b1?&dwG9tNgifqkh&u}cCBpUXH3;Ik7&u|zAq;uiAQF948o*VxsZ@b_MB3ECVU)dbh>UJM@9LN(vUL+x=yMVaQ; z`Nc19ufU*)~|q5<~W$e z>U04xIRKxzZsxs;EfnWYFtP|g3Fj^?B-ZxAi_{k)OvKOsZ?bLpDui zpRC@FiKfn%fmWK|%Yft+gH32LVa(u{;&R3u4L z{>H8!Gv25T$ed&DgGm&*wGDj?1<1CQSLu_jcyja_uB#yNnaDf-9sUn4-zRp! zTTf1XsVKmIw&V|_K+)S**v7aDHD~El2I5Z)rM$5wDc;;FJNzP_g;5l)F!2+8IFT)) zRBIOL@q(iki=fD{h8QFL`-D*0Vx{^WoBuV>=WOb)DU09yj|7|~9J^&21SKUsfAjOV zrg|kEGj_fC9%ex`fu(5VDN}+4_Ghq8ea#|n_Y9pqIp2Jqpq*JfNnmRiq{>5o@I{7E z)HDutK_$O7F>Z~_mAFkEJ@d-WPQaXZ-^~KzmUzc&wpb#YPI0eMtsW= zCbF?ni}XoTR?QM$A~Sp=wBQZ{%BaRGJW{}*8g^q=MHbOefexiceWKGUL171!{-pMU z+-@*)BrzJ{+)ei&fQa!u)x6}aic@tP!$2A); z>$5{!jjJA$KQT7(G^BIW3EVpP3{L`3FnzlFRDx7oaV%3# zfV!O2Yj!%f;RYm<&y39-SCXwYo!YzQblihtg^*9~fOq%qPS|5BtYR$xJ*+Ptv){W% z`&Id)greWzHlFHiGpF}1s<+omxQV@IE4zu{yC$oCg3nsu7c7p-K}-^oSH{S4>W$hp z32X7aPzP-VL=7C7${)?r4U6c$s*Ng;EUGlhy-M80bkHd4MH|!PQ*IGhy}?jv+jcaI zL`6vtKpKRj&1_R)y_5NI-xWq z$}#KJCpjBwvwYgNC~~nTMa3Ku>^5gkYXm{5v`5MnrswvC+}yp;a_GF-htb zO%|Gg>$H#=3Lj26eeGK+jmo$kALsKDj-Ct!UIMw>Ohz@TR;u){uo#^+d8*gkKc5)R zU;zDB4YwGt4eDWH?Ll~wd^es~8qC!;@$d61&hh#ywY-yfqUFSF^Sb5XAQ zft$03XCs~LO?JmsRy5skub;2E{*2~?rQ3N`J~=bBdJGygGq>%DIscnD{u^xH;U6R7 zh|8x~fhlSG6X&XPtNRERW*NAt*%os#Vn}R!7r?wtSR4Dti+s7>DhLz%u;CECQXHid z+q=2SF0O_-L#O7au^gxGy?H7bfsNOqQJntigOPvjoGK?I;8s97q%EpM6(@)Te_*MDe z^RQ|@=A@uNKMo3x38EHV9J_eYe~IfBMEwD#ha~5K{-Z#_N&;Qr=ilcPL=N^gRBjA5 z>tGO?M4Y#R*Kv+ex56~N(y&^N$X~HFpG{6C)jC7(CC^1)XAythZ7FG)G@Jo@#&r9i zC@;ax^I%06$*S-2em6=$DxBVClUm;-u3P^!!9;xpo?vy;!J^wbw~4Ekxsc=ivJh?h zDs$pPnT+j*PE{3TqbCx96BVSpmL|`tMgK6|5~$(q*S5WI*DUw&QUlDh)!e32X$9kY zzQB35ao+a+1W(u`;8+cb%CXh3gFYZ}!uC>fw(#8UTNh{pM~v(C9yiSsTA**8`1Hq> zmvg&hga0)-kZSm<1Z(NhMC&YWY|(f_(M;|djNTYOYD=lRJ1KP2mTlkn74uX0qwuML;bk{FE_%WJ})Fv0RQ+`CSf7ns_o|fwoW#avF?u>1CdAr|-XUCZky2K)SoSt91p!cJI?maI6G)3^IdMO} z^M|wH@mVrpV%H(h(4@JlMZ7^={Y=|m?j_!10XowHR~1<&lWm;-lOJLt2QFtmL*3-wY$Q9;-lj)jGEy3_bZ_Zuaf&bp82mPCk}-2(40b4%CV4J zv4iS+4_zs_P|fj(_kt@QD&8OnF4el)cq@EDBiR@Eeg@$cB(pM|26AJdLdPCoEly=Q zSO9$A6JBNX3nu}^UbVRrA)X%W11Es#Zx|t4XCFK#t60t-Fh;dBcn&{IRWaPxa@nKq z#yr2EVwP!mLw)}V3^=R=Ti)|(Ds!StoWOwg0gj>!Kq0C9t3X9jIBNh7j6WmI-T+Q-PlGp| z8QPuhUb~K6yHu#9*Nf{RmU#Ps>4Y@mpY0`35AK|emytx8|KE(shy+b}yc`ud!FSX5 zxm{Y)wnlDvCohYL9B{HS}h zGuTYzY=B(A&Kh!J0n$2iJnK^FiDzuT;)>W)pGSBgg*)U!>wK5U>%vnm^IrtK4n@#2 z{zL)TIA>7iDofdx<|N;DZ`0$8g7CFrJx(vudsR_;<1yvb2|_;&##DMYa=+q0ZfKd? z7Q1D34jDB79oME<3I$!3tJ}R?+;{c|glVw7dAkVEOLqR=2qw#hTNnT1Qo*A_tVUI% zUDA)5o5b33q{57*XQK6|1`umgJ9Z2D*Q>d@sw&EUDW^AxS%=7P*MCdyb${~wZoL@V zmE3gzNLSx|g{~+kL8Y}*$-8JvA?knw9SJ zk{!6qguK`NBgoeX?N#T-MJK%UePeRn*bel?HMozYNKI-N6vVi=NWdHTd!5I3--)eOH{A24=XX7HuHq7jwfo$^? zabra=#-IJgp)>!FSh*Tsb=V8zom_CG>^!oLK%ZV}db=+JzD()hgY0 zDOIZ$<#6>aW@Pu@@!5pbp{NyJcUA7}xJBswF7!T)y-JCzJ1}2RQ(&#lauXXd_gxOe z=sGRm76&>hMOQZG>oZC_Pdfc%#kT~w+Qw9nOGi)-!O*AKnA|O)|Bss|ZLVG1yLRub#kVM0Q z%0v#cvwwK}q3p_%H~=e|e<}BXGAUMHHfn3WM!DsfpOc#SVMV}qzLU)VCg1zyQ&b;M zXYO3CU#BTYJ4Ww06Z^C9K!I9qEG3-6U+zylC%OA`f+??7#j+N_pU@0yFte62G7G=n zh0B1&w*7k7H9JYEgi^?tSj6tk1@j(Ao?a0KVCntP)MBXtTPFtM*xR}Y-*+gV`As2Q z``!>jDstS3Diab^_IOi6zFbJZf#=OW`KlKI(<$j~?z2UezPsLT!HK-+(j)M_G(cU9 z)F+odPWa%v;Qd7JZJ8aH5;186dKIVP!$y&cIkp$@>5S^=fNdWvo3^DbT7eryG7Hxi zWHJCQ_8IhE!0uC+lk$p>lR$I(R-T#-=WW_)P6_=hQ|%M-5BstH2-$AfqfE}BMo=-> zw^Qxe=jXt;NFfHX%yZG7hi>8z1@I3WH&ywaZqjt1f2N?Uk4B)lPj&)&E;}3h;`k5W zb_xMY3!)K-Y6l6kWhBRARx=~k-W{Y+G^cyE!r+}x%lNZ+$~JhBAgVr6r?Goa0w_Ci zn9@2P*R0LBMUj3Yk`W-!IkLKb+|Y5{W?B?Yvd^Woy9VyN=TJ>CrY>gK<3VKV(0^M= z3vShRey>m{;~*_MBH`|w+prm`AAb|{kT|=D8*v6nWN_fppL+VoY(!%v(=A~M=|g9w zva<#!m0tcx>YV%m&UY-Z=JU|cR#_j%!TkDWLZ|00_E4P+w!wSot%9cZy1m!&b7p&( zxu6Cs%ezke3zE^~huFR1Z6c483FS`nTT`mSb^PUY6*cvgCO#nakWxUQ(tCGd3D26T z2-O%vrsXe61?k*_Kqw*>EvqhQihDZNaxjN>v_*mhGYD4_k4UkANP)rcBg&=>i{?NF@n0jmx}V}&J7l-i04S=S33l)mrOJk3REw@;oi z&l9|HiA^X0QK9l#GNbW8W*KkRv&$G7KNuzp0loF0JA%! zUXSgRA|G5Nl}9TztbwdtDBTrPo3IJnR+cK&Rq|noT;h`<7|#WQdImg{uss?=;jtM12i3ordzzhq;&H7 zt|zK)LT{xj&9gLDK13hb>nfL)PMaXPka!hMj5OVHPhS4Dnc))i`j3!(6mJIaN7t5l zzm{QWnqSQxLzvWZg{6LQ! z!4kLRzsas(rmj6>g`Y&D+oJx|tZ*$R3BR^E1G&a&e~iH#`q>*TLK65=lfY}ekBdBv zxuD+~0^RG=fNhi;OyWJGVTT7n`D4~`$&&)A5eGe@X4Iq0IBm4rWx@vws9x2PWLcWb zm)w|Du`+<2+om$i=yR&p8QZ8@6OmNc*J)@g*!yxvfA8T*L$H0B!F4c_<7m>y!4uT7 zh+hoP-n8Sv=o%*i_~&l4f1VLh zmZz+xajKIig+wYHSH2vHUo8K5HV3LdCqet|SKOW^2;MLTL0_93s+;Wm^AW*)BlWt9 z>zqP`o3Cc@hKa2Q2u6>xFeDdw_|c4el>?^)L7HF`EJf_$Gw|v$r;u%2?gGqa>HJ)} z7W?u=u9~JdSo>ubT1h&WyP0eN+E7?y*|SNn-EOQsIJsREHnhXKBo50R20-%3Dkrpt z-oXA8D`i(~DKGf;;C)D-mj>?+(ecd82-t~zDgH** z%}4VHdzF*)QgGwB-S+Z#{^#@0BTg5a%pXp-!J&TF2S)e~{A?&fmlf<7%kc6F-80y` zc}RAqL^5P4w|FlsilxqNysi+c$&?!bomQcf!Aau;j;n#dD|xoE72MhUsptbn1l!G2 z(pbZTLXiX2VqeeacYyIR#U1axv~5S+zwR(s>mA+)oDDYs`45N7ORsbVu;B*5TvW6GEu7Gw0f)vUI!6SrIesk@g zznhrrO(i0D6%&6>veGtfw_}t2makZ)#?=V?1f=YazZw~-$CE9bfgA%_gbr-`XW?dV zSq&Y{56XFTI+&ECJNyq{uXvoqe=H_h=pG4&{>N}=JgfYsWHIW5T8tx7q7c3zte^V_ zid{p}CkZK|Vt2>cSx2WV3#(kC^vAL{=3{awn@cf;qodaXdmEpoQGX)}$@PWtNYm?Qze|2;{D!8g|Ao+m5;I-oQy9V;Zp!G(*4l@6g6?bf=$Fa`%$I1HdJ4XXM!feBGvV_ zm2CV_Ytdt#%s~(DeQW&v`7t(1hTb-q3kZvar|KUfiZ}W$?7_KUb}4_YNz;0~02jt9 z2V7sjEY!%`2qVKpr7g7!+ZRW}*si02JE?r%1>}3@{`YOFJED&U&)D;f|66R%7~TwyX$&H66g{d( zm{@ewml5lIC7YwQ1kMAK+y(j443!G)6U-e&CrbiHN|Ie!Yb*t#fV@>hsDNaqj4N!d%=3wTbk68mJg#UPt!=4+5xNpon-m9ux)-i#Y*9HNpHOGhIT~fx3GaP8rZSDOjZ-rg<#L{Qj)IvS zHf;{}o?LVs{)nk!fG?A{B3~N_D2#d+kkFuK&Etc*Q{uO;eceM)fh)}TE7KqRA}dQY z@va|y*=pA)hKc4c2l}rwPEi`)I{lP%)wdFwj5>Q`?ZS*z5Uz_g(64v~w(9lbo2#RJ z@lF{Qqm^`v?+4G@b<3UJxW~?|dBnuh&AEQ!*_@QhaUL#$=i{93W?>GynS6~B!K;N1 zi=Y^IqR&D1xKUTA{=#@4Qxo=isLnsPzK^4+Sc;lVy>4;%$XS@xOFjC=*uvLSl#|7m2X?ie{$j|yOHhzpEn0)mjFq9m1`MCtp zgmMEgnChZ^t#rZ`l6BuFB)SZU<5e%{F!PqtF<*op5QD}1*F+pQp7KLrjdys9{Wk{YS&4-*K1?%VgrpNakK@DmEmFE5W;|@OZB3G7I5VwVxD~OPL zQ3Um7TxG2vyEIRN7JgPJ^iB*&Dg`|Dj>lW?m&}&gkw1I^fT*DqL;1AWFkzQ~aM;64 zKwK+R4khDLS-KW)sI9hF{qg)&rOoDcLoZ%9rP4I9bo`!u6~{(frX!?VoMb?LD5PR5 zuDE2U6L>^=-V0=E?_IEM|J*3y-Dn93)o%)Bp!tk%ekiMy{^Fikp)zYdY0t_ z5~Ixw{>i|g!JbVu=K}FZZ{G0C=cRd-GjyJB9_5r z>a0ax=pf!zx|;H)+;p!p_uNO{N)##7@786n5QK=b%~ZtWCpMwbR|$PI!i#s5T}D5} zR?hL@^4f5Z>i}Dg&E+_|j`+xKMI?IR)7$-bRxcJzvXobPM`U22b$OlY>n3!)ZU?sJ zF$X6)ob3~Goocihxn!gqNrWYQ>+MRN+ZOxLyFm0dz<;a6_hkh_ah}+|X!A-GZ@V8->VT&*5-QjTpBxK%Hu!Yjjx;gKHc4N7>?? zt|_ez;^5=?0l}OTDPmFs@zR^xMz&G6V)IZhHM;~Tt`{#J`=MgpG5dx1`+&ufhbaGb z!@Y8Fngs{g5P->^pK&hTC$p}2Th=Tx*gX$iv`a}M~688?_9y=wHpWmu4TXH4) zN65WFb=4BKP9D&{Vhbp%>N| zEP#W79iW^T3~(Tan&7y=<>7#j)IOqJAk|Y82^Mo^0a`NVZshklvW(Q zt`|yaOpo+e$mi|_XK3<;QEcpfHR$VPoe|H%pJbu?($A0rmk->6Fmk)}Yqk^S{_46Z zx!Wi8hmal5t(q89-RJ%ns z>;+X*iK9n(Mv%7!=0>Z2jG7zAOd;qpgV4cAdBs_3uP3LlnVoun4PQz?X+(8rN<_pD z0~NCcxHQ1GL`Zbq%D$2_;>)zBlfOoKn&CzwM+8*dxWdT?A%QM5VZck8cr^NSmId_w zxV+T`k!oIXcmfn%#=`&F^8Appn34G^^UcC$nR)D&&>hiS5y9C_`x}8#nYaUSnnx3Z z;nUBGj*l@hx5)ln%7cJc_lX=8jl(;HuG<#v0N}8b+R%D%DQ3`2mr`YV%^SNrWf=pE zm$-}q8BL8PdD6@SNEMqfwpj*GtluY8CGZdLBEL7S;*CT)p$445xm%n%hii@=@>CP5 zD>v;Rzsn(*sLf*aIo1K!jOKN>|M)xy62C5$!96q%aN@EI%!u>m3W@-%HEPc8hw<^q1Ep> zo8i}oR#&S_^zImW7^+;CK>w|>S>AQ4t8K;Ct`qej25l*!*K1Z+SNCaV?Mh!=loY>s zJ^6Ar<_6K!y5W#SFT~M%YjIzi{`{`vNwF7HO5PPryK{x@=HgHc@-ju!$2|O&$;`_yIJ2y177IaSQs7frE6|n;_JuLaDF8>ucWGbhDTntql6V3XsIES3zGFX#6HumZ zDV;<_-TpMBadfgw&6)05UZ`tYw&z;SY}zcjy#@5pNR&EIeYpK*B{aXIZfTV-&tFxG zD;=x2#+&D;oPO)|=?v$ts>{yke?$FG%y+F&q(ClqiT2--Qh8WB-bGtE`LiNn+XG08tx!<)o7ah-zVaJ1i zQRP*$IeIUKT3J<5P_3q8Sg&#InM(#k3MidWq%{q@WxlO}QvyyvVWYG;v zuiR@D*6Ydpt^o2GSl4pa6@qq#*;NIuC5`HnAncLX?A{Z!^HYNM&xa`o^b9Et3pAZY zsPp5Zm(m+-8 ze;~v_?-+RElx~e7pYU9ME-hLpEcR6){OVM}><#=Kk^jV?QyrDVRM*Yey5|N?NAEGd zUS@sx=iuS-C%?@3LAB4`s(q2QekR64+f}_hYrXUR)N_jqYEF^aA#F7EtCUhue0^d4 zms+yv^=t$1U}JS&b+}~NratoL7u0HDk9$+uv-?yWWY|VJ>@e%A;YZ>J~k9&|Cd0 z&+?9?zJV;LwI@lZXO{1@BUpks)pkulCFRBBW2Ri}9j`gLNQ4{ZrhV65aC#8tWUBG? zv!={VaZT}1JN$3ztf~IZ?u)%-`Kqb$54dgUPbxWCprQs7u9?x z%T*6J*koncmyECesnA1Hj0EMU*`y445%|^YJ3ja=BZN!y)I5Og1cIPa>ydlIF!_XN z>V}%FpR<{rpt-UBy6?qOmY`%}yF+2o{d2CwB7FgRO7!zdYR09zfVcAfs|pVARmxhH1`=Egb3+h5waeeqD~be;5I2_Bulo{0VK5oL3DTBt|TSB z5KOxQ*hij=LL0@%gkf1)mRET1)_o25(C`E1d8fo1?pRXwT3*nVS(qrzYTy+ms z(60oMmbc;gyT)I<>sY!>E{vZC)%G@~ZkR!Up6TekG-zBGz#Ro}YbeXASw?J8N!?(0 z4V$OH&O`ORyWKuc*VL%RxHKD&1FayGE?oLXxk7@fcFL=I3XpsdU+6x;fLXy6VJ^9T zQ0fg8xK!h2`w3wpc)ZGDM)8Z^o89@|#@|{_VyvTTCcC}kPITVNFe$yQ!%8)-Hup@t z|EO=SXx!+ORbz>6EpWnMSB+`|XbXdNDMeoAM=2Y~mKDIWY|IEiu4b8{&89)_3pGy6 z`Ss>iiIWgYe;Ujr&a1=pY0I0B_F`Qi z+FuCgJx)sAi-t;mX}a|R9sa|eL>Ynqx=IduENXEmgZU;aU2rbYZ|&VP9*4dm(o@jTH2T3N1kHx0_WuLZMA zwM=bCiN}@6cZ0Y zC0#9VhK>VSy?}YpQwRW4ApxKR8j=F}S*bDZLGg4SXKv?wEuMfz*Lq_nw5dc#i_Cb~ zh|;Yq2cXak{u3fm9qH!g-@ODIvpl9QZG9MKkDr~a1Q2$JQxwg6?#26@!3AyPt`~WQ zmd0(AhQ;Ry3V;MbJ|2H0VB)#1!08K%+B7G1j{I2PsXcM@8+dFJPCqj^g-c+5&a?B? zAMCWUOLcy~L#u*SBV5LKv z>*5j-b`5v!&6LQ-AW{yo(?O=6^9Sh-`a(eFi|%_ls7AKUKhi z@@4yZy6P5cb>6o->zSI%glN{&0R2lTdYlru?d#}_tQk)W_edgz*JwMm^ zN;VE0L94{n7>>xTTwYrd0HiNWiz0z|8B z)Sp=jEas|$$uUUJjW_{b11AJq%$9+B`w#|@x9@@`aZFOQDa=_@?48GN$|-g zZC@z8VrFq_o9TI{l!5u8gh1$+oTo-cY;eoRk{ZzIBSPX?7>~`)3~rH&*2#AQ_0IkX zTFFP;7#V47TX1A{l@mc z&HS{e_iABbk7XY@$45xQDx(JX=wFLE(`f4Hb4)3U%!HmW?rMA+U%#xxV@dj_U#MTSlcwD;%n?ILT!hguuop43@ZNdk7V@zPt zBTlywuX<-km69EMr9qPLxpLsiL~$6#m5#9tH6maqDGXV&oc4z9#+_KteynWa)uMZw zw%^AtRh#G?YwmJo-U)82mWO%a?L{OvC#`JL^`Dawg`K7DNXIQ6;KmCnx%f>>LUfzH zs#p(symg1F8>s1aH2Q42DuNwa(Sj*~YHnWY4(==k2>4$R#d8_`O7FtqNtkU4jz zC{On?%8lez8u}6^v=nW40lV-Fc*gV}?&0=;7^e_Tu`HS@+R-xkC$?&kPYQtOw0By! zKf4{scI!>otNHQT2Jd;hmKJN325K=>IK*PDNL@n{<@$0<@nExyUaG>Mi2*XE!d^^j zh~sj`ir`9H@1hp|w9l!BkDoaEqT+nlZsgnT1Lpo~W!D5mBq>~9YlYxddVh(f<|&$0 zo&V0ob`gskwg5pmQ4u_h&d95`sRvRxrmox%j-~+ z0ce^SIt8>(Pq{WRSB6ZSY899@O?}`)p2M<=C66AomkI$_`Ea$4!&O@Sk;=MX6n;!)&nm`m@R4=h1)SX1~IFdviu+Y?+gdft{7Zh{O!HOX0tV(Aq!p%7hYS= zeZeVM`qWa^VN!adRH)|?+oFWBmt1wUFLe*{WRZ4%CA5*4x5_3ER^|v3Q|E#A&;uIz zh(BhR>yN0E`30+#4PV4R}rCPl0 zV*|a!;!J{pVzf_FI?lbzi#Hs{{nb3H!gV3@#VKZB;WnjSXj$O<5^#*0?}8^&(?pYb z?}C?Nfr*Xjw$q@K%(8rUf;so)K0Ah2CFHPenXyuE>8P2BL|bb^{uIrsPH&HRD%2CD z1K5mA7#JDjAg?_1T=8zQM)NC#U|q|@mBuqdGcrRb=h`Bs!i}sWu^cL^dZlaKlE%{@ zJrKL(+Axu`|CVRTg3VlIAHkkR5iB+-tuCAJ(S#uoQQ{9rr^04btXM z>~8dty;}-}{#F-uoxgsfc4OeBk~!{DqdfaLxp9XIzn2K(-$-$EQF&#vV+|&sXkqjA zCsl6-zvCCk5_+V?;Qo(fXYD|UUP1V-G?02=A>4}$R8>#7l!XT>h!vK)b7LB za;S@Eidw-%yj0Yg6hVYUj?6mElQi(?qy&^9I?e2@@YtBu)oV_C>YLiyvN-CQ$=DaQ z`)ehA5RP{(FUa`xa%qiGiO?8!knvnAt*n~9d$LC{a{L8#I~#&xcKby;1(8H_$@@X` zp*SVm$q4Sy$r4>wW?kx+ zYaRd-VYKLPa3TFus-u=@r+)iw7C1)>6Lx z*y6U8dZYa!a^@2WKLq6jj|)R&Azg>~lZh&P6|w}OqN#iP4uA4fotZA?Q+yKbzP@RS z7P$kgRwSB+pG)dZjGx_0T!KdMN6cR6DdO)Vds1#{!P86wpjaP-WvQI3R#aq#$`!vN z!y!E8$l(ijhB^$ z0UGSx;9LMGoRG!EnIi-(KKC%y6GzmK#*G$PwFnIVddM=IaOuT4>o(4lOD2Bjh`6w} zH3u8b%}UotQ$lF&*t5IJF#$K`=ri3qGTTjoEF;uMrh2gg?sEWB8JB-?ODdX=0xR@G zWcmSvW!VUXEq}HNM^=w)$^@5SWUE)fK)}@j7Ot<^Mj!G+ls(3`yy>*QLhd=v4>#F} zTd11#HjH4B3TB$GJ$h_)u74)jf3B_LexpmEan#<|Vbrq{;*lZ;?nBNQA zlJY$=zV+44bL^m_;Utx-cUI+4S1*O@aozM6S@O>$V>t(|$f?=l@w@LrMw7IPbvnw* zu)4)0zj3zlXXr=yWxs3UcY5m9WV+yd-1~5 z{TddRXsQ=^TrMkYa83-&?E04PHD$jnF{eW8CMv%iI*`d9(n27L3K0rJi$_JD7QrCx zFcj#{Mjq@;WQee+Qv-5qCoK`6vVH%8Xe92xhU5A`9Ju+Ve78RIt33E{f^UcBEPclj z`_YU)-ERc&O`Tt3Wv_fcAmEN7K-S0v(UC`(kgmDvz8vh#JsG+^0s*9{hx! zE<)HyWeW8^t^f%?nlKFlXZ{d>^(WQ+_GbAU=DIEv^oj6xa#9S$7spkeKZD{+qU?fE zCZY~#)y-g!sjk-FTTv!75;k3cWTS@KuNne_Mc_kcefREZR^SXkK?O*QRhc&Bi@d)D zx`IeVuH>KWYo%uuVIx|_~-h(GE;TS^~7-^5!HK6TyVivr|{dTp~mcD?zb z6Hrg#O=goV!ax0cG=n~SR18bj`)W=ff$PjaRf+^AL%Y}gfD-)6h=WnvH zl5aDak#|(TFAm%7p+5}-49YW~^CzVPT2l$^G7yn^fpK+2h=LIwj}O-V9R!^01o>EIB4oCH-pYt4mis!zq6Wuit}XlGGMa@tPT zFD>ye%;cCF=@?ByYeD@nLPU*%PSL4L%B6ApReH!n_$JGqk>rYn;x{%Fw?q231j2pR zcMs`gGm1r+9`kjpU9N3gZQL~k#%QZ`#?{ut7FFPBS0Y@&z{?iwu+pbs;9C2a#%_B>PY=-A z!tyAjN~rUn-2=PyJ-_q1Ct=hRjsohCCH`FJGH)@yFuS7S@ZsMPq{d zFX>_I=BtQ`C%(~KRS*RwZ-?J!DjU(R={Y%G{8{BrAoTG?dnzLG^0?&oOiEPHtkk>s zX!AP@2t>4B*9$qgN(_%)gx zHbh@6So~7IK7vNX%+g0U;i@D3hWiRQ!`fpH`tDg(gRNwvb5eq@CZ z^z$n|6ih>XTi5T?zUH8k4?15_cdEx8A#Dn2iQiB+V53O`C*uZAxn8lBb<5yO&IZN| zgZ5wmD!y1_RB(-oiL`Y17n9IV?~`DvskkS3LG?px^ou)hYSM%s2Zgu&DE3eUZMzI{ zzg@?R7jke#gJ~$Z%@F_wXN3pKHs1x4Tev43+@_7?lmDW`8hvC#Ia2^a+j1p7YGX4T zT;oCQL^WSVs0K7Qx`lU9p^H?~RvuR?B>+>1cB+PS!vtimS1P#0&|4MMG+suH@4-a! z$I{h0VDYQ`kNS|SFXq6V@#mHW;$37a_$$r-!euUe z(_xA{&pGaOppSByLal6%322Es7MwrL;R`3F2)w97S`BfyHjky@inO~I#(U-6+q`wb zM>>Pz*cC|)^ymLjm16bsM6bAicao#8reCHGZ${)yY*xAE0HJK83C_P6hM#&P z`)cgPQ2c~OTHvP_>gQ}|pin|0LN^SWVy9c}^qsygbrwm3ks_m~CcpR-Izv+mokyRj zJVV4YL*b2m4HBf)mk!{DaF($Tq~d#qrC*FQfZ@thZ){QXDjE3uM>^$tFYO773^d8uRzeO15$(Of~? zCm5eP@V9R8{h7ftJLD4Q9xG?L$$zj;0s@=JnAm3I zSIzJx8pAk%(^fU9bH&_OxB!-1?88l>PU4;KS3gj+XF*Vk*-wHryeK<=R&lE@r5vyoet2m?$2Mp?PtcTLa zbk>rzhTFKSu85r3Rh2YE5E&@Kj!orwc_gpcxzyx6y>aOU@ReeMNHW>5I~}xb3vO_Z z4#F3&Ntfn2hIyCSw2vd-Pu{zWNKu|ljs0WU%l*f}Wh35LJ1%Gs_u&lbs5--Uf9%pL zrCZJCa&(oy+#0G4RQyBac=VWEoQ0}eoS}ks9+I;ksQ;IFi?rs+ z|2gy?ey1K;B8CU1_FVABWj(^X1GstUje9SNrUI3`ictZ>6Q;iJ; z&+GSRk=1pO7B3}3`|st*h)Esd^{f>*E3_xCM}FI)EKIoB7&KXcY{nbt+XFAPykKc$ zIp`3WhGyGw9oJ_dPs@CIKs>SPz&k15KUj7_4pXr@ECll9p!yPp9*kMUig>I_z$*p| ze5)TnzGWPPkZq==q`f^?y-N?Zg+@O8TvHmYm_om1qqq(xw*Ld~1W55Aki4cg1yI`> z-DhoRSH^(*Itqp$1zX)B#P=MYi(4^^_Yf=gdjAG~zC~ZV1wKBeV(rB7SFS;fmfbee zAvZt5Ks8o;4o)^ieON3jBO4cUJx#G+Wp42V-lz{65O~v1j*n5z`G$zh0mNst>ru@< zvBeLQtD@@cybNo3MdTSl11!zOA*A#h;!!2{TIQZ{Xy4hQOXy-;NzGu_RRTpfuFZAT zQU4Jev9U~=uj+SVqt26o;bItV;*&A0quAgEz(?q17U)A2=2q3xKyoQ$;&=8-nDf0(n6nmQEaAOF)G5%I)X_TH!9h6T+@fC3=F?vWMxUi_*Nm`Xx z%>M5)lqym`Aoj#QrM}VWx)Fs`+k^DOnK}s{u#wKz3AYjOX*7W>bIBI&Dqb>#04scb>A#N z-=IWb*;5;b(s!L+fR37rJaPkW5KAoyaaCc^oAKe+VS$ar8#v`VP}@?;4;nMPQ8AQD zbX+#6KM3E-xGOv8zJddJ(RV}DJm8)|cbuLBTN?{|no5kBVN>FuBl%8&HM2d;g*)R?D-gt}L;w9X@0P-z+TEF$k zMU}CH#B()FJ4gOkIh!HM_i;p(?3Ie*+uw>N&*P_UIf*JT1?+tC_;o=~fuqOGQ5(TD<}I+&<_bx%od zRI`53)oTJa*7+$D`Jm>_m<;*85Ae>QmvTs|cgnOh{Le?)+4R;Gk8Tu5F5W8x)Wo^e zZgB+lpgP3+QiIQt(fNE?epk@R5Td3Ut^zk{7i zOZF&vW5yw~qB3Zl$fFP>@XkBh-YN4{HPI<0KK_3co%=u2@BhblKG|#-=D0bVpHhalv ziEH9{|we&^t3c=N)|i!nS9`eN(N5;+v{+a28Ek8YdhL3`3O2^Zyl2>o{L z$-y%}*&knwgwnF~RtKA_?8O*o-N{1lb?rKN7%XVT@UAZJIWE9JCf zonmp~bql$?CRSp3zj1NR+)9m;b_f!n%(J+q6rwO26*#Bz;RD`j#bxdZFmmt`7(lqe zwLljzJj6(4U6KX*!o8YMK-6Vv0#XQ^3*#P2dB$+2A)7{0_Y_v365Mv5f1m_SDcOd0 z&oGqrnk?CqG`DY8V5ccE%-;7H*h#OwQ)HBe)5^#1|2B^-${SwiIGxa1cu5n?IPvvI z9T#{FUj$Mwfr6mi3|8K-`!J9k7ugi>jf6ocArE=L`KAI|5zC$4#$b9}VYDe{E{fv{ za;%wZirB_rk~&eTV9vd+agMq!XeMDTY*vi_W@y^wox0eqBpb#a71<;nLiV5Re1{9l zxQ$xmr{$azW+4RZZpi4sBN9Y=TZT6&5V9AtV>6NG1O?&!34xyoh)&A(Lv1H(+_(Fm zN_t;Gf%<5vYp4st(!EZpA5tAE%|B(ZCk!i_e_Xh`g;1oiWR5LTp#s%*XZnwLfWgs+ zoCu`3*r9A$=AuYz7wK^YS`VC`c$zGc6b~0ihBCvtsEkn39%m)FLk5k6x&!rBOWQyt3eOho{+kiZtghNBLCUz{oPu|)aq9;dEymEmo zme1*RmxzN$gja&`K|P9=c>Fd5n=zmd4ax|4Q3{BZ@XyZY+TiQhDm(UxyfQrhNe+WP z*JcXz9D`^$CY*EYq-4|gu3o1sav!G7g##ziZHW8>;5Kxu>ajEEFka|3BZdRk<3$PZ z{+W#bIWjdbCywaLZbSU9ZFjpYA2NUBnTSzGEl`CF(49&v5J#wW`VI&yG@4P4-<~H% zUQU8aX{~U5V%}E~j&qeXkX7i&(mizWNoOH_dSF@QDbMX-ja-qT#}{3ZiD{9ELZH22 zkxNkoao6_NI8&SH@|HN}z#aoL`dHE#&VNvnjE$FG)?gO*!@ioon`J-hiJU$AObSnT zMf@1pyJsuR>`RTq-~ko2?1`PzM*{~ks{|3P1o21v z1T{#2`@EB~$zHz@u1XOZvEOv}@6FrOd{PzTSB$+LL9?TQtiDFKO0xHqRifTh2Y*$g zIJuMR({>aE=#h2<3xZmtdG3g^R+L}0_B0pd87+V=USN1WTt@%_5Z=oB~iT6itiFV!HgHU9dEg?YY^OsE%)-sz%Rp50|A&fTCU27~-N} z{|t{%nnspnp#hbX+V3QL_BObkbT(tkZ_qL$FZJp9--^%wM!OaXW`=tZ$K3f!Q`#2a zgT}AUHEQPK?C5dK1u`(`kI6CM^|mGuXR6X3(G0+cOL}G*klLcnscag1kTv)fJ};(t z^(soj}m8a zf4JLL-U-r5y|(S$&-qovwWk5e=Waw69NR+h``-P$H(Ppu>(zxzH|m1x`RoQ5dxFyP z;5;4hpJ^kuLkqS%)yK9P!GE=GUIO>YZu&QE;TM|T&R(UYJFpiVGL?R|JbQ*fq?4L zRL;|z8*jPjFFi#a|0@PMJ2#~20r)OQOR9?Dq}Sa5eCIg*>E)Q+jlllM5Sz3wFH;(+ z%6^PCzWTGqcFF;$_E$b0NZdzE;Sg=>jtjbdZluUE5Kz+IO}{rjg0ta^5G>R(b|)o0 zDoM;p+bhMk(nI+z;N?_K*AuG%vijKBw+RG1dx{K~a4UBxp7pMTjl1jI#tlvR7vWy^ zwzo-%4yzH4FxgK_4n66%x*qtD06fy$Q1kobMCw)gxEc$2Mr>!F24JYPOgw@~LLZ0Y z?ss9EybVZ6DYAx`#*M1_B1K4PDTlej?N$p^YVBKR?R$#%Cbrv&32-z6%deD9WCnv(u_1x@p&wdao1xSE49kwQY_Ce*w8l>uXRu zstAXi>>HY2|9#JJ2KYPW9_xd;7TDE+r8lJ(UOFB1PfBo9QT@Yp^a6xNRP!dV6V4W{b{0au+$Q z4JmNW4=VlPmiNs^8j}!D{7YgPOlj0w|0oUDC!{!i1c83AoGzHg`)$BJg@5J}oiv#W z@{SzK)Kzt*saDEIFmM$3o;>)|*<@X-V;MyykCNXnKgBxkoPu?ErYKH2JLK+52> z&(l}hg&(}zGvEi&8*}pr96`y6bxI|D%e5@SgTBx6^k;t#di{TXbAd4f->={)w$tD8 z_6t%{0tu@xqLSS@iUFs>Nc0QE?O4d|v24{wq11PTm|Kd6(;#p}dkJ1}ozkdj$(mD) zmSbhLYK}SUUXIXB$@};tAsKdh%tUu$A7X4BA)NUz7KGrZkaTq|H0r2zm8{EaVDqKC z%gnsLS-H?>n2>n}zXZ`i9G%Q93K4W)0|$wrYdHl_EnS?$ubfT1JWf^7)@6#U!6iI1um5dt9nOBMkvye!(Q!&|otf^37yh%#J zdf>Y0O3(hh60enhuN7Nbx!f+#9!Jfh>O3*&py8^LL^x7 z)vqYQ+~yXl&LH@E??o>_MzSAMS`?V=C*7z+`+N|2IoH#)z>O*ZbDV_c`J>&>U_~CL zSTvk|dKBL*r(+LVLWo}e5v$?~!gWxNY0HDDLeKYqH(4@{<=$qf@aQXl<_ZLqg5fUh z;r-*DHezymkM7>HVa)fj(qdR0jX4PgdKct~06ET|Qro^2bU|@*h#ajb<9lO2lB=DV zb2(rx!hXbW%>3?#>_e|f%l*l%;z6M}a}rAhGY7?(jhTsM(3Z(APpEh$XA+wI{n^#y zDu-g4N4PTIKb$~{aMnUdZlBPB7o2_|NodR*XY-#StOC0B@16rCM-F^LXZ=_O8H*M5u3RVK zK-;ZD1D2ngnovo#{mYHg+yB-I+9@SH&cYHr!I!hf-k+^oNo4z2Iku~PeW1!TRoTzn3?Y} z$>v`~Bb1vXfY|wNWesPGU>3A0-IBfo1bDv^^SuE{3rfn=W_@)-1{qS|Zc4*D-9OE6 zwZD@9uP{_P##hkD0kQo!=q2L^lZ(YxjaQs-*fKq@Y}PCSU5dvQ4u|emY6QKI!@b0w z@Kw*IIo$N?CzKZ3e+fbB-a&Y^7LGN{S5tf~=NFgOq|zJ{N_wmbGE?3Jksf9O%_Nzq zrTfX6i9Hjd4NL1jT0W$-i7C#n?I5NZ#!7aoFK6DIiiU_o>($pB(Yl9Vb)*vy+j>J2 zkRhs_L(5AI!Te7S!bA0xyUYJW4b5QXcMGi%QoxmbAC9rnZ~kr0N}e{AZcM~B7K9Po z&H_2XAYE4(RSrHEc{<2T5`&SBn zBrcV%_^zoQ0-2Bqt6=s5X*6lwZWitCo#KIQU2~d!EgNUKtF7N@AqN$5@V$-oCJYJn z!uWj~r^om{#9*h}vAq#7_OtA5xQL)hbShH#eSzPTW7{swvKL2pTQgOVqPyJmL$KxC zKC#Dybk9j|i(#cx8rGaQLkmN~A=Ctxl(cW{MKAWj8f5S-soTCF;hjVs^+-P%2V5n0 z$g6$9O9IgHT}NK*L^cmmE6_b| zq%y2Es9KNO(22wYg>rp%EJC$kovR7n;Zxv6s{ZU9szmoIIxeiY&iFWtrD#NVm#O1q zEf3iii~)jlHQ7C4D;c>Tt2GFgI$<4fNGaWB&K#Gtu{>HhCD;yr;MdO(Tdx2vM9!42 z{B<7Ri%Qkc(6J~DT(QP{IAQ=EzBO@86tTU7fa3^}IDl;m_#P`^TmaCl!UaUq`FS0K zwUoVvX}iM0lGL9cBB;aE8H#(4Rusrg_Hd?*gx$k$@(}P>4~NsWM$@OJ2V>NNDQ}nG zhDb6U%LFtP9tDW^Xjb+xT^TG)!0xkN$-e~?R#9fvo;dw0 z&g|F>H7(g?>~P9iIZR834rT)PI&DJwstyA#Q3tKkzbKioLDAS9e?}iIDvE098hJU3 zY$loUoQLW9j2PB#U_Lnco+6(sFvh;XB)QG)A8sF)ieVZsC67xUGal|%C(c$aSj)%L z19op3lWF?aF{4;%4}&5v7+^UQ9-%5Z0T(63Go)R~EByF9dL-Wx-s#H|Z1B{otD-+7 z2BCWq5?M@p0QojC@io8Ln)ZKJyq^D4GUsMl09`R_(JZPn)6{ywb6uM@>?+#C1vpAK>3kif*w zq{QQlnn6~jt(iL9u3;YvRwL9-f<7XO7f9+6pOmGLx=u+~>eV>06B+ zKGAXpYR4cW_Nqv1deMdu6;sG<+NEf!~u+J&ky>} zGrz76CDx^=BARsOs_LX@g))@kDs%JFbWUrC8$IVudYcQ%9^*v;gV{jX%ljpo2|o+M zJS(w{RvcvN<{&X0YaL^_@%ksv19+xrpzxMbLJ9GcMoXcUafvDw0+jxyb^!ofBHN3+ zeHwGbMSGwWraVSfOncp4FOgeUcEeckIUSp5r-@uyN0PlVk~8K25X4lgNVn$uzkRsZ zpcMX!m=%!fM1S5k{6kAZLcfAyIO8?{`!=}alNVyFEy4pSb%Io4CXibZSo8_60oTKC zEkaAgzm(R%ea#^BpzB)_t@kAuTwMBdKFdS{p!ABnHG%cD@S>oE%B@P>`tXT3M|oU$e< z*K-_U4nVh3fPF)&r_M%^dNAEoff}K;UYvP#Q)b!qJbnjn+Ic$1QTTKlk}$^k)f?J= z#a9=es0Pl?g1X5_hl_^SW4U#sVz}C6jApCyQzD0=16=7Z?xnXAt@hOZh1~zR&)OhhBea{_ zt+&a$T64p@ahgSSTI9jwFOMaCMv9HSEla`tTfh(Hq+@NpG15csUKvmihmG7JF10o` zL&xo=`bwgawzaOW>VkaI(;&Rc%KmA$QW^U;X4I+}#b-(GP%BQI?>OHd+<$=uL7+P& zap{=lmvVlEvI3WBM2#E{vU8*_!|_4Es>$s!o)6VtArIr;bE0fO-Li?h8C81ozs`kk z9hLULo{fP9i`i=%gEG-vFU)ZXIkLNGWP>vTa2;KwR7`GMWNTBw$r1Q^bZU7R?)xz* zfUz8sdVury9mcwZ=W;G4>-^Azijksyxb4#wLazUPWrP=*3;^x5xq9;RFykHTHkWI| z9^_QA>aV{C^uMFL%A4?hG8<9zxDP#Wa3VK=E54+e_U>F71&+Pm{sy<9k*yWnP9Ad? zl!m!*g_**p_S|fPVW@s-1^kE?1hw^jf-bG8h*%8*26<@6JvCbB z0t0$$%5aVcjU86Euf7Lj(dZ$HO^6RE4T%_)QO#pN67JN9BTy9HbG$ea?^;*hD%WC?V30lx{Ep@T}^%8gKetv3Jd7Ppf9|YTGF+SL4oG z?pA^4?t83Cwz6MYblxRG;Zhtp^od5q1B#q#Kth!VBGEmEKqMInTs;9vH@k{^&F45> zP&0!C-wWlM%U;6+l5ptI7l$rbD)1DIrMwFd=PR->x*lphNPT~Zm)~uUdx6}pCxy?7 z+14?=ad(YKZA;CXLmy9i3Z_WILn3g$M=!~1^{4yL%x!p?k`Q;>_35r-^%_ARIDggd zwZFBEF+3{v*SowE20A~3BXajq=WjyL`<;Z|UVgYYtu=IP*N?lXovru~ZN;w4JdzS_ z7m(%zYK`@}WV)Nx*!m!^oqXPF-N06xr`^%&Xxfy)TL$7R# zm$nh7Q#kWfHMxt{grP^(%>ZJ`DbX7OL=U7jU7pujG0k^IIO9seYQMo}N*lflpSA&= zk_B9d)ImB*FbrdhTdfHNdoUk-b{TCk>U6;k+i>u0zW{O<1f*B31@zsdfkq>7ky+T* zCONqh_^Eg}XWr7~jP0pwKg~H)JZmOO?q+Gj3m1p3%&c)9KGO6c(!1tc{Jn#luN(Jq z`nEb$r3nnZs$48*>gSoRax|o=v;TM>lhPdYj|6Fb2pml5CMOMj;>47kEz%C%6wt4M-4pM{4+;ranxCtBPyWQ@8-}TXFNuR z>5XH6A2IGVfN3j9_OO0HZ5p~Nhi2g%xXX%QLA83+GrHN|SI6jIO8Fs(6Kf613=AvX0yv~NbU&%N_5I^7F;GC` z#Z%xzy^2BIa2N(v`6J`{uEFc6Ng)gv0gw88!=^LJC}7Wlu7|FM&uB<86jsozbhIB; z3^K|0C35~d9b!B^JVG5>~&tD-|YQYd#b0zgi1jI0Jnt^~_NPlhBy-W|+^DMD_g z?>HOwC!Pd)doVpO&m!*>?Z7Yja=Q1kJ(D>6osMfXYr}nZ5RzYUZ>C}!xTm+HRn)J3 z)VR~4cHg7oC{Py9>xrEqy^c};_o)G!t?o;A!kxP$csmaS7J5DP5R40}4>jaPdgh#` z{)^Gsn!=M5EiZsx^iNSoJU6nDX)rQ^4milD82VCn3xmXyU zfh&s)9MB5`^HUX*Bx~}aTlfbO7w=V_ZfECAuLZ+LrA9^tVgwibu5;5^B)rYtR_a+6 zJ1x~BP(`yZRY$MxZk=qFY$i&spRXgegW}-!a@u&HA7p)_k_P`tSBKgX>|rNB0GPljUPzrb}cFcv_f=gJWC zJwy&QC_D9hj!+hklnwt_GG}=W@K_fX4CMtJ$WssU#=vG|zlZ&|h!AKVaDR!>rEgG- zY8yURR?|7F7={Ppc219LOvwH=GQkN_8Z4soJqUycCFPHu&*+BQ4lB_%Yk>TD~WsF~=Hx{=`aJ{L9)CCGjt>-T-UvZ0==f%2!>R5$B4DPg`z??H zFC6o&g#TT7ZLYNILv7(%QW|(g*O||sn^e%NlHGgrfF%gG^S!0dfqHa)I|c-I^}D0* zt(!M(oA!WC^h-d1{Z;)0U-kww69PYaeJ#QeR`4z+sS7(ge$lc7po%Ua(0;ldlH2w% zCS_%7Dz;$b9}_imuCDkS!E~dS9hO?0tr;tKqrKy#0k!1Y)d$CI06`I8G>0l7(Q{AFbte=!);ee!>E2PFYxRCdZ6KfLKwRrpw;Qi^7aGs z|5eseS1t(ei*{TH+LZ|V50{svxZiV$z-Qlb@-WOu{-^Juh6#z`R#N~mT5cB%w;8nB z|IsRJ6S(n8fKMu?LC^?$+RoTRaei!|kB|6Zp35ZxXX#PA>Bn4OQ4}Bq#(67y_=exE z=hp8XoX+{?qY&rPTI-WW^bL6)ut!bG)x6ln+8bc-hi3*>tS+$;FC0d5zVvpV4KyH` zMGekMd_Ee=5li+WVJJDEm1Nwk3&1wuQg^>skn0)L1O<{ z*~8}IDtv5JAWn=(7X|_=``?pp35qBN!}fshkl#-CLBBh60RQ=Z>L>UX-&d2Ob)`dM zef^R5JJY5iRK&hK|A6h+ivLr3Ld_)U&LvhIF*IQre)#-Lg{8h}ohm$xj@g-sIlC$; z!w6pAn&F6;Tz76brV75(R-`e!p~BBE*Vtc3{i4?%_d`+KTo->zQ{@m&?ksVsJZF(d zlZa)y$$E;bsoOk^eU$LOiJH_L8w-M^MWHBP1{|7P_f(bS}s*Jkoz5FVJE>-lBp~ zEOTp3y6;z+%Ex`AgFiTv-h^m3Rn0i&u0IOrOw3rtipn{wcSt7!*9XvvAm30sY^&rv zgqIH2B#1Ks_S0`mjny%)Jw??GQp!PTxnrueeOzFbh~eqxL|;<6MLiC$)yl3$9G8{5 zOUzQDyz+F5xCUxZXcC7+bJGlQAtdO+6?*MCcA)}{ELccDbnWTJ^E_cU5|kufmhy*V zL9!hYy4_3@8E5M%$hb^~Z1Wsga16)`F=SrFT?f=1fDfWAJ>9}$CQj}#DrbXV8Mi7I zerD|Has_wB4k85#31|F2Zcks-0Ja@8qQ_9 z%ztWp-Wc_5kaf9`ij(CQ$}go#d0YrqTK`PU3l zwQGRga0QCWn4p}xbq3D94AL%O;R!x?P<*OGFGs>H#D!haaSMiB%*Uo>Frjbha@l1G zbM@^qMwXF<&EeY!=YjzDT8Txt=iyonOcY=GMm)4|E7J*DHEE1HRjb-;}*#G?M&493?YbAOeeho|O~ro|Tu^{gXA23tril{|#>A$5*J; zN+{R~m^FN@X$ybUc0ArK!B^8H%AOaAah3@H>xuJ3EH>@uCTG#%8TF>y@()rSndqt# ziZ>MFd=4K39tt-^}8% zO>zDFon=^bC}+VWq>WaQe8jN)ad--MPwN4oh*=F-YL`vABbApH*(b=) zxq1>6J7v_`z>H|Njj#HE@lXf&;?fDC(4RO+zy%=^qOHnFzeJ0l#l)Ol+D?z(>%|zp zlUL?&D_IGpHI{&SX@lu&+HRJ#c>bv>==qaOa%AQH0<%IFOopGrVo*ogJO{V z7kb9Y7HJA29e_elE6#+Df9<@G12hMg+=|-Xo4CMk*meL~jr%Sc$j!07+RSE^ z^dD9n1O{l=;xe-jtIR!P-|XRwWr^iwc)iWffBgl4$QhlUxzyazU~=zi23?`9S6|h( zkRbN0Fp9#P9AD2x?e+6wq25-$LS(}~@q=(B>ImZ?AxdiYkH~J*CDz3B+3leLr016$IY}b@QnbN{WFvk)LVaU6nGB7Du2OQ@z&$igFaUi5_J7Y#?6V}+Ya?dS{l?K3~D zXvA4;rJvUXU|fOGN5UF|4Z)SFhVn&#Z*j$IA*sgQP%7F{;Tjv4;8`PvDSei;%}p>` zmMd7LH7{+g?@|o^qL@OFZ&nnmMY8~7k%ekWMB`yB>if2m>xw;w5tdsIF9ETJ%L;%htLv|IcG!;!IH;|uecvZj zZ-`mK>mdrE@#~dw@sbc@B|dIi4siqL%_oh~B=ZU+u`|oLPGtU?1ZT`>gy8v4Zhot$ z9t#n<5IKJB${0q^wCafouTE?u0fHj;d!jzsM(NY2V@F=zGMc7NS=&$e;^&d2aQk2<5@SIOu0#?e>zstjGD*~sf(hPMh)KcbO0pQG{{IjhEzBfpGMlm_Ug z&kWzAALmiG2LbGZmnsixI{TU7^n;xi4iiBX3(t@_K?%;YP#bWw3SL2&ZmsjIH4%K4 zg>SZ4K_QV!F(SY2;!1ebc_G#NcwNKxs`NVh=UM0K zRtoIk4@&uv+I%^_7+ua1L|pT`f1iIJBUm{gPH1c1 zS9a%B_Lz$sZ+)Y1y+o$yY`9>{mWm6!njWT(lUmt&xm=OCsA9uwmY%VVK4PmEKhw%M zjIl|g&)J;E&7By)bT7|)y_9YLAc}AC=q{>apA{^d0}Y=_szG2@miZwTub+!mQ8mL|z}%f@eaIk@j|(!ic# zuu|to*N|a;hwIeL&h-DhL4Bu>KP1OzWJ^~t4vp0UxTv}lJFCspgtk7KMZ|z9K&*(+rwqLeaXrj)wJW!l|QM<{mZ&8T2JgUO2xQ|jZOpu&RiX12@R6JH%cw%6( z1*+)mkZGX-Bc6Dk&wYvty-R=X5YIiRp9{+{O6}(S{ojYL^x68H=5kp)3+Tja*9phy{vSXC_E3d z4&m}V=1rD{-N|hhEewduvV)%c*BBlzdi%et&)Ncj#H-Dy#@lz&ko7tC{hdmY=XaJ{ z9Z@DJIEif!RP8<)5`7%>`T7-n9regI*b&!_5ZFF;eiJrONaHl)v)7~xs2Sdi#R~#+G+coNplfm*e>U!{<9v;wJoF1i(H4&3tw zwd>@Hj&~u(R=Q8#5%9kU?OSmvO0H!k(BspH*z2;Xg|M(xW5l*-oruoEwM$8E3kr{o z(b`=F8=ckFe;Ut6e4oe?T@6_V8ef0B^t13pY*y2rW#rfk`(~8$^ycOQVE1&Zt$R>k zPV5#<+=uE-&8QfC_%QasYWf9b%Y)05!VfxaDkbzz8R~%A?uZL`&Cm>0iKe8cP|jC3 zqzWhcZ_3+M2ivGuF!xTV$^cxskJ=&YP9Qly9xX4H&Iq;MZ|?N>C~Q-qq7J0sP*#Yv zLD3)Wla=PgfP1CP7W~khN|Cp1mCr1F^D0qFif~xY(AYF0%L`L@Ga0g4nXUm2Vy||K z|2}uVCjA<`y7(Z~P_cSa7CrP+;7+p7QqX*Lyl6ODkI}?^VTc$A6UilL!Z$sFgQbDh z`}OLoZUx|6f?qhCM*S?oQzrCF<6_>|>9SWJqVbM#XiD?Xjb73lu5c5x)Enpp;;{a8 z`3G%wqks)cN--;dov9DqL(3DZ|AnjSI^lJ*mAiE7d8-}KN(HOPj89)Prc8lr$_+Rr zm~pxyd%-vZgCN;fTMFf0F0a*jf;liJR9UTEDY$j!Jx(tX0!vG0nCNEUX<1qk4Fqcw zRKr8jEnPzrldg(8MwJB>ZMk{J9zm(dojE6}(4^`S%L`Uwf?q88RAn*c3N|le;$U~| z*ZM!X*l(1KFO)XGk1AH&p)dhjQ3PUFZ|qvT7-(BO2JR0EpB7Sl-rTbLx-VXAk^lw1k0;$@PjV-q4l} zk+l^26`lGsn(z`N+xt27oMzA3jWrRcHk4OTiW~I^__yRgLTT-|rbXdNa{w z_!P6XiKVNeN7#$*vSufQyPXY0r!aMqeR)3*>$l>VkmZkJS(E-<^Kp1s4{&HX+3!ZG z$DZ?F8<4$SNJP8!BZO;I4ihyfBV;UpIU6ATQ8(a)_f6O0NS0?fZRsk&zqOc;R&Yx< z;G1;BUChkClVZp(pcZDgpM;$wpQs#`s&`SMh8qej3zw!NRe)fFHA#`sREBk`BIdX6(LGw+{bUokeHtFnQ|pJi?%4^vIfVLmGruD@ZYA0WytI zYpg z@1@uRCHrfm|6uKcwmBF^@Fy@NQtk)6cgB6mUC#}WQdYP09m573XBU`(3ZSzb4!#(T z5w-3-S6BZr8^ErkaeATskB4~2+Q48#lqEQ~A*N42)cFA{7|Vr6pt2I1WnXH_?mQ6d z@E&`751$&pCAZ;~ygD|YES<&{7ijy29Lv!~?n(BMq3hCOQRi&_dmJ5W5$MN@?D3I( zsEZtB|8E4>akMxPm=g6|4gXkG9wRwO1f!?r?a}TWAVT-J#aP74!7yPB)D zP6r^(eDurOBb)ehvqMOSZFT?7wP!vp6w;j>55cYjzURT3JC7T$fYnnw=|6dyyl}Jg z#3mAvD3iOsqxfO^_S+b7Y>7A$j^Vn%qyUpGUbueu62(8*wo z(nSD3X)?plcorir`=N9I6SNukb2}Mkus{~o}s!>?CdT!vkV-0W)+sEr%k&0YuA)tpIFJvD-aTt z=Yk86hG>+kqB9Pkq6(Ac9Ib!uw>zu1K`@aXguAYYgg(sARIt~2+MU#O&##$q4P9`d zEW~{A6`<7c`L@M$Gx_omaG)%_ccdj9HszyW#&A;TE5-BhOqdfWdp-L%WQAoDFQb=QHzs{1yhI)=*JZI@-9 z6UVUfe*3pk|G2j!d=_QCqe=o=B3RhsL)!zjs*Y3!sO(Kg3wz9TFC3x1H6N`8-Oy3= zy9LvcU*Axvk@Y`#NL5ZJJ5KF%-ai%NlF#qpFWUeYW92`i74vs#DS#uE!w2^rO-Igk zWg=$;GV&V%-r|(JeK>X_c=F3;$2LjmcC%)1K~%Y5?9ea0E^5y-u>1uO0s!tyb{hWN z<8uCK0F$lvOM>;iX#WN@^MLQf@HYZ3q+=|GVUU6Nbw>nueJnjEtiL1E+!?F-)N64KchYy8JH3D z(fsk}hiU42HpuW;J-t(gCha*=(ydyzm{OSI3Ec&rw zeaM+RrvuYkA;GdiPWs+ERm{R*5lIYjWo1C`&0PyPxI7wCoyxwb25=+!T?|$bqji4m z8106uX?;ezI%wp*c@9bu5~>3!kD8Xo?4nU87p=Iv63-_J;t}x;cxr6Rg9NlWfQu{ZGXHc5!e4J2p3BeE z2`waUYvr_wEw634q0&_mq%Z4nuzWF{5q4LXQI(JI1fa%^A4A~WqbBwz@C?fa)w8Tm z-+vNAsy$I|?uN|v;`;4XZqlW1hc5=m8uI86UThH3NrtJe1DIb8g9t>(PS+9Y-hg>W9y}8GUL=WjHCwP#rcZ#z7!y>yK~bvrIy8 zc_SG6sJjK_*ftf8c+ms^)COI>mw?a3J-zlgrdb_wM>dJD!b87}{LWrLW;~hh57~&0 z9Np;4NQNn+g_(^JP1wi=2NHRC$w6D^1P+{GG=EGIdG;`?aN!3#HD;S#Vg8_;%XfyL!FSp-)v9i)-1ldN z*T%6%8PGfa8>B3~4c5Jmg{?UlUNJK%)RP6l(9 z#yom7;D?cE2f#F3)&k}!<<3t!h=TPcL3f@@ARXx>4%;b%6Xrh*+}7bC~q3%Or`Y?bFG6d zSO=QeQyU`SZqbNE7snbP&fS^3`Y|Q@VKdY3QQy5UHX7td`$53vZ{Mq*Yn;pBDw=7G1hSKa%2`eD_{QWZF+ z>j~h{fi-AXT4Y3Jwz27BE#+-pRnXFXlt6VnVMflnLC|AU6roIE0EtW#`rge`u}!`( zU3IX-bRR(VFy0dF6rx7>u}7#y41k5&J6v`F!D?fl7!WW`JFl+NaXi&7Jv?xnOm3+Q z6!bZva@8WQy5ro&RsaELvhYi{SYa;k2g3$W&ejzhmjggwVeOJ!Y~BqBOiS1;nlaJSx1<1od7~ z&A71;cQjK+F@NKAP`@><;1eVR)x!At#_U`T{~DrYbK<%iA=$DAJn?XC4}!Zb7p!iX z5b7TZ$n%+mRR#ducfp%jtwe!`{P)%u4aVWVuScTZV6TtFWyCt>A5{l!bz$t?!LYB& zDivyx#3<|b@J@M#dvE6w zF-Dlb8x+&O+>V{vq-`B*acjgD%t-2b`pErrZk#cl)@@qu{l^9bnr^@@V0YW^zmTOl z@Un1pa=i=Dg}Z!t;(uL)E)rsImtjU1CA%xz729Y(2kF-CMs(x435#F8EOiI4_I9%} zx>?!X_TWP3fN;0-icbwV~s1Gn_mI?B8tl zfe|9dn==Rit`&u7{9$!vX%Zztqe5~v$t|jiva+gVRK}YBNxQJEqPx7n;+>t5%@V{*E^4QpzvP2WB z8x|7!rglqAth#r~e@ZT9tm(t5CWs)G>N4(^>?I^DrV}Q?J(5Y^rRs;1V8dgIf2)(p zI`b(s9UE(H395djr<-1h`i(=@>y*Kkd9Pb;&H3e!ph#EpnV%d)c6 z)Y7uD(n77oC6`v(j9gO7%3ds~OwBA_=F2ema5ys`_|MF9@AG>|{XU{Q;HFJo1BEkx zl84WI=bdxlMccaTv$K@tn%NbsKmCPcp%!fhZr^jW7YrLs$)_3H+@ZG?9fICwsfNG* z&YU`;)6&Z3&OD*${_<4y2KZ_nI#3n-;2W*g>dI9qFpZePxo(ACo44xRyzRXGi}OPw zm{%88!{-p2dZHr^=P2-nm297Ydj5sX?0D3s=*(&UGHf@YHQB zLwOYqnhE>$ilpt;La+SGt|(wR4M@C={NT=cob_W#o4fDQ>+^*1Hk=^NYA68Hd%htOu?8 zNBb;c$H573C6?3Ur8!<3Vn-|vazsx;AG^VM#Iz3e^>1TYpl9ccF`lmFT}cvZ$rxA` zs9S=To0+wOjcySMl63Cyn~?m~LXKDk^$7VO5f_nYy-hWoX4vbF4~~zvmRt-pi}`8aBr;>cCh&lbBYk~|qn#O~5bPZcy z&|S*K1PQ!tAQm|QP3-e+c>kq6Un4-2oZcgnn?1*0s7QwqF|2COtBuYTSwrM#=;6?R z3{$SGfkeQ`6u53?40~0%LZAc1>H|i^K8v+`5;jtLCPG)e*{^~GCif!HiuZZ+0BHMu z(r9*Sp&Q^als0^Rr`N4=54&N11|$0)8gm8xgKU~MIeKN@ev5ZGBjz9bn}vw1ybJe| z{oj`E_i)fKTlfOHWmQknQ!tAC0bQnwI=_D|oZJSmfA#ImnIQL!Lcuq}{R3@o zSMnvBoDWAxdV0z8OF3U0>+T159tiaHKDOh->t?yb2}9E0HqmCT%8mu-tJ?FbZM)wD zlVD>lMT1Hdqq7S1=m^GF$eQb+M%j#Wv}&*+EwqY<#>G*w;)IB%C>v3VEZwH!;VnRx zf!;yTSCr@}jGSZ9HpRItmSw?p_ZgHewgiGbI@j>RfPocgV^2&rL>x%2ocpdw=c|cQ zyn4{;>5YP#L*rMPZ(&=iv8^48_rKL)h1EYWcX?Qm`%Kc}Eo>hTI|#ule&PD#YV4~> zthh;B%=v}f<@Z8`7?ix1=X1sBmG4w=@?o-VVq8)AluaZ^AMF7Ar}6u|>b)Qs!`@2G zfAfh0b0Hbw=66h;Mm8ohX&FPX_Y%DZIBe(fy}}MiJ)}a1(EuN`)c*l@!vD0 zFxwyZ5i;`*f*S!tE0{?8Z(&^lPH607_66FATf4=QI@8n0g-@6PwIWp$Y-rChpYNN>gTQiz<=GArPwy8W8CrM$| z_}P}ZSYbB&32R7r)xd}Db!Q^7s_J&x*n+Zv0MO3i&Y5FZ=?YmbaPJCHd=!CwEiI;| ziUoi+z)$w916b_C{N3$pJ8~EMsadh=R(CVlS{YU$H?5)?trA@7bhXc0LwovrN}_tk z#@>yYSts;ZrT0@5cN`j{KjqV>+vB40U`#KhT1rH2k;*F13AUYil!(_OdOtov^jVf31$P zJ*R$cNxJ13rDeqC`m^g^@(p&+I8#gp7W5SK(0f2GdkRHGz&YLMte;5}%{QPGXIyEQ zz&VY(aNXz?>W(IQ*A+CS;ba7C=;H6a4?3W3FdnUtVXQ>_^0KjY_EBZ_6sx%BmKGSwgt6r{8=9t1zaNQ8FyUl$BX>jEE^O1A58T zojXX>G-nm2{R1=QKyuf6u?A z=ct}+oOr;!Okn7wCgXeawa6c=ZSYocz2uXmiz(#Ufl){BG2LfolAe5%j_u(sM^xqV zaHYD8iR833Y_6QwmgRZ}iBNf_BVTYK29v4hX!xT>HT@d`a2UOV_7Bjfx_+?n}Hk2SBQ;->J=K;Sf6V;0O@@D>YQ5YJwAu#zyJw_K9a>3 zx7pkO)32qw-%$l^zl??!40A$!U03wQAowP1`=oa#%aP-7Ox5Q!VMSd{{Wgjp8N&C^ zvi3CxZX?(d13E?XMofe_GDU58$tPq zeyYrw0v~<~VrWXv#I>+DDV`r&?f*z!42R!8eG!L=a!H(9g9m}jIQ}6Jsn+(9_uKEI z5%9O1FYVc}UhmMj6Q&~pdQ10`C@%i4aJx9$zMBhh2~@RH$;Wyi^$6^ePL?rWrZEc; zbqHQO_^*qyEy5XTjsj4-nV-A{xZ9%7`Nzw!rYFphQhjabzo?Mv{8;SbvanFh1xrkW-;n(NKLPKKP1=!kS24 z@_P%tf9~v^JhHiAmh-hEXyknVDzz{z@a$jiKxuDQoLJ zt>)S5Xyz->1uf6%)uJP#4Fx%$atrd_H+0M48Hl%=mphbIAoQAkS$ep z4YxW5`CYqLSWuwW*oLSdLZd4@pKw*%*r zxBTaelpD}zP4}p(hAZw^KL!AheE zGX2aUEOKj=5o=vg0XPXmU)eF)(W3j0=$$ol`nJ$)PdGg{Imcv+@a1*gyvlevEtM=3 zz%j78$w$(wPfuZ||9~(vHLHR1;8}I7Y#*>zWj%I28wLUzT&KOI=J^#I07V0Z6Zv<-zgigijm z6!Y#)wX3BP#)GCz$!_+r9mo0-RH!W2A@z>MkU6Yko(~f>p!oVYHddUThD}=R;3WJU z&B(^?7zI=mj7r8RmahH4?P#=ZwOY%O3UT@ePWPEd%oh0Kb*?cN2GUgDuHCGDsVmbY zQy#AWwC23eX#^HM=$T~2?X~|C$;$q+Aa_nNnW>c-GsK)eSTGuFoD8+u&5=g~CP^xX z#9rGqHwvhvWYwNv$Sg?4;ioXZkP{Ibyz}D?&QKeTQ_xo?BK}i0$a~fIh?hr>1&3;d z)h@alPisN_gc=5#*5<}7*J>OWgb!%`SKE%n7#Uo#s@K5Kjo_)&{)j^wB>P z-gu%xwB(T<_~^_!|K3RW$`|riO?~A4)t>~#CqNElZSnUAwXQie>kMvT{tMwz1dU{HubGn%t%DBq-j9%=aNWZ2#U{n$+(T z2I_1va0buIG+#=U1rOOzdpu_(R7DuOgzVEAkO31|{0bhK`hC1K4*7arS+Er5Q$r%|@U`m2s zfUHaNyz{42E)y>3QKKDO4y+YZ_+*a3SDB@@ZbsI3h%oj>SZ@j|d4Q z5%ERhSIZ=BoQhHsut9olflLxqh)FdvX{OP25_&bY`*p|b4QYz& z>fWHZK$4g;`E@eLCPns>bpP5yBA_s#kO-R*gz?vkbFU!*(rfiC#0n8f@bGm(6Mp02g4GUcV(VUw_c6P1pMjy35bH7CW6PMcJm{i?g-2E&f{MZbq|o`MTrs3}=xt3eBfc3HV*%p%cz(0`lsZMr&C zDW)_W4krt^I+7K$pUx>&b`}1uh(H_n(;a|mHwi;6x@V)Rkzki&HS!|;2`1V|WLvxQ zr`?uD^he_pho6}t6xJY|Gl*jmE4LDIZF7hj?}u^lV?OpMI*e57=QT7T+M*k&m}8Ln z8ucGzAOAcRTM6~QnSUdHT0lQ zTK1rZ+ApEM*+JIxoH!j`xo^75nH@F6=TpiS*G-FNYnN6uTyKw^T((~36{(xuSF!^! zE6)Y?OiAkA=Q!BLa`39}wUkxdBM#;6GZd`aOfekmEwU69fqr2h(LOJ2g&DR>>TJOjuIiT!`XQF|kJ*|ChN1Og02x_Cx2b&_TWyeEO3+)iJ^;eN(4gn} zqlr0EB<1mWK1o;dl9VyIt4-*|U1Uvawz|;h;4Iei`I?qJcb@giaoYT1wUfsOiW`kv z*E-4r*}9!oeZd4q?jil-jctlMEELmhbzhr)-KwTZ!cg&1QdRZbxadO&Tmg0ctsmh9 zN2tm*_?+g_Ju@>EaMvA$-Fl5h$++{nUzUz&DiCbwX!Kz@{`e$03F%wI737y zVUkaa`oVp)%4f;479A(yU!?8~naP@5;r(ow=Un{rO)!nigq&ySWGLer?$)i?l)UJ^ zv+wV2KoS{pI-}z%RTho+)<*;D8^8 zpPg*Da`BtFLq27Py2cFQ`alYrz1@cUg)HEcx#sJ>c@^x1 zI4wnNmCy2{XM8lM9h4h-Fdao$<3szb$ z>k!s$Pu)W!pAYiV_S@@E1-B~y$?oOH{0lKdbGe`S4BW5y<>MM8B@Zhx`vc1!AmhxY z@>qbppI3C(WZhwr@`J;ScSWrRWL|My86b;cqU^w)vy=FeUL$A*G2Z`78HNnPP5#-a z$_{gr25qskf$@$`$jNtzC08XMSC+uVxAJ_{^(wQ=bv` z+^OT8Cv-l=_7VIcZudDpuA6cuaPnSt)k#PZfVM9eErtsP@_1Ym*f48N?WK|I`^{Oa zWc4J5Wb=nNOWUY#MC_chDtwSFy$N_9uFK#qP`3p^au$bbx1IGGlDkOk2f zQ}jScuG+VsDdVkab8a)BkOLvnBD?y)jJ2hJvWkv9ALHHNfDR;`);%* zvlCMW7B-a3G|c#s2|DFIHnX#oODz2enQX!&n-lHSW;e_iwq-SDjcEJvTzKCFJ~rdk ztoeD-jY@R2sOV|mmxG|n5H3gc!Fl6zJlaXsbBBJM`{;8%kq|fmfR{MA#raEJ0L&8r z0efe4%0bW-=1Q6Vp#ZcelnHe!_jyO~guy81P2HxENEZ5qN4XCg0O9`hpU}sFd&$L4 zk&bw%zW!e7YI7KYKu{c`&CG60)|ymvg7LAOkUBp{uhSuNrD;hwzS8Qgm9<;_X)@H# z?sU1&85og>KBFi&IT2jz6$Mv{2dEO^=E27H-cTzoq4-g%@e#eo;{b^4>pS5|7(hX( zWGc6t9SA{&Px`>vzW%zN-69RHyVuij7!GInI#r^)x;rDuge{D-vO-P^wy%K95bT_PiI*lwSx1N@iR>P=xdy9CWDEpaXe{mg4{M6eEJZ}m$;PnM_jm@5x= zGCCg+t3qeEXnY0WO^_=8r&M6E{-i#1BTQ=MbU+`r5viXHh=$PUQvvv}cWwtP2v+(O zv(GH?lQfor()`={w{K?wkemKn0Bm6Q)PHT8s{xd-2*94q+AbORF9f)w4Lm#|w)xu- zC=|+>vY^$zzAP#gcwL|!S7ON7UcyC`zCMX)d-NuEA{4wmB*XyL(4KH6Dhf)YE$N?4pq9G zb66kGRBlHqovo?i()akC^vsR9m$vdg$s#P53)elT$~%TV|LCh%kR2XvT7o3({gDuM z6ipF$o;v;+$2x%rKtb39|4RLB1di>VJAEgsOa)cIcFJ*-2`pP_5tL^eB_2Hr&C&rrua+m%M})zdRyL2_dMj7~e6SQmnlbxF%N2aPlGVT5sc`iB!JlnYkx)r9v6D+RETNMxI9Y+VSYAl13m#qXGVt`uX_al%NAh~^^1Q@DX z(w1EAzw@G1tJZa5Eyi~kRlj)IERW{?VcO)h3mFWht}5rj(7b7rb^;~A%%NN%dV`1j z_Lf0eWeH~5Xo{psV=v*KfJO^i{x}f{fbL9}t00n>0C1B_OB2uqOKwqoSm}Z$L%VbY zO)ltU7$HbG-3CdySPnXkX5sXmeJHWXctXGs8?3KC7`_*(uuZ7!Jz<8%Boyn1;BP6c zM-P&%z(`hzqaBoJ1|b}WIXMmigJ@TRq6BzQ6cr?e<$HuTZ3ciCSK40ID0DD8GRAd} zE!q0v@}IEYdnoP)e#;Dw`yBK;W~oatgn~TAMRs!Jklc@(R3N1$G3R>JJ~&_u&SgC7 z7HvJPSu&>?$roRhtn2E<2pwf_XU6@!YUS0k!!3}3Q3`Y{6gH8!bhbY6Pu*S`bQCZ^ zuZ1~5UMRy1?d%9GTVyQ4D5u!`MMB^q2ddp{hKya|w4r3)zmQOsLw5QH(yr!F(|NJJ z4WqPFWD7MamWs)=*=d|a-GK{%(f9k%BaxLsNIzqY=1{WszmqIaeO|;{tM6deixVQ| z-q|fxw3KUyU3-n30#gavMA-oGMREx*IEDQiKHi{xM=kgqK=l=9{izmRm5U|OFh12P zJmN7U%*y1^s(PI^WMgF}CSu4Tbq(aLgc&gC)B(KhZ0Aq*wqxbtxm;#ghi%;PXEJYt zo9_T!GyH8mWZIp$ZIm5TO7)s*UCS4ecI2YJ>%nf6LY1HiCw!?ko_2ZHM^=P1mma?* zJ#Tko5q!kN_ySxRZtf96JKDVeaqq4OpNX1%MDZ#v7wzCr~S z<>!dB_D53e6X%NrSmMO3tG>nPP3WtjC})@v`ry)Pl(Bh9VD*dz1J+toeK}thW!9AQ zQS$<>P3}`n#CMr%`sf^jsq=iu!^XMYym}s4z5%JXlR+7DafhojV2_3<`1sfwqIL9y zRf;8I4t0nKcD?q5A{|8_&B%(UtVlDaYAkqMO(>95Ep(#BIvdVjFM?GkH(L5eO>zGVQfS7q)9LpQCp{%!)4iwTt=f3X9 zc0Y&BU7x8gkdvN??Cutu-Q?M}KE}k1(C=Lsubi8Gwhql_`0V5&^UpDb z9J5KtRVSAms$1^h!C*SHg0!%@+xW!v?$N?S7L)%H?MErdcfZFIh3j2h0NYL7aV>gU z7Gi{0+}{q`a5vqVGr2{BcXlI|1v^>6fsIRUn53@A#=)b+X^I65CKF^?^!=7^z&ehz z!23-4{T_qf&Wvp)8NX?3p*E@u_x$HnPyxE;U$IMCk(^mX-R9@t?SG? zmCO?y{Zy2^2U9^0jtn+bY)Jk$gjv65+)o%c4jpVa3K}3^;nJh$JECF~)&iftMjnSw%XyCR5Nh2nPaKn1a?BttG~?9H z*3lzW1G~Kk5Z&FG)J2<|clJmz7b#YW9?PzI8}7Q&zY#4Ew9T>9Yu43w2-E)Xh8-7L zGUXlUuLPL5j*jV|EWEJni?*lg|0#H0GNg`d7UhvhE&O%kvTic*XGs zWZ}pWOK@&7&x+5dpPJ7y(`PNCV_kVQUm4BvcNSSV65w1V<;fGpcmND z$I7c@=>LQdKmVe-vSk`#UpIGBrhypG?n#tw0=WJ1HU!GMH$eaHQI!wh-cDftn;HSu zGe3R_*X!e?J@fuzFDs;rzU6(nn?rkjf=d4{sErSC+ZwhpR3n8CWB^5T3?Mvp2{^)z*W zjI}J^SQHFU*{wOlIt+AaYVA;!ExusCf8Bdunxs`^PWZSTroRL7i?{BHN-2En&P&??%oW{%EWs=mqpwi^eqTPiQcHCS9->tM z-@Se!C8{XAUnXJ0R;~`HCSFfYzoT(CpY9M#wAP@dZ&PVP{)?m^FUtEQ&x_sh{6jDd zH)#p;dNh?I=b@&(Xd%9D*(^W>s)VqD6q=z4!jyPuA?z68`RfK)UC-H`tuUV*YK_7) z_g$V5bfY-j2!^(!DBdD)hf+5R2Deb+K;xH8qxUGQYCNA(3&xlxJ|5_GKTmk33z9@f zLSIA7U7#wzOiesCsy?4Itu)0WodiA_5jF#}JRY9flV5G<8+RZ`L+673as7tsBLb?S zUj4#Ot)(Pvhw_ayPZgLRQfX=pjngCh5SUwIZ=$byWh#kyG+?Xu3>P#!VgY#1!U=`B zCv;py8TT?F5aqQs;Q%oxzjEmmdpYOt5-%}^kQzQgHvOi>I#N5vM=m#M`1`Fu$3pm< zfMm*jzh?E@aZW9&vvL~PdW8G3`;QT61U*eS0P#N&SAQG0X@p+(nw z%k#s1r<#xV>_*y+QN@(+{;39rxX1UKDLw5+(T$_fQyH%xk~{~YGd$JhBDUcwKf6@R z!vV8ZSu;bP6BBPW*2k9gUYZ#T{RB_*vN3T@KZ~q2G`jqD(%2#cuA91U z%xY4Kb-o}&PCjwD%=48&#rJ=D$jc`wZ@oJ+C#QFIyhkD)(!x zdyBX;J6-s~^2DT@*cG>NqGR#fn4fIYhu$=iC%o_ibNjH6yQx|-c2fZp-F;2Iw;ATe zrRm0@Q($+Iy%nzJl#H1Tu6t7{-T$Da{(A0Hmb2WSMOpw|w%$h&{5;I_TI+M+Y51IU z?Y*}h5+HN(Ffw3^kq0@1>ph)C&BeL41n3%NGv~yU1bST%R9d>wZ5(UXTQHHU_2#hp zW^|cokv6@(%ncq=kYUtym7o7S0U1htg}DZ}qPLB-KI<2A22GdNJ-?wtbIqH#nfF|p zptYj&XU;;RXRukbCF05wZ?GdFKpG0;!C-HJ7y2?8C}fxQ)!6{1!@-B#k|ikBTsE;))agUUz9bv z`gG_dnASK11)WMgY0>tz``6G9tEAzX|LO~Z)O23#{;toi(UC98Xr6nl6DUEuVSkbRUR58c?squB(oI#olUUELTWxsi0c%KxfPC?CBBBlH;=NQyGKt zGd#|O$ver(o7i|e=;3BmBED(eqfIRN)4Ih}z{p2R<1V;#cifEI%IfZ{tu9(*eH4sn zHW@b`we(Uh3LdUC7y-_6`|THu3a*BS(wKG9U;(eQ>o^Ho>{P6-Anw_vPRecuxJXtV zZ*Vp!0c}$m->7~1_LL>{XQSC<(VZWh8DQtshk|*vmwzF#c>O;r0-awR0!Y)$dC=@Q zUZ2lKuAJO~q8~Mxr1hhik(Boqq&dG(aMQ%7PSehYov|7A;9E7!U3Ll>V_ANU_Zj(n zW&h4&U(vqgwP(?n&*$HOhYo_*#ga;x=Rak1M|m|{Pdxp3bt}c{GxncGQIEIs4)g{p zx5v<*f_HcoZw5Y@pNGhB9bMQ81gl-!uLYGcwZoL#HAJStR-E7HERt8v-=a(Eb?hlO|o=Fm&rZDZh#00l_ottV~yqA-diJ3-> z#zvWOVim43Zg_uj_9!H4Z(>2B z2ZvY80rhh&c732QMa+73UKq=!SSi5=FId1&CjW6d!qbl`THgyvto)H`5o;MN$a$x! zost2&umI|@E`d#{9Z5VYRr!wITu*%Pbdu0(dOEKpxJH1uztCMB8(s2L@U>)P3B)pC z-Gk_=GOG^whmZnIzQ|ZSA1ytG@SZWY^Pj?&@r5c`oJv+fo0r_0t)c3SsA zvY@A%%^S5S@WbOB%P5XS8PF~T7dbUkhpPVmhQ-zpd^bM3P*pT z6pe&PF1@`Up{uUDi-?cyl!AGzKY9i*e0}h_6jS#6apb&I*(cs)r~PVi^M2g7-Mj8B zU2hKdx%Dpna_85!WaHh#mL5un?bAd-dW*%graHTpz5t73izYv~OI|`pDc#T4zz?j! zJ7qAc*7?Uzy7jfKv6b2-Ut#;Jdx_q~ZK2`QBSHQ<%D{Yrk|8|DEOThR?)KG-$vMH|dq{cjiB__GF3b zcM$QP)W&O-&moHbZh~34*hJ$KXh8Jo_nDUp=ZceSuWl{YRL<0dK{Mq>1*)EC z-(ghA%{Nwo9kR-eb$>Z%9sW9eDgS)9f(=*`7u}Ly2u^FD+Lb=-a zPtaT*Mw+&z<2&&VOj-4g?7Xjsh}X2~;!i`Ubn^=Lxyf z0ote@dFzUowv(XQFtQg;heVf;vpHvOuRuU;gOVoR)JV^F8(W%4;IHE(=b z@?+1-^5I3!N0yJowgBSvn)}|b6`sPk^*J1kSu=mkTEoc4JJ-j-G%x^ll4!V&*ZE*^ zXlb?X?Qr*iTu>)55(?Xy>Rz0*EFl}_S@4QkTq&MsdYvXoU5^BK6--PaoF0eh3Bs*O&fcfZM~Q$Fhtg^WkOV)9B(1i;H+kF81GOrnWagi*X+ z2TQBu4L{E!$emvmAFNtU)Vr%DY!{4e>NdU=I9c8wr|t#Hh0`GVzp700tI|f1@h@pf zkH6J>9*p_zCN}2PLKD9iTfLz%CROog|ofI8=Nj$X&&(Es5M5%m0XP} zO7Sg*s$ENIH)6WN^%4vVDiD2xTUpa3_EnhVES2D+Wyj-f(c;IsMQz%Neqznmv-r*{ ztqvf+`mIKX|9kUM(_j{Oo#pb_TGg$7+^>oe(a2h*e&#q#TocgTl6GAQU)s*lt&QI? z)j{DP_T#O^QxK1jaOV`j^xvIpvj`R)19-V}?xl5JlOgXX7!R9VrmUU|gStc}bkHA_m_ zbNu#^loa(t$l$J6ym;wrL;2Z!csXcK$beqTGHF)evrcL`kR zk&VpP)geu1mwd7Jg)_@{=QN;BLU|TWv^q9>Lpl3uqQQmRN%hyOxTgjIRZvz)Au39k z=cF=xnE7rHB|f~#vQ>D5x&IJnk<`NS`D^!dm6CeLQ)`JlbfVpd^No}E5y@+BnLgev zhTxbZXF$3TLtV(hi&3qW<++Wgt{Q~-sh*0Sch8>;(!Bsdww z()^z0#A%q~a`UE+L1GFD)7G267=QgRCfe&$IA+(DIFn#>T7Nk@k)(3 z!CDJ*>j&40E`HcOWnq-oKfLOGgccGWINtzf_loX<{(igB8q{@(o3frtJn0q$yvB%m z@YNBcErm<|$alRrN=`tL`!~u@E(SEb?FLuF_^>}oxMT4aHAu7SEomS}s8M*Yozk3X zDuEug(h}`w)2+X~)^YERZn;9dxOx@l?^CN;URGBPbL{BxhRnnH(s)e|_UFW|;t;b) zBog_Ws6|K?R_K1<^H%qKJ#59BHqQigc~%A~RQ;+N>1?!^#8AVsHyr}&%nx?S9ezWS zlvVNiMn+%3t3+f(1Koi_eF{mk;z1K0;AOS#`ix#XT_JNvZX%E#KrHJU}3_1T6EMeR=2+e=V!oSYw1QS2YDyz*-2?O>ukl7W0R8bmQX^ z20;cCbN0|67%EqFE%7$OEe(#Jy>}e3()C%vFMU{~lWl{wJj59g=>^PY>Z-XFw(PYH z?s6ve!n$OCffJ(w#v3vDd>BRI*FKEDT-gDR&_dw!0!|I&MLF z&&9M8tYfE0Y@Ll2vhiNahe`3Ucid$MwasRkR%rWS-Hespdj>%YKWP`T6RH@<_z=Iy zc~i4Q->+$#0#aA`czUgfUT$?q1k8p*cw3VhIBZGq+F4$Cd=1bAHPRN@J|mgo%?U;q z&mf~GDzUhz^h0QKj}-t22!8dXS}jjzRao7ow*+cxnXYMIabbx;SK%MJno>y`$woat zpR=j&JVX@VM;#C~mg`BUTAFv1WCB2Q!L?DE+QI>`rRzilFP3*ntsUlia|T$=3%X{e zKg(Ern~tC=+VzJ74@J&7B{-?^Fyyy?xkJtbzE)E<1LQyt7%aN$oL#)*e=M<1@W+w5Xo zoe&LuEQG@*?mueKF~C8gZMfht3s{^PoUfU%Z0Z#}oUfaRLw1;zrtOYJjo07(Utw$9$x+SHP8l!a2JpW?C9#b211rgNCr+=Z>` z@dg_!k>b-tlGS&9o@8J{LCe0xT7D?#isr>hbX=?#^hLODf*aQ)xbC6q)V@>lKOMni zHFFOHzoKWp{cxILY`d=1z4tTb)hy^=${I?@1|if`BJ~pjzB1h~_fW(vXBNt6S=?Y0z_e*4Xab?d;fY#A-*=Y7Fr`e(uhsL%!cS)hdLcruf@$Mn;b zQ1!KsD5K^sYx3Q=O^~rTnfah!I-d{Eb_@+p)5(3d{wQud5M^o+1 zXtI^3AQaq*O+Ldb^)NGGsD*t&p4M2o&{Kl2GI?m4loAtiGBF}P{KpRjNE!uLlI5u!T&B)ucM30%pNDA+FIWiDXTHNP(Ot|$&uQ2V2G9pCazlNjTwae z(mJEDm}kR3**R4#JxdjFr>0IK94)*Pp{$c*!1Wg6$fFN>ll4nLxta9^50V~ODh3ulUR+6;M$hU^E~G4b{bJ z_!=N2V5W8tWUt7&#Roc5WHduO&P#ke)H|^&_X7}k&lwM+=eT$H-f&N#q*6W`v??Qy z36dc~Z1N`9pI>Nu^aF58%y+{_lb_Utnve95>GiFTI{XUS2*S^nefixH zY1?T%(PCit;}%7F+ASXDo?qi0Fk7SX zoi4b`C7KuNtgkXy1E(teIbxNazKvfS?=pjcs6#8r|ft0my~Ze8(e745ELWzDXOam4mtto$6eiI1gLiw6^Q5d9I6JXdM=dk zqRZZ)23Y#g(}htV8m#F1+ix2aTeH{@6=Zd^aq_D*AGRu@-UB7X8G1rQluq2<~kyz~qCrwmtv?=#|zcHxC zr!h3?C!UHrak~CT&*6?_i5rr8MhBnNwdV=Xvq!!6zL$pzJ%xywX4%g`EgGSfS|Z}a z|Hi!16i0~MZZPV{>mX}{r0tIa_cqmD^bOv4t5f2hb@$QIi@W`I#jdEGTKf5G=$%km zB0T@z@#np>y(7OEv2lZFX9?*~{u`>)W4u(ElB?yUMZc|;OS?+?)HI!_pO>a`eR(NR zPZy6=2~Z}L;=8R6daTPb8R+d3)s#6w=k=9;_`)FU{KbLI#A$h+O`720AP@*$H!!@h zpt3#s@ooThL36W{`zd1vX|Rcr@#{i&S}3kJW;M<6X|`=18jXK|oGd^iZ}-Lb!>(X? zfoEm=`_Ep9rT%%`ezZmt+J5M=JhqIYtEXDKP3@5@Xm5-ER{Z1%c;}^wAW~*Rv5^rR z9ap{GGk>G%>)meOBn7puz{pbIipu0)ol7WaPKPRBI{zvf$@89ww!W{?3(9ux%Uc0g zKuD{FAW23~xOK8`lIz;bI({q;bci^X1H-g(Pw_@_7_ zJ^Ib%w6pn*{7M#)e+qmQ`t?#$$IGt}7ppH$hjOF{BX3U4rKQL-HAa=bjeA||9Tmn6 z-%Biw$O(BrBB{1Fk#%onYFTqK@rq&{Sb4*hTt**nTC)_9i@w|$4Cfr;N9L|$4HjH6 zj(cJb+I`B@R^GCqnG?}{)7)1LPCv9C)MHFp=5>PT&vlLtz6s1No&m-5uXo;)AvNN! zA@?2)z68^WmLXu>sa|Z}r4Wys#ITPi#srLl}kdVvemrU(fF*?M88IG>(U$mE+i1!;5Bc-EySzxZ1`TT~% zX|}9Zjw^yzB{Lk7s$mQl37?1qSo$Dc$+}bl>W{qQsYx9Ffy3>;~G} z;$G&OK=E@fihzuS`n5WIF`-n34QrST`aMonj$^mzu98f+C0ZIYly$W3uoI14{h?PY z{b4cP9Tsx}sWE=P7QF3`KkP5kFu^~AX%uDF0%bv{5LM#b%f?)NMt-P>zE{!;v1T35udmo642xvIgR@${RM=W+ zbun^6$1rBqd@d#adtGn-KtGS1O9bQMpA;Duv*5ug$Jn~^Dtxg7Xa|NaKJ!n zKX+(!r^D%5U##~ZZIfXgQNZyJ$I!1?Y*V8x!`h?9n$Oz?w<@<}2wk2Od#_>pb{XxR z9(?sbMb{qAWdHx~ofu{|8|Ju;VU9V5$YxF}r#VF-hbTl*TU2DTIn1o4C_*TTCyFT2 zVRPoGo+L`CO!TCtCpz&hwV&TV_viE1`@XLGeqW#K`n=w+!^lWcO;PQ9aySzN++NqST`;xCD#A*_?E3N z+*j2qwC}pNN>lOJV@8x;Q9QUANH7J}V@(cfF z0zl@7AC$>Uw!6Czj?S2?3KO7s3dDsl_v&5l5>nAA6QeC)GoE3fe~ekERM7d5e4Ri{ z>T-&t;Uwt&+U4TN1HjHT??iIzpBF*7eeUMGI+TF>q@BL@RO!QkY1usvO1&%(D-FJ= z5PbOPVyr_C5HH`$PgJ;j*-qs^T!ZAV8ycWzECp<^;QqAl1(UeA*FWz*D^%RiqHB0E z_NeKSU0PLNr57&z;eRm(9*@Gploz_UY32-24L{L5{j3UcitYy#Ny4+Y5s0JO=bYA6 z;x}Y`GHAg}o*0GF^Pe9CfgAK==gm@yo=AAMnaDtI>fJy(gUp~lSK{DH`0e+Nyw|Bl zkZy{_I_=o%VO6(Ne776=*c+?)O9voDMj)TPFZis^cH(Kx7Ro(WvtDjF)ZKj64;=XFaqC2-6?K*0Uii)5HQ-*n~G-h)>{-EPwmN{uFTq)uogVctKl`BT- z$Far-phB?|>Z&lQYBj@hCtSbXD3Czlk-{@1A%3@Ffm~{2^SU*MnACkgKO45vLh#_m zp?*6;v`%a0D>od8^Ei^I@>fzV5YhxS^iyOBEer^st=B+InBDQeK8xk@C<1|t7=`4a z;uqM_VEG@^sDHM}JEU3?Y`KfAIP;BrP;Kc>^<{GuPxTyK6*&qo9ln106<7G6n>@Mfo<|Au8cYiIN_G|AyDH>YicN}<|>UkTW zn6Hymd+8{Y?xWTgqRvd{nnn*jG3yu;?W{UyT@Z)*46>1cO2uvt1cd0Qy;96KDSCKB z8q7?d9rQ>~`(G^E66ST3*zTf?e7@`&V(J(NcP^|erDGL8=R?tNmL7fMsjE|()#qSb zV-_h1Cu%9oUC#+xjElFum;D4fVBW8o9%it`;k;b@c-5CSk5~9^BPd)E{VwhQ<(iSk z)Ui;bs`VD1MB5IVz?zrkXS2ayU$9`nr**idj@TBT9<1QKB3Uu!_@sgxsRB&nswdZe`~xG9PynCnUFspM^G=5My)r z3K|W2tqumnj)PL;W3i-3bW{BQHgz}e^E0|B?JS3?KfCU{((F4@t0{9Hkv5-f(wWeB z;HRYEuxaP*how+OJRG4JZHGk2^@bugZ)g~1-0W;exBb4LBZ1k(QP`jGh5s4%@m1_U zjHW}<@|PUH`9Y0&Ly7OjJOH4v&mMTG;lG`Uff`xJ{0B?`(@v4I9v8S$7rNyTRAybK zkt{PxzqF=N1n%L#e`GE63XZ}^uoe&pFG7>`i&%cBXImyZrc>eHNts^L+X_SpyGqGw zrR8+5_f5R`>0BN3-)_tqekc^&Z;$}d6tFuJh7ab3Pp?GJk_&1(&;oA5Uu;NCaJs~7(Gf!d?g~JHWs3_fy8&>}X097rhZm}6-6#{|p6?AsB{m4}oPi1uWV3^2R z!hbwb+y9^+mFdSlwmAGO+4=FOqw9)^4S#fES(1krWi2x-F%vz-P?9k`qdJA+gmfq1 zovOT;{gII`!GDA5B6NQB#K|(4Q^mTPxHQ$|U+*1W-=3vIZ;9i_m`IB?qQa4uG5BXo zmuaF_Skp6 zOZf3dza;0RnFsFKnGZc6tBq&?G+3qQ8`+mkGu%8PPH=M+@uxw6{hbtQM;w2$hdGb5 zh3~PRO%%Q|D8ji$DkE(mL76~Tag}k9gYF)MbFk~2Dq*Hq)hiubm`+`KV_b3F_H!Gt z55fDb3Y~jYS`OZ)0!FYzu%Gfl2>lJ(Eb&=h7(b@f@1vJZXuw**A^2Lcp{~UpHAaJI zPl|1q2}l_YRtEVaZ}m?Oi{RiWRMsk8Qns{3JvEl|YWyY2{ow(EdNxXiO~YG^Gdr=9a{uCu| zP4zB@l|3F0b|1w%vMF7uy^L_e6r`9=OZEmkeLL_e41Aw~o7(5t*QeV!)d=Qh5`$rL5;44>&nmC4oR6J*ILsgU=Cj z4CzM^+A#`XxN$DR^0mD=iXUpWkiUcI=@++5#f3gdN)0tE$V%#9c8=GBoZnGVr(R+i z8Tgp-7WtgfgaN-loZ=P_s(ruP#^IS1uGMhjE#d`#x(eQ{dEy^oj+Lb_1JumPcv`s` znniv1`J@B;D(T(@8kB`t^#g5fxt$|Z?lsW*h5CoFRC&zP&l7hsdHpa@(A{C8^*)h0 ziv;y7TMR$>6Ia01RU9_^${>p&qtwdF$?&i=K(%yw4cXAW(uf#Z{)(FPLa2A^K(u@% zIao5}X8RiFM6}s}>`=wxn~f`|#H+g9jpXvD>hS*%`RA)vaTvb~57ywgWVm|Y*{#Vh z4ZtVidKB(^^EG*Wl!7!TdChE?|CRgsz<`!IkgHm$c0K=-OoczL#Zld(eb|=?ZEsN6 zu-U#OR9b?DeG)iScOQtfpWW@x;S|A51a;55y37u$Wz@_}k zS=RN|5q9OD#Y_Bp|FNZCG6TveY1(g?j=lI857B@BKbwH<0>L%6EqXixXDm!oJz1gd zCK;;F6yw88i(`S~B@Du!LLJ`>`YN~D?T%fdIksFkrDrPHl|RGktGzssLIrj5!9g<$ z_u*uIb+Q-Fi~?Qu^`Nj^^zI@J-}n`CCO7A8z3#W|GxX{Su=fHvXpiAk{HG6tZMLSz zN1$4*cAvQWC>eU;Y;1+Ho;RV*yRGm?lnF!67y7nzzk@3;t zxEH;oisgCqci84J7c0-zf&U0*)%(Gr*O4aKhTly^Ikj=v-#)fjX>1<4r>MS+vPEUp zt9^q1?2_@Sz{gz6&F~%5e*j9+T0h$^=r<+|+X@`m zwWECzC?Y^}GTyvHw)>L^iutnX{SCXrnG8+fKUJes(^fy3?%G0C=bQUhoXamgU+K_h zmOgiHQHp&7+P@5Ag8?8*d3!CMf@MN`@<~UnR*g1M`&xor zBNMegV@b9xSAb6+!dfY-dQ?r!yW zslW%bWz~7f$21;i6=bBgafaux^j3YKP8i2>J@(LrnHTTCZE>Bk!`tC1r`w}wyuGWm z?IwHgxuCqs*8v6J*eF{8V`C)1jS!R?68l=`wByXXfvG1T3okK6!J&{>2M@UUpG3{# zWiRA0$L~3(Db2Rq1qobeH&44W2fAxSlNOk!!wBbsYxyG&*i9W8+PtgGe%iNNId1ZM zwlAhFMe-`Y?c1&sX&e2{|9hNPAcF@$?mP7m>Bb!$r zXkL0e^g-hwL#MD*ro#CqWo^TeiT>%!}y^o7dHko~c+mz9I zxI+?2z-=vCU4J)F74t)P8`S9t9-eTROv&-a9bL9Zi^4HV`6}k}g@T;Ej zB_5dyQd;?`(Ng%c?HhJ^e|L`z#XZ^QMs}F z*}O4%(N?RwA7%8#4p;8mK9%0f=s&?M3!^+ITFHD9KEK}&E<-&t@>wHOJsQgUB+}F09)f^a1C0vx*@H~ABl^!ZVVBRF z%1l98sv0f0O{ak``8#A3j70fZKI%VZrK|e0qBG#ZeY2dO_i#ut%F*-OS-*cO4T_9k z8h=yMeCm47bUKkOMqSskaB8PoXXhPa-0|i7sb(QHu61eISZSDpRru3k0XYwdw*HiM0CXAc83CGH4Skk6+ESsbMuJ?%vQL=@@4$p1yguBqRW;r zjKt1G{Ip0@+f4RD?JE{|4-`~$Edd*c0pO8#aKFfu3SI^)U*eZBH9*JeRm@JqS7{Oy zV|s>(d#paGJc>(KiBRXm#qt3?&n%^z88*`n;B5N;SeDaL_(s~9x0ZdT!t#;bxMz3-H z?jQg09L7|w7-Q;V1bqK<)n8oepS&dU%j9S{f2UlLKd&KU?(GE1E&;Z@VQw?}=cC@i zk3%RZ#VhWiGyjVzwezHKfszd=s}C-g&(?ct`(kJNP=!r(eJr04%5A&Vv44{_c`Z;E zhVcpO-=@$j4(El1fD@ZE)3;NH2Y~kLoVoqalG43C{R#x8#NBnir0R~uR0 z1YR?yCF(*V=z8Ter-nR*{S~TD+vd#XAZ6oVaPCX>k^CK5(~1oPUXFEj8KNY9p~MFc z4XAHfDzpZ^GzNL2ZVt=6R+*Ou?SR*4eMdYY zM20cY9==&!e;4Gvq@N8`7Z^NQ-(zpxV3LCfdd@H@t#?xd*i&)iN6q&|{v8K_Ev4E1 zeaySQ5qgz4k&8V;DS>Oq3bi&oJCyWQxL4gw_M0Ld|J{jzu<(}WpR^HEWeTN?gDH8)>-_4m@up@S#YAl|Re1@t$zJrDV%t-l-hBxR|I%Rue> z{Dc}w9*r5Uwh@`H2zD?nT!*N~QWrO$%QZqTgP{_{Eorrv>C1(S-c#$mm)gYAIXLbdIk_x}IolJ=EfpOpT4{box{)7tXEV^@F1 z@}&2C+coXA!`Begr?NaF9|0w?o(Sd0GNNsh-fP0HyH`%Pl*Q;}J;e=W4(-0t0r5<3K_4cZ)5Y=k|m*kgj2Jy*eNw?;I;hV=p-h@Uaqn%h5L5O zHk5*p``9hMe?;mk?_j^jnfm-PC;Tre_=YMb5b4ys4@xG*Q^uUblIEQ`nqcsiI~cmX zlczJE>g9k%i3SeZ{TdS4`Z~INVd`s36;)3ldIe_#TzBRv$T5<&3%P4~PYRX?pHExQ zLz?+9>zUo%;?g86qnF=%{4;zkTw7_~4h2?s`JNa@p!^YOb$B>KI+)0JFhV2yF`jL~ z0rDR5#x2*YD7_BZtK=t za7Od*LndFs=gu_D+?7Acc;o}C^g@ekH%zmiUM(yxxUaiqO)4jPIBU%;V{Ll!8e6UU z9!~QoI=XIJjhmG(&wUcVx`O{vEIi9|f!JK!p_D3lo8=~XaWED0_KND_LCB_C)i=k+ zS-U!&w^}{=>+G7(Oj0!tisb%^rWCpzpDv^Cqs!Dyk@<_7JN&zpb`xzr#!{XNl1;yZ zuec1kt=F@594ddHUGK24iNG9NeL0}i1J8~IE35eEFaFuDrbnD+QdY%K2YzYJW44rq z&Kfm?gY-v7IVdopzhC7`7Y;B+^RKsLa7hF$wgE&MXs21C$5f5X&(Qaky0gpfo~|5C z8n<$oj%$`C$sdB^zn##w?Z5p?EQdgJ6fYC0Pur-QqmL2CnU)|`Onlf&l?O77+GlXR z)SJ9WRq3U_q4@Ds@P9yGz<(U?wK)8LN$aZX?4oaiGX=wh`Y#IjMZukgk-oh^UF}ap z?t;;uO@Q8-F4AL-xXOKxYr&x2=rXe92`L%sVpzLYbDAnfe6tv+Q3aK0V)$Pg2b+9P zJp?Ga?oTE7#~f4wnVZZ)q~|1{4wvyj07;qP(Iy6a|DfN?q4_i_`)dv34n-$cDx18$ zip5@|GtFfINtm8VHQ83~CF&o39UCJTsIKuAqiTBzVWnRI?)}tr3sOYe|nE&?9 zg)L2?>=$PQ(RDOWGpky!VlzX#$3%0pE`>@(Y|*4g_V!QGPuLwFBVSy}%VuICXII(n zAWfP}kjDq)z?{j3r}vXJZd0XdG(6nBIifJ*n6R==O;QWxmhVhXR~2U5D$7UBJ5?6g z$qyrtVeto1)qe1YebMT-JgJamvvEOsYyjcwztbPYfu|?Zb*Ez^V`e@b2<7&-yv+s` z7{8V!hby-Q@WLQ5_>&oig1lmqHl0n=1mUC&sY zF9A)Vta`3M^pqWGf2A047ankwqm&5!cXyiYhZhb$2){Y2_H5gqr5?V=M#rxeG>%SZ zZd>Kb9CiRN*3Q^&`KXg^)-QaBN}X=_S_$5#@m1X!`%L9^K{J{I=AvV5cqay@{i2!& zUR`U@x$H@0&$t$jv7*0ZdDTNafa zL&W&I>#((YUMBAxqqG|;i0TZKdQA2SS*ZCzfY=J65He0j;v0S8xnKnquRz_s^;EL^ z%ZpXccI~U8rR}bvSuN{|s3y1{)ud)=25Oy89pQWY4WA2BnhNz%(D4&|N|lC0tgNkU z0lS~(C|-~s!5JR-{4#qD1%+Z$L3|CwPtfgB-FjQH4N;(~5}8taP#Nj99Xiy09CLO1 zUIdzks53&H=hQX4^Q)e-yl10}DKWAsm7uqxoRSuC*VqQGw}4Zzp`n9z z+#1%ohlY~2ZhLK&nnfq30dbo=Rcyw)pK*UVxpOuRl2`txsc@iP?;z5UHGEhYn()Nn z^bHEv@I4|QUra%;LKW4CfuI5Q5W5Rs$MH+3j6e;9DdW)Z>$00BBsRCJRVF}017@^> z-m)>@C`D%tevB2}<~G_bRJ1ZSVO|caUlQTwIUr(5Hz+26-tOzrjma2Nbs{+ zJ@KIhPsg+R_L+{ZgSYAC{qvJggAsK`-94_@}eKDS)1Z9$Lp_IoMWU5xJE~1wT`cqv z$y8BK?_r1$0is9L(-gte@kAa8oM*gldw}?cv07*d;)I?n9{9c+G=~@~a{2Pu6nE%pD;cazoF$mCy?Z#3mBgJc7p71#Y|8=yp7CB8-$kD~m z<4rP_*A6<#&u&2Iet%@zj(}ICDbe-RGV*wR;Ef7$)CNFLs^S&JDfihBS5nnF^+wIs z-|RVONj{~q&9V)8u0I#QEHH)3Jp^}xyQhIjzsL<*(tZxmQ?n^W`|Ot+>`m31MeG!C zQ1l0I*F`zS;K952)h&X~!rZ9Q%l8}x3uj+w$ER9s7JuX~e~A1mxotZ~tZr9@<3dbM za6npSd<8HOz47&3{?_@GDJ=S+cwTc+_v&skrQk?1ge&)q{9k(+=d7Vc&0NKOgB}ea z&%sni_VSh?HGLu%r!JIwy!6=%QQkx~Z|3DZCyDO9#0AN zpM48^Y;vHdkX-tsoDWogarpZ0_{n>!XOO{LN8Z_}fiD?zi=~AM1g zggYtVLLuOw;B;iD5~q*`-?ms`PK(51gKbSfr_P11D>e18%RZF3XeZ{U69|>y5Pw+N zbtqf!_gW539)OJOtD26Fffy9r5H*$PTfP;)#+G$hLb!STGu|83Zp6WO-ai+) z1)vmzrKPQV|9p9aRAvWua(440zh5KE+2YlEMQQ-!2AX?>?Ye27 z8NaF-pWLBjH7Wgg{)T9;^|~Xow|;C6;z0(_ zaXauyOM}tRaW~hx<%=6gn4FfbWn_a0^CmEP6L zvHG<$U^14_C4Wg5b}{_q?HgcF3Ti~ju*!S!NjCW}&gSrH;QVMXWHx%+;$%o9sCG1}`)4RhC+axZv@6|;mu!DN&iXINvATh5xNT^!t6(O#bT$3V zcF}ZOCv^a=w9r67)il#z*_}8Kfb(pH*wH+lPp7RJOgkud&oNKxEA1yRY|_=Yl?G*N zLSr~WPWQTd#5{VKDvs!Jq~RTIv{zmI)U(=Y3!<@;bmV!L##Eh9z&sQG1-*?omL5e(o^hz>9V% zZ^b+fS4UMe!NxwZ)M0~McfpvLwCowj$nlqk`TdAv@x=ta$}1eZ>9rSv;wM~5_9b(; zz72994@ZFd*na;3;W;i?;)6D(u=qy1w09htj;kLW5wT$9v2DTAVk;72O_72Aq9L(ShZGnU+_Lhbb_BgPG?vxHIY9vu@BtfGN1pvGp zbVBT70ZTQL?Hv2YBFx&&iyErI|DQ2q&eRPO{EDA}_#Ny|2(Me*URk(3ydEWpQR3wq zkF;|4F2_Ur3j%jGjv~*h8}E#_@4*v&k2*#0SMqZRyzuzFjlvC$(T-I9n+LmctUBV} zs51y(p<1LIaHd0Tqp(?Nu(GFd&B@s*U$}p)rO^ZhAvFp$&+o59)MXb>YU&J1FNo|k z;WoGnx9SPSwEZZx@?1T9GyLMj46L!9+~W`(Uh_|7rKmDtxGe8+xxl+T;S*mqyWnm@ zK|;(4*s|0*5()AV=wzT^j0eY7Stg>}l*Y@wN(mSKw2t0Z9NLS4(VME*KQEUnk#daD#POryWeXL`GZYwbZYK#jx^s}|F(V~l61xS zZOy*KtVA_W;AABwiu_-|3iGzEk`5x`vXaNIT_{opj*Ft{B*xu&hPbUGqEF@ICQOfp1aYLrWKwd-rPW7rFc3-vWM%9YA{YS1|QV4`_!cW-HMuw*$YAkYTB zg)NlaORmmnJc&KAbD@zl6n|$kCZ4={)kXWx=QB27i&Pg8UKqfX7PlvHL~3N|*3eTE5;SgGn&u-PMJTBLT9)?eiA*8b8-UGb)m2Nd#+y}xNnHSd09YGU*O z0`$TFrnwXR#NGMM0ga~h-bCjhVezbDfXSPndq{_I{^Y*Ssth-+&0oHU?(G;ahg5+c z!eY~kGvXoxTs&FU4uDNI#FBR8$R?>7J*fke3K(D3_}8Z=t7YP6IvCD?D=~!Q5aaBN zC)(^68|QXMrm+oEjYOU)XWDab_0dn>0Qo{U)c!3*%i;}Brb+c?PSg6;vJ|hm{C=S@ z%_wYf??*t{C39y!r(#>^XBFTdzL|7^&lp^yT7N=#?7Muy%d$Q=w31qzkwN+P%~n+% zQJ1V3$Nu>i3aQDr2~JXOvHu>`U_Z-5YC{janpb=pmpyyOYRh@DM`}27)FZBGAr&A7 zq-=yh+3G!wM_m1i{+z!@DSkq7w|!iq2AVO~R6Ue2GoI=#Q8=Oukr_AP(u373+5=$I zzZ$y62_0I;5dz&-)%g$SVut^^Z~xUE=9WfSOE3Ww&*VkYBF5!Ejf5KDJ4TA%7B|v? zM=s(V_xn>ExQ6_1z=ryEvpbxX<|?fCabv^l+u{wtDtB+}HgbmLfYU5E_Z7RE4T z92zASm6uog1NnNDu^#IfxcC8oF2m#={c$0bWDyEa_8(OIorDn5di@9#wWw!{^2&<9 zz>5C{qo^+p1l&B6mM7v!pf z_!MO`Uu(e6Gy9Ig%Cw}R-fEkG8uujgshp-M*vzJqt42)Uf`L7n;X02b?4He<{1{VA z$%%A@|H)9wZ||%3A_X+viq-;x;(plXWoU`_!|FN-BN-nMw>k`1H-dt1vM{||=q@Am zDk5v`!3h zPC3^PY_T3jc8%@^JYD}iMgIq`MkK5dZ}K~4RNmT~5#z-a~bt+6VOY}0VjDKE$#oA@7TrN77J-phVTgkpUL zFZc4=xvS02)Eeja@;^?L!in=5byM3Q*pSpV+K)_szJF8R=Au2AI^fONkg64#pVvH_ zyId{sUY3iU|B4+MXOTWc+Vm0{6rou^woNQ%<8OepC6c!avzws6kv#J%B(wuPelmNA zK6}H|2=TG`)Bk&s(|O8G;=Db2Af-QnyLmMi$8+I%2i`UtrCL~-FwhNoJ9o%gtr2!F zKzR)<=i<#rsBkEt!60k=FD7S7bx$nv;6f%(&(_ZmLs*|LjJ=aR;%Ng53n1yepkWja)=)+1b#|O*nDg zUmCYwrFv(8KQGVqLAF)gAwHc~dN~G6q#R6oCn}E}%73xr$Psglay&ued6abd{^b52 zJz6f7f?+K8Z$LA)<5XN+N_+Xg+o7YbHP3{{`~>iS2&&D9xFovn5*H-QCs-Je{1T|R z-n*u>$mDPYYDP~~KZ)72x0a-jWdYjIFcR=s6)u<0YL6}!1-C%R6kJ(48rgFMc*qjxX39Hy+zS~B zPJW!GI($PsvzM_wT zl%$L)l)KNPUSEM`FZQ)J9)RqB>~y2qpwN^@FkeM7C7ta3%T}&nxxwMYdI_iRK*l)y z!rq+||`(C5|#h*sHW zHbB&Hiz9Gc%|;O(Ul^oJQ(tHV^egBHjsX>Q+A|HZMIBG!g(2`Q)12ctv<{Ly0OsP% zN~Rp=3ZgaCPQHV<81}q`W-6?Jz1b26gB8bMXg(;OPxS^)x?I`2fp02$#zb==u2VJ{ zH*h0x07QL@)ueFx^C4>kY<%3bK&SEB3$qvPuMd1$gC7d~+V_X>)$FUzDh+Hi6ch#K zZ;TF2ApfQZ6{gr&PcS)W2lc43<$3z+aNdv$^mk3#Q} z?pt~?4Lq}zP7Rx1qQP||gB5AmE8*j>9}7ZrBA*Ke=m}@- z6$AZzBaWZr!(m?zx`&#Q*BV(3cURw*mVl`a(87BTu7Q!q=01e-ByeJO@}k!#1sKf2 z^GjWy$NX3lr`S}8eeo9fL%%~O+lbWSWaLGjN`U(8 zwOiH6hHPIiK~|@r2F-8+0TR$CnxW=|Iafb*Z&pvfeVm{!9&r{jNIZ%pfdXVBdnC4fNGG=jrc&R7$t%Evzc9pBWA!>M> zr^ylEOUopTDZ@|miI!H<9B-1r_IF$?h?{MwesI&q26%RYv0Y0>;Qt`{TpS0sBQMz` zA>OvfI+!ahE$6;DMTI~@W1~qH1u_HH;7A_{q;tOkW)l^i2Z< zT*C7JqSVkZ4;MhbVW8p+wN;Uz`-d;H&VwRZ7`EJ<;cSwUhf_f`61WEmDD9Le*cTn5 zL)X@`Ud|#ITYqxkMx(o>FU~njMw+{qAPg(}ttf9p)41n#O9!tn_qJGi))#LnVTz9N z?woR_CdP>k7V(pg^z;{kQHg?5dP`ME{k>U#gm zCKq9orAApyL2>o2aaY`tHT15}Eo#Cb_&__o6SQxV0lu?I&cP|*0|8jJOy{;QcoS+@ zMKW-ag!Xw~*G0y5Jcjx}E}22we+@`RBFvt=20dZ^Q;TcT)fDiL^ny_zwjtKv?rP<( zoq3OcO9r*FU*mb|Ct(z?SkGt$1+j@S$y}+{(*mu%=jzI#9ui6U&Oyk0eOGL{q{xKg zB&ft$8Cw&it%ys1(!&XXpmMY+KzWVK@r*Q!3x*1c5v_sq6v%s?$hV9RCn_3(9M(vt z4$wTAPm^JJaS}%F%pAxb_VSd2F}MIfNQgfOR+MSzcdvL>v!I=TtoD6ZMF|nzHoW8G zY{7uDN9)N;C4QsR=VdiSLW|YhHH%%FEptdVo;P_B@%))2Su6A=&)r4&x^e3p7aRE9 zRzJwKC{L7g=KK3N1SoJS&+gHL_Z>H)dXwm(k1P1wC8cV|A%5Q~C-gkLGkB;~9bH)r zs%tzoIPc4HuLBJlzrDKCIu(fLW|q*!&SwChzOOx-_#SIB;84l+;L+$mtKq8bn8|kEv(|zv zT*h0-BpMD-E-WxFXYAcsHTs_0apn1Komg5s(=d3WX!?p0&Z zX!iuH$)0q#p?_M06RI6`sJ(QGVSqZgju+#ja3uhTi~Oa8(*G9%$(~+X2AmIqkGcmR zz+@xSRyqB6y^<;JqRvT;589tbK!~72^*wkP0v`X+6!M}CwvAYj$w&l{BWO z)`#LIjsAI3d}v1JD7Bk?VYLtyCs>W$7%ZCw$!~_lOYpHJRa?topOAvLc#vv^yIZLa zD8nZ;wGZRZNdrLl+KqW;IajdMLM^CB$kG&#YbDH+APx_b)o&1@WjDl;^J7%F?%QvA z;9k>cxaPkMr}`q|*tc#GuK7`WB%dSy^K`|qy;kOY{4P|KVbd;Mox7-q*ARrS-zJi! z=Qv9n9eKC#XGD6h{4ZIz`G=D=K(uCbU1Mt^p+S}c zuj6C%g3vvXvy2~d7I4C0`GFojhrDFpRM@?~D`wfg+3r}h^QD#E=aNV@Dn@UsJEEa# zGPk^hTdaDE!ECbyT6FQ4;762eR*#)0xwA%Bm&gLCKu5I668$TE@(DvAc7?Tm%JG3R{33|ds z*0LUEkAe~w<#Ygy#|b^*Pd=<6hr<>pw~=m4UsSw|+livsc+pG@DK=~3dezwLOpNdh z7349|U539n8EK`!xbhr$Y_z7dZWb#jKFj|*P`6umy%?viJb~;&xVM~skY!v{L=r8g zC@i59MUUZj7R%qx%)(Y)EQ(#>;CmX)qX@7f&{g@m@yP))=5@>(YRwilnH-DvYd)ee zi3o+e2@XRypXKFS+dmA0_mgMwuoaY@09l^z9oKEEVb&|8o#4E-IFh-jkw2c^=p0H| zw_t~&a&a3#Jz5>g{Tj;|Q`jNy0y{(bOnO;&{T1_-jc|cj>xBdi1Mg3zSufDM!WK3b zx?9G^-a0WYIo&UVCVC|^Hjomv4iOg?6=+(n3`;RN7VHZbQpW9-7kAt}`7r2f3bUQL z58$ItI3MZQT%UJ=DbB$g_Q0*P>)5fQ1<^}9d~s>?#zs_L$=O(I>N%o~;pHe%>&~>O zQQVAgJ+x83y{l*AC0chSgR_xai2Xt*Za>*9KmeRU@^y6T>I#eSuLTc-L|2C|jg4ej=?l)jf24Yg z$SUoyG2GwLtg87!JM1q^sk-~hadf_BDkACy@b{}@e=#EpdC`9Pq zf3JAmf{A*~4wnr*v%^N~>XtIzVXYD6l#_pqtDjI!6uan^tK54OZc$1UOp=&I6- z=YGZH8vq6*^YEYVfdhDnjl`-nfg*1L^)%}J(1Q2C{`?ta_QK?K2R|#FD$b1m%zq)i zEQ@%C&Za-fek`;zuf2U=Id8_jkDPpr4< z9zgBV(VNAxw@FZE-V33^a_BCxOq&GXoz1P){@=vw1*KJvKA0*{1{qSHx~s3|yVCJH zm%$x)aCTEBjDK9E-a@KzbQ1~qrwvLxH7!3^SPUw|W)Vg}7uREX?Cbn3*j2pzm%I{Y zMc$txJ?}yLX0@9uQWRLJjW-m)prFsuQGjCUrH5m)ALBua|D^kJOxu-bMw7pS{|ZTy zBLtew;?JosU^;w-ojR+Y+ve|CahPaRL%5y~&N*q#uO|#JnZ=-vE&8}FwGUu!jRrxpF#+_~Kj_!=i*IIcsSGYE z(%(D={CgAWADM^zlD1^!@E(J-9tAtQ`l|-KHTCPkbUsdwqvnNeY8=^{T|&oONdOQT z<4nsOCDJ4FoHaGka>u{U&}%5Ov_kT7lgq3tDnlI);UA}7HwU!h#1DK5#D-|JYG)50 zlIgKFwWnt}m=K#D;GH6VuBp-FwR+RWgAS?lyb9{taxx%`eqV+L8o;2T{sd)Dovm+- z>rv{;vGU&%PX9lit8Axv<2cxkN1%+H=i_pA))n#q#kAW%jk}nU*P}K%o$9J<6^OqA zS7RgZTtY0(H;W$vVWb^3dGk6a;v(zr$8Cg7)nd-28^ z6WK`Q2NR0YqeNgst?1=j4>_u}bp-wPB`<2^vg71tX%**{_@-pZ(Iu zB<4Jr9Vw8zYY=ZX_dnKK^`#$C$vBIl^It@+4FO7c`I%P9!e5#cwEPfksvnMC)5*lz zsjW5PRMp$-0^o*9Kjw_IA2-lfeIhCbYU5wRjHKef=7}~u_$OpnBzS8d5cqzg5Orj! z5CPFBwb1g*M)>~ye-xd2G}Hh8z;`plW@E!#Hw<$hxl?AykULo+lS?XUiKxhCZZp#= zif)KXAN7e+M#|h*sT9>pWlG-4OMF7#Bi-0g3fOY$(Y8V3F|T{(0Q7Lb(5l*HGi(7y zXu>5HjrP}rE{l1m{7#|a;4VWpb-!OCM>h~2@0}#k0N8YVJegi#uV;FaT$Nl7*5$LE zGg?k6t_)GOE+2eYD}b7p-j{b0oUguD;P}3j)JT+pG*ss4`fAU!_4hIxPqaYb<+~8_ z{ooHiRGuL_kO5+M8T5YKXD?yl2e=$#`SXEy17oc?@D8y0V2g!mnbW9EI>}})$=VnP z`E>V$a^hvW3BcP!p{)XWYiw4f;{Ek~)Kh+cl(~~ZDE&%Y#0;zwq-S66dZ!Xp2`UDh zR~1H?os0&L-=0O~j%`R9-UBEYphwX+@^cGx0i4BgD?tCs+7y&rw>9;qW_l^fD4??G zU}Co`_p}2xauj(B9LFdyGkq^U@Kr5c()K2tsL#<@CW~%d&93p$i2<>^$7s*Mac;2% zhd|$~*>vLCJOc#4dzq^=#VcAq*8XKU&_9++`pIbq4y&7Kz$|BKj$n>{+-P8X5>z*?NQd~A4B2y;Nl#VT_?*ndSil~<7mfF z+hkd>yIJnJxu+-lbe9AEpf>7Way8kTKa2OWElGG~{9gZiO}oTAyF~sbH@+zG4VsCm zEA-I1YdD~8bH_Bc#wN43^q_i%TO2L*Rk~)q@hON_?q$GUisP;M?4q}S5rA^Bo&`b)I zkwFP9O-V^lkr6dDp;V2K$MJ^Mygek!c-7@Os=qO%jD?5sG`P(Fx#iCw0`A(nd%;}zLN}c=dC|H z-`l;gY2`O!Ts_G3@~J{+;OHiGPti>!1&b!B2N8Z8@2!zX<(`76Koehl9%FJD zRwKqvBv*ZXj@`I%KS;r}pz5h_S;!-HdofWubaH^#VfJ%k5}+_O9Wbqof!q@$>na!- ze8%lj_N;Dv8Kfs=7MdNoWzIA-Pl7g0xpgmqY4e&1$aL%~ZEI)xn%y4lBBnInbbnov zsjNTJDL93_vJj*@Ba&uw#4Eewgbo9iJHRcO#nKAK$1|FDLvgpY{HfD7`vC2pye+`; zk<5hu!LIqK`sJe%^P(VDW==!?tjdmu(YQ*@e7sK9qw>kU32x{GuG+g;3Y*-2zw8?8 zoAr91y!}9Tq*L%;5C?s7ww^6|QCv6zz0T^KjpYrbM#5B9iTR+H|6LJ0@A;igG7Vpd zBIH@{+H3k<8I=5#QuVLpEU7XRYE1F8FAXKp6P0uPnYciw1Z7o})a|a*U$>1NGzDkB zPj=dHAPI$zRca~MTil60uD+3t!n*RkyL|?qr@Wzh?Ex!>^iHTUjDW{sTFrEp5fOiG zv(947BJscy+BlV);DNDpQLY#0o=6|D48D60S0hboBbe@ShMB&^JHlbd*)1M`H?#KR zx<2s}0XtE@PJNnkF8;cic$k~p&3W>k1N}Pp)u)sFZquNq4@64y1ZgFU%)p}PC@l3XFN;e(Qb6^+gJ=lO(5mcm*?(i zE?xF6Cg^w)Q|;re+|#{X7QrV)grBvV=s)865jFcp zyuW(VpFgm7-f%vRvX|edO4G6&;d8U+O%uFHA{%1a~VJIQ-BWY?tK z#d8myRqY@46u`>+9^I=Ysb;;V8oYIPD<62zTm%&rPsW^mb+i4MEnIMqdjG{bI7ey9 zRPRr5uG2$x$ur_LJ8elFjpwZGe|O}=YFY3w|^ zw_~VGz{*_Kl^$1|lcXNd3dW>htxPyx_{yonz>z8%6}hcxpQW#_@wa)Gw)!-Ne+Fgy zao8csR~9#L#10K}_D7y`78RI1Z%q)5vuK~k?~EbVvL9T}ENx4AS-btrb^p|2EWx`` z+rh23&u+F1c;4y3t`o|D`UBaR%N3b@r^+*mh3@bDP@L@(;DiG~8F%#89&F#%23LkH zbRtNp2Q`k{IAQz_b3gbDD#zgo>V&Ax{E-k~-lUuRZwALN28Bu9slTBeyUPG>`h9(25=tn_i45||6yK1DTnVLDtcD$JCCn>FV-AF5#kDh^`N z?m2)li1=A`$cq)Q zi@a?KMyKv%8t+pk#=mXTC@lRu7>eO-Rg}b3KJ9e553u*yH4vr%+$QaIP-24fCJOn1 z*Myd=9Jr^paU~@^GAP)IC#6{;ld*1VI-)r)a_x$2w#b z$1}EL9N;wjuO0E){%9Y9%@e6!y`5d?il3g;+?TU#O^T37aTNg$oIiVEn~f_^$SHKl z0VZ6kbY$wprlTA+%|S^5qYdQUk2|S`+T8|vU{F}dM>wmS%g$+_L%}yeaq9QgkVFKb zupG4cv(T*k)MM{+k^Ro6g0=k0x$(5qzz95XHMPh?jd`% zX{9Z+ZB-P2QR#QqJuLSJFretd6yh(f8$yQ^0*W;-i;zv|#ga<403Avujc>=thbJRe zIg+ncN+&yA<*!1kiCl%9wVIn^M>JAL7m&-qXwn$hlEFKBFKWW-s zWy;?WngEDBiz;HCN++lzaK!AcuBp0eV>Hc^6DYKwif)J9Q zw1sYlY%go@Iiu2Z>BZ>qw$UAEy_?vAQJ0%-9@&9F2P+w&qq;hFspy;Vw?V`UzDAZn z7t%0<{%ocEa4CKm|;=L1R z^g~C*zstd8`T+~AV~SiVrg!)cMTjgKU{3Qm}mK>ZYY* zQ5;kA&FtbddB?SL!Xk4dQWP(ChO5n%hdM zk3b0Mvmsd-@mer=axIx%Uw7bt;$ildbKD6k37Ax0jXoWGI1l_IzkV+ksSJTx20P;6 zIj;R>n}NJ?7`RDE39DRm6m?s(k_zOO-{>5p-emQH)JY#+_!FhxAddNcz;|CK7RhHq z^ziNjMYTVVqSAPxz8B_hh8zS9f>Hpw+Y8IfgBpX3duLFDpk(OJi-s4p41p(W(&LvxY`Z~`L zqeB2Hb=u}tQaXUvUv9?aJ*9kp!m#zOhP87vkHIhEv#b|bQ+?+4J}Rj2p0Cc125?(bptU4t?vuA(fi zwC&Vi@KQ%Dvr*fLD{kEJL5|NUASiNl;`BX*E1ms{{REQ8om>DkY>PCk(d8OOH~JLi zBDX=LYR9<(feLS@Pob$Kqermlf8OHwlXps50dfm~9JR$!q_DW*6_HIMkri5C1FDvJeUx{$OM{z@`gY=W;j=U}HgNT>5n? zkkL(_#CfG0x>D(2T5HHheW<{re>AieI#nVd-a=DV9qA4pZyy>@}^MBLX-Un?b-;VHJXO5Yn=KUtoO}d>blpD!B{JP$26XW0Nx0+kKUG=aWV?9{cnTv zao_LB@3)Ts*Y`zjBsU z4cwx5rWVa}=G+SJnCP9&SNTS{^?l21NA-Z;jF1;jFSY1<5ZyzK9W2Bhw^IiM7D^}q zLbO=Wh6ZV(x3jdLxHi{B$zNNvAgA;$Uh74PQw`qI#!v1;$Z_Sgl>#uJPhCPqOcLh| z#!Qwi%5`200utBoOeA|_1EF8FQBOr8M5a?{Z3K%`@66hS!Ys#!568wN5~$mf*js`?ECx~M_0v)R1S}1hyLJ4o3&8q@yNj}K^H2Vg2NY^Bo-p&4zqfoC z;vFya{_4L%Hj(jaL`OKYX}53{punGLceL6XXYv$R%eL<$NN|cSG7~Vw zQypzMzCTzXG~-O2+HL6QGUmf9y*Z#z4{79oTmO~l@|jyC$|a{e zFr%FkW%D{~GX2>U-wxnkyy^x){-0F!0JEKTr8cL`!)5koad)D3ElYTdttz$jf#@fhBV6$X~3!NzmKWz zQfEf9eoqOcSB}Y&P{TpL^qQlah@lU8Lmn z`u)(Gjr#e|GVYK2cp`X8`&S<1zu+RqoGGDjAROXRqF)SQ_#EGJFev)BVXQB4%zd$7 zL5DCpUvUMTW&a#8-4*T_I%e}6CRwo?R#jj1)Gly)%%lq*N|$2P(rN$h2%0q>ZU1`r zpr4HFnV+M9Tit#jT(&R!WdVcELex8Kf)h@ZoMu*QxX&({t*P1#Wg&ufLUPMn5V6@F`MW1d5$9Y>M9p(V$n zAY%al+gWa8CSY%L3cB_!0ALegEz!{A)ep{aRGwL5wydp7)@C%tYk>NiStM`%b&QId z0{>+=vVXdzRRLcG^d53tJd3#X_fe$KwV`crR*}%cQsNZ06>cHiDqpK~kyo;~{)bk5 z8M0r1MV)W!x+m!K2ZW@r9sYN1xC>|Xa%SHJt&SbyT_N0(`8C_HSs(E5$Q=Ch4>~@U zdxy)#Yc}1Gub31kB}SeXH=WQ+zL#z}tdWM#@$vM5&j$i?+o1KCMR0HeVMx!;t5Gfl zELXtQn1AevCz(pc6LYG<1~d-kGUU*k27`>HnK+#r$bc5WV}^l$zrBxHz0_=`g6w?7 zd8N`Kt6%u+W?Q+@46s{aiHTEQM7r#Lfl|keVP5b3$5#06g%>j0Tx$+cd;@1Wc4jCQ zQUtH>y?JTuJ9`}@4z6T>19QN_1o@NzS0asAUKsBCt3(jDAHFAQ_sH-2(k55QAe^kb z2VY*<{q|1VJrPss#jD-F>#hxhpvBKhOTIB;`t}z8&1?b6aK3u}jTegl2bA>{kEL7T zSeH3EnpRsi87_9zHZsa8RM#V44fVlf$L5mXSxQw_KEf+^QmncW-B;o7tPZKfMj;J} zkwcib_fUnczAd2Ur;`59w`6ozCZ{DRICjmb8DfB1JfpwODeeR^c9-JrZ1ypc+mTCr zHa;H{(jc#_(8_vVOUT!6-;NKaMrP1GVJq)Y|LY1kWE6BrZ!hps%2``aq7L&0y-<17 z)9VnlPNR+V@2uk!VN*kBEe{}cVJc5d|MvsVSa}du@Cw_Rz>guaL!j;B$?q@rw=_vV^6G@_fkM z+@e|KUv9h0D6qq_?GR{tf?$tjj;_2O)yRO&X%)Vz@)ZRjIbWJmKzrs4V~#>PBhzq* z4P+PsE@6Cu>mqRhTrvuJ`&T-srCv~izR>$6Y-qsk@-?I0XgKTPk?ygJ`VS8tpuhkx zk-MGgiJSOa!hu4(sjjR+VkFPbNhhtB)hMP&(>dba?$lAz)M$N5J}zpWo)*m?lBy_L@BY_ z4dM6aIBY@--p&6vW@8D;yNu|Hx`%`00UT=1c>uR8_}mV+0(0myzN} zkX)D>R?-~@CkA_IG^X6AtIA)1s&>+g+yn9oef`*~Pwi`)n4f^lErD0H$l)NVk}1J$ zRzYV-bQ%|0vyXQ8*#nc1hb?PK`L2QBP{8`B$djU0&9l&bnv7%a!}g_NtP8D>A*XY+8*{8S=jJW)8lk7yMDt{mOME{v#!WsO}?KLP= zsOBy*qimrM*>0CeC$2XsRiarB24WofEk8=+0B3;emx?@RL?typjEIr~MhEws>>@6( z3$deh41wOL9XFt9^uz?_iNS&uLHp* z8_ejiD(F-3y>_?aKw2n;8#5g-cHuVYO8MmGO)-73*=nXst9!C2#}+H~llNcp@lyr= z-khM(`G`fyfoX!a`U%k|RX>wT?@Y56R7jz-Nr^~kd2c!JW(98HpND{D9*g-FW;)G>1J_;4ZX}+cR1Mnxm1twK?Tt*u0&Y*-dKgBUEg1)g@3P`2lJ-qt6E)| zr5J4DSOYfd`}B~WuM2!t0eMsj^wRgdFo=1OH*!dDU1R(GdN3y&Aukm?22y_SKGwn+ zW}3;^XOLFipm=dNfn%9+HSo270@JTjo?n(u1akuE>fyv+G~|H7>L!timwhoC{XFqLNBnA#!WE!V#Jqs$){MfY+XFnJw9!1R6%c|!(t!|TTz;tpHq zAqBSp1C9NFrNG(UgP}{}sHTm#LfU#^h2J6{FsL>Vy3NYKt2!mqse#B86GkQ^(K`Kv zP-jU5vAVA4uKw>*b2b3g{-wt1Ag@tH>s5jD!f*qrI$tXv1KEvq z5};vTrlS80vs6Vr1$T-#&m+a7t*aYpjE9=AOe9GlOt+!*O(j_Q4)``iU48mzlA)=2 z3BUtR$8=}GpkZjB>-8LeczB%ZMRuseb^Mz%*@b{tsdW4B4wi;|bLG}DlDXp&C@bIz zRtb=-R+C6#y^fSj>!O-hPmh22953?|otMQ^J!77VGr$EKARVot?*-*~JwvA4U7> z8Xu|3{o2IA^nufV5#u(!Hg`WpiCO&b@2qso4i?Mu1VBF`9Y5Viyr<46v2ONpYkCRT zBbzfguNMENxgTJlvovG z7a?68y@RUNjY0=w7!d_8%Eytmlwi#;ouJq@3)K?5g9mf!p#iTZe2*xl-9r1SvticZ z@~9Hp$eLoI4deYHLhnzMHFc3ZO|;I=PgUS&4$=ga#@y>jZf9GeiY_DN-Qoqsc$Io}yZ>Ln=Sr zQMJPN8#rO0cf_v{51M@kN@dkJ>})sz`{6|M)aSikzprjYaGl}Y^kyl8?%TIWhlz+uS7(yI931*B*^W6oa zsrxVK6dw;G75@%de0~S?y2Y{u*~4|f&jzHfIk#yptib zosc(SgCX6Wf;oRd=k;?FWrF*_2ZC5#clX1-*p7~lP(2j=qD(dVadNDWSYK-~r_QY* z%B!?j&&a3Y9)|ceD}+5eq;Ys^^c3oP$fqwx|CKF*s@cZSJAoLnE0Qo6JudR>eO z4+86E?aiS^uKv4w=)WnPfMGnORAb?~sTGLlwj3GM17b6WC z!QL*`g&c#4rB3l*l+Wt-m)D|eAGWG^4nUMI4>4(QPEyG-Uc2v7W(;r|3rBCvc^Nqr zzTIWHSc~+{X*;)|vheg)U7EZ+36DsYFh zVwAw07jWP_BTPG>P1T^lum7 zDbET)LcwO2eO6{bo|Bv9CZi&CU^tr zGdVm7ypF4A6t?`Fx_(U?C1^-8zOQ_=IY~*SQ6n!W=-p=U-iY2!+2n(A zprU}6+AI++YxY~pj$O9Sc?cDUI#a$fZ`b`Jf6jxmGu`rrI2k?~9e+F=|@@mxA~ z#Coxd#onwMEcZ-U%vXICO0N9pcfwNo6cKpfHImxtj%RM}%b@528$3W0=^fmPlA8KM`wlmWD zcO&8ZtEgW53 zgMQWN!3y26@#AaJZql?g=V*bHrt(@_yGKL? zdXknP$aVm0lhoAWcweNt{lf1bQb-`qTNK0vdw5u%< z<9heoN>UHz4ZvzL6N0B<>R-mXmzt0@Sh0}0nUjGK0KjRC43Le5j#+J?jY32ZV_V2? z_+&@f`hHzT?@LVqx5PLy`GoRR$*M-jPhtYpXoeo!a$Tzas^)b0eR#`oiBsU$IZV)2lwvUaxEEj9Za&v9nW7^zAmsyQNHqn$RebeP&R$rq*^C z_Ii8Pg+VR5JtekmvXh(IYm3M})Cg^1J>s;Lnk4!?vOOc20(6z?TKm&EEnl7MwOE&w z)*b@fKtn3E*97){k6fOZ<-HFOxogL>lmYT}R=iD3ZLJi+^RI=XlR?})T0{Hqb0>?D z#erFu^5&P;ESJ^-m(~m}lZ}?vzy`;=A*K4@^IyaCa~}GUcgCFGR@A2gJl2IR9a#)% z=BSAy7U8D-0YggI3lZ7ZmE0HC;<*v&^oCnEpDAI@)Nes6<|7)qUz9p!A8%>af<;(N zTB%-t%xeRQ)FYPG90wQSw~+?5D%B|`eT)#)`FZSKU%Pq5S2Sn2ABOSg`F!D+F@#X9 z(&csqF>5&+HyecrHlJ0g)}`Vt1SN=Q^M~e$K@SIT{V{s2Wz)%l!Sd>R$XX*nUMW?~ zM$hs>qxK=qcz0~A6{jZYACH{IjVJes#7D_e&FjI?^Xb+bZj}l*V8YtFtf}l^)W>!b z`Q@H6#4H(xA8((%q{3@kGm|a2Fxvb!Y6YUlB{$;G%g&XUNDRlhvYZtF)z)g!A~xEHkI)$0!NN+x0_DkqjftEJAI zw?A``XVZDCR~&!;2!_5*I2uz<3aw;bdP%Y9e8U7@-8o?~vF0p<$%OqGUr?p|>4Dnr zT8FdW!xMSGrj3=gPb+Y!a5KDTb(nK#$8e>;{-ovs7X*-Nki7-Csd>RTdor8sm0nhy zQBKnOcdNDT!Y2Dx9$cqV4cT#09|or1EBokQJ`T&#)elESB```71EsV$RCx|o?a&PS zcwQS`>YPhD06u8jZGu|bG`1XxLj`CNEcf~fFgC?klddN8;S+04b(KFeEQBR{UqDtl z_&#ydsL2lOF5yHC@vnc?`SK-V?XqRylAK|1phmVYw;xA^r2lI}eA3DOKDp>_WlLkNJ!p}hNSu|3n70Zsie7;)-xi z6MaUC8A1JmeqgR;Tv- z1~=xG^YS}Ns)&=xlyqw`BTwIsK;87@Vgl)#mt0u`u=`$zYD7V7PV=raZpIn_DR#fU z$^ARpro4(eB@T7L!}73vfJCQ7S)SjL^^kDBwsywBi&;_QWf+acQ!OjwbZfAvlF!x- z&`KDvl?QN+oKmjV^YM)H2iV2X#ZxzhK8(jwMzE2hP7`V&bw4^t2X5G zSIjHvC-d^mZgy_9Y0j)nFsXjT<$CiQf!N*-oj`T5w?Jgqk1M}S^hVmlm>W@5!>;L2 zfD+O|EWm51<-$~6C~2|PznDvyx3G&h@!&rh02?_RxU>%1)ACcc?lZz_guld0#2;Z# zS()3a=c^X#vQ|FjYH;2x#=(%gzyFUYRo@x~_ReD-W11P(aswadB5)VD;RqYM-W>&W z69VXwqgJt9TLYZ)`YX6(A^>T`^n+~{{+D@5oAVc05a$Ei3N2LqaZsOA&;Yk5TM9w2 zb{xi1>dVP-Hst1sFE;8@5ilot1Wez@%~D8D7&8%#8`BUuAd`oX#X~+Z{6~6`8ip!+ za~~l%-wQ&>MD6zX53PzI&uHAgIA~VJAuhRZ00-Aw_~$kt@C5B@$c_iV9dJ%>hd>A_4B3!2v4VzNObg03 zfGU$McriPva3jX}It#YR3iwpxEr)?e0*zr*_+GRnjXwD#m)($4@5{HNC;x+b8eE2? z34AgLD!!-$r*c0?AsS3Ett|K{-7S%GC_**&=f^C0n3LjkfExS{&Ij9I(h)jUbgAu*0|IHPoX;}4^3cG{*C4sJ z(cWVFgcE`+dE~FZgs!9p z?@f;+8Q5)g|NBw`bZUTo&tDP-7~@#;)G2|pon}kVl#UAF%Koo$PnP_Vgl69i=j=S` zkUvNsGxl=FK<#n2Cp7P9$7<&NYMI_km!QE^f6)dihswLi^JyhxYe#*LPRw#wPe^@| zYV24CiiNMh0SaVe{DIOl!rWC_2&J>+D){JS--!a0Z+N>whWVob&) zIzvj+0w#9*M54(DdW`SsjRII;wl>phixASWb##Z#KM%zA5-HvoymPm48IrTr0RX`j z8KhUASFSMC*nyu<|HIY7%-jG%BXU8HWmbZ%)608bftvv+ch?J5AH*$Pohj|mInLDIz zxOaW}Xpza&*P)tI{yR9~5RPv`zcRdX%Mq9+HNj3>DDIi-$jMu+pcwKn!XG2&rcxO(+elKYIX*mD&J?% z^qDomDrB)B3zLrkfOmlqcE1R`m+L>c=;AyG-11BJK($j@(b5%XWf$uw=F z?J+a%GmGGRbdM$5QYG5X-W_;T8QOhd!$|*&$l~*JEsf<2OSSo`=F7y`9T~HGW|=8t z=L?Hcj92%`bC%3h@~EB2=aT?&d)rIH>$AANbzwOJx>Dnf++*XGYUuuI0Flv`W0R3X z^zHLrZO>Nv1l6*nmIxg*w%XeNH@h3ZS!43^Fmrh4hVz)sk4_j))1f;z)Za-*0eWn@ zN{!6g`J~pyNP#G*d*^?~+%#?s1l#sq z)lI;0e%}mW-Ec3ulkh)_Q@fAv99wQAS&;Oq*oK$08qbMGnoC)x;sD;xRUlXK|M%uc zpM~_IMvE0g**QN^>qy5J?qzltnZYMgSRNT4V)5;+N!ac zOcmJxKT5Xp_2XS0=q$jzNrJD?HQLsWgzzERw?w`-`t zo;hHQ-zmuVKq5zyW9NL({y4TcZjY_1;lBb~uTQ0#85KQ&8V3%|9J(RT8jTtq4Ier` z?6>)|_3GWw8|M3Z$mIog0T_yK^8JC)U@AQJ$l@<7`I_4U&fxS6& z<-XhB!e^o99Ti_6z%N<-9>cfk6eV!P zxLE+~*H8S5_Yu2}DAZcNn-|_`&Mnap-^Hq+bCo&swk2?nltbCWH*0H6gDy9LykRm5 zrMr3c@#A5o>L;bsV=6}~;*cJTqq_E$gmA?`Lf*pTE}=u$z`XeiKpvOHu}2}TuI1zuetvy7^u%KfafqG zN}kg}dW038L4NTVg?MRcOM!Q~Qi80BDj!eXn5{OKG?6+|LS1c!mqbxJnwRypcFxuq zbnbQu-VZrA3V8A|vIwbc0N`2RqfdJp%o$(pwg6Om=cT4k!~CjAF&SZ{Wca(7bbqe; z4V4~$^NH5cO>etl0M2NpjU~Xm;NJ6u(T!QnQVZFfV<*mM-TKm$qvc~N|YSC={)`K9Fc?x zvfzJt`a;E(46On+VSmnCV6mJ&dh2#{O9#vRD%$?vrDaNmqFNrOa)J{9(=dh;l0cd7A?K5^bHH4wm@GVEcgQ~duf&UG0wO;9E;1XW~tywLvZbxTrcQgScY3)E&)yEw7eXeB6$}Wb! zIPP*$Nd-bU0uq*SZULrbMn^0)k6(B?oox9yV53d>Kskx;VLZgH-kk4^IjXH;X*{l! z;Yu}`tGdSA{$;X{9F*#gnp8G~zdL6>X+z+aYb$G4z;HLvIpNz?70&EC5Ac1#cRrxn zNT~i!fuAeKRrfDvk(&syy0OTb$Ja|{T%Hnbrmiint5^0neul{3!{lm?#v>aH@VNhH z1CYq!XvLMz@W+E4+nBoi29T}dh0uZaZqV9C2MO0wui>>mFkEde-5P@PW!;}7eMI4J z<6-|T6f=8kky?&<8?@{ZkZ)CD_qn-kweybv^T@3hvG-za0vcZPVhlo0Z__2qa#Le< z1AU?V-jl%QHDfIjbvvI)3yjib5}DyPb4~WO>~$~U={r1-4n19K7a)-jq(4k4DJ#fW zo$?~sYdH|B`M^UtIpMq$sc#t;W&0W3iLHG-C6XSO|m9hRBO0okD-gnu@C?%ry!S$@4jCX~D?J0ls znYZyp!e(^*;KB;(x*G7aBSQa9{$sB9dbq?V-ma}fPVHx%aWxumW9b}7Mf!h#5Q;CV zd_0E*akaiVN;>caGKe!ha!b<|=l7HQ3Ba&UMs_NeCyW5^kd+Sq#c=&}G`CPRfJ;e z8dFZV>@wt8pOm=gIQiw`5y1ZQ8rGg#)_#^>?fqcAJL#$#BS+i(U%dFZ-;>*Wz0WL3 zKI7Yesu!wSd_1^cj@;Z5cn9N<>)~4t=hYq!e6GYoX;&08rU9Mjz7KQt6Eqq#AZj$r zhVkO6B3Nu=@q({Kxq|btU+#wwFqS7Gt%`diXtu@Bn@T}ZaL1aKFd>IH-K~DFAYMZf zi5-yN@8XUDjeIzVH~szR;m`^-l>4lL@^n`DN`qN9LvYx11Hz3w`LftM*ivdeOvXBv zcLSE;)`5(u&}q@vKELvPt9yawUa&38lfSj2{O1>=Lgw07C6VZD%2>QH*BIZ%Vw6~X zz2SQ(W{hV~jR;3su=nZZ&6={}gjWIAxc3Lw2SedEd%J;C-2hy89)^X()(E$4d|Egj zlnt9IVkY4rBi*W3IYAbx%YDdHS`nyi+x9PgTL2WE{9kMmQoB;+lwLT^bT>?2N(5c& zRW$TJUhz>aLc!%ZN5_Q0oYcvFxa83M&O~HmOc>2DQ;)t3=ta>btdhh#<=g~-`)MpL zQNxyAT{D%GjnZ!l4lWdeZ-v*GXuQQM$8OVrAm(yaXDC;;z~1_`&%_@LJK#A(G4}#! z>&>cChm?JFDQ6a2{v?dz@W~gn>xJjygT8OED}?2{eboLkSnBJDy0=0YxmL|j%xKGr!@|B!LEK(~pF|a{O@iz^0%fV^f zUw0qPS1b{wq5DaItSk%F4_p82HJV1l0Q9O10 zq_U0yEZ1_#RGKCU(aMik%dOuOh61=V3$?-Ik5_OPz1*sDvAP(76u#L)qkKg91P#+s zI9^099;6`lW?vf0NpMhWeE^tF6~^v+(Jxoy%W#LlGAS6@G;q)ykmk#Y@CXsMS5Hx5 zmd2ds)`4Z~xcs4d08Hs*f66EXK& zGD{Wy>J z`*mKI=To$6EqE{6)dlPU3#7~P zZ7XZX!Q3g~aM~Ve8O$DpTRed4;?G_PbYe&Q0>MX7c(I{G^&0IA6nA6Yf_MCW5u{jb zJrd$z>WMU{Ki%}k&ZZiRas{N z7e0`d>Ej=8rp4Pi3+Qu@#m+*Do!z6!zYEa1hX-b#({x@u$HP5&SlZUt!jr!)8U6Y2 zst&#{7Y+R9x!?KZYD#_9m`}YmC5=??zx55gb%8B=3Jc$T+kDJq4 zxYL6De%V+;dA|>Y)dWOaDl_qVj_|V^iUCy2(AB+#!|YzRjfigr#fTHi{c^Z#35o!U zDaO#h(Q{o9KeoUb$V(r<8BqyJVFY_SH_kxPixaRvA(U-r`6>^`;f0NWMv$+Mx!>4p z%heP)s{M8Tq?>j-8Qq&@OQN0tq$(@JfcMC9B|gfTme);NLl)CJ>BOc&xD_LMVbuaG z=XLVZRZ;k6S{zXa|)(G?B?kwUbO(XQ4!qs#x~oO{m|km{A7N2X__cEqdYS zegUI@+d~iQu=VvZ8z>WjS5s2~%CrWLP$7eEMUu zxY2tn-4y}XI#n^e>xZ(SKE~=|EFAVPc4gkVYM3mCAb&=RDq*i+TbH3ehJeZ&ZvUVn zoZBuT**UbtYX7l(r?^nhl(j7tHbeT@VFqKsfNCmPf-M2vaU|W^4isK+oW^z9^3eK&qm;h%ExdyFEXo z+9)u)?8Wn1)+@fa(3#mkv>XMOZ@CJ;-XEIYaw^4L#IJ7dYo>#GnJX^Tp-~^5H@L7` zUM=WZhBwvhGz`{!(A5uqyR9w^c8#FA0c_u2@-BrV%k6Br7FJE_3 z3Bf4LmE)Hn(NE2i=cJi!PQ_BOF)DJ53Fhm4d%u^1bqTE7~b*}&SYO1EvWq7Pjw##dX%K zpo?&~QgUEtGH4$clOE~fofLthO*jZDO2Avq6TpTmADwZB@!SYq(;ZRZ-IvL5ww{gwlsfiN zftor+L}kb-xq91=a9*O8%7fL1O-!7hmu`kbVRECAhs;|SaCcdKPX$?&af{~1x|iyn znaJt6BDvgi0kTjicGcEP>Yx!447Xw{s9(kdeqCWtpt3d!z4OVIv)W~V)!Ppt#j_C7J$>Poei@?g znw{Dxx(feq%Uq;bvkwkmFe9%+*X8^9x%LZDWLWg3!amFi`1Q7x`NF=MqW)g}dB}~z z-EsA&@VjPqaUn(-K*hHp02N-rw}^$Lm%wW9son^lJ8i}8%N=-9V#jeqIck`KpQ#dZ zgFXgVz7YBSjqoV;zy2;h>gkgG5^C>KZzS3`matv^&^|X-peL&@@mH$C_rU)UiYsS% zCLrSObEP#2@+QYJ+=W8rf^0Sf;aHF+RTY&(T=qprRBneIF>)WI+yNp(vjDklCCfj( zp@yLjOx?O_L)ew-dT(n))xoBDMemh*W2KTkti8pSYQVY9K!B|NE`VscC)u%aVMOI5 zYY8<9C>+CiobiM|p2LhT`{#VgaG@X;!;)o|9PcYyCh+}C`<9GE8@lm@;vH$Wg;FJI z$3{9?*1+^~aJ5{^dPhYhye7DX4*{-;A~6j-xwDQzqrZ?`A3(wAyk>f{fnpKh0?Q0? zsWk?VrxDU8xg7`2HmkPu^-asYx4*>ynVjabqa^j*e=EVN?vB+NH z-fF19bZE*iuqt|uTw;7o$PSH$cN+0l;qXd2wm1H$*NBY}L%l!lhXTaVsI(oT=J-W+aH!y zv8PC>Cr}d;>Nl4sj__OXhJRO*U4HO=I-PVj|6welBO~AfH?D9dz9<>&}YXfDL%vcDYqkUH}~Ie^txo_8}JO?=|-IlOOM8*(%$Lt%RPRr*0L8w zoZMsS@b#@mvBa&E-Iv$l!437q>8CvpB4leEyqDMR{5h^|};^oDf{?{}i z{ZT$)%W7Z>xyX=1VVyx2lCYXMoepR1?Lv$17;e}eT}7kKBsKeNbkK@F+`&^@zs-h% zw&fhKR2dl9)Vf9yB8ll67OK28nw;Y6`v+7n&@&vJl$x-=zjGwPnQV?C`;8n9!}b0) zHdvTjKIc=2N_W#bSq^s6mz4H1pGT!$p^arh?__MXD@A?LMP;)?E71M7-0Xx{RXi3f zjRYB=MLEDNf`N$Qx^#5Dpbd&xs#YqfLS#FV~q2p>(Mf6#` zIL9xVHJ4TrOmXJrYdCYYf^_{fRlx}a=H4gBZmsl#d$O+b-r^SdT`xpLVztuc#wFt6 zXg0I>NIWX{0TKXfdm<0WtYYXP_24d!B5vGCL6K-!A0BdUgE?R`szmQw7r0XI08{oY z%Ceb=5Cz`2b(jx%DW;69Xz2hwUNZ!it{o$mJKpe0@{Me2fca&``FPM<0m21-YO^w9 zUvmrdumiVmtc&7leB}~|h{o+s*=jvMiTcLzfOk`dx*BrA(JX?FlfkB9^E?1dtflBN z2p|nGc5kO__b2XfT0FlhpOTOsklThanx9cgut4s^w3%U$k4c~if5@Y1@4?%iJL5|v z#z7G# ze`ILq3;#ome8;2|T9%$ubB1uj_DT?JBNhHL@L%pQ;b$dhd=Rl=Q(wee>RW!L=Psg1 z^m2DH<;}~q3$*%EhqlXPGPj|WdU?4mLIl_Y;9l;`L(VnFpwI4a0NdQTXC|I zU=XnC+Zg^G7fZEcfuq21RZ>LJ!A_$vGk>PzS)Y0eC2L}tF>d@lRx-IA0 z364P3NkO5CDq88Ecir7_z@q#$Bw?*IeMc*OyD8u<4(ge{Cj_zBppYee5;J|W;@D>< z{{Gx%bm5HY@#44UA#MkK^-Z+F}K#n$wWVms%> zRgl^VhOA`eo_Vwa-PNS(?jx1(YT)h*9osy$uB?q=E+wPER<{0<10#mC8U2Hjr2KZ! zK*IM3iP%q7PBVlhykw~CxkHzEsdnl-j@^L&9Xg@QIXsVY!K87xAsAMb_^84 zYY$(LgD4F3;X~Ta3+iQkg6}%V3rprs2#O}NxluE|*j>JmT?F@5;bCr0$GBo@NEJJ+ z@MDyMi+cD&-;e(|k_j@f`P7d&8LMp_8~v+DYm%Ca>VS~kuF#oew=eA>$PcnWbYb1B zy6q^WLE?OI0F2eDDVA~6fLK_- zON8QhM0+mD{glf~H5g876gF>GgOJ3Q#-#l198|AxfUG(H=3)w}k7%I_6Jz#pU>kgx zn4+(DoK5-BfH@#viWWHxAijX3yY0MPU`cUs&WxoR99QWF#OU-Za+6A`+^7%Hk*m#s zb-W(6JM=~LqWKJGz{{v%@ZC201pjz!OvY?|edEpF8U-*(rQ3U+BNQfaS1fcz^W)In z6fY9IsK+0Yw6IsL#9T#PTo|+kuuum_b-l(PM4%&M7orZp=hoG3ullu+1NA2s3e6$! zuzo#J{GocZ?04|;EQD_N!Ek@;#J~mUg8cTUFHBJ# z_XZ-X&V3EgsgQm1#?APO1A6O6P#@)(wPJ@}x*n;w7-{WF!t`$MLB&w~72E{%o9Y+J z=K(>ZLme8;gZLR<%Hj}kfw=s*G ziSC+p#YVMcEo((Rt#nMc5c(q&b(LmFNu0c}KNNnc+20~dxwhP|P>aj%iI7BkY}5&q z006@uaK*AdENQjq&FoVqszcM+9#D8#{g~t7@46+kT#b5(EG$>f)|iZ_%RzfnOIg1W znX0LX-eq{!Z+=#Z;^#zl__>001&S;xcWjvRMXq;3>?2b8TgF*k-`J>{Y<~tl`Tcbv zmUQYBVA0Q?UNV=BzEwg0duifL1HQy-J*QQ42_tY@2p67zX>jyO^m%`k$aDByB0?A7 ze=lD`C#x<(}|^x){Yr=T?9w?gC!Lup&ASyeXt^6dxwQ zId=exxy17ORq9_nD(0$Iupq=F(~|CgNvj#q{~@08Ci7!`6Ox25w$h6gsHC`-@KG@mPH zHr}a%qAFHi93ktZ=N-lLu+Ry9fYLlg2@}oMS=sAF`ULEagTj4z5a9hSq#EHFz;U1c z>YDV9OfWsm2=W<2tXH2Zhxao;DvX85YR9Dmc29Tw;oNihc(*K^v_0hcxEp;3s0eTT zmEgF=?{DF>ys0UuX#qS8I?Npw8$J#O^iqd1?4#i7JSLDCNf|o+XF8tR5<2-odd_zea^MQ^yw(C--}4=uND%p5TRRzp*2wf z@u%6ZKT<)&wrG_$OxaU3p7UD%=(O#xTvo-t*vtKHD8OlN0DApS?FT^AK!oNBVeqx{tzyc(;2zrUHV)HIq;WB$c7M3C* zfNt_Y6s?aF^zDfT__)AXE-8`t0p=~;&$A~~U2pda|DjuaAslsSX;ww8q~K(PWYIrQ zp7k0sHt06U@*ouUHCaIu`Tcu{%$+n%k9pAhE-6Bc%PT{>RWT9Bt1t35OzsB&sHhGg zYbk*v>twhbfU6SNKzFAXh5uRb`D{*GwGdrFfZ)~f0ks#{zGS>6PIZ_Hoi@qe`nqKN zzZQ#=?39?uFkwtO{@9(Z^E=;M{0IBQ=9P@+aM3qoak1;2!FHA^Gr`k=r+^)P7DmXU z#uX7EQNF-oVfp}E_Vn!X$#se|Bm>CyU)zU@Wxg(>gE%wX?Obm?w%bB6`}dn<^hG?M zeRZj_*}rb}NrFg)9`!UQmlDNkQc}BiemiHjVG{h0^s2D5$n1YqJEVmF$duWBKpyaas9LKriQ>_ zoXfWW<#|+;KwfcyF23Bi8s-0dB5fX-A#@5`j+T+@cWg>{6C{@)UI}*BINw z9P$renv1-7+NWh#Oj#k|^uoH;Y@QCP`EzjT`NP6I8Ryi58$pc)G zH>N3oXky!}&xYuO|NJuv->V09F{dlLwwgOoa_cG*c7kt@m?KZD#yvmiI_%{rGxsJx zSN7Ry4`S|wkItzYTOS5!kzKhKgZ0Y%E3!HG1|QK~FP)*q00MS_T0nY6OHA^60NrAr z%2`{}Db-K#lvv$`TM0E|L|SEVD;MVroGxK_qQy+)pH0r{ey!&2IkaG(ecr=TOMvJe z?8+S7+Hd;Dar2jvPpjLNZ6RePgsy~w`vyU;kfvE?<6|v83y$Jcn*Y~n8=bl6A1ITw zUGv_*@9#Dq;EFv;jH(=SwmJC50ZCLjRlpfY5Z61EnLz)CWJ)fgII*S4-NrC zlia-5;*@l;x3c$xBaOr@hB7=>qLj~m$^)Zn0K(`)aL8R64V+zzQZv7HPqw>l$G{Y{ zy|bR6y6?krKF|F<8}2De9{ek~yqApV5Pb(lxvUMHYz6AAkEW)P-$CwU$B{4V!fL=D z3Ja1OXo*OGQs5q1QAUH-rpM>MDeDCV0slZq#wSEnBpvN5+UgB9M@s3CyL}JF|D<&MGS9OdwZJkcFTN{=~mv$UJ>xN-Vyt? zp07=t6M;u?R`Eud_?uXNzI*Fw1sUq;d6>?FO*)*v^@`0*)g|#z-HtaacH#+MD z?&|Ol@W2l?ONg5UWP+7bg0^_c)!`VOz7_dw0p?n=x6yzW6gRj~Vo%&24c^CZ*%Rn@ z^u)=ELGyqkw8Hw94LYqJRL2>gEhBRm`b@NEd=6wuZ*hL9>ImicoLq7ng+#>Q6VD!i zh;|OQ-5V*X*Y+^>hV&CR!&J?h#6pa*feP2$834s-F$vFniT}K-{{A`=>iTdo^q^M1 z;c999SYKQ48u`osoWn;``9yoU8&loRLK7R^Jdvl3%r$e z@R5dha&o?pj2T0S{6S65{8k~W-*+JD0zBd8`b;cJ!(1zi+zs){zu}BzJeW11u09qE}z1InqBlq{Pm= zxiDYtZ>kGyIJEFu+YMZ&K&<;uq;$^usP69F7WD`5^<51vqxztnPQ1gP5A&SaH*J6| zXym-IJc6Hacw>l7*uv9Sm5}o|Z|75Y60Lv!>MTxERrK9B98XC1qs#rFyH|Pc^ZuQ6 zX$k-*9q({H69NCBw+Wb^biPBE&$91^xQb(_Z_m6vEcQ3G_~yox#u8 zU)jk#z`XpHaA$mc>LRl0p);7NSI${X1%B2x@yg(HoeAQdwbhZA5)9?I73*|sP*FgOeXoev$cP?F`t%)t1dBq6S6SGVXuZ4XC^G!^Sp=; zyMiuN7C}tcjFdNGo2hjHdan^EZIV&FK4|(t(TwKhwi7A^o-PSpG3Z)#ssp2E_Bw(F z-Sy4yIg0t;CnE3#_n7)^NfD5rriWgDly39EKRBDDec;hM>tlI&E5Zj5(ins^vYx1x zS1@vhkOuocSS~~Vg>aGD9|deh1)zuQ71ul>;3gXn;f)Kk0^NtZZX*9aEQdU{efkns z`y-4Sx8}wf;VBhVU;r)Fqw^chPt!dvdp}Hj*h$A?Hw^YQwHL!eO(vcD(a5JA$>a0J zOGhi^w+Y4@w7w^>W4cD;AoWEa@crL+8XD;>;2acwLqoGxPDws4ForqL``4_5U#|b0 za39gE| z{9S5F39XQ3~{@iNGn{iOD2OibE1b9Udop{pC4hd)&e2S;uu>Ss(b6@QjJ|ryWqlxC_ zhGt(XwyK4}qdFjW64ax~-fu=u9(K# z5wW&Q#Cq;$3JT~sIfl2Ngd=i1%4~~qELYYR{#xHcYS+?agN6*=YuKIpKr=nMO0rPU zvq4p0>4t@0s2?MMmF5i-7NYGyPcmVU14&LfGfFoFw6YPX>Ne}K)=M`=py>t-#_jet z1iyiQOGVsk&;@vSw{o3VnC@c#aosw?72eV}6>dkDt`0J&F2D$g? z=P?Bl-0{jA;ij#M_tB1ey00|<7&d>K<*f2H{ORv5dMMWC{uf;U=Scr}L9n!Jxin+w zLXq5)0ZY){rR(PnmS^Ogax#b|jnTR}i9ums{%4|>KB zLCMt8@nVahXoR$0fv8)S!1)b~LT?qP%Cc2PDZ2LJ>0jgSH)n`Gx&4+$6#f%5K0Ng+ z`j#`FxZWFeKuGC~YmJx2u8H;IMk9s@#S%t=&jzisX7mJS2BO>_z6ZS!Oa{Egm&Y86 zQ3iB`YXzf~*u~R#VZ1?afC`H3w*_M8MwJ+qz>(W+Afewg3BWZ<=RT{83@G~{cY~4K zM@waHLpn2E?yWWPWI8u4z@G~rb4z%4TR&?z0?nB|t_2M=G-H0gg8FnKde`zUF4)zW z-KYTQzJ*`t2qN?ih6h4mVW1=wpcTvP%l;z=8XD%IIz15-a`m&cCkk+wC(P3?198Pn z1DmU*4^Zoz>)T#>m=WIS-3kCSL0yt}-|#nsRR0yp50sN(Y+Ms|S~ z0CG}U9>Ar1^s=-BwZ@RdQ?xkj@^p>a4xGU0sCRp{+I!%^H4_Qm#}oDZb>BQ1N=bHGg{Pi_Lbjo1?%=XK$z z(B+a=w>j|CA2Cd(e(amGdX9IAQ0f7wQ7wm{S1$hf<3gan)shL-KAa=>!ZAj`~e6G4_+voBW%uQBLPf?SG_~FqcM$hq2n&TOkxwkinO?!)w z5c^p@J}FCsn0`?MvJec@fc9zawNd{T;Our-EvMs-O1>8wsFB%Oxo7o-mKlv)F~X98 zXeT)Sj%N-FYrTo^8B$Y)P^h z8|*Gq8AbvQ?r@gJ>pv&x?l6LH!fFqq_Gg*LmTbr#G3^IAuz&?0a^9oEr(V+vXzd1X zUCK-9PicEAb#$Hr`oc~3nvwHP`0&%~qr~!;x(BTgU&&7oXKaX;5)J|8QVAddV9Sp2 zDL{WTVZx7(dn_SliT&uRMd9%l2?$4UE9T=r!!#8j>OzTG<^~Pbyb7I$?wjq$X5Cl& zO)NMgNnj(}Rs=SUhuW%Ta^^L6Gt*ePm!r!I;VBH2JY0M}th7GbK58^tGg^DCr%7!w zP%7Zoo)(@l;Si~4E<@;3tA#Wzl1-T1%|7_ZyAtnu$=VWPhHHEz2LTp=qiU-BON$PMrqWu7E$7e+@&jwR~|eEMr)!Yu^x}XNOZ4QoQqGt4^;E`e*%*W0M@8VOy!8sg8eMiG>jy zXNmL4DcQabBkseqF<{}N+L&mLj~x)PBN?xo2o}U`U(aLJ5hs-5bW;-yB~*oA%K$3R z^Xis<58=mvnw<2b;%&Z#%|H-c0`W(X)qMEF_KAk5&ll<` z!`8$n7awk#I-1^^wf|3nKoVY_9%AA+zEzoW?(>gej$aR;fd|ASENt?RYsdjMwCa@- z_qpSz73wZ`uGCX5G=AE0a@gkV#V+Uups(t8w+BMOEu?-k8{*8?TDCR))WBB!HoU-2 zzFlu|<(5W|9#=sdyjr0yC|OjAi*AFTIFxYWL@&{u1J4XOR5uf7So=Kbf7X8vqp*av;PLO|DL12-XV*1BJ-tb?wy zGj3wdmWRwg3B9ChAP9rV0Tub*qO63nmOe08k0y8;v;+O~!!`B#xRu|qPVS*y0n*N9 z&Z|>*mcZI}Mn7lY5^rG#xMdlI*&}CB&ni5dKzI^zGMZ5-8ETU&f#Q02CQ{-%my)S& zRl8{QU#-7PK(l4t?Pvurwx@eiu>y1fQVhVU4?DnHG#6XC%9|rW)=+{=b|#jTk(2aG z@s9L-@jYZqk{oh#K74@}Ck@-7uM>$my0URLwBVZ_Y3*{hL^_)$*(;UD+beuKLl;A1 za?1?JD^Ko1-{Y!=bqz-l;M)}JLO-!b<$JbeS>Np zv3$v{!N>ZXo^;JU(j1(R$fXx3QGEDOr~6|aX=iEY9{-V16Q*6fGIyJL(S1zi>AI$f ztXNbBv-flCWahs;<%;asm|U5O*ag+m*1K8bps`Bs2D5z+ zQvlr9c)0IdDkwen+=y4t)S^4Qa8U-%{}OXnyx7>nmdRQb2Sn!3&pCt4t#u!D?Uud0 zHW?l8(nZ4e5$-~Jr=xMZI8S+sly;8ohMUTNeD&8-1E%r3_pv?#Mo)a|E$2Q09doMu zxXU)gzt=N^2Z@{X=o_4SEVPcjG`lxwtar(Ypp)^_UB+ScD1r}f?$xoP-Pl^f&@LlA zwp)uH+bD@^b5!+qZptdw&J*)34$FDlD;PR{33waz8DgQ~o=n-w@v51^o>Yxy3sIeI zz|vAPn2C7nVy1Ju-_+&fh<<^cw#x>K0&k~#aVi#Qb)G_Llxcdv@2nwUmRXq&_}MU} zWJTv|!E{Y^LayHSqt1YRFVwb(H|^3oC~k#2f(q1vW{xK;JSS(D2W`qYU?H<}`TSB0 zSAIG3qU3-yv0!_-zI&AVW_sw4o&>eXLwq!3ej~hfT5Xs!(#~23XYH9x+y!)q6S2-T z9#P)qgg+qv9=@bpT`@QbgMn8NtYQ+wW-xj z;f&A^dR%TDxs<6)RVs&8{Mj6E8cT!u-Wzkr*Mow@V1dO?V#xH+#H@em*)R zq`B87P3pju))Vv9pXwJ}gVt)-kD?LK<^0zy@83A}Qn~%!N-8v#btffGa&2R}mO|k4 zFZV=Wot>V(o@a&S2_s|75Yzm1W{XT+)mpjlyGK!oAtdBN$VteMM=RgxlrS&k+lmRv zuzh~d;h1u$7$_hZn8J4y@UY)mn+cgOlY=RO$59*2YmU9wAd%8ZhRE*lV3DC|VDyRq z#@>-kEz#R7ZA;^f4fwW>fiZ#a-hLrDx-eXhJJ@9W?F0X`j#bk%=lOPfy8DYn z1NeOK1aUbJ>kW{ZiCRB1<<{lJbDY8cH`+u`Yoc4f2q!;?MUyh7+~S+;P&^+G>4b$lw<$snu;V?oZxdh0-&XKc91F>;Mj%zS^?a33_wp~~j1`ol z*{7AzTy4K5L;^LZEXJ>nOJ-SS2K@L#{buTvt^6X>!xWlrVycz7NeL~s_1pr-XP`Px zi_J1W%66-3DzlaoSOW^|aj~YJ`w#tZHgdxrkPr{Jq}qyglyT*ab3Kxy*(_ThhOfRF z9` znnYi7ZvSy1t7ojn6LOQ97QSWg;P0#5e&btoW4brfRBge*WZn)h(lr&MFUdnlRt=YN zukjtXkFI>Ry$p7P5gR5x%V-0c@n0x9$SvO#$;D5%#Ds-zyJQ~ zQxN{?u3HJWHX=8fMdJ4(*)So@x8XxK*N$R~Zv3FS*m|Qy?#aQm@eY8wU%-U|PnbPq zQ+R)N3h*}>9zh>UeL_m7`}mCpLqd52eOhkgZQ^ZR#hK!@Utd3kb`2o|yT0+gx~3{N zcO@Qu9DjAqzAM}!l!q|XL}tGG^oiI-PtfeDMyhl*BD&gPdjDFWnl!FL7p=+Q2B3R5 z9)T2nd%M80C_wKTLES{sg5k<@EBG@{4%yY498jIDGSim87B zerwb3P(hfo?1!)tXVfl{T0b$;%El)hruJJd%tNkjc}v^xb*U9}aAWIJhju>sgYwD& z(ox35f`jBOHWLKlC-OWl@=Yq+%RedH3CAw*QAG)5@^9+^&z>8qw78e0JG=$54EB8- z7H6V)Tet_`rG#74Schi}) z0}$%WKZVWgD$7aMZ(9Dht^|WD3QV&jxF}|SO`X-D{Lfu^{3zz{Y3`HN=={}}IDs(z z4p~d<{;s~kaT(X#(Q3JLAs!^TepY#Lb5=vUSrn(h{Bzt3si=WRao znhuk}zX7k!jLXTs(DOaJkU=T^@W&9|PWi{iWj zuWNFHE{kf;;2B0EoP1|Qk(C+a|DG?ZHjbZTkw%^!u(OcDrck6vS(H zKxdA)f+3nly(6+69zF#n@}N(k$64<=(k*QfLHiei#z?xyJe(~zw|B#Tu0YNp_mlYC zKQrEYk?8pG0Zr16Y=v@3>!MpNTY)p-exzI>d)X;wN41PiSg7 z&Lj5+%m4a0L4?q)N^)X}ujC(Ni4*dBVm~uT5@ zh(ceY_T|}WHUjN1WT53Z-Gq?vlOjn+D@G#-i!vDi>&Xu+4+fRP*ghb(5^MMwP?Yof zlM9;y^pCLQOB%+3Bget5%@qqmsTLQ|$38@~#=8yN@Dd)_GoG(8CI6w|9~ZfQ-|V01 zE&VaS-7E{28!V0VlN^i4AL@0Z4b{oKy(*LPI$LB&N}JB$pvVFz*huwq5>LpeQ|8)`VJH0rfOgZ+#(Z@%OvM8YIFB^E6K654=`}w!)=mv^EWg+htuOi%$l2hlk;q>+!N0W}xleXV`7rf2DtIz5}Ke5^AiuA!yi-ffuM;T}#V5qM4nWM?4{NFax73IR#xpuhACTdK&A1 z_G;sQ#n_kWr@x#^Ug(vdEZdDlH`|%Ptc>080Ry!(rqG2VC_P=Y$q5^a6h)Jx+|vN3 z3f-!JD$GNR9D-@@;k~Aaq#r4xK|A7kn}C8+>QPTynDzGcibCW_&DoACLBo*`6x1eZ zF+Bj3bk}4*=d}R5c^#^>_m$5&TN3pKDRK}g>}LfUf~H`W&9fT6eY^>E>2#G&-vH7X z+99w-`cA{YrLh5CEJ_UGcXB@D6==b~K1}mmnbjh0(qvD~U|E6S^XNQQ`Min1=i-Ij z{?q4XHKZe#=2{ZcV}$PtJ?u_GsTot250Af`L|%Eu$9j^stpfVZ%9Hq-gu6eII!j92 z7Ze*vsm;z+#fpE8&E=zrZe*&4Cj7MabXJPI^K}C{cyIIp?)#ik*sBTOjS4&L?F{oeSaODwL_IpdkqRX@uO&x$`;EsVtC^higTV7OW0J)^3 z21Y4u0fZwcPhzxQ`nIf4xMh;Kmye3lQ){q(SsQG9EOB-C6c=~RK2C4E+h-3g7=jy} zZ)#@h1t&6Co}h2rjP^uuHiR{`MAV%@dG+WFE&qD3e6mc?#2(yqi0dna)i7*Ec)n`N zIAfpne~b%X1^XERa6hbqgIQ*e?p9PGker2$e>y@`Ox@koG|orUg1+3Q8Mcfw&R;0T z55Yy%Y5zL-Itxo+Yh0r@*0%2@P_1F%!ZJ@@AfJ6ew)nw9GFe{tvPqxYH(q{yNqGAxMJOeySjf zq2He=mR#}$Z~$r%?#WHN>y|r<+kf?p88utL>R5SLG^4E|*i}JIkunf76Ns(-O^Yj) zpw*M72l1qD1K${o2l!Z(Z+NVaIZ>jj82lJeBG`)JCO`C=uhq)yU=wp8Bkrgg#-NIH?>F)#5 z*7iA)_*Pq+K*)I%279)VVyt&m`%!Uq6p2LFc$>UyhaM-&P*>wlqM@N-;@hf9)Adyu z=yL>(M&~6~oj@}HmX>rKy*(P1Dx9rHx1SNAzG#qBTwMNtv+e&j+uGXxZ?oh2lE{I| zC}a~dXS7&-H-twwbB+eoc{Lp&?@7$=_I&H1zC5a5N!B3y9P#qGWZE5W!ZGYOd&9PgmOnxDkJ{Udx4)W6~+GB6|6eNTs#0s}1ddDwCepRI(m6siPG{rUfeYhSBs5`H) z3Pu41ZvCfC;|`(!6&&cba*W-*4Dx9hqNVf)kHdrk&6D~gUu=9A_odInwg$DPjI?_D z*;q%I%FFZ$4ZamTd04M4D4MwQLxu+sAAEZCY4+!Yp^qc+K1YS)=eT>=LylkGZ|X7R z4pV+H{4!hZtHj=QO;Y&wHt+^dS;U;SzC07fJp4|h1x<<$G=wBYMd^0fW==C|DyL4!A(e_wmJXXk={t53N-mmBDdcLmfadiff__LYoxt#%Nl!g9Ub!xRXW}sNyz)5b+M;O!Ci$B57 zm8YAF$yEL3-Yt#~KDmcIH%)L?GR|3Tcr&|Q?Dk^W_hH+wFjGcXf&3Bn9s{C+BB z`wKs*bH%Vo=_TUN;$o|K;0%4BgBaNdmP8e;U>^^~WFQFpXtJ|n1R&HWuex8?DXx5I zygqY*vt4QFpx7x+p`$KrrG1xDgXNIZnc5ppFC`>ZzsH!eMKHWJ)>!t;P(ybYJXM@m z0S|Rldw*rDU%CHg9QXOpI`KmMHqbe(u|4%wzoZNpkYYlZ8lM_|!4ZYsL7A6^&;v+8&Y;8J4ON0HLg$6wt*2!1MW3=ygXV-Ae}YVSIC zJ?w%crEzHn_$p8=^PMrUKzS6;;MA7I7T3yW-b+j!kh+hy?d!9D|DJRAg%HpZh#d0+ zK>+&OQ;=6KzupI(c+;?Mo0xBC&sRt!$Jz~W-x^P51wZrwtOPb_A8sa zK^C+LmkU|9KNUZ2SfgS<@LX#r-0o+ec8!|$k@8t?+-=1%trBMo7ocT7_+W&Vh`QHs zE*+y$)=$Q?Y4OB$L0C5CYiVwoV|-Y0BHTL1KOwI4Wrl3jipaL1PS@XOfXt`m*17Vf_X@s%s=GY(B`fZxp0 z8*pHJ@{qM{QD|c*_3yU9kZ;sPdl%cwwgtkMm1j zYZfrHi(Z0H4~%ms90Hzu8B_1uZtnZ}jN32ME}P}b3|YqAvh&g1rEh*p)s2;9^|9eH636gL zq4pTbsN{H&iq3J*ztdwUWj#rKMh7)?#jd+S6`ItXkO$A|XuYc)kC94{l|EMRScdxF6) zjnmxhc=-lm_4V^p)8e>uFZR7Ytzv)iYls12J;{ zQwACtbL8!4$E_V$)nKH7dA?CN^&HTz`0C}^Hy>%T$|JH0SvBPMQf>3?JD`1|rLW)% zG0?bQ2X48(eXCe~$wP0+wGg&owK%`QOpqA4C9D+jo(7G@zuw3V@le5FWSQd+E=~*{ zme%Ic#7ZM=fM)~9ffO)N)Ks9X*1_ie$N+|o&%iv><*T#>X(GC$<8pNHLWyFDc{HSk z3{xX`m<~)y&!3I{&kw#Ya9`tr6PrhA(v=1KODbFi57{~m)RpO#Pix3r_?!0#3$GGr z$*1Cbd`zko*8G1L4ZavqlopZft$4Dpn;fYaVf~{0sVx($o5n|}kbFJ@X4XlvJ9cTi zBY-70gL+arJCZxoePE$)!>DaPh+zB9D%?@Wo`r;UcSDXT?AFFJ1%To}-z#dmm(b*{ zb`Pe81YQyVIPCk}c-)EV@;l0d;%d4_|YF8Zxf;hirxu;M|muI5n zv5zzt?Ah})fQA!OKWdkT5BU3`MeFSfmqL=Hx)AE26V-yPMLGZc>+X4Dy-$7p_*s== z1S&luair|}LE8F}TgnsZ@2~`1^@)zx3-6C32Y{)-q6Dv~>I1&W3a6zTNa%HjUl(O_ zCqNbuv-~P2ZfC>!R-k97#LKTn?9h&0QGFf2KN+QK&fn4fyC({%4MPn6&NEtGI)?^+pa; zD1F@Q4E6Vs;*eV=jeUs4FQs^5AOxFpV9VCA$TDyka<>)G&Bzt*-KTq|F)5dbvLZ5c zHOmX;r>t9vREPxG=Yc~^;{g2_J&DuqL|Yiu78AZZOa{uH`2uY0crbYX&jmhz1{6-C zkn>^Zv3Mk637mgXxLl9y94m7@2ff4Bu8<>^4qruv`S|8&lnnwRRWYYpJ^g>?kiAOS zm&aZ8Eo5up>*ZhkaeC|aF*ak|OFwqR`IyI`SL6pVL|JS(q~JE-HR0HM0l3lJ${ecX z)@VgIXp^lV1>4ZIv;W7N-b$4|b%g6IqvHS!Xw>vh-isc*@^A?E5d5kXAa40aQNL>*GPU|8c zND@D~34am=$K&&ErmrVh;0HzPOY6XeEeEqk?7VzY)w6~tblFr`>xohy^~-Y`cKr$^ z&_(=^@ROg#ya@pHG?N7*ej@L3(nPCmuz0nV+8*RHRn8Nrtm*_pw=m>&lrYhPu{2$) zWIyc%b}L2u9r_=utZrH9k$XMN_16wfZsBV{p>}oRlq}TM2>ROowS>qAS^m<}D*Go* z{r&cU9Z@!5B;-&j#U~c7-7yOoR_`O%KA66deNEMh!2?;p*MJ+_7}%{HfSBDeRMFge z>o>Y~@wU4z@1guyh~Q4>bq%fGE77nw3MKY*&_aY-k#T?-Y*9A20v`#E@CiRfB|Iv=VBE@bTltl zWpMVmE}<=AI$*adyZcooF#c220qrs3v`Y4sTOgz#`1$yqVDh_wF0@OFNL>%DEB6jV zU0yo%eg@vLoT#VDfUgd;(=jX#dt1SVW$HHbd+r64$%ciVH$%*Q4}N?G_y_L#k@ubz zr=WANfj6v?s^7`CTt>%gr}t&dk`vo2mid<!ssOZ#ixfnpS1kY!jiif!ljC*$ z-_`l-7TDN9>DU863%c{U>Fd-_ip6*50p%L!aU>Sd&pn&Tr>Uss&}}qQip3%M?Hz6O zjU+16OtL$jFlXUNOg9}I{HB0h=Dq_0K~0JYyXg?(U`dE%=fNJ^z>ogAw9oMypQjrr z@$)5)1^`aYYUBB!7vYc*#l30eFL>X=PSY*)heB}RA{ujwAM5G$by!G|Oic2_AbneQ z4+0~G!(htrJU*G>YPDcn6v-QtkMn&JO2=qjqH~;#T@X*t6f*v87Vnz@)|}szqZ5*- z$Mj29S-m}DfE6-D8vE4sVwn|FN+KMy`ULtlm(qN*lL0oI08w#-yzoT%gnUOh?vBQP zWDH9Y(goTafSK6(`vMcG!3)Ebg6)M&Ty4QOP@~ZqRStn>`ex)xM0@!(z+@`^|*`G<6+ngwYZe<1c!PI+7kkD47+9Frf z2Kd|s4L`(cQ`Snvo?{O4x8?aO-I?#pCBDezDGy*aLWf5|$Z+kPs?EX)q~;ptF#QJ*GYi#!ShVtybDGp`G*PMmzP1riNB(+7G` zpXCdbrxJ;qLG+D5usPYW^ImntRz5(DSPI_+<6tWT(WdDurBF&Z`s-4EH%JE|a<;%f z5H#7c??1&59KoAgC?xfC@oD3bGWx#;IqU>Jl*^8w50Z}WZ2U{2=i(3 zAR1B$d?ebphpSdCfpNxc&9Y z=ol5SE@a^vpT-%21LwhX2X*U#BGqyIDL(&a?vF3G&PPh1W>g{peRn&2wf_{HtL}4ea$9 zlR_CUVURsn5)T_DZ?Uj>Vo7>(~Sxhp@B>aM!$9eqy(N-Yj3Zr?VH9OHplkx3Mv z<@E%A)`6mUQi_yNv6;iw2Y7?R6_v1fy9EU@zE`(3czA@v_+uu?^%=? z{g?@8f1bvG&bREiRJ~IDYg;8+-jFj3&eqFTsKKd9t{l;y#GSvJgTBbfQQCMcLTUd2 z=z5soky^xqFe>|_T%f^URP;xgnlFNl(EI1BH027(r+qzHB3#+A22Z)C_GoWn4-2Dz zczP1Ae;mZpr>or}<8W{w(G4f?xhMYGNFYG_NhMeUc6kH;ZC+}QHD@V4z-w=;>`q$a zOjs(YZLk{aD@+{8=&fs$$tL{c?T`T1ntjNaw@3?KnCtx~H#MO1O+=pJPJ6#A1KMiH zlSVu+WWIPNNls_70XMWol#u~c|ql;Q_MW>fkFc`1cipFH@EOORlui5)IBTBJJOqG^CvG%{=T%ZuI^L+bO<$-HCE`mx>l0G|%5Fzn znZCZGkOW_mukXImNMGMUzZATv3i)_C02x8*Q$O*G9XHC~DncIsV6aizZM8ZzZDG)* z-1t@=)`;)u2znoM;w*QILkK$!+R>AIoVE zI8*h$)6ndy=k1ZPu*k=#$Il<15jerxbL=7n~8u<0p~)@cec@)t2M?jMjRoI2CoHai3aeEIIkx!Banr6^W9+Zk;d#Lt{0 z2iZlqUw`Lm?!^yNBZ_lv7QNwj(Uce$L&Z>j8WiOzh(MEx%H7A5kdu zgVcN8f@_`5KiXw&`XRqG4p~{;dAH2wW2x@6scU&>Y2tCyKOx9ru}OJX&x9{~=by@; zhxdG*m3Jg7A{|fhA^h|AgJDh8%ESGvL9Bk;3zH*3e&vrq+Vs&g{T2I~J>Jy~i$nUg zovl{hn9f1Exne7K7w8Sur+KUh?R*K}$0|Z+hmTbhsjeW#JYS%GBAhktL)%SG{4|fW zZJ<=p6mQ6@w~-h^&raA^uwvhQm608@i|SNU%=T)ox~rO0kl_XgtpZ>;dnP6& zczh}TQS);0#%5mKWPj=L_XZ(dl^+?+0x8mNhg%Ek)Pm=$JI;gR5%&3&)?^d>1j7}Z z+*3noLbV}b$a(J|QI67~_fp=PIB5ETHH@E<6M*VK4IdtN@Y!{`;-T%VdLblKt7MU$ z3~zKWb@o}ZUtF}8a;kQWTpv|X=+p6a(dZ*@P{DHUS^%Rj2^h8{4m2+flSi)?Oi2Ii zzlu^09gaNxIOLN{%QYVTGLK@${16tuR)Zj!i{Yf5VgzoK5DVA>l!5=k}Z1Q$mN>NEJ*T;0&Z>kWz#= zLjJEAg#$De4)wU2c}_{pBS51&aH@?Fp#Cf+%)ek@KLFf41QSi46lYQC5}!w~>~L^Z z;J-8T0zh_7-UEg*u>K>iWko46{YCaVl&^yhdGAA+Jlr+)O%ZNrS0vSO{9h4 ze1ImTU1LX39oocJ=ec+dX*ur8p_9`~7IsTC=+u&T}^3So0ecS4MS`#%%NfB?~=B+Z@~79x9aH zHe-LSAP9gUbG`{U4~@<%b#-p^^pHze2b`UV%Y!;eLcz66v4-E19M8 z9PtH}yKzfeN8VB|Q*6Ys?km*jZQSOIMR%x0HDq?G){*!UprPC_;!;`K&91?C#=FEakbnnb2V_jrE5@mdho0q#II1+9u}3lNeYVUnXKU&+k==ooh#_q# ztug&53VpN96GIKRPkkMmU$ra!otoA%tu4&<5wJBqiGMqOSW)d&l$emSWvK`_y5IlZT7K-yB47eSLh1lFTbR|tAUGJ= zZ-+W#SZAw1tCB5hhj!a9tIa1C{Q zChF-WO_-k& z+ch8aAmrISZRIseYxb@Z(t6qYua9SK?edx~M8+j~3+cgmq!ks^?hiJ_qxAG3Z$MkI zYIBt;Gj?x2n5`5T>&a8ma$TD^t8S*ekIuy2ly)2*%(`T6Dg)J4+I@&+j?Mk+gS(+B zp2ghz_{;ZTg9EoZ0QA7|>{t9TeuVzjTfmyo@o?|gmNHChwT~lkkav|4c8MQPKY>B& zz)lZ(W@pbI{g&fLzO}D)^2S-h7=jP;P)EfTbPe&Yix*uLlVwNzk6fit>u!HKb#aDO--W#c>Po01!>TRUiMogeb9t zUHYiE_IIFfjVAP`eOsf|ql?+bozm2B$km9?(Dbj;)|St9-6^QLL;umM+1889qkjh)kMQQ|$PDFGjH3oy zY0s3_69BHHzP9=9-!;~9Wkbn**F$;&GF=_x7rj{_^h^Qr)6de?+^BAAjmu8|3m(q7 z6MBGt=FgzkW`PLVYn_YleMKJy9*H9NV6=W?W0IOXIPX?`Yb>Cua`ifVySH}SPm#F8K_@wXxr5~u zHF}b3ti4a|99^9o)BUJ>VY6Os7Wp>;X<&{U}Ew>N09%#fmp_U_Qxw z4)65o-5Eof8N|XQ5PyC!V7(>4*OtGstb@+L;HCx6szzJ2E)qP#aeoyq=>Z>AYE+=$|DhbIu+QG?U?b3s3p58_6qis7g}lDM8QkueYh?bJ4_kw# zyJSLxiEqJt+RwpYYqn*Ojq}?r(G3Boky#l;X?HE?Ud9VmCD*v;$Y;A@@#x>7`NeEa zk)^uR;z%EN33j*uBnPmLI6`-)Fp9dbSA+=hCE!?2KxtRjPV?UK#slyN_9~!$Vvxnk=+w~S@BfLk#2H(nb>eU!Q0%O zCOm}my$RZtAZ6;Of^rEk;G;ybYNol3KngoQshY9#2FXA=9i{wEAtwV@O#u$Stm>7G z@+_dulB31vO13?@)5&$hXd`cJe@^MQNMaiP=b>GE4D5as>_Xb6`m{d>-V6))(0f2> zsoxB|cJfN9&lq$SBG?i0)s8L&t>q)hwz+Wn!h1jQ=SaXN^;eqN0?g8jeu=`RKV?_L_`_pyq<;2Uq3|V_`n`EAP%X@S8yT-!aPq*8 zT^>K_jW)fKvP86jdFy4pbG}lahK7qo&%OvtbMbqxQqpRSSFB-ydye`emA&(stq46) zz&q>XhD>yU4f@$ZrX*%9Gda(0^#_8|0*MN1PIB?`SPuKqIFUpT^Lhu&09^ccep5M|CeMJ5OHP39p8)@> zmowcTc~4WdA{B%Ar5pP<$R5ddYfh7{cO9y@m^PYiyG0s32?c6_`05UOWDFZUBD;_p~MA|6_r@^zY8db$--;}IYbzdFsiHMf+y-{$J1<_ zRF@71R$MQXmOzBhBoEoFfz(pvyxkf~Cg+6v^-Xh9RO8WSa<6UN^K_gFU z*)@=q0peWh(+qUkgZnr%bPdr_ar=#IEYa5WbN!*N6(lLG zo1}3HyKwHbIdRJkd;m<095{~NFF`BZ)N}@sh|@2Kmp@nD_stbH9!Vp!e|YFB^#8D1 zH`q$WiH-BQx*(9~@?NE16;Y2X9_gqK{#(k^$ErqD%qPCB40)W344qywxe|v$WqroM zJMoFE1>ISicivQDWcCe{ohIL5vziVO2fmqjr^EK{rrXupDRcQ?QF+x}r!)$j06wIF z!I8a1$D)!RqtBSBR;X-4?+M(R_ct^KXY4qLP4m%C7~)M5okJwHX(J(HX}sACrEAaD zkm1vOukDA17i^g~0K8zt+KqMFM5!45g>m+#V_ zI&)$*vmSV0`=GVt5Z7WSjlUy-jX=Vlw|&?cHvf{&-R@E;*8u7r01ohusSK#YNpkz0PAUaQ?~QMM zxMMnGL3|1-!h42VgPWkgJfolUk=6JymOSQG`16v77ECdzUmUvK?B+;075HnRA9w*b z@%1@o>u1SEe2QSZRYA+=Mbq2RE{M&rEm=SZt-Z9aLEMCc_^IPKPC`><6;c&SnryGoZk0BW*lp|M() zG1U-?M0fekPSyYH{Or};=5iIbC)wWQJay~e_qMSALJ6#I^F(q^D!2E^2b^8?o<~e` zT7k70obV(M_eF*b`04kpKzpQERSg{OxBoB3`2>1(G8ag;+NR#5G5n-8&~K(d*NOAt zl^NghOwP6`HI88Vz_bKn&-&EPDgzu=NIh`yGXSthaKK@|CU34|ArS1l)-PZG@Fhe+ z`gi=V-(MB(Ajlh^yrexg%^T&n7NVq~V;^O6z}Fz4^1F>LF$r{|h!AXd zCK$rJZ4{s_R(SREX91?cF>k+OwUSs-)BS(TKUorcWDrTcDaRrp5#Y^LoTNP0eS28v zs?q`7<2jlA`WKZ)0WRKywjdqR81K>WKWr8f=<4n^oa4L)hxSnD4>G!KiYg5){=%C- z)B|6&*?2ScfhoH~-Q!R^I z`bUG{e&oRU(;Um<`wI0e^Jqoh(7fD;Exo<<7T;HNoNlAVj0FvFF1jEOrGf5b8-*Dt zEf#Nqpi$ZQ93Q6qo1=6mc;xCfyXuQw)#&iwq##zy5e3W1z|GeJscCaXCYcs7X?bZT zY&o(Y(cAA*M=JjQL%~ndWN`IH8e!BPATxqH_Af2`t`jS$p7l-RAM&>PzPmSEm5r4+ z_-y2~w(l1tdUF@NRoOcYj}$8=mMQVd26i>8_mTdWcku*ne)2;_#x{-5;%VZ^hd6u znQ1b|_0>ADVLb>Xhw4zfI}@Fn8n^03AvyC3KPJExA)Rl!8Xu?#9p8itZ2mB?7L`$Z zkr8>Xp!Rsh&p7Yct)C`LA%d4JHeQwOFU2PQFyqOE2{TyUW8Uh^kIx}p7sCbH0=six zQeJv;gaOz2g~HD%mu;LJN8hMLxnuffy3AGCS6BOTN^m*pFT#VpUX6t$ZRHIasMY@s zdhy*dN_aO4rt4A~su|LGawPHo4gFs_SO3TQdY{J+0L|a~?E`phZ1@Tt>R$a?E=RMW^ z&HCI}T-s^bl;dmE4Pbr&q3;}djGhxzs{E6#y6ALI(Z}m+gOSncYfV$Y-qxfGmbrd^ zgP_-KjR=VXm_=m@(&9Tn%j#h-#nu9oX7nlTpVEoAfo&JZCAz8fe|S<&O!ZKi*Lf!x z0orslkE&a1Huz~M#$=lJ&BLj;*>V9E&~Mbi2C`B|fn!W@KRSI9iRw}X6z0SlBV#N+ zD<7imkA4t6w;yBN)(s!onSes--uv$0QY*wAA>Rp_`iky0za{$`6VjEf>AySTzsT+W zKj`b!v&}+?6xMc`%DzF=XucEh`h3ZF1d{Z|@^4>|O%BFW^^2!+4$`#^==NmGgCOLR z){6-I{c0NWV|wK%h|-(_1cT-`D`TQ4_rud2(IPUe04@Sf6UAlS<{=+B$;n1?kQ6w* z>HAGHv>iVP^OP7o-0K4?gc5+jtBnU7Onbcd>ISWOg*8$XC`kYhP@y92rVcp~#N&GG zDOB>M@01u*$0!idfgruoro;ePZumur-U;O!g8zQM|m@G)34xN6J|;_H2CLoxHh zAcLY!r198!9+(%=${U{gFGy`a{0-b|IGxp%tMUWduqlhIGt;E6K z%(J^ACiJyD0ucj={%E@X!e3R_iZZw#Tu!CPvgi32zP%^-GB$IH4Ef5VK$x3ecI#pf zz*Hj{khb_2Y*rKTeTsz}kw|=_&j>uuc#du-Ds&Nbh7LiB|3 z_G)F@$JOZyPN$*OES5U7plX9FU$*#B*eA{A>)uF}gXxGn8=e|XGSjy?cemQT^#Ns}HI0n0LZ8(t^>Z zML5&wR3Xxdk z=z4TpzxhU`5TWwR#hFLrzs1|WApomT-(Ujnm9K(yDcNy44(@Ywc4IHrlbhq~|GZ&U zW6X6l+zffy4VrU%Y_l0gDd)=Z<=3OHgOS5|&p2`va<2ciYV!#r47R*ocYOb`FYOWL z1Yjf9ELS}^HW&CboaWOX8xOn?r(I6myVyjWyrxOqbe}kR2{;Lyyx0aj7j>g!>{e4# zW6IG$Adm>;e+df*5|K)bgX8F12Y?Ki3Y?{5`r@)TTuzJ=P!xbbmM?tyE)aQT9?s_D zD5Ck;9-rUYtT2XaSOAYgW<%>aO}Mexz`~gpT54N9vpHFp$eNROYXD6CT41JSN0&~> zRX(ewU}mw$FUYu6ARR%0bhkA)UaGdhT2@;I0`yx7HeJ{`&_QO+@Q*_}ne>+r>;LF_<06BKgTZNEqlBGFEDHuHhm zSotmKvapuxio)&yB@g97rEVoHEn&7UPsa^+$-*c3_anEtB3sQPV+luX_9J5QHF9<| zNw?vGV4=!|DsFKQ1&)dq_gYw^_FQkA+Kk)NA}4y>??FuFYz=%1l$7UO8>@KGL_o{r%Ikg3J6qhQUIrpw=gweMMmRQ$K~#E&bko z`}X{psL6{=lqt3#rF2wcu=F%Y4qi%B1jr2tWWn zn;4>xef9!6blSd-@0TesLjeAk@gOqjJ{)%mN>!Wrf*O!$DV~-nYZG)67tDcx`NLD* z1ninm_FBmm5{IJcngI|i7nb`cGD_}<88{fLCdm+B#2NG*LHh12PWiBd8&v7tB{o@H zBWE)k#WCl+!LfO9_lxtl8191~Hq3p;QOtfQ0w+ep*4Q4Ped@4Wc)BP6*+T*X0Ofi@ zqi=lnK@S~gKPFZN@z&lbMuos&Qf@MCe$!})xU{c5^fY)=I$sVY2)ImPl@^cA{JC5N zvY^?(WPQjVJ`>xIho+3mk7idY<*M8+lT~;QK|j)@O9_=UDRd>wmkEUf9Rz*t2u&hv z5X$!rAW0EUo_%!1R`qD0?m>X^y z&j^stc5mxjWc5G0luM(@G_d(XQC`%`4Je+XaTxX}#Wm!q=^v2eM&626pf>{tEr4SlKKj3W?iTkcyoc!E`UoCf2_ouIhaK1+v6^ z+{z9r^AiYX@;%A$?g%C7u39V+_Mczi$FQ|E{UgxTnQn6=GlV{5h*au0YK; zYT`|O1!kQ;TD6F+uuiNk$cNuo^MUn8X`3fImCS2G?tD1SYxcYK%Cd?xZG^7&v(gJ9 zdG6GJ^Q1~ZG!MvJBRe*UFwx<$L)H5SlbOXxV!Qc3zotBNldFzK5$2SSD_=)rxm=C& z>AXddH*)7$kn#J9-hd+-zY-ss10-ST;!fq3r4OJC$AEUZ&%lYj;pt5DKKop3VJ_)x z_X;v&HNtJ-;827`0WVMg(lc6OFOrHg$R^N{w=k;0GTYL~jq=4kbhGU`<(uWwUzI&o z-g{x~$lvS#3Lf?tkjMl3K;TX z)C?jshXMdCupb*V?=Yub3_zUmM@3#N-7_8c%)Iux8Sl1cl1_E$^>fgHKML6Ds6*at zJE_|BO6ncq+id}TR>eb6!sp%!(Wx%}stQXP#X&kfA&UP6?4;fMmjuFBXoiQ3^)%yp z9Gtp8mxFlVu^n(uVovExltEZc-043chNTs2-Uh_5#Vs*$ZwLZvll{0d42#3O9>CZ7 z;CAc8wbEJ7*k@dK_O^5rcTh^A!06u4-n*iz0+%2kr>oN*`_jEyRG=&a-+9O`!nNiE zE>&SS>mgI?7+bw5n>`Mo`JmO`J%{ME0sciQ6BE5%n?oV@V|fA0%;e!~s8D~v_T<%H zXrWKuwrmWYhHX4GMcfKt?T6!NrcvQ2Mdd5G2M?<5Zbvrlr#nfFBX(9utXA2P(484L zy>RufruC1jKWt%`vfYU-=QyuO-VN5Hk-ACS3AaP>Ll9zC3#@IkNPb>OjxBqYtHH-D zWJR2oM9bm6w+~t(CKG#@<8Je6}6I2m}N1JJY>C~6yT;reQ`JqiDm`9I7>y+R(BMJO{=<_!n@ z3z-NN2l0sS^`KM1^hxL zIKGjxH{e^yC)Nh@p;Jekm1A=z6#0m3RWYc2zaOZKUH;P%Qw0QIKaM_Eq&gJD2Myp{ z6Pf3_SGb-AdtI*$KnQAn8LTrpq}X{Zu3?3K)YOp?KKibW3%3}(=+Kg3^*scYUJ!vG zxazE0>e^1Ow{rUvDNKdq;sITrV>hM>`7aBfXn~#l=z+*_t7^Qq#&_W%1ln)Ewxd}H ztS4(K6SGgtk@u~1^{u@$(IIL2opFkV)_kI_b=T2E@15sWt6z7HQ(f_v5I?wBZmf>j zd|hk1>!r;~z*TUvki|kvUx7id3AyXSL?zAV4kX{xK4}_4)y2EU?Cg?%d+mXgzrj%@ zp65y~jXl)cHYDuxKVWw5&ZmEJ5!O@4%h~i5odQU zWuQrQh8LA2FeKAkmx*+i>yQUnarCU5hUg5y%fIf?C%^n8>>HJ!U49x}RRM=tyrZQ1 z#9*U_o~5r=ZmOw-RHPPlhacJFz&66IhgZwiN+7+>%o)Y@`^*_WH8^kNSGZ=D?4zYEm?cuK<7QpV1F%8^qxid zfz+$M;&4JGJ5*d}kgIlOj1eYVebF#0Y~G6pGZ55@=qAdG=|2y85%TeR)(v&V#7Je) zzq||-c(vv%d&LLzPhlz48;MDIQIQwkNA^|tB!%G@OU6_L`gTiT%)Y9x9)}YLH;cMP z^|+ei#!0{+1go^Tc`eRWa^n$PMJF_3_XZ94Z!b7JcH|Et0}%VO;Q<$^bas#>FG20V zObJ?5e2qSO`=0Zgqz__QA@`F$=D&xcyap_2qW-*)cF<<-EJ$s9zTn4MJN;%+KE~FH zB2EO>+5{2HuuL0Fo-(os$F!@)%~J2TNG;J;lGWqpOsyYGU|o+oDj6qr>VnSW&g4M?6~OjBh4Ta`ls06lD-ZPMwe2?l z2!wGst-#T+{P^SOWan2}Vn9k*E|n7N#AFGLoM87dIosp^tAiXEy!3XlEfpM}$0EXq zh~B#+*s#X^bO9W>?I@BuHBjCqiRr{IFleM7UpB>I&aLdg4QiB)@&>u$*ErSTUR{kx z8sfTCW=pKW+2XZ<^M_;$HUYdq%fB{0O=-+*jw9rkQ z0kjwu5eG${eF8PSXK#l7*9v;8gO`?6tjg@~21KOuV!pUN+^L8Rd&9QT|27Xn9Y_?- z+o{?uaJQ944JuEE=o^rcfQBDq4wF&@e)Jg+=qecRx}aty+%fL|yjc2R5R2?CO_|zX zF)E^?-|GB=md+G-A+SbYe9fvMbEc4c`_y^#82wFr&w7usncZgTxk?*e%z78r2lHH= zCy^unI|z7~I&a;g&=D=}eu(Lqxq4J>6uEZ}ATxMOHeZk^doI+=(*?sn=IpQ*ZYLhxaao1dIMNX z#CcLjFB7}vrWeWJ0Q@e71)w1;q%sH#0P?BkSnCWDJduXixya4l*z)EtTiN-J~wrUY5hyI)J!FjGQ zKd|#%)JjiHrA&g88LnV|$dAH-(CTGefj+oj2)sNFGseni75YFf54slv=?lS6xJ!e| z%E(E%u5kr-9^JcMw!)Z?=aFvVtBKa$!Q1*O#S@RN6pBvEop+$ zkTYI^>^dhI5%(n8*Dyh#(h_W)AN2F#kaczRsC)YSo)|poB<+ew*-?M%Qa_jp2IL9G}Y+&Ku?*mN(BRp`)u9C=7+J|=7V4CilUT?RKwxy!ew z(1=K!DW~ku5BQ~Uk%N1@D{hBIGh~i@U8lm(WFvdqw}5o2p00Sf59EQJFuJ+Im)F}P zUkpYW28`H*YlIK=A+wq^aGzRBHH##=N@789sdU*&AFh7M;@0)ZBPW-H&1#kcZvh@? zu3GgMB0Vgn2J=bFRr{c|otmnebz0Zj_vdlIk)oF7N7#cU&0pr!@i574gSjtw^B=7= zzNSj}^9}rCz$p9ho>Fi5)XOo=H5$4aA{^l>sv?6NfBQpNMtqnltu4xHn5vY`lN|v{ z8zvMx90g!yAY#Ea)*%BT#v%_d$^9V+EUikJNn^w+Jw$#O&>v6$`$Qrl?R{3u&(qxk zCc}AmjrsIrVsy0U(79Y=x-xANj$LlA(^6C;28;(b6@$WJ!-%x3$4Q31SgF zP+rqOz0vObS(K=n!xoKYWgYJBxWc>11M?Hwqg&f$tR{W+g{Z?%u?%TtZVBc=b&QEU z0GMs!SOp5~VNnfKlQsokp`k(9A&1f7I>pBZqQi=ghJy}r5{WS-AboF9L3${-Dm7`E zpU{c4Q<`sBK|$sETsj73{e-Rktq8MbJ@6Kyfpud?C}Y8;&neR|SKu~({klyus)IT2 zTQzUG0ZBzKCR5Y9nZO2GuWLX%^Pc%bXoHVZw_498n%4(*p4vbCva4h*vz-bqN~bi- zmK0~keW2b;@Q(+k5j|4E(_`kMvia*L&2HIls4K%uNY;8d09X%F*J24LBTBQV~qN!wn!x${`4lWJ83tw|fOuCavy8zk=n z=jcaDQ0gv?fv-XI|AZhifX&*sZ|dEWRnrpUxH)~JPAPko^#~_c%-axcF%9Zgou=k9zgZap zt&4C#6RX1u^m^Ne0f@IF5Ley&(_P)-_!gnG{OHMwoQ%=kbD#D( z>BRvZ%w@?ox*qj{LhrF-2+j=F+`J@PaLnACv;4zYcgoHC#^XP1>N}7(@vD-p-E8f@ ze6`hYD6Y+`UFi#GJj_CO$JxCKOXD@JXYD5MVKOgeO@^#jhui2XArz|Y6-?vJK5xhJ z6u~*c{HWc4eaUeS$hx0`6YYEy{~N77`vJC3taaR(%&!nX8=-D@z0cxBaXBO56)h7u z`4vNlx$8513tG49gxwX|;hi^4EtZvSPkvkRBq!+SNiYK9lV1qAsAzv5kiF!|H>U4L6fEk$n~n%`iME zAHDKL1NMrjzz3T_oB!8+L>)$eTud`YGI}}}NC$TKjfU!CE)0oo-5D4F3whI}jiUnL zUGx9tD8Zwn&T5%`GdC$YA;0CcvlatjCJzrj9P&H0<`b_Wn-mC5`4Kp-I~S8oOdzT) zHnLYhSn7{Y#6E_;Rra_Dv*ZMuzj$(F zb61jUa*af(Xk(+zQixJ1_fQmFSBkmoPP!nM>GF+6O(`n1pWk2S@%TK>AD_S8=bZQZ z^?E&b7liO`86Lf)iP{7qpZRgk0wR`S55c(~>Z9x^XRCS3`H#<4D*K#wn3*b^p#i{B zZ!J>&4j7DCnCI7@6DJ0fO7X2b-Ld;Zkc!vFHje^97+`+9T=uUT_w4U)+!h?ikJgbL zd-);28equCq%r61*U;m>_)-2*#2>z|*>m3LlfgyVQK>KLR&xP0<~9uHZ;IR`2}7M9 z>55A7%l_wl$MH=TeHnEl3z)Q_Q-gy1?$k<^sSZh=vhK6901@1s;Oz?bTNR*WWOdh% zc1_o-*8(;;4pKXS91A3YUv6bU(iJV01qt|VsCxH`TAa;BK_X=>{^5|O1NYn1x^y%S z?qA=)piinE7?SSKwn+kj54VH=91nraZBo)dh7dt5sw;c{8Gy}~Wj7EdatK5=q^Gw? z-e@brCmYNJP~cH06$CR<^`Gs&;3>Tb(P3BkP5 zSfseB2+Z{HUMu+$;(v?j6CSC@)+32W9~X#8)vvpaSYG#wF6KH#%!>&kUf2BWd}<%v zCEZV__Z=0ba3Z}&1ky`+PP7eR9`L}pfIQ*vs$HC)<)^Wy6pyQMGM(UA>8>rAIw5`C z)8T*!tSqc_`n0P>8f}w9fh~nRREbcR`1q;Bg9xwZrT${6Ic3QkuB!ZMZ(*4 znTpfCPv==R@soJld%usWO4H$Tkm8Skb_by~(3(XA_0F-L07Z4I;i-xJ^gBajj64?K ztt9&t^u+6Oj&^&fM(xC7P#B1OJnC8v$PE5=jC1`&>?b+vJiyU?t zbm}P6ew>Hun=d+990n0&FBjZfHms`*|AJmW+w(zcRc$(+zaN2ad|kq3dsyg}3S zXj$++?SG-(c(g5jHRQW~B`^IXVGLQQOOmhuZYQHd6~MXiorp;yn%E0}f~xZqwa7BiO*p5x(?i zxa)7u*f)>Y0@OJnlD3wchh*!`7Bs81oNpSyk4tEeOcV>OXo-+y;|#K=FLOA>3E?ePV`?2s7g(70qOK=a;0LX9`wp3<&;Gnjt|R4buN4=8QsX%~ZG zzf?e&Vxdo-=c{$gNGMEGiWBk1e*gQebS+pkTRZ;GsaQCs!?MdVguRJ|?>`%?68*q) zkD9M*BliIK-~CVfQ7v4q1!}WwucnGUW?D zwCPzIjPGS02eH6`mgZ-B6c+s;Zy^ChF}B1=0EL4SrLmxI3DjLX8^P2QQ z<&<>|mUL9G)nU-*yYWm&qSBh`&BdS_>DD99A$7ps0Bhi`(A#_&<#MDPj-dPo92gSP z75V+J%ckq4N+qx8mEII$qB`by{;Su0%W^|TW3){Q(l^Lti!HH*)59T83& z(~yw?nA1$R@;Cbnml=YhWbPv5-ms($Zgh&ZNIDYUL>glsn-|O0)<74~Z|a0-U%T;V zeWrp}0wE4>*BS@I`}gq7qEWj9D&|E!m82q0*6!d_G00PJt#ZQKEdvv)2j(TGB@Z2Pt(%z;ElPxFriHvuf=nJRp52Sz`tmHv3qlJzqS@5k5u2ThVS-WX;}z=>g) zTTJ{miEm`CfccC&%n+z7aiTU*;#aQcAp7)y2GA-q4qzvHV8Q-E)O&WT1*CleAdE_S z=&aI^Z}_vn@6sK3#!(7V`*`c}j zH7xi`w+#{Px_NgJMCU3V-)F(>{uyoPKS+ZF;|Nl9gL|Puh*0K!W^=U0V@Yvao8jr1 zyWXgw-6m*jd5k*za?73C$iq(B0a?g;dgm(PU0buNL2B0eJvlsT^`T3D_8HXG=)EWK zyBB1AH4el`)IMMijPt~$syv!t_-#MbGIRUKv;MT>H&<`wM1FvuA^iQ)+V`iyy?A7Vc+n|+RXORVS$_jqJ5 z)v?^1!F=HdayqHVte-jVSYJf@2s!4YxN6NOHV6M6UAT z)Ua;w)viT72DWjn@j~JcI{-A0eX)H8SNx?bp$e7I z41JY}Sn&EX{mDSKXit_EPckI;wOyv(G*eClK+IaKhw}v(*OaT}76qt?^ACDPdgWH@PgtXN>ut{4BLkj(!Hf2bR-z(TRX5+M88quZkR?Pt zu=FbjqEwy&<*-;Vs0#5mp88iMKkB5y^@6dDS(t_-xmDr?4w|Kf>}Vmal+k^%#GmGl~UJcI=V?#Gdh2UM9GA=xj- zeQGeE+M;}wT8)>-ZTI>-7~u^ry_AE)Z)Qy$IVS5o!U@NeCrWDrM+KMdz=z-NBP{X~7RQTW7%|&rXg2G7{T0 z0;k5^(K#<)?(lgTNRiYmq}<#YIkm@`r@Hxqh!m84+V&9U$>joWKjM%y5h+NFwCxdT zREwe?Ve6ZlbaF8nPN{gUe4VZCd=OZ*_g-xX{q&he$Kal8CF4AZY1q6&v42X`&PnV1 z2%Qh19Lh+Hof0L-I#@5*3ZiR`!C8f<@NnU&x{%0xpAS!qPTQ*1@=m^E1Kh1q*Res{ z1KnCs)c|){7eNW$yCAwGu=9cQ^2f@CLj|x6D@_C|&(xdz+cWlPyYi~5W@^n0H4DKT zwz(oDmvP9)_4UGx@F|s^`UvDUNqagn;!$M_#()$FtZ^NrXd*#YMWxM0$QST~@H40z zaSbnC2>PmD=xNY*A7=RL!QDgOzA7?%Iq`KBz_3{qpls&b0m$?8FZYeGYPIKG^AgB+ zODJ;nYA2C$ulERLde*jSq5dUCe0bPbO%~pf0f&YW)EP)VeS;_1X0D%-c97dAR<~5+ zvo&#rN{ z!B`?j;OfnrQ9Xg&c?J9F{fXNljB6M!Z!@PRzpLgA1?7-81seDPU=WUM^`=_?T>Uu? z;$)imV2IYvl^?C6ZhS5FIMi&))37S&dqnBmeFL$ZsA?G!u5m@Rbatzrya)S8I7T`a zP+51A#LznjXuuh+xt0HLpSy!^gqTe1-y?u=^pG0s59W>rLRZL?WTK5yGLnLz9KU^2xjD7Z6v((%w zX;ZRiZ>whyPh|!#I?fXsz|hvIA!AO~Sx21cWc@JYS%ql+7jiOcl(urd(?3Vb*%yEy zHC%mnDkL-I&>)Z;r(cTAMxi3lJTW4~Mmr#ml`uMX#%l(`|9a!$(kyt>Aji_m%d{Qh zINlFQxM!J@>Q>UsC7}s8&bH5}ziV>{?Xbx1!sZ(HGufI>e&Ml(_ENx?7q30rI@u9I zVbuj{!1?00yf_seN`eiBTyo!bi4zIBek&aZ{!CM6wC9H9c-4e zygG+;wk~?CIu0pT(2V%*W(%^tmarZC5Hr5FnW}HVk+F&S^>>@xMXCra@-OHyzmUX^MTvKnJ(R`6lzqS*o0S}bgNWJbr_0PW(HlLd9Mw3#_@Q{+aGHVN(6#6^$ z-B^y*j^^O`&8p!1wSfQB^yt}BokGS5ED`#;By9C#pAfD8fpvW!O&z?qXA58=asQx) z$!ZG?o{%#dYS45K*Gudr4};5yy~KyROtkM4xoBsiS%AgpME#PHcUC! z>IvSxs+l~6+6#Rk4|AZ=^7>%M1i;y^pH(?HK1^Tcm3CdEjuP~gM2Kw}xS*<$~Zx>=5^ zkg9F`p&njP`T0ajQqI|iEoQ2Zsqax8>eil=qV8&Ent1{aHDDL3q70~3j17lH{#{`} zSVbF_ve)^c?6s+p$`ztAz1vApwFuiiJSUN+vPfYg>-U0)ooH!T9xr9mCC+>_P~t36 z%ix>F_1nRZ+)10XgXgs^rbRPNf@MHfO$nRita-6g+m*bIy{K(s+79k3`nbQQ*F83ffB0cv-i@14v#+Gvuy#K(w@nutr4Y6m;xPKh zoqW=JA(esb(h_gNp-KsJx&Sp*xwREUky^W__c;_iM7_lY0Aq|vMn57l2ck-++s&(j z3bi|M$}(O;^;l0RuJ%pZ^u^1V1Q9+fv`eZNztBfuhvvLY>O=YqF6z!>JXyL z6O9Xeh^JQ8Qo+JumIUZjq7;&sDYJM| z>8L#i4Dbgjemj_G!co z*6Zc35VHpAhz4PI^m**U0{;15C>Hqnn(%V%7HiON$2De-selXI1=1S!P~bshwx>BX z@}3yhCiTa9eigLu#=R7SS|>X2B2xlvVU)b|n&DG0(mS|MIFGkF#k%W(8rORwE_l9E zfjkjEOZS>D1YwkvpSDwW8Z{Q=TV0(ckzb#czTXG9w(~ySY$Dq&pi`tcd z7FSBxC+4j;0W30UmJ);aiR`iJk>B0-(QRx++4_AirO0Q^iR&31qvlHW0v*(h_olWt za`ok9aVXmG!#-}s_y`V!tNx&`eG4}N2gophd9x@)9%Oh4kF)7lwL1K)c0=MgttG+z zMuio0>rX>QX@hFv!HS{H>~Ack4Md%86nRq+*iFK+kd8e~)Kn{(%ZwY4YD-`{SyF#^ zO0b&reM|^fPFlUK1@MBoMUj3D@&4ruInXm~pvKHE$cBs^J3yNWe&U0~a#@>vab@^T zwu9G=Pb*!y9BzIWdRz`g@&-E3!2*#InvmCO8UNB8JblZ|)o6bCPFZ@}D8%s}vv*!E z>OmdrId@#hN_1mNFV|ooxY>FWgv09xE&!jU(Wpy6Jt4v-st z_mpTQktEf0@JaGj9Jyy6CQag=jM*_It$w5JY!xA=q*qP8swskgV{I(ts})s%q>T?+ zC@@I?+nDflKPI#t0mNdEe}8N1O44oJLvnavF-#xMdAVDfPw$2Eip|^Li~;!o+gVAHAj+A3J0!h@h|at5xa@n{(Tb(fi*>?0|O~ zT!&n%c$k=>>VUvyU|R&sjl(5ybXvt;6QMlF7KrFL0MMgi&W10((Yyu7L8TH8Vv`wX z+!Fc(5$$>ahw@xiE8QPH{44#P_7RhQoTzeqnP;hYsb(OLHi%R;~ZOkI`x~&CeAOQhs(GEKdc@J`fP3zPGLMEk708h?e7IZvD}O`;eVLBIX2dER*;H zmNHwU<10K26XL7HO3*N_Yjy>DeV*pP1qw-?Aa_Xe-CJzqtQcbz&o_KGN;A7BKr20E zag3Aa*3@#}!CIH8mX%mDGJ-rf_=|GqOTRK1oSu|xq-^NtA;ky)XR`5;)3T8~y{zfC z+;Lh3+&{XSOT2H6 z*p)oj%(#1G68SD54o)VUnP>x`034|Gqd~WUXp;o^msFkccHC{YCrq&!o9&P>-;0e* zMJ>aaxs{J4A;VB}(!CKY!f?uzZkBp0(DW8kpn}o$-FNN%VRe!fh^Z2s!0WT*MXc~? zL$JZTl`FI?#OYpub@Fb`8+#T#(&=5#m9jtgYK;1c8odSkv{fJnO`q*mbHNZZBB+pD z8=}K_KM!NU=(ay~z7%?&0Vamh!z(q5-*gsySPx}qXV_-{ zi_iOK2*}zV_7dS{Z-`X9^2q4F>xW10A$jC|0DWB~=-3wyYt}c6>LIq{(@eh(Thv?x z@+N0jQJ+Npphd1&Ic-9**b^@ERmbY!K5kD9d78#|CMa;vucd)`~!O513JQZ`AJviDiU#=ahHeO;6^Ka0>n9 z?Sm?OY^Ej&UT`oea--=W)1p_N_v|7=#=$iiOd<=F+e*(_0b|0RM;JI7097?)3vdmC zlNscZt$Y~)e3J@qVyH_|AqRAL>_6F6GnpgnG2|VaJHN;I2l9Fr@R^|E72=+kJLHPs z(%F&Bylj2xmM7FazVBQ6X=F6;66np4r<-vBcxaHRUFN!FrEA0p^@&?v)}(x=#)@F; z-Gb7_UF#Uh4qm^}wBQGy74GQt%VSw}vvMVwHZ1%2V0iMgb_8EZlh72NM*P7zoqX znDJue^<3E-z#)p)as5}E;hV#*=d;RVlz||ZNavtlBi>`)gtm$)aYw%fEw?0Oeo^!M zkF`0Q+PTlOH}Uu7CCBM1$LIHh`}GuzrMn^TX2t*VAYT59;Eh z{cU5ZHQ2j7c=fj^6PEnDxIxo{)r>J|KPl{eE-n0xu ze+C`v_;`fp9l&(w$~3Lz#C5our@e8%2>b=>auuz2jUK-87(h6%DpvB4!>KH3*#N8L z6TCG(Z$DED6)au0Gue*>_EGOL!cQJVU`vfplgFBU7`nR>3c zzrDMA-F1swY^ zFU9C@b?%kwkD{x%yrC4{@6G>8k;hQWYrHiS7Co?gp>(q%5=gEvPRf+9YsPE{2xTQT)!KRlWTF8Y#a%1{^TF3d+4v2o6(r6#xjXn>2|vPx;(=w-W%U zcPPDTsJ$}#{l8;e;jZxHv28QEglL&&W3BHWt)hxS?M^AGwW5NC7)ZBR$*YxuguJqV z=x531=`vNy&|SVVd0sst8UQWff~P;84@Ckm7S z((jGZXH>|&+Ja9e|#4I_8g`ohAEZQe0cy&MHUdQc%e z@f_TIITkJqhBT16ub1zd>N~YchKCa2>!%xb{Uzt_$h)P91vXs24sfY>n`g=cCbGdpvhrSY(=BgVQjUT4ec9O{;O=`#qRw;l1=N$)jX71=p6nQ!^mortJBR>^bg+ zkhR47q_eY}tT2d7kVJ`&W<17?AjFC6>*m@*CFg zVZJAWO!FUB;~ITicvV-?Yg6Pi@U>UGZyR^tEp3+PRm_^1z6JY&tDp4&vMo)3(7Jrk zK4Z{iUW0_vbDshr>{i_DY<9TE=b&zxrmYTe@{|FcPQZbaUKG_8a;eo`eX{{N{46+g z?6NB3wkh9zRc{od`g&dj9QsXBn$f86=m-h((VJbjIT-umKn)oq1uKSr1B~}Vq*pcN zV|KxZp$Xm6gv}wgB&{4xY_2>(lB@D8H=i8qAwYDFAQObLeQsEUbFMXX2y)}^en`%g z^}FSsxq&UMqg&R=zWMJzUniI^IlRJ#=dc}0e501`p3G;I8!&l~iRz%llRo)SpgR?} z-NlD_43lqP3~9f?)4HBc!CGlo!v|!N32Q)p6!+2W0h(KT3|5{Nd`4^2#CTL-wYW6nDcW*JQo z=kt5*b(FUr01kFj;Jtk087JiFtl&4Yf0dSR0J%eODas279*Z4$?=^-YxGhHOk39lnik&u1{t9XgI5-l9=qv%#sk+>Z-udZ({l`8k--Pc>KfL=8vzE* z+~9tYc5F>Ll|ATmG-ANL`3Zh~XSyEi_y`0asl`Iwxe3 znSaDAJKLzO8gDph5zUSksxktOV@Z1KCUrpB0+| z9Ez(u0I1F0c$L-7OY-o7&Q}`oGGS2^fU0egGDA&AGYE5I&ijX-u1}|DNx|8$Wakh2=cR1R4b!s>NY> z^|w{ybJvfoJ+BHNKJ3T1Gd11Mv1X3smA+uPUI7_`DAljS==YkN?Eb;!&IV?+|KKdA zEx*n|T|(Uc$|-^ru<9ajdJm4s(50^kO`CyErz;#a&!$@9?Sr7 z1)eg=e0!WLV;nF{SNtT9Kp>D&=XK34Sg>^I6qQNOW>$8w%5u1Er7d-Kb z`=(rky>!!`NKn{IRu-2T+H>%Puy*W; zS%z%YMvJ56Fp0IK(aVy3*fr7)xvUnYSh)9rx=sdGWw45@;r!!DQ%VjM@3az@UWF_D z*1oQly~lP-6uuhFxn*I9ywGcpX5I6JIV)v(bZGphl;)UcGl`%_KUn`xWTv25YY*D3 z3Gii8pc|Td+bKMCzShsUnA#3B?r(?bpG(6o1@(`cA7T*M}bchA8?8j{f0&{Q)^xT^IplyTwHUQe?2qYD|%dZ;&_Q?WIj8A%x-07WJX=b_uGfzFj zya+x3%su#1H>}Tteg8+6jK0@nz6g)0a9!eK-5J$mdHon53B{C$*E2J3Gc)v z^17lfucuX)s1R=)jHS$r4AK~vY}e#|mfbw%C`RAc-qup$)(h-$*GRat{x8eAV5O`J z8;A*AUU{X?Bg~%A9rwd;GBOsMM>{?_cwTwC4>f`;OCc;SN)A=a#KpnQrE6uV5XV4& z)jT~)_FBH-oml?e#4UC<4SJD}A4Nb~+_|I=3uLg%_6y%{eZg=T4@@hBifBH1&}Y3G z1XT2=q2*4nNnm-iQdAMhS*ElxO;t=WlgZp~*6_!tOoB$dH<2|{$h2LshD7$~Gku2n z;5=9t>$V&WePYnPFMX*;KP5uNr#~XU$7G*8qdx*|xYis~glB=2{ykD>ZPR*k0-{Z- z@bB-kMf8rB{uxhGj9$EaQo+Anr8oa1W*2Jc*&|*X*t2=%C?O@Z)Ie(DsURO^tyJ8< zsy%*$@J#x;xIpuLaRt;gvC!3Lv>KtDtY$%28+i^vkjlMyH0pds=N z8eiNvZDbp#8cDGlJ&(V;Uf`|~Tlnc%I|5FKJnf-l`&gOpGx$!mnyI3#jqmDrwYf0t zqa&~J$%fVscDRl)cQ!+(SJzXn%IkYrFBnfH`1g9~i#YbQBR#T2+&+65^-%O@6^hn~Nq}ms{R%Z= zMk{3E%S}LtMRt+9hJKyOzhM;9WN~J~9<7+Vpw5Rm{d7({$PrRA@i0?&f9j?sohbL3 z3BU>M>A9lOZ6TA)_$HS}D2X9Fe3r;bl|~(!HD_%iz=<=<=IN{3u;fx%zB?Z!mM=d- zf0y))575r0_5`{Gy1~*Pwa?<@QEtVGw@(y(gKP-~o_cN%W$L1&F9K1<+eU9Gci?x6 z6Cxju>I^H2eYQJg8PPM;{?7cOVa_i)-Q_Vjkoinws4~Ss1!l7DQ7C~V%=8IZd zw^AK@z6ZT+L9<6?k2WROkLnI5z9sl7{7i*UV6~@1{xq!6THqnbad)Nknpz4x^bhQs z%dCU8c}Wp*=An53z9Gs(&CGnuJ9mF%A6x+j^6>Cici4$}ItfV4F&v7ML@y~to@vtB z(_fFA+Brd6@pMNnrS9{y4|xm~0ac5qBj#f|jd@Dvi}Q>(huIgabSjw^$`*th_uU!; z9TZddX-0SWsfVfL7L=Tx)Ux9_Y4RCD+O4C7S7#sdhp2OFPKfp*uMJz4+`oqzajXRr z%N5$JLMHZPhHR8WaI1B{CxidA(-0!|@?x`p`FVBa?^_=6g?BCUWzFVmk1gJ!9Au{5 z+&dL8H8EtXFMTbR;|19F7Ek_}V4hb+kjlIkK%z{9XU5cW!wOi?%D^@i?t)EXv`~@a|O>cGzX<`LLE!wRGA_Xk`{!R-FTR8 z$i)Rs=Y+1e)2s>BgcVg(eQe|oO{m+AGUNZ&{LqHv>;hppIBQxS#xlR9Uc3?k^ z*Z|fA`12~s78q$@U2~s+Y+@Fzg52~Jm3DsQrCFE*LDMmhbQIupFWp8<)TtGphA*g& z(K=`leQKXxjh54?>X!UC3evl^9Cbg? z4ae)#leIGS&XQr7__&SCmh5bO**NlvoSYJ%V;Paff^F`M5r=t zqzDnl*FK5z(ucG6E|888C{V9R>0MVL{mOKUj8)*CtV01_U6sls_qA@GQTh!of3-MY znSSYNAA$U3+o8LJ{`*?O%EM|skf8a%uez6XM6?V|hc@DIL-_%|#_OWl*$ho@fPV73 z!a@xo#ZF#pYH%TRy(cXewdcukZz7*I5@QSr9jd%>sBZ_@_C_~IiIGT}hT?@Do^Ll3 z5H#!@@*)=v$DPAor2RmNwdlyNFqYI}$_G2O8_vf9<~*mPfRzS7=1<4$jR3h?_{98_ ztv>J64zdr)(e+03FZi5R@yQgoLSvM&*v~wU{>9T(!4uje-Fuo zd@FH;8L^(Ei0(a;#}HLU)l^BQ5!Raoz49dwWxmXR@MdUsGi6!)K^7^V@jNJU1SQY| ze|D&on0UEIo#TXeF-Y`oSlNtwHpTLqs%Dx5dO$_Gc_=%42&R5id&^VwF|$x@Zaq>{_l^!NvU?O} z6(8+LON{OBtl)k879GLo-)^U?MB<=w3>JDo*0?~}b})xZ=g084cWHC>2vE+?vBnrwUqgRKK36i zh41jq!(=5{;I=Y>4BTgoC&{@$VHx0R@uo81V*F!F0U)|A5~wX5>Cs7nvkx}CwzTSs zL`hF1J|t5V=Yc(9LVM!Rtx&QAcXc)ppv4l|^T79Kfv@X^&%D|^=q{DAedXv&p!%v_ z@8Uk#3H5ZmGF9^3ceJ$pq`bvAey-?jN0we+z7m8YZeq;eE|nQIZgpi^YPX^?t^WoW z39YR??H<{0^Cy#cKLOut3JJ=%yAv_f8Wgs3Gpi|#^UC8ER%z^dT&jhn*>cCWap_Z83bEoXO@ZGAEBURhwLBYE_4$6i{=%sA|w z0i2|KUh$l%$01nrgXAnc#F4c&7Tgx6ZT_eOGS0#euo4_yN6*Q@kXN`tTg?9dkJ4I1 z&|#~i1_E41qZRlKGcZY+E+-@E_7|R3te@O3$46dZ0E}eQ2aoPRJrX>V%lKUVGB(po zdTxYUG8#m+a<;8i{f9*xj$C?bKv6#74hcrEJ-<$>xKqvodV;pJ>2oY{@_cog2pfro zFdSK3{emVc!u9t(^ISOwlZT+1{k)pHrN=688;agNKfMd3VOw2#+|67Q8}y(v^92Ln z92mxP+li=2n<)sy@)&_yJO*;#fEQX2Ty1;oeGD}J;0IAbAKwi#`NbJRjQ+5)dWt4U$j|88%TIsOJzgL1E|QJB>%hFmhV3CW$XpuXyFT`sa#aZ>$ihHH?wuKlv^+z zl2$^k?ZV3C7F@O{>P(qAkssk7jkoT@$sufNIxj+WT%OE4%Ar12a)6N!txcW=dI?te zsae9XD@8k;9qrnVOdded+GPL^-=GF7x2_Lyn8HLXxU_~jcD#n4^wb7`XI+bGL6c*G z`qqMUuM9)F{Pi}W&2H8dcI43}$?tT%RX4xO!wvEtvk+eDz0l?@p9|f@iRh)uB`?cZjcZlSkw7an0Z_4F8rTwj#y?*R!yf&t4q@zDTM@Vq#^*N*ds&F+2Ps@_Z2 z{|)l_`wG9+#6j#yd65fgmx>Y3fsPOdsAAXflp7%V$Z%e-H&)1W{c!D(0GF}dI#pzz zu2(^#@9-AV9^bwEFG8SuVG2H2FoNvi;Ud z6zLO0K+DRkt%EbUDN9K^c*h+Us_&4z2hJbQcAhJ?QOfWZx^XK|I`lc^!uX-+l9BV4 z7MGCGO_KTe`FNi0=Q$_Odkv1~@9M0TMCh&CXTmw15rwZute-cSTHh8#IsX!?4^UD2 z!~uhw<^$%NAKV-bM#`{*EO#X)6SC>fii*cdSm_QQ+@;tJp*x2Nz8l+Z?T9UNCPyPtSI?YT_ z5`tk3%?iygwN=|4VPp_P!`Nh|=0owc{nfVkezJ_jlvoq(SNW_42g<0+Zc4SzN_)g` z=uZ`<-W}H;N>R~vGrvzL97_kNjXQR-8}S3qb3Y82DLpeP-pwbOuN=)vw%xyy?Xr~7 z2`C9Juk38s)asNXTU$R9I9X_~z@cn~=H#*zwzq8+` zRjtJXnBx{Yey54U(i+bQ2k7q@ze5QgKQb=UD#Pnp4i~;V2h|RTUOBvv(UAmLz2bM= zQ?BCA9IHN=R`aUnU{U8qA>tO`DEu07w$*L4*yqZ%GV`_LZ%yLO<1@7oowjYVJ5&)M z6k_+d)#qzx(uNAsn=+N-WgI``WYbvkoMHO@(7^(RB{C@N@$m5Q&ZxKq&ig>m`!k!B zmgSKLlq_O56R4qfxnFwN6W-w@OF7d^5oCCql8TQ1Vro47i;K^9y%Zf%I4rv*sAO+G zK^u6xT6ULfV;6R_0<~tTYy!BT7Pd3?e9yv}C%lT$0y?P^8l4f{rCsf=idgF47XCaWw<6-ENjx z>$Bxv^d2!nS}g{NmFL6?>_AQ1hN9THokd1xR+zvd4t@7K^RxO|QG4X0YQ?gE6gAqh zh`-Xz=uv65DCO?0=>0hGF}UTH(&c-gx3n6`Q#LA?R->m})d~>ynNxb+IP5HX{0QPu zwv!J6ss*wT^+gY~T+``%>+C^bh#&{)zm*tP1EV?uJOL&ZS}z|$jD?V@R7d01y?vPu zHC5)n+4^}r(DgS<&xcE<&8z?!FoYxaUg;p*WP;Z-bzh*UlFHQ)ovEs z@Z?N8w*(KdAAI$%7d*KnyO5Tde&qxjx#w6`sIfei2+#%q#+03!-=oDl$AFz8hf8kN z3e!LY`sfxipEl1Evj1*|D4sA5p0}Kb5dWM58qkKw>*+CyvCf`g-iBW5+&PA!W}E4* z_u*$h5Q;OMQnz=vs?3+Q;m0T;l zRq4BF_X!V~FxrwY(1R-fVAhqTXYQ8$2~w(PlJWbMbC}255#IIfuE4d9fx5LFKabjf zyvti|ZH>)2vvDdty9qlF_*@)J3G^;E#{h4gF|OZ|?zxNLyyaq#xy%vrFF;GSS{OB; z>PP%N5q1O^q_KrtY4QpAR%qm;e^k9#p4*(i0uu3k+=GM%S<&ATqO#Q6-u@u5vz5Fd_p{O9CiLt}&#^!^T;aJ}( zYpBX5zL!r>lu;-$A#}vh_;@BJ%gMi$Z1*zpKW==Fu(v}_iP!6&%wVi>Nh|gZP5avI zfMJ@Pp)f#V(g-7!Kv9&x0@#!A52qO8T_Ji6xyW&DE3pT z4NkQKU<+(|c@97=gICe0t(j%xXRj=VJ&5vB+8gUL51AQp1CP{mf%iwFjsHi{d4?tV zzHj_tsDP-TxHV95YvP^-f&*9LHW#?ck)@?&X#t7~BDu@f*Iiax+9b2Yk(pU(S!rdC zmZtrpvZAv1^M852dyePDeO%XhpXcZN8XsDUL2WnkqJbOBRyb>NALVOQdps{cRPJ^8 zDOtMt@gs_(4H#%#Kwuy42kC_a&(noCg4@k56+Z~bNo!6n8n{1?2*_10CTmfCuYhwm ztRVMvs{MY8_RK$GrYkI5bsg0qyC9t<+@Vvz2#B(O3T~KqUB(|nATUHJ>lW((@7Z^+ z(F@31`-^6<cG0%a;>_+c(-m|kc;MW8v+GT*>6!PK1 z%wbc*2BQaT=w>&{%t7T8;pdL~|3;gH@}A4CVIrFM$}sCFE8O&H`C&}aCh=GOd*>Tw z_m1uJcCi6pRsRfK*|)(MrxX$$iez5b3((5Xg?dEid2NS-i+>RE+;3^+i*{zN_d*6V z1l&vch+_5Nw0Ge1)skysp8TyI_GFs&KW(a2GRo2h{wS}ak6lY!W=}Mh`%V-CWp~}36%8sTWhrz^hqokHzs|@%<~408>z8dF6lAx8 z#M&uIeu7o6@g9aVr@KM?a9G~x+<4SuHL&5QL7?t(_@|oy^|8X?`jJt4P{#bJ+mF0# zrQ8N>;VfL$gjJ~Qybn7#vCEP>xJ2O1Jeg;y$dsY4Ly*Ns8`ZL_d|OFe1dW)qlEbBM z5lU-zE5fn<#$iit)$`D1eWJtk^sJtOkf0d=_mK=?PlB?f(Y<1l0Zf0k+J&u>CZrKpC{x3Z z%uSxparSCe>+|CXp$b))R`5;8z{LI2fUFByD#OB)qhY{Kyw5v*nIPgQ@cn>TGFp`p zX-eqxfELVDj4SI&eC9h*g0J*YgX5sXq&-BG$FL{bzjbUGx}_t{d?Va?OPMBj7fBld zxS_8bv3(B?e%}8y8fRExpX9u>t;v5;Ej7sqAW_Y(J!UYji+^SWK<&R*y>3PaBEU!6 zZp0XPgPotSOE)OlgU!{!or9_FcaE96U1j9viCP;K@$MWo2#i~My=Y1gAZ z7Kc=F@tiDZ%xllqTS^d!< zSmU1TJt}f|SAu8aUp`jv*!t;gMORC`d$@a=i_gFHt_Wv z455i%Pu-VIU@kMww&Bo`BFwVI$MR>@eehp6R4dAvHKa|g%mDqQ;*{>}#{6_ZncY5) z6r|2qyZI_Tw=;~I)BhRz0|q-3q)}oCQGr!__@eds@6m@<+_#&iI%zt-p5I1tgE}IF1;`ubLJgV?Sr%^@R^*u1Pa`I!F9DW@Aa637? z@%#`@|M4)kftk7J#vlrBSCkq8myqwT$UEtfzMTy`Zc+Okg5b?P2#YcqKZ^fpT?}>L zK$Z1|`Dzub>QygxJ~u&lfpvg=HQJBC@_?%C>1pS@1Kt)liSt{)?&CKkG6&W!zjp2B zeSJbGsaj87$C0i`wwd!_)b zk#_QehRo71Uv7+g&C4OLZrL7*dU*Cw8ZFV?#o=7ZPNv*k`QFUi6l(Jr9$i%=^Q?36GNzEeeIdGU(t zmCM(5l(k=RuBy5Od$@<2M$%$Wgc^np!tMy6 zQl@?Z(pGVXB{omu{_Ktk_=c-kh4$ak&r3q?ZH+H^XTPDu!nzEv^J0UECBEWr)qE&q z?7m89D}FW=u4e$M_E(gD>~aI%J!vFQ>=if9d$MV$n-7Qw?wv3C`!XwD46|wX%zS_J zI|;SsESH@fbF1R|D$)3noOR<~>Y}5Dhmb^$p=G34=Hps+GE&hrtvLi6M(!u4BIOl4 zM^|z9p$4UsvN?6MsjZ{4&rE}@i{8q}HUOeu-DdbqEGFP;n`v4tG;{C>q*0RO#1U+3 zPT5i48HY!e2^|$k}j>~BR=+ztC ztTVwKyt2e$4+cuvGfPqG(A96@8Z7*(d#> zA}*tNQ{_JeX_y!2AiT}_YxBPK_-@j`^EQt*PedECbm{p6a{z4G=8&$wBTX7Zb+s$F zA+OdEv|eWBG_p-a5F|0OI4^89u+ruII22Yd+H0ob-J~z=cJac+y9KxzucvjjB~X!0 zf1Y*gdf~NfPPQjctLiS)HRs#>H=w>#OAyo)ygYGI+oDZz`DFFUwnamY84kQ*F*5Oe z!=?s!106<6i;r&Ny|BaiLa`iZ@^%*EE39Gkzx464FfR_WbCBdOR1 z?t0EmmiCP_*tg!ov$;%VR(8VDjSN#xg<&!Vx~rC;uE5?|m|jQm#O2e3Ccf5%0f>z_ z?HEw$nc15sC5}A(LgsD*iku3|v=})`VzD|wHGUQ>)-m$!s%#Jd&Hg9d3(`)5#{>4T z*m4v%q9P5^^`QGP*3G-3F7Ek8Oektd#oyp8bzaaR@bVU0JSfdF?@CijOkg<;s{St$ zuCvE5I8%fmt(*WP;c~BJT@aDW2r>EsEGrTA`8?>P@l)o(z>1c06O!U>0qPapr5o%H zjmb%C6BHLD!-|5{>#fQ2Rj7B(+B`LSFU`7Dy-wkTwgY=Sn*EO5n`V8zG~yRLpT%0Y zvcM548+|ODl`{45tnc82vj>lfxFo@=60vTRW8h8Evf7WE0rK(?4`WM13P$^_?H4O! zkMQ1v0J2C|dr*DthM5=cZZ9-`Ux2j()Q%lUq6OmAM&owmkIGJ*2DI$d*1ZdSjG-X1 z9yh6ir%b;U?*<HhJww;<`ySaR#~hdYcft4GaWQ~bq24X zHVQrAU`+}{hs8jX_le#j64K0*N9|DIu%_YUVa)Ey(DN2kIUn;^LN2asIy=jVSzR&z z{_&~SKf}o8c3eMTPQEnvwaYg5!i0Z=4+dZ6!Bh#`c(zAg zFyD!S{f|_?&l`*jZQ>tnY?L!OC}eoA{J<*Hjg~=wJh@h_-N`czv70UZoFT^;jZH$< zuBzW?mns&^mqFd+$qHiTT?=`xDAy)_Zj!fL{F?V2}KO5|WlM=~bSkS5dUg@aQ=O?G)Kw zEfg)I2_F_SwF&AL61_CwD6444k8C0d*Ugghi&4t2Y&^W=;4jfhQxC0It@kH-rt@CZ zsXaWx%_Jy%Q5zFL0i*$|nl-WaxfMfcL>jv(Wa91GC7&;8_`2J4d{Vh!@2K({yGogs zem%*wcuAozh@%TDc&P&vXGs#lP)pqE2WYwn(;72wIg7iGc>Eh)+}%9c7vIC03}-7e)7YuMbxF0GwuP z7g(Y`_B+TD$BDJXRTwhq*_|l%(2zU2_9!LgVKTjVETyT!2L!loOt?=%#9J$`BpPfA zS?e@f&T+Y&a;OShn5Vh<4=hcRmnpTAmalHR`#w;gxC1CwwpatJH4$0eoa4v%s_Z6J zEHK0c>7qd{=;c68;Fp0BBhd5*!2fU+CF5PwC;8CqI?<`cZZqd2P; z*f-HRz@vug1Lq%S5+PALI@5W|V5;BWly~BvqC%4`zOsV7%6S>Rz9stK4}umQx$qK1 zOZex{e6^ppLsTHO7N(b?!9=?rA9(7kU2hilqqn<;Anh7*;c~}}CAjfW#VmZzY1Jt< zGe}~+z7O=g+g0K^b};>(_Zu*8%p`D!{OHABtYF`bx$Ky#Adxs^Jdv?Jv&|j(*On*Y zJ!!R8v#Z_1Wo@nAD^eOZ&qE4#zEZjk{~3Psgy$BW9bQ-GRZoLUV?;HW%?_WoJr@q! zj;h)Y*XfzP>i7pOw6Qv?o-iG*V@sHZom+vCJt~Hg$=ez-hgtx8I)ph|OWBfk@k-i7 zoxvTuui$f-iTU#K!Z%Dt91hxD&^tb0{a$c5e7OI-hT)@OB;V{h#`7RtB#U1rRQ0_o z-m`9uB!~F9j(E3P7`!^|c5i5Qn2@P;xL2suchAS+Lc3#BY1#EMVIA$J*QqICYuOI( z24QyJW>n~C`qG9RTpqD+@y}4vnYP|5E6C=LEU?nV_O>gD`XT=f(hbez+NuV3Ft6Lf zJ8x^6Ex~jYCBwD(?f)`&p?H;)W=&pfK(i5z+Bm&i1I+YFjL&m5w?^H*DzKcm(J-R- zu^@K)u84`&-03AFpcW<~8TkjM|qBC0K{m(b>4#Vj zMgZGN4Rj35&d3g^1>w1L>^!Cl>>7`JqkVv}H?MG!oN?v!r1S1Kn2s+gz|Ax@5+Q(( zO*7fRt74+gj4v9e?Rxd%ylUxYl!Wf}pRBFr2jpVX^8qQAHDkF`_dMyMgJ=-_C~CLZ z2tuVEZP%9Ip&=nkO9%1GM?+I=s2wfqj8m5>RWUK2Tva&VCB*{8B0!0xEB{)z*UNk? z2NJQS1|t8carT}Rp1R^@EIzY(b#M2hhF$Hq+N-Zg&t={jtuka{3+3E{*7s=*?4-OK zvME$xMu#c7Pm(SPN$bW%$8}CrlpoS&goO4~&p#)rOn+CXhw82KXaxR1%BZ6Wz__`` zeY->K)AmNtWQelWkh4;7ZS}vZAIjcq%xVg(FiLo*NZ);TNVBJx`JfB~{-O7X~fq13xmMj1VOO=5y|C`Nu#|m|pFGi7sSA(fkkZCq*lsc#7 z)wG#)ndSjPbk^9yTjQqYrzb#z-wykWW}*?kBoA{zG0o#xw!cIN3r%Ven^XgbmyNbq zW*f^1q!1e%=g2{%i%6j}y~*{r72@)BrHkCX^1MAC3mlrGA|FxpKnU1%`ZL2O7899v z>v+^p5*zmF394A22Xk7`Y`0zRjs9jV!p&-^7#9*e{NO|-t!Etu_e6(QdoF*=Q!vWS zt3mx+3{89BN#lk5)zB$=ui_a^628e=P$K#I&tLi;>-$y9t`}(DlCLxotCj&Eb|F{f zC@wR?AlgTM(FEfL+(8#qec%#2q4c$5sL>~u_~TV%octl;*x+nhLzFXv+tMuP3x$<)| z8?Ik9k4zf*^uOV(J=?KT66rH_s%kpog;HLq-;L;@tjqf>)3=3gsD52@S|hLA!M)=M z<`nf=-GCLSUoCw*j63~w(!uLFK#ykQ7hXC*lTk?gi4B2geYcaK=_XdEyJ?A8jY+T! zB;DlNNCa-zy7yj}dLY|z>t4Sjz$7#X|*>8{f zs4LKs$t^eUOrbnxqoNO5ZULhE=_M9$Vm}gpSbn#Trh$B<`A6_w7h>AjVw5GniskJI z1JjS9_h~VYNf1TSNPe+gBGUc|@~=|4`6fHT9Tjp=-tTci&_ou_hFJ69hGb3By8{QI-05Tki@HmJ=-_S%#6PrI~y! z_zVxWqQ7_k-jS3F*!Fc<>ARF$E^pVi2c;2-o30&m{3ES);lB9sxLg@G#+@-lZb53u zb#jCHw-;fLH;(Zkw&I;fm3cv!_2NmWyTLDmuW+QIEJv&J!FJGKOu51^^cK@#$YONo zX{-A`pC~)o_j=Bc*gjkPihmYKR@fc*@aKk+v1U*J$!xX6$FyBqFv9!Bo90VHbixT( zL|K^bU*5>KLLKTfGWq#?q%c$sEE>-l88%)9Uyz}O6N&o+%3dqV5Aqhqn>PIOEQfOu zr1A>Xoc91IadYwCE$L3-}uGQpXD7vKY_m@Rl=m5y#NQZEG=4i#dHgmK9-?Hi2 z{h#sq?mCBpUi~w!U0bo*w_Y(i;o>^`Q0Nxq_<~oSf-mh$mTjp(cR#@TQ0nVTTiPqP zJl~8xv(e#;iZ1OpKbTfLVrj}01Mhl8;ZN->UT?`-`(wZwvNrpYOAV^BfaVcJrp@T} z!|EKfAv*J_b{Xu2>YdTlPa4}`g&|N50!8nK=0NBXmyxccf$d!psFHiToLYPAp-S=V zn_Lg?DD(^T+Zn)NO`V7RSa%PB;tcz{5`s2_Ky_hXBLGWPq$or%w4_}lp3Dy(N4L3d_LUjo%l0m%Z_~8S`w^| zj1a69f_8Y+T&*P>BD~z3Yi=A6*vUj0=p6muOET5mk%E8?&P?+u=6*D)`NH-g$SHI! zsjwx{buyHy1iz8lWyubiZjYl-3*YYm;**E?-V%sSX0=z>(QB3fZPgR1l^;Ta^l9x= z-KpwPJpT}qw`QjY4lfKBcNrIO?sAvZU@)i?2kX76_ncj+qDqEK2Zm6LIwc)7v&<8%e}GNY!LH&+7=5EepplNqn z;33Z(HGjex>}BZoq~*H6BPOrbYIUuwKxKAsoSXaKvdh>`Sa+|~76;dz{G$b))SNZ_ z@QR+70xQ*0SZD_DBtiS_Oi%#2ELyV0qXnifiXI-!nLd^k-D>w`fM2Zz5;P45ElH^k z?{XNn>R4}HqRvedZo9#*@z-A4nk(+E2T|{ptV?SL(-3qBr0jwyYam-;q`N|1W%pR{OU z0!m4o(`oIsT`9CXmiheqP+STAA^z7Y!ve4QYn4;(FdzP?ktfNH=+C%>?wwqbs0L$h zN=$ozv(+NpFj41O>ZtUcZrT!wa;7xtKn;tew1V3_ATc`YrJ|(}e5zq{ar05Zu5d6p z*UmDKl6;cgjtv(7s-IC(7%lry0CL68*&CZw?OV+~;W#j?&F}DD<-O)8NDMY@;8BmV zp%*V)oCr7u3(Y1hH}6V3#|Zos^llGU5bq$SQi)Y@>{=pxoDkDA|6qlAbh!DjC$pL# zzY)f%nv=>!bDUDWyjl6tUQg5wl)=PZrd-z#tg;HvWyKq?&q~k~^~x*M48V1etzRu! z$^dEVzQhptON}r+%*jn;SjliT49ac9DyqR%&$kSqV!+qu;}IL05x~a^x#ya%+%467 z)gkI>(?9G~z;yLc$f46&O5liyHFL?2u6XZj;;_?)OkB-4e4iVrhXJEG`+X_yDRj}& z3jU&D00{S^=8`yA{jK?y+!(Rm&Ur{Be=Q%LPaQsAvxvs^H8%$`QRL+^_xGCc665e8$r4pc&m=|I>iBUh7LMbz0hF?*C>j zBoAUvpihjsuV-M+rtp(Xew3A`7EQ`4?YjTHiGgh1RRsAt;#m}6<-cZ0sOtuMPm{74 zp7Ul2FJT(H11cp?;R*wC{ZA1LV7+u14k@1F|9SK2`7h0Ir7!(p_dIksjx&7dY z{4>F3poP|jjkk>>B``8lHDqCTtwFb6)7^H$yDrovb`J!k)By0{^DnF2dNmuCj2hff zS|Ee*bZ|4gv75z-AXe*=JVrOfg>mXcDEYI+NJr)34A)Ei#2^bS{~$tJv-@6SchdCM zcq%B{?Zpi{aNJZ{x>uV<2^I_gs1@D!grF7jd%xP#2H&J6az}m9;lprcjo$Zm|CzZb zlpfUnXomgw0oQ$AD9N(T+B360J-4$UMPsA&D-{wNuTlP(La4xrZ(Waa}BTO>Ix`B z_rZrY;~3DsGP2o?7|-HPutOG6YvN4%ZQPSnM^+zt?l_H;PByM{IbK*cBV6i+C^1-} z<{7{)GlNG+aey%ar#JZdKDxS;kHN=p`ib)nltfra_Agc0Owh^& z(XD`2=s>nq+84BXy)0NtrSlJ!h*TQoAb$tpj0_6Q&i+woZWujB-)0PY;`;3nwgz-R-|1o=!i(x~ zPeL1G#z2ckYR~oxyzkKGRJc?q5q*SQ+QCcDV=SPnwakb;`O}&5I|GZ637t8sIIz#v{<)>tk*5|Tq0@SJ>Y)G(y42yH$w)L(A_Jf3qD-PCBk2S1XZmMTI7 zxlb%%B10>`k<2b#F~&jJa3+?JJps)L{7>mrnko1l$`wD3bGcRr3)lj7At={KN}jSt zMky(EK@y%k#HOsbqhPYz1W;!dic*kP_a?#&0C~HjOhyPO`a={RYDQ%?LA%ZR>tE@P zC>;BqAr;8jlLoAKb&7W=t}oF6Iw|?Bf!;|vzF$%p-K6a+ukLZz0^I5Co$@3m_(sDA zkFdYiB?=y*te?~F(CfMS{~}SJwpxANz+SMK;eE|8JN@wJk&e~7+T@HTw7FXy%TzkS zyFW)w$_Y&tlhe~T-@wkIIY({0b*G0s?EnX&BN8~-se;=bI0qK<(MJ+wmTuz7+<8wq z6XtE9JV;?TQGJ7*ssfhJo&1fGU26Ru$KO-v`P_=l@^%QEn{07pxdA;*H|4K!z(yy( zkWDPZt*y_t`wj;;$Mih$l1I;}?oHtsp*f2e`YPf+@3x!7bVO6b_6D1X2Kn2iTW^3QC)tYZsOtZ+Px8V0%y1z0bR+!V zO|13?0hJ+$c$-?YZSG097T-IqR$%f!((|`GNIX^PLKj2g>@G6m?R=g2^W`C4hIpSfeA z;=bXD9$MBLcbaxB10A(h?CGpu(CpFO1#6meCRO>U@mv#M;udHJy*o-&8R82-Q^jGo zirbf2zV9Uu+D4#Y&}l*yg85&=RQLpa~8^F3L1vOlJ-fadhi83;lN3}Gl1SwK_ff=lJ z<~5C{#>I9)An4#fKL4>6t!8d2Ffo_8FVt7nrDgex=xRl!v97TY2`6vd(YmNpi^GB3w@j~1)5b_VGDiKa%8_VM%g&QGNK^PW}vO!$-tg6|#zXDk}F zwep#62dYSS#!;XgbrbNmhZ7SoTv;m`&u)(25TW(TMUWN6qqT-@-9Xe+w8b?vGx?kY z`=!IJf*pS!Cx@zB)B)YS3K~B9SuQO$=0Njdyh6GbXbU^R_9XzIMMFqseWST2-w(+< z`h2*p9_ljYlc9<=JG6nzM7K4~3v_P?`pxv(>ObX3?m+bFov)l9U$BJ>29+oF#87On zndEyBeHB1Tg*NsIr}fE*l87mOTaq5g=H2-2yKWZ$eE9dWCf>AkWDPb|k63$WUW8S!$d#ZDb6C!DZUtyS3O+ zrvo5tg$mAOUW^0AQ47MoMcrX0kgbh z#AOYZuMjgks(fx(j%rrZ{yECnf;iEAt>C?ZZ4Xn?*Me0e(oxk~O9le~RK5`_N>mon z^p6T*d{qR}lvtTsNTcs1^CpU7SYqjhrPu^kXozGH*Hu3Cmn;8FxGO#qX~A#^@7~yN*m`@b~y{pRqHf9zT2UZiv&}IY80T2z^`s8gyb!6jtugCJD zra2feNMqp|b-=e-Qgr7|OM+e#vw)!j(+ddQ;H9HBDy-h5xS|@of?#y?p-`F%Vc%Kg zaH3Gj^gVZ&j>UF17}M}@Gvo8t3sYcOBzHmDA4TNex8V({+#VwFo|K0{dzkH(p6aiz zedUs&H4rBkEM3k}DEC%wP7bS*h}39IVNri*>Wbu8LYiFhB9luydVzF7sSyedF}M*2 zg=#Pei2lZ@f4WbbH(ucKNw6XMwFJ5A8+p+%;sv2~p6+u4cOnUvIXu!mgi%pa{6qTe@MOt(45Y@ZTV# z6-91i_gJ}=UU=UWMz9G52?=m@6<3DS$&lpm*8DU z^f+Wg_lWj!F(3F8?LM_`w8C3g6zjp4K z@hjUj3Yw_#m2!ZQfotC!{oC(l)zQDCW7I@U^i+>L9hP?_5u!e<%N+q+b)qR}{UCDi zeQTrSVl&Ur^mt7iirMW+b=OeY?suZ;WK~#TMB?)ck*gsxq=0Ll(Nfc&NK-@qK*il7 z53}FMsSMs)VH}g#DT~BOV{2`hH(sA#*T1wL(?u;znLY%0vpS_ID86aPthiZ`5D~OV z{4}P+=(Sz^+U^B0w>xh;^+)`wTBY!duxXxopk+w`t{)(Kk8`p(T5K){OT09&M5xV!|VR{k=j>=912_QCca8#y1y?BkOm?) zz#)|L*H8i1!vHmmE$ixJ96dOUu(MBC| z#91Ue@RP-(?!R%ADk(qw%onf4t;aEQkxj@f({V@a3F>MIbMSd7E-@XwR6LBQ50IKe z`)@C8soJm~wB$NXDL^V5&MWp_y(?VQH9;MI8TcYMnUaR=(~Moye-Iz)a{F&=Hud!( zFzv4}jx8AiDrISiP zRzK0XqtRYelpoU1d&qB&1^xw4d0&?lFt|L#ob=9N`&GVAab)LDpKsg0_<10Czj?)G z2Xw2eK`+#|j9Gu0eIb$26f-?#5N(tqk%dThU>@+u5C>K4ePAXSwzu5ZuFCtW4)`u6 zH*X#FgH#So_>GQs6#-AOKrakeijl)qD({6+Aku02emwM5c?RhBu~AvVe52W#1ch`jr7JyJZ$d$QbJ@{!jSG5o^WN4CI=kMG!{LH((q|4OZCatS z%p@C>zP9`_ab2|Tczb~DyN*z`PW z^YI9Azrh{A+GV`{K_CvD1}ZGQ;)2Ca-}3kJVgHVz^2Ak#AAyEe0)F~_PbrR@x}uWk z`_=r!FfKtFtmnxK-I*@?2Zp5R>^UjqbaF2>YRKA=tv<{XAKl->esN_B)%$%U)t{1R z_@L3L9#O({Rs${(U)5Hfp}lA(A9}{|aXAq4;J81Ghp7v+$wIzXu6^Ap-K%pWLQ!+4 z*)BCw*1HxT3}Q|#Dc~eMZA2`OX9PZbI~RF* z4X)u(JFsye$fbd2>7=vSepErsM-p@I&K-Szvgy`@sWco=$Muvi4D&dt#PSh(P z)!e*2y7diAt)zQL5AbAMIq6MEPsDJPAD_i3AwEL5DLoFFx)_!Z)8-P;ls$?Ik+)#i z$6bF$mt@}^Rv*4DFXNR|UY~cco%hR&4lI2QVj@S%J*B!V75PLd%7v@*^jaj7{zYdm zwfSo9&fyoZo}ahj&r|yv@~Qn-F2J|HDZ3q22TDghw!U}#=sW6MNkoK5W$+}(1Hbc) z@}ST^#zy|e<9I$a{$T#d5(_taj}-+(xH92A!#oC90H_iPKZOXeg?~iM?O(a9dZUe zB0b>&YYqd&mz7I`;*E!#`h60O>d0qf1Y}^B%E|luNH~wC zbi#bAVV83L9MdIVzUZMVemUs_*#zuf*<1M{0||qC3M33*#=;ybFIaR}pzC@pQk7 zqHaRsn?^6Z;&GU%NGSplXAu0iR0&d|10Jx4jk&5(X+VR-5+d>rCuYbc;q3gf+OU5* zwhDZpu|81VGzmGZH8TSg4>UI(|3i7DG^4SJ%a4Srk#B++ml?D)^e(z54KO@n7pw%C zJIb9Y7Rkq=_vHiFbD>3F4pKoBYj5hUMu6i^HrT;%oj{Xq9MoXRf*gvX>;1s~$D+Y7 z_NrH7Uy)~Mo5;LmlB$Ou-y(=&ii`SwYW|53FuyF9QkN>kx0a`PFpvM^FwJqGFGa+deBlUO2>jThXp<2oW6nj#SWf_a#!)t zxRojw+$I&M)ypoTI}J*9hn4$H*k>}e>Q+Y%iK8R*ij#;;#WIC^E`o@dFhvyjhZ7rl z*I!4PS0-kaF6uBJ)3S}vNtrtf5&I!PO4^*ew}nTxF;hKoNotCeYsa4XvQfK#&V0_| z^}@NC|IJxNayA#)?@=h;N63D$f;QeOcU1PAd#7556F0zou96pTE0tNI4~l>3PdJhQ zsqKc;I70vEyLiQ#V|Rn4iw5z&S_ALRVv2J~!Al!#dM;NmUnUvZc59DCC&|$}uayFfjLj#)puWS%u+4Rmc4Tq7}bJalHCf zwW4QrkDIwhZrl#gy-3X7`8c^G-DYXylmjxYc3;a-lgnL&_B4a}qws+v=2oy|N^{S# zVLrJXP`Z*1+Ia$`oXe3PVqzmv5L|vB2-_-t3LW9}YLfOYC zy4Lp&N@j&C@O}AM)z(petoHQc-b4-k*^bM~Q!idt#TLvSNL=a2J5o~s?bJ?7h=sv! z^>>9T+5V|D+vQJPo7vgLJ2x9cH460OjSZkYRL#e9zSn{``(|T!`cB8M3Vt1tHZ0%1! zy_tINO=MtRVNv$h=gYkSPb=#rRvHX(KkGNc;jKA5$dMX5|R}qhen!tDjIFMP}u+4haZ|B;-Zeshk}wqnVHw$N)Jb zd0HdMAVJ~npq7as<{i-iE++C0xTWLF{2-5s1ekdkMYiHDeNWh)=7ZEHXALw_Gye-} zL7i0`=m!FoM2*i`Lx<=0=WjqKz>LDJ9ey&+SR#OEw3AaQo|PZsP2ZjMfyrP;1K7{} z?v1haQYx%&q$;-YnF~@tFJp;flzK(PMa$d2ZG>{M2Tfly^zh+%Y*b!_cm=eU>a*HC$V-Y zB~eVneM8%U&gNV5F{ip4#}0zU@?U-4a79YMSt8NYBA>^EWge6iF)*+vnJ^yT$5V%p zh>=ZPa&F~`iK%b<6sI_E-*|>ldEv9^B_?ma=|Wt^xJs$oKaj71^b2$O0oDqo(eSR? zuiFn3mydhLu|C5l5uko^3%Inae3#Y(-XFEX4RX~c`(PSD^o#FdynrMonW2-9!{M<_^1!v?J^e%$_2;(a=!;J^gxFj=5Z& z{MRtl1rg4<5m>s4u{-t~5B6-{8ih8xfbo1f1x*h(kh-9H+6?kCKi1`j`wq=2@wA7t z_}FI~lMYj$%{^Qugfo6)J?Vi642MCWSn*6ZU-6#8_iYfqq4v{^;S|Bm76b%L@9)SS z&iz;(pVHgVkI6ZHBgk5MWT}LgPdSEOlD(2T1|eIA?VfQ^k^N zR7QY~&NYUe#Ag*@hn)sNhFT7~$k`Iu@2b}H%hlW<>BIe5a^{aC)~mhO9}A&MD}QQ3 z=g;^K!Wsn_s#fFJglB!L&i2ym3v}wKuUaL|5!9L-I35ZX5OQM=)rcw+>za}L2hef-5k3O%$(T-pDlMjuNDpp=A)r8D+2QT@QwDmU6ZK&3V@&77W2lur>3WOTpj_1mG#>5LQ8 z!br2|{3cI$**D-`m+JiFgl15TWw-)Y`me&%z#8V<;r znZf`^TbuqUTI-84H!W11xm@u`6Vna)EvKq+3BmA~eY8WM81P+pMFFC45tt+$-&Brc zh@ppEJuIO4IcXBJJZr}w;h&C@0mk;)AmPy}lSj5}^UXI@%N21H^-Aj3x65s53=z8@ zVo)K9Rs0UC=;$hcBoEn8_6Z8e7Nc60cShx}bjZ(KG6X~CTeQdSBCf{{9$=b8@@ z9KNVvuTuQKk3MoBk3o*c%>fq0Kl1*HQWi#aLmOV!mOfXe2n{9DP$AE3D*W?a6k?!* zi~Sq2F`4&~cfFKh>V!p&r#_#Er((D+PpyWAjY$w-9{hYY-HIJ+eb0^s^V{q>~RKL=3ITqS)? zwn`-I!%%5ebukg9g*yJ2>|<7CgRX=B!Gf#dpc_!8$hjgaElrEn#DwNAP@cCMbuxHI z)ah*VORD{M;e`_)<44)CkG-A$Y|_X#T8N9NSCt#(9EJS0f~>9JA&*3w3hJl0MPZJA zJ^)vP;rT1_0ZT@0q#m2R(^rcigD|=mH7k|w-IX{`n`|)t?F5}O?A(7h_S$3533R=9 zZP`1i2uwah3tGNo%!_EiVGidAsv73-fo{ntKE??ggN{{KySqahW)LV>Wa%@Bq!b~~ zT12%w;Y4Z!yos%=yosTz04nAF_)d5+C6ySS0#@M#L52yhY#kM*&ufzd4(o=%!cXdo zI-bfm{Dg%UCB%<5!qKt??X!|GLRYuO0p(E#(X6u2Y4%muQc>a-4eEeKop)%v(c{iBzxyF28!Xy zyt|5#be-=oB=2l>A4^)r5zfwXH@Ls4a2aKKX6JQRw&YUU%W$~mW{88Y49ZE1V z?5sN(|7@y#ZtYLQhX@}SZ?yjoYQs4yfM<;MvuxRr&%=)@{IPxTU3hcdRAdBFV*&5pwhV*ry%VE|R&T|d?hR=tYRf|K533}C&FP7#KbR0^v! zU+RQQ4@$t<%xIogG%o7VR~=m z>BkxDN1mVWa!I^%p#^t&Mc3Pq;J5v!>)=7zZSt4uS;rGpu;ORH8R( z=bYOuwuNw%H$OU^zr<|@G#e9#aTo{Nr5g455c;w@n%u~HC=dbi%&hzUaNI@p6VoE< zyux{e%Tn#`MSmF4SRb?b^pYxQx?eLV3`X1{&+{9$OLVFdu$m$6Xsp z0X>{T*8Ytp>t9?@Z^`FDg!({tGG(gP+vf1d-N%l{ zJ*h8dU7VJ3W}{af$si8q7I4ak%&R|zhKL~9u&I7c82k@;zCjv6ml1+DX^VaA;r?c} zuh42>cOuW{1hM4FtEi*jkEwa(Qi*yfgxkK@9YLyQ>&<;3L?z zeE*@A`{B5f4vNfl)dck-uH>6u`jtV#a*YMx52nzldv7vlqhA$_=_;V!@Q zrbuR@%6%vmzO#qNP)$p>P}@TgyOK{QtNfFvRf5

**`MT&G#FMH$xF%-^@z-}wlM zEf(oa&4jmlk+qIQ+WI!&bQ9$WU-5S8Bh54ZJ(g;xutbOv#KbnDXT63Us^z+WUszRn zQ2i0#d`iMXKk_qE4!1^Ivg-=yQWAbrmRE*1$M>$iFtH9XjyA7qO~6?5}mni|jz z8LoXf9l`RSLt#gC822dTjASaFTOO(UX~fFuiF7eexng8vSb~!cMmtXFt3yuQ`Hp?H z^$sodA8!Js{ASEyf+ymi7Ec46p|^e!e{nG0MrX#>MRd+lgIKHK-SA)SfB~R@GGa}( zq?rDJ0ivUP;s@`oeA&!60`l8$q_=2*mgQ&*;4kazBM+J%h86vQn?M3=%vg0|56*~ncjbEN9+0(YGX>wV_7$-J&aMC5cv4RqdAVZ zliE=HvWBK^BQ#EbEcVHF8S%S3QU3N~do><^Sx2k&*z+!jG!O}Tr*g2wVMm%lZ~Xn^ z|7$XA`d<^fI`??fdp4vUxAk-H&#rFJhu5dhCbZ+mI_82oCnzh%BLFJP#{s<6^sB~c zaA@@qmr z{!p1v!vQM&j(U=_Vh25RV{YZ87zEWhA&`Ps7s8@)`Tn-i_kSxQ)$&N`WmSRJcKyoxJ*^z+ z{XV5McvJi|?h6c;ZmoR8)MiVOU*gS{&OTq$8g(mAl3p4LCPJ1pXyOp98xFv)l#2t9 zy?EAl0S395gJ8uu^N=0--zGI+0et}jC#3t%o_zxv_+X?)76S{aPSrWqKV~pOC*P=m zOu}!mf?@eEH0szDc2R*9QBbfj3g*6Fg>QwPr_o{X0tAuaFw?N18E@PF46SfvtAj4I z-e6N^2`M3tLk(z~kORmphQR|e@bNr2$nKZ-D21%1c>j3}y+UySDvnLI#@ez_c3g4@iM}`{tS8(F(T$=>CI9 zk^<)7U202Q$)M`7W3ymamjp?mu-!ipzyO2+{52K^OW@9`sBA$nfU(5KG*irwVd5Yu z5`GC#wydOMIS@iIs>|1N$Y*HE_sXXoU*o-q5>fTz=K)Ul9kgg4CNiT^H+4fG-`Dji@2*==2lU)`{9 zJPShlY8|*S!e9~&2TGssN>lrS+^Zwnh)uooi#zxsYEO;PpJT?_DU7F!NUK|M;*+g` zketO~fkIUn`~*A#?8otU044WY0LxX@*iubiA5hR2JZN}K1+%CUP_(HWND%4Rghvo? zFrl9h$m+J5@|4UCwyrQiF!*FpFfJ&8tMn`BoqjSLy{$ye!+pm31rdEpC>Q1OcA zPxOQimj9y}A^KF*p6D4l6b(pS*#T2qf#7ppM`9s`Mlh*#c0Xb(Boh*aSVY(9t3s8k*(kV{2kYC5KbNELJ_%Ch^?YpFvGzWJY36dEP_f<*(>>t!f^c*a-DqCI z#_8SStWC(O+i(qVwF>Y(R!0EZV@er}_CP7MR7s2&&^aA<0r&IX!kgIq5ZLDncnUxD z-5MhYMfiG~bZHKl=Vlh&L_o?s-=Z4o_kD&``aqlZjV{9DTk$%MuUrYL4tEcY3MRbr z3~Fx6lh(Mc8hP$H&1q_|E7Bi2GtvK}J1!DL(W|Z@0AwuM)?p`zla;xYG^gjU& zVvnR}ja}j$u(8vbjf~J#SFjf{W8j!*AKk98A=V?4?GfuGEWP{j4~-pg+W#vSt3Jg? z9W0UsvZFiz%Dt0;{+sU!(FShGQNq*|DU5N<9pasyrdVcs{5_rVa{nlscN2d+_w|9y zegvA`#jya&xG>-cZV5o;Hzm_x$1T7a0bU;&AOooS+_zxjMO?n+vrkOwWBo-((f;=a zC#Yq*->9eAGxH5y(Uye?}O z`lbId?8$R@L9u6z{JKU7@o!A7$^|w`O1?H5iGMIC+3TJW(f`LtSImDU1uLEfAm^vf zm}3a2+wDBS@76|rHJ?#|RMe8>W0GQG#+Wm_B0ucMi%47vq!X>+Hr|PoJ&HGs6yf{2 z_a#dGW5!NTKfDAu6g%dCF_?aGzXPY$mozm+;p8IsnMK7+k7MYyy znl#2iFzOx*NCPj!g)6>-MN@~a^STe|@*S{$zvXH4%-ZfWXeS^uyBsqGQmeS{?J>oh zRVlm~6A+a|ih==z+(n`}N|x14^dQTB%yRW!QdvZYEJvT`$Vw@ec$A);;;~*Wv>%0# zb(Z?^?HR2NcR{7uRjKQ}KV5Q_tpuEgslv#{qW`q4P}%7u(Xmqo&Et0=qWn(It5?O7 zrS+t5!Xu8#$EkC2K(|Lf)soTQuVK{1J(!v!?XB2-jw^m46jmSu=t<14kgmIuR*cyS z*DbJiQ3=_-ji!oR-=(7&9bdR0Xr2;ncd(-UFOOT-*1>uCpa$6WW?#uBUwVrnH|Pkr zn+Lyrz}|<$_qr<-@Un&^;u~eR!P`CdnbrMw(e!P~+w}H}<+IWZ=1_9tLKrZUPFXbt z@3*)zln{ls<8cbV>H=K%4v8U`SmF<=zJxfB6`D>Oz{2gG2k^ZbH_~26ffBu668rDZ z1fU$@BuR5)NBh5K5Ttbb513b|d7KGQ-7rYLk~%a)1?XTrZwr1oOCQrg2_sADAVN^0 zf!X-!(5|n(Yf4`CDyiQnWZiGpnDkU-!pR*HyC9;I9uVy}{`llQmO?NNQYx}ZFd=r) zVT-%KIY&KNVg1u{Fan4J@0Fliuayj|;eMsugwl3RrH`K*ZZ0{6%wc(K-B$5Zbi8w; z;wE%uya+8U>mp6VZ@MB{w_P`SvA%HPam~6siB*|b#!d|qPFUSb8e}ZfCOik*^2ws= zz6&Lgi7{#4$>-uue`WDYd2Iv;<|TZ|B~V_dZ8azz=6aIm&~raEYXA-d*M^mUZ~ED$ z%99iwx=Lg^#KHTf1`lbw`$5gi zrEFV3tfT4dr^;={jvCsuLJX_{>%nC=mz9FRojy6^*>|*s&%+L|164)oEUlZ;;rdP> zh~Yc>F6lsd7mKqBpREu;NAXV~{ zxxk^@?ybt|IxKh>&}8R<3R)1MYui0Y=eL!WhHG6s{k|@-mbB|s*anf*yb}T#q?7|A zv@4`cTS!3uf^(@VLR;BBM#x9uc_|u~bk0L(eG1%+fEGPg5yqO36H^9`J_eh}4O_>7 zlC6;8GOA%dK{EgsyEDtkVyDHcZYlK5nuBZ;Y&W#lk$}A=jme z1kR_B)8W3ox1z86so$cnsHYSisAZt;^$-tQ&lF{JHj=yXY~7Mg{S_x6{UW}owiw!2 zzwMfv=6}=U+9NYnhrQ8#%sLYT!HB4mwy<~UNegE7DxklGk1{h+|FU;`Yja2Zgb8)s z0_a%Dj{L9AosjJaLJj${?INP;cGWs|&*VJ=jo{26cRi9^&Bt*OIe4*}LlZw=s!Sd^&mF0l z^-Ud^NZsM2g1fZC-p%N&0BvXV0aBu7=25?(b7c#l4}AF(eQhRsv7TIuw(SAIfS|_7 zU^;A~2lU-}kOBaQ`0#7ZM?rR&trtA?zO?fZZX4o+dAF!iypur+M9(m zdR7&I2T~V&@L4y>(YklbL2Ylk3;fSM{b`+-9+o5iGW%tdwauUHN?|f`@Hd*de%B;& z^Wn_D>vfB786N@Cy%5ODHr~kLy~C8L8_%P{G_mDdH)a2Ja z7SqIRO5^;t|6$8Wk={(Q(a5)sQ4(^Hz0+9hOwoWSvEF3f(u_3 z&WZ6pvos{~&?8O=PX1bT|d)f z3cMA*mZCj7JT6AUmtD^KaD4USlG4naclwzMUkO$VciG?(cSyY{ zTtawQ9*;;sb?Syquf0pU;q;jeJWc2Ax_;zPuZQV<NN+d|e>4RLiXSE056PZDA%cW!iGCA;lxN!3QbMBZEs#sJyU2V-!(1ELdNp8725%s7R~yjIpc!SLr6d63urZ(Cbsf zmL;?Go42kD>m#)S_j^qZ*UApOXm#)K*isVYuj_( zIA`f(b#hF|Yx)^LmOMs~JTG4i)CpXUEoma2%=0CjkPH1^ZdrP6dR4f=f9?JgetO2w z{q3E%!i_VD-hpda{UW#yWDW>>MvvB&MU2G%DzJSJOXK7(fD6{+_opI zdHM9?ywZHgjwlv2zFFiSL(qRBwew6%v_bbzbxcso7(3jkrKQ-8_aldg zhC8DBOzL!WU%oP>PR22dvpHK?VKCKsjl5jaSmV>Ocp!DKUo8hxK)wzqZ)a-l!eT6RWctMzJ!H`PCdhFd3r?e(Fq=6;4UMFRyk+nta729w?-;}(9E6H+ zz%hx+^&xOtj~yWh{|5VW0~UA~Yi6HP42mS_vcYOx$t*%`u6@G9JXvb?;Ypc7>fO_k ziuTLkA)go86eT0Sj{F`3TkL_&hW`Fg6iuvdl1`&C&#Fr@yLD3ihhM-AO1}rw6>Kd? zajSE))n+6q1uP1F2D{$F2qC-Z4u-$yG{iu@3*3Ep(_eGVat>9WGNa!|7qvz302TSFtv59m$?QAQo~Bva zT0L4t3Qj|q;n&Vh_IH9yGAW0im4v|@92Tb-W-b^HM`X#1@z{7@vcqDy&-<$;->s<* z7x7q8iN}c_Qy$M7N?a^mUN-{3v=WyU?C6M0xThgKEQ+UXZxUtjop%0aLnXwZ06$0C zYEpuQBOGYR3NzP5OuInK9(lZTAS@Sl7<_ue-Ew~z?^=lir#RW|vjaCJV*%|fV6k0X zG_S;uYiKiwlj6l(>0Oe7R0mCx5Abo*~jUjSXL!<7ks z6l;sm3|MH?%J@ew?hayJJoG$6{_Hn^EX;TlXVK75{1*RX;>+zd|{|zLlPwtEu{xvXijhmu$1Agm}L6tH(}UZ5&b0*U{gQIwW;* ztvk>hiVzP#BI4-KIf+^YHBoYP7=2sgYCL+w%Z%-Q!hi-6&^C{-4~z#JX3qJmNP*wr z=!ZiT&z0t;fhMLB5erhiT|fgEjRmixq&H0_R@_WvBmLk^4#_)yvr-t9;3wCW=A z^?!FgX#*jG9t3*mpLUp^er#teS5vWt9GoJaK30*@R@Pc;l|09vG8}h_^aS|iPg?Gh zM2MPcaQod5?)!yi+=%2z?Y8!#$jHvlTw|L2^NOWIp@u&Nv~C?B7h>rU!i_O8J^Pq6 z>a$l)P13pMOgfSBu4>g7b|0m;Gc*#P=MHQIo&o@v;n6|!=m1kD1+bMuHum-Kzj&UY z>>z7*FsXy**-W*iu(`T>z82d6c5SFR(~xH{^kgAYyB?w{xs{XLn6a}tKZUWgrSNoH zvD36_A^t#$<;{(jufyD%fqv@&S3XX+nGQd1k;q63AF{iswkf9S1LBRzW|VY?#V%Rio38kL zQSvCj%MU~6e>EG7?-SKBXmv2dvhc%(vF>(A%%|g7_Wx5Gvs?*l9a#`Rv^#0*A@kW{ zjD2!o$c70wn*W(hG4{Wjn3?%qZCx#Cy4^*Nz2E==UL@jOfMa|m@?&RcmwpVvP;RN-x zw&mC^4U`i!a9q%Jhh`WfA$S*sdFYSDQsUlP+*_1eqBS~Vz$>-Cm^Lum-Srvy8@9L$ z_(nwZqMgoLuKc`#(hT>~?<$U|+SJo^0*}nU)G`XZEekDxP&MU}_X77(8VrCeIzloy zVtd-U+E9IqnmKc1#XH~_Kx6v7I3L+<%6A8=~+x>+Vr#HY$64a-*kh% zCNsk>L_{TPq+sAVm|C&7kL@9Lv&}%?pNxFgss-2j7lB<22Tu6d(K^4^Iz7K>u_2(gY zH%~dXxi7%Ok&91Y2HXy{PSZLYzEqNSElM>$ybd#oDhxuY&RBs})VFFCQzKIr={3K( z3o2S=YfKROzTK^~1*ie&6JY0RLZ-D|!ATrWhhL|BeK_1 z)D@U`m*nmx!nCef?&;G~+TT>7!R{7mqY$b?9LwOWX7Q97!3Velig!q1GKl+U$2ZtT zemb3!2Wj*NlwNWg@B~{I?NrREe9whjYWMOBNdp=j%r)20X<{sL;QhV+SAL`L=yMFv zSFQe;vrh?Tw#swyW?Huc7}6Ptt$6$EF}iKrpI7ni(?x8^nped*vv*$WmA^p-dv=Qf zCnp2RJK2S~x1saKk*xUZY1n`2OV>JF=>a66Jz(FJ|3#*+=ib6VBl1j|w&06^A$74} z`|xG6wf_H*N}d~jb;s|-x|c;*Z_`t>f*)cjkR}9YZ$QQt>8l;MQA9e7TA4aAv+^@> z`pYYDErI)SjaIOT^<7`!ySLJ^K>z)mZtM-Omtp@~)NyqzN<{Thz&UjH6_+>wzpemJ zZ&w~@=6QWy++!||+<5=kz0cbM!$e2NZyW3`!v(Y+<$@PYY>v;|sl)_@T_PLjI#xOi z!@pP}NROrtT26r*rKFGLg4&{5VA){#HuM(jK7Qem+4Q1V+-K#k`Kprg719@qX#MVs$!M`55^*)@!_{r&#ZYS zMpV4OP3;8AREz9|IFg`i|H9fjEUCvR(wp3x$c3z=!k}%w}rOc zfyt*2bT%%RHVPi>&W>j)3O8jFJ9eO8tdQA~6}c2uEqpu|{THk`2n2@+vHl6=CfGi= zJt%dvY|jJ>DfC3`{ECa5xM5EaQdnYm-L-9I;oK;|Hk(jWZ?I$y5H`-5K#aWwC9%C1 zazO@jf*)5l=Yg)m-@z^50S?Wf)B5lLr`&<;vRe`?ocFkSJ~O8Ez)cnInlCj0cs8>I`4D(*cQo8WlNPw? zY+An;;qaauYeyhtw>06M^XsLaJuUr8b+mt<13*h3fNB4CWlHnq8ZkB&#M8KpkSvqQ^I!sWgwkTCBSw8SrzYJEw*-Y zA&)l@edv& zfp6yGN^;dP&qQB#0~ggedKH1NKwUFzJT<)VOZAl!+^Dq<0`t0ar6jZ2>wbcX!S{rO zN^yN;zH^6AeSeq~HD3oc?;r(~%zj$*)c2an(-{paI`+Vx9`>Q|*diQMIEPp5#hfn7 zF#Qgs{Y39Rr{R!p_i=l&>-@Sq9z)jzFG>vHiZ`A)hgFWAmXnZg(p)A)`@h40`vX~e zOVeE=hRhwTr)z{0|07{5bP>7C!G*h+Wwkl)b?1Cc?D4k==LJ({9)Ndjgd|=18S?%k zs6ON{!&_6qnsM-?bb)z9k zuVv}A<+Yu%+ghm5A+OUzJ2JR5RaJ?_ao9v=@pT$DGqJ>Od8DPmQg-6@gTKWeY&y%Z z?TC#JSZ6Z_b&lMD|85W8WYutK&Rc0b|Fe*y^iyJ)pI6S-L;(wpDPsDn0UkjX`Bwb9 z2lz}I-3uSKG~g?=DQBi2Tc|8Kif(o(k*Uu{9rElt(SH7g-p6l6*@G)tB2_1=Fhy>J zD$mW_29E!!+qH$a{bnShdTX24F_nwKNWe`Is-LNH*@ZVd74UHupz1hcIg$sTUO-a{ z`~m>n zC)r+(6VIk~Ip&c!%gfS)kmO6@`m?j{0G^6Rd2d8yl=yjTPaSTl@@_Mrt zYS5Y0Q7C~l;r#~mp8O9{hB)c8y_bIR!)%t-N_L11xHW$tqyvx4TU`@ztIr*Vt43d5 z7&`gu25}=JPcL!T8H%;Y;6#XxQwHrx9x{aJUO%^02+Lg6^hVHbt3s`j+_lV{Yt}@Y zzw9!N-C7PBSn+$HwF`LnXqx7PH6_Ml##bd}3V^isBYtbp6`O+4&XjsFbU(!lk4SXG z8Cxhkmxs0+0{K!ZBZ9sDwgG8VY{U5b1!6s;4@zHIRq(8+G0?l%!4S-q80_w`#u84P z4?o6|veUZeji!p;R_udX>AFyZQ#bGDIvKF@!N4!ed6&y;z=o}hI^|iI1nTQ`%{vf) z4W^Zm*ydQ#Rc*q}uM|^@A1irNgBgXQK*&DqnyY1(p5nqCqU8XEC-Cu9>sw%9a&;V! zL-OMehWI9k25apOi_a6#nSLDlb?ujKgA=DIN8S$40+4<-)XnB(BmlBA7W@D|tA69h z+3$|wbF(y3t-1}77!%}dX7ks9twFJ3v$pvy&ASkQOtxwt;+vj^!}_F6rgbH`CnXNS zN8Ercm-NR;XJ>ETzCk*AEr5dMgj<7DJNOOEw+na}0n|^KAMg_qo(oJh0?gI|sBHQ) z4+-Je?AHyrM2<#jW|XlaH5q4QIXJ?=ZhDQ0NUPnN=_ej)SiErTg;x$X*V-Jva*VQL zi*bbDD`_BrwS#%q!&VM(v;_5E;7|{FI+2v_$m^+8S#(hABm1%V-0TB^hiUO z9Z^a2862h`F$HO21j^OlX07tnRvoJt2wbXK8_77M3Z?*TeElv-LX>i+Jt5n2NlI)e zeS&%f!(bX@cN-Hn#j>+qLV0XLXz)vRfJ6i2Raqp!+O%Ot>p+{k0tRK-dSrAf3V#ReswLFr1IQ%JK>@$aTieUNl(;-~{Nl z+NUb?(=v8&y;pHe2LdB{B?y9+1EkhD*J zpWbDkcJZ;DH+3b}6zf*&t;lL;5DQAmu1Yn5-kPEZyOP{0`i>phmD<5+s=ZB=^4 z|Axz!BSPOfeSU&eFp}A;Rx=02Hmyc%LIQxX>T=VimLP_R`cy73flr{bT;s(-@! z5=gS=p&+gQ?((&nDi@{Ktc6k7xC_>xrgZhjpsh0|zOM@bH7maU#V;`@g&el+k3#cA z?6WmclTjSd;%YIf3L4`MK`fGE3RhH zP!sbw%;lD@7Vbv43VSa7l;0q4>6IaR9Yh_je7rGq9T`F+p)j8SgW8lm%E!-Xz4v2% zJnv+~CZKP2PnP?C+KHglk83|-_buL}2FfLyT?+DzWWjv69qR_Z8Yv zf&siVp>zAIRv+Yj$dXXM7dD};o-9z(W6HD6#RjnRsH^cXp^G{f6#VcYj9~S-&cZb zUKd$_2E~eeUhuVyXN6o|s+~>KJ>gRh)1UaRi!x1;66%S}UN+wv7IkUUR#mNg)jXi1 z(mjYuHR&&CSvu>EF8oKq?P}V%=iogy>v;(#vn1C|V83)V0g9S{X*sSns0F`wQ@t$K zK$6M(5Qk^|3jgS@u*2qHz8Gm z=MVoP(?3hMYD@q5M+3)D9SBM6R?`q}F%@snvvx}gD2)1YDI?~9l|Y{*8L}8mp8@9c zdDF{XnLM?$$trdKO1m%-r521hE9sfEvc2D8#%fRUw zoYu(9s2ms%Ir-9sCk8}y;{yRO#{-fda>^6+FO-9LlNITu*u?vY3ziusZPw;u%FjPx z6G<|nvVELduWMr-XjjRNA6*V`{Xm7@17-O^rv8Q?$GRZ?Bb$f3RH7#&<8`brZUCmK$s8Xcr7gF*70rMD2QPYLwYy$4rEvP+Qy`>*ro9Ep&DkZ7POr=u1Z)$NK#MjGi zQ3qgQ->U>>bZAtRg!Gm!)%T)3Wv5@<{~TMJOdEa^JpnUTnd1Tv^kfDAf7qKE;4Uy0 zO?N?d0YYLZbC!^3{;MR8wF;bO>}!@VT-$GO6uCWm`QDj)Keoob+ROv&1rEad`tPdV z7YYEUUDrW2o&eBF&b``3Iia7N8M7AotorMb?8Set{d+%F$^xrU#<|wX5b)l?>0M;o zSpH9)NYG)O$Yo`&9=1HvG!oeWR>@Fy4qBWq8c)&uyD z0Sy5_TmGpE5Xd1IY0QftDg$7qZ)dOl^`DpZ=}iFl zHA=fCW{Y3qpqP~}fh}V>{S)f}E$6pz1NAAD=PA^Te352*_VHg+eP|7QBW3J0zX-baFg?21mgPu<~L2C3E?du z)2f`p%F6`E?m$QPr@a-cj`1Eq7d#a61G|ncqzV+fVM)-lJ6ZfZzsyqdz*ZKwd9ciQ zlsmqH{w*f+ucrfc@c$Bt%-aj)Bv_QloSrYpDP-k-B!x4D0ecvsb{J3C=R!2)LWLqU z+uMmfL;xQ%Saez`CHX7vqKv0YFJ{B&F+I|A~oT`fY_6hL+mze8) z5`!*_EyuID2H6#44-Vf-m+ss@+o*yh+0q4cIa)9hU$eC<{+;fU?hiGv+CJ6INsCee zN|5KqfmV>37oC)*O@P})sNXQ*%_VnUbQzjE^4>q;lK>*nxB{+Ah=jy1TuIT$iqY%6 zYzF4YJp@CkrM#Rsvc-i3%w5XDkgsVZQK9OHdjJy*trSC?1Cp$@)U+?9i0|hu!E7SWk;=1klkm>2f9*^ihin32;>`zdWPeNQE0Hng6pzv*8T`n|JZvO!W z7#&KLL*a`irl16L!h6LeZqCsL_31aT2)gfdZTLUPxGB0>E<8t zKY0KRQM7lsrZuhz5AjKlc+V^lqc?C{)*d+K39`(c^f=~-TDRM&kor?G(xy9=o+Z|P z^uqX>vHo-rFkI<|mr__^YJFkpAQiY@1X3S)8yb+U2;4*7xaT9P6wDeC;qM&VOMDb5 z_Pt~MsbRVprwCVy9GWHB|2T5Ay{~4&CeJE0uJ1^O<1Z*+CM~ky45_zmpLM7US zb3l`MRmp0C!-Y}4r#HSMdCHV!r_H~Pp04k?8{mg|}yn^->sQR@3mQ z^#e`#ukY?k7Y4r&14-^fN+qJ4k7LR2ND)PQmaC^s=WeDMS^(&E>??J1U5sj<0|^dD z$=0c2QktGZ7_~=;_E$UDPIxs$s8L+!ZId01O=mTvGt_-pe8;I>EP_&odQ7U+cBRW= zDgu$aX3)nM_QL28CLYcJ`;2-Ui#eWYxV=iXi!i6r6EMNl6$Y?gILoZ82$c~{iI$@o zCO-V_bLaiAAU8x+7U=gww*krug$y*a13Xn>fXqPLW>T;{BKLJwb6Y5XpZ={pTjr!* zou}2c1s6+78>=Q-)+5HI6*o7{T#X*y-wg}xO6`B0K>u?K`C}&XO`fHTh=H%JsaOj8 zf;BWqu1j5grV)o<`;zgq#3uY8>&EC`+gSmVA&Maj1G(B!_)U&xw-`u8ppD?`CfF{% z<)+1Q!1a0wqM-aom4ikM-bKqnIZ@`TN7iPo6gU#SFPsaZbm^jL^Lyt_d<~F!)~;e6 zsx@Dv@?Sj{eOK-!9h#N~AY!-2+WW#@RUST0>?(=9kzv|i=TP^KNEuy_yr^SNAJ6;` zR&xK4E=I^BY+dbP=I{Ug3dCZ-^AmNms$>2I;yRyGFydkg zaPt!8LeYVh7t>~H;GGR_QARb|4RcAX8Z%`91vVWG>j)6n3^k}jR5+j%aU!$6Dc@K( zrS)Q$wE0x*ME&gHbAj+|AG&(Z+*chl?Um`Q zRE#ZJ^b*0x;k~QrgY4KqP@3i?5;CDK}zaFH_egSmY zb5;qPy_fwXYwqSlyl8W-Fd$C2nPRZHq~}up#qIa3`rx;iYZzBSL}*j!2u6f*X5F!- z;C(_bOh~UU)eau~&*Js#GKaxjies+LmzOODG3AG7k7y>(md<$OVSjeh7uCBf8%&=2 zsPcu%8#C=R!O&uE5Iu%KtoWl*LrTjp5#jQ?0^n1iRRHr~VBx!BQ4%FY&Qeb)Kdivd6q_c=6UIgn>|X zsfRp}a6vcj(yHuEKkzN_#MI=jAmCdxq;3JdIR^h!Kl{h!KKBMN7Y@`$s&L>4P@)O! zf}^@k)mm^vwQPuR=A3xVUV~2&sOl({*W7XbZC2*pAJF_Ayh+lVYL9{}GL<_!RNeK7 z2C@6_^f*7P$!)5nKeHJINnSET7&%0Ie4qJhiWg52$ReJpetc%+6eTS_1?bov-n@Ps za&wFFStGQsseOtOl(!26o9)Iwp`LXTsoQt)nH~e(vPzOoaMlgGgvUd|q7?4|%XMVA z{$zZuf2gG`Prx)T>QL>Tx`qaKNo2-wwMoiVhwYR3S6Y<-kSbBnkf3a65A+K}SVSuI z_6KQ7N4Z=6+Xam7B-ddiwB_2b6Uz3lf|0TtGLmGvP6@GC>fSVP$}kA#ln`aWw{+RZ zyrIYzBP#2gKmjC7eW>~oxX;8r1IbVY#=7oQ+b8oA^-Z|UfmZ0m z`^emjyCClM0Z?sao3qXLZ?(U`4~-LQPj8RNY$0^T267-7hFvoOrA;V5Q;1I>5$q&u zy_i5ZT04?va72;L z3Fo3ZA3zK3k9U8!&QNJ4nC_8YJKfv50?pD(eS|)JhtYTu@Q9vO96Jk>jFS@oNw=RY zi*>1$FpieuIuj(5`k8Oa_kBBm3wHfXG>?`^WL>I-Xr?Vh|#Ed`ZyVl3qe4YB6X`H?aCBmVr-e#Pk(aX;1Nm!6H3kae0$2o zr$6SD2jps^@+!;U7FdbynC}^PE(zpx-RsGJVm%c4d%9<-+v1iWJB50~hSFOh?mHni z!HDIzYUZUp1Bd>)3jkmL-Qt2`mGdRc!gEEc8!%k{O(C}eCq|}J1=Z9AuZ0toF`J}7 z8v!^y-F9mH)??{WDNR=}VDcgO*M~qIXuR+n8q(sjbpU@1R~SG^-}nfDTIsYi$F})= zPEC0j7_y_6uYXniSgp=e3s|NY6M2w5>^qUj?VEndSi(vx^V`Gk4NPMoYf;sn#&2u) zl83{wQV=UAGgx@NRslSJzG808!O4DiA!1? zu?=ImZn{9>dJ$={bFGHH$4MW)IIkV0E@%?GNd7lr5!=WL!#eDT=ln+a^ErII)|#ib zE+89xW=$tv*nw1pz<1yx@%#q*aHcARInf4+IG7h7q23*8vpA}%8g;GBDgKwnp$M=d zLLu}Y*YY2~%3a_XqZUA~P9Qs8^S^D3&CP-XHF+uu z{*=!@*F+J|`+t>j-j1kwdMyZ4U%;~l+SdKQy*O;OLvb%CiF{!QI7IfBBJ|F{86JR< zf3QaC4pKZiFJohD{NVDPWkCLNTtb0*x?h;$DI?+%1`qIQci>TDJsTQAoitrog3%L} zv19E@{7gOy-KP`%Vr$|p!BytqB6vha6{VrqAc0U+K)Yv*&OVabsXjy2U5Kb8*TMQ( ze&1+L5R_)uD}rg#%~nadNcB_O=BO^%^tNr@OiLv`M1Hlw`)7c)BMUaQ1l@FjNqQNf16ELsQF?gO~kQ!k#1mNQu zH3=Kip|vhA{t*xej$-W_&^ogXDLi8%U&-x#Ebel7^qG87R01p;cWg)_coAVU~@P^fBB%SS_5 zPB=W`V2pF3N6pH8$9CwdF9$dzq-T0Q?kP=F)udzwPO&nPt~G?{kpZjw-Nf|3+#b`7 z#p2+QoCV{D>E@Z{Rg;k0E{Sz3(tJz$tyhqkT<6fC&k!#je&XU3=1qIn?o`vY-x|^1 z45lh2!y1^g8)6|^loDl#eZMTcbwDjhNK5U>-t$I+kLhpa4`|&UgEkWL{C;im{07pC zlnk_bx4wm5f=Lw!KPO%nQ%un;8JvQQK4I*oOEBbv4i}5DtbS@ZQI$4G4%!vZ@lx&JbsuNsaoaD<&Jc>M_b!>m8vpvq`ztffU@@#n10wUi*>yiI#zSvti7|#VUMh)Pr1kI<}0_`d33G1 zh;wgmxbY6GwUv61l;GjY{4TpwFSYn}1Y4U?&5?^>OdUGg7OQT_4+GhMOUvzfbW^`! zoWShJ)>l?jntU6Y{xGdk<9HSauno&%26R9w5H}9~#qxA$l$L$1P+|%DO(W>*#@Rfp z{&6V@_Ed-euT-#seq;eykGqF9=GF>;CK^YLvw*RLLrB0riIQspeAV5-Jr^5izB2M77E{ zD{4Q#zdnC_&L8KT$KyOc=ly=aUau#`X-GRCXXeR}!YH%!Y#Rwmgqhpl2t1c>2S0NuQ-ey#?Ol zKTHIhtrlF8fAw?7>GT{S#>{a087o*zhAQ*AabeFj?y|g>8j~39Gi!JT)pHAs=);4Q zM*m4BKbO1HgY+Jv;r8RW$4m^M7X3s^Dk0Beg7!2+FNnSTqHLQ3swd?yF;|&<@t&2+U|)L z=?kVkhWvY$6sYhDJe5E*7nt@P3;(a`b()2gu-}k%fxmpf3s+@ms-XJ@cm@m6orh<$&tcbm|ZEWHG`lU^_*VpSu zc|3V#DMZG7xOP~LP+Zvj_Qm@@6jsIfkK#faO|3YxH)e-pcv+e+ZMdL6>RE_` zAD)Rg+4y3%L?4^@<|PiFmYn}w^G|AsBOHYTo#n+lgLKo=(Kdj|ZO4$9-2)NL=xVWhmsAh+0I{{1Y4-}VTy??Y`tVHoZlhQSUy_?^0S85) zkFnQ65=$efcP4Zu;&Z3f!kVoIVI}jTN$fzCgvp3?#ws)jW z)lFxqf(^Ou-|Qe|4bdZa2L|UMY{se^41HdG{uJ>lnconn*{DnT*9>ed+K9}WO-3zP zCcIZPkgp#xH3OtCsE3WDw#MEzaMMH4_(+xJ=*JO*?l7rTm;7xeOOf8mipo%MA7JAB z;Vs~`T|<4>%HjL-mG&osF5IBZ=5t7_F-l`M8E^!7=f4#hG4$v6Sw0yJ35&NZzLfMt)=PEtpeoi~BOyCT+llp4pg_mVqLW!*W?MLoGa3c9;f z)`7zw3NOHS-^^lYz08ws{>|=8;<9H@({55fw)iQmQL;@S#^`$OF1Cg3Lfa=pZox%H zGQ+8!L5KYNo|=E{#0K1T7H=tTHo|A@q2@FGzR6W^c?<$`vr{GxCbA6ArO4WD0XLIN z>scyV=WC+-4Oy#8uyrFyqRIL?d&bQJF5`0vVE=rVN}a%8Rl+|tNJ!QQ(tWIWB~TZt zkI0mH@WG>>s&)h<{+5=B(Wq?+T-@TUZeyUn!KhT;ON2bSxq~XGI0s(@p4p_qpbv;z zFVY;IRqlNp&G=FUj@!umYL&%IAdp!7m?=}1&*8@E#OJbu#c_64GOhU`ml8A5+g zTt4hB#Ey~-{>9~i{IIV&v4LPx!LPfgT1Kej1zM43iN8(04HoQ+nX@(Ct!LPkvi8Li z;Y(F#D=Zv{V=^yD-6I0$)UB6>s?!Sx zzpk;y_6qao-|b75CWE7G9lUoii6SG5PUV+7q7Qd!-NkFwh2*~G)GbY%P@HA|-WQ#D z>D-f!Q$O?N{Fap1w+Hv$SIdo0bBcKj2+&jb7I&TYEF^BcisU9SZe&HGgC*y%hgv;&eZz6b z{+`KJORwtaC8-2ZT@y`Ru2j}(<_{hpke#*xV6vZqSo0H&=~4tovqu4?xB_o zN~~M*Y|{)OomC&%>aQTEL!f*OA^W?rx3j19Ho4d(fg?!Op6l)GMz0{Re{@hTtRN7C zD8fMsB$Ifym!-C+3o_R1*+pWLtkYIb1Q;JcZz2i96*F-+bL%*g{F zn7l?bAqcdqcHkWNLc?x_kN<{Wn~i_`);i@HfNJw_@}gwOyb2tM;uUxHeY3)cgcr26*SVE@~>=Sr9jyk zPpB{JXD21fF_Cp*S+h4ZXqL}T>yqNM)l?PJ{R7BGwCGB#(D65D9koeh2g~Md5fAfc z-X)RaA3t#hvL`iXVXJ91|VVabbG z?4Rqjtlkpo=KZgb(v5gHV;mzdKJb+yjjY9O)%2^&_Ll~ARZgzDTeYRw_w@7zU{OIuRE@0fVZ{W1b(&_Z_ET2R!}JowGM-I zXuu4J63*o+PM0hW)m!e4C8l^S%!6US1NuO-pR&_wd|gG$wunMNMe0w+MyJCqL?`pm~qpmlk`r*;DL~GG3hWm!hutl z?QIfpseQ{A{|BARB?pn4*^}jq-OvXV&(G?~N25BC>Mhc6$D^%PM>}aS_z&ubEWOT{ zqYzjja>z3cVuEXoqW|E1oG>+k^TRq@eh5&W=mWx|@N3g>;(?K)01)ih4v3&oh0ru5 z@kh}6cHr9ZQ5hLDRfk48KzQ#9_q{=)gqFC$X-ny6XxgQOeM=5iRxwJW?>7fNy$fL; zC3De$;z{=Fx8H8_ziM{~H8-ph`ou5j8^GajTThnqX5Ze&G!~BOiiaOCwlN35nT)0W zBBg(p&^7s@6zDlq3SFx}{LkcVsXggV@3$I7^m!a-*PRB&Lm0#p3Vekve;1I_+VUSA z7*K*`^V`h7;^%>^G+`nFl-2Ap|`3<+BYYy#ssj zb>jX4nh;TJaA&4kODcqEgHKdX=B2xd9+LN9U|zs6ix?XvM5$_8T=S{KU6bQ-r_@0eeuma?1N# z&BU(CZ4(`|;KZr%$lwQZWv^vKsz36+XWZfy9%=PmW>2syOd75Qp!0)gC>>X$|0oK* z^E^8LQiqsQ<@9ep*6@?2r!68}7b}MmFYe;%y*Po=(}sQqx+YfPK(C6&z_!OD0}sK3 zK`ug5bJcU99*9}3|ECE|&VP3w$nlWvpyQ-TkQ;?`0a27{x(70&*JG1QMy!nX;s=9# z-fmM``g4pO+-n(gQi$KOx5C z3Qc_$6ufW>{kOqdS43WwcjkH%RaFetP#LS`%YVn1&;P|- z>4KBSH((sP5#jaWW=4fdSeSpouacno(gtvs1iWR;NolZP7#atTo^!fx-=U9<*abVG z;NCE*Sl#MM zWe)?ow_0V`h*v2DZG~Cl*Foj<;1sZu8T~|y6ZNig3)4Ki+WlgV1qj@B4uE79(_^FS zUr>Buuoeq9s7Mr3hn&gO}3>)p8-C?6dkhok^WSL<;t>JWu}?KN^&zc zkr|jmojCU@xqUsQfA_l3ZP;tM*tiJgLe<+*vzsPpJ9V$r(0e3IhMNcYO*>p?PR;w> zgGjRUG-lO{a`e%YIWNJ*4Y}Wln==b^bf!1~+WqUJ04VOOaK&)9BR>tb#AzgGzBGH6 z^}EeBLqm|CTP1e>2|ffWMQwmpHr~meSN|s_L0MmQY6awVdN4uuTrM5BJ*TJkbM&ee z8p)u#ZzPi>RG;x)bBEy72%ElxEKqa9Vetzwj^MFITn~Lu&NG2k42j=>47xsi<1RXi zm`Nc!x54rvx~DvA-b)JUh?5H@^ZP*CfGq6Z7^Q<@V!ax_6#De3FOKL4>W85(A>nQg z)p0)6nVWuwbCnapI)_t?#n<$@w?kdFHez|lPkz~Fj+gGP3Rt<<6C-Oq2jn$1RKac? zuRcVr@_N|ZvuDpI@OP*0R~bQ2pqremTZwPrsTA}>6+n(qW6$2KiCVk$ZA(U`nM&J_ ze~EVe>%n$iSVF2eY3zeC?x2T`W;Sb^rEKgU_1`srROVdKlcD*1yxI`Vs%wUd(}fz+ zN=D{(*4nTBBl_*iEAQdbF`}nD&3(W(g88FSvP^!=xi5ysaHe1Ul8xo}r&W|mi#WpH zC9S>)lwL1|qFQrKJJu4m|Mh8;kYGnh*PpH@ulD->f%J#U*LUL&FDgqA)|CsosBIO3Z;YwUtA}LbdEIn8-61yyikkrt~Qx7;E)#xuh zEkixJ9M(r|K^$d6P_Hq&wgoILWeuA+Y-RD5d3P&^^F~Iq;Yk$@mW7rW8`pDeVJa79B&38zYfUeTwEG5=A& zuAdGf*;3qxEK73CZ3kaMu*+gE?jzk5e6Nq>mJaR~7yYVbE}WA$gpxt|DpKEzZzRfYHEtMN;z?8n5cthOg z+8DGj@f*1(6B+W#>9|=zhO#H83h|uLH^FtiHGzHW?6DXp5<{`d`~)Ojc&?||+MebwI+-x!aT15i67r+&&VEGa0N zN4$NlPIu1>_RW;ZaS6x23>_uvpZpH2@i=re#PAQ7_AXv_#7D=BVBMYC}>?U3v7_UUdGk^<{t&RY#3Sx9}k zvS4@RhZh~px-oxi@V!O5hFC)a#nWEr@!gnTLm&Ji7wHcsu3`mVh%+pyVaSrtqzYYb6r`R~*n=szS+*^$iigEl@2g$Azm&Ish*R>< zE%nX7Kna)Ww^FmSH+u1N$uxMMEysW44>3O3K*VNiw0?al*M6ihnzV2)gBVvDk z=Kw;1MCA>W?N8IdH&ue>z~UxP5vh5QJMyPxSBXfeB&>v)8uegajkWM11!V8aLxh0) zl-=tq>!iqfL6XDJD$}%Z;m-@re}BOQu95p~f;Uqi3YjZUw^8n4|aZ?2+FIbEx zFqtQ(t?}IEm8(>h^81wSF}??=*jb#bZ3$xe8#oxDp&T;~FK){8VEbw>`j?{E0|rxn zHff6P8&Pj};^i z$upS&2a_&tix_NsE9Uu?QxcQ6^gUD7Uv@7iPJS`W3e#Ps3qLm+ZFb1;OsR5Cnr#T5 zcE_b_>}#!F$ihwwp1y@_s3A`x5$UY|fFS~O2!KJBCv{~3Ne^LT175=1#VQ4*ErZBCC0|H2#mXQO^a|4@nI!;>Jn1%>~Z5 zzqFsSK=0;WViYS>!Ad@}z0q6>e9cLGrgqO`0=EV>nn1KkX4k3psX9%28`L^r!6)%S9zZ+y0_hy$4MLKG+uoPJi+Jl}jX{Pr;9#Iez?mt}-g4w%jBN@PH?Pqe2A_qo-vtH1 zoR$#4wOOo+%QgLZ7C6=ZJ~CIn4mB7ts2QQ_qR|VII|3)u@B4*D3=V~%Aq%XD?U#*w z<;|49HWroNcJ~C$!x=rGx=nvKb%>X_luNAM8~JjD)|Hyo5pxQ?$y5jv7aIyat>T3P zSEv+%HnYh#;|{p|7x4tKPTno7e&VYc9&RjgGLXCK-RJSEr_pM|=zS{j7gkE&$rD+mxR$h|ogzgpDqyy6unOw=SfEz@|F zDc+u=J$FF_|3^7>ArTjC~{T}wU~gLQ+mLL zhpl(!aQm3fX+h2qivD%lgJK^FB;ID%w=wblGL__g4v8&#B{m}A0Va8f|wCsm@gC{}vv<%#XTv@eO z%uuAd3+K{xA8*8MQdkS7?FySD_&j%~3$ydMI@zN|jsHN#0J(16z->bY5F*3?!m&HM zqCm-JUL-z%Xs>i>@d*aoaqfyaj$xodGa)lIRR-grGH1OT|HlrKSL)%v#_Hk9Iy`wM zru^%Z!$ zs*XLWn?0~15o*in#L6b4W9XX%>*W5uqL+&bFmqj=2`j(**JZ?Y|3VNS`Wf zYoY7vWUK{7HKEyf}fuO|KN@9GH`eDFc z8qwMj*C`5)$qq6Q1&`p`S5jcQuch8z-6fjpZZ zRcr|n+(KH)mwn@P=}mEMkXH*^M=p5Fx)&FiyBUu-b+I9r*(O~sG#{0??I!)!Y~d$g zX@jxy*4Y)G*@Zm*<=9G|w4|zY;LcrH&8$mD2%5(W?`@mueAT8{pQ2D#f{?=w220XY zN`?)G*EuD^J+92a8t;tNwTsQ7`GzVaN*4 z$Kp?yHz6RT<nG=az7=t4fF&eP2FZp@ zy0KpiBX6kO3e2ell~ge<%E?V1Q9~P#7CqW!k_r8JDdY5+0F!OKo!&gLB8;C0ccHQoThUX!$p=<uJ7hG6ITYD_ zZclmEc$@*TdnA%ES`?a3zqb{%8^`TzLO88Jj+Ly%^ld;FjRpZNxuosA=TgliRWp5Q z+8c^7d5R2a$m{M0ae+!S^FR8B6fC_yp zXm}=x0_-=Fee!M0g?AWgJtsln&8pSack}=PGyHREZ=5e|U7l^u38tqw3z@t=Udh<A?4Ti82IeX1Z7B+70Z6pAab1}p{ zp$|ds6{217LL#er#A2xS0&Jv4`h*e$<6-x?uqUw@y+BwLxezNN9=FdOV+j-do_fC1QTUmCbuj1Y5a#fl?UOPai>5QZ$GY`;JLD){3wZX~}R1)Bk&I~;WP7dh-jnP63ZLodhT z@U?z*1Yo$}uWK#fIC11Xgs!(L&rva@y&>i8uNyp{WlEL8dWF^e>RBl=> z^eCtSlR4M+A@`CAIk={QtVc(tPc(wW%RaTr;AOC`;2Bwr;I)d18jf&=t8uSN2+r9a zT5;B_?YnvJ-W3sO*bI-bcU%E=ooBwxC%@u}-

&c?H!+VLRCY}363IwF7=8T94e{P3k+7chklnB<|V5bp5R zcuoKaqIC`ko0K>R2}_KyJ+4#vP*4>Zue%k`6WY$>ZNx~cCdzHJtCm$e_gx+FRa(hP_M=3Pv z!L`ie+!FR~u@%2g5QLRRk(FVAk%E}3pYzP=GztJe{ETb+2$``pCU;Wcs=dcXt$#xM z7iV5~E3i1ISwSr4@l=hA#;udere<$fq3+ z)?Tei&{~8`*lGA_nF;^UQYvpwimuKJ{0MiOj2Cwy=Rj}&&tO==O8IOUVTwV!Kl zbEE1s+e_E7Ezm_9+pW5fyBy1+8Y^G(obc4puViPvXz%lQ9wh@enw984=d&2%nv4LW ziCry};u3Z++m~{{o_MXg{4C!0D@F!)>2R{khIA|#X8@Wn;zYIIdDZkjJmZ)JOF(#Yvh8>_7Uv2|-)+S#q6i=3aL4;}t@ zc~W)iV=e3X4*j#GWl3z@MLHug0wfMg`Vzgoh_LlQ4#uEBrHmMJAcgJa!hl~&}-Z=Aen z2`;xHXnB_TUY>ucReV@o`B}-Z>WYVKOp;1K*`v>?3;H*f@6 zg)A>3MhB)#ZGM!*5w?l?uk!`aZ-x3Xqwz%t0kP#&!F>L*@nIYT{q59z>aW0w4SJz} zpYR(=RORXInXh{u1p8mo5$S4?LL<`7;-bQ{W%ujU>vOx=nci<}cp2?xdX+REl_f=; zy}E7U&XxZwo4I#hpVm;yU#td(ju;($IQBwm#}#DQqjAYH!}=GK5ba5m(sDMlOtTEQ zngtdM++1geOG#;5pFUEzAb0Lc6)w=oK#?RYJTdD?f->y&bU7Ea?MP}`+0aNszcU+h z3hU%IoXq(esH2Y3&g;S&cEZglFjq|?QAD?t4{QeQDG$IqZH!Uk$MAbM?DY7M*S0E& zRj@vcK>9$Yc1dV0^4G!A>>$aV*5@)3GBf&*vf_*0t^_AIB(N6>JZ~axm684oe7f-} z1cEiVNzjK{-X}%L+|+|*A~tz6iv-Y$er=pGs?kSnt0Jaf~2$ROWf zL_jhl+-7!AZ>l~&uPk445Pn=P_~cu@>SFJr zed=+k(Bg(7tllPTH?II4$8u=6^GrI=KO3CF0Y=W z^FuTzWdH@`#mUa}!y+l1@$qgKW8jhf0a@}Cgww5NSRuj%X=zJU-KtQy8F0HetV`;J z@escnlkv|-&i-d6H*;)bXvp)QpEX}wu|1rpbz`7DpDVF){$^=}jS{i-1*zT%I~i}v zgXI;hNM$9-7&wqlLMC1Y3Wnci2E)OhPI;2jj&I1jXcXuv6|GXvr1Aj!jPCn6;_Y{m zIZul3$%yOXqdKeS?y$X%J(89pmn|$$;LEBDIU`nI^Id)Mjyp{+AJKlTSCR!c>SIf^ z&%Orj3Nfh(jDTByE|kqF@Y;BWXy<(8yq-*nZjh!C!;qO{5Fkg1Dl7EZ)b8BfQZ&Ej zQ+o8dg4!tJVm_E>dW~reN-jrA>Zq|$7DKr z-7IbO6`VwtdAuA?@=y8?ekwIDk$$nA*c2szUauRTejd6!1VMIf{kXy zw=#>7uoaCO7HUDUxJ~+Sh;!n1l9+APLIq7~_vnfb;Rv1V@sM1!E9TO+6lwu2#dF!5 z4VT04TTDx-lgWuF_;%wals>KI(U>J}RJpD8I)4MYqkXJ-Gm$H{A6HoXY$IPvI>znw z!n8iKqF{pm@WI^B>(q_;#njDH&`!~cz9>TKF?PYXY3Pi(V;MdrV#C_pZz$U&rf=3| z<4jIx&E0w3*Pkrj%S^w|61pCXWyHv*3b3;$&e)mW}(4OBmb%m;+oS_DdNTLl8sT_ zWH+S@xA~BCCpSA~=*z_~sJWRC7x(vZMb_@fFu%1-2`-0s=NTt&XY2>NnBWALiHW zHuHGO`D!NrSvTL2uG4Mk_cXqLx~X+YnzNC2tzB2TV-J+nP}z1=qJCLf9)iFTCq(n~ z!WL=)=@PHj(?iS~GgAtoD}Z0Bd^u=yx(QTL{+r|MD!36a1Th|Cw|CISiPfa95=Ski zFhyw9Mgwz%YU-}O8i!1%E7W^ZCJ{8ORSp{lfab<|MSPHWqQHMwt(`Hng)9Gr!Wp|u zGBBQ2!uspFg}4=)^-gzx^4gTihxYE?e!1fdwaN<_B~!imUg8G9n0?1RwX~vkU)p## zJ_TtkQChieZ~V!a4D^6!2(n&y5@?I`sj7WM3dG)L6O?!aBpV$jsCK%qUV&R{Ap3qQ zR!bc3Z;jeh2UrhBe^q8Ry#X3;jG4TjHu|R)sB_V2=33pj@wh~*xl2rw$=XiTAcxu< z7XLw@yfl@h$Ae{~o3*zmabrJ2u1SD%2H%TAk;Ie@anfDwQJFU0u$Tm=pDpZ7@vk1( z!2LX_Rx37&uMCl~HTG`Z68!;nZg`8HhoQb70BoR{E5J_pM98eX)1>IaVO)c1(F0w(BgjPI4BytZ(A{Z@Brj(om zC2)uv;+|JN`!{SwdC-OOg4Y)a;?(9iG>`Uv`!NlNdxMNP6hQM`aM+#?rdQb`H8yIFG98>! z=4FwDm9?t!02OLg32QT`XcmpDI_0uG@tOAKF}Md1Lu9YR|THk@$+8+I&9u z)OKbUlshWY;*KR?{8UxTZc&wN2$7c0c`mnnl?=ydv^TiR{Av~3T}}-w%gf#lTF#Bm z6sE4o(FM~7s+w*Of*&{wbRn-?^5z!d{28h`3!KV&U%6uNzbF^z3vl^AT$hNWOp%Q) z5e+73JhZQAP!%QfrPr7z@=ZU*A>#-ev68|a;nT>^IzF40+u&emujZ{6f#YwjVZ6U%vYe zzl=Y-lzUd=FU%Fnzi=u4?9w0DQPA;+cKnS$^sf-UvLqB&uKZzF{>C5nSNvf@arNpS zcJ*)kVSmLRCKT7M{bASs#vk@q{9!`D<^EyZzww9t6@Qpebawt>oqyvG`z!u1q4?*Y zKTO#9LKuJ8U-5?t#r5ld*!92hhy4|Qm{4?e{b5~y;}82Q{xG5F?*7BN|HdEoSNvf@ z(bMyX_56)L?63I4grc{%_(Sg5USViT%Ttf#f>1ZTSB)i!ykUD`b80#W>zA3vN=l6* z#ige+(n$b}L}!uIrna}+?8!#PCZ=ZQ7M4~Hj!w=lJ0T>JT1DGyyh76>IJF;M`&f{z zS^Sv%g!kBx`alW3I&`oY3c<;!*CGswc>h^>`#M*PBX;Q?#0^2lRS zZ6qZcaqi|>TqBkXAJ@Q>uuDni(}L4*-Wkd{Ds9gC z)Vn5C#0*yr&%~0KPCoq#r_#o!h5ixiPrlC9s+$Kjsq?S0;Y)M-&(=24G`LtEV#_2E zGbfnc`9_1Hi3N!8d4B&>HhCfFAa33O&YTr!?T~kNIn|dRHwD^5IPy zuD6$5%O#``hQWu=1*6QlYng8%oeZ(&#C4CNm`|hOWd&g91(;Q*}=YX4O*Se>!vgdJlJP9wqZgcv8E#>Dt`}gs!{S{BG55fh&cDe9I7~@2~ zGk+sSiM1}$3gJ{djTp#e-sjfhn}|b0>N4Zwcs|jD86F@gl$r1j7?L641C4AySFdn-pk|$4qFlWRTFWLikl-2JPbq_5n(OigG_?K~5}zy-cNmIsO^VGYOOyl<6jli` zg~Y-LmG|)CW3i`rqEGLH0*Q^dL^Sh_^M0rzRkEmE=17cm3$ZC9pRdam(Ug|VrKTrK zv^+B@h-c8#S-E30gCAifN+|%4;lHu<1K#-4^GlNXpLukc1@IS-1T!>+qi4|qwm_JThC3zR ztV309ynPZL=Jk92Hd>D-6%iF+I=M%&aTYDDUOaf_pszs7R``Vej(Ru()2s1|E_)daCMh*@A1OMH6m8M35h6uLrWMd*4d$z=6*ffC ziTJ%KS^!p-4=EhHj3+-3NTcPii2j=lIj3+1v>`_vDk+vpWk|&7#HC-ZXgDe06Z{mL zr7;Lf13vT+m3q5DsY`J|RD7G2`|m55%3WDO9`$Z@rIP26q6z~QH zgI=2_DXz?maa)vc10bQd^94o5L5i!cT(ANww(?w-g5s_O_ZYbpN35HXT*FmdMDVO^RuOwnO0U^HK_VXZf>Vl&&-JY$aD^ zAL(r>8p-uoy?& z7g@DA<2JDitHWw?KCUw0Jd2IkH?A#NSgWJK(~(3h78w+hT_l@~{{!XLO49TsDf*K5 z56`nGHzl@iN)%$@*FK(?ENr?F#D}vDU+1m&7-)=}y^Ga=*N)?!4S2*~AODy1vXEyY z`OD)~5XBYCgcs11P&;S8dq6Y__?|)3evMo2`ai*$VtWU$>~ldbl% z58ia3$1ljA_@cnUBBv)6PTB7q-uU$%vPtt(%;;-&Ud<>G;Ab+C3ag683 zyVhsdy~kfR71+Vqcdy=qbI0XoehJQIWg7Spym?=5m1NH~VS$5OynuQ=|KkEhcIS00 zZD3pxj#HY*Te~g1tR@XUoTNY#p8O|vLpgR_CJS%(=T~0g7NY8~(%iTc{9@X9u{pkc z{8ie}aRcT~{!xn@X3o2l1v^Q5%;90ep%gZv-JRu70RQ@FVTgHwSAiWB-p26FzNZ4R zmj)hZh(G@6uB}3OJ@y1vW1MNXKDS?Nj{2l0>uTTD{epkYnS1B=U*N*|7r2!Mc2uRA zbwO6`R_%q__Oy3=$+vGsv7e-l=}lsNGH9RVC2mB>&~lSMPP8LFOV&t+&Si?Gs@ViKb>2NuIBSvKZ+>Y~PEvLYEG zbVUkj%`=^w{4ZAy%Cwv&*yMLbj7+E9%b*-Jv2d3E{Pd!xl^YB|r9^e5(Sz9euw9<6 z$jZw9hJhlBI+gizDXHO^ox92TzC@Vji=f z{%Y=vz(eV=rSdT;arAVpe9V*i$~Yt|W8A1(5fwP&-&7nQZd0o?BVzsIX5$ntK_HaO_EjuYteKLf2?_mqW3LXicz{?WVPWB{?J~;uVU?qi(zeIjB;YW?R|;) zp0O2=e$t}9VFp#VKpy^*cqq$6#K{DwZY+iPKILjefUcV=$QzR)l`VHz*ZHVHl?Zm1 z){L~Eq8574`z4Au!>q_o=BBP+C`y)=W;Q0$W6*jE06o5_3@ zs~E$zOgVb{P7t`i3CtSIWFi7*3sLlK6xYv*xQH= zy|B%{qiIxn1Co*uUkTk#4csqgQLTi%nsIP%=7roxmf?4ww{Y=$W%d#)i=$y z3ow`Ej9ZBtHO8B}7B=!VB`EZ)IK_8kpI>alWRGrzO? zEu!2WX(@Xnimrw2xNV~&3XbJaV4{LE4D)(tU!~ zu2MfH$HJ0#Bqk0m%hgkTpd$FFG{*P%+y-S#4>#&k^7?62r_D}`{EH@-encxQJW~t~GjAvLU|HF> z3}EI*qeD8h5MQDpU*fo#7G0S;2yaDg=-qv{CcD07h-%*2Yst$ywRHoNOJ`)Jm&V*l z#awYTT~!@>m}{h2e(1uZ*G4Ae=gnX2L1gW5HJ_|9o^i_BqnTyNud-NlwOFpY;~j`F zS^aD#sG897{%HBl)pSEr_DwiJunD`Uh+miBy-7#aD=T5%ElKi_SCH~3x9Y1=6jtU2 z+?BX$5rCb+!MDj$a1-859jTTxoo(N#0s`F3)JQ?onAE|yQa4jWYQ-Jh&~Km9l9No7 zNZ0EN90k?ufGO~C&GKulO&5qud z+?#PnjnD;XQk6;bV_p)mc@|&wCzBr;p>)S{C3#{EO~!Ad%@@N+mu%8s_=^>~5Kl8E zqfoChW(Jvy$)yawEW&tk=pudpZ3xq7dD?vSNB4sPNeh9iSoWpcCk0-RZ@O~&$q83F zo%SM7%)nWxWk_YT z`VWX1n-O*+Z58Z>^EAy#*+^M6$sx}lVQ6J7aT7G!Wlve44r19h0V=mK zNS?>=yI-8KS8jJ?F^^KmR9jxTy+fZiden6PTiJUT)}_& zWYO`llNhS9#aZJS#CgQBqpI?6gf*tCCd+(Lvv?UXvc}7E9bT2iD5TZ+z%&mC*3G|J z8*d=Q-*X5zj5ZO$?amv`1^}|C+eti4(Flr^F-B_oh_I|IMbI6tLsrM%;E=k?QZ}L) z$_^sd>&WwGLf2~)e=GEwl77B?a#7P<4T?*QO-PT85)4}e{L%` z!DVq& zy_Axhr;CckE%o!J*uXhm~39Tnu01cYhiAt>cs-6Z_jRWUEiP%Ss_t0;MQ5` zMErb7lIs}}REZg`LLy35H~eraLkeZ|$}pf;Gil$u%soSr*5(RC3li$RpW!#NAI55^ z-E_;1fej}uRBm>Hyq?qi;;(=@dGdcE>ZTb#dX&dliRzYEXTj{n;mj14wvCM3$Cd?4 zilVWFvnFEyw9_GYM-JpG-xGn+CW_=D}_bprjd@Y4YJ`Lh8?No0zUZ3A8gd;ykNp} z`O?x#d3f2L)i)v4W>hg(X7t#}KIj-qsW z5>J~GQ}hJATiL2pa>Q!vKhsAhKA`2yJjR_t88o3m_ivu&N4snc z#h92ZqAV;@&PNt6qbyWcT`yXzjA6|(1Sm`K@aY8YZ;hrKip@z2E3TWl=#QliOlKRo z6o4M%*y3&&LDBXmNX28~L^BbzyBNBXSnKDX=pcnQAbuQgGa_gjn?s#KPkEA|poR|Bwi#wLHE5wvKrcL=$ZNRcy*k7N>!H^z$wVvDjk3Z2T|1D-$X>NX z!xxIA4Ot(FLi+}rSyPJ88HgQ)l#xiZFw70lSEi?6CDShlmryw zj>i^zwgZtNtXvWFwM!KaJ|^L4pLiO&O=@Q4*yUIy__x!EyuKpJjgBAoVREqYtwNEpyN#@%gicCV6NN+f3r{H#T}9p;X~X=zxDD(zj>7rMz_R_cxW91 zcJ}8q#*QSlJAA0gPj#$%wGsH)t{HOr7+TSJK+bn`KH-sqJOE*8j5j-~ZD{1bAc~3h zt5x^q7#mMoUpf`{{1;({pd{JPS1IEc-zDDmE}j(7Tw~cri>V?Gvh?vF*fP4iUlr9uKo}lf5bS2eZf2%y>hl~nZIG*gvIS{`_bk2t{F?J zJx5+jvU@COcP3p7;cZMUHKtHQ;K&@I{dhH&{dF$6v2p;*H8tqM(hSC~BuA_;2C*}T z#<8o0udq-D*!WE(>}Ppm+RhMmZJHA|YBGn{^cB`-9rz#HH3 z-*f;Q15uz)nZl15w})V78e!PwLZ!S=$xbXXtbmABV3TsszMIe*SFsULf7tkZ#i_=U znH2TLrL%3Nv<3#YgQ_9C9@9Ri<|9KbEWiJ8+mBkEZzNrj@B!fgPd-&(>Zwr;O}{4D zJr&rnjXiNDXP2-MiS|3rMqw+PCi2eiZ#snK(p>Mno4EOov}@AG54+0sKK5>64jQ54 zgCz;5mi}{A8}O@GuJ6?drMz{~fh94!1}xxt5KGE9n|Iba4~t_(MqxLphrZq#nwE-G zDm{qhYYBIRKHFoZ#DC}4v zb~0*qDfbh0wGg}6BoeiyI54t=)ni{s!;;$41i~#4?0C3^RWIonMmqp0Kx+SOAT1iF z5BLM6@c_%f_}AA>DnJKf=pleBkl^-PJr$?I%mESr)1v<0Q&~z3xp)9*Lt&M=XNI#i zvC*WXPxQpE86vJsYSxh2J_5vQVBekV^G{Y=U48Cp!lZ7Vs=xnA3|ocHyxIBMP^659 zJtpiRGMYrRRZVSg7xp78)@&v2o-aC2Yxo6RTOWFig1dgT$6T|`YbmzXM9QQc3FazW zq%kCwu;AX7GJ4F7K?MCp%xJLjXd0s*yC9#ZDc+lsP0!630f^(rU%jKow@BC>Be_`M z)+8=7L7$SaKpmx`3$SR50-a$JvN9}0#jcN{_of>9J@z?JA{pWVWV?y1S?@F?8QD9e zO}X9k@g^R{m79LGu=1^~Q9Z|wkSZS)D5GFF`Dr| zMIJ!9WT5t`6fO;kfEsEh(`Pu6cJvzVV+4Dtfv*loxQO=bm6ps zNHZ`K(|BgI?pmLfil*FWq!X1~Yux}ds6;G9>()Zbn3TzM?4CzYD&ymQ!6AFavxE20R{H9;_P;W$>~_Q*3I#CG z%MTA3-g2s%7E53rq-4{RSU6!uez4|J2zr41aEUm8gUgG%syGDt&A=zo3`6Mz_jCA5 zs;()QGY(-fM)hqL*$!F4Qe5<|l=f_kt8`1pr>+$+aLUA0A`$DV(G{=>$THG%w>67= z`Q|#o{vRs^J1*Ufn~zFzQs6yFu}x5q0!%*l)!;`x)BXv$^c-|I%EH72SuSG_zvbYV zB8jiJ@D<6@y5`Nea;=gn$~BbC-uS6<0LPkkhs)Cz)`TbI0FMPPJQEW?fWufcUab+g zg2@n3;*(ROgE5J5u0%myi{nym<3wuW#U)MIU}~@neM%3CjbS}>-IW4KwZ~Mr`qP>z zqr`PRuSR6TI(vTFXhc_sl$59xhF!S|m+0faBX+O+q>c|!!PRZ}eA9=L-1rle zCivVvV~S(@EV-V5b={IS)O#A=;Nj{R=GvDOJnK`}ey6zwlQVjdUKzK`rCgLzbTr+O2Uh^B-)|OHI>I!LIS&Cup4@$%8 zT6zH@hU9W%c_J46f0C{{u8FK`Paw&J0FzK82$+N-0fi)VED(A?fuK|sNGPF5Ad$|Z zBuKZx+Q0@VDA)iM0ToOr3ht_40~95(?Bedif@Q&XQSx2(y97D^;{LN-UvHopDp9s9sy|pdjTit~I9bT#$C6 z4>JI_R!5#({SDeOsYMIldR(6+KRBe3uH{~>gMGRrSpnvN=&}#+oUa`wXip8O^;wcg z{7kKR_$tjFA_&tc#!P!sTPA_jX@ntf>e_XyU9%)J68V~mIIW8*_!y!v(qI-h zp}g_#E!8N-f`pa_o|VO?+|bN<=+Q-efQMIV?M~`dFMDjX@cL|Tqg}X`M@=zvfpc!{ z#)m$2Ioh1mX5IVygJ{JrcvBWcq&W^u@cx&Li>y=^G+ZmIq!r!l9IvER*8LfykMak* zWjo@GXS;eWbuGAdvy}wf=6cPI7IV)%jC$WN`J!&34hx8dc2OW)`hdag5(>8d=!l{hv+{9Ur zJEl9hij?%2@Kn+rnMsQv2AcKMPZR1MxG=#ZbAqApTdDi%D%L?p;prAR`%kx==T>;% z(>`6i!s+JQ)q5KMH+V@y#7tPrAh})Ifc53?{S`C$IR20@9!H3WIOne(e^xz6Npic8 zGB|cOuh<%w@*PjAhmb*;$|@|9nZ%8Kf{m*S=U)5sJ$r{Jl_1?~MV!yKVc5E#uZKCQFr1QR{&Z7WA78HGo z`xLF#v4`#3%DvuL6IQ0Z(fDalcYWAdzB4@LP02K)$^wn&Shm@V=emoDT#Tc zG?j}Zt78V`2RmHmZPZn$cs`i^5OY+vHLlXN$oS2^C~8WgN2BDg!qj-iITeC3AK#Rm!4;9@ls+mnTOboUh zU*FDvoXQ*uZtsH_Iipl->)l8TYP$$+UF5QwF$q1Jp(bTotYkm7v-bAXk)Si)aZEsGdfruquLyMhO=Tq``yC2^>ySO)ux|^Da znwmCgqtb#*vuVxvhbIO0@!Bfww%l=z^?&LAO#QN_=yDN?l_c?G9L``q<)usz8hv)A zOc-Pz$?#S&4X8B!a`&gLR##hn3j$yd(-CCy2-!W5`bD^EM(+Xv%Y>{3(=I$+_`@eh zJ*FszCP;gFq*k@=h~MFiiN!m4dRcML8ou8R{ONdXS?d0r*i0y?l>b!gMrOle%8uVQ zZ|K)f4o=j1y|OzlrE<&!@+5KdNxde9)FwQmKTd?J2nr9!-SgT-PO7$F_3`9$)DY>o}Wic*pzD z+#X(SJ(k{D4`C>xp(3}ia;qH&f7)Rb={psi^({!srOQfyd&U- z2!0N_Sgq)8_28kh7BM9*W@pS?gJSR0FR}cLZ6wLy>}DYpZhln}6L*r9AdJK1&>VVt zjcHxrr(S5d@Eq@e5iWk}($Av?iK%1p3CCo5zk8RtCTDg!MilbSmFH0gV_vye*QLNL zQ7@ytGovW08no3pr)kku6G}@T?!5nrI z=9{K75(1?+#PQ7A-7;?^7{;+>sP%E_o|V{?KP5s>LC$dVWVQNviYwwL@AK-CX~%tu z$ts#ppt)c@Z&U{A@`%%jiz>yhf?GbgB{P0k7~NK#==BRRo1d=I8f!3X0b4>hM@r8- z0=`8JJ$hwx2QRhem(BU?uW zZZHUMT~8~r=g@jcl%fSM2by&dmE&}wFhbM)4gIjg-_(xem^3zK9NqS#Wj6zAJq3kq zq}o#T8P^$U8~1H_n+5OSJPMVl= zH}k!73YB2qM?K@FuP>#uydjJyq|%z2A91hUno<2}EI_9via}y7_!JZ0(tq(33JA9{ zt6L^Rc%Fjf_F~ED<96X`ncGq3JTmcW95Zp%D5Eum9%b#iw!OWR?s55Nn+V*lUWP4= zF%!tETC*nJ24WpL=%-^VX8AndDk7HGIdvJ32f~jK0?J)Z*6iB_L98MkW?P=}fd}>k zk729xRM*h`fs^e$5A@kVwo}X#&AlwApybldeQpofPFx$!3Ts9<;<%kU&Q)bBO0aI@ z3uVFa4ZTJV3r@z=mPh{{C8r5BQlQxn&c(;gGseu{ZZ*B~*!0**Yea5vIFT!gBKVfB zVXwiEsAWypbD^JTtDi;ZQ)88zV@Uypis2zPI@!_Lv1yA#`YStIlB2!vluoF6mdS~Y z^wCWY4Pj{p$>pgGsXO)i7e?Q0x+qD+ifP=N&7nn2WxL*SdX2f}g3Jw~bfK|e z{0@a7O6PMi>_OfQdnFhmF`7_+?GevqTei`%dBQBg0wYVnG8j_N#C-=G73I2md%mbL29hh^R=m?7Oitlj(iVdpR>hDvJonf@>+d(y5vYnuMLouxpj*OjGyoK(-nx_rOYxh^Nkipm*CyzpU1ubRC}*>(xnLnY4ot%9oa z&xQ%f%Tk+rW5(%byk|i^wy^Ucx?#v-^{xPCu;`lvk9;ceIGC80rCF$lr#3ZRQBn7A z6*ADW6ts;}Nf<5MK?-E4KnD%o8kz`D7Ic&Ke9iDy0h9sphmFQP&z9w7K`4^v%-9k& zo9dTI^`sgbLv`qj>jie9RIVJ8tr+1@Hc*2b&N?@S(-l)Hv{n8_;++^H$qFu3tzyEx z8qeW>Ik4Uey+GOtwUQlnYE9`wm+Yx#oprt`g>Tj5H1D9;E^)AvwaLf6a)LSLTGdW8 z+r_e5ltiP|JB$`gCdVabj@6>BZd&()G5xAH>_xb+Rhx#}zC(Q-SL>_KwHFHkJ>Ef7 zed+mkCKhesB~+pczi6zim2`AmR=HK2HN975hd3Y@Z=%&%N7}shyt=uTz64X5n3A|D zShBO&YdO*r53Vv8ZB6+FJwN*r^ftJM~i!k|L|?eWL=d2nm`mzGr)&rAYdAF}4iuDa$8t`_L)6Yuk%N&gDKxyRXb#QjqGu#sS!;z6 z8!Ih|OYzm2P%c+3%`AtJ0A)Mu^Yh~tYCbC&D1PYSQVyPhiu9>*?CPoynC9sS2IJHEfnG zV88lE>dmVrpG{^`4(U}=Bt$DxTWB#>DPI$vOqGf@;4-?S^2g-NQ8zi&iMU4Apl__K zxAbV1HI-tCYZKP4+!)7{Pj<_9Tb9n<75z+^7gf@Dl_nICtFqn}{E%1-Q|A6wc-}!m z>JQnpc-`G#j=h^BS3n!-Scz3MqQJVj>_K)f_|TEjdbb3`jj_;^FHgYMGxbd-gkFsBo96?2I5V{Fhm^KX-TW+z2hg`Q-6V8KYV#Dlk2#G`#X zR9CI*@zHxlIDxm&Joj;~!5j9(QZz{Y{0vX$6aprM$BN#R&O3P8m6}o|(=klqs)q!( z$JRZTrYNY#$DVAM@#2ou9FZL(ALFJb`C?X~7!`3vgKh;R|Ek0<;^_XW?Hx5>GHkx1 zqn)QCb4Iz8V{PYyv-k9Luy(f9cK38OK_?^-O?r*`U%6M~iblChHd zD$PBaGYmhN0+yeM^yl0dvv;I}W>94MjK18Ov;%B^j5*%nF`#>d)G{I^vC;p%2b_-xnnf^d;{x38F^Ckf|1bu6cv`DI+=d?@XbPZpmLeO1x`G zJdN{UWmvN7e14rYM0|EdQWu9iL%|LZTi5~a=yIyS_??Od_+gnB$Lpk`X@w`@n_g?(jN8ODO&PCku~>w1vZ z`4(L_ogBaG75<;J*Gc?zmn&IovP6zsHN%d-h#ktxa7>$@r)N6EBs`1Xmy$Gh7fltV zr&-#p@yT^Uh7OI~)_!xtRW0)G9~>*wET-7pn`C=_Wh8!G_sl}u?1V9spMH^X*2)or z$9M&1dD{+eW%M#sQu#ltz3lb9V!>~v>;Bjl;r3Y&|DKu@!#>Myzs*l;3QQKul**9= zO&`kJp}$$s2eVDxS12fU{JJOJs}5gNDrxISZ#RpN`$i}(?57YZeaSx^*i#t6+{#Hv z$lwdFx{DyaF#n`DyBOWDHPv}p3RxU#=$I7m9a?OyxS3O5d8`jpGyaW>GtRiu*rQcQ zJmac6XVJ&lJ92uP@9{3uv2v+dLf0$8U$&{|tH44I97}?@7ne}o&L~A^iZy*r#bIuz z;C>&ly0QL}gubsQMJ^hZ$g42>dN#L>%H*+8C+9|qweqpka^CFW3MzG!DQ}4LzWhTR z);oEVspQRzlu@S)4*vFCE|b@X#-OH0+vIg6U%K;0wv(}KGOC7YUTx40ir%HmuUJRw zGS1vVUBuZ7+?*mPUu?k8r z%GCLk>U9_;*YIBVetdK0`{Q{~u2?p#UZ?5p<7rq(tk&5OYkak^ORRouw~0NcCSNjg zblmurn77sUuIk0oe|F3268Toy7N_N=G1IZA54;*wl6cC{E|BPrs!)hxRW%cv#c)U= zRP=|mD}yMF^{6T&Zp0=P%Q}Y zrSy6@Xf>RC^xkV%QCt-HheB5P4uZ~rzRLxs|L36kx_?;fRopMJR=vAw@q#n6JUoMhUmoDPwb}A*&QcZdgPwB+FOZM8CJXpt- zaaGLEjNKi=j<7ZxsctEPdK$7MK{vbVly2z*DnXBaoKcFK9s9qld2?bjtb%H_tfT!2 z7WGP>p#P1iqg5}|cCMlvL%dJ+aD9S)oJG8RDM9C@UX42b4J$_)l=(Vt7-s?mBmbiwd8e*Tct$f!cD#O1Yxa8Pa# zJl8tH@Z|(}gO(rMQ-WnP=nPJXK72=y4hF{PEJ-`ZbSkm9pI1>b#ju@z;qxX7OyNys z7+o|^Jsc6oFkB2@FVs=U94)pa55G}JWN#JXUjSyrCK?AEiXI_icHFsEH6qtaJo%4 z@_LJGDsTF`#>KqaroKs6tXD+*@N7B$M!cU8Cpu?<^2$jIT|%F@fD5aUg#CaI9dg;d@7 zJn$zBcMl*1tvw80vYwQ*KCSu{6eFgr&&bFr+Z0n(x#uD5!w22onDqGVn?JjY=y^F= z7p^_4-IOKZW+jr^s^I@!6OlM^nNXlGn^LUu&5IvbM$U>!FU?`@%}X>-H+CW(KXE%i zNg=Mo7q}*aWm#;rwulNfZOU5nu9wOU%gO+26Gc_gnH6jV#Sy_mVJyFsXC+`}d(*~5 z%<)p%0xKYy^0{3|3d!P!^Wzz)XMy*UvPkL4l`(!YClAhr_?W#nlAFW15H#c-oP0}@p1R|A^hD6#ZCLyXX;bbJC{|%ZT65SLRBM;NmT*uZEAeA;2 zb>OBr(k}7NI6+zexQ-gsA+@)tdy43~T6M_N(@!bfI>f-d-Ra=3s>r!bmH+Q}5D>Hv?iT2saPm^}4$K2X)Bcx})F4pFe z5ZaY0Sx;QdD=xKdzb2Uc!l$Tf2r&M$X@@82UD}=MtdyfMV7;ZGafgg!T4zoiaGy&} zj%Nt6qnnSeb}~<5gl$(xG`YHo>25q2eTD&zWBaLNm@CTMgc?vCtRWctdiF26(u#XH?O^hj}V1FK`B<3GH8V*Pli@d z7@_aC^FCGo6d6;s|50fon#QEqRJ_$>a|Oqt9A2IN-T1B;Fgr9oCXfBO(_xDjyE-Q+ zIg{^?p2ZQ;`Rv3MX4$@npiXQSv8I4Xh|7yfqpioeIvS*9#<27B%sO6X3Uicc>3nOP zzY3{ZFTY6fUizM9aKru6Uj*|nnqCvJ@S-%+Ve^BF3xZ7Z1@w*QR^|)l3)8w=Z_pQ* z>C9V))3&tIY;4!wI=t4-{xCRzHQZK**4}bnHyioj1v!xkP9BSVaLmsB0XTq@I=#mt zo!50HJa``FCSyW08*nlbto>fT$iZ<49KafIS>=d@*l!(`?KvviZaMo^e#g*`n4d^l z>GUkScxxR$oo&F!+N@6f#Q@W$)0!CPWH|6>hnl@Go)7bFOBUK=bC8`FRZZ5|h}!l$ zT8u_q-_B9CQ-7G(n_c`&KHDjQqW-#1m_|rU&Q0BSd+*B_5g7VU*aIeMRIPI&I*Ia9 z86US=GU@^@#wJr=zPgrKr_G3l-rCMNrZY5+i(HY=v~%P_DyC=yDaUi%4Q@#f%9-*l zDI_JQcFOdEsIwQE&Km3f1V%*`vN<>n>4m_@vWD>oGLhgneteTFj_{7{A3@Wx5h$oV z^eMf%B6!z=_vLnKHnVEmjb#7Fbk^#Da{b6tF@lZL^H{cC+_xcm-70QB9nsbe+Qy-j zSK_GKsI=1g!a+KOs+m`v%Zt8(9hxTIS^{(0He!PW<@H^8KxCiK;clD#mnC_Un)Zjo z!BE`?jXTG&k;N~lkgHPZ#AtVKR<$r&K%Hd;{Tb0+hvp~7CrkAHP>;CeHuqffly(Z^ ze4R_ar5-j=+D8eYRTTB!?Un8=TI)+$UYSjry9M52*kAW~jk7OUpG{PLnRZ$sOPGUj zWGuAvRLO7~@0V<_54sOwFB?j59YXfbzQt3BVLU9gkA`pdH{%{I^SxW&4ZA&nPmISD zbB`_j9m;ik=!hNB6WyQe(aAqF7(O?2Xdn#BL`0_-d?eT)itHX?jE62zR{dRn$-nVX zAB9^H*SB943U}AR=);xmf;gGV?)to<*7gl^>NS~hUBc9usDSR119WLtS}CS*Dqk(5 z7k-N(Ofk9sDjIu3+I9^1n~5_D?~XScgZZ1u3&KB-NdAqxH>Z@wD2CUlvT;Zz-Li}_)PzgZuz>fWrg;nlroAbfS|uj;g2ljGk~d-i+38)z99 z<1<~>PwnBd5eNuN0lmUr&xhy&niQ zN=-Nri@r`cSh}KjOeTFeSn@+%BU!EP3?;00N0AFFs@RK(t6O#XLHi)Q5hA%d_0eu- z2MVdjuD1NK{o~HW?sU#-_27=0x-FMuR%p_+;pE1wom5e4VEV=cM`t>w*J4HZn45-q z4Bp-0S>YIqc~3krFu4IADEGy7O$Mp#9;^M+O%CZ1@3Ay5QCmhRCc8vNO9Nso+Df;e zcdq~Cy#hGbOe92k;_h)5S9t7GiRA60ju>(Uh7&$#xKWgAy+}-*Trzma*WW>T|5@|T zUa=@?wu0Vlx`dh<}`eK=rRS3O@X(*dRLD!IdGOLLSp)lNBdkBmBwV-+7E`ztOuE(HDHQr$F7 zwX{#UMiv}(YrE{|^eA&4b3yzooBAt__YiMkW5aqWUR~zv+9uQyz0~sI>2u3cK3-$l z1##;G-}qvlwEe17X1>3Z&66ue=YCaIuAbZyiEVU@_W$0sS45$@G9QK%k35%7ahndG zoGI0z7weQ9Lhc!aJgq8aE7jP47CSyv?J8@diL+8ui6>XzWNT|z6Eu24L*?b~p+KWQSy!GILBk>BR-}IxH7rBL|o>`~f zp|k4e2X#3TZwdSTLut0E{Kz7Y`AcaVbry*k+4G`)AMcSODj)f9N~Ra@Ny{-($r;hh zC3aFDf9XCnS73qN5EzzEcdU_8s%o%B*Ib4#-@VV8FZwhuUT5d!?e6Jq?Z9-#**iM; z%O5UKI6Ri%;zjA1HJ7WZ0)=qJggm=_MWlM&R+I{m@VID96ZJO6_(2z{oN@d)*dc%s_R10X7bC)Ve#V&$R*E1kGXU14l9n;eUjo^`h3B- zfraxYg-mbcF)PCVMc>k6`3ccBcHJexxsMI&B^pf6A@Q#AMs7%uFr$q4nAY)X&5ZaB z=%zjmjoq`}O4@e}Z=5rg_b$hz)5&J_PmHWH{yLK*lyBl2BXuK^w=X@mp@K#X#f1tJ zEAogTj?wq>Cmu=~cnNv!X3=P16oao{8R zImjXQ7H$!u17N3|FU6BM0R+^orb~}Emv7%tF2Frv-EacQJ)~W zv-H8wmm*yoYO7N7!t|!!!x@GTD`fk`kJ!(x*wm@liTz%RBaN9c90E3dJ7@Tba@~PF z2{8h0nJG0>D1v0hzM5s#iE;Xd`uCd9lHEzh51f*cLA~Lr_iCl^k23YWTQ*_E8SH}= zqpn{3#Z`O5d2#WCI{i#gwNunMoQD`*{JK1yY<|JyQsOAfWnK`;n*Wa7fciG~}^q*2gwvKE9zt7{Q#z}ltoM*GpKB#yboS0FFvnEj(&i1(0 zVIoAML+ZGxo!rFAcQ0O8m(m&O{Ac)L^=HPU(`2FtQ>%n|fw^@vBjjL~zD?d9`3Opw za=niJ2Uc^C6r>xQlz@@kJNCVePc{g}?N{5EM{oVvxYx~~E~E{WrEYO^KHotSVne5J zinp7B65v4cQy+<9LOk&itG(k1s;=Ryq56{KH7lqW37Bx8sI)2q=H{y?^%J<_0lgfQ zluDddVVX((iYmbC9aL-TB?a_uy90J%aiW(O@g9F|ZP)=ux6Xb`)%8jeilJA3Y*)J# zD{l5=8n?+iRB-6Rd3@XJ!l*l?LWNSXllMmY`bd>pEKaH*?q*u80&^aF&bn9elxtn0 z*T`H~dIr?D8>}sTgObm^T>DWzA{V{cC3$0r`=W`2%7f4y*eZ-y)m~0LgdL8G*`a&K zH1|!NJI!#);)Y4(V1>2M^dd{~`mK$qEhq|NT*5#9W1#NaevB!Qh)u~b2elxQKyJpnwI<%!{d&YL79Di4hQ%hCY(PbI zCeN+;0@UAT0B@`H-OsR#lYbtL~xNsn{FQvtF>t@tS-v zIFl(TN9<|;Z2KBfsecMv3JG4Mu{cP$7mUiQby|=6eJ|EID0dQUzE$6?Ku@`1H-a&n zyr855ZO?0)My9?Qef$?2UqyR5mDlwe_s4PU@^Fv8=s?@U=>g-ndvyPF{ZkCS&_j;E zipuL{8)t7%J^vW~R~pu0b-Ou{V*M&uO3yOwR$Zgmn7EWFYisM*-;^Po zAb;;LZ~v|Ce!<>3^uXz-OG?gm&Q>q)t-kJoUjBZ8Y^l>$?^m5`(F)Ja;Y=@1ICx1{ zqT$hTyWvDn&a3Ry#XuiFb|^7CfVD!n;oD1#pQ~Lj2XOG6<`yO%VfNuCH@k1WrKK)x z86I3)6R~eI%6&S3GFRHE@|TG<&iYyr*Nhv~CfBQ}O7ig!rUbeNc(V-ADJ)Na_uya( zwk5=yT7#TX?-B{0~}J1}iHEI)cH_wKr8cQ0=oTKa_L9OS_neFAnp z6?*FWdH9Rf-N(ImeB0WD(v}V51Q8*1#~C8QD!pR&^M3~fRdToOo)K;d4e@d2R)qKk z%rf`RobnY1g!-EW`AhHfK5DOL8@SX^50m9G=LC_T+T`5H^(BNWskNa&LtFdGSKwmY zhmEanyGW)D1BNaVdyeELXp_hqsusT~TcFUwf%w{kFR-~8j}yb;cW4h+*ab2kvD!PdglvbcO9Tyw0{YOr| z58j+z>aO8&dT{#o-`jh*VlAhllw+2-C2wxdIBxEydS{TI7l&qi7?tXEdb3KMF}wp) z$<~iG{)o5TTvs`w5vf<2d$uy*Y=`B(z|hKhKVCy`$Sds}w)^6Cw=2QE5c`x$REwJ{ zr`4FfH(Wye7^EL)6HoFbg_DCq`p=dIFt-pw{OX_ybw?^YkmKRwr#J0faIry-0J0H|XmF-2HRdK3hj5s5Jvz#oxiI^XKkWBU?hfgV{I1#yH`@ z+uXdbZS&++)ax->PH9QTqbkK--W--~+snS{%cD_kNy8eP2saPCT-{R40Ur*#Gk~Pw zD9Y>i^|LH9(Nf}T-E(5n8H=juPTJLEVOl5dpmYZ#Bu~T#%TtCgSM`v}w%Li_9hN0C zy!Z}*x7^i8tgzms?(y6_ns=J?ezR3K=MC>2)vJ!klIODV$?y{TomXQW8A7@w0@Npu&p0ox(ea44Q9cAYc`4W{F*oheZ3$(zLqt028#zX(XOwkL~pms;kkg;TH3$V9m% zr@9ngwT2$Y2q>(B%#gPzv^yEI=MT@HeqPFo%dqFSnp>HmN;IGbYN_X*=@*!05fAlo zTAVb8C+rkstXnn`DX2f%uFh~Ix7XGhF=o!M>bso9G80RFlWwvKjgdx~OcoKuHJjYz zNuLZt>o2lqv9n6TbHSN7U8SrT=XfM_?cDc6bBox|SnA$Wvo2+&*b%Uuk=ssQi5x7? zHUH^QDb_6^5X&rF6FQlqM+~gTw&hE&DdrAUVMTw9fUVTr6?OH;+v*4-?z^FVI5G7g zF3+NBt>_?5R*tLiE2d6*M16<;5zQ!m+mEeWF|uky3h!Mny_rJ5r?i$2y14z#RximX z9NZZabU^e=Jr-5@-lCqX3OV4##Dhn(@j3MeHe*HiO&qEAm`Zn(llvWvMeZ1E+Dz8q zwI@MCyeEX)7-Bni1gjm(kN1>dUwO~1uUY|nsP*8_@=g8c4k_H`wg+im_4`S3*nv2r zIPdw0YbmkC>ZEAxKdZLW&FIgCJtB-Tt{k%7`>b#58XjVP?q5;-a>I(uf1E{q918+(lbP~sU_Uvc&T#eiDrNh7HU!I+;4m+WTP;1j% z71;Hm+{-N9(#Q!`)z1wP>~rj>5;cPtG9pBoa9iCtT!ap(V0x*6F)tI2s@s@d_BzIJ;gVs?AVc~_81F^4~Je#`MQ6Vr;9XP zD5?mztH+xZc@yQBDe<`}{FRg0S76}27~t4&*}(DU2onRgGDP;DC`!(3~MJ5S`U zr^e?cCC3@+biOdka~4n*4$3mM#Pdt@uR=vy;-SkPqW90D5pN@jCRE7$dM#+axC*az zFA0>C9_LL|&X&obZR!TDedgasVy}YJk5XKd%0m z7>A!m$q=^{h(6q68mcOIH}hi#iG+_HXG5pKg;vck=Y_37BS<&={ucpaq=(F{fWfU6 zqmPJi@nkpnP-cnd6{HxRUpcY(VbWXkH8KKAG)M@zXev`~(w=S*%Kour^{>bW_#h=o)1|kw-`>0f)-;H4MUvLv?UBN^ zC1>#pqzmp#K6aM|zH=}eHf<1TBq1B&$H)QA;Yn%F00`8HBrb|*F-n71$`Sdbd=e`F z!0~eqR$GqZ^Zx}3XXKNb)5vQ$^FTM=%o4%D2A7x7vH@R(_`=7!%AjSKszM7lDlcWb zuF1B9yDUE7{mBaeK1}%b?R>RjL;(MpGmdIU%3S(8>)~G>SGgk3VX%MN;>1VDYi%|h zoH$K5jU>T<8H?+tA4Ah%ztV$eI#q(K5F$Je0)K;&u6_l{gjYyTB53OtEAZibL2%1= zd?eWd)~5JsbR*?(PhF}~o3lnkmyUe2hL75=){G!KPk@%gUi?|~b3_8W`Yd304CEUf z*q;c$kiAx|Czr#1!AqzQ$bfi5yAZx^Iq^5M1HR6Fq;g>QG8BSfuMJ99wobYMIW5gHo}}bUxC0Wa6EC68Z*^S1_VWh_uiC zkM=`3gP1B{KXZBw^crA4U%cT*@Y6FYMh^4vK*t7+5X1`}%FP#_4_m^w12;i<07-{) zj&uij9GO$)kLPp;kw-t95W(^D zljESplSf{I5d8sJIM2iM^sR(k&=$k*6N`@pYvB>38IBG~#8TG<0(0`k-p2O0NMMHI zLBb1;8Oc0*b{Z1)c;ew?J6` zTm!UQI6OB4oKn0o{V@=omvxiF$ect|*FD<}zJ9}u0PrV|Moq#;^~qg;(Yjy~=#S}l zDrk>G?r`udQNGkZELT{#)k|eD8w@$o}0{OmscjIe-S>!Zm4B9XXI|S~+No21zQ|S60V#A#U%fi4@69A!#YX@5# z0R<^OGhZz!Dg2qqlm%TTj7PyrrhhR z>|Mdb&t2(79Y9`zrU>ARpA4}h;JPnr-H$^+%*koN@aO77n(^d~@X~KyojDVes4IY! zt|v7W0F%4tm$Lso5{5AgormLpNmY#pya&))LYMuCJqmzx;@2*f0i+$)1Ase`KcKN} z;sf{982hkMfF3z)8o5b57tqh)YAC)NIsIe$y&R6m+=HQTdKi2wW~HhdaLf!y*sjhw z8WNBfo<)e!4<9cJXd|4pG=N7(%!k97`vJk5K9kMh^HtGMF%lviPVI){zYG9nQg;NX zoBO6_v28vA*1e;ul1cXe&qOosI?ZmR2EO-?T>Tp`Yw?ttav(v7Wp3AlGrzNe#4U#{ z1nxhZr6~i#p7%gUQ)34(XF7X3sBH`|zQA=lo>lPa|H=^oeE!GpAj@{c#n0;1ydr5b zCwLV0+u#<6eEZL{+gf!s6u`4Gx*0-^nz%F2(E%?d0e_wSV`6cjS`#A!*g3lHG&y?t z8ONjGbqi|h_MlC6&gyD{|DF*9dv2q{_29bT3mgc|UFKw1G~Cd>8MhJWhw8P+u>8fNr!km;&hW4E;ET`KMlS=QWf?qBjwUrO z8?MUPgY^gX$TE1o{)m8bL9A1L)M6Tek%4dLmyRWFhaLjrrC;BJZSVPte1x;j;+Jdc z4p?>aGLi&1d*cHZR7=Z2tAS0Ev!IVa!hJ%}KQlKwufU!ecfTXk z@Qva?fXmRy#4y-YFC8laYBMVo_V!0&t^i0i99V~)M#iOEq zas`eH9=weu&KHap?wn7CRa5KG{(zRtF6++=gCxMzFQ+Q7T>$kmY0rGo|6G@gwHugh zj9E%&_$S9h@Qq`N2;hO`dVZmt3mpKe*5Awql|UPO?d_eO((hOXm9YFdn zhW8$tc~ii|ELY9s;sOxY;_Ue>xPRyp#tY<~<+wU*9K}dL&hvcxO>auLyIK{p8^A~ktD>gV9)beH zv~NFx`)PMR>vBsT?CE`5%?k)%|BVL#DLMt<(G3TSG?%g04CrR1sKYE%JkDPboiCqk z0rbo0#>WFFy~n`wj;|;2^?(5-HUH6XsiXOu&Vl`4=pNQF`WGMZ3bY*f^2_4_wPjn$ zOKaYNYzds?S)Msx5LU7$dp98VNAz;d1gxHL4TP2v@ji9CdK+^3#j?$wqtU8>fpFY4 zf2>)-@g5bAPPk#2{j)Mu>l2N#*zF$p%MEsbsybFJ|meGL#ENwKx zDDG+kG>w2PU4qju)PoNXbb%;X(t&q>%YCY`+%i?+@K@FQ-O-?F$FB6$MTNHQ9W8`a zFQTE1WUK#=$4|HLxgdp`s%=(pM;fz%8SoJS2Xu?Z;gWV&t0F)NOb7glYNfi|y$D_= zcJ{v-&A^5uzhFSWbp-YXD*J8KX$-Si5B{><2a^O?Q3{0keSGb5CUIyhK+sY!H*Wwo z?T&(Q$BO}1hv6e#TxfaR;8@@$_0xz*IgggZFVYSb0KB}|=Z&>5jqW`~)PpgbCU+wt z|FPRUK&Y}jtRP>S#(zMb+ZcY7!_wR3FtO}096u?KUj5h$CwPJf-gjQB8RCUE z-e_uofQTZHfarFBC)y!)Nw->=-D+9bDQafBTdSSARvy)^wOeVsmF-ddrtjnThs-?2 z&&+)0bIg3^GtbxS{lEI#-QELj0C&Jm&#t-wmL8(wgK%jxm^Z}TNwxuQixt8_@%Bsc zz7!w<9fsIk{Z=~t34H80%npKsMu5L`?qD}Kzwi_Rn~VLtnXvT}V$F-v*(Vzwegbcy zU%%ZmmeQa6ySjV;F#xvuui$Vaow1x~Mc<|f%D+xSt)QinA8Vhu#gujk| zq;1y5w^SgM*>u3Kw%yo}`gSX--p5t0Tz8_y&$(xFcK!;@$&Mf_A;er4q}T>a+zS@v zumUkcQjo`@VI4;qAy(>AEVj1s!v(wI9n&XT)GFtl0qx%}t@Yb|-a#(nv3!aZgy8JQ zY_AT+&7fHpjpsPczTiev9CUdqW(IeonoN$8TtV}lx%iZZigkQ`0kzDl{e2;U%3W!+ zjkhE@aSug>`6L}lV&3Kr2Nb-iTOXjYRac;jYy>G(N{qIX`XFzB-FfqCY zA^R>-$yi*A&X26=+?mTMIsP56*TvoV4iR}Nd>b3Ub8=diP8`ERKFxsP#EQ8p z6Nmkzv&?uwR5k}HqeKgh47SSzpX^|>Z4&_xRi z-r%BC=G>rb#(K3ThBQKAwNShH4UaXxnisL{k4ofviaYu%(b{gy=s1BbT~`#eb00I7 zbvGW>WNhdZ$9&}r4COZ1*-c+Gq~5bnN~FN&SR8)JHN6y-m=)~O&9b3lNmc0uxBF!_ zU~pUQ_Uu~T#ohPckph*SNr`L*@EbHaY;7K6L$K8A`}>6QD4BrZXgTef&@;3w-P<@v z$r1eFKHk~sciH$!-FAv98Q&?2b!rknB^sZrDSn>L<**HX4bx?bhxQyaRrY8DV zA9U)o@9s2OTZQA18n;CIT-R_pUGlycYcC~|Jlz)FlgWSTTf#>q4WH(gFDi`p4070j zw-G(K(e+q{Du!9b)43WX>m!yPb&d7cgP|M7 zWP5+}a9&RdXc}%_mJR+oJ)p%nzegDM^b+{nfdG;_(JKeuz9{bFQLxJizZP z?6iIrf%kSyS>ZGdjZsDp!TI-?LViz8g=-+>Uu2K4WXjI+%Q?tNaZLrF`i0Vb0%3i_ zd${&V>2JL6Ifzum*1pThiJ|0VXgntG0V0?Y1#}n?Mic=tScPe#3X?UKMu66vx?U$3 zL#=PQ5UZV1cP3*xwr4T(U`*!~eWib%T!0pzN_j{*2Wp;~JwDnhNI(S-rfjf$o~{fv z-SE6_4E(&VeDQ3gahT$)G|B08?F<-^U9+j}x)4eqdBMtg5 zqXb?}ar7f=-2;7`JdWbM{z<{hW2$$@=0^jR{7ffBO-O^wf?71E0xO+DjCHPO5 zMM+3ZN=`{lqo%vrD5K;u36s0z3lvdcCB4yie=jpV)#^_O3F`WBciM%pLdlh)yt>fF zdWrBy>(2*v=~kzK#&ZM+j%Y@~SLNc&W)zece0da*}P^_Gue=GTq3he=Jcj z#FYHXV!Ator-)hJAs(8mo640{yiJ@you}r9IB(d{s-d^QZGVE#u&D=-C(P;tCW2^Y zK*oOx%g`yJm~vtnj!U4ZO^bE52y}r9(KoERNN2mh3w4h@gp>hq+V{=ZxOvH^px$Rn zPY#V)7#QcoEnXrF-V8VI(X=tl$CvCooU8V{l7;u$bO02uI1|!Mb^FB^6fuCi6xxZ6 zi&4!t8K=u$aitY3q_cIR0}54l*1Lk^Ycdz)DUKnV_{GP@M)`-Hh%@%-ZJW$%ewNfQ zbZI%=!Ns3g?NR$i8@;4qbHwwPsMB*_$%3=HDi(aL@}!l5=8&D`Y1s>EQx$L%vM)%; z%KaUB_imHVqKI2+=kTftSz&>?3Nd}$FS}G&-F5!_b(1n5cfDF8A*v~0yXDvhTR_90 z9VQAm5c^e~EN(10kG~%@C)O{2Y&l`B7I;>i#;y2zdTc~egol>VCB2bTT^xJQ&*_dC z(h|;x%7yzKw+N!EJdTIg!AWGjWLwl^>x{OFiFcZ^pA~7k*B`K@x9Q;nkTl^Y)Dx-J zjWfXF;0Eei88Z`!YtRig#wU&Q#WZ$x_==^xa#{+V ziDWT#t~C`=?_+Gj0l+U>yz|_Hn=Ga#_Dy4$?@f+4TorLwnHtuFh~>TX00y$M6JvY& z3=MOzIaxe589wh$A(OY-7K^&req&-FcdY_7(P7$voV$p3V>D{JfBA2qeJ%QPN@0V3 z*a&NBlLUt11XELmJ4MH$tfk^I%jWFfJ%2jZNqVUj9D($GvA^h+?ebf_y<@WoM z9kKb5-gY5JsR_sQ^6nBFo6Ds@JFACGRXFNT3u^Uked+d^?SB|JepF?J`2Qy==wS?95(*yi&??N*{#Dmg2$r>s>-ia&WATd=^TiC`T^7^sR+47qc&&!RXk=YG*ILcGEZ~3ki_qNc= z^j2n-1$o><26k5x)iER8+0Jh_dF1n_ucZlBT|VLkyZeHf>O0ZDeG}@FKv+&0+<((} z@7@v645d~n0(f)URh^U~U&0s66R5-6!lI)q2-bg#gc_lgse*CKYk$8l$`L(PXdJM1 zdguGLE{0N(hnMxcl0-a^h|I& zsO}I34tK|X;l0m;61eQylVy?v6!Oljin1zc6ARwPymN~XKe0Q|IGMl=800KAW|VVPob1- zPx;jESiP>8=jJt3DU@9fEoM1~_C`bN7Z|-bjkY-_>_CLyGljE%NdP{!#Vf>48LoN7 z3a?Ocs^yeQUYJ7vPR6#Jju3;Wb(deLjV%WCxcs5-yeCnw)FFxeKQ6OyIb338f&Lw+ z#kCLSZ#_jT0%=I0#&-P7VFN=_my8jH8Vz+lPit=2)3*6_UZbLjL;w(#G(z?TdE)wu zP_qUEH1xPT->k+hQDnaC=y;z~Ntn`37wg%}Q&Vv%*<6GYyd$C^8s4fAbW**WiV$Ot z`@?MbMEDNF>9}G}ms80}p#DNxQJcavJ^31G&$MSepxe@Z}_QGeOc?k&})J>P<; z02We$zB%Hn&1)xJavj2 z$Ga2RqJX@-Jhn$q?C_Yv<0X8C$*Xj$>+g=m_CIK!nOKeyGVh>{&&DOzA#oCcHOvaXSXCHB5je`XwKY6FG3(cMk|Ky3A$jT?n8dRKYYKd zpn@}%$gTtf;UVJ;{o@{93RAW)9P^3Cpi^D(q zQVeH}tuGPJ^)-;y(fhy`AhXla091$;}kDAzS zOZ6}3fbkiA-#v09Bg92;J-{qBVdDH5o`D1mS4dq=-Qx(jQLVQ}asY7LNXY3!aonGe zR=?mE+w|}IfDvHD6G5X3w~Kk#ReOvKD<+g?TFw1FIngaOHqj?0;n2-tgMV>G66@dD zp^FW9Z|v1~gt-YlX6Evx)h)HqUP8@>z~9xAOo7bDslc-3G>r^&+gAp$31A|Tpy#2sr!>Q{rDgtH8Iv`WA3?I z$qThYy+x8Q@*T{R^zBtnB>Ar4!e@PwVN{x}E{)?Vk*$^$Yn`wZ0Vm?YJ6r?af-5Ba z1O(P2e|-XK3{@6#VHQd8-3)R_ao?lBSd%+PcJDdU^CUcal}PAZBFpMZHTAPrH%F6S zU0&=x=)nV7vqp}soU2WLo;Xxqb~FCk>L=rm z&)x)|+AMR5yL!35E2ndmCx+tiZd7lAV7L@#5wDyp3O@Ge)SP+Vs*tuGk3)KK?F?P= zL@K)wbuMNQ&o&CX6--s*jxGl*HKi}4Zo@TxY(Ok@F1+T!yEhG!1VRZ}*<73XIh;^X z<^*k+xfW?w1kmrB6X5BOImQjzt-EMOiePVb0S#F93dfDpU(G0{LamacJj1nEVL6>Y zxaSwrxm3PYnsyfJ(&+vbo>j^e2~Ra@52uJpRKm9VTKekd6R$2(H&S|eebjU;Xtl>B zK~9@KUL*lRJyK-DR}i30s^aiXLmRd)t~_UR2uTd>@gA&PI05(d4@v(6pND7=B+A&R z5PP}3DmkPL>9`nUe*g23Eg>%nvkjrHi&EJBBxJJbN(QCTRBfm9G!66rRnwM?fg#Ap zRk!yR4W%-x2OG^y?6riu7bgS|xK3G7oS&zi>=vuUZS9N}k~}#bSBj+Onm8-_AeUeg znU2Utp&8nKB3s?p+B^=xM4p~6|NJ4}#PBReSb7b`3?b*z=bQ>;PZ%cNh zvM6w*6;8KMyR9`qe@Eh)1Y4XgGFQ17K=v%VV|kp3k-YoUqR9CTf9t)*(keMbv7TO4 zTpiv{)p%BWvxf7pni*i1h9`>6jgf{JP?zzNaK@0D?k?7IUqBiDlZ|P}8etO<Fyk zXArbG+}qM|oI3G1V|~<|oA^4jvIqJ(?WMMP8a0MuQFN!L}U}#Ey#(iU;Y|tGLY7Uia9o=SZ5M3 zENeR3`1wXbuf39Rm#j%!O1_Wvk0)Vc>zwTW)`WY`U%i*aV$!nKrZm`6ehm$tk9v;~ z=h*c$YrqHBgbDocHcGE7Ut#*ES}FGk+nZ7uibvG#hUYVrM-Kfar30O*6YdWiGn>-~b{p?)qig8fwLDj>3&3^mgR&k8W+pFg>wbK7@|?z|19U$W zOAMZAU#kd!thtY6u_w_Fm6z!95j`V%8$%_Sm_G|#1GzyIuPk7lkdz*QP=q4}em6wr zYt1Ho4yaSYUeaWhJc+f=Cy(s>!ygum2gXXADy>$s^Ea#suqBDY~*XlA^PvjW^ea4v>*o)p3pYwgfHYU?ru0jKgy8 z;j%+vzd2Ry5>_h3K6M%F;c*Q!LF^P>p4gGT5y|R^1WleR3}s}QtJNCK0mQSYsDmEg6^msDO*R&~VYOqX%XIp}{h*#EnrQ z51;xF-F=B-5B2u`K43g2&}V?WIHa--Ki3b*(hzavYtbJG%zakLGnTg9VNY`PhkD|4 zI{2Ft+9ex#-rITj3Qph&;1vK*x=hFOGb z>tzO>Z-}qm_JBiEB=!(yill(Ot#;IN_O6 zQx^x^1IptF3vzFZPKU4Jg$h8ya7k{#wpyDQ>e~dbk%R-DR6$}_z9mlf(JX=S(0TrQ zb>&2}4-r$lscgjHzUq*WU{O0?wNK4xxJ6gWN;!hddL8C@xS<$6Q|$3_EoR)qB!O>0 zvgy#wz++kJIi<*VK$y?joIgq!}#u$_60NEdP0VZ}p18oE?OlO{Nx zJw22;L4XO%xRnt@cZ~b7a9)YTizbffz4qww`mAwU#P`F?>DX*$F;~JQ<7@YHe994R zN40FnQ|ZJD3(Ow)0YpC>pg>2~XErt1hrPMjX!LK6fG1J9rGAbr{ZXp^ z6!XKrn|osu3mSvqbNI-sM-!5SaCs^7lUd4r(APG&0(-lMD3liSB+^?b$V+f}T(7Uw z7S1ff?<;1}*pYJH9%r@_56OGf=pS9QXmpS9gdMqIG5(xEA^Ce@g_v5>A}G5ZJPs3b zaBrLT_LKxoVG5z4)Ocy-2{AQd+ohtCNEwB~bACy?&1G_VTxRi|k+j|f<^;qkbp2du zut~+1SKSG0lhVjX(RJ=7X{DlTs8&t~FBt#ctB#(`;|r(C!JpxG(#ejLfAcv^xs_3p zj2~G;^Tol<%xHYetCRD=w8c~o$@yFxqJje-r+5!9b1G>a((v7meg|5eE0I;^vHVJGIgG z(+&fS1JhA*XQdzxd3ji&T1jWJjJ>lqh?p!cBBn|^S}j_UQ;2#oM(_rB6Bjic~pU2E>FU~zFkKEbP?zE!gA@?OT@pyVabWM(@ z@c6KJk5(SmUfzn_mTM`8TRFAWPb~>ul(x>Q6y7#VC#28~X*^=X70$+L7<6H7@W4z2 zLs%6oJXLz3og2af#iY#-Qbn4QNY)3;jU1|s(w_CH5xFSm#!=Jl&O?-*R4XIjWO?Kq zy$;aHsZuaNn_So_9DWb3aj5ciWRN!AO(*ipvuq{mGUg?^k>j6^uaDGW~lhq+6qJAJ6pvscAoZoLNEm?NvKiJqD~?{@-RDUOtDiiIB8 z@<_&ugns#Hd61WO$I+$egOGu!^xYH%S&rH);;_o8;m{wR$#?>Z?ZAtXAa#{_d$>Rg zE@bGw0K1&zUuDwr5ZEP~UuDmDM;&j+L53aL$E!^7dp=*W|+rd8DP81+MpNgK_hvP1wkLxk!;)mF)ckNFYxi!K`rBx}F#Z z11~lkPOB)De%wmy;$L9;!YMAUiU}C>_Il%P9WRaSeM2+yI~V%xezOt^iG<@*wqy$h z)zD}={B6nYjLctsi zr1R#H0a+w$ltLGd2<3};QuSU!Y!xebikX+%UT2fbt7E)TjF&`?qj4>7lLxDK6Xi_Y znNPt&`c_6j#_@7Iy&0l^zA~7*+j#n_m9#=yDGWAlF$q&;b1E#Q9&b!B3~FM zr27p@D|sA+=bO4ER^<3YEhYO#Hm_naozoP(ejKB0wyDBa*TVi}Gi!ckbLyNU=CSNx zEE$mt*+xOVANDj1~R)_ES zYGXpD7*@}El%%1fyakLKw2kw(ep=a3nXOP&4U-i#UJ1S+i{k)(d8+GCv1=OcQ2!C@0qOtDK z(|@60j!Q%aRzL76-0%Q`S7zoXS>NomOW~t|bR|Z))#WGJ%5xJFbA1YWIt9Vs0 z+@_X+D~wp8KGDCrAI)dhED0l~DaAR$ zCQc>2%xKzI96^n^w722sJ^{-O%SA$NWyVmJ;u;Q^Y+`}dId5E}jnu}&qOB4)dTvZ6 z^}jembrmZ#gUtiSF5B%*L%~cxeEi;{iA>@?z7;kri)IeVfs8V}d!$ETq!%%l&F3;n z6E+D?%;=7^tL;V&nw zJr=Vr*^tgP1=?L%7Rq3`!aS1O#`qam%0$_ zdardLfffm7E$~a}|1kd?evt7mpl;(1h&-_$1;H^#bB`cEdB(rbbBqiaU{RfW=Fo}W z`03NBS;Wt!{8u2$_2Kvb-W-S;2|8wlcn3yQ_#f||hY&pcioOlPO)rMZk+|*+Op z#}F5q?ymtc(jGAH54QW7d}FxQz4!r+J8lIQ%!O`*@Ad=wyTJsl*i9z$Xv^f!nrn#G z-(SLAdLAFY)OWoDWUn4W@<8nh2m)ROS>I~J3a&v9Y!4uKZ~x!Azz0yH6Cphar_V(O z*$&?Oz6p}D|FH#$^J+vONl);j1Bl6;L1e8Ape;_epFs5d^GUE~*pLC9aq0wY7X1LM zpN)uCRTyd+Y(c=|{juPNm{aYDAPNm70on19Xi)Ky^B)Ll??u4e*|VqLemPU$ehP8y z8;jxpRo%+ey$iheCukW*c&L!jsV!(u=Tu4+fue0Ns_LPZ0zE8GRE4 zIN`QjNJ7P}>9+z^2q516%Z7-b9kLPEjpxiiZ>N8^;0O7Pexuk97a%s@cOU58J94)jaei|iI%PwunE+8& z-3<2GC*`|Em1_pUl22K9d%b1ND-d+Mk@0Ev?Y%V@LlD;-5NZJgtf1x04BZnjoUo-W-DwSOblg$ za-PAT!Q*KVJM&KKr+|Ro&d59P2DCZ2NrWg~eGud!LETZ(mFwu}mmm#!@!4*(sy2(u zR)_(VhL(~S3-0l8|KRmB2MJj3EwiICN%|&y znFSSu-iTlJUo-rc`|rk64g+(uAoIKz;nDHKX7uEXZ%|^(KhrSW)yD{H)io>Llf!9X z5#2bWuWB{BcNHc)h~Cj~lPYkVzO})oJ59?qz(0we0-6Oh#g8 zs$O;Bm6M@7L2=h^tFbAyzy5_MSruXcOH4}W4%$($e6y)eXDJtpIq+HJ{aTe5pS-Lz z=J7dfRq~wH!G#<%N!BcFwhak*x80$Aw~bNQ@cGQ zp#TEwRk~c0CV=iyg{6CG#w!g4lP0fxVhE+WGDe6gf)&G(+xOAiHkK3O!FVHdc5RID z@8Km}Ja8)<>MZ+rl&Q@}bYO*B)|D!Q5tt>ywXo=?u;QB9#wbJSxGc$F>_XL=NR4H~ z*h9f>u_W?lCb_&r7JTQ}jWxm&Fw9b3(#a*nZl!{|!91>Mi{jyiPlWCH2%~+zix4MB z?@(oB#A%!nhc*?jt&<9g{d>_ zI9cBc|H#~`@7#A7GOq0V1i+oBZDX%tN{-*wm>d_QOJU)+pnTK0jv_BDCX8~V$UfWP zSnXsb^uSr{9f9N!Z>u8v7w(W%ygvW(0Rvx1S8s12G;?(PY|}gtO?N18KZ`SgP!*!g z9+R50+yB_rNfgb=ZJ8SzV|H|#`G*wx#mPg`Gh3gKaH^iIlPIx7=L&RpTV|Rd5+KV? zC%tJtb*9!6ngk+dH=UW_*gdsq2~0hKjCuS(tX6ZfW*P&s_Rw#|F2sBVP3PA#+85;v z?2}BoP(ne=At6QCIxCrvV_!MRSXfmt5W6TOVTG`Hk4E*gnX>Z%Bzek-hnYK)g{pqo zxO)4z+TS3|J4>gd;o`j+rAUR_h;a_%$eC3yUe{o_vH%A@(B8oPDYF9cT7y&x$C}bt|x0;^u2wM`pwIPxcI& zJKjQ7%z~VYs#rp3CB-qxzJTuWHgCQv(e3@MOyoF7Hi#t!u?+3p9#RKzCe=ztW+@!g zlht@pZNYSg(g_RoZnG))$tJHKw!Q;%DQ8>c;#QA6Kz#b$*COW06=lX81m2i~^&Pw4H{d2DkQksMPZpw*xLh5hI4Y#Z6gtM8?hvBdYA5TboDJ5`;3z7Aa9mKf>f>sF{;}M&!OfSD8QeB}OIXY7x7z&c z5$a+kThB07H7@BvZQM%WP*Q=w=+9L=HkEK}KkiZGMQu~w3AeY*ow)&TMwd$^9I-DY zK4j1Rl||W4f5Z&@bf_mQk&>}C-l%_LHevGowzW~wTPM!F@(Z9Pt(Wp7b6HzVRKWX2 z?~)BCAB<45erN9rH$WO8rio&uP(0UClui~}a?e3Lk=%Hh*;QX}wV8Y?(*V0em|hqa zb_{)d$n{*trn96)(BTR>lBEWgy?a>5u#Jhz0YHFkRG zlN~c?!&>ZI<-4l(mjMfzTFR=-dpd}rbc_HGk0`U+E_r7DijC}oJd9A01rZkV7a6;1 ze1T9qBNMo*P#kLC=`vxdsg#tJYb8wlUq>?&#(Vwzw5?H7HnI$BQM!RV7klHZ5P4Nr zk34-$iJiZ67y@LBAKP#97O(0rAG_h641Tkk<~@+9)BApj{{s&(PxGc&0OMvN)D}|o zQ5(c>MkEX%>uLxpmU)>)<&~|-=BtL!nOMpLNCdqR%2^#+;0DRc1P2tr*YAVy8Kn~s0wzqY=rlU$X6Wf*1;btp? zx7CeU8|8jU(>mDdJLKp!T6C2f=C)6Mdm3!?q{;&L&aDb9OambM`FiEXZz z2XD1hKovDupwj`GH?lbOv#(HWe}fk?@AaMqFXm{O+bsM@hxDhNZcwu%hgo$MrB^xZ zl@d`y0{gAXzuAF!hr%CbnKs$RioN$7ZIqQ?%@)#b*%;ZlH7Ts`j;Kh9vW^}g z2*wmWTgcVWg7~QJ@Shc1f%(k@4WZTE35*2h=Ifrv7+#!fi?loWdMcGCURZ*gqj#L-iF2|HjC$uF^|9M2;;eAM zPWG@YNzX^>Mla!Yb_;~`3gdx?sTw-7rTvPBZpdOAG?_BzW0_~8qT}@2&8Euwg52eJ z<97I3x|lnBKPs6n%(E#y*-IBB>-hw)(Ao8-C4D|ehlFotiYkGg@zMLuEj24zbkLa|gjB!H#kK`0Hnu?rKMDilnqH{QDe+K|&FpcT2DlhqF#cIa3xhesdE&0o8rR7&q@Z(lt| zFRA1asQo!hbTL!1HvFN#lq8luzv6v%MTUEUGdhasraE8pO&;PV*A{3cQr+`rpJ;?o zmQngTU>pfhdHU4;xl$?6%e)V6E#s@)Lo%`^ont`U=9wsz=Zi*W~e^9Z82r;-p> zP)l1BF@QCwB_p6V%F$|kTv42tF*I21==w{*g>bx29kP!*AQ)C*X z5$AYfi0|kra`&8S>8kUQixQ4T4__fNVmBJ%Ny?o1nb1W)i%%{LYL>aI>g|!hAp;=+ zOK|YN9PZ$$ji`$!5;{DgoX(L<(+l{Kfk-hT?yzC*(sK-ad#-NyzW zzMROyb$oyge}%gQeKRbM&1Op)zB#q+K6Cr&GPryPjDY5CQH7Fk8{58l_PhD7nE-A5 zM`!<6J3%RI#leC04^H0)&Orf#{}$%m*yk$%KVZD7iL*p-gWABO`tM$<(6g=4Q%aN3 zpU6NeK7FY4es01SXgDAM)NW9Zrbh;1Wz;EP-Zx1F;9`uz*sxUS%O>H4orxkQ~#(tJ47B#vd{oXPjbQgo{JX=83?zDOzzW!v->k zUJ^oWhll+zI#x`X_5Dz6Xs`X77AKQbK#0#)Fk33F;%UKb9!y6HmyT&2&f()DhL}{J zCKVV$jSVodtZ~=&B|o%Iyoz#wU_>zygkoT)H^JO00r3Rsw|M`4KMb`zw0vqU(Jw|G ztG5?wXh-u}+*yv;kPT$3vax=7kILSLtAu_9)t!|KGB-IA0BS3qxg*?C_1qrVx?jrI zTO^Ot7<>aTl(ow4O>MVo0tNu%F#K)31Na0WAq_~Y^500v0a?ze|9W0!;~~rzj{oUzJQE+fm}Bi zaPnD5(>zkQ@@_-#BwBl;4^Egt=k~>46WDgNwY}(F*16!kU8y}#vxI5x;&&crtjB&D z^w?goIQQUOMzo%<+8{9qSx$4{`$$~T#bOkXLwNMhX-Abpr~gMHFS?!2lom@I+g_Ku zV>3HOi2xOfMf_JL9g_1$3FR59e++b5<2wbkp1&fCDbI)JA%%a_eW~t=RRIJ-hry9|Uj>KJ2=FL3a)V(7 z1j1ZBAs&2;pu_Pb`Ra)W`QVUQ4`DL#*Ux|9Nl`kT?pyZ(7dqXyp7OsHy?<6u{BK2< zN?Jdvh|&@|>o9HUlm308W#qSiG$-74KT-M$w>NJ(Y_R$>tReQM%Q5y#i{04|g9aoY zjJ~DWmU74Y4F8SY!NRAjuWkGfS{FUybfoyX+0M-Sf#)m#H29WgOVW>?r^U4VmIek%RM=df-g!x8h=Z(J@u~7*^0OJ zhl-v>Uf=XZuRdnf`6%m!`L3)7t1gKDGW?ciYw}NCr_2AaJy7r@;_8Nf5lYIqTMu^; ztENqbYGf-W{EE*y6?MX|SGa`lpwE$p?2Ju~%XkSdGqqm7=S^%xf>c3$dHTL0`Ti`j>bx(GK|3_u zrx^hBRC3cLGLXfE6`J4wxWuJ73|aw(b8=W86r$5BTT3&i2LNYKLyJDi8?c^wOSUxd z#t`C(^`-if{$&hS5wL}FKfnnOv4bHBCw!YK%n=%2XOdss^p<2875`Vui%BTnhqcN> zI)a$>isjzkD`L@LrYjo1FXE6OVUXVM@c60Bx9!JsSP z50d`zjND!W+jmh7F$q7<8E_hFV`h?i+V1+cIulJh4VtzmW!6tJ4=DaUTZFeXqCPQQ z2p-n{EJUkJ^e}*bW34~&!YRq*_7SVeBUVGV6mJNJ*2((L!UD5qIgQb6^{$KMPjSdDdue97 z8v^T`8F~KXff)2L3aV?Wd-n_%h-#{X=h3fKH{=eo%6;c|`isy0rN}{Bcounoe*E}7 znOKA$+yYwVy-N7{&x;!`=-KxOhx(@1P0L{?%swz&QTVek6kmb|PFI-Rb~jT5m^Fo? z(n24_mdByvJtj75j-b(L1UFQ!17>c+(l2gij~$}o!Dpwhe=hLdUzbZSqTtqR(4v63 z4R5cfDX{P;-?p^Lk|>W&Ho@Iy9rG{03?6YU{F+$(lD-f})jxz@m?I>c(YxSeJdkWQ zx8`O2tG-b)I&jqt!!a8GP3`BR|I|MyPfsvAvFq`6`s58WxmOVK`@Yqvxf#N%#LaVU zdeZxHvDxCYF-IT=R7=CPFHfhfm8Wkog8((nfXJ*VZS7oJxL`F(E>ec`zQDElW^z$# zl-pUv=1epB^J5>McMiRaK*_^+n-I%A=u|WL$t?F8#$7X#OX`E3#lufA?Tkga==Iju zk?oyuMUN;7rFeN%(E&uF);P79ER#@}C=}tPbCQCDO1SE{UB2=1RbnBN;-oR^z zSDlxuCS&vrB0m#eCR~6Hn$Dn=*-rl@zpJ0LpMfR)ol~-NNt%2uuq_Gj)PFY_y%Wi-ZdUMd30Go2~PesQ3xo(lSDfxC_ zdXl2$;r&7sde=&L!?53UxFWN&OJ5GOSQwFNl8xLJ?+m7CKXS>wh6kyN-w1XVp{_Oa z&Sr;<@~#2*40AZkJF(+~-C zB(ooTKJUQ$zpEQNw_=vF@4xM5e0*!Nm(AUCd~1BHy6B8dt;MYAnMiHcNmy=Yd(f_p z1aC{z8XpJ4eqSGLUixTsw6B$K&Ea>E`9|{!Ear+c&n%z-6Ep?yBbF85tcy%u>|pZ{ zY@P+rwb~VZtJY+fWR6Qm&rdz9s7ZpKa{}Qm(KZy!)#=zJ ze!8puk?Vxo7)Gur0dg)!ORQF`cRMICNN8wr6}T-W8G5hrPwCXN?1N%&xsN}}T>u`! z{0Gy`>$~*Ki3*R_v!fHRqY9iOGLPsQcX;`e?;%eh$RJK6Tp!Vg*=`#c9f&gi9eU>} z;5C=bR`xmD4gY*EZWU^ScYLRTIXiU`$W@#hzq0J!=KiNghQenC`5~khW=k_h8{A>p z|LyDfrQw?KgG=I0J#5565^iI%U*YKY`(u*>{PQ1K>_=qXNmckGtAnEc8Q@Cr>;53j6txmucXhgm#i zl~~?+(2M@E%C_XS-XkLu%!d;vKj8qm|JT1~ExZ-)E%(Apiw$Nk%+80rHeXIqMQ_S| zB?tKJ|0tkCib@MQHp=GZWTi!0tN%xfS?*AIe8ur|onnhBG(+GZsqTsY7aoJs4KY$a zx6u5*($inte=(1|+~`+;$*2mm%ISwMr%-^%#Av|+`Y7455!^0oR04Rk%A(=uI0 zPFb5lhX^e5HsMQ?Xmy8%hKKl`1h0ceg;GD`(D7}lDT1Y=pXp)l zwTpDgYeeoz)cN$y>A#`pzrR^~UEfkZ*gBo=)kZTqhW?cIYRJ6n1J<#xVj?}(9?6F2 zg`B|C|BXki``nlJ3*`1(6(3@5q?hRBdM)>N(OYH+L#Y1+{{>=PZP`asymNTJ1@a5; zFUH#kB+DGF0jV|ML~fC*1+i}Tm7%SQT{rzThL11BNb5c>hHMww61fv71Q(Uc0;r!D#M;UXd5)lxU}pL=MS1T*YFYgORZ^rGYSau z((Saoq#KH|baburNA*Z8Vd#GR-6(yMv8fAg0U9CAHpG8^>+KE9F%64F%gY__>})Uw z5T6c%27#UE-@{+$JaKKzzkNFNF|~bj4Lx1u*9UJT7?@XE9ftmx-F$RX-@fCY&HrGU zU^j=*dVAL>=zSTeq1x3sx96#tOw=;@HbRksilU+*m6%#x`f=fYhp6YXN??{Bz%TCNsN}+1;7UJe%ix&iS76QDeVUNsi8KkzAEE zmpEV3RxA5}RPNr4P6(v-)gh|vS-Mm#&Mr7K6))wcj3buf`{0!QZxK|fDy{Epf_a5D z4Y~=ZtuuZ%(5FJ_fv&%uN*p=zEU5C#9l{crwkD8Bi%prQs(ro9rjn z2+kBZE~p5mJpWW0Z=THc_Mg=+C4M5~ELjbUOKEG4oP(zNw&wfZG3UYzElH)9+&>O-`? zeMbcuQJP0bTTOTx!7Q?|B9-@OUJ~~B)znqzTHkiPRa50ckbx8T?cX0q>^mFGM z_T2-AGo=84zvARCh0T1KB&rGHSFz{)?M z%`_KX>Tfe2wSV)@4(V8ORnp(MwKaEsl~t z+-{3~7^i%SE)R(=KsLD6HmeduRGR%PtPto+jGg8EstqQBzn7&hQcbyUG1(Fa>dPeVIlIx*A&+nISn||M=y(xZB1MJjAEI0Z}qNI_>2L|J0^f)qAzThuA<`( zj0FP77up)|cRUw4I6|OdmH_VG@F1P;WAw%Pn4=*up%cTHhUS|7n7b~sdn55kc^3I| z$(sjA_Xu@x2Kgo>@eT>_#oXA{-rKLuTNt3@8=*&cNY+qOWj8Kdo8@CmhVoEvR~bvy zkw+K3?CKSQsWC7Ga7KU62g~26f*IBpw;)tx9+ieUwKFUShz<@4{@d#Nud*0pfQv0J zOMo&YMeb9T5dsrJ!Jg-ad+P2f4jmji;-EP>gLvFT#4rnoKJCp&!2 z7w(vO+eZPBOP}LaAfV+>j&Rfkg)yZ;r7=4ZS}ncMyTpC!Qej+Ga8;ZIXO|SDDN0V##6}*78_^^G+*k4s>#}4TH&nI1r0n9LIrd5e;|eX7}=FV?lMU zQjqjljsQz|R#p3u0JaujtG;`$PyL9;0IY!Qr(Z$>8xU@8kx7ZE{Ge0^ zU3?5bWyl;by5QTfL*B%lcPu}z@^y&y_OQ8j(nSQv;!*sy9TjXlXJ;kfAHlQw3J?1z z*nRU3n2Kl;HY@IbjRd)F0p3=~KlT$Zx9Z25{(es(SB?9qpQa447#O4WLu$oKpQh&0RJ^w8T zGccyRM>vy+H&XD(Cia!8gvC~QPq%EvR-)&Kk8C7TG9{8^D2$Rr>OWnDo2Ba3?l@BR zF;o|YK@+81YJWXcEk5GillXISJ6P4kzH`=glwb8&J;(SChRiZP zGo`K3+TS*?;tI8Xrkhay_>;2{!8HY!h$dzn8(Lz`b{{QakVL0$mtfHsuojfi{O*X7 z-mi{~2DGE2<7p>~g==tXMSXx{sU>CW?T^(J#|M%gvp!V3zyAR@o8sURK#Bj4a44=? zchCShthjLZ4cgfNG_+&~rxqoajRw}}*HQK;*9Bi3<=v&cLA%%(D2IEv@dYa!&wtvp zReq3l;qJnu#4^gnPYc&1*V`Y*pHrYAO3?roeR#;HGS3set_hpbo3t+jT1Ez`)#R!% zKx2Iuq%xt}L{L2GtgDqMcYNyLfa>W`(@^%FF_692y)$y?%h=_eWF|xtgRo9^EO_X$ z+`tbP>J;vm4Y?%+$dxEpm)%^hsntk8vD9xBN4PTmH}I;NB#~0wy0OncICQ>NxfGu8 z1soAT>xD%{2tA%Wa?;6+S-m#T@%Tu+rL>|ruQZD8z>GL=Q;{MG5HF(WUoy7mUS%i3 za}7kc)pzE)%FDg!Ms8;iJ9zk}n-3q8E6TR*JE32MDP%7MfFjiLfk`Z9`?rlBm(0zI zisUE6#AofCp!}G0%n-yxMWgQ@3@l<=^IB}mPPiAarJaNu}3o5GKX82jik zP@NSo@RSN;G6nHoF|TC4%6X1STOBXW9ll61ONvjkQHpMdi3}(#k1V(MU=x-i1;XhT$tVK_q;;Gf0GIweRfIB67K_P@ylrs&o` z@oe-hN-*v4=99CN_?Z^RFE%)KMmV+?;#ZZY38B;&;SzKDhg4CfM^=k_n7?50g87ac zO*l?*YTD6N@tIoT_VN7v*UO@xxkmXr#DvE^TS^@vr=-YJWpM&vVA#fKJO8jCQ7}^6 z5ak~s2xJ+hlZXQ+!;9v{Zv>Ai4PHk=bbYbKEu|wU_jvk1^>3tsomGzZn6@1m%f~w= z3A5&IVvz~c=I5eB;e6q@K2zG-;W7XCq=$2%lpp2frfB0=HFn&a>E`=I#f$uL?qR~vUU#gUlw zG=uLVNja91G~gGQ>*!T#nBPUTC~Xp@0Ejiu7iatr<%oEiZ%w;=1W_Q4sDS~f<)MX+ zkWmcK-I7%%#d^nx`8Lr}EOR|&YEgOl%Im!p<|D29KLqI1JYqs{=E5qUW^SOQ(q+sLZ;%db-&q7J1Cyhya;JCe#DvwOx00S{>cr}6zCPfRqzF8Cg` zC&_bPm$)TmS^n>SRq2amRYRGlmfF6ty(;`Q`;Q)hU}F-mh<&C!&9HUz0BgVW=F)ne z)lidqlPWb<{lM?dBYIS1yLE;3|i$N2{U*zr8e`G&Hy4D^u-><-md) z`WVew7nVxHr9ob)0^op#)w41xlXiSe7JJUk`{UC%Q;`96uBC_maGFwN5HvC?^ITAO z@~%^)_u*5ol&dZ;x%UQp0?g_J=7CBj{>hzr@pXfqJXBa=?f9L|D>fodteB%bVU07} zmsrYWiG3Pcq(Q2;klf+Hv6+Ug19P z6r@s5xlec8+J8;ex|iYIHH;Bg|Mug6I~f+6L@S|SEQFe4-bTiQ47AK zkE{H>B&*)dD=LZzmWq^HZQv;aM2IxU@M}uOjLnqA)KPq@!H!=6wwaIrs^s!ZpISW) z$9*Es11gv0Zv>d<=CS3Hd&;LO2XX4^xk>Od%y~h&n%JLRAFLCg7MZE*_=+|spm4O` zo{RS4CJODJ!G39!o6jhiRhTQ+eA!V#C{uP1AAm#Df-Cd2$^Yogz-sn0G=`hJ5&L{^ z2fU>+HwwC^q}7KCqr~{-wkPtUJl!PGsaxQ);$#yP$b<>d33HrPcD)ZALP(F~p)IV< z#2PNjqVWp||4pPKWAgW`AL+adzAI>l6fxI-k%sKMW6CN7)i*ze*eQcmg5S5zC?H%5+R8uOMCZtW8DFWZ#&-+{YWWlcoNhb%e{lg`?B}{r{G&U_v&1-? zRl#7Bcp-fMAtJsXtfOlCjpN2DUAlPg;!w6LqUD4MQxo$ZqFzTn42r*~Xn7vDTcr}5 z!yTd6<-rKYxu1h zcj+NiJG8cKIE?Wq6k)UTf3KR6rTO2TgpV6A>t+%GQTV@b9@}GHdx%DsoZ3j7L-0%5 zm*q>ZKch~<8b6SYkPjT;QUA)K*WYm1OwH=qdgfI=m||#_?CId|$dBsnSX4;Fow!J# z^~RTOFs=1xJb1W(*x=Uq7)?Y7uBjR>xKK=&m?s6mez%Hi9fGq7L);Js&OhhPujUpp z&A)5;N9J)ynAUyBkv;U~O5>+kXV51mx9GnrRmF-mvRwv9*C&yZd+KsJ z7U6mCY5B8=@O1A0T%cEEm|J+hS1K}4z$J`?antYU5ASP+Sq|}MqKdCA3)7tA@>wXK z7tbJnAQAlo<3ga?PeGG`u%y0vGDID!bqCT{G5tVY z?~hzDS;0|8tcp}Hf%pB(P=itpERUqmo1e%i<4bEWqkx9``X@DV4=)r7Ka-tOtmlu5 z@&(3rnpr0^mhmuE*rh;U+9(SROuAppSt_f@%_}T)0H}o+SwL|(9Ga0do-=8P)5%aFJx~H<-hicUob-!7T2C*)1;3ZWZl7p z$VMnc#Fn+%O-c#xEh=xzG0bw1==KXSzoAIn4kY2OHc9>|jUZQrS$Dop+oRTP7%|XH zbwNfYH9$)U07RdcbjyJV-tG3Im&mYOJju|Aqdfr>NjkiQV>^mXBkQ2e{R2N1lJce% z0gSTpyloN-LkFg%YsJUXsv0V*w(b2o;Ie3edcNR!$hWE@qK(I^O|7flHfTKpZ1?@S z=|OkER`}6h6h>3g%zF%CJgbRn2+ zMKW~|frk=6uR_*~lx7`k zRRYFsa-{=ymtq`1!Z#v`y?U(xmpJBYg05Ld)r3i6HD+St3lyT1coOL$?F!a3oIqXy zs+}~Nt@Ck(&&+uetKXLoD?cmgwzvmzr`d6l+K+TcuA?HZ?{i|#(dC(mpl&wKUYSbh zTW|r!-f)WRqf{Xzj(MKFuU)l7pmT1>+033hQ4;|`u=Fzik*Q4g(yS>(wWN6T9;tD; zL`8@vs|`!cJbUi^^coOuHH=|gqwdp(5yYd8`PkO8WeMeUXAyhbxlQ*fYFYE4f_|7xg4^+;f|OEXsvr$vcahcxIfN{$v5n{WaS+dZ09Y2}ni!`O9%w2mWF zb$vcB?&3QV9YfDmCm)DO(G)E%5^coQ0^&Nw%4jB1Mi8$g#4@=dD+qnM6@v8<74S+? zj}LM}RYke8A1>!#k+(Mw{kXiikM#6`u0Des=|Pgskk@{Jez|NpTr}Y#w4)9CXJw zovI?`;vukffHIC&x}Rk;WCKHSd!UoH@kHrRric`7SxRfCGsBe3Vt zzv~A8b3;ID_o^>B=L2zgWf zOfH)+BQ8GyN;oy4fKOXNKSaAZ^k`Q&Qx=u4;8DqT$CsTsGZ}v*Bfei^21!zi9`zTm zj3`3B=HER=G;X$i$&SvBn0#!u!Hgd^T<0*?^6*ca$QM@3Gh%&s*TC6ncY|>glEoO9 zr8(=nGVf5##Y@Hk{SgO)3BKP{n8ts@=B}~<)Dz&pb^GRrlX;@jP(y#YE)nscn2oIq@X!yuWdHLA;4go zS19iu&Fm&ri5QIKW1Qb#r8J5$#?DGf)%xZ-WIy_^>twrMz(Q!@ZqG1+sl&9Y$SY#e zEX#f1yaT|}#PG5jW=f*GH=Kwwb$;GHLG$||l zYX1HdeEv5mW+_%sm>9H5wz>~$4)P&{iExd8#hSjw;vAKf$HfEvWmo%D`7F=cJOE*p ziOH5apS5e{G1?Ff&siaE6Uc|6)OM9dkoOL1%9I zuB^MNIH!aA>WP^V0n-{g#4%Vel^{I2CF}ISCOBE@`T|MQBWe8+`d+fz8~sWENM%PR z$VHF4IYpvx+u?2HRnBG(exK}0BZ01+U70m~Y#lI*udaBf{UWjDeT^5d`#_piVy9gD z&)*%msyu|b-QNu-)~X5xaaQIH_Jw=u)auICOPPDbtth&AtJDFo#8g&kKwN^b(a6)j zF-l@r4#4j-YxQ;6BV^;GkFq86yBd?yoNr+OWVx-P!2?4k1V;{P_5lq?cH58~TkAxm zB~vKEt(-bT1>n#slP>nseuq28VxRQ+F0}~zzZrmY?J|?y1;7Nsq{0l)*Jlsju$-9hM(#o7MDC-{_U6yB9SN5_qFqScSu4n+lo21GqMye?D*KJvF} zOgWEqQ+IwIv&wZwubfX~b6me%vCCF*{sc8&U)Sy$`i)y}V#C=|wY-xXBoeMC=#iY+ z=;@OKvPvwkDzfykGNmB}A*wnw4%Y(A`7nuAAu z%T~ zbbb7xzkpmBukGPuIPy)KsN)8VHsXm6k+%jbItjAvqDBM@t=dHpakc#o!o6di1kvi? z%_#Lw*-jR4h^gKyl5`N*Hv17G!{ll+(uma_f~Yw01(d&zCxPA1oRUNBjNEp8o2hRI zuuo2vb3@h!@!0$10yDaa9zq+#zlrDZ7rH|$mW}tgU9C`8XqgM4kO5y07a{;3xVA&b z5w7jj?`w-9x;odIc4~5IJ zyAb6r+^No5)b6N_s(L5Lj?C}b_jCQ`utgCU@qz_0;!CS<+@x(>Lom5S9ghjrrEZ=a z*&3_d`*2{J@O(3RNG37N_4$)WmU%v|%+mB6h*qxgY1?iUf4t)_ujAd9&F*`Jy;Fw{ zuCyCi_m4N=NsQ`^taA|OE%E4x=xATv*q-2HN0vkQ^~Ssr=a>L4k%GP5{=!(oUen;c z+xOov^6YN5;$G<{CmQ0VdJ}1_AfgYk-@<%;6m|1P#JaU(VG9(SOn1LXLr_B!6mh`L zOd@TEs;A?+V16t`Qe`4n*+SP`+hl|S!WX9#Se4y;)Zi0eFcK#V4pKy;L14w zipqM3Ntu1fCT1$d!@db?=aWQBMpl`1 zRRUc@{hQKk&7$1lZ!TBwtP5gQ6TR$FeiaAHU*0fwx@P@|w-(dz0!5ZS(_3JC>Hg~$ z{UOHRWZF|0vrb&B_NFeXq1XO+cykWHgJT$%;n*CxBfA#brXLG3=&P+;Xi#sQY6_$} ziX{E{7J_I!3bewN;_m2;w1WYXPZd)i|9sj7;V2{k5bccC+RL^uSo!nCEtCLnQ4T8} zoqGY%heV+k7*C2>2ft^p0=sZCQ?|HAr}VoSuZ+v*(<62}`m1k7tTy#w?WVJoA$Ebn zTkMXL@C~Mn(#_J{A#iUIs4YxLa+{zJJ-TpQa#yb%B$zYVNWE$Yot3?7HA;9}Ph&g3 zb73kv=sX?OrcS+!u9xhf6Z#suS?pYRJ3XgX_MD~OPTxhB?4<8n-9pyuI_P>_x6WGF z33t$02GLpz?4omb)4_cY7AQCV`5M&Tu#+l|g>Jia>7>$BE|d37;CC^#Lw&$7LGW2d zkv$=Z)!mQn?XIft^*#6+zQ0;KOy~=U@chP}Fo^Hx#*dM8*DhL#v=C) zKhbl?zA;;Xi~v$!I{lCOqjIhKj;}9%MmWB8=_mF8!C>UAav;tc z2#s3*%r}@iD3G{m?{glqg%{@ZEJ_F#3joK*5%zeWowU4DCz?wpVS~;=O!~g(tbuVk z`BBQy*@}xJs;Jpy^ZuU?3+KxIU|iK980Y^5x%X_HCuJV5-eyU&j0-myIEF9{nGLz0*$_?2zZZh-HQ%=U{R0jLoCcE=o21`N&d>d91j zyd7TPrnq6}iWE!2TQVLr_;MF#%rshEI4bx2-vMsVs|2Pnq&V-(7!Q4+Pe z>_{<;Io-TOgI%y+B!}IUAeX> zH42cA)NpHsi{>aA=L_FWG7Hwdw-utIe-% zmWA1ey*{ABl}z^DPmn7k4f8TVN!0Y%CYUoCMb^egSAOi31uH>yf}?SdmTSwGbOv+B z30TuzvT?paFGPLq6Fn0`;+R)qNb~AIEO3^QIulAA?{nVNZ1nK7@g>=d&0y2xbuTLS z8Ern+NQ${GjAnG+)tSC|y>Kusuhb~%ueR~`#yh#u!Z(-K1K>Hg_g(P$oDYV@=l(vX zA^Ss)u`*JfVDEvUWOisO7iWs{;3q@bmgTcsg$p9Qbz^5jFK#(vadcSL6WSwUVtU}uEcNHj zMZz6Yvsx%rD}{d&6u$`mC=@|7<-U^3=P7(Fq$+d>L-@_=7w@jhzLq+zo)QHB6MWrg zs78+PS@cz^rm2EccZ4ofej`Z5IHH=2f@K-s36H-52|VQtK@{2;eS(*}@e;*HfaLY~ zYg0=eCEU_Y^CYKf#^c<#=v>EDdn}r7En6b!g=q?RN136qXF72gc<|(fYn_JkyTjUd zUw{9%H{$RH{m9jiD!&NiVvl-$m}dmni|f;38?fH(_{4k%oZgS?78uC)o{8{tC-fKp z4D%B3{q>2K0nZlzfaW2|CRlQQ%@yfm!-O+G$!S(Y@^jUDIZpI`t48`PymO%l_(1q& z=9g%m8un(rUxBETaCXuLP>L2nmtIa@6XunY9H#p+1vx zt$J-LgYD=DJ1SKqKAO1+sMHu

85Bpj^1#X5hZ(dbIxPB=_p$=xnrJj{c11tGq1^>$_0} zz#=Wj7T4bQETOVjebrjq2l>x(-A`cs*xa4SW#{Dk=VAGVuc9o=IPs zO(M>prwcddDWg6EpBt#r=3Haqw9#O=kV;fvA4x*r6)2%F5&c z|Ktjdg$dWvgv+HN)%Sa8kYmzp6N@%tgJxw*uIU;L`*@K>L01X=W&%X>Dsmk9VwL); z+EA_tjsCA%VNi0Cy8n7=HvYG$*$$yYcZUtQ26nT1^N-?#x=Sqa&AwE6Gd*4Q2McU` zkVq%$MUrmh#yDM{sF~_=QNjq#sW6wyfOOgE{dxNdQnkjp_M}!JqAJ}lM!Rd3>{%Yp zwOYU;pe@qg>MF1MkZRjLeseV-zWIo^3;7Y@)@hf6Bn5ZR^PmD9ICm@jhzRYrgm&}y zlY?im-#0h`(>^?)WAV=*rHd_{*mljRK1NNj(-DX|F0svY32=)cMxXP$C3{~@=75Adkdv6doGZM5lCssz8&3?;nigae;$U?BiR zsNzvAoU$>}B=qQMFxriH00ex_F6R=l@y^PalUXwd`94^oI_8N@yWqFR2f))$W2rM@ zzxzq4z!yBg&Cdu<_EJ-PLZUPOhO*lluiZak*{$Lg9*?Glv^gC-583mm7k;8zTCx>p zrofY5PUJ)}_v1^1r5U}1`VHbEEp>ak<0X?0hJr=TzZcHJC`(x=L|Th7M=MAsS+|Zg zr&+#Nd|aMUj55U_wqCoD58mL?B)ech!{9Xo8 zgy-N7{13f*uNhN9Rem}ivlX3fQm77LC!n(JDot4vhu{?#t}{f7x!)ZYyh?KB})jN4*dadc`HOVcO%o279cq0{x z)U)Vm;@KjFuq3%;Z%*kzthMMD>&7MM_$YI4*nVuB#>m9Geb#Zv9(zrQdjojeAux2A zdE%#xYVmY@^P1aDdJV4Lw?uoZghJ*i=A{T%4%+`!$NfuG*?*(2#Ccr~g;#u|IypY| z#^C!A7Sc;X66yBS|N5847D3!T>=AVv@TVph%DgR@B|K#(IJQ@_5=C&}INS6E?&Ge7 zWFovPSj`C z!V}cpL`5f27*~OjjP4h%`7M?c35Z}J5JuE6oDG-lB z-9(5-RBbZAZf~Q2I3icJT}DK#XhG_^Aq#oLOF6hO{muKSpllN{sJR8w3)6_2{Q%QO zu{}48sNaT_VYO*QRR)n7%%%(m5fvdsIEyI6=#B~9#koX%7WU$2aSD;Wmnh!yDI`E1 z3c{hQ*pT10lQTNc8Bmq^iKAtTBd*S=;c{}h>732Opm^@a>EOvwP^lHJ(dEAGZEphH zbtjdp#GvHU$|t>Qj*q0qg* zULsDarcS}}wCr>g)8mZ4zw<|DCv=RGM)lFm)X&^J zqE56lXAi6^yq~9MI|6~q1;V@vLq%6r$j-+Hr=+2OzNM`)x;jOjq`!FlmtySdm|na{ zTW3bqLksn$tM@pmOCTFN_CPUFFD|+Njk$?k$|==r7ZU>ezmXT~*+rOa3I|xjEz$SZ zYdw{sg~~;Kprq(c&?FNE)tav;*V5EbQm$VW?4nY9VQF)<$Y9usrz+*a#%)NRZ7V?J zna^8h%Hk!WYXss79$Z$AyfO`zk1cgy!UH%|T>>Aj;8Am-vS9H5p2v;n2_+NFdyqVt zL@7Z%>BkHGIa!lVal;LB-&2V5GT1UalDc{Ip>vSxD;U|o2Kju~LKm)`p^=)<@x7yI zaTcKn%9gA_Z0W8fHB1^yUVnlj#T_sz=)&Lp{XuS7S>>HY@om|DfhtOo?lCS`i zMsLnXzKnx>Gxb~)9GRjiAJRart=(5!?~Oqg0UDk#Q* zZ*aj8_$vzqi0DyPd5dxPL5l1?_ZyS6i0V2A3s}ak!R>?iTGT}#OfrjU9sOZHIe#F3 zv>wqcN!h{P$@do*=a|`tlkO_4W4OgJ==lqb9Fi$9sDjq zejI{ykUFiU7P(iOY5$I--WXG*_h!6Fe3JnYkoTg@?A@C!|2!)S|AR?##A)@Us;aye z^vm1ICr76$`X#>KRF+Wupb?fjtpn=FTi1MpK2VI>p5C6O&ap+?jnkvF5@N{nU7+8T z4;tF&_52JY4Oq%!gYVoU6v9u%*0#nz@1iE|R9Ft%Zc%>lL2YY-Lc}dUdbUd=Lpo#| z1y%W{kh)7iJsj1gZrKe>p~cGYu|MIr(ywWg%)4iH-Qh zLzE#+^y2EGq+L^LG*dd2B3C&pgncK>BNFuJ;FA#Jm`-1_JofVWE;RjOwea?kyMGY= z!#N_G{vfeD-S2qUWp^IQQM-Yme2z2ZtK&Wek-7-1a;pSiWa%WCTr_KTNwj0^0Hf!K z6i+_)Z1|y8kANc(ds@HhVe0H2`}H?AWZNf?JV%PqD%R}B0EUT!iVH{h*8$fDY2^?2eVUovUxv+aoO0n;dOkp$WYAI`iZ(1!Ai9AJ=-phAt|DNO&xXZlRw0G? z3ht82@XTJ8n#_c$f_);yzA!%1VQ>|0jAsH;nMWd8b1sr)Ha-V3(NDR17YD4`Y z#B(2@g-U<*nxTCf;mE$}3-bO8kYaKxTlaR=mQU4QdC+i6OMV9$`nQw5m^Ct;LZYr1 zc5j3FTz&hXDKQ_*6IQE3eONN*{18$=%ml zWhEAX3@_t*dnB|@T{ER;?=pv&^9izJ~I=YYr=hxbceSg&zW(-N*^L@ zkLZk>JOpF9_EiA&^RfsD{LgIT(RucZ#5)mAF8dQw9O5d;r8k^EdZSwvE7QUS>v9}s zr?sft#UO5z_SyAf;@o#>5@R8Gl$v`m_TWpd5y@|4Fz)t?%ea%aSJ*FIzclA5Kz#@8 zVRq@^G&f7%#b{cg=Ga{OS`x5QNW|SveDc>Or-*Fsxa+{vn4%GVh#o!j0q5LTL0xp^cB#S!-e>a zz_Uijx&ED!THj-ha9q~xKLJu((C&>V;nBPwCVAM;h(CKk6&4Yygc`G4vA=0AdgKT=l=rlWLX zfVpH{^XdZlAA-F2;Z&?fVZPbWN?wy#rJ^t|DzGwR=Fy1O`5H}Q_xyGi{I^rjN*1ze z)`iHPtLfsWsPdrKT-prU5ae8$Qmom27VNt{_67O6I26~ya5Tj3C+9%SSWr~8%CI(H z8&>9(o9UQqo$7yp`Ewe8R%NX!1rc zxbgjFd;+}!-2w%^kvPN|sSnpL%+Jr$A6n`EaY;Q6g+qa1C8pM{k_$ZGl!D-hHlidoBGGbiCPG5sg%q1-QRv|-QH~NR=IG?!qlxLWJDFkU! z=EC3uot(sG49qq6RyCGoo$j7L%+Ed@2vpc107F|l@Y(slW8n#BAZxesQlXQ~@xTO7 zR_KJ1A!M_iIh%#NN;{9_6t-RhiKsP=cM^)VA+ML(tx zK(WJbBao;RHj0hLU=4F{Ky0|-9EUe$o3aT+EE~%v8JQZsAyX{*D{R$1cIb9kmH1Uk z@4Jzkp#v-Pi$?0gl|icT_ZY+-<5va9g4T8uQyEHj#LRrNtqf12LuAO^!m|HcG{>rY zw)A!hcHek%!#(t>K`#Ds?mcwqoMH^n2IXweG0R14dJh`2eUJxc$tgl)!}%OQIeX1% zALI_ipfhg<_({fG6k3M(XlZ5(yem?GoxnwhS;q{91dbzSi|=NqE~8=e;B03X8L=$y zqf3eLW`wJwLfh7O{i*h?B@Rc~{}Y|#CM3pi+_&Ibo3lOKoG!+?b3O4Bgb6S2@k4QW z{FN-cgJ0?|L;3$rI!<3LBrKD>|LwL2-mvYz_Xj-s-yhEFTDx)FfrX$~)Ika6Fd#Qq zT6eT|6=^$uB-rcdeQsfW{%#-c&w)V+O9ionKz#X-h`NHLvX8}SQb?!?2qRM7-6z9N zNa{%HLK2FPAD5+&G-@3ct*Rr5*dZjduZm_(5owPJ(^;=dBlXQ{ZUjD&G-QNM$W1p~ z@wDFle~>txG$jFr`0-aziY}F;F$P4FK)Cyl=%1o6CF-*_oTNx%8iv7%#?(b55x0nh zV?*TI_PPf|>i-DvGZe7sK6epG)Nkw2!u?6r!S2>8N+)%N)%74;RaU(nywcP%q*X6> z|9k3T`O6mto}E0H%YCusVQc^Ko{! zRC%4Km#oLgQNLyEI6pYa+$VomdEl8q(MBXPn7WFj*R5C`%-&4m%IeUADdG(z>gs_M zOwI6Wy||f#Mr>%*tk&Cg;wHH3b(=_bDuhknMuRh5=BSpEpr-%HJd$J^NZe+Ucok{Y zbOo}B1U079U?~aEBqQ{2qM{Lk%NzBI`;zr~)~DVSV2xkPc9>QMw>y1Jg-Lxtk-s$I zjVtDbCZK&}`B8%8Iot1MGSgo1an_rDuzm))TMD>KXtG?rlidDa?K0#gMXPGR@;zUH zZow|y=>#lw*gcE#aFOfPpGe;Nv<2cj9K80ArCn_#Ut4ym8qGCEZ{P{5Y_Q zfyP^eF;#9D;0-k#XY)Sv%R9NRdm4hlFN*hDR6$gQ-qU$Eq{bQ8{j5Dr3FIqen0nXW$-GJwN0}r zlo`N0vh;wmQk#>0RaM`NY8{B`(0Or9K76-ye_{Grn3qnNwITf7jQ1YnIZcLf(c9G7 z^ot|Qs!$w(+ip<%+Ep5%{)3os9jA52g+6(%+E;Gv`l&Z!`;FBeLujouq{G>dmhYjwW(T zjCLD$5%v}yGaAP@Tos8H)Ussa%d`(i;XjV- zO-LEJg2`LZg{?AQdn9o^x$|2`N@0Ol=0v82#bw;bq(gV#zg(OFe5L-Ka@jFBTgcxg zQWjpjJW`Sv92uOH{LQ^+y2yRWr(}2@#Zj^WHMgy>RF*%9II?drVlW|N-J4e_Cgo+% z)|#231xNn3Z3yQTl*xwbuixJ#SJEzlLlXwY7W@e{+rrK@crvFR zK>UBz`roCiS~u@G>|yX@C~rKSFf@xV#W@rF0YDr<3z$aiW$$Uee$`O>yOEhnE%sTw zd>#$E9NZ#zd1CapRP2C&yNn>&6t<*7WDzHaz?lbx2b~8H)s=YV|$Z zwez!9WnEeazF{wV6&8{mzN9bvT(+p)*=fCWg1DH#Q(hz;YMHQwE|Me{NxrMG80l{k z?}1{yBz7eY=x3gpx@h5JF3#cS1)55_%H|0)hn+KoF#bBEniSp%>AhsE9y< ziXyh4tD+(aMa6Y@jf#kk1ZCGQvAaJ@zWB`_Iddk-$vJuFymO!X+;hXYZ}&@M&c> zH)YJs%)1116oGnV9`T;>NRRfN$@;!UXS0e3dm z;x8b)3u@(rfg^(K;utB5YHFz8o0Y{>R+T16#a`5Fq58dIA0sAgjH4Q>U@e|;0`oAT zipSmaqg<3**f-h#sl=D0FT*g+I7*-gfdWn(BG@^Um+1KA-rH#Qn4QL|xJH6vWhQXI z9~YdJTTbSXvej#rt_N?02pzY z3W;53Ru-RIJ9Mf??|crhmM>~1dob>SUn|cfN~w9pr`G{_K!x)9S*MNm#tsM|;dumY zhq3DiLx_vMR?k8_+apk`$J*=1PK|x(j+u;$%y21Odp?e+tw!EN?Cx;nVsMR{@lR;u z6-SKv5%Y&D#Fdome`2e6Lq>Sw=);R~9gjCj((&koIv9`Fsc5@vJN+9gy6bPxnv2c( zM?6!?#+Ds#*Q+5Q!OLTMHZ{8;0`JmFDCta>v^ z;DEX}ldWfRh(xoQG+%TZKGImFf8>O`^25}@fot@Coi!}&5S5s;{h~Ylq zum@GuAl2B%-0G6<`U=XsP>#D~3P>fhj4B07a}(KNd4GntKBNpYseagS_e+ptrqcxX z#2Mo+F&(tM<*XZe+F7Nhm*Lo%(7ob7nv3zD&g)H_#Mij5cK@5jG{s~|Hc@uF%WU$^ z@W=0&MLA#ci~KZ(TVw75Y^KDMjlVHjaT+@F;BhVPW{MdB^+-mkRzV^2#b+ksFy=aq zKF65j2dWZlr`D){U$2}@kc8H31aXgTjwg#I##Etnn}!S5N1X#YmrHW|?6-#2rZFVL zdfCW%vs`DQ)f#*DF=H$gqm4?B9lqs{Q>_qTG{Z9 zlq^xjwTF1I1OWJZ8mNKdu(VV<7Uf_V6)0#D8_BJ4mgHgkXN1j5ud-Uo7P!Hw!IN1% zwveC9Y5{#W2o=d9KQHte@b0c=ua^I9 zW5-b9Qpvl?*F;5+nu|JmRW+AD{Y=A8C{UPNeW}OD(y3bFTMpt~r>>Wo6kV#hU8Wnn z{AaOXsZiH=xTNf(fcJ(blW3g{2MtA8SMsaJ9B$O%Ilmu8f|(n&R$UvVQKE}0t`oE- z%Qs3%tIuC%X$dnY&rT{o)~k+jGenDB}fU~1LTchW}8YMyPU7M67LnTtsE@8tQ&27rK~mcI_*(k zLlH>qp`{s~sJ&KO$6ntBNbP)Vq2Ko-&|&)o?Togdz!-zhym~Enc|C&lu$9d)I1p?@ z(ahpZEb0TE=Q4S(Y$bwL05SLAQ!NE+&$J`%uUAll+$|=>wdXfp;*v;2GsWh%@fs!& zj9X7~Mlco9`jm0eD6ekmcrun>y`NJfHV6@=j-$pDs+BmAtUl!WY8+DTSZ5r!RWie< zSNIuj&Z}Ok7P{!Wi&rc7srgw5rldYJY|;(K2b|xkpo{UYB#($Ql`BSqeJuF{`ivk} zhnwXSKFbxi)omJ3fV6mq2hIUax8y6B`16c(>emdcxPc-GX)KIyq6puLH@Dj_Omi3! z3nm#x3OJHOh{W{`H0^-Ha0)=v#uP{6R1vtQhlpw+8z+pX&?0g7Mm7#8xXUPUV3f)= zz4FLGnk&#Joxvr!5)i@&uAdOZTNIjrRzO~VS1v4NByBUaVi6*#dEn~;QiKC+3x zktgSZswmGq^IQ z3^?rb?DBAKo-S2EFnO@eNh;eeuW4_w9aOB~X!>`TCWOV5oRQ+2A09ME!kcqjz>cG% zzcAp`?MMHr5Z>^I{~5P(8ICBb(To1r%ZM!@ojwhUK%mg@dB25*#78wG#z6Tm1-Y3c7{Gr~P8>vI;BV7C^u1 zV6d_H$9Om_h@53&{Bn~T`T|=*?_{9sF*v6CKJTG*=G%f%jYY3Kbhp@8czdjy_W25P zZs-3-Ho5vpzQqntK16jsfmvAM@|#JL&U4U=O1}G6$KDL0#u}TaV?H+C%~`vNC|eH7 zT#b8CT1m)!Q>(SgH&Nv|WlI()v`p-y>>FpiyiY$kwLN+*>LHH$w|~?=V(v3yIRUj7 z^*{6Cl7nwixx&am1_alj!#6{84;$OkjpmI!wm^*_Z`=L3S(ll^N1$ZrI_-me}o%A@3F5nN7mJDX*|APeq1*WGvRPa z>*dovy&CE}PK_!=6VmhaGWTq8aZXv>@rkjCiu}+NZI?qXtbml`tt(^y8Lt0b zu#jX_llCWf^P5y@N#=<#{Zyl+QPn@R%?%Zp-f}`7_b*vOApWMT1aSPXn5pcUBqJcSdt^e(qoQCuuS}3-HuVFb(Vd!HGlTe;197* zulmp0hvzjRP6V?8qvx*#*xFAB+gGk6?w)a(h{7)17EIu^GL_RA`qx+prmW!7vRn8* zvwhmjVvL~Tc|v~z`mcp75-A#a79hK{KWBYB{DhWrMH@7FXmION{Xg84dNG)1Fph1? zbZ?|z@wy+WmpWoA(~30buAn1L`!o7ylwpKtc6G+uen!~rOdP(Zkqk5X^I;(DmaWNu zGn89hvkk$*=` zfk$kQdNe*&!}-}CGl(JgtgI72qmI|yyJ5aps#v<{S>zImtodcQ6 z0L5->-eCk&DBNm|ALOfGbVYVa17zs;BTYE3W9~nX>p%*xddszFK83w;@&9zSuY##tf3%lelP7$P2R&rf^hZ&7|~w3=}(T--%-y zk#zfOgXLRcip20H`{G7h5SU};GWr*>{SHh?G27wGTp*T7z(Xg+#q3^r;Ls=+RJBv$ zxf_MVOM+>IR3!0U`-2M53h7&zYwq6KPnGPM*~{N)8hlW- zlSx7T7cxg{#&IK!4yw2v%oZGTEiKIqArw@UUe5>)4?o(xX9PWIIa8gi3fcF8d9NFqMF#9cMB#c3{9pM0vPLAo^rEm+_jB)xKr(GwTQ)dNHhBHRAEUOJ+p9we;x_m1S~O;Q&^pXBPQCB zYh6z3Oz7$wDIPq_Nym{^o9TPvm4Uadv@eB4BPzf){8|V#KJPt?bN_l8e6aH9rR>Zf zx<>m=YXujsY#aZhVHaT{a*b@7#Y9n|6ic3aLW%pM+9GV5p7CnP#1>nq({A9qi#YVx zfXwC?-fjlPn`qRhs$5+Q>!?MH16jKpf6OOFJ0rJeF)iAO#$5_3Hg&?z@F3?fGXhy4+PaG8+|g?9C&C zd8^{-(0|D?KEe|Wo&?(s=JLMQ!x+GKOB+XerQMFioC4!}g@uL1B`wqhKK z@kMCqRry3oFl50yY`V2&ecXL;t9If!$L+x=af}1pcq}cMW!#LZhMPkoEtM`{vv~ht z_4Ja-SKf?4SgTqV1vx6^{A%oy0eJC|7j3dyyVQNe!OzEUw~l_*rPKG#s)X_}R5Md) z5o`oUY^kH?X7QebM)|KmMnPRLc~I-bnf(XKwJPuk?9=h5;te{V5ZW)Smz$;X!)#Q` zE#?21?i1?0>D~e2@1QazKpFDH6K+*$c2hgmAZpbK_xbeKR6&aNj4Y6bE#&MmFi2$; z+ht~H={0^;5Q?%ekX9+`MorMm*PRG_H=^`VPT+$)K409BI3ljPL#?gasRl+exQIMC z;(Px27FN@24+V>mO*YumhxvH?&hr*+0$MXjc7HN#&VOFNpl@Mj*9r)R=qFv&21oL% z{6Y$4{U442G#fiWK*rs6lByEFihkQLV#tZ$ev^0~)iOd!#Xh%d#XG13&wmYaUv*T9 z7{2ugVO(EEA4Lg0Unh5x6)ch#px1W1Lx#VBzYuHP_Ra&x&;3HjvOlKho_C$7RrdA& z?4RvAoZqiGB3laz%~R8Vgx8)p4D?)n+!1bXx>Tz(9&v;j+9&Gjr*v=p2{LYqnJ-Z- zUfmpFH?FS{mB^HLfxUv3Qvm2?i+?&to&}sRoNrgMWFK;ArY1ed!n&*}J8DEA-}pIh~) zim<4gdqXc5`^fL{J}CF*YEOz@8w#STrv&C@$g(n)K(MS#YMw~>4X-n=z*zvRdizoj z3c_l4pi!D8DhAYN6KPtn+8yB%+q8XBz#18(Cm(g>g@4u4@x=8hPfANQa&(Drn~ z&N5dB-`i*sPwRR1T~rg4|FYW?UKZ#4`WVLoIXVSZm}{)9vN10QeD$PQgzNTGqTS`k zRz^*Z1IM19eAwaV8RZ~Q?yNP?M)JD;AuIn->I^#eoNBj1|ASI?nQD2@v3q@bThZBB zic5ddV7VVb6pZQUypsIa=0N6H%`lp)O-J7gNpKImJGa?kYBE~uwA`O8@NKUGh}hBt zWeD6kZ!xhTSk??{w=XYnAsypJvj-3s4(-n^hxK=hO>_^8UBUXYPl#)Qnc84L@4AeV zz^XY4iz|_)SFY8nhAZn$c#*iRQ3z-Et4oA_@1E2SbaUG5%*k|M>eTemr<#mfnV z1K#_)usQfeLyOlE1hz-2%jvMZ`nFth!HI6Nt5iu6$quO7EWbx}2|KBhfnkhj%@`&` z;Uibbkw_EKHuE)ElKZtLBn;2l%|?C&9`ie3XBN z`?%ZB#knCf`g`uHZyPI)W9XJriWj*Uc#x_BTApj-8eaZ7^l{FLMgIo z9N`>Jb_Z7!;13hdldj<2%}vPE+<1Ah7=mR*o4H^1@Mdsoh>m|RAH~Vfc=wPIm3>AM>U}=({Av#@3e?xNW^R=sDxPc* zvCg}mhdZ05)qJ5=T{rKv?DWC;;2^+(1Y3|er7Uw~P{-D2{5_>aEES#;M{yB)(vbKG z8Q)OKB~7a0%GhQ!63a{~TZ&s`ku%6r*d)W0JbJL5&xl~1k#>_uo4GS8&HKi;4BmIh zjY)_#$+U658zSv>YpmK|uVxjDd+)%-)d~oova3#&K4|9aR)jJJ9MWWn`K)rrQLVal z9Nwhm$1sWJv>;L=T>Otkp29fZ?K9>L(QXb(IzWxoV3_*Uf-oI31pghf5HdFxCU=<^ zH=%}DSf!j4`JSr!Y(WHLt--1Fmb%1B2G^ zSWzFCWq`+SR^|$hW5}83-2_EP& z1Us<|;elA5N7+NjeEAGdqG3f6T%bc$jN zpTrr)_3X!_c|yt){we$4-I|S~X2jk4dv%;9`kMj@*$&^|QpIu#Uim~s(_>K>FK^|I zn5uz~oNR&Zf^hzG?-!hzP%DB1e86!jb>H(IvG-&UKH+H2a$k54>+998xDue6tY-a- zQ*CFPHX_C~!(G^41aselII>E~yN3VGz2P6wP?kUTvt%YELXh|KVu5{HI@5ghhhE^2W=It@B=LiJ8^SqjOFUKh@}MyBz1=`84qzvIL|aPDSbu?opI z90!G;3YC4s5x(PQ3+szTQU`D=(w}$dCgIFklRDZ>DdsOQf}=gZ7ao}U$>U*mNMSYm zGZ*1`B1J7aAitfeQsYEo7Lr1c8mP?=v@Vxc7~sQqAr#7W1}7SG^_h}V@xmXtwO9aZ!&zuKGw~9$%^_TfMURQ+3mc;6e0J(FUM9+AzuyaK_ z)LOao(~lV!2;53LG&gAQ{J_Uy{t*Ldfc%6OyWW5=ks83)fs+ITq^LzLt*7c%+#x5` z=sxD(?n18FB0ZX#8d*6>5t8IH@W9F2Op=&-;(5neX?p-VQIp>d)o7vL3qgpc<%$&U zc*#XTR5=K-J{d83Sy~X)&7?Deuaw_hWhAel@JkDyG<(TxxyH6c`Lf-Aky_{4hU zcEJubR7N*08)8u1JvM}5%RCiXKJkT!roW`#9mM4O#3ZsAx$N_%l}k@qm_22^p<$~K z93Uw4i2VEq8VbAmiBmEmCB^fo>=QSYY_(Okg_q}rbs*{H=M=Dy=G{LOk)>8kuE*XO zKkN|Q%h|~)$Tj}`eD^un0}m+6>KjfGJ|(s=%ghJeJ zITeWL-mJFQl+3iDrhn2v*L(o&u`a=!aF-9>A;U7 zd6o{JuYWjrsRB^)A2G!Q)*S^eD_G7CtT8Ci;r#f#NuI`ZHG@)$3)sO^P4bP!`jeLa z;~$!;(}w$+(5X6*SqRePL}kunhB0J|ccEPkeqO#%t`%$Z82}>hS6w`t zdCk?q&OUY0&@?HwI4I{p5QTNrK8GbE1N@5o{|6qEKXA@VJ}~39?lYsF*$d2hU@q}>Ggv|00{i4 z9N1wKAzk7wdDNimoV+EST3U!oIOja~0(MxA`TRz`kk{Q(L0C{bKrs}ZPO8ujqUclu z3};B_2dTuuY2I?CcKPdF{Udk@6T=_QZ38P>&(Mc1Mmz~IEYMwN~ z8*OZjyBQ&FcI2r98)qES+5W07dwdae2v-goEIO_YXuEauL0cH&N4(M-(hgHD^?N7| zN<*6awT0h$$cPjm8qv21G1>Z)*c|(B`F<7g>n;__mpwjy83uK5McdYe+1s4;A?*8O zxYE8uoCrn&w}bHb#3KF8u`64aG2-gU;aqn{)|Rp{?d28-O1VlH^w&yRc0PnU7~f9GOX0&giVl*&TAC2`@vW^=Gr2vcua z57ZVl-S=bjh9$c{>~OY6M9rn%E_tYD5dq*oS{fQ?VF5ptMz{zPtd<@)$Iv!R zJoyJ`Fs9PdS%cY;b_{P!v6h8~UQd~H@(ATVSGpheVLzc`fo}j}pwLr1DLRvV=AN}Z zH4TZMjH`(sLULp;s0_KEWDyCNWmqsmet-ZiOv3s>e@>`lCP@~fE*4a+OWw;M-8@$H zre(7oVeMN}(0a+Q!ZJR)s_nq9{pS4G4dth2`|570wR0$-{V&r(;QxDKHNd=j$3BfG zRwI>uc5nVOkgM}+Thb(;Xwpx{XwL(37svD+4QiKK%pq>!TnHYhTEz~Vx<-0=USgp6 zvMNni5nKO!l#I$74-LXo-%@X#c$mn+kQf-MNQloHKgd@e*2HaA)a5~ZRsm4P>x4!M%x z2q9(T<4tn_Bw=K*)|I$|Z_5`i%Og~voW$dRtOC-e#nCUCjAI(8tRR7akHmFT@0Yi< zLa0Fwie<{JueN=dlew}%F&+uV-92_}PBJ6YU{Rm~!I=?asC-1(z@S3D`MrL70GAI* zs-b}>E5o6q%>KidMrf*^rbi5l+h zPt-rsyLoAfbd(||Db3X~kko@5ERcg#UhV%znqOtqQk9@wSkr%I+Y72VsQ+cbP!M22 zp{uVRE%1CzQfX0v7788zoCRqITCW8;14}T$ zJeUlZCi)GRxE$%r0cdCbF?((hG0JF#=Cw>zJC+MhZ#!h$ASicJv!Djz6v)@-5qv|r z*b?BskCr=itDD?F9%JO3-E%FbE;EW@8C*d4(b|`S1U&#B`#?}@z=pBx1y{t*pjl`a;V|#Zh zzu;1=h2FD9+9L}Q5+vZQPX$8)2xgr%rz&Y6W6yctH%sbVdk~u7ksIKsfaRCvfNbue z9r{$h8Vdip1Td`GAsf8e!S37?I)t_MEo=}5ZtfKd{}qZFvh@8N?R~k+CM{JR3%+&) ztU~ZL>??9!?}{aFsjpX}!;1~C2ciaEaA_ogZ_^!B7FOj?=v*BL%X3i2&?he&cWA`0 zL2j!KruptAPS^pT_Zl(lNEA|((XM4K|MEJs;|Sy#e=IR>OxO65riMrl4nyW=H>A6K zuBkc_=qXIKo#|S}HAwvksQz4JJJ30>1A0l~1~_yYg9!ScOd4hf^mQqo#0^G15ZCQK z68_kdwnEV!9MK#|lK~7Vqp{uJ-1}%`D!j2VV^nYQ(Ov8DhM)_dR4L> zLA^bOyzDWbdnj2K|Ct-eK_`2wVmvrANXJY*!!eVa4v4m--#a@BGbKJUgB7d|%xQ$P zSY&auZmfx^05a~K60b-KVR}+yX8*4ACV1M3gME=5_JfM=7f(9zc~m8&@@xXyT={%M z^e6zFf|w~tZAf+U{9_y=WM1R1R0x%bDvXrtWfE+p(BLL7zL}PRpf=ibhY3^qgW)M*oi*e_o@NCHf zFjRXUPYo3I;arFK!+OrPyXWCHg8y}xvY8VrXeVB zg{0EER1fIvtS5!hH*!l=Vy||-e$@;;{5VFfnWSK89CP8LxH{x=$(+Y9^5h`2?d>~NI-85Z>6pSLxQl$4tH$L zTSMBbhC7y_sm5{4I+wrXWV%z&6I*|h*psifEhf1B{Yo5yYNQKFpE>c z3IkpACuCV41O{at=8jGlMi;HiB#$K0BzL_4XTVSZFozk`QAy&EYeqa&-)fG1ji5?6z$fUgpP`N&$GG#UNRuWOKir#uALZY@INtPl^(h_T z(ReTNaM-6xza`Il|9ZC1aqa^66MNCX=}<%f;8wqXY8-o+Ux&Exiq#>Ngf0M+pVmpa z$K>ckgNg^3>_mm^?1p)%F@TpMh!WidVVUBM!J0+!g_#S|5@mJQJ3+r%OT#My>A~BA zcPq9`A}tGfsoE;)Imgg@VX_W?kcn|6nG|mGZ#Kv-eT;x_EL$ zaM{*E>@El0-B)l|F5XAdqNzQY?K|mEyPbXYhS1QJQ^0XznWG^o$uk0p~xuWpi=@7=pvZe=E4*9;6x1bujjWDym6!U;8N#ZAXZqV%3Se zM`)6x*@^6aru_nj!B>?xA&<$_ml4RdvVA{Rih%;YMX26qn(S+orlgCU&M?LdF_26Y zrmBBC%baBQDoNINL(-7q!nK6U`Yl1TuVD$YixAe0JdJdE0&Mgge4c>_%Dx zKKr;NLZ*$r5zhJMEa=&m>WrE!x0i-n!pvou0jxZ85 zayY;1@W`*Dx_4dI$O!o7{O1n=i|=$V=Yo!2(Z3+`FAwnPkuJ@t#*By=#s5Oq)=NU! ztA4Fi$**S5oUF9>_&J4)@<)G=#zdv~_!BF=3TwUqn%gq`rDHl6_fzx(#=N~y#eH*) zkYG;ueYi!WE%i-tV;64hC42`77QAG9BFjN3zpB1&)v}bDRJ7_5B-467AiPGq z#(mlkUwYsQ{#4!5rERn1OH&=VuQPy9jq%()_DGR20?THa#qnt7n=?BfP(x~2C(W<~ z6jP>&(KK9`3_=}U8L`XB^k!OJ09y}-60TtrZ`s+iurCRL>&|8FSuw@H3TKULE~b^| z$R9xa&!!JC*6T->6zLSpTsv{3t7X-gg__P&jz|fXtny2VA#E@-g(_aR=U{`8Ld z!-Lvu7@_VLVr*F+o*KKEy_ff(_K3suis^%BEY5e>nFl*b;--^xvT{kqD{Xlj%-Vfp z9~;D_Z#!5-mXZlp}f~+EYmH@G&4ftu;`upH4|sJ&giaT>Z^O`};b~O&cA6``(N} z9y((IKjmv9aDYT3#08fXM*T;h=`JLOuK4E=ebUD7Q~u_MWv2QUDu3_x^-BSto-3D%VdDQ7#htGnuQ)f$yn^g6h{x;(btHZwzSIJISzjClVCzaP5 z7dlLasr_l36sf$$nEMYdE7r)TL0UVnL+W`NrTZqq_t( zM_L@jf@Wl|wHB5wf2gIoq>w0A*lJ0EXFWVn!~v)vXa4c(x{WKg6aJ+sw$By6XUuEz zE!j#f4)4B}AaNW8ynqx~GHR4df}i8P)9xUp7cJvCLemq^xVgF1Fv4RbXEm_mCGg7p z6+~GO3~+ef+_SPk_i;G{jZ&~EombsO$gP=lNA3>x}#9E0yT(*(F_svTWcpZg#A3axyuP`Vx zS|jPZW|#m-#|D2FP|sU@qYY;RRrj)iYARWRWt}+n3}?M|P@S^@75D67sbaz#?ZoSap^kNNzPv28?8DrL51w&%ygq#R_z?tos6TA^ zw-_Y9UDC_Ww;Kl4g#3d)9BBuom$A8P3m*0^L5!5?x8xM-Us+_yJ+!=YHpbS@=Me!! z+SB+KX=8Y!*vFob8AqlKoZqnP;q^BRDmxjU_GZ_vU28fzyEUnLSKdWN%CHh`I@ahq zt^gsSlt#0%R>>J}1G7pJPQJ$`)IVf@h^+WJ6@f0yEdNLTW>vDWfMGJn00%F+&1?fC zE9h9~(D(f^M~9_4p}N-@-aD-TZYkb$-+1gUl?VMw?O91VH;x5#YX4nq>&410+z=6d zrl2-`aBa8&7zT&mtuc^ib{7u^%dwgA37ADci!DOx^j+G`;v2AwsgC61eRO&3S8eaw z+O#jrqQj9U0)>v27hYuWwZVUE!==aaBk={Aosr?-S{ZrJTfQVMPR~>x5nU<|WIWgk zPrx{Up%Zr;VLVX~Xzpxo3{~y8o!j3bqzPwe$|u_Ro4eb<1_4lh4J1brQ2k{?7a(O3 z6He4eZ?#4O+-kak>x|I5Dbb)pEBNNCkQCn6tjILLF)xk?Fz}o8b%KEs>beZs6-0^Q zCzuf#ax)1d8FtJdi;6;PURZFq1CRMJug5Y#00ASYc4FZ3JA>>4&QN2btV{ur_s<=G z-&N-4Y`l@7Kdy@$_Z4Hk_pE+q_t)iAcUEU!=7wBc-&f>|ODF&!=qqod^KGC;B1!l{ z>rcS+ML{M?ZwJA*ai1oX8E?{+cS5@eZ4^;()TiXuZ5fbb_?%nvBD$kd4|JO-2`MRd zqUcs$leO&;X&-cF5KyecndC7Ma%WyiQO;Ac+`ssT!QPJLh=X@TRlV?J*@eW)7XPSP z?ISuBMh%s^eh6=s6RrE$B*T-At=RmY^sEj;r0!?!+nyq$Qkdy7T8z`Z`c5VG48knR z!H~W?*H&ku6=&;g{FUIg<}g79kmyafGybH57R{f6^EwD779Up+VV*uj8HdGX%lHQ$ z_CLL52$pax?v@iAh*Pq=6Xx6c=I_>hKp7}()+ZF7H89S7&q*Yjkueh{ZuxH!e+(6S zVtIP{*ZjR>{>MwenUvt}oI=jwBdg0>b&CGtPEjol%M;I~aBa37!v3|dh|tc8D%?=P z`~GN;Nl0O)VsGh&=W8u=LL~!*>et5Kq?hq)H(|&TljBa`d!VNTk+YEMKe8AQ@jjMd=TM!P{jD}>L zQyOe#|A3UPL@EIgZ)m8S{JQJ(V7-WFU{6K@Sj3y3>HDmGktGH81hkHflC$l`b2J+( z)g|)}Fw8Lk_MfqMRZjYePzauNUje242`z-@32*+M*~52>AMr&hJ=e zt_4up;z>_CvhX(lQ25(8h}hNTHT|8ZU4>ko-4ZgwaAS$e!R? z^AuWRQ`7AycoA^#z(u%trvE!koMISxi=O2_;yssGd>y@aXoh2=!9hw24PsC} z_CCuG;If6T+*e(TJ^xY)A%fNB1Z#+(3`ppZ9CCeDy~@|s%?=u2|EaVAyLl;yU8YNI z*V$81n2Sb{#%`fiLWBSjs>W0%wywMvL>}TON6;J@8sIb|YpD#z$TE&^kozYPkX%?O z3q$`kAnvCmhR(d34oxbNhYgQv;RkRP^n>?eH?Burd3=!Z8y#(o$A@8q2=A5wURYzu zbxUKnJVK5>5;qX%VI93+M>Bxn`J<3WvGFhJF3w(Bh+0TYcwxO~+{}8jzqO%(@m5JL zAI#KW&h%k#RUq2ib|~=#X(&QdkKp!*2?RBFF4*|E2a^j5d8>!Fh)KDyF+n;*KmAT( zM3B-v&e!kIWy(XlS{_T*QCRrD8H+hEfoO8YP?rZk+@fu1ed< z#r!V}L&8;1Da!>+2$w4ALisa1;pioZy`Cz)ghTxWPSkIdNeoE_kT}Lcz&JJC?P-|`d$RW z=kmn22S`v=Nx)?2YHnxa8kwq+r9*veg@0VLK8-JphSOl;YR2%*U}`#0M_3=F$Z$NQ zpoj%GNxY53@y{T`jw*kmbZn?#{`R@LyP;h9bL(O7Gd^(S<|Y!zqE-5AirCB%BNw49 z5mm(-InzHETmG0GLT@PNc| zH|Gva!|N4B6PW|cjBeAJkgn5-09 z(Z2XU7xwelGV1Kad}{hLP*-0!{SN3PyHhJE6K)G?Q!J}T_SV%gTkXN+rBub&sz&qe z_@A~rB7~#9vM;u-jBObd6+~;3UH%Z50m-(J7?B3#v9}~bLK{9|r|g5Wv#=L#(?m;{ zAL8thiGX4*jQ&PxMneJ&}tKLq~JxZ|BB<`|fKo#<}D{z|D`nba}OfL-#9%2pj z{EYPnxv%j=MXW@Yequ|VYzK&XEOvcfj1&Frjus&SzsZY<;i-sW1t~%IwQ+^$8C*jZ zo4{=|puw}>#>3<{oN!%NbSzM<+BtxPB$qWu1G+bc4yJ+kWhvY@%kmj1YYJO(?#h#J z&L}5(TiV6ht@C3eZ6iQ|cjY|Gy7(Q`} zR~^Sor+l(JO;vt}xm}d~RHM3#YfRa_TB%WOT~ZiX6u>aS12JTUDvV4qH?p zhlPizw>={1)@yOxQNg`nI-T%)PpRpxU`qw-VE7-m`{AFc&RZs}fwvC&77uiIG1u;j zF(t!?R*EILjAUk>Rdk!zX6s0=6T5dBY|@j|1iJ^@%*640`{V8eM4Rimr2zTCrFn?i zcItz^S)1L|IyAGbh2KMKe4VQ?KT=JIjSV8aNM`n6aM)fvW?B2U#G>Zob|ovA+y;SQ zJL#4c25-ub#nvT6fpY2p5D8d)lWeWBq2}0G>T^7AYT~Fx+J}OH3w1Gin?W7cVAL^c z(zUFO_wTO_f3(8czK}uKw|h_6pk?-L$E8&SQ`|a^de0!VQ_52E-CregnmVLOC%EME z3Rv4}`#DRR7&JrOIf|3;?;jQOd$b=)4BM$ZUwzuC7C!GtRGzPx?*ON&g5*-5_p^bH z-ZPM}Kd%7c&eX4MW~upUUIsDD(v_xR7K)4syMY;{LN3Z04DEy3#E>Sjq(@9h>pe*ASF&hwmye>fc8_xt^Ph=p>4 z-^iCuSj0Dz#xtf;`BmE>23LYNDs+${L5|#?YqsUpJ_D%_GBJKd3$gWZjbkV#fU?+U zb`56|xj-SC#9(5fX*Wans|G0|>i2*J>uMc1;21+$GduX*dYm$4qSHElsWlmT^8<2q z5*|=+0}tqesr8@qTweSRG0L!PdxkT3hDmc+4Bb^yT!XdhO8kAtzI~*t@@)=hwy}tR zeBe8g%<1DwSm92CruudGSFtmmZdHbM2!TVnYvKY@i$~}3TjX{Zc!W=*(ZyH)JIvaC zc3G-_m057&!mW+&({{h_nzi_6^S~D6?m6noDVew^IhUhl>kn3 zr~1R`(cQ;j`wB?fS2x?&xm@U3rM{-)j`S1%AIm~qw+hW^IRs3K1L>#hEUbU-YmMyY zUb|+KvL!Om;=ClOSSvrl7-&Ss96ESN3&w}Df=?D+Dnb7e{ezx!^6vHsGTh(2&wX2& z$1S}HoUc|UiC}?%RW@6=vGh(9^(V#t<=Uo3$d$ECqKQUl8_S9(BQ82T+3rTy|KrKr z+^PS^lhNpFu5>bAkV;6y_)M=gU)m4!xq>?#DNQtp|$Hue{=(Zo3U-bpR91^Em~nOiM_&}wJEus-+T;CIp<=Wz9NCCZi&fz z@Og(vZ4m(aNaJoSd>7Q@uaj@x$XAKAp!(%7&4AZ{>XcBXtS553zmWkLE!a*&z+45g zTwNN0F>Y(dzq;<=7&caI5En@a`aP(pr!`-nCwXBLVl&X}IyJlk)_HbiBt`@cApj;n zaGH>ToPbsteDVjUbfB)a1 zn7~fhQ~iQt{;vHyAXUtrz$!n1Z505J)|+K?K^$@5A~|Deo!t0wBI}w4#BF< zQ%6wKW`lm5ns}UKu!*xrpJa6b{`eZ+vs@_jZJ&SETlk$I5SpTMq9rBm_plxt?8nwe z@-d`p`E|#r277**03PH$%Kq0Zcj>15N~@Qp84p>t6_9|vo?+2FT}hu-IG4@-j)C>{ z6jw|dBhDc0f=A)T7)0!75xne#(07fXVcYtmbfYi4!ohCPrBg{J1ZRufx+1d*v?*mn zy>IQtH>HK-ZDlk|{Y(4;8s=2BL*QzC(4MmQebrXa`8Q2VV64B@`g;#pJnN~h%t3wv zt-g0CO(mOvZ5_p4&awDjc#p*PeccLPtCACNnS7vDI_JG1_@GS19h4-OcwHZ4h`_RC zQuZ5eKDYj_zp*6Q+mH#R?WVU_5&+Y%$KPQke`7J9amiBVd#vo84^auBX+;JdoonO@ zowD(f=7L;7RMx2#4b7%r+Rg>X4@0$!Egxa*d4Wy`OllgTM_k`%`}kZ_a}h(W!=!JC ztOjZ6=2}em;tE~3!`xUr6@z4T(`Pr$8h1<;smNFFk(|ieF|r4W8YuI#<{t0@q^t)% zk#6jEZ%ga?t!>Kg7J^K30T8DShcxTm>jw@`@#6K2KhLCuFoY4z@$i?nn5D~%&&%c> zpUZHSc%NgnDJR!>FMD*l!7lqz>3c__oJ_t2KEZs0b(d4a6VMqM7NF^!^bI;L{6m;~ z_MW4@9|-h5-LfML4DXYK_4GfVnxnPc+*VmwA}Hk)fZRZzHycg0WJ$FMY zk&k1N*|K8t8LDMEx;_5UNJwW(Y>!xf3oDviaF(>M_Ez?unYUs>!hmNvvs1W3cJ2eP z9^NUoMF2aTu4-S^e@^E>HT!?Zd^ioH?;%xQh&sf5&+NL=7(|eE+8Nt zzG;`lK)u*70X0lmTz|=+V$R+8O*gP4Sc;x!>I=m|35OiGy8x>JD#A^{>>}>9N;fAj zF509zIP7En8{Ap)mP}|nXW3K}cwOeJ@W=r|>-OyYvx8quT)WCp<)hct! zIN-FaVr7!9G}7q}R?Niykz=|WCLQ0Cuo(cC_$rt-hH@?O8*aN}c-v_Ho0>2`X81~2 zav|<*&B3yb&4B4ZqnVJCB|b@fviT?JK)zi#SCvJA;8v#BvwTxXU9}W+ais!VTj36Av7A#csHKd30|ceL8WqS z^j9R-p6cKk7gy%M;b$-@)<}ZKx`_05_~Ob(Hl5!L&)RIAa{rr9Tscrw{`TPth>_}p z`UbP#Brob=(H`PF_XW}Y&Wz@m0_Q=^E$q;b0G{D(TzkQqzA?MgHtV*qAaBQ|HkWJ- zyZKp2W#-fmzxJ<^W|;BW+lX~TO!$4}#{(#RD8ZmS{>%{{_|_v_d&o2W!!T4U#2siR zyMpz&%OpdA2Dv~#or?>^@eD?dIoQVEx*L(J#x`mi>$^E*f4R>eH7Nwp*gsSqSM2{g zRUKS8G2i?{%|YD~92hx|cy{qIdY zV#}}F(Reksv4;eVTOg+HBn@@Bs7&N{6u555kn#y!+KmIhmJ10S$i)VL(v$eW9PPR$ zCs#d`qg$Ak^<$%J(g_*&7FiaxgjdJBh>m_0VbDQmmIDpar~L<4)n1GG5+yTNxt&w$Q< z&-R`GP35OghL5;-bN<WW+~N(m&?nLjp`c);*46*y3nM>#9ome9FyXqvUzz!~Zr}*?oM}<$C1*Z(9t%jO3@Bv6MFS{3tzPugsLKzY% zGRDc%vkm1@)COA;cprKWV>4*2cD2qE>R_2RKAFHX6r=}J=*_t(Sl0LDXqL3a6t|9nBNLMu@v|^dCkYqf3OyAit$IDYr-3$TRNf!`Io19E z)f`pWkCHqAjC~)&98r4+U6PWmO`hL7pMdP5LKM&^H`p_vRas|(B?pcm*b5yvWksE$ zbOo`t&qV##a^#=q&tE#|t|fK4aMz1I)-j(c;-E{IJe;-WX};!GR7du9m1yz>rq%~@ zm#CV0YNEVLbWO7ct3;28oiB9Lsy7zkjX{${728_<;C&PG*)wA0bE1lS{C0bl@Y6La z(}Zc$)FkP+Lqycjt`qj4pOD7vF%s^&gKwCkbk#?e<}p9>?JF#L`O~acbB9AVh)Blf zp_hYGhvZt*SBLlcrDp*P!?DUXWAzzlnE>(dN#~oW?r{+|E@ytISh>5!7|pqG!L#T) zUlWiFS>f4sH3aNVur|upV9PhND+Ddq0Eng7Bii^-9%YOz& z|2FX1%UUu^LWH{Z-W6hDl0t#@V#@0{V>l-z!+0YvQx15D83y^@1K!>sV!ig*lvASm z)SRj6TaSI;ca@gBdUpCSLd(r;iWg+VucviUbN(^`*p**`x^%R>gg97dA~k8zziT!b zlP18XSf~0Ze|+2sn@TsyrNU%<>-;tN>nk1?_`t|%@M_h=uWA!ga@2VE$mt)NKH0G7 zl`q1sjImO(P5Bq(0e8Pv{Yv}tGgEZX1SZnr_Tfu#TqCJ!;b`Y?qSxBHxL@k%o0@Eu z&i|NEH7elG?EKwv;#U^zSE}@N#--%4QiY9+VcnPldTK3x>~MM`Ax&|>_*{CZ zco3(cNZt;~`sA;~^0Jn{jqF!tG0F>QCjvRE0Z_rqY9b6SW<~RB_Q_q4VJk%3)?hJ5 zrgEc~7-fZl8ssfmGb*h3srSA}i{;Su*9tmz>6#R8B41rt{=Qy?Ne*FTyuh6AZe&QV z0X?FbrW*?DSbhz6ju?)%&?jvi|D-fhakpAft;7D+1%geOe@d0*+m5{iq|UGrE+Ytr ztJviVKYp$112UYX)QU`!?EC8^ByNSgsWscd3b^*_-aS3WiV(j)iBlnU3T2E>*r%K0 ztC<}ZlxlJAMWQ3Yrdje@FTKF-#m3-3eC@N{a`B@!Vdd-jFG`H;ed>HNqzrS5GcJyFzmz5ds5)$oJOTMBF}JrZN^71(6vu`G9Wg zKy@OTdzuG6T-Nlw14cvaCH_XE)-~iaM!BkD1ci5j22hTOabMrlDAb}{z8CGk>rKJU zn{ohMHU_9x)G|phFTh=DlFur(`f5se?VcpeE2ptPr4PA&t&1QT0H)RX?nv7GXF`2o zQCM1MbP2hbH@1Le9K!kXft+h72V1OTn04uTIOY?KZh8e z?x`sAt7#)Y2QB)HFI|JBzJ?b^F+ZWQyAhrarAYFpjdHLgl;hQ&Oee?Obtxf7bUpV0X-MFQzCKkgAI%0O=Bsj!s3{Y7f zxndzuZry+(9}N$10T}X=e^Gf?x<89Qm^5M?uYR=tNRfBoLdGHH+7beNsgygs4M!3Q zGy;OYRd<5+HNi{g4<*U0x$QXZN%Kd3n#R=5xTdumW)CU%g-V;^r3bUtjK?9H`K=;|9WUnv4juBO*IfU@CyDHwy2N z0XzJU7$|W_4Etbk+No6X%yJ@Mfvc46(XigoY&& z73ai77T4d2-6?NKY20jwxDYbptv>TBrcl6_@&0s}+j$2W7JH%V8^Mpf%OXd;ZBP2s z5_@YT+X3Npl~5*2`x>3ee~1o&Cm%&3Rcng*I+EakFjL5%#D!Fpe($|!-WR$}HZtM} z5~a<;L$9Ah?@uloT`s+!EgEx93@ZNb49-q%+GI?Kk z+fNNMw>Xss_hXR#pKCNOtKqLqaUCz#$U}Z3Ne4lA8(X=mhZo!yb{b@lUeu z++QD0n2#^@=wFE8=SBZs5^a<|zmb$Eta`KCO&RT+7Y#u~Cx@;Za8*XFor*G9l^`z; zjY48#X3i03*;IDUX1aj|SNZ5yF{^z124D8`(o70=e**D-da_Kp(s{4-rrwfdvmJr4 zKtbIatwh%MHN5+J`GN`gE2mMMa9jmtvyvl$OXJ}CQZP+W(ViR-qX#ieeo}M(QKMQf z0R+D;UAPe%cLy686&i+$t|7TBE`C-nEPJmX5y!$4gr0v8-$OST*jbWyrK*eJQV8xC?id@?Vqwgckzk@o z7j$vn#Qmsa2y_<`m+jJ}zYCpReY$o8_gyD1&fqT2wfvo`3L@yym#i$Saj%G98DU(z zYgeSY=aR!te_mW97GGLbX*~`Pn^k2_Z{KA34Pyi!K0t?U#;mS-KC6OX+u~y|g^|NY zd_cJG#t#|m|M&(kGbn)|!r0m`Kc$FDc4B-;SW*(nhTST8AHpjr6%Hk`*JDNpB?=`u zr^~&#P@sCYX^7CYky<7YhOi>_Ozf~1)z5@@i;7@>vaLfI9#Kp^Zq~f@o$>Dlrz&y^ zM5iIDyr~E~il{iZF?V0&jnl9kbh>*op1kUU)oE0km9#weI2K`HUlq>FYs(%xL~bL8 z8y1lXgIJ-_#r7OZUYuBkX#j546^i&}fctHoAVM4;Yr3y<%k0t}(sRG~FM&%i#6Lu* zrIRKW3csZ2u1eEzScL2^GG!Z~DaZ4{B~{@L*)tfDyYy3N2~R8dAKc@{l}woK#A#|r=?-^wKuNlZbo zKj4f`8E;I;%OxiZEIZT)w;rEgkkb!ES#16Tn_ z<$6qr#18z66G1Td_!;n%(V3z=-03ds&FekTwuoOI0J~v55##;oFR8xiK~)V%kac``!QM|w7dQe@#ss5>rD+z_ zjT2{8<)syAcG}?+iPiZP8w#uM1c~JKn*u|FV81y3M!xq9Qe4XaM)he2CPl@(a=t5s z2ofg-5gq4B3q>3(O;8S9CHc+Yo1c69qOoq1(#r{VuP8gA9g_g@VZ5@M#H1v$sQ65I z!y%}bIAFC1{NjEYxsp7!W*L?KVyx4ci`@TKz%MqkZc;azLzf>=_ zF#d4-ut39mx?nz&&yTM)fTQylJt`xVmO0iYtR*!Z{kc%66 zW;zqHCKpi#%{BJd7nybZBuB(1*YDPfzd66;_E&f#UU^xq5~v?t!J;|ppXYS|pRtZ5 z1tR+-vq9)^?bfX*Q!LJic=hS6TV#7D1^XAQj)b!UHUqkZvk1g`!_lHlEqCk?gu$_H zbnnZ>oAR#73e(zZWO=hShMJG&Z_c9@>p5YxW;6KP5)xIsSPOC(D zT$nm+gTNSog=1jK$b~2I=v^>f4?oYR(~-H3j%evy6vMk>G!TYt%13Q$v__91>LaCy zFvlXS!x*Xe)w9ZjG7MwN&+o3xTnGBGY+x$y;#|k-hm$t9uQk$V+-DxZ=&=h$ueenX zl`~>yd_{TfRd(%bjg}5=`1f?y8t4ua9F(ku9wr-I+qW~_C4D2q7H|7OVFYMh&IK!rH)xvh3Xo)(O z-~Ri6L{}yVt%!wFF<16A+hPt8`2cY}>2Hzy^27gj5LR{bb4ja0LRrbIRdm3w0iGiG zv@&YLmbJd*Uh+ea9r*{v!NBY zmw48K$&2;Aj>*I1s8CF^UV<8On1SIYDtwy)@#TtY;~W??{oHpiLBxHb zyS1XS;b}0PK3U9(3Xb*bntgTOV>u~=ZKXJ!_#Kl|_D4)FwkL%%WBY+Zf&W*!jD09) z`THC!Hw4<6?X^r;Ob!V3iw}*DUGvR~Ilh`|kk(TWA{4OumGG0&P`+B(^=VTnS+Q$1 zi=9Htx(IWKh+(=05&3~C#FCwcOklsSYupC-OfTFhDN`r%(pMJ>-j`)L zzsqh6pjHDV76Lrgv^OO=+|egE9<%&u7(j{9^80zHC4gA)%I{8q*}&~Vydgk(JJ z+n@)d7;tF8`j;>l%T9H=L_?-cC9dSNt7nRZg8MPqS2#6TLc}+SPBJ50@PFK$dCAn) z-ZsVd4DRZmn{5@9A}nidMF-DqKTW-o&M#dp;Fp<)ba*Vh zNpki&yNup0wa%`T^8l0Y#XKSTjk$>EH2Na*@x7tjsS8A~Y5PTo_?<4DPWap6lt#bM zS@y?_h3U016|B7^pb9!9gfYvuY}T~FtVs7%5PnNV20+`DxKqsm!_W<` zHMOB6VDa#fwRuoX1k5q{zR!kQEGeptLw`)Lib&=paXJT^^D;8y*XPFrarC`?f17ud zz^P%HX>nXgOiCy({;;z4Jh3Znd-%&Kp2{9DO^<#qs;K9HyMp5%$C|m5EL%TWq}Wvm zQWPx~7>H~9Wyh{@qBkJy^4%>j zy^{!)s{pa#w(t`1=_B4z?}R>o>hcKRO+SePne~t%McK_l$DeiHDHYqQ3d;*FXRDE? zgdx8FmD{AR6Jpa!g;R|vJLP{AS1;SPD&OmkYg$Ph=55?ykrE_jGOB&E=P*DG$QYj- zx1J^TLxe7c)(BYVs=Pm9Dj8{9;iooJ#e7T zpkY&|ji-#f`&$jz1g0a|Gb$UE2!%|Qbe?dPtmBB;sMyG-lY6E5GaVOF1FpSEj@AifFR{i)$`TA;wq zFMHaSbARXF>%VO&izOGnJAIhBkCav_S(%#&QO(>yq#Q+XNU3mZ11u$Az;ZVcu7}$H z;W1Jn-oTeN)f2=Mw+isK8`5pb2ys}=<`zAZJ5%hL&`Y4bF~v2+54FzyWru9@2Aty> zx{mV?Gy;($6h#F2JmEI~AAWAy5$<`2Z=fmM4Rmd0c6h*GnUZAQrP`8d3dYdCx?5~ zLphV~VzLU^qVHz}kYx8q5_t?505nS?#K8hebxH9g?^Vb!aUX6)E@*Ca=|RY0qu{W9 z+=YTES#O#@OTwbSfm~hNZoN-6Z1eteclK1GCf@>0mUdNVjMSsc0EXSztBq=Y>5%{O zBPc&3ox^+@%XwMeBFwXj3dNe^HG1_Te(AISpwXcWaa?>dE7>7DCTvY>no)LfaYAzm z!V$4fIPIa0g!Vcd{RuDZ);Eo>GWMl|NrrKP#Ot;)rb)ueC_-qh+t(M(INzv2^EDQ= zXFSC|;V$WhXw?wS6T=d`GK2ed#}@GR@|2j=^TK|Wt0Z)5eG2{=-tE)ds%@-=v#U=| z*#issW?>U^Oj24AML{|kZgcY`g-bNbMct#5sc#SwPS!+5H3p~1-k+BH5^i! zayLvkDngy7Msy_tVZxokkZnTSq}un**0c#*i1RwxjUKYXAdE7&G97aKJdPpJ8%<-I zk_#hc*v(cre6qKnht2*E(@r)w^bhMZ_I6DHuPz>!e*qnzp<=xNj?%Q!mgvRM!S6Pz znGSB^PP@aXrDLAD^sF7nq3zHOxwFcpZbO(@5(&Qq*JJh=il>_!SC2U?hUC8;$V!Up zK$0TD>(|bxt0+mPYvm`SyKuBa>%At#`50|16$86Ky%rrkNlW^W(laE5>y#SGP+3U2 z9Vyc3(9{!B{GrkT_7W;VZUZ6~pMMC?8r;6$JlxD+SN91)LA%u1)NpDnfV2e2W?=}N~#2p7u6&?-X68|AM>9# zPuwqgY%E8B)y<@mH6fMQAb)kg|IZH`0MwyYj8E8Ej|Dy^jw!CGRk^{}vGkt{BnT55 zY_U(v0Og3U&S*av01VPD2hFd(VgoWMUi+&G6c+CMhJl*>G}4s$;i(53v{ZL8+wJ75 z1)3gkOY+SX0RlT*{yuviYYN%UkRneQoWov_x~n+PNt1D;=dsL~MIHOHr&clsF*7de z_tcV11?odttaB_egJElk{(x=awkxu5dbtuYmJPA2cslcIKq`-}@;3qPR4~ zsgM2oYvN1Ca;1F4dR{z&h8=v@vRcC6jHm)L8C$gW4@gYy$Yh`d7|}8gVGWOpH;J_n z@fB{URJ(%1Sakv-8}7Mw*+Gm@VHJ#DU;w0E@*mnAB^wJ86Z9_S=2e~5cDG+F0EN<@ zRfgiY{rQSj(I{opucII_ejF9fkbrEL*2+N~h-TZ8cvL4Ifk5?OG5Sap+5m&a;r;L% z$WlWBU^HTEVxVW?qy>RYcl~`yHb_)}>J-6ZGl;o`rPWIk*~Zq+-a%XUI=IP^LVhlC zI~j?gPF~!02rL5p0a_LH?Z)Uum?!c~zDxSCPd|*UV=x}Ta8bWslouA4 z4MvJjJE-Rkl0(ZIE2bK`ezhS6`V8j5nTpelq8TJu|pnl^IsXyP`G+)+F(Z%Tea8V%QQbvLF1 zoFa;5^cqREwKqIM?5ps~3pkPR%S%O0Ag!NN%g76}c=?m>t5PhMsheg zQ6-DqI$EXsN_tD5o4dOx^pz^PY?4fuUW9de3+iDksaW;K`P+6S+25AF6_jz!3j+@e>RS$f1 zQ*L=~NxG_=uSk``z#wdNL!I-$TZNL31jER`C^uVAn|tkK(3j1_e>Bec{sW5iR-o4o zo?9jLE0%3k#>8~~5~I??mZJ`DbSNz?U2z(V#u-)Wj)<0I`)A2R^$rT0XP|4_O%34W zBi1`-ybKxw;RFu!`bb{wR_P~)4#9|h;MjyG?~gmwu~lM?=gix5t8FjD5d{#rN^Di< z%JftDZUX>HJCn`$2>^OqEG!QMZ9J-0c59S)h~~p@eWgsjy_@Q4$-ZYp{4VSQ zWl`?GpIXy%M5~J6XtfU0?Y10-sa?^%yGMIv=&-GS_u<*}kh_NdaK2kX9(q_ovZl9?&#>Pzb*NjJYJKU-t9hs!jV|9Uq0^ zatZOj7|uor=6g@}5{$cZ7B+Rj%xMD^2BS}XoXcnYfRRm&b(p4kqe_@&wP`YWJT%p@ zkTFNW#pxJMrjz}qh=1qv<6vC5X*-NL4h>i!Jca?M)|^6z**=wul?Fs>%dI>Q;OTc;Z#J3u@DhMXar)k94!4ly!?n@FD_ezYFP@5KB%&K8*k_e*% zK)t06#yhFs=pIl1ii4ef_F<8%Z$?x9)V}G6qp|nKKRCY^!-Xe{WL@$%*WT2qHM+qS ztkeCl=b$V;l>kFE{(WLiFFnXJ$TVaiR3rs`-KhUdyVvr`jsR@%VTfW?kLyo6GZZew z#-yhobng4K&!&_xl3q9~CduZY!PQH4AcTF|dElhscD+D`yN^ZWQM?2)gOq6J82TIV z-G-Mz0B{s>{*eX4A3DwS-piLk7=^aw0}TD+1rt_W5>dBs6`x~;O^^UMTUZ!%AQ-HG zLeX=U z%iUkOl`Lpp>?VA)>7yiaC zGToOsh>qnIMZ++Y!$Lt(?wouG0MWLT+(>XXDMf+u{%vxglN6v{`+HLxQHhe-y2||7-C`1^SaYBHDcZGo7;+I(7lDR;>~lyDTY>8 ziDzikCMEd{aX^u`n~(i=hIjck%VI`;iTwo^7od8GpUz5a>6aRefU(NADcevVL(tG#M`55>?jE)We;1o`z0)AVq}qB9rQW?bNV4*Yvu`^SDR|eTPWSxEi)mYI9 z-;y{CGFE7`_eHW!BjvxGzB!Q}gBugXk=z_Gw@&TkFbca)vBm7uX;UO!(1iDkXVi5n zStb7duR6;McE=iLYm=wF>EgFr7v>;wuWn$n;3Tz|ap#KJK&L{n#2@3RE?>B|h>=+{ zP3SPCbtffIGe|2GYnH=IrhJTz(Z^U6l^85}HzcZ*@Kj9?dSCt0isENEC*M|Ino3n` ztz6Bo-hc&=z?*D}w4d#+m+@grONC}Frrp*LP9RB4I%_ZJmVmfLM-(B>fZ&LjKMpm& zi?qgQ;DiPB-dL`bo*s+sBk6GEeA2e*xgUF7amJs+&8Mej7QgEVCQB{EHZU{6a1g9ESCXtPOn4G|U*r*0nq$ar(f z{I>`^Ch;&i>~xNW)}7;s`3?p{NO~=i5IBL_RBnF%riUJOt|gc|cc}QY!F+AB9!|*c zV2T8$f{=9ai0uJlke^yOrl;RyU%3`|`Tl5Lw{6O!PP#249yy6$rr#&?=i4 z!}bjb7aaZbY5T7_!!p*BY`+DFH^Z&*T!jmQ5wOikdU%H208v06TBn;4pzwwC95qY- zYF*i_@ig&%8}dkb64OopVAKV8=*1Sj4t7Q18E(Zt%mT+xQ$T;seTmY3+hFVlcT0X* zIaZCZ8@Q8{vRz|4ckfTKvDt4|Q|Prbkz447KUU9I2>7c40s>aS+8f%KBi~Fg=)#PV zp7d?4!(4?H_uo%hNQ@6s2f@5G=ZJd>fDT^jlrP&Ktl_DQp5MrZW>Ab8^w7!*_g{uc zN*ws47t|m3D)_P!3X5FQ+t4a>V#f}9%B{jtHr*P4(%bERXX@W>Z#%0!GkTj9FiBk9 zx*0gb<)RDVNPM!E1!6Iqwzq=7%tR&(lJbYLZW}>zb!FWD!A#)rmDT|88u7Yr5TW0P zBtr6$e@nJ82}mO7HENLA$LvEJ1jB;+FxcRx;65BavOV~iA%WQx>1brkJjQG?F%3Qz z+($GEZV#rKTSQ_an=GyVuYI>By{@wuwIk~?&|n+eTtqHlXRl*~fE^sEeq3}F<^L@Z zC+8d&R+Q?~l}mINRT3h{6chR$i&7BwUD3pd;;;E}2;ZC!p|0mf&2F|c>}G#=wn2bG zv(s$ctHoB^Iev`&O15OvP-BYH{x|ur0}pTCzyLD}Jx#(Mr^cVxkQbMr)T;{@+=7`A z*MA;xUAZre5hU3jaM*7;bjq;bsU+P<@1%2x=dHzFB@_1xjBuYl-Y)sNh3O0ASF{Hc?eSsA8#xy0O=TzbEUp}d(eO!}8RkiWpln4> z4U*octc9`ugRx+k=O9y*)AI1nYVSED1m4fAXekf`7yS&G3B?{lbVztCa&*U~*aH%M z1`KV-(*40vq9T({gOYGLd8D{mlpVh#SCO!|LXSQJ? z>N|twSJ@WVmsu>Ca5L(WaNg!6gWzv9Q-1~{&NZ8%MMCl1hmFDWEI4YB{<(X8x4qaP zp7(?tx(Wz6JSL+=$KLX*t(}tbRS%5|4AhcDuJKttd!GUh4_yqbtw61@1FsP! zrWPCsUJ80$*U3Yz#dA6kd1Vh-_J}??694^da4Mo4YdlE87r`0!gnMgo+Q5v zO>MCYL5uD-*^s`3fb6Rw821A}-7BL8K+oXVL#v}lIVhOy z!jk2NaLfggBN`ixcWBh9`OewptgxNGJzRh?ORqa0{?gF&kH#E>$A1zWIEdO;ELRAY zaS=D;%#YfH9B!)furs7M6c$4T1`ZU9raQytc#K5~VQ@x(j5ekSgsw(OZs+t3YfMty z&#c)pZaVP65Sm&(e}qT_J$u}J#{e)H*hp z<_Lk{q>f|{Ziww4g=xxS&K~1JjNa7*P@q*{YIX$H$f_4#JRi5!`5xAeWd6SQT&s|yC@f{mcT!cJAcfrt)5nMY#TTo_z@msEh@1dEx5@fyQ?tPx2`zw=Ykl`kOI`go4TFFVBvKk8$8Vx{WMFPuwlgW4|H;t3*_}+`QolR4`O8+}j2l_C zlon{+<=usNO7@yvi32$XMu@)*DZ9Z#tLMX~@(GkOkHfC}yZA<@nvhV6jN*d3b5m$c znQJ+`Z#;$g#su)X5pWDlIr3*xj)b`cm;zpu9vp&mXGfY&7)+UKHM2U!%FyY8JvwT^ z6#375Q7CzXx$ew4-6zf);92MnH8fY)vv9iMX5EXPEz?y?o7?($66jJ(7; z6@cqeaCf=O*sgr&(jl_>11Pw8pM+#QWx&nGx(|@olLP#0aDisH*!ugUrZ#}rH!7HT z6~}(A*kLPSk|EU2WG;Cm{f9?1j+%EM+O9Pa(OMFxj56ikk=R#9QQkt|WyiI|J5-aq zo=wEx#&u%S%~e@(rl0G-Is#toG}v4VghSC?c9`(KJ!XYTf)n7?x_mYI8*_cEr6X+4 zS$8V*TT;E|X0(g$FnNiYzTTgnZr|sc)xSY6*=7 zH|<~ER6-qqLHQ@;V}o$eBO;^FE3qq^J(3Xumy9Z~a}?CfNnYvC&U!y6$nnpdPDveM ztRufimvyI{(2)hN7QjT+lFfj8C_Jn~t4pSSpH;WdV_r);DTbcGbdKj0Drj6MUp?V? z-L*<$qO6dDMEXpUrBiVL(~-asIj(j%hF$+6$TH=`Fi3hd3-zrrMh!raiX{8BiJohn zKz#!a^+-I>{^zD!hQ`Yg+?r_d)&&&~cZ zOMo?TWZXXj$fr$jzpIVTaF{d7;{p9#uLn^Ow2uIPMEq(mSNdprnW%twV56x+{WT-y z@vk^q{oLNnhLO!TQ}>uWFu+Uqxu#VtZ(w?0p(_wC*)u7wXt7lbK8&@=LU9yjcs?+^ zEJrBJt)6Zq*!bS9&iRme!iW;vEB_0GcRp0r=w0-~p~lsrH`(6dlH*+KL;3a3<*^2r zj_p?L_-&iwy3A~)LLEg22sJuJBJVV{f646ZjAHLLXEI2}$!AOyoAnxdNyf)gw=qbE z&HO`mn=0US!w+|vlDN^hxb98@LwcoGnD|stfHg5ufPm z`+JRAtgM_8%dT9hV^)g9$@VlCNd(yWf<_I}pLBmSntPIxKu%iWt6vRJYIe9Tzonm3 zUGx1>kQ^OfQYZjuH6^_1afFrE35&B0B7O0@&448eL|2^KvL`wJ$eO2p)|*Vr{X46t zkMV+wA}SVU9v&$x1BinQt|FKJL#!k(0tP)uesk1LBPRYh~LU(%{D6h3TOH#*ldOPQksin>Y~ zKBJ78q93*h3V`@h7Vwsw1lye}w5XbSW8=Es?>Q(U65#EzYyvrE_-@i5Z7;59wCc8M z&J(_Idm~EJXu5|7XS!r=8P?rO`}Z9dbhK?vrA|Um3MU+TUQ&n~D%Fi&))7waTurVT zhmPyn{EwpZ4oh-<W6#m1YKRtvu4yCX_kacp6rw z;A)(fEwfC)#>q}rw9HPY`0;~3-j@qrF1X-%p8LL^@BRIlQN!e56Z78hLQCO?(bc1C zXrF;n3)R93_zS<6QCEGhMrB0Eoh&T_j?``&xb1#B!0OO*GtG8UWNW8WBBZ8|Pb4?g zHl1vzzo7bl#UX0V#t$yEy!1Cd=XZm5=2MduvR|_8HTBWXi8M{uhIfrNH@NPVjiB*9 z<8g=`;BIfkoZb`;z85is3KOqyzg^2~YVo(^i9Z-`l-RvR(7UD4Tv(Iue}@?KE(U_< z>tJ_U#Cvhg4y+os8Qmre<>{HmnN>+SyYtT^Sl*Q?59*K&4d4?=QiT1rWS3b0`Lxlt zUI>_8iZ$t$Id^wQy!3IS-O}NZpYXxSr>C2~8x~mbS~)+AlR);P2rHzVf%krRLl`yH z=#x6^j?Crnus&9dK!87>8U*xCsIGgKdMBDw{F@ zp`H;<>1l@Jx^*j$a)VtFku!~4pYc+`qD`)g7SnV(|2BGMlY||x3T5FZ%KN8 zYcq_`K7{D)9V8>eagDO-6aam6(Lns)IB4UBA>}8Hx9eO@_2{SO0haj5Bp(vKIuUs5 z2rPeMV=*z?pmB?y>iR~CTcu|aoPJsT-I=Hd2t%H-ENwH^{IZv)uxy-N4#fWrei78L zLv}K9Dbm6L`K6EhtR8eV;#q=!gg?A=^~=DyMj_PD$V?upA950MIzV`w!3=Bf(cwut z%M8{ArtL4PNNuT8CvS6SUUG$4M*g_RNpLCj=#PZ8BWLjoj6To$n>+9uDGwmVx<0@d z`^U=}23060!N3Knp5?|`RxE!KdWo-2ob1yR21(LB@e}VuA(8*7`*c7jjbWkS-56-S z@8bA3#w|;Wy6RPr9r@_v%aI08ubk-ia`rj)*kDJ2%nelJ%|63{9evI5xxD%e$JejS z@+Kz0_k4g26yY#(X;U=#9!jDsQlM6oifefDCgC09!J4Q*z^&)ZnUD_rGuF$C;9Y}3 zfLq6$S$RB?^JrOcO_cMjN6*HwwQa9Lg62KvgRY2(!>d>36mIm(cQX^%D_);-o4^f5hv^!S0p(T;9)I~tE(V#IA^?xb*0oOYiq_+;++ zM0ypd+X&%(h31%<<@JiwrW=^ABE!C;)E1W}D}DcS{m(DF8h)r|Q#V7Y=c-rlm#XI# z@npa~3Pj6@s*kuDcy*Cgw=FW#`T71$Lnk^J4b1Dn9_AfxpJW1Xih$X;)&-`5bLGY# z{)svesz{i#bFE8@?#I1xJdz-a<2R&n@`0b?SKjC+ac|SlF3amU?|(i#7M`I^v5fzHEap6>=Sd>(s>k!(EG~-R`m;2%QO~kgUGSDYQ2gA75E5%Aa3> z-FtQSi>velB$npr`=;XF#PnU$Bv@fZudZ3RR+k=MJJGw7h9?0@^adGv9RUN1wZPuZI25Ly_ zu6j#97!bWcInEj*o>mfrfb z1LUPbK2vc2Z7InOfW{{IheWgW0_#hN&Rx!O>^xOp=)6g1DZj2z1aiJho*k89ob{Zg z$;tx@fxqcDjij~e_N}M`&X9js6+D(~cJi)*)qT+4awqigng*CETePdPFU0$hcz~X^ z&ItBxN#ZM=L}+DN)wz-RQTCm!rtsYDxQGJ}PaJF6+X}Cg)bDg!c^c$!5I(yL$D6DU znEAdRwl7G$0~UsMLuk*1gq`DVIj@k%!o2U9!ejs-TD6tCNnEGWIczyq1quYpdMsAb zAaWCvuJbhej1bP5DTbXFR39Gb51U@mXg%aY<}1C&q5>i+*5V~!Kor&SOOc}1oiKZ* zN+FkdepCxD%3xxZ@9HrjzDseKrYcnlw@8j5V4T7YnhK%1Gw>)3tHeidZtPxw$-Cib z_0S%k(w%>C4269la#DL}SEbY&9|?+=+CHCU4*tfPT>W|Y_xK;`B&;dkT|(^Ee6nK6 zyk#Ol?IS?Y-C2DygZ9<*KPi8{i@kB2Ex(SxQ8A+?!eHW?SeQ(CufI?ueqf4a{M7{$ zt5Y{Eu9D+#UAzsxv-$gUrTci`T~iqAo;M5_7ak%Rw2HWiPGyVh zJSsLKE-dUqHFMbGb7^7$BcFXiGnwF%5D^lV5V>*Hyh(>M4C}-M+U4=>O&EH@;7Lp@ z!f%G+;4$sgd(1ulcHR{twyK|goOfTuW(Ip1^Zdz{f+Wt;|H zjmz_dcCYBNJ9=tQy$D-UWbh)t!Horp{m$S-ZYZzC>Car~xN$8%-@}-lPqHYNoMK)F zRkt)_CKVW2BNV=Uv2C7H`IUA0_GLyb?N8Aytfes#NZZ0JY=EzPGQL%IOWBM`6u|@J z+@!?}$r)mH_2vR|Ee!BWkI3+qn%38oIbol(GT+dKbB>(dM`zw1?V1xU@#a{VeToxA z?-`H?dJYH=TmdWGt)Ir1JsyHNDfmib*pz#k7y4B`${eH^fi_{aSKb^?~9 zz}2`HcoNi23YF}TE9VOINk^P^x8xH2SzKZ;kE@D&Jp5ICsY)g5CCZh0AUFtGS8ta} zZ~Bg!ZHt$~Sd{Sy>Y4DuMQa3(HHR-d{N$n!EHutJx9_a`N2^K}$PtNLJSX=ff?VCJ zfY}=gKP`3mmBs3-r|6)d%;mkNfdK)2o&lDi|Gv982Dm1<`Yd&I^kw{6`b+B)$Z~P@ zaCcp{+}EXQQSgOwY?lqfcdjv!_i2dpVsWBDEv{)PCd=JQ_ zZIgQ%Lv-_xb>GKy#Kydwk~S39@8I5Nidb$S3jlDSrb|Ml4@MO5qaGlwJ`os4@Zn4D zPP{JA=9-W@qwEm`^C{2XBaw3oSgfW7!cHpEoGYbWz8Jj2Q+1@8bD@1Q7OqMZ5ee-@ zQ$v_ZD0#44-r6oQHYZ5Qu|DafNfUyx=WF3b;v_0$tXV{gT`02L?gskQUAY~f%u5mv zOdC0E1$5NDF4t24uS&$SiS{#*hI$rorr8K!sAMjRu2HZD{P4&A(QTS5pNW|!Y*!$; zKr025&fv2(wG<^?`SzKSdyiK2e}zj^_|=b^3D%(LAX^zr+W$`R&yzDg9j$D+ioePR zRdrW5NLMNcQ42eDqZqINe&TiTYhFS`Kr|g!HntIrb@ZlNr;6E!o;{Rt*t%t>qkO=3 zg^l=_>dom-UBNYnZ;k7*d&m4zA#SViQ&vaOu++goCn*r?Oc)G{o5}mvV=u zL01fXq$kf9M-`NUKau%3n-c`b{cT0nu4t{}ujT>OmxS+do4f+7R0dyTqEX z@T)o8HCIuaC{hlI#|g2iDmmX-zNdsWQVa6b1>R@j(y^^~Rs0bV)l@xm{z4&?|a4JjqWhzxS9cT`t&72*SZ`5 zlL--|+S3j9=_c%iahnv;TbT;KA2Wy&5Ak;^<23(!elG|NIvi zr&{;$0P}mv|tD!bt>|eiSGl6XWr8^`5nUP`v4<2>h za+8r;K%EsEgi_hhZ3?c!tiRJk=2CaoYPGv^RYM=a*cA*aqbiJf5VD`j@M2gcMgFnT z2Bd3nb3N$F>vMj)Gc2~xL6FN#9_r0+TvhlxuW-_1wvnOJ5bex+A~4L-ZSZ?jE4gdR z-&cLKwvL<>j?u<)RKL4tJ>ZePs{{OE6(JG90ns6`0sdDWJwruWh3N&{TWuI5jPTFS zO^&w6MsNImgC_ig6CfXZU6@p3nJV>!-Ka}7jCM#LxwF^THHLTlw!*_C45tyV{2*T< zV#Io-|7*(CopDz1E^y5?HYbewKzueI;;G;qL~|M&Gse0=9v(j7$f=~ zevkNk+nQi=n{LtntjZ10G>D_^1qbTVx(MuXf~oP;ru&R@oK@VrqH4o$gz+#E4_et) zq7sUA)7D3?k|gWxUxhGN%E475zD+KVKEhcZAb%jlNktXVN&46-ZT*ZbeJ(|}}OU-(GT_(Scww zHUfJ_&7lh^VtO8A#7?C{`<<#8&@ly7s-7zx7rx@jGd5&wcI$&Jif3+#gq13VrvcsApfieD(V8H*;_Qc{l(5!$-}h&tJZNTL^QKXrCwK1Mo>#|1_5KAX7Qg* zG&PbFvc`w$&d(&ZiBnqB1xUl#y302oYpzzCzTvwD#O{1|I`0tO%W-Se9`-LInPGn10J|z@MbxyZi7wSeJUBn8 zsN&V<7{z$8rvvW?>}DSVyh`i-7*qT@G&x7h=jm*ja+JL$+WUahi5XRR-tiMs!ym%u zs#Hq+gH3crV9c?|wV*fj7hv1`{x7g``uN`-RvS=T6@ad6H1v`u2fTgwdwm@m(uJ?J z9+Sab4L*ZyO2Rkra<#%NFOMGBx^?cji^~4mk7^i4pth3d1h$z{(qbVhA&iqFB0CR< zi`KK|iUWTl(}w?M@E|@mh6*-EgPyhI{H<>X1IMwYVC8$QkQ*Ew~fG3R<#`qOoZyydZpwG)*?kU>`z)p`m|f>R+Jn zc`dma#fG_OPd(7{ets5i|Dq==HQ((V*AY)x{LK)M;1svIu>jC5#`_Z&&b2$7X$$XF zI|9et(0ROt4NbwJ_To5d{$iiN$oEWk6hcGRl^DY$k;!luiFEQgeQ)~WGlph+zP#T&c8ncbFvyN zQ~}?(JNf&^a6vhFZf_)5849_ox7`N?xPdkhe}4G9dYn@ns=xizPvGr|ZIWx^uT<(v zG_YJx@PN;I15zFsK3F|Nkpt~+aLmw8Zt$N)<8|sd+wBunEZ`Q^E-3_>wu%qnjIm2R zXUe;CUeloH^}Nh>@P6oGmLAe%QNdA#A&2vr&-8KAWV{A67lrZApRHtElH1AO>UY#N zU&d{~73yD{D(AjQI9C%OB(40L-H&WxCeDnhJ$r2z?%=lti}XuQc$xV8yj2;p)Itb_ zFL%B~TP*oU_vcCwK_I}Jp?hEKV&(BVZ#5?X zuJ2X{-6LZ4Pwo;5W;i0wI)nPknP3<XU~_{T_A@H5iBfBget;?6TLC8y`hVMIdN=`-Fs3etD~#TjlO1FJrDmm-JHR(?!9 z5^p7=j0^Z!e9zWx8NzHYVA`HE31vg{6?(J&;RWzC>guz32gA_V@(jfEH;Rzf3d5gI zR$?A3uRzkecba~vAi@@}!q?}5hMkP@&o7iyD@4zfwSRq(>csmS%l@ju+uViL6|r#> zHqi*2slbbnwzK3N6DQ2BtL@L#`MhMjJKgD5ufSky(=wKN4;SZTdjjV`S^Pd0&XtE+ zD0>g>%}Lg(TJ=t@qD$X;=6~P64|JK$hM+~Y*Z6-c2 z1%(1@AB@5EdYZ8)v7`dgSm_$QN%q>3jN(PfDjAtwVD=(H*9IigQvzx3h{M2H2Z6uWw zZT}5(Fs~zZEkd=XnN^QAU--a4K>OHy((oUl1G`Q+4kTq@^yiKzxN}d4$3Xb`s1556 z;JrX(49{QKz_;bp8V0W|;0fRB4`*DevCGX&W8=@*#aCCJ##Pf@&PU;;AP^!eb2mgg z5_(N!KqQeVRN4|}t@fU!y_L0%t)0EjiP)LtvUHiNo4bdnZsFH1U$JtPmp7Z^1E)O zS;8K7KM-O)(cJyF*P!sgBggidYhr<>Mv}Ndtzem#^&P7aiGDwge{~iqEvcY) zsWq_8u(|>KL*Ufl)B^8Y^pw2Ngf8*m45FMAIxsLeFsXwM!-Fd{FGdP{YjDG=Gq;J`f)N1v4S6s%8Z}!o( zfD%T2AKqdj&<7!1+6|%C4|pBPS;(b&XXa<+LDRC+axxAm`LtmBmTjI~@72X$9OjKd z&WG^d^n>(HM(zPzuC|$JPn2WNzxnH5t&kzGs`U5wSh~#3!}phV_3=@U_~pxd9DO~O z1vt99>tr>P27dhxEWhQ5s$HT)KQ}Wk1;+33DL?ID;fTqVlcx$jP#Hx`B*|L;QqU*3 zLE1z`v?ul{Ap<)fX!X3fco~+No2~>Ra?C{i7j#Y~06FIYn!NNjW9jyZCF|yPbJ{}^ zRmEUfYgKwl88HV3zucxCrTwSe_}YQFc}x21AI-y+u4Z^_3F%7d%j3HRpNSboq6+?v z^VX!|V1eTSTSBpU_wwbJ-6$-aZrm-`-TpuJdXKs#mKHBwIvHTmV9$0A7=5T5oB5%o zh;^xA*AJEOq4reLs12L&X&R&D&H(>vDZS4^b(zC|P=`6XyZj&0@u9AD=H<6`xYb*3 z`GmX6F~^D*mDfWiAEnI}6lXy%iMHBucK?-e-+w zB_qNCo()0+7Jm8AaJK%a)7Dgk2*SoMuIA%>fZ~6ynOY?m19=|jxZ-P@{(4tz9rEON zTTmfTpu4A8hjXhr=EbE7F#M-Gx4RI?6vdoB9}XSKv3?e|Q^3wRm*3b?<)<{V5(EAaM2dsk7&Www5-~txFQn zfT9|+`fMZjSt(F_s>*W`$g(a9EfLio8FHgktR`;wXlPN>7<~PWb0!}Fei9Vc2p@8c zrccEILR>Ur?%I|Y*+9;lLjRE3^awbRaM4}v*CE0?XA{P38eksQ(Rvr%5zcMYT)!?G zIE+p+=sf1{{HFE}si`k}<0>!ZMYMH7IFO|Xzs(@FcXCwW0sl`^z!WBXLo@-#q9^VXsPV>V~D?R|;7|cQFqul1HzM!++P7 zKUr}~muzU&3mP-d$O#_XCy9gP%`SlrS}XO*-yftCPx2H)9rl+F3wey+EPY{|D}{r zoOJ|QN6VOYaj3z2ydnH&N8{m(vr5*$9Y9MVH^(#83=7ep(a`3nB0O4da_9nHbfMKJ z4BM2ImVX&^kw|mtvoi9$A)ANc(sIN8m^=ao&6xcWL&tsQJ3W(XyvSIgu`)8asJLXT zlX<#&EUr7E?dwE_9~onA#Kh^RYUB*Siq-zr2FX-?+Y|Ejvn2J-o%nNg*~OroM~Fww zq9r9)j;ZmiAJLgrc<_7YIxddccJKUch)P??5N;p(LxP;scCrXPzv;vy1HKXZ9UPD+ z%Av2RR)n{&m?sStkIPMfauF@NDGYr`2(Di_D&Gbr<6Y|0gKqdSZW+y~jBHQwiE$W{ zdGe43oModgG6-x!Z_kTaPgN2ZLaK`4yj*e{j>*OaDLFZQO$tO~j8gC7YPRn`jhiy^ zN;Nnp0+JsEddnN{O|)&$+oqlMd=K(w;Jcnn*bLQ z$cS>7SW-S>)dgq)ky=2yS4k}n63N!}z~m!AKI@A_BKj(;vYJNB77RTMBUS%NnET$K zgFFz(-!W&PDZqCKlT&KjWa2r>7xTuQCSDy*(3r6S11AIwZ@#|cp9*&%NIElmcLM|4 z=Zckbwi2pL4t9j>KDz*b)_OFPfc+A_`#4Shne|N zT`KZ4zf3|q4KZQOnPc$$%#M0hW=Id-w>p=}DmT-R4ZfWO&&RJx&0rAyE}{&I7{o); zjcx#%%@vSp-aa6Z*aoFcfUGJcG7-F_jtA9MIxCBzA#x&}EpwN%$u5vYor!4YHwlqU zSJ^Kb;3v3jz3BV3I%|FdRrTfol2oUw!GW2+zqjFV$hs(qC8sRl{2uUqA?bRLXoW$) z72*B!l%((b@2hLf*QY~#wIY4Ayz%W3zK@tN2iTf7=tD57lh2F?p7ek5Hc?4hdjmE;2{Z)Y?bwQ62y}BNdmwAL_Ow># zeXLEmJ^Ai(p8Rznx5{KuHf5LUth-EXa}mCH-C- z13O7LV>lUuQ~xQ?PcZsvbnOq5j%uV4j>u^7MdcpnSe!8$$}Y{VjN=C%JS_dmAQs)o z&CRuJ3;X|J7y8Ek54pxSZd&LLjm9^sbq6L;#LV4581fw4Wo-B|R<(_jVsCE3Y-JhE zjWKL__A%qDJm0g|5X8nz1nmexNON!Jvtsai@#5@qS3=n;)MJ3Mw=}`Xan=pj+kbLZzWJ{Y+@%AmmF3;dhI34 zqyx}lXK2Q}eWzPNy>cq^-DhYZNlNzsKH12jhqRboi&h)xQ$o}7C}csp7WZ-g=(i~Z zRv%x`3MS%j+u$H*f20{%!Lxe){lfN*hoIO}p%Km3xr|W@#k9p+T*buf(??r3n689i zMI$E}^JUcK2nRFaC8ugo3JQOmjQUW2JaY-0>;setZd;b@AO3X(8V!#Ulv-Xw`G!9G z6G?jgyrD*UlxU&!I)4C1tgkOcLQ>K9Hzq}74IjD|X`3bodod5<&nn~auxbH{y+ki1 z)R9QK`xnrYS@sqAGdzE}zExI1x}k3fC_zl1l*%^H@kh*3u@Lzu#rw2nx3GHht?2hl zDEW(j)%y`~2sDg-x}q5Ql6d@~Y^|!KVx@4SF9gvG!voj2@bhrNF7`oWJkF%J80&cX zW^pkQWAMCwme@kPUpN4@$x4eX7i3mF1ZD{U<`@6T_3+K6OyIhbZnk{s=S+7ZPR1fB z4{tZF5Rw@b37%R|Sv1AQDLJ%A+qp74&*iYb~{k>Et#Hb<46sWGBP7ukyV3BsA#I(+=! zFpcfv^E?p?%dn2%#)}|(P%}WBRicP)lJbBr>Xit_9n$-Ch5;h62TTK1^0R9tbsZO4ShFyF5P;GxuqA2D7ehlSd~NFrKi*NhtaUe^6RN-KuvcG?eGMZO-(uVz z-2=dw*9+{@96bJW)28&;QY}4Jc`=qfKs3vjuH^lJ8pZFumE%?eA!m^BAu`9mkKNNV zvSFgUDW0}L#W>W-S{5nxxD8H6OE+S_Inqq6ybEds0s9VlhHRF*k{jKjSapDZIL%gN zbHm1>ALDxg^Pl>(5u%#(U)^KgZlw*=vCc|ekkMqz9@L!3T!J^-kiI@+NN4Rq9jY$D zmQ=67bA>s#-ZR+aX3GKGL~gB}f><(pe;6pd$vLyti{D|+lbFAKfC-y#SCNhkQ9j?F zRU()?(|OWLuEi|EUbUozcV`6ry_sRjq&?6>hQ=A%HM`p&;b})cJUCisG4Gu4iGohO_QSQHBPkVukX}xs7dHW(ZTJ(SJ zs1w~ZtQ^lu)2exqa~y&b|1Mv9z3JWnfYn$>F!*#9z9q24I-UNDNdoJHvHqH6Esne7 zj#B@7UuHO6|F0VYiq577FkaPlBSJmf1T;{amJJNX!!-6%%PTKy%*&r#g{A(bOaIr-o#ge-fy9c2v190q;OnB zzJuUEt+J5JkQ3m_VnH#v%^ugHRSL-(A-Slk5V4aip8#Nt4F=^UFS<79sx*kJWv=(E z*gANT1Ic?y!kSur%r}?h1uVGmQUV5T)B=p|O+o|74lXG6Ef&*y@b5p*J>;boWsI{F zIEAH^as6)>y1$xn%*)1Z5p-}Hm#@~oS)MK@=WbW7jTt#vW-QE(F^vSmH?>IHe`O`*FcJ!F1z2a&xckeIZ)`{mXnplm zMkd-2_VNn!-2PWcS_kqwNWm+r`3Gxx8}~A6Z8m1P<(R10gaJ{b&t?rKl;a}=y9~Zo zG%edNd~aJ^(O~z^M~lJEySyQt#qZAMxa9^Zcg$**z8RH9TnSb4qoZ&%#zm)_8{sZ;|COtnd zBgcsMjznt5im)Fw5aWl zsUq67I*+~*;NC{AIZ22EHn!YSI=5O|zqh6_K8}wVBVbhgD(idCp65s3>Wc5MuG6;@26+pQ;<9* z1?)UdK{yZ0>3lmV=vEB{X9fuMVaXf2s<4HCHaJ2Ps1ju*P z62>YKWN53qyp;h-fUPBhgD?gbUaQ0C6E}c}2*LFXJdQ*&UKth++EizK7(Q~`!5u?AcAongU7J%}Qe?A6 zXKjIoNbQbeyu6uG_p@Y#x2`oM6vi*z(d{NL{5TOn9iY!)e^GJr?&Uw%CA`Px{0Z0V zH7e7oZ3B}VdOe=^@(VBCVpDN{7Ouc*K}Pl8y1Zd*5Bn^0RNfGqobR7@=bPJc|6Wkz z!$9UQXMhXfOvC$4K&Sdp*3R}Re>UXyrLh}9r^1Ew#=u>9R3Vkoy5v!1-x`SHpW!I~ zk5xlm9(HUqAQl!3Ucq=(R%wrl0b;V3`V=iZLnT2#rmRiSk?m5)HdeVoTeZE)K#};2 zdC=Xw_LlNw2AZIlzQ7Tr!o4w>C7&#>`md})19fS`Jpp+Jh(hY+`ZKt10IgJd;(+Z3 zhR5oOCfV2i^hNlLS~EATZu>WV#0k~8 zyD7Ht9F;lZYsB_25Hx<9%qVsT*zc?_0Z+y`QgiRI-w6gQGV*xYStTX81zGHpcT4N& zxWJ6jW}u&8)`mBBIc@gM$y)DN88ec&+bV|T)E2hLB6~(xT&J`Ocvg2;Hk4r3;WVxT zHBNLhpwSF)Sn6U+$5g47hIebMjr(F=dg8x~iq+K*kR`1tI`cg!^l*vi~#?cla) zt2UgGHpKMvOlJ@LLXcJ~H5&7RQ8P0$ttpimW$$%P?gfAcrJ&L3;0Z_upvugAlF9FL zU+rw{Tv3sb>GZzjYDERSq9W2G^+4IP;9zP_jwrY-XVbIXv%G==sz4Bg0)R68hc*i8 znH2&-qcgO7ptx8E>u8PqskL8NQCtjw;vz!)BK-rxLSkdXbcP<6!2NzPu58u#kuJy_ zU>c|jgdA6|4^*Ye3EOI|ap!SWX7go?AAXujyxKF64a*9b1ON+NhNj0pWo!hlUCdYm zc=7Bwy-GG`{W8cyaj-P#5-i6AaaX3`PLm|7#}uL-J?v-hEJFFYOatO^?o7~w7SgYB)T^&JQH@xF9klwFcsH?~b( ze;;TDwYBpSs9nCB)+UPLR`7vQP8=QVe2J;^_efU{70|gxbX>Z6C4-_%MmRJt0kM27 zjV@j?+aUh9*6=W%LZ8wzg_yEvy4P%_^CvV$bYi&$PDvf7uGwZOpo7f6YMex3-eJC0 zpI;ulS0ja>SH0r+Qsf*3yjzze1xWdRXZ&EM5ojskFYq@U>;Nh7gDhWZESe<*{1m$n z(gqhK0aA_6EUNhx;43%?IXkO4EDzrzWyC{{8@gLc8_02bJcYz6pTxtbiC#g+bURuK zAu(8d5a1JS#^u9p3N-G?xQL~Y=@^R}Q58|#Kp@mzCRa1Mk`He5haqvw}lB zKqCR7AcZ6%u`b{~K2Wqpo{loxoF_HK>#RE@dF?EPz1rCs)T<|jG0rzh8dwTZI+Df} zNyE`ND-A{LsF3{pFsk_*PgLN;urMIJtXD!C#A?E>^G4igX;KB};x06PgsULQo*PIc zES}i;C|;y?p*+H?_wp3u_!lU);(qh-IgLxU9IRQoxxi?GlLS+zIIV5{Fz54{>U1Wo zEE2n;R9~@Hk{qEcISCN#Kd6B7$sJ#9z3w~N!|PZc8Ov>zj;iY&!uUyn)buX@?FC!M z;_IjE-ijGcblwM7Yv3gaf_;g4n*sI^W(~bq;p3c{Z;rwuzvtV9BgpQq`gqR{3?x7h zSvOr4;DEw$$jSP*$SDOe7Je=6A0A*RGr7<4gzpfv;V*;mYLjzf4@(?d_}()A_@saN zabsj8YUv!Z{-B;Ix%hQ>y;pl48BGT>tNjkeGW~So(NP`_S;B0FY+umlb9Gg71ZJrHO^&(;>0%~No>S>5tNdjy(PSA&H6 z%w-(+B(RAk?5s)snxH0GW`Iq+NJ30LzpAiEBoCLn7_{OHKrS!@jOrUU z^oZBK%eT`sF|v3WuQjn?ltns^Cw^6ZP`H$(b5G$9)4RC6V&1^7I^S(AY*pPox0LlP z6_=l3-2fkBb0Sons0j2&3vOgYq>9BwEq|1D8eB3*4^?mBZwFm}X`u1Pck$>Ub^wu=ZQ`fEzk;qN&~^^>|B(SImyUq_TA z8L|#)GEd7CVVL3e2(qy{rRsO4*3+SllCg%hwmDoL{-wTML`)36KowS;$;}u;?J3Gw zsT2}zV~=D{|Ca8U=p>R$URq8fv6!?9WXXl-v49;qIT&Gk!|2anD+5QG(*^(_HTB8% zF`i1Ph)qo^=VzNJ7!^a+JUM&V*SKSVEsL}8OjSI|(L;!MIkXFoUD@>63b0Yh`Yg6K z&?psOdq~}X0YTJ}UhOWLc!o)1Via>{Ow2!}WfT=20AE&OjZ%Sn5f9ioJ!jTNEh=)l zTvm|moJ#ewe;j}a71^fjIvrGSYLD5e&;jIgee`6Iao`SLu<71{ygNITozIFg%owl_ zCPRRAAp>h|_SH-PH_Z3T>?lOFV9-qtr{}t$q}e(zKi#O0iq+G| zc2cA^n?{v;tmV6dc1mo7J-KvQ0x;rd9AcT&M2$*HM`15>e|?tjM7 z0Kf8Byh8Fh5uJ-?YrO-5oplxcC;Ek1FB+2c9-}E|dbg)PD(uG4fQ<*2+T)FIz~-Ic zf}%pCz`;kz;2Y;9emC)%OW&S{r3u*I)|VtI0jQK4WL z&hYEf5re)oQlVgH2@6f66k>#3onIW$D95zQ+ynYc4(Gq;A1W3Kb$&h+%wqpB+~Pezyx&@5v*M9whh;N!9Q`y6n2T;RqpdQOWa~=`g4r&ZTQ!>m|+tk z=Hd)UkmPAA_SVY><{$`0&x~clbE$5qwMcH5XxaI-j=Q$Y#pL$4^2oEWbfumiJYnEHafh^xmzwtg_a*oWO{athAz!1|c3~D^`}S`XxNc z0=4GNVo}6ov{~T28!a0zUoV6lNwWu^&J|cT8mu0H>b4h@0s~5A%5?~Vee2KWkaNhv zt!C8+wxNi5zo47`;z&zoT;F*hjX6SX*l4!0P-3bsr0cQTgH?OZ0iPxNDY{&mK)#?U zH(*qM-X{(soGL>7lETAxjD*xREjFPuwhzT8D^jKD zFZ7S7wum=KtD7&h>2_;X93~G?AE21Qwl@FXKu6P){6OC^Ni|2V^OHyOK&6*jbSRQn zjatJdMX**~Ds5d)$|>d-t7Nk6er;k3TX;kXc{~X_LQ!##QC8ik4P|#w#78LxrZ#Bp z_)&_b+J_`PMDb_NerI>#J1EjsXa}sU^KgVg*#{GE4oqfEJxX~|2_Z}I-kJ!0=aPh6 zmbAMhWRWC!lAOFEtmVlbP)0hg!A93DT`YtD3>h{&LjthQ#gF2tafzCgV-?*Lm?7if zTMr0gu(q~OCob;}g*r-H&$}V!m&EkPZ1k1{tq*~KV*{klKaV7)*(dq0VWtAaC373V!Ek(;e_&4I zb%+7`Iu2zNiO(!pM$EkCSKm_LM#wCGyR7|9T2~q)93nmJ!e@Hz|X{+9ZA3(-H#*R8FyW%#ynW3BkkF z18nZvlQ>~R$`eOb$xjdeh; zaIQje1){0@ZdqpFH#}W|wtw;9?e0FCP1^Jrlf+{6Mn_PwIELW+bv@MW7%rYOOvwZ5 z0h?5ep`5ji9_o=MeU#1T1K?N_lZU@+VA&%*6nBP{{^|& za~3+_(eREfn-Zay%Uq80Ua~kw^Lq!czIT&?=}Pqv1jnL$k{=0L)GoUR`eB6a)q;Mr zfd!7~ybR2ti!&jSR-{*R;cj!Sa= z-}v(Y0-`Jj-~?Q_#d75Ww`D4B%T(N&19CSE+?JL!wNr_ zIj1tuvEs+~_vdqS^S}%47u@&t`CRWy4Rfq@hR$B4I9)2z5KCe7WgS~^$D&jA(0RWOJ{cQ@E~EsRtXMh_ zG;*SD{!)5qmGxOxvS0v3;4`QNZ=t7{2j;5$LlZo%Sx zB?KF@&xq;Y3Cnf+5%eVjH;}&+blNyn2t}6>(cPyxt{N#tEt;cryoAuyqW(N;NgqWD z;KCvHx=?(Ijrt{>hiWeOw65Vy$c=bvo`whE5Y|*kJ{&)rf1W_@$zSJTCfMG+!Y&K$ z#+nus63L`IB*9$YA+6cWP6MrVhdpKo-GDZSAt;|U4emYtEUjY);i--qra90wm*U3< zLIK023f2E)00_(O+ZrnD5b#)fVjO&5zSf2ySBEPxG{e%j`y&vuTLsblmCI7T?6Z4>j$v72r& zY|Fd1YZ$@VM!}4AA3I_bH*t6Vbr1F20)nL{A;Eo*L)Ff*312bXh4OPWX`RaTu2SaS z!hT>#CbsW}Dv!H}na1nj$;VZr#XB4JALD2=z_P+ze4PTHS&qv5{rvqMogF=WMwHV8 zZ`V~}^gMrOXCFs59~ak(l}M?s);xaipji`IU9HCEyCc64RXkRh2m4)px84Q`$DRgG z4Vu+{JGQ4HO`|x5hikwMq^9VMRWcZBZ}(RcPdC^Yk2FG4uHg5A+Gy#X z&YA|KdR!QBU!^vVP{DP?g47_`_qaMIqf0r3^dKrZHhWb96t@sFMMo;z8w2kl5!Cw& zdqykHKT@v{)pZD<+NK@59w8cM&tle9Sk3}RkW4qNz2NiouPaavE};lQL^j0jQr&!4 zDgzi}?b2mXM$IpHGNGL|*0Xd;K+6RNL!kjB%*ZE<=%+M!kz^?@8W}mdkzV?fI@M-U> z^l%(42*rnquO+M1bZX;qO;lJ8e`AKuF)enA!PNt^=GJzg7@N6YIKR@=7$#-r9jR$# zxYCAEmO=`gD7ygs4X_bJVW`^vdOCtQcYSUn7FwcZZ?FYAs%rEFgthr_{+#Q%q3Rd= z(t(s@iqN<;<%5npC;w}sqhyoIH968)efbXI|?5>GXh}>HAbuXCF+Qq8~YBrdSv77 zp2pq#mLu&reX@cd6hyqFDx!(nK9BnVJ1~!%g5>j_pji7dXaqN$JF2MAAa;p5sG}>Srjn3e!I+{?Tu1Y`^u1Uk=myD96;+db za$7CEpPw)f%dgg*~;cC z&8W_1lv08v^31X8REIObh**+MSjrZkwoK#U@Rpk)Rju-$0&w5P z(PPvX1&Ju=d5?LL$i#0j$7F5qtO|^x5{|z-3^dMg66ieTd1tH(J>~Q6{c8()v>?Wk_&%HX)SK_NA9S zlv@6j0FhZnvTjzG_#HVWk(dGW!$XSq1x(RD9N#L|=GV;AEr`8Eur zF%TLllOL|DkA5XNm3&w#+&!p%NmhM&@jFw+H>YTw8Ts*iyABbl@*QA}x$t)F&KKJk zhrDrc1woFHz@=IECbrHFxGphSjL4aSBUu;Y<^?+-e5g=FBqBXqH0jA)u0pL4zmWu7MUtKUE0tD~$lLaDudpG-bu{2p5xc#mjw@>Q4Bh7rLLX|j8nG~_*)-mOk zxJ$}65dH``Ss_6l5XIXBo!b8mt66+?0Dk$Q@BW@ASGBL3tB6-R#i1V>Ui!z}XLZ1* z3I9kg!{Nhvpir#K@vUIQxerQttx-KOr##A z3-If_ai$hFutf-MAx65vaU8p9_5 zeIqQ@LenP|5gFc%%eVQr6#!f=g*jBd#GQgX6dM%>;M~lrbI<#lycV6Y)xvnsx#45F zs9Q;drB-Avnsr=k_{`)Z3G8b>TTsqkO~v-90XQlXvL@XZz>V8CrvqLT_P!9@1%4nD z5x=^1?XfJcFrIa&{5skzrJSE{qs<)CrLR8DHb+*=MlOT58fAiW;Oz)5cS@p)GH_0@ zUApEYb(8zNFUOr5l(px9s91fq;lT}!#w+zH>+O*z_PyIyCKz3kj+J!~YTe^R+ncl1*^~abpv$R7aF;U&k z<4Npw+^EgyDAgMs$-EK44;DmhSld;xO)DZV{g!UykOrhZQj}op{9<2aH#Xr`j6^j1 ze%pGfT6dQgQ#-FDH~VB^cQs0t@Yg^rq!L@t4Qj&+skbYR>QmulMvD8lVQjbZvMK+v ziEl<0jVr>Eb3tp{7YyAURG1P%S4KyCd;-kk+Q`PwHPcir8SOn)&0LgF(YX)kx`p3Y zLt`5d#nsw|hDN1^ViCD+!~?%WcdDJvma&NksjEfPNNh>Y!G9hzd_kKhUZ=TuyCYsA_H!n4p zF)h@u-BE8hW6)%k(ty_z3u2arfvtcn6AeNjCyOVAvKzZBhw0WtvE>7+LdY6jnZSxo zvsyFaL9q$5QKi!WNt9@w@zblZeb5iQ-|`NjDieC%mAhK(wrF_6Snhn-8Qy*aLDVHH zj73fa#~3ISMXuPTN6KgX3c1f@Gb+S56FB@={7oiOR?$d`*CZPy&~R+V5Q8#WLxkgG z{gr}O$6umyV)A;_9FGdh;JQ{WsV+N79 zRQ>0(4_~tl#VstikrOQ|j%G!#nWI~cP(gSF>}$@(jh}~>`L?W(y;ZVUclFGF^3n@Z z@-t-1B1*I`FQs=*@~;4U@W`2n#y^!*wVsjFSc`Yyk>ZbjuYsFa6*iwp7bu>vG|uUB zg2vE;)q~{QH(x-n&cZQ^87cr!;O_lf30gW3COb4V-Zktqd-gh3cO(y|E}9}J7#a-MFdq8iIqB#h$KYbhReQX5 zD!S#FtM~W`vu%%`htm$R#}6JQU)IrV^%CoULmp)euemKt&*J5bjqt~4qFdPO-F#o3 z3~{>=CB(T?I&5~d;3eKtcVR6o*14X%X~da-h9wiRU@+qck})zR8AqCDdlNPA6u^sN zM)(6MT;`&iKXR3dC1zLb%`KaiA}<*jTx-Fj>rS=5kgY`r4;1gb!w6;u={Q#26w)0l z0}Oe>253C+%bcN^z>u+b+8_mSI%8wpX}*lvz{i{ax(pYYGlbX~MIKiqQyHe!*%6wu z0L{3YN|r1hpz)Qy&-kbc29z)~r))18X8%d1I`0Ucri)~|)tLFoa2!JSl76x$)Q|a! zqrB?79!7@FUaeOQx4p|5{tpgYt7q>9;OOm;#hZQDG_nije#^K!ceADUI71Z%1cZT5 znNROJ2MIHlK_t8SpZz9c63OyXHtCQ~+oF(NKA6sA9%c!vUJhB)ecOEhe}v6HED*AQ z8`gY33;$f!%f~|L-C^NHNL{^3{}$eXjn&H!t4c=gYMSVB+(g@ikneOOiXPY&C{zz% z>+&YuY@0T8C(mVAeYOv;2UBZwBE|Vy(?|xnev~;wrk8QlY$+ul;Snj6Mceh1Pn6Ql zL5n9(*OZ|!$p%G0uf*z|MQKejbEu^x8F#F|8j({#Oev3o#hJ0m(4a@gl{Kz805PTG zI9y$pk;!XpSBh?tKd^r(Pu7xrn$;6)N8BlY&KG2)MY)mO5L(IbQJ9x|88P1c5`X48 z>sm>6kD87V#JAXAP4c}X=yK3-W)6)#QBFs7St0lFAE2K|>nm{HG&nakB{!ys#jpiW zBprkO}qb*(#2pCV#;_A z;J)jp!agW1wy$#Y^K%SzxfbZJx;*~CDPWDAo6D*IJ4avtKUK}#N>%Kmi?fqTZ06uq z9%3WqeUqf!i457L_tg!vqKDcD;LtY4O&%^4kG->=C<-Bx!Av|hgea3_Uj!2wC|rE1 z5#xm=)6PXK-qGp9Ew*vt;V6?Q1b-itg8E_uE~GM%As@LPER@I6AKAiMA>_%YAOXA= zEQF4ofYF33QmouuG`T?twKp>{N{LAcmAyzewZ0@i&JeNHt-W~XCZ7KBiviVUwC`du zb2Sf!6vmxJ>D4)`WE?Wq)~zV!RL1c?`+@-)KF3Z}oi-l}esHb3L0v`$2dS$n=ZaXk@fLn3FJsV`zRin9>X z#&v@zKE2eYBOcrl>@G+Wtc#E|uIq4ywa$w0MPRv@xN#r!fc511An$ep zrY4ssy^AkF!WlT}E#6Cig^qNE6$KCQbv@NIt@QVGS>tBs<`>{jz zXsg<689L{f4uZ(oNCwF)I{VpUa@;xpgDKtFeqI|lZ%<}P4|o?-B#>qZP?~Pygxk{` zxyydq9OHL~9s)wJZfDa&_CalZp$?=cyn4#Gwa&Fr03ct{CFq~`gfmPwQt1l`yT&io(8J}R@IbZ2x;yHtz~Fs!o^H?pRG zU@$xUc1-gG6RmL7jJEcki3ij3it2Y;RhSTBpr4B+g0Km-+R+8F+Udcva_QuAA75Xs zKwn2!#{fsCK<8Dy6&gCT*(YVP-3>JT309nc(_)TjryMSsc^Arb+#}?wx+_P&5Q>$t zA*Q}`@#;$Y5*s>r6007vrSGE2Wle@ezL32wnuR^ko~Q}zE7yc;AC8CUH8;wmyw)c8 zuI@!4@jbl*S505|p`8>iCEaFo+=V3~+@jvQj4q=h9Y~vt4RBb}ExGzN`;{XsF9$4s z%S$V_l|Lq=`l=X$6M| zCb?@%-tWc)I0uqUo+Z|h*3sR3w0yJwyZ>gLt-Z=NxMsDRZ$(+%^NR)qP4U57OAE>f zIYfQ+^YGk=ho=Gu=DlJ%c4ytvVCL^RAXZ+c!&Ah`rNgVj9%mc;zFWV3czv1>6M`3` z3H;d}RpVsB`XDjkYwpjW>Pzb{4y+K3b z?u9X&67h=36)KX*^HgM@svwFDj%p&`DJc6H`ea-_EXDU$^FH4ute~<=wY3${T?1Lnm zn=@~bUhuZ{ogCSsLgCM;UrnW2iOXlwO+;AUN7l}~ZYZe%T5tSqWCJ8%lYCPQ1X5f5 z+u5}8EFW8yE0t98 zN7B}F3P3x0dYoo%MuFXNGAfWw$vBPzPaDDU--32<$X`a}+XaA^V zUKsOBZL^e--+(})?tVL3o16fJ%egjXg_J~-=P>e`Dj?awxKci8KsLE?IQ|X@#U2st zrQob{+C%+sA>DGz>*{iY)bSt8vn59QQz(3k{^9LPg6`epdIhJ!BD>zxU|NN{0j}JD zUy!Sn0dF_l?qZI8wDCasS1&xdkYq#Q-eY5G7e=)nni{!FG&n`K3ypl#i6z|E5Gdr> zrXrHzdMgG#JcLSWKwF_+d;OS|WTx4m@%KB5t7o=r8hq5#=mR}-R|`BT8xB9harx@+a@N%_oa9x}-XCO=lj`?Bd|-%*l1BEX%2Y0JU{~Vj zn~5Nd0U?`ohu_9%cr#oX!ZYa4jmc0=O)>&-^Z0xthl~XjWEiB{_D!lbl8OsXGQoML z7$duH4yWVPAZlVN*q_V8qhKh!DsS;5GH74r_oU3B4=tgk|otDK!}dU|O`T-VSw^8Hf(Tzh6H@BJ#>)lQl%&?>-p*gXwP zh+nO@+8Lv#y{bE@W3`c!a|NdEAU1@yy1rk~NOnqg!5Watq2umyFSu8R4^-3cz;n6f z(+XCW+Mua{5Z}S?vx>qI59RrRoe1h6Rt#%p6aGs_hakVO$ruB@u~}0X)d+X*$V5Dv z*kVwXJjq@RpU>g$2&I~KYu8TM<5H_Da+|4IN6d2`v`V1nho&+2p?*avMb`^Bf6c8> zHPTaah+O{XSsV&Qqed6Ju}&F+2n)znhdZcxq_qLE|-jKr8ZyfQj^LOiF9n#=w zc{V7rBu?Oh)-A}2C^~vsSHLZdAft6@HH{&xhokpnBal_;52=`yw)xA%SfidObtBor z9wSZdb?BU|wa6M#N{T^ORzQ49Kg1%yKm(7i*6?v44ru%>pYEh$h_P4m_hhfQC`xsW zDlb2hSU=Oy9ay(QanrJMGe=C|`n|TC|3SK*U{a8-slDm7i9yGu8CR&=?UV&x7Db*A z`MU59P0eiJeO^uvetxvkx9+Lcu{}ru=n9s9;Ia{$mFVI)$;;WQ%lnfX6VIh04?dGy z?v3XSQ0S{okaUcR^51XStnQ_MW%9RFW0;zfKW_}HxAZ?Y{LF#eUU6r&geCY%-TSjW z_^hhC?Q_9#i7s%8{LM2;(f&sgm%zo6rEj8H9lxW0lPTo|xbiBBv${AaVS$QsR}XW= z_##3Q!n}D;c2@IOwb9gLtrmx9y_y9F}*`Z;o1*Nwk^$H51);duL;}B591Tz z!#~iFVV1WvlWDc()zFX9oo9~rZ#}#<=!m@f@}@Vxl;Z^#BOEBoHf1taXXLP}Qd&#g zYDT6i>WGv^h53FOYY(wsy1VU*B2?KPE2+UC>Kb2$=IWCvx5=F;e;dm`{r+Eemy%D# z8S7f(6i~*qm=Li9g#u(iyskhD6Ir8Vd>Elg zsRM{qM9tm%fLLX$nwdzv>7r`3_*$qg28Sb~2ojXZ%uMxrvE*RgL2;~am_Pr(47+|; zas(xo%&dH@3N826Adg&>Yso05$TZKnbys?g(OU9_0Bm zkq=m=?s;*)#)ATAsC70q{I+x+I19U?9!g)^S2^BU%wCI3Gq}anZ06;59Ofs4UqZQq zr3!3#X?NK|eojo26ZbSchN_wtuhf zj1ECq2#z0%h?kI1s@*T}p+zI9B@@*V%JLT^QTgMc0&FNuQF5!pF-E?g@)0&1Z+R$Y zl|lioKZ+}R76X>mw0jTb+gb)o#{1|#@O$VJ{_xV4jiFRX&^<*DE*N5bIb2hKVODC3 zX1W0rbvB>$3A;ST((iihYyxU>p%-yFA^N5{LE1WQ&aEMBe(Us5(I(bjCWs#+tdHBE z>6C5#=n?c8^Y;B}6|+{CpnVsyh9_UW)-Y-uk?$29pDiKfHUprgG6gtLE!6#t{C5Jo z?^8A}>C??HY;lp|Gky*Ds!vix;IzesMIH^?` zq}TlPVJapq^pa-itjA`SpOh&I*AkWXc4Cej*)6^8cuWL~IY?5G* z^HQ%3y^VAD^r`WrnP_eVG8h>F+w|6Y8z$mpRL7gDU3v((DvJ!Mj@l8M$PBqryAH7C zSHbqr22gaO*4i`e-CR}2VpV_`25Z5rW8(09hy_z?#1>NR)6)op7iybS8ed!((Amdy z{kRaS8{Do@vJgTrlb*h|5KhG3R@<~dQcb(92SErf9?}Out=kd7J_dq|jj#nnfsMe% z$XIYuP)Vi;&I>xICi~U*pENZSPz6+T3)Q1mG)qCF;JlUf{tm%O8(V?KeyE+j-(DEK z8o)LU#P=yR8>{1IECMdq+>z>+-nkr!rER&t%59Z;lw>UBjw7JM z&MMiGA*v2otu8;qZ?;GT51dfrB$%& zMcG}H8&y8Q7p@U9sWNVtS*1FFm!?8)9zn(!9GTU))CW+~f($>|GR^wdaD(hoIHFOX zrY^<)?bEf!eWdxd?0xj~TiOu#A7uS*5A{=f_OZg<)i)JVww|o6PR!$mQ-vvO;MZHn z+Xuo;gz=KN*)Vx*nta0Bmckmkgcu(nLGpn?6nPnfLJ(e;6mz#6=Eb!A??(ZK`V_ zhV2kRx%!`t(CdKXF9rUw;GZK6n&J(R)fq^v);L}q#Z<#F8e#_^FOFVP zv(!ywNsPFa1Ihgo)ISHMXMc`sbN)Hu#Thi zY^~Rna_;(bHdw8h$B3IFYx)K64XtoS?Tt{3kU4e}b_;KvOeYAQYHY}Lf?OnFO^tQP z&(sKzJ_9T0E}g)V1w>`70~?$ALMu&X!ZrR?;o}*}4KVVnuI-A@O3lSkD#uD2^NMYV zsfMRQa+LcLYWHjj6{=%X50)aT6SR#D+G?)5SOqPlhi+Tzdr33s!Fv>;CM!#av?gQ6 z&71xzr^V;P6W5)ZG#sl_V>Ij1?-&{GzEdrRVuk>KWqd39mijpQY*Jb%Mw^H=oVRH* zib9fybWifX;m2RrFe3D23M~^G=IgoykGqdOfLmxZ#o44=Jlrh(ZJCBfMaPFc2sq;j ze7D{KxPFp)_Akk`Zc!+IYC8C!HVM|eDg6{#hBZv4V9f^R7T#FehO0oOWUkP+8PNfBSHj`Kv&LAX^ z&3(i1fd+o>D6{GxGJ-N7Fq3+mm(yNMzY2}R8?pWPuDs6)2*p3c_Vv*zCP*EjyO|q2 ztSAPGf{odrVsKv9!y@nZ%5;MqbuW!=TzsUt_>A0dpVf@;eGPvi0tYowlN&9<0=3g1G@ zx__mf24i$@R+jq>7Tli~xSz z%`NB+QqL~?Gb1TvjI8uRmHm3XYNSE=?U%D+9r4F7Fs41@Jeuf@o7ESN6EIHSQTmsq zo-UAa`9m49^}$DeiIax@C}Bh?9{z;8=E=c7jE25fCDDvVXm9bNZ9cToR=-0phg}}FcfxNzpiutC``O?3Wmg9 zkFeoPo15?_v06eO?&nODPr=rsYH@NuK>|pQ(l)D!0+F~<+Yc=N9K)^250g$hM*zCG zM6(k36gr`qAF?oTHMborQGJ0!LbccURXUnLRovA47!c_VfdQX77NP~bc+-y!rhb5f z!oVz$li)HN4<@-&nqedBa4RqKEcU?0C_W{H^IDy-NtA}mdPuWny|arJKh?U@XYngN zD64l#p;FAljHMX5-DhSSZB=yaZw!U~KOM)D%i?GMuiPN0X>S*OxmqS11Z>+d5+Oz^ zR2j&6%`tLAg&SbMU8T84YjXQ!yQ&0)!97=a_PQ;GEo0Nx~Xas>#$<3b!jr$AgUzw!86N@9XZ7% z#TmC;{KH|n=NW5SqBw<2Z={7oa7xj>^VO+Zh?0HzD=xE>u0a{a)vkMtDhnnf!&!v^ zy|F2OBbExUbQ-PXlt*%kRT&IXl9b*}rzc&m&Bl;uTCV;8beg#aaJ?dpO&M_g)Lp5f zaChNcSwtAmm&3^e!q>wZQ(8ZAwBm?%NI4qrI&IMNt&$v=Q;<_;Tt}Z~hE35`xQS_+ zxG*i7Jhq1f4|fTNZ!v=6S^}e7S}pDX$*%iGW2=!f4y1>=SR0=|*K<-hqB8wcEq`W& zWt0~?^mSMwkp;I1Lbe;E`H)`GfYZ=OJmYWwoWdev;M^XruZu?!;JV56@XM~sVgQJv zNH1Wb@)cZbKRr&s%L6}L{4{*n2+uXDOoW8csi@5xe&!+&zHg3l^wKtBew77Ti{s)bS3%F?Y{YaO5ypIX^f#*nfnrv_Z3fY73{oW>(94A74m zoBWSb$&6?EFjYyZDF`1wb}V}%b0b^j$45LiBHf_^4pCt~yT)!gpgZkG8Q$3+AK57U zM%bL4#f5o*jcKnW_D38e^^xYo6jo8QPSzCM;2A?}(xcKm-twKS@tv+NYMWi`COB7x z(rM$jOXN+j-|wPjhP}0?!~IkiO8~2C$}7n70rGxmY}T_GIBU>P;&S>p>a1guwplm-O!?K=C_Rav&2iLgy7#iq1J5 zN^X$Qe1(53m zknkOz@*g*gQFUJWIQ^^+hkME68s*kX5ra@i>GrAjTa5YhF?;znhq&-$=PZi0Y+-~{ zG5ToshX4ERfzz3+>>X`C;Iqk1_Q&9tBtP`uZI#N&&Tytp%xk&530W#LQ^@*|fY0>F zF|w}i(tE){;eDn<$Dz~>iCA26UN7|YX|y(P`y@>M4Ej(q&g?W`N*aU5kw6Rl176rp zXAsgYFZHp=ygRnVi|x11yy=2u1Y`nUHNY7jW_j#Bi<(h z2#hD?AG}muqO;W@dXm=c`9HW?QHld_*GAt6rIA}(B z4)$(3lr<}NDtSN(t!CcEbZoiO| zw%S3>s0o6;3Y2}~g~W^QZRL7gNJ-ziXHE)RQ{4FhrOtKEeA4-cuVtj1)9g=V zhFb&ix~5W1%SQLqBj(X96fNT4K&unkPmN6(NKxm;+v)VWhTR@YZWyPRuI8#=EkzDB z(BOnbhmGe>(7$)60aV9>-yl&vPtnwjWH9G|+wvfw?X3{l%yy`X$d4fHgTZjf>?d?h z<0xZKmB{=z|1vxH8+!fftkw3N%)=m+=`XboGh|E`yPRdMeA)Q_aJ=+_@~Wo)EtbRW z7kY__>Yf!){%#fKLUr)wxQ?k5tjJDW?WKZ;T6RQy?`_S5YVlKds zPX2jpRNLnT%grPUX&tc%`mcV%iJLy99k{EXU@!64QB1VfE$)bdf!Fad!`57 z6Rvf6Ox_e{Dsl4J%-<7~y(3I9y-QWdO+i3&eEpk7)b0AlR<$(@Z0;G!E?#EUoP3

KozXT+)Uz@nR&{~p2uoElJ z#U=y@(DrK63A}lB>WfQWkPUFs2HPbJ$wTB%NgJQKW`)#E8;22AOL`G0Qv!BCu;F<4 zDnd_95yz?nw7FpL(Cen6QsQd#eQIdc$AgvSu#n2YMT+nS-2blkUSlX~p5dzS8gv6j zgS3?rC}~@;@i`T2Po4Ql-TYN0Ux|C9{uFNPFN2UMd<9?lL|qJx-c=63NHS)E% zcDNFI5p$jJNn?xry$*1s6QzNu%*Oegh88zK9xi*?@VJabx$b#5kI7i$k5t3)D!%F0 zrI-fi0>I|#TGkLlWiLjGeK|h#W2(eYIA5F`9ZHc&P$b&9AgTt5*GzfN5_Pr-G{#iu zR8q2-jWWWXk*g~3@=k>h&)3oZcTeH(v_V5&ol zAQqkQJr{$a8h1g$@oa4fm)p;XzoUbBoXQ9UtxsmErPp&*eF{AJW}A6!6<@_d;9l!* zs=KhOogweZ$?G$=~=ua*^@&xz11&fL?vg5#3#Hk(I}f7ZEj z({F2Te8`OqM7k3c&`C)YC_R?HxQnDHr`g3LvVv~ zIcs0wNKrUrvJdV;GpJ-B!O#!7X3f#vgVsJ4xU-ud`->jWlw{Hh85)}~3oI6e!t zsCK$SpR2B2u}SKOhTZ`1kQkUt=fU}RP&W{20wH6uBO8Jqo!r|*JhTUHg)06Wj6S;n zA1Oiw_FKc;Ie`!b^~pwc2MCtjaHXjpmjQ_|)nDFu7ecvX`EV&8r9hn`atMH&@2snGf0Vn zS?)vpOoE+ClWWJZ9nN)B$7yL>VE$-mog-=x=G}nZ7~ozFR&Md!=yTcodbzzP;LRqp z4c=gv!~G@?zWoUrT7;|jpGp+AAs1sH7qh|FTm`4p5Y5$)u;~(Cw}oGyiIFfQO)hs+ z5Pe{Vw_ZDx)2?tOMs(w!WQ=F#9GkZT`MX*P8fUK}8CpodBNO?5A%3c>(n}B|@};qV z@2?53t2egw1~5oiL9BE#A%o6EwcHA$fG$j!3WxblK|01(O(ZhQ0E$xRU@=_U${ZZ}0sfnB!dCpv@K%5pdzJ9&53&A$58v_U zFXiv(**LXQ3*>vay$N6tzN#cbVuIK$ay;~h`;-uj5z*^;i=c$4Ijc##A%9(+CWk5* zy5He!K3hIA=E$;DER=3}Lw=hLvtYp@!d~On9{lO>pNf5K0Y<-ySKlaK{13J8<7>AC zYzrcCIUE(pb!2;N(QVVjV9P~l0wa1Zf%XTg<3crPv@gip}BHS@ZK8+l) z#E7%?ObH~@$`B8qF?wWIL1C3gY1^$zRy6o!mOXC88QX&7mj*_HG+ca-H|wQ5%sUIn zF&c4@fb46pMv5fr{64b_XXG9$Z(gtFFUu&V9?-_)d?gqlIh)Tss>(b$r$Z|MB>9dj z9pSL51CQzfnt_OXPnGkfG!^A91ObtAiq&XDP0eky{fkdIZ%1iCN=u8$=6+y0QL#jO z4k&;8a3vi0`7@jb428~JQ7TI*f&+3udGVr6S$xYci^J3V_n%kV0)X(`dp}egRO)?E zhUgm6BRD*I^dklM(MQd8QJMfeI-nG7Fd0+=O5sKz??sR4%uRr%bO4mgfB5t~Rr)B^ zfUdHqz5X~Q00nNykKTX#O?gc@pd24p1D+P=>{6D2SCq*;6`4IsJkUvt1eEShJx{&E z{{fUvN>bV0W0ZVlzj7vL@#j|{?btCxpndp?@{+Id0s>Hi4B*DO3!6Crkdz-$N&8vt z1{SV^RlQLu4}p(^Xg?3EQC(96a^Yv3rWHb|q$yyLxGDXR!J0c?KJSvY2D%Z=`Nevp z_W2^OZpW`Mc>9_;r&qcUpZ`lj%tbrboQwGkfS-Dv=DC0$!1v%g@NLh(_cOu2z}Mi* z`4LlGw?BXTOjBOz&J7c% z1QurxoxqsRa(J {}f%*Y7Q3fwMiQ#3M@s@>jQq0!Mnq@22j;ubd3j=$GxRNdbTT z`=d19AC#y2d9#_BZ1?{B6}7#Mn?c3>VM0Zs#f76`H;3az6_3SFk5!)OIc8j)EaQzh zBsFotH)R{`vl*cB_iymqi_CS#&+}%Nz$t5>ZGVx4{o4!s`cvizJ0oq43uE91Dhhhf zi}P0&s^z17#v>x|_sW0$CwGM<0}GrLXK>OT<9+>{@UJs_GDEltitCjB7C(}o@k<}m z=4agS#NPabwj}R~dd_@%Q(*Pm$#X4IyX9>0r?G*$og2#_a~zF=Ect;_Ow#K4pDWqt)gPZY6}8#%?7@BP`}BXY0fUbt``_ zEIuv{T@nv;t)LCOKM$PUxpfoVUk`i`LN*rVFSBo4aD9|MeUIC*DYAo%0Wb64fBUoHhf5Ax-8xBA22rwO|PBe-3#1H>r*1=If6nRR%-qS|IBkvo;dX zN1Ta{eX*ykbmV%Me(ZDlxXZih91BlEL6G+DDi6$)G_QhnvCoto3l`kd5ZuPw1`@x0 z0b2^VhqrRaPRJ(Oa`V9s*6`Jk2k$PmzN|u*W?}jtdhUH}4q4!g_lLP_4{uFs6P*^n zJ>5*m2{;)V<6V7@W)y(m+WFRu9cKnyOudWvCB8|s3iH2Z?SL1md!ZQ$Uxjz<(5FL-AKElR`I3|Fusj1vz} z_1}-8?X@%mdqc*aT)#Lm=;u8N=}8Myiia02T>n1zFlp%#4TUj*)<2i2^@xq8EZZ1ovcUXD@yi=6c?rw@mIFZsw=tr1vqw!=1?7x!Q~H<4b*yZ+SA5=}qlZ8*E~Y1#72 zR92m9*W#_Kdynp%3yqe>Is_I)(Pr}7o)}-=9oq{JG|QA)*G-jrpR+F{WX}FkH}IF^syfC_rwu<`gZ6faSwK9`{Lm}RI@4_7H!q(PCGz*XJl~mIx8Caa@{%k0UjOp^ z?%aa@$7bRr1Z=k7%VOV-y^^al@395hbAs}{32WLS3YOo>h*R9%HvRVV58dHE-pb-E z5o_-K#uV%kzrS+K__+iAC44r{xxejM&)F6Og%0-PaQB&sr%6-MeLrIMT5?Js+93`f z#YE2j{`;22gGU=3gA~%yFn3Icg{My3^R5$d-tQ|HK8*Ggj@8Y~TRip9eKe{2b8^zJ zZb}B9a!|97OVkqD13zAmeVP?8b5vvvBgVy7CN8{fseHh9dBsUe_n!+`2#b@Y`4RHx zr#Zp!@<^nlMy>SZzBti~q?nn%9zOVM_zGOqVNhy#ZsyhH2lL&8XCuB;R_)--RhTMV z`*Qqd)j>bp9?sp-(0XcnT#egzk@sylt=D@}u7Ksv!tM39v{^Ds;#GRwk3cTG=HRK` zvn4ZaH=pyqb>+d`{@3l8Uf$3;c<-L{-B$TGWd6keO9)Ih|KPc!D(3#+@p7x`{Y!OIU0lnBEsKKB>-;<^-8;Xbb-e9oUhosUnY<@zZDf1 zG4e+f?_8EJBrsl?z2iWUDZ@sYQ2=y$y-6dcX8?sIK}DvuX#$6m-8Eqz`CAKJbJB_1 zvgPN`rSU9YrvVxN5!^J-+WP>h0B1m4>BE3KgaaXDq(*d={RT#m&QyzM7{KuXEU+g8 z$27!#4B2Gklxu7jQ1CUQbsa1>IRw#CRZ<^9J4y}qf%uXARC;hl;~82!#MAtM#U{z&CbB*IeCKitz3h zlN{}I^vE;acLCM)q2)B}XC*lWC?{Yd(FrgfFAKRnc2Az1h z%30;r&1&0d{UM|0f0p+jRzo3XG<{AQ;hTIs`*nI2h3^_=oi!Qg@DhG;RdR9^km5rm z!G6%fRb>)%9xbfdleMkYa`ByNaJ6;;Po)%R`7|~MYHvp;c+h+~KzZi3jVL1Awpv-x zrxDCFp~lGpwQnv;zgK>Drv za^aZ^Em}XKTzs7q#&{m8^ay~rw# z-Gi$a6I)u;mu#DZbn;F#%D3AW9pExhGr&~FtHN7u=l0Ida1desWgnIo-_h0sDcIl_ zQ)Eq*;lYPiq5(mQ>jRqJ>@s3>u>j7XTBpeXCMyHT^uQq9lvqL+deh5|GiNQj5YHMI z`uRaQn37p2bQZ`@u1gL;fNfd;aDdY6!nfJXOCfczB-YKkhyM z9L|Mv&-tA9`~8v}yV7k2d^*P6zJ(1aq)?e5i~$HrQXaT93#4rJD^+MqhY;jUOAG(A zxXj|cVr1w`#aeXS$`gq|TDgjFF2D)GN5*+1oa{E{x>td_RpbeG%nXJss zdVAmG(2FTu(JnX`OI`S`ssqH*AY`$#F#8>VZ|ULyw9LQ7b6;2&5dVsqpi6%89OM^wIr1mdn2AP-7&pyS#hJuH`;1yH;)Ssc26#&A$q>IRw0`_-H3yjX{8`b;%EE=@rYhLjX;+uB2k*6kDhzOxCKj~6s zD5!&BtQ8%vM7z;BeFh&YZK$F?U3oV9J7!83k*?$%jfCi75MYezDb>rqMCe}2S z;7{g=ZIsS`ROZh(cP5~L)^?&gh8c||6w2~V9dCPY3_}LBZz&aaLh{ud(tEC-pFqKhDa zw$Ej!k05uu?N%;O0$=8=$93a#_>@V;Vcmv)z@kw7lD!DW+r27$@2Fh9iBIHhci4;G zAmwcRSm_0au^&F0cvI}XP93!maUA;_Wq$K2NOXRaFQs)yj836gz%Kq07He|p5$AMIBDOYTo##5hb5qV~ zWo;bL1T>*Apd6|RM*!=9yC70|t%*VdGigtZ~^pLh;89#m}=d#?p-zW6Z{Cl4IkJQhhY zPR6Ea{fC?Ejf11KD`(_QIL5;H04BJTxFd=a9iRyP0qKhhiM*!HXldZ%LxWTqFb2iW zKC9IL>0rFO;+NT}I+nnSbE5a!#$n3@2oRmseWL00{nwD}eL*wDpD;-H#tUNrWK3Fh z{8sqrEazm?X$o=D;2HpA`|mA|7QV5eUTucl`ff;>!EJYgpw zIQm4th3_M+4Z9M%@xbBIAJl+z;LST$na9W9!*6Pbs%aZTXkz*?c%bai4w4}uxvBi$ z1>Xw1vFo0HYI|nY`9$49yha38Q&nBB+Q^H!+LWTFVo5u_O}PQvweu#i``>0*5!!2u z7*Y)@(H{CavBlL>0!D}zZdZCgcab)T8!Az$8uVB!cN1+Rt@0AK*afRxry?9SvpXT<#M)u4ZhC1k;3Du^bCt1U57La2=Nygk@a9 z^2Rg2-#J6(gF@$H47S}l0zGq4Nm~tDFp|-D_cD>0ZblKz5Tnztz|`UI3%o#QP%Pu* z$j3VzRw4ikd816|k;Cs;Y+nXPjAXg)WISWH-L~b<<#9iYVm!w~j2Cm4yquTEd+)gx z`tg>;Aje1uF5Fujmv3?opn>ciEub=$J!z!lccRcgBu0Yt2m!_aqm3W(^mGQ<9>sW} zr_TM~;~|xJ4##4NmrO(^$!SYMUvhXzg@gtyOO9o3CxiU;ROc9RtR3+K;~2=_gH_1% zgpdkMIo^$mjEhX&3{Dms-BEEb@6Pmwp+CvirCsw@WS-=cWHHfoA5k%dHCisuH&0FAENCp+kbdhX5N=)m37W_im|Q ztu&0qCVU#tsZYG~va$PH)%}RI9-jJ>+>;8%Z(Y=y`>cUn!}IOC=(2nIDD-ucO2u2r zHsK}6eXKl%CCs3s!UY_B<;u(eELq&n;uI5RT=-gD<%GDz!8Ov;WO)(c0@yhkuipYP zPw<@Oc*e=5w5Hc!@p%cEgBMZ?{EDCa9^YWcrd5(FOJhz!mo#Q*3jP<}1>y|4mQ{I= zq+p+P*Kn$Y!8%td_b8g|I(DA@$pp?MeF{xOvCDg_#m8}VBDIN5l$Z5zq9lusA}w0i z^_^y-g>-?ZZO8qFF#Z5YstFd4u1_ub;)%A!{eK%Z5f z3(E#NqOy6*{{SlrQ7awFyd zAqT+L}>8f?1zWKvm}dVU1QrmS`Wny}jgN+Hs+0bxjY@V;Zg zz)`&%b(F3s?!ujuD*Jp`+F3|V8vB@-^mvOmo!_JA>aw=c@aDRSFkmEG(3AOa1=vLG za-*UMc$}cp8}Cj1CUj&9M!czj7Zr0Ns7$Jd?Q~bD^SG;*Q1|r~|o|+dbA@i3-%?vM!*jcWzXKyPT>9 z!k8=|E6~_Eg4n}NcXWTG5C%|vbPJa zl%zV)BT8DnBOuJ=P>Ev#gnXU#keKhVw1mEep6uh`CS<aR^w%^XZ%rDRUQhHKaITAQQZpZcy#1w3I@$4*1Gw9?$PDcPX zof5`cSRUJjS|WzlHurQme`0p9PcUBk3>f&rCy<((!lcy}1_lN|_j`}XtfQu7DELvP z4}pBJ3U@7{_dBOk`hES$RSpoKieu!D8Sl$mjHyZ`;*{b2s96H8xhkcy>wx@`aPs9> zAoq~69`Qb6FI?p^OXG0Ve`bj;Q!5x`@d?Yi#6i*z9(I{ zIma=noNkon>b|6n{?EhK+SYaLzizH;Y^)tnE(+W~T;uBEvDVEFx^5$L?a>R= z?aa2M_g!xS0;8Oq>Ai=tdc1jeU=FK!w@Iu3JukzHs2JZw6V!CDYO{)V?N_o|m#2O{ z6q|SuqY6!|2s^;INzfqBjiVp?xX^oDy*Li^bYBFhPw(UQIT-LB)1`c<1j?=Ky;aGv z(&(?+=3w=?tdI4MUnbeJ^C+->wFyP<`!k9D*jo|!2ngvC-GB;5E=h}?OH_4%Vf7@n z+fZTb`0H;V|Jn0iU}2jJ#q>Z*q{|1_krPGEZBY-l>8M)1PC!7%#WsLi*1E9NAX~$G z2!=*1H}0QZ09^ir;Gw!+_;~GOIyR34RlK0pO)qvxiq!f?Cgi10MDTp2r1k+owi1cH zS_rwRV4kzUT$vfq^AIsh*rLApJpl?w_E0F_NsH~IRdyB06aneu>Q8%ZMf?&WD?mRd zROT#Vl|mfhmCjm<)hZ02E5AD&CU_#sN3qv%g`3=d5_wXWUJ8-R=TSute91NVEP)ch z19BkV0~gig!hZb;oX+EHYHg6HEe{yaQuh(g_Z&|f8Tcp5yc{jtJhviHvw}crsB4TN zedGpqF-61Si9oe{jZC#_Z%#2X_bC6t=}hy~THa8ffCQ2Jn}JAYw;lZ(SEA?&t@f0g2q9yNRkLB=@(K(?s=Rnfl3!A-GclfgCK)Xr5{mo zAXXmYRwh$f-w$N6MRvkeDkw{#I!NLHy5t~WSckJnqIOkml6DKpBgu@zA;&lqyOs1w zp%{SFc?p9uGygUh1N-OyOT@`-M)^a8vDxP@{bsoADBe!D=$N zWC#hpu@m$PE4UkKAl`V^&{eCQ))<3wbzyt73;Uj;AsuT-5n3BXL!BBo^wamsUfnV( zuJ0rhUkOZit0L&tUWAQY^2jKist%LW_^()EGdzi&k@A4uC99-~yW)urX79~=@>FayYpkbxE5K+a1_T z25Oz^XxL1wf_U&+*44RN(8Qh2JgrAQ#N&pzJDF;pSe+D??rr6!W;;{P?}a!>qbRCR zA??AOR{hVXre1B)PqVml+iCAzD8$gSMZ-V`e#Csw+vpr~EM7mJyN~?HFHLt3fQ{TK zNjNOFLW~HJPf@PCNxdDgV8|Mncg@=#Cgk2{$&SsFuv@?mEU^*VPCEqR=g=zU;NJ`i zKtUF3<#bq>$6C43GR+T0axn&3n@O>j8MlL6a{=Ay=eTq=PU{KU6}UQ&RUM?Fw}-9O z3do)f>@IH&d7+>47W3LOu3v7cHU9-msj5U}Mm-p_84j2k&y!s>5VDF68Y$0VO z{@YnjnMT!9K>h~{C|H~KCBO*^R71&Ee%@QP^CC*+Ie<@hh|k#*{}lcz;ulg~Z+&{j zvkVfvzPNWx^I5QzLDb_OtY3}84y!~17U!&9&THay26rzV|!?^P98owVXcCmvLx z#&nRSI;T*jlHQ%J5@ieGZ6X@eO1%NryBU%M7`R8 zX+7u?wIvt}02HaWqxx=BD2NY`_YmhaZ-0&4p*n^O3qdU%O-k9Edpx>n9*Ne#5z}eL zjMq?n8!P^{(BGMlP5^mX2iB1qa2M;~wnaz_OpvWM;(*TnENZb8B1l=G$_0+^g9DAH z$QoF(6@xq>$k@kt0DxE!o)9D<9RzA$$gYY%M(DX^o_0VTo}%L*n|$E`^fm}D73!sX z7`VE@`rrD@IQd*=xEf6gnRIN89@f5wUE;xS-x1kyFCS3-4P0qM95LQ=qkCtGwLm~MytJRY=D~eY- z!By&zK~ur+U%y>0YDEeNL_3(Lgj?=GBp?0^r%GwvE{+ThBKHE-^adCL)cMs>k!P+A3aCWZ`SIm9X?B%=H7$xkF^ykuq<&)2 zY0(calf(eZdhO_lyi6h2dnJ=rx}+M26bgO$gAF>4`CR@m?MchF4;v0b$B}PnG>*!f zO#O-EUm-6oeiJI*FC1OQ`56&kImc8&$WV_g=*0hMvgdF8-YvF|VvI0GY>-#`u+V~y zdar$iTzu?RjoI(23|V1Gjq+Gl_hjSw&< zRrOqE3C*O69#KN&N={I-ijf;R#nj-9<_HCsvym0SJ9F$LRcR9hzVXCV{%LA(wUDTI zZeDg(R9v*+pSfw~9F^NxS>^rfFgU_)po(%g%{&x`jhv=(fr6CK`Lq~8MLsnotFeq$ zy8VA@>y09a*;Gd9fbw%Y7$HASm9^OYz_oX`I@9w!XiVS3L+~>qfkaTTEHfeEIramm zPjz=7m%*HY7WRqprdJUovGVZ|kok$D_)9#)LVCd!&iC0%x_iv|4^ZXBWG0Nhg)MAl z+ZSiChD`IP*qN25be@rb$}?2a)E0z;_zVlk7U~8$p#b?r1vmJ#v7izA@(N&75c zj?v`lbeat8A)aociIs+ZLU?cb-w`FX{6qk;7g!}d6S5KW_cxCY7EhkoiCOk4QKM6b z>AwCx#^`NNVV5B$qWy{=5;IiKuI<3QK3cNzw=H!$V|RcncVa}1NKx4(^V3h<&wWOn zD?s&+3{t&~I8DVZIB&#M6zzRLTWkOn9^XP#?2K}{*xEc40P9Gk5TgSmOy)nv-UR{d zfac|pbRWMy3y%L3!Z8`~{ZP~@H~xqPt?PLyM|85A%$un(BR^ zF4Sf9lA4bV*2h|CDNN#jm^IT(nU`-?1NE!2JUZ~3-D1x+Kv63PNAy=URAs#}{a1;f zRF~D+4o%8yY}|nDPm`%dm@VOsEAM(!qtuH3C zXNRs2J!X>eNJ@|4apcQ%wV*o1uAS#l3dPA$%p6Z)$X__PYSs2_8tFio`i`HE4T%0D zm{l!dJoTo1kZ^*Ig9(;^JGk6fbyDY-TDID9^H&q4O8Ro#hi!T{nVCp@K}S=T$%pz}6O;u5oUeAxe&%^xG|iUH2P>u9n$|mn?zxSbuHpAk{WzEdOc<;PAF&R`OMEyk5JtH-DirRAQq^u`v~jGxG0KP0Ch;a} z5$^mjIpJNk8rw!4*V&?Tz*bz9?s`gBa^9~}MXlINqJsne!^`eKd{jTnp8_)5%DGK* z|C?-nCQ&V7M>S0%3xwPFKR7?OI+h`1UIiSieKQ6B1B!xe_Wo_C#}~T3&~eyj)m!r}k6j|fiS@0(t3^c4T$guwyQQ$~~LrZ(rMx4nZhFE=-M>l+(R znNNd?n->FNyyWQRF7!QFclJr&>Yl$~ae?l;**bcgO38UET?qX6NuwPs?I;4qhOx9| zy$SNIVNNK&vg=zt2sCY7d|#;C#qtv!kDVPiTx_US+6>AhCI2dG72m-Z<1^ool0Unp zHCW~Ri9R^0-1h>Q^oGP8EIvl{xRXe%YU2Z|8{JRQYk(5)mdY8tz5{*dF~lM;QUAS4 ztdr#!q`!WxT>m4eshjlydH}m2u{ERW3gMbJ8cu@aw`m+QG2Hl7<^xjK>}c7?K?QWY z1By)!iM1Vwa~imVh7e?C iMuq6kRizGB=AL-!Wi98c{Iw>p)-APo58KTAWR0tI* z8N7UxBG8Eu<|YF}S%~8ed<@*d*geo)-9x$&6^`14+~oyN&zlwyv$O^>Is{Ll8R}et zTaY!#f_JgqALxUda`~#N^J6;{6`dj0i_C=S zGgdj|uVEmZg!<|`4Y{{ulAfsI{k=UZ=qtPE>JOo6EP6Jd(XTdf=!h?HO2J!SDZMj_ zqK$M`N+mQg_Jrh0n1bCy$84k_h}|>@qlnQ5^nTZU;L7h4I!k(Jw*Pd1a%rzC4)5t6 zb!C+l$bOayktRg#x(J4)&)=2sAUSw<$lr_R1yL|jL?^%Z4D<>t76MZjndSB4T(@vl z(QO}nqJqh%BxQOj2XTn6dLh#{8R2&@8hV*M51`=|MRFmPKn`kCgCaMWm=DpzJt$jh zDz3&j=$gs1u2HByA|e{g=wfP-Bc#_2657&cDFVX;~&c z1L}z|>;KmOwzL^oVM0X5~J5R{}+wgq*Ju>_(_w85K&9)QiR* zC(NO0MSR`rEB2x8>~xXrM9hui{{PYe0wy|Dx6Ap&J&0+gS@NT$^7QTv_g^6f{$C&- zLDRxDECH!3z@?lh0Vw*Mlb(Q%*%Tw+VD8vR?rpuIm?L{cWU(H7#MDP`|=t|hUDVBdJFN$fSGmR#^Qo+KbzkSc6R64z`pU1Ck5f$x$9fG1uy zKou}nlcoZcx7nmNB`a7MBKgbPh$mW;9>9p(=xjGq<=UUb5f-Uy+X@dD86R;a*~;wI z>BUN24oToaw8RTtj=7KoyC;g$`DCIcNo57+MjxpWEAQoC);LPoB)T|(;#7!dPTQ3z z+1cjb7y7#w3ON--D?C`-k$Qf3gt3+<%weowexD{air_f;IUd`v01DkB&_@;zgA8_y z3@@|L+Cr&C*7+onIOt=Cg1elnZp*?d&xp6xtu?2jEk#}cvSkMVtU8}H$dWyJV4viiuWK4rOst4G=0t;qcw?$433IxH`5I{6B?8~h+ea0%!ig| z4pJgjZ$wQb4PL{$r>-6zS(Oe_#e1vNnPdr`SQGmzRWJKO;sH!gcE(l;9h$^= zNBM|Jgniw(X3>3LUg{=$0(t#RydV?gZwbs$kb98J{ z>`0nB#~#?Dn5tH5cNV*V);6}5b)cr5y#T3Y0%dJw;kJbEl#J0)70nks*yc3^?Mh}D zX@+hNKV!HvNp)+Hz6grHR9p7X0}o&5|EwWSKG+@E5Qk3vFDIKd zhE!#Fzz0MA>`F02RYNieS+87&tLGIbd?0N zwOwwzH%D$6jM~45+z&<_8cn#TyUr1+Yb7gS0Xb3iR-Et?JLWW529|yEe*F z6`m77v0q%M1SD5wyNuvB$WnvOq*C_U#HC)F;Un8 zhki|cf83|BibsU)Cq4`0Yegc}>E^f>3F{#!g3X}^hR-9Qrmt;KgoWpP^0bLxJ<&hiFWBY@FNm{;P#jX!+Q(;w+l47wtv{nD`7`;ic z1l{PQp?~s$-zxFRiTO8*(sA+0nFQ^dtfZYu7dFK0I;_2R!`7h<@93Cp!HDo4DL(mK zrR%AmfEwLm;DqZQZKQg@*5j8t{y^&nQx`Bk{YbUX#$XO`<@FUb z0KK?LbI<axSGC;zSeGpY43T;~d0md$X83psxZ`hHo&6le65gwhgeQgl{eIH``N^3LJ5DKX3OLi$d+vV*)4#Qy9 z(+~yZHby-fhRDW+V^bj1c%C#&!h@x~TLsnj2UJUp0BfAqe2v@wri?F0v@a~TRF9@! zH)fMQv6gd|g)`2c#Mta0TCwvCvQ{0&`1eg%5q4hj>KS7eX}aTha|KVK7?M3i67^gJ zF>g_8KG!{Y8}FspI(x|NgRsBk96Yf3PGoz_%cvwUVMbiFh1MV;u9w4=Rb+2W6+aDk5o z8yd*TSD~eNtKUjnUq%4(#WeKeEu8QELwxw^D?GOw{s5U#zT0d3B(&qI7hH@I|{ z4U&jw`PUi_7xbyCqJlqLGRi9pRwIn^H^KA0nu`k0iOVqlXHK5qsg+|LhwZ_`4D`=D zFSyX)&E=4y;*s-$H{{4svxsncfqb~lSb_ckZ_4zmPZMDr%0fa8hb%o zE~!rPA>a>YkGQPbEi19JR0oKZwCKB*w%i>+?TJxI2~vPBirOn%^}iTxd*CHIQ)Qp) z*-XQUylZ8WM^0N#N(_Tex`vJxBW?L%mxh2~HckiXaiLFTb;i%;HhnN~0_#{soInmC zqM@{mjgQrmQrJ;pzP+Z=S=6)2T&kukCs}6BhR*<8{>Jp`YqpHl7y&5@$X1)K9N~dS zC*6!0s~gny`>XVpA>lzsz=QFrJur-i#__t`P%?!~IlRNSA2?@-JY{<5!|76Q2>!u| zfa@sH#98u1YTvROpaO3OeDa7MyoCoBskS$&&6NcJ*eBqB(6!4@NDjo42lueLB8UfL zcs?$Oq_|>jFRR?w>mDE^MNk^#DQ-1z<=OVV%0%BA2)0RchJx$|i=J2CgeFZ`o+kqH zP)@y1A$m4>wKYg4b;2G3^T!z)mtg05%sgNkc=Yk8E=?__4fE0qFhn)zJ7Wh3-g99* zO+dRraP$wcYq=fG5EsWaH zU_KMx&Yd;YBYwz#Ow`zz)rRm_CEj6VO=DM)vlgFKzRGuh$fmA-v2Trd0H1eUd(B9o zyv`D-rD~t1{_2fJk}Fa@no08VG56VM(_%+*HQl2VI8&VNG;$q^1omJwRFawTB2%2U zTKiP+;w*6JteyU`&pYf-Kmv2vFOp_8NaxSn64MA5&p%_>#;aG~xwmBiibFc60g$6{ zmvt4;E8p;1g0P_jO#p-pC(zLAP`cD3khtcA{db@&jFCb?=(Bs)VH`53P_TBxu=4=W zWQkH{ypG+&;1Nw-Fu%m!S4CaWTo9Zkua*pplHgpuwq#YL0uk$_euF0%%y5t2YY*qL zysUl`{e?g-%Dwn9z1EHCzBiWwrwFOg)r;H=ms@WsT>zm->}9n&W!ep{#|yP5hI4um zrBKh&VBJt~8KmI06L(-l_C~0Y_m2t2c6j5Tim{*v>1jY3pdb*#7!rl0_81wXXo^LN zMm&V>iYDF~4VkjBYlf(;swheW?qI_*=v<_NELJA73zBVBFoVjTc|4ucMcvZ zj7$TrR+~-m6ofYgxJ?R{a+IQ;f@Eb+)ERfSDEt*Z0a0tZ6a+CR&pm~ETum9MqfmIM zt0>3k!T%p0WJAW5Y$RPz-6bQpmUsiWmaCvJascciSA9dD9mSvEmLJ)il9CaOt5Ss8 zThvABE61k3&>ZCnF0Zyze)-yb8z@wvcm;*jz^Ca}V)s+SNtm)cuTg)n2+ar_`;bH@ zWWCXEM_UT|)v$aKp){k~%my}Gx|BhG-V?%h%R)Ae;i zGf-o2pSQ}|NJy5v1pqX?8w++`E78TSNeu}bvMYr`_8cM+EucZjO|C25S{zbL64&1J zY7OzEIrZw(!?UJTXe&~SV^`|v$&oiI@e*=i~vON)#-^9z+~O_HZ9 zO*_fv&;9~`hlfD`NYC}2>w6US^jPR$}>vF-7S(hJv|Hd)E4T^zS&R13BTdclY13!A~2G~=-&Z|X%ylK|_8%i#UQ z?g($cmT5}?$a`Jz@3NUR23i^;J(>_#s;CF=J3p-gr=EOozd6sl1MGuOhrx8P(0zybm7y5yWpQEiazjXZ;I^A z=m&CrAvj@NA{f39k+#)3H&OZ4?@Bs5F$5nrD4ewaMLu#b)2^zjbfEu4N7Eq=`3m@L zLD2#BXK0U4{vE6!56~bDg^LOOwHL}k|Cgi7>tfo%y{)^-lNLK(FYW*ia_2vm_I&CF zM;8_e1j_AJ@UK+yYIf=Mz3zmTn_yk;^7X}-tH6BG{#pFe#Ir>h<N423B zgFEK;{`ORSwY!rueg+(?9cYC>*rF!Uv^- z!BP7r3qL9B-m&f?TH!eU)18i26MMk9<|?>p#;3-M z5EW=e!Ug~Zf*=Zo(Yx1FW{0$c!_7c7HD>l-Bl&^tf$980{pFUX1Pu+)$|}Ma%uFgd z|7nA$_UK<}6ZmTEU5&-;2I1(WzugRYuYB9m>-q6`(8d_3=>&1ZbpXZ@1yQiNiYTOm zDxJ5JF67)zJ*v}E0#0A6Nt{r~Wlp-Ca=!(d0#r0CeQ@$!{`G1iv4{L`g&?Qd_0Wbf zx)9R3=<&S4y%a`yFd(Q&eH-(}s9+joN$tu&9mKyLwOvb3P;c>_Nfwl8=cPsRGI&4l z)tlNYnVs)qrV{6FfS>pAi)eqRD<<2?Mt^Enp2Qj72k%;ZYfGw2N=rf{{{CIEMEd~x ze*7d&zMXQ14%RomP##jAcvAzsk>TTiPd{3LyrHsK@|zbT?fgt2B58`H$_gVcR}d)neI%Fa|iSa|J2 zQ_&FgK8j*YQ3#bJt_I>?a6Gpg$^7S!QODUQ$d*Mfc_oS_H=1vWeL9OwR(!mh@_V#> za7nfq`NR3$tA`@+)B#VuEsIu-tRZ^{qp2sI6iD}orAW{OiXw?VWa8l4FA!L=p4@)4 zp$%%?l_-W<8ZXUzs%r87Cf`UN@p#%h@p9f`@@mYd8q7uJ&KjTk+d3%CS1F3F zuP+h^hQWZ5h1+a$7k;WGu^w6WUj$N6Pnnn)?(4kIEA*!yn{4@d%kvk__lK--#p3Jj z=}*ZY+m>N1LlmTNRdtbA~&z~MM5y8M>gS@^WW&nEj5o_Q{ z3YezjvCF?+K(WBL5N=A@0&aPElAt~q|038m504-I3svZh2|B=++`k#FdTBXuK1Hd3OIQ5T^ zrj*CO$|;gZUk=VW{Z{%srt>r*6uCUmuoUtier4&GZ6$<4`?)mt>I*(KVv+pC?#nVb zYZNZWTi}0`d?hb7eQ4_g!&}BY?j0}Xrux&8Iv*`jVp?`?>{bn-6$}Tj@I1N@vEktZ zH~(gb`Wsu;`+EUi%5j1ig7#X)zTFO1guRrzR4vymdPTT{pT!Z zJ5qlAZi}FUQ=`M={z1M1qZmzjSs7vb_@4SEH-kd{})LaKRW)uI~I1bns@aF zl4Z5s5j$q;$gvb(YjP9$)2Bp|Oh=p6FGBup8~xpzM)4T^^auaT=v$3n z*_ZCmHJ_UN7YlQD%Nw2N@e4`qNmq)BUjJ%~{WCB(ekWpdrFvkhv?y^O5ETo_xZM3{ zAvu|m^m#+7Bqk=Q<*h|@w50a+ywP4yW5RT2d*wwM&8T&;@Q>erQv2Xc+l8VI?y}v8 z*~{GTON+PcixypSeaAjQ<)W@%!!xtGkFJf4Hrqx$^gC+cf=K$=rrr|4do7%-=vR&WM4`?!!iRS_FJ~;ScZwc!gG%)8f#xw0U~M zqN^Azizkd7?Dh*Sf0Polm_37JCI$`FPHG|NPV!=SBSp9l_>9jt1S zH#U}jyBFH4LU6X2^Z0zNX(s0=9zXtx_Py{&gnaf^cQ^K;{nw7ckA4%e5m$6X;FoKI z((mBQ4=UUu{N>cn6RlBEsV;?l7K_`}C5@N*8}E7MeBlEaprC|9$mEwZIh&RWZ#lm` zH%qvGX`w!LvBT0qdT+Po$ClZJ8S>Pv%BSmAEWU;O7+mf~a~B)G#w=AV)I=ObrgTqP zK&NXgI#&w+_6&p?kGGH;kDaR+3BabzRTLcb{1oKfyUn!rk@4M{?YoQZYvJZlady9I z;Wq;E$`y~m3&$hu*l!LdBCOpb3ql zP!wwU8y~QSnANt~!=s_rExEHEPG?JDO(aI&((HH)O-l<5@B}jpH1ZeT|F!#V=O30{ z@E!b8F>|8`ET8qAUC?w>P#ZT}@D>7ZiyYBzBrO2buhuDbRZp^LXg-Fu2B<#$R&^F=(_iS!z2 zDdD0mGQ5z*^JoYi^e#ozDy?%@ z07UD2@a5=*;0gnaNYKA~H}bsy;pCc(ikwUPFV23vZTbDKKXUql>>hXNb2ZKGdt0fT zjMcCG@U6vv@n%z=IyD1YJI9ip$XaopZMJ{qYbyUR&=69ciUh(!;~+Iavk0p5+&bGc z_pSoqf?>uZs-?n3f#|}%=CNfnGb6j`zvuUpWVxy_3-9Yia}FD8kP!=aVrynHZdp6k z%v5o|w_AR_Q_Il_cMpY?z&!6y8?=Q~G}+CAvx!F*bxWqeH%2dS6ugqao$g$r z(Nqvi%fQisA;MUl;Ndnivz!o##%O6UMU|hGqNhjTE)hbdxuM>kH$%iZ)7|Drj$e@~ zI$I|jEg}!~NIQq^Zm6gB>E*uqT;z()%4jVT+aC+D->`7ga?$_R;Czeckr#T?w7Cxd z$Xw@{|J_;^H~xECB^`r2zceW7uA=U3h35MDwr+r<{Tv;;hOJ}lU3EY2DKu+(64taZ z2WjcCEaMLpE;aO#rDdb-O+~W0BV>xh^uTut`0;x0omn5`+|8tvn`64Yh{4+gBxSMv z-_E{V*37*o`L)qWwba2xX-gsazkNXLKn}NNt370tUX&s4x6IblzqK_@)-}pdfyTAX zO}Ah*zw%NL@)p)&iKSKN$bHtQd(%rlqW0y3mL07v=aPfI7zR$aD2A4S)ihydaI1&r zG47@;$~!hhCpdQ@CK9ca9}|k0?8N=^Ii%wI_vG;iN#LI<|G$&hxr&yg(cY)FowMYR z15=Hi)e#@2Yo%WYLO#}x{peO@)j$`Tr+>Pv3V&q*t$}@QZH6F+6a@TSr)5V&qp@hV zy6~E1;|jm3aHQ~JZs>f&$ys#mBVV9Z3yOzn^D~g`rxI$FahthiAGQw1!ef5T_{ffy z+|H<}G+t@TUBR-XzuTG?8x))P#|u8j%+%cV>|UeMg8Wj4Ohhc+E;{mor~}WP?MQmM z$_2Sto4fo6zH)G1;@gOhil$6ydUcs>GFT97zbWTmjyAju2{G0SLpcr@{Ppr0bTaMM zSuQW~c;(P-;mj=s~VaV{CJ;U#sDXngZ{q#bhRR_?qLEV72ilY#N z=pzU^3Y8nIc0{$YzP0uA)h@ul71H&z=t=T4cV%FE#nQ~*`^G;Fo$vqn`@QAs^}!i& z_$0z&x$wuWTwIvUqICWVL7npMcxcP;-4s{kFQL(=+f86)+Dy(T=Rxr(oHg#=^0DMW zOjYh+28nMaw0||Yj+$U4073E-P-fyMFMBkqXJt*3Y-;ztFKOA+vXeC!0$DYg3=-2v^jM+nxQJGoi^r9ec!001`qnGKtgE zODOEbcKA+smlAET-hMR^V&bt+CHV_71vb5O@em%F2;GtV*Zvdo$%5ZkUPkBQ!jm7@ z1{dxOuSn3W5B2tb|1&I9fe$yyZ_>NFsZ8a*WPqPR+KpIPoVh9eatCPosTVsTj{S}J zNA$9`*>bd^xih2N$QDxa%;?mq(O(c(M>D{TZh^=DK&zLNVafnUexy?qqOWNwx6MZe zhfmv7T!XTD>2!6xiJcOwvtIZ8;pJE&KwR_;J{Ly++xik>4c@q6nTvP+KNOv5SW@}h z$KjyoxN_7KtTAYrq!n7lX@RB%noZh9=08)AEz&lkE#j1dmO?H;E0`&0rnrJDXqk|v zG)+l0B{dbGCb$LIlsHYJkI%dF>RjhKzva4@@BR7us9txE+WsqjUe0e*5#Bd2N7cHv zUf;;~l}vUNvm7Vwub?Ujzs){KKgYTix7CWXrLJXBnL0Hhf{}fLje6A`8-|-U4GavV;t{K>(nNSQ zk>ulDcmeU=J96zh|4%~H#q>=8XF4l>dTS!i7xatp_cu`Hr|MQof)GJSE`rNm760w$ zT_=zQB$q+y?ecVul#~CdV;h=r2-|oq^+V0%sWgws_i9D!Nc9I5n!y#hM8oBCE-e9o_LPBEvM4cn}s$X>2P22)8NeG=V`6us|F0Gi5 z7>xCZi(Eqs#6QO(y)^gaF<*#cY#2<2wH)V_Wy>xsE=HtxmmYkMNE1 zpE};B35NAflH-1N!Ee!}gmko_$HNO(qe9m_#gj~PCtw6jH*JhO=r?VW=?AvC`h-(W zJvYF`w=D{p!9|E+pv8@7Mf+krnMOeKE0*c)?S;dE++CaWq9Ix`fpJm?V>O}XmYAV_MRURu+r#k9NqFui9q+ho;)&m*|h`% z_BLw=+xG2V>lDeyZ?Do5Ka<YJl)y74;>5wh2#%Mn$6$B|!(b%BoAzAmvqm3Y zRD-mbk@H2M{hXU1@bY>!uXh11v|;H|u&W38>zwJKz9KF&jQ`l_gYd+!Uyr??LrF>~ zh0u-Ue{UOs%nvL0Vqm;kJ*E+bwZ&K0P>g51~u1E*OI>^fOhAgl z;_c)Z!T#~r%qams!9H^)YU$deV0d`!oX+uHrzY`>FQ$rF2!R*Ehp=f=F#7rjbK>hO zlz*>m8Sm06!vDRq^-0PRWCZRX=r-ygLTq#Z-P7V9%c{)Pbb2b(U@Bu8>cdv$pcu^h zAFW%@iQkS{eMcyx=pHRe;?_Y)i}QO&tI5yuC3!$0D#Lu1MHik(vWl9~s}QU3`F=}* zWTXs*RJzl5dnvp9f-(Qs1*93ex@n+Fp0#r_gvXCg2?HWCp(^I()SKOlO(${+2T z$E`i062<{&h+uA=peEmUMNE9sfvo~|v+uwO4~BCTzWM2*LQzE`7JCr&!(}>^5o+(# zk2a7;HC!a)#f)_T_X9I-Xl6utP-{P>?{3_=H*;OMw~adLSdG9+`VStfCD^N|b-5%z zR{%LMLTW_%MH4(IAQ-=RS1N+;Y1!vLof7Uz=lybaO^>A%P9%V2GJbsg3wz+ymOvyS zw$*#8_J!Ed&GN<;O0=60ykXibkxvA?L5!KVVkWzPB`x#yX|eOvrpv?!2a;WQpxyR z`D{E5ZcM!Jn*@eQzSf?{@rhTw6W97IeS)09flPSMn0DYZ*W247(9E2&$-u;USwd%l zi%2_x7r)M(i($QH&-(dwF9JylLWY2Avkq+aB<_q7-@dv$Mr(e3iJ*Jqw?FcOmSYA! zwZLg>YOw5j=vSt&ZzpRRMRrqo98@_+DZ0#39#D)jaXy#qzew_KkiOor&ll389;2 z@qBzZC&FSQLC^_GyQi!2YEo>=K|H?Ii_J*3)<;i+d9j-h0)ItBfajzNV*OokrI+na z*YitmpSdHEAM3fL^0mShcy}`o`1p6N%PZ+2{XHq7WMKiy*G_k+)GJOLqLE<-4+x4n z_j0I)`kv%!uBJmxTKiaEQ)1+f&s@6->*W5|{5V~74L`!a-I;^!`wio`#3&*Al~tjeUmg; zmg=YfUR`B!O?b=@Pkrz(X6T#dWg(pRN}0Ffv0B5m%itsXm0NAffl3+r$HFyj|1>c< zPl(EnpU)Ac8JMrWVohJV*9{mDkT*1Wf2*HFJppW9CycpgVN4h9PVzcn?i}+!m79_| zZ4WYXkurgpG<&7j`HAzy-48$6UWh9X=_+k^;}TI>E=p$$_<+*WE%9I~CpSsGn;1T{(jcl+sf3>HJKE$v$DQB6& z^i^0Dr;Wa8g$;d+_dwQr=yZ&{mB#^>E*0YQ4-0pYynNV5$k+F=^#UN_P(aTxziWm# zg>5E});m3fi}I#*L96wscw%^5Vn$`?w|5+h1WnhinMsuqLTw_!(M9a|5oJyR@1Dfb z+B^S>n!QY}AHm2{cdtq3amF?3_?xJ`G@&c8w86))f?y&!{n9pWz{g^vmj;A!v_wam zpJL3>plhYJA+BY-o7BRLDK>Rqjf~g(LxQlLGuDE&b~hneyHA)eb$?4-ynwND*3MHN zeo8U0QM56VM__yLdburgO~JtiBx+fQ?=Gs@%L^8|Mz@d4D^3d@iGP0_GtY(VptU8j zdQSgzwDlD)F}e-BeS~AJzE>(Yq!6!2PWrK}BW0EkwH%K)KV*(pq@;i8f!kMQbSiuY z)~}65iB$DstBY-CPw24A&c=@om5D~G1b3Kc3~5}8w8wvKv{1#dz0+dhtnxeGc0XmBb1^Y2VV3+y6Mx|cnB}wm*nTo2K=JYGdG6LI*ktESlyFT8BboU{0d)hx|TY-uv6e!8_J4%W1}| z*jF@jx!u*cG?+z%qu+F*sy2i~#E)&FOwA>_HpU^m=}a7=cD)eCag2BBv|oGpAQ9Lp zfC|7!_H25uC0zhuM9vhxbRPhMu-&?}?`o$vjsTG1!p9pDlcF@G<~)ximpAnv)~Jen z^`4=3q(Ig6H|CGOTTaoz4$vTMJN9eRPiZ2}9~fgguJG9JzA#K6tgon_sT*&ComIS* z(Z|6{Rd8LD{2kE6YU$`?v z?zgMUr;(ruX`8Kx1z?;QH+TmN2E?IdGv!HVf7p;Fz8dj>KNf{N;T!vz^mjG*m8*y} zTt%0pG3a>AU#zEMLm~=V@!8%M=YAx8>CrWM!_gZ)c+LKI4Dwjq17HZVGyK^1AKk4o9~&b z(1C;n8Zs?A)n_M))=V)c9|@ch{=Vz8%8g)qt&#MVxZi8XPtFRm3t1M4m{lLIvE7fm zC+^sYGXD*BKEyp~eLeQcn>sL@uN`kteAG~_es+tiTIs0J4VFHe;?_(W(Wvt7oARM$$c2gL-s*C`X|7@$rKSr+x2lyemiPHllkqk3*Akv9+ErFXSpJ#eEEgC` z;D=R}&S9m}LjgJB@4EasiMaR;1>czM+RuE{q%Fz|rr@Z1v~NCO1H>G1<-GT_-6(u3oB3u*qb zk~0KV1R4?K9=kC&C6kGMdQt6eqUT%T-Vd$z54U*lRaLr-71-fI_%4nnh9l)ul3g*tw;}%GZ~sjjez``(#Ul0(ia%FP-1b7?H%^Uv}akd9-sH z4U46Cix&R0RscBwYQ_>^qlX0c4M46-X2h}JsrI)i!FA#TrXb=jZbbDTX>{vPCb>&z zbS2MzSki20fJO?V_6S$VMwC;4*=f^KHpGrrG6(5X#$K$Ox_(8(6GM2RkK=*)kwD0s z!Pn@x5YP| z;-f7R>p;XHai6&Cr~~(T{5;-;`=^ZkuHImq@fL`Vc5}yZIjDS#aO~#ES9ROIaK7%q=m7jiak=Au|3d<#)vTCL(zi0Z!Z*;xRnvIc)ueQiG!f`$Ie6% zP%@K@yPXshc;aaDBmF;F>kj`&Frp_ZR0|J}8{Vrh%k3y5KF-tZn01 ze

Gsn(~V7+R^kbb55uxXkTdzHedS*eL9@8}GHRDjn3=ZMlA5wDL+Zws4!=B0{W< zZ$}AGcK=MUgct2$QF)W7UhHAjJ2ijZVBnMz+&I}-|F{pD?1%O2PZ`mjjGKhphtF+H z!6a>l#IOI#JWCUXgI>JkJ9+b|Azi^3IKgX8q*@8X)c^9f)p)o;ns;#LzOXr@g<+yg zpFNWgca@Jly#W1FZ2c}}-sI;R!P_$L{Ro!Yu7JlkCYe7q2>!07>UT!A4=H%>N}%$h z8MJX8592fmcP}JSM~aQmhmF^Z3bb}UN&^g+gevd;U>{=WfOjhrLRmbNZdk?Kj;e>8 zHL%NgPL_%!gYRy2|4I1FeqSwmL%XyVh^iiAZ3xGB#oRAn!SwNglyUL*&pZz>Ce_0FZItFM{9O0VqZ_6=A-RXsSDTp#RTSkslYN-9ykXN zz~zi_J35o)jd9$7sBohJRf-?Hsk8UQ6pC)D<%af{88hfgwM{HF-*r6!qJhC;8NdR{ zg4c)2Iy<5N{T_ohMdy8ylv7P|QeABCnMAJLRF8Mx8Q$>eXY4?o;isIlugD+EX;JF# zRJPwVAEQDID3rLzhuyv;{QM$Z8K?$K)_1^a$d?rmgaMk8W}$Rl8#hMp3tZzmM}893 zUwBiydY4Z5?}Xw!X>dZEr?C33J5f>~BG)K4WVs5#5;FP=T#Zyys?>T_#}}5W8D*+W zaSuaXOzpR2F7?*|Xb*dla+s9z0`ODAYNyAkuck94Q(oO4$P<#^|2(_90@}Q2eQZ<@O*Yb=l0I|# zi%FIU&iHg{Y{miOY&;!_Ja*x*zvu>a!%9K~1bSFJ2&k*;1218~nX5Fq=!uXo=_^-) z+qcJ-{#-P-tGc`AD%0Y%W|T7V0`mei%Wivc#;LAC$vcIUZp}|V+#alRapV5(3=NA^ zw2nHkw>EY9hogpWkfQHK?W~d73JiVMXrZl3^)e1^@P;Vt#vk5J6)+VB-+Hj+fSRrP zs|T=~MoJBezKRbszcDGho^~pJTX_MgVwxtx!qV5V5ulPY?Y4il0u&GsKFbnOTKN}? zKycbDDCukZ88AB2QLrERY5KW_X_n~!7tCJM!H?ge~ z8Bxogc|AwTJe|GU1WPkafG3L76BBsK=^KR!?_4Z`B8O~Vl0}IfntVr;oK^V$ekMlt~1{d z$qoJEo$>K99nSXV(xEF;sUOB_ks)impvMx{(9I3GJ50thU6pxHx>SkwARAmY8#m7B zMbl08^YzY!w={9RH%0GNeeH8y5?XKf>-x)RGtBKLK8h})#Ox9rK1joRd($^wn|Gu@ zgwRiG8U%P(wi)DOAmbdT?SNFwQR1E0=XSUFAF_r@vq~C~9W(8Eh=+ z&->XMwQqA_h3((%|K?0$`f|zGJbJ`M)@;>aky>fIkNB{iTcuv6t=T?lA3YLCY>icu zojdx{`1l&#FvC`?ytvJ7P=Cl9r$Bv}mr6lTUi^nqn@N0+(tze|*|oP`x?~}B<bcDj2tSkhXcdy*r9mAP32ILnsN6) zWdHR^Sz`8%(Z(JP0AC^W=SjYACz=5qisZaz++#`@8jus5iVmu$FH-`zRHWW4&0`^^ zj#PDJJ3_!4smA9IhLM_>@*3zI^$3%?+=y zAc8%Fa%z059pz`}0=&HoJGR~@JMhShUcuji_@83PE(@Th>wnrh;g<=IIg#sPph4^GLWa30&31=(^PH$zE%-=)KuY^1IdZ z8My}D(4UoazUQ(>3VFw}DwmE(3fOP2_0ms&)q54Nb^`d^L#XI{?Atslu3xqYJzuN_ z=w)QECo;7{9CgUaWYnOdL!C@$xEv|ZP>=>H2X(W5f0+ zS-@aEeR+P*F+d?1DpK|a?3rue^j_IAim0S&`twAr;Onh8RG&;i9w{yfKz?KSHWhbY zJE>A{eT|Bd*i};{&p}Uk4wgc{^&JFqYjhnin=_r-;YxOYG1)iGu)0q%CHXx4<1`;? z5O+Gt5_oR`W*R0Wgp5S#QFA@%ZZJCyiWJ$reMDab`JO*#Ai%)E6+{g2%omj4;1BcH zhJfB8%CU~kAufJVY%As|aolS}|H@%K&+O~X+Ez#|B>{Usr=2AzoFj$KU_$#9cJ38y z$=v~cI9nW9yMR^ChM5UhpuX ziaM`tSCjFbU_iEOW($hgZ+Eg%|1?L_P$0f z(n3;4VWw^NAo&vP38U!LK$<@|T^q3Q-F^al{|`8QHn0k(Wf?JVE-ZK=qH}C~>jgtP zDy4YJI_o;aD}H_)EJq;e19BY$ES2E^PG8@ZH8<}CGy6o7_Unn+jH4nf78oedZU(Cg z?0F0YyejzpMCeRmYJR!LOYH~HG6 zt%sYH65;EbZzCfyPo+1dDcii32DkDstzTv>pg4j7(#+8c4dXS6KWFB1KwmfB_XW21ghG>|WBn?Kvh7}n3xe}lB^ zVn+QwtNNvG=Fc5@omd9*=-m9%YAgkQdkx$FG~_m8sE}Dguj=hss!(E4^f?^_5{Xwu zo{BC%$dnAXHA}smOmbB-tC~{lrx~WY9(@WjDIId!Ctiu~i3~@kj43jj#rd1QKG)dKyq_bUx z7x=27P^iqc zkp8Zcx`g`m;+d z-SBwtp8!$p6{MaK#7IhIQ!kk-`B18em-(0Q9C!wu)3g3Yxv5w}@>E{L&{)#00($(n z!E_$Y?n;}6V!V|(w^q%_22mCfnfSwKDz1Pupj;fH-pT2ckvJ#1&z;C;@=9oXk`Zis zu^QOli8QDUO)n7rNQm5fB{is2ha9<^gjA77Os=ZP;02}h3MzT{=1sajop}?!mx5re zbx^p!xP6z->4{S#lx;{?tr`MAWRiFGZY^0J;Pc?Y_8D2-2MSFi zQ+}@ZGh=u*rm}bC?sOZZ;0_dj`*2S_*;Xu4DsrbQH%vOJ?W$-_&J%*Rv^Jn7iKkTK zW+`b5wxJsEu6@KDA`r;K3zF0drTsYuH|>?EfuGI+H*e+u+tzbH5+09L_q#Gc?@1V7 z?ef7=Z6OhufDfYDivs*i-Iars6Fq^J&Ttd|FCoNQyMz*Jru3iJS~|Y&AQzBeTlU=i ztm}l{s}kZptm7%Nhc30eWbV32hseOt4dbe)Co>3zkUd|rDfip3e#xMvBVkXrcSvd;%Zt#ejGV!$0Mz*O%ph$hej4gy&?zubhE_kx0Ifny zQFv1aa^VyaE%BM^IVA)2PXE&O`keD7a5QORq>!%Gi?WxRsBx%)pr}PeQXidns#@oY z?YoNYmx%^8h<-fEqnm)B!H{SjeMs(ZOq;X9Ngv?(g{5WFHH$jF{hl)Y?R!pCP431q{k+IgAy#DD;4SNA`!&IrVALouK=K&mz`GDI2mjWBY_915!ohG`I=cOw+zzOn2^Ub) zMPmN$^IMh>Y;;0RZ^s6*qzH@L5fjK0IW7z<1G(IhD*K!y)Ec9c(e?@+E|(24hO6qj z{ML~j&~SCqmp>;%Hn^Bmx4cdk`}QVTH#0J+Ap8yOVYJGYE_}232Gfr93=FgfX88`F z71$X)+Wl1Gv}x4U3rEw&V=w-~(-R+b@)V1)5ylKO_-FR&hdE5RM=~sv%{VB_Wx|8k z2|!^RcOD*t8j^DhlYBPgnFK@H#vSz0GRt7^k%#3)*dliSwQW`RZjc$&hP__#PJ)^q zdD%734%l_}8#%9^vAM$)+C>?$R&(N@QgXrvfgh}-_FK0%Bx&A~Z&2}Dqbf?&YWtsQ z#k>egyZDOv&_%h}PfH7mz3jF0;EWk)Id9IsxV@ZY-QrAA49ZSO{LX+-a}aluf>hH~ z-q48~K0^WqUyi$7>h4`Hj(e63iX>5^^WvXmIbU2A*e~lBPynTE>Pfa^Vb~^xU8all z*ize{D-#XnXKcUd4f9bFOnL7yAP<&oSuoN0zT9Y6NP2(7f5174wf)Tg>uo<6cFGj+ z5VY!kwy#^{P(N(w$gsmhRT4XP>7NU``%5@O?)0a!)uVN$A(iavsx=)d$#6Aiz_9A^ z?nM!HsDvr3s&iT>eRWJMV~UbzGs(5*b`$m}L1S`m@1HMtkBM>uRSIt-{)+^!R-U8JyV1&Hpb`2AMC3US?rC zR=drwq;I+`>Ifo$Jbol?B!WK3+mp3oazrudkQ7-DTfJc8Adp;sT-{%&?vraXcI-{; zFJcdC2TGwUL7&vaN?sCtWmX(miLNr#j(S6bOzgdp@R`GG73ba6xSn8Ws9NCq;iODb z%{Jj)){JL5OGtl*f2vnL`KnQ$geju!-)JFNJD+-cVi5tp>~Frx$yRwfxkA>!7KArI z_3#k;X9qVsnL)Tkm#G-QYmwX)FX4>1yXLz?A(V;XAF$#4!H-naUg9;cme3otKZN0b z=UVq7=dLmv}(D;eK@?y8K^ zf0AqLKosvUA zp1|1;CkZG|Pu`5mb6*hv#@vj~z$tZVZ~E3nBo9$gs2*zjN^7^J{n$)Nhv>h{bFl4! zUzz$c@jVyu=7%5msU%n%Zr~C$aDSCyVYvMY)&}i+Gx~)Cc#G}VHLrQC#`lPrZ?J0D z)zQ}1m$~Mvl6U``=8cuV=MH~2uDZf0?TP5Q_R_s&+|ZxTej9GNM%_{IM{8er-*pD* zt#&ZD`+ilSn-cvsyPO&YIFDYuF;`Z}kPNC(Nu=#ENhx^K=XMyI(OZI_QZwF`_T`Dn z6-Z@ss_EI30M5+bGiT_ITlES3iSv8wQ=rG3PfYm9=x)7AcJ}zlWCWB) z;oP)c7g@Kmu;*nSPLu^0D5>=_Kz{Q+d>!h<91YJwSvRM5R~^$;tq;t>;$BQx#owVi zILyCH7m`-WKavJjQup)CJ}uoI{ga&@orA0-r-zBs&3{RY?f5EV5#|;9jntUt+8+7( zs-S0*xTbz-FQ+G$EgDN}ZhhX}eI9xhD<<&vddc8$G4MR+&7-kc_6y2W4Db|qA_2Qj z%iXcY3;b(&*D>-FUnUc6uU{46+YVUjV_y(o%3+c>_rU|5fr(05E{-kXIoBaWWfA|c zsL1zKWKauF}KfiIY zmaF6EF}D?V3Hkmyy7n(|rvQ!l{yY!xLBVepYcbv=2R-8RMMZyO=y6@W_fseaWS|s-#=P{pyFDRyy z`o5HiXXs~ysF%$Y4L{;_iLtMWdS}jRgsG70^mg{PktUwnYFhbw)&WbSZJ6D`3!+45 zG}+|AI{N({sD!PQzR5omR|9l;aXQSlP6^HP30gX5UiA$zVrW6o#z&ZdoqLdfBdx zPqP(S7NYHcqs*{w4V9=K>Q3Z966CmqVdO52k;w=hk;VGC&WRSCPJDiTGd8@ zA;{Q%Z$i&+qjfex5F~$~`D3i>I#|=xaxw4V*ASze- zBT&{APt|Tn*!das4X}WwRl;4wE))>AK5kEz5fm* zdcasCiFCIkCEaGq2=9Ju-dUQY|C4pu*n2U(bA@HDHpk$tVM8ZBJK7JSbjSC7Kip|;)ygNoiM;r zJr)-B%}Z4)hw9ibyhBh7fV4Z0`*TNi;# zQ#gya<<5`+UBJ;)`Bf$Ed$Eu)2!$ngGbvo^v-9f0`aJcYT9EZHHLTo)q#Oi~QjHUDHiVs%Vd1z$WWYiA8Py zdo+3{5o*<9hlU=snV9?S?KY*mo`5AMA}h|RqpGEV>Q^k!lC|5=bkYqro{Wal z-BzDTExPe^#A)Z6B!#vK)KHp1Z5l2Es;^7}Ma~?!Nvh!$oUT7NweOlCQl>n73VU^@ zF;*);-wSV#Xcs5%vBJD3*Cn=U)4xdvwQtZm+BFPdg@Dz+S?zF#YWAT@#)J)G3?E7&B;w!R~?U1>`>;~!}{+?k5qr49|*1`JtnZb zOJxtozaD4yUc&c@?f0fX+pGM`{^m06^~rR65B`n4t(>0tGKWrnC35%n_IBOs)P&c? z)f@$@x2I$ui9^>O5wY*wfOcjbcd}X%IBm~w@73yRadoZrx$pj}6xK&IfB?Qaj$F0< zv#Qbtz^Z5ps`0oz`)r8XKBaci+Uv{OKn$QYHyXj&Z@%l(oH5pcFTXOo!|Oq9I#C4I z3(0Zay?5#`4a5e+IkW⪚WkSfQibV*+EfWycU5PE{gb(7+@nj3(xj84h|Z+l z6zZ5iqIYZh*BlD~R>ohwVuwKO(eFQgJ?8y|9r0{$d5Vch1SvxPcS!uL!f>IU-<`3% zV_(kX*pqXn2Nk}%_LyJLq^1i)CA*k3bGGbq_#F9IFQ-raD5-6sjHm)UC)zODm)X>Z z>7tG@qN|n1z^Zm-2Ro||V~$!(^-$m6a(6@nTBD&g)E};RiPGW){F>u%9W$Wr&GR?_ zt2#zbIa-fRtmI;=IfN{yehA%Q!qkI}zuAe7ANM!t8bAl|8+HlN2ACQqYQegOb1i-K zaKl-XIt1t3Ew2fm`pe|WzB|LW@U`Sbnysq4YF+Zm$ASywwzvoIvx}qX&T|%V)#fY+ zc8KC)w(;&A%;;VZIgzEU2d9|G&O;{1bN%YE8yqh$sKMZa!8#x>pXW`q`6T}F#LW2f z@Y$Uh>BG}Jd*lit?hW% zB}NB6vpo?eZQvwx48Pe)Tfa!)VR_X26;| z7ddz1bi~e#DP<6@y!%pYT=>_E2+`j@8S++wrmq_SeX!lby(fH6F*JGT*(bzLlVcD> z7zuv12=BG%KmBQBoG*qN5wQ$@e(DhKLPTk)KJ7;crWtXsmAGAN_m$e7i@Q|6C$GFb zae?_%5G=_l|&E$_aHb#t;6rIFWS_y5vA z&~<_URULOoK=ryLvU$CK;%Txz@dmnJr>Im6SOYI>AGhX`zX znSl<#j>=P_dU`r3xoGP6+)7GuOJZsteFEx_wq#C?$-Qw}~0cHB91jnY2Y}x74UQdm(Tud0>7}gb)1>b7@%5Z_3Q;chV~@4b zZ6tQJz6yVpT{U{11X-kHMH{=xLn;(K%L&_sf|*hG&H8WWt8kjeW0SE|>!Jo4`MA4* zYYx`&@m1)ugYKJPNlW$`3c8qHGEs^yHU9SS6!jpZLV^u1Nt`b(JT&Q6oy0apf1jW} zIa%xE3^or?Vlg_YPz(1Z37=pJ$|%j z4#QN-C)7bf`6p#($m)~qZWwU3H}adr;CY5BjniVson>yZo*p2nTjj#vqU#JHTls6< zR1eRTeN$2^JQ_5K4O^IAUU=EM7(c5oFXAlo)R*$JOt%qp+&ZuI#l#B{_bR0&6TI&QGQIudb| zq&`fpIHbGNbTE~Bqw~guV*lxN=Id}_cuB-f&XK62aL)(xiqg`!5@Ln@RU$sAvm%}Z zR~;we^7}@9udGafs}f+qson$br90-rEj(HnaG~q2I%9lbTZS z8ZCd#vf)}IluFVV+W*VM=#nOH2|?*;cS>JNj*giePHT-2o39V+&U5N8<>7^_6M`@I zglJaHS5A4VAdt4Euyj%PcPXK;rtex$PjM^!=Xps(Vo}ZlR&ZB2rtyTkMfIV#r%R=xl^l@l zC>Y8Rs}9S`Iqs@)^S@~a;1cjAzZhM}Y0Y+*+6$v@fW_TY+vV5WZ7AYcoDQu-=l5bQ zrMR0%EkJpku{_TCk6$)iR(kYTtbg&&+W?`0JBdgA5#KB4CT=k_*K!!hMkv8RY?0lL zYY|{mmek=NFoX@su;SK;>dO<*Sstf3HIO}YjLN=aJNHp9qDby)GDyHux&)5Z6EaCn zQv$|y!q{#x_*G|TXOzk=W(R+?CSmZ@8qz(|^3 zxH>v9Jb&!Yv!ox^jlGd@Upe_@qutMlW2DU1fQjXVDLYNerKeaI#CUO$w88RAOL$R? z5WFcbKfLQ9ag^!xlT5#JHUq}uEqZgC z>du*%X)HILc?UNIED?_%{p^pwozCgtjyyhXzRBOlpNE(I?6syu#PLXz^xY%?-rZLS zi>uXG^Lioz8&RS*0&JKTN;wZ%MGj1sB^cjI%O&bkl&$C|;!`QTzHrnF`bBaCpkn~q za88Q9_0d_y?`J3V-<7o0*;!?Wn0bA7cvTn`jN(_{t~rInf)#Y3GKz(7(wEvec=Fh( z!aFyJQ)GNJzVt|6-<@)IX>1XtAnMwn^`w=R8!H7bC1%z>|9T~k7ZESre6VffuhEBu zv12h$X0JjJS(x2B-ErjZJ*#oVy=2O(SuG0AVb+n-6W<9*cT73*tMdHLn`YmoT8FEorH}?0>$-oTVM9Z8J+t$3gcM4m z7fA?#C_-z0E0?MP3^NRm-w=Ee-t1pL1FPw<(wnh1d}ItA9rum8cjNfYiOw|W{zudd zq3X#6?r{VTAN_<5VqMA^g^%2)NG-oX6qhHtHjW*&?pS_rUBYDPVLYiazhFpwlzxO! zafDQUBu#RZh(E;UU|3XFVyvu~%d^P#i4Sv1BzQ%{wf*NV^S{AM_=EImt0&HM9gE$) zYHQ58cdZM-t>5C-AG|RmzWb}F2;6e3`OH=H>Y38DIO1H&vMZ1M#rXnK)-8W9+!YBI{*vIKj9H0SLSLFA{bIvI)p;nO_ z>Km>8jeABmZ!GU+v&e7@Fk#i^>&57EJT)uN#_Qg_e&gm{->b<>D@5TlD77OIn2JbkV&G5KR^=y;tsL>RGysp>qhE!+)C7&O*G0T`PzA|Ctl`N5lh9l?bYjv zxJ5xz*gG)1GVQdJ6hfIEH9NLz$MT+bnYX$1+?Zs~7xW~gNTEu+_h!Z*FJcU6N;jpA zeNqYvW(`AerU&Vzh5Vl^4QK22nHS zTDK;0qrcm9W=FC>b{66(i%*3Q7j#lg=hcNbohj~ zNPE!1#A5M3#L+QdbuBY5J^SxZ2nu>J#5$}|8J6HfBcfKwkK0douL4)h#B(T-TT!cB z=pz%SRHBtjPn9_?*mB7_9z91rTTq{dZ-kB&d||9lrfWX_ba7ad%yVM_6|ZGD!h?;h znTnoB^V?LBfE&QOlTX3xF{O^namRP;`aC z8<$6v?Vk8C_P?RFL);BS=?)xyo|>6;9J?H2hZlegM~RN(*ziRmxUTt_h2)uQ;=7lW zE(^nxLEdWq8!BGj8c%^Qv23A3Y3Z??itaGP@jIHD6lR?~b<60k<4^-0Y)GD5xOTmZ zz^b6&w~XE_$DEjCY3o^V+8JFlR>VT5)@O})-olQF2#sf9Jb<3;5`mnKui{gq9GjT_ z2sa{k?>eL>Kt^V!Zmm{2&y4%KQB(a75|jv3oh+g*#Y*^aa|Zg= z=%^9G;7v<6Nai|hF*p>aI7_rERX5Th*eUr?SZA5-B2fv zEu+i!G5@!#MSqFK7R6-=dbT_nqFvYSH4(;s7;P?)MC9(8EQlyzGqx3LhxSZLuR|>C zzvk0iRz5mE_L?TQ>*CIC^z|oc#N>&?t0UM2^H;Vqq?;+L53BH%v&<2s>G=71$hA8o z=Elx);7_leVTCncMlc8=0~h>Wz3j-hbkM=Dkq|#^U17{gBl98(+ACDNfsk z55F15AgX4&ep$y5I2)9=E(Au_r_dSW{rBiBl#^6@s)&NZaRq!uzl1YoTXF^hn&~eH z%du_(l~Vb)mjDtF%6yYPj-tiUhbTXOBf%s1GB6Mcx9gGV;oyQV=UTB!(uGqoVa%?i zIq7=2jY#`^9_vrZmgnvk)F$*93?yt}MM13mU_q~MKBNA`OwGqWP$W zA@r5g7{~7zzM5(O(ZNm!*8Pat!{3MD9-N{Jb@FlNHB#=OzVR(~LfJ`C4Il3^rS<`} z$yiOWJMi2LQ= zm93+cbxZ9=FtU4Y>V%ikFS#!_!M>saX(m!U5c4v>!J>db~k<3{P%#^=hug zO84O@F$rv|GS+?l7m$40%d;D6=)4|_Kh@EZZ!2)-#nO58{cYFwVxu7is(>vxI(oGi z$hW}uD?bl(o}LHif|sImLdI7|QnI?z(8uL_ZjGOZ%+X7@Yi-LG$I6;YmyS)xE^+pr zSgRhJ9~1;F3PHEHkMW`w5=pc*tV3ew9g1)RxJ~{)0u-zEqVF`vcSf8U6P_RVkiM0R zzacH&l5}r+oaXeli=pF^#FqRm^rr1Cxe(p(qh^j3C*Pm!1QLr_qg-I``(C&pdb-L#&T zJXt)6ksJedBso|!EPO;fYrU_{Ju#!)0s#t{FYxNlkX#En99}*y;ON@ z_0?l1c@BVgNiN}J@v?qaUx-F;Q(tuLEIOOnB?v!Wx@TvVM}>Ghdedxm!Qt#m3LpuG zrw$Bp`_YTAju2o{x5mCE-~uD!R#Dc>@Wfd~>>tG2!bQd3kp7RMGjU5Y-`hAm;DcK{ zE+v`@ngx|5*&=2JrUhyW<^tvdnkAMdu7HYyiJ+yREz&lUEs`ywEn-uNVs-Ws@e zL@!>i=#aPFt`=zR1KHc;cdK=)Cd4+GmjK)q!GOE!s5boEZRaV7J(yp1X7 zeW}9^r$;CkTHXd{iT{vt_4J^(V&^ zY4J&-wSu#ml=J2t-ZyT_AvW2* zW$Mih&psaiP0&$_DC9LaNf*n+ag33cf=hEv=@vZDam9_h`gRP!bj2pk19wEWWc8(IIdA)#aF6t| z#p^>n!6grw;xPPsya=5XNnExp`}kO_fNuxt0Qd1B+aA!2twv(8CA-D-_|jb!vlG|2 z5}9q=@6lj+S#NG=7_OVHLkrWl{nVUlP--xMVoQ!1{@LpKyjP56vDI5uY&a8DVx$F;t-#v)S8Bqb&_&K+m^PS0^ z=^HSImG$KHZAZaUDkvIS`$`&X<#t~EzA)nPm$*@GePw)={ zFm0>fI8AcJ2cXBp@#&Te2L*>17u>76Ea>w&iUVfZeqsySqw-oRr0OHLTnlwWvyTsx ztj=lm1pYq7PG3uHZLJoKr9L`w;#BUi%eXTL9SE0_(aS)q4}Z46S>i8~QP%*zLLs=e zZ8LrstyX)lGj^RJX@l<2qi?l$gG@!+)YV{pypzv+qEW@64DW;Eo^=bX4);V_yGKqF zJwjFxP<-upx)?uQL8*#+l&9A$T$d>yfQF2*r%&-R)Qu3-iuX?&u-V<)@z5u`oM^{O!AUhvS0gcU@C0zYVS*MbqMl$9*{3pplRjXNwQ&G4;2+og z5JX%&D9`<23bH^rJa8%-cPz=K>!MJnJlfkX4PQWi{QFeLDLx_O;KYi#xAY`F*^jXK zbN7$P2l3oy zSSzN>g33cdM^5GXkSe~6nwdJ0iesHWWHW4!8KSUw1g0{3z3=)l@Ghr+_xh}$**iM_ zM*&h3=Z^3j^Pt5zhG_$1E<=pSjA1qNOUWU2*zntbi*!K$v^;vfeE zh%7oZ;R!W1c@C~I^5%f#zdIB`;$0ZUVIoAxu(YbIi}sFO>nR^`fnSROBg zAQb4vWJZhAiJozwm1eH2hAFYC1KP264q!$?muyU%gMa)NRY>5@p2@Zd#vih2(|kh$ zb*2+<(TJhzL|-d)|^$kMA97YDb{1w2ys%`;JI z-F>qb`|v)A+cSKwk>sV+3CB8$wz#VAWBd9V>;Ka)QkrzC&F;Jq&HZCzZxcdwtcNlc z_y`KHj9%+gg5O`uhj@t`Je~*C|7|dU?f{tPzb8U^Cpm!Ju$=vObB+9JMnr%T{L9D7 z59K1T+S8QR(e57T<^I1lV!1F|{%|Z-F`TP3Dpf$p030PQT#{>1LwOOj^4toY!?Ge+ zn}nA+{c=Z*K&d{Hsmrue%mvF^Q!(RBpYxxd0#AY`l5l00{nJK)Q>-*p8)x^Be=LMj zA0(EY2nqu(qke!`r=$a&iznH}GFiFgMBT&g1b)c1rMtC3k2LIoGc%%>K7k1#9O@2V ztIHq5fw$yKD1_M_g&9QSS1+tZ*9T;VxT=>@9|^?94ZW{${}o zre(>fi$}C>2I-KtQcz`jvPMA(0s5-PSlD{On{o2kJplol{68fAj*uwvc6{G2;sMG* z+@M_$@bK7Jzf_?dk_zNw4-8`fcH;JMdpTip<^-af4AL>g zXeZqh5oW+CHcd3>0i4NMWVcam58CQDG$|f ziIaql(3TVR$a{G^%l+VCKTq(RN8pTcY`9(4_==U6Eh6Lb(vM7b=oWlXE>i z9Oq7#Xq6D}t&nd9gFFh?_zD-VyNI`u84HK2!rwj&9FbLq%FPFl@o#nhBtfh|*z+U9?p2JCFzlJ)kg+0=Cr>-T8KEp~zHM0T z*OiyX+1gE`BtzcGo(L9rXgq(fYv2T#SkIgu`K4GrOY|&owFPh_AtzxSIPuU$w-KU?11LCxsd`vB9sSQ)V8u&S2}Zi zlN@ncmCFvN= zUA@2$PPRQ!qvB`+ zO%sLoL|$^Ty=4@sB0JAbWheni28fSrBl7{H;?hCbKWK{zKmc6GF(@pZxXNFHwa{Red?(?%e*7wOn5pgIjh_$syCVS5pUY5En_Qka&1v)}cduv%bT9 zSnEs$VWua8Le}9zY{j%JwJCVsarS)S4-LJqmO2$+9{oTNrH`wFeuyl^-8bH^fPy1^ zJJbSJRE76df(PIqu`1OtM*QWKTZEc?j5km#`SW(8wljCsY4XXFn$cYB{wUny0YvSr z31Jt-6+6<Dn_PxX}_H#Rv8cm zv_HgaR|ftN#Zqwuf^i?n9+V~vE{tAkaq36bB&{*k%HK+!|N)Dt7`f%o?Eo5&{f-i1&1N+F~-EN&uPR* z4Mt%o`t6TWZ41?Ei1z~1o7?-neovOJ9cj}JqV;m=b-ymX2>BRKh@GvGC&5_Gwj4li*%bF_& z*fNR9e?I!+(l`(0AfdhQYUh*o?oc#WTI63nJI2@=fX;o;AL%|x?HBZ_1O~^$yLm?O zV>bsxKXL3%kzz}fvA|4apr=GAAZ8mDu&UY1D(^gT|rlw8o^dCf4BYL4&S|Wn#{~ zg&Azewi7A8w&bG7%`ly2lOo=^&z;Obsi;{2-MZJ_~B$ZzF-%ygFf%AA1^!l7mRX#HPKL zRo+~104v4spUImm{u(@-Th6a$7oY#+0}a=vaV{L4y{>hILEQpKzwSS2_H1OIcrswF0duEuv>>N>U?eoxnS!>n%kL`+?f|p{>ks>IXebm6HR<#s#ZHNV zD6DUandB|g>9b<+kth#SSU&yo9+Rn8}*!y>g{`yrd_VVHav=_qKj2JWcT)y`?FGV4J*Y24$a%j~ERC{N3CvDL^-8 zH20vEIH%ZJ;563xYCgzQ8MX|qn4TpViQUXUQxFFi_1gCOBNKl{Zj|#@|pN+tR9cTx*5h@9BLNz^$fzS=jb1ezML@|djfou8p^Z+ zflxgeLWH^>)`E3r;h}dt@K&Xur)EB8!o?i&)8fi+(zZr}t`5ujHm$u@({e;3xYjo3 z#q{+uwD-1E{x5Qr<}!KakqJZ~2QD zP4r>huRp8x$5}vg`qQUR)%ufJCXS-&a~Mia0#378p+il9IT+TvH%B={mCD+f%6VE< z43kyl)+bIga?_e1O(C1PUXB*0t|#&Ga0n0{;Owb@G2kY7NbDO90Ow2xCB0PZF8=R<=}$AuMqvSvJ}k0+4uF$5*>O4VK;ZUj+ zVTH5OOh!EKOO91)&t@|sx|?NvEE#Lo!QF|DL&-}1+AW&i#ofPwSKOcmH7K#GO!8id z`1P{ivW2ig6D|H^>P>?Y5E)7)*@D50eEb2_`zMKo_{zPwrhVc`$v#yBOTGi` zClCY53_+29rjsH^tW5Ay7M^Ak<*pNJ`f(sZ6$vWj2WUcJenP8uL5Q#VzB@b=UCkEL zESydDp>ggS7bDVnuxq1_l?aCmqpy1L3_u;TepU|I&^|`PhRFaGap#XZM_gM@w_we5 z@X~Ae|AZD6vkPoQCe?i5NLxpV&zmVXit3KgDzEBRsCs%)s(?`LS{lTASQH1t0ZOR9 zihJ>$kLvNU>y?BlSGNg`fFgU;-~(tcsE1HZ*b}<1=(!l|wUE}4QtS`7fVb66$g@$8yZYF#1+RGHBatT9Kl`uOI z@MSrLsg&=7`%EpzoJitk1>3z-&Z;b$vby8=RwDOhRCmn{n&B$2Jdm=JC|cD!n#Y`A8$BA2(6Kjqa-ZmS(Tq!h)Cb*TC(bUKCZwGvB1 ztBTZ!Lq90cV!Fb9U+S6vN~awLLN zm2e$uTqj^ED`K~2tgqJBB~c(9A>x@UdpMbTK^0`)7jXE; zaXuKN4l}rSAJN|ypkTNMlKWP@odi2dEBmPHWeYM&6ndchj;?pDduJr)4)kq#O$Pm8 z_hX61ey&43(p64iO)uY^(`!}(+UR?3V~w2tt7n9DtwA1VMoaen`|0|>EUvC%Lw$ln zItGAS>=3Kqa-Q_bsZ-Wrl%Z$STp`~Xh5?;%Q}DTyOTodcA_WxnmRdE6J&~ntZ{!`Q z9;afqf29SFBfEiy6pRR_u1!TXk8%dR8)-aDOIpabAw1(GPTq=3&sWd2W)M$8DQi#7 z51h+jF)#ca7w1Q6MnUbh+Fs>;y(rG2m!O)BQgXqz+0aB8uEEoab%Rd*eb+{u^4I9R zdL<3xoeJ|SZuo=HLc=1&0bccUQnfO5qn2q<)l8mZ5Tw(&yqL4mVOjyJBK%R}dkf3V z+f_YWPq%^6c}nQUpJFYlNFYxB_4Kc$$}(=2eZO+L8#ju`GJ6P!gqx+DJW1f>EgKiS z_pc2t2ZAVwR0ac48b>5l9z$>l*MC}q0=$+G>+^b+=T2evRUW|Evdn{8gi(@~T z`gxWmt55!UD(ShNf1IVPkD3BWC_U1IcC-711X22H*p@&PJ{cd8am zGz)r1iTTfaO38p0xpgpu+pR5z2`*O4yUU3^6@nVZr>Kd}THXCRu|pO?f{RUmw@7_l zZzknOt)7E_XCQ6;2=3W+J!}QSP6?CycuC+^&QU_6*SG`dEJnzS=YI}e=A=zPA9-I~ zJkPFdtF5VHWqeMP(lnCxn&{alt*PZ4lss&pmX(eJI42mhF8x&lanmE?ts%#M>c!fW zdb)Hv+M(bzcPSKunYv~0Wb+(xjwr=eSQl5r@p8IYhpPMuDF4(RtcdO|2yNS5@;4=0 z6~pZjyjf+~Aw&x~*4rih4`J^(ygq0S$S>xwdP*i!eHtko;(N5<$8JmsiPN*COj-(c zS1?SkAKtzuvD}ejhOihM=U%mr_U)y-tTQgug2O(Ya?f=@FV&yuy5a@bM;~$eoUPMA zP&OJynB3M%D@@p^6BSH6D`Jb&Fw%4pQnVIoU}7Y3=>MDd6L3=yOnP@12LYT-&!kr$ zQ=g|0noSwAvDCfe3|&i56T5*skwl!X`^hLw=srN*?#Xg>5)^rwL!BKNPB!Rt`I60a6)ryKZesI(u8>r4Ur$gn@d&^AU(c~pA$YAaiY3P{)_DKXpr^BxA@cOA z$LCxuau3PUD5G*=gUZ2y=j`+Js4`VhcvuO8*=8yWuS zD(fJ=Q4ulzN^-KVmfMoow;}OjAK#+!#W*aE^zcf#{EKn6e$QU*su!|Q?rjYc^IG|& zm)0$!03UWK&*(`S^o@$D)mcXb4UF@$xjhp$sV=#8%6Sh4!ODumwB6O03ZPz`tNi9c8S0 zQc(Pff$Klcl^tqlp3ibukhkjXa5VbccpBVR!zfCGveX_X)OExnT$P|mPl1~9N9o*S zDlvlc;Y6aUA!)2`ztfJ*jw;f#V&5bhf&!3MvyYS@l&R1E4VyM*SsLu_(T^4^oZD7W+WaH3B%h-cmQ$uhf`uqDOa(5cwW&{ zjv|#){(j$Ukio4=d6PB@E+II#su>@0yeXFjP~g;sss2W&$KzbFdiSx+LG}VMP=o$i z>Y+o7c|wn|Gn*hg*m4XdHWbF;gfNDW4DbI2yKhdnN*jE|lOFMe#$>2Aut% z*{7_HM{001sci-7;k>T;jj+vEwVblDD5R8GJyOZAW`wT62yYZBYk&HB+@p9PSp}LiGxW+JKBwp9LXGOAPHV@gaFET*h`5MNGta9J3gn3U>19f@Dnx zmn zQta(If*2kBJJEczohgYB1GwA+(HdW0r>B_BT)Lf%dgLR~OquZ7-r+=Apue4}{W5(h z9wPhbYRqP3oZ zntUv{T_~nk236y8?34XG7KnK6+f81k8G8tUD1eZ$1RTl^`aQz4iDVG2%l^eRBrwDn zJ9lHT63iYgx7;q)?U8ZL+*%zROZy*e|u)vGk$yY7HIZ<_i+QJl1sc)kPJzat+_f6J9HjUrB05_B;em|Hl7odV|D{Ey4cjTzkIiFxr?e>BBg7@2dV>-`3^fC+=E z-yA@wjm@dEUt;5{L%=3A;pB0YU&3rRYj%*kGnv|$W)wNiM|?vkGmi4tty;d=xJONN z&^}*}dWJCBAk7cRc`K~lp<4>mB9*UY{8iLvb@PvAN<-pVrZVc#jf-m1eZkGe=I!cI z)=g9E+JV8_N5}5+OncrXKh~6*ZFI*N9|VQ!biKisIs?B z&e{E?J3@^?zg^SvcC>a3laxdMz%@(b)v3|N;f1sE6pYWt&PEo((u8skUd=k0VxbRJ zSx%&l2BHnXlhB}j`h09*s>4`IA(vY+4&N=CEu*}d+BI0jBi%TnhKDW(F*|EDcTs?w#y zHoMgx2WE-$zdL=W$x_6}Dg4Iu3&N}gJh3^|Vrln&klMs;mtch+h^bve#RELh${xSvgK#Jx(Vm8~qQJGuL!edj9R430an9cIrb+jl#@rmYb}ifWLZr-N#d7`8 z(U(bA#(Ct@5J2eHgzL=XZ8XCAeY*q9=Fr{Hi}h^JCqu_73;3M^0N2_?+;2l$+=L{FcpA-SU?36M9fu&67U z5kHavOJ7S1TuDK|yBt=-wwdHdJaHl3(;j?ZK45aNGlm8=hxT!|Z=FDw6jnj>dr#rD zc^Xs6pqy%NX5XlNawZ0%XpiPyGF&lHZlBGezo6V@^bmn2gx1BolLFve8|T zb37h`N35&GXhkgW#*3#r-RV_mO&xKnd4PGG|2Ag0E>CgrAZyTV@sQQtiVBhTNEF4CL5Z`%L`vp+O*m_yK1D0q7{=}d8YzO|qo4T{j68)kwaP1$ zAwMZ3Aj^9G*ncd7FjN+VBFZS}CMKaJC?#sDI`JIx2L^-Y5zp8*n1A&vL z>g~v4*d><{v9oii$Y$D}xkv4kF)q1|^6*TfK(wmpESJ?o>DiDKiy+=wtQWk{U!&d5 z*WbHv@zX_Z4^Q5GR2RpB$n+EXuliGuOE}9UK3h&{Zb;Y58@GFJVtZQ;IC<>nB2lI@P zxV4|>4y-AS;S6vxm8xkq%pK(Y{RCdR_06AtX&W?kTKngbO zO=~BFHd_Zqc7BbuT<0E!3?<(ES9oR~BW>_^ zB(8TW;B>~KqoiI{Dr!n+m9=EoVO`MOO4URt+FY|sN5}E*5x^6@F=-2I(`p{WDw&v=AH63Nsh6%R$A9F-?y7s z;5pbi(hX}P<#J|5`5Q$=jXN$#6vJ)vI5I;6s)r8k!Zm2Q@ezcHBmp3Idy9B0-p3Iq zm;>O!b&yOjxTEsvObCL2Zg_KDLQn$rObE)G>?^FrB;t(Xq;2=HPWpPH?3(}9ZH!Ze zT{#c7^IB1|%&KOZdaNm=<$y}iUN9OkDM%r)IwRNNFBY%SD5>G+i_8W_6M1@wh_awy z4o%G%B&ccnxTa;kox?Ge0>UiYiCtD{3hr3Oncjn^N3EFrl7y>NjVl+O1`nYw9p+{= zg}&;@MRoHylA^ho(axG%o8Rvyux{m1ZXK~ob~nGr6nYe6lt1n=p%J~MFk2^vA#C&C z_K&Hit3xGA%e8kUD3-q{B3CbUgpnc?X&`)}LifKjXIu6ua}imrE{>@u95j7Iv(Jai$E-w$Qi5A3J#N|WH|@}ug3)*2#!dU`gbfD2oZ^Ri1l zz!M@TiPo+>U6&kmi;&B-lgS_3@`<;3w|Kcy_b?vPYUycJbOC}MUj3Y_+9G0U#}37v z*?OOI_v^&h=LGTDnr2Xx<`Oh_pA{B1yJ85X1~DU>VI_UyV;=v?1F5;K&rfDO9Y^gL zTk!Edx&i##-&o=^mu5p@fMDI0EwhnW&{J&wp!{bJ;XU|obV?K)jrtVzfon_%)>JZf zMr>(Ojw9H}x@c#wP<@Rz^lAwE0IG=Q;25ikOSil#FjB-PgV+bdR|-1 z;J@3fggQ%SCA%Thbc|h7D8QdgtG!avnOm3=s+s$^$Os7$*gL6KUXk=75QauXLojRj z1e!-ET%UsD{)$$T&)3H-q!wle6($UxYFdt>DiNHa^aa_`qJjwoPQyd-MPE0mit#*R zB;fGany&^6LyD+2vr1HR$CzDiVWFmI*)5yHnCdv8Wc7$x*%!Mm%G>jlD-zfUCQB

QqGHrJVeOeO@fO@2iQr*8^#DQ^OZVlw7lQm^8SJ0HMA4GkixMN*TK#e zG}%8PH0tfEgNlnWxyiTxIH|G{px1ZH7K*y*diHLmFOGq*?iea=PSkU0(FLUkaSRYz zBo9rBIb>UkdID`hFytsqgj|`yoX# zX`*%iqDHHoWw3JyO`I7wPXRC&Mg}cNBm=ej0{k(Nu_YI$9=NjOr_Z0QObQ;I-zQ9+ zb0x2~oX8@zA5|ECbis6X7IEFr!iFffrEZEAh}vu6KTv+YQ-mWD)!QPQw~>vUDUiK( z^mZYuvEj;VTNtcc{yT{Fkw28p`oPXN%JgCbBU`EN5$nzXIzr&z=wWa*~LK`l22^sRgF^niE60fyty0F;*^l`K_R6H$!UC#Xj5XmT*mxBsP`5vy7PU-be*4sfDe z^t|X@gw<^|3mX#!1yD8<ZhU)53gXw{~AbFs0DRODE# zxURWdB%kZA{R6tgQ{5}+JqoF2fjc(J0hs9hUVV!+1WlZw-7do1mcj;~Q3Mpx?(fSw zZ7Q>BQ10U$eaPH-eBh)))Y+)5;#??r4xbF||>OSBkohxJV_Rkv?ni(e}v<5S25@!$HV)|nD*7Z%BS zGgX_RTryO}6&uPv%Z*4SSRnOzBDd{@Wvr;^hH|C)*S|lXA8Fz!wP{--|4>nk5?oc0 zVgv@67)s$@99RR2bHa2JcA-yLK~Q-)!OreU-4suaK-zQ)4rirbW`q%&u_xdIAwt#G zHde>=d7BhwVHb>C9fn3r_sNg#SF1eQVQsnkP@3|@#f3{+p1zZJb}z+6uPxG)bW9{B zU?5r+VtJqkNa{KQT+9I&1>&298o%DT*X@j5-|SaIS@XI0=mmyOnxh4{|3Pme8`t^dN@w@W=VhQf0U zYaRY#s@3omj^6XzPcNC>uv4GnpfJ_nu}M3vy!ehigD8en0DSLrKplf@yYd9gxjFlP z(UycUP}Q-jfg}d7j0DQC&Ng?2JW0>F7U0*5BcEtA?Ap#6Rlup&eJzSq4(fZzu%vK? zABWOjawiF5F^6+A?m1#OHS}p3_P_t$+SCujpnw(Rp;oBd#|Ng~^yRIm*m|y25_A;` z3gZ)!k&ikPbD6oDG~-v8+})$Qt%-Jzhw3%xmTYZyQ@PTEd?t6wr!41hAz0!y2~{=b&`}N#2pMwS+rjBpic7>J7#-33h`KK zn7+xcUJaY;F5z`6pI<@+$e53nM#I{d^8=uoq;&td;r#=3O1Ot)8wE&735=qYDBF)( ziO3bA$%_{;Wkd&gzk8=e z%9CJlc-qCt!bl|nBVxd%e>#knEexOiw0EK`hElwH_Ry(&QUAkE4cbevtlBdC)p|wC z`y4Q5$3ffFG2i0wPpz$Hf!ay3jd z%ThK>Ps_DaXT~q16+DE<8oktymb&N5%>U+Je*7o;lo3o^J#(wR< z`{HFza(0zCdgm^V3-4%@&VTM}%=nS`w&G}$rO_`A5luXq`kOzNNzM-KGZb%4N2)T7kqC0Yf?4VnMbl-FZkS21Tz{3 zh-Y^=x$`p(BtNRe|TO4Tw>8JU5vM!PxI}m5U=dO9A%h^XTfbpaI*3>FlxvUxXNbacP z;{L&%#0u(~FTt$>4sd2nGWUl0jj&&~7U{djEyehh4-hLLh1mG*fL^Aqj`N6v%%KkqIz&xeytam} zf|c5<=p@X{VnKFkr1pp)D?GvmZzl5 z(d>I@G6090YYiQz`Kjf7_Z9~%^NKAsyQy*Q^i>dmtg)X{&~p>;uRc6h8Is4DV45i~ zc5b3Wm5n_bE=X|v6g?xIy~;^2Eh*ISlNo=54K+|Kc@p2Kfp$R6JB<7Z#vqD^+{s^< zo#-NhvIV|%n$*T0CfrE%C}UlU$x<%2Dz8_*9xVH=($=W@?ZYqk2($pS$?#Bcv%=WE zBufkO&x|#*-&7u2yA8rb1o{Y8k^mk%86nUg?ZgM2yYbada$)u*D`9iw=v!C0K$oah z7JuGWW37zil6=f>c0#y{IIf7HwpRxiKu+V8vEx@H1aV&lDEj#7^9Ng(0j?4&r21XF zd_f>U?M9VG*hz6}OCJAVi2kp^`nmK?`qAXT=f%fMQ7LQWS({YeFPlJI?C7q}M)E`d zYhEUkeaFJnqpi4g0cjATU1Lv3nnVzv+K&&n z>&9k64yZz8ABvv&+8uo#e_#s%T~qddk|xbeBeMk-xc;ui>Oi=d#UbPW(>q1r0@pOE z8@x#WosROJa_(%>rekA4SJ2mdlsz!gcvmF{>ncLu~|Nd+F*q=B?qudEsx zH3PkW!S=mJ+`kc(xSH{nWMg7(Fcp?Z!#DuNSes~W*zd-6Ny2497h4mD;8bKr z86dKbfaaJVUk4fy)=OU+HkoOec~^GG*klYWj++s=c@WPHO5C&vvWIy|I-TA3A2C67 zd%J4{F+~SpT1%BlocI@cyq@J@yGv+9b;2)_YYH67xFyK$cRHV0EHewsI3)vx5yOQA zI|WC=$o@W2TJ#a`qN5XFXCC!X@Wm+zkf&{6B(9&>ql{vxQs}9K#m+a?8Yq1ujUE){ zwQ2+KPD9Xp{|NZ(*@Kg~O~fT}B-R~Rj0$EVP+8L{fwoxu_p><+f;=7@w}yf2e;J`l zBlg~lpM$eE5STof%N_TLq;-O%bwmlJ0m2^&qZLr@_dZ#n)6}v!(45~y(^9StFuIsF zbS;0Z>nP!umG~@FZ`AWO7kT#ulqs)T3I(`RBdCPI2bVj^<+p{(%H(}#9iVF6%89*0 z)nodr?cZKoIG3#7<<-@Y7FFcZ}~vVj8Cfndgd zkezFz{xQ~C_N}!lVS*+dl9)2JAwlVHYMu%45p*cw)`SgWP4NUdCuM^<0p$_5X$~=N zNWgQM>%9A24(i1oFB`GpvS{|+08HY#vtd0;gp95F74;A1so7zworXzN``4mq@%Y)C zfweEzaSy9~FqHx7>qiZS@Jn>`-BP~k;fscK8_W+mI|+2UtKM^>9e?B;ga+Ci}7~qQ2$$;0%H|t3eo_)mWpVU=dXb zM5yXZU6CkpOtg=I;8TCLvo(3ymC_*6Tg1P(JMg*NIo&|^=6#B!0+2%#X9jAaUfOZ( zelROYZ)C2ox8Ksv6YI%C?0*D7@_4*1(*OOwSMGX@Te|aPaG6Im_n-eHzJeKadl?(Y z5(k6+du0Oz&;yMO{JEF!|0%|>C_m+I{V8oNF9C&R`e7%Lp|AXi$?Ns$!I;qR>lg=j z;74~~#yM||rWD2E6jEhzDV0)}U~rEL1xC(cE`5L|_mHmU8@qUY;}IeY<4%QX`HumV zN2p_ljYug>tF6+#-{(I2KrA4C8-MtC(Bmh;U33@wLbu{j@UCxXbuV8Uh?7y52{ICi z@=L_$4wlu9=;G3TB+6tj7E6KHNqKvg?;>(=0Jpl6zT)c*hv8Ui)*gl@O#h`KaZEZh zxu(Qh305%1hVw=G?wSNfZ1@ooaj$KVYU^qLIGTh@B9W5cCyoCJ34{22zK1XYJP7O5 zm11gY9v9aG*aDEv34VHXXpLYR*bjb4`0YB?=HLg@iAYf?CL2r&&>nt&S>Lr4b!ZDM z5J~phtNnL9UsJpf;eTLXJv@@%bHErt!bPt@nCzHhl zCE;C_zkFk41k(;u2;Wxwa0S>pR#pu`F5pR~9b)(fO<&qc62_~2E zfSXdCX3iYlJK+!xpir-ldmhmcT$X(Vp;4ixR2Y^f4pg*`3d;eAc>=>J<;{ID|M>6moCN2!_^4EI~ z&?-lEc+)Bt7K+6P@~*|8jh@yBGWPw2ysch>?H~zbjvk6oehG;ggA>O|ZoX(g+|oV| zCc0QU7nCj|`&S9-8+pkKSTvQ6cNK~!=&LcQ!OYMi-0?Xp$0IxBKqQF1bZU-yurDNb zjPZ1xI6s=mi>8IPwQoH}=RosybLX+A4-&7Jy`>^3@*Yj~nR>%I-c*PFU7|AcV@F`WonMQ<7WV%(#)WOUN>!RU z%ZUdZe6FYP$OD@_iG4J&$YH04!qc7`zj?^S3nr(z#dO~MrVz;&?y8gBLKIFwU2p)R7?IYRj6MPcZN&d zW{`i|XF0e{o=vpOJ9+zYIU7lA_`u*gOZrAs>UxfZ1t+Bv$oq3sB`DGC5}HNbx88Cc zTzo@@Q<+i5)ek2p|KtcqK9!8}&96WyCi+zt*OuhAq0`Us0+-X4P43c#fIzs99?>6C zG#oYU8#>`cLD6uic8tg4|EK6Y1Cm-FKYlnMO9fou1}9E%qoo`-ngjR90Z!bY=BP|? zYnEtBTUu6XOY4@}?Us-^8ox9f+PJ0Gz1ei!Tk37dpFb~v7rZ#nf#=~l=Q}IAF2g#;PHN7M5vFTJT2hp2UHR3WOv=!~@x|Qk%f-#ABXAl0 z3);%CRd_t3m6;z{lKuy+xW?x8<>*9 z>nIFLd2@XPPv1ry5)W5Z6i#eeW5JhHiRs8Rn)oZM-W|ntUgN;Vud$ekj!2^2N7(Fl zb^?8}HYF5!%x%#cpGq6&DJFp@Xe5hPBaHoAxRuas^8GDXO|QpmTTTC;=wqxcMq(@d zTGBL{{aRg#{?xJ3Ye|0_Ddx;25EU_T7%+lOweacUU)Eo8`_xsIWLHZ1zZpz2)M&uG z1qKNk;_w|NWmIGQto0S{AG02v-nU?v5{l=Uc*A9XcVJMEo0;50`& z#5`8A;AMHa{ydxNxqdVxzx$eCmjx*d#hVzaku=PpcIt17K9+KZUQNc=$IhN>7qv?( z7S;yFG!!i*kO-*uGZ0RCkwrU(gu+=X*X73{I2p=VsUFP;((PV-q|NQg*H1>L0)EVrS*kd$ST&WH6&vOI_pyjERxrT zi3(J%B^)=@z?;fL2Ipb%Aq&E)3@Sh~My8yzIvy#(8EEcXO|uc&En-TVZ# zb%x5Lc@fXnqb9xlRzn;+ev0U4efentOF1D%)nb5A5ZO16x;iD!Wph$>=Ym%@Qal!t zy!3-J)Dpam-s#7PTME3OhOEJ^?y81XmXdPCD2iN}3br3=^^SB;-2jGWodox?a+ zw$h6DY5z;>OZP>lC||pVf5-JL9!l6qj3Tt3^jMO4i-+ptXQH=J;nD}w{Y$%4zdN+> z5(}ws|4p13K@MLpS`x7dv-^sRLuL8M03DtTl+8bys^`gbGjE4$B@!WWy|bJR=xF26&p*_c{#Qs!I;?V0u{<5cMVR&ybTMw$>c{7oW9Fno=_ zRxHCIrUA)?jCs^h&H{-50oyZ##F@-{%zr?dJJC!vC12l8xQw}Jkv*zV zq(S{ncq9%=_tfb9X;QXFhaP4|4yWPY8`+h#7e`2{smzA1N}_^Q$jhe2+|}x??FqA^ zP4r1FONL7(ru%)OzxOWL5z9K5o0;=4d!fU(vj~5!@F%%DbLn)U)M4gpjFS= zAyY!vqiq3XzY;HZlrvB=+2$}ZKJYrjX=8u6Ysm}@oMaAJe_i+9ES!n2AwxyMj*PrT zf%8YbHKR3-x$jyM?U>ZEjDw4}8pP_OhAjtY9(8#0sk-BK+L+Sna+!;s1mQ!ryaLpNfh3pw;#SU69intbB!mI zaMB6|6dZ?M|83b5W!X#k({{Y0#7T3;MdHSEm6wYodNpnMXoa5~@0N@QGU5UDdWFMM zNo_dHs)Eg!#xJk5=j}#Ty(_CNjFyh#0bWXQ%<^l?FR$ag7gCB-kr|?m5u>I!UQ_n2 z85-)6ZMyr~DxU?wbUzAmW|ne1=!#?n zypP5U#015>m#w}A;Wr=7%y@{w#Z)(5X&9>E5IB|)wT>xkkF$%;A^wSi;mf&HdsfUkd&V%l1s6{ngoOV32wK$+;PxKm&Mo`&nV7iRM z55klxgEiI^6lRXV?}?0LHVHnr;>PO`-h7n+4O4zYs0i=2`;wgboCx-cq##6~4B<7=ax+7Y_%w|a@4YQ85{uIKIM$TjA(8Q<@> zHIN1D?(C11-!bf?S(AnCo0+}h7@6!{d(HR-p`?RCrf8hj*H;}k`|}}uJd$0VPZkkt zJ9}dYxQo+YKdv@ei>Nnx!)#}xJ*DjR0DiXblE6=&JbZxXL7!>Zqz9Vv#slzxzVB?N zFC8wHJzHteCPs0cPG6p_{aw7CDqu-pRn9@jd;8Im9ZGus*4V$GN zZ*|e=c4zwQt+!L+@wjkYj0s1D<5$PC>n;ykIi2Xis($zO?du=q^*m$_G0(Ji$LQ3l z<@U_TI{cydxA+gCu8fQ=VtF$RQ&}<2l}w zwY2U>C7YPEbpM$wUkDx;nC3dbb3?ftS2FsAPqZ79#c`>w7;0-2Mg30`)tTu;>iX9A zmwm@g>F)Za!)je5hXGB=@);3(LRGbufT}^H12b^`B$+ga1SQ}QD93c&4T(Fg$fkg* z`6jhI8wi+>i2E?fhl9GRca-q6!|wHHv4`L3nKZ@MN|W`LglM5&7pV%PZ@)w*aTs}n z)qzr1ZFVtYcvh-A%O+Eq1op5&pKq3{J~&A%(XWVI%NMzb8<9=rdyvq%sp?wXjO_V~@t1>J}2nmFGmBkTA_lVM2Qr zwI=UZTt88=4NC1u31DT0l8wI1MsYLmVYzuNtM}?a(#+MHvRRuBEi0Eb zXwriy46?R_J4uW%XJ@&^Pi|up@g@p!%+IefcZ2`Uj1Q)~v}Ax_D_$Nh$jU-ug*NzcSiiS6 z`6BLq_`buebnqyFBnyZSxDKxy8jA`B2Jvc5_X|+nsAHSvG~E@oSelAt7@kSNtYKvNXnQnoyQ>%Bjuqla+_E7~$?azLqxg>%Phs zlQJw|G*VI+r;u?(E?vA15q%%xz>Awr4Wan75OLM-vI8lpf$GVQeG+-PauF2B|}IK;b*VC|6|0{)XBSF=Kec0^KzSGBq5 z;*x{|OhWluK>+_*)x6;JB0s&G{pvDTk2SV$fF*jg!}dpXdm$q@G0?V(HT+fx^(N3< zPuh)db!8=Zk__kJaJng&;fo*N+m_ zVlD%}!f2~{PB;K$wZ$y$g<(*zS0A*uTH$q}4YbUoAhPy?RPZH(@H=%{6s0j zsuu)#-*RrI60|X-v0cWWS!89No%+Q5E<0MC?u_S#uMJY(s-6CBFWb4R*LHzBO2jOi zGCPD^ujoI$o_zpi$-YZqIxFq?2h?mHdv;q`6JRA+3vS;9l4(}F#QgMF$Kb3+Hi}-X z-ZvH2tWBsxo?FH~IyjDWGlwV4pOM7BW3v6a*F|H=?(|eI^y!S2C9)p_bB3KY?#s&P zE1elun}wWk$m|jIhhAgk)O!2l0pb|5j&Q2(`&0T*xr+{4>-z=&R-C!k#=s^w30>(H zi0&e^nK3}JK*wgZO~L{hjgdF1m3rlUs^4@tq!SuSYc?B*vOO%E`Zz=DmeE{(cXTbw zw|O4_hGjY%Y~G#zrp6>XDseOYhEWba#fQYge|296oN@v<1)f@onXh3F`1MX)AHO>{rF(_~#4-g4up2R@0p5HWnVl$ODY z&fP+8ID<;+%^|VS9V3};!l*SjT-X)A({I*{7dVOxJGpkM%MF0`*ChDiA4{(HG}7 zqg_MN5oWVch&=c`>mqfkCy8)mUY(WUEK5y%)7rwDNV0C-I&weyW4A${w}Bn8J?g!* zkBpy>BM}$X+X;0Fnw~QXgEPDJ{Cwbe8Ht5)kkhDnC{<0hy(o57>El1@RFRlgit_RD z=C(dns$GfR!oC8<5|+QI)O%f%zSV)@DXvhb4yJmNeR)2qHeqt5Qc66!mAnHY^S87< zC6LxgEcOHGm1R$xwZ03@-)attSRWWC=tDPK{Y@&gzB>6ijJr`Y=5b#WHb)PR7m5_$ z+?oi6R<>F*hw`F*m$IQ|z>BrHZ#u=H+m=e>mPGQuH{Wv(rLvKmbScYQ+5ALh<&c-G zG*+#i1=8AD>e!QCR7w%m%}PDW65XsrUJ)>hZ|Ocb7o!8y^8iP>ml zI_QK#zpSU9^Ff*;nKhSbOL*co&sdghWeBA<#2XhQ%fnVm>26vaF`y)Ef_mz|z;nYXX19u4!{}wii8Ug& z4yyDU0<&58k`UC~ogJe)@VnyZ-n++lEVlbIQ1_1PZuOOYMRD1p-v~nL1Z&M&H^ylb zLzti=tn?FQFhHlS+i;Wx-HR*uPt=d z#QMJ0>6(1=pPX_?Ia796bL**oT_5WJ+vpvWva>o{!{w~=?7-o_AUknr-YRL{TBRZ}>B$+Q- zAYZ?Hqr!to3T(U*3O{eGX+Ay_r*nN>Uh9Eh14IW2rU7;OcHOY*4F<6sR=2|xlq_Pf z4HCy`TLV`T9m#Q2 zPgmousjUo8`i?GAgTf3cfzfERi!a0#nC1iv$vU>CNf`k`$#UuqHsi4AKlqtV4!!SU z%Ds7eVn%|gg+Z;V7nLY{RA7UTE7)4#yY}q@y#kUYIt^Y&$jL>1s~*OE_<+4eUCk`( z;(TigX?6f1P%#Hc;~wi(!*Kb%v;6mZg-an~8mXhlp!yO%8utQwv3Pu~Y{tSu|H-ge zMy2u)@cD0)N5WQ29!eZm>Nf+BQGj;bwFur4PZxi2Won&miX+*TkH@f6e9PUPR@*O0 zM}5vd9_r*+0P7HAoS$EQY;j&)K%BVcY5ANzua9C``vvSs=%s6Cx?{Tg!ACWq()W#n^PSOxYCEQXAJp zPWpqJrIu->?G`c#c6wHQ;sOf*S8fM(OAsI(j1~&P;N?>#2M(|x=#KZC?wYGB)yhq^ zbcuTPjcTKqo^EXXS$|oDPbTBp2!*TRmIyIE_6d9sxlGC9Sm>~R9|4DK`qsvg)pn=e zu)D0EZlx2Z>(RmAG;Pj$BR5`^M=~bUy%yBvwNc2tEsV-|>IzJhxKNiM#FLQ1_kK?Spc zn!_MnduSOIZjE9(>@rd#PtcG^x{g$>OaU^}nMDGycQ#E&>tJh&LBHwKg7w>zqvDVJ zhTLlEN964oS0lk28~f}{p~%Q*$pn=SHXeWA8=OUziQM}bUzr0ui?Wkg_T+|Phco(o zR9#)G>A;+lK?$Z8K>_va_S);Kh@-9qc3YGOtY;(}sdqTAVdPH(rZb_A(6T4zLjseO z=G9uFb4D~Lq)Wuy+e&0OV^{dX)?%I0Z>C%m-K^>CS0$fE@c|syRZkk*?>+Mkk2SfY zI}-KolB#gF@?GmU{XYYkQAOSZ9?>{y_tz9BS=8=u*IF7xhK$wmwiWe!Eu4x9OVL$R zyER%|0K^2YWY{iHfWC?fpU=mqq>O+UfD(THZxwoM zBDmGqiOSG*3dcF)TRRL=<(m`Er>73IpfzJ9s~gb<9Jz@?FJjK4Y1*&cVTe8#Smv5% zJ>kT(cTibg4ReNESXtSoZ!<~Nc&z5EdtxgO_3(;(`&%;MUs?6F!mh7`{iyCd zN1-~HE-heG^1aU1)U(28j=k~vAPQU(xG@SKZE+E|`(1>!bf>qjtoU|9@5M%~l`Y-4 zS!Jd^z(IHK3S! zqxu{65Ar>qT+hJktNJS|^ z9&oCQz9)j2E>)0*`pe%Ey#`a5>5(+JYuSnMtz&zGhX{hH2dAS)29=arr0Sg|5ZhpU ztq)sVAF;OB{LOPLJ-x#{0AT!VmCIH5GfD2;mKNbSOX)_Xue=8pUsGpLi=RY~e^OG| z(YuM(q%tTx{0sfliXS3cpuIQB^Yr4#_?;*pSA@+!tWCIao8BfhXvXB5?NAId%6XxT zE#7?x_O_XinFV*WCM;n!HS|q;vKg)FuL%oJkuUqCsPd5jTFH(`;kv_b9p&<<;FzFA zaTr{!`w?4urqA5~l3g4O`P+GO{}w!n)IHc6!>z#S55g}g$=MBk6^&^oG6`sb`ONL3 z`}wub#$W$b2Z3S*mcA-s`ZxXPHW>d_tLQ8hF%;kgp`kbSWR$CkIKrL^Bdbu$f*@7^ zxdK^}G&7Ce^)ZV*Lk_T!M$SHsUaSf3M?UA065J%B;-3fd94EkPoNuzTE7*ial{;!H z=B!(@W|rDRbcpjKn*l00_M=mL9ed#t`>O9{25UNBlroQ?_9T`lm-&(w!PhA+iCXxt zJb6HBFvoHzu;X={PxsR7!e&A0@IY?KbjP5p=1l3ebPls@<;;-6>uAaL(1XkqeY{Be zcwTtwt`BuAs1DT0ibIOWRf)sZCf3B+O;+v?fy*5wvMyEpn7JfpbGP%l_v%op>)Jrh zK#IZj{!LEjg-xN=b7Fl;%{1EfG-H$OC&A46qczZ__Rkk`1h1s)!hv0)a zVLIaio9l_x|LWBjDJM85+$MF%26<0O;n#uBbS`CFczLf59Kb_e$&aOj@D9>|E8!YO zT({T@mA5{^w)?xV*>3@ibRJRn)Z*b-dh=w7uz$sP{#}@_)9jbGw^n5%{HWWR6DgD8 z#_76=IR92al6AZ7ggd7@(y|St_wfd_zl3`Cn&OMoJCI_ubZmCLsd$$F=wk-D;w1n@ z;Ft7yeeL5FaOIMV@PY85Y$u*%t}oP|<>6coZ4I<8ise?p&wxrga12 zHQ;r69iqJ*w)2ulojfX^6TF!e2-}dMfV+)OHH*;K4fQ`V)NTl0Lp^#HF_I05@WgTK z0JI^4p;i-qz|rwcaqf#UpxT|uEJz+ z=tOhFU$ZC~=L@TS$ON{AlD>io_qh)7g#E%@LKNB#ntNU@`z6_9`@(A_3qtNuLrwU~ zeq@Pnmi`9eoQ1lJLlEx2Ex2at80XdGDZSOFl7D3Hp-1xl)IYp0ZU6gjGYO4WnOld8)0V9&np?M$Ye%S+qb?7 z82;{O`p@#!#)Qv*xe4WCAZf%~3Ex1|E%Bd|-5}^^fdQ%Dourc_f9*Ij`?L9{$!Xnp z182tI&kbQO$qM3kD=xB*?Sj&mLdh<(b*Jx>s5=nYAS-}0e+u8cvZ$^7CVBhj3^c+2 zk{q3fU-{*MLDWIC4aFBzN%4|@5#f;5pQg`@Wv~+A339q1`_yK`K4^GWSX}XEFJIC# zD~vZLef|n@pl7+a+Sh-1K&x)l7m73?w7wzyF0-q4&43=2oxO9P@XxcK{db0pJgvO0 zRK-$8etQYIH8kHR{Kjlsq8~9Eu@K8kX5B7V{MAtpU6RRu-4nJNt?EItVMx*?e`6q& zI77#4np@e!8#0?;27jf=BMQymb(%cJ&%-3b_fRk4md~S`lFI#Z)bMQ1uV9;PmXIB6 zseAiT_t!$#|DvJP?>$aj@H6Cbi-5Ee!u|nVoP^Lb3G7QurSeZ9^p~W`8cl?R|6sRU z-GYSc8!F4-e#3}$zU8F%>CtjZ6)$x}nN z3o_W7a*bbM@}^j5a>i|!=2eq>(8!Ai3i}pzL$i~XtKgTRd0F{?kZt^lBAE;}Ly{{ zh6dkX^OHc3{KWhJ`ZDQrtFWeHO4wn!D&WY0biz^DZa1$xvW*Uj(5bt5iOw|oc@fxk z%HS`?=&y2SkkzkBuJC#COo1-n7nMm|m?-!n z`7=l5Cq4!IZ$pT;u|>&#K@EQU^$CYw>bbOI0x*Hu&cNl@gB{Z7%6g>1o|QFB80EDW#qSNHz$ufJ|ipA!z1 z!|sRwSX=wilqcDj3c)0CpU?x3N-m3`9ET2=ihuvhTcbnH42hB%AF8Zsyy=U6CNv%B zYy32Ny@-8UKLu)gPKx`wQ(tbyjw1h0qB@}5ABMdNdwh88f4q`=W_6>&Dz$A{h-t2T z8SNfG$27+Lf23dX`-?-dkJayWKy7_nxPN_oCIkb&X2tD>DJl)Ug}9FrFIGJZ_^c^G zTY*@L!Q*G;XG$Yw$uAoJd8bM=yZ#h{ef$@)t10UpmHBDl3wo*^@cvhY;mR6uWI#Rc*-6#vAVswL3ok{ReGvcwvP|@p zX2S$ianz!azD3z_OMN*q3uj7RzJu_493)Hw%$mk>;^Yb1m}p(Z9v-H zt5ucWC5$?mR1|MV-ZPi28QC0)M~4GotJx|_rU0f8PjKoMc@U}6mp=RDUnb1}X>Vzz{frK_Es>X0VQZ*YE z72+AICvX-?FP^)!)NEdb=P*k9$riN+S5RJ-VuKEw zX*&n2Zhe1M+f>E*pgqzeO7+CmR9+t8lBQa~xYRb(SPcAIs`pqxn8E&=Eie44%zn;1 zteB&fv_+3Hr#0DziBDnZXFZI0?h%MR?V@UZ1FZN`m|T2k8*Q@;@feHzJ%waL(cEp@ zHcf#~D{446)Kh|5e&^aKNegvhik{az$fZ?|@l)ysZd$ml>8fYW>+kmAj^ySiQf3H! zFfc6ioEMTGm!V$47Nn--eA9hpe5nwtU?`Zlat`LOd_eT%nkUkGhbAh$&0wh9n3*xzPysvd*)j zSX)1(Q2e(>{AmRi6s6=*1kbP z&GqCf{@sn<0~Q(?s%L5#jCy=O#|Gf1h9RlR{y+@-QW}M@`~3R)r5?-gDM|ZMo&Ii2 z{*`B)GP7)r*4YS4`;%g={_J5`&Ob>7AMx3*J{yB&fxeWIw2-Tp)@+grA={7)0(<7` zbwh!mISxFtjh9b9D%ft*Htz?VEBxqvPxsE* zjKePhxMyO4sQf*kdhPk|icacjsc8ycBGbpMgc>ckK_x$q0e2fUZ z20o>k0A2Rm4|l~?0fTlmQVYL%4ltU8?=U z3)4=XYQl%jNNs@KMfqmQ%6Aek6ul2Un}sJ91lif0edM8XOVQt*-suj3-by$2Rk$JH zZI{4=lSf0{(kM?%6%OjDT%#Y;bk2GYR6oq=2XAI@IiY;Zp5>f{{h{iOFuXMufp_Cr zmn_EC7a8cU;?j!Kgr^QU*z_j$=0u*kRbFnJMonluNeNK={1l4t3?-#*LqV z?aJY=$QdWsfm)S7Sm@L9$r({U3!f@~$r3zxkjJ!s3R5fa`2n8R#yJ|HVNWXxZ8e`h zMK>g0s=V^JLV5Dj7VGqrkDqyNe@}RS$+(be127|&)9-AfxZMaAVVrTz(zaG~$>wKT z1fo*|jq-8&RF6gvY`gb`^KE(>{d?ygJv@EfX-#m@fuJD+)pYG*?JPiU(Ub~E2im=@ ztraNV+zR#e-wV=i{_sP3!VHq7n4iR?)a`OSW@vrzk&hjdMcaRC zys+C(l+7Y{n8~BAUk3-*DJEHCxq5`lE z*b3gq%usLKE!w@C?rl{zo^>9}1K+h$dHPtvSY*Mpr^gJ#0BGX;ejg1uV5d%q~`oQDT{!4JBhBlKCr z`U*yh9?WbCLSe#MY*I~rX`1f#IH~yrneFU4b2s#Cbd7UoW0hkndb{%3HUO=4>HPat zVXD3$M9Hh{Yyj6Idb-_u(!m2;NLQ*SWGVks{Ykn%C)t8hdaYs@GZ6rILKSqc7+CHh zO0va~5K0Q>!ANAh#;!E{3lMkAY?qVm-Lr7>kq7%}+wWdg__Z?(1TokrA!C-IOKXJ7K$wj;dm)*5%C~NEcRrcY=X!zTfCl?euVLI-iMwAN%t$1)g!%NYE zlYnYYaJ1BBJ?~dcrU*#^%0#3Y%>EC|frfcyrv}YPq%SP$d5U(|Zu2yc!xkBHj&ZKA z@jC>^OCOxihiC#Xn=Ou1$EPGyd``YRqvCFM`lUKDV$`uD18}i;#fa9xV!*SnJj`4{ z<||Kopuicm&D~C=dIo_u)l@>{?(@`qEUGQmc&rh8Ek=-R2j_~qDEUg3Jt9j@C_iTu z*M!vwAX#vpOCPkipocjEeh#;v;BTK?hu9N`)ndRD3q9ZR8EyA#t`s6PG!Y)i%92|W zyun*+-24HxhHD#Os#eh4FSGL?prEy^%)YbUTZRN}On~#6{~H+xMWZYM&t$)hpm1ZvQ*m7x2A0Be@!DR+7uzsT?M-QQCg$ z4q<3T@!7*1c(Mm9pDUn)nT02flhxGOpB%nbHi%k4KaB#=mi_DxN!a@s*d9WnvlK-#IW(-Y=&@pN;e{pu zzp9k>`0{sTBm>pv#PmZ}>YQc!oDYV+ScRvmfr@{EX9l;^ufMo!wbhiS#OYTDDsRnC zCQ+J^uZWcdG%yJeRF&^nD^)JXq$PDnEF}~ER@cw-(YXXv_fg6cvU62ylDPal&^-n& z{AFhbBJ<$c&EYcyA-~%E~{H>W8?d5?&Jn~CP%*%^yL_}o#Ys)c8`oq3T zIjNw&8>POPghl0;FVu-YJ$k8-tcWFWj0K1z=9BRljb>GqpXdVVtBdn?N_?Y2ZgK6L z{@oOmk>`5R!CDf&BqvjlR_dcEJ>NA~coZNY%sLAa_Z6s|pSSk4^|wq&nydFBK%jEI zlAuWYB(8Fc)L5vP?0h=uGMj5rTMeIm)7#RPe&yn+dzIDMAYHrZ+Ev576%Gxj-k7Qo z1ZpT}GPp%$B*@hVWM`ukz!YW0%(jsoeV{&^vwc1U@1h8@zDS`*_BA3caCJBPpxZBD0VACwxN zIEsGfPT?L)poj;D&;G1DAinr)B1uVOOMXKTA36_M=G;Bm0(Rf?6J3Bq6cqy@3VzBv zKMNjf8;ZUTVxQP>MU8o%0ENPc_n6tEHjdiEivPZL3<+$l^3w?1+S-Ly#{XBHfUUOv z+mgVgRGq3su3o}QFX1x09iOCE2ms*mk&BUY@b@RTqb~KVfFyp=(~&FSA?!;t3!RwF z>be>uYW9&8HgjXzw_I*dxyNfBF3`|!6lwl2(1>gsab##VV1irN4@4MMn##f+#jN>w zHN1u!(p(Gu#rBV=Bm?XQ{*O-QjLKcIe$PD=EuGs(fwC;6KO(l}h}w=+rbUwjsua-q zVDQ;x#l=%Mw;{jds zo4Vyt70}$~E)hc<=hhkT>DFSa`G$UCSX-mV|8d`8z6q7dN9o28$ac{)AzPjTnKr%rmTh zqQHHUbPdqO>1KBBS|lkRR%<9s7A(CuNt5sGRHwYntsYIrhLr-<7gg+ADq~*?6bwWv z!F$5|rutLM*oY=G$R zPWE!P$i%8?RmKh9gLm6RL-tJmN$MYkl z6@2)fDw}JU3^rX>BL63_p#cTDb1{v8Viu;Zu-Wz~|}z$uPqL0SGKN zc#z=^G@BR`hm3F!b=@cbd#UuPTnccrK@teu-4@v2;_hac0?@YWz??C*c|erla|}y` znqLz-m6+Ojejnl4$xW)(4}1XqUlZnI?hgaEEB=mHxh$&d3M57*Bka!RRi%)N~N>E z935t)hQj!hU-{m_;8>b4-LqWPn>+1brIG0HOfS8LO;tP;pczJa)(FzS{^tcZQM+o^ z1PIS(UW$v)6oVUTCd!6~^s+6IsP9iCdtkm?Ks@)z)K*f%MB|h__=uB{hdYfbIh*>d zcMI;q&cOncF7F}kmBihC7CDMtP)*sdVLN?q|`i+vgjU~O1?Kz5(WN2UUZGl45Ee?(=B90@98!v9z zd;Q|fQRC{lbLfDYk^ZQeqnk~rXnl831q(ZGVR_flO~)g(AD&^`_gLec2z3r-ud?&q z^?CG{^T1%3-I-S9he4G8unK~>Iu%>nw0Q@4wcdk((5S+HusuaKanl zi_cbNr8~y|60TQlmYN_afX0E!2!~wW|gg##*jhJuK}1 zW+2sXM%N(Ov-Tq0I~rD)6T?!0(aL6jWPQDny%CQX?eloW(H<8Rq8Z0uE>0^FXhte# zRu$3J=1z28wG2?K@AU8DWo-_)bIParS2$Wnt29#4&+dbJ?+LSnaO7_IUrL+c$y=0- zb|=g{-8a`P%owm0*yv&#rxZPumcZv}sedoC{V6|xrt$a%+Y2bs5C0A%0KfkQdjZ4& zj%B^b%z~HNOkh&EU@mjptUE5%Fha#lem8D7#ic$qm4`q(IC~9SKmGq>-=x~311~t| zAKBKUB2mcUWV)!qZ=E0B4&NW7>6<2ke?d|lGB>|bLF2av9Z7wm{yef~`g0sM#d(Pk5(yRR^W5n177(G`cu0G4qSkJJz^ zZ?!0lo0e^oDCX|=%|5s9s3(E5fj}VIL)*|)*XC^!bTUKpa1!jTX45&0kIwU8gc{D@ zD=7zy%L0z;2B^^vrxw~G?>i`hmSpd4wICreXzr+5q#_g*y;DGk)H0CI#n7tgHkT6Gn-!xs1)%PQ?}`D zIe)!?l5)}=(XWDZU!m*|ylwD1D&GrRZxckil05RjuMpdp4#UB&q*cUwc=fx5c%kkX z#@==A0b*?JO%FS1^c$^&MytEmwk2s7opIAtRLrsV>f#E_Hsg&?WbgBji}S)Y*B$yG zADKy8@wwV7Gr%t|stpX`VY^Zr&=q9*_yII80RE%MKai9YXhg@#PZvf!TK#_voo8HA zXWz$9_J)Kc5SAWx*a<^G97!My*&_l1B@+lE2_zAaS`%iNf{5a(Oj)8(rGle|so44m zDlW8w=K zLE{sb+khqXNnKRImhe?z)2+|-gO0B+=K^t&{OOVmY9iF+azr#Eoj|?^B-XpsWV$Zk zHapKz;xkHASTvV%#`7F?!v=G2Ql;-dP|a_qMt%t9Kcg4KG#hIeiyuUus>`pdjB{;p z)xSXjGY~`|K&ypLqkIt~WmmD`uH>u0On{LdVZ{Qou96nsbp#mWsUW!z3y@|Zx&30z z6LgU&7jgv#Emo_(vQD2Cyo8?inkWc1^W%Tg0`TV$%v0S9KNGeX}MAyHerP6 z+>h@V)HE)|x4!go@!9^-5>`j{ogoU5SQ8Tw1(FY~pAW!}lz9k$Ds}lf?!Jj_G2$Mt z1nucwh$B_zaX%F}-xauyc|?JM7K;@jJ}H+*wf(~9#LFB1YgzW6m_o&Er4OfT-|^#P z)6#UimuA^eJm&G64rc4^^{%L4@D8xPKie_dDF~hS=6plwl|TUaO4Kclc|G@eO7|&; znLGd;V0KVoC*xjM9AM%QK{r9ia!Nz9ACx_Mi(Sa0b<~-E!IAqa*42cQ;Y0JR_hn1T z6H8fZ=h1K}rfBA`K2T9&$VH~PAlK%p#l=2&saNhAwX?2ZMlhY;0$~S|O*AUG)I*qXh1%Q&Aj_Ca%B^t#0AN>R z!w68SAz(0=Fze~|3PjLt%|tEZ*Qxg{aLE2Ko`{|U6#niu5nl$#tzDFVL~2%cB#0HzK~><+)U|zyiOH??%e}%c?qY6 zLP@JS@7Vh5#x4~J?^^q0zB#Nz5cF0;&ww_y2p62mA1024e(l)Y*6ge?b?vjcn1=Fu z)-YgWe~$Rm^ob)B>+x(0lf|j$$XXvp_rYiXTTcw`dTR3iMydv9d0K>pb&Z)?6bRZU zS)EirX8v0oP4-%VXibiC{s(CZLV6)u0tG@a2V-5L%?;PmOBxJgd-;L5J&m}x*Dm_y zz=YSASS%Fw1{-@R=NZ)U!&Ue1>v3dZ#@mYh6VxB&`56K~w8=!Db*_R1F2@S&G-Q44 z`f>0)yL&SZP0GQk;Y>U;W5c81sl`gN>-%QCLy`?ean_>p%oujCv+W7E)e8aFRn|cp z9MqIVgzXJL2_XxDJHw`dNnFfiCv9EkTN0r+Zt)@Tu4xRDh90!@Wj`H#gZmfcQijFX zxl=qz`MJ+40vi~3*%*r1`xyWhu_}IkTFN%%(T9iop!s&+?seI6Mxc<0BYpI4WBWL_ z^Cw9)y1HZ%`B}2?Ec$0|0mo-3W zdIuYU_wqdKheXGe*)#P{n9AZu3d;=ZrmRysh{vAd3w;qB7m{`a*>mDg$w=bC3gVG6 z5>TGvuJf&p7)>>$=&^?oBhZnUp2o!}@Zdow%|!EQ=VliT*P4p~c|#o}5-kj-O_=Fk zfc+Wo=ZJn|@!Zd(6&PPhQn;`Z%p|N;ThrbO84%P3lo+A65T396p9?;cDx&53G}SJ9 ztrFRn2cIGRC7G%cHC2b6gSk2~Cb<5&d={c%!&^5#aI~0P#9B822>hWSwz46fSNFd? z#JX^FP-1)}=n8U;+EgwhL`bPEt8*E2*f2>VBq2sIN`3fAP0?j^q6L~vyu*RJrY2wz zIgd(?aWH0-^x*W0wprlI^5|(ojG!<&!v?Y`G0)P_Bsi=KnXUH*7Yz6?M+gD z#M_AjR)!63SH12#`zMzd%%G7??iYXsJi%*_$wgH5e8#gJ(d8yG^j*5S$^ATk``~8Y zImXW5M?~+UsVX|!Oa5Ob#xB!Nx&Bu_jD6-RtQ-hH>+^JN2voz^;q|~>BE*i}C_LAH zm7tnD`N6O@P@csk3f{W?_6JhmHdk5%lY5dMf_Pdc!k$~v($H`N&t!v3)x;T?xR6I_ zw51X+V7kW8|H*hqLTsV*XG&$_{5cf~-9xNGoMXbGrfM|MF74?4u?obVJ!k|4`k_$= zEnLjPHsQn;cj?;B3+uuP23W2L*goNdViUCn>cc02%sFdB8${ z*A5deIp>^f4!?*FnsOqTU6{cI`$-k5uIOMP<>V$h2xFc;8$m6{Y|ICT_j$OYqR$I}hnLi%wDkI6erfVIXskgsm>O03VcyM7#dg1h6* zSIpA^e|T2G^!~nm#b3*8BeCByj$&E$dtt8zYBAWC8wIicZryga6CvC=o<{?=|3+o0 zEw#m$JTM92L^(iq+iv4mVVoT(%LfXO$}bbGRy-TjR>L8?fQYaeiLeL4&)9I$J4jIAVsi*i0 zmd@x}L+osLxj7{!g8)z4 zSE*NWXB+gx$}E?GFZEjX3Q4ykgbZLY>;efs%@hB|BM33_6D!=7mVeUkG?y}aW(rHA zgiy{{#nBSZP@hv1rFI$^26MRLuEj(!W1Qwm_b;2;N;x=KH5!s+)EDHvE>mp%nxquX z2wpHux*!xR4od1`CZ0uyZt2ek} zPlU3A27bM}j*m9L7uf76+Y$H59O4UCQb9VzLdk@UDC@QcK!;Ax8O!N z{B7~&-BVU*y3*MR8!u5zxHV)hoq2hwZX+haAEZZd%774ecNs4T`^EOa=Z_yh+W3jr zn|y}gErTE%PRJk*YJ*%-1mZ zoraeC#QXdyKFlPDEVcOUCFD}>hgPKPFlj677veumEfGikL=>kJHq=oT_peNT*k%

ml(arl)>=FV5f>i8uB!hBgIaGzlT5D z2$n#yu5n&B2oz#IO!nsWCZA{6Z&0zU5=(ft!srn2+ztu4PQ-0*k=+y;WMsO;RAK_UYhiHaf17F?JHN zP5tkxH=c>FMEM5z<85h=qHHw7%zWtczwq7cjuK!yDdVyKg&q7A5e#R1h*O;ZT$iK-mEeCseWBZt_`y5_w{NJKTSeh05J zx_*Qxtc|47bfBU|Fy~r~7vz;1a{S$}SU&Y0gnvHJWEF9)M@j{X?1B&0lK{@5{o5o6 z*g9k#aEGNPj5r+UvMN}&Nnf7)EY{#6G&}Sz>m%yWYcT3{EZbEUVQE8e3B;1hPvqDJ zkH-ucev!k@aR)is&R=K-iJW;Id=PVON<#97M|t7Am~+$#S6c|#8k!*8acPh_LN1Sp z16&H&(2tHD3k8^v<-8A&xkIizl=I=5MEzVz2-?|Y>pnXckPB^sjEkXOTAd3}K8SCx zFmzUFJZ_H-JA0)E(@{Ai7)2$LP$ZLaa7H5P)pOz4DbG4uMVN0Q;Gtt8QdwwDZnMKl zVIpdxB90ofdjLR9JV=gnxSmLaD!5U@@xqF*T6Y`&6^*67#Q+(L_-p$L#L7FRFyC*;$6B=6YlBTm4&=C8pCdv<#-{bUa<^#U)Jj$RTWi%;7kp_H0DlI7B<-nM`A52p|tqFYVS~kJjoFNhHqfsrTvJCW!BQ`_c z*`%0R^)5*)Bn&QCL>P4n&RInE-P&i$%YUK4Wfv4?__Wi=6l=tU`QBk9;br?eUGvO1 zx+n_?pYf+w&opIQA`%GGw8Z*qyII>Rl64XR2QnSJ;+RkyCZ9G@bKRk)14k@^0O0jf0p{(`|qH0Q?7)*foqXq;YblQ_YT_1>OT=Fts( zK8IVcd5VH37D`fb50#%o?R&z}be6uy3Wv})I{M(g$5;-1L?xH`y5GD|B8f_l)t$YS z#Awn!cw@igsNPp1A+D#E;S7(UnLT~udomkXV_12K1--)dxwDL~vwZx+lk+t|OW{?e zD&B(c6Zr2bw4UPHmErS893Ge=fDkB;jeTE3qyV0zKB8H;x5aG=hpHzsc63n76U)qx z8)04BM^5wW9V&is$L9*If-IG+i^ySxa4Ve1v;*K{pRF%)UI4IzhA1nPKItn(KKr~c zT?@H_Swo!CYHl*|XrLFxB*MDl!3tL?X8r9%c?kIg9c5Q;N>=YJOv&_?SdM7syJ z|EN$y`iNCZLv_wWBChmF_|2$WJukz~#2qt-!V05ikcCD@GrE=xvpiobh$Yo&$Fu#l z;Q-3nzgBOag^h|!`)eO|4RExH{It5v3^4_}!J=$`S*jeK4+@;Lhk#{KhD5mGl9`XG4{6Fg|;`<`m<3^H02BQ80D zjyAaci%a0@To=u~Vz)nVrUqecEX3|5mAMyP4n>XAp}AQJsX_E838>;n$I(iP>VVS6R26iH zE8-;{YzJt;B{A6A?2|p#u>CBlF*{y(R&^@EF0p%C%oK0m&HO8+;9*YGFCE>8g1GZL z9{^Kl_e_PIV~AHHCy2}z^oN~dP)}w4R^x>?MqzP@VPFKGgy;!X*aQ&|(h8>$Po}(J z9WJuXlVX3t&QwGAKa#)Y_CBiuBY6XG$hKB#(P_JLBXY4YUri~b4i+E>H8Ut|GPwO2 zP{^W4&0+`QM9)6!{F`A{2-#P=SjT<_@OHt{jsg01miZ86f9xu3`b)d1ci(Y^2=bfS zhT|V*W%Rn3SEqPuMi5hA*vRy)gHzKeq(~9yCGzn68Y7pjVK^U_?4Jm6Qc-PengPYhESAAtSkq5NK))fk3gVaza6x zB4gQhz`$?*D6xYFaMlL`Y%* zF3?e(?Nmh;ws|y`vY`r}YRla}&ouK`cjCv(mL-Da%c(;EU@9;LH?!V_9?Fv!K87s= zkYZL`sX4F8BAzpHEac|RIKbl84q~P4Qb?_kc<9kX)`Z^YRrc4|hMdH`4g9iB+8_n$ zvR`wU*d)6~ydAR(n=fV7Z>ZAkwz^NMu89+LwOP_`85TWbw7qCfQsDe6ib6)dU#F>k zbSGX?bX8iLj_wJad+ZOG+ZvfHxqW|sG`-TJmRNP1;n4qrexu;k_v4L6^go<5-3i)4 z@=eSI7j3~U;9Fx};$FfF;F)QHAUE!E-%d|#ErXe8g)v2PxVGQ!u0caOjd?O%vJv2r zLHEGc_lPFKJ8F$#v5={eDU2?N64Vc3bx#C{&zDvkV0~3~Z^-qq2AF>is{mUg9n!{i zPa~67_AQ06@B9vKdVM=A_R?QloM!@fakkVX;52h8{tRf1rS>W!3!Wpg`)Z$4RiAv;&i1rNnZSvZ?DW-?N=~+2mniU8Z zy5&Zx>~?mlcX?-kTejB1$Z5a!?WN&$FtZMt|BB&~esHyPl`ihY`j3S)>ITtX9Zx35 zi2c0R3J}Fc~zve(IGxuANe8(^C!+4~LYG?{pY{fYX zw%IQxE+wF-U>=cZv0^Nv)m&TbUH0*@H5MYAPM~uQdc(36l7C-x#a1JokT|8DQ_w>i zjmW2iL4|ESGS0zKBeN=S!uyZh0tlY5;A$=9rMruvW#W93#Wzi0K14P(nWY$-XyE1+=#Sh( zVV`JoBwvDSx2C|-$%cSjvobUGZ`GJ>df7dR&dtbQR0OA)rP~p~s%QVVL=1YPO~M*k zUxfr&pTwCGALZwO!OV`W0l;A_Ry#|IvwFEiN+2DGwOROe_U~A3C8QS}FX7g(QK1rH zWtCxMy-(WRoKH2|Ki_3i{;tU>zzLcQ!9cUyG_mB;@A@EO{G%sUq=jBBjI6;XJA4kF zXf?kvv$XOAt9DLZIUhd(eZ2ZFYjptUst{Bp>UOlRuBh!6zrjF=5j~dqHOszl_>_0* zP#hU@Nsk2(DMien;seY)$F8zaP8O=x#;R$XKlEL#%MLs1$R5q?hghzwz9oYW?;%j! zr^?%GPTn=2>}tYdX#{nGwuNU#gd)n*)s!31+uYp(k!1Z4;9EgL-!V+Fsyc&P9 zZ*Uno()XpRsqGZaatdbD*Abhf+7@b7G3OUz5gKRkESp75pm&=?QTy-c%D9(}pXl-U z9U1Fc5MP_S#mr{xH%vA~dBH)Fi=6m)L06Aqh zfN9W#K6_vRFLypHz-uyc(d_)5y#REy=bwh``m)0@zcOw0QwEePlw)~3z7|TiL0)W! ze1_>pNxs~}X4Hm$yYt+%uTjKW8G3=_*p7rCN1F!C^p)V!#gutR#$$gqp5aj+lBc4b|B$rAy)e+&Xdsz zWu;SqKMnp~8BNiAsxdI$4rI*UkwCQS=pX@b$ZmeX7yBFu8N6j@2KZb0{cD6I7yF)p z)dta^w_wo7&uT2Z`yVn0DR(7x)M0s=ZS27%nE5u;@YZ(UNTNK|y4noV1HlCC)@N@9 z{9oQHepkKAzsJTo2>~4JNIe;vp)ldEo6TBz5;_$8iHKQ(02i zGS4G-ICbz8iVH1I&zr`I@?v#O81udpnwE6RNXS6tt**Wa?{2fSai0yYjGeNV~-RD*^E%+k&o=}>OsJ@O@EJM7#oZ~lXBh}X} zm<-IQ4}IUuXBypY3S*9B!Mb82UJg?Q`o+6JoUpirw1T4rm-n-c7YTx<3k=-@z1O=4 z3&fd&Ii@Cz(dU@TkculjoU4Bk%9KjqUTMeQ-bcOjnvl$fXW(~h)7BdxpJIr!i{~;W zo|p7EfPY8RnV(S1gRYpuKm@G4`d6$uJ^Hb6A32PTc!o(kbHX&nII1aR;hCM)OcdTf z7qTxzk0>9pjJJi2)bv5E40<@K0^SPU>KZbX*bor5tYeYAi3p2n5_!JwKH87xG2}vC z=#5js5(21`wkF!rc(OkE;T%S+8`uk@{9@abf{K@bwlFibtD;K7sJpzJjXc2w7QE+c zVilIhKve?mn_a)pOVR1w$cAncb1W=b>wc@>-gjXAhE|Q`ID?{p@!@*wFHarrF7DU| zae<)QnDxUFOcHb((O_lUtAWN(pp~~tc9jzEzYxI#b6=lRJ4T4_$FXl7#lcAs2oiu1 z3n+%?xopky0ywe9^Q`3P0~94WMI7&Dx#E%>TNN2-ZNi?qsy>AembZYcco{ zrHV&5QGbvtopH;4tM$h;wBBg>(`Xn_BJoA^AL9MoD+Nh33h29BBr4tWDsT# z;Rci8a1DNc%IUp&aX%9g_NVkFd4{$)LnMb0|Op{&+@5vRal$RINWg1&kjczjRKCXSP~yR)rV zrzPf!Ui2m3_?QqMVzhVi{Lg!Vx1icS6aEWCAihB));AS=Ll?j%lbqY1>~sAVE*@MS zVDSmxyp{*XSP(ANO(&-A2AjZ}!b|sP=rl;Dxp|S6h4bpBpW0UBeb5EX*w!!(7-O5d zplIHPwXzP_)Yr086-iW8wLpV^W-EEEh9aZw_970;Uc+JH`zMxm6jr{r0q|A2yEIo1 zC{4i*h2r?2-Z$KRyAANkVza!g(i%||AT9k59)Qy(#MCC-g0irzk`gcOp<@jq+NiHou+gHGWyQ3)>bk=c3Nn!I9^og58y&(^N&YjCLwMCSY<&|9W0B#THceVy z+=|11oS&nly+8+feCs3tuSHQTq2HUgb;JVZD2G}b0%|}S!RQ%~W%U3#=Pl7SYC%>D zIkNW&tV9TDt>`~&V(+BK)|oJqOKT^wmPJMh**`=d!Mrg8?f~+oNydLpnf# zAH#(n=j3cs!M-m{FV`fjhvR^F>Ur<1w3}V}K%(%&a(QF9pc)q=O9AThly-e*HRMr* zzZ$+kn!^+EF30OgWz;K8Oz(zKO6-%uC1fQ76?%8Im?@yiRe*pAUdFP6H3GU-! z6B8#Nmz(!zNJ$AfVFfq5MURZ^qvb}KQjs7GY3q0chFwMHkW}@=Mn{%-Hj}1Q<0&p;UGEV(D+j^Ox1(y1$h!e{LrA9TToYwtK+rB`p6_l8$aB`$c<$n~Dw7Aa* z|hewUg!O&rPk{kKsTb$};^;6x(7#^?4A;TW#b*fg{)F zCbe3G=lUc{d5>Djl&kP75UzuNh-ox}_g4V9IqVdyv;%!N60JT`+1G+b9IE0)O&_D$ zLh*_26Yd0I^T9+2m|SrEA1#1=W~3_0@UtCrkYv<>QSne^Eaz^Nn*0Wlcr9$n<}7xT zkxG(r+JqO8L~5B8=9Zm#L?m{`-(uG_w5P1*-hnf1NEeKI+Zv3Hpp;45X57(x!w#1v zmsrDETFag%d1G0fv{6dS{#sYpLCu35;bA)%;g|=>=gXd%@C4$GkWjahh0>p)4>xX@ z>5m5bn=hH*w^_kF!R6YioB12ApEXSk=--C03gv8;g7vW0_9t!75D|L!?8w~Yx!tG^ zz;D5_OD1LWHjWNhE2$`z71 z3mTD5^^3pa?__#AawzDg4gs0sf}wsBeo0nlSN;66{ET`AEGNF%Dct%tQ%G2aHZ|mt ziK!V!!1L1%wwaHScH@{GWlus%W*TCbaVklQdZs~ddbdE|ppSo)kAP|5El+umX!%~g zq!x^Z$ZC{ToR<1GlCRcy`FQz?C^HSNK2rN`Q6Vt^Aabap^NufO^&;dY7)#PH6|L`L z=_N&e-rhM++OOv8dromCVKCiuZz#dGyFlayHAWR>sR4F-Fu8;#b>!5XLT{vQg_)RD zw>hN2oNSES?TG`M1J`CXX9d)bL3VCsbF4`iBn7JFL!MJD=-bjwdOKs$CYau|(F#oE zH9M3zC8`Xer2tkqnKv0HQHE4A8dH!@_uchQ26G4g(g^1mRz_=z6 zWO1b&eEa^~3#QE@P;L2>Nv!!C!c`XQhglG(x%48&+)sj8&u!66>~Y!v0`BSK98ilD zKotnO2D14bYan$Olq%ofSa7rEIgAKW3jBnXdU$a95_FcmdGPAwK(2c?7uDhQxgrFf z5RQLGvJ1BUEIPM6m=3Xvq>y%Cn29#9X6@{0B=}A#RY}lwF3W-!0J%zvEP{=0BPH4Q zdbPTQkOosULtPMWDo|_4vM)FTi1vA??XTN{y3Pw)O&2>I{dz$n|EvKAIq&*@ z3v4woNYVZ^*R8|}WP$AM#rEy-s)g7nN_6D?)TLiQx_v$cOps@8sapHrkb|=u=*3_% z-O=8*6^KOUgXt@_ftQF(rVe#l(`F-BUs27Zs>oIS*;O{Qb6r#0YmaxpqG86~?YV4U z#F@hmPiH^g=h)tCAIgJvgk3q2&0^I!hZ`!S;TRJr0)ZY3Nw0UgqZeh)eCIVs;esv` z5TkSb5k4JwzA?nU{@Pb}FtkiRG0O{|zFqZmxfR|-Ug(W$YSu{JEj71p&5Z1mSz3LmssxJ-54$Z9%lO8>yD(+juPte{7uk_WKc4S*AMAt$GKT6rLCs!}~$~)0>^_ z=oC|Se7sR&%BS7(hqunnZwxyq)l1LH+Zk4oh4y&EIxxO`iQ>iwg=Mli;gS0)5<`q0 z<9{xR<|ZV>#19yqNDL3+MaBaEX5uNl_}G{P?xzIB%$n@QK)EzCsBC5JoyP-OTH0`I zp7KLVqH$-K8NmL`Fcv~%kIrT!_?4Om6iJ8zLyr@zxXdmNIBVC%SIq1tVvs> zu{O5R0z}dF2fH94uDlBNqfrso0~2;*plLaT>mEFob7u(S3lJzMq#6pZ$If3_@64hL z$j7XCf@*}CqXVG-dhr9fv5%lu?aPr2PH_;3+|cf>0k;sa(Cwe^C7BP1w>fTM1_Urc zx2CUKWX<#-XS#oYn{TPoo!;OJs(i!MkBI|t!<|!pI$g+MO6<6N?G)^&(H+Q-^Z9?~9~B3ZqWv|`UdRtE{~obj_`m#se+T+$AEnHbOnB5UzdRCp!)pRo zMhgb1KhD3~$ME=ktGsj)p@>(03^WA4Yx2wmC*__B^iGBB5WXr&!(*Jjyi0y&lC&M0 zXlF+4CO(Xhx5~Ap6D#ihd^TT_yEr;L4a?W<{0X$HnwVOQlqfH*9vz<3%3|9+oWC{k z%k2_xm4IY$N7~w(bmgw@UD2Qc$?0@cKT2(52@s( zZln`eh!Z>icOXX1RKAI@qK6z8sLoLQ|3t*7vL)U$#GyMGQJcMn9tsBJh4RAcgQY9$ zLU#TgJ$lw5_<_;1v)iKO6gO}}2i`^HA_|H@QlbHg6%vxtU?yC-sAj47X{k~rV zLqri6xMsX2@ks{$S0?^#VEM7!qc)AcKNOu7@2%}snA55T0u$xI%ejgoKqM$!v-suH zqS93+IaDawDt3R$i%?#+5K6_96F>;h>4>;Va@w@y{;w@c{F%1=4rQ*d+`Vmn=e5bw zh~pCFuU7nu!5@`XS87Yk9c=|qI0}O~RZ+9$Y3DON$STN8PpezZ-FtYul%7)Z{xKu7 z5HBkQ6obr{xE-%>`SA~8mEdLaFK>2!+4#vqC4DBsN+fOzq6H+kn4cwuSzI)FyG6QR zwsDXUcaI#G>H(&xkFS3E+f-OG<#u;zx!C%$D*Hn{TQ=;~R3^qHvsM&dd(6MLy|T1h zDeo7YECj9$#(7suB90~hR`f7y9tbi4y5pxqTWT za*p~0wk?_3sB9#~uldMjn~~ba^4N>tJEk4chogWbm3*PU{y_?viBVO^3__qHUD z4FbHLEqq+#Xm-6lV0f3>DMUDAMB|9B9CSO1#=*+_Zv4CNSo0m@?1p>S&_?%ckXR2e zYjau}tz^z`S8#I|X;szWjvP8j0WKf)H9<%K4Lwfnhk zxvw3xGc!-^l{^3CP_i{LmB<^l@uqLj!#sr%q2`@ZP?GedqzAHXDE5Q*N0!bcg@J4WN*6YGp}JY5x|w*tSI|hto)u+Y9 zHWu*=+D^&(oFJ@8(PMnk#`^@L_&sK8erO~ znP;B+e2w?nlPxHLdH=p$XuQ`+xw%VU4-+Vr(g%|o zuC(;G6Y4IglilopDR}dOKX-%qGZZ|Qy2|PbONwieu{bo}hzHpv%2S-bk&JU)`JH){ zmiJpq>aMZ`wU9zPJC1ID&*uvx;W1$+ieHCafgf?O^D4C>U);Z^=S-oLWKe(QU$U5R z$o=PSJ|-j*lMz*;K|q6(F6&*^_?GfQhtVo$D6JSgMs>Zj$EpN8}jnd*6^^J4O3m)-BpzetC!mrm7j z#=d>*YUlp^Iszwz5JbpO*EhWp&0&IF^1@zG;1g=jMUOo1ohO)mHs9k|wnHE$Y}>wnaH69V2z#3eMCV9ESKjQgik z&7ep|VpZbE@cN^(Mdg8d{x9b@%G|$5F#HPB{C3P8ic6y?=_FRM|JTPIjc7{9X%XFW zp@C`ohue7LrEDw6I4DSQPWnHKgL9TOzIF^)uDXKlQ|tN7y{zu4FWzYwQ-8Y^3~*bP z6y5i5Ltp=wTWsQJe`?SBji7YvP6&f8>&yhD@(KD$Mp<6q0yE8d>PqW{?zT1C3x$s& zX4bnb6sV&B(Sw>!&}VxaoET$xj_d1yE9g0)^~=_F8oa8!R6h#gU7Y|kGQC?C`A zjvtd}=1(|nd7+mo-3?(veuo>q<&Uzj4R48c~!mYqA)`Ijl(`a6J}ktHdaQD7DIdyR#K!O3j&yTIxp z+hWmbHJ#?u1@(Sg{S%49-ko@3G(Oj6uZw;MT-?-}>i^_*+uhe^i|6C(jZK*-ue)WW zz1EiY)oJIK<+2{hM|h>ENrw0pxc0*L&$nk+g#W#f;=X-g zbr$B?>h|0u9lMz8o0R5;t{#$z;zPG9_8AFuYwCCUzEOGQ{4&XSeNUjwZRjZTME@~C zUApy8(1~cG^x!t_8Dum+&CBzsSogy$!OCWmV0WvevY{9_E}*X1hq9}-qH?~69x8t} zIF-3+^0uUKb3*ruHrv+?6fBH{2z*A56O5~ZaW7T!`~K4fY*CR^)@=05>pAY66&jwT)MrR(MzVtC@-rY4I*I$RbQ}GKK09**0PRCEqgqZy*`{ zY%6VrLCdHmo@A|&ssu90Px{$+NfVz}i@NwNt?nMP^J4|=>PG2^4Em$&VV+v)zELic zt_cJqymY`SETHM1b;H)G31mip(<&6`Q;u|vv1``{Nb>}tYC#U}v%pLd*HqSZHSEdG z-`m|*UMF?Y$7p7^CGKv=b|Rs-JcnfR-#+E|R!^w1pBd*(`%9JFe7aONJN5I9y=Q`j zXDOqf@*|wz7w4F7gF03Az2B76)ZR{?5asTa%4W)!Zf{A;| zAxZH=L`Wrpl2=loF1w``yk|c?kgaq5AwNe{bZLxgIU@h^`BVhBU~(82gvPm{zu(S` z4u6%gqLNs~A<$4)GWRH{>ayF~TK|MYi&^TjuzCCf(1Wo<#=pi^SriGRdz4JGwV8yH z2!S#XLq7{bCPBBmZ!f|P8T{z?E4oPL9knmP(sC%M(m|m@SDvmJQf`xI5l)ncS=Xhi zugip|yJYf8C73*C7+5Lkyn0fvU0@nGR;`&Tr8~jGMX*`0a82MnS(yGrD5VNaD)fw4 z(Z$3j&W9rnqgyJB&dS#b-}*DA`1vWaEQ;^CnQB=H=8CVP-}0&`t0HrgU?6zpn1!YBf&^V$X{YYTAl- zZK}Z=eGeHd>j@s)kQrV5^#L#Jt%w2L1(LFqO20^3^Th!+X?m(f*?QJef`Ha>Yktf_$Be}FT z#54JP!voB-xgWke?+WZdhE!Jb26o02ue{Wt5c+Ex_Z;$b<5{AO~IWy>Cpi zz3|CUVV5fVEAX9N+`@Y|glDfPUkW+W*zcgY{#ArhSbwj8PGv={ROXs)uUF)mWmQ^Z z*8fMY?)Y^XM|1pIbh2<^kS`CAXWAL41I;WHt<;m&tue#(X6^xQpz9d2M+Ur0V-F`^ z8mNm!XBo(LR58(Vk=9ywF6lGhwTMvLcjZjVo2Q zPc*5m{thi;Xljfn{UW+)RVh{G+q%VHB1aHL6sUkgsbopmKr1GG6P9@6ITu}0m2S>2 zG_mfB8#gl08^0=zJ%2gd+{6@%zkK+!z9~IRlCH>>ilRq`=~RQuMj0*-dC;a6X-Q_L zs4ph+y}llk-CPUtq~@<9Elw?sm#CE!67fCR@mcJT3c<|obru1p#3zAf-{d_^jP({z&^96Uw}<*Z0llDl_r{ zmE8DMg7rKfd9Ly~%`LX_|D^hz34tT=nT677qlW9RZY$LyOIFqpfi0E>@P9$z(mv$d z5z#j9W{T?5r(YBqebx)ePv?p@;Ofp9)lSx2(+W(>)qmU%lF>w7J^>`}Es>RXV`_-! zo7;FD7-!pcsVjeI*A73kb=_B3jxE3HZ|i2JZ__Ze>zzq-g2>#6jUFBuF&yPMi#!x> z5v?-U-v4G(p{IWct@qDqLzTeX&I~Woz`jQkqK@CqGOtl|o*QM<>=Hz|e%mTicI!hS zzA}{@)vwiy9lXPSqa{|JGE5WKP2Ts7+0!{)b zs8!+wtpjkORRLQiwzl$1zkmJyzMuQv^LfX)=RD_qo`cYKEE(35(%yVRJkQU(UPPO< zlW&+Rnu4uYngs9saCpXk&7aRQjM^=>3zI}*Eg?cvh`dZ{EPcyN{(ICweJC$a&)eIS zX?q6wWrQwx^=0G{mhxg|gsZRcDlI9BJMgaKlIURGmIu*SLVY@UZ~q*C{xLrh6dD|u z5Er^5932zO+X$BY%=L*fiSrG4hI{Jm85_#th0))~azmY4lZsyRtb&!fGV!gg6_Gqz zXi|J#yz_-i^|V?;3VDCXBx^dV}=r#KZ;upl4is zpdiAIAM5ea+aM&G+a4qudDd^n4c{2fTN4uBFgzYp%H+jv{wp+2H>cEUFfk&e+bYnt z&#FqV+60vL4|F64Q&*3L6of|XS~Sk9w95;P`?o(LYQ2G2ni}d86uc%OBsgfWV&7~f zfM)frA(5Bp&ph}SYGZWsjd@|Y!g$@&hx2cf&E_lQPhQ8Zj*PoB`f&90+JwNS{^}@n z{qruv;HZYjODb@fzV6w^-`9k2xK+M{D3jJE9GaGhUlD5H@@J>(D= zS6`JH$~H9n`RXVJV-evJ&$AAGN5Y;8Nm@~f>1!c<_xX@>+)l|yACZlo{~!0)JPwlF zaFM^P4_s5rD%8;_JW!?U^Ig*EOvHoeQ0x3--^KIjPWGC8+wzY8Ysib6y0#QEgH-Q@ zTQ>X?ed+a=w<-GrgRiy3KN2#os?trKOuC;KbPso!Rz`+!&vMfb28V@xi5-9b;@_}8 zcrl?zrl$PcPFn`YIXGj!gx&u+u;glR_*Qy$R`}8-&!3iy0ydfSIKd630(*_ ztWVPPdRVgW?!vi=OmlopZhgXIwzs_YDk*wotBj!R8IM>Dv!1EMZEC9s?&!UgT?A$q zpWR#?^5-lwsB-%=9>ZHwm}J)b?hL)AM`Bsl=wfF@sfcCod_F)n@taRUFr! zwEbA(7B4Zb(^zHXTb=l>Kx6Q?A{ACkH)Y0GQ<}$porY)oMzVK=yWkUXYNhmFP03-x zSk^x--;?$s+=b+^BcBY0JkCn>!h^Q}^n9^{S>%qa&KJl>m06VUo6=fFiu82xo{ckC zghe#J)q-$`Ei_$x*y>c4=~?^6EHk971I_h{GYb1IQ#Yq2S{E<)Dd5)b?d!g;Ia9eV z?n7}$RyI!;zivh7*$7=c-!tM+FwV7dZ(?A#x^GX}-XU>8k%gjJxjO0>*VM8IsdGAz zlTq1Tz7`8Ec4X((vLyNypT*9jKa64j+$vPYkg~c8&sOJ78S5MKRz)xDs11HmRD?*n z{nc<|=8EUsyQJh7&r1V4y7pMPCDaR z^Fi;^I?Jjsg50eylCN$suTJ&DRi!%1$x=~=sx#mo&Ie-JpW|iu1%w$?z*L?}tyZL84e#c$Q=RHMzYMFmkcgtm8btfUpg`9M3)FdU`#U(s-_vJkX zMJ3tAMe7dk2rY4?CnSqB>(`fO9%>eEDU=xa9k$P19oe2cP?7KBFr8dP8w;L6=7|dS zhwE*}rqYG0UU(jTIBKP%$oNI)_?er&JLR{F9)+(9C`N{TG4*S>bLJ!XS6F;Mjkv~z2?c4s2`|{MZq;OaKT7bDH;O1E<(5L^GPt|!_bnz}Rp9VoK zQc{svzAiptfV0>6gyV@wazbc=ZT^FE1#TSRGSa+~UkD7Nb zKW|<)Z6@&?38)*MGb2@Cy|DjPP>YPMUx7yu1RK3I5%eb^CMY#{&Y61X?95Bs1Xk*G zy_E6-=Vwd7_j$3aSfc^J%3Nc#aT0EoU*K?+CHktzI6VNcGQwP2-ScZO0gAod)7zUc zmK$RQh4Bv9k%o{FfpM!YIIlEZ^VvjP@Vmc(C?*Y$$gox9?x4E`B~KalQLi)@W61}n zYJ`9pof!`L3{g@Mou|?~++FZxS;f0ZK@qpk1_u%z#%zk}Fm?c(V#-<@c4TDgdOIW; z?mEOXKqBrTIw?2Sa#Nimn&Q6C`h7^1=xG>Y5tA!glU)>N`vz})kB$vLQ)9o6tNTHb z;7`|T%RvsqY%@9rxfxlZCH0hV9Cf^g`=`0g+p|Q!%<%r?iZ?FqNSBjGLKj`4tmP*9 z`kYZ8-vAWOZBZZ*&N7O&6qGcB1v?Ihf0uaG`hCypnANKTm{f&s>htjABKwf<8#W70Wt9{F zeNBnt*XOQqyLaj&ObKvxX3VNdMoGR_fYAA1!mveA3MmNPpDdkYW7Q z1r_50o>X8`SlbW*pgEN0wHS;i?uxe_!^f5oo+D9R?hhF+?mWQ9%@=KAr=F_zghVA9 zelSYjEyRan^ZXK{qb=;u-`~p3EX?2Km|hy<(|G=xz0f5p?M49WaR6SJrw-d8WF7l~ zh4i;%J?vlj3uL|DB?1PqF6yu-&cQb254>9;WCeD|@3hlL zl~Za?TVvwGVge(L9V{ z(CLyjpO3F<>wS4KQpb9ZqJWe?{FGIp0h9Xb=_A7>W})( zr);i_B)AWHd3d?S#n_*J!oE4=7Fo{bj5Yo@pAr8HI1&!fe0vJeec?Kg6)i3U`KuQ4b0)P$(+m^p+@LPyk zKsJyEWEvC#Vj!O>8`%1R7+p-1L=%gEd_fr?x;*{$8Q|%dXDV`aUSA9p(u%e&eErHS zR%QdmIt4_r{ucbxt>e#1qUq8SqKHq+ApZ7ryY}TwgAy`6jdNL0HD%}Wbv2%t2jus< zK##Y72s@f}IRMzANDRUaW?Xc=QPP{R(GWc8zM#`(6K6pjF8~C-;=&3Lk&_xwMOZQ1 z0dpaK==!aIPwF~NacZOp^8f6NOX9A@br>Gf6D~S#F>uYq<70B~(pxY_O`WEy@{I8G zE(L&?^K;z`4TsLI^#V*#l-Yy?leO4zoR7}P_VcRanLPve7MI^um3HTXN3nW++ZqPL zeby}}8qrU!`iR9oU4KLZNUmExknUXvT2QTx>)!qScQuAiaY^@H5prpQ9qyTyS`+NLQ1R3bd!kv2 z2Lm$#l4eiT)3+!C;7y6PMHFe%cc_Uig; zgQ;MOG2O8CcYTUmj5w|H!p}?~i}k<;8~g`P>##gMb$=VD+FShLjf3#}0NomN;Ju1K zy<@f8K(8ZL8Encm(cRU_{Mrh$z zdOaf6DcB%Tcl4L+aih?O4!CbcH9LITJP#O=|ec@D+^ik4&?^y+GT&((^rHZjJ-_@&HC?d zrw3b4;U+=H?=xS4-m%#`S!jxMJ8kV#-+b3_+}GGADU{pgYi#FpG*n0E#T>;4W zY>5%3`iCIcmvT+d+{nWR?+|6_f$K;pwlQk1NDrVG`MMbzR@}kd?Xs#kIrWEd$LrqOfQD-f2(JRZmOGk7o<-m-JI)9bN=%OWVs(r_%!|dI3`GhyzwA&8`Lt-6D`LgIvoGl8}L*O|?uM z{N*;Tk-i(8y_@Sm;&sZE*CYgeZdF75a6K|&XQc#%x}_KT6SN17Jkw!LY6j}xWESc; z=OUwMqiYV7@{O`dp&4nF<@LD^`P5K?%^A>4?@<%VB-4D)Q_?b!6L=hTr z7z$u8*_o?=(M)hPVj9F^8ysJ4{b_`B%>1EA*ul5OI()m-vOAO8eiZ5HLmPEy1O1*pUIrH;9Y^V^fRK99S0_>}ejw-<%fkYL=CG^YC)YN_ zBNK3X%~q)|{@xjMjGnwYYh9;F9C%#E1P^iOWvT|!x@mCjdQ^4L!l?ijPJyZmJtJ5Z z6W}DV=3c|qAr?UHk3i`8FyvpsFZY_EkhPF4)QlSmT5*D|WEoxy*lZqMQM_JTj7Iq^ zA{(;}V(B>!S1RS@-0%0IvQe0bb76;(0k@`oENz=tnWiBt4(a@v8e^pJbc?EU*g;T6 zrH`caV$mU4o3?5lv=B1MXfn+GZX|fG%mJkH-4BCT31{qBC=Z!|RkPJbKiioO>Md&* zuhy;=gkKSb!<*v=@W#d+*U```a2H4b(akgA+O9JrO^-2|U$Nj$^qtD*$AecR>Y*r; z04PJY2$jcp8G8aS38MfHoM6Lg_w0%K*xGU+uKA9QFDW(NkfsGZi}g@m-p!fP5`wOm zmk#14_v)U=!zSVDK8}0gz|DCyxqp7@*Bpm@BkVGN zU*39weC2Qj&oj<4EYyI#A~+}DOGcrV?r^>C#F&xyR=~9`1EfeitE(1D3yqg@S{q8M zNSSU8_#EfG_@Nn>y3g>_)BAU+1*LmZab7eV@F zsds>z9!&ih(iMaqN5=%mV+^xFBR4Fj4tqTinhE)*4uMFBT{Co~!SWCnwv@&gpRY$9 z!4b+||nT5JWa&Inxj6&CRIuU|Vz5#N_wEa*;@Jc+sXnO{5Rzf$ct%*l% z9^NuZ>S(Ps7ORn+(JtG)0YrN}ps&uz(ob9x+JM|MOoosi$yR0+ zCyFR87ah^(5X12aZh=L0%u_}?8a{ui({{$(XK~OSnzG&{zHe)5$Ms%P1zLi zd_q;eP~z(O1~1>j5^K8)F9Dyi!y@y}Gr_{V~h20a5-4#MNj~V!OSNYmW<4RBxq^ zy+g-b8G*hB!_yu(5cL10ljS*`tUpUa*m@`3Q;{d-E_Z-#mKVzRUBJ=vwR=pSSKj%N z<;AYtT~V;d^Vl`F45F{suDTy5f6*}`v3C)^k8-w~DJdvMcp19iukj&5yH23JplZn+ zDi5dk=*+R((EgX67x7ahs3{fH3r)IM3H)$3U5|l7yy?IV>X=dVtPv_B%dNP)I-E)r zECJ{S=767jys#tup!wS)SA`B!$0LExZ4_NI0~I=rZTk}Kp|RCoi%E^?%s3*nLT>ex z=<>(IwittS6mr^Tb_Z4y7Z(8L-u1Gf1_mJZnZ)CcoZf3?S9!YuydI#}VKj=bMVlmT zsIxRQ+%mem0xy0aky{&wCfdMf)KlKqa-?(CaAI(R%|{9ilT)fobIUkB&k_ z`f0Zg6&lwCPy)uyodC#!AB8UB#{|@G*770XExHHYaR|S+_y7l|{nVf`>U_!>7j(dp z%KXe>68Vb8xdv12N9JcDqx9PXyo6?*K`%TlFMS4&=n~8kuGK4IFO2I}OYr!#WRibh z#ePsnPPB@a;L6HL`pByw>rw#NIm|l_l19{>M$H7nU#(|;GrVT1Rj1dIA#62g3@I;F z(1xU<+#+Qm$_5i`;7D>podoL+RdNs|@jEM@BbESZvge5_fpF;a3YF@WyCxOeS;_xm zXBsX$rFE$F6H@(`d1&YBQ$3VjsyL6Sak&+ZRqGDB3`I$jN+dmpvJL&KgZhVz?OFaM&ouc{f@p7KY(_cnDd+@^0^1@>jHHv zE|u4vmm9J36`YFwp6m1iH@zR+c~zM4Wu3lD_OI))mXmka-0E=HqLawzqavnDpmh1b zpRA9D6Qn{U%Gs}XrJLEHeX2pBSh7}UtC26u(#V*au-l*#Lewr#$3U3NB*H4<#VN_|*>*HtHwnZ!j3qRD~3xbgE0NO~tG{!CEpX?RK3#$J5KU z_vN1|u_JaJB$u(qwg(H-16?)$*x}67*lLmkVC`jB(v9#VrW@$eTW2c8 z#?xH}`NDu5p+|lRKKi(Ilg#d_v0ze{o?w465^q%PU{I_YUKF5D>{;!A6b6%M5kN5N zq(T73s;$9Z)lVKTWe+c*$~|-)F+mbu7J}u*T?_Q0Dn!OwMca)fUZRAcs_Lq* z1`pF?P_==NWs)vWiP@h;TaMD7&<`r&s+$4(g~mC!fN66d^o7$C!G()th3SCai^mC8lVt8gU|7feZzJU zSWLaCw6nVQxrM1o^cP4tEZM4x5EY0ENk-pC6m761+gvf<U-vPen$-rgfXCq3qjSycgPey>#9G0yC4DRLW-^j^QkTLlc! zc4m=gYoKt?W&mB~^Bl8>K=7;j)!=clN&2p#N&qnY;2DuU3jb^1VpG$vGyJcSlSf47 zzo!3^nU?>Sqk-%T0_du$&vL_|a{Jgl?|RDv=z{?b7j{&}Pi7IcQ1ggh{F#u z30;7TIWEJc@zLI`<>-)18$-8d1X4fLHtmjZ)l-%kHZeEU9vt;_hUhr89HEH0x?de+ zn_;EOPQ|EL7d`-m?+AA;Aj<{o%E29bpe$tHwnrIwgYPpi+cR>B=t!6EGYhu0?$0*I zq83n#=$y25)RR2;qrTfl--yggTZvS>`X}L`WZD}0S!27=M5JL7mbtv`>+%q| zdDqV%zw#6qUevDDaO(iqln?_mc7P`rp2*H>J6?jD%4$JTsT`y*{L^Z{*UvtDTV31+ zMid@IC-N&!D3smO-2Qo-Mi&6}!37f0b?|8$8m1v(28}SEZS_uM4%7i41e;Y__L%`q zI6=|g4GIn0KceIi7__N@4W9y_0|&O+v6cXs#!Mc*@PQK~ijFKfB<5nD7!^;li2w!S z5joQ(IDnvkC~NC5yxpOpbu`5r7RiUn0+XZ34hvjP|P_ z0XkbkAp_vWAv79ecWRl(m^t9r#|GHi8P!PtNt7|gyTewO9R@=;H7XzFc|U#%fL&lO zx)c13{WIq*_*ERTX=kF8EZH+)k;JBB#3W$O@I9$o1q^7w2LS(jJt~cFZ~qO8-(5uO z{{Z53m+(40H*PbvR$XSz9bj^J+MYvKBZ%`0tNcjlX$84GN1E${`Pp+5w+mT2{G zWIQwgP9!I_qNYSJO^hNEIaA&0#{*SwavOg-%E@V9e*?g!tgRW|;7{Ex0IGL%e%~$d zPw+1;e|4!`a$P0KZ9dCGW9gm`Rh-8F$NS%ZPtQAT#}ivX*ytSkJgBQ5tpoecJ#h-V zeS1!87?blTPdvdBsC9S%_y&CMt4VENeg^PqOqU9k_A^0IcGk)g)hdn`#aIF1bU&r?Y&#l_vKtqkRCdU!%D>1~9>2ma$cz zso=5+AP%nDbzzQ%5v9oqiMJG|rEC%Z&WeA&fY+~2Ap{x#K`~S<&Z(k{(P_0kXeEIl zLgJb4OuoxoSVoD_irU%z?+zXaBQGa6t-u%>sgSP{`S$O6ZMKP3B3r3hj!3K>jrxZg_0`|R8H^B&y zwX-%#hNarxqfJ|N=Q+NicR*vi8(3JTqXsmrvN9+yFOT+(Lc0J_e3>$Y*a}cv91a4< zVSj+R;oh4*9MHSK@Lb6n`Ig8ZB08;HU*65ns?$<6XCInK{gMmcsj>cja+*$*xF#Hr@sD#LddASnG6Uxen2mVfK zG|VR6T&gCN-T=T=O-F7Z=U`g*fWlBx2{6=Lq*ZP?!yQ;StvZKLa(K*FVZXeUPGe{_ zUs98p{KRcX`rG`_QW~4_@Zq1{ZBtWAFJ>zKfWu@50nE*%8nAQ}0Qb{gDwa?E0f>S# zwHk({iQBs)qod^@2|Vys$6|7F{u}#eknZ+C>vnQ~4xvhWy4L{0iE|jKcIjj+>ie@< zz<43RCveRM6WR0pn3@y18?_EXY;tNVJ&_p(h};P&t76KCk^}RiHbs*u4{AZULePHQ z3zlQ-zzpxu&1<);#Cq;NOdh&dCk*RFu;(t#h)29Zs%0l=;riOz`!_UMSU92moQ8X# zXqrene0W-G46~14is@wm3qin7acMJLa2j+3A}^>?)pkw*2tGlCv59amQN9s7#a%sm zAsv+%ERGJ!+`(p#($Eyd5+)#Bt}LLUzN{(jWH6zNT7A3TEaYpTn~XANUyPi({Qzxj zd#J#JS~_2My=CPz7N*^Pzy`>YxA-8@+<~o2L@)|y(%QlCDNokbOad5mMG1?+oB`OS zq=$ZDC=$>-1WsHzb`!K^mO`wDZaqziqrU?Ke?NSYKCTq+<0E}my_E4Lv($O;%BD%g z0szf(?k`sT&Jk9p^oMV57cuQlu~0o23#W;Hhk!9__ASsM@FkMF@jo}yj}}Upd{Hw1 zo)wp3nLJ&&Kn<@8z-qHTZt2%Sc1xoCOG;SfkbjT|D^?|Yb8=ebS$o+pRRM>*mk1Q|R?+_B^Rf9F#>6=ZovHo4^UGHS0(-dk zn|_WRwMhd>^(rYAn&>INQlZmaH`6Em=&DU*ooAIlq$HQKho2W0oB4mWPF2+L~>&1s7) zApRTWcXo@ue|E^U;#4rTjeq$b7r-f*(rJ-s`)eunpYY6xxcA^FeS28L5e0~j(i zFdTX(Q4^uN00ZV1QLdl2g-Zao){(4xRk@!-ZNjYtNL``xTDQjQeX7-OMp&4lk*4s| z&-132P0&R2I3|f%s>esuY?j~a?EgW*PpkvNG7q8#U>IO9eAXOVCUeNi_PYYq<4rn2 zE_by5cT3QpdrKP{{BPqa=YZVP3<1Dlp2HNZ69Q9KmR4dtLGOOp3S$YUU?f04JpPkW_?gSMnMb4ds4ViJELLh=4FJvy#t6uBkj=+ z2ujRG4vMRLAP77x7+?pbj_8WY%gcGyZ|w$%Oewgq*XPC-K9@XgI$N2l1T6$R9ja>t zQ%H6G$m9|N{^kb47Wiajy(zm1(~oA$Kq7p$E9H*yn_7f7|@NbNN(Vr z1Ewl^R_`B})`5>@_9jiE(tvTI@k+y%xpB9whUW1;?epPc9Vs{{itkJ8M3ND(20xr& zHH~SPf-9d*Xu2_sB9n2nQq3FqLN_mGF0{9s?g~_khZI_sYj9eCz!7#Mbb^;8cQB%{ONurPEV)$^2;(WbU|ILwF#_*j5qYL?lr&?+ZtctFLf zas*j)CE4=36fqn576|%zsh6)yOr)qW7~XK|+!bgVRSYakd@v^kY#6>uCDUOhd?|*K z!$FLpqt>h`wu=p(Ta$={*9?F9_a?R}DhkFZNP~AbFxvo1S@N!SK9bW8#qRh8Sf0`` zUinf4kGpn+e(Bo`^m6Z?ts0(S^MM7+)KN(bvlI|`v5!CkBFrp3KU>aLB7J}#KlJKj z(D89`ATkb$zj}4}HH?mrS4=<}FL^w6iWyx!oUA}=U$`AYB``%O1En&o8}teQDMYngkfM{MOGEhaL7p7H=-dFfUVJ?bFHKz z=&XDM?g5l!!l#z2{i0}cPT7btQzoZ4<#A`QElk?4D0I?Jpq=LQ#GpcUl+EOurV%ic z$h6C>CzqcI+b19xjVbiFZoMGG!a7<$Hq1ncSS*!63TGiibtXFO+cJ0XCuy1tdm4~h zzbE3z||rlW^YGAF=QJ5SpeP>A?R(!Tcj)u^qy|Sv(;$I8Q-}BLVzZKY4~CMFjK9h zBLfSVM8!{t8K?~*E$cQ+X%0M=Ri>0d(JS-jRe%Uy9v9;K@TCykR9V%$VTeo3>d&1j z0>Bz2%r;2;N#@;-hOz09E}CVDh&9$iX24ZdRqX*+0~GK985$yd>dPl=M~Jy-hvp({ zIS*!llej^1_!|T>PxWEB^K#Rgc*KH22a$wp*T{&T&%wqCsC|b#KY$_7@9z2K$G`=o zd|D2(ZdXbz$dG8@(oL1lOlje4$p!$2}(L8(8Ee}BCpQ&s>sLbOFO)e_x{!rjtYS z3(~*PaY`SwJV&68A6u2;)y&G`2uW2Jy4{L zDQKxR=Vk-~gxza-k+myDJ&ve&4U7!Y(36P;J0E!fin-j_!R=D=&=B7nsndm_4IpXN z!AmZJWMKSTa}X77qD)V}|N8YLzEtlSOzr?ptw-4gX2Z*llDQ|^@wE>*$BitmC>fZQ zz&p__K!nSdY;<_9p8$;D)K+~BG>)lNEtY?4LQM2!x3C3fW9k``13Juh3fjBD#C-_U z4Idw&VmKJy%+L#4C#9XmFCfj~I(TWQT^p8ZC|2XzS=EMSPd`D>GXb(W8<)iU#*q+3 z0k6>v+HkeXxB!M^r$)RsA~A@jzMxd>QupkA{5BbDLMf%olO?=qieVaI!vIAI3qDqL zlj+CM_BX-If~k;+a|@7-y9WAinvw^|*olQx$D5}rfcBxL{40U!g0W|iwPCAY7l4_k zEpHiqmN`v9h=K9lx&KQzXz1U5HU$-M?D6hf80Orp`3Ougbr|ls3wCsqeCAe&{>wwU zpG*u|4`HL3;HdWrlCqo6oLiAmJ&r-~XSnP2=DRd zi+QO-6##?G!fu?W(A4}Vqb*f)&w_5iw5z5SRCq~?CfGD%X!gL9zTIVtb{HDA4!76v zRz&q2FeS)rS3Cthg3fBKjx0mH<_IvH-ULYjQb`jpPwM+(rD88Y_!YmA4Kvb{C2A&{ zws7?J#`Vu=h-IXwFS|;K&@NMYcnE%(R!SAhVrpk%hB_yG#aoRm6J+xH`&IeK?bSuRc1b{H{nngP?= zCtYVk?0UiO#J*`_&rHD)XPCm#Hk?S`lIA8J_pX?^q{|>+Y11l0RUB~~V|bC!;@_m? z>tIU5cwfIRt^XZdt4JMp46-nBX!AcgHZ$QXZMglvOyld<<;Pq5s${7Edklj6xb>i{ zcQ=q!y?-kPW)dh-mHV}Fb}+?(z-M99#P&s5?)e46^pJY$Z!jcf(dj_Y-t8|7T1*^! zwXs~w|3+MZwxuR_T-mm5oDl+8-X&FsNxUd@+W0*~bTD zU13kRwfhW^3g96QZ?d*F4aQF&tPPljMHYlp;h1mTxMI}2Ka+-4PO%>K5yeLUHmoSV z8;dQqc=;rwP6;tNzt^R%;9>=kHL83okHcrcoA!>%U=$biY5DkVICTh@ zmnQ|QEBAnrAtH3az{&gmWqc}EA2uW0&MzZzU^I>^a%by?P}6N{c{NW>#BIBTw~QKW8T=!L(j%w_T8Z zyOh8_!cyro(J4Mt{x#k$+EHm~r7UJH&wj~t0NDR6I3Rtf;dP-_ld0#|yk{B z-sJ9d)eEqVQZQ?Fpy)s6z%!YxW=v#}FKa|}xP4A3$aEIIxQ2I&W|XgelqHc>>I;%0bG>Zgp+Q1h0~joTH|r>KYI z(-_ssTZB1~ivSDFr7UNnz2#o;K2znWKKUt zA085pCj}gh^_=%N?*<=EP7hiOXQq^mvOrq`YZ_3bfoysE^6So-=p=dR!VA5zV1)Z(ZzGaLfuDzYj!q}s|GVdpQW6DQag`d@+(P7?`ibl-QBZ#;HKlcL+6 zRJFAfp_oe2n;6D)Hs&^YdtCq+kh{zYesU4ZeP2ArPx^?K-TDr{+)tf}~AJ zRkCIFMA#-Oa=?3hN>Xk&0G>VLFV`%~Qj#`+4pw$3drMo8L9+&JEG*gTlnP&pNUEmj zMWeaiNVVplF259uA9szdaaA|2m;$$ndnIbswkfvSA0ZlvF?O0B0&;82e_$ZTi3dyr zqxsL4r)ng~Q**9av)G2}%g?Cm3?|!m0ZrmPeL6|Xlo0^?!}^JKMfbEN3nXdqy#{HU z!snoFNH=&xh=_rhx>HqxpZgh*l`i^i52p9fZ9s8O9(w#5sJc9KX?e)_D4E4@M!4EJ zf-bi9prf@NxA{lO1YaZ-@2o|P%@HpLKS%juEWUl~$)9@lQoc2x%yTOZqMZc~AG|nm z4ndqI@&w{;R%b=B<)S?smZ2w6Dr>(3VU2(aPf&ZS8Ab=tPo-oiOb=B zPe{=m89B?aXBsttec?hq%7d1<Th6(ch_nuDg8n}j8VIrNM{Y{mlM#V1iCI49&6y)zrIMHS6u@2>dRft?2q$mq#XuZTMl>)iWZs61xOj}9O`@##=yqLs_dpF^_^h}+yhU} z9jYK!J`01GvPS=%qGtjdcN%Ap@B^~Rn}O=laILN5MqI;7`AUkeSHG%tqVjl%rZ-wdo8Auf#wdU>{QeG*J^R-2}>fmdzMO z$%sZD5-Ks{vy^{k%_$~LzAheP7cYT%8Jjd+u3h~$^A;@*G#d!^`aY%D&fK!cl&1AG zhHXa8rr*gfMsi)zes_9W?@frN2 zbWdfAH;t%MJ7r>K*Kg}oO8!M)THr`8u(G$XNu0cY$NY(D^y5drAsFqJ#^#OAR?ngg zwS7jUO=ZGb(m+4))y`D@vmR}V^S6%od%@Mw#uCx%827tiphcg9kM$|}j;?X`3c6W= zw|KhrLC_|ah=bAbsfj{p*cSK+AeyJ>o!V*nL_R={hTs70=A|*&TyJ0Lm6T{$HeR{W z&Ay$9u8KTQ3R_mj0-ZSNfWahWAZ18D?Qjc1r`fd0(N&eHB@C-OF?r~M?` zG0dOEM!WfH$WK?Yyq8=(*<8Ni#5SV|GrrbM2I!?=<#I%5(@bAhZ`=5lQf|+~BPxeq zv-|_B$O8lCE~dV;SY{8kNRmvgkM=NKkacDZ8fItORhYRXDI{9(rUyh*)u^@X#Xc)LpgQM3N zjpUtwlZX^>U;lL5naA^+FZv`=R}QEtLuC^HW1iBUh%ht@*)*i&o${0~EH##U0L00r zDfa_l*qDMzjQ0E3zaUtyE+Ui1IXv0myVx`emjsikiGgzqO!=ynJ?LpES#P>NOfK`V za{*U4d-TZLIN*e@<{fWksNL%Stuk7(U7Hc<8OWNZO^wY^cBmnCUID$TYPl9%msSXF z{k~c;gq#@3o#>_UyYJTRNE-O5Y^|jTExKsdD3SSd2R7CGvXfhIRN@+vPHbXuW+waG znQ(z(zn#_n_9i^+M5Z2~^>Turq#r}OsvT??3S-%GWQxB%&3fXTK&8p@vj49_%Y6Hb z#z1B!D6o?ym;^^R4LyUZqE+Db*WM8_>yu)Ew5SE#l)YmVvi4b)%V9*K@IcBkO)oZ~ z8g445NU;4Ao6!Ubh7yf2@3iipC!VWvMZcz4u*-=nuJJ6$U_Dy8BvWGqbcy=euQzUJ zs)~B>{{O{o@X1ay2(uJMnK@sHy7?Q7r^!xe`;0WrHQ9zWPp7ogy=K>+(ngO>fK%!Y zng6`)p-?JWK|5X&>Lg-7%M+)uWlW`5mPjvyT82){WSr?48c&3Zo+eoe$ViyxGk3JI z7t${L&p~N=%ZyYP)4dpgkF=i2WKJv;M5^A72?YOtANxb~!!qW#_~n%M^lBQFmbyIn zI~~pbb%1Y^H0R2RXkSPNq~oVIaEF|Ewmcgmwtl7!qbFwn`m}{=S1@G{8yvk&EfCmn z!1;zXNF6eb6Xr$sdFJYksQ$sNBdoXAzuajjPh0F^BQiWO?QA>L?X?nEK5ka?(HkMs z2c&Qh5SKrN??p^fg$(8P`9l~tH#KHE|AsCx?fv@&n#Bmxgv`Z_xzUM}T(wrb*b-E8 zd%ZTl2q7v-J4mT`uHisrCUs}x_`m}#!ob!R;z%AQ%qBKsOrILZ#)vp?$#$$E0^4dh zZHI2-csstcsNla10CYbXi4W3Xcz)FhEUb8dTAjL^glUp~kWiAQlv>%^)XGFaL2Gau z3%Kk(f~KZUOmm?o)nto+qlw3-&+4?%d?1Svo%xAntKlORLp0|5fWi=we-h9d)QN1; zAb!V(u@<%~_3wr}^~Uf?3pz*178nI`Diok}L29NtES05#U>OxvX}&zLOjQ|EDH={n z?r6=!DNSkWMxBCXf_iGypulm6$T=z-kd*869vvc98s;j;0ex#9eaZm%nOMX`xia8* zoOO72FP(t7sJOhaF$|k1>gMbm<2^>urn9pJUY2goA`FvI_QsweU?eu6o;>X56J2sf z8!n49C~BnPmq~ zoAYgc`x+KS7`*+hfRE@!>#r4hh>;9RPBNgoj3xq@*wh%-G>_(u)D|<@ zW9QW5+sJAdEw3`@#VQfYoM_>S4#X5nv1ylSU=xkGzf*@hFb|2};5!qVrqL?9fqDi8 zMlc6!cT_bA&~S`iK)nzjllts6q^0GRo9!*A3~j!tiy?dcIv;UAGXQqVs15?>hut5K7x zNLT!H{N4Q$aI$^4b$zvHxeDV<7ARd8V(H=Fxcb(ylYg{x5U`HHTBeHQPr+LK6sNC% zVgdFEVKPt z<6W#s4R)(flj`=$d1z1UU7LaKy{?tMQgknZH|wyIK5#iMNiR-`_;&co#w*@51QR%Z zKf7ChnO0jBGT2V&l~UgzPoatAgBg9sYK|S`9fKJYglC)CFsGzz?n8-lDaxo=pCWQH#ic-^_CyG%F$cWUc#R0|JM*?*^n(Ve3zkJ;b!CVec2d>&LHW0~%9`3|p zF}mE96Ro>3xacXI&l<#>o_Z`Wa;AVYg-}pFquT}sh}W}mL=FR)TRytLP>WT#qy@X6 z=n+87ScT%gS9T{-`({wyy%-8Kw^5s<_QIa328U^DiPT;Jh#J3YWTrCS<6dME_;ZV*$r$RI05Q~x!*{(gB>rJw5 zp%6N69%&g$<=Q7u-~`2U5_KC(BlWO!SrsXsj1~gXx^=~h0@>m?u%>hiuth49Rtg|%)jeTz#`E-Ws6XVPh zOx%wJUmmY7W0N`9KYs)Ln{G8wg!_baNPL5miq33NCbS=}7;m`nS6*spbkSH_h$?)E_$Gi0~q-!o^rGu?DBwV-*I zpW=-r%z3`2%&Wt%l3ZiDQ*4u+XS_VK+%l)WIwdL|_e}lfT3Z4bnA(`03l8?qr%Qsb zGF8_?4dxXqR-C_flPax-!Qv7Wb;}N%O_QL=Jk9M}0alG}<|Nd$bgUT=ZlWe*aNGy9`!75zIq{F&1iEKYq(R*vsHQ&zBC z1!B0^L26N4LfZL}QUhgbjpx<{i7E}Tm%0ly+t3;!co*~6Z?Wb-9T!UonvpF4CqJK5 zfQCYi;o*aiBtlqJvAe!hHNv)|swQs(qI%)$Z2*8uThp7Sz$TlasPXkjt1Q7LBEP=M zk8_g?vzkuZX}aH6=l_iUE$3sl#m_1V zBqYA}WOR20+lSR2qY>yU!4qMkp3kK&95mT9?5R60C8^bnk$-g*+psoD{bc(zh#C)O zG=WpB8njiBW3P7n`A4pL@l>p*x}=CxXuiIpHN8cwID!||kF*I_Jnb8cm}!%F=NA(@ zi?$b~XH8b8kLd+?hVliwJjk~yUc9JIWLq)R?2lUXcON;kW>QoGL=>M|r+_0(XTHIiwJC)Lt&;%G*K`C~6`+ze#su@r1 z4I3naPP44uJBn9P1Zx>v!l$Z1H|!cSSdVJVEE=urJ(*iX0q>r?nln;?7A-w=m*6sE z5|&PT4+gA>glaJZGx6Ww-G*gN=Z9bx#)dR2Ud+diM4ei=d7vR?N$&31;N{GDEvQ?u z>&6NW*4o#9%&930UQ;Gz(qgVD<-z5MtyUF-&)?P&Tp|MTqE$tM>Th4cT3PY@wsi?r z97l~&88%xx9m;GHNo8%Aiq*_4tC}O|9iHxii$dH~4BRmg&stlaZPR&I975OF=xFTc z(_B$l4B40DDjS5zJ+f1$_Wki+I_TisMpgD9@DKjeG)|FRblUu%Id+v@%4(leg71h~ zt*2&1^fah2^|l3KP{QBRfG9^g%&vyyZhS;!^w+PyNMrUo zQ(Z5}mqz7a?n#kd|9EmKjn5y_NYJM0s>}_0vlHwIt{WHwBw)lO z7>s^@Ry`9G^RFH3qwoW!;q+<3xE^NAH{g^pxt&`1`9b_&4w_WNO|Q6QT7Xh1lhIv% zy&pGv{A^X3NT6lqy}%|{>3%)qT^$frV7hju+oq`q31a0rh#s?=>L$PH6vpk;)p<@f zd*Vu8?Gv^Yr@Oh~`&FHwE8?l!yxZd7-xvUn(2B~oe3O;YS<=>2;9MPYlYmeDJKJg@ zPvR3o(<$3^XepeOl>%T1+MHb+I-N=yUFbg)?M$NpbPx+d|5@n&4}nCcz&_-!#H3_e zYSFsyNA+k%iX#rK*^5GLgjXXVU`qp-+ zmAPsBi3(@=xiQchbRv8ad*$o*)1b z21iVZh7ELJL`?xJdtDQqiW7C=Fhe|{qy4PqyC4`IdDqZNh9o88g2=y@{*Sn;va)3; zUJxJR=ApRBQSqu&0IC?QvQ4O=D`flvz(^oj1xOHDu!pA^&ND>@7ZyL#%oahRS; zd)~-ViD0fGT1ZFg53}RyhF^ng3^5TsGendjl3m6V!vqTG8LlVKoOE=IGX31FP z_f;jqp-*sjXeicFuRd}wTBZjzrRU8V){)V7UksuVt=5oYoOwlx_Zql^++;saF!_Uj zd{(R+o8R$#2l8TGe$|Iip7-1+hLYSFZp$8N+2_5YD8@ z2uXN9zO%Gxm6qYfG9p9OTB}Jyge}RpX5^|MjVOF~mb(YjQg_I)4#d*1EIy1hygi8T z5#hOryWz?Nb}HuynB6z8ds;vWY?PpVh^)4FdS7P8{Hnm6^`t6r)Nm5JP$OvWO`mM; zu#3PGm!TeA5MA?l1J5e%8=Kl59TopTYoj@m;dbCES8N&CSJ1a8K!yjz^SQ!PxFI<< zy*U@k=@nVl48 zl7~%qcb)jCPgLR~!>RYDa`}GY(2K!AWXu>|QsMJs>+Yib1L|x;ip?wd6x~`bwt<@3 zqu(e)Lk!f#IW1r$u?u$_nKsrGRGt=BG-2>=$rX-p1_A9=0i#NQW>y1M75?6A=ZGsg z9yA@*R<^}@D6nv+?9C1aUxi=Ov9gK`yJoGat#hdG-j4!fXIvV%w@`OFiVOn>tn}2` zY;4ZY<&|>r5QY)mgLA!S(-e6&)oyL%3&4}#I{R#nj^+hgjfvlYn7|pblVQ$;V9IL* z8H6nPx8E?FP&q(KLFJkhDdgg0__i-9!VVy(j@&wRA{! z{5fF3v0pfeh&|T(WqbKyX{dp0d`KFffL8hrOwtI%J8I|AtP>^2+goK|1f?T6wL&u^ z1T>rbTg=Goh=WwS<1wl>bw`iToY>slU*>0-$Cb+qyY#Be42cW}w~6{sW~aDB4I+8P8G`O&9Dp(PC0rDjRBFT@iDl?D}zllBV%3LJ&!rZ2+} z!L{mRVV6+4QHEy~(UME&J4JCc=f-5;C&((6qFH%whywD+;HvbB24uEno|jY22`&&U zM)U?+TxQ9?O?E^YEr#9$GY8z0{CTxCzN(3~kCjU*1%Ws=@rNd=J~@l0Etx^KE1TTE!^*IKB}Dq z$K?oPzG=QOH)aa?el8z~^JD5YxCo^P`I*5|7pE139C0)p33q52a2^bE$`7IWES4Z4 z#v7Rv7>(i!zL?o=@iGNZ(pd%eo|Z$NLY*2JaenUhE00MP64s2VcX#g9B{1SV?e#mI zOmHnK{B4ZGpT25os>dQ8D%5EQgl&IojE%1W2)JQQRhr38shCk{IeVlhs)A=?JIi2> z1P>28;;{8y?z`lOI035tsFX_-w6L|lomDI(wLT5Xc#&b#WsV~PY4K=D)q>v5-LQz$ z;YLq>^R$9S2g1KRkO-yz`bMoiUDEZ74nwHYZSCG(SdzVhz0H^UK!*7P7Xs_l}0-Xjp&Txj4jVz>T76 zy3LTg!N2fL4=_Pta_197G>HOxA!R_)CdiQV?HN^R_dGU#gLlR0-1S=A8EHhLG z>vSYRY>-eYbF(Uf6?^J0_0Yt-k@6bVsDzeXKH7uqsa8dgWF7L%ZRlZQ4kEOqHd2CV zi9x^?l(;apj1e3MvehI>w6+d5fA8JrvrT%@?ZbiPW>bg8OW^QmB7I{`e^MF5Sn%BV zwN5DH5Vu`FRploNN>8^Bh8&^|B};3?^5BWX)sKB4W{89?q3PY7(@*tJGR4}M1(7^N zNC`rND||Z%5&w_~VDZr=*ot1WG2EsnTC?_Z^G0-xyTj;=01g6U*QUI)Rc(vs+QAiG z7AVk9>m9~*s9tN){#&OXZ^_{8KE{sGn`U)q3pqAIU*c!&lDMBa0(7_#!dR_t3c2M7!B+xPxDV3JAqqfv(IcV4 zQC6vuYnzY&&4;uO1*w1-HZo7 z4b|(KK$rVIX>Fq+DuI(n7QWda)_KF^npU-|1)L0|GFXg-zwoG0A)06K9#~!#2kn*D zrpY@5W|M3Wz^r1j78#Sko~rGqK3yFMIv6f=A^! z8D&K(L?MCdOU(=zmNxf)x+=2=tAa5LhU<~|Zb8Aeb1(oyDi$QeSL$MFFo*R&xCUa8 zF!d3QrfgE`XLt=Qcc)nrHJ4OoT;FUqX^JVifZ41yob9iQyGJE2>rw(j)?Q;`27k1q zlzcU{fv=}g9`uQMF-zCJRMLcos5k`C;32vYSu{6mUvILw1HNn1RCIk2%$WM%FxpFC z9KN%BQyeE5RRRkeDnLA(+FY(>h^rKj@xu~DgKeSQP{R>+V#6=UF2T=7JU@ous%XXw z!hRN`%G0}ddPgv*YzI>H66XiCvPeY?qASM`ueqTMBmuC9wC|G)6Ei5VqR8-7Zgw+6 z3aYy4LugtRE&%UqDn^WBG?A~o_~Zc=6)Td1m5{Ft&#|MYAW~JrN3*VCXzsFzyZ5_k z7%5Evfs{kG42HfFZ8my=mWbE(ALksr*Kgx_wi~@zvzIL0riGvmHL{Iokd;QAUS&8m z8df6~oRchBanTx=+#$*%psx^f6)Ne8kZ&+O4BfzO{$Md*Q9(g}r>tvYS>~O|JkrSS zl#y=_GfXy@=QP({*1-0r6l|2b6Qr!jK?Bduhqb=$TpqHCaRdulC)P@#Xe0QLsMTb` zh9tyWzdKK$h*4VAA}m#c*q z4B`+^aboObO@{@>V7s$y81eQuP!Qd1C2BX;b3>veO-=s5zg&_kUj@eZzv>|Ou$l-c zRAl&lG@V?=NmL}3tLr|EmzZG=hyR5j6BcluoLdMZU$^E|7N-3WvuJG1x58NsifpOv z*BCsxN--i7H?z-iIKrUI76}x$J7uh)^_}Z z_SfI8?`-o-r;Sb!2*YT^BSY{WP99)k_`#0z+DEBAHKp8l zz=aG^!?OR%UWf&7C$5W0_BRj}thDw%$g0VV3~mty+mQdj_kRq~?RD2B8_c{tR~A3; zVM0UaU!RjIiRegJ$|#dBRWO#{86?69nswQ*MJG^`a#Cg6Vwoy?QHEsxr16UAv;Ey3 z8$&PlD9<)4ERoW=gZ&bS0%7<694O+zIo$uvCiGyX*drLoJh(1vcLOfg@ib4F?>65i zH#i}tjn!93$Nyc%I^dksB_%2N@`7*LKVmo1&eseP)ilgd{|vIag3h;t&d;`t=o$|h z52%6+&KhO?>wLZds{4sF`Zy=sOdsPh^*EYrx4Lo2^uBtE zVL+96?W}2xA)$aioP>#qGC0<=kyk#?2{=^jUpebSWfD~!@gMaYr6s?0k`F7ZYFIc$`L4y-!_XCqRRU0 zg9uJNiALhuIlCXBxR$^G6yCi}Y0I=PKbb#0j-Qxg_|F!4lwr;PcJOWwf)LZ4>(t`d z04ptQXtUEu&H_@WxY}$C(%e>a&gM_Jyiw@{m@%L&u__3WE8F-{`rsBYmo6~5yX&|& zEoh1kL3}5x&B(-w4PWl?C>$zn?XmL`v&*vsFj+b0pDdBsXcOJqQvkn6)Q)OCiYz$u z_03NKJwFp9PmX!IQ^@^pu0GM&WS&rnJ#Mz!g8N*)`bZ&lH z2Px<)`1xiV){c0<#~mt)>rT_Z7)%OMEy%~UAZJef;hjSQG0SBD-~vb@nQ?r{OQ|GI zHvYI+%CTAOa$-w`ZpVlCTu~H_j|>vM9D%fA6=eZKpto zdb79%99`%YH{GYB=sL>Pd7>C{a}?*g%eE>xF0oV#PAEcYo0eihW;T-l_!hQuUfRZK6Z^VnwP$wxZTF|a7gI%{ z*DAwGiW;N^eT6k=@1R9C0Ui{h`EmX`U(QlVt74mcv&qPf2R$H_Ew-V>pS&q#PkgI= zVx-ySmLCX}2?L4=mS=-#YRSOT+^qcqRz7;#gVB)q%!0ltCV|lV-LVVvcq5eNL(9`A z0)Ibi>Dz>eKx_p$X*1Sq6fLI?!6l);jq3cJ*-QoA+z^(Oe?b9V0XQXmeQF6`z7D)) z5Gly#u>&T3Fsu7QiVyKucYHK>KPC{uzBwrX3T#gNlxZvva(SBOol)HUSE9bmGX4?&}f`MeyM57cCTyqC7WG zOYybAhBbi%G0J=j@PA)osUW(I*<)ajRgi#Ny-yQp{FkghB#Z@+G85PT1cI2Av&-Pn zjpqrqkb~lg`oi^46&Qtc%ys3AU_{_a%OFVX0#XiPRaF$0Y)hP~w=R)RI(HbOqXx+f z$2<~{x3=83NRHgG7cH!uY2__SslKWqNk{5CJa1WGDHY!O{4#5xXavq+qMI3-&E|yB zWA>g2*v|f8s)y`I^^0%)qidi00xUr@;?QI+beQj^ikmL@P`1nnoOe8hDlan zS4YvXjsEjHv|Ct?e*XtqYBR}3ini}#O%;X`FrK}iGeFn3Oth1sC&CZbtkGBMjyOHnwl@z%tZ6J>rm*Q8oCx>BIu<1PMsTk*{ zo&erQOM7=D9Y#`8mUT+%;Haf%xZQcop`()<(I?v+Vy*i9B@oEq%*|htZGq97s7Zhw zj1D5lAV-v4+O(Hy5y)28zhMi|hWpUHJr=Rx?GtMgSvWHe+A-C@Ml(R&bplZVYKU-k zr5X!5B%pD%<{XR`MA^EU>aiAFjGE*+h!*4UOIOcz>xr?( zse=`f4mk+-Eh#BvL@cGk+n+N+ES#y5APz7)kA`WfApv?s_k0ItzZm1dUB7(t1dO(` zd5IW0#s;y%yIw@SND;)~H<0fa-k+l!q8!cZpup94v(mQL2& zC$>8|XgyBX_xCeH;T=hX4vYrJU9-5>qDMP+Agj|h&fi+OrPmg09z*wL+A;~u6WjBs zRu)?GoX4)lY0$ds$M=?ELKuDNrD84C=Ehe4Gra?L9Q#tcG?Q=d-OPO|;EXzE509ZU z@#dZr+hUIy|R_+?l2c8 zP8vqwJs#P3wr4~$)tSV0NCf!v`&w-l985a#?z&hU8akadW#^|iq*9jvJ6oA(dVky#hx`aWgub)gx!tQ*Vjux#_Qv7&;=V;uch^hkE8eeFW0J)%V`gi`ItX4fcQKz+q`{&mm#%CG2*8)Kt7AnO(P_DkD;11T z&gV1N=%mm}$)(0E7>ZBwY{^=qHBZG@FI{kOy4#1XoE)QxPuGp*CyEjP9lJRilHSmnO8fS=)JaHb4o4P=@qGYTM*NX!>j zzxLE3^7n|^Ta%bR1aZ8xf;JMV<4&2!oRFeH((Do%=OgeG$WbthS5CV_l{%`oEub|# zMPcEc*xPf9ioi=5gKVqD;@!EUfR6BKp54_gJcJ}9~&p$($Yje*LS7bTgd9gCdY ziZa`a=9*Jt28VEBYJEimAu8;fx~L@9Ihs|2LC_qyS@NEiVKL8Kc>E^2%BWp=*KF&3 z31o~6h&{$$wk6`Da_;tB3vuW}Q_gs|R(M4RJ?qsv-_RlTM{fv_zz*Uj)R}aSf&wxy zWPx`s`2^3F^v%Lxm=b7r@7Ds{v{pGED@fAfv=)|RZxWvmU@1v0PUe><$v^pA!HG&) z@&wKBN=X?fA=0P)yX=uvSWALY8f@mjWD?PYksdxw@sG&xstlo!ef7z-0g%2#Lk6z8 z$|eGR8?=IP;dg|t3so%N(--p85tEcvfc7Ps-97EK54KjZ5a?O;KRqY@gzN&m`q9C~ zG|q&A?OmKvIt*JX%#Ww;4CvvCJ@d4WsSK>DT#dd<_agV^`Rv+eNTH}cy1@tY8{84e zRN(|0soz3?bVO<^{HcpcGEq+_bT+Nr?~h|MOw~o=Z`;71Ob{NSOfH1IB|*`gEz148 zQAYjtX_@09fF}Gfq|aIi-jQe8`U@jmiWwPn9;!)ACyUzK>zi5pm@T2+m{Zi@IlTCs zKm~D;7QTG5dynDVeFqixQ&K-8GDZWgN#x8PjD`lEBKVLB0fB|L^LVdR7_F%rZuip5 ztlXSLP!R{;a3=SuXqvu4l~U~1!2InL*drLS`3rit?-{_D$D7aLwR8^hg5vY?Q&^OW z=3eG=8iH1F7cL~zAsw+jYi!)5TD%kgxMCd|1R-y#)Uopr-Bumb5uW6~1hI%cBu z_9mMvj&Xe1$7FaLiKCmB#3?w&nX`}Ivr??$y+}c~p6?5wNp}S_a9%pEJt9z%*U%4k zKoBOJF5eOx(Sb3Er%cz_fQRM9?*l5A`ODO#iU@2@kpbeMluElgJrsX0ed#KVRK8`* z0}4g1r0WCCZDQ#cw2BQH z`YjyGZg&M!+a-xG#HzUzP8O>>&LO!m7EFsBc~^EVfg!m%-TWnk#kz(r(fR{kvheYJ zzr>|}j7sOSgsyxP8669Z4zElYk|0}J_Td@?(c~wxoLgn3a)xXzxzsW)#kJRwBM4Uv_j1HU z00IqNnTU$%K-o!C0;B+qN%NG7i5VF4atkMJ?CtIrARCave!)3eHwuCLge;*WLC5VQ zQmlbY9E@on7whGfy~9k6P;!3}HI+}ZH}`Lmu}1~)f$1RGO`oiqt%P{KBX8qBozOJy zpX*FgIVzPi3j{u2_MMw)s`v%2QY#mfplUv?p$_y; z-`}+v98}lSW`X~>a@XOb75W61fc6&o4TKYPJIBVj486Vn+l2#iX}m=48$K`;aYYiZ z_o0W%82xXj?inA@9IyMyM9FNP-21#jP$Y;A*QPAg4KzAW%ld+CoEqv3KEq~)WJob$ zOBJr}-lj#tI~23mW!Zs}3{F;uG4n%OgqrNH5{mY{iHr zt$yx1odZ$w!61`vAxJ*jvRI`akt#A4`l`nnw)?NHU1xR%hYa&JFzkVadE^WgUE{*$ znc8h}r7KV*7*oLwUw?d`p`T$1 zW#%qK`aaX;@0`Q)b5wFybskwjN5+N3Vu|@)U7wPOmrjpOZocJ-iy@f7LaFoYg4np; zRKC%}Qq17A;9%FB35EUn2Tff;RtO4{nX~+h73Q_q%DM%2Q3MtX60ItfQV!Fibzi1w zLq!b7F_rV30S248>IxsH-*D&BD=O-zqHo!0+-i^D}u&T_g$fxr%=g-Fy|%ep=>t~b)P2ZCTv8A_AF z$xOA)e|h|P^1x{G*?x==vg!sB-z70H6!x5~GlGaBt+_t2jK@b&N>-O~_$3}<2TT^k zXr8H5eGl-O;g+4II{B@Vo1~x*s68H!Nav8Et}gCXIMQU~U9k>@CMi>bq4-s}>MsK$ zbd^>HcsPzY6;laD*(vVRkBJ*6fo>7!AX_UWX(26k_l{6YRha=>L7|aD@2o?R~l;s5`ICwR@m7SOf4ki)ExQV z(#j;5iK||limW=|>dJzcqDgi~=n%lNHS^G+6i4&IVyeii%cJ;E<2=Oa%PYRD2=O1_ zSUEyI#zUTCqR+j*vqK_t z0(QiVafrK6Yo^&rQPK$mfdb`T%Az3x-}81jyGNt-;2Z3qeAlp+*66Ujy+-y4j~=C{ z+LbtsUX%>jH-0>9^m`H)HiW zg-P3&rRuTQa;K?6j1TJsa@6}E6oop^ljLT8&umsY5R&ax4s#~O9U32<9u&5 zzm37cj82!OAth7dB&l3Yi5_Hq@_!78!PBAIs&AFE`N6ZJP)0i?BY{AGm$|_C?{!6yoVoIHD$g^=2l)Kqf zi$!$kejTDY%~lX1OhqXy)E!vsD8_>?_gi;8KYly{Hax)lc2`7z zfRTCTpd7}Ofu3(p7D;uRxRPG0*VLTCT z*TUr*js_TfSotf8GMcHQGcOwSQ5NCCbf7|4ceH=+0ISXJ-+u#b^tzuG;9>R9i)mwh zJ&n5aiS;-aCEIg%$Ee7QS)BFM5<*=y9``4Bm!lfCj8;g~!3$YlmOX=CMr<3U@4> zrx3MlEXc^<2!e6wf(Pvl!6YzuCf|B(YItx0LDiZFo)i_{KBb_59*&7PkY$}L)r(XT zE?uZZg(@bhjbE-96{*OHBiBJ`sOlPlbU^Q*?%2&TVlZNCp(=QkhwE!^*G-Qp{L9YqrYj`sloG&kBA~+)7fBn|T(uZPzIm z5Hb($NcX{By7=<+wqXSe*q?=(n?slcoUi}aT1J+rd=4Iu=6ttk&f?FpDB$IbPoNc|8%xr)p3An7XS-dmH>kH zmI2G&{?($(*|Ho!?{k!o}y3e>Xvv%(|^Ht|8wq3S{PXWPNU=uxMuYKu6@yYpi{3tzrwnz zr3?k`1rA>OO8q{j++n{|)c*K`idDFiQRk6S2Xh$6Z?Y`0ZM&67gyk3b;g4-oCgwjV2fZ5f*0(qxOW}p6R+E2KOo*N$l z2Zz+?PSMGxXhp}dp%%L2gUOTM9&K?8&_#5#>UYc{%92yXRpo(Q zsLtqH96D0L`P;w*ngZ_lQU2$HG7>HEzz=$eIkA4qhJ{eksx^Ac{)ImdCC4H4h>#+Y z{=2_gU`bN{I9~aajjdvr`H$}IS+ibupz-iRwo|4-_Z#B)O*194H=l-W&1`CVcpN(is-BHMSChHV_J%wKxBvcwCClk%WcR9L_(i; z7Ev)3$(U*10WZEC;iJDpn__cswKSGc`kp9wZ-xHTvT;+RrY0f8nkJPo2N*n(HZh?aHSggw~C%dJ6Bj1r)S#C#gKTKLiI*>&?yz5fJXT12+xh z7k14xf5dm*(!UCPYQf3TmXG%{Qu7$P^_}3xj~DQ}g0E*vJ3Ab@$QK`c6jJ*hwVyEU z<^#69^Bj*p!T+{B?P<{K!eYc9I*J_6_IKibTXr4X{IR<4&~4_UA3xr!{nv~QjiI~S z@42zblYWboJ-CIw+k)Ds+^wgNT;9LP74E&@#yt4-ZmTYF7kZ;>Mp^fdA1ZwL|9Au# zyDJ@maoW+K_Ykb-JhbmA07AWXucOD*`Sq{puWwEB+YYfkANbL_TT@blE82ajd-@yK zbpmnOleeEqY2s6Z9iiXW>a>o%4_GRG&&jfvzF(^PakPJTzAL|U6nN13=0JHkY7X2z z?;9~azu)QqU^^QZxeKghC94{^|JTp{wE8g=+dM$|Yz)v{7HCiGU%cJV;=EV(8f5;F z4&6Sk9Oyo$k$#YJqS`vLwp~zjo0N%Lb)usC(a#-UVDd85%eUpqReV6qIPi=!3nDWQ zKN)%TTh%t7%TZu5Lo6~z9{BUGiQ$dw_bT{g)Yi{GZZrOqzx4|#8m2bSzq2E5;_a?Q z{N-#Cs{21#owzgxz`B6u8iwy;$&23H`cgy)Cp}EvOKrM`2FnbGSe7MV&coxcAAgBW zJ%4Sh!N|dg)Y!aTfHO5Jlg*;0!REN}>Qr_~M z)H4(~@$7fP*{u(gFrGRc>|}FY!h;NfuCeLPq+_N0CI5VbYdMxzH!R6!e5HGy-JB2p zhUen9uH3^BbuWMLRrq)K{RZS!dBlxP@!wppFQV(m6>NqyUib~ECAi$2=0XE)5~ zNNnw5qy#;9I4nP=b|gcMcsOlg?{+4tE0%<*d5;MW$;?&LcV6+Vw07!l*~Acy0AFvb9wMHFIaW+U+dw&}NH zH)*JDC$qmhtrv-iX1|FB?|2@38z`Mp(8}n(ZhY7C6n?mMV?X0}qEhogtMklL6zc=i z{8z-?S+(6j>;Zg*geT$Kv(oNfI!jCYZARMC?c|kY)cTEy8(&d+(KEHA_un(^p|>tW zy|-t1O6#U;pC^%HLW>@A5(EF_B~jWqLE2Yd6Z3?rDv11Xk*sbm`4!iVR?6T zj^P#EN;A3epokoS>oG#bvwN2&y*+j8Xy|HQk$HSHnY9*J^e)Pgs=qo z;k#GD9w+ep-8X^Qa9r~xs60&>?Y$2C`JXW$Twf0S8IQ-GY$*hO`SL#S%5e?|uFeC# z+VC3iwMGp5yJi>g*!A_>FE{p>aB*{y`k7-&2!@V)W6|fs= z`{Pd7{OyeofM1_I1i$k4yi<`m4gEd;BlpY$&os}TJuUh4HhAe>;Kdnz$w?h})=;{i zB;lQZJ8=77fkzK_T&5qJX_AA?hJU}Yx#(tl?V8Q`f#K!twd-b_s-%jwsUMBeDrU-F zlGKxLn*{I=ftD9lrJa?pPsDS-2mbi!r-ujD0HKSgke;-nLoCQ96ujDlSndz#m<@j3@H`_Y?Pu{_tQRzA$ zkuNAaYc#KY@WDTZKAu2h9ixvgR*kXPt46#ZFUZ*b(05Vz^TRtD{fp-K0rM{=p!A=z zcbi5&=>?A1T7lK>(Fs$6+JCU;r!PFfe;#{vvQ+xz3q!AM2X~J=*+5cu(B!jD;_}r` z3;Q;-tQ+pxd8Kt|@rZnI?h;nhFa_>{<|aSI>z}Z9u5cDkx;<>8cR8NU{kQPC(- zFZ}X2R+%sug3?i-XTA2y?(zM+>sbZeTS?~#_mqN~>kYNk1`gQw3Hey`_gsH<%Nhl^CFt@*eBum6PxAfuj`|o;Y zw@SSbdFlOS`69f?uytlOLEu?7S2$3JFS|HgQf4m2lMt386jDJ%?v_NV;7qug*DCOS z{#L>MhhDKrK+DTRTSUy=Hw#9q}^Xtx})1O>$ARrBumh$P_Z%ZTvde_s*&m(L?_xLobFY zwr*~pI!J=ohkASa`=cC(;^xXNhTekUWRwo{8*rZ;$$%A`6Y|$H}Th4P^&4s zUSpo)6l2|tAFH*ey$S1`K)GLo06GW1D3mp~@I@LI{@Kdg@Mh6@YUinZZ!w_#aU>n_CNC=#arGDD9S2>x`>psw0j0ICFXq>YcPc;9>f!>| zD@qPRoNCCYw|%;u-+6HMyNk+Z>Ya zZ_NK<34SJO!!TK*Dz^oq1T2`PYY8^Z_?; zNzgK=ENL6Csl+yDg{B&*sic`H(Q2S+5&Bi&vI|2@|Qe*n*OaedD@pL5?t%$@mA>|uM>&Q^%JX1?H$*sE;sj7NU+ zG&UkJQmALWhVv}RmH?B7oFM#nsgw ze6k0GRtwYl+R1BjEGgbj!TC!asOetc&9+iLc?*4Sl4(8Ex9~$~GYxcu+_Kr{Ylc-jTZZ;Z6Xy%5Q- z?=zZpW_bg$^Pokbm@_jrTgM>yDv7A-X-esi0L=A95w|ivL}i2p@uv2qrvtuCVw#W1 zvLYBfd9pw8Kw|J-t;5)fezhKuc2e0%?bl{5$$+ko&x!IBaqa|a=pk(E>Ul5HwFol! zT2_9e$9IUuEl&-TG8^J`;1s2THMK3tO@(i+NkEm(Cp4-pv{{6WTS6>2YoOtr0ck@ouxBqHZ{EO8;Hh@! z=Kg4i_qQG<5X|sa?hqtPW9ZIW9D^0Np*BAA3jk7JqL#!^6HJC!78WRF$>s%PP)Hp6 zM?oX-niySWQO#ksQJ>SV1)PP+dt3q$D?uqba;FzYGZ2-xU*zS|Z#!}pFJDs7X7DWn zqtJ|G;`wi~7pEHoTCb@%EE&c+8+tVJPh1^1s!5V${1-SFKL;jDB%aPDPEeJpoTfm2 zg14!0HiWo#_utIt zf}-~9W~Cq6K#Lf!2!f}bxvP4$KL#|3x(=gX>D~bXtAC;$__^{F5bDz*?e)UW)^|P- zv95x=FwtvHkaE|0@J3ij$o~4=1@k6_(rYPy^unfuMx8j`Q6BQ5X>Y*2eZL3e{CZIN zjgl4bPMe{9P-P4|d<>~cU%^abaDPo>1man-rPVG-MdJ{o=EgKAVELM-+lYmOa_0Et zVQWq-YtKemvgg1V?X3v-=IdebVww9bADA{91`m}XKpVs1?Qy7Su0omo^+7;)W97}w zsl~D81M{xIZctP+5h@f10eWaYU_QXyj7SASe?jRG?Lgiv=RIda{JRvy$_IE5AW-MY zPI!I;ic>8@gbp_0djHssItW;v#I3}U?k8IS!9Tp8zu@D0CKWZHRD0uqy!Lov#@o|> z0PQak(>hUa5WvS3o*~upfCQ6D0u;xkVm#?z(&Nn&KTbjm?b(ty09*^f?Xf9H;37hh*B^rsgW@lkkG` zUrdi{xpFbrQm#6a!rb{tB-+f)o5;hf3N~Y%n5njDiqJ`FRBD3@fgq{hW#*N%U2=S{ zzHC=HM^PJ@3B?-_Obl{ZhY~wd^az#M<^0Wb0*Gg>1bhk1B-a;5%ZXN9vP)rEhyVmj z8Zw+skBd}ti~z`^=pK7aCsL-NRsz#7scsH1?Th1tv$Ytb0#;_GzQF^kMMbceFUE`r zc;aw?$KdYHr$a!-;`s^+o6v4>= z(Hnc56akl)!*T%07s8=C;k0 z_>iMDf$RM{`+}pVVr@;^KXa!~LZL;mI0tUuqc zQoeIGe3JxvRu78&b?Mwk(7B%A#of*H3^^!p;Q<#9yPsb~gaDtv?A+lKvE9(DfAFgs zTnTIsAv{Gv1mIu`er;X#y%U(LfZritJHo;NsyL_LI2hhRfN6d0xcYeRrn~8zxnAol zuatK;C zL)u*%4ZwEi_HNo^QNr7s37B)>bBcoOe^P(_zOq_FAzmHnz?7SzG=sLWYRUoFAp=Zn z)OzDb9`jb(<&x$I_|l3Q*Tgk*fuzlA``=Vno??R*zCZogopKZSE=g@C@X?o@zX7Rp z%}j{2y%T?zY4%nEk4Vo;{0_+?Hne?w0J!RByhS{yZDpPVny<-Br@tSer6L7(6NG?F z**fzOP5TT23NR)3X>L*4i(4P+c_D9Kd;d1Rz6;zwubc+lidrRntD%WPceY#Y$g6sg zRw{hidLv`AK+gTL^OB!>Iu#%-+sH3#kt2 zeq9SxU_5u6$6#OHGs{535^IMOihj2G=;8a$xzFVE2dQ7%3%66fBVEEZ?Qa#PKY&;A zR`pvCQ(0SIpmlzju-aM*f#PHSLZY9UA{OX(q2OXOUvDHrQ+5?LJj`sAV8kYb?cShk zn_xBI(KG;i+5bQ5abYYfpy)(gyU!VSZgJsU!!y<)!-*-II1n!mA}`G07PY?4&Xy;1 zW%elg)OrDNov(6K%X>`^-i$FbIv-x)zf?TO#qa%Q%nAN&{o`Brx-J5NNdp^=*I)@2 z@X`%`UE7g4A5OAd|0xL`X8{&0`0O~uNZABrvkR`-eCLH5h9jWQz^ixVV^ej5_-ItVPny)lItT+{qAz)+BvtliYUV78>8j(vUX@T(Nz{Q|&#yFA^R?Kx`k zHn@@;7%y<%6W{2q_I&QNrZ=Hl5iei=Rm5NR3M&9>zSp3lol+?J&sP4ULt9rT#+|nV zWOKrmgQZ)y0x?>58yx%$HF^rN9&IPNo!RqFA0DVZ)7fyLLtgrh*^@q0b^0(zf|;-v zbw5DGeJvkvJAiux+{b^YXIFI3+2^1B-(ay?GKUKW75yThZ$0NGOg#2b>aG>7R-ei+*mP2$JXf0Pa-BeJSAgv6 zcp^XL1A4F->FsJWo5{DQEUG8Jdr<(i_(x+PT}sJQTn>oPg!T&1~ zGVtAHOq-`*M3l|rVEXahKu_|JJErcq?xUI@ai`mZVdF8aZFhf9k(yN-RL`A2&ooeP zcgf0r10-C)oSGSAEXX(8pMD zuKt!UzAIP4o6P!i%)R+H=x(>sZa|D#nwpP27|C`Ji;ULD{pD|st!UnRMKXvw#74 zEhD7{8?pQfZ3sX3nD-gz$@)^CVl<$*y)=DVR%{W_j8`N5mn18+WWHZ(k#KE>Wqgfzoi4#*pr%8Mvda{TS}+m)IPyshW(T2)4h~5 zw2zT%DSuaK9u^&OAt=tIVWCUEX2x=c2N=JvVFPD@Bi5^j3?n$^%kd-s@#ntKJ2~J@ zUJ$!@&ruG*a*)iKQ?ngx!mWgp3A{}Ur^IKpqm(F{EgjP$qeNI@U=#JmFUH2^6KLC4 z#OJsV<^AP~q$>k9CCw=&4Zjxcb0Hk;2kg)FtkzPA0U~Yw9z!pI{9lH(%$f(SmRt=h{1@zCjDo2h=|*>C65`N zgpcl5?Q>r`?-C_W8^o2iO0-F){cPCLH#n6vn)EzLj;e2^MFMYyKgNMzjJzl^YXA)5 zv;05;Btf_u_Y})_T&;%iPXhZ_(trNBl?a^7Sd=O_Ny4;Hm#m0cp5RO#E+5zYmy2{d zTo{jdE#zre>2;MoFe5rNVOkBzHz3@x=?6 zs1E5p1g?y*wN7F~l@NA&x@Cp0qE9KT`1SJR;l^e3xOwi_Sm4|)_4#HG!c^|CCp!T9 z#8|yO*3&)>`=MZnpl*9R=ilKfn6pn6cdrZ<6|Ck1UF_4@JfIX)AynI~crCXnOq~Z@ zIf$fReRjLCJc!41rcX_t{@L?X&SF;23hDydl78fVSB$Pr2cBLzTB39*6w(h5>CM4N z5`Ku%e_PonJcU4*Y?zPY(G=I<-NweCLgL6{eQ%PLl~Nib0|svE%^!i6UBL_q;$}v} z1KP>=<5Id$8tU< z5PH>vFs%KAqYu?{7ylu7ba3jTrFxHIgz3g7CR&RePr;a#rGgT3(8HIGl4}N>N)IFdKvRdKcp-Z9pRC%7xk7sr7c*`wGzq zkrb+o$a$4{%EZJ>o(ycE0-T!FVUG6`310%{aSkVZ1O|%ws;2#$?T}zU3SDaSzr(lQ z$elGBBnC2ELx{_GK8I#c>aWl^PFVxLk>91NhXU#S1LBT?0*A>28cP(vkS*lCRD$_G zUa-tT3cMg06<8migp`pt6Iz3WNH#~JbtVa0SdK#is zJ3Hg$kLG8h49T+!zeE8YOGd7**qw5ftk`L>>=SIDlt1Cx1~)MhG0X?lzA_LJamh$= zXO7)lC5|YhJL_bwds5j#0FVz$%FW5sPG?EQ4R>&+6J(C1{)l7y*OZX{C85Vzkb8fDvQ6yvAt+`<=w|K@o4~!_8YhSwD`!1s3Ku+ z9pU4B+DXrytuVX0{}v|UV|~xIlMzxE>Vul*to5nsS1BR#q5M#6KAALFL-bFHDeP>m zPQH}^+y9MV4yYVdBRgImItZbP?t4LgOHc1%08)VykD4;bmwD#SjZ4^rz461siEDkW zj`vqFn*^1zp%lkGR@{`b>5e_>bgo3rw=I!euFB-^8@gU z`6c~|AsW~*qkwg{ZHKF%r%GR*@LT(CeFa}sr-8I=6hKvG6oghvA5YZ|)S_(?PZ)`E z-#J+8Rqzn27qw=eXgPMrP~Fuj~1e*Pe(H9Ka(!F z>EBUnlT|6!jVFcnQnR-~(;aXp0--QB7<93S!wFTQ&ia zuD+`jF*5915*&KGbaWM&_UW!irTA+PJS8_yfVkm25yujedZt~D%V z60rm8Y2vxcHn6(s$?;<>!WB-d*j;U$t{!iFpp;lD>|J;3b*&%KK<}L>#V!VHsFuyE zed371>+6s(wDUo-dlre@_fYA&ZNx}*%hJtiG4M(FJ2Y`2qx?tW%vW7m%Nh6i+r9ju zp-EHZvuE?RS7NU|L+;aE(0Lghh^ik>mgQ!?zRCCAm8|nOEf)8=t(b0gmmk?OSc&~m zuk5Zk>QBwX$!nB%G4U^{Jb#y(>@0Ycadsq^YV!N%!v_?Wk^QDEj!3YZ_l8o1CJX=)S}7szs#- z%GeEqsNU9%kDn-e6n43Jq_sag_GEIeoLmlZ)MQiYRrXFiq#TOK8-$K%yhz0HpLgvU zYQV_`Z;5Y@SXVO$;&ySND9RYIlRhkewh5&1Lmq$iH}paNA$iN)1PcbkH?VYH5DWa6 zp9|_vmlvZm+oibidh?fhWjGo+;;i=eGW+Hpylg4IPlXLsz@{gj{yE*>Sts!mokom5 z8GOuk%0>NMH>sYl>2FgWFK7&K6)CgL-P`%w&%}Z^5;qLQc5lI^?%b(w53s=-*RR)m zu1XU6`@f@fieDtXleaT;0TNd|&Rv(4wB`})!-QOp9zP?~45}F}g>w6N)Fh&pmfakC zo=ky$s8n`sV;pcimiN`t2C6%g&Sw(F4Tg6$bMt~S&{#2O-OTz~ni$`Y95Ei4vDx1r z3x|)-*eMZhuheKRmKCK#XKJ<2C2d^0>vs*P$lW*bXyeHYEpBw;qk80yzBOp)K%dGZ z9=)s5?Wz|^huiS=5mS(Kwc$Qu6g-C)XRA}L^t6kFHj-YI`RIJGQQcecC$mI^v+VX! zB8i=}rrmye{_HM4SvIr{xbn;xy%3oS6-)S(r)uid#A}vYx17(*ueWwB-N(tghUIk& zEzK={dWTLjBL0X8p0d+AdPm0SsUlB%i8HyGpEFfBjkIx_7h<-LXpo?!!`XJo$48p} zI*yQ5k4+xDXXsX%{=OxX{#WlUHziyG=dKK!5N1AG3J)t{90DD(+uNIjL8=Q04{|x3 z4aE7dMUeL!W>XIHb_H_>pmulRF@!Hf3rmL(ZLl^+gEJs$B-PP2dRy$)n5 zNuLbyv&6wlS1nevudy*oZ*KLuw>YOGoPD+CfqSf%Amx}<#rh(z0s9}95sXDO4X2kk z#w{-Bh|AA6&IQc{eFm?=;t_}weG!SZ7Ld{(1R-ag_gA|8{3a5g?6NN^x{aNLFqo1A z*8>A*Ls+4pP?0u?>ZEShyaX=c3!lI#)Nf8`3?2T0Pf$~yXpQv2af zrAReSXB6~Sl1++#x65!90C`wNJeu+phm+i+-{&Z^VqF^JFf44}g+i=XU6pmfBEoki zIlBG{AbSeFGCi`bU8gQQRLXo1S|!N(?a2!XwDUKap;-&2ixPk8)HN%~SP)i;UwXNC zDj_g<07%`t{Fn%u-yhxJ-g4ZpEC>ir2no?2DqhSXNy59R;CFB~h|Sn}6nsOV%-TwD z>E%PWLF)ws;-^}MZb{piZM=p&s`7qNW^@G2lr;=hv%lWr9TT}kgSQ#ZY7!=EA^$_I z)4XT>ZK#bedR1KkZymx?hweA*y&NQGwfSIK&^c_|!~?Bmu}UXw(};;B%^Q5X*K7B$ z-3JTWz0b9;yLOqGp2f-7_=*Co7Wy}Z6$C}_va_FqpJJ(^Z%_I*5Frf|6iT%B=;>Z! zC;H}hI(i{OzHmll0{kC0>6>qWty}Z(hAV%AMA2jqFQtCVl6JjE8wdGV+vfWDS6+Jm z9g(vJVTjFVc;Z|JGEU`#_I<1eK|Y*6UM8$(J3kU#Q=tg9qnl)_1uq*=MP5v>)yghfqLQ*LSj< z` zu-OD|x5ONt?ZNR|n-hECaLl*}R>#;eBRVQb#2#OzT}BTC`D0hEL_fXIauvfNA?^{s zJT!C|#;p)BWcixa8Hyhne*IT9MnQ7sJXKkE5dXXJ&vzZBzAf27~zjSGm6 z+*W?ShUm_Mep|=8FH(T^`H|c$ZL$Y9@O9~eRF5G58rMJI|GOjJ1r7!waj=;G>FmTb z`bfU@2p9sv*{xwYn$*wnGZqVcyd3V7De?UyEoKlO4hqDrU2Ag9iAmtTyF_Z!K-_ck zWpQ5~Z;mPb(wTty1bb*GhP8tn5NXxEYMjMXO*K~d{47Yi{w^(a$^Iz%-L5;j5^;~) zg0N~@(63GrBpxknq?#BwvLo?Dq2!t=8|l9imO>TYM=XZ)xpbh#*uvn@RKIa46fBo< zoBv!_0kC4G<+|Li{J4$no$aKiE&$224ey~DU>W9}V3?p?bV9njc5j7hO z38%f9%pRqu54ff#+-~S4bvLGCdhY#q=6$S|>{cP&HKBY90cWow*Ir2`1iOe~2?aQT z0UYc{0ss(+Gk+)5-yG*}-4hZ`<(a4aoV~0Z$;AOgVghD-+#cq88a9Puo^jJ79|`8B zf;;EUqwLU~r_3h#+KQtU*5DH}eWmSV-WP57e&HQ{ooJAsbtE;4KSXri83#i>da6C) zgZjwHA9nLGgEdZvIWn(OMdc3KY|Z=tEFxXl)8On@ELtZG^_cI_K9XLn-YI{<>V8 zkZYQ)FhUUbQUDjWPas+z$buPzT+M5-{_KDNbK*)-2w#TsAw}OFI%%?-Z`8}f!I8l7$iIsN@!OKb59j*KBc^v3aoUH`PdTF+mI?Ct5gG&Gr84fq zK2HCOGo4k)F4G7Pi`_S(*u3(2UAGTgNwg7Wfyssc8MhZgzuwoMfz7(J< zpxAvE^uUjWE*~C`kr^mIT3>l_eRN7>CQ!1qb#r4u zE^5h=Ck}t$gB}D6fR#jHe6fKENO1F+{B>qpv@7&thA_D`{!92ncSuAkIB}l*@V?N= zWB81T-|@S~{;63bzVoa0j;%3$lJ(RTZtEl9FOoH&p&jUSm7_mYGo~Ri7`Y||vc?i* z_0-ZG72b%OYecMGUO7>@Qea(AW063UV;lu)X@AYJKubP#fM%~(ED79Gik z1}p~|4^!G;__*|v7k8lCT!-wiTC@M|xwZ#F4HxIIyf{{^9)KKuGv&rA&aRFNKbBg_DdX;$_b+TTct|l*79&Q9|ukK_R914^wWb$Sc|$y(CTzK|>DeRyaXd2D>r|Csic`Ich3ZS94$*KD&D@hllz=KNw!<) zY5{jVkD#w^0HA3e@Ikxdv4=W*%QgGXJcFTN@RTz;$b&L-Eka8bEiIQy#g{+Ia901v zbhmLYPW-ZEiRHo`85*{~`$aM#B7zM7BGJ=z1G z!dUey(#@XBIcRrpMuwpuDHIiM1B8N`|xe^+RM^pDa!%rc~WYk-LXTkCAZ!zZoLB_ zptySw7WxKts79njy6P0iau;|g0}ZtcTu?l|PBwmDItz8Pk@rt}{z2rExzAjvNO@#j z5HMTLolXn@1J0=(78Q%2k;6H&kKRNm{oqmF99K?OqjMvG=)Mi)pw_gPd<&H{if4R46%Mp+P0i_M&bC&^(-f5p@n zN$GL-NE9e_9K;;Fhh>}uFv5vC>OIBLt)S?XzgJ1ik)fia!6!f>FjNX-1U|1P(1^jJ z^|=tD0+9OOjLq$%Bh4uf=n#od&l1uWW!;=n9i_=M?b`{Rib2|7rSfsexF6y}m1eN& z36zeN@EXQAN9!kwOzCgA|8CCtG8U(&==KBYji2F(U(|+7va5{nLFq|bYsWc!cg!j- z38OxFe~q2&7vD^=mqXa#VQBzle5F|e{iv2rJVd4}bg@jCO%vxb4{g(}8{b0k0an1N zYmt5)7#M_}uKJ0L0ztqAnkWRG&EhMe9N2{pKTwE4Pdh0r+P00VF4#1y(DM9}#G|4; z2>v!~A=!r1=#gJTP5otbC;Q$E@oAH3TMlm=^X5#txGA%BZ^lCo;wkX=DZE&dXI;BY zKjQ0>RxzxTkzz`h&2*imI5ED1>4v65^bTj>j-$d#_RwAAu!VDpkAX_~ZjC>4X;V?M zieW0aVL6cc>>?|dY4rC8HLRW?6@z?q*wm!?TJkl?FY$R+04xbR3W`aVFc_ev7TnTm zKWA`3l11}lJSa-Jc(HJL!p*=2C8qr{aXAR{L_=z@9JvBf4)TD(o4<^2;S)xxwT?>V z(UD^>2z}``RBv3zITvTN{6)dD0$t{laZ)O@=$(Y;N_JJy_Kr`XIdAjzKhn)V-a-z_ z<$ki$)+twD4i-0Osnmio!km(9+$rlP4VLmAAGmYpBXg#a)Ye*(zFPXGm}LtMCH(bv zwoZL1*jXV-8>hkH(ksTzr&j&`isSDG)+64R48dSXBE&!BeRgPOfDor>U2&S3fB=Pi z&eA2P-8T^(`N*!=Q%X-gb+o~ryRgtQ`hfRAfgUVQ{=Q0!{7|h?&?>(y4e{K<3{kHM z7cTdO0=S(b?bF|k!Tj}yyDlMFhOqgeK20NK zZNe$uyl9};w<+|NOx;-^>uccoQTM`v@K9b52ws*ZLTV);A<`{`f#6nGp*3dtbvgIBuGqyyeTL&Jp~B>aAU^O&jQqqghtFz#_Xy@#ec>kmp0VaAvL(}>+9m1 zqZ?pD#nK@;fAlPAI!?(PxkHcNGrA*r^i`bl7n(*B5mnnp7+4B!ycm+LpOBR*s zSvDj`LIwep|KM#&#-!sGz+5A5V2qzEfPVO@F?P9)RmV6Pek`T;&5knW@}$!A%VflN}VK6e~__tw=9`gof&gi8~)-Cjya~2(#qq^`mL{ zJ>rUkj#gv_2lEy4se&)Fhdt{uM(Ias1+RF{kwI_6p0;zKwP(m z-O^&A;Szv%Z2y-Mf9|FJX7Jwg_9B0ZHmue$Xl018el+eODr23`N>@2u zOcBQIzsWfOzaC%@MENofMbh!)}mNor>PooZ@fueZZ2pGR8 zLs;gFN2HVPl?6Zjq;}*=vYQ*uGu30Z&u7@63*{5259Ord<`aA~(1pBB8$Uj)XNDc+ zxQRjfq(tO$Y!-&}qQ6XQFH;u%x-Unhr^=PhRHVozE`TIM`b(vtvmWssgYcAJuK3vm=IrUznqyMv)m9hWhaahRdV1~hAwapu|Qqkl(qDrTvM)GDvYh8RnU~Bi@rXH zBlp@M2tRv?JScu<(;z{K?A<$>rgYLJ=JAL=Tpe!wfgCU-KDXbYkEqG|z#X@<{}ta* zv$iI-;;f#6$Z%{_%DfA7j2~QPg~o(R{_~HrHoxp_3oQ?eV(s4vk3}F3aFKCuelJY^ z`*)JD+^Hvfp}{Zk~9BdR1tR9Rf^Jva47!EDPB>6z-&23biga$Ktx3{!!L25>1TS z<3Ptj2X1a@90(^Q7uas-eLk{f-B&4679N*6PU*iXaw;IPmk*!uor9G@g@bb$3gb|@ ze&((NB3XB(9H{T$wRN=0exn;h-R&zU7$6{_?tdIPO9t>OQ{#GYT-&_()^rO1L`;K0 z2z~2;^T`%VnhIz<#Z7S)y?d35*oJSP_^aS~eiojYsJ_7)EBe?l>Tk+6nXe{Y77Y{z zheOFy2ZJAdd|#xLe%nyrv8-{ZRM{^pFVrHkVvk9?0I9V3Y~Ft;NcS}Y8r-Kz3eozR zomE)*X@U!|Rq`Ej^1=oehtk=N@byi72=w>NhKbyy1;WWC z$EE(xT-x#hq!Ho|B{)|spT9aN2^H5m-v%Fdfv6I$xK+W)cg5FpbJc1)Wp0yoi;42D zq>c1Uw6y*+(CZ$ujZsPmk2LQ@S`4P%tBXfM3Xy%KG&5}HFF7KQ39;~5@l8>YzE_Ge zM}H*yN5a&zp#7p|0I`?_EEmMFi67&1WWAnt zzd?AdP=I!(KzwNni$(ac=@&VcMM0U?M0FseP{_Gy-*S=Peb=V0{OkgaJ32(ZDxv36 z^PYD$`FjM!d<8b>&S8wVk0?rTwgqjjG(`G9k<)dXC%T`sNY3iLLF?8t*6adoDFvFI zD_<`Bv==F}c~RY0h$+**{D8hjRrHsP{*aKblpEMpsvn+$lwN$p0*!rysU&7)9td+{ zRoeV5Te}BoHv2fK)VC`R>qfnnkB*F9<6CV;@sr(muW?9q2wuTAa|cJ)?<9x80)eyS zMIA6NtTQqa1PRycCZq9wlji=gTo_8H#di7GMd$=kd;PxI=-_`|T-a@CNJ%P-Yn5j# z9#498mJ-)>k=#{)$?OiM^W3W5*?;&+{^ zB~RR2lsN{s0u%pGaSFL0+ zwNnVY()HKxSevl>4}K4tez;qTy^4km6wP)h@-Y2q83>F`nG|qzxD<))E?9d0{2Z9M z(_+?NdJR2zU8?6@L&pocG`+|kDF{ORYjjnR5;LM?yK-(E=L0U4XLZJAxQsinDeYiB zl|E3%s5@Br-Hv3!U=55c(92CXvF~k0eDP$M_+H$pGD7?2y;2gL7y~GJv?Rxt#6*w0?m^-ftt*marB1$+d#~t~Hi()UNaN2frFu z(XQxu16NZb)7XrmVqX5%ow-Aj8;qW-lgMxW?z#-Iv_h~~(3_^Hx_YjWF}+gd&ciDY zL#P$R%7t(}SmZ!ESI+z220ATgs;bFJhYj9Fy5@f+^i|@NsxlA*Dj%vfxUvTh5#?lS zT-S}m~`T5zw;+#lXGArldlzTxz`ZI(O zP)K7&XpH2NKfX1=0iY-sivzP@zs#hmFKvzF1X1KC+`!9%+2Pg}Q}TNelG=3|I$xdw z=`R#6+$p9)WRigrc?{&>T0N`l(i}|ccCxznn&|xQf6*9dw^T-)G-KMIL#5_`cIbVL zSD`$2V%jE&T>%0U9$QxVp-Jm`{nG%pDsdTcMC;TH-eL5XPIv8)6T4-~D+#Nu)ZHhx zv!kKr#FpK=!%&ftL@+cXwM; z?+|U*{aZ@~!O5J#ThEOQ6+0PM9)h

>SI8z!=M1b3sV!`~esLZKsY-siDwnU=g_ z_M%yO2GD;U(egWohAaYsseMJd(QvR917Tgd()DL|_a%C_Xyoi6k=K4*gcjWUHysV> z^PS_a(Yh|HpUS9?GR8>tmGUEup>pydeUdpGm!64$4iOF>`D+fJi)8-;dRIZNk|;KO zqq%{8U#O8w0(`}k@Exk7piJ0=PA)jLg@;UdTaTj3cT#0?G<3WtcRQ89 zs|voFQbv@@X`Yeoz;q(PRn6f-cG9c#zL`h2%w?I1CfX<7il2ydw_LgU13yTLP-)g; z3MxEOxof=ZvJp)4gYt^Qffg7ISGO?fa99{MDAF@~_K)Mm7?|+!%%iC_;(yO3O?2%L zXk8P(BL_;*;FtnA9b&smGq&7R--hrJG6QS&0>4DC-5`}fcHa9}+I5+BRTFOfR;N@( zzi7(!5|mbABe1u<>k1W1ShIU-s*}fFoHzGoA6a`rkdvdK&0at9t%90der3v)EMqCP zJUnIAEf{t9&b+#aZZcJ4na*h$DyNpywO4DgMMc$pc-x5+G=D zMkqx9IL$OP0CeUBi{ao*>-liy_&KnawT zIa?+b7PQ@hQUL*?px%TdAlpaLxj`%5-0(~`o04KKu%)}{WGcl$rx&0-oE;A=OW7EO(b?aCVGzENv zfW@MLosSBd1H3*0IOX`^Ikw0IR4AX?j%~$G)n3|Xt{ZR9ZH+T#z7dilu^A&w6RG!i z4RLNJ8g_$#v|Yz-B#1d(mnC?xH9wqDPc1N05A0eO4LIPKJ!t-;Pz@@lC7S5>_X|i2daZTPao?57rMeyu%0ao64%33fUb( z({;RVP&vRGyj2X2o#iax>bEd0);L+gZ$*$;KT>B@n0`Ya=!6miQEK{5g~px5MgU;~ zCiqx zchkniYATP}eYvLp-UPZ=D(d6y2$-5oHA1w{)|b(#14SMuz7se{?c-4wEa3R5Sp%!9 zC(V;kaSIULu!5o6{HY5we+UJsp1W8NDN~V?2O(r>g=}z2HsF5Exl=O z%;T36k2?PlGuOw?nKeNV3Sv)${7df$4D^B_yt6m(q&_S+G?dL-{d~?gION^Rw|5{6Szb{C6l@IA7EYFKd^y_D_P-G4m+hc~r#R5G|fUkPD z?+slV3{g5o_nxdmh%<4vpks??P;ta{x^rkr37SXo+mtJEu!mMEWbC0TyP@j5#Yca? zJql-&r319VDxzcL&!r1tgViuwN>~0qWGRc;Q+DjHzn&7caqrJ^Ef&hNWQ8qt^F+XmZzq95X&5g1nTO|8s4{6Btj2{|lWGZ9e5Q>L7rB&m*n72jUk> z2BlK^<$cAwkp0(j5bUI^KrIS7P{hW5pVc*oj-$#kFvLiOxxWN`{+x0_38VKaQMaxp zoJMv^+t2yBMN~WAx~U0b*V=Eg2P?A{{%@v+TI0 z^!_L%Yico?rif4k!1%N?N!wOs7GWN?ji$ti(_fqiM3U#{baNW~oUbnP?SH@%Tc~oI z?@G$ukee;DOSQdMz#`Bbsjq@kY@YiqG7~C+yqd9n=QX6{!)?r*7PG-FlVBXB8y*d0 zYkKLu*QKlK`>)85127fv+hLE$q0GIiuD2rxsw8$hg!xlv?=9AVXQcMZ=FdME2NY7p zty-pBGFZ*((?13t97wRkZqd#9yzOpMcP$-lGmhRy3W_vmcHxxME{tk3_o0G9*Wcb3 z6(Uj!BQkP`fD)|ZgcBtDiT+`Tf+W%z32O8Hz96|2qORqz45Bb}Us==To!{>v6~a+XO-kcNgAOE~?? z-eP5U(VPX#z?$9?#-L_Hz<*7B<;p=hY(pNDmkzud_j_~)Q3dPg{vqzBqX!uZmWC6! zdl)uQ%`boO_XbHd!}!GW!#L)(itsV+^WC3Pmw%N%N0m_auHo$IFEj`Eqd}oTF|Az@ z3=q?~hA>*T9uxo(t~*C0`}y5>N-lq=r;||-I4vVFK*AcjbmBs!2L?4#>W;H$A)#dB zZhT7cmXfQKzlCuhuf(^&{AhNu*1U5hl#}u{&fE34>wREB?>Q36=ItvOjbPEemsnkY z=(|tOc_O1jdM-;zy?;m!o~P36mOLdgb^&MGTeXy4uX{^>Bf;mJQ=Ge7PGsFg+kjpz zDYrV=uIVYpKHMY-Q{rg0o0q1%pK0fn@>hJD7J=j8`U1dT1$PYgYHu~U3?-^z_bKuR z0+bTlM3oac&40B=L&R?8(T4~FtZHfw)!krGysZOju((j{?=<`;rLkf0<;kk#(+u}o zSjg7@z2GGW0x*EQ>hscam_H8c@4x*?OcoCZp{?$Q|1R;9uCBP8Pw*2#tucqgqcnCK zwh3y<+D`qm=)#%8!JX*tvsi2X=LJS9)+9mOFnt%V?TNI(`r_=D&^E_-NDs_6GD7!G zbr@^3SgVLW{@3`s_vnUq|3}f8KO~j*VIK~9j$0hff)<5Vs4S?dz&0qGq!la+tQ0Z} zTE!i50WAbqP)o2)v{Ew@)D*N#$V!?`s;8u8N=#>DrsffSpGkbH(U> zRMcyc=F=Zz>W1{1{(#T@(L9K)TWKP1$ANsG65~DoW{_a$;X;6Z<7V!>)_SHN) z9;73pJW5}9t)I@-cobGOh@B`qV3Fl;=Rkf=?*1@5<_tmBcQ@(LvrvQyo7v+t1NUZf zK*{;_plMBnt%UrSxsWlWQ@i>+{%~<)ZcX*LGk9&ZK1qAoNbcKkKIXUF$ZL_j_iF3A za^FBNvh>5$;HOV5s|6n_c#7A3eZ>hU@fFZ-d?gVUrV-@?CGfh4_lEZJoc;Y74Db?o zp#u5V63J!9V5j5CRZQjZyG^?o-M>}i`ETwnj~*wzt%S)Y%TUE=Er(x|y(*h1(j1)V z52XBmImI2tla5jA2k3tdstgqf^ zw1dU~&|&vF72DQo6lfnV=*0m@lxq5P>iL9;174(ZwecJ~bi!+bVk;26$n4F-a3&Ju zX?IcB@H)qN!WuPeG7*% z3N+fIZ(AwV=26!;__XIF!_UtS?7F*8Q(N0n?3=0c*5ilDM}2g@zQnAQge9qH73R#i z#2KOf(P^b!0A<-TR)7>|sUu{l%hfZ0`I|XXhVEi-Pb|3N9KP(}oi3K8GwoVU1-U-` zZs@>8hp|X2@x^j_fL_$_+cHdk?o!8q#VUT0!ahuClBZ(|WrLir$ z;2#|8M`lHD!c*bF#dIU+>u>*K!3+jy>qXT@#XSS!t>AX#@1Vl8ta`dFd@1ulEe`!4 zCr?sy)LplXXUlTQO*}u9R9Wh$L?IG@58)S1FzKonZZ*HL*sz)m&vDDnoval(}!th^iz4(f)%7% ziy^*Mk@)v^@d{TvrY$^`adi`~LE8=*6O-s2xc>j~-#>s-1s!OEf!mt+uyz97lIrYo z%VZM9vQCZ+KLX8p&c|PIdvQf3G|-8Az{UB9?GMmhN?Ix0)!_>FNDF_!zAreh8yg7! zW%7kuFfoTA);*V3)qQLkrEvlGPHmpdxpO^YRnK?hGknSGPhnFLJ{*Qmh-^VFXUY_? zJ$54#z}C+{J*0JN4z8P%3-khYk1XJyxZO%QtB*r#xGXUX>930Q|1si6eb$5ApR)xo zJ-bVNq)^wB@R*@br5tNQZmH5(Uh3$qn7%?=hAo>yZB^}Re4`RNe=wBac$D22F6IU4 z*Po%9)0K*cY0&cJ*IsuSu{KV~U7b$Sq;9Tr75v$4xJSfN^>2=2tC)>yKz9~vX;0N9 zxEftxTPhoxGP-t%VRTytCBxVb7Pz`D7-$`!F$b3mDxB1el@E&GcC{f7Zl~BXY#kjC zIlq$7#y3hQ&8|xH6T)N4W2NZDRYea3s)ielRg#CQ_h?i2Wek7o@9SaKcRn= z^7>@je5h8#87y1TQ-sG4DIImcGPYma;&^`%|KXV6NeuqI<82XxM7owv{Y}w(zsFz{ zlSzb@_@*=9>3DR_n`N(?Pb+v2lbs=i^v&GPM1j%ta9Q-jW?W0xJ^4Lm>-~baIuO7& z##8SO1F&vv*;6N*hH6W8I7DZfLZj?xqXPpN*U$==^|x6;!}%=y%ZJt$kZ=z)%KEQf zA0jE>dva{3m~fB@b?;pBHvac!}}q)@-?qYAScBCB7zWKMo#!ZvLf=Rof$u znI+?3Y4q`F2*Hk}=xufYbl_WkI1p$Y_n!N!rDwkbVIz@1n(xjPYPn<=p=Z`;wcIS} z%boHhL~a~^k!Sm{|Hqp9<~QML8)wkFo*Uj@s2Lx;``yU}0{01c=0y>aqyvm^3jy8$ znf|j((Ipz=7JX!4b&aPmXU!Ipb) z|F*(stru+i$|gdy?(l~(Tnlvy-%Leq>VJ?HK76|W6ms41I$!ilVHCVwo%I8WLjPr(u7tvD|)2rCQAxH|%Q`H)ve6`z(Q zr{(X*3<0(Y_0Jh1+>l zYywjcgc|@~4Zn~J#`1_MmUE82mR~=Yr5kjo6?aB}hI4TL*YQS-9&D!E<>LgS{UiP8 zCK}v$oOFVgRI_j6H!Z5Uwnfs*eREvQZxx$x%&vx{eUa5a;o%l-s|&b3cLd^{)87L} zK0YmIb=YNO_|4d96#yC}xNHP~-O!8s9ac9>;d?pIqr=n16g{cGzH4H1wEuQ*J*@>} zG(0TLa6aS-9>ts7Z2S7YGJYfX&!_Q(Eg?kjI&gPv%?#TXhX-Y62*L$rd-8#)lT#1F z8sTvWBI3PV!1i1(SG+HV{`uvX913NXs059}-J#Uhn!~NQcj6wPp{{oL^}q8swJUpd zKV*vD7D%E`66}`**!=34rT<{^9V)SPhDp*_Nt?PIDGJkTtf>OvWQd{G)x z*^KQ?Au2h~4A9+VxTiIZx_t3g2L2xS=BH^m&`^n|-jf&;vVIr3gMHG0IrDes5mweYD}R+6WYkj)J! zh=b`U4-;C}acJrU!`r&mbJ2GSfk)ZK?0X($4}iBfC%8Snv|r6-XY{56y=3*|Bg|;)F^_vZCNmD0^FGcX_ z)MUxOW{#^>h`)=zeL|Gkxzu$FtU=#o)Kq*HV<&6Twe%CLJ3(8t|5ITJH7BPk2LFz5 z=~A)!)T!nT8xk6wg2rTWV+#G^#s4Ixuv$gw?-p8u8AcWvWt4q->J#ZQ74Rq2-=G|2Jtnq}4p<2AnjY)|hNQ7SKRc4b0(mlgA7@{K~cwsYA0 zEAcHyLK+M1q`Z>6qrES%&HugZo`dMdS|reZ2)DS!R*x_bGNOkHw2qcU`)QH+EhEGv zq?{q^PrX1aouuA5X%gP(q-G@c+?doJgR2NNlv@u4;l2ywlx7T@iB9K$Mga{J`ng(Gb=5Jid4u>~H$Y!!J$HQ}@uoGxd-fQdnP-uI` z4SD*iz~1w!4EtrJJc{9-GGsMs3`3XU{}ih_mvldFO{?y$$F!w9eLOqT)!D1lg}?TV z`K#u*N~t@gaiQwg*9%;CkHa;fbI;hrTaugTDuJVlc>}x&MQ39B+~sn1Jl;g^66K=n z(6zW*XY9ai%(|!b@z(ly_;!7o{eQJ*&SC-L9pTi6Cv(H`mBQpWNS!8NA!Ed)$~H*z zAik4+X-Fx>X0hb0nLGac|D(bC(1lljyonJBIix2M~6F*XGm{ zIxixNopvRCG=gw#{Nea})lg&onD95}E7G^)-y+7z`NUu4190YiyuFO|rqn2|A(IK! zv2rkGFt_VgW&J5~Q&&RCruGW#U0g%$ozw2T^Yo1b>>X-<^DkrQ>f=}~2vlL~&bmG? z53kWHYbtAM4gc#ZykWR5zZ?f183!s{^RBxlHE4DGMQ~kj;QdRumnlLSrPkK0?X;0l=m7zPOiE3THQ3vrEZ#)7ZWFOX3L7#>v^fsO!wYtE ze|P7IFJAZXJcIKP*F7<}n=t%HiGLugc8$IjJng?F*_*c0{zkGGuTfZbwD}7>-0gA{ zfcI|HM>>I5h53e2 z$^zz?g=dU}UoPy-wSLk5aAB&&VadqRaBrU!-NoqO&l`1XP?AP0cqbu86w8p;F>8kf zn=>BL@YEZmn;?)8`QOiIeC=shEx(%f$!xJ)XI|!3@YUdj6E7c?rRC#9GR4sbN`m?< z`{XG^!E-r(JeI_LAAe&jCZ_MmdYqVEKSDZ6r3p@PPwQtJx74QWl2?{jUK6McpDMRFs|L{rE!f!~WHi{18 znHsF<{P=@BXYuPHBfgVBc!<6~79X$6V|7B*F0@ITo|1rT2+!(sb4NpG^Ip!HWs>`I zySLKhKV@b84S^^jz4`$w(*RhAz6fv6lr>5o1K$1Sw~0FMarEd8t(YCZLqFM*1Fd=D}BIsfJN>+M{SM|eF|stm@SD@wWnSOXZ(&QH=JRd zX1$FL-EikLx&Ac%Bu_Gc!VA*)nwyrO6`exSDM5|u-?A<;UQ4-r46h=j_!A|Q=X;kG z|3{U?k6GJQ8DZX%`x)Gc+uXN~eIx%AlY;vWy*@ZWe;xtgNDFDRcAfyo_el;Q@W1rN z$)&pDz_EdIcEc6+tyJp39n)unO!y#Qn;WJ`%p?op)Uiv+-x%!zpcU5=A^+o}AYDjo zX6-J@W$Vug&ugY<{PK5)!g3$5VL8rUUZC?tdhV5BQD02;0$t5!o3K=A%7M~AB$DB+ zzq@LfrH_%F>t=;SelbC)vTBdlCo4u~L%l>mA z{7ZrA(XMN*0ZgAh0ZcSBH*gB#ZNz$Eoa)^PM=b+if0CE;M?3k16mM*gBgXS;?3^l< zO7(zSjo|`vK(z1!6npJBS$WvylYIA8X4=`U^nF)y;&0%>Y2R0FoIY{Fqkk=B<@^7! ztCS>M$aD-A1HN{nv+i}NR~;!{*qN=+>e2?|i~kW(#({R( zr_C8zb<(zTbxaHXjnSB?GGq~3GcGLr8p;7$Gl;zRsX(Sge@@gcm*$g0pa*as9@Uu- zG<83!PMKt$XU1Yvj{VJy2o=~;yn_A$Vd3AoPwVL8CIC6=my;+}&GY+vB60p*FNB{4 zqIU-*EJ+ixcP)6dv`eZ>ay~w99hyE7MZf^uuE>}l2GTm6lZkZ=?t;n}*3}D%)$#P- zB?FZLK@DCHydha|^g00xU(3fn%YAPl5^o)MmT!hJ!R`Np7J3^Q zEJmN6OxG#q%-Xbnq-3~)Y7#B%vH45y<={~ry~SsdGd@{P7vS%@GjazXdb3^%&%vHz`)5bg6eDRSk(&P=vhpsWpwR zx?A>n#d*}QeGCg}1p?KLW8K|@tDu_-eV2DypEizs<2YPRyLv?b(-={8Efx}1byd!G z3})c2kTfxq2PCN*h z?W!O=72FVP8lmGWyAo({8F$$4^X6{8;7%VpyMt?J%Hp(CX5SL))i^P?6tnzRj+4p8qEQn&TdSAmfI2FxtavS1StGdXoO(W?&;zmnNL-%7!tR zNMm)Kb+RI{00Uz#!$+N(SdY<1=`O%fbm%FBpfQSLOxKQTF(JCp>Z8V^Dr3#rB`rLx zu^RrZHuTd}Ed4Uier*`2#K6VrLg0$7yr)!>i%DIuzZ!+%jqL47O?{QSow=opTDf+N zRGY3_Imfu0a6L|hanUhN(1huKF3%1sw8knuHwHF z6IKX|H(q%2E{G^2cEI#daYQ&-iPj`8&zzuSa1ZTN?3(M_DWAB#{1y7(MQma4RZlHv zFlSm0ehzxN7UTcDnX1%|m#IGN;|;W>SneiSmQ8x##=CN;m9g~W(I?U_AA!||n9L)8 zk7*d1I8GV2^667wo+7?L8h&-Iaz>-^sEv4C6>p!RrBp;uU8h{gG zyYr!odkuY!f7wvcTe`n*sA+aEDRc7FddipA`C(lw^)}l2c{Rgdn)@l_+4vumd(`ax4PU^^vQ$$N14aRWYY>OD`F-la!u0aL~PZa>zO&p-}sd$Socz(gu$zWDiFBNvtO2I4t*UOZgRQj=T~E>fZ76yNgIF)8o#H! zSGj__-v=XQCU1)8W=2PMMM?G$wp51VgT8flaLBV*%e$7cyW-J;C1?q1+02tV(JzcO zmUY37166gW21j_9Ba%3@?n(qk*dxIe8`Su}f{KMFiMLY~O_DhYnL+M0FcT|TJbhBs zE-`j>NJam8<&g26A_Jbat{`U$iSdBe1AiwPXz{i3&g#bsks)86)i?S6_lVS-%3nsieSeUmzz#e7-MtZ8yp9%Gd9 zJbS%6rB#Y59?aR(_SAAUhT)bCRbQ(Bq}QnxbLe}Af!gcGZAUt@95wF8Q0W!bHSXsD zNU7l(OS{yEHg1aEt-si->@Dn18K`MsqR$$R;;>7(2g0`*D0B7Nf{uiO>6+y;$#X-53I_)R^VD2zM7P4|0PR>`5IR`v~~P|%wQX5eym4YrR43N*2- zI{o%}off@>V`W3`}}cwILRwt z7Rj0c({V3Xw@N(y7+v#c%=hORgEp41|Cv7B%1euXmdBd76f<>m>PP{M#i&M#4_hkP z&D)r6c|(k;KGAQ2cAYy_$?@F(!yKoidd|#ey_(86s@!XzPB*H%!V`@EW6ZHOQCX$x zkiLYC-n%Sibho}VzgJ2~F5f(}vi68_ANu>ViRA_J^)x_5fD2Z%M7lQ&Y$E#GioQPC zrpE0;@8qP%;D`({^i+a-b+v%4w0S);nQn+QYLBn@M~jA0moQ*$|PO&Pf51A zF-!EcA^fRcaWBjG%?ZS^vWURFOayQ*cji71EsfEg0V|&<(JFR<;!EF6y_zlRIlNi5 zk+2*yE@cB=gUIYis|P~uhddl^zF_l&u*|X1fsruvi7?4_i&~A=Qd-R9G$tt0bf?3Sc}9$*MOJR?KvT z_9T=ybZ-o&L#jP9+fOWG?~Ur?as>+X@+;r1>!+O$-?}sLalu~fQM)We_fJ|)%9ITb zVOMXMGCD1bA~O+bEmmayuB@fp4uf*uzyp=&e!d*6bt_u3#1W+wVhKtOkp(($@)aqn3%+ivQ}PSdvhm_QG43oJ+a=aW zrKD&p0#bvkzsQK+L^~ErhnHjW3k$LM1@ZIw^DczNT$hB;=3)$4#i!rR^rR5{IV%FW z15Zy|*G#UNNe>4-a5UO>K9l(>do7K7h(L#^+ZKafM#VkJy_zsnCDv^tXvy5z9koHsyzrr%e+r+dXzD%@Z^NP+a%ncG!V?byHVii?7lZUGJow1a zW?Y8?J5p@1dfka zChmZ$*`XeHcRGZ@_kJ=Cf4Ee)e-dzG7l zUEi%-If}-GD@2Kj{2u>)KM+Po6e*rh1E+%0<~y$!Bjxh&#o!Wl6$(~=N7z!kbLse! z(Q-@Va^rE5J(ojINLZ`Q0(19>b5Q?UH9UHcPPB2^z|AS|)=YhqxFK7FiErqo4?a-?#J}noB{Fu*yH>D(&H-J%W!9CjR6p z!NTzK1R3k9E1;bhg;jusKmmT~*rvSjLN=LuF>p9NC&s4c0koBCN7w*}x^_&#SJL0P zbIl3B#aMiQ20rC{By+)~DRgPPc*gc=g#GvUX>Saa8F)-Og(fA1-~b zu+v*Io#u$Y__rxt?cn1?uYozedCrM2d$n9Mo_0vFWRbIGy0?_%jRHN&bK($i{!xU+ zY!&*hY*{H>(7pMG;4kpj(CC*c{}~&@SYn8d#4dfQ%J);vmc!m;@ldn_Gl!?EoU=D4 zIi5>9otBun{fGjS$;3+|MSmxLuM!j;WF3Yo|JezZO-43qkU>?QQJ=>DGxS$@qAsg4pJURh;EgDzNJzbZXq`-JZ2Q=J_>+Sw zXu2%EIM$;wihZbor8aFF?rPK&gYLz8Zsy zoVDZ(DBQ;*5QG(e8@mCfH(NZz=LS|Bs@CfAW5u zLI+~dGxlBoGe>~X2L{@HKXC@5vWk};x!Hw;r12B!^S(`<*vv@fpL>pg5{&9>VGR1= zkVd4^md6+eyzp@`iqa_Tv##)HH)psEER4hx=iGSO2VCSFg4Dc4K{vjKA?-2apEtIW zfg8|unDgi90@lSct~EuT+8)}zOBazwshPa@XLp7Vx2t?4^Ot5|CWRNiA$ZFFY-hKR zViH0nBp}~8(1b{b{`K<)Zjd^agV6>7vLim>?RK?}x6P zO5D99Q?E}KW!R$!Cl*rN3JDu$uUN6EpJr^%y5I~UJ_Vp3n(Oy0h#;}XGi$;+d| zN!xho%%M=^q$4xJmUq~`g>dWyc-ThDSvTG%nYwsbQ!?-jKU>k`QMCWk;bpUx3muM& z*>h)(Y2#pe&=LMx`z0v9>rB_Wetu>44)s1q1F0&)3mW{$RI0}RK|rCTVH$rH2Ekft z)T>4b%DOZMNW$bORA1s3`%Bl-SeAudzm1;^>6NF4Djechx%ZBROV0J=?#~~cja8^? zk{sPLdV)30dP7QJkdy_qWjc%u@s8iuq}h!>r7rr272_SKikzkS68#0%Z_m&c$AbbG zw`Oo4{wAhqGBNzX7GT|Elh&<%EGjwJJ`8wzX`JQ2t+H)(-+6i|tVTe_**r_&>-%SD z2-Vcp13de>2A8g(dAd+~88^t^K4UU~7Lm6JeUQIXn7MJ*fJk4N(SM;zpXir%P*E5y z+CAfoUa2j$mcCdg$v&v?EIv?I9u4O!W6}=M;qn*@>i3CDmFS9CqxQ+8>v1K~Cec*wlM_PJx^Qa)QwfXDk!?`j4{7Ls$>!@a?dP%Lye&3$^9q5{$Dj9Gvv;Te5g*e0q2 zTE&3(Im>lM1_IC`+i$w$NL>vK-FB%DbCi~pMvt8uI)~rrBy2dsz2J_olWxd(hs}I{@(b7W@^fON8hpF_Vs^v zW$sqfq&P|9{~asd3u&VO()&YrcF|!sUidJJG*-EiR7NXha^?lDM5@&Gr_G4DjEm76 zO{72m2piBI(;gS*4$Wn0x~hqf=4#auOS<8IiB}`ZN=epj{r89r(H1bHqT`Cn3Cx16c+U4_Jznv(BmXXFUE}fzn&rWXMiTlD@~7 zJAL5sSCLkouRI$;rzdqHdgjj6vXFX@Z}kAn*Vo~>&wFdOCmm2NN&H4Ida7j4Ek_lV zD3OdnLHo>LdC7Jm=1U3DFAGmy3-3wBWbFL%^Vp>E!d}cSX~C4redLeh_MJB^Pw}w8gZ_UID^_BcqA9`V z2~;R&sr}6QE=A55=VUzY+^{@qcHH1h=au;N0dY4cYn9;hYfqx-27wX3K6e=3W^FqM z$H~@*X+<3Q|DkLrVt}yh@0%<(a^20v*;?9pVOKs1={l^h<@aH`6$(ioA9rvoe)K5_ zIPEA;MepPc1{&?Qp)-IH4;&Jp?)dC=tFp$^4nb+pync0>(D1yhKf_#D@=EkhQrsq5 z(nlC8WjZJ_0o|X>%-qS#=fHVUZ@QJcjB=R%sln?5PYv{=?#hCGol-?%<;?1UB%V}b z0hPgFu&@%xS+C$|cp_2fI-EZ!+b_D>S2Yit;4O(TF3g-r@9I0i4VjP6Ht+943%w%- zwmz~skSK^=J?)9Vdwt(IV`FnfBtBiYgN75f)gD@2OW~)T8VKY}bR}%l@(Wf4U>-@+ zsuHB4JU@%VD(s*peZ1Y1E@(QQ(Twlr{ zcjj3~6M~-Hm+6brG6s&UALX7%JA@C~+P;9=Vr=hR2On6Z5xnZY>H}&#oU@A(rr4jx zLM*73;iqzD9o+8H`N%%yn~)wzm!|Mb(^jmT&k_Jt?5eP=SFx15jr*$t&?nLHl$1vU zLmpgtwteehY3O9X5DG-7p4V5VQPVYPL33RS?x$5@`Z|Cq=m<~9C3Lronl&Qj%$IpW zt2BM_bg-RlYxxi)kXzexrH}FxM*Fv7jo_X5YlQqSb0T&!h6nL^Wz69+%o>5@M9Zuw7JQQ{7737CnrB!Wh~;@ z*&m)FmF}{w^-%2kcYY8*+J1>k&3Q%~D2s+PMdt8{Ni~m!tYAFo=t%{p8~}VZR^zSm zx0c4R`emZ$RcYfT=o`3e7z90)zmt9l+_y09PSH}QTe`jY+OZm8h@(5squB#efF2u> zii55Na|NqLKhGl^968aGt!hy5Q`54ziO-`Q;+~vCysKxOx5dQ>u}%b=cAd0^aXk#u zo}ju*hE@>OCT&UK1aEN1zrnoS&+DJJl8u>`ipy`}cr6lQPUeo>Um0qkOKuzdx(KdG z)5Md8{USd-JsTgs4D!JT;Bx91Bwv0$HlfFlj`sA7x|ds64d}-Y>=@!PAP8}Q?!`Oe zslvka{j1$><&&No=2uH=C6Ia?w;Hu@{v+}B&a zi7m?PX$UVuy7zXX2w0sRTyGP)0@wpL0b#V?G@jAN^v}v*c%S?Pxo>3atblO-dW_Zb zA7tM-c^UsoWo1sFkEKyeT^shtdI72p7q@fC%sMG5c^5R~PMf+n`_htIX_gVjK-4z7 zfJa($uSq9iNueLwy&hT~b1uA6+;ll>)R)!S+=Cn3B%?{`?AZc<5liVk>-6&zg~t_{ zy}ShU=EsQ^(JnW;hdx(2s3;Bg*G8@$xD_p}OWbC19r=BIfK_?OlG&O&AVq^f8bDl+ zTF7)n^G?V%jb7yHflD~SyqMKOjm3F6K(~@;B~L^`N)+c(ti9l%2MuY%k7q=nmmlgB zRS0)T_^;+E^9~#EO>)J zGAlcHw&inC+pGV1^f6>!`rqv!3Z>`_c#rrl10sxSZ|)esmm`GtUzLm8{WBP$AZ-VOl(f(WJ@ZyHgR>Aez4%IKm2sXPI#AazzL zB;l3H{FRofByBUVO}o0AIs=``0nfd)xV3JHTF`-6(l&%{R%qZN)2;W?j!a(X1;$O; zS8_9si_%Uu^|rOk?A?V{bAIM`U29nPa&6@bjTs~*MpBnk{6`DS^JY0c9~a|raUxGF z6zg?S1_?N${wtL`MU0utt3diRP5&M9=>ZsKohBTmZ^oBiWbRy|2m|MlV-_&6vtoUk`+Y=@*_M*yg%c+1jSKC>7&PoFX+d`gbefmaqv+V zSIThlR&F-OUa9l9diWujXFp7lkw|x_!Y@J#pqSmdEE9HfeXOB;Z@h-Q>BYkX6Y4mf zXz}o>$#@O=L{B333@P4U(pl82u1@;hjMLCHE#j$l?~+qBP0f&I)}wV>8L;q8ZXAFI zRB(F+eQ1$G^YHxbbYh(-NL7NM%RBS5gZ|?8-B1y((0E&v&BE1CN_&&3e|jnjTSRc5 z4`P~hF$-C@)~(k^-B_7|Q0*$s>z>c^^yZ9ihUc9h|8gBOl^{Nx$C+}H`28A7DVPE^Zi`1*17fuPHS{K zUvSl`JQ!ao(eb{g&NO{UyyZdEbRiI1_rwNih^P-siw=@af!VW=L=%DzkY(O1Px`6N zPcD5q%*%)nvCC<%6smJOO&22RgLy$D*vP$D8d%k{pP@W-G3>7i1Pv%TBx1()%_fqM z5KBw}0K_mJ5pH(W4qb~iUJ=n_9A0l3tg>iZ-}$WciELI~3Qa&cuq-ogVv&|W@EKb8 z9>IcmAgC()b&1mndgVMS1*FDXoT@+vU;{k1pEU!%_FR${LAaa@=hrE-0w16$Y^ATqeuf3FnDKD42+}W43*A);Tl{F?E zwO|2cX?ECcm*R&X&Lf3WVrut?9>|jBhroh<;vG@5@RO@n%^w>>a1z2Z`lzcc3S8k4 zeOCX?S=J}v*nSVI`Pvs9kaqwZ1wC0v%P#KY31b5Xim@e!SY>#Y`05-*DZVtC{KG_J zTN&JSIhs(i>=K84m0E0jbDRLds)MEr;Z}3zZkJU?gP-usXVyAHXH8XMmOjQ!hw-i5 zJN{6q5dNnYF|dKprY%oobhDm};84~e6sIKk3JEZSU!quYDnhY zO>;0euQBtQsfOGuKT6a>V;(j)q1Z*auL6r%BiY3tpQQHE(Rg^}4`xpuMK)Wy*9|3| z8Vo@(416~;mmdUB729>FKF9V2|M3j8S!fG`5I3iR%mc%P|yD)$6l}7sRU0K4Fy$8JlvwrLkh&u3>aS)-RWF4+o3#&^&p^rJhEHDI;<_y%KB|F zCi(8a*KX``a^$)DO%Z1ErbHWE4Ow z0Qp=VHVqvc-d!X#=kHj@xTNSH4gB_X;S?b#2s-q#2 z@Q2L`jYHJ@NwfC%reqqR2j(0h33U3z>b`SUVmxlH& z9HkUQp}0aHybn|g&Px^4#pNVF=RxUFRq>lDS1Gsa&V({Z z|96#|tJxuF5*_|sOcbNVys5?{5jH!BCp5s^BP-B6PE%4);lcnqkNo}vld8ieQF%>r zWda)3onxgN+fwY=t`=F?o1ri~&#gDae;GBV)b0*-T@Ysu;`!d_gjK1pCTAl}+t21~ zx@$DTa4Z_JsFSdd5g)NaHLY{Pn81}D!pc{W$=C=Loa$Q+yrAwh5CnI{JT7q~6{6y>t=z$|5a={Alkgw*YgG~&gMq+`lxEH9}o z2^I8LsM{IJ)1O|xxFpG%2!~Gpuu#Af(z7{XhQ@QwCUzJaVMjxy4{u=ZW)fWi3Pt*D zG4_zU^KLPNk2VPh{DQCXU?dMf)r{tE6>!n$?@0exX7c93symjg4dBUjODa@VwDPFOI@4yt#ppXJT?x z6vg5F0XV>=z+~IM>`;v_*LZsi(~I)Ve!fl~G;=Uyo(KQ{;muEi5UHn!DSY!$ZxfWK z(7Xx`<{TsBKie=TLRn_W5tN)zZz~8iq`B&b79j1tO~Pd5Mehzlvc6d_d+TozG}d{1 zNepFU8M;h5u<6g{eI{xh`p!9($LFRC$lp5I171$TZ4uPDAuE%N!rss*`9b=sa~7 zb(uWnT2!{%LI=wc8}8yc2sdVluI%b#V2;wV*G+z3c5`SKo_?{o`SP#@Y$2q zDV$c>fbd^$e0zaFetc)(neIv@ZH>wE*^bU1+~_RC6ziiKt)Ru&QxWuRNE4wv{4pnS zS|3wzUN}H}s43j1$&0kbGQvMxIH;k9>f%l@P;`L$WY-=YN)^=+WWHuS;)1iu#Sr%Z zK5y@)zcTW*gk0u@D1FHl@lqUbIo?vVel6_h;X*P{tC8C+FfyQ>O&8i;?F~KBXNR(a z#dPb@@e_R+VD9ExZjaEK%|`uoVlB;;M(!TV!IGO(tmG0{1yxcBz`VxfeNt?)V3j3Q zqHIcqsHq(k)EhcWp!Yevs}Gz+@s?(tiMyLczacuFnfwiI&xe~ZmlL-)`HHpNadJqV zKI2@B&F* zbkrlr3$Ng86ro~62E$pPr*P5pgaLOe>nYe6vlCMGGQfkQIfWo4u_v7w1N#o-kW1o8 zg@e_j`4QM2IXCckBxDufFxc@#K*7O--2CBfqyf*q!h?0%2h`G=QH)A#;lZ$V&&s6VvYW%8hr)|%|R^W5F3SN2Eu`@JHu;2 zHdT~D?R7W1($=KuS$KSR`^!~&7{8&aw?;CI;^x-WHH1--n$ z96r7WD+6B@&d$5QD;m$=t<2B2^5nKW_dg+jKFO zJeA9G^|#@mcqucTltqZhiIT;QlL>;y$1)d=c)_Sm{!8*vL_CCwUD@IZQ)^^7@Y9E#U~FHi>z#SOxiN((#%`|*eVuH%b9SoX%numG7h+2SXG(Y0^VXLIZuv0rS$BfHR5x^j9z|_xtp_y>5bSnvE@yv79HrX ziCy~``_C@psqh_W&E^6{UycpCu11?5>5%QwJ{@Z>j&dpvU|TB)3pglO(UX$sM5ye5 zxAQ&ARd}eMkWrf|%MA@>h9|{uSQhf)?RFy_w1v$&oa<#F@2*);;t~`GChrlszc+Pd z$uT-LcmbI3>(G|DnAunrHIZs&Oa#_t9fGf(HouyP65dO3rfl@8m`zU*W)qPa)H|nm zK+@1^Zu42r<5Co?JcFet=O@gYkKI1?=bVuyC>=sIrf1fQli}iFrK_$k*$!2DO4YY9 z4(vh$^vcU_Q%H1hG3xQKro4OHokdN0GX7)N4gZ-Tu@~+r@Wm@{S z8If0Jn9d&B$|~*`(vm4&134@4wI?#G=O?I)$*}L`-y__m-mod@giUvrrx7-Vm_O$x zVd=P6YhO`Y@tTBz33GEMnb?$-ZC<=a59-NTgXmkdG^a}F1@r3EWrFzKa97m^#N91nt)$&gE7qsgw%t|CzH05R=zdK6wXOX4YyOzOW*#%|dC&X(dOcr) zsRNs7tRu7|*{-LyweU{RKF@~h7m&0@%z-SyG&1jENgXeQR#fw+jl|ZL0lEj}m=so4 zK$PA#A2Mn2&OtH=h1?k0iVmIpC(U7+zJ3N@XJe&*@Q7^)qaF|I$L(G4mtd+JL3TxJ zSD2@Aa<9$GsP$~&jgXpwAP`dRadTLzpM-8fz`kck?sEEQfV9@I*3>727|g4R7xE^- z8|^uS03~>{Ghjj0#Kqh=d3J!$Zp0~T7Ir=u%=xUYA|>L7dTCi1*FG1}n61r!MNw7{ zAQGuvr8!5la2dUsl2#4}gg>Jl$uQPuK-{nG{yja|k*(^Hs^WFP5l9H>29EzukYsZ? z#rfVS$tkR{ECp;CAy%^s#y8zt*PBBnh=u|`UvTpJ}bd#s+31)GpD0Xav1hHsE^(A++#@2pkIF4|3vi)KN3 z6~47wbFcjKedkqu0!i;45ddNK4oFn{Np}*?mjl9kjf6o1i_4hk)vvk3(6I@sgHWsy z{J?9RywOhY2;9HPUDw|+=n|9LO4gj3ME&)}&BLIajJKyC{R70`LQv0QSFKKZeoy@t zfnHJ`JBR8>p`mz5zr}td?2Pp(q;ro-vPl=bKv1@ooqXINaiS#7 z1cDyS9uSM1H4lyyau+>4(z{qNdf-HF|EccX&`V(5^i2U5;6KlcqVEEA0^l2m-)04z zq%B3&q}wKVU2BILYAN-90q--))YDN4YwFzwxkHV+WU}wzEDBaFdKQQe3Y$cw9y`GP zo1LGzWkFsQDpPb+R z_fHb$EaEKVhWQAzq3cxjxyLRNGZ6(GN2>p)_S@x2(}V3NID>IKrhPFq^73c>Y#OU zKCfo)vaS}K#6IW0&+RN2KSobjDV#o0A{TZGv-54f`oQ4!#P}%5=WO`0*>C!sWI7J5 zbmL_i)`TUXF*e>&fO3)Odby#S$D1^wy~XDc9AmIkP2=iJJeeK4;ap1+sX^`}LJmyq z#9r8S%!%@mf3Y0fE8scem^NcQEjKae=g{1n70}H}bJV4y`2;rVRxJVk{el38y1fqp znC|F2&c3}lE}v<3j}qCc?uxNrJ2E}XRWo1XA3a~&J}>V*RDH4`{>=-y!aLuk@`PIV zjBvf`@Xk7t(&zrQv$?0x|9;7WB!FHOJ(nJ?1fvkKG2`aVjPt)geS|X!vqcE#+2LbX zWN4a4;BlKjwJ2Opd1c(IjqV~#1w&X=xQ8-E+TCYK9a$g;BbgND{|a+aDpXsB4A}hC zgQQj-IwY2DG%1+BuGkyC+#xvmbG!V6NjQ8|(M}T=(dyE`@|UMby#Aan?$(9>b|&U( ztWrYI=hQSbov3q_aS`Y?++>!~fu!l|iy>k0YI@AzcIaFB>K(zpOaaXCZ@!%$AaNSf8Nl z6PTKkzKmJns>bg(ybbE%-KB`mth{bmXgQ8)%HxKIAL3XOj2OZQYrXAM5MpmXW=qBG zBrRzpw zC03sni28gru#H#LGT^9?yVpHg_ZU@|PcUeH$9QY|F!?J1YiuCJ}m4&%`2Lf1xHm9?E5 zg>t)Xk53C}7V9A!50SlWt_mGqV z5T(Ol<)gcG+*-1LX5NjWc%M+PTq_ObVD-3_Haz@gd37~+wcd7I-OcT5`f=A41XqGw zJAAgg5Vh2?oSVZ{i8=B;bc5jwX#Z*{JvkusiG929oc_kq(V0K=QJ8|~ilXVF0*Ptv z8{KmDN%W^to|)!@SYMaxP@(76)&^eTwG+xcza1O6N?ERvV&84=Wot+*+9e$aWzM+c zF*Ts!!=xJT{;eDgC_*-org%&g$OUR7|8OK&!ja#`+?7gs9`E$z`6%`uN4C>CTZS0S z;~Apvy`PFBE4z0}vlvR1inZ|6-^k&iRJUE`on3_hq27aJLZdlYZ;s(7u_ei#r1EwC=e24>wh-Kin1`|dZG zMpK+#cX61h=e?^%(Z+67b9?tn;~u9QdnJ;%Y83XnP9uy%{M4xtDGbxfzCMxq3+WN5 zaoSK_E9G}RX_=bhT!?p^zJlrOKgr%Tr&c^OpMAF8Hl-c5e6Sor8H(vV%8sGn#mD+) zO%h_OowKMAe!G$`t1gOyMQQR)|I@9Mn_BY8%rMK2;#S~&Z~4&9K`-s#W4LGfkmJ>S(va|Tx5MtK*{AIl09=%;Y` zb42;7W%Tp+TrQF(i88w}%fg&33E7FUlrhT)Ruaj_@5{3JgjnSqDv-%zv|Dk@yX6p9}WON3R8ysxS#ZxIW^!|(`4x9!pLZ-S*B z+>8(b@s6S&x*5?3%BVFhVXUPN_0hKbQ(sO$qT@-QTeS~uiHz`Fv;1> zs#Mvw?u^L{1Rz9nBZ*J1%2sua!W5k}MWRQ`Fs!G6?vf4}+}@t6>*UH5w~o0(Bgc3$ zRo=#z&54j+Oq!ju4`>7@IkNiXVgnx`Dh)3b2Y*s?so;SF6f3KUuvLr#g|;j!t|DKA z@}l&oT7V^De!RS^tA5yvIi4AADy*vfR1`U~FJ02MU9oG*CaSA^-_k(6=G^iHl|a+; z%@V3rpi$K*ZK+n4W)!4H-FAlY7{>KV?N%~^QziPk+S!h_McK`{BD;XZOM!dMENLWB zC)9Kb27;=)E%IgUVIA$mLyX{Z%N6Mf9_4acZ)Q`!`IX6Nltvh zHqbIKPqUHrZ6Uy`^@)^$*{{G%4&cDRAnMx(JBgA^O*r8EA0CN$wBG%6CU;C))c*RU zNt(+Ol-j#utLH7Wn(ymU7{VmNuCHqr50vM(uxDW6-~adMuw4`Z3ruZvPXv42-4U@g zX}UsWK5H`v}TEbN0QDY$(s+$Bo6AGe-ULt(CYF#p{N1xib7npz;Ir zi*m|t%FR6}C+Sw2N&&XcPjBo&ccDnv6ZRC{H=8y-u$hv;y$6(Z>)flWs5=D9fH+9` z%^~IYU!0z{!J;0v>t@O~ow#vHqm}zacgA3=*5%yPp`?C{K!TW=?ZP7)B5!F>E)sBWq$3=Cz#xgwv z)s_j$TQ~@SkKOw>7cI#|Adz`&FNT+lLTKV3hWg<`8>k-RCssU?GUYzIo&Q)uj%JYD>@UYD%8D!IO!cC0kalT@uZ^5I0I5Utz= zd`)_K4A$PsJLl);YR%(D(g{ap@**xCrv zMb3tQ#XRm`Kev2GfUP{Q`M32;!VBLyT*65O2#I^$vxV|SoZWGC3g2CK<4&zuUqUYgnY`H~;bgt2{pmZdySMg~tF=fxYF|D2m(OM$em3{2Ko z_JY@^_AR`;fY~#?bByH!ur3_|zdr;`4$uP_@CDU3-c1R5oog>gdubFpkd(B<-;D!aq)oVgRZ*zP6OC^KxPVkP>qC2jC z(5~HfmB!Pnn{5V7d9znLPtCOE$r2q7{cQfg?#b6oIq5d=)RqY9zk=?`W&%_yujX%f zn1jV;^F`3>0TCnC7exF~>+>(KEuX6qVRy8zIi=Lm3{~{~!g$jC#eYic#*gbl=MAvTz)xM76m2g056Y(~sSb zp3^bACQEgPE^tq1fKH{g%p&CyX}tTzxa$a*(oQ59gViyGNrNdm0j$1G-b~S9Qc0?$ z`mywK?tI}$`CV}`FcwKG-LQ7yAWO)*Tbncod@+88C)$*cnCd3+4YAgs{;~v6I{V&p zQ(#cn%CDpI+uI?H%ErAlZnATT@&~o&GI3RT@aZ1Ip>gb`hFn)rG5CAFGnxOL`5UaL z33CRaxz59!EbVdmgq*!pV7?G$N|Y_Uq?O+gx0Y^DYZN~9;g^b)!+~_^_&?T!)u)rc zUnfd&+@VJja>{0EyoJ;FA)0lFE3bnEP7}ekjcn2?K(04>OgE&Oh}Kj9=df31T2?ft z;8Q>~swHK{ailg?)xwsue;J}88H9Z?G48)Dsw#y=#2w}Nj`iYvdO;w~yGDV;l!X#i z*7aB968dzpW6?nmNp?0|`(R4e36Myzr$SKn^u`0Q}_y;4_W$=5XAs6^EqJx%^n2f;k6zz_3RDf z=#!1_?YL<{5~2Fl?)IA*supuY%I!wtG@k*I4yKg83LD`!aTK5(lH}N_%MY8qN#f>k zV!9|mPD)A&re7F~?m5Do{OgD?c5=^2Qg*h^#xcf72{tR@>)TnFkgzY(z0oadquXMq&3&*ply^OocSZLo$oVeb=`x@8ewkd*4 zdB~+KIh}=h@h+rRAAYwY(QRPN z&;v~jvVvP|=uf2GFjAfukj3GXd}O$ zrv|KpQIc;V){1jYU!!^CDmN?yGpk2A6`$H~o@EK6-oc%POhTFXyHP|6pUii7FwjoT z7#3t6pcO5s)zm}Dy@*1)l@?*5squl`)Zq_8qv^;+8;gR8`l&~!sj1#4%ZgeVEq<@s|md^z&l|7ee9 zvvVm*aK{$()5TPnO$~QbQmn$_ay9Ysq_aKr{bHWjJjn6ZZX*&{+?i~@Kpho1ZsJfR zsTW((E5wvd9QjuUo0>ctve2KBBcNzYcXej^2s3>gNuFgi^3HIHA3_9IL26~Rc6Vtj zmv`)bJISzGPC;GWJ)WYqUbw!8f=v!nhTgU)=>bva2?zr2wBT{NU||CSDY;c2;3D>s zHGs|X_Uo6_&Er>%p<2zAp39gcB`cYcA9&nJMK;2Itfq8@;@Y0`?qO7&?(V+2%-s5@$?s;r%UpNHiKoWib@mHx zZ;~(#sba<0LoxJ_IW&w(NacvGA8;c+1joM|5luX6lPB&$F35P6#EwtLlU81CoRy88 zI?~}ZFzcxUpE@O6K+WoALTXcqPMTmO3qfTkSF^_S^)GhOvn<=+Fy;`4doWffOfmmU z{h-s;r$R(jV;Xi!>r4ZiGRE!1rn#nc4yq2oTkQ*KKi&m{{B7Skk*<|&<@Ex^L73xv z&z10Kq5?k^xcyjUMiZups?q28Qsd4n3Pc*}g46Pkpd^*7j`50>eb%iZIPWO8mR-ar z@L#`HHy^=-C3CinXZU04PLe=??WgCEN7`BAA_5o6+l(u`Y$Hg+5_3F>o;DQi5n7h7 zW=G&R+9?jFY#Vtj&gI{t3kgt75@}zJchfNzbSO>trR$K>$XUXLWRW$Eab>suy5RN) z%o`Ku&OvCUXVl{XwoO;z<%w3Q8Xv~XzBF1K{7mgj)5Kr+?}c}9*9*VumF_%l^FpT{ z9o044ken%<3R3M;kWw;Ex_U*$Nh*^m_lCQrfL_ea0b|pVI@m$uq;Y`%#LO+!&ii2Oy)+_ zu8=swzp2=r!LT2Pyl{Ii$B)a7@oY*T==A1y(yTSoP&YXTGlqCa;z{RXw-~z}5bOC7 z?H+UZYTKT54&VK%bz-an@FpDY3)`Q(lSqYGXInO-`184&_3m!|w|30ay0~lSk;yZI zBvz*)w^iAhNX;a34%eR>%MXOhps?qZDPA={UR0ZeATe`!<%PSVxb?^;wX|cqptfks z&6Aew(iZ%xH|N4`-Hm<3?E`4_s;0x{G6zq1fCbp`MN-m0qbJ+y0cSvcM|1-D_%wV- z7KtwFp-i@m7l_;8E5x()6hy#0*1Upw_Ru*xoahQuE+&4&^k2lhxTiYNb7>nk3Yjgm z+WSiU6G>rm5}>ZFDfd5gRKnMHvBwJL>j9Z|PcjyJ@A*fB3Lqha6JjY%v=$c_91yU_ zId0U3e+0;8%Tq4NR5WiO9w0S!9?Y6NFqP(KD7Wy#lijWTn)s{3RYg$-B5^llQMz$n zh0N?K4Ho1Qp0E9OI~n9+{fwNY6ASH~UDl*s!a;zP=dURXf%k+|8^;T27Eo$&D?Q1lZ7MO*24#vmup30OaDRL;%bhyh95;mp7sW!jA9oy&WC1p90*XwLTP7vrN0A zeA{n_9=JxVjF}BIL zisQ13q|!&J1I zjsYUvHK+l4&2a3DN0`A5!onnMHv#{UM@{p>Z(uNowiP{hSIuCOroJ+`bb7+MW4x^s zkDg$4<#>L}E=*;s9YQrV*|Q*vvsvFh~0Oi+D@E4s9AvbDxb(bC=j<9EgJ z)*yS#wla~lkdy7M`IW%*+?z(@q97>e1SXKL99?_cZV-hc5jc1@n+;n$crQa+BPr4< zr2X?t(Ogcd!F|gIEH`adnCj&viKKybDcZU`3ZDbjb7=n~?x^odRqer4ITzn;?FM#P zA{-11>COmsai~OlIhFziF?yp3+9I055^iXKI@7H2z6D1Nh@cxHRxyF0bU!p$;(c>(S%RQ&1+aE33A zt%$MHonlGLy~fAtAe3%?Pg}hftGr!jZjDE0SX^|{>mH)>6~c1I@|73gQEzjPb`k%3 zLyB1Gd`lrbKW+v%NJsn-JCVbp_wOMHLFT4Sr|GsN^$F5imjm8SH1=>1<7_KwaTiQ$ zN|#{Wr!R51DRTBuX7n*(p$OQUys6Ijfo#8GUn*$t?lMl>k00D8uU|tPNiyNfqaxPT zV|G%bA{(xN*rG5Kk69Qx28In|@Ijmc+Mns*ioUaSehY{=9%Lw^>iAS7&)S9HE6?=b z?4Ec=v{`S6198346M?R9(neOo8(8K~unCxWGe8TVAmQaqxr5rap3D)3>WGY%9@J-HsC1UpiA?L|77qy123URh1J8|VYmn) z^K^`hN4c9K5wsV_Y$<00vmM|V78fv{{NVM1WBVy7&!Yq?0 zI1&cRmuzj!6QVS3v$Ok&WCE8(m?L7a$pn7P$m*~l8C#PI3X-0m zW$&#{tVyKoggA#^S#K~6{~fw8QxeWA4DA_mnwtmayKp`YTHE=4f38?puPvocGV`c6 z7aTsRGJVaOdE3X7VK11l@~c)BySm9TBw5?`aq&MOx!lbLnd@Mf6}@wh+eY=qaLoX5 zedbOPm1A{un1fJRJ6ss4c%#;!kcf3IDDX}b$;p~AE(q$Tx9a8vG~}8#MJnR<+M-*3vIwQ33etMtJ01W zy_y(%vsJP^pMlT?4zFyrGc`F z=Z%b7`X0vE`2%;y=c|*z-Gl_%9(ZF!$yZ=CZLG5UdD_Y?rm~D#XZUU*#)2sX3IY&7 zr8YWPkDBQLC`Ff_D0w@mGAV9B+>=aq6~En&+-AOh{7Nx-;vrXp741WV_n(=T)P{ zC2(i9oDS%kp9jc?KsO`Kk4VM2uvdXT-C-y?J_eY!#??9ua3_g*6=Y|2-xM zs*{XNU=PSL#l*nMN^G2U3>-p0$)ovGxhvfAa02xz7>?*E-x< z4ZpapGIcNJ13)GfdIOzT9%(QpSPh%r@I)A0JXcKtSLUMTo`HtOK6=wNU^x35de_ zI||e`4k3nSl`Y17!~?}%dML$gvS9=|$_$&A3{Z8fJ0bod%M@3Lr}7C@kKn$sSdc@O zUf>aW<{ooT>c1v$+naC=@yNhtA9T?0XtuOri z#EXx*%e5T*^3Z*;kaVZ!>c!tWH6z4p*ayTXEe-lK=&F1W-@d(=Jhhu-{vAa8=Y^eh zBLel}*R0bV$}=$K?nZ0LYu+Aj&YSU{A7Sb?md8!x1+R5Bz{c_@IhAM4dsmmN5hg2Y z;|@C-G8Lw4_uIZ*2FUZ2aKpY;TzTvyVA>RsaWw|O7ezeS+DhXUhnWJ%e)YI^KVJ8) z;9tOxuGl;u5sykJD%om7AZ2-4g5Vh}Z;0u&{}QR0u$2S@cs$MCegm?&O=etM*A}9% zLIodYUcp%+8343E5?EJ+l3}o zM>ua#nw~bhm-H#T^yr@D_MU?Ux2Kbl`XbnD7yev`E5Vm12phJqUwZu!{$kIpf_3S@ zyt`-}Nx94Ts1{@R>@kX1FWWu+fYx$}DId8^FMrux4t7FTO`G3K5$?t{h*y1KF?zGJ zUzC>g3dy@wA*A59Qu7`d3umF_n926*OE!c1lSv6koY+PfE7UtI29EYmRM1I!5Ay0b z63|C7pI>1PZWE2?>o^5=>`+GayzbwGsT#`{)`w+UuvIh^Q+c?2e_d+;MeU~^r#%0v zjpD8&UQ{dvtut@+(6DXT00dp>jEb5Cfa_LQW*I0S9muts>A`21Lo-dC`?%X`7E%0CcJ9QE zIO_+dq}kHCGE4<@0a}#q;7fON&qR@Ehbxr#M${Ju#kad22vpzIea;j!p=R?x8306EH6zeC`=cxLG&g-sDLJx13*4g|R_t(*Y_cHRXy z-DQdB1rPSBXjt1YvFJMPLOx>=uyS&_M8G{ey2^?=us{` zFIM&ty%gt?`rxvp+|Bu_QZKG+df6+>HQULy&zfgM8il8C zLSzJq=&T#Kh>g-^bEcVybbRNfUQhQto3W+$%Lq>WZE0^t;G|+fp2v+5>}DBjm=*^} z0zaB|ARHYrPUh>9BaRKafV)^Ul*~Ns5{kg*6ool#2)u39okut;j5xTr){)XTFWeG@8)K*uBvTC1;MB=kpnWL`YhEs)75yz)NX98 zxlv<2k3U^%i+vFabw5UaYA-ZeVJg=m*M`NYCb9A7+FYU6uUEEI?KkruKbAy1z(2N= zGL0Ahi;S2pFJr{_!BQ76rxE)i zh^^aYM={c@%QnWAW0+1{!|)!@Zc_`JmrxhgwKXhxqmDCP8ZRfp8&-$Kd889NNsdpu z+rN_X3IF+csxaqdk-6yzf4b%P*bsEPgnpY9uM|0w0N8b{Mq&4+%4PoY4*qYAl%c!C zp#)-o=%IxKP}EfniOz)%F7AxQni$c>IolZkDpQmuGg+?};a!tCJ-{?45K-|5USCgB+B(+BzZMiL$jvSzAFLvTd z6z6vWXUG_^M!0R=`W0sq4RWQWdWN)oZ(!*0Sw3y!8=0KlQ4HFfwTDTo$4jBZ5nVZN zdRnM88Q^xfCBo7)cc;~HnT2t*cNSsko^+$fdy07eaFKrA?xPi5nlB^B$nFU_a{Qse zYd*E@O=JHf{BZH>Krh~~S?t1c|4Jwk9zLqOb%Xa7H_UpI>h8|!&T47i{KdjVE(2so zUus>bFiN8K>d5&V7EmN9EetzMsAS62*We{ODR>s&a=dYbN5kk)+c)zPQX-U@l=;Z_ zYbIkbm|y~l}!Selxb?cWV+7ML=N?;+Qiwp88|l6 zSQ6`nI+iHlH#rj*I*Vp3%i;JiG;xBT051a_;1+Rde}536CPZrNoe!Q0u0a(AaCu<% zTxruWA6@i16N3;_iOryO($~Vs-b*1C5h!(}$N{ax;Ck$0f5{3_qbYGypM8*`kY)h$ z{I^$15X0F-KYc-M1xnL$T?jO@k(%h;1*VfeTn#gG&~kM2+>ulo0loP*a*$qqa$s@= z#3B^dj?OLK#Qx1Lx?uNjm|~s;Vp2Hd!JMz-EX{J7AL4A>CvZE-0)F$O)>k(t$a#o$ ziTWgE!Ef%`e2B&>@5(YV3Y(bRE^aK$W0$W9xY)slGfxlR>oKS6jutvgI+?Sl%8eh8 zb_>$osS-NFSLK^qT4D6}K%3mfh859inrY_K&w0bgSTN)##|Nks@z604Mi;_bJ2I-nb| zp2-e$<@NnU0<94UCJJ4`|EbFg(E9q{gRrfB4_=Ss>{JW>Z!V9KojLE@hwjd7;YSnK zhg~e>rK)oLmI9em*p?JeK0mVRL#v8k2AOo_ETHLl@a%RbFE3Wee;8I#JT}iyRohK- z415@B$fks99krr5VL`L!rwY^FWWlRLQwhKO2+EbE--i!z;NesKA4-tLeGGPC zN}#M=cU1)S7R2n7VySr%a6!xv)a*;;+3%x#l)Z%?Wdyu*2CIaoFCKH6yGXAYp@9v(T}S?k|k@dVij&5dS>c|I*AWof0?O} zYvOgE2e!N6yC^OTk)^nu__9!}cYnf%;y{gnMOaJxVvw6o=0l#cDav6Zgbyd0Q78N| z%61BYMeE$ZQK()3_@&{8D8A!5n|~5s{Xu|94*Z}sBmb1;ACtI`$E@1>FAT9d%M~># z#WTHuvqf8+4eQBFg{Vl<_ur$jT)X-`G%85 zQUW7M@zPPpf-8DED9)-$h>r8QAX&id9wza_<%i2;xtkT4lu(ZcgF0;>G|MT4_9C2y5_wL3&kkx4ja}+pFu& zSU}1ENls(>hl~Hks=yTHf5aXoMUqL8qxkN%t!1-f`BZ|8h=xa^sOBMX$gig&4lHJ} zpB#NQORa#pdy*opFFTWZt5&?(7O-ff2uX~H$tmyWhnU}n3^FP$gyZrcmGABSyLu_G z4K2}~ycYDzb*#U}cJ6v{^2N|g1?Jx{#CU}jHeDrYwLu7LbVD|+C7hlOxb`lSEl=8d z7l-M}*)+Ie!l?(Ga3Tb|Ir^*udgccB?n2<=YWzkHH;D2C_00lrD+5niN!sD7ER6+s z#)(jntxk|)KA3HDtbGlo_f@m23cn|TD@qC(wk~iakV5<)-|54j`;}Pv!_HwEx@kwt zV;MkTGgLbwr=DP*j*E7~Sj)1!gH?^9#FU3w^oMXon7M3ar*}Jlq2@5qQe!io7muSrGvIKsgfN30j+;*BW3ilxrCzke z8Dk^&bRc=pc&eN!SAL681_?ccPR!wN;6ySlFNERw#3mp{T^2(+wnkgZ;>YWr^x)mp zqy~r-`q-*ZkYpmj3;v&Wa$*8ZWzEIGsxGm^oSh#$_^=4m{864rPYBUP4xpM7DFxfO z>bClTJl(z#cFs}I01Z}iS>D>T2gcp-Hr2Bu{{hEJLyCmiSAs@%3DPMXOWraQ6Yef3 zbZ}Tsce92&J$x~T8qkP}O`CnfZ7e)Zd)l{`p16p?gCz7`8(}iVUOvCCZ%Pj0ZE*C? zsG&nt3=POrzPV4wq8XbU>+wtjsW)sr@2c^a1(7r!pXi;>Xnv}u7f14NcFJU*^UA$Q&q71cu zK##!m@I`FhBtujhE2~LrCym~xVZ=Eu_s-VCLbcIudR`PtFUo76vUIXjV?Iu{hIir_0YK1 z^a4wDuv0p_`5x0sga~Ww6Q?6wl^vEx7}%lei}jcc)Vn9)v!5-crs(p>+bH~> z?jdtXl9EW85Hol@fHIN;?(fja_I78H^4`S^5HN|MW8@dd&eo!3u;bmYFMOzerhLob z)jBP-LL%iZ^e6+V5a14^s$-s3JsfP2TYYF=B<_wT0p&9#TSc-DE{hqy+;l%q@*(hi z*Jgsxyf0>gSX-VB5v(|EC+}-mfGyctpXt4z2m=i->b$|cEIR>5# zXh?1=R`WKtdX$Yz@|va`;3lSm;BPpyg0N^34}s1CJTYDv_ymP4 z3?=QTIB8QsiIFp6yzvVsXbs~_56>173K$~XUUC)tO#2q8h*Xg*T4e5dtYMrb|2;Y| z^f@?_>$I)lkCr$-WnXHLIG{u>ShP;KhfR_1WeuXqcoSqUq&KaM-Bq&^mZQDT#JqP_ zfywX|aej!jZt@D^@%?@@0knM-uS3y<&#b2G?Tu+Ns^ie`MS=pn_xfTd7pF5d*+G?l z0t^jLU7RvEzuTjL0Ms7Qr{d)4Qwq?v?>0ju3hL{%}wWt0f8` zkV@&xtn$>0+=ii%Rl1<8l`D1wD-})IMq6#@_(TUrymT4x>pU)G)2tb1dXu$WfVUQ~l2~VGfTlZOqL69jTBEjJ0 zLNO-$-&vx_Xj*vmvvO~50f}_Wv9A&2psi$Jzza4=YO-h9@Y9K^u~JN}BaUb8{PFR+ zFeMS)d}^`Wf4w05$Yet8m=D~N&4`Hk4APg!LYV3#ETTJ;(UxC0`{||Pv7|t>KaG}( z_hIJK)0Y2the5k~+Tc(nLSET1TL?65nTn&CvO?v6_V>8SL#S)&FEmgZ<)indCylgt zN>z-i9nHwe+>+9iZ@@A`MyLyGmyTmFwDr*D^Nv5DQ7JPr_+ zPxjzcyif2(5>Q8vs-ol0y$dEo+1U!vz4#~x1S#f;(abS1v)?xY`H=6cU%i>P*s(z& zk+cOHJmp?u>oc!}HpIAyZ=EH_bMB^GKJrt&(zj*f8b#Ah+EhqCc|1L|`6^@u6)*`q zV}Z6uc5PdK~r8qfL-j>9qmQRIa3b92ch;Ya$tYq2W>wSLICBmIb1d#9a5Np!Ze@>w&WpH|c=Y z%9ogSj>_d}Z9`2@Hi598yo2F5*8MF3&3pOsn6vDAnW?0N2BHm{X5Q6pLbN+m5^mO9 z5ql-Mx!v0E!b>B&)m6Stu23j;Q2l<6k002@d+RoPt1M)yK^ivyM|$o%OjLj2R*ONq znNwKAG`GHVWAB;#oTvZ1U=XVvha1yO+#Iv+*8a@(dai5pACi7f$gJth)_SzX<|N_% zC`OWvt%Sk*Ez|f|bt$tvn~I8Px}eJ&KF%I=ta<*^74BoTz5Pk;noB~6T9tH0D1R$Mv*3~wh!oVmgY)$84M5 zS8~Ql$pPBz$)CCN9qjvH4l*b)LXmS?8UZMBG+<9~LhWntL==+Z0a=-zW#mB24{N>KrV#zm)#9=p`@v z`-Z?cnb;JC(b^1I8CU$4kU8EUQ|oYu-v4d75YB>R*V1DYRIL~nTvnCzv9iE@x`4N1`5-4d*M z*X)KOYzp%5rcUwd7fA9c!k&3(Y4t(h=DO#i38*T4Tb5>3BZ8Krx2;_@BT>D`?ay(4 ze)lQQXgmbaTdy19wjsZSP$O=CU-Cf5mT2ha3fk+qPSI!6=URx2UHFD>SOHOB&>#`}^tm}4&35th0B4&=W4GZ7ai za-ScBPEfw~`1^}t-tT(NYk1qAf1Br^7m(=8vyTD#zbS9^knT_Ora@F&YfKqIDrPmqB+R#VzE?4c=Q?4m7? zJTy}+9QcMAx+CV&X4XN2h*mj#Ln-Q&;k((cP zmX$!C?rQcvm)=Mwh}5@_yp0b=CTl3KpND=7L}-u*Z$h#+w371lME)}3?^p4APcFQT z%&j1NC$e0F=n2(#;0-hu`F6uMuOR5t4E1dcRdY#^Y&m{8N&J6a|L=TTR}uZA9{bcm^iLWD95L^OTtA84e9-iMn{7Y+<|;H&4KDusXyWyg zXdAQyqORum5$;{q{12T8d7F`};DJ=3=mKe5!B2*<4Jv48QY3iw7x0bd+N5X+iu@*l z%7a$^&F}lQEgD*m6pga)5ulY-(ML1%cBl2h7fsh+ed;_R_qzXd@a|5yJ@?SBP}$w6 z!;wdrXN*KIxfktA6%tB6oc$*9Fw|$>R)YG${O^w<$Q(n3{~UreJv8{wZKD5A)O*Jz zx&Hs-Hy}6278SSP$dL=T4ZU&TCoD0HUF9^{xLU?%lYD{MSi>OJbv*P zQK76E8X8^PIKB_Ou7@pZ{*~jW2wSn|_voR)8-q^MzVG$0*Y)PVp{0k%{70XL{%Jl- zFM@{0??K~O=TXh*;4A$<>66I%{~)~{rpUd-7z}ObD}t_#zY>QY%G%txV%z41Bo|OHf(_O-$J*pbeK|xU5B=nKUl4Vpx+onyMG#ewW0C7 z?17jqg)%1VUmCiHUO%TXuWOYl#Xez9zc!R5I-Ca99r}GG@)o~7EWz{lg5`q^$f5R+ zvtL6UZ|Pyx2xu<<;9HU&C9WEdE&UaqR;SOpRcyef!J>*vYAo!;c;rdJ_HJm)R@-gs zAu;sJcmH(2%3>6e z|08d8K|O?i5^%QI14MC!<1;*TcMkZ0y(~2y5>Gz$?vtKWhEfrcbsHmhh7IT^$}FV0 zP!|V7eOmu|4Mfxj*TTSBB{efwp9_upjWi(iN{F7TG4CSO+|tiMLmZ~d_$E7f%p!&N z;B3PdLo?gqFXh6pkhn}OX|N)SA+K@i%GuxI+sv|K(7)n=+eW=iNE4K5WHAN(f{ILU zuNTiK#YN)g0nKkHZ0ffRQjCq%vw_-arFaCm54l}a?EB-`-8twU>UP_w=$iI>koXty z!KM#^=G^-wo>kgaIYd`f-1`qg0iU8h9pfri-FpvJf9wf*CkAkko+$npaW4yp7gNSx z1CSD`P(1eju7~Ez9-NL+LZ*Jsk@dW_Q3$&8KD|84^wVX5!8a*a<={svkG&bFsbl5%*+WlQjOWQ~;qfpmZtxAnS!FkT^sl9pmP!_2`~~g#aLnVzNwPk7d?Vw*>FKZU z$Pnz~H}|)~3(z$sPYI|ooNs#KjBFNTRi4B*Rl}T+Jw6$Lnu|y@yI* zw*_8%QGvOH^e~1WO~C)_{~W=@Z?PWO3Csi=t-bAMQp(=fV-#Y`4xNr%b+mP5Zhhd( z{B7=;{zkGJOT90nJP0Ue!|4Nf)IDGP&4Rvi5jNi0@moGtG|$-5D8%#n)(uAEBDPZ; z?KbOx$){Me1y&m!xp|-PSV8Ct47A+Ybx)%V`5#=AU2z-XXbuVD;lXI!mj=>iXQUfv zzO#*4ihRuW9wV=0QxAnS7VOMsnk?TJP0k$RkxMRH$8m%X=N*ilr5pIcC?=@)KvxR# zix)O-;JSm)Sh$lLkgnhILppIr#!4jOoQn&%0)a>+tLIFU%&HjkV2fQ z;85Oqle($w-TB*KB)8=@PtUp;*CI~9Y)CKFl`8g}hcU?v9dv**evp*wvPAGa-T}E4 zSCdEfkA1KBUT;+kE{Bt63yMVmOlLE#l(BYrpg9;1v=5C!$9QJS8)4zW zFW*nx4u&DnMyME6)5Qia2#_pc$i}Z)Ee1)NPIw)ldcA7&8%W0?rgVda8`d2*P*R!_ z;>w#hxR@KsX`;%1x<=oux*hBo=}L1?&+HAM@fKPNX%$z)`xcaXY=I(^BU{~7yc4ZC zgz@09P1F%_DxX$X8A1bhn@^|(MO@ndI{xsq9(zs`nDIm+UPfFyU#PuG&s*_j87n@O z>2*{RJju+kAf#L|(r|zNqQ%8VC5zL&W152Pp_#}@$%DM-z`+GRv~mo1Zc#a{qGq~y z4UcV>1e?p26nWB$g`up(7%xmZi!sL4Y!L{4{%v8!;#Z_DNlf6ZN^h*DT#4CzWnAc! zF2Y@R!%}dmT3a`5G%I=0`L0UH4I|wR8G9Hkq~mtELD{34^Piel33jfMW6yCY0&KKH z5>rFkX96G5sPyY6@fd3i`-iwq1^t~Do19P>o)9jKh)bQ;>n}#;E{%yQic3iqB`2ov zqoaj_*yX~wsBrt=;#s``U@43Yj~6jBMQc*QIA&s$FgYfoI5Lt|oM_mW3VJms5SN7G|s_`c!zDx`%>B~Lv@(h%RsUq_KNbP{!Nt)!ocQe>f|(WqP%onbfR z@#7?0zRLzp7qf_e;aG6uVcjwYA>d-NkWlQkqFa@Ibv!`YsQe{lQpHqxhozg zaKd{9X?nto^~cwUF-+k(*Q#D(+diAs?QBz~Q%B_WeBL}c;Z3LsX{?A;*KQE@evVV3 z!gy9jD#9%iir~-#&#bQ#*V)rh zbrugH&zJ_4(TsgHS2#fZi61)aeyq5>(A&q{q)xc;EOe>7v=%rUapp9=I_xav$HTIh z5U&?_ov^bzsRTv15Znoy(fxnHi8xz?tLO~ zP}h7{Ax;sbs5nTE(XO4I`$V{fI+!*Cw>8^kiaPUi7ra*+YJCw2MTDm?pR!idaeaN{ zti0C9^;=$ZD{7%NxzlvF1J=4w_WR4d+!od9Kgax*?sGL^2eR2KR*c-}+`tUb}S-ivy~N!;Kvb|8OsLVZEB;X%_yxazhA#Xk=^zd z74iQF3QYXhwD?OkDL*mZ23=lbm_HzjvPiw!HxGZE_yB0(_QG0oks;hu3sdn6xO?h3 zKm#TfgKflRHQ2hJOTG?mZY8ZGQ;+h|b)*;VqFR9+U<-ZOtia!@;3Y6^s;_swbMpL? zTVBiA!MRXYztA#Bp^VrREvzle<(CR&R+>kicLQ(o&V1n3q_Y-2hyhWJVWa*UkP3-` zu4+8bhlT)A#NDgk*HR(Iil{#nL4b`0JTV!5{R!FU{jK~5=1^D5W?Hd73;_Vx)(7xB z&~@=tgT0k;ABe>Z4(z8SWw=^QAx6J>^PNBs|3x+MYE{QBaIU`VeWh;`cS%O47$8h>}7-zGV^LB7A8OeJzkeM93o1Oe?R)IAM5P^`i65Gh)+gChs2Tw7;yHc zbWI8&N4rs#vg_hy7|ysLdVWpUdyqzFa5SxrEU8ikcB601XBYCxZH{KuVl0qzHe1KX z_24zG`~yUbC{<;y_ojFczXc7ou|L-VhQ1-Bb>umfKiaz^ZjhG&E81Ap>!?h~J_YNm z0_>F;w9chlmsq#&bAOT|KmAcuR0yN?bRT8Ou8^#Ll)>taMHuvKWNVqQfR8qLNfB)A zoG))d+V&{82KiC*zkZ8@Vbmlgm z5e}z+B~dFKFbz*mFWbQFJApS}BS9%H4B>3p8=5j+%wk2S3h%?^+KYvU^HJ4>?4k}{ z+&@F7*E`N7;cG0DC3A6ahie-Jhy^4d20^%{{KvOsH60c@!` z{PDAwC@{0H9aa*Vig;su^$ughIV6#cdDA>`sAi zC0{DbO~-f*Vy^5%rx*MAAU?y)-Vo5fD9W}{^v!6q@V_I8j7u=%%->}SSR?a9Z-&jK z46kzl$vo(!4FbMm9?>Hc?ToRrh6C2k-Hc$|zJvh5hzGXEEt^qi%Ez&LjH1n!ul9j; zlW3-8ssO}64#F%y6VcsM?!+AuSmqTHcv{us-N$`bRr{(7lg#54S%RYHz*#V_@)!%f zGAFENj=i^eDd{!@ANs&J9VN_aQW#e}WMVCOS=#Kq3n)wY_wd)tR%k8%UR^m@OR~|; z7_+U*D)ItK2{d6*aY6aj#_h*E%PVF0tc3saqqe0I5ab#l6U&Kg)^;5*zrJI$! zvGUs#YgI%XqT9t~K|+I*4WDPV-zo>~5NPY>mH)uTD3EvuU#vQjTA0~@{n0^I;H)oV zEz9{gR*_x&0UL3eS>BQ(4a;|55g>e;(U^=zUULiUFyK_%#+=`RG|$7hNHZ$nCldDK zdKEC^AY|+?<2IWP2Xi%^heLX)sM6r4&LipA3+3o@i&X9_S>McPurN1DIv$(LK1GIg zGXCP`yLz^QwRrx7WeVcp;0_zOb&LH|Al$O$Z$_w5IJ2EW;Q7GlR`ysXd7|hrKydd04h<~6j-4|-8z_(oYC)1HWGayHA4Br-MA&jFFIT6)F37N~OrQ7O7F z`*mIuA!7M1MNdQyQbu1(udATN+G=F9x_euxxP#odqdmIvwN0+nw61@JlOc%3!LD#*zTaQYmL#2C&64c^Jz$#UUf8;MfKv zy=Mf%Y(PE~LqkJDHbvm>E=9dc7Nyo^lk8bNL9&B2^WSRoIfYixA#HzWkQ7wOXg#m% zT(qE|2$J&p+olo)W$7SL43-c|aq-taqgGkT=*S+FYwLu{yGvtCTO$zM7X(mquK{m$ zWmcO0LuemK2DBI)9>Rp#b*cLlkhrU5Kk!x>q+Yu%CLmO`)=EiQ_afYFe=I}4-yW04 zah`b6aEP2^4**GtA8=?7&^yjI!j0`5uF;9l#thCAR@G_LVq4dIBJOIkbwn11(o|5DpGl`VQ@TtFTWm`SL;zy zPg;_{kHXQcPv8nT?xV0Gv4<|t6su26Vfn`Go-@j;6o-pM6sdx*%_0VBitnm(X?^vkIuM@q{7kyDqD zQ1_2gqaV^@WS@!sC}3;VRvE1$x(R{$0n)b=Y?3`ZXqoWxYIa^ju?^J@s)^x5+d(e@ z;HkQ3rDlanCPk^%6FcNFRLPB+;muq1g00G8(JK?hR?Vwy+@VmmC-|sNfJ}k38ub%W ztjm1I<_@uJgW$$$&NlHj*=xJoPV#Ne;EP4O8-;9Osf@8p3O04mzt0luWZO({#BJX$ z)@}oLZ}Zq@nb+j8n*q^es*W4SQXZ&dsfz9F%@Z7JC8*QOA7qv&-+|yw7or-AXgLd-(>Tgv`c!TWa?(Yk~7-qKtz<}bEm4s-iEY1>i zB|)N8Yv@c97nPC}ZoSnS3e{h_iJ}8ajP6uplZR5$CspclZWye#&#gBO;|uIJ>kQ}Onsm$u*3?EEQWdo)`4tX-PehHw-cCRl#MmC% z_!jG#kYt~S8o!m8V)H&RCB~I&6aQ~)WiI}D?3I%yF_vB_ODzJT-p53d8kQpt#cb(d zUhnA3KZB`s%`5wIqkP&6D7YV6=!EwAi^~RqnXrz5=(FTt-)MSOQ_0f|KdKRxU%~4{ z$iCP(5aP-N#oWY6vOU>5GFQag(#QI1UWQ%Lo48}Io_ekcK_nh?(qFZi{`sALO;i4CIgvHy#-W5HGs!nfSha)CpO`q8zRn8<74EF0tX zDeIGB{OA{wSid_?X~CRd6_s4}55y4)JES4wphkI8z~ynC8hwbk5XIQn{TGSQj$)rKOU2kpKn=#^MBguI_gTZR5&@XHKoYN z9eiJY^(Si@nok(XPH0puz{J)l1va097RFEr?g_g}J{7guK-o+id`}lYpZC-WW4%4} zd{qq~nmK>WKIorF`2O3d=gTS|rRUX`@oj^zV){?!pAdmwIXrvH{K{4A;+%2-b}U-F zOm~_-l*$*x^U_N%wq2nev2r7Nf;C01^nK>o)O$RBopH6$Xek^<%xXKcM271o4GkSg z)44=ZBR$RjQHP$CDN;W!I~H_(cZ}w0L({6@5dZi|NwQ{4Y}$L%*PE+(gD5pw=?1ZN zi^e<}Lk`8pYOKUhkHfZ8Yi&I!m~tY`z++}Zd!kzK;FjK4k`}Qs)rvJIT{v_DMEm|= zGd1H)p!C9`KM&ckZ~oa}>lSAgTimoAOihPJwNZAr<01r$R`~TE=Y|)FP0VdNPG`I* zFErNHHu(7-(u;A!`^F==qG$|japf4h8gMlwrJPg!k3&7b_$6SuM2uG)vOCJ7ht|fj z|1h=TqShZd3WUNAxOb@F(94B= zqI~E8HTx7kBnM`vG+R$gdkGx~KSsBdWy>lLxKZo?;P*;Srl<0^xXhAnIbhG2L6_d) z#AEYN5neAp-%RFlzu;CpleB|MNSvFeG6oDhj>Oa$o+y_vax;q8RWS+~PFd6Fgs+w$ zJ(g3mc=X%iO~-~`e6Q{5`OhfP%sGJdzP9Uq(b`S>6_j7KU8+YPaM;vXtspu|4flvB z&DU7&6zrI2o(j+FuiNyj{Vdh1RLJvLr;V*39+Vq=53|kByM5xhE|uKELc9;o1Kp&C z7q8K8E(&(&jI=I)`YDT9MRJ{Aei;bvHM3nh1Y`tr$}q<|aXvNJArSx6n_p7Q`_-}T zu0<4A1fdAb8bNnRdg)#v6kVzvVO&y9#}#-bG?~2q#3*RZ_ev=iYj!>#gNF%4i+s@h zkZ4kC9+GG~c>FJlw2V6yUO~nFug@ndxz;PZK;&BJ7G<6DXGImSVoR6TKC5h+%r$L( zX(8`iQA&HcLA}Gv!tM7L?a$&ot_T&9G@ayuwsClCCPM%l&kQ#z`Q{T*iT|B1X-ruf z9?z{ExK@1L!v#4h%Fpc~G`zCJv9e-B9*QgF_cWvVMTp`IGj4G?RW*?+FpWV6S9$ya z_Kop`BR(sAsBWrj+>!g|tLXPGjHj0uC^0##KubC<_dD*}K*$jprsB@B|Qajj}u-swX?>x!xvd#s;l5wMEM}ft;PXHL|j(b5(WZ?^G91+84G|h9Q9}Vw)~` z%4VutQ^T^uuc1@WaTJN(+w-2$W?0x1tZtFKv@{GJZi);DTI*%g8qleSEk&{T zANKX)kK18U=`(BE6|`dRJtO1Pfz;x%W6O>hxvxr=Fx3eM3kQ7Bs0L9Nz<)MR?t9`rTWUS{5&W(iRpFyu>gce=*nL%A#*wD5fS`4N zZJD_fOcI;*x6Nr%xDecg*zwnV2RLmE_I+pwkRz=Gaj+uWNqK zkzHng`7OEi$CktSH&7y?^W~~s&~hHYP@qvp!hka}^11_kye*r47=Al257}pq%*@!K z&NyJQ>$nm8@y_x2$DGT##_XE0Rk;LnE*#`$)=lrpi|_?lq3oyKS-4jaYfnMr-UyC7 zO`LWB$m}(CPzwGegAbx)ce*o9)U#+pQ7CMBcvDPK8a1i9Joop(#Ya+>FH!8DHvSmy z6lug0)IK=Q zN!NNZ7=z#91o$;yfQr3qee8wc9U&iLbr*)+C zcmGDmSpIu$6N@YObN!Vj*QeOY0ztk6e7*H|2~UCm0#SMK6rlvS^~visYY)9;=2ngy zn_~i&f0G;i82;|;3HyQsLO}dD^WO=1`+3Lnf#42oL#4nkWO;M^f!%dT2ed?=AVFDJ z0ttf)bHh*b%Dtz@Nm+*vhaAp86Zz#+|L(fB^qDmERM4sW2j1nT8Kd;yT>scO(C*UC z#O$l`p1z_uk|qt3reSTy9E!+s`Medo7oR_Ud2IIzoJsHUgFk3J{yOzDyV=bLx%el> z2j*c!)Kxd6rbx2;^|3dXXh>aF3xZ;ZyGH-BA{qd=t&;>pLIgXMx72vv%}#hV!8Fac z;`N3btN%FOYxZam-h?PI!ho6Okqzc<&El{7rd{_xMx`cTFkC&;RA)&dz);)sFEmEF zy;`ACBQdsP|LM&!(aljB9<0%!X%EaU=2f^v^FY3wi!ebx$8Xf^L_xo*`Y@R5d^R$K z&wW=0GaJh{b+_i$Vyr)e7YkfZKdOjZUsnN9Ju zz^>HW&gLKHx}N`66NgRu7T|0FNU^UmQ@_!n9eb@(r3 zf)?D}WOYkg0?8x|!?=3LFNQ46&z(hUvpHnb+KTZf3r;y7_8{VKGtl9|Hn@!YD%4U( zD7Vc)XAd45GNv5 zH1KFJ^J~!R^w>6z!6WfLU>#4LY7D1nu3ru*}t! z)=y*5n}fbbR)nIxH8Wbjb)xQYY((V$DlV^#Vn)ZT^zOV98@FU>yusMzgv2D)Wy76i z$tkI6|7SiuBXfBc<3P+SE{-hjt6A}?MaNE4 zxfqTa_-EC{Zx(c}u|b`C=%5*^Ab1=iq{hSTH%#!}pmX<@*lFJgGa%l-ZMWYHUAH^_ zz#mJ0mF8V&b?v$Pjj6=i2emwY6|OwD#zMt(5LWv)&Pb5?Twb)$X3YcR&00Zi#r3rX z$6n6Q)4t`IPzx(JbvwG*T8er)2oH>zBH^2&+K%$?L1Tnv^1@#JQWosIvGEnJSk~sfwIa5?sUh*Jc*WU^Un~D zyTc(opK~KPXo%ZczOT0IjIB|dU)OH(xeBYWE6c1nCn`j|!g6=FHMT`J3xXF25gVC4 zX{#RxkJ{#+849O=HD5gmP=&m_?BtrjO^z)$M9*eS?gmiopM@u`X6^#8Ij1A{psucs zbJ@dW9${{epKVQvD~^kswX1N5L$#&G=G{I&rA}q^4;{qG*@rvq-yEz3#4qONG z&T~zwn?nhO4raM~HhWFE6YERw+zq7S^0wx+HkNoKoaEW?zP9AY^8VvFN6u2Ji}w^~ z--7uS7vl%bSI%A+6>Tq{b>P!+x7APi{LP9nsV$%X-{-8Q(`7CUFaEY}JH%+^Kb4#i znq}qn%52!%ESuWud-1mXCtc-KLijl*Lfn!l5NJ}lxme^)*j22E;$)luRX(^p*{2(| z8o5;XWl>!zyW6;_QfOKbN=FlDZugCzPEy1M{^rNba$^74`?3Pj`!qp`zhlcln19rn ztyMR!6)KlrF61RHO02=LO!By{X$N;pM$9z%szfkZ>*G{ZT#X6yuT+&bCFFCh>$MJd zN{>Y1gs#IL;K!1b^A?r&AECG@kL`@33#k3Mk%V@ zE~OOytu{X0G*5|A^&yRvJ0DwBo7s|-rW1Ex7@cw{eFmm6p6>N}3zJX6ii`$-(oPad zqAXs%;A7ce++yvjBBDbyX1Fz4+nR?zCjR?;(=Bs@)KrOeXU?a!#_RDUHkLEg_;HsR z&|S1@OY>eF0JGF3Og7yinu;1qwWQK;38$Cy+=e$`+;}7U>N*sKQw+TnQ?O=>5C2gd zzC=3;8vj*KHxr|r3rqRAPDsvX;35OGTVC-Oj6U2ReR++Zw}g&5p0EYW{)U zQJwoj*bnCCtR560@L?4)d+F+wuOC3AWcvFQ!TOk${@(&nt7Xnxo2dS-Z(kh?I480* z8yXr7IBk^cMqY{5nB@wqv0e$k)-0|Nx;832*cH`c(hp~;sk3@|%TNd@8vtSw`M+~F zOK6#JH+Ncb0WA>5+!g138@+H$ z-RsqC+D$^aRTdU5l&0Sq^W%0Wc69Hh;sTdCrhlNHKQr*RUaybv3Ze%@dIbbU zGQC1Vq5`}E10xqK2&P9wMlT3oml}JkNsl0{KhoFt93F}d60$!T13p>{Ec#MoiOM1r z2K=OL&VuSCwF`AeOf?i%t=@N;{|+jwNn+ZWhbMj=97e#t4cG#&Oy4-HR%1E0J{W z%)4_rmr--P`)^AXsHk1*OQ ziX@AZ1uL&9>0+BTI7_jON=&io_#fkpjo3s+R`+2eVbEgXherCbGhCyO#mKz2f7zx^ z#pSLsoP9?jBLhDb9bh{ev;?xBBUjc~IF35z1?a|Tjy|rgTNp@MYVgM^(-FDa^$Rl` zrwN#TOSifnmVF3n=*RTj!_4=%W|-@)ZQzIs3nx! zSEu`1z@0~YUQ@`6&wjf9Q+Cmna0k?Ut6XvJKVvtz`ywK0-t?K!DM}KUx54KS+o3$Zh!9^GKo#d({nu!AAoqu-U&BB=&egE;ZLa}z?onGT!hsEA6_mho=i6Qe} z>wK+`6LEow0m$Y_pyuL+PwT*T{rIgljQUQBW0zZ%m{hNn_*=J0QErg@1xo$A<88w> zl!9;iDx$spNBRpC#2mJW)d-%UphY1xqWT#M2!0m;{+JMQIYH5&fT9BhflW{4mkNUT zJ$bNsZXg>GG^XLIM{Lohb=g{0W(lN^b2#>w*~#=~O%taH7i+&+N&n@xI!2_UC{>!?LkoHx;4bDroxZMhCqT%CD2TduMQ zA|D0m@F&E2my&>A6Y_Fa7ss3e5j$U~eKyHd+Fd#a_A;DI5Ndrk{40zRYOV1u4q-{{ zGrQEZTL#)|3cXpzNVJ@YOJpo#B_$@wejI&ufX)g^l5v6rNXJ(GDw#A|8z!6Q+RA55 zYnRCwNsm(<7s$h){u0&)Nyebq0A@4MF@0qKWUbUKYDF=uWh4rnVf{!jF(l)FQiH{V z3k9YcQV@f3JEbC5#xW(CQebWXIM-z42U{<;L7i6NLpk-VwC}#85I9(j+&iX#eGuaZ zE5DFGDasNQ;#$D%)!0;c36Urc3dm@Po!k(p%WEnUhfF?ns~2$7SdC_z(5b7CFB6S6 zau*!{0MRB2CiJDA5NhpkB1hYD-v*T;U(arv-~MqZs`6$VTfID@EX9PHRiIj-|2O+D zyhh7-!fIb=zHb9NQ=?lsevVv6$kv4EG?PY(DfJUwn}&4^<$VQlMJzq4i9Wair&($O zP0;3a?XtgOZzOU!8uj4LvuxHYv?><-YM!H8w!(T*(4;wA@_A~-y3=7V!xW(WV|2RW zpCFCa|6>V3ny&uzIhywE=#>~da9V8qLo;MPsTT{Xm zO-H<_y)vLBPJ2Ba`wbS`?tw1DA`Tg1AOdkKW+;VXTugnbH)v$|4XugtKjz15Jn0-y z%z2%&+NCZaAUHhIcWzpv_xJM(5ApZ+3J4^J_=QJ!`Ozck(Sb~+ABSZ7C-`KHil}t7 zoP$h6vp0h&s-iC~jZR*dU$;Yz+NUSktk%>Rhm#e|7>@ZNRxzt@=txG*dbZN;BkAr% zp%rU=nJW24H$-YHge7mnZ&*jQOVy>nqW)$Nm}GkP%6{)qGvV_g(c?C&8uy5;c$|03 z>7{#^dq_1#Pax8!qg`i?hiy`B?AsWBLv(_=jiM|JNs>oI7fge!Q~XStOs|-xZ?;h7 zTv1M|_1ag9N99FNKnX3@NVWb@%|?CX>Ge_J1%+ESY9AHRvIUKiTd@zNn_K)NZ_!El zxiULz4u`wtfbK}ggd69^0VSqIXa?6Wd=Ow}u2eDG;HNdEE|T(a=Lnb(?!3 z>j*Pr@xT$SgY(4djM?sS4^izQX($a1z}m@1#0{Ip7NTzrkv9%-)x{1%JdySgzMcJ2 zCD9J&06#Po(e?-<(@DikAhfu2=$h<+#t}E{-L?>a3a)LuxtP{W;)Eu72Zxcb)l+hd z3xf-iDn&l9`#`Qco%Cwa1@wgOxBVMi^y6(;2Rd`v6c$Kxl@P<^rZpUqj239zV0tN7 z1Gtf8BYkDhCBF8gg+ZKPP;Nt!t}Cc3n;o|$$P;O08p=0~}9L1G6(^3K9|aCXNJZ%I{00mHp3h*b$EFKg(kr&h6y&#s06Vz_HFu;LTo z!yZRYUO@qD1jH!=#@NV0wBkay80o`qKxVp$*;~*TNJe6I)>z}R9vJi#@HDYyBG6~6 zkfU%a5^Ea5aJ}1qYhd@Ilx2&MexNl@%m)L)Vhs_K(d3l{f;G+2L*Ev6>;_Q5&9AK47+D&!-anw!mtK;B zBvlGfJ(CGqOrWqN6h7O^DER8jCG4?xmB0X{VAp_qgvH6kx$kLWiM6)7o;)-KEqkfu3k~%jp#;&)!w3%qe-q^w=RPUJ0j>$Ex18!*u;?d@F zu&e6*HbNMB&$3KKxF$Z-v~(wZXH!$G50;-R#>}y(%LEdGF5m5%J#4g2s7l!PNw6!) z;vp%VeQD_}EP8FO43!!edvej`-!~D!CnF*n$95x|Wk{Ut1iq*6voC=_&&CJq>O!@b z8hgdRf$ZxM(p}XhD2ewcp?m zpmMnlu~&RY3AtR?F_qn|TrQgSk`i|7{Vra<@v)x`)jPma`$lR(*TVMTZ1#T20X-_b zXup&Q?Rj2h*+69Lwo!CjK*s5*3#XR^Z6(kRQKK*&f%eZtN#ABrx>rSE5hNBH!HJoP zaD_cRh+!|M$U6(R+WkeXwpUt-O4j3E4wuo3eYR2-7r8U~wM~=$K&!*6ZpG3pfw3~D z|C%HE(lqId`9&D4(ziy&5npqRnUfzSGV@VULckA~vWx_T1T_8F&pxxcVV$TfcP6jL z83~1bkdRc(VdUjC4aKwHL)KWKma{A)Jb}TT#li z2g=k&wqMC0iqcct49JF^+%Kc3B z9>g8jJWZ7hFH^>q7Q-VhSIEl#>z$1RrTlUqDEad8xwVhCi#qUKz9HzQPOkYPD1Y$o zapDv5S*smwN|nFqI|3b)AE9Tib>Y~Ty9}POvG`XTPu3Gx57x66 z&CA-U!3}-M=_%Al^<}{y#%KHLz^Ft)Pay^DpR&IqeP2{i>;kF^(rv0=E~=UP%m7LJ zzjh_|3``BGpUCUOK*^0WH$g?y6YYeqtE$pF$udzjap1jOznlPcC@4BsDZ7r86Mc@r z8C2UDf<%Ke!()oG1W;~(UeRo|>t+rlf)c~zq_(J{{2*v2qCt+uXF-lSaws_DQu^`o zBL!zTL%VDzn%W40XzliQd+TNI@%GWQRY4#FkT0*%QBYOk^`PLWs_pZ){yM^lp&fPf z1Q#O80-}(7D7#ua3411*>Q)n6)Pk@H*8RS!nTdg!GneLW*Z&c8Q~_#_hAv+DLecIW z#;TIeN%uFQW{ygamA})PPMdYCv9;0@=j?z%}9ZBDp@t@1|sy7~Hf)@O4s8d+Bg=;o4uv*_A^p!Y5= zr>)h`7nXh?t%-c35mX4;=<>a-6$Si-;VTj0EC2Tic9g=F*2}l2XN6eajk8;ziJJMb z>F`Io;y&@5y63;t90KF~CBd1`hG45VL2*l`PAcqwV1NJdF5I!&CDFzdW8+t={0aIE(5NTNj$O<0v^wnu`?YOT(Ry_50cy7Ho#=k zi`I(8wxqr7#_TRROcTXcT(p)MA#!Y0mnVbmpnTUfr>co2m^$QT`hAC@f3Hl@-NQn9{$z^MqT=_qPFDq=3v5a-a`u24RU)R%-K$datkslvvizE$Du6Fce zoBrM_i`}^Ek<@Rn93C1dfq6MdC%tZY74lk~3LhIBPUF`W#;zs3VO_l82?VSQJr;IA z%sSP2_C(me0@=x4&Pflncu8slCVN$C^Oa-*hTq5nY|> z@nlL*UI{eX*ejaqYAU$JHb`Ez$my%T1vMKR^ zy~M@#*Ln{#V>a;F0sZX)yf6jOpSud2muSby`e62aCaFR))bw%L=Io{)=VZ#|v5&E$ zN-itP4y|ZjJZx*A)?_DTvmI{HjUAC_K;6=WOZn9+VH- z0Rj6+PjZ6ea0}IOA#s^k8TN7Twgc5g@ISwTtcUXe00urXH;T8CJSE&lOVZo5ZaX~J zBAQIm@DTiy2?G*b&UzcLds%0Tg=1UD@j*D;6lg5^9FI6`hl5wTCZh<_+*g2puqM1--8R=eNa4-$3H9vv)|uoM9supUzq3QWqT=6!A&VKiVJU72+Qd>=h6h9_bYx z5kZb_WPH&__y+qjeFLHc{R{#3D&3{-^QKnew7vq``A95+451{*3-ju$`Qj@C^BXDw zCI1M1=~BAiFb0`L5Lf4B;N=H^8deaZt|X*4*HX-`LK87@!To~xk9q{P(3hFULnD?7Zds9rCRdn^vXY%lsSp#31;%I0S7HBZ0oMX#Jylc)VNyVb#jwe z=fbU9K0ULH4&Q?G^@jWHb4$NMg8`P8H7o6Z8Q$CzwPW`>%qc=M>hSv!IQq)``zMV1 zE~5_iRB+~|=cWx#D939k^f5v^D%S{s{hnJU@UOSIxYClpk}W*2la;t`r$B6GfCS>!?PE813sGe;m(E%hs{gJH*=G`0V_jLf&g`~_#ABP0~54}X5ER5Pg@eaw;&Y&3Oja6XsOIzHU zk}M!vf#3~=g0`o=XLk-C$v4s4{czm6_s)T(&yDl9%6X!s9wWr_XkOC%V96$DxG7yQ zx$0E~{-WzxY;GF+o`lPFP>#rGx3h+~Ch5~B;Yqzp$BU$O8*lOQMqm+!MG>dUI+^5e*aP2id3y4AzK*gSAT}5gv zPok7WbOA-lcirE6-?#UdGUd#Rp7z?0t3Z3O^$? z1)*!}%Y=T)Abe}XWM-N8?^ZOU8iKJVgWuxg)4np-iX7kB8cM zr=jXYA%PvqIo}pTB$mXIm!0Rh&O}=n84(@XcbJ&DFWab7Hq1YQ4RBL=D>1Oybu(qF zvbD^CiIEJ5@Q(;5FdZr9&A(shQBl;BDomArDWc#TycNzN5<^8U#`hEUW2|rg1k!d4 z)!=8*7|JDgbE68I8W76}UVqmZm^PQz#D!S$t~ZB5y@WoI_SFIQ3aB#9x_?4>U1F2^Y-8( zeud+3)aVVj?0pPhfb;aZ-O3R>>6MQlmNM3AS5>5asaD079qV)F;g#bvR77W8z;2nnyU$ z^gkZuUy~l2m%~_d{Ej!K*9b={f293VvlSR6Ji~Z3mtj}VZ)yq!A`?RGw^@TLr?R$u zZ!kwA1030B9*tYv2@44x1vAepi%+uo{NikHE$lD}WftBW%^t|uRMe}wa)tfJi&&eW zd7~A@FCyk%+_@vX_|_fuU`??f;ufa*a);OHXYZ=4!(X54Jx{ zcTf%S_2p#k15i;)g~8eTqN&zWvNMyc0HH@=1i)F}GBwB|YyIT}S!uTesL~G%`x%_M zq{n0jn8bf-P(%hmmA818_5eux9mWpyZ6IC763hMJFju2cLC-$*^Yz}BAO@N12-1cJ z`A_NEY626M*$IQ9rvvh5;}{1Lfwf&lFrXx;VZF^RlAa8L`kM-(g8`H=nhb*?OoH4& z19BapFuET~GQ5~fuXqtgvOgvoC#VuZmLtdv7_1&PBp8N4!??JwsOO1xi$0ei1Lc~4 z@Zl{}M@K+t^b!b=j)`8hik;;i+PmqBQU^L;-#X>3fN^Cmj1;k8ojZ8QRLL}QZQ`-g z)x(bWn#SPC%a&tPz5xWdb5sh+_?B@PFVY$^#;JdGD2q#%{ZJMhmMg?e=*7*cV}PcJ z25LNP^hLLakBLC7Bf-ERus{;b`IAf`=ZfWpZ~Gw|V z6UBxvfxspdV!5VxbRmG4nM(*^IzOd5yJ69Xk!IO(ZTRELd2~>7uQnvAt0na8105YsL&ej zE{sxxdFrhoeoTpo>K8u@SgM_OW5+i056Y7Wb&mNt|KJ6wL0Xg{bvF@cmN`Lt7yNq} zP?ojEH69t7)Tw%c9d;RZeiNG4xB?e5i5#g%IBM$;)zIc^6dL2xcaN){hg)Q*h&D>% zeqU>dWFscna9+_DuyhrYAa`Hl+{$n}|HzKZsvOd#I^qkdt&6LPUdAhQqSk0!ar&xw zggWq32r?ZLjSsxP!fK?2Az!ZBhey@6M$>2g&N$Hgay>hLG0!Yh(XTwjMw6%n_B@-P zmQ=F^R){u|525*~Swh6QmZ+X6F*>j4c{WD+NMB5o*sfvz4U&DM zZBGFRS!&)>KOEIx$K7=xD;&6>+{$o7q<4nG3}o)gO$2UltH`hpUez2Wfa1L)c3@Db;ytV62b(ufQ@F9RnCT%?Xiq#$9NL(^9$B>{@Br`V-E#Q)6$x5g5 z9a}X?;6}&e|7!bH9?jG%C0$<$s^|0+N0Xnc-$IjiH28yG?>P{hbiOE`#>$v~WyuSj zcFjk|ibXCL;*^_CTkIAi&c%OT-pHbH=AY^_?DtJH_Vmbh;;MYLNUuF7VmOs_&g#4a9A0h`t^vDe5L4f0Rd#(;w7v_g<8D<3BNHYjOD&P6!u36;B& zw80eNSLLhSj1$M0YTSK08|Xjblv_xc&nzCUVHfVsK#+^lu>CEm$spt6lys(h|C=>( z7$iRh-f=HCv_X5IO*mzH4GPx~GBKxLN!x^@-YxZE=7w$87)}`Muzm-f557q{Pqgrm zGZBq+aT#e1J>K4@k)QvSkHZ`?wE{G67ho}!A5kF+gViDf`IzPE>cx-M+Yj@2xIkw! zPxNLhNy5(CH%)}3Ncqom9lI89QEY$IE=fMqAGcQQf(e$zppw-e70N)i4wM(*u)(gt zoIl;&yo%fDDP_O=JM&+df=i0KM3*}Z*4>4>3K74#dD&KBop?5)v_+Q$;VOSkxZ9~- ziI=ITcy2_9bAgl3hoY0b%iq#Vf11*Tl*zvs9*EdbUfQZNK0SC^8m=tE)-qp zwCL0dwKUS@ZbyTmtlQnN%;+IZ-6^NfNwR)aQ1nv>x4=H>P;qg&MAETrUGYK^!3k@> zN8CxzKe2p5m<{Fc%?rsxn*1tXPxNvze=Qtsk3Rryxof@0np9U;+qB~2#r38`$_L-@ zx87#mZee+IT0hN4n93v2D7vg&^UgGmVm#Hnt-5QGgbn=>agCN zHpvC)v4%LjMUkF41O!uO_KdP%eNt3^} zJ1qAGK?7Ea5tK2m@ZuFF%FamPN^bUh+nSX8oNQb>p zgY<2CpWX^0fC?EWw+KjdZrQFUCxJX~9v<7_<0bQNt|giZg3>%r?Cb`_lF`JpHNmDc z3;7=7F_)3%dC&!TO#w;ogF4`ex<_o}1*nZu~V@5OOHikj*gGq9huY5T1fehyaDs6=?^m!?Y17{v6D3Kvs;(WHhvat%zJj&*-zqaSPdq<1cW}?r!@(_up zc<=3!akHkn5}I&Tf>q;lRkclS{_oAYz%2LY*8^5xpXxn4IscgtbR*FkT$5ma(hTjj zGzQX4Lm{XNUw}3?mukH&(TS5m+#_e%^RE-7(S?CSZPBpWeJKqf`{?-@?js67v| zCZ}yY)Gdqvz|$G$Zl6t}l-e0n2#6YgyL;P0Mw5Bp_tUNnF@8R-=tSifSg z--B6pqCD$__wlsRi4!wH3D$de>}y}--fkm0S{ssaB;iO#a5TWin1}a?vtNXAHE|*6 z5c3d^s+#u7tb*B|hk1^?oJbY<*AcgfTcMG-gZlkJ8)KV$_OB27vq#j#wECn;%3e)P)2xS*U7bHepVV7Sr=Wi58qSR}&nhNn+%Er_4Q%9px<*8@a{n-qc zW*mtWgb1S6>!mwH|BNahH$wlsCRZe3k$ zG-s|ec5^K6O08Djlk_%ejB!$T#jLaN*5~@_+O$qmEHkiYGjTy9U%`&{4fAD8=`^=u z{v0hFkEzu*=8BW!Y{MmwH|*IU{Sw^KekZ*vq$?^`lUUcax38Ygb_j2nqHq^FpsL8>rbmR|C?j;$G=o!n!}iq8$I| zaU#7pinaJ^dt_FFA{;_>f^EZ>Ch!e(`X%44n|Q@XJn$MHPd_P?O;AJ0VWm6ExVd4# z%e$Y$PMz*t+)4ZNJe~P(GC0+;sgw22e~*0VgTp8_i}d=I-k+cvZkY30VUe~F`@Z1} zI(fnQ;kI;gSyf&gxd8z<5uLuFX^P&`Il$H?b)(meM_I(~MT#`6e~^qj60j=%c7(U~ zgCkcdm&u?Z;?Xh>R(G4mA!_nr>j;5(>~uQj8mu$X($VpWEIZv=((xqx>c_U=#neZq z{FzV4HwMi=uYPi7*R$=;WM-(O^i^ptEI?OZk8XuA_gq*U0q%u?nvqMQ@f%P^5v#QG zQih5!@AlNdgG+<*_Fd}q`($uPQaU7mM|v6t(n~at$?bSA;7|>=A$#c^1*W6tJP{kn zdYXFb`0*5+(@_*fW^bJlBJ(gm>KGTUc@6E`o{m_1-h~(m@z-`=wCgkYtYe-$xAcf% zskue}nOCt38iD!T9Y7BN?@S?WCpGCo8$KIYXWF>v^r90%oeMKvE-bmY2bvCay-1(# zQDFv-VbdMxOI2rx3&qY~velSlsSB`%j~`8?VD zIBLMK-I#DhpAb{)AQ}H=(N}}vjWolwz~9m=RER#lnb74wBs|#v+5Z=?P>nqMd-VRu z2G9Ev9g1h6)?#7y5`$47`fXZzXT`k%A$-%8ZT%J0C8 z(J1*1S#Rwj`Tng2O)RmfK?cE9Un`t??*}WE!ELEUO4`v#U(FP{(P<`=MG zOH&XxGkY^T2P(}MgJdbUYz;KI(RE0z}&!y%Lq*h4KDvHl(=DSTqu;A30F3UirdIRrf|?nkHuFj zI0*PJy*_lR*2i^P+K!?}m>7uwum~_1jT{8i^FGJOS$3Vo!Nf47Z#c;?@fs9y=Re@y z{`r5tU1UmMF=IAdWWt&l6nuj54@sw6N1E;;oEr-Qzz!1tz^+{g^gT8j6JuTPx0Jzm zs`Q<7*tJjB1k`Ut+x_-o=KHL1uF6$iPwCv*E&NnDiY0{%>kj(f10eu57rD((x*Ya~ zSs#to5nVjEyy9#RKD!{-gI(75eAdVYQaJH&m3FGi(09=YyL2&ti-@f?8i!_MBkK3t z86B-FU;k*y23J+CL_|Uf5kE8QC3Udbt%^OhwzUyxi5g!YN5Qkgb;W3kq?58SrLuEq z`%GzNvidb1@jH`I;CuP9@Ea51`cmNaq-3TsBz)f>LJ9CRiaV(Qi+#LLwpqR zYP&sIXprc!i2L+U=OfOamwq#@NKx+tDfR5ndZW_s_Wce>V15Q6G+jj!U?eK+$dspwf?}!BHPWCzV@D&TB5t7i z+=SG!HqCmvR!GV#9z!Ne(=-?GPFhrny;qM`sl9x+jD#dM#k$Rsq{2tU{VGqR!KS>! zr$8F@Osyq-lsqx6FLTt+8Yk;k^;*`(U{_7>k<#a=80%FpNFCevDtT&Xz3@%tJGSeT zbfUhYd}a@Eyy}f3fy@c(a^e`71W85Zw%7!n`>e||TWNbe+Rk;t;kb#33D89|fZN>! z-|kg+gm(7o1`wCF^#cOvwdjsb@*{~4C@hcaYC(CUBG6N6MO|o5B>ug8-JU2z>5%_w z1aaqnn{~Fg=vgs*uaK^5o8focD-0?OtA2&7-9Y+%MEdfPj?z7rEvie%2RJmiOP6f<|r_vUSy^i_AC41nS{=n#z% zsVofL+|MNRe|}qkL$^09DS4!~>GiIK=N{DtCwDQa980W9v^Re#LAMI_(J?*MvuLEa zcix3bO?hauz;e17?JqFhfoU>%)O?ppfBki4+pSkSYAS>&lR>r!!KvT=VO_g1e`ek+ z@TeYdhjLoOBnb)9uETw1>HBIZ7FnC8yV~9)kE?TT#X| z7khR~w6nTfROu(_my5c@$~^711%ii?S4#PkW@npvdvHzKZN7usV$-&lmB(D|aJOT1 zIp5A6c||O`HgDuXnpHgmbyV_Y=UT3fwFxJsPVRl~UXzy49Ox$DK&!0l7NX9!g&obX zL@G<(sIJ|zG;rKgsn1khO>}Mx?U@u5zn+Nig2+`aA@8p$;z^-uvU@!CN;{IGyKycr z{9OC7w+A67TbpZNPc6Zfdg-QSuH%smw-#>T@@kVWZuXTt1CHKT-AIL)&z8eUw2Z{TlP=%S`&flt5Qa zZ85#4UXr9scJlMOFq&ICapQIFWNEV&Q+f&|+|=uNAC)e6z%fDGrfwaxE1T1@{2Kk$ zAkL11a`u}yZxB~`{fVJho63|Hv1UOcN+_5rTt}Tu& z8k(HV%gE(r7P5aO_D%74(fVWU$^ZL1DfU5nlLd@-_)vfMU>pq0b={zr4Qk zx|!Y;Gy=s8h5Tt@?+pb+xPj0kG2XLd&%KKodB^jd2&y3zQ9U`?f(QjoH@W;8?XvJ# z>WHNp*y|Y0pf%^b{X{zh;u1RoXWSFLfS$9_J*6XEGr65`WY#uVd!9SoBfb$sIfWrgc zXxK0YBMuW+dP!Kj0^NYAWF#$$o!FAZLe&&>J$|RcskW94ldQ&!XMJPyxz@ zU?u>JGiGM<4j>r6z+&F{hW``te!R)yD+T~R0_J!u=BIyA#9t2f<^T738rX{gcz|6g HhH3s6`=5pE

Y_evqc#q=9fuPAz*H7egHUL2f$XoY>=2fIncg+uJ( zKD@&n(O~h!TJSXv_mJfnd{8>-9NkV?oVU^Wap}l6!|cKv^b4m4S|tD3gzq`pg6k2X zodC?#XDsKDPNBjY+p~s^H7#}6X?C*wT`J&DBlev3uxsfuua?sW*(_ z4J-BL{@-0`q5x6rIi~Wk?=oQ>D8h2WIt%NZGUc$_le3hq10?sgkYVea*lx&iZ`(sR z8H75dlGp||$*T(>qL9amK*s49mgZt%nPy>Yo6 z&O0EFEYCROI)vcH``|w=`rFUYwCu!vwwC?I{zc}S5aOGIGXH&{%&kXoHp}coe7eL{ zggdC9!&QtqzLWy@KwE+q=@+OLK!`&|FnWMsBRw!2RhyTC1h6vdPBIkr125&R@^n>2 zrUq_)=1}tAe?38WG-KX0b($H15IDn#!xTTPiy2~N%Q<=1q(wPxyl&#_ny72s?bbrjkOAX^en3z6jnBGa^2sr(&p9^ZcO=MC{ zHpy9s0AZJAADBLe*@<qI|sBqZb9GZc|2@FM4EDWjDcXj85k`df0f_5M)>~vv(LB zuG4Ate4zU>o4!iJ!6Om?K(Ek9-cvv~+xojdVYUw+(Sg=a6cO|amXT*d_}UvkcW+A3 znshVW^AKhvo|t^E2glNZ5d=cT?c(L{V!_A?U-6ypqYMb~JYD1arUM#MA8?$S|IDoEAGARjF;8TROIvUM&_8vh?O_~tv#(Xk< zXAfQ3;{9IPJ0LvP`pRvV$l|3ojlkE<@;*8Qh%G}n0+9vw(T`;OZE&49gmOcCyv1Ds zWC_0tvJ7cUHB>`iMTfL81FQ((tAr5MwQwuaRZ>Wga-)G=(&@yhcZrYri516Cy%!g~ zgRo8$o<|c+nCIW1Ej`JJ1d^V?iZ6xeijZm9!-+SPKF&hPvN>I{WC=vUT<8)(F%T8M zID&HJ(y^1wrC3SCE(5B2%`tiN-k)a62$wAUqCLGI8J#_CU6e z{qC?a(|gqaaAani(S^Z;K=)JnZ6E?e_x8<;VeJ%C71>5ddKN*}%8U|mm^jq432-c< zR+yOvnq%%X6%OJr6}ADN1Gf|TDo68u!YbV;>_R(I^6^Iu?_r#g&3parIrI)M*l~%M zmR29`GD!=TxkA6O_rh9|u%Cg7RT0l|Ov3~Tvxr@<=FSESCSvl029H2zR1U=+>*h(* zw2V(CwyEjn{8K1M2^;PKy$CS2Tpx3))DT*~Us%w8Lc8wMnl?!(xZ|ygsV?jufCtGS zod_rU^z?63xcT8s3)W{+6dea_Gf185a-fo-9DHu&iqo#($98b%?FmlK;bJb)W*Fo< zl>dP>LBfn%LG8P2wvrPBw}bDFWyqOPSo^RE9LQ|6yl#mWfnd#L?x;;Les3F#A7ua5 zIOsY7KJ{lW0R#hCf4?%iLVTDY`A5A!ChBssrEE;Mn*#v4;FSofjy5Z}(>tYRr%6n@ z;7Qx?Jwu@C@<+tjmL6khH^E@yi2-5bO5HOxNn{umu3D)T4LBH@%@d?{>Ar&3YrHoD zFQa6)?`h3sP7H9jC9r3w_>~pMpP?C4zaDx-uWi2kiGmG40Ny!Ym~ejc%xiUB8~>4? zP6u5Gb6AH)Z;a^%v(w)%K2=_xrcvpw60~LD0GS?YrrXfJj^Ytj0=8r^*C3gCp4DKe zVHqJ8eadsUr-Zl#I`sK0!Cgyh3nV}ITK~Z1h58~iOit)xr&$uXXvHK^=06(Jz#LC6 z{s9HMRg$q(S<0&ZW;VRuXuzMVS{Y8DQ;jZvb$Klo6bg^yIJjTQKoFrP(Ej4yOH z+N_`UKsR?7ls7y~ZPLJOy_n-^7r0&42hnW9RSqwsWFBkDZm#)~RrjCr@g;RHU~CDa ztyXY%SzggK54dX!^eicjrj{2wX4q=vSuA<3s(3dpIV#c_-f21J^$DC8NISufa~Y~t z0hvjH&|c5*Di~zjDHP& znZZzh5SRPz$7}ZsY|`0JPU;3K9+F{TChaLZC(5h=zLh^e*1sW>8wM8BUHLJ>|~txo{FIGc z0(YBFyPR2;Ln{CRqkp{|!4Km{IG#H+^x(!jW#!f*`~`3-!s?~LA_?tCmphh!;~TTb z#6J9~%=RGKh}@e;Ef>=8=|hRXT2}KPF~NSn#G+{=Npt^}noW{7yBfgziF;H_1?LKhlfZIs8Dt zvrsh5UW(NpYQ-4EBwbviL}T42E*-~s66#V+NBVA2EYE2Fn|D_g%Ic^t*RRp$@hsL2 zF#?K#w(KTSC4+p|tV7T0#ZylU&ylYOD)Iz` zlLAtW2V`HZ2KoH9-PQlDP5moK!#4=%ij8tj7SVrU{)#OEew(00u(o{rxkX^tiG1N! zeE-&-g6CTmhb~$UZz-c`sHE^<-$TtGutOi*mys2usQB~PBf;&oMw8QzSKkSQDiPDW zR)ViJ?TSHK#2Z*t`+Z2Hq(r2B2yPEe%qYyBHLdnLpVQ_^7Yr*F(q+S*2o{35J4k~b zv0E%JN<-f1ngFwqCBr9L*DQJ-_~;|@(GkJmQcwJK2aDRAUtV3wa{8tguupX~A%Zsl zXs7}?f)I%jceNbTK}ez8h}^bNWzB3wpeaT!-*TS>u+%153TTRD8zQ6knP&Wxiu^W3 zr`?0MYfdQgmlgR)5=t%Sw6>XIqIE1X&Ivzjn|q^`Jj#8r|NF z^;*7{r@|9Sq)qiatj)=EtW&i^O?_Rgko@#XW+h2%sRt~`gE`dh?l6XsiKR;WW#I7N z9Wh*gQOQt}!eRv5eIps!HCNh&p}W=&Utw^}vjdBy`@}HAZuIYeI+P~pfm(a+Dxbmn#Xxo&c1<%S ziZ;P&uM8T7O04j&p_c>_wH@z+{4gG&(Z`uh&e1D(D#t{f4f4;Ru(1gOVCuy!9B{y zx#cUE)n9B#va>;L>p&&5zLz#-!w{sr$S}zKtACSG?f@4i58LrVe8P)=wIX842D(&@ z?7Kr$(`v=;dFZ;hp#M-;D#E!1sE6W?Z0DPCy)ps2w1N{+`g*c#9J6zaYbz3mBPQumG#c}YUg!!M{81F708;1JOOJR zA0Fr|%U_%cB#k<%f~VzaZ#K`fCt4cIT%xk@rfLJ)ugF1V-KAFHP5eh zR$?gg8AMaJR}FRz1nw2y+h+<~qm$8Wu>)FP`CIpDPnOKcWEH&MmyO?VXdPu-pIk2I(0b{XGnkaJCE@G|#~Wi-hJ(Hn`so?+s~pkJgH zZs0u#gf%}esu}yuy~PU35v+R;yZlmRp^73`Sl({Dz~p!C`Au+>2wGvR~cLF81i1Lta_dIl*`v zupF4#&?yW-sFyr6JOze6HjjW6OI}mohf{PisjF|a)`3rD@6fv>hfW9Y(F8ja`=FYo zZctI9dPss+F|>!a&lR|qVeL^cr}QYQ(NBq2{0fo#Dbpb3>VhHQ9#V)uc=gZcvKHHv zIRdZ*SBSSJAg7~_NBhYRIxL~T+%ID{18g7m^Kjj$TS!KLAFH?O+Ce3aHkaro&>b5p zk{b|0gXQ5AV-3L+Gzik;4l9t$UYi1?z?PJ{sjy8J!%trK=w)a_L@8R-?%!^Hg{RrS zZ{FX!)3Z$`uOo)s$Hm)UW;xWSP29fsouDX=aN_f6QPa!$SAmcb+RU31IgAXQ|-8Li{gI*nGFdI8Af~%s80<*pAEi zd33+nP5oW`_BT5$jfHvqb$0uT?}AE^=l1fC?sB;Zr{qC6rsII3%8Ed!ls0>OyTo^c zI=L5P=E0A4sGKzdRq)hlkSAh`Lll}HCUFfTqzONyC`yvHojguFzTQ(GK15%uquJ;I z)($G6cToI~YF4xag|{_t!!q}J23*f_OByK~^ZWGbc)*oHrI^!n*ygs7-t>R%-TR4N z-FJXm9(jI0>xLitzgz*opE-FBp~-cXfY+neAN56p>fRXa%vScc!xg3`0@mRFcAq`Q zp*oNqJe@#IHe1U;QVJ-5UdD~6EnI%IOiheVq^97{Ailr#!bU~p^+U0y;Q5LD`K%%G zP{Cx&B-NnSpqq#%lCiKK+794+r6d1(5Cl9L#Lpp`HNsCZGpco`@h^WOauwRhGTIBz zWEFo{eS0L>ta~nl&A4YS*W7$A{#--E@d)S>& z#Rt(gJ5L(t?9fO)`O0V|&<(^@*ap0~(UGea-MkdlKK<;sOZG}wHi5`=hi6+IF)@X8 z?c*Cp{@k{8KR%XJtG~}pKfC91hW?Ik9PXEoaUT6WoJ0N{`S!0nI1=3;|4zDRKq#0J zVzsO&qiRB}QfJp`BPZJ+SiCJPk~JqB3A>1oyr_vB91%@F+@Tq$Cf1jD1(ALg2{ZH! z9QKT2t%DgcDsSi~14twHL|cmuc8Fh?v0EW%JMUc?U?T%F+V||m_n1$2SYMY}?B2~7 zToP>{9KHpm;rX`j+xv2U*pk8zv&_U#g(5n<_TW6reNL14iS7(h&x)8Rf~7$&ThV#g z@&edaofXM#Wr8ogpRs)wzlJ&Hv)*@DR`pAZQ^SnX%(GkFV zNM~w6G_$i%J3~P@GZOfO^Hn-#<0}ce4{)NPo%@OB`-4z1b;FaqXKK1;g_*7EC^qxM zrsN1{O+HnRI%~S=mo!t}CZkcU4sy9#8qMQH7GF+1aNpMKa5}I6E%1!eU=t6pV%|43 zXYp~`nbbq7<=GaUG66>&=2piqykJt%a%kpn#Y}|8{OYl<=(8C*$V@|Uwoh0eav>4B zC%an{VZYm2Dj$=*2pp(aoHkOIz!eKLO)^}lSHHw2?~mExZw%fDyT4aHGs}LHqoTtH z-Byq)7L_nh2OV3ELI16#;OewTf&zmjtzfjcRSHSk=;MG~*b%f{&vtBox~;Br$8E0G zZ$=p;6#9>((~bA7QVAo)U&Yn6RL7>n}kYXeZRk-h=&XMv60hT-e;}24LPd%WoR_>FQSCx(g!z_?67| zeu>P2W3cRjD}PiKd^3o!tqjdiuJ#~<(cC6$)s2VV zoqiDQboDmC>en6qX=Tc89nY!uS`{{Ri?Up%oIDV1@g2m8TAtPDjnw@Mkp*ql%28}q zDqRh<1U;{*aGVhHKAXoT8R8sS8CnxyT;)NxN4NIbL^}@3q=rzfa44l5yP%)tSZfaD zgIwlr^{-`GlT**L8dZ|$clRuPbSPg{4Hjk^Y(Fojazau|f{PvmcG!pVpxM6a-j|Ck z`mL@8%D8~j7VHP(uX)H)5HJ)N>O_09>NOjQ1IbS9F=T90PtMnKfYnpchLWClFmCAY zDfb>Vv_7!pR-WO=Nbuht`0!$U2{Tus2oF9v7MoG4h7)Q_S!(ofN6lhhE=ixs|Es=V z0~fhyP(2X23A7k33>{gNurgr=&W@C{Wc!vG|~S^JD{S~9GLZ<`>q3M##dFsH(W@b?ck=`E#M}oLVbuk^2*tZF*2%Qd$zIY(#?E&<3&Z*LDD4(i$!K^I4Ymr3zlsBbeU+2 zvRPy{pgb();B7x%FooQz&w0Bb3U`(#MfdR~jXnQiv#HT`V`zm8g>MtQkcm@;{xts-;jHr%r=ODuE#nu17lgp^-i2%qnmiWa8Ga&?Xqk`CQjQ=ok~Gp36AJ&0Ob%MWM)%D@+$*Gi}S&d6X?`fb}-P3Ge(dD+=;UwAw(d*m9g$|omBi>S^U$w9B_GCi18 zw+#pO?uUlWiVQ5}@#wV^^nRR@)~MkT4FKDGv-M=!=GwGgMZFfn7T~g6m%?|BU-pL#>fVGC<~cb`TUol}qUzjtxTd;+`;5)O0pJyw+nS*QG)2T}7?l1Y){ za8dDJt7*t3StX)2E1S9#W}rObOuhA()miPcCavQpy(NVLu1%&f{%^ zoR|bM1s_&^3VP>Fp zI1U%ZfnT|@!mG>$q|QBcCmrsbcaF-&#E`~So;m(|kQ))yEKYj`uKzzBMJg7kWsjGZdbnqLNwlG7j&;GWHy zOGd`z?8x?+445pB0UQU9g6c%_-PBd8?})+4wFfpb+J6te>iLVWavt%fn%n(2ADS_* z{=<;XS4}G!(ZbDZ{g0vZ3`nZ&!#Gn8f(n9)6L8Pe98qc@E^;Jp%S>%*Hng;;R6rac znz%|^YHHcGvO+DvZP_rh)D~#=J{App9!n~V*KeHjflnOHegE(4`u))PzW)ss7t09x zLx}%qLc7gq-n88_@SY3^wt0HIB?GeO3vQ{%{*S*g19l6IFAl?B-t;UUcD2W&2mA^* zx)aay&i9=IkM5h<6_+u0RY{#ZHUnI{p4GGIdR9I-KP0C|R4lSR=)-`O-GZ+uc?Q1i z{WrPwocuLyGW_<#d2<-=cbU%QxhZno?K%I|b9a|j-1n5=>@0}Kl`f{}dtDiw2IpIzPywmeZSRaIqu zK9#b@ZWsbxFLHt9QuC}wEzD~K!zX$2zg5y>;P_`hZ>%29(?BNo!yLZ7e%+nt6`Gg1 znjjZEv+GIyDM7z+pB{du;`;*EM?1GaWukM*r9D2JZ&&M}cOX=>B^OBi-G%py!{nl! zFs-t4#|-Q`BVZZPr(SiiU-~EE#Z zZ?6M9dxl!+Z>y(vr3pYhI2)o2D?9rt2k?gHJ|l<4bb#vHjFYaMiW2%^AcrssH{Dk1 z21{PAx6Oy{48bUFp*+>wMy@W#0t)MOaq9svnS_CP9RbA8dVY4(89%1g^+@fv@HS6# z;LQ=*Tbh<|1*Ci2EQTH${1#@p0u>jXGYSR*U$xh*VO;rLgviMoPiXSPq{Fmp# z>z*V(L*1eOs=*z)q*$?P^h*3Ul>(35g2J{Y!?{MQPz|IT+DV@E^i+IXOaU5L2g!4N zm8A_c*usbx8iA(*!Kp9u;xYS8j()h@F3{IosizqU13%XXY4(7wP;xL_=gxWU0HrbQ z5^T8{VBbDX{MQhwXykS;kzY3M&2N6G+(L>M!=7sF_+y-H*^~9ju$&R|N&wcr;@j>Z z=I}P$0&g(?gEN`^0J4g2=Z{_l+raCip?3Z1KPHsh>p%RNFt}v3cMBh0Pt*7@Yc?fs zf@Y?gS4enWqiI&4pkC&O%9Q9kr?+cU?lj)}wm@8Wy!{-7d;7-EUnnd+PS;p;?g{1F+ zDXoz*YOg_iEuy>ZG^FBfxAh0zcP+h+A?6?<|aXXLa1|gbRj{CJMg`X9sm9XUpY1@(}eHf_cqblqG;LNkGx&Y$G;7L8}C!3i@0>LAQ= z1AOz8FT~_p*!xgFoWp6$cgsOfGHRnA>7vDxyUK|p0XO06Z5L@{wWWppU(JE!ciYVu z*|L%YNMkL4F&dnsnknl9krYNd7U|KnL}^F==JC5ci{R*NL|FC*eeeYiRTzJT`^&}r zv(01{pzUe>Cb6cM8HVVB8ioEix16sq(d11E`w*cnGT{LVy$;l!^D@na8n<`+ppukrc;gL>&cpEZ z)WW0lX*Pmik?MCbOK4)6{N&&QdQ+tEdCJGvVYZ1lHp9S{RR#DbN&FZdmK}SP$-k#a zUb=Z2RiBHDtxr^q5HJ|PeuJ6rg}VN)x)>dt6&6kr6!f}}R`xH2%!1Duhlj`BA|QDY z!{eV%XvHFRIOjBm0))RsZ}$4#)G4*fv)6?I)^kQ}?xv<2ZPGySxKBbUxbT$cUlJQT z^x?M=eS_RHl;uho=rCcJ)MDaC_JS=>Egw(1SW{~NbQykh6~*_{8hKzLd>?^yMk8O{ z;8iZCK`-x13^d0?bnT{!WWeMzs;FEI&5(6$-hGhD&6^Z+m`F|8ceK;W)9X6+{#Jc7UB z2z;f83QdHNJ%^QOtrqO7T8-CP`j1?URuyWo^u{j}enC?xeMDg(Pr#ly?|}C5+nr@$ zfSCGkknBjrHQ$8UBkuvg4Qs`2_tOa>@Yw#LWT^g{=aL(+!)|&aGa--nj=J`$@rEZ)Pvb z;zq(x7~5oeRE80CK=vj63$wCh89pDpr0>rHkJc@&**3Ym;16<9wXEH(^EEWPGTGfa zsF4Bh?{R#UZG@_hfawax&ST`eK{^Jmh8aDf`YMX1)c^3tb)KVd8yfRq=6ys$4r&7h znFW($4@|EqEmBqk%<32t^V93lu;x~Dev0(0mi!gwTd)Xn#FyTzzMhWE>ohh`erwgL5n8RVoiv$^BFpK} zhwFsUwh~{O_be9ERvaDvqb(k0)VXE+zZ6V1hHg(dzKhJi3ionCB=A zbUcD1GWzhv<;yvDt7wz`0%arYZp{n5SeoGziD1-0W~iwLNitvVshEok=Hy@>^lMzn z0WBk?WwJw3&%%b_>&sshL#pPE&tVdUDXFkDE*`%CC%p&i5DXf$smo%zTFy6 z$j7oXj5n>#0X1e3gp5$Yyci%(nHJ8kWJ!7geB(=Z>c;zSvX4LGskEKg5WjA83(NfA zKN;KSfOZTUqPMX5moHlI@NN>Uqyj}G;4hnTZ@`uZ&7ctCrj@daX3%@cr^ab9DPUaw z#ANx`wTXB~955dXzgXX24yHgRQ+>qO5^P#fmk*g=i!VtLXiV4NlQ>&4>Wdqte7JUQ zVQsxk>BpIE|0~AqT=ZFbw~Z;5r)qYL?#N-18ryaE=(gqFJl2W}6pvC1KhUPyZJI^_ zpNNmnj)0_-lh%nrPO92=l$kaZ-cM;)Gti%uO*4jP0VGBqo#xZ6CWnio%1(~Gv44L#1@P=5mkul!blv(`{93NDIO|?7KW~i9`h^ zUEyNJj6XEB+yGd^54;}V)-d(ROqbq-zIWP^wi?v9YYrx@J2~Ch6DAjN=^*-Y5FJ2& zp;ltx4(m)bta6toYTksj2LvND_rp+-6I@&)2{i~Y6CKyLJm_EWA6f>3w1B94K4L>R zRJ(TWUX)(>i-omcj74nrL_tTyp_zt(d&KYh#^!_gjyEw-`fxZT;t z6(*kMWjzagokIvwZok_C`gDxlRq|E2%XZC4mwh%znXghj0L0ci?K_~l`tM^F@}1C^ zi}mn&qh*XLPJI@=5#(}tP@ZO8m}n|03P)y?&uIm?7e|gSqAS$TDC~cXlff9iKnen_ z5;ce-&h`JiZwV7iQnGcx1=F^T@~3^3dgtAxBONa~S2dvzRT*s&>RE&jrM84I4+y;a z_C7VTaf?<8@d??|w<%Jy4z5tor_B3bH0UdV+l84UDH|U2aq*;fcHT!!Bb;5e5EK@W zQf|D`X-T)YEtPU`x8SGkaV3Dlovh(!8|J5BgN&QLrd<{kl&(gE1R`VgV#ysjm@6Uv9akpQo3qB^L^eeYbO@ z5S_8#Z5hXALBVp_qY-(IBvucAL++^}7Qw)OsK{Mbab$@=HJ z<`|{IxA1iJ>5gdaiwiJ)AP(HJ|MSAa=c6s=a3$z}lRkLs(#6*3qH#M1jI`?@N30Ee%adQ4grJ+!W+M8o^5kJOe&)sMVuEx{bA*jKq zfF{hLx%s{Ci|663wSvj#iAy^)-``PFVcSt#NAn+U*`ayyFt`c~3V8@mNnn_`>k^?# z6rl{(MYvs{(YE`f$Hle%y$~e)i&c;rh4*jwbM7jqlWVxb(E&xRS zsQs^QnkrK8j^A5&S5zd$1s_Qfz$00zO?6K%>!4CFcoXc(u~~LR ztl0r6mw_HM9&)qwJVs1?CHU_J9<#AV$$N3%NFy{!a=rDE;mzwT*5jOQ$2Hd3zux1` zYyXye1GAI-b%sv4?HX@)1atM4Ogv27QYivIW9z*g?tOi14%9M@t0!_ z2tSo(l^lYVtnrV7JwfiPKCZ6ANC9?P4ZL}-Ej+a9lxmr!qcuyAn`7;XRER#4Hg*48)Z^D@?thCH{I3F#Y5B4idG~VN z{5_3-gs$`AEm<)9V8m;rN*B!Y+C6$7jlJ2d0xJemZah#6Y0+Op>bYi@^iOY{(ed`N z=MBi-8$`Ov(i1%3pOAjc7B5-{d(rmeRZK7>&q*j4EL7l^YSu$5C<^p*KZ+JyV@n!! zpT|TDMuaQ2_8HzRGBv?n$kH;s3?vM%rmK$L;uL1th|6G+>nwzQH2%pO2uL!PoHWQE zAS%B<=Z7tk5I&H_qLj1*kWLm*aN_Kc4Z8U9RJK(Z*uTiB2QI20>h_i$3&8G}lPkUE za-@i)%k@BSqCkl#sui}mL9>mHIGG^)UTN$*)_$PQ^8UIv$y@4-%CbrDW79Z+@*AQ4 z;44JM>M|cXJcoKi370}IksXD6gpc&(Iclx7$4!*^ca^O0OCm{mYG}^94>m#CB+Mb|uh1n>9|2*9 zN+_;Pvv^MvHL(5Ofu=WB!E|A0m46^^3wHk)sawww_G{^DSr*TqMnibSnrK|cu_nuf z+HrwVTtIBS7hgMEl+*wxeL5~qwqG{?-K|de$CnloT6y%frC_5%Yg?z2&fQzuM~C=c z3gDz69dmSU(a)QxGxu~f+zu^U>Lghad_ubVGo5S2!DMXei-J^%#Ed`Dk6zVKYo@2w z&bZbeHP1Cg$>bJr9z;#l_aoi*%60yF5%; z1D5UIC$y`hWXRlp<1P&ol`%{B<&)u>JBpLT!`d36N6v%bpa=JNcO>61mP|uX|1+N# z)%mwP512mR=ccmZT!+y^aeXj_K8X5Hvkp7MlzslJev z5H1Zs94GY0NqephS0H2gJEf%W;8rdgR6#!`P5%B2x;q~l5OCoc6tG+NXzo1AL(Q+-6cLAKE{djt3w2Tz+93`wL0IF; zo&w`vOWb6P`t$W&Oi>&ivRK+G66RL_05>t&l3V`oKu6m%@_q!DuCE*B_xVR&awjJx zZ%Wu`L=E<6y}U{4VruHEaGEZ%vgYKO==TVFT*4JP3b57-k&O0zuL(g-GvQtIFs%Fq z$_yELo`1+qxw=1VN8Q??3xhA`et!;I3L@#=ejfI8_<+e?f;bz8yXyhWZFl{9WlpA8&`H=EpO*rPQ0*%f{Qm$Pm z%?~)n(FCL=Hqrje0Yf7E5{SNasFf+2h#f;+_$ z%&=K5kEXTXHh4MMO6fD_{*$MIE~;CdpUHhm#SkM#)|q#v&Hf*+a6SUQ|p}^&lbX#)VFK zXd4IZ3!K&^lF)%=RNu&wH7|nNh;YT9*PyCFxU?N4s`zu(EwBqeSq8iPRwHlXXsL-o zsMh|OE>c1BYtwX0frqJHm%AOmt~s)f?_XLPx%`1yTf1rbvbn7-qdgDHI-w_K{Oh3E z82TZ#NU4)0t;L|PDb0pQORsC)Ds< z6;5RVwvfHoy9ljLa(V-pJ5wtdTs5PD_EIeGitOR6pyu$M{-7ts2Yr-$_B7+B+3=V1WY$0}Duska#d-P-*;84;ty*E(GUddFt_v_~S zl;OKGRGtNMZx7yquUKh61QQu+@;otnSK@0`*W%|$l~_4fcn-hWFV3R2u~vYWxz`J7GPZv5^c zZQ&!Iy`PeJJcFo_`4JAY1N5FW}L$}sZ(&J;%J=FpH!YQlp)5U3tj(~9*s@|SgR10Vig zZ#iWSo zZZA21f~UpFknOT%{#yNctlrrYwi+J3u`m5;q4xKA}ttw53ZGAbAbCof>A);~=y z$(A5(PygvokFbM-%{s*pT9dV`e$-}*`A%;XtZ4H>#I~@dMWNg6<}TUc?nK2ZQ8_S; zjSSg&gdhdxCs6Br!B3r+pZ}Xi_I|d6CzRx5)B{{6d=5a9!L>?;V+1FOSb8_1@2rJT zfI{+U9`*fqzhqdccw6%fEjXf4)JD7Ep4-+1O;p(g25Z(eD+!zkKJoyot?{AYT8tjl z?zFAG*$Qc`L}PF}r8RW(A5TK#)$nd0DG6*S0@qR?*hsy4i3%vbWAv+6;~(3ve6im# zV-8in=#XD3a(aQj(y|9R)x-cR1|4X^utMV zJzL`eX#a1RwRSWt>0v6ySLcOV+;$(gL!$XRYo{=_Trg70e>QS;&-oYEj#m*>p&8>D zX?eKEgj8u@AUiC5o< zU#Y{~LR%OepcNTeUs>}~@6aa8O%043 z%WbS^F#;hLYV2m}o+l7mT1Jv9({Lqmdr&8wfQnwYKyQ| zRClerGY3^nOYk$45VC&O4=^lEc4UDeil9|h#5624695!xU|En?EuI!rafq2J(eW1^> z4U@(!@3JhHLWO<-ShdGaE5q?NV9#NOT>RpMXwn1%-(P+4cV{u+=KTDOKA7iG=D%a}E68J0q4De!D%AziYJhBZyUPitf?@3LCaHw+}p47QJ zOu4O+JXu>2GY6l0_h6+-fXehZV%Q}-sCUqKFu_SMs6*dZjd(t6BP{AWDGi>95t@xPrAdeaY~2S>iQ=vRH4l z26}gm3GjIl^3_Ixa>z&KlTD2bmt*;)fuXD+{m(4ATS4dCgVGA!sb)j|ZZw@poL;lL zVB#6QxO86$HWL&dU|nyrMfZaGBqd^0yvMQCR~Ex`HmZMCs}`ntd-mOUrm7;hx+F`~ ze86w`A#?u)NPN!LHCq=;C5!R5c59`^onG-*mn-B$Ynl;Q@PVAG;GROj$E=Q~N!%-p zdLUl;Ofxcx5#6NQ*vIfNR^;)7#MP7BhjoksFxBJit^yeq+X>dQh<*=M;5z@N z9Q&|8nrdQlWcBSSX*G!Y+{HM4;9+WtEFu-ZVx{Ea4elG}#D6};Bc1te&vyo>JV@y@ zh500W*xiMG=r!cXI;SjZ%KbmNxF@ZNSwtI;wV4HhmYTla;ayhpA%0aDJ_XpIl!BYJ^>5^2h zO~weBJPCtoBc%8=A8*dq2U)#R%`f%$;g08edNN4g^pnkcnn5I~$80l5Qk65|Bn!M6 zn?3s$a&zhObTjCT?lJuha|r7WTOdg~ED~0(8LA%iUwPEL(5TB)AYMA*7bILs2vbabrxqjA=9@9o-NfKA~kA zu`l+4ULYL2z)qdB(6h(fTL2R!AeV9aVr6g)sz0zqbtEt8UkCj<+I@6f}>_<(wHh0WJzgO2s6&iu z+F1YO_bxEcM@Y*kBtd>@yyyLbF_?HSrb&zyv}q^_7DP%>XZ%KolheN-Tw1X*VGko| z_sx*uSmX$3>SiyH{|?2sb=P0yjo$aw*{D@uF!-7y)f6eA1{}GLGWPbJ9)Wq3V+bLC zftb3*+C0#Cy>87#U&AEV^|=;uAd1EBNtiW!TtY9J0Dig{c{E_~M0eH0BS}4OzPm?h z9}mJja`X&E$cBNP&)?MbVZoP~L)0n6WnHl#9;{x=*w6~#>tzE}$DOjmv3H^Z9ICAJ zFu%{!n5&xU+Qa?}LE)ZKhHN;s0lKdy5 zL%=ediQm&y|2($;Hn{Hj=*1nFGn3{aI>_J7+7?Nv)6V7zurnErX4N$>zC4pMb^7nF zUwfjgpJ^tAg2HNTo!VaZo0pA@ZeBYQPf+;Y#~)`LKTz11P}qdAzOKEYiyvVLt(y}; z5WkaLG3$DX6Cm%E^J}xm3}OMF!jyx5QD#17wF;fsjtnIUAfN0{c1eNf=oQOE z1r7-RRKs2i3gHuQsi8QXN2dGlnyrV#N6d2v+hxM3QF9sl_nZf3B43DDhSV3`-%H(c zUwC{Js_;VO1v?vDfG>TYzw?U0uP(i0xzR0kvA1t;jh5rj^kL4~uZ0PCXBr_bzQi@;>-N(WIwW{us=%#IpbZ2F#M7Vf{yG zW&CL3rfqsp8?>40*h9?SDY8*tEksdqw)*T+Lx){6sHM8eY&1Igg6STjH<-G`vM4#} zH5=QAHpyP^yNoNj$mWGan?BD^HlVtLii2Q}In@UtrDeMwW*4lsdrPAS)GQZ9eiqpZ z^rE@^GFZ7*rmw5-)hwc98Oosk?T$f<%ZOZgWA(Fsuxn>Vi9l@&M@);GlxRl);c~Wh zzN}{HAV;U@cli|?V{us_QTFvaukd$6CnlvBCsS<$4)+`wFn6&G8WxNWGAq#JaQRiU z44YS2FVgToq5~NZR#%vi+oTVN1+%~?=8-&}6r{A0&NV9=mG$n(;$XF3asim+cnfsY z@c6v8|I13Oausk-OL4Vwm_K<*_ieqF7fE!#g&a>eVNoVa9GbqxDk@SO5u$MaUV46VP{J`?U=-`a}YUoj`=aLnqVfOpD zm0xNy9#Chcl~MaEAAX3(JmR|;WxPryCPnk4&>7@|_@;}{qscN70q(y+Eh-N__Fk_W zxNu2)ZdU!6fr`h#)W?9$dc+R~>J4@ctLfydtw{REmK|bF1iIX~i(>4Th`-PQqRLY~ zO0zB-3L~>vCDLdM;jdXN`bjSPe{mPKZO_k0-g&RqbfrHjgVbj3UTT<^(e$MnEox;b zG@Gmk9fe6843|Jv(Ef$|OrA3XrCRh>mHnL~7UmCdA17@jT;?to3xBKJw2?d>>{+#)zjx@_09^bgWj1jMc$(rN)^f0>;Q@aE(pmkqzx@`PQRrqAng zvefJbAOU7HWuZ7#j^CV`j>$Egk7YpCTetI5>TD0$jWk+ZrPDwouV_D*W-En=?~L(R4V0tKEJCQ zgm;X_gA!5N2DjxAA;|DnkZI8XC@O(5ER^T}4?hHw@O9GQ5Qv@wVL9rJ(lWv8>m%Rn zU(>&nQPc20KhI3dw)qu{eiXNngcDJNK$$z4K9?QW5Bea-F@AN@o|yw)dUxXcDp@a_ zh+jJNE_^Q;_!4imG8;bqWsTlCjb^JB!sMJkq#S$oBR_kbHIZZMHr0t4pHOYNv9;); z(y7755s_4Pqy3$zq1RT2(kOpn?m_z3v~c!?`9}s+5bc&uh=`Evxw5=votvAhx(If= z@d3I%6(-BtZ62km)|K_7KiD2D?yyB+!5z8tf=Sak42YPKF4h3q0T*h`Z6HKCtbk5- zPdfM%+&osiHSd2Gn(J8Z%Oiwx$TYYRu`vk7lQO_|>@V)m*FF(0i#q)9XQLtq`ggS6 zWCHH`$T&Gf10#%0g$aJ~$0NzNo@U%`7pphV37(j@={`LyX68If{EW%q4t>O~`OJsQ zb&iTNn7`R?9A-ie<}WyAn2VR|=WRz*nNj=&?&mVmB=)H1!OL4)6`ocl(L%{S^7G9K zqgBZd1TBe7Lrh67HP{e$eg3nblyC*xOIlw}_5-s6b~&rDRkj;PZD&%P8R=4tl9jK# z!#(kak?cf?TvBX&&rlh0Ye)Q6&2@&6BwpwoC-rIdmKhb`iFi zS;rw?mwzZj|8&K(Uv3RhZ4X%T%m856dTjcb-GnbvTX&Hh()-F{XusE;YqetsWb^V@ zf*-Qv_}CVY_P}iCXR0MPQU$-S*aE3@javw_dsW_Pmk3W)DPkxQ`q;zD7xnZgso&)z z4&{PZ!Fjr%#f@B1cmwVyE3g{z_tRU#vVrDc-@E@c48h3s<+gEgwoyAz(>AUArbBG4 zmG+T*=~j6KdLX|#yZXPohmGcxUj6rDRy9s9p0!|x2BW=P^PKnbbXI0L&@(?01QrvC zj-?n*Vo=+}O6{P5K(0%(fu7c8>iO7Wwu=kFs>7hT%HZ3H>^VVyHW94K{Py3am!eNE zfTa8x4c+I3W92lA!00Tv1YaH(bpk^>wuM&i1jb)r0pjX%fvW0{m^DeTFyZZ~%>MJQ z-im9a3`UK^vyG1mKF*&}U8d&h5AmdGzfi`@b81koB3@Vp7O?m~`i?m231P)Yuj)p& zwQ26Fs*WR(zWC;7-ZJfM?(4yd>IFRsdc6i`1R{`{s=^JoR9E+MjwFM!3cengoCdhP zwRWR!e2hVoT#{i>umhXJU;O^{n>$D3mTev@EZ1Yzt?Vs3;f9gcw7{2@Hf8S+@O$2h zBZAn~;E?@?XD8V^8zBWvg{xu{Hon@seacrq6KhZqBhyqw2qf6*^=*5v_vU!o0_(Fd zFdKzEN0yr1g&b567kMhsyqsJk+(oiRivz9J;?Ia7*D-q&N$PzkAvagNvBv3z1Lr6& zZ~~s{F`*Pgu2VyrKn3;tdUQdrvjeWcIInMKOg%g!NiwlQtel*jYux&PJ4bz=g4(DS zDD(C_=-r!u%`$}9D^d!4)6^NZmB0G(Sc)*~*)jS_^6G_D*3+qpsI!Jyv%yzMxl!HZ zsmzj@eH#`)5-~Ke(FKq|Y|^K{oM8aLSz0i>!nllTI)6V)K`8r2@KB)*Pwzc{tbaiP z?*!>3J-PP&xyEK2vX)$<$eU~Nt5vbDy%fyO{slz#ag3(f(_8c*Kd)m}>Yf7sucpT? z1XJ{<9VPf_2$}r(VN+i2?YggcHfwa!I?>e-8+r%42)g<%k~W&?$6@?lOiA{HIG8h^%<#IJF>?bA)7mho(VWoNOuqb^k&P(c$3S$qAvZ z5hlbJ81x;H-tRhz8uE=Ih%2Ry?1o7|bk<=~Gt-c*De!M0?z@2{FCE4$QQqHb3$<*` zqN)v-VUI+^MHM9JVcP3Hfg@_&W1ceMesr?2mGbr$)5&`{DuuwD%p-Q zr2*004B<39&AM(Y2WMHO{d-`}H<^#@Vq~|w9K4pkL;x_{}8JT{UW! zZwmTyfaad=j%C-|TLVNq=%mDHrf#&Om%1W(Z(-@MSoDw>AniiFN)@}9qtJdgB3~3l zC-q>3y#(S2!s663eVlR@ggFL(nF_mVz6)oug~%>^hrAG@8d1TscjHOpw~zz+M7{>* z5UWdEkQV^9!-FSJ5Ptpl;sfUj#LW~(0gY6gFJbvLlsel5W4!p2lPDD#%*`(=$Z-x&(Zx?YB|MN1s8=-#b*DrtXimE2;sD+2UZaILm zn{!JGfVHt_!0PQ+7dfGj0XV)Sa+?yuybq$8pmO#XKzGQJ8@4&arcxZuzcRPI3U*=E zXM%_>589DhT?5?G_xw(v(e?6ZFUM~fyvXxmEpY`aX}bkg(S#BZSeI56O(F!oU)L@^>P zuCHqp;`{A+W22y!S7iVrIj(&NhhN=ut`U4M;7neOA02TWuVH;}>(lmUFGQ2ja3N}J zuK`Swh^n11iuEVTI!AmzCGrn<${!Jpamgz9W%ay9eIX~KU0u(LzkM;_>C>?HbzWY0 z_yTC_1(s`hR;HoIv%Fzezu!WwSq3)#E#&!UaeD^Z!VQXQr&RtncX zMCabv2oo*R0E>kSMo|cPq^J6L0i)BVVatzCq4G-m&({}>4UIofI3aW_bV_;H-8=PE zywN-(_-fWU?(k?IoS4acjMsRbE&oGbrmD*!VC>l1V8VL)fX`h9ljqOpnXoZrU&MtD zdG_ZQ*(;vHS&`r7)GiSdy#5DQI$ZDhYNET`kNu7nRk3~gQAr=(TV z-$MbD2c@T7KsDs!lNkVT$O#e7dWM`QpI7${@hDq4wqDVhS(dmb5z>g6sBb9yPi`j1 zTqmhPAFS>P>*4O3)!4~JnC#2kMP-?|^gok9YDbu%YZ??&5u~X&?JFz+! z-KfCr`PJ%j)byvo^;;>zy+JoyW4>>TZj(qtq!7Xem78%`=*0u+dSZuk-Jo9ms5*UR z3+Dt2c8+3Vmo{H9+<|}TxGRypTRi%NSQ1^b0aWY$RSELSt##Cz+v6K5Y=+RD1M84K zh3*89g!oEc*Ne8yga1)Lz_IR+I9acDg&Uju|AD8D{S5@`nG2u_3|T)A)+|&kGgs>g ztKk5p;Z6QsVsYWu-(}+Fvt@0Umu~yynTi}mLn6=( z5px5x8*czhT+Ru-(O7aPlvO^syqLyo1?_U6r$t>p5_w-=n2jsa|h z{)Ls*Uu#^ovKyMCU1rMIL5v`)`iWcEI#o%}4j}@3@Vl;S^wNd!y9;+*{UhJEk}dVl z=GGMY_ipw%`EBjYJKpB~ELc0s84~sh@pm;P|CZmeD-g={D-Z!|lJl(uhb_Cg zYZcwa=(H~mInu(xK1B1Pl94F@SN&lLYjJ=Cqi@S6YxZ*5{6{6>h4>-sbjaHaNgenWX zS^9MmD3svW)g6qd3IwJ$y^(8i9xNWD&bJi8|1JjEPPk3`+35rei%~wp`rnnAiuST% z$u4asDU#U++rBx|MEcdNFMfqd@;Wt0hw(8gTC#i@HK30Yjm|H_ky$m((8O{F2h|!96}A>L@CJ!vJMD~T`4%fU$*C!lAHVKXnnwmyN{$ig65O&X-K(zYVgVDxQ!dr=Fl|$ zRnoV!M3FFGbW z>H|)@^_yWRMGsHG_!&|j79O>5QBLl@2?`%h%rX=^05E9@+31r~KqZ8~E<+p-OOYS3b`3F|F< zoRmo%nb591uM4h1UNyE1eG!1J(d3#N?FKsp$ct*I+mrW19@N8`z(9^`JPBt49GU^B zE`|@=>AgS6JxO?%hxWJ$K&^Kz-%+uX8#HPpuU2H3B=qQ0Qi!gZQr%%9^5|6!{pniJ z&S)kD+mc{)kC_8Bos+FNqf;vIjDmSB7fBCZ(gWIlivKG`oFMj(1$*O(-B>s-w>zE zWh~dk56ic>5)`#5VMW)~Ooi=Mv(74it;T;p_(RZQC|uM4TKg@92E{{Ual01mr3)+i zc8c%2Pxu>|IsHrg8Miv+YT(Y8>tIc$dWiR?dXRHKy=x(O<3m9}#A0S}7I@d>K+I%A zL6ChPcrfxZys(-Q@TRRH8}a~Qx6Mp9(DUJRk<0OU#HwMw^g?B4IBAyYGQ=Dx1p&t8|Zalcuui-kS4iWOEJZ{i^|%14)m<6ljk)?hCAg*}K5 zTqRgRl2T>jl954zS~8@7tnoVlm4OX1{^HcN;*7864|wF45U|-kP#nMD%CWmJ76j9Nt%M7OIeQZBVmXng5B|U zqVg``c>ks;@u7rNb$)@YXj((cLw+Qxm7vmcEaT9&O6S`d9=dp=bML+K@B2XS)aDD~ zNy1XMtbUge*fUp(S9soF)*6ohqRZjj#KFSKs!UXtRv9nJz-7=s2rIp7K2}lt zk&d?>zlaIGcqsC{Vc9CING#DZ)oN2O;%W(H*%)IJ^8-Wj0S6fhuEe8AYq_AWw(r#<^*NJ_|@-TDog-yo8qEZ)G6d3M&#{C_wgn(%z_(BmcGRijDEHe2VG>I7d@AoDXxgSw+$ywa7EzE?m8&LJR$vHh-r~;l2KEA$9U|T`Xea8;0v9aiPW|}#JKeTv z!OI%hEQP^wJ~WqJbyjHd@JW!e43-LoE*qg=9w7Fs)`8ZB;!};QY#-&H)%1!F4XJ5_ zbaN&TLXNm_c^W>OisJaIg~+R0q|!MOR+pvS*R8$hifqYA_uO?0hAL$7P>x$>NMuwQ zZ1gO+8r!eyug(2YZ{){I2LAFeu;g-oOW?9om%by7blGZkJ~}MU%2KS`HdK(cqQ!xu z7m~xjEw^2XDMA$j1sN%#AT1Y3vwi5zT$}-yj=;D_L47$p8z%$|5@-MThd8k)0lfox!mEU{u`61 z+v7;a%KdUL%#PH_hdD+Y<+0Im3?O7%YQ=7EuVdeqO-+O3eCLPzzUG?ynrmLayk_QJ9#0Ay9}D}2JF|+! zJ5VKw>_)vMgQJe0gUx2ZE7gU2(oo-C=xGpPLEm2vdG_ihUkUF1@ZDTJmGLd(*$ zcoA;%4-&O=;x+O68n@*XHr7pvGd(iF5gMLRPY&PnIYwIUUP;y+3nY=$IaeMh zJJ!ALQYtt3p^MjM_+!m!M6Om*SOUcOUXZBJ?!KL1Yoro%+{dC7yyzLT9GBzJvnKh) zahC<5S}jPgMlXYGDrvDKra*aLqKPE_)-`B~K%Uk$So4_6MNz4hu}-GiAG&LxH40jh zAs6&kqgm3g*_;`)Zf@quids>5(c<}Ho9RoI2!lVsi z?4C;VEY3IQ!%6uPuv-2d$2nmo_V|4-T5?Ow+&s2a-BNoA(Wqd(k=bM#(7L{8 z=mbAeVA%yMRRkqczUhIjF79zP-xlpGC8st=BZv!)zCY$ev}PpedE zns!X96fk$xX?q0T=eW4YjXB8RUePNv-*97v>9J0AOPyq=?lM<+5Y9-9x6+GM_QAbMPc!tNri z=1$7IT0FfPtBDM4_N&=R*2mhO?Ox`C_AxcXLH~=VsgS)nZ@w4hy8ch<8aD% z3OhGZ-m7YKc(b5)bGOZ4PL5e+5`l;bCeGb(xlzK3s6@Dob9DmaUp`oE>6{9W$4(qh z27{DX`HfP%t=ym5VCt)qPcvEf#oZbUq0JUkCH|vbs7iS4YC@#_y(*_N3G^ksLE_Kq z!l(I}w+njaHMFCyjhj&s`$?g@3OhBgR;-O2bf17C9^qMVoG^C@S}#*OL~%_1GI5h7 zf5dAtc53a}8sERexg9C5ygO_C~*SQ9W^a;+m3>PP9I#(&vk{KYdld_P3s1SWb*Iy%=~1)Yp^YlkL9I^p#KV$Kk3>m+ z2nv)E8@FS#DMAc#!wLGY(-jWp3gFzmyUoV21!!c|7l(Y+9nvwKKPOpYUX30odz%RPhA=&nGjR1k*LLjT{6sK|Or7!z2&SCT4C;o1g4L5^E^)H)IhV zg!-&V7XdYvX2aAC-y(A}j=cWN6^sHIqVK9muXSRy4*;)wchw0YueO`!I{mdm9FHv&amze69Y;?nPz4Nlk3f70{5aCB-0@NNYXTs1X!DqSP85Z*ffE8ZP@UH4w6CJX%++2yBm z^*wE=m(2N#XMApgd~bZgk4R^iqjR8;_=vm<>5sJkq-Ni5TkkCxG#eE3t`GKjt$twy zveo{Jd)DQqC;XtW{obpSanrX~{D<6Q=1>;MJsf-E;0ax%^ws@4!-r-Z3peI!87g%? z-9wYP8|K`1&F$wDmTdDS33`~i6x9kcnJFOZl@~pvu^CqjqgI<*Li1Hn#gd*MZp+>x(t^qA)bXQVIxc#FJf|1$VUS*57 zh2KO&tVj8OA$2R(A$?zD7ID^?W*EsQIzE^rd`B)+c zRE71hfm1Y3VcoEHy#A`LS~X3gZ2h`N26`oTh>m3rMll$p-FJ@NSZ<1=RNnY-Qj2l& z8NM&LPAiFrmK7#@?kr$&8wupaeqlmrh_iqNN?6J_8_4Tky8v{ypm!0{JIliqIRqEK z-#Ue};_1ds{EXgb3AZ3Lf4~`QPnH3h54x7wiHOEg2XZ1 zjk!FP{%t$*Ac60-1HC{RC7%}5NxATkt8`R?In1JJCMpCIoDN4^1Kifpuo}8{e%B)c zT-b^$vu-9u9a7+(RnNxu2hbr~{ye$Q+ir#{zUFkC$ALYzmZnM9BRi=xunM@L{yuAg zhK_aHqE02~$S-fj9NuNN6kRlOi(Rk`;(lxjEf$r4@%=qZ+(0@qGPWu%`5XPS2x+#~ zJL6pcgX|JB<_h<&qDXSZ`Niq6cb5&`DAH#4ddMxJ>_3c&9aZd(bJEn2>Fag<9Aghg z-oJ)&Gj)RH*C{XMZ<<2n4AJ93j1N8FIw-hwF zpmE{!lav>g*x*#8E#(+o`BHya1RP*Z0-#a0q)OS(2*bYXC_haDT1?hGaJ>99r#Muk zDfj;VfIR$ryfu_yl$KMk>ZIGHG{v&lVttNBQCTB`A@JzG{En< zY5pS`81U)8j(6~S>^q@NJ7zpXKvcrwJqI0jTo3N?0`7ZjhG-qVI3Wgs9Y_hH@e9E* z9aW18vczER6DHChI6AqMb&kKi-F#d|wMW}>GS@vd^+0~+VUMf{#=hJ#wpa`3;EGHH zPMsRg9CV-=c;@dNPz&i8M$f+b+C`eW108K30KtpJ<5@~twYt{vs z3h#|_n+qOr0x+=$66-k;jkN}Stc`PlydO>(CBYx6H`yb45`Hv>(FNg6kb~ zeM|aUd{~M@#)LA2rR?r2Xz@Ub(v!2@eRR4DHJsdVFl*g zzoFo34hsR+Mf%?+HF{Etf5a$8`{?SrO5bg>Vac{p+&m|j@Z;hL9Z^QJs5pw6! z9dRnB@x6%g%-3tfRfF^{gx7ur?c0%k&xKK;!4DHWp5$xkP?kb`jQAekncJQhJ)uQx zmayc;$rUeF@XZH@6pG%HI>*gu;DPpxw7p%vVnT@#p}pN`)k!3MWvjk#P{*)eMV>pXt%6f|T*d>nma8eTKi>r}3c zSWO;^_vgiscP5n$L46keknpRPdyZ($T1p5d1jM_;y04uYa|tt)zNCGlL58&&1jHn(Gl#%ExyW50Lc*`t1xE; zn;ZpLPH&I3E=5_&i+XDny6dG;&&9r>XF|$au`qQyGz#p~t2J&o`R(i~pnJ&h8ayyP zMVPbI{a`BAIxmiY3c429^o;n%&GQA-k>RfHR_duO5WLcbb=%xcad&fbb@M7>TgNS{ zHkML?KnTquNnOv;5$DahF|@%~Qw`eVuRUQRZZdLl(d8Vk#eOPjY~;q(RA0L_0jXW1 zneVQ-AJ!=6V9f=utjIz6CA$LLZ6;{Z-P=;rew)X-(73Nj{-ihPa_l+K*OtPifL!H9 z_u#?q43FV_)auZ*>h6psKqR0$8nOOkeJ^nY9X{DDFbm@8=n)RZ!RSf&MGA5~xD-)W zlt9)dRT+s6S^}P!nr(v9yL+&w`C1&8;G{0N_+e`RzfBXlk&zwJ$a)7b(9b+l@u}1=Yi$ zI8`=AZ!AMzB^TU2iH8qMR>7_st36s@O5DHbl8JljYhWKjqnQ5qe3K$Rh$m3}Tnp7` zKug0a9lRf@nNhKkKH%IuEJbt;C){56;z$qTZKW{M(NZ+$-%}98^a}Q5I_lZ#wLc+f z`9*=%Ft>?gvlr?t(AgbNn&xCiNuB@<4Xr*?_V*;qt4%CUzLgPxPEfhzUp@1b0#rW@ zAmvxr`=*um{Gc|XNV!fYVj5vN+b4FSF+&^T>oFScHAysMI=$>08#rSy!hH`0tI~BO zL&L~f>Oddgzx_}Bot|z(!{kfUS`dg@=(yRcNsHGYoup~AbGPJs=@~=r>Q62k`gh*~ zmS4VyM1y;{p8@Vk!<%ctAvo*My_L=K%7ijQ(D}NUcSqLm1bx`$jxnR(GYx%r?G6WtZ@ zuRPMgNG&(_0w_P*(+2^+E}-{*0YrWqGlHWlx!h`S$zD^E z$}bZ@W_ty-%izVjeeFX*?<#cjdWL@wtL-w#WMx8?VMR{Du=+YK9?~fY20l}eP&#M> zuo>e1Zsn&DIsQEb?g=SS*=}ew|uI1KvFJPCPpiRBafybGb%qRe80bulyh( z!tYD{u`z?y%G2!b9{!NY3nQXfH1dywh3SQaJ&&GjryxBoHpm>{aH$uvxF9T!+J_li zqosN*^fR+)!w|Nw!}o%tD1ffbNCGi->5jp#Uj+75@TZOI^LC1LkI$Ncd{y@ua5Fhs zg`2NO=jN|YvS78YchRWiESd8&dXz+23NKMsA@XRg8WvB`(GQGH-W@q>A$fy}Z`W2Q zwZXwrj+(R&8`H_9I`U75qxq_e@KNr+W%D#(fCNWek*0OOAt5!k#CO=^2$o*St5{;Q z0bP;1O&2v^U3?8=^&%smgR_~LKat^d{5OJ|``8txxy@J6v8=EnKv5`iN@@DXOIeRJ?>mQl+s9$*-LvPYla zM>o~(P-+*RO-=;!H0Xu9dF2vqC*Ph%utL^y^3@1N6mc8!S&wKGWZy`Nrd)#=G=4a0 z(;%+uw50f1xmhvEXOmZ9Rzq1%+z>}UJwxSEa;41tpkX#uH-H?1ONIXlDXhVabPa1t z??BGxYYtw}!Ge$4dmt-j+71_uepOROF_Hv5KQOmdNaAbjXPlZwBzJncrVKK?b=NTG zcAT51xF2&+0_M)9Yqs~hTsZ%;@yAT(b?IV~4<5vxLyJ&``2&H|&S?849ecl?t?Dx=D^QsGg}E zS_T67s)3>H!gc?Wmcq>rq;};*dC79LRdxJ-z91#o2agc3A(8)mIOZ46A%1xFcnAUk z@NA?`1Kut?puU=Ih1Vbyono5@)S+=upN%<5> zf7;*MXR55cOWv0!$TR+Ex#f2Pr%PGq1;4;+F z6wk!j-zUQ4oMhc^YZMJeRyp8DzCr|3fdzV1Bv|$=RprPtOqAW6F-$_jaue-N!hP3q?rJ3rt+7skW z;3h~|>qwEj?+;KCxw8O|TCe?Y>FjdqVqn_f*gkrDxVuIQp?AyLt!i6UHCJCf=HHBe zZ-;AdXLX+kjE=*w=Dd^jwNCHw5%I8d&j3~iBO|M8N<%Pt~8tfOEnqtPk4!mACNe3$^ZHeR_Gk*l1AAj_L~ z4fxrgJPg`w=QjyU?wN+elEt?exHsdh!^$N2Zr~r!s|BvY5clqB74Zr4po$F(=4wyC zK9J2*L0T`kJ!nCU{fc;qhc@{OAYnI{Bli?=tJr|RWq1>aef(Hh{_ z@h`)4`Am$VVrw;V6Be8TIN--xIl>AVi+POyvM=c26tYe z>bsJ#)5CuDVARHdmc}ugvxEab|C>H}X~R});^T(yk8J($)i%baX7ns?t1avEx>xmj z?^{(df{9ZZP)^j|sj7&V)>ZZzS?)6JdzV1_IyoDWFXg=KwiRc#{XfZmivhINRFVGT zwUp^&7EqClr)pB za+gTfBqtrodcKm^4V(HmP9K$}1UCKzonX$Yyj0s9X{1c2H*sOzTkk*aX_BHQ@GZv!9DM_ZE zsTxg)Ycgm$$v%v!7FtsM)AxyXjkW;;Y_L20akr{3NG!3cj)H_*uY;hVH7ciq($LGtEKO}{**tYbXklmvYD$z zZ=>$|h}#2Y=;7_x6av;fmvxiz2k$qgn0Ec=_QepESOOr8(;e?jxY(-|6his3?zGvh zrvUH-d5)e;Od{}(tN|OlGhR@n2Nt)hf0DM6sPv!sS2Gd$jz96Qf8wqFq)WDwSjoAq z^b*5!4LZ=ODt{8hDkHu{K(tNqwzAs042` z*in^-?!Zaw`?9g_@dp;fCX?rP9h2jqRt0J<<1ouS7}dKEjDDnpe}UkU;v^>r+AWHzn@r z6yqG)2N4{;N_=UxxGgKC|8Bu$q8|Krl^s{{>=!8?sRNN)*nwm?O1}EfE~O^-6Jb;; z=oMQ)QFXne(wKMmc1`rDc0PI{_?_ACejENnXXg9Z)=c@gpKjv@;2zAo>`-&yEcgkg z|8LIkBRd5mxsjmJgJ=_={k5Mx=L^Qvn$dl=*KeDUvu6hOhl}#VH^b%8g5y)1X2`vA z{Of955v%G;If!vpQcjrIesJG9I-8KK9&fK^M>Tn-i_)EocukgE*r!SXcD_^0WMi@U znO4`bR*U5sjQ{Rcs)BEB&+DQ$PVa$p(CKr47wJI>WMxM7`oN%eoP z4adJ)6YgcaWu3epc~cZVb%69b^4#AP;+t_%>#=ov?TF=5xMv!mE;zOYMsp9v*y`ei zM_RbG^fLm{Cz(mB^pst-=9?l5UHq4Dcv39#beF=glFiU221fx zd-p;74qfnDq2FoRD0u(+*rH$6xzm?lAU)%O*fGl^ls&Z<>7Y;RSnH?~b=A?pRy{j#iuVI_Yqv}e6L8ip^s%vr0tH>DM?>*dNhqcX8?45 zc4_JcA&AN|^?D9{aJ!^M2wTT6$!L_7%wp#`g0eOU{VwW-f#ing#b}T|TyTX~GUF)= zbs)L2+y2w|lD>1V+*ijzR1tqo_oJFB0n74VzH}Yo)1Rp|z+Mh2p4QF5)yDSxRXkqk ze?0p4UxXBk^>nR#Lp*&rP{~$y4IM%!IIw3g>Tq1fn#@mHM+HfPa_xQ;xIvRuVvSn* zl;b_><`>FY?LkMXL{F!F9u#XZ`22v`byGERpsq{UTEV^;`=*;VyQdCy=nZ2}wCdyP@d$=@r8T55nz(Rm@StQ!KC22Yh-KxHI*>UIoA-!0m2O)+D{U z@Yv3@`r($r52RX3z04rjwTQ$FCQ0ukq^krx;GexNioTc_jDNW}@6CBo>Zb~v^(ZX* z^n5M=JuB0uhEbS{+mEo&RmHn!GY_6^D3SUN zDV#zyD2(8Of44_)x~V{ZHs!Cqt_flh3jOp<@trn7VY7{0dk^EGNZi~WbF&u?IV*;D z7d{~}Z@7#=G@&(lb7~5^1p9h+l1QvWY(8Z`3!4oI*D7s_rq1|m$`HJpJzLa&&yzXV zGN+`@HO^h@78(E$y2S?EM#Sv88EyU-V^D5NRz=JPezto06rf(lYER&6#3*)C5c}NO z5yxr|csceL(-ZW%1-*xNr{Xu&&O0l)!K0omnsQCEpds1Zg$kN%zYhPBvNv;_9OW<>H~RKAGO)&%dYE zbtpE5+az~9^ytY3lV3G{trCV-x(G>e5J6|n7yr**_nj7t?-MNa3uw{YC0L+F0ATW~ z8%t|d&rzyzf2p8OQXGv->1ys)?9ax(-n|aXPW|%)^(se&_uQo2DJSPo&cCT}_HXdJ ztvYi^lcVOUF(J&pr=9rg?X?V& zR*SD;^MX&$eewm{YY_xLF$G=UDvRK0Sy;B1oHY$*uO%~Y$g+#UOOe*(Jr+L-0AHGQ zs|4{0%dh-ppA4G59H91kzlyu&ry`G`GbU&Pa94{O*oVY(dmY_Kk;QCBSS zuKS^0vds^ZSdG&lqNkJ#rGAo|`NC~xodn~D@WkG7zz9mrd#}9vC)}&qC6hAqa@>* ze>N}yX#3xTHehdLTYC59#W!c;8~xO)^)wN3Rr%?kn#cnTJE+TFHxUsAJ>;5j4yHwG zsn48Q?Q~L^&5n_a*|2f?@WX}bHJYfo*431*K^I86g~gex7F_&rsj6>w#b<6sjv(yF zt#L<|$0)kCB2$38&*hiSP!-dPVd%d88v}mW2tcG%K(t?N2cBRLhVD`UHSa^rhLrLS zDy7gjt;!}HoA~k$ya%U!xQbqm#%!zzX^KQI}Pm@Aw1^x^o*j_PK7-E@Mx`2 z_%>}@7T(u-b;+kjWQ<#2HA(Z^9x;_3>73Pg5F!$^IV4!CgLdpXRK$JU>&x!i3-Fo9 zD8`Va+*23LS1Ahy!@IJ`4r-u6WO>J*YQ6F>V?w1ik=t_SPa@^76DJcc&ys32EM2QW zo5)d918?aTEpIQ!AR~{I3|)~NgKARlNR`8=iN5&J?!ftnPbtZqrYGDq!*`?yPV@OupKS)`r_r>^L*9J#iL&4 zmI3K6UnOr=1=g<{en>-KLMKzF6O--s1LiDLhx8?RZcPba93w0o+Nu5Kd^rF{1ZQnQ zL(ZI4$xM`Bm)%T7%iT=33m0+E3;&^t6gr2N9N(}-xvgu>DnVdv5wH}GbM@V8GaO{t zK5%4z<@zV1GVULC(-+MI(1B8p_682;05QH;`>F4D88+hWqdn3zpNn|88@W2LI_S7S8ku@c zS~$kh*nb7@nh7N~wWHA%g^e|9DNfS}9dhXlWl(o?FBu3@-SO&1G04|R#Vy$#*uOG- zg_!TylYYS>Dc7awxc~i25{`D`Xsb6y3)W>hIp^q^mbd zF^)Z`2RKXB9qNO7-f7YjjnIWoL-FK7+%8koH_thxxkH=XyBJf4)Rj8H6v0p%Mp7s_ zAJ^Vx9KycsucUBg$1m@f@V@+eJ}2^4du->c4VXcPQ8GctKz z@S>ED=T|NctDdeT2~Xh>_64kR3NpQQUP-Bl|67L9v}dL|SmZA7RtP8F#RrvB8;%_; zKh+?9oA-&9&K1>{^9;*lsKN|)o6RSak@QajeY0!o`ay&k1N-xKs`n z)r04Y=JM1((d|W1mv|%k=U-(r%Q}g8`QpWnaypVDtgtE9Bf}q_l!Q-LH5(?uljbHT z9A2XDVZb8)E5R_83@q&LlPPA!-lXRgqo1Gls!@%}TaMv~r{pi9=3Of)`!KTi+3B1= zSy`#+mSH=eKCZKw7?Y2=s0mJtjnO9BEK7E(Cr(V`G^IJc@J;K{qfDK26_N0sjd%R+ z7PcMKrbYz8M}=nM#t^bg%CI5vLrUi|7$*tUa=9CFt>4J^Xz94V z_}=Ls;NNlP{(&i9NZT>4q1gcqWwIw+Cc(%VWxLNa8WR%wF(^^9OHi zDc^qt+UejVn;!Wpm`^k^kLkBr+}BJe>kggN0MNOZt_>7eCLWVcb{?aT8` z%l$Gh9u*bz%MgCs`UOE3Y_*8oO_**l(lqrLy63;-??Ov=WR^1h!?vC0uCAne|5j$v z)R#6b?^y}FWD7=1kbK^LP|OL;h5`}k3FFz9Gb?Jw;UkZYgdZGQ@%-5AQ!s*r!L z+z#2<%6FLF9!;?nsrkE*a1}pgJ1otkcG6x2+>mW_#BOMOZ2ZdI$}&Um5~@pA?rA=6 z`(+}wh@E+7Xb58m4+jO}Ox-Zj*IhM{apS{-9+{kvtG}Y63lAOv;fp)G|3LIsMS|?c3%~*XdkH7EI{~ zw{e*NM+&1&iED_{0uBq$3zh3u@Tn6v8FD&7KrNZMv*sF-4;RX@2(yZ81b zo6*wHEyd}SLiYu#JtxCGjzxi0@<3{TQDW=rJ2<4dTF9%f2rW4FI2TN*3q->`)I;F6 zOmP`?h!A2j_Ij0aIJ)T}-!jXit^CGcO`};4*;rP9c;^6=dL>@RA`A|WClMGJ0<|zR z)Lgsi0a!o*KEwuFSiBqIDk3OH;UU#dB?QJ6XwX#mY_~dL&m{@`c6L=nKJP$XTi(J)Qg{xUR1bJ?!DMNvuyZ-DL}LoLJpFcGM( z5zg<0EVcB`-}|iS6TiSkUg|^Rn&j)8tgzpki+D>QaxU+MAnwdWD{pm6) z8I?L=FTj&v4^$#I$cWTd_BD02Uxus6g$X88L+40I>iqIK{d4fB>m-|P`utZ#epP~= zw*A$)@w=A8*L*0nv(&QaXM===Y3S_a4VuqoNW-6nLV4iu!(-=Z)&H<5V<6Bk&_5|< zkg7gLuFMMP;k-A@g~tB_Ei}{ak~oWDP4~i>+ZJVeL`ja#akH8z?7{cTvYxleg}|Uu zbia*14q&X?x)qb2>r%R5T;-fnzHv%e`{*`n_Ey(?&*I_~*E=X+kT}e}3(7ggL$RxL z(Fnj;RdsCWib|wVpS8{ik*9skOR%@oS`1iwLDv8S+ya`Oq$Kf~vuf-s2W&e{sKucl z7Zx@edE$(;2_v!1S5H~f^;B*D=vs1f-K}l<#&2=BNiL*pcj%eZW4357tGeSoFSxtS zUTM^7CP~F41C@;_R)(`C>PYXx3wO>1W;ysk+^!S|aTI~#V5G##4kMF$1l^6I#rawP zRBK+>7Wgu1_;YiyjX5P{=Rd4*@Bw?lX7?&uiIo2L=tMdTL@_$h1yfP0p-(lEU@FG1 z!gN5J8vi;W)1(8|w2;Y;HE)Cr0wUf>ZJJ0vOd5W(ZP%dIL6nZB9a+3&#h~`dP*l3T z9njJ(+HfEnWPE7SyYAX0P_RZdp$2+r^|;br*Ku|5rda__|4;+!{QT)#{(Ca)SNR54 z`vXqTUS5|ZqiegPRQrMi2(DhX2~|ufsyqR5IXxF~O=I@tVKuReWL&B=;r8aM9N@-6LE#KoANML4pK!R0 zzpH(CHr*4U*hkCq-BbnFAjE#KoIiK59;Z^cFX8Dct_(hLaIW2Ybk@=?u^rL4MWGk~ zkz=J1sy^vT=BPq<#lZsGWx$kM3d6h>hAF8h=4|} zE~aCcgO3Wm!c^C)BG196ZX!{JDP6w$)3mh2oY@Du}>qh(?9fp zmzzD*vsLTvJ?}YY(C#^B*oSc^Y}m`Ackv5sxouyelx9-C~xW@y2EV z%1E{n0rxZMoJ=tMN_!6V{*B#g>s9Pd9MCjzDA(+SJQ0-PxeDW)tae89UpIC^4YN0i zqC;=OSt@{>&eex*$(9%DAiF=~-s8bTaRw7~c-Q+QZ^~&55Z6`|`2EpCQvIU}%{tW; zi&>Hf_06z#!;o=Zhg#V{6_1YO+R)FW(DgJBv;y9vNAHnggiv3g)KT4EVXGv;Ew*bf z-Ferb&g}ux;5ltFQxOliKUBDO04SUmFEdI~ct5odjOn3alBuIGu058%-khG1^HyC4 zjtVeFt`A1H_P!s;wZxO+QC$)~ZTGO&91%52+1!vQ|+zL6cf$O3#sj+U0U0& zIXrNzy@%5?y|miflJr`CJ*qhWdTTlQuxm=h3t4vNHQ$IWTVno(JoQX$Kft?Vii06~ zo~`77a`$6-QVQ|Etx^>*Xo!?$_3SQ~o6C;9`RwCF;Bj12#zC9M1HxKme~ORCe^&>& z1ru79l5Lo;)S)|ndwN%H%Bz1r!G$|I;UMnTelQ@4PkH%?EiEL%gb*A6yMy$YK$X~n z?tpx@P}EQ1<^8>lur*;ru0uPt?QH{2zr5@JKzo0#N6!JQ`snq2TFCh0{|$jr+(djt zY48?FRZh(W0kB|Vb1Wd~7(l9)9PwXiyKeX$Ba4lcqV_rNs7vpVAcE3-id1{i~hfX7@Ft zHi4@Og2Q!Vxx^P8v=^E4HJe`)?l{@L^7I$e42w*Sl1c(nAv{SKU$gKYNj0W4)x1!E~R7L!Tjzr z@M9;_Lq8@W73`P%_)< zBDU34NnV8ANk`VX;O%APqkeui@1K0OZ-|NXhXTwor%!H1e2a0_PCwQn`H-h`f}5LRV;ZoE*rz_1$9lfDG!ob4Erx?0QQtO)siF2xL7 z&oASl{S}!MJ6m-e17_T7# zy|y?rIp+U%UT6kiWzPh0Y%iC=p6VZLcUGSLEqUd)5;iv~MP$q>v$=iExM26nHLEEl z_)zef#mFaRc%@m)EV!$i*S`=C9^FgQqJV9j0nj_@oR#|qvIJaq(DyMWe@dqMj4MTF zF~3-~TcQjElvQkAcF*e#$4wpn#?pVH~?!=0c z;ID>zZc$A4%UdN5J?Fr6GBNj?g9JZYvP>odl2UT{XgKDS3g^CqHK>pH6 zzkbDT{mZ1~WKm`_BA^pyR@4Rvs3p4NX6b;uaZg_BI%3mlHu_8*Ts0(`c+(RGd8AH6ltyU4{fI*P0{sNs z#_FauQ2b9VEL*H~`m;KBujNT)m{ix%A~{eezHc7qgWn$&hOZ6t!n8^f+_$M4M`i zoT^B~2fw!}06)~mcgL5XmtRHuyRC0)ef4y5zs&-Z!5 z`Qh&C^hWxSD2Z=fyyiPaPFAJ^m2-&jS zyAyQteYf|#1f4GT#sn>BPy0VI$qE#k*8vv*Ok>t7y9=9=kAd<(kVNYaG?n-SswqDV zg8u`7VR~T6TP+&yB|aeTc$a_)UN`ZEB?THfjNiH|)t`QL!D@%RMn_Q{(X(Y~ z4!6YCy7FJ+;P0nXdM0qXyWe(nD%N5T@<2*GBzoBfxFM7fBwh{A`7pi^<=yAVk!mssX}%`AbpNH!3JPZvP%)eAaYz7!=a@ZixZgBt?<1TAj@)j5s{@>I$kuw6^BUaq@JYhqDft1fAhHtR3v%|&Upf>hyukA+KPy01 zR!46B+fG?@vVtz%>se@?=A~WEv!)zk{Po4&{?uLG`v;Fw zBY88gdHIQ*j9K)WBs}W*ZWQ?H`Igy@TO4t$rOTZz1HX@!8}{po(v{*bD@R(=g*E9a z-5qa+l6!9T8mjh8wA_jZuQ{luV}%S+xW^_&DvJ9IA(&JG%@ooPrs~-AQt{4N z*A(UcJc+BvsT~J3%k6G&lgsS40>ec%_H)dPt42@3CvkeGcWZk-O~^U${8x__C~T0C zzXBfeuAa+2v^;pj?u8I#-m%^t(5uOQUMl3-y9$~i8J>AhL%?WPJq52fyB~!gE*BJ) zzv}jFE-CfoQy-Q(qs7y68iwRdo9@KXS>Np|7n4w3?u_#wz5kq zCj*@93|rh7K=Sd$)l!RRd693Dw^*j|x`n-vOE_I#jf^0ox%Ue53y}RSGR1ixz0iID zd@*72P7wCqj+Ckb1HsP}=UXeSTe=X#x1tbcX3ST+TcFoN@KrQxml}%d%=LBS<#uy_ zH*VemN0^nH?+#^oU$*cp3uoRw6Q;+i74$i#E3e#vy*d9m-81i~3)YguQ1wzXDRok5 zzD_DdU}t&O=7$OZ-0wA)+_l+U=03NGw2>q!l3Rss44b8eOr+I&_JB zWKH3m;@PjusJE+p(*)hFp`_VAd8_Gqoc_}~v{nze<0%LAAV=)3~(EeXf&y%Wa zhp*%Ea6=9$iW>0Rn{Qbr$lUMqzdyA@i+Jg`9S z(`!&KwcW7x`#Z6{0(YEPU=wxZeN{@gL(=0QB=EnWL3=tg1ifSMpo7kwhG%Ghy_b9s zTvxBi|EBqi(Pz(AWn!OFTel<~mzFL_TftOU=Af?I-#bHq7^F2n^xu-*m=tY5W)6Vr;HG3R5k;if#XTs)f;bk4T{QT=;b6`pCiE`5Q zgw;^-IuJlP_O_#!siOid+VPf4(ysECYp(-o_Xd=LMVYM9xxBpD%>eahqiP+Gjd;{w zX8MkL@uRv!J-~QdkXc0h&^T29_tzcQgIO*#O{B0)4nWp>Nk6r*p{^1Mu=dE&5}TlN z0+6y2(2hA(19_s7evUj^LCJ)~5Qx$Si~JnkD%a8sObsK`LQXfrb?JuTK5o5vuQui`m1)n4yUcJt#y@{%a@+5jd-o=@GOXao*}u+wocub+i(kT^AYi5 zlmq;u1NXKbxE4H6b!@B_YaGc-25Cm`nwiSiVtQrkxWNTqW5M}Yf%0WnhrRGdi&3id zQ*ql5ZZ9g-`_2;TRU1WIon-aF&9WD9XLV{P`jjJgA`Ca(rXw0x-<}d`k>T(-+{egz zJ^pzudp7}>gVFSb_uM(4hg7`lDQ?x+1z*iNx+P+e64CJ#XbJae*I77MK74%W@8etj zkAs4Yxo=Rd>^r-MxFWH@nk`XL8JSekq)%Nrm^yokY^$=zJ_ynDApo*Y;&c*o%GYjc z043c8Kg|txL@IoB6QHjXfQ40OP@D!BR&9Ah@UAH!9Tvjwdqv|iRl zNGkRpM#2++pMbpKg>h7s+8(TJCo1-};pnve5P&X|)?1`u>bZUg;85$=mBdGuENW+c zTXTDsp#|+U+_%OG$RoN-^^RbR;zD}95LR2Nk7$t8vG%hq>`qmpPlmCpJ)ovJ7I0u? z#}0$G4U+A&c?W~Tp8s`GedFT79zU@HStbBcmt#i=w0AWSTtis#d!CW1Dwf!yJQ51S z5qHykqp#Jp_5CW?n&gKRyu-LBg$i*Y@a8zT@u&n2*H2;OjM;84bkgi_|ez*tK zai`U!HQ(q+tZ`k;h+ptWVMVsyMLWknNxIAg47fo`{;5+s#M-7;Q-y ze#+F-Ny25QM?LPPRlU!iCb>qZ_iRa~Js+T6{GS2n2qxr<>ZV&49uz>Wk&f`-1Z%m$ zJQ6xd5?-`5GC!JIeug^{tia)Oc|3IPcmr2GcG6pT`@o9s9-NWFNJBe8tLno7Z|C=I*#IDH`MN zG!k(oeD&^CCx!yB2p1l>vScjuo=<%q)wg3e{|RWED<3MIP`rE((F*-1y|^I?)#lYF z!}EOxwIDIKRBRsNY5m=A`kltId=fH*q?@{Y?zcbk5wZ=Dzv!ovia7MuX%|G&HXh~fj>4O6 zcg%knUG-7R%lBCndUdjJ!zMi&W>B*_V}VjNTb-QkHL;P7H}1`4Z*C@+6}wD*6_C&R zl274bmMckWXFK%bo^2=$LdE+S`QOB?!!@Y6t=W_C)YF?X5QMydXhSVfPzV6vNDHQq zyg06Y`lyP;8qJpz)yc4ezT@DP>w*KfX1NneoPY&obT_j8@Mtwgk$X@BWMEFzDj(E{ z`|J2jAX_ON2sZW)#;p#e0yf6zHsb-J-m%DL(0|_~>AAQALwB#3)OQd$_B;9GC2QDQ zuc@~qEagOd)%ks8VKNf~Cw#}r{4nF~YgJ;D99Wxdjm$AMekir$9U_YTAYzE7qS118 z8-LbzUOvj5<>sV18UFO;ZtE5sw_`t!B~1_(v= zmVU;nfg(Nja`%s1#C3?z8a?8YL0l&BUWffClp!dFUpJ@W3iYid>X5g$3cm5k@YzSU zdX}Oa@Kjy)vGOE4V&nTZ{a8iiM#vOQSTo_>Fy0q(BLsuLRLe+*3L${**ZH4p)>^ookwHP^XR%vAa* zU%tMHoz&f4rekOiJ9UGQp=Dz$dcK9Lh(5F?<^s2Sj4t3CFxI`zQe1+#*A>q2tEfAk zW?oc6_nEEL9o0;KW!Yv)7fmMCSvJ-12#d z*X@rAd9b#e#>=JQe=B?~0f)lixDrn-)e;1lOsypAz3=0O+f6=+>#peOy9VAF41X2T zt*ceU%G^L^cC3^8}&<)C71zO`@@8Dlep(*j(|*ln*Sgryu2LlQAZ5}DHF5$Wl^gswO*d8vlKVhe@V zF(6AQ<^JFf#MC`Dge!g2NGz0Y8sm#)^}a!y6VMexq9kD+BmfW$75Btk%K3fI?0}yMl9Fq9X}o{z46RLw__}@FC8-$q)6Y{ ztQdQ&mqOvR19$Nac8t5?CCN8*3Q_^ya+hi92tnt4-aV8zk%t5XiH%{XT4BH7$I!^p zo;%n1;V}y@R(CYWqGOu4UCY6qm^%3LZIr*J^%*inb-66Y4-`V`{sUh}Z$OPpnxH{+ zy8#WYyTH2DkO;h?%@WtRF_259%{{dw!NKarMzP!dmsw^&*hcUg^X)G2W~duBOWxwk z&|=xT_=77C@xxiPlilTr9wIh}f1XQrjy&S^;$n zya3nCBWH`fOahnlmb}aYmwAB-2b>k?be1NHE04Q+iMof@ACy;#KyFNzLz`7h<(~6@ ze#rR=-Q0w5*@qLZ1bZnwhY2O5^y`H-%KZueb5;6#fqbbsGYMx=I>aTtfXiO{s(oQMys ziUpexQ0I7g0S!S0>NqLnY{;dS>rUoe7y&zFj~DUD_Vm&#j~=z?1j`1fzF`|j!}{z) zz9U&_9gW#Mq9HSyfi>gcdq4FG^ge3O_a&25IAd?O_W2y3-fzx%KooixALFPvX~i&- z7sF96|H^$aj#O-n_hb)>mU=-B)dNZJf21l(*bR$)E@um zXp1tR|LwL4#-0~~0EGVujNmlAVsH@vJEWuE`53gYtjHctZuY0iVLcZ{*(b#Ps^xhY=CbfT+ql1PSIx$%q zvkG&PA{fsN!W*pqd-LPk^#2~T9kVy#$~6djnPa>HQk{nh2Sv~HU@lah%67qvp*J78 z>FdL9|9LX*J2IT4H{Rw#P-)0_CUFLs+b@WTb zxQe;I27&RGW$c9)6Yy@&#rA=WMyS+u(@!UCZ1;DM$4pF5#b0Hah6Td&&5ba~K<+uf zi*a~RuY9i|8eZ)Tb7ezBXOKLir0lQ`46!z{FX<>v&M(Z4{ zuq?f;*3$glMO!U)i0b*Fx^R$k;^!+*Z}=I~QU_3E{FqxQlCC!vo6oS9>ZkeehNAXC zwUbOWCa&7^l#26pf~Ebga-PW2EjZmgdbd!80D2r9{S{7tZwjwv6P|h`?e?cjg6+wk zp-h5Kg*x|#Sx`XeCJnMdwYfFz9~U}rze~isntSSR$p7pBT2)j>HS?#9Ym?qk1X)_w z#wrkVRrJWc5g1iE=sd7=(XMP=56&AnWJ@g}sB_)-z{i~x!-2Gl{V2d360;K~4}xq) zZDxO40}dBMe3*rZb05?ub`5{{_F@lu&&S|5c4XuZr@74)Xzv3M?R-puKIDH~DvH3r zefS4!j&_FMUDKA2Jz77G+ca&VHxSrxWiy0m+jvH~!1;i7ey8NiZewuEIo$mS*&CVp z=3OQY#~OAE56=`D)W(z38j7K0jKN@Fi;W-{ZWbzDNA)~=vOQ+nxxDm$6Hq9W-Paoh zUxQ(uOlm+Q#QNus6)Tm>M)s$lX{tQl38dgKmWK8N&?lE|GC3p~8VK(W?=%mv?A=hX zJgZ`9`ORjH(Wl{ zwOygTty;wcJhgL^Jftzz+VGG+ZD{tDkhgnOjPuSiuj0!Fg1laoLP}=23V61(4Hn;6 zSE$|9$GZa1mj|L@Zb`rO@WTBLY|E z&;MBiFq}1@_rss-*Gu4kc?mqald)Bc{oG-_&k6Uez(EaHtpkDGH)(tZ&xgb9H*zdy z##HK7O%S2_4jT_loHJ3|neP^VtziM~sjG#!y;E}+aet=FX!9YJd~fso;9qE6AuQx_ z$OhF%WR^xdcQ1fzidR>1U*0QlOd(mCZuoD=&P}k^v^Eap)I^>ZxuJ&Ogb!BEhoeFL zF8@HQ+}MgT$MqW=!;%8t{0GncY#2hLN>J1FlXidu6j1GcxLEfFELovsXlFIav@jszakn`kK-UM~RBjXkj7Z#sGOIW>Qi20UBx`=C8$zSHe)?wc9w4{A}$*~3e!J^WZf;#rxugS_iWIX1PNpshTO@$ zYCQ*`Y160LAf~s;h|_YMaqgrS;8>9T2AYU<&aI{r;lEv&q~SZjbKcTphBFDxLgg}ypc-|kAmX|J=;G{w8X_ng&84<(ybfOm=CD_ zD-;ny%bc1=brd!5MQoXZ?0qonLw865q*r97pLcv4E?`$>z_DC7%~@58V?YhqD8^Nq z4E5&xXtw2GD0VeWs6llt~{M7i+LOCvEFc%X5eDq-RRclhR^meB1k3$FWh z6&kkg+=&1v5cIjxQGobqC+rjQ)@j=e23|P8KcRp!=@(A?fm?zDZLc)Wy4yQ?8rB)9 z#%E*k{vJ zvYy>wtSh z@rU|@sw(7O?+f3D*j&Y}66)_=I538D_^Vx_KCziQep6OualjhKIkE*}(om;G^@nI! zhiroj{A(qRm~V-HK_xg65)RuX^uwaJ! zo-3yk1sKsjZE-wyp?g_X$OLIE%)u(xdy?QwsD&`{x)_PAnR~s~9g^)6WKZ7u|Mi*d zYBC4ta{KZ58t(!d6rNLw3ts!8MXb-bS$ejfVA>6nR>>I!8w7r!Iqc<5({8EW$BekozCA% zQV3NHhfxaXJ=9vMqH?4o%oJtmhrB~Ve#^XjcdK;0=Q%2*z;s5%+8>Mvj5eFL>wMZA z?igf8<7ygT5&^;&xJlo{?G^a1CY(?;vbI|I3sUN#$RjZZcQ- zrE~3MCQy`xA)W>CgLvPH=DP35OXhRq^WO>V$cyF|CYs?T8USBO9x$5Lb>IS~Bg z5o3aJ>{j&wYSRwM>~AK7j41y>EB8+IwJb?gg=-11MHC*E2uJ$xdEgJ5QY#7N1-3j_ zSJGM>JUKSTSKIdl2_py|eiKdXq;2eIHxh?GRyA+2gRLW( zRL!Yw*11t*sn^S-mVc)ETX%?@9$L?09S28D&qk!8&Far*W(wBViKpz$+tv$_wfdOB zkHX$ABK5YQWw(ag`z7S`8l6h@-Pu!BpmvjrQ1=^^6J~Byg#Op=;10*}dQPu4ySoFG ze9|~P!EgJH@@PBrr^6bZ8?Kw#e5q75Wbc2x%%KJn9Aw6m-KTeMfbnt>*L6Bg#VKHo zF|G$4@EfLAAmL8%7~q+ay7l#$e1UXRR}1y%F}^;Q|DMCkz2szkXtgkLa$XrOJYn8! z@QbQw9vZA%$ThfFhiI;MK=5U0H#$680w?m#@3C_2tWMm2*Nm0n z)5N%=#%XFa)0Xlt=4$@+j2J<{OeP_{n;CRxr}Sz|BUUWMTZG2__@%2t9XMz>t7Y$J^bH^?~ zOQNAxH-USynpaKHR-P|^N54LI9`3Kwp`sqNN`QZA;n^AA?xl=ZB#ATB$M4g1I`94{ zyosS8EZ2w5Pn$vRSgl{^Ni42nYhdvUR_&iNl?!gFmSW(LZjZkEfsJ){Go|_y)4dT3 z&NerJ;cJRR77yKA03B3?0~PmMuM-$os3xcgu39NYY;J`89{et>spt0 zlVM2YjVry+cGQu3(s8>w9Qm2md~id7#$Jn$p_!?~LV1eHmZ;YYOWYr|CO+TZIM>F1 zx~y3}bI#s2|7^6};BwlGd;w_0O2l{)CX5=H5}PedzdQN)wPNVob=29Wtb9tB)V+t` z@s=xezR5MI1mXZ5K;H^(bd|>N>?2b()TwEv5Y@c)qGzkcJa?EBnLugeIS&(0D%mt~ z7BxESud^7?c69S-yVqdh?4_fd#TnER^umh0_O(lPgTGqRq~Pu^pkJ*50qePr;l{-7 z>$yje5`~h2r!a4X6r?wwD{az~E0yI7#Pm#f2%Nbi{0EpA{3pr7f!~ozAuVw;Wky zAbVZ$ln#9x3=)p!bk^iP^2>Xidr+EyoZS z3FYehz+Vn0b%Q9PECU4)QjO#eVV%E-?!=qPD=_SPxu!i%%vf#f$^iT^?16J+jmmgp`TGT)N;6*F z2tJj&O6B@6xpR3fYt9&0(_o3waBOEJ8cu$nDuFSJxtELlYRcff?;{#Oq$Gr8Z9r0K zUd?X(b}YtYqG|f()b6S5;xnv1V_-$CAs#^ZTFEX0Jsf!xvwRWpZ!_d!LPO=0W%6?1 zi-S8SynZEJ^Os?iIz=}Q)db*;=LR_e9!dx^%g|d&1&A|63@?C9Ej7Ic4$wPp2w=oC z8IWiW(UnoO|NPtG6HAUIQMwM0!YJ#i<$FL>3#k4I;B{h|%I(;^HT!zQb^oFQCr~RAe<}&$fWtz7tfPO-!vt zC7M|q<-AMERY9aZW%+3)Z~gWL={%7|3K^D`oq#lO`|h4J-k21lxDl_lz~*=YZszC& zacq8q1D}eS$ea!#w0(eP1Dw+tjepkkR!2{*OxEOg2&IuMz}xbyk@C;A0PHvFV#`72Zy+C%Y&?98Mydk zK@{XR70vnZZ(NlwCL}FbeLN2arY6=n9Z-=--h1E1ZweX1swyCd6Rq()u=tZUU~QiH zuVbuW&C6X2ZOuCgPW8AMnJKAgT5yrMSU^0s|AzKtv9=S$(jXa+gJV}Mq}RRquDvqs zCJe?37nte}020Q9X6`d+k9}hZ*0w!sw?5qgMDkaPOSDTb9#GWfU7iOsG9JZ{+QU@lQJtB za{G=uFn$WMYK(ZRcT_Zy`_my`wTZbRA2-QHDn};R$Sp9X{$@*Y5K%Ql_&G|NU@Iuz zQsKv3PrA25>wTPtwsN>v^ffTMMfCEn&hOcXCrX~lV3zWgx0|y$O%NfqP2qP$4;>!j z25h2@;Ab+Y8wt+}px;l3IOFDhPQ$2rc!&u88M1#VlczBg2Ja=roPrO|Dv!Vz!?TlL z=MYoAmcY?muswxFyUx-K@kGYlro;9llm+lD2wFUFhlTL%JwjL)RpYz#U0wlSnSFQe}`W z?*Q)tdiL^n5FqsRIQ7aVSlIwTLa@XQLV*j$omby~RRUr>NuTv<7}b)krdp;k(LQ_Q52Ynz(9(q&q<$*9V*BM1PSMY# z-Z1e>AClW~2_@4W^gn0kvHzQfOGoG4nLnmOrPdEuNqX9jf$2yt=5dIBS|C3>yw3&l z2jD$%U`kqIlooYP*g9|svgmLdmwiV|In-?-S=Y{9*Z;>sVhS2#NrYRCt0-;7~V6HS7FFsmRsEx%jEU|oE%Al>I$nD#1n@@e z;0WDp{|*S>7E@#zuxFrCoCs@9KP>*>a~7!2K$3n*0wvyT)Vn!LhSn zJ+v>|aGI%@-h`wR8_psCgcX}Lq(nYIN~5-23_w2&I7=wP+_G+N#88p zRh^v80jy8%z}?Wo%Rovun2$=y!GiXAZLQlnt59HB=KrRYf1a&Pt8w&o$V+r|$X9U$ zsmLO;eZ;4gp-uSMn1HG#H|-AP`z5!GCQqFVlqb=S`-k}ic)447Z+;f5eYc> zl%wVQ$M3s|IuxUFpjQ0PhtD?{=k+>7{##QJaNa(#<6;ZQ|02fF`;^XM&K;d%*Kluf zgnKSRE6(d4FtBQp1nb{=)V9t;k&%nhD1h8Caw@>qr}I-aaF({;qVC}|a7zA;UNvs7 z-&yrBDRAOK?~d2m!&;E;7d{SlPhF~ytL!YbS=#x??>@Q@_;eTEXYL2w$Z{FUS|Vka z#idN)?M2lw$nbijiSHyo|B~4+nm&hI77Yqlr%QjZWGQ!^lRkHx@fw0%V-_4%J0-iA zNO;zvv6>B3d1u>ilI*@IfKM5L=C2F4r_zolj^2>q|G{&ItH2*9+UiZn<+3wdH_q3g zP$~3yDP~adT#;c^`oJWKG6qEby=XVeh{s-N zt^BvBhn;7&a=yN4Mr$VWoz`e$25%j*uhSd3e5@%WEh8+0oPnR;LnHl$RC@FiGCdhJ zmGJgY*v8EybFX>{do%I{0!Y3EKek}@p8H^#0kc*~soRLZZoyvdl2%Luc3RLZ9;`e5 zblbnXJl^%~!xTC;k@6));?UTGNjBVI#Y)+!En#G^-k67iu-LOhL2PBzwq*emd{#q2 z&t&Ryh7GO0Zf+obctn#~?><+l*ahQ7F8|regB?Z5J-AVjkHA^G<)Gq<0r>VYpP}>i zl5Asm-#MO$-KqV)y{>PTpWgwf=(kbR+cPaM{W73t65SVBXwMF>)Qnj6g*II<23 z&TOtfO8n^w$c-3e?thaDj=F=)E?Od7LCDOSh}Vsdsx$?xVyxKE(ncG7Vg*7Q5v6;p zZHn=xX=t>uij)oqR1d<<1l@^{>r!jWP9-{m&))xM0;|hA9NxLbL@E297Gr=JzKY_k zc5Z`3N?!4F69=ysAF5$yEUQW3ptKufx*(l~J%RFqDxH#E+)De3LHKN0HLQ4IxpVnK@ zwbeIR3sJAeqfS}h6l7(?aBm!?S)~6>FuwNOE|2>Va5CR*#}=@y%c-Sig$n>ESyTVc z3zHW=TnRbF<#(_hUZQj`$ChHO{dYGctF8VU=1)_OtPKD$vnjp*4zr&sH# zzcJP1#Trc13Z*8Q=V|;-y_sSUr76Gp03|EMYyFNj-!QDp0-h_wL zdRyF4?5llsV$wyw)*mXRZO!0<;!iiH(h>=&(_0nr@P4aJ4*p$X+X-{XRybN7IlfVS zmy#=#!Ja2-l!FLW-V%{BbF;UVkk?f#01gM};R$4CIs5ez}T@R86g4*qfUHr&ZXezJabL zW*+1*KaQ)N84WEvcGo>$hgKmHK`p}aS2!D{EEjYpgo0F)5|-I))!{wa$Q8!xJ5YN# zYo9GhlxCy5A9*UV7prh2%#ha1IQsg!KeW|2@~o`<#mrU~2Mb?wB}UWiuRQ=8X6sZ( zfV&>eeGPc{YJKeu2I-cAP~T=SlON{*x6{N_cREKeRo`EDIvmW8TzCmC!MgHQcsh%VGYQgA;pZQzzX^)B4j^)RY-vf}F z3mm%9_`a&%WbR4iQdJ7oH4e$cYbKu=hWb6V2~iz>+P*7=F>u$RsQ zJnfs~@zHH6r0Jm`q;pTUGyC8Omd4^phmt%dRiGzEPPMJVQ|NsKJf5kJ!=I;_r5_6X zXxb39b$bQ?fTOIqRzR`=MWcmKblnK#UL1pZgr}NyU>Wjqab_AsnQuRh(s=~BRO#BW z3n6)#$F2M({N)o3I@)tP301hi9cX$&w*KS=~Il69Xf*1A#{x-k~ z@YJs4jMgFl#OecH3Nz!xTRR&O8tm#~rDkpTQ(=yO;U$P2kki5l6^js)N5wo(ye)cb zW8iXTz=PBAdO?dBIx`1~IQzApAQ6TBa`kJ_s_*?Vg`J0tg-yx(_HWV#eLnc5%YR6X zRPnI(CwGEIL*G{)P@e*GV8{3_g~pmkZpo!m8kH(}XX{PXJK@E!Fs%C%qT^B>+0QmP~< zeTf<0l&N_tzWa(mjyUFD6dbM>7Xi#V49cI?SvNXYYNX6Asqqw=W~$WwwnST!oiL;% zGvC5Q&54fdW|+ONW$M6>Fg++3(H8AS8U!b1`*){VTAcOzYI2q*NkPtdxVC*qbn-YC zsoiQ<5RAq($O*eZtzXwEcp|C6a=B8ib*&C2Qw`k;zN8LN6mWXr&H%V3AF0+jaLmjZ zKBe^VzrpmuXizG0fLRnQ0YdhISn)BRwGnF#!s>$dZ)=*hC;=$}sfqdl=V_k!(7zr; zD37r`Ja0D%_OzzrUn~Gmi$0v>+}G0J1Sb}+4F8Y&Lmg0vyzaj}yM~64tQ0b(h5Rv5 z@9@%U*5qH+(4CgykE^kd{CXe@70ZzHp?|a|XuFc~X#bt`z)M==DU8($Cz1O{Ie%`7 zl9Az`!SV*=X(ILkieMS{q{<9U0cQyKh97kFGF{AiuivOWyA{MG(zneTCF{bquJ!72 z-!z)P2O2>v)dgnk?h1(BJK51f$r~DXGQt63DaF;D^C7q{;I8{VO^X|0JvQ?|rW1GQ zdkvOlSC%1nzf4D1lCQWeM`3`IUQbFv+$XeGrme4@b9*Yyx|)%6Vf)Vdo-Y_1O3 z$^TTQme3Xb!z+)x`b$#)?_InfS~{H0Cf;Y~t;ujwsQKpWrZDx{vL;&>5=l{^bg7sJ z$?S&F_asBd3<9`(;rKmiK^2aRTn&ZHgpHS4~FV?%+Q=09pyf zJOc_B09D-|lii@kSk9=%)Jxq8wjHYzl0qnC1B~XE;%SligvQ(JOC{!2%iqg~W)65~ z*lT6ss0>gAC4CQMO+6?_Eeo_p!#>->Z;*Pii%utk8A0YKsw$LZtAZq4`S$@pcw#6+ z@>dN0zUujBAGUr_re4tvGO_cw`jY=eqNDpgo|bWs%TDenP; zbvFC-^*m75Tb&G8taR>j?h z_^2@H-*G{2i@<5V>+KYr^!_seIhY@iT~lu{2T~0TESi5TZUdFt4arn%;?f_EaEIRF zH<-Pmg->ZD9x2d<{@u4V^$!oZNrP>A%i*x4E?2w6(*Z|#H=H_oa&#e0DPC_AQ^Pj6#)>G{ag{x%XhZ0NBm;za# z(G+LP(|~}?rq>Oe&3spZt@Y172WIt)jqK?{tK#Kjj$=jg!FGJQUAmLS3kFn1F0G;Z_^PZMc zha&YZ?@i}eG1>oEfRfY7sN~B@hd*5oqN5o7ql@6V!@!}%3Rklw*cC%0uVTW%7N`ng zfP%6!LnAWvm{`BixggazvVqxpooLv6s1JJcfa&30)5lNjICmI&pbYGcTK?qfww)!4 z%c&oed-U;2bn-`$G_K}RqtgJnL}BP8#RCApHNOiXY<1vx-^Gw!Wx4MSihtRw!QuLx zTkyI@poKaG&)c3k1O?Y-ec*8dY{x8KffLc%UxsaW9^PEf=-ir3r_lq!Hi5`gs1G&D z#W|WO>@7{pzHz|SKfFpA|8jQy&`FeRm~x$bd4Rgn@zZF18Ixq7K0p+)eQ{LDnrpazCVlnz-%iWSRxaWP93rPvyNZ}$WSg%Kv`=^6 zXnp^v*>PMfa0l)MzO#L;Tl+d%^PGL-^J1W=EC6Lzp%-u(z3q%_wfy82poMf`(acf`=L*P z+Z}kFjalIKcN@E|L$jY=985L^$*D1 zM=CUUhfSoas{lnIP@bl6P})4_><-E3jFM)3>5?FUA{) zw+3BO zg`pGl+`KfEq7=9^&hFwG{N~Eu0!^O_GUtx37@2Pj3n=um^B?<|IqtOALe=ch!*u3s zH;q}r(LR7mNxjS2@mhvNiZvQDf!KVl^?Ojq^P#G0=)|nCy#E$Jvd6qe9`8mBbAon< z|4$=5`g|>)uYKm8N{mC*Q9I;!=PvWFC;gQNYxp}ttSw?Tu2BG22S$l{xnNnwT8M)~KOvS0JI)8cfJ`BHe&7kIvf#hiHrF z);G+So1dsxcJ>}3GHNO|dJaJsMN^JK?d@T4z(B8J%BSOIL zW9O<^yBY_3rumKBvGNY-xp!u3p;z>SEtKhem3uLNlm(;Dxna6`s2e9l=pQAT;lR!n z;Ssh7ka}=cjdtc71%3Kv##1n6Mg`Mx8HY$=%3VJqbJ}D%I}WKMO}X;zeZssY$TX$b zXzTrm`^PSu%a7gHzkh#W&2e+&Ghtkg7;cMi>2sN=!Ee-UJ=w(!;6oc(0i;izLJdI` z>83<3p_Ng-4Qoiu|4zw zT~+SfslJ)X;{^(D@pOEWcaS6{8On(JqWioX$byLdB>lVT7~+*Diih1bmO07-jK@xDRZTuE;^aZ%(zf}$_%k^eulaLXb z(yqbQj~{*hiz2r1bMDrLdRms6={C6^I}DJYIEM8GSP5jSu-3Rs(O)N%)sP0iW1XPg zF)^B5Ozx-?k7`>m?K-O4AFa+K20$msglbMGbLTqguAYK*R~$~;YW*#bQJF7nVv2(y z4f(cR$ZYA|Lzt5}_04N*t|wCN1*qRJ=_(A}kTUlu{(d6y-^wqogKa!lg|KvNzdnqH zn|<7#3r9-(kLZPZCL}$N!{rze1H~L5q0b@1jF#OR=PgjjA|(D|M_=SVMbU*Oe-2h6 zF9$^_iH;rxsb~0w$H$Rj`a<22nu8^g`U@nacQ0e^pEG1A3RLpVo_82H+plv~oNJTx zu2*P6G*%mJ<`#tXFOG~@vxZMGZXK=CYcW%!I9`4n4T)N9VyC6+y3~b7JDK89EX(CQ zWQ$(u)*I#8ulxa$%9_pi$~$@e^?(}bNwwN!{-KlUGc)e@ZH$LNKxEr7GmYEV>fM!N z%+l4mLDNMLogTUu(5S{#UK_6g`|1@SYGA&4MLkNGc#9GDy-dSvB|n4<3f3mfc_;Gl z8HbWV#FZ4P5N`pt-!~ zl4!PDmkn_x?jM{D$V4$N>xqGfDgwDfrKqDlkRwVo(>x{aeE2-TXiA*CThVc+(xE%R zK4Y+wc+tX5FlGMWAn~n(Q)pYY{X+PkQ805GFtNG0w;E8*?AUc05|A9O-=QNUiI25d zB9NVrrWQ~|IOSMTiKi;tL!S8?0(&{4R*V=Sp-26Im0ty34l0;pSeQNjsvoWKxAz8BupMry^kLqP!)=~vTN1t`s*5+$4LQ~a4>W9S ztoyxFQW{D@CLq#HH~*26QQ=jYd%YCHovUS-J%Cb$3Cr92#JUs2;>=*qCjSqo#KcEF zk$TY^hJZy@%h{m_?%yTM==cHq_5r|4ebm0WZY(-bu@xobQi03NMDs6wo)E@IZSes|8ErkRY6kXT?IVg1c$7}zA%$^{X1V&L}ufdOBaRIg^ zK6%pow5_teQq4TkX6C6`Y;#_FW!r_eSE=xXwiEDtRu+<=k$dR0f(pW#p^K_B;g-rm zB@AM0w&TKlceS=Mju^>7-5un8fRcHMT1AheA89)$#m|0&}yIbD|%9Q;9>M%KT=s zF#kG{LoTRgVS}7a?t6hWsZQ@Z@|}QN_h-7fx9ot`hnD=8hD}We5htG2JuZP?uV|?2 zf2@3ta=W>qt_VZ4uX8g^9GK`4U%qGlk)9`}YHriWh2Q55vY~^^o6X@Rc z#yPD4ReG1`R_oukup!r1Wv*V&$uZ|XsfRmHMJHv@avAkdI|%%@%wnmOy+Qlc(c17G zI+8J#dqK#d1}5F`O(|E|QL#Yee!x)MA4GWdulL#&nm8i0U~lVfhAPzJ1P={U?EPxk zXGIDSIuH8PSevj%*czIFG6C{kQ#3F+NA7o&z=6sHv|* zU#xE>oiUHDtLHV;)8g7}X0mGh5~0FnlVv@q5dc4gr-cVu`%&cOPF9}6{TXZ_u=qo~ zzfYz0iS?MM!+ET5ZG9GO$=5;3=ZpZRo?%m#&N{1@nqL@PRbi7ZBesoayH{PWqSJrn zz*^H~@Vv8B-&h3WY-5Y;rhF`WX-+i&eP#OdJ5Q^oS1E#%AI*h5rrz$0uxUSubt?E7 zF}0Cu**!YBf3n_`lI{D~o#Ua3IuPN}prcQSn5H#wwtnWw8$93W?(HUuErz3n7Pl0A zYBKYC0}|c;+UweZO4F2N+aXt&mrL`C%4-AajJXmS5EhcP&3ZaYQ@+G^cB_~UAp(CPUM0ntSs7lCVkRnvkXpRnsI-pQR$MUb)))82nDe2$9fut|c+7X%= zGy2~>fVPbc8&)peC4`0IYoumI+AtzkC8UqbJk(^BcIDTA81ueNZ*5h+-eYC>F$QIj z7d}}4-P+gPlm#w6cP?09NOquajTlsVQW_gic*u9=sDvy1^~_q@A^9*@93ki@{!X8paX3XA)1^Z+ z3e)tOq?kCpNPnzG3jta@DcE;De;@c~NlVU_VvU>8@vy&v)rd5B9v!dI$S_EFjVOl& zvfXl3pzi|5JyA$}epWCD+8nKU#S4>_Z#8FBM^3|ZZBu5AQKCt48&2hz*I{f3D;1-; z!(^|*983k|34yDjtgvfkeFh<6Gq?YCLDu>lS-*9T3=46#zaOSXVb+YEF<|p>Zfd&m z9L(*8Y;Hy9&J7))4GiN$i(19VU7PedWf?%15U>_7ufiu~N z12t+DKLBD4Rk{~Cr)`1b zcQkM-<^IM$bEJ0ItEMtsyH#fM-SXq%*#$d{dJEmJn_*ajy6a0d(jbOpV*Y9(@Ep(h znP!*JSO!`q`a5}?!n+_H6tvt zNO1wph9r7@!_T72bbFxN8Rq0nW8@Z}z6E|-XLsG#AAXs}T;H`^?4g$r%YwO~+_0ET zW5WY|;Ws8LAo?G#OK5efaFrbd6Tg8jk`}1`UcHJ)2Ly3Ss4n8vUW{MH{5#{@8r%4) z8G8z$9gi(KFU5>#g>vo{O)dT81~)8wE?KyAW}-%I$!4u-z1YJ)p=Jbu(*(n`O;7yY zf#Au~N(O#9X8&lB^!HKA>fLpY;5hj~Uyh~Z3AHiDfa@_C@MZ)aG^O$OPoGPPJM^Xu zb<(H3tJOX98${{iPIbkRtpmrV`>eV4YR9O)!tF|GJf|t4J?odydT=x$XtzJutAG>3 zS0A6g9pq4yp>B5Z(S_IFRu%NDE}C5&$@sGNk$Wy7&I*jalfHYxj@Z%rn2bd*t3+rEhCifV2MMy4pzt~f*B9vRn-_|12GrICcNPcu4q~@5{NGR?eDJUksJHky5 z{i#eTSWz1_If7hJ>g-X_Qu%K*19??LsK+i|R+Wv6K^I-~?bU^EN^Sn70~vhA`>_M< zk*z1eV&~*yANK|a_JYhNu21bR&R`B@L{m(H9oUi3MmmU_Y6vjU zvrPxTX6Ycx9K=sVnWHkxe@_LsoNOI(&pP3lRr|k^^#?&M%S+of=v)WI=A-I&zJ~Lg z)2uo-zmaRC!H1>q!$OCLHkMgTpES9VwUNGl+?rkYntSuZW~j=V>0s7uia8?T%xm5@ zj7YuWzHm!Oa5HD+fI?_d3?i~vC2c!&M}D7-h!>?P#iW%GmC)OG`s}3Bvx_$?vifO%hkoDt=4%x3*|5@_r>Ha24dJS<<&Zj##g_i=p z_6kaM*J{lUQ()H-$%47sb<|(|@~3q%J!*(6O?9yfzyE!^CLdS77dI|FdikW zP9ZQ3wO0dW};%U#`8XVrHuMiTSC@LXIKr}HkHt%3SBn?U!S~6NE)W8JxNzn zgB;OO$RZMlD}0FAIv$pEln%|{3DlBkz);wH!o-C634BC{tXzZGfIfEp`ajZ>F6gDq z&pEj^0)v>o8G%EZy(7+VV&(od z*-RdLAO!$DCRb(TQ_ZpU>X$L}J6$^H8x}Ti1mmY~9(%f;g2&h~dJ;j!%(N-KpOImQ zCK&wy2CWRas|s!lh%`mGa8>W;xmz}e$6$JA(CkR3u`Y*LNg$OhEW50m4UK~OqpzF> z-@iTw{`T$AuYh~xtf=EQ22mGgmLG5o%~dLg>T2lr} zNvFmSxL9&f|CUkMeL(azAsy+6Un~T&>cHFzrp3q;{+EOCF%rI%j{!w;@@CAG2F(4YHQA`^k>r2y<_u(qWaXcP#Nb|v-^i3_hoVS*>99f9kRN!+FKM6z zcF6QF=*SbIf<%IBYBllHFnxLZ)61OZ&t-xBs`s7}`Wt;c{cUy(Q{qOp7 zleYlJT9C;{z@LJK#%}YgwUNCV}d?tAbs&qFQzi zde;Gq7sdpQS7ym)^_-)9mtk`GC z#GUAs(d#6k-^>;|R&UdGL9K7@vsMhaHxv{tPOUbJv=ev0Q8Iq&dtAv#bi-~cl2_P> zSo>g}^?h%3zY{NZaW)FW_TKW$B5-53N%v?U;~l?5#P~pu{9ZhzHmvfl$dfQUKJm^YkIdC-q`In*in0LY$ zF~`zavLxbOc@KK##*8IdCykHvfmQ$3jUs?8b|DHbg2;;N2R~GATqxWni;BG}3j0@0 zY_(PB%Qk@JXN3O$Uiq*o3Pyq!eC1CJFu^*LtGM}TP< z=HJ>v?-vMbOml7CpdDh8a>FvNDZ*LsE0g%byYN@$R6)NLkn?c$+pba_Q^32MZup+{ z<2C<4-AUK7(C_b#a^`iX;9J?imaQ+?iEeXKWiJ_;vr+=vBr*0wYe9xkouXx>u;eG% zF)j8pdVp>*U`L8YH<4O%jw$^B;J$5dzHNrwl zRUxKhEzV!E%dmnu8!1}UzQoH9DlKRgJt1rjo|tO|GzFfK@)C*#ntgY|Hh&7L1LXw8}eF-d1da?_7G)FKHErf)z4|XnFEA6~Y);#8u@q%~U^x zNw2+0!?2`p1B=KDCw&OJF*~Bx)@}oB?)mQgOX9Wig#nv zCf5fZe<*P$ROmQTYHGz+w~?ByI?wR8#<+Qtm>^VEOOQelQh(SQWtU5TSAWO;zid&d zV(u0)g=Epo5=CQy1g&cCyXt6v zf}>F9Ss*m@JR6u%?39te#sf-P80ypCAAaxFD{~*tq}M*#+W21Uk=SVz)NUoac`OjP z?Bw()R5bK@4RWC+zLDcJI{F47hG;D!_4}kI#uz1(i%C}tq{=I`-u9R0?jS%bN8vuH z+UY~zORg_cd|qRKp2E-+poclZ-)zG*LqY^rb~_!9Q0%r>k?$~fGNMeOGAyyIi?{Ot zn2hur%8doR9|}!`Mi&U~(ptsgBsv6dp_#*J8ky?Rm|*%=iL6u71q>27$to(qHC{hJbf^-4FceM%aOE~YlRq55P@73)qKBW5v*{(AzbP|ia{ zOJ&{)wAJ{=QYD?Z+@X%{Wrx(jcNYv8`>WQ}$6z zHT?eKk`;Ux#(mDz@6_CP%y1MgSh%OMb?*FLS89aN#r)sQ^+=;Pl2jgWYv(DP=S0!TIzj-=$ts3uuI#ugV2$OrT<}jiA}h*u#Hto7trw3C+@~jvpLF z5vULBAg7skC8A{cC2Rdfw;xdE+wC&%3XO6|M3#G#7yd%Si|I+djWRAW1 z_FPHm;Gxt@0-WTgu}#gvCi^JJXvlm8BDDC5MCc z1B@|fpB5h^ARBnD-f1@qR8-MIV}*+M8e1fiy+Z801fkr$9YX1QM}@F^floK2k-Lwy z)%|f{MqnftEsdmfZp?nKQ*?34;oe@vnRs{i2V|h)XcG+5Sdw1&h0FMx`Q%Q}6OHhf zA^)K?0@dL>o^EqJ^t)1hQ)sF~7B`WwIFF~iL1Uc67@jgVV8Bkbuk?S0!Q!jh*pJGqMaBZ8Rwmxe0uLVpZJofmlaPKQ&#POnnz6aI$RyFG*AzeXNMcO*h zTA3~?v~OEwts~Un=M(;8)%Vx4tow<&=-aAIY2bMD<8Ce;d&Qs9E!@ z$lvfM{+9VqlAaLX^5XDH{$+a7K*pe2>2LudX@{vQSncd_43dR&mcwNyLK8tD+~&w_ z@dEgtvf$>g!eMrdOh(B$Xz+SCB-M+TGu&4yMJlwyMqo81IC^ogqAN4XPM+ZJFUbNu z?5-VT1?RYw>2xSmcvQ4M=I2#JxjpwCd2>h1b{~&CB2I_S6a-_)k%$1sRw(@{ZMClt zEr0kcbWggwxNlcS1s@*08Ct^HNEctAXH17lIBy5FpZMdbge>x1gJ_cWfSc3EvrF+Y zez$bwQivEQIz4zW5VKEutV3}3ObJ6GPGYjdQ=fi*s0ZD$4|_}@&9jG*?UMW)HdnEAtM_NW_8m>PD<|ke{Eb> zbml-UV#tfmvvEfc_M^jAXKsSso9*hmm`ql<7zAH zVoK+v0PVX@MMYkVCT1REF(J;i4Rg-`J#k02n3^#060>a4e1>Ju#}a10l~n~(2(m(H za^S7q^@^!C6K)x3fkkYPdIM|yGln)yJ^Dr);#v!>98%Y&xPzmoFdP@jTg*>S$V$r= zl$AdAh;sicd<~>?Uy59jh-wk)wBVV%LrGyn9+ALH0_A3?#P90!yPYX*<7^rae#>9e z`skl5*-xOmfj`>mY6))ViPs5+0%Qk6ETtF{TBnju@j`&4vSRl0{|SY5Mo+#~fHTp- za^v!wjC)0k`1-KSR5{*%m~_R)qZTMN75+M*qYNaO`e%8Ud~x;#{sCc6!E2ptq0WHc zA~o#pH^hHn?VV5to_6~I<>k;}o(GdB(X{s`0HxZvh+ncW6NQ_={)C-7+RXJ*yW0d^ zCLp4Wx@IlOzQpufE%|;qSf&;{U|<+O+xRfOnmDX>!eWe727_Mc8M!!2tKmt0jS@$h zPl+>#(Yd1w)X9_Ua>v5=i##-j14)^-EUQbzKoU4a%~JBHtUzUMBbJ<+0t!V!Bdi6~ zU+K8Es{t6O_((ReEjIX~pi6KzM>pt&<%*IO&7Q!;tptMACj=yNFsoeA!x> zO*M3N9k_e3D7M8Dnkv1gnu6L|Sift_5O@-v;rVsOFCcWE>K(nd0Kb$qPqcLWiKea8 zjuu-_9!qp9cv)AFND7uWXC%cPCL|1sT|J4wJ!<200)LL&A7vcim%!KeM6hAGa2vzk zolmk2shpji7pfp-bsr_K>Y}#oy9vHT zN5#(JI5RgKaxF0w7+)r^(>OQQd)45nv`;ngZ zmj?hRKXx$UEP>E3<|5dUl6TnDBqw}_LC+P1f|$HYd4MZ0*B<>~W=UIn)XY-<(i&`> zkgekSV532IIOOKRJAnoGMxZwzCUk1J4x5%wUid8hY z=PRczo_%aY?8W@Rc*(etRqO7CDxT8-2lI=?cW*5N$$sFurWW*kI&$S>*ZJq3F(eda zc>jKK&31xfcL;Q9xT*pMe)7fR%tGyf5?0_;A_ROJ{je-leXe`8wo%s6PrfaS7~2?= z1qA@$-nUkl(Yai|eB(aRWmuQ2>NGzZaR=A2i7Iy_upl$t=HTd2w!9@gOdEX6LPdf) z_BcNIz$f{Z@sdDstwA5GB*5v69czZ^0u#w7;NSnQ^#lQb!e=eZj+Rj1M;&NmFnvv^ zwfttS+tW!()9LpWh|-|9KbzWW){h|Zzk_$gvdglSJ=KD;<4dagX$J4W%R$+LqVD^tj>Y zyl>3U=rwarO9cy+igs-Rf0UBS-%sOgihohhKM`O~kza1c5E#+Ls!JbXZB8(WCuk^I zk-n|aT!Bp|1=kJTth8qABxvS&GD+wtw#TN}h?A5j_R!fl@mrK_;JfjWz95nn;+6Zn z8|Z~L)3`R*YT0BT&_v(63zo3bFlQ9ts^wm5Fx@I&i5%}OJKX`N+@6P?&CI&?*1Cmh z1~~PcQRAqE>st2KJ=l0OcbiGV^#CY=45glDY&(E??^|pvxoYlj80Tp3gi(sZ&kY@W z)W$0y`M`R&Wb$15FGhV-%{HH~nV&AzG8M?*_syp{ILMX34>Y9o#0WW=Om+IXz_ozUp)yQy3_Y7P#c8Tp2 zfRXXcLx4;zUDC~xq_X#S`A+`DPZI(cOW6u<_U+@Cxt+$4VkjiAy%e2d;w||ejCAGd zuL6LN4psl_xhznD#|za{bJOSNAud>{;o=t$3Xyhat1mHiHzo9V`{sUPgCg>5p}e>` zRpj|N)!VhuY_CPVLcAhleO`Y3h!;;Abk;fNpmenO$gr4qTd2x*m3}vfGw7u%wav@s z!Cfom5s*sk7E-F}tue78SsMHds-0cBIiks#b1c z4QdVwiVMGb8PthCg%2rJuGbPpoJpxk_93%RzM^5wZo5ScB0D|%V*DqjMHKC;*0ALV zpSCxcvhrm}+Rozdvpm}P{Sk@RC7o90JH@?w&9YHT1wxbf z0&GiH|e4j%7f5zoLX;-HRWEzzSNChL}H;?WU90E zjmexv9a!}n&6uE}0ini}t1^MsF+4$#fZjb}*9^c=to z2yh-%0qGRqAYL@&jk!V#i80Jri1rykNm?%Oiq1tTM;$0wh9m%W2E)K~*q&QX@6{0u zBZWL5vEH`!84H4M8wh@7KGfiT(SQ-3WEu>2>a{C$`DSBi>bCA@kwf(u zLa0!Hz$NueKbDmVqBrSG%0^(u`TU|i$&S>b*eZ?UOS8>K>F`t;A#2)YuaF1<-7%>8 zGB-4Jxv!Y+ZvT8=e9Se6L}0Vs-n;Pj#75jBtwe_a>`%SDt}Ze;w^jeNhg?mv7b;t3OJCF!!<0Ii-*lzxk($Hae>tySsB_Oa!0*NC!) zWw)`eVY;8c-@OPsPi>MX-J6YE;shW-_aguosX4So%+=J_b!wi!gE1XbDnnI2IQ4+m zzak9YQv<5Lxs_G=WXHpNPmX*5PIi1t5WCL-**oPnu{$uy&UyHCAulev0m9Ssynh3_3*{vzBfc@3Z4WDA_Q|E9DncD1>$bnO%GK0oXQHUf zX;9pxR44tn;YQ4zzSrHXP#y4S-mqjR7;{CB?HR09ExA{(5LFe{p z>!a#DTYYtdM|a657z{Ae{aKZ~IY+#;MbEx_prL!3M_K5CM?x&bE?dC`Ucc@;4>19c z_s4OG@dbO;Rj5Zs&XvY9hI`|V)=;T5V*iutBV??ba~_0%lpRd+|4=@b5f&A&>mKOS zIMHI?x$03vu1r|z>D=31`2LF< z_zrW+`vK!@@W=9COu5+d$VPBWSw8c>Qy2<-(@>kwbj?9X(Qc$}`b_ZLa@PxPekgy% z{aMC(F6O4ZTszP6pwzx}gUApAFD*Ly>mF!8B04O@>uGlh+m9HUEtJ`Fu<1Mgx;rAK zFFNkG0s;Ug41EWgLLco>(j39bO1x5ct+KJ8lnqvBKbd{GQeh+(RAiSn1g5hQ_8vCh z?vW{K9#Bl_SnTXsR%i#jqF&P|W_ZZs4z%xz=XgZeZeFlgv836dyC|KfA&V)?3N(!R z=>V0ul0c0B)@jX{LuQ&g#rj>5)KE7pW106Ly)}=gGYoXJ4yND>d}qoPE!;C9Hh<W+552tdLMJu8}t{y7*>0yL<%bT)6m4NBeK&so4g8%}$0q-N5eEcgHpo6O z%ryOnQMtieW2+q$7IUu<>Iy9Z@oR@MRh^%)JZ4!v@D{g-X-2fA)P~E4j2#o#I&DP} zFYk2#UERXo>MD^Bw_}6m#2HFspV=1h0G!h8-}hplxoo;vC~DpX68>Ljs&xIsAK9e8 zHx2ZafM>lQz`aWvNFp4RZijkMhKrddT0HY}`=E+EBvTw7x6i-F>N#VZO^yBZfiEY1 z;c~gM7sDTBo%;EDZ{j6ZLN&Lb!&>=t<*~I)R7_@7$F0_LQUj-!&efvTz24ko;BkdK z<0y}8Qxl+5U!SQqLjj((wkaff3-Lv-`^=UTV|zD1mpx3pxG~AwyEx;p$0ZjC7f9(I zYTg@eT=X{=wd4A8IYdSuz3@Q%efUUWr1+4i1T=hY2xlV3#JwIBCIu2hp*@W;!@eE2 zSNW~;rt&#@Cw5IAs|JTXeKibP2*uzRa-W@HJ^hl}c1uC!>{q)Btmv8P`}N__gH2Y2 z3fN)sd;9k}`QR5tA-|?5Y3%;Lx^AL$H^q}2+Vg9=SHOe{7Vk}4Eh{6GYqS9R|3T0Vn>Zk zf?4mgm=v4IJ6(AXvNL!Q+r~rI)|b* z$YJLq<&4K98<&bZvQ!2^TmzC<#!5h08)tst5PPXw>!Bj zuaRhtMO(sLRoAgk)|$C~D=i;c(@QvLKd80lC3s5i$WnXy)8QzYg^TR(SQ$%iTB4%Gnq+)k>O zrOBN5y<$>g`HbT4Ar~cv~99zFk7xkH0gn0k*R$r~`+No|}IBQ2!fb-2t3| z+6FRqZw{4Grnea|T!X@T_DO3i=7q&WyoE3B0U-w($@3X2c)-a;8v3Iw@yaSqe>h>- z%P^PC*zzr4anW*#wmb^a>I#_Pm0eKFh5KeY=@Z{lrxluJGjQP>eu4QS zSH#$I`T~0tk*FRikt$ct!v8l0ZQOjLzm4_rfPoF>!Ha@Lyt6}<9$8ZGE_Sl0ZffUf zKH<*?oPwH8?PM<_k<-#E)5^cqSWki)3$1IJ(6cKq^ATPMp}r~t+JEQdj8NHDT8L7n zS-YU(ysoq6dir|h95nzElfeJ?kUAH8-%2 zw`|6PatIS5w{mcHwaSC76g6#QUfjlIF8&{e7#MNgDK zVFG?z$tY3%M?Jh4`s9i=kQE$|@9tje=6hWt4}Cutw6?!V*{G%WW%SD(0)lPKjn-w* z+moHKHMN70LmB5-9y0C`-SJ9`$rl>pg60*CJSQLHf0~>#U6dZXy>R&cIHz+>L50gN z+4E%OT)UCob|z1ZluYC4Oj*jgg7+B zXoy5}2zj;f?W?PrfL1DK4zg0Wo=y`7?UUxxICm7N9@m9_>XqVoU-t9l)g64fUtmh_lK75F>Hz6|;*q$k)i1-v`bRX@)bd5fe!Q2Y$)jqL z?t#x5>$E3{3FGAj`!PO$*BZHZ<2N41B=9VF?hlrIz~H-5N6zL#g}d3jAsQ5{UX!j$ zQbu&F`$0^)?`oCMLcbVuJ$W+orr`HpDkCc+p6Axe#}B{m?7uq#Lf5)aW=+1cC0R|% z`?q$#kQ)W@H~k1($$AZ*HYH-`{X3Bb73F0qJC)&uia99NOcl+`TWH*ob<#KVok;mo znZ}V_S+2>=`Jr`;FtQ?g3s-&sB>ScN$G^R97~`tAhxFZb%@1g1ZAUta!Q zbxn_$Z;}3MfBpou#+Z`rvATR3@@REcrmYu-<+k)ku13l`PJ{1qdDc@04Feb4;q-CrvIU(BcFQF5$>2u$lrh6*{q zNjcf)77#+?l%i1fnZo&WenDXG!oQ38w6_L=;Xe!o@Zx63=YCed2Qk{?Cc9I~@?8-( z?GO7h-o&TOdG%`>w~@px@KpFlmhitaNqb73aN_5F@aZ!3I9x|u+A_nPsoCY*{G`V) z#^7}A3$4qbh&aPH-;6(ykh^X+d=R7NBhS`m=%($N7V7(Z?1bhO>qMMayKCbZK$GSn zkj@{I)=5LSn&6E?coPid;(8Nj z3c2tvZ*JM@WFA+3*b{s(U7(#R8Ymaj=BYVzbty{xWIezEem-_?V z$mNQ#^AthZ`D-B`<6rk1=P7CoQ3^Mw8J|)7Dr=#}@tKd+C6)3o6;pv5RmeB(2fZyO zTWh#8`$5{&;EyBf7x+W$`Q)SXB*Mg2b!MZTyq%KJKNUQ!eeTWcMIpXErXMPMFxV^J zO_t--+;3o58yl%LIz4;`6?^wBT(;8?^F1>Od`C$$5{g??Tfb#}5RcFLXvr=`S5XX0 zf=wPdLjLwM{S4xirT=U^`}F(BzfD^0kJZflo}ORk-vFQyy}*S?_nzsx2ee-7@Tv(Wm^$i|Q+1tR$9QuPp7r>Oqspm4y>yufEDM;chO z3Mt z+1~vlZd({kOQt&nXq#@$yN=H@+PGZq(^?Wdy$3T$F$9bl(lFutjLo>9C)JFWWdNi{ zQb;&))CVcP0xWqkt^)x@XB7-@!8oV^m#h|{F=5&8?D~?zo@Y91@t;;1<0+;m7s9^z zAnyYCBqZZe#;Fo(XQ9)^2ZFTO^2dwsUis;x;C6l1R%5<~%jD(Pn8Q7beMfwvWmrGP z7BSscD)7j-+m>x(=xR!@GjuEN`@Cz=G+#XU2li!Rb;A^p9eig+%MrjEV{N{095;Ut&QAm0!};^V1;Hrmx<*hh376h9Y)&+Ibq<&>O=I zomy=ipN4a9dzfX#Y!+)ZYnv`pPGuKl5t>bXCN&98S{!exIt5f#+eR_SmPe*nj1rEL zzt2|9*w+JOt*nfR)^kvqvVT-(+0##03y(lR@|ZTZn7C-hMJw^cQszmXrok!-s(N!T zMDV?tUA}z+(|Tyv%UR=(L505#tJ#YX(0n}96t6C)Lhdn+CwzbaYA5pO4u)Mo&PG9= zSlut6>}SIL7pRZ}n1~3z=^kH{x>z#t26x__n4uYMEjTGyyt>RCtul7f(U6+Qm3$>f z(_sO9&N91s1!pg`oI0kkF;l2ekruf)M!ve>{dW&jk6xsY`ND1=#v?vr&+7D@$oQ@o zDLG{tO)$ULd=}J1sGTI_7*CiHOtU@J?1>$-(j!;jC{DCCMn#>a4m+i+u1f9n1M_gz z+h1P^YU*BfRf`+#8^?!hYrf(A>a94JsO{;eddFq*l3os6;v*={d$y0T#1|&6u~!Sr zl2%r;gYRd7W$?I`#bK^1Q;ONR?!yMawJi za_&*Y^Ud`v7^nmzDe%+#5}o;hj|zBl*q@dcEqgF(qo3(aGFY<*gsQ{5=qGt9c?@Vx zgI$`vYk}w(3n!<7++wndARY7acam$Ov^sNol<~Yj)A1M)eP``|s2^CerN{tb8DA!y zo&*gXJPN+4NsRApmF7W%L?Fhcg$JAZD@npGZ|Bf|OxG&!TS?J>UVwgIQRx^)?-_~c zcaOh6EODanJM-mPR!S8Oukz+l@?k{K!Kv`^eJ_cT^2%W^Ws}rw6$uQj_LO}PPqiI= z!y|%IIvMtNw1ymDlTb%|h~f41no~nUxICmFa3*Up134trePJ}8q&&eAvk;|FXmgo< z8GPpng~<_()bv`N#9+n)@P~cz(QD2MWwmTY#Gv=WZDg#b7H@1Y=%7U$9J#e}Kqn*a zCGTxMaCuU2O>6Q*kXjk8qy>va-clU-Ds`KHX@lm%NR#1)BHPw0nC0ELK;oURzWS2&3WLy9BYaDUxhSQPWeJZ z#R;af4#$?5tt-(Hm6P{XWQekTEUg6YbHU4SV`)FcVcU=sd#$Wat#0R!M6C*}c`tP_ zi_hPj$?MIBL!7miH0|Aw(A5ke6f?w&2wO+Fd_Q?y!AWN#j84$s{oU8dWB3}Ka6n5W zukXHGW+5aP6!0a;&w6P?u8{~#Jr36E?QIJGsi?Z2jjcK57rHOWvI+CQ&NDx;Ex9tl zW<{e=-pc!B)mF%@DjtB1+!q}K9TWY(=R-P3pHNgUmQxQ(t(&Mg;&@>eaV_Mj zGTXIliAK4529U>{?%Xnvv0#U4Z!Rl5>ODkn9P42)!+1-ytP*z|6NUNEs|%slwKmmh z=p<^3pf&+sh^Bm0pm6Yvl7fnS4)l8oG&U2uK@RouX*!myABw@bqE9`HQdE^xmY(dx zFr}mMwTkK)jj{bEdwo>(Vu$4Uy4zFFG#dn~kGkRpsD`>;Qkw1w$xXGso}IGW6gAk1 zs&n`P8=*eqSHKN3{TKBrm<1kJt8#cI$7>=vbfW3!^grz$W ztSWi{$&y|^yvnBB1fQz9tD;VtAwM^1#{`Jtu;f#|?yFew|2aDEuq4|yj6dw9hzoIo zdn<0ug)21|ZgYa$9FXEF2X09%D@&VdT3T7*o2x8Et+Z{~Tjs>_O-oA}Us{=d)b-bS z@H^lc_XEexeP7pg?vR;gNuCiisI^^yuBNPzyl%);$_$Ykg0manr$O4oq6Z}hEkO%7 zq5rXqpen)?OSpKa(UPX83*DA2uQ5HsauEO#b+}^APZ(kk?hQr|2Yuo~r;22HZ72{B z7S}6XzNOYf@g1bB{k%k)3jJFlaB-*Bpz2~}`=hG&seYlyI?RYiiy_(JVw|7Vtw*wW zE#)hSgfI8ny&kTU9WU?E{fusCFKc}0Zd0`5q(O=!6(W`g{qoOk8rv?~3A$88si;MZ z7Dn}aFZ5`dcjf#TT7qbAmMm&54Ln;2XV=sMZ~SN?Wdfnc63b(0nRL!SMamu7k_^!8 z!M#Dr2PhZg?HjwKy1%ImHtq;D0xRy7@vGq-0Dcp0@@w)Duu@rv8{FaAG)aYr&5Ah$ zNr_CTIjjgPQn7x~xkzH$>XL;)Su*m_8I>T zD)Fbk74d}2w`Ui9nkhj}!5^~S$BshsG`)A)4qx1#`kC{yCTul0(I)PgVdYe52}*ms zP}s~o_!`<{`;|46RUT4w#Wn0mCZ?}QoHXeselP#&R;?3ffiq>&zo)_4x?*s`1c+ExXJ54+IkJ$57=v1? zSTlRxI5{%m9H_)j=q)*4^zct8WS2#tc;l1fWORs38df;BS*`Cra#K8|8&ZM~>m*ja zgu69m3_rjXE(vaW9S|WMk|o*Ns_S>OF99HUu~tiINUOid_b7Ky$n?0M2XZ4$r3jNI z1>5zs75~b2Xb%C`Y=5#ROX8b=N?D^9=Vb?^)e{972%7^9BL6PJ&s_IGqm+l=kU7qj`%8Myfr#gMe6DPX{;LDpW*n2TcGKDCIg^m8z|FldGfTI(P7&Lu zVRj+6j)TXpy)vU9DS}CH549T+?GY~jw6H_bl`|m6hiH(ZoL%=7VB|;>1hALnxj7F2 z0g23EyUCt=X5T`_g~r{!8gym#zF35I-8bGHP=TjY3LI`J{x9O6m!&4Pav;Jz3r=_5 z@J#G04bQ$Ko3iA`I)F+9zo#mq$VhIUIFf_RL)r_g0HvYhSxTQeD3EG`xEmiy_2m3<*u4Kt$g(74(gFV~d zHgopC3$a6!!BR5h(9Yu}A+VkJHu00~h86aQMPs9&rwO}h5;J(FX$MEtd zWth|T3nkzSQ&&sAp>(?Di7)W~oESu?tZzHc9P>yYbiTwHvqmi^$vlAPJv|gk)1|Lo z7Kr2;6PJ;l|pU-LEo2@AtKPiX2 z=TjJi@~d#6ouViUFfdJaG))5J)~oN%kJhUD-^aU#&pu6;+@5>C@b<)wQ&ZH+-#<7< zJ*)mTXReD^Jp>K8YnH!v_sF7_P#!v~5oo#*E$x?Jkkyhr&gc4P7fvWpcqIdxTTbSn zLt>L98L~PGw>j5K@R97hsy5qIoe($*aW8E$H(@R9&y$cd%=xXF(KZrs61ILq*V|vl! z_d}=NXi{o?L{@}pfGQH)q20ceO24CE1C=X=jSr7;T)jr|X8rdRA9S%pj`2*b_Y|lX zJ=MN>7on0^N}j?^nW1AF|$~`Z=lJn{l`w^zf z3Uy5Nunp~DPMCpZIbzRHU(^8;=>^MS)xIAwj1Swom|U{fibqMj)Ygg%=;3}EOK24t z*b+Bdo?l#qm@kUnon4QHVwP2bgi^LM(D)04@p-Sbkm*gl59&qx)YO*FPuxdgA>Dh!pvt~W{TNd-Y?JL$2~|6@l0pAd026&mOB;aDBTKixiVff-bf`}KmoOV zTBhxhCg$@d6ee$9DVCxcs$1ZC`})Uqe5|^cZ!p< zC|T^rFUY46Of5DVH$1V;9E!O!k9B`n;t3{O7Cg5BForyQ75OukqcS%v}C5hm2hFXJ|OEzss!t06`Abi>#VpWNvO{uCM z2h&p7YraqSCQx5c?G8Pm*@g@OrHy;0EF9OSc<{C0mcmjsEV;4`AT6WtP z^bLJhQ2R*DpynuB7X2I5SnCAk?RdZmuj$cwVW`%OyBt!I-7JNxg#MN;1^?a^2%$cl(jtg8zZN{p$OPV{3=C4a4WwFEF zVs|9L_(vrTbFvasPp z3|hTE;zWJZN^~ZiuPDSi_T@umJHZ||Q9o+!CPS{lr z?zqth{Fjb0dk#L^i}d$+5(fSB4>TdfiU@m=fC^zZ=*x%(HxILQe<(xJJ47u&P%_)l z7%Z@D02HJX3kT29+eEwVHyG9M%C7kFCxi7rCj<2k8tVd&K5<>M&lYJq;zAWJ52eAll|eN_t3>oz#-v6 ziM@Fq#c;*!kjOe%u3u+2=RnF}iJK}fbp4iipDsrIsLKssH~VaIJ{071AcR6TQRn~z^&n=nHOI8*BueZp<-c*7R;;5dvL)1KE@XffY zR-r@Zm3jr=TMpC;S5aBe!mrVg(Gvb=WM;DZdp6ANS*)bARO6C}R3Gw{wttfxaehI! z^?iX9Go_}IbwE%;bb`Thghixo^LqR)X?sO9&ibq4!|9S(aLxhN(3U*Dlxz2Rhr6o3 zG01*=d<8}r>r%L(upjCuva5SdUPPo>f91U@M7X#AO2dBF$OfRjdB4+8IexE}q-9Kn z!gpa&pJq%>gCuFkVr_fh*fxl3kkMkkVksQ;a zO_T_-Eb0UYw~SERsPrNV3u$1#6crSff8F}|p73Lc-_(Tl5W4(jbzq(rLG<+kgY;R{9vo5y+_!#j@cZqKn|k zd#bTrleci!d)V`JyEHOL>ad2b$pccj(&ti9(>;(<4Y7mPa=R)Ay+n}7fo@Q+4Oy&= zQ2|RabC44wen)lm6jJ^6Y=a~J=Z55*4~btiy@}+7rlB(x!um>&mD#TkZ%em>7WSi< z(RuDm_0v0sCi7a<#dzy{&UZ893Of16cHu|&4ZWYm*kC=16ip9vWYp2%#^j2-g@wKoxol1G5X6ly)qns)~JaL@dicz)NNY}}RS)a^OolW)6Iknm#`%~#fx}=_))b?Odx`=he zayBAe+B$PF3)dFplz{nwd;w9?Cr!tS|GZ`c`05d~YHBEMkK_@)SDIs9G!%86N-So( zu_Su|!TJGDGNPthu;C(m7gFe9td89RsMM%<&1qL&^ zz)a84tBrWNor5^>mR#B`n?*?pHSuB0L`4Dm-ziY6